From 6cdc660c05cd9e28fcdbf2cf6ccd13565cc6f822 Mon Sep 17 00:00:00 2001 From: msweet Date: Fri, 10 May 2013 18:56:23 +0000 Subject: [PATCH 1/1] Import cups.org releases git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/tags/release-1.4.7@4306 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES-1.0.txt | 217 + CHANGES-1.1.txt | 3462 +++ CHANGES-1.2.txt | 1261 + CHANGES-1.3.txt | 856 + CHANGES.txt | 838 + CREDITS.txt | 49 + INSTALL.txt | 207 + LICENSE.txt | 973 + Makedefs.in | 293 + Makefile | 437 + README.txt | 164 + backend/Dependencies | 76 + backend/Makefile | 282 + backend/backend-private.h | 322 + backend/dnssd.c | 912 + backend/easysw-firewire-design.txt | 71 + backend/easysw-firewire-linux.txt | 35 + backend/ieee1284.c | 466 + backend/ipp.c | 1953 ++ backend/lpd.c | 1380 + backend/network.c | 294 + backend/pap.c | 1696 ++ backend/parallel.c | 686 + backend/runloop.c | 426 + backend/scsi-irix.c | 241 + backend/scsi-linux.c | 260 + backend/scsi.c | 231 + backend/serial.c | 1330 + backend/snmp-supplies.c | 990 + backend/snmp.c | 1341 + backend/snmp.txt | 172 + backend/socket.c | 513 + backend/test1284.c | 87 + backend/testbackend.c | 654 + backend/testsupplies.c | 83 + backend/usb-darwin.c | 2260 ++ backend/usb-libusb.c | 835 + backend/usb-unix.c | 631 + backend/usb.c | 265 + berkeley/Dependencies | 16 + berkeley/Makefile | 167 + berkeley/lpc.c | 454 + berkeley/lpq.c | 686 + berkeley/lpr.c | 431 + berkeley/lprm.c | 227 + cgi-bin/Dependencies | 64 + cgi-bin/Makefile | 382 + cgi-bin/admin.c | 4324 +++ cgi-bin/api-cgi.header | 34 + cgi-bin/api-cgi.shtml | 17 + cgi-bin/cgi-private.h | 35 + cgi-bin/cgi.h | 119 + cgi-bin/classes.c | 558 + cgi-bin/help-index.c | 1331 + cgi-bin/help-index.h | 87 + cgi-bin/help.c | 392 + cgi-bin/html.c | 239 + cgi-bin/ipp-var.c | 1592 + cgi-bin/jobs.c | 214 + cgi-bin/libcupscgi.exp | 42 + cgi-bin/makedocset.c | 486 + cgi-bin/multipart.dat | Bin 0 -> 50411 bytes cgi-bin/printers.c | 578 + cgi-bin/search.c | 381 + cgi-bin/template.c | 733 + cgi-bin/testcgi.c | 75 + cgi-bin/testhi.c | 113 + cgi-bin/testhi.html | 31 + cgi-bin/testtemplate.c | 103 + cgi-bin/var.c | 1306 + cgi-bin/websearch.c | 116 + conf/Makefile | 143 + conf/cupsd.conf.in | 125 + conf/mime.convs.in | 104 + conf/mime.types | 181 + conf/pam.opendirectory | 5 + conf/pam.securityserver | 7 + conf/pam.std.in | 2 + conf/snmp.conf.in | 13 + config-scripts/cups-3264.m4 | 140 + config-scripts/cups-common.m4 | 375 + config-scripts/cups-compiler.m4 | 574 + config-scripts/cups-defaults.m4 | 452 + config-scripts/cups-directories.m4 | 429 + config-scripts/cups-dnssd.m4 | 68 + config-scripts/cups-gssapi.m4 | 124 + config-scripts/cups-image.m4 | 109 + config-scripts/cups-largefile.m4 | 52 + config-scripts/cups-launchd.m4 | 43 + config-scripts/cups-ldap.m4 | 52 + config-scripts/cups-libtool.m4 | 39 + config-scripts/cups-manpages.m4 | 96 + config-scripts/cups-network.m4 | 74 + config-scripts/cups-opsys.m4 | 35 + config-scripts/cups-pam.m4 | 102 + config-scripts/cups-pap.m4 | 31 + config-scripts/cups-pdf.m4 | 88 + config-scripts/cups-poll.m4 | 22 + config-scripts/cups-scripting.m4 | 100 + config-scripts/cups-sharedlibs.m4 | 263 + config-scripts/cups-slp.m4 | 38 + config-scripts/cups-ssl.m4 | 162 + config-scripts/cups-threads.m4 | 54 + config.h.in | 674 + configure.in | 81 + cups-config.in | 160 + cups/Dependencies | 453 + cups/Makefile | 644 + cups/adminutil.c | 2461 ++ cups/adminutil.h | 77 + cups/api-array.header | 34 + cups/api-array.shtml | 177 + cups/api-cups.header | 40 + cups/api-cups.shtml | 443 + cups/api-filedir.header | 36 + cups/api-filedir.shtml | 31 + cups/api-filter.header | 42 + cups/api-filter.shtml | 585 + cups/api-httpipp.header | 37 + cups/api-httpipp.shtml | 323 + cups/api-overview.header | 54 + cups/api-overview.shtml | 94 + cups/api-ppd.header | 36 + cups/api-ppd.shtml | 217 + cups/array.c | 1144 + cups/array.h | 84 + cups/attr.c | 422 + cups/auth.c | 724 + cups/backchannel.c | 199 + cups/backend.c | 134 + cups/backend.h | 76 + cups/conflicts.c | 1147 + cups/cups.h | 340 + cups/custom.c | 123 + cups/debug.c | 553 + cups/debug.h | 89 + cups/dest.c | 2077 ++ cups/dir.c | 474 + cups/dir.h | 69 + cups/emit.c | 1222 + cups/encode.c | 641 + cups/file-private.h | 98 + cups/file.c | 2441 ++ cups/file.h | 112 + cups/getdevices.c | 284 + cups/getifaddrs.c | 267 + cups/getputfile.c | 508 + cups/globals.c | 249 + cups/globals.h | 169 + cups/http-addr.c | 641 + cups/http-addrlist.c | 661 + cups/http-private.h | 278 + cups/http-support.c | 1728 ++ cups/http.c | 3548 +++ cups/http.h | 453 + cups/i18n.h | 115 + cups/ipp-private.h | 85 + cups/ipp-support.c | 482 + cups/ipp.c | 3210 +++ cups/ipp.h | 505 + cups/langprintf.c | 277 + cups/language.c | 1337 + cups/language.h | 115 + cups/libcups.exp | 372 + cups/libcups.order | 1 + cups/libcups2.def | 287 + cups/libcups_s.exp | 80 + cups/localize.c | 781 + cups/mark.c | 1099 + cups/md5-apple.h | 30 + cups/md5.c | 344 + cups/md5.h | 74 + cups/md5passwd.c | 142 + cups/notify.c | 202 + cups/options.c | 629 + cups/page.c | 397 + cups/ppd-private.h | 104 + cups/ppd.c | 3147 ++ cups/ppd.h | 434 + cups/pwg-file.c | 639 + cups/pwg-media.c | 849 + cups/pwg-ppd.c | 1491 + cups/pwg-private.h | 167 + cups/raster.h | 370 + cups/request.c | 950 + cups/sidechannel.c | 576 + cups/sidechannel.h | 136 + cups/snmp-private.h | 148 + cups/snmp.c | 1741 ++ cups/snprintf.c | 364 + cups/string.c | 794 + cups/string.h | 216 + cups/tempfile.c | 235 + cups/test.ppd | 262 + cups/test2.ppd | 252 + cups/testadmin.c | 120 + cups/testarray.c | 483 + cups/testconflicts.c | 126 + cups/testcups.c | 417 + cups/testfile.c | 823 + cups/testhttp.c | 576 + cups/testi18n.c | 686 + cups/testipp.c | 870 + cups/testlang.c | 116 + cups/testoptions.c | 117 + cups/testppd.c | 1081 + cups/testpwg.c | 495 + cups/testsnmp.c | 307 + cups/transcode.c | 1826 ++ cups/transcode.h | 81 + cups/usersys.c | 620 + cups/utf8demo.txt | 213 + cups/util.c | 1890 ++ cups/versioning.h | 80 + data/HPGLprolog | 27 + data/Makefile | 215 + data/classified | 6 + data/confidential | 6 + data/cups.irix | 3 + data/cups.pam | 2 + data/cups.suse | 2 + data/epson.h | 27 + data/escp.h | 34 + data/euc-cn.txt | 7536 +++++ data/euc-jp.txt | 15184 ++++++++++ data/euc-kr.txt | 8371 ++++++ data/euc-tw.txt | 17840 ++++++++++++ data/font.defs | 55 + data/hp.h | 24 + data/iso-8859-1.txt | 303 + data/iso-8859-10.txt | 303 + data/iso-8859-11.txt | 249 + data/iso-8859-13.txt | 299 + data/iso-8859-14.txt | 301 + data/iso-8859-15.txt | 303 + data/iso-8859-16.txt | 299 + data/iso-8859-2.txt | 303 + data/iso-8859-3.txt | 296 + data/iso-8859-4.txt | 303 + data/iso-8859-5.txt | 303 + data/iso-8859-6.txt | 260 + data/iso-8859-7.txt | 302 + data/iso-8859-8.txt | 270 + data/iso-8859-9.txt | 307 + data/jis-x0213.txt | 11425 ++++++++ data/koi8-r.txt | 257 + data/koi8-u.txt | 257 + data/label.h | 28 + data/mac-roman.txt | 223 + data/media.defs | 206 + data/pcl.h | 38 + data/psglyphs | 1051 + data/raster.defs | 94 + data/secret | 6 + data/smiley.ps | 28 + data/standard | 6 + data/testprint.in | 8 + data/topsecret | 6 + data/unclassified | 6 + data/utf-8 | 40 + data/windows-1250.txt | 274 + data/windows-1251.txt | 274 + data/windows-1252.txt | 274 + data/windows-1253.txt | 274 + data/windows-1254.txt | 274 + data/windows-1255.txt | 274 + data/windows-1256.txt | 274 + data/windows-1257.txt | 274 + data/windows-1258.txt | 274 + data/windows-1361.txt | 17396 +++++++++++ data/windows-874.txt | 274 + data/windows-932.txt | 9403 ++++++ data/windows-936.txt | 24071 ++++++++++++++++ data/windows-949.txt | 17367 +++++++++++ data/windows-950.txt | 19841 +++++++++++++ desktop/cups-128.png | Bin 0 -> 4888 bytes desktop/cups-16.png | Bin 0 -> 503 bytes desktop/cups-256.png | Bin 0 -> 10147 bytes desktop/cups-32.png | Bin 0 -> 1042 bytes desktop/cups-512.png | Bin 0 -> 21029 bytes desktop/cups-64.png | Bin 0 -> 2234 bytes desktop/cups.desktop.in | 39 + desktop/cups.icns | Bin 0 -> 107501 bytes desktop/cups.svg | 533 + doc/Makefile | 260 + doc/cups-printable.css | 327 + doc/cups.css | 459 + doc/de/index.html.in | 107 + doc/es/index.html.in | 107 + doc/eu/index.html.in | 106 + doc/help/accounting.html | 62 + doc/help/api-array.html | 983 + doc/help/api-cgi.html | 1123 + doc/help/api-cups.html | 2426 ++ doc/help/api-driver.html | 1153 + doc/help/api-filedir.html | 992 + doc/help/api-filter.html | 1420 + doc/help/api-httpipp.html | 4191 +++ doc/help/api-mime.html | 771 + doc/help/api-overview.html | 499 + doc/help/api-ppd.html | 2208 ++ doc/help/api-ppdc.html | 2194 ++ doc/help/api-raster.html | 1372 + doc/help/cgi.html | 86 + doc/help/glossary.html | 219 + doc/help/kerberos.html | 122 + doc/help/license.html | 1078 + doc/help/network.html | 684 + doc/help/options.html | 778 + doc/help/overview.html | 70 + doc/help/policies.html | 601 + doc/help/postscript-driver.html | 645 + doc/help/ppd-compiler.html | 1261 + doc/help/raster-driver.html | 561 + doc/help/ref-access_log.html | 140 + doc/help/ref-classes-conf.html | 566 + doc/help/ref-client-conf.html | 56 + doc/help/ref-cupsd-conf.html.in | 3099 ++ doc/help/ref-error_log.html | 55 + doc/help/ref-mailto-conf.html | 108 + doc/help/ref-page_log.html | 77 + doc/help/ref-ppdcfile.html | 2449 ++ doc/help/ref-printers-conf.html | 720 + doc/help/ref-snmp-conf.html | 146 + doc/help/ref-subscriptions-conf.html | 354 + doc/help/security.html | 172 + doc/help/sharing.html | 184 + doc/help/spec-banner.html | 156 + doc/help/spec-browsing.html | 118 + doc/help/spec-cmp.html | 1218 + doc/help/spec-command.html | 218 + doc/help/spec-design.html | 184 + doc/help/spec-ipp.html | 2879 ++ doc/help/spec-pdf.html | 24 + doc/help/spec-postscript.html | 148 + doc/help/spec-ppd.html | 2036 ++ doc/help/spec-raster.html | 720 + doc/help/spec-stp.html | 133 + doc/help/standard.html.in | 181 + doc/help/translation.html | 852 + doc/help/whatsnew.html | 204 + doc/id/index.html.in | 107 + doc/images/color-wheel.png | Bin 0 -> 13148 bytes doc/images/cups-block-diagram.png | Bin 0 -> 76386 bytes doc/images/cups-block-diagram.svg | 841 + doc/images/cups-command-chain.png | Bin 0 -> 14902 bytes doc/images/cups-command-chain.svg | 439 + doc/images/cups-icon.png | Bin 0 -> 4888 bytes doc/images/cups-postscript-chain.png | Bin 0 -> 17498 bytes doc/images/cups-postscript-chain.svg | 531 + doc/images/cups-raster-chain.png | Bin 0 -> 16916 bytes doc/images/cups-raster-chain.svg | 534 + doc/images/cups.png | Bin 0 -> 4888 bytes doc/images/cups.svg | 533 + doc/images/generic.png | Bin 0 -> 16913 bytes doc/images/left.gif | Bin 0 -> 1492 bytes doc/images/left.xcf.gz | Bin 0 -> 1194 bytes doc/images/raster-organization.png | Bin 0 -> 20974 bytes doc/images/raster-organization.svg | 378 + doc/images/raster.png | Bin 0 -> 37656 bytes doc/images/raster.svg | 386 + doc/images/right.gif | Bin 0 -> 341 bytes doc/images/sample-image.png | Bin 0 -> 3541 bytes doc/images/sel.gif | Bin 0 -> 362 bytes doc/images/smiley.jpg | Bin 0 -> 14120 bytes doc/images/unsel.gif | Bin 0 -> 127 bytes doc/images/wait.gif | Bin 0 -> 1810 bytes doc/images/webinterface.png | Bin 0 -> 150003 bytes doc/index.html.in | 107 + doc/it/index.html.in | 107 + doc/ja/index.html.in | 107 + doc/pl/index.html.in | 107 + doc/robots.txt | 31 + doc/ru/index.html.in | 103 + driver/Dependencies | 59 + driver/Makefile | 382 + driver/api-driver.header | 34 + driver/api-driver.shtml | 18 + driver/attr.c | 109 + driver/check.c | 111 + driver/cmyk.c | 1955 ++ driver/commandtoescpx.c | 244 + driver/commandtopclx.c | 171 + driver/dither.c | 306 + driver/driver.h | 249 + driver/image.pgm | Bin 0 -> 152380 bytes driver/image.ppm | Bin 0 -> 457020 bytes driver/libcupsdriver.exp | 30 + driver/lut.c | 202 + driver/pack.c | 307 + driver/pcl-common.c | 272 + driver/pcl-common.h | 71 + driver/rastertoescpx.c | 1919 ++ driver/rastertopclx.c | 1944 ++ driver/rgb.c | 558 + driver/srgb.c | 79 + driver/testcmyk.c | 437 + driver/testdither.c | 191 + driver/testdriver.c | 178 + driver/testrgb.c | 348 + examples/Makefile | 128 + examples/color.drv | 44 + examples/constraint.drv | 48 + examples/custom.drv | 41 + examples/grouping.drv | 36 + examples/laserjet-basic.drv | 88 + examples/laserjet-pjl.drv | 101 + examples/minimum.drv | 26 + examples/postscript.drv | 46 + examples/r300-basic.drv | 75 + examples/r300-colorman.drv | 85 + examples/r300-remote.drv | 85 + filter/Dependencies | 546 + filter/Makefile | 528 + filter/api-raster.header | 37 + filter/api-raster.shtml | 160 + filter/bannertops.c | 1092 + filter/commandtops.c | 356 + filter/common.c | 535 + filter/common.h | 84 + filter/error.c | 287 + filter/form-main.c | 53 + filter/form-ps.c | 40 + filter/form-tree.c | 615 + filter/form.h | 168 + filter/gziptoany.c | 118 + filter/hpgl-attr.c | 479 + filter/hpgl-char.c | 631 + filter/hpgl-config.c | 636 + filter/hpgl-input.c | 272 + filter/hpgl-main.c | 269 + filter/hpgl-polygon.c | 385 + filter/hpgl-prolog.c | 369 + filter/hpgl-vector.c | 773 + filter/hpgltops.h | 240 + filter/image-bmp.c | 545 + filter/image-colorspace.c | 1567 + filter/image-gif.c | 692 + filter/image-jpeg.c | 322 + filter/image-photocd.c | 333 + filter/image-pix.c | 240 + filter/image-png.c | 315 + filter/image-pnm.c | 320 + filter/image-private.h | 221 + filter/image-sgi.c | 295 + filter/image-sgi.h | 87 + filter/image-sgilib.c | 891 + filter/image-sun.c | 407 + filter/image-tiff.c | 1715 ++ filter/image-zoom.c | 361 + filter/image.c | 812 + filter/image.h | 130 + filter/imagetops.c | 1069 + filter/imagetoraster.c | 4355 +++ filter/interpret.c | 1660 ++ filter/libcupsimage.order | 1 + filter/libcupsimage2.def | 13 + filter/libcupsimage_s.exp | 16 + filter/pdftops.c | 599 + filter/postscript-driver.header | 17 + filter/postscript-driver.shtml | 276 + filter/ppd-compiler.header | 19 + filter/ppd-compiler.shtml | 883 + filter/pstext.c | 506 + filter/pstext.h | 75 + filter/pstops.c | 3531 +++ filter/raster-driver.header | 17 + filter/raster-driver.shtml | 194 + filter/raster.c | 1295 + filter/rasterbench.c | 355 + filter/rastertoepson.c | 1142 + filter/rastertohp.c | 870 + filter/rastertolabel.c | 1298 + filter/testimage.c | 99 + filter/testraster.c | 1076 + filter/textcommon.c | 1211 + filter/textcommon.h | 114 + filter/texttops.c | 1158 + fonts/Makefile | 118 + fonts/Monospace | 2744 ++ fonts/Monospace-Bold | 2354 ++ fonts/Monospace-BoldOblique | 2445 ++ fonts/Monospace-Oblique | 2706 ++ init/cups-lpd.in | 12 + init/cups.sh.in | 234 + init/cups.xml.in | 214 + init/org.cups.cups-lpd.plist.in | 35 + init/org.cups.cupsd.plist | 53 + install-sh | 222 + locale/Dependencies | 10 + locale/Makefile | 205 + locale/checkpo.c | 376 + locale/cups.footer | 5 + locale/cups.header | 30 + locale/cups.pot | 6730 +++++ locale/cups_da.po | 5663 ++++ locale/cups_de.po | 5703 ++++ locale/cups_es.po | 5689 ++++ locale/cups_eu.po | 7282 +++++ locale/cups_fi.po | 5679 ++++ locale/cups_fr.po | 5783 ++++ locale/cups_id.po | 7095 +++++ locale/cups_it.po | 5546 ++++ locale/cups_ja.po | 5527 ++++ locale/cups_ko.po | 5623 ++++ locale/cups_nl.po | 5726 ++++ locale/cups_no.po | 5642 ++++ locale/cups_pl.po | 5691 ++++ locale/cups_pt.po | 5709 ++++ locale/cups_pt_BR.po | 5708 ++++ locale/cups_ru.po | 5686 ++++ locale/cups_sv.po | 5655 ++++ locale/cups_zh.po | 5586 ++++ locale/cups_zh_TW.po | 5583 ++++ locale/locale.txt | 32 + locale/po2strings.c | 172 + locale/strings2po.c | 175 + locale/translate.c | 443 + man/Makefile | 234 + man/backend.man | 183 + man/cancel.man | 75 + man/classes.conf.man | 110 + man/client.conf.man.in | 49 + man/cups-config.man | 117 + man/cups-deviced.man.in | 44 + man/cups-driverd.man.in | 122 + man/cups-lpd.man.in | 124 + man/cups-polld.man | 38 + man/cups-snmp.conf.man | 73 + man/cupsaccept.man | 79 + man/cupsaddsmb.man.in | 214 + man/cupsctl.man | 107 + man/cupsd.conf.man.in | 714 + man/cupsd.man.in | 72 + man/cupsenable.man | 94 + man/cupsfilter.man | 86 + man/cupstestdsc.man | 50 + man/cupstestppd.man | 165 + man/filter.man | 256 + man/lp.man | 262 + man/lpadmin.man | 208 + man/lpc.man | 71 + man/lpinfo.man | 115 + man/lpmove.man | 66 + man/lpoptions.man.in | 135 + man/lppasswd.man | 68 + man/lpq.man | 72 + man/lpr.man | 122 + man/lprm.man | 65 + man/lpstat.man | 143 + man/mailto.conf.man | 60 + man/mantohtml.c | 715 + man/mime.convs.man | 46 + man/mime.types.man | 115 + man/notifier.man | 157 + man/ppdc.man | 80 + man/ppdcfile.man | 171 + man/ppdhtml.man | 46 + man/ppdi.man | 46 + man/ppdmerge.man | 47 + man/ppdpo.man | 52 + man/printers.conf.man | 124 + man/subscriptions.conf.man | 89 + monitor/Dependencies | 8 + monitor/Makefile | 146 + monitor/bcp.c | 290 + monitor/tbcp.c | 283 + notifier/Dependencies | 15 + notifier/Makefile | 162 + notifier/dbus.c | 552 + notifier/mailto.c | 792 + notifier/rss.c | 732 + notifier/testnotify.c | 285 + packaging/InstallationCheck | 11 + packaging/LICENSE.rtf | 434 + packaging/WELCOME.rtf | 24 + packaging/cups-dbus.conf | 13 + packaging/cups-desc.plist.in | 14 + packaging/cups-info.plist.in | 26 + packaging/cups.list.in | 779 + packaging/cups.spec.in | 371 + packaging/installer.gif | Bin 0 -> 3392 bytes packaging/installer.tif | Bin 0 -> 5538 bytes ppdc/Dependencies | 160 + ppdc/Makefile | 404 + ppdc/api-ppdc.header | 34 + ppdc/api-ppdc.shtml | 18 + ppdc/foo-fr.po | 11 + ppdc/foo.drv | 548 + ppdc/genstrings.cxx | 215 + ppdc/ppdc-array.cxx | 168 + ppdc/ppdc-attr.cxx | 66 + ppdc/ppdc-catalog.cxx | 897 + ppdc/ppdc-choice.cxx | 61 + ppdc/ppdc-constraint.cxx | 64 + ppdc/ppdc-driver.cxx | 1340 + ppdc/ppdc-file.cxx | 110 + ppdc/ppdc-filter.cxx | 60 + ppdc/ppdc-font.cxx | 66 + ppdc/ppdc-group.cxx | 103 + ppdc/ppdc-import.cxx | 343 + ppdc/ppdc-mediasize.cxx | 85 + ppdc/ppdc-message.cxx | 58 + ppdc/ppdc-option.cxx | 129 + ppdc/ppdc-private.h | 42 + ppdc/ppdc-profile.cxx | 65 + ppdc/ppdc-shared.cxx | 88 + ppdc/ppdc-source.cxx | 3901 +++ ppdc/ppdc-string.cxx | 62 + ppdc/ppdc-variable.cxx | 71 + ppdc/ppdc.cxx | 464 + ppdc/ppdc.h | 532 + ppdc/ppdhtml.cxx | 185 + ppdc/ppdi.cxx | 140 + ppdc/ppdmerge.cxx | 381 + ppdc/ppdpo.cxx | 268 + ppdc/sample.drv | 1250 + ppdc/testcatalog.cxx | 63 + scheduler/Dependencies | 260 + scheduler/Makefile | 484 + scheduler/api-mime.header | 34 + scheduler/api-mime.shtml | 17 + scheduler/auth.c | 2861 ++ scheduler/auth.h | 162 + scheduler/banners.c | 224 + scheduler/banners.h | 45 + scheduler/cert.c | 442 + scheduler/cert.h | 57 + scheduler/classes.c | 884 + scheduler/classes.h | 36 + scheduler/client.c | 5296 ++++ scheduler/client.h | 140 + scheduler/conf.c | 3863 +++ scheduler/conf.h | 300 + scheduler/cups-deviced.c | 806 + scheduler/cups-driverd.cxx | 2530 ++ scheduler/cups-lpd.c | 1735 ++ scheduler/cups-polld.c | 475 + scheduler/cupsd.h | 249 + scheduler/cupsd.order | 93 + scheduler/cupsfilter.c | 1352 + scheduler/dirsvc.c | 5552 ++++ scheduler/dirsvc.h | 212 + scheduler/env.c | 271 + scheduler/filter.c | 408 + scheduler/ipp.c | 11619 ++++++++ scheduler/job.c | 4610 +++ scheduler/job.h | 171 + scheduler/libcupsmime.exp | 19 + scheduler/listen.c | 443 + scheduler/log.c | 1031 + scheduler/main.c | 2206 ++ scheduler/mime.c | 774 + scheduler/mime.h | 151 + scheduler/network.c | 305 + scheduler/network.h | 53 + scheduler/policy.c | 366 + scheduler/policy.h | 54 + scheduler/printers.c | 5609 ++++ scheduler/printers.h | 186 + scheduler/process.c | 634 + scheduler/quotas.c | 257 + scheduler/removefile.c | 228 + scheduler/select.c | 951 + scheduler/server.c | 184 + scheduler/statbuf.c | 331 + scheduler/statbuf.h | 50 + scheduler/subscriptions.c | 1679 ++ scheduler/subscriptions.h | 167 + scheduler/sysman.c | 921 + scheduler/sysman.h | 64 + scheduler/testdirsvc.c | 326 + scheduler/testlpd.c | 552 + scheduler/testmime.c | 326 + scheduler/testspeed.c | 366 + scheduler/testsub.c | 522 + scheduler/type.c | 1178 + scheduler/util.c | 500 + scheduler/util.h | 70 + scripting/perl/CUPS.pm | 144 + scripting/perl/CUPS.xs | 270 + scripting/perl/Makefile.PL | 17 + scripting/perl/README | 35 + scripting/perl/test.pl | 17 + scripting/php/Dependencies | 6 + scripting/php/Makefile | 153 + scripting/php/README | 157 + scripting/php/phpcups.c | 487 + scripting/php/phpcups.h | 70 + scripting/php/phpcups.php | 60 + standards/Makefile | 163 + standards/X.690-0207.pdf | Bin 0 -> 524444 bytes standards/lcrc-ipp20-20090602.pdf | Bin 0 -> 112454 bytes standards/lcrc-ippstate10-20090603.pdf | Bin 0 -> 222564 bytes standards/papi-1.0.pdf | Bin 0 -> 503784 bytes standards/pwg5100.1.pdf | Bin 0 -> 37359 bytes standards/pwg5100.2.pdf | Bin 0 -> 37360 bytes standards/pwg5100.3.pdf | Bin 0 -> 262279 bytes standards/pwg5100.5.pdf | Bin 0 -> 2288291 bytes standards/pwg5100.6.pdf | Bin 0 -> 500649 bytes standards/pwg5100.7.pdf | Bin 0 -> 1090862 bytes standards/pwg5100.8.pdf | Bin 0 -> 395397 bytes standards/pwg5101.1.pdf | Bin 0 -> 924222 bytes standards/pwg5105.1.pdf | Bin 0 -> 2021826 bytes standards/pwg5107.1.pdf | Bin 0 -> 150688 bytes standards/rfc1155.txt | 1235 + standards/rfc1157.txt | 2019 ++ standards/rfc1179.txt | 787 + standards/rfc1213.txt | 3923 +++ standards/rfc1321.txt | 1179 + standards/rfc2222.txt | 899 + standards/rfc2246.txt | 4483 +++ standards/rfc2487.txt | 451 + standards/rfc2554.txt | 619 + standards/rfc2567.txt | 2411 ++ standards/rfc2568.txt | 563 + standards/rfc2569.txt | 1571 + standards/rfc2578.txt | 2541 ++ standards/rfc2579.txt | 1533 + standards/rfc2595.txt | 843 + standards/rfc2616.txt | 9859 +++++++ standards/rfc2617.txt | 1907 ++ standards/rfc2712.txt | 395 + standards/rfc2790.txt | 2803 ++ standards/rfc2817.txt | 731 + standards/rfc2818.txt | 395 + standards/rfc2821.txt | 4427 +++ standards/rfc2822.txt | 2859 ++ standards/rfc2910.txt | 2579 ++ standards/rfc2911.txt | 12547 ++++++++ standards/rfc2965.txt | 1459 + standards/rfc3196.txt | 5379 ++++ standards/rfc3239.txt | 843 + standards/rfc3380.txt | 3307 +++ standards/rfc3381.txt | 955 + standards/rfc3382.txt | 2131 ++ standards/rfc3391.txt | 1403 + standards/rfc3510.txt | 899 + standards/rfc3712.txt | 1851 ++ standards/rfc3805.txt | 9579 ++++++ standards/rfc3808.txt | 787 + standards/rfc3875.txt | 2019 ++ standards/rfc3986.txt | 3419 +++ standards/rfc3995.txt | 5323 ++++ standards/rfc3996.txt | 1739 ++ standards/rfc3997.txt | 955 + standards/rfc3998.txt | 2579 ++ standards/rfc4122.txt | 1795 ++ standards/rfc4234.txt | 899 + standards/rfctohtml.c | 504 + standards/wake-on-lan.pdf | Bin 0 -> 37276 bytes standards/wd-ippmailto10-20050519.pdf | Bin 0 -> 75741 bytes systemv/Dependencies | 55 + systemv/Makefile | 293 + systemv/cancel.c | 386 + systemv/cupsaccept.c | 249 + systemv/cupsaddsmb.c | 303 + systemv/cupsctl.c | 233 + systemv/cupstestdsc.c | 446 + systemv/cupstestppd.c | 3658 +++ systemv/lp.c | 744 + systemv/lpadmin.c | 1394 + systemv/lpinfo.c | 503 + systemv/lpmove.c | 221 + systemv/lpoptions.c | 552 + systemv/lppasswd.c | 501 + systemv/lpstat.c | 2011 ++ templates/Makefile | 201 + templates/add-class.tmpl | 40 + templates/add-printer.tmpl | 47 + templates/add-rss-subscription.tmpl | 44 + templates/admin.tmpl | 110 + templates/choose-device.tmpl | 53 + templates/choose-make.tmpl | 64 + templates/choose-model.tmpl | 60 + templates/choose-serial.tmpl | 52 + templates/choose-uri.tmpl | 44 + templates/class-added.tmpl | 8 + templates/class-confirm.tmpl | 10 + templates/class-deleted.tmpl | 7 + templates/class-jobs-header.tmpl | 3 + templates/class-modified.tmpl | 8 + templates/class.tmpl | 44 + templates/classes-header.tmpl | 1 + templates/classes.tmpl | 11 + templates/command.tmpl | 12 + templates/de/add-class.tmpl | 40 + templates/de/add-printer.tmpl | 47 + templates/de/add-rss-subscription.tmpl | 44 + templates/de/admin.tmpl | 110 + templates/de/choose-device.tmpl | 54 + templates/de/choose-make.tmpl | 64 + templates/de/choose-model.tmpl | 60 + templates/de/choose-serial.tmpl | 52 + templates/de/choose-uri.tmpl | 44 + templates/de/class-added.tmpl | 8 + templates/de/class-confirm.tmpl | 10 + templates/de/class-deleted.tmpl | 7 + templates/de/class-jobs-header.tmpl | 3 + templates/de/class-modified.tmpl | 8 + templates/de/class.tmpl | 44 + templates/de/classes-header.tmpl | 1 + templates/de/classes.tmpl | 11 + templates/de/command.tmpl | 12 + templates/de/edit-config.tmpl | 24 + templates/de/error-op.tmpl | 9 + templates/de/error.tmpl | 9 + templates/de/header.tmpl.in | 29 + templates/de/help-header.tmpl | 51 + templates/de/help-printable.tmpl | 9 + templates/de/help-trailer.tmpl | 1 + templates/de/job-cancel.tmpl | 7 + templates/de/job-hold.tmpl | 7 + templates/de/job-move.tmpl | 27 + templates/de/job-moved.tmpl | 8 + templates/de/job-release.tmpl | 7 + templates/de/job-restart.tmpl | 7 + templates/de/jobs-header.tmpl | 5 + templates/de/jobs.tmpl | 37 + templates/de/list-available-printers.tmpl | 11 + templates/de/modify-class.tmpl | 34 + templates/de/modify-printer.tmpl | 42 + templates/de/norestart.tmpl | 8 + templates/de/option-boolean.tmpl | 6 + templates/de/option-conflict.tmpl | 7 + templates/de/option-header.tmpl | 5 + templates/de/option-pickmany.tmpl | 6 + templates/de/option-pickone.tmpl | 18 + templates/de/option-trailer.tmpl | 5 + templates/de/pager.tmpl | 6 + templates/de/printer-accept.tmpl | 9 + templates/de/printer-added.tmpl | 8 + templates/de/printer-configured.tmpl | 8 + templates/de/printer-confirm.tmpl | 10 + templates/de/printer-default.tmpl | 13 + templates/de/printer-deleted.tmpl | 7 + templates/de/printer-jobs-header.tmpl | 3 + templates/de/printer-modified.tmpl | 8 + templates/de/printer-purge.tmpl | 9 + templates/de/printer-reject.tmpl | 9 + templates/de/printer-start.tmpl | 9 + templates/de/printer-stop.tmpl | 9 + templates/de/printer.tmpl | 47 + templates/de/printers-header.tmpl | 1 + templates/de/printers.tmpl | 11 + templates/de/restart.tmpl | 8 + templates/de/samba-export.tmpl | 55 + templates/de/samba-exported.tmpl | 1 + templates/de/search.tmpl | 10 + templates/de/set-printer-options-header.tmpl | 26 + templates/de/set-printer-options-trailer.tmpl | 16 + templates/de/subscription-added.tmpl | 5 + templates/de/subscription-canceled.tmpl | 5 + templates/de/test-page.tmpl | 8 + templates/de/trailer.tmpl | 8 + templates/de/users.tmpl | 30 + templates/edit-config.tmpl | 24 + templates/error-op.tmpl | 9 + templates/error.tmpl | 9 + templates/es/add-class.tmpl | 40 + templates/es/add-printer.tmpl | 47 + templates/es/add-rss-subscription.tmpl | 44 + templates/es/admin.tmpl | 110 + templates/es/choose-device.tmpl | 54 + templates/es/choose-make.tmpl | 64 + templates/es/choose-model.tmpl | 60 + templates/es/choose-serial.tmpl | 52 + templates/es/choose-uri.tmpl | 44 + templates/es/class-added.tmpl | 7 + templates/es/class-confirm.tmpl | 10 + templates/es/class-deleted.tmpl | 7 + templates/es/class-jobs-header.tmpl | 3 + templates/es/class-modified.tmpl | 6 + templates/es/class.tmpl | 44 + templates/es/classes-header.tmpl | 1 + templates/es/classes.tmpl | 11 + templates/es/command.tmpl | 12 + templates/es/edit-config.tmpl | 24 + templates/es/error-op.tmpl | 9 + templates/es/error.tmpl | 9 + templates/es/header.tmpl.in | 29 + templates/es/help-header.tmpl | 51 + templates/es/help-printable.tmpl | 9 + templates/es/help-trailer.tmpl | 1 + templates/es/job-cancel.tmpl | 7 + templates/es/job-hold.tmpl | 7 + templates/es/job-move.tmpl | 27 + templates/es/job-moved.tmpl | 8 + templates/es/job-release.tmpl | 7 + templates/es/job-restart.tmpl | 7 + templates/es/jobs-header.tmpl | 5 + templates/es/jobs.tmpl | 37 + templates/es/list-available-printers.tmpl | 11 + templates/es/modify-class.tmpl | 34 + templates/es/modify-printer.tmpl | 42 + templates/es/norestart.tmpl | 8 + templates/es/option-boolean.tmpl | 6 + templates/es/option-conflict.tmpl | 7 + templates/es/option-header.tmpl | 5 + templates/es/option-pickmany.tmpl | 6 + templates/es/option-pickone.tmpl | 18 + templates/es/option-trailer.tmpl | 5 + templates/es/pager.tmpl | 6 + templates/es/printer-accept.tmpl | 9 + templates/es/printer-added.tmpl | 7 + templates/es/printer-configured.tmpl | 8 + templates/es/printer-confirm.tmpl | 10 + templates/es/printer-default.tmpl | 13 + templates/es/printer-deleted.tmpl | 7 + templates/es/printer-jobs-header.tmpl | 3 + templates/es/printer-modified.tmpl | 7 + templates/es/printer-purge.tmpl | 8 + templates/es/printer-reject.tmpl | 9 + templates/es/printer-start.tmpl | 9 + templates/es/printer-stop.tmpl | 9 + templates/es/printer.tmpl | 47 + templates/es/printers-header.tmpl | 1 + templates/es/printers.tmpl | 11 + templates/es/restart.tmpl | 8 + templates/es/samba-export.tmpl | 55 + templates/es/samba-exported.tmpl | 1 + templates/es/search.tmpl | 10 + templates/es/set-printer-options-header.tmpl | 26 + templates/es/set-printer-options-trailer.tmpl | 16 + templates/es/subscription-added.tmpl | 5 + templates/es/subscription-canceled.tmpl | 5 + templates/es/test-page.tmpl | 8 + templates/es/trailer.tmpl | 8 + templates/es/users.tmpl | 30 + templates/eu/add-class.tmpl | 40 + templates/eu/add-printer.tmpl | 47 + templates/eu/add-rss-subscription.tmpl | 44 + templates/eu/admin.tmpl | 110 + templates/eu/choose-device.tmpl | 54 + templates/eu/choose-make.tmpl | 64 + templates/eu/choose-model.tmpl | 60 + templates/eu/choose-serial.tmpl | 52 + templates/eu/choose-uri.tmpl | 43 + templates/eu/class-added.tmpl | 7 + templates/eu/class-confirm.tmpl | 9 + templates/eu/class-deleted.tmpl | 7 + templates/eu/class-jobs-header.tmpl | 3 + templates/eu/class-modified.tmpl | 7 + templates/eu/class.tmpl | 44 + templates/eu/classes-header.tmpl | 1 + templates/eu/classes.tmpl | 11 + templates/eu/command.tmpl | 12 + templates/eu/edit-config.tmpl | 24 + templates/eu/error-op.tmpl | 9 + templates/eu/error.tmpl | 9 + templates/eu/header.tmpl.in | 29 + templates/eu/help-header.tmpl | 49 + templates/eu/help-printable.tmpl | 9 + templates/eu/help-trailer.tmpl | 1 + templates/eu/job-cancel.tmpl | 7 + templates/eu/job-hold.tmpl | 7 + templates/eu/job-move.tmpl | 27 + templates/eu/job-moved.tmpl | 8 + templates/eu/job-release.tmpl | 7 + templates/eu/job-restart.tmpl | 7 + templates/eu/jobs-header.tmpl | 5 + templates/eu/jobs.tmpl | 37 + templates/eu/list-available-printers.tmpl | 11 + templates/eu/modify-class.tmpl | 34 + templates/eu/modify-printer.tmpl | 42 + templates/eu/norestart.tmpl | 7 + templates/eu/option-boolean.tmpl | 6 + templates/eu/option-conflict.tmpl | 7 + templates/eu/option-header.tmpl | 5 + templates/eu/option-pickmany.tmpl | 6 + templates/eu/option-pickone.tmpl | 18 + templates/eu/option-trailer.tmpl | 5 + templates/eu/pager.tmpl | 6 + templates/eu/printer-accept.tmpl | 8 + templates/eu/printer-added.tmpl | 7 + templates/eu/printer-configured.tmpl | 8 + templates/eu/printer-confirm.tmpl | 9 + templates/eu/printer-default.tmpl | 11 + templates/eu/printer-deleted.tmpl | 7 + templates/eu/printer-jobs-header.tmpl | 3 + templates/eu/printer-modified.tmpl | 8 + templates/eu/printer-purge.tmpl | 8 + templates/eu/printer-reject.tmpl | 8 + templates/eu/printer-start.tmpl | 8 + templates/eu/printer-stop.tmpl | 8 + templates/eu/printer.tmpl | 47 + templates/eu/printers-header.tmpl | 1 + templates/eu/printers.tmpl | 11 + templates/eu/restart.tmpl | 8 + templates/eu/samba-export.tmpl | 54 + templates/eu/samba-exported.tmpl | 1 + templates/eu/search.tmpl | 10 + templates/eu/set-printer-options-header.tmpl | 26 + templates/eu/set-printer-options-trailer.tmpl | 16 + templates/eu/subscription-added.tmpl | 5 + templates/eu/subscription-canceled.tmpl | 5 + templates/eu/test-page.tmpl | 7 + templates/eu/trailer.tmpl | 8 + templates/eu/users.tmpl | 30 + templates/header.tmpl.in | 29 + templates/help-header.tmpl | 51 + templates/help-printable.tmpl | 9 + templates/help-trailer.tmpl | 1 + templates/id/add-class.tmpl | 40 + templates/id/add-printer.tmpl | 43 + templates/id/add-rss-subscription.tmpl | 44 + templates/id/admin.tmpl | 110 + templates/id/choose-device.tmpl | 54 + templates/id/choose-make.tmpl | 64 + templates/id/choose-model.tmpl | 60 + templates/id/choose-serial.tmpl | 52 + templates/id/choose-uri.tmpl | 43 + templates/id/class-added.tmpl | 7 + templates/id/class-confirm.tmpl | 10 + templates/id/class-deleted.tmpl | 7 + templates/id/class-jobs-header.tmpl | 3 + templates/id/class-modified.tmpl | 7 + templates/id/class.tmpl | 44 + templates/id/classes-header.tmpl | 1 + templates/id/classes.tmpl | 11 + templates/id/command.tmpl | 12 + templates/id/edit-config.tmpl | 24 + templates/id/error-op.tmpl | 9 + templates/id/error.tmpl | 9 + templates/id/header.tmpl.in | 29 + templates/id/help-header.tmpl | 47 + templates/id/help-printable.tmpl | 9 + templates/id/help-trailer.tmpl | 1 + templates/id/job-cancel.tmpl | 7 + templates/id/job-hold.tmpl | 7 + templates/id/job-move.tmpl | 27 + templates/id/job-moved.tmpl | 8 + templates/id/job-release.tmpl | 7 + templates/id/job-restart.tmpl | 7 + templates/id/jobs-header.tmpl | 5 + templates/id/jobs.tmpl | 36 + templates/id/list-available-printers.tmpl | 11 + templates/id/modify-class.tmpl | 34 + templates/id/modify-printer.tmpl | 38 + templates/id/norestart.tmpl | 7 + templates/id/option-boolean.tmpl | 6 + templates/id/option-conflict.tmpl | 7 + templates/id/option-header.tmpl | 5 + templates/id/option-pickmany.tmpl | 6 + templates/id/option-pickone.tmpl | 18 + templates/id/option-trailer.tmpl | 5 + templates/id/pager.tmpl | 6 + templates/id/printer-accept.tmpl | 9 + templates/id/printer-added.tmpl | 7 + templates/id/printer-configured.tmpl | 8 + templates/id/printer-confirm.tmpl | 10 + templates/id/printer-default.tmpl | 11 + templates/id/printer-deleted.tmpl | 7 + templates/id/printer-jobs-header.tmpl | 3 + templates/id/printer-modified.tmpl | 7 + templates/id/printer-purge.tmpl | 9 + templates/id/printer-reject.tmpl | 9 + templates/id/printer-start.tmpl | 9 + templates/id/printer-stop.tmpl | 9 + templates/id/printer.tmpl | 47 + templates/id/printers-header.tmpl | 1 + templates/id/printers.tmpl | 11 + templates/id/restart.tmpl | 8 + templates/id/samba-export.tmpl | 55 + templates/id/samba-exported.tmpl | 1 + templates/id/search.tmpl | 10 + templates/id/set-printer-options-header.tmpl | 26 + templates/id/set-printer-options-trailer.tmpl | 16 + templates/id/subscription-added.tmpl | 5 + templates/id/subscription-canceled.tmpl | 5 + templates/id/test-page.tmpl | 8 + templates/id/trailer.tmpl | 8 + templates/id/users.tmpl | 30 + templates/it/add-class.tmpl | 40 + templates/it/add-printer.tmpl | 43 + templates/it/add-rss-subscription.tmpl | 44 + templates/it/admin.tmpl | 110 + templates/it/choose-device.tmpl | 54 + templates/it/choose-make.tmpl | 64 + templates/it/choose-model.tmpl | 60 + templates/it/choose-serial.tmpl | 52 + templates/it/choose-uri.tmpl | 44 + templates/it/class-added.tmpl | 8 + templates/it/class-confirm.tmpl | 10 + templates/it/class-deleted.tmpl | 7 + templates/it/class-jobs-header.tmpl | 3 + templates/it/class-modified.tmpl | 8 + templates/it/class.tmpl | 44 + templates/it/classes-header.tmpl | 1 + templates/it/classes.tmpl | 11 + templates/it/command.tmpl | 12 + templates/it/edit-config.tmpl | 24 + templates/it/error-op.tmpl | 9 + templates/it/error.tmpl | 9 + templates/it/help-header.tmpl | 50 + templates/it/help-printable.tmpl | 9 + templates/it/help-trailer.tmpl | 1 + templates/it/job-cancel.tmpl | 7 + templates/it/job-hold.tmpl | 7 + templates/it/job-move.tmpl | 27 + templates/it/job-moved.tmpl | 8 + templates/it/job-release.tmpl | 7 + templates/it/job-restart.tmpl | 7 + templates/it/jobs-header.tmpl | 5 + templates/it/jobs.tmpl | 37 + templates/it/list-available-printers.tmpl | 11 + templates/it/modify-class.tmpl | 34 + templates/it/modify-printer.tmpl | 38 + templates/it/norestart.tmpl | 7 + templates/it/option-boolean.tmpl | 6 + templates/it/option-conflict.tmpl | 7 + templates/it/option-header.tmpl | 5 + templates/it/option-pickmany.tmpl | 6 + templates/it/option-pickone.tmpl | 18 + templates/it/option-trailer.tmpl | 5 + templates/it/pager.tmpl | 6 + templates/it/printer-accept.tmpl | 9 + templates/it/printer-added.tmpl | 7 + templates/it/printer-configured.tmpl | 8 + templates/it/printer-confirm.tmpl | 10 + templates/it/printer-default.tmpl | 12 + templates/it/printer-deleted.tmpl | 7 + templates/it/printer-jobs-header.tmpl | 3 + templates/it/printer-modified.tmpl | 8 + templates/it/printer-purge.tmpl | 9 + templates/it/printer-reject.tmpl | 9 + templates/it/printer-start.tmpl | 9 + templates/it/printer-stop.tmpl | 9 + templates/it/printer.tmpl | 47 + templates/it/printers-header.tmpl | 1 + templates/it/printers.tmpl | 11 + templates/it/restart.tmpl | 8 + templates/it/samba-export.tmpl | 54 + templates/it/samba-exported.tmpl | 1 + templates/it/search.tmpl | 10 + templates/it/set-printer-options-header.tmpl | 26 + templates/it/set-printer-options-trailer.tmpl | 16 + templates/it/subscription-added.tmpl | 5 + templates/it/subscription-canceled.tmpl | 5 + templates/it/test-page.tmpl | 8 + templates/it/trailer.tmpl | 8 + templates/it/users.tmpl | 30 + templates/ja/add-class.tmpl | 40 + templates/ja/add-printer.tmpl | 47 + templates/ja/add-rss-subscription.tmpl | 44 + templates/ja/admin.tmpl | 110 + templates/ja/choose-device.tmpl | 54 + templates/ja/choose-make.tmpl | 64 + templates/ja/choose-model.tmpl | 60 + templates/ja/choose-serial.tmpl | 52 + templates/ja/choose-uri.tmpl | 43 + templates/ja/class-added.tmpl | 7 + templates/ja/class-confirm.tmpl | 10 + templates/ja/class-deleted.tmpl | 7 + templates/ja/class-jobs-header.tmpl | 3 + templates/ja/class-modified.tmpl | 7 + templates/ja/class.tmpl | 44 + templates/ja/classes-header.tmpl | 1 + templates/ja/classes.tmpl | 11 + templates/ja/command.tmpl | 12 + templates/ja/edit-config.tmpl | 24 + templates/ja/error-op.tmpl | 9 + templates/ja/error.tmpl | 9 + templates/ja/header.tmpl.in | 29 + templates/ja/help-header.tmpl | 51 + templates/ja/help-printable.tmpl | 9 + templates/ja/help-trailer.tmpl | 1 + templates/ja/job-cancel.tmpl | 7 + templates/ja/job-hold.tmpl | 6 + templates/ja/job-move.tmpl | 27 + templates/ja/job-moved.tmpl | 8 + templates/ja/job-release.tmpl | 7 + templates/ja/job-restart.tmpl | 7 + templates/ja/jobs-header.tmpl | 5 + templates/ja/jobs.tmpl | 37 + templates/ja/list-available-printers.tmpl | 11 + templates/ja/modify-class.tmpl | 34 + templates/ja/modify-printer.tmpl | 42 + templates/ja/norestart.tmpl | 7 + templates/ja/option-boolean.tmpl | 6 + templates/ja/option-conflict.tmpl | 7 + templates/ja/option-header.tmpl | 5 + templates/ja/option-pickmany.tmpl | 6 + templates/ja/option-pickone.tmpl | 18 + templates/ja/option-trailer.tmpl | 5 + templates/ja/pager.tmpl | 6 + templates/ja/printer-accept.tmpl | 9 + templates/ja/printer-added.tmpl | 6 + templates/ja/printer-configured.tmpl | 7 + templates/ja/printer-confirm.tmpl | 9 + templates/ja/printer-default.tmpl | 12 + templates/ja/printer-deleted.tmpl | 6 + templates/ja/printer-jobs-header.tmpl | 3 + templates/ja/printer-modified.tmpl | 7 + templates/ja/printer-purge.tmpl | 9 + templates/ja/printer-reject.tmpl | 9 + templates/ja/printer-start.tmpl | 9 + templates/ja/printer-stop.tmpl | 8 + templates/ja/printer.tmpl | 47 + templates/ja/printers-header.tmpl | 1 + templates/ja/printers.tmpl | 11 + templates/ja/restart.tmpl | 8 + templates/ja/samba-export.tmpl | 56 + templates/ja/samba-exported.tmpl | 1 + templates/ja/search.tmpl | 10 + templates/ja/set-printer-options-header.tmpl | 26 + templates/ja/set-printer-options-trailer.tmpl | 16 + templates/ja/subscription-added.tmpl | 5 + templates/ja/subscription-canceled.tmpl | 5 + templates/ja/test-page.tmpl | 8 + templates/ja/trailer.tmpl | 8 + templates/ja/users.tmpl | 30 + templates/job-cancel.tmpl | 7 + templates/job-hold.tmpl | 7 + templates/job-move.tmpl | 27 + templates/job-moved.tmpl | 8 + templates/job-release.tmpl | 7 + templates/job-restart.tmpl | 7 + templates/jobs-header.tmpl | 5 + templates/jobs.tmpl | 36 + templates/list-available-printers.tmpl | 11 + templates/modify-class.tmpl | 34 + templates/modify-printer.tmpl | 42 + templates/norestart.tmpl | 8 + templates/option-boolean.tmpl | 6 + templates/option-conflict.tmpl | 7 + templates/option-header.tmpl | 5 + templates/option-pickmany.tmpl | 6 + templates/option-pickone.tmpl | 18 + templates/option-trailer.tmpl | 5 + templates/pager.tmpl | 6 + templates/pl/add-class.tmpl | 40 + templates/pl/add-printer.tmpl | 47 + templates/pl/add-rss-subscription.tmpl | 44 + templates/pl/admin.tmpl | 110 + templates/pl/choose-device.tmpl | 54 + templates/pl/choose-make.tmpl | 64 + templates/pl/choose-model.tmpl | 60 + templates/pl/choose-serial.tmpl | 52 + templates/pl/choose-uri.tmpl | 44 + templates/pl/class-added.tmpl | 8 + templates/pl/class-confirm.tmpl | 10 + templates/pl/class-deleted.tmpl | 7 + templates/pl/class-jobs-header.tmpl | 3 + templates/pl/class-modified.tmpl | 8 + templates/pl/class.tmpl | 44 + templates/pl/classes-header.tmpl | 1 + templates/pl/classes.tmpl | 11 + templates/pl/command.tmpl | 12 + templates/pl/edit-config.tmpl | 24 + templates/pl/error-op.tmpl | 9 + templates/pl/error.tmpl | 9 + templates/pl/header.tmpl.in | 29 + templates/pl/help-header.tmpl | 51 + templates/pl/help-printable.tmpl | 9 + templates/pl/help-trailer.tmpl | 1 + templates/pl/job-cancel.tmpl | 7 + templates/pl/job-hold.tmpl | 7 + templates/pl/job-move.tmpl | 27 + templates/pl/job-moved.tmpl | 8 + templates/pl/job-release.tmpl | 7 + templates/pl/job-restart.tmpl | 7 + templates/pl/jobs-header.tmpl | 5 + templates/pl/jobs.tmpl | 37 + templates/pl/list-available-printers.tmpl | 11 + templates/pl/modify-class.tmpl | 34 + templates/pl/modify-printer.tmpl | 42 + templates/pl/norestart.tmpl | 8 + templates/pl/option-boolean.tmpl | 6 + templates/pl/option-conflict.tmpl | 7 + templates/pl/option-header.tmpl | 5 + templates/pl/option-pickmany.tmpl | 6 + templates/pl/option-pickone.tmpl | 18 + templates/pl/option-trailer.tmpl | 5 + templates/pl/pager.tmpl | 6 + templates/pl/printer-accept.tmpl | 9 + templates/pl/printer-added.tmpl | 8 + templates/pl/printer-configured.tmpl | 8 + templates/pl/printer-confirm.tmpl | 10 + templates/pl/printer-default.tmpl | 13 + templates/pl/printer-deleted.tmpl | 7 + templates/pl/printer-jobs-header.tmpl | 3 + templates/pl/printer-modified.tmpl | 8 + templates/pl/printer-purge.tmpl | 9 + templates/pl/printer-reject.tmpl | 9 + templates/pl/printer-start.tmpl | 9 + templates/pl/printer-stop.tmpl | 9 + templates/pl/printer.tmpl | 47 + templates/pl/printers-header.tmpl | 1 + templates/pl/printers.tmpl | 11 + templates/pl/restart.tmpl | 8 + templates/pl/samba-export.tmpl | 55 + templates/pl/samba-exported.tmpl | 1 + templates/pl/search.tmpl | 10 + templates/pl/set-printer-options-header.tmpl | 26 + templates/pl/set-printer-options-trailer.tmpl | 16 + templates/pl/subscription-added.tmpl | 5 + templates/pl/subscription-canceled.tmpl | 5 + templates/pl/test-page.tmpl | 8 + templates/pl/trailer.tmpl | 8 + templates/pl/users.tmpl | 30 + templates/printer-accept.tmpl | 9 + templates/printer-added.tmpl | 8 + templates/printer-configured.tmpl | 8 + templates/printer-confirm.tmpl | 10 + templates/printer-default.tmpl | 13 + templates/printer-deleted.tmpl | 7 + templates/printer-jobs-header.tmpl | 3 + templates/printer-modified.tmpl | 8 + templates/printer-purge.tmpl | 9 + templates/printer-reject.tmpl | 9 + templates/printer-start.tmpl | 9 + templates/printer-stop.tmpl | 9 + templates/printer.tmpl | 47 + templates/printers-header.tmpl | 1 + templates/printers.tmpl | 11 + templates/restart.tmpl | 8 + templates/ru/Makefile | 201 + templates/ru/add-class.tmpl | 40 + templates/ru/add-printer.tmpl | 47 + templates/ru/add-rss-subscription.tmpl | 44 + templates/ru/admin.tmpl | 110 + templates/ru/choose-device.tmpl | 54 + templates/ru/choose-make.tmpl | 64 + templates/ru/choose-model.tmpl | 59 + templates/ru/choose-serial.tmpl | 52 + templates/ru/choose-uri.tmpl | 43 + templates/ru/class-added.tmpl | 7 + templates/ru/class-confirm.tmpl | 10 + templates/ru/class-deleted.tmpl | 7 + templates/ru/class-jobs-header.tmpl | 3 + templates/ru/class-modified.tmpl | 7 + templates/ru/class.tmpl | 44 + templates/ru/classes-header.tmpl | 1 + templates/ru/classes.tmpl | 11 + templates/ru/command.tmpl | 12 + templates/ru/edit-config.tmpl | 24 + templates/ru/error-op.tmpl | 9 + templates/ru/error.tmpl | 9 + templates/ru/header.tmpl.in | 29 + templates/ru/help-header.tmpl | 46 + templates/ru/help-printable.tmpl | 9 + templates/ru/help-trailer.tmpl | 1 + templates/ru/job-cancel.tmpl | 7 + templates/ru/job-hold.tmpl | 7 + templates/ru/job-move.tmpl | 27 + templates/ru/job-moved.tmpl | 7 + templates/ru/job-release.tmpl | 7 + templates/ru/job-restart.tmpl | 7 + templates/ru/jobs-header.tmpl | 6 + templates/ru/jobs.tmpl | 37 + templates/ru/list-available-printers.tmpl | 11 + templates/ru/modify-class.tmpl | 34 + templates/ru/modify-printer.tmpl | 42 + templates/ru/norestart.tmpl | 7 + templates/ru/option-boolean.tmpl | 6 + templates/ru/option-conflict.tmpl | 7 + templates/ru/option-header.tmpl | 5 + templates/ru/option-pickmany.tmpl | 6 + templates/ru/option-pickone.tmpl | 18 + templates/ru/option-trailer.tmpl | 5 + templates/ru/pager.tmpl | 6 + templates/ru/printer-accept.tmpl | 9 + templates/ru/printer-added.tmpl | 8 + templates/ru/printer-configured.tmpl | 8 + templates/ru/printer-confirm.tmpl | 10 + templates/ru/printer-default.tmpl | 12 + templates/ru/printer-deleted.tmpl | 7 + templates/ru/printer-jobs-header.tmpl | 3 + templates/ru/printer-modified.tmpl | 8 + templates/ru/printer-purge.tmpl | 9 + templates/ru/printer-reject.tmpl | 9 + templates/ru/printer-start.tmpl | 9 + templates/ru/printer-stop.tmpl | 9 + templates/ru/printer.tmpl | 47 + templates/ru/printers-header.tmpl | 1 + templates/ru/printers.tmpl | 11 + templates/ru/restart.tmpl | 8 + templates/ru/samba-export.tmpl | 54 + templates/ru/samba-exported.tmpl | 1 + templates/ru/search.tmpl | 10 + templates/ru/set-printer-options-header.tmpl | 26 + templates/ru/set-printer-options-trailer.tmpl | 16 + templates/ru/subscription-added.tmpl | 5 + templates/ru/subscription-canceled.tmpl | 5 + templates/ru/test-page.tmpl | 8 + templates/ru/trailer.tmpl | 6 + templates/ru/users.tmpl | 30 + templates/samba-export.tmpl | 55 + templates/samba-exported.tmpl | 1 + templates/search.tmpl | 10 + templates/set-printer-options-header.tmpl | 26 + templates/set-printer-options-trailer.tmpl | 16 + templates/subscription-added.tmpl | 5 + templates/subscription-canceled.tmpl | 5 + templates/test-page.tmpl | 8 + templates/trailer.tmpl | 8 + templates/users.tmpl | 30 + test/4.1-requests.test | 159 + test/4.2-cups-printer-ops.test | 327 + test/4.3-job-ops.test | 330 + test/4.4-subscription-ops.test | 148 + test/5.1-lpadmin.sh | 55 + test/5.2-lpc.sh | 31 + test/5.3-lpq.sh | 31 + test/5.4-lpstat.sh | 43 + test/5.5-lp.sh | 86 + test/5.6-lpr.sh | 86 + test/5.7-lprm.sh | 47 + test/5.8-cancel.sh | 45 + test/5.9-lpinfo.sh | 55 + test/Dependencies | 5 + test/Makefile | 117 + test/create-job-format.test | 56 + test/create-job-sheets.test | 55 + test/create-job-timeout.test | 54 + test/create-job.test | 52 + test/create-printer-subscription.test | 36 + test/get-devices.test | 21 + test/get-job-attributes.test | 27 + test/get-job-attributes2.test | 28 + test/get-jobs.test | 21 + test/get-ppd-printer.test | 20 + test/get-ppd.test | 20 + test/get-ppds-drv-only.test | 24 + test/get-ppds-language.test | 21 + test/get-ppds-make-and-model.test | 21 + test/get-ppds-make.test | 21 + test/get-ppds-product.test | 21 + test/get-ppds-psversion.test | 21 + test/get-ppds.test | 21 + test/get-printer-attributes-2.0.test | 48 + test/get-printer-attributes.test | 41 + test/get-printers.test | 19 + test/get-subscriptions.test | 21 + test/ipp-backend.test | 22 + test/ipptest.c | 1278 + test/print-job-hold.test | 33 + test/print-job-media-col.test | 39 + test/print-job.test | 32 + test/run-stp-tests.sh | 869 + test/set-attrs-hold.test | 180 + test/str-header.html | 31 + test/str-trailer.html | 2 + test/testfile.jpg | Bin 0 -> 204156 bytes test/testfile.pdf | Bin 0 -> 279746 bytes test/testfile.ps | 598 + test/testfile.txt | 60 + test/testhp.ppd | 186 + test/testps.ppd | 183 + test/waitjobs.sh | 60 + tools/checkglobals | 32 + tools/listpublic | 12 + tools/makesrcdist | 91 + tools/products.php | 50 + tools/testosx | 137 + tools/testrpm | 32 + vc2005/cups.sln | 78 + vc2005/cupstestppd.vcproj | 356 + vc2005/libcups2.vcproj | 1587 + vc2005/libcupsimage2.vcproj | 395 + vc2005/testfile.vcproj | 202 + vc2005/testhttp.vcproj | 202 + vcnet/config.h | 705 + vcnet/cups.sln | 78 + vcnet/cupstestppd.vcproj | 353 + vcnet/libcups2.vcproj | 1588 + vcnet/libcupsimage2.vcproj | 388 + vcnet/testfile.vcproj | 201 + vcnet/testhttp.vcproj | 201 + 1470 files changed, 735010 insertions(+) create mode 100644 CHANGES-1.0.txt create mode 100644 CHANGES-1.1.txt create mode 100644 CHANGES-1.2.txt create mode 100644 CHANGES-1.3.txt create mode 100644 CHANGES.txt create mode 100644 CREDITS.txt create mode 100644 INSTALL.txt create mode 100644 LICENSE.txt create mode 100644 Makedefs.in create mode 100644 Makefile create mode 100644 README.txt create mode 100644 backend/Dependencies create mode 100644 backend/Makefile create mode 100644 backend/backend-private.h create mode 100644 backend/dnssd.c create mode 100644 backend/easysw-firewire-design.txt create mode 100644 backend/easysw-firewire-linux.txt create mode 100644 backend/ieee1284.c create mode 100644 backend/ipp.c create mode 100644 backend/lpd.c create mode 100644 backend/network.c create mode 100644 backend/pap.c create mode 100644 backend/parallel.c create mode 100644 backend/runloop.c create mode 100644 backend/scsi-irix.c create mode 100644 backend/scsi-linux.c create mode 100644 backend/scsi.c create mode 100644 backend/serial.c create mode 100644 backend/snmp-supplies.c create mode 100644 backend/snmp.c create mode 100644 backend/snmp.txt create mode 100644 backend/socket.c create mode 100644 backend/test1284.c create mode 100644 backend/testbackend.c create mode 100644 backend/testsupplies.c create mode 100644 backend/usb-darwin.c create mode 100644 backend/usb-libusb.c create mode 100644 backend/usb-unix.c create mode 100644 backend/usb.c create mode 100644 berkeley/Dependencies create mode 100644 berkeley/Makefile create mode 100644 berkeley/lpc.c create mode 100644 berkeley/lpq.c create mode 100644 berkeley/lpr.c create mode 100644 berkeley/lprm.c create mode 100644 cgi-bin/Dependencies create mode 100644 cgi-bin/Makefile create mode 100644 cgi-bin/admin.c create mode 100644 cgi-bin/api-cgi.header create mode 100644 cgi-bin/api-cgi.shtml create mode 100644 cgi-bin/cgi-private.h create mode 100644 cgi-bin/cgi.h create mode 100644 cgi-bin/classes.c create mode 100644 cgi-bin/help-index.c create mode 100644 cgi-bin/help-index.h create mode 100644 cgi-bin/help.c create mode 100644 cgi-bin/html.c create mode 100644 cgi-bin/ipp-var.c create mode 100644 cgi-bin/jobs.c create mode 100644 cgi-bin/libcupscgi.exp create mode 100644 cgi-bin/makedocset.c create mode 100644 cgi-bin/multipart.dat create mode 100644 cgi-bin/printers.c create mode 100644 cgi-bin/search.c create mode 100644 cgi-bin/template.c create mode 100644 cgi-bin/testcgi.c create mode 100644 cgi-bin/testhi.c create mode 100644 cgi-bin/testhi.html create mode 100644 cgi-bin/testtemplate.c create mode 100644 cgi-bin/var.c create mode 100644 cgi-bin/websearch.c create mode 100644 conf/Makefile create mode 100644 conf/cupsd.conf.in create mode 100644 conf/mime.convs.in create mode 100644 conf/mime.types create mode 100644 conf/pam.opendirectory create mode 100644 conf/pam.securityserver create mode 100644 conf/pam.std.in create mode 100644 conf/snmp.conf.in create mode 100644 config-scripts/cups-3264.m4 create mode 100644 config-scripts/cups-common.m4 create mode 100644 config-scripts/cups-compiler.m4 create mode 100644 config-scripts/cups-defaults.m4 create mode 100644 config-scripts/cups-directories.m4 create mode 100644 config-scripts/cups-dnssd.m4 create mode 100644 config-scripts/cups-gssapi.m4 create mode 100644 config-scripts/cups-image.m4 create mode 100644 config-scripts/cups-largefile.m4 create mode 100644 config-scripts/cups-launchd.m4 create mode 100644 config-scripts/cups-ldap.m4 create mode 100644 config-scripts/cups-libtool.m4 create mode 100644 config-scripts/cups-manpages.m4 create mode 100644 config-scripts/cups-network.m4 create mode 100644 config-scripts/cups-opsys.m4 create mode 100644 config-scripts/cups-pam.m4 create mode 100644 config-scripts/cups-pap.m4 create mode 100644 config-scripts/cups-pdf.m4 create mode 100644 config-scripts/cups-poll.m4 create mode 100644 config-scripts/cups-scripting.m4 create mode 100644 config-scripts/cups-sharedlibs.m4 create mode 100644 config-scripts/cups-slp.m4 create mode 100644 config-scripts/cups-ssl.m4 create mode 100644 config-scripts/cups-threads.m4 create mode 100644 config.h.in create mode 100644 configure.in create mode 100755 cups-config.in create mode 100644 cups/Dependencies create mode 100644 cups/Makefile create mode 100644 cups/adminutil.c create mode 100644 cups/adminutil.h create mode 100644 cups/api-array.header create mode 100644 cups/api-array.shtml create mode 100644 cups/api-cups.header create mode 100644 cups/api-cups.shtml create mode 100644 cups/api-filedir.header create mode 100644 cups/api-filedir.shtml create mode 100644 cups/api-filter.header create mode 100644 cups/api-filter.shtml create mode 100644 cups/api-httpipp.header create mode 100644 cups/api-httpipp.shtml create mode 100644 cups/api-overview.header create mode 100644 cups/api-overview.shtml create mode 100644 cups/api-ppd.header create mode 100644 cups/api-ppd.shtml create mode 100644 cups/array.c create mode 100644 cups/array.h create mode 100644 cups/attr.c create mode 100644 cups/auth.c create mode 100644 cups/backchannel.c create mode 100644 cups/backend.c create mode 100644 cups/backend.h create mode 100644 cups/conflicts.c create mode 100644 cups/cups.h create mode 100644 cups/custom.c create mode 100644 cups/debug.c create mode 100644 cups/debug.h create mode 100644 cups/dest.c create mode 100644 cups/dir.c create mode 100644 cups/dir.h create mode 100644 cups/emit.c create mode 100644 cups/encode.c create mode 100644 cups/file-private.h create mode 100644 cups/file.c create mode 100644 cups/file.h create mode 100644 cups/getdevices.c create mode 100644 cups/getifaddrs.c create mode 100644 cups/getputfile.c create mode 100644 cups/globals.c create mode 100644 cups/globals.h create mode 100644 cups/http-addr.c create mode 100644 cups/http-addrlist.c create mode 100644 cups/http-private.h create mode 100644 cups/http-support.c create mode 100644 cups/http.c create mode 100644 cups/http.h create mode 100644 cups/i18n.h create mode 100644 cups/ipp-private.h create mode 100644 cups/ipp-support.c create mode 100644 cups/ipp.c create mode 100644 cups/ipp.h create mode 100644 cups/langprintf.c create mode 100644 cups/language.c create mode 100644 cups/language.h create mode 100644 cups/libcups.exp create mode 100755 cups/libcups.order create mode 100644 cups/libcups2.def create mode 100644 cups/libcups_s.exp create mode 100644 cups/localize.c create mode 100644 cups/mark.c create mode 100644 cups/md5-apple.h create mode 100644 cups/md5.c create mode 100644 cups/md5.h create mode 100644 cups/md5passwd.c create mode 100644 cups/notify.c create mode 100644 cups/options.c create mode 100644 cups/page.c create mode 100644 cups/ppd-private.h create mode 100644 cups/ppd.c create mode 100644 cups/ppd.h create mode 100644 cups/pwg-file.c create mode 100644 cups/pwg-media.c create mode 100644 cups/pwg-ppd.c create mode 100644 cups/pwg-private.h create mode 100644 cups/raster.h create mode 100644 cups/request.c create mode 100644 cups/sidechannel.c create mode 100644 cups/sidechannel.h create mode 100644 cups/snmp-private.h create mode 100644 cups/snmp.c create mode 100644 cups/snprintf.c create mode 100644 cups/string.c create mode 100644 cups/string.h create mode 100644 cups/tempfile.c create mode 100644 cups/test.ppd create mode 100644 cups/test2.ppd create mode 100644 cups/testadmin.c create mode 100644 cups/testarray.c create mode 100644 cups/testconflicts.c create mode 100644 cups/testcups.c create mode 100644 cups/testfile.c create mode 100644 cups/testhttp.c create mode 100644 cups/testi18n.c create mode 100644 cups/testipp.c create mode 100644 cups/testlang.c create mode 100644 cups/testoptions.c create mode 100644 cups/testppd.c create mode 100644 cups/testpwg.c create mode 100644 cups/testsnmp.c create mode 100644 cups/transcode.c create mode 100644 cups/transcode.h create mode 100644 cups/usersys.c create mode 100644 cups/utf8demo.txt create mode 100644 cups/util.c create mode 100644 cups/versioning.h create mode 100644 data/HPGLprolog create mode 100644 data/Makefile create mode 100644 data/classified create mode 100644 data/confidential create mode 100644 data/cups.irix create mode 100644 data/cups.pam create mode 100644 data/cups.suse create mode 100644 data/epson.h create mode 100644 data/escp.h create mode 100644 data/euc-cn.txt create mode 100644 data/euc-jp.txt create mode 100644 data/euc-kr.txt create mode 100644 data/euc-tw.txt create mode 100644 data/font.defs create mode 100644 data/hp.h create mode 100644 data/iso-8859-1.txt create mode 100644 data/iso-8859-10.txt create mode 100644 data/iso-8859-11.txt create mode 100644 data/iso-8859-13.txt create mode 100644 data/iso-8859-14.txt create mode 100644 data/iso-8859-15.txt create mode 100644 data/iso-8859-16.txt create mode 100644 data/iso-8859-2.txt create mode 100644 data/iso-8859-3.txt create mode 100644 data/iso-8859-4.txt create mode 100644 data/iso-8859-5.txt create mode 100644 data/iso-8859-6.txt create mode 100644 data/iso-8859-7.txt create mode 100644 data/iso-8859-8.txt create mode 100644 data/iso-8859-9.txt create mode 100644 data/jis-x0213.txt create mode 100644 data/koi8-r.txt create mode 100644 data/koi8-u.txt create mode 100644 data/label.h create mode 100644 data/mac-roman.txt create mode 100644 data/media.defs create mode 100644 data/pcl.h create mode 100644 data/psglyphs create mode 100644 data/raster.defs create mode 100644 data/secret create mode 100644 data/smiley.ps create mode 100644 data/standard create mode 100644 data/testprint.in create mode 100644 data/topsecret create mode 100644 data/unclassified create mode 100644 data/utf-8 create mode 100644 data/windows-1250.txt create mode 100644 data/windows-1251.txt create mode 100644 data/windows-1252.txt create mode 100644 data/windows-1253.txt create mode 100644 data/windows-1254.txt create mode 100644 data/windows-1255.txt create mode 100644 data/windows-1256.txt create mode 100644 data/windows-1257.txt create mode 100644 data/windows-1258.txt create mode 100644 data/windows-1361.txt create mode 100644 data/windows-874.txt create mode 100644 data/windows-932.txt create mode 100644 data/windows-936.txt create mode 100644 data/windows-949.txt create mode 100644 data/windows-950.txt create mode 100644 desktop/cups-128.png create mode 100644 desktop/cups-16.png create mode 100644 desktop/cups-256.png create mode 100644 desktop/cups-32.png create mode 100644 desktop/cups-512.png create mode 100644 desktop/cups-64.png create mode 100644 desktop/cups.desktop.in create mode 100644 desktop/cups.icns create mode 100644 desktop/cups.svg create mode 100644 doc/Makefile create mode 100644 doc/cups-printable.css create mode 100644 doc/cups.css create mode 100644 doc/de/index.html.in create mode 100755 doc/es/index.html.in create mode 100644 doc/eu/index.html.in create mode 100644 doc/help/accounting.html create mode 100644 doc/help/api-array.html create mode 100644 doc/help/api-cgi.html create mode 100644 doc/help/api-cups.html create mode 100644 doc/help/api-driver.html create mode 100644 doc/help/api-filedir.html create mode 100644 doc/help/api-filter.html create mode 100644 doc/help/api-httpipp.html create mode 100644 doc/help/api-mime.html create mode 100644 doc/help/api-overview.html create mode 100644 doc/help/api-ppd.html create mode 100644 doc/help/api-ppdc.html create mode 100644 doc/help/api-raster.html create mode 100644 doc/help/cgi.html create mode 100644 doc/help/glossary.html create mode 100644 doc/help/kerberos.html create mode 100644 doc/help/license.html create mode 100644 doc/help/network.html create mode 100644 doc/help/options.html create mode 100644 doc/help/overview.html create mode 100644 doc/help/policies.html create mode 100644 doc/help/postscript-driver.html create mode 100644 doc/help/ppd-compiler.html create mode 100644 doc/help/raster-driver.html create mode 100644 doc/help/ref-access_log.html create mode 100644 doc/help/ref-classes-conf.html create mode 100644 doc/help/ref-client-conf.html create mode 100644 doc/help/ref-cupsd-conf.html.in create mode 100644 doc/help/ref-error_log.html create mode 100644 doc/help/ref-mailto-conf.html create mode 100644 doc/help/ref-page_log.html create mode 100644 doc/help/ref-ppdcfile.html create mode 100644 doc/help/ref-printers-conf.html create mode 100644 doc/help/ref-snmp-conf.html create mode 100644 doc/help/ref-subscriptions-conf.html create mode 100644 doc/help/security.html create mode 100644 doc/help/sharing.html create mode 100644 doc/help/spec-banner.html create mode 100644 doc/help/spec-browsing.html create mode 100644 doc/help/spec-cmp.html create mode 100644 doc/help/spec-command.html create mode 100644 doc/help/spec-design.html create mode 100644 doc/help/spec-ipp.html create mode 100644 doc/help/spec-pdf.html create mode 100644 doc/help/spec-postscript.html create mode 100644 doc/help/spec-ppd.html create mode 100644 doc/help/spec-raster.html create mode 100644 doc/help/spec-stp.html create mode 100644 doc/help/standard.html.in create mode 100644 doc/help/translation.html create mode 100644 doc/help/whatsnew.html create mode 100644 doc/id/index.html.in create mode 100644 doc/images/color-wheel.png create mode 100644 doc/images/cups-block-diagram.png create mode 100644 doc/images/cups-block-diagram.svg create mode 100644 doc/images/cups-command-chain.png create mode 100644 doc/images/cups-command-chain.svg create mode 100644 doc/images/cups-icon.png create mode 100644 doc/images/cups-postscript-chain.png create mode 100644 doc/images/cups-postscript-chain.svg create mode 100644 doc/images/cups-raster-chain.png create mode 100644 doc/images/cups-raster-chain.svg create mode 100644 doc/images/cups.png create mode 100644 doc/images/cups.svg create mode 100644 doc/images/generic.png create mode 100644 doc/images/left.gif create mode 100644 doc/images/left.xcf.gz create mode 100644 doc/images/raster-organization.png create mode 100644 doc/images/raster-organization.svg create mode 100644 doc/images/raster.png create mode 100644 doc/images/raster.svg create mode 100644 doc/images/right.gif create mode 100644 doc/images/sample-image.png create mode 100644 doc/images/sel.gif create mode 100644 doc/images/smiley.jpg create mode 100644 doc/images/unsel.gif create mode 100644 doc/images/wait.gif create mode 100644 doc/images/webinterface.png create mode 100644 doc/index.html.in create mode 100644 doc/it/index.html.in create mode 100644 doc/ja/index.html.in create mode 100644 doc/pl/index.html.in create mode 100644 doc/robots.txt create mode 100644 doc/ru/index.html.in create mode 100644 driver/Dependencies create mode 100644 driver/Makefile create mode 100644 driver/api-driver.header create mode 100644 driver/api-driver.shtml create mode 100644 driver/attr.c create mode 100644 driver/check.c create mode 100644 driver/cmyk.c create mode 100644 driver/commandtoescpx.c create mode 100644 driver/commandtopclx.c create mode 100644 driver/dither.c create mode 100644 driver/driver.h create mode 100644 driver/image.pgm create mode 100644 driver/image.ppm create mode 100644 driver/libcupsdriver.exp create mode 100644 driver/lut.c create mode 100644 driver/pack.c create mode 100644 driver/pcl-common.c create mode 100644 driver/pcl-common.h create mode 100644 driver/rastertoescpx.c create mode 100644 driver/rastertopclx.c create mode 100644 driver/rgb.c create mode 100644 driver/srgb.c create mode 100644 driver/testcmyk.c create mode 100644 driver/testdither.c create mode 100644 driver/testdriver.c create mode 100644 driver/testrgb.c create mode 100644 examples/Makefile create mode 100644 examples/color.drv create mode 100644 examples/constraint.drv create mode 100644 examples/custom.drv create mode 100644 examples/grouping.drv create mode 100644 examples/laserjet-basic.drv create mode 100644 examples/laserjet-pjl.drv create mode 100644 examples/minimum.drv create mode 100644 examples/postscript.drv create mode 100644 examples/r300-basic.drv create mode 100644 examples/r300-colorman.drv create mode 100644 examples/r300-remote.drv create mode 100644 filter/Dependencies create mode 100644 filter/Makefile create mode 100644 filter/api-raster.header create mode 100644 filter/api-raster.shtml create mode 100644 filter/bannertops.c create mode 100644 filter/commandtops.c create mode 100644 filter/common.c create mode 100644 filter/common.h create mode 100644 filter/error.c create mode 100644 filter/form-main.c create mode 100644 filter/form-ps.c create mode 100644 filter/form-tree.c create mode 100644 filter/form.h create mode 100644 filter/gziptoany.c create mode 100644 filter/hpgl-attr.c create mode 100644 filter/hpgl-char.c create mode 100644 filter/hpgl-config.c create mode 100644 filter/hpgl-input.c create mode 100644 filter/hpgl-main.c create mode 100644 filter/hpgl-polygon.c create mode 100644 filter/hpgl-prolog.c create mode 100644 filter/hpgl-vector.c create mode 100644 filter/hpgltops.h create mode 100644 filter/image-bmp.c create mode 100644 filter/image-colorspace.c create mode 100644 filter/image-gif.c create mode 100644 filter/image-jpeg.c create mode 100644 filter/image-photocd.c create mode 100644 filter/image-pix.c create mode 100644 filter/image-png.c create mode 100644 filter/image-pnm.c create mode 100644 filter/image-private.h create mode 100644 filter/image-sgi.c create mode 100644 filter/image-sgi.h create mode 100644 filter/image-sgilib.c create mode 100644 filter/image-sun.c create mode 100644 filter/image-tiff.c create mode 100644 filter/image-zoom.c create mode 100644 filter/image.c create mode 100644 filter/image.h create mode 100644 filter/imagetops.c create mode 100644 filter/imagetoraster.c create mode 100644 filter/interpret.c create mode 100755 filter/libcupsimage.order create mode 100644 filter/libcupsimage2.def create mode 100644 filter/libcupsimage_s.exp create mode 100644 filter/pdftops.c create mode 100644 filter/postscript-driver.header create mode 100644 filter/postscript-driver.shtml create mode 100644 filter/ppd-compiler.header create mode 100644 filter/ppd-compiler.shtml create mode 100644 filter/pstext.c create mode 100644 filter/pstext.h create mode 100644 filter/pstops.c create mode 100644 filter/raster-driver.header create mode 100644 filter/raster-driver.shtml create mode 100644 filter/raster.c create mode 100644 filter/rasterbench.c create mode 100644 filter/rastertoepson.c create mode 100644 filter/rastertohp.c create mode 100644 filter/rastertolabel.c create mode 100644 filter/testimage.c create mode 100644 filter/testraster.c create mode 100644 filter/textcommon.c create mode 100644 filter/textcommon.h create mode 100644 filter/texttops.c create mode 100644 fonts/Makefile create mode 100644 fonts/Monospace create mode 100644 fonts/Monospace-Bold create mode 100644 fonts/Monospace-BoldOblique create mode 100644 fonts/Monospace-Oblique create mode 100644 init/cups-lpd.in create mode 100755 init/cups.sh.in create mode 100644 init/cups.xml.in create mode 100644 init/org.cups.cups-lpd.plist.in create mode 100644 init/org.cups.cupsd.plist create mode 100755 install-sh create mode 100644 locale/Dependencies create mode 100644 locale/Makefile create mode 100644 locale/checkpo.c create mode 100644 locale/cups.footer create mode 100644 locale/cups.header create mode 100644 locale/cups.pot create mode 100644 locale/cups_da.po create mode 100644 locale/cups_de.po create mode 100644 locale/cups_es.po create mode 100644 locale/cups_eu.po create mode 100644 locale/cups_fi.po create mode 100644 locale/cups_fr.po create mode 100644 locale/cups_id.po create mode 100644 locale/cups_it.po create mode 100644 locale/cups_ja.po create mode 100644 locale/cups_ko.po create mode 100644 locale/cups_nl.po create mode 100644 locale/cups_no.po create mode 100644 locale/cups_pl.po create mode 100644 locale/cups_pt.po create mode 100644 locale/cups_pt_BR.po create mode 100644 locale/cups_ru.po create mode 100644 locale/cups_sv.po create mode 100644 locale/cups_zh.po create mode 100644 locale/cups_zh_TW.po create mode 100644 locale/locale.txt create mode 100644 locale/po2strings.c create mode 100644 locale/strings2po.c create mode 100644 locale/translate.c create mode 100644 man/Makefile create mode 100644 man/backend.man create mode 100644 man/cancel.man create mode 100644 man/classes.conf.man create mode 100644 man/client.conf.man.in create mode 100644 man/cups-config.man create mode 100644 man/cups-deviced.man.in create mode 100644 man/cups-driverd.man.in create mode 100644 man/cups-lpd.man.in create mode 100644 man/cups-polld.man create mode 100644 man/cups-snmp.conf.man create mode 100644 man/cupsaccept.man create mode 100644 man/cupsaddsmb.man.in create mode 100644 man/cupsctl.man create mode 100644 man/cupsd.conf.man.in create mode 100644 man/cupsd.man.in create mode 100644 man/cupsenable.man create mode 100644 man/cupsfilter.man create mode 100644 man/cupstestdsc.man create mode 100644 man/cupstestppd.man create mode 100644 man/filter.man create mode 100644 man/lp.man create mode 100644 man/lpadmin.man create mode 100644 man/lpc.man create mode 100644 man/lpinfo.man create mode 100644 man/lpmove.man create mode 100644 man/lpoptions.man.in create mode 100644 man/lppasswd.man create mode 100644 man/lpq.man create mode 100644 man/lpr.man create mode 100644 man/lprm.man create mode 100644 man/lpstat.man create mode 100644 man/mailto.conf.man create mode 100644 man/mantohtml.c create mode 100644 man/mime.convs.man create mode 100644 man/mime.types.man create mode 100644 man/notifier.man create mode 100644 man/ppdc.man create mode 100644 man/ppdcfile.man create mode 100644 man/ppdhtml.man create mode 100644 man/ppdi.man create mode 100644 man/ppdmerge.man create mode 100644 man/ppdpo.man create mode 100644 man/printers.conf.man create mode 100644 man/subscriptions.conf.man create mode 100644 monitor/Dependencies create mode 100644 monitor/Makefile create mode 100644 monitor/bcp.c create mode 100644 monitor/tbcp.c create mode 100644 notifier/Dependencies create mode 100644 notifier/Makefile create mode 100644 notifier/dbus.c create mode 100644 notifier/mailto.c create mode 100644 notifier/rss.c create mode 100644 notifier/testnotify.c create mode 100755 packaging/InstallationCheck create mode 100644 packaging/LICENSE.rtf create mode 100644 packaging/WELCOME.rtf create mode 100644 packaging/cups-dbus.conf create mode 100644 packaging/cups-desc.plist.in create mode 100644 packaging/cups-info.plist.in create mode 100644 packaging/cups.list.in create mode 100644 packaging/cups.spec.in create mode 100644 packaging/installer.gif create mode 100644 packaging/installer.tif create mode 100644 ppdc/Dependencies create mode 100644 ppdc/Makefile create mode 100644 ppdc/api-ppdc.header create mode 100644 ppdc/api-ppdc.shtml create mode 100644 ppdc/foo-fr.po create mode 100644 ppdc/foo.drv create mode 100644 ppdc/genstrings.cxx create mode 100644 ppdc/ppdc-array.cxx create mode 100644 ppdc/ppdc-attr.cxx create mode 100644 ppdc/ppdc-catalog.cxx create mode 100644 ppdc/ppdc-choice.cxx create mode 100644 ppdc/ppdc-constraint.cxx create mode 100644 ppdc/ppdc-driver.cxx create mode 100644 ppdc/ppdc-file.cxx create mode 100644 ppdc/ppdc-filter.cxx create mode 100644 ppdc/ppdc-font.cxx create mode 100644 ppdc/ppdc-group.cxx create mode 100644 ppdc/ppdc-import.cxx create mode 100644 ppdc/ppdc-mediasize.cxx create mode 100644 ppdc/ppdc-message.cxx create mode 100644 ppdc/ppdc-option.cxx create mode 100644 ppdc/ppdc-private.h create mode 100644 ppdc/ppdc-profile.cxx create mode 100644 ppdc/ppdc-shared.cxx create mode 100644 ppdc/ppdc-source.cxx create mode 100644 ppdc/ppdc-string.cxx create mode 100644 ppdc/ppdc-variable.cxx create mode 100644 ppdc/ppdc.cxx create mode 100644 ppdc/ppdc.h create mode 100644 ppdc/ppdhtml.cxx create mode 100644 ppdc/ppdi.cxx create mode 100644 ppdc/ppdmerge.cxx create mode 100644 ppdc/ppdpo.cxx create mode 100644 ppdc/sample.drv create mode 100644 ppdc/testcatalog.cxx create mode 100644 scheduler/Dependencies create mode 100644 scheduler/Makefile create mode 100644 scheduler/api-mime.header create mode 100644 scheduler/api-mime.shtml create mode 100644 scheduler/auth.c create mode 100644 scheduler/auth.h create mode 100644 scheduler/banners.c create mode 100644 scheduler/banners.h create mode 100644 scheduler/cert.c create mode 100644 scheduler/cert.h create mode 100644 scheduler/classes.c create mode 100644 scheduler/classes.h create mode 100644 scheduler/client.c create mode 100644 scheduler/client.h create mode 100644 scheduler/conf.c create mode 100644 scheduler/conf.h create mode 100644 scheduler/cups-deviced.c create mode 100644 scheduler/cups-driverd.cxx create mode 100644 scheduler/cups-lpd.c create mode 100644 scheduler/cups-polld.c create mode 100644 scheduler/cupsd.h create mode 100644 scheduler/cupsd.order create mode 100644 scheduler/cupsfilter.c create mode 100644 scheduler/dirsvc.c create mode 100644 scheduler/dirsvc.h create mode 100644 scheduler/env.c create mode 100644 scheduler/filter.c create mode 100644 scheduler/ipp.c create mode 100644 scheduler/job.c create mode 100644 scheduler/job.h create mode 100644 scheduler/libcupsmime.exp create mode 100644 scheduler/listen.c create mode 100644 scheduler/log.c create mode 100644 scheduler/main.c create mode 100644 scheduler/mime.c create mode 100644 scheduler/mime.h create mode 100644 scheduler/network.c create mode 100644 scheduler/network.h create mode 100644 scheduler/policy.c create mode 100644 scheduler/policy.h create mode 100644 scheduler/printers.c create mode 100644 scheduler/printers.h create mode 100644 scheduler/process.c create mode 100644 scheduler/quotas.c create mode 100644 scheduler/removefile.c create mode 100644 scheduler/select.c create mode 100644 scheduler/server.c create mode 100644 scheduler/statbuf.c create mode 100644 scheduler/statbuf.h create mode 100644 scheduler/subscriptions.c create mode 100644 scheduler/subscriptions.h create mode 100644 scheduler/sysman.c create mode 100644 scheduler/sysman.h create mode 100644 scheduler/testdirsvc.c create mode 100644 scheduler/testlpd.c create mode 100644 scheduler/testmime.c create mode 100644 scheduler/testspeed.c create mode 100644 scheduler/testsub.c create mode 100644 scheduler/type.c create mode 100644 scheduler/util.c create mode 100644 scheduler/util.h create mode 100644 scripting/perl/CUPS.pm create mode 100644 scripting/perl/CUPS.xs create mode 100644 scripting/perl/Makefile.PL create mode 100644 scripting/perl/README create mode 100644 scripting/perl/test.pl create mode 100644 scripting/php/Dependencies create mode 100644 scripting/php/Makefile create mode 100644 scripting/php/README create mode 100644 scripting/php/phpcups.c create mode 100644 scripting/php/phpcups.h create mode 100755 scripting/php/phpcups.php create mode 100644 standards/Makefile create mode 100644 standards/X.690-0207.pdf create mode 100644 standards/lcrc-ipp20-20090602.pdf create mode 100644 standards/lcrc-ippstate10-20090603.pdf create mode 100644 standards/papi-1.0.pdf create mode 100644 standards/pwg5100.1.pdf create mode 100644 standards/pwg5100.2.pdf create mode 100644 standards/pwg5100.3.pdf create mode 100644 standards/pwg5100.5.pdf create mode 100644 standards/pwg5100.6.pdf create mode 100644 standards/pwg5100.7.pdf create mode 100644 standards/pwg5100.8.pdf create mode 100644 standards/pwg5101.1.pdf create mode 100644 standards/pwg5105.1.pdf create mode 100644 standards/pwg5107.1.pdf create mode 100644 standards/rfc1155.txt create mode 100644 standards/rfc1157.txt create mode 100644 standards/rfc1179.txt create mode 100644 standards/rfc1213.txt create mode 100644 standards/rfc1321.txt create mode 100644 standards/rfc2222.txt create mode 100644 standards/rfc2246.txt create mode 100644 standards/rfc2487.txt create mode 100644 standards/rfc2554.txt create mode 100644 standards/rfc2567.txt create mode 100644 standards/rfc2568.txt create mode 100644 standards/rfc2569.txt create mode 100644 standards/rfc2578.txt create mode 100644 standards/rfc2579.txt create mode 100644 standards/rfc2595.txt create mode 100644 standards/rfc2616.txt create mode 100644 standards/rfc2617.txt create mode 100644 standards/rfc2712.txt create mode 100644 standards/rfc2790.txt create mode 100644 standards/rfc2817.txt create mode 100644 standards/rfc2818.txt create mode 100644 standards/rfc2821.txt create mode 100644 standards/rfc2822.txt create mode 100644 standards/rfc2910.txt create mode 100644 standards/rfc2911.txt create mode 100644 standards/rfc2965.txt create mode 100644 standards/rfc3196.txt create mode 100644 standards/rfc3239.txt create mode 100644 standards/rfc3380.txt create mode 100644 standards/rfc3381.txt create mode 100644 standards/rfc3382.txt create mode 100644 standards/rfc3391.txt create mode 100644 standards/rfc3510.txt create mode 100644 standards/rfc3712.txt create mode 100644 standards/rfc3805.txt create mode 100644 standards/rfc3808.txt create mode 100644 standards/rfc3875.txt create mode 100644 standards/rfc3986.txt create mode 100644 standards/rfc3995.txt create mode 100644 standards/rfc3996.txt create mode 100644 standards/rfc3997.txt create mode 100644 standards/rfc3998.txt create mode 100644 standards/rfc4122.txt create mode 100644 standards/rfc4234.txt create mode 100644 standards/rfctohtml.c create mode 100644 standards/wake-on-lan.pdf create mode 100644 standards/wd-ippmailto10-20050519.pdf create mode 100644 systemv/Dependencies create mode 100644 systemv/Makefile create mode 100644 systemv/cancel.c create mode 100644 systemv/cupsaccept.c create mode 100644 systemv/cupsaddsmb.c create mode 100644 systemv/cupsctl.c create mode 100644 systemv/cupstestdsc.c create mode 100644 systemv/cupstestppd.c create mode 100644 systemv/lp.c create mode 100644 systemv/lpadmin.c create mode 100644 systemv/lpinfo.c create mode 100644 systemv/lpmove.c create mode 100644 systemv/lpoptions.c create mode 100644 systemv/lppasswd.c create mode 100644 systemv/lpstat.c create mode 100644 templates/Makefile create mode 100644 templates/add-class.tmpl create mode 100644 templates/add-printer.tmpl create mode 100644 templates/add-rss-subscription.tmpl create mode 100644 templates/admin.tmpl create mode 100644 templates/choose-device.tmpl create mode 100644 templates/choose-make.tmpl create mode 100644 templates/choose-model.tmpl create mode 100644 templates/choose-serial.tmpl create mode 100644 templates/choose-uri.tmpl create mode 100644 templates/class-added.tmpl create mode 100644 templates/class-confirm.tmpl create mode 100644 templates/class-deleted.tmpl create mode 100644 templates/class-jobs-header.tmpl create mode 100644 templates/class-modified.tmpl create mode 100644 templates/class.tmpl create mode 100644 templates/classes-header.tmpl create mode 100644 templates/classes.tmpl create mode 100644 templates/command.tmpl create mode 100644 templates/de/add-class.tmpl create mode 100644 templates/de/add-printer.tmpl create mode 100644 templates/de/add-rss-subscription.tmpl create mode 100644 templates/de/admin.tmpl create mode 100644 templates/de/choose-device.tmpl create mode 100644 templates/de/choose-make.tmpl create mode 100644 templates/de/choose-model.tmpl create mode 100644 templates/de/choose-serial.tmpl create mode 100644 templates/de/choose-uri.tmpl create mode 100644 templates/de/class-added.tmpl create mode 100644 templates/de/class-confirm.tmpl create mode 100644 templates/de/class-deleted.tmpl create mode 100644 templates/de/class-jobs-header.tmpl create mode 100644 templates/de/class-modified.tmpl create mode 100644 templates/de/class.tmpl create mode 100644 templates/de/classes-header.tmpl create mode 100644 templates/de/classes.tmpl create mode 100644 templates/de/command.tmpl create mode 100644 templates/de/edit-config.tmpl create mode 100644 templates/de/error-op.tmpl create mode 100644 templates/de/error.tmpl create mode 100644 templates/de/header.tmpl.in create mode 100644 templates/de/help-header.tmpl create mode 100644 templates/de/help-printable.tmpl create mode 100644 templates/de/help-trailer.tmpl create mode 100644 templates/de/job-cancel.tmpl create mode 100644 templates/de/job-hold.tmpl create mode 100644 templates/de/job-move.tmpl create mode 100644 templates/de/job-moved.tmpl create mode 100644 templates/de/job-release.tmpl create mode 100644 templates/de/job-restart.tmpl create mode 100644 templates/de/jobs-header.tmpl create mode 100644 templates/de/jobs.tmpl create mode 100644 templates/de/list-available-printers.tmpl create mode 100644 templates/de/modify-class.tmpl create mode 100644 templates/de/modify-printer.tmpl create mode 100644 templates/de/norestart.tmpl create mode 100644 templates/de/option-boolean.tmpl create mode 100644 templates/de/option-conflict.tmpl create mode 100644 templates/de/option-header.tmpl create mode 100644 templates/de/option-pickmany.tmpl create mode 100644 templates/de/option-pickone.tmpl create mode 100644 templates/de/option-trailer.tmpl create mode 100644 templates/de/pager.tmpl create mode 100644 templates/de/printer-accept.tmpl create mode 100644 templates/de/printer-added.tmpl create mode 100644 templates/de/printer-configured.tmpl create mode 100644 templates/de/printer-confirm.tmpl create mode 100644 templates/de/printer-default.tmpl create mode 100644 templates/de/printer-deleted.tmpl create mode 100644 templates/de/printer-jobs-header.tmpl create mode 100644 templates/de/printer-modified.tmpl create mode 100644 templates/de/printer-purge.tmpl create mode 100644 templates/de/printer-reject.tmpl create mode 100644 templates/de/printer-start.tmpl create mode 100644 templates/de/printer-stop.tmpl create mode 100644 templates/de/printer.tmpl create mode 100644 templates/de/printers-header.tmpl create mode 100644 templates/de/printers.tmpl create mode 100644 templates/de/restart.tmpl create mode 100644 templates/de/samba-export.tmpl create mode 100644 templates/de/samba-exported.tmpl create mode 100644 templates/de/search.tmpl create mode 100644 templates/de/set-printer-options-header.tmpl create mode 100644 templates/de/set-printer-options-trailer.tmpl create mode 100644 templates/de/subscription-added.tmpl create mode 100644 templates/de/subscription-canceled.tmpl create mode 100644 templates/de/test-page.tmpl create mode 100644 templates/de/trailer.tmpl create mode 100644 templates/de/users.tmpl create mode 100644 templates/edit-config.tmpl create mode 100644 templates/error-op.tmpl create mode 100644 templates/error.tmpl create mode 100755 templates/es/add-class.tmpl create mode 100755 templates/es/add-printer.tmpl create mode 100755 templates/es/add-rss-subscription.tmpl create mode 100755 templates/es/admin.tmpl create mode 100755 templates/es/choose-device.tmpl create mode 100755 templates/es/choose-make.tmpl create mode 100755 templates/es/choose-model.tmpl create mode 100755 templates/es/choose-serial.tmpl create mode 100755 templates/es/choose-uri.tmpl create mode 100755 templates/es/class-added.tmpl create mode 100755 templates/es/class-confirm.tmpl create mode 100755 templates/es/class-deleted.tmpl create mode 100755 templates/es/class-jobs-header.tmpl create mode 100755 templates/es/class-modified.tmpl create mode 100755 templates/es/class.tmpl create mode 100755 templates/es/classes-header.tmpl create mode 100755 templates/es/classes.tmpl create mode 100755 templates/es/command.tmpl create mode 100755 templates/es/edit-config.tmpl create mode 100755 templates/es/error-op.tmpl create mode 100755 templates/es/error.tmpl create mode 100755 templates/es/header.tmpl.in create mode 100755 templates/es/help-header.tmpl create mode 100755 templates/es/help-printable.tmpl create mode 100755 templates/es/help-trailer.tmpl create mode 100755 templates/es/job-cancel.tmpl create mode 100755 templates/es/job-hold.tmpl create mode 100755 templates/es/job-move.tmpl create mode 100755 templates/es/job-moved.tmpl create mode 100755 templates/es/job-release.tmpl create mode 100755 templates/es/job-restart.tmpl create mode 100755 templates/es/jobs-header.tmpl create mode 100755 templates/es/jobs.tmpl create mode 100755 templates/es/list-available-printers.tmpl create mode 100755 templates/es/modify-class.tmpl create mode 100755 templates/es/modify-printer.tmpl create mode 100755 templates/es/norestart.tmpl create mode 100755 templates/es/option-boolean.tmpl create mode 100755 templates/es/option-conflict.tmpl create mode 100755 templates/es/option-header.tmpl create mode 100755 templates/es/option-pickmany.tmpl create mode 100755 templates/es/option-pickone.tmpl create mode 100755 templates/es/option-trailer.tmpl create mode 100755 templates/es/pager.tmpl create mode 100755 templates/es/printer-accept.tmpl create mode 100755 templates/es/printer-added.tmpl create mode 100755 templates/es/printer-configured.tmpl create mode 100755 templates/es/printer-confirm.tmpl create mode 100755 templates/es/printer-default.tmpl create mode 100755 templates/es/printer-deleted.tmpl create mode 100755 templates/es/printer-jobs-header.tmpl create mode 100755 templates/es/printer-modified.tmpl create mode 100755 templates/es/printer-purge.tmpl create mode 100755 templates/es/printer-reject.tmpl create mode 100755 templates/es/printer-start.tmpl create mode 100755 templates/es/printer-stop.tmpl create mode 100755 templates/es/printer.tmpl create mode 100755 templates/es/printers-header.tmpl create mode 100755 templates/es/printers.tmpl create mode 100755 templates/es/restart.tmpl create mode 100755 templates/es/samba-export.tmpl create mode 100755 templates/es/samba-exported.tmpl create mode 100755 templates/es/search.tmpl create mode 100755 templates/es/set-printer-options-header.tmpl create mode 100755 templates/es/set-printer-options-trailer.tmpl create mode 100755 templates/es/subscription-added.tmpl create mode 100755 templates/es/subscription-canceled.tmpl create mode 100755 templates/es/test-page.tmpl create mode 100755 templates/es/trailer.tmpl create mode 100755 templates/es/users.tmpl create mode 100644 templates/eu/add-class.tmpl create mode 100644 templates/eu/add-printer.tmpl create mode 100644 templates/eu/add-rss-subscription.tmpl create mode 100644 templates/eu/admin.tmpl create mode 100644 templates/eu/choose-device.tmpl create mode 100644 templates/eu/choose-make.tmpl create mode 100644 templates/eu/choose-model.tmpl create mode 100644 templates/eu/choose-serial.tmpl create mode 100644 templates/eu/choose-uri.tmpl create mode 100644 templates/eu/class-added.tmpl create mode 100644 templates/eu/class-confirm.tmpl create mode 100644 templates/eu/class-deleted.tmpl create mode 100644 templates/eu/class-jobs-header.tmpl create mode 100644 templates/eu/class-modified.tmpl create mode 100644 templates/eu/class.tmpl create mode 100644 templates/eu/classes-header.tmpl create mode 100644 templates/eu/classes.tmpl create mode 100644 templates/eu/command.tmpl create mode 100644 templates/eu/edit-config.tmpl create mode 100644 templates/eu/error-op.tmpl create mode 100644 templates/eu/error.tmpl create mode 100644 templates/eu/header.tmpl.in create mode 100644 templates/eu/help-header.tmpl create mode 100644 templates/eu/help-printable.tmpl create mode 100644 templates/eu/help-trailer.tmpl create mode 100644 templates/eu/job-cancel.tmpl create mode 100644 templates/eu/job-hold.tmpl create mode 100644 templates/eu/job-move.tmpl create mode 100644 templates/eu/job-moved.tmpl create mode 100644 templates/eu/job-release.tmpl create mode 100644 templates/eu/job-restart.tmpl create mode 100644 templates/eu/jobs-header.tmpl create mode 100644 templates/eu/jobs.tmpl create mode 100644 templates/eu/list-available-printers.tmpl create mode 100644 templates/eu/modify-class.tmpl create mode 100644 templates/eu/modify-printer.tmpl create mode 100644 templates/eu/norestart.tmpl create mode 100644 templates/eu/option-boolean.tmpl create mode 100644 templates/eu/option-conflict.tmpl create mode 100644 templates/eu/option-header.tmpl create mode 100644 templates/eu/option-pickmany.tmpl create mode 100644 templates/eu/option-pickone.tmpl create mode 100644 templates/eu/option-trailer.tmpl create mode 100644 templates/eu/pager.tmpl create mode 100644 templates/eu/printer-accept.tmpl create mode 100644 templates/eu/printer-added.tmpl create mode 100644 templates/eu/printer-configured.tmpl create mode 100644 templates/eu/printer-confirm.tmpl create mode 100644 templates/eu/printer-default.tmpl create mode 100644 templates/eu/printer-deleted.tmpl create mode 100644 templates/eu/printer-jobs-header.tmpl create mode 100644 templates/eu/printer-modified.tmpl create mode 100644 templates/eu/printer-purge.tmpl create mode 100644 templates/eu/printer-reject.tmpl create mode 100644 templates/eu/printer-start.tmpl create mode 100644 templates/eu/printer-stop.tmpl create mode 100644 templates/eu/printer.tmpl create mode 100644 templates/eu/printers-header.tmpl create mode 100644 templates/eu/printers.tmpl create mode 100644 templates/eu/restart.tmpl create mode 100644 templates/eu/samba-export.tmpl create mode 100644 templates/eu/samba-exported.tmpl create mode 100644 templates/eu/search.tmpl create mode 100644 templates/eu/set-printer-options-header.tmpl create mode 100644 templates/eu/set-printer-options-trailer.tmpl create mode 100644 templates/eu/subscription-added.tmpl create mode 100644 templates/eu/subscription-canceled.tmpl create mode 100644 templates/eu/test-page.tmpl create mode 100644 templates/eu/trailer.tmpl create mode 100644 templates/eu/users.tmpl create mode 100644 templates/header.tmpl.in create mode 100644 templates/help-header.tmpl create mode 100644 templates/help-printable.tmpl create mode 100644 templates/help-trailer.tmpl create mode 100644 templates/id/add-class.tmpl create mode 100644 templates/id/add-printer.tmpl create mode 100644 templates/id/add-rss-subscription.tmpl create mode 100644 templates/id/admin.tmpl create mode 100644 templates/id/choose-device.tmpl create mode 100644 templates/id/choose-make.tmpl create mode 100644 templates/id/choose-model.tmpl create mode 100644 templates/id/choose-serial.tmpl create mode 100644 templates/id/choose-uri.tmpl create mode 100644 templates/id/class-added.tmpl create mode 100644 templates/id/class-confirm.tmpl create mode 100644 templates/id/class-deleted.tmpl create mode 100644 templates/id/class-jobs-header.tmpl create mode 100644 templates/id/class-modified.tmpl create mode 100644 templates/id/class.tmpl create mode 100644 templates/id/classes-header.tmpl create mode 100644 templates/id/classes.tmpl create mode 100644 templates/id/command.tmpl create mode 100644 templates/id/edit-config.tmpl create mode 100644 templates/id/error-op.tmpl create mode 100644 templates/id/error.tmpl create mode 100644 templates/id/header.tmpl.in create mode 100644 templates/id/help-header.tmpl create mode 100644 templates/id/help-printable.tmpl create mode 100644 templates/id/help-trailer.tmpl create mode 100644 templates/id/job-cancel.tmpl create mode 100644 templates/id/job-hold.tmpl create mode 100644 templates/id/job-move.tmpl create mode 100644 templates/id/job-moved.tmpl create mode 100644 templates/id/job-release.tmpl create mode 100644 templates/id/job-restart.tmpl create mode 100644 templates/id/jobs-header.tmpl create mode 100644 templates/id/jobs.tmpl create mode 100644 templates/id/list-available-printers.tmpl create mode 100644 templates/id/modify-class.tmpl create mode 100644 templates/id/modify-printer.tmpl create mode 100644 templates/id/norestart.tmpl create mode 100644 templates/id/option-boolean.tmpl create mode 100644 templates/id/option-conflict.tmpl create mode 100644 templates/id/option-header.tmpl create mode 100644 templates/id/option-pickmany.tmpl create mode 100644 templates/id/option-pickone.tmpl create mode 100644 templates/id/option-trailer.tmpl create mode 100644 templates/id/pager.tmpl create mode 100644 templates/id/printer-accept.tmpl create mode 100644 templates/id/printer-added.tmpl create mode 100644 templates/id/printer-configured.tmpl create mode 100644 templates/id/printer-confirm.tmpl create mode 100644 templates/id/printer-default.tmpl create mode 100644 templates/id/printer-deleted.tmpl create mode 100644 templates/id/printer-jobs-header.tmpl create mode 100644 templates/id/printer-modified.tmpl create mode 100644 templates/id/printer-purge.tmpl create mode 100644 templates/id/printer-reject.tmpl create mode 100644 templates/id/printer-start.tmpl create mode 100644 templates/id/printer-stop.tmpl create mode 100644 templates/id/printer.tmpl create mode 100644 templates/id/printers-header.tmpl create mode 100644 templates/id/printers.tmpl create mode 100644 templates/id/restart.tmpl create mode 100644 templates/id/samba-export.tmpl create mode 100644 templates/id/samba-exported.tmpl create mode 100644 templates/id/search.tmpl create mode 100644 templates/id/set-printer-options-header.tmpl create mode 100644 templates/id/set-printer-options-trailer.tmpl create mode 100644 templates/id/subscription-added.tmpl create mode 100644 templates/id/subscription-canceled.tmpl create mode 100644 templates/id/test-page.tmpl create mode 100644 templates/id/trailer.tmpl create mode 100644 templates/id/users.tmpl create mode 100644 templates/it/add-class.tmpl create mode 100644 templates/it/add-printer.tmpl create mode 100644 templates/it/add-rss-subscription.tmpl create mode 100644 templates/it/admin.tmpl create mode 100644 templates/it/choose-device.tmpl create mode 100644 templates/it/choose-make.tmpl create mode 100644 templates/it/choose-model.tmpl create mode 100644 templates/it/choose-serial.tmpl create mode 100644 templates/it/choose-uri.tmpl create mode 100644 templates/it/class-added.tmpl create mode 100644 templates/it/class-confirm.tmpl create mode 100644 templates/it/class-deleted.tmpl create mode 100644 templates/it/class-jobs-header.tmpl create mode 100644 templates/it/class-modified.tmpl create mode 100644 templates/it/class.tmpl create mode 100644 templates/it/classes-header.tmpl create mode 100644 templates/it/classes.tmpl create mode 100644 templates/it/command.tmpl create mode 100644 templates/it/edit-config.tmpl create mode 100644 templates/it/error-op.tmpl create mode 100644 templates/it/error.tmpl create mode 100644 templates/it/help-header.tmpl create mode 100644 templates/it/help-printable.tmpl create mode 100644 templates/it/help-trailer.tmpl create mode 100644 templates/it/job-cancel.tmpl create mode 100644 templates/it/job-hold.tmpl create mode 100644 templates/it/job-move.tmpl create mode 100644 templates/it/job-moved.tmpl create mode 100644 templates/it/job-release.tmpl create mode 100644 templates/it/job-restart.tmpl create mode 100644 templates/it/jobs-header.tmpl create mode 100644 templates/it/jobs.tmpl create mode 100644 templates/it/list-available-printers.tmpl create mode 100644 templates/it/modify-class.tmpl create mode 100644 templates/it/modify-printer.tmpl create mode 100644 templates/it/norestart.tmpl create mode 100644 templates/it/option-boolean.tmpl create mode 100644 templates/it/option-conflict.tmpl create mode 100644 templates/it/option-header.tmpl create mode 100644 templates/it/option-pickmany.tmpl create mode 100644 templates/it/option-pickone.tmpl create mode 100644 templates/it/option-trailer.tmpl create mode 100644 templates/it/pager.tmpl create mode 100644 templates/it/printer-accept.tmpl create mode 100644 templates/it/printer-added.tmpl create mode 100644 templates/it/printer-configured.tmpl create mode 100644 templates/it/printer-confirm.tmpl create mode 100644 templates/it/printer-default.tmpl create mode 100644 templates/it/printer-deleted.tmpl create mode 100644 templates/it/printer-jobs-header.tmpl create mode 100644 templates/it/printer-modified.tmpl create mode 100644 templates/it/printer-purge.tmpl create mode 100644 templates/it/printer-reject.tmpl create mode 100644 templates/it/printer-start.tmpl create mode 100644 templates/it/printer-stop.tmpl create mode 100644 templates/it/printer.tmpl create mode 100644 templates/it/printers-header.tmpl create mode 100644 templates/it/printers.tmpl create mode 100644 templates/it/restart.tmpl create mode 100644 templates/it/samba-export.tmpl create mode 100644 templates/it/samba-exported.tmpl create mode 100644 templates/it/search.tmpl create mode 100644 templates/it/set-printer-options-header.tmpl create mode 100644 templates/it/set-printer-options-trailer.tmpl create mode 100644 templates/it/subscription-added.tmpl create mode 100644 templates/it/subscription-canceled.tmpl create mode 100644 templates/it/test-page.tmpl create mode 100644 templates/it/trailer.tmpl create mode 100644 templates/it/users.tmpl create mode 100644 templates/ja/add-class.tmpl create mode 100644 templates/ja/add-printer.tmpl create mode 100644 templates/ja/add-rss-subscription.tmpl create mode 100644 templates/ja/admin.tmpl create mode 100644 templates/ja/choose-device.tmpl create mode 100644 templates/ja/choose-make.tmpl create mode 100644 templates/ja/choose-model.tmpl create mode 100644 templates/ja/choose-serial.tmpl create mode 100644 templates/ja/choose-uri.tmpl create mode 100644 templates/ja/class-added.tmpl create mode 100644 templates/ja/class-confirm.tmpl create mode 100644 templates/ja/class-deleted.tmpl create mode 100644 templates/ja/class-jobs-header.tmpl create mode 100644 templates/ja/class-modified.tmpl create mode 100644 templates/ja/class.tmpl create mode 100644 templates/ja/classes-header.tmpl create mode 100644 templates/ja/classes.tmpl create mode 100644 templates/ja/command.tmpl create mode 100644 templates/ja/edit-config.tmpl create mode 100644 templates/ja/error-op.tmpl create mode 100644 templates/ja/error.tmpl create mode 100644 templates/ja/header.tmpl.in create mode 100644 templates/ja/help-header.tmpl create mode 100644 templates/ja/help-printable.tmpl create mode 100644 templates/ja/help-trailer.tmpl create mode 100644 templates/ja/job-cancel.tmpl create mode 100644 templates/ja/job-hold.tmpl create mode 100644 templates/ja/job-move.tmpl create mode 100644 templates/ja/job-moved.tmpl create mode 100644 templates/ja/job-release.tmpl create mode 100644 templates/ja/job-restart.tmpl create mode 100644 templates/ja/jobs-header.tmpl create mode 100644 templates/ja/jobs.tmpl create mode 100644 templates/ja/list-available-printers.tmpl create mode 100644 templates/ja/modify-class.tmpl create mode 100644 templates/ja/modify-printer.tmpl create mode 100644 templates/ja/norestart.tmpl create mode 100644 templates/ja/option-boolean.tmpl create mode 100644 templates/ja/option-conflict.tmpl create mode 100644 templates/ja/option-header.tmpl create mode 100644 templates/ja/option-pickmany.tmpl create mode 100644 templates/ja/option-pickone.tmpl create mode 100644 templates/ja/option-trailer.tmpl create mode 100644 templates/ja/pager.tmpl create mode 100644 templates/ja/printer-accept.tmpl create mode 100644 templates/ja/printer-added.tmpl create mode 100644 templates/ja/printer-configured.tmpl create mode 100644 templates/ja/printer-confirm.tmpl create mode 100644 templates/ja/printer-default.tmpl create mode 100644 templates/ja/printer-deleted.tmpl create mode 100644 templates/ja/printer-jobs-header.tmpl create mode 100644 templates/ja/printer-modified.tmpl create mode 100644 templates/ja/printer-purge.tmpl create mode 100644 templates/ja/printer-reject.tmpl create mode 100644 templates/ja/printer-start.tmpl create mode 100644 templates/ja/printer-stop.tmpl create mode 100644 templates/ja/printer.tmpl create mode 100644 templates/ja/printers-header.tmpl create mode 100644 templates/ja/printers.tmpl create mode 100644 templates/ja/restart.tmpl create mode 100644 templates/ja/samba-export.tmpl create mode 100644 templates/ja/samba-exported.tmpl create mode 100644 templates/ja/search.tmpl create mode 100644 templates/ja/set-printer-options-header.tmpl create mode 100644 templates/ja/set-printer-options-trailer.tmpl create mode 100644 templates/ja/subscription-added.tmpl create mode 100644 templates/ja/subscription-canceled.tmpl create mode 100644 templates/ja/test-page.tmpl create mode 100644 templates/ja/trailer.tmpl create mode 100644 templates/ja/users.tmpl create mode 100644 templates/job-cancel.tmpl create mode 100644 templates/job-hold.tmpl create mode 100644 templates/job-move.tmpl create mode 100644 templates/job-moved.tmpl create mode 100644 templates/job-release.tmpl create mode 100644 templates/job-restart.tmpl create mode 100644 templates/jobs-header.tmpl create mode 100644 templates/jobs.tmpl create mode 100644 templates/list-available-printers.tmpl create mode 100644 templates/modify-class.tmpl create mode 100644 templates/modify-printer.tmpl create mode 100644 templates/norestart.tmpl create mode 100644 templates/option-boolean.tmpl create mode 100644 templates/option-conflict.tmpl create mode 100644 templates/option-header.tmpl create mode 100644 templates/option-pickmany.tmpl create mode 100644 templates/option-pickone.tmpl create mode 100644 templates/option-trailer.tmpl create mode 100644 templates/pager.tmpl create mode 100644 templates/pl/add-class.tmpl create mode 100644 templates/pl/add-printer.tmpl create mode 100644 templates/pl/add-rss-subscription.tmpl create mode 100644 templates/pl/admin.tmpl create mode 100644 templates/pl/choose-device.tmpl create mode 100644 templates/pl/choose-make.tmpl create mode 100644 templates/pl/choose-model.tmpl create mode 100644 templates/pl/choose-serial.tmpl create mode 100644 templates/pl/choose-uri.tmpl create mode 100644 templates/pl/class-added.tmpl create mode 100644 templates/pl/class-confirm.tmpl create mode 100644 templates/pl/class-deleted.tmpl create mode 100644 templates/pl/class-jobs-header.tmpl create mode 100644 templates/pl/class-modified.tmpl create mode 100644 templates/pl/class.tmpl create mode 100644 templates/pl/classes-header.tmpl create mode 100644 templates/pl/classes.tmpl create mode 100644 templates/pl/command.tmpl create mode 100644 templates/pl/edit-config.tmpl create mode 100644 templates/pl/error-op.tmpl create mode 100644 templates/pl/error.tmpl create mode 100644 templates/pl/header.tmpl.in create mode 100644 templates/pl/help-header.tmpl create mode 100644 templates/pl/help-printable.tmpl create mode 100644 templates/pl/help-trailer.tmpl create mode 100644 templates/pl/job-cancel.tmpl create mode 100644 templates/pl/job-hold.tmpl create mode 100644 templates/pl/job-move.tmpl create mode 100644 templates/pl/job-moved.tmpl create mode 100644 templates/pl/job-release.tmpl create mode 100644 templates/pl/job-restart.tmpl create mode 100644 templates/pl/jobs-header.tmpl create mode 100644 templates/pl/jobs.tmpl create mode 100644 templates/pl/list-available-printers.tmpl create mode 100644 templates/pl/modify-class.tmpl create mode 100644 templates/pl/modify-printer.tmpl create mode 100644 templates/pl/norestart.tmpl create mode 100644 templates/pl/option-boolean.tmpl create mode 100644 templates/pl/option-conflict.tmpl create mode 100644 templates/pl/option-header.tmpl create mode 100644 templates/pl/option-pickmany.tmpl create mode 100644 templates/pl/option-pickone.tmpl create mode 100644 templates/pl/option-trailer.tmpl create mode 100644 templates/pl/pager.tmpl create mode 100644 templates/pl/printer-accept.tmpl create mode 100644 templates/pl/printer-added.tmpl create mode 100644 templates/pl/printer-configured.tmpl create mode 100644 templates/pl/printer-confirm.tmpl create mode 100644 templates/pl/printer-default.tmpl create mode 100644 templates/pl/printer-deleted.tmpl create mode 100644 templates/pl/printer-jobs-header.tmpl create mode 100644 templates/pl/printer-modified.tmpl create mode 100644 templates/pl/printer-purge.tmpl create mode 100644 templates/pl/printer-reject.tmpl create mode 100644 templates/pl/printer-start.tmpl create mode 100644 templates/pl/printer-stop.tmpl create mode 100644 templates/pl/printer.tmpl create mode 100644 templates/pl/printers-header.tmpl create mode 100644 templates/pl/printers.tmpl create mode 100644 templates/pl/restart.tmpl create mode 100644 templates/pl/samba-export.tmpl create mode 100644 templates/pl/samba-exported.tmpl create mode 100644 templates/pl/search.tmpl create mode 100644 templates/pl/set-printer-options-header.tmpl create mode 100644 templates/pl/set-printer-options-trailer.tmpl create mode 100644 templates/pl/subscription-added.tmpl create mode 100644 templates/pl/subscription-canceled.tmpl create mode 100644 templates/pl/test-page.tmpl create mode 100644 templates/pl/trailer.tmpl create mode 100644 templates/pl/users.tmpl create mode 100644 templates/printer-accept.tmpl create mode 100644 templates/printer-added.tmpl create mode 100644 templates/printer-configured.tmpl create mode 100644 templates/printer-confirm.tmpl create mode 100644 templates/printer-default.tmpl create mode 100644 templates/printer-deleted.tmpl create mode 100644 templates/printer-jobs-header.tmpl create mode 100644 templates/printer-modified.tmpl create mode 100644 templates/printer-purge.tmpl create mode 100644 templates/printer-reject.tmpl create mode 100644 templates/printer-start.tmpl create mode 100644 templates/printer-stop.tmpl create mode 100644 templates/printer.tmpl create mode 100644 templates/printers-header.tmpl create mode 100644 templates/printers.tmpl create mode 100644 templates/restart.tmpl create mode 100644 templates/ru/Makefile create mode 100644 templates/ru/add-class.tmpl create mode 100644 templates/ru/add-printer.tmpl create mode 100644 templates/ru/add-rss-subscription.tmpl create mode 100644 templates/ru/admin.tmpl create mode 100644 templates/ru/choose-device.tmpl create mode 100644 templates/ru/choose-make.tmpl create mode 100644 templates/ru/choose-model.tmpl create mode 100644 templates/ru/choose-serial.tmpl create mode 100644 templates/ru/choose-uri.tmpl create mode 100644 templates/ru/class-added.tmpl create mode 100644 templates/ru/class-confirm.tmpl create mode 100644 templates/ru/class-deleted.tmpl create mode 100644 templates/ru/class-jobs-header.tmpl create mode 100644 templates/ru/class-modified.tmpl create mode 100644 templates/ru/class.tmpl create mode 100644 templates/ru/classes-header.tmpl create mode 100644 templates/ru/classes.tmpl create mode 100644 templates/ru/command.tmpl create mode 100644 templates/ru/edit-config.tmpl create mode 100644 templates/ru/error-op.tmpl create mode 100644 templates/ru/error.tmpl create mode 100644 templates/ru/header.tmpl.in create mode 100644 templates/ru/help-header.tmpl create mode 100644 templates/ru/help-printable.tmpl create mode 100644 templates/ru/help-trailer.tmpl create mode 100644 templates/ru/job-cancel.tmpl create mode 100644 templates/ru/job-hold.tmpl create mode 100644 templates/ru/job-move.tmpl create mode 100644 templates/ru/job-moved.tmpl create mode 100644 templates/ru/job-release.tmpl create mode 100644 templates/ru/job-restart.tmpl create mode 100644 templates/ru/jobs-header.tmpl create mode 100644 templates/ru/jobs.tmpl create mode 100644 templates/ru/list-available-printers.tmpl create mode 100644 templates/ru/modify-class.tmpl create mode 100644 templates/ru/modify-printer.tmpl create mode 100644 templates/ru/norestart.tmpl create mode 100644 templates/ru/option-boolean.tmpl create mode 100644 templates/ru/option-conflict.tmpl create mode 100644 templates/ru/option-header.tmpl create mode 100644 templates/ru/option-pickmany.tmpl create mode 100644 templates/ru/option-pickone.tmpl create mode 100644 templates/ru/option-trailer.tmpl create mode 100644 templates/ru/pager.tmpl create mode 100644 templates/ru/printer-accept.tmpl create mode 100644 templates/ru/printer-added.tmpl create mode 100644 templates/ru/printer-configured.tmpl create mode 100644 templates/ru/printer-confirm.tmpl create mode 100644 templates/ru/printer-default.tmpl create mode 100644 templates/ru/printer-deleted.tmpl create mode 100644 templates/ru/printer-jobs-header.tmpl create mode 100644 templates/ru/printer-modified.tmpl create mode 100644 templates/ru/printer-purge.tmpl create mode 100644 templates/ru/printer-reject.tmpl create mode 100644 templates/ru/printer-start.tmpl create mode 100644 templates/ru/printer-stop.tmpl create mode 100644 templates/ru/printer.tmpl create mode 100644 templates/ru/printers-header.tmpl create mode 100644 templates/ru/printers.tmpl create mode 100644 templates/ru/restart.tmpl create mode 100644 templates/ru/samba-export.tmpl create mode 100644 templates/ru/samba-exported.tmpl create mode 100644 templates/ru/search.tmpl create mode 100644 templates/ru/set-printer-options-header.tmpl create mode 100644 templates/ru/set-printer-options-trailer.tmpl create mode 100644 templates/ru/subscription-added.tmpl create mode 100644 templates/ru/subscription-canceled.tmpl create mode 100644 templates/ru/test-page.tmpl create mode 100644 templates/ru/trailer.tmpl create mode 100644 templates/ru/users.tmpl create mode 100644 templates/samba-export.tmpl create mode 100644 templates/samba-exported.tmpl create mode 100644 templates/search.tmpl create mode 100644 templates/set-printer-options-header.tmpl create mode 100644 templates/set-printer-options-trailer.tmpl create mode 100644 templates/subscription-added.tmpl create mode 100644 templates/subscription-canceled.tmpl create mode 100644 templates/test-page.tmpl create mode 100644 templates/trailer.tmpl create mode 100644 templates/users.tmpl create mode 100644 test/4.1-requests.test create mode 100644 test/4.2-cups-printer-ops.test create mode 100644 test/4.3-job-ops.test create mode 100644 test/4.4-subscription-ops.test create mode 100755 test/5.1-lpadmin.sh create mode 100755 test/5.2-lpc.sh create mode 100755 test/5.3-lpq.sh create mode 100755 test/5.4-lpstat.sh create mode 100755 test/5.5-lp.sh create mode 100755 test/5.6-lpr.sh create mode 100755 test/5.7-lprm.sh create mode 100755 test/5.8-cancel.sh create mode 100755 test/5.9-lpinfo.sh create mode 100644 test/Dependencies create mode 100644 test/Makefile create mode 100644 test/create-job-format.test create mode 100644 test/create-job-sheets.test create mode 100644 test/create-job-timeout.test create mode 100644 test/create-job.test create mode 100644 test/create-printer-subscription.test create mode 100644 test/get-devices.test create mode 100644 test/get-job-attributes.test create mode 100644 test/get-job-attributes2.test create mode 100644 test/get-jobs.test create mode 100644 test/get-ppd-printer.test create mode 100644 test/get-ppd.test create mode 100644 test/get-ppds-drv-only.test create mode 100644 test/get-ppds-language.test create mode 100644 test/get-ppds-make-and-model.test create mode 100644 test/get-ppds-make.test create mode 100644 test/get-ppds-product.test create mode 100644 test/get-ppds-psversion.test create mode 100644 test/get-ppds.test create mode 100644 test/get-printer-attributes-2.0.test create mode 100644 test/get-printer-attributes.test create mode 100644 test/get-printers.test create mode 100644 test/get-subscriptions.test create mode 100644 test/ipp-backend.test create mode 100644 test/ipptest.c create mode 100644 test/print-job-hold.test create mode 100644 test/print-job-media-col.test create mode 100644 test/print-job.test create mode 100755 test/run-stp-tests.sh create mode 100644 test/set-attrs-hold.test create mode 100644 test/str-header.html create mode 100644 test/str-trailer.html create mode 100644 test/testfile.jpg create mode 100644 test/testfile.pdf create mode 100644 test/testfile.ps create mode 100644 test/testfile.txt create mode 100644 test/testhp.ppd create mode 100644 test/testps.ppd create mode 100755 test/waitjobs.sh create mode 100755 tools/checkglobals create mode 100755 tools/listpublic create mode 100755 tools/makesrcdist create mode 100755 tools/products.php create mode 100755 tools/testosx create mode 100755 tools/testrpm create mode 100644 vc2005/cups.sln create mode 100644 vc2005/cupstestppd.vcproj create mode 100644 vc2005/libcups2.vcproj create mode 100644 vc2005/libcupsimage2.vcproj create mode 100644 vc2005/testfile.vcproj create mode 100644 vc2005/testhttp.vcproj create mode 100644 vcnet/config.h create mode 100644 vcnet/cups.sln create mode 100644 vcnet/cupstestppd.vcproj create mode 100644 vcnet/libcups2.vcproj create mode 100644 vcnet/libcupsimage2.vcproj create mode 100644 vcnet/testfile.vcproj create mode 100755 vcnet/testhttp.vcproj diff --git a/CHANGES-1.0.txt b/CHANGES-1.0.txt new file mode 100644 index 0000000000..296d89f791 --- /dev/null +++ b/CHANGES-1.0.txt @@ -0,0 +1,217 @@ +CHANGES-1.0.txt +--------------- + +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/CHANGES-1.1.txt b/CHANGES-1.1.txt new file mode 100644 index 0000000000..c641e794a3 --- /dev/null +++ b/CHANGES-1.1.txt @@ -0,0 +1,3462 @@ +CHANGES-1.1.txt +--------------- + +CHANGES IN CUPS V1.1.23 + + - Updated the Spanish man pages (STR #1041) + - The lpstat man page contained a typo (STR #1040) + - The scheduler's is_path_absolute() code could cause a + DoS (STR #1042) + - The scheduler's device loading code used the wrong + size limits for the make/model and info parameters + (STR #1035) + - The PNG loading code did not use a "long unsigned + integer" format specifier for the width and height + (STR #1032) + - The web interface only showed the first 4 or 8 + characters of "{variable-name}" for undefined template + variables (STR #1031) + - The hpgltops filter did not handle a common PCL + command to enter HP-GL/2 mode (STR #1037) + + +CHANGES IN CUPS V1.1.23rc1 + + - The lpr man page did not document the "-U" option (STR + #998) + - The scheduler no longer sends the page-set option when + printing banner pages (STR #995) + - Fixed a debug message in the imagetops filter (STR + #1012) + - The lprm man page listed the "-" option in the wrong + order (STR #911) + - The hpgltops filter contained two buffer overflows + that could potentially allow remote access to the "lp" + account (STR #1024) + - The lppasswd command did not protect against file + descriptor or ulimit attacks (STR #1023) + - The "lpc status" command used the wrong resource path + when querying the list of printers and jobs, causing + unnecessary authentication requests (STR #1018) + - The httpWait() function did not handle signal + interruptions (STR #1020) + - The USB backend used the wrong size status variable + when checking the printer status (STR #1017) + - The scheduler did not delete classes from other + classes or implicit classes, which could cause a crash + (STR #1015) + - The IPP backend now logs the remote print job ID at + log level NOTICE instead of INFO (so it shows up in + the error_log file...) + + +CHANGES IN CUPS V1.1.22 + + - The lpstat man page incorrectly listed the "-s" option + as using the equivalent of the "-p" option to list the + printers; it uses the "-v" option to list the printers + (STR #986) + - Now allow 0-length reads in the CUPS file API (STR + #985) + - cupsDoFileRequest() now sets cupsLastError() to + IPP_ERROR on network errors (STR #953) + - The pdftops filter didn't scale small pages up to the + output page size when the fitplot option was used (STR + #984) + - Fixed the ipptest program usage message (STR #959) + - Added Spanish man pages (STR #963) + - Fixed the order of comparisons in the client.conf + reading code (STR #971) + - cupsLangGet() incorrectly set the current locale (STR + #970) + + +CHANGES IN CUPS V1.1.22rc2 + + - The pdftops filter didn't check the range of all + integer attributes (STR #972) + - Documentation corrections (STR #944, STR #946) + - Also sanitize device URI in argv[0] (STR #933) + - cupsRasterReadHeader() didn't swap bytes for the + numeric fields properly (STR #930) + + +CHANGES IN CUPS V1.1.22rc1 + + - Now sanitize the device URI that is reported in the + error_log file (STR #920) + - Fixed some memory and file descriptor leaks in the job + dispatch code (STR #921) + - Deleting a printer could cause a crash with browsing + enabled (STR #865, STR #881, STR #928) + - Browsing would turn off if the scheduler got an EAGAIN + error (STR #924) + - The mime.types file didn't recognize PostScript as a + PJL language name (STR #925) + + +CHANGES IN CUPS V1.1.21 + + - The scheduler did not separate Digest authentication + parameters with commas (STR #882) + - Fixed some problems with image printing to custom page + sizes (STR #891) + - Removed the remaining scheduler code that did not use + the "close-on-exec" file descriptor flag to speed up + program invocations (STR #890) + - The "lpr -r" command removed the print file even if it + was not printed. It now only removes the file if the + job is successfully created (STR #886) + - Revamped the custom page size orientation fix (STR + #127) + - The lp, lpq, lpr, and lpstat commands now report when + an environment variable is pointing to a non-existent + printer instead of just saying "no default + destination" (STR #879) + - Queue names with 2 periods (e.g. "printer..2") were + not supported (STR #866) + + +CHANGES IN CUPS V1.1.21rc2 + + - Fixed a denial-of-service bug in the CUPS browse + protocol support (STR #863) + - The scheduler used a select() timeout of INT_MAX + seconds when there was nothing to do, which doesn't + work on IRIX (STR #864) + - Updated the cupsaddsmb program to use the new Windows + 2000 PostScript drivers instead of the Windows NT + printer drivers (STR #390) + - The gziptoany filter did not produce copies for raw + print jobs (STR #808) + - The cupsLangGet() function now uses nl_langinfo(), + when available, to get the current encoding (STR #856) + - Added a ReloadTimeout directive to control how long + the scheduler waits for jobs to complete before + restarting the scheduler (STR #861) + - Added a note to the default cupsd.conf file which + mentions that you must allow connections from + localhost for the command-line and web interfaces to + work (STR #850) + - The IPP backend incorrectly used the local port when + communicating with a remote server; this caused + problems with some custom configurations (STR #852) + - The cups-lpd mini-daemon wasn't using the right + default banner option (STR #851) + - Updated the new httpDecode64_2() and httpEncode64_2() + functions to handle arbitrary binary data, not just + text (STR #860) + - String options with quotes in their values were not + quoted properly by the scheduler (STR #839) + - Configure script changes for GNU/Hurd (STR #838) + - The lppasswd program was not installed properly by GNU + install when the installer was not root (STR #836) + - Updated the cups-lpd man page (STR #843) + - Fixed a typo in the cupsd man page (STR #833) + - The USB backend now defaults to using the newer + /dev/usb/lpN filenames; this helps on systems which + use the devfs filesystem type on Linux (STR #818) + - The config.h file did not define the HAVE_USERSEC_H + constant when the configure script detected the + usersec.h header file. This caused authentication + errors on AIX (STR #832) + - The lp and lpr commands now report the temporary + filename and error if they are unable to create a + temporary file (STR #812) + - Added ServerTokens directive to control the Server + header in HTTP responses (STR #792) + - Added new httpDecode64_2(), httpEncode64_2(), and + httpSeparate2() functions which offer buffer size + arguments (STR #797) + - The cupsGetFile() and cupsPutFile() code did not + support CDSA or GNUTLS (STR #794) + - The httpSeparate() function did not decode all + character escapes (STR #795) + - The cupstestppd program now checks for invalid Duplex + option choices and fails PPD files that use + non-standard values (STR #791) + - Updated the printer name error message to indicate + that spaces are not allowed (STR #675) + - The scheduler didn't handle HTTP GET form data + properly (STR #744) + - The pstops filter now makes sure that the prolog code + is sent before the setup code (STR #776) + - The pstops filter now handles print files that + incorrectly start @PJL commands without a language + escape (STR #734) + - Miscellaneous build fixes for NetBSD (STR #788) + - Added support for quoted system group names (STR #784) + - Added "version" option to IPP backend to workaround + serious bug in Linksys's IPP implementation (STR #767) + - Added Spanish translation of web interface (STR #772, + STR #802) + - The LPD backend now uses geteuid() instead of getuid() + when it is available (STR #752) + - The IPP backend did not report the printer state if + the wait option was set to "no" (STR #761) + - The printer state was not updated for "STATE: foo,bar" + messages (STR #745) + - Added new CUPS API convenience functions which accept + a HTTP connection to eliminate extra username/password + prompts. This resolves a previous authentication + caching issue (STR #729, STR #743) + - The scheduler did not correctly throttle the browse + broadcasts, resulting in missing printers on client + machines (STR #754) + - The scheduler did not pass the correct CUPS_ENCRYPTION + setting to CGI programs which caused problems on + systems which used non-standard encryption settings + (STR #773) + - The lpq command showed 11st, 12nd, and 13rd instead of + 11th, 12th, and 13th for the rank (STR #769) + - "make install" didn't work on some platforms due to an + error in the man page makefiles (STR #775) + - Changed some calls to snprintf() in the scheduler to + SetStringf() (STR #740) + + +CHANGES IN CUPS V1.1.21rc1 + + - Fixed some "type-punned" warnings produced by GCC when + -fstrict-aliasing is specified (STR #679) + - The PDF filter incorrectly calculated the bounding box + of a page (STR #682) + - The IPP backend did not use SSL when printing over a + port other than 443 (STR #730) + - The scheduler could crash when processing a Limit or + LimitExcept directive (STR #728) + - The lpq, lpr, and lp commands did not differentiate + between the server being unresponsive and the lack of + a default printer (STR #728) + - The PAM checks in the configure script did not stop + after the first match (STR #728) + - The cups-config man page was incorrectly placed in + section 3 (STR #728) + - The cupstestppd utility did not show a warning message + when a PPD file indicated BCP protocol support with + PJL (STR #720) + - The scheduler did not return the correct exit code + when startup failed (STR #718) + - The cupsRasterReadPixels() function checked for + EAGAIN, which caused problems on FreeBSD (STR #723) + - The cupsGetDests() function did not use the current + encryption setting (STR #653) + - The scheduler did not properly parse name-based + BrowseRelay directives in the cupsd.conf file (STR + #711) + - The IPP backend now supports the following options in + the device URI: encryption, waitjob, and waitprinter + (STR #699) + - The parallel, serial, socket, and USB backends did not + return a non-zero exit status when a job failed to + print in the middle of sending it (STR #715) + - Location directives in the cupsd.conf file were + case-sensitive for printer and class names, so + queue-specific access control was not reliable (STR + #700) + - cupsDoFileRequest() did not handle HTTP continue + status messages in all cases, causing sporatic + problems with IPP printers from some vendors (STR + #716) + - The rastertodymo driver now supports the Zebra ZPL + language (STR #713) + - The test suite no longer generates a printcap file, + which caused problems when testing as the root user + (STR #693) + - The scheduler now updates the accepting state of an + implicit class based upon the accepting state of its + member printers (STR #697) + - The pstops filter didn't properly skip leading PJL + commands (STR #664) + - The reinterpret_cast keyword was not highlighted when + printing C/C++ source files in prettyprint mode (STR + #694) + - Fixed a segfault problem with some of the client + programs (STR #668) + - When using RunAsUser, the scheduler did not correctly + set the ownership of the log files, preventing log + file rotation (STR #686) + - The image filters did not correctly load 1-bit PNG + files (STR #687) + - The pdftops filter did not show all annotation objects + in a PDF file (STR #674) + - The pdftops filter did not print the contents of + textual form elements, making it impossible to print a + filled-in form (STR #663) + - Integrated the MacOS X/Darwin USB backend into the + CUPS baseline (STR #661) + - The USB backend incorrectly reported "media tray + empty" (STR #660) + - The scheduler did not use a case-insensitive + comparison when checking for group membership, which + caused problems with Win9x clients printing via SAMBA + (STR #647) + - The scheduler did not report the addresses associated + with certain network errors, making troubleshooting + difficult (STR #648, #649) + - The cupstestppd program did not allow a default choice + of "Unknown" as required by the PPD spec (STR #651) + - The select() buffers are now allocated to be at least + as large as sizeof(fd_set) (STR #639) + - The LPD backend now supports overriding the print job + username via the device URI (STR #631) + - The scheduler did not handle an unknown MIME type when + checking for a CGI script (STR #603) + - Added a timeout optimization to the scheduler's main + loop to allow CUPS to sleep more of the time (STR + #629) + - The USB backend now retries printing to devices of the + form "usb://make/model" if any USB port shows up as + "busy" (STR #617) + - The httpGetHostByName() function did not range check + IP address values (STR #608) + - The httpUpdate() function could return HTTP_ERROR + instead of the HTTP status if the server closed the + connection before the client received the whole + response (STR #611) + - The LPD mini-daemon did not allow the administrator to + force banner pages on (STR #605) + - Added PAM support for Darwin/MacOS X (STR #550) + - The web interface now provides a "Set As Default" + button to set the default printer or class on a server + (STR #577) + - The HTTP authentication cache was broken (STR #517) + - The cupstestppd utility now fails PPD files that have + a DefaultOption keyword for a non-existance option + name (STR #476) + - Optimized the scanning of new PPD files on scheduler + startup (STR #424) + - The EPM list file did not include the bin, lib, or + sbin directories (STR #598) + - The web interface did not redirect administration + tasks to the primary server for a class or printer + (STR #491, #652) + - The cups-lpd mini-daemon did not reject print jobs to + queues that were rejecting new print jobs (STR #515) + - Some calls to the ctype functions did not account for + platforms that use a signed char type by default (STR + #518) + - The scheduler could use excess amounts of CPU if a CGI + program was sending data faster than the client could + take it (STR #595) + - Updated the Ghostscript 8.x integration stuff (STR + #484) + - The lpd backend used a source port of 732 by default, + which is outside of the range defined by RFC 1179; + also added a new (default) "reserve=any" option for + any priviledged port from 1 to 1023 (STR #474) + - The scheduler did not check for a valid Listen/Port + configuration (STR #499) + - The cupsPrintFiles() function did not always set the + last IPP error message (STR #538) + - The pstops filter did not write the PostScript header + line if the file began with a PJL escape sequence (STR + #574) + - The printer-is-accepting-jobs status of remote + printers was not sent to clients via browsing or + polling (STR #571) + - Browse packets did not indicate whether a printer + was accepting or rejecting jobs. + - The web interface did not show the printer state + history information (STR #592) + - The rastertoepson filter would crash under certain + cirsumstances (STR #583) + - The USB backend did not handle serial numbers using + the (incorrect) SN keyword and did not terminate the + make and model name strings properly (STR #471, STR + #588) + - The USB backend did not build on Solaris x86 (STR + #585) + - The cupsDoAuthentication() function did not use the + method name for Digest authentication (STR #584) + - The scheduler could crash if a print job could not be + printed and the PreserveJobHistory option was turned + off (STR #535) + - cups-lpd now logs the temporary filenames that could + not be opened in order to make troubleshooting easier + (STR #565) + - cupsGetJobs() now returns -1 on error (STR #569) + - Added localization for Belarusian (STR #575) + - The LPD backend used the full length of the hostname + when creating the data and control filenames, which + causes problems with older systems that can't handle + long filenames (STR #560) + - The scheduler did not refresh the common printer data + after a fast reload; this prevented banner and other + information from being updated (STR #562) + - The scheduler did not send common or history data to + the client when processing a CUPS-Get-Default request + (STR #559) + - The httpFlush() function did not always flush the + remaining response data in requests (STR #558) + - The scheduler could complete a job before it collected + the exit status from all filters and the backend (STR + #448) + - The PPD conformance tests did not catch group + translation strings that exceeded the maximum allowed + size (STR #454) + - Updated the client code in the scheduler to close the + client connection on errors rather than shutting down + the receive end of the socket; this caused resource + problems on some systems (STR #434) + - cups-polld didn't compile on Tru64 5.1B (STR #436) + - "lpc stat" crashed if the device URI was empty (STR + #548) + - The scheduler did not compile without zlib (STR #433) + - std:floor() cast needed on IRIX 6.5 with SGI C++ + compiler (STR #497) + - cupsRasterReadPixels() and cupsRasterWritePixels() did + not handle EAGAIN and EINTR properly (STR #473) + - RequiresPageRegion should not be consulted for Manual + Feed (STR #514) + - International characters were not substituted in + banner files properly (STR #468) + - Updated pdftops to Xpdf 2.03 code to fix printing bugs + (STR #470) + - The Digest authentication code did not include the + (required) "uri" attribute in the Authorization + response, preventing interoperation with Apache + (STR #408) + - The web interface could lockup when displaying certain + URLs (STR #459) + - The PostScript filters now convert underscores ("_") + to spaces for custom classification names (STR #555) + + +CHANGES IN CUPS V1.1.20 + + - The pstops filter didn't properly handle collated, + duplexed copies of documents with an odd number of + pages on printers that did not do their own collated + copies (STR #389) + - Tru64 doesn't define a prototype for hstrerror() (STR + #430) + - Updated the pdftops filter to use the annotation flags + instead of the subtype to determine whether to print + an annotation (STR #425) + - The French web interface localization did not use + absolute paths for the navigation bar (STR #428) + - The CUPS test suite did not undefine the PRINTER and + LPDEST environment variables. This could lead to bogus + test results (STR #380) + - The cupsLangDefault() function now works if you don't + have the base OS localization installed (STR #418) + - The pdftops filter no longer needs to create temporary + files with tmpnam (STR #406) + - The HTTP code did not use a case-insensitive + comparison when checking for the Basic authentication + method (STR #407) + - The httpEncode() function always added a trailing "=" + character, which is not required by the Base64 + encoding specification (STR #407) + - The signal handlers did not need to call sigset(); + this caused a recursion problem on some versions of + IRIX (STR #422) + - Moved the scheduler termination code into the mainline + to be consistent with the way other signals are + handled (STR #423) + - The cupsaddsmb program didn't export the new CUPS + driver for Windows properly (STR #390) + - The ppdOpen() functions did not issue an error when a + translation string exceeded the maximum allowed by the + Adobe PPD specification (STR #399) + - The default landscape orientation was not the same as + that defined in the PPD file (STR #397) + - Updated the pstoraster patch files and CUPS driver to + work with Ghostscript 8 (STR #402) + - The hpgltops filter did not skip PJL commands (STR + #379) + + +CHANGES IN CUPS V1.1.20rc6 + + - "lp -i jobid -H restart" would often return an error + even though the job restarted successfully (STR #362) + - The scheduler did not check for invalid allow/deny + addresses such as "11.22.33.44/24". It now masks off + the extra address bits and logs a warning message in + the error_log file (STR #337) + - The cupstestppd utility now checks for missing + ImageableArea and PaperDimension attributes for each + defined PageSize (STR #365) + - The IPP code did not wait for a reply indefinitely on + HTTP connections in "blocking" mode (STR #377) + - The web interfaces did not rewrite the default printer + URI properly (STR #299 and #369) + - The LPD backend passed the C and L commands in the + wrong order (STR #378) + - The Dymo label printer driver did not set the label + length properly (STR #373) + - The scheduler did not support job IDs higher than + 99999 (STR #371) + - The Visual C++ project files did not work (STR #366) + - The scheduler's cupsLangSeek() function did not reset + the "EOF" flag, preventing compressed files from being + typed properly in some cases (STR #368) + - The cupsLangGet() cache was only used if the locale + name provided an explicit character set name (STR + #354) + - The CUPS API convenience functions did not call + cupsLangFree() when they were done with the + localization data (STR #354) + - The scheduler did not return the + job-hold-until-supported or job-hold-until-default + attributes (STR #356) + - The cupsaddsmb program did not support the new CUPS + driver for Windows (STR #357) + + +CHANGES IN CUPS V1.1.20rc5 + + - The scheduler did not initialize the browse socket + file descriptor properly when only SLP browsing was + enabled (STR #259) + - The scheduler accessed the job attributes before they + were set (STR #347, fix to STR #335) + - The cupsCancelJob() function did not return 0 when the + job could not be canceled (STR #340) + + +CHANGES IN CUPS V1.1.20rc4 + + - The scheduler did not move the incoming job attributes + in the operation group to the job group (STR #335) + - The cupsDoFileRequest() function did not check for an + early HTTP response while sending the file (STR #314) + - The web interfaces did not quote #, ?, or . in printer + names, which caused some problems with the generated + URLs (STR #320) + - CUPS couldn't be completely compiled with the -dDEBUG + option (STR #331) + + +CHANGES IN CUPS V1.1.20rc3 + + - More SLP changes (STR #259) + - Revamped the child signal handling code to completely + avoid deadlock issues on Solaris (STR #325) + - The lpadmin command displayed an incorrect error + message when the "-u" option was provided with no + arguments (STR #313) + - The web admin interface did not display an error + message if the PPD file could not be loaded (STR #308) + - The ppdEmit() functions did not use the correct + orientation value position for custom page sizes (STR + #292) + + +CHANGES IN CUPS V1.1.20rc2 + + - The serial backend set the IXANY option on the port + for XON/XOFF flow control; this caused problems with + printers that returned status info but were not ready + for more print data (STR #287) + - The scheduler didn't support scripted index files + (index.php, index.pl, etc. - STR #290) + - The scheduler did not correctly localize script files + with "GET" variables (STR #268) + - Changes in job classification are now logged (STR + #289) + - Fixed a few more SLP-related bugs (STR #259) + - Updated the user/group configure checks for MacOS X + 10.3 (STR #270) + - Fixed an offset bug in the PDF filter (STR #284) + - The cupsDoRequest() and cupsDoFileRequest() functions + did not map several HTTP status codes to their IPP + counterparts. This made detecting certain conditions + very difficult (STR #277) + - Config, spool, and status files are now owned by the + scheduler user (usually root) with read permission for + the filter group (STR #283) + - The HP-GL/2 filter did not support the SI command, + some values for the AD and SD commands, and did not + rotate labels properly via the DI command (STR #282) + - The fax support did not update/set the job-hold-until + attribute when a fax job fails (STR #269) + - The cupsLangGet() function didn't support locales of + the form "ll.charset" (STR #271) + - The scheduler did not use the charset when getting the + language localization for a request; this caused extra + disk IO for every request (STR #271) + - The scheduler did not support requests with more than + one language specified (STR #267) + + +CHANGES IN CUPS V1.1.20rc1 + + - The scheduler now waits up to 60 seconds before + restarting to allow active jobs to complete printing + and pending requests to be processed (STR #226) + - The web interface did not work on systems where time_t + is 64 bits (STR #262) + - Added backend tweeks and content-length check from Red + Hat (STR #253) + - The USB backend now uses the 8255 constants instead of + the standard constants when reporting printer status + bits on Linux (STR #254) + - Added new cupsDoAuthentication(), cupsGetFd(), + cupsGetFile(), cupsPutFd(), and cupsPutFile() functions + to the CUPS API (STR #112) + - The PDF filter always scaled and offset pages; this + caused problems under MacOS X, so now the "fitplot" + option controls whether PDF files are scaled to fit + within the printable area of the page (STR #250) + - The LPD backend did not support the port number in a + URI (STR #247) + - Some filters didn't properly support boolean options + (STR #249) + - Landscape PDF files were not always offset by the + correct amount when rotating (STR #243) + - The scheduler could hang in a call to localtime() when + logging messages from the signal handler (STR #242) + - The PDF filter no longer prints form widgets; this + duplicates the behavior of Acrobat Reader (STR #241) + - cupsGetPPD() didn't handle a late termination of a + HTTP connection with the server (STR #220) + - ppdOpen() did not correctly check for "*PPD-Adobe-4." + on the first line of a PPD file. This caused incorrect + PASS results for some PPD files (STR #233) + - cupsEncodeOptions() did not allow boolean options to + use "yes" and "on" for true values (STR #227) + - The pstops filter only sent the TBCP exit sequence if + it was defined in the JCLEnd attribute in the PPD file + (STR #224) + - Support for more than 1024 files was broken on Solaris + 9 (STR #217) + - The setgroups() calls now pass in 1 group (the + configured group) instead of 0 for compatibility with + BSD and Darwin (STR #213) + - The scheduler's built-in broadcast throttling was + ineffective since incoming packets would cause the + next group of outgoing packets to be sent immediately + rather than waiting for the next time slot (STR #211) + - Added a new ppdSetConformance() function to set the + conformance requirements for PPD files. Currently only + two levels are defined, PPD_CONFORM_RELAXED and + PPD_CONFORM_STRICT, and the default is the relaxed + level (STR #212) + - The IPP backend did not correctly execute the + pictwpstops filter on OSX (STR #210) + - The LPD backend did not set the banner class when the + "banner=yes" option was specified in the device URI + (STR #209) + - The imagetoraster filter did not support all of the + page device attributes (STR #208) + - The pdftops filter incorrectly auto-rotated pages when + the user already had specified the proper orientation + (STR #207) + - Fixed AIX shared library support (STR #201) + - Added support for live testing with Valgrind (STR + #193) + - The CGI programs now collect the list of needed + attributes for the class, job, and printer template + files (STR #192) + - The scheduler now passes the first port that is bound + to the local loopback or "any" addresses to the CGI + programs rather than the port that the browser + connected to (STR #103) + - The cupstestppd program now checks for bad + JobPatchFile attributes and incorrect versions of the + Manufacturer attribute for HP printers (STR #155) + - The filter makefile incorrectly installed + libcupsimage.a in the filter directory (STR #180) + - The scheduler did not verify that the job history + files define the job-priority and + job-originating-user-name attributes (STR #178) + - The pstops filter didn't handle poorly-formed binary + PostScript files that had CTRL-D's in them (STR #156) + - The ppdOpen*() and cupsLangGet() functions did not + make a copy of the old locale strings when using the + POSIX locale when reading files, which apparently + caused problems with some implementations of the + standard C library. (STR #159) + - The pdftops filter did not work properly with some + embedded Type1C fonts (STR #177) + - Updated the pdftops filter to be based upon Xpdf + 2.02pl1 (STR #191) + - The scheduler did not reset the group list when + running CGI and filter processes (STR #185) + - The scheduler no longer calls malloc and free from the + signal handlers (STR #190) + - The USB backend now uses the manufacturer and model + strings if the description string is not available + (STR #174) + - The ppdOpen functions still supported the + VariablePaperSize attribute, which was removed in v4.0 + of the PPD spec. This caused problems with PPD files + that relocated the PageSize option to a non-standard + group (STR #158) + - The cups.list file referenced MAN1EXT, MAN3EXT, and + MAN5EXT, but none of those were actually defined (STR + #147) + - Chunked requests could cause a Denial of Service if + the connection is terminated before the first byte of + chunk data is sent/received (STR #143) + - Printers with special characters in their names were + not accessible from the web interface (STR #120) + - The lpstat command now shows the correct interface + script or PPD file, if any, for a print queue (STR #89) + - The lpstat command now shows the printer-state-message + and printer-state-reasons attributes whenever they are + not blank (STR #152) + - The French and German option-conflict.tmpl template + files did not get installed (STR #148) + - The cups.list.in file did not work when compiling + without shared libraries (STR #149) + - The DSOFLAGS included the LDFLAGS, which causes + problems on at least HP-UX (STR #150) + - The fax printer support did not keep track of the fax + capability bit (STR #144) + - The appleLangDefault() function could leak a small + amount of memory (STR #145) + - The ppdOpen() functions now mirror all normal + attributes to the attribute list; previously only + certain unassigned attributes would be added (STR + #139) + - The ppdEmitJCL() function wrote JCL commands to stdout + instead of the passed file pointer (STR #142) + - The httpGets() function could, in certain states, + block waiting for data (STR #132) + - The cupsEmitJCL() function not outputs an empty @PJL + command after the PJL language escape to work around + bugs in certain PJL implementations (STR #131) + - The cupsEmit*() functions didn't set the orientation + value properly (STR #127) + - The cups.spec file didn't list the rc2.d init + directory or the cupstestppd file (STR #134) + + +CHANGES IN CUPS V1.1.19 + + - The GNU TLS code incorrectly used + gnutls_check_pending() instead of + gnutls_record_check_pending() (STR #128) + - The ppdEmit() functions output "PageSize Custom" + instead of "CustomPageSize True" in the DSC comments. + Also, the custom page size code did not use the + ParamCustomPageSize attributes (STR #127) + - The cupstestppd command did not list the conflicting + options (STR #123) + - The lpq command did not ensure that there was + whitespace between the fields in the job listing (STR + #117) + - The German web templates had errors (STR #119) + - The configure script didn't specify the static + libraries properly when configuring with the + --disable-shared option (STR #104) + - The cups.list file used file dependencies for package + formats other than portable, RPM, and Debian (STR #98) + - cupsLangGet() didn't use its language cache (STR #97) + - "lpq -P" would segfault instead of showing a usage + message (STR #94) + - Fixed compiler warnings in pdftops filter (STR #96) + + +CHANGES IN CUPS V1.1.19rc5 + + - Jobs with banner pages that were printed to implicit + classes would get double banner pages for each + file/banner in the job (STR #68) + - The mime.convs file was missing the filter definition + for Windows BMP (image/x-bitmap) files (STR #85) + - The scheduler allowed some READ-ONLY job attributes to + be set, which could cause the scheduler to fail on the + next restart (STR #82) + - The lp and lpr commands did not report when the + scheduler was not responding; instead, the user would + incorrectly see a "no default destination" error (STR + #70) + - cupsLangGet() could fail on OSX due to a corrupt + language preference (STR #78) + - Added more checks for HTTP request timeouts. + - The scheduler dropped the first non-alpha character + after an open brace when doing attribute substitutions + in banner pages (STR #77) + - The scheduler child might send SIGUSR1 to the parent + before the signal handler was installed; this didn't + prevent the scheduler from starting but produced an + annoying error message (STR #45) + + +CHANGES IN CUPS V1.1.19rc4 + + - The lp command did not accept "-" for printing from + the standard input as required by POSIX 1003.1 (STR + #59) + - Added the job-originating-host-name information for + the page_log file documentation in the SAM (STR #31) + - The German web interface templates did not use the + right paths for job operations (STR #54) + - The scheduler would consume all available CPU if + started with a pending job in the queue (STR #35) + - The polling daemon allocated an extra localization + buffer but did not free it, causing cups-polld to + eventually use all available memory (STR #40) + + +CHANGES IN CUPS V1.1.19rc3 + + - The scheduler could get in an infinite loop cancelling + jobs using "cancel -u user dest" (STR #48) + - The "cancel -u user" command did nothing (it should + cancel all jobs on all printers owned by the named + user - STR #48) + - The scheduler would write 0-length job control files + (STR #46) + - Updated the French man pages (translation provided by + Gilles QUERRET) + - The scheduler would delete all printers from + printers.conf if a job was active when a HUP signal + was handled (STR #47) + - The cups-polld program would leak memory if it was + unable to send browse packets to the loopback + interface (STR #40) + - The scheduler did not put the + job-originating-host-name attribute in the job + attributes group. + - The text filter did not default to wrapping text as + defined by the IPP implementation document. + - Scan backends first, PPDs second (STR #37) + - Updated the Netatalk documentation in the SAM (STR #38 + and #39) + - The test suite sent text files to a non-PS print queue, + which requires ESP Ghostscript (provided separately). + Now send the JPEG test file (STR #33) + - The test suite did not show the estimated disk space + requirements (STR #33) + - The test suite did not set the MaxLogSize directive to + 0 to prevent log file rotation (STR #33) + - The test suite still setup the old CUPS Ghostscript + symlinks (STR #33) + - The pstops filter did not report the correct number of + copies for the page_log file when printing collated + copies to a printer that doesn't support them in + hardware (STR #32) + - cupsLangGet() needs to set the CTYPE locale to "C" + (POSIX) to avoid erroneous tolower/toupper values (fix + suggested by Bjoern Jacke) + - Fixed a typo in the cups.list.in file. + - Updated all of the Western European locales to default + to ISO-8859-15 (for Euro support, suggested by Bjoern + Jacke) + - Updated the German message catalog (update provided by + Bjoern Jacke) + + +CHANGES IN CUPS V1.1.19rc2 + + - cupsLangGet() now sets the encoding field based on the + trailing charset in the locale name, and doesn't look + for a message catalog in a specific locale.charset + directory. This fixes STR #26 and is more in line + with the CUPS 1.2 implementation. + - The configure script now aborts if the "ar" command or + compilers cannot be found. + - The static cupsimage library was not built by default. + - The path for the "ln" command was hardcoded in + Makedefs.in instead of being checked at configure time + (STR #28). + - Banner pages containing unescaped { characters would + not work. + - The printer-state-time collection attribute was + encoded as an enumeration instead of an integer. + - The printer-is-accepting-jobs collection attribute was + was not added to the collection value. + - The printer-state-sequence-number collection attribute + was not added to the collection value. + - Fixed typo and const mismatch in IPP backend. + - Updated the man pages for the new configuration + directives. + - Updated the SAM for MacOS 10.2, the CUPS drivers for + windows, the available LPD backend options, and the + new configuration directives. + - The imagetops filter didn't position images properly + on the page (STR #18) + - The configure script didn't add CPPFLAGS to the + compiler options or LDFLAGS to the DSO options (STR + #13) + - The scheduler would try to write a debug log message + when starting a job that contained a NULL string. + Since not all versions of snprintf() support NULL + string pointers this caused some problems (STR #20) + - The testipp program now supports reading of IPP + message files such as those used for the job history + in /var/spool/cups. + + +CHANGES IN CUPS V1.1.19rc1 + + - Added CUPS support files for Java, Perl, and PHP + (located in the "scripting" subdirectory...) + - The scheduler now supports fast-reloads of the + cupsd.conf file when it is updated via HTTP. + - The scheduler always changed the ownership of log + files; it now only does so if they are not in the /dev + directory (i.e. don't want to change the ownership and + permissions of /dev/null...) + - Added libpaper support (patch from Jeff Licquia) + - Added a new istring() rule for MIME types files that + does a case-insensitive comparison of strings. + - The cups-lpd mini-daemon now sends jobs to the default + queue when an empty queue name (or "lp" and there is + no "lp" queue) is sent. + - The scheduler now supports fax queues identified by a + "*cupsFax: True" attribute in the PPD file. When a job + can't be sent, it is held for 5 minutes by default + while other jobs are attempted. The FaxRetryLimit and + FaxRetryInterval directives control the number of + retries and the time between retries. + - The scheduler now preserves the default options of PPD + files when modifying/upgrading an existing PPD file. + When installing a new printer, the scheduler sets the + default media size to Letter or A4 as appropriate for + your locale. + - The scheduler no longer limits the number of + BrowseAddress, BrowsePoll, BrowseRelay, Listen, Port, + SSLListen, and SSLPort directives to 10. + - The scheduler now supports print files that have been + compressed using gzip. + - The scheduler used the stdio functions to read any job + ticket information in a PostScript print job. Since + some platforms limit the number of stdio files to 256, + job ticket information was ignored when the server had + a large number of clients connected to the system. + - Filters and backends may now report the total number + of pages ("PAGE: total NNN") to the scheduler. + - The LPD backend now supports timeout and + sanitize_title options (default to 300 and yes, + respectively) and has some additional changes to + reduce the chances of multiple copies being printed + when only one copy was requested. + - Fixed a polygon drawing bug in the HP-GL/2 filter. + - Added a robots.txt file to the standard install to + prevent search engines from indexing the CUPS server. + - Added support for STATE: messages + (printer-state-reasons), printer-state-history, and + printer-state-time to the scheduler. + - When using RunAsUser, the scheduler would initially + start any previously queued (pending) jobs with + RunAsUser disabled - all backends would be running as + root. + - If a backend failed for a printer, CUPS would + incorrectly requeue the job for printing again. + - Added support for IPP collections and files. + - Added experimental support for generic CGI scripts and + programs, Java, Perl, PHP, and Python to the + scheduler. See the file "CGI.txt" for more + information. + - The CUPS API now supports HTTP cookies and the Expect: + field. + - The cancel command now correctly supports the "-u + user" option to cancel all jobs for the named user. + - The Purge-Jobs operation now supports the my-jobs + boolean attribute and a new purge-jobs boolean + attribute to control whether job history data is + purged from the scheduler; the default is false for + my-jobs and true for purge-jobs to match the original + implementation. + - The scheduler would not timeout printers when only + using SLP browsing. + - If the scheduler was unable to execute a filter, it + would try to restart the job indefinitely until the + filter could be executed. + - When writing BSD printcap files, the scheduler now + includes the rm and rp attributes, allowing the file + to be exported to LPD clients. [Patch from Dominic + Kubla] + - The scheduler optimization to reference IPP attribute + data instead of performing a full copy caused problems + when the referenced data was deleted before it was + sent. It now only references attributes that change + only when the scheduler is restarted. The change also + reduced the memory footprint of a printer object to + 2k. + - The scheduler now holds signals while logging messages + to avoid potential deadlock issues when handling + signals on Solaris 8. + - The lpadmin command now allows printer access control + by group name as well as user name. + - "lpoptions -l" got in an infinite loop if no default + printer was available. + - The scheduler now logs the job-originating-host-name + attribute in the page_log file, and uses "-" for any + empty fields (patch from Dominik Kubla). + - The pdftops filter now scales PDF pages within the + printable area of the page. + - The pstops filter didn't include the page-label and + classification boxes when printing EPS or non- + conformant PS files. + - The imagetops filter didn't always correctly position + the image on the page when printing in landscape + orientation. + - The ppdEmit() functions now support the + RequiresPageRegion attribute when sending InputSlot + and ManualFeed commands. + - The PPD loading code now supports standard options + outside of OpenUI/CloseUI as required by the PPD spec. + - The cupstestppd program has been upgraded to provide a + concise PASS/FAIL report, additional detailed + conformance testing, and support for gzip'd PPD files. + - The PPD loading code is now much more strict when + loading a PPD file, and tracks more format errors. + - The scheduler ignored child signals when gathering the + list of available devices, when it should have been + using the default signal handler. + - The cupsEncodeOptions() function could encode an + option with a NULL last string. + - The socket backend could report the wrong number of + backchannel bytes if an error occurred on the link. + - The cups-polld program now only sleeps after getting + all printers and classes. This allows for longer + intervals without excessive delays before classes show + up... + - Added a new httpWait() function to support waiting for + data for a specific number of milliseconds. + - httpGets() now times out after 1 second on + non-blocking HTTP connections. + - The scheduler no longer accepts rangeOfInteger values + that are out of order (e.g. 5-1) + - The sides attribute was incorrectly sent as a name + value; it is a keyword value. + - The IPP backend now detects if the destination queue + has gone away and reports an error. + - The scheduler and HTTP API now allocate their select() + sets to support larger numbers of clients on systems + that support it. + - The scheduler now sets the CFProcessPath environment + variable under MacOS X. + - The cupsLangDefault() function now uses the + CoreFoundation localization API under MacOS X. + - The httpSeparate() function didn't handle file URIs of + the form "file:///path" properly. + - The lpadmin command now supports a "protocol" option + for specifying the binary communications protocol to + use when printing binary PostScript data. + - The scheduler did not properly parse the SystemGroup + directive, so only the first group would be used. + - Revamped how strings are stored in the scheduler, + providing a substantial improvement in memory usage + for systems with large numbers of printers. + - The PostScript filter now supports binary PostScript + files and files beginning with the PJL language escape + sequence. + - The PPD API now provides additional information from + the PPD file. + - The USB backend didn't compile on Solaris Intel. + - The cupstestppd utility now supports the "-q" option + (quiet) for use in scripts, etc. + - Merged several weight-reducing changes into the CUPS + baseline donated by Apple. + - Added preliminary support for CDSA; patch provided by + Apple. + - Implicit classes are now created from identical + printer classes on the network. + - The lp command now supports a "-H restart" option to + restart previously printed jobs. This functionality + only works if you have enabled the PreserveJobFiles + option. + - The scheduler now supports URIs in HTTP request lines + to conform to the HTTP/1.1 specification. + - The time-at-xyz attributes were not recognized in + banner files if prefixed by a question mark, e.g. + "{?time-at-creation}". + - Added support for pre-filtering application/pictwps + files on MacOS clients before sending them to a server + via IPP. + - The scheduler now allows file:/dev/null device URIs + even if FileDevices is set to No. + - CUPS uses strerror() for hostname resolution errors, + when it should have used hstrerror(). + - The USB backend no longer tries to guess the serial + number of a device from the USB devices file; this + means that printers that don't report their serial + numbers in the device ID string will not be + individually selectable. + - The pstops filter didn't handle page ranges properly + when a page contained an embedded document. + - Added a translation of the web interface to German. + - When printing using the OutputOrder=Reverse option + with duplexing, the output order is now truly + reversed; the order of sub-pages when printing N-up is + the same. + - The pstops filter did not always output the extra + blank page when printing a document with an odd number + of pages with duplexing enabled. + - The ippAddXYZ functions no longer allow the + application to add less than 1 value. + - Fixed a URL rewrite bug in the web interface - local + access was sometimes redirected away from localhost... + - The ppdOpen() functions could get in an infinite loop + if the PPD file contained a keyword or text that was + too large for the buffer. + - Added preliminary support for GNU TLS; patch provided + by Jeff Licquia. + - Now timeout IPP attribute reads after 1 second inside + an attribute definition. + - Now timeout connections that have been shutdown (due + to errors) after 30 seconds instead of the Timeout + setting (300 seconds by default). This provides + faster recovery from DoS attacks. + - A denial-of-service attack warning message was being + written to the log files by the scheduler for every + detection. This caused a DoS of its own in some + situations. The warning message is now written no more + than once per minute. + - Fixed the CIE colorspace support code in the image and + PS RIPs. + - The job-quota-period, job-page-limit, and job-k-limit + attributes were not flagged as integers, so setting + quotas would not work. + - Added an additional response check in the scheduler to + more quickly recover from denial-of-service attacks. + - The cupstestppd file was incorrectly installed in the + /usr/sbin directory instead of /usr/bin. + - The EPM list file did not include the cupstestppd + program or man page files. + + +CHANGES IN CUPS V1.1.18 + + - Fixed a bug in the Set-Job-Attributes code in the + scheduler that would cause it to crash or continuously + write a job control file. + - SECURITY FIX: The scheduler now provides a FileDevice + directive to control whether new printers can be added + using device URIs of the form "file:/filename". The + default is to not allow printers with these device + URIs. + - The scheduler did not compute the cost of filters + properly, nor did it choose a multi-filter solution + with a lower cost than a single filter solution. + - Now install CUPS PPD file test utility (cupstestppd) + to support basic conformance testing of PPD files. + - The scheduler now logs an error message when it sees a + non-conforming PPD file. + - Upgraded pdftops filter to Xpdf 2.01 with fixes for + TrueType fonts. + - Added a MaxClientsPerHost configuration directive to + provide limited protection against Denial of Service + attacks. + - SECURITY FIX: Potential underflow/overflow bug in web + interface. + - SECURITY FIX: Race condition in certificate creation. + - SECURITY FIX: Bad URIs in browse packets could be used + to exploint the web interface underflow/overflow bug. + - SECURITY FIX: Some types of Denial of Service attacks + were not handled properly, so once the attack was over + the scheduler did not close the connections + immediately on all platforms. + - SECURITY FIXES: Added integer overflow/underflow + checks for all image formats. + - The pstops filter didn't reset the showpage operator + back to its original at the end of a job; this + prevented the concatenation of documents (used + primarily for CUPS 1.2...) + - The cupsGetPPD() function didn't always set the + cupsLastError() value when an error occurred. + - The IPP media, output-bin, and sides attributes took + precedence over the corresponding PPD options, which + caused inconsistent behavior under MacOS X with some + PPD files. + - The cupsaddsmb utility specified the wrong number of + arguments to the adddriver command when adding the + Win9x PostScript drivers. + - The web interface did not always report the correct + error message. + - The scheduler did not clear the POSIX signal action + structure when waiting for the child to send it a + SIGUSR1 signal; this could cause the signal handler + not to be called properly, preventing the parent + process from returning. + + +CHANGES IN CUPS V1.1.17 + + - The "manual_copies" option did not work when the LPD + backend had to retry a print job. + - The image filters did not convert GIF images properly. + - The RunAsUser option was incompatible with the new + daemon-mode code in 1.1.16. + - Fixed a problem with the Set-Job-Attributes and + PostScript job ticket code in the scheduler - the + "last" attribute pointer was never updated, which + could cause the scheduler to crash when applying job + ticket data. + - Fixed a problem in the scheduler that caused it to + continue processing HTTP requests on a connection + after it was shutdown. + - The scheduler now allows accounts authenticated via + PAM to not have a corresponding UNIX account, but + group membership still requires the account name to be + listed in the UNIX group file(s)... + - The scheduler used a fixed-size (16k) buffer for + encoding job options for filters; it now dynamically + allocates and expands the buffer as needed depending + on the options that are sent in a job. + - The pdftops filter didn't support all of the MacOS + characters for MacRoman encoded fonts. + - The cupsEncodeOptions() and cupsParseOptions() + functions now conform to the grammer defined by the + current draft of the PAPI specification. The main + difference is that option=yes and option=no are no + longer treated as boolean options. + - The IPP backend didn't honor the encryption settings + in /etc/cups/client.conf. + - Fixed a potential bug in the HTTP code which was + caused by servers sending the status line and + newline(s) in separate packets. + - User-defined classification strings are now printed + verbatim - previously the classification box would be + empty. + - Re-added Spanish to the list of PPD languages that + CUPS supports. + - CUPS API library user and temp file updates for + Windows. + - The image filters did not properly handle grayscale + printing of Sun Raster images. + - The scheduler never reset the NumJobs variable before + loading the job list (previously this only happened on + a full start, so the problem was never apparent...) + - The HTTP and IPP read/write code didn't handle EINTR + (interrupted system call) errors. + - When under high load, the scheduler could abort due to + the wrong errno value after a select() call. This was + caused by the child signal handler. + - Added new load tests to the test target to verify that + cupsd can handle hundreds of simultaneous jobs without + error. + - The Solaris USB backend now supports the new device + URI syntax. + - The ppdOpen*() functions now reset the numeric locale + settings while loading a PPD file. + - Fixed the libtool build rules. + - The manpage make rules didn't use $(MAKE) and + $(MFLAGS) for the language subdirectories. + - Now set the LC_TIME locale category to get the + properly localized time string. + - Fixed a problem in the scheduler that would cause the + web interface problems when adding, modifying, or + configuring a printer or class. + - The backends now ignore SIGPIPE so that failed job + filters will not stop a print queue. + - The lpstat command did not allow for destination lists + ("lpstat -v printer1,printer2") + - Fixed parsing of long filter status messages in the + scheduler. + - Added some startup performance enhancements to the + scheduler so that the printer object information is + regenerated fewer times and the MIME type database is + not filled with lots of empty filters for raw/direct + queues. + - The LPD backend now sends the job title as the print + filename. + - Added support for variable sizes in the EPSON dot + matrix printer drivers. This allows for pages as + short as 1/2" (1 row of labels) and does not do an + automatic form feed. + - French translation updates. + - The filters did not quote the page label string when + embedding it in PostScript output. + - The serial backend now enumerates serial ports under + MacOS X. + - The pdftops filter contained font rasterizer code that + wasn't being used and that depended on X11. This code + has been removed. + + +CHANGES IN CUPS V1.1.16 + + - The cancel and lprm commands now both display an error + message and return a non-zero exit status if an + attempt is made to cancel a job on a non-existent + printer. + - The lpoptions command incorrectly complained if a + request to delete a non-existent printer was made. + - If the client.conf file defines an alternate server + name, the "configure printer" action in the web + interface might not work. + - The lpstat command now supports a "-W" option so that + you can display completed jobs as well as + not-completed (pending) jobs. + - The lp and lpr commands did not return an error when + one or more files in a set of files for printing could + not be printed. + - The lp, lpadmin, and lpstat commands now consistently + return with a non-zero exit status when an error + occurs. + - The scheduler would not accept print jobs sent to a + stopped remote printer. + - The texttops filter incorrectly converted the page + numbers in the prettyprint header to double-byte + characters when printing a non-Unicode text file. This + caused an extra space to appear between each digit in + the page number. + - The scheduler did not use a case-insensitive + comparison when adding filters for a printer. + - Upgraded the pdftops filter to Xpdf 1.01. + - 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 indefinitely. 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 + license exception. + - 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 instead of + . + - 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... + + +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 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 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. + + +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, , , 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 , 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. diff --git a/CHANGES-1.2.txt b/CHANGES-1.2.txt new file mode 100644 index 0000000000..7b0b1f2de1 --- /dev/null +++ b/CHANGES-1.2.txt @@ -0,0 +1,1261 @@ +CHANGES-1.2.txt +--------------- + +CHANGES IN CUPS V1.2.12 + + - The PHP cups_print_file() function crashed if the options + array contained non-string option values (STR #2430) + - The image/tiff file matching rule incorrectly identified + some text files as TIFF files (STR #2431) + - The filter(7) man page incorrectly documented the + "PAGE: total #-pages" message (STR #2427) + - PCL text files were mis-identified as HP-GL/2 and + caused the HP-GL/2 filter to hang (STR #2423) + - When printing to a queue with user ACLs, the scheduler + incorrectly returned a quota error instead of a "not + allowed to print" error (STR #2409) + - cupsaddsmb could get in a loop if no printer drivers + were installed (STR #2407) + - cupsRasterReadHeader() did not byte-swap the header + properly when compiled with certain versions of GCC. + - The IPP backend did not send the document-format + attribute for filtered jobs (STR #2411) + - Some PPD files could cause a crash in ppdOpen2 (STR + #2408) + - The web admin interface incorrectly handled the "share + printers" and "show remote printers" settings (STR + #2393) + - The scheduler's log messages about AuthClass and + AuthGroupName advised using a replacement directive but + had the wrong syntax (STR #2400) + - Updated the PostScript/PJL and HP-GL/2 MIME rules to + look in the first 4k of the file, not just the first 1k + (STR #2386) + - Updated the Italian localization (STR #2382) + + +CHANGES IN CUPS V1.2.11 + + - Fixed the "relaying from" log message (STR #2376) + - Updated the launchd support on Mac OS X to better + support reconfiguration. + - "make distclean" didn't remove all generated files + (STR #2366) + - Fixed a bug in the advertisement of classes (STR + #2373) + - The IPP backend now stays running until the job is + actually printed by the remote server; previously + it would stop monitoring the job if it was held or + temporarily stopped (STR #2352) + - PDF files were not always printed using the correct + orientation (STR #2348) + - The scheduler could crash if you specified a bad file: + URI for a printer (STR #2351) + - The Renew-Subscription operation now returns the + notify-lease-duration value that was used (STR #2346) + - The IPP backend sent job options to IPP printers, + however some printers tried to override the options + embedded in the PS/PCL stream with those job options + (STR #2349) + - ppdLocalize() now also tries a country-specific + localization for when localizing to a generic locale + name. + - The cupstestppd program now allows for partial + localizations to reduce the size of universal PPD + files. + - Chinese PPD files were incorrectly tagged with the + "cn" locale (should have been "zh") + - The backends now manage the printer-state-reasons + attribute more accurately (STR #2345) + - Java, PHP, Perl, and Python scripts did not work + properly (STR #2342) + - The scheduler would take forever to start if the + maximum number of file descriptors was set to + "unlimited" (STR #2329) + - The page-ranges option was incorrectly applied to the + banner pages (STR #2336) + - Fixed some GCC compile warnings (STR #2340) + - The DBUS notification code was broken for older + versions of DBUS (STR #2327) + - The IPv6 code did not compile on HP-UX 11.23 (STR + #2331) + - PPD constraints did not work properly with custom + options. + - Regular PPD options with the name "CustomFoo" did + not work. + - The USB backend did not work on NetBSD (STR #2324) + - The printer-state-reasons attribute was incorrectly + cleared after a job completed (STR #2323) + - The scheduler did not set the printer operation policy + on startup, only on soft reload (STR #2319) + - The AP_FIRSTPAGE_InputSlot option did not clear any + ManualFeed setting that was made, which caused problems + with some PPD files (STR #2318) + - cupsDoFileRequest() and cupsDoRequest() did not abort + when getting an error in the response (STR #2315) + - The scheduler did not schedule jobs properly to remote + or nested classes (STR #2317) + - Updated the mime.types and mime.convs headers to warn + that the files are overwritten when CUPS is installed. + Local changes should go in local.types or local.convs, + respectively (STR #2310) + - The scheduler could get in an infinite loop if a + printer in an implicit class disappeared (STR #2311) + - The pstops filter did not handle %%EndFeature comments + properly (STR #2306) + - Fixed a problem with the Polish web page printer icons + (STR #2305) + - ppdLocalize() now also localizes the cupsICCProfile + attributes. + - The scheduler still had a reference to the incorrect + "notify-recipient" attribute (STR #2307) + - The "make check" and "make test" subscription tests did + not set the locale (STR #2307) + - The "make check" and "make test" subscription tests + incorrectly used the notify-recipient attribute instead + of notify-recipient-uri (STR #2307) + - cupsRasterInterpretPPD() incorrectly limited the + cupsBorderlessScalingFactor when specified in the + job options. + + +CHANGES IN CUPS V1.2.10 + + - ppdLocalize() now supports localizing for Japanese + using the "jp" locale name used by the ppdmerge + program from the CUPS DDK 1.1.0 (STR #2301) + - _cupsAdminSetServerSettings() did not support changing + of top-level directives as designed. + - The init script path check was broken. + - CUPS incorrectly used the attribute "notify-recipient" + instead of "notify-recicpient-uri" in several places + (STR #2297) + - Fixed a configure script bug on MirBSD (STR #2294) + - The pdftops filter did not limit the amount of recursion + of page sets (STR #2293) + - Custom page sizes with fractional point sizes did not + work (STR #2296) + - The lpoptions command would crash when adding or removing + options on a system with no printers (STR #2295) + + +CHANGES IN CUPS V1.2.9 + + - The scheduler did not use the default job-sheets + (banners) for implicit classes (STR #2284) + - The scheduler could crash when listing complete jobs + that had been unloaded from memory (STR #2288) + - The French localization was doubled up (STR #2287) + - Build system fixes for several platforms (STR #2260, + STR #2275) + - The scheduler's openssl certificate generation code was + broken on some platforms (STR #2282) + - The scheduler's log rotation check for devices was + broken (STR #2278) + - The LPD mini-daemon did not handle the document-format + option correctly (STR #2266) + - The pdftops filter ignored the "match" size option in the + pdftops.conf file (STR #2285) + - cupstestppd now validates UTF-8 text strings in + globalized PPD files (STR #2283) + - The outputorder=reverse option did not work with all + printers (STR #2279) + - Classes containing other classes did not always work + (STR #2255) + - Printer location and description information was lost + if the corresponding string contained the "#" character + (STR #2254) + - cupsRemoveOption() did not work properly (STR #2264) + - The USB backend did not work with some USB to parallel + cables on Mac OS X. + - The test page did not print the rulers properly on + large media sizes (STR #2252) + - The text filter could crash when pretty printing certain + types of files (STR #2158) + + +CHANGES IN CUPS V1.2.8 + + - Documentation fixes (STR #2141, STR #2157) + - The HTTP upgrade redirection used by the scheduler did + not work with Internet Explorer (STR #2235) + - Members of a class with Unicode names did not appear + correctly in the web interface (STR #2154) + - Changing the "Save debugging information" setting in + the web interface no longer affects the other server + settings (STR #1993) + - The scheduler did not choose SSL certificates correctly + on Mac OS X (STR #2225) + - The scheduler could get in an infinite loop when + printing to a remote class (STR #2228) + - The jobs web page did not have separating space after + the number of pages column (STR #2230) + - Added French localization (STR #2221) + - Updated Spanish localization (STR #2223) + - Updated Japanese localization (STR #2216) + - cupsBorderlessScalingFacter was limited to a range of + 0.9 to 1.1, but some printers need larger values (STR + #2222) + - Landscape printing of PDF files did not always work + (STR #2149) + - Fixed slow USB printing on Minolta printers (STR #2104, + STR #2219) + - The ZPL label printer driver could produce stretched + output (PR #6448) + - The IPP backend now clears the printer-state-message + when there are no outstanding errors or warnings (STR + #2126) + - The CUPS Java scripting support did not work with + recent versions of Java due to the use of Sun's private + Base64 class (STR #2152) + - The scheduler did not pass HTTP GET form variables to + custom CGI programs (STR #2173) + - The lpoptions command now displays the reason why a PPD + file cannot be found (STR #2184) + - The scheduler did not accept "none" as a browse + protocol name (STR #2200) + - The scheduler still loaded the remote printer cache, + even when browsing was disabled (STR #2198) + - The SNMP backend now shows OfficeJet printers with the + "HP" manufacturer prefix (STR #2151) + - Web interface HTML cleanup (STR #2153) + - The parallel backend consumed 100% CPU on FreeBSD due + to an apparently common parallel port driver bug (STR + #2161) + - ippReadIO() incorrectly returned IPP_IDLE when the + initial IPP message header could not be read (STR + #2179) + - cupsRasterInterpretPPD() did not support custom options + (STR #1960) + - Collated output produced by the PostScript filter could + lose some options (STR #2137) + - job-hold-until with time values for the next day would + be held for 60 days (STR #2144) + - Some types of Sun raster files did not print correctly + (STR #2107) + - Raw PBM files did not print correctly (STR #2106) + - The SNMP backend no longer uses IPP with HP printers, + as some recent firmware versions appear to not work + (STR #2055) + - cupsMarkOptions() did not handle the + multiple-document-handling option (STR #2135) + - lpstat did not show the local job ID of active printers + (STR #2125) + - The backends incorrectly used STATUS: + media-tray-empty-error messages for out-of-paper + conditions (STR #2123, STR #2124) + - cupsGetPPD2() returned the wrong error when the PPD + file did not exist (STR #2122) + - cupsDoAuthentication() did not translate the password + prompt (STR #2121) + - httpGetLength2() did not handle error messages without + content correctly (STR #2133) + - Added support for 32/64-bit libraries on HP-UX Itanium + systems (STR #2115) + - Fixed a configure script problem with the 32/64-bit + library support (STR #2114) + - The PostScript filter did not properly output document + setup commands for reversed output (STR #2111) + - The scheduler did not parse IPv6 netmasks properly (STR + #2117) + + +CHANGES IN CUPS V1.2.7 + + - Documentation updates (STR #2089) + - Added an Italian translation (STR #2105) + - The PostScript filter now rotates the bounding box + values as needed (STR #2079) + - The scheduler no longer loads the remote printer cache + when browsing is disabled (STR #2084) + - The scheduler no longer writes a new launchd + configuration file if it doesn't have to (STR #2083) + - Updated the USB and PAP backends for Mac OS X (STR + #2086) + - The scheduler now picks up on changes to IPv6 and DNS + configuration on Mac OS X (STR #2085) + - The lpstat program could still hang (STR #2098) + - Fixed an inefficiency in the SNMP IPP detection code + (STR #2100) + - The SSL negotiation code did not implement short + timeouts (STR #2091) + + +CHANGES IN CUPS V1.2.6 + + - The web interface was not localized on Mac OS X (STR + #2075) + - "lpc status" did not show the number of queued jobs for + disabled queues (STR #2069) + - The lpstat program could hang (STR #2073) + - The serial backend did not support the new USB serial + filenames on Linux (STR #2061) + - The parallel backend did not support bidirectional I/O + properly (STR #2056) + - The network backends now log the numeric address that + is being used (STR #2046) + - Fixed a compile error when using libpaper. + - Fixed a compile error when compiling on Solaris with + threading enabled (STR #2049, STR #2050) + - Missing printer-state-changed event for + printer-state-message updates (STR #2047) + + +CHANGES IN CUPS V1.2.5 + + - Documentation updates (STR #2038) + - The SNMP backend no longer uses IPP for Epson printers + (STR #2028) + - Updated the configure script for Tru64 UNIX 5.1 (STR + #2033) + - Tru64 5.1B's getaddrinfo() and getnameinfo() functions + leak file descriptors (STR #2034) + - cupsAddDest() didn't add the parent destination's + options and attributes. + - ppdConflicts() did not handle custom option + constraints. + - Raw printing of gzip'd files did not work (STR #2009) + - The scheduler no longer preserves default option + choices when the new PPD no longer provides the old + default choice (STR #1929) + - The Linux SCSI backend is now only built if the SCSI + development headers are installed. + - USB printing to Minolta printers did not work (STR + #2019) + - Windows clients could not monitor the queue status (STR + #2006) + - The scheduler didn't log the operation name in the + access_log file for Create-Job and Print-Job requests. + - The PostScript filter now separates collated copies + with any required JCL commands so that JCL-based + finishing options act on the individual copies and not + all of the copies as a single document. + - The PostScript filter now disables duplex printing when + printing a 1-page document. + - cups-lpd didn't pass the correct + job-originating-host-name value (STR #2023) + - Fixed some speling errors in the German message catalog + (STR #2012) + - cupstestppd did not catch PPD files with bad + UIConstraints values (STR #2016) + - The USB backend did not work with the current udev- + created printers if the first printer was disconnected + (STR #2017) + - Mirrored and rotated printing did not work with some + documents (STR #2004) + - 2-sided printing with banners did not work properly on + some printers (STR #2018) + - Updated the raw type rule to handle PJL within the + first 4k of a print job (STR #1969) + - Added an Estonian translation (STR #1957) + - Clarified the documentation for the cupsd.conf @LOCAL + and @IF(name) allow/deny functionality (STR #1992) + - The PostScript filters did not escape the Title and For + comments in the print job header (STR #1988) + - The scheduler would use 100% CPU if browsing was + disabled and the cupsd.conf file contained BrowsePoll + lines (STR #1994) + - The cupsDirRead() function did not work properly on + non-POSIX-compliant systems (STR #2001) + - The cupsFile functions didn't handle read/write errors + properly (STR #1996) + - The DBUS support now works with older versions of the + DBUS library. + + +CHANGES IN CUPS V1.2.4 + + - The --with-printcap configure option did not work (STR + #1984) + - The character set reported by cupsLangGet() did not + always reflect the default character set of a given + locale (STR #1983) + - Older Lexmark and Tektronix printers did not work with + IPP (STR #1980) + - Failsafe printing did not work (PR #6328) + - Some web interface redirects did not work (STR #1978) + - The web interface change settings button could + introduce a "Port 0" line in cupsd.conf if there was no + loopback connection available (STR #1979) + - The web interface change settings and edit + configuration file buttons would truncate the + cupsd.conf file (STR #1976) + - The German web interface used the wrong printer icon + images (STR #1973) + - The "All Documents" link in the on-line help was + missing a trailing slash (STR #1971) + - The Polish web interface translation used the wrong + URLs for the job history (STR #1963) + - The "reprint job" button did not work (STR #1956) + - The scheduler did not always report printer or job + events properly (STR #1955) + - The scheduler always stopped the queue on error, + regardless of the exit code, if the error policy was + set to "stop-printer" (STR #1959) + - ppdEmitJCL() included UTF-8 characters in the JCL job + name, which caused problems on some printers (STR + #1959) + - Fixed a buffering problem that cause high CPU usage + (STR #1968) + - The command-line applications did not convert + command-line strings to UTF-8 as needed (STR #1958) + - cupsDirRead() incorrectly aborted when reading a + symbolic link that pointed to a file/directory that did + not exist (STR #1953) + - The cupsInterpretRasterPPD() function did not handle + custom page sizes properly. + + +CHANGES IN CUPS V1.2.3 + + - The scheduler did not send job-state or + job-config-changed events when a job was held, + released, or changed (STR #1947) + - The scheduler now aborts if the configuration file and + directory checks fail (STR #1941) + - Fixed a problem with ippPort() not using the port + number that was set via the client.conf file or + CUPS_SERVER environment variable (STR #1945) + - HTTP headers were not buffered (STR #1899) + - Some IPP printers (HP) did not like UTF-8 job names + (STR #1837) + - The CUPS desktop icon is now localized for Polish (STR + #1920) + - Printer options were not always honored when printing + from Windows clients (STR #1839) + - The openssl command would lock up the scheduler when + generating an encryption certificate on some platforms + due to a lack of entropy for the random number + generator (STR #1876) + - The web admin page did not recognize that "Listen 631" + enabled remote access (STR #1908) + - The web admin page did not check whether changes were + made to the Basic Server Settings check boxes (STR + #1908) + - The IPP backend could generate N*N copies in certain + edge cases. + - The scheduler did not restore remote printers properly + when BrowseShortNames was enabled (STR #1893) + - Polling did not handle changes to the network + environment on Mac OS X (STR #1896) + - The "make test" subscription tests used invalid + notify-recipient-uri values (STR #1910) + - Printers could be left in an undefined state on system + sleep (STR #1905) + - The Berkeley and System V commands did not always use + the expected character set (STR #1915) + - Remote printing fixes (STR #1881) + - The cupstestppd utility did not validate translation + strings for custom options properly. + - Multi-language PPD files were not properly localized in + the web interface (STR #1913) + - The admin page's simple settings options did not check + for local domain socket or IPv6 addresses and did not + use "localhost" as the listen address. + - An empty BrowseProtocols, BrowseLocalProtocols, or + BrowseRemoteProtocols line would crash the scheduler + instead of disabling the corresponding browsing options. + - The scheduler now logs IPP operation status as debug + messages instead of info or error. + - cupsFileRewind() didn't clear the end-of-file state. + - cupstestppd didn't report the actual misspelling of the + 1284DeviceID attribute (STR #1849) + - BrowseRelay didn't work on Debian (STR #1887) + - configure --without-languages didn't work (STR #1879) + - Manually added remote printers did not work (STR #1881) + - The header was not installed. + - Updated the build files for Autoconf 2.60 (STR #1853) + - The scheduler incorrectly terminated the polling + processes after receiving a partial log line. + - The cups-lpd mini-daemon reported "No printer-state + attribute found" errors when reporting the queue status + (PR #6250, STR #1821) + - SNMP backend improvements (STR #1737, STR #1742, STR + #1790, STR #1835, STR #1880) + - The scheduler erroneously reported an error with the + CGI pipe (STR #1860) + - Fixed HP-UX compile problems (STR #1858, STR #1859) + - cupstestppd crashed with some PPD files (STR #1864) + - The and header files did not + work with C++. + + +CHANGES IN CUPS V1.2.2 + + - Documentation updates (STR #1765, STR #1780) + - CUPS didn't know about alternate character set names + for Asian text (STR #1819) + - The lpoptions -o and -r options did not work unless you + specified a printer. + - The lpoptions command incorrectly allowed users to set + printer attributes like printer-type (STR #1791) + - httpWait() did not flush the write buffer, causing "bad + request" errors when communicating with CUPS 1.1.x + servers (STR #1717) + - Polling did not sanitize the printer description, + location, or make and model strings like broadcasts + did. + - Polled printers did not show the server's default + job-sheets option value. + - The Samba password prompt was not properly localized + (STR #1814) + - Added a German translation (STR #1842) + - The scheduler now creates self-signed SSL certficates + automatically when using OpenSSL and CDSA for + encryption, just as for GNU TLS. + - The SNMP backend sporatically reported some printers as + "unknown" (STR #1774) + - The scheduler now forces BrowseTimeout to be at least + twice the BrowseInterval value and non-zero to avoid + common configuration errors. + - The scheduler incorrectly returned printer URIs of the + form "ipp://server/printers/classname" for classes (STR + #1813) + - Updated Japanese localization (STR #1805) + - The scheduler's SSL certificate/key directory was not + created on installation (STR #1788) + - Added a mailto.conf man page and help page (STR #1754) + - The parallel and USB backends no longer wait for the + printer to go on-line - this caused problems with + certain printers that don't follow with the IEEE-1284 + standard (STR #1738) + - The scheduler could crash on a reload when implicit + classes were present (STR #1828) + - The IPP backend incorrectly used the CUPS_ENCRYPTION + environment variable to determine the default + encryption mode when printing (STR #1820) + - USB printing did not work on Solaris (STR #1756) + - The scheduler sorted job priorities in the wrong order + (STR #1811) + - The scheduler did not automatically restart notifiers + that exited or crashed (STR #1793) + - IPv6 support did not work on NetBSD (STR #1834) + - The EPM packaging file did not work (STR #1804) + - The scheduler used up the CPU if BrowseRemoteProtocols + was empty (STR #1792) + - Custom page sizes did not work (STR #1787) + - The SNMP backend could crash on some systems when SNMP + logging was enabled (STR #1789) + - Browsing could produce some funny printer names when + ServerName was set to an IP address (STR #1799) + - Fixed the log message for BrowseRelay (STR #1798) + - Fixes to allow CUPS to compile on MirBSD (STR #1796) + - The scheduler incorrectly set the FINAL_CONTENT_TYPE + environment variable (STR #1795) + - The pdftops filter incorrectly embedded a "produced by" + comment, causing PDF printing not to work on some + operating systems (STR #1801) + - Sending raw jobs from a client system could cause the + client's scheduler to eventually crash (STR #1786) + - The scheduler now checks that the notifier exists prior + to accepting a new subscription request. + - The scheduler now reports the supported + notify-recipient schemes based on the contents of the + ServerBin/notifier directory. + - Event notifications did not include the + notify-sequence-number or other required attributes + (STR #1747) + - Allow/Deny addresses of the form "11.22.33.*" did not + work on Linux (STR #1769) + - cupsGetPPD() did not work if the scheduler was only + listening on a domain socket (STR #1766) + - The scheduler could crash advertising a class (STR + #1768) + - The scheduler could crash if the default printer was + deleted (STR #1776) + - Added a new default CUPS raster format (v3) which does + not compress the raster stream in order to provide the + same cupsRasterReadPixels() and cupsRasterWritePixels() + performance as CUPS 1.1.x. + - The cupsaddsmb man page listed the wrong files for the + CUPS driver. + - Some configure --with options did not work (STR #1746) + - "Allow @IF(name)" didn't work if "name" wasn't the + first network interface (STR #1758) + - The lpstat command did not use the correct character + set when reporting the date and time (STR #1751) + - The cupsaddsmb command and web interface did not update + the Windows PPD files properly, resulting in corrupt + PPD files for the Windows client to use (STR #1750) + - The cupsd.conf man page didn't describe the Listen + domain socket syntax (STR #1753) + - The scheduler no longer tries to support more than + FD_SETSIZE file descriptors. + - CDSA (encryption) support fixes for MacOS X. + - The lppasswd program needs to be setuid to root to + create and update the /etc/cups/passwd.md5 file (STR + #1735) + - 32/64-bit library installation was broken (STR #1741) + - The USB backend now reports a "no such device" error + when using the old filename-based USB URIs instead of + the "success" error. + - Increased the HTTP and IPP read timeouts to 10 seconds, + as 1 second was too short on congested networks (STR + #1719) + - The SNMP backend now uses the device description over + the printer-make-and-model attribute when the attribute + contains a generic name (STR #1728) + - Fixed another file descriptor leak when printing raw + files (STR #1736) + - Raw queues were not shared via LDAP (STR #1739) + - The pstops filter didn't always embed PageSetup + commands from the PPD file (STR #1740) + - "make install" didn't work if you disabled all of the + localizations. + - The scheduler didn't always choose the least costly + filter. + - Fixed parsing of IPv6 addresses in Allow, Deny, + BrowseAllow, BrowseDeny, and BrowseRelay directives + (STR #1713) + - Printers that were shared via LDAP did not get added to + the LDAP server properly (STR #1733) + - LDAP browsing would crash the scheduler if a required + value was missing (STR #1731) + - Special cases for the "localhost" hostname did not + work, causing printing to not work when the /etc/hosts + file did not contain a localhost entry (STR #1723) + - Updated the Spanish translation (STR #1720, STR #1770) + - Reverse-order page output was broken when N-up or + landscape orientations were used (STR #1725) + - The parallel, serial, socket, and USB backends needed + print data before they would report back-channel data, + causing problems with several new drivers (STR #1724) + + +CHANGES IN CUPS V1.2.1 + + - "lprm -h hostname" did not work (STR #1800) + - The web interface did not handle reloads properly for + MSIE (STR #1716) + - The configure script no longer adds linker rpath + options when they are unnecessary. + - The scheduler could crash printing a debug message on + Solaris (STR #1714) + - The --enable-32bit and --enable-64bit configure options + did not always work. + - The password prompt showed the domain socket address + instead of "localhost" for local authentication (STR + #1706) + - The web interface filtered the list of printers even if + the user wasn't logged in (STR #1700) + - The IPP backend did not work reliably with some Xerox + printers (STR #1704) + - Trailing banners were not added when printing a single + file (STR #1698) + - The web interface support programs crashed on Solaris + (STR #1699) + - cupstestppd incorrectly reported problems with + *1284DeviceID attributes (STR #1710) + - Browsing could get disabled after a restart (STR #1670) + - Custom page sizes were not parsed properly (STR #1709) + - The -U option wasn't supported by lpadmin (STR #1702) + - The -u option didn't work with lpadmin (STR #1703) + - The scheduler did not create non-blocking back-channel + pipes, which caused problems when the printer driver + did not read the back-channel data (STR #1705) + - The scheduler no longer uses chunking in responses to + clients - this caused problems with older versions of + CUPS like 1.1.17 (PR #6143) + - Automatic raw printing was broken (STR #1667) + - 6-up printing was broken (STR #1697) + - The pstops filter did not disable CTRL-D processing on + the printer/RIP. + - ppdOpen*() did not load custom options properly (STR + #1680) + - "Set Printer Options" in the web interface did not + update the DefaultImageableArea or + DefaultPaperDimension attributes in the PPD file (STR + #1689) + - Fixed compile errors (STR #1682, STR #1684, STR #1685, + STR #1690) + - The lpstat command displayed the wrong error message + for a missing destination (STR #1683) + - Revised and completed the Polish translation (STR + #1669) + - Stopped jobs did not show up in the list of active jobs + (STR #1676) + - The configure script did not use the GNU TLS + "libgnutls-config" script to find the proper compiler + and linker options. + - The imagetoraster filter did not correctly generate + several 1, 2, and 4-bit color modes. + - cupsRasterWritePixels() could lose track of the current + output row. + - cupsRasterReadPixels() did not automatically swap + 12/16-bit chunked pixel data. + - Moved the private _cups_raster_s structure out of the + public header. + - Updated the CUPS raster format specification to include + encoding rules and colorspace definitions. + - The Zebra PPD files had the wrong PostScript code for + the "default" option choices. + - The imagetoraster filter did not generate correct CIE + XYZ or Lab color data. + - The cups-config script did not work when invoked from a + source directory (STR #1673) + - The SNMP backend did not compile on systems that used + the getifaddrs emulation functions (STR #1668) + + +CHANGES IN CUPS V1.2.0 + + - Documentation updates (STR #1618, STR #1620, STR #1622, + STR #1637) + - Static file copy buffers reduced from 64k to 32k to + work around bogus MallocDebug library assumptions (STR + #1660) + - The scheduler did not decode the backend exit code + properly (STR #1648) + - The MacOS X USB backend did not report the 1284 device ID, + nor did it fix device IDs returned by HP printers. + - The scheduler started more slowly than 1.1.x with large + numbers of printers (STR #1653) + - cupsRasterInterpretPPD() didn't support the + cupsPreferredBitsPerColor attribute, and imagetoraster + didn't use the new API. + - The "make test" script did not create all of the necessary + subdirectories for testing (STR #1638) + - The scheduler did not prevent rotation of logs + redirected to /dev/null (STR #1651) + - "make test" did not include the SNMP backend in the + test environment (STR #1625) + - The EPM packaging files did not work (STR #1621) + - "Use Default Configuration" inserted a broken + configuration file (STR #1624) + - Redirects in the web interface did not always preserve + the encrypted status of a connection (STR #1603) + - Added the Apple "pap" backend. + - Added CUPS library to CUPS Image shared library + linkage to support Linux --as-needed linker option + (STR #1606) + - Fixed support for --enable-pie (STR #1609) + - The pdftops filter did not validate the length of the + encryption key (STR #1608) + - Updated the Polish localization. + - "Encryption Required" in the cupsd.conf file now only + requires encryption when the connection is not over the + loopback interface or domain socket. + - Printer names containing "+" were not quoted properly in + the web interface (STR #1600) + - The SNMP backend now reports the make and model in the + information string so that the auto-generated printer + name is more useful than just an IP address. + + +CHANGES IN CUPS V1.2rc3 + + - The cups-lpd program always did reverse lookups on the + client address, which could be a performance problem. + Added a "-n" option to disable lookups. + - When configured with SSL support, require encryption by + default when displaying the /admin location (STR #1592) + - The next job ID was not computed correctly if the job + cache file got out of sync with the spool directory + (STR #1582) + - The PNG image handling code used deprecated functions + from libpng (STR #1587) + - Added a Polish translation (STR #1584, STR #1586) + - More changes to the scheduler to improve battery life + on portable devices (STR #1583) + - Changed the default log level for status messages back + to "DEBUG" to be consistent with CUPS 1.1.x (STR #1579) + - The error string was not set properly when + cupsDoFileRequest() was given the name of a directory + (STR #1578) + - Fixed handling of job-hold-until (STR #1581) + - Added explicit notes to the cupsaddsmb man page + explaining that the driver filenames are case-sensitive + under UNIX and that they must be all lowercase (Windows + 2000) or all UPPERCASE (Windows 95/98/Me) to work (STR + #1568) + - The USB backend incorrectly split the manufacturer name + if it contained spaces (STR #1566) + - The scheduler would hang when listing PPD files for a + manufacturer whose name contained spaces (STR #1567) + - Added the SNMP backend for network printer discovery + (STR #1555) + - cupstestppd now fails PPD files with 1284DeviceId + instead of 1284DeviceID, and cups-driverd uses a + case-insensitive comparison when looking for it (STR + #1573) + - cupsDoFileRequest() and cupsDoRequest() now work + properly with non-blocking HTTP connections. + - Added Swedish translation (STR #1569) + - "make install" now installs the MIME files with world + read permissions (STR #1565) + - More CDSA encryption support fixes (STR #1563) + - Updated the default mime.types file to support printing + of files that do not have a locally-recognized MIME + media type to raw or System V queues. + - Updated the serial port detection code on Linux (STR + #1562) + - Added some more error checking to httpGetHostname() + (STR #1561) + - The title of some administration pages was not + localized (STR #1548) + - The edit-config.tmpl file was not generated or + installed for the Spanish or Japanese localizations + (STR #1547) + - The mimeDelete() function freed the types before the + filters, but the filters needed the type data (STR #1558) + - The scheduler didn't keep track of the status pipes + properly, leading to a bad select() for multi-file jobs + (STR #1559) + - The cupstestdsc program didn't validate the ordinal + page number value for %%Page: comments. + + +CHANGES IN CUPS V1.2rc2 + + - The scheduler was not always using the string pool, + causing random crashes. + - The lpmove and the web interface's Move Job button did + not work with stopped jobs (STR #1534) + - The PostScript filter did not handle the page-set + option properly with number-up printing (STR #1543) + - The scheduler now only warns about unsupported ACLs + once (STR #1532) + - The "fitplot" option did not work with output from + Mozilla (STR #1542) + - The imagetops filter did not work with Level 2 or 3 + printers (STR #1533) + - The scheduler now recognizes PostScript files with PJL + commands that do not include an ENTER LANGUAGE command. + - Added --with-printcap configure option. + - 64-bit SSL fixes for MacOS X. + - The scheduler didn't send some printer state change + events. + - The scheduler didn't send jobs to busy remote printers. + - Fixed some problems with the launchd support. + - Added new USB printer backend for MacOS X. + - The PostScript filter now handles files that start with + an incomplete PJL header (PR #6076) + - The web interface language selection code did not try + the generic language localization (STR #1531) + - The language cache, string pool, and transcoding caches + are now process global instead of per-thread to avoid + problems with GNOME and to allow for data sharing + between threads (STR #1530) + - Fixed a CUPS 1.1.x compatibility bug (STR #1528) + - The web interface redirection after certain printer + administration tasks was broken (STR #1516) + - Web interface authorization could get stuck (STR #1512) + - Localization updates (STR #1513, STR #1518, STR #1520) + - The pstops filter didn't work with some files (STR + #1523) + - "./configure --enable-static" didn't work (STR #1522) + - The scheduler was not using the configured default + Group (STR #1521) + - The web interface still did not show the localized time + and date for some locales and systems (STR #1509) + - httpAddrGetList() would crash on systems without + getaddrinfo(). + - Socket URIs without a trailing slash would cause the + port number to not be accepted (STR #1519) + - Local raw and System V printers were not advertised as + such for printer browsing (STR #1502) + - The RPM spec file incorrectly put duplicate copies of + the Japanese and Spanish web interface templates in the + main cups package (STR #1517) + - cupsSetDests() did not explicitly set the permissions + of the /etc/cups/lpoptions file (STR #1508) + - The lpq command crashed with the -h option (STR #1515) + + +CHANGES IN CUPS V1.2rc1 + + - Documentation updates (STR #1497, STR #1498) + - The scheduler now redirects browsers to https: URLs + when encryption is required. + - The scheduler would crash when printing with a banner + (STR #1500) + - cups-driverd did not use the LanguageEncoding attribute + in PPD files to convert the NickName to UTF-8 (STR + #1503) + - The lpadmin command could not set the + printer-error-policy attribute (STR #1504) + - The web interface did not show the time and date in the + correct format for the locale (STR #1505) + - CUPS no longer accepts print jobs if a printer does not + support the file format (STR #1501) + - Cleaned up the PostScript filter (pstops) so that it + properly supports %%IncludeFeature and page scaling + (STR #1453) + - Fixed the cupsFileRewind() and cupsFileSeek() functions + to work properly with uncompressed files. + - Added cupsFileGetLine(), cupsFileStderr(), + cupsFileStdin(), and cupsFileStdout() functions to the + CUPS library. + - Added a new cupstestdsc program to test the DSC + conformance of PostScript files. + - Added KDE/GNOME icons and a Manage Printers menu item. + - Added --enable-image and --enable-pdftops configure + options to control whether the image and PDF filters + are built and installed (default = yes for all + platforms but MacOS X) + - Fixed a minor memory leak in the PPD API. + - Fixed transcoding issues (STR #1493) + - The scheduler now enforces a minimum job cost of 100 + when doing FilterLimit checks. + - The scheduler would leak file descriptors when printing + to raw queues (STR #1491) + - The IPv6 support did not compile on Tru64 UNIX (STR + #1488) + - ppdOpen2() now converts the NickName and all UI text to + UTF-8 (STR #1475) + - The Set Allowed Users web page did not work (STR #1486) + - When the default policy was not set or set to a non- + existing policy, the scheduler did not set the default + policy name to "default" (STR #1484) + - The Zebra CPCL driver did not use the correct righthand + margin for the 4" wide label sizes. + - Fixed a problem with the parsing of fractional real + numbers in PPD files. + - Added Spanish localization files (STR #1480) + - Fixed localization of a few scheduler messages (STR + #1478) + - Fixed support for HEAD requests in the scheduler (STR + #1481) + + +CHANGES IN CUPS V1.2b2 + + - Updated the CUPS design description. + - Added --enable-32bit and --enable-64bit configure + options to allow building of separate 32/64-bit + libraries on systems that support both environments + (STR #1472) + - Various compiler warning fixes. + - Fixes for Solaris 10 builds against old GNU TLS and + LDAP libraries. + - Added a cupsArrayUserData() function to retrieve the + user data pointer for an array (useful for typing + arrays) + - The ppdEmitString() function did not compute the + required buffer size properly, leading to dropped + characters on the end of the printer commands in pstops + and imagetops (STR #1470) + + +CHANGES IN CUPS V1.2b1 + + - The serial backend now supports Equinox 8-port serial + hubs (STR #526) + - The IPP backend now supports a compression option to + compress print files as they are sent to the remote + server (STR #956) + - The CUPS browse protocol now supports passing of + default options and browse timeout values from the + server to the clients (STR #800) + - Implicit classes that timed out could cause the + scheduler to crash (STR #1439) + - Added DragonFly support in local device backends (STR + #1362) + - Added LDAP printer browsing support (STR #338) + - Added official support for printer maintenance commands + via the CUPS Command file format and hooks in the + printer-type and web interfaces (STR #932) + - The HP-GL/2 filter could get in an infinite loop trying + to convert HP-PCL files (STR #1415) + - CUPS now implements the HTTP/1.1 Expect header (STR + #1407) + - Options in PPD files are no longer automatically put in + an "Extra" group; rather, all options that are not + inside an Open/CloseGroup will be placed in the + "General" group (STR #1385) + - The scheduler now creates a job-uuid attribute that + uniquely identifies a job on a network (STR #1410) + - The init script now unsets the TMPDIR environment + variable to prevent user temporary directories from + being used by cupsd accidentally (STR #1424) + - Added support for launchd on MacOS X. + - Added support for notify_post on MacOS X. + - Added support for DBUS on Linux. + - All of the Berkeley (except for lpc) and System V + commands now support specification of user, host, and + port (STR #1028, STR #1029, STR #1087) + - The lpmove command now allows you to move all jobs for + a given queue (STR #56) + - The web interface now supports moving of a job or jobs + to another queue (STR #56) + - The web interface now provides searching, paging, and + changing of the sort/display order of classes, jobs, + and printers. + - cupsaddsmb now accepts a password on the command-line + and supports passwords with special characters (STR + #822, STR #1236) + - ppdLoad*() no longer tries to "fix" bad characters in + UI text (STR #1101) + - Printer names can now (reliably) contain Unicode + characters (STR #896) + - The lpstat command now shows the time and date of the + last printer state change instead of the hardcoded "Jan + 01 00:00" (STR #659) + - The scheduler now adds a job-actual-printer-uri + attribute to job objects when printing to a class (STR + #116) + - The scheduler now logs log file open errors to the + system log (STR #1289) + - The scheduler now sets the job-originating-user-name to + the authenticated username, if available (STR #1318) + - The scheduler now only updates the permissions of SSL + keys and certificates when they are under the + ServerRoot directory (STR #1324) + - The rastertodymo driver has been renamed to + rastertolabel (a symlink is installed so that existing + queues continue to work) and now also supports Zebra's + CPCL language. + - The lpstat command could show the wrong active job for + a printer (STR #1301) + - Fixed a potential crash problem in the scheduler when + aborting a CGI program (STR #1290) + - Added a "cancel all jobs" button to the class and + printer web interfaces (STR #1140) + - The add-printer web page now shows the + set-printer-options page after the printer has been + added (STR #690) + - The classes web page now provides links to each of the + member printers (STR #307) + - CUPS now handles HTTP request/response lines up to 32k + in length; this is mainly for better cookie support + (STR #1274) + - Added support for the Apache PassEnv and SetEnv + directives to cupsd.conf (STR #853) + - Added large file (64-bit) support (STR #541) + - Fixed a performance issue with the ippReadIO() + implementation (STR #1284) + - Fixed a performance issue with the scheduler's implicit + class implementation (STR #1283) + - The pdftops filter now adds the Title and Creator + fields from the PDF file to the PostScript document + comments section (STR #539, STR #830) + - Added a new cups_array_t and cupsArray*() functions to + the CUPS API to support sorted lists of data. + - Made the CUPS API library thread-safe (STR #1276) + - Added "media" option support for EFI EFMediaType option + (STR #902) + - Added write buffering to the HTTP code to improve + performance (STR #547) + - The scheduler now uses the attributes-natural-language + attribute to localize banner pages (STR #386) + - The scheduler now returns the address that was used to + connect to it (STR #1076) + - Fixed a problem with N-up printing and OpenOffice (STR + #576) + - Added support for the GCC position independent + executable options (STR #1209) + - Added new BrowseLocalProtocols and + BrowseRemoteProtocols directives to cupsd.conf, + allowing for different browse protocols for local and + remote printers (STR #877) + - PPD files can now contain strings up to 256k in length + (STR #1215) + - The pstops filter now supports the IncludeFeature DSC + comment (STR #1212) + - The pstops filter now disables the setpagedevice + procedure when doing N-up printing (STR #1161) + - The serial backend now supports "stop=1", "stop=2", + "parity=space", and "parity=mark" options (STR #1155) + - "make install" no longer overwrites an existing PAM + configuration file (STR #1064) + - The scheduler now closes all files on startup when run + in daemon mode (STR #1009) + - Added a new RGBW colorspace to the CUPS raster format + (STR #1071) + - The pdftops filter now sets the page size based on the + media box when not scaling the output (STR #912) + - The pdftops filter now supports masked images (STR + #281) + - The pdftops filter produced large output when rendering + PDF files containing lot of repeated images (STR #327) + - The pdftops filter now minimizes print processing of + PDF files when using the page-ranges option (STR #273) + - Updated pdftops filter to Xpdf 3.01. + - Added new cupsBackchannelRead() and + cupsBackchannelWrite() functions, as well as + backchannel support to the parallel, serial, socket, + and USB backends (STR #1252) + - The parallel and USB backends now treat a "no space + available" error as an out-of-paper condition (STR + #1225) + - The "lpc" command now supports the "status all" command + (STR #1004) + - ippReadIO() did not read collections properly (STR + #1249) + - The "make test" script now creates the test files in + "/tmp/cups-$USER" instead of "/tmp/$USER" (STR #981) + - All backends now abort on error when printing a job to + a class - this allows the next printer in the class to + print the job (STR #1084) + - The scheduler now verifies that a printer supports + Letter or A4 media sizes before setting them as the + initial default (STR #1250) + - The cupstestppd program now flags bad Resolution + options (STR #1269) + - The USB backend now retries printing when the printer + is disconnected or turned off (STR #1267) + - Added new httpGetHostname() function to CUPS API, and + use it instead of gethostname() so that the web + interface will work correctly on systems whose hostname + is not the FQDN (STR #1266) + - The scheduler now stops printers if the backend for the + queue is missing on startup (STR #1265) + - The configure script now supports "--disable-library" + to disable particular image file format support + libraries, even if they are available on the build + system (STR #1248) + - The IPP backend did not always report on the total + number of pages that were printed (STR #1251) + - The lpstat program could display garbage date and time + values for locales whose date format exceeded 31 + characters (STR #1263) + - The cupstestppd program would segfault when testing + certain broken PPD files (STR #1268) + - Dramatically reduced the overhead of implicit classes. + - Added new cupsDir*() functions to CUPS API. + - Printers can now be published individually for sharing. + - Fixed a bug in the scheduler's startup signalling code + which caused cupsd to send the SIGUSR1 signal to the + init process instead of the original parent process + (STR #1258) + - Added new on-line help CGI to web interface to provide + searchable help. + - Devices are now tracked dynamically, with each query + doing a new device scan. This eliminates a previous + startup delay caused by slow backends and allows new + printers to be seen without restarting the server, + however it limits the amount of device URI checking + that can be done (basically now the scheduler only + requires a URI with a method that is a listed backend) + - Added new printer auto-detection, server configuration, + and log file viewing to the administration web page. + - Added new "set allowed users" web interface to set the + list of allowed users for a printer or class. + - The scheduler, command-line, and web interfaces now + limit the list of printers and classes to those + accessible by a user. + - cupsMarkOptions() now handles more non-standard + duplexing options and choices (STR #915) + - cups-lpd now honors remote banner requests with the + "standard" banner whenever a printer does not have one + defined (STR #1220) + - The scheduler's denial-of-service checks did not work + properly with IPv6 addresses (STR #1134) + - The lp and lpr commands did not error out properly when + they were unable to write to a temporary file (STR + #1129) + - The pstops filter did not handle Adobe-specific + comments in Windows NT driver output (STR #1085) + - "lpstat -l -p" incorrectly reported the printer + interface (STR #936) + - The web interface now operates exclusively with the + UTF-8 encoding, and sends the appropriate character set + and header information to the web browser (STR #919, + STR #1007) + - Added a "set allowed users" interface to the web + interface so that you can set the list of allowed or + denied users/groups for a printer or class. + - Disallow the "#" character in printer names, since it + has special meaning in the shell, config files, and in + URIs (STR #917, STR #1202) + - Added a new application/x-csource MIME type, and + support for it to the texttops filter so that you can + pretty print plain text files without the C/C++ + keywords being highlighted. + - The pdftops filter did not compile with GCC 4.0 (STR + #1226) + - The texttops filter did not highlight preprocessor + directives followed by a tab properly. + - HP PJL output now uses both JOB DISPLAY and RDYMSG + commands to show the current job on the printer's + display (STR #1218) + - Local authentication certificates are now stored in + /var/run/cups/certs by default instead of + /etc/cups/certs (STR #1211) + - Backends now use "&" to separate options in device + URIs; "+" is still recognized but is deprecated (STR + #842) + - The USB backend no longer supports the usb:/dev/foo + format on systems that support device ID queries. + - Forced classification markings did not work when the + job-sheets parameters were "none,none". + - "lpstat -l -p" incorrectly showed all users as allowed, + even if the queue was restricted to certain users (STR + #801) + - The scheduler now automatically detects SSL/TLS clients + without using the SSLPort/SSLListen directives. + - The CUPS API and scheduler no longer support SSLv2- + encrypted connections. + - Updated the cupsaddsmb utility to correctly export the + CUPS driver for Windows. + - Fixed a signal-handling bug in httpRead() which + ultimately caused the server to print multiple copies + when it was busy (STR #1184) + - The cupsFile API now uses the O_APPEND option when + opening files in append mode (STR #990) + - The md5.h header and md5_* functions are now officially + private and have been renamed to avoid conflicts with + other implementations with the same name. + - The pdftops filter incorrectly embedded some Type1 + fonts (STR #1093) + - The scheduler didn't detect a closed connection in the + middle of an IPP request (STR #1153) + - The scheduler could block trying to read the job status + if there was input pending and the job was cancelled in + the same input cycle (STR #1157) + - The scheduler could crash when deleting a class due to + infinite recursion. + - Updated the Zebra ZPL label printer driver to use the + run-length encoding and support more options. + - Updated serial backend to scan for /dev/ttyC* as well + as /dev/ttyc* for Cyclades serial ports (STR #1049) + - The scheduler could hang reading the job status under + certain circumstances (STR #1068) + - The USB backend termination signal code was inverted + (STR #1046) + - Moved enable and disable commands to sbindir to be + consistent. + - Added new cupsRasterInterpretPPD() function for RIP + filters to setup the raster page header from + PostScript commands in a PPD file. + - The CUPS browsing protocol now offers a "delete" bit + to remove printers as soon as they are deleted on the + server or as soon as the server shuts down gracefully + (STR #793) + - The CUPS_SERVER and ServerName directives (client.conf + and ~/.cupsrc) may now contain names of the form + "server:port" and "/path/to/domain/socket". + - The "cancel -u user" command now works for ordinary + users (STR #751) + - Added test run support to "make test" target (STR #64) + - Added domain socket support (STR #656) + - Added BrowseLocalOptions directive to allow the + administrator to add printer URI options to the browse + URI, e.g. "encryption=required" (STR #732) + - Added BrowseRemoteOptions directive to allow the + administrator to add standard URI options to the + remote printer URI, e.g. "encryption=required" (STR + #732) + - Now put "-I.." compiler option in front of all others + to ensure that local CUPS headers are used before + installed headers (STR #437) + - New cupsLangPrintf() and cupsLangPuts() for localized + interfaces. + - Now support custom attributes and extended options in + PPD files. + - Now provide functions to save PPD files. + - New policy mechanism allows per-operation and + per-printer control over what users and groups are + allowed to do various IPP operations. + - New error policy mechanism to control how aborted + backend errors are handled by the scheduler + (abort-job, retry-job, requeue-job, stop-printer) + - Updated the printer test page with a better color + wheel and a separate grayscale ramp. + - A single backend process is now run to send all print + data for a job. + - Backends and filters can now send and receive + backchannel data over file descriptor 3. + - Updated the raster stream format to support more + user-defined attributes and to do compression of the + page data. diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt new file mode 100644 index 0000000000..9af534f9bf --- /dev/null +++ b/CHANGES-1.3.txt @@ -0,0 +1,856 @@ +CHANGES-1.3.txt +--------------- + +CHANGES IN CUPS V1.3.11 + + - The scheduler did not prevent nested classes (STR #3211) + - The scheduler did not reprint processing jobs that were moved to + another destination (STR #3222) + - The scheduler did not reset the current job file when stopping a + printer (STR #3226) + - The scheduler did not handle POSTs to custom CGIs properly (STR #3221) + - The pdftops filter did not print landscape PDF pages properly + (STR #2881) + - The scheduler did not handle partial header lines properly from CGI + programs (STR #3194) + - The web interface could hang on OpenBSD (STR #3176, STR #3196) + - The scheduler and cupsfilter utility did not handle rules starting + with a negation operator properly (STR #3160) + - The scheduler and cupsfilter utility would crash with certain MIME + .types rules (STR #3159) + - httpSetField wasn't bracketing IPv6 numeric addresses for the Host: + field (STR #3164) + - The ServerName, if specified, was not treated as a valid alias for the + local system (STR #3167) + - "make epm" did not work (STR #3166) + - "lpstat -h server" showed non-shared printers (STR #3147) + - "make check" did not work on Linux (STR #3161) + + +CHANGES IN CUPS V1.3.10 + + - Documentation fixes (STR #2994, STR #2995, STR #3008, STR #3056, + STR #3057) + - SECURITY: The scheduler now protects against DNS rebinding attacks + (STR #3118) + - SECURITY: Fixed TIFF integer overflow in image filters (STR #3031) + - The scheduler did not support the job-hold-until attribute with the + Restart-Job operation (STR #3130) + - SECURITY: The PNG image reading code did not validate the + image size properly, leading to a potential buffer overflow + (STR #2974) + - The rastertohp driver did not set the 1-sided printing mode when + needed (STR #3131) + - Now use a wrapper program instead of our fork of the Xpdf code to + support printing of PDF files. The new wrapper supports using Xpdf, + poppler, or Ghostscript to convert PDF files to PostScript (STR #3129) + - Long job names caused problems with some PJL printers (STR #3125) + - The lpq command did not work when showing all destinations (STR #3117) + - The scheduler used a codeset name of UTF8 which is not supported on + Solaris (STR #3113) + - cupsGetJobs() did not work with a NULL destination (STR #3107) + - Fixed a localization problem for option choices (incorrectly) named + "Custom" (STR #3106) + - The fallback OpenSSL random number seeding would not work (STR #3079) + - The scheduler might miss a child signal, causing high CPU usage. + - The scheduler did not enforce quotas after the job history was + unloaded (STR #3078) + - The job-k-limit, job-page-limit, and job-quota-period attributes + could not be set using the lpadmin command (STR #3077) + - httpSeparateURI() did not error out on URIs with a missing port + number after a colon. + - Fixed a Valgrind-detected initialization error when creating a + missing directory on startup. + - The scheduler did not always read all of the HTTP headers from a + CGI script/program. + - The scheduler did not always set the "air" property in Bonjour/DNS-SD + registrations. + - The scheduler incorrectly compared Mac OS X UUIDs for access + control, preventing access in certain configurations. + - The IPP backend incorrectly reset the required authentication + to Kerberos when authentication failed. + - The scheduler no longer looks up the local hostname by default; + turn on hostname lookups to restore the previous behavior. + - The scheduler did not always load MIME type rules correctly + (STR #3059) + - The test page did not format correctly on A4 paper (STR #3060) + - The web interface sometimes incorrectly redirected users to + 127.0.0.1 (STR #3022) + - cupsPrintFile*() did not send the document filename for single + file submissions (STR #3055) + - The scheduler did not update the member-names attribute when + removing the last printer from a class. + - The scheduler did not report PPD Products with parenthesis + in them properly (STR #3046) + - The wrong italic fonts were listed in the UTF-8 charset file + for the text filter. + - The backends did not return an OK status for the + CUPS_SC_CMD_GET_BIDI side-channel command (STR #3029) + - The scheduler did not purge jobs that were missing a + time-at-creation attribute, indicating a bad job control file + (STR #3030) + - The "-o job-hold-until=week-end" option did not work properly + (STR #3025) + - The Solaris USB printer device does not support select or poll + (STR #3028) + - The scheduler would crash if you exceeded the MaxSubscriptions + limit. + - The lp "-H immediate" option did not specify that the job + should not be held (STR #3013) + - The scheduler did not support the "Connection: close" + HTTP header (STR #3010) + - The mailto notifier didn't terminate messages properly + (STR #3011) + - Backends could spin trying to read back-channel data + (STR #3001) + - The HP-GL/2 filter was using the wrong default colors + (STR #2966) + - The scheduler incorrectly allowed Get-Jobs operations without a + printer-uri (STR #2996) + - The compression option was not being encoded properly + (STR #2997) + - Added a missing character map for JIS-X0213/ShiftJIS. + - The scheduler now rejects ATTR: messages with empty values. + - The scheduler could consume all CPU handling closed connections + (STR #2988) + - Fixed some configure script bugs with rc/xinetd directories + (STR #2970) + - The Epson sample driver PPDs contained errors (STR #2979) + + +CHANGES IN CUPS V1.3.9 + + - SECURITY: The HP-GL/2 filter did not range check pen numbers + (STR #2911) + - SECURITY: The SGI image file reader did not range check + 16-bit run lengths (STR #2918) + - SECURITY: The text filter did not range check cpi, lpi, or + column values (STR #2919) + - Documentation updates (STR #2904, STR #2944) + - The French web admin page was never updated (STR #2963) + - The IPP backend did not retry print jobs when the printer + reported itself as busy or unavailable (STR #2951) + - The "Set Allowed Users" web interface did not handle trailing + whitespace correctly (STR #2956) + - The PostScript filter did not work with Adobe applications + using custom page sizes (STR #2968) + - The Mac OS X USB backend did not work with some printers + that reported a bad 1284 device ID. + - The scheduler incorrectly resolved the client connection + address when HostNameLookups was set to Off (STR #2946) + - The IPP backend incorrectly stopped the local queue if + the remote server reported the "paused" state. + - The cupsGetDests() function did not catch all types of + request errors. + - The scheduler did not always log "job queued" messages + (STR #2943) + - The scheduler did not support destination filtering using + the printer-location attribute properly (STR #2945) + - The scheduler did not send the server-started, + server-restarted, or server-stopped events (STR #2927) + - The scheduler no longer enforces configuration file + permissions on symlinked files (STR #2937) + - CUPS now reinitializes the DNS resolver on failures + (STR #2920) + - The CUPS desktop menu item was broken (STR #2924) + - The PPD parser was too strict about missing keyword + values in "relaxed" mode. + - The PostScript filter incorrectly mirrored landscape + documents. + - The scheduler did not correctly update the + auth-info-required value(s) if the AuthType was Default. + - The scheduler required Kerberos authentication for + all operations on remote Kerberized printers instead + of just for the operations that needed it. + - The socket backend could wait indefinitely for back- + channel data with some devices. + - PJL panel messages were not reset correctly on older + printers (STR #2909) + - cupsfilter used the wrong default path (STR #2908) + - Fixed address matching for "BrowseAddress @IF(name)" + (STR #2910) + - Fixed compiles on AIX. + - Firefox 3 did not work with the CUPS web interface in SSL + mode (STR #2892) + - Custom options with multiple parameters were not emitted + correctly. + - Refined the cupstestppd utility. + - ppdEmit*() did not support custom JCL options (STR #2889) + - The cupstestppd utility incorrectly reported missing + "en" base translations (STR #2887) + + +CHANGES IN CUPS V1.3.8 + + - Documentation updates (STR #2785, STR #2861, STR #2862) + - The scheduler did not add the ending job sheet when the + job was released. + - The IPP backend did not relay marker-* attributes. + - The CUPS GNOME/KDE menu item was not localized for + Chinese (STR #2880) + - The CUPS GNOME/KDE menu item was not localized for + Japanese (STR #2876) + - The cupstestppd utility reported mixed line endings for + Mac OS and Windows PPD files (STR #2874) + - The pdftops filter did not print landscape orientation PDF + pages correctly on all printers (STR #2850) + - The scheduler did not handle expiring of implicit classes + or their members properly, leading to a configuration where + one of the members would have a short name (STR #2766) + - The scheduler and cupstestppd utilities did not support + cupsFilter and cupsPreFilter programs with spaces in their + names (STR #2866) + - Removed unused variables and assignments found by the + LLVM "clang" tool. + - Added NULL checks recommended by the LLVM "clang" tool. + - The scheduler would crash if you started a printer that + pointed to a backend that did not exist (STR #2865) + - The ppdLocalize functions incorrectly mapped all generic + locales to country-specific locales. + - The cups-driverd program did not support Simplified Chinese + or Traditional Chinese language version strings (STR #2851) + - Added an Indonesian translation (STR #2792) + - Fixed a timing issue in the backends that could cause data + corruption with the CUPS_SC_CMD_DRAIN_OUTPUT side-channel + command (STR #2858) + - The scheduler did not support "HostNameLookups" with all of + the boolean names (STR #2861) + - Fixed a compile problem with glibc 2.8 (STR #2860) + - The scheduler incorrectly filtered out queues with ACLs and + authentication. + - The PostScript filter did not support %%IncludeFeature lines + in the page setup section of each page (STR #2831) + - The scheduler did not generate printer-state events when the + default printer was changed (STR #2764) + - cupstestppd incorrectly reported a warning about the PPD format + version in some locales (STR #2854) + - cupsGetPPD() and friends incorrectly returned a PPD file for + a class with no printers. + - The member-uris values for local printers in a class returned + by the scheduler did not reflect the connected hostname or + port. + - The CUPS PHP extension was not thread-safe (STR #2828) + - The scheduler incorrectly added the document-format-default + attribute to the list of "common" printer attributes, which + over time would slow down the printing system (STR #2755, + STR #2836) + - The cups-deviced and cups-driverd helper programs did not set + the CFProcessPath environment variable on Mac OS X (STR #2837) + - "lpstat -p" could report the wrong job as printing (STR #2845) + - The scheduler would crash when some cupsd.conf directives + were missing values (STR #2849) + - The web interface "move jobs" operation redirected users to + the wrong URL (STR #2815) + - The Polish web interface translation contained errors + (STR #2815) + - The scheduler did not report PostScript printer PPDs with + filters as PostScript devices. + - The scheduler did not set the job document-format attribute + for jobs submitted using Create-Job and Send-Document. + - cupsFileTell() did not work for log files opened in append + mode (STR #2810) + - The scheduler did not set QUERY_STRING all of the time + for CGI scripts (STR #2781, STR #2816) + - The scheduler now returns an error for bad job-sheets + values (STR #2775) + - Authenticated remote printing did not work over domain + sockets (STR #2750) + - The scheduler incorrectly logged errors for print filters + when a job was canceled (STR #2806, #2808) + - The scheduler no longer allows multiple RSS subscriptions + with the same URI (STR #2789) + - The scheduler now supports Kerberized printing with + multiple server names (STR #2783) + - "Satisfy any" did not work in IPP policies (STR #2782) + - The CUPS imaging library would crash with very large + images - more than 16Mx16M pixels (STR #2805) + - The PNG image loading code would crash with large images + (STR #2790) + - The scheduler did not limit the total number of filters. + - The scheduler now ensures that the RSS directory has + the correct permissions. + - The RSS notifier did not quote the feed URL in the RSS + file it created (STR #2801) + - The web interface allowed the creation and cancellation + of RSS subscriptions without a username (STR #2774) + - Increased the default MaxCopies value on Mac OS X to + 9999 to match the limit imposed by the print dialog. + - The scheduler did not reject requests with an empty + Content-Length field (STR #2787) + - The scheduler did not log the current date and time and + did not escape special characters in request URIs when + logging bad requests to the access_log file (STR #2788) + + +CHANGES IN CUPS V1.3.7 + + - CVE-2008-0047: cgiCompileSearch buffer overflow (STR #2729) + - CVE-2008-1373: CUPS GIF image filter overflow (STR #2765) + - Updated the "make check" tests to do a more thorough + automated test. + - cups-driverd complained about missing directories (STR + #2777) + - cupsaddsmb would leave the Samba username and password on + disk if no Windows drivers were installed (STR #2779) + - The Linux USB backend used 100% CPU when a printer was + disconnected (STR #2769) + - The sample raster drivers did not properly handle SIGTERM + (STR #2770) + - The scheduler sent notify_post() messages too often on + Mac OS X. + - Kerberos access to the web interface did not work + (STR #2748) + - The scheduler did not support "AuthType Default" in IPP + policies (STR #2749) + - The scheduler did not support the "HideImplicitMembers" + directive as documented (STR #2760) + - "make check" didn't return a non-zero exit code on + error (STR #2758) + - The scheduler incorrectly logged AUTH_foo environment + variables in debug mode (STR #2751) + - The image filters inverted PBM files (STR #2746) + - cupsctl would crash if the scheduler was not running + (STR #2741) + - The scheduler could crash when printing using a port + monitor (STR #2742) + - The scheduler would crash if PAM was broken (STR #2734) + - The image filters did not work with some CMYK JPEG files + produced by Adobe applications (STR #2727) + - The Mac OS X USB backend did not work with printers that + did not report a make or model. + - The job-sheets option was not encoded properly (STR #2715) + - The scheduler incorrectly complained about missing LSB + PPD directories. + + +CHANGES IN CUPS V1.3.6 + + - Documentation updates (STR #2646, STR #2647, STR #2649) + - Fixed a problem with the web interface "Use Kerberos + Authentication" check box (STR #2703) + - The scheduler unconditionally overwrote the printer-state- + message with "process-name failed" when a filter or backend + failed, preventing a useful error message from being shown + to the user. + - Policies on CUPS-Move-Job didn't work as expected (STR + #2699) + - The configure script only supported D-BUS on Linux + (STR #2702) + - The scheduler did not support (STR #2701) + - The scheduler did not reset the job-hold-until attribute + after a job's hold time was reached. + - The scheduler did not support printer supply attributes + (STR #1307) + - The Kerberos credentials provided by some Windows KDCs + were still too large - now use a dynamic buffer to + support credentials up to 64k in size (STR #2695) + - Printing a test page from the web interface incorrectly + defaulted to the "guest" user (STR #2688) + - The cupsEncodeOptions2() function did not parse multiple- + value attribute values properly (STR #2690) + - The scheduler incorrectly sent printer-stopped events for + status updates from the print filters (STR #2680) + - The IPP backend could crash when handling printer errors + (STR #2667) + - Multi-file jobs did not print to remote CUPS servers + (STR #2673) + - The scheduler did not provide the Apple language ID to + job filters. + - Kerberos authentication did not work with the web + interface (STR #2606, STR #2669) + - The requesing-user-name-allowed and -denied functionality + did not work for Kerberos-authenticated usernames (STR + #2670) + - CUPS didn't compile on HP-UX 11i (STR #2679) + - cupsEncodeOptions2() did not handle option values like + "What's up, doc?" properly. + - Added lots of memory allocation checks (Fortify) + - The scheduler would crash if it was unable to add a job + file (Fortify) + - ppdOpen*() did not check all memory allocations (Coverity) + - ippReadIO() did not check all memory allocations (Coverity) + - The PostScript filter did not detect read errors (Coverity) + - The scheduler did not check for a missing job-sheets-completed + attribute when sending an event notification (Coverity) + - "Set Printer Options" might not work with raw queues (Coverity) + - cupsRasterInterpretPPD() could crash on certain PostScript + errors (Coverity) + - The USB backend did not check for back-channel support + properly on all systems (Coverity) + - Fixed memory leaks in the GIF and PNM image loading code + (Coverity) + - Removed some dead code in the CUPS API and scheduler (Coverity) + - Fixed two overflow bugs in the HP-GL/2 filter (Coverity) + - Fixed another ASN1 string parsing bug (STR #2665) + - The RSS notifier directory was not installed with the + correct permissions. + - The standard CUPS backends could use 100% CPU while waiting + for print data (STR #2664) + - Filename-based MIME rules did not work (STR #2659) + - The cups-polld program did not exit if the scheduler crashed + (STR #2640) + - The scheduler would crash if you tried to set the port-monitor + on a raw queue (STR #2639) + - The scheduler could crash if a polled remote printer was + converted to a class (STR #2656) + - The web interface and cupsctl did not correctly reflect + the "allow printing from the Internet" state (STR #2650) + - The scheduler incorrectly treated MIME types as case- + sensitive (STR #2657) + - The Java support classes did not send UTF-8 strings to + the scheduler (STR #2651) + - The CGI code did not handle interrupted POST requests + properly (STR #2652) + - The PostScript filter incorrectly handled number-up when + the number of pages was evenly divisible by the number-up + value. + - The PDF filter incorrectly filtered pages when page-ranges + and number-up were both specified (STR #2643) + - The IPP backend did not handle printing of pictwps files + to a non-Mac CUPS server properly. + - The scheduler did not detect network interface changes + on operating systems other than Mac OS X (STR #2631) + - The scheduler now logs the UNIX error message when it + is unable to create a request file such as a print job. + - Added support for --enable-pie on Mac OS X. + + +CHANGES IN CUPS V1.3.5 + + - The SNMP backend did not check for negative string + lengths (STR #2589) + - The scheduler incorrectly removed auth-info attributes, + potentially leading to a loss of all options for a job. + - The scheduler stopped sending CUPS browse packets on a + restart when using fixed addresses (STR #2618) + - Fixed PDF filter security issues (CVE-2007-4352 + CVE-2007-5392 CVE-2007-5393) + - Changing settings would always change the DefaultAuthType + and Allow lines (STR #2580) + - The scheduler would crash when submitting an undefined + format file from Samba with LogLevel debug2 (STR #2600) + - The scheduler did not use poll() when epoll() was not + supported by the running kernel (STR #2582) + - Fixed a compile problem with Heimdal Kerberos (STR #2592) + - The USB backend now retries connections to a printer + indefinitely rather than stopping the queue. + - Printers with untranslated JCL options were not exported + to Samba correctly (STR #2570) + - The USB backend did not work with some Minolta USB + printers (STR #2604) + - The strcasecmp() emulation code did not compile (STR + #2612) + - The scheduler would crash if a job was sent to an empty + class (STR #2605) + - The lpc command did not work in non-UTF-8 locales (STR + #2595) + - Subscriptions for printer-stopped events also received + other state changes (STR #2572) + - cupstestppd incorrectly reported translation errors for + the "en" locale. + - ppdOpen() did not handle custom options properly when the + Custom attribute appeared before the OpenUI for that + option. + - The scheduler could crash when deleting a printer or + listing old jobs. + - The Mac OS X USB backend did not allow for requeuing of + jobs submitted to a class. + - lpmove didn't accept a job ID by itself. + - The scheduler incorrectly removed job history information + for remote print jobs. + - The scheduler incorrectly sent the + "com.apple.printerListChanged" message for printer state + changes. + - The PostScript filter drew the page borders (when enabled) + outside the imageable area. + - The LPD and IPP backends did not default to the correct + port numbers when using alternate scheme names. + - The scheduler incorrectly deleted hardwired remote + printers on system sleep. + - The scheduler would abort if a bad browse protocol name + was listed in the cupsd.conf file. + - The online cupsd.conf help file incorrectly showed + "dns-sd" instead of "dnssd" for Bonjour sharing. + - The scheduler could crash changing the port-monitor value. + - The scheduler generated CoreFoundation errors when run as + a background process. + - When printing with number-up > 1, it was possible to get + an extra blank page. + + +CHANGES IN CUPS V1.3.4 + + - Documentation updates (STR #2560, STR #2563, STR #2569) + - CUPS now maps the "nb" locale to "no" on all platforms + (STR #2575) + - CUPS did not work with a Windows 2003 R2 KDC (STR #2568) + - ippReadIO() could read past the end of a buffer (STR + #2561) + - The scheduler would crash on shutdown if it was unable + to create a Kerberos context. + - Multiple AuthTypes in cupsd.conf did not work (STR + #2545) + - The snmp.conf file referenced the wrong man page (STR + #2564) + - The cupsaddsmb program didn't handle domain sockets + properly (STR #2556) + - The scheduler now validates device URIs when adding + printers. + - Updated httpSeparateURI() to support hostnames with + the backslash character. + - Updated the Japanese localization (STR #2546) + - The parallel backend now gets the current IEEE-1284 + device ID string on Linux (STR #2553) + - The IPP backend now checks the job status at + variable intervals (from 1 to 10 seconds) instead + of every 10 seconds for faster remote printing + (STR #2548) + - "lpr -p" and "lpr -l" did not work (STR #2544) + - Compilation failed when a previous version of CUPS + was installed and was included in the SSL include + path (STR #2538) + - The scheduler did not reject requests with charsets + other than US-ASCII or UTF-8, and the CUPS API + incorrectly passed the locale charset to the scheduler + instead of UTF-8 (STR #2537) + - cups-deviced did not filter out duplicate devices. + - The AppleTalk backend incorrectly added a scheme + listing when AppleTalk was disabled or no printers + were found. + - The PostScript filter generated N^2 copies when the + printer supported collated copies and user requested + reverse-order output. + - The scheduler did not reprint all of the files in a + job that was held. + - The scheduler did not update the printcap file after + removing stale remote queues. + - The cupsd.conf man page incorrectly referenced + "AuthType Kerberos" instead of "AuthType Negotiate". + + +CHANGES IN CUPS V1.3.3 + + - The scheduler did not use the attributes-natural-language + attribute when passing the LANG environment variable to + cups-deviced or cups-driverd. + - The scheduler did not use the printer-op-policy when + modifying classes or printers (STR #2525) + - The auth-info-required attribute was not always updated + for remote queues that required authentication. + - The German web interface localization contained errors + (STR #2523) + - The Swedish localization contained errors (STR #2522) + + +CHANGES IN CUPS V1.3.2 + + - The 1.3.1 release was incorrectly created from the + 1.4.x source tree (STR #2519) + - Added support for 32/64-bit libraries on HP-UX + (STR #2520) + - The scheduler incorrectly used portrait as the default + orientation (STR #2513) + - The scheduler no longer writes the printcap file for + every remote printer update (STR #2512) + - Remote raw printing with multiple copies did not work + (STR #2518) + - Updated the configure script to require at least autoconf + 2.60 (STR #2515) + - Some gzip'd PPD files were not read in their entirety + (STR #2510) + + +CHANGES IN CUPS V1.3.1 + + - Documentation updates. + - The USB backend on Mac OS X could hang if the driver and + printer did not match. + - Delegated Kerberos credentials were not working. + - "make distclean" incorrectly removed the edit-config.tmpl + files (STR #2508) + - Fix compile problem on HP-UX (STR #2501) + - The cupstestppd utility now tests for resolutions greater + than 99999 DPI to detect a missing "x" between the X and Y + resolutions. + - Fixed many problems in the various translations and added + a new "checkpo" utility to validate them. + - The cupstestppd utility now tests the custom page size code + for CUPS raster drivers. + - cupsLangDefault() did not attempt to return a language that + was supported by the calling application. + - If a remote printer stopped while a job was being sent, the + local queue would also get stopped and the job re-queued, + resulting in duplicate prints in some cases. + - A few Apple-specific job options needed to be omitted when + printing a banner page. + - The new peer credential support did not compile on FreeBSD + (STR #2495) + - Direct links to help files did not set the current section + so the table-of-contents was not shown. + - The configure script did not support --localedir=foo (STR #2488) + - The backends were not displaying their localized messages. + - CUPS-Authenticate-Job did not require Kerberos authentication + on queues protected by Kerberos. + - The Zebra ZPL driver did not work with Brady label printers + (STR #2487) + - Norwegian wasn't localized on Mac OS X. + - getnameinfo() returns an error on some systems when DNS is + not available, leading to numerous problems (STR #2486) + - The cupsfilter command did not work properly on Mac OS X. + - The scheduler makefile contained a typo (STR #2483) + - The TBCP and BCP port monitors did not handle the trailing + CTRL-D in some PostScript output properly. + - Fixed the localization instructions and German template for + the "Find New Printers" button (STR #2478) + - The web interface did not work with the Chinese localization + (STR #2477) + - The web interface home page did not work for languages that + were only partially localized (STR #2472) + - Updated the Spanish web interface localization (STR #2473) + - ppdLocalize() did not work for country-specific localizations. + + +CHANGES IN CUPS V1.3.0 + + - The scheduler did not handle out-of-file conditions + gracefully when accepting new connections, leading to + heavy CPU usage. + - The scheduler did not detect ServerBin misconfigurations + (STR #2470) + - "AuthType Default" did not work as expected when the + "DefaultAuthType foo" line appeared after it in the + cupsd.conf file. + - The on-line help did not describe many common printing + options (STR #1846) + - The IPP backend did not return the "auth required" status + when printing to a Kerberos-protected queue. + - The scheduler was not looking in the correct directories + for LSB PPD files (STR #2464) + - Changed references to ESP Ghostscript to GPL Ghostscript + (STR #2463) + - The PostScript filter did not cleanly terminate when + the job was canceled or stopped. + - Fixed generation of Kerberos credentials for remote + printing. Note that this requires a recent version of + MIT Kerberos with a working krb5_cc_new_unique() + function or Heimdal Kerberos. + - Added Portuguese and updated Italian message catalogs. + + +CHANGES IN CUPS V1.3rc2 + + - Added more range checking to the pdftops filter. + - The scheduler would crash if a remote IPP queue was stopped + (STR #2460) + - The scheduler did not allow "DefaultAuthType None". + + +CHANGES IN CUPS V1.3rc1 + + - Updated the German localization (STR #2443) + - cupsAdminGetServerSettings() did not handle properly. + - When lprm and cancel are run with no job ID, they now will + cancel the first stopped job if no pending or processing + jobs are left in the queue. + - The scheduler now logs successful print jobs, filter + failures, and the job file types at the default log + level (STR #2458) + - The scheduler now logs the usernames it is using for + authorization at LogLevel debug instead of debug2 (STR #2448) + - Added Intellitech Intellibar and Zebra CPCL PPDs to the list + of installed PPDs. + - Added 6" and 8" wide label sizes for the Zebra ZPL Label + Printer driver (STR #2442) + - The cupsaddsmb program and web interface now support + exporting of 64-bit Windows drivers, when available + (STR #2439) + - Moving a job that was printing did not stop the job on the + original printer (STR #2262) + - The cups-lpd mini-daemon did not work on Mac OS X server. + - Added httpGetAuthString() and httpSetAuthString() APIs to get + and set the current (cached) authorization string to use for + HTTP requests. + - Updated the default cupsd.conf policy to list the + "administrative" operations separately from the "printer + control" operations so that it is easier to define a + group of users that are "printer operators". + - The web interface now pulls the default cupsd.conf file + from cupsd.conf.default in the CUPS config directory. + - Added a help file for using Kerberos with CUPS. + - The scheduler now strips the "@KDC" portion of Kerberos + usernames since those usernames typically do not appear in + the group membership lists used by CUPS. + - cupsMarkOptions() could (incorrectly) leave multiple option + choices marked. + - Backends could (incorrectly) run as root during discovery + (STR #2454) + - Avahi is now supported for DNS-SD (Bonjour) printer sharing + (STR #2455) + - The default cupsd.conf file had typos and old operation names + (STR #2450) + - The scheduler now erases authentication cache files using the + 7-pass US DoD algorithm. + - Delegated Kerberos credentials (proxy authentication) did not + work. + - The filter makefile did not optimize the libcupsimage.2.dylib + with a sectorder file. + - The IPP backend incorrectly wrote an empty printer message + when processing the "none" state reason. + - The USB backend could deadlock on Mac OS X while performing + a side-channel command. + - The scheduler did not prevent remote queues from being + shared/published. + - The scheduler did not remove the temporary request file on + authentication errors. + - ppdLocalizeIPPReason() did not handle "scheme:" schemes or + "file" URLs. + - ppdLocalizeIPPReason() was not exported on Mac OS X. + + +CHANGES IN CUPS V1.3b1 + + - Copyright updates - CUPS is now owned by Apple Inc. + - Documentation updates (STR #1775, STR #2027, STR #2130, + STR #2131, STR #2263, STR #2356, STR #2397) + - Added new cupsfilter utility (STR #1734) + - Added new job-printer-state-message and + job-printer-state-reasons attributes to jobs (STR #2418) + - Added LDAP+SSL support (STR #1967) + - CUPS now supports authentication via peer credentials + over domain sockets (STR #2242, STR #2277) + - The CUPS sample driver PPDs are now generated by the PPD + compiler and include all of the localized languages by + default (STR #2164) + - You can now specify "AuthType Default" in the cupsd.conf + file to use the default authentication defined by the + DefaultAuthType directive. + - The SNMP backend no longer adds a default Address line + when none is specified in the snmp.conf file; this allows + the backend to be easily disabled as needed (STR #2434) + - Added a new cupsctl command for doing basic changes to + the cupsd.conf file (STR #1777) + - Added a new ppdLocalizeIPPReason() function to get the + localized text/URI for a given IPP reason keyword for a + driver. + - Removed the deskjet2.ppd driver, as it only worked with + a very small subset of HP DeskJet printers and was + confusing to users. The rastertohp driver still + supports the deskjet2.ppd options for existing queues. + - The scheduler did not add a trailing banner page if a + client did not specify the last document in a job (STR + #1711) + - The scheduler did not report Bonjour shared printers as + remote printers (STR #2384) + - Added new -R and -W options to the cupstestppd program + for greater control over the testing of PPDs. + - Added a new cupsGetServerPPD() function for getting + an available PPD from the server (STR #2334) + - Added a new cupsDoIORequest() function for reading + and writing files via IPP requests (STR #2334) + - Added a new CUPS_GET_PPD operation for getting an + available PPD file on the server (STR #2334) + - CUPS_GET_PPDS now reports multiple ppd-product values + based on the PPD ModelName and Product strings (STR + #2334, STR #2383) + - CUPS_GET_PPDS now reports the PSVersion attributes + from a PPD file in the ppd-psversion attribute + (STR #2334) + - CUPS_GET_PPDS now reports the cupsModelNumber attribute + from a PPD file in the ppd-model-number attribute (STR + #2383) + - CUPS_GET_PPDS now reports a driver type string in the + ppd-type attribute based on the cupsFax and cupsFilter + attributes in a PPD file (STR #2383) + - Added a new printer attribute called "cups-version" + which reports the version of CUPS that is running + (STR #2240) + - backendRunLoop() now aborts immediately on SIGTERM + if no data has been written yet (STR #2103) + - Due to poor IPP support from the vendors, the SNMP + backend no longer tries IPP connections; instead, + it now uses a lookup file with fallback to port 9100 + (socket://address) and 515 (lpd://address) printing + (STR #2035, STR #2354) + - The scheduler now recreates the CUPS log directory as + needed (STR #2353) + - cupsLangDefault() now maps new-style Apple locale names + to the traditional ll_CC form (STR #2357) + - Add new cupsArrayNew2() API to support hashed lookups + of array elements (STR #2358) + - ppdConflicts() optimizations (STR #2358) + - The cupstestppd program now tests for existing filters, + icons, profiles, and dialog extensions (STR #2326) + - The web interface no longer lists new printers on the + main administration page. Instead, a new "List Available + Printers" button is provided that shows a separate page + with the list of printers. + - The web interface now supports setting the banner and + policy options on raw printers and classes (STR #2238) + - The socket backend now reads any pending back-channel + data before shutting down the socket (STR #2325) + - Added a new ErrorPolicy directive in the cupsd.conf + file (STR #1871) + - Printers that use JCL options are now exported to Samba + correctly (STR #1985) + - The IPP backend now relays printer-state-message values + from the server to the client (STR #2109) + - Added support for the PWG printer-alert and + printer-alert-description attributes (STR #2088) + - Added support for LPD "stream" mode (STR #2036) + - The scheduler now reports the PostScript product string + from PPD files in CUPS-Get-PPDs responses (STR #1900) + - Raw printing with queues pointing to the file pseudo- + device and multiple files and/or banners now works (STR + #1933) + - Added new public cupsAdminGetServerSettings() and + cupsAdminSetServerSettings() APIs. + - Added new "makebuttons" script in the "tools" directory + for creating web interface buttons (STR #2231) + - Added support for DNS-SD (aka "Bonjour") printer sharing + (STR #1171) + - Job operations (cancel, hold, release, etc.) from the + web interface now return back to the original page (STR + #2239) + - The classes or printers list is now shown after a + successful deletion from the web interface (STR #1999) + - The default configuration now allows browse packets from + any address (STR #2008) + - The web interface now provides an "allow printing from the + Internet" check box (STR #1897) + - The notify-events-default and + notify-lease-duration-default attributes can now be set + (STR #1671) + - Server-side default options are now sent to clients when + the "printer-defaults" attribute group is requested (STR + #1923) + - Added support for Linux "relro" linker option (STR #1614) + - CUPS now validates the number-up option value (STR #1329) + - The on-line help now provides better search capabilities + (STR #1701) + - The web interface "Add This Printer" button now allows you + to change the printer name, description, and location + (STR #1646) + - Added support for Mac OS X authorization services + (STR #2206) + - Added support for driver-specific pre-filters (STR #2108) + - Added a new side-channel API for drivers and backends + for basic device control and information queries (STR + #1898) + - The scheduler now uses poll(), epoll(), or /dev/kqueue + instead of select() when possible (STR #1261) + - Added new cupsArrayGetIndex() and cupsArrayGetInsert() + functions to get the current index and insertion + positions of an array. + - Added a new --with-max-copies configure option (STR + #2090) + - Added new cupsRemoveDest() and cupsSetDefaultDest() + functions. + - Added support for cupsPJLCharset attribute in PPD files + which specifies the character set that is used in PJL + strings (STR #1969) + - Moved the definition of the (private) _http_s structure + to http-private.h; code that directly accesses the + http_t members will no longer compile! + - Added support for setting the document-format-default + attribute on a per-printer basis. + - Added support for IntelliBar label printers. diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 0000000000..92301c4553 --- /dev/null +++ b/CHANGES.txt @@ -0,0 +1,838 @@ +CHANGES.txt - 2011-06-20 +------------------------ + +CHANGES IN CUPS V1.4.7 + + - Documentation changes (STR #3710, STR #3720, STR #3745, STR #3750, + STR #3757, STR #3758, STR #3782, STR #3826, STR #3829, STR #3837) + - Web interface fixes (STR #3412, STR #3345, STR #3455, STR #3707, + STR #3755, STR #3769, STR #3783) + - Configure script fixes (STR #3659, STR #3691) + - Compilation fixes (STR #3718, STR #3771, STR #3774) + - The imageto* filters could crash with bad GIF files (STR #3867) + - The scheduler might leave old job data files in the spool directory + (STR #3795) + - CUPS did not work with locales using the ASCII character set + (STR #3832) + - httpAddrString() did not return a URI-style IPv6 numeric address + (STR #3814) + - Fixed an issue when reading compressed CUPS raster streams (STR #3812) + - Fixed an issue with PostScript printer auto-configuration (STR #3443) + - Fixed some compatibility issues with the libusb-based USB backend + (STR #3799) + - The network backends no longer try to collect SNMP supply and status + information for raw queues (STR #3809) + - The DBUS notifier did not report job state changes (STR #3805) + - The scheduler did not always report that the "normal" print-quality + value was supported (STR #3803) + - The gziptoany filter did not report the correct error if it was unable + to write the uncompressed document to the next filter or backend in + the chain (STR #3797) + - The Epson and Oki 9-pin drivers had a bad resolution option + (STR #3798) + - The scheduler did not always register the correct default ICC profile + on Mac OS X. + - The scheduler did not use the job owner when authorizing access for + the CUPS-Get-Document operation, preventing non-admins from accessing + their own jobs. + - CUPS did not work with some printers that incorrectly implemented the + HTTP/1.1 standard (STR #3778, STR #3791) + - The scheduler did not retry fax jobs properly. + - The scheduler now recognizes an empty cupsCommands PPD keyword as + meaning that CUPS commands are not supported for a printer (STR #3773) + - Fixed a crash bug in the scheduler when the application/octet-stream + MIME type was not defined (STR #3690) + - Polled printers were advertised more slowly than necessary (STR #3574) + - cupsResolveConflicts() did not handle resolving multiple UIConstraints + issues (STR #3705) + - The SetEnv and PassEnv directives had no effect (STR #3664) + - The web interface no longer tries to use multi-part delivery when + adding printers (STR #3455) + - The libusb-based USB backend printed slowly to the LaserJet 1300 and + other printers (STR #3405) + - "lp" and "lpr" failed to print with Kerberos enabled (STR #3768) + - The cupsctl program now displays an error if you try to directly set + the Port or Listen directives (STR #3749) + - PPD files with "*JobPatchFile: bla" no longer fail to load in relaxed + conformance mode (STR #3747) + - The scheduler generated a bad notify-text string for printer state + change notifications (STR #3739) + - The scheduler incorrectly updated printers.conf when it really needed + to update classes.conf or remote.cache (STR #3726) + - Hardwired remote printers with options did not work (STR #3717) + - Accessing the CUPS web interface using a CNAME-based hostname would + sometimes fail due to redirection to the actual hostname (STR #3701) + - Subscription events had a misspelled attribute (STR #3693) + - "make check" failed if LC_MESSAGES was set (STR #3765) + - Fixed the configure script to always look for the pkg-config script + (STR #3761) + - The scheduler now only looks up interface hostnames if HostNameLookups + are enabled (STR #3737) + - Fixed a compilation problem on DragonFly BSD (STR #3738) + - The default PageLogFormat value had the username and job ID swapped + from CUPS 1.3.x (STR #3727) + - The scheduler could crash if a browsed printer times out while a job + is printing (STR #3754) + - The scheduler incorrectly mapped custom page sizes to standard sizes + (STR #3764) + - cupsfilter and pstops did not map IPP attributes to PPD options due to + a change in cupsMarkOptions (STR #3756) + - The scheduler did not always show the most recent status message from + the print filters (STR #3731) + - The PostScript filter did not apply the mirror and number-up options + properly, leading to offset and clipped output (STR #3732) + - The network backends always reported "low toner" or "out of toner" + states, even for inkjet printers (STR #3733) + + +CHANGES IN CUPS V1.4.6 + + - Fixed a "make check" issue on Solaris (STR #3729) + - Regression: The pstops filter did not support landscape printing of + PostScript files (STR #3722) + - The scheduler killed retried (fax) jobs after restarting them + (STR #3697) + - The cupsAdminSetServerSettings() function disabled sharing when + debug logging was enabled (STR #3712) + + +CHANGES IN CUPS V1.4.5 + + - Documentation fixes (STR #3542, STR #3650) + - Localization fixes (STR #3635, STR #3636, STR #3647, STR #3666) + - Security: Fixed a memory corruption bug reported in CVE-2010-2941 + (STR #3648) + - The CUPS API incorrectly mapped the HTTP_UNAUTHORIZED status to the + IPP_NOT_AUTHORIZED status code, when IPP_NOT_AUTHENTICATED would be + the correct mapping (STR #3684) + - The scheduler would restart jobs while shutting down (STR #3679) + - Fixed a PPD loader bug that could cause a crash in cupsd (STR #3680) + - Improved the mapping of non-standard PPD and PWG names (STR #3671) + - The scheduler did not initialize Kerberos in all cases (STR #3662) + - cupsAdminSetServerSettings duplicated Listen and Order lines + (STR #3645) + - Added DeviceN colorspace support to the CUPS Raster format (STR #3419) + - ppdMarkDefaults() did not clear the marked field of the previous + choices (STR #3642) + - The serial backend would not allow a raw job to be canceled + (STR #3649) + - The socket backend could go into an infinite loop with certain + printers (STR #3622) + - Setting the PRINTER or LPDEST environment variables to "name/instance" + did not work (STR #3485) + - The scheduler did not handle the JobRetryLimit setting properly + (STR #3466) + - The lpstat command always showed a remote job ID of 0 for shared + printers (STR #3627) + - Increased the write timeout for the libusb-based USB backend to 5 + minutes (STR #3595) + - The libusb-base USB backend did not check whether the printer has a + serial number (STR #3590) + - The lpadmin command did not support setting of custom option values + (STR #3631) + - The lpadmin command did not support setting of the location or + description of a class (STR #3613) + - The cupsaddsmb command did not give up after too many failed attempts + (STR #3615) + - The CUPS library no longer uses certain problematic ctype macros that + change based on the locale's character set. + - PJL value substitution of more than 9 values was broken (STR #3621) + - Custom options with missing string values caused ppdEmit* to segfault + (STR #3620) + - Fixed an issue with the Italian version of the web interface + (STR #3624) + - Fixed the Solaris SMF configuration file for cups-lpd (STR #3611) + - The scheduler did not set the notify-subscribed-event attribute when + delivering printer-added or printer-modified events (STR #3608) + - The mailto notifier could get into an infinite loop (STR #3609) + - Date/time information was not shown in banner pages. + - Relational operators were broken in #if/#elif/#else/#endif expressions + for the PPD compiler. + - Moving a job via the web interface failed without asking for + authentication (STR #3559) + - The scheduler now clears the printer-state-reasons when the driver is + changed (STR #3570) + - The web interface did not allow a user to change the driver + (STR #3537, STR #3601) + - The scheduler was not setting the PATH_INFO environment variable when + needed (STR #3600) + - The scheduler incorrectly set the CUPSD_AUTH_TYPE environment + variable instead of AUTH_TYPE (STR #3599) + - Fixed a buffer overrun in the PPD compiler (STR #3594) + - Fixed some additional IPP job template attribute mapping issues in the + scheduler. + + +CHANGES IN CUPS V1.4.4 + + - Documentation updates (STR #3453, STR #3527, STR #3528, STR #3529) + - Security: The texttops filter did not check the results of allocations + (STR #3516) + - Security: The fix for CVE-2009-3553 was incomplete (STR #3490) + - Security: The web admin interface could disclose the contents of + memory (STR #3577) + - Security: CUPS could overwrite files as root in directories owned or + writable by non-root users (STR #3510) + - The cups-config utility did not return the correct linker options on + AIX (STR #3587) + - Fixed some IPP conformance issues with the scheduler's + ippget-event-life, operations-supported, output-bin, and sides + attributes (STR #3554) + - The OpenSSL interfaces have been made thread-safe and the GNU TLS + interface is explicitly forbidden when threading is enabled + (STR #3461) + - Fixed an IPP conformance issue with the scheduler's Send-Document + implementation (STR #3514) + - Added additional validation checks for the 1284 device ID (STR #3534) + - Fixed a problem with the RPM spec file (STR #3544) + - The lpstat command did not limit the job list to the specified + printers (STR #3541) + - The cupsfilter command did not set the RIP_MAX_CACHE environment + variable (STR #3531) + - Fixed support for media-col and page size variants (STR #3394) + - The PostScript filter did not support all media selection options for + the first page (STR #3525) + - The scheduler did not always remove job control files (STR #3425) + - The scheduler could crash on restart if classes were defined + (STR #3524) + - The scheduler no longer looks up network interface hostnames by + default on Mac OS X (STR #3523) + - ippWriteIO did not write collection (member) attributes properly in + all cases (STR #3521) + - The "cupsctl --remote-any" and corresponding web interface check box + (allow printing from the Internet) did not work reliably (STR #3520) + - The lpq and lpr commands would sometimes choose different default + printers (STR #3503) + - cupsDo*Request did not flush error text, leading to multiple issues + (STR #3325, STR #3519) + - cupsDoAuthentication did not cancel password authentication after 3 + failures (STR #3518) + - Fixed several LDAP browsing bugs (STR #3392) + - The Dymo driver did not support copies (STR #3457) + - The scheduler did not update the classes.conf file when deleting a + printer belonging to a class (STR #3505) + - The lppasswd command did not use localized password prompts + (STR #3492) + - The socket backend no longer waits for back-channel data on platforms + other than Mac OS X (STR #3495) + - The scheduler didn't send events when a printer started accepting or + rejecting jobs (STR #3480) + - The web interface now includes additional CSRF protection (STR #3498) + + +CHANGES IN CUPS V1.4.3 + + - SECURITY: The scheduler could try responding on a closed client + connection, leading to a crash (STR #3200) + - SECURITY: The lppasswd program allowed the localization files to be + overridden when running in setuid mode (STR #3482) + - Localization updates (STR #3352, STR #3409, STR #3422, STR #3452, + STR #3473, STR #3502) + - Documentation updates (STR #3451, STR #3504) + - The IPP backend now sets the printer-state-message to "Ready to + print." at the end of a successful job (STR #3460) + - The PPD compiler did not correctly add the manufacturer to the output + filename when using the "-m" option (STR #3469) + - The IPP backend did not handle authentication properly for the Get- + Printer-Attributes operation (STR 3458) + - Getting SNMP values larger than 127 bytes did not work. + - IPP conformance: Get-Jobs has a default value for requested-attributes + (STR #3383) + - cupsPrintFiles() did not report all errors (STR #3449) + - cupsAddDest() could read freed memory (STR #3448) + - The DBUS notifier did not build (STR #3447) + - The scheduler would crash when an active printer was deleted. + - The snmp backend did not work with some printers (STR #3413) + - The web interface did not show the conflicting values when setting + options (STR #3440) + - Setting options in the web interface did not always work (STR #3439) + - The scheduler did not use the Get-Job-Attributes policy for a printer + (STR #3431) + - The scheduler added two job-name attributes to each job object + (STR #3428) + - CSS files would not print (STR #3442) + - The scheduler did not clean out completed jobs when PreserveJobHistory + was turned off (STR #3425) + - The web interface did not show completed jobs for a printer + (STR #3436) + - Authenticated printing did not always work when printing directly to + a remote server (STR #3435) + - The USB backend did not work on Solaris (STR #3423) + - cupstestppd didn't catch problems with JobPatchFile definitions + (STR #3421) + - The socket backend could crash if a SNMP string had a negative length. + - Fixed some termination issues with the USB backend on Mac OS X. + - The side-channel APIs did not handle interrupts properly. + - The network backends incorrectly cleared the media-empty-warning + state. + - The web interface did not allow users to successfully add serial + printers (STR #3391) + - cupsTempFd() did not work in some situations (STR #3382) + - Some C API headers were missing C++ wrapper logic. + - The PPD compiler did not localize single-language PPD options properly + (STR #3386) + - Modifying a printer from the web interface sometimes caused the wrong + driver to be selected (STR #3418) + - The scheduler did not handle out-of-memory conditions properly when + loading a job (STR #3407) + - When adding printers from the web interface, the dynamic updates of + the device list made it hard to pick a device (STR #3406) + - Fixed a typo in the web interface admin page template (STR 3403) + - The web interface did not preserve the "printer is shared" state when + modifying a printer (STR #3390) + - The PPD compiler incorrectly inserted translations of empty strings + (STR #3411) + - The scheduler did not reset the SIGPIPE handler of child processes + (STR #3399) + - cupsGetNamedDest() incorrectly returned the default printer if the + named printer did not exist (STR #3397) + - Fixed a GNU TLS error handling bug (STR #3381) + + +CHANGES IN CUPS V1.4.2 + + - SECURITY: The CUPS web interface was vulnerable to several XSS and + HTTP header/body attacks via attribute injection (STR #3367, + STR #3401) + - Fixed localization errors (STR #3359, STR #3372, STR #3380, STR #3387) + - The documentation for classes.conf and printers.conf did not provide + the correct instructions for manual changes (STR #3351) + - The scheduler did not always rebuild printer cache files when the + driver was changed (STR #3356) + - The documentation makefile failed to install localizations when using + newer versions of Bash (STR #3360) + - The configure script did not use the --with-xinetd value for the + default LPD configuration path (STR #3347) + - The configure script incorrectly required glib for DBUS support + (STR #3346) + - The cupstestppd program incorrectly reported filters with bad + permisssions as missing (STR #3363) + - The cups.desktop file used the wrong locale names (STR #3358) + - cupsSideChannelRead() did not return an error for short reads. + - The installed PAM configuration file did not use the correct options + with the pam_unix2 module (STR #3313) + - The scheduler did not preserve default options that contained special + characters (STR #3340) + - The scheduler did not remove old pre-filters when updating a printer + driver (STR #3342) + - The HP/GL-2 filter did not check for early end-of-file (STR #3319) + - The USB backend did not compile on some platforms (STR #3332) + - cupsSideChannelSNMPWalk() could go into an infinite loop with broken + SNMP implementations. + + +CHANGES IN CUPS V1.4.1 + + - Documention fixes (STR #3296) + - SNMP supply levels and states were wrong for some printers. + - The IPP backend did not update the auth-info-required value. + - The libusb-based USB backend would hang at the end of the job + (STR #3315, STR #3318) + - DNS-SD registrations for raw queues had an empty "ty" key (STR #3299) + - The JPEG and BMP MIME type rules were broken (STR #3284) + - cupsGetNamedDest returned the default printer when the named + destination did not exist (STR #3285) + - The JobKillDelay was not triggered for canceled jobs (STR #3292) + - The PPD compiler could get in an infinite loop (STR #3293) + - The configure check for dns-sd.h was broken (STR #3297) + - The "Query Printer for Default Options" page did not go away if the + query job was held (STR #3302) + - Boolean options did not show up as selected in the web interface + (STR #3303) + - The scheduler did not cache or report driver information files + correctly, leading to a variety of issues (STR #3283, STR #3297, + STR #3305) + - cupsDoIORequest() did not abort on permanent errors (STR #3311) + - Modifying a class in the web interface did not work (STR #3312) + - BrowseLocalProtocols could be cleared when changing the sharing + setting (STR #3287) + - The scheduler could return an empty supported document format + (STR #3308) + - The PPD compiler generated invalid PPD files when the locale used + something other than "." for the decimal point (STR #3300) + - The IPP backend did not handle some non-comforming IPP printer + implementations (STR #3262) + - The scheduler leaked three file descriptors to each job filter + (STR #3263) + - The scheduler now uses a default CUPS-Get-Devices timeout of 15 + seconds (STR #3307) + + +CHANGES IN CUPS V1.4.0 + + - Localization updates (STR #3223, STR #3246, STR #3248, STR #3250) + - Documentation updates (STR #3225, STR #3230, STR #3242, STR #3260) + - The --with-pdftops configure option did not accept a full path to the + filter (STR #3278) + - The banner filter did not position the back side image correctly + (STR #3277) + - The dnssd backend could crash (STR #3272) + - The 1284 device ID sometimes contained trailing garbage (STR #3266) + - The USB backend returned different URIs for some printers than in + CUPS 1.3 (STR #3259) + - The scheduler did not do local job-hold-until processing for remote + queues (STR #3258) + - The scheduler did not try all possible SSL certificates on Mac OS X. + - The scheduler did not always remove a file descriptor when using the + kqueue interface (STR #3256) + - The scheduler did not protect against bad job control files in all + cases (STR #3253) + - The scheduler did not encode "+" in model names (STR #3254) + - The web interface didn't show the default options (STR #3244) + - The IPP and LPD backends needed print data before they would do an + SNMP query. + - Fixed a GNU TLS compatibility issue (STR #3231) + - Fixed a HTML error in the add and modify printer web interface + templates (STR #3229) + - The scheduler did not minimize the number of printer state events that + were generated by filter STATE: messages, which could lead to poor + performance. + - The USB backend on Mac OS X did not cleanly cancel a job. + - The network backends now set the connecting-to-device printer-state- + reasons value when looking up the address and copying the print data + for consistency. + - The scheduler now supports the com.apple.print.recoverable-warning + reason on all platforms. + + +CHANGES IN CUPS V1.4rc1 + + - The PPD compiler documentation was missing information on localization + (STR #3212) + - The IPP backend now reconnects after every request when talking to + printers that claim IPP support but only use HTTP/1.0. + - The PPD compiler crashed when both "Resolution" and "Group foo Option + Resolution" were specified in the .drv file. + - The PPD compiler's #if/#elif/#else/#endif did not work for undefined + variables (STR #3210) + - Static libraries could not be installed by a non-root user on systems + needing a ranlib program (STR #3209) + - The scheduler incorrectly always tried to copy Kerberos credentials + for print jobs. + - Updated the Spanish localization (STR #3204) + - The scheduler crashed when getting the default paper size from + libpaper (STR #3205, STR #3206) + - The PPD compiler now defines six variables: CUPS_VERSION, + CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, CUPS_VERSION_PATCH, + PLATFORM_NAME, and PLATFORM_ARCH (STR #3203) + - Fixed a whitespace skipping bug in cupsRasterInterpretPPD. + - The scheduler did not return HTTP 403 (Forbidden) for authenticated + users that were not authorized to do IPP operations (STR #3193) + - The scheduler did not report more than 8 Product strings from a PPD + file. Some PPD files have as many as 24. + - ppdOpen*() could crash if a keyword had no value string (something + that cupstestppd looks for...) + - cupsLangDefault() did not return the correct language on Mac OS X. + - The Mac OS X USB backend did not handle aborted or stalled pipe + conditions properly, which prevented drivers from ejecting partial + pages when a job was canceled or held. + + +CHANGES IN CUPS V1.4b3 + + - Documentation fixes (STR #3044, STR #3057, STR #3153, STR #3158, + STR #3173) + - Added complete localizations for German, Japanese, Polish, and + Russian and partial localizations for Chinese, Danish, Finnish, + French, Italian, Korean, Norwegian, Portuguese, and Swedish + (STR #3096, STR #3098, STR #3109, STR #3111, STR #3141) + - Updated the configure check for -fstack-protector (STR #3198) + - The network backends now correctly convert SNMP supply descriptions to + UTF-8 encoding as needed. + - The scheduler could crash when deleting an attribute (STR #3197) + - The cups-driverd program did not detect symlink loops (STR #3185) + - The EPSON 24-pin series driver should now feed the correct amount + (STR #2624) + - The scheduler now automatically logs the last N debug messages for + failed print jobs. + - You can now modify a raw print queue (STR #3133) + - Fixed a number of ppdi issues and added a unit test to validate that + ppdc + ppdi can generate and import the same data (STR #3152) + - Moving jobs in the web interface now shows an error if you only have + one printer or class added (STR #3094) + - Since classes have never truly supported the printer-error-policy + stuff added in CUPS 1.2, update the code to reflect the current + reality and support only the retry-current-job policy for now + (STR #3171) + - Revised the password callback support (STR #2953) + - ppdEmit*() did not choose between PageSize and PageRegion properly. + - Make some fairly substantial changes to the Kerberos support code so + that CUPS can work in multi-realm environments and does not require + delegatable credentials. Shared printing still requires delegation, + however "delegation by policy" can be enabled in the KDC to make this + all work. + - "AccessLogLevel actions" did not hide client-error-not-found errors. + - AP_FIRST_InputSlot did not work with number-up. + - cupsBackChannelRead() and cupsBackChannelWrite() could fail due to a + lack of kernel buffers. + - The IPP and LPD backends did not respond to side-channel requests + while copying print data to a temporary file. + - cupsWriteRequestData() flushed the output buffer unnecessarily, + causing reduced performance in some situations. + - If a CGI process died before sending its MIME headers, the request + would hang on the client. + - The printer/class/job search feature on the web interface did not + work (STR #3132) + - The scheduler did not write the printers out for classes. + - CUPS-Get-PPDs did not work properly when filtering by language, + product, or psversion (STR #3136) + - The scheduler now kills job filters when it takes more than 30 seconds + (configurable) to cancel or hold the job. + - The cupstestppd program did not validate the capitalization of + filenames in the PPD file. + - The cupstestppd program did not validate the PageSize and PageRegion + values. + - The cups-deviced helper program could miss reporting some backend + devices (STR #3108) + - The cupsSideChannelSNMP* functions did not work. + - The scheduler could consume 100% CPU when jobs were canceled. + - Clicking on "Select Another Make/Manufacturer" in the web interface + incorrectly added the printer (STR #3095) + - The scheduler no longer uses programs with insecure file + permissions. + - httpAssembleURI*() did not escape backslashes in hostnames. + - The dnssd backend did not unquote "full names" before creating the + device URI. + - The scheduler now supports JobRetryInterval values less than 10 + seconds. + - Updated the Spanish localization (STR #3090) + - The scheduler did not redo Bonjour/DNS-SD registrations when updating + them failed. + - The "authenticated" policy incorrectly required authentication for + status operations. + - ppdOpen*() incorrectly loaded PPDs with multiple JobPatchFile + keywords. + - The network backends no longer report the SNMP "offline" or + maintenance status bits since they are inconsistently implemented and + often unreliable. + - The scheduler no longer logs child processes killed via SIGKILL as + "crashed". + - The printer link shown on the "job moved" template was bad (STR #3085) + - Updated the HTML templates to use the final HTML 4 DOCTYPE (STR #3086) + - The scheduler did not track the "paused" reason properly if a + printer had other reasons associated with it. + - cupsSendRequest() did not clear old local certificate auth data. + - The PPD compiler did not search for localization files properly + (STR #3084) + - cupsGetNamedDest() did not use the fallback default like + cupsGetDests*() (STR #3082) + - The scheduler now provides a LogTimeFormat directive to enable + microseconds in the date and time that are logged. + - The scheduler now provides a MultipleOperationTimeout directive to + control the timeout for multi-file print jobs. + - The configure script incorrectly allowed Avahi to be used for DNS-SD + printer discovery (STR #3065) + - The web interface and scheduler did not support URIs up to 1024 bytes + in length (STR #3072) + - Fixed pdftops issues with page sizes (STR #3063) + - Fixed pdftops issues with Ghostscript (STR #3062) + - The scheduler incorrectly registered default profiles for PostScript + printers with no specified colorspace. + - The scheduler incorrectly created an empty org.cups.printers.plist + file on Mac OS X. + - cupsGetPPD3() did not look for local PPDs in the right directory. + - SNMP lookups via side-channel did not work for NULL-VALUE and + and OCTET-STRING OIDs containing nul characters. + - The libusb-based USB backend did not work. + - The scheduler did not set the printer-commands attribute correctly + for some PPDs. + - The ppdi utility did not work. + - The web interface no longer uses multi-part output with old or broken + web browsers (STR #3049) + - CUPS now conforms to the draft IPP/2.0 and IPP/2.1 specification. + - Added a new cupsGetConflicts() API to get a list of conflicting + options. + - The PPD compiler didn't localize options or choices that did not + have associated translation text (STR #3045) + - Updated the Spanish localization (STR #3043) + - Fixed build problems (STR #3040, STR #3047) + - cupsResolveConflicts() did not resolve using the default option + choice in some cases due to the mirror UIConstraints that are + present in most PPD files. + - The scheduler did not honor MIME type priorities. + - The commandtops filter incorrectly used the JCLBegin code to end + its jobs. + - The default BrowseLocalProtocols value was not set properly. + - Since the commandtops filter does not actually support ReportLevels + all on its own, don't list that printer command by default for PS + printers. + - The scheduler did not give filters a chance to log errors or update + printer attributes when a job was canceled. + - The scheduler did not clear the "connecting-to-device" reason keyword + when a job finished. + + +CHANGES IN CUPS V1.4b2 + + - Documentation updates (STR #2983, STR #2998, STR #3021) + - The cupstestppd utility now validates the FileVersion and + FormatVersion values in PPD files. + - The default cupsd.conf file did not reflect the + --with-local-protocols value set at compile-time (STR #3037) + - The cupsGetPPD* APIs now create symlinks to local PPD files + rather than copying them whenever possible. + - Various performance optimizations in the string pool, dests, and + options implementations. + - The cupsGetDests* APIs now return the marker and printer-commands + attributes. + - Side-channel SNMP lookups would not work when cupsSNMPSupplies + was set to False in the PPD file. + - Localized the device descriptions for the SCSI, serial, + and network backends (STR #3014) + - Added a Spanish localization (STR #3015) + - Added support for marker-low-levels and marker-high-levels + attributes. + - The scheduler could hang writing a long log line. + - The cupsGetDevices() function now has an "include_schemes" + parameter. + - The lpinfo command now supports --include-schemes and + --exclude-schemes options. + - The CUPS-Get-PPDs operation now supports the include-schemes + and exclude-schemes attributes. + - The CUPS-Get-Devices operation now supports the include-schemes + attribute. + - The print filters now support a replacement for the fitplot + option called "fit-to-page". + - The LPD backend no longer tries to collect page accounting + information since the LPD protocol does not allow us to + prevent race conditions. + - The scheduler did not save the last marker-change-time value. + - Fixed a problem with printing to some IPP printers, including + CUPS 1.1.x. + - Fixed a redirection problem with the printer web page (STR #3012) + - Fixed a PPD compiler problem with the loading of message + catalogs (STR #2990) + - Fixed a PPD compiler problem with the loading of .strings files + (STR #2989) + - The cupsfilter utility did not set the CONTENT_TYPE environment + variable when running filters. + - The scheduler now waits to allow system sleep until the jobs + have all stopped. + - The IPP, LPD, and socket backends used different "connecting" + progress messages. + + +CHANGES IN CUPS V1.4b1 + + - Documentation updates (STR #2567) + - The PPD compiler now allows local message catalogs to + override the standard CUPS translations (STR #2642) + - The ppdmerge command did not merge custom option strings + (STR #2863) + - The scheduler now supports the Hold-New-Jobs and + Release-Held-New-Jobs operations; these are exposed via the + cupsdisable and cupsenable commands (STR #2332) + - The lpstat command is now much faster when displaying the + status of a single printer (STR #2843) + - The scheduler now caches information from PPD files to provide + significantly faster startup time with large numbers of PPDs + (STR #1293) + - CUPS-Get-Driver now provides much better driver matching based + on the IEEE-1284 device ID and make/model strings (STR #2707) + - Now support the cupsSNMPSupplies keyword to control whether + the network backends query the SNMP Printer MIB for supply + levels. + - Now support and use a new banner file format for better text + support and easier customization (STR #2490) + - The scheduler now sets the PRINTER_INFO and PRINTER_LOCATION + environment variables from the corresponding IPP attributes. + - The ippRead*() and ippWrite*() functions no longer use a + stack-based buffer (STR #2388) + - The CUPS-Add-Modify-Printer operation now allows you to set + the printer-state-reasons attribute. + - The "set printer options" page now supports auto-configuration + of printer options (STR #1440) + - The web interface now provides an advanced server settings + form. + - The web interface's "modify printer" pages now make it + easier to change just one setting (STR #1919) + - The scheduler now supports a plist PrintcapFormat. + - The scheduler now supports multiple addresses in Allow and + Deny lines, just like Apache (STR #2947) + - Added CUPS_JOBTYPE environment variable for job filters so + they know whether they are printing a banner or document + file (STR #2799) + - Added support for printer filtering by the cupsfilter + command (STR #2562) + - Added a SSLOptions directive to allow Windows clients to + talk to CUPS in FIPS mode (STR #2827) + - Renamed the accept and reject commands to cupsaccept and + cupsreject; the old names are still available (STR #2936) + - The locale/translate utility needed an update to work with + Google (STR #2882) + - The lpstat command now supports a -H option to display the + default server (STR #2833) + - The scheduler now supports a FatalErrors directive to control + which errors should cause the scheduler to exit (STR #2536) + - The scheduler now uses the php-cgi program if it is available + (STR #2923) + - The scheduler now supports a DefaultPaperSize directive + (STR #2848) + - The scheduler now passes the job-originating-host-name + value to filters in the options argument (STR #2558) + - CUPS now supports job tickets in PDF files (STR #2903) + - Added a DBUS notifier (STR #2529) + - The LPD mini-daemon now passes the document name when queuing + print jobs (STR #2482) + - The IPP backend did not relay com.apple.print.recoverable-message + values. + - The scheduler now supports a job-media-progress attribute to + track the progress of individual pages. + - The sample HP driver now supports A5 (STR #2798) + - The CUPS web interface menu item now uses the xdg-open + command, when available (STR #2724) + - The cups-lpd program now supports the -h option (STR #2794) + - The scheduler now sets the PAM_TTY parameter and the + PAM_ESTABLISH_CRED credential flag (STR #2745) + - The scheduler now logs unsuccessful requests to the error_log + file as errors (STR #2616) + - Added support for a "retry-current-job" error policy that + retries the current job immediately when the backend encounters + an error (STR #2555) + - The scheduler now returns a "forbidden" error when a user + correctly authenticates but does not have permission to + continue further (STR #2101) + - The scheduler now loads both the server and CA certificates + (if present) from the ServerCertificate file (STR #2146) + - New RSS subscriptions now create their feed files immediately + (STR #2853) + - Added support for a device-location attribute which provides + the physical location of a printer device. + - Added a cupsBackendReport() API which handles quoting of the + device data by a backend. + - Added support for custom options in the web interface + (STR #1729) + - Added support for Mozilla LDAP, reconnection to LDAP servers, + and improved LDAP performance (STR #1962) + - Added Solaris SMF support (STR #1477) + - Added optional support for using TCP wrappers to limit access + to CUPS (STR #263) + - Added ppdPageSizeLimits API. + - Added support for new cupsMediaQualifier2, cupsMediaQualifier3, + cupsMinSize, and cupsMaxSize attributes. + - Added cupsResolveConflicts and ppdInstallableConflict APIs. + - Added support for new cupsUIConstraints and cupsUIResolver + attributes for better option conflict detection and + resolution. + - Increased the maximum size of 1284 device ID strings to + 256 bytes (STR #2877) + - Added an AccessLogLevel directive to cupsd.conf to control + what is logged to the access_log file. + - The default LogLevel is now "warn" instead of "info" to reduce + the amount of logging that is done to disk by default. + - The PPD compiler did not include OID query keywords in PPD + files (STR #2871) + - The cups-driverd helper program now directly supports driver + information files. + - The USB backend now uses libusb when available (STR #1575) + - Added ppdLocalizeAttr function to get the localized version + of an attribute. + - MIME types now support a priority() attribute (STR #2719) + - The standard MIME types are now installed in + DataDir/mime (STR #2719) + - The lpoptions command now describes custom options and + the necessary parameters (STR #2660) + - The ppdmerge program did not support Simplified Chinese + or Traditional Chinese language version strings (STR #2851) + - The PPD compiler now supports localizable attributes + (STR #2738) + - The ppdpo utility now includes cupsIPPReasons values in + the message catalogs it generates (STR #2754) + - The PPD compiler now supports conditional directives + (STR #2636) + - The ppdc utility now supports a "-t" option to test PPD + files (STR #2739) + - The ppdc utility now supports a "-m" option to use the + ModelName value as the output filename. + - The ppdc utility now supports a FileName directive to + set an alternate output filename (STR #2740) + - The side-channel API now supports SNMP queries for the + standard network backends. + - Added a PageLogFormat directive to the cupsd.conf file to + control the format of lines in the page_log file. + - Filters can now send PPD: messages to stderr to set PPD + keywords like DefaultPageSize while a job is printing. + - Added a mdns backend for discovery and printing to printers + that advertise themselves via DNS-SD (Bonjour) + - The ipp, lpd, and socket backends now support DNS-SD service + name resolution. + - The scheduler now uses a single shared file descriptor for + all DNS-SD registrations (STR #2674) + - The ipp, lpd, and socket backends now support SNMP-based + page accounting and supply level monitoring (STR #1655) + - Added support for cupsPJLDisplay attribute to control what + PJL commands are used to display the job information. + - Driver information files can now be installed in + /Library/Printers/PPDs.drv on Mac OS X. + - The CUPS image library now supports reading images larger + than 2GB. + - The scheduler now delays writing config and state files to + reduce disk activity (STR #2684) + - The CUPS-Get-Devices operation now supports the + exclude-schemes and timeout attributes to control which + backends are polled and for how long. + - The cups-deviced helper application now runs backends in + parallel to get the list of devices faster. + - Added --enable-pap configure option. + - The default cupsd.conf file now includes an "authenticated" + policy which requires authentication for remote print jobs. + - Added support for Czech and Hungarian in PPD files + (STR #2735, STR #2736) + - The PPD compiler tools now support Mac OS X .strings files + for localization (STR #2737) + - ppdOpen*() now default the colorspace member to PPD_CS_N + when no DefaultColorSpace attribute is present in the PPD + file. + - The build system has been updated to support separate + installation of data, program, header, and library files. + - All support libraries are now built as shared libraries + by default. + - The scheduler now manages ICC color profiles on Mac OS X. + - The network backends (ipp, lpd, socket) now support + SNMP-based supply and page count monitoring (STR #1655) + - The lppasswd program is no longer installed setuid to + root to make the default installation more secure. + - Added a new ppdLocalizeMarkerName() function to get + the localized version of a marker-names value. + - The scheduler now provides the printer-dns-sd-name + attribute for printers shared via DNS-SD/Bonjour. + - The pdftops filter now executes the Xpdf or poppler + pdftops utility to convert PDF files (STR #1471) + - Bonjour printer registrations now advertise as local or + global based on the current access policies for the + printer. + - cupsGetDests*() and cupsSetDests*() now track the last + used printer preference on Mac OS X. + - Added a new streaming request API (STR #2261) + - Added a new cupsGetNamedDest() function to the CUPS + library for faster printing with lp and lpr (STR #2638) + - The scheduler now sets the PAM RHOST value on systems + that support it (STR #2637) + - The scheduler now sandboxes child processes when + possible. + - The Cancel-Job operation now supports a purge-job + attriibute to purge a specified job. + - ppdEmit* and ppdCollect* now use the NonUIOrderDependency + attributes for custom option selections. + - The web interface now enables/disables the printer + sharing (formerly publishing) controls based on the + server-is-sharing-printers state (STR #2233) + - The scheduler now tracks printer sharing via the + server-is-sharing-printers attribute, and manages LPD + and SMB sharing as well (STR #2233) + - The web interface now allows you to go back to the make/ + manufacturer page if there is no matching printer driver + on the model page (STR #2436) + - The printer list now shows the default media, banner, and + duplex options as well as the color and duplex capabilities + of printers (STR #1175) + - The web interface look-n-feel has been updated (STR #2492) + - The scheduler now supports a CUPS-Get-Document operation + that returns the specified print job document (STR #118) + - The cupsfilter utility now supports a "-J jobid" option + to filter the document from the specified job. + - The scheduler (cupsd) now supports a new option (-t) to + do a syntax check of the cupsd.conf file (STR #2003) + - Added new cupsGetPPD3() API to allow applications to + cache PPDs safely (STR #1473) + - Added generic PostScript and PCL printer driver PPDs. diff --git a/CREDITS.txt b/CREDITS.txt new file mode 100644 index 0000000000..a241eef4db --- /dev/null +++ b/CREDITS.txt @@ -0,0 +1,49 @@ +CREDITS.txt - 2010-03-13 +------------------------ + +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(). + Philippe Combes - French localization and buttons script. + Jean-Eric Cuendet - GhostScript filters for CUPS. + Van Dang - HTTP and IPP policeman. + L. Peter Deutsch - MD5 code. + Dr. ZP Han - setgid()/setuid(). + Guy Harris - *BSD shared libraries and lots of other + fixes. + Bjoern Jacke - I18N stuff. + Wang Jian - CUPS RPM corrections. + Roderick Johnstone - Beta tester of the millenium. + Till Kamppeter - Bug fixes, beta testing, evangelism. + I–aki Larra–aga - Basque localization. + Kenshi Muto - Japanese localization, patches, and + testing. + Tomohiro Kato - Japanese localization. + Kiko - Bug fixes. + Sergey V. Kovalyov - ESP Print Pro and CUPS beta tester. + Marek Laane - Estonian translation. + Mark Lawrence - Microsoft interoperability testing. + Jeff Licquia - Bug fixes, beta testing, evangelism. + Jason McMullan - Original CUPS RPM distributions. + Wes Morgan - *BSD fixes. + Daniel Nylander - Swedish localization. + Niklas 'Nille' kerstršm - Swedish localization. + Giulio Orsero - Bug fixes and testing. + Michal Osowiecki - Polish localization. + Citra Paska - Indonesian localization. + Kurt Pfeifle - Bug fixes, beta testing, evangelism. + Vincenzo Reale - Italian localization. + Petter Reinholdtsen - HP-UX compiler stuff. + Juan Pablo Gonz‡lez Riopedre - Spanish localization. + Opher Shachar - Hebrew localization. + Stuart Stevens - HP JetDirect IPP information. + Andrea Suatoni - IRIX desktop integration and testing. + Teppo Turliainen - Finnish localization. + Tim Waugh - Lots of patches, testing, and Linux + integration. + Yugami - LDAP browsing support. + +If I've missed someone, please let me know by sending an email to +"msweet@apple.com". diff --git a/INSTALL.txt b/INSTALL.txt new file mode 100644 index 0000000000..fbec65e96c --- /dev/null +++ b/INSTALL.txt @@ -0,0 +1,207 @@ +INSTALL - CUPS v1.4.7 - 2011-01-06 +---------------------------------- + +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 AND ARE NOT RUNNING MAC OS X, **** +**** YOU WILL ALSO NEED TO INSTALL GPL GHOSTSCRIPT WITH THE "cups" DRIVER **** +**** AFTER YOU INSTALL CUPS. **** + + +BEFORE YOU BEGIN + + You'll need ANSI-compliant C and C++ compilers, plus a make program and + POSIX-compliant shell (/bin/sh). The GNU compiler tools and Bash work well + and we have tested the current CUPS code against several versions of GCC + with excellent results. + + The makefiles used by the project should work with most versions of make. + We've tested them with GNU make as well as the make programs shipped by + Compaq, HP, SGI, and Sun. BSD users should use GNU make (gmake) since BSD + make does not support "include". + + Besides these tools you'll want the JPEG, PNG, TIFF, and ZLIB libraries for + image support, the CDSA, GNU TLS, or OpenSSL libraries for encryption + support, the OpenLDAP and OpenSLP libraries for directory services support, + and either MIT (1.6.3 or higher) or Heimdal Kerberos for Kerberos support. + 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 does not include the Ghostscript-based + PostScript filter needed by non-PostScript printers. You *must* download + GPL Ghostscript separately from the CUPS web site if you want to print + PostScript files to non-PostScript printers on operating systems other than + Mac OS X. + + +COMPILING THE SUBVERSION REPOSITORY CODE + + The CUPS Subversion repository doesn't hold a copy of the pre-built + configure script. You'll need to run the GNU autoconf software (2.60 or + higher) to create it: + + autoconf + + +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 + + 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 + + To see a complete list of configuration options, use the --help option: + + ./configure --help + + If any of the dependent libraries are not installed in a system default + location (typically "/usr/include" and "/usr/lib") you'll need to set the + CFLAGS, CPPFLAGS, CXXFLAGS, DSOFLAGS, and LDFLAGS environment variables + prior to running configure: + + setenv CFLAGS "-I/some/directory" + setenv CPPFLAGS "-I/some/directory" + setenv CXXFLAGS "-I/some/directory" + setenv DSOFLAGS "-L/some/directory" + setenv LDFLAGS "-L/some/directory" + ./configure ... + + or: + + CFLAGS="-I/some/directory" \ + CPPFLAGS="-I/some/directory" \ + CXXFLAGS="-I/some/directory" \ + DSOFLAGS="-L/some/directory" \ + LDFLAGS="-L/some/directory" \ + ./configure ... + + The "--enable-debug" option compiles CUPS with debugging information + enabled. Additional debug logging support can be enabled using the + "--enable-debug-printfs" option - these debug messages are enabled using the + CUPS_DEBUG_LOG environment variable at run-time. + + CUPS also includes an extensive set of unit tests that can be used to find + and diagnose a variety of common problems - use the "--enable-unit-tests" + configure option to run them at build time. + + Once you have configured things, just type: + + make ENTER + + or if you have FreeBSD, NetBSD, or OpenBSD type: + + gmake ENTER + + to build the software. + + +TESTING THE SOFTWARE + + Aside from the built-in unit tests, CUPS includes an automated test + framework for testing the entire printing system. To run the tests, just + type: + + make check ENTER + + or if you have FreeBSD, NetBSD, or OpenBSD type: + + gmake check ENTER + + The test framework runs a copy of the CUPS scheduler (cupsd) on port 8631 + in /tmp/cups-$USER and produces a nice HTML report of the results. + + +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 ("packaging/cups.spec") or EPM list file + ("packaging/cups.list"). The latter also supports building of binary RPMs, + so it may be more convenient to use. + + You can find the RPM software at: + + http://www.rpm.org/ + + The EPM software is available at: + + http://www.epmhome.org/ + + +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 ENTER + + or + + gmake ENTER + + for FreeBSD, NetBSD, and OpenBSD. The target is one of the + following: + + epm - Builds a script + tarfile package + aix - Builds an AIX package + bsd - Builds a *BSD package + deb - Builds a Debian package + depot - Builds a HP-UX package (also swinstall) + inst - Builds an IRIX package (also tardist) + osx - Builds a MacOS X package + pkg - Builds a Solaris package + rpm - Builds a RPM package + setld - Build a Tru64 UNIX package + slackware - Build a Slackware package + swinstall - Build a HP-UX package (also depot) + tardist - Builds an IRIX package (also inst) + + +GETTING DEBUG LOGGING FROM CUPS + + When configured with the "--enable-debug-printfs" option, CUPS compiles in + additional debug logging support in the scheduler, CUPS API, and CUPS + Imaging API. The following environment variables are used to enable and + control debug logging: + + CUPS_DEBUG_FILTER Specifies a POSIX regular expression to control + which messages are logged. + CUPS_DEBUG_LEVEL Specifies a number from 0 to 9 to control the + verbosity of the logging. The default level is 1. + CUPS_DEBUG_LOG Specifies a log file to use. Specify the name "-" + to send the messages to stderr. Prefix a filename + with "+" to append to an existing file. + + +REPORTING PROBLEMS + + If you have problems, READ THE DOCUMENTATION FIRST! If the documentation + does not solve your problems, please post a message on the "cups.general" + forum at: + + http://www.cups.org/newsgroups.php + + Include your operating system and version, compiler and version, and any + errors or problems you've run into. The "config.log" file and the output + from the configure script and make 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. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000000..fdad62bc85 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,973 @@ + CUPS License Agreement + + Copyright 2007-2009 by Apple Inc. + 1 Infinite Loop + Cupertino, CA 95014 USA + + WWW: http://www.cups.org/ + + +INTRODUCTION + +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 and CUPS Imaging libraries +located in the "cups" and "filter" subdirectories 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. + +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. + +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 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 and CUPS Imaging libraries +under other licenses and/or conditions as appropriate for your +application, driver, or filter. + + +LICENSE EXCEPTIONS + +In addition, as the copyright holder of CUPS, Apple Inc. 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. Apple Inc. 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. + + +KERBEROS SUPPORT CODE + +The Kerberos support code ("KSC") is copyright 2006 by Jelmer +Vernooij and is provided 'as-is', without any express or implied +warranty. In no event will the author or Apple Inc. be held +liable for any damages arising from the use of the KSC. + +Sources files containing KSC have the following text at the top +of each source file: + + This file contains Kerberos support code, copyright 2006 by + Jelmer Vernooij. + +The KSC copyright and license apply only to Kerberos-related +feature code in CUPS. Such code is typically conditionally +compiled based on the present of the HAVE_GSSAPI preprocessor +definition. + +Permission is granted to anyone to use the KSC for any purpose, +including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + + 1. The origin of the KSC must not be misrepresented; you + must not claim that you wrote the original software. If + you use the KSC 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. + + +TRADEMARKS + +CUPS and the CUPS logo (the "CUPS Marks") are trademarks of Apple +Inc. Apple grants you a non-exclusive and non-transferable right +to use the CUPS Marks in any direct port or binary distribution +incorporating CUPS software and in any promotional material +therefor. You agree that your products will meet the highest +levels of quality and integrity for similar goods, not be unlawful, +and be developed, manufactured, and distributed in compliance with +this license. You will not interfere with Apple's rights in the +CUPS Marks, and all use of the CUPS Marks shall inure to the +benefit of Apple. This license does not apply to use of the CUPS +Marks in a derivative products, which requires prior written +permission from Apple Inc. + + 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 + + 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. + + + Copyright (C) 19yy + + 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. + + , 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. + + 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 + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; 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. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Makedefs.in b/Makedefs.in new file mode 100644 index 0000000000..012ae0e55e --- /dev/null +++ b/Makedefs.in @@ -0,0 +1,293 @@ +# +# "$Id$" +# +# Common makefile definitions for CUPS. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Programs... +# + +AR = @AR@ +AWK = @AWK@ +CC = @LIBTOOL@ @CC@ +CHMOD = @CHMOD@ +CXX = @LIBTOOL@ @CXX@ +DSO = @DSO@ +DSOXX = @DSOXX@ +HTMLDOC = @HTMLDOC@ +INSTALL = @INSTALL@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN = @LN@ -sf +MV = @MV@ +PHPCONFIG = @PHPCONFIG@ +RANLIB = @RANLIB@ +RM = @RM@ -f +RMDIR = @RMDIR@ +SED = @SED@ +SHELL = /bin/sh + +# +# Installation programs... +# + +INSTALL_BIN = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@ +INSTALL_CONFIG = $(INSTALL) -c -m @CUPS_CONFIG_FILE_PERM@ +INSTALL_DATA = $(INSTALL) -c -m 444 +INSTALL_DIR = $(INSTALL) -d +INSTALL_LIB = $(LIBTOOL) $(INSTALL) -c -m 555 @INSTALL_STRIP@ +INSTALL_MAN = $(INSTALL) -c -m 444 +INSTALL_SCRIPT = $(INSTALL) -c -m 555 + +# +# Default user, group, and system groups for the scheduler... +# + +CUPS_USER = @CUPS_USER@ +CUPS_GROUP = @CUPS_GROUP@ +CUPS_SYSTEM_GROUPS = @CUPS_SYSTEM_GROUPS@ +CUPS_PRIMARY_SYSTEM_GROUP = @CUPS_PRIMARY_SYSTEM_GROUP@ + +# +# Default permissions... +# + +CUPS_CONFIG_FILE_PERM = @CUPS_CONFIG_FILE_PERM@ +CUPS_LOG_FILE_PERM = @CUPS_LOG_FILE_PERM@ + +# +# Languages to install... +# + +LANGUAGES = @LANGUAGES@ +INSTALL_LANGUAGES = @INSTALL_LANGUAGES@ +UNINSTALL_LANGUAGES = @UNINSTALL_LANGUAGES@ + +# +# Libraries... +# + +LIBCUPS = @LIBCUPS@ +LIBCUPSCGI = @LIBCUPSCGI@ +LIBCUPSDRIVER = @LIBCUPSDRIVER@ +LIBCUPSIMAGE = @LIBCUPSIMAGE@ +LIBCUPSMIME = @LIBCUPSMIME@ +LIBCUPSPPDC = @LIBCUPSPPDC@ +LIBJPEG = @LIBJPEG@ +LIBLDAP = @LIBLDAP@ +LIBMALLOC = @LIBMALLOC@ +LIBPAPER = @LIBPAPER@ +LIBPNG = @LIBPNG@ +LIBSLP = @LIBSLP@ +LIBGSSAPI = @LIBGSSAPI@ +LIBTIFF = @LIBTIFF@ +LIBUSB = @LIBUSB@ +LIBWRAP = @LIBWRAP@ +LIBZ = @LIBZ@ + +# +# Install static libraries? +# + +INSTALLSTATIC = @INSTALLSTATIC@ + +# +# Program options... +# +# ARCHFLAGS Defines the default architecture build options. +# ARCH32FLAGS Defines the 32-bit architecture build options, used +# when compiling separate 32/64-bit libraries. +# ARCH64FLAGS Defines the 64-bit architecture build options, used +# when compiling separate 32/64-bit libraries. +# OPTIM Defines the common compiler optimization/debugging options +# for all architectures. +# OPTIONS Defines other compile-time options (currently only -DDEBUG +# for extra debug info) +# + +ALL_CFLAGS = -I.. -D_CUPS_SOURCE $(CFLAGS) $(SSLFLAGS) \ + @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS) +ALL_CXXFLAGS = -I.. -D_CUPS_SOURCE $(CXXFLAGS) $(SSLFLAGS) \ + @LARGEFILE@ @PTHREAD_FLAGS@ $(OPTIONS) +ARCHFLAGS = @ARCHFLAGS@ +ARFLAGS = @ARFLAGS@ +BACKLIBS = @BACKLIBS@ +BANNERTOPS = @BANNERTOPS@ +CFLAGS = @CPPFLAGS@ @CFLAGS@ +COMMONLIBS = @LIBS@ +CUPSDLIBS = @CUPSDLIBS@ +CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ +CXXLIBS = @CXXLIBS@ +DBUS_NOTIFIER = @DBUS_NOTIFIER@ +DBUS_NOTIFIERLIBS = @DBUS_NOTIFIERLIBS@ +DNSSD_BACKEND = @DNSSD_BACKEND@ +DSOFLAGS = -L../cups @DSOFLAGS@ +DSOLIBS = @DSOLIBS@ $(COMMONLIBS) +DNSSDLIBS = @DNSSDLIBS@ +FONTS = @FONTS@ +IMGLIBS = @IMGLIBS@ +IMGFILTERS = @IMGFILTERS@ +LAUNCHDLIBS = @LAUNCHDLIBS@ +LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc \ + -L../scheduler @LDARCHFLAGS@ \ + @LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM) +LEGACY_BACKENDS = @LEGACY_BACKENDS@ +LIBCUPSORDER = @LIBCUPSORDER@ +LIBCUPSIMAGEORDER = @LIBCUPSIMAGEORDER@ +LINKCUPS = @LINKCUPS@ $(SSLLIBS) $(DNSSDLIBS) +LINKCUPSIMAGE = @LINKCUPSIMAGE@ +LIBS = $(LINKCUPS) $(COMMONLIBS) +OPTIM = @OPTIM@ +OPTIONS = +PAMLIBS = @PAMLIBS@ +PAP = @PAP@ +PDFTOPS = @PDFTOPS@ +PHPDIR = @PHPDIR@ +PHPOPTIONS = @PHPOPTIONS@ -I../.. `$(PHPCONFIG) --includes` +SSLFLAGS = @SSLFLAGS@ +SSLLIBS = @SSLLIBS@ +TEXTTOPS = @TEXTTOPS@ +UNITTESTS = @UNITTESTS@ + + +# +# Separate 32/64-bit library support... +# + +ARCH32FLAGS = @ARCH32FLAGS@ +DSO32FLAGS = @DSO32FLAGS@ +INSTALL32 = @INSTALL32@ +LIB32CUPS = @LIB32CUPS@ +LIB32CUPSIMAGE = @LIB32CUPSIMAGE@ +LIB32DIR = $(BUILDROOT)@LIB32DIR@ +UNINSTALL32 = @UNINSTALL32@ + +ARCH64FLAGS = @ARCH64FLAGS@ +DSO64FLAGS = @DSO64FLAGS@ +INSTALL64 = @INSTALL64@ +LIB64CUPS = @LIB64CUPS@ +LIB64CUPSIMAGE = @LIB64CUPSIMAGE@ +LIB64DIR = $(BUILDROOT)@LIB64DIR@ +UNINSTALL64 = @UNINSTALL64@ + +# +# 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... +# +# The "datarootdir" variable may not get defined if you are using +# a version of autoconf prior to 2.60. +# +# This is immediately followed by definition in ALL CAPS for the +# needed directories... +# + +bindir = @bindir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +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@ +CACHEDIR = $(BUILDROOT)@CUPS_CACHEDIR@ +DATADIR = $(BUILDROOT)@CUPS_DATADIR@ +DOCDIR = $(BUILDROOT)@CUPS_DOCROOT@ +ICONDIR = @ICONDIR@ +INCLUDEDIR = $(BUILDROOT)$(includedir) +INITDIR = @INITDIR@ +INITDDIR = @INITDDIR@ +LIBDIR = $(BUILDROOT)$(libdir) +LOCALEDIR = $(BUILDROOT)@CUPS_LOCALEDIR@ +LOGDIR = $(BUILDROOT)@CUPS_LOGDIR@ +MANDIR = $(BUILDROOT)@mandir@ +MENUDIR = @MENUDIR@ +PMANDIR = $(BUILDROOT)@PMANDIR@ +RCLEVELS = @RCLEVELS@ +RCSTART = @RCSTART@ +RCSTOP = @RCSTOP@ +REQUESTS = $(BUILDROOT)@CUPS_REQUESTS@ +SBINDIR = $(BUILDROOT)@sbindir@ +SERVERBIN = $(BUILDROOT)@CUPS_SERVERBIN@ +SERVERROOT = $(BUILDROOT)@CUPS_SERVERROOT@ +SMFMANIFESTDIR = @SMFMANIFESTDIR@ +STATEDIR = $(BUILDROOT)@CUPS_STATEDIR@ +XINETD = @XINETD@ + +MAN1EXT = @MAN1EXT@ +MAN5EXT = @MAN5EXT@ +MAN7EXT = @MAN7EXT@ +MAN8EXT = @MAN8EXT@ +MAN8DIR = @MAN8DIR@ + +PAMDIR = @PAMDIR@ +PAMFILE = @PAMFILE@ + +DEFAULT_LAUNCHD_CONF = @DEFAULT_LAUNCHD_CONF@ +DBUSDIR = @DBUSDIR@ + + +# +# Rules... +# + +.SILENT: +.SUFFIXES: .1 .1.gz .1m .1m.gz .3 .3.gz .5 .5.gz .7 .7.gz .8 .8.gz .a .c .cxx .h .man .o .32.o .64.o .gz + +.c.o: + echo Compiling $<... + $(CC) $(ARCHFLAGS) $(OPTIM) $(ALL_CFLAGS) -c -o $@ $< + +.c.32.o: + echo Compiling 32-bit $<... + $(CC) $(ARCH32FLAGS) $(OPTIM) $(ALL_CFLAGS) -c -o $@ $< + +.c.64.o: + echo Compiling 64-bit $<... + $(CC) $(ARCH64FLAGS) $(OPTIM) $(ALL_CFLAGS) -c -o $@ $< + +.cxx.o: + echo Compiling $<... + $(CXX) $(ARCHFLAGS) $(OPTIM) $(ALL_CXXFLAGS) -c -o $@ $< + +.man.1 .man.1m .man.3 .man.5 .man.7 .man.8: + echo Linking $<... + $(RM) $@ + $(LN) $< $@ + +.man.1.gz .man.1m.gz .man.3.gz .man.5.gz .man.7.gz .man.8.gz .man.gz: + echo -n Compressing $<... + $(RM) $@ + gzip -v9 <$< >$@ + + +# +# End of "$Id$" +# diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..2d71ec8a82 --- /dev/null +++ b/Makefile @@ -0,0 +1,437 @@ +# +# "$Id$" +# +# Top-level Makefile for CUPS. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include Makedefs + + +# +# Directories to make... +# + +DIRS = cups filter backend berkeley cgi-bin driver locale man monitor \ + notifier ppdc scheduler systemv test \ + $(PHPDIR) \ + conf data doc examples $(FONTS) templates + + +# +# Make all targets... +# + +all: + chmod +x cups-config + echo Using ARCHFLAGS="$(ARCHFLAGS)" + echo Using ALL_CFLAGS="$(ALL_CFLAGS)" + echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)" + echo Using CC="$(CC)" + echo Using CXX="$(CC)" + echo Using DSOFLAGS="$(DSOFLAGS)" + echo Using LDFLAGS="$(LDFLAGS)" + echo Using LIBS="$(LIBS)" + for dir in $(DIRS); do\ + echo Making all in $$dir... ;\ + (cd $$dir ; $(MAKE) $(MFLAGS) all $(UNITTESTS)) || exit 1;\ + done + + +# +# Make library targets... +# + +libs: + echo Using ARCHFLAGS="$(ARCHFLAGS)" + echo Using ALL_CFLAGS="$(ALL_CFLAGS)" + echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)" + echo Using CC="$(CC)" + echo Using CXX="$(CC)" + echo Using DSOFLAGS="$(DSOFLAGS)" + echo Using LDFLAGS="$(LDFLAGS)" + echo Using LIBS="$(LIBS)" + for dir in $(DIRS); do\ + echo Making libraries in $$dir... ;\ + (cd $$dir ; $(MAKE) $(MFLAGS) libs) || exit 1;\ + done + + +# +# Make unit test targets... +# + +unittests: + echo Using ARCHFLAGS="$(ARCHFLAGS)" + echo Using ALL_CFLAGS="$(ALL_CFLAGS)" + echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)" + echo Using CC="$(CC)" + echo Using CXX="$(CC)" + echo Using DSOFLAGS="$(DSOFLAGS)" + echo Using LDFLAGS="$(LDFLAGS)" + echo Using LIBS="$(LIBS)" + for dir in $(DIRS); do\ + echo Making all in $$dir... ;\ + (cd $$dir ; $(MAKE) $(MFLAGS) unittests) || 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 + + +# +# Remove all non-distribution files... +# + +distclean: clean + $(RM) Makedefs config.h config.log config.status + $(RM) cups-config + $(RM) conf/cupsd.conf conf/mime.convs conf/pam.std conf/snmp.conf + $(RM) doc/help/ref-cupsd-conf.html doc/help/standard.html doc/index.html + $(RM) init/cups.sh init/cups-lpd init/org.cups.cups-lpd.plist + $(RM) man/client.conf.man + $(RM) man/cups-deviced.man man/cups-driverd.man + $(RM) man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man + $(RM) man/cupsd.conf.man man/drv.man man/lpoptions.man + $(RM) packaging/cups.list + $(RM) packaging/cups-desc.plist packaging/cups-info.plist + $(RM) templates/header.tmpl + $(RM) desktop/cups.desktop + $(RM) init/cups.xml + -$(RM) doc/*/index.html + -$(RM) templates/*/header.tmpl + -$(RM) -r autom4te*.cache clang cups/charmaps cups/locale driver/test + + +# +# Make dependencies +# + +depend: + for dir in $(DIRS); do\ + echo Making dependencies in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) depend) || exit 1;\ + done + + +# +# Run the clang.llvm.org static code analysis tool on the C sources. +# (at least checker-231 is required for scan-build to work this way) +# + +.PHONY: clang clang-changes +clang: + $(RM) -r clang + scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) clean all +clang-changes: + scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) all + + +# +# Generate a ctags file... +# + +ctags: + ctags -R . + + +# +# Install everything... +# + +install: install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + for dir in $(DIRS); do\ + echo Installing data files in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) install-data) || exit 1;\ + done + echo Installing cups-config script... + $(INSTALL_DIR) -m 755 $(BINDIR) + $(INSTALL_SCRIPT) cups-config $(BINDIR)/cups-config + if test "x$(INITDIR)" != x; then \ + echo Installing init scripts...; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/init.d; \ + $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDIR)/init.d/cups; \ + for level in $(RCLEVELS); do \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc$${level}.d; \ + $(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc$${level}.d/S$(RCSTART)cups; \ + if test `uname` = HP-UX; then \ + level=`expr $$level - 1`; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc$${level}.d; \ + fi; \ + $(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc$${level}.d/K$(RCSTOP)cups; \ + done; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(INITDIR)/rc0.d; \ + $(LN) ../init.d/cups $(BUILDROOT)$(INITDIR)/rc0.d/K$(RCSTOP)cups; \ + fi + if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \ + $(INSTALL_DIR) $(BUILDROOT)$(INITDDIR); \ + if test "$(INITDDIR)" = "/System/Library/LaunchDaemons"; then \ + echo Installing LaunchDaemons configuration files...; \ + $(INSTALL_DATA) init/org.cups.cupsd.plist $(BUILDROOT)$(DEFAULT_LAUNCHD_CONF); \ + $(INSTALL_DATA) init/org.cups.cups-lpd.plist $(BUILDROOT)/System/Library/LaunchDaemons; \ + case `uname -r` in \ + 8.*) \ + $(INSTALL_DIR) $(BUILDROOT)/System/Library/StartupItems/PrintingServices; \ + $(INSTALL_SCRIPT) init/PrintingServices.launchd $(BUILDROOT)/System/Library/StartupItems/PrintingServices/PrintingServices; \ + $(INSTALL_DATA) init/StartupParameters.plist $(BUILDROOT)/System/Library/StartupItems/PrintingServices/StartupParameters.plist; \ + $(INSTALL_DIR) $(BUILDROOT)/System/Library/StartupItems/PrintingServices/Resources/English.lproj; \ + $(INSTALL_DATA) init/Localizable.strings $(BUILDROOT)/System/Library/StartupItems/PrintingServices/Resources/English.lproj/Localizable.strings; \ + ;; \ + esac \ + else \ + echo Installing RC script...; \ + $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDDIR)/cups; \ + fi \ + fi + if test "x$(SMFMANIFESTDIR)" != x; then \ + echo Installing SMF manifest in $(SMFMANIFESTDIR)...;\ + $(INSTALL_DIR) $(BUILDROOT)/$(SMFMANIFESTDIR); \ + $(INSTALL_SCRIPT) init/cups.xml $(BUILDROOT)$(SMFMANIFESTDIR)/cups.xml; \ + fi + if test "x$(DBUSDIR)" != x; then \ + echo Installing cups.conf in $(DBUSDIR)...;\ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(DBUSDIR)/system.d; \ + $(INSTALL_DATA) packaging/cups-dbus.conf $(BUILDROOT)$(DBUSDIR)/system.d/cups.conf; \ + fi + if test "x$(XINETD)" != x; then \ + echo Installing xinetd configuration file for cups-lpd...; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(XINETD); \ + $(INSTALL_DATA) init/cups-lpd $(BUILDROOT)$(XINETD)/cups-lpd; \ + fi + if test "x$(MENUDIR)" != x; then \ + echo Installing desktop menu...; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(MENUDIR); \ + $(INSTALL_DATA) desktop/cups.desktop $(BUILDROOT)$(MENUDIR); \ + fi + if test "x$(ICONDIR)" != x; then \ + echo Installing desktop icons...; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/16x16/apps; \ + $(INSTALL_DATA) desktop/cups-16.png $(BUILDROOT)$(ICONDIR)/hicolor/16x16/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/32x32/apps; \ + $(INSTALL_DATA) desktop/cups-32.png $(BUILDROOT)$(ICONDIR)/hicolor/32x32/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/64x64/apps; \ + $(INSTALL_DATA) desktop/cups-64.png $(BUILDROOT)$(ICONDIR)/hicolor/64x64/apps/cups.png; \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(ICONDIR)/hicolor/128x128/apps; \ + $(INSTALL_DATA) desktop/cups-128.png $(BUILDROOT)$(ICONDIR)/hicolor/128x128/apps/cups.png; \ + fi + +# +# Install header files... +# + +install-headers: + for dir in $(DIRS); do\ + echo Installing header files in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) install-headers) || exit 1;\ + done + + +# +# Install programs... +# + +install-exec: all + for dir in $(DIRS); do\ + echo Installing programs in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) install-exec) || exit 1;\ + done + + +# +# Install libraries... +# + +install-libs: libs + for dir in $(DIRS); do\ + echo Installing libraries in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) install-libs) || exit 1;\ + done + + +# +# Uninstall object and target files... +# + +uninstall: + for dir in $(DIRS); do\ + echo Uninstalling in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) uninstall) || exit 1;\ + done + echo Uninstalling cups-config script... + $(RM) $(BINDIR)/cups-config + -$(RMDIR) $(BINDIR) + echo Uninstalling startup script... + if test "x$(INITDIR)" != x; then \ + $(RM) $(BUILDROOT)$(INITDIR)/init.d/cups; \ + $(RMDIR) $(BUILDROOT)$(INITDIR)/init.d; \ + $(RM) $(BUILDROOT)$(INITDIR)/rc0.d/K00cups; \ + $(RMDIR) $(BUILDROOT)$(INITDIR)/rc0.d; \ + $(RM) $(BUILDROOT)$(INITDIR)/rc2.d/S99cups; \ + $(RMDIR) $(BUILDROOT)$(INITDIR)/rc2.d; \ + $(RM) $(BUILDROOT)$(INITDIR)/rc3.d/S99cups; \ + $(RMDIR) $(BUILDROOT)$(INITDIR)/rc3.d; \ + $(RM) $(BUILDROOT)$(INITDIR)/rc5.d/S99cups; \ + $(RMDIR) $(BUILDROOT)$(INITDIR)/rc5.d; \ + fi + if test "x$(INITDIR)" = x -a "x$(INITDDIR)" != x; then \ + if test "$(INITDDIR)" = "/System/Library/StartupItems/PrintingServices"; then \ + $(RM) $(BUILDROOT)$(INITDDIR)/PrintingServices; \ + $(RM) $(BUILDROOT)$(INITDDIR)/StartupParameters.plist; \ + $(RM) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj/Localizable.strings; \ + $(RMDIR) $(BUILDROOT)$(INITDDIR)/Resources/English.lproj; \ + elif test "$(INITDDIR)" = "/System/Library/LaunchDaemons"; then \ + $(RM) $(BUILDROOT)$(INITDDIR)/org.cups.cupsd.plist; \ + $(RM) $(BUILDROOT)$(INITDDIR)/org.cups.cups-lpd.plist; \ + $(RMDIR) $(BUILDROOT)/System/Library/StartupItems/PrintingServices; \ + else \ + $(INSTALL_SCRIPT) init/cups.sh $(BUILDROOT)$(INITDDIR)/cups; \ + fi \ + $(RMDIR) $(BUILDROOT)$(INITDDIR); \ + fi + if test "x$(SMFMANIFESTDIR)" != x; then \ + echo Uninstalling SMF manifest in $(SMFMANIFESTDIR)...;\ + $(RM) $(BUILDROOT)$(SMFMANIFESTDIR)/cups.xml; \ + fi + if test "x$(DBUSDIR)" != x; then \ + echo Uninstalling cups.conf in $(DBUSDIR)...;\ + $(RM) $(BUILDROOT)$(DBUSDIR)/cups.conf; \ + $(RMDIR) $(BUILDROOT)$(DBUSDIR); \ + fi + if test "x$(XINETD)" != x; then \ + echo Uninstalling xinetd configuration file for cups-lpd...; \ + $(RM) $(BUILDROOT)$(XINETD)/cups-lpd; \ + fi + if test "x$(MENUDIR)" != x; then \ + echo Uninstalling desktop menu...; \ + $(RM) $(BUILDROOT)$(MENUDIR)/cups.desktop; \ + fi + if test "x$(ICONDIR)" != x; then \ + echo Uninstalling desktop icons...; \ + $(RM) $(BUILDROOT)$(ICONDIR)/hicolor/16x16/apps/cups.png; \ + $(RM) $(BUILDROOT)$(ICONDIR)/hicolor/32x32/apps/cups.png; \ + $(RM) $(BUILDROOT)$(ICONDIR)/hicolor/64x64/apps/cups.png; \ + $(RM) $(BUILDROOT)$(ICONDIR)/hicolor/128x128/apps/cups.png; \ + fi + + +# +# Run the test suite... +# + +test: all unittests + echo Running CUPS test suite... + cd test; ./run-stp-tests.sh + + +check: all unittests + echo Running CUPS test suite with defaults... + cd test; ./run-stp-tests.sh 1 0 n + + +# +# Create HTML documentation... +# + +apihelp: + for dir in cgi-bin cups filter driver ppdc scheduler; do\ + echo Generating API help in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) apihelp) || exit 1;\ + done + +framedhelp: + for dir in cgi-bin cups filter driver ppdc scheduler; do\ + echo Generating framed API help in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) framedhelp) || exit 1;\ + done + + +# +# Create an Xcode docset... +# + +docset: apihelp + echo Generating docset directory tree... + $(RM) -r org.cups.docset + mkdir -p org.cups.docset/Contents/Resources/Documentation/help + mkdir -p org.cups.docset/Contents/Resources/Documentation/images + cd man; $(MAKE) $(MFLAGS) html + cd doc; $(MAKE) $(MFLAGS) docset + cd cgi-bin; $(MAKE) $(MFLAGS) makedocset + cgi-bin/makedocset org.cups.docset \ + `svnversion . | sed -e '1,$$s/[a-zA-Z]//g'` \ + doc/help/api-*.tokens + $(RM) doc/help/api-*.tokens + echo Indexing docset... + /Developer/usr/bin/docsetutil index org.cups.docset + echo Generating docset archive and feed... + $(RM) org.cups.docset.atom + /Developer/usr/bin/docsetutil package --output org.cups.docset.xar \ + --atom org.cups.docset.atom \ + --download-url http://www.cups.org/org.cups.docset.xar \ + org.cups.docset + + +# +# Make software distributions using EPM (http://www.epmhome.org/)... +# + +EPMFLAGS = -v --output-dir dist $(EPMARCH) + +aix bsd deb depot inst pkg setld slackware swinstall tardist: + epm $(EPMFLAGS) -f $@ cups packaging/cups.list + +epm: + epm $(EPMFLAGS) -s packaging/installer.gif cups packaging/cups.list + +osx: + epm $(EPMFLAGS) -f osx -s packaging/installer.tif cups packaging/cups.list + +rpm: + epm $(EPMFLAGS) -f rpm -s packaging/installer.gif cups packaging/cups.list + +.PHONEY: dist +dist: all + $(RM) -r dist + $(MAKE) $(MFLAGS) epm + case `uname` in \ + *BSD*) $(MAKE) $(MFLAGS) bsd;; \ + Darwin*) $(MAKE) $(MFLAGS) osx;; \ + IRIX*) $(MAKE) $(MFLAGS) tardist;; \ + Linux*) test ! -x /usr/bin/rpm || $(MAKE) $(MFLAGS) rpm;; \ + SunOS*) $(MAKE) $(MFLAGS) pkg;; \ + esac + + +# +# Don't run top-level build targets in parallel... +# + +.NOTPARALLEL: + + +# +# End of "$Id$". +# diff --git a/README.txt b/README.txt new file mode 100644 index 0000000000..ab9ebdcc91 --- /dev/null +++ b/README.txt @@ -0,0 +1,164 @@ +README - CUPS v1.4.7 - 2011-01-06 +--------------------------------- + +Looking for compile instructions? Read the file "INSTALL.txt" +instead... + + +INTRODUCTION + + CUPS is a standards-based, open source printing system developed by Apple + Inc. for Mac OS® X and other UNIX®-like operating systems. CUPS uses the + Internet Printing Protocol ("IPP") and provides System V and Berkeley + command-line interfaces, a web interface, and a C API to manage printers and + print jobs. It supports printing to both local (parallel, serial, USB) and + networked printers, and printers can be shared from one computer to another, + even over the Internet! + + Internally, CUPS uses PostScript Printer Description ("PPD") files to + describe printer capabilities and features and a wide variety of generic + and device-specific programs to convert and print many types of files. + Sample drivers are included with CUPS to support many Dymo, EPSON, HP, + Intellitech, OKIDATA, and Zebra printers. Many more drivers are available + online and (in some cases) on the driver CD-ROM that came with your printer. + + CUPS is licensed under the GNU General Public License and GNU Library + General Public License versions 2. See the file "LICENSE.txt" for more + information. + + +READING THE DOCUMENTATION + + Once you have installed the software you can access the documentation (and + a bunch of other stuff) online at: + + http://localhost:631/ + + If you're having trouble getting that far, the documentation is located + under the "doc/help" directory. + + Please read the documentation before asking questions. + + +GETTING SUPPORT AND OTHER RESOURCES + + If you have problems, READ THE DOCUMENTATION FIRST! We also provide many + discussion forums which are available at: + + http://www.cups.org/newsgroups.php + + See the CUPS web site at "http://www.cups.org/" for other resources. + + +SETTING UP PRINTER QUEUES USING YOUR WEB BROWSER + + CUPS includes a web-based administration tool that allows you to manage + printers, classes, and jobs on your server. Open the following URL in your + browser to access the printer administration tools: + + http://localhost:631/admin/ + + DO NOT use the hostname for your machine - it will not work with the default + CUPS configuration. To enable administration access on other addresses, + check the "Allow Remote Administration" box and click on the "Change + Settings" button. + + You will be asked for the administration password (root or any other user in + the sys/system/root/admin/lpadmin group on your system) when performing any + administrative function. + + +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. + + CUPS includes several sample PPD files you can use: + + Driver PPD Name + ----------------------------- ------------------------------ + Dymo Label Printers drv:///sample.drv/dymo.ppd + Intellitech Intellibar drv:///sample.drv/intelbar.ppd + EPSON Stylus Color Series drv:///sample.drv/stcolor.ppd + EPSON Stylus Photo Series drv:///sample.drv/stphoto.ppd + EPSON Stylus New Color Series drv:///sample.drv/stcolor2.ppd + EPSON Stylus New Photo Series drv:///sample.drv/stphoto2.ppd + EPSON 9-pin Series drv:///sample.drv/epson9.ppd + EPSON 24-pin Series drv:///sample.drv/epson24.ppd + Generic PCL Laser Printer drv:///sample.drv/generpcl.ppd + Generic PostScript Printer drv:///sample.drv/generic.ppd + HP DeskJet Series drv:///sample.drv/deskjet.ppd + HP LaserJet Series drv:///sample.drv/laserjet.ppd + OKIDATA 9-Pin Series drv:///sample.drv/okidata9.ppd + OKIDATA 24-Pin Series drv:///sample.drv/okidat24.ppd + Zebra CPCL Label Printer drv:///sample.drv/zebracpl.ppd + Zebra EPL1 Label Printer drv:///sample.drv/zebraep1.ppd + Zebra EPL2 Label Printer drv:///sample.drv/zebraep2.ppd + Zebra ZPL Label Printer drv:///sample.drv/zebra.ppd + + Run the "lpinfo -m" command to list the available drivers: + + lpinfo -m + + Run the "lpinfo -v" command to list the available printers: + + lpinfo -v + + Then use the correct URI to add the printer using the "lpadmin" command: + + lpadmin -p printername -E -v device-uri -m ppd-name + + Network printers typically use "socket" or "lpd" URIs: + + lpadmin -p printername -E -v socket://11.22.33.44 -m ppd-name + lpadmin -p printername -E -v lpd://11.22.33.44/ -m ppd-name + + The sample drivers provide basic printing capabilities, but generally do not + exercise the full potential of the printers or CUPS. The CUPS web site + provides links and drivers: + + http://www.cups.org/ppd.php PPD files + http://www.cups.org/links.php Links to other drivers + + +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 -o media=A4 -o resolution=600dpi filename + lpr -o media=A4 -o resolution=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 -o raw filename + lpr -l filename + + This will prevent the filters from misinterpreting your print + file. + + +LEGAL STUFF + + CUPS is Copyright 2007-2011 by Apple Inc. CUPS and the CUPS logo are + trademarks of Apple Inc. + + The MD5 Digest code is Copyright 1999 Aladdin Enterprises. + + This software is based in part on the work of the Independent JPEG Group. + + CUPS is provided under the terms of version 2 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 "doc/help/license.html" or "LICENSE.txt" files for more information. diff --git a/backend/Dependencies b/backend/Dependencies new file mode 100644 index 0000000000..9051be05c3 --- /dev/null +++ b/backend/Dependencies @@ -0,0 +1,76 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +ipp.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/versioning.h +ipp.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h backend-private.h +ipp.o: ../cups/backend.h ../cups/sidechannel.h ../cups/ppd-private.h +ipp.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ipp.o: ../cups/language.h ../cups/debug.h ../cups/i18n.h ../cups/transcode.h +ipp.o: ../cups/snmp-private.h ../cups/string.h +lpd.o: ../cups/http-private.h ../config.h ../cups/http.h ../cups/versioning.h +lpd.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h backend-private.h +lpd.o: ../cups/backend.h ../cups/sidechannel.h ../cups/ppd-private.h +lpd.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +lpd.o: ../cups/language.h ../cups/debug.h ../cups/i18n.h ../cups/transcode.h +lpd.o: ../cups/snmp-private.h ../cups/string.h +dnssd.o: backend-private.h ../cups/backend.h ../cups/versioning.h +dnssd.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +dnssd.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +dnssd.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/i18n.h +dnssd.o: ../cups/transcode.h ../cups/snmp-private.h ../cups/string.h +dnssd.o: ../config.h ../cups/array.h +pap.o: ../config.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pap.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pap.o: ../cups/language.h ../cups/backend.h ../cups/sidechannel.h +pap.o: ../cups/i18n.h ../cups/transcode.h +parallel.o: backend-private.h ../cups/backend.h ../cups/versioning.h +parallel.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +parallel.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +parallel.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/i18n.h +parallel.o: ../cups/transcode.h ../cups/snmp-private.h ../cups/string.h +parallel.o: ../config.h +scsi.o: ../cups/backend.h ../cups/versioning.h ../cups/cups.h ../cups/ipp.h +scsi.o: ../cups/http.h ../cups/ppd.h ../cups/array.h ../cups/file.h +scsi.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +scsi.o: ../cups/string.h ../config.h +serial.o: backend-private.h ../cups/backend.h ../cups/versioning.h +serial.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +serial.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +serial.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/i18n.h +serial.o: ../cups/transcode.h ../cups/snmp-private.h ../cups/string.h +serial.o: ../config.h +snmp.o: backend-private.h ../cups/backend.h ../cups/versioning.h +snmp.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +snmp.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +snmp.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/i18n.h +snmp.o: ../cups/transcode.h ../cups/snmp-private.h ../cups/string.h +snmp.o: ../config.h ../cups/array.h ../cups/file.h ../cups/http-private.h +snmp.o: ../cups/md5.h ../cups/ipp-private.h +socket.o: ../cups/http-private.h ../config.h ../cups/http.h +socket.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +socket.o: ../cups/ipp.h backend-private.h ../cups/backend.h +socket.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +socket.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +socket.o: ../cups/debug.h ../cups/i18n.h ../cups/transcode.h +socket.o: ../cups/snmp-private.h ../cups/string.h +test1284.o: ../cups/string.h ../config.h ieee1284.c backend-private.h +test1284.o: ../cups/backend.h ../cups/versioning.h ../cups/sidechannel.h +test1284.o: ../cups/ppd-private.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +test1284.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +test1284.o: ../cups/debug.h ../cups/i18n.h ../cups/transcode.h +test1284.o: ../cups/snmp-private.h +testbackend.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +testbackend.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testbackend.o: ../cups/array.h ../cups/file.h ../cups/language.h +testbackend.o: ../cups/sidechannel.h +testsupplies.o: backend-private.h ../cups/backend.h ../cups/versioning.h +testsupplies.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +testsupplies.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +testsupplies.o: ../cups/file.h ../cups/language.h ../cups/debug.h +testsupplies.o: ../cups/i18n.h ../cups/transcode.h ../cups/snmp-private.h +testsupplies.o: ../cups/string.h ../config.h +usb.o: backend-private.h ../cups/backend.h ../cups/versioning.h +usb.o: ../cups/sidechannel.h ../cups/ppd-private.h ../cups/cups.h +usb.o: ../cups/ipp.h ../cups/http.h ../cups/ppd.h ../cups/array.h +usb.o: ../cups/file.h ../cups/language.h ../cups/debug.h ../cups/i18n.h +usb.o: ../cups/transcode.h ../cups/snmp-private.h ../cups/string.h +usb.o: ../config.h diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000000..aac8c1724b --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,282 @@ +# +# "$Id$" +# +# Backend makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +# This file is subject to the Apple OS-Developed Software exception. +# + +include ../Makedefs + +RBACKENDS = ipp lpd $(DNSSD_BACKEND) +UBACKENDS = $(PAP) $(LEGACY_BACKENDS) serial snmp socket usb +UNITTESTS = test1284 testbackend testsupplies +TARGETS = libbackend.a $(RBACKENDS) $(UBACKENDS) +LIBOBJS = ieee1284.o network.o runloop.o snmp-supplies.o +OBJS = ipp.o lpd.o dnssd.o pap.o parallel.o scsi.o serial.o snmp.o \ + socket.o test1284.o testbackend.o testsupplies.o usb.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: $(UNITTESTS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) $(UNITTESTS) $(LIBOBJS) http mdns + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + $(INSTALL_DIR) -m 755 $(SERVERBIN)/backend + for file in $(RBACKENDS); do \ + $(LIBTOOL) $(INSTALL_BIN) -m 700 $$file $(SERVERBIN)/backend; \ + done + for file in $(UBACKENDS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/backend; \ + done + $(RM) $(SERVERBIN)/backend/http + $(LN) ipp $(SERVERBIN)/backend/http + if test "x$(DNSSD_BACKEND)" != x; then \ + $(RM) $(SERVERBIN)/backend/mdns; \ + $(LN) $(DNSSD_BACKEND) $(SERVERBIN)/backend/mdns; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(TARGETS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall all targets... +# + +uninstall: + for file in $(RBACKENDS) $(UBACKENDS); do \ + $(RM) $(SERVERBIN)/backend/$$file; \ + done + $(RM) $(SERVERBIN)/backend/http + -$(RMDIR) $(SERVERBIN)/backend + -$(RMDIR) $(SERVERBIN) + + +# +# test1284 +# + +test1284: test1284.o ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o test1284 test1284.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# testbackend +# + +testbackend: testbackend.o ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o testbackend testbackend.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# testsupplies +# + +testsupplies: testsupplies.o libbackend.a ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o testsupplies testsupplies.o libbackend.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + + +# +# libbackend.a +# + +libbackend.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# dnssd +# + +dnssd: dnssd.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o dnssd dnssd.o libbackend.a $(LIBS) + $(RM) mdns + $(LN) dnssd mdns + + +# +# ipp +# + +ipp: ipp.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o ipp ipp.o libbackend.a $(LIBS) + $(RM) http + $(LN) ipp http + + +# +# lpd +# + +lpd: lpd.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o lpd lpd.o libbackend.a $(LIBS) + + +# +# pap +# + +pap: pap.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o pap pap.o $(BACKLIBS) $(LIBS) -framework AppleTalk + + +# +# parallel +# + +parallel: parallel.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o parallel parallel.o libbackend.a $(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) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o serial serial.o libbackend.a $(BACKLIBS) $(LIBS) + + +# +# snmp +# + +snmp: snmp.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o snmp snmp.o libbackend.a $(LIBS) + + +# +# socket +# + +socket: socket.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o socket socket.o libbackend.a $(LIBS) + + +# +# usb +# + +usb: usb.o ../cups/$(LIBCUPS) libbackend.a + echo Linking $@... + $(CC) $(LDFLAGS) -o usb usb.o libbackend.a $(LIBUSB) \ + $(BACKLIBS) $(LIBS) +usb.o: usb.c usb-darwin.c usb-libusb.c usb-unix.c + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/backend/backend-private.h b/backend/backend-private.h new file mode 100644 index 0000000000..38505f407d --- /dev/null +++ b/backend/backend-private.h @@ -0,0 +1,322 @@ +/* + * "$Id$" + * + * Backend support definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_BACKEND_PRIVATE_H_ +# define _CUPS_BACKEND_PRIVATE_H_ + + +/* + * Include necessary headers. + */ + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# ifdef __linux +# include +# include +# define IOCNR_GET_DEVICE_ID 1 +# define LPIOC_GET_DEVICE_ID(len) _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) +# include +# include +# include +# include +# endif /* __linux */ + +# ifdef __sun +# ifdef __sparc +# include +# else +# include +# include +# endif /* __sparc */ +# endif /* __sun */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * OID constants... + */ + +/* Host MIB */ +#define CUPS_OID_mib2 1,3,6,1,2,1 + +#define CUPS_OID_system CUPS_OID_mib2,1 +#define CUPS_OID_sysLocation CUPS_OID_system,6 + +#define CUPS_OID_host CUPS_OID_mib2,25 + +#define CUPS_OID_hrSystem CUPS_OID_host,1 + +#define CUPS_OID_hrStorage CUPS_OID_host,2 + +#define CUPS_OID_hrDevice CUPS_OID_host,3 +#define CUPS_OID_hrDeviceTable CUPS_OID_hrDevice,2 +#define CUPS_OID_hrDeviceEntry CUPS_OID_hrDeviceTable,1 +#define CUPS_OID_hrDeviceIndex CUPS_OID_hrDeviceEntry,1 +#define CUPS_OID_hrDeviceType CUPS_OID_hrDeviceEntry,2 +#define CUPS_OID_hrDeviceDescr CUPS_OID_hrDeviceEntry,3 + +#define CUPS_OID_hrPrinterTable CUPS_OID_hrDevice,5 +#define CUPS_OID_hrPrinterEntry CUPS_OID_hrPrinterTable,1 +#define CUPS_OID_hrPrinterStatus CUPS_OID_hrPrinterEntry,1 +#define CUPS_OID_hrPrinterDetectedErrorState CUPS_OID_hrPrinterEntry,2 + +/* Printer MIB */ +#define CUPS_OID_printmib CUPS_OID_mib2,43 + +#define CUPS_OID_prtGeneral CUPS_OID_printmib,5 +#define CUPS_OID_prtGeneralTable CUPS_OID_prtGeneral,1 +#define CUPS_OID_prtGeneralEntry CUPS_OID_prtGeneralTable,1 +#define CUPS_OID_prtGeneralCurrentLocalization CUPS_OID_prtGeneralEntry,2 +#define CUPS_OID_prtGeneralPrinterName CUPS_OID_prtGeneralEntry,16 +#define CUPS_OID_prtGeneralSerialNumber CUPS_OID_prtGeneralEntry,17 + +#define CUPS_OID_prtCover CUPS_OID_printmib,6 +#define CUPS_OID_prtCoverTable CUPS_OID_prtCover,1 +#define CUPS_OID_prtCoverEntry CUPS_OID_prtCoverTable,1 +#define CUPS_OID_prtCoverDescription CUPS_OID_prtCoverEntry,2 +#define CUPS_OID_prtCoverStatus CUPS_OID_prtCoverEntry,3 + +#define CUPS_OID_prtLocalization CUPS_OID_printmib,7 +#define CUPS_OID_prtLocalizationTable CUPS_OID_prtLocalization,1 +#define CUPS_OID_prtLocalizationEntry CUPS_OID_prtLocalizationTable,1 +#define CUPS_OID_prtLocalizationCharacterSet CUPS_OID_prtLocalizationEntry,4 + +#define CUPS_OID_prtMarker CUPS_OID_printmib,10 +#define CUPS_OID_prtMarkerTable CUPS_OID_prtMarker,2 +#define CUPS_OID_prtMarkerEntry CUPS_OID_prtMarkerTable,1 +#define CUPS_OID_prtMarkerLifeCount CUPS_OID_prtMarkerEntry,4 + +#define CUPS_OID_prtMarkerSupplies CUPS_OID_printmib,11 +#define CUPS_OID_prtMarkerSuppliesTable CUPS_OID_prtMarkerSupplies,1 +#define CUPS_OID_prtMarkerSuppliesEntry CUPS_OID_prtMarkerSuppliesTable,1 +#define CUPS_OID_prtMarkerSuppliesIndex CUPS_OID_prtMarkerSuppliesEntry,1 +#define CUPS_OID_prtMarkerSuppliesMarkerIndex CUPS_OID_prtMarkerSuppliesEntry,2 +#define CUPS_OID_prtMarkerSuppliesColorantIndex CUPS_OID_prtMarkerSuppliesEntry,3 +#define CUPS_OID_prtMarkerSuppliesClass CUPS_OID_prtMarkerSuppliesEntry,4 +#define CUPS_OID_prtMarkerSuppliesType CUPS_OID_prtMarkerSuppliesEntry,5 +#define CUPS_OID_prtMarkerSuppliesDescription CUPS_OID_prtMarkerSuppliesEntry,6 +#define CUPS_OID_prtMarkerSuppliesSupplyUnit CUPS_OID_prtMarkerSuppliesEntry,7 +#define CUPS_OID_prtMarkerSuppliesMaxCapacity CUPS_OID_prtMarkerSuppliesEntry,8 +#define CUPS_OID_prtMarkerSuppliesLevel CUPS_OID_prtMarkerSuppliesEntry,9 + +#define CUPS_OID_prtMarkerColorant CUPS_OID_printmib,12 +#define CUPS_OID_prtMarkerColorantTable CUPS_OID_prtMarkerColorant,1 +#define CUPS_OID_prtMarkerColorantEntry CUPS_OID_prtMarkerColorantTable,1 +#define CUPS_OID_prtMarkerColorantIndex CUPS_OID_prtMarkerColorantEntry,1 +#define CUPS_OID_prtMarkerColorantMarkerIndex CUPS_OID_prtMarkerColorantEntry,2 +#define CUPS_OID_prtMarkerColorantRole CUPS_OID_prtMarkerColorantEntry,3 +#define CUPS_OID_prtMarkerColorantValue CUPS_OID_prtMarkerColorantEntry,4 +#define CUPS_OID_prtMarkerColorantTonality CUPS_OID_prtMarkerColorantEntry,5 + +#define CUPS_OID_prtInterpreter CUPS_OID_printmib,15 +#define CUPS_OID_prtInterpreterTable CUPS_OID_prtInterpreter,1 +#define CUPS_OID_prtInterpreterEntry CUPS_OID_prtInterpreterTable,1 +#define CUPS_OID_prtInterpreterLangFamily CUPS_OID_prtInterpreterEntry,2 +#define CUPS_OID_prtInterpreterLangLevel CUPS_OID_prtInterpreterEntry,3 + +/* Printer Port Monitor MIB */ +#define CUPS_OID_enterprises 1,3,6,1,4,1 +#define CUPS_OID_pwg CUPS_OID_enterprises,2699,1 +#define CUPS_OID_ppmMIB CUPS_OID_pwg,2 +#define CUPS_OID_ppmMIBObjects CUPS_OID_ppmMIB,1 + +#define CUPS_OID_ppmGeneral CUPS_OID_ppmMIBObjects,1 + +#define CUPS_OID_ppmPrinter CUPS_OID_ppmMIBObjects,2 +#define CUPS_OID_ppmPrinterTable CUPS_OID_ppmPrinter,1 +#define CUPS_OID_ppmPrinterEntry CUPS_OID_ppmPrinterTable,1 +#define CUPS_OID_ppmPrinterIndex CUPS_OID_ppmPrinterEntry,1 +#define CUPS_OID_ppmPrinterName CUPS_OID_ppmPrinterEntry,2 +#define CUPS_OID_ppmPrinterIEEE1284DeviceId CUPS_OID_ppmPrinterEntry,3 +#define CUPS_OID_ppmPrinterNumberOfPorts CUPS_OID_ppmPrinterEntry,4 +#define CUPS_OID_ppmPrinterPreferredPortIndex CUPS_OID_ppmPrinterEntry,5 +#define CUPS_OID_ppmPrinterHrDeviceIndex CUPS_OID_ppmPrinterEntry,6 +#define CUPS_OID_ppmPrinterSnmpCommunityName CUPS_OID_ppmPrinterEntry,7 +#define CUPS_OID_ppmPrinterSnmpQueryEnabled CUPS_OID_ppmPrinterEntry,8 + +#define CUPS_OID_ppmPort CUPS_OID_ppmMIBObjects,3 +#define CUPS_OID_ppmPortTable CUPS_OID_ppmPort,1 +#define CUPS_OID_ppmPortEntry CUPS_OID_ppmPortTable,1 +#define CUPS_OID_ppmPortIndex CUPS_OID_ppmPortEntry,1 +#define CUPS_OID_ppmPortEnabled CUPS_OID_ppmPortEntry,2 +#define CUPS_OID_ppmPortName CUPS_OID_ppmPortEntry,3 +#define CUPS_OID_ppmPortServiceNameOrURI CUPS_OID_ppmPortEntry,4 +#define CUPS_OID_ppmPortProtocolType CUPS_OID_ppmPortEntry,5 +#define CUPS_OID_ppmPortProtocolTargetPort CUPS_OID_ppmPortEntry,6 +#define CUPS_OID_ppmPortProtocolAltSourceEnabled CUPS_OID_ppmPortEntry,7 +#define CUPS_OID_ppmPortPrtChannelIndex CUPS_OID_ppmPortEntry,8 +#define CUPS_OID_ppmPortLprByteCountEnabled CUPS_OID_ppmPortEntry,9 + + +/* + * State constants... + */ + +#define CUPS_TC_other 1 +#define CUPS_TC_unknown 2 + +#define CUPS_TC_idle 3 +#define CUPS_TC_printing 4 +#define CUPS_TC_warmup 5 + +/* These come from the hrPrinterDetectedErrorState OCTET-STRING */ +#define CUPS_TC_lowPaper 0x8000 +#define CUPS_TC_noPaper 0x4000 +#define CUPS_TC_lowToner 0x2000 +#define CUPS_TC_noToner 0x1000 +#define CUPS_TC_doorOpen 0x0800 +#define CUPS_TC_jammed 0x0400 +#define CUPS_TC_offline 0x0200 +#define CUPS_TC_serviceRequested 0x0100 +#define CUPS_TC_inputTrayMissing 0x0080 +#define CUPS_TC_outputTrayMissing 0x0040 +#define CUPS_TC_markerSupplyMissing 0x0020 +#define CUPS_TC_outputNearFull 0x0010 +#define CUPS_TC_outputFull 0x0008 +#define CUPS_TC_inputTrayEmpty 0x0004 +#define CUPS_TC_overduePreventMaint 0x0002 + +#define CUPS_TC_prtCoverStatus_coverOpen 3 +#define CUPS_TC_prtCoverStatus_coverClosed 4 +#define CUPS_TC_prtCoverStatus_interlockOpen 5 +#define CUPS_TC_prtCoverStatus_interlockClosed 6 + +#define CUPS_TC_langPCL 3 +#define CUPS_TC_langHPGL 4 +#define CUPS_TC_langPJL 5 +#define CUPS_TC_langPS 6 +#define CUPS_TC_langEscapeP 9 +#define CUPS_TC_langCCITT 26 +#define CUPS_TC_langLIPS 39 +#define CUPS_TC_langTIFF 40 +#define CUPS_TC_langPCLXL 47 +#define CUPS_TC_langPDF 54 +#define CUPS_TC_langJPEG 61 + +#define CUPS_TC_supplyThatIsConsumed 3 +#define CUPS_TC_receptacleThatIsFilled 4 + +#define CUPS_TC_process 3 +#define CUPS_TC_spot 4 + +#define CUPS_TC_toner 3 +#define CUPS_TC_wasteToner 4 +#define CUPS_TC_ink 5 +#define CUPS_TC_inkCartridge 6 +#define CUPS_TC_inkRibbon 7 +#define CUPS_TC_wasteInk 8 +#define CUPS_TC_opc 9 +#define CUPS_TC_developer 10 +#define CUPS_TC_fuserOil 11 +#define CUPS_TC_solidWax 12 +#define CUPS_TC_ribbonWax 13 +#define CUPS_TC_wasteWax 14 +#define CUPS_TC_fuser 15 +#define CUPS_TC_coronaWire 16 +#define CUPS_TC_fuserOilWick 17 +#define CUPS_TC_cleanerUnit 18 +#define CUPS_TC_fuserCleaningPad 19 +#define CUPS_TC_transferUnit 20 +#define CUPS_TC_tonerCartridge 21 +#define CUPS_TC_fuserOiler 22 +#define CUPS_TC_water 23 +#define CUPS_TC_wasteWater 24 +#define CUPS_TC_glueWaterAdditive 25 +#define CUPS_TC_wastePaper 26 +#define CUPS_TC_bindingSupply 27 +#define CUPS_TC_bandingSupply 28 +#define CUPS_TC_stitchingWire 29 +#define CUPS_TC_shrinkWrap 30 +#define CUPS_TC_paperWrap 31 +#define CUPS_TC_staples 32 +#define CUPS_TC_inserts 33 +#define CUPS_TC_covers 34 + +/* These come from RFC 3808 to define character sets we support */ +/* Also see http://www.iana.org/assignments/character-sets */ +#define CUPS_TC_csASCII 3 +#define CUPS_TC_csISOLatin1 4 +#define CUPS_TC_csShiftJIS 17 +#define CUPS_TC_csUTF8 106 +#define CUPS_TC_csUnicode 1000 /* UCS2 BE */ +#define CUPS_TC_csUCS4 1001 /* UCS4 BE */ +#define CUPS_TC_csUnicodeASCII 1002 +#define CUPS_TC_csUnicodeLatin1 1003 +#define CUPS_TC_csUTF16BE 1013 +#define CUPS_TC_csUTF16LE 1014 +#define CUPS_TC_csUTF32 1017 +#define CUPS_TC_csUTF32BE 1018 +#define CUPS_TC_csUTF32LE 1019 + + +/* + * Prototypes... + */ + +extern void backendCheckSideChannel(int snmp_fd, http_addr_t *addr); +extern int backendDrainOutput(int print_fd, int device_fd); +extern int backendGetDeviceID(int fd, char *device_id, + int device_id_size, + char *make_model, + int make_model_size, + const char *scheme, char *uri, + int uri_size); +extern int backendGetMakeModel(const char *device_id, + char *make_model, + int make_model_size); +extern int backendNetworkSideCB(int print_fd, int device_fd, + int snmp_fd, http_addr_t *addr, + int use_bc); +extern ssize_t backendRunLoop(int print_fd, int device_fd, int snmp_fd, + http_addr_t *addr, int use_bc, + int update_state, + int (*side_cb)(int print_fd, + int device_fd, + int snmp_fd, + http_addr_t *addr, + int use_bc)); +extern int backendSNMPSupplies(int snmp_fd, http_addr_t *addr, + int *page_count, + int *printer_state); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_BACKEND_PRIVATE_H_ */ + + +/* + * End of "$Id$". + */ diff --git a/backend/dnssd.c b/backend/dnssd.c new file mode 100644 index 0000000000..50c364c5b3 --- /dev/null +++ b/backend/dnssd.c @@ -0,0 +1,912 @@ +/* + * "$Id$" + * + * DNS-SD discovery backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2008-2009 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Browse for printers. + * browse_callback() - Browse devices. + * browse_local_callback() - Browse local devices. + * compare_devices() - Compare two devices. + * exec_backend() - Execute the backend that corresponds to the + * resolved service name. + * get_device() - Create or update a device. + * query_callback() - Process query data. + * sigterm_handler() - Handle termination signals... + * unquote() - Unquote a name string. + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" +#include +#include + + +/* + * Device structure... + */ + +typedef enum +{ + CUPS_DEVICE_PRINTER = 0, /* lpd://... */ + CUPS_DEVICE_IPP, /* ipp://... */ + CUPS_DEVICE_FAX_IPP, /* ipp://... */ + CUPS_DEVICE_PDL_DATASTREAM, /* socket://... */ + CUPS_DEVICE_RIOUSBPRINT /* riousbprint://... */ +} cups_devtype_t; + + +typedef struct +{ + DNSServiceRef ref; /* Service reference for resolve */ + char *name, /* Service name */ + *domain, /* Domain name */ + *fullName, /* Full name */ + *make_and_model, /* Make and model from TXT record */ + *device_id; /* 1284 device ID from TXT record */ + cups_devtype_t type; /* Device registration type */ + int priority, /* Priority associated with type */ + cups_shared, /* CUPS shared printer? */ + sent; /* Did we list the device? */ +} cups_device_t; + + +/* + * Local globals... + */ + +static int job_canceled = 0; + /* Set to 1 on SIGTERM */ + + +/* + * Local functions... + */ + +static void browse_callback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *serviceName, + const char *regtype, + const char *replyDomain, void *context); +static void browse_local_callback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *serviceName, + const char *regtype, + const char *replyDomain, + void *context); +static int compare_devices(cups_device_t *a, cups_device_t *b); +static void exec_backend(char **argv); +static cups_device_t *get_device(cups_array_t *devices, + const char *serviceName, + const char *regtype, + const char *replyDomain); +static void query_callback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *fullName, uint16_t rrtype, + uint16_t rrclass, uint16_t rdlen, + const void *rdata, uint32_t ttl, + void *context); +static void sigterm_handler(int sig); +static void unquote(char *dst, const char *src, size_t dstsize); + + +/* + * 'main()' - Browse for printers. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + const char *name; /* Backend name */ + DNSServiceRef main_ref, /* Main service reference */ + fax_ipp_ref, /* IPP fax service reference */ + ipp_ref, /* IPP service reference */ + ipp_tls_ref, /* IPP w/TLS service reference */ + local_fax_ipp_ref, /* Local IPP fax service reference */ + local_ipp_ref, /* Local IPP service reference */ + local_ipp_tls_ref, /* Local IPP w/TLS service reference */ + local_printer_ref, /* Local LPD service reference */ + pdl_datastream_ref, /* AppSocket service reference */ + printer_ref, /* LPD service reference */ + riousbprint_ref; /* Remote IO service reference */ + int fd; /* Main file descriptor */ + fd_set input; /* Input set for select() */ + struct timeval timeout; /* Timeout for select() */ + cups_array_t *devices; /* Device array */ + cups_device_t *device; /* Current device */ + char uriName[1024]; /* Unquoted fullName for URI */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * Don't buffer stderr, and catch SIGTERM... + */ + + setbuf(stderr, NULL); + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, sigterm_handler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = sigterm_handler; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, sigterm_handler); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc >= 6) + exec_backend(argv); + else if (argc != 1) + { + fprintf(stderr, "Usage: %s job user title copies options [filename(s)]\n", + argv[0]); + return (1); + } + + /* + * Only do discovery when run as "dnssd"... + */ + + if ((name = strrchr(argv[0], '/')) != NULL) + name ++; + else + name = argv[0]; + + if (strcmp(name, "dnssd")) + return (0); + + /* + * Create an array to track devices... + */ + + devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); + + /* + * Browse for different kinds of printers... + */ + + if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) + { + perror("ERROR: Unable to create service connection"); + return (1); + } + + fd = DNSServiceRefSockFD(main_ref); + + fax_ipp_ref = main_ref; + DNSServiceBrowse(&fax_ipp_ref, kDNSServiceFlagsShareConnection, 0, + "_fax-ipp._tcp", NULL, browse_callback, devices); + + ipp_ref = main_ref; + DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, + "_ipp._tcp", NULL, browse_callback, devices); + + ipp_tls_ref = main_ref; + DNSServiceBrowse(&ipp_tls_ref, kDNSServiceFlagsShareConnection, 0, + "_ipp-tls._tcp", NULL, browse_callback, devices); + + local_fax_ipp_ref = main_ref; + DNSServiceBrowse(&local_fax_ipp_ref, kDNSServiceFlagsShareConnection, + kDNSServiceInterfaceIndexLocalOnly, + "_fax-ipp._tcp", NULL, browse_local_callback, devices); + + local_ipp_ref = main_ref; + DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection, + kDNSServiceInterfaceIndexLocalOnly, + "_ipp._tcp", NULL, browse_local_callback, devices); + + local_ipp_tls_ref = main_ref; + DNSServiceBrowse(&local_ipp_tls_ref, kDNSServiceFlagsShareConnection, + kDNSServiceInterfaceIndexLocalOnly, + "_ipp-tls._tcp", NULL, browse_local_callback, devices); + + local_printer_ref = main_ref; + DNSServiceBrowse(&local_printer_ref, kDNSServiceFlagsShareConnection, + kDNSServiceInterfaceIndexLocalOnly, + "_printer._tcp", NULL, browse_local_callback, devices); + + pdl_datastream_ref = main_ref; + DNSServiceBrowse(&pdl_datastream_ref, kDNSServiceFlagsShareConnection, 0, + "_pdl-datastream._tcp", NULL, browse_callback, devices); + + printer_ref = main_ref; + DNSServiceBrowse(&printer_ref, kDNSServiceFlagsShareConnection, 0, + "_printer._tcp", NULL, browse_callback, devices); + + riousbprint_ref = main_ref; + DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0, + "_riousbprint._tcp", NULL, browse_callback, devices); + + /* + * Loop until we are killed... + */ + + while (!job_canceled) + { + FD_ZERO(&input); + FD_SET(fd, &input); + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + if (select(fd + 1, &input, NULL, NULL, &timeout) < 0) + continue; + + if (FD_ISSET(fd, &input)) + { + /* + * Process results of our browsing... + */ + + DNSServiceProcessResult(main_ref); + } + else + { + /* + * Announce any devices we've found... + */ + + DNSServiceErrorType status; /* DNS query status */ + cups_device_t *best; /* Best matching device */ + char device_uri[1024]; /* Device URI */ + int count; /* Number of queries */ + + + for (device = (cups_device_t *)cupsArrayFirst(devices), + best = NULL, count = 0; + device; + device = (cups_device_t *)cupsArrayNext(devices)) + if (!device->ref && !device->sent) + { + /* + * Found the device, now get the TXT record(s) for it... + */ + + if (count < 10) + { + device->ref = main_ref; + + fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName); + + status = DNSServiceQueryRecord(&(device->ref), + kDNSServiceFlagsShareConnection, + 0, device->fullName, + kDNSServiceType_TXT, + kDNSServiceClass_IN, query_callback, + devices); + if (status != kDNSServiceErr_NoError) + { + fputs("ERROR: Unable to query for TXT records!\n", stderr); + fprintf(stderr, "DEBUG: DNSServiceQueryRecord returned %d\n", + status); + } + else + count ++; + } + } + else if (!device->sent) + { + /* + * Got the TXT records, now report the device... + */ + + DNSServiceRefDeallocate(device->ref); + device->ref = 0; + + if (!best) + best = device; + else if (strcasecmp(best->name, device->name) || + strcasecmp(best->domain, device->domain)) + { + unquote(uriName, best->fullName, sizeof(uriName)); + + httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), + "dnssd", NULL, uriName, 0, + best->cups_shared ? "/cups" : "/"); + + cupsBackendReport("network", device_uri, best->make_and_model, + best->name, best->device_id, NULL); + best->sent = 1; + best = device; + } + else if (best->priority > device->priority || + (best->priority == device->priority && + best->type < device->type)) + { + best->sent = 1; + best = device; + } + else + device->sent = 1; + } + + if (best) + { + unquote(uriName, best->fullName, sizeof(uriName)); + + httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), + "dnssd", NULL, uriName, 0, + best->cups_shared ? "/cups" : "/"); + + cupsBackendReport("network", device_uri, best->make_and_model, + best->name, best->device_id, NULL); + best->sent = 1; + } + } + } + + return (CUPS_BACKEND_OK); +} + + +/* + * 'browse_callback()' - Browse devices. + */ + +static void +browse_callback( + DNSServiceRef sdRef, /* I - Service reference */ + DNSServiceFlags flags, /* I - Option flags */ + uint32_t interfaceIndex, /* I - Interface number */ + DNSServiceErrorType errorCode, /* I - Error, if any */ + const char *serviceName, /* I - Name of service/device */ + const char *regtype, /* I - Type of service */ + const char *replyDomain, /* I - Service domain */ + void *context) /* I - Devices array */ +{ + fprintf(stderr, "DEBUG2: browse_callback(sdRef=%p, flags=%x, " + "interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", " + "regtype=\"%s\", replyDomain=\"%s\", context=%p)\n", + sdRef, flags, interfaceIndex, errorCode, + serviceName ? serviceName : "(null)", + regtype ? regtype : "(null)", + replyDomain ? replyDomain : "(null)", + context); + + /* + * Only process "add" data... + */ + + if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) + return; + + /* + * Get the device... + */ + + get_device((cups_array_t *)context, serviceName, regtype, replyDomain); +} + + +/* + * 'browse_local_callback()' - Browse local devices. + */ + +static void +browse_local_callback( + DNSServiceRef sdRef, /* I - Service reference */ + DNSServiceFlags flags, /* I - Option flags */ + uint32_t interfaceIndex, /* I - Interface number */ + DNSServiceErrorType errorCode, /* I - Error, if any */ + const char *serviceName, /* I - Name of service/device */ + const char *regtype, /* I - Type of service */ + const char *replyDomain, /* I - Service domain */ + void *context) /* I - Devices array */ +{ + cups_device_t *device; /* Device */ + + + fprintf(stderr, "DEBUG2: browse_local_callback(sdRef=%p, flags=%x, " + "interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", " + "regtype=\"%s\", replyDomain=\"%s\", context=%p)\n", + sdRef, flags, interfaceIndex, errorCode, + serviceName ? serviceName : "(null)", + regtype ? regtype : "(null)", + replyDomain ? replyDomain : "(null)", + context); + + /* + * Only process "add" data... + */ + + if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) + return; + + /* + * Get the device... + */ + + device = get_device((cups_array_t *)context, serviceName, regtype, + replyDomain); + + /* + * Hide locally-registered devices... + */ + + fprintf(stderr, "DEBUG: Hiding local printer \"%s\"...\n", + device->fullName); + device->sent = 1; +} + + +/* + * 'compare_devices()' - Compare two devices. + */ + +static int /* O - Result of comparison */ +compare_devices(cups_device_t *a, /* I - First device */ + cups_device_t *b) /* I - Second device */ +{ + return (strcmp(a->name, b->name)); +} + + +/* + * 'exec_backend()' - Execute the backend that corresponds to the + * resolved service name. + */ + +static void +exec_backend(char **argv) /* I - Command-line arguments */ +{ + const char *resolved_uri, /* Resolved device URI */ + *cups_serverbin; /* Location of programs */ + char scheme[1024], /* Scheme from URI */ + *ptr, /* Pointer into scheme */ + filename[1024]; /* Backend filename */ + + + /* + * Resolve the device URI... + */ + + job_canceled = -1; + + if ((resolved_uri = cupsBackendDeviceURI(argv)) == NULL) + exit(CUPS_BACKEND_FAILED); + + /* + * Extract the scheme from the URI... + */ + + strlcpy(scheme, resolved_uri, sizeof(scheme)); + if ((ptr = strchr(scheme, ':')) != NULL) + *ptr = '\0'; + + /* + * Get the filename of the backend... + */ + + if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL) + cups_serverbin = CUPS_SERVERBIN; + + snprintf(filename, sizeof(filename), "%s/backend/%s", cups_serverbin, scheme); + + /* + * Overwrite the device URI and run the new backend... + */ + + setenv("DEVICE_URI", resolved_uri, 1); + + argv[0] = (char *)resolved_uri; + + fprintf(stderr, "DEBUG: Executing backend \"%s\"...\n", filename); + + execv(filename, argv); + + fprintf(stderr, "ERROR: Unable to execute backend \"%s\": %s\n", filename, + strerror(errno)); + exit(CUPS_BACKEND_STOP); +} + + +/* + * 'get_device()' - Create or update a device. + */ + +static cups_device_t * /* O - Device */ +get_device(cups_array_t *devices, /* I - Device array */ + const char *serviceName, /* I - Name of service/device */ + const char *regtype, /* I - Type of service */ + const char *replyDomain) /* I - Service domain */ +{ + cups_device_t key, /* Search key */ + *device; /* Device */ + char fullName[kDNSServiceMaxDomainName]; + /* Full name for query */ + + + /* + * See if this is a new device... + */ + + key.name = (char *)serviceName; + + if (!strcmp(regtype, "_ipp._tcp.") || + !strcmp(regtype, "_ipp-tls._tcp.")) + key.type = CUPS_DEVICE_IPP; + else if (!strcmp(regtype, "_fax-ipp._tcp.")) + key.type = CUPS_DEVICE_FAX_IPP; + else if (!strcmp(regtype, "_printer._tcp.")) + key.type = CUPS_DEVICE_PRINTER; + else if (!strcmp(regtype, "_pdl-datastream._tcp.")) + key.type = CUPS_DEVICE_PDL_DATASTREAM; + else + key.type = CUPS_DEVICE_RIOUSBPRINT; + + for (device = cupsArrayFind(devices, &key); + device; + device = cupsArrayNext(devices)) + if (strcasecmp(device->name, key.name)) + break; + else if (device->type == key.type) + { + if (!strcasecmp(device->domain, "local.") && + strcasecmp(device->domain, replyDomain)) + { + /* + * Update the .local listing to use the "global" domain name instead. + * The backend will try local lookups first, then the global domain name. + */ + + free(device->domain); + device->domain = strdup(replyDomain); + + DNSServiceConstructFullName(fullName, device->name, regtype, + replyDomain); + free(device->fullName); + device->fullName = strdup(fullName); + } + + return (device); + } + + /* + * Yes, add the device... + */ + + fprintf(stderr, "DEBUG: Found \"%s.%s%s\"...\n", serviceName, regtype, + replyDomain); + + device = calloc(sizeof(cups_device_t), 1); + device->name = strdup(serviceName); + device->domain = strdup(replyDomain); + device->type = key.type; + device->priority = 50; + + cupsArrayAdd(devices, device); + + /* + * Set the "full name" of this service, which is used for queries... + */ + + DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain); + device->fullName = strdup(fullName); + + return (device); +} + + +/* + * 'query_callback()' - Process query data. + */ + +static void +query_callback( + DNSServiceRef sdRef, /* I - Service reference */ + DNSServiceFlags flags, /* I - Data flags */ + uint32_t interfaceIndex, /* I - Interface */ + DNSServiceErrorType errorCode, /* I - Error, if any */ + const char *fullName, /* I - Full service name */ + uint16_t rrtype, /* I - Record type */ + uint16_t rrclass, /* I - Record class */ + uint16_t rdlen, /* I - Length of record data */ + const void *rdata, /* I - Record data */ + uint32_t ttl, /* I - Time-to-live */ + void *context) /* I - Devices array */ +{ + cups_array_t *devices; /* Device array */ + char name[1024], /* Service name */ + *ptr; /* Pointer into string */ + cups_device_t dkey, /* Search key */ + *device; /* Device */ + + + fprintf(stderr, "DEBUG2: query_callback(sdRef=%p, flags=%x, " + "interfaceIndex=%d, errorCode=%d, fullName=\"%s\", " + "rrtype=%u, rrclass=%u, rdlen=%u, rdata=%p, ttl=%u, " + "context=%p)\n", + sdRef, flags, interfaceIndex, errorCode, + fullName ? fullName : "(null)", rrtype, rrclass, rdlen, rdata, ttl, + context); + + /* + * Only process "add" data... + */ + + if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) + return; + + /* + * Lookup the service in the devices array. + */ + + devices = (cups_array_t *)context; + dkey.name = name; + + unquote(name, fullName, sizeof(name)); + + if ((dkey.domain = strstr(name, "._tcp.")) != NULL) + dkey.domain += 6; + else + dkey.domain = (char *)"local."; + + if ((ptr = strstr(name, "._")) != NULL) + *ptr = '\0'; + + if (strstr(fullName, "_ipp._tcp.") || + strstr(fullName, "_ipp-tls._tcp.")) + dkey.type = CUPS_DEVICE_IPP; + else if (strstr(fullName, "_fax-ipp._tcp.")) + dkey.type = CUPS_DEVICE_FAX_IPP; + else if (strstr(fullName, "_printer._tcp.")) + dkey.type = CUPS_DEVICE_PRINTER; + else if (strstr(fullName, "_pdl-datastream._tcp.")) + dkey.type = CUPS_DEVICE_PDL_DATASTREAM; + else + dkey.type = CUPS_DEVICE_RIOUSBPRINT; + + for (device = cupsArrayFind(devices, &dkey); + device; + device = cupsArrayNext(devices)) + { + if (strcasecmp(device->name, dkey.name) || + strcasecmp(device->domain, dkey.domain)) + { + device = NULL; + break; + } + else if (device->type == dkey.type) + { + /* + * Found it, pull out the priority and make and model from the TXT + * record and save it... + */ + + const uint8_t *data, /* Pointer into data */ + *datanext, /* Next key/value pair */ + *dataend; /* End of entire TXT record */ + uint8_t datalen; /* Length of current key/value pair */ + char key[256], /* Key string */ + value[256], /* Value string */ + make_and_model[512], + /* Manufacturer and model */ + model[256], /* Model */ + device_id[2048];/* 1284 device ID */ + + + device_id[0] = '\0'; + make_and_model[0] = '\0'; + + strcpy(model, "Unknown"); + + for (data = rdata, dataend = data + rdlen; + data < dataend; + data = datanext) + { + /* + * Read a key/value pair starting with an 8-bit length. Since the + * length is 8 bits and the size of the key/value buffers is 256, we + * don't need to check for overflow... + */ + + datalen = *data++; + + if (!datalen || (data + datalen) >= dataend) + break; + + datanext = data + datalen; + + for (ptr = key; data < datanext && *data != '='; data ++) + *ptr++ = *data; + *ptr = '\0'; + + if (data < datanext && *data == '=') + { + data ++; + + if (data < datanext) + memcpy(value, data, datanext - data); + value[datanext - data] = '\0'; + } + else + continue; + + if (!strncasecmp(key, "usb_", 4)) + { + /* + * Add USB device ID information... + */ + + ptr = device_id + strlen(device_id); + snprintf(ptr, sizeof(device_id) - (ptr - device_id), "%s:%s;", + key + 4, value); + } + + if (!strcasecmp(key, "usb_MFG") || !strcasecmp(key, "usb_MANU") || + !strcasecmp(key, "usb_MANUFACTURER")) + strcpy(make_and_model, value); + else if (!strcasecmp(key, "usb_MDL") || !strcasecmp(key, "usb_MODEL")) + strcpy(model, value); + else if (!strcasecmp(key, "product") && !strstr(value, "Ghostscript")) + { + if (value[0] == '(') + { + /* + * Strip parenthesis... + */ + + if ((ptr = value + strlen(value) - 1) > value && *ptr == ')') + *ptr = '\0'; + + strcpy(model, value + 1); + } + else + strcpy(model, value); + } + else if (!strcasecmp(key, "ty")) + { + strcpy(model, value); + + if ((ptr = strchr(model, ',')) != NULL) + *ptr = '\0'; + } + else if (!strcasecmp(key, "priority")) + device->priority = atoi(value); + else if ((device->type == CUPS_DEVICE_IPP || + device->type == CUPS_DEVICE_PRINTER) && + !strcasecmp(key, "printer-type")) + { + /* + * This is a CUPS printer! + */ + + device->cups_shared = 1; + + if (device->type == CUPS_DEVICE_PRINTER) + device->sent = 1; + } + } + + if (device->device_id) + free(device->device_id); + + if (!device_id[0] && strcmp(model, "Unknown")) + { + if (make_and_model[0]) + snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s;", + make_and_model, model); + else if (!strncasecmp(model, "designjet ", 10)) + snprintf(device_id, sizeof(device_id), "MFG:HP;MDL:%s", model + 10); + else if (!strncasecmp(model, "stylus ", 7)) + snprintf(device_id, sizeof(device_id), "MFG:EPSON;MDL:%s", model + 7); + else if ((ptr = strchr(model, ' ')) != NULL) + { + /* + * Assume the first word is the make... + */ + + memcpy(make_and_model, model, ptr - model); + make_and_model[ptr - model] = '\0'; + + snprintf(device_id, sizeof(device_id), "MFG:%s;MDL:%s", + make_and_model, ptr + 1); + } + } + + if (device_id[0]) + device->device_id = strdup(device_id); + else + device->device_id = NULL; + + if (device->make_and_model) + free(device->make_and_model); + + if (make_and_model[0]) + { + strlcat(make_and_model, " ", sizeof(make_and_model)); + strlcat(make_and_model, model, sizeof(make_and_model)); + + device->make_and_model = strdup(make_and_model); + } + else + device->make_and_model = strdup(model); + break; + } + } + + if (!device) + fprintf(stderr, "DEBUG: Ignoring TXT record for \"%s\"...\n", fullName); +} + + +/* + * 'sigterm_handler()' - Handle termination signals... + */ + +static void +sigterm_handler(int sig) /* I - Signal number (unused) */ +{ + if (job_canceled) + exit(CUPS_BACKEND_OK); + else + job_canceled = 1; +} + + +/* + * 'unquote()' - Unquote a name string. + */ + +static void +unquote(char *dst, /* I - Destination buffer */ + const char *src, /* I - Source string */ + size_t dstsize) /* I - Size of destination buffer */ +{ + char *dstend = dst + dstsize - 1; /* End of destination buffer */ + + + while (*src && dst < dstend) + { + if (*src == '\\') + { + src ++; + if (isdigit(src[0] & 255) && isdigit(src[1] & 255) && + isdigit(src[2] & 255)) + { + *dst++ = ((((src[0] - '0') * 10) + src[1] - '0') * 10) + src[2] - '0'; + src += 3; + } + else + *dst++ = *src++; + } + else + *dst++ = *src ++; + } + + *dst = '\0'; +} + + +/* + * End of "$Id$". + */ diff --git a/backend/easysw-firewire-design.txt b/backend/easysw-firewire-design.txt new file mode 100644 index 0000000000..194c487ed8 --- /dev/null +++ b/backend/easysw-firewire-design.txt @@ -0,0 +1,71 @@ +Preliminary Design for CUPS Firewire Printer Backend - 03/19/2002 +----------------------------------------------------------------- + +OVERVIEW + + Easy Software Products will develop an IEEE-1394, a.k.a. + Firewire, printing interface for its Common UNIX Printing + System ("CUPS") for initial use under the Linux operating + system. A follow-on implementation for MacOS X is + anticipated as well. + + The operating system interfaces for IEEE-1394 ports vary + widely; the CUPS printing interface will abstract the OS + layer to a simpler interface geared towards discovering, + opening, reading from, writing to, and closing IEEE-1394 + printers. + + The initial development of the CUPS backend will be targeted + at the EPSON Stylus Pro 10000 large format printer, which + requires the bandwidth provided by Firewire in order to + print at full speed. This printer supports printing via + Serial Bus Protocol 2 (SBP-2) using the SCSI and PWG command + sets. The CUPS backend will implement the PWG command set on + LUN 0 only. + + +OS ABSTRACTION LAYER + + The OS abstraction layer will be a thin client library that + implements the following functions: + + ieee1394_list + ieee1394_open + ieee1394_close + ieee1394_read + ieee1394_write + ieee1394_error + + The "ieee1394_list" function will list all of the available + printer devices on the bus. The device information will + consist of the device URI (ieee1394:/something) used to + access the device and the make and model information, if + available, for the device ("EPSON Stylus Printer"). + + The "ieee1394_open" and "ieee1394_close" functions will open + and close a connection to the printer, respectively. + + The "ieee1394_read" and "ieee1394_write" functions will read + and write data to and from the printer, respectively. The + read function will be non-blocking, returning data only if + there is data coming back from the printer. + + The "ieee1394_error" function will return a string + describing the last error or NULL if no error occurred. + + The library will be responsible for creating any background + threads that are needed to monitor the connection to the + printer. + + +CUPS BACKEND + + The CUPS backend will use the OS abstraction layer to list + and access the Firewire printers. The "main" function will + read and write printer data, while the "list_devices" + function will be called as necessary to identify the + available devices. + + The CUPS 1.1 backend will record any status information in + the error log file, while the 1.2 backend will supply it to + the printer driver process. diff --git a/backend/easysw-firewire-linux.txt b/backend/easysw-firewire-linux.txt new file mode 100644 index 0000000000..a8e4611894 --- /dev/null +++ b/backend/easysw-firewire-linux.txt @@ -0,0 +1,35 @@ +Easy Software Products +44141 Airport View Drive +Suite 204 +Hollywood, Maryland 20636 ++1.301.373.9600 +March 8, 2002 + + +Subject: EPSON Firewire Printer Driver for Linux + +Currently, no Firewire printer support exists for Linux. Since +the latest EPSON printer products depend on the Firewire +interface to print at full speed, a solution is needed to +support customers using Linux as their server platform. + +The Linux Firewire subsystem provides a user-mode driver +interface that allows driver programs to access Firewire +devices. Easy Software Products will utilize this interface to +develop a "backend" program for the Common UNIX Printing System +that will allow users to print to EPSON printers using the +Firewire interface. + +After examining the Linux interface, we estimate that it will +require approximately 30 hours of development time to write, +test, and document the Firewire backend, for a total cost of +$3,000. The new backend will become a standard part of the CUPS +software distribution and will be included with at least the +following Linux distributions: + + - Caldera Linux + - Mandrake Linux + - Red Hat Linux + - SuSE Linux + +ESP will provide EPSON with binaries for Red Hat Linux 7.2. diff --git a/backend/ieee1284.c b/backend/ieee1284.c new file mode 100644 index 0000000000..add11a6955 --- /dev/null +++ b/backend/ieee1284.c @@ -0,0 +1,466 @@ +/* + * "$Id$" + * + * IEEE-1284 support functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * backendGetDeviceID() - Get the IEEE-1284 device ID string and + * corresponding URI. + * backendGetMakeModel() - Get the make and model string from the device ID. + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" + + +/* + * 'backendGetDeviceID()' - Get the IEEE-1284 device ID string and + * corresponding URI. + */ + +int /* O - 0 on success, -1 on failure */ +backendGetDeviceID( + int fd, /* I - File descriptor */ + char *device_id, /* O - 1284 device ID */ + int device_id_size, /* I - Size of buffer */ + char *make_model, /* O - Make/model */ + int make_model_size, /* I - Size of buffer */ + const char *scheme, /* I - URI scheme */ + char *uri, /* O - Device URI */ + int uri_size) /* I - Size of buffer */ +{ +#ifdef __APPLE__ /* This function is a no-op */ + return (-1); + +#else /* Get the device ID from the specified file descriptor... */ +# ifdef __linux + int length; /* Length of device ID info */ + int got_id = 0; +# endif /* __linux */ +# if defined(__sun) && defined(ECPPIOC_GETDEVID) + struct ecpp_device_id did; /* Device ID buffer */ +# endif /* __sun && ECPPIOC_GETDEVID */ + + + DEBUG_printf(("backendGetDeviceID(fd=%d, device_id=%p, device_id_size=%d, " + "make_model=%p, make_model_size=%d, scheme=\"%s\", " + "uri=%p, uri_size=%d)\n", fd, device_id, device_id_size, + make_model, make_model_size, scheme ? scheme : "(null)", + uri, uri_size)); + + /* + * Range check input... + */ + + if (!device_id || device_id_size < 32) + { + DEBUG_puts("backendGetDeviceID: Bad args!"); + return (-1); + } + + if (make_model) + *make_model = '\0'; + + if (fd >= 0) + { + /* + * Get the device ID string... + */ + + *device_id = '\0'; + +# ifdef __linux + if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id)) + { + /* + * Linux has to implement things differently for every device it seems. + * Since the standard parallel port driver does not provide a simple + * ioctl() to get the 1284 device ID, we have to open the "raw" parallel + * device corresponding to this port and do some negotiation trickery + * to get the current device ID. + */ + + if (uri && !strncmp(uri, "parallel:/dev/", 14)) + { + char devparport[16]; /* /dev/parportN */ + int devparportfd, /* File descriptor for raw device */ + mode; /* Port mode */ + + + /* + * Since the Linux parallel backend only supports 4 parallel port + * devices, just grab the trailing digit and use it to construct a + * /dev/parportN filename... + */ + + snprintf(devparport, sizeof(devparport), "/dev/parport%s", + uri + strlen(uri) - 1); + + if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1) + { + /* + * Claim the device... + */ + + if (!ioctl(devparportfd, PPCLAIM)) + { + fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK); + + mode = IEEE1284_MODE_COMPAT; + + if (!ioctl(devparportfd, PPNEGOT, &mode)) + { + /* + * Put the device into Device ID mode... + */ + + mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID; + + if (!ioctl(devparportfd, PPNEGOT, &mode)) + { + /* + * Read the 1284 device ID... + */ + + if ((length = read(devparportfd, device_id, + device_id_size - 1)) >= 2) + { + device_id[length] = '\0'; + got_id = 1; + } + } + } + + /* + * Release the device... + */ + + ioctl(devparportfd, PPRELEASE); + } + + close(devparportfd); + } + } + } + else + got_id = 1; + + if (got_id) + { + /* + * Extract the length of the device ID string from the first two + * bytes. The 1284 spec says the length is stored MSB first... + */ + + length = (((unsigned)device_id[0] & 255) << 8) + + ((unsigned)device_id[1] & 255); + + /* + * Check to see if the length is larger than our buffer; first + * assume that the vendor incorrectly implemented the 1284 spec, + * and then limit the length to the size of our buffer... + */ + + if (length > device_id_size) + length = (((unsigned)device_id[1] & 255) << 8) + + ((unsigned)device_id[0] & 255); + + if (length > device_id_size) + length = device_id_size; + + /* + * The length field counts the number of bytes in the string + * including the length field itself (2 bytes). The minimum + * length for a valid/usable device ID is 14 bytes: + * + * MFG: ;MDL: ; + * 2 + 4 + 1 + 5 + 1 + 1 + */ + + if (length < 14) + { + /* + * Can't use this device ID, so don't try to copy it... + */ + + device_id[0] = '\0'; + got_id = 0; + } + else + { + /* + * Copy the device ID text to the beginning of the buffer and + * nul-terminate. + */ + + length -= 2; + + memmove(device_id, device_id + 2, length); + device_id[length] = '\0'; + } + } +# ifdef DEBUG + else + DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n", + strerror(errno))); +# endif /* DEBUG */ +# endif /* __linux */ + +# if defined(__sun) && defined(ECPPIOC_GETDEVID) + did.mode = ECPP_CENTRONICS; + did.len = device_id_size - 1; + did.rlen = 0; + did.addr = device_id; + + if (!ioctl(fd, ECPPIOC_GETDEVID, &did)) + { + /* + * Nul-terminate the device ID text. + */ + + if (did.rlen < (device_id_size - 1)) + device_id[did.rlen] = '\0'; + else + device_id[device_id_size - 1] = '\0'; + } +# ifdef DEBUG + else + DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n", + strerror(errno))); +# endif /* DEBUG */ +# endif /* __sun && ECPPIOC_GETDEVID */ + } + + DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id)); + + if (scheme && uri) + *uri = '\0'; + + if (!*device_id) + return (-1); + + /* + * Get the make and model... + */ + + if (make_model) + backendGetMakeModel(device_id, make_model, make_model_size); + + /* + * Then generate a device URI... + */ + + if (scheme && uri && uri_size > 32) + { + int num_values; /* Number of keys and values */ + cups_option_t *values; /* Keys and values in device ID */ + const char *mfg, /* Manufacturer */ + *mdl, /* Model */ + *sern; /* Serial number */ + char temp[256], /* Temporary manufacturer string */ + *tempptr; /* Pointer into temp string */ + + + /* + * Get the make, model, and serial numbers... + */ + + num_values = _ppdGet1284Values(device_id, &values); + + if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL) + if ((sern = cupsGetOption("SERN", num_values, values)) == NULL) + sern = cupsGetOption("SN", num_values, values); + + if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL) + mfg = cupsGetOption("MFG", num_values, values); + + if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL) + mdl = cupsGetOption("MDL", num_values, values); + + if (mfg) + { + if (!strcasecmp(mfg, "Hewlett-Packard")) + mfg = "HP"; + else if (!strcasecmp(mfg, "Lexmark International")) + mfg = "Lexmark"; + } + else + { + strlcpy(temp, make_model, sizeof(temp)); + + if ((tempptr = strchr(temp, ' ')) != NULL) + *tempptr = '\0'; + + mfg = temp; + } + + if (!mdl) + mdl = ""; + + if (!strncasecmp(mdl, mfg, strlen(mfg))) + { + mdl += strlen(mfg); + + while (isspace(*mdl & 255)) + mdl ++; + } + + /* + * Generate the device URI from the manufacturer, make_model, and + * serial number strings. + */ + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, scheme, NULL, mfg, 0, + "/%s%s%s", mdl, sern ? "?serial=" : "", sern ? sern : ""); + + cupsFreeOptions(num_values, values); + } + + return (0); +#endif /* __APPLE__ */ +} + + +/* + * 'backendGetMakeModel()' - Get the make and model string from the device ID. + */ + +int /* O - 0 on success, -1 on failure */ +backendGetMakeModel( + const char *device_id, /* O - 1284 device ID */ + char *make_model, /* O - Make/model */ + int make_model_size) /* I - Size of buffer */ +{ + int num_values; /* Number of keys and values */ + cups_option_t *values; /* Keys and values */ + const char *mfg, /* Manufacturer string */ + *mdl, /* Model string */ + *des; /* Description string */ + + + DEBUG_printf(("backendGetMakeModel(device_id=\"%s\", " + "make_model=%p, make_model_size=%d)\n", device_id, + make_model, make_model_size)); + + /* + * Range check input... + */ + + if (!device_id || !*device_id || !make_model || make_model_size < 32) + { + DEBUG_puts("backendGetMakeModel: Bad args!"); + return (-1); + } + + *make_model = '\0'; + + /* + * Look for the description field... + */ + + num_values = _ppdGet1284Values(device_id, &values); + + if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL) + mdl = cupsGetOption("MDL", num_values, values); + + if (mdl) + { + /* + * Build a make-model string from the manufacturer and model attributes... + */ + + if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL) + mfg = cupsGetOption("MFG", num_values, values); + + if (!mfg || !strncasecmp(mdl, mfg, strlen(mfg))) + { + /* + * Just copy the model string, since it has the manufacturer... + */ + + _ppdNormalizeMakeAndModel(mdl, make_model, make_model_size); + } + else + { + /* + * Concatenate the make and model... + */ + + char temp[1024]; /* Temporary make and model */ + + if (mfg) + snprintf(temp, sizeof(temp), "%s %s", mfg, mdl); + else + snprintf(temp, sizeof(temp), "%s", mdl); + + _ppdNormalizeMakeAndModel(temp, make_model, make_model_size); + } + } + else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL || + (des = cupsGetOption("DES", num_values, values)) != NULL) + { + /* + * Make sure the description contains something useful, since some + * printer manufacturers (HP) apparently don't follow the standards + * they helped to define... + * + * Here we require the description to be 8 or more characters in length, + * containing at least one space and one letter. + */ + + if (strlen(des) >= 8) + { + const char *ptr; /* Pointer into description */ + int letters, /* Number of letters seen */ + spaces; /* Number of spaces seen */ + + + for (ptr = des, letters = 0, spaces = 0; *ptr; ptr ++) + { + if (isspace(*ptr & 255)) + spaces ++; + else if (isalpha(*ptr & 255)) + letters ++; + + if (spaces && letters) + break; + } + + if (spaces && letters) + _ppdNormalizeMakeAndModel(des, make_model, make_model_size); + } + } + + if (!make_model[0]) + { + /* + * Use "Unknown" as the printer make and model... + */ + + strlcpy(make_model, "Unknown", make_model_size); + } + + cupsFreeOptions(num_values, values); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/ipp.c b/backend/ipp.c new file mode 100644 index 0000000000..0f7e68adb7 --- /dev/null +++ b/backend/ipp.c @@ -0,0 +1,1953 @@ +/* + * "$Id$" + * + * IPP backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "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. + * cancel_job() - Cancel a print job. + * check_printer_state() - Check the printer state... + * compress_files() - Compress print files... + * password_cb() - Disable the password prompt for + * cupsDoFileRequest(). + * report_attr() - Report an IPP attribute value. + * report_printer_state() - Report the printer state. + * run_pictwps_filter() - Convert PICT files to PostScript when printing + * remotely. + * sigterm_handler() - Handle 'terminate' signals that stop the backend. + */ + +/* + * Include necessary headers. + */ + +#include +#include "backend-private.h" +#include +#include +#include + +/* + * Globals... + */ + +static char *password = NULL; /* Password for device URI */ +static int password_tries = 0; /* Password tries */ +static const char *auth_info_required = "none"; + /* New auth-info-required value */ +#ifdef __APPLE__ +static char pstmpname[1024] = ""; /* Temporary PostScript file name */ +#endif /* __APPLE__ */ +static char tmpfilename[1024] = ""; /* Temporary spool file name */ +static int job_cancelled = 0; /* Job cancelled? */ + + +/* + * Local functions... + */ + +static void cancel_job(http_t *http, const char *uri, int id, + const char *resource, const char *user, int version); +static void check_printer_state(http_t *http, const char *uri, + const char *resource, const char *user, + int version, int job_id); +#ifdef HAVE_LIBZ +static void compress_files(int num_files, char **files); +#endif /* HAVE_LIBZ */ +static const char *password_cb(const char *); +static void report_attr(ipp_attribute_t *attr); +static int report_printer_state(ipp_t *ipp, int job_id); + +#ifdef __APPLE__ +static int run_pictwps_filter(char **argv, const char *filename); +#endif /* __APPLE__ */ +static void sigterm_handler(int sig); + + +/* + * '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 args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int send_options; /* Send job options? */ + int num_options; /* Number of printer options */ + cups_option_t *options; /* Printer options */ + const char *device_uri; /* Device URI */ + char scheme[255], /* Scheme in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info */ + resource[1024], /* Resource info (printer name) */ + addrname[256], /* Address name */ + *optptr, /* Pointer to URI options */ + *name, /* Name of option */ + *value, /* Value of option */ + sep; /* Separator character */ + int snmp_fd, /* SNMP socket */ + start_count, /* Page count via SNMP at start */ + page_count, /* Page count via SNMP */ + have_supplies; /* Printer supports supply levels? */ + int num_files; /* Number of files to print */ + char **files, /* Files to print */ + *filename; /* Pointer to single filename */ + 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 */ + time_t start_time; /* Time of first connect */ + int recoverable; /* Recoverable error shown? */ + int contimeout; /* Connection timeout */ + int delay; /* Delay for retries... */ + int compression, /* Do compression of the job data? */ + waitjob, /* Wait for job complete? */ + waitprinter; /* Wait for printer ready? */ + ipp_attribute_t *job_id_attr; /* job-id attribute */ + int job_id; /* job-id value */ + ipp_attribute_t *job_sheets; /* job-media-sheets-completed */ + ipp_attribute_t *job_state; /* job-state */ + ipp_attribute_t *copies_sup; /* copies-supported */ + ipp_attribute_t *format_sup; /* document-format-supported */ + ipp_attribute_t *printer_state; /* printer-state attribute */ + ipp_attribute_t *printer_accepting; /* printer-is-accepting-jobs */ + int copies, /* Number of copies for job */ + copies_remaining; /* Number of copies remaining */ + const char *content_type, /* CONTENT_TYPE environment variable */ + *final_content_type; /* FINAL_CONTENT_TYPE environment var */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + int version; /* IPP version */ + static const char * const pattrs[] = + { /* Printer attributes we want */ + "com.apple.print.recoverable-message", + "copies-supported", + "document-format-supported", + "marker-colors", + "marker-high-levels", + "marker-levels", + "marker-low-levels", + "marker-message", + "marker-names", + "marker-types", + "printer-is-accepting-jobs", + "printer-state", + "printer-state-message", + "printer-state-reasons", + }; + static const char * const jattrs[] = + { /* Job attributes we want */ + "job-media-sheets-completed", + "job-state" + }; + + + /* + * Make sure status messages are not buffered... + */ + + setbuf(stderr, NULL); + + /* + * Ignore SIGPIPE and catch SIGTERM signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); + sigset(SIGTERM, sigterm_handler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); + + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGTERM); + action.sa_handler = sigterm_handler; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, sigterm_handler); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + char *s; + + if ((s = strrchr(argv[0], '/')) != NULL) + s ++; + else + s = argv[0]; + + printf("network %s \"Unknown\" \"%s (%s)\"\n", + s, _cupsLangString(cupsLangDefault(), + _("Internet Printing Protocol")), s); + return (CUPS_BACKEND_OK); + } + else if (argc < 6) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_STOP); + } + + /* + * Get the (final) content type... + */ + + if ((content_type = getenv("CONTENT_TYPE")) == NULL) + content_type = "application/octet-stream"; + + if ((final_content_type = getenv("FINAL_CONTENT_TYPE")) == NULL) + { + final_content_type = content_type; + + if (!strncmp(final_content_type, "printer/", 8)) + final_content_type = "application/vnd.cups-raw"; + } + + /* + * Extract the hostname and printer name from the URI... + */ + + if ((device_uri = cupsBackendDeviceURI(argv)) == NULL) + return (CUPS_BACKEND_FAILED); + + httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + if (!port) + port = IPP_PORT; /* Default to port 631 */ + + if (!strcmp(scheme, "https")) + cupsSetEncryption(HTTP_ENCRYPT_ALWAYS); + else + cupsSetEncryption(HTTP_ENCRYPT_IF_REQUESTED); + + /* + * See if there are any options... + */ + + compression = 0; + version = 11; + waitjob = 1; + waitprinter = 1; + contimeout = 7 * 24 * 60 * 60; + + if ((optptr = strchr(resource, '?')) != NULL) + { + /* + * Yup, terminate the device name string and move to the first + * character of the optptr... + */ + + *optptr++ = '\0'; + + /* + * Then parse the optptr... + */ + + while (*optptr) + { + /* + * Get the name... + */ + + name = optptr; + + while (*optptr && *optptr != '=' && *optptr != '+' && *optptr != '&') + optptr ++; + + if ((sep = *optptr) != '\0') + *optptr++ = '\0'; + + if (sep == '=') + { + /* + * Get the value... + */ + + value = optptr; + + while (*optptr && *optptr != '+' && *optptr != '&') + optptr ++; + + if (*optptr) + *optptr++ = '\0'; + } + else + value = (char *)""; + + /* + * Process the option... + */ + + if (!strcasecmp(name, "waitjob")) + { + /* + * Wait for job completion? + */ + + waitjob = !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || + !strcasecmp(value, "true"); + } + else if (!strcasecmp(name, "waitprinter")) + { + /* + * Wait for printer idle? + */ + + waitprinter = !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || + !strcasecmp(value, "true"); + } + else if (!strcasecmp(name, "encryption")) + { + /* + * Enable/disable encryption? + */ + + if (!strcasecmp(value, "always")) + cupsSetEncryption(HTTP_ENCRYPT_ALWAYS); + else if (!strcasecmp(value, "required")) + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + else if (!strcasecmp(value, "never")) + cupsSetEncryption(HTTP_ENCRYPT_NEVER); + else if (!strcasecmp(value, "ifrequested")) + cupsSetEncryption(HTTP_ENCRYPT_IF_REQUESTED); + else + { + _cupsLangPrintf(stderr, + _("ERROR: Unknown encryption option value \"%s\"!\n"), + value); + } + } + else if (!strcasecmp(name, "version")) + { + if (!strcmp(value, "1.0")) + version = 10; + else if (!strcmp(value, "1.1")) + version = 11; + else if (!strcmp(value, "2.0")) + version = 20; + else if (!strcmp(value, "2.1")) + version = 21; + else + { + _cupsLangPrintf(stderr, + _("ERROR: Unknown version option value \"%s\"!\n"), + value); + } + } +#ifdef HAVE_LIBZ + else if (!strcasecmp(name, "compression")) + { + compression = !strcasecmp(value, "true") || + !strcasecmp(value, "yes") || + !strcasecmp(value, "on") || + !strcasecmp(value, "gzip"); + } +#endif /* HAVE_LIBZ */ + else if (!strcasecmp(name, "contimeout")) + { + /* + * Set the connection timeout... + */ + + if (atoi(value) > 0) + contimeout = atoi(value); + } + else + { + /* + * Unknown option... + */ + + _cupsLangPrintf(stderr, + _("ERROR: Unknown option \"%s\" with value \"%s\"!\n"), + name, value); + } + } + } + + /* + * 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; /* File descriptor */ + http_addrlist_t *addrlist; /* Address list */ + off_t tbytes; /* Total bytes copied */ + + + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); + + if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, "1")) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), + hostname); + return (CUPS_BACKEND_STOP); + } + + snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family); + + if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to create temporary file")); + return (CUPS_BACKEND_FAILED); + } + + _cupsLangPuts(stderr, _("INFO: Copying print data...\n")); + + tbytes = backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0, + backendNetworkSideCB); + + if (snmp_fd >= 0) + _cupsSNMPClose(snmp_fd); + + httpAddrFreeList(addrlist); + + close(fd); + + /* + * Don't try printing files less than 2 bytes... + */ + + if (tbytes <= 1) + { + _cupsLangPuts(stderr, _("ERROR: Empty print file!\n")); + unlink(tmpfilename); + return (CUPS_BACKEND_FAILED); + } + + /* + * Point to the single file from stdin... + */ + + filename = tmpfilename; + num_files = 1; + files = &filename; + send_options = 0; + } + else + { + /* + * Point to the files on the command-line... + */ + + num_files = argc - 6; + files = argv + 6; + send_options = 1; + +#ifdef HAVE_LIBZ + if (compression) + compress_files(num_files, files); +#endif /* HAVE_LIBZ */ + } + + fprintf(stderr, "DEBUG: %d files to send in job...\n", num_files); + + /* + * Set the authentication info, if any... + */ + + cupsSetPasswordCB(password_cb); + + if (username[0]) + { + /* + * Use authenticaion information in the device URI... + */ + + if ((password = strchr(username, ':')) != NULL) + *password++ = '\0'; + + cupsSetUser(username); + } + else if (!getuid()) + { + /* + * Try loading authentication information from the environment. + */ + + const char *ptr = getenv("AUTH_USERNAME"); + + if (ptr) + cupsSetUser(ptr); + + password = getenv("AUTH_PASSWORD"); + } + + /* + * Try connecting to the remote server... + */ + + delay = 5; + recoverable = 0; + start_time = time(NULL); + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { + fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port); + _cupsLangPuts(stderr, _("INFO: Connecting to printer...\n")); + + if ((http = httpConnectEncrypt(hostname, port, cupsEncryption())) == NULL) + { + if (job_cancelled) + break; + + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + if (tmpfilename[0]) + unlink(tmpfilename); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (errno == ECONNREFUSED || errno == EHOSTDOWN || + errno == EHOSTUNREACH) + { + if (contimeout && (time(NULL) - start_time) > contimeout) + { + _cupsLangPuts(stderr, _("ERROR: Printer not responding!\n")); + return (CUPS_BACKEND_FAILED); + } + + recoverable = 1; + + _cupsLangPrintf(stderr, + _("WARNING: recoverable: Network host \'%s\' is busy; " + "will retry in %d seconds...\n"), + hostname, delay); + + sleep(delay); + + if (delay < 30) + delay += 5; + } + else if (h_errno) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), + hostname); + return (CUPS_BACKEND_STOP); + } + else + { + recoverable = 1; + + fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno)); + _cupsLangPuts(stderr, + _("ERROR: recoverable: Unable to connect to printer; will " + "retry in 30 seconds...\n")); + sleep(30); + } + + if (job_cancelled) + break; + } + } + while (http == NULL); + + if (job_cancelled || !http) + { + if (tmpfilename[0]) + unlink(tmpfilename); + + return (CUPS_BACKEND_FAILED); + } + + fputs("STATE: -connecting-to-device\n", stderr); + _cupsLangPuts(stderr, _("INFO: Connected to printer...\n")); + +#ifdef AF_INET6 + if (http->hostaddr->addr.sa_family == AF_INET6) + fprintf(stderr, "DEBUG: Connected to [%s]:%d (IPv6)...\n", + httpAddrString(http->hostaddr, addrname, sizeof(addrname)), + ntohs(http->hostaddr->ipv6.sin6_port)); + else +#endif /* AF_INET6 */ + if (http->hostaddr->addr.sa_family == AF_INET) + fprintf(stderr, "DEBUG: Connected to %s:%d (IPv4)...\n", + httpAddrString(http->hostaddr, addrname, sizeof(addrname)), + ntohs(http->hostaddr->ipv4.sin_port)); + + /* + * See if the printer supports SNMP... + */ + + if ((snmp_fd = _cupsSNMPOpen(http->hostaddr->addr.sa_family)) >= 0) + have_supplies = !backendSNMPSupplies(snmp_fd, http->hostaddr, &start_count, + NULL); + else + have_supplies = start_count = 0; + + /* + * 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... + */ + + httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, NULL, 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... + */ + + copies_sup = NULL; + format_sup = NULL; + supported = NULL; + + do + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, http->hostaddr); + + /* + * Build the IPP request... + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + /* + * Do the request... + */ + + fputs("DEBUG: Getting supported attributes...\n", stderr); + + if (http->version < HTTP_1_1) + httpReconnect(http); + + 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) + { + if (contimeout && (time(NULL) - start_time) > contimeout) + { + _cupsLangPuts(stderr, _("ERROR: Printer not responding!\n")); + return (CUPS_BACKEND_FAILED); + } + + recoverable = 1; + + _cupsLangPrintf(stderr, + _("WARNING: recoverable: Network host \'%s\' is busy; " + "will retry in %d seconds...\n"), + hostname, delay); + + report_printer_state(supported, 0); + + sleep(delay); + + if (delay < 30) + delay += 5; + } + else if ((ipp_status == IPP_BAD_REQUEST || + ipp_status == IPP_VERSION_NOT_SUPPORTED) && version > 10) + { + /* + * Switch to IPP/1.0... + */ + + _cupsLangPrintf(stderr, + _("INFO: Printer does not support IPP/%d.%d, trying " + "IPP/1.0...\n"), version / 10, version % 10); + version = 10; + httpReconnect(http); + } + else if (ipp_status == IPP_NOT_FOUND) + { + _cupsLangPuts(stderr, _("ERROR: Destination printer does not exist!\n")); + + if (supported) + ippDelete(supported); + + return (CUPS_BACKEND_STOP); + } + else if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) + { + if (!strncmp(httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE), + "Negotiate", 9)) + auth_info_required = "negotiate"; + + fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); + return (CUPS_BACKEND_AUTH_REQUIRED); + } + else + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to get printer status (%s)!\n"), + cupsLastErrorString()); + sleep(10); + } + + 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 */ + } + + 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, 0); + } + 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 && + waitprinter) || + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + ippDelete(supported); + httpClose(http); + + if (tmpfilename[0]) + unlink(tmpfilename); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + } + + if (recoverable) + { + /* + * If we've shown a recoverable error make sure the printer proxies + * have a chance to see the recovered message. Not pretty but + * necessary for now... + */ + + fputs("INFO: recovered: \n", stderr); + sleep(5); + } + + /* + * See if the printer supports multiple copies... + */ + + copies = atoi(argv[4]); + + if (copies_sup || argc < 7) + { + copies_remaining = 1; + + if (argc < 7) + copies = 1; + } + else + copies_remaining = copies; + + /* + * Then issue the print-job request... + */ + + job_id = 0; + + while (copies_remaining > 0) + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, http->hostaddr); + + /* + * Build the IPP request... + */ + + if (job_cancelled) + break; + + if (num_files > 1) + request = ippNewRequest(IPP_CREATE_JOB); + else + request = ippNewRequest(IPP_PRINT_JOB); + + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + + 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]); + + /* + * Only add a "job-name" attribute if the remote server supports + * copy generation - some IPP implementations like HP's don't seem + * to like UTF-8 job names (STR #1837)... + */ + + if (argv[3][0] && copies_sup) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, + argv[3]); + + fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]); + +#ifdef HAVE_LIBZ + if (compression) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "compression", NULL, "gzip"); +#endif /* HAVE_LIBZ */ + + /* + * Handle options on the command-line... + */ + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + +#ifdef __APPLE__ + if (!strcasecmp(final_content_type, "application/pictwps") && + num_files == 1) + { + if (format_sup != NULL) + { + for (i = 0; i < format_sup->num_values; i ++) + if (!strcasecmp(final_content_type, format_sup->values[i].string.text)) + break; + } + + if (format_sup == NULL || i >= format_sup->num_values) + { + /* + * Remote doesn't support "application/pictwps" (i.e. it's not MacOS X) + * so convert the document to PostScript... + */ + + if (run_pictwps_filter(argv, files[0])) + { + if (pstmpname[0]) + unlink(pstmpname); + + if (tmpfilename[0]) + unlink(tmpfilename); + + return (CUPS_BACKEND_FAILED); + } + + files[0] = pstmpname; + + /* + * Change the MIME type to application/postscript and change the + * number of copies to 1... + */ + + final_content_type = "application/postscript"; + copies = 1; + copies_remaining = 1; + send_options = 0; + } + } +#endif /* __APPLE__ */ + + if (format_sup != NULL) + { + for (i = 0; i < format_sup->num_values; i ++) + if (!strcasecmp(final_content_type, format_sup->values[i].string.text)) + break; + + if (i < format_sup->num_values) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, + "document-format", NULL, final_content_type); + } + + if (copies_sup && version > 10 && send_options) + { + /* + * Only send options if the destination printer supports the copies + * attribute and IPP/1.1. This is a hack for the HP and Lexmark + * implementations of IPP, which do not accept extension attributes + * and incorrectly report a client-error-bad-request error instead of + * the successful-ok-unsupported-attributes status. In short, at least + * some HP and Lexmark implementations of IPP are non-compliant. + */ + + cupsEncodeOptions(request, num_options, options); + + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", + copies); + } + + 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 (http->version < HTTP_1_1) + httpReconnect(http); + + if (num_files > 1) + response = cupsDoRequest(http, request, resource); + else + response = cupsDoFileRequest(http, request, resource, files[0]); + + ipp_status = cupsLastError(); + + if (ipp_status > IPP_OK_CONFLICT) + { + job_id = 0; + + if (job_cancelled) + break; + + if (ipp_status == IPP_SERVICE_UNAVAILABLE || + ipp_status == IPP_PRINTER_BUSY) + { + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 10 seconds...\n")); + sleep(10); + } + else if ((ipp_status == IPP_BAD_REQUEST || + ipp_status == IPP_VERSION_NOT_SUPPORTED) && version > 10) + { + /* + * Switch to IPP/1.0... + */ + + _cupsLangPrintf(stderr, + _("INFO: Printer does not support IPP/%d.%d, trying " + "IPP/1.0...\n"), version / 10, version % 10); + version = 10; + httpReconnect(http); + } + else + { + /* + * Update auth-info-required as needed... + */ + + _cupsLangPrintf(stderr, _("ERROR: Print file was not accepted (%s)!\n"), + cupsLastErrorString()); + + if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) + { + fprintf(stderr, "DEBUG: WWW-Authenticate=\"%s\"\n", + httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE)); + + /* + * Normal authentication goes through the password callback, which sets + * auth_info_required to "username,password". Kerberos goes directly + * through GSSAPI, so look for Negotiate in the WWW-Authenticate header + * here and set auth_info_required as needed... + */ + + if (!strncmp(httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE), + "Negotiate", 9)) + auth_info_required = "negotiate"; + } + } + } + else if ((job_id_attr = ippFindAttribute(response, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + _cupsLangPuts(stderr, + _("NOTICE: Print file accepted - job ID unknown.\n")); + job_id = 0; + } + else + { + job_id = job_id_attr->values[0].integer; + _cupsLangPrintf(stderr, _("NOTICE: Print file accepted - job ID %d.\n"), + job_id); + } + + ippDelete(response); + + if (job_cancelled) + break; + + if (job_id && num_files > 1) + { + for (i = 0; i < num_files; i ++) + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, http->hostaddr); + + /* + * Send the next file in the job... + */ + + request = ippNewRequest(IPP_SEND_DOCUMENT); + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + + 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]); + + if ((i + 1) == num_files) + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, + "document-format", NULL, content_type); + + if (http->version < HTTP_1_1) + httpReconnect(http); + + ippDelete(cupsDoFileRequest(http, request, resource, files[i])); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + ipp_status = cupsLastError(); + + _cupsLangPrintf(stderr, + _("ERROR: Unable to add file %d to job: %s\n"), + job_id, cupsLastErrorString()); + break; + } + } + } + + if (ipp_status <= IPP_OK_CONFLICT && argc > 6) + { + fprintf(stderr, "PAGE: 1 %d\n", copies_sup ? atoi(argv[4]) : 1); + copies_remaining --; + } + else if (ipp_status == IPP_SERVICE_UNAVAILABLE || + ipp_status == IPP_PRINTER_BUSY) + continue; + else + copies_remaining --; + + /* + * Wait for the job to complete... + */ + + if (!job_id || !waitjob) + continue; + + _cupsLangPuts(stderr, _("INFO: Waiting for job to complete...\n")); + + for (delay = 1; !job_cancelled;) + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, http->hostaddr); + + /* + * Build an IPP_GET_JOB_ATTRIBUTES request... + */ + + request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + + 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]); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]), + NULL, jattrs); + + /* + * Do the request... + */ + + if (!copies_sup || http->version < HTTP_1_1) + httpReconnect(http); + + response = cupsDoRequest(http, request, resource); + ipp_status = cupsLastError(); + + 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) + { + ippDelete(response); + + _cupsLangPrintf(stderr, + _("ERROR: Unable to get job %d attributes (%s)!\n"), + job_id, cupsLastErrorString()); + break; + } + } + + if (response) + { + 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_STOPPED) + { + if ((job_sheets = ippFindAttribute(response, + "job-media-sheets-completed", + IPP_TAG_INTEGER)) != NULL) + fprintf(stderr, "PAGE: total %d\n", + job_sheets->values[0].integer); + + ippDelete(response); + break; + } + } + else + { + /* + * If the printer does not return a job-state attribute, it does not + * conform to the IPP specification - break out immediately and fail + * the job... + */ + + fputs("DEBUG: No job-state available from printer - stopping queue.\n", + stderr); + ipp_status = IPP_INTERNAL_ERROR; + break; + } + } + + ippDelete(response); + + /* + * Check the printer state and report it if necessary... + */ + + check_printer_state(http, uri, resource, argv[2], version, job_id); + + /* + * Wait 1-10 seconds before polling again... + */ + + sleep(delay); + + delay ++; + if (delay > 10) + delay = 1; + } + } + + /* + * Cancel the job as needed... + */ + + if (job_cancelled && job_id) + cancel_job(http, uri, job_id, resource, argv[2], version); + + /* + * Check the printer state and report it if necessary... + */ + + check_printer_state(http, uri, resource, argv[2], version, job_id); + + /* + * Collect the final page count as needed... + */ + + if (have_supplies && + !backendSNMPSupplies(snmp_fd, http->hostaddr, &page_count, NULL) && + page_count > start_count) + fprintf(stderr, "PAGE: total %d\n", page_count - start_count); + +#ifdef HAVE_GSSAPI + /* + * See if we used Kerberos at all... + */ + + if (http->gssctx) + auth_info_required = "negotiate"; +#endif /* HAVE_GSSAPI */ + + /* + * Free memory... + */ + + httpClose(http); + + ippDelete(supported); + + /* + * Remove the temporary file(s) if necessary... + */ + + if (tmpfilename[0]) + unlink(tmpfilename); + +#ifdef HAVE_LIBZ + if (compression) + { + for (i = 0; i < num_files; i ++) + unlink(files[i]); + } +#endif /* HAVE_LIBZ */ + +#ifdef __APPLE__ + if (pstmpname[0]) + unlink(pstmpname); +#endif /* __APPLE__ */ + + /* + * Return the queue status... + */ + + fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); + + if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN) + return (CUPS_BACKEND_AUTH_REQUIRED); + else if (ipp_status == IPP_INTERNAL_ERROR) + return (CUPS_BACKEND_STOP); + else if (ipp_status > IPP_OK_CONFLICT) + return (CUPS_BACKEND_FAILED); + else + { + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + return (CUPS_BACKEND_OK); + } +} + + +/* + * 'cancel_job()' - Cancel a print job. + */ + +static void +cancel_job(http_t *http, /* I - HTTP connection */ + const char *uri, /* I - printer-uri */ + int id, /* I - job-id */ + const char *resource, /* I - Resource path */ + const char *user, /* I - requesting-user-name */ + int version) /* I - IPP version */ +{ + ipp_t *request; /* Cancel-Job request */ + + + _cupsLangPuts(stderr, _("INFO: Canceling print job...\n")); + + request = ippNewRequest(IPP_CANCEL_JOB); + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", id); + + if (user && user[0]) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + /* + * Do the request... + */ + + if (http->version < HTTP_1_1) + httpReconnect(http); + + ippDelete(cupsDoRequest(http, request, resource)); + + if (cupsLastError() > IPP_OK_CONFLICT) + _cupsLangPrintf(stderr, _("ERROR: Unable to cancel job %d: %s\n"), id, + cupsLastErrorString()); +} + + +/* + * 'check_printer_state()' - Check the printer state... + */ + +static void +check_printer_state( + http_t *http, /* I - HTTP connection */ + const char *uri, /* I - Printer URI */ + const char *resource, /* I - Resource path */ + const char *user, /* I - Username, if any */ + int version, /* I - IPP version */ + int job_id) /* I - Current job ID */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + static const char * const attrs[] = /* Attributes we want */ + { + "com.apple.print.recoverable-message", + "marker-colors", + "marker-levels", + "marker-message", + "marker-names", + "marker-types", + "printer-state-message", + "printer-state-reasons" + }; + + + /* + * Check on the printer state... + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + if (user && user[0]) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(attrs) / sizeof(attrs[0])), NULL, attrs); + + /* + * Do the request... + */ + + if (http->version < HTTP_1_1) + httpReconnect(http); + + if ((response = cupsDoRequest(http, request, resource)) != NULL) + { + report_printer_state(response, job_id); + ippDelete(response); + } +} + + +#ifdef HAVE_LIBZ +/* + * 'compress_files()' - Compress print files... + */ + +static void +compress_files(int num_files, /* I - Number of files */ + char **files) /* I - Files */ +{ + int i, /* Looping var */ + fd; /* Temporary file descriptor */ + ssize_t bytes; /* Bytes read/written */ + size_t total; /* Total bytes read */ + cups_file_t *in, /* Input file */ + *out; /* Output file */ + struct stat outinfo; /* Output file information */ + char filename[1024], /* Temporary filename */ + buffer[32768]; /* Copy buffer */ + + + fprintf(stderr, "DEBUG: Compressing %d job files...\n", num_files); + for (i = 0; i < num_files; i ++) + { + if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to create temporary compressed print " + "file: %s\n"), strerror(errno)); + exit(CUPS_BACKEND_FAILED); + } + + if ((out = cupsFileOpenFd(fd, "w9")) == NULL) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open temporary compressed print " + "file: %s\n"), strerror(errno)); + exit(CUPS_BACKEND_FAILED); + } + + if ((in = cupsFileOpen(files[i], "r")) == NULL) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open print file \"%s\": %s\n"), + files[i], strerror(errno)); + cupsFileClose(out); + exit(CUPS_BACKEND_FAILED); + } + + total = 0; + while ((bytes = cupsFileRead(in, buffer, sizeof(buffer))) > 0) + if (cupsFileWrite(out, buffer, bytes) < bytes) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to write %d bytes to \"%s\": %s\n"), + (int)bytes, filename, strerror(errno)); + cupsFileClose(in); + cupsFileClose(out); + exit(CUPS_BACKEND_FAILED); + } + else + total += bytes; + + cupsFileClose(out); + cupsFileClose(in); + + files[i] = strdup(filename); + + if (!stat(filename, &outinfo)) + fprintf(stderr, + "DEBUG: File %d compressed to %.1f%% of original size, " + CUPS_LLFMT " bytes...\n", + i + 1, 100.0 * outinfo.st_size / total, + CUPS_LLCAST outinfo.st_size); + } +} +#endif /* HAVE_LIBZ */ + + +/* + * 'password_cb()' - Disable the password prompt for cupsDoFileRequest(). + */ + +static const char * /* O - Password */ +password_cb(const char *prompt) /* I - Prompt (not used) */ +{ + (void)prompt; + + /* + * Remember that we need to authenticate... + */ + + auth_info_required = "username,password"; + + if (password && *password && password_tries < 3) + { + password_tries ++; + + return (password); + } + else + { + /* + * Give up after 3 tries or if we don't have a password to begin with... + */ + + return (NULL); + } +} + + +/* + * 'report_attr()' - Report an IPP attribute value. + */ + +static void +report_attr(ipp_attribute_t *attr) /* I - Attribute */ +{ + int i; /* Looping var */ + char value[1024], /* Value string */ + *valptr, /* Pointer into value string */ + *attrptr; /* Pointer into attribute value */ + + + /* + * Convert the attribute values into quoted strings... + */ + + for (i = 0, valptr = value; + i < attr->num_values && valptr < (value + sizeof(value) - 10); + i ++) + { + if (i > 0) + *valptr++ = ','; + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + snprintf(valptr, sizeof(value) - (valptr - value), "%d", + attr->values[i].integer); + valptr += strlen(valptr); + break; + + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + *valptr++ = '\"'; + for (attrptr = attr->values[i].string.text; + *attrptr && valptr < (value + sizeof(value) - 10); + attrptr ++) + { + if (*attrptr == '\\' || *attrptr == '\"') + *valptr++ = '\\'; + + *valptr++ = *attrptr; + } + *valptr++ = '\"'; + break; + + default : + /* + * Unsupported value type... + */ + + return; + } + } + + *valptr = '\0'; + + /* + * Tell the scheduler about the new values... + */ + + fprintf(stderr, "ATTR: %s=%s\n", attr->name, value); +} + + +/* + * 'report_printer_state()' - Report the printer state. + */ + +static int /* O - Number of reasons shown */ +report_printer_state(ipp_t *ipp, /* I - IPP response */ + int job_id) /* I - Current job ID */ +{ + int i; /* Looping var */ + int count; /* Count of reasons shown... */ + ipp_attribute_t *caprm, /* com.apple.print.recoverable-message */ + *psm, /* printer-state-message */ + *reasons, /* printer-state-reasons */ + *marker; /* marker-* attributes */ + const char *reason; /* Current reason */ + const char *prefix; /* Prefix for STATE: line */ + char state[1024]; /* State string */ + int saw_caprw; /* Saw com.apple.print.recoverable-warning state */ + + + if ((psm = ippFindAttribute(ipp, "printer-state-message", + IPP_TAG_TEXT)) != NULL) + fprintf(stderr, "INFO: %s\n", psm->values[0].string.text); + + if ((reasons = ippFindAttribute(ipp, "printer-state-reasons", + IPP_TAG_KEYWORD)) == NULL) + return (0); + + saw_caprw = 0; + state[0] = '\0'; + prefix = "STATE: "; + + for (i = 0, count = 0; i < reasons->num_values; i ++) + { + reason = reasons->values[i].string.text; + + if (!strcmp(reason, "com.apple.print.recoverable-warning")) + saw_caprw = 1; + else if (strcmp(reason, "paused")) + { + strlcat(state, prefix, sizeof(state)); + strlcat(state, reason, sizeof(state)); + + prefix = ","; + } + } + + if (state[0]) + fprintf(stderr, "%s\n", state); + + /* + * Relay com.apple.print.recoverable-message... + */ + + if ((caprm = ippFindAttribute(ipp, "com.apple.print.recoverable-message", + IPP_TAG_TEXT)) != NULL) + fprintf(stderr, "WARNING: %s: %s\n", + saw_caprw ? "recoverable" : "recovered", + caprm->values[0].string.text); + + /* + * Relay the current marker-* attribute values... + */ + + if ((marker = ippFindAttribute(ipp, "marker-colors", IPP_TAG_NAME)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-high-levels", + IPP_TAG_INTEGER)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-levels", + IPP_TAG_INTEGER)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-low-levels", + IPP_TAG_INTEGER)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-message", IPP_TAG_TEXT)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-names", IPP_TAG_NAME)) != NULL) + report_attr(marker); + if ((marker = ippFindAttribute(ipp, "marker-types", IPP_TAG_KEYWORD)) != NULL) + report_attr(marker); + + return (count); +} + + +#ifdef __APPLE__ +/* + * 'run_pictwps_filter()' - Convert PICT files to PostScript when printing + * remotely. + * + * This step is required because the PICT format is not documented and + * subject to change, so developing a filter for other OS's is infeasible. + * Also, fonts required by the PICT file need to be embedded on the + * client side (which has the fonts), so we run the filter to get a + * PostScript file for printing... + */ + +static int /* O - Exit status of filter */ +run_pictwps_filter(char **argv, /* I - Command-line arguments */ + const char *filename)/* I - Filename */ +{ + struct stat fileinfo; /* Print file information */ + const char *ppdfile; /* PPD file for destination printer */ + int pid; /* Child process ID */ + int fd; /* Temporary file descriptor */ + int status; /* Exit status of filter */ + const char *printer; /* PRINTER env var */ + static char ppdenv[1024]; /* PPD environment variable */ + + + /* + * First get the PPD file for the printer... + */ + + printer = getenv("PRINTER"); + if (!printer) + { + _cupsLangPuts(stderr, + _("ERROR: PRINTER environment variable not defined!\n")); + return (-1); + } + + if ((ppdfile = cupsGetPPD(printer)) == NULL) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to get PPD file for printer \"%s\" - " + "%s.\n"), printer, cupsLastErrorString()); + } + else + { + snprintf(ppdenv, sizeof(ppdenv), "PPD=%s", ppdfile); + putenv(ppdenv); + } + + /* + * Then create a temporary file for printing... + */ + + if ((fd = cupsTempFd(pstmpname, sizeof(pstmpname))) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to create temporary file")); + if (ppdfile) + unlink(ppdfile); + return (-1); + } + + /* + * Get the owner of the spool file - it is owned by the user we want to run + * as... + */ + + if (argv[6]) + stat(argv[6], &fileinfo); + else + { + /* + * Use the OSX defaults, as an up-stream filter created the PICT + * file... + */ + + fileinfo.st_uid = 1; + fileinfo.st_gid = 80; + } + + if (ppdfile) + chown(ppdfile, fileinfo.st_uid, fileinfo.st_gid); + + fchown(fd, fileinfo.st_uid, fileinfo.st_gid); + + /* + * Finally, run the filter to convert the file... + */ + + if ((pid = fork()) == 0) + { + /* + * Child process for pictwpstops... Redirect output of pictwpstops to a + * file... + */ + + dup2(fd, 1); + close(fd); + + if (!getuid()) + { + /* + * Change to an unpriviledged user... + */ + + if (setgid(fileinfo.st_gid)) + return (errno); + + if (setuid(fileinfo.st_uid)) + return (errno); + } + + execlp("pictwpstops", printer, argv[1], argv[2], argv[3], argv[4], argv[5], + filename, NULL); + _cupsLangPrintf(stderr, _("ERROR: Unable to exec pictwpstops: %s\n"), + strerror(errno)); + return (errno); + } + + close(fd); + + if (pid < 0) + { + /* + * Error! + */ + + _cupsLangPrintf(stderr, _("ERROR: Unable to fork pictwpstops: %s\n"), + strerror(errno)); + if (ppdfile) + unlink(ppdfile); + return (-1); + } + + /* + * Now wait for the filter to complete... + */ + + if (wait(&status) < 0) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to wait for pictwpstops: %s\n"), + strerror(errno)); + close(fd); + if (ppdfile) + unlink(ppdfile); + return (-1); + } + + if (ppdfile) + unlink(ppdfile); + + close(fd); + + if (status) + { + if (status >= 256) + _cupsLangPrintf(stderr, _("ERROR: pictwpstops exited with status %d!\n"), + status / 256); + else + _cupsLangPrintf(stderr, _("ERROR: pictwpstops exited on signal %d!\n"), + status); + + return (status); + } + + /* + * Return with no errors.. + */ + + return (0); +} +#endif /* __APPLE__ */ + + +/* + * 'sigterm_handler()' - Handle 'terminate' signals that stop the backend. + */ + +static void +sigterm_handler(int sig) /* I - Signal */ +{ + (void)sig; /* remove compiler warnings... */ + + if (!job_cancelled) + { + /* + * Flag that the job should be cancelled... + */ + + job_cancelled = 1; + return; + } + + /* + * The scheduler already tried to cancel us once, now just terminate + * after removing our temp files! + */ + + if (tmpfilename[0]) + unlink(tmpfilename); + +#ifdef __APPLE__ + if (pstmpname[0]) + unlink(pstmpname); +#endif /* __APPLE__ */ + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/lpd.c b/backend/lpd.c new file mode 100644 index 0000000000..73ff1a7112 --- /dev/null +++ b/backend/lpd.c @@ -0,0 +1,1380 @@ +/* + * "$Id$" + * + * Line Printer Daemon backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "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. + * rresvport_af() - A simple implementation of rresvport_af(). + * sigterm_handler() - Handle 'terminate' signals that stop the backend. + */ + +/* + * Include necessary headers. + */ + +#include +#include "backend-private.h" +#include +#include +#include + +#ifdef WIN32 +# include +#else +# include +# include +# include +# include +#endif /* WIN32 */ +#ifdef __APPLE__ +# include +# include +#endif /* __APPLE__ */ + + +/* + * Globals... + */ + +static char tmpfilename[1024] = ""; /* Temporary spool file name */ +static int abort_job = 0; /* Non-zero if we get SIGTERM */ + + +/* + * Print mode... + */ + +#define MODE_STANDARD 0 /* Queue a copy */ +#define MODE_STREAM 1 /* Stream a copy */ + + +/* + * The order for control and data files in LPD requests... + */ + +#define ORDER_CONTROL_DATA 0 /* Control file first, then data */ +#define ORDER_DATA_CONTROL 1 /* Data file first, then control */ + + +/* + * What to reserve... + */ + +#define RESERVE_NONE 0 /* Don't reserve a priviledged port */ +#define RESERVE_RFC1179 1 /* Reserve port 721-731 */ +#define RESERVE_ANY 2 /* Reserve port 1-1023 */ + + +/* + * Local functions... + */ + +static int lpd_command(int lpd_fd, int timeout, char *format, ...); +static int lpd_queue(const char *hostname, int port, const char *printer, + int print_fd, int mode, const char *user, + const char *title, int copies, int banner, + int format, int order, int reserve, + int manual_copies, int timeout, int contimeout); +static void lpd_timeout(int sig); +static int lpd_write(int lpd_fd, char *buffer, int length); +#ifndef HAVE_RRESVPORT_AF +static int rresvport_af(int *port, int family); +#endif /* !HAVE_RRESVPORT_AF */ +static void sigterm_handler(int sig); + + +/* + * '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 */ +{ + const char *device_uri; /* Device URI */ + char scheme[255], /* Scheme in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info */ + resource[1024], /* Resource info (printer name) */ + *options, /* Pointer to options */ + *name, /* Name of option */ + *value, /* Value of option */ + sep, /* Separator character */ + *filename, /* File to print */ + title[256]; /* Title string */ + int port; /* Port number */ + int fd; /* Print file */ + int status; /* Status of LPD job */ + int mode; /* Print mode */ + int banner; /* Print banner page? */ + int format; /* Print format */ + int order; /* Order of control/data files */ + int reserve; /* Reserve priviledged port? */ + int sanitize_title; /* Sanitize title string? */ + int manual_copies, /* Do manual copies? */ + timeout, /* Timeout */ + contimeout, /* Connection timeout */ + copies; /* Number of copies */ +#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); + + /* + * Ignore SIGPIPE and catch SIGTERM signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); + sigset(SIGTERM, sigterm_handler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); + + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGTERM); + action.sa_handler = sigterm_handler; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, sigterm_handler); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + printf("network lpd \"Unknown\" \"%s\"\n", + _cupsLangString(cupsLangDefault(), _("LPD/LPR Host or Printer"))); + return (CUPS_BACKEND_OK); + } + else if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* + * Extract the hostname and printer name from the URI... + */ + + if ((device_uri = cupsBackendDeviceURI(argv)) == NULL) + return (CUPS_BACKEND_FAILED); + + httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + if (!port) + port = 515; /* Default to port 515 */ + + if (!username[0]) + { + /* + * If no username is in the device URI, then use the print job user... + */ + + strlcpy(username, argv[2], sizeof(username)); + } + + /* + * See if there are any options... + */ + + mode = MODE_STANDARD; + banner = 0; + format = 'l'; + order = ORDER_CONTROL_DATA; + reserve = RESERVE_ANY; + manual_copies = 1; + timeout = 300; + contimeout = 7 * 24 * 60 * 60; + +#ifdef __APPLE__ + /* + * We want to pass utf-8 characters, not re-map them (3071945) + */ + + sanitize_title = 0; + + /* + * Get the default timeout from a system preference... + */ + + { + CFPropertyListRef pvalue; /* Preference value */ + SInt32 toval; /* Timeout value */ + + + pvalue = CFPreferencesCopyValue(CFSTR("timeout"), + CFSTR("com.apple.print.backends"), + kCFPreferencesAnyUser, + kCFPreferencesCurrentHost); + if (pvalue) + { + if (CFGetTypeID(pvalue) == CFNumberGetTypeID()) + { + CFNumberGetValue(pvalue, kCFNumberSInt32Type, &toval); + contimeout = (int)toval; + } + + CFRelease(pvalue); + } + } +#else + sanitize_title = 1; +#endif /* __APPLE__ */ + + 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... + */ + + name = options; + + while (*options && *options != '=' && *options != '+' && *options != '&') + options ++; + + if ((sep = *options) != '\0') + *options++ = '\0'; + + if (sep == '=') + { + /* + * Get the value... + */ + + value = options; + + while (*options && *options != '+' && *options != '&') + options ++; + + if (*options) + *options++ = '\0'; + } + else + value = (char *)""; + + /* + * Process the option... + */ + + if (!strcasecmp(name, "banner")) + { + /* + * Set the banner... + */ + + banner = !value[0] || !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || !strcasecmp(value, "true"); + } + else if (!strcasecmp(name, "format") && value[0]) + { + /* + * Set output format... + */ + + if (strchr("cdfglnoprtv", value[0])) + format = value[0]; + else + _cupsLangPrintf(stderr, _("ERROR: Unknown format character \"%c\"\n"), + value[0]); + } + else if (!strcasecmp(name, "mode") && value[0]) + { + /* + * Set control/data order... + */ + + if (!strcasecmp(value, "standard")) + mode = MODE_STANDARD; + else if (!strcasecmp(value, "stream")) + mode = MODE_STREAM; + else + _cupsLangPrintf(stderr, _("ERROR: Unknown print mode \"%s\"\n"), + value); + } + else if (!strcasecmp(name, "order") && value[0]) + { + /* + * Set control/data order... + */ + + if (!strcasecmp(value, "control,data")) + order = ORDER_CONTROL_DATA; + else if (!strcasecmp(value, "data,control")) + order = ORDER_DATA_CONTROL; + else + _cupsLangPrintf(stderr, _("ERROR: Unknown file order \"%s\"\n"), + value); + } + else if (!strcasecmp(name, "reserve")) + { + /* + * Set port reservation mode... + */ + + if (!value[0] || !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || !strcasecmp(value, "true") || + !strcasecmp(value, "rfc1179")) + reserve = RESERVE_RFC1179; + else if (!strcasecmp(value, "any")) + reserve = RESERVE_ANY; + else + reserve = RESERVE_NONE; + } + else if (!strcasecmp(name, "manual_copies")) + { + /* + * Set manual copies... + */ + + manual_copies = !value[0] || !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || !strcasecmp(value, "true"); + } + else if (!strcasecmp(name, "sanitize_title")) + { + /* + * Set sanitize title... + */ + + sanitize_title = !value[0] || !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || !strcasecmp(value, "true"); + } + else if (!strcasecmp(name, "timeout")) + { + /* + * Set the timeout... + */ + + if (atoi(value) > 0) + timeout = atoi(value); + } + else if (!strcasecmp(name, "contimeout")) + { + /* + * Set the connection timeout... + */ + + if (atoi(value) > 0) + contimeout = atoi(value); + } + } + } + + if (mode == MODE_STREAM) + order = ORDER_CONTROL_DATA; + + /* + * 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 && mode == MODE_STANDARD) + { + /* + * Copy stdin to a temporary file... + */ + + http_addrlist_t *addrlist; /* Address list */ + int snmp_fd; /* SNMP socket */ + + + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); + + if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, "1")) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), + hostname); + return (CUPS_BACKEND_STOP); + } + + snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family); + + if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to create temporary file")); + return (CUPS_BACKEND_FAILED); + } + + _cupsLangPuts(stderr, _("INFO: Copying print data...\n")); + + backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0, + backendNetworkSideCB); + + if (snmp_fd >= 0) + _cupsSNMPClose(snmp_fd); + + httpAddrFreeList(addrlist); + } + else if (argc == 6) + { + /* + * Stream from stdin... + */ + + filename = NULL; + fd = 0; + } + else + { + filename = argv[6]; + fd = open(filename, O_RDONLY); + + if (fd == -1) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open print file %s: %s\n"), + filename, strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + } + + /* + * Sanitize the document title... + */ + + strlcpy(title, argv[3], sizeof(title)); + + if (sanitize_title) + { + /* + * Sanitize the title string so that we don't cause problems on + * the remote end... + */ + + char *ptr; + + for (ptr = title; *ptr; ptr ++) + if (!isalnum(*ptr & 255) && !isspace(*ptr & 255)) + *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, port, resource + 1, fd, mode, + username, title, copies, + banner, format, order, reserve, manual_copies, + timeout, contimeout); + + if (!status) + fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4])); + } + else + status = lpd_queue(hostname, port, resource + 1, fd, mode, + username, title, 1, + banner, format, order, reserve, 1, + timeout, contimeout); + + /* + * Remove the temporary file if necessary... + */ + + if (tmpfilename[0]) + unlink(tmpfilename); + + if (fd) + close(fd); + + /* + * 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 */ + int timeout, /* I - Seconds to wait for a response */ + 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 */ + + + /* + * Don't try to send commands if the job has been cancelled... + */ + + if (abort_job) + return (-1); + + /* + * 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); + + if (lpd_write(fd, buf, bytes) < bytes) + { + _cupsLangPrintError(_("ERROR: Unable to send LPD command")); + return (-1); + } + + /* + * Read back the status from the command and return it... + */ + + fputs("DEBUG: Reading command status...\n", stderr); + + alarm(timeout); + + if (recv(fd, &status, 1, 0) < 1) + { + _cupsLangPrintf(stderr, + _("WARNING: Remote host did not respond with command " + "status byte after %d seconds!\n"), timeout); + status = errno; + } + + 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(const char *hostname, /* I - Host to connect to */ + int port, /* I - Port to connect on */ + const char *printer, /* I - Printer/queue name */ + int print_fd, /* I - File to print */ + int mode, /* I - Print mode */ + const char *user, /* I - Requesting user */ + const 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 timeout, /* I - Timeout... */ + int contimeout) /* I - Connection timeout */ +{ + char localhost[255]; /* Local host name */ + int error; /* Error number */ + struct stat filestats; /* File statistics */ + int lport; /* LPD connection local port */ + int fd; /* LPD socket */ + char control[10240], /* LPD control 'file' */ + *cptr; /* Pointer into control file string */ + char status; /* Status byte from command */ + char portname[255]; /* Port name */ + int delay; /* Delay for retries... */ + char addrname[256]; /* Address name */ + http_addrlist_t *addrlist, /* Address list */ + *addr; /* Socket address */ + int snmp_fd, /* SNMP socket */ + have_supplies; /* Printer supports supply levels? */ + int copy; /* Copies written */ + time_t start_time; /* Time of first connect */ + int recoverable; /* Recoverable error shown? */ + size_t nbytes; /* Number of bytes written */ + off_t tbytes; /* Total bytes written */ + char buffer[32768]; /* Output buffer */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !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 */ + + /* + * Find the printer... + */ + + sprintf(portname, "%d", port); + + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); + + if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), + hostname); + return (CUPS_BACKEND_STOP); + } + + /* + * Remember when we started trying to connect to the printer... + */ + + recoverable = 0; + start_time = time(NULL); + + /* + * Loop forever trying to print the file... + */ + + while (!abort_job) + { + /* + * First try to reserve a port for this connection... + */ + + fprintf(stderr, "DEBUG: Connecting to %s:%d for printer %s\n", hostname, + port, printer); + _cupsLangPuts(stderr, _("INFO: Connecting to printer...\n")); + + for (lport = reserve == RESERVE_RFC1179 ? 732 : 1024, addr = addrlist, + delay = 5;; + addr = addr->next) + { + /* + * Stop if this job has been cancelled... + */ + + if (abort_job) + { + httpAddrFreeList(addrlist); + + return (CUPS_BACKEND_FAILED); + } + + /* + * Choose the next priviledged port... + */ + + if (!addr) + addr = addrlist; + + lport --; + + if (lport < 721 && reserve == RESERVE_RFC1179) + lport = 731; + else if (lport < 1) + lport = 1023; + +#ifdef HAVE_GETEUID + if (geteuid() || !reserve) +#else + if (getuid() || !reserve) +#endif /* HAVE_GETEUID */ + { + /* + * Just create a regular socket... + */ + + if ((fd = socket(addr->addr.addr.sa_family, SOCK_STREAM, 0)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to create socket")); + sleep(1); + + continue; + } + + lport = 0; + } + else + { + /* + * We're running as root and want to comply with RFC 1179. Reserve a + * priviledged lport between 721 and 731... + */ + + if ((fd = rresvport_af(&lport, addr->addr.addr.sa_family)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to reserve port")); + sleep(1); + + continue; + } + } + + /* + * Connect to the printer or server... + */ + + if (abort_job) + { + httpAddrFreeList(addrlist); + + close(fd); + + return (CUPS_BACKEND_FAILED); + } + + if (!connect(fd, &(addr->addr.addr), httpAddrLength(&(addr->addr)))) + break; + + error = errno; + close(fd); + + if (addr->next) + continue; + + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + httpAddrFreeList(addrlist); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (error == ECONNREFUSED || error == EHOSTDOWN || + error == EHOSTUNREACH) + { + if (contimeout && (time(NULL) - start_time) > contimeout) + { + _cupsLangPuts(stderr, _("ERROR: Printer not responding!\n")); + return (CUPS_BACKEND_FAILED); + } + + recoverable = 1; + + _cupsLangPrintf(stderr, + _("WARNING: recoverable: Network host \'%s\' is busy; " + "will retry in %d seconds...\n"), hostname, delay); + + sleep(delay); + + if (delay < 30) + delay += 5; + } + else if (error == EADDRINUSE) + { + /* + * Try on another port... + */ + + sleep(1); + } + else + { + recoverable = 1; + + fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(errno)); + _cupsLangPuts(stderr, + _("ERROR: recoverable: Unable to connect to printer; " + "will retry in 30 seconds...\n")); + sleep(30); + } + } + + if (recoverable) + { + /* + * If we've shown a recoverable error make sure the printer proxies + * have a chance to see the recovered message. Not pretty but + * necessary for now... + */ + + fputs("INFO: recovered: \n", stderr); + sleep(5); + } + + fputs("STATE: -connecting-to-device\n", stderr); + _cupsLangPuts(stderr, _("INFO: Connected to printer...\n")); + +#ifdef AF_INET6 + if (addr->addr.addr.sa_family == AF_INET6) + fprintf(stderr, "DEBUG: Connected to [%s]:%d (IPv6) (local port %d)...\n", + httpAddrString(&addr->addr, addrname, sizeof(addrname)), + ntohs(addr->addr.ipv6.sin6_port), lport); + else +#endif /* AF_INET6 */ + if (addr->addr.addr.sa_family == AF_INET) + fprintf(stderr, "DEBUG: Connected to %s:%d (IPv4) (local port %d)...\n", + httpAddrString(&addr->addr, addrname, sizeof(addrname)), + ntohs(addr->addr.ipv4.sin_port), lport); + + /* + * See if the printer supports SNMP... + */ + + if ((snmp_fd = _cupsSNMPOpen(addr->addr.addr.sa_family)) >= 0) + have_supplies = !backendSNMPSupplies(snmp_fd, &(addr->addr), NULL, NULL); + else + have_supplies = 0; + + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, &(addr->addr)); + + /* + * Next, open the print file and figure out its size... + */ + + if (print_fd) + { + /* + * Use the size from the print file... + */ + + if (fstat(print_fd, &filestats)) + { + httpAddrFreeList(addrlist); + close(fd); + + _cupsLangPrintError(_("ERROR: unable to stat print file")); + return (CUPS_BACKEND_FAILED); + } + + filestats.st_size *= manual_copies; + } + else + { + /* + * Use a "very large value" for the size so that the printer will + * keep printing until we close the connection... + */ + +#ifdef _LARGEFILE_SOURCE + filestats.st_size = (size_t)(999999999999.0); +#else + filestats.st_size = 2147483647; +#endif /* _LARGEFILE_SOURCE */ + } + + /* + * Send a job header to the printer, specifying no banner page and + * literal output... + */ + + if (lpd_command(fd, timeout, "\002%s\n", + printer)) /* Receive print job(s) */ + { + httpAddrFreeList(addrlist); + close(fd); + return (CUPS_BACKEND_FAILED); + } + + httpGetHostname(NULL, localhost, sizeof(localhost)); + + snprintf(control, sizeof(control), + "H%.31s\n" /* RFC 1179, Section 7.2 - host name <= 31 chars */ + "P%.31s\n" /* RFC 1179, Section 7.2 - user name <= 31 chars */ + "J%.99s\n", /* RFC 1179, Section 7.2 - job name <= 99 chars */ + localhost, user, title); + cptr = control + strlen(control); + + if (banner) + { + snprintf(cptr, sizeof(control) - (cptr - control), + "C%.31s\n" /* RFC 1179, Section 7.2 - class name <= 31 chars */ + "L%s\n", + localhost, user); + cptr += strlen(cptr); + } + + while (copies > 0) + { + snprintf(cptr, sizeof(control) - (cptr - control), "%cdfA%03d%.15s\n", + format, (int)getpid() % 1000, localhost); + cptr += strlen(cptr); + copies --; + } + + snprintf(cptr, sizeof(control) - (cptr - control), + "UdfA%03d%.15s\n" + "N%.131s\n", /* RFC 1179, Section 7.2 - sourcefile name <= 131 chars */ + (int)getpid() % 1000, localhost, title); + + fprintf(stderr, "DEBUG: Control file is:\n%s", control); + + if (order == ORDER_CONTROL_DATA) + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, &(addr->addr)); + + /* + * Send the control file... + */ + + if (lpd_command(fd, timeout, "\002%d cfA%03.3d%.15s\n", strlen(control), + (int)getpid() % 1000, localhost)) + { + httpAddrFreeList(addrlist); + close(fd); + + return (CUPS_BACKEND_FAILED); + } + + _cupsLangPrintf(stderr, _("INFO: Sending control file (%u bytes)\n"), + (unsigned)strlen(control)); + + if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1)) + { + status = errno; + _cupsLangPrintError(_("ERROR: Unable to write control file")); + } + else + { + alarm(timeout); + + if (read(fd, &status, 1) < 1) + { + _cupsLangPrintf(stderr, + _("WARNING: Remote host did not respond with control " + "status byte after %d seconds!\n"), timeout); + status = errno; + } + + alarm(0); + } + + if (status != 0) + _cupsLangPrintf(stderr, + _("ERROR: Remote host did not accept control file " + "(%d)\n"), status); + else + _cupsLangPuts(stderr, _("INFO: Control file sent successfully\n")); + } + else + status = 0; + + if (status == 0) + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, &(addr->addr)); + + /* + * Send the print file... + */ + + if (lpd_command(fd, timeout, "\003" CUPS_LLFMT " dfA%03.3d%.15s\n", + CUPS_LLCAST filestats.st_size, (int)getpid() % 1000, + localhost)) + { + httpAddrFreeList(addrlist); + close(fd); + + return (CUPS_BACKEND_FAILED); + } + + _cupsLangPrintf(stderr, +#ifdef HAVE_LONG_LONG + _("INFO: Sending data file (%lld bytes)\n"), +#else + _("INFO: Sending data file (%ld bytes)\n"), +#endif /* HAVE_LONG_LONG */ + CUPS_LLCAST filestats.st_size); + + tbytes = 0; + for (copy = 0; copy < manual_copies; copy ++) + { + lseek(print_fd, 0, SEEK_SET); + + while ((nbytes = read(print_fd, buffer, sizeof(buffer))) > 0) + { + _cupsLangPrintf(stderr, + _("INFO: Spooling LPR job, %.0f%% complete...\n"), + 100.0 * tbytes / filestats.st_size); + + if (lpd_write(fd, buffer, nbytes) < nbytes) + { + _cupsLangPrintError(_("ERROR: Unable to send print file to printer")); + break; + } + else + tbytes += nbytes; + } + } + + if (mode == MODE_STANDARD) + { + if (tbytes < filestats.st_size) + status = errno; + else if (lpd_write(fd, "", 1) < 1) + { + _cupsLangPrintError(_("ERROR: Unable to send trailing nul to printer")); + status = errno; + } + else + { + /* + * Read the status byte from the printer; if we can't read the byte + * back now, we should set status to "errno", however at this point + * we know the printer got the whole file and we don't necessarily + * want to requeue it over and over... + */ + + alarm(timeout); + + if (recv(fd, &status, 1, 0) < 1) + { + _cupsLangPrintf(stderr, + _("WARNING: Remote host did not respond with data " + "status byte after %d seconds!\n"), timeout); + status = 0; + } + + alarm(0); + } + } + else + status = 0; + + if (status != 0) + _cupsLangPrintf(stderr, + _("ERROR: Remote host did not accept data file (%d)\n"), + status); + else + _cupsLangPuts(stderr, _("INFO: Data file sent successfully\n")); + } + + if (status == 0 && order == ORDER_DATA_CONTROL) + { + /* + * Check for side-channel requests... + */ + + backendCheckSideChannel(snmp_fd, &(addr->addr)); + + /* + * Send control file... + */ + + if (lpd_command(fd, timeout, "\002%d cfA%03.3d%.15s\n", strlen(control), + (int)getpid() % 1000, localhost)) + { + httpAddrFreeList(addrlist); + close(fd); + + return (CUPS_BACKEND_FAILED); + } + + _cupsLangPrintf(stderr, _("INFO: Sending control file (%lu bytes)\n"), + (unsigned long)strlen(control)); + + if (lpd_write(fd, control, strlen(control) + 1) < (strlen(control) + 1)) + { + status = errno; + _cupsLangPrintError(_("ERROR: Unable to write control file")); + } + else + { + alarm(timeout); + + if (read(fd, &status, 1) < 1) + { + _cupsLangPrintf(stderr, + _("WARNING: Remote host did not respond with control " + "status byte after %d seconds!\n"), timeout); + status = errno; + } + + alarm(0); + } + + if (status != 0) + _cupsLangPrintf(stderr, + _("ERROR: Remote host did not accept control file " + "(%d)\n"), status); + else + _cupsLangPuts(stderr, _("INFO: Control file sent successfully\n")); + } + + /* + * Collect the final supply levels as needed... + */ + + if (have_supplies) + backendSNMPSupplies(snmp_fd, &(addr->addr), NULL, NULL); + + /* + * Close the socket connection and input file... + */ + + close(fd); + + if (status == 0) + { + httpAddrFreeList(addrlist); + + return (CUPS_BACKEND_OK); + } + + /* + * Waiting for a retry... + */ + + sleep(30); + } + + httpAddrFreeList(addrlist); + + /* + * If we get here, then the job has been cancelled... + */ + + return (CUPS_BACKEND_FAILED); +} + + +/* + * '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 */ + + + if (abort_job) + return (-1); + + 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_AF +/* + * 'rresvport_af()' - A simple implementation of rresvport_af(). + */ + +static int /* O - Socket or -1 on error */ +rresvport_af(int *port, /* IO - Port number to bind to */ + int family) /* I - Address family */ +{ + http_addr_t addr; /* Socket address */ + int fd; /* Socket file descriptor */ + + + /* + * Try to create an IPv4 socket... + */ + + if ((fd = socket(family, SOCK_STREAM, 0)) < 0) + return (-1); + + /* + * Initialize the address buffer... + */ + + memset(&addr, 0, sizeof(addr)); + addr.addr.sa_family = family; + + /* + * Try to bind the socket to a reserved port... + */ + + while (*port > 511) + { + /* + * Set the port number... + */ + +# ifdef AF_INET6 + if (family == AF_INET6) + addr.ipv6.sin6_port = htons(*port); + else +# endif /* AF_INET6 */ + addr.ipv4.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_AF */ + + +/* + * 'sigterm_handler()' - Handle 'terminate' signals that stop the backend. + */ + +static void +sigterm_handler(int sig) /* I - Signal */ +{ + (void)sig; /* remove compiler warnings... */ + + abort_job = 1; +} + + +/* + * End of "$Id$". + */ diff --git a/backend/network.c b/backend/network.c new file mode 100644 index 0000000000..0a4908a77e --- /dev/null +++ b/backend/network.c @@ -0,0 +1,294 @@ +/* + * "$Id$" + * + * Common network APIs for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * backendCheckSideChannel() - Check the side-channel for pending requests. + * backendNetworkSideCB() - Handle common network side-channel commands. + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" +#include +#ifdef __hpux +# include +#else +# include +#endif /* __hpux */ + + +/* + * 'backendCheckSideChannel()' - Check the side-channel for pending requests. + */ + + +void +backendCheckSideChannel( + int snmp_fd, /* I - SNMP socket */ + http_addr_t *addr) /* I - Address of device */ +{ + fd_set input; /* Select input set */ + struct timeval timeout; /* Select timeout */ + + + FD_ZERO(&input); + FD_SET(CUPS_SC_FD, &input); + + timeout.tv_sec = timeout.tv_usec = 0; + + if (select(CUPS_SC_FD + 1, &input, NULL, NULL, &timeout) > 0) + backendNetworkSideCB(-1, -1, snmp_fd, addr, 0); +} + + +/* + * 'backendNetworkSideCB()' - Handle common network side-channel commands. + */ + +int /* O - -1 on error, 0 on success */ +backendNetworkSideCB( + int print_fd, /* I - Print file or -1 */ + int device_fd, /* I - Device file or -1 */ + int snmp_fd, /* I - SNMP socket */ + http_addr_t *addr, /* I - Address of device */ + int use_bc) /* I - Use back-channel data? */ +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + const char *device_id; /* 1284DEVICEID env var */ + + + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + return (-1); + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + /* + * Our sockets disable the Nagle algorithm and data is sent immediately. + */ + + if (device_fd < 0) + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + else if (backendDrainOutput(print_fd, device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else + status = CUPS_SC_STATUS_OK; + + datalen = 0; + break; + + case CUPS_SC_CMD_GET_BIDI : + status = CUPS_SC_STATUS_OK; + data[0] = use_bc; + datalen = 1; + break; + + case CUPS_SC_CMD_SNMP_GET : + case CUPS_SC_CMD_SNMP_GET_NEXT : + fprintf(stderr, "DEBUG: CUPS_SC_CMD_SNMP_%s: %d (%s)\n", + command == CUPS_SC_CMD_SNMP_GET ? "GET" : "GET_NEXT", datalen, + data); + + if (datalen < 2) + { + status = CUPS_SC_STATUS_BAD_MESSAGE; + datalen = 0; + break; + } + + if (snmp_fd >= 0) + { + cups_snmp_t packet; /* Packet from printer */ + + + if (!_cupsSNMPStringToOID(data, packet.object_name, CUPS_SNMP_MAX_OID)) + { + status = CUPS_SC_STATUS_BAD_MESSAGE; + datalen = 0; + break; + } + + status = CUPS_SC_STATUS_IO_ERROR; + datalen = 0; + + if (_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), + command == CUPS_SC_CMD_SNMP_GET ? + CUPS_ASN1_GET_REQUEST : + CUPS_ASN1_GET_NEXT_REQUEST, 1, + packet.object_name)) + { + if (_cupsSNMPRead(snmp_fd, &packet, 1.0)) + { + char *dataptr; /* Pointer into data */ + int i; /* Looping var */ + + + if (!_cupsSNMPOIDToString(packet.object_name, data, sizeof(data))) + { + fputs("DEBUG: Bad OID returned!\n", stderr); + break; + } + + datalen = (int)strlen(data) + 1; + dataptr = data + datalen; + + switch (packet.object_type) + { + case CUPS_ASN1_BOOLEAN : + snprintf(dataptr, sizeof(data) - (dataptr - data), "%d", + packet.object_value.boolean); + datalen += (int)strlen(dataptr); + break; + + case CUPS_ASN1_INTEGER : + snprintf(dataptr, sizeof(data) - (dataptr - data), "%d", + packet.object_value.integer); + datalen += (int)strlen(dataptr); + break; + + case CUPS_ASN1_BIT_STRING : + case CUPS_ASN1_OCTET_STRING : + if (packet.object_value.string.num_bytes < 0) + i = 0; + else if (packet.object_value.string.num_bytes < + (sizeof(data) - (dataptr - data))) + i = packet.object_value.string.num_bytes; + else + i = (int)(sizeof(data) - (dataptr - data)); + + memcpy(dataptr, packet.object_value.string.bytes, i); + + datalen += i; + break; + + case CUPS_ASN1_OID : + _cupsSNMPOIDToString(packet.object_value.oid, dataptr, + sizeof(data) - (dataptr - data)); + datalen += (int)strlen(dataptr); + break; + + case CUPS_ASN1_HEX_STRING : + for (i = 0; + i < packet.object_value.string.num_bytes && + dataptr < (data + sizeof(data) - 3); + i ++, dataptr += 2) + sprintf(dataptr, "%02X", + packet.object_value.string.bytes[i]); + datalen += (int)strlen(dataptr); + break; + + case CUPS_ASN1_COUNTER : + snprintf(dataptr, sizeof(data) - (dataptr - data), "%d", + packet.object_value.counter); + datalen += (int)strlen(dataptr); + break; + + case CUPS_ASN1_GAUGE : + snprintf(dataptr, sizeof(data) - (dataptr - data), "%u", + packet.object_value.gauge); + datalen += (int)strlen(dataptr); + break; + + case CUPS_ASN1_TIMETICKS : + snprintf(dataptr, sizeof(data) - (dataptr - data), "%u", + packet.object_value.timeticks); + datalen += (int)strlen(dataptr); + break; + + default : + fprintf(stderr, "DEBUG: Unknown OID value type %02X!\n", + packet.object_type); + + case CUPS_ASN1_NULL_VALUE : + dataptr[0] = '\0'; + break; + } + + fprintf(stderr, "DEBUG: Returning %s %s\n", data, data + datalen); + + status = CUPS_SC_STATUS_OK; + } + else + fputs("DEBUG: SNMP read error...\n", stderr); + } + else + fputs("DEBUG: SNMP write error...\n", stderr); + break; + } + + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + + case CUPS_SC_CMD_GET_DEVICE_ID : + if (snmp_fd >= 0) + { + cups_snmp_t packet; /* Packet from printer */ + static const int ppmPrinterIEEE1284DeviceId[] = + { CUPS_OID_ppmPrinterIEEE1284DeviceId,1,-1 }; + + + status = CUPS_SC_STATUS_IO_ERROR; + datalen = 0; + + if (_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), + CUPS_ASN1_GET_REQUEST, 1, + ppmPrinterIEEE1284DeviceId)) + { + if (_cupsSNMPRead(snmp_fd, &packet, 1.0) && + packet.object_type == CUPS_ASN1_OCTET_STRING) + { + strlcpy(data, (char *)packet.object_value.string.bytes, + sizeof(data)); + datalen = (int)strlen(data); + status = CUPS_SC_STATUS_OK; + } + } + + break; + } + + if ((device_id = getenv("1284DEVICEID")) != NULL) + { + strlcpy(data, device_id, sizeof(data)); + datalen = (int)strlen(data); + status = CUPS_SC_STATUS_OK; + break; + } + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/pap.c b/backend/pap.c new file mode 100644 index 0000000000..0071e3da1e --- /dev/null +++ b/backend/pap.c @@ -0,0 +1,1696 @@ +/* +* "$Id$" +* +* Copyright 2004-2008 Apple Inc. All rights reserved. +* +* IMPORTANT: This Apple software is supplied to you by Apple Computer, +* Inc. ("Apple") in consideration of your agreement to the following +* terms, and your use, installation, modification or redistribution of +* this Apple software constitutes acceptance of these terms. If you do +* not agree with these terms, please do not use, install, modify or +* redistribute this Apple software. +* +* In consideration of your agreement to abide by the following terms, and +* subject to these terms, Apple grants you a personal, non-exclusive +* license, under AppleÕs copyrights in this original Apple software (the +* "Apple Software"), to use, reproduce, modify and redistribute the Apple +* Software, with or without modifications, in source and/or binary forms; +* provided that if you redistribute the Apple Software in its entirety and +* without modifications, you must retain this notice and the following +* text and disclaimers in all such redistributions of the Apple Software. +* Neither the name, trademarks, service marks or logos of Apple Computer, +* Inc. may be used to endorse or promote products derived from the Apple +* Software without specific prior written permission from Apple. Except +* as expressly stated in this notice, no other rights or licenses, express +* or implied, are granted by Apple herein, including but not limited to +* any patent rights that may be infringed by your derivative works or by +* other works in which the Apple Software may be incorporated. +* +* The Apple Software is provided by Apple on an "AS IS" basis. APPLE +* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +* +* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* +* This program implements the Printer Access Protocol (PAP) on top of AppleTalk +* Transaction Protocol (ATP). If it were to use the blocking pap functions of +* the AppleTalk library it would need seperate threads for reading, writing +* and status. +* +* Contents: +* +* main() - Send a file to the specified Appletalk printer. +* listDevices() - List all LaserWriter printers in the local zone. +* printFile() - Print file. +* papOpen() - Open a pap session to a printer. +* papClose() - Close a pap session. +* papWrite() - Write bytes to a printer. +* papCloseResp() - Send a pap close response. +* papSendRequest() - Fomrat and send a pap packet. +* papCancelRequest() - Cancel a pending pap request. +* sidechannel_request() - Handle side-channel requests. +* statusUpdate() - Print printer status to stderr. +* parseUri() - Extract the print name and zone from a uri. +* addPercentEscapes() - Encode a string with percent escapes. +* removePercentEscapes - Remove percent escape sequences from a string. +* nbptuple_compare() - Compare routine for qsort. +* okayToUseAppleTalk() - Returns true if AppleTalk is available and enabled. +* packet_name() - Returns packet name string. +* connectTimeout() - Returns the connect timeout preference value. +* signalHandler() - handle SIGINT to close the session before quiting. +*/ + +/* + * This backend uses deprecated APIs for AppleTalk; we know this, so + * silence any warnings about it... + */ + +#ifdef MAC_OS_X_VERSION_MIN_REQUIRED +# undef MAC_OS_X_VERSION_MIN_REQUIRED +#endif /* MAX_OS_X_VERSION_MIN_REQUIRED */ +#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_0 + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_APPLETALK_AT_PROTO_H +# include +#else +/* These definitions come from at_proto.h... */ +# define ZIP_DEF_INTERFACE NULL +enum { RUNNING, NOTLOADED, LOADED, OTHERERROR }; + +extern int atp_abort(int fd, at_inet_t *dest, u_short tid); +extern int atp_close(int fd); +extern int atp_getreq(int fd, at_inet_t *src, char *buf, int *len, int *userdata, + int *xo, u_short *tid, u_char *bitmap, int nowait); +extern int atp_getresp(int fd, u_short *tid, at_resp_t *resp); +extern int atp_look(int fd); +extern int atp_open(at_socket *sock); +extern int atp_sendreq(int fd, at_inet_t *dest, char *buf, int len, + int userdata, int xo, int xo_relt, u_short *tid, + at_resp_t *resp, at_retry_t *retry, int nowait); +extern int atp_sendrsp(int fd, at_inet_t *dest, int xo, u_short tid, + at_resp_t *resp); +extern int checkATStack(); +extern int nbp_lookup(at_entity_t *entity, at_nbptuple_t *buf, int max, + at_retry_t *retry); +extern int nbp_make_entity(at_entity_t *entity, char *obj, char *type, + char *zone); +extern int zip_getmyzone(char *ifName, at_nvestr_t *zone); +#endif /* HAVE_APPLETALK_AT_PROTO_H */ + +#include +#include +#include + +/* Defines */ +#define MAX_PRINTERS 500 /* Max number of printers we can lookup */ +#define PAP_CONNID 0 +#define PAP_TYPE 1 +#define PAP_EOF 2 + +#define CONNID_OF(p) (((u_char *)&p)[0]) +#define TYPE_OF(p) (((u_char *)&p)[1]) +#define SEQUENCE_NUM(p) (((u_char *)&p)[2]) +#define IS_PAP_EOF(p) (((u_char *)&p)[2]) + +#ifndef true +#define true 1 +#define false 0 +#endif + +/* Globals */ +int gSockfd = 0; /* Socket descriptor */ +at_inet_t gSessionAddr = { 0 }; /* Address of the session responding socket */ +u_char gConnID = 0; /* PAP session connection id */ +u_short gSendDataID = 0; /* Transaction id of pending send-data request */ +u_short gTickleID = 0; /* Transaction id of outstanding tickle request*/ +int gWaitEOF = false; /* Option: wait for a remote's EOF */ +int gStatusInterval= 5; /* Option: 0=off else seconds between status requests*/ +int gErrorlogged = false; /* If an error was logged don't send any more INFO messages */ +int gDebug = 0; /* Option: emit debugging info */ + +/* Local functions */ +static int listDevices(void); +static int printFile(char* name, char* type, char* zone, int fdin, int fdout, + int fderr, int copies, int argc); +static int papOpen(at_nbptuple_t* tuple, u_char* connID, int* fd, + at_inet_t* pap_to, u_char* flowQuantum); +static int papClose(); +static int papWrite(int sockfd, at_inet_t* dest, u_short tid, u_char connID, + u_char flowQuantum, char* data, int len, int eof); +static int papCloseResp(int sockfd, at_inet_t* dest, int xo, u_short tid, + u_char connID); +static int papSendRequest(int sockfd, at_inet_t* dest, u_char connID, + int function, u_char bitmap, int xo, int seqno); +static int papCancelRequest(int sockfd, u_short tid); +static void sidechannel_request(); +static void statusUpdate(char* status, u_char statusLen); +static int parseUri(const char* argv0, char* name, char* type, char* zone); +static int addPercentEscapes(const char* src, char* dst, int dstMax); +static int removePercentEscapes(const char* src, char* dst, int dstMax); +static int nbptuple_compare(const void *p1, const void *p2); +static int okayToUseAppleTalk(void); +static const char *packet_name(u_char x); +static int connectTimeout(void); +static void signalHandler(int sigraised); + + +/*! + * @function main + * @abstract Send a file to the specified AppleTalk PAP address. + * + * Usage: printer-uri job-id user title copies options [file] + * + * @param argc # of arguments + * @param argv array of arguments + * + * @result A non-zero return value for errors + */ +int main (int argc, const char * argv[]) +{ + int err = 0; + FILE *fp; /* Print file */ + int copies; /* Number of copies to print */ + char name[NBP_NVE_STR_SIZE + 1]; /* +1 for a nul */ + char type[NBP_NVE_STR_SIZE + 1]; /* +1 for a nul */ + char zone[NBP_NVE_STR_SIZE + 1]; /* +1 for a nul */ + + /* Make sure status messages are not buffered... */ + setbuf(stderr, NULL); + + if (argc == 1 || (argc == 2 && strcmp(argv[1], "-discover") == 0)) + { + listDevices(); + + return 0; + } + + if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + if (argc == 6) + { + fp = stdin; + copies = 1; + } + else + { + fprintf(stderr, "DEBUG: opening print file \"%s\"\n", argv[6]); + + /* Try to open the print file... */ + if ((fp = fopen(argv[6], "rb")) == NULL) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open print file \"%s\": %s\n"), + argv[6], strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + + copies = atoi(argv[4]); + } + + /* Extract the device name and options from the URI... */ + parseUri(cupsBackendDeviceURI((char **)argv), name, type, zone); + + err = printFile(name, type, zone, fileno(fp), STDOUT_FILENO, STDERR_FILENO, copies, argc); + + if (fp != stdin) + fclose(fp); + + /* Only clear the last status if there wasn't an error */ + if (err == noErr && !gErrorlogged) + fprintf(stderr, "INFO:\n"); + + return err; +} + + +/*! + * @function listDevices + * @abstract Print a list of all LaserWriter type devices registered in the default zone. + * + * @result A non-zero return value for errors + */ +static int listDevices(void) +{ + int i; + int numberFound; + + at_nvestr_t at_zone; + at_entity_t entity; + at_nbptuple_t buf[MAX_PRINTERS]; + at_retry_t retry; + char name[NBP_NVE_STR_SIZE+1]; + char encodedName[(3 * NBP_NVE_STR_SIZE) + 1]; + char zone[NBP_NVE_STR_SIZE+1]; + char encodedZone[(3 * NBP_NVE_STR_SIZE) + 1]; + + /* Make sure it's okay to use appletalk */ + if (!okayToUseAppleTalk()) + { + _cupsLangPuts(stderr, _("INFO: AppleTalk disabled in System Preferences\n")); + return -1; /* Network is down */ + } + + if (zip_getmyzone(ZIP_DEF_INTERFACE, &at_zone)) + { + _cupsLangPrintError(_("ERROR: Unable to get default AppleTalk zone")); + return -2; + } + + memcpy(zone, at_zone.str, MIN(at_zone.len, sizeof(zone)-1)); + zone[MIN(at_zone.len, sizeof(zone)-1)] = '\0'; + + _cupsLangPrintf(stderr, _("INFO: Using default AppleTalk zone \"%s\"\n"), + zone); + + addPercentEscapes(zone, encodedZone, sizeof(encodedZone)); + + /* Look up all the printers in our zone */ + nbp_make_entity(&entity, "=", "LaserWriter", zone); + retry.retries = 1; + retry.interval = 1; + retry.backoff = 1; + + if ((numberFound = nbp_lookup(&entity, buf, MAX_PRINTERS, &retry)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to lookup AppleTalk printers")); + return numberFound; + } + + if (numberFound >= MAX_PRINTERS) + _cupsLangPrintf(stderr, + _("WARNING: Adding only the first %d printers found"), + MAX_PRINTERS); + + /* Not required but sort them so they look nice */ + qsort(buf, numberFound, sizeof(at_nbptuple_t), nbptuple_compare); + + for (i = 0; i < numberFound; i++) + { + memcpy(name, buf[i].enu_entity.object.str, MIN(buf[i].enu_entity.object.len, sizeof(name)-1)); + name[MIN(buf[i].enu_entity.object.len, sizeof(name)-1)] = '\0'; + + if (addPercentEscapes(name, encodedName, sizeof(encodedName)) == 0) + { + /* Each line is of the form: "class URI "make model" "info" */ + char make_model[128], /* Make and model */ + *ptr; + + + if ((ptr = strchr(name, ' ')) != NULL) + { + /* + * If the printer name contains spaces, it is probably a make and + * model... + */ + + if (!strncmp(name, "ET00", 4)) + { + /* + * Drop leading ethernet address info... + */ + + strlcpy(make_model, ptr + 1, sizeof(make_model)); + } + else + strlcpy(make_model, name, sizeof(make_model)); + } + else + strcpy(make_model, "Unknown"); + + printf("network pap://%s/%s/LaserWriter \"%s\" \"%s AppleTalk\"\n", + encodedZone, encodedName, make_model, name); + } + } + return numberFound; +} + + +/*! + * @function printFile + * @abstract Open a PAP session and send the data from the input socket to the printer. + * + * @param name NBP name + * @param zone NBP zone + * @param type NBP type + * @param fdin File descriptor to read data from + * @param fdout File descriptor to write printer responses to + * @param fderr File descriptor to write printer status to + * @param copies # of copies to send (in case in the converter couldn't handle this for us). + * @param argc # of command line arguments. + * + * @result A non-zero return value for errors + */ +static int printFile(char* name, char* type, char* zone, int fdin, int fdout, int fderr, int copies, int argc) +{ + int err; + int rc; + int val; + int len, i; + + char fileBuffer[4096]; /* File buffer */ + int fileBufferNbytes; + off_t fileTbytes; + int fileEOFRead; + int fileEOFSent; + + char sockBuffer[4096 + 1]; /* Socket buffer with room for nul */ + char atpReqBuf[AT_PAP_DATA_SIZE]; + fd_set readSet; + int use_sidechannel; /* Use side channel? */ + + at_nbptuple_t tuple; + at_inet_t sendDataAddr; + at_inet_t src; + at_resp_t resp; + int userdata, xo = 0, reqlen; + u_short tid; + u_char bitmap; + int maxfdp1, + nbp_failures = 0; + struct timeval timeout, *timeoutPtr; + u_char flowQuantum = 1; + time_t now, + start_time, + elasped_time, + sleep_time, + connect_timeout = -1, + nextStatusTime = 0; + at_entity_t entity; + at_retry_t retry; + +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + /* + * Test the side channel descriptor before calling papOpen() since it may open + * an unused fd 4 (a.k.a. CUPS_SC_FD)... + */ + + FD_ZERO(&readSet); + FD_SET(CUPS_SC_FD, &readSet); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + if ((select(CUPS_SC_FD+1, &readSet, NULL, NULL, &timeout)) >= 0) + use_sidechannel = 1; + else + use_sidechannel = 0; + + /* try to find our printer */ + if ((err = nbp_make_entity(&entity, name, type, zone)) != noErr) + { + _cupsLangPrintError(_("ERROR: Unable to make AppleTalk address")); + goto Exit; + } + + /* + * Remember when we started looking for the printer. + */ + + start_time = time(NULL); + + retry.interval = 1; + retry.retries = 5; + retry.backoff = 0; + + fprintf(stderr, "STATE: +connecting-to-device\n"); + + /* Loop forever trying to get an open session with the printer. */ + for (;;) + { + /* Make sure it's okay to use appletalk */ + if (okayToUseAppleTalk()) + { + /* Clear this printer-state-reason in case we've set it */ + fprintf(stderr, "STATE: -apple-appletalk-disabled-warning\n"); + + /* Resolve the name into an address. Returns the number found or an error */ + if ((err = nbp_lookup(&entity, &tuple, 1, &retry)) > 0) + { + if (err > 1) + fprintf(stderr, "DEBUG: Found more than one printer with the name \"%s\"\n", name); + + if (nbp_failures) + { + fprintf(stderr, "STATE: -apple-nbp-lookup-warning\n"); + nbp_failures = 0; + } + + /* Open a connection to the device */ + if ((err = papOpen(&tuple, &gConnID, &gSockfd, &gSessionAddr, &flowQuantum)) == 0) + break; + + _cupsLangPrintf(stderr, _("WARNING: Unable to open \"%s:%s\": %s\n"), + name, zone, strerror(err)); + } + else + { + /* It's not unusual to have to call nbp_lookup() twice before it's sucessful... */ + if (++nbp_failures > 2) + { + retry.interval = 2; + retry.retries = 3; + fprintf(stderr, "STATE: +apple-nbp-lookup-warning\n"); + _cupsLangPuts(stderr, _("WARNING: Printer not responding\n")); + } + } + } + else + { + fprintf(stderr, "STATE: +apple-appletalk-disabled-warning\n"); + _cupsLangPuts(stderr, + _("INFO: AppleTalk disabled in System Preferences.\n")); + } + + elasped_time = time(NULL) - start_time; + + if (connect_timeout == -1) + connect_timeout = connectTimeout(); + + if (connect_timeout && elasped_time > connect_timeout) + { + _cupsLangPuts(stderr, _("ERROR: Printer not responding\n")); + err = ETIMEDOUT; + goto Exit; /* Waiting too long... */ + } + else if (elasped_time < (30 * 60)) + sleep_time = 10; /* Waiting < 30 minutes */ + else if (elasped_time < (24 * 60 * 60)) + sleep_time = 30; /* Waiting < 24 hours */ + else + sleep_time = 60; /* Waiting > 24 hours */ + + fprintf(stderr, "DEBUG: sleeping %d seconds...\n", (int)sleep_time); + sleep(sleep_time); + } + + fprintf(stderr, "STATE: -connecting-to-device\n"); + + /* + * Now that we are connected to the printer ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... if we are printing data from a file then catch the + * signal so we can send a PAP Close packet (otherwise you can't cancel + * raw jobs...) + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, (argc < 7) ? SIG_IGN : signalHandler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = (argc < 7) ? SIG_IGN : signalHandler; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, (argc < 7) ? SIG_IGN : signalHandler); + +#ifdef DEBUG + /* Makes debugging easier; otherwise printer will be busy for several minutes */ + signal(SIGINT, signalHandler); +#endif /* DEBUG */ + +#endif /* HAVE_SIGSET */ + + _cupsLangPuts(stderr, _("INFO: Sending data\n")); + + sendDataAddr = tuple.enu_addr; + + /* Start the tickle packets and set a timeout alarm */ + if ((err = papSendRequest(gSockfd, &gSessionAddr, gConnID, AT_PAP_TYPE_TICKLE, 0, false, false)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to send PAP tickle request")); + goto Exit; + } + signal(SIGALRM, signalHandler); + alarm(PAP_TIMEOUT); + + /* Prime the pump with an initial send-data packet */ + if ((err = papSendRequest(gSockfd, &gSessionAddr, gConnID, AT_PAP_TYPE_SEND_DATA, 0xFF, true, true)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to send initial PAP send data request")); + goto Exit; + } + + /* Set non-blocking mode on our data source descriptor */ + val = fcntl(fdin, F_GETFL, 0); + fcntl(fdin, F_SETFL, val | O_NONBLOCK); + + fileBufferNbytes = 0; + fileTbytes = 0; + fileEOFRead = fileEOFSent = false; + + maxfdp1 = MAX(fdin, gSockfd) + 1; + + if (use_sidechannel && CUPS_SC_FD >= maxfdp1) + maxfdp1 = CUPS_SC_FD + 1; + + if (gStatusInterval != 0) + { + timeout.tv_usec = 0; + nextStatusTime = time(NULL) + gStatusInterval; + timeoutPtr = &timeout; + } + else + timeoutPtr = NULL; + + + for (;;) + { + /* Set up our descriptors for the select */ + FD_ZERO(&readSet); + FD_SET(gSockfd, &readSet); + + if (fileBufferNbytes == 0 && fileEOFRead == false) + FD_SET(fdin, &readSet); + + if (use_sidechannel) + FD_SET(CUPS_SC_FD, &readSet); + + /* Set the select timeout value based on the next status interval */ + if (gStatusInterval != 0) + { + now = time(NULL); + timeout.tv_sec = (nextStatusTime > now) ? nextStatusTime - now : 1; + } + + /* Wait here for something interesting to happen */ + if ((err = select(maxfdp1, &readSet, 0, 0, timeoutPtr)) < 0) + { + _cupsLangPrintError(_("ERROR: select() failed")); + break; + } + + if (err == 0 || (gStatusInterval != 0 && time(NULL) >= nextStatusTime)) + { + /* Time to send a status request */ + if ((err = papSendRequest(gSockfd, &tuple.enu_addr, 0, AT_PAP_TYPE_SEND_STATUS, 0x01, false, false)) < 0) + _cupsLangPrintError(_("WARNING: Unable to send PAP status request")); + + if (gStatusInterval) + nextStatusTime = time(NULL) + gStatusInterval; + } + + /* + * Check if we have a side-channel request ready... + */ + + if (use_sidechannel && FD_ISSET(CUPS_SC_FD, &readSet)) + sidechannel_request(); + + /* Was there an event on the input stream? */ + if (FD_ISSET(fdin, &readSet)) + { + FD_CLR(fdin, &readSet); + + assert(fileBufferNbytes == 0); + fileBufferNbytes = read(fdin, fileBuffer, MIN(sizeof(fileBuffer), AT_PAP_DATA_SIZE * flowQuantum)); + if (fileBufferNbytes == 0) + fileEOFRead = true; + + if (fileEOFSent == false && fileBufferNbytes >= 0 && gSendDataID != 0) + { + fprintf(stderr, "DEBUG: -> PAP_DATA %d bytes %s\n", fileBufferNbytes, fileEOFRead ? "with EOF" : ""); + papWrite(gSockfd, &sendDataAddr, gSendDataID, gConnID, flowQuantum, fileBuffer, fileBufferNbytes, fileEOFRead); + + fileTbytes += fileBufferNbytes; + if (argc > 6 && !gErrorlogged) + fprintf(stderr, "DEBUG: Sending print file, %qd bytes\n", (off_t)fileTbytes); + + fileBufferNbytes = 0; + gSendDataID = 0; + if (fileEOFRead) + { + fileEOFSent = true; + if (gWaitEOF == false || fileTbytes == 0) + { + err = 0; + goto Exit; + } + } + } + } + + /* Was there an event on the output stream? */ + if (FD_ISSET(gSockfd, &readSet)) + { + if ((rc = atp_look(gSockfd)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to look for PAP response")); + break; + } + + if (rc > 0) + { + /* It's an ATP response */ + resp.resp[0].iov_base = sockBuffer; + resp.resp[0].iov_len = sizeof(sockBuffer) - 1; + resp.bitmap = 0x01; + + if ((err = atp_getresp(gSockfd, &tid, &resp)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to get PAP response")); + break; + } + userdata = resp.userdata[0]; + } + else + { + /* It's an ATP request */ + reqlen = sizeof(atpReqBuf); + if ((err = atp_getreq(gSockfd, &src, atpReqBuf, &reqlen, &userdata, &xo, &tid, &bitmap, 0)) < 0) + { + _cupsLangPrintError(_("ERROR: Unable to get PAP request")); + break; + } + } + + fprintf(stderr, "DEBUG: <- %s\n", packet_name(TYPE_OF(userdata))); + + switch (TYPE_OF(userdata)) + { + case AT_PAP_TYPE_SEND_STS_REPLY: /* Send-Status-Reply packet */ + if (resp.bitmap & 1) + { + char *iov_base = (char *)resp.resp[0].iov_base; + statusUpdate(&iov_base[5], iov_base[4]); + } + break; + + case AT_PAP_TYPE_SEND_DATA: /* Send-Data packet */ + sendDataAddr.socket = src.socket; + gSendDataID = tid; + OSReadBigInt16(&SEQUENCE_NUM(userdata), 0); + + if ((fileBufferNbytes > 0 || fileEOFRead) && fileEOFSent == false) + { + fprintf(stderr, "DEBUG: -> PAP_DATA %d bytes %s\n", fileBufferNbytes, fileEOFRead ? "with EOF" : ""); + papWrite(gSockfd, &sendDataAddr, gSendDataID, gConnID, flowQuantum, fileBuffer, fileBufferNbytes, fileEOFRead); + + fileTbytes += fileBufferNbytes; + if (argc > 6 && !gErrorlogged) + fprintf(stderr, "DEBUG: Sending print file, %qd bytes\n", (off_t)fileTbytes); + + fileBufferNbytes = 0; + gSendDataID = 0; + if (fileEOFRead) + { + fileEOFSent = true; + if (gWaitEOF == false) + { + err = 0; + goto Exit; + } + } + } + break; + + case AT_PAP_TYPE_DATA: /* Data packet */ + for (len=0, i=0; i < ATP_TRESP_MAX; i++) + { + if (resp.bitmap & (1 << i)) + len += resp.resp[i].iov_len; + } + + fprintf(stderr, "DEBUG: <- PAP_DATA %d bytes %s\n", len, IS_PAP_EOF(userdata) ? "with EOF" : ""); + + if (len > 0) + { + char *pLineBegin, *pCommentEnd, *pChar; + char *logLevel; + char logstr[512]; + int logstrlen; + + cupsBackChannelWrite(sockBuffer, len, 1.0); + + sockBuffer[len] = '\0'; /* We always reserve room for the nul so we can use strstr() below*/ + pLineBegin = sockBuffer; + + /* If there are PostScript status comments in the buffer log them. + * + * This logic shouldn't be in the backend but until we get backchannel + * data in CUPS 1.2 it has to live here. + */ + while (pLineBegin < sockBuffer + len && + (pLineBegin = strstr(pLineBegin, "%%[")) != NULL && + (pCommentEnd = strstr(pLineBegin, "]%%")) != NULL) + { + pCommentEnd += 3; /* Skip past "]%%" */ + *pCommentEnd = '\0'; /* There's always room for the nul */ + + /* Strip the CRs & LFs before writing it to stderr */ + for (pChar = pLineBegin; pChar < pCommentEnd; pChar++) + if (*pChar == '\r' || *pChar == '\n') + *pChar = ' '; + + if (strncasecmp(pLineBegin, "%%[ Error:", 10) == 0) + { + /* logLevel should be "ERROR" here but this causes PrintCenter + * to pause the queue which in turn clears this error, which + * restarts the job. So the job ends up in an infinite loop with + * the queue being held/un-held. Just make it DEBUG for now until + * we fix notifications later. + */ + logLevel = "DEBUG"; + gErrorlogged = true; + } + else if (strncasecmp(pLineBegin, "%%[ Flushing", 12) == 0) + logLevel = "DEBUG"; + else + logLevel = "INFO"; + + if ((logstrlen = snprintf(logstr, sizeof(logstr), "%s: %s\n", logLevel, pLineBegin)) >= sizeof(logstr)) + { + /* If the string was trucnated make sure it has a linefeed before the nul */ + logstrlen = sizeof(logstr) - 1; + logstr[logstrlen - 1] = '\n'; + } + + write(fderr, logstr, logstrlen); + + pLineBegin = pCommentEnd + 1; + } + } + + if (IS_PAP_EOF(userdata) != 0) + { + /* If this is EOF then were we expecting it? */ + if (fileEOFSent == true) + goto Exit; + else + { + _cupsLangPuts(stderr, _("WARNING: Printer sent unexpected EOF\n")); + } + } + + if ((err = papSendRequest(gSockfd, &gSessionAddr, gConnID, AT_PAP_TYPE_SEND_DATA, 0xFF, true, true)) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Error %d sending PAPSendData request: %s\n"), + err, strerror(errno)); + goto Exit; + } + break; + + case AT_PAP_TYPE_TICKLE: /* Tickle packet */ + break; + + case AT_PAP_TYPE_CLOSE_CONN: /* Close-Connection packet */ + /* We shouldn't normally see this. */ + papCloseResp(gSockfd, &gSessionAddr, xo, tid, gConnID); + + /* If this is EOF then were we expecting it? */ + if (fileEOFSent == true) + { + _cupsLangPuts(stderr, _("WARNING: Printer sent unexpected EOF\n")); + } + else + { + _cupsLangPuts(stderr, _("ERROR: Printer sent unexpected EOF\n")); + } + goto Exit; + break; + + case AT_PAP_TYPE_OPEN_CONN: /* Open-Connection packet */ + case AT_PAP_TYPE_OPEN_CONN_REPLY: /* Open-Connection-Reply packet */ + case AT_PAP_TYPE_SEND_STATUS: /* Send-Status packet */ + case AT_PAP_TYPE_CLOSE_CONN_REPLY: /* Close-Connection-Reply packet */ + _cupsLangPrintf(stderr, _("WARNING: Unexpected PAP packet of type %d\n"), + TYPE_OF(userdata)); + break; + + default: + _cupsLangPrintf(stderr, _("WARNING: Unknown PAP packet of type %d\n"), + TYPE_OF(userdata)); + break; + } + + if (CONNID_OF(userdata) == gConnID) + { + /* Reset tickle timer */ + alarm(0); + alarm(PAP_TIMEOUT); + } + } + } + +Exit: + /* + * Close the socket and return... + */ + papClose(); + + return err; +} + + +#pragma mark - +/*! + * @function papOpen + * @abstract Open a pap session to a printer. + * + * @param tuple nbp address of printer + * @param connID returned pap connection id + * @param fd returned socket descriptor + * @param sessionAddr returned session address + * @param flowQuantum returned flow quantum (usually 8) + * + * @result A non-zero return value for errors + */ +static int papOpen(at_nbptuple_t* tuple, u_char* connID, int* fd, + at_inet_t* sessionAddr, u_char* flowQuantum) +{ + int result, + open_result, + userdata; + time_t tm, + waitTime; + char data[10], + rdata[ATP_DATA_SIZE]; + u_char *puserdata; + at_socket socketfd; + at_resp_t resp; + at_retry_t retry; + + result = 0; + socketfd = 0; + puserdata = (u_char *)&userdata; + + _cupsLangPuts(stderr, _("INFO: Opening connection\n")); + + if ((*fd = atp_open(&socketfd)) < 0) + return -1; + + /* + * Build the open connection request packet. + */ + + tm = time(NULL); + srand(tm); + + *connID = (rand()&0xff) | 0x01; + puserdata[0] = *connID; + puserdata[1] = AT_PAP_TYPE_OPEN_CONN; + puserdata[2] = 0; + puserdata[3] = 0; + + retry.interval = 2; + retry.retries = 5; + + resp.bitmap = 0x01; + resp.resp[0].iov_base = rdata; + resp.resp[0].iov_len = sizeof(rdata); + + data[0] = socketfd; + data[1] = 8; + + for (;;) + { + waitTime = time(NULL) - tm; + OSWriteBigInt16(&data[2], 0, (u_short)waitTime); + + fprintf(stderr, "DEBUG: -> %s\n", packet_name(AT_PAP_TYPE_OPEN_CONN)); + + if (atp_sendreq(*fd, &tuple->enu_addr, data, 4, userdata, 1, 0, + 0, &resp, &retry, 0) < 0) + { + statusUpdate("Destination unreachable", 23); + result = EHOSTUNREACH; + break; + } + + puserdata = (u_char *)&resp.userdata[0]; + open_result = OSReadBigInt16(&rdata[2], 0); + + fprintf(stderr, "DEBUG: <- %s, status %d\n", packet_name(puserdata[1]), + open_result); + + /* + * Just for the sake of our sanity check the other fields in the packet + */ + + if (puserdata[1] != AT_PAP_TYPE_OPEN_CONN_REPLY || + (open_result == 0 && (puserdata[0] & 0xff) != *connID)) + { + result = EINVAL; + break; + } + + statusUpdate(&rdata[5], rdata[4] & 0xff); + + /* + * if the connection established okay exit from the loop + */ + + if (open_result == 0) + break; + + sleep(1); + } + + if (result == 0) + { + /* Update the session address + */ + sessionAddr->net = tuple->enu_addr.net; + sessionAddr->node = tuple->enu_addr.node; + sessionAddr->socket = rdata[0]; + *flowQuantum = rdata[1]; + } + else + { + atp_close(*fd); + *fd = 0; + sleep(1); + } + + return result; +} + + +/*! + * @function papClose + * @abstract End a PAP session by canceling outstanding send-data & tickle + * transactions and sending a PAP close request. + * + * @result A non-zero return value for errors + */ +static int papClose() +{ + int fd; + u_short tmpID; + unsigned char rdata[ATP_DATA_SIZE]; + int userdata; + u_char *puserdata = (u_char *)&userdata; + at_resp_t resp; + at_retry_t retry; + + if (gSockfd != 0) + { + fd = gSockfd; + gSockfd = 0; + + alarm(0); + + /* Cancel the pending send-data and tickle trnsactions + */ + if (gSendDataID) + { + tmpID = gSendDataID; + gSendDataID = 0; + papCancelRequest(fd, tmpID); + } + + if (gTickleID) + { + tmpID = gTickleID; + gTickleID = 0; + papCancelRequest(fd, tmpID); + } + + /* This is a workaround for bug #2735145. The problem is papWrite() + * returns before the ATP TRel arrives for it. If we send the pap close packet + * before this release then the printer can drop the last data packets. + * The effect on an Epson printer is the last page doesn't print, on HP it + * doesn't close the pap session. + */ + if (gWaitEOF == false) + sleep(2); + + fprintf(stderr, "DEBUG: -> %s\n", packet_name(AT_PAP_TYPE_CLOSE_CONN)); + + puserdata[0] = gConnID; + puserdata[1] = AT_PAP_TYPE_CLOSE_CONN; + puserdata[2] = 0; + puserdata[3] = 0; + + retry.interval = 2; + retry.retries = 5; + + resp.bitmap = 0x01; + resp.resp[0].iov_base = rdata; + resp.resp[0].iov_len = sizeof(rdata); + + atp_sendreq(fd, &gSessionAddr, 0, 0, userdata, 1, 0, 0, &resp, &retry, 0); + + close(fd); + } + return noErr; +} + + +/*! + * @function papWrite + * @abstract Write bytes to a printer. + * + * @param sockfd socket descriptor + * @param dest destination address + * @param tid transaction id + * @param connID connection id + * @param flowQuantum returned flow quantum (usually 8) + * @param data pointer to the data + * @param len number of bytes to send + * @param eof pap eof flag + * + * @result A non-zero return value for errors + */ +static int papWrite(int sockfd, at_inet_t* dest, u_short tid, u_char connID, u_char flowQuantum, char* data, int len, int eof) +{ + int result; + int i; + u_char* puserdata; + at_resp_t resp; + + /* fprintf(stderr, "DEBUG: papWrite(%d%s) to %d,%d,%d; %d\n", len, eof ? " EOF":"", dest->net, dest->node, dest->socket, connID); */ + + if (len > AT_PAP_DATA_SIZE * flowQuantum) + { + fprintf(stderr, "DEBUG: papWrite() len of %d is too big!\n", len); + errno = E2BIG; + return -1; + } + + /* + * Break up the outgoing data into a set of + * response packets to reply to an incoming + * PAP 'SENDDATA' request + */ + for (i = 0; i < flowQuantum; i++) + { + resp.userdata[i] = 0; + puserdata = (u_char *)&resp.userdata[i]; + + puserdata[PAP_CONNID] = connID; + puserdata[PAP_TYPE] = AT_PAP_TYPE_DATA; + puserdata[PAP_EOF] = eof ? 1 : 0; + + resp.resp[i].iov_base = (caddr_t)data; + + if (data) + data += AT_PAP_DATA_SIZE; + + resp.resp[i].iov_len = MIN((int)len, (int)AT_PAP_DATA_SIZE); + len -= resp.resp[i].iov_len; + if (len == 0) + break; + } + resp.bitmap = (1 << (i + 1)) - 1; + + /* + * Write out the data as a PAP 'DATA' response + */ + errno = 0; + if ((result = atp_sendrsp(sockfd, dest, true, tid, &resp)) < 0) + { + fprintf(stderr, "DEBUG: atp_sendrsp() returns %d, errno %d \"%s\"\n", result, errno, strerror(errno)); + return -1; + } + return(0); +} + + +/*! + * @function papCloseResp + * @abstract Send a pap close response in the rare case we receive a close connection request. + * + * @param sockfd socket descriptor + * @param dest destination address + * @param tid transaction id + * @param connID connection id + * + * @result A non-zero return value for errors + */ +static int papCloseResp(int sockfd, at_inet_t* dest, int xo, u_short tid, u_char connID) +{ + int result; + at_resp_t resp; + + resp.bitmap = 1; + resp.userdata[0] = 0; + + ((u_char*)&resp.userdata[0])[PAP_CONNID] = connID; + ((u_char*)&resp.userdata[0])[PAP_TYPE] = AT_PAP_TYPE_CLOSE_CONN_REPLY; + + resp.resp[0].iov_base = NULL; + resp.resp[0].iov_len = 0; + + if ((result = atp_sendrsp(sockfd, dest, xo, tid, &resp)) < 0) + { + fprintf(stderr, "DEBUG: atp_sendrsp() returns %d, errno %d \"%s\"\n", result, errno, strerror(errno)); + return -1; + } + return 0; +} + + +/*! + * @function papSendRequest + * @abstract Send a pap close response in the rare case we receive a close connection request. + * + * @param sockfd socket descriptor + * @param dest destination address + * @param function pap function + * @param bitmap bitmap + * @param xo exactly once + * @param seqno sequence number + * + * @result A non-zero return value for errors + */ +static int papSendRequest(int sockfd, at_inet_t* dest, u_char connID, int function, u_char bitmap, int xo, int seqno) +{ + u_short tid; + int err; + sigset_t sv, osv; + int userdata; + u_char *puserdata = (u_char *)&userdata; + at_retry_t retry; + at_resp_t resp; + static u_short pap_send_count = 0; + + fprintf(stderr, "DEBUG: -> %s\n", packet_name(function)); + + puserdata[0] = connID; + puserdata[1] = function; + resp.bitmap = bitmap; + retry.interval = 10; + retry.retries = -1; /* was ATP_INFINITE_RETRIES */ + if (seqno) + { + pap_send_count++; + if (pap_send_count == 0) + pap_send_count = 1; + + OSWriteBigInt16(&puserdata[2], 0, pap_send_count); + } + else + OSWriteBigInt16(&puserdata[2], 0, 0); + + sigemptyset(&sv); + sigaddset(&sv, SIGIO); + sigprocmask(SIG_SETMASK, &sv, &osv); + + err = atp_sendreq(sockfd, dest, 0, 0, userdata, xo, 0, &tid, &resp, &retry, 1); + + sigprocmask(SIG_SETMASK, &osv, NULL); + + return err; +} + + +/*! + * @function papCancelRequest + * @abstract Cancel a pending pap request. + * + * @param sockfd socket descriptor + * @param tid transaction ID + * + * @result A non-zero return value for errors + */ +int papCancelRequest(int sockfd, u_short tid) +{ + sigset_t sv, osv; + + sigemptyset(&sv); + sigaddset(&sv, SIGIO); + sigprocmask(SIG_SETMASK, &sv, &osv); + + if (atp_abort(sockfd, NULL, tid) < 0) + { + sigprocmask(SIG_SETMASK, &osv, NULL); + return -1; + } + sigprocmask(SIG_SETMASK, &osv, NULL); + + return 0; +} + + +/* + * 'sidechannel_request()' - Handle side-channel requests. + */ + +static int +sidechannel_request() +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + return (-1); + + switch (command) + { + case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */ + data[0] = 1; + return (cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0)); + break; + + case CUPS_SC_CMD_GET_STATE: /* Return device state */ + data[0] = CUPS_SC_STATE_ONLINE; + return (cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0)); + break; + + case CUPS_SC_CMD_DRAIN_OUTPUT: /* Drain all pending output */ + case CUPS_SC_CMD_SOFT_RESET: /* Do a soft reset */ + case CUPS_SC_CMD_GET_DEVICE_ID: /* Return IEEE-1284 device ID */ + default: + return (cupsSideChannelWrite(command, CUPS_SC_STATUS_NOT_IMPLEMENTED, + NULL, 0, 1.0)); + break; + } + return (0); +} + + +#pragma mark - +/*! + * @function statusUpdate + * @abstract Format and print a PAP status response to stderr. + * + * @param status The status response string + * @param statusLen The length of the status response string + */ +void statusUpdate(char* status, u_char statusLen) +{ + static char status_str[255]; + static u_char last_statusLen = 0xFF; + + /* Only send this if the status has changed */ + if (statusLen != last_statusLen || memcmp(status, status_str, statusLen) != 0) + { + if (statusLen > sizeof(status_str)-1) + statusLen = sizeof(status_str)-1; + last_statusLen = statusLen; + memcpy(status_str, status, statusLen); + status_str[(int)statusLen] = '\0'; + + /* + * Make sure the status string is in the form of a PostScript comment. + */ + + if (statusLen > 3 && memcmp(status, "%%[", 3) == 0) + fprintf(stderr, "INFO: %s\n", status_str); + else + fprintf(stderr, "INFO: %%%%[ %s ]%%%%\n", status_str); + } + return; +} + + +/*! + * @function parseUri + * @abstract Parse a PAP URI into it's NBP components. + * + * @param argv0 The PAP URI to parse + * @param name NBP name + * @param zone NBP zone + * @param type NBP type + * + * @result A non-zero return value for errors + */ +static int parseUri(const char* argv0, char* name, char* type, char* zone) +{ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024], /* Resource info (device and options) */ + *resourcePtr, + *typePtr, + *options, /* Pointer to options */ + *optionName, /* Name of option */ + *value, /* Value of option */ + sep; /* Separator character */ + int port; /* Port number (not used) */ + int statusInterval; /* */ + + /* + * Extract the device name and options from the URI... + */ + method[0] = username[0] = hostname[0] = resource[0] = '\0'; + port = 0; + + httpSeparateURI(HTTP_URI_CODING_NONE, argv0, method, sizeof(method), + username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(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'; + + while (*options != '\0') + { + /* + * Get the name... + */ + + optionName = options; + + while (*options && *options != '=' && *options != '+' && *options != '&') + options ++; + + if ((sep = *options) != '\0') + *options++ = '\0'; + + if (sep == '=') + { + /* + * Get the value... + */ + + value = options; + + while (*options && *options != '+' && *options != '&') + options ++; + + if (*options) + *options++ = '\0'; + } + else + value = (char *)""; + + /* + * Process the option... + */ + + if (!strcasecmp(optionName, "waiteof")) + { + /* + * Wait for the end of the print file? + */ + + if (!strcasecmp(value, "on") || + !strcasecmp(value, "yes") || + !strcasecmp(value, "true")) + { + gWaitEOF = true; + } + else if (!strcasecmp(value, "off") || + !strcasecmp(value, "no") || + !strcasecmp(value, "false")) + { + gWaitEOF = false; + } + else + { + _cupsLangPrintf(stderr, + _("WARNING: Boolean expected for waiteof option \"%s\"\n"), + value); + } + } + else if (!strcasecmp(optionName, "status")) + { + /* + * Set status reporting interval... + */ + + statusInterval = atoi(value); + if (value[0] < '0' || value[0] > '9' || statusInterval < 0) + { + _cupsLangPrintf(stderr, + _("WARNING: number expected for status option \"%s\"\n"), + value); + } + else + { + gStatusInterval = statusInterval; + } + } + } + } + + resourcePtr = resource; + + if (*resourcePtr == '/') + resourcePtr++; + + /* If the resource has a slash we assume the slash seperates the AppleTalk object + * name from the AppleTalk type. If the slash is not present we assume the AppleTalk + * type is LaserWriter. + */ + + typePtr = strchr(resourcePtr, '/'); + if (typePtr != NULL) + { + *typePtr++ = '\0'; + } + else + { + typePtr = "LaserWriter"; + } + + removePercentEscapes(hostname, zone, NBP_NVE_STR_SIZE + 1); + removePercentEscapes(resourcePtr, name, NBP_NVE_STR_SIZE + 1); + removePercentEscapes(typePtr, type, NBP_NVE_STR_SIZE + 1); + + return 0; +} + + +/*! + * @function addPercentEscapes + * @abstract Encode a string with percent escapes + * + * @param src The source C string + * @param dst Desination buffer + * @param dstMax Size of desination buffer + * + * @result A non-zero return value for errors + */ +static int addPercentEscapes(const char* src, char* dst, int dstMax) +{ + char c; + char *dstEnd = dst + dstMax - 1; /* -1 to leave room for the NUL */ + + while (*src) + { + c = *src++; + + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || (c == '.' || c == '-' || c == '*' || c == '_')) + { + if (dst >= dstEnd) + return -1; + + *dst++ = c; + } + else + { + if (dst >= dstEnd - 2) + return -1; + + snprintf(dst, dstEnd - dst, "%%%02x", c); + dst += 3; + } + } + + *dst = '\0'; + return 0; +} + + +/*! + * @function removePercentEscapes + * @abstract Returns a string with any percent escape sequences replaced with their equivalent character + * + * @param src Source buffer + * @param srclen Number of bytes in source buffer + * @param dst Desination buffer + * @param dstMax Size of desination buffer + * + * @result A non-zero return value for errors + */ +static int removePercentEscapes(const char* src, char* dst, int dstMax) +{ + int c; + const char *dstEnd = dst + dstMax; + + while (*src && dst < dstEnd) + { + c = *src++; + + if (c == '%') + { + sscanf(src, "%02x", &c); + src += 2; + } + *dst++ = (char)c; + } + + if (dst >= dstEnd) + return -1; + + *dst = '\0'; + return 0; +} + + +/*! + * @function nbptuple_compare + * @abstract An NBP comparator for qsort. + * + * @result p1p2: 1 + */ +int nbptuple_compare(const void *p1, const void *p2) +{ + int result; + int len = MIN(((at_nbptuple_t*)p1)->enu_entity.object.len, + ((at_nbptuple_t*)p2)->enu_entity.object.len); + + if ((result = memcmp(((at_nbptuple_t*)p1)->enu_entity.object.str, ((at_nbptuple_t*)p2)->enu_entity.object.str, len)) == 0) + { + if (((at_nbptuple_t*)p1)->enu_entity.object.len < ((at_nbptuple_t*)p2)->enu_entity.object.len) + result = -1; + else if (((at_nbptuple_t*)p1)->enu_entity.object.len > ((at_nbptuple_t*)p2)->enu_entity.object.len) + result = 1; + else + result = 0; + } + return result; +} + + +/*! + * @function okayToUseAppleTalk + * @abstract Returns true if AppleTalk is available and enabled. + * + * @result non-zero if AppleTalk is enabled + */ +static int okayToUseAppleTalk() +{ + int atStatus = checkATStack(); + + /* I think the test should be: + * return atStatus == RUNNING || atStatus == LOADED; + * but when I disable AppleTalk from the network control panel and + * reboot, AppleTalk shows up as loaded. The test empirically becomes + * the following: + */ + return atStatus == RUNNING; +} + + +/*! + * @function packet_name + * @abstract Returns packet name string. + * + * @result A string + */ +static const char *packet_name(u_char x) +{ + switch (x) + { + case AT_PAP_TYPE_OPEN_CONN: return "PAP_OPEN_CONN"; + case AT_PAP_TYPE_OPEN_CONN_REPLY: return "PAP_OPEN_CONN_REPLY"; + case AT_PAP_TYPE_SEND_DATA: return "PAP_SEND_DATA"; + case AT_PAP_TYPE_DATA: return "PAP_DATA"; + case AT_PAP_TYPE_TICKLE: return "PAP_TICKLE"; + case AT_PAP_TYPE_CLOSE_CONN: return "PAP_CLOSE_CONN"; + case AT_PAP_TYPE_CLOSE_CONN_REPLY: return "PAP_CLOSE_CONN_REPLY"; + case AT_PAP_TYPE_SEND_STATUS: return "PAP_SEND_STATUS"; + case AT_PAP_TYPE_SEND_STS_REPLY: return "PAP_SEND_STS_REPLY"; + case AT_PAP_TYPE_READ_LW: return "PAP_READ_LW"; + } + return ""; +} + + +/*! + * @function connectTimeout + * @abstract Returns the connect timeout preference value. + */ +static int connectTimeout() +{ + CFPropertyListRef value; + SInt32 connect_timeout = (7 * 24 * 60 * 60); /* Default timeout is one week... */ + + value = CFPreferencesCopyValue(CFSTR("timeout"), CFSTR("com.apple.print.backends"), + kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + if (value != NULL) + { + if (CFGetTypeID(value) == CFNumberGetTypeID()) + CFNumberGetValue(value, kCFNumberSInt32Type, &connect_timeout); + + CFRelease(value); + } + + return connect_timeout; +} + + +/*! + * @function signalHandler + * @abstract A signal handler so we can clean up the pap session before exiting. + * + * @param sigraised The signal raised + * + * @result Never returns + */ +static void signalHandler(int sigraised) +{ + _cupsLangPuts(stderr, _("ERROR: There was a timeout error while sending data to the printer\n")); + + papClose(); + + _exit(1); +} diff --git a/backend/parallel.c b/backend/parallel.c new file mode 100644 index 0000000000..f006f706bd --- /dev/null +++ b/backend/parallel.c @@ -0,0 +1,686 @@ +/* + * "$Id$" + * + * Parallel port backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "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. + * side_cb() - Handle side-channel requests... + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" + +#ifdef __hpux +# include +#else +# include +#endif /* __hpux */ + +#ifdef WIN32 +# include +#else +# include +# include +# include +# include +#endif /* WIN32 */ + +#ifdef __sgi +# include +# 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... + */ + +static void list_devices(void); +static int side_cb(int print_fd, int device_fd, int snmp_fd, + http_addr_t *addr, int use_bc); + + +/* + * '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 print_fd, /* Print file */ + device_fd, /* Parallel device */ + use_bc; /* Read back-channel data? */ + int copies; /* Number of copies to print */ + size_t tbytes; /* Total number of bytes written */ + 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); + + /* + * Ignore SIGPIPE signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + list_devices(); + return (CUPS_BACKEND_OK); + } + else if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + print_fd = 0; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((print_fd = open(argv[6], O_RDONLY)) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open print file \"%s\": %s\n"), + argv[6], strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the device name and options from the URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), + method, sizeof(method), username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(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... + */ + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { +#if defined(__linux) || defined(__FreeBSD__) + /* + * The Linux and FreeBSD parallel port drivers currently are broken WRT + * select() and bidirection I/O... + */ + + device_fd = open(resource, O_WRONLY | O_EXCL); + use_bc = 0; + +#else + if ((device_fd = open(resource, O_RDWR | O_EXCL)) < 0) + { + device_fd = open(resource, O_WRONLY | O_EXCL); + use_bc = 0; + } + else + use_bc = 1; +#endif /* __linux || __FreeBSD__ */ + + if (device_fd == -1) + { + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (errno == EBUSY) + { + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 30 seconds...\n")); + sleep(30); + } + else if (errno == ENXIO || errno == EIO || errno == ENOENT) + { + _cupsLangPuts(stderr, + _("INFO: Printer not connected; will retry in 30 " + "seconds...\n")); + sleep(30); + } + else + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open device file \"%s\": %s\n"), + resource, strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + } + } + while (device_fd < 0); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * Set any options provided... + */ + + tcgetattr(device_fd, &opts); + + opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ + + /**** No options supported yet ****/ + + tcsetattr(device_fd, TCSANOW, &opts); + + /* + * Finally, send the print file... + */ + + tbytes = 0; + + while (copies > 0 && tbytes >= 0) + { + copies --; + + if (print_fd != 0) + { + fputs("PAGE: 1 1\n", stderr); + lseek(print_fd, 0, SEEK_SET); + } + + tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, 1, side_cb); + + if (print_fd != 0 && tbytes >= 0) + _cupsLangPrintf(stderr, +#ifdef HAVE_LONG_LONG + _("INFO: Sent print file, %lld bytes...\n"), +#else + _("INFO: Sent print file, %ld bytes...\n"), +#endif /* HAVE_LONG_LONG */ + CUPS_LLCAST tbytes); + } + + /* + * Close the socket connection and input file and return... + */ + + close(device_fd); + + if (print_fd != 0) + close(print_fd); + + return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); +} + + +/* + * 'list_devices()' - List all parallel devices. + */ + +static 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 */ + basedevice[255], /* Base device filename for ports */ + device_id[1024], /* Device ID string */ + make_model[1024], /* Make and model */ + info[1024], /* Info string */ + uri[1024]; /* Device URI */ + + + if (!access("/dev/parallel/", 0)) + strcpy(basedevice, "/dev/parallel/"); + else if (!access("/dev/printers/", 0)) + strcpy(basedevice, "/dev/printers/"); + else + strcpy(basedevice, "/dev/lp"); + + for (i = 0; i < 4; i ++) + { + /* + * Open the port, if available... + */ + + sprintf(device, "%s%d", basedevice, i); + if ((fd = open(device, O_RDWR | O_EXCL)) < 0) + fd = open(device, O_WRONLY); + + if (fd >= 0) + { + /* + * Now grab the IEEE 1284 device ID string... + */ + + snprintf(uri, sizeof(uri), "parallel:%s", device); + + if (!backendGetDeviceID(fd, device_id, sizeof(device_id), + make_model, sizeof(make_model), + NULL, uri, sizeof(uri))) + { + snprintf(info, sizeof(info), "%s LPT #%d", make_model, i + 1); + cupsBackendReport("direct", uri, make_model, info, device_id, NULL); + } + else + { + snprintf(info, sizeof(info), "LPT #%d", i + 1); + cupsBackendReport("direct", uri, NULL, info, NULL, NULL); + } + + close(fd); + } + } +#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__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + 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 +} + + +/* + * 'side_cb()' - Handle side-channel requests... + */ + +static int /* O - 0 on success, -1 on error */ +side_cb(int print_fd, /* I - Print file */ + int device_fd, /* I - Device file */ + int snmp_fd, /* I - SNMP socket (unused) */ + http_addr_t *addr, /* I - Device address (unused) */ + int use_bc) /* I - Using back-channel? */ +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + + (void)snmp_fd; + (void)addr; + + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + return (-1); + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + if (backendDrainOutput(print_fd, device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else if (tcdrain(device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else + status = CUPS_SC_STATUS_OK; + + datalen = 0; + break; + + case CUPS_SC_CMD_GET_BIDI : + status = CUPS_SC_STATUS_OK; + data[0] = use_bc; + datalen = 1; + break; + + case CUPS_SC_CMD_GET_DEVICE_ID : + memset(data, 0, sizeof(data)); + + if (backendGetDeviceID(device_fd, data, sizeof(data) - 1, + NULL, 0, NULL, NULL, 0)) + { + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + } + else + { + status = CUPS_SC_STATUS_OK; + datalen = strlen(data); + } + break; + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/runloop.c b/backend/runloop.c new file mode 100644 index 0000000000..06f042997a --- /dev/null +++ b/backend/runloop.c @@ -0,0 +1,426 @@ +/* + * "$Id$" + * + * Common run loop APIs for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * backendDrainOutput() - Drain pending print data to the device. + * backendRunLoop() - Read and write print and back-channel data. + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" +#include +#ifdef __hpux +# include +#else +# include +#endif /* __hpux */ + + +/* + * 'backendDrainOutput()' - Drain pending print data to the device. + */ + +int /* O - 0 on success, -1 on error */ +backendDrainOutput(int print_fd, /* I - Print file descriptor */ + int device_fd) /* I - Device file descriptor */ +{ + int nfds; /* Maximum file descriptor value + 1 */ + fd_set input; /* Input set for reading */ + ssize_t print_bytes, /* Print bytes read */ + bytes; /* Bytes written */ + char print_buffer[8192], /* Print data buffer */ + *print_ptr; /* Pointer into print data buffer */ + struct timeval timeout; /* Timeout for read... */ + + + fprintf(stderr, "DEBUG: backendDrainOutput(print_fd=%d, device_fd=%d)\n", + print_fd, device_fd); + + /* + * Figure out the maximum file descriptor value to use with select()... + */ + + nfds = (print_fd > device_fd ? print_fd : device_fd) + 1; + + /* + * Now loop until we are out of data from print_fd... + */ + + for (;;) + { + /* + * Use select() to determine whether we have data to copy around... + */ + + FD_ZERO(&input); + FD_SET(print_fd, &input); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + if (select(nfds, &input, NULL, NULL, &timeout) < 0) + return (-1); + + if (!FD_ISSET(print_fd, &input)) + return (0); + + if ((print_bytes = read(print_fd, print_buffer, + sizeof(print_buffer))) < 0) + { + /* + * Read error - bail if we don't see EAGAIN or EINTR... + */ + + if (errno != EAGAIN || errno != EINTR) + { + perror("ERROR: Unable to read print data"); + return (-1); + } + + print_bytes = 0; + } + else if (print_bytes == 0) + { + /* + * End of file, return... + */ + + return (0); + } + + fprintf(stderr, "DEBUG: Read %d bytes of print data...\n", + (int)print_bytes); + + for (print_ptr = print_buffer; print_bytes > 0;) + { + if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0) + { + /* + * Write error - bail if we don't see an error we can retry... + */ + + if (errno != ENOSPC && errno != ENXIO && errno != EAGAIN && + errno != EINTR && errno != ENOTTY) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to write print data: %s\n"), + strerror(errno)); + return (-1); + } + } + else + { + fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes); + + print_bytes -= bytes; + print_ptr += bytes; + } + } + } +} + + +/* + * 'backendRunLoop()' - Read and write print and back-channel data. + */ + +ssize_t /* O - Total bytes on success, -1 on error */ +backendRunLoop( + int print_fd, /* I - Print file descriptor */ + int device_fd, /* I - Device file descriptor */ + int snmp_fd, /* I - SNMP socket or -1 if none */ + http_addr_t *addr, /* I - Address of device */ + int use_bc, /* I - Use back-channel? */ + int update_state, /* I - Update printer-state-reasons? */ + int (*side_cb)(int, int, int, http_addr_t *, int)) + /* I - Side-channel callback */ +{ + int nfds; /* Maximum file descriptor value + 1 */ + fd_set input, /* Input set for reading */ + output; /* Output set for writing */ + ssize_t print_bytes, /* Print bytes read */ + bc_bytes, /* Backchannel bytes read */ + total_bytes, /* Total bytes written */ + bytes; /* Bytes written */ + int paperout; /* "Paper out" status */ + int offline; /* "Off-line" status */ + char print_buffer[8192], /* Print data buffer */ + *print_ptr, /* Pointer into print data buffer */ + bc_buffer[1024]; /* Back-channel data buffer */ + struct timeval timeout; /* Timeout for select() */ + time_t curtime, /* Current time */ + snmp_update = 0; +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + fprintf(stderr, + "DEBUG: backendRunLoop(print_fd=%d, device_fd=%d, snmp_fd=%d, " + "addr=%p, use_bc=%d, side_cb=%p)\n", + print_fd, device_fd, snmp_fd, addr, use_bc, side_cb); + + /* + * If we are printing data from a print driver on stdin, ignore SIGTERM + * so that the driver can finish out any page data, e.g. to eject the + * current page. We only do this for stdin printing as otherwise there + * is no way to cancel a raw print job... + */ + + if (!print_fd) + { +#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 */ + } + else if (print_fd < 0) + { + /* + * Copy print data from stdin, but don't mess with the signal handlers... + */ + + print_fd = 0; + } + + /* + * Figure out the maximum file descriptor value to use with select()... + */ + + nfds = (print_fd > device_fd ? print_fd : device_fd) + 1; + + /* + * Now loop until we are out of data from print_fd... + */ + + for (print_bytes = 0, print_ptr = print_buffer, offline = -1, + paperout = -1, total_bytes = 0;;) + { + /* + * Use select() to determine whether we have data to copy around... + */ + + FD_ZERO(&input); + if (!print_bytes) + FD_SET(print_fd, &input); + if (use_bc) + FD_SET(device_fd, &input); + if (!print_bytes && side_cb) + FD_SET(CUPS_SC_FD, &input); + + FD_ZERO(&output); + if (print_bytes || (!use_bc && !side_cb)) + FD_SET(device_fd, &output); + + if (use_bc || side_cb) + { + timeout.tv_sec = 5; + timeout.tv_usec = 0; + + if (select(nfds, &input, &output, NULL, &timeout) < 0) + { + /* + * Pause printing to clear any pending errors... + */ + + if (errno == ENXIO && offline != 1 && update_state) + { + fputs("STATE: +offline-report\n", stderr); + _cupsLangPuts(stderr, _("INFO: Printer is currently offline.\n")); + offline = 1; + } + else if (errno == EINTR && total_bytes == 0) + { + fputs("DEBUG: Received an interrupt before any bytes were " + "written, aborting!\n", stderr); + return (0); + } + + sleep(1); + continue; + } + } + + /* + * Check if we have a side-channel request ready... + */ + + if (side_cb && FD_ISSET(CUPS_SC_FD, &input)) + { + /* + * Do the side-channel request, then start back over in the select + * loop since it may have read from print_fd... + */ + + if ((*side_cb)(print_fd, device_fd, snmp_fd, addr, use_bc)) + side_cb = NULL; + continue; + } + + /* + * Check if we have back-channel data ready... + */ + + if (FD_ISSET(device_fd, &input)) + { + if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0) + { + fprintf(stderr, + "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n", + CUPS_LLCAST bc_bytes); + cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0); + } + else if (bc_bytes < 0 && errno != EAGAIN && errno != EINTR) + { + fprintf(stderr, "DEBUG: Error reading back-channel data: %s\n", + strerror(errno)); + use_bc = 0; + } + else if (bc_bytes == 0) + use_bc = 0; + } + + /* + * Check if we have print data ready... + */ + + if (FD_ISSET(print_fd, &input)) + { + if ((print_bytes = read(print_fd, print_buffer, + sizeof(print_buffer))) < 0) + { + /* + * Read error - bail if we don't see EAGAIN or EINTR... + */ + + if (errno != EAGAIN || errno != EINTR) + { + perror("ERROR: Unable to read print data"); + return (-1); + } + + print_bytes = 0; + } + else if (print_bytes == 0) + { + /* + * End of file, break out of the loop... + */ + + break; + } + + print_ptr = print_buffer; + + fprintf(stderr, "DEBUG: Read %d bytes of print data...\n", + (int)print_bytes); + } + + /* + * Check if the device is ready to receive data and we have data to + * send... + */ + + if (print_bytes && FD_ISSET(device_fd, &output)) + { + if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0) + { + /* + * Write error - bail if we don't see an error we can retry... + */ + + if (errno == ENOSPC) + { + if (paperout != 1 && update_state) + { + fputs("STATE: +media-empty-warning\n", stderr); + _cupsLangPuts(stderr, _("ERROR: Out of paper!\n")); + paperout = 1; + } + } + else if (errno == ENXIO) + { + if (offline != 1 && update_state) + { + fputs("STATE: +offline-report\n", stderr); + _cupsLangPuts(stderr, _("INFO: Printer is currently off-line.\n")); + offline = 1; + } + } + else if (errno != EAGAIN && errno != EINTR && errno != ENOTTY) + { + fprintf(stderr, _("ERROR: Unable to write print data: %s\n"), + strerror(errno)); + return (-1); + } + } + else + { + if (paperout && update_state) + { + fputs("STATE: -media-empty-warning\n", stderr); + paperout = 0; + } + + if (offline && update_state) + { + fputs("STATE: -offline-report\n", stderr); + _cupsLangPuts(stderr, _("INFO: Printer is now online.\n")); + offline = 0; + } + + fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes); + + print_bytes -= bytes; + print_ptr += bytes; + total_bytes += bytes; + } + } + + /* + * Do SNMP updates periodically... + */ + + if (snmp_fd >= 0 && time(&curtime) >= snmp_update) + { + if (backendSNMPSupplies(snmp_fd, addr, NULL, NULL)) + snmp_update = INT_MAX; + else + snmp_update = curtime + 5; + } + } + + /* + * Return with success... + */ + + return (total_bytes); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/scsi-irix.c b/backend/scsi-irix.c new file mode 100644 index 0000000000..1115652cb9 --- /dev/null +++ b/backend/scsi-irix.c @@ -0,0 +1,241 @@ +/* + * "$Id$" + * + * IRIX SCSI printer support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2003-2005 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 /* memcpy() and friends */ +#include /* SCSI interface stuff */ + + +/* + * 'list_devices()' - List the available SCSI printer devices. + */ + +void +list_devices(void) +{ + printf("direct scsi \"Unknown\" \"%s\"\n", + _cupsLangString(cupsLangDefault(), _("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 */ +#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) + { + _cupsLangPrintf(stderr, _("ERROR: Bad SCSI device file \"%s\"!\n"), + resource); + return (CUPS_BACKEND_STOP); + } + + /* + * Open the SCSI device file... + */ + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { + if ((scsi_fd = open(resource, O_RDWR | O_EXCL)) == -1) + { + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (1); + } + + if (errno != EAGAIN && errno != EBUSY) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open device file \"%s\": %s\n"), + resource, strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + else + { + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 30 seconds...\n")); + sleep(30); + } + } + } + while (scsi_fd == -1); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * 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) + { + _cupsLangPrintf(stderr, + _("WARNING: SCSI command timed out (%d); " + "retrying...\n"), scsi_req.ds_status); + sleep(try + 1); + } + else + break; + + if (try >= 10) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to send print data (%d)\n"), + scsi_req.ds_status); + close(scsi_fd); + return (CUPS_BACKEND_FAILED); + } + } + + copies --; + } + + /* + * Close the device and return... + */ + + close(fd); + + return (CUPS_BACKEND_OK); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/scsi-linux.c b/backend/scsi-linux.c new file mode 100644 index 0000000000..1e90ebd0b5 --- /dev/null +++ b/backend/scsi-linux.c @@ -0,0 +1,260 @@ +/* + * "$Id$" + * + * Linux SCSI printer support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2003-2005 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 +#include + + +/* + * 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) +{ + printf("direct scsi \"Unknown\" \"%s\"\n", + _cupsLangString(cupsLangDefault(), _("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 */ + unsigned 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) + { + _cupsLangPrintf(stderr, _("ERROR: Bad SCSI device file \"%s\"!\n"), + resource); + return (CUPS_BACKEND_STOP); + } + + /* + * Open the SCSI device file... + */ + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { + if ((scsi_fd = open(resource, O_RDWR | O_EXCL)) == -1) + { + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (errno != EAGAIN && errno != EBUSY) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open device file \"%s\": %s\n"), + resource, strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + else + { + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 30 seconds...\n")); + sleep(30); + } + } + } + while (scsi_fd == -1); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * 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) + { + _cupsLangPrintf(stderr, + _("WARNING: SCSI command timed out (%d); " + "retrying...\n"), scsi_req.status); + sleep(try + 1); + } + else + break; + + if (try >= 10) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to send print data (%d)\n"), + scsi_req.status); + close(scsi_fd); + return (CUPS_BACKEND_FAILED); + } + } + + copies --; + } + + /* + * Close the device and return... + */ + + close(fd); + + return (CUPS_BACKEND_OK); +} +#endif /* !SG_DXFER_TO_DEV */ + + +/* + * End of "$Id$". + */ diff --git a/backend/scsi.c b/backend/scsi.c new file mode 100644 index 0000000000..1d88107e7e --- /dev/null +++ b/backend/scsi.c @@ -0,0 +1,231 @@ +/* + * "$Id$" + * + * SCSI printer backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2003-2006 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +# include +#else +# include +# include +# ifdef HAVE_SYS_IOCTL_H +# include +# endif /* HAVE_SYS_IOCTL_H */ +#endif /* WIN32 */ + + +/* + * Local functions... + */ + +void list_devices(void); +int print_device(const char *resource, int fd, int copies); + + +#if defined(__linux__) && defined(HAVE_SCSI_SG_H) +# 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 (CUPS_BACKEND_FAILED); } +#endif /* __linux && HAVE_SCSI_SG_H */ + + +/* + * '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 */ +#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); + + /* + * Ignore SIGPIPE signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + list_devices(); + return (CUPS_BACKEND_OK); + } + else if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* + * 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) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open print file \"%s\": %s\n"), + argv[6], strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the device name and options from the URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), + method, sizeof(method), username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(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); + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/serial.c b/backend/serial.c new file mode 100644 index 0000000000..c3a844dd64 --- /dev/null +++ b/backend/serial.c @@ -0,0 +1,1330 @@ +/* + * "$Id$" + * + * Serial port backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "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. + * side_cb() - Handle side-channel requests... + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" + +#ifdef __hpux +# include +#endif /* __hpux */ + +#ifdef WIN32 +# include +#else +# include +# include +# include +# ifdef __hpux +# include +# else +# include +# endif /* __hpux */ +# ifdef HAVE_SYS_IOCTL_H +# include +# endif /* HAVE_SYS_IOCTL_H */ +#endif /* WIN32 */ + +#ifdef __sgi +# include +# 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 */ + +#if defined(__APPLE__) +# include +# include +# include +# include +#endif /* __APPLE__ */ + +#if defined(__linux) && defined(TIOCGSERIAL) +# include +# include +#endif /* __linux && TIOCGSERIAL */ + + +/* + * Local functions... + */ + +static void list_devices(void); +static int side_cb(int print_fd, int device_fd, int use_bc); + + +/* + * '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, /* Name of option */ + *value, /* Value of option */ + sep; /* Option separator */ + int port; /* Port number (not used) */ + int copies; /* Number of copies to print */ + int side_eof = 0, /* Saw EOF on side-channel? */ + print_fd, /* Print file */ + device_fd; /* Serial device */ + int nfds; /* Maximum file descriptor value + 1 */ + fd_set input, /* Input set for reading */ + output; /* Output set for writing */ + ssize_t print_bytes, /* Print bytes read */ + bc_bytes, /* Backchannel bytes read */ + total_bytes, /* Total bytes written */ + bytes; /* Bytes written */ + int dtrdsr; /* Do dtr/dsr flow control? */ + int print_size; /* Size of output buffer for writes */ + char print_buffer[8192], /* Print data buffer */ + *print_ptr, /* Pointer into print data buffer */ + bc_buffer[1024]; /* Back-channel data 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); + + /* + * Ignore SIGPIPE signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + list_devices(); + return (CUPS_BACKEND_OK); + } + else if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + print_fd = 0; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((print_fd = open(argv[6], O_RDONLY)) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open print file \"%s\": %s\n"), + argv[6], strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the device name and options from the URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, cupsBackendDeviceURI(argv), + method, sizeof(method), username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(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... + */ + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { + if ((device_fd = open(resource, O_RDWR | O_NOCTTY | O_EXCL | + O_NDELAY)) == -1) + { + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (errno == EBUSY) + { + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 30 seconds...\n")); + sleep(30); + } + else + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open device file \"%s\": %s\n"), + resource, strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + } + } + while (device_fd < 0); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * Set any options provided... + */ + + tcgetattr(device_fd, &origopts); + tcgetattr(device_fd, &opts); + + opts.c_lflag &= ~(ICANON | ECHO | ISIG); + /* Raw mode */ + opts.c_oflag &= ~OPOST; /* Don't post-process */ + + print_size = 96; /* 9600 baud / 10 bits/char / 10Hz */ + dtrdsr = 0; /* No dtr/dsr flow control */ + + if (options) + { + while (*options) + { + /* + * Get the name... + */ + + name = options; + + while (*options && *options != '=' && *options != '+' && *options != '&') + options ++; + + if ((sep = *options) != '\0') + *options++ = '\0'; + + if (sep == '=') + { + /* + * Get the value... + */ + + value = options; + + while (*options && *options != '+' && *options != '&') + options ++; + + if (*options) + *options++ = '\0'; + } + else + value = (char *)""; + + /* + * Process the option... + */ + + if (!strcasecmp(name, "baud")) + { + /* + * Set the baud rate... + */ + + print_size = 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 : + _cupsLangPrintf(stderr, _("WARNING: Unsupported baud rate %s!\n"), + value); + break; + } +#endif /* B19200 == 19200 */ + } + else if (!strcasecmp(name, "bits")) + { + /* + * 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")) + { + /* + * Set parity checking... + */ + + if (!strcasecmp(value, "even")) + { + opts.c_cflag |= PARENB; + opts.c_cflag &= ~PARODD; + } + else if (!strcasecmp(value, "odd")) + { + opts.c_cflag |= PARENB; + opts.c_cflag |= PARODD; + } + else if (!strcasecmp(value, "none")) + opts.c_cflag &= ~PARENB; + else if (!strcasecmp(value, "space")) + { + /* + * Note: we only support space parity with 7 bits per character... + */ + + opts.c_cflag &= ~CSIZE; + opts.c_cflag |= CS8; + opts.c_cflag &= ~PARENB; + } + else if (!strcasecmp(value, "mark")) + { + /* + * Note: we only support mark parity with 7 bits per character + * and 1 stop bit... + */ + + opts.c_cflag &= ~CSIZE; + opts.c_cflag |= CS7; + opts.c_cflag &= ~PARENB; + opts.c_cflag |= CSTOPB; + } + } + else if (!strcasecmp(name, "flow")) + { + /* + * Set flow control... + */ + + if (!strcasecmp(value, "none")) + { + opts.c_iflag &= ~(IXON | IXOFF); + opts.c_cflag &= ~CRTSCTS; + } + else if (!strcasecmp(value, "soft")) + { + opts.c_iflag |= IXON | IXOFF; + opts.c_cflag &= ~CRTSCTS; + } + else if (!strcasecmp(value, "hard") || + !strcasecmp(value, "rtscts")) + { + opts.c_iflag &= ~(IXON | IXOFF); + opts.c_cflag |= CRTSCTS; + } + else if (!strcasecmp(value, "dtrdsr")) + { + opts.c_iflag &= ~(IXON | IXOFF); + opts.c_cflag &= ~CRTSCTS; + + dtrdsr = 1; + } + } + else if (!strcasecmp(name, "stop")) + { + switch (atoi(value)) + { + case 1 : + opts.c_cflag &= ~CSTOPB; + break; + + case 2 : + opts.c_cflag |= CSTOPB; + break; + } + } + } + } + + tcsetattr(device_fd, TCSANOW, &opts); + fcntl(device_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 (!print_fd) + { +#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 */ + } + + /* + * Figure out the maximum file descriptor value to use with select()... + */ + + nfds = (print_fd > device_fd ? print_fd : device_fd) + 1; + + /* + * Finally, send the print file. Ordinarily we would just use the + * backendRunLoop() function, however since we need to use smaller + * writes and may need to do DSR/DTR flow control, we duplicate much + * of the code here instead... + */ + + if (print_size > sizeof(print_buffer)) + print_size = sizeof(print_buffer); + + total_bytes = 0; + + while (copies > 0) + { + copies --; + + if (print_fd != 0) + { + fputs("PAGE: 1 1\n", stderr); + lseek(print_fd, 0, SEEK_SET); + } + + /* + * Now loop until we are out of data from print_fd... + */ + + for (print_bytes = 0, print_ptr = print_buffer;;) + { + /* + * Use select() to determine whether we have data to copy around... + */ + + FD_ZERO(&input); + if (!print_bytes) + FD_SET(print_fd, &input); + FD_SET(device_fd, &input); + if (!print_bytes && !side_eof) + FD_SET(CUPS_SC_FD, &input); + + FD_ZERO(&output); + if (print_bytes) + FD_SET(device_fd, &output); + + if (select(nfds, &input, &output, NULL, NULL) < 0) + continue; /* Ignore errors here */ + + /* + * Check if we have a side-channel request ready... + */ + + if (FD_ISSET(CUPS_SC_FD, &input)) + { + /* + * Do the side-channel request, then start back over in the select + * loop since it may have read from print_fd... + */ + + if (side_cb(print_fd, device_fd, 1)) + side_eof = 1; + continue; + } + + /* + * Check if we have back-channel data ready... + */ + + if (FD_ISSET(device_fd, &input)) + { + if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0) + { + fprintf(stderr, + "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n", + CUPS_LLCAST bc_bytes); + cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0); + } + } + + /* + * Check if we have print data ready... + */ + + if (FD_ISSET(print_fd, &input)) + { + if ((print_bytes = read(print_fd, print_buffer, print_size)) < 0) + { + /* + * Read error - bail if we don't see EAGAIN or EINTR... + */ + + if (errno != EAGAIN || errno != EINTR) + { + _cupsLangPrintError(_("ERROR: Unable to read print data")); + + tcsetattr(device_fd, TCSADRAIN, &origopts); + + close(device_fd); + + if (print_fd != 0) + close(print_fd); + + return (CUPS_BACKEND_FAILED); + } + + print_bytes = 0; + } + else if (print_bytes == 0) + { + /* + * End of file, break out of the loop... + */ + + break; + } + + print_ptr = print_buffer; + } + + /* + * Check if the device is ready to receive data and we have data to + * send... + */ + + if (print_bytes && FD_ISSET(device_fd, &output)) + { + if (dtrdsr) + { + /* + * Check the port and sleep until DSR is set... + */ + + int status; + + + if (!ioctl(device_fd, TIOCMGET, &status)) + if (!(status & TIOCM_DSR)) + { + /* + * Wait for DSR to go high... + */ + + fputs("DEBUG: DSR is low; waiting for device...\n", stderr); + + do + { + /* + * Poll every 100ms... + */ + + usleep(100000); + + if (ioctl(device_fd, TIOCMGET, &status)) + break; + } + while (!(status & TIOCM_DSR)); + + fputs("DEBUG: DSR is high; writing to device...\n", stderr); + } + } + + if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0) + { + /* + * Write error - bail if we don't see an error we can retry... + */ + + if (errno != EAGAIN && errno != EINTR && errno != ENOTTY) + { + _cupsLangPrintError(_("ERROR: Unable to write print data")); + + tcsetattr(device_fd, TCSADRAIN, &origopts); + + close(device_fd); + + if (print_fd != 0) + close(print_fd); + + return (CUPS_BACKEND_FAILED); + } + } + else + { + fprintf(stderr, "DEBUG: Wrote %d bytes...\n", (int)bytes); + + print_bytes -= bytes; + print_ptr += bytes; + total_bytes += bytes; + } + } + } + } + + /* + * Close the serial port and input file and return... + */ + + tcsetattr(device_fd, TCSADRAIN, &origopts); + + close(device_fd); + + if (print_fd != 0) + close(print_fd); + + return (total_bytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); +} + + +/* + * 'list_devices()' - List all serial devices. + */ + +static void +list_devices(void) +{ +#if defined(__hpux) || defined(__sgi) || defined(__sun) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; + /* Funky hex numbering used for some * + * devices */ +#endif /* __hpux || __sgi || __sun || __FreeBSD__ || __OpenBSD__ || __FreeBSD_kernel__ */ + + +#ifdef __linux + int i, j; /* Looping vars */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + char info[255]; /* Device info/description */ +# ifdef TIOCGSERIAL + struct serial_struct serinfo; /* serial port info */ +# endif /* TIOCGSERIAL */ + + + for (i = 0; i < 100; i ++) + { + sprintf(device, "/dev/ttyS%d", i); + + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { +# ifdef TIOCGSERIAL + /* + * See if this port exists... + */ + + serinfo.reserved_char[0] = 0; + + if (!ioctl(fd, TIOCGSERIAL, &serinfo)) + { + if (serinfo.type == PORT_UNKNOWN) + { + /* + * Nope... + */ + + close(fd); + continue; + } + } +# endif /* TIOCGSERIAL */ + + close(fd); + + snprintf(info, sizeof(info), + _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); + +# if defined(_ARCH_PPC) || defined(powerpc) || defined(__powerpc) + printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); +# else + printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); +# endif /* _ARCH_PPC || powerpc || __powerpc */ + } + } + + for (i = 0; i < 16; i ++) + { + snprintf(info, sizeof(info), + _cupsLangString(cupsLangDefault(), _("USB Serial Port #%d")), + i + 1); + + 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\" \"%s\"\n", device, info); + } + + sprintf(device, "/dev/ttyUSB%d", i); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=230400 \"Unknown\" \"%s\"\n", device, info); + } + } + + for (i = 0; i < 64; i ++) + { + for (j = 0; j < 8; j ++) + { + sprintf(device, "/dev/ttyQ%02de%d", i, j); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + + printf("serial serial:%s?baud=115200 \"Unknown\" " + "\"Equinox ESP %d Port #%d\"\n", device, i, j + 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 */ + char info[255]; /* Device info/description */ + + + /* + * Standard serial ports... + */ + + for (i = 0; i < 26; i ++) + { + sprintf(device, "/dev/cua/%c", 'a' + i); + if (!access(device, 0)) + { + snprintf(info, sizeof(info), + _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); + +# ifdef B115200 + printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); +# else + printf("serial serial:%s?baud=38400 \"Unknown\" \"%s\"\n", device, info); +# 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__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + int i, j; /* Looping vars */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + char info[255]; /* Device info/description */ + + + /* + * 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); + + snprintf(info, sizeof(info), + _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); + + printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); + } + } + + /* + * 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); + } + + 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 */ + char info[255]; /* Device info/description */ + + + /* + * 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); + + snprintf(info, sizeof(info), + _cupsLangString(cupsLangDefault(), _("Serial Port #%d")), i + 1); + + printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", device, info); + } + } + + /* + * 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); + } + } +#elif defined(__APPLE__) + /* + * Standard serial ports on MacOS X... + */ + + kern_return_t kernResult; + mach_port_t masterPort; + io_iterator_t serialPortIterator; + CFMutableDictionaryRef classesToMatch; + io_object_t serialService; + + + kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort); + if (KERN_SUCCESS != kernResult) + return; + + /* + * Serial devices are instances of class IOSerialBSDClient. + */ + + classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); + if (classesToMatch != NULL) + { + CFDictionarySetValue(classesToMatch, CFSTR(kIOSerialBSDTypeKey), + CFSTR(kIOSerialBSDRS232Type)); + + kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, + &serialPortIterator); + if (kernResult == KERN_SUCCESS) + { + while ((serialService = IOIteratorNext(serialPortIterator))) + { + CFTypeRef serialNameAsCFString; + CFTypeRef bsdPathAsCFString; + CFTypeRef hiddenVal; + char serialName[128]; + char bsdPath[1024]; + Boolean result; + + + /* Check if hidden... */ + hiddenVal = IORegistryEntrySearchCFProperty(serialService, + kIOServicePlane, + CFSTR("HiddenPort"), + kCFAllocatorDefault, + kIORegistryIterateRecursively | + kIORegistryIterateParents); + if (hiddenVal) + CFRelease(hiddenVal); /* This interface should not be used */ + else + { + serialNameAsCFString = + IORegistryEntryCreateCFProperty(serialService, + CFSTR(kIOTTYDeviceKey), + kCFAllocatorDefault, 0); + if (serialNameAsCFString) + { + result = CFStringGetCString(serialNameAsCFString, serialName, + sizeof(serialName), + kCFStringEncodingASCII); + CFRelease(serialNameAsCFString); + + if (result) + { + bsdPathAsCFString = + IORegistryEntryCreateCFProperty(serialService, + CFSTR(kIOCalloutDeviceKey), + kCFAllocatorDefault, 0); + if (bsdPathAsCFString) + { + result = CFStringGetCString(bsdPathAsCFString, bsdPath, + sizeof(bsdPath), + kCFStringEncodingASCII); + CFRelease(bsdPathAsCFString); + + if (result) + printf("serial serial:%s?baud=115200 \"Unknown\" \"%s\"\n", + bsdPath, serialName); + } + } + } + } + + IOObjectRelease(serialService); + } + + /* + * Release the iterator. + */ + + IOObjectRelease(serialPortIterator); + } + } +#endif +} + + +/* + * 'side_cb()' - Handle side-channel requests... + */ + +static int /* O - 0 on success, -1 on error */ +side_cb(int print_fd, /* I - Print file */ + int device_fd, /* I - Device file */ + int use_bc) /* I - Using back-channel? */ +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + return (-1); + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + if (backendDrainOutput(print_fd, device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else if (tcdrain(device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else + status = CUPS_SC_STATUS_OK; + + datalen = 0; + break; + + case CUPS_SC_CMD_GET_BIDI : + status = CUPS_SC_STATUS_OK; + data[0] = use_bc; + datalen = 1; + break; + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c new file mode 100644 index 0000000000..d6d8ae1b96 --- /dev/null +++ b/backend/snmp-supplies.c @@ -0,0 +1,990 @@ +/* + * "$Id$" + * + * SNMP supplies functions for CUPS. + * + * Copyright 2008-2011 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * backendSNMPSupplies() - Get the current supplies for a device. + * backend_init_supplies() - Initialize the supplies list. + * backend_walk_cb() - Interpret the supply value responses. + * utf16_to_utf8() - Convert UTF-16 text to UTF-8. + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" +#include + + +/* + * Local constants... + */ + +#define CUPS_MAX_SUPPLIES 32 /* Maximum number of supplies for a printer */ +#define CUPS_SUPPLY_TIMEOUT 2.0 /* Timeout for SNMP lookups */ + +#define CUPS_DEVELOPER_LOW 1 +#define CUPS_DEVELOPER_EMPTY 2 +#define CUPS_MARKER_SUPPLY_LOW 4 +#define CUPS_MARKER_SUPPLY_EMPTY 8 +#define CUPS_MARKER_WASTE_ALMOST_FULL 16 +#define CUPS_MARKER_WASTE_FULL 32 +#define CUPS_OPC_NEAR_EOL 64 +#define CUPS_OPC_LIFE_OVER 128 +#define CUPS_TONER_LOW 256 +#define CUPS_TONER_EMPTY 512 + + +/* + * Local structures... + */ + +typedef struct /**** Printer supply data ****/ +{ + char name[CUPS_SNMP_MAX_STRING], /* Name of supply */ + color[8]; /* Color: "#RRGGBB" or "none" */ + int colorant, /* Colorant index */ + type, /* Supply type */ + max_capacity, /* Maximum capacity */ + level; /* Current level value */ +} backend_supplies_t; + +typedef struct /**** Printer state table ****/ +{ + int bit; /* State bit */ + const char *keyword; /* IPP printer-state-reasons keyword */ +} backend_state_t; + + +/* + * Local globals... + */ + +static http_addr_t current_addr; /* Current address */ +static int current_state = -1; + /* Current device state bits */ +static int charset = -1; /* Character set for supply names */ +static int num_supplies = 0; + /* Number of supplies found */ +static backend_supplies_t supplies[CUPS_MAX_SUPPLIES]; + /* Supply information */ +static int supply_state = -1; + /* Supply state info */ + +static const int hrDeviceDescr[] = + { CUPS_OID_hrDeviceDescr, 1, -1 }; + /* Device description OID */ +static const int hrPrinterStatus[] = + { CUPS_OID_hrPrinterStatus, 1, -1 }; + /* Current state OID */ +static const int hrPrinterDetectedErrorState[] = + { CUPS_OID_hrPrinterDetectedErrorState, 1, -1 }; + /* Current printer state bits OID */ +static const int prtGeneralCurrentLocalization[] = + { CUPS_OID_prtGeneralCurrentLocalization, 1, -1 }; +static const int prtLocalizationCharacterSet[] = + { CUPS_OID_prtLocalizationCharacterSet, 1, 1, -1 }, + prtLocalizationCharacterSetOffset = + (sizeof(prtLocalizationCharacterSet) / + sizeof(prtLocalizationCharacterSet[0])); +static const int prtMarkerColorantValue[] = + { CUPS_OID_prtMarkerColorantValue, -1 }, + /* Colorant OID */ + prtMarkerColorantValueOffset = + (sizeof(prtMarkerColorantValue) / + sizeof(prtMarkerColorantValue[0])); + /* Offset to colorant index */ +static const int prtMarkerLifeCount[] = + { CUPS_OID_prtMarkerLifeCount, 1, 1, -1 }; + /* Page counter OID */ +static const int prtMarkerSuppliesEntry[] = + { CUPS_OID_prtMarkerSuppliesEntry, -1 }; + /* Supplies OID */ +static const int prtMarkerSuppliesColorantIndex[] = + { CUPS_OID_prtMarkerSuppliesColorantIndex, -1 }, + /* Colorant index OID */ + prtMarkerSuppliesColorantIndexOffset = + (sizeof(prtMarkerSuppliesColorantIndex) / + sizeof(prtMarkerSuppliesColorantIndex[0])); + /* Offset to supply index */ +static const int prtMarkerSuppliesDescription[] = + { CUPS_OID_prtMarkerSuppliesDescription, -1 }, + /* Description OID */ + prtMarkerSuppliesDescriptionOffset = + (sizeof(prtMarkerSuppliesDescription) / + sizeof(prtMarkerSuppliesDescription[0])); + /* Offset to supply index */ +static const int prtMarkerSuppliesLevel[] = + { CUPS_OID_prtMarkerSuppliesLevel, -1 }, + /* Level OID */ + prtMarkerSuppliesLevelOffset = + (sizeof(prtMarkerSuppliesLevel) / + sizeof(prtMarkerSuppliesLevel[0])); + /* Offset to supply index */ +static const int prtMarkerSuppliesMaxCapacity[] = + { CUPS_OID_prtMarkerSuppliesMaxCapacity, -1 }, + /* Max capacity OID */ + prtMarkerSuppliesMaxCapacityOffset = + (sizeof(prtMarkerSuppliesMaxCapacity) / + sizeof(prtMarkerSuppliesMaxCapacity[0])); + /* Offset to supply index */ +static const int prtMarkerSuppliesType[] = + { CUPS_OID_prtMarkerSuppliesType, -1 }, + /* Type OID */ + prtMarkerSuppliesTypeOffset = + (sizeof(prtMarkerSuppliesType) / + sizeof(prtMarkerSuppliesType[0])); + /* Offset to supply index */ + +static const backend_state_t const printer_states[] = + { + { CUPS_TC_lowPaper, "media-low-report" }, + { CUPS_TC_noPaper | CUPS_TC_inputTrayEmpty, "media-empty-warning" }, + /* { CUPS_TC_lowToner, "toner-low-report" }, */ /* now use prtMarkerSupplies */ + /* { CUPS_TC_noToner, "toner-empty-warning" }, */ /* now use prtMarkerSupplies */ + { CUPS_TC_doorOpen, "door-open-report" }, + { CUPS_TC_jammed, "media-jam-warning" }, + /* { CUPS_TC_offline, "offline-report" }, */ /* unreliable */ + /* { CUPS_TC_serviceRequested | CUPS_TC_overduePreventMaint, "service-needed-warning" }, */ /* unreliable */ + { CUPS_TC_inputTrayMissing, "input-tray-missing-warning" }, + { CUPS_TC_outputTrayMissing, "output-tray-missing-warning" }, + { CUPS_TC_markerSupplyMissing, "marker-supply-missing-warning" }, + { CUPS_TC_outputNearFull, "output-area-almost-full-report" }, + { CUPS_TC_outputFull, "output-area-full-warning" } + }; + +static const backend_state_t const supply_states[] = + { + { CUPS_DEVELOPER_LOW, "developer-low-report" }, + { CUPS_DEVELOPER_EMPTY, "developer-empty-warning" }, + { CUPS_MARKER_SUPPLY_LOW, "marker-supply-low-report" }, + { CUPS_MARKER_SUPPLY_EMPTY, "marker-supply-empty-warning" }, + { CUPS_MARKER_WASTE_ALMOST_FULL, "marker-waste-almost-full-report" }, + { CUPS_MARKER_WASTE_FULL, "marker-waste-full-warning" }, + { CUPS_OPC_NEAR_EOL, "opc-near-eol-report" }, + { CUPS_OPC_LIFE_OVER, "opc-life-over-warning" }, + { CUPS_TONER_LOW, "toner-low-report" }, + { CUPS_TONER_EMPTY, "toner-empty-warning" } + }; + + +/* + * Local functions... + */ + +static void backend_init_supplies(int snmp_fd, http_addr_t *addr); +static void backend_walk_cb(cups_snmp_t *packet, void *data); +static void utf16_to_utf8(cups_utf8_t *dst, const unsigned char *src, + size_t srcsize, size_t dstsize, int le); + + +/* + * 'backendSNMPSupplies()' - Get the current supplies for a device. + */ + +int /* O - 0 on success, -1 on error */ +backendSNMPSupplies( + int snmp_fd, /* I - SNMP socket */ + http_addr_t *addr, /* I - Printer address */ + int *page_count, /* O - Page count */ + int *printer_state) /* O - Printer state */ +{ + if (!httpAddrEqual(addr, ¤t_addr)) + backend_init_supplies(snmp_fd, addr); + else if (num_supplies > 0) + _cupsSNMPWalk(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), prtMarkerSuppliesLevel, + CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL); + + if (page_count) + *page_count = -1; + + if (printer_state) + *printer_state = -1; + + if (num_supplies > 0) + { + int i, /* Looping var */ + percent, /* Percent full */ + new_state, /* New state value */ + change_state, /* State change */ + new_supply_state = 0; /* Supply state */ + char value[CUPS_MAX_SUPPLIES * 4], + /* marker-levels value string */ + *ptr; /* Pointer into value string */ + cups_snmp_t packet; /* SNMP response packet */ + + /* + * Generate the marker-levels value string... + */ + + for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) + { + percent = 100 * supplies[i].level / supplies[i].max_capacity; + + if (percent <= 10) + { + switch (supplies[i].type) + { + case CUPS_TC_toner : + case CUPS_TC_tonerCartridge : + if (percent <= 1) + new_supply_state |= CUPS_TONER_EMPTY; + else + new_supply_state |= CUPS_TONER_LOW; + break; + case CUPS_TC_wasteToner : + case CUPS_TC_wasteInk : + if (percent <= 1) + new_supply_state |= CUPS_MARKER_WASTE_FULL; + else + new_supply_state |= CUPS_MARKER_WASTE_ALMOST_FULL; + break; + case CUPS_TC_ink : + case CUPS_TC_inkCartridge : + case CUPS_TC_inkRibbon : + case CUPS_TC_solidWax : + case CUPS_TC_ribbonWax : + if (percent <= 1) + new_supply_state |= CUPS_MARKER_SUPPLY_EMPTY; + else + new_supply_state |= CUPS_MARKER_SUPPLY_LOW; + break; + case CUPS_TC_developer : + if (percent <= 1) + new_supply_state |= CUPS_DEVELOPER_EMPTY; + else + new_supply_state |= CUPS_DEVELOPER_LOW; + break; + case CUPS_TC_coronaWire : + case CUPS_TC_fuser : + case CUPS_TC_opc : + case CUPS_TC_transferUnit : + if (percent <= 1) + new_supply_state |= CUPS_OPC_LIFE_OVER; + else + new_supply_state |= CUPS_OPC_NEAR_EOL; + break; + } + } + + if (i) + *ptr++ = ','; + + if (supplies[i].max_capacity > 0) + sprintf(ptr, "%d", percent); + else + strcpy(ptr, "-1"); + } + + fprintf(stderr, "ATTR: marker-levels=%s\n", value); + + if (supply_state < 0) + change_state = 0xffff; + else + change_state = supply_state ^ new_supply_state; + + fprintf(stderr, "DEBUG: new_supply_state=%x, change_state=%x\n", + new_supply_state, change_state); + + for (i = 0; + i < (int)(sizeof(supply_states) / sizeof(supply_states[0])); + i ++) + if (change_state & supply_states[i].bit) + { + fprintf(stderr, "STATE: %c%s\n", + (new_supply_state & supply_states[i].bit) ? '+' : '-', + supply_states[i].keyword); + } + + supply_state = new_supply_state; + + /* + * Get the current printer status bits... + */ + + if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1, + hrPrinterDetectedErrorState)) + return (-1); + + if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) || + packet.object_type != CUPS_ASN1_OCTET_STRING) + return (-1); + + if (packet.object_value.string.num_bytes == 2) + new_state = (packet.object_value.string.bytes[0] << 8) | + packet.object_value.string.bytes[1]; + else if (packet.object_value.string.num_bytes == 1) + new_state = (packet.object_value.string.bytes[0] << 8); + else + new_state = 0; + + if (current_state < 0) + change_state = 0xffff; + else + change_state = current_state ^ new_state; + + fprintf(stderr, "DEBUG: new_state=%x, change_state=%x\n", new_state, + change_state); + + for (i = 0; + i < (int)(sizeof(printer_states) / sizeof(printer_states[0])); + i ++) + if (change_state & printer_states[i].bit) + { + fprintf(stderr, "STATE: %c%s\n", + (new_state & printer_states[i].bit) ? '+' : '-', + printer_states[i].keyword); + } + + current_state = new_state; + + /* + * Get the current printer state... + */ + + if (printer_state) + { + if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1, + hrPrinterStatus)) + return (-1); + + if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) || + packet.object_type != CUPS_ASN1_INTEGER) + return (-1); + + *printer_state = packet.object_value.integer; + } + + /* + * Get the current page count... + */ + + if (page_count) + { + if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1, + prtMarkerLifeCount)) + return (-1); + + if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) || + packet.object_type != CUPS_ASN1_COUNTER) + return (-1); + + *page_count = packet.object_value.counter; + } + + return (0); + } + else + return (-1); +} + + +/* + * 'backend_init_supplies()' - Initialize the supplies list. + */ + +static void +backend_init_supplies( + int snmp_fd, /* I - SNMP socket */ + http_addr_t *addr) /* I - Printer address */ +{ + int i, /* Looping var */ + type; /* Current marker type */ + cups_file_t *cachefile; /* Cache file */ + const char *cachedir; /* CUPS_CACHEDIR value */ + char addrstr[1024], /* Address string */ + cachefilename[1024], /* Cache filename */ + description[CUPS_SNMP_MAX_STRING], + /* Device description string */ + value[CUPS_MAX_SUPPLIES * (CUPS_SNMP_MAX_STRING * 2 + 3)], + /* Value string */ + *ptr, /* Pointer into value string */ + *name_ptr; /* Pointer into name string */ + cups_snmp_t packet; /* SNMP response packet */ + ppd_file_t *ppd; /* PPD file for this queue */ + ppd_attr_t *ppdattr; /* cupsSNMPSupplies attribute */ + static const char * const types[] = /* Supply types */ + { + "other", + "unknown", + "toner", + "wasteToner", + "ink", + "inkCartridge", + "inkRibbon", + "wasteInk", + "opc", + "developer", + "fuserOil", + "solidWax", + "ribbonWax", + "wasteWax", + "fuser", + "coronaWire", + "fuserOilWick", + "cleanerUnit", + "fuserCleaningPad", + "transferUnit", + "tonerCartridge", + "fuserOiler", + "water", + "wasteWater", + "glueWaterAdditive", + "wastePaper", + "bindingSupply", + "bandingSupply", + "stitchingWire", + "shrinkWrap", + "paperWrap", + "staples", + "inserts", + "covers" + }; + + + /* + * Reset state information... + */ + + current_addr = *addr; + current_state = -1; + num_supplies = -1; + charset = -1; + + memset(supplies, 0, sizeof(supplies)); + + /* + * See if we should be getting supply levels via SNMP... + */ + + if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL || + ((ppdattr = ppdFindAttr(ppd, "cupsSNMPSupplies", NULL)) != NULL && + ppdattr->value && strcasecmp(ppdattr->value, "true"))) + { + ppdClose(ppd); + return; + } + + ppdClose(ppd); + + /* + * Get the device description... + */ + + if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1, + hrDeviceDescr)) + return; + + if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) || + packet.object_type != CUPS_ASN1_OCTET_STRING) + { + strlcpy(description, "Unknown", sizeof(description)); + num_supplies = 0; + } + else + strlcpy(description, (char *)packet.object_value.string.bytes, + sizeof(description)); + + fprintf(stderr, "DEBUG2: hrDeviceDesc=\"%s\"\n", description); + + /* + * See if we have already queried this device... + */ + + httpAddrString(addr, addrstr, sizeof(addrstr)); + + if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL) + cachedir = CUPS_CACHEDIR; + + snprintf(cachefilename, sizeof(cachefilename), "%s/%s.snmp", cachedir, + addrstr); + + if ((cachefile = cupsFileOpen(cachefilename, "r")) != NULL) + { + /* + * Yes, read the cache file: + * + * 2 num_supplies charset + * device description + * supply structures... + */ + + if (cupsFileGets(cachefile, value, sizeof(value))) + { + if (sscanf(value, "2 %d%d", &num_supplies, &charset) == 2 && + num_supplies <= CUPS_MAX_SUPPLIES && + cupsFileGets(cachefile, value, sizeof(value))) + { + if (!strcmp(description, value)) + cupsFileRead(cachefile, (char *)supplies, + num_supplies * sizeof(backend_supplies_t)); + else + { + num_supplies = -1; + charset = -1; + } + } + else + { + num_supplies = -1; + charset = -1; + } + } + + cupsFileClose(cachefile); + } + + /* + * If the cache information isn't correct, scan for supplies... + */ + + if (charset < 0) + { + /* + * Get the configured character set... + */ + + int oid[CUPS_SNMP_MAX_OID]; /* OID for character set */ + + + if (!_cupsSNMPWrite(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1, + prtGeneralCurrentLocalization)) + return; + + if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) || + packet.object_type != CUPS_ASN1_INTEGER) + { + fprintf(stderr, + "DEBUG: prtGeneralCurrentLocalization type is %x, expected %x!\n", + packet.object_type, CUPS_ASN1_INTEGER); + return; + } + + fprintf(stderr, "DEBUG2: prtGeneralCurrentLocalization=%d\n", + packet.object_value.integer); + + _cupsSNMPCopyOID(oid, prtLocalizationCharacterSet, CUPS_SNMP_MAX_OID); + oid[prtLocalizationCharacterSetOffset - 2] = packet.object_value.integer; + + + if (!_cupsSNMPWrite(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1, + oid)) + return; + + if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) || + packet.object_type != CUPS_ASN1_INTEGER) + { + fprintf(stderr, + "DEBUG: prtLocalizationCharacterSet type is %x, expected %x!\n", + packet.object_type, CUPS_ASN1_INTEGER); + return; + } + + fprintf(stderr, "DEBUG2: prtLocalizationCharacterSet=%d\n", + packet.object_value.integer); + charset = packet.object_value.integer; + } + + if (num_supplies < 0) + { + /* + * Walk the printer configuration information... + */ + + _cupsSNMPWalk(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), prtMarkerSuppliesEntry, + CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL); + } + + /* + * Save the cached information... + */ + + if (num_supplies < 0) + num_supplies = 0; + + if ((cachefile = cupsFileOpen(cachefilename, "w")) != NULL) + { + cupsFilePrintf(cachefile, "2 %d %d\n", num_supplies, charset); + cupsFilePrintf(cachefile, "%s\n", description); + + if (num_supplies > 0) + cupsFileWrite(cachefile, (char *)supplies, + num_supplies * sizeof(backend_supplies_t)); + + cupsFileClose(cachefile); + } + + if (num_supplies <= 0) + return; + + /* + * Get the colors... + */ + + for (i = 0; i < num_supplies; i ++) + strcpy(supplies[i].color, "none"); + + _cupsSNMPWalk(snmp_fd, ¤t_addr, CUPS_SNMP_VERSION_1, + _cupsSNMPDefaultCommunity(), prtMarkerColorantValue, + CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL); + + /* + * Output the marker-colors attribute... + */ + + for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) + { + if (i) + *ptr++ = ','; + + strcpy(ptr, supplies[i].color); + } + + fprintf(stderr, "ATTR: marker-colors=%s\n", value); + + /* + * Output the marker-names attribute... + */ + + for (i = 0, ptr = value; i < num_supplies; i ++) + { + if (i) + *ptr++ = ','; + + *ptr++ = '\"'; + for (name_ptr = supplies[i].name; *name_ptr;) + { + if (*name_ptr == '\\' || *name_ptr == '\"') + *ptr++ = '\\'; + + *ptr++ = *name_ptr++; + } + *ptr++ = '\"'; + } + + *ptr = '\0'; + + fprintf(stderr, "ATTR: marker-names=%s\n", value); + + /* + * Output the marker-types attribute... + */ + + for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr)) + { + if (i) + *ptr++ = ','; + + type = supplies[i].type; + + if (type < CUPS_TC_other || type > CUPS_TC_covers) + strcpy(ptr, "unknown"); + else + strcpy(ptr, types[type - CUPS_TC_other]); + } + + fprintf(stderr, "ATTR: marker-types=%s\n", value); +} + + +/* + * 'backend_walk_cb()' - Interpret the supply value responses. + */ + +static void +backend_walk_cb(cups_snmp_t *packet, /* I - SNMP packet */ + void *data) /* I - User data (unused) */ +{ + int i, j, k; /* Looping vars */ + static const char * const colors[8][2] = + { /* Standard color names */ + { "black", "#000000" }, + { "blue", "#0000FF" }, + { "cyan", "#00FFFF" }, + { "green", "#00FF00" }, + { "magenta", "#FF00FF" }, + { "red", "#FF0000" }, + { "white", "#FFFFFF" }, + { "yellow", "#FFFF00" } + }; + + + (void)data; + + if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerColorantValue) && + packet->object_type == CUPS_ASN1_OCTET_STRING) + { + /* + * Get colorant... + */ + + i = packet->object_name[prtMarkerColorantValueOffset]; + + fprintf(stderr, "DEBUG2: prtMarkerColorantValue.1.%d = \"%s\"\n", i, + (char *)packet->object_value.string.bytes); + + for (j = 0; j < num_supplies; j ++) + if (supplies[j].colorant == i) + { + for (k = 0; k < (int)(sizeof(colors) / sizeof(colors[0])); k ++) + if (!strcmp(colors[k][0], (char *)packet->object_value.string.bytes)) + { + strcpy(supplies[j].color, colors[k][1]); + break; + } + } + } + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesColorantIndex)) + { + /* + * Get colorant index... + */ + + i = packet->object_name[prtMarkerSuppliesColorantIndexOffset]; + if (i < 1 || i > CUPS_MAX_SUPPLIES || + packet->object_type != CUPS_ASN1_INTEGER) + return; + + fprintf(stderr, "DEBUG2: prtMarkerSuppliesColorantIndex.1.%d = %d\n", i, + packet->object_value.integer); + + if (i > num_supplies) + num_supplies = i; + + supplies[i - 1].colorant = packet->object_value.integer; + } + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesDescription)) + { + /* + * Get supply name/description... + */ + + i = packet->object_name[prtMarkerSuppliesDescriptionOffset]; + if (i < 1 || i > CUPS_MAX_SUPPLIES || + packet->object_type != CUPS_ASN1_OCTET_STRING) + return; + + if (i > num_supplies) + num_supplies = i; + + switch (charset) + { + case CUPS_TC_csASCII : + case CUPS_TC_csUTF8 : + case CUPS_TC_csUnicodeASCII : + strlcpy(supplies[i - 1].name, + (char *)packet->object_value.string.bytes, + sizeof(supplies[0].name)); + break; + + case CUPS_TC_csISOLatin1 : + case CUPS_TC_csUnicodeLatin1 : + cupsCharsetToUTF8((cups_utf8_t *)supplies[i - 1].name, + (char *)packet->object_value.string.bytes, + sizeof(supplies[0].name), CUPS_ISO8859_1); + break; + + case CUPS_TC_csShiftJIS : + cupsCharsetToUTF8((cups_utf8_t *)supplies[i - 1].name, + (char *)packet->object_value.string.bytes, + sizeof(supplies[0].name), CUPS_JIS_X0213); + break; + + case CUPS_TC_csUCS4 : + case CUPS_TC_csUTF32 : + case CUPS_TC_csUTF32BE : + case CUPS_TC_csUTF32LE : + cupsUTF32ToUTF8((cups_utf8_t *)supplies[i - 1].name, + (cups_utf32_t *)packet->object_value.string.bytes, + sizeof(supplies[0].name)); + break; + + case CUPS_TC_csUnicode : + case CUPS_TC_csUTF16BE : + case CUPS_TC_csUTF16LE : + utf16_to_utf8((cups_utf8_t *)supplies[i - 1].name, + packet->object_value.string.bytes, + packet->object_value.string.num_bytes, + sizeof(supplies[0].name), charset == CUPS_TC_csUTF16LE); + break; + + default : + /* + * If we get here, the printer is using an unknown character set and + * we just want to copy characters that look like ASCII... + */ + + { + char *src, *dst; /* Pointers into strings */ + + + /* + * Loop safe because both the object_value and supplies char arrays + * are CUPS_SNMP_MAX_STRING elements long. + */ + + for (src = (char *)packet->object_value.string.bytes, + dst = supplies[i - 1].name; + *src; + src ++) + { + if ((*src & 0x80) || *src < ' ' || *src == 0x7f) + *dst++ = '?'; + else + *dst++ = *src; + } + + *dst = '\0'; + } + break; + } + + fprintf(stderr, "DEBUG2: prtMarkerSuppliesDescription.1.%d = \"%s\"\n", i, + supplies[i - 1].name); + + } + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesLevel)) + { + /* + * Get level... + */ + + i = packet->object_name[prtMarkerSuppliesLevelOffset]; + if (i < 1 || i > CUPS_MAX_SUPPLIES || + packet->object_type != CUPS_ASN1_INTEGER) + return; + + fprintf(stderr, "DEBUG2: prtMarkerSuppliesLevel.1.%d = %d\n", i, + packet->object_value.integer); + + if (i > num_supplies) + num_supplies = i; + + supplies[i - 1].level = packet->object_value.integer; + } + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesMaxCapacity)) + { + /* + * Get max capacity... + */ + + i = packet->object_name[prtMarkerSuppliesMaxCapacityOffset]; + if (i < 1 || i > CUPS_MAX_SUPPLIES || + packet->object_type != CUPS_ASN1_INTEGER) + return; + + fprintf(stderr, "DEBUG2: prtMarkerSuppliesMaxCapacity.1.%d = %d\n", i, + packet->object_value.integer); + + if (i > num_supplies) + num_supplies = i; + + supplies[i - 1].max_capacity = packet->object_value.integer; + } + else if (_cupsSNMPIsOIDPrefixed(packet, prtMarkerSuppliesType)) + { + /* + * Get marker type... + */ + + i = packet->object_name[prtMarkerSuppliesTypeOffset]; + if (i < 1 || i > CUPS_MAX_SUPPLIES || + packet->object_type != CUPS_ASN1_INTEGER) + return; + + fprintf(stderr, "DEBUG2: prtMarkerSuppliesType.1.%d = %d\n", i, + packet->object_value.integer); + + if (i > num_supplies) + num_supplies = i; + + supplies[i - 1].type = packet->object_value.integer; + } +} + + +/* + * 'utf16_to_utf8()' - Convert UTF-16 text to UTF-8. + */ + +static void +utf16_to_utf8( + cups_utf8_t *dst, /* I - Destination buffer */ + const unsigned char *src, /* I - Source string */ + size_t srcsize, /* I - Size of source string */ + size_t dstsize, /* I - Size of destination buffer */ + int le) /* I - Source is little-endian? */ +{ + cups_utf32_t ch, /* Current character */ + temp[CUPS_SNMP_MAX_STRING], + /* UTF-32 string */ + *ptr; /* Pointer into UTF-32 string */ + + + for (ptr = temp; srcsize >= 2;) + { + if (le) + ch = src[0] | (src[1] << 8); + else + ch = (src[0] << 8) | src[1]; + + src += 2; + srcsize -= 2; + + if (ch >= 0xd800 && ch <= 0xdbff && srcsize >= 2) + { + /* + * Multi-word UTF-16 char... + */ + + int lch; /* Lower word */ + + + if (le) + lch = src[0] | (src[1] << 8); + else + lch = (src[0] << 8) | src[1]; + + if (lch >= 0xdc00 && lch <= 0xdfff) + { + src += 2; + srcsize -= 2; + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + } + + if (ptr < (temp + CUPS_SNMP_MAX_STRING - 1)) + *ptr++ = ch; + } + + *ptr = '\0'; + + cupsUTF32ToUTF8(dst, temp, dstsize); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/snmp.c b/backend/snmp.c new file mode 100644 index 0000000000..b315799854 --- /dev/null +++ b/backend/snmp.c @@ -0,0 +1,1341 @@ +/* + * "$Id$" + * + * SNMP discovery backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Discover printers via SNMP. + * add_array() - Add a string to an array. + * add_cache() - Add a cached device... + * add_device_uri() - Add a device URI to the cache. + * alarm_handler() - Handle alarm signals... + * compare_cache() - Compare two cache entries. + * debug_printf() - Display some debugging information. + * fix_make_model() - Fix common problems in the make-and-model + * string. + * free_array() - Free an array of strings. + * free_cache() - Free the array of cached devices. + * get_interface_addresses() - Get the broadcast address(es) associated with + * an interface. + * list_device() - List a device we found... + * password_cb() - Handle authentication requests. + * probe_device() - Probe a device to discover whether it is a + * printer. + * read_snmp_conf() - Read the snmp.conf file. + * read_snmp_response() - Read and parse a SNMP response... + * run_time() - Return the total running time... + * scan_devices() - Scan for devices using SNMP. + * try_connect() - Try connecting on a port... + * update_cache() - Update a cached device... + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" +#include +#include +#include +#include + + +/* + * This backend implements SNMP printer discovery. It uses a broadcast- + * based approach to get SNMP response packets from potential printers, + * requesting OIDs from the Host and Port Monitor MIBs, does a URI + * lookup based on the device description string, and finally a probe of + * port 9100 (AppSocket) and 515 (LPD). + * + * The current focus is on printers with internal network cards, although + * the code also works with many external print servers as well. + * + * The backend reads the snmp.conf file from the CUPS_SERVERROOT directory + * which can contain comments, blank lines, or any number of the following + * directives: + * + * Address ip-address + * Address @LOCAL + * Address @IF(name) + * Community name + * DebugLevel N + * DeviceURI "regex pattern" uri + * HostNameLookups on + * HostNameLookups off + * MaxRunTime N + * + * The default is to use: + * + * Address @LOCAL + * Community public + * DebugLevel 0 + * HostNameLookups off + * MaxRunTime 120 + * + * This backend is known to work with the following network printers and + * print servers: + * + * Axis OfficeBasic, 5400, 5600 + * Brother + * EPSON + * Genicom + * HP JetDirect + * Lexmark + * Sharp + * Tektronix + * Xerox + * + * It does not currently work with: + * + * DLink + * Linksys + * Netgear + * Okidata + * + * (for all of these, they do not support the Host MIB) + */ + +/* + * Types... + */ + +enum /**** Request IDs for each field ****/ +{ + DEVICE_TYPE = 1, + DEVICE_DESCRIPTION, + DEVICE_LOCATION, + DEVICE_ID, + DEVICE_URI, + DEVICE_PRODUCT +}; + +typedef struct device_uri_s /**** DeviceURI values ****/ +{ + regex_t re; /* Regular expression to match */ + cups_array_t *uris; /* URIs */ +} device_uri_t; + +typedef struct snmp_cache_s /**** SNMP scan cache ****/ +{ + http_addr_t address; /* Address of device */ + char *addrname, /* Name of device */ + *uri, /* device-uri */ + *id, /* device-id */ + *info, /* device-info */ + *location, /* device-location */ + *make_and_model; /* device-make-and-model */ + int sent; /* Has this device been listed? */ +} snmp_cache_t; + + +/* + * Private CUPS API to set the last error... + */ + +extern void _cupsSetError(ipp_status_t status, const char *message); + + +/* + * Local functions... + */ + +static char *add_array(cups_array_t *a, const char *s); +static void add_cache(http_addr_t *addr, const char *addrname, + const char *uri, const char *id, + const char *make_and_model); +static device_uri_t *add_device_uri(char *value); +static void alarm_handler(int sig); +static int compare_cache(snmp_cache_t *a, snmp_cache_t *b); +static void debug_printf(const char *format, ...); +static void fix_make_model(char *make_model, + const char *old_make_model, + int make_model_size); +static void free_array(cups_array_t *a); +static void free_cache(void); +static http_addrlist_t *get_interface_addresses(const char *ifname); +static void list_device(snmp_cache_t *cache); +static const char *password_cb(const char *prompt); +static void probe_device(snmp_cache_t *device); +static void read_snmp_conf(const char *address); +static void read_snmp_response(int fd); +static double run_time(void); +static void scan_devices(int fd); +static int try_connect(http_addr_t *addr, const char *addrname, + int port); +static void update_cache(snmp_cache_t *device, const char *uri, + const char *id, const char *make_model); + + +/* + * Local globals... + */ + +static cups_array_t *Addresses = NULL; +static cups_array_t *Communities = NULL; +static cups_array_t *Devices = NULL; +static int DebugLevel = 0; +static const int DescriptionOID[] = { CUPS_OID_hrDeviceDescr, 1, -1 }; +static const int LocationOID[] = { CUPS_OID_sysLocation, 0, -1 }; +static const int DeviceTypeOID[] = { CUPS_OID_hrDeviceType, 1, -1 }; +static const int DeviceIdOID[] = { CUPS_OID_ppmPrinterIEEE1284DeviceId, 1, -1 }; +static const int UriOID[] = { CUPS_OID_ppmPortServiceNameOrURI, 1, 1, -1 }; +static const int LexmarkProductOID[] = { 1,3,6,1,4,1,641,2,1,2,1,2,1,-1 }; +static const int LexmarkProductOID2[] = { 1,3,6,1,4,1,674,10898,100,2,1,2,1,2,1,-1 }; +static const int LexmarkDeviceIdOID[] = { 1,3,6,1,4,1,641,2,1,2,1,3,1,-1 }; +static const int XeroxProductOID[] = { 1,3,6,1,4,1,128,2,1,3,1,2,0,-1 }; +static cups_array_t *DeviceURIs = NULL; +static int HostNameLookups = 0; +static int MaxRunTime = 120; +static struct timeval StartTime; + + +/* + * 'main()' - Discover printers via SNMP. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + int fd; /* SNMP socket */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * Check command-line options... + */ + + if (argc > 2) + { + fputs(_("Usage: snmp [host-or-ip-address]\n"), stderr); + return (1); + } + + /* + * Set the password callback for IPP operations... + */ + + cupsSetPasswordCB(password_cb); + + /* + * Catch SIGALRM signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGALRM, alarm_handler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGALRM); + action.sa_handler = alarm_handler; + sigaction(SIGALRM, &action, NULL); +#else + signal(SIGALRM, alarm_handler); +#endif /* HAVE_SIGSET */ + + /* + * Open the SNMP socket... + */ + + if ((fd = _cupsSNMPOpen(AF_INET)) < 0) + return (1); + + /* + * Read the configuration file and any cache data... + */ + + read_snmp_conf(argv[1]); + + _cupsSNMPSetDebug(DebugLevel); + + Devices = cupsArrayNew((cups_array_func_t)compare_cache, NULL); + + /* + * Scan for devices... + */ + + scan_devices(fd); + + /* + * Close, free, and return with no errors... + */ + + _cupsSNMPClose(fd); + + free_array(Addresses); + free_array(Communities); + free_cache(); + + return (0); +} + + +/* + * 'add_array()' - Add a string to an array. + */ + +static char * /* O - New string */ +add_array(cups_array_t *a, /* I - Array */ + const char *s) /* I - String to add */ +{ + char *dups; /* New string */ + + + dups = strdup(s); + + cupsArrayAdd(a, dups); + + return (dups); +} + + +/* + * 'add_cache()' - Add a cached device... + */ + +static void +add_cache(http_addr_t *addr, /* I - Device IP address */ + const char *addrname, /* I - IP address or name string */ + const char *uri, /* I - Device URI */ + const char *id, /* I - 1284 device ID */ + const char *make_and_model) /* I - Make and model */ +{ + snmp_cache_t *temp; /* New device entry */ + + + debug_printf("DEBUG: add_cache(addr=%p, addrname=\"%s\", uri=\"%s\", " + "id=\"%s\", make_and_model=\"%s\")\n", + addr, addrname, uri ? uri : "(null)", id ? id : "(null)", + make_and_model ? make_and_model : "(null)"); + + temp = calloc(1, sizeof(snmp_cache_t)); + memcpy(&(temp->address), addr, sizeof(temp->address)); + + temp->addrname = strdup(addrname); + + if (uri) + temp->uri = strdup(uri); + + if (id) + temp->id = strdup(id); + + if (make_and_model) + temp->make_and_model = strdup(make_and_model); + + cupsArrayAdd(Devices, temp); + + if (uri) + list_device(temp); +} + + +/* + * 'add_device_uri()' - Add a device URI to the cache. + * + * The value string is modified (chopped up) as needed. + */ + +static device_uri_t * /* O - Device URI */ +add_device_uri(char *value) /* I - Value from snmp.conf */ +{ + device_uri_t *device_uri; /* Device URI */ + char *start; /* Start of value */ + + + /* + * Allocate memory as needed... + */ + + if (!DeviceURIs) + DeviceURIs = cupsArrayNew(NULL, NULL); + + if (!DeviceURIs) + return (NULL); + + if ((device_uri = calloc(1, sizeof(device_uri_t))) == NULL) + return (NULL); + + if ((device_uri->uris = cupsArrayNew(NULL, NULL)) == NULL) + { + free(device_uri); + return (NULL); + } + + /* + * Scan the value string for the regular expression and URI(s)... + */ + + value ++; /* Skip leading " */ + + for (start = value; *value && *value != '\"'; value ++) + if (*value == '\\' && value[1]) + _cups_strcpy(value, value + 1); + + if (!*value) + { + fputs("ERROR: Missing end quote for DeviceURI!\n", stderr); + + cupsArrayDelete(device_uri->uris); + free(device_uri); + + return (NULL); + } + + *value++ = '\0'; + + if (regcomp(&(device_uri->re), start, REG_EXTENDED | REG_ICASE)) + { + fputs("ERROR: Bad regular expression for DeviceURI!\n", stderr); + + cupsArrayDelete(device_uri->uris); + free(device_uri); + + return (NULL); + } + + while (*value) + { + while (isspace(*value & 255)) + value ++; + + if (!*value) + break; + + for (start = value; *value && !isspace(*value & 255); value ++); + + if (*value) + *value++ = '\0'; + + cupsArrayAdd(device_uri->uris, strdup(start)); + } + + /* + * Add the device URI to the list and return it... + */ + + cupsArrayAdd(DeviceURIs, device_uri); + + return (device_uri); +} + + +/* + * 'alarm_handler()' - Handle alarm signals... + */ + +static void +alarm_handler(int sig) /* I - Signal number */ +{ + /* + * Do nothing... + */ + + (void)sig; + +#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) + signal(SIGALRM, alarm_handler); +#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */ + + if (DebugLevel) + write(2, "DEBUG: ALARM!\n", 14); +} + + +/* + * 'compare_cache()' - Compare two cache entries. + */ + +static int /* O - Result of comparison */ +compare_cache(snmp_cache_t *a, /* I - First cache entry */ + snmp_cache_t *b) /* I - Second cache entry */ +{ + return (strcasecmp(a->addrname, b->addrname)); +} + + +/* + * 'debug_printf()' - Display some debugging information. + */ + +static void +debug_printf(const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to arguments */ + + + if (!DebugLevel) + return; + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} + + +/* + * 'fix_make_model()' - Fix common problems in the make-and-model string. + */ + +static void +fix_make_model( + char *make_model, /* I - New make-and-model string */ + const char *old_make_model, /* I - Old make-and-model string */ + int make_model_size) /* I - Size of new string buffer */ +{ + char *mmptr; /* Pointer into make-and-model string */ + + + /* + * Fix some common problems with the make-and-model string so + * that printer driver detection works better... + */ + + if (!strncasecmp(old_make_model, "Hewlett-Packard", 15)) + { + /* + * Strip leading Hewlett-Packard and hp prefixes and replace + * with a single HP manufacturer prefix... + */ + + mmptr = (char *)old_make_model + 15; + + while (isspace(*mmptr & 255)) + mmptr ++; + + if (!strncasecmp(mmptr, "hp", 2)) + { + mmptr += 2; + + while (isspace(*mmptr & 255)) + mmptr ++; + } + + make_model[0] = 'H'; + make_model[1] = 'P'; + make_model[2] = ' '; + strlcpy(make_model + 3, mmptr, make_model_size - 3); + } + else if (!strncasecmp(old_make_model, "deskjet", 7)) + snprintf(make_model, make_model_size, "HP DeskJet%s", old_make_model + 7); + else if (!strncasecmp(old_make_model, "officejet", 9)) + snprintf(make_model, make_model_size, "HP OfficeJet%s", old_make_model + 9); + else if (!strncasecmp(old_make_model, "stylus_pro_", 11)) + snprintf(make_model, make_model_size, "EPSON Stylus Pro %s", + old_make_model + 11); + else + strlcpy(make_model, old_make_model, make_model_size); + + if ((mmptr = strstr(make_model, ", Inc.,")) != NULL) + { + /* + * Strip inc. from name, e.g. "Tektronix, Inc., Phaser 560" + * becomes "Tektronix Phaser 560"... + */ + + _cups_strcpy(mmptr, mmptr + 7); + } + + if ((mmptr = strstr(make_model, " Network")) != NULL) + { + /* + * Drop unnecessary informational text, e.g. "Xerox DocuPrint N2025 + * Network LaserJet - 2.12" becomes "Xerox DocuPrint N2025"... + */ + + *mmptr = '\0'; + } + + if ((mmptr = strchr(make_model, ',')) != NULL) + { + /* + * Drop anything after a trailing comma... + */ + + *mmptr = '\0'; + } +} + + +/* + * 'free_array()' - Free an array of strings. + */ + +static void +free_array(cups_array_t *a) /* I - Array */ +{ + char *s; /* Current string */ + + + for (s = (char *)cupsArrayFirst(a); s; s = (char *)cupsArrayNext(a)) + free(s); + + cupsArrayDelete(a); +} + + +/* + * 'free_cache()' - Free the array of cached devices. + */ + +static void +free_cache(void) +{ + snmp_cache_t *cache; /* Cached device */ + + + for (cache = (snmp_cache_t *)cupsArrayFirst(Devices); + cache; + cache = (snmp_cache_t *)cupsArrayNext(Devices)) + { + free(cache->addrname); + + if (cache->uri) + free(cache->uri); + + if (cache->id) + free(cache->id); + + if (cache->make_and_model) + free(cache->make_and_model); + + free(cache); + } + + cupsArrayDelete(Devices); + Devices = NULL; +} + + +/* + * 'get_interface_addresses()' - Get the broadcast address(es) associated + * with an interface. + */ + +static http_addrlist_t * /* O - List of addresses */ +get_interface_addresses( + const char *ifname) /* I - Interface name */ +{ + struct ifaddrs *addrs, /* Interface address list */ + *addr; /* Current interface address */ + http_addrlist_t *first, /* First address in list */ + *last, /* Last address in list */ + *current; /* Current address */ + + + if (getifaddrs(&addrs) < 0) + return (NULL); + + for (addr = addrs, first = NULL, last = NULL; addr; addr = addr->ifa_next) + if ((addr->ifa_flags & IFF_BROADCAST) && addr->ifa_broadaddr && + addr->ifa_broadaddr->sa_family == AF_INET && + (!ifname || !strcmp(ifname, addr->ifa_name))) + { + current = calloc(1, sizeof(http_addrlist_t)); + + memcpy(&(current->addr), addr->ifa_broadaddr, + sizeof(struct sockaddr_in)); + + if (!last) + first = current; + else + last->next = current; + + last = current; + } + + freeifaddrs(addrs); + + return (first); +} + + +/* + * 'list_device()' - List a device we found... + */ + +static void +list_device(snmp_cache_t *cache) /* I - Cached device */ +{ + if (cache->uri) + cupsBackendReport("network", cache->uri, cache->make_and_model, + cache->info, cache->id, cache->location); +} + + +/* + * 'password_cb()' - Handle authentication requests. + * + * All we do right now is return NULL, indicating that no authentication + * is possible. + */ + +static const char * /* O - Password (NULL) */ +password_cb(const char *prompt) /* I - Prompt message */ +{ + (void)prompt; /* Anti-compiler-warning-code */ + + return (NULL); +} + + +/* + * 'probe_device()' - Probe a device to discover whether it is a printer. + * + * TODO: Try using the Port Monitor MIB to discover the correct protocol + * to use - first need a commercially-available printer that supports + * it, though... + */ + +static void +probe_device(snmp_cache_t *device) /* I - Device */ +{ + char uri[1024], /* Full device URI */ + *uriptr, /* Pointer into URI */ + *format; /* Format string for device */ + device_uri_t *device_uri; /* Current DeviceURI match */ + + + debug_printf("DEBUG: %.3f Probing %s...\n", run_time(), device->addrname); + +#ifdef __APPLE__ + /* + * TODO: Try an mDNS query first, and then fallback on direct probes... + */ + + if (!try_connect(&(device->address), device->addrname, 5353)) + { + debug_printf("DEBUG: %s supports mDNS, not reporting!\n", device->addrname); + return; + } +#endif /* __APPLE__ */ + + /* + * Lookup the device in the match table... + */ + + for (device_uri = (device_uri_t *)cupsArrayFirst(DeviceURIs); + device_uri; + device_uri = (device_uri_t *)cupsArrayNext(DeviceURIs)) + if (device->make_and_model && + !regexec(&(device_uri->re), device->make_and_model, 0, NULL, 0)) + { + /* + * Found a match, add the URIs... + */ + + for (format = (char *)cupsArrayFirst(device_uri->uris); + format; + format = (char *)cupsArrayNext(device_uri->uris)) + { + for (uriptr = uri; *format && uriptr < (uri + sizeof(uri) - 1);) + if (*format == '%' && format[1] == 's') + { + /* + * Insert hostname/address... + */ + + strlcpy(uriptr, device->addrname, sizeof(uri) - (uriptr - uri)); + uriptr += strlen(uriptr); + format += 2; + } + else + *uriptr++ = *format++; + + *uriptr = '\0'; + + update_cache(device, uri, NULL, NULL); + } + + return; + } + + /* + * Then try the standard ports... + */ + + if (!try_connect(&(device->address), device->addrname, 9100)) + { + debug_printf("DEBUG: %s supports AppSocket!\n", device->addrname); + + snprintf(uri, sizeof(uri), "socket://%s", device->addrname); + update_cache(device, uri, NULL, NULL); + } + else if (!try_connect(&(device->address), device->addrname, 515)) + { + debug_printf("DEBUG: %s supports LPD!\n", device->addrname); + + snprintf(uri, sizeof(uri), "lpd://%s/", device->addrname); + update_cache(device, uri, NULL, NULL); + } +} + + +/* + * 'read_snmp_conf()' - Read the snmp.conf file. + */ + +static void +read_snmp_conf(const char *address) /* I - Single address to probe */ +{ + cups_file_t *fp; /* File pointer */ + char filename[1024], /* Filename */ + line[1024], /* Line from file */ + *value; /* Value on line */ + int linenum; /* Line number */ + const char *cups_serverroot; /* CUPS_SERVERROOT env var */ + const char *debug; /* CUPS_DEBUG_LEVEL env var */ + const char *runtime; /* CUPS_MAX_RUN_TIME env var */ + + + /* + * Initialize the global address and community lists... + */ + + Addresses = cupsArrayNew(NULL, NULL); + Communities = cupsArrayNew(NULL, NULL); + + if (address) + add_array(Addresses, address); + + if ((debug = getenv("CUPS_DEBUG_LEVEL")) != NULL) + DebugLevel = atoi(debug); + + if ((runtime = getenv("CUPS_MAX_RUN_TIME")) != NULL) + MaxRunTime = atoi(runtime); + + /* + * Find the snmp.conf file... + */ + + if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL) + cups_serverroot = CUPS_SERVERROOT; + + snprintf(filename, sizeof(filename), "%s/snmp.conf", cups_serverroot); + + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + /* + * Read the snmp.conf file... + */ + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!value) + fprintf(stderr, "ERROR: Missing value on line %d of %s!\n", linenum, + filename); + else if (!strcasecmp(line, "Address")) + { + if (!address) + add_array(Addresses, value); + } + else if (!strcasecmp(line, "Community")) + add_array(Communities, value); + else if (!strcasecmp(line, "DebugLevel")) + DebugLevel = atoi(value); + else if (!strcasecmp(line, "DeviceURI")) + { + if (*value != '\"') + fprintf(stderr, + "ERROR: Missing double quote for regular expression on " + "line %d of %s!\n", linenum, filename); + else + add_device_uri(value); + } + else if (!strcasecmp(line, "HostNameLookups")) + HostNameLookups = !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || + !strcasecmp(value, "true") || + !strcasecmp(value, "double"); + else if (!strcasecmp(line, "MaxRunTime")) + MaxRunTime = atoi(value); + else + fprintf(stderr, "ERROR: Unknown directive %s on line %d of %s!\n", + line, linenum, filename); + } + + cupsFileClose(fp); + } + + /* + * Use defaults if parameters are undefined... + */ + + if (cupsArrayCount(Addresses) == 0) + { + /* + * If we have no addresses, exit immediately... + */ + + fprintf(stderr, + "DEBUG: No address specified and no Address line in %s...\n", + filename); + exit(0); + } + + if (cupsArrayCount(Communities) == 0) + { + fputs("INFO: Using default SNMP Community public\n", stderr); + add_array(Communities, "public"); + } +} + + +/* + * 'read_snmp_response()' - Read and parse a SNMP response... + */ + +static void +read_snmp_response(int fd) /* I - SNMP socket file descriptor */ +{ + char addrname[256]; /* Source address name */ + cups_snmp_t packet; /* Decoded packet */ + snmp_cache_t key, /* Search key */ + *device; /* Matching device */ + + + /* + * Read the response data... + */ + + if (!_cupsSNMPRead(fd, &packet, -1.0)) + { + fprintf(stderr, "ERROR: Unable to read data from socket: %s\n", + strerror(errno)); + return; + } + + if (HostNameLookups) + httpAddrLookup(&(packet.address), addrname, sizeof(addrname)); + else + httpAddrString(&(packet.address), addrname, sizeof(addrname)); + + debug_printf("DEBUG: %.3f Received data from %s...\n", run_time(), addrname); + + /* + * Look for the response status code in the SNMP message header... + */ + + if (packet.error) + { + fprintf(stderr, "ERROR: Bad SNMP packet from %s: %s\n", addrname, + packet.error); + + return; + } + + debug_printf("DEBUG: community=\"%s\"\n", packet.community); + debug_printf("DEBUG: request-id=%d\n", packet.request_id); + debug_printf("DEBUG: error-status=%d\n", packet.error_status); + + if (packet.error_status) + return; + + /* + * Find a matching device in the cache... + */ + + key.addrname = addrname; + device = (snmp_cache_t *)cupsArrayFind(Devices, &key); + + /* + * Process the message... + */ + + switch (packet.request_id) + { + case DEVICE_TYPE : + /* + * Got the device type response... + */ + + if (device) + { + debug_printf("DEBUG: Discarding duplicate device type for \"%s\"...\n", + addrname); + return; + } + + /* + * Add the device and request the device data... + */ + + add_cache(&(packet.address), addrname, NULL, NULL, NULL); + + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_DESCRIPTION, DescriptionOID); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_ID, DeviceIdOID); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_URI, UriOID); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_LOCATION, LocationOID); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_PRODUCT, LexmarkProductOID); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_PRODUCT, LexmarkProductOID2); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_ID, LexmarkDeviceIdOID); + _cupsSNMPWrite(fd, &(packet.address), CUPS_SNMP_VERSION_1, + packet.community, CUPS_ASN1_GET_REQUEST, + DEVICE_PRODUCT, XeroxProductOID); + break; + + case DEVICE_DESCRIPTION : + if (device && packet.object_type == CUPS_ASN1_OCTET_STRING) + { + /* + * Update an existing cache entry... + */ + + char make_model[256]; /* Make and model */ + + + if (strchr((char *)packet.object_value.string.bytes, ':') && + strchr((char *)packet.object_value.string.bytes, ';')) + { + /* + * Description is the IEEE-1284 device ID... + */ + + if (!device->id) + device->id = strdup((char *)packet.object_value.string.bytes); + + backendGetMakeModel((char *)packet.object_value.string.bytes, + make_model, sizeof(make_model)); + + if (device->info) + free(device->info); + + device->info = strdup(make_model); + } + else + { + /* + * Description is plain text... + */ + + fix_make_model(make_model, (char *)packet.object_value.string.bytes, + sizeof(make_model)); + + if (device->info) + free(device->info); + + device->info = strdup((char *)packet.object_value.string.bytes); + } + + if (!device->make_and_model) + device->make_and_model = strdup(make_model); + } + break; + + case DEVICE_ID : + if (device && packet.object_type == CUPS_ASN1_OCTET_STRING && + (!device->id || + strlen(device->id) < packet.object_value.string.num_bytes)) + { + /* + * Update an existing cache entry... + */ + + char make_model[256]; /* Make and model */ + + + if (device->id) + free(device->id); + + device->id = strdup((char *)packet.object_value.string.bytes); + + /* + * Convert the ID to a make and model string... + */ + + backendGetMakeModel((char *)packet.object_value.string.bytes, + make_model, sizeof(make_model)); + if (device->make_and_model) + free(device->make_and_model); + + device->make_and_model = strdup(make_model); + } + break; + + case DEVICE_LOCATION : + if (device && packet.object_type == CUPS_ASN1_OCTET_STRING && + !device->location) + device->location = strdup((char *)packet.object_value.string.bytes); + break; + + case DEVICE_PRODUCT : + if (device && packet.object_type == CUPS_ASN1_OCTET_STRING && + !device->id) + { + /* + * Update an existing cache entry... + */ + + if (!device->info) + device->info = strdup((char *)packet.object_value.string.bytes); + + if (device->make_and_model) + free(device->make_and_model); + + device->make_and_model = strdup((char *)packet.object_value.string.bytes); + } + break; + + case DEVICE_URI : + if (device && packet.object_type == CUPS_ASN1_OCTET_STRING && + !device->uri && packet.object_value.string.num_bytes > 0) + { + /* + * Update an existing cache entry... + */ + + if (!strncmp((char *)packet.object_value.string.bytes, "lpr:", 4)) + { + /* + * We want "lpd://..." for the URI... + */ + + packet.object_value.string.bytes[2] = 'd'; + } + + device->uri = strdup((char *)packet.object_value.string.bytes); + } + break; + } +} + + +/* + * 'run_time()' - Return the total running time... + */ + +static double /* O - Number of seconds */ +run_time(void) +{ + struct timeval curtime; /* Current time */ + + + gettimeofday(&curtime, NULL); + + return (curtime.tv_sec - StartTime.tv_sec + + 0.000001 * (curtime.tv_usec - StartTime.tv_usec)); +} + + +/* + * 'scan_devices()' - Scan for devices using SNMP. + */ + +static void +scan_devices(int fd) /* I - SNMP socket */ +{ + char *address, /* Current address */ + *community; /* Current community */ + fd_set input; /* Input set for select() */ + struct timeval timeout; /* Timeout for select() */ + time_t endtime; /* End time for scan */ + http_addrlist_t *addrs, /* List of addresses */ + *addr; /* Current address */ + snmp_cache_t *device; /* Current device */ + + + gettimeofday(&StartTime, NULL); + + /* + * First send all of the broadcast queries... + */ + + for (address = (char *)cupsArrayFirst(Addresses); + address; + address = (char *)cupsArrayNext(Addresses)) + { + if (!strcmp(address, "@LOCAL")) + addrs = get_interface_addresses(NULL); + else if (!strncmp(address, "@IF(", 4)) + { + char ifname[255]; /* Interface name */ + + + strlcpy(ifname, address + 4, sizeof(ifname)); + if (ifname[0]) + ifname[strlen(ifname) - 1] = '\0'; + + addrs = get_interface_addresses(ifname); + } + else + addrs = httpAddrGetList(address, AF_INET, NULL); + + if (!addrs) + { + fprintf(stderr, "ERROR: Unable to scan \"%s\"!\n", address); + continue; + } + + for (community = (char *)cupsArrayFirst(Communities); + community; + community = (char *)cupsArrayNext(Communities)) + { + debug_printf("DEBUG: Scanning for devices in \"%s\" via \"%s\"...\n", + community, address); + + for (addr = addrs; addr; addr = addr->next) + _cupsSNMPWrite(fd, &(addr->addr), CUPS_SNMP_VERSION_1, community, + CUPS_ASN1_GET_REQUEST, DEVICE_TYPE, DeviceTypeOID); + } + + httpAddrFreeList(addrs); + } + + /* + * Then read any responses that come in over the next 3 seconds... + */ + + endtime = time(NULL) + MaxRunTime; + + FD_ZERO(&input); + + while (time(NULL) < endtime) + { + timeout.tv_sec = 2; + timeout.tv_usec = 0; + + FD_SET(fd, &input); + if (select(fd + 1, &input, NULL, NULL, &timeout) < 0) + { + fprintf(stderr, "ERROR: %.3f select() for %d failed: %s\n", run_time(), + fd, strerror(errno)); + break; + } + + if (FD_ISSET(fd, &input)) + read_snmp_response(fd); + else + { + /* + * List devices with complete information... + */ + + int sent_something = 0; + + for (device = (snmp_cache_t *)cupsArrayFirst(Devices); + device; + device = (snmp_cache_t *)cupsArrayNext(Devices)) + if (!device->sent && device->info && device->make_and_model) + { + if (device->uri) + list_device(device); + else + probe_device(device); + + device->sent = sent_something = 1; + } + + if (!sent_something) + break; + } + } + + debug_printf("DEBUG: %.3f Scan complete!\n", run_time()); +} + + +/* + * 'try_connect()' - Try connecting on a port... + */ + +static int /* O - 0 on success or -1 on error */ +try_connect(http_addr_t *addr, /* I - Socket address */ + const char *addrname, /* I - Hostname or IP address */ + int port) /* I - Port number */ +{ + int fd; /* Socket */ + int status; /* Connection status */ + + + debug_printf("DEBUG: %.3f Trying %s://%s:%d...\n", run_time(), + port == 515 ? "lpd" : "socket", addrname, port); + + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + fprintf(stderr, "ERROR: Unable to create socket: %s\n", + strerror(errno)); + return (-1); + } + + addr->ipv4.sin_port = htons(port); + + alarm(1); + + status = connect(fd, (void *)addr, httpAddrLength(addr)); + + close(fd); + alarm(0); + + return (status); +} + + +/* + * 'update_cache()' - Update a cached device... + */ + +static void +update_cache(snmp_cache_t *device, /* I - Device */ + const char *uri, /* I - Device URI */ + const char *id, /* I - Device ID */ + const char *make_model) /* I - Device make and model */ +{ + if (device->uri) + free(device->uri); + + device->uri = strdup(uri); + + if (id) + { + if (device->id) + free(device->id); + + device->id = strdup(id); + } + + if (make_model) + { + if (device->make_and_model) + free(device->make_and_model); + + device->make_and_model = strdup(make_model); + } + + list_device(device); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/snmp.txt b/backend/snmp.txt new file mode 100644 index 0000000000..77a38c498d --- /dev/null +++ b/backend/snmp.txt @@ -0,0 +1,172 @@ +snmp.txt - 2006-04-19 +--------------------- + +This file lists the "interesting" bits from the command: + + snmpwalk -v 1 -c public HOST .1 + +for many network print servers and internal cards. It is mainly here +for SNMP documentation and development purposes. + + +AXIS 5600 + +SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM J.sp.00,JETDIRECT EX,JD28,EEPROM 6.16.5 +SNMPv2-MIB::sysName.0 = STRING: +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceType.3 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: Hewlett-Packard hp LaserJet 3380 +HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: Axis AXIS 5600 +HOST-RESOURCES-MIB::hrDeviceDescr.3 = STRING: Axis AXIS 5600 +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero +HOST-RESOURCES-MIB::hrDeviceID.2 = OID: SNMPv2-SMI::zeroDotZero +HOST-RESOURCES-MIB::hrDeviceID.3 = OID: SNMPv2-SMI::zeroDotZero +SNMPv2-SMI::enterprises.11.2.4.3.10.8.0 = STRING: "AXIS433AE8" +SNMPv2-SMI::enterprises.368.2.3.2.601.0 = INTEGER: 9100 +SNMPv2-SMI::enterprises.368.2.3.2.602.0 = INTEGER: 9101 +SNMPv2-SMI::enterprises.368.2.3.2.603.0 = INTEGER: 9102 +SNMPv2-SMI::enterprises.368.2.3.10.901.0 = STRING: "AXIS433AE8" + + +AXIS OfficeBasic + +SNMPv2-MIB::sysDescr.0 = STRING: AXIS OfficeBasic Parallel Network Print Server V6.43 Sep 4 2003 +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: EPSON Stylus Photo 870 +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero + + +DLink DP-301P+ + +SNMPv2-MIB::sysDescr.0 = STRING: D-Link DP-301P+ Print Server + + +Genicom ML280 + +SNMPv2-MIB::sysDescr.0 = STRING: GENICOM microLaser 280 +SNMPv2-MIB::sysName.0 = STRING: PRQ_004F75 +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: MANUFACTURER:GENICOM;MODEL:microLaser 280; +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.3369.1.1.2.4 + + +EPSON Type-B Network Card + +SNMPv2-MIB::sysDescr.0 = STRING: EPSON Type-B 10Base-T/100Base-TX Print Server +SNMPv2-MIB::sysName.0 = STRING: StylusPro7600-BB87A8 +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: EPSON Stylus Pro 7600 +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.1248.1.2.1.22.69.109.117.108.97.116.101.83.116.121.108.117.115.32.80.114.111.32.55.54.48.48 +SNMPv2-SMI::enterprises.11.2.3.9.1.1.7.0 = STRING: "MFG:EPSON;CMD:ESCPL2,BDC;MDL:Stylus Pro 7600;CLS:PRINTER;DES:EPSON Stylus Pro 7600;" +SNMPv2-SMI::enterprises.1248.1.2.2.1.1.1.1.1 = STRING: "MFG:EPSON;CMD:ESCPL2,BDC;MDL:Stylus Pro 7600;CLS:PRINTER;DES:EPSON Stylus Pro 7600;" + + +EPSON Wireless 802.11b Print Server + +SNMPv2-MIB::sysDescr.0 = STRING: EPSON Wireless LAN Print Interface compatible with an HP JETDIRECT EX +SNMPv2-MIB::sysName.0 = STRING: EAI_0F550B +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero + + +HP JetDirect EX3plus + +SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM D.04.03,JETDIRECT EX,JD26,EEPROM D.05.22 +SNMPv2-MIB::sysName.0 = STRING: NPID1EC0F + + +HP LJ4000 + +SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM G.05.34,JETDIRECT,JD30,EEPROM G.08.32 +SNMPv2-MIB::sysName.0 = STRING: +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: HP LaserJet 4000 Series +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.11.2.3.9.1.2.5 + + +HP CLJ4550 + +SNMPv2-MIB::sysDescr.0 = STRING: HP ETHERNET MULTI-ENVIRONMENT,ROM L.20.07,JETDIRECT,JD84,EEPROM L.21.22,CIDATE 07/06/2001 +SNMPv2-MIB::sysName.0 = STRING: NPI02FDE7 +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: HP Color LaserJet 4550 +HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: Hewlett-Packard Dynamic RAM Disk +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.11.2.3.9.1.2.14 + + +Lexmark C522 + +SNMPv2-MIB::sysDescr.0 = STRING: Lexmark C522 version NS.NP.N212 kernel 2.6.6 All-N-1 +SNMPv2-MIB::sysName.0 = STRING: ET0004000D0CCA +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDeviceNonVolatileMemory +HOST-RESOURCES-MIB::hrDeviceType.3 = OID: HOST-RESOURCES-TYPES::hrDeviceProcessor +HOST-RESOURCES-MIB::hrDeviceType.4 = OID: HOST-RESOURCES-TYPES::hrDeviceSerialPort +HOST-RESOURCES-MIB::hrDeviceType.5 = OID: HOST-RESOURCES-TYPES::hrDeviceNetwork +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: Lexmark C522 9421TTV LS.FA.P129 +HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: Nonvolatile RAM +HOST-RESOURCES-MIB::hrDeviceDescr.3 = STRING: IBM 750 Rev CXr +HOST-RESOURCES-MIB::hrDeviceDescr.4 = STRING: USB Interface +HOST-RESOURCES-MIB::hrDeviceDescr.5 = STRING: Network Interface +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::zeroDotZero +HOST-RESOURCES-MIB::hrDeviceID.2 = OID: SNMPv2-SMI::zeroDotZero +HOST-RESOURCES-MIB::hrDeviceID.3 = OID: SNMPv2-SMI::zeroDotZero +HOST-RESOURCES-MIB::hrDeviceID.4 = OID: SNMPv2-SMI::zeroDotZero +HOST-RESOURCES-MIB::hrDeviceID.5 = OID: SNMPv2-SMI::enterprises.641.1 +SNMPv2-SMI::enterprises.641.2.1.2.1.2.1 = STRING: "Lexmark C522" +SNMPv2-SMI::enterprises.641.2.1.2.1.3.1 = STRING: "MANUFACTURER:Lexmark International;COMMAND SET:;MODEL:Lexmark C522" + + +Linksys EPSX3 + +SNMPv2-MIB::sysDescr.0 = STRING: ETHERNET MULTI-ENVIRONMENT.ROM, JETDIRECT EX, EEPROM 6016 + + +NetGear PS113 + +SNMPv2-MIB::sysDescr.0 = STRING: A SNMP proxy agent. + + +Okidata C7200 + +SNMPv2-MIB::sysDescr.0 = STRING: OkiLAN 6200e +SNMPv2-MIB::sysName.0 = STRING: OKI7009715 +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDeviceNonVolat +ileMemory +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: C7200 +HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: FLASH0 +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.2001.1.1.1.1 +HOST-RESOURCES-MIB::hrDeviceID.2 = OID: SNMPv2-SMI::zeroDotZero +SNMPv2-SMI::mib-2.43.14.1.1.3.1.1 = STRING: "IEEE 1284" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.2 = STRING: "EtherTalk Phase 2" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.3 = STRING: "LPD" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.4 = STRING: "Netware Rprinter" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.5 = STRING: "Netware Bindery or NDS Pserver" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.6 = STRING: "Raw TCP Port 9100" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.7 = STRING: "FTP" +SNMPv2-SMI::mib-2.43.14.1.1.3.1.8 = STRING: "DLC/LLC" +SNMPv2-SMI::enterprises.2001.1.1.1.1.1.3530.0 = STRING: "C7200" + + +Xerox N2025 + +SNMPv2-MIB::sysDescr.0 = STRING: Xerox DocuPrint N2025 Network Laser Printer - 2.12-02 +SNMPv2-MIB::sysName.0 = STRING: +HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter +HOST-RESOURCES-MIB::hrDeviceType.2 = OID: HOST-RESOURCES-TYPES::hrDeviceParallelPort +HOST-RESOURCES-MIB::hrDeviceType.3 = OID: HOST-RESOURCES-TYPES::hrDeviceNetwork +HOST-RESOURCES-MIB::hrDeviceType.6 = OID: HOST-RESOURCES-TYPES::hrDeviceProcessor +HOST-RESOURCES-MIB::hrDeviceType.7 = OID: HOST-RESOURCES-TYPES::hrDeviceOther +HOST-RESOURCES-MIB::hrDeviceType.9 = OID: HOST-RESOURCES-TYPES::hrDeviceVolatileMemory +HOST-RESOURCES-MIB::hrDeviceType.10 = OID: HOST-RESOURCES-TYPES::hrDeviceNonVolatileMemory +HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: Xerox DocuPrint N2025 Network Laser Printer - 2.12-02 +HOST-RESOURCES-MIB::hrDeviceDescr.2 = STRING: IEEE 1284 port +HOST-RESOURCES-MIB::hrDeviceDescr.3 = STRING: Ethernet port +HOST-RESOURCES-MIB::hrDeviceDescr.6 = STRING: Motorola Power PC +HOST-RESOURCES-MIB::hrDeviceDescr.7 = STRING: USB Port +HOST-RESOURCES-MIB::hrDeviceDescr.9 = STRING: RAM Memory +HOST-RESOURCES-MIB::hrDeviceDescr.10 = STRING: ROM Memory +HOST-RESOURCES-MIB::hrDeviceID.1 = OID: SNMPv2-SMI::enterprises.253.8.62.1.3.2.17.1 + diff --git a/backend/socket.c b/backend/socket.c new file mode 100644 index 0000000000..4de410c830 --- /dev/null +++ b/backend/socket.c @@ -0,0 +1,513 @@ +/* + * "$Id$" + * + * AppSocket backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "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. + * wait_bc() - Wait for back-channel data... + */ + +/* + * Include necessary headers. + */ + +#include +#include "backend-private.h" +#include +#include +#include + +#ifdef WIN32 +# include +#else +# include +# include +# include +# include +# include +# include +#endif /* WIN32 */ + + +/* + * Local functions... + */ + +static int wait_bc(int device_fd, int secs); + + +/* + * '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 */ +{ + const char *device_uri; /* Device URI */ + char scheme[255], /* Scheme in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024], /* Resource info (not used) */ + *options, /* Pointer to options */ + *name, /* Name of option */ + *value, /* Value of option */ + sep; /* Option separator */ + int print_fd; /* Print file */ + int copies; /* Number of copies to print */ + time_t start_time; /* Time of first connect */ +#ifdef __APPLE__ + time_t current_time, /* Current time */ + wait_time; /* Time to wait before shutting down socket */ +#endif /* __APPLE__ */ + int recoverable; /* Recoverable error shown? */ + int contimeout; /* Connection timeout */ + int waiteof; /* Wait for end-of-file? */ + int port; /* Port number */ + char portname[255]; /* Port name */ + int delay; /* Delay for retries... */ + int device_fd; /* AppSocket */ + int error; /* Error code (if any) */ + http_addrlist_t *addrlist, /* Address list */ + *addr; /* Connected address */ + char addrname[256]; /* Address name */ + int snmp_fd, /* SNMP socket */ + start_count, /* Page count via SNMP at start */ + page_count, /* Page count via SNMP */ + have_supplies; /* Printer supports supply levels? */ + ssize_t tbytes; /* Total number of bytes written */ +#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); + + /* + * Ignore SIGPIPE signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + printf("network socket \"Unknown\" \"%s\"\n", + _cupsLangString(cupsLangDefault(), _("AppSocket/HP JetDirect"))); + return (CUPS_BACKEND_OK); + } + else if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + print_fd = 0; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((print_fd = open(argv[6], O_RDONLY)) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open print file \"%s\": %s\n"), + argv[6], strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the hostname and port number from the URI... + */ + + if ((device_uri = cupsBackendDeviceURI(argv)) == NULL) + return (CUPS_BACKEND_FAILED); + + httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + if (port == 0) + port = 9100; /* Default to HP JetDirect/Tektronix PhaserShare */ + + /* + * Get options, if any... + */ + + waiteof = 1; + contimeout = 7 * 24 * 60 * 60; + + 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... + */ + + name = options; + + while (*options && *options != '=' && *options != '+' && *options != '&') + options ++; + + if ((sep = *options) != '\0') + *options++ = '\0'; + + if (sep == '=') + { + /* + * Get the value... + */ + + value = options; + + while (*options && *options != '+' && *options != '&') + options ++; + + if (*options) + *options++ = '\0'; + } + else + value = (char *)""; + + /* + * Process the option... + */ + + if (!strcasecmp(name, "waiteof")) + { + /* + * Set the wait-for-eof value... + */ + + waiteof = !value[0] || !strcasecmp(value, "on") || + !strcasecmp(value, "yes") || !strcasecmp(value, "true"); + } + else if (!strcasecmp(name, "contimeout")) + { + /* + * Set the connection timeout... + */ + + if (atoi(value) > 0) + contimeout = atoi(value); + } + } + } + + /* + * Then try to connect to the remote host... + */ + + recoverable = 0; + start_time = time(NULL); + + sprintf(portname, "%d", port); + + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); + + if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to locate printer \'%s\'!\n"), + hostname); + return (CUPS_BACKEND_STOP); + } + + fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port); + _cupsLangPuts(stderr, _("INFO: Connecting to printer...\n")); + + for (delay = 5;;) + { + if ((addr = httpAddrConnect(addrlist, &device_fd)) == NULL) + { + error = errno; + device_fd = -1; + + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (error == ECONNREFUSED || error == EHOSTDOWN || + error == EHOSTUNREACH) + { + if (contimeout && (time(NULL) - start_time) > contimeout) + { + _cupsLangPuts(stderr, _("ERROR: Printer not responding!\n")); + return (CUPS_BACKEND_FAILED); + } + + recoverable = 1; + + _cupsLangPrintf(stderr, + _("WARNING: recoverable: Network host \'%s\' is busy; " + "will retry in %d seconds...\n"), + hostname, delay); + + sleep(delay); + + if (delay < 30) + delay += 5; + } + else + { + recoverable = 1; + + _cupsLangPrintf(stderr, "DEBUG: Connection error: %s\n", + strerror(errno)); + _cupsLangPuts(stderr, + _("ERROR: recoverable: Unable to connect to printer; " + "will retry in 30 seconds...\n")); + sleep(30); + } + } + else + break; + } + + if (recoverable) + { + /* + * If we've shown a recoverable error make sure the printer proxies have a + * chance to see the recovered message. Not pretty but necessary for now... + */ + + fputs("INFO: recovered: \n", stderr); + sleep(5); + } + + fputs("STATE: -connecting-to-device\n", stderr); + _cupsLangPuts(stderr, _("INFO: Connected to printer...\n")); + +#ifdef AF_INET6 + if (addr->addr.addr.sa_family == AF_INET6) + fprintf(stderr, "DEBUG: Connected to [%s]:%d (IPv6)...\n", + httpAddrString(&addr->addr, addrname, sizeof(addrname)), + ntohs(addr->addr.ipv6.sin6_port)); + else +#endif /* AF_INET6 */ + if (addr->addr.addr.sa_family == AF_INET) + fprintf(stderr, "DEBUG: Connected to %s:%d (IPv4)...\n", + httpAddrString(&addr->addr, addrname, sizeof(addrname)), + ntohs(addr->addr.ipv4.sin_port)); + + /* + * See if the printer supports SNMP... + */ + + if ((snmp_fd = _cupsSNMPOpen(addr->addr.addr.sa_family)) >= 0) + { + have_supplies = !backendSNMPSupplies(snmp_fd, &(addr->addr), &start_count, + NULL); + } + else + have_supplies = start_count = 0; + + /* + * Print everything... + */ + + tbytes = 0; + + while (copies > 0 && tbytes >= 0) + { + copies --; + + if (print_fd != 0) + { + fputs("PAGE: 1 1\n", stderr); + lseek(print_fd, 0, SEEK_SET); + } + + tbytes = backendRunLoop(print_fd, device_fd, snmp_fd, &(addr->addr), 1, 0, + backendNetworkSideCB); + + if (print_fd != 0 && tbytes >= 0) + _cupsLangPrintf(stderr, +#ifdef HAVE_LONG_LONG + _("INFO: Sent print file, %lld bytes...\n"), +#else + _("INFO: Sent print file, %ld bytes...\n"), +#endif /* HAVE_LONG_LONG */ + CUPS_LLCAST tbytes); + } + +#ifdef __APPLE__ + /* + * Wait up to 5 seconds to get any pending back-channel data... + */ + + wait_time = time(NULL) + 5; + while (wait_time >= time(¤t_time)) + if (wait_bc(device_fd, wait_time - current_time) <= 0) + break; +#endif /* __APPLE__ */ + + if (waiteof) + { + /* + * Shutdown the socket and wait for the other end to finish... + */ + + _cupsLangPuts(stderr, + _("INFO: Print file sent, waiting for printer to finish...\n")); + + shutdown(device_fd, 1); + + while (wait_bc(device_fd, 90) > 0); + } + + /* + * Collect the final page count as needed... + */ + + if (have_supplies && + !backendSNMPSupplies(snmp_fd, &(addr->addr), &page_count, NULL) && + page_count > start_count) + fprintf(stderr, "PAGE: total %d\n", page_count - start_count); + + /* + * Close the socket connection... + */ + + close(device_fd); + + httpAddrFreeList(addrlist); + + /* + * Close the input file and return... + */ + + if (print_fd != 0) + close(print_fd); + + if (tbytes >= 0) + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + + return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); +} + + +/* + * 'wait_bc()' - Wait for back-channel data... + */ + +static int /* O - # bytes read or -1 on error */ +wait_bc(int device_fd, /* I - Socket */ + int secs) /* I - Seconds to wait */ +{ + struct timeval timeout; /* Timeout for select() */ + fd_set input; /* Input set for select() */ + ssize_t bytes; /* Number of back-channel bytes read */ + char buffer[1024]; /* Back-channel buffer */ + + + /* + * Wait up to "secs" seconds for backchannel data... + */ + + timeout.tv_sec = secs; + timeout.tv_usec = 0; + + FD_ZERO(&input); + FD_SET(device_fd, &input); + + if (select(device_fd + 1, &input, NULL, NULL, &timeout) > 0) + { + /* + * Grab the data coming back and spit it out to stderr... + */ + + if ((bytes = read(device_fd, buffer, sizeof(buffer))) > 0) + { + fprintf(stderr, "DEBUG: Received %d bytes of back-channel data!\n", + (int)bytes); + cupsBackChannelWrite(buffer, bytes, 1.0); + } + + return (bytes); + } + else + return (-1); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/test1284.c b/backend/test1284.c new file mode 100644 index 0000000000..59a2d2aa7a --- /dev/null +++ b/backend/test1284.c @@ -0,0 +1,87 @@ +/* + * "$Id$" + * + * IEEE-1284 support functions test program for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Test the device-ID functions. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#ifdef WIN32 +# include +#else +# include +# include +#endif /* WIN32 */ + +#include "ieee1284.c" + + +/* + * 'main()' - Test the device-ID functions. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, /* Looping var */ + fd; /* File descriptor */ + char device_id[1024], /* 1284 device ID string */ + make_model[1024], /* make-and-model string */ + uri[1024]; /* URI string */ + + + if (argc < 2) + { + puts("Usage: test1284 device-file [... device-file-N]"); + exit(1); + } + + for (i = 1; i < argc; i ++) + { + if ((fd = open(argv[i], O_RDWR)) < 0) + { + perror(argv[i]); + return (errno); + } + + printf("%s:\n", argv[i]); + + backendGetDeviceID(fd, device_id, sizeof(device_id), make_model, + sizeof(make_model), "test", uri, sizeof(uri)); + + printf(" device_id=\"%s\"\n", device_id); + printf(" make_model=\"%s\"\n", make_model); + printf(" uri=\"%s\"\n", uri); + + close(fd); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/testbackend.c b/backend/testbackend.c new file mode 100644 index 0000000000..3213450f74 --- /dev/null +++ b/backend/testbackend.c @@ -0,0 +1,654 @@ +/* + * "$Id$" + * + * Backend test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Run the named backend. + * sigterm_handler() - Flag when we get SIGTERM. + * usage() - Show usage information. + * walk_cb() - Show results of cupsSideChannelSNMPWalk... + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local globals... + */ + +static int job_canceled = 0; + + +/* + * Local functions... + */ + +static void sigterm_handler(int sig); +static void usage(void); +static void walk_cb(const char *oid, const char *data, int datalen, + void *context); + + +/* + * 'main()' - Run the named backend. + * + * Usage: + * + * betest [-s] [-t] device-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int first_arg, /* First argument for backend */ + do_cancel = 0, /* Simulate a cancel-job via SIGTERM */ + do_ps = 0, /* Do PostScript query+test? */ + do_pcl = 0, /* Do PCL query+test? */ + do_side_tests = 0, /* Test side-channel ops? */ + do_trickle = 0, /* Trickle data to backend */ + do_walk = 0, /* Do OID lookup (0) or walking (1) */ + show_log = 0; /* Show log messages from backends? */ + const char *oid = ".1.3.6.1.2.1.43.10.2.1.4.1.1"; + /* OID to lookup or walk */ + char scheme[255], /* Scheme in URI == backend */ + backend[1024]; /* Backend path */ + const char *serverbin; /* CUPS_SERVERBIN environment variable */ + int fd, /* Temporary file descriptor */ + back_fds[2], /* Back-channel pipe */ + side_fds[2], /* Side-channel socket */ + data_fds[2], /* Data pipe */ + back_pid = -1, /* Backend process ID */ + data_pid = -1, /* Trickle process ID */ + pid, /* Process ID */ + status; /* Exit status */ + + + /* + * See if we have side-channel tests to do... + */ + + for (first_arg = 1; + argv[first_arg] && argv[first_arg][0] == '-'; + first_arg ++) + if (!strcmp(argv[first_arg], "-d")) + show_log = 1; + else if (!strcmp(argv[first_arg], "-cancel")) + do_cancel = 1; + else if (!strcmp(argv[first_arg], "-pcl")) + do_pcl = 1; + else if (!strcmp(argv[first_arg], "-ps")) + do_ps = 1; + else if (!strcmp(argv[first_arg], "-s")) + do_side_tests = 1; + else if (!strcmp(argv[first_arg], "-t")) + do_trickle = 1; + else if (!strcmp(argv[first_arg], "-get") && (first_arg + 1) < argc) + { + first_arg ++; + + do_side_tests = 1; + oid = argv[first_arg]; + } + else if (!strcmp(argv[first_arg], "-walk") && (first_arg + 1) < argc) + { + first_arg ++; + + do_side_tests = 1; + do_walk = 1; + oid = argv[first_arg]; + } + else + usage(); + + argc -= first_arg; + if (argc < 6 || argc > 7 || (argc == 7 && do_trickle)) + usage(); + + /* + * Extract the scheme from the device-uri - that's the program we want to + * execute. + */ + + if (sscanf(argv[first_arg], "%254[^:]", scheme) != 1) + { + fputs("testbackend: Bad device-uri - no colon!\n", stderr); + return (1); + } + + if (!access(scheme, X_OK)) + strlcpy(backend, scheme, sizeof(backend)); + else + { + if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL) + serverbin = CUPS_SERVERBIN; + + snprintf(backend, sizeof(backend), "%s/backend/%s", serverbin, scheme); + if (access(backend, X_OK)) + { + fprintf(stderr, "testbackend: Unknown device scheme \"%s\"!\n", scheme); + return (1); + } + } + + /* + * Create the back-channel pipe and side-channel socket... + */ + + open("/dev/null", O_WRONLY); /* Make sure fd 3 and 4 are used */ + open("/dev/null", O_WRONLY); + + pipe(back_fds); + fcntl(back_fds[0], F_SETFL, fcntl(back_fds[0], F_GETFL) | O_NONBLOCK); + fcntl(back_fds[1], F_SETFL, fcntl(back_fds[1], F_GETFL) | O_NONBLOCK); + + socketpair(AF_LOCAL, SOCK_STREAM, 0, side_fds); + fcntl(side_fds[0], F_SETFL, fcntl(side_fds[0], F_GETFL) | O_NONBLOCK); + fcntl(side_fds[1], F_SETFL, fcntl(side_fds[1], F_GETFL) | O_NONBLOCK); + + /* + * Execute the trickle process as needed... + */ + + if (do_trickle || do_pcl || do_ps || do_cancel) + { + pipe(data_fds); + + signal(SIGTERM, sigterm_handler); + + if ((data_pid = fork()) == 0) + { + /* + * Trickle/query child comes here. Rearrange file descriptors so that + * FD 1, 3, and 4 point to the backend... + */ + + if ((fd = open("/dev/null", O_RDONLY)) != 0) + { + dup2(fd, 0); + close(fd); + } + + if (data_fds[1] != 1) + { + dup2(data_fds[1], 1); + close(data_fds[1]); + } + close(data_fds[0]); + + if (back_fds[0] != 3) + { + dup2(back_fds[0], 3); + close(back_fds[0]); + } + close(back_fds[1]); + + if (side_fds[0] != 4) + { + dup2(side_fds[0], 4); + close(side_fds[0]); + } + close(side_fds[1]); + + if (do_trickle) + { + /* + * Write 10 spaces, 1 per second... + */ + + int i; /* Looping var */ + + for (i = 0; i < 10; i ++) + { + write(1, " ", 1); + sleep(1); + } + } + else if (do_cancel) + { + /* + * Write PS or PCL lines until we see SIGTERM... + */ + + int line = 0, page = 0; /* Current line and page */ + ssize_t bytes; /* Number of bytes of response data */ + char buffer[1024]; /* Output buffer */ + + + if (do_pcl) + write(1, "\033E", 2); + else + write(1, "%!\n/Courier findfont 12 scalefont setfont 0 setgray\n", 52); + + while (!job_canceled) + { + if (line == 0) + { + page ++; + + if (do_pcl) + snprintf(buffer, sizeof(buffer), "PCL Page %d\r\n\r\n", page); + else + snprintf(buffer, sizeof(buffer), + "18 732 moveto (PS Page %d) show\n", page); + + write(1, buffer, strlen(buffer)); + } + + line ++; + + if (do_pcl) + snprintf(buffer, sizeof(buffer), "Line %d\r\n", line); + else + snprintf(buffer, sizeof(buffer), "18 %d moveto (Line %d) show\n", + 720 - line * 12, line); + + write(1, buffer, strlen(buffer)); + + if (line >= 55) + { + /* + * Eject after 55 lines... + */ + + line = 0; + if (do_pcl) + write(1, "\014", 1); + else + write(1, "showpage\n", 9); + } + + /* + * Check for back-channel data... + */ + + if ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0)) > 0) + write(2, buffer, bytes); + + /* + * Throttle output to ~100hz... + */ + + usleep(10000); + } + + /* + * Eject current page with info... + */ + + if (do_pcl) + snprintf(buffer, sizeof(buffer), + "Canceled on line %d of page %d\r\n\014\033E", line, page); + else + snprintf(buffer, sizeof(buffer), + "\n18 %d moveto (Canceled on line %d of page %d)\nshowpage\n", + 720 - line * 12, line, page); + + write(1, buffer, strlen(buffer)); + + /* + * See if we get any back-channel data... + */ + + while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), 5.0)) > 0) + write(2, buffer, bytes); + + exit(0); + } + else + { + /* + * Do PS or PCL query + test pages. + */ + + char buffer[1024]; /* Buffer for response data */ + ssize_t bytes; /* Number of bytes of response data */ + double timeout; /* Timeout */ + const char *data; /* Data to send */ + static const char *pcl_data = /* PCL data */ + "\033%-12345X@PJL\r\n" + "@PJL JOB NAME = \"Hello, World!\"\r\n" + "@PJL INFO USTATUS\r\n" + "@PJL ENTER LANGUAGE = PCL\r\n" + "\033E" + "Hello, World!\n" + "\014" + "\033%-12345X@PJL\r\n" + "@PJL EOJ NAME=\"Hello, World!\"\r\n" + "\033%-12345X"; + static const char *ps_data = /* PostScript data */ + "%!\n" + "save\n" + "product = flush\n" + "currentpagedevice /PageSize get aload pop\n" + "2 copy gt {exch} if\n" + "(Unknown)\n" + "19 dict\n" + "dup [612 792] (Letter) put\n" + "dup [612 1008] (Legal) put\n" + "dup [612 935] (w612h935) put\n" + "dup [522 756] (Executive) put\n" + "dup [595 842] (A4) put\n" + "dup [420 595] (A5) put\n" + "dup [499 709] (ISOB5) put\n" + "dup [516 728] (B5) put\n" + "dup [612 936] (w612h936) put\n" + "dup [284 419] (Postcard) put\n" + "dup [419.5 567] (DoublePostcard) put\n" + "dup [558 774] (w558h774) put\n" + "dup [553 765] (w553h765) put\n" + "dup [522 737] (w522h737) put\n" + "dup [499 709] (EnvISOB5) put\n" + "dup [297 684] (Env10) put\n" + "dup [459 649] (EnvC5) put\n" + "dup [312 624] (EnvDL) put\n" + "dup [279 540] (EnvMonarch) put\n" + "{ exch aload pop 4 index sub abs 5 le exch\n" + " 5 index sub abs 5 le and\n" + " {exch pop exit} {pop} ifelse\n" + "} bind forall\n" + "= flush pop pop\n" + "/Courier findfont 12 scalefont setfont\n" + "0 setgray 36 720 moveto (Hello, ) show product show (!) show\n" + "showpage\n" + "restore\n" + "\004"; + + + if (do_pcl) + data = pcl_data; + else + data = ps_data; + + write(1, data, strlen(data)); + write(2, "DEBUG: START\n", 13); + timeout = 60.0; + while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer), + timeout)) > 0) + { + write(2, buffer, bytes); + timeout = 5.0; + } + write(2, "\nDEBUG: END\n", 12); + } + + exit(0); + } + else if (data_pid < 0) + { + perror("testbackend: Unable to fork"); + return (1); + } + } + else + data_fds[0] = data_fds[1] = -1; + + /* + * Execute the backend... + */ + + if ((back_pid = fork()) == 0) + { + /* + * Child comes here... + */ + + if (do_trickle || do_ps || do_pcl || do_cancel) + { + if (data_fds[0] != 0) + { + dup2(data_fds[0], 0); + close(data_fds[0]); + } + close(data_fds[1]); + } + + if (!show_log) + { + if ((fd = open("/dev/null", O_WRONLY)) != 2) + { + dup2(fd, 2); + close(fd); + } + } + + if (back_fds[1] != 3) + { + dup2(back_fds[1], 3); + close(back_fds[0]); + } + close(back_fds[1]); + + if (side_fds[1] != 4) + { + dup2(side_fds[1], 4); + close(side_fds[0]); + } + close(side_fds[1]); + + execv(backend, argv + first_arg); + fprintf(stderr, "testbackend: Unable to execute \"%s\": %s\n", backend, + strerror(errno)); + return (errno); + } + else if (back_pid < 0) + { + perror("testbackend: Unable to fork"); + return (1); + } + + /* + * Parent comes here, setup back and side channel file descriptors... + */ + + if (do_trickle || do_ps || do_pcl || do_cancel) + { + close(data_fds[0]); + close(data_fds[1]); + } + + if (back_fds[0] != 3) + { + dup2(back_fds[0], 3); + close(back_fds[0]); + } + close(back_fds[1]); + + if (side_fds[0] != 4) + { + dup2(side_fds[0], 4); + close(side_fds[0]); + } + close(side_fds[1]); + + /* + * Do side-channel tests as needed, then wait for the backend... + */ + + if (do_side_tests) + { + int length; /* Length of buffer */ + char buffer[2049]; /* Buffer for reponse */ + cups_sc_status_t scstatus; /* Status of side-channel command */ + static const char * const statuses[] = + { + "CUPS_SC_STATUS_NONE", /* No status */ + "CUPS_SC_STATUS_OK", /* Operation succeeded */ + "CUPS_SC_STATUS_IO_ERROR", /* An I/O error occurred */ + "CUPS_SC_STATUS_TIMEOUT", /* The backend did not respond */ + "CUPS_SC_STATUS_NO_RESPONSE", /* The device did not respond */ + "CUPS_SC_STATUS_BAD_MESSAGE", /* The command/response message was invalid */ + "CUPS_SC_STATUS_TOO_BIG", /* Response too big */ + "CUPS_SC_STATUS_NOT_IMPLEMENTED" /* Command not implemented */ + }; + + + sleep(2); + + length = 0; + scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer, + &length, 60.0); + printf("CUPS_SC_CMD_DRAIN_OUTPUT returned %s\n", statuses[scstatus]); + + length = 1; + scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer, + &length, 5.0); + printf("CUPS_SC_CMD_GET_BIDI returned %s, %d\n", statuses[scstatus], buffer[0]); + + length = sizeof(buffer) - 1; + scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, buffer, + &length, 5.0); + buffer[length] = '\0'; + printf("CUPS_SC_CMD_GET_DEVICE_ID returned %s, \"%s\"\n", + statuses[scstatus], buffer); + + length = 1; + scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_STATE, buffer, + &length, 5.0); + printf("CUPS_SC_CMD_GET_STATE returned %s, %02X\n", statuses[scstatus], + buffer[0] & 255); + + if (do_walk) + { + /* + * Walk the OID tree... + */ + + scstatus = cupsSideChannelSNMPWalk(oid, 5.0, walk_cb, NULL); + printf("CUPS_SC_CMD_SNMP_WALK returned %s\n", statuses[scstatus]); + } + else + { + /* + * Lookup the same OID twice... + */ + + length = sizeof(buffer); + scstatus = cupsSideChannelSNMPGet(oid, buffer, &length, 5.0); + printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %s\n", oid, + statuses[scstatus], buffer); + + length = sizeof(buffer); + scstatus = cupsSideChannelSNMPGet(oid, buffer, &length, 5.0); + printf("CUPS_SC_CMD_SNMP_GET %s returned %s, %s\n", oid, + statuses[scstatus], buffer); + } + + length = 0; + scstatus = cupsSideChannelDoRequest(CUPS_SC_CMD_SOFT_RESET, buffer, + &length, 5.0); + printf("CUPS_SC_CMD_SOFT_RESET returned %s\n", statuses[scstatus]); + } + + if (do_cancel) + { + sleep(1); + kill(data_pid, SIGTERM); + kill(back_pid, SIGTERM); + } + + while ((pid = wait(&status)) > 0) + { + if (status) + { + if (WIFEXITED(status)) + printf("%s exited with status %d!\n", + pid == back_pid ? backend : "test", + WEXITSTATUS(status)); + else + printf("%s crashed with signal %d!\n", + pid == back_pid ? backend : "test", + WTERMSIG(status)); + } + } + + /* + * Exit accordingly... + */ + + return (status != 0); +} + + +/* + * 'sigterm_handler()' - Flag when we get SIGTERM. + */ + +static void +sigterm_handler(int sig) /* I - Signal */ +{ + (void)sig; + + job_canceled = 1; +} + + +/* + * 'usage()' - Show usage information. + */ + +static void +usage(void) +{ + puts("Usage: testbackend [-cancel] [-d] [-ps | -pcl] [-s [-oid OID] " + "[-walk OID]] [-t] device-uri job-id user title copies options [file]"); + puts(""); + puts("Options:"); + puts(" -cancel Simulate a canceled print job after 2 seconds."); + puts(" -d Show log messages from backend."); + puts(" -oid OID Lookup the specified SNMP OID."); + puts(" (.1.3.6.1.2.1.43.10.2.1.4.1.1 is a good one for printers)"); + puts(" -pcl Send PCL+PJL query and test page to backend."); + puts(" -ps Send PostScript query and test page to backend."); + puts(" -s Do side-channel + SNMP tests."); + puts(" -t Send spaces slowly to backend ('trickle')."); + puts(" -walk OID Walk the specified SNMP OID."); + puts(" (.1.3.6.1.2.1.43 is a good one for printers)"); + + exit(1); +} + + +/* + * 'walk_cb()' - Show results of cupsSideChannelSNMPWalk... + */ + +static void +walk_cb(const char *oid, /* I - OID */ + const char *data, /* I - Data */ + int datalen, /* I - Length of data */ + void *context) /* I - Context (unused) */ +{ + printf("CUPS_SC_CMD_SNMP_WALK %s=%s (%d bytes)\n", oid, data, datalen); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/testsupplies.c b/backend/testsupplies.c new file mode 100644 index 0000000000..c380f280f3 --- /dev/null +++ b/backend/testsupplies.c @@ -0,0 +1,83 @@ +/* + * "$Id$" + * + * SNMP supplies test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2008 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Show the supplies state of a printer. + */ + +/* + * Include necessary headers. + */ + +#include "backend-private.h" + + +/* + * 'main()' - Show the supplies state of a printer. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + http_addrlist_t *host; /* Host addresses */ + int snmp_fd; /* SNMP socket */ + int page_count, /* Current page count */ + printer_state; /* Current printer state */ + + + if (argc != 2) + { + puts("Usage: testsupplies ip-or-hostname"); + return (1); + } + + if ((host = httpAddrGetList(argv[1], AF_UNSPEC, "9100")) == NULL) + { + perror(argv[1]); + return (1); + } + + if ((snmp_fd = _cupsSNMPOpen(host->addr.addr.sa_family)) < 0) + { + perror(argv[1]); + return (1); + } + + for (;;) + { + fputs("backendSNMPSupplies: ", stdout); + + if (backendSNMPSupplies(snmp_fd, &(host->addr), &page_count, + &printer_state)) + { + puts("FAIL"); + return (1); + } + + printf("backendSNMPSupplies: %s (page_count=%d, printer_state=%d)\n", + page_count < 0 || printer_state < CUPS_TC_other || + printer_state > CUPS_TC_warmup ? "FAIL" : "PASS", + page_count, printer_state); + + sleep(5); + } +} + + +/* + * End of "$Id$". + */ diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c new file mode 100644 index 0000000000..40bda96a92 --- /dev/null +++ b/backend/usb-darwin.c @@ -0,0 +1,2260 @@ +/* +* "$Id$" +* +* Copyright 2005-2010 Apple Inc. All rights reserved. +* +* IMPORTANT: This Apple software is supplied to you by Apple Computer, +* Inc. ("Apple") in consideration of your agreement to the following +* terms, and your use, installation, modification or redistribution of +* this Apple software constitutes acceptance of these terms. If you do +* not agree with these terms, please do not use, install, modify or +* redistribute this Apple software. +* +* In consideration of your agreement to abide by the following terms, and +* subject to these terms, Apple grants you a personal, non-exclusive +* license, under Apple's copyrights in this original Apple software (the +* "Apple Software"), to use, reproduce, modify and redistribute the Apple +* Software, with or without modifications, in source and/or binary forms; +* provided that if you redistribute the Apple Software in its entirety and +* without modifications, you must retain this notice and the following +* text and disclaimers in all such redistributions of the Apple Software. +* Neither the name, trademarks, service marks or logos of Apple Computer, +* Inc. may be used to endorse or promote products derived from the Apple +* Software without specific prior written permission from Apple. Except +* as expressly stated in this notice, no other rights or licenses, express +* or implied, are granted by Apple herein, including but not limited to +* any patent rights that may be infringed by your derivative works or by +* other works in which the Apple Software may be incorporated. +* +* The Apple Software is provided by Apple on an "AS IS" basis. APPLE +* MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION +* THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND +* OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. +* +* IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL +* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, +* MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED +* AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), +* STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* Contents: +* +* list_devices() - List all USB devices. +* print_device() - Print a file to a USB device. +* sidechannel_thread() - Thread to handle side-channel requests. +* read_thread() - Thread to read the backchannel data on. +* list_device_cb() - list_device iterator callback. +* find_device_cb() - print_device iterator callback. +* status_timer_cb() - Status timer callback. +* iterate_printers() - Iterate over all the printers. +* device_added() - Device added notifier. +* copy_deviceinfo() - Copy strings from the 1284 device ID. +* release_deviceinfo() - Release deviceinfo strings. +* load_classdriver() - Load a classdriver. +* unload_classdriver() - Unload a classdriver. +* load_printerdriver() - Load vendor's classdriver. +* registry_open() - Open a connection to the printer. +* registry_close() - Close the connection to the printer. +* copy_deviceid() - Copy the 1284 device id string. +* copy_devicestring() - Copy the 1284 device id string. +* copy_value_for_key() - Copy value string associated with a key. +* cfstr_create_trim() - Create CFString and trim whitespace characters. +* parse_options() - Parse uri options. +* setup_cfLanguage() - Create AppleLanguages array from LANG environment var. +* run_legacy_backend() - Re-exec backend as ppc or i386. +* sigterm_handler() - SIGTERM handler. +* next_line() - Find the next line in a buffer. +* parse_pserror() - Scan the backchannel data for postscript errors. +* get_device_id() - Return IEEE-1284 device ID. +*/ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "backend-private.h" + +#include +#include +#include + +#include +#include + +extern char **environ; + + +/* + * DEBUG_WRITES, if defined, causes the backend to write data to the printer in + * 512 byte increments, up to 8192 bytes, to make debugging with a USB bus + * analyzer easier. + */ + +#define DEBUG_WRITES 0 + +/* + * WAIT_EOF_DELAY is number of seconds we'll wait for responses from + * the printer after we've finished sending all the data + */ +#define WAIT_EOF_DELAY 7 +#define WAIT_SIDE_DELAY 3 +#define DEFAULT_TIMEOUT 5000L + +#define USB_INTERFACE_KIND CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID190) +#define kUSBLanguageEnglish 0x409 + +#define PRINTER_POLLING_INTERVAL 5 /* seconds */ +#define INITIAL_LOG_INTERVAL PRINTER_POLLING_INTERVAL +#define SUBSEQUENT_LOG_INTERVAL 3 * INITIAL_LOG_INTERVAL + +#define kUSBPrinterClassTypeID CFUUIDGetConstantUUIDWithBytes(NULL, 0x06, 0x04, 0x7D, 0x16, 0x53, 0xA2, 0x11, 0xD6, 0x92, 0x06, 0x00, 0x30, 0x65, 0x52, 0x45, 0x92) +#define kUSBPrinterClassInterfaceID CFUUIDGetConstantUUIDWithBytes(NULL, 0x03, 0x34, 0x6D, 0x74, 0x53, 0xA3, 0x11, 0xD6, 0x9E, 0xA1, 0x76, 0x30, 0x65, 0x52, 0x45, 0x92) + +#define kUSBClassDriverProperty CFSTR("USB Printing Class") + +#define kUSBGenericTOPrinterClassDriver CFSTR("/System/Library/Printers/Libraries/USBGenericTOPrintingClass.plugin") +#define kUSBPrinterClassDeviceNotOpen -9664 /*kPMInvalidIOMContext*/ + + +/* + * Section 5.3 USB Printing Class spec + */ +#define kUSBPrintingSubclass 1 +#define kUSBPrintingProtocolNoOpen 0 +#define kUSBPrintingProtocolUnidirectional 1 +#define kUSBPrintingProtocolBidirectional 2 + +typedef IOUSBInterfaceInterface190 **printer_interface_t; + +typedef struct iodevice_request_s /**** Device request ****/ +{ + UInt8 requestType; + UInt8 request; + UInt16 value; + UInt16 index; + UInt16 length; + void *buffer; +} iodevice_request_t; + +typedef union /**** Centronics status byte ****/ +{ + char b; + struct + { + unsigned reserved0:2; + unsigned paperError:1; + unsigned select:1; + unsigned notError:1; + unsigned reserved1:3; + } status; +} centronics_status_t; + +typedef struct classdriver_s /**** g.classdriver context ****/ +{ + IUNKNOWN_C_GUTS; + CFPlugInRef plugin; /* release plugin */ + IUnknownVTbl **factory; /* Factory */ + void *vendorReference; /* vendor class specific usage */ + UInt32 location; /* unique location in bus topology */ + UInt8 interfaceNumber; /* Interface number */ + UInt16 vendorID; /* Vendor id */ + UInt16 productID; /* Product id */ + printer_interface_t interface; /* identify the device to IOKit */ + UInt8 outpipe; /* mandatory bulkOut pipe */ + UInt8 inpipe; /* optional bulkIn pipe */ + + /* general class requests */ + kern_return_t (*DeviceRequest)(struct classdriver_s **printer, iodevice_request_t *iorequest, UInt16 timeout); + kern_return_t (*GetString)(struct classdriver_s **printer, UInt8 whichString, UInt16 language, UInt16 timeout, CFStringRef *result); + + /* standard printer class requests */ + kern_return_t (*SoftReset)(struct classdriver_s **printer, UInt16 timeout); + kern_return_t (*GetCentronicsStatus)(struct classdriver_s **printer, centronics_status_t *result, UInt16 timeout); + kern_return_t (*GetDeviceID)(struct classdriver_s **printer, CFStringRef *devid, UInt16 timeout); + + /* standard bulk device requests */ + kern_return_t (*ReadPipe)(struct classdriver_s **printer, UInt8 *buffer, UInt32 *count); + kern_return_t (*WritePipe)(struct classdriver_s **printer, UInt8 *buffer, UInt32 *count, Boolean eoj); + + /* interface requests */ + kern_return_t (*Open)(struct classdriver_s **printer, UInt32 location, UInt8 protocol); + kern_return_t (*Abort)(struct classdriver_s **printer); + kern_return_t (*Close)(struct classdriver_s **printer); + + /* initialize and terminate */ + kern_return_t (*Initialize)(struct classdriver_s **printer, struct classdriver_s **baseclass); + kern_return_t (*Terminate)(struct classdriver_s **printer); + +} classdriver_t; + +typedef Boolean (*iterator_callback_t)(void *refcon, io_service_t obj); + +typedef struct iterator_reference_s /**** Iterator reference data */ +{ + iterator_callback_t callback; + void *userdata; + Boolean keepRunning; +} iterator_reference_t; + +typedef struct globals_s +{ + io_service_t printer_obj; + classdriver_t **classdriver; + + pthread_mutex_t read_thread_mutex; + pthread_cond_t read_thread_cond; + int read_thread_stop; + int read_thread_done; + + pthread_mutex_t readwrite_lock_mutex; + pthread_cond_t readwrite_lock_cond; + int readwrite_lock; + + CFStringRef make; + CFStringRef model; + CFStringRef serial; + UInt32 location; + UInt8 interfaceNum; + + CFRunLoopTimerRef status_timer; + + int print_fd; /* File descriptor to print */ + ssize_t print_bytes; /* Print bytes read */ +#if DEBUG_WRITES + ssize_t debug_bytes; /* Current bytes to read */ +#endif /* DEBUG_WRITES */ + + Boolean wait_eof; + int drain_output; /* Drain all pending output */ + int bidi_flag; /* 0=unidirectional, 1=bidirectional */ + + pthread_mutex_t sidechannel_thread_mutex; + pthread_cond_t sidechannel_thread_cond; + int sidechannel_thread_stop; + int sidechannel_thread_done; +} globals_t; + + +/* + * Globals... + */ + +globals_t g = { 0 }; /* Globals */ + + +/* + * Local functions... + */ + +static Boolean find_device_cb(void *refcon, io_service_t obj); +static Boolean list_device_cb(void *refcon, io_service_t obj); +static CFStringRef cfstr_create_trim(const char *cstr); +static CFStringRef copy_value_for_key(CFStringRef deviceID, CFStringRef *keys); +static kern_return_t load_classdriver(CFStringRef driverPath, printer_interface_t intf, classdriver_t ***printerDriver); +static kern_return_t load_printerdriver(CFStringRef *driverBundlePath); +static kern_return_t registry_close(); +static kern_return_t registry_open(CFStringRef *driverBundlePath); +static kern_return_t unload_classdriver(); +static OSStatus copy_deviceid(classdriver_t **printer, CFStringRef *deviceID); +static void *read_thread(void *reference); +static void *sidechannel_thread(void *reference); +static void copy_deviceinfo(CFStringRef deviceIDString, CFStringRef *make, CFStringRef *model, CFStringRef *serial); +static void copy_devicestring(io_service_t usbInterface, CFStringRef *deviceID, UInt32 *deviceLocation, UInt8 *interfaceNum); +static void device_added(void *userdata, io_iterator_t iterator); +static void get_device_id(cups_sc_status_t *status, char *data, int *datalen); +static void iterate_printers(iterator_callback_t callBack, void *userdata); +static void parse_options(char *options, char *serial, int serial_size, UInt32 *location, Boolean *wait_eof); +static void release_deviceinfo(CFStringRef *make, CFStringRef *model, CFStringRef *serial); +static void setup_cfLanguage(void); +static void soft_reset(); +static void status_timer_cb(CFRunLoopTimerRef timer, void *info); + +#if defined(__i386__) || defined(__x86_64__) +static pid_t child_pid; /* Child PID */ +static void run_legacy_backend(int argc, char *argv[], int fd); /* Starts child backend process running as a ppc executable */ +#endif /* __i386__ || __x86_64__ */ +static void sigterm_handler(int sig); /* SIGTERM handler */ + +#ifdef PARSE_PS_ERRORS +static const char *next_line (const char *buffer); +static void parse_pserror (char *sockBuffer, int len); +#endif /* PARSE_PS_ERRORS */ + +#pragma mark - + +/* + * 'list_devices()' - List all USB devices. + */ + +void list_devices() +{ + iterate_printers(list_device_cb, NULL); +} + + +/* + * 'print_device()' - Print a file to a USB device. + */ + +int /* O - Exit status */ +print_device(const char *uri, /* I - Device URI */ + const char *hostname, /* I - Hostname/manufacturer */ + const char *resource, /* I - Resource/modelname */ + char *options, /* I - Device options/serial number */ + int print_fd, /* I - File descriptor to print */ + int copies, /* I - Copies to print */ + int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + char serial[1024]; /* Serial number buffer */ + OSStatus status; /* Function results */ + IOReturn iostatus; /* Current IO status */ + pthread_t read_thread_id, /* Read thread */ + sidechannel_thread_id;/* Side-channel thread */ + int have_sidechannel = 0; /* Was the side-channel thread started? */ + struct stat sidechannel_info; /* Side-channel file descriptor info */ + char print_buffer[8192], /* Print data buffer */ + *print_ptr; /* Pointer into print data buffer */ + UInt32 location; /* Unique location in bus topology */ + fd_set input_set; /* Input set for select() */ + CFStringRef driverBundlePath; /* Class driver path */ + int countdown, /* Logging interval */ + nfds; /* Number of file descriptors */ + ssize_t total_bytes; /* Total bytes written */ + UInt32 bytes; /* Bytes written */ + struct timeval *timeout, /* Timeout pointer */ + stimeout; /* Timeout for select() */ + struct timespec cond_timeout; /* pthread condition timeout */ + + + /* + * See if the side-channel descriptor is valid... + */ + + have_sidechannel = !fstat(CUPS_SC_FD, &sidechannel_info) && + S_ISSOCK(sidechannel_info.st_mode); + + /* + * Localize using CoreFoundation... + */ + + setup_cfLanguage(); + + parse_options(options, serial, sizeof(serial), &location, &g.wait_eof); + + if (resource[0] == '/') + resource++; + + g.print_fd = print_fd; + g.make = cfstr_create_trim(hostname); + g.model = cfstr_create_trim(resource); + g.serial = cfstr_create_trim(serial); + g.location = location; + + if (!g.make || !g.model) + { + _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n")); + + if (!g.make) + fputs("DEBUG: USB make string is NULL\n", stderr); + if (!g.model) + fputs("DEBUG: USB model string is NULL\n", stderr); + + return (CUPS_BACKEND_STOP); + } + + fputs("STATE: +connecting-to-device\n", stderr); + + countdown = INITIAL_LOG_INTERVAL; + + do + { + if (g.printer_obj) + { + IOObjectRelease(g.printer_obj); + unload_classdriver(&g.classdriver); + g.printer_obj = 0x0; + g.classdriver = 0x0; + } + + fprintf(stderr, "DEBUG: Looking for '%s %s'\n", hostname, resource); + + iterate_printers(find_device_cb, NULL); + + fputs("DEBUG: Opening connection\n", stderr); + + driverBundlePath = NULL; + + status = registry_open(&driverBundlePath); + +#if defined(__i386__) || defined(__x86_64__) + /* + * If we were unable to load the class drivers for this printer it's + * probably because they're ppc or i386. In this case try to run this + * backend as i386 or ppc executables so we can use them... + */ + if (status == -2) + { + run_legacy_backend(argc, argv, print_fd); + /* Never returns here */ + } +#endif /* __i386__ || __x86_64__ */ + + if (status == -2) + { + /* + * If we still were unable to load the class drivers for this printer log + * the error and stop the queue... + */ + + if (driverBundlePath == NULL || !CFStringGetCString(driverBundlePath, print_buffer, sizeof(print_buffer), kCFStringEncodingUTF8)) + strlcpy(print_buffer, "USB class driver", sizeof(print_buffer)); + + fputs("STATE: +apple-missing-usbclassdriver-error\n", stderr); + _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n")); + fprintf(stderr, "DEBUG: Could not load %s\n", print_buffer); + + if (driverBundlePath) + CFRelease(driverBundlePath); + + return (CUPS_BACKEND_STOP); + } + + if (driverBundlePath) + CFRelease(driverBundlePath); + + if (status != noErr) + { + sleep(PRINTER_POLLING_INTERVAL); + countdown -= PRINTER_POLLING_INTERVAL; + if (countdown <= 0) + { + _cupsLangPuts(stderr, + _("INFO: Waiting for printer to become available...\n")); + fprintf(stderr, "DEBUG: USB printer status: 0x%08x\n", (int)status); + countdown = SUBSEQUENT_LOG_INTERVAL; /* subsequent log entries, every 15 seconds */ + } + } + } while (status != noErr); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * 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 (!print_fd) + { + struct sigaction action; /* POSIX signal action */ + + + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); + } + + /* + * Start the side channel thread if the descriptor is valid... + */ + + pthread_mutex_init(&g.readwrite_lock_mutex, NULL); + pthread_cond_init(&g.readwrite_lock_cond, NULL); + g.readwrite_lock = 1; + + if (have_sidechannel) + { + g.sidechannel_thread_stop = 0; + g.sidechannel_thread_done = 0; + + pthread_cond_init(&g.sidechannel_thread_cond, NULL); + pthread_mutex_init(&g.sidechannel_thread_mutex, NULL); + + if (pthread_create(&sidechannel_thread_id, NULL, sidechannel_thread, NULL)) + { + _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n")); + fputs("DEBUG: Couldn't create side-channel thread\n", stderr); + registry_close(); + return (CUPS_BACKEND_STOP); + } + } + + /* + * Get the read thread going... + */ + + g.read_thread_stop = 0; + g.read_thread_done = 0; + + pthread_cond_init(&g.read_thread_cond, NULL); + pthread_mutex_init(&g.read_thread_mutex, NULL); + + if (pthread_create(&read_thread_id, NULL, read_thread, NULL)) + { + _cupsLangPuts(stderr, _("ERROR: Fatal USB error\n")); + fputs("DEBUG: Couldn't create read thread\n", stderr); + registry_close(); + return (CUPS_BACKEND_STOP); + } + + /* + * The main thread sends the print file... + */ + + g.drain_output = 0; + g.print_bytes = 0; + total_bytes = 0; + print_ptr = print_buffer; + + while (status == noErr && copies-- > 0) + { + _cupsLangPuts(stderr, _("INFO: Sending print data...\n")); + + if (print_fd != STDIN_FILENO) + { + fputs("PAGE: 1 1\n", stderr); + lseek(print_fd, 0, SEEK_SET); + } + + while (status == noErr) + { + FD_ZERO(&input_set); + + if (!g.print_bytes) + FD_SET(print_fd, &input_set); + + /* + * Calculate select timeout... + * If we have data waiting to send timeout is 100ms. + * else if we're draining print_fd timeout is 0. + * else we're waiting forever... + */ + + if (g.print_bytes) + { + stimeout.tv_sec = 0; + stimeout.tv_usec = 100000; /* 100ms */ + timeout = &stimeout; + } + else if (g.drain_output) + { + stimeout.tv_sec = 0; + stimeout.tv_usec = 0; + timeout = &stimeout; + } + else + timeout = NULL; + + /* + * I/O is unlocked around select... + */ + + pthread_mutex_lock(&g.readwrite_lock_mutex); + g.readwrite_lock = 0; + pthread_cond_signal(&g.readwrite_lock_cond); + pthread_mutex_unlock(&g.readwrite_lock_mutex); + + nfds = select(print_fd + 1, &input_set, NULL, NULL, timeout); + + /* + * Reacquire the lock... + */ + + pthread_mutex_lock(&g.readwrite_lock_mutex); + while (g.readwrite_lock) + pthread_cond_wait(&g.readwrite_lock_cond, &g.readwrite_lock_mutex); + g.readwrite_lock = 1; + pthread_mutex_unlock(&g.readwrite_lock_mutex); + + if (nfds < 0) + { + if (errno == EINTR && total_bytes == 0) + { + fputs("DEBUG: Received an interrupt before any bytes were " + "written, aborting\n", stderr); + registry_close(); + return (CUPS_BACKEND_OK); + } + else if (errno != EAGAIN && errno != EINTR) + { + _cupsLangPuts(stderr, _("ERROR: Unable to read print data\n")); + perror("DEBUG: select"); + registry_close(); + return (CUPS_BACKEND_FAILED); + } + } + + /* + * If drain output has finished send a response... + */ + + if (g.drain_output && !nfds && !g.print_bytes) + { + /* Send a response... */ + cupsSideChannelWrite(CUPS_SC_CMD_DRAIN_OUTPUT, CUPS_SC_STATUS_OK, NULL, 0, 1.0); + g.drain_output = 0; + } + + /* + * Check if we have print data ready... + */ + + if (FD_ISSET(print_fd, &input_set)) + { +#if DEBUG_WRITES + g.debug_bytes += 512; + if (g.debug_bytes > sizeof(print_buffer)) + g.debug_bytes = 512; + + g.print_bytes = read(print_fd, print_buffer, g.debug_bytes); + +#else + g.print_bytes = read(print_fd, print_buffer, sizeof(print_buffer)); +#endif /* DEBUG_WRITES */ + + if (g.print_bytes < 0) + { + /* + * Read error - bail if we don't see EAGAIN or EINTR... + */ + + if (errno != EAGAIN && errno != EINTR) + { + _cupsLangPuts(stderr, _("ERROR: Unable to read print data\n")); + perror("DEBUG: read"); + registry_close(); + return (CUPS_BACKEND_FAILED); + } + + g.print_bytes = 0; + } + else if (g.print_bytes == 0) + { + /* + * End of file, break out of the loop... + */ + + break; + } + + print_ptr = print_buffer; + + fprintf(stderr, "DEBUG: Read %d bytes of print data...\n", + (int)g.print_bytes); + } + + if (g.print_bytes) + { + bytes = g.print_bytes; + iostatus = (*g.classdriver)->WritePipe(g.classdriver, (UInt8*)print_ptr, &bytes, 0); + + /* + * Ignore timeout errors, but retain the number of bytes written to + * avoid sending duplicate data ()... + */ + + if (iostatus == kIOUSBTransactionTimeout) + { + fputs("DEBUG: Got USB transaction timeout during write\n", stderr); + iostatus = 0; + } + + /* + * If we've stalled, retry the write... + */ + + else if (iostatus == kIOUSBPipeStalled) + { + fputs("DEBUG: Got USB pipe stalled during write\n", stderr); + + bytes = g.print_bytes; + iostatus = (*g.classdriver)->WritePipe(g.classdriver, (UInt8*)print_ptr, &bytes, 0); + } + + /* + * Retry a write after an aborted write since we probably just got + * SIGTERM ()... + */ + + else if (iostatus == kIOReturnAborted) + { + fputs("DEBUG: Got USB return aborted during write\n", stderr); + + IOReturn err = (*g.classdriver)->Abort(g.classdriver); + fprintf(stderr, "DEBUG: USB class driver Abort returned %x\n", err); + +#if DEBUG_WRITES + sleep(5); +#endif /* DEBUG_WRITES */ + + bytes = g.print_bytes; + iostatus = (*g.classdriver)->WritePipe(g.classdriver, (UInt8*)print_ptr, &bytes, 0); + } + + if (iostatus || bytes < 0) + { + /* + * Write error - bail if we don't see an error we can retry... + */ + + _cupsLangPuts(stderr, _("ERROR: Unable to send print data\n")); + fprintf(stderr, "DEBUG: USB class driver WritePipe returned %x\n", + iostatus); + + IOReturn err = (*g.classdriver)->Abort(g.classdriver); + fprintf(stderr, "DEBUG: USB class driver Abort returned %x\n", + err); + + status = CUPS_BACKEND_FAILED; + break; + } + else if (bytes > 0) + { + fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes); + + g.print_bytes -= bytes; + print_ptr += bytes; + total_bytes += bytes; + } + } + + if (print_fd != 0 && status == noErr) + fprintf(stderr, "DEBUG: Sending print file, %lld bytes...\n", + (off_t)total_bytes); + } + } + + fprintf(stderr, "DEBUG: Sent %lld bytes...\n", (off_t)total_bytes); + + if (!print_fd) + { + /* + * Re-enable the SIGTERM handler so pthread_kill() will work... + */ + + struct sigaction action; /* POSIX signal action */ + + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGTERM); + action.sa_handler = sigterm_handler; + sigaction(SIGTERM, &action, NULL); + } + + /* + * Wait for the side channel thread to exit... + */ + + if (have_sidechannel) + { + close(CUPS_SC_FD); + pthread_mutex_lock(&g.readwrite_lock_mutex); + g.readwrite_lock = 0; + pthread_cond_signal(&g.readwrite_lock_cond); + pthread_mutex_unlock(&g.readwrite_lock_mutex); + + g.sidechannel_thread_stop = 1; + pthread_mutex_lock(&g.sidechannel_thread_mutex); + if (!g.sidechannel_thread_done) + { + /* + * Wait for the side-channel thread to exit... + */ + + cond_timeout.tv_sec = time(NULL) + WAIT_SIDE_DELAY; + cond_timeout.tv_nsec = 0; + if (pthread_cond_timedwait(&g.sidechannel_thread_cond, + &g.sidechannel_thread_mutex, + &cond_timeout) != 0) + { + /* + * Force the side-channel thread to exit... + */ + + fputs("DEBUG: Force the side-channel thread to exit...\n", stderr); + pthread_kill(sidechannel_thread_id, SIGTERM); + } + } + pthread_mutex_unlock(&g.sidechannel_thread_mutex); + + pthread_join(sidechannel_thread_id, NULL); + + pthread_cond_destroy(&g.sidechannel_thread_cond); + pthread_mutex_destroy(&g.sidechannel_thread_mutex); + } + + pthread_cond_destroy(&g.readwrite_lock_cond); + pthread_mutex_destroy(&g.readwrite_lock_mutex); + + /* + * Signal the read thread to stop... + */ + + g.read_thread_stop = 1; + + /* + * Give the read thread WAIT_EOF_DELAY seconds to complete all the data. If + * we are not signaled in that time then force the thread to exit. + */ + + pthread_mutex_lock(&g.read_thread_mutex); + + if (!g.read_thread_done) + { + cond_timeout.tv_sec = time(NULL) + WAIT_EOF_DELAY; + cond_timeout.tv_nsec = 0; + + if (pthread_cond_timedwait(&g.read_thread_cond, &g.read_thread_mutex, + &cond_timeout) != 0) + { + /* + * Force the read thread to exit... + */ + + g.wait_eof = 0; + fputs("DEBUG: Force the read thread to exit...\n", stderr); + pthread_kill(read_thread_id, SIGTERM); + } + } + pthread_mutex_unlock(&g.read_thread_mutex); + + pthread_join(read_thread_id, NULL); /* wait for the read thread to return */ + + pthread_cond_destroy(&g.read_thread_cond); + pthread_mutex_destroy(&g.read_thread_mutex); + + /* + * Close the connection and input file and general clean up... + */ + + registry_close(); + + if (print_fd != STDIN_FILENO) + close(print_fd); + + if (g.make != NULL) + CFRelease(g.make); + + if (g.model != NULL) + CFRelease(g.model); + + if (g.serial != NULL) + CFRelease(g.serial); + + if (g.printer_obj != 0x0) + IOObjectRelease(g.printer_obj); + + return status; +} + + +/* + * 'read_thread()' - Thread to read the backchannel data on. + */ + +static void *read_thread(void *reference) +{ + UInt8 readbuffer[512]; + UInt32 rbytes; + kern_return_t readstatus; + struct mach_timebase_info timeBaseInfo; + uint64_t start, + delay; + + /* Calculate what 250 milliSeconds are in mach absolute time... + */ + mach_timebase_info(&timeBaseInfo); + delay = ((uint64_t)250000000 * (uint64_t)timeBaseInfo.denom) / (uint64_t)timeBaseInfo.numer; + + do + { + /* + * Remember when we started so we can throttle the loop after the read call... + */ + + start = mach_absolute_time(); + + rbytes = sizeof(readbuffer); + readstatus = (*g.classdriver)->ReadPipe(g.classdriver, readbuffer, &rbytes); + if (readstatus == kIOReturnSuccess && rbytes > 0) + { + fprintf(stderr, "DEBUG: Read %d bytes of back-channel data...\n", + (int)rbytes); + cupsBackChannelWrite((char*)readbuffer, rbytes, 1.0); + + /* cntrl-d is echoed by the printer. + * NOTES: + * Xerox Phaser 6250D doesn't echo the cntrl-d. + * Xerox Phaser 6250D doesn't always send the product query. + */ + if (g.wait_eof && readbuffer[rbytes-1] == 0x4) + break; + +#ifdef PARSE_PS_ERRORS + parse_pserror(readbuffer, rbytes); +#endif + } + else if (readstatus == kIOUSBTransactionTimeout) + fputs("DEBUG: Got USB transaction timeout during read\n", stderr); + else if (readstatus == kIOUSBPipeStalled) + fputs("DEBUG: Got USB pipe stalled during read\n", stderr); + else if (readstatus == kIOReturnAborted) + fputs("DEBUG: Got USB return aborted during read\n", stderr); + + /* + * Make sure this loop executes no more than once every 250 miliseconds... + */ + + if ((readstatus != kIOReturnSuccess || rbytes == 0) && (g.wait_eof || !g.read_thread_stop)) + mach_wait_until(start + delay); + + } while (g.wait_eof || !g.read_thread_stop); /* Abort from main thread tests error here */ + + /* + * Let the main thread know that we have completed the read thread... + */ + + pthread_mutex_lock(&g.read_thread_mutex); + g.read_thread_done = 1; + pthread_cond_signal(&g.read_thread_cond); + pthread_mutex_unlock(&g.read_thread_mutex); + + return NULL; +} + + +/* + * 'sidechannel_thread()' - Handle side-channel requests. + */ + +static void* +sidechannel_thread(void *reference) +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + + do + { + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + { + if (status == CUPS_SC_STATUS_TIMEOUT) + continue; + else + break; + } + + switch (command) + { + case CUPS_SC_CMD_SOFT_RESET: /* Do a soft reset */ + fputs("DEBUG: CUPS_SC_CMD_SOFT_RESET received from driver...\n", + stderr); + + if ((*g.classdriver)->SoftReset != NULL) + { + soft_reset(); + cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, NULL, 0, 1.0); + fputs("DEBUG: Returning status CUPS_STATUS_OK with no bytes...\n", + stderr); + } + else + { + cupsSideChannelWrite(command, CUPS_SC_STATUS_NOT_IMPLEMENTED, + NULL, 0, 1.0); + fputs("DEBUG: Returning status CUPS_STATUS_NOT_IMPLEMENTED with " + "no bytes...\n", stderr); + } + break; + + case CUPS_SC_CMD_DRAIN_OUTPUT: /* Drain all pending output */ + fputs("DEBUG: CUPS_SC_CMD_DRAIN_OUTPUT received from driver...\n", + stderr); + + g.drain_output = 1; + break; + + case CUPS_SC_CMD_GET_BIDI: /* Is the connection bidirectional? */ + fputs("DEBUG: CUPS_SC_CMD_GET_BIDI received from driver...\n", + stderr); + + data[0] = g.bidi_flag; + cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0); + + fprintf(stderr, + "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n", + data[0]); + break; + + case CUPS_SC_CMD_GET_DEVICE_ID: /* Return IEEE-1284 device ID */ + fputs("DEBUG: CUPS_SC_CMD_GET_DEVICE_ID received from driver...\n", + stderr); + + datalen = sizeof(data); + get_device_id(&status, data, &datalen); + cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, datalen, 1.0); + + if (datalen < sizeof(data)) + data[datalen] = '\0'; + else + data[sizeof(data) - 1] = '\0'; + + fprintf(stderr, + "DEBUG: Returning CUPS_SC_STATUS_OK with %d bytes (%s)...\n", + datalen, data); + break; + + case CUPS_SC_CMD_GET_STATE: /* Return device state */ + fputs("DEBUG: CUPS_SC_CMD_GET_STATE received from driver...\n", + stderr); + + data[0] = CUPS_SC_STATE_ONLINE; + cupsSideChannelWrite(command, CUPS_SC_STATUS_OK, data, 1, 1.0); + + fprintf(stderr, + "DEBUG: Returned CUPS_SC_STATUS_OK with 1 byte (%02X)...\n", + data[0]); + break; + + default: + fprintf(stderr, "DEBUG: Unknown side-channel command (%d) received " + "from driver...\n", command); + + cupsSideChannelWrite(command, CUPS_SC_STATUS_NOT_IMPLEMENTED, + NULL, 0, 1.0); + + fputs("DEBUG: Returned CUPS_SC_STATUS_NOT_IMPLEMENTED with no bytes...\n", + stderr); + break; + } + } + while (!g.sidechannel_thread_stop); + + pthread_mutex_lock(&g.sidechannel_thread_mutex); + g.sidechannel_thread_done = 1; + pthread_cond_signal(&g.sidechannel_thread_cond); + pthread_mutex_unlock(&g.sidechannel_thread_mutex); + + return NULL; +} + + +#pragma mark - +/* + * 'iterate_printers()' - Iterate over all the printers. + */ + +static void iterate_printers(iterator_callback_t callBack, + void *userdata) +{ + mach_port_t masterPort = 0x0; + kern_return_t kr = IOMasterPort (bootstrap_port, &masterPort); + + if (kr == kIOReturnSuccess && masterPort != 0x0) + { + io_iterator_t addIterator = 0x0; + + iterator_reference_t reference = { callBack, userdata, true }; + IONotificationPortRef addNotification = IONotificationPortCreate(masterPort); + + int klass = kUSBPrintingClass; + int subklass = kUSBPrintingSubclass; + + CFNumberRef usb_klass = CFNumberCreate(NULL, kCFNumberIntType, &klass); + CFNumberRef usb_subklass = CFNumberCreate(NULL, kCFNumberIntType, &subklass); + CFMutableDictionaryRef usbPrinterMatchDictionary = IOServiceMatching(kIOUSBInterfaceClassName); + + CFDictionaryAddValue(usbPrinterMatchDictionary, CFSTR("bInterfaceClass"), usb_klass); + CFDictionaryAddValue(usbPrinterMatchDictionary, CFSTR("bInterfaceSubClass"), usb_subklass); + + CFRelease(usb_klass); + CFRelease(usb_subklass); + + kr = IOServiceAddMatchingNotification(addNotification, kIOMatchedNotification, usbPrinterMatchDictionary, &device_added, &reference, &addIterator); + if (addIterator != 0x0) + { + device_added (&reference, addIterator); + + if (reference.keepRunning) + { + CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(addNotification), kCFRunLoopDefaultMode); + CFRunLoopRun(); + } + IOObjectRelease(addIterator); + } + mach_port_deallocate(mach_task_self(), masterPort); + } +} + + +/* + * 'device_added()' - Device added notifier. + */ + +static void device_added(void *userdata, + io_iterator_t iterator) +{ + iterator_reference_t *reference = userdata; + + io_service_t obj; + while (reference->keepRunning && (obj = IOIteratorNext(iterator)) != 0x0) + { + if (reference->callback != NULL) + reference->keepRunning = reference->callback(reference->userdata, obj); + + IOObjectRelease(obj); + } + + /* One last call to the call back now that we are not longer have printers left to iterate... + */ + if (reference->keepRunning) + reference->keepRunning = reference->callback(reference->userdata, 0x0); + + if (!reference->keepRunning) + CFRunLoopStop(CFRunLoopGetCurrent()); +} + + +/* + * 'list_device_cb()' - list_device iterator callback. + */ + +static Boolean list_device_cb(void *refcon, + io_service_t obj) +{ + Boolean keepRunning = (obj != 0x0); + + if (keepRunning) + { + CFStringRef deviceIDString = NULL; + UInt32 deviceLocation = 0; + UInt8 interfaceNum = 0; + + copy_devicestring(obj, &deviceIDString, &deviceLocation, &interfaceNum); + if (deviceIDString != NULL) + { + CFStringRef make = NULL, model = NULL, serial = NULL; + char uristr[1024], makestr[1024], modelstr[1024], serialstr[1024]; + char optionsstr[1024], idstr[1024], make_modelstr[1024]; + + copy_deviceinfo(deviceIDString, &make, &model, &serial); + CFStringGetCString(deviceIDString, idstr, sizeof(idstr), + kCFStringEncodingUTF8); + backendGetMakeModel(idstr, make_modelstr, sizeof(make_modelstr)); + + modelstr[0] = '/'; + + if (!make || + !CFStringGetCString(make, makestr, sizeof(makestr), + kCFStringEncodingUTF8)) + strcpy(makestr, "Unknown"); + + if (!model || + !CFStringGetCString(model, &modelstr[1], sizeof(modelstr)-1, + kCFStringEncodingUTF8)) + strcpy(modelstr + 1, "Printer"); + + optionsstr[0] = '\0'; + if (serial != NULL) + { + CFStringGetCString(serial, serialstr, sizeof(serialstr), kCFStringEncodingUTF8); + snprintf(optionsstr, sizeof(optionsstr), "?serial=%s", serialstr); + } + else if (deviceLocation != 0) + snprintf(optionsstr, sizeof(optionsstr), "?location=%x", (unsigned)deviceLocation); + + httpAssembleURI(HTTP_URI_CODING_ALL, uristr, sizeof(uristr), "usb", NULL, makestr, 0, modelstr); + strlcat(uristr, optionsstr, sizeof(uristr)); + + cupsBackendReport("direct", uristr, make_modelstr, make_modelstr, idstr, + NULL); + + release_deviceinfo(&make, &model, &serial); + CFRelease(deviceIDString); + } + } + + return keepRunning; +} + + +/* + * 'find_device_cb()' - print_device iterator callback. + */ + +static Boolean find_device_cb(void *refcon, + io_service_t obj) +{ + Boolean keepLooking = true; + + if (obj != 0x0) + { + CFStringRef idString = NULL; + UInt32 location = -1; + UInt8 interfaceNum = 0; + + copy_devicestring(obj, &idString, &location, &interfaceNum); + if (idString != NULL) + { + CFStringRef make = NULL, model = NULL, serial = NULL; + + copy_deviceinfo(idString, &make, &model, &serial); + if (make && CFStringCompare(make, g.make, kCFCompareCaseInsensitive) == kCFCompareEqualTo) + { + if (model && CFStringCompare(model, g.model, kCFCompareCaseInsensitive) == kCFCompareEqualTo) + { + if (g.serial != NULL && CFStringGetLength(g.serial) > 0) + { + if (serial != NULL && CFStringCompare(serial, g.serial, kCFCompareCaseInsensitive) == kCFCompareEqualTo) + { + IOObjectRetain(obj); + g.printer_obj = obj; + keepLooking = false; + } + } + else + { + if (g.printer_obj != 0) + IOObjectRelease(g.printer_obj); + + g.printer_obj = obj; + IOObjectRetain(obj); + + if (g.location == 0 || g.location == location) + keepLooking = false; + } + if ( !keepLooking ) + g.interfaceNum = interfaceNum; + } + } + + release_deviceinfo(&make, &model, &serial); + CFRelease(idString); + } + } + else + { + keepLooking = (g.printer_obj == 0); + if (obj == 0x0 && keepLooking) + { + CFRunLoopTimerContext context = { 0, refcon, NULL, NULL, NULL }; + CFRunLoopTimerRef timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + 1.0, 10, 0x0, 0x0, status_timer_cb, &context); + if (timer != NULL) + { + CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode); + g.status_timer = timer; + } + } + } + + if (!keepLooking && g.status_timer != NULL) + { + fputs("STATE: -offline-report\n", stderr); + _cupsLangPuts(stderr, _("INFO: Printer is now online.\n")); + CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), g.status_timer, kCFRunLoopDefaultMode); + CFRelease(g.status_timer); + g.status_timer = NULL; + } + + return keepLooking; +} + + +/* + * 'status_timer_cb()' - Status timer callback. + */ + +static void status_timer_cb(CFRunLoopTimerRef timer, + void *info) +{ + fputs("STATE: +offline-report\n", stderr); + _cupsLangPuts(stderr, _("INFO: Printer is offline.\n")); + + 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. + * + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + exit(CUPS_BACKEND_FAILED); + } +} + + +#pragma mark - +/* + * 'copy_deviceinfo()' - Copy strings from the 1284 device ID. + */ + +static void copy_deviceinfo(CFStringRef deviceIDString, + CFStringRef *make, + CFStringRef *model, + CFStringRef *serial) +{ + CFStringRef modelKeys[] = { CFSTR("MDL:"), CFSTR("MODEL:"), NULL }; + CFStringRef makeKeys[] = { CFSTR("MFG:"), CFSTR("MANUFACTURER:"), NULL }; + CFStringRef serialKeys[] = { CFSTR("SN:"), CFSTR("SERN:"), NULL }; + + if (make != NULL) + *make = copy_value_for_key(deviceIDString, makeKeys); + + if (model != NULL) + *model = copy_value_for_key(deviceIDString, modelKeys); + + if (serial != NULL) + *serial = copy_value_for_key(deviceIDString, serialKeys); +} + + +/* + * 'release_deviceinfo()' - Release deviceinfo strings. + */ + +static void release_deviceinfo(CFStringRef *make, + CFStringRef *model, + CFStringRef *serial) +{ + if (make != NULL && *make != NULL) + { + CFRelease(*make); + *make = NULL; + } + + if (model != NULL && *model != NULL) + { + CFRelease(*model); + *model = NULL; + } + + if (serial != NULL && *serial != NULL) + { + CFRelease(*serial); + *serial = NULL; + } +} + + +#pragma mark - +/* + * 'load_classdriver()' - Load a classdriver. + */ + +static kern_return_t load_classdriver(CFStringRef driverPath, + printer_interface_t intf, + classdriver_t ***printerDriver) +{ + kern_return_t kr = kUSBPrinterClassDeviceNotOpen; + classdriver_t **driver = NULL; + CFStringRef bundle = driverPath ? driverPath : kUSBGenericTOPrinterClassDriver; + char bundlestr[1024]; /* Bundle path */ + struct stat bundleinfo; /* File information for bundle */ + CFURLRef url; /* URL for driver */ + CFPlugInRef plugin = NULL; /* Plug-in address */ + + + CFStringGetCString(bundle, bundlestr, sizeof(bundlestr), kCFStringEncodingUTF8); + + /* + * Validate permissions for the class driver... + */ + + if (stat(bundlestr, &bundleinfo)) + { + fprintf(stderr, "DEBUG: Unable to load class driver \"%s\": %s\n", + bundlestr, strerror(errno)); + if (errno == ENOENT) + return (load_classdriver(NULL, intf, printerDriver)); + else + return (kr); + } + else if (bundleinfo.st_mode & S_IWOTH) + { + fprintf(stderr, "DEBUG: Unable to load class driver \"%s\": insecure file " + "permissions (0%o)\n", bundlestr, bundleinfo.st_mode); + return (kr); + } + + /* + * Try loading the class driver... + */ + + url = CFURLCreateWithFileSystemPath(NULL, bundle, kCFURLPOSIXPathStyle, true); + + if (url) + { + plugin = CFPlugInCreate(NULL, url); + CFRelease(url); + } + else + plugin = NULL; + + if (plugin) + { + CFArrayRef factories = CFPlugInFindFactoriesForPlugInTypeInPlugIn(kUSBPrinterClassTypeID, plugin); + if (factories != NULL && CFArrayGetCount(factories) > 0) + { + CFUUIDRef factoryID = CFArrayGetValueAtIndex(factories, 0); + IUnknownVTbl **iunknown = CFPlugInInstanceCreate(NULL, factoryID, kUSBPrinterClassTypeID); + if (iunknown != NULL) + { + kr = (*iunknown)->QueryInterface(iunknown, CFUUIDGetUUIDBytes(kUSBPrinterClassInterfaceID), (LPVOID *)&driver); + if (kr == kIOReturnSuccess && driver != NULL) + { + classdriver_t **genericDriver = NULL; + if (driverPath != NULL && CFStringCompare(driverPath, kUSBGenericTOPrinterClassDriver, 0) != kCFCompareEqualTo) + kr = load_classdriver(NULL, intf, &genericDriver); + + if (kr == kIOReturnSuccess) + { + (*driver)->interface = intf; + (*driver)->Initialize(driver, genericDriver); + + (*driver)->plugin = plugin; + (*driver)->interface = intf; + *printerDriver = driver; + } + } + (*iunknown)->Release(iunknown); + } + CFRelease(factories); + } + } + + fprintf(stderr, "DEBUG: load_classdriver(%s) (kr:0x%08x)\n", bundlestr, (int)kr); + + return (kr); +} + + +/* + * 'unload_classdriver()' - Unload a classdriver. + */ + +static kern_return_t unload_classdriver(classdriver_t ***classdriver) +{ + if (*classdriver != NULL) + { + (**classdriver)->Release(*classdriver); + *classdriver = NULL; + } + + return kIOReturnSuccess; +} + + +/* + * 'load_printerdriver()' - Load vendor's classdriver. + * + * If driverBundlePath is not NULL on return it is the callers responsbility to release it! + */ + +static kern_return_t load_printerdriver(CFStringRef *driverBundlePath) +{ + IOCFPlugInInterface **iodev = NULL; + SInt32 score; + kern_return_t kr; + printer_interface_t intf; + HRESULT res; + + kr = IOCreatePlugInInterfaceForService(g.printer_obj, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score); + if (kr == kIOReturnSuccess) + { + if ((res = (*iodev)->QueryInterface(iodev, USB_INTERFACE_KIND, (LPVOID *) &intf)) == noErr) + { + *driverBundlePath = IORegistryEntryCreateCFProperty(g.printer_obj, kUSBClassDriverProperty, NULL, kNilOptions); + + kr = load_classdriver(*driverBundlePath, intf, &g.classdriver); + + if (kr != kIOReturnSuccess) + (*intf)->Release(intf); + } + IODestroyPlugInInterface(iodev); + } + return kr; +} + + +/* + * 'registry_open()' - Open a connection to the printer. + */ + +static kern_return_t registry_open(CFStringRef *driverBundlePath) +{ + g.bidi_flag = 0; /* 0=unidirectional */ + + kern_return_t kr = load_printerdriver(driverBundlePath); + if (kr != kIOReturnSuccess) + kr = -2; + + if (g.classdriver != NULL) + { + (*g.classdriver)->interfaceNumber = g.interfaceNum; + kr = (*g.classdriver)->Open(g.classdriver, g.location, kUSBPrintingProtocolBidirectional); + if (kr != kIOReturnSuccess || (*g.classdriver)->interface == NULL) + { + kr = (*g.classdriver)->Open(g.classdriver, g.location, kUSBPrintingProtocolUnidirectional); + if (kr == kIOReturnSuccess) + { + if ((*g.classdriver)->interface == NULL) + { + (*g.classdriver)->Close(g.classdriver); + kr = -1; + } + } + } + else + g.bidi_flag = 1; /* 1=bidirectional */ + } + + if (kr != kIOReturnSuccess) + unload_classdriver(&g.classdriver); + + return kr; +} + + +/* + * 'registry_close()' - Close the connection to the printer. + */ + +static kern_return_t registry_close() +{ + if (g.classdriver != NULL) + (*g.classdriver)->Close(g.classdriver); + + unload_classdriver(&g.classdriver); + return kIOReturnSuccess; +} + + +/* + * 'copy_deviceid()' - Copy the 1284 device id string. + */ + +static OSStatus copy_deviceid(classdriver_t **classdriver, + CFStringRef *deviceID) +{ + CFStringRef devID = NULL, + + deviceMake = NULL, + deviceModel = NULL, + deviceSerial = NULL; + + OSStatus err = (*classdriver)->GetDeviceID(classdriver, &devID, DEFAULT_TIMEOUT); + + copy_deviceinfo(devID, &deviceMake, &deviceModel, &deviceSerial); + + if (deviceMake == NULL || deviceModel == NULL || deviceSerial == NULL) + { + IOUSBDeviceDescriptor desc; + iodevice_request_t request; + + request.requestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); + request.request = kUSBRqGetDescriptor; + request.value = (kUSBDeviceDesc << 8) | 0; + request.index = 0; + request.length = sizeof(desc); + request.buffer = &desc; + err = (*classdriver)->DeviceRequest(classdriver, &request, DEFAULT_TIMEOUT); + if (err == kIOReturnSuccess) + { + CFMutableStringRef newDevID = CFStringCreateMutable(NULL, 0); + + if (deviceMake == NULL) + { + CFStringRef data = NULL; + err = (*classdriver)->GetString(classdriver, desc.iManufacturer, kUSBLanguageEnglish, DEFAULT_TIMEOUT, &data); + if (data != NULL) + { + CFStringAppendFormat(newDevID, NULL, CFSTR("MFG:%@;"), data); + CFRelease(data); + } + } + + if (deviceModel == NULL) + { + CFStringRef data = NULL; + err = (*classdriver)->GetString(classdriver, desc.iProduct, kUSBLanguageEnglish, DEFAULT_TIMEOUT, &data); + if (data != NULL) + { + CFStringAppendFormat(newDevID, NULL, CFSTR("MDL:%@;"), data); + CFRelease(data); + } + } + + if (deviceSerial == NULL && desc.iSerialNumber != 0) + { + CFStringRef data = NULL; + err = (*classdriver)->GetString(classdriver, desc.iSerialNumber, kUSBLanguageEnglish, DEFAULT_TIMEOUT, &data); + if (data != NULL) + { + CFStringAppendFormat(newDevID, NULL, CFSTR("SERN:%@;"), data); + CFRelease(data); + } + } + + if (devID != NULL) + { + CFStringAppend(newDevID, devID); + CFRelease(devID); + } + + *deviceID = newDevID; + } + } + else + { + *deviceID = devID; + } + release_deviceinfo(&deviceMake, &deviceModel, &deviceSerial); + + return err; +} + + +/* + * 'copy_devicestring()' - Copy the 1284 device id string. + */ + +static void copy_devicestring(io_service_t usbInterface, + CFStringRef *deviceID, + UInt32 *deviceLocation, + UInt8 *interfaceNumber ) +{ + IOCFPlugInInterface **iodev = NULL; + SInt32 score; + kern_return_t kr; + printer_interface_t intf; + HRESULT res; + classdriver_t **klassDriver = NULL; + CFStringRef driverBundlePath; + + if ((kr = IOCreatePlugInInterfaceForService(usbInterface, + kIOUSBInterfaceUserClientTypeID, + kIOCFPlugInInterfaceID, + &iodev, &score)) == kIOReturnSuccess) + { + if ((res = (*iodev)->QueryInterface(iodev, USB_INTERFACE_KIND, (LPVOID *) + &intf)) == noErr) + { + (*intf)->GetLocationID(intf, deviceLocation); + (*intf)->GetInterfaceNumber(intf, interfaceNumber); + + driverBundlePath = IORegistryEntryCreateCFProperty(usbInterface, + kUSBClassDriverProperty, + NULL, kNilOptions); + + kr = load_classdriver(driverBundlePath, intf, &klassDriver); + + if (kr != kIOReturnSuccess && driverBundlePath != NULL) + kr = load_classdriver(NULL, intf, &klassDriver); + + if (kr == kIOReturnSuccess && klassDriver != NULL) + kr = copy_deviceid(klassDriver, deviceID); + + unload_classdriver(&klassDriver); + + if (driverBundlePath != NULL) + CFRelease(driverBundlePath); + + /* (*intf)->Release(intf); */ + } + IODestroyPlugInInterface(iodev); + } +} + + +#pragma mark - +/* + * 'copy_value_for_key()' - Copy value string associated with a key. + */ + +static CFStringRef copy_value_for_key(CFStringRef deviceID, + CFStringRef *keys) +{ + CFStringRef value = NULL; + CFArrayRef kvPairs = deviceID != NULL ? CFStringCreateArrayBySeparatingStrings(NULL, deviceID, CFSTR(";")) : NULL; + CFIndex max = kvPairs != NULL ? CFArrayGetCount(kvPairs) : 0; + CFIndex idx = 0; + + while (idx < max && value == NULL) + { + CFStringRef kvpair = CFArrayGetValueAtIndex(kvPairs, idx); + CFIndex idxx = 0; + while (keys[idxx] != NULL && value == NULL) + { + CFRange range = CFStringFind(kvpair, keys[idxx], kCFCompareCaseInsensitive); + if (range.length != -1) + { + if (range.location != 0) + { + CFMutableStringRef theString = CFStringCreateMutableCopy(NULL, 0, kvpair); + CFStringTrimWhitespace(theString); + range = CFStringFind(theString, keys[idxx], kCFCompareCaseInsensitive); + if (range.location == 0) + value = CFStringCreateWithSubstring(NULL, theString, CFRangeMake(range.length, CFStringGetLength(theString) - range.length)); + + CFRelease(theString); + } + else + { + CFStringRef theString = CFStringCreateWithSubstring(NULL, kvpair, CFRangeMake(range.length, CFStringGetLength(kvpair) - range.length)); + CFMutableStringRef theString2 = CFStringCreateMutableCopy(NULL, 0, theString); + CFRelease(theString); + + CFStringTrimWhitespace(theString2); + value = theString2; + } + } + idxx++; + } + idx++; + } + + if (kvPairs != NULL) + CFRelease(kvPairs); + return value; +} + + +/* + * 'cfstr_create_trim()' - Create CFString and trim whitespace characters. + */ + +CFStringRef cfstr_create_trim(const char *cstr) +{ + CFStringRef cfstr; + CFMutableStringRef cfmutablestr = NULL; + + if ((cfstr = CFStringCreateWithCString(NULL, cstr, kCFStringEncodingUTF8)) != NULL) + { + if ((cfmutablestr = CFStringCreateMutableCopy(NULL, 1024, cfstr)) != NULL) + CFStringTrimWhitespace(cfmutablestr); + + CFRelease(cfstr); + } + return (CFStringRef) cfmutablestr; +} + + +#pragma mark - +/* + * 'parse_options()' - Parse URI options. + */ + +static void parse_options(char *options, + char *serial, + int serial_size, + UInt32 *location, + Boolean *wait_eof) +{ + char sep, /* Separator character */ + *name, /* Name of option */ + *value; /* Value of option */ + + + if (serial) + *serial = '\0'; + if (location) + *location = 0; + + if (!options) + return; + + while (*options) + { + /* + * Get the name... + */ + + name = options; + + while (*options && *options != '=' && *options != '+' && *options != '&') + options ++; + + if ((sep = *options) != '\0') + *options++ = '\0'; + + if (sep == '=') + { + /* + * Get the value... + */ + + value = options; + + while (*options && *options != '+' && *options != '&') + options ++; + + if (*options) + *options++ = '\0'; + } + else + value = (char *)""; + + /* + * Process the option... + */ + + if (!strcasecmp(name, "waiteof")) + { + if (!strcasecmp(value, "on") || + !strcasecmp(value, "yes") || + !strcasecmp(value, "true")) + *wait_eof = true; + else if (!strcasecmp(value, "off") || + !strcasecmp(value, "no") || + !strcasecmp(value, "false")) + *wait_eof = false; + else + _cupsLangPrintf(stderr, + _("WARNING: Boolean expected for waiteof option " + "\"%s\"\n"), value); + } + else if (!strcasecmp(name, "serial")) + strlcpy(serial, value, serial_size); + else if (!strcasecmp(name, "location") && location) + *location = strtol(value, NULL, 16); + } +} + + +/*! + * @function setup_cfLanguage + * @abstract Convert the contents of the CUPS 'APPLE_LANGUAGE' environment + * variable into a one element CF array of languages. + * + * @discussion Each submitted job comes with a natural language. CUPS passes + * that language in an environment variable. We take that language + * and jam it into the AppleLanguages array so that CF will use + * it when reading localized resources. We need to do this before + * any CF code reads and caches the languages array, so this function + * should be called early in main() + */ +static void setup_cfLanguage(void) +{ + CFStringRef lang[1] = {NULL}; + CFArrayRef langArray = NULL; + const char *requestedLang = NULL; + + if ((requestedLang = getenv("APPLE_LANGUAGE")) == NULL) + requestedLang = getenv("LANG"); + + if (requestedLang != NULL) + { + lang[0] = CFStringCreateWithCString(kCFAllocatorDefault, requestedLang, kCFStringEncodingUTF8); + langArray = CFArrayCreate(kCFAllocatorDefault, (const void **)lang, sizeof(lang) / sizeof(lang[0]), &kCFTypeArrayCallBacks); + + CFPreferencesSetValue(CFSTR("AppleLanguages"), langArray, kCFPreferencesCurrentApplication, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + fprintf(stderr, "DEBUG: usb: AppleLanguages=\"%s\"\n", requestedLang); + + CFRelease(lang[0]); + CFRelease(langArray); + } + else + fputs("DEBUG: usb: LANG and APPLE_LANGUAGE environment variables missing.\n", stderr); +} + +#pragma mark - +#if defined(__i386__) || defined(__x86_64__) +/*! + * @function run_legacy_backend + * + * @abstract Starts child backend process running as a ppc or i386 executable. + * + * @result Never returns; always calls exit(). + * + * @discussion + */ +static void run_legacy_backend(int argc, + char *argv[], + int fd) +{ + int i; + int exitstatus = 0; + int childstatus; + pid_t waitpid_status; + char *my_argv[32]; + char *usb_legacy_status; + + /* + * If we're running as x86_64 or i386 and couldn't load the class driver + * (because it's ppc or i386), then try to re-exec ourselves in ppc or i386 + * mode to try again. If we don't have a ppc or i386 architecture we may be + * running with the same architecture again so guard against this by setting + * and testing an environment variable... + */ + +# ifdef __x86_64__ + usb_legacy_status = getenv("USB_I386_STATUS"); +# else + usb_legacy_status = getenv("USB_PPC_STATUS"); +# endif /* __x86_64__ */ + + if (!usb_legacy_status) + { + /* + * Setup a SIGTERM handler then block it before forking... + */ + + int err; /* posix_spawn result */ + struct sigaction action; /* POSIX signal action */ + sigset_t newmask, /* New signal mask */ + oldmask; /* Old signal mask */ + char usbpath[1024]; /* Path to USB backend */ + const char *cups_serverbin;/* Path to CUPS binaries */ + + + memset(&action, 0, sizeof(action)); + sigaddset(&action.sa_mask, SIGTERM); + action.sa_handler = sigterm_handler; + sigaction(SIGTERM, &action, NULL); + + sigemptyset(&newmask); + sigaddset(&newmask, SIGTERM); + sigprocmask(SIG_BLOCK, &newmask, &oldmask); + + /* + * Set the environment variable... + */ + +# ifdef __x86_64__ + setenv("USB_I386_STATUS", "1", false); +# else + setenv("USB_PPC_STATUS", "1", false); +# endif /* __x86_64__ */ + + /* + * Tell the kernel to use the specified CPU architecture... + */ + +# ifdef __x86_64__ + cpu_type_t cpu = CPU_TYPE_I386; +# else + cpu_type_t cpu = CPU_TYPE_POWERPC; +# endif /* __x86_64__ */ + size_t ocount = 1; + posix_spawnattr_t attrs; + + if (!posix_spawnattr_init(&attrs)) + { + posix_spawnattr_setsigdefault(&attrs, &oldmask); + if (posix_spawnattr_setbinpref_np(&attrs, 1, &cpu, &ocount) || ocount != 1) + { +# ifdef __x86_64__ + perror("DEBUG: Unable to set binary preference to i386"); +# else + perror("DEBUG: Unable to set binary preference to ppc"); +# endif /* __x86_64__ */ + _cupsLangPrintf(stderr, _("Unable to use legacy USB class driver\n")); + exit(CUPS_BACKEND_STOP); + } + } + + /* + * Set up the arguments and call posix_spawn... + */ + + if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL) + cups_serverbin = CUPS_SERVERBIN; + snprintf(usbpath, sizeof(usbpath), "%s/backend/usb", cups_serverbin); + + for (i = 0; i < argc && i < (sizeof(my_argv) / sizeof(my_argv[0])) - 1; i ++) + my_argv[i] = argv[i]; + + my_argv[i] = NULL; + + if ((err = posix_spawn(&child_pid, usbpath, NULL, &attrs, my_argv, + environ)) != 0) + { + fprintf(stderr, "DEBUG: Unable to exec %s: %s\n", usbpath, + strerror(err)); + _cupsLangPrintf(stderr, _("Unable to use legacy USB class driver\n")); + exit(CUPS_BACKEND_STOP); + } + + /* + * Unblock signals... + */ + + sigprocmask(SIG_SETMASK, &oldmask, NULL); + + /* + * Close the fds we won't be using then wait for the child backend to exit. + */ + + close(fd); + close(1); + + fprintf(stderr, "DEBUG: Started usb(legacy) backend (PID %d)\n", + (int)child_pid); + + while ((waitpid_status = waitpid(child_pid, &childstatus, 0)) == (pid_t)-1 && errno == EINTR) + usleep(1000); + + if (WIFSIGNALED(childstatus)) + { + exitstatus = CUPS_BACKEND_STOP; + fprintf(stderr, "DEBUG: usb(legacy) backend %d crashed on signal %d\n", + child_pid, WTERMSIG(childstatus)); + } + else + { + if ((exitstatus = WEXITSTATUS(childstatus)) != 0) + fprintf(stderr, + "DEBUG: usb(legacy) backend %d stopped with status %d\n", + child_pid, exitstatus); + else + fprintf(stderr, "DEBUG: usb(legacy) backend %d exited with no errors\n", + child_pid); + } + } + else + { + fputs("DEBUG: usb(legacy) backend running native again\n", stderr); + exitstatus = CUPS_BACKEND_STOP; + } + + exit(exitstatus); +} +#endif /* __i386__ || __x86_64__ */ + + +/* + * 'sigterm_handler()' - SIGTERM handler. + */ + +static void +sigterm_handler(int sig) /* I - Signal */ +{ +#if defined(__i386__) || defined(__x86_64__) + /* + * If we started a child process pass the signal on to it... + */ + + if (child_pid) + { + /* + * If we started a child process pass the signal on to it... + */ + + int status; + + kill(child_pid, sig); + while (waitpid(child_pid, &status, 0) < 0 && errno == EINTR); + + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + else if (status == SIGTERM || status == SIGKILL) + exit(0); + else + { + fprintf(stderr, "DEBUG: Child crashed on signal %d\n", status); + exit(CUPS_BACKEND_STOP); + } + } +#endif /* __i386__ || __x86_64__ */ +} + + +#ifdef PARSE_PS_ERRORS +/* + * 'next_line()' - Find the next line in a buffer. + */ + +static const char *next_line (const char *buffer) +{ + const char *cptr, *lptr = NULL; + + for (cptr = buffer; *cptr && lptr == NULL; cptr++) + if (*cptr == '\n' || *cptr == '\r') + lptr = cptr; + return lptr; +} + + +/* + * 'parse_pserror()' - Scan the backchannel data for postscript errors. + */ + +static void parse_pserror(char *sockBuffer, + int len) +{ + static char gErrorBuffer[1024] = ""; + static char *gErrorBufferPtr = gErrorBuffer; + static char *gErrorBufferEndPtr = gErrorBuffer + sizeof(gErrorBuffer); + + char *pCommentBegin, *pCommentEnd, *pLineEnd; + char *logLevel; + char logstr[1024]; + int logstrlen; + + if (gErrorBufferPtr + len > gErrorBufferEndPtr - 1) + gErrorBufferPtr = gErrorBuffer; + if (len > sizeof(gErrorBuffer) - 1) + len = sizeof(gErrorBuffer) - 1; + + memcpy(gErrorBufferPtr, (const void *)sockBuffer, len); + gErrorBufferPtr += len; + *(gErrorBufferPtr + 1) = '\0'; + + pLineEnd = (char *)next_line((const char *)gErrorBuffer); + while (pLineEnd != NULL) + { + *pLineEnd++ = '\0'; + + pCommentBegin = strstr(gErrorBuffer,"%%["); + pCommentEnd = strstr(gErrorBuffer, "]%%"); + if (pCommentBegin != gErrorBuffer && pCommentEnd != NULL) + { + pCommentEnd += 3; /* Skip past "]%%" */ + *pCommentEnd = '\0'; /* There's always room for the nul */ + + if (strncasecmp(pCommentBegin, "%%[ Error:", 10) == 0) + logLevel = "DEBUG"; + else if (strncasecmp(pCommentBegin, "%%[ Flushing", 12) == 0) + logLevel = "DEBUG"; + else + logLevel = "INFO"; + + if ((logstrlen = snprintf(logstr, sizeof(logstr), "%s: %s\n", logLevel, pCommentBegin)) >= sizeof(logstr)) + { + /* If the string was trucnated make sure it has a linefeed before the nul */ + logstrlen = sizeof(logstr) - 1; + logstr[logstrlen - 1] = '\n'; + } + write(STDERR_FILENO, logstr, logstrlen); + } + + /* move everything over... */ + strcpy(gErrorBuffer, pLineEnd); + gErrorBufferPtr = gErrorBuffer; + pLineEnd = (char *)next_line((const char *)gErrorBuffer); + } +} +#endif /* PARSE_PS_ERRORS */ + + +/* + * 'soft_reset()' - Send a soft reset to the device. + */ + +static void soft_reset() +{ + fd_set input_set; /* Input set for select() */ + struct timeval stimeout; /* Timeout for select() */ + char buffer[2048]; /* Buffer */ + struct timespec cond_timeout; /* pthread condition timeout */ + + /* + * Send an abort once a second until the I/O lock is released by the main thread... + */ + + pthread_mutex_lock(&g.readwrite_lock_mutex); + while (g.readwrite_lock) + { + (*g.classdriver)->Abort(g.classdriver); + + cond_timeout.tv_sec = time(NULL) + 1; + cond_timeout.tv_nsec = 0; + + pthread_cond_timedwait(&g.readwrite_lock_cond, &g.readwrite_lock_mutex, &cond_timeout); + } + + g.readwrite_lock = 1; + pthread_mutex_unlock(&g.readwrite_lock_mutex); + + /* + * Flush bytes waiting on print_fd... + */ + + g.print_bytes = 0; + + FD_ZERO(&input_set); + FD_SET(g.print_fd, &input_set); + + stimeout.tv_sec = 0; + stimeout.tv_usec = 0; + + while (select(g.print_fd+1, &input_set, NULL, NULL, &stimeout) > 0) + if (read(g.print_fd, buffer, sizeof(buffer)) <= 0) + break; + + /* + * Send the reset... + */ + + (*g.classdriver)->SoftReset(g.classdriver, DEFAULT_TIMEOUT); + + /* + * Release the I/O lock... + */ + + pthread_mutex_lock(&g.readwrite_lock_mutex); + g.readwrite_lock = 0; + pthread_cond_signal(&g.readwrite_lock_cond); + pthread_mutex_unlock(&g.readwrite_lock_mutex); +} + + +/* + * 'get_device_id()' - Return IEEE-1284 device ID. + */ + +static void get_device_id(cups_sc_status_t *status, + char *data, + int *datalen) +{ + CFStringRef deviceIDString = NULL; + + /* GetDeviceID */ + copy_deviceid(g.classdriver, &deviceIDString); + + if (deviceIDString) + { + CFStringGetCString(deviceIDString, data, *datalen, kCFStringEncodingUTF8); + *datalen = strlen(data); + CFRelease(deviceIDString); + } + *status = CUPS_SC_STATUS_OK; +} + + +/* + * End of "$Id$". + */ diff --git a/backend/usb-libusb.c b/backend/usb-libusb.c new file mode 100644 index 0000000000..436f58293e --- /dev/null +++ b/backend/usb-libusb.c @@ -0,0 +1,835 @@ +/* + * "$Id$" + * + * Libusb interface code for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * list_devices() - List the available printers. + * print_device() - Print a file to a USB device. + * close_device() - Close the connection to the USB printer. + * find_device() - Find or enumerate USB printers. + * get_device_id() - Get the IEEE-1284 device ID for the printer. + * list_cb() - List USB printers for discovery. + * make_device_uri() - Create a device URI for a USB printer. + * open_device() - Open a connection to the USB printer. + * print_cb() - Find a USB printer for printing. + * side_cb() - Handle side-channel requests. + */ + +/* + * Include necessary headers... + */ + +#include +#include + + +/* + * Local types... + */ + +typedef struct usb_printer_s /**** USB Printer Data ****/ +{ + struct usb_device *device; /* Device info */ + int conf, /* Configuration */ + iface, /* Interface */ + altset, /* Alternate setting */ + write_endp, /* Write endpoint */ + read_endp; /* Read endpoint */ + struct usb_dev_handle *handle; /* Open handle to device */ +} usb_printer_t; + +typedef int (*usb_cb_t)(usb_printer_t *, const char *, const char *, + const void *); + + +/* + * Local functions... + */ + +static int close_device(usb_printer_t *printer); +static usb_printer_t *find_device(usb_cb_t cb, const void *data); +static int get_device_id(usb_printer_t *printer, char *buffer, + size_t bufsize); +static int list_cb(usb_printer_t *printer, const char *device_uri, + const char *device_id, const void *data); +static char *make_device_uri(usb_printer_t *printer, + const char *device_id, + char *uri, size_t uri_size); +static int open_device(usb_printer_t *printer, int verbose); +static int print_cb(usb_printer_t *printer, const char *device_uri, + const char *device_id, const void *data); +static ssize_t side_cb(usb_printer_t *printer, int print_fd); + + +/* + * 'list_devices()' - List the available printers. + */ + +void +list_devices(void) +{ + fputs("DEBUG: list_devices\n", stderr); + find_device(list_cb, NULL); +} + + +/* + * 'print_device()' - Print a file to a USB device. + */ + +int /* O - Exit status */ +print_device(const char *uri, /* I - Device URI */ + const char *hostname, /* I - Hostname/manufacturer */ + const char *resource, /* I - Resource/modelname */ + char *options, /* I - Device options/serial number */ + int print_fd, /* I - File descriptor to print */ + int copies, /* I - Copies to print */ + int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + usb_printer_t *printer; /* Printer */ + ssize_t bytes, /* Bytes read/written */ + tbytes; /* Total bytes written */ + char buffer[512]; /* Print data buffer */ + struct sigaction action; /* Actions for POSIX signals */ + struct pollfd pfds[2]; /* Poll descriptors */ + + + fputs("DEBUG: print_device\n", stderr); + + /* + * Connect to the printer... + */ + + while ((printer = find_device(print_cb, uri)) == NULL) + { + _cupsLangPuts(stderr, + _("INFO: Waiting for printer to become available...\n")); + sleep(5); + } + + + /* + * If we are printing data from a print driver on stdin, ignore SIGTERM + * so that the driver can finish out any page data, e.g. to eject the + * current page. We only do this for stdin printing as otherwise there + * is no way to cancel a raw print job... + */ + + if (!print_fd) + { + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); + } + + tbytes = 0; + + pfds[0].fd = print_fd; + pfds[0].events = POLLIN; + pfds[1].fd = CUPS_SC_FD; + pfds[1].events = POLLIN; + + while (copies > 0 && tbytes >= 0) + { + copies --; + + if (print_fd != 0) + { + fputs("PAGE: 1 1\n", stderr); + lseek(print_fd, 0, SEEK_SET); + } + + /* + * TODO: Add back-channel support, along with better write error handling. + */ + + while (poll(pfds, 2, -1) > 0) + { + /* + * CUPS STR #3318: USB process hangs on end-of-file, making further + * printing impossible + * + * From a strict interpretation of POSIX poll(), POLLHUP should never be + * set without POLLIN, since POLLIN is the event you request. That said, + * it appears that some versions of Linux break this. + */ + + if (pfds[0].revents & (POLLIN | POLLHUP)) + { + if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0) + { + if (usb_bulk_write(printer->handle, printer->write_endp, buffer, + bytes, 3600000) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to write %d bytes to printer!\n"), + (int)bytes); + tbytes = -1; + break; + } + + tbytes += bytes; + } + else if (bytes == 0 || (bytes < 0 && errno != EAGAIN && errno != EINTR)) + break; + } + + if (pfds[1].revents & (POLLIN | POLLHUP)) + { + if ((bytes = side_cb(printer, print_fd)) < 0) + pfds[1].events = 0; /* Filter has gone away... */ + else + tbytes += bytes; + } + } + } + + /* + * Close our connection and return... + */ + + close_device(printer); + + return (CUPS_BACKEND_OK); +} + + +/* + * 'close_device()' - Close the connection to the USB printer. + */ + +static int /* I - 0 on success, -1 on failure */ +close_device(usb_printer_t *printer) /* I - Printer */ +{ + if (printer->handle) + { + /* + * Release interfaces before closing so that we know all data is written + * to the device... + */ + + int number = printer->device->config[printer->conf]. + interface[printer->iface]. + altsetting[printer->altset].bInterfaceNumber; + usb_release_interface(printer->handle, number); + + if (number != 0) + usb_release_interface(printer->handle, 0); + + /* + * Close the interface and return... + */ + + usb_close(printer->handle); + printer->handle = NULL; + } + + return (0); +} + + +/* + * 'find_device()' - Find or enumerate USB printers. + */ + +static usb_printer_t * /* O - Found printer */ +find_device(usb_cb_t cb, /* I - Callback function */ + const void *data) /* I - User data for callback */ +{ + struct usb_bus *bus; /* Current bus */ + struct usb_device *device; /* Current device */ + struct usb_config_descriptor *confptr;/* Pointer to current configuration */ + struct usb_interface *ifaceptr; /* Pointer to current interface */ + struct usb_interface_descriptor *altptr; + /* Pointer to current alternate setting */ + struct usb_endpoint_descriptor *endpptr; + /* Pointer to current endpoint */ + int conf, /* Current configuration */ + iface, /* Current interface */ + altset, /* Current alternate setting */ + protocol, /* Current protocol */ + endp, /* Current endpoint */ + read_endp, /* Current read endpoint */ + write_endp; /* Current write endpoint */ + char device_id[1024],/* IEEE-1284 device ID */ + device_uri[1024]; + /* Device URI */ + static usb_printer_t printer; /* Current printer */ + + + /* + * Initialize libusb... + */ + + usb_init(); + fprintf(stderr, "DEBUG: usb_find_busses=%d\n", usb_find_busses()); + fprintf(stderr, "DEBUG: usb_find_devices=%d\n", usb_find_devices()); + + /* + * Then loop through the devices it found... + */ + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (device = bus->devices; device; device = device->next) + { + /* + * Ignore devices with no configuration data and anything that is not + * a printer... + */ + + if (!device->config || !device->descriptor.idVendor || + !device->descriptor.idProduct) + continue; + + for (conf = 0, confptr = device->config; + conf < device->descriptor.bNumConfigurations; + conf ++, confptr ++) + for (iface = 0, ifaceptr = confptr->interface; + iface < confptr->bNumInterfaces; + iface ++, ifaceptr ++) + { + /* + * Some printers offer multiple interfaces... + */ + + protocol = 0; + + for (altset = 0, altptr = ifaceptr->altsetting; + altset < ifaceptr->num_altsetting; + altset ++, altptr ++) + { + /* + * Currently we only support unidirectional and bidirectional + * printers. Future versions of this code will support the + * 1284.4 (packet mode) protocol as well. + */ + + if (altptr->bInterfaceClass != USB_CLASS_PRINTER || + altptr->bInterfaceSubClass != 1 || + (altptr->bInterfaceProtocol != 1 && /* Unidirectional */ + altptr->bInterfaceProtocol != 2) || /* Bidirectional */ + altptr->bInterfaceProtocol < protocol) + continue; + + read_endp = -1; + write_endp = -1; + + for (endp = 0, endpptr = altptr->endpoint; + endp < altptr->bNumEndpoints; + endp ++, endpptr ++) + if ((endpptr->bmAttributes & USB_ENDPOINT_TYPE_MASK) == + USB_ENDPOINT_TYPE_BULK) + { + if (endpptr->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + read_endp = endp; + else + write_endp = endp; + } + + if (write_endp >= 0) + { + /* + * Save the best match so far... + */ + + protocol = altptr->bInterfaceProtocol; + printer.altset = altset; + printer.write_endp = write_endp; + printer.read_endp = read_endp; + } + } + + if (protocol > 0) + { + printer.device = device; + printer.conf = conf; + printer.iface = iface; + printer.handle = NULL; + + if (!open_device(&printer, data != NULL)) + { + if (!get_device_id(&printer, device_id, sizeof(device_id))) + { + make_device_uri(&printer, device_id, device_uri, + sizeof(device_uri)); + + if ((*cb)(&printer, device_uri, device_id, data)) + { + printer.read_endp = printer.device->config[printer.conf]. + interface[printer.iface]. + altsetting[printer.altset]. + endpoint[printer.read_endp]. + bEndpointAddress; + printer.write_endp = printer.device->config[printer.conf]. + interface[printer.iface]. + altsetting[printer.altset]. + endpoint[printer.write_endp]. + bEndpointAddress; + return (&printer); + } + } + + close_device(&printer); + } + } + } + } + + /* + * If we get this far without returning, then we haven't found a printer + * to print to... + */ + + return (NULL); +} + + +/* + * 'get_device_id()' - Get the IEEE-1284 device ID for the printer. + */ + +static int /* O - 0 on success, -1 on error */ +get_device_id(usb_printer_t *printer, /* I - Printer */ + char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Number of bytes in buffer */ +{ + int length; /* Length of device ID */ + + + if (usb_control_msg(printer->handle, + USB_TYPE_CLASS | USB_ENDPOINT_IN | USB_RECIP_INTERFACE, + 0, printer->conf, (printer->iface << 8) | printer->altset, + buffer, bufsize, 5000) < 0) + { + *buffer = '\0'; + return (-1); + } + + /* + * Extract the length of the device ID string from the first two + * bytes. The 1284 spec says the length is stored MSB first... + */ + + length = (((unsigned)buffer[0] & 255) << 8) + + ((unsigned)buffer[1] & 255); + + /* + * Check to see if the length is larger than our buffer; first + * assume that the vendor incorrectly implemented the 1284 spec, + * and then limit the length to the size of our buffer... + */ + + if (length > bufsize) + length = (((unsigned)buffer[1] & 255) << 8) + + ((unsigned)buffer[0] & 255); + + if (length > bufsize) + length = bufsize; + + length -= 2; + + /* + * Copy the device ID text to the beginning of the buffer and + * nul-terminate. + */ + + memmove(buffer, buffer + 2, length); + buffer[length] = '\0'; + + return (0); +} + + +/* + * 'list_cb()' - List USB printers for discovery. + */ + +static int /* O - 0 to continue, 1 to stop */ +list_cb(usb_printer_t *printer, /* I - Printer */ + const char *device_uri, /* I - Device URI */ + const char *device_id, /* I - IEEE-1284 device ID */ + const void *data) /* I - User data (not used) */ +{ + char make_model[1024]; /* Make and model */ + + + /* + * Get the device URI and make/model strings... + */ + + backendGetMakeModel(device_id, make_model, sizeof(make_model)); + + /* + * Report the printer... + */ + + cupsBackendReport("direct", device_uri, make_model, make_model, device_id, + NULL); + + /* + * Keep going... + */ + + return (0); +} + + +/* + * 'make_device_uri()' - Create a device URI for a USB printer. + */ + +static char * /* O - Device URI */ +make_device_uri( + usb_printer_t *printer, /* I - Printer */ + const char *device_id, /* I - IEEE-1284 device ID */ + char *uri, /* I - Device URI buffer */ + size_t uri_size) /* I - Size of device URI buffer */ +{ + char options[1024]; /* Device URI options */ + int num_values; /* Number of 1284 parameters */ + cups_option_t *values; /* 1284 parameters */ + const char *mfg, /* Manufacturer */ + *mdl, /* Model */ + *des, /* Description */ + *sern; /* Serial number */ + char tempmfg[256], /* Temporary manufacturer string */ + tempsern[256], /* Temporary serial number string */ + *tempptr; /* Pointer into temp string */ + + + /* + * Get the make, model, and serial numbers... + */ + + num_values = _ppdGet1284Values(device_id, &values); + + if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL) + if ((sern = cupsGetOption("SERN", num_values, values)) == NULL) + if ((sern = cupsGetOption("SN", num_values, values)) == NULL && + printer->device->descriptor.iSerialNumber) + { + /* + * Try getting the serial number from the device itself... + */ + + int length = usb_get_string_simple(printer->handle, + printer->device->descriptor. + iSerialNumber, + tempsern, sizeof(tempsern) - 1); + if (length > 0) + { + tempsern[length] = '\0'; + sern = tempsern; + } + } + + if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL) + mfg = cupsGetOption("MFG", num_values, values); + + if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL) + mdl = cupsGetOption("MDL", num_values, values); + +#ifdef __APPLE__ + /* + * To maintain compatibility with the original IOKit-based backend on Mac OS X, + * don't map manufacturer names... + */ + + if (!mfg) + +#else + /* + * To maintain compatibility with the original character device backend on + * Linux and *BSD, map manufacturer names... + */ + + if (mfg) + { + if (!strcasecmp(mfg, "Hewlett-Packard")) + mfg = "HP"; + else if (!strcasecmp(mfg, "Lexmark International")) + mfg = "Lexmark"; + } + else +#endif /* __APPLE__ */ + { + /* + * No manufacturer? Use the model string or description... + */ + + if (mdl) + _ppdNormalizeMakeAndModel(mdl, tempmfg, sizeof(tempmfg)); + else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL || + (des = cupsGetOption("DES", num_values, values)) != NULL) + _ppdNormalizeMakeAndModel(des, tempmfg, sizeof(tempmfg)); + else + strlcpy(tempmfg, "Unknown", sizeof(tempmfg)); + + if ((tempptr = strchr(tempmfg, ' ')) != NULL) + *tempptr = '\0'; + + mfg = tempmfg; + } + + /* + * Generate the device URI from the manufacturer, model, serial number, + * and interface number... + */ + + if (sern) + { + if (printer->iface > 0) + snprintf(options, sizeof(options), "?serial=%s&interface=%d", sern, + printer->iface); + else + snprintf(options, sizeof(options), "?serial=%s", sern); + } + else if (printer->iface > 0) + snprintf(options, sizeof(options), "?interface=%d", printer->iface); + else + options[0] = '\0'; + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, "usb", NULL, mfg, 0, + "/%s%s", mdl, options); + + cupsFreeOptions(num_values, values); + + return (uri); +} + + +/* + * 'open_device()' - Open a connection to the USB printer. + */ + +static int /* O - 0 on success, -1 on error */ +open_device(usb_printer_t *printer, /* I - Printer */ + int verbose) /* I - Update connecting-to-device state? */ +{ + int number; /* Configuration/interface/altset numbers */ + + + /* + * Return immediately if we are already connected... + */ + + if (printer->handle) + return (0); + + /* + * Try opening the printer... + */ + + if ((printer->handle = usb_open(printer->device)) == NULL) + return (-1); + + /* + * Then set the desired configuration... + */ + + if (verbose) + fputs("STATE: +connecting-to-device\n", stderr); + + number = printer->device->config[printer->conf].bConfigurationValue; + + if (usb_set_configuration(printer->handle, number) < 0) + { + /* + * If the set fails, chances are that the printer only supports a + * single configuration. Technically these printers don't conform to + * the USB printer specification, but otherwise they'll work... + */ + + if (errno != EBUSY) + fprintf(stderr, "DEBUG: Failed to set configuration %d for %04x:%04x\n", + number, printer->device->descriptor.idVendor, + printer->device->descriptor.idProduct); + } + + /* + * Claim interfaces as needed... + */ + + number = printer->device->config[printer->conf].interface[printer->iface]. + altsetting[printer->altset].bInterfaceNumber; + while (usb_claim_interface(printer->handle, number) < 0) + { + if (errno != EBUSY) + fprintf(stderr, "DEBUG: Failed to claim interface %d for %04x:%04x: %s\n", + number, printer->device->descriptor.idVendor, + printer->device->descriptor.idProduct, strerror(errno)); + + goto error; + } + +#if 0 /* STR #3801: Claiming interface 0 causes problems with some printers */ + if (number != 0) + while (usb_claim_interface(printer->handle, 0) < 0) + { + if (errno != EBUSY) + fprintf(stderr, "DEBUG: Failed to claim interface 0 for %04x:%04x: %s\n", + printer->device->descriptor.idVendor, + printer->device->descriptor.idProduct, strerror(errno)); + + goto error; + } +#endif /* 0 */ + + /* + * Set alternate setting... + */ + + number = printer->device->config[printer->conf].interface[printer->iface]. + altsetting[printer->altset].bAlternateSetting; + while (usb_set_altinterface(printer->handle, number) < 0) + { + if (errno != EBUSY) + fprintf(stderr, + "DEBUG: Failed to set alternate interface %d for %04x:%04x: %s\n", + number, printer->device->descriptor.idVendor, + printer->device->descriptor.idProduct, strerror(errno)); + + goto error; + } + + if (verbose) + fputs("STATE: -connecting-to-device\n", stderr); + + return (0); + + /* + * If we get here, there was a hard error... + */ + + error: + + if (verbose) + fputs("STATE: -connecting-to-device\n", stderr); + + usb_close(printer->handle); + printer->handle = NULL; + + return (-1); +} + + +/* + * 'print_cb()' - Find a USB printer for printing. + */ + +static int /* O - 0 to continue, 1 to stop (found) */ +print_cb(usb_printer_t *printer, /* I - Printer */ + const char *device_uri, /* I - Device URI */ + const char *device_id, /* I - IEEE-1284 device ID */ + const void *data) /* I - User data (make, model, S/N) */ +{ + return (!strcmp((char *)data, device_uri)); +} + + +/* + * 'side_cb()' - Handle side-channel requests. + */ + +static ssize_t /* O - Number of bytes written */ +side_cb(usb_printer_t *printer, /* I - Printer */ + int print_fd) /* I - File to print */ +{ + ssize_t bytes, /* Bytes read/written */ + tbytes; /* Total bytes written */ + char buffer[512]; /* Print data buffer */ + struct pollfd pfd; /* Poll descriptor */ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + + tbytes = 0; + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + return (-1); + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + pfd.fd = print_fd; + pfd.events = POLLIN; + + while (poll(&pfd, 1, 1000) > 0) + { + if ((bytes = read(print_fd, buffer, sizeof(buffer))) > 0) + { + while (usb_bulk_write(printer->handle, printer->write_endp, buffer, + bytes, 5000) < 0) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to write %d bytes to printer!\n"), + (int)bytes); + tbytes = -1; + break; + } + + tbytes += bytes; + } + else if (bytes < 0 && errno != EAGAIN && errno != EINTR) + break; + } + + if (tbytes < 0) + status = CUPS_SC_STATUS_IO_ERROR; + else + status = CUPS_SC_STATUS_OK; + + datalen = 0; + break; + + case CUPS_SC_CMD_GET_BIDI : + status = CUPS_SC_STATUS_OK; + data[0] = 0; /* TODO: Change to 1 when read supported */ + datalen = 1; + break; + + case CUPS_SC_CMD_GET_DEVICE_ID : + if (get_device_id(printer, data, sizeof(data))) + { + status = CUPS_SC_STATUS_IO_ERROR; + datalen = 0; + } + else + { + status = CUPS_SC_STATUS_OK; + datalen = strlen(data); + } + break; + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + cupsSideChannelWrite(command, status, data, datalen, 1.0); + + return (tbytes); +} + + +/* + * End of "$Id$". + */ + diff --git a/backend/usb-unix.c b/backend/usb-unix.c new file mode 100644 index 0000000000..d41baca539 --- /dev/null +++ b/backend/usb-unix.c @@ -0,0 +1,631 @@ +/* + * "$Id$" + * + * USB port backend for the Common UNIX Printing System (CUPS). + * + * This file is included from "usb.c" when compiled on UNIX/Linux. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * print_device() - Print a file to a USB device. + * list_devices() - List all USB devices. + * open_device() - Open a USB device... + * side_cb() - Handle side-channel requests... + */ + +/* + * Include necessary headers. + */ + +#include + + +/* + * Local functions... + */ + +static int open_device(const char *uri, int *use_bc); +static int side_cb(int print_fd, int device_fd, int snmp_fd, + http_addr_t *addr, int use_bc); + + +/* + * 'print_device()' - Print a file to a USB device. + */ + +int /* O - Exit status */ +print_device(const char *uri, /* I - Device URI */ + const char *hostname, /* I - Hostname/manufacturer */ + const char *resource, /* I - Resource/modelname */ + char *options, /* I - Device options/serial number */ + int print_fd, /* I - File descriptor to print */ + int copies, /* I - Copies to print */ + int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + int use_bc; /* Use backchannel path? */ + int device_fd; /* USB device */ + size_t tbytes; /* Total number of bytes written */ + struct termios opts; /* Parallel port options */ + + + (void)argc; + (void)argv; + + /* + * Open the USB port device... + */ + + fputs("STATE: +connecting-to-device\n", stderr); + + do + { +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) + /* + * *BSD's ulpt driver currently does not support the + * back-channel, incorrectly returns data ready on a select(), + * and locks up on read()... + */ + + use_bc = 0; + +#elif defined(__sun) + /* + * CUPS STR #3028: Solaris' usbprn driver apparently does not support + * select() or poll(), so we can't support backchannel... + */ + + use_bc = 0; + +#else + /* + * Disable backchannel data when printing to Brother, Canon, or + * Minolta USB printers - apparently these printers will return + * the IEEE-1284 device ID over and over and over when they get + * a read request... + */ + + use_bc = strcasecmp(hostname, "Brother") && + strcasecmp(hostname, "Canon") && + strncasecmp(hostname, "Konica", 6) && + strncasecmp(hostname, "Minolta", 7); +#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */ + + if ((device_fd = open_device(uri, &use_bc)) == -1) + { + 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. + */ + + _cupsLangPuts(stderr, + _("INFO: Unable to contact printer, queuing on next " + "printer in class...\n")); + + /* + * Sleep 5 seconds to keep the job from requeuing too rapidly... + */ + + sleep(5); + + return (CUPS_BACKEND_FAILED); + } + + if (errno == EBUSY) + { + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 10 seconds...\n")); + sleep(10); + } + else if (errno == ENXIO || errno == EIO || errno == ENOENT || + errno == ENODEV) + { + _cupsLangPuts(stderr, + _("INFO: Printer not connected; will retry in 30 " + "seconds...\n")); + sleep(30); + } + else + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open device file \"%s\": %s\n"), + resource, strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + } + } + while (device_fd < 0); + + fputs("STATE: -connecting-to-device\n", stderr); + + /* + * Set any options provided... + */ + + tcgetattr(device_fd, &opts); + + opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ + + /**** No options supported yet ****/ + + tcsetattr(device_fd, TCSANOW, &opts); + + /* + * Finally, send the print file... + */ + + tbytes = 0; + + while (copies > 0 && tbytes >= 0) + { + copies --; + + if (print_fd != 0) + { + fputs("PAGE: 1 1\n", stderr); + lseek(print_fd, 0, SEEK_SET); + } + +#ifdef __sun + /* + * CUPS STR #3028: Solaris' usbprn driver apparently does not support + * select() or poll(), so we can't support the sidechannel either... + */ + + tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, 1, NULL); + +#else + tbytes = backendRunLoop(print_fd, device_fd, -1, NULL, use_bc, 1, side_cb); +#endif /* __sun */ + + if (print_fd != 0 && tbytes >= 0) + _cupsLangPrintf(stderr, +#ifdef HAVE_LONG_LONG + _("INFO: Sent print file, %lld bytes...\n"), +#else + _("INFO: Sent print file, %ld bytes...\n"), +#endif /* HAVE_LONG_LONG */ + CUPS_LLCAST tbytes); + } + + /* + * Close the USB port and return... + */ + + close(device_fd); + + return (tbytes < 0 ? CUPS_BACKEND_FAILED : CUPS_BACKEND_OK); +} + + +/* + * 'list_devices()' - List all USB devices. + */ + +void +list_devices(void) +{ +#ifdef __linux + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255], /* Device filename */ + device_id[1024], /* Device ID string */ + device_uri[1024], /* Device URI string */ + make_model[1024]; /* Make and model */ + + + /* + * Try to open each USB device... + */ + + for (i = 0; i < 16; i ++) + { + /* + * Linux has a long history of changing the standard filenames used + * for USB printer devices. We get the honor of trying them all... + */ + + sprintf(device, "/dev/usblp%d", i); + + if ((fd = open(device, O_RDWR | O_EXCL)) < 0) + { + if (errno != ENOENT) + continue; + + sprintf(device, "/dev/usb/lp%d", i); + + if ((fd = open(device, O_RDWR | O_EXCL)) < 0) + { + if (errno != ENOENT) + continue; + + sprintf(device, "/dev/usb/usblp%d", i); + + if ((fd = open(device, O_RDWR | O_EXCL)) < 0) + continue; + } + } + + if (!backendGetDeviceID(fd, device_id, sizeof(device_id), + make_model, sizeof(make_model), + "usb", device_uri, sizeof(device_uri))) + cupsBackendReport("direct", device_uri, make_model, make_model, + device_id, NULL); + + close(fd); + } +#elif defined(__sgi) +#elif defined(__sun) && defined(ECPPIOC_GETDEVID) + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255], /* Device filename */ + device_id[1024], /* Device ID string */ + device_uri[1024], /* Device URI string */ + make_model[1024]; /* Make and model */ + + + /* + * Open each USB device... + */ + + for (i = 0; i < 8; i ++) + { + sprintf(device, "/dev/usb/printer%d", i); + + if ((fd = open(device, O_WRONLY | O_EXCL)) >= 0) + { + if (!backendGetDeviceID(fd, device_id, sizeof(device_id), + make_model, sizeof(make_model), + "usb", device_uri, sizeof(device_uri))) + cupsBackendReport("direct", device_uri, make_model, make_model, + device_id, NULL); + + close(fd); + } + } +#elif defined(__hpux) +#elif defined(__osf) +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + 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... + */ + +static int /* O - File descriptor or -1 on error */ +open_device(const char *uri, /* I - Device URI */ + int *use_bc) /* O - Set to 0 for unidirectional */ +{ + int fd; /* File descriptor */ + + + /* + * 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)) +#ifdef __linux + { + /* + * Do not allow direct devices anymore... + */ + + errno = ENODEV; + return (-1); + } + else if (!strncmp(uri, "usb://", 6)) + { + /* + * For Linux, try looking up the device serial number or model... + */ + + int i; /* Looping var */ + int busy; /* Are any ports busy? */ + char device[255], /* Device filename */ + device_id[1024], /* Device ID string */ + make_model[1024], /* Make and model */ + device_uri[1024]; /* Device URI string */ + + + /* + * Find the correct USB device... + */ + + for (;;) + { + for (busy = 0, i = 0; i < 16; i ++) + { + /* + * Linux has a long history of changing the standard filenames used + * for USB printer devices. We get the honor of trying them all... + */ + + sprintf(device, "/dev/usblp%d", i); + + if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT) + { + sprintf(device, "/dev/usb/lp%d", i); + + if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT) + { + sprintf(device, "/dev/usb/usblp%d", i); + + if ((fd = open(device, O_RDWR | O_EXCL)) < 0 && errno == ENOENT) + continue; + } + } + + if (fd >= 0) + { + backendGetDeviceID(fd, device_id, sizeof(device_id), + make_model, sizeof(make_model), + "usb", device_uri, sizeof(device_uri)); + } + else + { + /* + * If the open failed because it was busy, flag it so we retry + * as needed... + */ + + if (errno == EBUSY) + busy = 1; + + device_uri[0] = '\0'; + } + + if (!strcmp(uri, device_uri)) + { + /* + * Yes, return this file descriptor... + */ + + fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n", + device); + + return (fd); + } + + /* + * This wasn't the one... + */ + + if (fd >= 0) + close(fd); + } + + /* + * If we get here and at least one of the printer ports showed up + * as "busy", then sleep for a bit and retry... + */ + + if (busy) + _cupsLangPuts(stderr, + _("INFO: Printer busy; will retry in 5 seconds...\n")); + + sleep(5); + } + } +#elif defined(__sun) && defined(ECPPIOC_GETDEVID) + { + /* + * Do not allow direct devices anymore... + */ + + errno = ENODEV; + return (-1); + } + else if (!strncmp(uri, "usb://", 6)) + { + /* + * For Solaris, try looking up the device serial number or model... + */ + + int i; /* Looping var */ + int busy; /* Are any ports busy? */ + char device[255], /* Device filename */ + device_id[1024], /* Device ID string */ + make_model[1024], /* Make and model */ + device_uri[1024]; /* Device URI string */ + + + /* + * Find the correct USB device... + */ + + do + { + for (i = 0, busy = 0; i < 8; i ++) + { + sprintf(device, "/dev/usb/printer%d", i); + + if ((fd = open(device, O_WRONLY | O_EXCL)) >= 0) + backendGetDeviceID(fd, device_id, sizeof(device_id), + make_model, sizeof(make_model), + "usb", device_uri, sizeof(device_uri)); + else + { + /* + * If the open failed because it was busy, flag it so we retry + * as needed... + */ + + if (errno == EBUSY) + busy = 1; + + device_uri[0] = '\0'; + } + + if (!strcmp(uri, device_uri)) + { + /* + * Yes, return this file descriptor... + */ + + fputs("DEBUG: Setting use_bc to 0!\n", stderr); + + *use_bc = 0; + + return (fd); + } + + /* + * This wasn't the one... + */ + + if (fd >= 0) + close(fd); + } + + /* + * If we get here and at least one of the printer ports showed up + * as "busy", then sleep for a bit and retry... + */ + + if (busy) + { + _cupsLangPuts(stderr, + _("INFO: Printer is busy; will retry in 5 seconds...\n")); + sleep(5); + } + } + while (busy); + + /* + * Couldn't find the printer, return "no such device or address"... + */ + + errno = ENODEV; + + return (-1); + } +#else + { + if (*use_bc) + fd = open(uri + 4, O_RDWR | O_EXCL); + else + fd = -1; + + if (fd < 0) + { + fd = open(uri + 4, O_WRONLY | O_EXCL); + *use_bc = 0; + } + + return (fd); + } +#endif /* __linux */ + else + { + errno = ENODEV; + return (-1); + } +} + + +/* + * 'side_cb()' - Handle side-channel requests... + */ + +static int /* O - 0 on success, -1 on error */ +side_cb(int print_fd, /* I - Print file */ + int device_fd, /* I - Device file */ + int snmp_fd, /* I - SNMP socket (unused) */ + http_addr_t *addr, /* I - Device address (unused) */ + int use_bc) /* I - Using back-channel? */ +{ + cups_sc_command_t command; /* Request command */ + cups_sc_status_t status; /* Request/response status */ + char data[2048]; /* Request/response data */ + int datalen; /* Request/response data size */ + + + (void)snmp_fd; + (void)addr; + + datalen = sizeof(data); + + if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0)) + return (-1); + + switch (command) + { + case CUPS_SC_CMD_DRAIN_OUTPUT : + if (backendDrainOutput(print_fd, device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else if (tcdrain(device_fd)) + status = CUPS_SC_STATUS_IO_ERROR; + else + status = CUPS_SC_STATUS_OK; + + datalen = 0; + break; + + case CUPS_SC_CMD_GET_BIDI : + status = CUPS_SC_STATUS_OK; + data[0] = use_bc; + datalen = 1; + break; + + case CUPS_SC_CMD_GET_DEVICE_ID : + memset(data, 0, sizeof(data)); + + if (backendGetDeviceID(device_fd, data, sizeof(data) - 1, + NULL, 0, NULL, NULL, 0)) + { + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + } + else + { + status = CUPS_SC_STATUS_OK; + datalen = strlen(data); + } + break; + + default : + status = CUPS_SC_STATUS_NOT_IMPLEMENTED; + datalen = 0; + break; + } + + return (cupsSideChannelWrite(command, status, data, datalen, 1.0)); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/usb.c b/backend/usb.c new file mode 100644 index 0000000000..bec58bc1a6 --- /dev/null +++ b/backend/usb.c @@ -0,0 +1,265 @@ +/* + * "$Id$" + * + * USB port backend for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * list_devices() - List all available USB devices to stdout. + * print_device() - Print a file to a USB device. + * main() - Send a file to the specified USB port. + */ + +/* + * Include necessary headers. + */ + +#ifdef __APPLE__ + /* A header order dependency requires this be first */ +# include +#endif /* __APPLE__ */ + +#include "backend-private.h" + +#ifdef WIN32 +# include +#else +# include +# include +# include +#endif /* WIN32 */ + + +/* + * Local functions... + */ + +void list_devices(void); +int print_device(const char *uri, const char *hostname, + const char *resource, char *options, + int print_fd, int copies, int argc, char *argv[]); + + +/* + * Include the vendor-specific USB implementation... + */ + +#ifdef HAVE_USB_H +# include "usb-libusb.c" +#elif defined(__APPLE__) +# include "usb-darwin.c" +#elif defined(__linux) || defined(__sun) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +# include "usb-unix.c" +#else +/* + * Use dummy functions that do nothing on unsupported platforms... + * These can be used as templates for implementing USB printing on new + * platforms... + */ + +/* + * 'list_devices()' - List all available USB devices to stdout. + */ + +void +list_devices(void) +{ + /* + * Don't have any devices to list... Use output of the form: + * + * direct usb:/make/model?serial=foo "Make Model" "USB Printer" + * + * Note that "Hewlett Packard" or any other variation MUST be mapped to + * "HP" for compatibility with the PPD and ICC specs. + */ +} + + +/* + * 'print_device()' - Print a file to a USB device. + */ + +int /* O - Exit status */ +print_device(const char *uri, /* I - Device URI */ + const char *hostname, /* I - Hostname/manufacturer */ + const char *resource, /* I - Resource/modelname */ + char *options, /* I - Device options/serial number */ + int print_fd, /* I - File descriptor to print */ + int copies, /* I - Copies to print */ + int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + /* + * Can't print, so just reference the arguments to eliminate compiler + * warnings and return and exit status of 1. Normally you would use the + * arguments to send a file to the printer and return 0 if everything + * worked OK and non-zero if there was an error. + */ + + (void)uri; + (void)hostname; + (void)resource; + (void)options; + (void)print_fd; + (void)copies; + (void)argc; + (void)argv; + + return (CUPS_BACKEND_FAILED); +} +#endif /* __APPLE__ */ + + +/* + * '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 */ +{ + int print_fd; /* Print file */ + int copies; /* Number of copies to print */ + int status; /* Exit status */ + int port; /* Port number (not used) */ + const char *uri; /* Device URI */ + 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 */ +#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); + + /* + * Ignore SIGPIPE signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Check command-line... + */ + + if (argc == 1) + { + list_devices(); + return (CUPS_BACKEND_OK); + } + else if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (CUPS_BACKEND_FAILED); + } + + /* + * Extract the device name and options from the URI... + */ + + uri = cupsBackendDeviceURI(argv); + + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, + method, sizeof(method), username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)) < HTTP_URI_OK) + { + _cupsLangPuts(stderr, + _("ERROR: No device URI found in argv[0] or in DEVICE_URI " + "environment variable!\n")); + return (1); + } + + /* + * 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'; + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + print_fd = 0; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((print_fd = open(argv[6], O_RDONLY)) < 0) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open print file %s - %s\n"), + argv[6], strerror(errno)); + return (CUPS_BACKEND_FAILED); + } + + copies = atoi(argv[4]); + } + + /* + * Finally, send the print file... + */ + + status = print_device(uri, hostname, resource, options, print_fd, copies, + argc, argv); + + /* + * Close the input file and return... + */ + + if (print_fd != 0) + close(print_fd); + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/Dependencies b/berkeley/Dependencies new file mode 100644 index 0000000000..460f6e0b7d --- /dev/null +++ b/berkeley/Dependencies @@ -0,0 +1,16 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +lpc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +lpc.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +lpc.o: ../cups/i18n.h ../cups/transcode.h ../cups/debug.h ../cups/string.h +lpc.o: ../config.h +lpq.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +lpq.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h +lpq.o: ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h +lpq.o: ../cups/debug.h +lpr.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +lpr.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h +lpr.o: ../cups/file.h ../cups/language.h ../cups/i18n.h ../cups/transcode.h +lprm.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +lprm.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +lprm.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h diff --git a/berkeley/Makefile b/berkeley/Makefile new file mode 100644 index 0000000000..fb155ba27a --- /dev/null +++ b/berkeley/Makefile @@ -0,0 +1,167 @@ +# +# "$Id$" +# +# Berkeley commands makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# 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-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + echo Installing Berkeley user printing commands in $(BINDIR)... + $(INSTALL_DIR) -m 755 $(BINDIR) + $(INSTALL_BIN) lpq $(BINDIR) + $(INSTALL_BIN) lpr $(BINDIR) + $(INSTALL_BIN) lprm $(BINDIR) + echo Installing Berkeley admin printing commands in $(BINDIR)... + $(INSTALL_DIR) -m 755 $(SBINDIR) + $(INSTALL_BIN) lpc $(SBINDIR) + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(TARGETS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall all targets... +# + +uninstall: + $(RM) $(BINDIR)/lpq + $(RM) $(BINDIR)/lpr + $(RM) $(BINDIR)/lprm + $(RM) $(SBINDIR)/lpc + -$(RMDIR) $(SBINDIR) + -$(RMDIR) $(BINDIR) + + +# +# 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 0000000000..2ed5d074f5 --- /dev/null +++ b/berkeley/lpc.c @@ -0,0 +1,454 @@ +/* + * "$Id$" + * + * "lpc" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int compare_strings(const char *, const char *, int); +static void do_command(http_t *, const char *, const char *); +static void show_help(const char *); +static void show_status(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 */ +{ + http_t *http; /* Connection to server */ + char line[1024], /* Input line from user */ + *params; /* Pointer to parameters */ + + + _cupsSetLocale(argv); + + /* + * 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... + */ + + _cupsLangPuts(stdout, _("lpc> ")); + while (fgets(line, sizeof(line), stdin) != NULL) + { + /* + * Strip trailing whitespace... + */ + + for (params = line + strlen(line) - 1; params >= line;) + if (!isspace(*params & 255)) + break; + else + *params-- = '\0'; + + /* + * Strip leading whitespace... + */ + + for (params = line; isspace(*params & 255); params ++); + + if (params > line) + _cups_strcpy(line, params); + + if (!line[0]) + { + /* + * Nothing left, just show a prompt... + */ + + _cupsLangPuts(stdout, _("lpc> ")); + continue; + } + + /* + * Find any options in the string... + */ + + for (params = line; *params != '\0'; params ++) + if (isspace(*params & 255)) + break; + + /* + * Remove whitespace between the command and parameters... + */ + + while (isspace(*params & 255)) + *params++ = '\0'; + + /* + * The "quit" and "exit" commands exit; otherwise, process as needed... + */ + + if (!compare_strings(line, "quit", 1) || + !compare_strings(line, "exit", 2)) + break; + + if (*params == '\0') + do_command(http, line, NULL); + else + do_command(http, line, params); + + /* + * Put another prompt out to the user... + */ + + _cupsLangPuts(stdout, _("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(const char *s, /* I - Command-line string */ + const 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 */ + const char *command, /* I - Command string */ + const char *params) /* I - Parameters for command */ +{ + if (!compare_strings(command, "status", 4)) + show_status(http, params); + else if (!compare_strings(command, "help", 1) || !strcmp(command, "?")) + show_help(params); + else + _cupsLangPrintf(stdout, + _("%s is not implemented by the CUPS version of lpc.\n"), + command); +} + + +/* + * 'show_help()' - Show help messages. + */ + +static void +show_help(const char *command) /* I - Command to describe or NULL */ +{ + if (!command) + { + _cupsLangPrintf(stdout, + _("Commands may be abbreviated. Commands are:\n" + "\n" + "exit help quit status ?\n")); + } + else if (!compare_strings(command, "help", 1) || !strcmp(command, "?")) + _cupsLangPrintf(stdout, _("help\t\tget help on commands\n")); + else if (!compare_strings(command, "status", 4)) + _cupsLangPrintf(stdout, _("status\t\tshow status of daemon and queue\n")); + else + _cupsLangPrintf(stdout, _("?Invalid help command unknown\n")); +} + + +/* + * 'show_status()' - Show printers. + */ + +static void +show_status(http_t *http, /* I - HTTP connection to server */ + const char *dests) /* I - Destinations */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + char *printer, /* Printer name */ + *device, /* Device URI */ + *delimiter; /* Char search result */ + ipp_pstate_t pstate; /* Printer state */ + int accepting; /* Is printer accepting jobs? */ + int jobcount; /* Count of current jobs */ + const char *dptr, /* Pointer into destination list */ + *ptr; /* Pointer into printer name */ + int match; /* Non-zero if this job matches */ + static const char *requested[] = /* Requested attributes */ + { + "device-uri", + "printer-is-accepting-jobs", + "printer-name", + "printer-state", + "queued-job-count" + }; + + + DEBUG_printf(("show_status(http=%p, dests=\"%s\")\n", http, dests)); + + if (http == NULL) + return; + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + 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, "/")) != 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, "device-uri") && + attr->value_tag == IPP_TAG_URI) + device = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-is-accepting-jobs") && + attr->value_tag == IPP_TAG_BOOLEAN) + accepting = attr->values[0].boolean; + else if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) + printer = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-state") && + attr->value_tag == IPP_TAG_ENUM) + pstate = (ipp_pstate_t)attr->values[0].integer; + else if (!strcmp(attr->name, "queued-job-count") && + attr->value_tag == IPP_TAG_INTEGER) + jobcount = attr->values[0].integer; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (printer == NULL) + { + if (attr == NULL) + break; + else + continue; + } + + /* + * A single 'all' printer name is special, meaning all printers. + */ + + if (dests != NULL && !strcmp(dests, "all")) + dests = NULL; + + /* + * 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 & 255) || *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 & 255))) + { + match = 1; + break; + } + + /* + * Skip trailing junk... + */ + + while (!isspace(*dptr & 255) && *dptr != '\0') + dptr ++; + while (isspace(*dptr & 255) || *dptr == ',') + dptr ++; + + if (*dptr == '\0') + break; + } + } + + /* + * Display the printer entry if needed... + */ + + if (match) + { + /* + * Display it... + */ + + printf("%s:\n", printer); + if (!strncmp(device, "file:", 5)) + _cupsLangPrintf(stdout, + _("\tprinter is on device \'%s\' speed -1\n"), + device + 5); + else + { + /* + * Just show the scheme... + */ + + if ((delimiter = strchr(device, ':')) != NULL ) + { + *delimiter = '\0'; + _cupsLangPrintf(stdout, + _("\tprinter is on device \'%s\' speed -1\n"), + device); + } + } + + if (accepting) + _cupsLangPuts(stdout, _("\tqueuing is enabled\n")); + else + _cupsLangPuts(stdout, _("\tqueuing is disabled\n")); + + if (pstate != IPP_PRINTER_STOPPED) + _cupsLangPuts(stdout, _("\tprinting is enabled\n")); + else + _cupsLangPuts(stdout, _("\tprinting is disabled\n")); + + if (jobcount == 0) + _cupsLangPuts(stdout, _("\tno entries\n")); + else + _cupsLangPrintf(stdout, _("\t%d entries\n"), jobcount); + + _cupsLangPuts(stdout, _("\tdaemon present\n")); + } + + if (attr == NULL) + break; + } + + ippDelete(response); + } +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/lpq.c b/berkeley/lpq.c new file mode 100644 index 0000000000..6140332b08 --- /dev/null +++ b/berkeley/lpq.c @@ -0,0 +1,686 @@ +/* + * "$Id$" + * + * "lpq" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and commands. + * show_jobs() - Show jobs. + * show_printer() - Show printer status. + * usage() - Show program usage. + */ + +/* + * Include necessary headers... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static http_t *connect_server(const char *, http_t *); +static int show_jobs(const char *, http_t *, const char *, + const char *, const int, const int); +static void show_printer(const char *, http_t *, const char *); +static void usage(void); + + +/* + * '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 */ + *val; /* Environment variable name */ + char *instance; /* Printer instance */ + int id, /* Desired job ID */ + all, /* All printers */ + interval, /* Reporting interval */ + longstatus; /* Show file details */ + int num_dests; /* Number of destinations */ + cups_dest_t *dests; /* Destinations */ + + + _cupsSetLocale(argv); + + /* + * Check for command-line options... + */ + + http = NULL; + dest = NULL; + user = NULL; + id = 0; + interval = 0; + longstatus = 0; + all = 0; + num_dests = 0; + dests = NULL; + + 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_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + + if (http) + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + return (1); + } + + cupsSetUser(argv[i]); + } + break; + + case 'P' : /* Printer */ + if (argv[i][2]) + dest = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + httpClose(http); + cupsFreeDests(num_dests, dests); + + usage(); + } + + dest = argv[i]; + } + + if ((instance = strchr(dest, '/')) != NULL) + *instance++ = '\0'; + + http = connect_server(argv[0], http); + + if (num_dests == 0) + num_dests = cupsGetDests2(http, &dests); + + if (cupsGetDest(dest, instance, num_dests, dests) == NULL) + { + if (instance) + _cupsLangPrintf(stderr, + _("%s: Error - unknown destination \"%s/%s\"!\n"), + argv[0], dest, instance); + else + _cupsLangPrintf(stderr, + _("%s: Unknown destination \"%s\"!\n"), + argv[0], dest); + + return (1); + } + break; + + case 'a' : /* All printers */ + all = 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-h\' option!\n"), + argv[0]); + return (1); + } + else + cupsSetServer(argv[i]); + } + break; + + case 'l' : /* Long status */ + longstatus = 1; + break; + + default : + httpClose(http); + cupsFreeDests(num_dests, dests); + + usage(); + break; + } + } + else if (isdigit(argv[i][0] & 255)) + id = atoi(argv[i]); + else + user = argv[i]; + + http = connect_server(argv[0], http); + + if (dest == NULL && !all) + { + if (num_dests == 0) + num_dests = cupsGetDests2(http, &dests); + + for (i = 0; i < num_dests; i ++) + if (dests[i].is_default) + dest = dests[i].name; + + if (dest == NULL) + { + val = NULL; + + if ((dest = getenv("LPDEST")) == NULL) + { + if ((dest = getenv("PRINTER")) != NULL) + { + if (!strcmp(dest, "lp")) + dest = NULL; + else + val = "PRINTER"; + } + } + else + val = "LPDEST"; + + if (dest && !cupsGetDest(dest, NULL, num_dests, dests)) + _cupsLangPrintf(stderr, + _("%s: error - %s environment variable names " + "non-existent destination \"%s\"!\n"), + argv[0], val, dest); + else + _cupsLangPrintf(stderr, + _("%s: error - no default destination available.\n"), + argv[0]); + httpClose(http); + cupsFreeDests(num_dests, dests); + return (1); + } + } + + /* + * Show the status in a loop... + */ + + for (;;) + { + if (dest) + show_printer(argv[0], http, dest); + + i = show_jobs(argv[0], 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); +} + + +/* + * 'connect_server()' - Connect to the server as necessary... + */ + +static http_t * /* O - New HTTP connection */ +connect_server(const char *command, /* I - Command name */ + http_t *http) /* I - Current HTTP connection */ +{ + if (!http) + { + http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, _("%s: Unable to connect to server\n"), command); + exit(1); + } + } + + return (http); +} + + +/* + * 'show_jobs()' - Show jobs. + */ + +static int /* O - Number of jobs in queue */ +show_jobs(const char *command, /* I - Command name */ + 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 */ + 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 * const jobattrs[] =/* Job attributes we want to see */ + { + "copies", + "job-id", + "job-k-octets", + "job-name", + "job-originating-user-name", + "job-printer-uri", + "job-priority", + "job-state" + }; + static const char * const ranks[10] = /* Ranking strings */ + { + "th", + "st", + "nd", + "rd", + "th", + "th", + "th", + "th", + "th", + "th" + }; + + + DEBUG_printf(("show_jobs(http=%p, dest=%p, user=%p, id=%d, longstatus%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 + * requested-attributes + */ + + request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS); + + if (id) + { + snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d", id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, resource); + } + else if (dest) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, resource, sizeof(resource), "ipp", + NULL, "localhost", 0, "/printers/%s", dest); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, resource); + } + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + + if (user) + { + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); + } + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(jobattrs) / sizeof(jobattrs[0])), NULL, jobattrs); + + /* + * 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) + { + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); + 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") && + attr->value_tag == IPP_TAG_INTEGER) + jobid = attr->values[0].integer; + + if (!strcmp(attr->name, "job-k-octets") && + attr->value_tag == IPP_TAG_INTEGER) + jobsize = attr->values[0].integer; + +#ifdef __osf__ + if (!strcmp(attr->name, "job-priority") && + attr->value_tag == IPP_TAG_INTEGER) + jobpriority = attr->values[0].integer; +#endif /* __osf__ */ + + if (!strcmp(attr->name, "job-state") && + attr->value_tag == IPP_TAG_ENUM) + jobstate = (ipp_jstate_t)attr->values[0].integer; + + if (!strcmp(attr->name, "job-printer-uri") && + attr->value_tag == IPP_TAG_URI) + if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) + jobdest ++; + + if (!strcmp(attr->name, "job-originating-user-name") && + attr->value_tag == IPP_TAG_NAME) + jobuser = attr->values[0].string.text; + + if (!strcmp(attr->name, "job-name") && + attr->value_tag == IPP_TAG_NAME) + jobname = attr->values[0].string.text; + + if (!strcmp(attr->name, "copies") && + 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__ + _cupsLangPuts(stdout, + _("Rank Owner Pri Job Files" + " Total Size\n")); +#else + _cupsLangPuts(stdout, + _("Rank Owner Job File(s)" + " Total Size\n")); +#endif /* __osf__ */ + + jobcount ++; + + /* + * Display the job... + */ + + if (jobstate == IPP_JOB_PROCESSING) + strcpy(rankstr, "active"); + else + { + /* + * Make the rank show the "correct" suffix for each number + * (11-13 are the only special cases, for English anyways...) + */ + + if ((rank % 100) >= 11 && (rank % 100) <= 13) + snprintf(rankstr, sizeof(rankstr), "%dth", rank); + else + snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]); + + rank ++; + } + + if (longstatus) + { + _cupsLangPuts(stdout, "\n"); + + if (jobcopies > 1) + snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies, + jobname); + else + strlcpy(namestr, jobname, sizeof(namestr)); + + _cupsLangPrintf(stdout, _("%s: %-33.33s [job %d localhost]\n"), + jobuser, rankstr, jobid); + _cupsLangPrintf(stdout, _(" %-39.39s %.0f bytes\n"), + namestr, 1024.0 * jobsize); + } + else +#ifdef __osf__ + _cupsLangPrintf(stdout, + _("%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n"), + rankstr, jobuser, jobpriority, jobid, jobname, + 1024.0 * jobsize); +#else + _cupsLangPrintf(stdout, + _("%-7s %-7.7s %-7d %-31.31s %.0f bytes\n"), + rankstr, jobuser, jobid, jobname, 1024.0 * jobsize); +#endif /* __osf */ + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); + return (0); + } + + if (jobcount == 0) + _cupsLangPuts(stdout, _("no entries\n")); + + return (jobcount); +} + + +/* + * 'show_printer()' - Show printer status. + */ + +static void +show_printer(const char *command, /* I - Command name */ + 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 */ + 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 = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/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) + { + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); + 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 : + _cupsLangPrintf(stdout, _("%s is ready\n"), dest); + break; + case IPP_PRINTER_PROCESSING : + _cupsLangPrintf(stdout, _("%s is ready and printing\n"), + dest); + break; + case IPP_PRINTER_STOPPED : + _cupsLangPrintf(stdout, _("%s is not ready\n"), dest); + break; + } + + ippDelete(response); + } + else + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); +} + + +/* + * 'usage()' - Show program usage. + */ + +static void +usage(void) +{ + _cupsLangPuts(stderr, + _("Usage: lpq [-P dest] [-U username] [-h hostname[:port]] " + "[-l] [+interval]\n")); + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/lpr.c b/berkeley/lpr.c new file mode 100644 index 0000000000..5a2a2117cd --- /dev/null +++ b/berkeley/lpr.c @@ -0,0 +1,431 @@ +/* + * "$Id$" + * + * "lpr" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and send files for printing. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + +#include +#include +#include + + +/* + * '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 */ + *val; /* Environment variable name */ + int num_copies; /* Number of copies per file */ + int num_files; /* Number of files to print */ + const char *files[1000]; /* Files to print */ + cups_dest_t *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 */ + + + _cupsSetLocale(argv); + + deletefile = 0; + printer = NULL; + dest = 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_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + return (1); + } + + cupsSetUser(argv[i]); + } + break; + + case 'H' : /* Connect to host */ + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-H\' option!\n"), + argv[0]); + return (1); + } + else + cupsSetServer(argv[i]); + } + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected value after \'-%c\' " + "option!\n"), argv[0], 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 */ + _cupsLangPrintf(stderr, + _("%s: Warning - \'%c\' format modifier not " + "supported - output may not be correct!\n"), + argv[0], ch); + break; + + case 'o' : /* Option */ + if (argv[i][2] != '\0') + num_options = cupsParseOptions(argv[i] + 2, num_options, &options); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: error - expected option=value after " + "\'-o\' option!\n"), + argv[0]); + return (1); + } + + num_options = cupsParseOptions(argv[i], num_options, &options); + } + break; + + case 'l' : /* Literal/raw */ + num_options = cupsAddOption("raw", "true", num_options, &options); + break; + + case 'p' : /* Prettyprint */ + num_options = cupsAddOption("prettyprint", "true", 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 */ + { + char email[1024]; /* EMail address */ + + + snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), + httpGetHostname(NULL, buffer, sizeof(buffer))); + num_options = cupsAddOption("notify-recipient-uri", email, + num_options, &options); + } + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected destination after " + "\'-P\' option!\n"), + argv[0]); + return (1); + } + + printer = argv[i]; + } + + if ((instance = strrchr(printer, '/')) != NULL) + *instance++ = '\0'; + + if ((dest = cupsGetNamedDest(NULL, printer, instance)) != 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected copy count after " + "\'-#\' option!\n"), + argv[0]); + return (1); + } + + num_copies = atoi(argv[i]); + } + + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected name after \'-%c\' " + "option!\n"), argv[0], ch); + return (1); + } + + title = argv[i]; + } + break; + + default : + _cupsLangPrintf(stderr, + _("%s: Error - unknown option \'%c\'!\n"), + argv[0], argv[i][1]); + return (1); + } + else if (num_files < 1000) + { + /* + * Print a file... + */ + + if (access(argv[i], R_OK) != 0) + { + _cupsLangPrintf(stderr, + _("%s: Error - unable to access \"%s\" - %s\n"), + argv[0], argv[i], strerror(errno)); + return (1); + } + + files[num_files] = argv[i]; + num_files ++; + + if (title == NULL) + { + if ((title = strrchr(argv[i], '/')) != NULL) + title ++; + else + title = argv[i]; + } + } + else + _cupsLangPrintf(stderr, + _("%s: Error - too many files - \"%s\"\n"), + argv[0], argv[i]); + /* + * See if we have any files to print; if not, print from stdin... + */ + + if (printer == NULL) + { + if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL) + { + printer = dest->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); + } + } + + if (printer == NULL) + { + val = NULL; + + if ((printer = getenv("LPDEST")) == NULL) + { + if ((printer = getenv("PRINTER")) != NULL) + { + if (!strcmp(printer, "lp")) + printer = NULL; + else + val = "PRINTER"; + } + } + else + val = "LPDEST"; + + if (printer && !cupsGetNamedDest(NULL, printer, NULL)) + _cupsLangPrintf(stderr, + _("%s: Error - %s environment variable names " + "non-existent destination \"%s\"!\n"), + argv[0], val, printer); + else if (cupsLastError() == IPP_NOT_FOUND) + _cupsLangPrintf(stderr, + _("%s: Error - no default destination available.\n"), + argv[0]); + else + _cupsLangPrintf(stderr, + _("%s: Error - scheduler not responding!\n"), + argv[0]); + + return (1); + } + + if (num_files > 0) + { + job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options); + + if (deletefile && job_id > 0) + { + /* + * Delete print files after printing... + */ + + for (i = 0; i < num_files; i ++) + unlink(files[i]); + } + } + else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer, + title ? title : "(stdin)", + num_options, options)) > 0) + { + http_status_t status; /* Write status */ + const char *format; /* Document format */ + ssize_t bytes; /* Bytes read */ + + + if (cupsGetOption("raw", num_options, options)) + format = CUPS_FORMAT_RAW; + else if ((format = cupsGetOption("document-format", num_options, + options)) == NULL) + format = CUPS_FORMAT_AUTO; + + status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL, + format, 1); + + while (status == HTTP_CONTINUE && + (bytes = read(0, buffer, sizeof(buffer))) > 0) + status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes); + + if (status != HTTP_CONTINUE) + { + _cupsLangPrintf(stderr, + _("%s: Error - unable to queue from stdin - %s\n"), + argv[0], httpStatus(status)); + return (1); + } + + if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK) + job_id = 0; + } + + if (job_id < 1) + { + _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/lprm.c b/berkeley/lprm.c new file mode 100644 index 0000000000..d3db6d701a --- /dev/null +++ b/berkeley/lprm.c @@ -0,0 +1,227 @@ +/* + * "$Id$" + * + * "lprm" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and cancel jobs. + */ + +/* + * Include necessary headers... + */ + +#include +#include + +#include +#include +#include + + +/* + * '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 */ +{ + int i; /* Looping var */ + int job_id; /* Job ID */ + const char *name; /* Destination printer */ + char *instance; /* Pointer to instance name */ + cups_dest_t *dest, /* Destination */ + *defdest; /* Default destination */ + int did_cancel; /* Did we cancel something? */ + + + _cupsSetLocale(argv); + + /* + * Setup to cancel individual print jobs... + */ + + did_cancel = 0; + defdest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL); + name = defdest ? defdest->name : NULL; + + /* + * 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_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'P' : /* Cancel jobs on a printer */ + if (argv[i][2]) + name = argv[i] + 2; + else + { + i ++; + name = argv[i]; + } + + if ((instance = strchr(name, '/')) != NULL) + *instance = '\0'; + + if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, name, + NULL)) == NULL) + { + _cupsLangPrintf(stderr, + _("%s: Error - unknown destination \"%s\"!\n"), + argv[0], name); + goto error; + } + + cupsFreeDests(1, dest); + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + goto error; + } + + cupsSetUser(argv[i]); + } + break; + + case 'h' : /* Connect to host */ + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-h\' option!\n"), + argv[0]); + goto error; + } + else + cupsSetServer(argv[i]); + } + + if (defdest) + cupsFreeDests(1, defdest); + + defdest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL); + name = defdest ? defdest->name : NULL; + break; + + default : + _cupsLangPrintf(stderr, + _("%s: Error - unknown option \'%c\'!\n"), + argv[0], argv[i][1]); + goto error; + } + else + { + /* + * Cancel a job or printer... + */ + + if ((dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, argv[i], NULL)) != NULL) + cupsFreeDests(1, dest); + + if (dest) + { + name = argv[i]; + job_id = 0; + } + else if (isdigit(argv[i][0] & 255)) + { + name = NULL; + job_id = atoi(argv[i]); + } + else if (!strcmp(argv[i], "-")) + { + /* + * Cancel all jobs + */ + + job_id = -1; + } + else + { + _cupsLangPrintf(stderr, + _("%s: Error - unknown destination \"%s\"!\n"), + argv[0], argv[i]); + goto error; + } + + if (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0) != IPP_OK) + { + _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); + goto error; + } + + did_cancel = 1; + } + + /* + * If nothing has been canceled yet, cancel the current job on the specified + * (or default) printer... + */ + + if (!did_cancel && cupsCancelJob2(CUPS_HTTP_DEFAULT, name, 0, 0) != IPP_OK) + { + _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); + goto error; + } + + if (defdest) + cupsFreeDests(1, defdest); + + return (0); + + /* + * If we get here there was an error, so clean up... + */ + + error: + + if (defdest) + cupsFreeDests(1, defdest); + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/Dependencies b/cgi-bin/Dependencies new file mode 100644 index 0000000000..f018cd0a0a --- /dev/null +++ b/cgi-bin/Dependencies @@ -0,0 +1,64 @@ +# DO NOT DELETE + +help-index.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +help-index.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +help-index.o: ../cups/file.h ../cups/language.h ../cups/array.h help-index.h +help-index.o: ../cups/debug.h ../cups/i18n.h ../cups/transcode.h +help-index.o: ../cups/string.h ../config.h ../cups/dir.h +html.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +html.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +html.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +html.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +ipp-var.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +ipp-var.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ipp-var.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +ipp-var.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +search.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +search.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +search.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +search.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +template.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +template.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +template.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +template.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +var.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +var.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +var.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +var.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +admin.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +admin.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +admin.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +admin.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +admin.o: ../cups/adminutil.h ../cups/cups.h ../cups/file.h +classes.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +classes.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +classes.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +classes.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +help.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +help.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +help.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +help.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +jobs.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +jobs.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +jobs.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +jobs.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +makedocset.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +makedocset.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +makedocset.o: ../cups/file.h ../cups/language.h ../cups/array.h help-index.h +printers.o: cgi-private.h cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +printers.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +printers.o: ../cups/language.h ../cups/array.h help-index.h ../cups/debug.h +printers.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +testcgi.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testcgi.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +testcgi.o: ../cups/language.h ../cups/array.h help-index.h +testhi.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testhi.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +testhi.o: ../cups/language.h ../cups/array.h help-index.h +testtemplate.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testtemplate.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +testtemplate.o: ../cups/file.h ../cups/language.h ../cups/array.h +testtemplate.o: help-index.h +websearch.o: cgi.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +websearch.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +websearch.o: ../cups/file.h ../cups/language.h ../cups/array.h help-index.h diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile new file mode 100644 index 0000000000..030a448ec3 --- /dev/null +++ b/cgi-bin/Makefile @@ -0,0 +1,382 @@ +# +# "$Id$" +# +# CGI makefile for CUPS. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +LIBOBJS = \ + help-index.o \ + html.o \ + ipp-var.o \ + search.o \ + template.o \ + var.o +OBJS = \ + $(LIBOBJS) \ + admin.o \ + classes.o \ + help.o \ + jobs.o \ + makedocset.o \ + printers.o \ + testcgi.o \ + testhi.o \ + testtemplate.o \ + websearch.o +CGIS = \ + admin.cgi \ + classes.cgi \ + help.cgi \ + jobs.cgi \ + printers.cgi +LIBTARGETS = \ + libcupscgi.a \ + $(LIBCUPSCGI) \ + websearch + +UNITTARGETS = \ + testcgi \ + testhi \ + testtemplate + +TARGETS = \ + $(LIBTARGETS) \ + $(CGIS) + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: $(LIBTARGETS) $(UNITTESTS) + + +# +# Make unit tests... +# + +unittests: $(UNITTARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) $(UNITTARGETS) makedocset + $(RM) libcupscgi.so libcupscgi.sl libcupscgi.dylib + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + $(INSTALL_DIR) -m 755 $(SERVERBIN)/cgi-bin + for file in $(CGIS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/cgi-bin; \ + done + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(CGIS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + echo Installing header files in $(INCLUDEDIR)/cups... + $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups + $(INSTALL_DATA) cgi.h $(INCLUDEDIR)/cups + $(INSTALL_DATA) help-index.h $(INCLUDEDIR)/cups + + +# +# Install libraries... +# + +install-libs: $(INSTALLSTATIC) + echo Installing libraries in $(LIBDIR)... + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) $(LIBCUPSCGI) $(LIBDIR) + if test $(LIBCUPSCGI) = "libcupscgi.so.1" -o $(LIBCUPSCGI) = "libcupscgi.sl.1"; then \ + $(RM) $(LIBDIR)/`basename $(LIBCUPSCGI) .1`; \ + $(LN) $(LIBCUPSCGI) $(LIBDIR)/`basename $(LIBCUPSCGI) .1`; \ + fi + if test $(LIBCUPSCGI) = "libcupscgi.1.dylib"; then \ + $(RM) $(LIBDIR)/libcupscgi.dylib; \ + $(LN) $(LIBCUPSCGI) $(LIBDIR)/libcupscgi.dylib; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(LIBCUPSCGI) $(SYMROOT); \ + fi + +installstatic: + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) -m 755 libcupscgi.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcupscgi.a + $(CHMOD) 555 $(LIBDIR)/libcupscgi.a + + +# +# Uninstall all targets... +# + +uninstall: + for file in $(CGIS); do \ + $(RM) $(SERVERBIN)/cgi-bin/$$file; \ + done + -$(RMDIR) $(SERVERBIN)/cgi-bin + $(RM) $(LIBDIR)/libcupscgi.1.dylib + $(RM) $(LIBDIR)/libcupscgi.a + $(RM) $(LIBDIR)/libcupscgi.dylib + $(RM) $(LIBDIR)/libcupscgi_s.a + $(RM) $(LIBDIR)/libcupscgi.sl + $(RM) $(LIBDIR)/libcupscgi.sl.1 + $(RM) $(LIBDIR)/libcupscgi.so + $(RM) $(LIBDIR)/libcupscgi.so.1 + -$(RMDIR) $(LIBDIR) + $(RM) $(INCLUDEDIR)/cups/cgi.h + $(RM) $(INCLUDEDIR)/cups/help-index.h + -$(RMDIR) $(INCLUDEDIR)/cups + + +# +# Automatic API help files... +# + +apihelp: + mxmldoc --section "Programming" \ + --title "CGI API" \ + --css ../doc/cups-printable.css \ + --header api-cgi.header --intro api-cgi.shtml \ + cgi.h help-index.h $(LIBOBJS:.o=.c) >../doc/help/api-cgi.html + mxmldoc --tokens help/api-cgi.html api-cgi.xml >../doc/help/api-cgi.tokens + $(RM) api-cgi.xml + +framedhelp: + mxmldoc --framed api-cgi \ + --section "Programming" \ + --title "CGI API" \ + --css ../doc/cups-printable.css \ + --header api-cgi.header --intro api-cgi.shtml \ + cgi.h help-index.h $(LIBOBJS:.o=.c) + + +# +# libcupscgi.so.1, libcupscgi.sl.1 +# + +libcupscgi.so.1 libcupscgi.sl.1: $(LIBOBJS) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) + $(RM) `basename $@ .1` + $(LN) $@ `basename $@ .1` + + +# +# libcupscgi.1.dylib +# + +libcupscgi.1.dylib: $(LIBOBJS) libcupscgi.exp + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.0.0 \ + -compatibility_version 1.0.0 \ + -exported_symbols_list libcupscgi.exp \ + $(LIBOBJS) $(LIBS) + $(RM) libcupscgi.dylib + $(LN) $@ libcupscgi.dylib + + +# +# libcupscgi_s.a +# + +libcupscgi_s.a: $(LIBOBJS) + echo Creating $@... + $(DSO) $(DSOFLAGS) -o libcupscgi_s.o $(LIBOBJS) $(LIBS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcupscgi_s.o + + +# +# libcupscgi.la +# + +libcupscgi.la: $(LIBOBJS) + echo Linking $@... + $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \ + -version-info 1:0 $(LIBS) + + +# +# libcupscgi.a +# + +libcupscgi.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# admin.cgi +# + +admin.cgi: admin.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ admin.o -lcupscgi $(LIBS) + + +# +# classes.cgi +# + +classes.cgi: classes.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ classes.o -lcupscgi $(LIBS) + + +# +# help.cgi +# + +help.cgi: help.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ help.o -lcupscgi $(LIBS) + + +# +# jobs.cgi +# + +jobs.cgi: jobs.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ jobs.o -lcupscgi $(LIBS) + + +# +# makedocset +# + +makedocset: makedocset.o ../Makedefs libcupscgi.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ makedocset.o libcupscgi.a \ + ../cups/libcups.a $(COMMONLIBS) $(SSLLIBS) $(DNSSDLIBS) \ + $(LIBZ) $(LIBGSSAPI) + + +# +# printers.cgi +# + +printers.cgi: printers.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSCGI) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ printers.o -L. -lcupscgi $(LIBS) + + +# +# testcgi +# + +testcgi: testcgi.o ../Makedefs libcupscgi.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcgi.o libcupscgi.a \ + ../cups/libcups.a $(COMMONLIBS) $(SSLLIBS) $(DNSSDLIBS) \ + $(LIBZ) $(LIBGSSAPI) + echo Testing CGI API... + ./testcgi + + +# +# testhi +# + +testhi: testhi.o ../Makedefs libcupscgi.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testhi.o libcupscgi.a \ + ../cups/libcups.a $(COMMONLIBS) $(SSLLIBS) $(DNSSDLIBS) \ + $(LIBZ) $(LIBGSSAPI) + echo Testing help index API... + ./testhi + + +# +# testtemplate +# + +testtemplate: testtemplate.o ../Makedefs libcupscgi.a ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testtemplate.o libcupscgi.a ../cups/libcups.a \ + $(COMMONLIBS) $(SSLLIBS) $(DNSSDLIBS) $(LIBZ) $(LIBGSSAPI) + + +# +# websearch +# + +websearch: websearch.o ../Makedefs libcupscgi.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ websearch.o libcupscgi.a \ + ../cups/libcups.a $(COMMONLIBS) $(SSLLIBS) $(DNSSDLIBS) \ + $(LIBZ) $(LIBGSSAPI) + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c new file mode 100644 index 0000000000..ff8642ec18 --- /dev/null +++ b/cgi-bin/admin.c @@ -0,0 +1,4324 @@ +/* + * "$Id$" + * + * Administration CGI for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for CGI. + * choose_device_cb() - Add a device to the device selection page. + * do_add_rss_subscription() - Add a RSS subscription. + * do_am_class() - Add or modify a class. + * do_am_printer() - Add or modify a printer. + * do_cancel_subscription() - Cancel a subscription. + * do_config_server() - Configure server settings. + * do_delete_class() - Delete a class. + * do_delete_printer() - Delete a printer. + * do_export() - Export printers to Samba. + * do_list_printers() - List available printers. + * do_menu() - Show the main menu. + * do_set_allowed_users() - Set the allowed/denied users for a queue. + * do_set_default() - Set the server default printer/class. + * do_set_options() - Configure the default options for a queue. + * do_set_sharing() - Set printer-is-shared value. + * get_option_value() - Return the value of an option. + * get_points() - Get a value in points. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local globals... + */ + +static int current_device = 0; /* Current device shown */ + + +/* + * Local functions... + */ + +static void choose_device_cb(const char *device_class, + const char *device_id, const char *device_info, + const char *device_make_and_model, + const char *device_uri, + const char *device_location, + const char *title); +static void do_add_rss_subscription(http_t *http); +static void do_am_class(http_t *http, int modify); +static void do_am_printer(http_t *http, int modify); +static void do_cancel_subscription(http_t *http); +static void do_config_server(http_t *http); +static void do_delete_class(http_t *http); +static void do_delete_printer(http_t *http); +static void do_export(http_t *http); +static void do_list_printers(http_t *http); +static void do_menu(http_t *http); +static void do_set_allowed_users(http_t *http); +static void do_set_default(http_t *http); +static void do_set_options(http_t *http, int is_class); +static void do_set_sharing(http_t *http); +static char *get_option_value(ppd_file_t *ppd, const char *name, + char *buffer, size_t bufsize); +static double get_points(double number, const char *uval); + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + http_t *http; /* Connection to the server */ + const char *op; /* Operation name */ + + + /* + * Connect to the HTTP server... + */ + + fputs("DEBUG: admin.cgi started...\n", stderr); + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + if (!http) + { + perror("ERROR: Unable to connect to cupsd"); + fprintf(stderr, "DEBUG: cupsServer()=\"%s\"\n", + cupsServer() ? cupsServer() : "(null)"); + fprintf(stderr, "DEBUG: ippPort()=%d\n", ippPort()); + fprintf(stderr, "DEBUG: cupsEncryption()=%d\n", cupsEncryption()); + exit(1); + } + + fprintf(stderr, "DEBUG: http=%p\n", http); + + /* + * Set the web interface section... + */ + + cgiSetVariable("SECTION", "admin"); + cgiSetVariable("REFRESH_PAGE", ""); + + /* + * See if we have form data... + */ + + if (!cgiInitialize() || !cgiGetVariable("OP")) + { + /* + * Nope, send the administration menu... + */ + + fputs("DEBUG: No form data, showing main menu...\n", stderr); + + do_menu(http); + } + else if ((op = cgiGetVariable("OP")) != NULL && cgiIsPOST()) + { + /* + * Do the operation... + */ + + fprintf(stderr, "DEBUG: op=\"%s\"...\n", op); + + if (!*op) + { + const char *printer = getenv("PRINTER_NAME"), + /* Printer or class name */ + *server_port = getenv("SERVER_PORT"); + /* Port number string */ + int port = atoi(server_port ? server_port : "0"); + /* Port number */ + char uri[1024]; /* URL */ + + if (printer) + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), + getenv("HTTPS") ? "https" : "http", NULL, + getenv("SERVER_NAME"), port, "/%s/%s", + cgiGetVariable("IS_CLASS") ? "classes" : "printers", + printer); + else + httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), + getenv("HTTPS") ? "https" : "http", NULL, + getenv("SERVER_NAME"), port, "/admin"); + + printf("Location: %s\n\n", uri); + } + else if (!strcmp(op, "set-allowed-users")) + do_set_allowed_users(http); + else if (!strcmp(op, "set-as-default")) + do_set_default(http); + else if (!strcmp(op, "set-sharing")) + do_set_sharing(http); + else if (!strcmp(op, "find-new-printers") || + !strcmp(op, "list-available-printers")) + do_list_printers(http); + else if (!strcmp(op, "add-class")) + do_am_class(http, 0); + else if (!strcmp(op, "add-printer")) + do_am_printer(http, 0); + else if (!strcmp(op, "modify-class")) + do_am_class(http, 1); + else if (!strcmp(op, "modify-printer")) + do_am_printer(http, 1); + else if (!strcmp(op, "delete-class")) + do_delete_class(http); + else if (!strcmp(op, "delete-printer")) + do_delete_printer(http); + else if (!strcmp(op, "set-class-options")) + do_set_options(http, 1); + else if (!strcmp(op, "set-printer-options")) + do_set_options(http, 0); + else if (!strcmp(op, "config-server")) + do_config_server(http); + else if (!strcmp(op, "export-samba")) + do_export(http); + else if (!strcmp(op, "add-rss-subscription")) + do_add_rss_subscription(http); + else if (!strcmp(op, "cancel-subscription")) + do_cancel_subscription(http); + else + { + /* + * Bad operation code - display an error... + */ + + cgiStartHTML(cgiText(_("Administration"))); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + } + else if (op && !strcmp(op, "redirect")) + { + const char *url; /* Redirection URL... */ + char prefix[1024]; /* URL prefix */ + + + if (getenv("HTTPS")) + snprintf(prefix, sizeof(prefix), "https://%s:%s", + getenv("SERVER_NAME"), getenv("SERVER_PORT")); + else + snprintf(prefix, sizeof(prefix), "http://%s:%s", + getenv("SERVER_NAME"), getenv("SERVER_PORT")); + + fprintf(stderr, "DEBUG: redirecting with prefix %s!\n", prefix); + + if ((url = cgiGetVariable("URL")) != NULL) + { + char encoded[1024], /* Encoded URL string */ + *ptr; /* Pointer into encoded string */ + + + ptr = encoded; + if (*url != '/') + *ptr++ = '/'; + + for (; *url && ptr < (encoded + sizeof(encoded) - 4); url ++) + { + if (strchr("%@&+ <>#=", *url) || *url < ' ' || *url & 128) + { + /* + * Percent-encode this character; safe because we have at least 4 + * bytes left in the array... + */ + + sprintf(ptr, "%%%02X", *url & 255); + ptr += 3; + } + else + *ptr++ = *url; + } + + *ptr = '\0'; + + if (*url) + { + /* + * URL was too long, just redirect to the admin page... + */ + + printf("Location: %s/admin\n\n", prefix); + } + else + { + /* + * URL is OK, redirect there... + */ + + printf("Location: %s%s\n\n", prefix, encoded); + } + } + else + printf("Location: %s/admin\n\n", prefix); + } + else + { + /* + * Form data but no operation code - display an error... + */ + + cgiStartHTML(cgiText(_("Administration"))); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'choose_device_cb()' - Add a device to the device selection page. + */ + +static void +choose_device_cb( + const char *device_class, /* I - Class */ + const char *device_id, /* I - 1284 device ID */ + const char *device_info, /* I - Description */ + const char *device_make_and_model, /* I - Make and model */ + const char *device_uri, /* I - Device URI */ + const char *device_location, /* I - Location */ + const char *title) /* I - Page title */ +{ + /* + * For modern browsers, start a multi-part page so we can show that something + * is happening. Non-modern browsers just get everything at the end... + */ + + if (current_device == 0 && cgiSupportsMultipart()) + { + cgiStartMultipart(); + cgiStartHTML(title); + cgiCopyTemplateLang("choose-device.tmpl"); + cgiEndHTML(); + fflush(stdout); + } + + + /* + * Add the device to the array... + */ + + cgiSetArray("device_class", current_device, device_class); + cgiSetArray("device_id", current_device, device_id); + cgiSetArray("device_info", current_device, device_info); + cgiSetArray("device_make_and_model", current_device, device_make_and_model); + cgiSetArray("device_uri", current_device, device_uri); + cgiSetArray("device_location", current_device, device_location); + + current_device ++; +} + + +/* + * 'do_add_rss_subscription()' - Add a RSS subscription. + */ + +static void +do_add_rss_subscription(http_t *http) /* I - HTTP connection */ +{ + ipp_t *request, /* IPP request data */ + *response; /* IPP response data */ + char rss_uri[1024]; /* RSS notify-recipient URI */ + int num_events; /* Number of events */ + const char *events[12], /* Subscribed events */ + *subscription_name, /* Subscription name */ + *printer_uri, /* Printer URI */ + *ptr, /* Pointer into name */ + *user; /* Username */ + int max_events; /* Maximum number of events */ + + + /* + * See if we have all of the required information... + */ + + subscription_name = cgiGetVariable("SUBSCRIPTION_NAME"); + printer_uri = cgiGetVariable("PRINTER_URI"); + num_events = 0; + + if (cgiGetVariable("EVENT_JOB_CREATED")) + events[num_events ++] = "job-created"; + if (cgiGetVariable("EVENT_JOB_COMPLETED")) + events[num_events ++] = "job-completed"; + if (cgiGetVariable("EVENT_JOB_STOPPED")) + events[num_events ++] = "job-stopped"; + if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED")) + events[num_events ++] = "job-config-changed"; + if (cgiGetVariable("EVENT_PRINTER_STOPPED")) + events[num_events ++] = "printer-stopped"; + if (cgiGetVariable("EVENT_PRINTER_ADDED")) + events[num_events ++] = "printer-added"; + if (cgiGetVariable("EVENT_PRINTER_MODIFIED")) + events[num_events ++] = "printer-modified"; + if (cgiGetVariable("EVENT_PRINTER_DELETED")) + events[num_events ++] = "printer-deleted"; + if (cgiGetVariable("EVENT_SERVER_STARTED")) + events[num_events ++] = "server-started"; + if (cgiGetVariable("EVENT_SERVER_STOPPED")) + events[num_events ++] = "server-stopped"; + if (cgiGetVariable("EVENT_SERVER_RESTARTED")) + events[num_events ++] = "server-restarted"; + if (cgiGetVariable("EVENT_SERVER_AUDIT")) + events[num_events ++] = "server-audit"; + + if ((ptr = cgiGetVariable("MAX_EVENTS")) != NULL) + max_events = atoi(ptr); + else + max_events = 0; + + if (!subscription_name || !printer_uri || !num_events || + max_events <= 0 || max_events > 9999) + { + /* + * Don't have everything we need, so get the available printers + * and classes and (re)show the add page... + */ + + if (cgiGetVariable("EVENT_JOB_CREATED")) + cgiSetVariable("EVENT_JOB_CREATED", "CHECKED"); + if (cgiGetVariable("EVENT_JOB_COMPLETED")) + cgiSetVariable("EVENT_JOB_COMPLETED", "CHECKED"); + if (cgiGetVariable("EVENT_JOB_STOPPED")) + cgiSetVariable("EVENT_JOB_STOPPED", "CHECKED"); + if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED")) + cgiSetVariable("EVENT_JOB_CONFIG_CHANGED", "CHECKED"); + if (cgiGetVariable("EVENT_PRINTER_STOPPED")) + cgiSetVariable("EVENT_PRINTER_STOPPED", "CHECKED"); + if (cgiGetVariable("EVENT_PRINTER_ADDED")) + cgiSetVariable("EVENT_PRINTER_ADDED", "CHECKED"); + if (cgiGetVariable("EVENT_PRINTER_MODIFIED")) + cgiSetVariable("EVENT_PRINTER_MODIFIED", "CHECKED"); + if (cgiGetVariable("EVENT_PRINTER_DELETED")) + cgiSetVariable("EVENT_PRINTER_DELETED", "CHECKED"); + if (cgiGetVariable("EVENT_SERVER_STARTED")) + cgiSetVariable("EVENT_SERVER_STARTED", "CHECKED"); + if (cgiGetVariable("EVENT_SERVER_STOPPED")) + cgiSetVariable("EVENT_SERVER_STOPPED", "CHECKED"); + if (cgiGetVariable("EVENT_SERVER_RESTARTED")) + cgiSetVariable("EVENT_SERVER_RESTARTED", "CHECKED"); + if (cgiGetVariable("EVENT_SERVER_AUDIT")) + cgiSetVariable("EVENT_SERVER_AUDIT", "CHECKED"); + + request = ippNewRequest(CUPS_GET_PRINTERS); + response = cupsDoRequest(http, request, "/"); + + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + ippDelete(response); + + cgiStartHTML(cgiText(_("Add RSS Subscription"))); + + cgiCopyTemplateLang("add-rss-subscription.tmpl"); + + cgiEndHTML(); + return; + } + + /* + * Make sure we have a username... + */ + + if ((user = getenv("REMOTE_USER")) == NULL) + { + puts("Status: 401\n"); + exit(0); + } + + /* + * Validate the subscription name... + */ + + for (ptr = subscription_name; *ptr; ptr ++) + if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || + *ptr == '?' || *ptr == '#') + break; + + if (*ptr) + { + cgiSetVariable("ERROR", + cgiText(_("The subscription name may not " + "contain spaces, slashes (/), question marks (?), " + "or the pound sign (#)."))); + cgiStartHTML(_("Add RSS Subscription")); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Add the subscription... + */ + + ptr = subscription_name + strlen(subscription_name) - 4; + if (ptr < subscription_name || strcmp(ptr, ".rss")) + httpAssembleURIf(HTTP_URI_CODING_ALL, rss_uri, sizeof(rss_uri), "rss", + NULL, NULL, 0, "/%s.rss?max_events=%d", subscription_name, + max_events); + else + httpAssembleURIf(HTTP_URI_CODING_ALL, rss_uri, sizeof(rss_uri), "rss", + NULL, NULL, 0, "/%s?max_events=%d", subscription_name, + max_events); + + request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION); + + if (!strcasecmp(printer_uri, "#ALL#")) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, printer_uri); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, user); + + ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-recipient-uri", NULL, rss_uri); + ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", + num_events, NULL, events); + ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-lease-duration", 0); + + ippDelete(cupsDoRequest(http, request, "/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(_("Add RSS Subscription")); + cgiShowIPPError(_("Unable to add RSS subscription:")); + } + else + { + /* + * Redirect successful updates back to the admin page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin"); + cgiStartHTML(_("Add RSS Subscription")); + cgiCopyTemplateLang("subscription-added.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'do_am_class()' - Add or modify a class. + */ + +static void +do_am_class(http_t *http, /* I - HTTP connection */ + 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 */ + char uri[HTTP_MAX_URI]; /* Device or printer URI */ + const char *name, /* Pointer to class name */ + *op, /* Operation name */ + *ptr; /* Pointer to CGI variable */ + const char *title; /* Title of page */ + static const char * const pattrs[] = /* Requested printer attributes */ + { + "member-names", + "printer-info", + "printer-location" + }; + + + title = cgiText(modify ? _("Modify Class") : _("Add Class")); + op = cgiGetVariable("OP"); + name = cgiGetVariable("PRINTER_NAME"); + + if (cgiGetVariable("PRINTER_LOCATION") == NULL) + { + /* + * Build a CUPS_GET_PRINTERS request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", + CUPS_PRINTER_LOCAL); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", + CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE | + CUPS_PRINTER_IMPLICIT); + + /* + * Do the request and get back a response... + */ + + cgiClearVariables(); + if (op) + cgiSetVariable("OP", op); + if (name) + cgiSetVariable("PRINTER_NAME", name); + + 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")) + { + if ((ptr = strrchr(attr->values[0].string.text, '/')) != NULL && + (!name || strcasecmp(name, ptr + 1))) + { + /* + * Don't show the current class... + */ + + 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")) + { + if (!name || strcasecmp(name, attr->values[0].string.text)) + { + /* + * Don't show the current class... + */ + + cgiSetArray("MEMBER_NAMES", element, attr->values[0].string.text); + element ++; + } + } + + num_printers = cgiGetSize("MEMBER_URIS"); + + ippDelete(response); + } + else + num_printers = 0; + + if (modify) + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", name); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(pattrs) / sizeof(pattrs[0])), + NULL, pattrs); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if ((attr = ippFindAttribute(response, "member-names", + IPP_TAG_NAME)) != 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 (!strcasecmp(attr->values[i].string.text, + cgiGetArray("MEMBER_NAMES", j))) + { + cgiSetArray("MEMBER_SELECTED", j, "SELECTED"); + break; + } + } + } + } + + if ((attr = ippFindAttribute(response, "printer-info", + IPP_TAG_TEXT)) != NULL) + cgiSetVariable("PRINTER_INFO", attr->values[0].string.text); + + if ((attr = ippFindAttribute(response, "printer-location", + IPP_TAG_TEXT)) != NULL) + cgiSetVariable("PRINTER_LOCATION", attr->values[0].string.text); + + ippDelete(response); + } + + /* + * Update the location and description of an existing printer... + */ + + cgiStartHTML(title); + cgiCopyTemplateLang("modify-class.tmpl"); + } + else + { + /* + * Get the name, location, and description for a new printer... + */ + + cgiStartHTML(title); + cgiCopyTemplateLang("add-class.tmpl"); + } + + cgiEndHTML(); + + return; + } + + if (!name) + { + cgiStartHTML(title); + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + for (ptr = name; *ptr; ptr ++) + if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#') + break; + + if (*ptr || ptr == name || strlen(name) > 127) + { + cgiSetVariable("ERROR", + cgiText(_("The class name may only contain up to " + "127 printable characters and may not " + "contain spaces, slashes (/), or the " + "pound sign (#)."))); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * 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 = ippNewRequest(CUPS_ADD_CLASS); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", 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 = _cupsStrAlloc(cgiGetArray("MEMBER_URIS", i)); + } + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(http, request, "/admin/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(title); + cgiShowIPPError(modify ? _("Unable to modify class:") : + _("Unable to add class:")); + } + else + { + /* + * Redirect successful updates back to the class page... + */ + + char refresh[1024]; /* Refresh URL */ + + cgiFormEncode(uri, name, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=/classes/%s", + uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + + if (modify) + cgiCopyTemplateLang("class-modified.tmpl"); + else + cgiCopyTemplateLang("class-added.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'do_am_printer()' - Add or modify a printer. + */ + +static void +do_am_printer(http_t *http, /* I - HTTP connection */ + int modify) /* I - Modify the printer? */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_t *request, /* IPP request */ + *response, /* IPP response */ + *oldinfo; /* Old printer information */ + const cgi_file_t *file; /* Uploaded file, if any */ + 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 */ + const char *name, /* Pointer to class name */ + *ptr; /* Pointer to CGI variable */ + const char *title; /* Title of page */ + static int baudrates[] = /* Baud rates */ + { + 1200, + 2400, + 4800, + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, + 460800 + }; + + + ptr = cgiGetVariable("DEVICE_URI"); + fprintf(stderr, "DEBUG: do_am_printer: DEVICE_URI=\"%s\"\n", + ptr ? ptr : "(null)"); + + title = cgiText(modify ? _("Modify Printer") : _("Add Printer")); + + if (modify) + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/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; + + file = cgiGetFile(); + + if (file) + { + fprintf(stderr, "DEBUG: file->tempfile=%s\n", file->tempfile); + fprintf(stderr, "DEBUG: file->name=%s\n", file->name); + fprintf(stderr, "DEBUG: file->filename=%s\n", file->filename); + fprintf(stderr, "DEBUG: file->mimetype=%s\n", file->mimetype); + } + + if ((name = cgiGetVariable("PRINTER_NAME")) != NULL) + { + for (ptr = name; *ptr; ptr ++) + if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#') + break; + + if (*ptr || ptr == name || strlen(name) > 127) + { + cgiSetVariable("ERROR", + cgiText(_("The printer name may only contain up to " + "127 printable characters and may not " + "contain spaces, slashes (/), or the " + "pound sign (#)."))); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + } + + if ((var = cgiGetVariable("DEVICE_URI")) != NULL) + { + if ((uriptr = strrchr(var, '|')) != NULL) + { + /* + * Extract make and make/model from device URI string... + */ + + char make[1024], /* Make string */ + *makeptr; /* Pointer into make */ + + + *uriptr++ = '\0'; + + strlcpy(make, uriptr, sizeof(make)); + + if ((makeptr = strchr(make, ' ')) != NULL) + *makeptr = '\0'; + else if ((makeptr = strchr(make, '-')) != NULL) + *makeptr = '\0'; + else if (!strncasecmp(make, "laserjet", 8) || + !strncasecmp(make, "deskjet", 7) || + !strncasecmp(make, "designjet", 9)) + strcpy(make, "HP"); + else if (!strncasecmp(make, "phaser", 6)) + strcpy(make, "Xerox"); + else if (!strncasecmp(make, "stylus", 6)) + strcpy(make, "Epson"); + else + strcpy(make, "Generic"); + + if (!cgiGetVariable("CURRENT_MAKE")) + cgiSetVariable("CURRENT_MAKE", make); + + if (!cgiGetVariable("CURRENT_MAKE_AND_MODEL")) + cgiSetVariable("CURRENT_MAKE_AND_MODEL", uriptr); + + if (!modify) + { + char template[128], /* Template name */ + *tptr; /* Pointer into template name */ + + cgiSetVariable("PRINTER_INFO", uriptr); + + for (tptr = template; + tptr < (template + sizeof(template) - 1) && *uriptr; + uriptr ++) + if (isalnum(*uriptr & 255) || *uriptr == '_' || *uriptr == '-' || + *uriptr == '.') + *tptr++ = *uriptr; + else if ((*uriptr == ' ' || *uriptr == '/') && tptr > template && + tptr[-1] != '_') + *tptr++ = '_'; + else if (*uriptr == '?' || *uriptr == '(') + break; + + *tptr = '\0'; + + cgiSetVariable("TEMPLATE_NAME", template); + } + } + } + + if (!var) + { + /* + * Look for devices so the user can pick something... + */ + + if ((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", attr->values[0].string.text); + cgiSetVariable("CURRENT_DEVICE_SCHEME", uri); + } + + /* + * Scan for devices for up to 30 seconds... + */ + + fputs("DEBUG: Getting list of devices...\n", stderr); + + current_device = 0; + if (cupsGetDevices(http, 5, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE, + (cups_device_cb_t)choose_device_cb, + (void *)title) == IPP_OK) + { + fputs("DEBUG: Got device list!\n", stderr); + + if (cgiSupportsMultipart()) + cgiStartMultipart(); + + cgiSetVariable("CUPS_GET_DEVICES_DONE", "1"); + cgiStartHTML(title); + cgiCopyTemplateLang("choose-device.tmpl"); + cgiEndHTML(); + + if (cgiSupportsMultipart()) + cgiEndMultipart(); + } + else + { + fprintf(stderr, + "ERROR: CUPS-Get-Devices request failed with status %x: %s\n", + cupsLastError(), cupsLastErrorString()); + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else + { + cgiStartHTML(title); + cgiShowIPPError(modify ? _("Unable to modify printer:") : + _("Unable to add printer:")); + cgiEndHTML(); + return; + } + } + } + else if (!strchr(var, '/') || + (!strncmp(var, "lpd://", 6) && !strchr(var + 6, '/'))) + { + if ((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("CURRENT_DEVICE_URI", attr->values[0].string.text); + } + + /* + * User needs to set the full URI... + */ + + cgiStartHTML(title); + cgiCopyTemplateLang("choose-uri.tmpl"); + cgiEndHTML(); + } + else if (!strncmp(var, "serial:", 7) && !cgiGetVariable("BAUDRATE")) + { + /* + * 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); + } + + cgiStartHTML(title); + cgiCopyTemplateLang("choose-serial.tmpl"); + cgiEndHTML(); + } + else if (!name || !cgiGetVariable("PRINTER_LOCATION")) + { + cgiStartHTML(title); + + if (modify) + { + /* + * Update the location and description of an existing printer... + */ + + if (oldinfo) + { + if ((attr = ippFindAttribute(oldinfo, "printer-info", + IPP_TAG_TEXT)) != NULL) + cgiSetVariable("PRINTER_INFO", attr->values[0].string.text); + + if ((attr = ippFindAttribute(oldinfo, "printer-location", + IPP_TAG_TEXT)) != NULL) + cgiSetVariable("PRINTER_LOCATION", attr->values[0].string.text); + + if ((attr = ippFindAttribute(oldinfo, "printer-is-shared", + IPP_TAG_BOOLEAN)) != NULL) + cgiSetVariable("PRINTER_IS_SHARED", + attr->values[0].boolean ? "1" : "0"); + } + + cgiCopyTemplateLang("modify-printer.tmpl"); + } + else + { + /* + * Get the name, location, and description for a new printer... + */ + +#ifdef __APPLE__ + if (!strncmp(var, "usb:", 4)) + cgiSetVariable("printer_is_shared", "1"); + else +#endif /* __APPLE__ */ + cgiSetVariable("printer_is_shared", "0"); + + cgiCopyTemplateLang("add-printer.tmpl"); + } + + cgiEndHTML(); + + if (oldinfo) + ippDelete(oldinfo); + + return; + } + else if (!file && + (!cgiGetVariable("PPD_NAME") || cgiGetVariable("SELECT_MAKE"))) + { + if (modify && !cgiGetVariable("SELECT_MAKE")) + { + /* + * 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 */ + http_status_t get_status; /* Status of GET */ + + + /* TODO: Use cupsGetFile() API... */ + snprintf(uri, sizeof(uri), "/printers/%s.ppd", name); + + if (httpGet(http, uri)) + httpGet(http, uri); + + while ((get_status = httpUpdate(http)) == HTTP_CONTINUE); + + if (get_status != HTTP_OK) + { + httpFlush(http); + + fprintf(stderr, "ERROR: Unable to get PPD file %s: %d - %s\n", + uri, get_status, httpStatus(get_status)); + } + else if ((fd = cupsTempFd(filename, sizeof(filename))) >= 0) + { + while ((bytes = httpRead2(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 + { + fprintf(stderr, "ERROR: Unable to open PPD file %s: %s\n", + filename, ppdErrorString(ppdLastError(&bytes))); + } + } + else + { + httpFlush(http); + + fprintf(stderr, + "ERROR: Unable to create temporary file for PPD file: %s\n", + strerror(errno)); + } + } + + /* + * Build a CUPS_GET_PPDS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(CUPS_GET_PPDS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers/"); + + if ((var = cgiGetVariable("PPD_MAKE")) == NULL) + var = cgiGetVariable("CURRENT_MAKE"); + if (var && !cgiGetVariable("SELECT_MAKE")) + { + const char *make_model; /* Make and model */ + + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, + "ppd-make", NULL, var); + + if ((make_model = cgiGetVariable("CURRENT_MAKE_AND_MODEL")) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, + "ppd-make-and-model", NULL, make_model); + } + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "ppd-make"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Got the list of PPDs, see if the user has selected a make... + */ + + if (cgiSetIPPVars(response, NULL, NULL, NULL, 0) == 0 && !modify) + { + /* + * No PPD files with this make, try again with all makes... + */ + + ippDelete(response); + + request = ippNewRequest(CUPS_GET_PPDS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers/"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "ppd-make"); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + cgiStartHTML(title); + cgiCopyTemplateLang("choose-make.tmpl"); + cgiEndHTML(); + } + else if (!var || cgiGetVariable("SELECT_MAKE")) + { + cgiStartHTML(title); + cgiCopyTemplateLang("choose-make.tmpl"); + cgiEndHTML(); + } + else + { + /* + * Let the user choose a model... + */ + + cgiStartHTML(title); + if (!cgiGetVariable("PPD_MAKE")) + cgiSetVariable("PPD_MAKE", cgiGetVariable("CURRENT_MAKE")); + if (!modify) + cgiSetVariable("CURRENT_MAKE_AND_MODEL", + cgiGetArray("PPD_MAKE_AND_MODEL", 0)); + cgiCopyTemplateLang("choose-model.tmpl"); + cgiEndHTML(); + } + + ippDelete(response); + } + else + { + cgiStartHTML(title); + cgiShowIPPError(_("Unable to get list of printer drivers:")); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + } + } + 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-is-shared + * printer-state + */ + + request = ippNewRequest(CUPS_ADD_PRINTER); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/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")); + + if (!file) + { + var = cgiGetVariable("PPD_NAME"); + if (strcmp(var, "__no_change__")) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name", + NULL, var); + } + + strlcpy(uri, cgiGetVariable("DEVICE_URI"), sizeof(uri)); + + /* + * Strip make and model from URI... + */ + + if ((uriptr = strrchr(uri, '|')) != NULL) + *uriptr = '\0'; + + if (!strncmp(uri, "serial:", 7)) + { + /* + * 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); + + var = cgiGetVariable("printer_is_shared"); + ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-shared", + var && (!strcmp(var, "1") || !strcmp(var, "on"))); + + ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", + IPP_PRINTER_IDLE); + + /* + * Do the request and get back a response... + */ + + if (file) + ippDelete(cupsDoFileRequest(http, request, "/admin/", file->tempfile)); + else + ippDelete(cupsDoRequest(http, request, "/admin/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(title); + cgiShowIPPError(modify ? _("Unable to modify printer:") : + _("Unable to add printer:")); + } + else if (modify) + { + /* + * Redirect successful updates back to the printer page... + */ + + char refresh[1024]; /* Refresh URL */ + + + cgiFormEncode(uri, name, sizeof(uri)); + + snprintf(refresh, sizeof(refresh), + "5;/admin/?OP=redirect&URL=/printers/%s", uri); + + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + + cgiCopyTemplateLang("printer-modified.tmpl"); + } + else + { + /* + * Set the printer options... + */ + + cgiSetVariable("OP", "set-printer-options"); + do_set_options(http, 0); + return; + } + + cgiEndHTML(); + } + + if (oldinfo) + ippDelete(oldinfo); +} + + +/* + * 'do_cancel_subscription()' - Cancel a subscription. + */ + +static void +do_cancel_subscription(http_t *http)/* I - HTTP connection */ +{ + ipp_t *request; /* IPP request data */ + const char *var, /* Form variable */ + *user; /* Username */ + int id; /* Subscription ID */ + + + /* + * See if we have all of the required information... + */ + + if ((var = cgiGetVariable("NOTIFY_SUBSCRIPTION_ID")) != NULL) + id = atoi(var); + else + id = 0; + + if (id <= 0) + { + cgiSetVariable("ERROR", cgiText(_("Bad subscription ID!"))); + cgiStartHTML(_("Cancel RSS Subscription")); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Require a username... + */ + + if ((user = getenv("REMOTE_USER")) == NULL) + { + puts("Status: 401\n"); + exit(0); + } + + /* + * Cancel the subscription... + */ + + request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "notify-subscription-id", id); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, user); + + ippDelete(cupsDoRequest(http, request, "/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(_("Cancel RSS Subscription")); + cgiShowIPPError(_("Unable to cancel RSS subscription:")); + } + else + { + /* + * Redirect successful updates back to the admin page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin"); + cgiStartHTML(_("Cancel RSS Subscription")); + cgiCopyTemplateLang("subscription-canceled.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'do_config_server()' - Configure server settings. + */ + +static void +do_config_server(http_t *http) /* I - HTTP connection */ +{ + if (cgiGetVariable("CHANGESETTINGS")) + { + /* + * Save basic setting changes... + */ + + int num_settings; /* Number of server settings */ + cups_option_t *settings; /* Server settings */ + int advanced, /* Advanced settings shown? */ + changed; /* Have settings changed? */ + const char *debug_logging, /* DEBUG_LOGGING value */ + *remote_admin, /* REMOTE_ADMIN value */ + *remote_any, /* REMOTE_ANY value */ + *remote_printers, + /* REMOTE_PRINTERS value */ + *share_printers,/* SHARE_PRINTERS value */ + *user_cancel_any, + /* USER_CANCEL_ANY value */ + *browse_web_if = NULL, + /* BrowseWebIF value */ + *preserve_job_history = NULL, + /* PreserveJobHistory value */ + *preserve_job_files = NULL, + /* PreserveJobFiles value */ + *max_clients = NULL, + /* MaxClients value */ + *max_jobs = NULL, + /* MaxJobs value */ + *max_log_size = NULL; + /* MaxLogSize value */ + char local_protocols[255], + /* BrowseLocalProtocols */ + remote_protocols[255]; + /* BrowseRemoteProtocols */ + const char *current_browse_web_if, + /* BrowseWebIF value */ + *current_preserve_job_history, + /* PreserveJobHistory value */ + *current_preserve_job_files, + /* PreserveJobFiles value */ + *current_max_clients, + /* MaxClients value */ + *current_max_jobs, + /* MaxJobs value */ + *current_max_log_size, + /* MaxLogSize value */ + *current_local_protocols, + /* BrowseLocalProtocols */ + *current_remote_protocols; + /* BrowseRemoteProtocols */ +#ifdef HAVE_GSSAPI + char default_auth_type[255]; + /* DefaultAuthType value */ + const char *val; /* Setting value */ +#endif /* HAVE_GSSAPI */ + + + /* + * Get the checkbox values from the form... + */ + + debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0"; + remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0"; + remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0"; + remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0"; + share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0"; + user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0"; + + advanced = cgiGetVariable("ADVANCEDSETTINGS") != NULL; + if (advanced) + { + /* + * Get advanced settings... + */ + + browse_web_if = cgiGetVariable("BROWSE_WEB_IF") ? "Yes" : "No"; + preserve_job_history = cgiGetVariable("PRESERVE_JOB_HISTORY") ? "Yes" : "No"; + preserve_job_files = cgiGetVariable("PRESERVE_JOB_FILES") ? "Yes" : "No"; + max_clients = cgiGetVariable("MAX_CLIENTS"); + max_jobs = cgiGetVariable("MAX_JOBS"); + max_log_size = cgiGetVariable("MAX_LOG_SIZE"); + + if (!max_clients || atoi(max_clients) <= 0) + max_clients = "100"; + + if (!max_jobs || atoi(max_jobs) <= 0) + max_jobs = "500"; + + if (!max_log_size || atof(max_log_size) <= 0.0) + max_log_size = "1m"; + + if (cgiGetVariable("BROWSE_LOCAL_CUPS")) + strcpy(local_protocols, "cups"); + else + local_protocols[0] = '\0'; + +#ifdef HAVE_DNSSD + if (cgiGetVariable("BROWSE_LOCAL_DNSSD")) + { + if (local_protocols[0]) + strcat(local_protocols, " dnssd"); + else + strcat(local_protocols, "dnssd"); + } +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_LDAP + if (cgiGetVariable("BROWSE_LOCAL_LDAP")) + { + if (local_protocols[0]) + strcat(local_protocols, " ldap"); + else + strcat(local_protocols, "ldap"); + } +#endif /* HAVE_LDAP */ + +#ifdef HAVE_LIBSLP + if (cgiGetVariable("BROWSE_LOCAL_SLP")) + { + if (local_protocols[0]) + strcat(local_protocols, " slp"); + else + strcat(local_protocols, "slp"); + } +#endif /* HAVE_SLP */ + + if (cgiGetVariable("BROWSE_REMOTE_CUPS")) + strcpy(remote_protocols, "cups"); + else + remote_protocols[0] = '\0'; + +#ifdef HAVE_LDAP + if (cgiGetVariable("BROWSE_REMOTE_LDAP")) + { + if (remote_protocols[0]) + strcat(remote_protocols, " ldap"); + else + strcat(remote_protocols, "ldap"); + } +#endif /* HAVE_LDAP */ + +#ifdef HAVE_LIBSLP + if (cgiGetVariable("BROWSE_REMOTE_SLP")) + { + if (remote_protocols[0]) + strcat(remote_protocols, " slp"); + else + strcat(remote_protocols, "slp"); + } +#endif /* HAVE_SLP */ + } + + /* + * Get the current server settings... + */ + + if (!cupsAdminGetServerSettings(http, &num_settings, &settings)) + { + cgiStartHTML(cgiText(_("Change Settings"))); + cgiSetVariable("MESSAGE", + cgiText(_("Unable to change server settings:"))); + cgiSetVariable("ERROR", cupsLastErrorString()); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + +#ifdef HAVE_GSSAPI + /* + * Get authentication settings... + */ + + if (cgiGetVariable("KERBEROS")) + strlcpy(default_auth_type, "Negotiate", sizeof(default_auth_type)); + else + { + val = cupsGetOption("DefaultAuthType", num_settings, settings); + + if (!val || !strcasecmp(val, "Negotiate")) + strlcpy(default_auth_type, "Basic", sizeof(default_auth_type)); + else + strlcpy(default_auth_type, val, sizeof(default_auth_type)); + } + + fprintf(stderr, "DEBUG: DefaultAuthType %s\n", default_auth_type); +#endif /* HAVE_GSSAPI */ + + if ((current_browse_web_if = cupsGetOption("BrowseWebIF", num_settings, + settings)) == NULL) + current_browse_web_if = "No"; + + if ((current_preserve_job_history = cupsGetOption("PreserveJobHistory", + num_settings, + settings)) == NULL) + current_preserve_job_history = "Yes"; + + if ((current_preserve_job_files = cupsGetOption("PreserveJobFiles", + num_settings, + settings)) == NULL) + current_preserve_job_files = "No"; + + if ((current_max_clients = cupsGetOption("MaxClients", num_settings, + settings)) == NULL) + current_max_clients = "100"; + + if ((current_max_jobs = cupsGetOption("MaxJobs", num_settings, + settings)) == NULL) + current_max_jobs = "500"; + + if ((current_max_log_size = cupsGetOption("MaxLogSize", num_settings, + settings)) == NULL) + current_max_log_size = "1m"; + + if ((current_local_protocols = cupsGetOption("BrowseLocalProtocols", + num_settings, + settings)) == NULL) + current_local_protocols = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS; + + if ((current_remote_protocols = cupsGetOption("BrowseRemoteProtocols", + num_settings, + settings)) == NULL) + current_remote_protocols = CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS; + + /* + * See if the settings have changed... + */ + + changed = strcmp(debug_logging, cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, + num_settings, settings)) || + strcmp(remote_admin, cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, + num_settings, settings)) || + strcmp(remote_any, cupsGetOption(CUPS_SERVER_REMOTE_ANY, + num_settings, settings)) || + strcmp(remote_printers, cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, + num_settings, settings)) || + strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, + num_settings, settings)) || +#ifdef HAVE_GSSAPI + !cupsGetOption("DefaultAuthType", num_settings, settings) || + strcmp(default_auth_type, cupsGetOption("DefaultAuthType", + num_settings, settings)) || +#endif /* HAVE_GSSAPI */ + strcmp(user_cancel_any, cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, + num_settings, settings)); + + if (advanced && !changed) + changed = strcasecmp(local_protocols, current_local_protocols) || + strcasecmp(remote_protocols, current_remote_protocols) || + strcasecmp(browse_web_if, current_browse_web_if) || + strcasecmp(preserve_job_history, current_preserve_job_history) || + strcasecmp(preserve_job_files, current_preserve_job_files) || + strcasecmp(max_clients, current_max_clients) || + strcasecmp(max_jobs, current_max_jobs) || + strcasecmp(max_log_size, current_max_log_size); + + if (changed) + { + /* + * Settings *have* changed, so save the changes... + */ + + cupsFreeOptions(num_settings, settings); + + num_settings = 0; + num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, + debug_logging, num_settings, &settings); + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, + remote_admin, num_settings, &settings); + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, + remote_any, num_settings, &settings); + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, + remote_printers, num_settings, &settings); + num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, + share_printers, num_settings, &settings); + num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, + user_cancel_any, num_settings, &settings); +#ifdef HAVE_GSSAPI + num_settings = cupsAddOption("DefaultAuthType", default_auth_type, + num_settings, &settings); +#endif /* HAVE_GSSAPI */ + + if (advanced) + { + /* + * Add advanced settings... + */ + + if (strcasecmp(local_protocols, current_local_protocols)) + num_settings = cupsAddOption("BrowseLocalProtocols", local_protocols, + num_settings, &settings); + if (strcasecmp(remote_protocols, current_remote_protocols)) + num_settings = cupsAddOption("BrowseRemoteProtocols", remote_protocols, + num_settings, &settings); + if (strcasecmp(browse_web_if, current_browse_web_if)) + num_settings = cupsAddOption("BrowseWebIF", browse_web_if, + num_settings, &settings); + if (strcasecmp(preserve_job_history, current_preserve_job_history)) + num_settings = cupsAddOption("PreserveJobHistory", + preserve_job_history, num_settings, + &settings); + if (strcasecmp(preserve_job_files, current_preserve_job_files)) + num_settings = cupsAddOption("PreserveJobFiles", preserve_job_files, + num_settings, &settings); + if (strcasecmp(max_clients, current_max_clients)) + num_settings = cupsAddOption("MaxClients", max_clients, num_settings, + &settings); + if (strcasecmp(max_jobs, current_max_jobs)) + num_settings = cupsAddOption("MaxJobs", max_jobs, num_settings, + &settings); + if (strcasecmp(max_log_size, current_max_log_size)) + num_settings = cupsAddOption("MaxLogSize", max_log_size, num_settings, + &settings); + } + + if (!cupsAdminSetServerSettings(http, num_settings, settings)) + { + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + + cgiStartHTML(cgiText(_("Change Settings"))); + cgiSetVariable("MESSAGE", + cgiText(_("Unable to change server settings:"))); + cgiSetVariable("ERROR", cupsLastErrorString()); + cgiCopyTemplateLang("error.tmpl"); + } + else + { + if (advanced) + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/admin/?ADVANCEDSETTINGS=YES"); + else + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect"); + cgiStartHTML(cgiText(_("Change Settings"))); + cgiCopyTemplateLang("restart.tmpl"); + } + } + else + { + /* + * No changes... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect"); + cgiStartHTML(cgiText(_("Change Settings"))); + cgiCopyTemplateLang("norestart.tmpl"); + } + + cupsFreeOptions(num_settings, settings); + + cgiEndHTML(); + } + else if (cgiGetVariable("SAVECHANGES") && cgiGetVariable("CUPSDCONF")) + { + /* + * Save hand-edited config file... + */ + + http_status_t status; /* PUT status */ + char tempfile[1024]; /* Temporary new cupsd.conf */ + int tempfd; /* Temporary file descriptor */ + cups_file_t *temp; /* Temporary file */ + const char *start, /* Start of line */ + *end; /* End of line */ + + + /* + * Create a temporary file for the new cupsd.conf file... + */ + + if ((tempfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) + { + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file:"))); + cgiSetVariable("ERROR", strerror(errno)); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + perror(tempfile); + return; + } + + if ((temp = cupsFileOpenFd(tempfd, "w")) == NULL) + { + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file:"))); + cgiSetVariable("ERROR", strerror(errno)); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + perror(tempfile); + close(tempfd); + unlink(tempfile); + return; + } + + /* + * Copy the cupsd.conf text from the form variable... + */ + + start = cgiGetVariable("CUPSDCONF"); + while (start) + { + if ((end = strstr(start, "\r\n")) == NULL) + if ((end = strstr(start, "\n")) == NULL) + end = start + strlen(start); + + cupsFileWrite(temp, start, end - start); + cupsFilePutChar(temp, '\n'); + + if (*end == '\r') + start = end + 2; + else if (*end == '\n') + start = end + 1; + else + start = NULL; + } + + cupsFileClose(temp); + + /* + * Upload the configuration file to the server... + */ + + status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile); + + if (status == HTTP_UNAUTHORIZED) + { + puts("Status: 401\n"); + unlink(tempfile); + exit(0); + } + else if (status != HTTP_CREATED) + { + cgiSetVariable("MESSAGE", + cgiText(_("Unable to upload cupsd.conf file:"))); + cgiSetVariable("ERROR", httpStatus(status)); + + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiCopyTemplateLang("error.tmpl"); + } + else + { + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect"); + + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiCopyTemplateLang("restart.tmpl"); + } + + cgiEndHTML(); + + unlink(tempfile); + } + else + { + struct stat info; /* cupsd.conf information */ + cups_file_t *cupsd; /* cupsd.conf file */ + char *buffer, /* Buffer for entire file */ + *bufptr, /* Pointer into buffer */ + *bufend; /* End of buffer */ + int ch; /* Character from file */ + char filename[1024]; /* Filename */ + const char *server_root; /* Location of config files */ + + + /* + * Locate the cupsd.conf file... + */ + + if ((server_root = getenv("CUPS_SERVERROOT")) == NULL) + server_root = CUPS_SERVERROOT; + + snprintf(filename, sizeof(filename), "%s/cupsd.conf", server_root); + + /* + * Figure out the size... + */ + + if (stat(filename, &info)) + { + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiSetVariable("MESSAGE", + cgiText(_("Unable to access cupsd.conf file:"))); + cgiSetVariable("ERROR", strerror(errno)); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + perror(filename); + return; + } + + if (info.st_size > (1024 * 1024)) + { + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiSetVariable("MESSAGE", + cgiText(_("Unable to access cupsd.conf file:"))); + cgiSetVariable("ERROR", + cgiText(_("Unable to edit cupsd.conf files larger than " + "1MB!"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + fprintf(stderr, "ERROR: \"%s\" too large (%ld) to edit!\n", filename, + (long)info.st_size); + return; + } + + /* + * Open the cupsd.conf file... + */ + + if ((cupsd = cupsFileOpen(filename, "r")) == NULL) + { + /* + * Unable to open - log an error... + */ + + cgiStartHTML(cgiText(_("Edit Configuration File"))); + cgiSetVariable("MESSAGE", + cgiText(_("Unable to access cupsd.conf file:"))); + cgiSetVariable("ERROR", strerror(errno)); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + perror(filename); + return; + } + + /* + * Allocate memory and load the file into a string buffer... + */ + + if ((buffer = calloc(1, info.st_size + 1)) != NULL) + { + cupsFileRead(cupsd, buffer, info.st_size); + cgiSetVariable("CUPSDCONF", buffer); + free(buffer); + } + + cupsFileClose(cupsd); + + /* + * Then get the default cupsd.conf file and put that into a string as + * well... + */ + + strlcat(filename, ".default", sizeof(filename)); + + if (!stat(filename, &info) && info.st_size < (1024 * 1024) && + (cupsd = cupsFileOpen(filename, "r")) != NULL) + { + if ((buffer = calloc(1, 2 * info.st_size + 1)) != NULL) + { + bufend = buffer + 2 * info.st_size - 1; + + for (bufptr = buffer; + bufptr < bufend && (ch = cupsFileGetChar(cupsd)) != EOF;) + { + if (ch == '\\' || ch == '\"') + { + *bufptr++ = '\\'; + *bufptr++ = ch; + } + else if (ch == '\n') + { + *bufptr++ = '\\'; + *bufptr++ = 'n'; + } + else if (ch == '\t') + { + *bufptr++ = '\\'; + *bufptr++ = 't'; + } + else if (ch >= ' ') + *bufptr++ = ch; + } + + *bufptr = '\0'; + + cgiSetVariable("CUPSDCONF_DEFAULT", buffer); + free(buffer); + } + + cupsFileClose(cupsd); + } + + /* + * Show the current config file... + */ + + cgiStartHTML(cgiText(_("Edit Configuration File"))); + + cgiCopyTemplateLang("edit-config.tmpl"); + + cgiEndHTML(); + } +} + + +/* + * 'do_delete_class()' - Delete a class. + */ + +static void +do_delete_class(http_t *http) /* I - HTTP connection */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *pclass; /* Printer class name */ + + + /* + * Get form variables... + */ + + if (cgiGetVariable("CONFIRM") == NULL) + { + cgiStartHTML(cgiText(_("Delete Class"))); + cgiCopyTemplateLang("class-confirm.tmpl"); + cgiEndHTML(); + return; + } + + if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL) + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", pclass); + else + { + cgiStartHTML(cgiText(_("Delete Class"))); + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Build a CUPS_DELETE_CLASS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(CUPS_DELETE_CLASS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(http, request, "/admin/")); + + /* + * Show the results... + */ + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() <= IPP_OK_CONFLICT) + { + /* + * Redirect successful updates back to the classes page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/classes"); + } + + cgiStartHTML(cgiText(_("Delete Class"))); + + if (cupsLastError() > IPP_OK_CONFLICT) + cgiShowIPPError(_("Unable to delete class:")); + else + cgiCopyTemplateLang("class-deleted.tmpl"); + + cgiEndHTML(); +} + + +/* + * 'do_delete_printer()' - Delete a printer. + */ + +static void +do_delete_printer(http_t *http) /* I - HTTP connection */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *printer; /* Printer printer name */ + + + /* + * Get form variables... + */ + + if (cgiGetVariable("CONFIRM") == NULL) + { + cgiStartHTML(cgiText(_("Delete Printer"))); + cgiCopyTemplateLang("printer-confirm.tmpl"); + cgiEndHTML(); + return; + } + + if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL) + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + else + { + cgiStartHTML(cgiText(_("Delete Printer"))); + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Build a CUPS_DELETE_PRINTER request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(CUPS_DELETE_PRINTER); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(http, request, "/admin/")); + + /* + * Show the results... + */ + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() <= IPP_OK_CONFLICT) + { + /* + * Redirect successful updates back to the printers page... + */ + + cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/printers"); + } + + cgiStartHTML(cgiText(_("Delete Printer"))); + + if (cupsLastError() > IPP_OK_CONFLICT) + cgiShowIPPError(_("Unable to delete printer:")); + else + cgiCopyTemplateLang("printer-deleted.tmpl"); + + cgiEndHTML(); +} + + +/* + * 'do_export()' - Export printers to Samba. + */ + +static void +do_export(http_t *http) /* I - HTTP connection */ +{ + int i, j; /* Looping vars */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + const char *username, /* Samba username */ + *password, /* Samba password */ + *export_all; /* Export all printers? */ + int export_count, /* Number of printers to export */ + printer_count; /* Number of available printers */ + const char *name, /* What name to pull */ + *dest; /* Current destination */ + char ppd[1024]; /* PPD file */ + + + /* + * Get form data... + */ + + username = cgiGetVariable("USERNAME"); + password = cgiGetVariable("PASSWORD"); + export_all = cgiGetVariable("EXPORT_ALL"); + export_count = cgiGetSize("EXPORT_NAME"); + + /* + * Get list of available printers... + */ + + cgiSetSize("PRINTER_NAME", 0); + cgiSetSize("PRINTER_EXPORT", 0); + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type", 0); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type-mask", CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE | + CUPS_PRINTER_IMPLICIT); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "printer-name"); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + ippDelete(response); + + if (!export_all) + { + printer_count = cgiGetSize("PRINTER_NAME"); + + for (i = 0; i < printer_count; i ++) + { + dest = cgiGetArray("PRINTER_NAME", i); + + for (j = 0; j < export_count; j ++) + if (!strcasecmp(dest, cgiGetArray("EXPORT_NAME", j))) + break; + + cgiSetArray("PRINTER_EXPORT", i, j < export_count ? "Y" : ""); + } + } + } + + /* + * Export or get the printers to export... + */ + + if (username && *username && password && *password && + (export_all || export_count > 0)) + { + /* + * Do export... + */ + + fputs("DEBUG: Export printers...\n", stderr); + + if (export_all) + { + name = "PRINTER_NAME"; + export_count = cgiGetSize("PRINTER_NAME"); + } + else + name = "EXPORT_NAME"; + + for (i = 0; i < export_count; i ++) + { + dest = cgiGetArray(name, i); + + if (!cupsAdminCreateWindowsPPD(http, dest, ppd, sizeof(ppd))) + break; + + j = cupsAdminExportSamba(dest, ppd, "localhost", username, password, + stderr); + + unlink(ppd); + + if (!j) + break; + } + + if (i < export_count) + cgiSetVariable("ERROR", cupsLastErrorString()); + else + { + cgiStartHTML(cgiText(_("Export Printers to Samba"))); + cgiCopyTemplateLang("samba-exported.tmpl"); + cgiEndHTML(); + return; + } + } + else if (username && !*username) + cgiSetVariable("ERROR", + cgiText(_("A Samba username is required to export " + "printer drivers!"))); + else if (username && (!password || !*password)) + cgiSetVariable("ERROR", + cgiText(_("A Samba password is required to export " + "printer drivers!"))); + + /* + * Show form... + */ + + cgiStartHTML(cgiText(_("Export Printers to Samba"))); + cgiCopyTemplateLang("samba-export.tmpl"); + cgiEndHTML(); +} + + +/* + * 'do_list_printers()' - List available printers. + */ + +static void +do_list_printers(http_t *http) /* I - HTTP connection */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + + + cgiStartHTML(cgiText(_("List Available Printers"))); + fflush(stdout); + + /* + * Get the list of printers and their devices... + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "device-uri"); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", + CUPS_PRINTER_LOCAL); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", + CUPS_PRINTER_LOCAL); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Got the printer list, now load the devices... + */ + + int i; /* Looping var */ + cups_array_t *printer_devices; /* Printer devices for local printers */ + char *printer_device; /* Current printer device */ + + + /* + * Allocate an array and copy the device strings... + */ + + printer_devices = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + for (attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI); + attr; + attr = ippFindNextAttribute(response, "device-uri", IPP_TAG_URI)) + { + cupsArrayAdd(printer_devices, _cupsStrAlloc(attr->values[0].string.text)); + } + + /* + * Free the printer list and get the device list... + */ + + ippDelete(response); + + request = ippNewRequest(CUPS_GET_DEVICES); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Got the device list, let's parse it... + */ + + const char *device_uri, /* device-uri attribute value */ + *device_make_and_model, /* device-make-and-model value */ + *device_info; /* device-info value */ + + + for (i = 0, attr = response->attrs; attr; attr = attr->next) + { + /* + * Skip leading attributes until we hit a device... + */ + + while (attr && attr->group_tag != IPP_TAG_PRINTER) + attr = attr->next; + + if (!attr) + break; + + /* + * Pull the needed attributes from this device... + */ + + device_info = NULL; + device_make_and_model = NULL; + device_uri = NULL; + + while (attr && attr->group_tag == IPP_TAG_PRINTER) + { + if (!strcmp(attr->name, "device-info") && + attr->value_tag == IPP_TAG_TEXT) + device_info = attr->values[0].string.text; + + if (!strcmp(attr->name, "device-make-and-model") && + attr->value_tag == IPP_TAG_TEXT) + device_make_and_model = attr->values[0].string.text; + + if (!strcmp(attr->name, "device-uri") && + attr->value_tag == IPP_TAG_URI) + device_uri = attr->values[0].string.text; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (device_info && device_make_and_model && device_uri && + strcasecmp(device_make_and_model, "unknown") && + strchr(device_uri, ':')) + { + /* + * Yes, now see if there is already a printer for this + * device... + */ + + if (!cupsArrayFind(printer_devices, (void *)device_uri)) + { + /* + * Not found, so it must be a new printer... + */ + + char option[1024], /* Form variables for this device */ + *option_ptr; /* Pointer into string */ + const char *ptr; /* Pointer into device string */ + + + /* + * Format the printer name variable for this device... + * + * We use the device-info string first, then device-uri, + * and finally device-make-and-model to come up with a + * suitable name. + */ + + if (strncasecmp(device_info, "unknown", 7)) + ptr = device_info; + else if ((ptr = strstr(device_uri, "://")) != NULL) + ptr += 3; + else + ptr = device_make_and_model; + + for (option_ptr = option; + option_ptr < (option + sizeof(option) - 1) && *ptr; + ptr ++) + if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' || + *ptr == '.') + *option_ptr++ = *ptr; + else if ((*ptr == ' ' || *ptr == '/') && option_ptr > option && + option_ptr[-1] != '_') + *option_ptr++ = '_'; + else if (*ptr == '?' || *ptr == '(') + break; + + *option_ptr = '\0'; + + cgiSetArray("TEMPLATE_NAME", i, option); + + /* + * Finally, set the form variables for this printer... + */ + + cgiSetArray("device_info", i, device_info); + cgiSetArray("device_make_and_model", i, device_make_and_model); + cgiSetArray("device_uri", i, device_uri); + i ++; + } + } + + if (!attr) + break; + } + + ippDelete(response); + + /* + * Free the device list... + */ + + for (printer_device = (char *)cupsArrayFirst(printer_devices); + printer_device; + printer_device = (char *)cupsArrayNext(printer_devices)) + _cupsStrFree(printer_device); + + cupsArrayDelete(printer_devices); + } + } + + /* + * Finally, show the printer list... + */ + + cgiCopyTemplateLang("list-available-printers.tmpl"); + + cgiEndHTML(); +} + + +/* + * 'do_menu()' - Show the main menu. + */ + +static void +do_menu(http_t *http) /* I - HTTP connection */ +{ + int num_settings; /* Number of server settings */ + cups_option_t *settings; /* Server settings */ + const char *val; /* Setting value */ + char filename[1024]; /* Temporary filename */ + const char *datadir; /* Location of data files */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + + + /* + * Get the current server settings... + */ + + if (!cupsAdminGetServerSettings(http, &num_settings, &settings)) + { + cgiSetVariable("SETTINGS_MESSAGE", + cgiText(_("Unable to open cupsd.conf file:"))); + cgiSetVariable("SETTINGS_ERROR", cupsLastErrorString()); + } + + if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("DEBUG_LOGGING", "CHECKED"); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("REMOTE_ADMIN", "CHECKED"); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("REMOTE_ANY", "CHECKED"); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("REMOTE_PRINTERS", "CHECKED"); + + if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("SHARE_PRINTERS", "CHECKED"); + + if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings, + settings)) != NULL && atoi(val)) + cgiSetVariable("USER_CANCEL_ANY", "CHECKED"); + +#ifdef HAVE_GSSAPI + cgiSetVariable("HAVE_GSSAPI", "1"); + + if ((val = cupsGetOption("DefaultAuthType", num_settings, + settings)) != NULL && !strcasecmp(val, "Negotiate")) + cgiSetVariable("KERBEROS", "CHECKED"); + else +#endif /* HAVE_GSSAPI */ + cgiSetVariable("KERBEROS", ""); + +#ifdef HAVE_DNSSD + cgiSetVariable("HAVE_DNSSD", "1"); +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_LDAP + cgiSetVariable("HAVE_LDAP", "1"); +#endif /* HAVE_LDAP */ + +#ifdef HAVE_LIBSLP + cgiSetVariable("HAVE_LIBSLP", "1"); +#endif /* HAVE_LIBSLP */ + + if ((val = cupsGetOption("BrowseRemoteProtocols", num_settings, + settings)) == NULL) + if ((val = cupsGetOption("BrowseProtocols", num_settings, + settings)) == NULL) + val = CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS; + + if (strstr(val, "cups") || strstr(val, "CUPS")) + cgiSetVariable("BROWSE_REMOTE_CUPS", "CHECKED"); + + if (strstr(val, "ldap") || strstr(val, "LDAP")) + cgiSetVariable("BROWSE_REMOTE_LDAP", "CHECKED"); + + if (strstr(val, "slp") || strstr(val, "SLP")) + cgiSetVariable("BROWSE_REMOTE_SLP", "CHECKED"); + + if ((val = cupsGetOption("BrowseLocalProtocols", num_settings, + settings)) == NULL) + if ((val = cupsGetOption("BrowseProtocols", num_settings, + settings)) == NULL) + val = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS; + + if (strstr(val, "cups") || strstr(val, "CUPS")) + cgiSetVariable("BROWSE_LOCAL_CUPS", "CHECKED"); + + if (strstr(val, "dnssd") || strstr(val, "DNSSD") || + strstr(val, "dns-sd") || strstr(val, "DNS-SD") || + strstr(val, "bonjour") || strstr(val, "BONJOUR")) + cgiSetVariable("BROWSE_LOCAL_DNSSD", "CHECKED"); + + if (strstr(val, "ldap") || strstr(val, "LDAP")) + cgiSetVariable("BROWSE_LOCAL_LDAP", "CHECKED"); + + if (strstr(val, "slp") || strstr(val, "SLP")) + cgiSetVariable("BROWSE_LOCAL_SLP", "CHECKED"); + + if ((val = cupsGetOption("BrowseWebIF", num_settings, + settings)) == NULL) + val = "No"; + + if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") || + !strcasecmp(val, "true")) + cgiSetVariable("BROWSE_WEB_IF", "CHECKED"); + + if ((val = cupsGetOption("PreserveJobHistory", num_settings, + settings)) == NULL) + val = "Yes"; + + if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") || + !strcasecmp(val, "true")) + { + cgiSetVariable("PRESERVE_JOB_HISTORY", "CHECKED"); + + if ((val = cupsGetOption("PreserveJobFiles", num_settings, + settings)) == NULL) + val = "No"; + + if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") || + !strcasecmp(val, "true")) + cgiSetVariable("PRESERVE_JOB_FILES", "CHECKED"); + } + + if ((val = cupsGetOption("MaxClients", num_settings, settings)) == NULL) + val = "100"; + + cgiSetVariable("MAX_CLIENTS", val); + + if ((val = cupsGetOption("MaxJobs", num_settings, settings)) == NULL) + val = "500"; + + cgiSetVariable("MAX_JOBS", val); + + if ((val = cupsGetOption("MaxLogSize", num_settings, settings)) == NULL) + val = "1m"; + + cgiSetVariable("MAX_LOG_SIZE", val); + + cupsFreeOptions(num_settings, settings); + + /* + * See if Samba and the Windows drivers are installed... + */ + + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + snprintf(filename, sizeof(filename), "%s/drivers/pscript5.dll", datadir); + if (!access(filename, R_OK)) + { + /* + * Found Windows 2000 driver file, see if we have smbclient and + * rpcclient... + */ + + if (cupsFileFind("smbclient", getenv("PATH"), 1, filename, + sizeof(filename)) && + cupsFileFind("rpcclient", getenv("PATH"), 1, filename, + sizeof(filename))) + cgiSetVariable("HAVE_SAMBA", "Y"); + else + { + if (!cupsFileFind("smbclient", getenv("PATH"), 1, filename, + sizeof(filename))) + fputs("ERROR: smbclient not found!\n", stderr); + + if (!cupsFileFind("rpcclient", getenv("PATH"), 1, filename, + sizeof(filename))) + fputs("ERROR: rpcclient not found!\n", stderr); + } + } + else + perror(filename); + + /* + * Subscriptions... + */ + + request = ippNewRequest(IPP_GET_SUBSCRIPTIONS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + ippDelete(response); + } + + /* + * Finally, show the main menu template... + */ + + cgiStartHTML(cgiText(_("Administration"))); + + cgiCopyTemplateLang("admin.tmpl"); + + cgiEndHTML(); +} + + +/* + * 'do_set_allowed_users()' - Set the allowed/denied users for a queue. + */ + +static void +do_set_allowed_users(http_t *http) /* I - HTTP connection */ +{ + int i; /* Looping var */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + const char *printer, /* Printer name (purge-jobs) */ + *is_class, /* Is a class? */ + *users, /* List of users or groups */ + *type; /* Allow/deny type */ + int num_users; /* Number of users */ + char *ptr, /* Pointer into users string */ + *end, /* Pointer to end of users string */ + quote; /* Quote character */ + ipp_attribute_t *attr; /* Attribute */ + static const char * const attrs[] = /* Requested attributes */ + { + "requesting-user-name-allowed", + "requesting-user-name-denied" + }; + + + is_class = cgiGetVariable("IS_CLASS"); + printer = cgiGetVariable("PRINTER_NAME"); + + if (!printer) + { + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiStartHTML(cgiText(_("Set Allowed Users"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + users = cgiGetVariable("users"); + type = cgiGetVariable("type"); + + if (!users || !type || + (strcmp(type, "requesting-user-name-allowed") && + strcmp(type, "requesting-user-name-denied"))) + { + /* + * Build a Get-Printer-Attributes request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requested-attributes + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, is_class ? "/classes/%s" : "/printers/%s", + printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(attrs) / sizeof(attrs[0])), NULL, attrs); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + ippDelete(response); + } + + cgiStartHTML(cgiText(_("Set Allowed Users"))); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + cgiShowIPPError(_("Unable to get printer attributes:")); + else + cgiCopyTemplateLang("users.tmpl"); + + cgiEndHTML(); + } + else + { + /* + * Save the changes... + */ + + for (num_users = 0, ptr = (char *)users; *ptr; num_users ++) + { + /* + * Skip whitespace and commas... + */ + + while (*ptr == ',' || isspace(*ptr & 255)) + ptr ++; + + if (!*ptr) + break; + + if (*ptr == '\'' || *ptr == '\"') + { + /* + * Scan quoted name... + */ + + quote = *ptr++; + + for (end = ptr; *end; end ++) + if (*end == quote) + break; + } + else + { + /* + * Scan space or comma-delimited name... + */ + + for (end = ptr; *end; end ++) + if (isspace(*end & 255) || *end == ',') + break; + } + + /* + * Advance to the next name... + */ + + ptr = end; + } + + /* + * Build a CUPS-Add-Printer/Class request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requesting-user-name-{allowed,denied} + */ + + request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, is_class ? "/classes/%s" : "/printers/%s", + printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + if (num_users == 0) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, + "requesting-user-name-allowed", NULL, "all"); + else + { + attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME, + type, num_users, NULL, NULL); + + for (i = 0, ptr = (char *)users; *ptr; i ++) + { + /* + * Skip whitespace and commas... + */ + + while (*ptr == ',' || isspace(*ptr & 255)) + ptr ++; + + if (!*ptr) + break; + + if (*ptr == '\'' || *ptr == '\"') + { + /* + * Scan quoted name... + */ + + quote = *ptr++; + + for (end = ptr; *end; end ++) + if (*end == quote) + break; + } + else + { + /* + * Scan space or comma-delimited name... + */ + + for (end = ptr; *end; end ++) + if (isspace(*end & 255) || *end == ',') + break; + } + + /* + * Terminate the name... + */ + + if (*end) + *end++ = '\0'; + + /* + * Add the name... + */ + + attr->values[i].string.text = _cupsStrAlloc(ptr); + + /* + * Advance to the next name... + */ + + ptr = end; + } + } + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(http, request, "/admin/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(cgiText(_("Set Allowed Users"))); + cgiShowIPPError(_("Unable to change printer:")); + } + else + { + /* + * Redirect successful updates back to the printer page... + */ + + char url[1024], /* Printer/class URL */ + refresh[1024]; /* Refresh URL */ + + + cgiRewriteURL(uri, url, sizeof(url), NULL); + cgiFormEncode(uri, url, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", + uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(cgiText(_("Set Allowed Users"))); + + cgiCopyTemplateLang(is_class ? "class-modified.tmpl" : + "printer-modified.tmpl"); + } + + cgiEndHTML(); + } +} + + +/* + * 'do_set_default()' - Set the server default printer/class. + */ + +static void +do_set_default(http_t *http) /* I - HTTP connection */ +{ + const char *title; /* Page title */ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + const char *printer, /* Printer name (purge-jobs) */ + *is_class; /* Is a class? */ + + + is_class = cgiGetVariable("IS_CLASS"); + printer = cgiGetVariable("PRINTER_NAME"); + title = cgiText(_("Set As Server Default")); + + if (!printer) + { + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Build a printer request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(CUPS_SET_DEFAULT); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, is_class ? "/classes/%s" : "/printers/%s", + printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(http, request, "/admin/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(title); + cgiShowIPPError(_("Unable to set server default:")); + } + else + { + /* + * Redirect successful updates back to the printer page... + */ + + char url[1024], /* Printer/class URL */ + refresh[1024]; /* Refresh URL */ + + + cgiRewriteURL(uri, url, sizeof(url), NULL); + cgiFormEncode(uri, url, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + cgiCopyTemplateLang("printer-default.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'do_set_options()' - Configure the default options for a queue. + */ + +static void +do_set_options(http_t *http, /* I - HTTP connection */ + int is_class) /* I - Set options for class? */ +{ + int i, j, k, m; /* 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 */ + const char *filename; /* PPD filename */ + char tempfile[1024]; /* Temporary filename */ + cups_file_t *in, /* Input file */ + *out; /* Output file */ + char line[1024], /* Line from PPD file */ + value[1024], /* Option value */ + 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 */ + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + ppd_attr_t *ppdattr; /* PPD attribute */ + const char *title; /* Page title */ + + + title = cgiText(is_class ? _("Set Class Options") : _("Set Printer Options")); + + fprintf(stderr, "DEBUG: do_set_options(http=%p, is_class=%d)\n", http, + is_class); + + /* + * Get the printer name... + */ + + if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL) + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, is_class ? "/classes/%s" : "/printers/%s", + printer); + else + { + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + fprintf(stderr, "DEBUG: printer=\"%s\", uri=\"%s\"...\n", printer, uri); + + /* + * If the user clicks on the Auto-Configure button, send an AutoConfigure + * command file to the printer... + */ + + if (cgiGetVariable("AUTOCONFIGURE")) + { + cgiPrintCommand(http, printer, "AutoConfigure", "Set Default Options"); + return; + } + + /* + * Get the PPD file... + */ + + if (is_class) + filename = NULL; + else + filename = cupsGetPPD2(http, printer); + + if (filename) + { + fprintf(stderr, "DEBUG: Got PPD file: \"%s\"\n", filename); + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + cgiSetVariable("ERROR", ppdErrorString(ppdLastError(&i))); + cgiSetVariable("MESSAGE", cgiText(_("Unable to open PPD file:"))); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + } + else + { + fputs("DEBUG: No PPD file\n", stderr); + ppd = NULL; + } + + if (cgiGetVariable("job_sheets_start") != NULL || + cgiGetVariable("job_sheets_end") != NULL) + have_options = 1; + else + have_options = 0; + + if (ppd) + { + ppdMarkDefaults(ppd); + + for (option = ppdFirstOption(ppd); + option; + option = ppdNextOption(ppd)) + { + if ((var = cgiGetVariable(option->keyword)) != NULL) + { + have_options = 1; + ppdMarkOption(ppd, option->keyword, var); + fprintf(stderr, "DEBUG: Set %s to %s...\n", option->keyword, var); + } + else + fprintf(stderr, "DEBUG: Didn't find %s...\n", option->keyword); + } + } + + if (!have_options || ppdConflicts(ppd)) + { + /* + * Show the options to the user... + */ + + fputs("DEBUG: Showing options...\n", stderr); + + /* + * Show auto-configure button if supported... + */ + + if (ppd) + { + if (ppd->num_filters == 0 || + ((ppdattr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL && + ppdattr->value && strstr(ppdattr->value, "AutoConfigure"))) + cgiSetVariable("HAVE_AUTOCONFIGURE", "YES"); + else + { + for (i = 0; i < ppd->num_filters; i ++) + if (!strncmp(ppd->filters[i], "application/vnd.cups-postscript", 31)) + { + cgiSetVariable("HAVE_AUTOCONFIGURE", "YES"); + break; + } + } + } + + /* + * Get the printer attributes... + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + response = cupsDoRequest(http, request, "/"); + + /* + * List the groups used as "tabs"... + */ + + i = 0; + + if (ppd) + { + for (group = ppd->groups; + i < ppd->num_groups; + i ++, group ++) + { + cgiSetArray("GROUP_ID", i, group->name); + + if (!strcmp(group->name, "InstallableOptions")) + cgiSetArray("GROUP", i, cgiText(_("Options Installed"))); + else + cgiSetArray("GROUP", i, group->text); + } + } + + if (ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO)) + { + cgiSetArray("GROUP_ID", i, "CUPS_BANNERS"); + cgiSetArray("GROUP", i ++, cgiText(_("Banners"))); + } + + if (ippFindAttribute(response, "printer-error-policy-supported", + IPP_TAG_ZERO) || + ippFindAttribute(response, "printer-op-policy-supported", + IPP_TAG_ZERO)) + { + cgiSetArray("GROUP_ID", i, "CUPS_POLICIES"); + cgiSetArray("GROUP", i ++, cgiText(_("Policies"))); + } + + if ((attr = ippFindAttribute(response, "port-monitor-supported", + IPP_TAG_NAME)) != NULL && attr->num_values > 1) + { + cgiSetArray("GROUP_ID", i, "CUPS_PORT_MONITOR"); + cgiSetArray("GROUP", i, cgiText(_("Port Monitor"))); + } + + cgiStartHTML(cgiText(_("Set Printer Options"))); + cgiCopyTemplateLang("set-printer-options-header.tmpl"); + + if (ppd) + { + ppdLocalize(ppd); + + 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); + + for (m = 0; m < option->num_choices; m ++) + { + if (option->choices[m].marked) + { + cgiSetArray("cchoice", k, option->choices[m].text); + break; + } + } + + k ++; + } + + cgiCopyTemplateLang("option-conflict.tmpl"); + } + + for (i = ppd->num_groups, group = ppd->groups; + i > 0; + i --, group ++) + { + cgiSetVariable("GROUP_ID", group->name); + + if (!strcmp(group->name, "InstallableOptions")) + cgiSetVariable("GROUP", cgiText(_("Options Installed"))); + else + cgiSetVariable("GROUP", group->text); + + cgiCopyTemplateLang("option-header.tmpl"); + + for (j = group->num_options, option = group->options; + j > 0; + j --, option ++) + { + if (!strcmp(option->keyword, "PageRegion")) + continue; + + cgiSetVariable("KEYWORD", option->keyword); + cgiSetVariable("KEYTEXT", option->text); + + if (option->conflicted) + cgiSetVariable("CONFLICTED", "1"); + else + cgiSetVariable("CONFLICTED", "0"); + + cgiSetSize("CHOICES", 0); + cgiSetSize("TEXT", 0); + for (k = 0, m = 0; k < option->num_choices; k ++) + { + cgiSetArray("CHOICES", m, option->choices[k].choice); + cgiSetArray("TEXT", m, option->choices[k].text); + + m ++; + + if (option->choices[k].marked) + cgiSetVariable("DEFCHOICE", option->choices[k].choice); + } + + cgiSetSize("PARAMS", 0); + cgiSetSize("PARAMTEXT", 0); + cgiSetSize("PARAMVALUE", 0); + cgiSetSize("INPUTTYPE", 0); + + if ((coption = ppdFindCustomOption(ppd, option->keyword))) + { + const char *units = NULL; /* Units value, if any */ + + + cgiSetVariable("ISCUSTOM", "1"); + + for (cparam = ppdFirstCustomParam(coption), m = 0; + cparam; + cparam = ppdNextCustomParam(coption), m ++) + { + if (!strcasecmp(option->keyword, "PageSize") && + strcasecmp(cparam->name, "Width") && + strcasecmp(cparam->name, "Height")) + { + m --; + continue; + } + + cgiSetArray("PARAMS", m, cparam->name); + cgiSetArray("PARAMTEXT", m, cparam->text); + cgiSetArray("INPUTTYPE", m, "text"); + + switch (cparam->type) + { + case PPD_CUSTOM_POINTS : + if (!strncasecmp(option->defchoice, "Custom.", 7)) + { + units = option->defchoice + strlen(option->defchoice) - 2; + + if (strcmp(units, "mm") && strcmp(units, "cm") && + strcmp(units, "in") && strcmp(units, "ft")) + { + if (units[1] == 'm') + units ++; + else + units = "pt"; + } + } + else + units = "pt"; + + if (!strcmp(units, "mm")) + snprintf(value, sizeof(value), "%g", + cparam->current.custom_points / 72.0 * 25.4); + else if (!strcmp(units, "cm")) + snprintf(value, sizeof(value), "%g", + cparam->current.custom_points / 72.0 * 2.54); + else if (!strcmp(units, "in")) + snprintf(value, sizeof(value), "%g", + cparam->current.custom_points / 72.0); + else if (!strcmp(units, "ft")) + snprintf(value, sizeof(value), "%g", + cparam->current.custom_points / 72.0 / 12.0); + else if (!strcmp(units, "m")) + snprintf(value, sizeof(value), "%g", + cparam->current.custom_points / 72.0 * 0.0254); + else + snprintf(value, sizeof(value), "%g", + cparam->current.custom_points); + cgiSetArray("PARAMVALUE", m, value); + break; + + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_REAL : + snprintf(value, sizeof(value), "%g", + cparam->current.custom_real); + cgiSetArray("PARAMVALUE", m, value); + break; + + case PPD_CUSTOM_INT: + snprintf(value, sizeof(value), "%d", + cparam->current.custom_int); + cgiSetArray("PARAMVALUE", m, value); + break; + + case PPD_CUSTOM_PASSCODE: + case PPD_CUSTOM_PASSWORD: + if (cparam->current.custom_password) + cgiSetArray("PARAMVALUE", m, + cparam->current.custom_password); + else + cgiSetArray("PARAMVALUE", m, ""); + cgiSetArray("INPUTTYPE", m, "password"); + break; + + case PPD_CUSTOM_STRING: + if (cparam->current.custom_string) + cgiSetArray("PARAMVALUE", m, + cparam->current.custom_string); + else + cgiSetArray("PARAMVALUE", m, ""); + break; + } + } + + if (units) + { + cgiSetArray("PARAMS", m, "Units"); + cgiSetArray("PARAMTEXT", m, cgiText(_("Units"))); + cgiSetArray("PARAMVALUE", m, units); + } + } + else + cgiSetVariable("ISCUSTOM", "0"); + + switch (option->ui) + { + case PPD_UI_BOOLEAN : + cgiCopyTemplateLang("option-boolean.tmpl"); + break; + case PPD_UI_PICKONE : + cgiCopyTemplateLang("option-pickone.tmpl"); + break; + case PPD_UI_PICKMANY : + cgiCopyTemplateLang("option-pickmany.tmpl"); + break; + } + } + + cgiCopyTemplateLang("option-trailer.tmpl"); + } + } + + if ((attr = ippFindAttribute(response, "job-sheets-supported", + IPP_TAG_ZERO)) != NULL) + { + /* + * Add the job sheets options... + */ + + cgiSetVariable("GROUP_ID", "CUPS_BANNERS"); + cgiSetVariable("GROUP", cgiText(_("Banners"))); + cgiCopyTemplateLang("option-header.tmpl"); + + 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", cgiText(_("Starting Banner"))); + cgiSetVariable("DEFCHOICE", attr != NULL ? + attr->values[0].string.text : ""); + + cgiCopyTemplateLang("option-pickone.tmpl"); + + cgiSetVariable("KEYWORD", "job_sheets_end"); + cgiSetVariable("KEYTEXT", cgiText(_("Ending Banner"))); + cgiSetVariable("DEFCHOICE", attr != NULL && attr->num_values > 1 ? + attr->values[1].string.text : ""); + + cgiCopyTemplateLang("option-pickone.tmpl"); + + cgiCopyTemplateLang("option-trailer.tmpl"); + } + + if (ippFindAttribute(response, "printer-error-policy-supported", + IPP_TAG_ZERO) || + ippFindAttribute(response, "printer-op-policy-supported", + IPP_TAG_ZERO)) + { + /* + * Add the error and operation policy options... + */ + + cgiSetVariable("GROUP_ID", "CUPS_POLICIES"); + cgiSetVariable("GROUP", cgiText(_("Policies"))); + cgiCopyTemplateLang("option-header.tmpl"); + + /* + * Error policy... + */ + + attr = ippFindAttribute(response, "printer-error-policy-supported", + IPP_TAG_ZERO); + + if (attr) + { + 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, "printer-error-policy", + IPP_TAG_ZERO); + + cgiSetVariable("KEYWORD", "printer_error_policy"); + cgiSetVariable("KEYTEXT", cgiText(_("Error Policy"))); + cgiSetVariable("DEFCHOICE", attr == NULL ? + "" : attr->values[0].string.text); + } + + cgiCopyTemplateLang("option-pickone.tmpl"); + + /* + * Operation policy... + */ + + attr = ippFindAttribute(response, "printer-op-policy-supported", + IPP_TAG_ZERO); + + if (attr) + { + 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, "printer-op-policy", IPP_TAG_ZERO); + + cgiSetVariable("KEYWORD", "printer_op_policy"); + cgiSetVariable("KEYTEXT", cgiText(_("Operation Policy"))); + cgiSetVariable("DEFCHOICE", attr == NULL ? + "" : attr->values[0].string.text); + + cgiCopyTemplateLang("option-pickone.tmpl"); + } + + cgiCopyTemplateLang("option-trailer.tmpl"); + } + + /* + * Binary protocol support... + */ + + if ((attr = ippFindAttribute(response, "port-monitor-supported", + IPP_TAG_NAME)) != NULL && attr->num_values > 1) + { + cgiSetVariable("GROUP_ID", "CUPS_PORT_MONITOR"); + cgiSetVariable("GROUP", cgiText(_("Port Monitor"))); + + cgiSetSize("CHOICES", attr->num_values); + cgiSetSize("TEXT", attr->num_values); + + for (i = 0; i < attr->num_values; i ++) + { + cgiSetArray("CHOICES", i, attr->values[i].string.text); + cgiSetArray("TEXT", i, attr->values[i].string.text); + } + + attr = ippFindAttribute(response, "port-monitor", IPP_TAG_NAME); + cgiSetVariable("KEYWORD", "port_monitor"); + cgiSetVariable("KEYTEXT", cgiText(_("Port Monitor"))); + cgiSetVariable("DEFCHOICE", attr ? attr->values[0].string.text : "none"); + + cgiCopyTemplateLang("option-header.tmpl"); + cgiCopyTemplateLang("option-pickone.tmpl"); + cgiCopyTemplateLang("option-trailer.tmpl"); + } + + cgiCopyTemplateLang("set-printer-options-trailer.tmpl"); + cgiEndHTML(); + + ippDelete(response); + } + else + { + /* + * Set default options... + */ + + fputs("DEBUG: Setting options...\n", stderr); + + if (filename) + { + out = cupsTempFile2(tempfile, sizeof(tempfile)); + in = cupsFileOpen(filename, "r"); + + if (!in || !out) + { + cgiSetVariable("ERROR", strerror(errno)); + cgiStartHTML(cgiText(_("Set Printer Options"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + if (in) + cupsFileClose(in); + + if (out) + { + cupsFileClose(out); + unlink(tempfile); + } + + unlink(filename); + return; + } + + while (cupsFileGets(in, line, sizeof(line))) + { + if (!strncmp(line, "*cupsProtocol:", 14)) + continue; + else if (strncmp(line, "*Default", 8)) + cupsFilePrintf(out, "%s\n", line); + else + { + /* + * Get default option name... + */ + + strlcpy(keyword, line + 8, sizeof(keyword)); + + for (keyptr = keyword; *keyptr; keyptr ++) + if (*keyptr == ':' || isspace(*keyptr & 255)) + break; + + *keyptr = '\0'; + + if (!strcmp(keyword, "PageRegion") || + !strcmp(keyword, "PaperDimension") || + !strcmp(keyword, "ImageableArea")) + var = get_option_value(ppd, "PageSize", value, sizeof(value)); + else + var = get_option_value(ppd, keyword, value, sizeof(value)); + + if (!var) + cupsFilePrintf(out, "%s\n", line); + else + cupsFilePrintf(out, "*Default%s: %s\n", keyword, var); + } + } + + cupsFileClose(in); + cupsFileClose(out); + } + else + { + /* + * Make sure temporary filename is cleared when there is no PPD... + */ + + tempfile[0] = '\0'; + } + + /* + * Build a CUPS_ADD_MODIFY_CLASS/PRINTER request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * job-sheets-default + * printer-error-policy + * printer-op-policy + * [ppd file] + */ + + request = ippNewRequest(is_class ? CUPS_ADD_MODIFY_CLASS : + CUPS_ADD_MODIFY_PRINTER); + + 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 = _cupsStrAlloc(cgiGetVariable("job_sheets_start")); + attr->values[1].string.text = _cupsStrAlloc(cgiGetVariable("job_sheets_end")); + + if ((var = cgiGetVariable("printer_error_policy")) != NULL) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-error-policy", NULL, var); + + if ((var = cgiGetVariable("printer_op_policy")) != NULL) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-op-policy", NULL, var); + + if ((var = cgiGetVariable("port_monitor")) != NULL) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, + "port-monitor", NULL, var); + + /* + * Do the request and get back a response... + */ + + if (filename) + ippDelete(cupsDoFileRequest(http, request, "/admin/", tempfile)); + else + ippDelete(cupsDoRequest(http, request, "/admin/")); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(title); + cgiShowIPPError(_("Unable to set options:")); + } + else + { + /* + * Redirect successful updates back to the printer page... + */ + + char refresh[1024]; /* Refresh URL */ + + + cgiFormEncode(uri, printer, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=/%s/%s", + is_class ? "classes" : "printers", uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + + cgiCopyTemplateLang("printer-configured.tmpl"); + } + + cgiEndHTML(); + + if (filename) + unlink(tempfile); + } + + if (filename) + unlink(filename); +} + + +/* + * 'do_set_sharing()' - Set printer-is-shared value. + */ + +static void +do_set_sharing(http_t *http) /* I - HTTP connection */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + const char *printer, /* Printer name */ + *is_class, /* Is a class? */ + *shared; /* Sharing value */ + + + is_class = cgiGetVariable("IS_CLASS"); + printer = cgiGetVariable("PRINTER_NAME"); + shared = cgiGetVariable("SHARED"); + + if (!printer || !shared) + { + cgiSetVariable("ERROR", cgiText(_("Missing form variable!"))); + cgiStartHTML(cgiText(_("Set Publishing"))); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + return; + } + + /* + * Build a CUPS-Add-Printer/CUPS-Add-Class request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * printer-is-shared + */ + + request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, is_class ? "/classes/%s" : "/printers/%s", + printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddBoolean(request, IPP_TAG_OPERATION, "printer-is-shared", atoi(shared)); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + ippDelete(response); + } + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(cgiText(_("Set Publishing"))); + cgiShowIPPError(_("Unable to change printer-is-shared attribute:")); + } + else + { + /* + * Redirect successful updates back to the printer page... + */ + + char url[1024], /* Printer/class URL */ + refresh[1024]; /* Refresh URL */ + + + cgiRewriteURL(uri, url, sizeof(url), NULL); + cgiFormEncode(uri, url, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(cgiText(_("Set Publishing"))); + cgiCopyTemplateLang(is_class ? "class-modified.tmpl" : + "printer-modified.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'get_option_value()' - Return the value of an option. + * + * This function also handles generation of custom option values. + */ + +static char * /* O - Value string or NULL on error */ +get_option_value( + ppd_file_t *ppd, /* I - PPD file */ + const char *name, /* I - Option name */ + char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Size of buffer */ +{ + char *bufptr, /* Pointer into buffer */ + *bufend; /* End of buffer */ + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Current custom parameter */ + char keyword[256]; /* Parameter name */ + const char *val, /* Parameter value */ + *uval; /* Units value */ + long integer; /* Integer value */ + double number, /* Number value */ + number_points; /* Number in points */ + + + /* + * See if we have a custom option choice... + */ + + if ((val = cgiGetVariable(name)) == NULL) + { + /* + * Option not found! + */ + + return (NULL); + } + else if (strcasecmp(val, "Custom") || + (coption = ppdFindCustomOption(ppd, name)) == NULL) + { + /* + * Not a custom choice... + */ + + strlcpy(buffer, val, bufsize); + return (buffer); + } + + /* + * OK, we have a custom option choice, format it... + */ + + *buffer = '\0'; + + if (!strcmp(coption->keyword, "PageSize")) + { + const char *lval; /* Length string value */ + double width, /* Width value */ + width_points, /* Width in points */ + length, /* Length value */ + length_points; /* Length in points */ + + + val = cgiGetVariable("PageSize.Width"); + lval = cgiGetVariable("PageSize.Height"); + uval = cgiGetVariable("PageSize.Units"); + + if (!val || !lval || !uval || + (width = strtod(val, NULL)) == 0.0 || + (length = strtod(lval, NULL)) == 0.0 || + (strcmp(uval, "pt") && strcmp(uval, "in") && strcmp(uval, "ft") && + strcmp(uval, "cm") && strcmp(uval, "mm") && strcmp(uval, "m"))) + return (NULL); + + width_points = get_points(width, uval); + length_points = get_points(length, uval); + + if (width_points < ppd->custom_min[0] || + width_points > ppd->custom_max[0] || + length_points < ppd->custom_min[1] || + length_points > ppd->custom_max[1]) + return (NULL); + + snprintf(buffer, bufsize, "Custom.%gx%g%s", width, length, uval); + } + else if (cupsArrayCount(coption->params) == 1) + { + cparam = ppdFirstCustomParam(coption); + snprintf(keyword, sizeof(keyword), "%s.%s", coption->keyword, cparam->name); + + if ((val = cgiGetVariable(keyword)) == NULL) + return (NULL); + + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_REAL : + if ((number = strtod(val, NULL)) == 0.0 || + number < cparam->minimum.custom_real || + number > cparam->maximum.custom_real) + return (NULL); + + snprintf(buffer, bufsize, "Custom.%g", number); + break; + + case PPD_CUSTOM_INT : + if (!*val || (integer = strtol(val, NULL, 10)) == LONG_MIN || + integer == LONG_MAX || + integer < cparam->minimum.custom_int || + integer > cparam->maximum.custom_int) + return (NULL); + + snprintf(buffer, bufsize, "Custom.%ld", integer); + break; + + case PPD_CUSTOM_POINTS : + snprintf(keyword, sizeof(keyword), "%s.Units", coption->keyword); + + if ((number = strtod(val, NULL)) == 0.0 || + (uval = cgiGetVariable(keyword)) == NULL || + (strcmp(uval, "pt") && strcmp(uval, "in") && strcmp(uval, "ft") && + strcmp(uval, "cm") && strcmp(uval, "mm") && strcmp(uval, "m"))) + return (NULL); + + number_points = get_points(number, uval); + if (number_points < cparam->minimum.custom_points || + number_points > cparam->maximum.custom_points) + return (NULL); + + snprintf(buffer, bufsize, "Custom.%g%s", number, uval); + break; + + case PPD_CUSTOM_PASSCODE : + for (uval = val; *uval; uval ++) + if (!isdigit(*uval & 255)) + return (NULL); + + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + integer = (long)strlen(val); + if (integer < cparam->minimum.custom_string || + integer > cparam->maximum.custom_string) + return (NULL); + + snprintf(buffer, bufsize, "Custom.%s", val); + break; + } + } + else + { + const char *prefix = "{"; /* Prefix string */ + + + bufptr = buffer; + bufend = buffer + bufsize; + + for (cparam = ppdFirstCustomParam(coption); + cparam; + cparam = ppdNextCustomParam(coption)) + { + snprintf(keyword, sizeof(keyword), "%s.%s", coption->keyword, + cparam->name); + + if ((val = cgiGetVariable(keyword)) == NULL) + return (NULL); + + snprintf(bufptr, bufend - bufptr, "%s%s=", prefix, cparam->name); + bufptr += strlen(bufptr); + prefix = " "; + + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_REAL : + if ((number = strtod(val, NULL)) == 0.0 || + number < cparam->minimum.custom_real || + number > cparam->maximum.custom_real) + return (NULL); + + snprintf(bufptr, bufend - bufptr, "%g", number); + break; + + case PPD_CUSTOM_INT : + if (!*val || (integer = strtol(val, NULL, 10)) == LONG_MIN || + integer == LONG_MAX || + integer < cparam->minimum.custom_int || + integer > cparam->maximum.custom_int) + return (NULL); + + snprintf(bufptr, bufend - bufptr, "%ld", integer); + break; + + case PPD_CUSTOM_POINTS : + snprintf(keyword, sizeof(keyword), "%s.Units", coption->keyword); + + if ((number = strtod(val, NULL)) == 0.0 || + (uval = cgiGetVariable(keyword)) == NULL || + (strcmp(uval, "pt") && strcmp(uval, "in") && + strcmp(uval, "ft") && strcmp(uval, "cm") && + strcmp(uval, "mm") && strcmp(uval, "m"))) + return (NULL); + + number_points = get_points(number, uval); + if (number_points < cparam->minimum.custom_points || + number_points > cparam->maximum.custom_points) + return (NULL); + + snprintf(bufptr, bufend - bufptr, "%g%s", number, uval); + break; + + case PPD_CUSTOM_PASSCODE : + for (uval = val; *uval; uval ++) + if (!isdigit(*uval & 255)) + return (NULL); + + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + integer = (long)strlen(val); + if (integer < cparam->minimum.custom_string || + integer > cparam->maximum.custom_string) + return (NULL); + + if ((bufptr + 2) > bufend) + return (NULL); + + bufend --; + *bufptr++ = '\"'; + + while (*val && bufptr < bufend) + { + if (*val == '\\' || *val == '\"') + { + if ((bufptr + 1) >= bufend) + return (NULL); + + *bufptr++ = '\\'; + } + + *bufptr++ = *val++; + } + + if (bufptr >= bufend) + return (NULL); + + *bufptr++ = '\"'; + *bufptr = '\0'; + bufend ++; + break; + } + + bufptr += strlen(bufptr); + } + + if (bufptr == buffer || (bufend - bufptr) < 2) + return (NULL); + + strcpy(bufptr, "}"); + } + + return (buffer); +} + + +/* + * 'get_points()' - Get a value in points. + */ + +static double /* O - Number in points */ +get_points(double number, /* I - Original number */ + const char *uval) /* I - Units */ +{ + if (!strcmp(uval, "mm")) /* Millimeters */ + return (number * 72.0 / 25.4); + else if (!strcmp(uval, "cm")) /* Centimeters */ + return (number * 72.0 / 2.54); + else if (!strcmp(uval, "in")) /* Inches */ + return (number * 72.0); + else if (!strcmp(uval, "ft")) /* Feet */ + return (number * 72.0 * 12.0); + else if (!strcmp(uval, "m")) /* Meters */ + return (number * 72.0 / 0.0254); + else /* Points */ + return (number); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/api-cgi.header b/cgi-bin/api-cgi.header new file mode 100644 index 0000000000..e3355a6b99 --- /dev/null +++ b/cgi-bin/api-cgi.header @@ -0,0 +1,34 @@ + + +

CGI API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/cgi.h
Library-lcupscgi
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/cgi-bin/api-cgi.shtml b/cgi-bin/api-cgi.shtml new file mode 100644 index 0000000000..cf0413a5e4 --- /dev/null +++ b/cgi-bin/api-cgi.shtml @@ -0,0 +1,17 @@ + + +

Overview

+ +

The CGI API provides Common Gateway Interface functions for CUPS.

diff --git a/cgi-bin/cgi-private.h b/cgi-bin/cgi-private.h new file mode 100644 index 0000000000..7aed9ef3c7 --- /dev/null +++ b/cgi-bin/cgi-private.h @@ -0,0 +1,35 @@ +/* + * "$Id$" + * + * Private CGI definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Include necessary headers... + */ + +#include "cgi.h" +#include +#include +#include + + +/* + * Limits... + */ + +#define CUPS_PAGE_MAX 100 /* Maximum items per page */ + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/cgi.h b/cgi-bin/cgi.h new file mode 100644 index 0000000000..61eb7fc754 --- /dev/null +++ b/cgi-bin/cgi.h @@ -0,0 +1,119 @@ +/* + * "$Id$" + * + * CGI support library definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_CGI_H_ +# define _CUPS_CGI_H_ + +# include +# include +# include +# include + +# ifdef WIN32 +# include +# include +# else +# include +# endif /* WIN32 */ + +# include +# include +# include "help-index.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Types... + */ + +typedef struct cgi_file_s /**** Uploaded file data ****/ +{ + char tempfile[1024], /* Temporary file containing data */ + *name, /* Variable name */ + *filename, /* Original filename */ + *mimetype; /* MIME media type */ + size_t filesize; /* Size of uploaded file */ +} cgi_file_t; + + +/* + * Prototypes... + */ + +extern void cgiAbort(const char *title, const char *stylesheet, + const char *format, ...); +extern int cgiCheckVariables(const char *names); +extern void cgiClearVariables(void); +extern void *cgiCompileSearch(const char *query); +extern void cgiCopyTemplateFile(FILE *out, const char *tmpl); +extern void cgiCopyTemplateLang(const char *tmpl); +extern int cgiDoSearch(void *search, const char *text); +extern void cgiEndHTML(void); +extern void cgiEndMultipart(void); +extern char *cgiFormEncode(char *dst, const char *src, + size_t dstsize); +extern void cgiFreeSearch(void *search); +extern const char *cgiGetArray(const char *name, int element); +extern void cgiGetAttributes(ipp_t *request, const char *tmpl); +extern const char *cgiGetCookie(const char *name); +extern const cgi_file_t *cgiGetFile(void); +extern cups_array_t *cgiGetIPPObjects(ipp_t *response, void *search); +extern int cgiGetSize(const char *name); +extern char *cgiGetTemplateDir(void); +extern const char *cgiGetVariable(const char *name); +extern int cgiInitialize(void); +extern int cgiIsPOST(void); +extern void cgiMoveJobs(http_t *http, const char *dest, int job_id); +extern void cgiPrintCommand(http_t *http, const char *dest, + const char *command, const char *title); +extern void cgiPrintTestPage(http_t *http, const char *dest); +extern char *cgiRewriteURL(const char *uri, char *url, int urlsize, + const char *newresource); +extern void cgiSetArray(const char *name, int element, + const char *value); +extern void cgiSetCookie(const char *name, const char *value, + const char *path, const char *domain, + time_t expires, int secure); +extern ipp_attribute_t *cgiSetIPPObjectVars(ipp_attribute_t *obj, + const char *prefix, int element); +extern int cgiSetIPPVars(ipp_t *response, const char *filter_name, + const char *filter_value, + const char *prefix, int parent_el); +extern void cgiSetServerVersion(void); +extern void cgiSetSize(const char *name, int size); +extern void cgiSetVariable(const char *name, const char *value); +extern void cgiShowIPPError(const char *message); +extern void cgiShowJobs(http_t *http, const char *dest); +extern void cgiStartHTML(const char *title); +extern void cgiStartMultipart(void); +extern int cgiSupportsMultipart(void); +extern const char *cgiText(const char *message); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_CGI_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/classes.c b/cgi-bin/classes.c new file mode 100644 index 0000000000..91c2cb32b3 --- /dev/null +++ b/cgi-bin/classes.c @@ -0,0 +1,558 @@ +/* + * "$Id$" + * + * Class status CGI for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for CGI. + * do_class_op() - Do a class operation. + * show_all_classes() - Show all classes... + * show_class() - Show a single class. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" + + +/* + * Local functions... + */ + +static void do_class_op(http_t *http, const char *printer, ipp_op_t op, + const char *title); +static void show_all_classes(http_t *http, const char *username); +static void show_class(http_t *http, const char *printer); + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + const char *pclass; /* Class name */ + const char *user; /* Username */ + http_t *http; /* Connection to the server */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + const char *op; /* Operation to perform, if any */ + static const char *def_attrs[] = /* Attributes for default printer */ + { + "printer-name", + "printer-uri-supported" + }; + + + /* + * Get any form variables... + */ + + cgiInitialize(); + + op = cgiGetVariable("OP"); + + /* + * Set the web interface section... + */ + + cgiSetVariable("SECTION", "classes"); + cgiSetVariable("REFRESH_PAGE", ""); + + /* + * See if we are displaying a printer or all classes... + */ + + if ((pclass = getenv("PATH_INFO")) != NULL) + { + pclass ++; + + if (!*pclass) + pclass = NULL; + + if (pclass) + cgiSetVariable("PRINTER_NAME", pclass); + } + + /* + * See who is logged in... + */ + + user = getenv("REMOTE_USER"); + + /* + * Connect to the HTTP server... + */ + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + /* + * Get the default printer... + */ + + if (!op || !cgiIsPOST()) + { + /* + * Get the default destination... + */ + + request = ippNewRequest(CUPS_GET_DEFAULT); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs); + + 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 url[HTTP_MAX_URI]; /* New URL */ + + + cgiSetVariable("DEFAULT_URI", + cgiRewriteURL(attr->values[0].string.text, + url, sizeof(url), NULL)); + } + + ippDelete(response); + } + + /* + * See if we need to show a list of classes or the status of a + * single printer... + */ + + if (!pclass) + show_all_classes(http, user); + else + show_class(http, pclass); + } + else if (pclass) + { + if (!*op) + { + const char *server_port = getenv("SERVER_PORT"); + /* Port number string */ + int port = atoi(server_port ? server_port : "0"); + /* Port number */ + char uri[1024]; /* URL */ + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), + getenv("HTTPS") ? "https" : "http", NULL, + getenv("SERVER_NAME"), port, "/classes/%s", pclass); + + printf("Location: %s\n\n", uri); + } + else if (!strcmp(op, "start-class")) + do_class_op(http, pclass, IPP_RESUME_PRINTER, cgiText(_("Resume Class"))); + else if (!strcmp(op, "stop-class")) + do_class_op(http, pclass, IPP_PAUSE_PRINTER, cgiText(_("Pause Class"))); + else if (!strcmp(op, "accept-jobs")) + do_class_op(http, pclass, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs"))); + else if (!strcmp(op, "reject-jobs")) + do_class_op(http, pclass, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs"))); + else if (!strcmp(op, "purge-jobs")) + do_class_op(http, pclass, IPP_PURGE_JOBS, cgiText(_("Purge Jobs"))); + else if (!strcasecmp(op, "print-test-page")) + cgiPrintTestPage(http, pclass); + else if (!strcasecmp(op, "move-jobs")) + cgiMoveJobs(http, pclass, 0); + else + { + /* + * Unknown/bad operation... + */ + + cgiStartHTML(pclass); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + } + else + { + /* + * Unknown/bad operation... + */ + + cgiStartHTML(cgiText(_("Classes"))); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'do_class_op()' - Do a class operation. + */ + +static void +do_class_op(http_t *http, /* I - HTTP connection */ + const char *printer, /* I - Printer name */ + ipp_op_t op, /* I - Operation to perform */ + const char *title) /* I - Title of page */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI], /* Printer URI */ + resource[HTTP_MAX_URI]; /* Path for request */ + + + /* + * Build a printer request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(op); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + snprintf(resource, sizeof(resource), "/classes/%s", printer); + ippDelete(cupsDoRequest(http, request, resource)); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(title); + cgiShowIPPError(_("Unable to do maintenance command:")); + } + else + { + /* + * Redirect successful updates back to the printer page... + */ + + char url[1024], /* Printer/class URL */ + refresh[1024]; /* Refresh URL */ + + + cgiRewriteURL(uri, url, sizeof(url), NULL); + cgiFormEncode(uri, url, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + + cgiSetVariable("IS_CLASS", "YES"); + + if (op == IPP_PAUSE_PRINTER) + cgiCopyTemplateLang("printer-stop.tmpl"); + else if (op == IPP_RESUME_PRINTER) + cgiCopyTemplateLang("printer-start.tmpl"); + else if (op == CUPS_ACCEPT_JOBS) + cgiCopyTemplateLang("printer-accept.tmpl"); + else if (op == CUPS_REJECT_JOBS) + cgiCopyTemplateLang("printer-reject.tmpl"); + else if (op == IPP_PURGE_JOBS) + cgiCopyTemplateLang("printer-purge.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'show_all_classes()' - Show all classes... + */ + +static void +show_all_classes(http_t *http, /* I - Connection to server */ + const char *user) /* I - Username */ +{ + int i; /* Looping var */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + cups_array_t *classes; /* Array of class objects */ + ipp_attribute_t *pclass; /* Class object */ + int ascending, /* Order of classes (0 = descending) */ + first, /* First class to show */ + count; /* Number of classes */ + const char *var; /* Form variable */ + void *search; /* Search data */ + char val[1024]; /* Form variable */ + + + /* + * Show the standard header... + */ + + cgiStartHTML(cgiText(_("Classes"))); + + /* + * Build a CUPS_GET_CLASSES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requesting-user-name + */ + + request = ippNewRequest(CUPS_GET_CLASSES); + + if (user) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + cgiGetAttributes(request, "classes.tmpl"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Get a list of matching job objects. + */ + + if ((var = cgiGetVariable("QUERY")) != NULL && + !cgiGetVariable("CLEAR")) + search = cgiCompileSearch(var); + else + search = NULL; + + classes = cgiGetIPPObjects(response, search); + count = cupsArrayCount(classes); + + if (search) + cgiFreeSearch(search); + + /* + * Figure out which classes to display... + */ + + if ((var = cgiGetVariable("FIRST")) != NULL) + first = atoi(var); + else + first = 0; + + if (first >= count) + first = count - CUPS_PAGE_MAX; + + first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; + + if (first < 0) + first = 0; + + sprintf(val, "%d", count); + cgiSetVariable("TOTAL", val); + + if ((var = cgiGetVariable("ORDER")) != NULL) + ascending = !strcasecmp(var, "asc"); + else + ascending = 1; + + if (ascending) + { + for (i = 0, pclass = (ipp_attribute_t *)cupsArrayIndex(classes, first); + i < CUPS_PAGE_MAX && pclass; + i ++, pclass = (ipp_attribute_t *)cupsArrayNext(classes)) + cgiSetIPPObjectVars(pclass, NULL, i); + } + else + { + for (i = 0, pclass = (ipp_attribute_t *)cupsArrayIndex(classes, count - first - 1); + i < CUPS_PAGE_MAX && pclass; + i ++, pclass = (ipp_attribute_t *)cupsArrayPrev(classes)) + cgiSetIPPObjectVars(pclass, NULL, i); + } + + /* + * Save navigation URLs... + */ + + cgiSetVariable("THISURL", "/classes/"); + + if (first > 0) + { + sprintf(val, "%d", first - CUPS_PAGE_MAX); + cgiSetVariable("PREV", val); + } + + if ((first + CUPS_PAGE_MAX) < count) + { + sprintf(val, "%d", first + CUPS_PAGE_MAX); + cgiSetVariable("NEXT", val); + } + + /* + * Then show everything... + */ + + cgiCopyTemplateLang("search.tmpl"); + + cgiCopyTemplateLang("classes-header.tmpl"); + + if (count > CUPS_PAGE_MAX) + cgiCopyTemplateLang("pager.tmpl"); + + cgiCopyTemplateLang("classes.tmpl"); + + if (count > CUPS_PAGE_MAX) + cgiCopyTemplateLang("pager.tmpl"); + + /* + * Delete the response... + */ + + cupsArrayDelete(classes); + ippDelete(response); + } + else + { + /* + * Show the error... + */ + + cgiShowIPPError(_("Unable to get class list:")); + } + + cgiEndHTML(); +} + + +/* + * 'show_class()' - Show a single class. + */ + +static void +show_class(http_t *http, /* I - Connection to server */ + const char *pclass) /* I - Name of class */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + char refresh[1024]; /* Refresh URL */ + + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", pclass); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + + cgiGetAttributes(request, "class.tmpl"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Got the result; set the CGI variables and check the status of a + * single-queue request... + */ + + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + if (pclass && (attr = ippFindAttribute(response, "printer-state", + IPP_TAG_ENUM)) != NULL && + attr->values[0].integer == IPP_PRINTER_PROCESSING) + { + /* + * Class is processing - automatically refresh the page until we + * are done printing... + */ + + cgiFormEncode(uri, pclass, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "10;URL=/classes/%s", uri); + cgiSetVariable("refresh_page", refresh); + } + + /* + * Delete the response... + */ + + ippDelete(response); + + /* + * Show the standard header... + */ + + cgiStartHTML(pclass); + + /* + * Show the class status... + */ + + cgiCopyTemplateLang("class.tmpl"); + + /* + * Show jobs for the specified class... + */ + + cgiCopyTemplateLang("class-jobs-header.tmpl"); + cgiShowJobs(http, pclass); + } + else + { + /* + * Show the IPP error... + */ + + cgiStartHTML(pclass); + cgiShowIPPError(_("Unable to get class status:")); + } + + cgiEndHTML(); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/help-index.c b/cgi-bin/help-index.c new file mode 100644 index 0000000000..37e8b9d38c --- /dev/null +++ b/cgi-bin/help-index.c @@ -0,0 +1,1331 @@ +/* + * "$Id$" + * + * Online help index routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * helpDeleteIndex() - Delete an index, freeing all memory used. + * helpFindNode() - Find a node in an index. + * helpLoadIndex() - Load a help index from disk. + * helpSaveIndex() - Save a help index to disk. + * helpSearchIndex() - Search an index. + * help_add_word() - Add a word to a node. + * help_compile_search() - Convert a search string into a regular expression. + * help_delete_node() - Free all memory used by a node. + * help_delete_word() - Free all memory used by a word. + * help_load_directory() - Load a directory of files into an index. + * help_load_file() - Load a HTML files into an index. + * help_new_node() - Create a new node and add it to an index. + * help_sort_nodes_by_name() - Sort nodes by section, filename, and anchor. + * help_sort_nodes_by_score() - Sort nodes by score and text. + * help_sort_words() - Sort words alphabetically. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" +#include + + +/* + * List of common English words that should not be indexed... + */ + +static char help_common_words[][6] = + { + "about", + "all", + "an", + "and", + "are", + "as", + "at", + "be", + "been", + "but", + "by", + "call", + "can", + "come", + "could", + "day", + "did", + "do", + "down", + "each", + "find", + "first", + "for", + "from", + "go", + "had", + "has", + "have", + "he", + "her", + "him", + "his", + "hot", + "how", + "if", + "in", + "is", + "it", + "know", + "like", + "long", + "look", + "make", + "many", + "may", + "more", + "most", + "my", + "no", + "now", + "of", + "on", + "one", + "or", + "other", + "out", + "over", + "said", + "see", + "she", + "side", + "so", + "some", + "sound", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "thing", + "this", + "time", + "to", + "two", + "up", + "use", + "was", + "water", + "way", + "we", + "were", + "what", + "when", + "which", + "who", + "will", + "with", + "word", + "would", + "write", + "you", + "your" + }; + + +/* + * Local functions... + */ + +static help_word_t *help_add_word(help_node_t *n, const char *text); +static void help_delete_node(help_node_t *n); +static void help_delete_word(help_word_t *w); +static int help_load_directory(help_index_t *hi, + const char *directory, + const char *relative); +static int help_load_file(help_index_t *hi, + const char *filename, + const char *relative, + time_t mtime); +static help_node_t *help_new_node(const char *filename, const char *anchor, + const char *section, const char *text, + time_t mtime, off_t offset, + size_t length); +static int help_sort_by_name(help_node_t *p1, help_node_t *p2); +static int help_sort_by_score(help_node_t *p1, help_node_t *p2); +static int help_sort_words(help_word_t *w1, help_word_t *w2); + + +/* + * 'helpDeleteIndex()' - Delete an index, freeing all memory used. + */ + +void +helpDeleteIndex(help_index_t *hi) /* I - Help index */ +{ + help_node_t *node; /* Current node */ + + + DEBUG_printf(("helpDeleteIndex(hi=%p)\n", hi)); + + if (!hi) + return; + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes); + node; + node = (help_node_t *)cupsArrayNext(hi->nodes)) + { + if (!hi->search) + help_delete_node(node); + } + + cupsArrayDelete(hi->nodes); + cupsArrayDelete(hi->sorted); + + free(hi); +} + + +/* + * 'helpFindNode()' - Find a node in an index. + */ + +help_node_t * /* O - Node pointer or NULL */ +helpFindNode(help_index_t *hi, /* I - Index */ + const char *filename, /* I - Filename */ + const char *anchor) /* I - Anchor */ +{ + help_node_t key; /* Search key */ + + + DEBUG_printf(("helpFindNode(hi=%p, filename=\"%s\", anchor=\"%s\")\n", + hi, filename ? filename : "(nil)", anchor ? anchor : "(nil)")); + + /* + * Range check input... + */ + + if (!hi || !filename) + return (NULL); + + /* + * Initialize the search key... + */ + + key.filename = (char *)filename; + key.anchor = (char *)anchor; + + /* + * Return any match... + */ + + return ((help_node_t *)cupsArrayFind(hi->nodes, &key)); +} + + +/* + * 'helpLoadIndex()' - Load a help index from disk. + */ + +help_index_t * /* O - Index pointer or NULL */ +helpLoadIndex(const char *hifile, /* I - Index filename */ + const char *directory) /* I - Directory that is indexed */ +{ + help_index_t *hi; /* Help index */ + cups_file_t *fp; /* Current file */ + char line[2048], /* Line from file */ + *ptr, /* Pointer into line */ + *filename, /* Filename in line */ + *anchor, /* Anchor in line */ + *sectptr, /* Section pointer in line */ + section[1024], /* Section name */ + *text; /* Text in line */ + time_t mtime; /* Modification time */ + off_t offset; /* Offset into file */ + size_t length; /* Length in bytes */ + int update; /* Update? */ + help_node_t *node; /* Current node */ + help_word_t *word; /* Current word */ + + + DEBUG_printf(("helpLoadIndex(hifile=\"%s\", directory=\"%s\")\n", + hifile, directory)); + + /* + * Create a new, empty index. + */ + + if ((hi = (help_index_t *)calloc(1, sizeof(help_index_t))) == NULL) + return (NULL); + + hi->nodes = cupsArrayNew((cups_array_func_t)help_sort_by_name, NULL); + hi->sorted = cupsArrayNew((cups_array_func_t)help_sort_by_score, NULL); + + if (!hi->nodes || !hi->sorted) + { + cupsArrayDelete(hi->nodes); + cupsArrayDelete(hi->sorted); + free(hi); + return (NULL); + } + + /* + * Try loading the existing index file... + */ + + if ((fp = cupsFileOpen(hifile, "r")) != NULL) + { + /* + * Lock the file and then read the first line... + */ + + cupsFileLock(fp, 1); + + if (cupsFileGets(fp, line, sizeof(line)) && !strcmp(line, "HELPV2")) + { + /* + * Got a valid header line, now read the data lines... + */ + + node = NULL; + + while (cupsFileGets(fp, line, sizeof(line))) + { + /* + * Each line looks like one of the following: + * + * filename mtime offset length "section" "text" + * filename#anchor offset length "text" + * SP count word + */ + + if (line[0] == ' ') + { + /* + * Read a word in the current node... + */ + + if (!node || (ptr = strrchr(line, ' ')) == NULL) + continue; + + if ((word = help_add_word(node, ptr + 1)) != NULL) + word->count = atoi(line + 1); + } + else + { + /* + * Add a node... + */ + + filename = line; + + if ((ptr = strchr(line, ' ')) == NULL) + break; + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + + if ((anchor = strrchr(filename, '#')) != NULL) + { + *anchor++ = '\0'; + mtime = 0; + } + else + mtime = strtol(ptr, &ptr, 10); + + offset = strtoll(ptr, &ptr, 10); + length = strtoll(ptr, &ptr, 10); + + while (isspace(*ptr & 255)) + ptr ++; + + if (!anchor) + { + /* + * Get section... + */ + + if (*ptr != '\"') + break; + + ptr ++; + sectptr = ptr; + + while (*ptr && *ptr != '\"') + ptr ++; + + if (*ptr != '\"') + break; + + *ptr++ = '\0'; + + strlcpy(section, sectptr, sizeof(section)); + + while (isspace(*ptr & 255)) + ptr ++; + } + + if (*ptr != '\"') + break; + + ptr ++; + text = ptr; + + while (*ptr && *ptr != '\"') + ptr ++; + + if (*ptr != '\"') + break; + + *ptr++ = '\0'; + + if ((node = help_new_node(filename, anchor, section, text, + mtime, offset, length)) == NULL) + break; + + node->score = -1; + + cupsArrayAdd(hi->nodes, node); + } + } + } + + cupsFileClose(fp); + } + + /* + * Scan for new/updated files... + */ + + update = help_load_directory(hi, directory, NULL); + + /* + * Remove any files that are no longer installed... + */ + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes); + node; + node = (help_node_t *)cupsArrayNext(hi->nodes)) + if (node->score < 0) + { + /* + * Delete this node... + */ + + cupsArrayRemove(hi->nodes, node); + help_delete_node(node); + } + + /* + * Add nodes to the sorted array... + */ + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes); + node; + node = (help_node_t *)cupsArrayNext(hi->nodes)) + cupsArrayAdd(hi->sorted, node); + + /* + * Save the index if we updated it... + */ + + if (update) + helpSaveIndex(hi, hifile); + + /* + * Return the index... + */ + + return (hi); +} + + +/* + * 'helpSaveIndex()' - Save a help index to disk. + */ + +int /* O - 0 on success, -1 on error */ +helpSaveIndex(help_index_t *hi, /* I - Index */ + const char *hifile) /* I - Index filename */ +{ + cups_file_t *fp; /* Index file */ + help_node_t *node; /* Current node */ + help_word_t *word; /* Current word */ + + + DEBUG_printf(("helpSaveIndex(hi=%p, hifile=\"%s\")\n", hi, hifile)); + + /* + * Try creating a new index file... + */ + + if ((fp = cupsFileOpen(hifile, "w9")) == NULL) + return (-1); + + /* + * Lock the file while we write it... + */ + + cupsFileLock(fp, 1); + + cupsFilePuts(fp, "HELPV2\n"); + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes); + node; + node = (help_node_t *)cupsArrayNext(hi->nodes)) + { + /* + * Write the current node with/without the anchor... + */ + + if (node->anchor) + { + if (cupsFilePrintf(fp, "%s#%s " CUPS_LLFMT " " CUPS_LLFMT " \"%s\"\n", + node->filename, node->anchor, + CUPS_LLCAST node->offset, CUPS_LLCAST node->length, + node->text) < 0) + break; + } + else + { + if (cupsFilePrintf(fp, "%s %d " CUPS_LLFMT " " CUPS_LLFMT " \"%s\" \"%s\"\n", + node->filename, (int)node->mtime, + CUPS_LLCAST node->offset, CUPS_LLCAST node->length, + node->section ? node->section : "", node->text) < 0) + break; + } + + /* + * Then write the words associated with the node... + */ + + for (word = (help_word_t *)cupsArrayFirst(node->words); + word; + word = (help_word_t *)cupsArrayNext(node->words)) + if (cupsFilePrintf(fp, " %d %s\n", word->count, word->text) < 0) + break; + } + + cupsFileFlush(fp); + + if (cupsFileClose(fp) < 0) + return (-1); + else if (node) + return (-1); + else + return (0); +} + + +/* + * 'helpSearchIndex()' - Search an index. + */ + +help_index_t * /* O - Search index */ +helpSearchIndex(help_index_t *hi, /* I - Index */ + const char *query, /* I - Query string */ + const char *section, /* I - Limit search to this section */ + const char *filename) /* I - Limit search to this file */ +{ + help_index_t *search; /* Search index */ + help_node_t *node; /* Current node */ + help_word_t *word; /* Current word */ + void *sc; /* Search context */ + int matches; /* Number of matches */ + + + DEBUG_printf(("helpSearchIndex(hi=%p, query=\"%s\", filename=\"%s\")\n", + hi, query ? query : "(nil)", + filename ? filename : "(nil)")); + + /* + * Range check... + */ + + if (!hi || !query) + return (NULL); + + /* + * Reset the scores of all nodes to 0... + */ + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes); + node; + node = (help_node_t *)cupsArrayNext(hi->nodes)) + node->score = 0; + + /* + * Find the first node to search in... + */ + + if (filename) + { + node = helpFindNode(hi, filename, NULL); + if (!node) + return (NULL); + } + else + node = (help_node_t *)cupsArrayFirst(hi->nodes); + + /* + * Convert the query into a regular expression... + */ + + sc = cgiCompileSearch(query); + if (!sc) + return (NULL); + + /* + * Allocate a search index... + */ + + search = calloc(1, sizeof(help_index_t)); + if (!search) + { + cgiFreeSearch(sc); + return (NULL); + } + + search->nodes = cupsArrayNew((cups_array_func_t)help_sort_by_name, NULL); + search->sorted = cupsArrayNew((cups_array_func_t)help_sort_by_score, NULL); + + if (!search->nodes || !search->sorted) + { + cupsArrayDelete(search->nodes); + cupsArrayDelete(search->sorted); + free(search); + cgiFreeSearch(sc); + return (NULL); + } + + search->search = 1; + + /* + * Check each node in the index, adding matching nodes to the + * search index... + */ + + for (; node; node = (help_node_t *)cupsArrayNext(hi->nodes)) + if (section && strcmp(node->section, section)) + continue; + else if (filename && strcmp(node->filename, filename)) + continue; + else + { + matches = cgiDoSearch(sc, node->text); + + for (word = (help_word_t *)cupsArrayFirst(node->words); + word; + word = (help_word_t *)cupsArrayNext(node->words)) + if (cgiDoSearch(sc, word->text) > 0) + matches += word->count; + + if (matches > 0) + { + /* + * Found a match, add the node to the search index... + */ + + node->score = matches; + + cupsArrayAdd(search->nodes, node); + cupsArrayAdd(search->sorted, node); + } + } + + /* + * Free the search context... + */ + + cgiFreeSearch(sc); + + /* + * Return the results... + */ + + return (search); +} + + +/* + * 'help_add_word()' - Add a word to a node. + */ + +static help_word_t * /* O - New word */ +help_add_word(help_node_t *n, /* I - Node */ + const char *text) /* I - Word text */ +{ + help_word_t *w, /* New word */ + key; /* Search key */ + + + DEBUG_printf(("help_add_word(n=%p, text=\"%s\")\n", n, text)); + + /* + * Create the words array as needed... + */ + + if (!n->words) + n->words = cupsArrayNew((cups_array_func_t)help_sort_words, NULL); + + /* + * See if the word is already added... + */ + + key.text = (char *)text; + + if ((w = (help_word_t *)cupsArrayFind(n->words, &key)) == NULL) + { + /* + * Create a new word... + */ + + if ((w = calloc(1, sizeof(help_word_t))) == NULL) + return (NULL); + + if ((w->text = strdup(text)) == NULL) + { + free(w); + return (NULL); + } + + cupsArrayAdd(n->words, w); + } + + /* + * Bump the counter for this word and return it... + */ + + w->count ++; + + return (w); +} + + +/* + * 'help_delete_node()' - Free all memory used by a node. + */ + +static void +help_delete_node(help_node_t *n) /* I - Node */ +{ + help_word_t *w; /* Current word */ + + + DEBUG_printf(("help_delete_node(n=%p)\n", n)); + + if (!n) + return; + + if (n->filename) + free(n->filename); + + if (n->anchor) + free(n->anchor); + + if (n->section) + free(n->section); + + if (n->text) + free(n->text); + + for (w = (help_word_t *)cupsArrayFirst(n->words); + w; + w = (help_word_t *)cupsArrayNext(n->words)) + help_delete_word(w); + + cupsArrayDelete(n->words); + + free(n); +} + + +/* + * 'help_delete_word()' - Free all memory used by a word. + */ + +static void +help_delete_word(help_word_t *w) /* I - Word */ +{ + DEBUG_printf(("help_delete_word(w=%p)\n", w)); + + if (!w) + return; + + if (w->text) + free(w->text); + + free(w); +} + + +/* + * 'help_load_directory()' - Load a directory of files into an index. + */ + +static int /* O - 0 = success, -1 = error, 1 = updated */ +help_load_directory( + help_index_t *hi, /* I - Index */ + const char *directory, /* I - Directory */ + const char *relative) /* I - Relative path */ +{ + cups_dir_t *dir; /* Directory file */ + cups_dentry_t *dent; /* Directory entry */ + char *ext, /* Pointer to extension */ + filename[1024], /* Full filename */ + relname[1024]; /* Relative filename */ + int update; /* Updated? */ + help_node_t *node; /* Current node */ + + + DEBUG_printf(("help_load_directory(hi=%p, directory=\"%s\", relative=\"%s\")\n", + hi, directory ? directory : "(nil)", relative ? relative : "(nil)")); + + /* + * Open the directory and scan it... + */ + + if ((dir = cupsDirOpen(directory)) == NULL) + return (0); + + update = 0; + + while ((dent = cupsDirRead(dir)) != NULL) + { + /* + * Skip "." files... + */ + + if (dent->filename[0] == '.') + continue; + + /* + * Get absolute and relative filenames... + */ + + snprintf(filename, sizeof(filename), "%s/%s", directory, dent->filename); + if (relative) + snprintf(relname, sizeof(relname), "%s/%s", relative, dent->filename); + else + strlcpy(relname, dent->filename, sizeof(relname)); + + /* + * Check if we have a HTML file... + */ + + if ((ext = strstr(dent->filename, ".html")) != NULL && + (!ext[5] || !strcmp(ext + 5, ".gz"))) + { + /* + * HTML file, see if we have already indexed the file... + */ + + if ((node = helpFindNode(hi, relname, NULL)) != NULL) + { + /* + * File already indexed - check dates to confirm that the + * index is up-to-date... + */ + + if (node->mtime == dent->fileinfo.st_mtime) + { + /* + * Same modification time, so mark all of the nodes + * for this file as up-to-date... + */ + + for (; node; node = (help_node_t *)cupsArrayNext(hi->nodes)) + if (!strcmp(node->filename, relname)) + node->score = 0; + else + break; + + continue; + } + } + + update = 1; + + help_load_file(hi, filename, relname, dent->fileinfo.st_mtime); + } + else if (S_ISDIR(dent->fileinfo.st_mode)) + { + /* + * Process sub-directory... + */ + + if (help_load_directory(hi, filename, relname) == 1) + update = 1; + } + } + + cupsDirClose(dir); + + return (update); +} + + +/* + * 'help_load_file()' - Load a HTML files into an index. + */ + +static int /* O - 0 = success, -1 = error */ +help_load_file( + help_index_t *hi, /* I - Index */ + const char *filename, /* I - Filename */ + const char *relative, /* I - Relative path */ + time_t mtime) /* I - Modification time */ +{ + cups_file_t *fp; /* HTML file */ + help_node_t *node; /* Current node */ + char line[1024], /* Line from file */ + temp[1024], /* Temporary word */ + section[1024], /* Section */ + *ptr, /* Pointer into line */ + *anchor, /* Anchor name */ + *text; /* Text for anchor */ + off_t offset; /* File offset */ + char quote; /* Quote character */ + help_word_t *word; /* Current word */ + int wordlen; /* Length of word */ + + + DEBUG_printf(("help_load_file(hi=%p, filename=\"%s\", relative=\"%s\", mtime=%ld)\n", + hi, filename ? filename : "(nil)", + relative ? relative : "(nil)", mtime)); + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + return (-1); + + node = NULL; + offset = 0; + + strcpy(section, "Other"); + + while (cupsFileGets(fp, line, sizeof(line))) + { + /* + * Look for "", "<A NAME", or "<!-- SECTION:" prefix... + */ + + if (!strncasecmp(line, "<!-- SECTION:", 13)) + { + /* + * Got section line, copy it! + */ + + for (ptr = line + 13; isspace(*ptr & 255); ptr ++); + + strlcpy(section, ptr, sizeof(section)); + if ((ptr = strstr(section, "-->")) != NULL) + { + /* + * Strip comment stuff from end of line... + */ + + for (*ptr-- = '\0'; ptr > line && isspace(*ptr & 255); *ptr-- = '\0'); + + if (isspace(*ptr & 255)) + *ptr = '\0'; + } + continue; + } + + for (ptr = line; (ptr = strchr(ptr, '<')) != NULL;) + { + ptr ++; + + if (!strncasecmp(ptr, "TITLE>", 6)) + { + /* + * Found the title... + */ + + anchor = NULL; + ptr += 6; + } + else if (!strncasecmp(ptr, "A NAME=", 7)) + { + /* + * Found an anchor... + */ + + ptr += 7; + + if (*ptr == '\"' || *ptr == '\'') + { + /* + * Get quoted anchor... + */ + + quote = *ptr; + anchor = ptr + 1; + if ((ptr = strchr(anchor, quote)) != NULL) + *ptr++ = '\0'; + else + break; + } + else + { + /* + * Get unquoted anchor... + */ + + anchor = ptr + 1; + + for (ptr = anchor; *ptr && *ptr != '>' && !isspace(*ptr & 255); ptr ++); + + if (*ptr) + *ptr++ = '\0'; + else + break; + } + + /* + * Got the anchor, now lets find the end... + */ + + while (*ptr && *ptr != '>') + ptr ++; + + if (*ptr != '>') + break; + + ptr ++; + } + else + continue; + + /* + * Now collect text for the link... + */ + + text = ptr; + while ((ptr = strchr(text, '<')) == NULL) + { + ptr = text + strlen(text); + if (ptr >= (line + sizeof(line) - 2)) + break; + + *ptr++ = ' '; + + if (!cupsFileGets(fp, ptr, sizeof(line) - (ptr - line) - 1)) + break; + } + + *ptr = '\0'; + + if (node) + node->length = offset - node->offset; + + if (!*text) + { + node = NULL; + break; + } + + if ((node = helpFindNode(hi, relative, anchor)) != NULL) + { + /* + * Node already in the index, so replace the text and other + * data... + */ + + cupsArrayRemove(hi->nodes, node); + + if (node->section) + free(node->section); + + if (node->text) + free(node->text); + + if (node->words) + { + for (word = (help_word_t *)cupsArrayFirst(node->words); + word; + word = (help_word_t *)cupsArrayNext(node->words)) + help_delete_word(word); + + cupsArrayDelete(node->words); + node->words = NULL; + } + + node->section = section[0] ? strdup(section) : NULL; + node->text = strdup(text); + node->mtime = mtime; + node->offset = offset; + node->score = 0; + } + else + { + /* + * New node... + */ + + node = help_new_node(relative, anchor, section, text, mtime, offset, 0); + } + + /* + * Go through the text value and replace tabs and newlines with + * whitespace and eliminate extra whitespace... + */ + + for (ptr = node->text, text = node->text; *ptr;) + if (isspace(*ptr & 255)) + { + while (isspace(*ptr & 255)) + ptr ++; + + *text++ = ' '; + } + else if (text != ptr) + *text++ = *ptr++; + else + { + text ++; + ptr ++; + } + + *text = '\0'; + + /* + * (Re)add the node to the array... + */ + + cupsArrayAdd(hi->nodes, node); + + if (!anchor) + node = NULL; + break; + } + + if (node) + { + /* + * Scan this line for words... + */ + + for (ptr = line; *ptr; ptr ++) + { + /* + * Skip HTML stuff... + */ + + if (*ptr == '<') + { + if (!strncmp(ptr, "<!--", 4)) + { + /* + * Skip HTML comment... + */ + + if ((text = strstr(ptr + 4, "-->")) == NULL) + ptr += strlen(ptr) - 1; + else + ptr = text + 2; + } + else + { + /* + * Skip HTML element... + */ + + for (ptr ++; *ptr && *ptr != '>'; ptr ++) + { + if (*ptr == '\"' || *ptr == '\'') + { + for (quote = *ptr++; *ptr && *ptr != quote; ptr ++); + + if (!*ptr) + ptr --; + } + } + + if (!*ptr) + ptr --; + } + + continue; + } + else if (*ptr == '&') + { + /* + * Skip HTML entity... + */ + + for (ptr ++; *ptr && *ptr != ';'; ptr ++); + + if (!*ptr) + ptr --; + + continue; + } + else if (!isalnum(*ptr & 255)) + continue; + + /* + * Found the start of a word, search until we find the end... + */ + + for (text = ptr, ptr ++; *ptr && isalnum(*ptr & 255); ptr ++); + + wordlen = ptr - text; + + memcpy(temp, text, wordlen); + temp[wordlen] = '\0'; + + ptr --; + + if (wordlen > 1 && !bsearch(temp, help_common_words, + (sizeof(help_common_words) / + sizeof(help_common_words[0])), + sizeof(help_common_words[0]), + (int (*)(const void *, const void *)) + strcasecmp)) + help_add_word(node, temp); + } + } + + /* + * Get the offset of the next line... + */ + + offset = cupsFileTell(fp); + } + + cupsFileClose(fp); + + if (node) + node->length = offset - node->offset; + + return (0); +} + + +/* + * 'help_new_node()' - Create a new node and add it to an index. + */ + +static help_node_t * /* O - Node pointer or NULL on error */ +help_new_node(const char *filename, /* I - Filename */ + const char *anchor, /* I - Anchor */ + const char *section, /* I - Section */ + const char *text, /* I - Text */ + time_t mtime, /* I - Modification time */ + off_t offset, /* I - Offset in file */ + size_t length) /* I - Length in bytes */ +{ + help_node_t *n; /* Node */ + + + DEBUG_printf(("help_new_node(filename=\"%s\", anchor=\"%s\", text=\"%s\", " + "mtime=%ld, offset=%ld, length=%ld)\n", + filename ? filename : "(nil)", anchor ? anchor : "(nil)", + text ? text : "(nil)", (long)mtime, (long)offset, + (long)length)); + + n = (help_node_t *)calloc(1, sizeof(help_node_t)); + if (!n) + return (NULL); + + n->filename = strdup(filename); + n->anchor = anchor ? strdup(anchor) : NULL; + n->section = (section && *section) ? strdup(section) : NULL; + n->text = strdup(text); + n->mtime = mtime; + n->offset = offset; + n->length = length; + + return (n); +} + + +/* + * 'help_sort_nodes_by_name()' - Sort nodes by section, filename, and anchor. + */ + +static int /* O - Difference */ +help_sort_by_name(help_node_t *n1, /* I - First node */ + help_node_t *n2) /* I - Second node */ +{ + int diff; /* Difference */ + + + DEBUG_printf(("help_sort_by_name(n1=%p(%s#%s), n2=%p(%s#%s)\n", + n1, n1->filename, n1->anchor ? n1->anchor : "", + n2, n2->filename, n2->anchor ? n2->anchor : "")); + + if ((diff = strcmp(n1->filename, n2->filename)) != 0) + return (diff); + + if (!n1->anchor && !n2->anchor) + return (0); + else if (!n1->anchor) + return (-1); + else if (!n2->anchor) + return (1); + else + return (strcmp(n1->anchor, n2->anchor)); +} + + +/* + * 'help_sort_nodes_by_score()' - Sort nodes by score and text. + */ + +static int /* O - Difference */ +help_sort_by_score(help_node_t *n1, /* I - First node */ + help_node_t *n2) /* I - Second node */ +{ + int diff; /* Difference */ + + + DEBUG_printf(("help_sort_by_score(n1=%p(%d \"%s\" \"%s\"), " + "n2=%p(%d \"%s\" \"%s\")\n", + n1, n1->score, n1->section ? n1->section : "", n1->text, + n2, n2->score, n2->section ? n2->section : "", n2->text)); + + if (n1->score != n2->score) + return (n2->score - n1->score); + + if (n1->section && !n2->section) + return (1); + else if (!n1->section && n2->section) + return (-1); + else if (n1->section && n2->section && + (diff = strcmp(n1->section, n2->section)) != 0) + return (diff); + + return (strcasecmp(n1->text, n2->text)); +} + + +/* + * 'help_sort_words()' - Sort words alphabetically. + */ + +static int /* O - Difference */ +help_sort_words(help_word_t *w1, /* I - Second word */ + help_word_t *w2) /* I - Second word */ +{ + DEBUG_printf(("help_sort_words(w1=%p(\"%s\"), w2=%p(\"%s\"))\n", + w1, w1->text, w2, w2->text)); + + return (strcasecmp(w1->text, w2->text)); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/help-index.h b/cgi-bin/help-index.h new file mode 100644 index 0000000000..bd9350eb0e --- /dev/null +++ b/cgi-bin/help-index.h @@ -0,0 +1,87 @@ +/* + * "$Id$" + * + * Online help index definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_HELP_INDEX_H_ +# define _CUPS_HELP_INDEX_H_ + +/* + * Include necessary headers... + */ + +# include <cups/array.h> + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Data structures... + */ + +typedef struct help_word_s /**** Help word structure... ****/ +{ + int count; /* Number of occurrences */ + char *text; /* Word text */ +} help_word_t; + +typedef struct help_node_s /**** Help node structure... ****/ +{ + char *filename; /* Filename, relative to help dir */ + char *section; /* Section name (NULL if none) */ + char *anchor; /* Anchor name (NULL if none) */ + char *text; /* Text in anchor */ + cups_array_t *words; /* Words after this node */ + time_t mtime; /* Last modification time */ + off_t offset; /* Offset in file */ + size_t length; /* Length in bytes */ + int score; /* Search score */ +} help_node_t; + +typedef struct help_index_s /**** Help index structure ****/ +{ + int search; /* 1 = search index, 0 = normal */ + cups_array_t *nodes; /* Nodes sorted by filename */ + cups_array_t *sorted; /* Nodes sorted by score + text */ +} help_index_t; + + +/* + * Functions... + */ + +extern void helpDeleteIndex(help_index_t *hi); +extern help_node_t *helpFindNode(help_index_t *hi, const char *filename, + const char *anchor); +extern help_index_t *helpLoadIndex(const char *hifile, const char *directory); +extern int helpSaveIndex(help_index_t *hi, const char *hifile); +extern help_index_t *helpSearchIndex(help_index_t *hi, const char *query, + const char *section, + const char *filename); + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_HELP_INDEX_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/help.c b/cgi-bin/help.c new file mode 100644 index 0000000000..7c0b6b628a --- /dev/null +++ b/cgi-bin/help.c @@ -0,0 +1,392 @@ +/* + * "$Id$" + * + * Online help CGI for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for CGI. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.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 */ +{ + help_index_t *hi, /* Help index */ + *si; /* Search index */ + help_node_t *n; /* Current help node */ + int i; /* Looping var */ + const char *query; /* Search query */ + const char *cache_dir; /* CUPS_CACHEDIR environment variable */ + const char *docroot; /* CUPS_DOCROOT environment variable */ + const char *helpfile; /* Current help file */ + const char *topic; /* Current topic */ + char topic_data[1024]; /* Topic form data */ + const char *section; /* Current section */ + char filename[1024], /* Filename */ + directory[1024]; /* Directory */ + cups_file_t *fp; /* Help file */ + char line[1024]; /* Line from file */ + int printable; /* Show printable version? */ + + + /* + * Get any form variables... + */ + + cgiInitialize(); + + printable = cgiGetVariable("PRINTABLE") != NULL; + + /* + * Set the web interface section... + */ + + cgiSetVariable("SECTION", "help"); + cgiSetVariable("REFRESH_PAGE", ""); + + /* + * Load the help index... + */ + + if ((cache_dir = getenv("CUPS_CACHEDIR")) == NULL) + cache_dir = CUPS_CACHEDIR; + + snprintf(filename, sizeof(filename), "%s/help.index", cache_dir); + + if ((docroot = getenv("CUPS_DOCROOT")) == NULL) + docroot = CUPS_DOCROOT; + + snprintf(directory, sizeof(directory), "%s/help", docroot); + + fprintf(stderr, "DEBUG: helpLoadIndex(filename=\"%s\", directory=\"%s\")\n", + filename, directory); + + hi = helpLoadIndex(filename, directory); + if (!hi) + { + perror(filename); + + cgiStartHTML(cgiText(_("Online Help"))); + cgiSetVariable("ERROR", "Unable to load help index!"); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + return (1); + } + + fprintf(stderr, "DEBUG: %d nodes in help index...\n", + cupsArrayCount(hi->nodes)); + + /* + * See if we are viewing a file... + */ + + for (i = 0; i < argc; i ++) + fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + + if ((helpfile = getenv("PATH_INFO")) != NULL) + { + helpfile ++; + + if (!*helpfile) + helpfile = NULL; + } + + if (helpfile) + { + /* + * Verify that the help file exists and is part of the index... + */ + + snprintf(filename, sizeof(filename), "%s/help/%s", docroot, helpfile); + + fprintf(stderr, "DEBUG: helpfile=\"%s\", filename=\"%s\"\n", + helpfile, filename); + + if (access(filename, R_OK)) + { + perror(filename); + + cgiStartHTML(cgiText(_("Online Help"))); + cgiSetVariable("ERROR", "Unable to access help file!"); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + return (1); + } + + if ((n = helpFindNode(hi, helpfile, NULL)) == NULL) + { + cgiStartHTML(cgiText(_("Online Help"))); + cgiSetVariable("ERROR", "Help file not in index!"); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + return (1); + } + + /* + * Set the page title and save the help file... + */ + + cgiSetVariable("HELPFILE", helpfile); + cgiSetVariable("HELPTITLE", n->text); + cgiSetVariable("TOPIC", n->section); + + /* + * Send a standard page header... + */ + + if (printable) + puts("Content-Type: text/html;charset=utf-8\n"); + else + cgiStartHTML(n->text); + } + else + { + /* + * Send a standard page header... + */ + + cgiStartHTML(cgiText(_("Online Help"))); + } + + /* + * Do a search as needed... + */ + + if (cgiGetVariable("CLEAR")) + cgiSetVariable("QUERY", ""); + + query = cgiGetVariable("QUERY"); + topic = cgiGetVariable("TOPIC"); + si = helpSearchIndex(hi, query, topic, helpfile); + + cgiClearVariables(); + if (query) + cgiSetVariable("QUERY", query); + if (topic) + cgiSetVariable("TOPIC", topic); + + fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n", + query ? query : "(null)", topic ? topic : "(null)"); + + if (si) + { + help_node_t *nn; /* Parent node */ + + + fprintf(stderr, + "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si, + si->sorted, cupsArrayCount(si->sorted)); + + for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted); + n; + i ++, n = (help_node_t *)cupsArrayNext(si->sorted)) + { + if (helpfile && n->anchor) + snprintf(line, sizeof(line), "#%s", n->anchor); + else if (n->anchor) + snprintf(line, sizeof(line), "/help/%s?QUERY=%s#%s", n->filename, + query ? query : "", n->anchor); + else + snprintf(line, sizeof(line), "/help/%s?QUERY=%s", n->filename, + query ? query : ""); + + cgiSetArray("QTEXT", i, n->text); + cgiSetArray("QLINK", i, line); + + if (!helpfile && n->anchor) + { + nn = helpFindNode(hi, n->filename, NULL); + + snprintf(line, sizeof(line), "/help/%s?QUERY=%s", nn->filename, + query ? query : ""); + + cgiSetArray("QPTEXT", i, nn->text); + cgiSetArray("QPLINK", i, line); + } + else + { + cgiSetArray("QPTEXT", i, ""); + cgiSetArray("QPLINK", i, ""); + } + + fprintf(stderr, "DEBUG: [%d] = \"%s\" @ \"%s\"\n", i, n->text, line); + } + + helpDeleteIndex(si); + } + + /* + * OK, now list the bookmarks within the index... + */ + + for (i = 0, section = NULL, n = (help_node_t *)cupsArrayFirst(hi->sorted); + n; + n = (help_node_t *)cupsArrayNext(hi->sorted)) + { + if (n->anchor) + continue; + + /* + * Add a section link as needed... + */ + + if (n->section && + (!section || strcmp(n->section, section))) + { + /* + * Add a link for this node... + */ + + snprintf(line, sizeof(line), "/help/?TOPIC=%s&QUERY=%s", + cgiFormEncode(topic_data, n->section, sizeof(topic_data)), + query ? query : ""); + cgiSetArray("BMLINK", i, line); + cgiSetArray("BMTEXT", i, n->section); + cgiSetArray("BMINDENT", i, "0"); + + i ++; + section = n->section; + } + + if (!topic || strcmp(n->section, topic)) + continue; + + /* + * Add a link for this node... + */ + + snprintf(line, sizeof(line), "/help/%s?TOPIC=%s&QUERY=%s", n->filename, + cgiFormEncode(topic_data, n->section, sizeof(topic_data)), + query ? query : ""); + cgiSetArray("BMLINK", i, line); + cgiSetArray("BMTEXT", i, n->text); + cgiSetArray("BMINDENT", i, "1"); + + i ++; + + if (helpfile && !strcmp(helpfile, n->filename)) + { + help_node_t *nn; /* Pointer to sub-node */ + + + cupsArraySave(hi->sorted); + + for (nn = (help_node_t *)cupsArrayFirst(hi->sorted); + nn; + nn = (help_node_t *)cupsArrayNext(hi->sorted)) + if (nn->anchor && !strcmp(helpfile, nn->filename)) + { + /* + * Add a link for this node... + */ + + snprintf(line, sizeof(line), "#%s", nn->anchor); + cgiSetArray("BMLINK", i, line); + cgiSetArray("BMTEXT", i, nn->text); + cgiSetArray("BMINDENT", i, "2"); + + i ++; + } + + cupsArrayRestore(hi->sorted); + } + } + + /* + * Show the search and bookmark content... + */ + + if (!helpfile || !printable) + cgiCopyTemplateLang("help-header.tmpl"); + else + cgiCopyTemplateLang("help-printable.tmpl"); + + /* + * If we are viewing a file, copy it in now... + */ + + if (helpfile) + { + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + int inbody; /* Are we inside the body? */ + + + inbody = 0; + + while (cupsFileGets(fp, line, sizeof(line))) + { + if (inbody) + { + if (!strncasecmp(line, "</BODY>", 7)) + break; + + printf("%s\n", line); + } + else if (!strncasecmp(line, "<BODY", 5)) + inbody = 1; + } + + cupsFileClose(fp); + } + else + { + perror(filename); + cgiSetVariable("ERROR", "Unable to open help file."); + cgiCopyTemplateLang("error.tmpl"); + } + } + + /* + * Send a standard trailer... + */ + + if (!printable) + { + cgiCopyTemplateLang("help-trailer.tmpl"); + cgiEndHTML(); + } + else + puts("</BODY>\n</HTML>"); + + /* + * Delete the index... + */ + + helpDeleteIndex(hi); + + /* + * 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 0000000000..9db5438ebf --- /dev/null +++ b/cgi-bin/html.c @@ -0,0 +1,239 @@ +/* + * "$Id$" + * + * HTML support functions for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cgiEndHTML() - End a HTML page. + * cgiEndMultipart() - End the delivery of a multipart web page. + * cgiFormEncode() - Encode a string as a form variable. + * cgiStartHTML() - Start a HTML page. + * cgiStartMultipart() - Start a multipart delivery of a web page. + * cgiSupportsMultipart() - Does the browser support multi-part documents? + * cgi_null_passwd() - Return a NULL password for authentication. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" + + +/* + * Local globals... + */ + +static const char *cgi_multipart = NULL; + /* Multipart separator, if any */ + + +/* + * Local functions... + */ + +static const char *cgi_null_passwd(const char *prompt); + + +/* + * 'cgiEndHTML()' - End a HTML page. + */ + +void +cgiEndHTML(void) +{ + /* + * Send the standard trailer... + */ + + cgiCopyTemplateLang("trailer.tmpl"); +} + + +/* + * 'cgiEndMultipart()' - End the delivery of a multipart web page. + */ + +void +cgiEndMultipart(void) +{ + if (cgi_multipart) + { + printf("\n%s--\n", cgi_multipart); + fflush(stdout); + } +} + + +/* + * 'cgiFormEncode()' - Encode a string as a form variable. + */ + +char * /* O - Destination string */ +cgiFormEncode(char *dst, /* I - Destination string */ + const char *src, /* I - Source string */ + size_t dstsize) /* I - Size of destination string */ +{ + char *dstptr, /* Pointer into destination */ + *dstend; /* End of destination */ + static const char *hex = /* Hexadecimal characters */ + "0123456789ABCDEF"; + + + /* + * Mark the end of the string... + */ + + dstend = dst + dstsize - 1; + + /* + * Loop through the source string and copy... + */ + + for (dstptr = dst; *src && dstptr < dstend;) + { + switch (*src) + { + case ' ' : + /* + * Encode spaces with a "+"... + */ + + *dstptr++ = '+'; + src ++; + break; + + case '&' : + case '%' : + case '+' : + /* + * Encode special characters with %XX escape... + */ + + if (dstptr < (dstend - 2)) + { + *dstptr++ = '%'; + *dstptr++ = hex[(*src & 255) >> 4]; + *dstptr++ = hex[*src & 15]; + src ++; + } + break; + + default : + /* + * Copy other characters literally... + */ + + *dstptr++ = *src++; + break; + } + } + + /* + * Nul-terminate the destination string... + */ + + *dstptr = '\0'; + + /* + * Return the encoded string... + */ + + return (dst); +} + + +/* + * 'cgiStartHTML()' - Start a HTML page. + */ + +void +cgiStartHTML(const char *title) /* I - Title of page */ +{ + /* + * Disable any further authentication attempts... + */ + + cupsSetPasswordCB(cgi_null_passwd); + + /* + * Tell the client to expect UTF-8 encoded HTML... + */ + + if (cgi_multipart) + puts(cgi_multipart); + + puts("Content-Type: text/html;charset=utf-8\n"); + + /* + * Send a standard header... + */ + + cgiSetVariable("TITLE", title); + cgiSetServerVersion(); + + cgiCopyTemplateLang("header.tmpl"); +} + + +/* + * 'cgiStartMultipart()' - Start a multipart delivery of a web page. + */ + +void +cgiStartMultipart(void) +{ + puts("MIME-Version: 1.0\n" + "Content-Type: multipart/x-mixed-replace; boundary=\"CUPS-MULTIPART\"\n"); + fflush(stdout); + + cgi_multipart = "--CUPS-MULTIPART"; +} + + +/* + * 'cgiSupportsMultipart()' - Does the browser support multi-part documents? + */ + +int /* O - 1 if multi-part supported, 0 otherwise */ +cgiSupportsMultipart(void) +{ + /* + * Too many bug reports for browsers that don't support it, and too much pain + * to whitelist known-good browsers, so for now we just punt on multi-part + * support... :( + */ + + return (0); +} + + +/* + * 'cgi_null_passwd()' - Return a NULL password for authentication. + */ + +static const char * /* O - NULL */ +cgi_null_passwd(const char *prompt) /* I - Prompt string (unused) */ +{ + (void)prompt; + + fprintf(stderr, "DEBUG: cgi_null_passwd(prompt=\"%s\") called!\n", + prompt ? prompt : "(null)"); + + return (NULL); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c new file mode 100644 index 0000000000..6440879581 --- /dev/null +++ b/cgi-bin/ipp-var.c @@ -0,0 +1,1592 @@ +/* + * "$Id$" + * + * CGI <-> IPP variable routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cgiGetAttributes() - Get the list of attributes that are needed by the + * template file. + * cgiGetIPPObjects() - Get the objects in an IPP response. + * cgiMoveJobs() - Move one or more jobs. + * cgiPrintCommand() - Print a CUPS command job. + * cgiPrintTestPage() - Print a test page. + * cgiRewriteURL() - Rewrite a printer URI into a web browser URL... + * cgiSetIPPObjectVars() - Set CGI variables from an IPP object. + * cgiSetIPPVars() - Set CGI variables from an IPP response. + * cgiShowIPPError() - Show the last IPP error message. + * cgiShowJobs() - Show print jobs. + * cgiText() - Return localized text. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" + + +/* + * 'cgiGetAttributes()' - Get the list of attributes that are needed + * by the template file. + */ + +void +cgiGetAttributes(ipp_t *request, /* I - IPP request */ + const char *tmpl) /* I - Base filename */ +{ + int num_attrs; /* Number of attributes */ + char *attrs[1000]; /* Attributes */ + int i; /* Looping var */ + char filename[1024], /* Filename */ + locale[16]; /* Locale name */ + const char *directory, /* Directory */ + *lang; /* Language */ + FILE *in; /* Input file */ + int ch; /* Character from file */ + char name[255], /* Name of variable */ + *nameptr; /* Pointer into name */ + + + /* + * Convert the language to a locale name... + */ + + if ((lang = getenv("LANG")) != NULL) + { + for (i = 0; lang[i] && i < 15; i ++) + if (isalnum(lang[i] & 255)) + 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... + */ + + directory = cgiGetTemplateDir(); + + 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; + + /* + * Loop through the file adding attribute names as needed... + */ + + num_attrs = 0; + attrs[0] = NULL; /* Eliminate compiler warning */ + + while ((ch = getc(in)) != EOF) + if (ch == '\\') + getc(in); + else if (ch == '{' && num_attrs < (sizeof(attrs) / sizeof(attrs[0]))) + { + /* + * Grab the name... + */ + + for (nameptr = name; (ch = getc(in)) != EOF;) + if (strchr("}]<>=!~ \t\n", ch)) + break; + else if (nameptr > name && ch == '?') + break; + else if (nameptr < (name + sizeof(name) - 1)) + { + if (ch == '_') + *nameptr++ = '-'; + else + *nameptr++ = ch; + } + + *nameptr = '\0'; + + if (!strncmp(name, "printer_state_history", 21)) + strcpy(name, "printer_state_history"); + + /* + * Possibly add it to the list of attributes... + */ + + for (i = 0; i < num_attrs; i ++) + if (!strcmp(attrs[i], name)) + break; + + if (i >= num_attrs) + { + attrs[num_attrs] = strdup(name); + num_attrs ++; + } + } + + /* + * If we have attributes, add a requested-attributes attribute to the + * request... + */ + + if (num_attrs > 0) + { + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", num_attrs, NULL, (const char **)attrs); + + for (i = 0; i < num_attrs; i ++) + free(attrs[i]); + } + + fclose(in); +} + + +/* + * 'cgiGetIPPObjects()' - Get the objects in an IPP response. + */ + +cups_array_t * /* O - Array of objects */ +cgiGetIPPObjects(ipp_t *response, /* I - IPP response */ + void *search) /* I - Search filter */ +{ + int i; /* Looping var */ + cups_array_t *objs; /* Array of objects */ + ipp_attribute_t *attr, /* Current attribute */ + *first; /* First attribute for object */ + ipp_tag_t group; /* Current group tag */ + int add; /* Add this object to the array? */ + + + if (!response) + return (0); + + for (add = 0, first = NULL, objs = cupsArrayNew(NULL, NULL), + group = IPP_TAG_ZERO, attr = response->attrs; + attr; + attr = attr->next) + { + if (attr->group_tag != group) + { + group = attr->group_tag; + + if (group != IPP_TAG_ZERO && group != IPP_TAG_OPERATION) + { + first = attr; + add = 0; + } + else if (add && first) + { + cupsArrayAdd(objs, first); + + add = 0; + first = NULL; + } + } + + if (attr->name && attr->group_tag != IPP_TAG_OPERATION && !add) + { + if (!search) + { + /* + * Add all objects if there is no search... + */ + + add = 1; + } + else + { + /* + * Check the search string against the string and integer values. + */ + + switch (attr->value_tag) + { + 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_MIMETYPE : + for (i = 0; !add && i < attr->num_values; i ++) + if (cgiDoSearch(search, attr->values[i].string.text)) + add = 1; + break; + + case IPP_TAG_INTEGER : + for (i = 0; !add && i < attr->num_values; i ++) + { + char buf[255]; /* Number buffer */ + + + sprintf(buf, "%d", attr->values[i].integer); + + if (cgiDoSearch(search, buf)) + add = 1; + } + break; + + default : + break; + } + } + } + } + + if (add && first) + cupsArrayAdd(objs, first); + + return (objs); +} + + +/* + * 'cgiMoveJobs()' - Move one or more jobs. + * + * At least one of dest or job_id must be non-zero/NULL. + */ + +void +cgiMoveJobs(http_t *http, /* I - Connection to server */ + const char *dest, /* I - Destination or NULL */ + int job_id) /* I - Job ID or 0 for all */ +{ + int i; /* Looping var */ + const char *user; /* Username */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* Current attribute */ + const char *name; /* Destination name */ + const char *job_printer_uri; /* JOB_PRINTER_URI form variable */ + char current_dest[1024]; /* Current destination */ + + + /* + * Make sure we have a username... + */ + + if ((user = getenv("REMOTE_USER")) == NULL) + { + puts("Status: 401\n"); + exit(0); + } + + /* + * See if the user has already selected a new destination... + */ + + if ((job_printer_uri = cgiGetVariable("JOB_PRINTER_URI")) == NULL) + { + /* + * Make sure necessary form variables are set... + */ + + if (job_id) + { + char temp[255]; /* Temporary string */ + + + sprintf(temp, "%d", job_id); + cgiSetVariable("JOB_ID", temp); + } + + if (dest) + cgiSetVariable("PRINTER_NAME", dest); + + /* + * No new destination specified, show the user what the available + * printers/classes are... + */ + + if (!dest) + { + /* + * Get the current destination for job N... + */ + + char job_uri[1024]; /* Job URI */ + + + request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); + + snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", job_id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, job_uri); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "job-printer-uri"); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if ((attr = ippFindAttribute(response, "job-printer-uri", + IPP_TAG_URI)) != NULL) + { + /* + * Pull the name from the URI... + */ + + strlcpy(current_dest, strrchr(attr->values[0].string.text, '/') + 1, + sizeof(current_dest)); + dest = current_dest; + } + + ippDelete(response); + } + + if (!dest) + { + /* + * Couldn't get the current destination... + */ + + cgiStartHTML(cgiText(_("Move Job"))); + cgiShowIPPError(_("Unable to find destination for job!")); + cgiEndHTML(); + return; + } + } + + /* + * Get the list of available destinations... + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "printer-uri-supported"); + + if (user) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type", + CUPS_PRINTER_LOCAL); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask", + CUPS_PRINTER_SCANNER); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + for (i = 0, attr = ippFindAttribute(response, "printer-uri-supported", + IPP_TAG_URI); + attr; + attr = ippFindNextAttribute(response, "printer-uri-supported", + IPP_TAG_URI)) + { + /* + * Pull the name from the URI... + */ + + name = strrchr(attr->values[0].string.text, '/') + 1; + + /* + * If the name is not the same as the current destination, add it! + */ + + if (strcasecmp(name, dest)) + { + cgiSetArray("JOB_PRINTER_URI", i, attr->values[0].string.text); + cgiSetArray("JOB_PRINTER_NAME", i, name); + i ++; + } + } + + ippDelete(response); + } + + /* + * Show the form... + */ + + if (job_id) + cgiStartHTML(cgiText(_("Move Job"))); + else + cgiStartHTML(cgiText(_("Move All Jobs"))); + + if (cgiGetSize("JOB_PRINTER_NAME") > 0) + cgiCopyTemplateLang("job-move.tmpl"); + else + { + if (job_id) + cgiSetVariable("MESSAGE", cgiText(_("Unable to move job"))); + else + cgiSetVariable("MESSAGE", cgiText(_("Unable to move jobs"))); + + cgiSetVariable("ERROR", cgiText(_("No destinations added."))); + cgiCopyTemplateLang("error.tmpl"); + } + } + else + { + /* + * Try moving the job or jobs... + */ + + char uri[1024], /* Job/printer URI */ + resource[1024], /* Post resource */ + refresh[1024]; /* Refresh URL */ + const char *job_printer_name; /* New printer name */ + + + request = ippNewRequest(CUPS_MOVE_JOB); + + if (job_id) + { + /* + * Move 1 job... + */ + + snprintf(resource, sizeof(resource), "/jobs/%d", job_id); + + snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, uri); + } + else + { + /* + * Move all active jobs on a destination... + */ + + snprintf(resource, sizeof(resource), "/%s/%s", + cgiGetVariable("SECTION"), dest); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/%s/%s", + cgiGetVariable("SECTION"), dest); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + } + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-printer-uri", + NULL, job_printer_uri); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + ippDelete(cupsDoRequest(http, request, resource)); + + /* + * Show the results... + */ + + job_printer_name = strrchr(job_printer_uri, '/') + 1; + + if (cupsLastError() <= IPP_OK_CONFLICT) + { + const char *path = strstr(job_printer_uri, "/printers/"); + if (!path) + { + path = strstr(job_printer_uri, "/classes/"); + cgiSetVariable("IS_CLASS", "YES"); + } + + if (path) + { + cgiFormEncode(uri, path, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + } + } + + if (job_id) + cgiStartHTML(cgiText(_("Move Job"))); + else + cgiStartHTML(cgiText(_("Move All Jobs"))); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + if (job_id) + cgiShowIPPError(_("Unable to move job")); + else + cgiShowIPPError(_("Unable to move jobs")); + } + else + { + cgiSetVariable("JOB_PRINTER_NAME", job_printer_name); + cgiCopyTemplateLang("job-moved.tmpl"); + } + } + + cgiEndHTML(); +} + + +/* + * 'cgiPrintCommand()' - Print a CUPS command job. + */ + +void +cgiPrintCommand(http_t *http, /* I - Connection to server */ + const char *dest, /* I - Destination printer */ + const char *command, /* I - Command to send */ + const char *title) /* I - Page/job title */ +{ + int job_id; /* Command file job */ + char uri[HTTP_MAX_URI], /* Job URI */ + resource[1024], /* Printer resource path */ + refresh[1024], /* Refresh URL */ + command_file[1024]; /* Command "file" */ + http_status_t status; /* Document status */ + cups_option_t hold_option; /* job-hold-until option */ + const char *user; /* User name */ + ipp_t *request, /* Get-Job-Attributes request */ + *response; /* Get-Job-Attributes response */ + ipp_attribute_t *attr; /* Current job attribute */ + static const char const *job_attrs[] =/* Job attributes we want */ + { + "job-state", + "job-printer-state-message" + }; + + + /* + * Create the CUPS command file... + */ + + snprintf(command_file, sizeof(command_file), "#CUPS-COMMAND\n%s\n", command); + + /* + * Show status... + */ + + if (cgiSupportsMultipart()) + { + cgiStartMultipart(); + cgiStartHTML(title); + cgiCopyTemplateLang("command.tmpl"); + cgiEndHTML(); + fflush(stdout); + } + + /* + * Send the command file job... + */ + + hold_option.name = "job-hold-until"; + hold_option.value = "no-hold"; + + if ((user = getenv("REMOTE_USER")) != NULL) + cupsSetUser(user); + else + cupsSetUser("anonymous"); + + if ((job_id = cupsCreateJob(http, dest, title, + 1, &hold_option)) < 1) + { + cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver!"))); + cgiSetVariable("ERROR", cupsLastErrorString()); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + if (cgiSupportsMultipart()) + cgiEndMultipart(); + return; + } + + status = cupsStartDocument(http, dest, job_id, NULL, CUPS_FORMAT_COMMAND, 1); + if (status == HTTP_CONTINUE) + status = cupsWriteRequestData(http, command_file, + strlen(command_file)); + if (status == HTTP_CONTINUE) + cupsFinishDocument(http, dest); + + if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) + { + cgiSetVariable("MESSAGE", cgiText(_("Unable to send command to printer driver!"))); + cgiSetVariable("ERROR", cupsLastErrorString()); + cgiStartHTML(title); + cgiCopyTemplateLang("error.tmpl"); + cgiEndHTML(); + + if (cgiSupportsMultipart()) + cgiEndMultipart(); + + cupsCancelJob(dest, job_id); + return; + } + + /* + * Wait for the job to complete... + */ + + if (cgiSupportsMultipart()) + { + for (;;) + { + /* + * Get the current job state... + */ + + snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); + request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, uri); + if (user) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", 2, NULL, job_attrs); + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM); + if (!attr || attr->values[0].integer >= IPP_JOB_STOPPED || + attr->values[0].integer == IPP_JOB_HELD) + { + ippDelete(response); + break; + } + + /* + * Job not complete, so update the status... + */ + + ippDelete(response); + + cgiStartHTML(title); + cgiCopyTemplateLang("command.tmpl"); + cgiEndHTML(); + fflush(stdout); + + sleep(5); + } + } + + /* + * Send the final page that reloads the printer's page... + */ + + snprintf(resource, sizeof(resource), "/printers/%s", dest); + + cgiFormEncode(uri, resource, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + cgiCopyTemplateLang("command.tmpl"); + cgiEndHTML(); + + if (cgiSupportsMultipart()) + cgiEndMultipart(); +} + + +/* + * 'cgiPrintTestPage()' - Print a test page. + */ + +void +cgiPrintTestPage(http_t *http, /* I - Connection to server */ + const char *dest) /* I - Destination printer/class */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI], /* Printer URI */ + resource[1024], /* POST resource path */ + refresh[1024], /* Refresh URL */ + filename[1024]; /* Test page filename */ + const char *datadir; /* CUPS_DATADIR env var */ + const char *user; /* Username */ + + + /* + * See who is logged in... + */ + + user = getenv("REMOTE_USER"); + + /* + * Locate the test page file... + */ + + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + snprintf(filename, sizeof(filename), "%s/data/testprint", datadir); + + /* + * Point to the printer/class... + */ + + snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"), + dest); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"), + dest); + + /* + * Build an IPP_PRINT_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requesting-user-name + */ + + request = ippNewRequest(IPP_PRINT_JOB); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + if (user) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", + NULL, "Test Page"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoFileRequest(http, request, resource, + filename)) != NULL) + { + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + ippDelete(response); + } + + if (cupsLastError() <= IPP_OK_CONFLICT) + { + /* + * Automatically reload the printer status page... + */ + + cgiFormEncode(uri, resource, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + } + else if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + + cgiStartHTML(cgiText(_("Print Test Page"))); + + if (cupsLastError() > IPP_OK_CONFLICT) + cgiShowIPPError(_("Unable to print test page:")); + else + { + cgiSetVariable("PRINTER_NAME", dest); + + cgiCopyTemplateLang("test-page.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'cgiRewriteURL()' - Rewrite a printer URI into a web browser URL... + */ + +char * /* O - New URL */ +cgiRewriteURL(const char *uri, /* I - Current URI */ + char *url, /* O - New URL */ + int urlsize, /* I - Size of URL buffer */ + const char *newresource) /* I - Replacement resource */ +{ + char scheme[HTTP_MAX_URI], + userpass[HTTP_MAX_URI], + hostname[HTTP_MAX_URI], + rawresource[HTTP_MAX_URI], + resource[HTTP_MAX_URI], + /* URI components... */ + *rawptr, /* Pointer into rawresource */ + *resptr; /* Pointer into resource */ + int port; /* Port number */ + static int ishttps = -1; /* Using encryption? */ + static const char *server; /* Name of server */ + static char servername[1024]; + /* Local server name */ + static const char hexchars[] = "0123456789ABCDEF"; + /* Hexadecimal conversion characters */ + + + /* + * Check if we have been called before... + */ + + if (ishttps < 0) + { + /* + * No, initialize static vars for the conversion... + * + * First get the server name associated with the client interface as + * well as the locally configured hostname. We'll check *both* of + * these to see if the printer URL is local... + */ + + if ((server = getenv("SERVER_NAME")) == NULL) + server = ""; + + httpGetHostname(NULL, servername, sizeof(servername)); + + /* + * Then flag whether we are using SSL on this connection... + */ + + ishttps = getenv("HTTPS") != NULL; + } + + /* + * Convert the URI to a URL... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, + sizeof(userpass), hostname, sizeof(hostname), &port, + rawresource, sizeof(rawresource)); + + if (!strcmp(scheme, "ipp") || + !strcmp(scheme, "http") || + !strcmp(scheme, "https")) + { + if (newresource) + { + /* + * Force the specified resource name instead of the one in the URL... + */ + + strlcpy(resource, newresource, sizeof(resource)); + } + else + { + /* + * Rewrite the resource string so it doesn't contain any + * illegal chars... + */ + + for (rawptr = rawresource, resptr = resource; *rawptr; rawptr ++) + if ((*rawptr & 128) || *rawptr == '%' || *rawptr == ' ' || + *rawptr == '#' || *rawptr == '?' || + *rawptr == '.') /* For MSIE */ + { + if (resptr < (resource + sizeof(resource) - 3)) + { + *resptr++ = '%'; + *resptr++ = hexchars[(*rawptr >> 4) & 15]; + *resptr++ = hexchars[*rawptr & 15]; + } + } + else if (resptr < (resource + sizeof(resource) - 1)) + *resptr++ = *rawptr; + + *resptr = '\0'; + } + + /* + * Map local access to a local URI... + */ + + if (!strcasecmp(hostname, "127.0.0.1") || + !strcasecmp(hostname, "[::1]") || + !strcasecmp(hostname, "localhost") || + !strncasecmp(hostname, "localhost.", 10) || + !strcasecmp(hostname, server) || + !strcasecmp(hostname, servername)) + { + /* + * Make URI relative to the current server... + */ + + strlcpy(url, resource, urlsize); + } + else + { + /* + * Rewrite URI with HTTP/HTTPS scheme... + */ + + if (userpass[0]) + snprintf(url, urlsize, "%s://%s@%s:%d%s", + ishttps ? "https" : "http", + userpass, hostname, port, resource); + else + snprintf(url, urlsize, "%s://%s:%d%s", + ishttps ? "https" : "http", + hostname, port, resource); + } + } + else + strlcpy(url, uri, urlsize); + + return (url); +} + + +/* + * 'cgiSetIPPObjectVars()' - Set CGI variables from an IPP object. + */ + +ipp_attribute_t * /* O - Next object */ +cgiSetIPPObjectVars( + ipp_attribute_t *obj, /* I - Response data to be copied... */ + const char *prefix, /* I - Prefix for name or NULL */ + int element) /* I - Parent element number */ +{ + ipp_attribute_t *attr; /* Attribute in response... */ + int i; /* Looping var */ + char name[1024], /* Name of attribute */ + *nameptr, /* Pointer into name */ + value[16384], /* Value(s) */ + *valptr; /* Pointer into value */ + struct tm *date; /* Date information */ + + + fprintf(stderr, "DEBUG2: cgiSetIPPObjectVars(obj=%p, prefix=\"%s\", " + "element=%d)\n", + obj, prefix ? prefix : "(null)", element); + + /* + * Set common CGI template variables... + */ + + if (!prefix) + cgiSetServerVersion(); + + /* + * Loop through the attributes and set them for the template... + */ + + for (attr = obj; attr && attr->group_tag != IPP_TAG_ZERO; attr = attr->next) + { + /* + * Copy the attribute name, substituting "_" for "-"... + */ + + if (!attr->name) + continue; + + if (prefix) + { + snprintf(name, sizeof(name), "%s.", prefix); + nameptr = name + strlen(name); + } + else + nameptr = name; + + for (i = 0; attr->name[i] && nameptr < (name + sizeof(name) - 1); i ++) + if (attr->name[i] == '-') + *nameptr++ = '_'; + else + *nameptr++ = attr->name[i]; + + *nameptr = '\0'; + + /* + * Add "job_printer_name" variable if we have a "job_printer_uri" + * attribute... + */ + + if (!strcmp(name, "job_printer_uri")) + { + if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL) + valptr = "unknown"; + else + valptr ++; + + cgiSetArray("job_printer_name", element, valptr); + } + + /* + * Localize event names in "notify_events" variable... + */ + + if (!strcmp(name, "notify_events")) + { + size_t remaining; /* Remaining bytes in buffer */ + + + value[0] = '\0'; + valptr = value; + + for (i = 0; i < attr->num_values; i ++) + { + if (valptr >= (value + sizeof(value) - 3)) + break; + + if (i) + { + *valptr++ = ','; + *valptr++ = ' '; + } + + remaining = sizeof(value) - (valptr - value); + + if (!strcmp(attr->values[i].string.text, "printer-stopped")) + strlcpy(valptr, _("Printer Paused"), remaining); + else if (!strcmp(attr->values[i].string.text, "printer-added")) + strlcpy(valptr, _("Printer Added"), remaining); + else if (!strcmp(attr->values[i].string.text, "printer-modified")) + strlcpy(valptr, _("Printer Modified"), remaining); + else if (!strcmp(attr->values[i].string.text, "printer-deleted")) + strlcpy(valptr, _("Printer Deleted"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-created")) + strlcpy(valptr, _("Job Created"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-completed")) + strlcpy(valptr, _("Job Completed"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-stopped")) + strlcpy(valptr, _("Job Stopped"), remaining); + else if (!strcmp(attr->values[i].string.text, "job-config-changed")) + strlcpy(valptr, _("Job Options Changed"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-restarted")) + strlcpy(valptr, _("Server Restarted"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-started")) + strlcpy(valptr, _("Server Started"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-stopped")) + strlcpy(valptr, _("Server Stopped"), remaining); + else if (!strcmp(attr->values[i].string.text, "server-audit")) + strlcpy(valptr, _("Server Security Auditing"), remaining); + else + strlcpy(valptr, attr->values[i].string.text, remaining); + + valptr += strlen(valptr); + } + + cgiSetArray("notify_events", element, value); + continue; + } + + /* + * Add "notify_printer_name" variable if we have a "notify_printer_uri" + * attribute... + */ + + if (!strcmp(name, "notify_printer_uri")) + { + if ((valptr = strrchr(attr->values[0].string.text, '/')) == NULL) + valptr = "unknown"; + else + valptr ++; + + cgiSetArray("notify_printer_name", element, valptr); + } + + /* + * Add "notify_recipient_name" variable if we have a "notify_recipient_uri" + * attribute, and rewrite recipient URI... + */ + + if (!strcmp(name, "notify_recipient_uri")) + { + char uri[1024], /* New URI */ + scheme[32], /* Scheme portion of URI */ + userpass[256], /* Username/password portion of URI */ + host[1024], /* Hostname portion of URI */ + resource[1024], /* Resource portion of URI */ + *options; /* Options in URI */ + int port; /* Port number */ + + + httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, + scheme, sizeof(scheme), userpass, sizeof(userpass), + host, sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(scheme, "rss")) + { + /* + * RSS notification... + */ + + if ((options = strchr(resource, '?')) != NULL) + *options = '\0'; + + if (host[0]) + { + /* + * Link to remote feed... + */ + + httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "http", + userpass, host, port, resource); + strlcpy(name, uri, sizeof(name)); + } + else + { + /* + * Link to local feed... + */ + + snprintf(uri, sizeof(uri), "/rss%s", resource); + strlcpy(name, resource + 1, sizeof(name)); + } + } + else + { + /* + * Other... + */ + + strlcpy(uri, attr->values[0].string.text, sizeof(uri)); + strlcpy(name, resource, sizeof(name)); + } + + cgiSetArray("notify_recipient_uri", element, uri); + cgiSetArray("notify_recipient_name", element, name); + continue; + } + + /* + * Add "admin_uri" variable if we have a "printer_uri_supported" + * attribute... + */ + + if (!strcmp(name, "printer_uri_supported")) + { + cgiRewriteURL(attr->values[0].string.text, value, sizeof(value), + "/admin/"); + + cgiSetArray("admin_uri", element, value); + } + + /* + * 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) + { + time_t t; /* Temporary time value */ + + t = (time_t)attr->values[i].integer; + date = localtime(&t); + + strftime(valptr, sizeof(value) - (valptr - value), "%c", 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, ':') && + strcmp(name, "device_uri")) + { + /* + * Rewrite URIs... + */ + + if (!strcmp(name, "member_uris")) + { + char url[1024]; /* URL for class member... */ + + + cgiRewriteURL(attr->values[i].string.text, url, + sizeof(url), NULL); + + snprintf(valptr, sizeof(value) - (valptr - value), + "<A HREF=\"%s\">%s</A>", url, + strrchr(attr->values[i].string.text, '/') + 1); + } + else + cgiRewriteURL(attr->values[i].string.text, valptr, + sizeof(value) - (valptr - value), NULL); + 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 : + case IPP_TAG_MIMETYPE : + strlcat(valptr, attr->values[i].string.text, + sizeof(value) - (valptr - value)); + break; + + case IPP_TAG_BEGIN_COLLECTION : + snprintf(value, sizeof(value), "%s%d", name, i + 1); + cgiSetIPPVars(attr->values[i].collection, NULL, NULL, value, + element); + break; + + default : + break; /* anti-compiler-warning-code */ + } + } + + /* + * Add the element... + */ + + if (attr->value_tag != IPP_TAG_BEGIN_COLLECTION) + { + cgiSetArray(name, element, value); + + fprintf(stderr, "DEBUG2: %s[%d]=\"%s\"\n", name, element, value); + } + } + + return (attr ? attr->next : NULL); +} + + +/* + * 'cgiSetIPPVars()' - Set CGI variables from an IPP response. + */ + +int /* O - Maximum number of elements */ +cgiSetIPPVars(ipp_t *response, /* I - Response data to be copied... */ + const char *filter_name, /* I - Filter name */ + const char *filter_value, /* I - Filter value */ + const char *prefix, /* I - Prefix for name or NULL */ + int parent_el) /* I - Parent element number */ +{ + int element; /* Element in CGI array */ + ipp_attribute_t *attr, /* Attribute in response... */ + *filter; /* Filtering attribute */ + + + fprintf(stderr, "DEBUG2: cgiSetIPPVars(response=%p, filter_name=\"%s\", " + "filter_value=\"%s\", prefix=\"%s\", parent_el=%d)\n", + response, filter_name ? filter_name : "(null)", + filter_value ? filter_value : "(null)", + prefix ? prefix : "(null)", parent_el); + + /* + * Set common CGI template variables... + */ + + if (!prefix) + cgiSetServerVersion(); + + /* + * Loop through the attributes and set them for the template... + */ + + attr = response->attrs; + + if (!prefix) + while (attr && attr->group_tag == IPP_TAG_OPERATION) + attr = attr->next; + + for (element = parent_el; attr; element ++) + { + /* + * Copy attributes to a separator... + */ + + while (attr && attr->group_tag == IPP_TAG_ZERO) + attr= attr->next; + + if (!attr) + break; + + 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) && + (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)) + break; + + if (!filter) + return (element + 1); + + if (filter->group_tag == IPP_TAG_ZERO) + { + attr = filter; + element --; + continue; + } + } + + attr = cgiSetIPPObjectVars(attr, prefix, element); + } + + fprintf(stderr, "DEBUG2: Returing %d from cgiSetIPPVars()...\n", element); + + return (element); +} + + +/* + * 'cgiShowIPPError()' - Show the last IPP error message. + * + * The caller must still call cgiStartHTML() and cgiEndHTML(). + */ + +void +cgiShowIPPError(const char *message) /* I - Contextual message */ +{ + cgiSetVariable("MESSAGE", cgiText(message)); + cgiSetVariable("ERROR", cupsLastErrorString()); + cgiCopyTemplateLang("error.tmpl"); +} + + +/* + * 'cgiShowJobs()' - Show print jobs. + */ + +void +cgiShowJobs(http_t *http, /* I - Connection to server */ + const char *dest) /* I - Destination name or NULL */ +{ + int i; /* Looping var */ + const char *which_jobs; /* Which jobs to show */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + cups_array_t *jobs; /* Array of job objects */ + ipp_attribute_t *job; /* Job object */ + int ascending, /* Order of jobs (0 = descending) */ + first, /* First job to show */ + count; /* Number of jobs */ + const char *var, /* Form variable */ + *query, /* Query string */ + *section; /* Section in web interface */ + void *search; /* Search data */ + char url[1024], /* Printer URI */ + val[1024]; /* Form variable */ + + + /* + * Build an IPP_GET_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(IPP_GET_JOBS); + + if (dest) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, url, sizeof(url), "ipp", NULL, + "localhost", ippPort(), "/printers/%s", dest); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, url); + } + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + "ipp://localhost/"); + + if ((which_jobs = cgiGetVariable("which_jobs")) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", + NULL, which_jobs); + + cgiGetAttributes(request, "jobs.tmpl"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Get a list of matching job objects. + */ + + if ((query = cgiGetVariable("QUERY")) != NULL && + !cgiGetVariable("CLEAR")) + search = cgiCompileSearch(query); + else + { + query = NULL; + search = NULL; + } + + jobs = cgiGetIPPObjects(response, search); + count = cupsArrayCount(jobs); + + if (search) + cgiFreeSearch(search); + + /* + * Figure out which jobs to display... + */ + + if ((var = cgiGetVariable("FIRST")) != NULL) + first = atoi(var); + else + first = 0; + + if (first >= count) + first = count - CUPS_PAGE_MAX; + + first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; + + if (first < 0) + first = 0; + + if ((var = cgiGetVariable("ORDER")) != NULL) + ascending = !strcasecmp(var, "asc"); + else + ascending = !which_jobs || !strcasecmp(which_jobs, "not-completed"); + + section = cgiGetVariable("SECTION"); + + cgiClearVariables(); + + if (query) + cgiSetVariable("QUERY", query); + + cgiSetVariable("ORDER", ascending ? "asc" : "dec"); + + cgiSetVariable("SECTION", section); + + sprintf(val, "%d", count); + cgiSetVariable("TOTAL", val); + + if (which_jobs) + cgiSetVariable("WHICH_JOBS", which_jobs); + + if (ascending) + { + for (i = 0, job = (ipp_attribute_t *)cupsArrayIndex(jobs, first); + i < CUPS_PAGE_MAX && job; + i ++, job = (ipp_attribute_t *)cupsArrayNext(jobs)) + cgiSetIPPObjectVars(job, NULL, i); + } + else + { + for (i = 0, job = (ipp_attribute_t *)cupsArrayIndex(jobs, count - first - 1); + i < CUPS_PAGE_MAX && job; + i ++, job = (ipp_attribute_t *)cupsArrayPrev(jobs)) + cgiSetIPPObjectVars(job, NULL, i); + } + + /* + * Save navigation URLs... + */ + + if (dest) + { + snprintf(val, sizeof(val), "/%s/%s", section, dest); + cgiSetVariable("PRINTER_NAME", dest); + cgiSetVariable("PRINTER_URI_SUPPORTED", val); + } + else + strlcpy(val, "/jobs/", sizeof(val)); + + cgiSetVariable("THISURL", val); + + if (first > 0) + { + sprintf(val, "%d", first - CUPS_PAGE_MAX); + cgiSetVariable("PREV", val); + } + + if ((first + CUPS_PAGE_MAX) < count) + { + sprintf(val, "%d", first + CUPS_PAGE_MAX); + cgiSetVariable("NEXT", val); + } + + /* + * Then show everything... + */ + + if (dest) + cgiSetVariable("SEARCH_DEST", dest); + + cgiCopyTemplateLang("search.tmpl"); + + cgiCopyTemplateLang("jobs-header.tmpl"); + + if (count > CUPS_PAGE_MAX) + cgiCopyTemplateLang("pager.tmpl"); + + cgiCopyTemplateLang("jobs.tmpl"); + + if (count > CUPS_PAGE_MAX) + cgiCopyTemplateLang("pager.tmpl"); + + cupsArrayDelete(jobs); + ippDelete(response); + } +} + + +/* + * 'cgiText()' - Return localized text. + */ + +const char * /* O - Localized message */ +cgiText(const char *message) /* I - Message */ +{ + static cups_lang_t *language = NULL; + /* Language */ + + + if (!language) + language = cupsLangDefault(); + + return (_cupsLangString(language, message)); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/jobs.c b/cgi-bin/jobs.c new file mode 100644 index 0000000000..1001a629f2 --- /dev/null +++ b/cgi-bin/jobs.c @@ -0,0 +1,214 @@ +/* + * "$Id$" + * + * Job status CGI for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for CGI. + * do_job_op() - Do a job operation. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" + + +/* + * Local functions... + */ + +static void do_job_op(http_t *http, int job_id, 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 */ +{ + http_t *http; /* Connection to the server */ + const char *op; /* Operation name */ + const char *job_id_var; /* Job ID form variable */ + int job_id; /* Job ID */ + + + /* + * Get any form variables... + */ + + cgiInitialize(); + + /* + * Set the web interface section... + */ + + cgiSetVariable("SECTION", "jobs"); + cgiSetVariable("REFRESH_PAGE", ""); + + /* + * Connect to the HTTP server... + */ + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + /* + * Get the job ID, if any... + */ + + if ((job_id_var = cgiGetVariable("JOB_ID")) != NULL) + job_id = atoi(job_id_var); + else + job_id = 0; + + /* + * Do the operation... + */ + + if ((op = cgiGetVariable("OP")) != NULL && job_id > 0 && cgiIsPOST()) + { + /* + * Do the operation... + */ + + if (!strcmp(op, "cancel-job")) + do_job_op(http, job_id, IPP_CANCEL_JOB); + else if (!strcmp(op, "hold-job")) + do_job_op(http, job_id, IPP_HOLD_JOB); + else if (!strcmp(op, "move-job")) + cgiMoveJobs(http, NULL, job_id); + else if (!strcmp(op, "release-job")) + do_job_op(http, job_id, IPP_RELEASE_JOB); + else if (!strcmp(op, "restart-job")) + do_job_op(http, job_id, IPP_RESTART_JOB); + else + { + /* + * Bad operation code... Display an error... + */ + + cgiStartHTML(cgiText(_("Jobs"))); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + } + else + { + /* + * Show a list of jobs... + */ + + cgiStartHTML(cgiText(_("Jobs"))); + cgiShowJobs(http, NULL); + cgiEndHTML(); + } + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'do_job_op()' - Do a job operation. + */ + +static void +do_job_op(http_t *http, /* I - HTTP connection */ + int job_id, /* I - Job ID */ + ipp_op_t op) /* I - Operation to perform */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *user; /* Username */ + + + /* + * 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 = ippNewRequest(op); + + snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, uri); + + if ((user = getenv("REMOTE_USER")) == NULL) + user = "guest"; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(http, request, "/jobs")); + + if (cupsLastError() <= IPP_OK_CONFLICT && getenv("HTTP_REFERER")) + { + /* + * Redirect successful updates back to the parent page... + */ + + char url[1024]; /* Encoded URL */ + + + strcpy(url, "5;URL="); + cgiFormEncode(url + 6, getenv("HTTP_REFERER"), sizeof(url) - 6); + cgiSetVariable("refresh_page", url); + } + else if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + + cgiStartHTML(cgiText(_("Jobs"))); + + if (cupsLastError() > IPP_OK_CONFLICT) + cgiShowIPPError(_("Job operation failed:")); + else if (op == IPP_CANCEL_JOB) + cgiCopyTemplateLang("job-cancel.tmpl"); + else if (op == IPP_HOLD_JOB) + cgiCopyTemplateLang("job-hold.tmpl"); + else if (op == IPP_RELEASE_JOB) + cgiCopyTemplateLang("job-release.tmpl"); + else if (op == IPP_RESTART_JOB) + cgiCopyTemplateLang("job-restart.tmpl"); + + cgiEndHTML(); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/libcupscgi.exp b/cgi-bin/libcupscgi.exp new file mode 100644 index 0000000000..3a26229d79 --- /dev/null +++ b/cgi-bin/libcupscgi.exp @@ -0,0 +1,42 @@ +_cgiCheckVariables +_cgiClearVariables +_cgiCompileSearch +_cgiCopyTemplateFile +_cgiCopyTemplateLang +_cgiDoSearch +_cgiEndHTML +_cgiEndMultipart +_cgiFormEncode +_cgiFreeSearch +_cgiGetArray +_cgiGetAttributes +_cgiGetCookie +_cgiGetFile +_cgiGetIPPObjects +_cgiGetSize +_cgiGetTemplateDir +_cgiGetVariable +_cgiInitialize +_cgiIsPOST +_cgiMoveJobs +_cgiPrintCommand +_cgiPrintTestPage +_cgiRewriteURL +_cgiSetArray +_cgiSetIPPObjectVars +_cgiSetIPPVars +_cgiSetCookie +_cgiSetServerVersion +_cgiSetSize +_cgiSetVariable +_cgiShowIPPError +_cgiShowJobs +_cgiStartHTML +_cgiStartMultipart +_cgiSupportsMultipart +_cgiText +_helpDeleteIndex +_helpFindNode +_helpLoadIndex +_helpSaveIndex +_helpSearchIndex diff --git a/cgi-bin/makedocset.c b/cgi-bin/makedocset.c new file mode 100644 index 0000000000..7d90c80732 --- /dev/null +++ b/cgi-bin/makedocset.c @@ -0,0 +1,486 @@ +/* + * "$Id$" + * + * Xcode documentation set generator. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Usage: + * + * makedocset directory *.tokens + * + * Contents: + * + * main() - Test the help index code. + * compare_html() - Compare the titles of two HTML files. + * compare_sections() - Compare the names of two help sections. + * compare_sections_files() - Compare the number of files and section names. + * write_index() - Write an index file for the CUPS help. + * write_info() - Write the Info.plist file. + * write_nodes() - Write the Nodes.xml file. + */ + +/* + * Include necessary headers... + */ + +#include "cgi.h" +#include <errno.h> + + +/* + * Local structures... + */ + +typedef struct _cups_html_s /**** Help file ****/ +{ + char *path; /* Path to help file */ + char *title; /* Title of help file */ +} _cups_html_t; + +typedef struct _cups_section_s /**** Help section ****/ +{ + char *name; /* Section name */ + cups_array_t *files; /* Files in this section */ +} _cups_section_t; + + +/* + * Local functions... + */ + +static int compare_html(_cups_html_t *a, _cups_html_t *b); +static int compare_sections(_cups_section_t *a, _cups_section_t *b); +static int compare_sections_files(_cups_section_t *a, _cups_section_t *b); +static void write_index(const char *path, help_index_t *hi); +static void write_info(const char *path, const char *revision); +static void write_nodes(const char *path, help_index_t *hi); + + +/* + * 'main()' - Test the help index code. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + char path[1024], /* Path to documentation */ + line[1024]; /* Line from file */ + help_index_t *hi; /* Help index */ + cups_file_t *tokens, /* Tokens.xml file */ + *fp; /* Current file */ + + + if (argc < 4) + { + puts("Usage: makedocset directory revision *.tokens"); + return (1); + } + + /* + * Index the help documents... + */ + + snprintf(path, sizeof(path), "%s/Contents/Resources/Documentation", argv[1]); + if ((hi = helpLoadIndex(NULL, path)) == NULL) + { + fputs("makedocset: Unable to index help files!\n", stderr); + return (1); + } + + snprintf(path, sizeof(path), "%s/Contents/Resources/Documentation/index.html", + argv[1]); + write_index(path, hi); + + snprintf(path, sizeof(path), "%s/Contents/Resources/Nodes.xml", argv[1]); + write_nodes(path, hi); + + /* + * Write the Info.plist file... + */ + + snprintf(path, sizeof(path), "%s/Contents/Info.plist", argv[1]); + write_info(path, argv[2]); + + /* + * Merge the Tokens.xml files... + */ + + snprintf(path, sizeof(path), "%s/Contents/Resources/Tokens.xml", argv[1]); + if ((tokens = cupsFileOpen(path, "w")) == NULL) + { + fprintf(stderr, "makedocset: Unable to create \"%s\": %s\n", path, + strerror(errno)); + return (1); + } + + cupsFilePuts(tokens, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + cupsFilePuts(tokens, "<Tokens version=\"1.0\">\n"); + + for (i = 3; i < argc; i ++) + { + if ((fp = cupsFileOpen(argv[i], "r")) == NULL) + { + fprintf(stderr, "makedocset: Unable to open \"%s\": %s\n", argv[i], + strerror(errno)); + return (1); + } + + if (!cupsFileGets(fp, line, sizeof(line)) || strncmp(line, "<?xml ", 6) || + !cupsFileGets(fp, line, sizeof(line)) || strncmp(line, "<Tokens ", 8)) + { + fprintf(stderr, "makedocset: Bad Tokens.xml file \"%s\"!\n", argv[i]); + return (1); + } + + while (cupsFileGets(fp, line, sizeof(line))) + { + if (strcmp(line, "</Tokens>")) + cupsFilePrintf(tokens, "%s\n", line); + } + + cupsFileClose(fp); + } + + cupsFilePuts(tokens, "</Tokens>\n"); + + cupsFileClose(tokens); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'compare_html()' - Compare the titles of two HTML files. + */ + +static int /* O - Result of comparison */ +compare_html(_cups_html_t *a, /* I - First file */ + _cups_html_t *b) /* I - Second file */ +{ + return (strcasecmp(a->title, b->title)); +} + + +/* + * 'compare_sections()' - Compare the names of two help sections. + */ + +static int /* O - Result of comparison */ +compare_sections(_cups_section_t *a, /* I - First section */ + _cups_section_t *b) /* I - Second section */ +{ + return (strcasecmp(a->name, b->name)); +} + + +/* + * 'compare_sections_files()' - Compare the number of files and section names. + */ + +static int /* O - Result of comparison */ +compare_sections_files( + _cups_section_t *a, /* I - First section */ + _cups_section_t *b) /* I - Second section */ +{ + int ret = cupsArrayCount(b->files) - cupsArrayCount(a->files); + + if (ret) + return (ret); + else + return (strcasecmp(a->name, b->name)); +} + + +/* + * 'write_index()' - Write an index file for the CUPS help. + */ + +static void +write_index(const char *path, /* I - File to write */ + help_index_t *hi) /* I - Index of files */ +{ + cups_file_t *fp; /* Output file */ + help_node_t *node; /* Current help node */ + _cups_section_t *section, /* Current section */ + key; /* Section search key */ + _cups_html_t *html; /* Current HTML file */ + cups_array_t *sections, /* Sections in index */ + *sections_files,/* Sections sorted by size */ + *columns[3]; /* Columns in final HTML file */ + int column, /* Current column */ + lines[3], /* Number of lines in each column */ + min_column, /* Smallest column */ + min_lines; /* Smallest number of lines */ + + + /* + * Build an array of sections and their files. + */ + + sections = cupsArrayNew((cups_array_func_t)compare_sections, NULL); + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes); + node; + node = (help_node_t *)cupsArrayNext(hi->nodes)) + { + if (node->anchor) + continue; + + key.name = node->section ? node->section : "Miscellaneous"; + if ((section = (_cups_section_t *)cupsArrayFind(sections, &key)) == NULL) + { + section = (_cups_section_t *)calloc(1, sizeof(_cups_section_t)); + section->name = key.name; + section->files = cupsArrayNew((cups_array_func_t)compare_html, NULL); + + cupsArrayAdd(sections, section); + } + + html = (_cups_html_t *)calloc(1, sizeof(_cups_html_t)); + html->path = node->filename; + html->title = node->text; + + cupsArrayAdd(section->files, html); + } + + /* + * Build a sorted list of sections based on the number of files in each section + * and the section name... + */ + + sections_files = cupsArrayNew((cups_array_func_t)compare_sections_files, + NULL); + for (section = (_cups_section_t *)cupsArrayFirst(sections); + section; + section = (_cups_section_t *)cupsArrayNext(sections)) + cupsArrayAdd(sections_files, section); + + /* + * Then build three columns to hold everything, trying to balance the number of + * lines in each column... + */ + + for (column = 0; column < 3; column ++) + { + columns[column] = cupsArrayNew((cups_array_func_t)compare_sections, NULL); + lines[column] = 0; + } + + for (section = (_cups_section_t *)cupsArrayFirst(sections_files); + section; + section = (_cups_section_t *)cupsArrayNext(sections_files)) + { + for (min_column = 0, min_lines = lines[0], column = 1; + column < 3; + column ++) + { + if (lines[column] < min_lines) + { + min_column = column; + min_lines = lines[column]; + } + } + + cupsArrayAdd(columns[min_column], section); + lines[min_column] += cupsArrayCount(section->files) + 2; + } + + /* + * Write the HTML file... + */ + + if ((fp = cupsFileOpen(path, "w")) == NULL) + { + fprintf(stderr, "makedocset: Unable to create %s: %s\n", path, + strerror(errno)); + exit(1); + } + + cupsFilePuts(fp, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 " + "Transitional//EN\" " + "\"http://www.w3.org/TR/html4/loose.dtd\">\n" + "<html>\n" + "<head>\n" + "<title>CUPS Documentation\n" + "\n" + "\n" + "\n" + "

CUPS Documentation

\n" + "\n" + "\n"); + + for (column = 0; column < 3; column ++) + { + if (column) + cupsFilePuts(fp, "\n"); + + cupsFilePuts(fp, "\n"); + } + cupsFilePuts(fp, "\n" + "
     "); + for (section = (_cups_section_t *)cupsArrayFirst(columns[column]); + section; + section = (_cups_section_t *)cupsArrayNext(columns[column])) + { + cupsFilePrintf(fp, "

%s

\n", section->name); + for (html = (_cups_html_t *)cupsArrayFirst(section->files); + html; + html = (_cups_html_t *)cupsArrayNext(section->files)) + cupsFilePrintf(fp, "

%s

\n", + html->path, html->title); + } + cupsFilePuts(fp, "
\n" + "\n" + "\n"); + cupsFileClose(fp); +} + + +/* + * 'write_info()' - Write the Info.plist file. + */ + +static void +write_info(const char *path, /* I - File to write */ + const char *revision) /* I - Subversion revision number */ +{ + cups_file_t *fp; /* File */ + + + if ((fp = cupsFileOpen(path, "w")) == NULL) + { + fprintf(stderr, "makedocset: Unable to create %s: %s\n", path, + strerror(errno)); + exit(1); + } + + cupsFilePrintf(fp, "\n" + "\n" + "\n" + "\n" + "\tCFBundleIdentifier\n" + "\torg.cups.docset\n" + "\tCFBundleName\n" + "\tCUPS Documentation\n" + "\tCFBundleVersion\n" + "\t%d.%d.%s\n" + "\tCFBundleShortVersionString\n" + "\t%d.%d.%d\n" + "\tDocSetFeedName\n" + "\tcups.org\n" + "\tDocSetFeedURL\n" + "\thttp://www.cups.org/org.cups.docset.atom" + "\n" + "\tDocSetPublisherIdentifier\n" + "\torg.cups\n" + "\tDocSetPublisherName\n" + "\tCUPS\n" + "\n" + "\n", + CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, revision, + CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, CUPS_VERSION_PATCH); + + cupsFileClose(fp); +} + + +/* + * 'write_nodes()' - Write the Nodes.xml file. + */ + +static void +write_nodes(const char *path, /* I - File to write */ + help_index_t *hi) /* I - Index of files */ +{ + cups_file_t *fp; /* Output file */ + int id; /* Current node ID */ + help_node_t *node; /* Current help node */ + int subnodes; /* Currently in Subnodes for file? */ + int needclose; /* Need to close the current node? */ + + + if ((fp = cupsFileOpen(path, "w")) == NULL) + { + fprintf(stderr, "makedocset: Unable to create %s: %s\n", path, + strerror(errno)); + exit(1); + } + + cupsFilePuts(fp, "\n" + "\n" + "\n" + "\n" + "CUPS Documentation\n" + "Documentation/index.html\n" + "\n"); + + for (node = (help_node_t *)cupsArrayFirst(hi->nodes), id = 1, subnodes = 0, + needclose = 0; + node; + node = (help_node_t *)cupsArrayNext(hi->nodes), id ++) + { + if (node->anchor) + { + if (!subnodes) + { + cupsFilePuts(fp, "\n"); + subnodes = 1; + } + + cupsFilePrintf(fp, "\n" + "Documentation/%s\n" + "%s\n" + "%s\n" + "\n", id, node->filename, node->anchor, + node->text); + } + else + { + if (subnodes) + { + cupsFilePuts(fp, "\n"); + subnodes = 0; + } + + if (needclose) + cupsFilePuts(fp, "\n"); + + cupsFilePrintf(fp, "\n" + "Documentation/%s\n" + "%s\n", id, node->filename, node->text); + needclose = 1; + } + } + + if (subnodes) + cupsFilePuts(fp, "\n"); + + if (needclose) + cupsFilePuts(fp, "\n"); + + cupsFilePuts(fp, "\n" + "\n"); + + cupsFileClose(fp); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/multipart.dat b/cgi-bin/multipart.dat new file mode 100644 index 0000000000000000000000000000000000000000..91c5bb5b4c0e039c6692bc116be57983b836be68 GIT binary patch literal 50411 zc-pkQ2|Sc*A2*&9rDzq|B_%Rr#w?`BPPVcRhKw;7X3UtyR%u0Ki9(2yESWKleF-hL z?2)A`$sUp|91v9`5(Y)U zRH1ML6bXZ?Dybl0DylGL2n52F(j@sH!3rp-M_nDP0WJ zU&?~yO7q1~a8j!yY1D&KngoKBIY*W%Wsai)#BeU417K|mZiRvlhK7^VImFSRqym8{ zDJiQcsVXP|jRRmyJdJ>p)AW)u`(r**Bv&b#I}U&+5=mZCR;Gq100{3z!+W_&S@=_F zIN|}YCY|O^qR5%xvF;cgLCV4xhoc=(SI2p|0CVDl{+Jub8em;7EXf5J4c5WCy5cA} zFD#B~FQp6xQ^^=C4vh1|5->!tH=RVoxi}NRUUZ@}jzYz|d4XL>1OkQvCgUhrz_wrv z5ol2{UM{P`R6r*I2POli@FL(`X{)UjlYub+PYRyu2__ThR4^8p3kFQYdjV}g1)k&r zrV=nzcW?lXLIRV#aA2A*2~2aR;Ba795}g8e#rxpERJ0QE&hQ48R)$b_Qd?E?{6TU^lQk7!URUdx8mIBG?N|0+YesU<#NDrh(~T zAFwaj59|*PSkaFA1Cg?N_7f5fPjJCWL7*yNT{?v%1yNS|$pg+9Du6^F0WtE!i7S0L z0s&8^;;CR4jGG%^m(@3pi&vSu5^#PTcL1S8U-7C17DEBd=0?X8Ry42hG1HZTz~HNz zS2|W&tK|Lz_h&zFvUVqhMTcL=43fO#KVs>QE9eRk$kH z)&&m)D~JEjaq2?y^#ZR%BPYTLoUq2yDV(782m1q|;!GiV;=DLUq~fqEQSd_z_CE;? zCQ)2mfe2a&C=NIQMIT7!L<76~lidM@6r3BL1BG(|6ERp0T^F1iCr~+& zy&BR$@KWh3aZOnb;vZ)iES-h}6X~4PzyQ%fcK;*(IWt(%iN(19_!v$S{1^q$BLaS> z6Mo_M2X!w_uv0j34m8~{1lLu_KRT&DqJPCunyV41xynQHC%R{cU2J8M9WwP1VSHUd$FqY#0pb|z54m_HJ8^)lwCv6xj@ z%nucq6*FLfLh~Op;8q9YRtMvL8jSlf3co6YUzNfCB!mAUg9FUqwF*aC6(_BVlYSB> z{UPvUlndSm&*@k-0)2HLeRUxHr-AezBm7q{(pHS%|DSG$AFG4%ud9O|uyBGc=*~3G z38x1F)&i=>O1Cypi-GY!RuC!9%3}UQ6YPK2WQix@sEXz!z$5>p4gPy5t&2)mSia!g$_&-PvBH7Jx-4f4loN2Y=d{9xl5_SAb{Cc zc3R3nQwvX{9>-CD{SO(aa9%Vi7}yx+3%bJQQH*W z_qPaEeQlB3U%uLy&`8*;d^K%YsiGpYEl-0en? zs-DnEo^@wXFO0NXiCe_W=xw@EPoHR=l&hc;`d};s6^iy8rCPH=-`}=%jt;X^*S(10)?5Bv z-N7N7`Z+yL zl$#orESX96K@YzAtS{tLm^3d6$ry7Db8J}K^~IOn(7Z8t0!jDDk@#N91`@-uI*YgwX9n|Fy&}pz z1^;q3{pDA96q|Oe#bNf5*?~{tRrh-Dx`f)AIh4r;jxU&X?a4nB@g;6xU-P2vM-Yl$ zbrv}|Q=U`;K6Gd*vqky4|32T{d`IF(jxOo+*>?|Go|`xR);!+3GnxMG+swmbaq}@< z!!OgyjdsM`EZ&%3xwj{EPBID}< zWNf=g2Qsib8mpn96>EcBf z+kugxLu>BRu%XQ6+0 zY+PO0J$MyU@=JopWq9T0F6*vFzjo2sA@sqB*mv?KHeXK%*l!99Xuf~+UhaIjZNFQB z+ZjnoPybM6`q^u?kyX*;dUnc~%64_S%i50X-W{6+Hx5`wlY?y^w(9NwdTAli?ZH&@ zekiGeVcY6%G?LSrNHZGEDQ@vem^Xa)&UQisl^K2sn6ml)W0~2kyC~HJ2b-FGbZ{Lr zv#jAdzN_#c8*$cQ&v@MDFV`u)N4oO25A4wJigl5F@kOWRgqdN%aCm;LO(bfcXM;e1 zVG6u*NE$_Sj>zfQVtobWJKO__=Vs_KM@xLtNEbWzSht<3r95j~6aZxUL&vuk9%0+n z*d3_zK00B&p6Qbt=B4ssa9~Q1-BW898kncIp1F`~eJ91vii;7!jCJ3yW&OxwKZBP1 zsbCbno>`RlVSepc+0#cpfLva~D_W${h0kY@s2rCZON86QbFHrIyf9L#tbZVRbKwgQc<&2}d%HnoCMI>QrpfDfyA ztV>CPx5*Cjs~Bu!5UwW;KTJ*fRQI-qi!sf7OC#m)=bn*%$u3*+s~U(-R*$nUS-x``&uSJo7ZW@!8;mbzPSEak>`$yVX0x7UV}2*%@(# z1uaE3Tl8hZbMCoX-PW#nAA&j=779a|f19NL+AA)wZlMaD*E)WY*JON;u33U7P_R<^1ksx4gl`PBV= zr!P;QkjXJRlFam+e7JS02i2vju?{6v?Xd^Lb`7=KlAI0)-syGMWlCN;?zUIGx89S_ zR^e_~NZ?*Em-O6dCDgQQMOFHDx(11#-B5ST$wWpWKGwzTAj8Y3j~r+reu+ ztA{V`aJ8Bte|6vNi5<`}=6%P5vZ$J@(Wy!%Up4K!KW0<0!+Q44VdxE}8!_A^=a5#6 zgt(tJJ1y8&5GsBieula4akPHN;SV8BUKI+-uiv;e*x$pAuKCR6Kfj@ErlH)muyGq~ zboTLr&yxUurw`T{o5>g8{L;^72i>isyCyFi`ZhVu3q&4&9vi#ADK=ln+SLB;tE~#_ zzmM~!5lWrlObQ8YDz04ShIy5U+;+k-Dpg|Y{7l^m_SY@UU@KVrsp>jbY}Z?CPJW7e zes-ALcV(v6?FP&KXW}0`^0O^qH>|`TRqOA0m3y^N6FsS+gcOnRbZ|vxLqvzT*#Usx z4XO>F6T#OCS^6fX7C1{6RFnyH*!QXEn@cA9Plpt@*d^?1nk(z*f3wB7Ej8QAFZz9` zP2~Fr&g@`Yf1am`qPE`88qrM8?>DVg*{;D>$+Kno$gy)m?2MRLMI(ExS;rdBV{={f zgyIIqrR!}Q-9idSY!bR2C8j4TO-E=%Ze*&wS^u}0Mt{jH8N=+ewKyHrPG?8jPnNtV z?6SS)!2D|I6j4&13AVmEPidFFlb;tz9OOBz|Il8ui;GxOW0$dM6Y}-IJ_p~!513xz zOoY!9(!`j2URU>!bH%m%==prZYZ@-`^F$D+D<-1X%*9NU@pKWydR%C{>?Ff5YLU+q z=$rRL`Q~iC#H&*f!z2wEdi%UdOvWp`yiu~Rbuqsddl>F4d+%_j zHIMNgqO9nS?)7ZPvbG0<;tCHAncCOaR@1qd7lEa=N_H_fHk%`|6s^k+qqpi>Rd{8} z&wT7fov_aRQ0ksN6_+hA0`E_@!d3JolT9vfiDbw&oP5#HuvC__sI#2TB0m2^1sC2Vt+$kNNvGRX8A+3m#26l(ug~swsz7aK zod0%?2`!YgO3x{hWpQ;qzJubuIJ2Bpr0ccxU9Nqp?^Bq`yxGYuZ%=N2b(*U9-Ei}l z^?6~Vjo9w5qs`6JO97?DrFaRtfV$*ejQ@R&`{|)m^EH3~9ecL#%f_XM?u*wC&V1A_ zf_YculC4X>0vo{Zfv?LmzkUxKp1aR;!0vm7Mkz3;Ii1aOr}&Dde0;GX>7je*RF!Og z2K|dMNyBJIw~bT8)grs36326JtsV~|uuWj3iz*!(O62vtThQ5FJ%0!#lb#c|kA-|B za)4L}U~ROv-?1zgI;G9lJ7%wFf{^K*u-vmxcBrv{G}$( zHC^Gk*4IqzAD5MLIONwZ?t57v$ZRyK@VWr^WDdwC6g;SOE_6%TlQt>*#?d@Z?zpNWkpZBIUv6fE(j z8H~NzE6NyXco4qMCTiB%;x9mb$>4i z5%V8E|9xZE$J`Y68YKnd8@CTmCbA5LM330WwagEC@cYYcTqujD0Z+WNl$rt#IySX# zAhR=~3R@}&{iRRjw-}6e+aMn$YIVsM*AD9sqoUe2W=404s_E07h#HX18+(N7?dUEg zBX2Llm4W)Jx-YgZ(&d|lOhu!D0;<#dW1)478l4eR}|Oa4vLiEQJ(O;-?%?8`$M-2Twq zhIL&fwx^&MwsTKoIhT)pt4{yUO_h13KFVE()!xUheJVdgyXn&^=IqAVC0i?HHL)o$-{m=%D`wN`ELCVfF6dSr=i+AUz9TE!DM5@BFeeHFhJx z5AI%cd?ez#pV_dZNxrtL3IT*ok4F6bezxm{&IjPQSJJ9odF|xe5+Kj#Z?+t3X*wx# zOvAIc_h>~?AD>TtdpOfU;E_#KXU-RC3-3j^9go769fdDZ4sDjLnc}w4s-A@p)(L%= zA2`%`bXD5l3@vP&dArLx+{z}wW8e0D@-6jt1HxNu`Y%TmDvNrCXsWe%|&qdOB&7TT_wp7ULjr#XzHGR`W`YRU7luja&EXPf{klTVn^XGu96?1N$c^I{PHk zCW>|IUM{~M%2>D^Z^+!wJ4=637=ZrptFn!m1 z&E8j&->Z;yYAiVe6EPzkR*+jO3{_2)_sM)3VO7AOwsd~9_=-~NNNRAqeAe(>q3)># zQhof~eIw7x@%E4N-t5}w*E{c9=Hjr^s@c1*`8UL#q555=m8xV1-n(7NHD*0<0=)O- zHgeO8^oglqg-6HskBC|NYcz8g%8YZVdYmltJN7PC&1YhpZj=2*tG5>jH~Q~j;AVox zIy3o22?HbEJ4@0R-RV~>uj)SUuCs9>jCS0*d+YG&>yaH>YO;M^%)Tq#kj#EdB`h3)6vvuz(tzUr8t?Q|AAvGzdI)+s$p z>$a~?tOzzC`tmO3W*bfT1h-s~-wq0QRpim$=g-jR*dolz(fpCgxk6EvbEDmE{_&h4 zO^fw$^J%-fr7d3_3hRuHm93H=V6NCLtg~5Cxal)$UcKn3puNx*lZ2;-Wz`)ZC0N$& zv-dPy39+-M+SokV#=5|^Wd8Ofuvse zx7xd*0!$^DhT%Eor}m<7=4QJ0pv`$Xo19E8SoulR&yh{b6WJ1$G98yPPolHW!zH?A z)!Y&4N);|^nOCMR+QiI1*8KeJ^059UzJy1Kdp+Uco!mC2*D{-|#Mv1)3j^U=?c;6d z;r&>K(V&H$nI1ZQClkLpfh-{KmyaHu&PS@#59;TGK8xG})qJ+*M*I1Qc_tP&z4p_n zXsp_6yNs+id)NLfbl;YnpI=oTdb$WjdM0Xg+W!xw{GXb;R|_m-FY-0gF!00Vd-~xa z^klpWuUnJ3$-Jt{$m{UZXrm)FqCDfpk#0HZK2@~8*O%jRWdEU?AH+KkUww5c^4;|v z$Ab#O5-_8Sgi{UkNdXmDXZW?6APLd@cJaF9TUPk7-IjT^$KvuDcD*S3Q09G0v(Tc` z)xWF%Rg*=QOK9wavczQOVey67Ey#DuADfstU#|pJCe+dCw#~Kd$j+v4^-edZz;EKm zXO4J+Z^FAGo0%0wj7+^ai&H-SUDojW%;$m{EzN|nNvp3J0bc!ch=+NSr*W@+J7~9) z6C10F{lYW1TFr$8p6g7QoVU7WRM=zuKhf@dsBX}J6w9ghtPyF4FlZcRQb_C2cH_B|qLQO>rfPZ&<1bOB7doe{6YIYntNz5mx>EsFMAe zo<5n0dTQd#ank{N!&09@(`Zq~!}&unKvi{*1y!*T@xpwEqa?-5Ipe|oS-I?OrAeS* z+tPXS_p#q|Oih~e-@Q+I0RK*$M>;!Kl#Z;^Z&A##j_EdKH`I!}2ynjET=2>}Rwf|C zW9>)8*~q#?rhSK`@fk(_J7b%28zR#MPvbuOUdl{C*$0Yz!Il{oWR|U+d5C@yU0hTG z2@_7Yc&$33ZBNRWkG${q;@VtZ!-BcIrwDv;3Pc@2eo zKN^gx`GoowL0~tyX4|y08%_t_pij<6hFEoOOvh?QjE}R#K7DgUHuZQLPaKc>?&ZCm zF_k5asLuYbr-%9$+rczNs<^JV&9tBKLv<3y^Dy2X^KLRYSIvh{dSvHxTCdCOi^vJE zY-6&@K8;uCZj(+rp+GLe=^<1 zOucIO{d^p<+V!Fp=}w&F#zy`fuL6{Fe9@yDGIQ)Cy0!1dekQEfnB&V|_;v;%ZaX=C z^TF*8T_>3E*?kh8b@)$NS<89|6waiNdAG^5S1bw?9Oz-Rv0 zLhZ-p2AwKaCVo2^sMN$ozBx5oz3Q#9eK+~6OZNoG;zn&ci6yo?#jg%diMw4G<~8d& zxR4LRCqx%oaeMOEDyrS&XL_@JhULzk>s0R&LFK>L`01aE2W#sTrU;Bv)$j}eh zQ~vRVIUMq@Uzn@H;s5=GdGg6qX$N3EJH~ahCZ!Ue1GoCi|X<42$m$^~y zY15jpGmVd_N2ax^6st%)!o~w<>(_om##?NgdH8ARTjTT6(_dS^w=VURR`-6tXFwaB z_%eSc89nsriiF{X-eud}@t=v<#e=Q)=j}?~A4e8wc)kueW%yLKzdM@xO<}vEzq)SI ze3H@Vb1~_}+z)E5DW$I(sw=+Q=+|~u>~%c0C?eQBQ*B>w+C~nA&e}T43{tu_J=7ix zH7eix%4m`5&0-m7U0>ccwiv%o-nL?I_x-&nL$fR1{#}}8PFs;(`d>;n#LLC()l<4` zzM=C2)`w-wMme$99uyE}a$Vu#IbpE z);O&fNEohh5>L5ua6t!@d)PXL=e4}d>tmD|G;zDGs{hz_T`_cm8w^uGUwkV+Z}oZP6gPP6*4fDY zU%p7_u(>Y2uZlI@`|V0`yb?E0YRJ^fGRwvBb3WwPhk|#@`*$q7stVYkg1+<-`?#53 zJ-75lDvzSWO~ax=inlg@K!8`B9kjz3G)B&Czo)7lr(B9Ue;6qm193SJ#n_lOEfMne z(UAOD-s1;Ig>r)A*-(_`O?N!JSBOcbU|y33=hHsf+3nX}M~W_YJJ>$W z5D#L^Zf#MCO{)sIxWCiDa~XX}qQeg~C~>zmE|PTF6@;Qu92!p+NneN;Jl4f4FWbHK zaYz$S0=l4{T}81nQgum@b3=hH?Dkqbmp-z4Pe~F+Md7ad5LX>N{0ZO2BlX_sZSK-0 zhs<}{JYeg)%DvcF6=YLYzQvKey{LvP=zW<-cS?DkP2-lPI8k;_i&f1Yk?UM)FG|A< zU@0B9`WiZG;pnGajZCzaOI6TEOko7$GNI(ES%BN%{?irjMi5Wa5uYc)??z z9i!zGo@d;x5xIsImFb?wx+GVr2%Ntq^(etnHBtdWJ%86xT)ppLTim*v6ZE4L@o;qV z$J1*(gKyZzOqHH{Q=U;uk?HPS$g7ibNx826oEob$4sVW4D3!32mSaeKROZzq`#qwZ z5s43;N}X1GwHb2klO!N09oh80N&evZz$pggpl*&M@@>3Q^e z1hbABYL@?u+HVq8VB0E)i`x5w=T{aBI1v67O}>i6C!mS~N}e0MgCJY#g~+=kC@$RV?`y%3wU z!5E7Z@_Et{(>r+HQ~aK|TO1jigrW0Z6^!T#zb=hD_)_>~b%rFhpI|j8KeExt@lxog zi9O!2K)-3z()5w$GSry4@|{R7sL1&gd4$|qx`b(dlr+^U41?q{UtXgaQd=`HT(M8% zlw!QFw_w;Poy#1~B|e`xefL56XV{sPLB0dA3{1nITd8T+=aRQ=r+e;audyD>x1z+B z%gG0@E(qz?w8)}Il$=>DCj_vg9;I!V5p=W7wJK4Ynn;1+u|prysW=CDVH*^N7Ce%@Kw8lntrC#?@zP6Q@1lrfn84hK?fP%aI)h7az4p+$c z21fP2YNM+Y3y7XBFI>28+N(>INGu_$>TNwseZ*MFDMl%V8t>4uy=Nw7`LmVZ3CbAoL#A#IdeqAE$`#+llp=!P zkKP_`P(_ypGlVttTG2Ka;iE15WjDM_@*v%r?sv^<`rmPl#!+G2nys;uCBfZaj-%7m z&iSfpEL|%eaz&`HruTM_F28EfnRskXKUf&)nMv36I2`7_S1qBn3UM?@R86gWTK98O z+r6p*ol*%YU+=0x5x9pSFL_DjDA8GRE85&H>`--7UkXNOhd_5$bif;0<1m+{F#QSn zNc&}&?FW0J&=xTkCe56`2@F&Hc&Rb}Ir_;XtAtXDKsUS1DFfXE<+c>=#Fj{CxaTd; zqYs35K6Ce*wR~OLz7?G~b=n7HlIHWq>67HBpwb{_tOef1-%M9mi=Pm1V%dZD2bNqq zKb6((5A?0;E;*4-XP?`c_TiQ8mMf=Pa(ZfJSG(`gb>vuzVT{hD`(0c0@vJ%NlG=!H zbk2U(F;PUH-eyOZ`RyQzbhD$m zZKB2+=nqXiwS_`B4ye-8V>QTh8)}3VR$i%^IxWY-$jEd@OG+#RTvR5^M3t$Ow}cFd zAmn-Q*}klHQ5!qalDo&PCWc-gl8p3xcDXfHy0rb`$KIrqmBdqTKRSq^$E&>gMPg%| z70^MFpaaXtBay6LiPFj|7pG3Eur$+7h;=%Zevl|OouH%Jmr`L4<(Cn$MnsyJo=#_k z!p6onj!WCkK-^-Kgzhk{k-JrRs;N&_55_+MpO8Y2i^pIqn5z!JKGpkY3gDaI6 zh;PsGzbUVQ@E02QP(>e;k^YodQ6~y&JhlaWp(-6AFFAg4dHY%$@ff4ZmXI+3I&H2& zxI{!CzQ=v*#yBBR{3tYxabs*!1??e2$K8}ndmY1?8!Y9CxX#63>@GDO16hlK3ZoPC z)(L^87W5{cTJ8I=YuZ}!y#*liz2QoYs|0H)Y0YMbot%I?+irb{m*v;cE4%#uVcpVr z4%)N+yx@mqO*Sb%2UPs2!77k?hMIHUb56JP1Dzr`fd0=vAZw7_NE<&^b@CK;^kSvW zv3m~=c0X)XYihSK_B}us8VlI%c+%n|Vs8b;)WYVh$Zd^#$6!L~;T6;|dHo4dkCe*O zhvBTo*N5&UrJgVO9%%!cY%DLU!_=K@ijY_6);x0?Q*voc$M8%lhB`1Ll$E4!&FU9J z-?q1l|FBN; zM&xDBZ;i5@e|B^ts42J%#`+j|dJz(u?}QF2=eH5K{vC68UdKVi#^aNv~4|+&w^jkO`HEHkal=U9{kk(t~ZQH(OX1VXknd`}W ztqW=T4e0o4dgU_xtnq`}=!6N$mc!=evmMqNDU5QH_PL$v>xSixCsc}+M@=sr*k|th z9$nWvptd|}p~Ujs>j$llNPtF!(+$y`Cc!Onj=aNV$#nHwAGx|@uMJtWL;x4wKMgcl zazcOFdZwdyN=Rd83>eYfNr~8@2Hx3BtW4>*Q2`y0ba~c0`MkI9Ol~PCh*7co(d^fd z{*sKA`H_HzQ=v)TyK-`Y{s-Uud>SLs7US&L1&NS66;=-Y0D4d9!>wo3nn!7s2g4K6 zN97nb==evS17dTd#e*e0wgvbjBK2Y?;-ApzO+v+DF-8GxamP}ZVpJ_0__{kG#X^#j zF;jDU-pa)vizghi6{-W|rqe4$_klw)%(cy`_t%)W$RcBY-QNU-gqPRg)df6-cCW$(u_&-5_MyxDT$>_%@WH` zd|l0^9J(Pccc(ichbWyT-?TS%TLL})cauiG-zjrKCpg ze;KEkk7oj^5~rFIo06xLD!%sAPhE|O_RI#1c}8X42_11brS5Uv=0j>$@lQIBSaV-P zgFbD&PkgQsrJZvTkYfRX^{Pm=!$Omnl{_!D;JpFwc+j*nooqN0#9wD+!t4x2?*M!( z8`(JF=z}~#e+oYl|JdpQmFPWzsCssGC*#IcOi6YdX)T%V8noM+-uF!|cI`VeTukG{ zH_=JQrl`P}Mj-xh0UC^xpnLiED}owP@ztHL&Md;>pX)8W6s_1>E?a$dom-iKjAhpl-Iga836t&@P#oRb|F(0xr(2=hms4f!k-l za9k*(ew8Ro56fxf?fb-|Cu9H*EV;AkF2USJEf73zp04FB$k?PpNL{yZiiF*yaxCeL z^utV*qU53{8N5$tVj~q_8yrWoi_U4IzA1iKYL?lgVkg!;Ss7KCE5Pk^C+CfrGAfhb zsR@3l?sP$enA3>tAzo{{{_ReEnlu3>J96#q&seI{0(;Bx1(5{qska_$ujWf5Kf?y8+g=gNfZ9Be(A3$z>!W*W z)LyN($G1rWtyY^oA@&KIq(4S);Jy8pFQDL={vI*?>jG=+j$pS%uFYMHDM^ggF}Id3 zk&rzaCA4^2FfaNZdP8cfwX|qyL(q#dLmO$)UM`zbfk8R4{F=|a+jOg?uWpfiA1oR~ zE-(OZy0i}tP+{lbA6L9CK*^Wru zeqnXWniwj|??U0{^qp6oM}zhY4}RQcAYVqlY@o6}Bt=ealc`dJwD_}H|2DYr=w`0V z{PBGwSsRkM??i%1>os3`@D5d@k58yI?ByCV0B3!?D~`X7a4?-PI@WzI`|g$LqKz>b zTyzhR>*WphJ;J4tvm$$lOX~v`*Y)ap1XB*KbBV9KDvf|?ul>O1CarzAJq7tJ$8VeV z&gy4^PmONkHs?yKd%fAcgK%CrcdzM|H>x`hMzw8@jpZRrG=04i8@$L)9XDpbv}u;L zYQF7e!cMq$&_3_e`4sqLS09X^ztyg5R4c_?Z*1fsSsK=Y8&P{I^-^~u5Fg_2~%wH$|^g!EiNhFG` zEml>iNhyrpd_%58Q{|&+u*&D`betA{zr0WYQhRe5dDm&i`B%+bFM1qVn0WUL?Wet2 zPCVyg^U)cP%lHa*t!K@qzIBMZvfoWUySk5TuWyfgp=v1fu_aj8V29CuNxqhAh^xMO z_Njqxn{T=ig=hLy?KY__ElOD!?~Ke_uby&aS+KEfKKepP=+wZKZ!)LJW}_Yk++!AM za*46mN_FzK-jM6tzveT9a?9z?$M>nP>%|W9Sl;!oz>?e42h+YH^LLtFI`kUjtC`2= zYxQ-sPUlfwK&Ol_f1}uzbMfES*C*c`tA-j0ehzDY=cM6g{$!%c>3x<7Yf`f|u_S`$ z`{CuPLw-ds1Ut4gyhNXQ%q1H5Ts8Y^#@VLO)=qXw%*QQsw(u?uLEaZ7H@M^Ww$fie zPIMHtEzQ1U|Ni8mW$U~Q@0lmE+XMaeY_Xr7EKTw52ZeB{wdUI-sa8Vn9c<)Pi*G#V z(DthN?2_-}?+?`UL6cBp&#U)m(!6(&mY$4y&$G}DLz#z<%zRq9H6uAne0cVN*m6%x zLSx-Ie{j)P{mt>0uX>K3Z#3C1v>PO5bDG=d{S(3db1#c4$!KR{RnW+un>|e@wu%NA zuqrQyPK`t{9J6mMtN)*8w1|y>)g`~f&xv7y9W}k+|(9##|+(4 zsLrc_IP`CcKWj^Sh#U-J2n7;nJ1g`9OVkN%16OgG>Jlu+@@i$2dg)>Qmvi@`A{ass zlX34e?^k{v8OpRC$a4HPUk#4e4uJ2WpE3l25>94sMT_N)->O{Ndg00qp2?KLk-jWGtwGJSU3H33sP(WY&QO( zeBfc_L*C`5wk5md-fKwY#JBwSp9%iFna~1kWp2p%FXv99kq?2vzP`R79ER#o^#x%` z#6R!RgZz1u-hcj@V2tbA*A4{2oTZ%tVN=@;3)Q- zKT9Y%fHkF7kpH}`0HXZwM6h%+6-1)A{X_%yZ!}a@K@cgpvJyyD3Z|mUp#f6{ss0TO zaK@e~NiG!#7w-_o)KVcx?uwO7#ev5&G0QQ3*Q~>*N z@F2g(fFq&5V5t5U1C9i=L*OtF6u?vZZ}0p!1`H1Q83U^HTMQTs2t{!Gr%E1FC}j1q1q942TNH=SuKD@csv%LpdJ!2}Aj}7=U)b z=SoVzD+lj?@Hs^J*LlExhXGNAaC{D3iCrbwKlvQ`bL>KX$qy*}w-`tjj?V#qz*q2) zzsG=cBIzfL-{$#h_CXLzf8fD?kD;vc>pXs&=MXp)@HrHU1gaMYPx*hqfczS}zs+-w zl^`pgSjB_<9s>&fH3wDyQ!x>%6%)Dorn35`y7IP?sOGD=WWE~i=Bp8Dz8W;v7(k|weqx0DEh89^g9u<1QRcLP^_$@)$%I=rreqhV>caC3S^bZNw{D(l0 zsvw%*Po)i}@>^1zk|6~oh>8>fs3Ct-Jyux!L`wDljufzbAbuqUSNa_(IIu7){Xt3z z`nSQQ`s+Q`kpD|k2*_Va{Wjv^2pA`{IHcf6_}|4B{MU$w{}J)_u+=3Ewz`(VRu?hY z>KX`NUHn$yf21$`&tT^)u~Z;ve%1VED_#c9y}WP~;B?3%Im0eL0}y96+p0M~*;tIe=K9F8AZ9H!Den zSS7=GDhuZs6<%1}0mLdHIu%DDk!gUoRZ5)6AeH_y`#;l0=U+cf!Bu_|{I`!paMgbj z{LAMWgwj6={^i370`gCSf7$&bp#LcN>lPlN{7-^^`OJcV{gdEdHtY!a&w~H5>qa2{ zN$@Y*TEs7&`B@OD{ENX6D*vSMFPm|M>OVsNy4yu6{gdEdwya3VufL5vjsa4D^TY@* znv}|Fx~($jL$2mCay6e<1C4LhpnR(cd@8FVDyt$tfk6Ko1bCrve&x7Az#RO?gP*8? zX;#ina4vX^7Rhg=+`v`gQb<*(15ln;x3$#O2R>mfa5Q`HaUDIdCC-nw`a4do)i>?c zH$#V&r!oNIdVq~qH0!~nV5<$F+^#lMrT!@T|M_VsAa4i(BIJ)vE^tB9%ZmiCgZx^V zkbg$u-~7z;kDqTslvRK&{9k^)8If#Hl`YOqADCB=|Ee^+qwUUQV1oY#-8?~z3nyOjMAn`iyJGz1BqoWOLkIU_RKXbn(_gEQFnX=@>D0*x2Z~VqSisIP;03ksOt60h+ff!=cCBg}>7O2mrT5|nUtiShqCGO8Qe^_*)=urmo zolH@axP#HdAXKCpQ@l1dmzWqTS(ZAJNhOE{$KGemWTfzkFQ$w7a_t_=jY1ty*9yt? z9CtWcA|Gz@SmjBEw|%#Gms#7Jz}+g@Rpnm&rJ35rOl6yrfeQi{Pc>E4gTnA2g|~9q zRb9UQpz`UyIyruA4U5=XA5_`gdkRID5H=|C0RJXfJPs=Xv);aYNp;LEv{2ePoY;R9 z6ka73cqTIE`J)p=ZA(?rI&YD9|B%ts!Xa_bZ)D*^g38@x5QSna?+nj=%;WLP&7$^( zNMm0wYmHXV*2kNX$IOIOSlRyzP zOD@a|znEr|i}erovBj~epT+fv+SN}Yo(3&E4oRM;%(YB6g(6S9nqf+IDLUF1WToh2 zK)%*UY$~>{t_}5H@Q9bzmi&Gt*I(pm170LEFeFF~hw&Vv_hm8h?`rAs24dS52ernO zi-OTT80oe>T~Ug*W<_s%9El&}wt}+T3l^&0v1T4%!udZ#x7?IZ6&GDR(nW`C)PCOB z4JB3;*`$38?bj@!XN^(agO(iZg4wlYL2vs4YBTV!u>B&WtMs>eVRL;aD9M=qqMFym zo+ZAnwME{ZzAxH+x7qh5pl@imZ$1^?elyUZSmT?|n4U*SkSo+#(+@+i3!ZzM{y=Ww zoHV*GZMMI>PD@Yc;H6ue(w9mHFsadzFY+SMZ*<}dtDelLZY(B_E-29q=UBTpJ3Lb& zXEs%A!<^<k2FTRqH$=sdBie*3R^F4KNuV?iI;Ro!X>cbE7%kZ{wmlb8)9`sI| zD$o1vqAo2)CT*@YcM0}M_KCRISAHR=m;BbZ%fh$LL)z|UgjXtMPF`=@OGX`ONG#_ilf#EQdR3s^?GcHB9AV1%uBfoI{uChn| z_YuBEmc3;YAs{%kAs8NY!IO5d~<&=|edpTb%if z10alA?t`@%MN#orPrcAmEYt{_?=8GM7GB*~>puPRKnL_Qm7dE>gn# z7h5Ik%HMx5aFbWsZS>h=@ceBJJ_CaWpCmrxV6h-OHM0}M@HFR>ioUzTf)rjvyjOdd zvO6jB^Jck=3@yd^17Y%DkN;3)EmwHCfFAr5?5z%Vd8c6 z@wDE`P;rGQ!T$H=Lh4PsoOdtlDp0xMxE zMVc|ySuF35Zy0Uo?mUwB=xvBBZbGTPEkoVV(Dq9JhY=6?4FYa7j&>2`^?-}&239*;;dC|k?OYWvu5 z!tYC7*>>&Hx z2S*jLf`#-@?(HWP3t-ykzj#bPN>fW@dqv%+rRis_ZQS9@>v4wgxUT@_abd752=X<6 z8Rsg%Kh{a)yI7NjsMB;ZF;Qaf(kuFw+p{x7kB8d%=8V=&b&>8IR)(;3+Ep<|PQPDp zsfYGy!^blcAu@$qBWJ~os71UUb4rr0TJ(UyMFJBCTCLJ{zuXQCHoUT5xJojd4zFR` zxl_up@FBi~X3mmX5&Z#vYNGJRzhN-o1;Q(rX~Z0XhmlZ-c|q97 zXI5rHS1I6Ge?)CgQZ|lxXP4L17ZmZvuuPQG7g>jU2$r`2n>c|>Kbw9h4w8i^=-;}Z zg6ZEmci*xjxCHU~C@~D|yOYsDob0Y*HD}?PY^I*y*=M(<&Ea@)xK&4ymwi-cS8DR6 z&5X9Ciiyw1@)MmZ?cTr^ON5zIivj)XfbbQK*M>U=SUG)3e}BGb`;6!EF)KxEY*`y~ zV7Tri;A~D1AC+l@n$03|n|2H2&tXKT0O zW=sckUWhXyV*2{Y4FMj#wb%T@Mn`u6k%m^YvuH%6dkw$XBE*@YXE!`M{pDDqU9G&w zl#-ZwUt6`=!<{!Ii0PNx5tW_@NDG7_Akv$(AVO#fMXHE^0cnO_-wNv9`=0-O@1FCKZIeodSp{dPMy!K7WEf0!w~6As5S%~1;sGY?S=mbhG3W#QTu zdqoH0OyIU!(~`E*rsEqto0agDEw4{&R#M5qsgkZ_<)f_mphKGL$%4>=Rk zW*zp5+pKAC1ucB06dBHzZ|_ajGNlV7G=M+_=Ma_trAfMIkNKWG+e|2)S4OC8%?jPILer8 zyFMi+Ib&~R+jeEDM8L|zB?bg75x2je;XD9QzyKocBowO|y+_a-6nJ|@s_-vcxw?{vf=A&&b)w;CkkyIjJvT7Xw5^R(V zsa^}l+8k}jq)pZ?pDaRW1^>5Djxub6xe!Revcb?tgFWOH0QUt_gwFC^DwPl+IgAi( zsEkVv0~zLI83fvYZO9WfK)#h*Im-fJ|nz(NnnXVTVqkb!=n2*+wa#T+sHi~5s5EeC4EQ|dKR z^9ZBWJY_3^D*72+3l-dOFx}57wMtms8Ik< zQ)-C`oeDR-om}XvTlh8DVwg%N&(+egw&mILCzC{@LeUVO&0|`yklJY7`NmbX+7%i;)pk|3{szy;YPZuqjN*m1CQRTTWPza^Y@&Lu z6aX}SLRCpCBfr3Msu*8-`njqXB12R@G7Ny|%y3gC`r5~!X?ZNa&}}u-+hLq+^2Px- z=PsfYX!*EX6NGwgC8=h?;CHnb^~8j%e?cWn1}sbzu^eSS2K-E-27d*q*6~Ly0^WX^x$YS@rBl4Z{2BGRUUBf&byQt?1ZB=Sg z#)q+Tfp?E7@{bVnz*yMsGSt2(jih7JW&;v4%swT2M=~OMTj*PAB#WDrtKr-+06RxP z6`2Mw;iEwt)l&?BWV-pCyVHI^02VG}-Q~s8SR4UAavGW7K@0hwWz^&pCw-+dnO34l zb-&&XYh4!BPi4dj%%WYr!+J5DBQweVc#2$*-?7pGbOc)hIOdyQ=~3&Md`zB{iXz{6 zgRB9@LTRL7W;pJXLEDX|7;>!*iXyc4 z%k{C}I#>H|7bOTcMLhy2i@OXcUUq-#&}0z-7-F-jr_@6YNA3j`?-@MW z3PY;}ilYrVNXvzmP}ei`4ZDwjRT8-vo2^6W+Qy8PaKXvQFk0O*y^(?{gdTP;hjVQT zW^T2Vnt%(2!&zGiH`?A9M&2pAh_Q_+EK8Cv|CF6BjUJ4X)OXd06eIIpSI zM7W`o_g@Ox3eL(;NCq?PQ$@WI^(=YI*Vxl+Ae;BmVu|5e8g00YV%Yqs$Wx959`qnx zc+tJ&QdwBTx`OmUhegTB&@j%07Lu)T&~AEZNadkby~W#g*q%^7@De}E3s8HA4QACG z@n*@#taFf*OtAQ9U1`NIPL0Yy1EH1QJpfR{LhlzjZ!4|nA(keuCPO9=(_1}j2_GEv z7^PCp7xnDjn9UiFtPV+c|CHP$UG|g0(*TMK_Q11z(S(w{kZ9F=qp8G@Nz9gEb*m0( zNFxOjNL6?Ua;|PbhJlXyp$^217orEah6hZ(E{xu`?c28GoelK8VGA{_HM7ub_GhyW zIEDTGA@OY_2icuGYWk?#UCF%c5@TgNyUZK!okg3c0KShToH z*L6R6x9HNOf$5V!J>+OoaTFX)xJzoyQmY(q+ozz*vM1cGs`A!F0>d-cle0_p=U(Iq zHvTDH`fz;_cC$7MZxP$(QRfy{?Ktx?TE5!e+LJ_nJsRQGpQ8pQc{I*g{$Fz48h77l zRr1?5t6rX@Yes=K>%|y4!{2@w!wk7T>*P9H5X!~^Zzc~lF+G}M6Ux)V&1&Ann*-A; zXqhu7+#oMOz|2msXEu8}Q^ewu!S@HLZ6UK+Xv#|eEers5;pGW8eSAkoPh|DyPP$jL zUFT&rC$?9?70zcJclT7{SLiW19s=DQISeI0jZ|XVE#KY*z0an1pm%1lW&O z0m0Ri&w4D+mg$O|F&nYozgb6=c5ND)yK$?M6Nc6_GITSrlVvt73BeWaBo;L#UyoNW zks7Np6pxZUkM4?0GlCCTyUI z(1+QrMGXey+U;O@AE|0O&dWmNF1=jpQ0qUZNu>5uQ zGYgjE1YZM4AfM1cU6>QR-lAch7&7(@)wwergoTq!lC3LXk8R;W2G&>Sdsj#@Gig?E zz*i@)^nw*!CLdKu+u||0l^jV)!hXZl?}e=oE7{GO}1| zmMFi#0xyh6Hj16+<97d2)3-Wrib>R{mRWH}4b23rOaIqVZ;$0q%ao7FC6DuQ;0^+4 z3zi!81qVA3G{L&ky7a!Z0|fGfFVP%v0-X*#;nrx$reT>ee;wPZZ2;N6$TsAZ^_irF zLluamofaEbG?alF;Ix}ca+Pu3k)Y}8{O*}$or9F53(_%1tAtj9whrVoCDl+2!w=Oi zpH2m5idxaSi8*KNPOn@sn?ZUBay{5`;U%*4f+d#hJy{sbkx!pu0AB!iDr3@B?swHL z%(*Xt^uz{*U7<#}ozQ_oHhSY&LiGA6pwY=+O{?bzEhmcnHk3=B=Esl5`1Es{Z=4)*7~VYqdQNi$AXw%shNnKjE*+BrM3VH zQP)754#K76l!2)gMtH=LMqGe|(RC}D9K2aeDFWLE6_Th1uNKf#_$mPNSqMy~`P+h!qH7m)kV{t3$p^G^ivJ4~%T;_(((B(Vj)pSAix&z`0Z;-a9uvZi; zG9JAG>*3ey4PwxNJIo=^PSAm$-Ocqhf1ym{W=@@Q_fs-T`Q3yT$ZPx!->bZ-yYgYk zyYk5@SDxBm%BV@X8=TC?%ul$&+$#R^BKp}CfSB}dU_k9spKlEv^L5K5bxppPqO(`E zcDj{CocX)1{1Tz={^Em{uGq6sg4!h>aGWv|9=Q4GmX`tU3bPLWE_0Xa6 zSRr|Wr|3Hjcoix<>%Ii&VaKv|)WWU1q}V&Hk2sT2Jnt#r=G%&%z@*UMf%7R`L~{hw zCXhx-kR42UXtL-R(NpxFN1STE01KGYvLc-TlOJ`u^;3(R3TH{8R|t@ebxo+)iG2I; z+h811v`Y8~`I!&r3jsL;SIDk?YJmvx#LB&uIOD5MBzJqM?L^C`xkPu>HIqC z62QLlD4JSg9Is06hj%UbH`P`|SC2<@kR3#pb)tnM7!=3Dgr~pbA$FulC-2B*WOohV zj=aJgSz{3{0Xq;kl?~GqSzc^Z$&Q|)5WGRS^2!2niNWa{gFFx@WgtLWV$V*9K(FZJ zox?u{B7Fx8y^?Lqd>saQIV-WowZ3iEw9+k2t$?b(MxCDOn(<1RTH#r!h)OnX;u)GD zC^IH_=5BM?{Y$zfua#MDTz%D4xA_>!voBh~X06=3qGU|n0ytX=n&cUw*(KwD{|wCl zpp)O-sF~gWZGOsKc{tz87sy}vCqMJ}SfMR5O}_mln(#CBuPbMQ@7`yh5X4(dJaeoFE%;d|=vS(G{9!+WaYyY8P4z{oD_xe>y&i1um1zoiUs>FId7|Ygy~#xaBs^&> zhk{z`zh*q*!|#lj7qYwL;k0+H_LVY6%gI80kjj;|vAeX>2|4-bBV7i0eB>Gf@jW}S zfF`^1=nnSEOHiUdk)8gkmYk`Jf2>70xgg2f$u0^dS8wgl`$sW8#ZRz4)he!_c{Inc zzD>O~oF&kefP?qZB`?$=^vvX1e1M$0+GCrWSs&%le~aYgr=ykFPBAe)+z>z#92%zGt zxp#mntg#0w5v%~>BXba~f!u38jE=F$}S@Uw4-!&o%LW|z9M(jqyJF8&Y$Bm6^qE6y-K!!~SG zEX_L%_leys63rf1Bz&|$Pt3nlcA~|$sRmYGiqCK@k>xR3m>!52%uyCSB^*K@uJ?^!kGy?5+G6Pb zmdpV#S*sef)oFvG4ORD?aD}1gU&mdtwV@X((J!=0v{-r&VD%pyTaNXmAL{n~Vhl%F zHR|${6F_?`B~9lvV#u)nY)bfl6O%E$Ypb!EkRAP5NlHFl@CY|Tjm&+Ye0cEms?B6uZ{X3G9wKEFmo{O=C2fdph7^)6t@K3YGQ?G_&daycB=YpS&x=&eUdc`$UU| z5|bDOv2tcbcCoToIhK{AA%cHw-IcCB8GduJAldJ9{E53DcX=VbtPs>-(FcACj>-(V z)5?-wYM>zTJPKf1TnwIid@8)#3k&DFcq-26tN6wE-irtlXY6uD-=-{L`t^Jw=x|$S zI#Hxf_AY2MTR#SsH&w+0zIBxf#)r6dF>tK^uE3qkRTOxU;Na~z5NBny?$^Z9`(t-; zF~*X6;}(d9oH#z0jCYV!YHRuwuXB|}rqeIg0vl$kY`W6zSi@W;hEAC6}hOO-HAv!*YXCbVTU?Z|ckAicm<88!6CTeWPU-;r zMLEPf*0W?{m!l10UiDNeY%X}gwmAxPX5t(~uFn3}Aafe;R}pbgUGR1RimxVM!Qgap zQ?I&LWc9t5vn!lnNS$%J#z|_o7Swb356PkW03K(#wlkLeQ&0oJIwt%IZTR2FLFdT3 z%Gs)Ir{d70CB@Ur{puI%XbQsEtN;kTKe^iK+DiHAGH1h*`0nH~10pNd+LM2T<+-|* zLG-<8Vh8cQcQ*I{EBB>~d1nQK`+;3%xYu_y=0n{wo0|8747}Q$qQ3B*4Rr|nY3Jw0 zymbrgj2swi=jOdCdv6}}6bpR>d3&2F5A_zq){nc6J-Y2OR?|DVv0i0U$P9^A89S?h zf?JilrbXCe^6kAdkp9om$q+;SQD*oUAF_Nr48j3bNC_;MT<7==+l4GwF_}g2ZN%U9&pS_G2WDlKEKPFwssZjK_Tkv)Edaq7BP)jw|d zmpsRrjO5*y>Ju-ure`6iJCHfXyA}2SP>!v1k4xwR`SbFhGx1x9n{@%BP*oZ7PM!_M zY}Pima$2A<`vaWQEDt>u27j0J(rW2z5KVDw5%WYtl+Fho!`$D;@rv+YM+fai%w{8D--Cbr@8q4) z5AlhGaRPY-sq^WoTT}IaX+-DT44(>14%Y_>Bli09@_%{eC9-28diyhK;{~D0r zf-oNQu4A4E9cTu`kxvo;*_XOP*#>a#P8@EHE`2~!P5n4u16~?Auk>itmF!z#?3KDm zAfYP}g-4P6^(cUJ@AR!YW+1cQKe-08WRe>wgTQ_Vh-<=i1pBu^l1nUI=Qn2;&w&wv z(-)^wzlxa(`km3E6K)l+3!Wl#05xK!0|~gs+BKf0*n*m#jey`P1Y6#<;t~Zuqe_g9 z60VEEc~TgriwkALq>!IAOhg}@Agjaxfj2()g79~Ku%9MNJ_V@uz|*Jz?NWsS$RqBF z_r0zhwYQcgqmHUbgbxr|O94jYQ%_UV4fs52derj09ZIS7%(&N1_^EL-+%+T_D+n`d zwD`&gzlq4xJX0B6z0CHLI+~Mdc|rb6rF|r-N(eUkq>8tY74p=6OjPd~xeI2=79T~1qZ~^L^j~oIZ0U+%-M(3Tom)>7&88K&? z_yd!FiUoYmOegP#o;bS^U1Vv3EX}p)*+B1{DTbcfy*j3v6^hW`en*LHK0d}!oHqqD z1smS7>x6yKouh|Aw-A9FXuLX`Y{2~A=}bNrd(bka7={EgdvFToIFnm^380%@`MFWJ z{)1eA>~TP8EW!AWo;Vrg`Cka8OXz_|Be~3W?EivnPD2@%nHobD62XgOOA&wf2CpAg z;pFb9lSd=WPY7kRI z_;SKJD?D?Icl?of+O)w0Vtbbl}M)M`SM`SS(1;Vv&? z=D~x`WMhafU1MtOK(Ls?lWh;x-Ds-7=f*x;aM+lwW@)6+wY0d`o{FCfJdD?LK+A%$ zjt2Kencu6DpXC~H`|*x|Y=$wbI8BQNqmgZw&+=k@=L-b)$Jmk~Vb^N$H@FrP9u-O; zVCEJq1rECrd&%5JsMGv2qux z*_fAh#j=5L<5AbAQaL&V(b*xVXSMGN#jEk$1%1X@l%xedxC8g5>1V75$_xHJ1@UAX zKH7YqcTxGT%7=hVX97#|&|R-FVbMV^S2nhhqQG2$nQSsNHiVLQlSaZz#ZCZ}de&r(w6%&``;nEQet;SS>a zaiM&M%dv3*V9pRBs##v2cBw6pM9kQQjeUYT;G{x+kg%Z7=5>V5JtMjncxTD$g1$bc zP7@2WORGJZBN8sCUebo7RC#skERbyO79x}D?_-)Pv=_eWJ4gCFYlQ^p&<%BMHiOz7 zg$Z_HojPR3=jIQb=Dl4eNUWi?45P%pybsc4-opKPtfKMDR0sU9T%~cfCqA~TyVe)> z)QlaseXi^Iy_LXUYM`X+Nv)N)DMlr9U!A^^D==KZu)3ksC8pYN4_&-)OVqz$kzl7O zb~c&KEQ=L!R{fFhDt=MIVr&-ETKD*4#Dg`RrsLIt-RZ~K;O~XXJ^=T8l_$iX#=SO5 zA3rX|P*p>jMb$d4E+|N2uzguWFRO2$np5UlCDp8Ha2=n4&#H(eA^iuW7rn)r>_sD5 zT=i361N&oOy1PaID-8046D@;gFzMkNE?MA{b0nTA+UZ^y*gGCwOyUJ2{Xo4dVEF1> zR+v*{pSRtR)LeU)M}h{TMbmqT@a^IIgp-$|`+~FGZpaB0jVZO8{xus=iAp~`2=+MH z&zWSvnMbl!b!~iU`I#~B=QS^emU7r@u5?u%Wk*Zo zxAub^a}=pur<*)SWb{66@kev}A|&OH*Ds+9ZN9wk)0nFYv5{LW6%VJ$w=b9*%a1qU zeC;AVQk64TF*>e_rCBrJ-mL5xtw}WCJhn0jbwv$=7llnNIz9=0(->I;mmjA}Y!5UZ za#D~6heVEBVm5&#+R5%(;3FSVq>ZDEXS2HhpUogy@%-WA!gV~hC1ijpP%!H%}Go3^1j6OEi0N? zHGsB$Vmj~B&mWYX0U``~Rk)Wd_jxNe+&YJu=HAZO_&%BGzBKmNWx4a6QO}sOyi%fb zj`ee`nVu2cAD0NVx{9?^^Lp+oFJ706=#k-DzF6LFr}n|1T`ymc z8|F>)y*6VVS9sv-|D`cUR2wn#aIqC?W`RBSX}jdV>)wHrgHCcdEY|c zQW%%aw+9K<&Kh2oT~5g9ZvJ=cdexnF^BEP-kONqMSM#NHt!v)DTdB7=v&`gjhW+nPA&IS^l7djWpjApY-Scy0P0n+h|7%GPB$Zk~^3x zSUKxcE`hHy6U4RiiP!2I?-cLO<`(}53UUlb)N|sT7lR@u)kg;$gGPn*O~nw|E2T7j zry64p6&v>#M~fS_5f1YElLzNQBP>4lhEhQ7vQU+kCiN9Qex!v-Y4M=#nYF#naiSY( z%Z;=%wZ`pyxIHjr3Ni1iPB!1%*R`9Qm^j$+ishD*l@$-#?^!-{Cbf{pTNcJ!02so; z#ksN0-!+=Qyu==x6+Y-8ZqEqqsdx>XS;2Y1&iMY+Obuix=UD_3GOw;d(kFs^eVl4m zq4)^yHvac5EcI-=k~(P_a+Bl!RkC4GyZ(~(4fYN7f!qCiYg?p+xrI6Hy#DFMT+~p~ zRxXcH*>>lojBJ2UgWn-fJQK3681oc@b6#3TaT6niak05cOu_g?mO~F^ynyeWpB|9@ zm%LY2Hd@A2N!u;s3q;}$acyiY%?y#YJdtX4&4S?+w82F*;;lbT(uJjPV*dH8mGsVD z_i+}dRZ{se++@&x!Q}pWM0$5<_zMop7arB!#Rmu6&d7yX;_CML&iFp2ID*0jWNa+ODJ@3au-4}yR$sr(pPbCo_=Rbbs)CB*PV5x5L-X+L>?&Si%jqK$K)qR+ zzKqb&Cob>a8Y8-29-Ek`4@dFo%q;N`rl!IB`ezQ3E_?2Gu8+$Yvj-}F-h}kS4_I4~ zjj0phDaxSrsr7YYPyh)x*OOk1kd>)7k&$gY9MFA#MVzLIL6kRMGSoOOYJYJZ*EkUo zZ&+v%kHx-eUU6i`KU4R`dGAxJkt0_Ky>?vagXE!v3pM=7bXeK*#Q% z#GGxU@R!QmxuDb~4RfU2xXkPBuN^kw-}eu8?p7L9aU86*EGq~>4)>?M8W(D8cJG}D zkO4RP?8;5NyBl|Sjn!?SZl7ssIe?h1(KFW;w!5>mfBY(ogV5rk|CG)Pxj+U8l(aKE zrhP}F^i9&?_}(MmD&9^xlfy^%ue$~KafJrbVD1HZX$f9buwcGruiBQ4>8J<=ax z)+n9I-ZejW>*q9)c(60Owz{^$DX=+j&OO9y(X*@|bFix+x3{%&03|7ah&vlgJbMek zjcF)pYL)b?pTx7fHYLs1Q&H7RDOV@w>KJ(X^CPGnL$$BlzWe^tl594j(6{hG{zspE zOrvGk?n3YE;W^1P;arCX(`Mn|;dO_tf?Q1lKF>Tr9@#f#MMzq=xPMG^D^x)p~iC<|7Y4?J9~oP4y@FV`$QI0KK~-jy+JZz1Xy zoEfPfYDcyE-QQjg+In)(g)!JEFcICK8eK>VN@dv}pLTo7r2l2nD?6S`l(_?R zcDC3N&m3ybD46?0*OsGm9!-Xgm`(=P`Ms$CS45l@JJ2Qdw0j9VchfTBitWG2y>d(&?owrbbidH)DH^CjB!H(R$0mkmA^7`41ub89k$Kk?B<;bTiVA z-81YQe9h!uCu|dmiM8|bCxkU}QMKtUGHaijvISy?hWgkSW<#n|_8l0Ow7CQJw|AaT zudNZs171l9+#(2^*deZl-PgcyHg69_?A8XQb|W7{bfRY0R(jfnd3Zx0!Wuof4)b(~ zmM?4DQ3i@L5oue*)#uh;-3?M2RR+M_;F3^DeL3o%yu%QhwUJ|R2w0sQ-9+Sg-=g@LEDUN5jMDQ!g_9xQkb#ow9ICmx($ z6da$TsVf?L;Vj?MvH9t3yLwQXAK{B)Rl!%&YccxlrD0~5_YxQ6V^rUAUsYyrkWM$t z{DjM$`!bDMTl;{<(tB?b_f?~t`57-vbzG6Y-=i7?UWI)*peft!EM{*ZBkDYlUNb$4=co^q zJgCZFBp%kb>mL@5R7|eni@7Q}3Ywge`EEEgx^W0qgD{yE*g3f`e2`Tz{^H=T!?Pn5 zH9s!TD%kDLsunJdu2M;8t2Va6gNg9KAN6;jAXBGv&32k+)O6htb__FmAk(4+KZR-* zHGM9BP`q)IPC0rbCS!~iT~Kc7e612-3*e$BlL@|uI+NKPP*|={MHV$kuO<${3H*T4 z5Ib<0Z!`!0MefA@ODf|pDPetN>U^Ygc%LSM3O}&-<(D)wZ8Di|kyqf45~C*f@@}bL zAZmoz2`97%s3q->ZdZ7OKN3iOI|wo5f6?dRQTsMg6Fr;*KY+zn>s*A1Zx+CV zDZu7lsdofnx1CP4SZH=8zh(XYut>d@=fV^l`!k09eESD@=xC_}Jvy348+f~G`Tft^ z7EMNKZR`t7o;_Mf#`3mylRG{IiQp8TiD`-#vF3-@Tu&AIMSwwfdkDVOZhA}>c3GE8 zjY9#QiAG_Uf-}^`!qpU^V5hIs742w_<7h=F#L3h-5C2PrpFY>TIP9Yi!5z=U{gdHH zu{PA0%~v7SmOhykJpP_5A`W6|SBi|p5&VIeK-+BLumy%0w3T8}?itPk z3_$O|sZb5PIz6?q(!`f!vKF7p${5peM6)hCc9R8xx$BOuC7#2a$pjMpjC$IoDMk?Q zUwq&10j~xR=scF`0l8x3gI?i}$e&Nf{CfTV8emr=AjOSn2izUevnU>Rg194ENyak- z8O{Rs^;|9?!~5Rgpos_hT(SH9iRBB_1hoJ1wmvFF>&z1kli(xYplrq07O0N=xDFft zB@&4k ziLL(~bO?h2h+zLKKaTHP;G-$Oz+$NpcXj(vtv(_>C33Y2FVg{zhksfZW*l#BG(O(ogVf(oH8*^u-}gH z%=-QLi0bGdW6PH>s>bBtVD60!wd~~Sh~U^k<@tTFcVa}c2mM;|;w_W~w?;JUIF7^J z$3^3fu`iI$49D*V^OTp0MDLxVCfFH?FY(ic6C{VYJ_*8%-G_ilr-mGF25cr;IW1|<3xAgaIhPGKUT)-(J8 zWz!2zs5>Z6B%C1c03;Rgp`S4M!&wwo69EVopRm@1(dXqX3F&pRYeikf*#VcBzIxmn zEO4nGF$lbBs?J0Wh=vpP-asSR7ceO-HzZgq-%4!2oXBmI^mYiXU|kM0%rzKr4KzLq zjmv$dnM$dQ(&y#dZQ%q3aGpI-v(EH*9-x+3kw(`cJ(XL*F%1a4fpDzH=>ni#lGb}U z$xRqrv%~-o#=tKZy*1E}lId8XV)fJ68+(_>%DwiQ+!qDYa7X=7klx8zvvWApNN&r1 zOiFy8AeMRBW#?jE}M{X^(;7K*AesA+#4|3Yc3LX!K zQyqt|dY&B|K-%{~n@k|5r)xL`6~)L5g7iemWqaN(9fVV794?V?;y7F!C0KNSv?win ziEfsX?Mo(SeWQH|(xMZNaJ(8#eRZ%T1sRSb>;%qpP=Fawm-U+xf&%2;w?;rWFzW~Bj8QP=ugV+fF;xZzBDF0`_J z%FW_HT#t?$ULso+(UkZ$Q4Aj~h}w}Hk0&DLwFFza9ERQ^Y0)U!3P&T2GqVA8O}VI~ zD8}(rbBK*&n|rcE;kDuZ^Pq`5f6ljS^^DW+m4qj1cRYY;V~;|kL17kw~9l+Jl znwUoIFsA^q;X>C|JJ{cL9|tBHveX9eIlqplZ$KD*VGUYc_Zb-?dR`p1b%72erP)k5k_t$VinQ_=|Z<@=uB&vs)h6- z0E6gLY#l$lfA6mqLjUd$61aV5Ul!9=u}8f4LA{s72c=%X%UaAG`EP-21f!-|2p)82-!zKLtM=j z`~7ZB>9fTrc2OJp)(208OZD)K*C~8pJpx~Fq#LS z;r3f*GWOwd@`Rxvt3^IPniT+4B2D*iP1FzuJOv>0I_yLIggSXz0cG-$FjPkoh4@8r zI)gj`0D>C(kp-$Dj71H`;$u9YEvMQqUEai>)JFn7#&4*JA35SU+TK{4JXVk*)||_V zMZe9@F@5yQg2&gL?ulCcLWM`nZ(RDt@18utc9CpfFMYTqG>WB^Ja~XASui5Il8oD4 zy5~3U@EQp+D*HSKg;ezQ>fv9wDB{*QIWWJeY3RTj?o#8!Nkwvj)}OF zHoe8xFnXIaYCUMnGRNufehLy;O^K#8M^3$WRFLTKjYN?bMHX-g7L-kv%Id#Z13MGc3x zDswa)=NK{mn{-fP>DnKu0N(mi`hOUeoSmh+|78qK(Z7swIv3Bg@G3?m9tx5{g(o=L zdr1C^c45!L&Y9zH>@in3-id_2qd`B!m%NH;@a*cH5UogtD$$(4-=ndG`$`y%Ta!&E zTTi|+vHa(%qW2nXix87<;=S6aA2+?sHj_EF1Xu44D=qDRYDo z_?L;c%^E5_iUyhd0lsW?hbC14DhuP6kB%_3&?i@QN=rkK1*qjvx6L5ai?t`xp9*#Z;a@;O#&6t2fN(8-D~7 zKZn1ZkQu2q?CsDwoi}F_I8(( zu5MkiYhXWzs6sqRv8>`_jZOfTwZLrfS#D+F_=x0c3MWheURRSc`%J_6M2+hfy!csW zVyR7e-GNNDjMt#vLJxu6_<>u%$eh?>88|=}fe$EW^+RKaBRQ8-UU-Hs4sNI=V?-)4 zv7@rR5NEZ^qpG8_XUhRxF&@Y#to=Kc#Hh4gM17bwu;y`YxFc3kYwJXc`K31CzA~vB zf54N07%Tc^!C$0^1RE&Yx+@Iva7dm~?A&3GWZYJC} z52|@rObF7;)prh}9blZBUoLKF^jqI(e;fJN(uMq*`Sy&OS`Ba0@x_LKn{w$(=K9O& z&I3e~)Q$9lh&lX{=gstr_LjxXdD4cF)AI7>=D?!K`3vbna~iwz8?NT2&ZC=fdLeH(!FnCbnRrNeSS;1Z)3d@hJ@K6j@MQqrt=qxX=}v; z(;HW`c;(CG0>;ujciZ=go-skA6Zx^D$zS#ZgCZk#dgk`mS*a%5V`a^Uhsyf|c4W;r zlNQiBOGW{*W3t#2OCG$2vfR(x^R#4M$F`H^RKD8#jRr*Lw+E#dNGdlhVM60$ZcBjPXY)MbSX%MG)S63!Gy;=}aXsHt%l>Sn z#pckvVUg&@Ei~$VML3!!Mb@uK>%4wxOxniourg#IHiEI#TR`7bE=|r{+ac0vsidGg ziE$J^6~tFN+@0sH#oJous4#R0StUB3(ZGDac*z+pzb9+ETeLG(k|V9j zGCsVrx$O4QfNo&lXH#wNVdM_dVKa<4z3pC=3M*kO-i{ZJneq4aX{*|mRCQDxWh8vc zhwZWJe%ZipxQt=Xh;px#-{&naKG+*KkL&29HhB;y7{e=(mOQ7Zx#NFhyYp6{6&Kf3 z%T#i<%JRPF=BTU$5!cD5nN)K)y}fq3=wW^(H)Cn@nqJB7*W-+96g%S{lAnUI7%TUa z6yrFL>3s^ak( z<8PixLWI@n%FdLx-{x}nXFP|^@z;IMgyd*1(CCreU-70VJv3wyX7AZ`*mk)Az5eJx zQL(bow61Ik@3gnG&ht&%Q+xkpYTS_b_M4xdA6?k-mwxWeHFGs~O~<9GRnz>Wq}s!P zoo@^L)F{ z{tTu5ou9g4NjpQ@JojG0Xp{td)YH2{tNArOJy)EA&Q()MK@c@xzP6YvxH(*F^_p3g zzwqVjc`1p=cS;phoc5WFCI_3uMDgj>VNGKbY*yNV_x@VV zwug8y&q2(WdHQbQC;Io&AKv3$7Pb@*{!FPM)UFQ_ur#2LP)J^lGtR2-4Fru6zP9|} za1wsENOL1wllMk6^kmXvQ_FavbEo^~${k-XQjW82Tk*x$Ue=5xhOLCh9quD_5iAY* z&A|{&T46`t@~294m=&I@w?dn~*WGN9S05C}c(SgbQPhe&5GMuh?HgSP6FRy1eLqI$ zj->xL`G!d5!T#cntc380$lG`G_-8k*gm$<~YV=--3CA4RRj~zrsbeXe4>0^@)FTu{ zm+ujN(?8w6@i=0wpyagNNiH4A_9w5B1ufgmQgj^CPBY!r|KK=qaLktK#Jz#LKfZkK z!hF=KLHaZ_AAi`Z!JmB`j2~}(GVL7kB_kp^Hu2P*dF|#WNM#~{K#xiKBGDa1+j74l z^Gqt;9myA_$1lIBCbp}aX+7wWa(feYP0{efd4&j!v^A67)AQQNGX)<`Jy%PedbN!X z=}%Xp++k(8AB)K;^)^|zA|;5ZXP--58SY`dFHd92KcLe;1?QK|8UA)I3-4ev*ed8O zt?ij<90?-}-~oDdWVzHrXvxr)&DhIjAc@BVeei7p;&Sv_xl;sV@@ z8@jR9>URU;-CVCh%{D(WEFl!H*Y9!dRjh-uXSQcZnX9Wx`j{+~d&*YwGecbOg-REQ z9s$~u?YWBkFc91s_RToW?d}abbw$3rn*5Zm*U)z%w7Vr|Cn}fka+_n$T-`IHoO^VY=;r+Uo1V^A*joecjH9s~+6#$SHI6IZh<*b!&etB6W*r13xW*n++w;a= zRKN>P#H}9xkCaH}a}wut!RIfqhwg?;?-IG@LPfa3j@2d@W?5{NmkN)nu9LpqlslXX zRm|i*+;g!zCBe~CWO$F?(l3m!?FOStCu&2xV=YBKBki0!Uqx8Ubd=Ap z)Qq^dzB<>b7}#GJX*KSi`IxI*cOX(n7WNJT!o(>-&U6w~3bSYV<5MLl!*0f?e)!gT z-PEZzU^+*CD^CG@Pu0Bz8Y6a9rO(Z%Sn`hBi}-AsH2$n_7&@N|6&|_MvSQ0pQuhm> zDFLXZM=yO7^6!N5S9G~0nR(g9**uRN;~0+k%MX^vvLbU$*rB}k_UAXxLcnD={lhYU zf+j^*ltO~2>=m_b)px!;4Z5sPiRf0gBj#IQ4>ZUqR~<}`)KK^l!9t}b9{BM-T+_v{ z$J3E9PPPYkisKz4n}NyP*H+~?&{bx;ZOfb8;!7%Z9gn=Wl(=0DE-k*mMC&zSXGYJw zMn+Pe6PsLD4Zftp=BoXvfXy__jPRN#cv6k`>-}06+az96Vbbjy$7fmx`vn&=l64;J z9<=Yg5On2AH@1b0mX_Co-ox{gO>HTs>-ib#r>&hKQ4UDUG2vsw`zm=Zp zEy7YRw=;StYn)qaj2cmMli0|Zy>n$^$hHo0_q(&uXlJ7H-LGm99fxW^YvfTx1kBXg zlait zCfmFXqDu`GByZ+Iyvni~V*`&{LYD3RbK2efA56Pj|2L-H|7pnm`8`t6|MiEVA-Dcp zBM$=kkC7Lq4|N-rV5;BMcl3Dm@QPl%wc$Lp0;Mhr&D8suebW3Q^ZOSs9#g*X++W^h zeWN@N8&l!yepG7iJSp@gU0)<-aIXF-ks$m z`0f2$54@uI6NG1{q;SdG%dGF8W+~nq`im~Iovz9uq3QZT%x9u_O%c`ddlt)^9Azja z4*K@JzK4=;sRljnvSZsnS===Gu-Vj0S7ccf)xP@joq&QA$p&n+EMe9q{b<#WQaYHx zKNojwJo7K3@x||tZ=28+E!ob}RZl&>V_|ylhFy1FMU4d{bxY0FMT@R{JiE^|6LQ`L z^g7y~#RXDKSh%Byy-pbFX))0L3@9$k0Nt%W-H(96qiq7l@=7{D>Sfz!yCpE(8Gkvw zI!ILxR8Fl~zpYNLVWBfnSXmG(3j zHR3C+2ekYQ>gb<}ysx5p1v~X&L7Gb0r{u3lhoN)cdEM1AE2;ZdVGSJgEl=1?V(@l!Ji?{Ss-UHPlHpa&Q=75kbXlOh_@ zUjr2FYNt+^2+K_h5*3Y3igDh%EdC7kgFreB=1={m%U`{-{{Iwro>5J9+oDE95D*Zg ziHHbDQy`7x4Imwn-ld}u2)#vmkuFG)8bIj?h;*b^r5B|O(u;KI(h=n1-uLV?KEt^8 z+h?3H_WLhSR-1FJIcJi!R_0<2VeH#yc(&?(U!7Zq*1|ecjn?T4&$naEu4A_22eFA%xdkiBZlVF3hwMWDVtg^(U%T&7a?U+98Ejkzq@PeE_`YI} zHLuc0iT`W!{ul;<6EydeU6vD2MnHe(*2jmvt84V;9s&BwY*kV5>G(yQJgi6A9k0ZF z5sJx1?UeCKb!^gJZq(D4$-#uL+zRrh*HzI97xwl@8jw5WDiN>RKCI{QHIbR=ViUvG zA$x2N??{l6S2SrtX(>WVhlX!gH<=ekmT+8_m+L0VHsk7>Qri(aUAgV}MR4vzSt@eX z{i53h*WBgj-{g|2IQ+9^)l%#IJ3=&Wdosx9jK0WS8Okg3-gjt)fexP@-bwEwKcrDz zQrrmbp7Q8sT)}(0BYMeJm@yD|c@l3WisQo;zeB~%D`BF4}R;Wq=q zmWe+^@3PsectF%>Z%EW$#*)e_%em{KIwVCDQr`*sy}G8oWNRZSFdnS8j|93&U57PNs{DTRgWhhzc1Vo3#N*(o5-C{GI0m`Cpj*u zsWquNZO#$j-ZRR@Q1eaLu2O7FKfgNR?oPjrx_)amNbC9V7ds9+G94XaWt9Hferv2W z`|Q(bqTSE#p4u08E~!PU zU&09XSUJrUX^gkLK~*fa2_HCr-YPyk1lJ1keyapTjykN&TWpC}b&}fc5^s&9X}%ft z{Q!e|6i)gi!kwV`)rAK5Ldg* z(ps2_I!+9zxajFQ(;zm#%j01ijDNU!EyuO7?}*Hp+hXAoU(;A$V>rE6lA`x7Bg)rb z0#5h41|MslUN{P|5yc6W0O;?BN&x(y2$lZ|jsW;?{aH60H#lM+DcFtySL+rvuXv0& zQ06+l7FY-0BGXA7b2B8GxP(cQ8bz~4a?6bD{yOrMkPUugUB`n7x*Z9%opgu3Dda#g z%-G7uE$&!|ySifP09RLMu~{(BBNyl^gMRUT&KqG5O52s5T0U~q7nH&duyZcT6mnWo z%ajdPvG8Dt-7=q2mhxwGbymMWT$8a1;B9`dY|0iYd1c;SXtJ;lQ#xQM;Y+f1abz&0 zB`%thtgZ0jAHQSHVXZJsZ1w8A` z`W4$(Tfn^{?ktr2T?1JWV3%q^0txnw{aiZX`{+gU!{wDs&BvBm`Bb;3N{3l?;+$wRJrr~lodp4z?O#nfxh!X51M@(w<*e1Ze1c>21YdvDrHCnL@vB^PB* zFIpNz`dkY4-1UhZY<5VmAL&-WKKv^S=g6m96K@FsYll!yOneBXE%vES<77u>6^~pk z6Yc1cQDOI~=Ddy%w1 zu)eG$N3(m5L<#9P%ftvNJLX8%Me0v;1-EYgM3)Yy7CB%iY@P^?%n^6NWFX-TuarW# z31fN&MXYZ+eSS!1#rF2clZoVo&KBbRYo0u8>V}-}Yt{y=-GG~=>yHI$P}6>abfu~+ zA9W*-RE2V~GUzEKjnIZg9+gK+Ri{l+1Vc z9Ydz=Jni_5h76xA_3F?Q_jQ-5F}CgZ<6GMaP?#Tk@v%{hlNP^8?Q441Idol`$*Nb~ zkC3AEMd_W;pj)D7b?=?<yCrwu$@c>jFg+Z&OA@nc1hl>aD&s2z51_l`b$;B9^EVVJf&)~BkI)S?tmd$n5IJjlAM!e0A@&R11ABKv zAHQa_KL4#N@vYchgKeV<$L#Mrj$2lzjjZ`Cqo2gTtq^^xiL22?yJ#;Jg%=NzB-}#j z2cLk3Z~t2^p%VD8Xg>Agj{c&s``PO=sH*dlmYA zIc8Sx`cdh;55?y$bWKCK59zFLLYZ;*Z0NLE6TE#Bv$Jr3m~V+0(DUYHvOAtz`!?4T z?R8;4fcOS(DET+CL;%qLY$*9#c^~*e;B!LBC(Ia}dgABZb>sQZ4@>6)?`?b^c5F?8 zsYqiIq~OfNvO!|rw?*%Ee%;se{^I8}?y!1E3V+|eyNc+*36@3qtJMKMbDAgQRsjf9 z3BKKmr@d4!pA}cyZXOf*fK|u1Ed-nK%JEt9V9pP9&NUN-&d6d**??%|NP6o2ty@bc zBrAG)&XIbdRNuND6x8TzSf{A--oz@Dr>ncwdej`a!O~|A?jfZnXJv;1^5qO6GM4k2 zrK+E>d4XjPj}Qjhew>|8-mn^CFbWzYqpWP00ir`T{-ia!yZ~*u5!btjM#Sal((6hb z9Z1tvi^Pe^HOGpT&$Bhh$ujwwTRT;qq?qzeOBGhMwOlo}%p)Uw=ymD4xIm2;tz)V# z*xj+YU_JIy$R|_K?YdNPK!~Cpi~nj%S%)nz^AXG7v9ft&N0cT0leA7@qNVIOIJ>A~ z9$oTKqe_z}w*-Qs1Q{0H*E7BK<7cdA*0V9A9E`@N(07yqyr|0%!-uh4zH~z%D&^3a zs?QR>(KUC2rHU7xza21c>?okBPU$jZLbU}5nqw3Ol)vPab3GaMFE1ld-^oZcdg8*G z+e}-0$Gam0u+qi!?+UPMJQ8>kbX2-=DXB^uBXTep2u$m`|Jk?ZSJB-)8)8AL;72NgR}x7 z<94q(T($+Vkvw?lJ^MvRWLhkwz9=b(=>j>5C=J_Lg$GqS?m^EpZEfp;^)HUn-sHrT z7L&Qkg{wYF^Dy!4yHwnoqXjuO3DADQ9w*)RF;tzASSymH%vD%xfmZLi4YEv! zl|LR_0@5f-bgTP@voCzF)-OEnt`>A$}k#}gky+kloc`2wPQ zPrxh|`H^RlwmARmvjo;r#XE`74c}$I<-_e%NdWiM>}O?t1O7}!RxWo*O_WEhPJ>RU z?|nLHbm5L(evYl!xJ*XWJ@%2v)OkmoXoc2#KaiGSwwP~z@<^#)Vs2($o!&;XL!Njj zVcVm^E=ekcBh3L&saW~I_=zC!N5Wo_@c~1#;!AvRCd(}E=kx? z*z6(O<2pu+J97(VbZ?QzVzaqBwtcLZOh~=hr$frOiU~MPN@^A!vAAF1ctD>CjOnW` z+<$nS`Kz(+a?~v9U0KHAZpuc1y#lq#RRc?E#&^~RMKaHqjbkE}&GfK8x+b$5zlg^h zbgCt`M_=_%;Z@PjaFD3(V3Kgsx~P|`3W;8mO2gh%Z>wNs=LOYSX;b6`@fXsN=apiA zluEe@C9^MTqF(DIb405&kM?rJH$?lUmGM6H8<8jq4Bt=wLgD%0k1poA) z1v%;zw8U$=`tgW`!|U$obmNey=m=xYL^iMD4A+iVGa0e48(!56M2p)SNfFg2)VrTU zN)C1U-k^77=kg>o=G{6lHfAl!$l~e+`E6hIg#I}_j1X9kEXrU?!L<2GzNu=e&5of46 z$c)Y#3uJzWnzk~r_8eKc&tFCyYT?iwxe`efH3qk7)Bf7#^9|VRRoS?&z;AK&M`V`# zk0_?@$qA*m8%*6^-rs0cc6oF5R8DIScHM4%$yMlmcmWN6jc}r&t~Hg?-ZS`Kz0V%i zqtH@jafK@=!<D)(dHy?Nl1)hN_HUnh4h^0o|ngvEkyvNNYO0 z!*)JJm{9XEe)G6FfxTPiC$i?5b41NUkJn042q zwVhF){n25XVIO#Fm(SPke8y&hhP_YyhRtxoP4&U;5fzCW0_kRWpN7RknwW36nLV~B zc(su_(yC=}y&AgSl?E&{ldXV)20jPMh;+UTm%emAjm<8`vK*YB%sd^bi-@6#zESVoEguWU*CE_V<|E*wT=0*o?Rzb!Yg2yABn7qB*Jxyb z4DC0sH1P`c)hCvVgx|HtUvTk8kDAcX7T93~8vTVKuxp7_p=)5q;hNFBcidSB+pEjZ zPjxhC7$)rI zzMs;^OZTcamQJ?DF!hH)cMDSRye`(~FubjjcOfW~qPyle+FCfyXx)%$E;MMJ%^5J! zt20cK#y%Ta_nflyN3~!WO-p$a+v9;KXo#e4B8_`v07|J#jLK`l=KVd{RFBN&*n;~Z z@u11~`&m(5g)w)3>BxM-{Cu8@cxb@2W+RfQ=6bceTPV1?j$j*38h^TM7oLxev))|0 zJwuM3E0+iDz{a=;CAeRYzkb6bLv@ETETDkq!CV5K=SC7wUmj)b?2*#T^3!+IPL`R$ zq(}aHJV^^DpfI&fpPSAlTkCs!_fBaqfuD&sHv#mShAyQGiRCNV2cC;nBH)Zdj}GvR zS*#Q4h&9TVBbr#UdlR*wMG|Mp@vGdVP3lfY!p@^$US2J`2tB3;YkR#Z6s7@axu15E zSzYDkCC?&4S!4sXBU*$HwfgCXk4oN9#iFK|P;q4AXkj^L`j@{#cG<5#?4V+9TS)tf zhHM-U9@4ck(lz1w;eX@s0`R|Zc;SEUe)<2JvK9C{Cm7%m7&Gp6j+%n)sOWF^yAc1d zc$U94eljWs_At${>B0BgaryTN5G(r5&OSdj1T9ff*}-?Ox(FXndek1?H@eyv*Z}NK zr87wxN+u8VG|_GNz~q)Io*Ofur6n43NEOhAvT62`UP<;OQe2r|Kh~B&k9yfc8k;Y+ z&aH;3nMFD1S!eSrrn!t_9Mgt2(=3InYZZLJ)0Uepiav4HCzPAttiX#E4JP_ICH786{T#IXNkW4#RG~8M5u!4t*5nqC-;i7ZtsuXYz=$Ec0%u5 zg)Ois&+4O{VN1=-X8U}S#gpIOI52`KP83O!;0?W4|25^w3zIwEw-`!KXOu?pPH$eI zmrlpG@qcgmy}*{#7jGTtdE6p+5uO&kEYo@~G}`IHgBUH+ZKJ7cQdfH&!v^xE`ojuN zrkOtQKC5Nw$kFeu(}%BZ>H_cYUL>^kb6^rwT{1{3HvFpPWEEO`Pab{cn*$ZQijz>k ztstz1WdCHB%wc85m+4OY11LqLt1Xr344`Q4bb7_9TY5^`>w*sL^B`P{`(p!D!qCCc z%GUIs*(LwW=6=7BH*~dibl_7nw=uOc`M-8)YNGIad22j1QM9!&`Ij-cU`)^?AZ7r` zOal7X!wl!=hw?L{|C{~J(D;vcZ2rX{P#gvZ&c2)DFa&NnX& z3~~;Gp2J}0F#dBG{2X?U9Q^0V!GDe%@N?vVgMX(-|C1qcbP9*y&IcR{!(}iiZe7?p z?eU+}9{l$w@;?{?!jH=UFb)IYxN;!D2wa9+7XiXuR|qifnnXarAY29jI1Gxw?E?nI zZSNlmZ~tTfjvNR$97k6O1dg49&(wlD765_U9ukCG4vDLK;GA^;;QE&{hT8`K#nn9k z)=eKxN-ovb9AQWKifO= z2Dl6g2L9{=3LtR&GZaAb|H)t=ejFQwfe<)02!lWYT*i;v-r02EFc=uewqX1SoH>H= zBXRphfcbIio(=EMxr6~{;{7*sz!;ianP5nMXKXijGdYWce5$s#4$QzmGk(k1plzA| z8CPW_b%j7s + + +/* + * Local functions... + */ + +static void do_printer_op(http_t *http, const char *printer, ipp_op_t op, + const char *title); +static void show_all_printers(http_t *http, const char *username); +static void show_printer(http_t *http, const char *printer); + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + const char *printer; /* Printer name */ + const char *user; /* Username */ + http_t *http; /* Connection to the server */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + const char *op; /* Operation to perform, if any */ + static const char *def_attrs[] = /* Attributes for default printer */ + { + "printer-name", + "printer-uri-supported" + }; + + + /* + * Get any form variables... + */ + + cgiInitialize(); + + op = cgiGetVariable("OP"); + + /* + * Set the web interface section... + */ + + cgiSetVariable("SECTION", "printers"); + cgiSetVariable("REFRESH_PAGE", ""); + + /* + * See if we are displaying a printer or all printers... + */ + + if ((printer = getenv("PATH_INFO")) != NULL) + { + printer ++; + + if (!*printer) + printer = NULL; + + if (printer) + cgiSetVariable("PRINTER_NAME", printer); + } + + /* + * See who is logged in... + */ + + user = getenv("REMOTE_USER"); + + /* + * Connect to the HTTP server... + */ + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + /* + * Get the default printer... + */ + + if (!op || !cgiIsPOST()) + { + /* + * Get the default destination... + */ + + request = ippNewRequest(CUPS_GET_DEFAULT); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs); + + 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 url[HTTP_MAX_URI]; /* New URL */ + + + cgiSetVariable("DEFAULT_URI", + cgiRewriteURL(attr->values[0].string.text, + url, sizeof(url), NULL)); + } + + ippDelete(response); + } + + /* + * See if we need to show a list of printers or the status of a + * single printer... + */ + + if (!printer) + show_all_printers(http, user); + else + show_printer(http, printer); + } + else if (printer) + { + if (!*op) + { + const char *server_port = getenv("SERVER_PORT"); + /* Port number string */ + int port = atoi(server_port ? server_port : "0"); + /* Port number */ + char uri[1024]; /* URL */ + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), + getenv("HTTPS") ? "https" : "http", NULL, + getenv("SERVER_NAME"), port, "/printers/%s", printer); + + printf("Location: %s\n\n", uri); + } + else if (!strcmp(op, "start-printer")) + do_printer_op(http, printer, IPP_RESUME_PRINTER, + cgiText(_("Resume Printer"))); + else if (!strcmp(op, "stop-printer")) + do_printer_op(http, printer, IPP_PAUSE_PRINTER, + cgiText(_("Pause Printer"))); + else if (!strcmp(op, "accept-jobs")) + do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs"))); + else if (!strcmp(op, "reject-jobs")) + do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs"))); + else if (!strcmp(op, "purge-jobs")) + do_printer_op(http, printer, IPP_PURGE_JOBS, cgiText(_("Purge Jobs"))); + else if (!strcasecmp(op, "print-self-test-page")) + cgiPrintCommand(http, printer, "PrintSelfTestPage", + cgiText(_("Print Self-Test Page"))); + else if (!strcasecmp(op, "clean-print-heads")) + cgiPrintCommand(http, printer, "Clean all", + cgiText(_("Clean Print Heads"))); + else if (!strcasecmp(op, "print-test-page")) + cgiPrintTestPage(http, printer); + else if (!strcasecmp(op, "move-jobs")) + cgiMoveJobs(http, printer, 0); + else + { + /* + * Unknown/bad operation... + */ + + cgiStartHTML(printer); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + } + else + { + /* + * Unknown/bad operation... + */ + + cgiStartHTML(cgiText(_("Printers"))); + cgiCopyTemplateLang("error-op.tmpl"); + cgiEndHTML(); + } + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'do_printer_op()' - Do a printer operation. + */ + +static void +do_printer_op(http_t *http, /* I - HTTP connection */ + const char *printer, /* I - Printer name */ + ipp_op_t op, /* I - Operation to perform */ + const char *title) /* I - Title of page */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI], /* Printer URI */ + resource[HTTP_MAX_URI]; /* Path for request */ + + + /* + * Build a printer request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(op); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + snprintf(resource, sizeof(resource), "/printers/%s", printer); + ippDelete(cupsDoRequest(http, request, resource)); + + if (cupsLastError() == IPP_NOT_AUTHORIZED) + { + puts("Status: 401\n"); + exit(0); + } + else if (cupsLastError() > IPP_OK_CONFLICT) + { + cgiStartHTML(title); + cgiShowIPPError(_("Unable to do maintenance command:")); + } + else + { + /* + * Redirect successful updates back to the printer page... + */ + + char url[1024], /* Printer/class URL */ + refresh[1024]; /* Refresh URL */ + + + cgiRewriteURL(uri, url, sizeof(url), NULL); + cgiFormEncode(uri, url, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "5;URL=%s", uri); + cgiSetVariable("refresh_page", refresh); + + cgiStartHTML(title); + + if (op == IPP_PAUSE_PRINTER) + cgiCopyTemplateLang("printer-stop.tmpl"); + else if (op == IPP_RESUME_PRINTER) + cgiCopyTemplateLang("printer-start.tmpl"); + else if (op == CUPS_ACCEPT_JOBS) + cgiCopyTemplateLang("printer-accept.tmpl"); + else if (op == CUPS_REJECT_JOBS) + cgiCopyTemplateLang("printer-reject.tmpl"); + else if (op == IPP_PURGE_JOBS) + cgiCopyTemplateLang("printer-purge.tmpl"); + } + + cgiEndHTML(); +} + + +/* + * 'show_all_printers()' - Show all printers... + */ + +static void +show_all_printers(http_t *http, /* I - Connection to server */ + const char *user) /* I - Username */ +{ + int i; /* Looping var */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + cups_array_t *printers; /* Array of printer objects */ + ipp_attribute_t *printer; /* Printer object */ + int ascending, /* Order of printers (0 = descending) */ + first, /* First printer to show */ + count; /* Number of printers */ + const char *var; /* Form variable */ + void *search; /* Search data */ + char val[1024]; /* Form variable */ + + + fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n", + http, user ? user : "(null)"); + + /* + * Show the standard header... + */ + + cgiStartHTML(cgiText(_("Printers"))); + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-type + * printer-type-mask + * requesting-user-name + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type", 0); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type-mask", CUPS_PRINTER_CLASS); + + if (user) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + + cgiGetAttributes(request, "printers.tmpl"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Get a list of matching job objects. + */ + + if ((var = cgiGetVariable("QUERY")) != NULL && + !cgiGetVariable("CLEAR")) + search = cgiCompileSearch(var); + else + search = NULL; + + printers = cgiGetIPPObjects(response, search); + count = cupsArrayCount(printers); + + if (search) + cgiFreeSearch(search); + + /* + * Figure out which printers to display... + */ + + if ((var = cgiGetVariable("FIRST")) != NULL) + first = atoi(var); + else + first = 0; + + if (first >= count) + first = count - CUPS_PAGE_MAX; + + first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; + + if (first < 0) + first = 0; + + sprintf(val, "%d", count); + cgiSetVariable("TOTAL", val); + + if ((var = cgiGetVariable("ORDER")) != NULL) + ascending = !strcasecmp(var, "asc"); + else + ascending = 1; + + if (ascending) + { + for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first); + i < CUPS_PAGE_MAX && printer; + i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers)) + cgiSetIPPObjectVars(printer, NULL, i); + } + else + { + for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1); + i < CUPS_PAGE_MAX && printer; + i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers)) + cgiSetIPPObjectVars(printer, NULL, i); + } + + /* + * Save navigation URLs... + */ + + cgiSetVariable("THISURL", "/printers/"); + + if (first > 0) + { + sprintf(val, "%d", first - CUPS_PAGE_MAX); + cgiSetVariable("PREV", val); + } + + if ((first + CUPS_PAGE_MAX) < count) + { + sprintf(val, "%d", first + CUPS_PAGE_MAX); + cgiSetVariable("NEXT", val); + } + + /* + * Then show everything... + */ + + cgiCopyTemplateLang("search.tmpl"); + + cgiCopyTemplateLang("printers-header.tmpl"); + + if (count > CUPS_PAGE_MAX) + cgiCopyTemplateLang("pager.tmpl"); + + cgiCopyTemplateLang("printers.tmpl"); + + if (count > CUPS_PAGE_MAX) + cgiCopyTemplateLang("pager.tmpl"); + + /* + * Delete the response... + */ + + cupsArrayDelete(printers); + ippDelete(response); + } + else + { + /* + * Show the error... + */ + + cgiShowIPPError(_("Unable to get printer list:")); + } + + cgiEndHTML(); +} + + +/* + * 'show_printer()' - Show a single printer. + */ + +static void +show_printer(http_t *http, /* I - Connection to server */ + const char *printer) /* I - Name of printer */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + char refresh[1024]; /* Refresh URL */ + + + fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n", + http, printer ? printer : "(null)"); + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + + cgiGetAttributes(request, "printer.tmpl"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Got the result; set the CGI variables and check the status of a + * single-queue request... + */ + + cgiSetIPPVars(response, NULL, NULL, NULL, 0); + + if (printer && (attr = ippFindAttribute(response, "printer-state", + IPP_TAG_ENUM)) != NULL && + attr->values[0].integer == IPP_PRINTER_PROCESSING) + { + /* + * Printer is processing - automatically refresh the page until we + * are done printing... + */ + + cgiFormEncode(uri, printer, sizeof(uri)); + snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri); + cgiSetVariable("refresh_page", refresh); + } + + /* + * Delete the response... + */ + + ippDelete(response); + + /* + * Show the standard header... + */ + + cgiStartHTML(printer); + + /* + * Show the printer status... + */ + + cgiCopyTemplateLang("printer.tmpl"); + + /* + * Show jobs for the specified printer... + */ + + cgiCopyTemplateLang("printer-jobs-header.tmpl"); + cgiShowJobs(http, printer); + } + else + { + /* + * Show the IPP error... + */ + + cgiStartHTML(printer); + cgiShowIPPError(_("Unable to get printer status:")); + } + + cgiEndHTML(); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/search.c b/cgi-bin/search.c new file mode 100644 index 0000000000..b40d8431a1 --- /dev/null +++ b/cgi-bin/search.c @@ -0,0 +1,381 @@ +/* + * "$Id$" + * + * Search routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cgiCompileSearch() - Compile a search string. + * cgiDoSearch() - Do a search of some text. + * cgiFreeSearch() - Free a compiled search context. + */ + +/* + * Include necessary headers... + */ + +#include "cgi-private.h" +#include + + +/* + * 'cgiCompileSearch()' - Compile a search string. + */ + +void * /* O - Search context */ +cgiCompileSearch(const char *query) /* I - Query string */ +{ + regex_t *re; /* Regular expression */ + char *s, /* Regular expression string */ + *sptr, /* Pointer into RE string */ + *sword; /* Pointer to start of word */ + int slen; /* Allocated size of RE string */ + const char *qptr, /* Pointer into query string */ + *qend; /* End of current word */ + const char *prefix; /* Prefix to add to next word */ + int quoted; /* Word is quoted */ + int wlen; /* Word length */ + char *lword; /* Last word in query */ + + + DEBUG_printf(("cgiCompileSearch(query=\"%s\")\n", query)); + + /* + * Range check input... + */ + + if (!query) + return (NULL); + + /* + * Allocate a regular expression storage structure... + */ + + if ((re = (regex_t *)calloc(1, sizeof(regex_t))) == NULL) + return (NULL); + + /* + * Allocate a buffer to hold the regular expression string, starting + * at 1024 bytes or 3 times the length of the query string, whichever + * is greater. We'll expand the string as needed... + */ + + slen = strlen(query) * 3; + if (slen < 1024) + slen = 1024; + + if ((s = (char *)malloc(slen)) == NULL) + { + free(re); + return (NULL); + } + + /* + * Copy the query string to the regular expression, handling basic + * AND and OR logic... + */ + + prefix = ".*"; + qptr = query; + sptr = s; + lword = NULL; + + while (*qptr) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*qptr & 255)) + qptr ++; + + if (!*qptr) + break; + + /* + * Find the end of the current word... + */ + + if (*qptr == '\"' || *qptr == '\'') + { + /* + * Scan quoted string... + */ + + quoted = *qptr ++; + for (qend = qptr; *qend && *qend != quoted; qend ++); + + if (!*qend) + { + /* + * No closing quote, error out! + */ + + free(s); + free(re); + + if (lword) + free(lword); + + return (NULL); + } + } + else + { + /* + * Scan whitespace-delimited string... + */ + + quoted = 0; + for (qend = qptr + 1; *qend && !isspace(*qend); qend ++); + } + + wlen = qend - qptr; + + /* + * Look for logic words: AND, OR + */ + + if (wlen == 3 && !strncasecmp(qptr, "AND", 3)) + { + /* + * Logical AND with the following text... + */ + + if (sptr > s) + prefix = ".*"; + + qptr = qend; + } + else if (wlen == 2 && !strncasecmp(qptr, "OR", 2)) + { + /* + * Logical OR with the following text... + */ + + if (sptr > s) + prefix = ".*|.*"; + + qptr = qend; + } + else + { + /* + * Add a search word, making sure we have enough room for the + * string + RE overhead... + */ + + wlen = (sptr - s) + 2 * 4 * wlen + 2 * strlen(prefix) + 11; + if (lword) + wlen += strlen(lword); + + if (wlen > slen) + { + /* + * Expand the RE string buffer... + */ + + char *temp; /* Temporary string pointer */ + + + slen = wlen + 128; + temp = (char *)realloc(s, slen); + if (!temp) + { + free(s); + free(re); + + if (lword) + free(lword); + + return (NULL); + } + + sptr = temp + (sptr - s); + s = temp; + } + + /* + * Add the prefix string... + */ + + strcpy(sptr, prefix); + sptr += strlen(sptr); + + /* + * Then quote the remaining word characters as needed for the + * RE... + */ + + sword = sptr; + + while (qptr < qend) + { + /* + * Quote: ^ . [ $ ( ) | * + ? { \ + */ + + if (strchr("^.[$()|*+?{\\", *qptr)) + *sptr++ = '\\'; + + *sptr++ = *qptr++; + } + + *sptr = '\0'; + + /* + * For "word1 AND word2", add reciprocal "word2 AND word1"... + */ + + if (!strcmp(prefix, ".*") && lword) + { + char *lword2; /* New "last word" */ + + + if ((lword2 = strdup(sword)) == NULL) + { + free(lword); + free(s); + free(re); + return (NULL); + } + + strcpy(sptr, ".*|.*"); + sptr += 5; + + strcpy(sptr, lword2); + sptr += strlen(sptr); + + strcpy(sptr, ".*"); + sptr += 2; + + strcpy(sptr, lword); + sptr += strlen(sptr); + + free(lword); + lword = lword2; + } + else + { + if (lword) + free(lword); + + lword = strdup(sword); + } + + prefix = ".*|.*"; + } + + /* + * Advance to the next string... + */ + + if (quoted) + qptr ++; + } + + if (lword) + free(lword); + + if (sptr > s) + strcpy(sptr, ".*"); + else + { + /* + * No query data, return NULL... + */ + + free(s); + free(re); + + return (NULL); + } + + /* + * Compile the regular expression... + */ + + DEBUG_printf((" s=\"%s\"\n", s)); + + if (regcomp(re, s, REG_EXTENDED | REG_ICASE)) + { + free(re); + free(s); + + return (NULL); + } + + /* + * Free the RE string and return the new regular expression we compiled... + */ + + free(s); + + return ((void *)re); +} + + +/* + * 'cgiDoSearch()' - Do a search of some text. + */ + +int /* O - Number of matches */ +cgiDoSearch(void *search, /* I - Search context */ + const char *text) /* I - Text to search */ +{ + int i; /* Looping var */ + regmatch_t matches[100]; /* RE matches */ + + + /* + * Range check... + */ + + if (!search || !text) + return (0); + + /* + * Do a lookup... + */ + + if (!regexec((regex_t *)search, text, sizeof(matches) / sizeof(matches[0]), + matches, 0)) + { + /* + * Figure out the number of matches in the string... + */ + + for (i = 0; i < (int)(sizeof(matches) / sizeof(matches[0])); i ++) + if (matches[i].rm_so < 0) + break; + + return (i); + } + else + return (0); +} + + +/* + * 'cgiFreeSearch()' - Free a compiled search context. + */ + +void +cgiFreeSearch(void *search) /* I - Search context */ +{ + regfree((regex_t *)search); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/template.c b/cgi-bin/template.c new file mode 100644 index 0000000000..fdfaf03fc6 --- /dev/null +++ b/cgi-bin/template.c @@ -0,0 +1,733 @@ +/* + * "$Id$" + * + * CGI template function. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cgiCopyTemplateFile() - Copy a template file and replace all the + * '{variable}' strings with the variable value. + * cgiCopyTemplateLang() - Copy a template file using a language... + * cgiGetTemplateDir() - Get the templates directory... + * cgiSetServerVersion() - Set the server name and CUPS version... + * cgi_copy() - Copy the template file, substituting as needed... + * cgi_puts() - Put a string to the output file, quoting as + * needed... + */ + +#include "cgi-private.h" +#include +#include + + +/* + * Local functions... + */ + +static void cgi_copy(FILE *out, FILE *in, int element, char term, + int indent); +static void cgi_puts(const char *s, FILE *out); +static void cgi_puturi(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 */ + + + fprintf(stderr, "DEBUG2: cgiCopyTemplateFile(out=%p, tmpl=\"%s\")\n", out, + tmpl ? tmpl : "(null)"); + + /* + * Range check input... + */ + + if (!tmpl || !out) + return; + + /* + * Open the template file... + */ + + if ((in = fopen(tmpl, "r")) == NULL) + { + fprintf(stderr, "ERROR: Unable to open template file \"%s\" - %s\n", + tmpl ? tmpl : "(null)", strerror(errno)); + return; + } + + /* + * Parse the file to the end... + */ + + cgi_copy(out, in, 0, 0, 0); + + /* + * Close the template file and return... + */ + + fclose(in); +} + + +/* + * 'cgiCopyTemplateLang()' - Copy a template file using a language... + */ + +void +cgiCopyTemplateLang(const char *tmpl) /* I - Base filename */ +{ + char filename[1024], /* Filename */ + locale[16], /* Locale name */ + *locptr; /* Pointer into locale name */ + const char *directory, /* Directory for templates */ + *lang; /* Language */ + FILE *in; /* Input file */ + + + fprintf(stderr, "DEBUG2: cgiCopyTemplateLang(tmpl=\"%s\")\n", + tmpl ? tmpl : "(null)"); + + /* + * Convert the language to a locale name... + */ + + locale[0] = '\0'; + + if ((lang = getenv("LANG")) != NULL) + { + locale[0] = '/'; + strlcpy(locale + 1, lang, sizeof(locale) - 1); + + if ((locptr = strchr(locale, '.')) != NULL) + *locptr = '\0'; /* Strip charset */ + } + + fprintf(stderr, "DEBUG2: lang=\"%s\", locale=\"%s\"...\n", + lang ? lang : "(null)", locale); + + /* + * See if we have a template file for this language... + */ + + directory = cgiGetTemplateDir(); + + snprintf(filename, sizeof(filename), "%s%s/%s", directory, locale, tmpl); + if ((in = fopen(filename, "r")) == NULL) + { + locale[3] = '\0'; + + snprintf(filename, sizeof(filename), "%s%s/%s", directory, locale, tmpl); + if ((in = fopen(filename, "r")) == NULL) + { + snprintf(filename, sizeof(filename), "%s/%s", directory, tmpl); + in = fopen(filename, "r"); + } + } + + fprintf(stderr, "DEBUG2: Template file is \"%s\"...\n", filename); + + /* + * Open the template file... + */ + + if (!in) + { + fprintf(stderr, "ERROR: Unable to open template file \"%s\" - %s\n", + filename, strerror(errno)); + return; + } + + /* + * Parse the file to the end... + */ + + cgi_copy(stdout, in, 0, 0, 0); + + /* + * Close the template file and return... + */ + + fclose(in); +} + + +/* + * 'cgiGetTemplateDir()' - Get the templates directory... + */ + +char * /* O - Template directory */ +cgiGetTemplateDir(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); +} + + +/* + * 'cgiSetServerVersion()' - Set the server name and CUPS version... + */ + +void +cgiSetServerVersion(void) +{ + cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME")); + cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER")); + cgiSetVariable("CUPS_VERSION", CUPS_SVERSION); + +#ifdef LC_TIME + setlocale(LC_TIME, ""); +#endif /* LC_TIME */ +} + + +/* + * '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 indent) /* I - Debug info indentation */ +{ + 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 */ + int uriencode; /* Encode as URI */ + regex_t re; /* Regular expression to match */ + + + fprintf(stderr, "DEBUG2: %*sStarting at file position %ld...\n", indent, "", + ftell(in)); + + /* + * Parse the file to the end... + */ + + while ((ch = getc(in)) != EOF) + if (ch == term) + break; + else if (ch == '{') + { + /* + * Get a variable name... + */ + + uriencode = 0; + + for (s = name; (ch = getc(in)) != EOF;) + if (strchr("}]<>=!~ \t\n", ch)) + break; + else if (s == name && ch == '%') + uriencode = 1; + else if (s > name && ch == '?') + break; + else if (s < (name + sizeof(name) - 1)) + *s++ = ch; + + *s = '\0'; + + if (s == name && isspace(ch & 255)) + { + fprintf(stderr, "DEBUG2: %*sLone { at %ld...\n", indent, "", ftell(in)); + + if (out) + { + putc('{', out); + putc(ch, out); + } + + continue; + } + + if (ch == '}') + fprintf(stderr, "DEBUG2: %*s\"{%s}\" at %ld...\n", indent, "", name, + ftell(in)); + + /* + * See if it has a value... + */ + + if (name[0] == '?') + { + /* + * Insert value only if it exists... + */ + + if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1] & 255)) + { + *nameptr++ = '\0'; + + if ((value = cgiGetArray(name + 1, atoi(nameptr) - 1)) != NULL) + outptr = value; + else + { + outval[0] = '\0'; + outptr = outval; + } + } + else 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] & 255)) + count = atoi(name + 1); + else + count = cgiGetSize(name + 1); + + pos = ftell(in); + + fprintf(stderr, "DEBUG2: %*sLooping on \"%s\" at %ld, count=%d...\n", + indent, "", name + 1, pos, count); + + if (count > 0) + { + for (i = 0; i < count; i ++) + { + if (i) + fseek(in, pos, SEEK_SET); + + cgi_copy(out, in, i, '}', indent + 2); + } + } + else + cgi_copy(NULL, in, 0, '}', indent + 2); + + fprintf(stderr, "DEBUG2: %*sFinished looping on \"%s\"...\n", indent, + "", name + 1); + + continue; + } + else if (name[0] == '$') + { + /* + * Insert cookie value or nothing if not defined. + */ + + if ((value = cgiGetCookie(name + 1)) != NULL) + outptr = value; + else + { + outval[0] = '\0'; + outptr = outval; + } + } + else + { + /* + * Insert variable or variable name (if element is NULL)... + */ + + if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1] & 255)) + { + *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) + { + if (uriencode) + cgi_puturi(outptr, out); + else if (!strcasecmp(name, "?cupsdconf_default")) + fputs(outptr, stdout); + else + cgi_puts(outptr, out); + } + + continue; + } + + /* + * OK, process one of the following checks: + * + * {name?exist:not-exist} Exists? + * {name=value?true:false} Equal + * {namevalue?true:false} Greater than + * {name!value?true:false} Not equal + * {name~refex?true:false} Regex match + */ + + op = ch; + + if (ch == '?') + { + /* + * Test for existance... + */ + + if (name[0] == '?') + result = cgiGetArray(name + 1, element) != NULL; + else if (name[0] == '#') + result = cgiGetVariable(name + 1) != NULL; + else + result = cgiGetArray(name, element) != NULL; + + result = result && outptr[0]; + compare[0] = '\0'; + } + else + { + /* + * Compare to a string... + */ + + 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] & 255)) + { + *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(compare) - (s - compare), "{%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 != '?') + { + fprintf(stderr, + "DEBUG2: %*sBad terminator '%c' at file position %ld...\n", + indent, "", ch, ftell(in)); + 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; + case '~' : + fprintf(stderr, "DEBUG: Regular expression \"%s\"\n", compare); + + if (regcomp(&re, compare, REG_EXTENDED | REG_ICASE)) + { + fprintf(stderr, + "ERROR: Unable to compile regular expresion \"%s\"!\n", + compare); + result = 0; + } + else + { + regmatch_t matches[10]; + + result = 0; + + if (!regexec(&re, outptr, 10, matches, 0)) + { + int i; + for (i = 0; i < 10; i ++) + { + fprintf(stderr, "DEBUG: matches[%d].rm_so=%d\n", i, + (int)matches[i].rm_so); + if (matches[i].rm_so < 0) + break; + + result ++; + } + } + + regfree(&re); + } + break; + default : + result = 1; + break; + } + } + + fprintf(stderr, + "DEBUG2: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n", + indent, "", name, op, compare, ftell(in), result); + + if (result) + { + /* + * Comparison true; output first part and ignore second... + */ + + fprintf(stderr, "DEBUG2: %*sOutput first part...\n", indent, ""); + cgi_copy(out, in, element, ':', indent + 2); + + fprintf(stderr, "DEBUG2: %*sSkip second part...\n", indent, ""); + cgi_copy(NULL, in, element, '}', indent + 2); + } + else + { + /* + * Comparison false; ignore first part and output second... + */ + + fprintf(stderr, "DEBUG2: %*sSkip first part...\n", indent, ""); + cgi_copy(NULL, in, element, ':', indent + 2); + + fprintf(stderr, "DEBUG2: %*sOutput second part...\n", indent, ""); + cgi_copy(out, in, element, '}', indent + 2); + } + + fprintf(stderr, "DEBUG2: %*sFinished \"{%s%c%s\", out=%p...\n", indent, "", + name, op, compare, out); + } + else if (ch == '\\') /* Quoted char */ + { + if (out) + putc(getc(in), out); + else + getc(in); + } + else if (out) + putc(ch, out); + + if (ch == EOF) + fprintf(stderr, "DEBUG2: %*sReturning at file position %ld on EOF...\n", + indent, "", ftell(in)); + else + fprintf(stderr, + "DEBUG2: %*sReturning at file position %ld on character '%c'...\n", + indent, "", ftell(in), ch); + + if (ch == EOF && term) + fprintf(stderr, "ERROR: %*sSaw EOF, expected '%c'!\n", indent, "", term); + + /* + * 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, /* I - String to output */ + FILE *out) /* I - Output file */ +{ + while (*s) + { + if (*s == '<') + { + /* + * Pass and , otherwise quote it... + */ + + if (!strncasecmp(s, "", out); + } + else if (!strncasecmp(s, "", 4)) + { + fputs("", out); + s += 3; + } + else + fputs("<", out); + } + else if (*s == '>') + fputs(">", out); + else if (*s == '\"') + fputs(""", out); + else if (*s == '\'') + fputs("'", out); + else if (*s == '&') + fputs("&", out); + else + putc(*s, out); + + s ++; + } +} + + +/* + * 'cgi_puturi()' - Put a URI string to the output file, quoting as needed... + */ + +static void +cgi_puturi(const char *s, /* I - String to output */ + FILE *out) /* I - Output file */ +{ + while (*s) + { + if (strchr("%@&+ <>#=", *s) || *s < ' ' || *s & 128) + fprintf(out, "%%%02X", *s & 255); + else + putc(*s, out); + + s ++; + } +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/testcgi.c b/cgi-bin/testcgi.c new file mode 100644 index 0000000000..dd57b8b402 --- /dev/null +++ b/cgi-bin/testcgi.c @@ -0,0 +1,75 @@ +/* + * "$Id$" + * + * CGI test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Test the help index code. + * list_nodes() - List nodes in an array... + */ + +/* + * Include necessary headers... + */ + +#include "cgi.h" + + +/* + * 'main()' - Test the CGI code. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + /* + * Test file upload/multi-part submissions... + */ + + freopen("multipart.dat", "rb", stdin); + + putenv("CONTENT_TYPE=multipart/form-data; " + "boundary=---------------------------1977426492562745908748943111"); + putenv("REQUEST_METHOD=POST"); + + printf("cgiInitialize: "); + if (cgiInitialize()) + { + const cgi_file_t *file; /* Upload file */ + + if ((file = cgiGetFile()) != NULL) + { + puts("PASS"); + printf(" tempfile=\"%s\"\n", file->tempfile); + printf(" name=\"%s\"\n", file->name); + printf(" filename=\"%s\"\n", file->filename); + printf(" mimetype=\"%s\"\n", file->mimetype); + } + else + puts("FAIL (no file!)"); + } + else + puts("FAIL (init)"); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/testhi.c b/cgi-bin/testhi.c new file mode 100644 index 0000000000..8a2c165bd8 --- /dev/null +++ b/cgi-bin/testhi.c @@ -0,0 +1,113 @@ +/* + * "$Id$" + * + * Help index test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Test the help index code. + * list_nodes() - List nodes in an array... + */ + +/* + * Include necessary headers... + */ + +#include "cgi.h" + + +/* + * Local functions... + */ + +static void list_nodes(const char *title, cups_array_t *nodes); + + +/* + * 'main()' - Test the help index code. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + help_index_t *hi, /* Help index */ + *search; /* Search index */ + + + /* + * Load the help index... + */ + + hi = helpLoadIndex("testhi.index", "."); + + list_nodes("nodes", hi->nodes); + list_nodes("sorted", hi->sorted); + + /* + * Do any searches... + */ + + if (argc > 1) + { + search = helpSearchIndex(hi, argv[1], NULL, argv[2]); + + if (search) + { + list_nodes(argv[1], search->sorted); + helpDeleteIndex(search); + } + else + printf("%s (0 nodes)\n", argv[1]); + } + + helpDeleteIndex(hi); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'list_nodes()' - List nodes in an array... + */ + +static void +list_nodes(const char *title, /* I - Title string */ + cups_array_t *nodes) /* I - Nodes */ +{ + int i; /* Looping var */ + help_node_t *node; /* Current node */ + + + printf("%s (%d nodes):\n", title, cupsArrayCount(nodes)); + for (i = 1, node = (help_node_t *)cupsArrayFirst(nodes); + node; + i ++, node = (help_node_t *)cupsArrayNext(nodes)) + { + if (node->anchor) + printf(" %d: %s#%s \"%s\"", i, node->filename, node->anchor, + node->text); + else + printf(" %d: %s \"%s\"", i, node->filename, node->text); + + printf(" (%d words)\n", cupsArrayCount(node->words)); + } +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/testhi.html b/cgi-bin/testhi.html new file mode 100644 index 0000000000..0000e9eff8 --- /dev/null +++ b/cgi-bin/testhi.html @@ -0,0 +1,31 @@ + + + Test File for Help Index Code + + + +

This is a test file for the help index code. The help index +code reads plain HTML and indexes the title and any anchored +text, ignoring all other markup. Anchor tags must be on a single +line, although the text they wrap may cross multiple lines and be +up to 1024 bytes in length.

+ +

This is the First Anchor

+ +

This is some text for the first anchor.

+ + +

This is the Second Anchor

+ +

This is some text for the first anchor.

+ +

John asked Mary to the dance.

+ + +

This is the Third Anchor

+ +

This is some text for the third anchor. This +is an in-line anchor that crosses a line.

+ + + diff --git a/cgi-bin/testtemplate.c b/cgi-bin/testtemplate.c new file mode 100644 index 0000000000..153f4d289b --- /dev/null +++ b/cgi-bin/testtemplate.c @@ -0,0 +1,103 @@ +/* + * "$Id$" + * + * CGI template test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Test the template code. + */ + +/* + * Include necessary headers... + */ + +#include "cgi.h" + + +/* + * 'main()' - Test the template code. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + char *value; /* Value in name=value */ + FILE *out; /* Where to send output */ + + + /* + * Don't buffer stdout or stderr so that the mixed output is sane... + */ + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + /* + * Loop through the command-line, assigning variables for any args with + * "name=value"... + */ + + out = stdout; + + for (i = 1; i < argc; i ++) + { + if (!strcmp(argv[i], "-o")) + { + i ++; + if (i < argc) + { + out = fopen(argv[i], "w"); + if (!out) + { + perror(argv[i]); + return (1); + } + } + } + else if (!strcmp(argv[i], "-e")) + { + i ++; + + if (i < argc) + { + if (!freopen(argv[i], "w", stderr)) + { + perror(argv[i]); + return (1); + } + } + } + else if (!strcmp(argv[i], "-q")) + freopen("/dev/null", "w", stderr); + else if ((value = strchr(argv[i], '=')) != NULL) + { + *value++ = '\0'; + cgiSetVariable(argv[i], value); + } + else + cgiCopyTemplateFile(out, argv[i]); + } + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/var.c b/cgi-bin/var.c new file mode 100644 index 0000000000..f57a823242 --- /dev/null +++ b/cgi-bin/var.c @@ -0,0 +1,1306 @@ +/* + * "$Id$" + * + * CGI form variable and array functions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cgiCheckVariables() - Check for the presence of "required" + * variables. + * cgiClearVariables() - Clear all form variables. + * cgiGetArray() - Get an element from a form array. + * cgiGetCookie() - Get a cookie value. + * cgiGetFile() - Get the file (if any) that was submitted in + * the form. + * cgiGetSize() - Get the size of a form array value. + * cgiGetVariable() - Get a CGI variable from the database. + * cgiInitialize() - Initialize the CGI variable "database". + * cgiIsPOST() - Determine whether this page was POSTed. + * cgiSetArray() - Set array element N to the specified string. + * cgiSetCookie() - Set a cookie value. + * cgiSetSize() - Set the array size. + * 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_cookies() - Initialize cookies. + * cgi_initialize_get() - Initialize form variables using the GET + * method. + * cgi_initialize_multipart() - Initialize variables and file using the POST + * method. + * cgi_initialize_post() - Initialize variables using the POST method. + * cgi_initialize_string() - Initialize form variables from a string. + * cgi_passwd() - Catch authentication requests and notify the + * server. + * cgi_set_sid() - Set the CUPS session ID. + * cgi_sort_variables() - Sort all form variables for faster lookup. + * cgi_unlink_file() - Remove the uploaded form. + */ + +/*#define DEBUG*/ +#include "cgi-private.h" +#include +#include +#include + + +/* + * Session ID name + */ + +#define CUPS_SID "org.cups.sid" + + +/* + * Data structure to hold all the CGI form variables and arrays... + */ + +typedef struct /**** Form variable structure ****/ +{ + const char *name; /* Name of variable */ + int nvalues, /* Number of values */ + avalues; /* Number of values allocated */ + const char **values; /* Value(s) of variable */ +} _cgi_var_t; + + +/* + * Local globals... + */ + +static int num_cookies = 0;/* Number of cookies */ +static cups_option_t *cookies = NULL;/* Cookies */ +static int form_count = 0, /* Form variable count */ + form_alloc = 0; /* Number of variables allocated */ +static _cgi_var_t *form_vars = NULL; + /* Form variables */ +static cgi_file_t *form_file = NULL; + /* Uploaded file */ + + +/* + * Local functions... + */ + +static void cgi_add_variable(const char *name, int element, + const char *value); +static int cgi_compare_variables(const _cgi_var_t *v1, + const _cgi_var_t *v2); +static _cgi_var_t *cgi_find_variable(const char *name); +static void cgi_initialize_cookies(void); +static int cgi_initialize_get(void); +static int cgi_initialize_multipart(const char *boundary); +static int cgi_initialize_post(void); +static int cgi_initialize_string(const char *data); +static const char *cgi_passwd(const char *prompt); +static const char *cgi_set_sid(void); +static void cgi_sort_variables(void); +static void cgi_unlink_file(void); + + +/* + * '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); +} + + +/* + * 'cgiClearVariables()' - Clear all form variables. + */ + +void +cgiClearVariables(void) +{ + int i, j; /* Looping vars */ + _cgi_var_t *v; /* Current variable */ + + + for (v = form_vars, i = form_count; i > 0; v ++, i --) + { + _cupsStrFree(v->name); + for (j = 0; j < v->nvalues; j ++) + if (v->values[j]) + _cupsStrFree(v->values[j]); + } + + form_count = 0; + + cgi_unlink_file(); +} + + +/* + * '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) */ +{ + _cgi_var_t *var; /* Pointer to variable */ + + + if ((var = cgi_find_variable(name)) == NULL) + return (NULL); + + if (element < 0 || element >= var->nvalues) + return (NULL); + + return (_cupsStrRetain(var->values[element])); +} + + +/* + * 'cgiGetCookie()' - Get a cookie value. + */ + +const char * /* O - Value or NULL */ +cgiGetCookie(const char *name) /* I - Name of cookie */ +{ + return (cupsGetOption(name, num_cookies, cookies)); +} + + +/* + * 'cgiGetFile()' - Get the file (if any) that was submitted in the form. + */ + +const cgi_file_t * /* O - Attached file or NULL */ +cgiGetFile(void) +{ + return (form_file); +} + + +/* + * 'cgiGetSize()' - Get the size of a form array value. + */ + +int /* O - Number of elements */ +cgiGetSize(const char *name) /* I - Name of variable */ +{ + _cgi_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 _cgi_var_t *var; /* Returned variable */ + + + var = cgi_find_variable(name); + +#ifdef DEBUG + if (var == NULL) + DEBUG_printf(("cgiGetVariable(\"%s\") is returning NULL...\n", name)); + else + DEBUG_printf(("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name, + var->values[var->nvalues - 1])); +#endif /* DEBUG */ + + return ((var == NULL) ? NULL : _cupsStrRetain(var->values[var->nvalues - 1])); +} + + +/* + * 'cgiInitialize()' - Initialize the CGI variable "database". + */ + +int /* O - Non-zero if there was form data */ +cgiInitialize(void) +{ + const char *method, /* Form posting method */ + *content_type, /* Content-Type of post data */ + *cups_sid_cookie, /* SID cookie */ + *cups_sid_form; /* SID form variable */ + + + /* + * Setup a password callback for authentication... + */ + + cupsSetPasswordCB(cgi_passwd); + + /* + * Set the locale so that times, etc. are formatted properly... + */ + + setlocale(LC_ALL, ""); + +#ifdef DEBUG + /* + * Disable output buffering to find bugs... + */ + + setbuf(stdout, NULL); +#endif /* DEBUG */ + + /* + * Get cookies... + */ + + cgi_initialize_cookies(); + + if ((cups_sid_cookie = cgiGetCookie(CUPS_SID)) == NULL) + { + fputs("DEBUG: " CUPS_SID " cookie not found, initializing!\n", stderr); + cups_sid_cookie = cgi_set_sid(); + } + + fprintf(stderr, "DEBUG: " CUPS_SID " cookie is \"%s\"\n", cups_sid_cookie); + + /* + * Get the request method (GET or POST)... + */ + + method = getenv("REQUEST_METHOD"); + content_type = getenv("CONTENT_TYPE"); + if (!method) + return (0); + + /* + * Grab form data from the corresponding location... + */ + + if (!strcasecmp(method, "GET")) + return (cgi_initialize_get()); + else if (!strcasecmp(method, "POST") && content_type) + { + const char *boundary = strstr(content_type, "boundary="); + + if (boundary) + boundary += 9; + + if (content_type && !strncmp(content_type, "multipart/form-data; ", 21)) + { + if (!cgi_initialize_multipart(boundary)) + return (0); + } + else if (!cgi_initialize_post()) + return (0); + + if ((cups_sid_form = cgiGetVariable(CUPS_SID)) == NULL || + strcmp(cups_sid_cookie, cups_sid_form)) + { + if (cups_sid_form) + fprintf(stderr, "DEBUG: " CUPS_SID " form variable is \"%s\"\n", + cups_sid_form); + else + fputs("DEBUG: " CUPS_SID " form variable is not present.\n", stderr); + + cgiClearVariables(); + return (0); + } + else + return (1); + } + else + return (0); +} + + +/* + * 'cgiIsPOST()' - Determine whether this page was POSTed. + */ + +int /* O - 1 if POST, 0 if GET */ +cgiIsPOST(void) +{ + const char *method; /* REQUEST_METHOD environment variable */ + + + if ((method = getenv("REQUEST_METHOD")) == NULL) + return (0); + else + return (!strcmp(method, "POST")); +} + + +/* + * '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 */ + _cgi_var_t *var; /* Returned variable */ + + + if (name == NULL || value == NULL || element < 0 || element > 100000) + return; + + if ((var = cgi_find_variable(name)) == NULL) + { + cgi_add_variable(name, element, value); + cgi_sort_variables(); + } + else + { + if (element >= var->avalues) + { + const char **temp; /* Temporary pointer */ + + temp = (const char **)realloc((void *)(var->values), + sizeof(char *) * (element + 16)); + if (!temp) + return; + + var->avalues = element + 16; + var->values = temp; + } + + if (element >= var->nvalues) + { + for (i = var->nvalues; i < element; i ++) + var->values[i] = NULL; + + var->nvalues = element + 1; + } + else if (var->values[element]) + _cupsStrFree((char *)var->values[element]); + + var->values[element] = _cupsStrAlloc(value); + } +} + + +/* + * 'cgiSetCookie()' - Set a cookie value. + */ + +void +cgiSetCookie(const char *name, /* I - Name */ + const char *value, /* I - Value */ + const char *path, /* I - Path (typically "/") */ + const char *domain, /* I - Domain name */ + time_t expires, /* I - Expiration date (0 for session) */ + int secure) /* I - Require SSL */ +{ + num_cookies = cupsAddOption(name, value, num_cookies, &cookies); + + printf("Set-Cookie: %s=%s;", name, value); + if (path) + printf("; path=%s", path); + if (domain) + printf("; domain=%s", domain); + if (expires) + { + char date[256]; /* Date string */ + + printf("; expires=%s", httpGetDateString2(expires, date, sizeof(date))); + } + if (secure) + puts("; secure;"); + else + puts(";"); +} + + +/* + * '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 */ + _cgi_var_t *var; /* Returned variable */ + + + if (name == NULL || size < 0 || size > 100000) + return; + + if ((var = cgi_find_variable(name)) == NULL) + return; + + if (size >= var->avalues) + { + const char **temp; /* Temporary pointer */ + + temp = (const char **)realloc((void *)(var->values), + sizeof(char *) * (size + 16)); + if (!temp) + return; + + var->avalues = size + 16; + var->values = temp; + } + + 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]) + _cupsStrFree((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 */ + _cgi_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]) + _cupsStrFree((char *)var->values[i]); + + var->values[0] = _cupsStrAlloc(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 */ +{ + _cgi_var_t *var; /* New variable */ + + + if (name == NULL || value == NULL || element < 0 || element > 100000) + return; + + DEBUG_printf(("cgi_add_variable: Adding variable \'%s\' with value " + "\'%s\'...\n", name, value)); + + if (form_count >= form_alloc) + { + _cgi_var_t *temp_vars; /* Temporary form pointer */ + + + if (form_alloc == 0) + temp_vars = malloc(sizeof(_cgi_var_t) * 16); + else + temp_vars = realloc(form_vars, (form_alloc + 16) * sizeof(_cgi_var_t)); + + if (!temp_vars) + return; + + form_vars = temp_vars; + form_alloc += 16; + } + + var = form_vars + form_count; + + if ((var->values = calloc(element + 1, sizeof(char *))) == NULL) + return; + + var->name = _cupsStrAlloc(name); + var->nvalues = element + 1; + var->avalues = element + 1; + var->values[element] = _cupsStrAlloc(value); + + form_count ++; +} + + +/* + * 'cgi_compare_variables()' - Compare two variables. + */ + +static int /* O - Result of comparison */ +cgi_compare_variables( + const _cgi_var_t *v1, /* I - First variable */ + const _cgi_var_t *v2) /* I - Second variable */ +{ + return (strcasecmp(v1->name, v2->name)); +} + + +/* + * 'cgi_find_variable()' - Find a variable. + */ + +static _cgi_var_t * /* O - Variable pointer or NULL */ +cgi_find_variable(const char *name) /* I - Name of variable */ +{ + _cgi_var_t key; /* Search key */ + + + if (form_count < 1 || name == NULL) + return (NULL); + + key.name = name; + + return ((_cgi_var_t *)bsearch(&key, form_vars, form_count, sizeof(_cgi_var_t), + (int (*)(const void *, const void *))cgi_compare_variables)); +} + + +/* + * 'cgi_initialize_cookies()' - Initialize cookies. + */ + +static void +cgi_initialize_cookies(void) +{ + const char *cookie; /* HTTP_COOKIE environment variable */ + char name[128], /* Name string */ + value[512], /* Value string */ + *ptr; /* Pointer into name/value */ + + + if ((cookie = getenv("HTTP_COOKIE")) == NULL) + return; + + while (*cookie) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*cookie & 255)) + cookie ++; + if (!*cookie) + break; + + /* + * Copy the name... + */ + + for (ptr = name; *cookie && *cookie != '=';) + if (ptr < (name + sizeof(name) - 1)) + *ptr++ = *cookie++; + else + break; + + if (*cookie != '=') + break; + + *ptr = '\0'; + cookie ++; + + /* + * Then the value... + */ + + if (*cookie == '\"') + { + for (cookie ++, ptr = value; *cookie && *cookie != '\"';) + if (ptr < (value + sizeof(value) - 1)) + *ptr++ = *cookie++; + else + break; + + if (*cookie == '\"') + cookie ++; + } + else + { + for (ptr = value; *cookie && *cookie != ';';) + if (ptr < (value + sizeof(value) - 1)) + *ptr++ = *cookie++; + else + break; + } + + if (*cookie == ';') + cookie ++; + else if (*cookie) + break; + + *ptr = '\0'; + + /* + * Then add the cookie to an array as long as the name doesn't start with + * "$"... + */ + + if (name[0] != '$') + num_cookies = cupsAddOption(name, value, num_cookies, &cookies); + } +} + + +/* + * '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 */ + + + DEBUG_puts("cgi_initialize_get: Initializing variables using GET method..."); + + /* + * 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_multipart()' - Initialize variables and file using the POST + * method. + * + * TODO: Update to support files > 2GB. + */ + +static int /* O - 1 if form data was read */ +cgi_initialize_multipart( + const char *boundary) /* I - Boundary string */ +{ + char line[10240], /* MIME header line */ + name[1024], /* Form variable name */ + filename[1024], /* Form filename */ + mimetype[1024], /* MIME media type */ + bstring[256], /* Boundary string to look for */ + *ptr, /* Pointer into name/filename */ + *end; /* End of buffer */ + int ch, /* Character from file */ + fd, /* Temporary file descriptor */ + blen; /* Length of boundary string */ + + + DEBUG_printf(("cgi_initialize_multipart(boundary=\"%s\")\n", boundary)); + + /* + * Read multipart form data until we run out... + */ + + name[0] = '\0'; + filename[0] = '\0'; + mimetype[0] = '\0'; + + snprintf(bstring, sizeof(bstring), "\r\n--%s", boundary); + blen = strlen(bstring); + + while (fgets(line, sizeof(line), stdin)) + { + if (!strcmp(line, "\r\n")) + { + /* + * End of headers, grab value... + */ + + if (filename[0]) + { + /* + * Read an embedded file... + */ + + if (form_file) + { + /* + * Remove previous file... + */ + + cgi_unlink_file(); + } + + /* + * Allocate memory for the new file... + */ + + if ((form_file = calloc(1, sizeof(cgi_file_t))) == NULL) + return (0); + + form_file->name = strdup(name); + form_file->filename = strdup(filename); + form_file->mimetype = strdup(mimetype); + + fd = cupsTempFd(form_file->tempfile, sizeof(form_file->tempfile)); + + if (fd < 0) + return (0); + + atexit(cgi_unlink_file); + + /* + * Copy file data to the temp file... + */ + + ptr = line; + + while ((ch = getchar()) != EOF) + { + *ptr++ = ch; + + if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen)) + { + ptr -= blen; + break; + } + + if ((ptr - line - blen) >= 8192) + { + /* + * Write out the first 8k of the buffer... + */ + + write(fd, line, 8192); + memmove(line, line + 8192, ptr - line - 8192); + ptr -= 8192; + } + } + + /* + * Write the rest of the data and close the temp file... + */ + + if (ptr > line) + write(fd, line, ptr - line); + + close(fd); + } + else + { + /* + * Just get a form variable; the current code only handles + * form values up to 10k in size... + */ + + ptr = line; + end = line + sizeof(line) - 1; + + while ((ch = getchar()) != EOF) + { + if (ptr < end) + *ptr++ = ch; + + if ((ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen)) + { + ptr -= blen; + break; + } + } + + *ptr = '\0'; + + /* + * Set the form variable... + */ + + if ((ptr = strrchr(name, '-')) != NULL && isdigit(ptr[1] & 255)) + { + /* + * Set a specific index in the array... + */ + + *ptr++ = '\0'; + if (line[0]) + cgiSetArray(name, atoi(ptr) - 1, line); + } + else if (cgiGetVariable(name)) + { + /* + * Add another element in the array... + */ + + cgiSetArray(name, cgiGetSize(name), line); + } + else + { + /* + * Just set the line... + */ + + cgiSetVariable(name, line); + } + } + + /* + * Read the rest of the current line... + */ + + fgets(line, sizeof(line), stdin); + + /* + * Clear the state vars... + */ + + name[0] = '\0'; + filename[0] = '\0'; + mimetype[0] = '\0'; + } + else if (!strncasecmp(line, "Content-Disposition:", 20)) + { + if ((ptr = strstr(line + 20, " name=\"")) != NULL) + { + strlcpy(name, ptr + 7, sizeof(name)); + + if ((ptr = strchr(name, '\"')) != NULL) + *ptr = '\0'; + } + + if ((ptr = strstr(line + 20, " filename=\"")) != NULL) + { + strlcpy(filename, ptr + 11, sizeof(filename)); + + if ((ptr = strchr(filename, '\"')) != NULL) + *ptr = '\0'; + } + } + else if (!strncasecmp(line, "Content-Type:", 13)) + { + for (ptr = line + 13; isspace(*ptr & 255); ptr ++); + + strlcpy(mimetype, ptr, sizeof(mimetype)); + + for (ptr = mimetype + strlen(mimetype) - 1; + ptr > mimetype && isspace(*ptr & 255); + *ptr-- = '\0'); + } + } + + /* + * Return 1 for "form data found"... + */ + + return (1); +} + + +/* + * '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 */ + + + DEBUG_puts("cgi_initialize_post: Initializing variables using POST method..."); + + /* + * 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); + } + else + nbytes = 0; + } + else if (nbytes == 0) + { + /* + * CUPS STR #3176: OpenBSD: Early end-of-file on POST data causes 100% CPU + * + * This should never happen, but does on OpenBSD. If we see early end-of- + * file, treat this as an error and process no data. + */ + + 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 /* O - 1 if form data was processed */ +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 (!isxdigit(data[1] & 255) || !isxdigit(data[2] & 255)) + return (0); + + 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 && isspace(*s & 255)) + *s-- = '\0'; + + /* + * Add the string to the variable "database"... + */ + + if ((s = strrchr(name, '-')) != NULL && isdigit(s[1] & 255)) + { + *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_passwd()' - Catch authentication requests and notify the server. + * + * This function sends a Status header and exits, forcing authentication + * for this request. + */ + +static const char * /* O - NULL (no return) */ +cgi_passwd(const char *prompt) /* I - Prompt (not used) */ +{ + (void)prompt; + + fprintf(stderr, "DEBUG: cgi_passwd(prompt=\"%s\") called!\n", + prompt ? prompt : "(null)"); + + /* + * Send a 401 (unauthorized) status to the server, so it can notify + * the client that authentication is required. + */ + + puts("Status: 401\n"); + exit(0); + + /* + * This code is never executed, but is present to satisfy the compiler. + */ + + return (NULL); +} + + +/* + * 'cgi_set_sid()' - Set the CUPS session ID. + */ + +static const char * /* O - New session ID */ +cgi_set_sid(void) +{ + char buffer[512], /* SID data */ + sid[33]; /* SID string */ + _cups_md5_state_t md5; /* MD5 state */ + unsigned char sum[16]; /* MD5 sum */ + const char *remote_addr, /* REMOTE_ADDR */ + *server_name, /* SERVER_NAME */ + *server_port; /* SERVER_PORT */ + + + if ((remote_addr = getenv("REMOTE_ADDR")) == NULL) + remote_addr = "REMOTE_ADDR"; + if ((server_name = getenv("SERVER_NAME")) == NULL) + server_name = "SERVER_NAME"; + if ((server_port = getenv("SERVER_PORT")) == NULL) + server_port = "SERVER_PORT"; + + CUPS_SRAND(time(NULL)); + snprintf(buffer, sizeof(buffer), "%s:%s:%s:%02X%02X%02X%02X%02X%02X%02X%02X", + remote_addr, server_name, server_port, + (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255, + (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255, + (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255, + (unsigned)CUPS_RAND() & 255, (unsigned)CUPS_RAND() & 255); + _cupsMD5Init(&md5); + _cupsMD5Append(&md5, (unsigned char *)buffer, (int)strlen(buffer)); + _cupsMD5Finish(&md5, sum); + + cgiSetCookie(CUPS_SID, httpMD5String(sum, sid), "/", NULL, 0, 0); + + return (cupsGetOption(CUPS_SID, num_cookies, cookies)); +} + + +/* + * 'cgi_sort_variables()' - Sort all form variables for faster lookup. + */ + +static void +cgi_sort_variables(void) +{ +#ifdef DEBUG + int i; + + + DEBUG_puts("cgi_sort_variables: Sorting variables..."); +#endif /* DEBUG */ + + if (form_count < 2) + return; + + qsort(form_vars, form_count, sizeof(_cgi_var_t), + (int (*)(const void *, const void *))cgi_compare_variables); + +#ifdef DEBUG + DEBUG_puts("cgi_sort_variables: Sorted variable list is:"); + for (i = 0; i < form_count; i ++) + DEBUG_printf(("cgi_sort_variables: %d: %s (%d) = \"%s\" ...\n", i, + form_vars[i].name, form_vars[i].nvalues, + form_vars[i].values[0])); +#endif /* DEBUG */ +} + + +/* + * 'cgi_unlink_file()' - Remove the uploaded form. + */ + +static void +cgi_unlink_file(void) +{ + if (form_file) + { + /* + * Remove the temporary file... + */ + + unlink(form_file->tempfile); + + /* + * Free memory used... + */ + + free(form_file->name); + free(form_file->filename); + free(form_file->mimetype); + free(form_file); + + form_file = NULL; + } +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/websearch.c b/cgi-bin/websearch.c new file mode 100644 index 0000000000..351f92db08 --- /dev/null +++ b/cgi-bin/websearch.c @@ -0,0 +1,116 @@ +/* + * "$Id$" + * + * Web search program for www.cups.org. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Usage: + * + * websearch directory "search string" + * + * Contents: + * + * main() - Search a directory of help files. + * list_nodes() - List matching nodes. + */ + +/* + * Include necessary headers... + */ + +#include "cgi.h" + + +/* + * Local functions... + */ + +static void list_nodes(help_index_t *hi, const char *title, + cups_array_t *nodes); + + +/* + * 'main()' - Test the help index code. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + help_index_t *hi, /* Help index */ + *search; /* Search index */ + char indexname[1024]; /* Name of index file */ + + + if (argc != 3) + { + puts("Usage: websearch directory \"search terms\""); + return (1); + } + + /* + * Load the help index... + */ + + snprintf(indexname, sizeof(indexname), "%s/.index", argv[1]); + hi = helpLoadIndex(indexname, argv[1]); + + /* + * Do any searches... + */ + + search = helpSearchIndex(hi, argv[2], NULL, NULL); + + if (search) + list_nodes(hi, argv[1], search->sorted); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'list_nodes()' - List nodes in an array... + */ + +static void +list_nodes(help_index_t *hi, /* I - Help index */ + const char *title, /* I - Title string */ + cups_array_t *nodes) /* I - Nodes */ +{ + help_node_t *node, /* Current node */ + *file; /* File node */ + + + printf("%d\n", cupsArrayCount(nodes)); + for (node = (help_node_t *)cupsArrayFirst(nodes); + node; + node = (help_node_t *)cupsArrayNext(nodes)) + { + if (node->anchor) + { + file = helpFindNode(hi, node->filename, NULL); + printf("%d|%s#%s|%s|%s\n", node->score, node->filename, node->anchor, + node->text, file ? file->text : node->filename); + } + else + printf("%d|%s|%s|%s\n", node->score, node->filename, node->text, + node->text); + } +} + + +/* + * End of "$Id$". + */ diff --git a/conf/Makefile b/conf/Makefile new file mode 100644 index 0000000000..503cf2596a --- /dev/null +++ b/conf/Makefile @@ -0,0 +1,143 @@ +# +# "$Id$" +# +# Configuration file makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1993-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +# +# Config files... +# + +KEEP = cupsd.conf snmp.conf +REPLACE = mime.convs mime.types + + +# +# Make everything... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Dummy depend... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + for file in $(KEEP); do \ + if test -r $(SERVERROOT)/$$file ; then \ + $(INSTALL_CONFIG) -g $(CUPS_GROUP) $$file $(SERVERROOT)/$$file.N ; \ + else \ + $(INSTALL_CONFIG) -g $(CUPS_GROUP) $$file $(SERVERROOT) ; \ + fi ; \ + done + $(INSTALL_CONFIG) -g $(CUPS_GROUP) cupsd.conf $(SERVERROOT)/cupsd.conf.default + $(INSTALL_DIR) -m 755 $(DATADIR)/mime + for file in $(REPLACE); do \ + if test -r $(DATADIR)/mime/$$file ; then \ + $(MV) $(DATADIR)/mime/$$file $(DATADIR)/mime/$$file.O ; \ + fi ; \ + if test -r $(SERVERROOT)/$$file ; then \ + $(MV) $(SERVERROOT)/$$file $(DATADIR)/mime/$$file.O ; \ + fi ; \ + $(INSTALL_DATA) $$file $(DATADIR)/mime ; \ + done + -if test x$(PAMDIR) != x; then \ + $(INSTALL_DIR) -m 755 $(BUILDROOT)$(PAMDIR); \ + if test -r $(BUILDROOT)$(PAMDIR)/cups ; then \ + $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups.N ; \ + else \ + $(INSTALL_DATA) $(PAMFILE) $(BUILDROOT)$(PAMDIR)/cups ; \ + fi ; \ + fi + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: + for file in $(KEEP) $(REPLACE) cupsd.conf.default; do \ + $(RM) $(SERVERROOT)/$$file; \ + done + -$(RMDIR) $(SERVERROOT) + for file in $(REPLACE); do \ + $(RM) $(DATADIR)/mime/$$file; \ + done + -$(RMDIR) $(DATADIR)/mime + -if test x$(PAMDIR) != x; then \ + $(RM) $(BUILDROOT)$(PAMDIR)/cups; \ + $(RMDIR) $(BUILDROOT)$(PAMDIR); \ + fi + + +# +# End of "$Id$". +# diff --git a/conf/cupsd.conf.in b/conf/cupsd.conf.in new file mode 100644 index 0000000000..c42351e49e --- /dev/null +++ b/conf/cupsd.conf.in @@ -0,0 +1,125 @@ +# +# "$Id$" +# +# Sample configuration file for the CUPS scheduler. See "man cupsd.conf" for a +# complete description of this file. +# + +# Log general information in error_log - change "@CUPS_LOG_LEVEL@" to "debug" +# for troubleshooting... +LogLevel @CUPS_LOG_LEVEL@ + +# Administrator user group... +SystemGroup @CUPS_SYSTEM_GROUPS@ +@CUPS_SYSTEM_AUTHKEY@ + +# Only listen for connections from the local machine. +Listen localhost:@DEFAULT_IPP_PORT@ +@CUPS_LISTEN_DOMAINSOCKET@ + +# Show shared printers on the local network. +Browsing On +BrowseOrder allow,deny +BrowseAllow all +BrowseLocalProtocols @CUPS_BROWSE_LOCAL_PROTOCOLS@ + +# Default authentication type, when authentication is required... +DefaultAuthType Basic + +# Restrict access to the server... + + Order allow,deny + + +# Restrict access to the admin pages... + + Order allow,deny + + +# Restrict access to configuration files... + + AuthType Default + Require user @SYSTEM + Order allow,deny + + +# Set the default printer/job policies... + + # Job-related operations must be done by the owner or an administrator... + + Order deny,allow + + + + Require user @OWNER @SYSTEM + Order deny,allow + + + # All administration operations require an administrator to authenticate... + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + # All printer operations require a printer operator to authenticate... + + AuthType Default + Require user @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ + Order deny,allow + + + # Only the owner or an administrator can cancel or authenticate a job... + + Require user @OWNER @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ + Order deny,allow + + + + Order deny,allow + + + +# Set the authenticated printer/job policies... + + # Job-related operations must be done by the owner or an administrator... + + AuthType Default + Order deny,allow + + + + AuthType Default + Require user @OWNER @SYSTEM + Order deny,allow + + + # All administration operations require an administrator to authenticate... + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + # All printer operations require a printer operator to authenticate... + + AuthType Default + Require user @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ + Order deny,allow + + + # Only the owner or an administrator can cancel or authenticate a job... + + AuthType Default + Require user @OWNER @CUPS_DEFAULT_PRINTOPERATOR_AUTH@ + Order deny,allow + + + + Order deny,allow + + + +# +# End of "$Id$". +# diff --git a/conf/mime.convs.in b/conf/mime.convs.in new file mode 100644 index 0000000000..19e4f31e9b --- /dev/null +++ b/conf/mime.convs.in @@ -0,0 +1,104 @@ +# +# "$Id$" +# +# DO NOT EDIT THIS FILE, AS IT IS OVERWRITTEN WHEN YOU INSTALL NEW +# VERSIONS OF CUPS. Instead, create a "local.convs" file that +# reflects your local configuration changes. +# +# MIME converts file for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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/vnd.cups-postscript 66 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-csource 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/css 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-bitmap 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 +application/vnd.cups-banner application/postscript 33 bannertops + +######################################################################## +# +# 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-bitmap 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 part of GPL Ghostscript... +application/vnd.cups-postscript application/vnd.cups-raster 100 pstoraster + +######################################################################## +# +# Raw filter... +# +# Uncomment the following filter to allow printing of arbitrary files +# without the -oraw option. +# + +@DEFAULT_RAW_PRINTING@application/octet-stream application/vnd.cups-raw 0 - + +# +# End of "$Id$". +# diff --git a/conf/mime.types b/conf/mime.types new file mode 100644 index 0000000000..d4403001d1 --- /dev/null +++ b/conf/mime.types @@ -0,0 +1,181 @@ +# +# "$Id: mime.types 8783 2009-08-28 17:51:05Z mike $" +# +# MIME types file for the Common UNIX Printing System (CUPS). +# +# DO NOT EDIT THIS FILE, AS IT IS OVERWRITTEN WHEN YOU INSTALL NEW +# VERSIONS OF CUPS. Instead, create a "local.types" file that +# reflects your local configuration changes. +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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) +# priority(number) Sets priority of type (0=lowest, +# 100=default, 200=highest) +# 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 +# istring(offset,"string") True if bytes are identical to +# case-insensitive 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. If two types use the same +# rules to resolve a type and have the same priority, e.g. "doc" extension for +# "text/bar" and "text/foo", the returned type will be the first type as +# sorted in alphanumerically ascending order without regard to case. Thus, +# the "text/bar" type will match the "doc" extension first unless the +# "text/foo" type has specified a higher priority. +# +# 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 notation. +# + +######################################################################## +# +# Application-generated files... +# + +#application/msword doc string(0,) +application/pdf pdf string(0,%PDF) +application/postscript ai eps ps string(0,%!) string(0,<04>%!) \ + contains(0,128,<1B>%-12345X) + \ + (contains(0,4096,"LANGUAGE=POSTSCRIPT") \ + contains(0,4096,"LANGUAGE = Postscript") \ + contains(0,4096,"LANGUAGE = PostScript") \ + contains(0,4096,"LANGUAGE = POSTSCRIPT") \ + (contains(0,4096,<0a>%!) + \ + !contains(0,4096,"ENTER LANGUAGE"))) +application/vnd.hp-HPGL hpgl \ + 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,4096,"LANGUAGE=HPGL") \ + contains(0,4096,"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,) +\ + (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<002A>) string(0,II<2A00>) +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 string(4,<00000007>) +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) +image/x-icon ico + +######################################################################## +# +# Text files... +# + +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)) +application/x-csource c cxx cpp cc C h hpp \ + printable(0,1024) + \ + (string(0,/*) string(0,//) + string(0,#include) contains(0,1024,<0a>#include) \ + string(0,#define) contains(0,1024,<0a>#define)) +text/html html htm printable(0,1024) +\ + (istring(0,"") istring(0,"E) + !string(2,<1B>%0B)) \ + string(0,<1B>@) \ + (contains(0,128,<1B>%-12345X) + \ + (contains(0,4096,"LANGUAGE=PCL") \ + contains(0,4096,"LANGUAGE = PCL"))) + +######################################################################## +# +# Raw print file support... +# +# Comment the following type to prevent raw file printing. +# + +application/octet-stream + +# +# End of "$Id: mime.types 8783 2009-08-28 17:51:05Z mike $". +# diff --git a/conf/pam.opendirectory b/conf/pam.opendirectory new file mode 100644 index 0000000000..b336306a88 --- /dev/null +++ b/conf/pam.opendirectory @@ -0,0 +1,5 @@ +# cups: auth account password session +auth required pam_opendirectory.so +account required pam_permit.so +password required pam_deny.so +session required pam_permit.so diff --git a/conf/pam.securityserver b/conf/pam.securityserver new file mode 100644 index 0000000000..ff724da4d6 --- /dev/null +++ b/conf/pam.securityserver @@ -0,0 +1,7 @@ +# cups: auth account password session +auth sufficient pam_securityserver.so +auth sufficient pam_unix.so +auth required pam_deny.so +account required pam_permit.so +password required pam_deny.so +session required pam_permit.so diff --git a/conf/pam.std.in b/conf/pam.std.in new file mode 100644 index 0000000000..68fb50af3d --- /dev/null +++ b/conf/pam.std.in @@ -0,0 +1,2 @@ +auth required @PAMMODAUTH@ +account required @PAMMOD@ diff --git a/conf/snmp.conf.in b/conf/snmp.conf.in new file mode 100644 index 0000000000..43855ab66e --- /dev/null +++ b/conf/snmp.conf.in @@ -0,0 +1,13 @@ +# +# "$Id$" +# +# Sample SNMP configuration file for CUPS. See "man cups-snmp.conf" for a +# complete description of this file. +# + +@CUPS_SNMP_ADDRESS@ +@CUPS_SNMP_COMMUNITY@ + +# +# End of "$Id$". +# diff --git a/config-scripts/cups-3264.m4 b/config-scripts/cups-3264.m4 new file mode 100644 index 0000000000..a9711dd33f --- /dev/null +++ b/config-scripts/cups-3264.m4 @@ -0,0 +1,140 @@ +dnl +dnl "$Id: cups-3264.m4 8524 2009-04-19 21:18:45Z mike $" +dnl +dnl 32/64-bit library support stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Setup support for separate 32/64-bit library generation... +AC_ARG_ENABLE(32bit, [ --enable-32bit generate 32-bit libraries on 32/64-bit systems]) + +INSTALL32="" +LIB32CUPS="" +LIB32CUPSIMAGE="" +LIB32DIR="" +UNINSTALL32="" + +AC_SUBST(INSTALL32) +AC_SUBST(LIB32CUPS) +AC_SUBST(LIB32CUPSIMAGE) +AC_SUBST(LIB32DIR) +AC_SUBST(UNINSTALL32) + +AC_ARG_ENABLE(64bit, [ --enable-64bit generate 64-bit libraries on 32/64-bit systems]) + +INSTALL64="" +LIB64CUPS="" +LIB64CUPSIMAGE="" +LIB64DIR="" +UNINSTALL64="" + +AC_SUBST(INSTALL64) +AC_SUBST(LIB64CUPS) +AC_SUBST(LIB64CUPSIMAGE) +AC_SUBST(LIB64DIR) +AC_SUBST(UNINSTALL64) + +case "$uname" in + HP-UX*) + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + INSTALL32="install32bit" + LIB32CUPS="32bit/libcups.so.2" + LIB32CUPSIMAGE="32bit/libcupsimage.so.2" + LIB32DIR="$exec_prefix/lib" + if test -d /usr/lib/hpux32; then + LIB32DIR="${LIB32DIR}/hpux32" + fi + UNINSTALL32="uninstall32bit" + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + INSTALL64="install64bit" + LIB64CUPS="64bit/libcups.so.2" + LIB64CUPSIMAGE="64bit/libcupsimage.so.2" + LIB64DIR="$exec_prefix/lib" + if test -d /usr/lib/hpux64; then + LIB64DIR="${LIB64DIR}/hpux64" + fi + UNINSTALL64="uninstall64bit" + fi + ;; + + IRIX) + if test "x$enable_32bit" = xyes; then + INSTALL32="install32bit" + LIB32CUPS="32bit/libcups.so.2" + LIB32CUPSIMAGE="32bit/libcupsimage.so.2" + LIB32DIR="$prefix/lib32" + UNINSTALL32="uninstall32bit" + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + INSTALL64="install64bit" + LIB64CUPS="64bit/libcups.so.2" + LIB64CUPSIMAGE="64bit/libcupsimage.so.2" + LIB64DIR="$prefix/lib64" + UNINSTALL64="uninstall64bit" + fi + ;; + + Linux*) + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + INSTALL32="install32bit" + LIB32CUPS="32bit/libcups.so.2" + LIB32CUPSIMAGE="32bit/libcupsimage.so.2" + LIB32DIR="$exec_prefix/lib" + if test -d /usr/lib32; then + LIB32DIR="${LIB32DIR}32" + fi + UNINSTALL32="uninstall32bit" + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + INSTALL64="install64bit" + LIB64CUPS="64bit/libcups.so.2" + LIB64CUPSIMAGE="64bit/libcupsimage.so.2" + LIB64DIR="$exec_prefix/lib" + if test -d /usr/lib64; then + LIB64DIR="${LIB64DIR}64" + fi + UNINSTALL64="uninstall64bit" + fi + ;; + + SunOS*) + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + INSTALL32="install32bit" + LIB32CUPS="32bit/libcups.so.2" + LIB32CUPSIMAGE="32bit/libcupsimage.so.2" + LIB32DIR="$exec_prefix/lib/32" + UNINSTALL32="uninstall32bit" + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + INSTALL64="install64bit" + LIB64CUPS="64bit/libcups.so.2" + LIB64CUPSIMAGE="64bit/libcupsimage.so.2" + LIB64DIR="$exec_prefix/lib/64" + UNINSTALL64="uninstall64bit" + fi + ;; +esac + +dnl +dnl End of "$Id: cups-3264.m4 8524 2009-04-19 21:18:45Z mike $". +dnl diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 new file mode 100644 index 0000000000..6d4a5fefc4 --- /dev/null +++ b/config-scripts/cups-common.m4 @@ -0,0 +1,375 @@ +dnl +dnl "$Id: cups-common.m4 9482 2011-01-14 18:57:44Z mike $" +dnl +dnl Common configuration stuff for CUPS. +dnl +dnl Copyright 2007-2011 by Apple Inc. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl We need at least autoconf 2.60... +AC_PREREQ(2.60) + +dnl Set the name of the config header file... +AC_CONFIG_HEADER(config.h) + +dnl Version number information... +CUPS_VERSION="1.4.7" +CUPS_REVISION="" +#if test -z "$CUPS_REVISION" -a -d .svn; then +# CUPS_REVISION="-r`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[[a-zA-Z]]*//g'`" +#fi +CUPS_BUILD="cups-$CUPS_VERSION" + +AC_ARG_WITH(cups_build, [ --with-cups-build set "cups-config --build" string ], + CUPS_BUILD="$withval") + +AC_SUBST(CUPS_VERSION) +AC_SUBST(CUPS_REVISION) +AC_SUBST(CUPS_BUILD) +AC_DEFINE_UNQUOTED(CUPS_SVERSION, "CUPS v$CUPS_VERSION$CUPS_REVISION") +AC_DEFINE_UNQUOTED(CUPS_MINIMAL, "CUPS/$CUPS_VERSION$CUPS_REVISION") + +dnl Default compiler flags... +CFLAGS="${CFLAGS:=}" +CPPFLAGS="${CPPFLAGS:=}" +CXXFLAGS="${CXXFLAGS:=}" +LDFLAGS="${LDFLAGS:=}" + +dnl Checks for programs... +AC_PROG_AWK +AC_PROG_CC +AC_PROG_CPP +AC_PROG_CXX +AC_PROG_RANLIB +AC_PATH_PROG(AR,ar) +AC_PATH_PROG(CHMOD,chmod) +AC_PATH_PROG(HTMLDOC,htmldoc) +AC_PATH_PROG(LD,ld) +AC_PATH_PROG(LN,ln) +AC_PATH_PROG(MV,mv) +AC_PATH_PROG(RM,rm) +AC_PATH_PROG(RMDIR,rmdir) +AC_PATH_PROG(SED,sed) +AC_PATH_PROG(XDGOPEN,xdg-open) +if test "x$XDGOPEN" = x; then + CUPS_HTMLVIEW="htmlview" +else + CUPS_HTMLVIEW="$XDGOPEN" +fi +AC_SUBST(CUPS_HTMLVIEW) + +AC_MSG_CHECKING(for install-sh script) +INSTALL="`pwd`/install-sh" +AC_SUBST(INSTALL) +AC_MSG_RESULT(using $INSTALL) + +if test "x$AR" = x; then + AC_MSG_ERROR([Unable to find required library archive command.]) +fi +if test "x$CC" = x; then + AC_MSG_ERROR([Unable to find required C compiler command.]) +fi + +dnl Static library option... +INSTALLSTATIC="" +AC_ARG_ENABLE(static, [ --enable-static install static libraries]) + +if test x$enable_static = xyes; then + echo Installing static libraries... + INSTALLSTATIC="installstatic" +fi + +AC_SUBST(INSTALLSTATIC) + +dnl Check for pkg-config, which is used for some other tests later on... +AC_PATH_PROG(PKGCONFIG, pkg-config) + +dnl Check for libraries... +AC_SEARCH_LIBS(crypt, crypt) +AC_SEARCH_LIBS(getspent, sec gen) + +LIBMALLOC="" +AC_ARG_ENABLE(mallinfo, [ --enable-mallinfo build with malloc debug logging]) + +if test x$enable_mallinfo = xyes; then + SAVELIBS="$LIBS" + LIBS="" + AC_SEARCH_LIBS(mallinfo, malloc, AC_DEFINE(HAVE_MALLINFO)) + LIBMALLOC="$LIBS" + LIBS="$SAVELIBS" +fi + +AC_SUBST(LIBMALLOC) + +dnl Check for libpaper support... +AC_ARG_ENABLE(libpaper, [ --enable-libpaper build with libpaper support]) + +if test x$enable_libpaper = xyes; then + AC_CHECK_LIB(paper,systempapername, + AC_DEFINE(HAVE_LIBPAPER) + LIBPAPER="-lpaper", + LIBPAPER="") +else + LIBPAPER="" +fi +AC_SUBST(LIBPAPER) + +dnl Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADER(crypt.h,AC_DEFINE(HAVE_CRYPT_H)) +AC_CHECK_HEADER(langinfo.h,AC_DEFINE(HAVE_LANGINFO_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)) +AC_CHECK_HEADER(sys/param.h,AC_DEFINE(HAVE_SYS_PARAM_H)) +AC_CHECK_HEADER(sys/ucred.h,AC_DEFINE(HAVE_SYS_UCRED_H)) +AC_CHECK_HEADER(scsi/sg.h,AC_DEFINE(HAVE_SCSI_SG_H)) + +dnl Checks for statfs and its many headers... +AC_CHECK_HEADER(sys/mount.h,AC_DEFINE(HAVE_SYS_MOUNT_H)) +AC_CHECK_HEADER(sys/statfs.h,AC_DEFINE(HAVE_SYS_STATFS_H)) +AC_CHECK_HEADER(sys/statvfs.h,AC_DEFINE(HAVE_SYS_STATVFS_H)) +AC_CHECK_HEADER(sys/vfs.h,AC_DEFINE(HAVE_SYS_VFS_H)) +AC_CHECK_FUNCS(statfs statvfs) + +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 for random number functions... +AC_CHECK_FUNCS(random lrand48 arc4random) + +dnl Check for geteuid function. +AC_CHECK_FUNCS(geteuid) + +dnl Check for vsyslog function. +AC_CHECK_FUNCS(vsyslog) + +dnl Checks for signal functions. +case "$uname" in + Linux | GNU) + # Do not use sigset on Linux or GNU HURD + ;; + *) + # Use sigset on other platforms, if available + AC_CHECK_FUNCS(sigset) + ;; +esac + +AC_CHECK_FUNCS(sigaction) + +dnl Checks for wait functions. +AC_CHECK_FUNCS(waitpid 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 ],[struct tm t; + int o = t.tm_gmtoff;], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_TM_GMTOFF), + AC_MSG_RESULT(no)) + +dnl See if the stat structure has the st_gen member... +AC_MSG_CHECKING(for st_gen member in stat structure) +AC_TRY_COMPILE([#include ],[struct stat t; + int o = t.st_gen;], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ST_GEN), + AC_MSG_RESULT(no)) + +dnl See if we have the removefile(3) function for securely removing files +AC_CHECK_FUNCS(removefile) + +dnl See if we have libusb... +AC_ARG_ENABLE(libusb, [ --enable-libusb use libusb for USB printing]) + +LIBUSB="" +AC_SUBST(LIBUSB) + +if test x$enable_libusb = xyes; then + check_libusb=yes +elif test x$enable_libusb != xno -a $uname != Darwin; then + check_libusb=yes +else + check_libusb=no +fi + +if test $check_libusb = yes; then + AC_CHECK_LIB(usb, usb_get_string_simple,[ + AC_CHECK_HEADER(usb.h, + AC_DEFINE(HAVE_USB_H) + LIBUSB="-lusb")]) +fi + +dnl See if we have libwrap for TCP wrappers support... +AC_ARG_ENABLE(tcp_wrappers, [ --enable-tcp-wrappers use libwrap for TCP wrappers support]) + +LIBWRAP="" +AC_SUBST(LIBWRAP) + +if test x$enable_tcp_wrappers = xyes; then + AC_CHECK_LIB(wrap, hosts_access,[ + AC_CHECK_HEADER(tcpd.h, + AC_DEFINE(HAVE_TCPD_H) + LIBWRAP="-lwrap")]) +fi + +dnl Flags for "ar" command... +case $uname in + Darwin* | *BSD*) + ARFLAGS="-rcv" + ;; + *) + ARFLAGS="crvs" + ;; +esac + +AC_SUBST(ARFLAGS) + +dnl Prep libraries specifically for cupsd and backends... +BACKLIBS="" +CUPSDLIBS="" +AC_SUBST(BACKLIBS) +AC_SUBST(CUPSDLIBS) + +dnl See if we have POSIX ACL support... +SAVELIBS="$LIBS" +LIBS="" +AC_ARG_ENABLE(acl, [ --enable-acl build with POSIX ACL support]) +if test "x$enable_acl" != xno; then + AC_SEARCH_LIBS(acl_init, acl, AC_DEFINE(HAVE_ACL_INIT)) + CUPSDLIBS="$CUPSDLIBS $LIBS" +fi +LIBS="$SAVELIBS" + +dnl Check for DBUS support +if test -d /etc/dbus-1; then + DBUSDIR="/etc/dbus-1" +else + DBUSDIR="" +fi + +AC_ARG_ENABLE(dbus, [ --enable-dbus build with DBUS support]) +AC_ARG_WITH(dbusdir, [ --with-dbusdir set DBUS configuration directory ], + DBUSDIR="$withval") + +DBUS_NOTIFIER="" +DBUS_NOTIFIERLIBS="" + +if test "x$enable_dbus" != xno -a "x$PKGCONFIG" != x; then + AC_MSG_CHECKING(for DBUS) + if $PKGCONFIG --exists dbus-1; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DBUS) + CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1` -DDBUS_API_SUBJECT_TO_CHANGE" + CUPSDLIBS="$CUPSDLIBS `$PKGCONFIG --libs dbus-1`" + DBUS_NOTIFIER="dbus" + DBUS_NOTIFIERLIBS="`$PKGCONFIG --libs dbus-1`" + SAVELIBS="$LIBS" + LIBS="$LIBS $DBUS_NOTIFIERLIBS" + AC_CHECK_FUNC(dbus_message_iter_init_append, + AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_INIT_APPEND)) + LIBS="$SAVELIBS" + else + AC_MSG_RESULT(no) + fi +fi + +AC_SUBST(DBUSDIR) +AC_SUBST(DBUS_NOTIFIER) +AC_SUBST(DBUS_NOTIFIERLIBS) + +dnl Extra platform-specific libraries... +CUPS_DEFAULT_PRINTOPERATOR_AUTH="@SYSTEM" +CUPS_SYSTEM_AUTHKEY="" +FONTS="fonts" +LEGACY_BACKENDS="parallel scsi" + +case $uname in + Darwin*) + LEGACY_BACKENDS="" + BACKLIBS="$BACKLIBS -framework IOKit" + CUPSDLIBS="$CUPSDLIBS -sectorder __TEXT __text cupsd.order -e start -framework IOKit -framework SystemConfiguration -weak_framework ApplicationServices" + LIBS="-framework SystemConfiguration -framework CoreFoundation -framework Security $LIBS" + + dnl Check for framework headers... + AC_CHECK_HEADER(ApplicationServices/ApplicationServices.h,AC_DEFINE(HAVE_APPLICATIONSERVICES_H)) + AC_CHECK_HEADER(CoreFoundation/CoreFoundation.h,AC_DEFINE(HAVE_COREFOUNDATION_H)) + AC_CHECK_HEADER(CoreFoundation/CFPriv.h,AC_DEFINE(HAVE_CFPRIV_H)) + AC_CHECK_HEADER(CoreFoundation/CFBundlePriv.h,AC_DEFINE(HAVE_CFBUNDLEPRIV_H)) + + dnl Check for dynamic store function... + AC_CHECK_FUNCS(SCDynamicStoreCopyComputerName) + + dnl Check for the new membership functions in MacOSX 10.4... + AC_CHECK_HEADER(membership.h,AC_DEFINE(HAVE_MEMBERSHIP_H)) + AC_CHECK_HEADER(membershipPriv.h,AC_DEFINE(HAVE_MEMBERSHIPPRIV_H)) + AC_CHECK_FUNCS(mbr_uid_to_uuid) + + dnl Check for the vproc_transaction_begin/end stuff... + AC_CHECK_FUNCS(vproc_transaction_begin) + + dnl Need header... + AC_CHECK_HEADER(dlfcn.h,AC_DEFINE(HAVE_DLFCN_H)) + + dnl Check for notify_post support + AC_CHECK_HEADER(notify.h,AC_DEFINE(HAVE_NOTIFY_H)) + AC_CHECK_FUNCS(notify_post) + + dnl Check for Authorization Services support + AC_ARG_WITH(adminkey, [ --with-adminkey set the default SystemAuthKey value], + default_adminkey="$withval", + default_adminkey="default") + AC_ARG_WITH(operkey, [ --with-operkey set the default operator @AUTHKEY value], + default_operkey="$withval", + default_operkey="default") + + AC_CHECK_HEADER(Security/Authorization.h, [ + AC_DEFINE(HAVE_AUTHORIZATION_H) + + if test "x$default_adminkey" != xdefault; then + CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey $default_adminkey" + elif grep -q system.print.operator /etc/authorization; then + CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.print.admin" + else + CUPS_SYSTEM_AUTHKEY="SystemGroupAuthKey system.preferences" + fi + + if test "x$default_operkey" != xdefault; then + CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY($default_operkey) @admin @lpadmin" + elif grep -q system.print.operator /etc/authorization; then + CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY(system.print.operator) @admin @lpadmin" + else + CUPS_DEFAULT_PRINTOPERATOR_AUTH="@AUTHKEY(system.print.admin) @admin @lpadmin" + fi]) + AC_CHECK_HEADER(Security/SecBasePriv.h,AC_DEFINE(HAVE_SECBASEPRIV_H)) + + dnl Check for sandbox/Seatbelt support + AC_CHECK_HEADER(sandbox.h,AC_DEFINE(HAVE_SANDBOX_H)) + ;; +esac + +AC_SUBST(CUPS_DEFAULT_PRINTOPERATOR_AUTH) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_PRINTOPERATOR_AUTH, "$CUPS_DEFAULT_PRINTOPERATOR_AUTH") +AC_SUBST(CUPS_SYSTEM_AUTHKEY) +AC_SUBST(FONTS) +AC_SUBST(LEGACY_BACKENDS) + +dnl +dnl End of "$Id: cups-common.m4 9482 2011-01-14 18:57:44Z mike $". +dnl diff --git a/config-scripts/cups-compiler.m4 b/config-scripts/cups-compiler.m4 new file mode 100644 index 0000000000..1c880d2e62 --- /dev/null +++ b/config-scripts/cups-compiler.m4 @@ -0,0 +1,574 @@ +dnl +dnl "$Id: cups-compiler.m4 9822 2011-06-10 22:59:36Z mike $" +dnl +dnl Compiler stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Clear the debugging and non-shared library options unless the user asks +dnl for them... +INSTALL_STRIP="" +OPTIM="" +AC_SUBST(INSTALL_STRIP) +AC_SUBST(OPTIM) + +AC_ARG_WITH(optim, [ --with-optim set optimization flags ]) +AC_ARG_ENABLE(debug, [ --enable-debug build with debugging symbols]) +AC_ARG_ENABLE(debug_guards, [ --enable-debug-guards build with memory allocation guards]) +AC_ARG_ENABLE(debug_printfs, [ --enable-debug-printfs build with CUPS_DEBUG_LOG support]) +AC_ARG_ENABLE(unit_tests, [ --enable-unit-tests build and run unit tests]) + +dnl For debugging, keep symbols, otherwise strip them... +if test x$enable_debug = xyes; then + OPTIM="-g" +else + INSTALL_STRIP="-s" +fi + +dnl Debug printfs can slow things down, so provide a separate option for that +if test x$enable_debug_printfs = xyes; then + CFLAGS="$CFLAGS -DDEBUG" + CXXFLAGS="$CXXFLAGS -DDEBUG" +fi + +dnl Debug guards use an extra 4 bytes for some structures like strings in the +dnl string pool, so provide a separate option for that +if test x$enable_debug_guards = xyes; then + CFLAGS="$CFLAGS -DDEBUG_GUARDS" + CXXFLAGS="$CXXFLAGS -DDEBUG_GUARDS" +fi + +dnl Unit tests take up time during a compile... +if test x$enable_unit_tests = xyes; then + UNITTESTS="unittests" +else + UNITTESTS="" +fi +AC_SUBST(UNITTESTS) + +dnl Setup general architecture flags... +AC_ARG_WITH(archflags, [ --with-archflags set default architecture flags ]) +AC_ARG_WITH(ldarchflags, [ --with-ldarchflags set program architecture flags ]) + +if test -z "$with_archflags"; then + ARCHFLAGS="" +else + ARCHFLAGS="$with_archflags" +fi + +if test -z "$with_ldarchflags"; then + if test "$uname" = Darwin; then + # Only create 32-bit programs by default + LDARCHFLAGS="`echo $ARCHFLAGS | sed -e '1,$s/-arch x86_64//' -e '1,$s/-arch ppc64//'`" + else + LDARCHFLAGS="$ARCHFLAGS" + fi +else + LDARCHFLAGS="$with_ldarchflags" +fi + +AC_SUBST(ARCHFLAGS) +AC_SUBST(LDARCHFLAGS) + +dnl Setup support for separate 32/64-bit library generation... +AC_ARG_WITH(arch32flags, [ --with-arch32flags set 32-bit architecture flags]) +ARCH32FLAGS="" +AC_SUBST(ARCH32FLAGS) + +AC_ARG_WITH(arch64flags, [ --with-arch64flags set 64-bit architecture flags]) +ARCH64FLAGS="" +AC_SUBST(ARCH64FLAGS) + +dnl Read-only data/program support on Linux... +AC_ARG_ENABLE(relro, [ --enable-relro build with the GCC relro option]) + +dnl Update compiler options... +CXXLIBS="${CXXLIBS:=}" +AC_SUBST(CXXLIBS) + +PIEFLAGS="" +AC_SUBST(PIEFLAGS) + +RELROFLAGS="" +AC_SUBST(RELROFLAGS) + +LIBCUPSORDER="libcups.order" +AC_ARG_WITH(libcupsorder, [ --with-libcupsorder set libcups secorder file, default=libcups.order], + if test -f "$withval"; then + LIBCUPSORDER="$withval" + fi) +AC_SUBST(LIBCUPSORDER) + +LIBCUPSIMAGEORDER="libcupsimage.order" +AC_ARG_WITH(libcupsimageorder, [ --with-libcupsimagesorder + set libcupsimage secorder file, default=libcupsimage.order], + if test -f "$withval"; then + LIBCUPSIMAGEORDER="$withval" + fi) +AC_SUBST(LIBCUPSIMAGEORDER) + +PHPOPTIONS="" +AC_SUBST(PHPOPTIONS) + +if test -n "$GCC"; then + # Add GCC-specific compiler options... + if test -z "$OPTIM"; then + if test "x$with_optim" = x; then + # Default to optimize-for-size and debug + OPTIM="-Os -g" + else + OPTIM="$with_optim $OPTIM" + fi + fi + + # Generate position-independent code as needed... + if test $PICFLAG = 1 -a $uname != AIX; then + OPTIM="-fPIC $OPTIM" + fi + + # The -fstack-protector option is available with some versions of + # GCC and adds "stack canaries" which detect when the return address + # has been overwritten, preventing many types of exploit attacks. + AC_MSG_CHECKING(if GCC supports -fstack-protector) + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fstack-protector" + AC_TRY_LINK(,, + OPTIM="$OPTIM -fstack-protector" + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + CFLAGS="$OLDCFLAGS" + + # The -fPIE option is available with some versions of GCC and adds + # randomization of addresses, which avoids another class of exploits + # that depend on a fixed address for common functions. + AC_MSG_CHECKING(if GCC supports -fPIE) + OLDCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fPIE" + AC_TRY_COMPILE(,, + [case "$CC" in + *clang) + PIEFLAGS="-fPIE -Wl,-pie" + ;; + *) + PIEFLAGS="-fPIE -pie" + ;; + esac + AC_MSG_RESULT(yes)], + AC_MSG_RESULT(no)) + CFLAGS="$OLDCFLAGS" + + if test "x$with_optim" = x; then + # Add useful warning options for tracking down problems... + OPTIM="-Wall -Wno-format-y2k $OPTIM" + # Additional warning options for development testing... + if test -d .svn; then + OPTIM="-Wshadow -Wunused $OPTIM" + CFLAGS="-Werror-implicit-function-declaration $CFLAGS" + PHPOPTIONS="-Wno-shadow" + fi + fi + + case "$uname" in + Darwin*) + # -D_FORTIFY_SOURCE=2 adds additional object size + # checking, basically wrapping all string functions + # with buffer-limited ones. Not strictly needed for + # CUPS since we already use buffer-limited calls, but + # this will catch any additions that are broken. + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + + if test x$enable_pie = xyes; then + # GCC 4 on Mac OS X needs -Wl,-pie as well + LDFLAGS="$LDFLAGS -Wl,-pie" + fi + ;; + + HP-UX*) + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + if test -z "$with_arch32flags"; then + ARCH32FLAGS="-milp32" + else + ARCH32FLAGS="$with_arch32flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="-mlp64" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + if test -z "$with_arch64flags"; then + ARCH64FLAGS="-mlp64" + else + ARCH64FLAGS="$with_arch64flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="-milp32" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + fi + ;; + + IRIX) + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + if test -z "$with_arch32flags"; then + ARCH32FLAGS="-n32 -mips3" + else + ARCH32FLAGS="$with_arch32flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="-64 -mips4" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + if test -z "$with_arch64flags"; then + ARCH64FLAGS="-64 -mips4" + else + ARCH64FLAGS="$with_arch64flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="-n32 -mips3" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + fi + ;; + + Linux*) + # The -z relro option is provided by the Linux linker command to + # make relocatable data read-only. + if test x$enable_relro = xyes; then + RELROFLAGS="-Wl,-z,relro" + fi + + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + if test -z "$with_arch32flags"; then + ARCH32FLAGS="-m32" + else + ARCH32FLAGS="$with_arch32flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="-m64" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + if test -z "$with_arch64flags"; then + ARCH64FLAGS="-m64" + else + ARCH64FLAGS="$with_arch64flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="-m32" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + fi + ;; + + SunOS*) + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + if test -z "$with_arch32flags"; then + ARCH32FLAGS="-m32" + else + ARCH32FLAGS="$with_arch32flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="-m64" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + if test -z "$with_arch64flags"; then + ARCH64FLAGS="-m64" + else + ARCH64FLAGS="$with_arch64flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="-m32" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + fi + ;; + esac +else + # Add vendor-specific compiler options... + 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 $PICFLAG = 1; then + OPTIM="+z $OPTIM" + fi + + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + if test -z "$with_arch32flags"; then + ARCH32FLAGS="+DD32" + else + ARCH32FLAGS="$with_arch32flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="+DD64" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + if test -z "$with_arch64flags"; then + ARCH64FLAGS="+DD64" + else + ARCH64FLAGS="$with_arch64flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="+DD32" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + 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 "x$with_optim" = x; then + OPTIM="-fullwarn -woff 1183,1209,1349,1506,3201 $OPTIM" + fi + + if test "x$enable_32bit" = xyes; then + # Build 32-bit libraries, 64-bit base... + if test -z "$with_arch32flags"; then + ARCH32FLAGS="-n32 -mips3" + else + ARCH32FLAGS="$with_arch32flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="-64 -mips4" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + fi + + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries, 32-bit base... + if test -z "$with_arch64flags"; then + ARCH64FLAGS="-64 -mips4" + else + ARCH64FLAGS="$with_arch64flags" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="-n32 -mips3" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + fi + ;; + OSF*) + # Tru64 UNIX aka Digital UNIX aka OSF/1 + if test -z "$OPTIM"; then + if test "x$with_optim" = x; then + OPTIM="-O" + else + OPTIM="$with_optim" + fi + fi + ;; + SunOS*) + # Solaris + if test -z "$OPTIM"; then + if test "x$with_optim" = x; then + OPTIM="-xO2" + else + OPTIM="$with_optim $OPTIM" + fi + fi + + if test $PICFLAG = 1; then + OPTIM="-KPIC $OPTIM" + fi + + if test "x$enable_32bit" = xyes; then + # Compiling on a Solaris system, build 64-bit + # binaries with separate 32-bit libraries... + ARCH32FLAGS="-xarch=generic" + + if test "x$with_optim" = x; then + # Suppress all of Sun's questionable + # warning messages, and default to + # 64-bit compiles of everything else... + OPTIM="-w $OPTIM" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch64flags"; then + ARCHFLAGS="-xarch=generic64" + else + ARCHFLAGS="$with_arch64flags" + fi + fi + else + if test "x$enable_64bit" = xyes; then + # Build 64-bit libraries... + ARCH64FLAGS="-xarch=generic64" + fi + + if test "x$with_optim" = x; then + # Suppress all of Sun's questionable + # warning messages, and default to + # 32-bit compiles of everything else... + OPTIM="-w $OPTIM" + fi + + if test -z "$with_archflags"; then + if test -z "$with_arch32flags"; then + ARCHFLAGS="-xarch=generic" + else + ARCHFLAGS="$with_arch32flags" + fi + fi + 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 LDFLAGS environment" + echo "variables before running configure." + ;; + esac +fi + +# Add general compiler options per platform... +case $uname in + HP-UX*) + # HP-UX 10.20 (at least) needs this definition to get the + # h_errno global... + OPTIM="$OPTIM -D_XOPEN_SOURCE_EXTENDED" + + # HP-UX 11.00 (at least) needs this definition to get the + # u_short type used by the IP headers... + OPTIM="$OPTIM -D_INCLUDE_HPUX_SOURCE" + + # HP-UX 11.23 (at least) needs this definition to get the + # IPv6 header to work... + OPTIM="$OPTIM -D_HPUX_SOURCE" + ;; + + Linux*) + # glibc 2.8 and higher breaks peer credentials unless you + # define _GNU_SOURCE... + OPTIM="$OPTIM -D_GNU_SOURCE" + ;; + + OSF*) + # Tru64 UNIX aka Digital UNIX aka OSF/1 need to be told + # to be POSIX-compliant... + OPTIM="$OPTIM -D_XOPEN_SOURCE=500 -D_XOPEN_SOURCE_EXTENDED -D_OSF_SOURCE" + ;; +esac + +dnl +dnl End of "$Id: cups-compiler.m4 9822 2011-06-10 22:59:36Z mike $". +dnl diff --git a/config-scripts/cups-defaults.m4 b/config-scripts/cups-defaults.m4 new file mode 100644 index 0000000000..0d08f402b4 --- /dev/null +++ b/config-scripts/cups-defaults.m4 @@ -0,0 +1,452 @@ +dnl +dnl "$Id: cups-defaults.m4 8929 2009-12-15 22:40:37Z mike $" +dnl +dnl Default cupsd configuration settings for the Common UNIX Printing System +dnl (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 2006-2007 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Default languages... +LANGUAGES="`ls -1 locale/cups_*.po | sed -e '1,$s/locale\/cups_//' -e '1,$s/\.po//' | tr '\n' ' '`" + +AC_ARG_WITH(languages, [ --with-languages set installed languages, default=all ],[ + case "$withval" in + none | no) LANGUAGES="" ;; + all) ;; + *) LANGUAGES="$withval" ;; + esac]) +AC_SUBST(LANGUAGES) + +dnl Default ConfigFilePerm +AC_ARG_WITH(config_file_perm, [ --with-config-file-perm set default ConfigFilePerm value, default=0640], + CUPS_CONFIG_FILE_PERM="$withval", + if test "x$uname" = xDarwin; then + CUPS_CONFIG_FILE_PERM="644" + else + CUPS_CONFIG_FILE_PERM="640" + fi) +AC_SUBST(CUPS_CONFIG_FILE_PERM) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_CONFIG_FILE_PERM, 0$CUPS_CONFIG_FILE_PERM) + +dnl Default LogFilePerm +AC_ARG_WITH(log_file_perm, [ --with-log-file-perm set default LogFilePerm value, default=0644], + CUPS_LOG_FILE_PERM="$withval", + CUPS_LOG_FILE_PERM="644") +AC_SUBST(CUPS_LOG_FILE_PERM) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_LOG_FILE_PERM, 0$CUPS_LOG_FILE_PERM) + +dnl Default FatalErrors +AC_ARG_WITH(fatal_errors, [ --with-fatal-errors set default FatalErrors value, default=config], + CUPS_FATAL_ERRORS="$withval", + CUPS_FATAL_ERRORS="config") +AC_SUBST(CUPS_FATAL_ERRORS) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_FATAL_ERRORS, "$CUPS_FATAL_ERRORS") + + +dnl Default LogLevel +AC_ARG_WITH(log_level, [ --with-log-level set default LogLevel value, default=warn], + CUPS_LOG_LEVEL="$withval", + CUPS_LOG_LEVEL="warn") +AC_SUBST(CUPS_LOG_LEVEL) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_LOG_LEVEL, "$CUPS_LOG_LEVEL") + +dnl Default AccessLogLevel +AC_ARG_WITH(access_log_level, [ --with-access-log-level set default AccessLogLevel value, default=actions], + CUPS_ACCESS_LOG_LEVEL="$withval", + CUPS_ACCESS_LOG_LEVEL="actions") +AC_SUBST(CUPS_ACCESS_LOG_LEVEL) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_ACCESS_LOG_LEVEL, "$CUPS_ACCESS_LOG_LEVEL") + +dnl Default Browsing +AC_ARG_ENABLE(browsing, [ --disable-browsing disable Browsing by default]) +if test "x$enable_browsing" = xno; then + CUPS_BROWSING="No" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSING, 0) +else + CUPS_BROWSING="Yes" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSING, 1) +fi +AC_SUBST(CUPS_BROWSING) + +dnl Default BrowseLocalProtocols +AC_ARG_WITH(local_protocols, [ --with-local-protocols set default BrowseLocalProtocols, default="CUPS"], + default_local_protocols="$withval", + default_local_protocols="default") + +if test x$with_local_protocols != xno; then + if test "x$default_local_protocols" = "xdefault"; then + if test "x$DNSSDLIBS" != "x"; then + CUPS_BROWSE_LOCAL_PROTOCOLS="CUPS dnssd" + else + CUPS_BROWSE_LOCAL_PROTOCOLS="CUPS" + fi + else + CUPS_BROWSE_LOCAL_PROTOCOLS="$default_local_protocols" + fi +else + CUPS_BROWSE_LOCAL_PROTOCOLS="" +fi + +AC_SUBST(CUPS_BROWSE_LOCAL_PROTOCOLS) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS, + "$CUPS_BROWSE_LOCAL_PROTOCOLS") + +dnl Default BrowseRemoteProtocols +AC_ARG_WITH(remote_protocols, [ --with-remote-protocols set default BrowseRemoteProtocols, default="CUPS"], + default_remote_protocols="$withval", + default_remote_protocols="default") + +if test x$with_remote_protocols != xno; then + if test "x$default_remote_protocols" = "xdefault"; then + if test "$uname" = "Darwin" -a $uversion -ge 90; then + CUPS_BROWSE_REMOTE_PROTOCOLS="" + else + CUPS_BROWSE_REMOTE_PROTOCOLS="CUPS" + fi + else + CUPS_BROWSE_REMOTE_PROTOCOLS="$default_remote_protocols" + fi +else + CUPS_BROWSE_REMOTE_PROTOCOLS="" +fi + +AC_SUBST(CUPS_BROWSE_REMOTE_PROTOCOLS) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS, + "$CUPS_BROWSE_REMOTE_PROTOCOLS") + +dnl Default BrowseShortNames +AC_ARG_ENABLE(browse_short, [ --disable-browse-short-names + disable BrowseShortNames by default]) +if test "x$enable_browse_short" = xno; then + CUPS_BROWSE_SHORT_NAMES="No" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSE_SHORT_NAMES, 0) +else + CUPS_BROWSE_SHORT_NAMES="Yes" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_BROWSE_SHORT_NAMES, 1) +fi +AC_SUBST(CUPS_BROWSE_SHORT_NAMES) + +dnl Default DefaultShared +AC_ARG_ENABLE(default_shared, [ --disable-default-shared + disable DefaultShared by default]) +if test "x$enable_default_shared" = xno; then + CUPS_DEFAULT_SHARED="No" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_DEFAULT_SHARED, 0) +else + CUPS_DEFAULT_SHARED="Yes" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_DEFAULT_SHARED, 1) +fi +AC_SUBST(CUPS_DEFAULT_SHARED) + +dnl Default ImplicitClasses +AC_ARG_ENABLE(implicit, [ --disable-implicit-classes + disable ImplicitClasses by default]) +if test "x$enable_implicit" = xno; then + CUPS_IMPLICIT_CLASSES="No" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IMPLICIT_CLASSES, 0) +else + CUPS_IMPLICIT_CLASSES="Yes" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IMPLICIT_CLASSES, 1) +fi +AC_SUBST(CUPS_IMPLICIT_CLASSES) + +dnl Default UseNetworkDefault +AC_ARG_ENABLE(use_network_default, [ --enable-use-network-default + set UseNetworkDefault to Yes by default]) +if test "x$enable_use_network_default" != xno; then + AC_MSG_CHECKING(whether to use network default printers) + if test "x$enable_use_network_default" = xyes -o $uname != Darwin; then + CUPS_USE_NETWORK_DEFAULT="Yes" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USE_NETWORK_DEFAULT, 1) + AC_MSG_RESULT(yes) + else + CUPS_USE_NETWORK_DEFAULT="No" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USE_NETWORK_DEFAULT, 0) + AC_MSG_RESULT(no) + fi +else + CUPS_USE_NETWORK_DEFAULT="No" + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USE_NETWORK_DEFAULT, 0) +fi +AC_SUBST(CUPS_USE_NETWORK_DEFAULT) + +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 x$uname = xDarwin; then + if test x`id -u _lp 2>/dev/null` = x; then + CUPS_USER="lp"; + else + CUPS_USER="_lp"; + fi + AC_MSG_RESULT($CUPS_USER) + elif 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="nobody" + AC_MSG_RESULT(not found, using "$CUPS_USER") + fi + else + CUPS_USER="nobody" + AC_MSG_RESULT(no password file, using "$CUPS_USER") + fi) + +if test "x$CUPS_USER" = "xroot" -o "x$CUPS_USER" = "x0"; then + AC_MSG_ERROR([The default user for CUPS cannot be root!]) +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 + if test x`id -g _lp 2>/dev/null` = x; then + CUPS_GROUP="lp"; + else + CUPS_GROUP="_lp"; + fi + AC_MSG_RESULT($CUPS_GROUP) + elif test -f /etc/group; then + GROUP_LIST="_lp lp nobody" + CUPS_GROUP="" + for group in $GROUP_LIST; 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="nobody" + AC_MSG_RESULT(not found, using "$CUPS_GROUP") + fi + else + CUPS_GROUP="nobody" + AC_MSG_RESULT(no group file, using "$CUPS_GROUP") + fi) + +if test "x$CUPS_GROUP" = "xroot" -o "x$CUPS_GROUP" = "xwheel" -o "x$CUPS_GROUP" = "x0"; then + AC_MSG_ERROR([The default group for CUPS cannot be root!]) +fi + +AC_ARG_WITH(system_groups, [ --with-system-groups set default system groups for CUPS], + CUPS_SYSTEM_GROUPS="$withval", + if test x$uname = xDarwin; then + CUPS_SYSTEM_GROUPS="admin" + else + AC_MSG_CHECKING(for default system groups) + if test -f /etc/group; then + CUPS_SYSTEM_GROUPS="" + GROUP_LIST="lpadmin sys system root" + for group in $GROUP_LIST; do + if test "`grep \^${group}: /etc/group`" != ""; then + if test "x$CUPS_SYSTEM_GROUPS" = x; then + CUPS_SYSTEM_GROUPS="$group" + else + CUPS_SYSTEM_GROUPS="$CUPS_SYSTEM_GROUPS $group" + fi + fi + done + + if test "x$CUPS_SYSTEM_GROUPS" = x; then + CUPS_SYSTEM_GROUPS="$GROUP_LIST" + AC_MSG_RESULT(no groups found, using "$CUPS_SYSTEM_GROUPS") + else + AC_MSG_RESULT("$CUPS_SYSTEM_GROUPS") + fi + else + CUPS_SYSTEM_GROUPS="$GROUP_LIST" + AC_MSG_RESULT(no group file, using "$CUPS_SYSTEM_GROUPS") + fi + fi) + +CUPS_PRIMARY_SYSTEM_GROUP="`echo $CUPS_SYSTEM_GROUPS | awk '{print $1}'`" + +for group in $CUPS_SYSTEM_GROUPS; do + if test "x$CUPS_GROUP" = "x$group"; then + AC_MSG_ERROR([The default system groups cannot contain the default CUPS group!]) + fi +done + +AC_SUBST(CUPS_USER) +AC_SUBST(CUPS_GROUP) +AC_SUBST(CUPS_SYSTEM_GROUPS) +AC_SUBST(CUPS_PRIMARY_SYSTEM_GROUP) + +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_USER, "$CUPS_USER") +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GROUP, "$CUPS_GROUP") +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_SYSTEM_GROUPS, "$CUPS_SYSTEM_GROUPS") + +dnl Default printcap file... +AC_ARG_WITH(printcap, [ --with-printcap set default printcap file], + default_printcap="$withval", + default_printcap="default") + +if test x$default_printcap != xno; then + if test "x$default_printcap" = "xdefault"; then + case $uname in + Darwin*) + if test $uversion -ge 90; then + CUPS_DEFAULT_PRINTCAP="/Library/Preferences/org.cups.printers.plist" + else + CUPS_DEFAULT_PRINTCAP="/etc/printcap" + fi + ;; + SunOS*) + CUPS_DEFAULT_PRINTCAP="/etc/printers.conf" + ;; + *) + CUPS_DEFAULT_PRINTCAP="/etc/printcap" + ;; + esac + else + CUPS_DEFAULT_PRINTCAP="$default_printcap" + fi +else + CUPS_DEFAULT_PRINTCAP="" +fi + +AC_SUBST(CUPS_DEFAULT_PRINTCAP) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_PRINTCAP, "$CUPS_DEFAULT_PRINTCAP") + +dnl Default LPD config file... +AC_ARG_WITH(lpdconfigfile, [ --with-lpdconfigfile set default LPDConfigFile URI], + default_lpdconfigfile="$withval", + default_lpdconfigfile="default") + +if test x$default_lpdconfigfile != xno; then + if test "x$default_lpdconfigfile" = "xdefault"; then + case $uname in + Darwin*) + CUPS_DEFAULT_LPD_CONFIG_FILE="launchd:///System/Library/LaunchDaemons/org.cups.cups-lpd.plist" + ;; + *) + if test "x$XINETD" != x; then + CUPS_DEFAULT_LPD_CONFIG_FILE="xinetd://$XINETD/cups-lpd" + else + CUPS_DEFAULT_LPD_CONFIG_FILE="" + fi + ;; + esac + else + CUPS_DEFAULT_LPD_CONFIG_FILE="$default_lpdconfigfile" + fi +else + CUPS_DEFAULT_LPD_CONFIG_FILE="" +fi + +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_LPD_CONFIG_FILE, "$CUPS_DEFAULT_LPD_CONFIG_FILE") + +dnl Default SMB config file... +AC_ARG_WITH(smbconfigfile, [ --with-smbconfigfile set default SMBConfigFile URI], + default_smbconfigfile="$withval", + default_smbconfigfile="default") + +if test x$default_smbconfigfile != xno; then + if test "x$default_smbconfigfile" = "xdefault"; then + if test -f /etc/smb.conf; then + CUPS_DEFAULT_SMB_CONFIG_FILE="samba:///etc/smb.conf" + else + CUPS_DEFAULT_SMB_CONFIG_FILE="" + fi + else + CUPS_DEFAULT_SMB_CONFIG_FILE="$default_smbconfigfile" + fi +else + CUPS_DEFAULT_SMB_CONFIG_FILE="" +fi + +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_SMB_CONFIG_FILE, "$CUPS_DEFAULT_SMB_CONFIG_FILE") + +dnl Default MaxCopies value... +AC_ARG_WITH(max-copies, [ --with-max-copies set default max copies value, default=9999 ], + CUPS_MAX_COPIES="$withval", + CUPS_MAX_COPIES="9999") + +AC_SUBST(CUPS_MAX_COPIES) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_MAX_COPIES, $CUPS_MAX_COPIES) + +dnl Default raw printing state +AC_ARG_ENABLE(raw_printing, [ --disable-raw-printing do not allow raw printing by default]) +if test "x$enable_raw_printing" != xno; then + DEFAULT_RAW_PRINTING="" +else + DEFAULT_RAW_PRINTING="#" +fi +AC_SUBST(DEFAULT_RAW_PRINTING) + +dnl Default SNMP options... +AC_ARG_WITH(snmp-address, [ --with-snmp-address set SNMP query address, default=auto ], + if test "x$withval" = x; then + CUPS_SNMP_ADDRESS="" + else + CUPS_SNMP_ADDRESS="Address $withval" + fi, + if test "x$uname" = xDarwin; then + CUPS_SNMP_ADDRESS="" + else + CUPS_SNMP_ADDRESS="Address @LOCAL" + fi) + +AC_ARG_WITH(snmp-community, [ --with-snmp-community set SNMP community, default=public ], + CUPS_SNMP_COMMUNITY="Community $withval", + CUPS_SNMP_COMMUNITY="Community public") + +AC_SUBST(CUPS_SNMP_ADDRESS) +AC_SUBST(CUPS_SNMP_COMMUNITY) + +dnl New default port definition for IPP... +AC_ARG_WITH(ipp-port, [ --with-ipp-port set port number for IPP, default=631 ], + DEFAULT_IPP_PORT="$withval", + DEFAULT_IPP_PORT="631") + +AC_SUBST(DEFAULT_IPP_PORT) +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_IPP_PORT,$DEFAULT_IPP_PORT) + +dnl Filters +AC_ARG_ENABLE(bannertops, [ --enable-bannertops always build the banner filter ]) +AC_ARG_ENABLE(texttops, [ --enable-texttops always build the text filter ]) + +if test "x$enable_bannertops" = xno; then + BANNERTOPS="" +elif test "x$enable_bannertops" = xyes; then + BANNERTOPS="bannertops" +elif test $uname = Darwin; then + BANNERTOPS="" +else + BANNERTOPS="bannertops" +fi + +if test "x$enable_texttops" = xno; then + TEXTTOPS="" +elif test "x$enable_texttops" = xyes; then + TEXTTOPS="texttops" +elif test $uname = Darwin; then + TEXTTOPS="" +else + TEXTTOPS="texttops" +fi + +AC_SUBST(BANNERTOPS) +AC_SUBST(TEXTTOPS) + +dnl +dnl End of "$Id: cups-defaults.m4 8929 2009-12-15 22:40:37Z mike $". +dnl diff --git a/config-scripts/cups-directories.m4 b/config-scripts/cups-directories.m4 new file mode 100644 index 0000000000..66d3fa16c7 --- /dev/null +++ b/config-scripts/cups-directories.m4 @@ -0,0 +1,429 @@ +dnl +dnl "$Id: cups-directories.m4 8497 2009-04-12 23:04:51Z mike $" +dnl +dnl Directory stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007 by Apple Inc. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_PREFIX_DEFAULT(/) + +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 "bindir" variable... +if test "$bindir" = "\${exec_prefix}/bin"; then + bindir="$exec_prefix/bin" +fi + +AC_DEFINE_UNQUOTED(CUPS_BINDIR, "$bindir") + +dnl Fix "sbindir" variable... +if test "$sbindir" = "\${exec_prefix}/sbin"; then + sbindir="$exec_prefix/sbin" +fi + +AC_DEFINE_UNQUOTED(CUPS_SBINDIR, "$sbindir") + +dnl Fix "sharedstatedir" variable if it hasn't been specified... +if test "$sharedstatedir" = "\${prefix}/com" -a "$prefix" = "/"; then + sharedstatedir="/usr/com" +fi + +dnl Fix "datarootdir" variable if it hasn't been specified... +if test "$datarootdir" = "\${prefix}/share"; then + if test "$prefix" = "/"; then + datarootdir="/usr/share" + else + datarootdir="$prefix/share" + fi +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 +elif test "$datadir" = "\${datarootdir}"; then + datadir="$datarootdir" +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 + if test "$uname" = Darwin; then + localstatedir="/private/var" + else + localstatedir="/var" + fi + 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 + if test "$uname" = Darwin; then + sysconfdir="/private/etc" + else + sysconfdir="/etc" + fi + else + sysconfdir="$prefix/etc" + fi +fi + +dnl Fix "libdir" variable... +if test "$libdir" = "\${exec_prefix}/lib"; then + case "$uname" in + IRIX*) + libdir="$exec_prefix/lib32" + ;; + Linux*) + if test -d /usr/lib64; then + libdir="$exec_prefix/lib64" + fi + ;; + HP-UX*) + if test -d /usr/lib/hpux32; then + libdir="$exec_prefix/lib/hpux32" + fi + ;; + esac +fi + +dnl Setup init.d locations... +AC_ARG_WITH(rcdir, [ --with-rcdir set path for rc scripts],rcdir="$withval",rcdir="") +AC_ARG_WITH(rclevels, [ --with-rclevels set run levels for rc scripts],rclevels="$withval",rclevels="2 3 5") +AC_ARG_WITH(rcstart, [ --with-rcstart set start number for rc scripts],rcstart="$withval",rcstart="99") +AC_ARG_WITH(rcstop, [ --with-rcstop set stop number for rc scripts],rcstop="$withval",rcstop="00") +AC_ARG_WITH(smfmanifestdir, [ --with-smfmanifestdir set path for Solaris SMF manifest],smfmanifestdir="$withval",smfmanifestdir="") + +INITDIR="" +INITDDIR="" +RCLEVELS="$rclevels" +RCSTART="$rcstart" +RCSTOP="$rcstop" +SMFMANIFESTDIR="" + +if test x$rcdir = x; then + case "$uname" in + AIX*) + INITDIR="/etc/rc.d" + ;; + + Darwin*) + # Darwin and MacOS X... + if test -x /sbin/launchd; then + INITDDIR="/System/Library/LaunchDaemons" + else + INITDDIR="/System/Library/StartupItems/PrintingServices" + fi + ;; + + FreeBSD* | OpenBSD* | MirBSD* | ekkoBSD*) + # FreeBSD and OpenBSD + ;; + + HP-UX*) + INITDIR="/sbin" + RCLEVELS="2" + RCSTART="380" + RCSTOP="620" + ;; + + IRIX*) + # IRIX + INITDIR="/etc" + RCSTART="60" + RCSTOP="25" + ;; + + Linux | GNU | GNU/k*BSD*) + # Linux/HURD seems to choose an init.d directory at random... + if test -d /sbin/init.d; then + # SuSE + INITDIR="/sbin/init.d" + else + if test -d /etc/init.d; then + # Others + INITDIR="/etc" + else + # RedHat + INITDIR="/etc/rc.d" + fi + fi + RCSTART="81" + RCSTOP="36" + ;; + + NetBSD*) + # NetBSD + INITDDIR="/etc/rc.d" + ;; + + OSF1*) + INITDIR="/sbin" + ;; + + SunOS*) + # Solaris + if test "x$smfmanifestdir" != x; then + SMFMANIFESTDIR=$smfmanifestdir + else + INITDIR="/etc" + RCSTART="81" + fi + ;; + + *) + INITDIR="/etc" + ;; + + esac +elif test "x$rcdir" != xno; then + if test "x$rclevels" = x; then + INITDDIR="$rcdir" + else + INITDIR="$rcdir" + fi +fi + +AC_SUBST(INITDIR) +AC_SUBST(INITDDIR) +AC_SUBST(RCLEVELS) +AC_SUBST(RCSTART) +AC_SUBST(RCSTOP) +AC_SUBST(SMFMANIFESTDIR) + +dnl Xinetd support... +AC_ARG_WITH(xinetd, [ --with-xinetd set path for xinetd config files],XINETD="$withval",XINETD="") + +if test "x$XINETD" = x -a ! -x /sbin/launchd; then + for dir in /private/etc/xinetd.d /etc/xinetd.d /usr/local/etc/xinetd.d; do + if test -d $dir; then + XINETD="$dir" + break + fi + done +elif test "x$XINETD" = xno; then + XINETD="" +fi + +AC_SUBST(XINETD) + +dnl LPD sharing support... +AC_ARG_WITH(lpdconfig, [ --with-lpdconfig set URI for LPD config file], + LPDCONFIG="$withval", LPDCONFIG="") + +if test "x$LPDCONFIG" = x; then + if test -f /System/Library/LaunchDaemons/org.cups.cups-lpd.plist; then + LPDCONFIG="launchd:///System/Library/LaunchDaemons/org.cups.cups-lpd.plist" + elif test "x$XINETD" != x; then + LPDCONFIG="xinetd://$XINETD/cups-lpd" + fi +fi + +if test "x$LPDCONFIG" = xoff; then + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_LPD_CONFIG, "") +else + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_LPD_CONFIG, "$LPDCONFIG") +fi + +dnl SMB sharing support... +AC_ARG_WITH(smbconfig, [ --with-smbconfig set URI for Samba config file], + SMBCONFIG="$withval", SMBCONFIG="") + +if test "x$SMBCONFIG" = x; then + if test -f /System/Library/LaunchDaemons/smbd.plist; then + SMBCONFIG="launchd:///System/Library/LaunchDaemons/smbd.plist" + else + for dir in /etc /etc/samba /usr/local/etc; do + if test -f $dir/smb.conf; then + SMBCONFIG="samba://$dir/smb.conf" + break + fi + done + fi +fi + +if test "x$SMBCONFIG" = xoff; then + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_SMB_CONFIG, "") +else + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_SMB_CONFIG, "$SMBCONFIG") +fi + +dnl Setup default locations... +# Cache data... +AC_ARG_WITH(cachedir, [ --with-cachedir set path for cache files],cachedir="$withval",cachedir="") + +if test x$cachedir = x; then + if test "x$uname" = xDarwin; then + CUPS_CACHEDIR="$localstatedir/spool/cups/cache" + else + CUPS_CACHEDIR="$localstatedir/cache/cups" + fi +else + CUPS_CACHEDIR="$cachedir" +fi +AC_DEFINE_UNQUOTED(CUPS_CACHEDIR, "$CUPS_CACHEDIR") +AC_SUBST(CUPS_CACHEDIR) + +# Data files +CUPS_DATADIR="$datadir/cups" +AC_DEFINE_UNQUOTED(CUPS_DATADIR, "$datadir/cups") +AC_SUBST(CUPS_DATADIR) + +# Icon directory +AC_ARG_WITH(icondir, [ --with-icondir set path for application icons],icondir="$withval",icondir="") + +if test "x$icondir" = x -a -d /usr/share/icons; then + ICONDIR="/usr/share/icons" +else + ICONDIR="$icondir" +fi + +AC_SUBST(ICONDIR) + +# Menu directory +AC_ARG_WITH(menudir, [ --with-menudir set path for application menus],menudir="$withval",menudir="") + +if test "x$menudir" = x -a -d /usr/share/applications; then + MENUDIR="/usr/share/applications" +else + MENUDIR="$menudir" +fi + +AC_SUBST(MENUDIR) + +# Documentation files +AC_ARG_WITH(docdir, [ --with-docdir set path for documentation],docdir="$withval",docdir="") + +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) + +# Fonts +AC_ARG_WITH(fontpath, [ --with-fontpath set font path for pstoraster],fontpath="$withval",fontpath="") + +if test "x$fontpath" = "x"; then + CUPS_FONTPATH="$datadir/cups/fonts" +else + CUPS_FONTPATH="$fontpath" +fi + +AC_SUBST(CUPS_FONTPATH) +AC_DEFINE_UNQUOTED(CUPS_FONTPATH, "$CUPS_FONTPATH") + +# Locale data +if test "$localedir" = "\${datarootdir}/locale"; then + case "$uname" in + Linux | GNU | *BSD* | Darwin*) + CUPS_LOCALEDIR="$datarootdir/locale" + ;; + + OSF1* | AIX*) + CUPS_LOCALEDIR="$exec_prefix/lib/nls/msg" + ;; + + *) + # This is the standard System V location... + CUPS_LOCALEDIR="$exec_prefix/lib/locale" + ;; + esac +else + CUPS_LOCALEDIR="$localedir" +fi + +AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$CUPS_LOCALEDIR") +AC_SUBST(CUPS_LOCALEDIR) + +# Log files... +AC_ARG_WITH(logdir, [ --with-logdir set path for log files],logdir="$withval",logdir="") + +if test x$logdir = x; then + CUPS_LOGDIR="$localstatedir/log/cups" + AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$localstatedir/log/cups") +else + CUPS_LOGDIR="$logdir" +fi +AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$CUPS_LOGDIR") +AC_SUBST(CUPS_LOGDIR) + +# Longer-term spool data +CUPS_REQUESTS="$localstatedir/spool/cups" +AC_DEFINE_UNQUOTED(CUPS_REQUESTS, "$localstatedir/spool/cups") +AC_SUBST(CUPS_REQUESTS) + +# Server executables... +case "$uname" in + *BSD* | Darwin*) + # *BSD and Darwin (MacOS X) + INSTALL_SYSV="" + CUPS_SERVERBIN="$exec_prefix/libexec/cups" + ;; + *) + # All others + INSTALL_SYSV="install-sysv" + CUPS_SERVERBIN="$exec_prefix/lib/cups" + ;; +esac + +AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$CUPS_SERVERBIN") +AC_SUBST(CUPS_SERVERBIN) +AC_SUBST(INSTALL_SYSV) + +# Configuration files +CUPS_SERVERROOT="$sysconfdir/cups" +AC_DEFINE_UNQUOTED(CUPS_SERVERROOT, "$sysconfdir/cups") +AC_SUBST(CUPS_SERVERROOT) + +# Transient run-time state +case "$uname" in + Darwin*) + # Darwin (Mac OS X) + CUPS_STATEDIR="$CUPS_SERVERROOT" + ;; + *) + # All others + CUPS_STATEDIR="$localstatedir/run/cups" + ;; +esac +AC_DEFINE_UNQUOTED(CUPS_STATEDIR, "$CUPS_STATEDIR") +AC_SUBST(CUPS_STATEDIR) + +dnl +dnl End of "$Id: cups-directories.m4 8497 2009-04-12 23:04:51Z mike $". +dnl diff --git a/config-scripts/cups-dnssd.m4 b/config-scripts/cups-dnssd.m4 new file mode 100644 index 0000000000..4d858ee0d1 --- /dev/null +++ b/config-scripts/cups-dnssd.m4 @@ -0,0 +1,68 @@ +dnl +dnl "$Id: cups-dnssd.m4 8789 2009-08-28 22:54:34Z mike $" +dnl +dnl DNS Service Discovery (aka Bonjour) stuff for the Common UNIX Printing System (CUPS). +dnl +dnl http://www.dns-sd.org +dnl http://www.multicastdns.org/ +dnl http://developer.apple.com/networking/bonjour/ +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(dnssd, [ --disable-dnssd disable DNS Service Discovery support]) +AC_ARG_WITH(dnssd-libs, [ --with-dnssd-libs set directory for DNS Service Discovery library], + LDFLAGS="-L$withval $LDFLAGS" + DSOFLAGS="-L$withval $DSOFLAGS",) +AC_ARG_WITH(dnssd-includes, [ --with-dnssd-includes set directory for DNS Service Discovery includes], + CFLAGS="-I$withval $CFLAGS" + CPPFLAGS="-I$withval $CPPFLAGS",) + +DNSSDLIBS="" +DNSSD_BACKEND="" + +if test x$enable_dnssd != xno; then + AC_CHECK_HEADER(dns_sd.h, [ + case "$uname" in + Darwin*) + # Darwin and MacOS X... + AC_DEFINE(HAVE_DNSSD) + AC_DEFINE(HAVE_COREFOUNDATION) + AC_DEFINE(HAVE_SYSTEMCONFIGURATION) + DNSSDLIBS="-framework CoreFoundation -framework SystemConfiguration" + DNSSD_BACKEND="dnssd" + ;; + *) + # All others... + AC_MSG_CHECKING(for current version of dns_sd library) + SAVELIBS="$LIBS" + LIBS="$LIBS -ldns_sd" + AC_TRY_COMPILE([#include ], + [int constant = kDNSServiceFlagsShareConnection; + unsigned char txtRecord[100]; + uint8_t valueLen; + TXTRecordGetValuePtr(sizeof(txtRecord), + txtRecord, "value", &valueLen);], + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DNSSD) + DNSSDLIBS="-ldns_sd" + DNSSD_BACKEND="dnssd", + AC_MSG_RESULT(no)) + LIBS="$SAVELIBS" + ;; + esac + ]) +fi + +AC_SUBST(DNSSDLIBS) +AC_SUBST(DNSSD_BACKEND) + +dnl +dnl End of "$Id: cups-dnssd.m4 8789 2009-08-28 22:54:34Z mike $". +dnl diff --git a/config-scripts/cups-gssapi.m4 b/config-scripts/cups-gssapi.m4 new file mode 100644 index 0000000000..7aa1876ff5 --- /dev/null +++ b/config-scripts/cups-gssapi.m4 @@ -0,0 +1,124 @@ +dnl +dnl "$Id: cups-gssapi.m4 8659 2009-05-18 22:03:04Z mike $" +dnl +dnl GSSAPI/Kerberos library detection. +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 2006-2007 by Easy Software Products. +dnl +dnl This file contains Kerberos support code, copyright 2006 by +dnl Jelmer Vernooij. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(gssapi, [ --disable-gssapi disable GSSAPI support]) + +LIBGSSAPI="" +AC_SUBST(LIBGSSAPI) + +if test x$enable_gssapi != xno; then + AC_PATH_PROG(KRB5CONFIG, krb5-config) + if test "x$KRB5CONFIG" != x; then + case "$uname" in + Darwin) + # Mac OS X weak-links to the Kerberos framework... + LIBGSSAPI="-weak_framework Kerberos" + ;; + SunOS*) + # Solaris has a non-standard krb5-config, don't use it! + AC_CHECK_LIB(gss, gss_display_status, + AC_DEFINE(HAVE_GSSAPI, 1, [Whether GSSAPI is available]) + CFLAGS="`$KRB5CONFIG --cflags` $CFLAGS" + CPPFLAGS="`$KRB5CONFIG --cflags` $CPPFLAGS" + LIBGSSAPI="-lgss `$KRB5CONFIG --libs`") + ;; + *) + # Other platforms just ask for GSSAPI + CFLAGS="`$KRB5CONFIG --cflags gssapi` $CFLAGS" + CPPFLAGS="`$KRB5CONFIG --cflags gssapi` $CPPFLAGS" + LIBGSSAPI="`$KRB5CONFIG --libs gssapi`" + ;; + esac + AC_DEFINE(HAVE_GSSAPI, 1, [Whether GSSAPI is available]) + else + # Check for vendor-specific implementations... + case "$uname" in + HP-UX*) + AC_CHECK_LIB(gss, gss_display_status, + AC_DEFINE(HAVE_GSSAPI, 1, [Whether GSSAPI is available]) + LIBGSSAPI="-lgss -lgssapi_krb5") + ;; + SunOS*) + AC_CHECK_LIB(gss, gss_display_status, + AC_DEFINE(HAVE_GSSAPI, 1, [Whether GSSAPI is available]) + LIBGSSAPI="-lgss") + ;; + esac + fi + + if test "x$LIBGSSAPI" != x; then + AC_CHECK_HEADER(krb5.h, AC_DEFINE(HAVE_KRB5_H)) + AC_CHECK_HEADER(gssapi.h, AC_DEFINE(HAVE_GSSAPI_H)) + AC_CHECK_HEADER(gssapi/gssapi.h, AC_DEFINE(HAVE_GSSAPI_GSSAPI_H)) + AC_CHECK_HEADER(gssapi/gssapi_generic.h, AC_DEFINE(HAVE_GSSAPI_GSSAPI_GENERIC_H)) + AC_CHECK_HEADER(gssapi/gssapi_krb5.h, AC_DEFINE(HAVE_GSSAPI_GSSAPI_KRB5_H)) + + SAVELIBS="$LIBS" + LIBS="$LIBS $LIBGSSAPI" + + AC_CHECK_FUNC(gsskrb5_register_acceptor_identity, + AC_DEFINE(HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY)) + AC_CHECK_FUNC(krb5_cc_new_unique, AC_DEFINE(HAVE_KRB5_CC_NEW_UNIQUE)) + AC_CHECK_FUNC(krb5_ipc_client_set_target_uid, AC_DEFINE(HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID)) + + AC_MSG_CHECKING(for GSS_C_NT_HOSTBASED_SERVICE) + if test $ac_cv_header_gssapi_gssapi_h = yes; then + AC_TRY_COMPILE([ #include ], + [ gss_OID foo = GSS_C_NT_HOSTBASED_SERVICE; ], + AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + else + AC_TRY_COMPILE([ #include ], + [ gss_OID foo = GSS_C_NT_HOSTBASED_SERVICE; ], + AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + fi + + LIBS="$SAVELIBS" + + AC_MSG_CHECKING(for Heimdal Kerberos) + AC_TRY_COMPILE([ #include ], + [ char *tmp = heimdal_version; ], + AC_DEFINE(HAVE_HEIMDAL) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + fi +fi + +dnl Default GSS service name... +AC_ARG_WITH(gssservicename, [ --with-gssservicename set default gss service name], + default_gssservicename="$withval", + default_gssservicename="default") + +if test x$default_gssservicename != xno; then + if test "x$default_gssservicename" = "xdefault"; then + CUPS_DEFAULT_GSSSERVICENAME="host" + else + CUPS_DEFAULT_GSSSERVICENAME="$default_gssservicename" + fi +else + CUPS_DEFAULT_GSSSERVICENAME="" +fi + +AC_DEFINE_UNQUOTED(CUPS_DEFAULT_GSSSERVICENAME, "$CUPS_DEFAULT_GSSSERVICENAME") + +dnl +dnl End of "$Id: cups-gssapi.m4 8659 2009-05-18 22:03:04Z mike $". +dnl diff --git a/config-scripts/cups-image.m4 b/config-scripts/cups-image.m4 new file mode 100644 index 0000000000..0b59a1aa3a --- /dev/null +++ b/config-scripts/cups-image.m4 @@ -0,0 +1,109 @@ +dnl +dnl "$Id: cups-image.m4 8344 2009-02-10 17:05:35Z mike $" +dnl +dnl Image library/filter stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl See if we want the image filters included at all... +AC_ARG_ENABLE(image, [ --enable-image always build the image filters]) + +IMGFILTERS="" +if test "x$enable_image" != xno; then + AC_MSG_CHECKING(whether to build image filters) + if test "x$enable_image" = xyes -o $uname != Darwin; then + IMGFILTERS="imagetops imagetoraster" + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi +fi + +AC_SUBST(IMGFILTERS) + +dnl Check for image libraries... +AC_ARG_ENABLE(jpeg, [ --disable-jpeg disable JPEG support]) +AC_ARG_ENABLE(png, [ --disable-png disable PNG support]) +AC_ARG_ENABLE(tiff, [ --disable-tiff disable TIFF support]) + +LIBJPEG="" +LIBPNG="" +LIBTIFF="" +LIBZ="" + +AC_SUBST(LIBJPEG) +AC_SUBST(LIBPNG) +AC_SUBST(LIBTIFF) +AC_SUBST(LIBZ) + +dnl Image libraries use math library functions... +AC_SEARCH_LIBS(pow, m) + +dnl Save the current libraries since we don't want the image libraries +dnl included with every program... +SAVELIBS="$LIBS" + +dnl JPEG library... +if test x$enable_jpeg != xno; then + AC_CHECK_HEADER(jpeglib.h, + AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, + AC_DEFINE(HAVE_LIBJPEG) + LIBJPEG="-ljpeg" + LIBS="$LIBS -ljpeg")) +else + AC_MSG_NOTICE([JPEG support disabled with --disable-jpeg.]) +fi + +dnl ZLIB library... +AC_CHECK_HEADER(zlib.h, + AC_CHECK_LIB(z, gzgets, + AC_DEFINE(HAVE_LIBZ) + LIBZ="-lz" + LIBS="$LIBS -lz")) + +dnl PNG library... +if test x$enable_png != xno; then + AC_CHECK_HEADER(png.h, + AC_CHECK_LIB(png, png_create_read_struct, + AC_DEFINE(HAVE_LIBPNG) + LIBPNG="-lpng")) +else + AC_MSG_NOTICE([PNG support disabled with --disable-png.]) +fi + +dnl TIFF library... +if test x$enable_tiff != xno; then + AC_CHECK_HEADER(tiff.h, + AC_CHECK_LIB(tiff, TIFFReadScanline, + AC_DEFINE(HAVE_LIBTIFF) + LIBTIFF="-ltiff")) +else + AC_MSG_NOTICE([TIFF support disabled with --disable-tiff.]) +fi + +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 8344 2009-02-10 17:05:35Z mike $". +dnl diff --git a/config-scripts/cups-largefile.m4 b/config-scripts/cups-largefile.m4 new file mode 100644 index 0000000000..dbfcb499cb --- /dev/null +++ b/config-scripts/cups-largefile.m4 @@ -0,0 +1,52 @@ +dnl +dnl "$Id: cups-largefile.m4 6649 2007-07-11 21:46:42Z mike $" +dnl +dnl Large file support stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Check for largefile support... +AC_SYS_LARGEFILE + +dnl Define largefile options as needed... +LARGEFILE="" +if test x$enable_largefile != xno; then + LARGEFILE="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" + + if test x$ac_cv_sys_large_files = x1; then + LARGEFILE="$LARGEFILE -D_LARGE_FILES" + fi + + if test x$ac_cv_sys_file_offset_bits = x64; then + LARGEFILE="$LARGEFILE -D_FILE_OFFSET_BITS=64" + fi +fi +AC_SUBST(LARGEFILE) + +dnl Check for "long long" support... +AC_CACHE_CHECK(for long long int, ac_cv_c_long_long, + [if test "$GCC" = yes; then + ac_cv_c_long_long=yes + else + AC_TRY_COMPILE(,[long long int i;], + ac_cv_c_long_long=yes, + ac_cv_c_long_long=no) + fi]) + +if test $ac_cv_c_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG) +fi + +AC_CHECK_FUNC(strtoll, AC_DEFINE(HAVE_STRTOLL)) + +dnl +dnl End of "$Id: cups-largefile.m4 6649 2007-07-11 21:46:42Z mike $". +dnl diff --git a/config-scripts/cups-launchd.m4 b/config-scripts/cups-launchd.m4 new file mode 100644 index 0000000000..df15524869 --- /dev/null +++ b/config-scripts/cups-launchd.m4 @@ -0,0 +1,43 @@ +dnl +dnl "$Id: cups-launchd.m4 9120 2010-04-23 18:56:34Z mike $" +dnl +dnl launchd stuff for CUPS. +dnl +dnl Copyright 2007-2010 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + + +AC_ARG_ENABLE(launchd, [ --disable-launchd disable launchd support]) + +DEFAULT_LAUNCHD_CONF="" +LAUNCHDLIBS="" + +if test x$enable_launchd != xno; then + AC_CHECK_FUNC(launch_msg, AC_DEFINE(HAVE_LAUNCHD)) + AC_CHECK_HEADER(launch.h, AC_DEFINE(HAVE_LAUNCH_H)) + + case "$uname" in + Darwin*) + # Darwin, MacOS X + DEFAULT_LAUNCHD_CONF="/System/Library/LaunchDaemons/org.cups.cupsd.plist" + # liblaunch is already part of libSystem + ;; + *) + # All others; this test will need to be updated + ;; + esac +fi + +AC_SUBST(DEFAULT_LAUNCHD_CONF) +AC_SUBST(LAUNCHDLIBS) + +dnl +dnl End of "$Id: cups-launchd.m4 9120 2010-04-23 18:56:34Z mike $". +dnl diff --git a/config-scripts/cups-ldap.m4 b/config-scripts/cups-ldap.m4 new file mode 100644 index 0000000000..587ca2dc70 --- /dev/null +++ b/config-scripts/cups-ldap.m4 @@ -0,0 +1,52 @@ +dnl +dnl "$Id: cups-ldap.m4 8344 2009-02-10 17:05:35Z mike $" +dnl +dnl LDAP configuration stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 2003-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(ldap, [ --disable-ldap disable LDAP support]) +AC_ARG_WITH(ldap-libs, [ --with-ldap-libs set directory for LDAP library], + LDFLAGS="-L$withval $LDFLAGS" + DSOFLAGS="-L$withval $DSOFLAGS",) +AC_ARG_WITH(ldap-includes, [ --with-ldap-includes set directory for LDAP includes], + CFLAGS="-I$withval $CFLAGS" + CPPFLAGS="-I$withval $CPPFLAGS",) + +LIBLDAP="" + +if test x$enable_ldap != xno; then + AC_CHECK_HEADER(ldap.h, [ + AC_CHECK_LIB(ldap, ldap_initialize, + AC_DEFINE(HAVE_LDAP) + AC_DEFINE(HAVE_OPENLDAP) + LIBLDAP="-lldap" + AC_CHECK_LIB(ldap, ldap_start_tls, + AC_DEFINE(HAVE_LDAP_SSL)), + + AC_CHECK_LIB(ldap, ldap_init, + AC_DEFINE(HAVE_LDAP) + AC_DEFINE(HAVE_MOZILLA_LDAP) + LIBLDAP="-lldap" + AC_CHECK_HEADER(ldap_ssl.h, AC_DEFINE(HAVE_LDAP_SSL_H),,[#include ]) + AC_CHECK_LIB(ldap, ldapssl_init, + AC_DEFINE(HAVE_LDAP_SSL))) + ) + AC_CHECK_LIB(ldap, ldap_set_rebind_proc, AC_DEFINE(HAVE_LDAP_REBIND_PROC)) + ]) +fi + +AC_SUBST(LIBLDAP) + + +dnl +dnl End of "$Id: cups-ldap.m4 8344 2009-02-10 17:05:35Z mike $". +dnl diff --git a/config-scripts/cups-libtool.m4 b/config-scripts/cups-libtool.m4 new file mode 100644 index 0000000000..cbd8069725 --- /dev/null +++ b/config-scripts/cups-libtool.m4 @@ -0,0 +1,39 @@ +dnl +dnl "$Id: cups-libtool.m4 8344 2009-02-10 17:05:35Z mike $" +dnl +dnl Libtool stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(libtool_unsupported, [ --enable-libtool-unsupported + build with libtool (UNSUPPORTED!)], + [if test x$enable_libtool_unsupported != xno; then + LIBTOOL="$enable_libtool_unsupported" + enable_shared=no + echo "WARNING: libtool is not supported or endorsed by Apple Inc." + echo " WE DO NOT PROVIDE SUPPORT FOR LIBTOOL PROBLEMS." + 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 8344 2009-02-10 17:05:35Z mike $". +dnl diff --git a/config-scripts/cups-manpages.m4 b/config-scripts/cups-manpages.m4 new file mode 100644 index 0000000000..3fdc5363e1 --- /dev/null +++ b/config-scripts/cups-manpages.m4 @@ -0,0 +1,96 @@ +dnl +dnl "$Id: cups-manpages.m4 8230 2009-01-12 19:17:09Z mike $" +dnl +dnl Manpage stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007 by Apple Inc. +dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Fix "mandir" variable... +if test "$mandir" = "\${datarootdir}/man" -a "$prefix" = "/"; then + # New GNU "standards" break previous ones, so make sure we use + # the right default location for the operating system... + mandir="\${prefix}/man" +fi + +if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/"; then + case "$uname" in + Darwin* | Linux | GNU | *BSD* | AIX*) + # Darwin, MacOS X, Linux, GNU HURD, *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 + IRIX*) + # SGI IRIX + MAN1EXT=1 + MAN5EXT=5 + MAN7EXT=7 + MAN8EXT=1m + MAN8DIR=1 + ;; + SunOS* | HP-UX*) + # Solaris and HP-UX + MAN1EXT=1 + MAN5EXT=5 + MAN7EXT=7 + MAN8EXT=1m + MAN8DIR=1m + ;; + Linux* | GNU* | Darwin*) + # Linux, GNU Hurd, and Mac OS X + MAN1EXT=1.gz + MAN5EXT=5.gz + MAN7EXT=7.gz + MAN8EXT=8.gz + MAN8DIR=8 + ;; + *) + # All others + MAN1EXT=1 + MAN5EXT=5 + MAN7EXT=7 + MAN8EXT=8 + MAN8DIR=8 + ;; +esac + +AC_SUBST(MAN1EXT) +AC_SUBST(MAN5EXT) +AC_SUBST(MAN7EXT) +AC_SUBST(MAN8EXT) +AC_SUBST(MAN8DIR) + +dnl +dnl End of "$Id: cups-manpages.m4 8230 2009-01-12 19:17:09Z mike $". +dnl diff --git a/config-scripts/cups-network.m4 b/config-scripts/cups-network.m4 new file mode 100644 index 0000000000..bf673025ea --- /dev/null +++ b/config-scripts/cups-network.m4 @@ -0,0 +1,74 @@ +dnl +dnl "$Id: cups-network.m4 7918 2008-09-08 22:03:01Z mike $" +dnl +dnl Networking stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2008 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_CHECK_HEADER(resolv.h,AC_DEFINE(HAVE_RESOLV_H)) +AC_SEARCH_LIBS(socket, socket) +AC_SEARCH_LIBS(gethostbyaddr, nsl) +AC_SEARCH_LIBS(getifaddrs, nsl, AC_DEFINE(HAVE_GETIFADDRS)) +AC_SEARCH_LIBS(hstrerror, nsl socket resolv, AC_DEFINE(HAVE_HSTRERROR)) +AC_SEARCH_LIBS(rresvport_af, nsl, AC_DEFINE(HAVE_RRESVPORT_AF)) +AC_SEARCH_LIBS(__res_init, resolv bind, AC_DEFINE(HAVE_RES_INIT), + AC_SEARCH_LIBS(res_9_init, resolv bind, AC_DEFINE(HAVE_RES_INIT), + AC_SEARCH_LIBS(res_init, resolv bind, AC_DEFINE(HAVE_RES_INIT)))) + +# Tru64 5.1b leaks file descriptors with these functions; disable until +# we can come up with a test for this... +if test "$uname" != "OSF1"; then + AC_SEARCH_LIBS(getaddrinfo, nsl, AC_DEFINE(HAVE_GETADDRINFO)) + AC_SEARCH_LIBS(getnameinfo, nsl, AC_DEFINE(HAVE_GETNAMEINFO)) +fi + +AC_CHECK_MEMBER(struct sockaddr.sa_len,,, [#include ]) +AC_CHECK_HEADER(sys/sockio.h, AC_DEFINE(HAVE_SYS_SOCKIO_H)) + +CUPS_DEFAULT_DOMAINSOCKET="" + +dnl Domain socket support... +AC_ARG_WITH(domainsocket, [ --with-domainsocket set unix domain socket name], + default_domainsocket="$withval", + default_domainsocket="") + +if test x$enable_domainsocket != xno -a x$default_domainsocket != xno; then + if test "x$default_domainsocket" = x; then + case "$uname" in + Darwin*) + # Darwin and MaxOS X do their own thing... + CUPS_DEFAULT_DOMAINSOCKET="$localstatedir/run/cupsd" + ;; + *) + # All others use FHS standard... + CUPS_DEFAULT_DOMAINSOCKET="$CUPS_STATEDIR/cups.sock" + ;; + esac + else + CUPS_DEFAULT_DOMAINSOCKET="$default_domainsocket" + fi + + CUPS_LISTEN_DOMAINSOCKET="Listen $CUPS_DEFAULT_DOMAINSOCKET" + + AC_DEFINE_UNQUOTED(CUPS_DEFAULT_DOMAINSOCKET, "$CUPS_DEFAULT_DOMAINSOCKET") +else + CUPS_LISTEN_DOMAINSOCKET="" +fi + +AC_SUBST(CUPS_DEFAULT_DOMAINSOCKET) +AC_SUBST(CUPS_LISTEN_DOMAINSOCKET) + +AC_CHECK_HEADERS(AppleTalk/at_proto.h,AC_DEFINE(HAVE_APPLETALK_AT_PROTO_H),, + [#include ]) + +dnl +dnl End of "$Id: cups-network.m4 7918 2008-09-08 22:03:01Z mike $". +dnl diff --git a/config-scripts/cups-opsys.m4 b/config-scripts/cups-opsys.m4 new file mode 100644 index 0000000000..ae81eb481c --- /dev/null +++ b/config-scripts/cups-opsys.m4 @@ -0,0 +1,35 @@ +dnl +dnl "$Id: cups-opsys.m4 6649 2007-07-11 21:46:42Z mike $" +dnl +dnl Operating system stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007 by Apple Inc. +dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Get the operating system, version number, and architecture... +uname=`uname` +uversion=`uname -r | sed -e '1,$s/^[[^0-9]]*\([[0-9]]*\)\.\([[0-9]]*\).*/\1\2/'` +uarch=`uname -m` + +case "$uname" in + GNU* | GNU/*) + uname="GNU" + ;; + IRIX*) + uname="IRIX" + ;; + Linux*) + uname="Linux" + ;; +esac + +dnl +dnl "$Id: cups-opsys.m4 6649 2007-07-11 21:46:42Z mike $" +dnl diff --git a/config-scripts/cups-pam.m4 b/config-scripts/cups-pam.m4 new file mode 100644 index 0000000000..3fd301317b --- /dev/null +++ b/config-scripts/cups-pam.m4 @@ -0,0 +1,102 @@ +dnl +dnl "$Id: cups-pam.m4 8825 2009-09-22 21:53:31Z mike $" +dnl +dnl PAM stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(pam, [ --disable-pam disable PAM support]) +AC_ARG_WITH(pam_module, [ --with-pam-module specify the PAM module to use]) + +dnl Don't use PAM with AIX... +if test $uname = AIX; then + enable_pam=no +fi + +PAMDIR="" +PAMFILE="pam.std" +PAMLIBS="" +PAMMOD="pam_unknown.so" +PAMMODAUTH="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_LIB(pam,pam_set_item,AC_DEFINE(HAVE_PAM_SET_ITEM)) + AC_CHECK_LIB(pam,pam_setcred,AC_DEFINE(HAVE_PAM_SETCRED)) + AC_CHECK_HEADER(security/pam_appl.h) + if test x$ac_cv_header_security_pam_appl_h != xyes; then + AC_CHECK_HEADER(pam/pam_appl.h, + AC_DEFINE(HAVE_PAM_PAM_APPL_H)) + fi + + if test x$ac_cv_lib_pam_pam_start != xno; then + # Set the necessary libraries for PAM... + if test x$ac_cv_lib_dl_dlopen != xno; then + PAMLIBS="-lpam -ldl" + else + PAMLIBS="-lpam" + fi + + # Find the PAM configuration directory, if any... + for dir in /private/etc/pam.d /etc/pam.d; do + if test -d $dir; then + PAMDIR=$dir + break; + fi + done + fi + + LIBS="$SAVELIBS" + + case "$uname" in + Darwin*) + # Darwin/Mac OS X + if test "x$with_pam_module" != x; then + PAMFILE="pam.$with_pam_module" + elif test -f /usr/lib/pam/pam_opendirectory.so.2; then + PAMFILE="pam.opendirectory" + else + PAMFILE="pam.securityserver" + fi + ;; + + *) + # All others; this test might need to be updated + # as Linux distributors move things around... + if test "x$with_pam_module" != x; then + PAMMOD="pam_${with_pam_module}.so" + elif test -f /lib/security/pam_unix2.so; then + PAMMOD="pam_unix2.so" + elif test -f /lib/security/pam_unix.so; then + PAMMOD="pam_unix.so" + fi + + if test "x$PAMMOD" = xpam_unix.so; then + PAMMODAUTH="$PAMMOD shadow nodelay" + else + PAMMODAUTH="$PAMMOD nodelay" + fi + ;; + esac +fi + +AC_SUBST(PAMDIR) +AC_SUBST(PAMFILE) +AC_SUBST(PAMLIBS) +AC_SUBST(PAMMOD) +AC_SUBST(PAMMODAUTH) + +dnl +dnl End of "$Id: cups-pam.m4 8825 2009-09-22 21:53:31Z mike $". +dnl diff --git a/config-scripts/cups-pap.m4 b/config-scripts/cups-pap.m4 new file mode 100644 index 0000000000..7e42cd7f5d --- /dev/null +++ b/config-scripts/cups-pap.m4 @@ -0,0 +1,31 @@ +dnl +dnl "$Id: cups-pap.m4 8524 2009-04-19 21:18:45Z mike $" +dnl +dnl PAP (AppleTalk) stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +# Currently the PAP backend is only supported on MacOS X with the AppleTalk +# SDK installed... +AC_ARG_ENABLE(pap, [ --enable-pap build with AppleTalk support]) + +PAP="" +AC_SUBST(PAP) + +if test x$enable_pap = xyes -a $uname = Darwin; then + AC_CHECK_HEADER(netat/appletalk.h,[ + PAP="pap" + AC_CHECK_HEADER(AppleTalk/at_proto.h)]) +fi + +dnl +dnl End of "$Id: cups-pap.m4 8524 2009-04-19 21:18:45Z mike $". +dnl diff --git a/config-scripts/cups-pdf.m4 b/config-scripts/cups-pdf.m4 new file mode 100644 index 0000000000..b3801f5a22 --- /dev/null +++ b/config-scripts/cups-pdf.m4 @@ -0,0 +1,88 @@ +dnl +dnl "$Id: cups-pdf.m4 8760 2009-08-07 22:30:30Z mike $" +dnl +dnl PDF filter configuration stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_WITH(pdftops, [ --with-pdftops set pdftops filter (gs,/path/to/gs,pdftops,/path/to/pdftops,none), default=pdftops ]) + +PDFTOPS="" +CUPS_PDFTOPS="" +CUPS_GHOSTSCRIPT="" + +case "x$with_pdftops" in + x) # Default/auto + if test $uname != Darwin; then + AC_PATH_PROG(CUPS_PDFTOPS, pdftops) + if test "x$CUPS_PDFTOPS" != x; then + AC_DEFINE(HAVE_PDFTOPS) + PDFTOPS="pdftops" + else + AC_PATH_PROG(CUPS_GHOSTSCRIPT, gs) + if test "x$CUPS_GHOSTSCRIPT" != x; then + AC_DEFINE(HAVE_GHOSTSCRIPT) + PDFTOPS="pdftops" + fi + fi + fi + ;; + + xgs) + AC_PATH_PROG(CUPS_GHOSTSCRIPT, gs) + if test "x$CUPS_GHOSTSCRIPT" != x; then + AC_DEFINE(HAVE_GHOSTSCRIPT) + PDFTOPS="pdftops" + else + AC_MSG_ERROR(Unable to find gs program!) + exit 1 + fi + ;; + + x/*/gs) # Use /path/to/gs without any check: + CUPS_GHOSTSCRIPT="$with_pdftops" + AC_DEFINE(HAVE_GHOSTSCRIPT) + PDFTOPS="pdftops" + ;; + + xpdftops) + AC_PATH_PROG(CUPS_PDFTOPS, pdftops) + if test "x$CUPS_PDFTOPS" != x; then + AC_DEFINE(HAVE_PDFTOPS) + PDFTOPS="pdftops" + else + AC_MSG_ERROR(Unable to find pdftops program!) + exit 1 + fi + ;; + + x/*/pdftops) # Use /path/to/pdftops without any check: + CUPS_PDFTOPS="$with_pdftops" + AC_DEFINE(HAVE_PDFTOPS) + PDFTOPS="pdftops" + ;; + + xnone) # Make no pdftops filter if with_pdftops=none: + ;; + + *) # Invalid with_pdftops value: + AC_MSG_ERROR(Invalid with_pdftops value!) + exit 1 + ;; +esac + +AC_DEFINE_UNQUOTED(CUPS_PDFTOPS, "$CUPS_PDFTOPS") +AC_DEFINE_UNQUOTED(CUPS_GHOSTSCRIPT, "$CUPS_GHOSTSCRIPT") +AC_SUBST(PDFTOPS) + +dnl +dnl End of "$Id: cups-pdf.m4 8760 2009-08-07 22:30:30Z mike $". +dnl diff --git a/config-scripts/cups-poll.m4 b/config-scripts/cups-poll.m4 new file mode 100644 index 0000000000..bb5155ac58 --- /dev/null +++ b/config-scripts/cups-poll.m4 @@ -0,0 +1,22 @@ +dnl +dnl "$Id: cups-poll.m4 8524 2009-04-19 21:18:45Z mike $" +dnl +dnl Select/poll stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007 by Apple Inc. +dnl Copyright 2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_CHECK_FUNC(poll, AC_DEFINE(HAVE_POLL)) +AC_CHECK_FUNC(epoll_create, AC_DEFINE(HAVE_EPOLL)) +AC_CHECK_FUNC(kqueue, AC_DEFINE(HAVE_KQUEUE)) + +dnl +dnl End of "$Id: cups-poll.m4 8524 2009-04-19 21:18:45Z mike $". +dnl diff --git a/config-scripts/cups-scripting.m4 b/config-scripts/cups-scripting.m4 new file mode 100644 index 0000000000..a8960070ec --- /dev/null +++ b/config-scripts/cups-scripting.m4 @@ -0,0 +1,100 @@ +dnl +dnl "$Id: cups-scripting.m4 7915 2008-09-07 22:18:29Z mike $" +dnl +dnl Scripting configuration stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2008 by Apple Inc. +dnl Copyright 1997-2006 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +dnl Do we have Java? +AC_ARG_WITH(java, [ --with-java set Java interpreter for web interfaces ], + CUPS_JAVA="$withval", + CUPS_JAVA="") + +if test "x$CUPS_JAVA" = x; then + AC_PATH_PROG(JAVA,java) + CUPS_JAVA="$JAVA" +fi + +AC_DEFINE_UNQUOTED(CUPS_JAVA, "$CUPS_JAVA") + +if test "x$CUPS_JAVA" != x; then + AC_DEFINE(HAVE_JAVA) +fi + +dnl Do we have Perl? +AC_ARG_WITH(perl, [ --with-perl set Perl interpreter for web interfaces ], + CUPS_PERL="$withval", + CUPS_PERL="") + +if test "x$CUPS_PERL" = x; then + AC_PATH_PROG(PERL,perl) + CUPS_PERL="$PERL" +fi + +AC_DEFINE_UNQUOTED(CUPS_PERL, "$CUPS_PERL") + +if test "x$CUPS_PERL" != x; then + AC_DEFINE(HAVE_PERL) +fi + +dnl Do we have PHP? +AC_ARG_WITH(php, [ --with-php set PHP interpreter for web interfaces ], + CUPS_PHP="$withval", + CUPS_PHP="") + +if test "x$CUPS_PHP" = x; then + AC_PATH_PROG(PHPCGI,php-cgi) + if test "x$PHPCGI" = x; then + AC_PATH_PROG(PHP,php) + CUPS_PHP="$PHP" + else + CUPS_PHP="$PHPCGI" + fi +fi + +AC_DEFINE_UNQUOTED(CUPS_PHP, "$CUPS_PHP") + +if test "x$CUPS_PHP" = x; then + CUPS_PHP="no" +else + AC_DEFINE(HAVE_PHP) +fi + +PHPDIR="" +if test "x$CUPS_PHP" != xno; then + AC_PATH_PROG(PHPCONFIG, php-config) + + if test "x$PHPCONFIG" != x; then + PHPDIR="scripting/php" + fi +fi + +AC_SUBST(PHPDIR) + +dnl Do we have Python? +AC_ARG_WITH(python, [ --with-python set Python interpreter for web interfaces ], + CUPS_PYTHON="$withval", + CUPS_PYTHON="") + +if test "x$CUPS_PYTHON" = x; then + AC_PATH_PROG(PYTHON,python) + CUPS_PYTHON="$PYTHON" +fi + +AC_DEFINE_UNQUOTED(CUPS_PYTHON, "$CUPS_PYTHON") + +if test "x$CUPS_PYTHON" != x; then + AC_DEFINE(HAVE_PYTHON) +fi + +dnl +dnl End of "$Id: cups-scripting.m4 7915 2008-09-07 22:18:29Z mike $". +dnl diff --git a/config-scripts/cups-sharedlibs.m4 b/config-scripts/cups-sharedlibs.m4 new file mode 100644 index 0000000000..fa5885e08c --- /dev/null +++ b/config-scripts/cups-sharedlibs.m4 @@ -0,0 +1,263 @@ +dnl +dnl "$Id: cups-sharedlibs.m4 9154 2010-06-16 00:49:01Z mike $" +dnl +dnl Shared library support for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +PICFLAG=1 +DSOFLAGS="${DSOFLAGS:=}" + +AC_ARG_ENABLE(shared, [ --disable-shared do not create shared libraries]) + +if test x$enable_shared != xno; then + case "$uname" in + SunOS*) + LIBCUPS="libcups.so.2" + LIBCUPSCGI="libcupscgi.so.1" + LIBCUPSDRIVER="libcupsdriver.so.1" + LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPSMIME="libcupsmime.so.1" + LIBCUPSPPDC="libcupsppdc.so.1" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -Wl,-h\`basename \$@\` -G \$(OPTIM)" + ;; + UNIX_S*) + LIBCUPS="libcups.so.2" + LIBCUPSCGI="libcupscgi.so.1" + LIBCUPSDRIVER="libcupsdriver.so.1" + LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPSMIME="libcupsmime.so.1" + LIBCUPSPPDC="libcupsppdc.so.1" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G \$(OPTIM)" + ;; + HP-UX*) + case "$uarch" in + ia64) + LIBCUPS="libcups.so.2" + LIBCUPSCGI="libcupscgi.so.1" + LIBCUPSDRIVER="libcupsdriver.so.1" + LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPSMIME="libcupsmime.so.1" + LIBCUPSPPDC="libcupsppdc.so.1" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -Wl,-b,-z,+h,\`basename \$@\`" + ;; + *) + LIBCUPS="libcups.sl.2" + LIBCUPSCGI="libcupscgi.sl.1" + LIBCUPSDRIVER="libcupsdriver.sl.1" + LIBCUPSIMAGE="libcupsimage.sl.2" + LIBCUPSMIME="libcupsmime.sl.1" + LIBCUPSPPDC="libcupsppdc.sl.1" + DSO="\$(LD)" + DSOXX="\$(LD)" + DSOFLAGS="$DSOFLAGS -b -z +h \`basename \$@\`" + ;; + esac + ;; + IRIX) + LIBCUPS="libcups.so.2" + LIBCUPSCGI="libcupscgi.so.1" + LIBCUPSDRIVER="libcupsdriver.so.1" + LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPSMIME="libcupsmime.so.1" + LIBCUPSPPDC="libcupsppdc.so.1" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -set_version,sgi2.6,-soname,\`basename \$@\` -shared \$(OPTIM)" + ;; + OSF1* | Linux | GNU | *BSD*) + LIBCUPS="libcups.so.2" + LIBCUPSCGI="libcupscgi.so.1" + LIBCUPSDRIVER="libcupsdriver.so.1" + LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPSMIME="libcupsmime.so.1" + LIBCUPSPPDC="libcupsppdc.so.1" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared \$(OPTIM)" + ;; + Darwin*) + LIBCUPS="libcups.2.dylib" + LIBCUPSCGI="libcupscgi.1.dylib" + LIBCUPSDRIVER="libcupsdriver.1.dylib" + LIBCUPSIMAGE="libcupsimage.2.dylib" + LIBCUPSMIME="libcupsmime.1.dylib" + LIBCUPSPPDC="libcupsppdc.1.dylib" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -dynamiclib -single_module -lc" + ;; + AIX*) + LIBCUPS="libcups_s.a" + LIBCUPSCGI="libcupscgi_s.a" + LIBCUPSDRIVER="libcupsdriver_s.a" + LIBCUPSIMAGE="libcupsimage_s.a" + LIBCUPSMIME="libcupsmime_s.a" + LIBCUPSPPDC="libcupsppdc_s.a" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -Wl,-bexpall,-bM:SRE,-bnoentry,-blibpath:\$(libdir)" + ;; + *) + echo "Warning: shared libraries may not be supported. Trying -shared" + echo " option with compiler." + LIBCUPS="libcups.so.2" + LIBCUPSCGI="libcupscgi.so.1" + LIBCUPSDRIVER="libcupsdriver.so.1" + LIBCUPSIMAGE="libcupsimage.so.2" + LIBCUPSMIME="libcupsmime.so.1" + LIBCUPSPPDC="libcupsppdc.so.1" + DSO="\$(CC)" + DSOXX="\$(CXX)" + DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared \$(OPTIM)" + ;; + esac +else + PICFLAG=0 + LIBCUPS="libcups.a" + LIBCUPSCGI="libcupscgi.a" + LIBCUPSDRIVER="libcupsdriver.a" + LIBCUPSIMAGE="libcupsimage.a" + LIBCUPSMIME="libcupsmime.a" + LIBCUPSPPDC="libcupsppdc.a" + DSO=":" + DSOXX=":" +fi + +# 32-bit and 64-bit libraries need variations of the standard +# DSOFLAGS... +DSO32FLAGS="$DSOFLAGS" +DSO64FLAGS="$DSOFLAGS" + +AC_SUBST(DSO) +AC_SUBST(DSOXX) +AC_SUBST(DSOFLAGS) +AC_SUBST(DSO32FLAGS) +AC_SUBST(DSO64FLAGS) +AC_SUBST(LIBCUPS) +AC_SUBST(LIBCUPSCGI) +AC_SUBST(LIBCUPSDRIVER) +AC_SUBST(LIBCUPSIMAGE) +AC_SUBST(LIBCUPSMIME) +AC_SUBST(LIBCUPSPPDC) + +if test x$enable_shared = xno; then + LINKCUPS="../cups/libcups.a" + LINKCUPSIMAGE="../filter/libcupsimage.a" + + EXTLINKCUPS="-lcups" + EXTLINKCUPSDRIVER="-lcupsdriver" + EXTLINKCUPSIMAGE="-lcupsimage" +else + if test $uname = AIX; then + LINKCUPS="-lcups_s" + LINKCUPSIMAGE="-lcupsimage_s" + + EXTLINKCUPS="-lcups_s" + EXTLINKCUPSDRIVER="-lcupsdriver_s" + EXTLINKCUPSIMAGE="-lcupsimage_s" + else + LINKCUPS="-lcups" + LINKCUPSIMAGE="-lcupsimage" + + EXTLINKCUPS="-lcups" + EXTLINKCUPSDRIVER="-lcupsdriver" + EXTLINKCUPSIMAGE="-lcupsimage" + fi +fi + +AC_SUBST(EXTLINKCUPS) +AC_SUBST(EXTLINKCUPSDRIVER) +AC_SUBST(EXTLINKCUPSIMAGE) +AC_SUBST(LINKCUPS) +AC_SUBST(LINKCUPSIMAGE) + +dnl Update libraries for DSOs... +EXPORT_LDFLAGS="" + +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="\$(LIBTIFF) \$(LIBPNG) \$(LIBJPEG) \$(LIBZ)" + IMGLIBS="" + + # Tell the run-time linkers where to find a DSO. Some platforms + # need this option, even when the library is installed in a + # standard location... + case $uname in + HP-UX*) + # HP-UX needs the path, even for /usr/lib... + case "$uarch" in + ia64) + DSOFLAGS="-Wl,+s,+b,$libdir $DSOFLAGS" + DSO32FLAGS="-Wl,+s,+b,$LIB32DIR $DSO32FLAGS" + DSO64FLAGS="-Wl,+s,+b,$LIB64DIR $DSO64FLAGS" + ;; + *) + DSOFLAGS="+s +b $libdir $DSOFLAGS" + DSO32FLAGS="+s +b $LIB32DIR $DSO32FLAGS" + DSO64FLAGS="+s +b $LIB64DIR $DSO64FLAGS" + ;; + esac + LDFLAGS="$LDFLAGS -Wl,+s,+b,$libdir" + EXPORT_LDFLAGS="-Wl,+s,+b,$libdir" + ;; + SunOS*) + # Solaris... + if test $exec_prefix != /usr; then + DSOFLAGS="-R$libdir $DSOFLAGS" + DSO32FLAGS="-R$LIB32DIR $DSO32FLAGS" + DSO64FLAGS="-R$LIB64DIR $DSO64FLAGS" + LDFLAGS="$LDFLAGS -R$libdir" + EXPORT_LDFLAGS="-R$libdir" + fi + ;; + *BSD*) + # *BSD... + if test $exec_prefix != /usr; then + DSOFLAGS="-Wl,-R$libdir $DSOFLAGS" + DSO32FLAGS="-Wl,-R$LIB32DIR $DSO32FLAGS" + DSO64FLAGS="-Wl,-R$LIB64DIR $DSO64FLAGS" + LDFLAGS="$LDFLAGS -Wl,-R$libdir" + EXPORT_LDFLAGS="-Wl,-R$libdir" + fi + ;; + IRIX | Linux | GNU) + # IRIX, Linux, and HURD... + if test $exec_prefix != /usr; then + DSOFLAGS="-Wl,-rpath,$libdir $DSOFLAGS" + DSO32FLAGS="-Wl,-rpath,$LIB32DIR $DSO32FLAGS" + DSO64FLAGS="-Wl,-rpath,$LIB64DIR $DSO64FLAGS" + LDFLAGS="$LDFLAGS -Wl,-rpath,$libdir" + EXPORT_LDFLAGS="-Wl,-rpath,$libdir" + fi + ;; + esac +else + DSOLIBS="" + IMGLIBS="\$(LIBTIFF) \$(LIBPNG) \$(LIBJPEG) \$(LIBZ)" +fi + +AC_SUBST(DSOLIBS) +AC_SUBST(IMGLIBS) +AC_SUBST(EXPORT_LDFLAGS) + +dnl +dnl End of "$Id: cups-sharedlibs.m4 9154 2010-06-16 00:49:01Z mike $". +dnl diff --git a/config-scripts/cups-slp.m4 b/config-scripts/cups-slp.m4 new file mode 100644 index 0000000000..fac42bd522 --- /dev/null +++ b/config-scripts/cups-slp.m4 @@ -0,0 +1,38 @@ +dnl +dnl "$Id: cups-slp.m4 8344 2009-02-10 17:05:35Z mike $" +dnl +dnl OpenSLP configuration stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(slp, [ --disable-slp disable SLP support]) +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" + 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-slp.m4 8344 2009-02-10 17:05:35Z mike $". +dnl diff --git a/config-scripts/cups-ssl.m4 b/config-scripts/cups-ssl.m4 new file mode 100644 index 0000000000..c689f9dfcc --- /dev/null +++ b/config-scripts/cups-ssl.m4 @@ -0,0 +1,162 @@ +dnl +dnl "$Id: cups-ssl.m4 9470 2011-01-11 07:05:58Z mike $" +dnl +dnl OpenSSL/GNUTLS stuff for CUPS. +dnl +dnl Copyright 2007-2011 by Apple Inc. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(ssl, [ --disable-ssl disable SSL/TLS support]) +AC_ARG_ENABLE(cdsassl, [ --enable-cdsassl use CDSA for SSL/TLS support, default=first]) +AC_ARG_ENABLE(gnutls, [ --enable-gnutls use GNU TLS for SSL/TLS support, default=second]) +AC_ARG_ENABLE(openssl, [ --enable-openssl use OpenSSL for SSL/TLS support, default=third]) +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" + CPPFLAGS="-I$withval $CPPFLAGS",) + +SSLFLAGS="" +SSLLIBS="" +have_ssl=0 + +if test x$enable_ssl != xno; then + dnl Look for CDSA... + if test $have_ssl = 0 -a "x$enable_cdsassl" != "xno"; then + if test $uname = Darwin; then + AC_CHECK_HEADER(Security/SecureTransport.h, [ + have_ssl=1 + AC_DEFINE(HAVE_SSL) + AC_DEFINE(HAVE_CDSASSL) + + dnl Check for the various security headers... + AC_CHECK_HEADER(Security/SecItem.h, + AC_DEFINE(HAVE_SECITEM_H)) + AC_CHECK_HEADER(Security/SecItemPriv.h, + AC_DEFINE(HAVE_SECITEMPRIV_H)) + AC_CHECK_HEADER(Security/SecPolicy.h, + AC_DEFINE(HAVE_SECPOLICY_H)) + AC_CHECK_HEADER(Security/SecPolicyPriv.h, + AC_DEFINE(HAVE_SECPOLICYPRIV_H)) + AC_CHECK_HEADER(Security/SecBasePriv.h, + AC_DEFINE(HAVE_SECBASEPRIV_H)) + AC_CHECK_HEADER(Security/SecIdentitySearchPriv.h, + AC_DEFINE(HAVE_SECIDENTITYSEARCHPRIV_H)) + + dnl Check for SecIdentitySearchCreateWithPolicy... + AC_MSG_CHECKING(for SecIdentitySearchCreateWithPolicy) + if test $uversion -ge 80; then + AC_DEFINE(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + + dnl Check for SecPolicyCreateSSL... + AC_MSG_CHECKING(for SecPolicyCreateSSL) + if test $uversion -ge 110; then + AC_DEFINE(HAVE_SECPOLICYCREATESSL) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi]) + fi + fi + + dnl Then look for GNU TLS... + if test $have_ssl = 0 -a "x$enable_gnutls" != "xno" -a "x$PKGCONFIG" != x; then + AC_PATH_PROG(LIBGNUTLSCONFIG,libgnutls-config) + AC_PATH_PROG(LIBGCRYPTCONFIG,libgcrypt-config) + if $PKGCONFIG --exists gnutls; then + if test "x$have_pthread" = xyes; then + AC_MSG_WARN([The current version of GNU TLS cannot be made thread-safe.]) + else + have_ssl=1 + SSLLIBS=`$PKGCONFIG --libs gnutls` + SSLFLAGS=`$PKGCONFIG --cflags gnutls` + AC_DEFINE(HAVE_SSL) + AC_DEFINE(HAVE_GNUTLS) + fi + elif test "x$LIBGNUTLSCONFIG" != x; then + if test "x$have_pthread" = xyes; then + AC_MSG_WARN([The current version of GNU TLS cannot be made thread-safe.]) + else + have_ssl=1 + SSLLIBS=`$LIBGNUTLSCONFIG --libs` + SSLFLAGS=`$LIBGNUTLSCONFIG --cflags` + AC_DEFINE(HAVE_SSL) + AC_DEFINE(HAVE_GNUTLS) + fi + fi + + if test $have_ssl = 1; then + if $PKGCONFIG --exists gcrypt; then + SSLLIBS="$SSLLIBS `$PKGCONFIG --libs gcrypt`" + SSLFLAGS="$SSLFLAGS `$PKGCONFIG --cflags gcrypt`" + elif test "x$LIBGCRYPTCONFIG" != x; then + SSLLIBS="$SSLLIBS `$LIBGCRYPTCONFIG --libs`" + SSLFLAGS="$SSLFLAGS `$LIBGCRYPTCONFIG --cflags`" + fi + fi + fi + + dnl Check for the OpenSSL library last... + if test $have_ssl = 0 -a "x$enable_openssl" != "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, + [have_ssl=1 + SSLFLAGS="-DOPENSSL_DISABLE_OLD_DES_SUPPORT" + SSLLIBS="-lssl $libcrypto" + AC_DEFINE(HAVE_SSL) + AC_DEFINE(HAVE_LIBSSL)],, + $libcrypto) + + if test "x${SSLLIBS}" != "x"; then + break + fi + done + + LIBS="$SAVELIBS") + fi +fi + +if test $have_ssl = 1; then + AC_MSG_RESULT([ Using SSLLIBS="$SSLLIBS"]) + AC_MSG_RESULT([ Using SSLFLAGS="$SSLFLAGS"]) +elif test x$enable_cdsa = xyes -o x$enable_gnutls = xyes -o x$enable_openssl = xyes; then + AC_MSG_ERROR([Unable to enable SSL support.]) +fi + +AC_SUBST(SSLFLAGS) +AC_SUBST(SSLLIBS) + +EXPORT_SSLLIBS="$SSLLIBS" +AC_SUBST(EXPORT_SSLLIBS) + + +dnl +dnl End of "$Id: cups-ssl.m4 9470 2011-01-11 07:05:58Z mike $". +dnl diff --git a/config-scripts/cups-threads.m4 b/config-scripts/cups-threads.m4 new file mode 100644 index 0000000000..08e5777fc4 --- /dev/null +++ b/config-scripts/cups-threads.m4 @@ -0,0 +1,54 @@ +dnl +dnl "$Id: cups-threads.m4 8344 2009-02-10 17:05:35Z mike $" +dnl +dnl Threading stuff for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007-2009 by Apple Inc. +dnl Copyright 1997-2005 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "http://www.cups.org/". +dnl + +AC_ARG_ENABLE(threads, [ --disable-threads disable multi-threading support]) + +have_pthread=no +PTHREAD_FLAGS="" + +if test "x$enable_threads" != xno; then + AC_CHECK_HEADER(pthread.h, AC_DEFINE(HAVE_PTHREAD_H)) + + if test x$ac_cv_header_pthread_h = xyes; then + dnl Check various threading options for the platforms we support + for flag in -lpthreads -lpthread -pthread; do + AC_MSG_CHECKING([for pthread_create using $flag]) + SAVELIBS="$LIBS" + LIBS="$flag $LIBS" + AC_TRY_LINK([#include ], + [pthread_create(0, 0, 0, 0);], + have_pthread=yes, + LIBS="$SAVELIBS") + AC_MSG_RESULT([$have_pthread]) + + if test $have_pthread = yes; then + PTHREAD_FLAGS="-D_THREAD_SAFE -D_REENTRANT" + + # Solaris requires -D_POSIX_PTHREAD_SEMANTICS to + # be POSIX-compliant... :( + if test $uname = SunOS; then + PTHREAD_FLAGS="$PTHREAD_FLAGS -D_POSIX_PTHREAD_SEMANTICS" + fi + break + fi + done + fi +fi + +AC_SUBST(PTHREAD_FLAGS) + +dnl +dnl End of "$Id: cups-threads.m4 8344 2009-02-10 17:05:35Z mike $". +dnl diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000000..a45e28229a --- /dev/null +++ b/config.h.in @@ -0,0 +1,674 @@ +/* + * "$Id$" + * + * Configuration file for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_CONFIG_H_ +#define _CUPS_CONFIG_H_ + +/* + * Version of software... + */ + +#define CUPS_SVERSION "" +#define CUPS_MINIMAL "" + + +/* + * Default user and groups... + */ + +#define CUPS_DEFAULT_USER "lp" +#define CUPS_DEFAULT_GROUP "sys" +#define CUPS_DEFAULT_SYSTEM_GROUPS "sys root system" +#define CUPS_DEFAULT_PRINTOPERATOR_AUTH "@SYSTEM" + + +/* + * Default file permissions... + */ + +#define CUPS_DEFAULT_CONFIG_FILE_PERM 0640 +#define CUPS_DEFAULT_LOG_FILE_PERM 0644 + + +/* + * Default logging settings... + */ + +#define CUPS_DEFAULT_LOG_LEVEL "warn" +#define CUPS_DEFAULT_ACCESS_LOG_LEVEL "actions" + + +/* + * Default fatal error settings... + */ + +#define CUPS_DEFAULT_FATAL_ERRORS "config" + + +/* + * Default browsing settings... + */ + +#define CUPS_DEFAULT_BROWSING 1 +#define CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS "CUPS" +#define CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS "CUPS" +#define CUPS_DEFAULT_BROWSE_SHORT_NAMES 1 +#define CUPS_DEFAULT_DEFAULT_SHARED 1 +#define CUPS_DEFAULT_IMPLICIT_CLASSES 1 +#define CUPS_DEFAULT_USE_NETWORK_DEFAULT 1 + + +/* + * Default IPP port... + */ + +#define CUPS_DEFAULT_IPP_PORT 631 + + +/* + * Default printcap file... + */ + +#define CUPS_DEFAULT_PRINTCAP "/etc/printcap" + + +/* + * Default Samba and LPD config files... + */ + +#define CUPS_DEFAULT_SMB_CONFIG_FILE "" +#define CUPS_DEFAULT_LPD_CONFIG_FILE "" + + +/* + * Default MaxCopies value... + */ + +#define CUPS_DEFAULT_MAX_COPIES 100 + + +/* + * Do we have domain socket support? + */ + +#undef CUPS_DEFAULT_DOMAINSOCKET + + +/* + * Where are files stored? + * + * Note: These are defaults, which can be overridden by environment + * variables at run-time... + */ + +#define CUPS_BINDIR "/usr/bin" +#define CUPS_CACHEDIR "/var/cache/cups" +#define CUPS_DATADIR "/usr/share/cups" +#define CUPS_DOCROOT "/usr/share/doc/cups" +#define CUPS_FONTPATH "/usr/share/cups/fonts" +#define CUPS_LOCALEDIR "/usr/share/locale" +#define CUPS_LOGDIR "/var/logs/cups" +#define CUPS_REQUESTS "/var/spool/cups" +#define CUPS_SBINDIR "/usr/sbin" +#define CUPS_SERVERBIN "/usr/lib/cups" +#define CUPS_SERVERROOT "/etc/cups" +#define CUPS_STATEDIR "/var/run/cups" + + +/* + * Do we have various image libraries? + */ + +#undef HAVE_LIBPNG +#undef HAVE_LIBZ +#undef HAVE_LIBJPEG +#undef HAVE_LIBTIFF + + +/* + * Do we have PAM stuff? + */ + +#ifndef HAVE_LIBPAM +#define HAVE_LIBPAM 0 +#endif /* !HAVE_LIBPAM */ + +#undef HAVE_PAM_PAM_APPL_H +#undef HAVE_PAM_SET_ITEM +#undef HAVE_PAM_SETCRED + + +/* + * Do we have ? + */ + +#undef HAVE_SHADOW_H + + +/* + * Do we have ? + */ + +#undef HAVE_CRYPT_H + + +/* + * Do we have ? + */ + +#undef HAVE_SCSI_SG_H + + +/* + * Use , , and/or ? + */ + +#undef HAVE_STRING_H +#undef HAVE_STRINGS_H +#undef HAVE_BSTRING_H + +/* + * Do we have the long long type? + */ + +#undef HAVE_LONG_LONG + +#ifdef HAVE_LONG_LONG +# define CUPS_LLFMT "%lld" +# define CUPS_LLCAST (long long) +#else +# define CUPS_LLFMT "%ld" +# define CUPS_LLCAST (long) +#endif /* HAVE_LONG_LONG */ + +/* + * Do we have the strtoll() function? + */ + +#undef HAVE_STRTOLL + +#ifndef HAVE_STRTOLL +# define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base)) +#endif /* !HAVE_STRTOLL */ + +/* + * 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 geteuid() function? + */ + +#undef HAVE_GETEUID + + +/* + * 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 POSIX ACL functions? + */ + +#undef HAVE_ACL_INIT + + +/* + * Do we have the langinfo.h header file? + */ + +#undef HAVE_LANGINFO_H + + +/* + * Which encryption libraries do we have? + */ + +#undef HAVE_CDSASSL +#undef HAVE_GNUTLS +#undef HAVE_LIBSSL +#undef HAVE_SSL + + +/* + * What Security framework headers do we have? + */ + +#undef HAVE_AUTHORIZATION_H +#undef HAVE_SECITEM_H +#undef HAVE_SECITEMPRIV_H +#undef HAVE_SECPOLICY_H +#undef HAVE_SECPOLICYPRIV_H +#undef HAVE_SECBASEPRIV_H +#undef HAVE_SECIDENTITYSEARCHPRIV_H + + +/* + * Do we have the SecIdentitySearchCreateWithPolicy function? + */ + +#undef HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY + + +/* + * Do we have the SecPolicyCreateSSL function? + */ + +#undef HAVE_SECPOLICYCREATESSL + + +/* + * Do we have the SLP library? + */ + +#undef HAVE_LIBSLP + + +/* + * Do we have an LDAP library? + */ + +#undef HAVE_LDAP +#undef HAVE_OPENLDAP +#undef HAVE_MOZILLA_LDAP +#undef HAVE_LDAP_SSL_H +#undef HAVE_LDAP_SSL +#undef HAVE_LDAP_REBIND_PROC + + +/* + * Do we have libpaper? + */ + +#undef HAVE_LIBPAPER + + +/* + * Do we have DNS Service Discovery (aka Bonjour)? + */ + +#undef HAVE_DNSSD + + +/* + * Do we have ? + */ + +#undef HAVE_SYS_IOCTL_H + + +/* + * Does the "stat" structure contain the "st_gen" member? + */ + +#undef HAVE_ST_GEN + + +/* + * Does the "tm" structure contain the "tm_gmtoff" member? + */ + +#undef HAVE_TM_GMTOFF + + +/* + * Do we have rresvport_af()? + */ + +#undef HAVE_RRESVPORT_AF + + +/* + * Do we have getaddrinfo()? + */ + +#undef HAVE_GETADDRINFO + + +/* + * Do we have getnameinfo()? + */ + +#undef HAVE_GETNAMEINFO + + +/* + * Do we have getifaddrs()? + */ + +#undef HAVE_GETIFADDRS + + +/* + * Do we have hstrerror()? + */ + +#undef HAVE_HSTRERROR + + +/* + * Do we have res_init()? + */ + +#undef HAVE_RES_INIT + + +/* + * Do we have + */ + +#undef HAVE_RESOLV_H + + +/* + * Do we have the header file? + */ + +#undef HAVE_SYS_SOCKIO_H + + +/* + * Does the sockaddr structure contain an sa_len parameter? + */ + +#undef HAVE_STRUCT_SOCKADDR_SA_LEN + + +/* + * Do we have the AIX usersec.h header file? + */ + +#undef HAVE_USERSEC_H + + +/* + * Do we have pthread support? + */ + +#undef HAVE_PTHREAD_H + + +/* + * Do we have launchd support? + */ + +#undef HAVE_LAUNCH_H +#undef HAVE_LAUNCHD + + +/* + * Various scripting languages... + */ + +#undef HAVE_JAVA +#define CUPS_JAVA "/usr/bin/java" +#undef HAVE_PERL +#define CUPS_PERL "/usr/bin/perl" +#undef HAVE_PHP +#define CUPS_PHP "/usr/bin/php" +#undef HAVE_PYTHON +#define CUPS_PYTHON "/usr/bin/python" + + +/* + * Location of the poppler/Xpdf pdftops program... + */ + +#undef HAVE_PDFTOPS +#define CUPS_PDFTOPS "/usr/bin/pdftops" + + +/* + * Location of the Ghostscript gs program... + */ + +#undef HAVE_GHOSTSCRIPT +#define CUPS_GHOSTSCRIPT "/usr/bin/gs" + + +/* + * Do we have Darwin's CoreFoundation and SystemConfiguration frameworks? + */ + +#undef HAVE_COREFOUNDATION +#undef HAVE_SYSTEMCONFIGURATION + + +/* + * Do we have CoreFoundation public and private headers? + */ + +#undef HAVE_COREFOUNDATION_H +#undef HAVE_CFPRIV_H +#undef HAVE_CFBUNDLEPRIV_H + + +/* + * Do we have ApplicationServices public headers? + */ + +#undef HAVE_APPLICATIONSERVICES_H + + +/* + * Do we have the SCDynamicStoreCopyComputerName function? + */ + +#undef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME + + +/* + * Do we have MacOSX 10.4's mbr_XXX functions? + */ + +#undef HAVE_MEMBERSHIP_H +#undef HAVE_MEMBERSHIPPRIV_H +#undef HAVE_MBR_UID_TO_UUID + + +/* + * Do we have Darwin's notify_post header and function? + */ + +#undef HAVE_NOTIFY_H +#undef HAVE_NOTIFY_POST + + +/* + * Do we have DBUS? + */ + +#undef HAVE_DBUS +#undef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND + + +/* + * Do we have the AppleTalk/at_proto.h header? + */ + +#undef HAVE_APPLETALK_AT_PROTO_H + + +/* + * Do we have the GSSAPI support library (for Kerberos support)? + */ + +#undef HAVE_GSSAPI +#undef HAVE_GSSAPI_H +#undef HAVE_GSSAPI_GSSAPI_H +#undef HAVE_GSSAPI_GSSAPI_GENERIC_H +#undef HAVE_GSSAPI_GSSAPI_KRB5_H +#undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY +#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE +#undef HAVE_KRB5_CC_NEW_UNIQUE +#undef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID +#undef HAVE_KRB5_H +#undef HAVE_HEIMDAL + + +/* + * Default GSS service name... + */ + +#define CUPS_DEFAULT_GSSSERVICENAME "" + + +/* + * Select/poll interfaces... + */ + +#undef HAVE_POLL +#undef HAVE_EPOLL +#undef HAVE_KQUEUE + + +/* + * Do we have the header? + */ + +#undef HAVE_DLFCN_H + + +/* + * Do we have ? + */ + +#undef HAVE_SYS_PARAM_H + + +/* + * Do we have ? + */ + +#undef HAVE_SYS_UCRED_H + + +/* + * Do we have removefile()? + */ + +#undef HAVE_REMOVEFILE + + +/* + * Do we have ? + */ + +#undef HAVE_SANDBOX_H + + +/* + * Which random number generator function to use... + */ + +#undef HAVE_ARC4RANDOM +#undef HAVE_RANDOM +#undef HAVE_LRAND48 + +#ifdef HAVE_ARC4RANDOM +# define CUPS_RAND() arc4random() +# define CUPS_SRAND(v) arc4random_stir() +#elif defined(HAVE_RANDOM) +# define CUPS_RAND() random() +# define CUPS_SRAND(v) srandom(v) +#elif defined(HAVE_LRAND48) +# define CUPS_RAND() lrand48() +# define CUPS_SRAND(v) srand48(v) +#else +# define CUPS_RAND() rand() +# define CUPS_SRAND(v) srand(v) +#endif /* HAVE_ARC4RANDOM */ + + +/* + * Do we have vproc_transaction_begin/end? + */ + +#undef HAVE_VPROC_TRANSACTION_BEGIN + + +/* + * Do we have libusb? + */ + +#undef HAVE_USB_H + + +/* + * Do we have libwrap and tcpd.h? + */ + +#undef HAVE_TCPD_H + + +/* + * Do we have statfs or statvfs and one of the corresponding headers? + */ + +#undef HAVE_STATFS +#undef HAVE_STATVFS +#undef HAVE_SYS_MOUNT_H +#undef HAVE_SYS_STATFS_H +#undef HAVE_SYS_STATVFS_H +#undef HAVE_SYS_VFS_H + + +#endif /* !_CUPS_CONFIG_H_ */ + +/* + * End of "$Id$". + */ diff --git a/configure.in b/configure.in new file mode 100644 index 0000000000..11c134f800 --- /dev/null +++ b/configure.in @@ -0,0 +1,81 @@ +dnl +dnl "$Id$" +dnl +dnl Configuration script for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 2007 by Apple Inc. +dnl Copyright 1997-2007 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Apple Inc. and are protected by Federal copyright +dnl law. Distribution and use rights are outlined in the file "LICENSE.txt" +dnl which should have been included with this file. If this file is +dnl file is missing or damaged, see the license at "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-3264.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-poll.m4) +sinclude(config-scripts/cups-slp.m4) +sinclude(config-scripts/cups-gssapi.m4) +sinclude(config-scripts/cups-ldap.m4) +sinclude(config-scripts/cups-threads.m4) +sinclude(config-scripts/cups-ssl.m4) +sinclude(config-scripts/cups-pam.m4) +sinclude(config-scripts/cups-largefile.m4) +sinclude(config-scripts/cups-dnssd.m4) +sinclude(config-scripts/cups-launchd.m4) +sinclude(config-scripts/cups-defaults.m4) +sinclude(config-scripts/cups-pap.m4) +sinclude(config-scripts/cups-pdf.m4) +sinclude(config-scripts/cups-scripting.m4) + +INSTALL_LANGUAGES="" +UNINSTALL_LANGUAGES="" +LANGFILES="" +if test "x$LANGUAGES" != x; then + INSTALL_LANGUAGES="install-languages" + UNINSTALL_LANGUAGES="uninstall-languages" + for lang in $LANGUAGES; do + if test -f doc/$lang/index.html.in; then + LANGFILES="$LANGFILES doc/$lang/index.html" + fi + + if test -f templates/$lang/header.tmpl.in; then + LANGFILES="$LANGFILES templates/$lang/header.tmpl" + fi + done +fi + +AC_SUBST(INSTALL_LANGUAGES) +AC_SUBST(UNINSTALL_LANGUAGES) + +AC_OUTPUT(Makedefs packaging/cups.list init/cups.sh init/cups-lpd cups-config + conf/cupsd.conf conf/mime.convs conf/pam.std conf/snmp.conf + data/testprint + desktop/cups.desktop + doc/index.html doc/help/ref-cupsd-conf.html doc/help/standard.html + init/org.cups.cups-lpd.plist init/cups.xml + man/client.conf.man man/cups-deviced.man man/cups-driverd.man + man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man + man/cupsd.conf.man man/lpoptions.man + templates/header.tmpl + $LANGFILES) + +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 0000000000..e44eb52847 --- /dev/null +++ b/cups-config.in @@ -0,0 +1,160 @@ +#! /bin/sh +# +# "$Id$" +# +# CUPS configuration utility. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 2001-2006 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +VERSION="@CUPS_VERSION@" +APIVERSION="1.4" +BUILD="@CUPS_BUILD@" + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +bindir=@bindir@ +includedir=@includedir@ +libdir=@libdir@ +imagelibdir=@libdir@ +datarootdir=@datadir@ +datadir=@datadir@ +sysconfdir=@sysconfdir@ +cups_datadir=@CUPS_DATADIR@ +cups_serverbin=@CUPS_SERVERBIN@ +cups_serverroot=@CUPS_SERVERROOT@ +INSTALLSTATIC=@INSTALLSTATIC@ + +# flags for C++ compiler: +CFLAGS="" +LDFLAGS="@EXPORT_LDFLAGS@" +LIBS="@LIBGSSAPI@ @EXPORT_SSLLIBS@ @EXPORT_LIBZ@ @LIBS@" +IMGLIBS="@EXPORT_LIBTIFF@ @EXPORT_LIBJPEG@ @EXPORT_LIBPNG@" + +# Check for local invocation... +selfdir=`dirname $0` + +if test -f "$selfdir/cups/cups.h"; then + CFLAGS="-I$selfdir" + LDFLAGS="-L$selfdir/cups -L$selfdir/filter $LDFLAGS" + libdir="$selfdir/cups" + imagelibdir="$selfdir/filter" + if test ! -f "$selfdir/cups/raster.h"; then + ln -s ../filter/raster.h "$selfdir/cups" + fi +else + if test $includedir != /usr/include; then + CFLAGS="$CFLAGS -I$includedir" + fi + + if test $libdir != /usr/lib -a $libdir != /usr/lib32 -a $libdir != /usr/lib64; then + LDFLAGS="$LDFLAGS -L$libdir" + fi +fi + + +usage () +{ + echo "Usage: cups-config --api-version" + echo " cups-config --build" + echo " cups-config --cflags" + echo " cups-config --datadir" + echo " cups-config --help" + echo " cups-config --ldflags" + echo " cups-config [--driver] [--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 +driver=no + +while test $# -gt 0; do + case $1 in + --api-version) + echo $APIVERSION + ;; + --build) + echo $BUILD + ;; + --cflags) + echo $CFLAGS + ;; + --datadir) + echo $cups_datadir + ;; + --driver) + driver=yes + ;; + --help) + usage 0 + ;; + --image) + image=yes + ;; + --ldflags) + echo $LDFLAGS + ;; + --libs) + if test $static = no; then + libs="@EXTLINKCUPS@ $LIBS"; + if test $image = yes; then + libs="@EXTLINKCUPSIMAGE@ $libs" + fi + if test $driver = yes; then + libs="@EXTLINKCUPSDRIVER@ $libs" + fi + else + libs="$libdir/libcups.a $LIBS"; + if test $image = yes; then + libs="$libdir/libcupsimage.a $IMGLIBS $libs" + fi + if test $driver = yes; then + libs="$libdir/libcupsdriver.a $libs" + fi + fi + echo $libs + ;; + --serverbin) + echo $cups_serverbin + ;; + --serverroot) + echo $cups_serverroot + ;; + --static) + if test -z "$INSTALLSTATIC"; then + echo "WARNING: Static libraries not installed!" >&2 + else + static=yes + fi + ;; + --version) + echo $VERSION + ;; + *) + usage 1 + ;; + esac + + shift +done + +# +# End of "$Id$". +# diff --git a/cups/Dependencies b/cups/Dependencies new file mode 100644 index 0000000000..6ccc01b665 --- /dev/null +++ b/cups/Dependencies @@ -0,0 +1,453 @@ +# DO NOT DELETE + +adminutil.o: adminutil.h cups.h ipp.h http.h versioning.h ppd.h array.h +adminutil.o: file.h language.h globals.h string.h ../config.h http-private.h +adminutil.o: md5.h ipp-private.h i18n.h transcode.h pwg-private.h +adminutil.o: ../cups/cups.h debug.h +array.o: array.h versioning.h string.h ../config.h debug.h +attr.o: ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h file.h +attr.o: language.h debug.h string.h ../config.h +auth.o: globals.h string.h ../config.h http-private.h http.h versioning.h +auth.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +auth.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +backchannel.o: cups.h ipp.h http.h versioning.h ppd.h array.h file.h +backchannel.o: language.h +backend.o: backend.h versioning.h globals.h string.h ../config.h +backend.o: http-private.h http.h md5.h ipp-private.h ipp.h cups.h ppd.h +backend.o: array.h file.h language.h i18n.h transcode.h pwg-private.h +backend.o: ../cups/cups.h +conflicts.o: ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h +conflicts.o: file.h language.h string.h ../config.h debug.h +custom.o: globals.h string.h ../config.h http-private.h http.h versioning.h +custom.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +custom.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +debug.o: globals.h string.h ../config.h http-private.h http.h versioning.h +debug.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +debug.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +dest.o: debug.h globals.h string.h ../config.h http-private.h http.h +dest.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h +dest.o: language.h i18n.h transcode.h pwg-private.h ../cups/cups.h +dir.o: dir.h versioning.h string.h ../config.h debug.h +emit.o: ppd.h array.h versioning.h file.h string.h ../config.h debug.h +encode.o: cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +encode.o: ipp-private.h string.h ../config.h debug.h +file.o: file-private.h http-private.h ../config.h http.h versioning.h md5.h +file.o: ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h file.h +file.o: language.h i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +getdevices.o: globals.h string.h ../config.h http-private.h http.h +getdevices.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +getdevices.o: file.h language.h i18n.h transcode.h pwg-private.h +getdevices.o: ../cups/cups.h debug.h +getifaddrs.o: http-private.h ../config.h http.h versioning.h md5.h +getifaddrs.o: ipp-private.h ipp.h +getputfile.o: globals.h string.h ../config.h http-private.h http.h +getputfile.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +getputfile.o: file.h language.h i18n.h transcode.h pwg-private.h +getputfile.o: ../cups/cups.h debug.h +globals.o: http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +globals.o: ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +globals.o: i18n.h transcode.h pwg-private.h ../cups/cups.h +http.o: http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +http.o: ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +http.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +http-addr.o: http-private.h ../config.h http.h versioning.h md5.h +http-addr.o: ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h +http-addr.o: file.h language.h i18n.h transcode.h pwg-private.h +http-addr.o: ../cups/cups.h debug.h +http-addrlist.o: http-private.h ../config.h http.h versioning.h md5.h +http-addrlist.o: ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h +http-addrlist.o: file.h language.h i18n.h transcode.h pwg-private.h +http-addrlist.o: ../cups/cups.h debug.h +http-support.o: debug.h globals.h string.h ../config.h http-private.h http.h +http-support.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +http-support.o: file.h language.h i18n.h transcode.h pwg-private.h +http-support.o: ../cups/cups.h +ipp.o: http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +ipp.o: ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h +ipp.o: transcode.h pwg-private.h ../cups/cups.h debug.h +ipp-support.o: globals.h string.h ../config.h http-private.h http.h +ipp-support.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +ipp-support.o: file.h language.h i18n.h transcode.h pwg-private.h +ipp-support.o: ../cups/cups.h debug.h +langprintf.o: globals.h string.h ../config.h http-private.h http.h +langprintf.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +langprintf.o: file.h language.h i18n.h transcode.h pwg-private.h +langprintf.o: ../cups/cups.h +language.o: globals.h string.h ../config.h http-private.h http.h versioning.h +language.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +language.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +localize.o: globals.h string.h ../config.h http-private.h http.h versioning.h +localize.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +localize.o: i18n.h transcode.h pwg-private.h ../cups/cups.h ppd-private.h +localize.o: debug.h +mark.o: cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +mark.o: string.h ../config.h debug.h pwg-private.h ../cups/cups.h +md5.o: md5.h string.h ../config.h +md5passwd.o: http-private.h ../config.h http.h versioning.h md5.h +md5passwd.o: ipp-private.h ipp.h string.h +notify.o: globals.h string.h ../config.h http-private.h http.h versioning.h +notify.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +notify.o: i18n.h transcode.h pwg-private.h ../cups/cups.h +options.o: cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +options.o: string.h ../config.h debug.h +page.o: ppd.h array.h versioning.h file.h string.h ../config.h debug.h +ppd.o: ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h file.h +ppd.o: language.h pwg-private.h ../cups/cups.h globals.h string.h ../config.h +ppd.o: http-private.h md5.h ipp-private.h i18n.h transcode.h debug.h +pwg-file.o: pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-file.o: http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-file.o: cups.h ppd.h array.h file.h language.h i18n.h transcode.h debug.h +pwg-media.o: pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-media.o: http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-media.o: cups.h ppd.h array.h file.h language.h i18n.h transcode.h +pwg-media.o: debug.h +pwg-ppd.o: pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-ppd.o: http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-ppd.o: cups.h ppd.h array.h file.h language.h i18n.h transcode.h debug.h +request.o: globals.h string.h ../config.h http-private.h http.h versioning.h +request.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +request.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +sidechannel.o: sidechannel.h versioning.h string.h ../config.h debug.h +snmp.o: globals.h string.h ../config.h http-private.h http.h versioning.h +snmp.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +snmp.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +snmp.o: snmp-private.h +snprintf.o: string.h ../config.h +string.o: array.h versioning.h debug.h string.h ../config.h +tempfile.o: globals.h string.h ../config.h http-private.h http.h versioning.h +tempfile.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +tempfile.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +transcode.o: globals.h string.h ../config.h http-private.h http.h +transcode.o: versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +transcode.o: file.h language.h i18n.h transcode.h pwg-private.h +transcode.o: ../cups/cups.h debug.h +usersys.o: http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +usersys.o: ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +usersys.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +util.o: globals.h string.h ../config.h http-private.h http.h versioning.h +util.o: md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +util.o: i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +testadmin.o: adminutil.h cups.h ipp.h http.h versioning.h ppd.h array.h +testadmin.o: file.h language.h string.h ../config.h +testarray.o: ../cups/string.h ../config.h string.h array.h versioning.h dir.h +testarray.o: debug.h +testconflicts.o: cups.h ipp.h http.h versioning.h ppd.h array.h file.h +testconflicts.o: language.h string.h ../config.h +testcups.o: cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +testcups.o: string.h ../config.h +testfile.o: string.h ../config.h file.h versioning.h debug.h +testhttp.o: http-private.h ../config.h http.h versioning.h md5.h +testhttp.o: ipp-private.h ipp.h string.h +testi18n.o: i18n.h transcode.h language.h array.h versioning.h string.h +testi18n.o: ../config.h +testipp.o: ../cups/string.h ../config.h string.h ipp-private.h ipp.h http.h +testipp.o: versioning.h +testoptions.o: string.h ../config.h cups.h ipp.h http.h versioning.h ppd.h +testoptions.o: array.h file.h language.h +testlang.o: i18n.h transcode.h language.h array.h versioning.h string.h +testlang.o: ../config.h +testppd.o: ../cups/cups.h ../cups/string.h ../config.h string.h +testpwg.o: pwg-private.h ../cups/cups.h +testsnmp.o: string.h ../config.h snmp-private.h http.h versioning.h +# DO NOT DELETE + +adminutil.32.o: adminutil.c adminutil.h cups.h ipp.h http.h versioning.h ppd.h array.h +adminutil.32.o: adminutil.c file.h language.h globals.h string.h ../config.h http-private.h +adminutil.32.o: adminutil.c md5.h ipp-private.h i18n.h transcode.h pwg-private.h +adminutil.32.o: adminutil.c ../cups/cups.h debug.h +array.32.o: array.c array.h versioning.h string.h ../config.h debug.h +attr.32.o: attr.c ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h file.h +attr.32.o: attr.c language.h debug.h string.h ../config.h +auth.32.o: auth.c globals.h string.h ../config.h http-private.h http.h versioning.h +auth.32.o: auth.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +auth.32.o: auth.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +backchannel.32.o: backchannel.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h +backchannel.32.o: backchannel.c language.h +backend.32.o: backend.c backend.h versioning.h globals.h string.h ../config.h +backend.32.o: backend.c http-private.h http.h md5.h ipp-private.h ipp.h cups.h ppd.h +backend.32.o: backend.c array.h file.h language.h i18n.h transcode.h pwg-private.h +backend.32.o: backend.c ../cups/cups.h +conflicts.32.o: conflicts.c ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h +conflicts.32.o: conflicts.c file.h language.h string.h ../config.h debug.h +custom.32.o: custom.c globals.h string.h ../config.h http-private.h http.h versioning.h +custom.32.o: custom.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +custom.32.o: custom.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +debug.32.o: debug.c globals.h string.h ../config.h http-private.h http.h versioning.h +debug.32.o: debug.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +debug.32.o: debug.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +dest.32.o: dest.c debug.h globals.h string.h ../config.h http-private.h http.h +dest.32.o: dest.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h +dest.32.o: dest.c language.h i18n.h transcode.h pwg-private.h ../cups/cups.h +dir.32.o: dir.c dir.h versioning.h string.h ../config.h debug.h +emit.32.o: emit.c ppd.h array.h versioning.h file.h string.h ../config.h debug.h +encode.32.o: encode.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +encode.32.o: encode.c ipp-private.h string.h ../config.h debug.h +file.32.o: file.c file-private.h http-private.h ../config.h http.h versioning.h md5.h +file.32.o: file.c ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h file.h +file.32.o: file.c language.h i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +getdevices.32.o: getdevices.c globals.h string.h ../config.h http-private.h http.h +getdevices.32.o: getdevices.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +getdevices.32.o: getdevices.c file.h language.h i18n.h transcode.h pwg-private.h +getdevices.32.o: getdevices.c ../cups/cups.h debug.h +getifaddrs.32.o: getifaddrs.c http-private.h ../config.h http.h versioning.h md5.h +getifaddrs.32.o: getifaddrs.c ipp-private.h ipp.h +getputfile.32.o: getputfile.c globals.h string.h ../config.h http-private.h http.h +getputfile.32.o: getputfile.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +getputfile.32.o: getputfile.c file.h language.h i18n.h transcode.h pwg-private.h +getputfile.32.o: getputfile.c ../cups/cups.h debug.h +globals.32.o: globals.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +globals.32.o: globals.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +globals.32.o: globals.c i18n.h transcode.h pwg-private.h ../cups/cups.h +http.32.o: http.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +http.32.o: http.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +http.32.o: http.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +http-addr.32.o: http-addr.c http-private.h ../config.h http.h versioning.h md5.h +http-addr.32.o: http-addr.c ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h +http-addr.32.o: http-addr.c file.h language.h i18n.h transcode.h pwg-private.h +http-addr.32.o: http-addr.c ../cups/cups.h debug.h +http-addrlist.32.o: http-addrlist.c http-private.h ../config.h http.h versioning.h md5.h +http-addrlist.32.o: http-addrlist.c ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h +http-addrlist.32.o: http-addrlist.c file.h language.h i18n.h transcode.h pwg-private.h +http-addrlist.32.o: http-addrlist.c ../cups/cups.h debug.h +http-support.32.o: http-support.c debug.h globals.h string.h ../config.h http-private.h http.h +http-support.32.o: http-support.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +http-support.32.o: http-support.c file.h language.h i18n.h transcode.h pwg-private.h +http-support.32.o: http-support.c ../cups/cups.h +ipp.32.o: ipp.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +ipp.32.o: ipp.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h +ipp.32.o: ipp.c transcode.h pwg-private.h ../cups/cups.h debug.h +ipp-support.32.o: ipp-support.c globals.h string.h ../config.h http-private.h http.h +ipp-support.32.o: ipp-support.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +ipp-support.32.o: ipp-support.c file.h language.h i18n.h transcode.h pwg-private.h +ipp-support.32.o: ipp-support.c ../cups/cups.h debug.h +langprintf.32.o: langprintf.c globals.h string.h ../config.h http-private.h http.h +langprintf.32.o: langprintf.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +langprintf.32.o: langprintf.c file.h language.h i18n.h transcode.h pwg-private.h +langprintf.32.o: langprintf.c ../cups/cups.h +language.32.o: language.c globals.h string.h ../config.h http-private.h http.h versioning.h +language.32.o: language.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +language.32.o: language.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +localize.32.o: localize.c globals.h string.h ../config.h http-private.h http.h versioning.h +localize.32.o: localize.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +localize.32.o: localize.c i18n.h transcode.h pwg-private.h ../cups/cups.h ppd-private.h +localize.32.o: localize.c debug.h +mark.32.o: mark.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +mark.32.o: mark.c string.h ../config.h debug.h pwg-private.h ../cups/cups.h +md5.32.o: md5.c md5.h string.h ../config.h +md5passwd.32.o: md5passwd.c http-private.h ../config.h http.h versioning.h md5.h +md5passwd.32.o: md5passwd.c ipp-private.h ipp.h string.h +notify.32.o: notify.c globals.h string.h ../config.h http-private.h http.h versioning.h +notify.32.o: notify.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +notify.32.o: notify.c i18n.h transcode.h pwg-private.h ../cups/cups.h +options.32.o: options.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +options.32.o: options.c string.h ../config.h debug.h +page.32.o: page.c ppd.h array.h versioning.h file.h string.h ../config.h debug.h +ppd.32.o: ppd.c ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h file.h +ppd.32.o: ppd.c language.h pwg-private.h ../cups/cups.h globals.h string.h ../config.h +ppd.32.o: ppd.c http-private.h md5.h ipp-private.h i18n.h transcode.h debug.h +pwg-file.32.o: pwg-file.c pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-file.32.o: pwg-file.c http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-file.32.o: pwg-file.c cups.h ppd.h array.h file.h language.h i18n.h transcode.h debug.h +pwg-media.32.o: pwg-media.c pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-media.32.o: pwg-media.c http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-media.32.o: pwg-media.c cups.h ppd.h array.h file.h language.h i18n.h transcode.h +pwg-media.32.o: pwg-media.c debug.h +pwg-ppd.32.o: pwg-ppd.c pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-ppd.32.o: pwg-ppd.c http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-ppd.32.o: pwg-ppd.c cups.h ppd.h array.h file.h language.h i18n.h transcode.h debug.h +request.32.o: request.c globals.h string.h ../config.h http-private.h http.h versioning.h +request.32.o: request.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +request.32.o: request.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +sidechannel.32.o: sidechannel.c sidechannel.h versioning.h string.h ../config.h debug.h +snmp.32.o: snmp.c globals.h string.h ../config.h http-private.h http.h versioning.h +snmp.32.o: snmp.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +snmp.32.o: snmp.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +snmp.32.o: snmp.c snmp-private.h +snprintf.32.o: snprintf.c string.h ../config.h +string.32.o: string.c array.h versioning.h debug.h string.h ../config.h +tempfile.32.o: tempfile.c globals.h string.h ../config.h http-private.h http.h versioning.h +tempfile.32.o: tempfile.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +tempfile.32.o: tempfile.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +transcode.32.o: transcode.c globals.h string.h ../config.h http-private.h http.h +transcode.32.o: transcode.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +transcode.32.o: transcode.c file.h language.h i18n.h transcode.h pwg-private.h +transcode.32.o: transcode.c ../cups/cups.h debug.h +usersys.32.o: usersys.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +usersys.32.o: usersys.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +usersys.32.o: usersys.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +util.32.o: util.c globals.h string.h ../config.h http-private.h http.h versioning.h +util.32.o: util.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +util.32.o: util.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +testadmin.32.o: testadmin.c adminutil.h cups.h ipp.h http.h versioning.h ppd.h array.h +testadmin.32.o: testadmin.c file.h language.h string.h ../config.h +testarray.32.o: testarray.c ../cups/string.h ../config.h string.h array.h versioning.h dir.h +testarray.32.o: testarray.c debug.h +testconflicts.32.o: testconflicts.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h +testconflicts.32.o: testconflicts.c language.h string.h ../config.h +testcups.32.o: testcups.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +testcups.32.o: testcups.c string.h ../config.h +testfile.32.o: testfile.c string.h ../config.h file.h versioning.h debug.h +testhttp.32.o: testhttp.c http-private.h ../config.h http.h versioning.h md5.h +testhttp.32.o: testhttp.c ipp-private.h ipp.h string.h +testi18n.32.o: testi18n.c i18n.h transcode.h language.h array.h versioning.h string.h +testi18n.32.o: testi18n.c ../config.h +testipp.32.o: testipp.c ../cups/string.h ../config.h string.h ipp-private.h ipp.h http.h +testipp.32.o: testipp.c versioning.h +testoptions.32.o: testoptions.c string.h ../config.h cups.h ipp.h http.h versioning.h ppd.h +testoptions.32.o: testoptions.c array.h file.h language.h +testlang.32.o: testlang.c i18n.h transcode.h language.h array.h versioning.h string.h +testlang.32.o: testlang.c ../config.h +testppd.32.o: testppd.c ../cups/cups.h ../cups/string.h ../config.h string.h +testpwg.32.o: testpwg.c pwg-private.h ../cups/cups.h +testsnmp.32.o: testsnmp.c string.h ../config.h snmp-private.h http.h versioning.h +# DO NOT DELETE + +adminutil.64.o: adminutil.c adminutil.h cups.h ipp.h http.h versioning.h ppd.h array.h +adminutil.64.o: adminutil.c file.h language.h globals.h string.h ../config.h http-private.h +adminutil.64.o: adminutil.c md5.h ipp-private.h i18n.h transcode.h pwg-private.h +adminutil.64.o: adminutil.c ../cups/cups.h debug.h +array.64.o: array.c array.h versioning.h string.h ../config.h debug.h +attr.64.o: attr.c ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h file.h +attr.64.o: attr.c language.h debug.h string.h ../config.h +auth.64.o: auth.c globals.h string.h ../config.h http-private.h http.h versioning.h +auth.64.o: auth.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +auth.64.o: auth.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +backchannel.64.o: backchannel.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h +backchannel.64.o: backchannel.c language.h +backend.64.o: backend.c backend.h versioning.h globals.h string.h ../config.h +backend.64.o: backend.c http-private.h http.h md5.h ipp-private.h ipp.h cups.h ppd.h +backend.64.o: backend.c array.h file.h language.h i18n.h transcode.h pwg-private.h +backend.64.o: backend.c ../cups/cups.h +conflicts.64.o: conflicts.c ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h +conflicts.64.o: conflicts.c file.h language.h string.h ../config.h debug.h +custom.64.o: custom.c globals.h string.h ../config.h http-private.h http.h versioning.h +custom.64.o: custom.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +custom.64.o: custom.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +debug.64.o: debug.c globals.h string.h ../config.h http-private.h http.h versioning.h +debug.64.o: debug.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +debug.64.o: debug.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +dest.64.o: dest.c debug.h globals.h string.h ../config.h http-private.h http.h +dest.64.o: dest.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h +dest.64.o: dest.c language.h i18n.h transcode.h pwg-private.h ../cups/cups.h +dir.64.o: dir.c dir.h versioning.h string.h ../config.h debug.h +emit.64.o: emit.c ppd.h array.h versioning.h file.h string.h ../config.h debug.h +encode.64.o: encode.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +encode.64.o: encode.c ipp-private.h string.h ../config.h debug.h +file.64.o: file.c file-private.h http-private.h ../config.h http.h versioning.h md5.h +file.64.o: file.c ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h file.h +file.64.o: file.c language.h i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +getdevices.64.o: getdevices.c globals.h string.h ../config.h http-private.h http.h +getdevices.64.o: getdevices.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +getdevices.64.o: getdevices.c file.h language.h i18n.h transcode.h pwg-private.h +getdevices.64.o: getdevices.c ../cups/cups.h debug.h +getifaddrs.64.o: getifaddrs.c http-private.h ../config.h http.h versioning.h md5.h +getifaddrs.64.o: getifaddrs.c ipp-private.h ipp.h +getputfile.64.o: getputfile.c globals.h string.h ../config.h http-private.h http.h +getputfile.64.o: getputfile.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +getputfile.64.o: getputfile.c file.h language.h i18n.h transcode.h pwg-private.h +getputfile.64.o: getputfile.c ../cups/cups.h debug.h +globals.64.o: globals.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +globals.64.o: globals.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +globals.64.o: globals.c i18n.h transcode.h pwg-private.h ../cups/cups.h +http.64.o: http.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +http.64.o: http.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +http.64.o: http.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +http-addr.64.o: http-addr.c http-private.h ../config.h http.h versioning.h md5.h +http-addr.64.o: http-addr.c ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h +http-addr.64.o: http-addr.c file.h language.h i18n.h transcode.h pwg-private.h +http-addr.64.o: http-addr.c ../cups/cups.h debug.h +http-addrlist.64.o: http-addrlist.c http-private.h ../config.h http.h versioning.h md5.h +http-addrlist.64.o: http-addrlist.c ipp-private.h ipp.h globals.h string.h cups.h ppd.h array.h +http-addrlist.64.o: http-addrlist.c file.h language.h i18n.h transcode.h pwg-private.h +http-addrlist.64.o: http-addrlist.c ../cups/cups.h debug.h +http-support.64.o: http-support.c debug.h globals.h string.h ../config.h http-private.h http.h +http-support.64.o: http-support.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +http-support.64.o: http-support.c file.h language.h i18n.h transcode.h pwg-private.h +http-support.64.o: http-support.c ../cups/cups.h +ipp.64.o: ipp.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +ipp.64.o: ipp.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h i18n.h +ipp.64.o: ipp.c transcode.h pwg-private.h ../cups/cups.h debug.h +ipp-support.64.o: ipp-support.c globals.h string.h ../config.h http-private.h http.h +ipp-support.64.o: ipp-support.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +ipp-support.64.o: ipp-support.c file.h language.h i18n.h transcode.h pwg-private.h +ipp-support.64.o: ipp-support.c ../cups/cups.h debug.h +langprintf.64.o: langprintf.c globals.h string.h ../config.h http-private.h http.h +langprintf.64.o: langprintf.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +langprintf.64.o: langprintf.c file.h language.h i18n.h transcode.h pwg-private.h +langprintf.64.o: langprintf.c ../cups/cups.h +language.64.o: language.c globals.h string.h ../config.h http-private.h http.h versioning.h +language.64.o: language.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +language.64.o: language.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +localize.64.o: localize.c globals.h string.h ../config.h http-private.h http.h versioning.h +localize.64.o: localize.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +localize.64.o: localize.c i18n.h transcode.h pwg-private.h ../cups/cups.h ppd-private.h +localize.64.o: localize.c debug.h +mark.64.o: mark.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +mark.64.o: mark.c string.h ../config.h debug.h pwg-private.h ../cups/cups.h +md5.64.o: md5.c md5.h string.h ../config.h +md5passwd.64.o: md5passwd.c http-private.h ../config.h http.h versioning.h md5.h +md5passwd.64.o: md5passwd.c ipp-private.h ipp.h string.h +notify.64.o: notify.c globals.h string.h ../config.h http-private.h http.h versioning.h +notify.64.o: notify.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +notify.64.o: notify.c i18n.h transcode.h pwg-private.h ../cups/cups.h +options.64.o: options.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +options.64.o: options.c string.h ../config.h debug.h +page.64.o: page.c ppd.h array.h versioning.h file.h string.h ../config.h debug.h +ppd.64.o: ppd.c ppd-private.h cups.h ipp.h http.h versioning.h ppd.h array.h file.h +ppd.64.o: ppd.c language.h pwg-private.h ../cups/cups.h globals.h string.h ../config.h +ppd.64.o: ppd.c http-private.h md5.h ipp-private.h i18n.h transcode.h debug.h +pwg-file.64.o: pwg-file.c pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-file.64.o: pwg-file.c http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-file.64.o: pwg-file.c cups.h ppd.h array.h file.h language.h i18n.h transcode.h debug.h +pwg-media.64.o: pwg-media.c pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-media.64.o: pwg-media.c http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-media.64.o: pwg-media.c cups.h ppd.h array.h file.h language.h i18n.h transcode.h +pwg-media.64.o: pwg-media.c debug.h +pwg-ppd.64.o: pwg-ppd.c pwg-private.h ../cups/cups.h globals.h string.h ../config.h +pwg-ppd.64.o: pwg-ppd.c http-private.h http.h versioning.h md5.h ipp-private.h ipp.h +pwg-ppd.64.o: pwg-ppd.c cups.h ppd.h array.h file.h language.h i18n.h transcode.h debug.h +request.64.o: request.c globals.h string.h ../config.h http-private.h http.h versioning.h +request.64.o: request.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +request.64.o: request.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +sidechannel.64.o: sidechannel.c sidechannel.h versioning.h string.h ../config.h debug.h +snmp.64.o: snmp.c globals.h string.h ../config.h http-private.h http.h versioning.h +snmp.64.o: snmp.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +snmp.64.o: snmp.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +snmp.64.o: snmp.c snmp-private.h +snprintf.64.o: snprintf.c string.h ../config.h +string.64.o: string.c array.h versioning.h debug.h string.h ../config.h +tempfile.64.o: tempfile.c globals.h string.h ../config.h http-private.h http.h versioning.h +tempfile.64.o: tempfile.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +tempfile.64.o: tempfile.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +transcode.64.o: transcode.c globals.h string.h ../config.h http-private.h http.h +transcode.64.o: transcode.c versioning.h md5.h ipp-private.h ipp.h cups.h ppd.h array.h +transcode.64.o: transcode.c file.h language.h i18n.h transcode.h pwg-private.h +transcode.64.o: transcode.c ../cups/cups.h debug.h +usersys.64.o: usersys.c http-private.h ../config.h http.h versioning.h md5.h ipp-private.h +usersys.64.o: usersys.c ipp.h globals.h string.h cups.h ppd.h array.h file.h language.h +usersys.64.o: usersys.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +util.64.o: util.c globals.h string.h ../config.h http-private.h http.h versioning.h +util.64.o: util.c md5.h ipp-private.h ipp.h cups.h ppd.h array.h file.h language.h +util.64.o: util.c i18n.h transcode.h pwg-private.h ../cups/cups.h debug.h +testadmin.64.o: testadmin.c adminutil.h cups.h ipp.h http.h versioning.h ppd.h array.h +testadmin.64.o: testadmin.c file.h language.h string.h ../config.h +testarray.64.o: testarray.c ../cups/string.h ../config.h string.h array.h versioning.h dir.h +testarray.64.o: testarray.c debug.h +testconflicts.64.o: testconflicts.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h +testconflicts.64.o: testconflicts.c language.h string.h ../config.h +testcups.64.o: testcups.c cups.h ipp.h http.h versioning.h ppd.h array.h file.h language.h +testcups.64.o: testcups.c string.h ../config.h +testfile.64.o: testfile.c string.h ../config.h file.h versioning.h debug.h +testhttp.64.o: testhttp.c http-private.h ../config.h http.h versioning.h md5.h +testhttp.64.o: testhttp.c ipp-private.h ipp.h string.h +testi18n.64.o: testi18n.c i18n.h transcode.h language.h array.h versioning.h string.h +testi18n.64.o: testi18n.c ../config.h +testipp.64.o: testipp.c ../cups/string.h ../config.h string.h ipp-private.h ipp.h http.h +testipp.64.o: testipp.c versioning.h +testoptions.64.o: testoptions.c string.h ../config.h cups.h ipp.h http.h versioning.h ppd.h +testoptions.64.o: testoptions.c array.h file.h language.h +testlang.64.o: testlang.c i18n.h transcode.h language.h array.h versioning.h string.h +testlang.64.o: testlang.c ../config.h +testppd.64.o: testppd.c ../cups/cups.h ../cups/string.h ../config.h string.h +testpwg.64.o: testpwg.c pwg-private.h ../cups/cups.h +testsnmp.64.o: testsnmp.c string.h ../config.h snmp-private.h http.h versioning.h diff --git a/cups/Makefile b/cups/Makefile new file mode 100644 index 0000000000..2b50951277 --- /dev/null +++ b/cups/Makefile @@ -0,0 +1,644 @@ +# +# "$Id$" +# +# API library Makefile for CUPS. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +# This file is subject to the Apple OS-Developed Software exception. +# + +include ../Makedefs + +# +# Object files... +# + +LIBOBJS = \ + adminutil.o \ + array.o \ + attr.o \ + auth.o \ + backchannel.o \ + backend.o \ + conflicts.o \ + custom.o \ + debug.o \ + dest.o \ + dir.o \ + emit.o \ + encode.o \ + file.o \ + getdevices.o \ + getifaddrs.o \ + getputfile.o \ + globals.o \ + http.o \ + http-addr.o \ + http-addrlist.o \ + http-support.o \ + ipp.o \ + ipp-support.o \ + langprintf.o \ + language.o \ + localize.o \ + mark.o \ + md5.o \ + md5passwd.o \ + notify.o \ + options.o \ + page.o \ + ppd.o \ + pwg-file.o \ + pwg-media.o \ + pwg-ppd.o \ + request.o \ + sidechannel.o \ + snmp.o \ + snprintf.o \ + string.o \ + tempfile.o \ + transcode.o \ + usersys.o \ + util.o +LIB32OBJS = $(LIBOBJS:.o=.32.o) +LIB64OBJS = $(LIBOBJS:.o=.64.o) +OBJS = \ + $(LIBOBJS) \ + $(LIB32OBJS) \ + $(LIB64OBJS) \ + testadmin.o \ + testarray.o \ + testconflicts.o \ + testcups.o \ + testfile.o \ + testhttp.o \ + testi18n.o \ + testipp.o \ + testoptions.o \ + testlang.o \ + testppd.o \ + testpwg.o \ + testsnmp.o + + +# +# Header files to install... +# + +HEADERS = \ + adminutil.h \ + array.h \ + backend.h \ + cups.h \ + dir.h \ + file.h \ + http.h \ + ipp.h \ + language.h \ + ppd.h \ + raster.h \ + sidechannel.h \ + transcode.h \ + versioning.h + + +# +# Targets in this directory... +# + +LIBTARGETS = \ + $(LIBCUPS) \ + $(LIB32CUPS) \ + $(LIB64CUPS) \ + libcups.a + +UNITTARGETS = \ + testadmin \ + testarray \ + testconflicts \ + testcups \ + testfile \ + testhttp \ + testi18n \ + testipp \ + testlang \ + testoptions \ + testppd \ + testpwg \ + testsnmp + +TARGETS = \ + $(LIBTARGETS) + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: $(LIBTARGETS) + + +# +# Make unit tests... +# + +unittests: $(UNITTARGETS) + + +# +# Remove object and target files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) $(UNITTARGETS) + $(RM) libcups.so libcups.sl libcups.dylib + $(RM) -r 32bit 64bit + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + touch Dependencies.tmp + makedepend -Y -I.. -fDependencies.tmp $(OBJS:.o=.c) >/dev/null 2>&1 + $(RM) Dependencies + cp Dependencies.tmp Dependencies + sed -E -e '1,$$s/^([^.]+)\.o:/\1\.32.o: \1\.c /' Dependencies.tmp >>Dependencies + sed -E -e '1,$$s/^([^.]+)\.o:/\1\.64.o: \1\.c /' Dependencies.tmp >>Dependencies + $(RM) Dependencies.tmp + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + echo Installing header files into $(INCLUDEDIR)/cups... + $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups + for file in $(HEADERS); do \ + $(INSTALL_DATA) $$file $(INCLUDEDIR)/cups; \ + done + + +# +# Install libraries... +# + +install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64) + echo Installing libraries in $(LIBDIR)... + $(INSTALL_DIR) -m 755 $(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 \ + $(RM) $(LIBDIR)/libcups.dylib; \ + $(LN) $(LIBCUPS) $(LIBDIR)/libcups.dylib; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(LIBCUPS) $(SYMROOT); \ + fi + +installstatic: + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) -m 755 libcups.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcups.a + $(CHMOD) 555 $(LIBDIR)/libcups.a + +install32bit: + echo Installing libraries in $(LIB32DIR)... + $(INSTALL_DIR) -m 755 $(LIB32DIR) + $(INSTALL_LIB) 32bit/libcups.so.2 $(LIB32DIR)/libcups.so.2 + $(LN) libcups.so.2 $(LIB32DIR)/libcups.so + +install64bit: + echo Installing libraries in $(LIB64DIR)... + $(INSTALL_DIR) -m 755 $(LIB64DIR) + $(INSTALL_LIB) 64bit/libcups.so.2 $(LIB64DIR)/libcups.so.2 + $(LN) libcups.so.2 $(LIB64DIR)/libcups.so + + +# +# Uninstall object and target files... +# + +uninstall: $(UNINSTALL32) $(UNINSTALL64) + $(RM) $(LIBDIR)/libcups.2.dylib + $(RM) $(LIBDIR)/libcups.a + $(RM) $(LIBDIR)/libcups.dylib + $(RM) $(LIBDIR)/libcups_s.a + $(RM) $(LIBDIR)/libcups.sl + $(RM) $(LIBDIR)/libcups.sl.2 + $(RM) $(LIBDIR)/libcups.so + $(RM) $(LIBDIR)/libcups.so.2 + -$(RMDIR) $(LIBDIR) + for file in $(HEADERS); do \ + $(RM) $(INCLUDEDIR)/cups/$$file; \ + done + -$(RMDIR) $(INCLUDEDIR)/cups + +uninstall32bit: + $(RM) $(LIB32DIR)/libcups.so + $(RM) $(LIB32DIR)/libcups.so.2 + -$(RMDIR) $(LIB32DIR) + +uninstall64bit: + $(RM) $(LIB64DIR)/libcups.so + $(RM) $(LIB64DIR)/libcups.so.2 + -$(RMDIR) $(LIB64DIR) + + +# +# libcups.so.2, libcups.sl.2 +# + +libcups.so.2 libcups.sl.2: $(LIBOBJS) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBGSSAPI) \ + $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + $(RM) `basename $@ .2` + $(LN) $@ `basename $@ .2` + + +# +# 32bit/libcups.so.2 +# + +32bit/libcups.so.2: $(LIB32OBJS) + echo Linking 32-bit $@... + -mkdir 32bit + $(DSO) $(ARCH32FLAGS) $(DSO32FLAGS) -o $@ $(LIB32OBJS) $(LIBGSSAPI) \ + $(DNSSDLIBS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(RM) 32bit/libcups.so + $(LN) libcups.so.2 32bit/libcups.so + + +# +# 64bit/libcups.so.2 +# + +64bit/libcups.so.2: $(LIB64OBJS) + echo Linking 64-bit $@... + -mkdir 64bit + $(DSO) $(ARCH64FLAGS) $(DSO64FLAGS) -o $@ $(LIB64OBJS) $(LIBGSSAPI) \ + $(DNSSDLIBS) $(SSLLIBS) $(COMMONLIBS) $(LIBZ) + $(RM) 64bit/libcups.so + $(LN) libcups.so.2 64bit/libcups.so + + +# +# libcups.2.dylib +# + +libcups.2.dylib: $(LIBOBJS) $(LIBCUPSORDER) libcups.exp + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 2.8.0 \ + -compatibility_version 2.0.0 \ + -exported_symbols_list libcups.exp \ + -sectorder __TEXT __text $(LIBCUPSORDER) \ + $(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + $(RM) libcups.dylib + $(LN) $@ libcups.dylib + + +# +# libcups_s.a +# + +libcups_s.a: $(LIBOBJS) libcups_s.exp + echo Creating $@... + $(DSO) $(DSOFLAGS) -Wl,-bexport:libcups_s.exp -o libcups_s.o \ + $(LIBOBJS) $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) -lm + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcups_s.o + + +# +# libcups.la +# + +libcups.la: $(LIBOBJS) + echo Linking $@... + $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) \ + -rpath $(LIBDIR) -version-info 2:8 $(LIBGSSAPI) $(SSLLIBS) \ + $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# libcups.a +# + +libcups.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# testadmin (dependency on static CUPS library is intentional) +# + +testadmin: testadmin.o libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testadmin.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# testarray (dependency on static CUPS library is intentional) +# + +testarray: testarray.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testarray.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running array API tests... + ./testarray + + +# +# testconflicts (dependency on static CUPS library is intentional) +# + +testconflicts: testconflicts.o libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testconflicts.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# testcups (dependency on static CUPS library is intentional) +# + +testcups: testcups.o libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testcups.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# testfile (dependency on static CUPS library is intentional) +# + +testfile: testfile.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testfile.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running file API tests... + ./testfile + + +# +# testhttp (dependency on static CUPS library is intentional) +# + +testhttp: testhttp.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testhttp.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running HTTP API tests... + ./testhttp + + +# +# testipp (dependency on static CUPS library is intentional) +# + +testipp: testipp.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testipp.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running IPP API tests... + ./testipp + + +# +# testi18n (dependency on static CUPS library is intentional) +# + +testi18n: testi18n.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testi18n.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running internationalization API tests... + ./testi18n + + +# +# testlang (dependency on static CUPS library is intentional) +# + +testlang: testlang.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testlang.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running language API tests... + ./testlang + + +# +# testoptions (dependency on static CUPS library is intentional) +# + +testoptions: testoptions.o libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testoptions.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running option API tests... + ./testoptions + + +# +# testppd (dependency on static CUPS library is intentional) +# + +testppd: testppd.o libcups.a test.ppd test2.ppd + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testppd.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running PPD API tests... + ./testppd + + +# +# testpwg (dependency on static CUPS library is intentional) +# + +testpwg: testpwg.o libcups.a test.ppd + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testpwg.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Running PWG API tests... + ./testpwg test.ppd + + +# +# testsnmp (dependency on static CUPS library is intentional) +# + +testsnmp: testsnmp.o libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testsnmp.o libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# Automatic API help files... +# + +apihelp: + echo Generating CUPS API help files... + mxmldoc --section "Programming" \ + --title "Introduction to CUPS Programming" \ + --css ../doc/cups-printable.css \ + --header api-overview.header --intro api-overview.shtml \ + >../doc/help/api-overview.html + mxmldoc --section "Programming" --title "Array API" \ + --css ../doc/cups-printable.css \ + --header api-array.header --intro api-array.shtml \ + api-array.xml \ + array.h array.c >../doc/help/api-array.html + mxmldoc --tokens help/api-array.html api-array.xml >../doc/help/api-array.tokens + $(RM) api-array.xml + mxmldoc --section "Programming" --title "CUPS API" \ + --css ../doc/cups-printable.css \ + --header api-cups.header --intro api-cups.shtml \ + api-cups.xml \ + cups.h adminutil.c dest.c language.c notify.c \ + options.c tempfile.c usersys.c \ + util.c >../doc/help/api-cups.html + mxmldoc --tokens help/api-cups.html api-cups.xml >../doc/help/api-cups.tokens + $(RM) api-cups.xml + mxmldoc --section "Programming" --title "File and Directory APIs" \ + --css ../doc/cups-printable.css \ + --header api-filedir.header --intro api-filedir.shtml \ + api-filedir.xml \ + file.h file.c dir.h dir.c >../doc/help/api-filedir.html + mxmldoc --tokens api-filedir.xml >../doc/help/api-filedir.tokens + $(RM) api-filedir.xml + mxmldoc --section "Programming" --title "PPD API" \ + --css ../doc/cups-printable.css \ + --header api-ppd.header --intro api-ppd.shtml \ + api-ppd.xml \ + ppd.h attr.c conflicts.c custom.c emit.c localize.c mark.c page.c \ + ppd.c >../doc/help/api-ppd.html + mxmldoc --tokens help/api-ppd.html api-ppd.xml >../doc/help/api-ppd.tokens + $(RM) api-ppd.xml + mxmldoc --section "Programming" --title "HTTP and IPP APIs" \ + --css ../doc/cups-printable.css \ + --header api-httpipp.header --intro api-httpipp.shtml \ + api-httpipp.xml \ + http.h ipp.h auth.c getdevices.c getputfile.c encode.c \ + http.c http-addr.c http-support.c ipp.c ipp-support.c \ + md5passwd.c request.c >../doc/help/api-httpipp.html + mxmldoc --tokens help/api-httpipp.html api-httpipp.xml >../doc/help/api-httpipp.tokens + $(RM) api-httpipp.xml + mxmldoc --section "Programming" \ + --title "Filter and Backend Programming" \ + --css ../doc/cups-printable.css \ + --header api-filter.header --intro api-filter.shtml \ + api-filter.xml \ + backchannel.c backend.h backend.c sidechannel.c sidechannel.h \ + >../doc/help/api-filter.html + mxmldoc --tokens help/api-filter.html api-filter.xml >../doc/help/api-filter.tokens + $(RM) api-filter.xml + +framedhelp: + echo Generating CUPS API help files... + mxmldoc --framed api-overview \ + --section "Programming" \ + --title "Introduction to CUPS Programming" \ + --css ../doc/cups-printable.css \ + --header api-overview.header --intro api-overview.shtml + mxmldoc --framed api-array \ + --section "Programming" --title "Array API" \ + --css ../doc/cups-printable.css \ + --header api-array.header --intro api-array.shtml \ + array.h array.c + mxmldoc --framed api-cups \ + --section "Programming" --title "CUPS API" \ + --css ../doc/cups-printable.css \ + --header api-cups.header --intro api-cups.shtml \ + cups.h adminutil.c dest.c language.c notify.c \ + options.c tempfile.c usersys.c \ + util.c + mxmldoc --framed api-filedir \ + --section "Programming" --title "File and Directory APIs" \ + --css ../doc/cups-printable.css \ + --header api-filedir.header --intro api-filedir.shtml \ + file.h file.c dir.h dir.c + mxmldoc --framed api-ppd \ + --section "Programming" --title "PPD API" \ + --css ../doc/cups-printable.css \ + --header api-ppd.header --intro api-ppd.shtml \ + ppd.h attr.c conflicts.c custom.c emit.c localize.c mark.c \ + page.c ppd.c + mxmldoc --framed api-httpipp \ + --section "Programming" --title "HTTP and IPP APIs" \ + --css ../doc/cups-printable.css \ + --header api-httpipp.header --intro api-httpipp.shtml \ + http.h ipp.h auth.c getdevices.c getputfile.c encode.c \ + http.c http-addr.c http-support.c ipp.c ipp-support.c \ + md5passwd.c request.c + mxmldoc --framed api-filter \ + --section "Programming" \ + --title "Filter and Backend Programming" \ + --css ../doc/cups-printable.css \ + --header api-filter.header --intro api-filter.shtml \ + backchannel.c backend.h backend.c sidechannel.c sidechannel.h + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/cups/adminutil.c b/cups/adminutil.c new file mode 100644 index 0000000000..c2d74c5017 --- /dev/null +++ b/cups/adminutil.c @@ -0,0 +1,2461 @@ +/* + * "$Id$" + * + * Administration utility API definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 2001-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsAdminCreateWindowsPPD() - Create the Windows PPD file for a printer. + * cupsAdminExportSamba() - Export a printer to Samba. + * cupsAdminGetServerSettings() - Get settings from the server. + * cupsAdminSetServerSettings() - Set settings on the server. + * do_samba_command() - Do a SAMBA command. + * get_cupsd_conf() - Get the current cupsd.conf file. + * invalidate_cupsd_cache() - Invalidate the cached cupsd.conf settings. + * write_option() - Write a CUPS option to a PPD file. + */ + +/* + * Include necessary headers... + */ + +#include "adminutil.h" +#include "globals.h" +#include "debug.h" +#include +#include +#include +#ifdef WIN32 +#else +# include +# include +#endif /* WIN32 */ + + +/* + * Local functions... + */ + +static int do_samba_command(const char *command, + const char *address, + const char *subcommand, + const char *authfile, + FILE *logfile); +static http_status_t get_cupsd_conf(http_t *http, _cups_globals_t *cg, + time_t last_update, char *name, + int namelen, int *remote); +static void invalidate_cupsd_cache(_cups_globals_t *cg); +static void write_option(cups_file_t *dstfp, int order, + const char *name, const char *text, + const char *attrname, + ipp_attribute_t *suppattr, + ipp_attribute_t *defattr, int defval, + int valcount); + + +/* + * 'cupsAdminCreateWindowsPPD()' - Create the Windows PPD file for a printer. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - PPD file or NULL */ +cupsAdminCreateWindowsPPD( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *dest, /* I - Printer or class */ + char *buffer, /* I - Filename buffer */ + int bufsize) /* I - Size of filename buffer */ +{ + const char *src; /* Source PPD filename */ + cups_file_t *srcfp, /* Source PPD file */ + *dstfp; /* Destination PPD file */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *suppattr, /* IPP -supported attribute */ + *defattr; /* IPP -default attribute */ + cups_lang_t *language; /* Current language */ + char line[256], /* Line from PPD file */ + junk[256], /* Extra junk to throw away */ + *ptr, /* Pointer into line */ + uri[1024], /* Printer URI */ + option[41], /* Option */ + choice[41]; /* Choice */ + int jcloption, /* In a JCL option? */ + jclorder, /* Next JCL order dependency */ + linenum; /* Current line number */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + static const char * const pattrs[] = /* Printer attributes we want */ + { + "job-hold-until-supported", + "job-hold-until-default", + "job-sheets-supported", + "job-sheets-default", + "job-priority-supported", + "job-priority-default" + }; + + + /* + * Range check the input... + */ + + if (buffer) + *buffer = '\0'; + + if (!http) + http = _cupsConnect(); + + if (!http || !dest || !buffer || bufsize < 2) + return (NULL); + + /* + * Get the PPD file... + */ + + if ((src = cupsGetPPD2(http, dest)) == NULL) + return (NULL); + + /* + * Get the supported banner pages, etc. for the printer... + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", dest); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, uri); + + 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... + */ + + response = cupsDoRequest(http, request, "/"); + if (!response || cupsLastError() > IPP_OK_CONFLICT) + { + unlink(src); + return (NULL); + } + + /* + * Open the original PPD file... + */ + + if ((srcfp = cupsFileOpen(src, "rb")) == NULL) + return (NULL); + + /* + * Create a temporary output file using the destination buffer... + */ + + if ((dstfp = cupsTempFile2(buffer, bufsize)) == NULL) + { + cupsFileClose(srcfp); + + unlink(src); + + return (NULL); + } + + /* + * Write a new header explaining that this isn't the original PPD... + */ + + cupsFilePuts(dstfp, "*PPD-Adobe: \"4.3\"\n"); + + curtime = time(NULL); + curdate = gmtime(&curtime); + + cupsFilePrintf(dstfp, "*%% Modified on %04d%02d%02d%02d%02d%02d+0000 " + "for CUPS Windows Driver\n", + curdate->tm_year + 1900, curdate->tm_mon + 1, curdate->tm_mday, + curdate->tm_hour, curdate->tm_min, curdate->tm_sec); + + /* + * Read the existing PPD file, converting all PJL commands to CUPS + * job ticket comments... + */ + + jcloption = 0; + jclorder = 0; + linenum = 0; + language = cupsLangDefault(); + + while (cupsFileGets(srcfp, line, sizeof(line))) + { + linenum ++; + + if (!strncmp(line, "*PPD-Adobe:", 11)) + { + /* + * Already wrote the PPD header... + */ + + continue; + } + else if (!strncmp(line, "*JCLBegin:", 10) || + !strncmp(line, "*JCLToPSInterpreter:", 20) || + !strncmp(line, "*JCLEnd:", 8) || + !strncmp(line, "*Protocols:", 11)) + { + /* + * Don't use existing JCL keywords; we'll create our own, below... + */ + + cupsFilePrintf(dstfp, "*%% Commented out for CUPS Windows Driver...\n" + "*%%%s\n", line + 1); + continue; + } + else if (!strncmp(line, "*JCLOpenUI", 10)) + { + jcloption = 1; + cupsFilePrintf(dstfp, "%s\n", line); + } + else if (!strncmp(line, "*JCLCloseUI", 11)) + { + jcloption = 0; + cupsFilePrintf(dstfp, "%s\n", line); + } + else if (jcloption && !strncmp(line, "*OrderDependency:", 17)) + { + for (ptr = line + 17; _cups_isspace(*ptr); ptr ++); + + ptr = strchr(ptr, ' '); + + if (ptr) + { + cupsFilePrintf(dstfp, "*OrderDependency: %d%s\n", jclorder, ptr); + jclorder ++; + } + else + cupsFilePrintf(dstfp, "%s\n", line); + } + else if (jcloption && + strncmp(line, "*End", 4) && + strncmp(line, "*Default", 8)) + { + if ((ptr = strchr(line, ':')) == NULL) + { + snprintf(line, sizeof(line), + _cupsLangString(language, _("Missing value on line %d!")), + linenum); + _cupsSetError(IPP_DOCUMENT_FORMAT_ERROR, line, 0); + + cupsFileClose(srcfp); + cupsFileClose(dstfp); + + unlink(src); + unlink(buffer); + + *buffer = '\0'; + + return (NULL); + } + + if ((ptr = strchr(ptr, '\"')) == NULL) + { + snprintf(line, sizeof(line), + _cupsLangString(language, + _("Missing double quote on line %d!")), + linenum); + _cupsSetError(IPP_DOCUMENT_FORMAT_ERROR, line, 0); + + cupsFileClose(srcfp); + cupsFileClose(dstfp); + + unlink(src); + unlink(buffer); + + *buffer = '\0'; + + return (NULL); + } + + if (sscanf(line, "*%40s%*[ \t]%40[^:/]", option, choice) != 2) + { + snprintf(line, sizeof(line), + _cupsLangString(language, + _("Bad option + choice on line %d!")), + linenum); + _cupsSetError(IPP_DOCUMENT_FORMAT_ERROR, line, 0); + + cupsFileClose(srcfp); + cupsFileClose(dstfp); + + unlink(src); + unlink(buffer); + + *buffer = '\0'; + + return (NULL); + } + + if (strchr(ptr + 1, '\"') == NULL) + { + /* + * Skip remaining... + */ + + while (cupsFileGets(srcfp, junk, sizeof(junk)) != NULL) + { + linenum ++; + + if (!strncmp(junk, "*End", 4)) + break; + } + } + + snprintf(ptr + 1, sizeof(line) - (ptr - line + 1), + "%%cupsJobTicket: %s=%s\n\"\n*End", option, choice); + + cupsFilePrintf(dstfp, "*%% Changed for CUPS Windows Driver...\n%s\n", + line); + } + else + cupsFilePrintf(dstfp, "%s\n", line); + } + + cupsFileClose(srcfp); + unlink(src); + + if (linenum == 0) + { + _cupsSetError(IPP_DOCUMENT_FORMAT_ERROR, _("Empty PPD file!"), 1); + + cupsFileClose(dstfp); + unlink(buffer); + + *buffer = '\0'; + + return (NULL); + } + + /* + * Now add the CUPS-specific attributes and options... + */ + + cupsFilePuts(dstfp, "\n*% CUPS Job Ticket support and options...\n"); + cupsFilePuts(dstfp, "*Protocols: PJL\n"); + cupsFilePuts(dstfp, "*JCLBegin: \"%!PS-Adobe-3.0<0A>\"\n"); + cupsFilePuts(dstfp, "*JCLToPSInterpreter: \"\"\n"); + cupsFilePuts(dstfp, "*JCLEnd: \"\"\n"); + + cupsFilePuts(dstfp, "\n*OpenGroup: CUPS/CUPS Options\n\n"); + + if ((defattr = ippFindAttribute(response, "job-hold-until-default", + IPP_TAG_ZERO)) != NULL && + (suppattr = ippFindAttribute(response, "job-hold-until-supported", + IPP_TAG_ZERO)) != NULL) + write_option(dstfp, jclorder ++, "cupsJobHoldUntil", "Hold Until", + "job-hold-until", suppattr, defattr, 0, 1); + + if ((defattr = ippFindAttribute(response, "job-priority-default", + IPP_TAG_INTEGER)) != NULL && + (suppattr = ippFindAttribute(response, "job-priority-supported", + IPP_TAG_RANGE)) != NULL) + write_option(dstfp, jclorder ++, "cupsJobPriority", "Priority", + "job-priority", suppattr, defattr, 0, 1); + + if ((defattr = ippFindAttribute(response, "job-sheets-default", + IPP_TAG_ZERO)) != NULL && + (suppattr = ippFindAttribute(response, "job-sheets-supported", + IPP_TAG_ZERO)) != NULL) + { + write_option(dstfp, jclorder ++, "cupsJobSheetsStart", "Start Banner", + "job-sheets", suppattr, defattr, 0, 2); + write_option(dstfp, jclorder, "cupsJobSheetsEnd", "End Banner", + "job-sheets", suppattr, defattr, 1, 2); + } + + cupsFilePuts(dstfp, "*CloseGroup: CUPS\n"); + cupsFileClose(dstfp); + + ippDelete(response); + + return (buffer); +} + + +/* + * 'cupsAdminExportSamba()' - Export a printer to Samba. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsAdminExportSamba( + const char *dest, /* I - Destination to export */ + const char *ppd, /* I - PPD file */ + const char *samba_server, /* I - Samba server */ + const char *samba_user, /* I - Samba username */ + const char *samba_password, /* I - Samba password */ + FILE *logfile) /* I - Log file, if any */ +{ + int status; /* Status of Samba commands */ + int have_drivers; /* Have drivers? */ + char file[1024], /* File to test for */ + authfile[1024], /* Temporary authentication file */ + address[1024], /* Address for command */ + subcmd[1024], /* Sub-command */ + message[1024]; /* Error message */ + cups_file_t *fp; /* Authentication file */ + cups_lang_t *language; /* Current language */ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + /* + * Range check input... + */ + + if (!dest || !ppd || !samba_server || !samba_user || !samba_password) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + return (0); + } + + /* + * Create a temporary authentication file for Samba... + */ + + if ((fp = cupsTempFile2(authfile, sizeof(authfile))) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + return (0); + } + + cupsFilePrintf(fp, "username = %s\n", samba_user); + cupsFilePrintf(fp, "password = %s\n", samba_password); + cupsFileClose(fp); + + /* + * See which drivers are available; the new CUPS v6 and Adobe drivers + * depend on the Windows 2k PS driver, so copy that driver first: + * + * Files: + * + * ps5ui.dll + * pscript.hlp + * pscript.ntf + * pscript5.dll + */ + + have_drivers = 0; + language = cupsLangDefault(); + + snprintf(file, sizeof(file), "%s/drivers/pscript5.dll", cg->cups_datadir); + if (!access(file, 0)) + { + have_drivers |= 1; + + /* + * Windows 2k driver is installed; do the smbclient commands needed + * to copy the Win2k drivers over... + */ + + snprintf(address, sizeof(address), "//%s/print$", samba_server); + + snprintf(subcmd, sizeof(subcmd), + "mkdir W32X86;" + "put %s W32X86/%s.ppd;" + "put %s/drivers/ps5ui.dll W32X86/ps5ui.dll;" + "put %s/drivers/pscript.hlp W32X86/pscript.hlp;" + "put %s/drivers/pscript.ntf W32X86/pscript.ntf;" + "put %s/drivers/pscript5.dll W32X86/pscript5.dll", + ppd, dest, cg->cups_datadir, cg->cups_datadir, + cg->cups_datadir, cg->cups_datadir); + + if ((status = do_samba_command("smbclient", address, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to copy Windows 2000 printer " + "driver files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + + /* + * See if we also have the CUPS driver files; if so, use them! + */ + + snprintf(file, sizeof(file), "%s/drivers/cupsps6.dll", cg->cups_datadir); + if (!access(file, 0)) + { + /* + * Copy the CUPS driver files over... + */ + + snprintf(subcmd, sizeof(subcmd), + "put %s/drivers/cups6.ini W32X86/cups6.ini;" + "put %s/drivers/cupsps6.dll W32X86/cupsps6.dll;" + "put %s/drivers/cupsui6.dll W32X86/cupsui6.dll", + cg->cups_datadir, cg->cups_datadir, cg->cups_datadir); + + if ((status = do_samba_command("smbclient", address, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to copy CUPS printer driver " + "files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + + /* + * Do the rpcclient command needed for the CUPS drivers... + */ + + snprintf(subcmd, sizeof(subcmd), + "adddriver \"Windows NT x86\" \"%s:" + "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" + "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf," + "cups6.ini,cupsps6.dll,cupsui6.dll\"", + dest, dest, dest); + } + else + { + /* + * Don't have the CUPS drivers, so just use the standard Windows + * drivers... + */ + + snprintf(subcmd, sizeof(subcmd), + "adddriver \"Windows NT x86\" \"%s:" + "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" + "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf\"", + dest, dest, dest); + } + + if ((status = do_samba_command("rpcclient", samba_server, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to install Windows 2000 printer " + "driver files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + } + + /* + * See if we have the Win9x PS driver... + */ + + snprintf(file, sizeof(file), "%s/drivers/ADOBEPS4.DRV", cg->cups_datadir); + if (!access(file, 0)) + { + have_drivers |= 2; + + /* + * Do the smbclient commands needed for the Adobe Win9x drivers... + */ + + snprintf(address, sizeof(address), "//%s/print$", samba_server); + + 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/ICONLIB.DLL WIN40/ICONLIB.DLL;" + "put %s/drivers/PSMON.DLL WIN40/PSMON.DLL;", + ppd, dest, cg->cups_datadir, cg->cups_datadir, + cg->cups_datadir, cg->cups_datadir, cg->cups_datadir); + + if ((status = do_samba_command("smbclient", address, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to copy Windows 9x printer " + "driver files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + + /* + * 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," + "ICONLIB.DLL\"", + dest, dest, dest); + + if ((status = do_samba_command("rpcclient", samba_server, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to install Windows 9x printer " + "driver files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + } + + /* + * See if we have the 64-bit Windows PS driver... + * + * Files: + * + * x64/ps5ui.dll + * x64/pscript.hlp + * x64/pscript.ntf + * x64/pscript5.dll + */ + + snprintf(file, sizeof(file), "%s/drivers/x64/pscript5.dll", cg->cups_datadir); + if (!access(file, 0)) + { + have_drivers |= 4; + + /* + * 64-bit Windows driver is installed; do the smbclient commands needed + * to copy the Win64 drivers over... + */ + + snprintf(address, sizeof(address), "//%s/print$", samba_server); + + snprintf(subcmd, sizeof(subcmd), + "mkdir x64;" + "put %s x64/%s.ppd;" + "put %s/drivers/x64/ps5ui.dll x64/ps5ui.dll;" + "put %s/drivers/x64/pscript.hlp x64/pscript.hlp;" + "put %s/drivers/x64/pscript.ntf x64/pscript.ntf;" + "put %s/drivers/x64/pscript5.dll x64/pscript5.dll", + ppd, dest, cg->cups_datadir, cg->cups_datadir, + cg->cups_datadir, cg->cups_datadir); + + if ((status = do_samba_command("smbclient", address, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to copy 64-bit Windows printer " + "driver files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + + /* + * See if we also have the CUPS driver files; if so, use them! + */ + + snprintf(file, sizeof(file), "%s/drivers/x64/cupsps6.dll", cg->cups_datadir); + if (!access(file, 0)) + { + /* + * Copy the CUPS driver files over... + */ + + snprintf(subcmd, sizeof(subcmd), + "put %s/drivers/x64/cups6.ini x64/cups6.ini;" + "put %s/drivers/x64/cupsps6.dll x64/cupsps6.dll;" + "put %s/drivers/x64/cupsui6.dll x64/cupsui6.dll", + cg->cups_datadir, cg->cups_datadir, cg->cups_datadir); + + if ((status = do_samba_command("smbclient", address, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to copy 64-bit CUPS printer driver " + "files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + + /* + * Do the rpcclient command needed for the CUPS drivers... + */ + + snprintf(subcmd, sizeof(subcmd), + "adddriver \"Windows x64\" \"%s:" + "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" + "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf," + "cups6.ini,cupsps6.dll,cupsui6.dll\"", + dest, dest, dest); + } + else + { + /* + * Don't have the CUPS drivers, so just use the standard Windows + * drivers... + */ + + snprintf(subcmd, sizeof(subcmd), + "adddriver \"Windows x64\" \"%s:" + "pscript5.dll:%s.ppd:ps5ui.dll:pscript.hlp:NULL:RAW:" + "pscript5.dll,%s.ppd,ps5ui.dll,pscript.hlp,pscript.ntf\"", + dest, dest, dest); + } + + if ((status = do_samba_command("rpcclient", samba_server, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to install Windows 2000 printer " + "driver files (%d)!")), status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + } + + if (logfile && !(have_drivers & 1)) + { + if (!have_drivers) + strlcpy(message, + _cupsLangString(language, + _("No Windows printer drivers are installed!")), + sizeof(message)); + else + strlcpy(message, + _cupsLangString(language, + _("Warning, no Windows 2000 printer drivers " + "are installed!")), + sizeof(message)); + + _cupsSetError(IPP_NOT_FOUND, message, 0); + _cupsLangPrintf(logfile, "%s\n", message); + } + + if (have_drivers == 0) + { + _cupsSetError(IPP_NOT_FOUND, message, 0); + + unlink(authfile); + + return (0); + } + + /* + * Finally, associate the drivers we just added with the queue... + */ + + snprintf(subcmd, sizeof(subcmd), "setdriver %s %s", dest, dest); + + if ((status = do_samba_command("rpcclient", samba_server, subcmd, + authfile, logfile)) != 0) + { + snprintf(message, sizeof(message), + _cupsLangString(language, + _("Unable to set Windows printer driver (%d)!")), + status); + + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + if (logfile) + _cupsLangPrintf(logfile, "%s\n", message); + + unlink(authfile); + + return (0); + } + + unlink(authfile); + + return (1); +} + + +/* + * 'cupsAdminGetServerSettings()' - Get settings from the server. + * + * The returned settings should be freed with cupsFreeOptions() when + * you are done with them. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsAdminGetServerSettings( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + int *num_settings, /* O - Number of settings */ + cups_option_t **settings) /* O - Settings */ +{ + int i; /* Looping var */ + cups_file_t *cupsd; /* cupsd.conf file */ + char cupsdconf[1024]; /* cupsd.conf filename */ + int remote; /* Remote cupsd.conf file? */ + http_status_t status; /* Status of getting cupsd.conf */ + char line[1024], /* Line from cupsd.conf file */ + *value; /* Value on line */ + cups_option_t *setting; /* Current setting */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + /* + * Range check input... + */ + + if (!http) + { + /* + * See if we are connected to the same server... + */ + + if (cg->http) + { + /* + * Compare the connection hostname, port, and encryption settings to + * the cached defaults; these were initialized the first time we + * connected... + */ + + if (strcmp(cg->http->hostname, cg->server) || + cg->ipp_port != _httpAddrPort(cg->http->hostaddr) || + (cg->http->encryption != cg->encryption && + cg->http->encryption == HTTP_ENCRYPT_NEVER)) + { + /* + * Need to close the current connection because something has changed... + */ + + httpClose(cg->http); + cg->http = NULL; + } + } + + /* + * (Re)connect as needed... + */ + + if (!cg->http) + { + if ((cg->http = _httpCreate(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + if (errno) + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + else + _cupsSetError(IPP_SERVICE_UNAVAILABLE, + _("Unable to connect to host."), 1); + + if (num_settings) + *num_settings = 0; + + if (settings) + *settings = NULL; + + return (0); + } + } + + http = cg->http; + } + + if (!http || !num_settings || !settings) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + if (num_settings) + *num_settings = 0; + + if (settings) + *settings = NULL; + + return (0); + } + + *num_settings = 0; + *settings = NULL; + + /* + * Get the cupsd.conf file... + */ + + if ((status = get_cupsd_conf(http, cg, cg->cupsd_update, cupsdconf, + sizeof(cupsdconf), &remote)) == HTTP_OK) + { + if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL) + { + char message[1024]; /* Message string */ + + + snprintf(message, sizeof(message), + _cupsLangString(cupsLangDefault(), _("Open of %s failed: %s")), + cupsdconf, strerror(errno)); + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + } + } + else + cupsd = NULL; + + if (cupsd) + { + /* + * Read the file, keeping track of what settings are enabled... + */ + + int remote_access = 0, /* Remote access allowed? */ + remote_admin = 0, /* Remote administration allowed? */ + remote_any = 0, /* Remote access from anywhere allowed? */ + browsing = 1, /* Browsing enabled? */ + browse_allow = 1, /* Browse address set? */ + browse_address = 0, /* Browse address set? */ + cancel_policy = 1, /* Cancel-job policy set? */ + debug_logging = 0; /* LogLevel debug set? */ + int linenum = 0, /* Line number in file */ + in_location = 0, /* In a location section? */ + in_policy = 0, /* In a policy section? */ + in_cancel_job = 0, /* In a cancel-job section? */ + in_admin_location = 0; /* In the /admin location? */ + + + invalidate_cupsd_cache(cg); + + cg->cupsd_update = time(NULL); + httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname)); + + while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum)) + { + if (!value && strncmp(line, "")) + { + in_policy = 0; + } + else if (!strcasecmp(line, "")) + { + in_cancel_job = 0; + } + else if (!strcasecmp(line, "Require") && in_cancel_job) + { + cancel_policy = 0; + } + else if (!strcasecmp(line, "")) + { + in_admin_location = 0; + in_location = 0; + } + else if (!strcasecmp(line, "Allow") && value && + strcasecmp(value, "localhost") && strcasecmp(value, "127.0.0.1") +#ifdef AF_LOCAL + && *value != '/' +#endif /* AF_LOCAL */ +#ifdef AF_INET6 + && strcmp(value, "::1") +#endif /* AF_INET6 */ + ) + { + if (in_admin_location) + remote_admin = 1; + else if (!strcasecmp(value, "all")) + remote_any = 1; + } + else if (line[0] != '<' && !in_location && !in_policy && + strcasecmp(line, "Allow") && + strcasecmp(line, "AuthType") && + strcasecmp(line, "Deny") && + strcasecmp(line, "Order") && + strcasecmp(line, "Require") && + strcasecmp(line, "Satisfy")) + cg->cupsd_num_settings = cupsAddOption(line, value, + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + } + + cupsFileClose(cupsd); + + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, + debug_logging ? "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, + (remote_access && remote_admin) ? + "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, + remote_any ? "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, + (browsing && browse_allow) ? + "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, + (remote_access && browsing && + browse_address) ? "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + + cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, + cancel_policy ? "1" : "0", + cg->cupsd_num_settings, + &(cg->cupsd_settings)); + } + else if (status != HTTP_NOT_MODIFIED) + invalidate_cupsd_cache(cg); + + /* + * Remove any temporary files and copy the settings array... + */ + + if (remote) + unlink(cupsdconf); + + for (i = cg->cupsd_num_settings, setting = cg->cupsd_settings; + i > 0; + i --, setting ++) + *num_settings = cupsAddOption(setting->name, setting->value, + *num_settings, settings); + + return (cg->cupsd_num_settings > 0); +} + + +/* + * 'cupsAdminSetServerSettings()' - Set settings on the server. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsAdminSetServerSettings( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + int num_settings, /* I - Number of settings */ + cups_option_t *settings) /* I - Settings */ +{ + int i; /* Looping var */ + http_status_t status; /* GET/PUT status */ + const char *server_port_env; /* SERVER_PORT env var */ + int server_port; /* IPP port for server */ + cups_file_t *cupsd; /* cupsd.conf file */ + char cupsdconf[1024]; /* cupsd.conf filename */ + int remote; /* Remote cupsd.conf file? */ + char tempfile[1024]; /* Temporary new cupsd.conf */ + cups_file_t *temp; /* Temporary file */ + char line[1024], /* Line from cupsd.conf file */ + *value; /* Value on line */ + int linenum, /* Line number in file */ + in_location, /* In a location section? */ + in_policy, /* In a policy section? */ + in_default_policy, /* In the default policy section? */ + in_cancel_job, /* In a cancel-job section? */ + in_admin_location, /* In the /admin location? */ + in_conf_location, /* In the /admin/conf location? */ + in_root_location; /* In the / location? */ + const char *val; /* Setting value */ + int remote_printers, /* Show remote printers */ + share_printers, /* Share local printers */ + remote_admin, /* Remote administration allowed? */ + remote_any, /* Remote access from anywhere? */ + user_cancel_any, /* Cancel-job policy set? */ + debug_logging; /* LogLevel debug set? */ + int wrote_port_listen, /* Wrote the port/listen lines? */ + wrote_browsing, /* Wrote the browsing lines? */ + wrote_policy, /* Wrote the policy? */ + wrote_loglevel, /* Wrote the LogLevel line? */ + wrote_admin_location, /* Wrote the /admin location? */ + wrote_conf_location, /* Wrote the /admin/conf location? */ + wrote_root_location; /* Wrote the / location? */ + int indent; /* Indentation */ + int cupsd_num_settings; /* New number of settings */ + int old_remote_printers, /* Show remote printers */ + old_share_printers, /* Share local printers */ + old_remote_admin, /* Remote administration allowed? */ + old_user_cancel_any, /* Cancel-job policy set? */ + old_debug_logging; /* LogLevel debug set? */ + cups_option_t *cupsd_settings, /* New settings */ + *setting; /* Current setting */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + /* + * Range check input... + */ + + if (!http) + http = _cupsConnect(); + + if (!http || !num_settings || !settings) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (0); + } + + /* + * Get the cupsd.conf file... + */ + + if (get_cupsd_conf(http, cg, 0, cupsdconf, sizeof(cupsdconf), + &remote) == HTTP_OK) + { + if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + return (0); + } + } + else + return (0); + + /* + * Get current settings... + */ + + if (!cupsAdminGetServerSettings(http, &cupsd_num_settings, + &cupsd_settings)) + return (0); + + if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, cupsd_num_settings, + cupsd_settings)) != NULL) + old_debug_logging = atoi(val); + else + old_debug_logging = 0; + + DEBUG_printf(("1cupsAdminSetServerSettings: old debug_logging=%d", + old_debug_logging)); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, cupsd_num_settings, + cupsd_settings)) != NULL) + old_remote_admin = atoi(val); + else + old_remote_admin = 0; + + DEBUG_printf(("1cupsAdminSetServerSettings: old remote_admin=%d", + old_remote_admin)); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, cupsd_num_settings, + cupsd_settings)) != NULL) + remote_any = atoi(val); + else + remote_any = 0; + + DEBUG_printf(("1cupsAdminSetServerSettings: old remote_any=%d", + remote_any)); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, cupsd_num_settings, + cupsd_settings)) != NULL) + old_remote_printers = atoi(val); + else + old_remote_printers = 1; + + DEBUG_printf(("1cupsAdminSetServerSettings: old remote_printers=%d", + old_remote_printers)); + + if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, cupsd_num_settings, + cupsd_settings)) != NULL) + old_share_printers = atoi(val); + else + old_share_printers = 0; + + DEBUG_printf(("1cupsAdminSetServerSettings: old share_printers=%d", + old_share_printers)); + + if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, cupsd_num_settings, + cupsd_settings)) != NULL) + old_user_cancel_any = atoi(val); + else + old_user_cancel_any = 0; + + DEBUG_printf(("1cupsAdminSetServerSettings: old user_cancel_any=%d", + old_user_cancel_any)); + + cupsFreeOptions(cupsd_num_settings, cupsd_settings); + + /* + * Get basic settings... + */ + + if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings, + settings)) != NULL) + { + debug_logging = atoi(val); + + if (debug_logging == old_debug_logging) + { + /* + * No change to this setting... + */ + + debug_logging = -1; + } + } + else + debug_logging = -1; + + DEBUG_printf(("1cupsAdminSetServerSettings: debug_logging=%d", + debug_logging)); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, + settings)) != NULL) + remote_any = atoi(val); + + DEBUG_printf(("1cupsAdminSetServerSettings: remote_any=%d", + remote_any)); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings, + settings)) != NULL) + { + remote_admin = atoi(val); + + if (remote_admin == old_remote_admin) + { + /* + * No change to this setting... + */ + + remote_admin = -1; + } + } + else + remote_admin = -1; + + DEBUG_printf(("1cupsAdminSetServerSettings: remote_admin=%d", + remote_admin)); + + if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings, + settings)) != NULL) + { + remote_printers = atoi(val); + + if (remote_printers == old_remote_printers) + { + /* + * No change to this setting... + */ + + remote_printers = -1; + } + } + else + remote_printers = -1; + + DEBUG_printf(("1cupsAdminSetServerSettings: remote_printers=%d", + remote_printers)); + + if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings, + settings)) != NULL) + { + share_printers = atoi(val); + + if (share_printers == old_share_printers) + { + /* + * No change to this setting... + */ + + share_printers = -1; + } + } + else + share_printers = -1; + + DEBUG_printf(("1cupsAdminSetServerSettings: share_printers=%d", + share_printers)); + + if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings, + settings)) != NULL) + { + user_cancel_any = atoi(val); + + if (user_cancel_any == old_user_cancel_any) + { + /* + * No change to this setting... + */ + + user_cancel_any = -1; + } + } + else + user_cancel_any = -1; + + DEBUG_printf(("1cupsAdminSetServerSettings: user_cancel_any=%d", + user_cancel_any)); + + /* + * Create a temporary file for the new cupsd.conf file... + */ + + if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL) + { + cupsFileClose(cupsd); + + if (remote) + unlink(cupsdconf); + + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + return (0); + } + + /* + * Copy the old file to the new, making changes along the way... + */ + + cupsd_num_settings = 0; + in_admin_location = 0; + in_cancel_job = 0; + in_conf_location = 0; + in_default_policy = 0; + in_location = 0; + in_policy = 0; + in_root_location = 0; + linenum = 0; + wrote_admin_location = 0; + wrote_browsing = 0; + wrote_conf_location = 0; + wrote_loglevel = 0; + wrote_policy = 0; + wrote_port_listen = 0; + wrote_root_location = 0; + indent = 0; + + if ((server_port_env = getenv("SERVER_PORT")) != NULL) + { + if ((server_port = atoi(server_port_env)) <= 0) + server_port = ippPort(); + } + else + server_port = ippPort(); + + if (server_port <= 0) + server_port = IPP_PORT; + + while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum)) + { + if ((!strcasecmp(line, "Port") || !strcasecmp(line, "Listen")) && + (remote_admin >= 0 || remote_any > 0 || share_printers >= 0)) + { + if (!wrote_port_listen) + { + wrote_port_listen = 1; + + if (remote_admin > 0 || remote_any > 0 || share_printers > 0) + { + cupsFilePuts(temp, "# Allow remote access\n"); + cupsFilePrintf(temp, "Port %d\n", server_port); + } + else + { + cupsFilePuts(temp, "# Only listen for connections from the local " + "machine.\n"); + cupsFilePrintf(temp, "Listen localhost:%d\n", server_port); + } + +#ifdef CUPS_DEFAULT_DOMAINSOCKET + if ((!value || strcmp(CUPS_DEFAULT_DOMAINSOCKET, value)) && + !access(CUPS_DEFAULT_DOMAINSOCKET, 0)) + cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n"); +#endif /* CUPS_DEFAULT_DOMAINSOCKET */ + } + else if (value && value[0] == '/' +#ifdef CUPS_DEFAULT_DOMAINSOCKET + && strcmp(CUPS_DEFAULT_DOMAINSOCKET, value) +#endif /* CUPS_DEFAULT_DOMAINSOCKET */ + ) + cupsFilePrintf(temp, "Listen %s\n", value); + } + else if ((!strcasecmp(line, "Browsing") || + !strcasecmp(line, "BrowseAddress") || + !strcasecmp(line, "BrowseAllow") || + !strcasecmp(line, "BrowseDeny") || + !strcasecmp(line, "BrowseLocalProtocols") || + !strcasecmp(line, "BrowseRemoteProtocols") || + !strcasecmp(line, "BrowseOrder")) && + (remote_printers >= 0 || share_printers >= 0)) + { + if (!wrote_browsing) + { + int new_remote_printers = (remote_printers > 0 || + (remote_printers == -1 && + old_remote_printers > 0)); + int new_share_printers = (share_printers > 0 || + (share_printers == -1 && + old_share_printers > 0)); + + wrote_browsing = 1; + + if (new_remote_printers || new_share_printers) + { + const char *localp = cupsGetOption("BrowseLocalProtocols", + num_settings, settings); + const char *remotep = cupsGetOption("BrowseRemoteProtocols", + num_settings, settings); + + if (!localp || !localp[0]) + localp = cupsGetOption("BrowseLocalProtocols", cupsd_num_settings, + cupsd_settings); + + if (!remotep) + remotep = cupsGetOption("BrowseRemoteProtocols", cupsd_num_settings, + cupsd_settings); + + if (new_remote_printers && new_share_printers) + cupsFilePuts(temp, + "# Enable printer sharing and shared printers.\n"); + else if (new_remote_printers) + cupsFilePuts(temp, + "# Show shared printers on the local network.\n"); + else + cupsFilePuts(temp, + "# Share local printers on the local network.\n"); + + cupsFilePuts(temp, "Browsing On\n"); + cupsFilePuts(temp, "BrowseOrder allow,deny\n"); + + if (new_remote_printers) + { + cupsFilePuts(temp, "BrowseAllow all\n"); + + if (!remotep) + remotep = CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS; + + cupsFilePrintf(temp, "BrowseRemoteProtocols %s\n", remotep); + } + else + cupsFilePuts(temp, "BrowseRemoteProtocols\n"); + + cupsd_num_settings = cupsAddOption("BrowseRemoteProtocols", remotep, + cupsd_num_settings, + &cupsd_settings); + + if (new_share_printers) + { + cupsFilePuts(temp, "BrowseAddress @LOCAL\n"); + + if (!localp) + localp = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS; + + cupsFilePrintf(temp, "BrowseLocalProtocols %s\n", localp); + } + else + cupsFilePuts(temp, "BrowseLocalProtocols\n"); + + cupsd_num_settings = cupsAddOption("BrowseLocalProtocols", localp, + cupsd_num_settings, + &cupsd_settings); + } + else + { + cupsFilePuts(temp, + "# Disable printer sharing and shared printers.\n"); + cupsFilePuts(temp, "Browsing Off\n"); + } + } + } + else if (!strcasecmp(line, "LogLevel") && debug_logging >= 0) + { + wrote_loglevel = 1; + + if (debug_logging) + { + cupsFilePuts(temp, + "# Show troubleshooting information in error_log.\n"); + cupsFilePuts(temp, "LogLevel debug\n"); + } + else + { + cupsFilePuts(temp, "# Show general information in error_log.\n"); + cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n"); + } + } + else if (!strcasecmp(line, "\n", line, value); + indent += 2; + } + else if (!strcasecmp(line, "")) + { + indent -= 2; + if (!wrote_policy && in_default_policy) + { + wrote_policy = 1; + + if (!user_cancel_any) + cupsFilePuts(temp, " # Only the owner or an administrator can " + "cancel a job...\n" + " \n" + " Order deny,allow\n" + " Require user @OWNER " + CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n" + " \n"); + } + + in_policy = 0; + in_default_policy = 0; + + cupsFilePuts(temp, "\n"); + } + else if (!strcasecmp(line, "\n", line, value); + } + else if (!strcasecmp(line, "")) + { + in_location = 0; + indent -= 2; + if (in_admin_location && remote_admin >= 0) + { + wrote_admin_location = 1; + + if (remote_admin) + cupsFilePuts(temp, " # Allow remote administration...\n"); + else if (remote_admin == 0) + cupsFilePuts(temp, " # Restrict access to the admin pages...\n"); + + cupsFilePuts(temp, " Order allow,deny\n"); + + if (remote_admin) + cupsFilePrintf(temp, " Allow %s\n", + remote_any > 0 ? "all" : "@LOCAL"); + } + else if (in_conf_location && remote_admin >= 0) + { + wrote_conf_location = 1; + + if (remote_admin) + cupsFilePuts(temp, " # Allow remote access to the configuration " + "files...\n"); + else + cupsFilePuts(temp, " # Restrict access to the configuration " + "files...\n"); + + cupsFilePuts(temp, " Order allow,deny\n"); + + if (remote_admin) + cupsFilePrintf(temp, " Allow %s\n", + remote_any > 0 ? "all" : "@LOCAL"); + } + else if (in_root_location && + (remote_admin >= 0 || remote_any > 0 || share_printers >= 0)) + { + wrote_root_location = 1; + + if (remote_admin > 0 && share_printers > 0) + cupsFilePuts(temp, " # Allow shared printing and remote " + "administration...\n"); + else if (remote_admin > 0) + cupsFilePuts(temp, " # Allow remote administration...\n"); + else if (share_printers > 0) + cupsFilePuts(temp, " # Allow shared printing...\n"); + else if (remote_any > 0) + cupsFilePuts(temp, " # Allow remote access...\n"); + else + cupsFilePuts(temp, " # Restrict access to the server...\n"); + + cupsFilePuts(temp, " Order allow,deny\n"); + + if (remote_admin > 0 || remote_any > 0 || share_printers > 0) + cupsFilePrintf(temp, " Allow %s\n", + remote_any > 0 ? "all" : "@LOCAL"); + } + + in_admin_location = 0; + in_conf_location = 0; + in_root_location = 0; + + cupsFilePuts(temp, "\n"); + } + else if (!strcasecmp(line, "= 0) + { + /* + * Don't write anything for this limit section... + */ + + in_cancel_job = 2; + } + else + { + cupsFilePrintf(temp, "%*s%s", indent, "", line); + + while (*value) + { + for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++); + + if (*valptr) + *valptr++ = '\0'; + + if (!strcasecmp(value, "cancel-job") && user_cancel_any >= 0) + { + /* + * Write everything except for this definition... + */ + + in_cancel_job = 1; + } + else + cupsFilePrintf(temp, " %s", value); + + for (value = valptr; _cups_isspace(*value); value ++); + } + + cupsFilePuts(temp, ">\n"); + } + } + else + cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value); + + indent += 2; + } + else if (!strcasecmp(line, "
") && in_cancel_job) + { + indent -= 2; + + if (in_cancel_job == 1) + cupsFilePuts(temp, " \n"); + + wrote_policy = 1; + + if (!user_cancel_any) + cupsFilePuts(temp, " # Only the owner or an administrator can cancel " + "a job...\n" + " \n" + " Order deny,allow\n" + " Require user @OWNER " + CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n" + " \n"); + + in_cancel_job = 0; + } + else if ((((in_admin_location || in_conf_location || in_root_location) && + (remote_admin >= 0 || remote_any > 0)) || + (in_root_location && share_printers >= 0)) && + (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny") || + !strcasecmp(line, "Order"))) + continue; + else if (in_cancel_job == 2) + continue; + else if (line[0] == '<') + { + if (value) + { + cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value); + indent += 2; + } + else + { + if (line[1] == '/') + indent -= 2; + + cupsFilePrintf(temp, "%*s%s\n", indent, "", line); + } + } + else if (!in_policy && !in_location && + (val = cupsGetOption(line, num_settings, settings)) != NULL) + { + /* + * Replace this directive's value with the new one... + */ + + cupsd_num_settings = cupsAddOption(line, val, cupsd_num_settings, + &cupsd_settings); + + /* + * Write the new value in its place, without indentation since we + * only support setting root directives, not in sections... + */ + + cupsFilePrintf(temp, "%s %s\n", line, val); + } + else if (value) + { + if (!in_policy && !in_location) + { + /* + * Record the non-policy, non-location directives that we find + * in the server settings, since we cache this info and record it + * in cupsAdminGetServerSettings()... + */ + + cupsd_num_settings = cupsAddOption(line, value, cupsd_num_settings, + &cupsd_settings); + } + + cupsFilePrintf(temp, "%*s%s %s\n", indent, "", line, value); + } + else + cupsFilePrintf(temp, "%*s%s\n", indent, "", line); + } + + /* + * Write any missing info... + */ + + if (!wrote_browsing && (remote_printers >= 0 || share_printers >= 0)) + { + if (remote_printers > 0 || share_printers > 0) + { + if (remote_printers > 0 && share_printers > 0) + cupsFilePuts(temp, "# Enable printer sharing and shared printers.\n"); + else if (remote_printers > 0) + cupsFilePuts(temp, "# Show shared printers on the local network.\n"); + else + cupsFilePuts(temp, "# Share local printers on the local network.\n"); + + cupsFilePuts(temp, "Browsing On\n"); + cupsFilePuts(temp, "BrowseOrder allow,deny\n"); + + if (remote_printers > 0) + cupsFilePuts(temp, "BrowseAllow all\n"); + + if (share_printers > 0) + cupsFilePuts(temp, "BrowseAddress @LOCAL\n"); + } + else + { + cupsFilePuts(temp, "# Disable printer sharing and shared printers.\n"); + cupsFilePuts(temp, "Browsing Off\n"); + } + } + + if (!wrote_loglevel && debug_logging >= 0) + { + if (debug_logging) + { + cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n"); + cupsFilePuts(temp, "LogLevel debug\n"); + } + else + { + cupsFilePuts(temp, "# Show general information in error_log.\n"); + cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n"); + } + } + + if (!wrote_port_listen && + (remote_admin >= 0 || remote_any > 0 || share_printers >= 0)) + { + if (remote_admin > 0 || remote_any > 0 || share_printers > 0) + { + cupsFilePuts(temp, "# Allow remote access\n"); + cupsFilePrintf(temp, "Port %d\n", ippPort()); + } + else + { + cupsFilePuts(temp, + "# Only listen for connections from the local machine.\n"); + cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort()); + } + +#ifdef CUPS_DEFAULT_DOMAINSOCKET + if (!access(CUPS_DEFAULT_DOMAINSOCKET, 0)) + cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n"); +#endif /* CUPS_DEFAULT_DOMAINSOCKET */ + } + + if (!wrote_root_location && + (remote_admin >= 0 || remote_any > 0 || share_printers >= 0)) + { + if (remote_admin > 0 && share_printers > 0) + cupsFilePuts(temp, + "# Allow shared printing and remote administration...\n"); + else if (remote_admin > 0) + cupsFilePuts(temp, "# Allow remote administration...\n"); + else if (share_printers > 0) + cupsFilePuts(temp, "# Allow shared printing...\n"); + else if (remote_any > 0) + cupsFilePuts(temp, "# Allow remote access...\n"); + else + cupsFilePuts(temp, "# Restrict access to the server...\n"); + + cupsFilePuts(temp, "\n" + " Order allow,deny\n"); + + if (remote_admin > 0 || remote_any > 0 || share_printers > 0) + cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); + + cupsFilePuts(temp, "\n"); + } + + if (!wrote_admin_location && remote_admin >= 0) + { + if (remote_admin) + cupsFilePuts(temp, "# Allow remote administration...\n"); + else + cupsFilePuts(temp, "# Restrict access to the admin pages...\n"); + + cupsFilePuts(temp, "\n" + " Order allow,deny\n"); + + if (remote_admin) + cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); + + cupsFilePuts(temp, "\n"); + } + + if (!wrote_conf_location && remote_admin >= 0) + { + if (remote_admin) + cupsFilePuts(temp, + "# Allow remote access to the configuration files...\n"); + else + cupsFilePuts(temp, "# Restrict access to the configuration files...\n"); + + cupsFilePuts(temp, "\n" + " AuthType Default\n" + " Require user @SYSTEM\n" + " Order allow,deny\n"); + + if (remote_admin) + cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); + + cupsFilePuts(temp, "\n"); + } + + if (!wrote_policy && user_cancel_any >= 0) + { + cupsFilePuts(temp, "\n" + " # Job-related operations must be done by the owner " + "or an administrator...\n" + " \n" + " Require user @OWNER @SYSTEM\n" + " Order deny,allow\n" + " \n" + " # All administration operations require an " + "administrator to authenticate...\n" + " \n" + " AuthType Default\n" + " Require user @SYSTEM\n" + " Order deny,allow\n" + "\n"); + + if (!user_cancel_any) + cupsFilePuts(temp, " # Only the owner or an administrator can cancel " + "a job...\n" + " \n" + " Order deny,allow\n" + " Require user @OWNER " + CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n" + " \n"); + + cupsFilePuts(temp, " \n" + " Order deny,allow\n" + " \n" + "\n"); + } + + for (i = num_settings, setting = settings; i > 0; i --, setting ++) + if (setting->name[0] != '_' && + strcasecmp(setting->name, "Listen") && + strcasecmp(setting->name, "Port") && + !cupsGetOption(setting->name, cupsd_num_settings, cupsd_settings)) + { + /* + * Add this directive to the list of directives we have written... + */ + + cupsd_num_settings = cupsAddOption(setting->name, setting->value, + cupsd_num_settings, &cupsd_settings); + + /* + * Write the new value, without indentation since we only support + * setting root directives, not in sections... + */ + + cupsFilePrintf(temp, "%s %s\n", setting->name, setting->value); + } + + cupsFileClose(cupsd); + cupsFileClose(temp); + + /* + * Upload the configuration file to the server... + */ + + status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile); + + if (status == HTTP_CREATED) + { + /* + * Updated OK, add the basic settings... + */ + + if (debug_logging >= 0) + cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, + debug_logging ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + else + cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, + old_debug_logging ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + + if (remote_admin >= 0) + cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, + remote_admin ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + else + cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, + old_remote_admin ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + + cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, + remote_any ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + + if (remote_printers >= 0) + cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, + remote_printers ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + else + cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, + old_remote_printers ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + + if (share_printers >= 0) + cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, + share_printers ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + else + cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, + old_share_printers ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + + if (user_cancel_any >= 0) + cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, + user_cancel_any ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + else + cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, + old_user_cancel_any ? "1" : "0", + cupsd_num_settings, &cupsd_settings); + + /* + * Save the new values... + */ + + invalidate_cupsd_cache(cg); + + cg->cupsd_num_settings = cupsd_num_settings; + cg->cupsd_settings = cupsd_settings; + cg->cupsd_update = time(NULL); + + httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname)); + } + else + cupsFreeOptions(cupsd_num_settings, cupsd_settings); + + /* + * Remote our temp files and return... + */ + + if (remote) + unlink(cupsdconf); + + unlink(tempfile); + + return (status == HTTP_CREATED); +} + + +/* + * 'do_samba_command()' - Do a SAMBA command. + */ + +static int /* O - Status of command */ +do_samba_command(const char *command, /* I - Command to run */ + const char *address, /* I - Address for command */ + const char *subcmd, /* I - Sub-command */ + const char *authfile, /* I - Samba authentication file */ + FILE *logfile) /* I - Optional log file */ +{ +#ifdef WIN32 + return (1); /* Always fail on Windows... */ + +#else + int status; /* Status of command */ + int pid; /* Process ID of child */ + + + if (logfile) + _cupsLangPrintf(logfile, + _("Running command: %s %s -N -A %s -c \'%s\'\n"), + command, address, authfile, subcmd); + + if ((pid = fork()) == 0) + { + /* + * Child goes here, redirect stdin/out/err and execute the command... + */ + + int fd = open("/dev/null", O_RDONLY); + + if (fd > 0) + { + dup2(fd, 0); + close(fd); + } + + if (logfile) + dup2(fileno(logfile), 1); + else if ((fd = open("/dev/null", O_WRONLY)) > 1) + { + dup2(fd, 1); + close(fd); + } + + dup2(1, 2); + + execlp(command, command, address, "-N", "-A", authfile, "-c", subcmd, + (char *)0); + exit(errno); + } + else if (pid < 0) + { + status = -1; + + if (logfile) + _cupsLangPrintf(logfile, _("Unable to run \"%s\": %s\n"), + command, strerror(errno)); + } + else + { + /* + * Wait for the process to complete... + */ + + while (wait(&status) != pid); + } + + if (logfile) + _cupsLangPuts(logfile, "\n"); + + DEBUG_printf(("9do_samba_command: status=%d", status)); + + if (WIFEXITED(status)) + return (WEXITSTATUS(status)); + else + return (-WTERMSIG(status)); +#endif /* WIN32 */ +} + + +/* + * 'get_cupsd_conf()' - Get the current cupsd.conf file. + */ + +static http_status_t /* O - Status of request */ +get_cupsd_conf( + http_t *http, /* I - Connection to server */ + _cups_globals_t *cg, /* I - Global data */ + time_t last_update, /* I - Last update time for file */ + char *name, /* I - Filename buffer */ + int namesize, /* I - Size of filename buffer */ + int *remote) /* O - Remote file? */ +{ + int fd; /* Temporary file descriptor */ +#ifndef WIN32 + struct stat info; /* cupsd.conf file information */ +#endif /* WIN32 */ + http_status_t status; /* Status of getting cupsd.conf */ + char host[HTTP_MAX_HOST]; /* Hostname for connection */ + + + /* + * See if we already have the data we need... + */ + + httpGetHostname(http, host, sizeof(host)); + + if (strcasecmp(cg->cupsd_hostname, host)) + invalidate_cupsd_cache(cg); + + snprintf(name, namesize, "%s/cupsd.conf", cg->cups_serverroot); + *remote = 0; + +#ifndef WIN32 + if (!strcasecmp(host, "localhost") && !access(name, R_OK)) + { + /* + * Read the local file rather than using HTTP... + */ + + if (stat(name, &info)) + { + char message[1024]; /* Message string */ + + + snprintf(message, sizeof(message), + _cupsLangString(cupsLangDefault(), _("stat of %s failed: %s")), + name, strerror(errno)); + _cupsSetError(IPP_INTERNAL_ERROR, message, 0); + + *name = '\0'; + + return (HTTP_SERVER_ERROR); + } + else if (last_update && info.st_mtime <= last_update) + status = HTTP_NOT_MODIFIED; + else + status = HTTP_OK; + } + else +#endif /* !WIN32 */ + { + /* + * Read cupsd.conf via a HTTP GET request... + */ + + if ((fd = cupsTempFd(name, namesize)) < 0) + { + *name = '\0'; + + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + + invalidate_cupsd_cache(cg); + + return (HTTP_SERVER_ERROR); + } + + *remote = 1; + + httpClearFields(http); + + if (last_update) + httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, + httpGetDateString(last_update)); + + status = cupsGetFd(http, "/admin/conf/cupsd.conf", fd); + + close(fd); + + if (status != HTTP_OK) + { + unlink(name); + *name = '\0'; + } + } + + return (status); +} + + +/* + * 'invalidate_cupsd_cache()' - Invalidate the cached cupsd.conf settings. + */ + +static void +invalidate_cupsd_cache( + _cups_globals_t *cg) /* I - Global data */ +{ + cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings); + + cg->cupsd_hostname[0] = '\0'; + cg->cupsd_update = 0; + cg->cupsd_num_settings = 0; + cg->cupsd_settings = NULL; +} + + +/* + * 'write_option()' - Write a CUPS option to a PPD file. + */ + +static void +write_option(cups_file_t *dstfp, /* I - PPD file */ + int order, /* I - Order dependency */ + const char *name, /* I - Option name */ + const char *text, /* I - Option text */ + const char *attrname, /* I - Attribute name */ + ipp_attribute_t *suppattr, /* I - IPP -supported attribute */ + ipp_attribute_t *defattr, /* I - IPP -default attribute */ + int defval, /* I - Default value number */ + int valcount) /* I - Number of values */ +{ + int i; /* Looping var */ + + + cupsFilePrintf(dstfp, "*JCLOpenUI *%s/%s: PickOne\n" + "*OrderDependency: %d JCLSetup *%s\n", + name, text, order, name); + + if (defattr->value_tag == IPP_TAG_INTEGER) + { + /* + * Do numeric options with a range or list... + */ + + cupsFilePrintf(dstfp, "*Default%s: %d\n", name, + defattr->values[defval].integer); + + if (suppattr->value_tag == IPP_TAG_RANGE) + { + /* + * List each number in the range... + */ + + for (i = suppattr->values[0].range.lower; + i <= suppattr->values[0].range.upper; + i ++) + { + cupsFilePrintf(dstfp, "*%s %d: \"", name, i); + + if (valcount == 1) + cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\n\"\n*End\n", + attrname, i); + else if (defval == 0) + cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\"\n", attrname, i); + else if (defval < (valcount - 1)) + cupsFilePrintf(dstfp, ",%d\"\n", i); + else + cupsFilePrintf(dstfp, ",%d\n\"\n*End\n", i); + } + } + else + { + /* + * List explicit numbers... + */ + + for (i = 0; i < suppattr->num_values; i ++) + { + cupsFilePrintf(dstfp, "*%s %d: \"", name, suppattr->values[i].integer); + + if (valcount == 1) + cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\n\"\n*End\n", attrname, + suppattr->values[i].integer); + else if (defval == 0) + cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%d\"\n", attrname, + suppattr->values[i].integer); + else if (defval < (valcount - 1)) + cupsFilePrintf(dstfp, ",%d\"\n", suppattr->values[i].integer); + else + cupsFilePrintf(dstfp, ",%d\n\"\n*End\n", suppattr->values[i].integer); + } + } + } + else + { + /* + * Do text options with a list... + */ + + cupsFilePrintf(dstfp, "*Default%s: %s\n", name, + defattr->values[defval].string.text); + + for (i = 0; i < suppattr->num_values; i ++) + { + cupsFilePrintf(dstfp, "*%s %s: \"", name, + suppattr->values[i].string.text); + + if (valcount == 1) + cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%s\n\"\n*End\n", attrname, + suppattr->values[i].string.text); + else if (defval == 0) + cupsFilePrintf(dstfp, "%%cupsJobTicket: %s=%s\"\n", attrname, + suppattr->values[i].string.text); + else if (defval < (valcount - 1)) + cupsFilePrintf(dstfp, ",%s\"\n", suppattr->values[i].string.text); + else + cupsFilePrintf(dstfp, ",%s\n\"\n*End\n", + suppattr->values[i].string.text); + } + } + + cupsFilePrintf(dstfp, "*JCLCloseUI: *%s\n\n", name); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/adminutil.h b/cups/adminutil.h new file mode 100644 index 0000000000..7562fe596f --- /dev/null +++ b/cups/adminutil.h @@ -0,0 +1,77 @@ +/* + * "$Id$" + * + * Administration utility API definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 2001-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_ADMINUTIL_H_ +# define _CUPS_ADMINUTIL_H_ + +/* + * Include necessary headers... + */ + +# include "cups.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Constants... + */ + +# define CUPS_SERVER_DEBUG_LOGGING "_debug_logging" +# define CUPS_SERVER_REMOTE_ADMIN "_remote_admin" +# define CUPS_SERVER_REMOTE_ANY "_remote_any" +# define CUPS_SERVER_REMOTE_PRINTERS "_remote_printers" +# define CUPS_SERVER_SHARE_PRINTERS "_share_printers" +# define CUPS_SERVER_USER_CANCEL_ANY "_user_cancel_any" + + +/* + * Functions... + */ + +extern int cupsAdminExportSamba(const char *dest, const char *ppd, + const char *samba_server, + const char *samba_user, + const char *samba_password, + FILE *logfile) _CUPS_API_1_2; +extern char *cupsAdminCreateWindowsPPD(http_t *http, const char *dest, + char *buffer, int bufsize) _CUPS_API_1_2; + +extern int cupsAdminGetServerSettings(http_t *http, + int *num_settings, + cups_option_t **settings) _CUPS_API_1_3; +extern int cupsAdminSetServerSettings(http_t *http, + int num_settings, + cups_option_t *settings) _CUPS_API_1_3; + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_ADMINUTIL_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/api-array.header b/cups/api-array.header new file mode 100644 index 0000000000..b9a734161d --- /dev/null +++ b/cups/api-array.header @@ -0,0 +1,34 @@ + + +

Array API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/array.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/cups/api-array.shtml b/cups/api-array.shtml new file mode 100644 index 0000000000..66effeb554 --- /dev/null +++ b/cups/api-array.shtml @@ -0,0 +1,177 @@ + + +

Overview

+ +

The CUPS array API provides a high-performance generic array container. +The contents of the array container can be sorted and the container itself is +designed for optimal speed and memory usage under a wide variety of conditions. +Sorted arrays use a binary search algorithm from the last found or inserted +element to quickly find matching elements in the array. Arrays created with the +optional hash function can often find elements with a single lookup. The +cups_array_t type is used when +referring to a CUPS array.

+ +

The CUPS scheduler (cupsd) and many of the CUPS API +functions use the array API to efficiently manage large lists of +data.

+ +

Managing Arrays

+ +

Arrays are created using either the +cupsArrayNew or +cupsArrayNew2 functions. The +first function creates a new array with the specified callback function +and user data pointer:

+ +
+#include <cups/array.h>
+
+static int compare_func(void *first, void *second, void *user_data);
+
+void *user_data;
+cups_array_t *array = cupsArrayNew(compare_func, user_data);
+
+ +

The comparison function (type +cups_arrayfunc_t) is called +whenever an element is added to the array and can be NULL to +create an unsorted array. The function returns -1 if the first element should +come before the second, 0 if the first and second elements should have the same +ordering, and 1 if the first element should come after the second.

+ +

The "user_data" pointer is passed to your comparison function. Pass +NULL if you do not need to associate the elements in your array +with additional information.

+ +

The cupsArrayNew2 function adds +two more arguments to support hashed lookups, which can potentially provide +instantaneous ("O(1)") lookups in your array:

+ +
+#include <cups/array.h>
+
+#define HASH_SIZE 512 /* Size of hash table */
+
+static int compare_func(void *first, void *second, void *user_data);
+static int hash_func(void *element, void *user_data);
+
+void *user_data;
+cups_array_t *array = cupsArrayNew2(compare_func, user_data, hash_func, HASH_SIZE);
+
+ +

The hash function (type +cups_ahash_func_t) should return a +number from 0 to (hash_size-1) that (hopefully) uniquely identifies the +element and is called whenever you look up an element in the array with +cupsArrayFind. The hash size is +only limited by available memory, but generally should not be larger than +16384 to realize any performance improvement.

+ +

Once you have created the array, you add elements using the +cupsArrayAdd +cupsArrayInsert functions. +The first function adds an element to the array, adding the new element +after any elements that have the same order, while the second inserts the +element before others with the same order. For unsorted arrays, +cupsArrayAdd appends the element to +the end of the array while +cupsArrayInsert inserts the +element at the beginning of the array. For example, the following code +creates a sorted array of character strings:

+ +
+#include <cups/array.h>
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+
+/* Add four strings to the array */
+cupsArrayAdd(array, "One Fish");
+cupsArrayAdd(array, "Two Fish");
+cupsArrayAdd(array, "Red Fish");
+cupsArrayAdd(array, "Blue Fish");
+
+ +

Elements are removed using the +cupsArrayRemove function, for +example:

+ +
+#include <cups/array.h>
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+
+/* Add four strings to the array */
+cupsArrayAdd(array, "One Fish");
+cupsArrayAdd(array, "Two Fish");
+cupsArrayAdd(array, "Red Fish");
+cupsArrayAdd(array, "Blue Fish");
+
+/* Remove "Red Fish" */
+cupsArrayRemove(array, "Red Fish");
+
+ +

Finally, you free the memory used by the array using the +cupsArrayDelete function. All +of the memory for the array and hash table (if any) is freed, however CUPS +does not free the elements - if necessary, you must allocate and free the +elements yourself.

+ +

Finding and Enumerating Elements

+ +

CUPS provides several functions to find and enumerate elements in an +array. Each one sets or updates a "current index" into the array, such that +future lookups will start where the last one left off:

+ +
+
cupsArrayFind
+
Returns the first matching element.
+
cupsArrayFirst
+
Returns the first element in the array.
+
cupsArrayIndex
+
Returns the Nth element in the array, starting at 0.
+
cupsArrayLast
+
Returns the last element in the array.
+
cupsArrayNext
+
Returns the next element in the array.
+
cupsArrayPrev
+
Returns the previous element in the array.
+
+ +

Each of these functions returns NULL when there is no +corresponding element. For example, a simple for loop using the +cupsArrayFirst and +cupsArrayNext functions will +enumerate all of the strings in our previous example:

+ +
+#include <cups/array.h>
+
+/* Use strcmp() to compare strings - it will ignore the user_data pointer */
+cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+
+/* Add four strings to the array */
+cupsArrayAdd(array, "One Fish");
+cupsArrayAdd(array, "Two Fish");
+cupsArrayAdd(array, "Red Fish");
+cupsArrayAdd(array, "Blue Fish");
+
+/* Show all of the strings in the array */
+char *s;
+for (s = (char *)cupsArrayFirst(array); s != NULL; s = (char *)cupsArrayNext(array))
+  puts(s);
+
diff --git a/cups/api-cups.header b/cups/api-cups.header new file mode 100644 index 0000000000..b0c3b29512 --- /dev/null +++ b/cups/api-cups.header @@ -0,0 +1,40 @@ + + +

CUPS API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/cups.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: Array API
+ Programming: File and Directory APIs
+ Programming: Filter and Backend Programming
+ Programming: HTTP and IPP APIs
+ Programming: PPD API
+ Programming: Raster API
diff --git a/cups/api-cups.shtml b/cups/api-cups.shtml new file mode 100644 index 0000000000..47d34450bb --- /dev/null +++ b/cups/api-cups.shtml @@ -0,0 +1,443 @@ + + +

Overview

+ +

The CUPS API provides the convenience functions needed to support +applications, filters, printer drivers, and backends that need to interface +with the CUPS scheduler.

+ +

Clients and Servers

+ +

CUPS is based on the Internet Printing Protocol ("IPP"), which allows +clients (applications) to communicate with a server (the scheduler) to get a +list of printers, send print jobs, and so forth. You identify which server +you want to communicate with using a pointer to the opaque structure +http_t. All of the examples in this document use the +CUPS_HTTP_DEFAULT constant, referring to the default connection +to the scheduler. The HTTP and IPP +APIs document provides more information on server connections.

+ +

Printers and Classes

+ +

Printers and classes (collections of printers) are accessed through +the cups_dest_t structure which +includes the name (name), instance (instance - +a way of selecting certain saved options/settings), and the options and +attributes associated with that destination (num_options and +options). Destinations are created using the +cupsGetDests function and freed +using the cupsFreeDests function. +The cupsGetDest function finds a +specific destination for printing:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dests;
+int num_dests = cupsGetDests(&dests);
+cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
+
+/* do something with dest */
+
+cupsFreeDests(num_dests, dests);
+
+ +

Passing NULL to +cupsGetDest for the destination name +will return the default destination. Similarly, passing a NULL +instance will return the default instance for that destination.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Printer Attributes
Attribute NameDescription
"auth-info-required"The type of authentication required for printing to this + destination: "none", "username,password", "domain,username,password", + or "negotiate" (Kerberos)
"printer-info"The human-readable description of the destination such as "My + Laser Printer".
"printer-is-accepting-jobs""true" if the destination is accepting new jobs, "false" if + not.
"printer-is-shared""true" if the destination is being shared with other computers, + "false" if not.
"printer-location"The human-readable location of the destination such as "Lab 4".
"printer-make-and-model"The human-readable make and model of the destination such as "HP + LaserJet 4000 Series".
"printer-state""3" if the destination is idle, "4" if the destination is printing + a job, and "5" if the destination is stopped.
"printer-state-change-time"The UNIX time when the destination entered the current state.
"printer-state-reasons"Additional comma-delimited state keywords for the destination + such as "media-tray-empty-error" and "toner-low-warning".
"printer-type"The cups_printer_t + value associated with the destination.
+ +

Options

+ +

Options are stored in arrays of +cups_option_t structures. Each +option has a name (name) and value (value) +associated with it. The cups_dest_t +num_options and options members contain the +default options for a particular destination, along with several informational +attributes about the destination as shown in Table 1. +The cupsGetOption function gets +the value for the named option. For example, the following code lists the +available destinations and their human-readable descriptions:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dests;
+int num_dests = cupsGetDests(&dests);
+cups_dest_t *dest;
+int i;
+const char *value;
+
+for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+  if (dest->instance == NULL)
+  {
+    value = cupsGetOption("printer-info", dest->num_options, dest->options);
+    printf("%s (%s)\n", dest->name, value ? value : "no description");
+  }
+
+cupsFreeDests(num_dests, dests);
+
+ +

You can create your own option arrays using the +cupsAddOption function, which +adds a single named option to an array:

+ +
+#include <cups/cups.h>
+
+int num_options = 0;
+cups_option_t *options = NULL;
+
+/* The returned num_options value is updated as needed */
+num_options = cupsAddOption("first", "value", num_options, &options);
+
+/* This adds a second option value */
+num_options = cupsAddOption("second", "value", num_options, &options);
+
+/* This replaces the first option we added */
+num_options = cupsAddOption("first", "new value", num_options, &options);
+
+ +

Use a for loop to copy the options from a destination:

+ +
+#include <cups/cups.h>
+
+int i;
+int num_options = 0;
+cups_option_t *options = NULL;
+cups_dest_t *dest;
+
+for (i = 0; i < dest->num_options; i ++)
+  num_options = cupsAddOption(dest->options[i].name, dest->options[i].value,
+                              num_options, &options);
+
+ +

Use the cupsFreeOptions +function to free the options array when you are done using it:

+ +
+cupsFreeOptions(num_options, options);
+
+ +

Print Jobs

+ +

Print jobs are identified by a locally-unique job ID number from 1 to +231-1 and have options and one or more files for printing to a +single destination. The cupsPrintFile +function creates a new job with one file. The following code prints the CUPS +test page file:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dest;
+int num_options;
+cups_option_t *options;
+int job_id;
+
+/* Print a single file */
+job_id = cupsPrintFile(dest->name, "/usr/share/cups/data/testprint.ps",
+                        "Test Print", num_options, options);
+
+ +

The cupsPrintFiles function +creates a job with multiple files. The files are provided in a +char * array:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dest;
+int num_options;
+cups_option_t *options;
+int job_id;
+char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
+
+/* Print three files */
+job_id = cupsPrintFiles(dest->name, 3, files, "Test Print", num_options, options);
+
+ +

Finally, the cupsCreateJob +function creates a new job with no files in it. Files are added using the +cupsStartDocument, +cupsWriteRequestData, +and cupsFinishDocument functions. +The following example creates a job with 10 text files for printing:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dest;
+int num_options;
+cups_option_t *options;
+int job_id;
+int i;
+char buffer[1024];
+
+/* Create the job */
+job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, dest->name, "10 Text Files",
+                       num_options, options);
+
+/* If the job is created, add 10 files */
+if (job_id > 0)
+{
+  for (i = 1; i <= 10; i ++)
+  {
+    snprintf(buffer, sizeof(buffer), "file%d.txt", i);
+
+    cupsStartDocument(CUPS_HTTP_DEFAULT, dest->name, job_id, buffer,
+                      CUPS_FORMAT_TEXT, i == 10);
+
+    snprintf(buffer, sizeof(buffer),
+             "File %d\n"
+             "\n"
+             "One fish,\n"
+             "Two fish,\n
+             "Red fish,\n
+             "Blue fish\n", i);
+
+    /* cupsWriteRequestData can be called as many times as needed */
+    cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
+
+    cupsFinishDocument(CUPS_HTTP_DEFAULT, dest->name);
+  }
+}
+
+ +

Once you have created a job, you can monitor its status using the +cupsGetJobs function, which returns +an array of cups_job_t structures. +Each contains the job ID (id), destination name +(dest), title (title), and other information +associated with the job. The job array is freed using the +cupsFreeJobs function. The following +example monitors a specific job ID, showing the current job state once every +5 seconds until the job is completed:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dest;
+int job_id;
+int num_jobs;
+cups_job_t *jobs;
+int i;
+ipp_jstate_t job_state = IPP_JOB_PENDING;
+ 
+while (job_state < IPP_JOB_STOPPED)
+{
+  /* Get my jobs (1) with any state (-1) */
+  num_jobs = cupsGetJobs(&jobs, dest->name, 1, -1);
+
+  /* Loop to find my job */
+  job_state = IPP_JOB_COMPLETED;
+
+  for (i = 0; i < num_jobs; i ++)
+    if (jobs[i].id == job_id)
+    {
+      job_state = jobs[i].state;
+      break;
+    }
+
+  /* Free the job array */
+  cupsFreeJobs(num_jobs, jobs);
+
+  /* Show the current state */
+  switch (job_state)
+  {
+    case IPP_JOB_PENDING :
+        printf("Job %d is pending.\n", job_id);
+        break;
+    case IPP_JOB_HELD :
+        printf("Job %d is held.\n", job_id);
+        break;
+    case IPP_JOB_PROCESSING :
+        printf("Job %d is processing.\n", job_id);
+        break;
+    case IPP_JOB_STOPPED :
+        printf("Job %d is stopped.\n", job_id);
+        break;
+    case IPP_JOB_CANCELED :
+        printf("Job %d is canceled.\n", job_id);
+        break;
+    case IPP_JOB_ABORTED :
+        printf("Job %d is aborted.\n", job_id);
+        break;
+    case IPP_JOB_COMPLETED :
+        printf("Job %d is completed.\n", job_id);
+        break;
+  }
+
+  /* Sleep if the job is not finished */
+  if (job_state < IPP_JOB_STOPPED)
+    sleep(5);
+}
+
+ +

To cancel a job, use the +cupsCancelJob function with the +job ID:

+ +
+#include <cups/cups.h>
+
+cups_dest_t *dest;
+int job_id;
+
+cupsCancelJob(dest->name, job_id);
+
+ +

Error Handling

+ +

If any of the CUPS API printing functions returns an error, the reason for +that error can be found by calling the +cupsLastError and +cupsLastErrorString functions. +cupsLastError returns the last IPP +error code +(ipp_status_t) +that was encountered, while +cupsLastErrorString returns +a (localized) human-readable string that can be shown to the user. For example, +if any of the job creation functions returns a job ID of 0, you can use +cupsLastErrorString to show +the reason why the job could not be created:

+ +
+#include <cups/cups.h>
+
+int job_id;
+
+if (job_id == 0)
+  puts(cupsLastErrorString());
+
+ +

Passwords and Authentication

+ +

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.

+ +

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.

+ +

The cupsSetPasswordCB +function is used to set a password callback in your program. Only one +function can be used at any time.

+ +

The cupsSetUser function sets the +current username for authentication. This function can be called by your +password callback function to change the current username as needed.

+ +

The following example shows a simple password callback that gets a +username and password from the user:

+ +
+#include <cups/cups.h>
+
+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);
+
+ +

Similarly, a GUI could display the prompt string in a window with input +fields for the username and password. The username should default to the +string returned by the cupsUser +function.

diff --git a/cups/api-filedir.header b/cups/api-filedir.header new file mode 100644 index 0000000000..f65c3eb642 --- /dev/null +++ b/cups/api-filedir.header @@ -0,0 +1,36 @@ + + +

File and Directory APIs

+ +
+ + + + + + + + + + + + + + + + +
Headerscups/file.h
+ cups/dir.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
diff --git a/cups/api-filedir.shtml b/cups/api-filedir.shtml new file mode 100644 index 0000000000..c003ae118e --- /dev/null +++ b/cups/api-filedir.shtml @@ -0,0 +1,31 @@ + + +

Overview

+ +

The CUPS file and directory APIs provide portable interfaces +for manipulating files and listing files and directories. Unlike +stdio FILE streams, the cupsFile functions +allow you to open more than 256 files at any given time. They +also manage the platform-specific details of locking, large file +support, line endings (CR, LF, or CR LF), and reading and writing +files using Flate ("gzip") compression. Finally, you can also +connect, read from, and write to network connections using the +cupsFile functions.

+ +

The cupsDir functions manage the platform-specific +details of directory access/listing and provide a convenient way +to get both a list of files and the information (permissions, +size, timestamp, etc.) for each of those files.

diff --git a/cups/api-filter.header b/cups/api-filter.header new file mode 100644 index 0000000000..1b1d1e1009 --- /dev/null +++ b/cups/api-filter.header @@ -0,0 +1,42 @@ + + +

Filter and Backend Programming

+ +
+ + + + + + + + + + + + + + + + +
Headerscups/backend.h
+ cups/sidechannel.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ Programming: PPD API
+ Programming: Raster API
+ Programming: Developing PostScript Printer Drivers
+ Programming: Developing Raster Printer Drivers
+ Specifications: CUPS Design Description
diff --git a/cups/api-filter.shtml b/cups/api-filter.shtml new file mode 100644 index 0000000000..134958f2a1 --- /dev/null +++ b/cups/api-filter.shtml @@ -0,0 +1,585 @@ + + +

Overview

+ +

Filters (which include printer drivers and port monitors) and backends +are used to convert job files to a printable format and send that data to the +printer itself. All of these programs use a common interface for processing +print jobs and communicating status information to the scheduler. Each is run +with a standard set of command-line arguments:

+ +

+ +
argv[1]
+
The job ID
+ +
argv[2]
+
The user printing the job
+ +
argv[3]
+
The job name/title
+ +
argv[4]
+
The number of copies to print
+ +
argv[5]
+
The options that were provided when the job was submitted
+ +
argv[6]
+
The file to print (first program only)
+
+ +

The scheduler runs one or more of these programs to print any given job. The +first filter reads from the print file and writes to the standard output, while +the remaining filters read from the standard input and write to the standard +output. The backend is the last filter in the chain and writes to the +device.

+ +

Filters are always run as a non-privileged user, typically "lp", with no +connection to the user's desktop. Backends are run either as a non-privileged +user or as root if the file permissions do not allow user or group execution. +The file permissions section talks about this in +more detail.

+ +

Security Considerations

+ +

It is always important to use security programming practices. Filters and +most backends are run as a non-privileged user, so the major security +consideration is resource utilization - filters should not depend on unlimited +amounts of CPU, memory, or disk space, and should protect against conditions +that could lead to excess usage of any resource like infinite loops and +unbounded recursion. In addition, filters must never allow the user to +specify an arbitrary file path to a separator page, template, or other file +used by the filter since that can lead to an unauthorized disclosure of +information. Always treat input as suspect and validate it!

+ +

If you are developing a backend that runs as root, make sure to check for +potential buffer overflows, integer under/overflow conditions, and file +accesses since these can lead to privilege escalations. When writing files, +always validate the file path and never allow a user to determine +where to store a file.

+ +
Note: + +

Never write files to a user's home directory. Aside from the +security implications, CUPS is a network print service and as such the network +user may not be the same as the local user and/or there may not be a local home +directory to write to.

+ +

In addition, some operating systems provide additional security mechanisms +that further limit file system access, even for backends running as root. On +Mac OS X, for example, no backend may write to a user's home directory.

+
+ +

File Permissions

+ +

For security reasons, CUPS will only run filters and backends that are owned +by root and do not have world or group write permissions. The recommended +permissions for filters and backends are 0555 - read and execute but no write. +Backends that must run as root should use permissions of 0500 - read and execute +by root, no access for other users. Write permissions can be enabled for the +root user only.

+ +

To avoid a warning message, the directory containing your filter(s) must also +be owned by root and have world and group write disabled - permissions of 0755 +or 0555 are strongly encouraged.

+ +

Temporary Files

+ +

Temporary files should be created in the directory specified by the +"TMPDIR" environment variable. The +cupsTempFile2 function can be +used to safely create temporary files in this directory.

+ +

Copy Generation

+ +

The argv[4] argument specifies the number of copies to produce +of the input file. In general, you should only generate copies if the +filename argument is supplied. The only exception to this are +filters that produce device-independent PostScript output, since the PostScript +filter pstops is responsible for generating copies of PostScript +files.

+ +

Exit Codes

+ +

Filters must exit with status 0 when they successfully generate print data +or 1 when they encounter an error. Backends can return any of the +cups_backend_t constants.

+ +

Environment Variables

+ +

The following environment variables are defined by the printing system +when running print filters and backends:

+ +
+ +
APPLE_LANGUAGE
+
The Apple language identifier associated with the job + (Mac OS X only).
+ +
CHARSET
+
The job character set, typically "utf-8".
+ +
CLASS
+
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.
+ +
CONTENT_TYPE
+
The MIME type associated with the file (e.g. + application/postscript).
+ +
CUPS_CACHEDIR
+
The directory where cache files can be stored. Cache files can be + used to retain information between jobs or files in a job.
+ +
CUPS_DATADIR
+
The directory where (read-only) CUPS data files can be found.
+ +
CUPS_FILETYPE
+
The type of file being printed: "job-sheet" for a banner page and + "document" for a regular print file.
+ +
CUPS_SERVERROOT
+
The root directory of the server.
+ +
DEVICE_URI
+
The device-uri associated with the printer.
+ +
FINAL_CONTENT_TYPE
+
The MIME type associated with the printer (e.g. + application/vnd.cups-postscript).
+ +
LANG
+
The language locale associated with the job.
+ +
PPD
+
The full pathname of the PostScript Printer Description (PPD) + file for this printer.
+ +
PRINTER
+
The queue name of the class or printer.
+ +
RIP_CACHE
+
The recommended amount of memory to use for Raster Image + Processors (RIPs).
+ +
TMPDIR
+
The directory where temporary files should be created.
+ +
+ +

Communicating with the Scheduler

+ +

Filters and backends communicate with the scheduler by writing messages +to the standard error file. The scheduler reads messages from all filters in +a job and processes the message based on its prefix. For example, the following +code sets the current printer state message to "Printing page 5":

+ +
+int page = 5;
+
+fprintf(stderr, "INFO: Printing page %d\n", page);
+
+ +

Each message is a single line of text starting with one of the following +prefix strings:

+ +
+ +
ALERT: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "alert" log level.
+ +
ATTR: attribute=value [attribute=value]
+
Sets the named printer or job attribute(s). Typically this is used + to set the marker-colors, marker-levels, + marker-message, marker-names, + marker-types, printer-alert, and + printer-alert-description printer attributes. Standard + marker-types values are listed in Table + 1.
+ +
CRIT: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "critical" log + level.
+ +
DEBUG: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "debug" log level.
+ +
DEBUG2: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "debug2" log level.
+ +
EMERG: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "emergency" log + level.
+ +
ERROR: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "error" log level. + Use "ERROR:" messages for non-persistent processing errors.
+ +
INFO: message
+
Sets the printer-state-message attribute. If the current log level + is set to "debug2", also adds the specified message to the current error + log file using the "info" log level.
+ +
NOTICE: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "notice" log level.
+ +
PAGE: page-number #-copies
+
PAGE: total #-pages
+
Adds an entry to the current page log file. The first form adds + #-copies to the job-media-sheets-completed attribute. The second + form sets the job-media-sheets-completed attribute to #-pages.
+ +
PPD: keyword=value [keyword=value ...]
+
Changes or adds keywords to the printer's PPD file. Typically + this is used to update installable options or default media settings + based on the printer configuration.
+ +
STATE: printer-state-reason [printer-state-reason ...]
+
STATE: + printer-state-reason [printer-state-reason ...]
+
STATE: - printer-state-reason [printer-state-reason ...]
+
Sets, adds, or removes printer-state-reason keywords to the + current queue. Typically this is used to indicate persistent media, + ink, toner, and configuration conditions or errors on a printer. + Table 2 lists the standard state keywords - + use vendor-prefixed ("com.acme.foo") keywords for custom states. + +
Note: + +

"STATE:" messages often provide visible alerts to the user. For example, on + Mac OS X setting a printer-state-reason value with an "-error" or "-warning" + suffix will cause the printer's dock item to bounce if the corresponding reason + is localized with a cupsIPPReason keyword in the printer's PPD file.

+ +
+ +
WARNING: message
+
Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "warning" log + level.
+ +
+ +

Messages without one of these prefixes are treated as if they began with +the "DEBUG:" prefix string.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Standard marker-types Values
marker-typeDescription
developerDeveloper unit
fuserFuser unit
fuserCleaningPadFuser cleaning pad
fuserOilFuser oil
inkInk supply
opcPhoto conductor
solidWaxWax supply
staplesStaple supply
tonerToner supply
transferUnitTransfer unit
wasteInkWaste ink tank
wasteTonerWaste toner tank
wasteWaxWaste wax tank
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Standard State Keywords
KeywordDescription
connecting-to-deviceConnecting to printer but not printing yet
cover-openA cover is open on the printer
input-tray-missingAn input tray is missing from the printer
marker-supply-emptyOut of ink
marker-supply-lowLow on ink
marker-waste-almost-fullWaste tank almost full
marker-waste-fullWaste tank full
media-emptyOut of media
media-jamMedia is jammed in the printer
media-lowLow on media
pausedStop the printer
timed-outUnable to connect to printer
toner-emptyOut of toner
toner-lowLow on toner
+ +

Communicating with the Backend

+ +

Filters can communicate with the backend via the +cupsBackChannelRead and +cupsSideChannelDoRequest +functions. The +cupsBackChannelRead function +reads data that has been sent back from the device and is typically used to +obtain status and configuration information. For example, the following code +polls the backend for back-channel data:

+ +
+#include <cups/cups.h>
+
+char buffer[8192];
+ssize_t bytes;
+
+/* Use a timeout of 0.0 seconds to poll for back-channel data */
+bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
+
+ +

Filters can also use select() or poll() on the +back-channel file descriptor (3 or CUPS_BC_FD) to read data only +when it is available.

+ +

The +cupsSideChannelDoRequest +function allows you to get out-of-band status information and do synchronization +with the device. For example, the following code gets the current IEEE-1284 +device ID string from the backend:

+ +
+#include <cups/sidechannel.h>
+
+char data[2049];
+int datalen;
+cups_sc_status_t status;
+
+/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for
+   nul-termination... */
+datalen = sizeof(data) - 1;
+
+/* Get the IEEE-1284 device ID, waiting for up to 1 second */
+status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &datalen, 1.0);
+
+/* Use the returned value if OK was returned and the length is non-zero */
+if (status == CUPS_SC_STATUS_OK && datalen > 0)
+  data[datalen] = '\0';
+else
+  data[0] = '\0';
+
+ +

Communicating with Filters

+ +

Backends communicate with filters using the reciprocal functions +cupsBackChannelWrite, +cupsSideChannelRead, and +cupsSideChannelWrite. We +recommend writing back-channel data using a timeout of 1.0 seconds:

+ +
+#include <cups/cups.h>
+
+char buffer[8192];
+ssize_t bytes;
+
+/* Obtain data from printer/device */
+...
+
+/* Use a timeout of 1.0 seconds to give filters a chance to read */
+cupsBackChannelWrite(buffer, bytes, 1.0);
+
+ +

The cupsSideChannelRead +function reads a side-channel command from a filter, driver, or port monitor. +Backends can either poll for commands using a timeout of 0.0, wait +indefinitely for commands using a timeout of -1.0 (probably in a +separate thread for that purpose), or use select or +poll on the CUPS_SC_FD file descriptor (4) to handle +input and output on several file descriptors at the same time.

+ +

Once a command is processed, the backend uses the +cupsSideChannelWrite function +to send its response. For example, the following code shows how to poll for a +side-channel command and respond to it:

+ +
+#include <cups/sidechannel.h>
+
+cups_sc_command_t command;
+cups_sc_status_t status;
+char data[2048];
+int datalen = sizeof(data);
+
+/* Poll for a command... */
+if (!cupsSideChannelRead(&command, &status, data, &datalen, 0.0))
+{
+  switch (command)
+  {
+    /* handle supported commands, fill data/datalen/status with values as needed */
+
+    default :
+        status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+	datalen = 0;
+	break;
+  }
+
+  /* Send a response... */
+  cupsSideChannelWrite(command, status, data, datalen, 1.0);
+}
+
+ +

Doing SNMP Queries with Network Printers

+ +

The Simple Network Management Protocol (SNMP) allows you to get the current +status, page counter, and supply levels from most network printers. Every +piece of information is associated with an Object Identifier (OID), and +every printer has a community name associated with it. OIDs can be +queried directly or by "walking" over a range of OIDs with a common prefix.

+ +

The two CUPS SNMP functions provide a simple API for querying network +printers through the side-channel interface. Each accepts a string containing +an OID like ".1.3.6.1.2.1.43.10.2.1.4.1.1" (the standard page counter OID) +along with a timeout for the query.

+ +

The cupsSideChannelSNMPGet +function queries a single OID and returns the value as a string in a buffer +you supply:

+ +
+#include <cups/sidechannel.h>
+
+char data[512];
+int datalen = sizeof(data);
+
+if (cupsSideChannelSNMPGet(".1.3.6.1.2.1.43.10.2.1.4.1.1", data, &datalen, 5.0)
+        == CUPS_SC_STATUS_OK)
+{
+  /* Do something with the value */
+  printf("Page counter is: %s\n", data);
+}
+
+ +

The +cupsSideChannelSNMPWalk +function allows you to query a whole group of OIDs, calling a function of your +choice for each OID that is found:

+ +
+#include <cups/sidechannel.h>
+
+void
+my_callback(const char *oid, const char *data, int datalen, void *context)
+{
+  /* Do something with the value */
+  printf("%s=%s\n", oid, data);
+}
+
+...
+
+void *my_data;
+
+cupsSNMPSideChannelWalk(".1.3.6.1.2.1.43", 5.0, my_callback, my_data);
+
diff --git a/cups/api-httpipp.header b/cups/api-httpipp.header new file mode 100644 index 0000000000..fab38d1594 --- /dev/null +++ b/cups/api-httpipp.header @@ -0,0 +1,37 @@ + + +

HTTP and IPP APIs

+ +
+ + + + + + + + + + + + + + + + +
Headercups/cups.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ References: CUPS Implementation of IPP
diff --git a/cups/api-httpipp.shtml b/cups/api-httpipp.shtml new file mode 100644 index 0000000000..c8ae9cf8b1 --- /dev/null +++ b/cups/api-httpipp.shtml @@ -0,0 +1,323 @@ + + +

Overview

+ +

The CUPS HTTP and IPP APIs provide low-level access to the HTTP and IPP +protocols and CUPS scheduler. They are typically used by monitoring and +administration programs to perform specific functions not supported by the +high-level CUPS API functions.

+ +

The HTTP APIs use an opaque structure called +http_t to manage connections to +a particular HTTP or IPP server. The +httpConnectEncrypt function is +used to create an instance of this structure for a particular server. +The constant CUPS_HTTP_DEFAULT can be used with all of the +cups functions to refer to the default CUPS server - the functions +create a per-thread http_t as needed.

+ +

The IPP APIs use two structures for requests (messages sent to the CUPS +scheduler) and responses (messages sent back to your application from the +scheduler). The ipp_t structure holds a +complete request or response and is allocated using the +ippNew or +ippNewRequest functions and +freed using the ippDelete function.

+ +

The second structure is called +ipp_attribute_t and holds a +single IPP attribute which consists of a group tag (group_tag), a +value type tag (value_tag), the attribute name (name), +and 1 or more values (values[]). Attributes are added to an +ipp_t structure using one of the +ippAdd functions. For example, use +ippAddString to add a +"requesting-user-name" string attribute to a request:

+ +
+ipp_t *request = ippNewRequest(IPP_GET_JOBS);
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+
+ +

Once you have created an IPP request, use the cups +functions to send the request to and read the response from the server. +For example, the cupsDoRequest +function can be used for simple query operations that do not involve files:

+ +
+#include <cups/cups.h>
+
+
+ipp_t *get_jobs(void)
+{
+  ipp_t *request = ippNewRequest(IPP_GET_JOBS);
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+               NULL, cupsUser());
+
+  return (cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/"));
+}
+
+ +

The cupsDoRequest function frees +the request structure and returns an IPP response structure or NULL pointer if +the request could not be sent to the server. Once you have a response from +the server, you can either use the +ippFindAttribute and +ippFindNextAttribute functions +to find specific attributes, for example:

+ +
+ipp_t *response;
+ipp_attribute_t *attr;
+
+attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM);
+
+ +

You can also walk the list of attributes with a simple for loop +like this:

+ +
+ipp_t *response;
+ipp_attribute_t *attr;
+
+for (attr = response->attrs; attr != NULL; attr = attr->next)
+  if (attr->name == NULL)
+    puts("--SEPARATOR--");
+  else
+    puts(attr->name);
+
+ +

The for loop approach is normally used when collecting +attributes for multiple objects (jobs, printers, etc.) in a response. Attributes +with NULL names indicate a separator between the attributes of +each object. For example, the following code will list the jobs returned from +our previous get_jobs example code:

+ +
+ipp_t *response = get_jobs();
+
+if (response != NULL)
+{
+  ipp_attribute_t *attr;
+  int job_id = 0;
+  char *job_name = NULL;
+  char *job_originating_user_name = NULL;
+
+  puts("Job ID  Owner             Title");
+  puts("------  ----------------  ---------------------------------");
+
+  for (attr = response->attrs; attr != NULL; attr = attr->next)
+  {
+   /* Attributes without names are separators between jobs */
+    if (attr->name == NULL)
+    {
+      if (job_id > 0 && job_name != NULL && job_originating_user_name != NULL)
+        printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
+
+      job_id = 0;
+      job_name = NULL;
+      job_originating_user_name = NULL;
+      continue;
+    }
+    else if (!strcmp(attr->name, "job-id") && attr->value_tag == IPP_TAG_INTEGER)
+      job_id = attr->values[0].integer;
+    else if (!strcmp(attr->name, "job-name") && attr->value_tag == IPP_TAG_NAME)
+      job_name = attr->values[0].string.text;
+    else if (!strcmp(attr->name, "job-originating-user-name") &&
+             attr->value_tag == IPP_TAG_NAME)
+      job_originating_user_name = attr->values[0].string.text;
+  }
+
+  if (job_id > 0 && job_name != NULL && job_originating_user_name != NULL)
+    printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
+}
+
+ +

Creating URI Strings

+ +

To ensure proper encoding, the +httpAssembleURIf function must be +used to format a "printer-uri" string for all printer-based requests:

+ +
+const char *name = "Foo";
+char uri[1024];
+ipp_t *request;
+
+httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+                 ippPort(), "/printers/%s", name);
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
+
+ +

Sending Requests with Files

+ +

The cupsDoFileRequest and +cupsDoIORequest functions are +used for requests involving files. The +cupsDoFileRequest function +attaches the named file to a request and is typically used when sending a print +file or changing a printer's PPD file:

+ +
+const char *filename = "/usr/share/cups/data/testprint.ps";
+const char *name = "Foo";
+char uri[1024];
+char resource[1024];
+ipp_t *request = ippNewRequest(IPP_PRINT_JOB);
+ipp_t *response;
+
+/* Use httpAssembleURIf for the printer-uri string */
+httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
+                 ippPort(), "/printers/%s", name);
+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());
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+             NULL, "testprint.ps");
+
+/* Use snprintf for the resource path */
+snprintf(resource, sizeof(resource), "/printers/%s", name);
+
+response = cupsDoFileRequest(CUPS_HTTP_DEFAULT, request, resource, filename);
+
+ +

The cupsDoIORequest function +optionally attaches a file to the request and optionally saves a file in the +response from the server. It is used when using a pipe for the request +attachment or when using a request that returns a file, currently only +CUPS_GET_DOCUMENT and CUPS_GET_PPD. For example, +the following code will download the PPD file for the sample HP LaserJet +printer driver:

+ +
+char tempfile[1024];
+int tempfd;
+ipp_t *request = ippNewRequest(CUPS_GET_PPD);
+ipp_t *response;
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+response = cupsDoIORequest(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
+
+ +

The example passes -1 for the input file descriptor to specify +that no file is to be attached to the request. The PPD file attached to the +response is written to the temporary file descriptor we created using the +cupsTempFd function.

+ +

Asynchronous Request Processing

+ +

The cupsSendRequest and +cupsGetResponse support +asynchronous communications with the server. Unlike the other request +functions, the IPP request is not automatically freed, so remember to +free your request with the ippDelete +function.

+ +

File data is attached to the request using the +cupsWriteRequestData +function, while file data returned from the server is read using the +cupsReadResponseData +function. We can rewrite the previous CUPS_GET_PPD example +to use the asynchronous functions quite easily:

+ +
+char tempfile[1024];
+int tempfd;
+ipp_t *request = ippNewRequest(CUPS_GET_PPD);
+ipp_t *response;
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+if (cupsSendRequest(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
+{
+  response = cupsGetResponse(CUPS_HTTP_DEFAULT, "/");
+
+  if (response != NULL)
+  {
+    ssize_t bytes;
+    char buffer[8192];
+
+    while ((bytes = cupsReadResponseData(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+      write(tempfd, buffer, bytes);
+  }
+}
+
+/* Free the request! */
+ippDelete(request);
+
+ +

The cupsSendRequest function +returns the initial HTTP request status, typically either +HTTP_CONTINUE or HTTP_UNAUTHORIZED. The latter status +is returned when the request requires authentication of some sort. The +cupsDoAuthentication function +must be called when your see HTTP_UNAUTHORIZED and the request +re-sent. We can add authentication support to our example code by using a +do ... while loop:

+ +
+char tempfile[1024];
+int tempfd;
+ipp_t *request = ippNewRequest(CUPS_GET_PPD);
+ipp_t *response;
+http_status_t status;
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
+             NULL, "laserjet.ppd");
+
+tempfd = cupsTempFd(tempfile, sizeof(tempfile));
+
+/* Loop for authentication */
+do
+{
+  status = cupsSendRequest(CUPS_HTTP_DEFAULT, request, "/");
+
+  if (status == HTTP_UNAUTHORIZED)
+  {
+    /* Try to authenticate, break out of the loop if that fails */
+    if (cupsDoAuthentication(CUPS_HTTP_DEFAULT, "POST", "/"))
+      break;
+  }
+}
+while (status != HTTP_CONTINUE && status != HTTP_UNAUTHORIZED);
+
+if (status == HTTP_CONTINUE)
+{
+  response = cupsGetResponse(CUPS_HTTP_DEFAULT, "/");
+
+  if (response != NULL)
+  {
+    ssize_t bytes;
+    char buffer[8192];
+
+    while ((bytes = cupsReadResponseData(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
+      write(tempfd, buffer, bytes);
+  }
+}
+
+/* Free the request! */
+ippDelete(request);
+
diff --git a/cups/api-overview.header b/cups/api-overview.header new file mode 100644 index 0000000000..892ed1c7e7 --- /dev/null +++ b/cups/api-overview.header @@ -0,0 +1,54 @@ + + +

Introduction to CUPS Programming

+ +
+ + + + + + + + + + + + + + + + +
Headerscups/cups.h
+ cups/array.h
+ cups/backend.h
+ cups/dir.h
+ cups/file.h
+ cups/ppd.h
+ cups/raster.h
+ cups/sidechannel.h
Libraries-lcups
+ -lcupsimage
See AlsoProgramming: Developing Raster Printer Drivers
+ Programming: Developing PostScript Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Introduction to the PPD Compiler
+ Programming: Array API
+ Programming: CUPS API
+ Programming: File and Directory APIs
+ Programming: HTTP and IPP APIs
+ Programming: PPD API
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
diff --git a/cups/api-overview.shtml b/cups/api-overview.shtml new file mode 100644 index 0000000000..3ece1033ca --- /dev/null +++ b/cups/api-overview.shtml @@ -0,0 +1,94 @@ + + +

Overview

+ +

CUPS provides two libraries that interface with the different parts of the +printing system. The "cups" library provides all of the common application and +filter functions while the "cupsimage" library provides all of the imaging +functions used in raster printer drivers. The "cups" library functions are +accessed by including the <cups/cups.h> header, while +"cupsimage" functions are found in the <cups/raster.h> +header.

+ +

Compiling Programs

+ +

The CUPS libraries can be used from any C, C++, or Objective C program. +The method of compiling against the libraries varies depending on the +operating system and installation of CUPS. The following sections show how +to compile a simple program (shown below) in two common environments.

+ +

The following simple program lists the available printers on the system:

+ +
+#include <stdio.h>
+#include <cups/cups.h>
+
+int main(void)
+{
+  int i;
+  cups_dest_t *dests, *dest;
+  int num_dests = cupsGetDests(&dests);
+
+  for (i = num_dests, dest = dests; i > 0; i --, dest ++)
+  {
+    if (dest->instance)
+      printf("%s/%s\n", dest->name, dest->instance);
+    else
+      puts(dest->name);
+  }
+
+  return (0);
+}
+
+ +

Compiling with Xcode

+ +

In Xcode, choose New Project... from the File menu, +then select the Standard Tool project type under Command Line +Utility. Click Next and choose a project directory. Click +Next to create the project.

+ +

In the project window, double-click on the Targets group and +control-click on the simple target to show the context menu. Choose +Existing Framework... from the Add submenu. When the file +chooser sheet appears, press the / key and enter "/usr/lib". Scroll +down the file list and select the libcups.dylib file. Click the +Add button in the file chooser and attributes sheets.

+ +

In the project window, double-click on the main.c source file. +Replace the template source code with the listing above and save it. Click the +Build and Go button to build the sample program and run it.

+ +

Compiling with GCC

+ +

From the command-line, create a file called sample.c using your +favorite editor and then run the following command to compile it with GCC and +run it:

+ +
+gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
+./simple
+
+ +

The cups-config command provides the compiler flags +("cups-config --cflags") and libraries ("cups-config --libs") needed for the +local system.

+ +

Where to Go Next

+ +

If you are developing a print filter, driver, or backend, see the +Filter and Backend Programming +guide. Raster printer driver developers should also read the +Raster API reference.

diff --git a/cups/api-ppd.header b/cups/api-ppd.header new file mode 100644 index 0000000000..4fe645417f --- /dev/null +++ b/cups/api-ppd.header @@ -0,0 +1,36 @@ + + +

PPD API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/ppd.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ Specifications: CUPS PPD Extensions
diff --git a/cups/api-ppd.shtml b/cups/api-ppd.shtml new file mode 100644 index 0000000000..59620e8565 --- /dev/null +++ b/cups/api-ppd.shtml @@ -0,0 +1,217 @@ + + +

Overview

+ +

The CUPS PPD API provides read-only access the data in PostScript Printer +Description ("PPD") files which are used for all printers with a driver. With +it you can obtain the data necessary to display printer options to users, mark +option choices and check for conflicting choices, and output marked choices in +PostScript output. The ppd_file_t +structure contains all of the information in a PPD file.

+ +
Note: + +

The CUPS PPD API uses the terms "option" and "choice" instead of the Adobe +terms "MainKeyword" and "OptionKeyword" to refer to specific printer options and +features. CUPS also treats option ("MainKeyword") and choice ("OptionKeyword") +values as case-insensitive strings, so option "InputSlot" and choice "Upper" +are equivalent to "inputslot" and "upper", respectively.

+
+ +

Loading a PPD File

+ +

The ppdOpenFile function "opens" a +PPD file and loads it into memory. For example, the following code opens the +current printer's PPD file in a CUPS filter:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd = ppdOpenFile(getenv("PPD"));
+
+ +

The return value is a pointer to a new +ppd_file_t structure or NULL +if the PPD file does not exist or cannot be loaded. The +ppdClose function frees the memory used +by the structure:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdClose(ppd);
+
+ +

Once closed, pointers to the ppd_file_t +structure and any data in it will no longer be valid.

+ +

Options and Groups

+ +

PPD files support multiple options, which are stored in arrays of +ppd_option_t and +ppd_choice_t structures.

+ +

Each option in turn is associated with a group stored in a +ppd_group_t structure. Groups can be +specified in the PPD file; if an option is not associated with a group +then it is put in an automatically-generated "General" group. Groups can also +have sub-groups, however CUPS currently ignores sub-groups because of past +abuses of this functionality.

+ +

Option choices are selected by marking them using one of three functions. The +first is ppdMarkDefaults which +selects all of the default options in the PPD file:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkDefaults(ppd);
+
+ +

The second is ppdMarkOption +which selects a single option choice in the PPD file. For example, the following +code selects the upper paper tray:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkOption(ppd, "InputSlot", "Upper");
+
+ +

The last function is +cupsMarkOptions which selects +multiple option choices in the PPD file from an array of CUPS options, mapping +IPP attributes like "media" and "sides" to their corresponding PPD options. You +typically use this function in a print filter with +cupsParseOptions and +ppdMarkDefaults to select all of +the option choices needed for the job, for example:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd = ppdOpenFile(getenv("PPD"));
+cups_option_t *options = NULL;
+int num_options = cupsParseOptions(argv[5], 0, &options);
+
+ppdMarkDefaults(ppd);
+cupsMarkOptions(ppd, num_options, options);
+cupsFreeOptions(num_options, options);
+
+ +

Constraints

+ +

PPD files support specification of conflict conditions, called +constraints, between different options. Constraints are stored in an array of +ppd_const_t structures which specify +the options and choices that conflict with each other. The +ppdConflicts function tells you +how many of the selected options are incompatible. Since constraints are +normally specified in pairs, the returned value is typically an even number.

+ +

Page Sizes

+ +

Page sizes are special options which have physical dimensions and margins +associated with them. The size information is stored in +ppd_size_t structures and is available +by looking up the named size with the +ppdPageSize function. The page size and +margins are returned in units called points; there are 72 points per inch. If +you pass NULL for the size, the currently selected size is +returned:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_size_t *size = ppdPageSize(ppd, NULL);
+
+ +

Besides the standard page sizes listed in a PPD file, some printers +support variable or custom page sizes. Custom page sizes are supported if the +variables_sizes member of the +ppd_file_t structure is non-zero. +The custom_min, custom_max, and +custom_margins members of the +ppd_file_t structure define the limits +of the printable area. To get the resulting media size, use a page size string +of the form "Custom.widthxlength", where "width" and "length" are +in points. Custom page size names can also be specified in inches +("Custom.widthxheightin"), centimeters +("Custom.widthxheightcm"), or millimeters +("Custom.widthxheightmm"):

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+/* Get an 576x720 point custom page size */
+ppd_size_t *size = ppdPageSize(ppd, "Custom.576x720");
+
+/* Get an 8x10 inch custom page size */
+ppd_size_t *size = ppdPageSize(ppd, "Custom.8x10in");
+
+/* Get a 100x200 millimeter custom page size */
+ppd_size_t *size = ppdPageSize(ppd, "Custom.100x200mm");
+
+/* Get a 12.7x34.5 centimeter custom page size */
+ppd_size_t *size = ppdPageSize(ppd, "Custom.12.7x34.5cm");
+
+ +

If the PPD does not support variable page sizes, the +ppdPageSize function will return +NULL.

+ +

Attributes

+ +

Every PPD file is composed of one or more attributes. Most of these +attributes are used to define groups, options, choices, and page sizes, +however several informational attributes may be present which you can access +in your program or filter. Attributes normally look like one of the following +examples in a PPD file:

+ +
+*name: "value"
+*name spec: "value"
+*name spec/text: "value"
+
+ +

The ppdFindAttr and +ppdFindNextAttr functions find the +first and next instances, respectively, of the named attribute with the given +"spec" string and return a ppd_attr_t +structure. If you provide a NULL specifier string, all attributes with the +given name will be returned. For example, the following code lists all of the +Product attributes in a PPD file:

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_attr_t *attr;
+
+for (attr = ppdFindAttr(ppd, "Product", NULL);
+     attr != NULL;
+     attr = ppdFindNextAttr(ppd, "Product", NULL))
+  puts(attr->value);
+
diff --git a/cups/array.c b/cups/array.c new file mode 100644 index 0000000000..98f2e3f9dc --- /dev/null +++ b/cups/array.c @@ -0,0 +1,1144 @@ +/* + * "$Id$" + * + * Sorted array routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsArrayAdd() - Add an element to the array. + * cupsArrayClear() - Clear the array. + * cupsArrayCount() - Get the number of elements in the array. + * cupsArrayCurrent() - Return the current element in the array. + * cupsArrayDelete() - Free all memory used by the array. + * cupsArrayDup() - Duplicate the array. + * cupsArrayFind() - Find an element in the array. + * cupsArrayFirst() - Get the first element in the array. + * cupsArrayGetIndex() - Get the index of the current element. + * cupsArrayGetInsert() - Get the index of the last inserted element. + * cupsArrayIndex() - Get the N-th element in the array. + * cupsArrayInsert() - Insert an element in the array. + * cupsArrayLast() - Get the last element in the array. + * cupsArrayNew() - Create a new array. + * cupsArrayNext() - Get the next element in the array. + * cupsArrayPrev() - Get the previous element in the array. + * cupsArrayRemove() - Remove an element from the array. + * cupsArrayRestore() - Reset the current element to the last cupsArraySave. + * cupsArraySave() - Mark the current element for a later + * cupsArrayRestore. + * cupsArrayUserData() - Return the user data for an array. + * cups_array_add() - Insert or append an element to the array... + * cups_array_find() - Find an element in the array... + */ + +/* + * Include necessary headers... + */ + +#include "array.h" +#include "string.h" +#include "debug.h" + + +/* + * Limits... + */ + +#define _CUPS_MAXSAVE 32 /**** Maximum number of saves ****/ + + +/* + * Types and structures... + */ + +struct _cups_array_s /**** CUPS array structure ****/ +{ + /* + * The current implementation uses an insertion sort into an array of + * sorted pointers. We leave the array type private/opaque so that we + * can change the underlying implementation without affecting the users + * of this API. + */ + + int num_elements, /* Number of array elements */ + alloc_elements, /* Allocated array elements */ + current, /* Current element */ + insert, /* Last inserted element */ + unique, /* Are all elements unique? */ + num_saved, /* Number of saved elements */ + saved[_CUPS_MAXSAVE]; + /* Saved elements */ + void **elements; /* Array elements */ + cups_array_func_t compare; /* Element comparison function */ + void *data; /* User data passed to compare */ + cups_ahash_func_t hashfunc; /* Hash function */ + int hashsize, /* Size of hash */ + *hash; /* Hash array */ +}; + + +/* + * Local functions... + */ + +static int cups_array_add(cups_array_t *a, void *e, int insert); +static int cups_array_find(cups_array_t *a, void *e, int prev, int *rdiff); + + +/* + * 'cupsArrayAdd()' - Add an element to the array. + * + * When adding an element to a sorted array, non-unique elements are + * appended at the end of the run of identical elements. For unsorted arrays, + * the element is appended to the end of the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsArrayAdd(cups_array_t *a, /* I - Array */ + void *e) /* I - Element */ +{ + DEBUG_printf(("2cupsArrayAdd(a=%p, e=%p)", a, e)); + + /* + * Range check input... + */ + + if (!a || !e) + { + DEBUG_puts("3cupsArrayAdd: returning 0"); + return (0); + } + + /* + * Append the element... + */ + + return (cups_array_add(a, e, 0)); +} + + +/* + * 'cupsArrayClear()' - Clear the array. + * + * This function is equivalent to removing all elements in the array. + * The caller is responsible for freeing the memory used by the + * elements themselves. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsArrayClear(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return; + + /* + * Set the number of elements to 0; we don't actually free the memory + * here - that is done in cupsArrayDelete()... + */ + + a->num_elements = 0; + a->current = -1; + a->insert = -1; + a->unique = 1; + a->num_saved = 0; +} + + +/* + * 'cupsArrayCount()' - Get the number of elements in the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Number of elements */ +cupsArrayCount(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return (0); + + /* + * Return the number of elements... + */ + + return (a->num_elements); +} + + +/* + * 'cupsArrayCurrent()' - Return the current element in the array. + * + * The current element is undefined until you call @link cupsArrayFind@, + * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - Element */ +cupsArrayCurrent(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return (NULL); + + /* + * Return the current element... + */ + + if (a->current >= 0 && a->current < a->num_elements) + return (a->elements[a->current]); + else + return (NULL); +} + + +/* + * 'cupsArrayDelete()' - Free all memory used by the array. + * + * The caller is responsible for freeing the memory used by the + * elements themselves. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsArrayDelete(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return; + + /* + * Free the array of element pointers - the caller is responsible + * for freeing the elements themselves... + */ + + if (a->alloc_elements) + free(a->elements); + + if (a->hashsize) + free(a->hash); + + free(a); +} + + +/* + * 'cupsArrayDup()' - Duplicate the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_array_t * /* O - Duplicate array */ +cupsArrayDup(cups_array_t *a) /* I - Array */ +{ + cups_array_t *da; /* Duplicate array */ + + + /* + * Range check input... + */ + + if (!a) + return (NULL); + + /* + * Allocate memory for the array... + */ + + da = calloc(1, sizeof(cups_array_t)); + if (!da) + return (NULL); + + da->compare = a->compare; + da->data = a->data; + da->current = a->current; + da->insert = a->insert; + da->unique = a->unique; + da->num_saved = a->num_saved; + + memcpy(da->saved, a->saved, sizeof(a->saved)); + + if (a->num_elements) + { + /* + * Allocate memory for the elements... + */ + + da->elements = malloc(a->num_elements * sizeof(void *)); + if (!da->elements) + { + free(da); + return (NULL); + } + + /* + * Copy the element pointers... + */ + + memcpy(da->elements, a->elements, a->num_elements * sizeof(void *)); + da->num_elements = a->num_elements; + da->alloc_elements = a->num_elements; + } + + /* + * Return the new array... + */ + + return (da); +} + + +/* + * 'cupsArrayFind()' - Find an element in the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - Element found or @code NULL@ */ +cupsArrayFind(cups_array_t *a, /* I - Array */ + void *e) /* I - Element */ +{ + int current, /* Current element */ + diff, /* Difference */ + hash; /* Hash index */ + + + /* + * Range check input... + */ + + if (!a || !e) + return (NULL); + + /* + * See if we have any elements... + */ + + if (!a->num_elements) + return (NULL); + + /* + * Yes, look for a match... + */ + + if (a->hash) + { + hash = (*(a->hashfunc))(e, a->data); + + if (hash < 0 || hash >= a->hashsize) + { + current = a->current; + hash = -1; + } + else + { + current = a->hash[hash]; + + if (current < 0 || current >= a->num_elements) + current = a->current; + } + } + else + { + current = a->current; + hash = -1; + } + + current = cups_array_find(a, e, current, &diff); + if (!diff) + { + /* + * Found a match! If the array does not contain unique values, find + * the first element that is the same... + */ + + if (!a->unique && a->compare) + { + /* + * The array is not unique, find the first match... + */ + + while (current > 0 && !(*(a->compare))(e, a->elements[current - 1], + a->data)) + current --; + } + + a->current = current; + + if (hash >= 0) + a->hash[hash] = current; + + return (a->elements[current]); + } + else + { + /* + * No match... + */ + + a->current = -1; + + return (NULL); + } +} + + +/* + * 'cupsArrayFirst()' - Get the first element in the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - First element or @code NULL@ if the array is empty */ +cupsArrayFirst(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return (NULL); + + /* + * Return the first element... + */ + + a->current = 0; + + return (cupsArrayCurrent(a)); +} + + +/* + * 'cupsArrayGetIndex()' - Get the index of the current element. + * + * The current element is undefined until you call @link cupsArrayFind@, + * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - Index of the current element, starting at 0 */ +cupsArrayGetIndex(cups_array_t *a) /* I - Array */ +{ + if (!a) + return (-1); + else + return (a->current); +} + + +/* + * 'cupsArrayGetInsert()' - Get the index of the last inserted element. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - Index of the last inserted element, starting at 0 */ +cupsArrayGetInsert(cups_array_t *a) /* I - Array */ +{ + if (!a) + return (-1); + else + return (a->insert); +} + + +/* + * 'cupsArrayIndex()' - Get the N-th element in the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - N-th element or @code NULL@ */ +cupsArrayIndex(cups_array_t *a, /* I - Array */ + int n) /* I - Index into array, starting at 0 */ +{ + if (!a) + return (NULL); + + a->current = n; + + return (cupsArrayCurrent(a)); +} + + +/* + * 'cupsArrayInsert()' - Insert an element in the array. + * + * When inserting an element in a sorted array, non-unique elements are + * inserted at the beginning of the run of identical elements. For unsorted + * arrays, the element is inserted at the beginning of the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on failure, 1 on success */ +cupsArrayInsert(cups_array_t *a, /* I - Array */ + void *e) /* I - Element */ +{ + DEBUG_printf(("2cupsArrayInsert(a=%p, e=%p)", a, e)); + + /* + * Range check input... + */ + + if (!a || !e) + { + DEBUG_puts("3cupsArrayInsert: returning 0"); + return (0); + } + + /* + * Insert the element... + */ + + return (cups_array_add(a, e, 1)); +} + + +/* + * 'cupsArrayLast()' - Get the last element in the array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - Last element or @code NULL@ if the array is empty */ +cupsArrayLast(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return (NULL); + + /* + * Return the last element... + */ + + a->current = a->num_elements - 1; + + return (cupsArrayCurrent(a)); +} + + +/* + * 'cupsArrayNew()' - Create a new array. + * + * The comparison function ("f") is used to create a sorted array. The function + * receives pointers to two elements and the user data pointer ("d") - the user + * data pointer argument can safely be omitted when not required so functions + * like @code strcmp@ can be used for sorted string arrays. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_array_t * /* O - Array */ +cupsArrayNew(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */ + void *d) /* I - User data pointer or @code NULL@ */ +{ + return (cupsArrayNew2(f, d, 0, 0)); +} + + +/* + * 'cupsArrayNew2()' - Create a new array with hash. + * + * The comparison function ("f") is used to create a sorted array. The function + * receives pointers to two elements and the user data pointer ("d") - the user + * data pointer argument can safely be omitted when not required so functions + * like @code strcmp@ can be used for sorted string arrays. + * + * The hash function ("h") is used to implement cached lookups with the + * specified hash size ("hsize"). + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +cups_array_t * /* O - Array */ +cupsArrayNew2(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */ + void *d, /* I - User data or @code NULL@ */ + cups_ahash_func_t h, /* I - Hash function or @code NULL@ for unhashed lookups */ + int hsize) /* I - Hash size (>= 0) */ +{ + cups_array_t *a; /* Array */ + + + /* + * Allocate memory for the array... + */ + + a = calloc(1, sizeof(cups_array_t)); + if (!a) + return (NULL); + + a->compare = f; + a->data = d; + a->current = -1; + a->insert = -1; + a->num_saved = 0; + a->unique = 1; + + if (hsize > 0 && h) + { + a->hashfunc = h; + a->hashsize = hsize; + a->hash = malloc(hsize * sizeof(int)); + + if (!a->hash) + { + free(a); + return (NULL); + } + + memset(a->hash, -1, hsize * sizeof(int)); + } + + return (a); +} + + +/* + * 'cupsArrayNext()' - Get the next element in the array. + * + * This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) + 1)". + * + * The next element is undefined until you call @link cupsArrayFind@, + * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@ + * to set the current element. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - Next element or @code NULL@ */ +cupsArrayNext(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return (NULL); + + /* + * Return the next element... + */ + + if (a->current < a->num_elements) + a->current ++; + + return (cupsArrayCurrent(a)); +} + + +/* + * 'cupsArrayPrev()' - Get the previous element in the array. + * + * This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) - 1)". + * + * The previous element is undefined until you call @link cupsArrayFind@, + * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@ + * to set the current element. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - Previous element or @code NULL@ */ +cupsArrayPrev(cups_array_t *a) /* I - Array */ +{ + /* + * Range check input... + */ + + if (!a) + return (NULL); + + /* + * Return the previous element... + */ + + if (a->current >= 0) + a->current --; + + return (cupsArrayCurrent(a)); +} + + +/* + * 'cupsArrayRemove()' - Remove an element from the array. + * + * If more than one element matches "e", only the first matching element is + * removed. + * + * The caller is responsible for freeing the memory used by the + * removed element. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsArrayRemove(cups_array_t *a, /* I - Array */ + void *e) /* I - Element */ +{ + int i, /* Looping var */ + current, /* Current element */ + diff; /* Difference */ + + + /* + * Range check input... + */ + + if (!a || !e) + return (0); + + /* + * See if the element is in the array... + */ + + if (!a->num_elements) + return (0); + + current = cups_array_find(a, e, a->current, &diff); + if (diff) + return (0); + + /* + * Yes, now remove it... + */ + + a->num_elements --; + + if (current < a->num_elements) + memmove(a->elements + current, a->elements + current + 1, + (a->num_elements - current) * sizeof(void *)); + + if (current <= a->current) + a->current --; + + if (current < a->insert) + a->insert --; + else if (current == a->insert) + a->insert = -1; + + for (i = 0; i < a->num_saved; i ++) + if (current <= a->saved[i]) + a->saved[i] --; + + if (a->num_elements <= 1) + a->unique = 1; + + return (1); +} + + +/* + * 'cupsArrayRestore()' - Reset the current element to the last @link cupsArraySave@. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - New current element */ +cupsArrayRestore(cups_array_t *a) /* I - Array */ +{ + if (!a) + return (NULL); + + if (a->num_saved <= 0) + return (NULL); + + a->num_saved --; + a->current = a->saved[a->num_saved]; + + if (a->current >= 0 && a->current < a->num_elements) + return (a->elements[a->current]); + else + return (NULL); +} + + +/* + * 'cupsArraySave()' - Mark the current element for a later @link cupsArrayRestore@. + * + * The current element is undefined until you call @link cupsArrayFind@, + * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@ + * to set the current element. + * + * The save/restore stack is guaranteed to be at least 32 elements deep. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsArraySave(cups_array_t *a) /* I - Array */ +{ + if (!a) + return (0); + + if (a->num_saved >= _CUPS_MAXSAVE) + return (0); + + a->saved[a->num_saved] = a->current; + a->num_saved ++; + + return (1); +} + + +/* + * 'cupsArrayUserData()' - Return the user data for an array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void * /* O - User data */ +cupsArrayUserData(cups_array_t *a) /* I - Array */ +{ + if (a) + return (a->data); + else + return (NULL); +} + + +/* + * 'cups_array_add()' - Insert or append an element to the array... + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +static int /* O - 1 on success, 0 on failure */ +cups_array_add(cups_array_t *a, /* I - Array */ + void *e, /* I - Element to add */ + int insert) /* I - 1 = insert, 0 = append */ +{ + int i, /* Looping var */ + current, /* Current element */ + diff; /* Comparison with current element */ + + + DEBUG_printf(("7cups_array_add(a=%p, e=%p, insert=%d)", a, e, insert)); + + /* + * Verify we have room for the new element... + */ + + if (a->num_elements >= a->alloc_elements) + { + /* + * Allocate additional elements; start with 16 elements, then + * double the size until 1024 elements, then add 1024 elements + * thereafter... + */ + + void **temp; /* New array elements */ + int count; /* New allocation count */ + + + if (a->alloc_elements == 0) + { + count = 16; + temp = malloc(count * sizeof(void *)); + } + else + { + if (a->alloc_elements < 1024) + count = a->alloc_elements * 2; + else + count = a->alloc_elements + 1024; + + temp = realloc(a->elements, count * sizeof(void *)); + } + + DEBUG_printf(("9cups_array_add: count=%d", count)); + + if (!temp) + { + DEBUG_puts("9cups_array_add: allocation failed, returning 0"); + return (0); + } + + a->alloc_elements = count; + a->elements = temp; + } + + /* + * Find the insertion point for the new element; if there is no + * compare function or elements, just add it to the beginning or end... + */ + + if (!a->num_elements || !a->compare) + { + /* + * No elements or comparison function, insert/append as needed... + */ + + if (insert) + current = 0; /* Insert at beginning */ + else + current = a->num_elements; /* Append to the end */ + } + else + { + /* + * Do a binary search for the insertion point... + */ + + current = cups_array_find(a, e, a->insert, &diff); + + if (diff > 0) + { + /* + * Insert after the current element... + */ + + current ++; + } + else if (!diff) + { + /* + * Compared equal, make sure we add to the begining or end of + * the current run of equal elements... + */ + + a->unique = 0; + + if (insert) + { + /* + * Insert at beginning of run... + */ + + while (current > 0 && !(*(a->compare))(e, a->elements[current - 1], + a->data)) + current --; + } + else + { + /* + * Append at end of run... + */ + + do + { + current ++; + } + while (current < a->num_elements && + !(*(a->compare))(e, a->elements[current], a->data)); + } + } + } + + /* + * Insert or append the element... + */ + + if (current < a->num_elements) + { + /* + * Shift other elements to the right... + */ + + memmove(a->elements + current + 1, a->elements + current, + (a->num_elements - current) * sizeof(void *)); + + if (a->current >= current) + a->current ++; + + for (i = 0; i < a->num_saved; i ++) + if (a->saved[i] >= current) + a->saved[i] ++; + + DEBUG_printf(("9cups_array_add: insert element at index %d...", current)); + } +#ifdef DEBUG + else + DEBUG_printf(("9cups_array_add: append element at %d...", current)); +#endif /* DEBUG */ + + a->elements[current] = e; + a->num_elements ++; + a->insert = current; + +#ifdef DEBUG + for (current = 0; current < a->num_elements; current ++) + DEBUG_printf(("9cups_array_add: a->elements[%d]=%p", current, + a->elements[current])); +#endif /* DEBUG */ + + DEBUG_puts("9cups_array_add: returning 1"); + + return (1); +} + + +/* + * 'cups_array_find()' - Find an element in the array... + */ + +static int /* O - Index of match */ +cups_array_find(cups_array_t *a, /* I - Array */ + void *e, /* I - Element */ + int prev, /* I - Previous index */ + int *rdiff) /* O - Difference of match */ +{ + int left, /* Left side of search */ + right, /* Right side of search */ + current, /* Current element */ + diff; /* Comparison with current element */ + + + DEBUG_printf(("7cups_array_find(a=%p, e=%p, prev=%d, rdiff=%p)", a, e, prev, + rdiff)); + + if (a->compare) + { + /* + * Do a binary search for the element... + */ + + DEBUG_puts("9cups_array_find: binary search"); + + if (prev >= 0 && prev < a->num_elements) + { + /* + * Start search on either side of previous... + */ + + if ((diff = (*(a->compare))(e, a->elements[prev], a->data)) == 0 || + (diff < 0 && prev == 0) || + (diff > 0 && prev == (a->num_elements - 1))) + { + /* + * Exact or edge match, return it! + */ + + DEBUG_printf(("9cups_array_find: Returning %d, diff=%d", prev, diff)); + + *rdiff = diff; + + return (prev); + } + else if (diff < 0) + { + /* + * Start with previous on right side... + */ + + left = 0; + right = prev; + } + else + { + /* + * Start wih previous on left side... + */ + + left = prev; + right = a->num_elements - 1; + } + } + else + { + /* + * Start search in the middle... + */ + + left = 0; + right = a->num_elements - 1; + } + + do + { + current = (left + right) / 2; + diff = (*(a->compare))(e, a->elements[current], a->data); + + DEBUG_printf(("9cups_array_find: left=%d, right=%d, current=%d, diff=%d", + left, right, current, diff)); + + if (diff == 0) + break; + else if (diff < 0) + right = current; + else + left = current; + } + while ((right - left) > 1); + + if (diff != 0) + { + /* + * Check the last 1 or 2 elements... + */ + + if ((diff = (*(a->compare))(e, a->elements[left], a->data)) <= 0) + current = left; + else + { + diff = (*(a->compare))(e, a->elements[right], a->data); + current = right; + } + } + } + else + { + /* + * Do a linear pointer search... + */ + + DEBUG_puts("9cups_array_find: linear search"); + + diff = 1; + + for (current = 0; current < a->num_elements; current ++) + if (a->elements[current] == e) + { + diff = 0; + break; + } + } + + /* + * Return the closest element and the difference... + */ + + DEBUG_printf(("8cups_array_find: Returning %d, diff=%d", current, diff)); + + *rdiff = diff; + + return (current); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/array.h b/cups/array.h new file mode 100644 index 0000000000..c619dc3c9a --- /dev/null +++ b/cups/array.h @@ -0,0 +1,84 @@ +/* + * "$Id$" + * + * Sorted array definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_ARRAY_H_ +# define _CUPS_ARRAY_H_ + +/* + * Include necessary headers... + */ + +# include "versioning.h" +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Types and structures... + */ + +typedef struct _cups_array_s cups_array_t; + /**** CUPS array type ****/ +typedef int (*cups_array_func_t)(void *first, void *second, void *data); + /**** Array comparison function ****/ +typedef int (*cups_ahash_func_t)(void *element, void *data); + /**** Array hash function ****/ + + +/* + * Functions... + */ + +extern int cupsArrayAdd(cups_array_t *a, void *e) _CUPS_API_1_2; +extern void cupsArrayClear(cups_array_t *a) _CUPS_API_1_2; +extern int cupsArrayCount(cups_array_t *a) _CUPS_API_1_2; +extern void *cupsArrayCurrent(cups_array_t *a) _CUPS_API_1_2; +extern void cupsArrayDelete(cups_array_t *a) _CUPS_API_1_2; +extern cups_array_t *cupsArrayDup(cups_array_t *a) _CUPS_API_1_2; +extern void *cupsArrayFind(cups_array_t *a, void *e) _CUPS_API_1_2; +extern void *cupsArrayFirst(cups_array_t *a) _CUPS_API_1_2; +extern int cupsArrayGetIndex(cups_array_t *a) _CUPS_API_1_3; +extern int cupsArrayGetInsert(cups_array_t *a) _CUPS_API_1_3; +extern void *cupsArrayIndex(cups_array_t *a, int n) _CUPS_API_1_2; +extern int cupsArrayInsert(cups_array_t *a, void *e) _CUPS_API_1_2; +extern void *cupsArrayLast(cups_array_t *a) _CUPS_API_1_2; +extern cups_array_t *cupsArrayNew(cups_array_func_t f, void *d) _CUPS_API_1_2; +extern cups_array_t *cupsArrayNew2(cups_array_func_t f, void *d, + cups_ahash_func_t h, int hsize) _CUPS_API_1_3; +extern void *cupsArrayNext(cups_array_t *a) _CUPS_API_1_2; +extern void *cupsArrayPrev(cups_array_t *a) _CUPS_API_1_2; +extern int cupsArrayRemove(cups_array_t *a, void *e) _CUPS_API_1_2; +extern void *cupsArrayRestore(cups_array_t *a) _CUPS_API_1_2; +extern int cupsArraySave(cups_array_t *a) _CUPS_API_1_2; +extern void *cupsArrayUserData(cups_array_t *a) _CUPS_API_1_2; + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_ARRAY_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/attr.c b/cups/attr.c new file mode 100644 index 0000000000..92f3534946 --- /dev/null +++ b/cups/attr.c @@ -0,0 +1,422 @@ +/* + * "$Id$" + * + * PPD model-specific attribute routines for the Common UNIX Printing System + * (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * ppdFindAttr() - Find the first matching attribute. + * ppdFindNextAttr() - Find the next matching attribute. + * _ppdGet1284Values() - Get 1284 device ID keys and values. + * _ppdNormalizeMakeAndModel() - Normalize a product/make-and-model string. + */ + +/* + * Include necessary headers... + */ + +#include "ppd-private.h" +#include "debug.h" +#include "string.h" +#include + + +/* + * 'ppdFindAttr()' - Find the first matching attribute. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ppd_attr_t * /* O - Attribute or @code NULL@ if not found */ +ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */ + const char *name, /* I - Attribute name */ + const char *spec) /* I - Specifier string or @code NULL@ */ +{ + ppd_attr_t key, /* Search key */ + *attr; /* Current attribute */ + + + DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name, + spec)); + + /* + * Range check input... + */ + + if (!ppd || !name || ppd->num_attrs == 0) + return (NULL); + + /* + * Search for a matching attribute... + */ + + memset(&key, 0, sizeof(key)); + strlcpy(key.name, name, sizeof(key.name)); + + /* + * Return the first matching attribute, if any... + */ + + if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL) + { + if (spec) + { + /* + * Loop until we find the first matching attribute for "spec"... + */ + + while (attr && strcasecmp(spec, attr->spec)) + { + if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL && + strcasecmp(attr->name, name)) + attr = NULL; + } + } + } + + return (attr); +} + + +/* + * 'ppdFindNextAttr()' - Find the next matching attribute. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ppd_attr_t * /* O - Attribute or @code NULL@ if not found */ +ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */ + const char *name, /* I - Attribute name */ + const char *spec) /* I - Specifier string or @code NULL@ */ +{ + ppd_attr_t *attr; /* Current attribute */ + + + /* + * Range check input... + */ + + if (!ppd || !name || ppd->num_attrs == 0) + return (NULL); + + /* + * See if there are more attributes to return... + */ + + while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL) + { + /* + * Check the next attribute to see if it is a match... + */ + + if (strcasecmp(attr->name, name)) + { + /* + * Nope, reset the current pointer to the end of the array... + */ + + cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs)); + + return (NULL); + } + + if (!spec || !strcasecmp(attr->spec, spec)) + break; + } + + /* + * Return the next attribute's value... + */ + + return (attr); +} + + +/* + * '_ppdGet1284Values()' - Get 1284 device ID keys and values. + * + * The returned dictionary is a CUPS option array that can be queried with + * cupsGetOption and freed with cupsFreeOptions. + */ + +int /* O - Number of key/value pairs */ +_ppdGet1284Values( + const char *device_id, /* I - IEEE-1284 device ID string */ + cups_option_t **values) /* O - Array of key/value pairs */ +{ + int num_values; /* Number of values */ + char key[256], /* Key string */ + value[256], /* Value string */ + *ptr; /* Pointer into key/value */ + + + /* + * Range check input... + */ + + if (values) + *values = NULL; + + if (!device_id || !values) + return (0); + + /* + * Parse the 1284 device ID value into keys and values. The format is + * repeating sequences of: + * + * [whitespace]key:value[whitespace]; + */ + + num_values = 0; + while (*device_id) + { + while (_cups_isspace(*device_id)) + device_id ++; + + if (!*device_id) + break; + + for (ptr = key; *device_id && *device_id != ':'; device_id ++) + if (ptr < (key + sizeof(key) - 1)) + *ptr++ = *device_id; + + if (!*device_id) + break; + + while (ptr > key && _cups_isspace(ptr[-1])) + ptr --; + + *ptr = '\0'; + device_id ++; + + while (_cups_isspace(*device_id)) + device_id ++; + + if (!*device_id) + break; + + for (ptr = value; *device_id && *device_id != ';'; device_id ++) + if (ptr < (value + sizeof(value) - 1)) + *ptr++ = *device_id; + + if (!*device_id) + break; + + while (ptr > value && _cups_isspace(ptr[-1])) + ptr --; + + *ptr = '\0'; + device_id ++; + + num_values = cupsAddOption(key, value, num_values, values); + } + + return (num_values); +} + + +/* + * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string. + * + * This function tries to undo the mistakes made by many printer manufacturers + * to produce a clean make-and-model string we can use. + */ + +char * /* O - Normalized make-and-model string or NULL on error */ +_ppdNormalizeMakeAndModel( + const char *make_and_model, /* I - Original make-and-model string */ + char *buffer, /* I - String buffer */ + size_t bufsize) /* I - Size of string buffer */ +{ + char *bufptr; /* Pointer into buffer */ + + + if (!make_and_model || !buffer || bufsize < 1) + { + if (buffer) + *buffer = '\0'; + + return (NULL); + } + + /* + * Skip leading whitespace... + */ + + while (_cups_isspace(*make_and_model)) + make_and_model ++; + + /* + * Remove parenthesis and add manufacturers as needed... + */ + + if (make_and_model[0] == '(') + { + strlcpy(buffer, make_and_model + 1, bufsize); + + if ((bufptr = strrchr(buffer, ')')) != NULL) + *bufptr = '\0'; + } + else if (!strncasecmp(make_and_model, "XPrint", 6)) + { + /* + * Xerox XPrint... + */ + + snprintf(buffer, bufsize, "Xerox %s", make_and_model); + } + else if (!strncasecmp(make_and_model, "Eastman", 7)) + { + /* + * Kodak... + */ + + snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7); + } + else if (!strncasecmp(make_and_model, "laserwriter", 11)) + { + /* + * Apple LaserWriter... + */ + + snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11); + } + else if (!strncasecmp(make_and_model, "colorpoint", 10)) + { + /* + * Seiko... + */ + + snprintf(buffer, bufsize, "Seiko %s", make_and_model); + } + else if (!strncasecmp(make_and_model, "fiery", 5)) + { + /* + * EFI... + */ + + snprintf(buffer, bufsize, "EFI %s", make_and_model); + } + else if (!strncasecmp(make_and_model, "ps ", 3) || + !strncasecmp(make_and_model, "colorpass", 9)) + { + /* + * Canon... + */ + + snprintf(buffer, bufsize, "Canon %s", make_and_model); + } + else if (!strncasecmp(make_and_model, "primera", 7)) + { + /* + * Fargo... + */ + + snprintf(buffer, bufsize, "Fargo %s", make_and_model); + } + else if (!strncasecmp(make_and_model, "designjet", 9) || + !strncasecmp(make_and_model, "deskjet", 7)) + { + /* + * HP... + */ + + snprintf(buffer, bufsize, "HP %s", make_and_model); + } + else + strlcpy(buffer, make_and_model, bufsize); + + /* + * Clean up the make... + */ + + if (!strncasecmp(buffer, "agfa", 4)) + { + /* + * Replace with AGFA (all uppercase)... + */ + + buffer[0] = 'A'; + buffer[1] = 'G'; + buffer[2] = 'F'; + buffer[3] = 'A'; + } + else if (!strncasecmp(buffer, "Hewlett-Packard hp ", 19)) + { + /* + * Just put "HP" on the front... + */ + + buffer[0] = 'H'; + buffer[1] = 'P'; + _cups_strcpy(buffer + 2, buffer + 18); + } + else if (!strncasecmp(buffer, "Hewlett-Packard ", 16)) + { + /* + * Just put "HP" on the front... + */ + + buffer[0] = 'H'; + buffer[1] = 'P'; + _cups_strcpy(buffer + 2, buffer + 15); + } + else if (!strncasecmp(buffer, "Lexmark International", 21)) + { + /* + * Strip "International"... + */ + + _cups_strcpy(buffer + 8, buffer + 21); + } + else if (!strncasecmp(buffer, "herk", 4)) + { + /* + * Replace with LHAG... + */ + + buffer[0] = 'L'; + buffer[1] = 'H'; + buffer[2] = 'A'; + buffer[3] = 'G'; + } + else if (!strncasecmp(buffer, "linotype", 8)) + { + /* + * Replace with LHAG... + */ + + buffer[0] = 'L'; + buffer[1] = 'H'; + buffer[2] = 'A'; + buffer[3] = 'G'; + _cups_strcpy(buffer + 4, buffer + 8); + } + + /* + * Remove trailing whitespace and return... + */ + + for (bufptr = buffer + strlen(buffer) - 1; + bufptr >= buffer && _cups_isspace(*bufptr); + bufptr --); + + bufptr[1] = '\0'; + + return (buffer[0] ? buffer : NULL); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/auth.c b/cups/auth.c new file mode 100644 index 0000000000..9fe3badf38 --- /dev/null +++ b/cups/auth.c @@ -0,0 +1,724 @@ +/* + * "$Id$" + * + * Authentication functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsDoAuthentication() - Authenticate a request. + * cups_get_gssname() - Get GSSAPI name for authentication. + * cups_gss_printf() - Show error messages from GSSAPI... + * cups_local_auth() - Get the local authorization certificate if + * available/applicable... + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include +#include +#include +#include +#include +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + +#if HAVE_AUTHORIZATION_H +# include +# ifdef HAVE_SECBASEPRIV_H +# include +# else +extern const char *cssmErrorString(int error); +# endif /* HAVE_SECBASEPRIV_H */ +#endif /* HAVE_AUTHORIZATION_H */ + +#if defined(SO_PEERCRED) && defined(AF_LOCAL) +# include +#endif /* SO_PEERCRED && AF_LOCAL */ + + +/* + * Local functions... + */ + +#ifdef HAVE_GSSAPI +static gss_name_t cups_get_gssname(http_t *http, const char *service_name); +# ifdef DEBUG +static void cups_gss_printf(OM_uint32 major_status, OM_uint32 minor_status, + const char *message); +# else +# define cups_gss_printf(major, minor, message) +# endif /* DEBUG */ +#endif /* HAVE_GSSAPI */ +static int cups_local_auth(http_t *http); + + +/* + * 'cupsDoAuthentication()' - Authenticate a request. + * + * This function should be called in response to a @code HTTP_UNAUTHORIZED@ + * status, prior to resubmitting your request. + * + * @since CUPS 1.1.20/Mac OS X 10.4@ + */ + +int /* O - 0 on success, -1 on error */ +cupsDoAuthentication( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *method, /* I - Request method ("GET", "POST", "PUT") */ + const char *resource) /* I - Resource path */ +{ + const char *password; /* Password string */ + char prompt[1024], /* Prompt for user */ + realm[HTTP_MAX_VALUE], /* realm="xyz" string */ + nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */ + int localauth; /* Local authentication result */ + _cups_globals_t *cg; /* Global data */ + + + DEBUG_printf(("cupsDoAuthentication(http=%p, method=\"%s\", resource=\"%s\")", + http, method, resource)); + + if (!http) + http = _cupsConnect(); + + if (!http || !method || !resource) + return (-1); + + DEBUG_printf(("2cupsDoAuthentication: digest_tries=%d, userpass=\"%s\"", + http->digest_tries, http->userpass)); + DEBUG_printf(("2cupsDoAuthentication: WWW-Authenticate=\"%s\"", + httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE))); + + /* + * Clear the current authentication string... + */ + + httpSetAuthString(http, NULL, NULL); + + /* + * See if we can do local authentication... + */ + + if (http->digest_tries < 3) + { + if ((localauth = cups_local_auth(http)) == 0) + { + DEBUG_printf(("2cupsDoAuthentication: authstring=\"%s\"", + http->authstring)); + + if (http->status == HTTP_UNAUTHORIZED) + http->digest_tries ++; + + return (0); + } + else if (localauth == -1) + { + http->status = HTTP_AUTHORIZATION_CANCELED; + return (-1); /* Error or canceled */ + } + } + + /* + * Nope, see if we should retry the current username:password... + */ + + if ((http->digest_tries > 1 || !http->userpass[0]) && + strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9)) + { + /* + * Nope - get a new password from the user... + */ + + cg = _cupsGlobals(); + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + snprintf(prompt, sizeof(prompt), + _cupsLangString(cg->lang_default, _("Password for %s on %s? ")), + cupsUser(), + http->hostname[0] == '/' ? "localhost" : http->hostname); + + http->digest_tries = strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], + "Digest", 5) != 0; + http->userpass[0] = '\0'; + + if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) + { + http->status = HTTP_AUTHORIZATION_CANCELED; + return (-1); + } + + if (!password[0]) + { + http->status = HTTP_AUTHORIZATION_CANCELED; + return (-1); + } + + snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(), + password); + } + else if (http->status == HTTP_UNAUTHORIZED) + http->digest_tries ++; + + if (http->status == HTTP_UNAUTHORIZED && http->digest_tries >= 3) + { + DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)", + http->digest_tries)); + + http->status = HTTP_AUTHORIZATION_CANCELED; + return (-1); + } + + /* + * Got a password; encode it for the server... + */ + + if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9)) + { +#ifdef HAVE_GSSAPI + /* + * Kerberos authentication... + */ + + OM_uint32 minor_status, /* Minor status code */ + major_status; /* Major status code */ + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER, + /* Output token */ + input_token = GSS_C_EMPTY_BUFFER; + /* Input token */ + char *gss_service_name; + /* GSS service name */ +# ifdef USE_SPNEGO + const char *authorization; + /* Pointer into Authorization string */ +# endif /* USE_SPNEGO */ + + +# ifdef __APPLE__ + /* + * If the weak-linked GSSAPI/Kerberos library is not present, don't try + * to use it... + */ + + if (gss_init_sec_context == NULL) + { + DEBUG_puts("1cupsDoAuthentication: Weak-linked GSSAPI/Kerberos framework " + "is not present"); + http->status = HTTP_AUTHORIZATION_CANCELED; + + return (-1); + } +# endif /* __APPLE__ */ + + if (http->gssname == GSS_C_NO_NAME) + { + if ((gss_service_name = getenv("CUPS_GSSSERVICENAME")) == NULL) + gss_service_name = CUPS_DEFAULT_GSSSERVICENAME; + else + DEBUG_puts("2cupsDoAuthentication: GSS service name set via " + "environment variable"); + + http->gssname = cups_get_gssname(http, gss_service_name); + } + +# ifdef USE_SPNEGO /* We don't implement SPNEGO just yet... */ + /* + * Find the start of the Kerberos input token... + */ + + authorization = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE); + + authorization += 9; + while (*authorization && _cups_isspace(*authorization)) + authorization ++; + + if (*authorization) + { + /* + * Decode the authorization string to get the input token... + */ + + int len = strlen(authorization); + + input_token.value = malloc(len); + input_token.value = httpDecode64_2(input_token.value, &len, + authorization); + input_token.length = len; + +# ifdef DEBUG + { + char *ptr = (char *)input_token.value; + int left = len; + + fputs("input_token=", stdout); + while (left > 0) + { + if (*ptr < ' ') + printf("\\%03o", *ptr & 255); + else + putchar(*ptr); + ptr ++; + left --; + } + putchar('\n'); + } +# endif /* DEBUG */ + } +# endif /* USE_SPNEGO */ + + if (http->gssctx != GSS_C_NO_CONTEXT) + { + gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER); + http->gssctx = GSS_C_NO_CONTEXT; + } + + major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, + &http->gssctx, + http->gssname, http->gssmech, +#ifdef GSS_C_DELEG_POLICY_FLAG + GSS_C_DELEG_POLICY_FLAG | +#endif /* GSS_C_DELEG_POLICY_FLAG */ + GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG, + GSS_C_INDEFINITE, + GSS_C_NO_CHANNEL_BINDINGS, + &input_token, &http->gssmech, + &output_token, NULL, NULL); + + if (input_token.value) + free(input_token.value); + + if (GSS_ERROR(major_status)) + { + cups_gss_printf(major_status, minor_status, + "cupsDoAuthentication: Unable to initialize security " + "context"); + http->status = HTTP_AUTHORIZATION_CANCELED; + + return (-1); + } + + if (major_status == GSS_S_CONTINUE_NEEDED) + cups_gss_printf(major_status, minor_status, + "cupsDoAuthentication: Continuation needed!"); + + if (output_token.length > 0 && output_token.length <= 65536) + { + /* + * Allocate the authorization string since Windows KDCs can have + * arbitrarily large credentials... + */ + + int authsize = 10 + /* "Negotiate " */ + output_token.length * 4 / 3 + 1 + /* Base64 */ + 1; /* nul */ + + httpSetAuthString(http, NULL, NULL); + + if ((http->authstring = malloc(authsize)) == NULL) + { + http->authstring = http->_authstring; + authsize = sizeof(http->_authstring); + } + + strcpy(http->authstring, "Negotiate "); + httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value, + output_token.length); + + gss_release_buffer(&minor_status, &output_token); + } + else + { + DEBUG_printf(("1cupsDoAuthentication: Kerberos credentials too large - " + "%d bytes!", (int)output_token.length)); + http->status = HTTP_AUTHORIZATION_CANCELED; + gss_release_buffer(&minor_status, &output_token); + + return (-1); + } +#endif /* HAVE_GSSAPI */ + } + else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6)) + { + /* + * Basic authentication... + */ + + char encode[256]; /* Base64 buffer */ + + + httpEncode64_2(encode, sizeof(encode), http->userpass, + (int)strlen(http->userpass)); + httpSetAuthString(http, "Basic", encode); + } + else + { + /* + * Digest authentication... + */ + + char encode[33], /* MD5 buffer */ + digest[1024]; /* Digest auth data */ + + + httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm); + httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce); + + httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode); + httpMD5Final(nonce, method, resource, encode); + snprintf(digest, sizeof(digest), + "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", " + "response=\"%s\"", cupsUser(), realm, nonce, resource, encode); + httpSetAuthString(http, "Digest", digest); + } + + DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring)); + + return (0); +} + + +#ifdef HAVE_GSSAPI +/* + * 'cups_get_gssname()' - Get CUPS service credentials for authentication. + */ + +static gss_name_t /* O - Server name */ +cups_get_gssname( + http_t *http, /* I - Connection to server */ + const char *service_name) /* I - Service name */ +{ + gss_buffer_desc token = GSS_C_EMPTY_BUFFER; + /* Service token */ + OM_uint32 major_status, /* Major status code */ + minor_status; /* Minor status code */ + gss_name_t server_name; /* Server name */ + char buf[1024], /* Name buffer */ + fqdn[HTTP_MAX_URI]; /* Server name buffer */ + + + DEBUG_printf(("7cups_get_gssname(http=%p, service_name=\"%s\")", http, + service_name)); + + + /* + * Get the hostname... + */ + + httpGetHostname(http, fqdn, sizeof(fqdn)); + + if (!strcmp(fqdn, "localhost")) + httpGetHostname(NULL, fqdn, sizeof(fqdn)); + + /* + * Get a server name we can use for authentication purposes... + */ + + snprintf(buf, sizeof(buf), "%s@%s", service_name, fqdn); + + DEBUG_printf(("9cups_get_gssname: Looking up %s...", buf)); + + token.value = buf; + token.length = strlen(buf); + server_name = GSS_C_NO_NAME; + major_status = gss_import_name(&minor_status, &token, + GSS_C_NT_HOSTBASED_SERVICE, + &server_name); + + if (GSS_ERROR(major_status)) + { + cups_gss_printf(major_status, minor_status, + "cups_get_gssname: gss_import_name() failed"); + return (NULL); + } + + return (server_name); +} + + +# ifdef DEBUG +/* + * 'cups_gss_printf()' - Show debug error messages from GSSAPI... + */ + +static void +cups_gss_printf(OM_uint32 major_status,/* I - Major status code */ + OM_uint32 minor_status,/* I - Minor status code */ + const char *message) /* I - Prefix for error message */ +{ + OM_uint32 err_major_status, /* Major status code for display */ + err_minor_status; /* Minor status code for display */ + OM_uint32 msg_ctx; /* Message context */ + gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER, + /* Major status message */ + minor_status_string = GSS_C_EMPTY_BUFFER; + /* Minor status message */ + + + msg_ctx = 0; + err_major_status = gss_display_status(&err_minor_status, + major_status, + GSS_C_GSS_CODE, + GSS_C_NO_OID, + &msg_ctx, + &major_status_string); + + if (!GSS_ERROR(err_major_status)) + gss_display_status(&err_minor_status, minor_status, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &minor_status_string); + + DEBUG_printf(("1%s: %s, %s", message, (char *)major_status_string.value, + (char *)minor_status_string.value)); + + gss_release_buffer(&err_minor_status, &major_status_string); + gss_release_buffer(&err_minor_status, &minor_status_string); +} +# endif /* DEBUG */ +#endif /* HAVE_GSSAPI */ + + +/* + * 'cups_local_auth()' - Get the local authorization certificate if + * available/applicable... + */ + +static int /* O - 0 if available */ + /* 1 if not available */ + /* -1 error */ +cups_local_auth(http_t *http) /* I - HTTP connection to server */ +{ +#if defined(WIN32) || defined(__EMX__) + /* + * Currently WIN32 and OS-2 do not support the CUPS server... + */ + + return (1); +#else + int pid; /* Current process ID */ + FILE *fp; /* Certificate file */ + char trc[16], /* Try Root Certificate parameter */ + filename[1024], /* Certificate filename */ + certificate[33];/* Certificate string */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ +# if defined(HAVE_AUTHORIZATION_H) + OSStatus status; /* Status */ + AuthorizationItem auth_right; /* Authorization right */ + AuthorizationRights auth_rights; /* Authorization rights */ + AuthorizationFlags auth_flags; /* Authorization flags */ + AuthorizationExternalForm auth_extrn; /* Authorization ref external */ + char auth_key[1024]; /* Buffer */ + char buffer[1024]; /* Buffer */ +# endif /* HAVE_AUTHORIZATION_H */ + + + DEBUG_printf(("7cups_local_auth(http=%p) hostaddr=%s, hostname=\"%s\"", + http, httpAddrString(http->hostaddr, filename, sizeof(filename)), http->hostname)); + + /* + * See if we are accessing localhost... + */ + + if (!httpAddrLocalhost(http->hostaddr) && + strcasecmp(http->hostname, "localhost") != 0) + { + DEBUG_puts("8cups_local_auth: Not a local connection!"); + return (1); + } + +# if defined(HAVE_AUTHORIZATION_H) + /* + * Delete any previous authorization reference... + */ + + if (http->auth_ref) + { + AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); + http->auth_ref = NULL; + } + + if (!getenv("GATEWAY_INTERFACE") && + httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "authkey", + auth_key, sizeof(auth_key))) + { + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, + kAuthorizationFlagDefaults, &http->auth_ref); + if (status != errAuthorizationSuccess) + { + DEBUG_printf(("8cups_local_auth: AuthorizationCreate() returned %d (%s)", + (int)status, cssmErrorString(status))); + return (-1); + } + + auth_right.name = auth_key; + auth_right.valueLength = 0; + auth_right.value = NULL; + auth_right.flags = 0; + + auth_rights.count = 1; + auth_rights.items = &auth_right; + + auth_flags = kAuthorizationFlagDefaults | + kAuthorizationFlagPreAuthorize | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagExtendRights; + + status = AuthorizationCopyRights(http->auth_ref, &auth_rights, + kAuthorizationEmptyEnvironment, + auth_flags, NULL); + if (status == errAuthorizationSuccess) + status = AuthorizationMakeExternalForm(http->auth_ref, &auth_extrn); + + if (status == errAuthorizationSuccess) + { + /* + * Set the authorization string and return... + */ + + httpEncode64_2(buffer, sizeof(buffer), (void *)&auth_extrn, + sizeof(auth_extrn)); + + httpSetAuthString(http, "AuthRef", buffer); + + DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"", + http->authstring)); + return (0); + } + else if (status == errAuthorizationCanceled) + return (-1); + + DEBUG_printf(("9cups_local_auth: AuthorizationCopyRights() returned %d (%s)", + (int)status, cssmErrorString(status))); + + /* + * Fall through to try certificates... + */ + } +# endif /* HAVE_AUTHORIZATION_H */ + +# if defined(SO_PEERCRED) && defined(AF_LOCAL) + /* + * See if we can authenticate using the peer credentials provided over a + * domain socket; if so, specify "PeerCred username" as the authentication + * information... + */ + +# ifdef HAVE_GSSAPI + if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9) && +# else + if ( +# endif /* HAVE_GSSAPI */ + http->hostaddr->addr.sa_family == AF_LOCAL && + !getenv("GATEWAY_INTERFACE")) /* Not via CGI programs... */ + { + /* + * Verify that the current cupsUser() matches the current UID... + */ + + struct passwd *pwd; /* Password information */ + const char *username; /* Current username */ + + username = cupsUser(); + + if ((pwd = getpwnam(username)) != NULL && pwd->pw_uid == getuid()) + { + httpSetAuthString(http, "PeerCred", username); + + DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"", + http->authstring)); + + return (0); + } + } +# endif /* SO_PEERCRED && AF_LOCAL */ + + /* + * Try opening a certificate file for this PID. If that fails, + * try the root certificate... + */ + + pid = getpid(); + snprintf(filename, sizeof(filename), "%s/certs/%d", cg->cups_statedir, pid); + if ((fp = fopen(filename, "r")) == NULL && pid > 0) + { + /* + * No certificate for this PID; see if we can get the root certificate... + */ + + DEBUG_printf(("9cups_local_auth: Unable to open file %s: %s", + filename, strerror(errno))); + +#ifdef HAVE_GSSAPI + if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9)) + { + /* + * Kerberos required, don't try the root certificate... + */ + + return (1); + } +#endif /* HAVE_GSSAPI */ + + if (!httpGetSubField2(http, HTTP_FIELD_WWW_AUTHENTICATE, "trc", trc, + sizeof(trc))) + { + /* + * Scheduler doesn't want us to use the root certificate... + */ + + return (1); + } + + snprintf(filename, sizeof(filename), "%s/certs/0", cg->cups_statedir); + fp = fopen(filename, "r"); + } + + if (fp) + { + /* + * Read the certificate from the file... + */ + + fgets(certificate, sizeof(certificate), fp); + fclose(fp); + + /* + * Set the authorization string and return... + */ + + httpSetAuthString(http, "Local", certificate); + + DEBUG_printf(("8cups_local_auth: Returning authstring=\"%s\"", + http->authstring)); + + return (0); + } + + return (1); +#endif /* WIN32 || __EMX__ */ +} + + +/* + * End of "$Id$". + */ diff --git a/cups/backchannel.c b/cups/backchannel.c new file mode 100644 index 0000000000..bc04d46028 --- /dev/null +++ b/cups/backchannel.c @@ -0,0 +1,199 @@ +/* + * "$Id$" + * + * Backchannel functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsBackChannelRead() - Read data from the backchannel. + * cupsBackChannelWrite() - Write data to the backchannel. + * cups_setup() - Setup select() + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include +#ifdef WIN32 +# include +# include +#else +# include +#endif /* WIN32 */ + + +/* + * Local functions... + */ + +static void cups_setup(fd_set *set, struct timeval *tval, + double timeout); + + +/* + * 'cupsBackChannelRead()' - Read data from the backchannel. + * + * Reads up to "bytes" bytes from the backchannel/backend. The "timeout" + * parameter controls how many seconds to wait for the data - use 0.0 to + * return immediately if there is no data, -1.0 to wait for data indefinitely. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ssize_t /* O - Bytes read or -1 on error */ +cupsBackChannelRead(char *buffer, /* I - Buffer to read into */ + size_t bytes, /* I - Bytes to read */ + double timeout) /* I - Timeout in seconds, typically 0.0 to poll */ +{ + fd_set input; /* Input set */ + struct timeval tval; /* Timeout value */ + int status; /* Select status */ + + + /* + * Wait for input ready. + */ + + do + { + cups_setup(&input, &tval, timeout); + + if (timeout < 0.0) + status = select(4, &input, NULL, NULL, NULL); + else + status = select(4, &input, NULL, NULL, &tval); + } + while (status < 0 && errno != EINTR && errno != EAGAIN); + + if (status < 0) + return (-1); /* Timeout! */ + + /* + * Read bytes from the pipe... + */ + +#ifdef WIN32 + return ((ssize_t)_read(3, buffer, (unsigned)bytes)); +#else + return (read(3, buffer, bytes)); +#endif /* WIN32 */ +} + + +/* + * 'cupsBackChannelWrite()' - Write data to the backchannel. + * + * Writes "bytes" bytes to the backchannel/filter. The "timeout" parameter + * controls how many seconds to wait for the data to be written - use + * 0.0 to return immediately if the data cannot be written, -1.0 to wait + * indefinitely. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ssize_t /* O - Bytes written or -1 on error */ +cupsBackChannelWrite( + const char *buffer, /* I - Buffer to write */ + size_t bytes, /* I - Bytes to write */ + double timeout) /* I - Timeout in seconds, typically 1.0 */ +{ + fd_set output; /* Output set */ + struct timeval tval; /* Timeout value */ + int status; /* Select status */ + ssize_t count; /* Current bytes */ + size_t total; /* Total bytes */ + + + /* + * Write all bytes... + */ + + total = 0; + + while (total < bytes) + { + /* + * Wait for write-ready... + */ + + do + { + cups_setup(&output, &tval, timeout); + + if (timeout < 0.0) + status = select(4, NULL, &output, NULL, NULL); + else + status = select(4, NULL, &output, NULL, &tval); + } + while (status < 0 && errno != EINTR && errno != EAGAIN); + + if (status <= 0) + return (-1); /* Timeout! */ + + /* + * Write bytes to the pipe... + */ + +#ifdef WIN32 + count = (ssize_t)_write(3, buffer, (unsigned)(bytes - total)); +#else + count = write(3, buffer, bytes - total); +#endif /* WIN32 */ + + if (count < 0) + { + /* + * Write error - abort on fatal errors... + */ + + if (errno != EINTR && errno != EAGAIN) + return (-1); + } + else + { + /* + * Write succeeded, update buffer pointer and total count... + */ + + buffer += count; + total += count; + } + } + + return ((ssize_t)bytes); +} + + +/* + * 'cups_setup()' - Setup select() + */ + +static void +cups_setup(fd_set *set, /* I - Set for select() */ + struct timeval *tval, /* I - Timer value */ + double timeout) /* I - Timeout in seconds */ +{ + tval->tv_sec = (int)timeout; + tval->tv_usec = (int)(1000000.0 * (timeout - tval->tv_sec)); + + FD_ZERO(set); + FD_SET(3, set); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/backend.c b/cups/backend.c new file mode 100644 index 0000000000..acea7dc3bd --- /dev/null +++ b/cups/backend.c @@ -0,0 +1,134 @@ +/* + * "$Id$" + * + * Backend functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsBackendDeviceURI() - Get the device URI for a backend. + * cupsBackendReport() - Write a device line from a backend. + * quote_string() - Write a quoted string to stdout, escaping \ and ". + */ + +/* + * Include necessary headers... + */ + +#include +#include "backend.h" +#include "globals.h" + + +/* + * Local functions... + */ + +static void quote_string(const char *s); + + +/* + * 'cupsBackendDeviceURI()' - Get the device URI for a backend. + * + * The "argv" argument is the argv argument passed to main(). This + * function returns the device URI passed in the DEVICE_URI environment + * variable or the device URI passed in argv[0], whichever is found + * first. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +const char * /* O - Device URI or @code NULL@ */ +cupsBackendDeviceURI(char **argv) /* I - Command-line arguments */ +{ + const char *device_uri; /* Device URI */ + _cups_globals_t *cg = _cupsGlobals(); /* Global info */ + + + if ((device_uri = getenv("DEVICE_URI")) == NULL) + { + if (!argv || !argv[0] || !strchr(argv[0], ':')) + return (NULL); + + device_uri = argv[0]; + } + + return (_httpResolveURI(device_uri, cg->resolved_uri, + sizeof(cg->resolved_uri), 1)); +} + + +/* + * 'cupsBackendReport()' - Write a device line from a backend. + * + * This function writes a single device line to stdout for a backend. + * It handles quoting of special characters in the device-make-and-model, + * device-info, device-id, and device-location strings. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +void +cupsBackendReport( + const char *device_scheme, /* I - device-scheme string */ + const char *device_uri, /* I - device-uri string */ + const char *device_make_and_model, /* I - device-make-and-model string or @code NULL@ */ + const char *device_info, /* I - device-info string or @code NULL@ */ + const char *device_id, /* I - device-id string or @code NULL@ */ + const char *device_location) /* I - device-location string or @code NULL@ */ +{ + if (!device_scheme || !device_uri) + return; + + printf("%s %s", device_scheme, device_uri); + if (device_make_and_model && *device_make_and_model) + quote_string(device_make_and_model); + else + quote_string("unknown"); + quote_string(device_info); + quote_string(device_id); + quote_string(device_location); + putchar('\n'); + fflush(stdout); +} + + +/* + * 'quote_string()' - Write a quoted string to stdout, escaping \ and ". + */ + +static void +quote_string(const char *s) /* I - String to write */ +{ + fputs(" \"", stdout); + + if (s) + { + while (*s) + { + if (*s == '\\' || *s == '\"') + putchar('\\'); + + putchar(*s); + + s ++; + } + } + + putchar('\"'); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/backend.h b/cups/backend.h new file mode 100644 index 0000000000..1bd5bb76b6 --- /dev/null +++ b/cups/backend.h @@ -0,0 +1,76 @@ +/* + * "$Id$" + * + * Backend definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_BACKEND_H_ +# define _CUPS_BACKEND_H_ + + +/* + * Include necessary headers... + */ + +# include "versioning.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Constants... + */ + +enum cups_backend_e /**** Backend exit codes ****/ +{ + CUPS_BACKEND_OK = 0, /* Job completed successfully */ + CUPS_BACKEND_FAILED = 1, /* Job failed, use error-policy */ + CUPS_BACKEND_AUTH_REQUIRED = 2, /* Job failed, authentication required */ + CUPS_BACKEND_HOLD = 3, /* Job failed, hold job */ + CUPS_BACKEND_STOP = 4, /* Job failed, stop queue */ + CUPS_BACKEND_CANCEL = 5 /* Job failed, cancel job */ +}; +typedef enum cups_backend_e cups_backend_t; + /**** Backend exit codes ****/ + + +/* + * Prototypes... + */ + +extern const char *cupsBackendDeviceURI(char **argv) _CUPS_API_1_2; +extern void cupsBackendReport(const char *device_scheme, + const char *device_uri, + const char *device_make_and_model, + const char *device_info, + const char *device_id, + const char *device_location) + _CUPS_API_1_4; + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_BACKEND_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/conflicts.c b/cups/conflicts.c new file mode 100644 index 0000000000..6870a1ed25 --- /dev/null +++ b/cups/conflicts.c @@ -0,0 +1,1147 @@ +/* + * "$Id$" + * + * Option marking routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsGetConflicts() - Get a list of conflicting options in a marked + * PPD. + * cupsResolveConflicts() - Resolve conflicts in a marked PPD. + * ppdConflicts() - Check to see if there are any conflicts among + * the marked option choices. + * ppdInstallableConflict() - Test whether an option choice conflicts with an + * installable option. + * ppd_is_installable() - Determine whether an option is in the + * InstallableOptions group. + * ppd_load_constraints() - Load constraints from a PPD file. + * ppd_test_constraints() - See if any constraints are active. + */ + +/* + * Include necessary headers... + */ + +#include "ppd-private.h" +#include "string.h" +#include "debug.h" + + +/* + * Local constants... + */ + +enum +{ + _PPD_NORMAL_CONSTRAINTS, + _PPD_OPTION_CONSTRAINTS, + _PPD_INSTALLABLE_CONSTRAINTS, + _PPD_ALL_CONSTRAINTS +}; + + +/* + * Local functions... + */ + +static int ppd_is_installable(ppd_group_t *installable, + const char *option); +static void ppd_load_constraints(ppd_file_t *ppd); +static cups_array_t *ppd_test_constraints(ppd_file_t *ppd, + const char *option, + const char *choice, + int num_options, + cups_option_t *options, + int which); + + +/* + * 'cupsGetConflicts()' - Get a list of conflicting options in a marked PPD. + * + * This function gets a list of options that would conflict if "option" and + * "choice" were marked in the PPD. You would typically call this function + * after marking the currently selected options in the PPD in order to + * determine whether a new option selection would cause a conflict. + * + * The number of conflicting options are returned with "options" pointing to + * the conflicting options. The returned option array must be freed using + * @link cupsFreeOptions@. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +int /* O - Number of conflicting options */ +cupsGetConflicts( + ppd_file_t *ppd, /* I - PPD file */ + const char *option, /* I - Option to test */ + const char *choice, /* I - Choice to test */ + cups_option_t **options) /* O - Conflicting options */ +{ + int i, /* Looping var */ + num_options; /* Number of conflicting options */ + cups_array_t *active; /* Active conflicts */ + _ppd_cups_uiconsts_t *c; /* Current constraints */ + _ppd_cups_uiconst_t *cptr; /* Current constraint */ + + + /* + * Range check input... + */ + + if (options) + *options = NULL; + + if (!ppd || !option || !choice || !options) + return (0); + + /* + * Test for conflicts... + */ + + active = ppd_test_constraints(ppd, option, choice, 0, NULL, + _PPD_ALL_CONSTRAINTS); + + /* + * Loop through all of the UI constraints and add any options that conflict... + */ + + for (num_options = 0, c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active); + c; + c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) + { + for (i = c->num_constraints, cptr = c->constraints; + i > 0; + i --, cptr ++) + if (strcasecmp(cptr->option->keyword, option)) + num_options = cupsAddOption(cptr->option->keyword, cptr->choice->choice, + num_options, options); + } + + cupsArrayDelete(active); + + return (num_options); +} + + +/* + * 'cupsResolveConflicts()' - Resolve conflicts in a marked PPD. + * + * This function attempts to resolve any conflicts in a marked PPD, returning + * a list of option changes that are required to resolve them. On input, + * "num_options" and "options" contain any pending option changes that have + * not yet been marked, while "option" and "choice" contain the most recent + * selection which may or may not be in "num_options" or "options". + * + * On successful return, "num_options" and "options" are updated to contain + * "option" and "choice" along with any changes required to resolve conflicts + * specified in the PPD file and 1 is returned. + * + * If option conflicts cannot be resolved, "num_options" and "options" are not + * changed and 0 is returned. + * + * When resolving conflicts, @code cupsResolveConflicts@ does not consider + * changes to the current page size (@code media@, @code PageSize@, and + * @code PageRegion@) or to the most recent option specified in "option". + * Thus, if the only way to resolve a conflict is to change the page size + * or the option the user most recently changed, @code cupsResolveConflicts@ + * will return 0 to indicate it was unable to resolve the conflicts. + * + * The @code cupsResolveConflicts@ function uses one of two sources of option + * constraint information. The preferred constraint information is defined by + * @code cupsUIConstraints@ and @code cupsUIResolver@ attributes - in this + * case, the PPD file provides constraint resolution actions. + * + * The backup constraint information is defined by the + * @code UIConstraints@ and @code NonUIConstraints@ attributes. These + * constraints are resolved algorithmically by first selecting the default + * choice for the conflicting option, then iterating over all possible choices + * until a non-conflicting option choice is found. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +int /* O - 1 on success, 0 on failure */ +cupsResolveConflicts( + ppd_file_t *ppd, /* I - PPD file */ + const char *option, /* I - Newly selected option or @code NULL@ for none */ + const char *choice, /* I - Newly selected choice or @code NULL@ for none */ + int *num_options, /* IO - Number of additional selected options */ + cups_option_t **options) /* IO - Additional selected options */ +{ + int i, /* Looping var */ + tries, /* Number of tries */ + num_newopts; /* Number of new options */ + cups_option_t *newopts; /* New options */ + cups_array_t *active, /* Active constraints */ + *pass, /* Resolvers for this pass */ + *resolvers, /* Resolvers we have used */ + *test; /* Test array for conflicts */ + _ppd_cups_uiconsts_t *consts; /* Current constraints */ + _ppd_cups_uiconst_t *constptr; /* Current constraint */ + ppd_attr_t *resolver; /* Current resolver */ + const char *resval; /* Pointer into resolver value */ + char resoption[PPD_MAX_NAME], + /* Current resolver option */ + reschoice[PPD_MAX_NAME], + /* Current resolver choice */ + *resptr; /* Pointer into option/choice */ + const char *value; /* Selected option value */ + int changed; /* Did we change anything? */ + ppd_choice_t *marked; /* Marked choice */ + + + /* + * Range check input... + */ + + if (!ppd || !num_options || !options || (option == NULL) != (choice == NULL)) + return (0); + + /* + * Build a shadow option array... + */ + + num_newopts = 0; + newopts = NULL; + + for (i = 0; i < *num_options; i ++) + num_newopts = cupsAddOption((*options)[i].name, (*options)[i].value, + num_newopts, &newopts); + if (option && strcasecmp(option, "Collate")) + num_newopts = cupsAddOption(option, choice, num_newopts, &newopts); + + /* + * Loop until we have no conflicts... + */ + + cupsArraySave(ppd->sorted_attrs); + + resolvers = NULL; + pass = cupsArrayNew((cups_array_func_t)strcasecmp, NULL); + tries = 0; + + while (tries < 100 && + (active = ppd_test_constraints(ppd, NULL, NULL, num_newopts, newopts, + _PPD_ALL_CONSTRAINTS)) != NULL) + { + tries ++; + + if (!resolvers) + resolvers = cupsArrayNew((cups_array_func_t)strcasecmp, NULL); + + for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active), changed = 0; + consts; + consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) + { + if (consts->resolver[0]) + { + /* + * Look up the resolver... + */ + + if (cupsArrayFind(pass, consts->resolver)) + continue; /* Already applied this resolver... */ + + if (cupsArrayFind(resolvers, consts->resolver)) + { + /* + * Resolver loop! + */ + + DEBUG_printf(("1ppdResolveConflicts: Resolver loop with %s!", + consts->resolver)); + goto error; + } + + if ((resolver = ppdFindAttr(ppd, "cupsUIResolver", + consts->resolver)) == NULL) + { + DEBUG_printf(("1ppdResolveConflicts: Resolver %s not found!", + consts->resolver)); + goto error; + } + + if (!resolver->value) + { + DEBUG_printf(("1ppdResolveConflicts: Resolver %s has no value!", + consts->resolver)); + goto error; + } + + /* + * Add the options from the resolver... + */ + + cupsArrayAdd(pass, consts->resolver); + cupsArrayAdd(resolvers, consts->resolver); + + for (resval = resolver->value; *resval && !changed;) + { + while (_cups_isspace(*resval)) + resval ++; + + if (*resval != '*') + break; + + for (resval ++, resptr = resoption; + *resval && !_cups_isspace(*resval); + resval ++) + if (resptr < (resoption + sizeof(resoption) - 1)) + *resptr++ = *resval; + + *resptr = '\0'; + + while (_cups_isspace(*resval)) + resval ++; + + for (resptr = reschoice; + *resval && !_cups_isspace(*resval); + resval ++) + if (resptr < (reschoice + sizeof(reschoice) - 1)) + *resptr++ = *resval; + + *resptr = '\0'; + + if (!resoption[0] || !reschoice[0]) + break; + + /* + * Is this the option we are changing? + */ + + if (option && + (!strcasecmp(resoption, option) || + (!strcasecmp(option, "PageSize") && + !strcasecmp(resoption, "PageRegion")) || + (!strcasecmp(option, "PageRegion") && + !strcasecmp(resoption, "PageSize")))) + continue; + + /* + * Try this choice... + */ + + if ((test = ppd_test_constraints(ppd, resoption, reschoice, + num_newopts, newopts, + _PPD_ALL_CONSTRAINTS)) == NULL) + { + /* + * That worked... + */ + + changed = 1; + } + else + cupsArrayDelete(test); + + /* + * Add the option/choice from the resolver regardless of whether it + * worked; this makes sure that we can cascade several changes to + * make things resolve... + */ + + num_newopts = cupsAddOption(resoption, reschoice, num_newopts, + &newopts); + } + } + else + { + /* + * Try resolving by choosing the default values for non-installable + * options, then by iterating through the possible choices... + */ + + int j; /* Looping var */ + ppd_choice_t *cptr; /* Current choice */ + ppd_size_t *size; /* Current page size */ + + + for (i = consts->num_constraints, constptr = consts->constraints; + i > 0 && !changed; + i --, constptr ++) + { + /* + * Can't resolve by changing an installable option... + */ + + if (constptr->installable) + continue; + + /* + * Is this the option we are changing? + */ + + if (option && + (!strcasecmp(constptr->option->keyword, option) || + (!strcasecmp(option, "PageSize") && + !strcasecmp(constptr->option->keyword, "PageRegion")) || + (!strcasecmp(option, "PageRegion") && + !strcasecmp(constptr->option->keyword, "PageSize")))) + continue; + + /* + * Get the current option choice... + */ + + if ((value = cupsGetOption(constptr->option->keyword, num_newopts, + newopts)) == NULL) + { + if (!strcasecmp(constptr->option->keyword, "PageSize") || + !strcasecmp(constptr->option->keyword, "PageRegion")) + { + if ((value = cupsGetOption("PageSize", num_newopts, + newopts)) == NULL) + value = cupsGetOption("PageRegion", num_newopts, newopts); + + if (!value) + { + if ((size = ppdPageSize(ppd, NULL)) != NULL) + value = size->name; + else + value = ""; + } + } + else + { + marked = ppdFindMarkedChoice(ppd, constptr->option->keyword); + value = marked ? marked->choice : ""; + } + } + + if (!strncasecmp(value, "Custom.", 7)) + value = "Custom"; + + /* + * Try the default choice... + */ + + test = NULL; + + if (strcasecmp(value, constptr->option->defchoice) && + (test = ppd_test_constraints(ppd, constptr->option->keyword, + constptr->option->defchoice, + num_newopts, newopts, + _PPD_OPTION_CONSTRAINTS)) == NULL) + { + /* + * That worked... + */ + + num_newopts = cupsAddOption(constptr->option->keyword, + constptr->option->defchoice, + num_newopts, &newopts); + changed = 1; + } + else + { + /* + * Try each choice instead... + */ + + for (j = constptr->option->num_choices, + cptr = constptr->option->choices; + j > 0; + j --, cptr ++) + { + cupsArrayDelete(test); + test = NULL; + + if (strcasecmp(value, cptr->choice) && + strcasecmp(constptr->option->defchoice, cptr->choice) && + strcasecmp("Custom", cptr->choice) && + (test = ppd_test_constraints(ppd, constptr->option->keyword, + cptr->choice, num_newopts, + newopts, + _PPD_OPTION_CONSTRAINTS)) == NULL) + { + /* + * This choice works... + */ + + num_newopts = cupsAddOption(constptr->option->keyword, + cptr->choice, num_newopts, + &newopts); + changed = 1; + break; + } + } + + cupsArrayDelete(test); + } + } + } + } + + if (!changed) + { + DEBUG_puts("1ppdResolveConflicts: Unable to automatically resolve " + "constraint!"); + goto error; + } + + cupsArrayClear(pass); + cupsArrayDelete(active); + active = NULL; + } + + if (tries >= 100) + goto error; + + /* + * Free the caller's option array... + */ + + cupsFreeOptions(*num_options, *options); + + /* + * If Collate is the option we are testing, add it here. Otherwise, remove + * any Collate option from the resolve list since the filters automatically + * handle manual collation... + */ + + if (option && !strcasecmp(option, "Collate")) + num_newopts = cupsAddOption(option, choice, num_newopts, &newopts); + else + num_newopts = cupsRemoveOption("Collate", num_newopts, &newopts); + + /* + * Return the new list of options to the caller... + */ + + *num_options = num_newopts; + *options = newopts; + + cupsArrayDelete(pass); + cupsArrayDelete(resolvers); + + cupsArrayRestore(ppd->sorted_attrs); + + DEBUG_printf(("1cupsResolveConflicts: Returning %d options:", num_newopts)); +#ifdef DEBUG + for (i = 0; i < num_newopts; i ++) + DEBUG_printf(("1cupsResolveConflicts: options[%d]: %s=%s", i, + newopts[i].name, newopts[i].value)); +#endif /* DEBUG */ + + return (1); + + /* + * If we get here, we failed to resolve... + */ + + error: + + cupsFreeOptions(num_newopts, newopts); + + cupsArrayDelete(active); + cupsArrayDelete(pass); + cupsArrayDelete(resolvers); + + cupsArrayRestore(ppd->sorted_attrs); + + DEBUG_puts("1cupsResolveConflicts: Unable to resolve conflicts!"); + + return (0); +} + + +/* + * 'ppdConflicts()' - Check to see if there are any conflicts among the + * marked option choices. + * + * The returned value is the same as returned by @link ppdMarkOption@. + */ + +int /* O - Number of conflicts found */ +ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ +{ + int i, /* Looping variable */ + conflicts; /* Number of conflicts */ + cups_array_t *active; /* Active conflicts */ + _ppd_cups_uiconsts_t *c; /* Current constraints */ + _ppd_cups_uiconst_t *cptr; /* Current constraint */ + ppd_option_t *o; /* Current option */ + + + if (!ppd) + return (0); + + /* + * Clear all conflicts... + */ + + cupsArraySave(ppd->options); + + for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd)) + o->conflicted = 0; + + cupsArrayRestore(ppd->options); + + /* + * Test for conflicts... + */ + + active = ppd_test_constraints(ppd, NULL, NULL, 0, NULL, + _PPD_ALL_CONSTRAINTS); + conflicts = cupsArrayCount(active); + + /* + * Loop through all of the UI constraints and flag any options + * that conflict... + */ + + for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active); + c; + c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) + { + for (i = c->num_constraints, cptr = c->constraints; + i > 0; + i --, cptr ++) + cptr->option->conflicted = 1; + } + + cupsArrayDelete(active); + + /* + * Return the number of conflicts found... + */ + + return (conflicts); +} + + +/* + * 'ppdInstallableConflict()' - Test whether an option choice conflicts with + * an installable option. + * + * This function tests whether a particular option choice is available based + * on constraints against options in the "InstallableOptions" group. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +int /* O - 1 if conflicting, 0 if not conflicting */ +ppdInstallableConflict( + ppd_file_t *ppd, /* I - PPD file */ + const char *option, /* I - Option */ + const char *choice) /* I - Choice */ +{ + cups_array_t *active; /* Active conflicts */ + + + DEBUG_printf(("2ppdInstallableConflict(ppd=%p, option=\"%s\", choice=\"%s\")", + ppd, option, choice)); + + /* + * Range check input... + */ + + if (!ppd || !option || !choice) + return (0); + + /* + * Test constraints using the new option... + */ + + active = ppd_test_constraints(ppd, option, choice, 0, NULL, + _PPD_INSTALLABLE_CONSTRAINTS); + + cupsArrayDelete(active); + + return (active != NULL); +} + + +/* + * 'ppd_is_installable()' - Determine whether an option is in the + * InstallableOptions group. + */ + +static int /* O - 1 if installable, 0 if normal */ +ppd_is_installable( + ppd_group_t *installable, /* I - InstallableOptions group */ + const char *name) /* I - Option name */ +{ + if (installable) + { + int i; /* Looping var */ + ppd_option_t *option; /* Current option */ + + + for (i = installable->num_options, option = installable->options; + i > 0; + i --, option ++) + if (!strcasecmp(option->keyword, name)) + return (1); + } + + return (0); +} + + +/* + * 'ppd_load_constraints()' - Load constraints from a PPD file. + */ + +static void +ppd_load_constraints(ppd_file_t *ppd) /* I - PPD file */ +{ + int i; /* Looping var */ + ppd_const_t *oldconst; /* Current UIConstraints data */ + ppd_attr_t *constattr; /* Current cupsUIConstraints attribute */ + _ppd_cups_uiconsts_t *consts; /* Current cupsUIConstraints data */ + _ppd_cups_uiconst_t *constptr; /* Current constraint */ + ppd_group_t *installable; /* Installable options group */ + const char *vptr; /* Pointer into constraint value */ + char option[PPD_MAX_NAME], /* Option name/MainKeyword */ + choice[PPD_MAX_NAME], /* Choice/OptionKeyword */ + *ptr; /* Pointer into option or choice */ + + + DEBUG_printf(("7ppd_load_constraints(ppd=%p)", ppd)); + + /* + * Create an array to hold the constraint data... + */ + + ppd->cups_uiconstraints = cupsArrayNew(NULL, NULL); + + /* + * Find the installable options group if it exists... + */ + + for (i = ppd->num_groups, installable = ppd->groups; + i > 0; + i --, installable ++) + if (!strcasecmp(installable->name, "InstallableOptions")) + break; + + if (i <= 0) + installable = NULL; + + /* + * Load old-style [Non]UIConstraints data... + */ + + for (i = ppd->num_consts, oldconst = ppd->consts; i > 0; i --, oldconst ++) + { + /* + * Weed out nearby duplicates, since the PPD spec requires that you + * define both "*Foo foo *Bar bar" and "*Bar bar *Foo foo"... + */ + + if (i > 1 && + !strcasecmp(oldconst[0].option1, oldconst[1].option2) && + !strcasecmp(oldconst[0].choice1, oldconst[1].choice2) && + !strcasecmp(oldconst[0].option2, oldconst[1].option1) && + !strcasecmp(oldconst[0].choice2, oldconst[1].choice1)) + continue; + + /* + * Allocate memory... + */ + + if ((consts = calloc(1, sizeof(_ppd_cups_uiconsts_t))) == NULL) + { + DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " + "UIConstraints!"); + return; + } + + if ((constptr = calloc(2, sizeof(_ppd_cups_uiconst_t))) == NULL) + { + free(consts); + DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " + "UIConstraints!"); + return; + } + + /* + * Fill in the information... + */ + + consts->num_constraints = 2; + consts->constraints = constptr; + + if (!strncasecmp(oldconst->option1, "Custom", 6) && + !strcasecmp(oldconst->choice1, "True")) + { + constptr[0].option = ppdFindOption(ppd, oldconst->option1 + 6); + constptr[0].choice = ppdFindChoice(constptr[0].option, "Custom"); + constptr[0].installable = 0; + } + else + { + constptr[0].option = ppdFindOption(ppd, oldconst->option1); + constptr[0].choice = ppdFindChoice(constptr[0].option, + oldconst->choice1); + constptr[0].installable = ppd_is_installable(installable, + oldconst->option1); + } + + if (!constptr[0].option || (!constptr[0].choice && oldconst->choice1[0])) + { + DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!", + oldconst->option1, oldconst->choice1)); + free(consts->constraints); + free(consts); + continue; + } + + if (!strncasecmp(oldconst->option2, "Custom", 6) && + !strcasecmp(oldconst->choice2, "True")) + { + constptr[1].option = ppdFindOption(ppd, oldconst->option2 + 6); + constptr[1].choice = ppdFindChoice(constptr[1].option, "Custom"); + constptr[1].installable = 0; + } + else + { + constptr[1].option = ppdFindOption(ppd, oldconst->option2); + constptr[1].choice = ppdFindChoice(constptr[1].option, + oldconst->choice2); + constptr[1].installable = ppd_is_installable(installable, + oldconst->option2); + } + + if (!constptr[1].option || (!constptr[1].choice && oldconst->choice2[0])) + { + DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!", + oldconst->option2, oldconst->choice2)); + free(consts->constraints); + free(consts); + continue; + } + + consts->installable = constptr[0].installable || constptr[1].installable; + + /* + * Add it to the constraints array... + */ + + cupsArrayAdd(ppd->cups_uiconstraints, consts); + } + + /* + * Then load new-style constraints... + */ + + for (constattr = ppdFindAttr(ppd, "cupsUIConstraints", NULL); + constattr; + constattr = ppdFindNextAttr(ppd, "cupsUIConstraints", NULL)) + { + if (!constattr->value) + { + DEBUG_puts("8ppd_load_constraints: Bad cupsUIConstraints value!"); + continue; + } + + for (i = 0, vptr = strchr(constattr->value, '*'); + vptr; + i ++, vptr = strchr(vptr + 1, '*')); + + if (i == 0) + { + DEBUG_puts("8ppd_load_constraints: Bad cupsUIConstraints value!"); + continue; + } + + if ((consts = calloc(1, sizeof(_ppd_cups_uiconsts_t))) == NULL) + { + DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " + "cupsUIConstraints!"); + return; + } + + if ((constptr = calloc(i, sizeof(_ppd_cups_uiconst_t))) == NULL) + { + free(consts); + DEBUG_puts("8ppd_load_constraints: Unable to allocate memory for " + "cupsUIConstraints!"); + return; + } + + consts->num_constraints = i; + consts->constraints = constptr; + + strlcpy(consts->resolver, constattr->spec, sizeof(consts->resolver)); + + for (i = 0, vptr = strchr(constattr->value, '*'); + vptr; + i ++, vptr = strchr(vptr, '*'), constptr ++) + { + /* + * Extract "*Option Choice" or just "*Option"... + */ + + for (vptr ++, ptr = option; *vptr && !_cups_isspace(*vptr); vptr ++) + if (ptr < (option + sizeof(option) - 1)) + *ptr++ = *vptr; + + *ptr = '\0'; + + while (_cups_isspace(*vptr)) + vptr ++; + + if (*vptr == '*') + choice[0] = '\0'; + else + { + for (ptr = choice; *vptr && !_cups_isspace(*vptr); vptr ++) + if (ptr < (choice + sizeof(choice) - 1)) + *ptr++ = *vptr; + + *ptr = '\0'; + } + + if (!strncasecmp(option, "Custom", 6) && !strcasecmp(choice, "True")) + { + _cups_strcpy(option, option + 6); + strcpy(choice, "Custom"); + } + + constptr->option = ppdFindOption(ppd, option); + constptr->choice = ppdFindChoice(constptr->option, choice); + constptr->installable = ppd_is_installable(installable, option); + consts->installable |= constptr->installable; + + if (!constptr->option || (!constptr->choice && choice[0])) + { + DEBUG_printf(("8ppd_load_constraints: Unknown option *%s %s!", + option, choice)); + break; + } + } + + if (!vptr) + cupsArrayAdd(ppd->cups_uiconstraints, consts); + else + { + free(consts->constraints); + free(consts); + } + } +} + + +/* + * 'ppd_test_constraints()' - See if any constraints are active. + */ + +static cups_array_t * /* O - Array of active constraints */ +ppd_test_constraints( + ppd_file_t *ppd, /* I - PPD file */ + const char *option, /* I - Current option */ + const char *choice, /* I - Current choice */ + int num_options, /* I - Number of additional options */ + cups_option_t *options, /* I - Additional options */ + int which) /* I - Which constraints to test */ +{ + int i; /* Looping var */ + _ppd_cups_uiconsts_t *consts; /* Current constraints */ + _ppd_cups_uiconst_t *constptr; /* Current constraint */ + ppd_choice_t key, /* Search key */ + *marked; /* Marked choice */ + cups_array_t *active = NULL; /* Active constraints */ + const char *value; /* Current value */ + + + DEBUG_printf(("7ppd_test_constraints(ppd=%p, option=\"%s\", choice=\"%s\", " + "num_options=%d, options=%p, which=%d)", ppd, option, choice, + num_options, options, which)); + + if (!ppd->cups_uiconstraints) + ppd_load_constraints(ppd); + + DEBUG_printf(("9ppd_test_constraints: %d constraints!", + cupsArrayCount(ppd->cups_uiconstraints))); + + cupsArraySave(ppd->marked); + + for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(ppd->cups_uiconstraints); + consts; + consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(ppd->cups_uiconstraints)) + { + DEBUG_printf(("9ppd_test_constraints: installable=%d, resolver=\"%s\", " + "num_constraints=%d option1=\"%s\", choice1=\"%s\", " + "option2=\"%s\", choice2=\"%s\", ...", + consts->installable, consts->resolver, consts->num_constraints, + consts->constraints[0].option->keyword, + consts->constraints[0].choice ? + consts->constraints[0].choice->choice : "", + consts->constraints[1].option->keyword, + consts->constraints[1].choice ? + consts->constraints[1].choice->choice : "")); + + if (consts->installable && which < _PPD_INSTALLABLE_CONSTRAINTS) + continue; /* Skip installable option constraint */ + + if (!consts->installable && which == _PPD_INSTALLABLE_CONSTRAINTS) + continue; /* Skip non-installable option constraint */ + + if (which == _PPD_OPTION_CONSTRAINTS && option) + { + /* + * Skip constraints that do not involve the current option... + */ + + for (i = consts->num_constraints, constptr = consts->constraints; + i > 0; + i --, constptr ++) + if (!strcasecmp(constptr->option->keyword, option)) + break; + + if (!i) + continue; + } + + DEBUG_puts("9ppd_test_constraints: Testing..."); + + for (i = consts->num_constraints, constptr = consts->constraints; + i > 0; + i --, constptr ++) + { + DEBUG_printf(("9ppd_test_constraints: %s=%s?", constptr->option->keyword, + constptr->choice ? constptr->choice->choice : "")); + + if (constptr->choice && + (!strcasecmp(constptr->option->keyword, "PageSize") || + !strcasecmp(constptr->option->keyword, "PageRegion"))) + { + /* + * PageSize and PageRegion are used depending on the selected input slot + * and manual feed mode. Validate against the selected page size instead + * of an individual option... + */ + + if (option && choice && + (!strcasecmp(option, "PageSize") || + !strcasecmp(option, "PageRegion"))) + { + value = choice; + } + else if ((value = cupsGetOption("PageSize", num_options, + options)) == NULL) + if ((value = cupsGetOption("PageRegion", num_options, + options)) == NULL) + if ((value = cupsGetOption("media", num_options, options)) == NULL) + { + ppd_size_t *size = ppdPageSize(ppd, NULL); + + if (size) + value = size->name; + } + + if (value && !strncasecmp(value, "Custom.", 7)) + value = "Custom"; + + if (!value || strcasecmp(value, constptr->choice->choice)) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + else if (constptr->choice) + { + if (option && choice && !strcasecmp(option, constptr->option->keyword)) + { + if (!strncasecmp(choice, "Custom.", 7)) + value = "Custom"; + else + value = choice; + + if (strcasecmp(value, constptr->choice->choice)) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + else if ((value = cupsGetOption(constptr->option->keyword, num_options, + options)) != NULL) + { + if (!strncasecmp(value, "Custom.", 7)) + value = "Custom"; + + if (strcasecmp(value, constptr->choice->choice)) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + else if (!constptr->choice->marked) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + else if (option && choice && + !strcasecmp(option, constptr->option->keyword)) + { + if (!strcasecmp(choice, "None") || !strcasecmp(choice, "Off") || + !strcasecmp(choice, "False")) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + else if ((value = cupsGetOption(constptr->option->keyword, num_options, + options)) != NULL) + { + if (!strcasecmp(value, "None") || !strcasecmp(value, "Off") || + !strcasecmp(value, "False")) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + else + { + key.option = constptr->option; + + if ((marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) + == NULL || + (!strcasecmp(marked->choice, "None") || + !strcasecmp(marked->choice, "Off") || + !strcasecmp(marked->choice, "False"))) + { + DEBUG_puts("9ppd_test_constraints: NO"); + break; + } + } + } + + if (i <= 0) + { + if (!active) + active = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(active, consts); + DEBUG_puts("9ppd_test_constraints: Added..."); + } + } + + cupsArrayRestore(ppd->marked); + + DEBUG_printf(("8ppd_test_constraints: Found %d active constraints!", + cupsArrayCount(active))); + + return (active); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/cups.h b/cups/cups.h new file mode 100644 index 0000000000..a2ac8574ac --- /dev/null +++ b/cups/cups.h @@ -0,0 +1,340 @@ +/* + * "$Id$" + * + * API definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) +# define __CUPS_SSIZE_T_DEFINED +# include +/* Windows does not support the ssize_t type, so map it to off_t... */ +typedef off_t ssize_t; /* @private@ */ +# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */ + +# include "file.h" +# include "ipp.h" +# include "ppd.h" +# include "language.h" + + +/* + * With GCC 3.0 and higher, we can mark old APIs "deprecated" so you get + * a warning at compile-time. + */ + +# if defined(__GNUC__) && __GNUC__ > 2 +# define _CUPS_DEPRECATED __attribute__ ((__deprecated__)) +# else +# define _CUPS_DEPRECATED +# endif /* __GNUC__ && __GNUC__ > 2 */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Constants... + */ + +# define CUPS_VERSION 1.0407 +# define CUPS_VERSION_MAJOR 1 +# define CUPS_VERSION_MINOR 4 +# define CUPS_VERSION_PATCH 7 + +# define CUPS_BC_FD 3 /* Back-channel file descriptor for select/poll */ +# define CUPS_DATE_ANY (time_t)-1 +# define CUPS_EXCLUDE_NONE (const char *)0 +# define CUPS_FORMAT_AUTO "application/octet-stream" +# define CUPS_FORMAT_COMMAND "application/vnd.cups-command" +# define CUPS_FORMAT_PDF "application/pdf" +# define CUPS_FORMAT_POSTSCRIPT "application/postscript" +# define CUPS_FORMAT_RAW "application/vnd.cups-raw" +# define CUPS_FORMAT_TEXT "text/plain" +# define CUPS_HTTP_DEFAULT (http_t *)0 +# define CUPS_INCLUDE_ALL (const char *)0 +# define CUPS_JOBID_ALL -1 +# define CUPS_JOBID_CURRENT 0 +# define CUPS_LENGTH_VARIABLE (ssize_t)0 +# define CUPS_TIMEOUT_DEFAULT 0 +# define CUPS_WHICHJOBS_ALL -1 +# define CUPS_WHICHJOBS_ACTIVE 0 +# define CUPS_WHICHJOBS_COMPLETED 1 + + +/* + * Types and structures... + */ + +typedef unsigned cups_ptype_t; /**** Printer type/capability bits ****/ +enum cups_ptype_e /**** Printer type/capability bit constants ****/ +{ /* 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_FAX = 0x40000, /* Fax queue */ + CUPS_PRINTER_REJECTING = 0x80000, /* Printer is rejecting jobs */ + CUPS_PRINTER_DELETE = 0x100000, /* Delete printer @since CUPS 1.2/Mac OS X 10.5@ */ + CUPS_PRINTER_NOT_SHARED = 0x200000, /* Printer is not shared @since CUPS 1.2/Mac OS X 10.5@ */ + CUPS_PRINTER_AUTHENTICATED = 0x400000,/* Printer requires authentication @since CUPS 1.2/Mac OS X 10.5@ */ + CUPS_PRINTER_COMMANDS = 0x800000, /* Printer supports maintenance commands @since CUPS 1.2/Mac OS X 10.5@ */ + CUPS_PRINTER_DISCOVERED = 0x1000000, /* Printer was automatically discovered and added @since CUPS 1.3/Mac OS X 10.5@ */ + CUPS_PRINTER_SCANNER = 0x2000000, /* Scanner-only device @since CUPS 1.4/Mac OS X 10.6@ */ + CUPS_PRINTER_MFP = 0x4000000, /* Printer with scanning capabilities @since CUPS 1.4/Mac OS X 10.6@ */ + CUPS_PRINTER_OPTIONS = 0x6fffc /* ~(CLASS | REMOTE | IMPLICIT | DEFAULT | FAX | REJECTING | DELETE | NOT_SHARED | AUTHENTICATED | COMMANDS | DISCOVERED) @private@ */ +}; + +typedef const char *(*cups_password_cb_t)(const char *prompt); + /**** Password callback ****/ + +typedef const char *(*cups_password_cb2_t)(const char *prompt, http_t *http, + const char *method, + const char *resource, + void *user_data); + /**** New password callback @since CUPS 1.4/Mac OS X 10.6@ ****/ + +typedef void (*cups_device_cb_t)(const char *device_class, + const char *device_id, const char *device_info, + const char *device_make_and_model, + const char *device_uri, + const char *device_location, void *user_data); + /**** Device callback @since CUPS 1.4/Mac OS X 10.6@ ****/ + +typedef struct cups_option_s /**** Printer Options ****/ +{ + char *name; /* Name of option */ + char *value; /* Value of option */ +} cups_option_t; + +typedef struct cups_dest_s /**** 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 cups_job_s /**** Job ****/ +{ + int id; /* The job ID */ + char *dest; /* Printer or class name */ + char *title; /* Title/job name */ + char *user; /* User the submitted the job */ + char *format; /* Document format */ + ipp_jstate_t state; /* Job state */ + int size; /* Size in kilobytes */ + int priority; /* Priority (1-100) */ + time_t completed_time; /* Time the job was completed */ + time_t creation_time; /* Time the job was created */ + time_t processing_time; /* Time the job was processed */ +} cups_job_t; + + +/* + * Functions... + */ + +extern int cupsCancelJob(const char *name, int job_id); +extern ipp_t *cupsDoFileRequest(http_t *http, ipp_t *request, + const char *resource, + const char *filename); +extern ipp_t *cupsDoRequest(http_t *http, ipp_t *request, + const char *resource); +extern http_encryption_t cupsEncryption(void); +extern void cupsFreeJobs(int num_jobs, cups_job_t *jobs); +extern int cupsGetClasses(char ***classes) _CUPS_DEPRECATED; +extern const char *cupsGetDefault(void); +extern int cupsGetJobs(cups_job_t **jobs, const char *name, + int myjobs, int whichjobs); +extern const char *cupsGetPPD(const char *name); +extern int cupsGetPrinters(char ***printers) _CUPS_DEPRECATED; +extern ipp_status_t cupsLastError(void); +extern int cupsPrintFile(const char *name, const char *filename, + const char *title, int num_options, + cups_option_t *options); +extern int cupsPrintFiles(const char *name, int num_files, + const char **files, const char *title, + int num_options, cups_option_t *options); +extern char *cupsTempFile(char *filename, int len) _CUPS_DEPRECATED; +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 cupsMarkOptions(ppd_file_t *ppd, int num_options, + cups_option_t *options); +extern int cupsParseOptions(const char *arg, 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(cups_password_cb_t cb); +extern void cupsSetServer(const char *server); +extern void cupsSetUser(const char *user); +extern const char *cupsUser(void); + +/**** New in CUPS 1.1.20 ****/ +extern int cupsDoAuthentication(http_t *http, const char *method, + const char *resource) _CUPS_API_1_1_20; +extern http_status_t cupsGetFile(http_t *http, const char *resource, + const char *filename) _CUPS_API_1_1_20; +extern http_status_t cupsGetFd(http_t *http, const char *resource, int fd); +extern http_status_t cupsPutFile(http_t *http, const char *resource, + const char *filename) _CUPS_API_1_1_20; +extern http_status_t cupsPutFd(http_t *http, const char *resource, int fd) _CUPS_API_1_1_20; + +/**** New in CUPS 1.1.21 ****/ +extern const char *cupsGetDefault2(http_t *http) _CUPS_API_1_1_21; +extern int cupsGetDests2(http_t *http, cups_dest_t **dests) _CUPS_API_1_1_21; +extern int cupsGetJobs2(http_t *http, cups_job_t **jobs, + const char *name, int myjobs, + int whichjobs) _CUPS_API_1_1_21; +extern const char *cupsGetPPD2(http_t *http, const char *name) _CUPS_API_1_1_21; +extern int cupsPrintFile2(http_t *http, const char *name, + const char *filename, + const char *title, int num_options, + cups_option_t *options) _CUPS_API_1_1_21; +extern int cupsPrintFiles2(http_t *http, const char *name, + int num_files, const char **files, + const char *title, int num_options, + cups_option_t *options) _CUPS_API_1_1_21; +extern int cupsSetDests2(http_t *http, int num_dests, + cups_dest_t *dests) _CUPS_API_1_1_21; + +/**** New in CUPS 1.2/Mac OS X 10.5 ****/ +extern ssize_t cupsBackChannelRead(char *buffer, size_t bytes, + double timeout) _CUPS_API_1_2; +extern ssize_t cupsBackChannelWrite(const char *buffer, size_t bytes, + double timeout) _CUPS_API_1_2; +extern void cupsEncodeOptions2(ipp_t *ipp, int num_options, + cups_option_t *options, + ipp_tag_t group_tag) _CUPS_API_1_2; +extern const char *cupsLastErrorString(void) _CUPS_API_1_2; +extern char *cupsNotifySubject(cups_lang_t *lang, ipp_t *event) _CUPS_API_1_2; +extern char *cupsNotifyText(cups_lang_t *lang, ipp_t *event) _CUPS_API_1_2; +extern int cupsRemoveOption(const char *name, int num_options, + cups_option_t **options) _CUPS_API_1_2; +extern cups_file_t *cupsTempFile2(char *filename, int len) _CUPS_API_1_2; + +/**** New in CUPS 1.3/Mac OS X 10.5 ****/ +extern ipp_t *cupsDoIORequest(http_t *http, ipp_t *request, + const char *resource, int infile, + int outfile) _CUPS_API_1_3; +extern char *cupsGetServerPPD(http_t *http, const char *name) _CUPS_API_1_3; +extern int cupsRemoveDest(const char *name, + const char *instance, + int num_dests, cups_dest_t **dests) _CUPS_API_1_3; +extern void cupsSetDefaultDest(const char *name, + const char *instance, + int num_dests, + cups_dest_t *dests) _CUPS_API_1_3; + +/**** New in CUPS 1.4/Mac OS X 10.6 ****/ +extern ipp_status_t cupsCancelJob2(http_t *http, const char *name, + int job_id, int purge) _CUPS_API_1_4; +extern int cupsCreateJob(http_t *http, const char *name, + const char *title, int num_options, + cups_option_t *options) _CUPS_API_1_4; +extern ipp_status_t cupsFinishDocument(http_t *http, + const char *name) _CUPS_API_1_4; +extern int cupsGetConflicts(ppd_file_t *ppd, const char *option, + const char *choice, + cups_option_t **options) + _CUPS_API_1_4; +extern ipp_status_t cupsGetDevices(http_t *http, int timeout, + const char *include_schemes, + const char *exclude_schemes, + cups_device_cb_t callback, + void *user_data) _CUPS_API_1_4; +extern cups_dest_t *cupsGetNamedDest(http_t *http, const char *name, + const char *instance) _CUPS_API_1_4; +extern const char *cupsGetPassword2(const char *prompt, http_t *http, + const char *method, + const char *resource) _CUPS_API_1_4; +extern http_status_t cupsGetPPD3(http_t *http, const char *name, + time_t *modtime, char *buffer, + size_t bufsize) _CUPS_API_1_4; +extern ipp_t *cupsGetResponse(http_t *http, + const char *resource) _CUPS_API_1_4; +extern ssize_t cupsReadResponseData(http_t *http, char *buffer, + size_t length) _CUPS_API_1_4; +extern int cupsResolveConflicts(ppd_file_t *ppd, const char *option, + const char *choice, + int *num_options, + cups_option_t **options) + _CUPS_API_1_4; +extern http_status_t cupsSendRequest(http_t *http, ipp_t *request, + const char *resource, + size_t length) _CUPS_API_1_4; +extern void cupsSetPasswordCB2(cups_password_cb2_t cb, + void *user_data) _CUPS_API_1_4; +extern http_status_t cupsStartDocument(http_t *http, const char *name, + int job_id, const char *docname, + const char *format, + int last_document) _CUPS_API_1_4; +extern http_status_t cupsWriteRequestData(http_t *http, const char *buffer, + size_t length) _CUPS_API_1_4; + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_CUPS_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/custom.c b/cups/custom.c new file mode 100644 index 0000000000..5f578ac63d --- /dev/null +++ b/cups/custom.c @@ -0,0 +1,123 @@ +/* + * "$Id$" + * + * PPD custom option routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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: + * + * ppdFindCustomOption() - Find a custom option. + * ppdFindCustomParam() - Find a parameter for a custom option. + * ppdFirstCustomParam() - Return the first parameter for a custom option. + * ppdNextCustomParam() - Return the next parameter for a custom option. + */ + +/* + * Include necessary headers. + */ + +#include "globals.h" +#include "debug.h" + + +/* + * 'ppdFindCustomOption()' - Find a custom option. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_coption_t * /* O - Custom option or NULL */ +ppdFindCustomOption(ppd_file_t *ppd, /* I - PPD file */ + const char *keyword)/* I - Custom option name */ +{ + ppd_coption_t key; /* Custom option search key */ + + + if (!ppd) + return (NULL); + + strlcpy(key.keyword, keyword, sizeof(key.keyword)); + return ((ppd_coption_t *)cupsArrayFind(ppd->coptions, &key)); +} + + +/* + * 'ppdFindCustomParam()' - Find a parameter for a custom option. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_cparam_t * /* O - Custom parameter or NULL */ +ppdFindCustomParam(ppd_coption_t *opt, /* I - Custom option */ + const char *name) /* I - Parameter name */ +{ + ppd_cparam_t *param; /* Current custom parameter */ + + + if (!opt) + return (NULL); + + for (param = (ppd_cparam_t *)cupsArrayFirst(opt->params); + param; + param = (ppd_cparam_t *)cupsArrayNext(opt->params)) + if (!strcasecmp(param->name, name)) + break; + + return (param); +} + + +/* + * 'ppdFirstCustomParam()' - Return the first parameter for a custom option. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_cparam_t * /* O - Custom parameter or NULL */ +ppdFirstCustomParam(ppd_coption_t *opt) /* I - Custom option */ +{ + if (!opt) + return (NULL); + + return ((ppd_cparam_t *)cupsArrayFirst(opt->params)); +} + + +/* + * 'ppdNextCustomParam()' - Return the next parameter for a custom option. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_cparam_t * /* O - Custom parameter or NULL */ +ppdNextCustomParam(ppd_coption_t *opt) /* I - Custom option */ +{ + if (!opt) + return (NULL); + + return ((ppd_cparam_t *)cupsArrayNext(opt->params)); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/debug.c b/cups/debug.c new file mode 100644 index 0000000000..f3d2f1c5b5 --- /dev/null +++ b/cups/debug.c @@ -0,0 +1,553 @@ +/* + * "$Id$" + * + * Debugging functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2008-2009 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * debug_vsnprintf() - Format a string into a fixed size buffer. + * _cups_debug_printf() - Write a formatted line to the log. + * _cups_debug_puts() - Write a single line to the log. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#ifdef WIN32 +# include +#else +# include +# include +#endif /* WIN32 */ +#include +#ifndef WIN32 +# include +#endif /* WIN32 */ + + +/* + * Globals... + */ + +int _cups_debug_fd = -1; + /* Debug log file descriptor */ +int _cups_debug_level = 1; + /* Log level (0 to 9) */ + + +#ifdef DEBUG +/* + * Local globals... + */ + +# ifndef WIN32 +static regex_t *debug_filter = NULL; + /* Filter expression for messages */ +# endif /* !WIN32 */ +static int debug_init = 0; /* Did we initialize debugging? */ +# ifdef HAVE_PTHREAD_H +static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER; + /* Mutex to control initialization */ +# endif /* HAVE_PTHREAD_H */ + + +/* + * 'debug_vsnprintf()' - Format a string into a fixed size buffer. + */ + +int /* O - Number of bytes formatted */ +debug_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 */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + *tptr, /* Pointer into temporary format */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int bytes; /* Total number of bytes needed */ + + + if (!buffer || bufsize < 2 || !format) + return (-1); + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + bytes = 0; + + while (*format) + { + if (*format == '%') + { + tptr = tformat; + *tptr++ = *format++; + + if (*format == '%') + { + if (bufptr < bufend) + *bufptr++ = *format; + bytes ++; + format ++; + continue; + } + else if (strchr(" -+#\'", *format)) + *tptr++ = *format++; + + if (*format == '*') + { + /* + * Get width from argument... + */ + + format ++; + width = va_arg(ap, int); + + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); + tptr += strlen(tptr); + } + else + { + width = 0; + + while (isdigit(*format & 255)) + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + width = width * 10 + *format++ - '0'; + } + } + + if (*format == '.') + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + format ++; + + if (*format == '*') + { + /* + * Get precision from argument... + */ + + format ++; + prec = va_arg(ap, int); + + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); + tptr += strlen(tptr); + } + else + { + prec = 0; + + while (isdigit(*format & 255)) + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + prec = prec * 10 + *format++ - '0'; + } + } + } + + if (*format == 'l' && format[1] == 'l') + { + size = 'L'; + + if (tptr < (tformat + sizeof(tformat) - 2)) + { + *tptr++ = 'l'; + *tptr++ = 'l'; + } + + format += 2; + } + else if (*format == 'h' || *format == 'l' || *format == 'L') + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + size = *format++; + } + else + size = 0; + + if (!*format) + break; + + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + type = *format++; + *tptr = '\0'; + + switch (type) + { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, double)); + + bytes += (int)strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + 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 ((width + 2) > sizeof(temp)) + break; + +#ifdef HAVE_LONG_LONG + if (size == 'L') + sprintf(temp, tformat, va_arg(ap, long long)); + else +#endif /* HAVE_LONG_LONG */ + if (size == 'l') + sprintf(temp, tformat, va_arg(ap, long)); + else + sprintf(temp, tformat, va_arg(ap, int)); + + bytes += (int)strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'p' : /* Pointer value */ + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, void *)); + + bytes += (int)strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'c' : /* Character or character array */ + bytes += width; + + if (bufptr) + { + if (width <= 1) + *bufptr++ = va_arg(ap, int); + else + { + if ((bufptr + width) > bufend) + width = (int)(bufend - bufptr); + + memcpy(bufptr, va_arg(ap, char *), (size_t)width); + bufptr += width; + } + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) + s = "(null)"; + + /* + * Copy the C string, replacing control chars and \ with + * C character escapes... + */ + + for (bufend --; *s && bufptr < bufend; s ++) + { + if (*s == '\n') + { + *bufptr++ = '\\'; + *bufptr++ = 'n'; + } + else if (*s == '\r') + { + *bufptr++ = '\\'; + *bufptr++ = 'r'; + } + else if (*s == '\t') + { + *bufptr++ = '\\'; + *bufptr++ = 't'; + } + else if (*s == '\\') + { + *bufptr++ = '\\'; + *bufptr++ = '\\'; + } + else if (*s == '\'') + { + *bufptr++ = '\\'; + *bufptr++ = '\''; + } + else if (*s == '\"') + { + *bufptr++ = '\\'; + *bufptr++ = '\"'; + } + else if ((*s & 255) < ' ') + { + *bufptr++ = '\\'; + *bufptr++ = '0'; + *bufptr++ = '0' + *s / 8; + *bufptr++ = '0' + (*s & 7); + } + else + *bufptr++ = *s; + } + + bufend ++; + break; + + case 'n' : /* Output number of chars so far */ + *(va_arg(ap, int *)) = bytes; + break; + } + } + else + { + bytes ++; + + if (bufptr < bufend) + *bufptr++ = *format; + + format ++; + } + } + + /* + * Nul-terminate the string and return the number of characters needed. + */ + + *bufptr = '\0'; + + return (bytes); +} + + +/* + * '_cups_debug_printf()' - Write a formatted line to the log. + */ + +void +_cups_debug_printf(const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to arguments */ + struct timeval curtime; /* Current time */ + char buffer[2048]; /* Output buffer */ + size_t bytes; /* Number of bytes in buffer */ + int level; /* Log level in message */ + const char *cups_debug_filter, + /* CUPS_DEBUG_FILTER environment variable */ + *cups_debug_level, + /* CUPS_DEBUG_LEVEL environment variable */ + *cups_debug_log;/* CUPS_DEBUG_LOG environment variable */ + + + /* + * See if we need to do any logging... + */ + + if (!debug_init) + { + /* + * Get a lock on the debug initializer, then re-check in case another + * thread already did it... + */ + + pthread_mutex_lock(&debug_mutex); + + if (!debug_init) + { + if ((cups_debug_log = getenv("CUPS_DEBUG_LOG")) == NULL) + _cups_debug_fd = -1; + else if (!strcmp(cups_debug_log, "-")) + _cups_debug_fd = 2; + else + { + snprintf(buffer, sizeof(buffer), cups_debug_log, getpid()); + + if (buffer[0] == '+') + _cups_debug_fd = open(buffer + 1, O_WRONLY | O_APPEND | O_CREAT, 0644); + else + _cups_debug_fd = open(buffer, O_WRONLY | O_TRUNC | O_CREAT, 0644); + } + + if ((cups_debug_level = getenv("CUPS_DEBUG_LEVEL")) != NULL) + _cups_debug_level = atoi(cups_debug_level); + + if ((cups_debug_filter = getenv("CUPS_DEBUG_FILTER")) != NULL) + { + if ((debug_filter = (regex_t *)calloc(1, sizeof(regex_t))) == NULL) + fputs("Unable to allocate memory for CUPS_DEBUG_FILTER - results not " + "filtered!\n", stderr); + else if (regcomp(debug_filter, cups_debug_filter, REG_EXTENDED)) + { + fputs("Bad regular expression in CUPS_DEBUG_FILTER - results not " + "filtered!\n", stderr); + free(debug_filter); + debug_filter = NULL; + } + } + + debug_init = 1; + } + + pthread_mutex_unlock(&debug_mutex); + } + + if (_cups_debug_fd < 0) + return; + + /* + * Filter as needed... + */ + + if (isdigit(format[0])) + level = *format++ - '0'; + else + level = 0; + + if (level > _cups_debug_level) + return; + + if (debug_filter) + { + int result; /* Filter result */ + + pthread_mutex_lock(&debug_mutex); + result = regexec(debug_filter, format, 0, NULL, 0); + pthread_mutex_unlock(&debug_mutex); + + if (result) + return; + } + + /* + * Format the message... + */ + + gettimeofday(&curtime, NULL); + snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d ", + (int)((curtime.tv_sec / 3600) % 24), + (int)((curtime.tv_sec / 60) % 60), + (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000)); + + va_start(ap, format); + debug_vsnprintf(buffer + 13, sizeof(buffer) - 14, format, ap); + va_end(ap); + + bytes = strlen(buffer); + if (buffer[bytes - 1] != '\n') + { + buffer[bytes] = '\n'; + bytes ++; + buffer[bytes] = '\0'; + } + + /* + * Write it out... + */ + + write(_cups_debug_fd, buffer, bytes); +} + + +/* + * '_cups_debug_puts()' - Write a single line to the log. + */ + +void +_cups_debug_puts(const char *s) /* I - String to output */ +{ + char format[4]; /* C%s */ + + format[0] = *s++; + format[1] = '%'; + format[2] = 's'; + format[3] = '\0'; + + _cups_debug_printf(format, s); +} + + +#elif defined(__APPLE__) +/* Mac OS X needs these stubbed since we reference them in the libcups.exp file */ +void _cups_debug_printf(const char *format, ...) {} +void _cups_debug_puts(const char *s) {} +#endif /* DEBUG */ + + +/* + * End of "$Id$". + */ diff --git a/cups/debug.h b/cups/debug.h new file mode 100644 index 0000000000..1fce9fdbd0 --- /dev/null +++ b/cups/debug.h @@ -0,0 +1,89 @@ +/* + * "$Id$" + * + * Debugging macros for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_DEBUG_H_ +# define _CUPS_DEBUG_H_ + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * 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... + * + * Newlines are not required on the end of messages, as both add one when + * writing the output. + * + * If the first character is a digit, then it represents the "log level" of the + * message from 0 to 9. The default level is 1. The following defines the + * current levels we use: + * + * 0 = public APIs, other than value accessor functions + * 1 = return values for public APIs + * 2 = public value accessor APIs, progress for public APIs + * 3 = return values for value accessor APIs + * 4 = private APIs, progress for value accessor APIs + * 5 = return values for private APIs + * 6 = progress for private APIs + * 7 = static functions + * 8 = return values for static functions + * 9 = progress for static functions + */ + +# ifdef DEBUG +# define DEBUG_puts(x) _cups_debug_puts(x) +# define DEBUG_printf(x) _cups_debug_printf x +# else +# define DEBUG_puts(x) +# define DEBUG_printf(x) +# endif /* DEBUG */ + + +/* + * Prototypes... + */ + +extern int _cups_debug_fd; +extern int _cups_debug_level; +extern void _cups_debug_printf(const char *format, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 1, 2))) +#endif /* __GNUC__ */ +; +extern void _cups_debug_puts(const char *s); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_DEBUG_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/dest.c b/cups/dest.c new file mode 100644 index 0000000000..15f3814bcb --- /dev/null +++ b/cups/dest.c @@ -0,0 +1,2077 @@ +/* + * "$Id$" + * + * User-defined destination (and option) support for the Common UNIX + * Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 from the default + * server. + * cupsGetDests2() - Get the list of destinations from the specified + * server. + * cupsGetNamedDest() - Get options for the named destination. + * cupsRemoveDest() - Remove a destination from the destination list. + * cupsSetDefaultDest() - Set the default destination. + * cupsSetDests() - Save the list of destinations for the default + * server. + * cupsSetDests2() - Save the list of destinations for the specified + * server. + * appleCopyLocations() - Copy the location history array. + * appleCopyNetwork() - Get the network ID for the current location. + * appleGetPaperSize() - Get the default paper size. + * appleGetPrinter() - Get a printer from the history array. + * appleSetDefault() - Set the default printer for this location. + * appleUseLastPrinter() - Get the default printer preference value. + * cups_add_dest() - Add a destination to the array. + * cups_compare_dests() - Compare two destinations. + * cups_find_dest() - Find a destination using a binary search. + * cups_get_default() - Get the default destination from an lpoptions file. + * cups_get_dests() - Get destinations from a file. + * cups_get_sdests() - Get destinations from a server. + * cups_make_string() - Make a comma-separated string of values from an IPP + * attribute. + */ + +/* + * Include necessary headers... + */ + +#include "debug.h" +#include "globals.h" +#include "pwg-private.h" +#include +#include +#include + +#ifdef HAVE_NOTIFY_H +# include +#endif /* HAVE_NOTIFY_H */ + +#ifdef __APPLE__ +# include +# include +# include +# define kDefaultPaperIDKey CFSTR("DefaultPaperID") +# define kLocationHistoryArrayKey CFSTR("kLocationHistoryArrayKeyTMP") +# define kLocationNetworkKey CFSTR("kLocationNetworkKey") +# define kLocationPrinterIDKey CFSTR("kLocationPrinterIDKey") +# define kPMPrintingPreferences CFSTR("com.apple.print.PrintingPrefs") +# define kUseLastPrinterAsCurrentPrinterKey CFSTR("UseLastPrinterAsCurrentPrinter") +#endif /* __APPLE__ */ + + +/* + * Local functions... + */ + +#ifdef __APPLE__ +static CFArrayRef appleCopyLocations(void); +static CFStringRef appleCopyNetwork(void); +static char *appleGetPaperSize(char *name, int namesize); +static CFStringRef appleGetPrinter(CFArrayRef locations, CFStringRef network, + CFIndex *locindex); +static void appleSetDefault(const char *name); +static int appleUseLastPrinter(void); +#endif /* __APPLE__ */ +static cups_dest_t *cups_add_dest(const char *name, const char *instance, + int *num_dests, cups_dest_t **dests); +static int cups_compare_dests(cups_dest_t *a, cups_dest_t *b); +static int cups_find_dest(const char *name, const char *instance, + int num_dests, cups_dest_t *dests, int prev, + int *rdiff); +static char *cups_get_default(const char *filename, char *namebuf, + size_t namesize, const char **instance); +static int cups_get_dests(const char *filename, const char *match_name, + const char *match_inst, int user_default_set, + int num_dests, cups_dest_t **dests); +static int cups_get_sdests(http_t *http, ipp_op_t op, const char *name, + int num_dests, cups_dest_t **dests); +static char *cups_make_string(ipp_attribute_t *attr, char *buffer, + size_t bufsize); + + +/* + * 'cupsAddDest()' - Add a destination to the list of destinations. + * + * This function cannot be used to add a new class or printer queue, + * it only adds a new container of saved options for the named + * destination or instance. + * + * If the named destination already exists, the destination list is + * returned unchanged. Adding a new instance of a destination creates + * a copy of that destination's options. + * + * Use the @link cupsSaveDests@ function to save the updated list of + * destinations to the user's lpoptions file. + */ + +int /* O - New number of destinations */ +cupsAddDest(const char *name, /* I - Destination name */ + const char *instance, /* I - Instance name or @code NULL@ for none/primary */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int i; /* Looping var */ + cups_dest_t *dest; /* Destination pointer */ + cups_dest_t *parent = NULL; /* Parent destination */ + cups_option_t *doption, /* Current destination option */ + *poption; /* Current parent option */ + + + if (!name || !dests) + return (0); + + if (!cupsGetDest(name, instance, num_dests, *dests)) + { + if (instance && !cupsGetDest(name, NULL, num_dests, *dests)) + return (num_dests); + + dest = cups_add_dest(name, instance, &num_dests, dests); + + /* + * Find the base dest again now the array has been realloc'd. + */ + + parent = cupsGetDest(name, NULL, num_dests, *dests); + + if (instance && parent && parent->num_options > 0) + { + /* + * Copy options from parent... + */ + + dest->options = calloc(sizeof(cups_option_t), parent->num_options); + + if (dest->options) + { + dest->num_options = parent->num_options; + + for (i = dest->num_options, doption = dest->options, + poption = parent->options; + i > 0; + i --, doption ++, poption ++) + { + doption->name = _cupsStrRetain(poption->name); + doption->value = _cupsStrRetain(poption->value); + } + } + } + } + + return (num_dests); +} + + +/* + * '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 ++) + { + _cupsStrFree(dest->name); + _cupsStrFree(dest->instance); + + cupsFreeOptions(dest->num_options, dest->options); + } + + free(dests); +} + + +/* + * 'cupsGetDest()' - Get the named destination from the list. + * + * Use the @link cupsGetDests@ or @link cupsGetDests2@ functions to get a + * list of supported destinations for the current user. + */ + +cups_dest_t * /* O - Destination pointer or @code NULL@ */ +cupsGetDest(const char *name, /* I - Destination name or @code NULL@ for the default destination */ + const char *instance, /* I - Instance name or @code NULL@ */ + int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ +{ + int diff, /* Result of comparison */ + match; /* Matching index */ + + + if (num_dests <= 0 || !dests) + return (NULL); + + if (!name) + { + /* + * 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... + */ + + match = cups_find_dest(name, instance, num_dests, dests, -1, &diff); + + if (!diff) + return (dests + match); + } + + return (NULL); +} + + +/* + * 'cupsGetDests()' - Get the list of destinations from the default server. + * + * Starting with CUPS 1.2, the returned list of destinations include the + * printer-info, printer-is-accepting-jobs, printer-is-shared, + * printer-make-and-model, printer-state, printer-state-change-time, + * printer-state-reasons, and printer-type attributes as options. CUPS 1.4 + * adds the marker-change-time, marker-colors, marker-high-levels, + * marker-levels, marker-low-levels, marker-message, marker-names, + * marker-types, and printer-commands attributes as well. + * + * Use the @link cupsFreeDests@ function to free the destination list and + * the @link cupsGetDest@ function to find a particular destination. + */ + +int /* O - Number of destinations */ +cupsGetDests(cups_dest_t **dests) /* O - Destinations */ +{ + return (cupsGetDests2(CUPS_HTTP_DEFAULT, dests)); +} + + +/* + * 'cupsGetDests2()' - Get the list of destinations from the specified server. + * + * Starting with CUPS 1.2, the returned list of destinations include the + * printer-info, printer-is-accepting-jobs, printer-is-shared, + * printer-make-and-model, printer-state, printer-state-change-time, + * printer-state-reasons, and printer-type attributes as options. CUPS 1.4 + * adds the marker-change-time, marker-colors, marker-high-levels, + * marker-levels, marker-low-levels, marker-message, marker-names, + * marker-types, and printer-commands attributes as well. + * + * Use the @link cupsFreeDests@ function to free the destination list and + * the @link cupsGetDest@ function to find a particular destination. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +int /* O - Number of destinations */ +cupsGetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + 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 ~/.cups/lpoptions file */ + const char *defprinter; /* Default printer */ + char name[1024], /* Copy of printer name */ + *instance, /* Pointer to instance name */ + *user_default; /* User default printer */ + int num_reals; /* Number of real queues */ + cups_dest_t *reals; /* Real queues */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * Range check the input... + */ + + if (!dests) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad NULL dests pointer"), 1); + return (0); + } + + /* + * Initialize destination array... + */ + + num_dests = 0; + *dests = (cups_dest_t *)0; + + /* + * Grab the printers and classes... + */ + + num_dests = cups_get_sdests(http, CUPS_GET_PRINTERS, NULL, num_dests, dests); + + if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) + { + cupsFreeDests(num_dests, *dests); + *dests = (cups_dest_t *)0; + return (0); + } + + /* + * 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 ((user_default = _cupsUserDefault(name, sizeof(name))) != NULL) + defprinter = name; + else if ((defprinter = cupsGetDefault2(http)) != NULL) + { + strlcpy(name, defprinter, sizeof(name)); + defprinter = name; + } + + if (defprinter) + { + /* + * Separate printer and instance 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 + instance = NULL; + + /* + * Load the /etc/cups/lpoptions and ~/.cups/lpoptions files... + */ + + snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); + num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL, + num_dests, dests); + + if ((home = getenv("HOME")) != NULL) + { + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + if (access(filename, 0)) + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + + num_dests = cups_get_dests(filename, NULL, NULL, user_default != NULL, + num_dests, dests); + } + + /* + * Validate the current default destination - this prevents old + * Default lines in /etc/cups/lpoptions and ~/.cups/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... + */ + + if (num_dests > 0) + _cupsSetError(IPP_OK, NULL, 0); + + return (num_dests); +} + + +/* + * 'cupsGetNamedDest()' - Get options for the named destination. + * + * This function is optimized for retrieving a single destination and should + * be used instead of @link cupsGetDests@ and @link cupsGetDest@ when you either + * know the name of the destination or want to print to the default destination. + * If @code NULL@ is returned, the destination does not exist or there is no + * default destination. + * + * If "http" is @code CUPS_HTTP_DEFAULT@, the connection to the default print + * server will be used. + * + * If "name" is @code NULL@, the default printer for the current user will be + * returned. + * + * The returned destination must be freed using @link cupsFreeDests@ with a + * "num_dests" value of 1. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +cups_dest_t * /* O - Destination or @code NULL@ */ +cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name, /* I - Destination name or @code NULL@ for the default destination */ + const char *instance) /* I - Instance name or @code NULL@ */ +{ + cups_dest_t *dest; /* Destination */ + char filename[1024], /* Path to lpoptions */ + defname[256]; /* Default printer name */ + const char *home = getenv("HOME"); /* Home directory */ + int set_as_default = 0; /* Set returned destination as default */ + ipp_op_t op = IPP_GET_PRINTER_ATTRIBUTES; + /* IPP operation to get server ops */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * If "name" is NULL, find the default destination... + */ + + if (!name) + { + set_as_default = 1; + name = _cupsUserDefault(defname, sizeof(defname)); + + if (name) + { + char *ptr; /* Temporary pointer... */ + + if ((ptr = strchr(defname, '/')) != NULL) + { + *ptr++ = '\0'; + instance = ptr; + } + else + instance = NULL; + } + else if (home) + { + /* + * No default in the environment, try the user's lpoptions files... + */ + + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + + if ((name = cups_get_default(filename, defname, sizeof(defname), + &instance)) == NULL) + { + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + name = cups_get_default(filename, defname, sizeof(defname), + &instance); + } + } + + if (!name) + { + /* + * Still not there? Try the system lpoptions file... + */ + + snprintf(filename, sizeof(filename), "%s/lpoptions", + cg->cups_serverroot); + name = cups_get_default(filename, defname, sizeof(defname), &instance); + } + + if (!name) + { + /* + * No locally-set default destination, ask the server... + */ + + op = CUPS_GET_DEFAULT; + } + } + + /* + * Get the printer's attributes... + */ + + if (!cups_get_sdests(http, op, name, 0, &dest)) + { + if (op == CUPS_GET_DEFAULT || (name && !set_as_default)) + return (NULL); + + /* + * The default printer from environment variables or from a + * configuration file does not exist. Find out the real default. + */ + + if (!cups_get_sdests(http, CUPS_GET_DEFAULT, NULL, 0, &dest)) + return (NULL); + } + + if (instance) + dest->instance = _cupsStrAlloc(instance); + + if (set_as_default) + dest->is_default = 1; + + /* + * Then add local options... + */ + + snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); + cups_get_dests(filename, name, instance, 1, 1, &dest); + + if (home) + { + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + + if (access(filename, 0)) + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + + cups_get_dests(filename, name, instance, 1, 1, &dest); + } + + /* + * Return the result... + */ + + return (dest); +} + + +/* + * 'cupsRemoveDest()' - Remove a destination from the destination list. + * + * Removing a destination/instance does not delete the class or printer + * queue, merely the lpoptions for that destination/instance. Use the + * @link cupsSetDests@ or @link cupsSetDests2@ functions to save the new + * options for the user. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - New number of destinations */ +cupsRemoveDest(const char *name, /* I - Destination name */ + const char *instance, /* I - Instance name or @code NULL@ */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int i; /* Index into destinations */ + cups_dest_t *dest; /* Pointer to destination */ + + + /* + * Find the destination... + */ + + if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL) + return (num_dests); + + /* + * Free memory... + */ + + _cupsStrFree(dest->name); + _cupsStrFree(dest->instance); + cupsFreeOptions(dest->num_options, dest->options); + + /* + * Remove the destination from the array... + */ + + num_dests --; + + i = dest - *dests; + + if (i < num_dests) + memmove(dest, dest + 1, (num_dests - i) * sizeof(cups_dest_t)); + + return (num_dests); +} + + +/* + * 'cupsSetDefaultDest()' - Set the default destination. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +void +cupsSetDefaultDest( + const char *name, /* I - Destination name */ + const char *instance, /* I - Instance name or @code NULL@ */ + int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ +{ + int i; /* Looping var */ + cups_dest_t *dest; /* Current destination */ + + + /* + * Range check input... + */ + + if (!name || num_dests <= 0 || !dests) + return; + + /* + * Loop through the array and set the "is_default" flag for the matching + * destination... + */ + + for (i = num_dests, dest = dests; i > 0; i --, dest ++) + dest->is_default = !strcasecmp(name, dest->name) && + ((!instance && !dest->instance) || + (instance && dest->instance && + !strcasecmp(instance, dest->instance))); +} + + +/* + * 'cupsSetDests()' - Save the list of destinations for the default server. + * + * This function saves the destinations to /etc/cups/lpoptions when run + * as root and ~/.cups/lpoptions when run as a normal user. + */ + +void +cupsSetDests(int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ +{ + cupsSetDests2(CUPS_HTTP_DEFAULT, num_dests, dests); +} + + +/* + * 'cupsSetDests2()' - Save the list of destinations for the specified server. + * + * This function saves the destinations to /etc/cups/lpoptions when run + * as root and ~/.cups/lpoptions when run as a normal user. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +int /* O - 0 on success, -1 on error */ +cupsSetDests2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + 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 */ + _ipp_option_t *match; /* Matching attribute for option */ + FILE *fp; /* File pointer */ +#ifndef WIN32 + const char *home; /* HOME environment variable */ +#endif /* WIN32 */ + 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 */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * Range check the input... + */ + + if (!num_dests || !dests) + return (-1); + + /* + * Get the server destinations... + */ + + num_temps = cups_get_sdests(http, CUPS_GET_PRINTERS, NULL, 0, &temps); + + if (cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) + { + cupsFreeDests(num_temps, temps); + return (-1); + } + + /* + * Figure out which file to write to... + */ + + snprintf(filename, sizeof(filename), "%s/lpoptions", cg->cups_serverroot); + +#ifndef WIN32 + if (getuid()) + { + /* + * Merge in server defaults... + */ + + num_temps = cups_get_dests(filename, NULL, NULL, 0, num_temps, &temps); + + /* + * Point to user defaults... + */ + + if ((home = getenv("HOME")) != NULL) + { + /* + * Remove the old ~/.lpoptions file... + */ + + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + unlink(filename); + + /* + * Create ~/.cups subdirectory... + */ + + snprintf(filename, sizeof(filename), "%s/.cups", home); + if (access(filename, 0)) + mkdir(filename, 0700); + + snprintf(filename, sizeof(filename), "%s/.cups/lpoptions", home); + } + } +#endif /* !WIN32 */ + + /* + * Try to open the file... + */ + + if ((fp = fopen(filename, "w")) == NULL) + { + cupsFreeDests(num_temps, temps); + return (-1); + } + +#ifndef WIN32 + /* + * Set the permissions to 0644 when saving to the /etc/cups/lpoptions + * file... + */ + + if (!getuid()) + fchmod(fileno(fp), 0644); +#endif /* !WIN32 */ + + /* + * 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 this option is a printer attribute; if so, skip it... + */ + + if ((match = _ippFindOption(option->name)) != NULL && + match->group_tag == IPP_TAG_PRINTER) + continue; + + /* + * 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 && + !strcasecmp(val, option->value)) + 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, ' ') || + strchr(option->value, '\\') || + strchr(option->value, '\"') || + strchr(option->value, '\'')) + { + /* + * Quote the value... + */ + + fprintf(fp, " %s=\"", option->name); + + for (val = option->value; *val; val ++) + { + if (strchr("\"\'\\", *val)) + putc('\\', fp); + + putc(*val, fp); + } + + putc('\"', fp); + } + else + { + /* + * Store the literal value... + */ + + fprintf(fp, " %s=%s", option->name, option->value); + } + } + else + fprintf(fp, " %s", option->name); + } + + if (wrote) + fputs("\n", fp); + } + + /* + * Free the temporary destinations and close the file... + */ + + cupsFreeDests(num_temps, temps); + + fclose(fp); + +#ifdef __APPLE__ + /* + * Set the default printer for this location - this allows command-line + * and GUI applications to share the same default destination... + */ + + if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL) + appleSetDefault(dest->name); +#endif /* __APPLE__ */ + +#ifdef HAVE_NOTIFY_POST + /* + * Send a notification so that MacOS X applications can know about the + * change, too. + */ + + notify_post("com.apple.printerListChange"); +#endif /* HAVE_NOTIFY_POST */ + + return (0); +} + + +/* + * '_cupsUserDefault()' - Get the user default printer from environment + * variables and location information. + */ + +char * /* O - Default printer or NULL */ +_cupsUserDefault(char *name, /* I - Name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + const char *env; /* LPDEST or PRINTER env variable */ +#ifdef __APPLE__ + CFStringRef network; /* Network location */ + CFArrayRef locations; /* Location array */ + CFStringRef locprinter; /* Current printer */ +#endif /* __APPLE__ */ + + + if ((env = getenv("LPDEST")) == NULL) + if ((env = getenv("PRINTER")) != NULL && !strcmp(env, "lp")) + env = NULL; + + if (env) + { + strlcpy(name, env, namesize); + return (name); + } + +#ifdef __APPLE__ + /* + * Use location-based defaults if "use last printer" is selected in the + * system preferences... + */ + + if (!appleUseLastPrinter()) + { + DEBUG_puts("1_cupsUserDefault: Not using last printer as default..."); + name[0] = '\0'; + return (NULL); + } + + /* + * Get the current location... + */ + + if ((network = appleCopyNetwork()) == NULL) + { + DEBUG_puts("1_cupsUserDefault: Unable to get current network..."); + name[0] = '\0'; + return (NULL); + } + +# ifdef DEBUG + CFStringGetCString(network, name, namesize, kCFStringEncodingUTF8); + DEBUG_printf(("2_cupsUserDefault: network=\"%s\"", name)); +# endif /* DEBUG */ + + /* + * Lookup the network in the preferences... + */ + + if ((locations = appleCopyLocations()) == NULL) + { + /* + * Missing or bad location array, so no location-based default... + */ + + DEBUG_puts("1_cupsUserDefault: Missing or bad location history array..."); + + CFRelease(network); + + name[0] = '\0'; + return (NULL); + } + + DEBUG_printf(("2_cupsUserDefault: Got location, %d entries...", + (int)CFArrayGetCount(locations))); + + if ((locprinter = appleGetPrinter(locations, network, NULL)) != NULL) + CFStringGetCString(locprinter, name, namesize, kCFStringEncodingUTF8); + else + name[0] = '\0'; + + CFRelease(network); + CFRelease(locations); + + DEBUG_printf(("1_cupsUserDefault: Returning \"%s\"...", name)); + + return (*name ? name : NULL); + +#else + /* + * No location-based defaults on this platform... + */ + + name[0] = '\0'; + return (NULL); +#endif /* __APPLE__ */ +} + + +#ifdef __APPLE__ +/* + * 'appleCopyLocations()' - Copy the location history array. + */ + +static CFArrayRef /* O - Location array or NULL */ +appleCopyLocations(void) +{ + CFArrayRef locations; /* Location array */ + + + /* + * Look up the location array in the preferences... + */ + + if ((locations = CFPreferencesCopyAppValue(kLocationHistoryArrayKey, + kPMPrintingPreferences)) == NULL) + return (NULL); + + if (CFGetTypeID(locations) != CFArrayGetTypeID()) + { + CFRelease(locations); + return (NULL); + } + + return (locations); +} + + +/* + * 'appleCopyNetwork()' - Get the network ID for the current location. + */ + +static CFStringRef /* O - Network ID */ +appleCopyNetwork(void) +{ + SCDynamicStoreRef dynamicStore; /* System configuration data */ + CFStringRef key; /* Current network configuration key */ + CFDictionaryRef ip_dict; /* Network configuration data */ + CFStringRef network = NULL; /* Current network ID */ + + + if ((dynamicStore = SCDynamicStoreCreate(NULL, CFSTR("Printing"), NULL, + NULL)) != NULL) + { + if ((key = SCDynamicStoreKeyCreateNetworkGlobalEntity( + NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4)) != NULL) + { + if ((ip_dict = SCDynamicStoreCopyValue(dynamicStore, key)) != NULL) + { + if ((network = CFDictionaryGetValue(ip_dict, + kSCPropNetIPv4Router)) != NULL) + CFRetain(network); + + CFRelease(ip_dict); + } + + CFRelease(key); + } + + CFRelease(dynamicStore); + } + + return (network); +} + + +/* + * 'appleGetPaperSize()' - Get the default paper size. + */ + +static char * /* O - Default paper size */ +appleGetPaperSize(char *name, /* I - Paper size name buffer */ + int namesize) /* I - Size of buffer */ +{ + CFStringRef defaultPaperID; /* Default paper ID */ + _pwg_media_t *pwgmedia; /* PWG media size */ + + + defaultPaperID = CFPreferencesCopyAppValue(kDefaultPaperIDKey, + kPMPrintingPreferences); + if (!defaultPaperID || + CFGetTypeID(defaultPaperID) != CFStringGetTypeID() || + !CFStringGetCString(defaultPaperID, name, namesize, + kCFStringEncodingUTF8)) + name[0] = '\0'; + else if ((pwgmedia = _pwgMediaForLegacy(name)) != NULL) + strlcpy(name, pwgmedia->pwg, namesize); + + if (defaultPaperID) + CFRelease(defaultPaperID); + + return (name); +} + + +/* + * 'appleGetPrinter()' - Get a printer from the history array. + */ + +static CFStringRef /* O - Printer name or NULL */ +appleGetPrinter(CFArrayRef locations, /* I - Location array */ + CFStringRef network, /* I - Network name */ + CFIndex *locindex) /* O - Index in array */ +{ + CFIndex i, /* Looping var */ + count; /* Number of locations */ + CFDictionaryRef location; /* Current location */ + CFStringRef locnetwork, /* Current network */ + locprinter; /* Current printer */ + + + for (i = 0, count = CFArrayGetCount(locations); i < count; i ++) + if ((location = CFArrayGetValueAtIndex(locations, i)) != NULL && + CFGetTypeID(location) == CFDictionaryGetTypeID()) + { + if ((locnetwork = CFDictionaryGetValue(location, + kLocationNetworkKey)) != NULL && + CFGetTypeID(locnetwork) == CFStringGetTypeID() && + CFStringCompare(network, locnetwork, 0) == kCFCompareEqualTo && + (locprinter = CFDictionaryGetValue(location, + kLocationPrinterIDKey)) != NULL && + CFGetTypeID(locprinter) == CFStringGetTypeID()) + { + if (locindex) + *locindex = i; + + return (locprinter); + } + } + + return (NULL); +} + + +/* + * 'appleSetDefault()' - Set the default printer for this location. + */ + +static void +appleSetDefault(const char *name) /* I - Default printer/class name */ +{ + CFStringRef network; /* Current network */ + CFArrayRef locations; /* Old locations array */ + CFIndex locindex; /* Index in locations array */ + CFStringRef locprinter; /* Current printer */ + CFMutableArrayRef newlocations; /* New locations array */ + CFMutableDictionaryRef newlocation; /* New location */ + CFStringRef newprinter; /* New printer */ + + + /* + * Get the current location... + */ + + if ((network = appleCopyNetwork()) == NULL) + { + DEBUG_puts("1appleSetDefault: Unable to get current network..."); + return; + } + + if ((newprinter = CFStringCreateWithCString(kCFAllocatorDefault, name, + kCFStringEncodingUTF8)) == NULL) + { + CFRelease(network); + return; + } + + /* + * Lookup the network in the preferences... + */ + + if ((locations = appleCopyLocations()) != NULL) + locprinter = appleGetPrinter(locations, network, &locindex); + else + { + locprinter = NULL; + locindex = -1; + } + + if (!locprinter || + CFStringCompare(locprinter, newprinter, 0) != kCFCompareEqualTo) + { + /* + * Need to change the locations array... + */ + + if (locations) + { + newlocations = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, + locations); + + if (locprinter) + CFArrayRemoveValueAtIndex(newlocations, locindex); + } + else + newlocations = CFArrayCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeArrayCallBacks); + + newlocation = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + if (newlocation && newlocations) + { + /* + * Put the new location at the front of the array... + */ + + CFDictionaryAddValue(newlocation, kLocationNetworkKey, network); + CFDictionaryAddValue(newlocation, kLocationPrinterIDKey, newprinter); + CFArrayInsertValueAtIndex(newlocations, 0, newlocation); + + /* + * Limit the number of locations to 10... + */ + + while (CFArrayGetCount(newlocations) > 10) + CFArrayRemoveValueAtIndex(newlocations, 10); + + /* + * Push the changes out... + */ + + CFPreferencesSetAppValue(kLocationHistoryArrayKey, newlocations, + kPMPrintingPreferences); + CFPreferencesAppSynchronize(kPMPrintingPreferences); + notify_post("com.apple.printerPrefsChange"); + } + + if (newlocations) + CFRelease(newlocations); + + if (newlocation) + CFRelease(newlocation); + } + + if (locations) + CFRelease(locations); + + CFRelease(network); + CFRelease(newprinter); +} + + +/* + * 'appleUseLastPrinter()' - Get the default printer preference value. + */ + +static int /* O - 1 to use last printer, 0 otherwise */ +appleUseLastPrinter(void) +{ + CFPropertyListRef uselast; /* Use last printer preference value */ + + + if (getenv("CUPS_DISABLE_APPLE_DEFAULT")) + return (0); + + if ((uselast = CFPreferencesCopyAppValue(kUseLastPrinterAsCurrentPrinterKey, + kPMPrintingPreferences)) != NULL) + { + CFRelease(uselast); + + if (uselast == kCFBooleanFalse) + return (0); + } + + return (1); +} +#endif /* __APPLE__ */ + + +/* + * 'cups_add_dest()' - Add a destination to the array. + * + * Unlike cupsAddDest(), this function does not check for duplicates. + */ + +static cups_dest_t * /* O - New destination */ +cups_add_dest(const char *name, /* I - Name of destination */ + const char *instance, /* I - Instance or NULL */ + int *num_dests, /* IO - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int insert, /* Insertion point */ + diff; /* Result of comparison */ + cups_dest_t *dest; /* Destination pointer */ + + + /* + * 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) + return (NULL); + + *dests = dest; + + /* + * Find where to insert the destination... + */ + + if (*num_dests == 0) + insert = 0; + else + { + insert = cups_find_dest(name, instance, *num_dests, *dests, *num_dests - 1, + &diff); + + if (diff > 0) + insert ++; + } + + /* + * Move the array elements as needed... + */ + + if (insert < *num_dests) + memmove(*dests + insert + 1, *dests + insert, + (*num_dests - insert) * sizeof(cups_dest_t)); + + (*num_dests) ++; + + /* + * Initialize the destination... + */ + + dest = *dests + insert; + dest->name = _cupsStrAlloc(name); + dest->instance = _cupsStrAlloc(instance); + dest->is_default = 0; + dest->num_options = 0; + dest->options = (cups_option_t *)0; + + return (dest); +} + + +/* + * 'cups_compare_dests()' - Compare two destinations. + */ + +static int /* O - Result of comparison */ +cups_compare_dests(cups_dest_t *a, /* I - First destination */ + cups_dest_t *b) /* I - Second destination */ +{ + int diff; /* Difference */ + + + if ((diff = strcasecmp(a->name, b->name)) != 0) + return (diff); + else if (a->instance && b->instance) + return (strcasecmp(a->instance, b->instance)); + else + return ((a->instance && !b->instance) - (!a->instance && b->instance)); +} + + +/* + * 'cups_find_dest()' - Find a destination using a binary search. + */ + +static int /* O - Index of match */ +cups_find_dest(const char *name, /* I - Destination name */ + const char *instance, /* I - Instance or NULL */ + int num_dests, /* I - Number of destinations */ + cups_dest_t *dests, /* I - Destinations */ + int prev, /* I - Previous index */ + int *rdiff) /* O - Difference of match */ +{ + int left, /* Low mark for binary search */ + right, /* High mark for binary search */ + current, /* Current index */ + diff; /* Result of comparison */ + cups_dest_t key; /* Search key */ + + + key.name = (char *)name; + key.instance = (char *)instance; + + if (prev >= 0) + { + /* + * Start search on either side of previous... + */ + + if ((diff = cups_compare_dests(&key, dests + prev)) == 0 || + (diff < 0 && prev == 0) || + (diff > 0 && prev == (num_dests - 1))) + { + *rdiff = diff; + return (prev); + } + else if (diff < 0) + { + /* + * Start with previous on right side... + */ + + left = 0; + right = prev; + } + else + { + /* + * Start wih previous on left side... + */ + + left = prev; + right = num_dests - 1; + } + } + else + { + /* + * Start search in the middle... + */ + + left = 0; + right = num_dests - 1; + } + + do + { + current = (left + right) / 2; + diff = cups_compare_dests(&key, dests + current); + + if (diff == 0) + break; + else if (diff < 0) + right = current; + else + left = current; + } + while ((right - left) > 1); + + if (diff != 0) + { + /* + * Check the last 1 or 2 elements... + */ + + if ((diff = cups_compare_dests(&key, dests + left)) <= 0) + current = left; + else + { + diff = cups_compare_dests(&key, dests + right); + current = right; + } + } + + /* + * Return the closest destination and the difference... + */ + + *rdiff = diff; + + return (current); +} + + +/* + * 'cups_get_default()' - Get the default destination from an lpoptions file. + */ + +static char * /* O - Default destination or NULL */ +cups_get_default(const char *filename, /* I - File to read */ + char *namebuf, /* I - Name buffer */ + size_t namesize, /* I - Size of name buffer */ + const char **instance) /* I - Instance */ +{ + cups_file_t *fp; /* lpoptions file */ + char line[8192], /* Line from file */ + *value, /* Value for line */ + *nameptr; /* Pointer into name */ + int linenum; /* Current line */ + + + *namebuf = '\0'; + + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!strcasecmp(line, "default") && value) + { + strlcpy(namebuf, value, namesize); + + if ((nameptr = strchr(namebuf, ' ')) != NULL) + *nameptr = '\0'; + if ((nameptr = strchr(namebuf, '\t')) != NULL) + *nameptr = '\0'; + + if ((nameptr = strchr(namebuf, '/')) != NULL) + *nameptr++ = '\0'; + + *instance = nameptr; + break; + } + } + + cupsFileClose(fp); + } + + return (*namebuf ? namebuf : NULL); +} + + +/* + * '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 */ + const char *match_name, /* I - Destination name we want */ + const char *match_inst, /* I - Instance name we want */ + int user_default_set, /* I - User default printer set? */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int i; /* Looping var */ + cups_dest_t *dest; /* Current destination */ + cups_file_t *fp; /* File pointer */ + char line[8192], /* Line from file */ + *lineptr, /* Pointer into line */ + *name, /* Name of destination/option */ + *instance; /* Instance of destination */ + int linenum; /* Current line number */ + + + DEBUG_printf(("7cups_get_dests(filename=\"%s\", match_name=\"%s\", " + "match_inst=\"%s\", user_default_set=%d, num_dests=%d, " + "dests=%p)", filename, match_name, match_inst, + user_default_set, num_dests, dests)); + + /* + * Try to open the file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + return (num_dests); + + /* + * Read each printer; each line looks like: + * + * Dest name[/instance] options + * Default name[/instance] options + */ + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &lineptr, &linenum)) + { + /* + * See what type of line it is... + */ + + DEBUG_printf(("9cups_get_dests: linenum=%d line=\"%s\" lineptr=\"%s\"", + linenum, line, lineptr)); + + if ((strcasecmp(line, "dest") && strcasecmp(line, "default")) || !lineptr) + { + DEBUG_puts("9cups_get_dests: Not a dest or default line..."); + continue; + } + + name = lineptr; + + /* + * Search for an instance... + */ + + while (!isspace(*lineptr & 255) && *lineptr && *lineptr != '/') + lineptr ++; + + if (*lineptr == '/') + { + /* + * Found an instance... + */ + + *lineptr++ = '\0'; + instance = lineptr; + + /* + * Search for an instance... + */ + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + } + else + instance = NULL; + + if (*lineptr) + *lineptr++ = '\0'; + + DEBUG_printf(("9cups_get_dests: name=\"%s\", instance=\"%s\"", name, + instance)); + + /* + * See if the primary instance of the destination exists; if not, + * ignore this entry and move on... + */ + + if (match_name) + { + if (strcasecmp(name, match_name) || + (!instance && match_inst) || + (instance && !match_inst) || + (instance && strcasecmp(instance, match_inst))) + continue; + + dest = *dests; + } + else if (cupsGetDest(name, NULL, num_dests, *dests) == NULL) + { + DEBUG_puts("9cups_get_dests: Not found!"); + continue; + } + else + { + /* + * Add the destination... + */ + + num_dests = cupsAddDest(name, instance, num_dests, dests); + + if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL) + { + /* + * Out of memory! + */ + + DEBUG_puts("9cups_get_dests: Out of memory!"); + break; + } + } + + /* + * Add options until we hit the end of the line... + */ + + dest->num_options = cupsParseOptions(lineptr, dest->num_options, + &(dest->options)); + + /* + * If we found what we were looking for, stop now... + */ + + if (match_name) + break; + + /* + * Set this as default if needed... + */ + + if (!user_default_set && !strcasecmp(line, "default")) + { + DEBUG_puts("9cups_get_dests: Setting as default..."); + + for (i = 0; i < num_dests; i ++) + (*dests)[i].is_default = 0; + + dest->is_default = 1; + } + } + + /* + * Close the file and return... + */ + + cupsFileClose(fp); + + return (num_dests); +} + + +/* + * 'cups_get_sdests()' - Get destinations from a server. + */ + +static int /* O - Number of destinations */ +cups_get_sdests(http_t *http, /* I - Connection to server or CUPS_HTTP_DEFAULT */ + ipp_op_t op, /* I - IPP operation */ + const char *name, /* I - Name of destination */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + cups_dest_t *dest; /* Current destination */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + const char *printer_name; /* printer-name attribute */ + char uri[1024]; /* printer-uri value */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ +#ifdef __APPLE__ + char media_default[41]; /* Default paper size */ +#endif /* __APPLE__ */ + char optname[1024], /* Option name */ + value[2048], /* Option value */ + *ptr; /* Pointer into name/value */ + static const char * const pattrs[] = /* Attributes we're interested in */ + { + "auth-info-required", + "device-uri", + "job-sheets-default", + "marker-change-time", + "marker-colors", + "marker-high-levels", + "marker-levels", + "marker-low-levels", + "marker-message", + "marker-names", + "marker-types", +#ifdef __APPLE__ + "media-supported", +#endif /* __APPLE__ */ + "printer-commands", + "printer-defaults", + "printer-info", + "printer-is-accepting-jobs", + "printer-is-shared", + "printer-location", + "printer-make-and-model", + "printer-name", + "printer-state", + "printer-state-change-time", + "printer-state-reasons", + "printer-type", + "printer-uri-supported" + }; + + +#ifdef __APPLE__ + /* + * Get the default paper size... + */ + + appleGetPaperSize(media_default, sizeof(media_default)); +#endif /* __APPLE__ */ + + /* + * Build a CUPS_GET_PRINTERS or IPP_GET_PRINTER_ATTRIBUTES request, which + * require the following attributes: + * + * attributes-charset + * attributes-natural-language + * requesting-user-name + * printer-uri [for IPP_GET_PRINTER_ATTRIBUTES] + */ + + request = ippNewRequest(op); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, cupsUser()); + + if (name && op != CUPS_GET_DEFAULT) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/printers/%s", 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) + { + 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_name = NULL; + num_options = 0; + options = NULL; + + for (; attr && attr->group_tag == IPP_TAG_PRINTER; attr = attr->next) + { + if (attr->value_tag != IPP_TAG_INTEGER && + attr->value_tag != IPP_TAG_ENUM && + attr->value_tag != IPP_TAG_BOOLEAN && + attr->value_tag != IPP_TAG_TEXT && + attr->value_tag != IPP_TAG_TEXTLANG && + attr->value_tag != IPP_TAG_NAME && + attr->value_tag != IPP_TAG_NAMELANG && + attr->value_tag != IPP_TAG_KEYWORD && + attr->value_tag != IPP_TAG_RANGE && + attr->value_tag != IPP_TAG_URI) + continue; + + if (!strcmp(attr->name, "auth-info-required") || + !strcmp(attr->name, "device-uri") || + !strcmp(attr->name, "marker-change-time") || + !strcmp(attr->name, "marker-colors") || + !strcmp(attr->name, "marker-high-levels") || + !strcmp(attr->name, "marker-levels") || + !strcmp(attr->name, "marker-low-levels") || + !strcmp(attr->name, "marker-message") || + !strcmp(attr->name, "marker-names") || + !strcmp(attr->name, "marker-types") || + !strcmp(attr->name, "printer-commands") || + !strcmp(attr->name, "printer-info") || + !strcmp(attr->name, "printer-is-shared") || + !strcmp(attr->name, "printer-make-and-model") || + !strcmp(attr->name, "printer-state") || + !strcmp(attr->name, "printer-state-change-time") || + !strcmp(attr->name, "printer-type") || + !strcmp(attr->name, "printer-is-accepting-jobs") || + !strcmp(attr->name, "printer-location") || + !strcmp(attr->name, "printer-state-reasons") || + !strcmp(attr->name, "printer-uri-supported")) + { + /* + * Add a printer description attribute... + */ + + num_options = cupsAddOption(attr->name, + cups_make_string(attr, value, + sizeof(value)), + num_options, &options); + } +#ifdef __APPLE__ + else if (!strcmp(attr->name, "media-supported")) + { + /* + * See if we can set a default media size... + */ + + int i; /* Looping var */ + + for (i = 0; i < attr->num_values; i ++) + if (!strcasecmp(media_default, attr->values[i].string.text)) + { + num_options = cupsAddOption("media", media_default, num_options, + &options); + break; + } + } +#endif /* __APPLE__ */ + else if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) + printer_name = attr->values[0].string.text; + else if (strncmp(attr->name, "notify-", 7) && + (attr->value_tag == IPP_TAG_BOOLEAN || + attr->value_tag == IPP_TAG_ENUM || + attr->value_tag == IPP_TAG_INTEGER || + attr->value_tag == IPP_TAG_KEYWORD || + attr->value_tag == IPP_TAG_NAME || + attr->value_tag == IPP_TAG_RANGE) && + (ptr = strstr(attr->name, "-default")) != NULL) + { + /* + * Add a default option... + */ + + strlcpy(optname, attr->name, sizeof(optname)); + optname[ptr - attr->name] = '\0'; + + if (strcasecmp(optname, "media") || + !cupsGetOption("media", num_options, options)) + num_options = cupsAddOption(optname, + cups_make_string(attr, value, + sizeof(value)), + num_options, &options); + } + } + + /* + * See if we have everything needed... + */ + + if (!printer_name) + { + cupsFreeOptions(num_options, options); + + if (attr == NULL) + break; + else + continue; + } + + if ((dest = cups_add_dest(printer_name, NULL, &num_dests, dests)) != NULL) + { + dest->num_options = num_options; + dest->options = options; + } + else + cupsFreeOptions(num_options, options); + + if (attr == NULL) + break; + } + + ippDelete(response); + } + + /* + * Return the count... + */ + + return (num_dests); +} + + +/* + * 'cups_make_string()' - Make a comma-separated string of values from an IPP + * attribute. + */ + +static char * /* O - New string */ +cups_make_string( + ipp_attribute_t *attr, /* I - Attribute to convert */ + char *buffer, /* I - Buffer */ + size_t bufsize) /* I - Size of buffer */ +{ + int i; /* Looping var */ + char *ptr, /* Pointer into buffer */ + *end, /* Pointer to end of buffer */ + *valptr; /* Pointer into string attribute */ + + + /* + * Return quickly if we have a single string value... + */ + + if (attr->num_values == 1 && + attr->value_tag != IPP_TAG_INTEGER && + attr->value_tag != IPP_TAG_ENUM && + attr->value_tag != IPP_TAG_BOOLEAN && + attr->value_tag != IPP_TAG_RANGE) + return (attr->values[0].string.text); + + /* + * Copy the values to the string, separating with commas and escaping strings + * as needed... + */ + + end = buffer + bufsize - 1; + + for (i = 0, ptr = buffer; i < attr->num_values && ptr < end; i ++) + { + if (i) + *ptr++ = ','; + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + snprintf(ptr, end - ptr + 1, "%d", attr->values[i].integer); + break; + + case IPP_TAG_BOOLEAN : + if (attr->values[i].boolean) + strlcpy(ptr, "true", end - ptr + 1); + else + strlcpy(ptr, "false", end - ptr + 1); + break; + + case IPP_TAG_RANGE : + if (attr->values[i].range.lower == attr->values[i].range.upper) + snprintf(ptr, end - ptr + 1, "%d", attr->values[i].range.lower); + else + snprintf(ptr, end - ptr + 1, "%d-%d", attr->values[i].range.lower, + attr->values[i].range.upper); + break; + + default : + for (valptr = attr->values[i].string.text; + *valptr && ptr < end;) + { + if (strchr(" \t\n\\\'\"", *valptr)) + { + if (ptr >= (end - 1)) + break; + + *ptr++ = '\\'; + } + + *ptr++ = *valptr++; + } + + *ptr = '\0'; + break; + } + + ptr += strlen(ptr); + } + + *ptr = '\0'; + + return (buffer); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/dir.c b/cups/dir.c new file mode 100644 index 0000000000..8f9b0b92dd --- /dev/null +++ b/cups/dir.c @@ -0,0 +1,474 @@ +/* + * "$Id$" + * + * Public directory routines for the Common UNIX Printing System (CUPS). + * + * This set of APIs abstracts enumeration of directory entries. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * _cups_dir_time() - Convert a FILETIME value to a UNIX time value. + * cupsDirClose() - Close a directory. + * cupsDirOpen() - Open a directory. + * cupsDirRead() - Read the next directory entry. + * cupsDirRewind() - Rewind to the start of the directory. + * cupsDirClose() - Close a directory. + * cupsDirOpen() - Open a directory. + * cupsDirRead() - Read the next directory entry. + * cupsDirRewind() - Rewind to the start of the directory. + */ + +/* + * Include necessary headers... + */ + +#include "dir.h" +#include "string.h" +#include "debug.h" +#include +#include + + +/* + * Windows implementation... + */ + +#ifdef WIN32 +# include + +/* + * Types and structures... + */ + +struct _cups_dir_s /**** Directory data structure ****/ +{ + char directory[1024]; /* Directory filename */ + HANDLE dir; /* Directory handle */ + cups_dentry_t entry; /* Directory entry */ +}; + + +/* + * '_cups_dir_time()' - Convert a FILETIME value to a UNIX time value. + */ + +time_t /* O - UNIX time */ +_cups_dir_time(FILETIME ft) /* I - File time */ +{ + ULONGLONG val; /* File time in 0.1 usecs */ + + + /* + * Convert file time (1/10 microseconds since Jan 1, 1601) to UNIX + * time (seconds since Jan 1, 1970). There are 11,644,732,800 seconds + * between them... + */ + + val = ft.dwLowDateTime + ((ULONGLONG)ft.dwHighDateTime << 32); + return ((time_t)(val / 10000000 - 11644732800)); +} + + +/* + * 'cupsDirClose()' - Close a directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */ +{ + /* + * Range check input... + */ + + if (!dp) + return; + + /* + * Close an open directory handle... + */ + + if (dp->dir != INVALID_HANDLE_VALUE) + FindClose(dp->dir); + + /* + * Free memory used... + */ + + free(dp); +} + + +/* + * 'cupsDirOpen()' - Open a directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */ +cupsDirOpen(const char *directory) /* I - Directory name */ +{ + cups_dir_t *dp; /* Directory */ + + + /* + * Range check input... + */ + + if (!directory) + return (NULL); + + /* + * Allocate memory for the directory structure... + */ + + dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t)); + if (!dp) + return (NULL); + + /* + * Copy the directory name for later use... + */ + + dp->dir = INVALID_HANDLE_VALUE; + + strlcpy(dp->directory, directory, sizeof(dp->directory)); + + /* + * Return the new directory structure... + */ + + return (dp); +} + + +/* + * 'cupsDirRead()' - Read the next directory entry. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_dentry_t * /* O - Directory entry or @code NULL@ if there are no more */ +cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */ +{ + WIN32_FIND_DATA entry; /* Directory entry data */ + + + /* + * Range check input... + */ + + if (!dp) + return (NULL); + + /* + * See if we have already started finding files... + */ + + if (dp->dir == INVALID_HANDLE_VALUE) + { + /* + * No, find the first file... + */ + + dp->dir = FindFirstFile(dp->directory, &entry); + if (dp->dir == INVALID_HANDLE_VALUE) + return (NULL); + } + else if (!FindNextFile(dp->dir, &entry)) + return (NULL); + + /* + * Copy the name over and convert the file information... + */ + + strlcpy(dp->entry.filename, entry.cFileName, sizeof(dp->entry.filename)); + + if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + dp->entry.fileinfo.st_mode = 0755 | S_IFDIR; + else + dp->entry.fileinfo.st_mode = 0644; + + dp->entry.fileinfo.st_atime = _cups_dir_time(entry.ftLastAccessTime); + dp->entry.fileinfo.st_ctime = _cups_dir_time(entry.ftCreationTime); + dp->entry.fileinfo.st_mtime = _cups_dir_time(entry.ftLastWriteTime); + dp->entry.fileinfo.st_size = entry.nFileSizeLow + (entry.nFileSizeHigh << 32); + + /* + * Return the entry... + */ + + return (&(dp->entry)); +} + + +/* + * 'cupsDirRewind()' - Rewind to the start of the directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */ +{ + /* + * Range check input... + */ + + if (!dp) + return; + + /* + * Close an open directory handle... + */ + + if (dp->dir != INVALID_HANDLE_VALUE) + { + FindClose(dp->dir); + dp->dir = INVALID_HANDLE_VALUE; + } +} + + +#else + +/* + * POSIX implementation... + */ + +# include +# include + + +/* + * Types and structures... + */ + +struct _cups_dir_s /**** Directory data structure ****/ +{ + char directory[1024]; /* Directory filename */ + DIR *dir; /* Directory file */ + cups_dentry_t entry; /* Directory entry */ +}; + + +/* + * 'cupsDirClose()' - Close a directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsDirClose(cups_dir_t *dp) /* I - Directory pointer */ +{ + DEBUG_printf(("cupsDirClose(dp=%p)", dp)); + + /* + * Range check input... + */ + + if (!dp) + return; + + /* + * Close the directory and free memory... + */ + + closedir(dp->dir); + free(dp); +} + + +/* + * 'cupsDirOpen()' - Open a directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_dir_t * /* O - Directory pointer or @code NULL@ if the directory could not be opened. */ +cupsDirOpen(const char *directory) /* I - Directory name */ +{ + cups_dir_t *dp; /* Directory */ + + + DEBUG_printf(("cupsDirOpen(directory=\"%s\")", directory)); + + /* + * Range check input... + */ + + if (!directory) + return (NULL); + + /* + * Allocate memory for the directory structure... + */ + + dp = (cups_dir_t *)calloc(1, sizeof(cups_dir_t)); + if (!dp) + return (NULL); + + /* + * Open the directory... + */ + + dp->dir = opendir(directory); + if (!dp->dir) + { + free(dp); + return (NULL); + } + + /* + * Copy the directory name for later use... + */ + + strlcpy(dp->directory, directory, sizeof(dp->directory)); + + /* + * Return the new directory structure... + */ + + return (dp); +} + + +/* + * 'cupsDirRead()' - Read the next directory entry. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_dentry_t * /* O - Directory entry or @code NULL@ when there are no more */ +cupsDirRead(cups_dir_t *dp) /* I - Directory pointer */ +{ + struct dirent *entry; /* Pointer to entry */ + char filename[1024]; /* Full filename */ +# ifdef HAVE_PTHREAD_H + char buffer[sizeof(struct dirent) + 1024]; + /* Directory entry buffer */ +# endif /* HAVE_PTHREAD_H */ + + + DEBUG_printf(("2cupsDirRead(dp=%p)", dp)); + + /* + * Range check input... + */ + + if (!dp) + return (NULL); + + /* + * Try reading an entry that is not "." or ".."... + */ + + for (;;) + { +# ifdef HAVE_PTHREAD_H + /* + * Read the next entry using the reentrant version of readdir... + */ + + if (readdir_r(dp->dir, (struct dirent *)buffer, &entry)) + { + DEBUG_printf(("3cupsDirRead: readdir_r() failed - %s\n", strerror(errno))); + return (NULL); + } + + if (!entry) + { + DEBUG_puts("3cupsDirRead: readdir_r() returned a NULL pointer!"); + return (NULL); + } + + DEBUG_printf(("4cupsDirRead: readdir_r() returned \"%s\"...", + entry->d_name)); + +# else + /* + * Read the next entry using the original version of readdir... + */ + + if ((entry = readdir(dp->dir)) == NULL) + { + DEBUG_puts("3cupsDirRead: readdir() returned a NULL pointer!"); + return (NULL); + } + + DEBUG_printf(("4cupsDirRead: readdir() returned \"%s\"...", entry->d_name)); + +# endif /* HAVE_PTHREAD_H */ + + /* + * Skip "." and ".."... + */ + + if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) + continue; + + /* + * Copy the name over and get the file information... + */ + + strlcpy(dp->entry.filename, entry->d_name, sizeof(dp->entry.filename)); + + snprintf(filename, sizeof(filename), "%s/%s", dp->directory, entry->d_name); + + if (stat(filename, &(dp->entry.fileinfo))) + { + DEBUG_printf(("3cupsDirRead: stat() failed for \"%s\" - %s...", filename, + strerror(errno))); + continue; + } + + /* + * Return the entry... + */ + + return (&(dp->entry)); + } +} + + +/* + * 'cupsDirRewind()' - Rewind to the start of the directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsDirRewind(cups_dir_t *dp) /* I - Directory pointer */ +{ + DEBUG_printf(("cupsDirRewind(dp=%p)", dp)); + + /* + * Range check input... + */ + + if (!dp) + return; + + /* + * Rewind the directory... + */ + + rewinddir(dp->dir); +} + + +#endif /* WIN32 */ + +/* + * End of "$Id$". + */ diff --git a/cups/dir.h b/cups/dir.h new file mode 100644 index 0000000000..5a4f8d6d00 --- /dev/null +++ b/cups/dir.h @@ -0,0 +1,69 @@ +/* + * "$Id$" + * + * Public directory definitions for the Common UNIX Printing System (CUPS). + * + * This set of APIs abstracts enumeration of directory entries. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_DIR_H_ +# define _CUPS_DIR_H_ + + +/* + * Include necessary headers... + */ + +# include "versioning.h" +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Data types... + */ + +typedef struct _cups_dir_s cups_dir_t; /**** Directory type ****/ + +typedef struct cups_dentry_s /**** Directory entry type ****/ +{ + char filename[260]; /* File name */ + struct stat fileinfo; /* File information */ +} cups_dentry_t; + + +/* + * Prototypes... + */ + +extern void cupsDirClose(cups_dir_t *dp) _CUPS_API_1_2; +extern cups_dir_t *cupsDirOpen(const char *directory) _CUPS_API_1_2; +extern cups_dentry_t *cupsDirRead(cups_dir_t *dp) _CUPS_API_1_2; +extern void cupsDirRewind(cups_dir_t *dp) _CUPS_API_1_2; + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_DIR_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/emit.c b/cups/emit.c new file mode 100644 index 0000000000..748533d517 --- /dev/null +++ b/cups/emit.c @@ -0,0 +1,1222 @@ +/* + * "$Id$" + * + * PPD code emission routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * ppdCollect2() - Collect all marked options that reside in the + * specified section and minimum order. + * ppdEmit() - Emit code for marked options to a file. + * ppdEmitAfterOrder() - Emit a subset of the 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. + * ppdEmitJCLEnd() - Emit JCLEnd code to a file. + * ppdEmitString() - Get a string containing the code for marked + * options. + * ppd_compare_cparams() - Compare the order of two custom parameters. + * ppd_handle_media() - Handle media selection... + */ + +/* + * Include necessary headers... + */ + +#include "ppd.h" +#include +#include "string.h" +#include +#include "debug.h" + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * Local functions... + */ + +static int ppd_compare_cparams(ppd_cparam_t *a, ppd_cparam_t *b); +static void ppd_handle_media(ppd_file_t *ppd); + + +/* + * Local globals... + */ + +static const char ppd_custom_code[] = + "pop pop pop\n" + "<>setpagedevice\n"; + + +/* + * 'ppdCollect()' - Collect all marked options that reside in the specified + * section. + * + * The choices array should be freed using @code free@ when you are + * finished with it. + */ + +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 */ +{ + return (ppdCollect2(ppd, section, 0.0, choices)); +} + + +/* + * 'ppdCollect2()' - Collect all marked options that reside in the + * specified section and minimum order. + * + * The choices array should be freed using @code free@ when you are + * finished with it. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Number of options marked */ +ppdCollect2(ppd_file_t *ppd, /* I - PPD file data */ + ppd_section_t section, /* I - Section to collect */ + float min_order, /* I - Minimum OrderDependency value */ + ppd_choice_t ***choices) /* O - Pointers to choices */ +{ + ppd_choice_t *c; /* Current choice */ + ppd_section_t csection; /* Current section */ + float corder; /* Current OrderDependency value */ + int count; /* Number of choices collected */ + ppd_choice_t **collect; /* Collected choices */ + float *orders; /* Collected order values */ + + + DEBUG_printf(("ppdCollect2(ppd=%p, section=%d, min_order=%f, choices=%p)", + ppd, section, min_order, choices)); + + if (!ppd || !choices) + { + if (choices) + *choices = NULL; + + return (0); + } + + /* + * Allocate memory for up to N selected choices... + */ + + count = 0; + if ((collect = calloc(sizeof(ppd_choice_t *), + cupsArrayCount(ppd->marked))) == NULL) + { + *choices = NULL; + return (0); + } + + if ((orders = calloc(sizeof(float), cupsArrayCount(ppd->marked))) == NULL) + { + *choices = NULL; + free(collect); + return (0); + } + + /* + * Loop through all options and add choices as needed... + */ + + for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); + c; + c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) + { + csection = c->option->section; + corder = c->option->order; + + if (!strcmp(c->choice, "Custom")) + { + ppd_attr_t *attr; /* NonUIOrderDependency value */ + float aorder; /* Order value */ + char asection[17], /* Section name */ + amain[PPD_MAX_NAME + 1], + aoption[PPD_MAX_NAME]; + /* *CustomFoo and True */ + + + for (attr = ppdFindAttr(ppd, "NonUIOrderDependency", NULL); + attr; + attr = ppdFindNextAttr(ppd, "NonUIOrderDependency", NULL)) + if (attr->value && + sscanf(attr->value, "%f%16s%41s%40s", &aorder, asection, amain, + aoption) == 4 && + !strncmp(amain, "*Custom", 7) && + !strcmp(amain + 7, c->option->keyword) && !strcmp(aoption, "True")) + { + /* + * Use this NonUIOrderDependency... + */ + + corder = aorder; + + if (!strcmp(asection, "DocumentSetup")) + csection = PPD_ORDER_DOCUMENT; + else if (!strcmp(asection, "ExitServer")) + csection = PPD_ORDER_EXIT; + else if (!strcmp(asection, "JCLSetup")) + csection = PPD_ORDER_JCL; + else if (!strcmp(asection, "PageSetup")) + csection = PPD_ORDER_PAGE; + else if (!strcmp(asection, "Prolog")) + csection = PPD_ORDER_PROLOG; + else + csection = PPD_ORDER_ANY; + + break; + } + } + + if (csection == section && corder >= min_order) + { + collect[count] = c; + orders[count] = corder; + count ++; + } + } + + /* + * If we have more than 1 marked choice, sort them... + */ + + if (count > 1) + { + int i, j; /* Looping vars */ + + for (i = 0; i < (count - 1); i ++) + for (j = i + 1; j < count; j ++) + if (orders[i] > orders[j]) + { + c = collect[i]; + corder = orders[i]; + collect[i] = collect[j]; + orders[i] = orders[j]; + collect[j] = c; + orders[j] = corder; + } + } + + free(orders); + + DEBUG_printf(("2ppdCollect2: %d marked choices...", count)); + + /* + * 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 */ +{ + return (ppdEmitAfterOrder(ppd, fp, section, 0, 0.0)); +} + + +/* + * 'ppdEmitAfterOrder()' - Emit a subset of the code for marked options to a file. + * + * When "limit" is non-zero, this function only emits options whose + * OrderDependency value is greater than or equal to "min_order". + * + * When "limit" is zero, this function is identical to ppdEmit(). + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on failure */ +ppdEmitAfterOrder( + ppd_file_t *ppd, /* I - PPD file record */ + FILE *fp, /* I - File to write to */ + ppd_section_t section, /* I - Section to write */ + int limit, /* I - Non-zero to use min_order */ + float min_order) /* I - Lowest OrderDependency */ +{ + char *buffer; /* Option code */ + int status; /* Return status */ + + + /* + * Range check input... + */ + + if (!ppd || !fp) + return (-1); + + /* + * Get the string... + */ + + buffer = ppdEmitString(ppd, section, min_order); + + /* + * Write it as needed and return... + */ + + if (buffer) + { + status = fputs(buffer, fp) < 0 ? -1 : 0; + + free(buffer); + } + else + status = 0; + + return (status); +} + + +/* + * '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 */ +{ + char *buffer, /* Option code */ + *bufptr; /* Pointer into code */ + size_t buflength; /* Length of option code */ + ssize_t bytes; /* Bytes written */ + int status; /* Return status */ + + + /* + * Range check input... + */ + + if (!ppd || fd < 0) + return (-1); + + /* + * Get the string... + */ + + buffer = ppdEmitString(ppd, section, 0.0); + + /* + * Write it as needed and return... + */ + + if (buffer) + { + buflength = strlen(buffer); + bufptr = buffer; + bytes = 0; + + while (buflength > 0) + { +#ifdef WIN32 + if ((bytes = (ssize_t)write(fd, bufptr, (unsigned)buflength)) < 0) +#else + if ((bytes = write(fd, bufptr, buflength)) < 0) +#endif /* WIN32 */ + { + if (errno == EAGAIN || errno == EINTR) + continue; + + break; + } + + buflength -= bytes; + bufptr += bytes; + } + + status = bytes < 0 ? -1 : 0; + + free(buffer); + } + else + status = 0; + + return (status); +} + + +/* + * '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 */ +{ + char *ptr; /* Pointer into JCL string */ + char temp[65], /* Local title string */ + displaymsg[33]; /* Local display string */ + + + /* + * Range check the input... + */ + + if (!ppd || !ppd->jcl_begin || !ppd->jcl_ps) + return (0); + + /* + * See if the printer supports HP PJL... + */ + + if (!strncmp(ppd->jcl_begin, "\033%-12345X@", 10)) + { + /* + * This printer uses HP PJL commands for output; filter the output + * so that we only have a single "@PJL JOB" command in the header... + * + * To avoid bugs in the PJL implementation of certain vendors' products + * (Xerox in particular), we add a dummy "@PJL" command at the beginning + * of the PJL commands to initialize PJL processing. + */ + + ppd_attr_t *charset; /* PJL charset */ + ppd_attr_t *display; /* PJL display command */ + + + if ((charset = ppdFindAttr(ppd, "cupsPJLCharset", NULL)) != NULL) + { + if (!charset->value || strcasecmp(charset->value, "UTF-8")) + charset = NULL; + } + + if ((display = ppdFindAttr(ppd, "cupsPJLDisplay", NULL)) != NULL) + { + if (!display->value) + display = NULL; + } + + fputs("\033%-12345X@PJL\n", fp); + for (ptr = ppd->jcl_begin + 9; *ptr;) + if (!strncmp(ptr, "@PJL JOB", 8)) + { + /* + * 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 ++; + } + + /* + * Clean up the job title... + */ + + if ((ptr = strrchr(title, '/')) != NULL) + { + /* + * Only show basename of file path... + */ + + title = ptr + 1; + } + + if (!strncmp(title, "smbprn.", 7)) + { + /* + * Skip leading smbprn.######## from Samba jobs... + */ + + for (title += 7; *title && isdigit(*title & 255); title ++); + while (_cups_isspace(*title)) + title ++; + + if ((ptr = strstr(title, " - ")) != NULL) + { + /* + * Skip application name in "Some Application - Title of job"... + */ + + title = ptr + 3; + } + } + + /* + * Replace double quotes with single quotes and UTF-8 characters with + * question marks so that the title does not cause a PJL syntax error. + */ + + strlcpy(temp, title, sizeof(temp)); + + for (ptr = temp; *ptr; ptr ++) + if (*ptr == '\"') + *ptr = '\''; + else if (!charset && (*ptr & 128)) + *ptr = '?'; + + /* + * CUPS STR #3125: Long PJL JOB NAME causes problems with some printers + * + * Generate the display message, truncating at 32 characters + nul to avoid + * issues with some printer's PJL implementations... + */ + + snprintf(displaymsg, sizeof(displaymsg), "%d %s %s", job_id, user, temp); + + /* + * Send PJL JOB and PJL RDYMSG commands before we enter PostScript mode... + */ + + if (display && strcmp(display->value, "job")) + { + fprintf(fp, "@PJL JOB NAME = \"%s\"\n", temp); + + if (display && !strcmp(display->value, "rdymsg")) + fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg); + } + else + fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%s\"\n", temp, + displaymsg); + } + else + fputs(ppd->jcl_begin, fp); + + ppdEmit(ppd, fp, PPD_ORDER_JCL); + fputs(ppd->jcl_ps, fp); + + return (0); +} + + +/* + * 'ppdEmitJCLEnd()' - Emit JCLEnd code to a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on failure */ +ppdEmitJCLEnd(ppd_file_t *ppd, /* I - PPD file record */ + FILE *fp) /* I - File to write to */ +{ + /* + * Range check the input... + */ + + if (!ppd) + return (0); + + if (!ppd->jcl_end) + { + if (ppd->num_filters == 0) + putc(0x04, fp); + + return (0); + } + + /* + * See if the printer supports HP PJL... + */ + + if (!strncmp(ppd->jcl_end, "\033%-12345X@", 10)) + { + /* + * This printer uses HP PJL commands for output; filter the output + * so that we only have a single "@PJL JOB" command in the header... + * + * To avoid bugs in the PJL implementation of certain vendors' products + * (Xerox in particular), we add a dummy "@PJL" command at the beginning + * of the PJL commands to initialize PJL processing. + */ + + fputs("\033%-12345X@PJL\n", fp); + fputs("@PJL RDYMSG DISPLAY = \"\"\n", fp); + fputs(ppd->jcl_end + 9, fp); + } + else + fputs(ppd->jcl_end, fp); + + return (0); +} + + +/* + * 'ppdEmitString()' - Get a string containing the code for marked options. + * + * When "min_order" is greater than zero, this function only includes options + * whose OrderDependency value is greater than or equal to "min_order". + * Otherwise, all options in the specified section are included in the + * returned string. + * + * The return string is allocated on the heap and should be freed using + * @code free@ when you are done with it. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - String containing option code or @code NULL@ if there is no option code */ +ppdEmitString(ppd_file_t *ppd, /* I - PPD file record */ + ppd_section_t section, /* I - Section to write */ + float min_order) /* I - Lowest OrderDependency */ +{ + int i, j, /* Looping vars */ + count; /* Number of choices */ + ppd_choice_t **choices; /* Choices */ + ppd_size_t *size; /* Custom page size */ + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + size_t bufsize; /* Size of string buffer needed */ + char *buffer, /* String buffer */ + *bufptr, /* Pointer into buffer */ + *bufend; /* End of buffer */ + struct lconv *loc; /* Locale data */ + + + DEBUG_printf(("ppdEmitString(ppd=%p, section=%d, min_order=%f)", + ppd, section, min_order)); + + /* + * Range check input... + */ + + if (!ppd) + return (NULL); + + /* + * Use PageSize or PageRegion as required... + */ + + ppd_handle_media(ppd); + + /* + * Collect the options we need to emit... + */ + + if ((count = ppdCollect2(ppd, section, min_order, &choices)) == 0) + return (NULL); + + /* + * Count the number of bytes that are required to hold all of the + * option code... + */ + + for (i = 0, bufsize = 1; i < count; i ++) + { + if (section == PPD_ORDER_JCL) + { + if (!strcasecmp(choices[i]->choice, "Custom") && + (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) + != NULL) + { + /* + * Add space to account for custom parameter substitution... + */ + + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + { + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_POINTS : + case PPD_CUSTOM_REAL : + case PPD_CUSTOM_INT : + bufsize += 10; + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) + bufsize += strlen(cparam->current.custom_string); + break; + } + } + } + } + else if (section != PPD_ORDER_EXIT) + { + bufsize += 3; /* [{\n */ + + if ((!strcasecmp(choices[i]->option->keyword, "PageSize") || + !strcasecmp(choices[i]->option->keyword, "PageRegion")) && + !strcasecmp(choices[i]->choice, "Custom")) + { + DEBUG_puts("2ppdEmitString: Custom size set!"); + + bufsize += 37; /* %%BeginFeature: *CustomPageSize True\n */ + bufsize += 50; /* Five 9-digit numbers + newline */ + } + else if (!strcasecmp(choices[i]->choice, "Custom") && + (coption = ppdFindCustomOption(ppd, + choices[i]->option->keyword)) + != NULL) + { + bufsize += 23 + strlen(choices[i]->option->keyword) + 6; + /* %%BeginFeature: *Customkeyword True\n */ + + + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + { + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_POINTS : + case PPD_CUSTOM_REAL : + case PPD_CUSTOM_INT : + bufsize += 10; + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + bufsize += 3; + if (cparam->current.custom_string) + bufsize += 4 * strlen(cparam->current.custom_string); + break; + } + } + } + else + bufsize += 17 + strlen(choices[i]->option->keyword) + 1 + + strlen(choices[i]->choice) + 1; + /* %%BeginFeature: *keyword choice\n */ + + bufsize += 13; /* %%EndFeature\n */ + bufsize += 22; /* } stopped cleartomark\n */ + } + + if (choices[i]->code) + bufsize += strlen(choices[i]->code) + 1; + else + bufsize += strlen(ppd_custom_code); + } + + /* + * Allocate memory... + */ + + DEBUG_printf(("2ppdEmitString: Allocating %d bytes for string...", + (int)bufsize)); + + if ((buffer = calloc(1, bufsize)) == NULL) + { + free(choices); + return (NULL); + } + + bufend = buffer + bufsize - 1; + loc = localeconv(); + + /* + * Copy the option code to the buffer... + */ + + for (i = 0, bufptr = buffer; i < count; i ++, bufptr += strlen(bufptr)) + if (section == PPD_ORDER_JCL) + { + if (!strcasecmp(choices[i]->choice, "Custom") && + choices[i]->code && + (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) + != NULL) + { + /* + * Handle substitutions in custom JCL options... + */ + + char *cptr; /* Pointer into code */ + int pnum; /* Parameter number */ + + + for (cptr = choices[i]->code; *cptr && bufptr < bufend;) + { + if (*cptr == '\\') + { + cptr ++; + + if (isdigit(*cptr & 255)) + { + /* + * Substitute parameter... + */ + + pnum = *cptr++ - '0'; + while (isdigit(*cptr & 255)) + pnum = pnum * 10 + *cptr++ - '0'; + + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + if (cparam->order == pnum) + break; + + if (cparam) + { + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_POINTS : + case PPD_CUSTOM_REAL : + bufptr = _cupsStrFormatd(bufptr, bufend, + cparam->current.custom_real, + loc); + break; + + case PPD_CUSTOM_INT : + snprintf(bufptr, bufend - bufptr, "%d", + cparam->current.custom_int); + bufptr += strlen(bufptr); + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) + { + strlcpy(bufptr, cparam->current.custom_string, + bufend - bufptr); + bufptr += strlen(bufptr); + } + break; + } + } + } + else if (*cptr) + *bufptr++ = *cptr++; + } + else + *bufptr++ = *cptr++; + } + } + else + { + /* + * Otherwise just copy the option code directly... + */ + + strlcpy(bufptr, choices[i]->code, bufend - bufptr + 1); + bufptr += strlen(bufptr); + } + } + else if (section != PPD_ORDER_EXIT) + { + /* + * Add wrapper commands to prevent printer errors for unsupported + * options... + */ + + strlcpy(bufptr, "[{\n", bufend - bufptr + 1); + bufptr += 3; + + /* + * Send DSC comments with option... + */ + + DEBUG_printf(("2ppdEmitString: Adding code for %s=%s...", + choices[i]->option->keyword, choices[i]->choice)); + + if ((!strcasecmp(choices[i]->option->keyword, "PageSize") || + !strcasecmp(choices[i]->option->keyword, "PageRegion")) && + !strcasecmp(choices[i]->choice, "Custom")) + { + /* + * Variable size; write out standard size options, using the + * parameter positions defined in the PPD file... + */ + + ppd_attr_t *attr; /* PPD attribute */ + int pos, /* Position of custom value */ + orientation; /* Orientation to use */ + float values[5]; /* Values for custom command */ + + + strlcpy(bufptr, "%%BeginFeature: *CustomPageSize True\n", + bufend - bufptr + 1); + bufptr += 37; + + size = ppdPageSize(ppd, "Custom"); + + memset(values, 0, sizeof(values)); + + if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Width")) != NULL) + { + pos = atoi(attr->value) - 1; + + if (pos < 0 || pos > 4) + pos = 0; + } + else + pos = 0; + + values[pos] = size->width; + + if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", "Height")) != NULL) + { + pos = atoi(attr->value) - 1; + + if (pos < 0 || pos > 4) + pos = 1; + } + else + pos = 1; + + values[pos] = size->length; + + /* + * According to the Adobe PPD specification, an orientation of 1 + * will produce a print that comes out upside-down with the X + * axis perpendicular to the direction of feed, which is exactly + * what we want to be consistent with non-PS printers. + * + * We could also use an orientation of 3 to produce output that + * comes out rightside-up (this is the default for many large format + * printer PPDs), however for consistency we will stick with the + * value 1. + * + * If we wanted to get fancy, we could use orientations of 0 or + * 2 and swap the width and length, however we don't want to get + * fancy, we just want it to work consistently. + * + * The orientation value is range limited by the Orientation + * parameter definition, so certain non-PS printer drivers that + * only support an Orientation of 0 will get the value 0 as + * expected. + */ + + orientation = 1; + + if ((attr = ppdFindAttr(ppd, "ParamCustomPageSize", + "Orientation")) != NULL) + { + int min_orient, max_orient; /* Minimum and maximum orientations */ + + + if (sscanf(attr->value, "%d%*s%d%d", &pos, &min_orient, + &max_orient) != 3) + pos = 4; + else + { + pos --; + + if (pos < 0 || pos > 4) + pos = 4; + + if (orientation > max_orient) + orientation = max_orient; + else if (orientation < min_orient) + orientation = min_orient; + } + } + else + pos = 4; + + values[pos] = (float)orientation; + + for (pos = 0; pos < 5; pos ++) + { + bufptr = _cupsStrFormatd(bufptr, bufend, values[pos], loc); + *bufptr++ = '\n'; + } + + if (!choices[i]->code) + { + /* + * 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... + */ + + strlcpy(bufptr, ppd_custom_code, bufend - bufptr + 1); + bufptr += strlen(bufptr); + } + } + else if (!strcasecmp(choices[i]->choice, "Custom") && + (coption = ppdFindCustomOption(ppd, choices[i]->option->keyword)) + != NULL) + { + /* + * Custom option... + */ + + const char *s; /* Pointer into string value */ + cups_array_t *params; /* Parameters in the correct output order */ + + + params = cupsArrayNew((cups_array_func_t)ppd_compare_cparams, NULL); + + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + cupsArrayAdd(params, cparam); + + snprintf(bufptr, bufend - bufptr + 1, + "%%%%BeginFeature: *Custom%s True\n", coption->keyword); + bufptr += strlen(bufptr); + + for (cparam = (ppd_cparam_t *)cupsArrayFirst(params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(params)) + { + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_POINTS : + case PPD_CUSTOM_REAL : + bufptr = _cupsStrFormatd(bufptr, bufend, + cparam->current.custom_real, loc); + *bufptr++ = '\n'; + break; + + case PPD_CUSTOM_INT : + snprintf(bufptr, bufend - bufptr + 1, "%d\n", + cparam->current.custom_int); + bufptr += strlen(bufptr); + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + *bufptr++ = '('; + + if (cparam->current.custom_string) + { + for (s = cparam->current.custom_string; *s; s ++) + { + if (*s < ' ' || *s == '(' || *s == ')' || *s >= 127) + { + snprintf(bufptr, bufend - bufptr + 1, "\\%03o", *s & 255); + bufptr += strlen(bufptr); + } + else + *bufptr++ = *s; + } + } + + *bufptr++ = ')'; + *bufptr++ = '\n'; + break; + } + } + + cupsArrayDelete(params); + } + else + { + snprintf(bufptr, bufend - bufptr + 1, "%%%%BeginFeature: *%s %s\n", + choices[i]->option->keyword, choices[i]->choice); + bufptr += strlen(bufptr); + } + + if (choices[i]->code && choices[i]->code[0]) + { + j = (int)strlen(choices[i]->code); + memcpy(bufptr, choices[i]->code, j); + bufptr += j; + + if (choices[i]->code[j - 1] != '\n') + *bufptr++ = '\n'; + } + + strlcpy(bufptr, "%%EndFeature\n" + "} stopped cleartomark\n", bufend - bufptr + 1); + bufptr += strlen(bufptr); + + DEBUG_printf(("2ppdEmitString: Offset in string is %d...", + (int)(bufptr - buffer))); + } + else + { + strlcpy(bufptr, choices[i]->code, bufend - bufptr + 1); + bufptr += strlen(bufptr); + } + + /* + * Nul-terminate, free, and return... + */ + + *bufptr = '\0'; + + free(choices); + + return (buffer); +} + + +/* + * 'ppd_compare_cparams()' - Compare the order of two custom parameters. + */ + +static int /* O - Result of comparison */ +ppd_compare_cparams(ppd_cparam_t *a, /* I - First parameter */ + ppd_cparam_t *b) /* I - Second parameter */ +{ + return (a->order - b->order); +} + + +/* + * 'ppd_handle_media()' - Handle media selection... + */ + +static void +ppd_handle_media(ppd_file_t *ppd) /* I - PPD file */ +{ + ppd_choice_t *manual_feed, /* ManualFeed choice, if any */ + *input_slot; /* InputSlot choice, if any */ + ppd_size_t *size; /* Current media size */ + ppd_attr_t *rpr; /* RequiresPageRegion value */ + + + /* + * This function determines what page size code to use, if any, for the + * current media size, InputSlot, and ManualFeed selections. + * + * We use the PageSize code if: + * + * 1. A custom media size is selected. + * 2. ManualFeed and InputSlot are not selected (or do not exist). + * 3. ManualFeed is selected but is False and InputSlot is not selected or + * the selection has no code - the latter check done to support "auto" or + * "printer default" InputSlot options. + * + * We use the PageRegion code if: + * + * 4. RequiresPageRegion does not exist and the PPD contains cupsFilter + * keywords, indicating this is a CUPS-based driver. + * 5. RequiresPageRegion exists for the selected InputSlot (or "All" for any + * InputSlot or ManualFeed selection) and is True. + * + * If none of the 5 conditions are true, no page size code is used and we + * unmark any existing PageSize or PageRegion choices. + */ + + if ((size = ppdPageSize(ppd, NULL)) == NULL) + return; + + manual_feed = ppdFindMarkedChoice(ppd, "ManualFeed"); + input_slot = ppdFindMarkedChoice(ppd, "InputSlot"); + + if (input_slot != NULL) + rpr = ppdFindAttr(ppd, "RequiresPageRegion", input_slot->choice); + else + rpr = NULL; + + if (!rpr) + rpr = ppdFindAttr(ppd, "RequiresPageRegion", "All"); + + if (!strcasecmp(size->name, "Custom") || + (!manual_feed && !input_slot) || + (manual_feed && !strcasecmp(manual_feed->choice, "False") && + (!input_slot || (input_slot->code && !input_slot->code[0]))) || + (!rpr && ppd->num_filters > 0)) + { + /* + * Use PageSize code... + */ + + ppdMarkOption(ppd, "PageSize", size->name); + } + else if (rpr && rpr->value && !strcasecmp(rpr->value, "True")) + { + /* + * Use PageRegion code... + */ + + ppdMarkOption(ppd, "PageRegion", size->name); + } + else + { + /* + * Do not use PageSize or PageRegion code... + */ + + ppd_choice_t *page; /* PageSize/Region choice, if any */ + + if ((page = ppdFindMarkedChoice(ppd, "PageSize")) != NULL) + { + /* + * Unmark PageSize... + */ + + page->marked = 0; + cupsArrayRemove(ppd->marked, page); + } + + if ((page = ppdFindMarkedChoice(ppd, "PageRegion")) != NULL) + { + /* + * Unmark PageRegion... + */ + + page->marked = 0; + cupsArrayRemove(ppd->marked, page); + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/cups/encode.c b/cups/encode.c new file mode 100644 index 0000000000..3848c21845 --- /dev/null +++ b/cups/encode.c @@ -0,0 +1,641 @@ +/* + * "$Id$" + * + * Option encoding routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsEncodeOptions() - Encode printer options into IPP attributes. + * cupsEncodeOptions2() - Encode printer options into IPP attributes for + * a group. + * _ippFindOption() - Find the attribute information for an option. + * compare_ipp_options() - Compare two IPP options. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include "ipp-private.h" +#include +#include +#include "string.h" +#include "debug.h" + + +/* + * Local list of option names and the value tags they should use... + * + * **** THIS LIST MUST BE SORTED **** + */ + +static const _ipp_option_t ipp_options[] = +{ + { 1, "auth-info", IPP_TAG_TEXT, IPP_TAG_JOB }, + { 1, "auth-info-required", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "blackplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "blackplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "brightness", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "brightness-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "columns", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "columns-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "compression", IPP_TAG_KEYWORD, IPP_TAG_OPERATION }, + { 0, "copies", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "copies-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "device-uri", IPP_TAG_URI, IPP_TAG_PRINTER }, + { 0, "document-format", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION }, + { 0, "document-format-default", IPP_TAG_MIMETYPE, IPP_TAG_PRINTER }, + { 1, "exclude-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION }, + { 1, "finishings", IPP_TAG_ENUM, IPP_TAG_JOB }, + { 1, "finishings-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "fit-to-page", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "fit-to-page-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "fitplot", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "fitplot-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "gamma", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "gamma-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "hue", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "hue-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "include-schemes", IPP_TAG_NAME, IPP_TAG_OPERATION }, + { 0, "job-impressions", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "job-k-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "job-page-limit", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "job-priority", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "job-quota-period", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "job-sheets", IPP_TAG_NAME, IPP_TAG_JOB }, + { 1, "job-sheets-default", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 0, "job-uuid", IPP_TAG_URI, IPP_TAG_JOB }, + { 0, "landscape", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 1, "marker-change-time", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "marker-colors", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 1, "marker-high-levels", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "marker-levels", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "marker-low-levels", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "marker-message", IPP_TAG_TEXT, IPP_TAG_PRINTER }, + { 1, "marker-names", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 1, "marker-types", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 1, "media", IPP_TAG_KEYWORD, IPP_TAG_JOB }, + { 0, "media-col", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_JOB }, + { 0, "media-col-default", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_PRINTER }, + { 0, "media-color", IPP_TAG_KEYWORD, IPP_TAG_JOB }, + { 1, "media-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "media-key", IPP_TAG_KEYWORD, IPP_TAG_JOB }, + { 0, "media-size", IPP_TAG_BEGIN_COLLECTION, IPP_TAG_JOB }, + { 0, "media-type", IPP_TAG_KEYWORD, IPP_TAG_JOB }, + { 0, "mirror", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "mirror-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "natural-scaling", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "natural-scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "notify-charset", IPP_TAG_CHARSET, IPP_TAG_SUBSCRIPTION }, + { 1, "notify-events", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION }, + { 1, "notify-events-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "notify-lease-duration", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION }, + { 0, "notify-lease-duration-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "notify-natural-language", IPP_TAG_LANGUAGE, IPP_TAG_SUBSCRIPTION }, + { 0, "notify-pull-method", IPP_TAG_KEYWORD, IPP_TAG_SUBSCRIPTION }, + { 0, "notify-recipient-uri", IPP_TAG_URI, IPP_TAG_SUBSCRIPTION }, + { 0, "notify-time-interval", IPP_TAG_INTEGER, IPP_TAG_SUBSCRIPTION }, + { 0, "notify-user-data", IPP_TAG_STRING, IPP_TAG_SUBSCRIPTION }, + { 0, "number-up", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "number-up-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "orientation-requested", IPP_TAG_ENUM, IPP_TAG_JOB }, + { 0, "orientation-requested-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "page-bottom", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "page-bottom-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "page-left", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "page-left-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "page-ranges", IPP_TAG_RANGE, IPP_TAG_JOB }, + { 1, "page-ranges-default", IPP_TAG_RANGE, IPP_TAG_PRINTER }, + { 0, "page-right", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "page-right-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "page-top", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "page-top-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "penwidth", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "penwidth-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "port-monitor", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 0, "ppd-name", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 0, "ppi", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "ppi-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "prettyprint", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "prettyprint-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "print-quality", IPP_TAG_ENUM, IPP_TAG_JOB }, + { 0, "print-quality-default", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 1, "printer-commands", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "printer-error-policy", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 0, "printer-info", IPP_TAG_TEXT, IPP_TAG_PRINTER }, + { 0, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "printer-is-shared", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "printer-location", IPP_TAG_TEXT, IPP_TAG_PRINTER }, + { 0, "printer-make-and-model", IPP_TAG_TEXT, IPP_TAG_PRINTER }, + { 0, "printer-more-info", IPP_TAG_URI, IPP_TAG_PRINTER }, + { 0, "printer-op-policy", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 0, "printer-resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB }, + { 0, "printer-state", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "printer-state-change-time", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 1, "printer-state-reasons", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "printer-type", IPP_TAG_ENUM, IPP_TAG_PRINTER }, + { 0, "printer-uri", IPP_TAG_URI, IPP_TAG_OPERATION }, + { 1, "printer-uri-supported", IPP_TAG_URI, IPP_TAG_PRINTER }, + { 0, "queued-job-count", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "raw", IPP_TAG_MIMETYPE, IPP_TAG_OPERATION }, + { 1, "requested-attributes", IPP_TAG_NAME, IPP_TAG_OPERATION }, + { 1, "requesting-user-name-allowed", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 1, "requesting-user-name-denied", IPP_TAG_NAME, IPP_TAG_PRINTER }, + { 0, "resolution", IPP_TAG_RESOLUTION, IPP_TAG_JOB }, + { 0, "resolution-default", IPP_TAG_RESOLUTION, IPP_TAG_PRINTER }, + { 0, "saturation", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "saturation-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "scaling", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "scaling-default", IPP_TAG_INTEGER, IPP_TAG_PRINTER }, + { 0, "sides", IPP_TAG_KEYWORD, IPP_TAG_JOB }, + { 0, "sides-default", IPP_TAG_KEYWORD, IPP_TAG_PRINTER }, + { 0, "wrap", IPP_TAG_BOOLEAN, IPP_TAG_JOB }, + { 0, "wrap-default", IPP_TAG_BOOLEAN, IPP_TAG_PRINTER }, + { 0, "x-dimension", IPP_TAG_INTEGER, IPP_TAG_JOB }, + { 0, "y-dimension", IPP_TAG_INTEGER, IPP_TAG_JOB } +}; + + +/* + * Local functions... + */ + +static int compare_ipp_options(_ipp_option_t *a, _ipp_option_t *b); + + +/* + * 'cupsEncodeOptions()' - Encode printer options into IPP attributes. + * + * This function adds operation, job, and then subscription attributes, + * in that order. Use the cupsEncodeOptions2() function to add attributes + * for a single group. + */ + +void +cupsEncodeOptions(ipp_t *ipp, /* I - Request to add to */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + DEBUG_printf(("cupsEncodeOptions(%p, %d, %p)", ipp, num_options, options)); + + /* + * Add the options in the proper groups & order... + */ + + cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_OPERATION); + cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_JOB); + cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_SUBSCRIPTION); +} + + +/* + * 'cupsEncodeOptions2()' - Encode printer options into IPP attributes for a group. + * + * This function only adds attributes for a single group. Call this + * function multiple times for each group, or use cupsEncodeOptions() + * to add the standard groups. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +cupsEncodeOptions2( + ipp_t *ipp, /* I - Request to add to */ + int num_options, /* I - Number of options */ + cups_option_t *options, /* I - Options */ + ipp_tag_t group_tag) /* I - Group to encode */ +{ + 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 */ + quote; /* Quote character */ + ipp_attribute_t *attr; /* IPP attribute */ + ipp_tag_t value_tag; /* IPP value tag */ + cups_option_t *option; /* Current option */ + ipp_t *collection; /* Collection value */ + int num_cols; /* Number of collection values */ + cups_option_t *cols; /* Collection values */ + + + DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, " + "group_tag=%x)", ipp, num_options, options, group_tag)); + + /* + * Range check input... + */ + + if (!ipp || num_options < 1 || !options) + return; + + /* + * Do special handling for the document-format/raw options... + */ + + if (group_tag == IPP_TAG_OPERATION) + { + /* + * 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 loop through the options... + */ + + for (i = num_options, option = options; i > 0; i --, option ++) + { + _ipp_option_t *match; /* Matching attribute */ + + + /* + * Skip document format options that are handled above... + */ + + if (!strcasecmp(option->name, "raw") || + !strcasecmp(option->name, "document-format") || + !option->name[0]) + continue; + + /* + * Figure out the proper value and group tags for this option... + */ + + if ((match = _ippFindOption(option->name)) != NULL) + { + if (match->group_tag != group_tag) + continue; + + value_tag = match->value_tag; + } + else + { + int namelen; /* Length of name */ + + + namelen = (int)strlen(option->name); + + if (namelen < 9 || strcmp(option->name + namelen - 8, "-default")) + { + if (group_tag != IPP_TAG_JOB) + continue; + } + else if (group_tag != IPP_TAG_PRINTER) + continue; + + if (!strcasecmp(option->value, "true") || + !strcasecmp(option->value, "false")) + value_tag = IPP_TAG_BOOLEAN; + else + value_tag = IPP_TAG_NAME; + } + + /* + * Count the number of values... + */ + + if (match && match->multivalue) + { + for (count = 1, sep = option->value, quote = 0; *sep; sep ++) + { + if (*sep == quote) + quote = 0; + else if (!quote && (*sep == '\'' || *sep == '\"')) + { + /* + * Skip quoted option value... + */ + + quote = *sep++; + } + else if (*sep == ',' && !quote) + count ++; + else if (*sep == '\\' && sep[1]) + sep ++; + } + } + else + count = 1; + + DEBUG_printf(("2cupsEncodeOptions2: option=\"%s\", count=%d", + option->name, count)); + + /* + * Allocate memory for the attribute values... + */ + + if ((attr = _ippAddAttr(ipp, count)) == NULL) + { + /* + * Ran out of memory! + */ + + DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for attributes!"); + return; + } + + /* + * Now figure out what type of value we have... + */ + + attr->group_tag = group_tag; + attr->value_tag = value_tag; + + /* + * Copy the name over... + */ + + attr->name = _cupsStrAlloc(option->name); + + if (count > 1) + { + /* + * Make a copy of the value we can fiddle with... + */ + + if ((copy = strdup(option->value)) == NULL) + { + /* + * Ran out of memory! + */ + + DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for value copy!"); + ippDeleteAttribute(ipp, attr); + return; + } + + val = copy; + } + else + { + /* + * Since we have a single value, use the value directly... + */ + + val = option->value; + copy = NULL; + } + + /* + * Scan the value string for values... + */ + + for (j = 0, sep = val; j < count; val = sep, j ++) + { + /* + * Find the end of this value and mark it if needed... + */ + + if (count > 1) + { + for (quote = 0; *sep; sep ++) + { + if (*sep == quote) + { + /* + * Finish quoted value... + */ + + quote = 0; + } + else if (!quote && (*sep == '\'' || *sep == '\"')) + { + /* + * Handle quoted option value... + */ + + quote = *sep; + } + else if (*sep == ',' && count > 1) + break; + else if (*sep == '\\' && sep[1]) + { + /* + * Skip quoted character... + */ + + sep ++; + } + } + + if (*sep == ',') + *sep++ = '\0'; + } + + /* + * 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, 10); + + DEBUG_printf(("2cupsEncodeOptions2: Added integer option value " + "%d...", attr->values[j].integer)); + break; + + case IPP_TAG_BOOLEAN : + if (!strcasecmp(val, "true") || + !strcasecmp(val, "on") || + !strcasecmp(val, "yes")) + { + /* + * Boolean value - true... + */ + + attr->values[j].boolean = 1; + + DEBUG_puts("2cupsEncodeOptions2: Added boolean true value..."); + } + else + { + /* + * Boolean value - false... + */ + + attr->values[j].boolean = 0; + + DEBUG_puts("2cupsEncodeOptions2: 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, 10); + + if (*s == '-') + { + if (s[1]) + attr->values[j].range.upper = strtol(s + 1, NULL, 10); + else + attr->values[j].range.upper = 2147483647; + } + else + attr->values[j].range.upper = attr->values[j].range.lower; + + DEBUG_printf(("2cupsEncodeOptions2: Added range option value " + "%d-%d...", attr->values[j].range.lower, + attr->values[j].range.upper)); + break; + + case IPP_TAG_RESOLUTION : + /* + * Resolution... + */ + + attr->values[j].resolution.xres = strtol(val, &s, 10); + + if (*s == 'x') + attr->values[j].resolution.yres = strtol(s + 1, &s, 10); + else + attr->values[j].resolution.yres = attr->values[j].resolution.xres; + + if (!strcasecmp(s, "dpc")) + attr->values[j].resolution.units = IPP_RES_PER_CM; + else + attr->values[j].resolution.units = IPP_RES_PER_INCH; + + DEBUG_printf(("2cupsEncodeOptions2: Added resolution option value " + "%s...", val)); + break; + + case IPP_TAG_STRING : + /* + * octet-string + */ + + attr->values[j].unknown.length = (int)strlen(val); + attr->values[j].unknown.data = strdup(val); + + DEBUG_printf(("2cupsEncodeOptions2: Added octet-string value " + "\"%s\"...", (char *)attr->values[j].unknown.data)); + break; + + case IPP_TAG_BEGIN_COLLECTION : + /* + * Collection value + */ + + num_cols = cupsParseOptions(val, 0, &cols); + if ((collection = ippNew()) == NULL) + { + cupsFreeOptions(num_cols, cols); + + if (copy) + free(copy); + + ippDeleteAttribute(ipp, attr); + return; + } + + attr->values[j].collection = collection; + cupsEncodeOptions2(collection, num_cols, cols, IPP_TAG_JOB); + cupsFreeOptions(num_cols, cols); + break; + + default : + if ((attr->values[j].string.text = _cupsStrAlloc(val)) == NULL) + { + /* + * Ran out of memory! + */ + + DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for string!"); + + if (copy) + free(copy); + + ippDeleteAttribute(ipp, attr); + return; + } + + DEBUG_printf(("2cupsEncodeOptions2: Added string value \"%s\"...", + val)); + break; + } + } + + if (copy) + free(copy); + } +} + + +/* + * '_ippFindOption()' - Find the attribute information for an option. + */ + +_ipp_option_t * /* O - Attribute information */ +_ippFindOption(const char *name) /* I - Option/attribute name */ +{ + _ipp_option_t key; /* Search key */ + + + /* + * Lookup the proper value and group tags for this option... + */ + + key.name = name; + + return ((_ipp_option_t *)bsearch(&key, ipp_options, + sizeof(ipp_options) / sizeof(ipp_options[0]), + sizeof(ipp_options[0]), + (int (*)(const void *, const void *)) + compare_ipp_options)); +} + + +/* + * 'compare_ipp_options()' - Compare two IPP options. + */ + +static int /* O - Result of comparison */ +compare_ipp_options(_ipp_option_t *a, /* I - First option */ + _ipp_option_t *b) /* I - Second option */ +{ + return (strcmp(a->name, b->name)); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/file-private.h b/cups/file-private.h new file mode 100644 index 0000000000..978428d393 --- /dev/null +++ b/cups/file-private.h @@ -0,0 +1,98 @@ +/* + * "$Id$" + * + * Private file definitions for the Common UNIX Printing System (CUPS). + * + * Since stdio files max out at 256 files on many systems, we have to + * write similar functions without this limit. At the same time, using + * our own file functions allows us to provide transparent support of + * gzip'd print files, PPD files, etc. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_FILE_PRIVATE_H_ +# define _CUPS_FILE_PRIVATE_H_ + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include +# include +# include "http-private.h" +# include "globals.h" +# include "debug.h" + +# ifdef HAVE_LIBZ +# include +# endif /* HAVE_LIBZ */ +# ifdef WIN32 +# include +# include +# endif /* WIN32 */ + + +/* + * Some operating systems support large files via open flag O_LARGEFILE... + */ + +# ifndef O_LARGEFILE +# define O_LARGEFILE 0 +# endif /* !O_LARGEFILE */ + + +/* + * Some operating systems don't define O_BINARY, which is used by Microsoft + * and IBM to flag binary files... + */ + +# ifndef O_BINARY +# define O_BINARY 0 +# endif /* !O_BINARY */ + + +/* + * Types and structures... + */ + +struct _cups_file_s /**** CUPS file structure... ****/ + +{ + int fd; /* File descriptor */ + char mode, /* Mode ('r' or 'w') */ + compressed, /* Compression used? */ + is_stdio, /* stdin/out/err? */ + eof, /* End of file? */ + buf[4096], /* Buffer */ + *ptr, /* Pointer into buffer */ + *end; /* End of buffer data */ + off_t pos, /* Position in file */ + bufpos; /* File position for start of buffer */ + +#ifdef HAVE_LIBZ + z_stream stream; /* (De)compression stream */ + Bytef cbuf[4096]; /* (De)compression buffer */ + uLong crc; /* (De)compression CRC */ +#endif /* HAVE_LIBZ */ + + char *printf_buffer; /* cupsFilePrintf buffer */ + size_t printf_size; /* Size of cupsFilePrintf buffer */ +}; + + +#endif /* !_CUPS_FILE_PRIVATE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/file.c b/cups/file.c new file mode 100644 index 0000000000..6828351285 --- /dev/null +++ b/cups/file.c @@ -0,0 +1,2441 @@ +/* + * "$Id$" + * + * File functions for the Common UNIX Printing System (CUPS). + * + * Since stdio files max out at 256 files on many systems, we have to + * write similar functions without this limit. At the same time, using + * our own file functions allows us to provide transparent support of + * gzip'd print files, PPD files, etc. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsFileClose() - Close a CUPS file. + * cupsFileCompression() - Return whether a file is compressed. + * cupsFileEOF() - Return the end-of-file status. + * cupsFileFind() - Find a file using the specified path. + * cupsFileFlush() - Flush pending output. + * cupsFileGetChar() - Get a single character from a file. + * cupsFileGetConf() - Get a line from a configuration file... + * cupsFileGetLine() - Get a CR and/or LF-terminated line that may contain + * binary data. + * cupsFileGets() - Get a CR and/or LF-terminated line. + * cupsFileLock() - Temporarily lock access to a file. + * cupsFileNumber() - Return the file descriptor associated with a CUPS + * file. + * cupsFileOpen() - Open a CUPS file. + * cupsFileOpenFd() - Open a CUPS file using a file descriptor. + * cupsFilePeekChar() - Peek at the next character from a file. + * cupsFilePrintf() - Write a formatted string. + * cupsFilePutChar() - Write a character. + * cupsFilePuts() - Write a string. + * cupsFileRead() - Read from a file. + * cupsFileRewind() - Set the current file position to the beginning of + * the file. + * cupsFileSeek() - Seek in a file. + * cupsFileStderr() - Return a CUPS file associated with stderr. + * cupsFileStdin() - Return a CUPS file associated with stdin. + * cupsFileStdout() - Return a CUPS file associated with stdout. + * cupsFileTell() - Return the current file position. + * cupsFileUnlock() - Unlock access to a file. + * cupsFileWrite() - Write to a file. + * cups_compress() - Compress a buffer of data... + * cups_fill() - Fill the input buffer... + * cups_read() - Read from a file descriptor. + * cups_write() - Write to a file descriptor. + */ + +/* + * Include necessary headers... + */ + +#include "file-private.h" +#include +#include + + +/* + * Local functions... + */ + +#ifdef HAVE_LIBZ +static ssize_t cups_compress(cups_file_t *fp, const char *buf, size_t bytes); +#endif /* HAVE_LIBZ */ +static ssize_t cups_fill(cups_file_t *fp); +static int cups_open(const char *filename, int mode); +static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes); +static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes); + + +/* + * 'cupsFileClose()' - Close a CUPS file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsFileClose(cups_file_t *fp) /* I - CUPS file */ +{ + int fd; /* File descriptor */ + char mode; /* Open mode */ + int status; /* Return status */ + int is_stdio; /* Is a stdio file? */ + + + DEBUG_printf(("cupsFileClose(fp=%p)", fp)); + + /* + * Range check... + */ + + if (!fp) + return (-1); + + /* + * Flush pending write data... + */ + + if (fp->mode == 'w') + status = cupsFileFlush(fp); + else + status = 0; + +#ifdef HAVE_LIBZ + if (fp->compressed && status >= 0) + { + if (fp->mode == 'r') + { + /* + * Free decompression data... + */ + + inflateEnd(&fp->stream); + } + else + { + /* + * Flush any remaining compressed data... + */ + + unsigned char trailer[8]; /* Trailer CRC and length */ + int done; /* Done writing... */ + + + fp->stream.avail_in = 0; + + for (done = 0;;) + { + if (fp->stream.next_out > fp->cbuf) + { + if (cups_write(fp, (char *)fp->cbuf, + fp->stream.next_out - fp->cbuf) < 0) + status = -1; + + fp->stream.next_out = fp->cbuf; + fp->stream.avail_out = sizeof(fp->cbuf); + } + + if (done || status < 0) + break; + + done = deflate(&fp->stream, Z_FINISH) == Z_STREAM_END && + fp->stream.next_out == fp->cbuf; + } + + /* + * Write the CRC and length... + */ + + trailer[0] = fp->crc; + trailer[1] = fp->crc >> 8; + trailer[2] = fp->crc >> 16; + trailer[3] = fp->crc >> 24; + trailer[4] = fp->pos; + trailer[5] = fp->pos >> 8; + trailer[6] = fp->pos >> 16; + trailer[7] = fp->pos >> 24; + + if (cups_write(fp, (char *)trailer, 8) < 0) + status = -1; + + /* + * Free all memory used by the compression stream... + */ + + deflateEnd(&(fp->stream)); + } + } +#endif /* HAVE_LIBZ */ + + /* + * Save the file descriptor we used and free memory... + */ + + fd = fp->fd; + mode = fp->mode; + is_stdio = fp->is_stdio; + + if (fp->printf_buffer) + free(fp->printf_buffer); + + free(fp); + + /* + * Close the file, returning the close status... + */ + + if (mode == 's') + { + if (closesocket(fd) < 0) + status = -1; + } + else if (!is_stdio) + { + if (close(fd) < 0) + status = -1; + } + + return (status); +} + + +/* + * 'cupsFileCompression()' - Return whether a file is compressed. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - @code CUPS_FILE_NONE@ or @code CUPS_FILE_GZIP@ */ +cupsFileCompression(cups_file_t *fp) /* I - CUPS file */ +{ + return (fp ? fp->compressed : CUPS_FILE_NONE); +} + + +/* + * 'cupsFileEOF()' - Return the end-of-file status. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 on end of file, 0 otherwise */ +cupsFileEOF(cups_file_t *fp) /* I - CUPS file */ +{ + return (fp ? fp->eof : 1); +} + + +/* + * 'cupsFileFind()' - Find a file using the specified path. + * + * This function allows the paths in the path string to be separated by + * colons (UNIX standard) or semicolons (Windows standard) and stores the + * result in the buffer supplied. If the file cannot be found in any of + * the supplied paths, @code NULL@ is returned. A @code NULL@ path only + * matches the current directory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +const char * /* O - Full path to file or @code NULL@ if not found */ +cupsFileFind(const char *filename, /* I - File to find */ + const char *path, /* I - Colon/semicolon-separated path */ + int executable, /* I - 1 = executable files, 0 = any file/dir */ + char *buffer, /* I - Filename buffer */ + int bufsize) /* I - Size of filename buffer */ +{ + char *bufptr, /* Current position in buffer */ + *bufend; /* End of buffer */ + + + /* + * Range check input... + */ + + DEBUG_printf(("cupsFileFind(filename=\"%s\", path=\"%s\", executable=%d, " + "buffer=%p, bufsize=%d)", filename, path, executable, buffer, + bufsize)); + + if (!filename || !buffer || bufsize < 2) + return (NULL); + + if (!path) + { + /* + * No path, so check current directory... + */ + + if (!access(filename, 0)) + { + strlcpy(buffer, filename, bufsize); + return (buffer); + } + else + return (NULL); + } + + /* + * Now check each path and return the first match... + */ + + bufend = buffer + bufsize - 1; + bufptr = buffer; + + while (*path) + { +#ifdef WIN32 + if (*path == ';' || (*path == ':' && ((bufptr - buffer) > 1 || !isalpha(buffer[0] & 255)))) +#else + if (*path == ';' || *path == ':') +#endif /* WIN32 */ + { + if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend) + *bufptr++ = '/'; + + strlcpy(bufptr, filename, bufend - bufptr); + +#ifdef WIN32 + if (!access(buffer, 0)) +#else + if (!access(buffer, executable ? X_OK : 0)) +#endif /* WIN32 */ + { + DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer)); + return (buffer); + } + + bufptr = buffer; + } + else if (bufptr < bufend) + *bufptr++ = *path; + + path ++; + } + + /* + * Check the last path... + */ + + if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend) + *bufptr++ = '/'; + + strlcpy(bufptr, filename, bufend - bufptr); + + if (!access(buffer, 0)) + { + DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer)); + return (buffer); + } + else + { + DEBUG_puts("1cupsFileFind: Returning NULL"); + return (NULL); + } +} + + +/* + * 'cupsFileFlush()' - Flush pending output. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsFileFlush(cups_file_t *fp) /* I - CUPS file */ +{ + ssize_t bytes; /* Bytes to write */ + + + DEBUG_printf(("cupsFileFlush(fp=%p)", fp)); + + /* + * Range check input... + */ + + if (!fp || fp->mode != 'w') + { + DEBUG_puts("1cupsFileFlush: Attempt to flush a read-only file..."); + return (-1); + } + + bytes = (ssize_t)(fp->ptr - fp->buf); + + DEBUG_printf(("2cupsFileFlush: Flushing " CUPS_LLFMT " bytes...", + CUPS_LLCAST bytes)); + + if (bytes > 0) + { +#ifdef HAVE_LIBZ + if (fp->compressed) + bytes = cups_compress(fp, fp->buf, bytes); + else +#endif /* HAVE_LIBZ */ + bytes = cups_write(fp, fp->buf, bytes); + + if (bytes < 0) + return (-1); + + fp->ptr = fp->buf; + } + + return (0); +} + + +/* + * 'cupsFileGetChar()' - Get a single character from a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Character or -1 on end of file */ +cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */ +{ + /* + * Range check input... + */ + + if (!fp || (fp->mode != 'r' && fp->mode != 's')) + { + DEBUG_puts("3cupsFileGetChar: Bad arguments!"); + return (-1); + } + + /* + * If the input buffer is empty, try to read more data... + */ + + if (fp->ptr >= fp->end) + if (cups_fill(fp) < 0) + { + DEBUG_puts("3cupsFileGetChar: Unable to fill buffer!"); + return (-1); + } + + /* + * Return the next character in the buffer... + */ + + DEBUG_printf(("3cupsFileGetChar: Returning %d...", *(fp->ptr) & 255)); + + fp->pos ++; + + DEBUG_printf(("4cupsFileGetChar: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (*(fp->ptr)++ & 255); +} + + +/* + * 'cupsFileGetConf()' - Get a line from a configuration file... + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Line read or @code NULL@ on end of file or error */ +cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */ + char *buf, /* O - String buffer */ + size_t buflen, /* I - Size of string buffer */ + char **value, /* O - Pointer to value */ + int *linenum) /* IO - Current line number */ +{ + char *ptr; /* Pointer into line */ + + + /* + * Range check input... + */ + + DEBUG_printf(("2cupsFileGetConf(fp=%p, buf=%p, buflen=" CUPS_LLFMT + ", value=%p, linenum=%p)", fp, buf, CUPS_LLCAST buflen, + value, linenum)); + + if (!fp || (fp->mode != 'r' && fp->mode != 's') || + !buf || buflen < 2 || !value) + { + if (value) + *value = NULL; + + return (NULL); + } + + /* + * Read the next non-comment line... + */ + + *value = NULL; + + while (cupsFileGets(fp, buf, buflen)) + { + (*linenum) ++; + + /* + * Strip any comments... + */ + + if ((ptr = strchr(buf, '#')) != NULL) + { + if (ptr > buf && ptr[-1] == '\\') + { + // Unquote the #... + _cups_strcpy(ptr - 1, ptr); + } + else + { + // Strip the comment and any trailing whitespace... + while (ptr > buf) + { + if (!_cups_isspace(ptr[-1])) + break; + + ptr --; + } + + *ptr = '\0'; + } + } + + /* + * Strip leading whitespace... + */ + + for (ptr = buf; _cups_isspace(*ptr); ptr ++); + + if (ptr > buf) + _cups_strcpy(buf, ptr); + + /* + * See if there is anything left... + */ + + if (buf[0]) + { + /* + * Yes, grab any value and return... + */ + + for (ptr = buf; *ptr; ptr ++) + if (_cups_isspace(*ptr)) + break; + + if (*ptr) + { + /* + * Have a value, skip any other spaces... + */ + + while (_cups_isspace(*ptr)) + *ptr++ = '\0'; + + if (*ptr) + *value = ptr; + + /* + * Strip trailing whitespace and > for lines that begin with <... + */ + + ptr += strlen(ptr) - 1; + + if (buf[0] == '<' && *ptr == '>') + *ptr-- = '\0'; + else if (buf[0] == '<' && *ptr != '>') + { + /* + * Syntax error... + */ + + *value = NULL; + return (buf); + } + + while (ptr > *value && _cups_isspace(*ptr)) + *ptr-- = '\0'; + } + + /* + * Return the line... + */ + + return (buf); + } + } + + return (NULL); +} + + +/* + * 'cupsFileGetLine()' - Get a CR and/or LF-terminated line that may + * contain binary data. + * + * This function differs from @link cupsFileGets@ in that the trailing CR + * and LF are preserved, as is any binary data on the line. The buffer is + * nul-terminated, however you should use the returned length to determine + * the number of bytes on the line. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +size_t /* O - Number of bytes on line or 0 on end of file */ +cupsFileGetLine(cups_file_t *fp, /* I - File to read from */ + char *buf, /* I - Buffer */ + size_t buflen) /* I - Size of buffer */ +{ + int ch; /* Character from file */ + char *ptr, /* Current position in line buffer */ + *end; /* End of line buffer */ + + + /* + * Range check input... + */ + + DEBUG_printf(("2cupsFileGetLine(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")", + fp, buf, CUPS_LLCAST buflen)); + + if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 3) + return (0); + + /* + * Now loop until we have a valid line... + */ + + for (ptr = buf, end = buf + buflen - 2; ptr < end ;) + { + if (fp->ptr >= fp->end) + if (cups_fill(fp) <= 0) + break; + + *ptr++ = ch = *(fp->ptr)++; + fp->pos ++; + + if (ch == '\r') + { + /* + * Check for CR LF... + */ + + if (fp->ptr >= fp->end) + if (cups_fill(fp) <= 0) + break; + + if (*(fp->ptr) == '\n') + { + *ptr++ = *(fp->ptr)++; + fp->pos ++; + } + + break; + } + else if (ch == '\n') + { + /* + * Line feed ends a line... + */ + + break; + } + } + + *ptr = '\0'; + + DEBUG_printf(("4cupsFileGetLine: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (ptr - buf); +} + + +/* + * 'cupsFileGets()' - Get a CR and/or LF-terminated line. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Line read or @code NULL@ on end of file or error */ +cupsFileGets(cups_file_t *fp, /* I - CUPS file */ + char *buf, /* O - String buffer */ + size_t buflen) /* I - Size of string buffer */ +{ + int ch; /* Character from file */ + char *ptr, /* Current position in line buffer */ + *end; /* End of line buffer */ + + + /* + * Range check input... + */ + + DEBUG_printf(("2cupsFileGets(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")", fp, buf, + CUPS_LLCAST buflen)); + + if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 2) + return (NULL); + + /* + * Now loop until we have a valid line... + */ + + for (ptr = buf, end = buf + buflen - 1; ptr < end ;) + { + if (fp->ptr >= fp->end) + if (cups_fill(fp) <= 0) + { + if (ptr == buf) + return (NULL); + else + break; + } + + ch = *(fp->ptr)++; + fp->pos ++; + + if (ch == '\r') + { + /* + * Check for CR LF... + */ + + if (fp->ptr >= fp->end) + if (cups_fill(fp) <= 0) + break; + + if (*(fp->ptr) == '\n') + { + fp->ptr ++; + fp->pos ++; + } + + break; + } + else if (ch == '\n') + { + /* + * Line feed ends a line... + */ + + break; + } + else + *ptr++ = ch; + } + + *ptr = '\0'; + + DEBUG_printf(("4cupsFileGets: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (buf); +} + + +/* + * 'cupsFileLock()' - Temporarily lock access to a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsFileLock(cups_file_t *fp, /* I - CUPS file */ + int block) /* I - 1 to wait for the lock, 0 to fail right away */ +{ + /* + * Range check... + */ + + if (!fp || fp->mode == 's') + return (-1); + + /* + * Try the lock... + */ + +#ifdef WIN32 + return (_locking(fp->fd, block ? _LK_LOCK : _LK_NBLCK, 0)); +#else + return (lockf(fp->fd, block ? F_LOCK : F_TLOCK, 0)); +#endif /* WIN32 */ +} + + +/* + * 'cupsFileNumber()' - Return the file descriptor associated with a CUPS file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - File descriptor */ +cupsFileNumber(cups_file_t *fp) /* I - CUPS file */ +{ + if (fp) + return (fp->fd); + else + return (-1); +} + + +/* + * 'cupsFileOpen()' - Open a CUPS file. + * + * The "mode" parameter can be "r" to read, "w" to write, overwriting any + * existing file, "a" to append to an existing file or create a new file, + * or "s" to open a socket connection. + * + * When opening for writing ("w"), an optional number from 1 to 9 can be + * supplied which enables Flate compression of the file. Compression is + * not supported for the "a" (append) mode. + * + * When opening a socket connection, the filename is a string of the form + * "address:port" or "hostname:port". The socket will make an IPv4 or IPv6 + * connection as needed, generally preferring IPv6 connections when there is + * a choice. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_file_t * /* O - CUPS file or @code NULL@ if the file or socket cannot be opened */ +cupsFileOpen(const char *filename, /* I - Name of file */ + const char *mode) /* I - Open mode */ +{ + cups_file_t *fp; /* New CUPS file */ + int fd; /* File descriptor */ + char hostname[1024], /* Hostname */ + *portname; /* Port "name" (number or service) */ + http_addrlist_t *addrlist; /* Host address list */ + + + DEBUG_printf(("cupsFileOpen(filename=\"%s\", mode=\"%s\")", filename, + mode)); + + /* + * Range check input... + */ + + if (!filename || !mode || + (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's') || + (*mode == 'a' && isdigit(mode[1] & 255))) + return (NULL); + + /* + * Open the file... + */ + + switch (*mode) + { + case 'a' : /* Append file */ + fd = cups_open(filename, + O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE | O_BINARY); + break; + + case 'r' : /* Read file */ + fd = open(filename, O_RDONLY | O_LARGEFILE | O_BINARY, 0); + break; + + case 'w' : /* Write file */ + fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY); + if (fd < 0 && errno == ENOENT) + { + fd = cups_open(filename, + O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE | O_BINARY); + if (fd < 0 && errno == EEXIST) + fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY); + } + + if (fd >= 0) +#ifdef WIN32 + _chsize(fd, 0); +#else + ftruncate(fd, 0); +#endif /* WIN32 */ + break; + + case 's' : /* Read/write socket */ + strlcpy(hostname, filename, sizeof(hostname)); + if ((portname = strrchr(hostname, ':')) != NULL) + *portname++ = '\0'; + else + return (NULL); + + /* + * Lookup the hostname and service... + */ + + if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) + return (NULL); + + /* + * Connect to the server... + */ + + if (!httpAddrConnect(addrlist, &fd)) + { + httpAddrFreeList(addrlist); + return (NULL); + } + + httpAddrFreeList(addrlist); + break; + + default : /* Remove bogus compiler warning... */ + return (NULL); + } + + if (fd < 0) + return (NULL); + + /* + * Create the CUPS file structure... + */ + + if ((fp = cupsFileOpenFd(fd, mode)) == NULL) + { + if (*mode == 's') + closesocket(fd); + else + close(fd); + } + + /* + * Return it... + */ + + return (fp); +} + +/* + * 'cupsFileOpenFd()' - Open a CUPS file using a file descriptor. + * + * The "mode" parameter can be "r" to read, "w" to write, "a" to append, + * or "s" to treat the file descriptor as a bidirectional socket connection. + * + * When opening for writing ("w"), an optional number from 1 to 9 can be + * supplied which enables Flate compression of the file. Compression is + * not supported for the "a" (append) mode. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_file_t * /* O - CUPS file or @code NULL@ if the file could not be opened */ +cupsFileOpenFd(int fd, /* I - File descriptor */ + const char *mode) /* I - Open mode */ +{ + cups_file_t *fp; /* New CUPS file */ + + + DEBUG_printf(("cupsFileOpenFd(fd=%d, mode=\"%s\")", fd, mode)); + + /* + * Range check input... + */ + + if (fd < 0 || !mode || + (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's') || + (*mode == 'a' && isdigit(mode[1] & 255))) + return (NULL); + + /* + * Allocate memory... + */ + + if ((fp = calloc(1, sizeof(cups_file_t))) == NULL) + return (NULL); + + /* + * Open the file... + */ + + fp->fd = fd; + + switch (*mode) + { + case 'a' : + fp->pos = lseek(fd, 0, SEEK_END); + + case 'w' : + fp->mode = 'w'; + fp->ptr = fp->buf; + fp->end = fp->buf + sizeof(fp->buf); + +#ifdef HAVE_LIBZ + if (mode[1] >= '1' && mode[1] <= '9') + { + /* + * Open a compressed stream, so write the standard gzip file + * header... + */ + + unsigned char header[10]; /* gzip file header */ + time_t curtime; /* Current time */ + + + curtime = time(NULL); + header[0] = 0x1f; + header[1] = 0x8b; + header[2] = Z_DEFLATED; + header[3] = 0; + header[4] = curtime; + header[5] = curtime >> 8; + header[6] = curtime >> 16; + header[7] = curtime >> 24; + header[8] = 0; + header[9] = 0x03; + + cups_write(fp, (char *)header, 10); + + /* + * Initialize the compressor... + */ + + deflateInit2(&(fp->stream), mode[1] - '0', Z_DEFLATED, -15, 8, + Z_DEFAULT_STRATEGY); + + fp->stream.next_out = fp->cbuf; + fp->stream.avail_out = sizeof(fp->cbuf); + fp->compressed = 1; + fp->crc = crc32(0L, Z_NULL, 0); + } +#endif /* HAVE_LIBZ */ + break; + + case 'r' : + fp->mode = 'r'; + break; + + case 's' : + fp->mode = 's'; + break; + + default : /* Remove bogus compiler warning... */ + return (NULL); + } + + /* + * Don't pass this file to child processes... + */ + +#ifndef WIN32 + fcntl(fp->fd, F_SETFD, fcntl(fp->fd, F_GETFD) | FD_CLOEXEC); +#endif /* !WIN32 */ + + return (fp); +} + + +/* + * 'cupsFilePeekChar()' - Peek at the next character from a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Character or -1 on end of file */ +cupsFilePeekChar(cups_file_t *fp) /* I - CUPS file */ +{ + /* + * Range check input... + */ + + if (!fp || (fp->mode != 'r' && fp->mode != 's')) + return (-1); + + /* + * If the input buffer is empty, try to read more data... + */ + + if (fp->ptr >= fp->end) + if (cups_fill(fp) < 0) + return (-1); + + /* + * Return the next character in the buffer... + */ + + return (*(fp->ptr) & 255); +} + + +/* + * 'cupsFilePrintf()' - Write a formatted string. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Number of bytes written or -1 on error */ +cupsFilePrintf(cups_file_t *fp, /* I - CUPS file */ + const char *format, /* I - Printf-style format string */ + ...) /* I - Additional args as necessary */ +{ + va_list ap; /* Argument list */ + ssize_t bytes; /* Formatted size */ + + + DEBUG_printf(("2cupsFilePrintf(fp=%p, format=\"%s\", ...)", fp, format)); + + if (!fp || !format || (fp->mode != 'w' && fp->mode != 's')) + return (-1); + + if (!fp->printf_buffer) + { + /* + * Start with an 1k printf buffer... + */ + + if ((fp->printf_buffer = malloc(1024)) == NULL) + return (-1); + + fp->printf_size = 1024; + } + + va_start(ap, format); + bytes = vsnprintf(fp->printf_buffer, fp->printf_size, format, ap); + va_end(ap); + + if (bytes >= (ssize_t)fp->printf_size) + { + /* + * Expand the printf buffer... + */ + + char *temp; /* Temporary buffer pointer */ + + + if (bytes > 65535) + return (-1); + + if ((temp = realloc(fp->printf_buffer, bytes + 1)) == NULL) + return (-1); + + fp->printf_buffer = temp; + fp->printf_size = bytes + 1; + + va_start(ap, format); + bytes = vsnprintf(fp->printf_buffer, fp->printf_size, format, ap); + va_end(ap); + } + + if (fp->mode == 's') + { + if (cups_write(fp, fp->printf_buffer, bytes) < 0) + return (-1); + + fp->pos += bytes; + + DEBUG_printf(("4cupsFilePrintf: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (bytes); + } + + if ((fp->ptr + bytes) > fp->end) + if (cupsFileFlush(fp)) + return (-1); + + fp->pos += bytes; + + DEBUG_printf(("4cupsFilePrintf: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + if (bytes > sizeof(fp->buf)) + { +#ifdef HAVE_LIBZ + if (fp->compressed) + return (cups_compress(fp, fp->printf_buffer, bytes)); + else +#endif /* HAVE_LIBZ */ + return (cups_write(fp, fp->printf_buffer, bytes)); + } + else + { + memcpy(fp->ptr, fp->printf_buffer, bytes); + fp->ptr += bytes; + return (bytes); + } +} + + +/* + * 'cupsFilePutChar()' - Write a character. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */ + int c) /* I - Character to write */ +{ + /* + * Range check input... + */ + + if (!fp || (fp->mode != 'w' && fp->mode != 's')) + return (-1); + + if (fp->mode == 's') + { + /* + * Send character immediately over socket... + */ + + char ch; /* Output character */ + + + ch = c; + + if (send(fp->fd, &ch, 1, 0) < 1) + return (-1); + } + else + { + /* + * Buffer it up... + */ + + if (fp->ptr >= fp->end) + if (cupsFileFlush(fp)) + return (-1); + + *(fp->ptr) ++ = c; + } + + fp->pos ++; + + DEBUG_printf(("4cupsFilePutChar: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (0); +} + + +/* + * 'cupsFilePutConf()' - Write a configuration line. + * + * This function handles any comment escaping of the value. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ssize_t /* O - Number of bytes written or -1 on error */ +cupsFilePutConf(cups_file_t *fp, /* I - CUPS file */ + const char *directive, /* I - Directive */ + const char *value) /* I - Value */ +{ + ssize_t bytes, /* Number of bytes written */ + temp; /* Temporary byte count */ + const char *ptr; /* Pointer into value */ + + + if (!fp || !directive || !*directive) + return (-1); + + if ((bytes = cupsFilePuts(fp, directive)) < 0) + return (-1); + + if (cupsFilePutChar(fp, ' ') < 0) + return (-1); + bytes ++; + + if (value && *value) + { + if ((ptr = strchr(value, '#')) != NULL) + { + /* + * Need to quote the first # in the info string... + */ + + if ((temp = cupsFileWrite(fp, value, ptr - value)) < 0) + return (-1); + bytes += temp; + + if (cupsFilePutChar(fp, '\\') < 0) + return (-1); + bytes ++; + + if ((temp = cupsFilePuts(fp, ptr)) < 0) + return (-1); + bytes += temp; + } + else if ((temp = cupsFilePuts(fp, value)) < 0) + return (-1); + else + bytes += temp; + } + + if (cupsFilePutChar(fp, '\n') < 0) + return (-1); + else + return (bytes + 1); +} + + +/* + * 'cupsFilePuts()' - Write a string. + * + * Like the @code fputs@ function, no newline is appended to the string. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Number of bytes written or -1 on error */ +cupsFilePuts(cups_file_t *fp, /* I - CUPS file */ + const char *s) /* I - String to write */ +{ + ssize_t bytes; /* Bytes to write */ + + + /* + * Range check input... + */ + + if (!fp || !s || (fp->mode != 'w' && fp->mode != 's')) + return (-1); + + /* + * Write the string... + */ + + bytes = (int)strlen(s); + + if (fp->mode == 's') + { + if (cups_write(fp, s, bytes) < 0) + return (-1); + + fp->pos += bytes; + + DEBUG_printf(("4cupsFilePuts: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (bytes); + } + + if ((fp->ptr + bytes) > fp->end) + if (cupsFileFlush(fp)) + return (-1); + + fp->pos += bytes; + + DEBUG_printf(("4cupsFilePuts: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + if (bytes > sizeof(fp->buf)) + { +#ifdef HAVE_LIBZ + if (fp->compressed) + return (cups_compress(fp, s, bytes)); + else +#endif /* HAVE_LIBZ */ + return (cups_write(fp, s, bytes)); + } + else + { + memcpy(fp->ptr, s, bytes); + fp->ptr += bytes; + return (bytes); + } +} + + +/* + * 'cupsFileRead()' - Read from a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ssize_t /* O - Number of bytes read or -1 on error */ +cupsFileRead(cups_file_t *fp, /* I - CUPS file */ + char *buf, /* O - Buffer */ + size_t bytes) /* I - Number of bytes to read */ +{ + size_t total; /* Total bytes read */ + ssize_t count; /* Bytes read */ + + + DEBUG_printf(("2cupsFileRead(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", fp, buf, + CUPS_LLCAST bytes)); + + /* + * Range check input... + */ + + if (!fp || !buf || bytes < 0 || (fp->mode != 'r' && fp->mode != 's')) + return (-1); + + if (bytes == 0) + return (0); + + /* + * Loop until all bytes are read... + */ + + total = 0; + while (bytes > 0) + { + if (fp->ptr >= fp->end) + if (cups_fill(fp) <= 0) + { + DEBUG_printf(("4cupsFileRead: cups_fill() returned -1, total=" + CUPS_LLFMT, CUPS_LLCAST total)); + + if (total > 0) + return ((ssize_t)total); + else + return (-1); + } + + count = (ssize_t)(fp->end - fp->ptr); + if (count > (ssize_t)bytes) + count = (ssize_t)bytes; + + memcpy(buf, fp->ptr, count); + fp->ptr += count; + fp->pos += count; + + DEBUG_printf(("4cupsFileRead: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + /* + * Update the counts for the last read... + */ + + bytes -= count; + total += count; + buf += count; + } + + /* + * Return the total number of bytes read... + */ + + DEBUG_printf(("3cupsFileRead: total=" CUPS_LLFMT, CUPS_LLCAST total)); + + return ((ssize_t)total); +} + + +/* + * 'cupsFileRewind()' - Set the current file position to the beginning of the + * file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +off_t /* O - New file position or -1 on error */ +cupsFileRewind(cups_file_t *fp) /* I - CUPS file */ +{ + /* + * Range check input... + */ + + DEBUG_printf(("cupsFileRewind(fp=%p)", fp)); + DEBUG_printf(("2cupsFileRewind: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + if (!fp || fp->mode != 'r') + return (-1); + + /* + * Handle special cases... + */ + + if (fp->bufpos == 0) + { + /* + * No seeking necessary... + */ + + fp->pos = 0; + + if (fp->ptr) + { + fp->ptr = fp->buf; + fp->eof = 0; + } + + DEBUG_printf(("2cupsFileRewind: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (0); + } + + /* + * Otherwise, seek in the file and cleanup any compression buffers... + */ + +#ifdef HAVE_LIBZ + if (fp->compressed) + { + inflateEnd(&fp->stream); + fp->compressed = 0; + } +#endif /* HAVE_LIBZ */ + + if (lseek(fp->fd, 0, SEEK_SET)) + { + DEBUG_printf(("1cupsFileRewind: lseek failed: %s", strerror(errno))); + return (-1); + } + + fp->bufpos = 0; + fp->pos = 0; + fp->ptr = NULL; + fp->end = NULL; + fp->eof = 0; + + DEBUG_printf(("2cupsFileRewind: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (0); +} + + +/* + * 'cupsFileSeek()' - Seek in a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +off_t /* O - New file position or -1 on error */ +cupsFileSeek(cups_file_t *fp, /* I - CUPS file */ + off_t pos) /* I - Position in file */ +{ + ssize_t bytes; /* Number bytes in buffer */ + + + DEBUG_printf(("cupsFileSeek(fp=%p, pos=" CUPS_LLFMT ")", fp, + CUPS_LLCAST pos)); + DEBUG_printf(("2cupsFileSeek: fp->pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + DEBUG_printf(("2cupsFileSeek: fp->ptr=%p, fp->end=%p", fp->ptr, fp->end)); + + /* + * Range check input... + */ + + if (!fp || pos < 0 || fp->mode != 'r') + return (-1); + + /* + * Handle special cases... + */ + + if (pos == 0) + return (cupsFileRewind(fp)); + + if (fp->ptr) + { + bytes = (ssize_t)(fp->end - fp->buf); + + DEBUG_printf(("2cupsFileSeek: bytes=" CUPS_LLFMT, CUPS_LLCAST bytes)); + + if (pos >= fp->bufpos && pos < (fp->bufpos + bytes)) + { + /* + * No seeking necessary... + */ + + fp->pos = pos; + fp->ptr = fp->buf + pos - fp->bufpos; + fp->eof = 0; + + return (pos); + } + } + +#ifdef HAVE_LIBZ + if (!fp->compressed && !fp->ptr) + { + /* + * Preload a buffer to determine whether the file is compressed... + */ + + if (cups_fill(fp) < 0) + return (-1); + } +#endif /* HAVE_LIBZ */ + + /* + * Seek forwards or backwards... + */ + + fp->eof = 0; + + if (pos < fp->bufpos) + { + /* + * Need to seek backwards... + */ + + DEBUG_puts("2cupsFileSeek: SEEK BACKWARDS"); + +#ifdef HAVE_LIBZ + if (fp->compressed) + { + inflateEnd(&fp->stream); + + lseek(fp->fd, 0, SEEK_SET); + fp->bufpos = 0; + fp->pos = 0; + fp->ptr = NULL; + fp->end = NULL; + + while ((bytes = cups_fill(fp)) > 0) + if (pos >= fp->bufpos && pos < (fp->bufpos + bytes)) + break; + + if (bytes <= 0) + return (-1); + + fp->ptr = fp->buf + pos - fp->bufpos; + fp->pos = pos; + } + else +#endif /* HAVE_LIBZ */ + { + fp->bufpos = lseek(fp->fd, pos, SEEK_SET); + fp->pos = fp->bufpos; + fp->ptr = NULL; + fp->end = NULL; + + DEBUG_printf(("2cupsFileSeek: lseek() returned " CUPS_LLFMT, + CUPS_LLCAST fp->pos)); + } + } + else + { + /* + * Need to seek forwards... + */ + + DEBUG_puts("2cupsFileSeek: SEEK FORWARDS"); + +#ifdef HAVE_LIBZ + if (fp->compressed) + { + while ((bytes = cups_fill(fp)) > 0) + { + if (pos >= fp->bufpos && pos < (fp->bufpos + bytes)) + break; + } + + if (bytes <= 0) + return (-1); + + fp->ptr = fp->buf + pos - fp->bufpos; + fp->pos = pos; + } + else +#endif /* HAVE_LIBZ */ + { + fp->bufpos = lseek(fp->fd, pos, SEEK_SET); + fp->pos = fp->bufpos; + fp->ptr = NULL; + fp->end = NULL; + + DEBUG_printf(("2cupsFileSeek: lseek() returned " CUPS_LLFMT, + CUPS_LLCAST fp->pos)); + } + } + + DEBUG_printf(("2cupsFileSeek: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return (fp->pos); +} + + +/* + * 'cupsFileStderr()' - Return a CUPS file associated with stderr. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_file_t * /* O - CUPS file */ +cupsFileStderr(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */ + + + /* + * Open file descriptor 2 as needed... + */ + + if (!cg->stdio_files[2]) + { + /* + * Flush any pending output on the stdio file... + */ + + fflush(stderr); + + /* + * Open file descriptor 2... + */ + + if ((cg->stdio_files[2] = cupsFileOpenFd(2, "w")) != NULL) + cg->stdio_files[2]->is_stdio = 1; + } + + return (cg->stdio_files[2]); +} + + +/* + * 'cupsFileStdin()' - Return a CUPS file associated with stdin. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_file_t * /* O - CUPS file */ +cupsFileStdin(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */ + + + /* + * Open file descriptor 0 as needed... + */ + + if (!cg->stdio_files[0]) + { + /* + * Open file descriptor 0... + */ + + if ((cg->stdio_files[0] = cupsFileOpenFd(0, "r")) != NULL) + cg->stdio_files[0]->is_stdio = 1; + } + + return (cg->stdio_files[0]); +} + + +/* + * 'cupsFileStdout()' - Return a CUPS file associated with stdout. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_file_t * /* O - CUPS file */ +cupsFileStdout(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */ + + + /* + * Open file descriptor 1 as needed... + */ + + if (!cg->stdio_files[1]) + { + /* + * Flush any pending output on the stdio file... + */ + + fflush(stdout); + + /* + * Open file descriptor 1... + */ + + if ((cg->stdio_files[1] = cupsFileOpenFd(1, "w")) != NULL) + cg->stdio_files[1]->is_stdio = 1; + } + + return (cg->stdio_files[1]); +} + + +/* + * 'cupsFileTell()' - Return the current file position. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +off_t /* O - File position */ +cupsFileTell(cups_file_t *fp) /* I - CUPS file */ +{ + DEBUG_printf(("2cupsFileTell(fp=%p)", fp)); + DEBUG_printf(("3cupsFileTell: pos=" CUPS_LLFMT, + CUPS_LLCAST (fp ? fp->pos : -1))); + + return (fp ? fp->pos : 0); +} + + +/* + * 'cupsFileUnlock()' - Unlock access to a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsFileUnlock(cups_file_t *fp) /* I - CUPS file */ +{ + /* + * Range check... + */ + + DEBUG_printf(("cupsFileUnlock(fp=%p)", fp)); + + if (!fp || fp->mode == 's') + return (-1); + + /* + * Unlock... + */ + +#ifdef WIN32 + return (_locking(fp->fd, _LK_UNLCK, 0)); +#else + return (lockf(fp->fd, F_ULOCK, 0)); +#endif /* WIN32 */ +} + + +/* + * 'cupsFileWrite()' - Write to a file. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ssize_t /* O - Number of bytes written or -1 on error */ +cupsFileWrite(cups_file_t *fp, /* I - CUPS file */ + const char *buf, /* I - Buffer */ + size_t bytes) /* I - Number of bytes to write */ +{ + /* + * Range check input... + */ + + DEBUG_printf(("2cupsFileWrite(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", + fp, buf, CUPS_LLCAST bytes)); + + if (!fp || !buf || bytes < 0 || (fp->mode != 'w' && fp->mode != 's')) + return (-1); + + if (bytes == 0) + return (0); + + /* + * Write the buffer... + */ + + if (fp->mode == 's') + { + if (cups_write(fp, buf, bytes) < 0) + return (-1); + + fp->pos += (off_t)bytes; + + DEBUG_printf(("4cupsFileWrite: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + return ((ssize_t)bytes); + } + + if ((fp->ptr + bytes) > fp->end) + if (cupsFileFlush(fp)) + return (-1); + + fp->pos += (off_t)bytes; + + DEBUG_printf(("4cupsFileWrite: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos)); + + if (bytes > sizeof(fp->buf)) + { +#ifdef HAVE_LIBZ + if (fp->compressed) + return (cups_compress(fp, buf, bytes)); + else +#endif /* HAVE_LIBZ */ + return (cups_write(fp, buf, bytes)); + } + else + { + memcpy(fp->ptr, buf, bytes); + fp->ptr += bytes; + return ((ssize_t)bytes); + } +} + + +#ifdef HAVE_LIBZ +/* + * 'cups_compress()' - Compress a buffer of data... + */ + +static ssize_t /* O - Number of bytes written or -1 */ +cups_compress(cups_file_t *fp, /* I - CUPS file */ + const char *buf, /* I - Buffer */ + size_t bytes) /* I - Number bytes */ +{ + DEBUG_printf(("7cups_compress(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", fp, buf, + CUPS_LLCAST bytes)); + + /* + * Update the CRC... + */ + + fp->crc = crc32(fp->crc, (const Bytef *)buf, bytes); + + /* + * Deflate the bytes... + */ + + fp->stream.next_in = (Bytef *)buf; + fp->stream.avail_in = bytes; + + while (fp->stream.avail_in > 0) + { + /* + * Flush the current buffer... + */ + + DEBUG_printf(("9cups_compress: avail_in=%d, avail_out=%d", + fp->stream.avail_in, fp->stream.avail_out)); + + if (fp->stream.avail_out < (int)(sizeof(fp->cbuf) / 8)) + { + if (cups_write(fp, (char *)fp->cbuf, fp->stream.next_out - fp->cbuf) < 0) + return (-1); + + fp->stream.next_out = fp->cbuf; + fp->stream.avail_out = sizeof(fp->cbuf); + } + + deflate(&(fp->stream), Z_NO_FLUSH); + } + + return (bytes); +} +#endif /* HAVE_LIBZ */ + + +/* + * 'cups_fill()' - Fill the input buffer... + */ + +static ssize_t /* O - Number of bytes or -1 */ +cups_fill(cups_file_t *fp) /* I - CUPS file */ +{ + ssize_t bytes; /* Number of bytes read */ +#ifdef HAVE_LIBZ + int status; /* Decompression status */ + const unsigned char *ptr, /* Pointer into buffer */ + *end; /* End of buffer */ +#endif /* HAVE_LIBZ */ + + + DEBUG_printf(("7cups_fill(fp=%p)", fp)); + DEBUG_printf(("9cups_fill: fp->ptr=%p, fp->end=%p, fp->buf=%p, " + "fp->bufpos=" CUPS_LLFMT ", fp->eof=%d", + fp->ptr, fp->end, fp->buf, CUPS_LLCAST fp->bufpos, fp->eof)); + + if (fp->ptr && fp->end) + fp->bufpos += fp->end - fp->buf; + +#ifdef HAVE_LIBZ + DEBUG_printf(("9cups_fill: fp->compressed=%d", fp->compressed)); + + while (!fp->ptr || fp->compressed) + { + /* + * Check to see if we have read any data yet; if not, see if we have a + * compressed file... + */ + + if (!fp->ptr) + { + /* + * Reset the file position in case we are seeking... + */ + + fp->compressed = 0; + + /* + * Read the first bytes in the file to determine if we have a gzip'd + * file... + */ + + if ((bytes = cups_read(fp, (char *)fp->buf, sizeof(fp->buf))) < 0) + { + /* + * Can't read from file! + */ + + DEBUG_printf(("9cups_fill: cups_read() returned " CUPS_LLFMT, + CUPS_LLCAST bytes)); + + return (-1); + } + + if (bytes < 10 || fp->buf[0] != 0x1f || + (fp->buf[1] & 255) != 0x8b || + fp->buf[2] != 8 || (fp->buf[3] & 0xe0) != 0) + { + /* + * Not a gzip'd file! + */ + + fp->ptr = fp->buf; + fp->end = fp->buf + bytes; + + DEBUG_printf(("9cups_fill: Returning " CUPS_LLFMT, + CUPS_LLCAST bytes)); + + return (bytes); + } + + /* + * Parse header junk: extra data, original name, and comment... + */ + + ptr = (unsigned char *)fp->buf + 10; + end = (unsigned char *)fp->buf + bytes; + + if (fp->buf[3] & 0x04) + { + /* + * Skip extra data... + */ + + if ((ptr + 2) > end) + { + /* + * Can't read from file! + */ + + return (-1); + } + + bytes = ((unsigned char)ptr[1] << 8) | (unsigned char)ptr[0]; + ptr += 2 + bytes; + + if (ptr > end) + { + /* + * Can't read from file! + */ + + return (-1); + } + } + + if (fp->buf[3] & 0x08) + { + /* + * Skip original name data... + */ + + while (ptr < end && *ptr) + ptr ++; + + if (ptr < end) + ptr ++; + else + { + /* + * Can't read from file! + */ + + return (-1); + } + } + + if (fp->buf[3] & 0x10) + { + /* + * Skip comment data... + */ + + while (ptr < end && *ptr) + ptr ++; + + if (ptr < end) + ptr ++; + else + { + /* + * Can't read from file! + */ + + return (-1); + } + } + + if (fp->buf[3] & 0x02) + { + /* + * Skip header CRC data... + */ + + ptr += 2; + + if (ptr > end) + { + /* + * Can't read from file! + */ + + return (-1); + } + } + + /* + * Copy the flate-compressed data to the compression buffer... + */ + + if ((bytes = end - ptr) > 0) + memcpy(fp->cbuf, ptr, bytes); + + /* + * Setup the decompressor data... + */ + + fp->stream.zalloc = (alloc_func)0; + fp->stream.zfree = (free_func)0; + fp->stream.opaque = (voidpf)0; + fp->stream.next_in = (Bytef *)fp->cbuf; + fp->stream.next_out = NULL; + fp->stream.avail_in = bytes; + fp->stream.avail_out = 0; + fp->crc = crc32(0L, Z_NULL, 0); + + if (inflateInit2(&(fp->stream), -15) != Z_OK) + return (-1); + + fp->compressed = 1; + } + + if (fp->compressed) + { + /* + * If we have reached end-of-file, return immediately... + */ + + if (fp->eof) + return (-1); + + /* + * Fill the decompression buffer as needed... + */ + + if (fp->stream.avail_in == 0) + { + if ((bytes = cups_read(fp, (char *)fp->cbuf, sizeof(fp->cbuf))) <= 0) + return (-1); + + fp->stream.next_in = fp->cbuf; + fp->stream.avail_in = bytes; + } + + /* + * Decompress data from the buffer... + */ + + fp->stream.next_out = (Bytef *)fp->buf; + fp->stream.avail_out = sizeof(fp->buf); + + status = inflate(&(fp->stream), Z_NO_FLUSH); + + if (fp->stream.next_out > (Bytef *)fp->buf) + fp->crc = crc32(fp->crc, (Bytef *)fp->buf, + fp->stream.next_out - (Bytef *)fp->buf); + + if (status == Z_STREAM_END) + { + /* + * Read the CRC and length... + */ + + unsigned char trailer[8]; /* Trailer bytes */ + uLong tcrc; /* Trailer CRC */ + + + if (read(fp->fd, trailer, sizeof(trailer)) < sizeof(trailer)) + { + /* + * Can't get it, so mark end-of-file... + */ + + fp->eof = 1; + } + else + { + tcrc = (((((trailer[3] << 8) | trailer[2]) << 8) | trailer[1]) << 8) | + trailer[0]; + + if (tcrc != fp->crc) + { + /* + * Bad CRC, mark end-of-file... + */ + + DEBUG_printf(("9cups_fill: tcrc=%08x, fp->crc=%08x", + (unsigned int)tcrc, (unsigned int)fp->crc)); + + fp->eof = 1; + + return (-1); + } + + /* + * Otherwise, reset the compressed flag so that we re-read the + * file header... + */ + + fp->compressed = 0; + } + } + + bytes = sizeof(fp->buf) - fp->stream.avail_out; + + /* + * Return the decompressed data... + */ + + fp->ptr = fp->buf; + fp->end = fp->buf + bytes; + + if (bytes) + return (bytes); + } + } +#endif /* HAVE_LIBZ */ + + /* + * Read a buffer's full of data... + */ + + if ((bytes = cups_read(fp, fp->buf, sizeof(fp->buf))) <= 0) + { + /* + * Can't read from file! + */ + + fp->eof = 1; + fp->ptr = fp->buf; + fp->end = fp->buf; + + return (-1); + } + + /* + * Return the bytes we read... + */ + + fp->eof = 0; + fp->ptr = fp->buf; + fp->end = fp->buf + bytes; + + return (bytes); +} + + +/* + * 'cups_open()' - Safely open a file for writing. + * + * We don't allow appending to directories or files that are hard-linked or + * symlinked. + */ + +static int /* O - File descriptor or -1 otherwise */ +cups_open(const char *filename, /* I - Filename */ + int mode) /* I - Open mode */ +{ + int fd; /* File descriptor */ + struct stat fileinfo; /* File information */ +#ifndef WIN32 + struct stat linkinfo; /* Link information */ +#endif /* !WIN32 */ + + + /* + * Open the file... + */ + + if ((fd = open(filename, mode, 0666)) < 0) + return (-1); + + /* + * Then verify that the file descriptor doesn't point to a directory or hard- + * linked file. + */ + + if (fstat(fd, &fileinfo)) + { + close(fd); + return (-1); + } + + if (fileinfo.st_nlink != 1) + { + close(fd); + errno = EPERM; + return (-1); + } + +#ifdef WIN32 + if (fileinfo.st_mode & _S_IFDIR) +#else + if (S_ISDIR(fileinfo.st_mode)) +#endif /* WIN32 */ + { + close(fd); + errno = EISDIR; + return (-1); + } + +#ifndef WIN32 + /* + * Then use lstat to determine whether the filename is a symlink... + */ + + if (lstat(filename, &linkinfo)) + { + close(fd); + return (-1); + } + + if (S_ISLNK(linkinfo.st_mode) || + fileinfo.st_dev != linkinfo.st_dev || + fileinfo.st_ino != linkinfo.st_ino || +#ifdef HAVE_ST_GEN + fileinfo.st_gen != linkinfo.st_gen || +#endif /* HAVE_ST_GEN */ + fileinfo.st_nlink != linkinfo.st_nlink || + fileinfo.st_mode != linkinfo.st_mode) + { + /* + * Yes, don't allow! + */ + + close(fd); + errno = EPERM; + return (-1); + } +#endif /* !WIN32 */ + + return (fd); +} + + +/* + * 'cups_read()' - Read from a file descriptor. + */ + +static ssize_t /* O - Number of bytes read or -1 */ +cups_read(cups_file_t *fp, /* I - CUPS file */ + char *buf, /* I - Buffer */ + size_t bytes) /* I - Number bytes */ +{ + ssize_t total; /* Total bytes read */ + + + DEBUG_printf(("7cups_read(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", fp, buf, + CUPS_LLCAST bytes)); + + /* + * Loop until we read at least 0 bytes... + */ + + for (;;) + { +#ifdef WIN32 + if (fp->mode == 's') + total = (ssize_t)recv(fp->fd, buf, (unsigned)bytes, 0); + else + total = (ssize_t)read(fp->fd, buf, (unsigned)bytes); +#else + if (fp->mode == 's') + total = recv(fp->fd, buf, bytes, 0); + else + total = read(fp->fd, buf, bytes); +#endif /* WIN32 */ + + DEBUG_printf(("9cups_read: total=" CUPS_LLFMT, CUPS_LLCAST total)); + + if (total >= 0) + break; + + /* + * Reads can be interrupted by signals and unavailable resources... + */ + + if (errno == EAGAIN || errno == EINTR) + continue; + else + return (-1); + } + + /* + * Return the total number of bytes read... + */ + + return (total); +} + + +/* + * 'cups_write()' - Write to a file descriptor. + */ + +static ssize_t /* O - Number of bytes written or -1 */ +cups_write(cups_file_t *fp, /* I - CUPS file */ + const char *buf, /* I - Buffer */ + size_t bytes) /* I - Number bytes */ +{ + size_t total; /* Total bytes written */ + ssize_t count; /* Count this time */ + + + DEBUG_printf(("7cups_write(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", fp, buf, + CUPS_LLCAST bytes)); + + /* + * Loop until all bytes are written... + */ + + total = 0; + while (bytes > 0) + { +#ifdef WIN32 + if (fp->mode == 's') + count = (ssize_t)send(fp->fd, buf, (unsigned)bytes, 0); + else + count = (ssize_t)write(fp->fd, buf, (unsigned)bytes); +#else + if (fp->mode == 's') + count = send(fp->fd, buf, bytes, 0); + else + count = write(fp->fd, buf, bytes); +#endif /* WIN32 */ + + DEBUG_printf(("9cups_write: count=" CUPS_LLFMT, CUPS_LLCAST count)); + + if (count < 0) + { + /* + * Writes can be interrupted by signals and unavailable resources... + */ + + if (errno == EAGAIN || errno == EINTR) + continue; + else + return (-1); + } + + /* + * Update the counts for the last write call... + */ + + bytes -= count; + total += count; + buf += count; + } + + /* + * Return the total number of bytes written... + */ + + return ((ssize_t)total); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/file.h b/cups/file.h new file mode 100644 index 0000000000..e6aa5b97d1 --- /dev/null +++ b/cups/file.h @@ -0,0 +1,112 @@ +/* + * "$Id$" + * + * Public file definitions for the Common UNIX Printing System (CUPS). + * + * Since stdio files max out at 256 files on many systems, we have to + * write similar functions without this limit. At the same time, using + * our own file functions allows us to provide transparent support of + * gzip'd print files, PPD files, etc. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_FILE_H_ +# define _CUPS_FILE_H_ + + +/* + * Include necessary headers... + */ + +# include "versioning.h" +# include +# include +# if defined(WIN32) && !defined(__CUPS_SSIZE_T_DEFINED) +# define __CUPS_SSIZE_T_DEFINED +/* Windows does not support the ssize_t type, so map it to off_t... */ +typedef off_t ssize_t; /* @private@ */ +# endif /* WIN32 && !__CUPS_SSIZE_T_DEFINED */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * CUPS file definitions... + */ + +# define CUPS_FILE_NONE 0 /* No compression */ +# define CUPS_FILE_GZIP 1 /* GZIP compression */ + + +/* + * Types and structures... + */ + +typedef struct _cups_file_s cups_file_t;/**** CUPS file type ****/ + + +/* + * Prototypes... + */ + +extern int cupsFileClose(cups_file_t *fp) _CUPS_API_1_2; +extern int cupsFileCompression(cups_file_t *fp) _CUPS_API_1_2; +extern int cupsFileEOF(cups_file_t *fp) _CUPS_API_1_2; +extern const char *cupsFileFind(const char *filename, const char *path, + int executable, char *buffer, + int bufsize) _CUPS_API_1_2; +extern int cupsFileFlush(cups_file_t *fp) _CUPS_API_1_2; +extern int cupsFileGetChar(cups_file_t *fp) _CUPS_API_1_2; +extern char *cupsFileGetConf(cups_file_t *fp, char *buf, size_t buflen, + char **value, int *linenum) _CUPS_API_1_2; +extern size_t cupsFileGetLine(cups_file_t *fp, char *buf, + size_t buflen) _CUPS_API_1_2; +extern char *cupsFileGets(cups_file_t *fp, char *buf, size_t buflen) _CUPS_API_1_2; +extern int cupsFileLock(cups_file_t *fp, int block) _CUPS_API_1_2; +extern int cupsFileNumber(cups_file_t *fp) _CUPS_API_1_2; +extern cups_file_t *cupsFileOpen(const char *filename, const char *mode) _CUPS_API_1_2; +extern cups_file_t *cupsFileOpenFd(int fd, const char *mode) _CUPS_API_1_2; +extern int cupsFilePeekChar(cups_file_t *fp) _CUPS_API_1_2; +extern int cupsFilePrintf(cups_file_t *fp, const char *format, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +#endif /* __GNUC__ */ +_CUPS_API_1_2; +extern int cupsFilePutChar(cups_file_t *fp, int c) _CUPS_API_1_2; +extern ssize_t cupsFilePutConf(cups_file_t *fp, const char *directive, + const char *value) _CUPS_API_1_4; +extern int cupsFilePuts(cups_file_t *fp, const char *s) _CUPS_API_1_2; +extern ssize_t cupsFileRead(cups_file_t *fp, char *buf, size_t bytes) _CUPS_API_1_2; +extern off_t cupsFileRewind(cups_file_t *fp) _CUPS_API_1_2; +extern off_t cupsFileSeek(cups_file_t *fp, off_t pos) _CUPS_API_1_2; +extern cups_file_t *cupsFileStderr(void) _CUPS_API_1_2; +extern cups_file_t *cupsFileStdin(void) _CUPS_API_1_2; +extern cups_file_t *cupsFileStdout(void) _CUPS_API_1_2; +extern off_t cupsFileTell(cups_file_t *fp) _CUPS_API_1_2; +extern int cupsFileUnlock(cups_file_t *fp) _CUPS_API_1_2; +extern ssize_t cupsFileWrite(cups_file_t *fp, const char *buf, size_t bytes) _CUPS_API_1_2; + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_FILE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/getdevices.c b/cups/getdevices.c new file mode 100644 index 0000000000..1f41d76514 --- /dev/null +++ b/cups/getdevices.c @@ -0,0 +1,284 @@ +/* + * "$Id$" + * + * cupsGetDevices implementation for the Common UNIX Printing System (CUPS). + * + * Copyright 2008-2010 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsGetDevices() - Get available printer devices. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" + + +/* + * 'cupsGetDevices()' - Get available printer devices. + * + * This function sends a CUPS-Get-Devices request and streams the discovered + * devices to the specified callback function. The "timeout" parameter controls + * how long the request lasts, while the "include_schemes" and "exclude_schemes" + * parameters provide comma-delimited lists of backends to include or omit from + * the request respectively. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ipp_status_t /* O - Request status - @code IPP_OK@ on success. */ +cupsGetDevices( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + int timeout, /* I - Timeout in seconds or @code CUPS_TIMEOUT_DEFAULT@ */ + const char *include_schemes, /* I - Comma-separated URI schemes to include or @code CUPS_INCLUDE_ALL@ */ + const char *exclude_schemes, /* I - Comma-separated URI schemes to exclude or @code CUPS_EXCLUDE_NONE@ */ + cups_device_cb_t callback, /* I - Callback function */ + void *user_data) /* I - User data pointer */ +{ + ipp_t *request, /* CUPS-Get-Devices request */ + *response; /* CUPS-Get-Devices response */ + ipp_attribute_t *attr; /* Current attribute */ + const char *device_class, /* device-class value */ + *device_id, /* device-id value */ + *device_info, /* device-info value */ + *device_location, /* device-location value */ + *device_make_and_model, /* device-make-and-model value */ + *device_uri; /* device-uri value */ + int blocking; /* Current blocking-IO mode */ + cups_option_t option; /* in/exclude-schemes option */ + http_status_t status; /* HTTP status of request */ + ipp_state_t state; /* IPP response state */ + + + /* + * Range check input... + */ + + DEBUG_printf(("cupsGetDevices(http=%p, timeout=%d, include_schemes=\"%s\", " + "exclude_schemes=\"%s\", callback=%p, user_data=%p)", http, + timeout, include_schemes, exclude_schemes, callback, + user_data)); + + if (!callback) + return (IPP_INTERNAL_ERROR); + + if (!http) + http = _cupsConnect(); + + if (!http) + return (IPP_SERVICE_UNAVAILABLE); + + /* + * Create a CUPS-Get-Devices request... + */ + + request = ippNewRequest(CUPS_GET_DEVICES); + + if (timeout > 0) + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout", + timeout); + + if (include_schemes) + { + option.name = "include-schemes"; + option.value = (char *)include_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + + if (exclude_schemes) + { + option.name = "exclude-schemes"; + option.value = (char *)exclude_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + + /* + * Send the request and do any necessary authentication... + */ + + do + { + DEBUG_puts("2cupsGetDevices: Sending request..."); + status = cupsSendRequest(http, request, "/", ippLength(request)); + + DEBUG_puts("2cupsGetDevices: Waiting for response status..."); + while (status == HTTP_CONTINUE) + status = httpUpdate(http); + + if (status != HTTP_OK) + { + httpFlush(http); + + if (status == HTTP_UNAUTHORIZED) + { + /* + * See if we can do authentication... + */ + + DEBUG_puts("2cupsGetDevices: Need authorization..."); + + if (!cupsDoAuthentication(http, "POST", "/")) + httpReconnect(http); + else + { + status = HTTP_AUTHORIZATION_CANCELED; + break; + } + } + +#ifdef HAVE_SSL + else if (status == HTTP_UPGRADE_REQUIRED) + { + /* + * Force a reconnect with encryption... + */ + + DEBUG_puts("2cupsGetDevices: Need encryption..."); + + if (!httpReconnect(http)) + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); + } +#endif /* HAVE_SSL */ + } + } + while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED); + + DEBUG_printf(("2cupsGetDevices: status=%d", status)); + + ippDelete(request); + + if (status != HTTP_OK) + { + _cupsSetHTTPError(status); + return (cupsLastError()); + } + + /* + * Read the response in non-blocking mode... + */ + + blocking = httpGetBlocking(http); + httpBlocking(http, 0); + + response = ippNew(); + device_class = NULL; + device_id = NULL; + device_info = NULL; + device_location = ""; + device_make_and_model = NULL; + device_uri = NULL; + attr = NULL; + + DEBUG_puts("2cupsGetDevices: Reading response..."); + + do + { + if ((state = ippRead(http, response)) == IPP_ERROR) + break; + + DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, + response->last)); + + if (!response->attrs) + continue; + + while (attr != response->last) + { + if (!attr) + attr = response->attrs; + else + attr = attr->next; + + DEBUG_printf(("2cupsGetDevices: attr->name=\"%s\", attr->value_tag=%d", + attr->name, attr->value_tag)); + + if (!attr->name) + { + if (device_class && device_id && device_info && device_make_and_model && + device_uri) + (*callback)(device_class, device_id, device_info, + device_make_and_model, device_uri, device_location, + user_data); + + device_class = NULL; + device_id = NULL; + device_info = NULL; + device_location = ""; + device_make_and_model = NULL; + device_uri = NULL; + } + else if (!strcmp(attr->name, "device-class") && + attr->value_tag == IPP_TAG_KEYWORD) + device_class = attr->values[0].string.text; + else if (!strcmp(attr->name, "device-id") && + attr->value_tag == IPP_TAG_TEXT) + device_id = attr->values[0].string.text; + else if (!strcmp(attr->name, "device-info") && + attr->value_tag == IPP_TAG_TEXT) + device_info = attr->values[0].string.text; + else if (!strcmp(attr->name, "device-location") && + attr->value_tag == IPP_TAG_TEXT) + device_location = attr->values[0].string.text; + else if (!strcmp(attr->name, "device-make-and-model") && + attr->value_tag == IPP_TAG_TEXT) + device_make_and_model = attr->values[0].string.text; + else if (!strcmp(attr->name, "device-uri") && + attr->value_tag == IPP_TAG_URI) + device_uri = attr->values[0].string.text; + } + } + while (state != IPP_DATA); + + DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, + response->last)); + + if (device_class && device_id && device_info && device_make_and_model && + device_uri) + (*callback)(device_class, device_id, device_info, + device_make_and_model, device_uri, device_location, user_data); + + /* + * Set the IPP status and return... + */ + + httpBlocking(http, blocking); + httpFlush(http); + + if (status == HTTP_ERROR) + _cupsSetError(IPP_ERROR, NULL, 0); + else + { + attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT); + + DEBUG_printf(("cupsGetDevices: status-code=%s, status-message=\"%s\"", + ippErrorString(response->request.status.status_code), + attr ? attr->values[0].string.text : "")); + + _cupsSetError(response->request.status.status_code, + attr ? attr->values[0].string.text : + ippErrorString(response->request.status.status_code), 0); + } + + ippDelete(response); + + return (cupsLastError()); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/getifaddrs.c b/cups/getifaddrs.c new file mode 100644 index 0000000000..261c0acc36 --- /dev/null +++ b/cups/getifaddrs.c @@ -0,0 +1,267 @@ +/* + * "$Id$" + * + * Network interface functions for the Common UNIX Printing System + * (CUPS) scheduler. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * _cups_getifaddrs() - Get a list of network interfaces on the system. + * _cups_freeifaddrs() - Free an interface list... + */ + +/* + * Include necessary headers. + */ + +#include "http-private.h" + + +#ifndef HAVE_GETIFADDRS +/* + * '_cups_getifaddrs()' - Get a list of network interfaces on the system. + */ + +int /* O - 0 on success, -1 on error */ +_cups_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_broadaddr = + calloc(1, sizeof(request.ifr_broadaddr))) != NULL) + memcpy(temp->ifa_broadaddr, &(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); +} + + +/* + * '_cups_freeifaddrs()' - Free an interface list... + */ + +void +_cups_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/cups/getputfile.c b/cups/getputfile.c new file mode 100644 index 0000000000..fe632765d9 --- /dev/null +++ b/cups/getputfile.c @@ -0,0 +1,508 @@ +/* + * "$Id$" + * + * Get/put file functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsGetFd() - Get a file from the server. + * cupsGetFile() - Get a file from the server. + * cupsPutFd() - Put a file on the server. + * cupsPutFile() - Put a file on the server. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "cups.h" +#include "language.h" +#include "debug.h" +#include +#include +#include +#include +#include +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * 'cupsGetFd()' - Get a file from the server. + * + * This function returns @code HTTP_OK@ when the file is successfully retrieved. + * + * @since CUPS 1.1.20/Mac OS X 10.4@ + */ + +http_status_t /* O - HTTP status */ +cupsGetFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *resource, /* I - Resource name */ + int fd) /* I - File descriptor */ +{ + int bytes; /* Number of bytes read */ + char buffer[8192]; /* Buffer for file */ + http_status_t status; /* HTTP status from server */ + char if_modified_since[HTTP_MAX_VALUE]; + /* If-Modified-Since header */ + + + /* + * Range check input... + */ + + DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)", http, + resource, fd)); + + if (!resource || fd < 0) + { + if (http) + http->error = EINVAL; + + return (HTTP_ERROR); + } + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (HTTP_SERVICE_UNAVAILABLE); + + /* + * Then send GET requests to the HTTP server... + */ + + strlcpy(if_modified_since, httpGetField(http, HTTP_FIELD_IF_MODIFIED_SINCE), + sizeof(if_modified_since)); + + do + { + httpClearFields(http); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, if_modified_since); + + if (httpGet(http, resource)) + { + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + else + { + status = HTTP_UNAUTHORIZED; + continue; + } + } + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + + if (status == HTTP_UNAUTHORIZED) + { + /* + * Flush any error message... + */ + + httpFlush(http); + + /* + * See if we can do authentication... + */ + + if (cupsDoAuthentication(http, "GET", resource)) + { + status = HTTP_AUTHORIZATION_CANCELED; + break; + } + + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + + continue; + } +#ifdef HAVE_SSL + else if (status == HTTP_UPGRADE_REQUIRED) + { + /* Flush any error message... */ + httpFlush(http); + + /* Reconnect... */ + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + + /* Upgrade with encryption... */ + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); + + /* Try again, this time with encryption enabled... */ + continue; + } +#endif /* HAVE_SSL */ + } + while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED); + + /* + * See if we actually got the file or an error... + */ + + if (status == HTTP_OK) + { + /* + * Yes, copy the file... + */ + + while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0) + write(fd, buffer, bytes); + } + else + { + _cupsSetHTTPError(status); + httpFlush(http); + } + + /* + * Return the request status... + */ + + DEBUG_printf(("1cupsGetFd: Returning %d...", status)); + + return (status); +} + + +/* + * 'cupsGetFile()' - Get a file from the server. + * + * This function returns @code HTTP_OK@ when the file is successfully retrieved. + * + * @since CUPS 1.1.20/Mac OS X 10.4@ + */ + +http_status_t /* O - HTTP status */ +cupsGetFile(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *resource, /* I - Resource name */ + const char *filename) /* I - Filename */ +{ + int fd; /* File descriptor */ + http_status_t status; /* Status */ + + + /* + * Range check input... + */ + + if (!http || !resource || !filename) + { + if (http) + http->error = EINVAL; + + return (HTTP_ERROR); + } + + /* + * Create the file... + */ + + if ((fd = open(filename, O_WRONLY | O_EXCL | O_TRUNC)) < 0) + { + /* + * Couldn't open the file! + */ + + http->error = errno; + + return (HTTP_ERROR); + } + + /* + * Get the file... + */ + + status = cupsGetFd(http, resource, fd); + + /* + * If the file couldn't be gotten, then remove the file... + */ + + close(fd); + + if (status != HTTP_OK) + unlink(filename); + + /* + * Return the HTTP status code... + */ + + return (status); +} + + +/* + * 'cupsPutFd()' - Put a file on the server. + * + * This function returns @code HTTP_CREATED@ when the file is stored + * successfully. + * + * @since CUPS 1.1.20/Mac OS X 10.4@ + */ + +http_status_t /* O - HTTP status */ +cupsPutFd(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *resource, /* I - Resource name */ + int fd) /* I - File descriptor */ +{ + int bytes, /* Number of bytes read */ + retries; /* Number of retries */ + char buffer[8192]; /* Buffer for file */ + http_status_t status; /* HTTP status from server */ + + + /* + * Range check input... + */ + + DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)", http, + resource, fd)); + + if (!resource || fd < 0) + { + if (http) + http->error = EINVAL; + + return (HTTP_ERROR); + } + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (HTTP_SERVICE_UNAVAILABLE); + + /* + * Then send PUT requests to the HTTP server... + */ + + retries = 0; + + do + { + DEBUG_printf(("2cupsPutFd: starting attempt, authstring=\"%s\"...", + http->authstring)); + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked"); + httpSetExpect(http, HTTP_CONTINUE); + + if (httpPut(http, resource)) + { + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + else + { + status = HTTP_UNAUTHORIZED; + continue; + } + } + + /* + * Wait up to 1 second for a 100-continue response... + */ + + if (httpWait(http, 1000)) + status = httpUpdate(http); + else + status = HTTP_CONTINUE; + + if (status == HTTP_CONTINUE) + { + /* + * Copy the file... + */ + + lseek(fd, 0, SEEK_SET); + + while ((bytes = read(fd, buffer, sizeof(buffer))) > 0) + if (httpCheck(http)) + { + if ((status = httpUpdate(http)) != HTTP_CONTINUE) + break; + } + else + httpWrite2(http, buffer, bytes); + } + + if (status == HTTP_CONTINUE) + { + httpWrite2(http, buffer, 0); + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + } + + if (status == HTTP_ERROR && !retries) + { + DEBUG_printf(("2cupsPutFd: retry on status %d", status)); + + retries ++; + + /* Flush any error message... */ + httpFlush(http); + + /* Reconnect... */ + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + + /* Try again... */ + continue; + } + + DEBUG_printf(("2cupsPutFd: status=%d", status)); + + if (status == HTTP_UNAUTHORIZED) + { + /* + * Flush any error message... + */ + + httpFlush(http); + + /* + * See if we can do authentication... + */ + + if (cupsDoAuthentication(http, "PUT", resource)) + { + status = HTTP_AUTHORIZATION_CANCELED; + break; + } + + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + + continue; + } +#ifdef HAVE_SSL + else if (status == HTTP_UPGRADE_REQUIRED) + { + /* Flush any error message... */ + httpFlush(http); + + /* Reconnect... */ + if (httpReconnect(http)) + { + status = HTTP_ERROR; + break; + } + + /* Upgrade with encryption... */ + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); + + /* Try again, this time with encryption enabled... */ + continue; + } +#endif /* HAVE_SSL */ + } + while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED || + (status == HTTP_ERROR && retries < 2)); + + /* + * See if we actually put the file or an error... + */ + + if (status != HTTP_CREATED) + { + _cupsSetHTTPError(status); + httpFlush(http); + } + + DEBUG_printf(("1cupsPutFd: Returning %d...", status)); + + return (status); +} + + +/* + * 'cupsPutFile()' - Put a file on the server. + * + * This function returns @code HTTP_CREATED@ when the file is stored + * successfully. + * + * @since CUPS 1.1.20/Mac OS X 10.4@ + */ + +http_status_t /* O - HTTP status */ +cupsPutFile(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *resource, /* I - Resource name */ + const char *filename) /* I - Filename */ +{ + int fd; /* File descriptor */ + http_status_t status; /* Status */ + + + /* + * Range check input... + */ + + if (!http || !resource || !filename) + { + if (http) + http->error = EINVAL; + + return (HTTP_ERROR); + } + + /* + * Open the local file... + */ + + if ((fd = open(filename, O_RDONLY)) < 0) + { + /* + * Couldn't open the file! + */ + + http->error = errno; + + return (HTTP_ERROR); + } + + /* + * Put the file... + */ + + status = cupsPutFd(http, resource, fd); + + close(fd); + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/globals.c b/cups/globals.c new file mode 100644 index 0000000000..dbe8608128 --- /dev/null +++ b/cups/globals.c @@ -0,0 +1,249 @@ +/* + * "$Id$" + * + * Global variable access routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsGlobals() - Return a pointer to thread local storage. + * cups_env_init() - Initialize environment variables. + * globals_init() - Initialize globals once. + * globals_destructor() - Free memory allocated by _cupsGlobals(). + */ + +/* + * Include necessary headers... + */ + +#include "http-private.h" +#include "globals.h" +#include + + +/* + * 'cups_env_init()' - Initialize environment variables. + */ + +static void +cups_env_init(_cups_globals_t *g) /* I - Global data */ +{ +#ifndef WIN32 +# ifdef HAVE_GETEUID + if ((geteuid() != getuid() && getuid()) || getegid() != getgid()) +# else + if (!getuid()) +# endif /* HAVE_GETEUID */ + { + /* + * When running setuid/setgid, don't allow environment variables to override + * the directories... + */ + + g->cups_datadir = CUPS_DATADIR; + g->cups_serverbin = CUPS_SERVERBIN; + g->cups_serverroot = CUPS_SERVERROOT; + g->cups_statedir = CUPS_STATEDIR; + g->localedir = CUPS_LOCALEDIR; + } + else +#endif /* !WIN32 */ + { + /* + * Allow directories to be overridden by environment variables. + */ + + if ((g->cups_datadir = getenv("CUPS_DATADIR")) == NULL) + g->cups_datadir = CUPS_DATADIR; + + if ((g->cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL) + g->cups_serverbin = CUPS_SERVERBIN; + + if ((g->cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL) + g->cups_serverroot = CUPS_SERVERROOT; + + if ((g->cups_statedir = getenv("CUPS_STATEDIR")) == NULL) + g->cups_statedir = CUPS_STATEDIR; + + if ((g->localedir = getenv("LOCALEDIR")) == NULL) + g->localedir = CUPS_LOCALEDIR; + } +} + + +#ifdef HAVE_PTHREAD_H +/* + * Implement per-thread globals... + */ + +/* + * Local globals... + */ + +static pthread_key_t globals_key = -1; + /* Thread local storage key */ +static pthread_once_t globals_key_once = PTHREAD_ONCE_INIT; + /* One-time initialization object */ + + +/* + * Local functions... + */ + +static void globals_init(); +static void globals_destructor(void *value); + + +/* + * '_cupsGlobals()' - Return a pointer to thread local storage + */ + +_cups_globals_t * /* O - Pointer to global data */ +_cupsGlobals(void) +{ + _cups_globals_t *globals; /* Pointer to global data */ + + + /* + * Initialize the global data exactly once... + */ + + pthread_once(&globals_key_once, globals_init); + + /* + * See if we have allocated the data yet... + */ + + if ((globals = (_cups_globals_t *)pthread_getspecific(globals_key)) == NULL) + { + /* + * No, allocate memory as set the pointer for the key... + */ + + globals = calloc(1, sizeof(_cups_globals_t)); + pthread_setspecific(globals_key, globals); + + /* + * Initialize variables that have non-zero values + */ + + globals->encryption = (http_encryption_t)-1; + globals->password_cb = (cups_password_cb2_t)_cupsGetPassword; + + cups_env_init(globals); + } + + /* + * Return the pointer to the data... + */ + + return (globals); +} + + +/* + * 'globals_init()' - Initialize globals once. + */ + +static void +globals_init() +{ + pthread_key_create(&globals_key, globals_destructor); +} + + +/* + * 'globals_destructor()' - Free memory allocated by _cupsGlobals(). + */ + +static void +globals_destructor(void *value) /* I - Data to free */ +{ + int i; /* Looping var */ + _ipp_buffer_t *buffer, /* Current IPP read/write buffer */ + *next; /* Next buffer */ + _cups_globals_t *cg; /* Global data */ + + + cg = (_cups_globals_t *)value; + + httpClose(cg->http); + + for (i = 0; i < 3; i ++) + cupsFileClose(cg->stdio_files[i]); + + if (cg->last_status_message) + _cupsStrFree(cg->last_status_message); + +# ifndef CUPS_LITE + cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings); +# endif /* !CUPS_LITE */ + + for (buffer = cg->ipp_buffers; buffer; buffer = next) + { + next = buffer->next; + free(buffer); + } + + cupsArrayDelete(cg->leg_size_lut); + cupsArrayDelete(cg->ppd_size_lut); + cupsArrayDelete(cg->pwg_size_lut); + + free(value); +} + + +#else +/* + * Implement static globals... + */ + +/* + * '_cupsGlobals()' - Return a pointer to thread local storage. + */ + +_cups_globals_t * /* O - Pointer to global data */ +_cupsGlobals(void) +{ + static _cups_globals_t globals; /* Global data */ + static int initialized = 0;/* Global data initialized? */ + + + /* + * Initialize global data as needed... + */ + + if (!initialized) + { + initialized = 1; + + /* + * Initialize global variables... + */ + + memset(&globals, 0, sizeof(globals)); + + globals.encryption = (http_encryption_t)-1; + globals.password_cb = (cups_password_cb2_t)_cupsGetPassword; + + cups_env_init(&globals); + } + + return (&globals); +} +#endif /* HAVE_PTHREAD_H */ + + +/* + * End of "$Id$". + */ diff --git a/cups/globals.h b/cups/globals.h new file mode 100644 index 0000000000..9dbe6068a2 --- /dev/null +++ b/cups/globals.h @@ -0,0 +1,169 @@ +/* + * "$Id$" + * + * Global variable definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_GLOBALS_H_ +# define _CUPS_GLOBALS_H_ + +/* + * Include necessary headers... + */ + +# include "string.h" +# include "http-private.h" +# include "cups.h" +# include "i18n.h" +# include "ppd-private.h" +# include "pwg-private.h" + +# ifdef HAVE_PTHREAD_H +# include +# endif /* HAVE_PTHREAD_H */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * To make libcups thread safe, define thread safe globals (aka thread- + * specific data) for the static variables used in the library. + */ + +typedef struct _cups_globals_s /**** CUPS global state data ****/ +{ + /* Multiple places... */ + const char *cups_datadir, /* CUPS_DATADIR environment var */ + *cups_serverbin,/* CUPS_SERVERBIN environment var */ + *cups_serverroot, + /* CUPS_SERVERROOT environment var */ + *cups_statedir, /* CUPS_STATEDIR environment var */ + *localedir; /* LOCALDIR environment var */ + + /* adminutil.c */ + time_t cupsd_update; /* Last time we got or set cupsd.conf */ + char cupsd_hostname[HTTP_MAX_HOST]; + /* Hostname for connection */ + int cupsd_num_settings; + /* Number of server settings */ + cups_option_t *cupsd_settings;/* Server settings */ + + /* backend.c */ + char resolved_uri[1024]; + /* Buffer for cupsBackendDeviceURI */ + + /* file.c */ + cups_file_t *stdio_files[3];/* stdin, stdout, stderr */ + + /* http.c */ + char http_date[256]; /* Date+time buffer */ + + /* http-addr.c */ + unsigned ip_addr; /* Packed IPv4 address */ + char *ip_ptrs[2]; /* Pointer to packed address */ + struct hostent hostent; /* Host entry for IP address */ +# ifdef HAVE_GETADDRINFO + char hostname[1024]; /* Hostname */ +# endif /* HAVE_GETADDRINFO */ + int need_res_init; /* Need to reinitialize resolver? */ + + /* ipp.c */ + ipp_uchar_t ipp_date[11]; /* RFC-1903 date/time data */ + _ipp_buffer_t *ipp_buffers; /* Buffer list */ + + /* ipp-support.c */ + int ipp_port; /* IPP port number */ + char ipp_unknown[255]; + /* Unknown error statuses */ + + /* language.c */ + cups_lang_t *lang_default; /* Default language */ +# ifdef __APPLE__ + char language[32]; /* Cached language */ +# endif /* __APPLE__ */ + + /* ppd.c */ + ppd_status_t ppd_status; /* Status of last ppdOpen*() */ + int ppd_line; /* Current line number */ + ppd_conform_t ppd_conform; /* Level of conformance required */ + + /* pwg-media.c */ + cups_array_t *leg_size_lut, /* Lookup table for legacy names */ + *ppd_size_lut, /* Lookup table for PPD names */ + *pwg_size_lut; /* Lookup table for PWG names */ + _pwg_media_t pwg_media; /* PWG media data for custom size */ + char pwg_name[65]; /* PWG media name for custom size */ + + /* snmp.c */ + char snmp_community[255]; + /* Default SNMP community name */ + int snmp_debug; /* Log SNMP IO to stderr? */ + + /* tempfile.c */ + char tempfile[1024]; /* cupsTempFd/File buffer */ + + /* usersys.c */ + http_encryption_t encryption; /* Encryption setting */ + char user[65], /* User name */ + server[256], /* Server address */ + servername[256];/* Server hostname */ + cups_password_cb2_t password_cb; /* Password callback */ + void *password_data; /* Password user data */ + + /* util.c */ + http_t *http; /* Current server connection */ + ipp_status_t last_error; /* Last IPP error */ + char *last_status_message; + /* Last IPP status-message */ + + char def_printer[256]; + /* Default printer */ + char ppd_filename[HTTP_MAX_URI]; + /* PPD filename */ +} _cups_globals_t; + + +/* + * Prototypes... + */ + +extern http_t *_cupsConnect(void); +extern const char *_cupsGetPassword(const char *prompt); +extern _cups_globals_t *_cupsGlobals(void); +extern void _cupsSetDefaults(void); +extern void _cupsSetError(ipp_status_t status, const char *message, + int localize); +extern void _cupsSetHTTPError(http_status_t status); +extern char *_cupsUserDefault(char *name, size_t namesize); + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_GLOBALS_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/http-addr.c b/cups/http-addr.c new file mode 100644 index 0000000000..d1656c8a3b --- /dev/null +++ b/cups/http-addr.c @@ -0,0 +1,641 @@ +/* + * "$Id$" + * + * HTTP address routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * httpAddrAny() - Check for the "any" address. + * httpAddrEqual() - Compare two addresses. + * httpAddrLocalhost() - Check for the local loopback address. + * httpAddrLookup() - Lookup the hostname associated with the address. + * _httpAddrPort() - Get the port number associated with an address. + * httpAddrString() - Convert an IP address to a dotted string. + * httpGetHostByName() - Lookup a hostname or IP address, and return + * address records for the specified name. + * httpGetHostname() - Get the FQDN for the local system. + */ + +/* + * Include necessary headers... + */ + +#include "http-private.h" +#include "globals.h" +#include "debug.h" +#include +#include +#ifdef HAVE_RESOLV_H +# include +#endif /* HAVE_RESOLV_H */ + + +/* + * 'httpAddrAny()' - Check for the "any" address. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 if "any", 0 otherwise */ +httpAddrAny(const http_addr_t *addr) /* I - Address to check */ +{ + if (!addr) + return (0); + +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6 && + IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr))) + return (1); +#endif /* AF_INET6 */ + + if (addr->addr.sa_family == AF_INET && + ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000) + return (1); + + return (0); +} + + +/* + * 'httpAddrEqual()' - Compare two addresses. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 if equal, 0 if not */ +httpAddrEqual(const http_addr_t *addr1, /* I - First address */ + const http_addr_t *addr2) /* I - Second address */ +{ + if (!addr1 && !addr2) + return (1); + + if (!addr1 || !addr2) + return (0); + + if (addr1->addr.sa_family != addr2->addr.sa_family) + return (0); + +#ifdef AF_LOCAL + if (addr1->addr.sa_family == AF_LOCAL) + return (!strcmp(addr1->un.sun_path, addr2->un.sun_path)); +#endif /* AF_LOCAL */ + +#ifdef AF_INET6 + if (addr1->addr.sa_family == AF_INET6) + return (!memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16)); +#endif /* AF_INET6 */ + + return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr); +} + + +/* + * 'httpAddrLength()' - Return the length of the address in bytes. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Length in bytes */ +httpAddrLength(const http_addr_t *addr) /* I - Address */ +{ + if (!addr) + return (0); + +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6) + return (sizeof(addr->ipv6)); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + return (offsetof(struct sockaddr_un, sun_path) + + strlen(addr->un.sun_path) + 1); + else +#endif /* AF_LOCAL */ + if (addr->addr.sa_family == AF_INET) + return (sizeof(addr->ipv4)); + else + return (0); + +} + + +/* + * 'httpAddrLocalhost()' - Check for the local loopback address. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 if local host, 0 otherwise */ +httpAddrLocalhost( + const http_addr_t *addr) /* I - Address to check */ +{ + if (!addr) + return (1); + +#ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6 && + IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr))) + return (1); +#endif /* AF_INET6 */ + +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + return (1); +#endif /* AF_LOCAL */ + + if (addr->addr.sa_family == AF_INET && + (ntohl(addr->ipv4.sin_addr.s_addr) & 0xff000000) == 0x7f000000) + return (1); + + return (0); +} + + +#ifdef __sgi +# define ADDR_CAST (struct sockaddr *) +#else +# define ADDR_CAST (char *) +#endif /* __sgi */ + + +/* + * 'httpAddrLookup()' - Lookup the hostname associated with the address. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Host name */ +httpAddrLookup( + const http_addr_t *addr, /* I - Address to lookup */ + char *name, /* I - Host name buffer */ + int namelen) /* I - Size of name buffer */ +{ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)", addr, name, + namelen)); + + /* + * Range check input... + */ + + if (!addr || !name || namelen <= 2) + { + if (name && namelen >= 1) + *name = '\0'; + + return (NULL); + } + +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + { + strlcpy(name, addr->un.sun_path, namelen); + return (name); + } +#endif /* AF_LOCAL */ + + /* + * Optimize lookups for localhost/loopback addresses... + */ + + if (httpAddrLocalhost(addr)) + { + strlcpy(name, "localhost", namelen); + return (name); + } + +#ifdef HAVE_RES_INIT + /* + * STR #2920: Initialize resolver after failure in cups-polld + * + * If the previous lookup failed, re-initialize the resolver to prevent + * temporary network errors from persisting. This *should* be handled by + * the resolver libraries, but apparently the glibc folks do not agree. + * + * We set a flag at the end of this function if we encounter an error that + * requires reinitialization of the resolver functions. We then call + * res_init() if the flag is set on the next call here or in httpAddrLookup(). + */ + + if (cg->need_res_init) + { + res_init(); + + cg->need_res_init = 0; + } +#endif /* HAVE_RES_INIT */ + +#ifdef HAVE_GETNAMEINFO + { + /* + * STR #2486: httpAddrLookup() fails when getnameinfo() returns EAI_AGAIN + * + * FWIW, I think this is really a bug in the implementation of + * getnameinfo(), but falling back on httpAddrString() is easy to + * do... + */ + + int error = getnameinfo(&addr->addr, httpAddrLength(addr), name, namelen, + NULL, 0, 0); + + if (error) + { + if (error == EAI_FAIL) + cg->need_res_init = 1; + + return (httpAddrString(addr, name, namelen)); + } + } +#else + { + struct hostent *host; /* Host from name service */ + + +# ifdef AF_INET6 + if (addr->addr.sa_family == AF_INET6) + host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr), + sizeof(struct in_addr), AF_INET6); + else +# endif /* AF_INET6 */ + host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr), + sizeof(struct in_addr), AF_INET); + + if (host == NULL) + { + /* + * No hostname, so return the raw address... + */ + + if (h_errno == NO_RECOVERY) + cg->need_res_init = 1; + + return (httpAddrString(addr, name, namelen)); + } + + strlcpy(name, host->h_name, namelen); + } +#endif /* HAVE_GETNAMEINFO */ + + DEBUG_printf(("1httpAddrLookup: returning \"%s\"...", name)); + + return (name); +} + + +/* + * '_httpAddrPort()' - Get the port number associated with an address. + */ + +int /* O - Port number */ +_httpAddrPort(http_addr_t *addr) /* I - Address */ +{ + if (!addr) + return (ippPort()); +#ifdef AF_INET6 + else if (addr->addr.sa_family == AF_INET6) + return (ntohs(addr->ipv6.sin6_port)); +#endif /* AF_INET6 */ + else if (addr->addr.sa_family == AF_INET) + return (ntohs(addr->ipv4.sin_port)); + else + return (ippPort()); +} + + +/* + * 'httpAddrString()' - Convert an address to a numeric string. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Numeric address string */ +httpAddrString(const http_addr_t *addr, /* I - Address to convert */ + char *s, /* I - String buffer */ + int slen) /* I - Length of string */ +{ + DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)", addr, s, slen)); + + /* + * Range check input... + */ + + if (!addr || !s || slen <= 2) + { + if (s && slen >= 1) + *s = '\0'; + + return (NULL); + } + +#ifdef AF_LOCAL + if (addr->addr.sa_family == AF_LOCAL) + strlcpy(s, addr->un.sun_path, slen); + else +#endif /* AF_LOCAL */ + if (addr->addr.sa_family == AF_INET) + { + unsigned temp; /* Temporary address */ + + + temp = ntohl(addr->ipv4.sin_addr.s_addr); + + snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, + (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); + } +#ifdef AF_INET6 + else if (addr->addr.sa_family == AF_INET6) + { + char *sptr, /* Pointer into string */ + temps[64]; /* Temporary string for address */ + +# ifdef HAVE_GETNAMEINFO + if (getnameinfo(&addr->addr, httpAddrLength(addr), temps, sizeof(temps), + NULL, 0, NI_NUMERICHOST)) + { + /* + * If we get an error back, then the address type is not supported + * and we should zero out the buffer... + */ + + s[0] = '\0'; + + return (NULL); + } + else if ((sptr = strchr(temps, '%')) != NULL) + { + /* + * Convert "%zone" to "+zone" to match URI form... + */ + + *sptr = '+'; + } + +# else + int i; /* Looping var */ + unsigned temp; /* Current value */ + const char *prefix; /* Prefix for address */ + + + prefix = ""; + for (sptr = temps, i = 0; i < 4 && addr->ipv6.sin6_addr.s6_addr32[i]; i ++) + { + temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); + + snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, + (temp >> 16) & 0xffff); + prefix = ":"; + sptr += strlen(sptr); + + temp &= 0xffff; + + if (temp || i == 3 || addr->ipv6.sin6_addr.s6_addr32[i + 1]) + { + snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, temp); + sptr += strlen(sptr); + } + } + + if (i < 4) + { + while (i < 4 && !addr->ipv6.sin6_addr.s6_addr32[i]) + i ++; + + if (i < 4) + { + snprintf(sptr, sizeof(temps) - (sptr - temps), "%s:", prefix); + prefix = ":"; + sptr += strlen(sptr); + + for (; i < 4; i ++) + { + temp = ntohl(addr->ipv6.sin6_addr.s6_addr32[i]); + + if ((temp & 0xffff0000) || + (i > 0 && addr->ipv6.sin6_addr.s6_addr32[i - 1])) + { + snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, + (temp >> 16) & 0xffff); + sptr += strlen(sptr); + } + + snprintf(sptr, sizeof(temps) - (sptr - temps), "%s%x", prefix, + temp & 0xffff); + sptr += strlen(sptr); + } + } + else if (sptr == s) + { + /* + * Empty address... + */ + + strlcpy(temps, "::", sizeof(temps)); + } + else + { + /* + * Empty at end... + */ + + strlcpy(sptr, "::", sizeof(temps) - (sptr - temps)); + } + } +# endif /* HAVE_GETNAMEINFO */ + + /* + * Add "[v1." and "]" around IPv6 address to convert to URI form. + */ + + snprintf(s, slen, "[v1.%s]", temps); + } +#endif /* AF_INET6 */ + else + strlcpy(s, "UNKNOWN", slen); + + DEBUG_printf(("1httpAddrString: returning \"%s\"...", s)); + + return (s); +} + + +/* + * 'httpGetHostByName()' - Lookup a hostname or IPv4 address, and return + * address records for the specified name. + * + * @deprecated@ + */ + +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 */ + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + + + DEBUG_printf(("httpGetHostByName(name=\"%s\")", name)); + + /* + * Avoid lookup delays and configuration problems when connecting + * to the localhost address... + */ + + if (!strcmp(name, "localhost")) + name = "127.0.0.1"; + + /* + * This function is needed because some operating systems have a + * buggy implementation of gethostbyname() 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. + * + * We also support domain sockets when supported by the underlying + * OS... + */ + +#ifdef AF_LOCAL + if (name[0] == '/') + { + /* + * A domain socket address, so make an AF_LOCAL entry and return it... + */ + + cg->hostent.h_name = (char *)name; + cg->hostent.h_aliases = NULL; + cg->hostent.h_addrtype = AF_LOCAL; + cg->hostent.h_length = strlen(name) + 1; + cg->hostent.h_addr_list = cg->ip_ptrs; + cg->ip_ptrs[0] = (char *)name; + cg->ip_ptrs[1] = NULL; + + DEBUG_puts("1httpGetHostByName: returning domain socket address..."); + + return (&cg->hostent); + } +#endif /* AF_LOCAL */ + + for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++); + + if (!*nameptr) + { + /* + * We have an IPv4 address; break it up and provide the host entry + * to the caller. + */ + + if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4) + return (NULL); /* Must have 4 numbers */ + + if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255) + return (NULL); /* Invalid byte ranges! */ + + cg->ip_addr = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | + ip[3])); + + /* + * Fill in the host entry and return it... + */ + + cg->hostent.h_name = (char *)name; + cg->hostent.h_aliases = NULL; + cg->hostent.h_addrtype = AF_INET; + cg->hostent.h_length = 4; + cg->hostent.h_addr_list = cg->ip_ptrs; + cg->ip_ptrs[0] = (char *)&(cg->ip_addr); + cg->ip_ptrs[1] = NULL; + + DEBUG_puts("1httpGetHostByName: returning IPv4 address..."); + + return (&cg->hostent); + } + else + { + /* + * Use the gethostbyname() function to get the IPv4 address for + * the name... + */ + + DEBUG_puts("1httpGetHostByName: returning domain lookup address(es)..."); + + return (gethostbyname(name)); + } +} + + +/* + * 'httpGetHostname()' - Get the FQDN for the connection or local system. + * + * When "http" points to a connected socket, return the hostname or + * address that was used in the call to httpConnect() or httpConnectEncrypt(). + * Otherwise, return the FQDN for the local system using both gethostname() + * and gethostbyname() to get the local hostname with domain. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +const char * /* O - FQDN for connection or system */ +httpGetHostname(http_t *http, /* I - HTTP connection or NULL */ + char *s, /* I - String buffer for name */ + int slen) /* I - Size of buffer */ +{ + struct hostent *host; /* Host entry to get FQDN */ + + + if (!s || slen <= 1) + return (NULL); + + if (http) + { + if (http->hostname[0] == '/') + strlcpy(s, "localhost", slen); + else + strlcpy(s, http->hostname, slen); + } + else + { + /* + * Get the hostname... + */ + + if (gethostname(s, slen) < 0) + strlcpy(s, "localhost", slen); + + if (!strchr(s, '.')) + { + /* + * The hostname is not a FQDN, so look it up... + */ + + if ((host = gethostbyname(s)) != NULL && host->h_name) + strlcpy(s, host->h_name, slen); + } + } + + /* + * Return the hostname with as much domain info as we have... + */ + + return (s); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/http-addrlist.c b/cups/http-addrlist.c new file mode 100644 index 0000000000..d317899a48 --- /dev/null +++ b/cups/http-addrlist.c @@ -0,0 +1,661 @@ +/* + * "$Id$" + * + * HTTP address list routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * httpAddrConnect() - Connect to any of the addresses in the list. + * httpAddrFreeList() - Free an address list. + * httpAddrGetList() - Get a list of addresses for a hostname. + */ + +/* + * Include necessary headers... + */ + +#include "http-private.h" +#include "globals.h" +#include "debug.h" +#include +#include +#ifdef HAVE_RESOLV_H +# include +#endif /* HAVE_RESOLV_H */ + + +/* + * 'httpAddrConnect()' - Connect to any of the addresses in the list. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +http_addrlist_t * /* O - Connected address or NULL on failure */ +httpAddrConnect( + http_addrlist_t *addrlist, /* I - List of potential addresses */ + int *sock) /* O - Socket */ +{ + int val; /* Socket option value */ +#ifdef DEBUG + char temp[256]; /* Temporary address string */ +#endif /* DEBUG */ + + + DEBUG_printf(("httpAddrConnect(addrlist=%p, sock=%p)", addrlist, sock)); + + if (!sock) + { + errno = EINVAL; + return (NULL); + } + + /* + * Loop through each address until we connect or run out of addresses... + */ + + while (addrlist) + { + /* + * Create the socket... + */ + + DEBUG_printf(("2httpAddrConnect: Trying %s:%d...", + httpAddrString(&(addrlist->addr), temp, sizeof(temp)), + _httpAddrPort(&(addrlist->addr)))); + + if ((*sock = (int)socket(addrlist->addr.addr.sa_family, SOCK_STREAM, + 0)) < 0) + { + /* + * Don't abort yet, as this could just be an issue with the local + * system not being configured with IPv4/IPv6/domain socket enabled... + */ + + addrlist = addrlist->next; + continue; + } + + /* + * Set options... + */ + + val = 1; +#ifdef WIN32 + setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, + sizeof(val)); +#else + setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); +#endif /* WIN32 */ + +#ifdef SO_REUSEPORT + val = 1; + setsockopt(*sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); +#endif /* SO_REUSEPORT */ + +#ifdef SO_NOSIGPIPE + val = 1; + setsockopt(*sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val)); +#endif /* SO_NOSIGPIPE */ + + /* + * Using TCP_NODELAY improves responsiveness, especially on systems + * with a slow loopback interface... + */ + + val = 1; +#ifdef WIN32 + setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, + sizeof(val)); +#else + setsockopt(*sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); +#endif /* WIN32 */ + +#ifdef FD_CLOEXEC + /* + * Close this socket when starting another process... + */ + + fcntl(*sock, F_SETFD, FD_CLOEXEC); +#endif /* FD_CLOEXEC */ + + /* + * Then connect... + */ + + if (!connect(*sock, &(addrlist->addr.addr), + httpAddrLength(&(addrlist->addr)))) + { + DEBUG_printf(("1httpAddrConnect: Connected to %s:%d...", + httpAddrString(&(addrlist->addr), temp, sizeof(temp)), + _httpAddrPort(&(addrlist->addr)))); + break; + } + + DEBUG_printf(("1httpAddrConnect: Unable to connect to %s:%d: %s", + httpAddrString(&(addrlist->addr), temp, sizeof(temp)), + _httpAddrPort(&(addrlist->addr)), strerror(errno))); + + /* + * Close this socket and move to the next address... + */ + +#ifdef WIN32 + closesocket(*sock); +#else + close(*sock); +#endif /* WIN32 */ + + *sock = -1; + addrlist = addrlist->next; + } + + return (addrlist); +} + + +/* + * 'httpAddrFreeList()' - Free an address list. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +httpAddrFreeList( + http_addrlist_t *addrlist) /* I - Address list to free */ +{ + http_addrlist_t *next; /* Next address in list */ + + + /* + * Free each address in the list... + */ + + while (addrlist) + { + next = addrlist->next; + + free(addrlist); + + addrlist = next; + } +} + + +/* + * 'httpAddrGetList()' - Get a list of addresses for a hostname. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +http_addrlist_t * /* O - List of addresses or NULL */ +httpAddrGetList(const char *hostname, /* I - Hostname, IP address, or NULL for passive listen address */ + int family, /* I - Address family or AF_UNSPEC */ + const char *service) /* I - Service name or port number */ +{ + http_addrlist_t *first, /* First address in list */ + *addr, /* Current address in list */ + *temp; /* New address */ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + +#ifdef DEBUG + _cups_debug_printf("httpAddrGetList(hostname=\"%s\", family=AF_%s, " + "service=\"%s\")\n", + hostname ? hostname : "(nil)", + family == AF_UNSPEC ? "UNSPEC" : +# ifdef AF_LOCAL + family == AF_LOCAL ? "LOCAL" : +# endif /* AF_LOCAL */ +# ifdef AF_INET6 + family == AF_INET6 ? "INET6" : +# endif /* AF_INET6 */ + family == AF_INET ? "INET" : "???", service); +#endif /* DEBUG */ + +#ifdef HAVE_RES_INIT + /* + * STR #2920: Initialize resolver after failure in cups-polld + * + * If the previous lookup failed, re-initialize the resolver to prevent + * temporary network errors from persisting. This *should* be handled by + * the resolver libraries, but apparently the glibc folks do not agree. + * + * We set a flag at the end of this function if we encounter an error that + * requires reinitialization of the resolver functions. We then call + * res_init() if the flag is set on the next call here or in httpAddrLookup(). + */ + + if (cg->need_res_init) + { + res_init(); + + cg->need_res_init = 0; + } +#endif /* HAVE_RES_INIT */ + + + /* + * Lookup the address the best way we can... + */ + + first = addr = NULL; + +#ifdef AF_LOCAL + if (hostname && hostname[0] == '/') + { + /* + * Domain socket address... + */ + + if ((first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t))) != NULL) + { + first->addr.un.sun_family = AF_LOCAL; + strlcpy(first->addr.un.sun_path, hostname, sizeof(first->addr.un.sun_path)); + } + } + else +#endif /* AF_LOCAL */ + if (!hostname || strcasecmp(hostname, "localhost")) + { +#ifdef HAVE_GETADDRINFO + struct addrinfo hints, /* Address lookup hints */ + *results, /* Address lookup results */ + *current; /* Current result */ + char ipv6[64], /* IPv6 address */ + *ipv6zone; /* Pointer to zone separator */ + int ipv6len; /* Length of IPv6 address */ + int error; /* getaddrinfo() error */ + + + /* + * Lookup the address as needed... + */ + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_flags = hostname ? 0 : AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + + if (hostname && *hostname == '[') + { + /* + * Remove brackets from numeric IPv6 address... + */ + + if (!strncmp(hostname, "[v1.", 4)) + { + /* + * Copy the newer address format which supports link-local addresses... + */ + + strlcpy(ipv6, hostname + 4, sizeof(ipv6)); + if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']') + { + ipv6[ipv6len] = '\0'; + hostname = ipv6; + + /* + * Convert "+zone" in address to "%zone"... + */ + + if ((ipv6zone = strrchr(ipv6, '+')) != NULL) + *ipv6zone = '%'; + } + } + else + { + /* + * Copy the regular non-link-local IPv6 address... + */ + + strlcpy(ipv6, hostname + 1, sizeof(ipv6)); + if ((ipv6len = (int)strlen(ipv6) - 1) >= 0 && ipv6[ipv6len] == ']') + { + ipv6[ipv6len] = '\0'; + hostname = ipv6; + } + } + } + + if ((error = getaddrinfo(hostname, service, &hints, &results)) == 0) + { + /* + * Copy the results to our own address list structure... + */ + + for (current = results; current; current = current->ai_next) + if (current->ai_family == AF_INET || current->ai_family == AF_INET6) + { + /* + * Copy the address over... + */ + + temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!temp) + { + httpAddrFreeList(first); + return (NULL); + } + + if (current->ai_family == AF_INET6) + memcpy(&(temp->addr.ipv6), current->ai_addr, + sizeof(temp->addr.ipv6)); + else + memcpy(&(temp->addr.ipv4), current->ai_addr, + sizeof(temp->addr.ipv4)); + + /* + * Append the address to the list... + */ + + if (!first) + first = temp; + + if (addr) + addr->next = temp; + + addr = temp; + } + + /* + * Free the results from getaddrinfo()... + */ + + freeaddrinfo(results); + } + else if (error == EAI_FAIL) + cg->need_res_init = 1; + +#else + if (hostname) + { + int i; /* Looping vars */ + unsigned ip[4]; /* IPv4 address components */ + const char *ptr; /* Pointer into hostname */ + struct hostent *host; /* Result of lookup */ + struct servent *port; /* Port number for service */ + int portnum; /* Port number */ + + + /* + * Lookup the service... + */ + + if (!service) + portnum = 0; + else if (isdigit(*service & 255)) + portnum = atoi(service); + else if ((port = getservbyname(service, NULL)) != NULL) + portnum = ntohs(port->s_port); + else if (!strcmp(service, "http")) + portnum = 80; + else if (!strcmp(service, "https")) + portnum = 443; + else if (!strcmp(service, "ipp")) + portnum = 631; + else if (!strcmp(service, "lpd")) + portnum = 515; + else if (!strcmp(service, "socket")) + portnum = 9100; + else + return (NULL); + + /* + * This code is needed because some operating systems have a + * buggy implementation of gethostbyname() that does not support + * IPv4 addresses. If the hostname string is an IPv4 address, then + * sscanf() is used to extract the IPv4 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 (ptr = hostname; isdigit(*ptr & 255) || *ptr == '.'; ptr ++); + + if (!*ptr) + { + /* + * We have an IPv4 address; break it up and create an IPv4 address... + */ + + if (sscanf(hostname, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) == 4 && + ip[0] <= 255 && ip[1] <= 255 && ip[2] <= 255 && ip[3] <= 255) + { + first = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!first) + return (NULL); + + first->addr.ipv4.sin_family = AF_INET; + first->addr.ipv4.sin_addr.s_addr = htonl(((((((ip[0] << 8) | + ip[1]) << 8) | + ip[2]) << 8) | ip[3])); + first->addr.ipv4.sin_port = htons(portnum); + } + } + else if ((host = gethostbyname(hostname)) != NULL && +# ifdef AF_INET6 + (host->h_addrtype == AF_INET || host->h_addrtype == AF_INET6)) +# else + host->h_addrtype == AF_INET) +# endif /* AF_INET6 */ + { + for (i = 0; host->h_addr_list[i]; i ++) + { + /* + * Copy the address over... + */ + + temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!temp) + { + httpAddrFreeList(first); + return (NULL); + } + +# ifdef AF_INET6 + if (host->h_addrtype == AF_INET6) + { + temp->addr.ipv6.sin6_family = AF_INET6; + memcpy(&(temp->addr.ipv6.sin6_addr), host->h_addr_list[i], + sizeof(temp->addr.ipv6)); + temp->addr.ipv6.sin6_port = htons(portnum); + } + else +# endif /* AF_INET6 */ + { + temp->addr.ipv4.sin_family = AF_INET; + memcpy(&(temp->addr.ipv4.sin_addr), host->h_addr_list[i], + sizeof(temp->addr.ipv4)); + temp->addr.ipv4.sin_port = htons(portnum); + } + + /* + * Append the address to the list... + */ + + if (!first) + first = temp; + + if (addr) + addr->next = temp; + + addr = temp; + } + } + else if (h_errno == NO_RECOVERY) + cg->need_res_init = 1; + } +#endif /* HAVE_GETADDRINFO */ + } + + /* + * Detect some common errors and handle them sanely... + */ + + if (!addr && (!hostname || !strcasecmp(hostname, "localhost"))) + { + struct servent *port; /* Port number for service */ + int portnum; /* Port number */ + + + /* + * Lookup the service... + */ + + if (!service) + portnum = 0; + else if (isdigit(*service & 255)) + portnum = atoi(service); + else if ((port = getservbyname(service, NULL)) != NULL) + portnum = ntohs(port->s_port); + else if (!strcmp(service, "http")) + portnum = 80; + else if (!strcmp(service, "https")) + portnum = 443; + else if (!strcmp(service, "ipp")) + portnum = 631; + else if (!strcmp(service, "lpd")) + portnum = 515; + else if (!strcmp(service, "socket")) + portnum = 9100; + else + return (NULL); + + if (hostname && !strcasecmp(hostname, "localhost")) + { + /* + * Unfortunately, some users ignore all of the warnings in the + * /etc/hosts file and delete "localhost" from it. If we get here + * then we were unable to resolve the name, so use the IPv6 and/or + * IPv4 loopback interface addresses... + */ + +#ifdef AF_INET6 + if (family != AF_INET) + { + /* + * Add [::1] to the address list... + */ + + temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!temp) + { + httpAddrFreeList(first); + return (NULL); + } + + temp->addr.ipv6.sin6_family = AF_INET6; + temp->addr.ipv6.sin6_port = htons(portnum); +# ifdef WIN32 + temp->addr.ipv6.sin6_addr.u.Byte[15] = 1; +# else + temp->addr.ipv6.sin6_addr.s6_addr32[3] = htonl(1); +# endif /* WIN32 */ + + if (!first) + first = temp; + + addr = temp; + } + + if (family != AF_INET6) +#endif /* AF_INET6 */ + { + /* + * Add 127.0.0.1 to the address list... + */ + + temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!temp) + { + httpAddrFreeList(first); + return (NULL); + } + + temp->addr.ipv4.sin_family = AF_INET; + temp->addr.ipv4.sin_port = htons(portnum); + temp->addr.ipv4.sin_addr.s_addr = htonl(0x7f000001); + + if (!first) + first = temp; + + if (addr) + addr->next = temp; + } + } + else if (!hostname) + { + /* + * Provide one or more passive listening addresses... + */ + +#ifdef AF_INET6 + if (family != AF_INET) + { + /* + * Add [::] to the address list... + */ + + temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!temp) + { + httpAddrFreeList(first); + return (NULL); + } + + temp->addr.ipv6.sin6_family = AF_INET6; + temp->addr.ipv6.sin6_port = htons(portnum); + + if (!first) + first = temp; + + addr = temp; + } + + if (family != AF_INET6) +#endif /* AF_INET6 */ + { + /* + * Add 0.0.0.0 to the address list... + */ + + temp = (http_addrlist_t *)calloc(1, sizeof(http_addrlist_t)); + if (!temp) + { + httpAddrFreeList(first); + return (NULL); + } + + temp->addr.ipv4.sin_family = AF_INET; + temp->addr.ipv4.sin_port = htons(portnum); + + if (!first) + first = temp; + + if (addr) + addr->next = temp; + } + } + } + + /* + * Return the address list... + */ + + return (first); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/http-private.h b/cups/http-private.h new file mode 100644 index 0000000000..a705d71901 --- /dev/null +++ b/cups/http-private.h @@ -0,0 +1,278 @@ +/* + * "$Id$" + * + * Private HTTP definitions for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_HTTP_PRIVATE_H_ +# define _CUPS_HTTP_PRIVATE_H_ + +/* + * Include necessary headers... + */ + +# include +# include + +# ifdef __sun +# include +# endif /* __sun */ + +# include +# ifdef WIN32 +# include +# include +# else +# include +# include +# include +# define closesocket(f) close(f) +# endif /* WIN32 */ + +# ifdef HAVE_GSSAPI +# ifdef HAVE_GSSAPI_GSSAPI_H +# include +# endif /* HAVE_GSSAPI_GSSAPI_H */ +# ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H +# include +# endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */ +# ifdef HAVE_GSSAPI_GSSAPI_KRB5_H +# include +# endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */ +# ifdef HAVE_GSSAPI_H +# include +# endif /* HAVE_GSSAPI_H */ +# ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE +# define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name +# endif /* !HAVE_GSS_C_NT_HOSTBASED_SERVICE */ +# ifdef HAVE_KRB5_H +# include +# endif /* HAVE_KRB5_H */ +# endif /* HAVE_GSSAPI */ + +# ifdef HAVE_AUTHORIZATION_H +# include +# endif /* HAVE_AUTHORIZATION_H */ + +# if defined(__sgi) || (defined(__APPLE__) && !defined(_SOCKLEN_T)) +/* + * IRIX and MacOS X 10.2.x do not define socklen_t, and in fact use an int instead of + * unsigned type for length values... + */ + +typedef int socklen_t; +# endif /* __sgi || (__APPLE__ && !_SOCKLEN_T) */ + +# include "http.h" +# include "md5.h" +# include "ipp-private.h" + +# if defined HAVE_LIBSSL +/* + * The OpenSSL library provides its own SSL/TLS context structure for its + * IO and protocol management. However, we need to provide our own BIO + * (basic IO) implementation to do timeouts... + */ + +# include +# include +# include + +typedef SSL http_tls_t; + +extern BIO_METHOD *_httpBIOMethods(void); + +# elif defined HAVE_GNUTLS +/* + * The GNU TLS library is more of a "bare metal" SSL/TLS library... + */ +# include +# include + +typedef struct +{ + gnutls_session session; /* GNU TLS session object */ + void *credentials; /* GNU TLS credentials object */ +} http_tls_t; + +extern ssize_t _httpReadGNUTLS(gnutls_transport_ptr ptr, void *data, + size_t length); +extern ssize_t _httpWriteGNUTLS(gnutls_transport_ptr ptr, const void *data, + size_t length); + +# elif defined(HAVE_CDSASSL) +/* + * Darwin's Security framework provides its own SSL/TLS context structure + * for its IO and protocol management... + */ + +# include + +typedef struct /**** CDSA connection information ****/ +{ + SSLContextRef session; /* CDSA session object */ + CFArrayRef certsArray; /* Certificates array */ +} http_tls_t; + +extern OSStatus _httpReadCDSA(SSLConnectionRef connection, void *data, + size_t *dataLength); +extern OSStatus _httpWriteCDSA(SSLConnectionRef connection, const void *data, + size_t *dataLength); +# endif /* HAVE_LIBSSL */ + + +struct _http_s /**** HTTP connection structure. ****/ +{ + 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 @deprecated@ */ + 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 @deprecated@ */ + int used; /* Number of bytes used in buffer */ + char buffer[HTTP_MAX_BUFFER]; + /* Buffer for incoming data */ + int auth_type; /* Authentication in use */ + _cups_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 */ + /**** New in CUPS 1.1.19 ****/ + fd_set *input_set; /* select() set for httpWait() @deprecated@ */ + http_status_t expect; /* Expect: header @since CUPS 1.1.19@ */ + char *cookie; /* Cookie value(s) @since CUPS 1.1.19@ */ + /**** New in CUPS 1.1.20 ****/ + char _authstring[HTTP_MAX_VALUE], + /* Current Authentication value. @deprecated@ */ + userpass[HTTP_MAX_VALUE]; + /* Username:password string @since CUPS 1.1.20@ */ + int digest_tries; /* Number of tries for digest auth @since CUPS 1.1.20@ */ + /**** New in CUPS 1.2 ****/ + off_t data_remaining; /* Number of bytes left @since CUPS 1.2@ */ + http_addr_t *hostaddr; /* Current host address and port @since CUPS 1.2@ */ + http_addrlist_t *addrlist; /* List of valid addresses @since CUPS 1.2@ */ + char wbuffer[HTTP_MAX_BUFFER]; + /* Buffer for outgoing data */ + int wused; /* Write buffer bytes used @since CUPS 1.2@ */ + /**** New in CUPS 1.3 ****/ + char *field_authorization; + /* Authorization field @since CUPS 1.3@ */ + char *authstring; /* Current authorization field @since CUPS 1.3 */ +# ifdef HAVE_GSSAPI + gss_OID gssmech; /* Authentication mechanism @since CUPS 1.3@ */ + gss_ctx_id_t gssctx; /* Authentication context @since CUPS 1.3@ */ + gss_name_t gssname; /* Authentication server name @since CUPS 1.3@ */ +# endif /* HAVE_GSSAPI */ +# ifdef HAVE_AUTHORIZATION_H + AuthorizationRef auth_ref; /* Authorization ref */ +# endif /* HAVE_AUTHORIZATION_H */ +}; + + +/* + * Some OS's don't have hstrerror(), most notably Solaris... + */ + +# ifndef HAVE_HSTRERROR +extern const char *_cups_hstrerror(int error); +# define hstrerror _cups_hstrerror +# elif defined(_AIX) || defined(__osf__) +/* + * AIX and Tru64 UNIX don't provide a prototype but do provide the function... + */ +extern const char *hstrerror(int error); +# endif /* !HAVE_HSTRERROR */ + + +/* + * Some OS's don't have getifaddrs() and freeifaddrs()... + */ + +# ifndef WIN32 +# include +# ifdef HAVE_GETIFADDRS +# include +# else +# include +# ifdef HAVE_SYS_SOCKIO_H +# include +# endif /* HAVE_SYS_SOCKIO_H */ + +# 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 */ + union + { + struct sockaddr *ifu_broadaddr; /* Broadcast address of this interface. */ + struct sockaddr *ifu_dstaddr; /* Point-to-point destination address. */ + } ifa_ifu; + + void *ifa_data; /* Interface statistics */ +}; + +# ifndef ifa_broadaddr +# define ifa_broadaddr ifa_ifu.ifu_broadaddr +# endif /* !ifa_broadaddr */ +# ifndef ifa_dstaddr +# define ifa_dstaddr ifa_ifu.ifu_dstaddr +# endif /* !ifa_dstaddr */ + +extern int _cups_getifaddrs(struct ifaddrs **addrs); +# define getifaddrs _cups_getifaddrs +extern void _cups_freeifaddrs(struct ifaddrs *addrs); +# define freeifaddrs _cups_freeifaddrs +# endif /* HAVE_GETIFADDRS */ +# endif /* !WIN32 */ + +/* + * Prototypes... + */ + +extern int _httpAddrPort(http_addr_t *addr); +extern http_t *_httpCreate(const char *host, int port, + http_encryption_t encryption); +extern char *_httpEncodeURI(char *dst, const char *src, + size_t dstsize); +extern const char *_httpResolveURI(const char *uri, char *resolved_uri, + size_t resolved_size, int log); +extern int _httpUpdate(http_t *http, http_status_t *status); +extern int _httpWait(http_t *http, int msec, int usessl); +#endif /* !_CUPS_HTTP_PRIVATE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/http-support.c b/cups/http-support.c new file mode 100644 index 0000000000..5f723ba0f8 --- /dev/null +++ b/cups/http-support.c @@ -0,0 +1,1728 @@ +/* + * "$Id$" + * + * HTTP support routines for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * httpAssembleURI() - Assemble a uniform resource identifier from its + * components. + * httpAssembleURIf() - Assemble a uniform resource identifier from its + * components with a formatted resource. + * httpDecode64() - Base64-decode a string. + * httpDecode64_2() - Base64-decode a string. + * httpEncode64() - Base64-encode a string. + * httpEncode64_2() - Base64-encode a string. + * httpGetDateString() - Get a formatted date/time string from a time value. + * httpGetDateString2() - Get a formatted date/time string from a time value. + * httpGetDateTime() - Get a time value from a formatted date/time string. + * httpSeparate() - Separate a Universal Resource Identifier into its + * components. + * httpSeparate2() - Separate a Universal Resource Identifier into its + * components. + * httpSeparateURI() - Separate a Universal Resource Identifier into its + * components. + * httpStatus() - Return a short string describing a HTTP status code. + * _cups_hstrerror() - hstrerror() emulation function for Solaris and + * others... + * _httpEncodeURI() - Percent-encode a HTTP request URI. + * _httpResolveURI() - Resolve a DNS-SD URI. + * http_copy_decode() - Copy and decode a URI. + * http_copy_encode() - Copy and encode a URI. + * resolve_callback() - Build a device URI for the given service name. + */ + +/* + * Include necessary headers... + */ + +#include "debug.h" +#include "globals.h" +#include +#include +#ifdef HAVE_DNSSD +# include +# include +#endif /* HAVE_DNSSD */ + + +/* + * Local types... + */ + +typedef struct _http_uribuf_s /* URI buffer */ +{ + char *buffer; /* Pointer to buffer */ + size_t bufsize; /* Size of buffer */ +} _http_uribuf_t; + + +/* + * Local globals... + */ + +static const char * const http_days[7] = + { + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat" + }; +static const char * const http_months[12] = + { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + }; + + +/* + * Local functions... + */ + +static const char *http_copy_decode(char *dst, const char *src, + int dstsize, const char *term, + int decode); +static char *http_copy_encode(char *dst, const char *src, + char *dstend, const char *reserved, + const char *term, int encode); +#ifdef HAVE_DNSSD +static void resolve_callback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *fullName, + const char *hostTarget, + uint16_t port, uint16_t txtLen, + const unsigned char *txtRecord, + void *context); +#endif /* HAVE_DNSSD */ + + +/* + * 'httpAssembleURI()' - Assemble a uniform resource identifier from its + * components. + * + * This function escapes reserved characters in the URI depending on the + * value of the "encoding" argument. You should use this function in + * place of traditional string functions whenever you need to create a + * URI string. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +http_uri_status_t /* O - URI status */ +httpAssembleURI( + http_uri_coding_t encoding, /* I - Encoding flags */ + char *uri, /* I - URI buffer */ + int urilen, /* I - Size of URI buffer */ + const char *scheme, /* I - Scheme name */ + const char *username, /* I - Username */ + const char *host, /* I - Hostname or address */ + int port, /* I - Port number */ + const char *resource) /* I - Resource */ +{ + char *ptr, /* Pointer into URI buffer */ + *end; /* End of URI buffer */ + + + /* + * Range check input... + */ + + if (!uri || urilen < 1 || !scheme || port < 0) + { + if (uri) + *uri = '\0'; + + return (HTTP_URI_BAD_ARGUMENTS); + } + + /* + * Assemble the URI starting with the scheme... + */ + + end = uri + urilen - 1; + ptr = http_copy_encode(uri, scheme, end, NULL, NULL, 0); + + if (!ptr) + goto assemble_overflow; + + if (!strcmp(scheme, "mailto")) + { + /* + * mailto: only has :, no //... + */ + + if (ptr < end) + *ptr++ = ':'; + else + goto assemble_overflow; + } + else + { + /* + * Schemes other than mailto: all have //... + */ + + if ((ptr + 2) < end) + { + *ptr++ = ':'; + *ptr++ = '/'; + *ptr++ = '/'; + } + else + goto assemble_overflow; + } + + /* + * Next the username and hostname, if any... + */ + + if (host) + { + if (username && *username) + { + /* + * Add username@ first... + */ + + ptr = http_copy_encode(ptr, username, end, "/?@", NULL, + encoding & HTTP_URI_CODING_USERNAME); + + if (!ptr) + goto assemble_overflow; + + if (ptr < end) + *ptr++ = '@'; + else + goto assemble_overflow; + } + + /* + * Then add the hostname. Since IPv6 is a particular pain to deal + * with, we have several special cases to deal with. If we get + * an IPv6 address with brackets around it, assume it is already in + * URI format. Since DNS-SD service names can sometimes look like + * raw IPv6 addresses, we specifically look for "._tcp" in the name, + * too... + */ + + if (host[0] != '[' && strchr(host, ':') && !strstr(host, "._tcp")) + { + /* + * We have a raw IPv6 address... + */ + + if (strchr(host, '%')) + { + /* + * We have a link-local address, add "[v1." prefix... + */ + + if ((ptr + 4) < end) + { + *ptr++ = '['; + *ptr++ = 'v'; + *ptr++ = '1'; + *ptr++ = '.'; + } + else + goto assemble_overflow; + } + else + { + /* + * We have a normal address, add "[" prefix... + */ + + if (ptr < end) + *ptr++ = '['; + else + goto assemble_overflow; + } + + /* + * Copy the rest of the IPv6 address, and terminate with "]". + */ + + while (ptr < end && *host) + { + if (*host == '%') + { + *ptr++ = '+'; /* Convert zone separator */ + host ++; + } + else + *ptr++ = *host++; + } + + if (*host) + goto assemble_overflow; + + if (ptr < end) + *ptr++ = ']'; + else + goto assemble_overflow; + } + else + { + /* + * Otherwise, just copy the host string... + */ + + ptr = http_copy_encode(ptr, host, end, ":/?#[]@\\", NULL, + encoding & HTTP_URI_CODING_HOSTNAME); + + if (!ptr) + goto assemble_overflow; + } + + /* + * Finish things off with the port number... + */ + + if (port > 0) + { + snprintf(ptr, end - ptr + 1, ":%d", port); + ptr += strlen(ptr); + + if (ptr >= end) + goto assemble_overflow; + } + } + + /* + * Last but not least, add the resource string... + */ + + if (resource) + { + char *query; /* Pointer to query string */ + + + /* + * Copy the resource string up to the query string if present... + */ + + query = strchr(resource, '?'); + ptr = http_copy_encode(ptr, resource, end, NULL, "?", + encoding & HTTP_URI_CODING_RESOURCE); + if (!ptr) + goto assemble_overflow; + + if (query) + { + /* + * Copy query string without encoding... + */ + + ptr = http_copy_encode(ptr, query, end, NULL, NULL, + encoding & HTTP_URI_CODING_QUERY); + if (!ptr) + goto assemble_overflow; + } + } + else if (ptr < end) + *ptr++ = '/'; + else + goto assemble_overflow; + + /* + * Nul-terminate the URI buffer and return with no errors... + */ + + *ptr = '\0'; + + return (HTTP_URI_OK); + + /* + * Clear the URI string and return an overflow error; I don't usually + * like goto's, but in this case it makes sense... + */ + + assemble_overflow: + + *uri = '\0'; + return (HTTP_URI_OVERFLOW); +} + + +/* + * 'httpAssembleURIf()' - Assemble a uniform resource identifier from its + * components with a formatted resource. + * + * This function creates a formatted version of the resource string + * argument "resourcef" and escapes reserved characters in the URI + * depending on the value of the "encoding" argument. You should use + * this function in place of traditional string functions whenever + * you need to create a URI string. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +http_uri_status_t /* O - URI status */ +httpAssembleURIf( + http_uri_coding_t encoding, /* I - Encoding flags */ + char *uri, /* I - URI buffer */ + int urilen, /* I - Size of URI buffer */ + const char *scheme, /* I - Scheme name */ + const char *username, /* I - Username */ + const char *host, /* I - Hostname or address */ + int port, /* I - Port number */ + const char *resourcef, /* I - Printf-style resource */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to additional arguments */ + char resource[1024]; /* Formatted resource string */ + int bytes; /* Bytes in formatted string */ + + + /* + * Range check input... + */ + + if (!uri || urilen < 1 || !scheme || port < 0 || !resourcef) + { + if (uri) + *uri = '\0'; + + return (HTTP_URI_BAD_ARGUMENTS); + } + + /* + * Format the resource string and assemble the URI... + */ + + va_start(ap, resourcef); + bytes = vsnprintf(resource, sizeof(resource), resourcef, ap); + va_end(ap); + + if (bytes >= sizeof(resource)) + { + *uri = '\0'; + return (HTTP_URI_OVERFLOW); + } + else + return (httpAssembleURI(encoding, uri, urilen, scheme, username, host, + port, resource)); +} + + +/* + * 'httpDecode64()' - Base64-decode a string. + * + * This function is deprecated. Use the httpDecode64_2() function instead + * which provides buffer length arguments. + * + * @deprecated@ + */ + +char * /* O - Decoded string */ +httpDecode64(char *out, /* I - String to write to */ + const char *in) /* I - String to read from */ +{ + int outlen; /* Output buffer length */ + + + /* + * Use the old maximum buffer size for binary compatibility... + */ + + outlen = 512; + + return (httpDecode64_2(out, &outlen, in)); +} + + +/* + * 'httpDecode64_2()' - Base64-decode a string. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +char * /* O - Decoded string */ +httpDecode64_2(char *out, /* I - String to write to */ + int *outlen, /* IO - Size of output string */ + const char *in) /* I - String to read from */ +{ + int pos, /* Bit position */ + base64; /* Value of this character */ + char *outptr, /* Output pointer */ + *outend; /* End of output buffer */ + + + /* + * Range check input... + */ + + if (!out || !outlen || *outlen < 1 || !in) + return (NULL); + + if (!*in) + { + *out = '\0'; + *outlen = 0; + + return (out); + } + + /* + * Convert from base-64 to bytes... + */ + + for (outptr = out, outend = out + *outlen - 1, 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 : + if (outptr < outend) + *outptr = base64 << 2; + pos ++; + break; + case 1 : + if (outptr < outend) + *outptr++ |= (base64 >> 4) & 3; + if (outptr < outend) + *outptr = (base64 << 4) & 255; + pos ++; + break; + case 2 : + if (outptr < outend) + *outptr++ |= (base64 >> 2) & 15; + if (outptr < outend) + *outptr = (base64 << 6) & 255; + pos ++; + break; + case 3 : + if (outptr < outend) + *outptr++ |= base64; + pos = 0; + break; + } + } + + *outptr = '\0'; + + /* + * Return the decoded string and size... + */ + + *outlen = (int)(outptr - out); + + return (out); +} + + +/* + * 'httpEncode64()' - Base64-encode a string. + * + * This function is deprecated. Use the httpEncode64_2() function instead + * which provides buffer length arguments. + * + * @deprecated@ + */ + +char * /* O - Encoded string */ +httpEncode64(char *out, /* I - String to write to */ + const char *in) /* I - String to read from */ +{ + return (httpEncode64_2(out, 512, in, (int)strlen(in))); +} + + +/* + * 'httpEncode64_2()' - Base64-encode a string. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +char * /* O - Encoded string */ +httpEncode64_2(char *out, /* I - String to write to */ + int outlen, /* I - Size of output string */ + const char *in, /* I - String to read from */ + int inlen) /* I - Size of input string */ +{ + char *outptr, /* Output pointer */ + *outend; /* End of output buffer */ + static const char base64[] = /* Base64 characters... */ + { + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/" + }; + + + /* + * Range check input... + */ + + if (!out || outlen < 1 || !in) + return (NULL); + + /* + * Convert bytes to base-64... + */ + + for (outptr = out, outend = out + outlen - 1; inlen > 0; in ++, inlen --) + { + /* + * Encode the up to 3 characters as 4 Base64 numbers... + */ + + if (outptr < outend) + *outptr ++ = base64[(in[0] & 255) >> 2]; + + if (outptr < outend) + { + if (inlen > 1) + *outptr ++ = base64[(((in[0] & 255) << 4) | ((in[1] & 255) >> 4)) & 63]; + else + *outptr ++ = base64[((in[0] & 255) << 4) & 63]; + } + + in ++; + inlen --; + if (inlen <= 0) + { + if (outptr < outend) + *outptr ++ = '='; + if (outptr < outend) + *outptr ++ = '='; + break; + } + + if (outptr < outend) + { + if (inlen > 1) + *outptr ++ = base64[(((in[0] & 255) << 2) | ((in[1] & 255) >> 6)) & 63]; + else + *outptr ++ = base64[((in[0] & 255) << 2) & 63]; + } + + in ++; + inlen --; + if (inlen <= 0) + { + if (outptr < outend) + *outptr ++ = '='; + break; + } + + if (outptr < outend) + *outptr ++ = base64[in[0] & 63]; + } + + *outptr = '\0'; + + /* + * Return the encoded string... + */ + + return (out); +} + + +/* + * 'httpGetDateString()' - Get a formatted date/time string from a time value. + * + * @deprecated@ + */ + +const char * /* O - Date/time string */ +httpGetDateString(time_t t) /* I - UNIX time */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + return (httpGetDateString2(t, cg->http_date, sizeof(cg->http_date))); +} + + +/* + * 'httpGetDateString2()' - Get a formatted date/time string from a time value. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +const char * /* O - Date/time string */ +httpGetDateString2(time_t t, /* I - UNIX time */ + char *s, /* I - String buffer */ + int slen) /* I - Size of string buffer */ +{ + struct tm *tdate; /* UNIX date/time data */ + + + tdate = gmtime(&t); + snprintf(s, slen, "%s, %02d %s %d %02d:%02d:%02d GMT", + http_days[tdate->tm_wday], tdate->tm_mday, + http_months[tdate->tm_mon], tdate->tm_year + 1900, + tdate->tm_hour, tdate->tm_min, tdate->tm_sec); + + return (s); +} + + +/* + * '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 */ + char mon[16]; /* Abbreviated month name */ + int day, year; /* Day of month and year */ + int hour, min, sec; /* Time */ + int days; /* Number of days since 1970 */ + static const int normal_days[] = /* Days to a month, normal years */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; + static const int leap_days[] = /* Days to a month, leap years */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; + + + DEBUG_printf(("2httpGetDateTime(s=\"%s\")", s)); + + /* + * Extract the date and time from the formatted string... + */ + + if (sscanf(s, "%*s%d%15s%d%d:%d:%d", &day, mon, &year, &hour, &min, &sec) < 6) + return (0); + + DEBUG_printf(("4httpGetDateTime: day=%d, mon=\"%s\", year=%d, hour=%d, " + "min=%d, sec=%d", day, mon, year, hour, min, sec)); + + /* + * Convert the month name to a number from 0 to 11. + */ + + for (i = 0; i < 12; i ++) + if (!strcasecmp(mon, http_months[i])) + break; + + if (i >= 12) + return (0); + + DEBUG_printf(("4httpGetDateTime: i=%d", i)); + + /* + * Now convert the date and time to a UNIX time value in seconds since + * 1970. We can't use mktime() since the timezone may not be UTC but + * the date/time string *is* UTC. + */ + + if ((year & 3) == 0 && ((year % 100) != 0 || (year % 400) == 0)) + days = leap_days[i] + day - 1; + else + days = normal_days[i] + day - 1; + + DEBUG_printf(("4httpGetDateTime: days=%d", days)); + + days += (year - 1970) * 365 + /* 365 days per year (normally) */ + ((year - 1) / 4 - 492) - /* + leap days */ + ((year - 1) / 100 - 19) + /* - 100 year days */ + ((year - 1) / 400 - 4); /* + 400 year days */ + + DEBUG_printf(("4httpGetDateTime: days=%d\n", days)); + + return (days * 86400 + hour * 3600 + min * 60 + sec); +} + + +/* + * 'httpSeparate()' - Separate a Universal Resource Identifier into its + * components. + * + * This function is deprecated; use the httpSeparateURI() function instead. + * + * @deprecated@ + */ + +void +httpSeparate(const char *uri, /* I - Universal Resource Identifier */ + char *scheme, /* O - Scheme [32] (http, https, etc.) */ + char *username, /* O - Username [1024] */ + char *host, /* O - Hostname [1024] */ + int *port, /* O - Port number to use */ + char *resource) /* O - Resource/filename [1024] */ +{ + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, 32, username, + HTTP_MAX_URI, host, HTTP_MAX_URI, port, resource, + HTTP_MAX_URI); +} + + +/* + * 'httpSeparate2()' - Separate a Universal Resource Identifier into its + * components. + * + * This function is deprecated; use the httpSeparateURI() function instead. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + * @deprecated@ + */ + +void +httpSeparate2(const char *uri, /* I - Universal Resource Identifier */ + char *scheme, /* O - Scheme (http, https, etc.) */ + int schemelen, /* I - Size of scheme buffer */ + char *username, /* O - Username */ + int usernamelen, /* I - Size of username buffer */ + char *host, /* O - Hostname */ + int hostlen, /* I - Size of hostname buffer */ + int *port, /* O - Port number to use */ + char *resource, /* O - Resource/filename */ + int resourcelen) /* I - Size of resource buffer */ +{ + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, schemelen, username, + usernamelen, host, hostlen, port, resource, resourcelen); +} + + +/* + * 'httpSeparateURI()' - Separate a Universal Resource Identifier into its + * components. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +http_uri_status_t /* O - Result of separation */ +httpSeparateURI( + http_uri_coding_t decoding, /* I - Decoding flags */ + const char *uri, /* I - Universal Resource Identifier */ + char *scheme, /* O - Scheme (http, https, etc.) */ + int schemelen, /* I - Size of scheme buffer */ + char *username, /* O - Username */ + int usernamelen, /* I - Size of username buffer */ + char *host, /* O - Hostname */ + int hostlen, /* I - Size of hostname buffer */ + int *port, /* O - Port number to use */ + char *resource, /* O - Resource/filename */ + int resourcelen) /* I - Size of resource buffer */ +{ + char *ptr, /* Pointer into string... */ + *end; /* End of string */ + const char *sep; /* Separator character */ + http_uri_status_t status; /* Result of separation */ + + + /* + * Initialize everything to blank... + */ + + if (scheme && schemelen > 0) + *scheme = '\0'; + + if (username && usernamelen > 0) + *username = '\0'; + + if (host && hostlen > 0) + *host = '\0'; + + if (port) + *port = 0; + + if (resource && resourcelen > 0) + *resource = '\0'; + + /* + * Range check input... + */ + + if (!uri || !port || !scheme || schemelen <= 0 || !username || + usernamelen <= 0 || !host || hostlen <= 0 || !resource || + resourcelen <= 0) + return (HTTP_URI_BAD_ARGUMENTS); + + if (!*uri) + return (HTTP_URI_BAD_URI); + + /* + * Grab the scheme portion of the URI... + */ + + status = HTTP_URI_OK; + + if (!strncmp(uri, "//", 2)) + { + /* + * Workaround for HP IPP client bug... + */ + + strlcpy(scheme, "ipp", schemelen); + status = HTTP_URI_MISSING_SCHEME; + } + else if (*uri == '/') + { + /* + * Filename... + */ + + strlcpy(scheme, "file", schemelen); + status = HTTP_URI_MISSING_SCHEME; + } + else + { + /* + * Standard URI with scheme... + */ + + for (ptr = scheme, end = scheme + schemelen - 1; + *uri && *uri != ':' && ptr < end;) + if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-+.", *uri) != NULL) + *ptr++ = *uri++; + else + break; + + *ptr = '\0'; + + if (*uri != ':') + { + *scheme = '\0'; + return (HTTP_URI_BAD_SCHEME); + } + + uri ++; + } + + /* + * Set the default port number... + */ + + if (!strcmp(scheme, "http")) + *port = 80; + else if (!strcmp(scheme, "https")) + *port = 443; + else if (!strcmp(scheme, "ipp")) + *port = 631; + else if (!strcasecmp(scheme, "lpd")) + *port = 515; + else if (!strcmp(scheme, "socket")) /* Not yet registered with IANA... */ + *port = 9100; + else if (strcmp(scheme, "file") && strcmp(scheme, "mailto")) + status = HTTP_URI_UNKNOWN_SCHEME; + + /* + * Now see if we have a hostname... + */ + + if (!strncmp(uri, "//", 2)) + { + /* + * Yes, extract it... + */ + + uri += 2; + + /* + * Grab the username, if any... + */ + + if ((sep = strpbrk(uri, "@/")) != NULL && *sep == '@') + { + /* + * Get a username:password combo... + */ + + uri = http_copy_decode(username, uri, usernamelen, "@", + decoding & HTTP_URI_CODING_USERNAME); + + if (!uri) + { + *username = '\0'; + return (HTTP_URI_BAD_USERNAME); + } + + uri ++; + } + + /* + * Then the hostname/IP address... + */ + + if (*uri == '[') + { + /* + * Grab IPv6 address... + */ + + uri ++; + if (!strncmp(uri, "v1.", 3)) + uri += 3; /* Skip IPvN leader... */ + + uri = http_copy_decode(host, uri, hostlen, "]", + decoding & HTTP_URI_CODING_HOSTNAME); + + if (!uri) + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + + /* + * Validate value... + */ + + if (*uri != ']') + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + + uri ++; + + for (ptr = host; *ptr; ptr ++) + if (*ptr == '+') + { + /* + * Convert zone separator to % and stop here... + */ + + *ptr = '%'; + break; + } + else if (*ptr != ':' && *ptr != '.' && !isxdigit(*ptr & 255)) + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + } + else + { + /* + * Validate the hostname or IPv4 address first... + */ + + for (ptr = (char *)uri; *ptr; ptr ++) + if (strchr(":?/", *ptr)) + break; + else if (!strchr("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "-._~" + "%" + "!$&'()*+,;=\\", *ptr)) + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + + /* + * Then copy the hostname or IPv4 address to the buffer... + */ + + uri = http_copy_decode(host, uri, hostlen, ":?/", + decoding & HTTP_URI_CODING_HOSTNAME); + + if (!uri) + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + } + + /* + * Validate hostname for file scheme - only empty and localhost are + * acceptable. + */ + + if (!strcmp(scheme, "file") && strcmp(host, "localhost") && host[0]) + { + *host = '\0'; + return (HTTP_URI_BAD_HOSTNAME); + } + + /* + * See if we have a port number... + */ + + if (*uri == ':') + { + /* + * Yes, collect the port number... + */ + + if (!isdigit(uri[1] & 255)) + { + *port = 0; + return (HTTP_URI_BAD_PORT); + } + + *port = strtol(uri + 1, (char **)&uri, 10); + + if (*uri != '/' && *uri) + { + *port = 0; + return (HTTP_URI_BAD_PORT); + } + } + } + + /* + * The remaining portion is the resource string... + */ + + if (*uri == '?' || !*uri) + { + /* + * Hostname but no path... + */ + + status = HTTP_URI_MISSING_RESOURCE; + *resource = '/'; + + /* + * Copy any query string... + */ + + if (*uri == '?') + uri = http_copy_decode(resource + 1, uri, resourcelen - 1, NULL, + decoding & HTTP_URI_CODING_QUERY); + else + resource[1] = '\0'; + } + else + { + uri = http_copy_decode(resource, uri, resourcelen, "?", + decoding & HTTP_URI_CODING_RESOURCE); + + if (uri && *uri == '?') + { + /* + * Concatenate any query string... + */ + + char *resptr = resource + strlen(resource); + + uri = http_copy_decode(resptr, uri, resourcelen - (int)(resptr - resource), + NULL, decoding & HTTP_URI_CODING_QUERY); + } + } + + if (!uri) + { + *resource = '\0'; + return (HTTP_URI_BAD_RESOURCE); + } + + /* + * Return the URI separation status... + */ + + return (status); +} + + +/* + * 'httpStatus()' - Return a short string describing a HTTP status code. + * + * The returned string is localized to the current POSIX locale and is based + * on the status strings defined in RFC 2616. + */ + +const char * /* O - Localized status string */ +httpStatus(http_status_t status) /* I - HTTP status code */ +{ + const char *s; /* Status string */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + switch (status) + { + case HTTP_CONTINUE : + s = _("Continue"); + break; + case HTTP_SWITCHING_PROTOCOLS : + s = _("Switching Protocols"); + break; + case HTTP_OK : + s = _("OK"); + break; + case HTTP_CREATED : + s = _("Created"); + break; + case HTTP_ACCEPTED : + s = _("Accepted"); + break; + case HTTP_NO_CONTENT : + s = _("No Content"); + break; + case HTTP_MOVED_PERMANENTLY : + s = _("Moved Permanently"); + break; + case HTTP_SEE_OTHER : + s = _("See Other"); + break; + case HTTP_NOT_MODIFIED : + s = _("Not Modified"); + break; + case HTTP_BAD_REQUEST : + s = _("Bad Request"); + break; + case HTTP_UNAUTHORIZED : + case HTTP_AUTHORIZATION_CANCELED : + s = _("Unauthorized"); + break; + case HTTP_FORBIDDEN : + s = _("Forbidden"); + break; + case HTTP_NOT_FOUND : + s = _("Not Found"); + break; + case HTTP_REQUEST_TOO_LARGE : + s = _("Request Entity Too Large"); + break; + case HTTP_URI_TOO_LONG : + s = _("URI Too Long"); + break; + case HTTP_UPGRADE_REQUIRED : + s = _("Upgrade Required"); + break; + case HTTP_NOT_IMPLEMENTED : + s = _("Not Implemented"); + break; + case HTTP_NOT_SUPPORTED : + s = _("Not Supported"); + break; + case HTTP_EXPECTATION_FAILED : + s = _("Expectation Failed"); + break; + case HTTP_SERVICE_UNAVAILABLE : + s = _("Service Unavailable"); + break; + case HTTP_SERVER_ERROR : + s = _("Internal Server Error"); + break; + + default : + s = _("Unknown"); + break; + } + + return (_cupsLangString(cg->lang_default, s)); +} + + +#ifndef HAVE_HSTRERROR +/* + * '_cups_hstrerror()' - hstrerror() emulation function for Solaris and others... + */ + +const char * /* O - Error string */ +_cups_hstrerror(int error) /* I - Error number */ +{ + static const char * const errors[] = /* Error strings */ + { + "OK", + "Host not found.", + "Try again.", + "Unrecoverable lookup error.", + "No data associated with name." + }; + + + if (error < 0 || error > 4) + return ("Unknown hostname lookup error."); + else + return (errors[error]); +} +#endif /* !HAVE_HSTRERROR */ + + +/* + * '_httpEncodeURI()' - Percent-encode a HTTP request URI. + */ + +char * /* O - Encoded URI */ +_httpEncodeURI(char *dst, /* I - Destination buffer */ + const char *src, /* I - Source URI */ + size_t dstsize) /* I - Size of destination buffer */ +{ + http_copy_encode(dst, src, dst + dstsize - 1, NULL, NULL, 1); + return (dst); +} + + +/* + * '_httpResolveURI()' - Resolve a DNS-SD URI. + */ + +const char * /* O - Resolved URI */ +_httpResolveURI( + const char *uri, /* I - DNS-SD URI */ + char *resolved_uri, /* I - Buffer for resolved URI */ + size_t resolved_size, /* I - Size of URI buffer */ + int logit) /* I - Log progress to stderr? */ +{ + char scheme[32], /* URI components... */ + userpass[256], + hostname[1024], + resource[1024]; + int port; +#ifdef DEBUG + http_uri_status_t status; /* URI decode status */ +#endif /* DEBUG */ + + + DEBUG_printf(("4_httpResolveURI(uri=\"%s\", resolved_uri=%p, " + "resolved_size=" CUPS_LLFMT ")", uri, resolved_uri, + CUPS_LLCAST resolved_size)); + + /* + * Get the device URI... + */ + +#ifdef DEBUG + if ((status = httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, + sizeof(scheme), userpass, sizeof(userpass), + hostname, sizeof(hostname), &port, resource, + sizeof(resource))) < HTTP_URI_OK) +#else + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, + sizeof(scheme), userpass, sizeof(userpass), + hostname, sizeof(hostname), &port, resource, + sizeof(resource)) < HTTP_URI_OK) +#endif /* DEBUG */ + { + if (logit) + _cupsLangPrintf(stderr, _("Bad device URI \"%s\"!\n"), uri); + + DEBUG_printf(("6_httpResolveURI: httpSeparateURI returned %d!", status)); + DEBUG_puts("5_httpResolveURI: Returning NULL"); + return (NULL); + } + + /* + * Resolve it as needed... + */ + + if (strstr(hostname, "._tcp")) + { +#ifdef HAVE_DNSSD + DNSServiceRef ref, /* DNS-SD master service reference */ + domainref, /* DNS-SD service reference for domain */ + localref; /* DNS-SD service reference for .local */ + int domainsent = 0, /* Send the domain resolve? */ + offline = 0; /* offline-report state set? */ + char *regtype, /* Pointer to type in hostname */ + *domain; /* Pointer to domain in hostname */ + _http_uribuf_t uribuf; /* URI buffer */ + struct pollfd polldata; /* Polling data */ + + + if (logit) + fprintf(stderr, "DEBUG: Resolving \"%s\"...\n", hostname); + + /* + * Separate the hostname into service name, registration type, and domain... + */ + + for (regtype = strstr(hostname, "._tcp") - 2; + regtype > hostname; + regtype --) + if (regtype[0] == '.' && regtype[1] == '_') + { + /* + * Found ._servicetype in front of ._tcp... + */ + + *regtype++ = '\0'; + break; + } + + if (regtype <= hostname) + { + DEBUG_puts("5_httpResolveURI: Bad hostname, returning NULL"); + return (NULL); + } + + for (domain = strchr(regtype, '.'); + domain; + domain = strchr(domain + 1, '.')) + if (domain[1] != '_') + break; + + if (domain) + *domain++ = '\0'; + + uribuf.buffer = resolved_uri; + uribuf.bufsize = resolved_size; + + resolved_uri[0] = '\0'; + + DEBUG_printf(("6_httpResolveURI: Resolving hostname=\"%s\", regtype=\"%s\", " + "domain=\"%s\"\n", hostname, regtype, domain)); + if (logit) + { + fputs("STATE: +connecting-to-device\n", stderr); + fprintf(stderr, "DEBUG: Resolving \"%s\", regtype=\"%s\", " + "domain=\"local.\"...\n", hostname, regtype); + } + + uri = NULL; + + if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError) + { + localref = ref; + if (DNSServiceResolve(&localref, kDNSServiceFlagsShareConnection, 0, + hostname, regtype, "local.", resolve_callback, + &uribuf) == kDNSServiceErr_NoError) + { + int fds; /* Number of ready descriptors */ + time_t timeout, /* Poll timeout */ + start_time = time(NULL);/* Start time */ + + for (;;) + { + if (logit) + _cupsLangPuts(stderr, _("INFO: Looking for printer...\n")); + + /* + * For the first minute, wakeup every 2 seconds to emit a + * "looking for printer" message... + */ + + timeout = (time(NULL) < (start_time + 60)) ? 2000 : -1; + + polldata.fd = DNSServiceRefSockFD(ref); + polldata.events = POLLIN; + + fds = poll(&polldata, 1, timeout); + + if (fds < 0) + { + if (errno != EINTR && errno != EAGAIN) + { + DEBUG_printf(("5_httpResolveURI: poll error: %s", strerror(errno))); + break; + } + } + else if (fds == 0) + { + /* + * Wait 2 seconds for a response to the local resolve; if nothing + * comes in, do an additional domain resolution... + */ + + if (domainsent == 0 && strcasecmp(domain, "local.")) + { + if (logit) + fprintf(stderr, + "DEBUG: Resolving \"%s\", regtype=\"%s\", " + "domain=\"%s\"...\n", hostname, regtype, domain); + + domainref = ref; + if (DNSServiceResolve(&domainref, kDNSServiceFlagsShareConnection, 0, + hostname, regtype, domain, resolve_callback, + &uribuf) == kDNSServiceErr_NoError) + domainsent = 1; + } + + /* + * If it hasn't resolved within 5 seconds set the offline-report + * printer-state-reason... + */ + + if (logit && offline == 0 && time(NULL) > (start_time + 5)) + { + fputs("STATE: +offline-report\n", stderr); + offline = 1; + } + } + else + { + if (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError) + { + uri = resolved_uri; + break; + } + } + } + + if (domainsent) + DNSServiceRefDeallocate(domainref); + + DNSServiceRefDeallocate(localref); + } + + DNSServiceRefDeallocate(ref); + } + + if (logit) + { + if (uri) + fprintf(stderr, "DEBUG: Resolved as \"%s\"...\n", uri); + else + fputs("DEBUG: Unable to resolve URI!\n", stderr); + + fputs("STATE: -connecting-to-device,offline-report\n", stderr); + } + +#else + /* + * No DNS-SD support... + */ + + uri = NULL; +#endif /* HAVE_DNSSD */ + + if (logit && !uri) + _cupsLangPuts(stderr, _("Unable to find printer!\n")); + } + + DEBUG_printf(("5_httpResolveURI: Returning \"%s\"", uri)); + + return (uri); +} + + +/* + * 'http_copy_decode()' - Copy and decode a URI. + */ + +static const char * /* O - New source pointer or NULL on error */ +http_copy_decode(char *dst, /* O - Destination buffer */ + const char *src, /* I - Source pointer */ + int dstsize, /* I - Destination size */ + const char *term, /* I - Terminating characters */ + int decode) /* I - Decode %-encoded values */ +{ + char *ptr, /* Pointer into buffer */ + *end; /* End of buffer */ + int quoted; /* Quoted character */ + + + /* + * Copy the src to the destination until we hit a terminating character + * or the end of the string. + */ + + for (ptr = dst, end = dst + dstsize - 1; + *src && (!term || !strchr(term, *src)); + src ++) + if (ptr < end) + { + if (*src == '%' && decode) + { + if (isxdigit(src[1] & 255) && isxdigit(src[2] & 255)) + { + /* + * Grab a hex-encoded character... + */ + + src ++; + if (isalpha(*src)) + quoted = (tolower(*src) - 'a' + 10) << 4; + else + quoted = (*src - '0') << 4; + + src ++; + if (isalpha(*src)) + quoted |= tolower(*src) - 'a' + 10; + else + quoted |= *src - '0'; + + *ptr++ = quoted; + } + else + { + /* + * Bad hex-encoded character... + */ + + *ptr = '\0'; + return (NULL); + } + } + else + *ptr++ = *src; + } + + *ptr = '\0'; + + return (src); +} + + +/* + * 'http_copy_encode()' - Copy and encode a URI. + */ + +static char * /* O - End of current URI */ +http_copy_encode(char *dst, /* O - Destination buffer */ + const char *src, /* I - Source pointer */ + char *dstend, /* I - End of destination buffer */ + const char *reserved, /* I - Extra reserved characters */ + const char *term, /* I - Terminating characters */ + int encode) /* I - %-encode reserved chars? */ +{ + static const char hex[] = "0123456789ABCDEF"; + + + while (*src && dst < dstend) + { + if (term && *src == *term) + return (dst); + + if (encode && (*src == '%' || *src <= ' ' || *src & 128 || + (reserved && strchr(reserved, *src)))) + { + /* + * Hex encode reserved characters... + */ + + if ((dst + 2) >= dstend) + break; + + *dst++ = '%'; + *dst++ = hex[(*src >> 4) & 15]; + *dst++ = hex[*src & 15]; + + src ++; + } + else + *dst++ = *src++; + } + + *dst = '\0'; + + if (*src) + return (NULL); + else + return (dst); +} + + +#ifdef HAVE_DNSSD +/* + * 'resolve_callback()' - Build a device URI for the given service name. + */ + +static void +resolve_callback( + DNSServiceRef sdRef, /* I - Service reference */ + DNSServiceFlags flags, /* I - Results flags */ + uint32_t interfaceIndex, /* I - Interface number */ + DNSServiceErrorType errorCode, /* I - Error, if any */ + const char *fullName, /* I - Full service name */ + const char *hostTarget, /* I - Hostname */ + uint16_t port, /* I - Port number */ + uint16_t txtLen, /* I - Length of TXT record */ + const unsigned char *txtRecord, /* I - TXT record data */ + void *context) /* I - Pointer to URI buffer */ +{ + const char *scheme; /* URI scheme */ + char rp[257]; /* Remote printer */ + const void *value; /* Value from TXT record */ + uint8_t valueLen; /* Length of value */ + _http_uribuf_t *uribuf; /* URI buffer */ + + + DEBUG_printf(("7resolve_callback(sdRef=%p, flags=%x, interfaceIndex=%u, " + "errorCode=%d, fullName=\"%s\", hostTarget=\"%s\", port=%u, " + "txtLen=%u, txtRecord=%p, context=%p)", sdRef, flags, + interfaceIndex, errorCode, fullName, hostTarget, port, txtLen, + txtRecord, context)); + + /* + * Figure out the scheme from the full name... + */ + + if (strstr(fullName, "._ipp") || strstr(fullName, "._fax-ipp")) + scheme = "ipp"; + else if (strstr(fullName, "._printer.")) + scheme = "lpd"; + else if (strstr(fullName, "._pdl-datastream.")) + scheme = "socket"; + else + scheme = "riousbprint"; + + /* + * Extract the "remote printer" key from the TXT record... + */ + + if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp", + &valueLen)) != NULL) + { + /* + * Convert to resource by concatenating with a leading "/"... + */ + + rp[0] = '/'; + memcpy(rp + 1, value, valueLen); + rp[valueLen + 1] = '\0'; + } + else + rp[0] = '\0'; + + /* + * Assemble the final device URI... + */ + + uribuf = (_http_uribuf_t *)context; + + httpAssembleURI(HTTP_URI_CODING_ALL, uribuf->buffer, uribuf->bufsize, scheme, + NULL, hostTarget, ntohs(port), rp); + + DEBUG_printf(("8resolve_callback: Resolved URI is \"%s\"...", + uribuf->buffer)); +} +#endif /* HAVE_DNSSD */ + + +/* + * End of "$Id$". + */ diff --git a/cups/http.c b/cups/http.c new file mode 100644 index 0000000000..f98b455c44 --- /dev/null +++ b/cups/http.c @@ -0,0 +1,3548 @@ +/* + * "$Id$" + * + * HTTP routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _httpBIOMethods() - Get the OpenSSL BIO methods for HTTP connections. + * httpBlocking() - Set blocking/non-blocking behavior on a connection. + * httpCheck() - Check to see if there is a pending response from the + * server. + * httpClearCookie() - Clear the cookie value(s). + * httpClearFields() - Clear HTTP request fields. + * httpClose() - Close an HTTP connection. + * httpConnect() - Connect to a HTTP server. + * httpConnectEncrypt() - Connect to a HTTP server using encryption. + * _httpCreate() - Create an unconnected HTTP connection. + * httpDelete() - Send a DELETE request to the server. + * httpEncryption() - Set the required encryption on the link. + * httpError() - Get the last error on a connection. + * httpFlush() - Flush data from a HTTP connection. + * httpFlushWrite() - Flush data in write buffer. + * httpGet() - Send a GET request to the server. + * httpGetAuthString() - Get the current authorization string. + * httpGetBlocking() - Get the blocking/non-block state of a connection. + * httpGetCookie() - Get any cookie data from the response. + * httpGetFd() - Get the file descriptor associated with a + * connection. + * httpGetField() - Get a field value from a request/response. + * httpGetLength() - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + * httpGetLength2() - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + * httpGetStatus() - Get the status of the last HTTP request. + * httpGetSubField() - Get a sub-field value. + * httpGetSubField2() - Get a sub-field value. + * httpGets() - Get a line of text from a HTTP connection. + * httpHead() - Send a HEAD request to the server. + * httpInitialize() - Initialize the HTTP interface library and set the + * default HTTP proxy (if any). + * httpOptions() - Send an OPTIONS request to the server. + * httpPost() - Send a POST request to the server. + * httpPrintf() - Print a formatted string to a HTTP connection. + * httpPut() - Send a PUT request to the server. + * httpRead() - Read data from a HTTP connection. + * httpRead2() - Read data from a HTTP connection. + * _httpReadCDSA() - Read function for the CDSA library. + * _httpReadGNUTLS() - Read function for the GNU TLS library. + * httpReconnect() - Reconnect to a HTTP server. + * httpSetAuthString() - Set the current authorization string. + * httpSetCookie() - Set the cookie value(s). + * httpSetExpect() - Set the Expect: header in a request. + * httpSetField() - Set the value of an HTTP header. + * httpSetLength() - Set the content-length and content-encoding. + * httpTrace() - Send an TRACE request to the server. + * _httpUpdate() - Update the current HTTP status for incoming data. + * httpUpdate() - Update the current HTTP state for incoming data. + * _httpWait() - Wait for data available on a connection (no flush). + * httpWait() - Wait for data available on a connection. + * httpWrite() - Write data to a HTTP connection. + * httpWrite2() - Write data to a HTTP connection. + * _httpWriteCDSA() - Write function for the CDSA library. + * _httpWriteGNUTLS() - Write function for the GNU TLS library. + * http_bio_ctrl() - Control the HTTP connection. + * http_bio_free() - Free OpenSSL data. + * http_bio_new() - Initialize an OpenSSL BIO structure. + * http_bio_puts() - Send a string for OpenSSL. + * http_bio_read() - Read data for OpenSSL. + * http_bio_write() - Write data for OpenSSL. + * http_debug_hex() - Do a hex dump of a buffer. + * http_field() - Return the field index for a field name. + * http_read_ssl() - Read from a SSL/TLS connection. + * http_locking_cb() - Lock/unlock a thread's mutex. + * http_send() - Send a request with all fields and the trailing + * blank line. + * http_setup_ssl() - Set up SSL/TLS support on a connection. + * http_shutdown_ssl() - Shut down SSL/TLS on a connection. + * http_threadid_cb() - Return the current thread ID. + * http_upgrade() - Force upgrade to TLS encryption. + * http_write() - Write a buffer to a HTTP connection. + * http_write_chunk() - Write a chunked buffer. + * http_write_ssl() - Write to a SSL/TLS connection. + */ + +/* + * Include necessary headers... + */ + +#include "http-private.h" +#include "globals.h" +#include "debug.h" +#include +#include +#include +#ifndef WIN32 +# include +# include +# include +#endif /* !WIN32 */ +#ifdef HAVE_POLL +# include +#endif /* HAVE_POLL */ + + +/* + * 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... + */ + +#ifdef DEBUG +static void http_debug_hex(const char *prefix, const char *buffer, + int bytes); +#endif /* DEBUG */ +static http_field_t http_field(const char *name); +static int http_send(http_t *http, http_state_t request, + const char *uri); +static int http_write(http_t *http, const char *buffer, + int length); +static int http_write_chunk(http_t *http, const char *buffer, + int length); +#ifdef HAVE_SSL +static int http_read_ssl(http_t *http, char *buf, int len); +static int http_setup_ssl(http_t *http); +static void http_shutdown_ssl(http_t *http); +static int http_upgrade(http_t *http); +static int http_write_ssl(http_t *http, const char *buf, int len); + +# ifdef HAVE_GNUTLS +# ifdef HAVE_PTHREAD_H +GCRY_THREAD_OPTION_PTHREAD_IMPL; +# endif /* HAVE_PTHREAD_H */ + +# elif defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD_H) +static pthread_mutex_t *http_locks; /* OpenSSL lock mutexes */ + +static void http_locking_cb(int mode, int type, const char *file, + int line); +static unsigned long http_threadid_cb(void); +# endif /* HAVE_GNUTLS */ +#endif /* HAVE_SSL */ + + +/* + * Local globals... + */ + +static const char * const 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" + }; +#ifdef DEBUG +static const char * const http_states[] = + { + "HTTP_WAITING", + "HTTP_OPTIONS", + "HTTP_GET", + "HTTP_GET_SEND", + "HTTP_HEAD", + "HTTP_POST", + "HTTP_POST_RECV", + "HTTP_POST_SEND", + "HTTP_PUT", + "HTTP_PUT_RECV", + "HTTP_DELETE", + "HTTP_TRACE", + "HTTP_CLOSE", + "HTTP_STATUS" + }; +#endif /* DEBUG */ + + +#if defined(HAVE_SSL) && defined(HAVE_LIBSSL) +/* + * BIO methods for OpenSSL... + */ + +static int http_bio_write(BIO *h, const char *buf, int num); +static int http_bio_read(BIO *h, char *buf, int size); +static int http_bio_puts(BIO *h, const char *str); +static long http_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int http_bio_new(BIO *h); +static int http_bio_free(BIO *data); + +static BIO_METHOD http_bio_methods = + { + BIO_TYPE_SOCKET, + "http", + http_bio_write, + http_bio_read, + http_bio_puts, + NULL, /* http_bio_gets, */ + http_bio_ctrl, + http_bio_new, + http_bio_free, + NULL, + }; + + +/* + * '_httpBIOMethods()' - Get the OpenSSL BIO methods for HTTP connections. + */ + +BIO_METHOD * /* O - BIO methods for OpenSSL */ +_httpBIOMethods(void) +{ + return (&http_bio_methods); +} +#endif /* HAVE_SSL && HAVE_LIBSSL */ + + +/* + * 'httpBlocking()' - Set blocking/non-blocking behavior on a connection. + */ + +void +httpBlocking(http_t *http, /* I - Connection to server */ + int b) /* I - 1 = blocking, 0 = non-blocking */ +{ + if (http) + http->blocking = b; +} + + +/* + * '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 - Connection to server */ +{ + return (httpWait(http, 0)); +} + + +/* + * 'httpClearCookie()' - Clear the cookie value(s). + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +void +httpClearCookie(http_t *http) /* I - Connection to server */ +{ + if (!http) + return; + + if (http->cookie) + { + free(http->cookie); + http->cookie = NULL; + } +} + + +/* + * 'httpClearFields()' - Clear HTTP request fields. + */ + +void +httpClearFields(http_t *http) /* I - Connection to server */ +{ + if (http) + { + memset(http->fields, 0, sizeof(http->fields)); + if (http->hostname[0] == '/') + httpSetField(http, HTTP_FIELD_HOST, "localhost"); + else + httpSetField(http, HTTP_FIELD_HOST, http->hostname); + + if (http->field_authorization) + { + free(http->field_authorization); + http->field_authorization = NULL; + } + + http->expect = (http_status_t)0; + } +} + + +/* + * 'httpClose()' - Close an HTTP connection. + */ + +void +httpClose(http_t *http) /* I - Connection to server */ +{ +#ifdef HAVE_GSSAPI + OM_uint32 minor_status; /* Minor status code */ +#endif /* HAVE_GSSAPI */ + + + DEBUG_printf(("httpClose(http=%p)", http)); + + if (!http) + return; + + httpAddrFreeList(http->addrlist); + + if (http->cookie) + free(http->cookie); + +#ifdef HAVE_SSL + if (http->tls) + http_shutdown_ssl(http); +#endif /* HAVE_SSL */ + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + +#ifdef HAVE_GSSAPI + if (http->gssctx != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER); + + if (http->gssname != GSS_C_NO_NAME) + gss_release_name(&minor_status, &http->gssname); +#endif /* HAVE_GSSAPI */ + +#ifdef HAVE_AUTHORIZATION_H + if (http->auth_ref) + AuthorizationFree(http->auth_ref, kAuthorizationFlagDefaults); +#endif /* HAVE_AUTHORIZATION_H */ + + httpClearFields(http); + + if (http->authstring && http->authstring != http->_authstring) + free(http->authstring); + + free(http); +} + + +/* + * 'httpConnect()' - Connect to a HTTP server. + * + * This function is deprecated - use @link httpConnectEncrypt@ instead. + * + * @deprecated@ + */ + +http_t * /* O - New HTTP connection */ +httpConnect(const char *host, /* I - Host to connect to */ + int port) /* I - Port number */ +{ + return (httpConnectEncrypt(host, port, HTTP_ENCRYPT_IF_REQUESTED)); +} + + +/* + * '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 encryption) /* I - Type of encryption to use */ +{ + http_t *http; /* New HTTP connection */ + + + DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encryption=%d)", + host, port, encryption)); + + /* + * Create the HTTP structure... + */ + + if ((http = _httpCreate(host, port, encryption)) == NULL) + return (NULL); + + /* + * Connect to the remote system... + */ + + if (!httpReconnect(http)) + return (http); + + /* + * Could not connect to any known address - bail out! + */ + + httpAddrFreeList(http->addrlist); + + free(http); + + return (NULL); +} + + +/* + * '_httpCreate()' - Create an unconnected HTTP connection. + */ + +http_t * /* O - HTTP connection */ +_httpCreate( + const char *host, /* I - Hostname */ + int port, /* I - Port number */ + http_encryption_t encryption) /* I - Encryption to use */ +{ + http_t *http; /* New HTTP connection */ + http_addrlist_t *addrlist; /* Host address data */ + char service[255]; /* Service name */ + + + DEBUG_printf(("4_httpCreate(host=\"%s\", port=%d, encryption=%d)", + host, port, encryption)); + + if (!host) + return (NULL); + + httpInitialize(); + + /* + * Lookup the host... + */ + + sprintf(service, "%d", port); + + if ((addrlist = httpAddrGetList(host, AF_UNSPEC, service)) == NULL) + return (NULL); + + /* + * Allocate memory for the structure... + */ + + if ((http = calloc(sizeof(http_t), 1)) == NULL) + { + httpAddrFreeList(addrlist); + return (NULL); + } + + /* + * Initialize the HTTP data... + */ + + http->activity = time(NULL); + http->addrlist = addrlist; + http->blocking = 1; + http->fd = -1; +#ifdef HAVE_GSSAPI + http->gssctx = GSS_C_NO_CONTEXT; + http->gssname = GSS_C_NO_NAME; +#endif /* HAVE_GSSAPI */ + http->version = HTTP_1_1; + + strlcpy(http->hostname, host, sizeof(http->hostname)); + + if (port == 443) /* Always use encryption for https */ + http->encryption = HTTP_ENCRYPT_ALWAYS; + else + http->encryption = encryption; + + /* + * Return the new structure... + */ + + return (http); +} + + +/* + * 'httpDelete()' - Send a DELETE request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpDelete(http_t *http, /* I - Connection to server */ + const char *uri) /* I - URI to delete */ +{ + return (http_send(http, HTTP_DELETE, uri)); +} + + +/* + * 'httpEncryption()' - Set the required encryption on the link. + */ + +int /* O - -1 on error, 0 on success */ +httpEncryption(http_t *http, /* I - Connection to server */ + http_encryption_t e) /* I - New encryption preference */ +{ + DEBUG_printf(("httpEncryption(http=%p, e=%d)", http, e)); + +#ifdef HAVE_SSL + 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_SSL */ +} + + +/* + * 'httpError()' - Get the last error on a connection. + */ + +int /* O - Error code (errno) value */ +httpError(http_t *http) /* I - Connection to server */ +{ + if (http) + return (http->error); + else + return (EINVAL); +} + + +/* + * 'httpFlush()' - Flush data from a HTTP connection. + */ + +void +httpFlush(http_t *http) /* I - Connection to server */ +{ + char buffer[8192]; /* Junk buffer */ + int blocking; /* To block or not to block */ + http_state_t oldstate; /* Old state */ + + + DEBUG_printf(("httpFlush(http=%p), state=%s", http, + http_states[http->state])); + + /* + * Temporarily set non-blocking mode so we don't get stuck in httpRead()... + */ + + blocking = http->blocking; + http->blocking = 0; + + /* + * Read any data we can... + */ + + oldstate = http->state; + while (httpRead2(http, buffer, sizeof(buffer)) > 0); + + /* + * Restore blocking and reset the connection if we didn't get all of + * the remaining data... + */ + + http->blocking = blocking; + + if (http->state == oldstate && http->state != HTTP_WAITING && http->fd >= 0) + { + /* + * Didn't get the data back, so close the current connection. + */ + + http->state = HTTP_WAITING; + +#ifdef HAVE_SSL + if (http->tls) + http_shutdown_ssl(http); +#endif /* HAVE_SSL */ + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + http->fd = -1; + } +} + + +/* + * 'httpFlushWrite()' - Flush data in write buffer. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - Bytes written or -1 on error */ +httpFlushWrite(http_t *http) /* I - Connection to server */ +{ + int bytes; /* Bytes written */ + + + DEBUG_printf(("httpFlushWrite(http=%p)", http)); + + if (!http || !http->wused) + return (0); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + bytes = http_write_chunk(http, http->wbuffer, http->wused); + else + bytes = http_write(http, http->wbuffer, http->wused); + + http->wused = 0; + + return (bytes); +} + + +/* + * 'httpGet()' - Send a GET request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpGet(http_t *http, /* I - Connection to server */ + const char *uri) /* I - URI to get */ +{ + return (http_send(http, HTTP_GET, uri)); +} + + +/* + * 'httpGetAuthString()' - Get the current authorization string. + * + * The authorization string is set by cupsDoAuthentication() and + * httpSetAuthString(). Use httpGetAuthString() to retrieve the + * string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION + * value. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +char * /* O - Authorization string */ +httpGetAuthString(http_t *http) /* I - Connection to server */ +{ + if (http) + return (http->authstring); + else + return (NULL); +} + + +/* + * 'httpGetBlocking()' - Get the blocking/non-block state of a connection. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 1 if blocking, 0 if non-blocking */ +httpGetBlocking(http_t *http) /* I - Connection to server */ +{ + return (http ? http->blocking : 0); +} + + +/* + * 'httpGetCookie()' - Get any cookie data from the response. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +const char * /* O - Cookie data or NULL */ +httpGetCookie(http_t *http) /* I - HTTP connecion */ +{ + return (http ? http->cookie : NULL); +} + + +/* + * 'httpGetFd()' - Get the file descriptor associated with a connection. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - File descriptor or -1 if none */ +httpGetFd(http_t *http) /* I - Connection to server */ +{ + return (http ? http->fd : -1); +} + + +/* + * 'httpGetField()' - Get a field value from a request/response. + */ + +const char * /* O - Field value */ +httpGetField(http_t *http, /* I - Connection to server */ + http_field_t field) /* I - Field to get */ +{ + if (!http || field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) + return (NULL); + else if (field == HTTP_FIELD_AUTHORIZATION && + http->field_authorization) + { + /* + * Special case for WWW-Authenticate: as its contents can be + * longer than HTTP_MAX_VALUE... + */ + + return (http->field_authorization); + } + else + return (http->fields[field]); +} + + +/* + * 'httpGetLength()' - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + * + * This function is deprecated and will not return lengths larger than + * 2^31 - 1; use httpGetLength2() instead. + * + * @deprecated@ + */ + +int /* O - Content length */ +httpGetLength(http_t *http) /* I - Connection to server */ +{ + /* + * Get the read content length and return the 32-bit value. + */ + + if (http) + { + httpGetLength2(http); + + return (http->_data_remaining); + } + else + return (-1); +} + + +/* + * 'httpGetLength2()' - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + * + * This function returns the complete content length, even for + * content larger than 2^31 - 1. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +off_t /* O - Content length */ +httpGetLength2(http_t *http) /* I - Connection to server */ +{ + DEBUG_printf(("2httpGetLength2(http=%p), state=%s", http, + http_states[http->state])); + + if (!http) + return (-1); + + if (!strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked")) + { + DEBUG_puts("4httpGetLength2: 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]) + { + /* + * Default content length is 0 for errors and 2^31-1 for other + * successful requests... + */ + + if (http->status >= HTTP_MULTIPLE_CHOICES) + http->data_remaining = 0; + else + http->data_remaining = 2147483647; + } + else + http->data_remaining = strtoll(http->fields[HTTP_FIELD_CONTENT_LENGTH], + NULL, 10); + + DEBUG_printf(("4httpGetLength2: content_length=" CUPS_LLFMT, + CUPS_LLCAST http->data_remaining)); + } + + if (http->data_remaining <= INT_MAX) + http->_data_remaining = (int)http->data_remaining; + else + http->_data_remaining = INT_MAX; + + return (http->data_remaining); +} + + +/* + * 'httpGetStatus()' - Get the status of the last HTTP request. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +http_status_t /* O - HTTP status */ +httpGetStatus(http_t *http) /* I - Connection to server */ +{ + return (http ? http->status : HTTP_ERROR); +} + + +/* + * 'httpGetSubField()' - Get a sub-field value. + * + * @deprecated@ + */ + +char * /* O - Value or NULL */ +httpGetSubField(http_t *http, /* I - Connection to server */ + http_field_t field, /* I - Field index */ + const char *name, /* I - Name of sub-field */ + char *value) /* O - Value string */ +{ + return (httpGetSubField2(http, field, name, value, HTTP_MAX_VALUE)); +} + + +/* + * 'httpGetSubField2()' - Get a sub-field value. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Value or NULL */ +httpGetSubField2(http_t *http, /* I - Connection to server */ + http_field_t field, /* I - Field index */ + const char *name, /* I - Name of sub-field */ + char *value, /* O - Value string */ + int valuelen) /* I - Size of value buffer */ +{ + const char *fptr; /* Pointer into field */ + char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */ + *ptr, /* Pointer into string buffer */ + *end; /* End of value buffer */ + + DEBUG_printf(("2httpGetSubField2(http=%p, field=%d, name=\"%s\", value=%p, " + "valuelen=%d)", http, field, name, value, valuelen)); + + if (!http || !name || !value || valuelen < 2 || + field <= HTTP_FIELD_UNKNOWN || field >= HTTP_FIELD_MAX) + return (NULL); + + end = value + valuelen - 1; + + for (fptr = http->fields[field]; *fptr;) + { + /* + * Skip leading whitespace... + */ + + while (_cups_isspace(*fptr)) + fptr ++; + + if (*fptr == ',') + { + fptr ++; + continue; + } + + /* + * Get the sub-field name... + */ + + for (ptr = temp; + *fptr && *fptr != '=' && !_cups_isspace(*fptr) && + ptr < (temp + sizeof(temp) - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + DEBUG_printf(("4httpGetSubField2: name=\"%s\"", temp)); + + /* + * Skip trailing chars up to the '='... + */ + + while (_cups_isspace(*fptr)) + fptr ++; + + if (!*fptr) + break; + + if (*fptr != '=') + continue; + + /* + * Skip = and leading whitespace... + */ + + fptr ++; + + while (_cups_isspace(*fptr)) + fptr ++; + + if (*fptr == '\"') + { + /* + * Read quoted string... + */ + + for (ptr = value, fptr ++; + *fptr && *fptr != '\"' && ptr < end; + *ptr++ = *fptr++); + + *ptr = '\0'; + + while (*fptr && *fptr != '\"') + fptr ++; + + if (*fptr) + fptr ++; + } + else + { + /* + * Read unquoted string... + */ + + for (ptr = value; + *fptr && !_cups_isspace(*fptr) && *fptr != ',' && ptr < end; + *ptr++ = *fptr++); + + *ptr = '\0'; + + while (*fptr && !_cups_isspace(*fptr) && *fptr != ',') + fptr ++; + } + + DEBUG_printf(("4httpGetSubField2: value=\"%s\"", value)); + + /* + * See if this is the one... + */ + + if (!strcmp(name, temp)) + { + DEBUG_printf(("3httpGetSubField2: Returning \"%s\"", value)); + return (value); + } + } + + value[0] = '\0'; + + DEBUG_puts("3httpGetSubField2: Returning NULL"); + + return (NULL); +} + + +/* + * '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 - Connection to server */ +{ + char *lineptr, /* Pointer into line */ + *lineend, /* End of line */ + *bufptr, /* Pointer into input buffer */ + *bufend; /* Pointer to end of buffer */ + int bytes, /* Number of bytes read */ + eol; /* End-of-line? */ + + + DEBUG_printf(("2httpGets(line=%p, length=%d, http=%p)", line, length, http)); + + if (http == NULL || line == NULL) + return (NULL); + + /* + * Read a line from the buffer... + */ + + http->error = 0; + lineptr = line; + lineend = line + length - 1; + eol = 0; + + while (lineptr < lineend) + { + /* + * Pre-load the buffer as needed... + */ + +#ifdef WIN32 + WSASetLastError(0); +#else + errno = 0; +#endif /* WIN32 */ + + while (http->used == 0) + { + /* + * No newline; see if there is more data to be read... + */ + + if (!http->blocking && !_httpWait(http, 10000, 1)) + { + DEBUG_puts("3httpGets: Timed out!"); +#ifdef WIN32 + http->error = WSAETIMEDOUT; +#else + http->error = ETIMEDOUT; +#endif /* WIN32 */ + return (NULL); + } + +#ifdef HAVE_SSL + if (http->tls) + bytes = http_read_ssl(http, http->buffer + http->used, + HTTP_MAX_BUFFER - http->used); + else +#endif /* HAVE_SSL */ + bytes = recv(http->fd, http->buffer + http->used, + HTTP_MAX_BUFFER - http->used, 0); + + DEBUG_printf(("4httpGets: read %d bytes...", bytes)); + + if (bytes < 0) + { + /* + * Nope, can't get a line this time... + */ + +#ifdef WIN32 + if (WSAGetLastError() != http->error) + { + http->error = WSAGetLastError(); + continue; + } + + DEBUG_printf(("3httpGets: recv() error %d!", WSAGetLastError())); +#else + DEBUG_printf(("3httpGets: recv() error %d!", errno)); + + if (errno == EINTR || errno == EAGAIN) + continue; + else if (errno != http->error) + { + http->error = errno; + continue; + } +#endif /* WIN32 */ + + return (NULL); + } + else if (bytes == 0) + { + http->error = EPIPE; + + return (NULL); + } + + /* + * Yup, update the amount used... + */ + + http->used += bytes; + } + + /* + * Now copy as much of the current line as possible... + */ + + for (bufptr = http->buffer, bufend = http->buffer + http->used; + lineptr < lineend && bufptr < bufend;) + { + if (*bufptr == 0x0a) + { + eol = 1; + bufptr ++; + break; + } + else if (*bufptr == 0x0d) + bufptr ++; + else + *lineptr++ = *bufptr++; + } + + http->used -= (int)(bufptr - http->buffer); + if (http->used > 0) + memmove(http->buffer, bufptr, http->used); + + if (eol) + { + /* + * End of line... + */ + + http->activity = time(NULL); + + *lineptr = '\0'; + + DEBUG_printf(("3httpGets: Returning \"%s\"", line)); + + return (line); + } + } + + DEBUG_puts("3httpGets: No new line available!"); + + return (NULL); +} + + +/* + * 'httpHead()' - Send a HEAD request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpHead(http_t *http, /* I - Connection to server */ + const char *uri) /* I - URI for head */ +{ + DEBUG_printf(("httpHead(http=%p, uri=\"%s\")", http, uri)); + return (http_send(http, HTTP_HEAD, uri)); +} + + +/* + * 'httpInitialize()' - Initialize the HTTP interface library and set the + * default HTTP proxy (if any). + */ + +void +httpInitialize(void) +{ + static int initialized = 0; /* Have we been called before? */ +#ifdef WIN32 + WSADATA winsockdata; /* WinSock data */ +#endif /* WIN32 */ +#ifdef HAVE_LIBSSL + int i; /* Looping var */ + unsigned char data[1024]; /* Seed data */ +#endif /* HAVE_LIBSSL */ + + + if (initialized) + return; + +#ifdef WIN32 + WSAStartup(MAKEWORD(2,2), &winsockdata); + +#elif !defined(SO_NOSIGPIPE) + /* + * Ignore SIGPIPE signals... + */ + +# ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); + +# elif defined(HAVE_SIGACTION) + struct sigaction action; /* POSIX sigaction data */ + + + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); + +# else + signal(SIGPIPE, SIG_IGN); +# endif /* !SO_NOSIGPIPE */ +#endif /* WIN32 */ + +#ifdef HAVE_GNUTLS + /* + * Make sure we handle threading properly... + */ + +# ifdef HAVE_PTHREAD_H + gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); +# endif /* HAVE_PTHREAD_H */ + + /* + * Initialize GNU TLS... + */ + + gnutls_global_init(); + +#elif defined(HAVE_LIBSSL) + /* + * Initialize OpenSSL... + */ + + SSL_load_error_strings(); + SSL_library_init(); + + /* + * Set the threading callbacks... + */ + +# ifdef HAVE_PTHREAD_H + http_locks = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t)); + + for (i = 0; i < CRYPTO_num_locks(); i ++) + pthread_mutex_init(http_locks + i, NULL); + + CRYPTO_set_id_callback(http_threadid_cb); + CRYPTO_set_locking_callback(http_locking_cb); +# endif /* HAVE_PTHREAD_H */ + + /* + * 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...) + */ + + CUPS_SRAND(time(NULL)); + + for (i = 0; i < sizeof(data); i ++) + data[i] = CUPS_RAND(); + + RAND_seed(data, sizeof(data)); +#endif /* HAVE_GNUTLS */ + + initialized = 1; +} + + +/* + * 'httpOptions()' - Send an OPTIONS request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpOptions(http_t *http, /* I - Connection to server */ + 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 - Connection to server */ + const char *uri) /* I - URI for post */ +{ + return (http_send(http, HTTP_POST, uri)); +} + + +/* + * 'httpPrintf()' - Print a formatted string to a HTTP connection. + * + * @private@ + */ + +int /* O - Number of bytes written */ +httpPrintf(http_t *http, /* I - Connection to server */ + const char *format, /* I - printf-style format string */ + ...) /* I - Additional args as needed */ +{ + int bytes; /* Number of bytes to write */ + char buf[16384]; /* Buffer for formatted string */ + va_list ap; /* Variable argument pointer */ + + + DEBUG_printf(("2httpPrintf(http=%p, format=\"%s\", ...)", http, format)); + + va_start(ap, format); + bytes = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + DEBUG_printf(("3httpPrintf: %s", buf)); + + if (http->data_encoding == HTTP_ENCODE_FIELDS) + return (httpWrite2(http, buf, bytes)); + else + { + if (http->wused) + { + DEBUG_puts("4httpPrintf: flushing existing data..."); + + if (httpFlushWrite(http) < 0) + return (-1); + } + + return (http_write(http, buf, bytes)); + } +} + + +/* + * 'httpPut()' - Send a PUT request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpPut(http_t *http, /* I - Connection to server */ + const char *uri) /* I - URI to put */ +{ + DEBUG_printf(("httpPut(http=%p, uri=\"%s\")", http, uri)); + return (http_send(http, HTTP_PUT, uri)); +} + + +/* + * 'httpRead()' - Read data from a HTTP connection. + * + * This function is deprecated. Use the httpRead2() function which can + * read more than 2GB of data. + * + * @deprecated@ + */ + +int /* O - Number of bytes read */ +httpRead(http_t *http, /* I - Connection to server */ + char *buffer, /* I - Buffer for data */ + int length) /* I - Maximum number of bytes */ +{ + return ((int)httpRead2(http, buffer, length)); +} + + +/* + * 'httpRead2()' - Read data from a HTTP connection. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ssize_t /* O - Number of bytes read */ +httpRead2(http_t *http, /* I - Connection to server */ + char *buffer, /* I - Buffer for data */ + size_t length) /* I - Maximum number of bytes */ +{ + ssize_t bytes; /* Bytes read */ + char len[32]; /* Length string */ + + + DEBUG_printf(("httpRead2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", + http, buffer, CUPS_LLCAST length)); + + if (http == NULL || buffer == NULL) + return (-1); + + http->activity = time(NULL); + http->error = 0; + + if (length <= 0) + return (0); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED && + http->data_remaining <= 0) + { + DEBUG_puts("2httpRead2: Getting chunk length..."); + + if (httpGets(len, sizeof(len), http) == NULL) + { + DEBUG_puts("1httpRead2: Could not get length!"); + return (0); + } + + http->data_remaining = strtoll(len, NULL, 16); + if (http->data_remaining < 0) + { + DEBUG_puts("1httpRead2: Negative chunk length!"); + return (0); + } + } + + DEBUG_printf(("2httpRead2: data_remaining=" CUPS_LLFMT, + CUPS_LLCAST 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; + + /* + * Prevent future reads for this request... + */ + + http->data_encoding = HTTP_ENCODE_LENGTH; + + return (0); + } + else if (length > (size_t)http->data_remaining) + length = (size_t)http->data_remaining; + + if (http->used == 0 && length <= 256) + { + /* + * Buffer small reads for better performance... + */ + + if (!http->blocking && !httpWait(http, 10000)) + return (0); + + if (http->data_remaining > sizeof(http->buffer)) + bytes = sizeof(http->buffer); + else + bytes = http->data_remaining; + +#ifdef HAVE_SSL + if (http->tls) + bytes = http_read_ssl(http, http->buffer, bytes); + else +#endif /* HAVE_SSL */ + { + DEBUG_printf(("2httpRead2: reading %d bytes from socket into buffer...", + (int)bytes)); + + bytes = recv(http->fd, http->buffer, bytes, 0); + + DEBUG_printf(("2httpRead2: read %d bytes from socket into buffer...", + (int)bytes)); + } + + if (bytes > 0) + http->used = bytes; + else if (bytes < 0) + { +#ifdef WIN32 + http->error = WSAGetLastError(); + return (-1); +#else + if (errno != EINTR && errno != EAGAIN) + { + http->error = errno; + return (-1); + } +#endif /* WIN32 */ + } + else + { + http->error = EPIPE; + return (0); + } + } + + if (http->used > 0) + { + if (length > (size_t)http->used) + length = (size_t)http->used; + + bytes = (ssize_t)length; + + DEBUG_printf(("2httpRead2: grabbing %d bytes from input buffer...", + (int)bytes)); + + memcpy(buffer, http->buffer, length); + http->used -= (int)length; + + if (http->used > 0) + memmove(http->buffer, http->buffer + length, http->used); + } +#ifdef HAVE_SSL + else if (http->tls) + { + if (!http->blocking && !httpWait(http, 10000)) + return (0); + + bytes = (ssize_t)http_read_ssl(http, buffer, (int)length); + } +#endif /* HAVE_SSL */ + else + { + if (!http->blocking && !httpWait(http, 10000)) + return (0); + + DEBUG_printf(("2httpRead2: reading " CUPS_LLFMT " bytes from socket...", + CUPS_LLCAST length)); + +#ifdef WIN32 + bytes = (ssize_t)recv(http->fd, buffer, (int)length, 0); +#else + while ((bytes = recv(http->fd, buffer, length, 0)) < 0) + if (errno != EINTR && errno != EAGAIN) + break; +#endif /* WIN32 */ + + DEBUG_printf(("2httpRead2: read " CUPS_LLFMT " bytes from socket...", + CUPS_LLCAST bytes)); + } + + if (bytes > 0) + { + http->data_remaining -= bytes; + + if (http->data_remaining <= INT_MAX) + http->_data_remaining = (int)http->data_remaining; + else + http->_data_remaining = INT_MAX; + } + else if (bytes < 0) + { +#ifdef WIN32 + http->error = WSAGetLastError(); +#else + if (errno == EINTR || errno == EAGAIN) + bytes = 0; + else + http->error = errno; +#endif /* WIN32 */ + } + else + { + http->error = EPIPE; + return (0); + } + + 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 + http_debug_hex("httpRead2", buffer, (int)bytes); +#endif /* DEBUG */ + + return (bytes); +} + + +#if defined(HAVE_SSL) && defined(HAVE_CDSASSL) +/* + * '_httpReadCDSA()' - Read function for the CDSA library. + */ + +OSStatus /* O - -1 on error, 0 on success */ +_httpReadCDSA( + SSLConnectionRef connection, /* I - SSL/TLS connection */ + void *data, /* I - Data buffer */ + size_t *dataLength) /* IO - Number of bytes */ +{ + OSStatus result; /* Return value */ + ssize_t bytes; /* Number of bytes read */ + http_t *http; /* HTTP connection */ + + + http = (http_t *)connection; + + if (!http->blocking) + { + /* + * Make sure we have data before we read... + */ + + if (!_httpWait(http, 10000, 0)) + { + http->error = ETIMEDOUT; + return (-1); + } + } + + do + { + bytes = recv(http->fd, data, *dataLength, 0); + } + while (bytes == -1 && (errno == EINTR || errno == EAGAIN)); + + if (bytes == *dataLength) + { + result = 0; + } + else if (bytes > 0) + { + *dataLength = bytes; + result = errSSLWouldBlock; + } + else + { + *dataLength = 0; + + if (bytes == 0) + result = errSSLClosedGraceful; + else if (errno == EAGAIN) + result = errSSLWouldBlock; + else + result = errSSLClosedAbort; + } + + return (result); +} +#endif /* HAVE_SSL && HAVE_CDSASSL */ + + +#if defined(HAVE_SSL) && defined(HAVE_GNUTLS) +/* + * '_httpReadGNUTLS()' - Read function for the GNU TLS library. + */ + +ssize_t /* O - Number of bytes read or -1 on error */ +_httpReadGNUTLS( + gnutls_transport_ptr ptr, /* I - Connection to server */ + void *data, /* I - Buffer */ + size_t length) /* I - Number of bytes to read */ +{ + http_t *http; /* HTTP connection */ + + + http = (http_t *)ptr; + + if (!http->blocking) + { + /* + * Make sure we have data before we read... + */ + + if (!_httpWait(http, 10000, 0)) + { + http->error = ETIMEDOUT; + return (-1); + } + } + + return (recv(http->fd, data, length, 0)); +} +#endif /* HAVE_SSL && HAVE_GNUTLS */ + + +/* + * 'httpReconnect()' - Reconnect to a HTTP server. + */ + +int /* O - 0 on success, non-zero on failure */ +httpReconnect(http_t *http) /* I - Connection to server */ +{ + http_addrlist_t *addr; /* Connected address */ +#ifdef DEBUG + http_addrlist_t *current; /* Current address */ + char temp[256]; /* Temporary address string */ +#endif /* DEBUG */ + + + DEBUG_printf(("httpReconnect(http=%p)", http)); + + if (!http) + return (-1); + +#ifdef HAVE_SSL + if (http->tls) + { + DEBUG_puts("2httpReconnect: Shutting down SSL/TLS..."); + http_shutdown_ssl(http); + } +#endif /* HAVE_SSL */ + + /* + * Close any previously open socket... + */ + + if (http->fd >= 0) + { + DEBUG_printf(("2httpReconnect: Closing socket %d...", http->fd)); + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + http->fd = -1; + } + + /* + * Connect to the server... + */ + +#ifdef DEBUG + for (current = http->addrlist; current; current = current->next) + DEBUG_printf(("2httpReconnect: Address %s:%d", + httpAddrString(&(current->addr), temp, sizeof(temp)), + _httpAddrPort(&(current->addr)))); +#endif /* DEBUG */ + + if ((addr = httpAddrConnect(http->addrlist, &(http->fd))) == NULL) + { + /* + * Unable to connect... + */ + +#ifdef WIN32 + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 */ + http->status = HTTP_ERROR; + + DEBUG_printf(("1httpReconnect: httpAddrConnect failed: %s", + strerror(http->error))); + + return (-1); + } + + DEBUG_printf(("2httpReconnect: New socket=%d", http->fd)); + + http->hostaddr = &(addr->addr); + http->error = 0; + http->status = HTTP_CONTINUE; + +#ifdef HAVE_SSL + if (http->encryption == HTTP_ENCRYPT_ALWAYS) + { + /* + * Always do encryption via SSL. + */ + + if (http_setup_ssl(http) != 0) + { +# ifdef WIN32 + closesocket(http->fd); +# else + close(http->fd); +# endif /* WIN32 */ + + return (-1); + } + } + else if (http->encryption == HTTP_ENCRYPT_REQUIRED) + return (http_upgrade(http)); +#endif /* HAVE_SSL */ + + DEBUG_printf(("1httpReconnect: Connected to %s:%d...", + httpAddrString(http->hostaddr, temp, sizeof(temp)), + _httpAddrPort(http->hostaddr))); + + return (0); +} + + +/* + * 'httpSetAuthString()' - Set the current authorization string. + * + * This function just stores a copy of the current authorization string in + * the HTTP connection object. You must still call httpSetField() to set + * HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(), + * httpHead(), httpOptions(), httpPost, or httpPut(). + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +void +httpSetAuthString(http_t *http, /* I - Connection to server */ + const char *scheme, /* I - Auth scheme (NULL to clear it) */ + const char *data) /* I - Auth data (NULL for none) */ +{ + /* + * Range check input... + */ + + if (!http) + return; + + if (http->authstring && http->authstring != http->_authstring) + free(http->authstring); + + http->authstring = http->_authstring; + + if (scheme) + { + /* + * Set the current authorization string... + */ + + int len = (int)strlen(scheme) + (data ? (int)strlen(data) + 1 : 0) + 1; + char *temp; + + if (len > (int)sizeof(http->_authstring)) + { + if ((temp = malloc(len)) == NULL) + len = sizeof(http->_authstring); + else + http->authstring = temp; + } + + if (data) + snprintf(http->authstring, len, "%s %s", scheme, data); + else + strlcpy(http->authstring, scheme, len); + } + else + { + /* + * Clear the current authorization string... + */ + + http->_authstring[0] = '\0'; + } +} + + +/* + * 'httpSetCookie()' - Set the cookie value(s). + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +void +httpSetCookie(http_t *http, /* I - Connection */ + const char *cookie) /* I - Cookie string */ +{ + if (!http) + return; + + if (http->cookie) + free(http->cookie); + + if (cookie) + http->cookie = strdup(cookie); + else + http->cookie = NULL; +} + + +/* + * 'httpSetExpect()' - Set the Expect: header in a request. + * + * Currently only HTTP_CONTINUE is supported for the "expect" argument. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +httpSetExpect(http_t *http, /* I - Connection to server */ + http_status_t expect) /* I - HTTP status to expect (HTTP_CONTINUE) */ +{ + if (http) + http->expect = expect; +} + + +/* + * 'httpSetField()' - Set the value of an HTTP header. + */ + +void +httpSetField(http_t *http, /* I - Connection to server */ + 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); + + if (field == HTTP_FIELD_AUTHORIZATION) + { + /* + * Special case for Authorization: as its contents can be + * longer than HTTP_MAX_VALUE + */ + + if (http->field_authorization) + free(http->field_authorization); + + http->field_authorization = strdup(value); + } + else if (field == HTTP_FIELD_HOST) + { + /* + * Special-case for Host: as we don't want a trailing "." on the hostname and + * need to bracket IPv6 numeric addresses. + */ + + char *ptr = strchr(value, ':'); + + if (value[0] != '[' && ptr && strchr(ptr + 1, ':')) + { + /* + * Bracket IPv6 numeric addresses... + * + * This is slightly inefficient (basically copying twice), but is an edge + * case and not worth optimizing... + */ + + snprintf(http->fields[HTTP_FIELD_HOST], + sizeof(http->fields[HTTP_FIELD_HOST]), "[%s]", value); + } + else + { + /* + * Check for a trailing dot on the hostname... + */ + + ptr = http->fields[HTTP_FIELD_HOST]; + + if (*ptr) + { + ptr += strlen(ptr) - 1; + + if (*ptr == '.') + *ptr = '\0'; + } + } + } +} + + +/* + * 'httpSetLength()' - Set the content-length and content-encoding. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +void +httpSetLength(http_t *http, /* I - Connection to server */ + size_t length) /* I - Length (0 for chunked) */ +{ + if (!http) + return; + + if (!length) + { + strcpy(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked"); + http->fields[HTTP_FIELD_CONTENT_LENGTH][0] = '\0'; + } + else + { + http->fields[HTTP_FIELD_TRANSFER_ENCODING][0] = '\0'; + snprintf(http->fields[HTTP_FIELD_CONTENT_LENGTH], HTTP_MAX_VALUE, + CUPS_LLFMT, CUPS_LLCAST length); + } +} + + +/* + * 'httpTrace()' - Send an TRACE request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpTrace(http_t *http, /* I - Connection to server */ + const char *uri) /* I - URI for trace */ +{ + return (http_send(http, HTTP_TRACE, uri)); +} + + +/* + * '_httpUpdate()' - Update the current HTTP status for incoming data. + * + * Note: Unlike httpUpdate(), this function does not flush pending write data + * and only retrieves a single status line from the HTTP connection. + */ + +int /* O - 1 to continue, 0 to stop */ +_httpUpdate(http_t *http, /* I - Connection to server */ + http_status_t *status) /* O - Current HTTP status */ +{ + char line[32768], /* Line from connection... */ + *value; /* Pointer to value on line */ + http_field_t field; /* Field index */ + int major, minor; /* HTTP version numbers */ + + + DEBUG_printf(("_httpUpdate(http=%p, status=%p), state=%s", http, status, + http_states[http->state])); + + /* + * Grab a single line from the connection... + */ + + if (!httpGets(line, sizeof(line), http)) + { + *status = HTTP_ERROR; + return (0); + } + + DEBUG_printf(("2_httpUpdate: Got \"%s\"", 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) + { + *status = http->status; + return (0); + } + + if (http->status < HTTP_BAD_REQUEST) + http->digest_tries = 0; + +#ifdef HAVE_SSL + if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls) + { + if (http_setup_ssl(http) != 0) + { +# ifdef WIN32 + closesocket(http->fd); +# else + close(http->fd); +# endif /* WIN32 */ + + *status = http->status = HTTP_ERROR; + return (0); + } + + *status = HTTP_CONTINUE; + return (0); + } +#endif /* HAVE_SSL */ + + httpGetLength2(http); + + switch (http->state) + { + case HTTP_GET : + case HTTP_POST : + case HTTP_POST_RECV : + case HTTP_PUT : + http->state ++; + case HTTP_POST_SEND : + case HTTP_HEAD : + break; + + default : + http->state = HTTP_WAITING; + break; + } + + *status = http->status; + return (0); + } + else if (!strncmp(line, "HTTP/", 5)) + { + /* + * Got the beginning of a response... + */ + + int intstatus; /* Status value as an integer */ + + if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &intstatus) != 3) + { + *status = http->status = HTTP_ERROR; + return (0); + } + + http->version = (http_version_t)(major * 100 + minor); + *status = http->status = (http_status_t)intstatus; + } + else if ((value = strchr(line, ':')) != NULL) + { + /* + * Got a value... + */ + + *value++ = '\0'; + while (_cups_isspace(*value)) + value ++; + + /* + * Be tolerants of servers that send unknown attribute fields... + */ + + if (!strcasecmp(line, "expect")) + { + /* + * "Expect: 100-continue" or similar... + */ + + http->expect = (http_status_t)atoi(value); + } + else if (!strcasecmp(line, "cookie")) + { + /* + * "Cookie: name=value[; name=value ...]" - replaces previous cookies... + */ + + httpSetCookie(http, value); + } + else if ((field = http_field(line)) != HTTP_FIELD_UNKNOWN) + httpSetField(http, field, value); +#ifdef DEBUG + else + DEBUG_printf(("1_httpUpdate: unknown field %s seen!", line)); +#endif /* DEBUG */ + } + else + { + DEBUG_printf(("1_httpUpdate: Bad response line \"%s\"!", line)); + *status = http->status = HTTP_ERROR; + return (0); + } + + return (1); +} + + +/* + * 'httpUpdate()' - Update the current HTTP state for incoming data. + */ + +http_status_t /* O - HTTP status */ +httpUpdate(http_t *http) /* I - Connection to server */ +{ + http_status_t status; /* Request status */ + + + DEBUG_printf(("httpUpdate(http=%p), state=%s", http, + http_states[http->state])); + + /* + * Flush pending data, if any... + */ + + if (http->wused) + { + DEBUG_puts("2httpUpdate: flushing buffer..."); + + if (httpFlushWrite(http) < 0) + return (HTTP_ERROR); + } + + /* + * 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 (_httpUpdate(http, &status)); + + /* + * See if there was an error... + */ + + if (http->error == EPIPE && http->status > HTTP_CONTINUE) + { + DEBUG_printf(("1httpUpdate: Returning status %d...", http->status)); + return (http->status); + } + + if (http->error) + { + DEBUG_printf(("1httpUpdate: socket error %d - %s", http->error, + strerror(http->error))); + http->status = HTTP_ERROR; + return (HTTP_ERROR); + } + + /* + * Return the current status... + */ + + return (status); +} + + +/* + * '_httpWait()' - Wait for data available on a connection (no flush). + */ + +int /* O - 1 if data is available, 0 otherwise */ +_httpWait(http_t *http, /* I - Connection to server */ + int msec, /* I - Milliseconds to wait */ + int usessl) /* I - Use SSL context? */ +{ +#ifdef HAVE_POLL + struct pollfd pfd; /* Polled file descriptor */ +#else + fd_set input_set; /* select() input set */ + struct timeval timeout; /* Timeout */ +#endif /* HAVE_POLL */ + int nfds; /* Result from select()/poll() */ + + + DEBUG_printf(("4_httpWait(http=%p, msec=%d, usessl=%d)", http, msec, usessl)); + + if (http->fd < 0) + return (0); + + /* + * Check the SSL/TLS buffers for data first... + */ + +#ifdef HAVE_SSL + if (http->tls && usessl) + { +# ifdef HAVE_LIBSSL + if (SSL_pending((SSL *)(http->tls))) + return (1); +# elif defined(HAVE_GNUTLS) + if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session)) + return (1); +# elif defined(HAVE_CDSASSL) + size_t bytes; /* Bytes that are available */ + + if (!SSLGetBufferedReadSize(((http_tls_t *)(http->tls))->session, &bytes) && + bytes > 0) + return (1); +# endif /* HAVE_LIBSSL */ + } +#endif /* HAVE_SSL */ + + /* + * Then try doing a select() or poll() to poll the socket... + */ + +#ifdef HAVE_POLL + pfd.fd = http->fd; + pfd.events = POLLIN; + + while ((nfds = poll(&pfd, 1, msec)) < 0 && + (errno == EINTR || errno == EAGAIN)); + +#else + do + { + FD_ZERO(&input_set); + FD_SET(http->fd, &input_set); + + DEBUG_printf(("6_httpWait: msec=%d, http->fd=%d", msec, http->fd)); + + if (msec >= 0) + { + timeout.tv_sec = msec / 1000; + timeout.tv_usec = (msec % 1000) * 1000; + + nfds = select(http->fd + 1, &input_set, NULL, NULL, &timeout); + } + else + nfds = select(http->fd + 1, &input_set, NULL, NULL, NULL); + + DEBUG_printf(("6_httpWait: select() returned %d...", nfds)); + } +# ifdef WIN32 + while (nfds < 0 && WSAGetLastError() == WSAEINTR); +# else + while (nfds < 0 && (errno == EINTR || errno == EAGAIN)); +# endif /* WIN32 */ +#endif /* HAVE_POLL */ + + DEBUG_printf(("5_httpWait: returning with nfds=%d...", nfds)); + + return (nfds > 0); +} + + +/* + * 'httpWait()' - Wait for data available on a connection. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +int /* O - 1 if data is available, 0 otherwise */ +httpWait(http_t *http, /* I - Connection to server */ + int msec) /* I - Milliseconds to wait */ +{ + /* + * First see if there is data in the buffer... + */ + + if (http == NULL) + return (0); + + if (http->used) + return (1); + + /* + * Flush pending data, if any... + */ + + if (http->wused) + { + if (httpFlushWrite(http) < 0) + return (0); + } + + /* + * If not, check the SSL/TLS buffers and do a select() on the connection... + */ + + return (_httpWait(http, msec, 1)); +} + + +/* + * 'httpWrite()' - Write data to a HTTP connection. + * + * This function is deprecated. Use the httpWrite2() function which can + * write more than 2GB of data. + * + * @deprecated@ + */ + +int /* O - Number of bytes written */ +httpWrite(http_t *http, /* I - Connection to server */ + const char *buffer, /* I - Buffer for data */ + int length) /* I - Number of bytes to write */ +{ + return ((int)httpWrite2(http, buffer, length)); +} + + +/* + * 'httpWrite2()' - Write data to a HTTP connection. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ssize_t /* O - Number of bytes written */ +httpWrite2(http_t *http, /* I - Connection to server */ + const char *buffer, /* I - Buffer for data */ + size_t length) /* I - Number of bytes to write */ +{ + ssize_t bytes; /* Bytes written */ + + + DEBUG_printf(("httpWrite2(http=%p, buffer=%p, length=" CUPS_LLFMT ")", http, + buffer, CUPS_LLCAST length)); + + /* + * Range check input... + */ + + if (http == NULL || buffer == NULL) + return (-1); + + /* + * Mark activity on the connection... + */ + + http->activity = time(NULL); + + /* + * Buffer small writes for better performance... + */ + + if (length > 0) + { + if (http->wused && (length + http->wused) > sizeof(http->wbuffer)) + { + DEBUG_printf(("2httpWrite2: Flushing buffer (wused=%d, length=" + CUPS_LLFMT ")", http->wused, CUPS_LLCAST length)); + + httpFlushWrite(http); + } + + if ((length + http->wused) <= sizeof(http->wbuffer) && + length < sizeof(http->wbuffer)) + { + /* + * Write to buffer... + */ + + DEBUG_printf(("2httpWrite2: Copying " CUPS_LLFMT " bytes to wbuffer...", + CUPS_LLCAST length)); + + memcpy(http->wbuffer + http->wused, buffer, length); + http->wused += (int)length; + bytes = (ssize_t)length; + } + else + { + /* + * Otherwise write the data directly... + */ + + DEBUG_printf(("2httpWrite2: Writing " CUPS_LLFMT " bytes to socket...", + CUPS_LLCAST length)); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + bytes = (ssize_t)http_write_chunk(http, buffer, (int)length); + else + bytes = (ssize_t)http_write(http, buffer, (int)length); + + DEBUG_printf(("2httpWrite2: Wrote " CUPS_LLFMT " bytes...", + CUPS_LLCAST bytes)); + } + + if (http->data_encoding == HTTP_ENCODE_LENGTH) + http->data_remaining -= bytes; + } + else + bytes = 0; + + /* + * Handle end-of-request processing... + */ + + if ((http->data_encoding == HTTP_ENCODE_CHUNKED && length == 0) || + (http->data_encoding == HTTP_ENCODE_LENGTH && http->data_remaining == 0)) + { + /* + * Finished with the transfer; unless we are sending POST or PUT + * data, go idle... + */ + + DEBUG_puts("2httpWrite: changing states..."); + + if (http->wused) + httpFlushWrite(http); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + { + /* + * Send a 0-length chunk at the end of the request... + */ + + http_write(http, "0\r\n\r\n", 5); + + /* + * Reset the data state... + */ + + http->data_encoding = HTTP_ENCODE_LENGTH; + http->data_remaining = 0; + } + } + + return (bytes); +} + + +#if defined(HAVE_SSL) && defined(HAVE_CDSASSL) +/* + * '_httpWriteCDSA()' - Write function for the CDSA library. + */ + +OSStatus /* O - -1 on error, 0 on success */ +_httpWriteCDSA( + SSLConnectionRef connection, /* I - SSL/TLS connection */ + const void *data, /* I - Data buffer */ + size_t *dataLength) /* IO - Number of bytes */ +{ + OSStatus result; /* Return value */ + ssize_t bytes; /* Number of bytes read */ + http_t *http; /* HTTP connection */ + + + http = (http_t *)connection; + + do + { + bytes = write(http->fd, data, *dataLength); + } + while (bytes == -1 && (errno == EINTR || errno == EAGAIN)); + + if (bytes == *dataLength) + { + result = 0; + } + else if (bytes >= 0) + { + *dataLength = bytes; + result = errSSLWouldBlock; + } + else + { + *dataLength = 0; + + if (errno == EAGAIN) + result = errSSLWouldBlock; + else + result = errSSLClosedAbort; + } + + return (result); +} +#endif /* HAVE_SSL && HAVE_CDSASSL */ + + +#if defined(HAVE_SSL) && defined(HAVE_GNUTLS) +/* + * '_httpWriteGNUTLS()' - Write function for the GNU TLS library. + */ + +ssize_t /* O - Number of bytes written or -1 on error */ +_httpWriteGNUTLS( + gnutls_transport_ptr ptr, /* I - Connection to server */ + const void *data, /* I - Data buffer */ + size_t length) /* I - Number of bytes to write */ +{ + return (send(((http_t *)ptr)->fd, data, length, 0)); +} +#endif /* HAVE_SSL && HAVE_GNUTLS */ + + +#if defined(HAVE_SSL) && defined(HAVE_LIBSSL) +/* + * 'http_bio_ctrl()' - Control the HTTP connection. + */ + +static long /* O - Result/data */ +http_bio_ctrl(BIO *h, /* I - BIO data */ + int cmd, /* I - Control command */ + long arg1, /* I - First argument */ + void *arg2) /* I - Second argument */ +{ + switch (cmd) + { + default : + return (0); + + case BIO_CTRL_RESET : + h->ptr = NULL; + return (0); + + case BIO_C_SET_FILE_PTR : + h->ptr = arg2; + h->init = 1; + return (1); + + case BIO_C_GET_FILE_PTR : + if (arg2) + { + *((void **)arg2) = h->ptr; + return (1); + } + else + return (0); + + case BIO_CTRL_DUP : + case BIO_CTRL_FLUSH : + return (1); + } +} + + +/* + * 'http_bio_free()' - Free OpenSSL data. + */ + +static int /* O - 1 on success, 0 on failure */ +http_bio_free(BIO *h) /* I - BIO data */ +{ + if (!h) + return (0); + + if (h->shutdown) + { + h->init = 0; + h->flags = 0; + } + + return (1); +} + + +/* + * 'http_bio_new()' - Initialize an OpenSSL BIO structure. + */ + +static int /* O - 1 on success, 0 on failure */ +http_bio_new(BIO *h) /* I - BIO data */ +{ + if (!h) + return (0); + + h->init = 0; + h->num = 0; + h->ptr = NULL; + h->flags = 0; + + return (1); +} + + +/* + * 'http_bio_puts()' - Send a string for OpenSSL. + */ + +static int /* O - Bytes written */ +http_bio_puts(BIO *h, /* I - BIO data */ + const char *str) /* I - String to write */ +{ +#ifdef WIN32 + return (send(((http_t *)h->ptr)->fd, str, (int)strlen(str), 0)); +#else + return (send(((http_t *)h->ptr)->fd, str, strlen(str), 0)); +#endif /* WIN32 */ +} + + +/* + * 'http_bio_read()' - Read data for OpenSSL. + */ + +static int /* O - Bytes read */ +http_bio_read(BIO *h, /* I - BIO data */ + char *buf, /* I - Buffer */ + int size) /* I - Number of bytes to read */ +{ + http_t *http; /* HTTP connection */ + + + http = (http_t *)h->ptr; + + if (!http->blocking) + { + /* + * Make sure we have data before we read... + */ + + if (!_httpWait(http, 10000, 0)) + { +#ifdef WIN32 + http->error = WSAETIMEDOUT; +#else + http->error = ETIMEDOUT; +#endif /* WIN32 */ + + return (-1); + } + } + + return (recv(http->fd, buf, size, 0)); +} + + +/* + * 'http_bio_write()' - Write data for OpenSSL. + */ + +static int /* O - Bytes written */ +http_bio_write(BIO *h, /* I - BIO data */ + const char *buf, /* I - Buffer to write */ + int num) /* I - Number of bytes to write */ +{ + return (send(((http_t *)h->ptr)->fd, buf, num, 0)); +} +#endif /* HAVE_SSL && HAVE_LIBSSL */ + + +#ifdef DEBUG +/* + * 'http_debug_hex()' - Do a hex dump of a buffer. + */ + +static void +http_debug_hex(const char *prefix, /* I - Prefix for line */ + const char *buffer, /* I - Buffer to dump */ + int bytes) /* I - Bytes to dump */ +{ + int i, j, /* Looping vars */ + ch; /* Current character */ + char line[255], /* Line buffer */ + *start, /* Start of line after prefix */ + *ptr; /* Pointer into line */ + + + if (_cups_debug_fd < 0 || _cups_debug_level < 6) + return; + + DEBUG_printf(("6%s: %d bytes:\n", prefix, bytes)); + + snprintf(line, sizeof(line), "6%s: ", prefix); + start = line + strlen(line); + + for (i = 0; i < bytes; i += 16) + { + for (j = 0, ptr = start; j < 16 && (i + j) < bytes; j ++, ptr += 2) + sprintf(ptr, "%02X", buffer[i + j] & 255); + + while (j < 16) + { + strcpy(ptr, " "); + ptr += 2; + j ++; + } + + strcpy(ptr, " "); + ptr += 2; + + for (j = 0; j < 16 && (i + j) < bytes; j ++) + { + ch = buffer[i + j] & 255; + + if (ch < ' ' || ch >= 127) + ch = '.'; + + *ptr++ = ch; + } + + *ptr = '\0'; + DEBUG_puts(line); + } +} +#endif /* DEBUG */ + + +/* + * '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); +} + + +#ifdef HAVE_SSL +/* + * 'http_read_ssl()' - Read from a SSL/TLS connection. + */ + +static int /* O - Bytes read */ +http_read_ssl(http_t *http, /* I - Connection to server */ + char *buf, /* I - Buffer to store data */ + int len) /* I - Length of buffer */ +{ +# if defined(HAVE_LIBSSL) + return (SSL_read((SSL *)(http->tls), buf, len)); + +# elif defined(HAVE_GNUTLS) + ssize_t result; /* Return value */ + + + result = gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len); + + if (result < 0 && !errno) + { + /* + * Convert GNU TLS error to errno value... + */ + + switch (result) + { + case GNUTLS_E_INTERRUPTED : + errno = EINTR; + break; + + case GNUTLS_E_AGAIN : + errno = EAGAIN; + break; + + default : + errno = EPIPE; + break; + } + + result = -1; + } + + return ((int)result); + +# elif defined(HAVE_CDSASSL) + int result; /* Return value */ + OSStatus error; /* Error info */ + size_t processed; /* Number of bytes processed */ + + + error = SSLRead(((http_tls_t *)http->tls)->session, buf, len, &processed); + + switch (error) + { + case 0 : + result = (int)processed; + break; + case errSSLClosedGraceful : + result = 0; + break; + case errSSLWouldBlock : + if (processed) + result = (int)processed; + else + { + result = -1; + errno = EINTR; + } + break; + default : + errno = EPIPE; + result = -1; + break; + } + + return (result); +# endif /* HAVE_LIBSSL */ +} +#endif /* HAVE_SSL */ + + +#if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD_H) +/* + * 'http_locking_cb()' - Lock/unlock a thread's mutex. + */ + +static void +http_locking_cb(int mode, /* I - Lock mode */ + int type, /* I - Lock type */ + const char *file, /* I - Source file */ + int line) /* I - Line number */ +{ + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(http_locks + type); + else + pthread_mutex_unlock(http_locks + type); +} +#endif /* HAVE_LIBSSL && HAVE_PTHREAD_H */ + + +/* + * '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 - Connection to server */ + http_state_t request, /* I - Request code */ + const char *uri) /* I - URI */ +{ + int i; /* Looping var */ + char buf[1024]; /* Encoded URI buffer */ + static const char * const codes[] = + { /* Request code strings */ + NULL, + "OPTIONS", + "GET", + NULL, + "HEAD", + "POST", + NULL, + NULL, + "PUT", + NULL, + "DELETE", + "TRACE", + "CLOSE" + }; + + + DEBUG_printf(("7http_send(http=%p, request=HTTP_%s, uri=\"%s\")", + http, codes[request], uri)); + + if (http == NULL || uri == NULL) + return (-1); + + /* + * Set the User-Agent field if it isn't already... + */ + + if (!http->fields[HTTP_FIELD_USER_AGENT][0]) + httpSetField(http, HTTP_FIELD_USER_AGENT, CUPS_MINIMAL); + + /* + * Encode the URI as needed... + */ + + _httpEncodeURI(buf, uri, sizeof(buf)); + + /* + * See if we had an error the last time around; if so, reconnect... + */ + + if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST) + if (httpReconnect(http)) + return (-1); + + /* + * Flush any written data that is pending... + */ + + if (http->wused) + { + if (httpFlushWrite(http) < 0) + if (httpReconnect(http)) + return (-1); + } + + /* + * Send the request header... + */ + + http->state = request; + http->data_encoding = HTTP_ENCODE_FIELDS; + + if (request == HTTP_POST || request == HTTP_PUT) + http->state ++; + + http->status = HTTP_CONTINUE; + +#ifdef HAVE_SSL + 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_SSL */ + + 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(("9http_send: %s: %s", http_fields[i], + httpGetField(http, i))); + + if (httpPrintf(http, "%s: %s\r\n", http_fields[i], + httpGetField(http, i)) < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + } + + if (http->cookie) + if (httpPrintf(http, "Cookie: $Version=0; %s\r\n", http->cookie) < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + if (http->expect == HTTP_CONTINUE && + (http->state == HTTP_POST_RECV || http->state == HTTP_PUT_RECV)) + if (httpPrintf(http, "Expect: 100-continue\r\n") < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + if (httpPrintf(http, "\r\n") < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + if (httpFlushWrite(http) < 0) + return (-1); + + httpGetLength2(http); + httpClearFields(http); + + /* + * The Kerberos and AuthRef authentication strings can only be used once... + */ + + if (http->field_authorization && http->authstring && + (!strncmp(http->authstring, "Negotiate", 9) || + !strncmp(http->authstring, "AuthRef", 7))) + { + http->_authstring[0] = '\0'; + + if (http->authstring != http->_authstring) + free(http->authstring); + + http->authstring = http->_authstring; + } + + return (0); +} + + +#ifdef HAVE_SSL +/* + * 'http_setup_ssl()' - Set up SSL/TLS support on a connection. + */ + +static int /* O - Status of connection */ +http_setup_ssl(http_t *http) /* I - Connection to server */ +{ +# ifdef HAVE_LIBSSL + SSL_CTX *context; /* Context for encryption */ + SSL *conn; /* Connection for encryption */ + BIO *bio; /* BIO data */ +# elif defined(HAVE_GNUTLS) + http_tls_t *conn; /* TLS session object */ + gnutls_certificate_client_credentials *credentials; + /* TLS credentials */ +# elif defined(HAVE_CDSASSL) + OSStatus error; /* Error code */ + http_tls_t *conn; /* CDSA connection information */ +# endif /* HAVE_LIBSSL */ + + + DEBUG_printf(("7http_setup_ssl(http=%p)", http)); + +# ifdef HAVE_LIBSSL + context = SSL_CTX_new(SSLv23_client_method()); + + SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */ + + bio = BIO_new(_httpBIOMethods()); + BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)http); + + conn = SSL_new(context); + SSL_set_bio(conn, bio, bio); + + if (SSL_connect(conn) != 1) + { +# ifdef DEBUG + unsigned long error; /* Error code */ + + while ((error = ERR_get_error()) != 0) + DEBUG_printf(("8http_setup_ssl: %s", ERR_error_string(error, NULL))); +# endif /* DEBUG */ + + SSL_CTX_free(context); + SSL_free(conn); + +# ifdef WIN32 + http->error = WSAGetLastError(); +# else + http->error = errno; +# endif /* WIN32 */ + http->status = HTTP_ERROR; + + return (HTTP_ERROR); + } + +# elif defined(HAVE_GNUTLS) + if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL) + { + http->error = errno; + http->status = HTTP_ERROR; + + return (-1); + } + + credentials = (gnutls_certificate_client_credentials *) + malloc(sizeof(gnutls_certificate_client_credentials)); + if (credentials == NULL) + { + free(conn); + + http->error = errno; + http->status = HTTP_ERROR; + + return (-1); + } + + gnutls_certificate_allocate_credentials(credentials); + + gnutls_init(&(conn->session), GNUTLS_CLIENT); + gnutls_set_default_priority(conn->session); + gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials); + gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)http); + gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS); + gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS); + + if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS) + { + http->error = errno; + http->status = HTTP_ERROR; + + gnutls_deinit(conn->session); + gnutls_certificate_free_credentials(*credentials); + free(credentials); + free(conn); + + return (-1); + } + + conn->credentials = credentials; + +# elif defined(HAVE_CDSASSL) + conn = (http_tls_t *)calloc(1, sizeof(http_tls_t)); + + if (conn == NULL) + return (-1); + + if ((error = SSLNewContext(false, &conn->session))) + { + http->error = error; + http->status = HTTP_ERROR; + + free(conn); + return (-1); + } + + /* + * Use a union to resolve warnings about int/pointer size mismatches... + */ + + error = SSLSetConnection(conn->session, http); + + if (!error) + error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA); + + if (!error) + error = SSLSetAllowsExpiredCerts(conn->session, true); + + if (!error) + error = SSLSetAllowsAnyRoot(conn->session, true); + + if (!error) + error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false); + + if (!error) + { + while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock) + usleep(1000); + } + + if (error) + { + http->error = error; + http->status = HTTP_ERROR; + + SSLDisposeContext(conn->session); + + free(conn); + + return (-1); + } +# endif /* HAVE_CDSASSL */ + + http->tls = conn; + return (0); +} +#endif /* HAVE_SSL */ + + +#ifdef HAVE_SSL +/* + * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection. + */ + +static void +http_shutdown_ssl(http_t *http) /* I - Connection to server */ +{ +# ifdef HAVE_LIBSSL + SSL_CTX *context; /* Context for encryption */ + SSL *conn; /* Connection for encryption */ + + + conn = (SSL *)(http->tls); + context = SSL_get_SSL_CTX(conn); + + SSL_shutdown(conn); + SSL_CTX_free(context); + SSL_free(conn); + +# elif defined(HAVE_GNUTLS) + http_tls_t *conn; /* Encryption session */ + gnutls_certificate_client_credentials *credentials; + /* TLS credentials */ + + + conn = (http_tls_t *)(http->tls); + credentials = (gnutls_certificate_client_credentials *)(conn->credentials); + + gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); + gnutls_deinit(conn->session); + gnutls_certificate_free_credentials(*credentials); + free(credentials); + free(conn); + +# elif defined(HAVE_CDSASSL) + http_tls_t *conn; /* CDSA connection information */ + + + conn = (http_tls_t *)(http->tls); + + while (SSLClose(conn->session) == errSSLWouldBlock) + usleep(1000); + + SSLDisposeContext(conn->session); + + if (conn->certsArray) + CFRelease(conn->certsArray); + + free(conn); +# endif /* HAVE_LIBSSL */ + + http->tls = NULL; +} +#endif /* HAVE_SSL */ + + +#if defined(HAVE_LIBSSL) && defined(HAVE_PTHREAD_H) +/* + * 'http_threadid_cb()' - Return the current thread ID. + */ + +static unsigned long /* O - Thread ID */ +http_threadid_cb(void) +{ + return ((unsigned long)pthread_self()); +} +#endif /* HAVE_LIBSSL && HAVE_PTHREAD_H */ + + +#ifdef HAVE_SSL +/* + * 'http_upgrade()' - Force upgrade to TLS encryption. + */ + +static int /* O - Status of connection */ +http_upgrade(http_t *http) /* I - Connection to server */ +{ + int ret; /* Return value */ + http_t myhttp; /* Local copy of HTTP data */ + + + DEBUG_printf(("7http_upgrade(%p)", http)); + + /* + * Flush the connection to make sure any previous "Upgrade" message + * has been read. + */ + + httpFlush(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... + */ + + http->field_authorization = NULL; /* Don't free the auth string */ + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_CONNECTION, "upgrade"); + httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0"); + + if ((ret = httpOptions(http, "*")) == 0) + { + /* + * Wait for the secure connection... + */ + + while (httpUpdate(http) == HTTP_CONTINUE); + } + + /* + * Restore the HTTP request data... + */ + + memcpy(http->fields, myhttp.fields, sizeof(http->fields)); + http->data_encoding = myhttp.data_encoding; + http->data_remaining = myhttp.data_remaining; + http->_data_remaining = myhttp._data_remaining; + http->expect = myhttp.expect; + http->field_authorization = myhttp.field_authorization; + http->digest_tries = myhttp.digest_tries; + + /* + * See if we actually went secure... + */ + + if (!http->tls) + { + /* + * Server does not support HTTP upgrade... + */ + + DEBUG_puts("8http_upgrade: 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_SSL */ + + +/* + * 'http_write()' - Write a buffer to a HTTP connection. + */ + +static int /* O - Number of bytes written */ +http_write(http_t *http, /* I - Connection to server */ + const char *buffer, /* I - Buffer for data */ + int length) /* I - Number of bytes to write */ +{ + int tbytes, /* Total bytes sent */ + bytes; /* Bytes sent */ + + + http->error = 0; + tbytes = 0; + + while (length > 0) + { +#ifdef HAVE_SSL + if (http->tls) + bytes = http_write_ssl(http, buffer, length); + else +#endif /* HAVE_SSL */ + bytes = send(http->fd, buffer, length, 0); + + if (bytes < 0) + { +#ifdef WIN32 + if (WSAGetLastError() != http->error) + { + http->error = WSAGetLastError(); + continue; + } +#else + if (errno == EINTR || errno == EAGAIN) + continue; + else if (errno != http->error && errno != ECONNRESET) + { + http->error = errno; + continue; + } +#endif /* WIN32 */ + + DEBUG_puts("8http_write: error writing data..."); + + return (-1); + } + + buffer += bytes; + tbytes += bytes; + length -= bytes; + } + +#ifdef DEBUG + http_debug_hex("http_write", buffer - tbytes, tbytes); +#endif /* DEBUG */ + + return (tbytes); +} + + +/* + * 'http_write_chunk()' - Write a chunked buffer. + */ + +static int /* O - Number bytes written */ +http_write_chunk(http_t *http, /* I - Connection to server */ + const char *buffer, /* I - Buffer to write */ + int length) /* I - Length of buffer */ +{ + char header[255]; /* Chunk header */ + int bytes; /* Bytes written */ + + + DEBUG_printf(("7http_write_chunk(http=%p, buffer=%p, length=%d)", + http, buffer, length)); + + /* + * Write the chunk header, data, and trailer. + */ + + sprintf(header, "%x\r\n", length); + if (http_write(http, header, (int)strlen(header)) < 0) + { + DEBUG_puts("8http_write_chunk: http_write of length failed!"); + return (-1); + } + + if ((bytes = http_write(http, buffer, length)) < 0) + { + DEBUG_puts("8http_write_chunk: http_write of buffer failed!"); + return (-1); + } + + if (http_write(http, "\r\n", 2) < 0) + { + DEBUG_puts("8http_write_chunk: http_write of CR LF failed!"); + return (-1); + } + + return (bytes); +} + + +#ifdef HAVE_SSL +/* + * 'http_write_ssl()' - Write to a SSL/TLS connection. + */ + +static int /* O - Bytes written */ +http_write_ssl(http_t *http, /* I - Connection to server */ + const char *buf, /* I - Buffer holding data */ + int len) /* I - Length of buffer */ +{ +# if defined(HAVE_LIBSSL) + return (SSL_write((SSL *)(http->tls), buf, len)); + +# elif defined(HAVE_GNUTLS) + ssize_t result; /* Return value */ + + result = gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len); + + if (result < 0 && !errno) + { + /* + * Convert GNU TLS error to errno value... + */ + + switch (result) + { + case GNUTLS_E_INTERRUPTED : + errno = EINTR; + break; + + case GNUTLS_E_AGAIN : + errno = EAGAIN; + break; + + default : + errno = EPIPE; + break; + } + + result = -1; + } + + return ((int)result); + +# elif defined(HAVE_CDSASSL) + int result; /* Return value */ + OSStatus error; /* Error info */ + size_t processed; /* Number of bytes processed */ + + + error = SSLWrite(((http_tls_t *)http->tls)->session, buf, len, &processed); + + switch (error) + { + case 0 : + result = (int)processed; + break; + case errSSLClosedGraceful : + result = 0; + break; + case errSSLWouldBlock : + if (processed) + result = (int)processed; + else + { + result = -1; + errno = EINTR; + } + break; + default : + errno = EPIPE; + result = -1; + break; + } + + return (result); +# endif /* HAVE_LIBSSL */ +} +#endif /* HAVE_SSL */ + + +/* + * End of "$Id$". + */ diff --git a/cups/http.h b/cups/http.h new file mode 100644 index 0000000000..67a69f90a5 --- /dev/null +++ b/cups/http.h @@ -0,0 +1,453 @@ +/* + * "$Id$" + * + * Hyper-Text Transport Protocol definitions for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 "versioning.h" +# include +# include +# include +# ifdef WIN32 +# ifndef __CUPS_SSIZE_T_DEFINED +# define __CUPS_SSIZE_T_DEFINED +/* Windows does not support the ssize_t type, so map it to off_t... */ +typedef off_t ssize_t; /* @private@ */ +# endif /* !__CUPS_SSIZE_T_DEFINED */ +# include +# include +# else +# ifdef __sgi +# define INET6 /* IRIX IPv6 support... */ +# endif /* __sgi */ +# include +# include +# include +# include +# include +# include +# include +# include +# if !defined(__APPLE__) || !defined(TCP_NODELAY) +# include +# endif /* !__APPLE__ || !TCP_NODELAY */ +# if defined(AF_UNIX) && !defined(AF_LOCAL) +# define AF_LOCAL AF_UNIX /* Older UNIX's have old names... */ +# endif /* AF_UNIX && !AF_LOCAL */ +# ifdef AF_LOCAL +# include +# endif /* AF_LOCAL */ +# if defined(LOCAL_PEERCRED) && !defined(SO_PEERCRED) +# define SO_PEERCRED LOCAL_PEERCRED +# endif /* LOCAL_PEERCRED && !SO_PEERCRED */ +# endif /* WIN32 */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Oh, the wonderful world of IPv6 compatibility. Apparently some + * implementations expose the (more logical) 32-bit address parts + * to everyone, while others only expose it to kernel code... To + * make supporting IPv6 even easier, each vendor chose different + * core structure and union names, so the same defines or code + * can't be used on all platforms. + * + * The following will likely need tweaking on new platforms that + * support IPv6 - the "s6_addr32" define maps to the 32-bit integer + * array in the in6_addr union, which is named differently on various + * platforms. + */ + +#if defined(AF_INET6) && !defined(s6_addr32) +# if defined(__sun) +# define s6_addr32 _S6_un._S6_u32 +# elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)|| defined(__DragonFly__) +# define s6_addr32 __u6_addr.__u6_addr32 +# elif defined(__osf__) +# define s6_addr32 s6_un.sa6_laddr +# elif defined(WIN32) +/* + * Windows only defines byte and 16-bit word members of the union and + * requires special casing of all raw address code... + */ +# define s6_addr32 error_need_win32_specific_code +# endif /* __sun */ +#endif /* AF_INET6 && !s6_addr32 */ + + +/* + * 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 */ + + +/* + * Types and structures... + */ + +typedef enum http_auth_e /**** HTTP authentication types ****/ +{ + 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_NEGOTIATE /* GSSAPI authentication in use @since CUPS 1.3/Mac OS X 10.5@ */ +} http_auth_t; + +typedef enum http_encoding_e /**** HTTP transfer encoding values ****/ +{ + HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */ + HTTP_ENCODE_CHUNKED, /* Data is chunked */ + HTTP_ENCODE_FIELDS /* Sending HTTP fields */ +} http_encoding_t; + +typedef enum http_encryption_e /**** HTTP encryption values ****/ +{ + 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; + +typedef enum http_field_e /**** HTTP field names ****/ +{ + HTTP_FIELD_UNKNOWN = -1, /* Unknown field */ + HTTP_FIELD_ACCEPT_LANGUAGE, /* Accept-Language field */ + HTTP_FIELD_ACCEPT_RANGES, /* Accept-Ranges field */ + HTTP_FIELD_AUTHORIZATION, /* Authorization field */ + HTTP_FIELD_CONNECTION, /* Connection field */ + HTTP_FIELD_CONTENT_ENCODING, /* Content-Encoding field */ + HTTP_FIELD_CONTENT_LANGUAGE, /* Content-Language field */ + HTTP_FIELD_CONTENT_LENGTH, /* Content-Length field */ + HTTP_FIELD_CONTENT_LOCATION, /* Content-Location field */ + HTTP_FIELD_CONTENT_MD5, /* Content-MD5 field */ + HTTP_FIELD_CONTENT_RANGE, /* Content-Range field */ + HTTP_FIELD_CONTENT_TYPE, /* Content-Type field */ + HTTP_FIELD_CONTENT_VERSION, /* Content-Version field */ + HTTP_FIELD_DATE, /* Date field */ + HTTP_FIELD_HOST, /* Host field */ + HTTP_FIELD_IF_MODIFIED_SINCE, /* If-Modified-Since field */ + HTTP_FIELD_IF_UNMODIFIED_SINCE, /* If-Unmodified-Since field */ + HTTP_FIELD_KEEP_ALIVE, /* Keep-Alive field */ + HTTP_FIELD_LAST_MODIFIED, /* Last-Modified field */ + HTTP_FIELD_LINK, /* Link field */ + HTTP_FIELD_LOCATION, /* Location field */ + HTTP_FIELD_RANGE, /* Range field */ + HTTP_FIELD_REFERER, /* Referer field */ + HTTP_FIELD_RETRY_AFTER, /* Retry-After field */ + HTTP_FIELD_TRANSFER_ENCODING, /* Transfer-Encoding field */ + HTTP_FIELD_UPGRADE, /* Upgrade field */ + HTTP_FIELD_USER_AGENT, /* User-Agent field */ + HTTP_FIELD_WWW_AUTHENTICATE, /* WWW-Authenticate field */ + HTTP_FIELD_MAX /* Maximum field index */ +} http_field_t; + +typedef enum http_keepalive_e /**** HTTP keep-alive values ****/ +{ + HTTP_KEEPALIVE_OFF = 0, /* No keep alive support */ + HTTP_KEEPALIVE_ON /* Use keep alive */ +} http_keepalive_t; + +typedef enum http_state_e /**** HTTP state values; 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; + +typedef enum http_status_e /**** HTTP status codes ****/ +{ + 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_REQUESTED_RANGE, /* The requested range is not satisfiable */ + HTTP_EXPECTATION_FAILED, /* The expectation given in an Expect header field was not met */ + 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_AUTHORIZATION_CANCELED = 1000 /* User canceled authorization */ + +} http_status_t; + +typedef enum http_uri_status_e /**** URI separation status @since CUPS1.2@ ****/ +{ + HTTP_URI_OVERFLOW = -8, /* URI buffer for httpAssembleURI is too small */ + HTTP_URI_BAD_ARGUMENTS = -7, /* Bad arguments to function (error) */ + HTTP_URI_BAD_RESOURCE = -6, /* Bad resource in URI (error) */ + HTTP_URI_BAD_PORT = -5, /* Bad port number in URI (error) */ + HTTP_URI_BAD_HOSTNAME = -4, /* Bad hostname in URI (error) */ + HTTP_URI_BAD_USERNAME = -3, /* Bad username in URI (error) */ + HTTP_URI_BAD_SCHEME = -2, /* Bad scheme in URI (error) */ + HTTP_URI_BAD_URI = -1, /* Bad/empty URI (error) */ + HTTP_URI_OK = 0, /* URI decoded OK */ + HTTP_URI_MISSING_SCHEME, /* Missing scheme in URI (warning) */ + HTTP_URI_UNKNOWN_SCHEME, /* Unknown scheme in URI (warning) */ + HTTP_URI_MISSING_RESOURCE /* Missing resource in URI (warning) */ +} http_uri_status_t; + +typedef enum http_uri_coding_e /**** URI en/decode flags ****/ +{ + HTTP_URI_CODING_NONE = 0, /* Don't en/decode anything */ + HTTP_URI_CODING_USERNAME = 1, /* En/decode the username portion */ + HTTP_URI_CODING_HOSTNAME = 2, /* En/decode the hostname portion */ + HTTP_URI_CODING_RESOURCE = 4, /* En/decode the resource portion */ + HTTP_URI_CODING_MOST = 7, /* En/decode all but the query */ + HTTP_URI_CODING_QUERY = 8, /* En/decode the query portion */ + HTTP_URI_CODING_ALL = 15 /* En/decode everything */ +} http_uri_coding_t; + +typedef enum http_version_e /**** HTTP version numbers ****/ +{ + HTTP_0_9 = 9, /* HTTP/0.9 */ + HTTP_1_0 = 100, /* HTTP/1.0 */ + HTTP_1_1 = 101 /* HTTP/1.1 */ +} http_version_t; + +typedef union _http_addr_u /**** Socket address union, which + **** makes using IPv6 and other + **** address types easier and + **** more portable. @since CUPS 1.2/Mac OS X 10.5@ + ****/ +{ + struct sockaddr addr; /* Base structure for family value */ + struct sockaddr_in ipv4; /* IPv4 address */ +#ifdef AF_INET6 + struct sockaddr_in6 ipv6; /* IPv6 address */ +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + struct sockaddr_un un; /* Domain socket file */ +#endif /* AF_LOCAL */ + char pad[256]; /* Padding to ensure binary compatibility */ +} http_addr_t; + +typedef struct http_addrlist_s /**** Socket address list, which is + **** used to enumerate all of the + **** addresses that are associated + **** with a hostname. @since CUPS 1.2/Mac OS X 10.5@ + ****/ +{ + struct http_addrlist_s *next; /* Pointer to next address in list */ + http_addr_t addr; /* Address */ +} http_addrlist_t; + +typedef struct _http_s http_t; /**** HTTP connection type ****/ + + +/* + * Prototypes... + */ + +extern void httpBlocking(http_t *http, int b); +extern int httpCheck(http_t *http); +extern void httpClearFields(http_t *http); +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 encryption); +extern int httpDelete(http_t *http, const char *uri); +extern int httpEncryption(http_t *http, http_encryption_t e); +extern int httpError(http_t *http); +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); +extern const char *httpGetField(http_t *http, http_field_t 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) _CUPS_DEPRECATED; +extern int httpReconnect(http_t *http); +extern void httpSeparate(const char *uri, char *method, + char *username, char *host, int *port, + char *resource) _CUPS_DEPRECATED; +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) _CUPS_DEPRECATED; +extern char *httpEncode64(char *out, const char *in) _CUPS_DEPRECATED; +extern char *httpDecode64(char *out, const char *in) _CUPS_DEPRECATED; +extern int httpGetLength(http_t *http) _CUPS_DEPRECATED; +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 unsigned char *, char [33]); + +/**** New in CUPS 1.1.19 ****/ +extern void httpClearCookie(http_t *http) _CUPS_API_1_1_19; +extern const char *httpGetCookie(http_t *http) _CUPS_API_1_1_19; +extern void httpSetCookie(http_t *http, const char *cookie) _CUPS_API_1_1_19; +extern int httpWait(http_t *http, int msec) _CUPS_API_1_1_19; + +/**** New in CUPS 1.1.21 ****/ +extern char *httpDecode64_2(char *out, int *outlen, const char *in) _CUPS_API_1_1_21; +extern char *httpEncode64_2(char *out, int outlen, const char *in, + int inlen) _CUPS_API_1_1_21; +extern void httpSeparate2(const char *uri, + char *method, int methodlen, + char *username, int usernamelen, + char *host, int hostlen, int *port, + char *resource, int resourcelen) _CUPS_DEPRECATED; + +/**** New in CUPS 1.2/Mac OS X 10.5 ****/ +extern int httpAddrAny(const http_addr_t *addr) _CUPS_API_1_2; +extern http_addrlist_t *httpAddrConnect(http_addrlist_t *addrlist, int *sock) _CUPS_API_1_2; +extern int httpAddrEqual(const http_addr_t *addr1, + const http_addr_t *addr2) _CUPS_API_1_2; +extern void httpAddrFreeList(http_addrlist_t *addrlist) _CUPS_API_1_2; +extern http_addrlist_t *httpAddrGetList(const char *hostname, int family, + const char *service) _CUPS_API_1_2; +extern int httpAddrLength(const http_addr_t *addr) _CUPS_API_1_2; +extern int httpAddrLocalhost(const http_addr_t *addr) _CUPS_API_1_2; +extern char *httpAddrLookup(const http_addr_t *addr, + char *name, int namelen) _CUPS_API_1_2; +extern char *httpAddrString(const http_addr_t *addr, + char *s, int slen) _CUPS_API_1_2; +extern http_uri_status_t httpAssembleURI(http_uri_coding_t encoding, + char *uri, int urilen, + const char *scheme, + const char *username, + const char *host, int port, + const char *resource) _CUPS_API_1_2; +extern http_uri_status_t httpAssembleURIf(http_uri_coding_t encoding, + char *uri, int urilen, + const char *scheme, + const char *username, + const char *host, int port, + const char *resourcef, ...) _CUPS_API_1_2; +extern int httpFlushWrite(http_t *http) _CUPS_API_1_2; +extern int httpGetBlocking(http_t *http) _CUPS_API_1_2; +extern const char *httpGetDateString2(time_t t, char *s, int slen) _CUPS_API_1_2; +extern int httpGetFd(http_t *http) _CUPS_API_1_2; +extern const char *httpGetHostname(http_t *http, char *s, int slen) _CUPS_API_1_2; +extern off_t httpGetLength2(http_t *http) _CUPS_API_1_2; +extern http_status_t httpGetStatus(http_t *http) _CUPS_API_1_2; +extern char *httpGetSubField2(http_t *http, http_field_t field, + const char *name, char *value, + int valuelen) _CUPS_API_1_2; +extern ssize_t httpRead2(http_t *http, char *buffer, size_t length) _CUPS_API_1_2; +extern http_uri_status_t httpSeparateURI(http_uri_coding_t decoding, + const char *uri, + char *scheme, int schemelen, + char *username, int usernamelen, + char *host, int hostlen, int *port, + char *resource, int resourcelen) _CUPS_API_1_2; +extern void httpSetExpect(http_t *http, http_status_t expect) _CUPS_API_1_2; +extern void httpSetLength(http_t *http, size_t length) _CUPS_API_1_2; +extern ssize_t httpWrite2(http_t *http, const char *buffer, + size_t length) _CUPS_API_1_2; + +/**** New in CUPS 1.3/Mac OS X 10.5 ****/ +extern char *httpGetAuthString(http_t *http) _CUPS_API_1_3; +extern void httpSetAuthString(http_t *http, const char *scheme, + const char *data) _CUPS_API_1_3; + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_HTTP_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/i18n.h b/cups/i18n.h new file mode 100644 index 0000000000..0a43c3502a --- /dev/null +++ b/cups/i18n.h @@ -0,0 +1,115 @@ +/* + * "$Id$" + * + * (Private) localization support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_I18N_H_ +# define _CUPS_I18N_H_ + +/* + * Include necessary headers... + */ + +# include +# include "transcode.h" + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Macro for localized text... + */ + +# define _(x) x + + +/* + * Types... + */ + +typedef struct _cups_message_s /**** Message catalog entry ****/ +{ + char *id, /* Original string */ + *str; /* Localized string */ +} _cups_message_t; + +typedef struct _cups_cmap_s /**** SBCS Charmap Struct ****/ +{ + struct _cups_cmap_s *next; /* Next charmap in cache */ + int used; /* Number of times entry used */ + cups_encoding_t encoding; /* Legacy charset encoding */ + cups_ucs2_t char2uni[256]; /* Map Legacy SBCS -> UCS-2 */ + cups_sbcs_t *uni2char[256]; /* Map UCS-2 -> Legacy SBCS */ +} _cups_cmap_t; + +typedef struct _cups_wide2uni_s /**** Wide to Unicode ****/ +{ + cups_vbcs_t widechar; /* VBCS 32-bit Char (EUC) */ + cups_ucs2_t unichar; /* UCS-2 Char */ +} _cups_wide2uni_t; + +typedef struct _cups_vmap_s /**** VBCS Charmap Struct ****/ +{ + struct _cups_vmap_s *next; /* Next charmap in cache */ + int used; /* Number of times entry used */ + cups_encoding_t encoding; /* Legacy charset encoding */ + cups_ucs2_t *char2uni[256]; /* Map 16-bit Char -> UCS-2 */ + int charcount; /* Count of 16-bit VBCS Chars */ + _cups_wide2uni_t *wide2uni; /* Map 32-bit Char -> UCS-2 */ + int widecount; /* Count of 32-bit VBCS Chars */ + cups_vbcs_t *uni2char[256]; /* Map UCS-2 -> 32-bit VBCS */ + cups_sbcs_t lead2char[256]; /* Legacy Lead Char - 2-byte */ + cups_sbcs_t lead3char[256]; /* Legacy Lead Char - 3-byte */ + cups_sbcs_t lead4char[256]; /* Legacy Lead Char - 4-byte */ +} _cups_vmap_t; + + +/* + * Prototypes... + */ + +#ifdef __APPLE__ +extern const char *_cupsAppleLanguage(const char *locale, char *language, + size_t langsize); +#endif /* __APPLE__ */ +extern void _cupsCharmapFlush(void); +extern void _cupsCharmapFree(const cups_encoding_t encoding); +extern void *_cupsCharmapGet(const cups_encoding_t encoding); +extern const char *_cupsEncodingName(cups_encoding_t encoding); +extern void _cupsLangPrintError(const char *message); +extern int _cupsLangPrintf(FILE *fp, const char *message, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +# endif /* __GNUC__ */ +; +extern int _cupsLangPuts(FILE *fp, const char *message); +extern const char *_cupsLangString(cups_lang_t *lang, const char *message); +extern void _cupsMessageFree(cups_array_t *a); +extern cups_array_t *_cupsMessageLoad(const char *filename, int unquote); +extern const char *_cupsMessageLookup(cups_array_t *a, const char *m); +extern void _cupsSetLocale(char *argv[]); + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_I18N_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/ipp-private.h b/cups/ipp-private.h new file mode 100644 index 0000000000..eee7922435 --- /dev/null +++ b/cups/ipp-private.h @@ -0,0 +1,85 @@ +/* + * "$Id$" + * + * Private IPP definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_IPP_PRIVATE_H_ +# define _CUPS_IPP_PRIVATE_H_ + +/* + * Include necessary headers... + */ + +# include "ipp.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Constants... + */ + +# define IPP_BUF_SIZE (IPP_MAX_LENGTH + 2) + /* Size of buffer */ + + +/* + * Structures... + */ + +typedef struct _ipp_buffer_s /**** Read/write buffer ****/ +{ + unsigned char d[IPP_BUF_SIZE];/* Data buffer */ + struct _ipp_buffer_s *next; /* Next buffer in list */ + int used; /* Is this buffer used? */ +} _ipp_buffer_t; + +typedef struct /**** Attribute mapping data ****/ +{ + int multivalue; /* Option has multiple values? */ + const char *name; /* Option/attribute name */ + ipp_tag_t value_tag; /* Value tag for this attribute */ + ipp_tag_t group_tag; /* Group tag for this attribute */ +} _ipp_option_t; + + +/* + * Prototypes for private functions... + */ + +extern ipp_attribute_t *_ippAddAttr(ipp_t *, int); +extern _ipp_option_t *_ippFindOption(const char *name); +extern void _ippFreeAttr(ipp_attribute_t *); + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_IPP_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/ipp-support.c b/cups/ipp-support.c new file mode 100644 index 0000000000..9c3231c042 --- /dev/null +++ b/cups/ipp-support.c @@ -0,0 +1,482 @@ +/* + * "$Id$" + * + * Internet Printing Protocol support functions for the Common UNIX + * Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * ippErrorString() - Return a name for the given status code. + * ippErrorValue() - Return a status code for the given name. + * ippOpString() - Return a name for the given operation id. + * ippOpValue() - Return an operation id for the given name. + * ippPort() - Return the default IPP port number. + * ippSetPort() - Set the default port number. + * ippTagString() - Return the tag name corresponding to a tag value. + * ippTagValue() - Return the tag value corresponding to a tag name. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include + + +/* + * Local globals... + */ + +static const char * const ipp_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", + "successful-ok-events-complete" + }, + * const ipp_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" + }, + * const ipp_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" + }; +static char * const ipp_std_ops[] = + { + /* 0x0000 - 0x000f */ + "", "", "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", "", + + /* 0x0010 - 0x001f */ + "Pause-Printer", "Resume-Printer", + "Purge-Jobs", "Set-Printer-Attributes", + "Set-Job-Attributes", + "Get-Printer-Supported-Values", + "Create-Printer-Subscription", + "Create-Job-Subscription", + "Get-Subscription-Attributes", + "Get-Subscriptions", "Renew-Subscription", + "Cancel-Subscription", "Get-Notifications", + "Send-Notifications", "", "", + + /* 0x0020 - 0x002f */ + "", + "Get-Printer-Support-Files", + "Enable-Printer", + "Disable-Printer", + "Pause-Printer-After-Current-Job", + "Hold-New-Jobs", + "Release-Held-New-Jobs", + "Deactivate-Printer", + "Activate-Printer", + "Restart-Printer", + "Shutdown-Printer", + "Startup-Printer", + "Reprocess-Job", + "Cancel-Current-Job", + "Suspend-Current-Job", + "Resume-Job", + + /* 0x0030 - 0x0031 */ + "Promote-Job", + "Schedule-Job-After" + }, + * const ipp_cups_ops[] = + { + "CUPS-Get-Default", + "CUPS-Get-Printers", + "CUPS-Add-Modify-Printer", + "CUPS-Delete-Printer", + "CUPS-Get-Classes", + "CUPS-Add-Modify-Class", + "CUPS-Delete-Class", + "CUPS-Accept-Jobs", + "CUPS-Reject-Jobs", + "CUPS-Set-Default", + "CUPS-Get-Devices", + "CUPS-Get-PPDs", + "CUPS-Move-Job", + "CUPS-Authenticate-Job", + "CUPS-Get-PPD" + }, + * const ipp_cups_ops2[] = + { + "CUPS-Get-Document" + }, + * const ipp_tag_names[] = + { /* Value/group tag names */ + "zero", /* 0x00 */ + "operation-attributes-tag", + /* 0x01 */ + "job-attributes-tag", /* 0x02 */ + "end-of-attributes-tag", + /* 0x03 */ + "printer-attributes-tag", + /* 0x04 */ + "unsupported-attributes-tag", + /* 0x05 */ + "subscription-attributes-tag", + /* 0x06 */ + "event-notification-attributes-tag", + /* 0x07 */ + "unknown-08", /* 0x08 */ + "unknown-09", /* 0x09 */ + "unknown-0a", /* 0x0a */ + "unknown-0b", /* 0x0b */ + "unknown-0c", /* 0x0c */ + "unknown-0d", /* 0x0d */ + "unknown-0e", /* 0x0e */ + "unknown-0f", /* 0x0f */ + "unsupported", /* 0x10 */ + "default", /* 0x11 */ + "unknown", /* 0x12 */ + "no-value", /* 0x13 */ + "unknown-14", /* 0x14 */ + "not-settable", /* 0x15 */ + "delete-attribute", /* 0x16 */ + "admin-define", /* 0x17 */ + "unknown-18", /* 0x18 */ + "unknown-19", /* 0x19 */ + "unknown-1a", /* 0x1a */ + "unknown-1b", /* 0x1b */ + "unknown-1c", /* 0x1c */ + "unknown-1d", /* 0x1d */ + "unknown-1e", /* 0x1e */ + "unknown-1f", /* 0x1f */ + "unknown-20", /* 0x20 */ + "integer", /* 0x21 */ + "boolean", /* 0x22 */ + "enum", /* 0x23 */ + "unknown-24", /* 0x24 */ + "unknown-25", /* 0x25 */ + "unknown-26", /* 0x26 */ + "unknown-27", /* 0x27 */ + "unknown-28", /* 0x28 */ + "unknown-29", /* 0x29 */ + "unknown-2a", /* 0x2a */ + "unknown-2b", /* 0x2b */ + "unknown-2c", /* 0x2c */ + "unknown-2d", /* 0x2d */ + "unknown-2e", /* 0x2e */ + "unknown-2f", /* 0x2f */ + "octetString", /* 0x30 */ + "dateTime", /* 0x31 */ + "resolution", /* 0x32 */ + "rangeOfInteger", /* 0x33 */ + "begCollection", /* 0x34 */ + "textWithLanguage", /* 0x35 */ + "nameWithLanguage", /* 0x36 */ + "endCollection", /* 0x37 */ + "unknown-38", /* 0x38 */ + "unknown-39", /* 0x39 */ + "unknown-3a", /* 0x3a */ + "unknown-3b", /* 0x3b */ + "unknown-3c", /* 0x3c */ + "unknown-3d", /* 0x3d */ + "unknown-3e", /* 0x3e */ + "unknown-3f", /* 0x3f */ + "unknown-40", /* 0x40 */ + "textWithoutLanguage",/* 0x41 */ + "nameWithoutLanguage",/* 0x42 */ + "unknown-43", /* 0x43 */ + "keyword", /* 0x44 */ + "uri", /* 0x45 */ + "uriScheme", /* 0x46 */ + "charset", /* 0x47 */ + "naturalLanguage", /* 0x48 */ + "mimeMediaType", /* 0x49 */ + "memberAttrName" /* 0x4a */ + }; + + +/* + * 'ippErrorString()' - Return a name for the given status code. + */ + +const char * /* O - Text string */ +ippErrorString(ipp_status_t error) /* I - Error status */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * See if the error code is a known value... + */ + + if (error >= IPP_OK && error <= IPP_OK_EVENTS_COMPLETE) + return (ipp_status_oks[error]); + else if (error == IPP_REDIRECTION_OTHER_SITE) + return ("redirection-other-site"); + else if (error == CUPS_SEE_OTHER) + return ("cups-see-other"); + else if (error >= IPP_BAD_REQUEST && error <= IPP_PRINT_SUPPORT_FILE_NOT_FOUND) + return (ipp_status_400s[error - IPP_BAD_REQUEST]); + else if (error >= IPP_INTERNAL_ERROR && error <= IPP_PRINTER_IS_DEACTIVATED) + return (ipp_status_500s[error - IPP_INTERNAL_ERROR]); + + /* + * No, build an "unknown-xxxx" error string... + */ + + sprintf(cg->ipp_unknown, "unknown-%04x", error); + + return (cg->ipp_unknown); +} + + +/* + * 'ippErrorValue()' - Return a status code for the given name. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ipp_status_t /* O - IPP status code */ +ippErrorValue(const char *name) /* I - Name */ +{ + int i; + + + for (i = 0; i < (sizeof(ipp_status_oks) / sizeof(ipp_status_oks[0])); i ++) + if (!strcasecmp(name, ipp_status_oks[i])) + return ((ipp_status_t)i); + + if (!strcasecmp(name, "redirection-other-site")) + return (IPP_REDIRECTION_OTHER_SITE); + + if (!strcasecmp(name, "cups-see-other")) + return (CUPS_SEE_OTHER); + + for (i = 0; i < (sizeof(ipp_status_400s) / sizeof(ipp_status_400s[0])); i ++) + if (!strcasecmp(name, ipp_status_400s[i])) + return ((ipp_status_t)(i + 0x400)); + + for (i = 0; i < (sizeof(ipp_status_500s) / sizeof(ipp_status_500s[0])); i ++) + if (!strcasecmp(name, ipp_status_500s[i])) + return ((ipp_status_t)(i + 0x500)); + + return ((ipp_status_t)-1); +} + + +/* + * 'ippOpString()' - Return a name for the given operation id. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +const char * /* O - Name */ +ippOpString(ipp_op_t op) /* I - Operation ID */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * See if the operation ID is a known value... + */ + + if (op >= IPP_PRINT_JOB && op <= IPP_SCHEDULE_JOB_AFTER) + return (ipp_std_ops[op]); + else if (op == IPP_PRIVATE) + return ("windows-ext"); + else if (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD) + return (ipp_cups_ops[op - CUPS_GET_DEFAULT]); + else if (op == CUPS_GET_DOCUMENT) + return (ipp_cups_ops2[0]); + + /* + * No, build an "unknown-xxxx" operation string... + */ + + sprintf(cg->ipp_unknown, "unknown-%04x", op); + + return (cg->ipp_unknown); +} + + +/* + * 'ippOpValue()' - Return an operation id for the given name. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ipp_op_t /* O - Operation ID */ +ippOpValue(const char *name) /* I - Textual name */ +{ + int i; + + + for (i = 0; i < (sizeof(ipp_std_ops) / sizeof(ipp_std_ops[0])); i ++) + if (!strcasecmp(name, ipp_std_ops[i])) + return ((ipp_op_t)i); + + if (!strcasecmp(name, "windows-ext")) + return (IPP_PRIVATE); + + for (i = 0; i < (sizeof(ipp_cups_ops) / sizeof(ipp_cups_ops[0])); i ++) + if (!strcasecmp(name, ipp_cups_ops[i])) + return ((ipp_op_t)(i + 0x4001)); + + for (i = 0; i < (sizeof(ipp_cups_ops2) / sizeof(ipp_cups_ops2[0])); i ++) + if (!strcasecmp(name, ipp_cups_ops2[i])) + return ((ipp_op_t)(i + 0x4027)); + + if (!strcasecmp(name, "CUPS-Add-Class")) + return (CUPS_ADD_MODIFY_CLASS); + + if (!strcasecmp(name, "CUPS-Add-Printer")) + return (CUPS_ADD_MODIFY_PRINTER); + + return ((ipp_op_t)-1); +} + + +/* + * 'ippPort()' - Return the default IPP port number. + */ + +int /* O - Port number */ +ippPort(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + DEBUG_puts("ippPort()"); + + if (!cg->ipp_port) + _cupsSetDefaults(); + + DEBUG_printf(("1ippPort: Returning %d...", cg->ipp_port)); + + return (cg->ipp_port); +} + + +/* + * 'ippSetPort()' - Set the default port number. + */ + +void +ippSetPort(int p) /* I - Port number to use */ +{ + DEBUG_printf(("ippSetPort(p=%d)", p)); + + _cupsGlobals()->ipp_port = p; +} + + +/* + * 'ippTagString()' - Return the tag name corresponding to a tag value. + * + * The returned names are defined in RFC 2911 and 3382. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +const char * /* O - Tag name */ +ippTagString(ipp_tag_t tag) /* I - Tag value */ +{ + tag &= IPP_TAG_MASK; + + if (tag < (ipp_tag_t)(sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0]))) + return (ipp_tag_names[tag]); + else + return ("UNKNOWN"); +} + + +/* + * 'ippTagValue()' - Return the tag value corresponding to a tag name. + * + * The tag names are defined in RFC 2911 and 3382. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ipp_tag_t /* O - Tag value */ +ippTagValue(const char *name) /* I - Tag name */ +{ + int i; /* Looping var */ + + + for (i = 0; i < (sizeof(ipp_tag_names) / sizeof(ipp_tag_names[0])); i ++) + if (!strcasecmp(name, ipp_tag_names[i])) + return ((ipp_tag_t)i); + + if (!strcasecmp(name, "operation")) + return (IPP_TAG_OPERATION); + else if (!strcasecmp(name, "job")) + return (IPP_TAG_JOB); + else if (!strcasecmp(name, "printer")) + return (IPP_TAG_PRINTER); + else if (!strcasecmp(name, "subscription")) + return (IPP_TAG_SUBSCRIPTION); + else if (!strcasecmp(name, "language")) + return (IPP_TAG_LANGUAGE); + else if (!strcasecmp(name, "mimetype")) + return (IPP_TAG_MIMETYPE); + else if (!strcasecmp(name, "name")) + return (IPP_TAG_NAME); + else if (!strcasecmp(name, "text")) + return (IPP_TAG_TEXT); + else + return (IPP_TAG_ZERO); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/ipp.c b/cups/ipp.c new file mode 100644 index 0000000000..ae7746a4bf --- /dev/null +++ b/cups/ipp.c @@ -0,0 +1,3210 @@ +/* + * "$Id$" + * + * Internet Printing Protocol functions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * ippAddBoolean() - Add a boolean attribute to an IPP message. + * ippAddBooleans() - Add an array of boolean values. + * ippAddDate() - Add a date attribute to an IPP message. + * ippAddInteger() - Add a integer attribute to an IPP message. + * ippAddIntegers() - Add an array of integer values. + * ippAddOctetString() - Add an octetString value to an IPP message. + * ippAddString() - Add a language-encoded string to an IPP message. + * ippAddStrings() - Add language-encoded strings to an IPP message. + * ippAddRange() - Add a range of values to an IPP message. + * ippAddRanges() - Add ranges of values to an IPP message. + * ippAddResolution() - Add a resolution value to an IPP message. + * ippAddResolutions() - Add resolution values to an IPP message. + * ippAddSeparator() - Add a group separator to an IPP message. + * ippDateToTime() - Convert from RFC 1903 Date/Time format to + * UNIX time in seconds. + * ippDelete() - Delete an IPP message. + * ippDeleteAttribute() - Delete a single attribute in an IPP message. + * ippFindAttribute() - Find a named attribute in a request... + * ippFindNextAttribute() - Find the next named attribute in a request... + * ippLength() - Compute the length of an IPP message. + * ippNew() - Allocate a new IPP message. + * ippNewRequest() - Allocate a new IPP message. + * ippRead() - Read data for an IPP message from a HTTP + * connection. + * ippReadFile() - Read data for an IPP message from a file. + * ippReadIO() - Read data for an IPP message. + * ippTimeToDate() - Convert from UNIX time to RFC 1903 format. + * ippWrite() - Write data for an IPP message to a HTTP + * connection. + * ippWriteFile() - Write data for an IPP message to a file. + * ippWriteIO() - Write data for an IPP message. + * _ippAddAttr() - Add a new attribute to the request. + * _ippFreeAttr() - Free an attribute. + * ipp_length() - Compute the length of an IPP message or + * collection value. + * ipp_read_http() - Semi-blocking read on a HTTP connection... + * ipp_read_file() - Read IPP data from a file. + * ipp_write_file() - Write IPP data to a file. + */ + +/* + * Include necessary headers... + */ + +#include "http-private.h" +#include "globals.h" +#include "debug.h" +#include +#include +#ifdef WIN32 +# include +#endif /* WIN32 */ + + +/* + * Local functions... + */ + +static unsigned char *ipp_buffer_get(void); +static void ipp_buffer_release(unsigned char *b); +static size_t ipp_length(ipp_t *ipp, int collection); +static ssize_t ipp_read_http(http_t *http, ipp_uchar_t *buffer, + size_t length); +static ssize_t ipp_read_file(int *fd, ipp_uchar_t *buffer, + size_t length); +static ssize_t ipp_write_file(int *fd, ipp_uchar_t *buffer, + size_t length); + + +/* + * 'ippAddBoolean()' - Add a boolean attribute to an IPP message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddBoolean(ipp_t *ipp, /* I - IPP message */ + 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(ipp=%p, group=%02x(%s), name=\"%s\", value=%d)", + ipp, group, ippTagString(group), name, value)); + + if (!ipp || !name) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message */ + 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(ipp=%p, group=%02x(%s), name=\"%s\", " + "num_values=%d, values=%p)", ipp, group, ippTagString(group), + name, num_values, values)); + + if (!ipp || !name || num_values < 1) + return (NULL); + + if ((attr = _ippAddAttr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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); +} + + +/* + * 'ippAddCollection()' - Add a collection value. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddCollection(ipp_t *ipp, /* I - IPP message */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + ipp_t *value) /* I - Value */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddCollection(ipp=%p, group=%02x(%s), name=\"%s\", " + "value=%p)", ipp, group, ippTagString(group), name, value)); + + if (!ipp || !name) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_BEGIN_COLLECTION; + attr->values[0].collection = value; + + value->use ++; + + return (attr); +} + + +/* + * 'ippAddCollections()' - Add an array of collection values. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddCollections( + ipp_t *ipp, /* I - IPP message */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + int num_values, /* I - Number of values */ + const ipp_t **values) /* I - Values */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ + + + DEBUG_printf(("ippAddCollections(ipp=%p, group=%02x(%s), name=\"%s\", " + "num_values=%d, values=%p)", ipp, group, ippTagString(group), + name, num_values, values)); + + if (!ipp || !name || num_values < 1) + return (NULL); + + if ((attr = _ippAddAttr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_BEGIN_COLLECTION; + + if (values != NULL) + { + for (i = 0, value = attr->values; + i < num_values; + i ++, value ++) + { + value->collection = (ipp_t *)values[i]; + value->collection->use ++; + } + } + + return (attr); +} + + +/* + * 'ippAddDate()' - Add a date attribute to an IPP message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddDate(ipp_t *ipp, /* I - IPP message */ + 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(ipp=%p, group=%02x(%s), name=\"%s\", value=%p)", + ipp, group, ippTagString(group), name, value)); + + if (!ipp || !name || !value) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddInteger(ipp_t *ipp, /* I - IPP message */ + 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(ipp=%p, group=%02x(%s), type=%02x(%s), " + "name=\"%s\", value=%d)", ipp, group, ippTagString(group), + type, ippTagString(type), name, value)); + + if (!ipp || !name) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message */ + 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 */ + + + DEBUG_printf(("ippAddIntegers(ipp=%p, group=%02x(%s), type=%02x(%s), " + "name=\"%s\", num_values=%d, values=%p)", ipp, + group, ippTagString(group), type, ippTagString(type), name, + num_values, values)); + + if (!ipp || !name || num_values < 1) + return (NULL); + + if ((attr = _ippAddAttr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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); +} + + +/* + * 'ippAddOctetString()' - Add an octetString value to an IPP message. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddOctetString(ipp_t *ipp, /* I - IPP message */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + const void *data, /* I - octetString data */ + int datalen) /* I - Length of data in bytes */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + /* + * Initialize the attribute data... + */ + + attr->name = _cupsStrAlloc(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_STRING; + attr->values[0].unknown.length = datalen; + + if (data) + { + if ((attr->values[0].unknown.data = malloc(datalen)) == NULL) + { + ippDeleteAttribute(ipp, attr); + return (NULL); + } + + memcpy(attr->values[0].unknown.data, data, datalen); + } + + /* + * Return the new attribute... + */ + + return (attr); +} + + +/* + * 'ippAddString()' - Add a language-encoded string to an IPP message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddString(ipp_t *ipp, /* I - IPP message */ + 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 */ + char buffer[1024], /* Language/charset value buffer */ + *bufptr; /* Pointer into buffer */ + + + DEBUG_printf(("ippAddString(ipp=%p, group=%02x(%s), type=%02x(%s), " + "name=\"%s\", charset=\"%s\", value=\"%s\")", ipp, + group, ippTagString(group), type, ippTagString(type), name, + charset, value)); + + if (!ipp || !name) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + /* + * Force value to be English for the POSIX locale... + */ + + if (type == IPP_TAG_LANGUAGE && !strcasecmp(value, "C")) + value = "en"; + + /* + * Convert language and charset values to lowercase and change _ to - as + * needed... + */ + + if ((type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) && value) + { + strlcpy(buffer, value, sizeof(buffer)); + value = buffer; + + for (bufptr = buffer; *bufptr; bufptr ++) + if (*bufptr == '_') + *bufptr = '-'; + else + *bufptr = tolower(*bufptr & 255); + } + + /* + * Initialize the attribute data... + */ + + attr->name = _cupsStrAlloc(name); + attr->group_tag = group; + attr->value_tag = type; + attr->values[0].string.charset = ((int)type & IPP_TAG_COPY) ? (char *)charset : + charset ? _cupsStrAlloc(charset) : NULL; + attr->values[0].string.text = ((int)type & IPP_TAG_COPY) ? (char *)value : + value ? _cupsStrAlloc(value) : NULL; + + return (attr); +} + + +/* + * 'ippAddStrings()' - Add language-encoded strings to an IPP message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddStrings( + ipp_t *ipp, /* I - IPP message */ + 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 * const *values) /* I - Values */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + ipp_value_t *value; /* Current value */ + char buffer[1024], /* Language/charset value buffer */ + *bufptr; /* Pointer into buffer */ + + + DEBUG_printf(("ippAddStrings(ipp=%p, group=%02x(%s), type=%02x(%s), " + "name=\"%s\", num_values=%d, charset=\"%s\", values=%p)", ipp, + group, ippTagString(group), type, ippTagString(type), name, + num_values, charset, values)); + + if (!ipp || !name || num_values < 1) + return (NULL); + + if ((attr = _ippAddAttr(ipp, num_values)) == NULL) + return (NULL); + + /* + * Initialize the attribute data... + */ + + attr->name = _cupsStrAlloc(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 ? _cupsStrAlloc(charset) : NULL; + else + value->string.charset = attr->values[0].string.charset; + + if (values != NULL) + { + if ((int)type & IPP_TAG_COPY) + value->string.text = (char *)values[i]; + else if (type == IPP_TAG_LANGUAGE && !strcasecmp(values[i], "C")) + { + /* + * Force language to be English for the POSIX locale... + */ + + value->string.text = ((int)type & IPP_TAG_COPY) ? "en" : + _cupsStrAlloc("en"); + } + else if (type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) + { + /* + * Convert language values to lowercase and change _ to - as needed... + */ + + strlcpy(buffer, values[i], sizeof(buffer)); + + for (bufptr = buffer; *bufptr; bufptr ++) + if (*bufptr == '_') + *bufptr = '-'; + else + *bufptr = tolower(*bufptr & 255); + + value->string.text = _cupsStrAlloc(buffer); + } + else + value->string.text = _cupsStrAlloc(values[i]); + + } + } + + return (attr); +} + + +/* + * 'ippAddRange()' - Add a range of values to an IPP message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddRange(ipp_t *ipp, /* I - IPP message */ + 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 */ + + + DEBUG_printf(("ippAddRange(ipp=%p, group=%02x(%s), name=\"%s\", lower=%d, " + "upper=%d)", ipp, group, ippTagString(group), name, lower, + upper)); + + if (!ipp || !name) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddRanges(ipp_t *ipp, /* I - IPP message */ + 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 */ + + + DEBUG_printf(("ippAddRanges(ipp=%p, group=%02x(%s), name=\"%s\", " + "num_values=%d, lower=%p, upper=%p)", ipp, group, + ippTagString(group), name, num_values, lower, upper)); + + if (!ipp || !name || num_values < 1) + return (NULL); + + if ((attr = _ippAddAttr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddResolution(ipp_t *ipp, /* I - IPP message */ + 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 */ + + + DEBUG_printf(("ippAddResolution(ipp=%p, group=%02x(%s), name=\"%s\", " + "units=%d, xres=%d, yres=%d)", ipp, group, + ippTagString(group), name, units, xres, yres)); + + if (!ipp || !name) + return (NULL); + + if ((attr = _ippAddAttr(ipp, 1)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddResolutions(ipp_t *ipp, /* I - IPP message */ + 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 */ + + + DEBUG_printf(("ippAddResolutions(ipp=%p, group=%02x(%s), name=\"%s\", " + "num_value=%d, units=%d, xres=%p, yres=%p)", ipp, group, + ippTagString(group), name, num_values, units, xres, yres)); + + if (!ipp || !name || num_values < 1) + return (NULL); + + if ((attr = _ippAddAttr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = _cupsStrAlloc(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 message. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddSeparator(ipp_t *ipp) /* I - IPP message */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddSeparator(ipp=%p)", ipp)); + + if (!ipp) + return (NULL); + + if ((attr = _ippAddAttr(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 */ + + + if (!date) + return (0); + + 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 message. + */ + +void +ippDelete(ipp_t *ipp) /* I - IPP message */ +{ + ipp_attribute_t *attr, /* Current attribute */ + *next; /* Next attribute */ + + + DEBUG_printf(("ippDelete(ipp=%p)", ipp)); + + if (!ipp) + return; + + ipp->use --; + if (ipp->use > 0) + return; + + for (attr = ipp->attrs; attr != NULL; attr = next) + { + next = attr->next; + _ippFreeAttr(attr); + } + + free(ipp); +} + + +/* + * 'ippDeleteAttribute()' - Delete a single attribute in an IPP message. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +void +ippDeleteAttribute( + ipp_t *ipp, /* I - IPP message */ + ipp_attribute_t *attr) /* I - Attribute to delete */ +{ + ipp_attribute_t *current, /* Current attribute */ + *prev; /* Previous attribute */ + + + DEBUG_printf(("ippDeleteAttribute(ipp=%p, attr=%p(%s))", ipp, attr, + attr ? attr->name : "(null)")); + + /* + * Find the attribute in the list... + */ + + for (current = ipp->attrs, prev = NULL; + current != NULL && current != attr; + prev = current, current = current->next); + + if (current) + { + /* + * Found it, remove the attribute from the list... + */ + + if (prev) + prev->next = current->next; + else + ipp->attrs = current->next; + + if (current == ipp->last) + ipp->last = prev; + + /* + * Free memory used by the attribute... + */ + + _ippFreeAttr(current); + } +} + + +/* + * 'ippFindAttribute()' - Find a named attribute in a request... + */ + +ipp_attribute_t * /* O - Matching attribute */ +ippFindAttribute(ipp_t *ipp, /* I - IPP message */ + const char *name, /* I - Name of attribute */ + ipp_tag_t type) /* I - Type of attribute */ +{ + DEBUG_printf(("2ippFindAttribute(ipp=%p, name=\"%s\", type=%02x(%s))", ipp, + name, type, ippTagString(type))); + + if (!ipp || !name) + 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 message */ + 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(("2ippFindNextAttribute(ipp=%p, name=\"%s\", type=%02x(%s))", + ipp, name, type, ippTagString(type))); + + if (!ipp || !name) + return (NULL); + + if (ipp->current) + { + ipp->prev = ipp->current; + attr = ipp->current->next; + } + else + { + ipp->prev = NULL; + attr = ipp->attrs; + } + + for (; attr != NULL; ipp->prev = attr, attr = attr->next) + { + DEBUG_printf(("4ippFindAttribute: attr=%p, name=\"%s\"", 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; + ipp->prev = NULL; + + return (NULL); +} + + +/* + * 'ippLength()' - Compute the length of an IPP message. + */ + +size_t /* O - Size of IPP message */ +ippLength(ipp_t *ipp) /* I - IPP message */ +{ + return (ipp_length(ipp, 0)); +} + + +/* + * 'ippNew()' - Allocate a new IPP message. + */ + +ipp_t * /* O - New IPP message */ +ippNew(void) +{ + ipp_t *temp; /* New IPP message */ + + + DEBUG_puts("ippNew()"); + + 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; + temp->use = 1; + } + + DEBUG_printf(("1ippNew: Returning %p", temp)); + + return (temp); +} + + +/* + * 'ippNewRequest()' - Allocate a new IPP request message. + * + * The new request message is initialized with the attributes-charset and + * attributes-natural-language attributes added. The + * attributes-natural-language value is derived from the current locale. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ipp_t * /* O - IPP request message */ +ippNewRequest(ipp_op_t op) /* I - Operation code */ +{ + ipp_t *request; /* IPP request message */ + cups_lang_t *language; /* Current language localization */ + + + DEBUG_printf(("ippNewRequest(op=%02x(%s))", op, ippOpString(op))); + + /* + * Create a new IPP message... + */ + + if ((request = ippNew()) == NULL) + return (NULL); + + /* + * Set the operation and request ID... + */ + + request->request.op.operation_id = op; + request->request.op.request_id = 1; + + /* + * Use UTF-8 as the character set... + */ + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, "utf-8"); + + /* + * Get the language from the current locale... + */ + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + /* + * Return the new request... + */ + + return (request); +} + + +/* + * 'ippRead()' - Read data for an IPP message from a HTTP connection. + */ + +ipp_state_t /* O - Current state */ +ippRead(http_t *http, /* I - HTTP connection */ + ipp_t *ipp) /* I - IPP data */ +{ + DEBUG_printf(("ippRead(http=%p, ipp=%p), data_remaining=" CUPS_LLFMT, + http, ipp, CUPS_LLCAST (http ? http->data_remaining : -1))); + + if (!http) + return (IPP_ERROR); + + DEBUG_printf(("2ippRead: http->state=%d, http->used=%d", http->state, + http->used)); + + return (ippReadIO(http, (ipp_iocb_t)ipp_read_http, http->blocking, NULL, + ipp)); +} + + +/* + * 'ippReadFile()' - Read data for an IPP message from a file. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ipp_state_t /* O - Current state */ +ippReadFile(int fd, /* I - HTTP data */ + ipp_t *ipp) /* I - IPP data */ +{ + DEBUG_printf(("ippReadFile(fd=%d, ipp=%p)", fd, ipp)); + + return (ippReadIO(&fd, (ipp_iocb_t)ipp_read_file, 1, NULL, ipp)); +} + + +/* + * 'ippReadIO()' - Read data for an IPP message. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ipp_state_t /* O - Current state */ +ippReadIO(void *src, /* I - Data source */ + ipp_iocb_t cb, /* I - Read callback function */ + int blocking, /* I - Use blocking IO? */ + ipp_t *parent, /* I - Parent request, if any */ + ipp_t *ipp) /* I - IPP data */ +{ + int n; /* Length of data */ + unsigned char *buffer, /* Data buffer */ + string[IPP_MAX_NAME], + /* Small string buffer */ + *bufptr; /* Pointer into buffer */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_tag_t tag; /* Current tag */ + ipp_tag_t value_tag; /* Current value tag */ + ipp_value_t *value; /* Current value */ + + + DEBUG_printf(("ippReadIO(src=%p, cb=%p, blocking=%d, parent=%p, ipp=%p)", + src, cb, blocking, parent, ipp)); + DEBUG_printf(("2ippReadIO: ipp->state=%d", ipp->state)); + + if (!src || !ipp) + return (IPP_ERROR); + + if ((buffer = ipp_buffer_get()) == NULL) + { + DEBUG_puts("1ippReadIO: Unable to get read buffer!"); + return (IPP_ERROR); + } + + switch (ipp->state) + { + case IPP_IDLE : + ipp->state ++; /* Avoid common problem... */ + + case IPP_HEADER : + if (parent == NULL) + { + /* + * Get the request header... + */ + + if ((*cb)(src, buffer, 8) < 8) + { + DEBUG_puts("1ippReadIO: Unable to read header!"); + ipp_buffer_release(buffer); + 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]; + + DEBUG_printf(("2ippReadIO: version=%d.%d", buffer[0], buffer[1])); + DEBUG_printf(("2ippReadIO: op_status=%04x", + ipp->request.any.op_status)); + DEBUG_printf(("2ippReadIO: request_id=%d", + ipp->request.any.request_id)); + } + + ipp->state = IPP_ATTRIBUTE; + ipp->current = NULL; + ipp->curtag = IPP_TAG_ZERO; + ipp->prev = ipp->last; + + /* + * If blocking is disabled, stop here... + */ + + if (!blocking) + break; + + case IPP_ATTRIBUTE : + for (;;) + { + if ((*cb)(src, buffer, 1) < 1) + { + DEBUG_puts("1ippReadIO: Callback returned EOF/error"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + DEBUG_printf(("2ippReadIO: ipp->current=%p, ipp->prev=%p", + ipp->current, ipp->prev)); + + /* + * Read this attribute... + */ + + tag = (ipp_tag_t)buffer[0]; + + if (tag == IPP_TAG_END) + { + /* + * No more attributes left... + */ + + DEBUG_puts("2ippReadIO: 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) + ipp->prev = ippAddSeparator(ipp); + else if (ipp->current) + ipp->prev = ipp->current; + + ipp->curtag = tag; + ipp->current = NULL; + DEBUG_printf(("2ippReadIO: group tag=%x(%s), ipp->prev=%p", tag, + ippTagString(tag), ipp->prev)); + continue; + } + + DEBUG_printf(("2ippReadIO: value tag=%x(%s)", tag, + ippTagString(tag))); + + /* + * Get the name... + */ + + if ((*cb)(src, buffer, 2) < 2) + { + DEBUG_puts("1ippReadIO: unable to read name length!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + n = (buffer[0] << 8) | buffer[1]; + + if (n >= IPP_BUF_SIZE) + { + DEBUG_printf(("1ippReadIO: bad name length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + DEBUG_printf(("2ippReadIO: name length=%d", n)); + + if (n == 0 && tag != IPP_TAG_MEMBERNAME && + tag != IPP_TAG_END_COLLECTION) + { + /* + * More values for current attribute... + */ + + if (ipp->current == NULL) + { + DEBUG_puts("1ippReadIO: Attribute without name and no current"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + attr = ipp->current; + value_tag = (ipp_tag_t)(attr->value_tag & IPP_TAG_MASK); + + /* + * Make sure we aren't adding a new value of a different + * type... + */ + + if (value_tag == IPP_TAG_ZERO) + { + /* + * Setting the value of a collection member... + */ + + attr->value_tag = tag; + } + else if (value_tag == IPP_TAG_TEXTLANG || + value_tag == IPP_TAG_NAMELANG || + (value_tag >= IPP_TAG_TEXT && + value_tag <= IPP_TAG_MIMETYPE)) + { + /* + * String values can sometimes come across in different + * forms; accept sets of differing values... + */ + + if (tag != IPP_TAG_TEXTLANG && tag != IPP_TAG_NAMELANG && + (tag < IPP_TAG_TEXT || tag > IPP_TAG_MIMETYPE) && + tag != IPP_TAG_NOVALUE) + { + DEBUG_printf(("1ippReadIO: 1setOf value tag %x(%s) != %x(%s)", + value_tag, ippTagString(value_tag), tag, + ippTagString(tag))); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + } + else if (value_tag != tag) + { + DEBUG_printf(("1ippReadIO: value tag %x(%s) != %x(%s)", + value_tag, ippTagString(value_tag), tag, + ippTagString(tag))); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + /* + * Finally, reallocate the attribute array as needed... + */ + + if (attr->num_values == 1 || + (attr->num_values > 0 && + (attr->num_values & (IPP_MAX_VALUES - 1)) == 0)) + { + ipp_attribute_t *temp; /* Pointer to new buffer */ + + + DEBUG_printf(("2ippReadIO: reallocating for up to %d values...", + attr->num_values + IPP_MAX_VALUES)); + + /* + * Reallocate memory... + */ + + if ((temp = realloc(attr, sizeof(ipp_attribute_t) + + (attr->num_values + IPP_MAX_VALUES - 1) * + sizeof(ipp_value_t))) == NULL) + { + DEBUG_puts("1ippReadIO: Unable to resize attribute"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if (temp != attr) + { + /* + * Reset pointers in the list... + */ + + if (ipp->prev) + ipp->prev->next = temp; + else + ipp->attrs = temp; + + attr = ipp->current = ipp->last = temp; + } + } + } + else if (tag == IPP_TAG_MEMBERNAME) + { + /* + * Name must be length 0! + */ + + if (n) + { + DEBUG_puts("1ippReadIO: member name not empty!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if (ipp->current) + ipp->prev = ipp->current; + + attr = ipp->current = _ippAddAttr(ipp, 1); + + DEBUG_printf(("2ippReadIO: membername, ipp->current=%p, " + "ipp->prev=%p", ipp->current, ipp->prev)); + + attr->group_tag = ipp->curtag; + attr->value_tag = IPP_TAG_ZERO; + attr->num_values = 0; + } + else if (tag != IPP_TAG_END_COLLECTION) + { + /* + * New attribute; read the name and add it... + */ + + if ((*cb)(src, buffer, n) < n) + { + DEBUG_puts("1ippReadIO: unable to read name!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + buffer[n] = '\0'; + + if (ipp->current) + ipp->prev = ipp->current; + + if ((attr = ipp->current = _ippAddAttr(ipp, 1)) == NULL) + { + DEBUG_puts("1ippReadIO: unable to allocate attribute!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + DEBUG_printf(("2ippReadIO: name=\"%s\", ipp->current=%p, " + "ipp->prev=%p", buffer, ipp->current, ipp->prev)); + + attr->group_tag = ipp->curtag; + attr->value_tag = tag; + attr->name = _cupsStrAlloc((char *)buffer); + attr->num_values = 0; + } + else + attr = NULL; + + if (tag != IPP_TAG_END_COLLECTION) + value = attr->values + attr->num_values; + else + value = NULL; + + if ((*cb)(src, buffer, 2) < 2) + { + DEBUG_puts("1ippReadIO: unable to read value length!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + n = (buffer[0] << 8) | buffer[1]; + DEBUG_printf(("2ippReadIO: value length=%d", n)); + + switch (tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + if (n != 4) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, 4) < 4) + { + DEBUG_puts("1ippReadIO: Unable to read integer value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + + value->integer = n; + break; + + case IPP_TAG_BOOLEAN : + if (n != 1) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, 1) < 1) + { + DEBUG_puts("1ippReadIO: Unable to read boolean value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + value->boolean = buffer[0]; + break; + + case IPP_TAG_NOVALUE : + case IPP_TAG_NOTSETTABLE : + case IPP_TAG_DELETEATTR : + case IPP_TAG_ADMINDEFINE : + /* + * These value types are not supposed to have values, however + * some vendors (Brother) do not implement IPP correctly and so + * we need to map non-empty values to text... + */ + + if (attr->value_tag == tag) + { + if (n == 0) + break; + + attr->value_tag = IPP_TAG_TEXT; + } + + 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 : + if (n >= IPP_BUF_SIZE) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, n) < n) + { + DEBUG_puts("1ippReadIO: unable to read name!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + buffer[n] = '\0'; + value->string.text = _cupsStrAlloc((char *)buffer); + DEBUG_printf(("2ippReadIO: value=\"%s\"", value->string.text)); + break; + + case IPP_TAG_DATE : + if (n != 11) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, value->date, 11) < 11) + { + DEBUG_puts("1ippReadIO: Unable to read date value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + break; + + case IPP_TAG_RESOLUTION : + if (n != 9) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, 9) < 9) + { + DEBUG_puts("1ippReadIO: Unable to read resolution value!"); + ipp_buffer_release(buffer); + 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 (n != 8) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, 8) < 8) + { + DEBUG_puts("1ippReadIO: Unable to read range value!"); + ipp_buffer_release(buffer); + 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 >= IPP_BUF_SIZE || n < 4) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, n) < n) + { + DEBUG_puts("1ippReadIO: Unable to read string w/language " + "value!"); + ipp_buffer_release(buffer); + 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]; + + if ((bufptr + 2 + n) >= (buffer + IPP_BUF_SIZE) || + n >= sizeof(string)) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + memcpy(string, bufptr + 2, n); + string[n] = '\0'; + + value->string.charset = _cupsStrAlloc((char *)string); + + bufptr += 2 + n; + n = (bufptr[0] << 8) | bufptr[1]; + + if ((bufptr + 2 + n) >= (buffer + IPP_BUF_SIZE)) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + bufptr[2 + n] = '\0'; + value->string.text = _cupsStrAlloc((char *)bufptr + 2); + break; + + case IPP_TAG_BEGIN_COLLECTION : + /* + * Oh, boy, here comes a collection value, so read it... + */ + + value->collection = ippNew(); + + if (n > 0) + { + DEBUG_puts("1ippReadIO: begCollection tag with value length " + "> 0!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if (ippReadIO(src, cb, 1, ipp, value->collection) == IPP_ERROR) + { + DEBUG_puts("1ippReadIO: Unable to read collection value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + break; + + case IPP_TAG_END_COLLECTION : + ipp_buffer_release(buffer); + + if (n > 0) + { + DEBUG_puts("1ippReadIO: endCollection tag with value length " + "> 0!"); + return (IPP_ERROR); + } + + DEBUG_puts("1ippReadIO: endCollection tag..."); + return (ipp->state = IPP_DATA); + + case IPP_TAG_MEMBERNAME : + /* + * The value the name of the member in the collection, which + * we need to carry over... + */ + + if (n >= IPP_BUF_SIZE) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, buffer, n) < n) + { + DEBUG_puts("1ippReadIO: Unable to read member name value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + buffer[n] = '\0'; + attr->name = _cupsStrAlloc((char *)buffer); + + /* + * Since collection members are encoded differently than + * regular attributes, make sure we don't start with an + * empty value... + */ + + attr->num_values --; + + DEBUG_printf(("2ippReadIO: member name=\"%s\"", attr->name)); + break; + + default : /* Other unsupported values */ + if (n > IPP_MAX_LENGTH) + { + DEBUG_printf(("1ippReadIO: bad value length %d!", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if (!value) + { + DEBUG_puts("1ippReadIO: NULL value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + value->unknown.length = n; + if (n > 0) + { + if ((value->unknown.data = malloc(n)) == NULL) + { + DEBUG_puts("1ippReadIO: Unable to allocate value"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((*cb)(src, value->unknown.data, n) < n) + { + DEBUG_puts("1ippReadIO: Unable to read unsupported value!"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + } + else + value->unknown.data = NULL; + break; + } + + attr->num_values ++; + + /* + * If blocking is disabled, stop here... + */ + + if (!blocking) + break; + } + break; + + case IPP_DATA : + break; + + default : + break; /* anti-compiler-warning-code */ + } + + DEBUG_printf(("1ippReadIO: returning ipp->state=%d!", ipp->state)); + ipp_buffer_release(buffer); + + 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 */ + ipp_uchar_t *date = _cupsGlobals()->ipp_date; + /* 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 message to a HTTP connection. + */ + +ipp_state_t /* O - Current state */ +ippWrite(http_t *http, /* I - HTTP connection */ + ipp_t *ipp) /* I - IPP data */ +{ + DEBUG_printf(("ippWrite(http=%p, ipp=%p)", http, ipp)); + + if (!http) + return (IPP_ERROR); + + return (ippWriteIO(http, (ipp_iocb_t)httpWrite2, http->blocking, NULL, ipp)); +} + + +/* + * 'ippWriteFile()' - Write data for an IPP message to a file. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ipp_state_t /* O - Current state */ +ippWriteFile(int fd, /* I - HTTP data */ + ipp_t *ipp) /* I - IPP data */ +{ + DEBUG_printf(("ippWriteFile(fd=%d, ipp=%p)", fd, ipp)); + + ipp->state = IPP_IDLE; + + return (ippWriteIO(&fd, (ipp_iocb_t)ipp_write_file, 1, NULL, ipp)); +} + + +/* + * 'ippWriteIO()' - Write data for an IPP message. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ipp_state_t /* O - Current state */ +ippWriteIO(void *dst, /* I - Destination */ + ipp_iocb_t cb, /* I - Write callback function */ + int blocking, /* I - Use blocking IO? */ + ipp_t *parent, /* I - Parent IPP message */ + ipp_t *ipp) /* I - IPP data */ +{ + int i; /* Looping var */ + int n; /* Length of data */ + unsigned char *buffer, /* Data buffer */ + *bufptr; /* Pointer into buffer */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_value_t *value; /* Current value */ + + + DEBUG_printf(("ippWriteIO(dst=%p, cb=%p, blocking=%d, parent=%p, ipp=%p)", + dst, cb, blocking, parent, ipp)); + + if (!dst || !ipp) + return (IPP_ERROR); + + if ((buffer = ipp_buffer_get()) == NULL) + { + DEBUG_puts("1ippWriteIO: Unable to get write buffer"); + return (IPP_ERROR); + } + + switch (ipp->state) + { + case IPP_IDLE : + ipp->state ++; /* Avoid common problem... */ + + case IPP_HEADER : + if (parent == NULL) + { + /* + * 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; + + DEBUG_printf(("2ippWriteIO: version=%d.%d", buffer[0], buffer[1])); + DEBUG_printf(("2ippWriteIO: op_status=%04x", + ipp->request.any.op_status)); + DEBUG_printf(("2ippWriteIO: request_id=%d", + ipp->request.any.request_id)); + + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP header..."); + ipp_buffer_release(buffer); + 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(("1ippWriteIO: ipp->current=%p", ipp->current)); + + /* + * If blocking is disabled, stop here... + */ + + if (!blocking) + break; + + case IPP_ATTRIBUTE : + while (ipp->current != NULL) + { + /* + * Write this attribute... + */ + + bufptr = buffer; + attr = ipp->current; + + ipp->current = ipp->current->next; + + if (!parent) + { + 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(("2ippWriteIO: wrote group tag=%x(%s)", + attr->group_tag, ippTagString(attr->group_tag))); + *bufptr++ = attr->group_tag; + } + else if (attr->group_tag == IPP_TAG_ZERO) + continue; + } + + DEBUG_printf(("1ippWriteIO: %s (%s%s)", attr->name, + attr->num_values > 1 ? "1setOf " : "", + ippTagString(attr->value_tag))); + + /* + * 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. + * + * Collection values (parent != NULL) are written differently... + */ + + if (parent == NULL) + { + /* + * Get the length of the attribute name, and make sure it won't + * overflow the buffer... + */ + + if ((n = (int)strlen(attr->name)) > (IPP_BUF_SIZE - 4)) + { + DEBUG_printf(("1ippWriteIO: Attribute name too long (%d)", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + /* + * Write the value tag, name length, and name string... + */ + + DEBUG_printf(("2ippWriteIO: writing value tag=%x(%s)", + attr->value_tag, ippTagString(attr->value_tag))); + DEBUG_printf(("2ippWriteIO: writing name=%d,\"%s\"", n, + attr->name)); + + *bufptr++ = attr->value_tag; + *bufptr++ = n >> 8; + *bufptr++ = n; + memcpy(bufptr, attr->name, n); + bufptr += n; + } + else + { + /* + * Get the length of the attribute name, and make sure it won't + * overflow the buffer... + */ + + if ((n = (int)strlen(attr->name)) > (IPP_BUF_SIZE - 7)) + { + DEBUG_printf(("1ippWriteIO: Attribute name too long (%d)", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + /* + * Write the member name tag, name length, name string, value tag, + * and empty name for the collection member attribute... + */ + + DEBUG_printf(("2ippWriteIO: writing value tag=%x(memberName)", + IPP_TAG_MEMBERNAME)); + DEBUG_printf(("2ippWriteIO: writing name=%d,\"%s\"", n, + attr->name)); + DEBUG_printf(("2ippWriteIO: writing value tag=%x(%s)", + attr->value_tag, ippTagString(attr->value_tag))); + DEBUG_puts("2ippWriteIO: writing name=0,\"\""); + + *bufptr++ = IPP_TAG_MEMBERNAME; + *bufptr++ = 0; + *bufptr++ = 0; + *bufptr++ = n >> 8; + *bufptr++ = n; + memcpy(bufptr, attr->name, n); + bufptr += n; + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + /* + * 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 9) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 6) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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_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(("2ippWriteIO: writing value tag=%x(%s)", + attr->value_tag, + ippTagString(attr->value_tag))); + DEBUG_printf(("2ippWriteIO: writing name=0,\"\"")); + + if ((IPP_BUF_SIZE - (bufptr - buffer)) < 3) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + if (value->string.text != NULL) + n = (int)strlen(value->string.text); + else + n = 0; + + if (n > (IPP_BUF_SIZE - 2)) + { + DEBUG_printf(("1ippWriteIO: String too long (%d)", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + DEBUG_printf(("2ippWriteIO: writing string=%d,\"%s\"", n, + value->string.text)); + + if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2)) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + /* + * 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 IPP_MAX_LENGTH + * bytes since the 2-byte length is a signed (twos-complement) + * value. + * + * Put the 2-byte length and string characters in the buffer. + */ + + *bufptr++ = n >> 8; + *bufptr++ = n; + + if (n > 0) + { + 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 16) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 14) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 13) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 3) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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 = 4; + + if (value->string.charset != NULL) + n += (int)strlen(value->string.charset); + + if (value->string.text != NULL) + n += (int)strlen(value->string.text); + + if (n > (IPP_BUF_SIZE - 2)) + { + DEBUG_printf(("1ippWriteIO: text/nameWithLanguage value " + "too long (%d)", n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2)) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + /* Length of entire value */ + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Length of charset */ + if (value->string.charset != NULL) + n = (int)strlen(value->string.charset); + else + n = 0; + + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Charset */ + if (n > 0) + { + memcpy(bufptr, value->string.charset, n); + bufptr += n; + } + + /* Length of text */ + if (value->string.text != NULL) + n = (int)strlen(value->string.text); + else + n = 0; + + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Text */ + if (n > 0) + { + memcpy(bufptr, value->string.text, n); + bufptr += n; + } + } + break; + + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + { + /* + * Collections are written with the begin-collection + * tag first with a value of 0 length, followed by the + * attributes in the collection, then the end-collection + * value... + */ + + if ((IPP_BUF_SIZE - (bufptr - buffer)) < 5) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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; + } + + /* + * Write a data length of 0 and flush the buffer... + */ + + *bufptr++ = 0; + *bufptr++ = 0; + + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + bufptr = buffer; + + /* + * Then write the collection attribute... + */ + + value->collection->state = IPP_IDLE; + + if (ippWriteIO(dst, cb, 1, ipp, + value->collection) == IPP_ERROR) + { + DEBUG_puts("1ippWriteIO: Unable to write collection value"); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + } + 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 ((IPP_BUF_SIZE - (bufptr - buffer)) < 3) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + /* + * An unknown value might 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 > (IPP_BUF_SIZE - 2)) + { + DEBUG_printf(("1ippWriteIO: Data length too long (%d)", + n)); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + if ((int)(IPP_BUF_SIZE - (bufptr - buffer)) < (n + 2)) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP " + "attribute..."); + ipp_buffer_release(buffer); + 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 (bufptr > buffer) + { + if ((*cb)(dst, buffer, (int)(bufptr - buffer)) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP attribute..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + DEBUG_printf(("2ippWriteIO: wrote %d bytes", + (int)(bufptr - buffer))); + } + + /* + * If blocking is disabled, stop here... + */ + + if (!blocking) + break; + } + + if (ipp->current == NULL) + { + /* + * Done with all of the attributes; add the end-of-attributes + * tag or end-collection attribute... + */ + + if (parent == NULL) + { + buffer[0] = IPP_TAG_END; + n = 1; + } + else + { + buffer[0] = IPP_TAG_END_COLLECTION; + buffer[1] = 0; /* empty name */ + buffer[2] = 0; + buffer[3] = 0; /* empty value */ + buffer[4] = 0; + n = 5; + } + + if ((*cb)(dst, buffer, n) < 0) + { + DEBUG_puts("1ippWriteIO: Could not write IPP end-tag..."); + ipp_buffer_release(buffer); + return (IPP_ERROR); + } + + ipp->state = IPP_DATA; + } + break; + + case IPP_DATA : + break; + + default : + break; /* anti-compiler-warning-code */ + } + + ipp_buffer_release(buffer); + + return (ipp->state); +} + + +/* + * '_ippAddAttr()' - Add a new attribute to the request. + */ + +ipp_attribute_t * /* O - New attribute */ +_ippAddAttr(ipp_t *ipp, /* I - IPP message */ + int num_values) /* I - Number of values */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("4_ippAddAttr(ipp=%p, num_values=%d)", ipp, num_values)); + + if (!ipp || num_values < 0) + return (NULL); + + attr = calloc(sizeof(ipp_attribute_t) + + (num_values - 1) * sizeof(ipp_value_t), 1); + + if (attr != NULL) + { + attr->num_values = num_values; + + if (ipp->last == NULL) + ipp->attrs = attr; + else + ipp->last->next = attr; + + ipp->last = attr; + } + + DEBUG_printf(("5_ippAddAttr: Returning %p", attr)); + + return (attr); +} + + +/* + * '_ippFreeAttr()' - Free an attribute. + */ + +void +_ippFreeAttr(ipp_attribute_t *attr) /* I - Attribute to free */ +{ + int i; /* Looping var */ + ipp_value_t *value; /* Current value */ + + + DEBUG_printf(("4_ippFreeAttr(attr=%p)", attr)); + + switch (attr->value_tag) + { + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_RESERVED_STRING : + case IPP_TAG_KEYWORD : + 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 ++) + _cupsStrFree(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) + _cupsStrFree(value->string.charset); + _cupsStrFree(value->string.text); + } + break; + + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + case IPP_TAG_BOOLEAN : + case IPP_TAG_DATE : + case IPP_TAG_RESOLUTION : + case IPP_TAG_RANGE : + break; + + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + ippDelete(value->collection); + break; + + case IPP_TAG_STRING : + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + free(value->unknown.data); + break; + + default : + if (!((int)attr->value_tag & IPP_TAG_COPY)) + { + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + if (value->unknown.data) + free(value->unknown.data); + } + break; + } + + if (attr->name) + _cupsStrFree(attr->name); + + free(attr); +} + + +/* + * 'ipp_buffer_get()' - Get a read/write buffer. + */ + +static unsigned char * /* O - Buffer */ +ipp_buffer_get(void) +{ + _ipp_buffer_t *buffer; /* Current buffer */ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + for (buffer = cg->ipp_buffers; buffer; buffer = buffer->next) + if (!buffer->used) + { + buffer->used = 1; + return (buffer->d); + } + + if ((buffer = malloc(sizeof(_ipp_buffer_t))) == NULL) + return (NULL); + + buffer->used = 1; + buffer->next = cg->ipp_buffers; + cg->ipp_buffers = buffer; + + return (buffer->d); +} + + +/* + * 'ipp_buffer_release()' - Release a read/write buffer. + */ + +static void +ipp_buffer_release(unsigned char *b) /* I - Buffer to release */ +{ + ((_ipp_buffer_t *)b)->used = 0; +} + + +/* + * 'ipp_length()' - Compute the length of an IPP message or collection value. + */ + +static size_t /* O - Size of IPP message */ +ipp_length(ipp_t *ipp, /* I - IPP message or collection */ + int collection) /* I - 1 if a collection, 0 otherwise */ +{ + 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 message header... + */ + + bytes = collection ? 0 : 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 && !collection) + { + group = attr->group_tag; + if (group == IPP_TAG_ZERO) + continue; + + bytes ++; /* Group tag */ + } + + if (!attr->name) + continue; + + DEBUG_printf(("9ipp_length: attr->name=\"%s\", attr->num_values=%d, " + "bytes=%d", attr->name, attr->num_values, bytes)); + + bytes += (int)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 */ + + if (collection) + bytes += 5; /* Add membername overhead */ + + 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_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 (value->string.text != NULL) + bytes += (int)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 ++) + { + if (value->string.charset != NULL) + bytes += (int)strlen(value->string.charset); + + if (value->string.text != NULL) + bytes += (int)strlen(value->string.text); + } + break; + + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + bytes += (int)ipp_length(value->collection, 1); + break; + + default : + for (i = 0, value = attr->values; + i < attr->num_values; + i ++, value ++) + bytes += value->unknown.length; + break; + } + } + + /* + * Finally, add 1 byte for the "end of attributes" tag or 5 bytes + * for the "end of collection" tag and return... + */ + + if (collection) + bytes += 5; + else + bytes ++; + + DEBUG_printf(("8ipp_length: Returning %d bytes", bytes)); + + return (bytes); +} + + +/* + * 'ipp_read_http()' - Semi-blocking read on a HTTP connection... + */ + +static ssize_t /* O - Number of bytes read */ +ipp_read_http(http_t *http, /* I - Client connection */ + ipp_uchar_t *buffer, /* O - Buffer for data */ + size_t length) /* I - Total length */ +{ + int tbytes, /* Total bytes read */ + bytes; /* Bytes read this pass */ + char len[32]; /* Length string */ + + + DEBUG_printf(("7ipp_read_http(http=%p, buffer=%p, length=%d)", + http, buffer, (int)length)); + + /* + * Loop until all bytes are read... + */ + + for (tbytes = 0, bytes = 0; + tbytes < (int)length; + tbytes += bytes, buffer += bytes) + { + DEBUG_printf(("9ipp_read_http: tbytes=%d, http->state=%d", tbytes, + http->state)); + + if (http->state == HTTP_WAITING) + break; + + if (http->used > 0 && http->data_encoding == HTTP_ENCODE_LENGTH) + { + /* + * Do "fast read" from HTTP buffer directly... + */ + + if (http->used > (int)(length - tbytes)) + bytes = (int)(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->data_remaining <= INT_MAX) + http->_data_remaining = (int)http->data_remaining; + else + http->_data_remaining = INT_MAX; + + if (http->used > 0) + memmove(http->buffer, http->buffer + bytes, http->used); + + if (http->data_remaining == 0) + { + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + { + /* + * Get the trailing CR LF after the chunk... + */ + + if (!httpGets(len, sizeof(len), http)) + return (-1); + } + + if (http->data_encoding != HTTP_ENCODE_CHUNKED) + { + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + } + } + } + else + { + /* + * Wait a maximum of 1 second for data... + */ + + if (!http->blocking) + { + /* + * Wait up to 10 seconds for more data on non-blocking sockets... + */ + + if (!httpWait(http, 10000)) + { + /* + * Signal no data... + */ + + bytes = -1; + break; + } + } + + if ((bytes = httpRead2(http, (char *)buffer, length - tbytes)) < 0) + { +#ifdef WIN32 + break; +#else + if (errno != EAGAIN && errno != EINTR) + break; + + bytes = 0; +#endif /* WIN32 */ + } + else if (bytes == 0) + break; + } + } + + /* + * Return the number of bytes read... + */ + + if (tbytes == 0 && bytes < 0) + tbytes = -1; + + DEBUG_printf(("8ipp_read_http: Returning %d bytes", tbytes)); + + return (tbytes); +} + + +/* + * 'ipp_read_file()' - Read IPP data from a file. + */ + +static ssize_t /* O - Number of bytes read */ +ipp_read_file(int *fd, /* I - File descriptor */ + ipp_uchar_t *buffer, /* O - Read buffer */ + size_t length) /* I - Number of bytes to read */ +{ +#ifdef WIN32 + return ((ssize_t)read(*fd, buffer, (unsigned)length)); +#else + return (read(*fd, buffer, length)); +#endif /* WIN32 */ +} + + +/* + * 'ipp_write_file()' - Write IPP data to a file. + */ + +static ssize_t /* O - Number of bytes written */ +ipp_write_file(int *fd, /* I - File descriptor */ + ipp_uchar_t *buffer, /* I - Data to write */ + size_t length) /* I - Number of bytes to write */ +{ +#ifdef WIN32 + return ((ssize_t)write(*fd, buffer, (unsigned)length)); +#else + return (write(*fd, buffer, length)); +#endif /* WIN32 */ +} + + +#ifdef __linux +/* + * The following symbol definitions are provided only for KDE + * compatibility during the CUPS 1.2 testing period and will be + * removed in a future release of CUPS. These are PRIVATE APIs + * from CUPS 1.1.x that the KDE developers chose to use... + */ + +ipp_attribute_t * /* O - New attribute */ +_ipp_add_attr(ipp_t *ipp, /* I - IPP message */ + int num_values) /* I - Number of values */ +{ + return (_ippAddAttr(ipp, num_values)); +} + +void +_ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */ +{ + _ippFreeAttr(attr); +} +#endif /* __linux */ + + +/* + * End of "$Id$". + */ diff --git a/cups/ipp.h b/cups/ipp.h new file mode 100644 index 0000000000..2b71c0f5e5 --- /dev/null +++ b/cups/ipp.h @@ -0,0 +1,505 @@ +/* + * "$Id$" + * + * Internet Printing Protocol definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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... + * + * Note: Applications should never use IPP_PORT, but instead use the + * ippPort() function to allow overrides via the IPP_PORT environment + * variable and services file if needed! + */ + +# define IPP_PORT 631 + +/* + * Common limits... + */ + +# define IPP_MAX_LENGTH 32767 /* Maximum size of any single value */ +# define IPP_MAX_NAME 256 /* Maximum length of common name values */ +# define IPP_MAX_VALUES 8 /* Power-of-2 allocation increment */ + + +/* + * Types and structures... + */ + +typedef enum ipp_tag_e /**** Format tags for attributes ****/ +{ + IPP_TAG_ZERO = 0x00, /* Zero tag - used for separators */ + IPP_TAG_OPERATION, /* Operation group */ + IPP_TAG_JOB, /* Job group */ + IPP_TAG_END, /* End-of-attributes */ + IPP_TAG_PRINTER, /* Printer group */ + IPP_TAG_UNSUPPORTED_GROUP, /* Unsupported attributes group */ + IPP_TAG_SUBSCRIPTION, /* Subscription group */ + IPP_TAG_EVENT_NOTIFICATION, /* Event group */ + IPP_TAG_UNSUPPORTED_VALUE = 0x10, /* Unsupported value */ + IPP_TAG_DEFAULT, /* Default value */ + IPP_TAG_UNKNOWN, /* Unknown value */ + IPP_TAG_NOVALUE, /* No-value value */ + IPP_TAG_NOTSETTABLE = 0x15, /* Not-settable value */ + IPP_TAG_DELETEATTR, /* Delete-attribute value */ + IPP_TAG_ADMINDEFINE, /* Admin-defined value */ + IPP_TAG_INTEGER = 0x21, /* Integer value */ + IPP_TAG_BOOLEAN, /* Boolean value */ + IPP_TAG_ENUM, /* Enumeration value */ + IPP_TAG_STRING = 0x30, /* Octet string value */ + IPP_TAG_DATE, /* Date/time value */ + IPP_TAG_RESOLUTION, /* Resolution value */ + IPP_TAG_RANGE, /* Range value */ + IPP_TAG_BEGIN_COLLECTION, /* Beginning of collection value */ + IPP_TAG_TEXTLANG, /* Text-with-language value */ + IPP_TAG_NAMELANG, /* Name-with-language value */ + IPP_TAG_END_COLLECTION, /* End of collection value */ + IPP_TAG_TEXT = 0x41, /* Text value */ + IPP_TAG_NAME, /* Name value */ + IPP_TAG_RESERVED_STRING, /* Reserved for future string value @private@ */ + IPP_TAG_KEYWORD, /* Keyword value */ + IPP_TAG_URI, /* URI value */ + IPP_TAG_URISCHEME, /* URI scheme value */ + IPP_TAG_CHARSET, /* Character set value */ + IPP_TAG_LANGUAGE, /* Language value */ + IPP_TAG_MIMETYPE, /* MIME media type value */ + IPP_TAG_MEMBERNAME, /* Collection member name value */ + IPP_TAG_MASK = 0x7fffffff, /* Mask for copied attribute values */ + IPP_TAG_COPY = -0x7fffffff-1 /* Bitflag for copied attribute values */ +} ipp_tag_t; + +typedef enum ipp_res_e /**** Resolution units ****/ +{ + IPP_RES_PER_INCH = 3, /* Pixels per inch */ + IPP_RES_PER_CM /* Pixels per centimeter */ +} ipp_res_t; + +typedef enum ipp_finish_e /**** Finishings ****/ +{ + IPP_FINISHINGS_NONE = 3, /* No finishing */ + IPP_FINISHINGS_STAPLE, /* Staple (any location) */ + IPP_FINISHINGS_PUNCH, /* Punch (any location/count) */ + IPP_FINISHINGS_COVER, /* Add cover */ + IPP_FINISHINGS_BIND, /* Bind */ + IPP_FINISHINGS_SADDLE_STITCH, /* Staple interior */ + IPP_FINISHINGS_EDGE_STITCH, /* Stitch along any side */ + IPP_FINISHINGS_FOLD, /* Fold (any type) */ + IPP_FINISHINGS_TRIM, /* Trim (any type) */ + IPP_FINISHINGS_BALE, /* Bale (any type) */ + IPP_FINISHINGS_BOOKLET_MAKER, /* Fold to make booklet */ + IPP_FINISHINGS_JOB_OFFSET, /* Offset for binding (any type) */ + IPP_FINISHINGS_STAPLE_TOP_LEFT = 20, /* Staple top left corner */ + IPP_FINISHINGS_STAPLE_BOTTOM_LEFT, /* Staple bottom left corner */ + IPP_FINISHINGS_STAPLE_TOP_RIGHT, /* Staple top right corner */ + IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT, /* Staple bottom right corner */ + IPP_FINISHINGS_EDGE_STITCH_LEFT, /* Stitch along left side */ + IPP_FINISHINGS_EDGE_STITCH_TOP, /* Stitch along top edge */ + IPP_FINISHINGS_EDGE_STITCH_RIGHT, /* Stitch along right side */ + IPP_FINISHINGS_EDGE_STITCH_BOTTOM, /* Stitch along bottom edge */ + IPP_FINISHINGS_STAPLE_DUAL_LEFT, /* Two staples on left */ + IPP_FINISHINGS_STAPLE_DUAL_TOP, /* Two staples on top */ + IPP_FINISHINGS_STAPLE_DUAL_RIGHT, /* Two staples on right */ + IPP_FINISHINGS_STAPLE_DUAL_BOTTOM, /* Two staples on bottom */ + IPP_FINISHINGS_BIND_LEFT = 50, /* Bind on left */ + IPP_FINISHINGS_BIND_TOP, /* Bind on top */ + IPP_FINISHINGS_BIND_RIGHT, /* Bind on right */ + IPP_FINISHINGS_BIND_BOTTOM /* Bind on bottom */ +} ipp_finish_t; + +typedef enum ipp_orient_e /**** Orientation values ****/ +{ + 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 ipp_quality_e /**** Qualities ****/ +{ + IPP_QUALITY_DRAFT = 3, /* Draft quality */ + IPP_QUALITY_NORMAL, /* Normal quality */ + IPP_QUALITY_HIGH /* High quality */ +} ipp_quality_t; + +typedef enum ipp_jstate_e /**** Job states ****/ +{ + IPP_JOB_PENDING = 3, /* Job is waiting to be printed */ + IPP_JOB_HELD, /* Job is held for printing */ + IPP_JOB_PROCESSING, /* Job is currently printing */ + IPP_JOB_STOPPED, /* Job has been stopped */ + IPP_JOB_CANCELED, /* Job has been canceled */ + IPP_JOB_ABORTED, /* Job has aborted due to error */ + IPP_JOB_COMPLETED /* Job has completed successfully */ +} ipp_jstate_t; +#define IPP_JOB_CANCELLED IPP_JOB_CANCELED + +typedef enum ipp_pstate_e /**** Printer states ****/ +{ + IPP_PRINTER_IDLE = 3, /* Printer is idle */ + IPP_PRINTER_PROCESSING, /* Printer is working */ + IPP_PRINTER_STOPPED /* Printer is stopped */ +} ipp_pstate_t; + +typedef enum ipp_state_e /**** 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_op_e /**** IPP operations ****/ +{ + IPP_PRINT_JOB = 0x0002, /* Print a single file */ + IPP_PRINT_URI, /* Print a single URL @private@ */ + IPP_VALIDATE_JOB, /* Validate job options */ + IPP_CREATE_JOB, /* Create an empty print job */ + IPP_SEND_DOCUMENT, /* Add a file to a job */ + IPP_SEND_URI, /* Add a URL to a job @private@ */ + IPP_CANCEL_JOB, /* Cancel a job */ + IPP_GET_JOB_ATTRIBUTES, /* Get job attributes */ + IPP_GET_JOBS, /* Get a list of jobs */ + IPP_GET_PRINTER_ATTRIBUTES, /* Get printer attributes */ + IPP_HOLD_JOB, /* Hold a job for printing */ + IPP_RELEASE_JOB, /* Release a job for printing */ + IPP_RESTART_JOB, /* Reprint a job */ + IPP_PAUSE_PRINTER = 0x0010, /* Stop a printer */ + IPP_RESUME_PRINTER, /* Start a printer */ + IPP_PURGE_JOBS, /* Cancel all jobs */ + IPP_SET_PRINTER_ATTRIBUTES, /* Set printer attributes @private@ */ + IPP_SET_JOB_ATTRIBUTES, /* Set job attributes */ + IPP_GET_PRINTER_SUPPORTED_VALUES, /* Get supported attribute values */ + IPP_CREATE_PRINTER_SUBSCRIPTION, /* Create a printer subscription @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_CREATE_JOB_SUBSCRIPTION, /* Create a job subscription @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_GET_SUBSCRIPTION_ATTRIBUTES, /* Get subscription attributes @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_GET_SUBSCRIPTIONS, /* Get list of subscriptions @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_RENEW_SUBSCRIPTION, /* Renew a printer subscription @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_CANCEL_SUBSCRIPTION, /* Cancel a subscription @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_GET_NOTIFICATIONS, /* Get notification events @since CUPS 1.2/Mac OS X 10.5@ */ + IPP_SEND_NOTIFICATIONS, /* Send notification events @private@ */ + IPP_GET_PRINT_SUPPORT_FILES = 0x0021, /* Get printer support files @private@ */ + IPP_ENABLE_PRINTER, /* Start a printer */ + IPP_DISABLE_PRINTER, /* Stop a printer */ + IPP_PAUSE_PRINTER_AFTER_CURRENT_JOB, /* Stop printer after the current job @private@ */ + IPP_HOLD_NEW_JOBS, /* Hold new jobs @private@ */ + IPP_RELEASE_HELD_NEW_JOBS, /* Release new jobs @private@ */ + IPP_DEACTIVATE_PRINTER, /* Stop a printer @private@ */ + IPP_ACTIVATE_PRINTER, /* Start a printer @private@ */ + IPP_RESTART_PRINTER, /* Restart a printer @private@ */ + IPP_SHUTDOWN_PRINTER, /* Turn a printer off @private@ */ + IPP_STARTUP_PRINTER, /* Turn a printer on @private@ */ + IPP_REPROCESS_JOB, /* Reprint a job @private@ */ + IPP_CANCEL_CURRENT_JOB, /* Cancel the current job @private@ */ + IPP_SUSPEND_CURRENT_JOB, /* Suspend the current job @private@ */ + IPP_RESUME_JOB, /* Resume the current job @private@ */ + IPP_PROMOTE_JOB, /* Promote a job to print sooner @private@ */ + IPP_SCHEDULE_JOB_AFTER, /* Schedule a job to print after another @private@ */ + IPP_PRIVATE = 0x4000, /* Reserved @private@ */ + CUPS_GET_DEFAULT, /* Get the default printer */ + CUPS_GET_PRINTERS, /* Get a list of printers and/or classes */ + CUPS_ADD_MODIFY_PRINTER, /* Add or modify a printer */ + CUPS_DELETE_PRINTER, /* Delete a printer */ + CUPS_GET_CLASSES, /* Get a list of classes @deprecated@ */ + CUPS_ADD_MODIFY_CLASS, /* Add or modify a class */ + CUPS_DELETE_CLASS, /* Delete a class */ + CUPS_ACCEPT_JOBS, /* Accept new jobs on a printer */ + CUPS_REJECT_JOBS, /* Reject new jobs on a printer */ + CUPS_SET_DEFAULT, /* Set the default printer */ + CUPS_GET_DEVICES, /* Get a list of supported devices */ + CUPS_GET_PPDS, /* Get a list of supported drivers */ + CUPS_MOVE_JOB, /* Move a job to a different printer */ + CUPS_AUTHENTICATE_JOB, /* Authenticate a job @since CUPS 1.2/Mac OS X 10.5@ */ + CUPS_GET_PPD, /* Get a PPD file @since CUPS 1.3/Mac OS X 10.5@ */ + CUPS_GET_DOCUMENT = 0x4027 /* Get a document file @since CUPS 1.4/Mac OS X 10.6@ */ +} ipp_op_t; + +/* Old names for the operations */ +#define CUPS_ADD_PRINTER CUPS_ADD_MODIFY_PRINTER +#define CUPS_ADD_CLASS CUPS_ADD_MODIFY_CLASS + +typedef enum ipp_status_e /**** IPP status codes ****/ +{ + IPP_OK = 0x0000, /* successful-ok */ + IPP_OK_SUBST, /* successful-ok-ignored-or-substituted-attributes */ + IPP_OK_CONFLICT, /* successful-ok-conflicting-attributes */ + IPP_OK_IGNORED_SUBSCRIPTIONS, /* successful-ok-ignored-subscriptions */ + IPP_OK_IGNORED_NOTIFICATIONS, /* successful-ok-ignored-notifications */ + IPP_OK_TOO_MANY_EVENTS, /* successful-ok-too-many-events */ + IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* successful-ok-but-cancel-subscription */ + IPP_OK_EVENTS_COMPLETE, /* successful-ok-events-complete */ + IPP_REDIRECTION_OTHER_SITE = 0x200, /* redirection-other-site @private@ */ + CUPS_SEE_OTHER = 0x280, /* cups-see-other */ + IPP_BAD_REQUEST = 0x0400, /* client-error-bad-request */ + IPP_FORBIDDEN, /* client-error-forbidden */ + IPP_NOT_AUTHENTICATED, /* client-error-not-authenticated */ + IPP_NOT_AUTHORIZED, /* client-error-not-authorized */ + IPP_NOT_POSSIBLE, /* client-error-not-possible */ + IPP_TIMEOUT, /* client-error-timeout */ + IPP_NOT_FOUND, /* client-error-not-found */ + IPP_GONE, /* client-error-gone */ + IPP_REQUEST_ENTITY, /* client-error-request-entity-too-large */ + IPP_REQUEST_VALUE, /* client-error-request-value-too-long */ + IPP_DOCUMENT_FORMAT, /* client-error-document-format-not-supported */ + IPP_ATTRIBUTES, /* client-error-attributes-or-values-not-supported */ + IPP_URI_SCHEME, /* client-error-uri-scheme-not-supported */ + IPP_CHARSET, /* client-error-charset-not-supported */ + IPP_CONFLICT, /* client-error-conflicting-attributes */ + IPP_COMPRESSION_NOT_SUPPORTED, /* client-error-compression-not-supported */ + IPP_COMPRESSION_ERROR, /* client-error-compression-error */ + IPP_DOCUMENT_FORMAT_ERROR, /* client-error-document-format-error */ + IPP_DOCUMENT_ACCESS_ERROR, /* client-error-document-access-error */ + IPP_ATTRIBUTES_NOT_SETTABLE, /* client-error-attributes-not-settable */ + IPP_IGNORED_ALL_SUBSCRIPTIONS, /* client-error-ignored-all-subscriptions */ + IPP_TOO_MANY_SUBSCRIPTIONS, /* client-error-too-many-subscriptions */ + IPP_IGNORED_ALL_NOTIFICATIONS, /* client-error-ignored-all-notifications */ + IPP_PRINT_SUPPORT_FILE_NOT_FOUND, /* client-error-print-support-file-not-found */ + + IPP_INTERNAL_ERROR = 0x0500, /* server-error-internal-error */ + IPP_OPERATION_NOT_SUPPORTED, /* server-error-operation-not-supported */ + IPP_SERVICE_UNAVAILABLE, /* server-error-service-unavailable */ + IPP_VERSION_NOT_SUPPORTED, /* server-error-version-not-supported */ + IPP_DEVICE_ERROR, /* server-error-device-error */ + IPP_TEMPORARY_ERROR, /* server-error-temporary-error */ + IPP_NOT_ACCEPTING, /* server-error-not-accepting-jobs */ + IPP_PRINTER_BUSY, /* server-error-busy */ + IPP_ERROR_JOB_CANCELED, /* server-error-job-canceled */ + IPP_MULTIPLE_JOBS_NOT_SUPPORTED, /* server-error-multiple-document-jobs-not-supported */ + IPP_PRINTER_IS_DEACTIVATED /* server-error-printer-is-deactivated */ +} ipp_status_t; +#define IPP_ERROR_JOB_CANCELLED IPP_ERROR_JOB_CANCELED + +typedef unsigned char ipp_uchar_t; /**** Unsigned 8-bit integer/character ****/ + +/**** New in CUPS 1.2 ****/ +typedef ssize_t (*ipp_iocb_t)(void *, ipp_uchar_t *, size_t); + /**** IPP IO Callback Function @since CUPS 1.2/Mac OS X 10.5@ ****/ + +typedef union ipp_request_u /**** 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; + + /**** New in CUPS 1.1.19 ****/ + struct /* Event Header @since CUPS 1.1.19/Mac OS X 10.3@ */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + ipp_status_t status_code; /* Status code */ + int request_id; /* Request ID */ + } event; +} ipp_request_t; + +/**** New in CUPS 1.1.19 ****/ +typedef struct ipp_s ipp_t; + +typedef union ipp_value_u /**** 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 */ + +/**** New in CUPS 1.1.19 ****/ + ipp_t *collection; /* Collection value @since CUPS 1.1.19/Mac OS X 10.3@ */ +} 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; + +struct ipp_s /**** IPP Request/Response/Notification ****/ +{ + ipp_state_t state; /* State of request */ + ipp_request_t request; /* Request header */ + ipp_attribute_t *attrs; /* Attributes */ + ipp_attribute_t *last; /* Last attribute in list */ + ipp_attribute_t *current; /* Current attribute (for read/write) */ + ipp_tag_t curtag; /* Current attribute group tag */ + +/**** New in CUPS 1.2 ****/ + ipp_attribute_t *prev; /* Previous attribute (for read) @since CUPS 1.2/Mac OS X 10.5@ */ + +/**** New in CUPS 1.5 ****/ + int use; /* Use count */ +}; + + +/* + * 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 * const *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); + +/**** New in CUPS 1.1.19 ****/ +extern ipp_attribute_t *ippAddCollection(ipp_t *ipp, ipp_tag_t group, + const char *name, ipp_t *value) _CUPS_API_1_1_19; +extern ipp_attribute_t *ippAddCollections(ipp_t *ipp, ipp_tag_t group, + const char *name, int num_values, + const ipp_t **values) _CUPS_API_1_1_19; +extern void ippDeleteAttribute(ipp_t *ipp, ipp_attribute_t *attr) _CUPS_API_1_1_19; +extern ipp_state_t ippReadFile(int fd, ipp_t *ipp) _CUPS_API_1_1_19; +extern ipp_state_t ippWriteFile(int fd, ipp_t *ipp) _CUPS_API_1_1_19; + +/**** New in CUPS 1.2 ****/ +extern ipp_attribute_t *ippAddOctetString(ipp_t *ipp, ipp_tag_t group, + const char *name, + const void *data, int datalen) _CUPS_API_1_2; +extern ipp_status_t ippErrorValue(const char *name) _CUPS_API_1_2; +extern ipp_t *ippNewRequest(ipp_op_t op) _CUPS_API_1_2; +extern const char *ippOpString(ipp_op_t op) _CUPS_API_1_2; +extern ipp_op_t ippOpValue(const char *name) _CUPS_API_1_2; +extern ipp_state_t ippReadIO(void *src, ipp_iocb_t cb, int blocking, + ipp_t *parent, ipp_t *ipp) _CUPS_API_1_2; +extern ipp_state_t ippWriteIO(void *dst, ipp_iocb_t cb, int blocking, + ipp_t *parent, ipp_t *ipp) _CUPS_API_1_2; + +/**** New in CUPS 1.4 ****/ +extern const char *ippTagString(ipp_tag_t tag) _CUPS_API_1_4; +extern ipp_tag_t ippTagValue(const char *name) _CUPS_API_1_4; + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_IPP_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/langprintf.c b/cups/langprintf.c new file mode 100644 index 0000000000..c12efe669e --- /dev/null +++ b/cups/langprintf.c @@ -0,0 +1,277 @@ +/* + * "$Id$" + * + * Localized printf/puts functions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2002-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsLangPrintError() - Print a message followed by a standard error. + * _cupsLangPrintf() - Print a formatted message string to a file. + * _cupsLangPuts() - Print a static message string to a file. + * _cupsSetLocale() - Set the current locale and transcode the + * command-line. + */ + +/* + * Include necessary headers... + */ + +#include +#include "globals.h" +#include + + +/* + * '_cupsLangPrintError()' - Print a message followed by a standard error. + */ + +void +_cupsLangPrintError(const char *message)/* I - Message */ +{ + int bytes; /* Number of bytes formatted */ + int last_errno; /* Last error */ + char buffer[2048], /* Message buffer */ + output[8192]; /* Output buffer */ + _cups_globals_t *cg; /* Global data */ + + + /* + * Range check... + */ + + if (!message) + return; + + /* + * Save the errno value... + */ + + last_errno = errno; + + /* + * Get the message catalog... + */ + + cg = _cupsGlobals(); + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + /* + * Format the message... + */ + + snprintf(buffer, sizeof(buffer), "%s: %s\n", + _cupsLangString(cg->lang_default, message), strerror(last_errno)); + + /* + * Convert and write to stderr... + */ + + bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), + cg->lang_default->encoding); + + if (bytes > 0) + fwrite(output, 1, bytes, stderr); +} + + +/* + * '_cupsLangPrintf()' - Print a formatted message string to a file. + */ + +int /* O - Number of bytes written */ +_cupsLangPrintf(FILE *fp, /* I - File to write to */ + const char *message, /* I - Message string to use */ + ...) /* I - Additional arguments as needed */ +{ + int bytes; /* Number of bytes formatted */ + char buffer[2048], /* Message buffer */ + output[8192]; /* Output buffer */ + va_list ap; /* Pointer to additional arguments */ + _cups_globals_t *cg; /* Global data */ + + + /* + * Range check... + */ + + if (!fp || !message) + return (-1); + + cg = _cupsGlobals(); + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + /* + * Format the string... + */ + + va_start(ap, message); + vsnprintf(buffer, sizeof(buffer), + _cupsLangString(cg->lang_default, message), ap); + va_end(ap); + + /* + * Transcode to the destination charset... + */ + + bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), + cg->lang_default->encoding); + + /* + * Write the string and return the number of bytes written... + */ + + if (bytes > 0) + return ((int)fwrite(output, 1, bytes, fp)); + else + return (bytes); +} + + +/* + * '_cupsLangPuts()' - Print a static message string to a file. + */ + +int /* O - Number of bytes written */ +_cupsLangPuts(FILE *fp, /* I - File to write to */ + const char *message) /* I - Message string to use */ +{ + int bytes; /* Number of bytes formatted */ + char output[2048]; /* Message buffer */ + _cups_globals_t *cg; /* Global data */ + + + /* + * Range check... + */ + + if (!fp || !message) + return (-1); + + cg = _cupsGlobals(); + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + /* + * Transcode to the destination charset... + */ + + bytes = cupsUTF8ToCharset(output, + (cups_utf8_t *)_cupsLangString(cg->lang_default, + message), + sizeof(output), cg->lang_default->encoding); + + /* + * Write the string and return the number of bytes written... + */ + + if (bytes > 0) + return ((int)fwrite(output, 1, bytes, fp)); + else + return (bytes); +} + + +/* + * '_cupsSetLocale()' - Set the current locale and transcode the command-line. + */ + +void +_cupsSetLocale(char *argv[]) /* IO - Command-line arguments */ +{ + int i; /* Looping var */ + char buffer[8192]; /* Command-line argument buffer */ + _cups_globals_t *cg; /* Global data */ +#ifdef LC_TIME + const char *lc_time; /* Current LC_TIME value */ + char new_lc_time[255], /* New LC_TIME value */ + *charset; /* Pointer to character set */ +#endif /* LC_TIME */ + + + /* + * Set the locale so that times, etc. are displayed properly. + * + * Unfortunately, while we need the localized time value, we *don't* + * want to use the localized charset for the time value, so we need + * to set LC_TIME to the locale name with .UTF-8 on the end (if + * the locale includes a character set specifier...) + */ + + setlocale(LC_ALL, ""); + +#ifdef LC_TIME + if ((lc_time = setlocale(LC_TIME, NULL)) == NULL) + lc_time = setlocale(LC_ALL, NULL); + + if (lc_time) + { + strlcpy(new_lc_time, lc_time, sizeof(new_lc_time)); + if ((charset = strchr(new_lc_time, '.')) == NULL) + charset = new_lc_time + strlen(new_lc_time); + + strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (charset - new_lc_time)); + } + else + strcpy(new_lc_time, "C"); + + setlocale(LC_TIME, new_lc_time); +#endif /* LC_TIME */ + + /* + * Initialize the default language info... + */ + + cg = _cupsGlobals(); + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + /* + * Transcode the command-line arguments from the locale charset to + * UTF-8... + */ + + if (cg->lang_default->encoding != CUPS_US_ASCII && + cg->lang_default->encoding != CUPS_UTF8) + { + for (i = 1; argv[i]; i ++) + { + /* + * Try converting from the locale charset to UTF-8... + */ + + if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer), + cg->lang_default->encoding) < 0) + continue; + + /* + * Save the new string if it differs from the original... + */ + + if (strcmp(buffer, argv[i])) + argv[i] = strdup(buffer); + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/cups/language.c b/cups/language.c new file mode 100644 index 0000000000..f57d709602 --- /dev/null +++ b/cups/language.c @@ -0,0 +1,1337 @@ +/* + * "$Id$" + * + * I18N/language support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsAppleLanguage() - Get the Apple language identifier associated + * with a locale ID. + * _cupsEncodingName() - Return the character encoding name string + * for the given encoding enumeration. + * cupsLangDefault() - Return the default language. + * 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. + * _cupsLangString() - Get a message string. + * _cupsMessageFree() - Free a messages array. + * _cupsMessageLoad() - Load a .po file into a messages array. + * _cupsMessageLookup() - Lookup a message string. + * appleLangDefault() - Get the default locale string. + * cups_cache_lookup() - Lookup a language in the cache... + * cups_message_compare() - Compare two messages. + * cups_unquote() - Unquote characters in strings... + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include +#include +#ifdef HAVE_LANGINFO_H +# include +#endif /* HAVE_LANGINFO_H */ +#ifdef WIN32 +# include +#else +# include +#endif /* WIN32 */ +#ifdef HAVE_COREFOUNDATION_H +# include +#endif /* HAVE_COREFOUNDATION_H */ + + +/* + * Local globals... + */ + +#ifdef HAVE_PTHREAD_H +static pthread_mutex_t lang_mutex = PTHREAD_MUTEX_INITIALIZER; + /* Mutex to control access to cache */ +#endif /* HAVE_PTHREAD_H */ +static cups_lang_t *lang_cache = NULL; + /* Language string cache */ +static const char * const 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", "iso-8859-11", + "iso-8859-16", "mac-roman", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "windows-932", "windows-936", + "windows-949", "windows-950", + "windows-1361", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "euc-cn", "euc-jp", + "euc-kr", "euc-tw", + "jis-x0213" + }; + +#ifdef __APPLE__ +typedef struct +{ + const char * const language; /* Language ID */ + const char * const locale; /* Locale ID */ +} _apple_language_locale_t; + +static const _apple_language_locale_t apple_language_locale[] = +{ /* Locale to language ID LUT */ + { "en" , "en_US" }, + { "nb" , "no" }, + { "zh-Hans" , "zh_CN" }, + { "zh-Hant" , "zh_TW" } +}; +#endif /* __APPLE__ */ + + +/* + * Local functions... + */ + +#ifdef __APPLE__ +static const char *appleLangDefault(void); +#endif /* __APPLE__ */ +static cups_lang_t *cups_cache_lookup(const char *name, + cups_encoding_t encoding); +static int cups_message_compare(_cups_message_t *m1, + _cups_message_t *m2); +static void cups_unquote(char *d, const char *s); + + +#ifdef __APPLE__ +/* + * _cupsAppleLanguage() - Get the Apple language identifier associated + * with a locale ID. + */ + +const char * /* O - Language ID */ +_cupsAppleLanguage(const char *locale, /* I - Locale ID */ + char *language,/* I - Language ID buffer */ + size_t langsize) /* I - Size of language ID buffer */ +{ + int i; /* Looping var */ + CFStringRef localeid, /* CF locale identifier */ + langid; /* CF language identifier */ + + + /* + * Copy the locale name and convert, as needed, to the Apple-specific + * locale identifier... + */ + + switch (strlen(locale)) + { + default : + /* + * Invalid locale... + */ + + strlcpy(language, "en", langsize); + break; + + case 2 : + strlcpy(language, locale, langsize); + break; + + case 5 : + strlcpy(language, locale, langsize); + + if (language[2] == '-') + { + /* + * Convert ll-cc to ll_CC... + */ + + language[2] = '_'; + language[3] = toupper(language[3] & 255); + language[4] = toupper(language[4] & 255); + } + break; + } + + for (i = 0; + i < (int)(sizeof(apple_language_locale) / + sizeof(apple_language_locale[0])); + i ++) + if (!strcmp(locale, apple_language_locale[i].locale)) + { + strlcpy(language, apple_language_locale[i].language, sizeof(language)); + break; + } + + /* + * Attempt to map the locale ID to a language ID... + */ + + if ((localeid = CFStringCreateWithCString(kCFAllocatorDefault, language, + kCFStringEncodingASCII)) != NULL) + { + if ((langid = CFLocaleCreateCanonicalLanguageIdentifierFromString( + kCFAllocatorDefault, localeid)) != NULL) + { + CFStringGetCString(langid, language, langsize, kCFStringEncodingASCII); + CFRelease(langid); + } + + CFRelease(localeid); + } + + /* + * Return what we got... + */ + + return (language); +} +#endif /* __APPLE__ */ + + +/* + * '_cupsEncodingName()' - Return the character encoding name string + * for the given encoding enumeration. + */ + +const char * /* O - Character encoding */ +_cupsEncodingName( + cups_encoding_t encoding) /* I - Encoding value */ +{ + if (encoding < 0 || + encoding >= (sizeof(lang_encodings) / sizeof(const char *))) + { + DEBUG_printf(("1_cupsEncodingName(encoding=%d) = out of range (\"%s\")", + encoding, lang_encodings[0])); + return (lang_encodings[0]); + } + else + { + DEBUG_printf(("1_cupsEncodingName(encoding=%d) = \"%s\"", + encoding, lang_encodings[encoding])); + return (lang_encodings[encoding]); + } +} + + +/* + * 'cupsLangDefault()' - Return the default language. + */ + +cups_lang_t * /* O - Language data */ +cupsLangDefault(void) +{ + return (cupsLangGet(NULL)); +} + + +/* + * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.) + * for the given language. + */ + +const char * /* O - Character encoding */ +cupsLangEncoding(cups_lang_t *lang) /* I - Language data */ +{ + if (lang == NULL) + return ((char*)lang_encodings[0]); + else + return ((char*)lang_encodings[lang->encoding]); +} + + +/* + * 'cupsLangFlush()' - Flush all language data out of the cache. + */ + +void +cupsLangFlush(void) +{ + cups_lang_t *lang, /* Current language */ + *next; /* Next language */ + + + /* + * Free all languages in the cache... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ + + for (lang = lang_cache; lang != NULL; lang = next) + { + /* + * Free all messages... + */ + + _cupsMessageFree(lang->strings); + + /* + * Then free the language structure itself... + */ + + next = lang->next; + free(lang); + } + + lang_cache = NULL; + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * 'cupsLangFree()' - Free language data. + * + * This does not actually free anything; use @link cupsLangFlush@ for that. + */ + +void +cupsLangFree(cups_lang_t *lang) /* I - Language to free */ +{ +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ + + if (lang != NULL && lang->used > 0) + lang->used --; + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * 'cupsLangGet()' - Get a language. + */ + +cups_lang_t * /* O - Language data */ +cupsLangGet(const char *language) /* I - Language or locale */ +{ + int i; /* Looping var */ +#ifndef __APPLE__ + char locale[255]; /* Copy of locale name */ +#endif /* !__APPLE__ */ + char langname[16], /* Requested language name */ + country[16], /* Country code */ + charset[16], /* Character set */ + *csptr, /* Pointer to CODESET string */ + *ptr, /* Pointer into language/charset */ + real[48], /* Real language name */ + filename[1024]; /* Filename for language locale file */ + cups_encoding_t encoding; /* Encoding to use */ + cups_lang_t *lang; /* Current language... */ + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + static const char * const locale_encodings[] = + { /* Locale charset names */ + "ASCII", "ISO88591", "ISO88592", "ISO88593", + "ISO88594", "ISO88595", "ISO88596", "ISO88597", + "ISO88598", "ISO88599", "ISO885910", "UTF8", + "ISO885913", "ISO885914", "ISO885915", "CP874", + "CP1250", "CP1251", "CP1252", "CP1253", + "CP1254", "CP1255", "CP1256", "CP1257", + "CP1258", "KOI8R", "KOI8U", "ISO885911", + "ISO885916", "MACROMAN", "", "", + + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + + "CP932", "CP936", "CP949", "CP950", + "CP1361", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + + "EUCCN", "EUCJP", "EUCKR", "EUCTW", + "SHIFT_JISX0213" + }; + + + DEBUG_printf(("2cupsLangGet(language=\"%s\")", language)); + +#ifdef __APPLE__ + /* + * Set the character set to UTF-8... + */ + + strcpy(charset, "UTF8"); + + /* + * Apple's setlocale doesn't give us the user's localization + * preference so we have to look it up this way... + */ + + if (!language) + { + if (!getenv("SOFTWARE") || (language = getenv("LANG")) == NULL) + language = appleLangDefault(); + + DEBUG_printf(("4cupsLangGet: language=\"%s\"", language)); + } + +#else + /* + * Set the charset to "unknown"... + */ + + charset[0] = '\0'; + + /* + * Use setlocale() to determine the currently set locale, and then + * fallback to environment variables to avoid setting the locale, + * since setlocale() is not thread-safe! + */ + + if (!language) + { + /* + * First see if the locale has been set; if it is still "C" or + * "POSIX", use the environment to get the default... + */ + +# ifdef LC_MESSAGES + ptr = setlocale(LC_MESSAGES, NULL); +# else + ptr = setlocale(LC_ALL, NULL); +# endif /* LC_MESSAGES */ + + DEBUG_printf(("4cupsLangGet: current locale is \"%s\"", ptr)); + + if (!ptr || !strcmp(ptr, "C") || !strcmp(ptr, "POSIX")) + { + /* + * Get the character set from the LC_CTYPE locale setting... + */ + + if ((ptr = getenv("LC_CTYPE")) == NULL) + if ((ptr = getenv("LC_ALL")) == NULL) + if ((ptr = getenv("LANG")) == NULL) + ptr = "en_US"; + + if ((csptr = strchr(ptr, '.')) != NULL) + { + /* + * Extract the character set from the environment... + */ + + for (ptr = charset, csptr ++; *csptr; csptr ++) + if (ptr < (charset + sizeof(charset) - 1) && _cups_isalnum(*csptr)) + *ptr++ = *csptr; + + *ptr = '\0'; + } + + /* + * Get the locale for messages from the LC_MESSAGES locale setting... + */ + + if ((ptr = getenv("LC_MESSAGES")) == NULL) + if ((ptr = getenv("LC_ALL")) == NULL) + if ((ptr = getenv("LANG")) == NULL) + ptr = "en_US"; + } + + if (ptr) + { + strlcpy(locale, ptr, sizeof(locale)); + language = locale; + + /* + * CUPS STR #2575: Map "nb" to "no" for back-compatibility... + */ + + if (!strncmp(locale, "nb", 2)) + locale[1] = 'o'; + + DEBUG_printf(("4cupsLangGet: new language value is \"%s\"", language)); + } + } +#endif /* __APPLE__ */ + + /* + * If "language" is NULL at this point, then chances are we are using + * a language that is not installed for the base OS. + */ + + if (!language) + { + /* + * Switch to the POSIX ("C") locale... + */ + + language = "C"; + } + +#ifdef CODESET + /* + * On systems that support the nl_langinfo(CODESET) call, use + * this value as the character set... + */ + + if (!charset[0] && (csptr = nl_langinfo(CODESET)) != NULL) + { + /* + * Copy all of the letters and numbers in the CODESET string... + */ + + for (ptr = charset; *csptr; csptr ++) + if (_cups_isalnum(*csptr) && ptr < (charset + sizeof(charset) - 1)) + *ptr++ = *csptr; + + *ptr = '\0'; + + DEBUG_printf(("4cupsLangGet: charset set to \"%s\" via " + "nl_langinfo(CODESET)...", charset)); + } +#endif /* CODESET */ + + /* + * If we don't have a character set by now, default to UTF-8... + */ + + if (!charset[0]) + strcpy(charset, "UTF8"); + + /* + * Parse 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[.charset] (language-country) + * to ll_CC[.CHARSET] to match the file naming convention used by all + * POSIX-compliant operating systems. Invalid language names are mapped + * to the POSIX locale. + */ + + country[0] = '\0'; + + if (language == NULL || !language[0] || + !strcmp(language, "POSIX")) + strcpy(langname, "C"); + else + { + /* + * Copy the parts of the locale string over safely... + */ + + for (ptr = langname; *language; language ++) + if (*language == '_' || *language == '-' || *language == '.') + break; + else if (ptr < (langname + sizeof(langname) - 1)) + *ptr++ = tolower(*language & 255); + + *ptr = '\0'; + + if (*language == '_' || *language == '-') + { + /* + * Copy the country code... + */ + + for (language ++, ptr = country; *language; language ++) + if (*language == '.') + break; + else if (ptr < (country + sizeof(country) - 1)) + *ptr++ = toupper(*language & 255); + + *ptr = '\0'; + } + + if (*language == '.' && !charset[0]) + { + /* + * Copy the encoding... + */ + + for (language ++, ptr = charset; *language; language ++) + if (_cups_isalnum(*language) && ptr < (charset + sizeof(charset) - 1)) + *ptr++ = toupper(*language & 255); + + *ptr = '\0'; + } + + /* + * Force a POSIX locale for an invalid language name... + */ + + if (strlen(langname) != 2) + { + strcpy(langname, "C"); + country[0] = '\0'; + charset[0] = '\0'; + } + } + + DEBUG_printf(("4cupsLangGet: langname=\"%s\", country=\"%s\", charset=\"%s\"", + langname, country, charset)); + + /* + * Figure out the desired encoding... + */ + + encoding = CUPS_AUTO_ENCODING; + + if (charset[0]) + { + for (i = 0; + i < (int)(sizeof(locale_encodings) / sizeof(locale_encodings[0])); + i ++) + if (!strcasecmp(charset, locale_encodings[i])) + { + encoding = (cups_encoding_t)i; + break; + } + + if (encoding == CUPS_AUTO_ENCODING) + { + /* + * Map alternate names for various character sets... + */ + + if (!strcasecmp(charset, "iso-2022-jp") || + !strcasecmp(charset, "sjis")) + encoding = CUPS_WINDOWS_932; + else if (!strcasecmp(charset, "iso-2022-cn")) + encoding = CUPS_WINDOWS_936; + else if (!strcasecmp(charset, "iso-2022-kr")) + encoding = CUPS_WINDOWS_949; + else if (!strcasecmp(charset, "big5")) + encoding = CUPS_WINDOWS_950; + } + } + + DEBUG_printf(("4cupsLangGet: encoding=%d(%s)", encoding, + encoding == CUPS_AUTO_ENCODING ? "auto" : + lang_encodings[encoding])); + + /* + * See if we already have this language/country loaded... + */ + + if (country[0]) + { + snprintf(real, sizeof(real), "%s_%s", langname, country); + + snprintf(filename, sizeof(filename), "%s/%s/cups_%s.po", cg->localedir, + real, real); + } + else + { + strcpy(real, langname); + filename[0] = '\0'; /* anti-compiler-warning-code */ + } + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ + + if ((lang = cups_cache_lookup(real, encoding)) != NULL) + { +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ + + DEBUG_printf(("3cupsLangGet: Using cached copy of \"%s\"...", real)); + + return (lang); + } + + if (!country[0] || access(filename, 0)) + { + /* + * Country localization not available, look for generic localization... + */ + + snprintf(filename, sizeof(filename), "%s/%s/cups_%s.po", cg->localedir, + langname, langname); + + if (access(filename, 0)) + { + /* + * No generic localization, so use POSIX... + */ + + DEBUG_printf(("4cupsLangGet: access(\"%s\", 0): %s", filename, + strerror(errno))); + + snprintf(filename, sizeof(filename), "%s/C/cups_C.po", cg->localedir); + } + } + + /* + * 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) + { +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (NULL); + } + + lang->next = lang_cache; + lang_cache = lang; + } + else + { + /* + * Free all old strings as needed... + */ + + _cupsMessageFree(lang->strings); + } + + /* + * Then assign the language and encoding fields... + */ + + lang->used ++; + strlcpy(lang->language, real, sizeof(lang->language)); + + if (encoding != CUPS_AUTO_ENCODING) + lang->encoding = encoding; + else + lang->encoding = CUPS_UTF8; + + /* + * Read the strings from the file... + */ + + lang->strings = _cupsMessageLoad(filename, 1); + + /* + * Return... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&lang_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (lang); +} + + +/* + * '_cupsLangString()' - Get a message string. + * + * The returned string is UTF-8 encoded; use cupsUTF8ToCharset() to + * convert the string to the language encoding. + */ + +const char * /* O - Localized message */ +_cupsLangString(cups_lang_t *lang, /* I - Language */ + const char *message) /* I - Message */ +{ + /* + * Range check input... + */ + + if (!lang || !message) + return (message); + +#ifdef HAVE_PTHREAD_H + { + const char *s; /* Localized message */ + + pthread_mutex_lock(&lang_mutex); + + s = _cupsMessageLookup(lang->strings, message); + + pthread_mutex_unlock(&lang_mutex); + + return (s); + } +#else + return (_cupsMessageLookup(lang->strings, message)); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * '_cupsMessageFree()' - Free a messages array. + */ + +void +_cupsMessageFree(cups_array_t *a) /* I - Message array */ +{ + _cups_message_t *m; /* Current message */ + + + for (m = (_cups_message_t *)cupsArrayFirst(a); + m; + m = (_cups_message_t *)cupsArrayNext(a)) + { + /* + * Remove the message from the array, then free the message and strings. + */ + + cupsArrayRemove(a, m); + + if (m->id) + free(m->id); + + if (m->str) + free(m->str); + + free(m); + } + + /* + * Free the array... + */ + + cupsArrayDelete(a); +} + + +/* + * '_cupsMessageLoad()' - Load a .po file into a messages array. + */ + +cups_array_t * /* O - New message array */ +_cupsMessageLoad(const char *filename, /* I - Message catalog to load */ + int unquote) /* I - Unescape \foo in strings */ +{ + cups_file_t *fp; /* Message file */ + cups_array_t *a; /* Message array */ + _cups_message_t *m; /* Current message */ + char s[4096], /* String buffer */ + *ptr, /* Pointer into buffer */ + *temp; /* New string */ + int length; /* Length of combined strings */ + + + DEBUG_printf(("4_cupsMessageLoad(filename=\"%s\")", filename)); + + /* + * Create an array to hold the messages... + */ + + if ((a = cupsArrayNew((cups_array_func_t)cups_message_compare, NULL)) == NULL) + { + DEBUG_puts("5_cupsMessageLoad: Unable to allocate array!"); + return (NULL); + } + + /* + * Open the message catalog file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + DEBUG_printf(("5_cupsMessageLoad: Unable to open file: %s", + strerror(errno))); + return (a); + } + + /* + * Read messages from the catalog file until EOF... + * + * The format is the GNU gettext .po format, which is fairly simple: + * + * msgid "some text" + * msgstr "localized text" + * + * The ID and localized text can span multiple lines using the form: + * + * msgid "" + * "some long text" + * msgstr "" + * "localized text spanning " + * "multiple lines" + */ + + m = NULL; + + while (cupsFileGets(fp, s, sizeof(s)) != NULL) + { + /* + * Skip blank and comment lines... + */ + + if (s[0] == '#' || !s[0]) + continue; + + /* + * Strip the trailing quote... + */ + + if ((ptr = strrchr(s, '\"')) == NULL) + continue; + + *ptr = '\0'; + + /* + * Find start of value... + */ + + if ((ptr = strchr(s, '\"')) == NULL) + continue; + + ptr ++; + + /* + * Unquote the text... + */ + + if (unquote) + cups_unquote(ptr, ptr); + + /* + * Create or add to a message... + */ + + if (!strncmp(s, "msgid", 5)) + { + /* + * Add previous message as needed... + */ + + if (m) + cupsArrayAdd(a, m); + + /* + * Create a new message with the given msgid string... + */ + + if ((m = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL) + { + cupsFileClose(fp); + return (a); + } + + if ((m->id = strdup(ptr)) == NULL) + { + free(m); + cupsFileClose(fp); + return (a); + } + } + else if (s[0] == '\"' && m) + { + /* + * Append to current string... + */ + + length = (int)strlen(m->str ? m->str : m->id); + + if ((temp = realloc(m->str ? m->str : m->id, + length + strlen(ptr) + 1)) == NULL) + { + cupsFileClose(fp); + return (a); + } + + if (m->str) + { + /* + * Copy the new portion to the end of the msgstr string - safe + * to use strcpy because the buffer is allocated to the correct + * size... + */ + + m->str = temp; + + strcpy(m->str + length, ptr); + } + else + { + /* + * Copy the new portion to the end of the msgid string - safe + * to use strcpy because the buffer is allocated to the correct + * size... + */ + + m->id = temp; + + strcpy(m->id + length, ptr); + } + } + else if (!strncmp(s, "msgstr", 6) && m) + { + /* + * Set the string... + */ + + if ((m->str = strdup(ptr)) == NULL) + { + cupsFileClose(fp); + return (a); + } + } + } + + /* + * Add the last message string to the array as needed... + */ + + if (m) + cupsArrayAdd(a, m); + + /* + * Close the message catalog file and return the new array... + */ + + cupsFileClose(fp); + + DEBUG_printf(("5_cupsMessageLoad: Returning %d messages...", + cupsArrayCount(a))); + + return (a); +} + + +/* + * '_cupsMessageLookup()' - Lookup a message string. + */ + +const char * /* O - Localized message */ +_cupsMessageLookup(cups_array_t *a, /* I - Message array */ + const char *m) /* I - Message */ +{ + _cups_message_t key, /* Search key */ + *match; /* Matching message */ + + + /* + * Lookup the message string; if it doesn't exist in the catalog, + * then return the message that was passed to us... + */ + + key.id = (char *)m; + match = (_cups_message_t *)cupsArrayFind(a, &key); + + if (match && match->str) + return (match->str); + else + return (m); +} + + +#ifdef __APPLE__ +/* + * 'appleLangDefault()' - Get the default locale string. + */ + +static const char * /* O - Locale string */ +appleLangDefault(void) +{ + int i; /* Looping var */ + CFBundleRef bundle; /* Main bundle (if any) */ + CFArrayRef bundleList; /* List of localizations in bundle */ + CFPropertyListRef localizationList; + /* List of localization data */ + CFStringRef languageName; /* Current name */ + CFStringRef localeName; /* Canonical from of name */ + char *lang; /* LANG environment variable */ + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + + + DEBUG_puts("2appleLangDefault()"); + + /* + * Only do the lookup and translation the first time. + */ + + if (!cg->language[0]) + { + if (getenv("SOFTWARE") != NULL && (lang = getenv("LANG")) != NULL) + { + strlcpy(cg->language, lang, sizeof(cg->language)); + return (cg->language); + } + else if ((bundle = CFBundleGetMainBundle()) != NULL && + (bundleList = CFBundleCopyBundleLocalizations(bundle)) != NULL) + { + localizationList = + CFBundleCopyPreferredLocalizationsFromArray(bundleList); + + CFRelease(bundleList); + } + else + localizationList = + CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), + kCFPreferencesCurrentApplication); + + if (localizationList) + { + if (CFGetTypeID(localizationList) == CFArrayGetTypeID() && + CFArrayGetCount(localizationList) > 0) + { + languageName = CFArrayGetValueAtIndex(localizationList, 0); + + if (languageName && + CFGetTypeID(languageName) == CFStringGetTypeID()) + { + localeName = CFLocaleCreateCanonicalLocaleIdentifierFromString( + kCFAllocatorDefault, languageName); + + if (localeName) + { + CFStringGetCString(localeName, cg->language, sizeof(cg->language), + kCFStringEncodingASCII); + CFRelease(localeName); + + DEBUG_printf(("9appleLangDefault: cg->language=\"%s\"", + cg->language)); + + /* + * Map new language identifiers to locales... + */ + + for (i = 0; + i < (int)(sizeof(apple_language_locale) / + sizeof(apple_language_locale[0])); + i ++) + { + if (!strcmp(cg->language, apple_language_locale[i].language)) + { + DEBUG_printf(("9appleLangDefault: mapping \"%s\" to \"%s\"...", + cg->language, apple_language_locale[i].locale)); + strlcpy(cg->language, apple_language_locale[i].locale, + sizeof(cg->language)); + break; + } + } + + /* + * Convert language subtag into region subtag... + */ + + if (cg->language[2] == '-') + cg->language[2] = '_'; + + if (!strchr(cg->language, '.')) + strlcat(cg->language, ".UTF-8", sizeof(cg->language)); + } + } + } + + CFRelease(localizationList); + } + + /* + * If we didn't find the language, default to en_US... + */ + + if (!cg->language[0]) + strlcpy(cg->language, "en_US.UTF-8", sizeof(cg->language)); + } + + /* + * Return the cached locale... + */ + + return (cg->language); +} +#endif /* __APPLE__ */ + + +/* + * 'cups_cache_lookup()' - Lookup a language in the cache... + */ + +static cups_lang_t * /* O - Language data or NULL */ +cups_cache_lookup(const char *name,/* I - Name of locale */ + cups_encoding_t encoding) + /* I - Encoding of locale */ +{ + cups_lang_t *lang; /* Current language */ + + + DEBUG_printf(("7cups_cache_lookup(name=\"%s\", encoding=%d(%s))", name, + encoding, encoding == CUPS_AUTO_ENCODING ? "auto" : + lang_encodings[encoding])); + + /* + * Loop through the cache and return a match if found... + */ + + for (lang = lang_cache; lang != NULL; lang = lang->next) + { + DEBUG_printf(("9cups_cache_lookup: lang=%p, language=\"%s\", " + "encoding=%d(%s)", lang, lang->language, lang->encoding, + lang_encodings[lang->encoding])); + + if (!strcmp(lang->language, name) && + (encoding == CUPS_AUTO_ENCODING || encoding == lang->encoding)) + { + lang->used ++; + + DEBUG_puts("8cups_cache_lookup: returning match!"); + + return (lang); + } + } + + DEBUG_puts("8cups_cache_lookup: returning NULL!"); + + return (NULL); +} + + +/* + * 'cups_message_compare()' - Compare two messages. + */ + +static int /* O - Result of comparison */ +cups_message_compare( + _cups_message_t *m1, /* I - First message */ + _cups_message_t *m2) /* I - Second message */ +{ + return (strcmp(m1->id, m2->id)); +} + + +/* + * 'cups_unquote()' - Unquote characters in strings... + */ + +static void +cups_unquote(char *d, /* O - Unquoted string */ + const char *s) /* I - Original string */ +{ + while (*s) + { + if (*s == '\\') + { + s ++; + if (isdigit(*s)) + { + *d = 0; + + while (isdigit(*s)) + { + *d = *d * 8 + *s - '0'; + s ++; + } + + d ++; + } + else + { + if (*s == 'n') + *d ++ = '\n'; + else if (*s == 'r') + *d ++ = '\r'; + else if (*s == 't') + *d ++ = '\t'; + else + *d++ = *s; + + s ++; + } + } + else + *d++ = *s++; + } + + *d = '\0'; +} + + +/* + * End of "$Id$". + */ diff --git a/cups/language.h b/cups/language.h new file mode 100644 index 0000000000..815045086d --- /dev/null +++ b/cups/language.h @@ -0,0 +1,115 @@ +/* + * "$Id$" + * + * Multi-language support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +# include "array.h" + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Types... + */ + +typedef enum cups_encoding_e /**** Language Encodings ****/ +{ + CUPS_AUTO_ENCODING = -1, /* Auto-detect the encoding @private@ */ + CUPS_US_ASCII, /* US ASCII */ + CUPS_ISO8859_1, /* ISO-8859-1 */ + CUPS_ISO8859_2, /* ISO-8859-2 */ + CUPS_ISO8859_3, /* ISO-8859-3 */ + CUPS_ISO8859_4, /* ISO-8859-4 */ + CUPS_ISO8859_5, /* ISO-8859-5 */ + CUPS_ISO8859_6, /* ISO-8859-6 */ + CUPS_ISO8859_7, /* ISO-8859-7 */ + CUPS_ISO8859_8, /* ISO-8859-8 */ + CUPS_ISO8859_9, /* ISO-8859-9 */ + CUPS_ISO8859_10, /* ISO-8859-10 */ + CUPS_UTF8, /* UTF-8 */ + CUPS_ISO8859_13, /* ISO-8859-13 */ + CUPS_ISO8859_14, /* ISO-8859-14 */ + CUPS_ISO8859_15, /* ISO-8859-15 */ + CUPS_WINDOWS_874, /* CP-874 */ + CUPS_WINDOWS_1250, /* CP-1250 */ + CUPS_WINDOWS_1251, /* CP-1251 */ + CUPS_WINDOWS_1252, /* CP-1252 */ + CUPS_WINDOWS_1253, /* CP-1253 */ + CUPS_WINDOWS_1254, /* CP-1254 */ + CUPS_WINDOWS_1255, /* CP-1255 */ + CUPS_WINDOWS_1256, /* CP-1256 */ + CUPS_WINDOWS_1257, /* CP-1257 */ + CUPS_WINDOWS_1258, /* CP-1258 */ + CUPS_KOI8_R, /* KOI-8-R */ + CUPS_KOI8_U, /* KOI-8-U */ + CUPS_ISO8859_11, /* ISO-8859-11 */ + CUPS_ISO8859_16, /* ISO-8859-16 */ + CUPS_MAC_ROMAN, /* MacRoman */ + CUPS_ENCODING_SBCS_END = 63, /* End of single-byte encodings @private@ */ + + CUPS_WINDOWS_932, /* Japanese JIS X0208-1990 */ + CUPS_WINDOWS_936, /* Simplified Chinese GB 2312-80 */ + CUPS_WINDOWS_949, /* Korean KS C5601-1992 */ + CUPS_WINDOWS_950, /* Traditional Chinese Big Five */ + CUPS_WINDOWS_1361, /* Korean Johab */ + CUPS_ENCODING_DBCS_END = 127, /* End of double-byte encodings @private@ */ + + CUPS_EUC_CN, /* EUC Simplified Chinese */ + CUPS_EUC_JP, /* EUC Japanese */ + CUPS_EUC_KR, /* EUC Korean */ + CUPS_EUC_TW, /* EUC Traditional Chinese */ + CUPS_JIS_X0213, /* JIS X0213 aka Shift JIS */ + CUPS_ENCODING_VBCS_END = 191 /* End of variable-length encodings @private@ */ +} cups_encoding_t; + +typedef struct cups_lang_s /**** Language Cache Structure ****/ +{ + struct cups_lang_s *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 */ + cups_array_t *strings; /* Message strings @private@ */ +} cups_lang_t; + + +/* + * Prototypes... + */ + +extern cups_lang_t *cupsLangDefault(void); +extern const 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); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_LANGUAGE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/libcups.exp b/cups/libcups.exp new file mode 100644 index 0000000000..ea87af4f0a --- /dev/null +++ b/cups/libcups.exp @@ -0,0 +1,372 @@ +__cups_debug_fd +__cups_debug_printf +__cups_debug_puts +__cups_strcpy +__cupsAppleLanguage +__cupsCharmapFlush +__cupsCharmapFree +__cupsCharmapGet +__cupsEncodingName +__cupsGetPassword +__cupsGlobals +__cupsLangPrintError +__cupsLangPrintf +__cupsLangPuts +__cupsLangString +__cupsMD5Append +__cupsMD5Finish +__cupsMD5Init +__cupsMessageFree +__cupsMessageLoad +__cupsMessageLookup +__cupsSetError +__cupsSetLocale +__cupsSNMPClose +__cupsSNMPCopyOID +__cupsSNMPDefaultCommunity +__cupsSNMPIsOID +__cupsSNMPIsOIDPrefixed +__cupsSNMPOIDToString +__cupsSNMPOpen +__cupsSNMPRead +__cupsSNMPSetDebug +__cupsSNMPStringToOID +__cupsSNMPWalk +__cupsSNMPWrite +__cupsStrAlloc +__cupsStrFlush +__cupsStrFormatd +__cupsStrFree +__cupsStrRetain +__cupsStrScand +__cupsStrStatistics +__httpAddrPort +__httpCreate +__httpEncodeURI +__httpReadCDSA +__httpResolveURI +__httpWriteCDSA +__ippAddAttr +__ippFindOption +__ippFreeAttr +__ppdFreeLanguages +__ppdGet1284Values +__ppdGetEncoding +__ppdGetLanguages +__ppdHashName +__ppdLocalizedAttr +__ppdNormalizeMakeAndModel +__ppdParseOptions +__pwgCreateWithFile +__pwgCreateWithPPD +__pwgDestroy +__pwgGenerateSize +__pwgGetBin +__pwgGetInputSlot +__pwgGetMediaType +__pwgGetOutputBin +__pwgGetPageSize +__pwgGetSize +__pwgGetSource +__pwgGetType +__pwgInitSize +__pwgInputSlotForSource +__pwgMediaForLegacy +__pwgMediaForPPD +__pwgMediaForPWG +__pwgMediaForSize +__pwgMediaTypeForType +__pwgPageSizeForMedia +__pwgWriteFile +_cupsAddDest +_cupsAddOption +_cupsAdminCreateWindowsPPD +_cupsAdminExportSamba +_cupsAdminGetServerSettings +_cupsAdminSetServerSettings +_cupsArrayAdd +_cupsArrayClear +_cupsArrayCount +_cupsArrayCurrent +_cupsArrayDelete +_cupsArrayDup +_cupsArrayFind +_cupsArrayFirst +_cupsArrayGetIndex +_cupsArrayGetInsert +_cupsArrayIndex +_cupsArrayInsert +_cupsArrayLast +_cupsArrayNew +_cupsArrayNew2 +_cupsArrayNext +_cupsArrayPrev +_cupsArrayRemove +_cupsArrayRestore +_cupsArraySave +_cupsArrayUserData +_cupsBackChannelRead +_cupsBackChannelWrite +_cupsBackendDeviceURI +_cupsBackendReport +_cupsCancelJob +_cupsCancelJob2 +_cupsCharsetToUTF8 +_cupsCreateJob +_cupsDirClose +_cupsDirOpen +_cupsDirRead +_cupsDirRewind +_cupsDoAuthentication +_cupsDoFileRequest +_cupsDoIORequest +_cupsDoRequest +_cupsEncodeOptions +_cupsEncodeOptions2 +_cupsEncryption +_cupsFileClose +_cupsFileCompression +_cupsFileEOF +_cupsFileFind +_cupsFileFlush +_cupsFileGetChar +_cupsFileGetConf +_cupsFileGetLine +_cupsFileGets +_cupsFileLock +_cupsFileNumber +_cupsFileOpen +_cupsFileOpenFd +_cupsFilePeekChar +_cupsFilePrintf +_cupsFilePutChar +_cupsFilePutConf +_cupsFilePuts +_cupsFileRead +_cupsFileRewind +_cupsFileSeek +_cupsFileStderr +_cupsFileStdin +_cupsFileStdout +_cupsFileTell +_cupsFileUnlock +_cupsFileWrite +_cupsFinishDocument +_cupsFreeDests +_cupsFreeJobs +_cupsFreeOptions +_cupsGetClasses +_cupsGetConflicts +_cupsGetDefault +_cupsGetDefault2 +_cupsGetDest +_cupsGetDests +_cupsGetDests2 +_cupsGetDevices +_cupsGetFd +_cupsGetFile +_cupsGetJobs +_cupsGetJobs2 +_cupsGetNamedDest +_cupsGetOption +_cupsGetPassword +_cupsGetPassword2 +_cupsGetPPD +_cupsGetPPD2 +_cupsGetPPD3 +_cupsGetPrinters +_cupsGetResponse +_cupsGetServerPPD +_cupsLangDefault +_cupsLangEncoding +_cupsLangFlush +_cupsLangFree +_cupsLangGet +_cupsLastError +_cupsLastErrorString +_cupsMarkOptions +_cupsNotifySubject +_cupsNotifyText +_cupsParseOptions +_cupsPrintFile +_cupsPrintFile2 +_cupsPrintFiles +_cupsPrintFiles2 +_cupsPutFd +_cupsPutFile +_cupsReadResponseData +_cupsRemoveDest +_cupsRemoveOption +_cupsResolveConflicts +_cupsSendRequest +_cupsServer +_cupsSetDefaultDest +_cupsSetDests +_cupsSetDests2 +_cupsSetEncryption +_cupsSetPasswordCB +_cupsSetPasswordCB2 +_cupsSetServer +_cupsSetUser +_cupsSideChannelDoRequest +_cupsSideChannelRead +_cupsSideChannelWrite +_cupsSideChannelSNMPGet +_cupsSideChannelSNMPWalk +_cupsStartDocument +_cupsTempFd +_cupsTempFile +_cupsTempFile2 +_cupsUser +_cupsUTF32ToUTF8 +_cupsUTF8ToCharset +_cupsUTF8ToUTF32 +_cupsWriteRequestData +_httpAddrAny +_httpAddrConnect +_httpAddrEqual +_httpAddrFreeList +_httpAddrGetList +_httpAddrLength +_httpAddrLocalhost +_httpAddrLookup +_httpAddrString +_httpAssembleURI +_httpAssembleURIf +_httpBlocking +_httpCheck +_httpClearCookie +_httpClearFields +_httpClose +_httpConnect +_httpConnectEncrypt +_httpDecode64 +_httpDecode64_2 +_httpDelete +_httpEncode64 +_httpEncode64_2 +_httpEncryption +_httpError +_httpFlush +_httpFlushWrite +_httpGet +_httpGetAuthString +_httpGetBlocking +_httpGetCookie +_httpGetDateString +_httpGetDateString2 +_httpGetDateTime +_httpGetFd +_httpGetField +_httpGetHostByName +_httpGetHostname +_httpGetLength +_httpGetLength2 +_httpGets +_httpGetStatus +_httpGetSubField +_httpGetSubField2 +_httpHead +_httpInitialize +_httpMD5 +_httpMD5Final +_httpMD5String +_httpOptions +_httpPost +_httpPrintf +_httpPut +_httpRead +_httpRead2 +_httpReconnect +_httpSeparate +_httpSeparate2 +_httpSeparateURI +_httpSetAuthString +_httpSetCookie +_httpSetExpect +_httpSetField +_httpSetLength +_httpStatus +_httpTrace +_httpUpdate +_httpWait +_httpWrite +_httpWrite2 +_ippAddBoolean +_ippAddBooleans +_ippAddCollection +_ippAddCollections +_ippAddDate +_ippAddInteger +_ippAddIntegers +_ippAddOctetString +_ippAddRange +_ippAddRanges +_ippAddResolution +_ippAddResolutions +_ippAddSeparator +_ippAddString +_ippAddStrings +_ippDateToTime +_ippDelete +_ippDeleteAttribute +_ippErrorString +_ippErrorValue +_ippFindAttribute +_ippFindNextAttribute +_ippLength +_ippNew +_ippNewRequest +_ippOpString +_ippOpValue +_ippPort +_ippRead +_ippReadFile +_ippReadIO +_ippSetPort +_ippTagString +_ippTagValue +_ippTimeToDate +_ippWrite +_ippWriteFile +_ippWriteIO +_ppdClose +_ppdCollect +_ppdCollect2 +_ppdConflicts +_ppdEmit +_ppdEmitAfterOrder +_ppdEmitFd +_ppdEmitJCL +_ppdEmitJCLEnd +_ppdEmitString +_ppdErrorString +_ppdFindAttr +_ppdFindChoice +_ppdFindCustomOption +_ppdFindCustomParam +_ppdFindMarkedChoice +_ppdFindNextAttr +_ppdFindOption +_ppdFirstCustomParam +_ppdFirstOption +_ppdInstallableConflict +_ppdIsMarked +_ppdLastError +_ppdLocalize +_ppdLocalizeAttr +_ppdLocalizeIPPReason +_ppdLocalizeMarkerName +_ppdMarkDefaults +_ppdMarkOption +_ppdNextCustomParam +_ppdNextOption +_ppdOpen +_ppdOpen2 +_ppdOpenFd +_ppdOpenFile +_ppdPageLength +_ppdPageSize +_ppdPageSizeLimits +_ppdPageWidth +_ppdSetConformance diff --git a/cups/libcups.order b/cups/libcups.order new file mode 100755 index 0000000000..92820f7c2b --- /dev/null +++ b/cups/libcups.order @@ -0,0 +1 @@ +single module:dyld_stub_binding_helper diff --git a/cups/libcups2.def b/cups/libcups2.def new file mode 100644 index 0000000000..8bfc1a2f38 --- /dev/null +++ b/cups/libcups2.def @@ -0,0 +1,287 @@ +LIBRARY libcups2 +VERSION 2.7 +EXPORTS +_cupsCharmapFlush +_cupsCharmapFree +_cupsCharmapGet +_cupsEncodingName +_cupsGetPassword +_cupsGlobals +_cupsLangPrintf +_cupsLangPuts +_cupsLangString +_cupsMD5Append +_cupsMD5Finish +_cupsMD5Init +_cupsMessageFree +_cupsMessageLoad +_cupsMessageLookup +_cupsSetError +_cupsSetLocale +_cupsStrAlloc +_cupsStrFlush +_cupsStrFormatd +_cupsStrFree +_cupsStrScand +_cupsStrStatistics +_cups_strcpy +_cups_strlcat +_cups_strlcpy +_httpResolveURI +_ippAddAttr +_ippFindOption +_ippFreeAttr +_ppdFreeLanguages +_ppdGetEncoding +_ppdGetLanguages +_ppdHashName +cupsAddDest +cupsAddOption +cupsAdminCreateWindowsPPD +cupsAdminExportSamba +cupsArrayAdd +cupsArrayClear +cupsArrayCount +cupsArrayCurrent +cupsArrayDelete +cupsArrayDup +cupsArrayFind +cupsArrayFirst +cupsArrayIndex +cupsArrayInsert +cupsArrayLast +cupsArrayNew +cupsArrayNext +cupsArrayPrev +cupsArrayRemove +cupsArrayRestore +cupsArraySave +cupsArrayUserData +cupsCancelJob +cupsCharsetToUTF8 +cupsDirClose +cupsDirOpen +cupsDirRead +cupsDirRewind +cupsDoAuthentication +cupsDoFileRequest +cupsDoRequest +cupsEncodeOptions +cupsEncodeOptions2 +cupsEncryption +cupsFileClose +cupsFileCompression +cupsFileEOF +cupsFileFind +cupsFileFlush +cupsFileGetChar +cupsFileGetConf +cupsFileGetLine +cupsFileGets +cupsFileLock +cupsFileNumber +cupsFileOpen +cupsFileOpenFd +cupsFilePeekChar +cupsFilePrintf +cupsFilePutChar +cupsFilePuts +cupsFileRead +cupsFileRewind +cupsFileSeek +cupsFileStderr +cupsFileStdin +cupsFileStdout +cupsFileTell +cupsFileUnlock +cupsFileWrite +cupsFreeDests +cupsFreeJobs +cupsFreeOptions +cupsGetClasses +cupsGetDefault +cupsGetDefault2 +cupsGetDest +cupsGetDests +cupsGetDests2 +cupsGetFd +cupsGetFile +cupsGetJobs +cupsGetJobs2 +cupsGetOption +cupsGetPPD +cupsGetPPD2 +cupsGetPassword +cupsGetPrinters +cupsLangDefault +cupsLangEncoding +cupsLangFlush +cupsLangFree +cupsLangGet +cupsLastError +cupsLastErrorString +cupsMarkOptions +cupsNotifySubject +cupsNotifyText +cupsParseOptions +cupsPrintFile +cupsPrintFile2 +cupsPrintFiles +cupsPrintFiles2 +cupsPutFd +cupsPutFile +cupsRemoveOption +cupsResolveConflicts +cupsServer +cupsSetDests +cupsSetDests2 +cupsSetEncryption +cupsSetPasswordCB +cupsSetServer +cupsSetUser +cupsTempFd +cupsTempFile +cupsTempFile2 +cupsUTF32ToUTF8 +cupsUTF8ToCharset +cupsUTF8ToUTF32 +cupsUser +httpAddrAny +httpAddrConnect +httpAddrEqual +httpAddrFreeList +httpAddrGetList +httpAddrLength +httpAddrLocalhost +httpAddrLookup +httpAddrString +httpAssembleURI +httpAssembleURIf +httpBlocking +httpCheck +httpClearCookie +httpClearFields +httpClose +httpConnect +httpConnectEncrypt +httpDecode64 +httpDecode64_2 +httpDelete +httpEncode64 +httpEncode64_2 +httpEncryption +httpError +httpFlush +httpFlushWrite +httpGet +httpGetBlocking +httpGetCookie +httpGetDateString +httpGetDateString2 +httpGetDateTime +httpGetFd +httpGetField +httpGetHostByName +httpGetHostname +httpGetLength +httpGetLength2 +httpGetStatus +httpGetSubField +httpGetSubField2 +httpGets +httpHead +httpInitialize +httpMD5 +httpMD5Final +httpMD5String +httpOptions +httpPost +httpPrintf +httpPut +httpRead +httpRead2 +httpReconnect +httpSeparate +httpSeparate2 +httpSeparateURI +httpSetCookie +httpSetExpect +httpSetField +httpSetLength +httpStatus +httpTrace +httpUpdate +httpWait +httpWrite +httpWrite2 +ippAddBoolean +ippAddBooleans +ippAddCollection +ippAddCollections +ippAddDate +ippAddInteger +ippAddIntegers +ippAddOctetString +ippAddRange +ippAddRanges +ippAddResolution +ippAddResolutions +ippAddSeparator +ippAddString +ippAddStrings +ippDateToTime +ippDelete +ippDeleteAttribute +ippErrorString +ippErrorValue +ippFindAttribute +ippFindNextAttribute +ippLength +ippNew +ippNewRequest +ippOpString +ippOpValue +ippPort +ippRead +ippReadFile +ippReadIO +ippSetPort +ippTimeToDate +ippWrite +ippWriteFile +ippWriteIO +ppdClose +ppdCollect +ppdCollect2 +ppdConflicts +ppdEmit +ppdEmitAfterOrder +ppdEmitFd +ppdEmitJCL +ppdEmitJCLEnd +ppdEmitString +ppdErrorString +ppdFindAttr +ppdFindChoice +ppdFindCustomOption +ppdFindCustomParam +ppdFindMarkedChoice +ppdFindNextAttr +ppdFindOption +ppdFirstCustomParam +ppdFirstOption +ppdIsMarked +ppdLastError +ppdLocalize +ppdMarkDefaults +ppdMarkOption +ppdNextCustomParam +ppdNextOption +ppdOpen +ppdOpen2 +ppdOpenFd +ppdOpenFile +ppdPageLength +ppdPageSize +ppdPageWidth +ppdSetConformance diff --git a/cups/libcups_s.exp b/cups/libcups_s.exp new file mode 100644 index 0000000000..718cc07149 --- /dev/null +++ b/cups/libcups_s.exp @@ -0,0 +1,80 @@ +_cups_debug_fd +_cupsCharmapFlush +_cupsCharmapFree +_cupsCharmapGet +_cupsEncodingName +_cupsGetPassword +_cupsGlobals +_cupsLangPrintError +_cupsLangPrintf +_cupsLangPuts +_cupsLangString +_cupsMD5Append +_cupsMD5Finish +_cupsMD5Init +_cupsMessageFree +_cupsMessageLoad +_cupsMessageLookup +_cupsSetError +_cupsSetLocale +_cupsSNMPClose +_cupsSNMPCopyOID +_cupsSNMPDefaultCommunity +_cupsSNMPIsOID +_cupsSNMPIsOIDPrefixed +_cupsSNMPOIDToString +_cupsSNMPOpen +_cupsSNMPRead +_cupsSNMPSetDebug +_cupsSNMPStringToOID +_cupsSNMPWalk +_cupsSNMPWrite +_cupsStrAlloc +_cupsStrFlush +_cupsStrFormatd +_cupsStrFree +_cupsStrRetain +_cupsStrScand +_cupsStrStatistics +_cups_getifaddrs +_cups_freeifaddrs +_cups_strcpy +_cups_strlcat +_cups_strlcpy +_httpAddrPort +_httpBIOMethods +_httpCreate +_httpEncodeURI +_httpResolveURI +_httpWait +_ippAddAttr +_ippFreeAttr +_ppdFreeLanguages +_ppdGet1284Values +_ppdGetEncoding +_ppdGetLanguages +_ppdHashName +_ppdLocalizedAttr +_ppdNormalizeMakeAndModel +_ppdParseOptions +_pwgCreateWithFile +_pwgDestroy +_pwgWriteFile +_pwgGenerateSize +_pwgInitSize +_pwgMediaForLegacy +_pwgMediaForPPD +_pwgMediaForPWG +_pwgMediaForSize +_pwgCreateWithPPD +_pwgGetBin +_pwgGetInputSlot +_pwgGetMediaType +_pwgGetOutputBin +_pwgGetPageSize +_pwgGetSize +_pwgGetSource +_pwgGetType +_pwgInputSlotForSource +_pwgMediaTypeForType +_pwgPageSizeForMedia diff --git a/cups/localize.c b/cups/localize.c new file mode 100644 index 0000000000..f31cd72b77 --- /dev/null +++ b/cups/localize.c @@ -0,0 +1,781 @@ +/* + * "$Id$" + * + * PPD localization routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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: + * + * ppdLocalize() - Localize the PPD file to the current locale. + * ppdLocalizeAttr() - Localize an attribute. + * ppdLocalizeIPPReason() - Get the localized version of a cupsIPPReason + * attribute. + * ppdLocalizeMarkerName() - Get the localized version of a marker-names + * attribute value. + * _ppdFreeLanguages() - Free an array of languages from _ppdGetLanguages. + * _ppdGetLanguages() - Get an array of languages from a PPD file. + * _ppdHashName() - Generate a hash value for a device or profile + * name. + * _ppdLocalizedAttr() - Find a localized attribute. + * ppd_ll_CC() - Get the current locale names. + */ + +/* + * Include necessary headers. + */ + +#include "globals.h" +#include "ppd-private.h" +#include "debug.h" + + +/* + * Local functions... + */ + +static cups_lang_t *ppd_ll_CC(char *ll_CC, int ll_CC_size); + + +/* + * 'ppdLocalize()' - Localize the PPD file to the current locale. + * + * All groups, options, and choices are localized, as are ICC profile + * descriptions, printer presets, and custom option parameters. Each + * localized string uses the UTF-8 character encoding. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +ppdLocalize(ppd_file_t *ppd) /* I - PPD file */ +{ + int i, j, k; /* Looping vars */ + ppd_group_t *group; /* Current group */ + ppd_option_t *option; /* Current option */ + ppd_choice_t *choice; /* Current choice */ + ppd_coption_t *coption; /* Current custom option */ + ppd_cparam_t *cparam; /* Current custom parameter */ + ppd_attr_t *attr, /* Current attribute */ + *locattr; /* Localized attribute */ + char ckeyword[PPD_MAX_NAME], /* Custom keyword */ + ll_CC[6]; /* Language + country locale */ + + + /* + * Range check input... + */ + + DEBUG_printf(("ppdLocalize(ppd=%p)", ppd)); + + if (!ppd) + return (-1); + + /* + * Get the default language... + */ + + ppd_ll_CC(ll_CC, sizeof(ll_CC)); + + /* + * Now lookup all of the groups, options, choices, etc. + */ + + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + { + if ((locattr = _ppdLocalizedAttr(ppd, "Translation", group->name, + ll_CC)) != NULL) + strlcpy(group->text, locattr->text, sizeof(group->text)); + + for (j = group->num_options, option = group->options; j > 0; j --, option ++) + { + if ((locattr = _ppdLocalizedAttr(ppd, "Translation", option->keyword, + ll_CC)) != NULL) + strlcpy(option->text, locattr->text, sizeof(option->text)); + + for (k = option->num_choices, choice = option->choices; + k > 0; + k --, choice ++) + { + if (strcmp(choice->choice, "Custom") || + !ppdFindCustomOption(ppd, option->keyword)) + locattr = _ppdLocalizedAttr(ppd, option->keyword, choice->choice, + ll_CC); + else + { + snprintf(ckeyword, sizeof(ckeyword), "Custom%s", option->keyword); + + locattr = _ppdLocalizedAttr(ppd, ckeyword, "True", ll_CC); + } + + if (locattr) + strlcpy(choice->text, locattr->text, sizeof(choice->text)); + } + } + } + + /* + * Translate any custom parameters... + */ + + for (coption = (ppd_coption_t *)cupsArrayFirst(ppd->coptions); + coption; + coption = (ppd_coption_t *)cupsArrayNext(ppd->coptions)) + { + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + { + snprintf(ckeyword, sizeof(ckeyword), "ParamCustom%s", coption->keyword); + + if ((locattr = _ppdLocalizedAttr(ppd, ckeyword, cparam->name, + ll_CC)) != NULL) + strlcpy(cparam->text, locattr->text, sizeof(cparam->text)); + } + } + + /* + * Translate ICC profile names... + */ + + if ((attr = ppdFindAttr(ppd, "APCustomColorMatchingName", NULL)) != NULL) + { + if ((locattr = _ppdLocalizedAttr(ppd, "APCustomColorMatchingName", + attr->spec, ll_CC)) != NULL) + strlcpy(attr->text, locattr->text, sizeof(attr->text)); + } + + for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL)) + { + cupsArraySave(ppd->sorted_attrs); + + if ((locattr = _ppdLocalizedAttr(ppd, "cupsICCProfile", attr->spec, + ll_CC)) != NULL) + strlcpy(attr->text, locattr->text, sizeof(attr->text)); + + cupsArrayRestore(ppd->sorted_attrs); + } + + /* + * Translate printer presets... + */ + + for (attr = ppdFindAttr(ppd, "APPrinterPreset", NULL); + attr; + attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) + { + cupsArraySave(ppd->sorted_attrs); + + if ((locattr = _ppdLocalizedAttr(ppd, "APPrinterPreset", attr->spec, + ll_CC)) != NULL) + strlcpy(attr->text, locattr->text, sizeof(attr->text)); + + cupsArrayRestore(ppd->sorted_attrs); + } + + return (0); +} + + +/* + * 'ppdLocalizeAttr()' - Localize an attribute. + * + * This function uses the current locale to find the localized attribute for + * the given main and option keywords. If no localized version of the + * attribute exists for the current locale, the unlocalized version is returned. + */ + +ppd_attr_t * /* O - Localized attribute or @code NULL@ if none exists */ +ppdLocalizeAttr(ppd_file_t *ppd, /* I - PPD file */ + const char *keyword, /* I - Main keyword */ + const char *spec) /* I - Option keyword or @code NULL@ for none */ +{ + ppd_attr_t *locattr; /* Localized attribute */ + char ll_CC[6]; /* Language + country locale */ + + + /* + * Get the default language... + */ + + ppd_ll_CC(ll_CC, sizeof(ll_CC)); + + /* + * Find the localized attribute... + */ + + if (spec) + locattr = _ppdLocalizedAttr(ppd, keyword, spec, ll_CC); + else + locattr = _ppdLocalizedAttr(ppd, "Translation", keyword, ll_CC); + + if (!locattr) + locattr = ppdFindAttr(ppd, keyword, spec); + + return (locattr); +} + + +/* + * 'ppdLocalizeIPPReason()' - Get the localized version of a cupsIPPReason + * attribute. + * + * This function uses the current locale to find the corresponding reason + * text or URI from the attribute value. If "scheme" is NULL or "text", + * the returned value contains human-readable (UTF-8) text from the translation + * string or attribute value. Otherwise the corresponding URI is returned. + * + * If no value of the requested scheme can be found, NULL is returned. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +const char * /* O - Value or NULL if not found */ +ppdLocalizeIPPReason( + ppd_file_t *ppd, /* I - PPD file */ + const char *reason, /* I - IPP reason keyword to look up */ + const char *scheme, /* I - URI scheme or NULL for text */ + char *buffer, /* I - Value buffer */ + size_t bufsize) /* I - Size of value buffer */ +{ + cups_lang_t *lang; /* Current language */ + ppd_attr_t *locattr; /* Localized attribute */ + char ll_CC[6], /* Language + country locale */ + *bufptr, /* Pointer into buffer */ + *bufend, /* Pointer to end of buffer */ + *valptr; /* Pointer into value */ + int ch, /* Hex-encoded character */ + schemelen; /* Length of scheme name */ + + + /* + * Range check input... + */ + + if (buffer) + *buffer = '\0'; + + if (!ppd || !reason || (scheme && !*scheme) || + !buffer || bufsize < PPD_MAX_TEXT) + return (NULL); + + /* + * Get the default language... + */ + + lang = ppd_ll_CC(ll_CC, sizeof(ll_CC)); + + /* + * Find the localized attribute... + */ + + if ((locattr = _ppdLocalizedAttr(ppd, "cupsIPPReason", reason, + ll_CC)) == NULL) + locattr = ppdFindAttr(ppd, "cupsIPPReason", reason); + + if (!locattr) + { + if (lang && (!scheme || !strcmp(scheme, "text"))) + { + /* + * Try to localize a standard printer-state-reason keyword... + */ + + const char *message = NULL; /* Localized message */ + + + if (!strncmp(reason, "media-needed", 12)) + message = _("Media tray needs to be filled."); + else if (!strncmp(reason, "media-jam", 9)) + message = _("Media jam!"); + else if (!strncmp(reason, "offline", 7) || + !strncmp(reason, "shutdown", 8)) + message = _("Printer offline."); + else if (!strncmp(reason, "toner-low", 9)) + message = _("Toner low."); + else if (!strncmp(reason, "toner-empty", 11)) + message = _("Out of toner!"); + else if (!strncmp(reason, "cover-open", 10)) + message = _("Cover open."); + else if (!strncmp(reason, "interlock-open", 14)) + message = _("Interlock open."); + else if (!strncmp(reason, "door-open", 9)) + message = _("Door open."); + else if (!strncmp(reason, "input-tray-missing", 18)) + message = _("Media tray missing!"); + else if (!strncmp(reason, "media-low", 9)) + message = _("Media tray almost empty."); + else if (!strncmp(reason, "media-empty", 11)) + message = _("Media tray empty!"); + else if (!strncmp(reason, "output-tray-missing", 19)) + message = _("Output tray missing!"); + else if (!strncmp(reason, "output-area-almost-full", 23)) + message = _("Output bin almost full."); + else if (!strncmp(reason, "output-area-full", 16)) + message = _("Output bin full!"); + else if (!strncmp(reason, "marker-supply-low", 17)) + message = _("Ink/toner almost empty."); + else if (!strncmp(reason, "marker-supply-empty", 19)) + message = _("Ink/toner empty!"); + else if (!strncmp(reason, "marker-waste-almost-full", 24)) + message = _("Ink/toner waste bin almost full."); + else if (!strncmp(reason, "marker-waste-full", 17)) + message = _("Ink/toner waste bin full!"); + else if (!strncmp(reason, "fuser-over-temp", 15)) + message = _("Fuser temperature high!"); + else if (!strncmp(reason, "fuser-under-temp", 16)) + message = _("Fuser temperature low!"); + else if (!strncmp(reason, "opc-near-eol", 12)) + message = _("OPC almost at end-of-life."); + else if (!strncmp(reason, "opc-life-over", 13)) + message = _("OPC at end-of-life!"); + else if (!strncmp(reason, "developer-low", 13)) + message = _("Developer almost empty."); + else if (!strncmp(reason, "developer-empty", 15)) + message = _("Developer empty!"); + + if (message) + { + strlcpy(buffer, _cupsLangString(lang, message), bufsize); + return (buffer); + } + } + + return (NULL); + } + + /* + * Now find the value we need... + */ + + bufend = buffer + bufsize - 1; + + if (!scheme || !strcmp(scheme, "text")) + { + /* + * Copy a text value (either the translation text or text:... URIs from + * the value... + */ + + strlcpy(buffer, locattr->text, bufsize); + + for (valptr = locattr->value, bufptr = buffer; *valptr && bufptr < bufend;) + { + if (!strncmp(valptr, "text:", 5)) + { + /* + * Decode text: URI and add to the buffer... + */ + + valptr += 5; + + while (*valptr && !_cups_isspace(*valptr) && bufptr < bufend) + { + if (*valptr == '%' && isxdigit(valptr[1] & 255) && + isxdigit(valptr[2] & 255)) + { + /* + * Pull a hex-encoded character from the URI... + */ + + valptr ++; + + if (isdigit(*valptr & 255)) + ch = (*valptr - '0') << 4; + else + ch = (tolower(*valptr) - 'a' + 10) << 4; + valptr ++; + + if (isdigit(*valptr & 255)) + *bufptr++ = ch | (*valptr - '0'); + else + *bufptr++ = ch | (tolower(*valptr) - 'a' + 10); + valptr ++; + } + else if (*valptr == '+') + { + *bufptr++ = ' '; + valptr ++; + } + else + *bufptr++ = *valptr++; + } + } + else + { + /* + * Skip this URI... + */ + + while (*valptr && !_cups_isspace(*valptr)) + valptr++; + } + + /* + * Skip whitespace... + */ + + while (_cups_isspace(*valptr)) + valptr ++; + } + + if (bufptr > buffer) + *bufptr = '\0'; + + return (buffer); + } + else + { + /* + * Copy a URI... + */ + + schemelen = strlen(scheme); + if (scheme[schemelen - 1] == ':') /* Force scheme to be just the name */ + schemelen --; + + for (valptr = locattr->value, bufptr = buffer; *valptr && bufptr < bufend;) + { + if ((!strncmp(valptr, scheme, schemelen) && valptr[schemelen] == ':') || + (*valptr == '/' && !strcmp(scheme, "file"))) + { + /* + * Copy URI... + */ + + while (*valptr && !_cups_isspace(*valptr) && bufptr < bufend) + *bufptr++ = *valptr++; + + *bufptr = '\0'; + + return (buffer); + } + else + { + /* + * Skip this URI... + */ + + while (*valptr && !_cups_isspace(*valptr)) + valptr++; + } + + /* + * Skip whitespace... + */ + + while (_cups_isspace(*valptr)) + valptr ++; + } + + return (NULL); + } +} + + +/* + * 'ppdLocalizeMarkerName()' - Get the localized version of a marker-names + * attribute value. + * + * This function uses the current locale to find the corresponding name + * text from the attribute value. If no localized text for the requested + * name can be found, @code NULL@ is returned. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +const char * /* O - Value or @code NULL@ if not found */ +ppdLocalizeMarkerName( + ppd_file_t *ppd, /* I - PPD file */ + const char *name) /* I - Marker name to look up */ +{ + ppd_attr_t *locattr; /* Localized attribute */ + char ll_CC[6]; /* Language + country locale */ + + + /* + * Range check input... + */ + + if (!ppd || !name) + return (NULL); + + /* + * Get the default language... + */ + + ppd_ll_CC(ll_CC, sizeof(ll_CC)); + + /* + * Find the localized attribute... + */ + + if ((locattr = _ppdLocalizedAttr(ppd, "cupsMarkerName", name, + ll_CC)) == NULL) + locattr = ppdFindAttr(ppd, "cupsMarkerName", name); + + return (locattr ? locattr->text : NULL); +} + + +/* + * '_ppdFreeLanguages()' - Free an array of languages from _ppdGetLanguages. + */ + +void +_ppdFreeLanguages( + cups_array_t *languages) /* I - Languages array */ +{ + char *language; /* Current language */ + + + for (language = (char *)cupsArrayFirst(languages); + language; + language = (char *)cupsArrayNext(languages)) + free(language); + + cupsArrayDelete(languages); +} + + +/* + * '_ppdGetLanguages()' - Get an array of languages from a PPD file. + */ + +cups_array_t * /* O - Languages array */ +_ppdGetLanguages(ppd_file_t *ppd) /* I - PPD file */ +{ + cups_array_t *languages; /* Languages array */ + ppd_attr_t *attr; /* cupsLanguages attribute */ + char *value, /* Copy of attribute value */ + *start, /* Start of current language */ + *ptr; /* Pointer into languages */ + + + /* + * See if we have a cupsLanguages attribute... + */ + + if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) == NULL || !attr->value) + return (NULL); + + /* + * Yes, load the list... + */ + + if ((languages = cupsArrayNew((cups_array_func_t)strcmp, NULL)) == NULL) + return (NULL); + + if ((value = strdup(attr->value)) == NULL) + { + cupsArrayDelete(languages); + return (NULL); + } + + for (ptr = value; *ptr;) + { + /* + * Skip leading whitespace... + */ + + while (_cups_isspace(*ptr)) + ptr ++; + + if (!*ptr) + break; + + /* + * Find the end of this language name... + */ + + for (start = ptr; *ptr && !_cups_isspace(*ptr); ptr ++); + + if (*ptr) + *ptr++ = '\0'; + + if (!strcmp(start, "en")) + continue; + + cupsArrayAdd(languages, strdup(start)); + } + + /* + * Free the temporary string and return either an array with one or more + * values or a NULL pointer... + */ + + free(value); + + if (cupsArrayCount(languages) == 0) + { + cupsArrayDelete(languages); + return (NULL); + } + else + return (languages); +} + + +/* + * '_ppdHashName()' - Generate a hash value for a device or profile name. + * + * This function is primarily used on Mac OS X, but is generally accessible + * since cupstestppd needs to check for profile name collisions in PPD files... + */ + +unsigned /* O - Hash value */ +_ppdHashName(const char *name) /* I - Name to hash */ +{ + int mult; /* Multiplier */ + unsigned hash = 0; /* Hash value */ + + + for (mult = 1; *name && mult <= 128; mult ++, name ++) + hash += (*name & 255) * mult; + + return (hash); +} + + +/* + * '_ppdLocalizedAttr()' - Find a localized attribute. + */ + +ppd_attr_t * /* O - Localized attribute or NULL */ +_ppdLocalizedAttr(ppd_file_t *ppd, /* I - PPD file */ + const char *keyword, /* I - Main keyword */ + const char *spec, /* I - Option keyword */ + const char *ll_CC) /* I - Language + country locale */ +{ + char lkeyword[PPD_MAX_NAME]; /* Localization keyword */ + ppd_attr_t *attr; /* Current attribute */ + + + DEBUG_printf(("4_ppdLocalizedAttr(ppd=%p, keyword=\"%s\", spec=\"%s\", " + "ll_CC=\"%s\")", ppd, keyword, spec, ll_CC)); + + /* + * Look for Keyword.ll_CC, then Keyword.ll... + */ + + snprintf(lkeyword, sizeof(lkeyword), "%s.%s", ll_CC, keyword); + if ((attr = ppdFindAttr(ppd, lkeyword, spec)) == NULL) + { + snprintf(lkeyword, sizeof(lkeyword), "%2.2s.%s", ll_CC, keyword); + attr = ppdFindAttr(ppd, lkeyword, spec); + + if (!attr) + { + if (!strncmp(ll_CC, "ja", 2)) + { + /* + * Due to a bug in the CUPS DDK 1.1.0 ppdmerge program, Japanese + * PPD files were incorrectly assigned "jp" as the locale name + * instead of "ja". Support both the old (incorrect) and new + * locale names for Japanese... + */ + + snprintf(lkeyword, sizeof(lkeyword), "jp.%s", keyword); + attr = ppdFindAttr(ppd, lkeyword, spec); + } + else if (!strncmp(ll_CC, "no", 2)) + { + /* + * Norway has two languages, "Bokmal" (the primary one) + * and "Nynorsk" (new Norwegian); we map "no" to "nb" here as + * recommended by the locale folks... + */ + + snprintf(lkeyword, sizeof(lkeyword), "nb.%s", keyword); + attr = ppdFindAttr(ppd, lkeyword, spec); + } + } + } + +#ifdef DEBUG + if (attr) + DEBUG_printf(("5_ppdLocalizedAttr: *%s %s/%s: \"%s\"\n", attr->name, + attr->spec, attr->text, attr->value ? attr->value : "")); + else + DEBUG_puts("5_ppdLocalizedAttr: NOT FOUND"); +#endif /* DEBUG */ + + return (attr); +} + + +/* + * 'ppd_ll_CC()' - Get the current locale names. + */ + +static cups_lang_t * /* O - Current language */ +ppd_ll_CC(char *ll_CC, /* O - Country-specific locale name */ + int ll_CC_size) /* I - Size of country-specific name */ +{ + cups_lang_t *lang; /* Current language */ + + + /* + * Get the current locale... + */ + + if ((lang = cupsLangDefault()) == NULL) + { + strlcpy(ll_CC, "en_US", ll_CC_size); + return (NULL); + } + + /* + * Copy the locale name... + */ + + strlcpy(ll_CC, lang->language, ll_CC_size); + + if (strlen(ll_CC) == 2) + { + /* + * Map "ll" to primary/origin country locales to have the best + * chance of finding a match... + */ + + if (!strcmp(ll_CC, "cs")) + strlcpy(ll_CC, "cs_CZ", ll_CC_size); + else if (!strcmp(ll_CC, "en")) + strlcpy(ll_CC, "en_US", ll_CC_size); + else if (!strcmp(ll_CC, "ja")) + strlcpy(ll_CC, "ja_JP", ll_CC_size); + else if (!strcmp(ll_CC, "sv")) + strlcpy(ll_CC, "sv_SE", ll_CC_size); + else if (!strcmp(ll_CC, "zh")) /* Simplified Chinese */ + strlcpy(ll_CC, "zh_CN", ll_CC_size); + } + + DEBUG_printf(("8ppd_ll_CC: lang->language=\"%s\", ll_CC=\"%s\"...", + lang->language, ll_CC)); + return (lang); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/mark.c b/cups/mark.c new file mode 100644 index 0000000000..ad91ada9e3 --- /dev/null +++ b/cups/mark.c @@ -0,0 +1,1099 @@ +/* + * "$Id$" + * + * Option marking routines for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsMarkOptions() - Mark command-line options in a PPD file. + * 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 and return the number + * of conflicts. + * ppdFirstOption() - Return the first option in the PPD file. + * ppdNextOption() - Return the next option in the PPD file. + * _ppdParseOptions() - Parse options from a PPD file. + * ppd_debug_marked() - Output the marked array to stdout... + * ppd_defaults() - Set the defaults for this group and all sub-groups. + * ppd_mark_choices() - Mark one or more option choices from a string. + * ppd_mark_option() - Quickly mark an option without checking for + * conflicts. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include "string.h" +#include "debug.h" +#include "ppd-private.h" +#include "pwg-private.h" + + +/* + * Local functions... + */ + +#ifdef DEBUG +static void ppd_debug_marked(ppd_file_t *ppd, const char *title); +#else +# define ppd_debug_marked(ppd,title) +#endif /* DEBUG */ +static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g); +static void ppd_mark_choices(ppd_file_t *ppd, const char *s); +static void ppd_mark_option(ppd_file_t *ppd, const char *option, + const char *choice); + + +/* + * 'cupsMarkOptions()' - Mark command-line options in a PPD file. + * + * This function maps the IPP "finishings", "media", "mirror", + * "multiple-document-handling", "output-bin", "printer-resolution", and + * "sides" attributes to their corresponding PPD options and choices. + */ + +int /* O - 1 if conflicts exist, 0 otherwise */ +cupsMarkOptions( + ppd_file_t *ppd, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int i, j; /* Looping vars */ + char *ptr, /* Pointer into string */ + s[255]; /* Temporary string */ + const char *val, /* Pointer into value */ + *media, /* media option */ + *output_bin, /* output-bin option */ + *output_mode, /* output-mode option */ + *page_size, /* PageSize option */ + *ppd_keyword, /* PPD keyword */ + *print_quality, /* print-quality option */ + *sides; /* sides option */ + cups_option_t *optptr; /* Current option */ + ppd_attr_t *attr; /* PPD attribute */ + _pwg_t *pwg; /* PWG mapping data */ + + + /* + * Check arguments... + */ + + if (!ppd || num_options <= 0 || !options) + return (0); + + ppd_debug_marked(ppd, "Before..."); + + /* + * Do special handling for finishings, media, output-bin, output-mode, + * print-color-mode, print-quality, and PageSize... + */ + + media = cupsGetOption("media", num_options, options); + output_bin = cupsGetOption("output-bin", num_options, options); + output_mode = cupsGetOption("output-mode", num_options, options); + page_size = cupsGetOption("PageSize", num_options, options); + print_quality = cupsGetOption("print-quality", num_options, options); + sides = cupsGetOption("sides", num_options, options); + + if ((media || output_bin || output_mode || print_quality || sides) && + !ppd->pwg) + { + /* + * Load PWG mapping data as needed... + */ + + ppd->pwg = _pwgCreateWithPPD(ppd); + } + + pwg = (_pwg_t *)ppd->pwg; + + if (media) + { + /* + * Loop through the option string, separating it at commas and marking each + * individual option as long as the corresponding PPD option (PageSize, + * InputSlot, etc.) is not also set. + * + * For PageSize, we also check for an empty option value since some versions + * of MacOS X use it to specify auto-selection of the media based solely on + * the size. + */ + + for (val = media; *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 (!page_size || !page_size[0]) + { + if (!strncasecmp(s, "Custom.", 7) || ppdPageSize(ppd, s)) + ppd_mark_option(ppd, "PageSize", s); + else if ((ppd_keyword = _pwgGetPageSize(pwg, NULL, s, NULL)) != NULL) + ppd_mark_option(ppd, "PageSize", ppd_keyword); + } + + if (pwg && pwg->source_option && + !cupsGetOption(pwg->source_option, num_options, options) && + (ppd_keyword = _pwgGetInputSlot(pwg, NULL, s)) != NULL) + ppd_mark_option(ppd, pwg->source_option, ppd_keyword); + + if (!cupsGetOption("MediaType", num_options, options) && + (ppd_keyword = _pwgGetMediaType(pwg, NULL, s)) != NULL) + ppd_mark_option(ppd, "MediaType", ppd_keyword); + } + } + + if (pwg) + { + if (!cupsGetOption("com.apple.print.DocumentTicket.PMSpoolFormat", + num_options, options) && + !cupsGetOption("APPrinterPreset", num_options, options) && + (output_mode || print_quality)) + { + /* + * Map output-mode and print-quality to a preset... + */ + + _pwg_output_mode_t pwg_om; /* output-mode index */ + _pwg_print_quality_t pwg_pq; /* print-quality index */ + cups_option_t *preset;/* Current preset option */ + + if (output_mode && !strcmp(output_mode, "monochrome")) + pwg_om = _PWG_OUTPUT_MODE_MONOCHROME; + else + pwg_om = _PWG_OUTPUT_MODE_COLOR; + + if (print_quality) + { + pwg_pq = atoi(print_quality) - IPP_QUALITY_DRAFT; + if (pwg_pq < _PWG_PRINT_QUALITY_DRAFT) + pwg_pq = _PWG_PRINT_QUALITY_DRAFT; + else if (pwg_pq > _PWG_PRINT_QUALITY_HIGH) + pwg_pq = _PWG_PRINT_QUALITY_HIGH; + } + else + pwg_pq = _PWG_PRINT_QUALITY_NORMAL; + + if (pwg->num_presets[pwg_om][pwg_pq] == 0) + { + /* + * Try to find a preset that works so that we maximize the chances of us + * getting a good print using IPP attributes. + */ + + if (pwg->num_presets[pwg_om][_PWG_PRINT_QUALITY_NORMAL] > 0) + pwg_pq = _PWG_PRINT_QUALITY_NORMAL; + else if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_pq] > 0) + pwg_om = _PWG_OUTPUT_MODE_COLOR; + else + { + pwg_pq = _PWG_PRINT_QUALITY_NORMAL; + pwg_om = _PWG_OUTPUT_MODE_COLOR; + } + } + + if (pwg->num_presets[pwg_om][pwg_pq] > 0) + { + /* + * Copy the preset options as long as the corresponding names are not + * already defined in the IPP request... + */ + + for (i = pwg->num_presets[pwg_om][pwg_pq], + preset = pwg->presets[pwg_om][pwg_pq]; + i > 0; + i --, preset ++) + { + if (!cupsGetOption(preset->name, num_options, options)) + ppd_mark_option(ppd, preset->name, preset->value); + } + } + } + + if (output_bin && !cupsGetOption("OutputBin", num_options, options) && + (ppd_keyword = _pwgGetOutputBin(pwg, output_bin)) != NULL) + { + /* + * Map output-bin to OutputBin... + */ + + ppd_mark_option(ppd, "OutputBin", ppd_keyword); + } + + if (sides && pwg->sides_option && + !cupsGetOption(pwg->sides_option, num_options, options)) + { + /* + * Map sides to duplex option... + */ + + if (!strcmp(sides, "one-sided")) + ppd_mark_option(ppd, pwg->sides_option, pwg->sides_1sided); + else if (!strcmp(sides, "two-sided-long-edge")) + ppd_mark_option(ppd, pwg->sides_option, pwg->sides_2sided_long); + else if (!strcmp(sides, "two-sided-short-edge")) + ppd_mark_option(ppd, pwg->sides_option, pwg->sides_2sided_short); + } + } + + /* + * Mark other options... + */ + + for (i = num_options, optptr = options; i > 0; i --, optptr ++) + if (!strcasecmp(optptr->name, "media") || + !strcasecmp(optptr->name, "output-bin") || + !strcasecmp(optptr->name, "output-mode") || + !strcasecmp(optptr->name, "print-quality") || + !strcasecmp(optptr->name, "sides")) + continue; + else if (!strcasecmp(optptr->name, "resolution") || + !strcasecmp(optptr->name, "printer-resolution")) + { + ppd_mark_option(ppd, "Resolution", optptr->value); + ppd_mark_option(ppd, "SetResolution", optptr->value); + /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */ + ppd_mark_option(ppd, "JCLResolution", optptr->value); + /* HP */ + ppd_mark_option(ppd, "CNRes_PGP", optptr->value); + /* Canon */ + } + else if (!strcasecmp(optptr->name, "multiple-document-handling")) + { + if (!cupsGetOption("Collate", num_options, options) && + ppdFindOption(ppd, "Collate")) + { + if (strcasecmp(optptr->value, "separate-documents-uncollated-copies")) + ppd_mark_option(ppd, "Collate", "True"); + else + ppd_mark_option(ppd, "Collate", "False"); + } + } + else if (!strcasecmp(optptr->name, "finishings")) + { + /* + * Lookup cupsIPPFinishings attributes for each value... + */ + + for (ptr = optptr->value; *ptr;) + { + /* + * Get the next finishings number... + */ + + if (!isdigit(*ptr & 255)) + break; + + if ((j = strtol(ptr, &ptr, 10)) < 3) + break; + + /* + * Skip separator as needed... + */ + + if (*ptr == ',') + ptr ++; + + /* + * Look it up in the PPD file... + */ + + sprintf(s, "%d", j); + + if ((attr = ppdFindAttr(ppd, "cupsIPPFinishings", s)) == NULL) + continue; + + /* + * Apply "*Option Choice" settings from the attribute value... + */ + + ppd_mark_choices(ppd, attr->value); + } + } + else if (!strcasecmp(optptr->name, "APPrinterPreset")) + { + /* + * Lookup APPrinterPreset value... + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterPreset", optptr->value)) != NULL) + { + /* + * Apply "*Option Choice" settings from the attribute value... + */ + + ppd_mark_choices(ppd, attr->value); + } + } + else if (!strcasecmp(optptr->name, "mirror")) + ppd_mark_option(ppd, "MirrorPrint", optptr->value); + else + ppd_mark_option(ppd, optptr->name, optptr->value); + + ppd_debug_marked(ppd, "After..."); + + return (ppdConflicts(ppd) > 0); +} + + +/* + * 'ppdFindChoice()' - Return a pointer to an option choice. + */ + +ppd_choice_t * /* O - Choice pointer or @code 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 || !choice) + return (NULL); + + if (choice[0] == '{' || !strncasecmp(choice, "Custom.", 7)) + choice = "Custom"; + + for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) + if (!strcasecmp(c->choice, choice)) + return (c); + + return (NULL); +} + + +/* + * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option. + */ + +ppd_choice_t * /* O - Pointer to choice or @code NULL@ */ +ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */ + const char *option) /* I - Keyword/option name */ +{ + ppd_choice_t key, /* Search key for choice */ + *marked; /* Marked choice */ + + + DEBUG_printf(("2ppdFindMarkedChoice(ppd=%p, option=\"%s\")", ppd, option)); + + if ((key.option = ppdFindOption(ppd, option)) == NULL) + { + DEBUG_puts("3ppdFindMarkedChoice: Option not found, returning NULL"); + return (NULL); + } + + marked = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key); + + DEBUG_printf(("3ppdFindMarkedChoice: Returning %p(%s)...", marked, + marked ? marked->choice : "NULL")); + + return (marked); +} + + +/* + * 'ppdFindOption()' - Return a pointer to the specified option. + */ + +ppd_option_t * /* O - Pointer to option or @code NULL@ */ +ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */ + const char *option) /* I - Option/Keyword name */ +{ + /* + * Range check input... + */ + + if (!ppd || !option) + return (NULL); + + if (ppd->options) + { + /* + * Search in the array... + */ + + ppd_option_t key; /* Option search key */ + + + strlcpy(key.keyword, option, sizeof(key.keyword)); + + return ((ppd_option_t *)cupsArrayFind(ppd->options, &key)); + } + else + { + /* + * Search in each group... + */ + + int i, j; /* Looping vars */ + ppd_group_t *group; /* Current group */ + ppd_option_t *optptr; /* Current option */ + + + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + for (j = group->num_options, optptr = group->options; + j > 0; + j --, optptr ++) + if (!strcasecmp(optptr->keyword, option)) + return (optptr); + + 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_choice_t key, /* Search key */ + *c; /* Choice pointer */ + + + if (!ppd) + return (0); + + if ((key.option = ppdFindOption(ppd, option)) == NULL) + return (0); + + if ((c = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) == NULL) + return (0); + + return (!strcmp(c->choice, choice)); +} + + +/* + * '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 */ + ppd_choice_t *c; /* Current choice */ + + + if (!ppd) + return; + + /* + * Clean out the marked array... + */ + + for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); + c; + c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) + { + cupsArrayRemove(ppd->marked, c); + c->marked = 0; + } + + /* + * Then repopulate it with the defaults... + */ + + for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) + ppd_defaults(ppd, g); +} + + +/* + * 'ppdMarkOption()' - Mark an option in a PPD file and return the number of + * conflicts. + */ + +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 */ +{ + DEBUG_printf(("ppdMarkOption(ppd=%p, option=\"%s\", choice=\"%s\")", + ppd, option, choice)); + + /* + * Range check input... + */ + + if (!ppd || !option || !choice) + return (0); + + /* + * Mark the option... + */ + + ppd_mark_option(ppd, option, choice); + + /* + * Return the number of conflicts... + */ + + return (ppdConflicts(ppd)); +} + + +/* + * 'ppdFirstOption()' - Return the first option in the PPD file. + * + * Options are returned from all groups in ascending alphanumeric order. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_option_t * /* O - First option or @code NULL@ */ +ppdFirstOption(ppd_file_t *ppd) /* I - PPD file */ +{ + if (!ppd) + return (NULL); + else + return ((ppd_option_t *)cupsArrayFirst(ppd->options)); +} + + +/* + * 'ppdNextOption()' - Return the next option in the PPD file. + * + * Options are returned from all groups in ascending alphanumeric order. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_option_t * /* O - Next option or @code NULL@ */ +ppdNextOption(ppd_file_t *ppd) /* I - PPD file */ +{ + if (!ppd) + return (NULL); + else + return ((ppd_option_t *)cupsArrayNext(ppd->options)); +} + + +/* + * '_ppdParseOptions()' - Parse options from a PPD file. + * + * This function looks for strings of the form: + * + * *option choice ... *optionN choiceN + * property value ... propertyN valueN + * + * It stops when it finds a string that doesn't match this format. + */ + +int /* O - Number of options */ +_ppdParseOptions( + const char *s, /* I - String to parse */ + int num_options, /* I - Number of options */ + cups_option_t **options, /* IO - Options */ + _ppd_parse_t which) /* I - What to parse */ +{ + char option[PPD_MAX_NAME * 2 + 1], /* Current option/property */ + choice[PPD_MAX_NAME], /* Current choice/value */ + *ptr; /* Pointer into option or choice */ + + + if (!s) + return (num_options); + + /* + * Read all of the "*Option Choice" and "property value" pairs from the + * string, add them to an options array as we go... + */ + + while (*s) + { + /* + * Skip leading whitespace... + */ + + while (_cups_isspace(*s)) + s ++; + + /* + * Get the option/property name... + */ + + ptr = option; + while (*s && !_cups_isspace(*s) && ptr < (option + sizeof(option) - 1)) + *ptr++ = *s++; + + if (ptr == s || !_cups_isspace(*s)) + break; + + *ptr = '\0'; + + /* + * Get the choice... + */ + + while (_cups_isspace(*s)) + s ++; + + if (!*s) + break; + + ptr = choice; + while (*s && !_cups_isspace(*s) && ptr < (choice + sizeof(choice) - 1)) + *ptr++ = *s++; + + if (*s && !_cups_isspace(*s)) + break; + + *ptr = '\0'; + + /* + * Add it to the options array... + */ + + if (option[0] == '*' && which != _PPD_PARSE_PROPERTIES) + num_options = cupsAddOption(option + 1, choice, num_options, options); + else if (option[0] != '*' && which != _PPD_PARSE_OPTIONS) + num_options = cupsAddOption(option, choice, num_options, options); + } + + return (num_options); +} + + +#ifdef DEBUG +/* + * 'ppd_debug_marked()' - Output the marked array to stdout... + */ + +static void +ppd_debug_marked(ppd_file_t *ppd, /* I - PPD file data */ + const char *title) /* I - Title for list */ +{ + ppd_choice_t *c; /* Current choice */ + + + DEBUG_printf(("2cupsMarkOptions: %s", title)); + + for (c = (ppd_choice_t *)cupsArrayFirst(ppd->marked); + c; + c = (ppd_choice_t *)cupsArrayNext(ppd->marked)) + DEBUG_printf(("2cupsMarkOptions: %s=%s", c->option->keyword, c->choice)); +} +#endif /* DEBUG */ + + +/* + * '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 */ + + + 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); +} + + +/* + * 'ppd_mark_choices()' - Mark one or more option choices from a string. + */ + +static void +ppd_mark_choices(ppd_file_t *ppd, /* I - PPD file */ + const char *s) /* I - "*Option Choice ..." string */ +{ + int i, /* Looping var */ + num_options; /* Number of options */ + cups_option_t *options, /* Options */ + *option; /* Current option */ + + + if (!s) + return; + + options = NULL; + num_options = _ppdParseOptions(s, 0, &options, 0); + + for (i = num_options, option = options; i > 0; i --, option ++) + ppd_mark_option(ppd, option->name, option->value); + + cupsFreeOptions(num_options, options); +} + + +/* + * 'ppd_mark_option()' - Quick mark an option without checking for conflicts. + */ + +static void +ppd_mark_option(ppd_file_t *ppd, /* I - PPD file */ + const char *option, /* I - Option name */ + const char *choice) /* I - Choice name */ +{ + int i, j; /* Looping vars */ + ppd_option_t *o; /* Option pointer */ + ppd_choice_t *c, /* Choice pointer */ + *oldc, /* Old choice pointer */ + key; /* Search key for choice */ + struct lconv *loc; /* Locale data */ + + + DEBUG_printf(("7ppd_mark_option(ppd=%p, option=\"%s\", choice=\"%s\")", + ppd, option, choice)); + + /* + * AP_D_InputSlot is the "default input slot" on MacOS X, and setting + * it clears the regular InputSlot choices... + */ + + if (!strcasecmp(option, "AP_D_InputSlot")) + { + cupsArraySave(ppd->options); + + if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + + cupsArrayRestore(ppd->options); + } + + /* + * Check for custom options... + */ + + cupsArraySave(ppd->options); + + o = ppdFindOption(ppd, option); + + cupsArrayRestore(ppd->options); + + if (!o) + return; + + loc = localeconv(); + + if (!strncasecmp(choice, "Custom.", 7)) + { + /* + * Handle a custom option... + */ + + if ((c = ppdFindChoice(o, "Custom")) == NULL) + return; + + if (!strcasecmp(option, "PageSize")) + { + /* + * Handle custom page sizes... + */ + + ppdPageSize(ppd, choice); + } + else + { + /* + * Handle other custom options... + */ + + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + char *units; /* Custom points units */ + + + if ((coption = ppdFindCustomOption(ppd, option)) != NULL) + { + if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL) + return; + + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_REAL : + cparam->current.custom_real = (float)_cupsStrScand(choice + 7, + NULL, loc); + break; + + case PPD_CUSTOM_POINTS : + cparam->current.custom_points = (float)_cupsStrScand(choice + 7, + &units, + loc); + + if (units) + { + if (!strcasecmp(units, "cm")) + cparam->current.custom_points *= 72.0f / 2.54f; + else if (!strcasecmp(units, "mm")) + cparam->current.custom_points *= 72.0f / 25.4f; + else if (!strcasecmp(units, "m")) + cparam->current.custom_points *= 72.0f / 0.0254f; + else if (!strcasecmp(units, "in")) + cparam->current.custom_points *= 72.0f; + else if (!strcasecmp(units, "ft")) + cparam->current.custom_points *= 12.0f * 72.0f; + } + break; + + case PPD_CUSTOM_INT : + cparam->current.custom_int = atoi(choice + 7); + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) + _cupsStrFree(cparam->current.custom_string); + + cparam->current.custom_string = _cupsStrAlloc(choice + 7); + break; + } + } + } + + /* + * Make sure that we keep the option marked below... + */ + + choice = "Custom"; + } + else if (choice[0] == '{') + { + /* + * Handle multi-value custom options... + */ + + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + char *units; /* Custom points units */ + int num_vals; /* Number of values */ + cups_option_t *vals, /* Values */ + *val; /* Value */ + + + if ((c = ppdFindChoice(o, "Custom")) == NULL) + return; + + if ((coption = ppdFindCustomOption(ppd, option)) != NULL) + { + num_vals = cupsParseOptions(choice, 0, &vals); + + for (i = 0, val = vals; i < num_vals; i ++, val ++) + { + if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL) + continue; + + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + case PPD_CUSTOM_INVCURVE : + case PPD_CUSTOM_REAL : + cparam->current.custom_real = (float)_cupsStrScand(val->value, + NULL, loc); + break; + + case PPD_CUSTOM_POINTS : + cparam->current.custom_points = (float)_cupsStrScand(val->value, + &units, + loc); + + if (units) + { + if (!strcasecmp(units, "cm")) + cparam->current.custom_points *= 72.0f / 2.54f; + else if (!strcasecmp(units, "mm")) + cparam->current.custom_points *= 72.0f / 25.4f; + else if (!strcasecmp(units, "m")) + cparam->current.custom_points *= 72.0f / 0.0254f; + else if (!strcasecmp(units, "in")) + cparam->current.custom_points *= 72.0f; + else if (!strcasecmp(units, "ft")) + cparam->current.custom_points *= 12.0f * 72.0f; + } + break; + + case PPD_CUSTOM_INT : + cparam->current.custom_int = atoi(val->value); + break; + + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + if (cparam->current.custom_string) + _cupsStrFree(cparam->current.custom_string); + + cparam->current.custom_string = _cupsStrRetain(val->value); + break; + } + } + + cupsFreeOptions(num_vals, vals); + } + } + else + { + for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) + if (!strcasecmp(c->choice, choice)) + break; + + if (!i) + return; + } + + /* + * Option found; mark it and then handle unmarking any other options. + */ + + if (o->ui != PPD_UI_PICKMANY) + { + /* + * Unmark all other choices... + */ + + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + + if (!strcasecmp(option, "PageSize") || !strcasecmp(option, "PageRegion")) + { + /* + * Mark current page size... + */ + + for (j = 0; j < ppd->num_sizes; j ++) + ppd->sizes[j].marked = !strcasecmp(ppd->sizes[j].name, + choice); + + /* + * Unmark the current PageSize or PageRegion setting, as + * appropriate... + */ + + cupsArraySave(ppd->options); + + if (!strcasecmp(option, "PageSize")) + { + if ((o = ppdFindOption(ppd, "PageRegion")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + } + else + { + if ((o = ppdFindOption(ppd, "PageSize")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + } + + cupsArrayRestore(ppd->options); + } + else if (!strcasecmp(option, "InputSlot")) + { + /* + * Unmark ManualFeed option... + */ + + cupsArraySave(ppd->options); + + if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + + cupsArrayRestore(ppd->options); + } + else if (!strcasecmp(option, "ManualFeed") && + !strcasecmp(choice, "True")) + { + /* + * Unmark InputSlot option... + */ + + cupsArraySave(ppd->options); + + if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) + { + key.option = o; + if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL) + { + oldc->marked = 0; + cupsArrayRemove(ppd->marked, oldc); + } + } + + cupsArrayRestore(ppd->options); + } + } + + c->marked = 1; + + cupsArrayAdd(ppd->marked, c); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/md5-apple.h b/cups/md5-apple.h new file mode 100644 index 0000000000..873026ee03 --- /dev/null +++ b/cups/md5-apple.h @@ -0,0 +1,30 @@ +/* + * "$Id$" + * + * MD5 MacOS X compatibility header for the Common UNIX Printing + * System (CUPS). + * + * This file just defines aliases to the (private) CUPS MD5 functions. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +void md5_init(_cups_md5_state_t *pms) + { _cupsMD5Init(pms); } +void md5_append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes) + { _cupsMD5Append(pms, data, nbytes); } +void md5_finish(_cups_md5_state_t *pms, unsigned char digest[16]) + { _cupsMD5Finish(pms, digest); } + +/* + * End of "$Id$". + */ diff --git a/cups/md5.c b/cups/md5.c new file mode 100644 index 0000000000..5fa8c6df7e --- /dev/null +++ b/cups/md5.c @@ -0,0 +1,344 @@ +/* + Copyright 2005 by Easy Software Products + + This source file implements private APIs and should not be used in + CUPS-based applications. + + 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 + . 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 __APPLE__ +# include "md5-apple.h" +#endif /* __APPLE__ */ + +#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 +_cups_md5_process(_cups_md5_state_t *pms, const unsigned char *data /*[64]*/) +{ + unsigned int + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + unsigned int 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.) + */ + unsigned int X[16]; + const unsigned char *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. + */ + unsigned int xbuf[16]; + const unsigned int *X; + + if (!((data - (const unsigned char *)0) & 3)) { + /* data are properly aligned */ + X = (const unsigned int *)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 +_cupsMD5Init(_cups_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 +_cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes) +{ + const unsigned char *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + unsigned int nbits = (unsigned int)(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; + _cups_md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + _cups_md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +_cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]) +{ + static const unsigned char 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 + }; + unsigned char data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (unsigned char)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + _cupsMD5Append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + _cupsMD5Append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/cups/md5.h b/cups/md5.h new file mode 100644 index 0000000000..3d39b8db4c --- /dev/null +++ b/cups/md5.h @@ -0,0 +1,74 @@ +/* + Copyright 2005 by Easy Software Products + + This header file defines private APIs and should not be used in + CUPS-based applications. + + 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 + . 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 . + 1999-05-03 lpd Original version. + */ + +#ifndef _CUPS_MD5_H_ +# define _CUPS_MD5_H_ + +/* Define the state of the MD5 Algorithm. */ +typedef struct _cups_md5_state_s { + unsigned int count[2]; /* message length in bits, lsw first */ + unsigned int abcd[4]; /* digest buffer */ + unsigned char buf[64]; /* accumulate block */ +} _cups_md5_state_t; + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* Initialize the algorithm. */ +void _cupsMD5Init(_cups_md5_state_t *pms); + +/* Append a string to the message. */ +void _cupsMD5Append(_cups_md5_state_t *pms, const unsigned char *data, int nbytes); + +/* Finish the message and return the digest. */ +void _cupsMD5Finish(_cups_md5_state_t *pms, unsigned char digest[16]); + +# ifdef __cplusplus +} /* end extern "C" */ +# endif /* __cplusplus */ +#endif /* !_CUPS_MD5_H_ */ diff --git a/cups/md5passwd.c b/cups/md5passwd.c new file mode 100644 index 0000000000..295d915d2f --- /dev/null +++ b/cups/md5passwd.c @@ -0,0 +1,142 @@ +/* + * "$Id$" + * + * MD5 password support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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-private.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 */ +{ + _cups_md5_state_t state; /* MD5 state info */ + unsigned char 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); + _cupsMD5Init(&state); + _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line)); + _cupsMD5Finish(&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 */ +{ + _cups_md5_state_t state; /* MD5 state info */ + unsigned char 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); + _cupsMD5Init(&state); + _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line)); + _cupsMD5Finish(&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); + + _cupsMD5Init(&state); + _cupsMD5Append(&state, (unsigned char *)line, (int)strlen(line)); + _cupsMD5Finish(&state, sum); + + return (httpMD5String(sum, md5)); +} + + +/* + * 'httpMD5String()' - Convert an MD5 sum to a character string. + */ + +char * /* O - MD5 sum in hex */ +httpMD5String(const unsigned char *sum, /* I - MD5 sum data */ + char md5[33]) + /* O - MD5 sum in hex */ +{ + int i; /* Looping var */ + char *md5ptr; /* Pointer into MD5 string */ + static const 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/notify.c b/cups/notify.c new file mode 100644 index 0000000000..689eeb1948 --- /dev/null +++ b/cups/notify.c @@ -0,0 +1,202 @@ +/* + * "$Id$" + * + * Notification routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2005-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsNotifySubject() - Return the subject for the given notification + * message. + * cupsNotifyText() - Return the text for the given notification message. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" + + +/* + * 'cupsNotifySubject()' - Return the subject for the given notification message. + * + * The returned string must be freed by the caller using @code free@. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Subject string or @code NULL@ */ +cupsNotifySubject(cups_lang_t *lang, /* I - Language data */ + ipp_t *event) /* I - Event data */ +{ + char buffer[1024]; /* Subject buffer */ + const char *prefix, /* Prefix on subject */ + *state; /* Printer/job state string */ + ipp_attribute_t *job_id, /* notify-job-id */ + *job_name, /* job-name */ + *job_state, /* job-state */ + *printer_name, /* printer-name */ + *printer_state, /* printer-state */ + *printer_uri, /* notify-printer-uri */ + *subscribed; /* notify-subscribed-event */ + + + /* + * Range check input... + */ + + if (!event || !lang) + return (NULL); + + /* + * Get the required attributes... + */ + + job_id = ippFindAttribute(event, "notify-job-id", IPP_TAG_INTEGER); + job_name = ippFindAttribute(event, "job-name", IPP_TAG_NAME); + job_state = ippFindAttribute(event, "job-state", IPP_TAG_ENUM); + printer_name = ippFindAttribute(event, "printer-name", IPP_TAG_NAME); + printer_state = ippFindAttribute(event, "printer-state", IPP_TAG_ENUM); + printer_uri = ippFindAttribute(event, "notify-printer-uri", IPP_TAG_URI); + subscribed = ippFindAttribute(event, "notify-subscribed-event", + IPP_TAG_KEYWORD); + + + if (job_id && printer_name && printer_uri && job_state) + { + /* + * Job event... + */ + + prefix = _cupsLangString(lang, _("Print Job:")); + + switch (job_state->values[0].integer) + { + case IPP_JOB_PENDING : + state = _cupsLangString(lang, _("pending")); + break; + case IPP_JOB_HELD : + state = _cupsLangString(lang, _("held")); + break; + case IPP_JOB_PROCESSING : + state = _cupsLangString(lang, _("processing")); + break; + case IPP_JOB_STOPPED : + state = _cupsLangString(lang, _("stopped")); + break; + case IPP_JOB_CANCELED : + state = _cupsLangString(lang, _("canceled")); + break; + case IPP_JOB_ABORTED : + state = _cupsLangString(lang, _("aborted")); + break; + case IPP_JOB_COMPLETED : + state = _cupsLangString(lang, _("completed")); + break; + default : + state = _cupsLangString(lang, _("unknown")); + break; + } + + snprintf(buffer, sizeof(buffer), "%s %s-%d (%s) %s", + prefix, + printer_name->values[0].string.text, + job_id->values[0].integer, + job_name ? job_name->values[0].string.text : + _cupsLangString(lang, _("untitled")), + state); + } + else if (printer_uri && printer_name && printer_state) + { + /* + * Printer event... + */ + + prefix = _cupsLangString(lang, _("Printer:")); + + switch (printer_state->values[0].integer) + { + case IPP_PRINTER_IDLE : + state = _cupsLangString(lang, _("idle")); + break; + case IPP_PRINTER_PROCESSING : + state = _cupsLangString(lang, _("processing")); + break; + case IPP_PRINTER_STOPPED : + state = _cupsLangString(lang, _("stopped")); + break; + default : + state = _cupsLangString(lang, _("unknown")); + break; + } + + snprintf(buffer, sizeof(buffer), "%s %s %s", + prefix, + printer_name->values[0].string.text, + state); + } + else if (subscribed) + strlcpy(buffer, subscribed->values[0].string.text, sizeof(buffer)); + else + return (NULL); + + /* + * Duplicate and return the subject string... + */ + + return (strdup(buffer)); +} + + +/* + * 'cupsNotifyText()' - Return the text for the given notification message. + * + * The returned string must be freed by the caller using @code free@. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +char * /* O - Message text or @code NULL@ */ +cupsNotifyText(cups_lang_t *lang, /* I - Language data */ + ipp_t *event) /* I - Event data */ +{ + ipp_attribute_t *notify_text; /* notify-text */ + + + /* + * Range check input... + */ + + if (!event || !lang) + return (NULL); + + /* + * Get the notify-text attribute from the server... + */ + + if ((notify_text = ippFindAttribute(event, "notify-text", + IPP_TAG_TEXT)) == NULL) + return (NULL); + + /* + * Return a copy... + */ + + return (strdup(notify_text->values[0].string.text)); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/options.c b/cups/options.c new file mode 100644 index 0000000000..2ebddab14a --- /dev/null +++ b/cups/options.c @@ -0,0 +1,629 @@ +/* + * "$Id$" + * + * Option routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * cupsRemoveOption() - Remove an option from an option array. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include +#include +#include "string.h" +#include "debug.h" + + +/* + * Local functions... + */ + +static int cups_compare_options(cups_option_t *a, cups_option_t *b); +static int cups_find_option(const char *name, int num_options, + cups_option_t *option, int prev, int *rdiff); + + +/* + * 'cupsAddOption()' - Add an option to an option array. + * + * New option arrays can be initialized simply by passing 0 for the + * "num_options" parameter. + */ + +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 */ +{ + cups_option_t *temp; /* Pointer to new option */ + int insert, /* Insertion point */ + diff; /* Result of search */ + + + DEBUG_printf(("2cupsAddOption(name=\"%s\", value=\"%s\", num_options=%d, " + "options=%p)", name, value, num_options, options)); + + if (!name || !name[0] || !value || !options || num_options < 0) + { + DEBUG_printf(("3cupsAddOption: Returning %d", num_options)); + return (num_options); + } + + /* + * Look for an existing option with the same name... + */ + + if (num_options == 0) + { + insert = 0; + diff = 1; + } + else + { + insert = cups_find_option(name, num_options, *options, num_options - 1, + &diff); + + if (diff > 0) + insert ++; + } + + if (diff) + { + /* + * No matching option name... + */ + + DEBUG_printf(("4cupsAddOption: New option inserted at index %d...", + insert)); + + 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) + { + DEBUG_puts("3cupsAddOption: Unable to expand option array, returning 0"); + return (0); + } + + *options = temp; + + if (insert < num_options) + { + DEBUG_printf(("4cupsAddOption: Shifting %d options...", + (int)(num_options - insert))); + memmove(temp + insert + 1, temp + insert, + (num_options - insert) * sizeof(cups_option_t)); + } + + temp += insert; + temp->name = _cupsStrAlloc(name); + num_options ++; + } + else + { + /* + * Match found; free the old value... + */ + + DEBUG_printf(("4cupsAddOption: Option already exists at index %d...", + insert)); + + temp = *options + insert; + _cupsStrFree(temp->value); + } + + temp->value = _cupsStrAlloc(value); + + DEBUG_printf(("3cupsAddOption: Returning %d", num_options)); + + 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 */ + + + DEBUG_printf(("cupsFreeOptions(num_options=%d, options=%p)", num_options, + options)); + + if (num_options <= 0 || !options) + return; + + for (i = 0; i < num_options; i ++) + { + _cupsStrFree(options[i].name); + _cupsStrFree(options[i].value); + } + + free(options); +} + + +/* + * 'cupsGetOption()' - Get an option value. + */ + +const char * /* O - Option value or @code NULL@ */ +cupsGetOption(const char *name, /* I - Name of option */ + int num_options,/* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int diff, /* Result of comparison */ + match; /* Matching index */ + + + DEBUG_printf(("2cupsGetOption(name=\"%s\", num_options=%d, options=%p)", + name, num_options, options)); + + if (!name || num_options <= 0 || !options) + { + DEBUG_puts("3cupsGetOption: Returning NULL"); + return (NULL); + } + + match = cups_find_option(name, num_options, options, -1, &diff); + + if (!diff) + { + DEBUG_printf(("3cupsGetOption: Returning \"%s\"", options[match].value)); + return (options[match].value); + } + + DEBUG_puts("3cupsGetOption: Returning NULL"); + return (NULL); +} + + +/* + * 'cupsParseOptions()' - Parse options from a command-line argument. + * + * This function converts space-delimited name/value pairs according + * to the PAPI text option ABNF specification. Collection values + * ("name={a=... b=... c=...}") are stored with the curley brackets + * intact - use @code cupsParseOptions@ on the value to extract the + * collection attributes. + */ + +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 */ + sep, /* Separator character */ + quote; /* Quote character */ + + + DEBUG_printf(("cupsParseOptions(arg=\"%s\", num_options=%d, options=%p)", + arg, num_options, options)); + + /* + * Range check input... + */ + + if (!arg) + { + DEBUG_printf(("1cupsParseOptions: Returning %d", num_options)); + return (num_options); + } + + if (!options || num_options < 0) + { + DEBUG_puts("1cupsParseOptions: Returning 0"); + return (0); + } + + /* + * Make a copy of the argument string and then divide it up... + */ + + if ((copyarg = strdup(arg)) == NULL) + { + DEBUG_puts("1cupsParseOptions: Unable to copy arg string"); + DEBUG_printf(("1cupsParseOptions: Returning %d", num_options)); + return (num_options); + } + + if (*copyarg == '{') + { + /* + * Remove surrounding {} so we can parse "{name=value ... name=value}"... + */ + + if ((ptr = copyarg + strlen(copyarg) - 1) > copyarg && *ptr == '}') + { + *ptr = '\0'; + ptr = copyarg + 1; + } + else + ptr = copyarg; + } + else + ptr = copyarg; + + /* + * Skip leading spaces... + */ + + while (_cups_isspace(*ptr)) + ptr ++; + + /* + * Loop through the string... + */ + + while (*ptr != '\0') + { + /* + * Get the name up to a SPACE, =, or end-of-string... + */ + + name = ptr; + while (!strchr("\f\n\r\t\v =", *ptr) && *ptr) + ptr ++; + + /* + * Avoid an empty name... + */ + + if (ptr == name) + break; + + /* + * Skip trailing spaces... + */ + + while (_cups_isspace(*ptr)) + *ptr++ = '\0'; + + if ((sep = *ptr) == '=') + *ptr++ = '\0'; + + DEBUG_printf(("2cupsParseOptions: name=\"%s\"", name)); + + if (sep != '=') + { + /* + * Boolean option... + */ + + if (!strncasecmp(name, "no", 2)) + num_options = cupsAddOption(name + 2, "false", num_options, + options); + else + num_options = cupsAddOption(name, "true", num_options, options); + + continue; + } + + /* + * Remove = and parse the value... + */ + + value = ptr; + + while (*ptr && !_cups_isspace(*ptr)) + { + if (*ptr == ',') + ptr ++; + else if (*ptr == '\'' || *ptr == '\"') + { + /* + * Quoted string constant... + */ + + quote = *ptr; + _cups_strcpy(ptr, ptr + 1); + + while (*ptr != quote && *ptr) + { + if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + + ptr ++; + } + + if (*ptr) + _cups_strcpy(ptr, ptr + 1); + } + else if (*ptr == '{') + { + /* + * Collection value... + */ + + int depth; + + for (depth = 0; *ptr; ptr ++) + { + if (*ptr == '{') + depth ++; + else if (*ptr == '}') + { + depth --; + if (!depth) + { + ptr ++; + break; + } + } + else if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + } + } + else + { + /* + * Normal space-delimited string... + */ + + while (*ptr && !_cups_isspace(*ptr)) + { + if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + + ptr ++; + } + } + } + + if (*ptr != '\0') + *ptr++ = '\0'; + + DEBUG_printf(("2cupsParseOptions: value=\"%s\"", value)); + + /* + * Skip trailing whitespace... + */ + + while (_cups_isspace(*ptr)) + ptr ++; + + /* + * 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); + + DEBUG_printf(("1cupsParseOptions: Returning %d", num_options)); + + return (num_options); +} + + +/* + * 'cupsRemoveOption()' - Remove an option from an option array. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - New number of options */ +cupsRemoveOption( + const char *name, /* I - Option name */ + int num_options, /* I - Current number of options */ + cups_option_t **options) /* IO - Options */ +{ + int i; /* Looping var */ + cups_option_t *option; /* Current option */ + + + DEBUG_printf(("2cupsRemoveOption(name=\"%s\", num_options=%d, options=%p)", + name, num_options, options)); + + /* + * Range check input... + */ + + if (!name || num_options < 1 || !options) + { + DEBUG_printf(("3cupsRemoveOption: Returning %d", num_options)); + return (num_options); + } + + /* + * Loop for the option... + */ + + for (i = num_options, option = *options; i > 0; i --, option ++) + if (!strcasecmp(name, option->name)) + break; + + if (i) + { + /* + * Remove this option from the array... + */ + + DEBUG_puts("4cupsRemoveOption: Found option, removing it..."); + + num_options --; + i --; + + _cupsStrFree(option->name); + _cupsStrFree(option->value); + + if (i > 0) + memmove(option, option + 1, i * sizeof(cups_option_t)); + } + + /* + * Return the new number of options... + */ + + DEBUG_printf(("3cupsRemoveOption: Returning %d", num_options)); + return (num_options); +} + + +/* + * 'cups_compare_options()' - Compare two options. + */ + +static int /* O - Result of comparison */ +cups_compare_options(cups_option_t *a, /* I - First option */ + cups_option_t *b) /* I - Second option */ +{ + return (strcasecmp(a->name, b->name)); +} + + +/* + * 'cups_find_option()' - Find an option using a binary search. + */ + +static int /* O - Index of match */ +cups_find_option( + const char *name, /* I - Option name */ + int num_options, /* I - Number of options */ + cups_option_t *options, /* I - Options */ + int prev, /* I - Previous index */ + int *rdiff) /* O - Difference of match */ +{ + int left, /* Low mark for binary search */ + right, /* High mark for binary search */ + current, /* Current index */ + diff; /* Result of comparison */ + cups_option_t key; /* Search key */ + + + DEBUG_printf(("7cups_find_option(name=\"%s\", num_options=%d, options=%p, " + "prev=%d, rdiff=%p)", name, num_options, options, prev, + rdiff)); + +#ifdef DEBUG + for (left = 0; left < num_options; left ++) + DEBUG_printf(("9cups_find_option: options[%d].name=\"%s\", .value=\"%s\"", + left, options[left].name, options[left].value)); +#endif /* DEBUG */ + + key.name = (char *)name; + + if (prev >= 0) + { + /* + * Start search on either side of previous... + */ + + if ((diff = cups_compare_options(&key, options + prev)) == 0 || + (diff < 0 && prev == 0) || + (diff > 0 && prev == (num_options - 1))) + { + *rdiff = diff; + return (prev); + } + else if (diff < 0) + { + /* + * Start with previous on right side... + */ + + left = 0; + right = prev; + } + else + { + /* + * Start wih previous on left side... + */ + + left = prev; + right = num_options - 1; + } + } + else + { + /* + * Start search in the middle... + */ + + left = 0; + right = num_options - 1; + } + + do + { + current = (left + right) / 2; + diff = cups_compare_options(&key, options + current); + + if (diff == 0) + break; + else if (diff < 0) + right = current; + else + left = current; + } + while ((right - left) > 1); + + if (diff != 0) + { + /* + * Check the last 1 or 2 elements... + */ + + if ((diff = cups_compare_options(&key, options + left)) <= 0) + current = left; + else + { + diff = cups_compare_options(&key, options + right); + current = right; + } + } + + /* + * Return the closest destination and the difference... + */ + + *rdiff = diff; + + return (current); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/page.c b/cups/page.c new file mode 100644 index 0000000000..2e9fcd02af --- /dev/null +++ b/cups/page.c @@ -0,0 +1,397 @@ +/* + * "$Id$" + * + * Page size functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * ppdPageSizeLimits() - Return the custom page size limits. + * 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 +#include "debug.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 */ + ppd_size_t *size; /* Current page size */ + double w, l; /* Width and length of page */ + char *nameptr; /* Pointer into name */ + struct lconv *loc; /* Locale data */ + ppd_coption_t *coption; /* Custom option for page size */ + ppd_cparam_t *cparam; /* Custom option parameter */ + + + DEBUG_printf(("2ppdPageSize(ppd=%p, name=\"%s\")", ppd, name)); + + if (!ppd) + { + DEBUG_puts("3ppdPageSize: Bad PPD pointer, returning NULL..."); + return (NULL); + } + + if (name) + { + if (!strncmp(name, "Custom.", 7) && ppd->variable_sizes) + { + /* + * Find the custom page size... + */ + + for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) + if (!strcmp("Custom", size->name)) + break; + + if (!i) + { + DEBUG_puts("3ppdPageSize: No custom sizes, returning NULL..."); + return (NULL); + } + + /* + * Variable size; size name can be one of the following: + * + * Custom.WIDTHxLENGTHin - Size in inches + * Custom.WIDTHxLENGTHft - Size in feet + * Custom.WIDTHxLENGTHcm - Size in centimeters + * Custom.WIDTHxLENGTHmm - Size in millimeters + * Custom.WIDTHxLENGTHm - Size in meters + * Custom.WIDTHxLENGTH[pt] - Size in points + */ + + loc = localeconv(); + w = _cupsStrScand(name + 7, &nameptr, loc); + if (!nameptr || *nameptr != 'x') + return (NULL); + + l = _cupsStrScand(nameptr + 1, &nameptr, loc); + if (!nameptr) + return (NULL); + + if (!strcasecmp(nameptr, "in")) + { + w *= 72.0; + l *= 72.0; + } + else if (!strcasecmp(nameptr, "ft")) + { + w *= 12.0 * 72.0; + l *= 12.0 * 72.0; + } + else if (!strcasecmp(nameptr, "mm")) + { + w *= 72.0 / 25.4; + l *= 72.0 / 25.4; + } + else if (!strcasecmp(nameptr, "cm")) + { + w *= 72.0 / 2.54; + l *= 72.0 / 2.54; + } + else if (!strcasecmp(nameptr, "m")) + { + w *= 72.0 / 0.0254; + l *= 72.0 / 0.0254; + } + + size->width = (float)w; + size->length = (float)l; + size->left = ppd->custom_margins[0]; + size->bottom = ppd->custom_margins[1]; + size->right = (float)(w - ppd->custom_margins[2]); + size->top = (float)(l - ppd->custom_margins[3]); + + /* + * Update the custom option records for the page size, too... + */ + + if ((coption = ppdFindCustomOption(ppd, "PageSize")) != NULL) + { + if ((cparam = ppdFindCustomParam(coption, "Width")) != NULL) + cparam->current.custom_points = w; + + if ((cparam = ppdFindCustomParam(coption, "Height")) != NULL) + cparam->current.custom_points = l; + } + + /* + * Return the page size... + */ + + DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, + size->name, size->width, size->length)); + + return (size); + } + else + { + /* + * Lookup by name... + */ + + for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) + if (!strcasecmp(name, size->name)) + { + DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, + size->name, size->width, size->length)); + + return (size); + } + } + } + else + { + /* + * Find default... + */ + + for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) + if (size->marked) + { + DEBUG_printf(("3ppdPageSize: Returning %p (\"%s\", %gx%g)", size, + size->name, size->width, size->length)); + + return (size); + } + } + + DEBUG_puts("3ppdPageSize: Size not found, returning NULL"); + + return (NULL); +} + + +/* + * 'ppdPageSizeLimits()' - Return the custom page size limits. + * + * This function returns the minimum and maximum custom page sizes and printable + * areas based on the currently-marked (selected) options. + * + * If the specified PPD file does not support custom page sizes, both + * "minimum" and "maximum" are filled with zeroes. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +int /* O - 1 if custom sizes are supported, 0 otherwise */ +ppdPageSizeLimits(ppd_file_t *ppd, /* I - PPD file record */ + ppd_size_t *minimum, /* O - Minimum custom size */ + ppd_size_t *maximum) /* O - Maximum custom size */ +{ + ppd_choice_t *qualifier2, /* Second media qualifier */ + *qualifier3; /* Third media qualifier */ + ppd_attr_t *attr; /* Attribute */ + float width, /* Min/max width */ + length; /* Min/max length */ + char spec[PPD_MAX_NAME]; /* Selector for min/max */ + + + /* + * Range check input... + */ + + if (!ppd || !ppd->variable_sizes || !minimum || !maximum) + { + if (minimum) + memset(minimum, 0, sizeof(ppd_size_t)); + + if (maximum) + memset(maximum, 0, sizeof(ppd_size_t)); + + return (0); + } + + /* + * See if we have the cupsMediaQualifier2 and cupsMediaQualifier3 attributes... + */ + + cupsArraySave(ppd->sorted_attrs); + + if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier2", NULL)) != NULL && + attr->value) + qualifier2 = ppdFindMarkedChoice(ppd, attr->value); + else + qualifier2 = NULL; + + if ((attr = ppdFindAttr(ppd, "cupsMediaQualifier3", NULL)) != NULL && + attr->value) + qualifier3 = ppdFindMarkedChoice(ppd, attr->value); + else + qualifier3 = NULL; + + /* + * Figure out the current minimum width and length... + */ + + width = ppd->custom_min[0]; + length = ppd->custom_min[1]; + + if (qualifier2) + { + /* + * Try getting cupsMinSize... + */ + + if (qualifier3) + { + snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice, + qualifier3->choice); + attr = ppdFindAttr(ppd, "cupsMinSize", spec); + } + else + attr = NULL; + + if (!attr) + { + snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice); + attr = ppdFindAttr(ppd, "cupsMinSize", spec); + } + + if (!attr && qualifier3) + { + snprintf(spec, sizeof(spec), "..%s", qualifier3->choice); + attr = ppdFindAttr(ppd, "cupsMinSize", spec); + } + + if ((attr && attr->value && + sscanf(attr->value, "%f%f", &width, &length) != 2) || !attr) + { + width = ppd->custom_min[0]; + length = ppd->custom_min[1]; + } + } + + minimum->width = width; + minimum->length = length; + minimum->left = ppd->custom_margins[0]; + minimum->bottom = ppd->custom_margins[1]; + minimum->right = width - ppd->custom_margins[2]; + minimum->top = length - ppd->custom_margins[3]; + + /* + * Figure out the current maximum width and length... + */ + + width = ppd->custom_max[0]; + length = ppd->custom_max[1]; + + if (qualifier2) + { + /* + * Try getting cupsMaxSize... + */ + + if (qualifier3) + { + snprintf(spec, sizeof(spec), ".%s.%s", qualifier2->choice, + qualifier3->choice); + attr = ppdFindAttr(ppd, "cupsMaxSize", spec); + } + else + attr = NULL; + + if (!attr) + { + snprintf(spec, sizeof(spec), ".%s.", qualifier2->choice); + attr = ppdFindAttr(ppd, "cupsMaxSize", spec); + } + + if (!attr && qualifier3) + { + snprintf(spec, sizeof(spec), "..%s", qualifier3->choice); + attr = ppdFindAttr(ppd, "cupsMaxSize", spec); + } + + if (!attr || + (attr->value && sscanf(attr->value, "%f%f", &width, &length) != 2)) + { + width = ppd->custom_max[0]; + length = ppd->custom_max[1]; + } + } + + maximum->width = width; + maximum->length = length; + maximum->left = ppd->custom_margins[0]; + maximum->bottom = ppd->custom_margins[1]; + maximum->right = width - ppd->custom_margins[2]; + maximum->top = length - ppd->custom_margins[3]; + + /* + * Return the min and max... + */ + + cupsArrayRestore(ppd->sorted_attrs); + + return (1); +} + + +/* + * '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-private.h b/cups/ppd-private.h new file mode 100644 index 0000000000..f1af0b3b4a --- /dev/null +++ b/cups/ppd-private.h @@ -0,0 +1,104 @@ +/* + * "$Id$" + * + * Private PPD definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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_PRIVATE_H_ +# define _CUPS_PPD_PRIVATE_H_ + +/* + * Include necessary headers... + */ + +# include "cups.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Types and structures... + */ + +typedef enum _ppd_parse_e /**** Selector for _ppdParseOptions ****/ +{ + _PPD_PARSE_OPTIONS, /* Parse only the options */ + _PPD_PARSE_PROPERTIES, /* Parse only the properties */ + _PPD_PARSE_ALL /* Parse everything */ +} _ppd_parse_t; + +typedef struct _ppd_cups_uiconst_s /**** Constraint from cupsUIConstraints ****/ +{ + ppd_option_t *option; /* Constrained option */ + ppd_choice_t *choice; /* Constrained choice or @code NULL@ */ + int installable; /* Installable option? */ +} _ppd_cups_uiconst_t; + +typedef struct _ppd_cups_uiconsts_s /**** cupsUIConstraints ****/ +{ + char resolver[PPD_MAX_NAME]; /* Resolver name */ + int installable, /* Constrained against any installable options? */ + num_constraints; /* Number of constraints */ + _ppd_cups_uiconst_t *constraints; /* Constraints */ +} _ppd_cups_uiconsts_t; + + +/* + * Prototypes... + */ + +extern void _ppdFreeLanguages(cups_array_t *languages); +extern int _ppdGet1284Values(const char *device_id, + cups_option_t **values); +extern cups_encoding_t _ppdGetEncoding(const char *name); +extern cups_array_t *_ppdGetLanguages(ppd_file_t *ppd); +extern unsigned _ppdHashName(const char *name); +extern ppd_attr_t *_ppdLocalizedAttr(ppd_file_t *ppd, const char *keyword, + const char *spec, const char *ll_CC); +extern char *_ppdNormalizeMakeAndModel(const char *make_and_model, + char *buffer, + size_t bufsize); +extern int _ppdParseOptions(const char *s, int num_options, + cups_option_t **options, + _ppd_parse_t which); + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_PPD_PRIVATE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/ppd.c b/cups/ppd.c new file mode 100644 index 0000000000..bfc51f56b1 --- /dev/null +++ b/cups/ppd.c @@ -0,0 +1,3147 @@ +/* + * "$Id$" + * + * PPD file routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * ppdErrorString() - Returns the text assocated with a status. + * _ppdGetEncoding() - Get the CUPS encoding value for the given + * LanguageEncoding. + * ppdLastError() - Return the status from the last ppdOpen*(). + * ppdOpen() - Read a PPD file into memory. + * ppdOpen2() - Read a PPD file into memory. + * ppdOpenFd() - Read a PPD file into memory. + * ppdOpenFile() - Read a PPD file into memory. + * ppdSetConformance() - Set the conformance level for PPD files. + * ppd_add_attr() - Add an attribute to the PPD data. + * ppd_add_choice() - Add a choice to an option. + * ppd_add_size() - Add a page size. + * ppd_compare_attrs() - Compare two attributes. + * ppd_compare_choices() - Compare two choices... + * ppd_compare_coptions() - Compare two custom options. + * ppd_compare_options() - Compare two options. + * ppd_decode() - Decode a string value... + * ppd_free_group() - Free a single UI group. + * ppd_free_option() - Free a single option. + * ppd_get_coption() - Get a custom option record. + * ppd_get_cparam() - Get a custom parameter record. + * ppd_get_group() - Find or create the named group as needed. + * ppd_get_option() - Find or create the named option as needed. + * ppd_hash_option() - Generate a hash of the option name... + * ppd_read() - Read a line from a PPD file, skipping comment + * lines as necessary. + */ + +/* + * Include necessary headers. + */ + +#include "ppd-private.h" +#include "pwg-private.h" +#include "globals.h" +#include "debug.h" +#include + + +/* + * 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 ppd_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 */ + +#define PPD_HASHSIZE 512 /* Size of hash */ + + +/* + * Line buffer structure... + */ + +typedef struct _ppd_line_s +{ + char *buffer; /* Pointer to buffer */ + size_t bufsize; /* Size of the buffer */ +} _ppd_line_t; + + +/* + * Local functions... + */ + +static ppd_attr_t *ppd_add_attr(ppd_file_t *ppd, const char *name, + const char *spec, const char *text, + const char *value); +static ppd_choice_t *ppd_add_choice(ppd_option_t *option, const char *name); +static ppd_size_t *ppd_add_size(ppd_file_t *ppd, const char *name); +static int ppd_compare_attrs(ppd_attr_t *a, ppd_attr_t *b); +static int ppd_compare_choices(ppd_choice_t *a, ppd_choice_t *b); +static int ppd_compare_coptions(ppd_coption_t *a, + ppd_coption_t *b); +static int ppd_compare_options(ppd_option_t *a, ppd_option_t *b); +static int ppd_decode(char *string); +static void ppd_free_group(ppd_group_t *group); +static void ppd_free_option(ppd_option_t *option); +static ppd_coption_t *ppd_get_coption(ppd_file_t *ppd, const char *name); +static ppd_cparam_t *ppd_get_cparam(ppd_coption_t *opt, + const char *param, + const char *text); +static ppd_group_t *ppd_get_group(ppd_file_t *ppd, const char *name, + const char *text, _cups_globals_t *cg, + cups_encoding_t encoding); +static ppd_option_t *ppd_get_option(ppd_group_t *group, const char *name); +static int ppd_hash_option(ppd_option_t *option); +static int ppd_read(cups_file_t *fp, _ppd_line_t *line, + char *keyword, char *option, char *text, + char **string, int ignoreblank, + _cups_globals_t *cg); + + +/* + * '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 */ + ppd_attr_t **attr; /* Current attribute */ + ppd_coption_t *coption; /* Current custom option */ + ppd_cparam_t *cparam; /* Current custom parameter */ + + + /* + * Range check arguments... + */ + + if (!ppd) + return; + + /* + * Free all strings at the top level... + */ + + _cupsStrFree(ppd->lang_encoding); + _cupsStrFree(ppd->nickname); + if (ppd->patches) + free(ppd->patches); + _cupsStrFree(ppd->jcl_begin); + _cupsStrFree(ppd->jcl_end); + _cupsStrFree(ppd->jcl_ps); + + /* + * Free any emulations... + */ + + if (ppd->num_emulations > 0) + { + for (i = ppd->num_emulations, emul = ppd->emulations; i > 0; i --, emul ++) + { + _cupsStrFree(emul->start); + _cupsStrFree(emul->stop); + } + + ppd_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); + + ppd_free(ppd->groups); + } + + cupsArrayDelete(ppd->options); + cupsArrayDelete(ppd->marked); + + /* + * Free any page sizes... + */ + + if (ppd->num_sizes > 0) + ppd_free(ppd->sizes); + + /* + * Free any constraints... + */ + + if (ppd->num_consts > 0) + ppd_free(ppd->consts); + + /* + * Free any filters... + */ + + if (ppd->num_filters > 0) + { + for (i = ppd->num_filters, filter = ppd->filters; i > 0; i --, filter ++) + _cupsStrFree(*filter); + + ppd_free(ppd->filters); + } + + /* + * Free any fonts... + */ + + if (ppd->num_fonts > 0) + { + for (i = ppd->num_fonts, font = ppd->fonts; i > 0; i --, font ++) + _cupsStrFree(*font); + + ppd_free(ppd->fonts); + } + + /* + * Free any profiles... + */ + + if (ppd->num_profiles > 0) + ppd_free(ppd->profiles); + + /* + * Free any attributes... + */ + + if (ppd->num_attrs > 0) + { + for (i = ppd->num_attrs, attr = ppd->attrs; i > 0; i --, attr ++) + { + _cupsStrFree((*attr)->value); + ppd_free(*attr); + } + + ppd_free(ppd->attrs); + } + + cupsArrayDelete(ppd->sorted_attrs); + + /* + * Free custom options... + */ + + for (coption = (ppd_coption_t *)cupsArrayFirst(ppd->coptions); + coption; + coption = (ppd_coption_t *)cupsArrayNext(ppd->coptions)) + { + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + { + switch (cparam->type) + { + case PPD_CUSTOM_PASSCODE : + case PPD_CUSTOM_PASSWORD : + case PPD_CUSTOM_STRING : + _cupsStrFree(cparam->current.custom_string); + break; + + default : + break; + } + + free(cparam); + } + + cupsArrayDelete(coption->params); + + free(coption); + } + + cupsArrayDelete(ppd->coptions); + + /* + * Free constraints... + */ + + if (ppd->cups_uiconstraints) + { + _ppd_cups_uiconsts_t *consts; /* Current constraints */ + + + for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(ppd->cups_uiconstraints); + consts; + consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(ppd->cups_uiconstraints)) + { + free(consts->constraints); + free(consts); + } + + cupsArrayDelete(ppd->cups_uiconstraints); + } + + /* + * Free any PWG mapping data... + */ + + if (ppd->pwg) + _pwgDestroy((_pwg_t *)ppd->pwg); + + /* + * Free the whole record... + */ + + ppd_free(ppd); +} + + +/* + * 'ppdErrorString()' - Returns the text assocated with a status. + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +const char * /* O - Status string */ +ppdErrorString(ppd_status_t status) /* I - PPD status */ +{ + static const char * const messages[] =/* Status messages */ + { + _("OK"), + _("Unable to open PPD file"), + _("NULL PPD file pointer"), + _("Memory allocation error"), + _("Missing PPD-Adobe-4.x header"), + _("Missing value string"), + _("Internal error"), + _("Bad OpenGroup"), + _("OpenGroup without a CloseGroup first"), + _("Bad OpenUI/JCLOpenUI"), + _("OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first"), + _("Bad OrderDependency"), + _("Bad UIConstraints"), + _("Missing asterisk in column 1"), + _("Line longer than the maximum allowed (255 characters)"), + _("Illegal control character"), + _("Illegal main keyword string"), + _("Illegal option keyword string"), + _("Illegal translation string"), + _("Illegal whitespace character"), + _("Bad custom parameter"), + _("Missing option keyword"), + _("Bad value string") + }; + + + if (status < PPD_OK || status >= PPD_MAX_STATUS) + return (_cupsLangString(cupsLangDefault(), _("Unknown"))); + else + return (_cupsLangString(cupsLangDefault(), messages[status])); +} + + +/* + * '_ppdGetEncoding()' - Get the CUPS encoding value for the given + * LanguageEncoding. + */ + +cups_encoding_t /* O - CUPS encoding value */ +_ppdGetEncoding(const char *name) /* I - LanguageEncoding string */ +{ + if (!strcasecmp(name, "ISOLatin1")) + return (CUPS_ISO8859_1); + else if (!strcasecmp(name, "ISOLatin2")) + return (CUPS_ISO8859_2); + else if (!strcasecmp(name, "ISOLatin5")) + return (CUPS_ISO8859_5); + else if (!strcasecmp(name, "JIS83-RKSJ")) + return (CUPS_JIS_X0213); + else if (!strcasecmp(name, "MacStandard")) + return (CUPS_MAC_ROMAN); + else if (!strcasecmp(name, "WindowsANSI")) + return (CUPS_WINDOWS_1252); + else + return (CUPS_UTF8); +} + + +/* + * 'ppdLastError()' - Return the status from the last ppdOpen*(). + * + * @since CUPS 1.1.19/Mac OS X 10.3@ + */ + +ppd_status_t /* O - Status code */ +ppdLastError(int *line) /* O - Line number */ +{ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + if (line) + *line = cg->ppd_line; + + return (cg->ppd_status); +} + + +/* + * 'ppdOpen()' - Read a PPD file into memory. + */ + +ppd_file_t * /* O - PPD file record */ +ppdOpen(FILE *fp) /* I - File to read from */ +{ + ppd_file_t *ppd; /* PPD file record */ + cups_file_t *cf; /* CUPS file */ + + + /* + * Reopen the stdio file as a CUPS file... + */ + + if ((cf = cupsFileOpenFd(fileno(fp), "r")) == NULL) + return (NULL); + + /* + * Load the PPD file using the newer API... + */ + + ppd = ppdOpen2(cf); + + /* + * Close the CUPS file and return the PPD... + */ + + cupsFileClose(cf); + + return (ppd); +} + + +/* + * 'ppdOpen2()' - Read a PPD file into memory. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */ +ppdOpen2(cups_file_t *fp) /* I - File to read from */ +{ + int i, j, k; /* Looping vars */ + int count; /* Temporary count */ + _ppd_line_t line; /* Line buffer */ + 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 */ + struct lconv *loc; /* Locale data */ + int ui_keyword; /* Is this line a UI keyword? */ + cups_encoding_t encoding; /* Encoding of PPD file */ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + char custom_name[PPD_MAX_NAME]; + /* CustomFoo attribute name */ + ppd_attr_t *custom_attr; /* CustomFoo attribute */ + static const char * const ui_keywords[] = + { +#ifdef CUPS_USE_FULL_UI_KEYWORDS_LIST + /* + * Adobe defines some 41 keywords as "UI", meaning that they are + * user interface elements and that they should be treated as such + * even if the PPD creator doesn't use Open/CloseUI around them. + * + * Since this can cause previously invisible options to appear and + * confuse users, the default is to only treat the PageSize and + * PageRegion keywords this way. + */ + /* Boolean keywords */ + "BlackSubstitution", + "Booklet", + "Collate", + "ManualFeed", + "MirrorPrint", + "NegativePrint", + "Sorter", + "TraySwitch", + + /* PickOne keywords */ + "AdvanceMedia", + "BindColor", + "BindEdge", + "BindType", + "BindWhen", + "BitsPerPixel", + "ColorModel", + "CutMedia", + "Duplex", + "FoldType", + "FoldWhen", + "InputSlot", + "JCLFrameBufferSize", + "JCLResolution", + "Jog", + "MediaColor", + "MediaType", + "MediaWeight", + "OutputBin", + "OutputMode", + "OutputOrder", + "PageRegion", + "PageSize", + "Resolution", + "Separations", + "Signature", + "Slipsheet", + "Smoothing", + "StapleLocation", + "StapleOrientation", + "StapleWhen", + "StapleX", + "StapleY" +#else /* !CUPS_USE_FULL_UI_KEYWORDS_LIST */ + "PageRegion", + "PageSize" +#endif /* CUPS_USE_FULL_UI_KEYWORDS_LIST */ + }; + + + DEBUG_printf(("ppdOpen2(fp=%p)", fp)); + + /* + * Default to "OK" status... + */ + + cg->ppd_status = PPD_OK; + cg->ppd_line = 0; + + /* + * Range check input... + */ + + if (fp == NULL) + { + cg->ppd_status = PPD_NULL_FILE; + return (NULL); + } + + /* + * Grab the first line and make sure it reads '*PPD-Adobe: "major.minor"'... + */ + + line.buffer = NULL; + line.bufsize = 0; + + mask = ppd_read(fp, &line, keyword, name, text, &string, 0, cg); + + DEBUG_printf(("2ppdOpen2: mask=%x, keyword=\"%s\"...", mask, keyword)); + + if (mask == 0 || + strcmp(keyword, "PPD-Adobe") || + string == NULL || string[0] != '4') + { + /* + * Either this is not a PPD file, or it is not a 4.x PPD file. + */ + + if (cg->ppd_status == PPD_OK) + cg->ppd_status = PPD_MISSING_PPDADOBE4; + + _cupsStrFree(string); + ppd_free(line.buffer); + + return (NULL); + } + + DEBUG_printf(("2ppdOpen2: keyword=%s, string=%p", keyword, string)); + + _cupsStrFree(string); + + /* + * Allocate memory for the PPD file record... + */ + + if ((ppd = calloc(1, sizeof(ppd_file_t))) == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + _cupsStrFree(string); + ppd_free(line.buffer); + + return (NULL); + } + + ppd->language_level = 2; + ppd->color_device = 0; + ppd->colorspace = PPD_CS_N; + ppd->landscape = -90; + ppd->coptions = cupsArrayNew((cups_array_func_t)ppd_compare_coptions, + NULL); + + /* + * Get the default language for the user... + */ + + language = cupsLangDefault(); + loc = localeconv(); + + /* + * Read lines from the PPD file and add them to the file record... + */ + + group = NULL; + subgroup = NULL; + option = NULL; + choice = NULL; + ui_keyword = 0; + encoding = CUPS_ISO8859_1; + + while ((mask = ppd_read(fp, &line, keyword, name, text, &string, 1, cg)) != 0) + { + DEBUG_printf(("2ppdOpen2: mask=%x, keyword=\"%s\", name=\"%s\", " + "text=\"%s\", string=%d chars...", mask, keyword, name, text, + string ? (int)strlen(string) : 0)); + + if (strncmp(keyword, "Default", 7) && !string && + cg->ppd_conform != PPD_CONFORM_RELAXED) + { + /* + * Need a string value! + */ + + cg->ppd_status = PPD_MISSING_VALUE; + + goto error; + } + else if (!string) + continue; + + /* + * Certain main keywords (as defined by the PPD spec) may be used + * without the usual OpenUI/CloseUI stuff. Presumably this is just + * so that Adobe wouldn't completely break compatibility with PPD + * files prior to v4.0 of the spec, but it is hopelessly + * inconsistent... Catch these main keywords and automatically + * create the corresponding option, as needed... + */ + + if (ui_keyword) + { + /* + * Previous line was a UI keyword... + */ + + option = NULL; + ui_keyword = 0; + } + + if (option == NULL && + (mask & (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) == + (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) + { + for (i = 0; i < (int)(sizeof(ui_keywords) / sizeof(ui_keywords[0])); i ++) + if (!strcmp(keyword, ui_keywords[i])) + break; + + if (i < (int)(sizeof(ui_keywords) / sizeof(ui_keywords[0]))) + { + /* + * Create the option in the appropriate group... + */ + + ui_keyword = 1; + + DEBUG_printf(("2ppdOpen2: FOUND ADOBE UI KEYWORD %s WITHOUT OPENUI!", + keyword)); + + if (!group) + { + if ((group = ppd_get_group(ppd, "General", _("General"), cg, + encoding)) == NULL) + goto error; + + DEBUG_printf(("2ppdOpen2: Adding to group %s...", group->text)); + option = ppd_get_option(group, keyword); + group = NULL; + } + else + option = ppd_get_option(group, keyword); + + if (option == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + /* + * Now fill in the initial information for the option... + */ + + if (!strncmp(keyword, "JCL", 3)) + option->section = PPD_ORDER_JCL; + else + option->section = PPD_ORDER_ANY; + + option->order = 10.0f; + + if (i < 8) + option->ui = PPD_UI_BOOLEAN; + else + option->ui = PPD_UI_PICKONE; + + for (j = 0; j < ppd->num_attrs; j ++) + if (!strncmp(ppd->attrs[j]->name, "Default", 7) && + !strcmp(ppd->attrs[j]->name + 7, keyword) && + ppd->attrs[j]->value) + { + DEBUG_printf(("2ppdOpen2: Setting Default%s to %s via attribute...", + option->keyword, ppd->attrs[j]->value)); + strlcpy(option->defchoice, ppd->attrs[j]->value, + sizeof(option->defchoice)); + break; + } + + if (!strcmp(keyword, "PageSize")) + strlcpy(option->text, _("Media Size"), sizeof(option->text)); + else if (!strcmp(keyword, "MediaType")) + strlcpy(option->text, _("Media Type"), sizeof(option->text)); + else if (!strcmp(keyword, "InputSlot")) + strlcpy(option->text, _("Media Source"), sizeof(option->text)); + else if (!strcmp(keyword, "ColorModel")) + strlcpy(option->text, _("Output Mode"), sizeof(option->text)); + else if (!strcmp(keyword, "Resolution")) + strlcpy(option->text, _("Resolution"), sizeof(option->text)); + else + strlcpy(option->text, keyword, sizeof(option->text)); + } + } + + if (!strcmp(keyword, "LanguageLevel")) + ppd->language_level = atoi(string); + else if (!strcmp(keyword, "LanguageEncoding")) + { + /* + * Say all PPD files are UTF-8, since we convert to UTF-8... + */ + + ppd->lang_encoding = _cupsStrAlloc("UTF-8"); + encoding = _ppdGetEncoding(string); + } + else if (!strcmp(keyword, "LanguageVersion")) + ppd->lang_version = string; + else if (!strcmp(keyword, "Manufacturer")) + ppd->manufacturer = string; + else if (!strcmp(keyword, "ModelName")) + ppd->modelname = string; + else if (!strcmp(keyword, "Protocols")) + ppd->protocols = string; + else if (!strcmp(keyword, "PCFileName")) + ppd->pcfilename = string; + else if (!strcmp(keyword, "NickName")) + { + if (encoding != CUPS_UTF8) + { + cups_utf8_t utf8[256]; /* UTF-8 version of NickName */ + + + cupsCharsetToUTF8(utf8, string, sizeof(utf8), encoding); + ppd->nickname = _cupsStrAlloc((char *)utf8); + } + else + ppd->nickname = _cupsStrAlloc(string); + } + else if (!strcmp(keyword, "Product")) + ppd->product = string; + else if (!strcmp(keyword, "ShortNickName")) + ppd->shortnickname = string; + else if (!strcmp(keyword, "TTRasterizer")) + ppd->ttrasterizer = string; + else if (!strcmp(keyword, "JCLBegin")) + { + ppd->jcl_begin = _cupsStrAlloc(string); + ppd_decode(ppd->jcl_begin); /* Decode quoted string */ + } + else if (!strcmp(keyword, "JCLEnd")) + { + ppd->jcl_end = _cupsStrAlloc(string); + ppd_decode(ppd->jcl_end); /* Decode quoted string */ + } + else if (!strcmp(keyword, "JCLToPSInterpreter")) + { + ppd->jcl_ps = _cupsStrAlloc(string); + ppd_decode(ppd->jcl_ps); /* Decode quoted string */ + } + else if (!strcmp(keyword, "AccurateScreensSupport")) + ppd->accurate_screens = !strcmp(string, "True"); + else if (!strcmp(keyword, "ColorDevice")) + ppd->color_device = !strcmp(string, "True"); + else if (!strcmp(keyword, "ContoneOnly")) + ppd->contone_only = !strcmp(string, "True"); + else if (!strcmp(keyword, "cupsFlipDuplex")) + ppd->flip_duplex = !strcmp(string, "True"); + else if (!strcmp(keyword, "cupsManualCopies")) + ppd->manual_copies = !strcmp(string, "True"); + else if (!strcmp(keyword, "cupsModelNumber")) + ppd->model_number = atoi(string); + else if (!strcmp(keyword, "cupsColorProfile")) + { + if (ppd->num_profiles == 0) + profile = malloc(sizeof(ppd_profile_t)); + else + profile = realloc(ppd->profiles, sizeof(ppd_profile_t) * + (ppd->num_profiles + 1)); + + if (!profile) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + 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)); + + profile->density = (float)_cupsStrScand(string, &sptr, loc); + profile->gamma = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[0][0] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[0][1] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[0][2] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[1][0] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[1][1] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[1][2] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[2][0] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[2][1] = (float)_cupsStrScand(sptr, &sptr, loc); + profile->matrix[2][2] = (float)_cupsStrScand(sptr, &sptr, loc); + } + else if (!strcmp(keyword, "cupsFilter")) + { + if (ppd->num_filters == 0) + filter = malloc(sizeof(char *)); + else + filter = realloc(ppd->filters, sizeof(char *) * (ppd->num_filters + 1)); + + if (filter == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + 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")) + ppd->throughput = atoi(string); + else if (!strcmp(keyword, "Font")) + { + /* + * 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) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + ppd->fonts = tempfonts; + ppd->fonts[ppd->num_fonts] = _cupsStrAlloc(name); + ppd->num_fonts ++; + } + else if (!strncmp(keyword, "ParamCustom", 11)) + { + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + int corder; /* Order number */ + char ctype[33], /* Data type */ + cminimum[65], /* Minimum value */ + cmaximum[65]; /* Maximum value */ + + + /* + * Get the custom option and parameter... + */ + + if ((coption = ppd_get_coption(ppd, keyword + 11)) == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + if ((cparam = ppd_get_cparam(coption, name, text)) == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + /* + * Get the parameter data... + */ + + if (!string || + sscanf(string, "%d%32s%64s%64s", &corder, ctype, cminimum, + cmaximum) != 4) + { + cg->ppd_status = PPD_BAD_CUSTOM_PARAM; + + goto error; + } + + cparam->order = corder; + + if (!strcmp(ctype, "curve")) + { + cparam->type = PPD_CUSTOM_CURVE; + cparam->minimum.custom_curve = (float)_cupsStrScand(cminimum, NULL, loc); + cparam->maximum.custom_curve = (float)_cupsStrScand(cmaximum, NULL, loc); + } + else if (!strcmp(ctype, "int")) + { + cparam->type = PPD_CUSTOM_INT; + cparam->minimum.custom_int = atoi(cminimum); + cparam->maximum.custom_int = atoi(cmaximum); + } + else if (!strcmp(ctype, "invcurve")) + { + cparam->type = PPD_CUSTOM_INVCURVE; + cparam->minimum.custom_invcurve = (float)_cupsStrScand(cminimum, NULL, loc); + cparam->maximum.custom_invcurve = (float)_cupsStrScand(cmaximum, NULL, loc); + } + else if (!strcmp(ctype, "passcode")) + { + cparam->type = PPD_CUSTOM_PASSCODE; + cparam->minimum.custom_passcode = atoi(cminimum); + cparam->maximum.custom_passcode = atoi(cmaximum); + } + else if (!strcmp(ctype, "password")) + { + cparam->type = PPD_CUSTOM_PASSWORD; + cparam->minimum.custom_password = atoi(cminimum); + cparam->maximum.custom_password = atoi(cmaximum); + } + else if (!strcmp(ctype, "points")) + { + cparam->type = PPD_CUSTOM_POINTS; + cparam->minimum.custom_points = (float)_cupsStrScand(cminimum, NULL, loc); + cparam->maximum.custom_points = (float)_cupsStrScand(cmaximum, NULL, loc); + } + else if (!strcmp(ctype, "real")) + { + cparam->type = PPD_CUSTOM_REAL; + cparam->minimum.custom_real = (float)_cupsStrScand(cminimum, NULL, loc); + cparam->maximum.custom_real = (float)_cupsStrScand(cmaximum, NULL, loc); + } + else if (!strcmp(ctype, "string")) + { + cparam->type = PPD_CUSTOM_STRING; + cparam->minimum.custom_string = atoi(cminimum); + cparam->maximum.custom_string = atoi(cmaximum); + } + else + { + cg->ppd_status = PPD_BAD_CUSTOM_PARAM; + + goto error; + } + + /* + * Now special-case for CustomPageSize... + */ + + if (!strcmp(coption->keyword, "PageSize")) + { + if (!strcmp(name, "Width")) + { + ppd->custom_min[0] = cparam->minimum.custom_points; + ppd->custom_max[0] = cparam->maximum.custom_points; + } + else if (!strcmp(name, "Height")) + { + ppd->custom_min[1] = cparam->minimum.custom_points; + ppd->custom_max[1] = cparam->maximum.custom_points; + } + } + } + else if (!strcmp(keyword, "HWMargins")) + { + for (i = 0, sptr = string; i < 4; i ++) + ppd->custom_margins[i] = (float)_cupsStrScand(sptr, &sptr, loc); + } + else if (!strncmp(keyword, "Custom", 6) && !strcmp(name, "True") && !option) + { + ppd_option_t *custom_option; /* Custom option */ + + DEBUG_puts("2ppdOpen2: Processing Custom option..."); + + /* + * Get the option and custom option... + */ + + if (!ppd_get_coption(ppd, keyword + 6)) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + if (option && !strcasecmp(option->keyword, keyword + 6)) + custom_option = option; + else + custom_option = ppdFindOption(ppd, keyword + 6); + + if (custom_option) + { + /* + * Add the "custom" option... + */ + + if ((choice = ppdFindChoice(custom_option, "Custom")) == NULL) + if ((choice = ppd_add_choice(custom_option, "Custom")) == NULL) + { + DEBUG_puts("1ppdOpen2: Unable to add Custom choice!"); + + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + strlcpy(choice->text, text[0] ? text : _("Custom"), + sizeof(choice->text)); + + choice->code = _cupsStrAlloc(string); + + if (custom_option->section == PPD_ORDER_JCL) + ppd_decode(choice->code); + } + + /* + * Now process custom page sizes specially... + */ + + if (!strcmp(keyword, "CustomPageSize")) + { + /* + * Add a "Custom" page size entry... + */ + + ppd->variable_sizes = 1; + + ppd_add_size(ppd, "Custom"); + + if (option && !strcasecmp(option->keyword, "PageRegion")) + custom_option = option; + else + custom_option = ppdFindOption(ppd, "PageRegion"); + + if (custom_option) + { + if ((choice = ppdFindChoice(custom_option, "Custom")) == NULL) + if ((choice = ppd_add_choice(custom_option, "Custom")) == NULL) + { + DEBUG_puts("1ppdOpen2: Unable to add Custom choice!"); + + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + strlcpy(choice->text, text[0] ? text : _("Custom"), + sizeof(choice->text)); + } + } + } + else if (!strcmp(keyword, "LandscapeOrientation")) + { + if (!strcmp(string, "Minus90")) + ppd->landscape = -90; + else if (!strcmp(string, "Plus90")) + ppd->landscape = 90; + } + else if (!strcmp(keyword, "Emulators") && string) + { + for (count = 1, sptr = string; sptr != NULL;) + if ((sptr = strchr(sptr, ' ')) != NULL) + { + count ++; + while (*sptr == ' ') + sptr ++; + } + + ppd->num_emulations = count; + if ((ppd->emulations = calloc(count, sizeof(ppd_emul_t))) == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + 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)) + { + ppd_decode(string); + + for (i = 0; i < ppd->num_emulations; i ++) + if (!strcmp(keyword + 14, ppd->emulations[i].name)) + { + ppd->emulations[i].start = string; + string = NULL; + } + } + else if (!strncmp(keyword, "StopEmulator_", 13)) + { + ppd_decode(string); + + for (i = 0; i < ppd->num_emulations; i ++) + if (!strcmp(keyword + 13, ppd->emulations[i].name)) + { + ppd->emulations[i].stop = string; + string = NULL; + } + } + else if (!strcmp(keyword, "JobPatchFile")) + { + /* + * CUPS STR #3421: Check for "*JobPatchFile: int: string" + */ + + if (isdigit(*string & 255)) + { + for (sptr = string + 1; isdigit(*sptr & 255); sptr ++); + + if (*sptr == ':') + { + /* + * Found "*JobPatchFile: int: string"... + */ + + cg->ppd_status = PPD_BAD_VALUE; + + goto error; + } + } + + if (!name[0]) + { + /* + * Found "*JobPatchFile: string"... + */ + + cg->ppd_status = PPD_MISSING_OPTION_KEYWORD; + + goto error; + } + + if (ppd->patches == NULL) + ppd->patches = strdup(string); + else + { + temp = realloc(ppd->patches, strlen(ppd->patches) + + strlen(string) + 1); + if (temp == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + ppd->patches = temp; + + strcpy(ppd->patches + strlen(ppd->patches), string); + } + } + else if (!strcmp(keyword, "OpenUI")) + { + /* + * Don't allow nesting of options... + */ + + if (option && cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_NESTED_OPEN_UI; + + goto error; + } + + /* + * Add an option record to the current sub-group, group, or file... + */ + + DEBUG_printf(("2ppdOpen2: name=\"%s\" (%d)", name, (int)strlen(name))); + + if (name[0] == '*') + _cups_strcpy(name, name + 1); /* Eliminate leading asterisk */ + + for (i = (int)strlen(name) - 1; i > 0 && _cups_isspace(name[i]); i --) + name[i] = '\0'; /* Eliminate trailing spaces */ + + DEBUG_printf(("2ppdOpen2: OpenUI of %s in group %s...", name, + group ? group->text : "(null)")); + + if (subgroup != NULL) + option = ppd_get_option(subgroup, name); + else if (group == NULL) + { + if ((group = ppd_get_group(ppd, "General", _("General"), cg, + encoding)) == NULL) + goto error; + + DEBUG_printf(("2ppdOpen2: Adding to group %s...", group->text)); + option = ppd_get_option(group, name); + group = NULL; + } + else + option = ppd_get_option(group, name); + + if (option == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + /* + * Now fill in the initial information for the option... + */ + + if (string && !strcmp(string, "PickMany")) + option->ui = PPD_UI_PICKMANY; + else if (string && !strcmp(string, "Boolean")) + option->ui = PPD_UI_BOOLEAN; + else if (string && !strcmp(string, "PickOne")) + option->ui = PPD_UI_PICKONE; + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_OPEN_UI; + + goto error; + } + else + option->ui = PPD_UI_PICKONE; + + for (j = 0; j < ppd->num_attrs; j ++) + if (!strncmp(ppd->attrs[j]->name, "Default", 7) && + !strcmp(ppd->attrs[j]->name + 7, name) && + ppd->attrs[j]->value) + { + DEBUG_printf(("2ppdOpen2: Setting Default%s to %s via attribute...", + option->keyword, ppd->attrs[j]->value)); + strlcpy(option->defchoice, ppd->attrs[j]->value, + sizeof(option->defchoice)); + break; + } + + if (text[0]) + cupsCharsetToUTF8((cups_utf8_t *)option->text, text, + sizeof(option->text), encoding); + else + { + if (!strcmp(name, "PageSize")) + strlcpy(option->text, _("Media Size"), sizeof(option->text)); + else if (!strcmp(name, "MediaType")) + strlcpy(option->text, _("Media Type"), sizeof(option->text)); + else if (!strcmp(name, "InputSlot")) + strlcpy(option->text, _("Media Source"), sizeof(option->text)); + else if (!strcmp(name, "ColorModel")) + strlcpy(option->text, _("Output Mode"), sizeof(option->text)); + else if (!strcmp(name, "Resolution")) + strlcpy(option->text, _("Resolution"), sizeof(option->text)); + else + strlcpy(option->text, name, sizeof(option->text)); + } + + option->section = PPD_ORDER_ANY; + + _cupsStrFree(string); + string = NULL; + + /* + * Add a custom option choice if we have already seen a CustomFoo + * attribute... + */ + + if (!strcasecmp(name, "PageRegion")) + strcpy(custom_name, "CustomPageSize"); + else + snprintf(custom_name, sizeof(custom_name), "Custom%s", name); + + if ((custom_attr = ppdFindAttr(ppd, custom_name, "True")) != NULL) + { + if ((choice = ppdFindChoice(option, "Custom")) == NULL) + if ((choice = ppd_add_choice(option, "Custom")) == NULL) + { + DEBUG_puts("1ppdOpen2: Unable to add Custom choice!"); + + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + strlcpy(choice->text, + custom_attr->text[0] ? custom_attr->text : _("Custom"), + sizeof(choice->text)); + choice->code = _cupsStrRetain(custom_attr->value); + } + } + else if (!strcmp(keyword, "JCLOpenUI")) + { + /* + * Don't allow nesting of options... + */ + + if (option && cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_NESTED_OPEN_UI; + + goto error; + } + + /* + * Find the JCL group, and add if needed... + */ + + group = ppd_get_group(ppd, "JCL", _("JCL"), cg, encoding); + + if (group == NULL) + goto error; + + /* + * Add an option record to the current JCLs... + */ + + if (name[0] == '*') + _cups_strcpy(name, name + 1); + + option = ppd_get_option(group, name); + + if (option == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + /* + * Now fill in the initial information for the option... + */ + + if (string && !strcmp(string, "PickMany")) + option->ui = PPD_UI_PICKMANY; + else if (string && !strcmp(string, "Boolean")) + option->ui = PPD_UI_BOOLEAN; + else if (string && !strcmp(string, "PickOne")) + option->ui = PPD_UI_PICKONE; + else + { + cg->ppd_status = PPD_BAD_OPEN_UI; + + goto error; + } + + for (j = 0; j < ppd->num_attrs; j ++) + if (!strncmp(ppd->attrs[j]->name, "Default", 7) && + !strcmp(ppd->attrs[j]->name + 7, name) && + ppd->attrs[j]->value) + { + DEBUG_printf(("2ppdOpen2: Setting Default%s to %s via attribute...", + option->keyword, ppd->attrs[j]->value)); + strlcpy(option->defchoice, ppd->attrs[j]->value, + sizeof(option->defchoice)); + break; + } + + if (text[0]) + cupsCharsetToUTF8((cups_utf8_t *)option->text, text, + sizeof(option->text), encoding); + else + strlcpy(option->text, name, sizeof(option->text)); + + option->section = PPD_ORDER_JCL; + group = NULL; + + _cupsStrFree(string); + string = NULL; + + /* + * Add a custom option choice if we have already seen a CustomFoo + * attribute... + */ + + snprintf(custom_name, sizeof(custom_name), "Custom%s", name); + + if ((custom_attr = ppdFindAttr(ppd, custom_name, "True")) != NULL) + { + if ((choice = ppd_add_choice(option, "Custom")) == NULL) + { + DEBUG_puts("1ppdOpen2: Unable to add Custom choice!"); + + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + strlcpy(choice->text, + custom_attr->text[0] ? custom_attr->text : _("Custom"), + sizeof(choice->text)); + choice->code = _cupsStrRetain(custom_attr->value); + } + } + else if (!strcmp(keyword, "CloseUI") || !strcmp(keyword, "JCLCloseUI")) + { + option = NULL; + + _cupsStrFree(string); + string = NULL; + } + else if (!strcmp(keyword, "OpenGroup")) + { + /* + * Open a new group... + */ + + if (group != NULL) + { + cg->ppd_status = PPD_NESTED_OPEN_GROUP; + + goto error; + } + + if (!string) + { + cg->ppd_status = PPD_BAD_OPEN_GROUP; + + goto error; + } + + /* + * Separate the group name from the text (name/text)... + */ + + if ((sptr = strchr(string, '/')) != NULL) + *sptr++ = '\0'; + else + sptr = string; + + /* + * Fix up the text... + */ + + ppd_decode(sptr); + + /* + * Find/add the group... + */ + + group = ppd_get_group(ppd, string, sptr, cg, encoding); + + if (group == NULL) + goto error; + + _cupsStrFree(string); + string = NULL; + } + else if (!strcmp(keyword, "CloseGroup")) + { + group = NULL; + + _cupsStrFree(string); + string = NULL; + } + else if (!strcmp(keyword, "OrderDependency")) + { + order = (float)_cupsStrScand(string, &sptr, loc); + + if (!sptr || sscanf(sptr, "%40s%40s", name, keyword) != 2) + { + cg->ppd_status = PPD_BAD_ORDER_DEPENDENCY; + + goto error; + } + + if (keyword[0] == '*') + _cups_strcpy(keyword, keyword + 1); + + if (!strcmp(name, "ExitServer")) + section = PPD_ORDER_EXIT; + else if (!strcmp(name, "Prolog")) + section = PPD_ORDER_PROLOG; + else if (!strcmp(name, "DocumentSetup")) + section = PPD_ORDER_DOCUMENT; + else if (!strcmp(name, "PageSetup")) + section = PPD_ORDER_PAGE; + else if (!strcmp(name, "JCLSetup")) + section = PPD_ORDER_JCL; + else + section = PPD_ORDER_ANY; + + if (option == NULL) + { + ppd_group_t *gtemp; + + + /* + * Only valid for Non-UI options... + */ + + for (i = ppd->num_groups, gtemp = ppd->groups; i > 0; i --, gtemp ++) + if (gtemp->text[0] == '\0') + break; + + if (i > 0) + for (i = 0; i < gtemp->num_options; i ++) + if (!strcmp(keyword, gtemp->options[i].keyword)) + { + gtemp->options[i].section = section; + gtemp->options[i].order = order; + break; + } + } + else + { + option->section = section; + option->order = order; + } + + _cupsStrFree(string); + string = NULL; + } + else if (!strncmp(keyword, "Default", 7)) + { + if (string == NULL) + continue; + + /* + * Drop UI text, if any, from value... + */ + + if (strchr(string, '/') != NULL) + *strchr(string, '/') = '\0'; + + /* + * Assign the default value as appropriate... + */ + + if (!strcmp(keyword, "DefaultColorSpace")) + { + /* + * Set default colorspace... + */ + + if (!strcmp(string, "CMY")) + ppd->colorspace = PPD_CS_CMY; + else if (!strcmp(string, "CMYK")) + ppd->colorspace = PPD_CS_CMYK; + else if (!strcmp(string, "RGB")) + ppd->colorspace = PPD_CS_RGB; + else if (!strcmp(string, "RGBK")) + ppd->colorspace = PPD_CS_RGBK; + else if (!strcmp(string, "N")) + ppd->colorspace = PPD_CS_N; + else + ppd->colorspace = PPD_CS_GRAY; + } + else if (option && !strcmp(keyword + 7, option->keyword)) + { + /* + * Set the default as part of the current option... + */ + + DEBUG_printf(("2ppdOpen2: Setting %s to %s...", keyword, string)); + + strlcpy(option->defchoice, string, sizeof(option->defchoice)); + + DEBUG_printf(("2ppdOpen2: %s is now %s...", keyword, option->defchoice)); + } + else + { + /* + * Lookup option and set if it has been defined... + */ + + ppd_option_t *toption; /* Temporary option */ + + + if ((toption = ppdFindOption(ppd, keyword + 7)) != NULL) + { + DEBUG_printf(("2ppdOpen2: Setting %s to %s...", keyword, string)); + strlcpy(toption->defchoice, string, sizeof(toption->defchoice)); + } + } + } + else if (!strcmp(keyword, "UIConstraints") || + !strcmp(keyword, "NonUIConstraints")) + { + if (!string) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (ppd->num_consts == 0) + constraint = calloc(2, sizeof(ppd_const_t)); + else + constraint = realloc(ppd->consts, + (ppd->num_consts + 2) * sizeof(ppd_const_t)); + + if (constraint == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + 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 */ + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + + case 2 : /* Two options... */ + /* + * Check for broken constraints like "* Option"... + */ + + if (cg->ppd_conform == PPD_CONFORM_STRICT && + (!strcmp(constraint->option1, "*") || + !strcmp(constraint->choice1, "*"))) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + /* + * The following strcpy's are safe, as optionN and + * choiceN are all the same size (size defined by PPD spec...) + */ + + if (constraint->option1[0] == '*') + _cups_strcpy(constraint->option1, constraint->option1 + 1); + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (constraint->choice1[0] == '*') + _cups_strcpy(constraint->option2, constraint->choice1 + 1); + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + constraint->choice1[0] = '\0'; + constraint->choice2[0] = '\0'; + break; + + case 3 : /* Two options, one choice... */ + /* + * Check for broken constraints like "* Option"... + */ + + if (cg->ppd_conform == PPD_CONFORM_STRICT && + (!strcmp(constraint->option1, "*") || + !strcmp(constraint->choice1, "*") || + !strcmp(constraint->option2, "*"))) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + /* + * The following _cups_strcpy's are safe, as optionN and + * choiceN are all the same size (size defined by PPD spec...) + */ + + if (constraint->option1[0] == '*') + _cups_strcpy(constraint->option1, constraint->option1 + 1); + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (constraint->choice1[0] == '*') + { + if (cg->ppd_conform == PPD_CONFORM_STRICT && + constraint->option2[0] == '*') + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + _cups_strcpy(constraint->choice2, constraint->option2); + _cups_strcpy(constraint->option2, constraint->choice1 + 1); + constraint->choice1[0] = '\0'; + } + else + { + if (constraint->option2[0] == '*') + _cups_strcpy(constraint->option2, constraint->option2 + 1); + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + constraint->choice2[0] = '\0'; + } + break; + + case 4 : /* Two options, two choices... */ + /* + * Check for broken constraints like "* Option"... + */ + + if (cg->ppd_conform == PPD_CONFORM_STRICT && + (!strcmp(constraint->option1, "*") || + !strcmp(constraint->choice1, "*") || + !strcmp(constraint->option2, "*") || + !strcmp(constraint->choice2, "*"))) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (constraint->option1[0] == '*') + _cups_strcpy(constraint->option1, constraint->option1 + 1); + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (cg->ppd_conform == PPD_CONFORM_STRICT && + constraint->choice1[0] == '*') + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (constraint->option2[0] == '*') + _cups_strcpy(constraint->option2, constraint->option2 + 1); + else if (cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + + if (cg->ppd_conform == PPD_CONFORM_STRICT && + constraint->choice2[0] == '*') + { + cg->ppd_status = PPD_BAD_UI_CONSTRAINTS; + goto error; + } + break; + } + + /* + * Don't add this one as an attribute... + */ + + _cupsStrFree(string); + string = NULL; + } + else if (!strcmp(keyword, "PaperDimension")) + { + if ((size = ppdPageSize(ppd, name)) == NULL) + size = ppd_add_size(ppd, name); + + if (size == NULL) + { + /* + * Unable to add or find size! + */ + + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + size->width = (float)_cupsStrScand(string, &sptr, loc); + size->length = (float)_cupsStrScand(sptr, NULL, loc); + + _cupsStrFree(string); + string = NULL; + } + else if (!strcmp(keyword, "ImageableArea")) + { + if ((size = ppdPageSize(ppd, name)) == NULL) + size = ppd_add_size(ppd, name); + + if (size == NULL) + { + /* + * Unable to add or find size! + */ + + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + size->left = (float)_cupsStrScand(string, &sptr, loc); + size->bottom = (float)_cupsStrScand(sptr, &sptr, loc); + size->right = (float)_cupsStrScand(sptr, &sptr, loc); + size->top = (float)_cupsStrScand(sptr, NULL, loc); + + _cupsStrFree(string); + string = NULL; + } + else if (option != NULL && + (mask & (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) == + (PPD_KEYWORD | PPD_OPTION | PPD_STRING) && + !strcmp(keyword, option->keyword)) + { + DEBUG_printf(("2ppdOpen2: group=%p, subgroup=%p", group, subgroup)); + + if (!strcmp(keyword, "PageSize")) + { + /* + * Add a page size... + */ + + if (ppdPageSize(ppd, name) == NULL) + ppd_add_size(ppd, name); + } + + /* + * Add the option choice... + */ + + if ((choice = ppd_add_choice(option, name)) == NULL) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + goto error; + } + + if (text[0]) + cupsCharsetToUTF8((cups_utf8_t *)choice->text, text, + sizeof(choice->text), encoding); + else if (!strcmp(name, "True")) + strcpy(choice->text, _("Yes")); + else if (!strcmp(name, "False")) + 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 add as an attribute below */ + } + + /* + * Add remaining lines with keywords and string values as attributes... + */ + + if (string && + (mask & (PPD_KEYWORD | PPD_STRING)) == (PPD_KEYWORD | PPD_STRING)) + ppd_add_attr(ppd, keyword, name, text, string); + else + _cupsStrFree(string); + } + + ppd_free(line.buffer); + + /* + * Reset language preferences... + */ + + cupsLangFree(language); + +#ifdef DEBUG + if (!cupsFileEOF(fp)) + DEBUG_printf(("1ppdOpen2: Premature EOF at %lu...\n", + (unsigned long)cupsFileTell(fp))); +#endif /* DEBUG */ + + if (cg->ppd_status != PPD_OK) + { + /* + * Had an error reading the PPD file, cannot continue! + */ + + ppdClose(ppd); + + return (NULL); + } + + /* + * Create the sorted options array and set the option back-pointer for + * each choice and custom option... + */ + + ppd->options = cupsArrayNew2((cups_array_func_t)ppd_compare_options, NULL, + (cups_ahash_func_t)ppd_hash_option, + PPD_HASHSIZE); + + for (i = ppd->num_groups, group = ppd->groups; + i > 0; + i --, group ++) + { + for (j = group->num_options, option = group->options; + j > 0; + j --, option ++) + { + ppd_coption_t *coption; /* Custom option */ + + + cupsArrayAdd(ppd->options, option); + + for (k = 0; k < option->num_choices; k ++) + option->choices[k].option = option; + + if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL) + coption->option = option; + } + } + + /* + * Create an array to track the marked choices... + */ + + ppd->marked = cupsArrayNew((cups_array_func_t)ppd_compare_choices, NULL); + + /* + * Return the PPD file structure... + */ + + return (ppd); + + /* + * Common exit point for errors to save code size... + */ + + error: + + _cupsStrFree(string); + ppd_free(line.buffer); + + ppdClose(ppd); + + cupsLangFree(language); + + return (NULL); +} + + +/* + * 'ppdOpenFd()' - Read a PPD file into memory. + */ + +ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */ +ppdOpenFd(int fd) /* I - File to read from */ +{ + cups_file_t *fp; /* CUPS file pointer */ + ppd_file_t *ppd; /* PPD file record */ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + /* + * Set the line number to 0... + */ + + cg->ppd_line = 0; + + /* + * Range check input... + */ + + if (fd < 0) + { + cg->ppd_status = PPD_NULL_FILE; + + return (NULL); + } + + /* + * Try to open the file and parse it... + */ + + if ((fp = cupsFileOpenFd(fd, "r")) != NULL) + { + ppd = ppdOpen2(fp); + + cupsFileClose(fp); + } + else + { + cg->ppd_status = PPD_FILE_OPEN_ERROR; + ppd = NULL; + } + + return (ppd); +} + + +/* + * 'ppdOpenFile()' - Read a PPD file into memory. + */ + +ppd_file_t * /* O - PPD file record or @code NULL@ if the PPD file could not be opened. */ +ppdOpenFile(const char *filename) /* I - File to read from */ +{ + cups_file_t *fp; /* File pointer */ + ppd_file_t *ppd; /* PPD file record */ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + /* + * Set the line number to 0... + */ + + cg->ppd_line = 0; + + /* + * Range check input... + */ + + if (filename == NULL) + { + cg->ppd_status = PPD_NULL_FILE; + + return (NULL); + } + + /* + * Try to open the file and parse it... + */ + + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + ppd = ppdOpen2(fp); + + cupsFileClose(fp); + } + else + { + cg->ppd_status = PPD_FILE_OPEN_ERROR; + ppd = NULL; + } + + return (ppd); +} + + +/* + * 'ppdSetConformance()' - Set the conformance level for PPD files. + * + * @since CUPS 1.1.20/Mac OS X 10.4@ + */ + +void +ppdSetConformance(ppd_conform_t c) /* I - Conformance level */ +{ + _cups_globals_t *cg = _cupsGlobals(); + /* Global data */ + + + cg->ppd_conform = c; +} + + +/* + * 'ppd_add_attr()' - Add an attribute to the PPD data. + */ + +static ppd_attr_t * /* O - New attribute */ +ppd_add_attr(ppd_file_t *ppd, /* I - PPD file data */ + const char *name, /* I - Attribute name */ + const char *spec, /* I - Specifier string, if any */ + const char *text, /* I - Text string, if any */ + const char *value) /* I - Value of attribute */ +{ + ppd_attr_t **ptr, /* New array */ + *temp; /* New attribute */ + + + /* + * Range check input... + */ + + if (ppd == NULL || name == NULL || spec == NULL) + return (NULL); + + /* + * Create the array as needed... + */ + + if (!ppd->sorted_attrs) + ppd->sorted_attrs = cupsArrayNew((cups_array_func_t)ppd_compare_attrs, + NULL); + + /* + * Allocate memory for the new attribute... + */ + + if (ppd->num_attrs == 0) + ptr = malloc(sizeof(ppd_attr_t *)); + else + ptr = realloc(ppd->attrs, (ppd->num_attrs + 1) * sizeof(ppd_attr_t *)); + + if (ptr == NULL) + return (NULL); + + ppd->attrs = ptr; + ptr += ppd->num_attrs; + + if ((temp = calloc(1, sizeof(ppd_attr_t))) == NULL) + return (NULL); + + *ptr = temp; + + ppd->num_attrs ++; + + /* + * Copy data over... + */ + + strlcpy(temp->name, name, sizeof(temp->name)); + strlcpy(temp->spec, spec, sizeof(temp->spec)); + strlcpy(temp->text, text, sizeof(temp->text)); + temp->value = (char *)value; + + /* + * Add the attribute to the sorted array... + */ + + cupsArrayAdd(ppd->sorted_attrs, temp); + + /* + * Return the attribute... + */ + + return (temp); +} + + +/* + * '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 */ + const 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 */ + const 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); +} + + +/* + * 'ppd_compare_attrs()' - Compare two attributes. + */ + +static int /* O - Result of comparison */ +ppd_compare_attrs(ppd_attr_t *a, /* I - First attribute */ + ppd_attr_t *b) /* I - Second attribute */ +{ + return (strcasecmp(a->name, b->name)); +} + + +/* + * 'ppd_compare_choices()' - Compare two choices... + */ + +static int /* O - Result of comparison */ +ppd_compare_choices(ppd_choice_t *a, /* I - First choice */ + ppd_choice_t *b) /* I - Second choice */ +{ + return (strcmp(a->option->keyword, b->option->keyword)); +} + + +/* + * 'ppd_compare_coptions()' - Compare two custom options. + */ + +static int /* O - Result of comparison */ +ppd_compare_coptions(ppd_coption_t *a, /* I - First option */ + ppd_coption_t *b) /* I - Second option */ +{ + return (strcasecmp(a->keyword, b->keyword)); +} + + +/* + * 'ppd_compare_options()' - Compare two options. + */ + +static int /* O - Result of comparison */ +ppd_compare_options(ppd_option_t *a, /* I - First option */ + ppd_option_t *b) /* I - Second option */ +{ + return (strcasecmp(a->keyword, b->keyword)); +} + + +/* + * 'ppd_decode()' - Decode a string value... + */ + +static int /* O - Length of decoded string */ +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] & 255)) + { + /* + * Convert hex to 8-bit values... + */ + + inptr ++; + while (isxdigit(*inptr & 255)) + { + if (_cups_isalpha(*inptr)) + *outptr = (tolower(*inptr) - 'a' + 10) << 4; + else + *outptr = (*inptr - '0') << 4; + + inptr ++; + + if (!isxdigit(*inptr & 255)) + break; + + if (_cups_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'; + + return ((int)(outptr - string)); +} + + +/* + * '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); + + ppd_free(group->options); + } + + if (group->num_subgroups > 0) + { + for (i = group->num_subgroups, subgroup = group->subgroups; + i > 0; + i --, subgroup ++) + ppd_free_group(subgroup); + + ppd_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 ++) + { + _cupsStrFree(choice->code); + } + + ppd_free(option->choices); + } +} + + +/* + * 'ppd_get_coption()' - Get a custom option record. + */ + +static ppd_coption_t * /* O - Custom option... */ +ppd_get_coption(ppd_file_t *ppd, /* I - PPD file */ + const char *name) /* I - Name of option */ +{ + ppd_coption_t *copt; /* New custom option */ + + + /* + * See if the option already exists... + */ + + if ((copt = ppdFindCustomOption(ppd, name)) != NULL) + return (copt); + + /* + * Not found, so create the custom option record... + */ + + if ((copt = calloc(1, sizeof(ppd_coption_t))) == NULL) + return (NULL); + + strlcpy(copt->keyword, name, sizeof(copt->keyword)); + + copt->params = cupsArrayNew((cups_array_func_t)NULL, NULL); + + cupsArrayAdd(ppd->coptions, copt); + + /* + * Return the new record... + */ + + return (copt); +} + + +/* + * 'ppd_get_cparam()' - Get a custom parameter record. + */ + +static ppd_cparam_t * /* O - Extended option... */ +ppd_get_cparam(ppd_coption_t *opt, /* I - PPD file */ + const char *param, /* I - Name of parameter */ + const char *text) /* I - Human-readable text */ +{ + ppd_cparam_t *cparam; /* New custom parameter */ + + + /* + * See if the parameter already exists... + */ + + if ((cparam = ppdFindCustomParam(opt, param)) != NULL) + return (cparam); + + /* + * Not found, so create the custom parameter record... + */ + + if ((cparam = calloc(1, sizeof(ppd_cparam_t))) == NULL) + return (NULL); + + strlcpy(cparam->name, param, sizeof(cparam->name)); + strlcpy(cparam->text, text[0] ? text : param, sizeof(cparam->text)); + + /* + * Add this record to the array... + */ + + cupsArrayAdd(opt->params, cparam); + + /* + * Return the new record... + */ + + return (cparam); +} + + +/* + * '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 */ + const char *name, /* I - Name of group */ + const char *text, /* I - Text for group */ + _cups_globals_t *cg, /* I - Global data */ + cups_encoding_t encoding) /* I - Encoding of text */ +{ + int i; /* Looping var */ + ppd_group_t *group; /* Group */ + + + DEBUG_printf(("7ppd_get_group(ppd=%p, name=\"%s\", text=\"%s\", cg=%p)", + ppd, name, text, cg)); + + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + if (!strcmp(group->name, name)) + break; + + if (i == 0) + { + DEBUG_printf(("8ppd_get_group: Adding group %s...", name)); + + if (cg->ppd_conform == PPD_CONFORM_STRICT && strlen(text) >= sizeof(group->text)) + { + cg->ppd_status = PPD_ILLEGAL_TRANSLATION; + + return (NULL); + } + + 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) + { + cg->ppd_status = PPD_ALLOC_ERROR; + + return (NULL); + } + + ppd->groups = group; + group += ppd->num_groups; + ppd->num_groups ++; + + memset(group, 0, sizeof(ppd_group_t)); + strlcpy(group->name, name, sizeof(group->name)); + + cupsCharsetToUTF8((cups_utf8_t *)group->text, text, + sizeof(group->text), encoding); + } + + 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 */ + const char *name) /* I - Name of option */ +{ + int i; /* Looping var */ + ppd_option_t *option; /* Option */ + + + DEBUG_printf(("7ppd_get_option(group=%p(\"%s\"), name=\"%s\")", + group, group->name, name)); + + for (i = group->num_options, option = group->options; i > 0; i --, option ++) + if (!strcmp(option->keyword, name)) + 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_hash_option()' - Generate a hash of the option name... + */ + +static int /* O - Hash index */ +ppd_hash_option(ppd_option_t *option) /* I - Option */ +{ + int hash = 0; /* Hash index */ + const char *k; /* Pointer into keyword */ + + + for (hash = option->keyword[0], k = option->keyword + 1; *k;) + hash = 33 * hash + *k++; + + return (hash & 511); +} + + +/* + * 'ppd_read()' - Read a line from a PPD file, skipping comment lines as + * necessary. + */ + +static int /* O - Bitmask of fields read */ +ppd_read(cups_file_t *fp, /* I - File to read from */ + _ppd_line_t *line, /* I - Line buffer */ + 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 ignoreblank, /* I - Ignore blank lines? */ + _cups_globals_t *cg) /* I - Global data */ +{ + int ch, /* Character from file */ + col, /* Column in line */ + colon, /* Colon seen? */ + endquote, /* Waiting for an end quote */ + mask, /* Mask to be returned */ + startline, /* Start line */ + textlen; /* Length of text */ + char *keyptr, /* Keyword pointer */ + *optptr, /* Option pointer */ + *textptr, /* Text pointer */ + *strptr, /* Pointer into string */ + *lineptr; /* Current position in line buffer */ + + + /* + * Now loop until we have a valid line... + */ + + *string = NULL; + col = 0; + startline = cg->ppd_line + 1; + + if (!line->buffer) + { + line->bufsize = 1024; + line->buffer = malloc(1024); + + if (!line->buffer) + return (0); + } + + do + { + /* + * Read the line... + */ + + lineptr = line->buffer; + endquote = 0; + colon = 0; + + while ((ch = cupsFileGetChar(fp)) != EOF) + { + if (lineptr >= (line->buffer + line->bufsize - 1)) + { + /* + * Expand the line buffer... + */ + + char *temp; /* Temporary line pointer */ + + + line->bufsize += 1024; + if (line->bufsize > 262144) + { + /* + * Don't allow lines longer than 256k! + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_LINE_TOO_LONG; + + return (0); + } + + temp = realloc(line->buffer, line->bufsize); + if (!temp) + { + cg->ppd_line = startline; + cg->ppd_status = PPD_LINE_TOO_LONG; + + return (0); + } + + lineptr = temp + (lineptr - line->buffer); + line->buffer = temp; + } + + if (ch == '\r' || ch == '\n') + { + /* + * Line feed or carriage return... + */ + + cg->ppd_line ++; + col = 0; + + if (ch == '\r') + { + /* + * Check for a trailing line feed... + */ + + if ((ch = cupsFilePeekChar(fp)) == EOF) + { + ch = '\n'; + break; + } + + if (ch == 0x0a) + cupsFileGetChar(fp); + } + + if (lineptr == line->buffer && ignoreblank) + continue; /* Skip blank lines */ + + ch = '\n'; + + if (!endquote) /* Continue for multi-line text */ + break; + + *lineptr++ = '\n'; + } + else if (ch < ' ' && ch != '\t' && cg->ppd_conform == PPD_CONFORM_STRICT) + { + /* + * Other control characters... + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_ILLEGAL_CHARACTER; + + return (0); + } + else if (ch != 0x1a) + { + /* + * Any other character... + */ + + *lineptr++ = ch; + col ++; + + if (col > (PPD_MAX_LINE - 1)) + { + /* + * Line is too long... + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_LINE_TOO_LONG; + + return (0); + } + + if (ch == ':' && strncmp(line->buffer, "*%", 2) != 0) + colon = 1; + + if (ch == '\"' && colon) + endquote = !endquote; + } + } + + if (endquote) + { + /* + * Didn't finish this quoted string... + */ + + while ((ch = cupsFileGetChar(fp)) != EOF) + if (ch == '\"') + break; + else if (ch == '\r' || ch == '\n') + { + cg->ppd_line ++; + col = 0; + + if (ch == '\r') + { + /* + * Check for a trailing line feed... + */ + + if ((ch = cupsFilePeekChar(fp)) == EOF) + break; + if (ch == 0x0a) + cupsFileGetChar(fp); + } + } + else if (ch < ' ' && ch != '\t' && cg->ppd_conform == PPD_CONFORM_STRICT) + { + /* + * Other control characters... + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_ILLEGAL_CHARACTER; + + return (0); + } + else if (ch != 0x1a) + { + col ++; + + if (col > (PPD_MAX_LINE - 1)) + { + /* + * Line is too long... + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_LINE_TOO_LONG; + + return (0); + } + } + } + + if (ch != '\n') + { + /* + * Didn't finish this line... + */ + + while ((ch = cupsFileGetChar(fp)) != EOF) + if (ch == '\r' || ch == '\n') + { + /* + * Line feed or carriage return... + */ + + cg->ppd_line ++; + col = 0; + + if (ch == '\r') + { + /* + * Check for a trailing line feed... + */ + + if ((ch = cupsFilePeekChar(fp)) == EOF) + break; + if (ch == 0x0a) + cupsFileGetChar(fp); + } + + break; + } + else if (ch < ' ' && ch != '\t' && cg->ppd_conform == PPD_CONFORM_STRICT) + { + /* + * Other control characters... + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_ILLEGAL_CHARACTER; + + return (0); + } + else if (ch != 0x1a) + { + col ++; + + if (col > (PPD_MAX_LINE - 1)) + { + /* + * Line is too long... + */ + + cg->ppd_line = startline; + cg->ppd_status = PPD_LINE_TOO_LONG; + + return (0); + } + } + } + + if (lineptr > line->buffer && lineptr[-1] == '\n') + lineptr --; + + *lineptr = '\0'; + + DEBUG_printf(("9ppd_read: LINE=\"%s\"", line->buffer)); + + /* + * The dynamically created PPDs for older style Mac OS X + * drivers include a large blob of data inserted as comments + * at the end of the file. As an optimization we can stop + * reading the PPD when we get to the start of this data. + */ + + if (!strcmp(line->buffer, "*%APLWORKSET START")) + return (0); + + if (ch == EOF && lineptr == line->buffer) + return (0); + + /* + * Now parse it... + */ + + mask = 0; + lineptr = line->buffer + 1; + + keyword[0] = '\0'; + option[0] = '\0'; + text[0] = '\0'; + *string = NULL; + + if ((!line->buffer[0] || /* Blank line */ + !strncmp(line->buffer, "*%", 2) || /* Comment line */ + !strcmp(line->buffer, "*End")) && /* End of multi-line string */ + ignoreblank) /* Ignore these? */ + { + startline = cg->ppd_line + 1; + continue; + } + + if (!strcmp(line->buffer, "*")) /* (Bad) comment line */ + { + if (cg->ppd_conform == PPD_CONFORM_RELAXED) + { + startline = cg->ppd_line + 1; + continue; + } + else + { + cg->ppd_line = startline; + cg->ppd_status = PPD_ILLEGAL_MAIN_KEYWORD; + + return (0); + } + } + + if (line->buffer[0] != '*') /* All lines start with an asterisk */ + { + /* + * Allow lines consisting of just whitespace... + */ + + for (lineptr = line->buffer; *lineptr; lineptr ++) + if (*lineptr && !_cups_isspace(*lineptr)) + break; + + if (*lineptr) + { + cg->ppd_status = PPD_MISSING_ASTERISK; + return (0); + } + else if (ignoreblank) + continue; + else + return (0); + } + + /* + * Get a keyword... + */ + + keyptr = keyword; + + while (*lineptr && *lineptr != ':' && !_cups_isspace(*lineptr)) + { + if (*lineptr <= ' ' || *lineptr > 126 || *lineptr == '/' || + (keyptr - keyword) >= (PPD_MAX_NAME - 1)) + { + cg->ppd_status = PPD_ILLEGAL_MAIN_KEYWORD; + return (0); + } + + *keyptr++ = *lineptr++; + } + + *keyptr = '\0'; + + if (!strcmp(keyword, "End")) + continue; + + mask |= PPD_KEYWORD; + + if (_cups_isspace(*lineptr)) + { + /* + * Get an option name... + */ + + while (_cups_isspace(*lineptr)) + lineptr ++; + + optptr = option; + + while (*lineptr && !_cups_isspace(*lineptr) && *lineptr != ':' && + *lineptr != '/') + { + if (*lineptr <= ' ' || *lineptr > 126 || + (optptr - option) >= (PPD_MAX_NAME - 1)) + { + cg->ppd_status = PPD_ILLEGAL_OPTION_KEYWORD; + return (0); + } + + *optptr++ = *lineptr++; + } + + *optptr = '\0'; + + if (_cups_isspace(*lineptr) && cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_ILLEGAL_WHITESPACE; + return (0); + } + + while (_cups_isspace(*lineptr)) + lineptr ++; + + mask |= PPD_OPTION; + + if (*lineptr == '/') + { + /* + * Get human-readable text... + */ + + lineptr ++; + + textptr = text; + + while (*lineptr != '\0' && *lineptr != '\n' && *lineptr != ':') + { + if (((unsigned char)*lineptr < ' ' && *lineptr != '\t') || + (textptr - text) >= (PPD_MAX_LINE - 1)) + { + cg->ppd_status = PPD_ILLEGAL_TRANSLATION; + return (0); + } + + *textptr++ = *lineptr++; + } + + *textptr = '\0'; + textlen = ppd_decode(text); + + if (textlen > PPD_MAX_TEXT && cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_ILLEGAL_TRANSLATION; + return (0); + } + + mask |= PPD_TEXT; + } + } + + if (_cups_isspace(*lineptr) && cg->ppd_conform == PPD_CONFORM_STRICT) + { + cg->ppd_status = PPD_ILLEGAL_WHITESPACE; + return (0); + } + + while (_cups_isspace(*lineptr)) + lineptr ++; + + if (*lineptr == ':') + { + /* + * Get string after triming leading and trailing whitespace... + */ + + lineptr ++; + while (_cups_isspace(*lineptr)) + lineptr ++; + + strptr = lineptr + strlen(lineptr) - 1; + while (strptr >= lineptr && _cups_isspace(*strptr)) + *strptr-- = '\0'; + + if (*strptr == '\"') + { + /* + * Quoted string by itself, remove quotes... + */ + + *strptr = '\0'; + lineptr ++; + } + + *string = _cupsStrAlloc(lineptr); + + mask |= PPD_STRING; + } + } + while (mask == 0); + + return (mask); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/ppd.h b/cups/ppd.h new file mode 100644 index 0000000000..060531c193 --- /dev/null +++ b/cups/ppd.h @@ -0,0 +1,434 @@ +/* + * "$Id$" + * + * PostScript Printer Description definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +# include "array.h" +# include "file.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 ppd_ui_e /**** 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 ppd_section_e /**** 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 ppd_cs_e /**** 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 enum ppd_status_e /**** Status Codes @since CUPS 1.1.19/Mac OS X 10.3@ ****/ +{ + PPD_OK = 0, /* OK */ + PPD_FILE_OPEN_ERROR, /* Unable to open PPD file */ + PPD_NULL_FILE, /* NULL PPD file pointer */ + PPD_ALLOC_ERROR, /* Memory allocation error */ + PPD_MISSING_PPDADOBE4, /* Missing PPD-Adobe-4.x header */ + PPD_MISSING_VALUE, /* Missing value string */ + PPD_INTERNAL_ERROR, /* Internal error */ + PPD_BAD_OPEN_GROUP, /* Bad OpenGroup */ + PPD_NESTED_OPEN_GROUP, /* OpenGroup without a CloseGroup first */ + PPD_BAD_OPEN_UI, /* Bad OpenUI/JCLOpenUI */ + PPD_NESTED_OPEN_UI, /* OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first */ + PPD_BAD_ORDER_DEPENDENCY, /* Bad OrderDependency */ + PPD_BAD_UI_CONSTRAINTS, /* Bad UIConstraints */ + PPD_MISSING_ASTERISK, /* Missing asterisk in column 0 */ + PPD_LINE_TOO_LONG, /* Line longer than 255 chars */ + PPD_ILLEGAL_CHARACTER, /* Illegal control character */ + PPD_ILLEGAL_MAIN_KEYWORD, /* Illegal main keyword string */ + PPD_ILLEGAL_OPTION_KEYWORD, /* Illegal option keyword string */ + PPD_ILLEGAL_TRANSLATION, /* Illegal translation string */ + PPD_ILLEGAL_WHITESPACE, /* Illegal whitespace character */ + PPD_BAD_CUSTOM_PARAM, /* Bad custom parameter */ + PPD_MISSING_OPTION_KEYWORD, /* Missing option keyword */ + PPD_BAD_VALUE, /* Bad value string */ + PPD_MAX_STATUS /* @private@ */ +} ppd_status_t; + +enum ppd_conform_e /**** Conformance Levels @since CUPS 1.1.19/Mac OS X 10.3@ ****/ +{ + PPD_CONFORM_RELAXED, /* Relax whitespace and control char */ + PPD_CONFORM_STRICT /* Require strict conformance */ +}; + +typedef enum ppd_conform_e ppd_conform_t; + /**** Conformance Levels @since CUPS 1.1.19/Mac OS X 10.3@ ****/ + +typedef struct ppd_attr_s /**** PPD Attribute Structure @since CUPS 1.1.19/Mac OS X 10.3@ ****/ +{ + char name[PPD_MAX_NAME]; /* Name of attribute (cupsXYZ) */ + char spec[PPD_MAX_NAME]; /* Specifier string, if any */ + char text[PPD_MAX_TEXT]; /* Human-readable text, if any */ + char *value; /* Value string */ +} ppd_attr_t; + +typedef struct ppd_option_s ppd_option_t; + /**** Options ****/ + +typedef struct ppd_choice_s /**** Option choices ****/ +{ + char marked; /* 0 if not selected, 1 otherwise */ + char choice[PPD_MAX_NAME]; /* Computer-readable option name */ + char text[PPD_MAX_TEXT]; /* Human-readable option name */ + char *code; /* Code to send for this option */ + ppd_option_t *option; /* Pointer to parent option structure */ +} ppd_choice_t; + +struct ppd_option_s /**** Options ****/ +{ + char conflicted; /* 0 if no conflicts exist, 1 otherwise */ + char keyword[PPD_MAX_NAME]; /* Option keyword name ("PageSize", etc.) */ + char defchoice[PPD_MAX_NAME];/* Default option choice */ + char 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 */ +}; + +typedef struct ppd_group_s /**** Groups ****/ +{ + /**** Group text strings are limited to 39 chars + nul in order to + **** preserve binary compatibility and allow applications to get + **** the group's keyword name. + ****/ + char text[PPD_MAX_TEXT - PPD_MAX_NAME]; + /* Human-readable group name */ + char name[PPD_MAX_NAME]; /* Group name @since CUPS 1.1.18/Mac OS X 10.3@ */ + int num_options; /* Number of options */ + ppd_option_t *options; /* Options */ + int num_subgroups; /* Number of sub-groups */ + struct ppd_group_s *subgroups; /* Sub-groups (max depth = 1) */ +} ppd_group_t; + +typedef struct ppd_const_s /**** Constraints ****/ +{ + char option1[PPD_MAX_NAME]; /* First keyword */ + char choice1[PPD_MAX_NAME]; /* First option/choice (blank for all) */ + char option2[PPD_MAX_NAME]; /* Second keyword */ + char choice2[PPD_MAX_NAME]; /* Second option/choice (blank for all) */ +} ppd_const_t; + +typedef struct ppd_size_s /**** Page Sizes ****/ +{ + int marked; /* Page size selected? */ + char name[PPD_MAX_NAME]; /* Media size option */ + float width; /* Width of media in points */ + float length; /* Length of media in points */ + float left; /* Left printable margin in points */ + float bottom; /* Bottom printable margin in points */ + float right; /* Right printable margin in points */ + float top; /* Top printable margin in points */ +} ppd_size_t; + +typedef struct ppd_emul_s /**** Emulators ****/ +{ + char name[PPD_MAX_NAME]; /* Emulator name */ + char *start; /* Code to switch to this emulation */ + char *stop; /* Code to stop this emulation */ +} ppd_emul_t; + +typedef struct ppd_profile_s /**** sRGB Color Profiles ****/ +{ + char resolution[PPD_MAX_NAME]; + /* Resolution or "-" */ + char media_type[PPD_MAX_NAME]; + /* Media type or "-" */ + float density; /* Ink density to use */ + float gamma; /* Gamma correction to use */ + float matrix[3][3]; /* Transform matrix */ +} ppd_profile_t; + +/**** New in CUPS 1.2/Mac OS X 10.5 ****/ +typedef enum ppd_cptype_e /**** Custom Parameter Type @since CUPS 1.2/Mac OS X 10.5@ ****/ +{ + PPD_CUSTOM_CURVE, /* Curve value for f(x) = x^value */ + PPD_CUSTOM_INT, /* Integer number value */ + PPD_CUSTOM_INVCURVE, /* Curve value for f(x) = x^(1/value) */ + PPD_CUSTOM_PASSCODE, /* String of (hidden) numbers */ + PPD_CUSTOM_PASSWORD, /* String of (hidden) characters */ + PPD_CUSTOM_POINTS, /* Measurement value in points */ + PPD_CUSTOM_REAL, /* Real number value */ + PPD_CUSTOM_STRING /* String of characters */ +} ppd_cptype_t; + +typedef union ppd_cplimit_u /**** Custom Parameter Limit @since CUPS 1.2/Mac OS X 10.5@ ****/ +{ + float custom_curve; /* Gamma value */ + int custom_int; /* Integer value */ + float custom_invcurve; /* Gamma value */ + int custom_passcode; /* Passcode length */ + int custom_password; /* Password length */ + float custom_points; /* Measurement value */ + float custom_real; /* Real value */ + int custom_string; /* String length */ +} ppd_cplimit_t; + +typedef union ppd_cpvalue_u /**** Custom Parameter Value @since CUPS 1.2/Mac OS X 10.5@ ****/ +{ + float custom_curve; /* Gamma value */ + int custom_int; /* Integer value */ + float custom_invcurve; /* Gamma value */ + char *custom_passcode; /* Passcode value */ + char *custom_password; /* Password value */ + float custom_points; /* Measurement value */ + float custom_real; /* Real value */ + char *custom_string; /* String value */ +} ppd_cpvalue_t; + +typedef struct ppd_cparam_s /**** Custom Parameter @since CUPS 1.2/Mac OS X 10.5@ ****/ +{ + char name[PPD_MAX_NAME]; /* Parameter name */ + char text[PPD_MAX_TEXT]; /* Human-readable text */ + int order; /* Order (0 to N) */ + ppd_cptype_t type; /* Parameter type */ + ppd_cplimit_t minimum, /* Minimum value */ + maximum; /* Maximum value */ + ppd_cpvalue_t current; /* Current value */ +} ppd_cparam_t; + +typedef struct ppd_coption_s /**** Custom Option @since CUPS 1.2/Mac OS X 10.5@ ****/ +{ + char keyword[PPD_MAX_NAME]; /* Name of option that is being extended... */ + ppd_option_t *option; /* Option that is being extended... */ + int marked; /* Extended option is marked */ + cups_array_t *params; /* Parameters */ +} ppd_coption_t; + +typedef struct ppd_file_s /**** PPD File ****/ +{ + int language_level; /* Language level of device */ + int color_device; /* 1 = color device, 0 = grayscale */ + int variable_sizes; /* 1 = supports variable sizes, 0 = doesn't */ + int accurate_screens; /* 1 = supports accurate screens, 0 = not */ + int contone_only; /* 1 = continuous tone only, 0 = not */ + int landscape; /* -90 or 90 */ + int model_number; /* Device-specific model number */ + int manual_copies; /* 1 = Copies done manually, 0 = hardware */ + int 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 */ + char *jcl_ps; /* Enter PostScript interpreter */ + char *jcl_end; /* End JCL commands */ + char *lang_encoding; /* Language encoding */ + char *lang_version; /* Language version (English, Spanish, etc.) */ + char *modelname; /* Model name (general) */ + char *ttrasterizer; /* Truetype rasterizer */ + char *manufacturer; /* Manufacturer name */ + char *product; /* Product name (from PS RIP/interpreter) */ + char *nickname; /* Nickname (specific) */ + char *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 */ + float custom_max[2]; /* Maximum variable page size */ + float 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 @deprecated@ */ + ppd_profile_t *profiles; /* sRGB color profiles @deprecated@ */ + int num_filters; /* Number of filters */ + char **filters; /* Filter strings... */ + + /**** New in CUPS 1.1 ****/ + int flip_duplex; /* 1 = Flip page for back sides @deprecated@ */ + + /**** New in CUPS 1.1.19 ****/ + char *protocols; /* Protocols (BCP, TBCP) string @since CUPS 1.1.19/Mac OS X 10.3@ */ + char *pcfilename; /* PCFileName string @since CUPS 1.1.19/Mac OS X 10.3@ */ + int num_attrs; /* Number of attributes @since CUPS 1.1.19/Mac OS X 10.3@ @private@ */ + int cur_attr; /* Current attribute @since CUPS 1.1.19/Mac OS X 10.3@ @private@ */ + ppd_attr_t **attrs; /* Attributes @since CUPS 1.1.19/Mac OS X 10.3@ @private@ */ + + /**** New in CUPS 1.2/Mac OS X 10.5 ****/ + cups_array_t *sorted_attrs; /* Attribute lookup array @since CUPS 1.2/Mac OS X 10.5@ @private@ */ + cups_array_t *options; /* Option lookup array @since CUPS 1.2/Mac OS X 10.5@ @private@ */ + cups_array_t *coptions; /* Custom options array @since CUPS 1.2/Mac OS X 10.5@ @private@ */ + + /**** New in CUPS 1.3/Mac OS X 10.5 ****/ + cups_array_t *marked; /* Marked choices @since CUPS 1.3/Mac OS X 10.5@ @private@ */ + + /**** New in CUPS 1.4/Mac OS X 10.6 ****/ + cups_array_t *cups_uiconstraints; /* cupsUIConstraints @since CUPS 1.4/Mac OS X 10.6@ @private@ */ + + /**** New in CUPS 1.5 ****/ + void *pwg; /* PWG to/from PPD mappings */ +} 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 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 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_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); + +/**** New in CUPS 1.1.19 ****/ +extern const char *ppdErrorString(ppd_status_t status) _CUPS_API_1_1_19; +extern ppd_attr_t *ppdFindAttr(ppd_file_t *ppd, const char *name, + const char *spec) _CUPS_API_1_1_19; +extern ppd_attr_t *ppdFindNextAttr(ppd_file_t *ppd, const char *name, + const char *spec) _CUPS_API_1_1_19; +extern ppd_status_t ppdLastError(int *line) _CUPS_API_1_1_19; + +/**** New in CUPS 1.1.20 ****/ +extern void ppdSetConformance(ppd_conform_t c) _CUPS_API_1_1_20; + +/**** New in CUPS 1.2 ****/ +extern int ppdCollect2(ppd_file_t *ppd, ppd_section_t section, + float min_order, ppd_choice_t ***choices) _CUPS_API_1_2; +extern int ppdEmitAfterOrder(ppd_file_t *ppd, FILE *fp, + ppd_section_t section, int limit, + float min_order) _CUPS_API_1_2; +extern int ppdEmitJCLEnd(ppd_file_t *ppd, FILE *fp) _CUPS_API_1_2; +extern char *ppdEmitString(ppd_file_t *ppd, ppd_section_t section, + float min_order) _CUPS_API_1_2; +extern ppd_coption_t *ppdFindCustomOption(ppd_file_t *ppd, + const char *keyword) _CUPS_API_1_2; +extern ppd_cparam_t *ppdFindCustomParam(ppd_coption_t *opt, + const char *name) _CUPS_API_1_2; +extern ppd_cparam_t *ppdFirstCustomParam(ppd_coption_t *opt) _CUPS_API_1_2; +extern ppd_option_t *ppdFirstOption(ppd_file_t *ppd) _CUPS_API_1_2; +extern ppd_cparam_t *ppdNextCustomParam(ppd_coption_t *opt) _CUPS_API_1_2; +extern ppd_option_t *ppdNextOption(ppd_file_t *ppd) _CUPS_API_1_2; +extern int ppdLocalize(ppd_file_t *ppd) _CUPS_API_1_2; +extern ppd_file_t *ppdOpen2(cups_file_t *fp) _CUPS_API_1_2; + +/**** New in CUPS 1.3/Mac OS X 10.5 ****/ +extern const char *ppdLocalizeIPPReason(ppd_file_t *ppd, + const char *reason, + const char *scheme, + char *buffer, + size_t bufsize) _CUPS_API_1_3; + +/**** New in CUPS 1.4/Mac OS X 10.6 ****/ +extern int ppdInstallableConflict(ppd_file_t *ppd, + const char *option, + const char *choice) + _CUPS_API_1_4; +extern ppd_attr_t *ppdLocalizeAttr(ppd_file_t *ppd, const char *keyword, + const char *spec) _CUPS_API_1_4; +extern const char *ppdLocalizeMarkerName(ppd_file_t *ppd, + const char *name) _CUPS_API_1_4; +extern int ppdPageSizeLimits(ppd_file_t *ppd, + ppd_size_t *minimum, + ppd_size_t *maximum) _CUPS_API_1_4; + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_PPD_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/pwg-file.c b/cups/pwg-file.c new file mode 100644 index 0000000000..c5722f1cf1 --- /dev/null +++ b/cups/pwg-file.c @@ -0,0 +1,639 @@ +/* + * "$Id$" + * + * PWG load/save API implementation for CUPS. + * + * Copyright 2010 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _pwgCreateWithFile() - Create PWG mapping data from a written file. + * _pwgDestroy() - Free all memory used for PWG mapping data. + * _pwgWriteFile() - Write PWG mapping data to a file. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include + + +/* + * '_pwgCreateWithFile()' - Create PWG mapping data from a written file. + * + * Use the @link _pwgWriteFile@ function to write PWG mapping data to a file. + */ + +_pwg_t * /* O - PWG mapping data */ +_pwgCreateWithFile(const char *filename)/* I - File to read */ +{ + cups_file_t *fp; /* File */ + _pwg_t *pwg; /* PWG mapping data */ + _pwg_size_t *size; /* Current size */ + _pwg_map_t *map; /* Current map */ + int linenum, /* Current line number */ + num_bins, /* Number of bins in file */ + num_sizes, /* Number of sizes in file */ + num_sources, /* Number of sources in file */ + num_types; /* Number of types in file */ + char line[2048], /* Current line */ + *value, /* Pointer to value in line */ + *valueptr, /* Pointer into value */ + pwg_keyword[128], /* PWG keyword */ + ppd_keyword[PPD_MAX_NAME]; + /* PPD keyword */ + _pwg_output_mode_t output_mode; /* Output mode for preset */ + _pwg_print_quality_t print_quality; /* Print quality for preset */ + + + DEBUG_printf(("_pwgCreateWithFile(filename=\"%s\")", filename)); + + /* + * Range check input... + */ + + if (!filename) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + return (NULL); + } + + /* + * Open the file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + return (NULL); + } + + /* + * Allocate the mapping data structure... + */ + + if ((pwg = calloc(1, sizeof(_pwg_t))) == NULL) + { + DEBUG_puts("_pwgCreateWithFile: Unable to allocate pwg_t."); + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + goto create_error; + } + + /* + * Read the file... + */ + + linenum = 0; + num_bins = 0; + num_sizes = 0; + num_sources = 0; + num_types = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + DEBUG_printf(("_pwgCreateWithFile: line=\"%s\", value=\"%s\", linenum=%d", + line, value, linenum)); + + if (!value) + { + DEBUG_printf(("_pwgCreateWithFile: Missing value on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + else if (!strcasecmp(line, "NumBins")) + { + if (num_bins > 0) + { + DEBUG_puts("_pwgCreateWithFile: NumBins listed multiple times."); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((num_bins = atoi(value)) <= 0 || num_bins > 65536) + { + DEBUG_printf(("_pwgCreateWithFile: Bad NumBins value %d on line %d.", + num_sizes, linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((pwg->bins = calloc(num_bins, sizeof(_pwg_map_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d bins.", + num_sizes)); + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + goto create_error; + } + } + else if (!strcasecmp(line, "Bin")) + { + if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2) + { + DEBUG_printf(("_pwgCreateWithFile: Bad Bin on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if (pwg->num_bins >= num_bins) + { + DEBUG_printf(("_pwgCreateWithFile: Too many Bin's on line %d.", + linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + map = pwg->bins + pwg->num_bins; + map->pwg = _cupsStrAlloc(pwg_keyword); + map->ppd = _cupsStrAlloc(ppd_keyword); + + pwg->num_bins ++; + } + else if (!strcasecmp(line, "NumSizes")) + { + if (num_sizes > 0) + { + DEBUG_puts("_pwgCreateWithFile: NumSizes listed multiple times."); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536) + { + DEBUG_printf(("_pwgCreateWithFile: Bad NumSizes value %d on line %d.", + num_sizes, linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((pwg->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sizes.", + num_sizes)); + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + goto create_error; + } + } + else if (!strcasecmp(line, "Size")) + { + if (pwg->num_sizes >= num_sizes) + { + DEBUG_printf(("_pwgCreateWithFile: Too many Size's on line %d.", + linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + size = pwg->sizes + pwg->num_sizes; + + if (sscanf(value, "%127s%40s%d%d%d%d%d%d", pwg_keyword, ppd_keyword, + &(size->width), &(size->length), &(size->left), + &(size->bottom), &(size->right), &(size->top)) != 8) + { + DEBUG_printf(("_pwgCreateWithFile: Bad Size on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + size->map.pwg = _cupsStrAlloc(pwg_keyword); + size->map.ppd = _cupsStrAlloc(ppd_keyword); + + pwg->num_sizes ++; + } + else if (!strcasecmp(line, "CustomSize")) + { + if (pwg->custom_max_width > 0) + { + DEBUG_printf(("_pwgCreateWithFile: Too many CustomSize's on line %d.", + linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if (sscanf(value, "%d%d%d%d%d%d%d%d", &(pwg->custom_max_width), + &(pwg->custom_max_length), &(pwg->custom_min_width), + &(pwg->custom_min_length), &(pwg->custom_size.left), + &(pwg->custom_size.bottom), &(pwg->custom_size.right), + &(pwg->custom_size.top)) != 8) + { + DEBUG_printf(("_pwgCreateWithFile: Bad CustomSize on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max", + pwg->custom_max_width, pwg->custom_max_length); + pwg->custom_max_keyword = _cupsStrAlloc(pwg_keyword); + + _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min", + pwg->custom_min_width, pwg->custom_min_length); + pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword); + } + else if (!strcasecmp(line, "SourceOption")) + { + pwg->source_option = _cupsStrAlloc(value); + } + else if (!strcasecmp(line, "NumSources")) + { + if (num_sources > 0) + { + DEBUG_puts("_pwgCreateWithFile: NumSources listed multiple times."); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((num_sources = atoi(value)) <= 0 || num_sources > 65536) + { + DEBUG_printf(("_pwgCreateWithFile: Bad NumSources value %d on line %d.", + num_sources, linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((pwg->sources = calloc(num_sources, sizeof(_pwg_map_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sources.", + num_sources)); + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + goto create_error; + } + } + else if (!strcasecmp(line, "Source")) + { + if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2) + { + DEBUG_printf(("_pwgCreateWithFile: Bad Source on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if (pwg->num_sources >= num_sources) + { + DEBUG_printf(("_pwgCreateWithFile: Too many Source's on line %d.", + linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + map = pwg->sources + pwg->num_sources; + map->pwg = _cupsStrAlloc(pwg_keyword); + map->ppd = _cupsStrAlloc(ppd_keyword); + + pwg->num_sources ++; + } + else if (!strcasecmp(line, "NumTypes")) + { + if (num_types > 0) + { + DEBUG_puts("_pwgCreateWithFile: NumTypes listed multiple times."); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((num_types = atoi(value)) <= 0 || num_types > 65536) + { + DEBUG_printf(("_pwgCreateWithFile: Bad NumTypes value %d on line %d.", + num_types, linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if ((pwg->types = calloc(num_types, sizeof(_pwg_map_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d types.", + num_types)); + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + goto create_error; + } + } + else if (!strcasecmp(line, "Type")) + { + if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2) + { + DEBUG_printf(("_pwgCreateWithFile: Bad Type on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if (pwg->num_types >= num_types) + { + DEBUG_printf(("_pwgCreateWithFile: Too many Type's on line %d.", + linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + map = pwg->types + pwg->num_types; + map->pwg = _cupsStrAlloc(pwg_keyword); + map->ppd = _cupsStrAlloc(ppd_keyword); + + pwg->num_types ++; + } + else if (!strcasecmp(line, "Preset")) + { + /* + * Preset output-mode print-quality name=value ... + */ + + output_mode = (_pwg_output_mode_t)strtol(value, &valueptr, 10); + print_quality = (_pwg_print_quality_t)strtol(valueptr, &valueptr, 10); + + if (output_mode < _PWG_OUTPUT_MODE_MONOCHROME || + output_mode >= _PWG_OUTPUT_MODE_MAX || + print_quality < _PWG_PRINT_QUALITY_DRAFT || + print_quality >= _PWG_PRINT_QUALITY_MAX || + valueptr == value || !*valueptr) + { + DEBUG_printf(("_pwgCreateWithFile: Bad Preset on line %d.", linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + pwg->num_presets[output_mode][print_quality] = + cupsParseOptions(valueptr, 0, + pwg->presets[output_mode] + print_quality); + } + else if (!strcasecmp(line, "SidesOption")) + pwg->sides_option = _cupsStrAlloc(value); + else if (!strcasecmp(line, "Sides1Sided")) + pwg->sides_1sided = _cupsStrAlloc(value); + else if (!strcasecmp(line, "Sides2SidedLong")) + pwg->sides_2sided_long = _cupsStrAlloc(value); + else if (!strcasecmp(line, "Sides2SidedShort")) + pwg->sides_2sided_short = _cupsStrAlloc(value); + else + { + DEBUG_printf(("_pwgCreateWithFile: Unknown %s on line %d.", line, + linenum)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + } + + if (pwg->num_sizes < num_sizes) + { + DEBUG_printf(("_pwgCreateWithFile: Not enough sizes (%d < %d).", + pwg->num_sizes, num_sizes)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if (pwg->num_sources < num_sources) + { + DEBUG_printf(("_pwgCreateWithFile: Not enough sources (%d < %d).", + pwg->num_sources, num_sources)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + if (pwg->num_types < num_types) + { + DEBUG_printf(("_pwgCreateWithFile: Not enough types (%d < %d).", + pwg->num_types, num_types)); + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1); + goto create_error; + } + + cupsFileClose(fp); + + return (pwg); + + /* + * If we get here the file was bad - free any data and return... + */ + + create_error: + + cupsFileClose(fp); + _pwgDestroy(pwg); + + return (NULL); +} + + +/* + * '_pwgDestroy()' - Free all memory used for PWG mapping data. + */ + +void +_pwgDestroy(_pwg_t *pwg) /* I - PWG mapping data */ +{ + int i; /* Looping var */ + _pwg_map_t *map; /* Current map */ + _pwg_size_t *size; /* Current size */ + + + /* + * Range check input... + */ + + if (!pwg) + return; + + /* + * Free memory as needed... + */ + + if (pwg->bins) + { + for (i = pwg->num_bins, map = pwg->bins; i > 0; i --, map ++) + { + _cupsStrFree(map->pwg); + _cupsStrFree(map->ppd); + } + + free(pwg->bins); + } + + if (pwg->sizes) + { + for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++) + { + _cupsStrFree(size->map.pwg); + _cupsStrFree(size->map.ppd); + } + + free(pwg->sizes); + } + + if (pwg->source_option) + _cupsStrFree(pwg->source_option); + + if (pwg->sources) + { + for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++) + { + _cupsStrFree(map->pwg); + _cupsStrFree(map->ppd); + } + + free(pwg->sources); + } + + if (pwg->types) + { + for (i = pwg->num_types, map = pwg->types; i > 0; i --, map ++) + { + _cupsStrFree(map->pwg); + _cupsStrFree(map->ppd); + } + + free(pwg->types); + } + + if (pwg->custom_max_keyword) + _cupsStrFree(pwg->custom_max_keyword); + + if (pwg->custom_min_keyword) + _cupsStrFree(pwg->custom_min_keyword); + + free(pwg); +} + + +/* + * '_pwgWriteFile()' - Write PWG mapping data to a file. + */ + +int /* O - 1 on success, 0 on failure */ +_pwgWriteFile(_pwg_t *pwg, /* I - PWG mapping data */ + const char *filename) /* I - File to write */ +{ + int i, j, k; /* Looping vars */ + cups_file_t *fp; /* Output file */ + _pwg_size_t *size; /* Current size */ + _pwg_map_t *map; /* Current map */ + cups_option_t *option; /* Current option */ + + + /* + * Range check input... + */ + + if (!pwg || !filename) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + return (0); + } + + /* + * Open the file and write with compression... + */ + + if ((fp = cupsFileOpen(filename, "w9")) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0); + return (0); + } + + /* + * Standard header... + */ + + cupsFilePuts(fp, "#CUPS-PWGPPD\n"); + + /* + * Output bins... + */ + + if (pwg->num_bins > 0) + { + cupsFilePrintf(fp, "NumBins %d\n", pwg->num_bins); + for (i = pwg->num_bins, map = pwg->bins; i > 0; i --, map ++) + cupsFilePrintf(fp, "Bin %s %s\n", map->pwg, map->ppd); + } + + /* + * Media sizes... + */ + + cupsFilePrintf(fp, "NumSizes %d\n", pwg->num_sizes); + for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++) + cupsFilePrintf(fp, "Size %s %s %d %d %d %d %d %d\n", size->map.pwg, + size->map.ppd, size->width, size->length, size->left, + size->bottom, size->right, size->top); + if (pwg->custom_max_width > 0) + cupsFilePrintf(fp, "CustomSize %d %d %d %d %d %d %d %d\n", + pwg->custom_max_width, pwg->custom_max_length, + pwg->custom_min_width, pwg->custom_min_length, + pwg->custom_size.left, pwg->custom_size.bottom, + pwg->custom_size.right, pwg->custom_size.top); + + /* + * Media sources... + */ + + if (pwg->source_option) + cupsFilePrintf(fp, "SourceOption %s\n", pwg->source_option); + + if (pwg->num_sources > 0) + { + cupsFilePrintf(fp, "NumSources %d\n", pwg->num_sources); + for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++) + cupsFilePrintf(fp, "Source %s %s\n", map->pwg, map->ppd); + } + + /* + * Media types... + */ + + if (pwg->num_types > 0) + { + cupsFilePrintf(fp, "NumTypes %d\n", pwg->num_types); + for (i = pwg->num_types, map = pwg->types; i > 0; i --, map ++) + cupsFilePrintf(fp, "Type %s %s\n", map->pwg, map->ppd); + } + + /* + * Presets... + */ + + for (i = _PWG_OUTPUT_MODE_MONOCHROME; i < _PWG_OUTPUT_MODE_MAX; i ++) + for (j = _PWG_PRINT_QUALITY_DRAFT; j < _PWG_PRINT_QUALITY_MAX; j ++) + if (pwg->num_presets[i][j]) + { + cupsFilePrintf(fp, "Preset %d %d", i, j); + for (k = pwg->num_presets[i][j], option = pwg->presets[i][j]; + k > 0; + k --, option ++) + cupsFilePrintf(fp, " %s=%s", option->name, option->value); + cupsFilePutChar(fp, '\n'); + } + + /* + * Duplex/sides... + */ + + if (pwg->sides_option) + cupsFilePrintf(fp, "SidesOption %s\n", pwg->sides_option); + + if (pwg->sides_1sided) + cupsFilePrintf(fp, "Sides1Sided %s\n", pwg->sides_1sided); + + if (pwg->sides_2sided_long) + cupsFilePrintf(fp, "Sides2SidedLong %s\n", pwg->sides_2sided_long); + + if (pwg->sides_2sided_short) + cupsFilePrintf(fp, "Sides2SidedShort %s\n", pwg->sides_2sided_short); + + /* + * Close and return... + */ + + return (!cupsFileClose(fp)); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/pwg-media.c b/cups/pwg-media.c new file mode 100644 index 0000000000..1a7cac7a88 --- /dev/null +++ b/cups/pwg-media.c @@ -0,0 +1,849 @@ +/* + * "$Id$" + * + * PWG media name API implementation for CUPS. + * + * Copyright 2009-2010 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _pwgGenerateSize() - Generate a PWG size keyword. + * _pwgInitSize() - Initialize a PWG size using IPP job template + * attributes. + * _pwgMediaForLegacy() - Find a PWG media size by ISO/IPP legacy name. + * _pwgMediaForPPD() - Find a PWG media size by Adobe PPD name. + * _pwgMediaForPWG() - Find a PWG media size by 5101.1 self-describing + * name. + * _pwgMediaForSize() - Get the PWG media name for a given size. + * pwg_compare_legacy() - Compare two sizes using the legacy names. + * pwg_compare_ppd() - Compare two sizes using the PPD names. + * pwg_compare_pwg() - Compare two sizes using the PWG names. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include + + +/* + * Local macros... + */ + +#define _PWG_MEDIA_IN(p,l,a,x,y) {p, l, a, (int)(x * 2540), (int)(y * 2540)} +#define _PWG_MEDIA_MM(p,l,a,x,y) {p, l, a, (int)(x * 100), (int)(y * 100)} + + +/* + * Local functions... + */ + +static int pwg_compare_legacy(_pwg_media_t *a, _pwg_media_t *b); +static int pwg_compare_pwg(_pwg_media_t *a, _pwg_media_t *b); +static int pwg_compare_ppd(_pwg_media_t *a, _pwg_media_t *b); + + +/* + * Local globals... + */ + +static _pwg_media_t const cups_pwg_media[] = +{ /* Media size lookup table */ + /* North American Standard Sheet Media Sizes */ + _PWG_MEDIA_IN("na_index-3x5_3x5in", NULL, "3x5", 3, 5), + _PWG_MEDIA_IN("na_personal_3.625x6.5in", NULL, "EnvPersonal", 3.625, 6.5), + _PWG_MEDIA_IN("na_monarch_3.875x7.5in", "monarch-envelope", "EnvMonarch", 3.875, 7.5), + _PWG_MEDIA_IN("na_number-9_3.875x8.875in", "na-number-9-envelope", "Env9", 3.875, 8.875), + _PWG_MEDIA_IN("na_index-4x6_4x6in", NULL, "4x6", 4, 6), + _PWG_MEDIA_IN("na_number-10_4.125x9.5in", "na-number-10-envelope", "Env10", 4.125, 9.5), + _PWG_MEDIA_IN("na_a2_4.375x5.75in", NULL, NULL, 4.375, 5.75), + _PWG_MEDIA_IN("na_number-11_4.5x10.375in", NULL, "Env11", 4.5, 10.375), + _PWG_MEDIA_IN("na_number-12_4.75x11in", NULL, "Env12", 4.75, 11), + _PWG_MEDIA_IN("na_5x7_5x7in", NULL, "5x7", 5, 7), + _PWG_MEDIA_IN("na_index-5x8_5x8in", NULL, "5x8", 5, 8), + _PWG_MEDIA_IN("na_number-14_5x11.5in", NULL, "Env14", 5, 11.5), + _PWG_MEDIA_IN("na_invoice_5.5x8.5in", "invoice", "Statement", 5.5, 8.5), + _PWG_MEDIA_IN("na_index-4x6-ext_6x8in", NULL, NULL, 6, 8), + _PWG_MEDIA_IN("na_6x9_6x9in", "na-6x9-envelope", "6x9", 6, 9), + _PWG_MEDIA_IN("na_c5_6.5x9.5in", NULL, "6.5x9.5", 6.5, 9.5), + _PWG_MEDIA_IN("na_7x9_7x9in", "na-7x9-envelope", "7x9", 7, 9), + _PWG_MEDIA_IN("na_executive_7.25x10.5in", "executive", "Executive", 7.25, 10.5), + _PWG_MEDIA_IN("na_govt-letter_8x10in", "na-8x10", "8x10", 8, 10), + _PWG_MEDIA_IN("na_govt-legal_8x13in", NULL, "8x13", 8, 13), + _PWG_MEDIA_IN("na_quarto_8.5x10.83in", "quarto", "Quarto", 8.5, 10.83), + _PWG_MEDIA_IN("na_letter_8.5x11in", "na-letter", "Letter", 8.5, 11), + _PWG_MEDIA_IN("na_fanfold-eur_8.5x12in", NULL, "FanFoldGerman", 8.5, 12), + _PWG_MEDIA_IN("na_letter-plus_8.5x12.69in", NULL, "LetterPlus", 8.5, 12.69), + _PWG_MEDIA_IN("na_foolscap_8.5x13in", NULL, "FanFoldGermanLegal", 8.5, 13), + _PWG_MEDIA_IN("na_legal_8.5x14in", "na-legal", "Legal", 8.5, 14), + _PWG_MEDIA_IN("na_super-a_8.94x14in", NULL, "SuperA", 8.94, 14), + _PWG_MEDIA_IN("na_9x11_9x11in", "na-9x11-envelope", "9x11", 9, 11), + _PWG_MEDIA_IN("na_arch-a_9x12in", "arch-a", "ARCHA", 9, 12), + _PWG_MEDIA_IN("na_letter-extra_9.5x12in", NULL, "LetterExtra", 9.5, 12), + _PWG_MEDIA_IN("na_legal-extra_9.5x15in", NULL, "LegalExtra", 9.5, 15), + _PWG_MEDIA_IN("na_10x11_10x11in", NULL, "10x11", 10, 11), + _PWG_MEDIA_IN("na_10x13_10x13in", "na-10x13-envelope", "10x13", 10, 13), + _PWG_MEDIA_IN("na_10x14_10x14in", "na-10x14-envelope", "10x14", 10, 14), + _PWG_MEDIA_IN("na_10x15_10x15in", "na-10x15-envelope", "10x15", 10, 15), + _PWG_MEDIA_IN("na_11x12_11x12in", NULL, "11x12", 11, 12), + _PWG_MEDIA_IN("na_edp_11x14in", NULL, "11x14", 11, 14), + _PWG_MEDIA_IN("na_fanfold-us_11x14.875in", NULL, NULL, 11, 14.875), + _PWG_MEDIA_IN("na_11x15_11x15in", NULL, "11x15", 11, 15), + _PWG_MEDIA_IN("na_ledger_11x17in", "tabloid", "Tabloid", 11, 17), + _PWG_MEDIA_IN("na_eur-edp_12x14in", NULL, NULL, 12, 14), + _PWG_MEDIA_IN("na_arch-b_12x18in", "arch-b", "ARCHB", 12, 18), + _PWG_MEDIA_IN("na_12x19_12x19in", NULL, "12x19", 12, 19), + _PWG_MEDIA_IN("na_b-plus_12x19.17in", NULL, "SuperB", 12, 19.17), + _PWG_MEDIA_IN("na_super-b_13x19in", "super-b", NULL, 13, 19), + _PWG_MEDIA_IN("na_c_17x22in", "c", "AnsiC", 17, 22), + _PWG_MEDIA_IN("na_arch-c_18x24in", "arch-c", "ARCHC", 18, 24), + _PWG_MEDIA_IN("na_d_22x34in", "d", "AnsiD", 22, 34), + _PWG_MEDIA_IN("na_arch-d_24x36in", "arch-d", "ARCHD", 24, 36), + _PWG_MEDIA_IN("asme_f_28x40in", "f", NULL, 28, 40), + _PWG_MEDIA_IN("na_wide-format_30x42in", NULL, NULL, 30, 42), + _PWG_MEDIA_IN("na_e_34x44in", "e", "AnsiE", 34, 44), + _PWG_MEDIA_IN("na_arch-e_36x48in", "arch-e", "ARCHE", 36, 48), + _PWG_MEDIA_IN("na_f_44x68in", NULL, "AnsiF", 44, 68), + + /* Chinese Standard Sheet Media Inch Sizes */ + _PWG_MEDIA_IN("roc_16k_7.75x10.75in", NULL, NULL, 7.75, 10.75), + _PWG_MEDIA_IN("roc_8k_10.75x15.5in", NULL, NULL, 10.75, 15.5), + + /* ISO Standard Sheet Media Sizes */ + _PWG_MEDIA_MM("iso_a10_26x37mm", "iso-a10", "A10", 26, 37), + _PWG_MEDIA_MM("iso_a9_37x52mm", "iso-a9", "A9", 37, 52), + _PWG_MEDIA_MM("iso_a8_52x74mm", "iso-a8", "A8", 52, 74), + _PWG_MEDIA_MM("iso_a7_74x105mm", "iso-a7", "A7", 74, 105), + _PWG_MEDIA_MM("iso_a6_105x148mm", "iso-a6", "A6", 105, 148), + _PWG_MEDIA_MM("iso_a5_148x210mm", "iso-a5", "A5", 148, 210), + _PWG_MEDIA_MM("iso_a5-extra_174x235mm", NULL, "A5Extra", 174, 235), + _PWG_MEDIA_MM("iso_a4_210x297mm", "iso-a4", "A4", 210, 297), + _PWG_MEDIA_MM("iso_a4-tab_225x297mm", NULL, NULL, 225, 297), + _PWG_MEDIA_MM("iso_a4-extra_235.5x322.3mm", NULL, "A4Extra", 235.5, 322.3), + _PWG_MEDIA_MM("iso_a3_297x420mm", "iso-a3", "A3", 297, 420), + _PWG_MEDIA_MM("iso_a4x3_297x630mm", "iso-a4x3", NULL, 297, 630), + _PWG_MEDIA_MM("iso_a4x4_297x841mm", "iso-a4x4", NULL, 297, 841), + _PWG_MEDIA_MM("iso_a4x5_297x1051mm", "iso-a4x5", NULL, 297, 1051), + _PWG_MEDIA_MM("iso_a4x6_297x1261mm", "iso-a4x6", NULL, 297, 1261), + _PWG_MEDIA_MM("iso_a4x7_297x1471mm", "iso-a4x7", NULL, 297, 1471), + _PWG_MEDIA_MM("iso_a4x8_297x1682mm", "iso-a4x8", NULL, 297, 1682), + _PWG_MEDIA_MM("iso_a4x9_297x1892mm", "iso-a4x9", NULL, 297, 1892), + _PWG_MEDIA_MM("iso_a3-extra_322x445mm", "iso-a3-extra", "A3Extra", 322, 445), + _PWG_MEDIA_MM("iso_a2_420x594mm", "iso-a2", "A2", 420, 594), + _PWG_MEDIA_MM("iso_a3x3_420x891mm", "iso-a3x3", NULL, 420, 891), + _PWG_MEDIA_MM("iso_a3x4_420x1189mm", "iso-a3x4", NULL, 420, 1189), + _PWG_MEDIA_MM("iso_a3x5_420x1486mm", "iso-a3x5", NULL, 420, 1486), + _PWG_MEDIA_MM("iso_a3x6_420x1783mm", "iso-a3x6", NULL, 420, 1783), + _PWG_MEDIA_MM("iso_a3x7_420x2080mm", "iso-a3x7", NULL, 420, 2080), + _PWG_MEDIA_MM("iso_a1_594x841mm", "iso-a1", "A1", 594, 841), + _PWG_MEDIA_MM("iso_a2x3_594x1261mm", "iso-a2x3", NULL, 594, 1261), + _PWG_MEDIA_MM("iso_a2x4_594x1682mm", "iso-a2x4", NULL, 594, 1682), + _PWG_MEDIA_MM("iso_a2x5_594x2102mm", "iso-a2x5", NULL, 594, 2102), + _PWG_MEDIA_MM("iso_a0_841x1189mm", "iso-a0", "A0", 841, 1189), + _PWG_MEDIA_MM("iso_a1x3_841x1783mm", "iso-a1x3", NULL, 841, 1783), + _PWG_MEDIA_MM("iso_a1x4_841x2378mm", "iso-a1x4", NULL, 841, 2378), + _PWG_MEDIA_MM("iso_2a0_1189x1682mm", NULL, NULL, 1189, 1682), + _PWG_MEDIA_MM("iso_a0x3_1189x2523mm", NULL, NULL, 1189, 2523), + _PWG_MEDIA_MM("iso_b10_31x44mm", "iso-b10", "ISOB10", 31, 44), + _PWG_MEDIA_MM("iso_b9_44x62mm", "iso-b9", "ISOB9", 44, 62), + _PWG_MEDIA_MM("iso_b8_62x88mm", "iso-b8", "ISOB8", 62, 88), + _PWG_MEDIA_MM("iso_b7_88x125mm", "iso-b7", "ISOB7", 88, 125), + _PWG_MEDIA_MM("iso_b6_125x176mm", "iso-b6", "ISOB6", 125, 176), + _PWG_MEDIA_MM("iso_b6c4_125x324mm", NULL, NULL, 125, 324), + _PWG_MEDIA_MM("iso_b5_176x250mm", "iso-b5", "ISOB5", 176, 250), + _PWG_MEDIA_MM("iso_b5-extra_201x276mm", NULL, "ISOB5Extra", 201, 276), + _PWG_MEDIA_MM("iso_b4_250x353mm", "iso-b4", "ISOB4", 250, 353), + _PWG_MEDIA_MM("iso_b3_353x500mm", "iso-b3", "ISOB3", 353, 500), + _PWG_MEDIA_MM("iso_b2_500x707mm", "iso-b2", "ISOB2", 500, 707), + _PWG_MEDIA_MM("iso_b1_707x1000mm", "iso-b1", "ISOB1", 707, 1000), + _PWG_MEDIA_MM("iso_b0_1000x1414mm", "iso-b0", "ISOB0", 1000, 1414), + _PWG_MEDIA_MM("iso_c10_28x40mm", "iso-c10", NULL, 28, 40), + _PWG_MEDIA_MM("iso_c9_40x57mm", "iso-c9", NULL, 40, 57), + _PWG_MEDIA_MM("iso_c8_57x81mm", "iso-c8", NULL, 57, 81), + _PWG_MEDIA_MM("iso_c7_81x114mm", "iso-c7", "EnvC7", 81, 114), + _PWG_MEDIA_MM("iso_c7c6_81x162mm", NULL, NULL, 81, 162), + _PWG_MEDIA_MM("iso_c6_114x162mm", "iso-c6", "EnvC6", 114, 162), + _PWG_MEDIA_MM("iso_c6c5_114x229mm", NULL, "EnvC65", 114, 229), + _PWG_MEDIA_MM("iso_c5_162x229mm", "iso-c5", "EnvC5", 162, 229), + _PWG_MEDIA_MM("iso_c4_229x324mm", "iso-c4", "EnvC4", 229, 324), + _PWG_MEDIA_MM("iso_c3_324x458mm", "iso-c3", "EnvC3", 324, 458), + _PWG_MEDIA_MM("iso_c2_458x648mm", "iso-c2", "EnvC2", 458, 648), + _PWG_MEDIA_MM("iso_c1_648x917mm", "iso-c1", "EnvC1", 648, 917), + _PWG_MEDIA_MM("iso_c0_917x1297mm", "iso-c0", "EnvC0", 917, 1297), + _PWG_MEDIA_MM("iso_dl_110x220mm", "iso-designated", "EnvDL", 110, 220), + _PWG_MEDIA_MM("iso_ra2_430x610mm", "iso-ra2", NULL, 430, 610), + _PWG_MEDIA_MM("iso_sra2_450x640mm", "iso-sra2", NULL, 450, 640), + _PWG_MEDIA_MM("iso_ra1_610x860mm", "iso-ra1", NULL, 610, 860), + _PWG_MEDIA_MM("iso_sra1_640x900mm", "iso-sra1", NULL, 640, 900), + _PWG_MEDIA_MM("iso_ra0_860x1220mm", "iso-ra0", NULL, 860, 1220), + _PWG_MEDIA_MM("iso_sra0_900x1280mm", "iso-sra0", NULL, 900, 1280), + + /* Japanese Standard Sheet Media Sizes */ + _PWG_MEDIA_MM("jis_b10_32x45mm", "jis-b10", "B10", 32, 45), + _PWG_MEDIA_MM("jis_b9_45x64mm", "jis-b9", "B9", 45, 64), + _PWG_MEDIA_MM("jis_b8_64x91mm", "jis-b8", "B8", 64, 91), + _PWG_MEDIA_MM("jis_b7_91x128mm", "jis-b7", "B7", 91, 128), + _PWG_MEDIA_MM("jis_b6_128x182mm", "jis-b6", "B6", 128, 182), + _PWG_MEDIA_MM("jis_b5_182x257mm", "jis-b5", "B5", 182, 257), + _PWG_MEDIA_MM("jis_b4_257x364mm", "jis-b4", "B4", 257, 364), + _PWG_MEDIA_MM("jis_b3_364x515mm", "jis-b3", "B3", 364, 515), + _PWG_MEDIA_MM("jis_b2_515x728mm", "jis-b2", "B2", 515, 728), + _PWG_MEDIA_MM("jis_b1_728x1030mm", "jis-b1", "B1", 728, 1030), + _PWG_MEDIA_MM("jis_b0_1030x1456mm", "jis-b0", "B0", 1030, 1456), + _PWG_MEDIA_MM("jis_exec_216x330mm", NULL, NULL, 216, 330), + _PWG_MEDIA_MM("jpn_chou4_90x205mm", NULL, "EnvChou4", 90, 205), + _PWG_MEDIA_MM("jpn_hagaki_100x148mm", NULL, "Postcard", 100, 148), + _PWG_MEDIA_MM("jpn_you4_105x235mm", NULL, "EnvYou4", 105, 235), + _PWG_MEDIA_MM("jpn_chou2_111.1x146mm", NULL, NULL, 111.1, 146), + _PWG_MEDIA_MM("jpn_chou3_120x235mm", NULL, "EnvChou3", 120, 235), + _PWG_MEDIA_MM("jpn_oufuku_148x200mm", NULL, "DoublePostcardRotated", 148, 200), + _PWG_MEDIA_MM("jpn_kahu_240x322.1mm", NULL, NULL, 240, 322.1), + _PWG_MEDIA_MM("jpn_kaku2_240x332mm", NULL, "EnvKaku2", 240, 332), + + /* Chinese Standard Sheet Media Sizes */ + _PWG_MEDIA_MM("prc_32k_97x151mm", NULL, "PRC32K", 97, 151), + _PWG_MEDIA_MM("prc_1_102x165mm", NULL, "EnvPRC1", 102, 165), + _PWG_MEDIA_MM("prc_2_102x176mm", NULL, "EnvPRC2", 102, 176), + _PWG_MEDIA_MM("prc_4_110x208mm", NULL, "EnvPRC4", 110, 208), + _PWG_MEDIA_MM("prc_5_110x220mm", NULL, "EnvPRC5", 110, 220), + _PWG_MEDIA_MM("prc_8_120x309mm", NULL, "EnvPRC8", 120, 309), + _PWG_MEDIA_MM("prc_6_120x320mm", NULL, NULL, 120, 320), + _PWG_MEDIA_MM("prc_3_125x176mm", NULL, "EnvPRC3", 125, 176), + _PWG_MEDIA_MM("prc_16k_146x215mm", NULL, "PRC16K", 146, 215), + _PWG_MEDIA_MM("prc_7_160x230mm", NULL, "EnvPRC7", 160, 230), + _PWG_MEDIA_MM("om_juuro-ku-kai_198x275mm", NULL, NULL, 198, 275), + _PWG_MEDIA_MM("om_pa-kai_267x389mm", NULL, NULL, 267, 389), + _PWG_MEDIA_MM("om_dai-pa-kai_275x395mm", NULL, NULL, 275, 395), + _PWG_MEDIA_MM("prc_10_324x458mm", NULL, "EnvPRC10", 324, 458), + + /* Other Metric Standard Sheet Media Sizes */ + _PWG_MEDIA_MM("om_small-photo_100x150mm", NULL, NULL, 100, 150), + _PWG_MEDIA_MM("om_italian_110x230mm", NULL, "EnvItalian", 110, 230), + _PWG_MEDIA_MM("om_postfix_114x229mm", NULL, NULL, 114, 229), + _PWG_MEDIA_MM("om_large-photo_200x300", NULL, NULL, 200, 300), + _PWG_MEDIA_MM("om_folio_210x330mm", "folio", "Folio", 210, 330), + _PWG_MEDIA_MM("om_folio-sp_215x315mm", NULL, NULL, 215, 315), + _PWG_MEDIA_MM("om_invite_220x220mm", NULL, "EnvInvite", 220, 220) +}; + + +/* + * '_pwgGenerateSize()' - Generate a PWG size keyword. + */ + +void +_pwgGenerateSize(char *keyword, /* I - Keyword buffer */ + size_t keysize, /* I - Size of keyword buffer */ + const char *prefix, /* I - Prefix for PWG size or NULL */ + const char *name, /* I - Size name or NULL */ + int width, /* I - Width of page in 2540ths */ + int length) /* I - Length of page in 2540ths */ +{ + struct lconv *loc; /* Locale conversion data */ + double uwidth, /* Width in inches or millimeters */ + ulength; /* Height in inches or millimeters */ + const char *units; /* Units to report */ + char usize[12 + 1 + 12 + 3], /* Unit size: NNNNNNNNNNNNxNNNNNNNNNNNNuu */ + *uptr; /* Pointer into unit size */ + + + loc = localeconv(); + + if ((width % 635) == 0 && (length % 635) == 0) + { + /* + * Use inches since the size is a multiple of 1/4 inch. + */ + + uwidth = width / 2540.0; + ulength = length / 2540.0; + units = "in"; + + if (!prefix) + prefix = "oe"; + } + else + { + /* + * Use millimeters since the size is not a multiple of 1/4 inch. + */ + + uwidth = width * 0.01; + ulength = length * 0.01; + units = "mm"; + + if (!prefix) + prefix = "om"; + } + + uptr = usize; + _cupsStrFormatd(uptr, uptr + 12, uwidth, loc); + uptr += strlen(uptr); + *uptr++ = 'x'; + _cupsStrFormatd(uptr, uptr + 12, ulength, loc); + uptr += strlen(uptr); + + /* + * Safe because usize can hold up to 12 + 1 + 12 + 4 bytes. + */ + + strcpy(uptr, units); + + if (!name) + name = usize; + + /* + * Format the name... + */ + + snprintf(keyword, keysize, "%s_%s_%s", prefix, name, usize); +} + + +/* + * '_pwgInitSize()' - Initialize a PWG size using IPP job template attributes. + */ + +int /* O - 1 if size was initialize, 0 otherwise */ +_pwgInitSize(_pwg_size_t *size, /* I - Size to initialize */ + ipp_t *job, /* I - Job template attributes */ + int *margins_set) /* O - 1 if margins were set, 0 otherwise */ +{ + ipp_attribute_t *media, /* media attribute */ + *media_bottom_margin, /* media-bottom-margin member attribute */ + *media_col, /* media-col attribute */ + *media_left_margin, /* media-left-margin member attribute */ + *media_right_margin, /* media-right-margin member attribute */ + *media_size, /* media-size member attribute */ + *media_top_margin, /* media-top-margin member attribute */ + *x_dimension, /* x-dimension member attribute */ + *y_dimension; /* y-dimension member attribute */ + _pwg_media_t *pwg; /* PWG media value */ + + + /* + * Range check input... + */ + + if (!size || !job || !margins_set) + return (0); + + /* + * Look for media-col and then media... + */ + + memset(size, 0, sizeof(_pwg_size_t)); + *margins_set = 0; + + if ((media_col = ippFindAttribute(job, "media-col", + IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + /* + * Got media-col, look for media-size member attribute... + */ + + if ((media_size = ippFindAttribute(media_col->values[0].collection, + "media-size", + IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + /* + * Got media-size, look for x-dimension and y-dimension member + * attributes... + */ + + x_dimension = ippFindAttribute(media_size->values[0].collection, + "x-dimension", IPP_TAG_INTEGER); + y_dimension = ippFindAttribute(media_size->values[0].collection, + "y-dimension", IPP_TAG_INTEGER); + + if (x_dimension && y_dimension) + { + size->width = x_dimension->values[0].integer; + size->length = y_dimension->values[0].integer; + } + else if (!x_dimension) + { + _cupsSetError(IPP_INTERNAL_ERROR, + _("Missing x-dimension in media-size."), 1); + return (0); + } + else if (!y_dimension) + { + _cupsSetError(IPP_INTERNAL_ERROR, + _("Missing y-dimension in media-size."), 1); + return (0); + } + } + else + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Missing media-size in media-col."), + 1); + return (0); + } + + /* media-*-margin */ + media_bottom_margin = ippFindAttribute(media_col->values[0].collection, + "media-bottom-margin", + IPP_TAG_INTEGER); + media_left_margin = ippFindAttribute(media_col->values[0].collection, + "media-left-margin", + IPP_TAG_INTEGER); + media_right_margin = ippFindAttribute(media_col->values[0].collection, + "media-right-margin", + IPP_TAG_INTEGER); + media_top_margin = ippFindAttribute(media_col->values[0].collection, + "media-top-margin", + IPP_TAG_INTEGER); + if (media_bottom_margin && media_left_margin && media_right_margin && + media_top_margin) + { + *margins_set = 1; + size->bottom = media_bottom_margin->values[0].integer; + size->left = media_left_margin->values[0].integer; + size->right = media_right_margin->values[0].integer; + size->top = media_top_margin->values[0].integer; + } + } + else + { + if ((media = ippFindAttribute(job, "media", IPP_TAG_NAME)) == NULL) + if ((media = ippFindAttribute(job, "media", IPP_TAG_KEYWORD)) == NULL) + if ((media = ippFindAttribute(job, "PageSize", IPP_TAG_NAME)) == NULL) + media = ippFindAttribute(job, "PageRegion", IPP_TAG_NAME); + + if (media) + { + const char *name = media->values[0].string.text; + /* Name string */ + + if ((pwg = _pwgMediaForPWG(name)) == NULL) + { + /* + * Not a PWG name, try a legacy name... + */ + + if ((pwg = _pwgMediaForLegacy(name)) == NULL) + { + /* + * Not a legacy name, try a PPD name... + */ + + const char *suffix; /* Suffix on media string */ + + pwg = _pwgMediaForPPD(name); + if (pwg && + (suffix = name + strlen(name) - 10 /* .FullBleed */) > name && + !strcasecmp(suffix, ".FullBleed")) + { + /* + * Indicate that margins are set with the default values of 0. + */ + + *margins_set = 1; + } + } + } + + if (pwg) + { + size->width = pwg->width; + size->length = pwg->length; + } + else + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Unsupported media value."), 1); + return (0); + } + } + else + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Missing media or media-col."), 1); + return (0); + } + } + + return (1); +} + + +/* + * '_pwgMediaForLegacy()' - Find a PWG media size by ISO/IPP legacy name. + */ + +_pwg_media_t * /* O - Matching size or NULL */ +_pwgMediaForLegacy( + const char *legacy) /* I - Legacy size name */ +{ + _pwg_media_t key; /* Search key */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + /* + * Range check input... + */ + + if (!legacy) + return (NULL); + + /* + * Build the lookup table for PWG names as needed... + */ + + if (!cg->leg_size_lut) + { + int i; /* Looping var */ + _pwg_media_t *size; /* Current size */ + + cg->leg_size_lut = cupsArrayNew((cups_array_func_t)pwg_compare_legacy, + NULL); + + for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])), + size = (_pwg_media_t *)cups_pwg_media; + i > 0; + i --, size ++) + if (size->legacy) + cupsArrayAdd(cg->leg_size_lut, size); + } + + /* + * Lookup the name... + */ + + key.legacy = legacy; + return ((_pwg_media_t *)cupsArrayFind(cg->leg_size_lut, &key)); +} + + +/* + * '_pwgMediaForPPD()' - Find a PWG media size by Adobe PPD name. + */ + +_pwg_media_t * /* O - Matching size or NULL */ +_pwgMediaForPPD(const char *ppd) /* I - PPD size name */ +{ + _pwg_media_t key, /* Search key */ + *size; /* Matching size */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + /* + * Range check input... + */ + + if (!ppd) + return (NULL); + + /* + * Build the lookup table for PWG names as needed... + */ + + if (!cg->ppd_size_lut) + { + int i; /* Looping var */ + + cg->ppd_size_lut = cupsArrayNew((cups_array_func_t)pwg_compare_ppd, NULL); + + for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])), + size = (_pwg_media_t *)cups_pwg_media; + i > 0; + i --, size ++) + if (size->ppd) + cupsArrayAdd(cg->ppd_size_lut, size); + } + + /* + * Lookup the name... + */ + + key.ppd = ppd; + if ((size = (_pwg_media_t *)cupsArrayFind(cg->ppd_size_lut, &key)) == NULL) + { + /* + * See if the name is of the form: + * + * [Custom.]WIDTHxLENGTH[.FullBleed] - Size in points/inches [borderless] + * [Custom.]WIDTHxLENGTHcm[.FullBleed] - Size in centimeters [borderless] + * [Custom.]WIDTHxLENGTHft[.FullBleed] - Size in feet [borderless] + * [Custom.]WIDTHxLENGTHin[.FullBleed] - Size in inches [borderless] + * [Custom.]WIDTHxLENGTHm[.FullBleed] - Size in meters [borderless] + * [Custom.]WIDTHxLENGTHmm[.FullBleed] - Size in millimeters [borderless] + * [Custom.]WIDTHxLENGTHpt[.FullBleed] - Size in points [borderless] + */ + + double w, l, /* Width and length of page */ + factor; /* Unit scaling factor */ + char *ptr; /* Pointer into name */ + struct lconv *loc; /* Locale data */ + int custom; /* Custom page size? */ + + if (!strncasecmp(ppd, "Custom.", 7)) + { + custom = 1; + factor = 2540.0 / 72.0; + ptr = (char *)ppd + 7; + } + else + { + custom = 0; + factor = 2540.0; + ptr = (char *)ppd; + } + + loc = localeconv(); + w = _cupsStrScand(ptr, &ptr, loc); + + if (ptr && ptr > ppd && *ptr == 'x') + { + l = _cupsStrScand(ptr + 1, &ptr, loc); + + if (ptr && + (!*ptr || + !strcasecmp(ptr, "FullBleed") || + !strcasecmp(ptr, ".FullBleed") || + !strcasecmp(ptr, "cm") || + !strcasecmp(ptr, "cm.FullBleed") || + !strcasecmp(ptr, "ft") || + !strcasecmp(ptr, "ft.FullBleed") || + !strcasecmp(ptr, "in") || + !strcasecmp(ptr, "in.FullBleed") || + !strcasecmp(ptr, "m") || + !strcasecmp(ptr, "m.FullBleed") || + !strcasecmp(ptr, "mm") || + !strcasecmp(ptr, "mm.FullBleed") || + !strcasecmp(ptr, "pt") || + !strcasecmp(ptr, "pt.FullBleed"))) + { + size = &(cg->pwg_media); + + if (!strncasecmp(ptr, "cm", 2)) + factor = 1000.0; + else if (!strncasecmp(ptr, "ft", 2)) + factor = 2540.0 * 12.0; + else if (!strncasecmp(ptr, "in", 2)) + factor = 2540.0; + else if (!strncasecmp(ptr, "mm", 2)) + factor = 100.0; + else if (*ptr == 'm' || *ptr == 'M') + factor = 100000.0; + else if (!strncasecmp(ptr, "pt", 2)) + factor = 2540.0 / 72.0; + + /* + * Not a standard size; convert it to a PWG custom name of the form: + * + * [oe|om]_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu + */ + + size->width = (int)(w * factor); + size->length = (int)(l * factor); + size->pwg = cg->pwg_name; + + _pwgGenerateSize(cg->pwg_name, sizeof(cg->pwg_name), + custom ? "custom" : NULL, custom ? ppd + 7 : NULL, + size->width, size->length); + } + } + } + + return (size); +} + + +/* + * '_pwgMediaForPWG()' - Find a PWG media size by 5101.1 self-describing name. + */ + +_pwg_media_t * /* O - Matching size or NULL */ +_pwgMediaForPWG(const char *pwg) /* I - PWG size name */ +{ + char *ptr; /* Pointer into name */ + _pwg_media_t key, /* Search key */ + *size; /* Matching size */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + /* + * Range check input... + */ + + if (!pwg) + return (NULL); + + /* + * Build the lookup table for PWG names as needed... + */ + + if (!cg->pwg_size_lut) + { + int i; /* Looping var */ + + cg->pwg_size_lut = cupsArrayNew((cups_array_func_t)pwg_compare_pwg, NULL); + + for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])), + size = (_pwg_media_t *)cups_pwg_media; + i > 0; + i --, size ++) + cupsArrayAdd(cg->pwg_size_lut, size); + } + + /* + * Lookup the name... + */ + + key.pwg = pwg; + if ((size = (_pwg_media_t *)cupsArrayFind(cg->pwg_size_lut, &key)) == NULL && + (ptr = (char *)strchr(pwg, '_')) != NULL && + (ptr = (char *)strchr(ptr + 1, '_')) != NULL) + { + /* + * Try decoding the self-describing name of the form: + * + * class_name_WWWxHHHin + * class_name_WWWxHHHmm + */ + + double w, l; /* Width and length of page */ + struct lconv *loc; /* Locale data */ + + ptr ++; + loc = localeconv(); + w = _cupsStrScand(ptr, &ptr, loc); + + if (ptr && *ptr == 'x') + { + l = _cupsStrScand(ptr + 1, &ptr, loc); + + if (ptr && (!strcmp(ptr, "in") || !strcmp(ptr, "mm"))) + { + size = &(cg->pwg_media); + + if (!strcmp(ptr, "mm")) + { + size->width = (int)(w * 100); + size->length = (int)(l * 100); + } + else + { + size->width = (int)(w * 2540); + size->length = (int)(l * 2540); + } + + strlcpy(cg->pwg_name, pwg, sizeof(cg->pwg_name)); + size->pwg = cg->pwg_name; + } + } + } + + return (size); +} + + +/* + * '_pwgMediaForSize()' - Get the PWG media name for a given size. + */ + +_pwg_media_t * /* O - PWG media name */ +_pwgMediaForSize(int width, /* I - Width in 2540ths */ + int length) /* I - Length in 2540ths */ +{ + int i; /* Looping var */ + _pwg_media_t *media; /* Current media */ + int dw, dl; /* Difference in width and length */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + /* + * Range check input... + */ + + if (width <= 0 || length <= 0) + return (NULL); + + /* + * Look for a standard size... + */ + + for (i = (int)(sizeof(cups_pwg_media) / sizeof(cups_pwg_media[0])), + media = (_pwg_media_t *)cups_pwg_media; + i > 0; + i --, media ++) + { + /* + * Adobe uses a size matching algorithm with an epsilon of 5 points, which + * is just about 176/2540ths... + */ + + dw = media->width - width; + dl = media->length - length; + + if (dw > -176 && dw < 176 && dl > -176 && dl < 176) + return (media); + } + + /* + * Not a standard size; convert it to a PWG custom name of the form: + * + * custom_WIDTHxHEIGHTuu_WIDTHxHEIGHTuu + */ + + _pwgGenerateSize(cg->pwg_name, sizeof(cg->pwg_name), "custom", NULL, width, + length); + + cg->pwg_media.pwg = cg->pwg_name; + cg->pwg_media.width = width; + cg->pwg_media.length = length; + + return (&(cg->pwg_media)); +} + + +/* + * 'pwg_compare_legacy()' - Compare two sizes using the legacy names. + */ + +static int /* O - Result of comparison */ +pwg_compare_legacy(_pwg_media_t *a, /* I - First size */ + _pwg_media_t *b) /* I - Second size */ +{ + return (strcmp(a->legacy, b->legacy)); +} + + +/* + * 'pwg_compare_ppd()' - Compare two sizes using the PPD names. + */ + +static int /* O - Result of comparison */ +pwg_compare_ppd(_pwg_media_t *a, /* I - First size */ + _pwg_media_t *b) /* I - Second size */ +{ + return (strcmp(a->ppd, b->ppd)); +} + + +/* + * 'pwg_compare_pwg()' - Compare two sizes using the PWG names. + */ + +static int /* O - Result of comparison */ +pwg_compare_pwg(_pwg_media_t *a, /* I - First size */ + _pwg_media_t *b) /* I - Second size */ +{ + return (strcmp(a->pwg, b->pwg)); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/pwg-ppd.c b/cups/pwg-ppd.c new file mode 100644 index 0000000000..91d0b2f3b0 --- /dev/null +++ b/cups/pwg-ppd.c @@ -0,0 +1,1491 @@ +/* + * "$Id$" + * + * PWG PPD mapping API implementation for CUPS. + * + * Copyright 2010-2011 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _pwgCreateWithPPD() - Create PWG mapping data from a PPD file. + * _pwgGetBin() - Get the PWG output-bin keyword associated with a + * PPD OutputBin. + * _pwgGetInputSlot() - Get the PPD InputSlot associated with the job + * attributes or a keyword string. + * _pwgGetMediaType() - Get the PPD MediaType associated with the job + * attributes or a keyword string. + * _pwgGetOutputBin() - Get the PPD OutputBin associated with the + * keyword string. + * _pwgGetPageSize() - Get the PPD PageSize associated with the job + * attributes or a keyword string. + * _pwgGetSize() - Get the PWG size associated with a PPD PageSize. + * _pwgGetSource() - Get the PWG media-source associated with a PPD + * InputSlot. + * _pwgGetType() - Get the PWG media-type associated with a PPD + * MediaType. + * _pwgInputSlotForSource() - Get the InputSlot name for the given PWG source. + * _pwgMediaTypeForType() - Get the MediaType name for the given PWG type. + * _pwgPageSizeForMedia() - Get the PageSize name for the given media. + * pwg_ppdize_name() - Convert an IPP keyword to a PPD keyword. + * pwg_unppdize_name() - Convert a PPD keyword to a lowercase IPP + * keyword. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include + + +/* + * Macro to test for two almost-equal PWG measurements. + */ + +#define _PWG_EQUIVALENT(x, y) (abs((x)-(y)) < 2) + + +/* + * Local functions... + */ + +static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize); +static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize); + + +/* + * '_pwgCreateWithPPD()' - Create PWG mapping data from a PPD file. + */ + +_pwg_t * /* O - PWG mapping data */ +_pwgCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */ +{ + int i, j, k; /* Looping vars */ + _pwg_t *pwg; /* PWG mapping data */ + ppd_option_t *input_slot, /* InputSlot option */ + *media_type, /* MediaType option */ + *output_bin, /* OutputBin option */ + *color_model, /* ColorModel option */ + *duplex; /* Duplex option */ + ppd_choice_t *choice; /* Current InputSlot/MediaType */ + _pwg_map_t *map; /* Current source/type map */ + ppd_attr_t *ppd_attr; /* Current PPD preset attribute */ + int num_options; /* Number of preset options and props */ + cups_option_t *options; /* Preset options and properties */ + ppd_size_t *ppd_size; /* Current PPD size */ + _pwg_size_t *pwg_size; /* Current PWG size */ + char pwg_keyword[3 + PPD_MAX_NAME + 1 + 12 + 1 + 12 + 3], + /* PWG keyword string */ + ppd_name[PPD_MAX_NAME]; + /* Normalized PPD name */ + const char *pwg_name; /* Standard PWG media name */ + _pwg_media_t *pwg_media; /* PWG media data */ + _pwg_output_mode_t pwg_output_mode;/* output-mode index */ + _pwg_print_quality_t pwg_print_quality; + /* print-quality index */ + int similar; /* Are the old and new size similar? */ + _pwg_size_t *old_size; /* Current old size */ + int old_imageable, /* Old imageable length in 2540ths */ + old_borderless, /* Old borderless state */ + old_known_pwg; /* Old PWG name is well-known */ + int new_width, /* New width in 2540ths */ + new_length, /* New length in 2540ths */ + new_left, /* New left margin in 2540ths */ + new_bottom, /* New bottom margin in 2540ths */ + new_right, /* New right margin in 2540ths */ + new_top, /* New top margin in 2540ths */ + new_imageable, /* New imageable length in 2540ths */ + new_borderless, /* New borderless state */ + new_known_pwg; /* New PWG name is well-known */ + _pwg_size_t *new_size; /* New size to add, if any */ + + + DEBUG_printf(("_pwgCreateWithPPD(ppd=%p)", ppd)); + + /* + * Range check input... + */ + + if (!ppd) + return (NULL); + + /* + * Allocate memory... + */ + + if ((pwg = calloc(1, sizeof(_pwg_t))) == NULL) + { + DEBUG_puts("_pwgCreateWithPPD: Unable to allocate _pwg_t."); + goto create_error; + } + + /* + * Copy and convert size data... + */ + + if (ppd->num_sizes == 0) + { + DEBUG_puts("_pwgCreateWithPPD: No page sizes in PPD."); + goto create_error; + } + + if ((pwg->sizes = calloc(ppd->num_sizes, sizeof(_pwg_size_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_size_t's.", + ppd->num_sizes)); + goto create_error; + } + + for (i = ppd->num_sizes, pwg_size = pwg->sizes, ppd_size = ppd->sizes; + i > 0; + i --, ppd_size ++) + { + /* + * Don't copy over custom size... + */ + + if (!strcasecmp(ppd_size->name, "Custom")) + continue; + + /* + * Convert the PPD size name to the corresponding PWG keyword name. + */ + + if ((pwg_media = _pwgMediaForPPD(ppd_size->name)) != NULL) + { + /* + * Standard name, do we have conflicts? + */ + + for (j = 0; j < pwg->num_sizes; j ++) + if (!strcmp(pwg->sizes[j].map.pwg, pwg_media->pwg)) + { + pwg_media = NULL; + break; + } + } + + if (pwg_media) + { + /* + * Standard name and no conflicts, use it! + */ + + pwg_name = pwg_media->pwg; + new_known_pwg = 1; + } + else + { + /* + * Not a standard name; convert it to a PWG vendor name of the form: + * + * pp_lowerppd_WIDTHxHEIGHTuu + */ + + pwg_name = pwg_keyword; + new_known_pwg = 0; + + pwg_unppdize_name(ppd_size->name, ppd_name, sizeof(ppd_name)); + _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), NULL, ppd_name, + _PWG_FROMPTS(ppd_size->width), + _PWG_FROMPTS(ppd_size->length)); + } + + /* + * If we have a similar paper with non-zero margins then we only + * want to keep it if it has a larger imageable area length. + */ + + new_width = _PWG_FROMPTS(ppd_size->width); + new_length = _PWG_FROMPTS(ppd_size->length); + new_left = _PWG_FROMPTS(ppd_size->left); + new_bottom = _PWG_FROMPTS(ppd_size->bottom); + new_right = _PWG_FROMPTS(ppd_size->width - ppd_size->right); + new_top = _PWG_FROMPTS(ppd_size->length - ppd_size->top); + new_imageable = new_length - new_top - new_bottom; + new_borderless = new_bottom == 0 && new_top == 0 && + new_left == 0 && new_right == 0; + + for (k = pwg->num_sizes, similar = 0, old_size = pwg->sizes, new_size = NULL; + k > 0 && !similar; + k --, old_size ++) + { + old_imageable = old_size->length - old_size->top - old_size->bottom; + old_borderless = old_size->left == 0 && old_size->bottom == 0 && + old_size->right == 0 && old_size->top == 0; + old_known_pwg = strncmp(old_size->map.pwg, "oe_", 3) && + strncmp(old_size->map.pwg, "om_", 3); + + similar = old_borderless == new_borderless && + _PWG_EQUIVALENT(old_size->width, new_width) && + _PWG_EQUIVALENT(old_size->length, new_length); + + if (similar && + (new_known_pwg || (!old_known_pwg && new_imageable > old_imageable))) + { + /* + * The new paper has a larger imageable area so it could replace + * the older paper. Regardless of the imageable area, we always + * prefer the size with a well-known PWG name. + */ + + new_size = old_size; + _cupsStrFree(old_size->map.ppd); + _cupsStrFree(old_size->map.pwg); + } + } + + if (!similar) + { + /* + * The paper was unique enough to deserve its own entry so add it to the + * end. + */ + + new_size = pwg_size ++; + pwg->num_sizes ++; + } + + if (new_size) + { + /* + * Save this size... + */ + + new_size->map.ppd = _cupsStrAlloc(ppd_size->name); + new_size->map.pwg = _cupsStrAlloc(pwg_name); + new_size->width = new_width; + new_size->length = new_length; + new_size->left = new_left; + new_size->bottom = new_bottom; + new_size->right = new_right; + new_size->top = new_top; + } + } + + if (ppd->variable_sizes) + { + /* + * Generate custom size data... + */ + + _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max", + _PWG_FROMPTS(ppd->custom_max[0]), + _PWG_FROMPTS(ppd->custom_max[1])); + pwg->custom_max_keyword = _cupsStrAlloc(pwg_keyword); + pwg->custom_max_width = _PWG_FROMPTS(ppd->custom_max[0]); + pwg->custom_max_length = _PWG_FROMPTS(ppd->custom_max[1]); + + _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min", + _PWG_FROMPTS(ppd->custom_min[0]), + _PWG_FROMPTS(ppd->custom_min[1])); + pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword); + pwg->custom_min_width = _PWG_FROMPTS(ppd->custom_min[0]); + pwg->custom_min_length = _PWG_FROMPTS(ppd->custom_min[1]); + + pwg->custom_size.left = _PWG_FROMPTS(ppd->custom_margins[0]); + pwg->custom_size.bottom = _PWG_FROMPTS(ppd->custom_margins[1]); + pwg->custom_size.right = _PWG_FROMPTS(ppd->custom_margins[2]); + pwg->custom_size.top = _PWG_FROMPTS(ppd->custom_margins[3]); + } + + /* + * Copy and convert InputSlot data... + */ + + if ((input_slot = ppdFindOption(ppd, "InputSlot")) == NULL) + input_slot = ppdFindOption(ppd, "HPPaperSource"); + + if (input_slot) + { + pwg->source_option = _cupsStrAlloc(input_slot->keyword); + + if ((pwg->sources = calloc(input_slot->num_choices, + sizeof(_pwg_map_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's " + "for InputSlot.", input_slot->num_choices)); + goto create_error; + } + + pwg->num_sources = input_slot->num_choices; + + for (i = input_slot->num_choices, choice = input_slot->choices, + map = pwg->sources; + i > 0; + i --, choice ++, map ++) + { + if (!strncasecmp(choice->choice, "Auto", 4) || + !strcasecmp(choice->choice, "Default")) + pwg_name = "auto"; + else if (!strcasecmp(choice->choice, "Cassette")) + pwg_name = "main"; + else if (!strcasecmp(choice->choice, "PhotoTray")) + pwg_name = "photo"; + else if (!strcasecmp(choice->choice, "CDTray")) + pwg_name = "disc"; + else if (!strncasecmp(choice->choice, "Multipurpose", 12) || + !strcasecmp(choice->choice, "MP") || + !strcasecmp(choice->choice, "MPTray")) + pwg_name = "alternate"; + else if (!strcasecmp(choice->choice, "LargeCapacity")) + pwg_name = "large-capacity"; + else if (!strncasecmp(choice->choice, "Lower", 5)) + pwg_name = "bottom"; + else if (!strncasecmp(choice->choice, "Middle", 6)) + pwg_name = "middle"; + else if (!strncasecmp(choice->choice, "Upper", 5)) + pwg_name = "top"; + else if (!strncasecmp(choice->choice, "Side", 4)) + pwg_name = "side"; + else if (!strcasecmp(choice->choice, "Roll") || + !strcasecmp(choice->choice, "Roll1")) + pwg_name = "main-roll"; + else if (!strcasecmp(choice->choice, "Roll2")) + pwg_name = "alternate-roll"; + else + { + /* + * Convert PPD name to lowercase... + */ + + pwg_name = pwg_keyword; + pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword)); + } + + map->pwg = _cupsStrAlloc(pwg_name); + map->ppd = _cupsStrAlloc(choice->choice); + } + } + + /* + * Copy and convert MediaType data... + */ + + if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL) + { + if ((pwg->types = calloc(media_type->num_choices, + sizeof(_pwg_map_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's " + "for MediaType.", media_type->num_choices)); + goto create_error; + } + + pwg->num_types = media_type->num_choices; + + for (i = media_type->num_choices, choice = media_type->choices, + map = pwg->types; + i > 0; + i --, choice ++, map ++) + { + if (!strncasecmp(choice->choice, "Auto", 4) || + !strcasecmp(choice->choice, "Any") || + !strcasecmp(choice->choice, "Default")) + pwg_name = "auto"; + else if (!strncasecmp(choice->choice, "Card", 4)) + pwg_name = "cardstock"; + else if (!strncasecmp(choice->choice, "Env", 3)) + pwg_name = "envelope"; + else if (!strncasecmp(choice->choice, "Gloss", 5)) + pwg_name = "photographic-glossy"; + else if (!strcasecmp(choice->choice, "HighGloss")) + pwg_name = "photographic-high-gloss"; + else if (!strcasecmp(choice->choice, "Matte")) + pwg_name = "photographic-matte"; + else if (!strncasecmp(choice->choice, "Plain", 5)) + pwg_name = "stationery"; + else if (!strncasecmp(choice->choice, "Coated", 6)) + pwg_name = "stationery-coated"; + else if (!strcasecmp(choice->choice, "Inkjet")) + pwg_name = "stationery-inkjet"; + else if (!strcasecmp(choice->choice, "Letterhead")) + pwg_name = "stationery-letterhead"; + else if (!strncasecmp(choice->choice, "Preprint", 8)) + pwg_name = "stationery-preprinted"; + else if (!strncasecmp(choice->choice, "Transparen", 10)) + pwg_name = "transparency"; + else + { + /* + * Convert PPD name to lowercase... + */ + + pwg_name = pwg_keyword; + pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword)); + } + + map->pwg = _cupsStrAlloc(pwg_name); + map->ppd = _cupsStrAlloc(choice->choice); + } + } + + + /* + * Copy and convert OutputBin data... + */ + + if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL) + { + if ((pwg->bins = calloc(output_bin->num_choices, + sizeof(_pwg_map_t))) == NULL) + { + DEBUG_printf(("_pwgCreateWithPPD: Unable to allocate %d _pwg_map_t's " + "for OutputBin.", output_bin->num_choices)); + goto create_error; + } + + pwg->num_bins = output_bin->num_choices; + + for (i = output_bin->num_choices, choice = output_bin->choices, + map = pwg->bins; + i > 0; + i --, choice ++, map ++) + { + pwg_unppdize_name(choice->choice, pwg_keyword, sizeof(pwg_keyword)); + + map->pwg = _cupsStrAlloc(pwg_keyword); + map->ppd = _cupsStrAlloc(choice->choice); + } + } + + if ((ppd_attr = ppdFindAttr(ppd, "APPrinterPreset", NULL)) != NULL) + { + /* + * Copy and convert APPrinterPreset (output-mode + print-quality) data... + */ + + const char *quality, /* com.apple.print.preset.quality value */ + *output_mode, /* com.apple.print.preset.output-mode value */ + *color_model_val, /* ColorModel choice */ + *graphics_type, /* com.apple.print.preset.graphicsType value */ + *paper_coating; /* com.apple.print.preset.media-front-coating value */ + + + do + { + num_options = _ppdParseOptions(ppd_attr->value, 0, &options, + _PPD_PARSE_ALL); + + if ((quality = cupsGetOption("com.apple.print.preset.quality", + num_options, options)) != NULL) + { + /* + * Get the print-quality for this preset... + */ + + if (!strcmp(quality, "low")) + pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT; + else if (!strcmp(quality, "high")) + pwg_print_quality = _PWG_PRINT_QUALITY_HIGH; + else + pwg_print_quality = _PWG_PRINT_QUALITY_NORMAL; + + /* + * Ignore graphicsType "Photo" presets that are not high quality. + */ + + graphics_type = cupsGetOption("com.apple.print.preset.graphicsType", + num_options, options); + + if (pwg_print_quality != _PWG_PRINT_QUALITY_HIGH && graphics_type && + !strcmp(graphics_type, "Photo")) + continue; + + /* + * Ignore presets for normal and draft quality where the coating + * isn't "none" or "autodetect". + */ + + paper_coating = cupsGetOption( + "com.apple.print.preset.media-front-coating", + num_options, options); + + if (pwg_print_quality != _PWG_PRINT_QUALITY_HIGH && paper_coating && + strcmp(paper_coating, "none") && + strcmp(paper_coating, "autodetect")) + continue; + + /* + * Get the output mode for this preset... + */ + + output_mode = cupsGetOption("com.apple.print.preset.output-mode", + num_options, options); + color_model_val = cupsGetOption("ColorModel", num_options, options); + + if (output_mode) + { + if (!strcmp(output_mode, "monochrome")) + pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME; + else + pwg_output_mode = _PWG_OUTPUT_MODE_COLOR; + } + else if (color_model_val) + { + if (!strcasecmp(color_model_val, "Gray")) + pwg_output_mode = _PWG_OUTPUT_MODE_MONOCHROME; + else + pwg_output_mode = _PWG_OUTPUT_MODE_COLOR; + } + else + pwg_output_mode = _PWG_OUTPUT_MODE_COLOR; + + /* + * Save the options for this combination as needed... + */ + + if (!pwg->num_presets[pwg_output_mode][pwg_print_quality]) + pwg->num_presets[pwg_output_mode][pwg_print_quality] = + _ppdParseOptions(ppd_attr->value, 0, + pwg->presets[pwg_output_mode] + + pwg_print_quality, _PPD_PARSE_OPTIONS); + } + + cupsFreeOptions(num_options, options); + } + while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset", NULL)) != NULL); + } + + if (!pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_DRAFT] && + !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_NORMAL] && + !pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][_PWG_PRINT_QUALITY_HIGH]) + { + /* + * Try adding some common color options to create grayscale presets. These + * are listed in order of popularity... + */ + + const char *color_option = NULL, /* Color control option */ + *gray_choice = NULL; /* Choice to select grayscale */ + + if ((color_model = ppdFindOption(ppd, "ColorModel")) != NULL && + ppdFindChoice(color_model, "Gray")) + { + color_option = "ColorModel"; + gray_choice = "Gray"; + } + else if ((color_model = ppdFindOption(ppd, "HPColorMode")) != NULL && + ppdFindChoice(color_model, "grayscale")) + { + color_option = "HPColorMode"; + gray_choice = "grayscale"; + } + else if ((color_model = ppdFindOption(ppd, "BRMonoColor")) != NULL && + ppdFindChoice(color_model, "Mono")) + { + color_option = "BRMonoColor"; + gray_choice = "Mono"; + } + else if ((color_model = ppdFindOption(ppd, "CNIJSGrayScale")) != NULL && + ppdFindChoice(color_model, "1")) + { + color_option = "CNIJSGrayScale"; + gray_choice = "1"; + } + else if ((color_model = ppdFindOption(ppd, "HPColorAsGray")) != NULL && + ppdFindChoice(color_model, "True")) + { + color_option = "HPColorAsGray"; + gray_choice = "True"; + } + + if (color_option && gray_choice) + { + /* + * Copy and convert ColorModel (output-mode) data... + */ + + cups_option_t *coption, /* Color option */ + *moption; /* Monochrome option */ + + for (pwg_print_quality = _PWG_PRINT_QUALITY_DRAFT; + pwg_print_quality < _PWG_PRINT_QUALITY_MAX; + pwg_print_quality ++) + { + if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][pwg_print_quality]) + { + /* + * Copy the color options... + */ + + num_options = pwg->num_presets[_PWG_OUTPUT_MODE_COLOR] + [pwg_print_quality]; + options = calloc(sizeof(cups_option_t), num_options); + + if (options) + { + for (i = num_options, moption = options, + coption = pwg->presets[_PWG_OUTPUT_MODE_COLOR] + [pwg_print_quality]; + i > 0; + i --, moption ++, coption ++) + { + moption->name = _cupsStrRetain(coption->name); + moption->value = _cupsStrRetain(coption->value); + } + + pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] = + num_options; + pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] = + options; + } + } + else if (pwg_print_quality != _PWG_PRINT_QUALITY_NORMAL) + continue; + + /* + * Add the grayscale option to the preset... + */ + + pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME][pwg_print_quality] = + cupsAddOption(color_option, gray_choice, + pwg->num_presets[_PWG_OUTPUT_MODE_MONOCHROME] + [pwg_print_quality], + pwg->presets[_PWG_OUTPUT_MODE_MONOCHROME] + + pwg_print_quality); + } + } + } + + /* + * Copy and convert Duplex (sides) data... + */ + + if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "JCLDuplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL) + duplex = ppdFindOption(ppd, "KD03Duplex"); + + if (duplex) + { + pwg->sides_option = _cupsStrAlloc(duplex->keyword); + + for (i = duplex->num_choices, choice = duplex->choices; + i > 0; + i --, choice ++) + { + if ((!strcasecmp(choice->choice, "None") || + !strcasecmp(choice->choice, "False")) && !pwg->sides_1sided) + pwg->sides_1sided = _cupsStrAlloc(choice->choice); + else if ((!strcasecmp(choice->choice, "DuplexNoTumble") || + !strcasecmp(choice->choice, "LongEdge") || + !strcasecmp(choice->choice, "Top")) && !pwg->sides_2sided_long) + pwg->sides_2sided_long = _cupsStrAlloc(choice->choice); + else if ((!strcasecmp(choice->choice, "DuplexTumble") || + !strcasecmp(choice->choice, "ShortEdge") || + !strcasecmp(choice->choice, "Bottom")) && + !pwg->sides_2sided_short) + pwg->sides_2sided_short = _cupsStrAlloc(choice->choice); + } + } + + return (pwg); + + /* + * If we get here we need to destroy the PWG mapping data and return NULL... + */ + + create_error: + + _cupsSetError(IPP_INTERNAL_ERROR, _("Out of memory."), 1); + _pwgDestroy(pwg); + + return (NULL); +} + + +/* + * '_pwgGetBin()' - Get the PWG output-bin keyword associated with a PPD + * OutputBin. + */ + +const char * /* O - output-bin or NULL */ +_pwgGetBin(_pwg_t *pwg, /* I - PWG mapping data */ + const char *output_bin) /* I - PPD OutputBin string */ +{ + int i; /* Looping var */ + + + /* + * Range check input... + */ + + if (!pwg || !output_bin) + return (NULL); + + /* + * Look up the OutputBin string... + */ + + + for (i = 0; i < pwg->num_bins; i ++) + if (!strcasecmp(output_bin, pwg->bins[i].ppd)) + return (pwg->bins[i].pwg); + + return (NULL); +} + + +/* + * '_pwgGetInputSlot()' - Get the PPD InputSlot associated with the job + * attributes or a keyword string. + */ + +const char * /* O - PPD InputSlot or NULL */ +_pwgGetInputSlot(_pwg_t *pwg, /* I - PWG mapping data */ + ipp_t *job, /* I - Job attributes or NULL */ + const char *keyword) /* I - Keyword string or NULL */ +{ + /* + * Range check input... + */ + + if (!pwg || pwg->num_sources == 0 || (!job && !keyword)) + return (NULL); + + if (job && !keyword) + { + /* + * Lookup the media-col attribute and any media-source found there... + */ + + ipp_attribute_t *media_col, /* media-col attribute */ + *media_source; /* media-source attribute */ + _pwg_size_t size; /* Dimensional size */ + int margins_set; /* Were the margins set? */ + + media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION); + if (media_col && + (media_source = ippFindAttribute(media_col->values[0].collection, + "media-source", + IPP_TAG_KEYWORD)) != NULL) + { + /* + * Use the media-source value from media-col... + */ + + keyword = media_source->values[0].string.text; + } + else if (_pwgInitSize(&size, job, &margins_set)) + { + /* + * For media <= 5x7, look for a photo tray... + */ + + if (size.width <= (5 * 2540) && size.length <= (7 * 2540)) + keyword = "photo"; + } + } + + if (keyword) + { + int i; /* Looping var */ + + for (i = 0; i < pwg->num_sources; i ++) + if (!strcasecmp(keyword, pwg->sources[i].pwg)) + return (pwg->sources[i].ppd); + } + + return (NULL); +} + + +/* + * '_pwgGetMediaType()' - Get the PPD MediaType associated with the job + * attributes or a keyword string. + */ + +const char * /* O - PPD MediaType or NULL */ +_pwgGetMediaType(_pwg_t *pwg, /* I - PWG mapping data */ + ipp_t *job, /* I - Job attributes or NULL */ + const char *keyword) /* I - Keyword string or NULL */ +{ + /* + * Range check input... + */ + + if (!pwg || pwg->num_types == 0 || (!job && !keyword)) + return (NULL); + + if (job && !keyword) + { + /* + * Lookup the media-col attribute and any media-source found there... + */ + + ipp_attribute_t *media_col, /* media-col attribute */ + *media_type; /* media-type attribute */ + + media_col = ippFindAttribute(job, "media-col", IPP_TAG_BEGIN_COLLECTION); + if (media_col) + { + if ((media_type = ippFindAttribute(media_col->values[0].collection, + "media-type", + IPP_TAG_KEYWORD)) == NULL) + media_type = ippFindAttribute(media_col->values[0].collection, + "media-type", IPP_TAG_NAME); + + if (media_type) + keyword = media_type->values[0].string.text; + } + } + + if (keyword) + { + int i; /* Looping var */ + + for (i = 0; i < pwg->num_types; i ++) + if (!strcasecmp(keyword, pwg->types[i].pwg)) + return (pwg->types[i].ppd); + } + + return (NULL); +} + + +/* + * '_pwgGetOutputBin()' - Get the PPD OutputBin associated with the keyword + * string. + */ + +const char * /* O - PPD OutputBin or NULL */ +_pwgGetOutputBin(_pwg_t *pwg, /* I - PWG mapping data */ + const char *output_bin)/* I - Keyword string */ +{ + int i; /* Looping var */ + + + /* + * Range check input... + */ + + if (!pwg || !output_bin) + return (NULL); + + /* + * Look up the OutputBin string... + */ + + + for (i = 0; i < pwg->num_bins; i ++) + if (!strcasecmp(output_bin, pwg->bins[i].pwg)) + return (pwg->bins[i].ppd); + + return (NULL); +} + + +/* + * '_pwgGetPageSize()' - Get the PPD PageSize associated with the job + * attributes or a keyword string. + */ + +const char * /* O - PPD PageSize or NULL */ +_pwgGetPageSize(_pwg_t *pwg, /* I - PWG mapping data */ + ipp_t *job, /* I - Job attributes or NULL */ + const char *keyword, /* I - Keyword string or NULL */ + int *exact) /* O - 1 if exact match, 0 otherwise */ +{ + int i; /* Looping var */ + _pwg_size_t *size, /* Current size */ + *closest, /* Closest size */ + jobsize; /* Size data from job */ + int margins_set, /* Were the margins set? */ + dwidth, /* Difference in width */ + dlength, /* Difference in length */ + dleft, /* Difference in left margins */ + dright, /* Difference in right margins */ + dbottom, /* Difference in bottom margins */ + dtop, /* Difference in top margins */ + dmin, /* Minimum difference */ + dclosest; /* Closest difference */ + const char *ppd_name; /* PPD media name */ + + + DEBUG_printf(("_pwgGetPageSize(pwg=%p, job=%p, keyword=\"%s\", exact=%p)", + pwg, job, keyword, exact)); + + /* + * Range check input... + */ + + if (!pwg || (!job && !keyword)) + return (NULL); + + if (exact) + *exact = 0; + + ppd_name = keyword; + + if (job) + { + /* + * Try getting the PPD media name from the job attributes... + */ + + ipp_attribute_t *attr; /* Job attribute */ + + if ((attr = ippFindAttribute(job, "PageSize", IPP_TAG_ZERO)) == NULL) + if ((attr = ippFindAttribute(job, "PageRegion", IPP_TAG_ZERO)) == NULL) + attr = ippFindAttribute(job, "media", IPP_TAG_ZERO); + +#ifdef DEBUG + if (attr) + DEBUG_printf(("1_pwgGetPageSize: Found attribute %s (%s)", attr->name, + ippTagString(attr->value_tag))); + else + DEBUG_puts("1_pwgGetPageSize: Did not find media attribute."); +#endif /* DEBUG */ + + if (attr && (attr->value_tag == IPP_TAG_NAME || + attr->value_tag == IPP_TAG_KEYWORD)) + ppd_name = attr->values[0].string.text; + } + + DEBUG_printf(("1_pwgGetPageSize: ppd_name=\"%s\"", ppd_name)); + + if (ppd_name) + { + /* + * Try looking up the named PPD size first... + */ + + for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++) + { + DEBUG_printf(("2_pwgGetPageSize: size[%d]=[\"%s\" \"%s\"]", + (int)(size - pwg->sizes), size->map.pwg, size->map.ppd)); + + if (!strcasecmp(ppd_name, size->map.ppd) || + !strcasecmp(ppd_name, size->map.pwg)) + { + if (exact) + *exact = 1; + + DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\"", ppd_name)); + + return (size->map.ppd); + } + } + } + + if (job && !keyword) + { + /* + * Get the size using media-col or media, with the preference being + * media-col. + */ + + if (!_pwgInitSize(&jobsize, job, &margins_set)) + return (NULL); + } + else + { + /* + * Get the size using a media keyword... + */ + + _pwg_media_t *media; /* Media definition */ + + + if ((media = _pwgMediaForPWG(keyword)) == NULL) + if ((media = _pwgMediaForLegacy(keyword)) == NULL) + if ((media = _pwgMediaForPPD(keyword)) == NULL) + return (NULL); + + jobsize.width = media->width; + jobsize.length = media->length; + margins_set = 0; + } + + /* + * Now that we have the dimensions and possibly the margins, look at the + * available sizes and find the match... + */ + + closest = NULL; + dclosest = 999999999; + + if (!ppd_name || strncasecmp(ppd_name, "Custom.", 7) || + strncasecmp(ppd_name, "custom_", 7)) + { + for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++) + { + /* + * Adobe uses a size matching algorithm with an epsilon of 5 points, which + * is just about 176/2540ths... + */ + + dwidth = size->width - jobsize.width; + dlength = size->length - jobsize.length; + + if (dwidth <= -176 || dwidth >= 176 || dlength <= -176 || dlength >= 176) + continue; + + if (margins_set) + { + /* + * Use a tighter epsilon of 1 point (35/2540ths) for margins... + */ + + dleft = size->left - jobsize.left; + dright = size->right - jobsize.right; + dtop = size->top - jobsize.top; + dbottom = size->bottom - jobsize.bottom; + + if (dleft <= -35 || dleft >= 35 || dright <= -35 || dright >= 35 || + dtop <= -35 || dtop >= 35 || dbottom <= -35 || dbottom >= 35) + { + dleft = dleft < 0 ? -dleft : dleft; + dright = dright < 0 ? -dright : dright; + dbottom = dbottom < 0 ? -dbottom : dbottom; + dtop = dtop < 0 ? -dtop : dtop; + dmin = dleft + dright + dbottom + dtop; + + if (dmin < dclosest) + { + dclosest = dmin; + closest = size; + } + + continue; + } + } + + if (exact) + *exact = 1; + + DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\"", size->map.ppd)); + + return (size->map.ppd); + } + } + + if (closest) + { + DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\" (closest)", + closest->map.ppd)); + + return (closest->map.ppd); + } + + /* + * If we get here we need to check for custom page size support... + */ + + if (jobsize.width >= pwg->custom_min_width && + jobsize.width <= pwg->custom_max_width && + jobsize.length >= pwg->custom_min_length && + jobsize.length <= pwg->custom_max_length) + { + /* + * In range, format as Custom.WWWWxLLLL (points). + */ + + snprintf(pwg->custom_ppd_size, sizeof(pwg->custom_ppd_size), "Custom.%dx%d", + (int)_PWG_TOPTS(jobsize.width), (int)_PWG_TOPTS(jobsize.length)); + + if (margins_set && exact) + { + dleft = pwg->custom_size.left - jobsize.left; + dright = pwg->custom_size.right - jobsize.right; + dtop = pwg->custom_size.top - jobsize.top; + dbottom = pwg->custom_size.bottom - jobsize.bottom; + + if (dleft > -35 && dleft < 35 && dright > -35 && dright < 35 && + dtop > -35 && dtop < 35 && dbottom > -35 && dbottom < 35) + *exact = 1; + } + else if (exact) + *exact = 1; + + DEBUG_printf(("1_pwgGetPageSize: Returning \"%s\" (custom)", + pwg->custom_ppd_size)); + + return (pwg->custom_ppd_size); + } + + /* + * No custom page size support or the size is out of range - return NULL. + */ + + DEBUG_puts("1_pwgGetPageSize: Returning NULL"); + + return (NULL); +} + + +/* + * '_pwgGetSize()' - Get the PWG size associated with a PPD PageSize. + */ + +_pwg_size_t * /* O - PWG size or NULL */ +_pwgGetSize(_pwg_t *pwg, /* I - PWG mapping data */ + const char *page_size) /* I - PPD PageSize */ +{ + int i; + _pwg_size_t *size; /* Current size */ + + + /* + * Range check input... + */ + + if (!pwg || !page_size) + return (NULL); + + if (!strncasecmp(page_size, "Custom.", 7)) + { + /* + * Custom size; size name can be one of the following: + * + * Custom.WIDTHxLENGTHin - Size in inches + * Custom.WIDTHxLENGTHft - Size in feet + * Custom.WIDTHxLENGTHcm - Size in centimeters + * Custom.WIDTHxLENGTHmm - Size in millimeters + * Custom.WIDTHxLENGTHm - Size in meters + * Custom.WIDTHxLENGTH[pt] - Size in points + */ + + double w, l; /* Width and length of page */ + char *ptr; /* Pointer into PageSize */ + struct lconv *loc; /* Locale data */ + + loc = localeconv(); + w = (float)_cupsStrScand(page_size + 7, &ptr, loc); + if (!ptr || *ptr != 'x') + return (NULL); + + l = (float)_cupsStrScand(ptr + 1, &ptr, loc); + if (!ptr) + return (NULL); + + if (!strcasecmp(ptr, "in")) + { + w *= 2540.0; + l *= 2540.0; + } + else if (!strcasecmp(ptr, "ft")) + { + w *= 12.0 * 2540.0; + l *= 12.0 * 2540.0; + } + else if (!strcasecmp(ptr, "mm")) + { + w *= 100.0; + l *= 100.0; + } + else if (!strcasecmp(ptr, "cm")) + { + w *= 1000.0; + l *= 1000.0; + } + else if (!strcasecmp(ptr, "m")) + { + w *= 100000.0; + l *= 100000.0; + } + else + { + w *= 2540.0 / 72.0; + l *= 2540.0 / 72.0; + } + + pwg->custom_size.width = (int)w; + pwg->custom_size.length = (int)l; + + return (&(pwg->custom_size)); + } + + /* + * Not a custom size - look it up... + */ + + for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++) + if (!strcasecmp(page_size, size->map.ppd)) + return (size); + + return (NULL); +} + + +/* + * '_pwgGetSource()' - Get the PWG media-source associated with a PPD InputSlot. + */ + +const char * /* O - PWG media-source keyword */ +_pwgGetSource(_pwg_t *pwg, /* I - PWG mapping data */ + const char *input_slot) /* I - PPD InputSlot */ +{ + int i; /* Looping var */ + _pwg_map_t *source; /* Current source */ + + + /* + * Range check input... + */ + + if (!pwg || !input_slot) + return (NULL); + + for (i = pwg->num_sources, source = pwg->sources; i > 0; i --, source ++) + if (!strcasecmp(input_slot, source->ppd)) + return (source->pwg); + + return (NULL); +} + + +/* + * '_pwgGetType()' - Get the PWG media-type associated with a PPD MediaType. + */ + +const char * /* O - PWG media-type keyword */ +_pwgGetType(_pwg_t *pwg, /* I - PWG mapping data */ + const char *media_type) /* I - PPD MediaType */ +{ + int i; /* Looping var */ + _pwg_map_t *type; /* Current type */ + + + /* + * Range check input... + */ + + if (!pwg || !media_type) + return (NULL); + + for (i = pwg->num_types, type = pwg->types; i > 0; i --, type ++) + if (!strcasecmp(media_type, type->ppd)) + return (type->pwg); + + return (NULL); +} + + +/* + * '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG source. + */ + +const char * /* O - InputSlot name */ +_pwgInputSlotForSource( + const char *media_source, /* I - PWG media-source */ + char *name, /* I - Name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + /* + * Range check input... + */ + + if (!media_source || !name || namesize < PPD_MAX_NAME) + return (NULL); + + if (strcasecmp(media_source, "main")) + strlcpy(name, "Cassette", namesize); + else if (strcasecmp(media_source, "alternate")) + strlcpy(name, "Multipurpose", namesize); + else if (strcasecmp(media_source, "large-capacity")) + strlcpy(name, "LargeCapacity", namesize); + else if (strcasecmp(media_source, "bottom")) + strlcpy(name, "Lower", namesize); + else if (strcasecmp(media_source, "middle")) + strlcpy(name, "Middle", namesize); + else if (strcasecmp(media_source, "top")) + strlcpy(name, "Upper", namesize); + else if (strcasecmp(media_source, "rear")) + strlcpy(name, "Rear", namesize); + else if (strcasecmp(media_source, "side")) + strlcpy(name, "Side", namesize); + else if (strcasecmp(media_source, "envelope")) + strlcpy(name, "Envelope", namesize); + else if (strcasecmp(media_source, "main-roll")) + strlcpy(name, "Roll", namesize); + else if (strcasecmp(media_source, "alternate-roll")) + strlcpy(name, "Roll2", namesize); + else + pwg_ppdize_name(media_source, name, namesize); + + return (name); +} + + +/* + * '_pwgMediaTypeForType()' - Get the MediaType name for the given PWG type. + */ + +const char * /* O - MediaType name */ +_pwgMediaTypeForType( + const char *media_type, /* I - PWG media-source */ + char *name, /* I - Name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + /* + * Range check input... + */ + + if (!media_type || !name || namesize < PPD_MAX_NAME) + return (NULL); + + if (strcasecmp(media_type, "auto")) + strlcpy(name, "Auto", namesize); + else if (strcasecmp(media_type, "cardstock")) + strlcpy(name, "Cardstock", namesize); + else if (strcasecmp(media_type, "envelope")) + strlcpy(name, "Envelope", namesize); + else if (strcasecmp(media_type, "photographic-glossy")) + strlcpy(name, "Glossy", namesize); + else if (strcasecmp(media_type, "photographic-high-gloss")) + strlcpy(name, "HighGloss", namesize); + else if (strcasecmp(media_type, "photographic-matte")) + strlcpy(name, "Matte", namesize); + else if (strcasecmp(media_type, "stationery")) + strlcpy(name, "Plain", namesize); + else if (strcasecmp(media_type, "stationery-coated")) + strlcpy(name, "Coated", namesize); + else if (strcasecmp(media_type, "stationery-inkjet")) + strlcpy(name, "Inkjet", namesize); + else if (strcasecmp(media_type, "stationery-letterhead")) + strlcpy(name, "Letterhead", namesize); + else if (strcasecmp(media_type, "stationery-preprinted")) + strlcpy(name, "Preprinted", namesize); + else if (strcasecmp(media_type, "transparency")) + strlcpy(name, "Transparency", namesize); + else + pwg_ppdize_name(media_type, name, namesize); + + return (name); +} + + +/* + * '_pwgPageSizeForMedia()' - Get the PageSize name for the given media. + */ + +const char * /* O - PageSize name */ +_pwgPageSizeForMedia( + _pwg_media_t *media, /* I - Media */ + char *name, /* I - PageSize name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + const char *sizeptr, /* Pointer to size in PWG name */ + *dimptr; /* Pointer to dimensions in PWG name */ + + + /* + * Range check input... + */ + + if (!media || !name || namesize < PPD_MAX_NAME) + return (NULL); + + /* + * Copy or generate a PageSize name... + */ + + if (media->ppd) + { + /* + * Use a standard Adobe name... + */ + + strlcpy(name, media->ppd, namesize); + } + else if (!media->pwg || !strncmp(media->pwg, "custom_", 7) || + (sizeptr = strchr(media->pwg, '_')) == NULL || + (dimptr = strchr(sizeptr + 1, '_')) == NULL || + (dimptr - sizeptr) > namesize) + { + /* + * Use a name of the form "wNNNhNNN"... + */ + + snprintf(name, namesize, "w%dh%d", (int)_PWG_TOPTS(media->width), + (int)_PWG_TOPTS(media->length)); + } + else + { + /* + * Copy the size name from class_sizename_dimensions... + */ + + memcpy(name, sizeptr + 1, dimptr - sizeptr - 1); + name[dimptr - sizeptr - 1] = '\0'; + } + + return (name); +} + + +/* + * 'pwg_ppdize_name()' - Convert an IPP keyword to a PPD keyword. + */ + +static void +pwg_ppdize_name(const char *ipp, /* I - IPP keyword */ + char *name, /* I - Name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + char *ptr, /* Pointer into name buffer */ + *end; /* End of name buffer */ + + + *name = toupper(*ipp++); + + for (ptr = name + 1, end = name + namesize - 1; *ipp && ptr < end;) + { + if (*ipp == '-' && _cups_isalpha(ipp[1])) + { + ipp ++; + *ptr++ = toupper(*ipp++ & 255); + } + else + *ptr++ = *ipp++; + } + + *ptr = '\0'; +} + + +/* + * 'pwg_unppdize_name()' - Convert a PPD keyword to a lowercase IPP keyword. + */ + +static void +pwg_unppdize_name(const char *ppd, /* I - PPD keyword */ + char *name, /* I - Name buffer */ + size_t namesize) /* I - Size of name buffer */ +{ + char *ptr, /* Pointer into name buffer */ + *end; /* End of name buffer */ + + + for (ptr = name, end = name + namesize - 1; *ppd && ptr < end; ppd ++) + { + if (_cups_isalnum(*ppd) || *ppd == '-') + *ptr++ = tolower(*ppd & 255); + else if (*ppd == '_' || *ppd == '.') + *ptr++ = '-'; + + if (!_cups_isupper(*ppd) && _cups_isalnum(*ppd) && + _cups_isupper(ppd[1]) && ptr < end) + *ptr++ = '-'; + } + + *ptr = '\0'; +} + + +/* + * End of "$Id$". + */ diff --git a/cups/pwg-private.h b/cups/pwg-private.h new file mode 100644 index 0000000000..0cfe80c027 --- /dev/null +++ b/cups/pwg-private.h @@ -0,0 +1,167 @@ +/* + * "$Id$" + * + * Private PWG media API definitions for CUPS. + * + * Copyright 2009-2010 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_PWG_PRIVATE_H_ +# define _CUPS_PWG_PRIVATE_H_ + + +/* + * Include necessary headers... + */ + +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Macros... + */ + +/* Convert from points to 2540ths */ +# define _PWG_FROMPTS(n) (int)((n) * 2540 / 72) +/* Convert from 2540ths to points */ +# define _PWG_TOPTS(n) ((n) * 72.0 / 2540.0) + + +/* + * Types and structures... + */ + +typedef enum _pwg_output_mode_e /**** PWG output-mode indices ****/ +{ + _PWG_OUTPUT_MODE_MONOCHROME = 0, /* output-mode=monochrome */ + _PWG_OUTPUT_MODE_COLOR, /* output-mode=color */ + _PWG_OUTPUT_MODE_MAX +} _pwg_output_mode_t; + +typedef enum _pwg_print_quality_e /**** PWG print-quality indices ****/ +{ + _PWG_PRINT_QUALITY_DRAFT = 0, /* print-quality=3 */ + _PWG_PRINT_QUALITY_NORMAL, /* print-quality=4 */ + _PWG_PRINT_QUALITY_HIGH, /* print-quality=5 */ + _PWG_PRINT_QUALITY_MAX +} _pwg_print_quality_t; + +typedef struct _pwg_media_s /**** Common media size data ****/ +{ + const char *pwg, /* PWG 5101.1 "self describing" name */ + *legacy, /* IPP/ISO legacy name */ + *ppd; /* Standard Adobe PPD name */ + int width, /* Width in 2540ths */ + length; /* Length in 2540ths */ +} _pwg_media_t; + +typedef struct _pwg_map_s /**** Map element - PPD to/from PWG */ +{ + char *pwg, /* PWG media keyword */ + *ppd; /* PPD option keyword */ +} _pwg_map_t; + +typedef struct _pwg_size_s /**** Size element - PPD to/from PWG */ +{ + _pwg_map_t map; /* Map element */ + int width, /* Width in 2540ths */ + length, /* Length in 2540ths */ + left, /* Left margin in 2540ths */ + bottom, /* Bottom margin in 2540ths */ + right, /* Right margin in 2540ths */ + top; /* Top margin in 2540ths */ +} _pwg_size_t; + +typedef struct _pwg_s /**** PWG-PPD conversion data ****/ +{ + int num_bins; /* Number of output bins */ + _pwg_map_t *bins; /* Output bins */ + int num_sizes; /* Number of media sizes */ + _pwg_size_t *sizes; /* Media sizes */ + int custom_max_width, /* Maximum custom width in 2540ths */ + custom_max_length, /* Maximum custom length in 2540ths */ + custom_min_width, /* Minimum custom width in 2540ths */ + custom_min_length; /* Minimum custom length in 2540ths */ + char *custom_max_keyword, /* Maximum custom size PWG keyword */ + *custom_min_keyword, /* Minimum custom size PWG keyword */ + custom_ppd_size[41]; /* Custom PPD size name */ + _pwg_size_t custom_size; /* Custom size record */ + char *source_option; /* PPD option for media source */ + int num_sources; /* Number of media sources */ + _pwg_map_t *sources; /* Media sources */ + int num_types; /* Number of media types */ + _pwg_map_t *types; /* Media types */ + int num_presets[_PWG_OUTPUT_MODE_MAX][_PWG_PRINT_QUALITY_MAX]; + /* Number of output-mode/print-quality options */ + cups_option_t *presets[_PWG_OUTPUT_MODE_MAX][_PWG_PRINT_QUALITY_MAX]; + /* output-mode/print-quality options */ + char *sides_option, /* PPD option for sides */ + *sides_1sided, /* Choice for one-sided */ + *sides_2sided_long, /* Choice for two-sided-long-edge */ + *sides_2sided_short; /* Choice for two-sided-short-edge */ +} _pwg_t; + + +/* + * Functions... + */ + +extern _pwg_t *_pwgCreateWithFile(const char *filename); +extern _pwg_t *_pwgCreateWithPPD(ppd_file_t *ppd); +extern void _pwgDestroy(_pwg_t *pwg); +extern void _pwgGenerateSize(char *keyword, size_t keysize, + const char *prefix, + const char *ppdname, + int width, int length); +extern const char *_pwgGetBin(_pwg_t *pwg, const char *output_bin); +extern const char *_pwgGetInputSlot(_pwg_t *pwg, ipp_t *job, + const char *keyword); +extern const char *_pwgGetMediaType(_pwg_t *pwg, ipp_t *job, + const char *keyword); +extern const char *_pwgGetOutputBin(_pwg_t *pwg, const char *keyword); +extern const char *_pwgGetPageSize(_pwg_t *pwg, ipp_t *job, + const char *keyword, int *exact); +extern _pwg_size_t *_pwgGetSize(_pwg_t *pwg, const char *page_size); +extern const char *_pwgGetSource(_pwg_t *pwg, const char *input_slot); +extern const char *_pwgGetType(_pwg_t *pwg, const char *media_type); +extern int _pwgInitSize(_pwg_size_t *size, ipp_t *job, + int *margins_set); +extern const char *_pwgInputSlotForSource(const char *media_source, + char *name, size_t namesize); +extern _pwg_media_t *_pwgMediaForLegacy(const char *legacy); +extern _pwg_media_t *_pwgMediaForPPD(const char *ppd); +extern _pwg_media_t *_pwgMediaForPWG(const char *pwg); +extern _pwg_media_t *_pwgMediaForSize(int width, int length); +extern const char *_pwgMediaTypeForType(const char *media_source, + char *name, size_t namesize); +extern const char *_pwgPageSizeForMedia(_pwg_media_t *media, + char *name, size_t namesize); +extern int _pwgWriteFile(_pwg_t *pwg, const char *filename); + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_PWG_PRIVATE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/raster.h b/cups/raster.h new file mode 100644 index 0000000000..3c4537a1c0 --- /dev/null +++ b/cups/raster.h @@ -0,0 +1,370 @@ +/* + * "$Id$" + * + * Raster file definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * This file is part of the CUPS Imaging library. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_RASTER_H_ +# define _CUPS_RASTER_H_ + +/* + * Include necessary headers... + */ + +# include + +# 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/GPL + * 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 0x52615333 /* RaS3 */ +# define CUPS_RASTER_REVSYNC 0x33536152 /* 3SaR */ + +# define CUPS_RASTER_SYNCv1 0x52615374 /* RaSt */ +# define CUPS_RASTER_REVSYNCv1 0x74536152 /* tSaR */ + +# define CUPS_RASTER_SYNCv2 0x52615332 /* RaS2 */ +# define CUPS_RASTER_REVSYNCv2 0x32536152 /* 2SaR */ + + +/* + * 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_adv_e /**** AdvanceMedia attribute values ****/ +{ + CUPS_ADVANCE_NONE = 0, /* Never advance the roll */ + CUPS_ADVANCE_FILE = 1, /* Advance the roll after this file */ + CUPS_ADVANCE_JOB = 2, /* Advance the roll after this job */ + CUPS_ADVANCE_SET = 3, /* Advance the roll after this set */ + CUPS_ADVANCE_PAGE = 4 /* Advance the roll after this page */ +} cups_adv_t; + +typedef enum cups_bool_e /**** Boolean type ****/ +{ + CUPS_FALSE = 0, /* Logical false */ + CUPS_TRUE = 1 /* Logical true */ +} cups_bool_t; + +typedef enum cups_cspace_e /**** cupsColorSpace attribute values ****/ +{ + CUPS_CSPACE_W = 0, /* Luminance (DeviceGray, gamma 2.2 by default) */ + CUPS_CSPACE_RGB = 1, /* Red, green, blue (DeviceRGB, sRGB by default) */ + CUPS_CSPACE_RGBA = 2, /* Red, green, blue, alpha (DeviceRGB, sRGB by default) */ + CUPS_CSPACE_K = 3, /* Black (DeviceK) */ + CUPS_CSPACE_CMY = 4, /* Cyan, magenta, yellow (DeviceCMY) */ + CUPS_CSPACE_YMC = 5, /* Yellow, magenta, cyan @deprecated@ */ + CUPS_CSPACE_CMYK = 6, /* Cyan, magenta, yellow, black (DeviceCMYK) */ + CUPS_CSPACE_YMCK = 7, /* Yellow, magenta, cyan, black @deprecated@ */ + CUPS_CSPACE_KCMY = 8, /* Black, cyan, magenta, yellow @deprecated@ */ + CUPS_CSPACE_KCMYcm = 9, /* Black, cyan, magenta, yellow, light-cyan, light-magenta @deprecated@ */ + CUPS_CSPACE_GMCK = 10, /* Gold, magenta, yellow, black @deprecated@ */ + CUPS_CSPACE_GMCS = 11, /* Gold, magenta, yellow, silver @deprecated@ */ + CUPS_CSPACE_WHITE = 12, /* White ink (as black) @deprecated@ */ + CUPS_CSPACE_GOLD = 13, /* Gold foil @deprecated@ */ + CUPS_CSPACE_SILVER = 14, /* Silver foil @deprecated@ */ + + CUPS_CSPACE_CIEXYZ = 15, /* CIE XYZ @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_CIELab = 16, /* CIE Lab @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_RGBW = 17, /* Red, green, blue, white (DeviceRGB, sRGB by default) @since CUPS 1.2/Mac OS X 10.5@ */ + CUPS_CSPACE_SW = 18, /* Luminance (gamma 2.2) @since CUPS 1.4.5@ */ + CUPS_CSPACE_SRGB = 19, /* Red, green, blue (sRGB) @since CUPS 1.4.5@ */ + CUPS_CSPACE_ADOBERGB = 20, /* Red, green, blue (Adobe RGB) @since CUPS 1.4.5@ */ + + CUPS_CSPACE_ICC1 = 32, /* ICC-based, 1 color @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC2 = 33, /* ICC-based, 2 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC3 = 34, /* ICC-based, 3 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC4 = 35, /* ICC-based, 4 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC5 = 36, /* ICC-based, 5 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC6 = 37, /* ICC-based, 6 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC7 = 38, /* ICC-based, 7 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC8 = 39, /* ICC-based, 8 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICC9 = 40, /* ICC-based, 9 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICCA = 41, /* ICC-based, 10 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICCB = 42, /* ICC-based, 11 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICCC = 43, /* ICC-based, 12 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICCD = 44, /* ICC-based, 13 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICCE = 45, /* ICC-based, 14 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + CUPS_CSPACE_ICCF = 46, /* ICC-based, 15 colors @since CUPS 1.1.19/Mac OS X 10.3@ */ + + CUPS_CSPACE_DEVICE1 = 48, /* DeviceN, 1 color @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE2 = 49, /* DeviceN, 2 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE3 = 50, /* DeviceN, 3 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE4 = 51, /* DeviceN, 4 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE5 = 52, /* DeviceN, 5 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE6 = 53, /* DeviceN, 6 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE7 = 54, /* DeviceN, 7 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE8 = 55, /* DeviceN, 8 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICE9 = 56, /* DeviceN, 9 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICEA = 57, /* DeviceN, 10 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICEB = 58, /* DeviceN, 11 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICEC = 59, /* DeviceN, 12 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICED = 60, /* DeviceN, 13 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICEE = 61, /* DeviceN, 14 colors @since CUPS 1.4.5@ */ + CUPS_CSPACE_DEVICEF = 62 /* DeviceN, 15 colors @since CUPS 1.4.5@ */ +} cups_cspace_t; + +typedef enum cups_cut_e /**** CutMedia attribute values ****/ +{ + CUPS_CUT_NONE = 0, /* Never cut the roll */ + CUPS_CUT_FILE = 1, /* Cut the roll after this file */ + CUPS_CUT_JOB = 2, /* Cut the roll after this job */ + CUPS_CUT_SET = 3, /* Cut the roll after this set */ + CUPS_CUT_PAGE = 4 /* Cut the roll after this page */ +} cups_cut_t; + +typedef enum cups_edge_e /**** LeadingEdge attribute values ****/ +{ + CUPS_EDGE_TOP = 0, /* Leading edge is the top of the page */ + CUPS_EDGE_RIGHT = 1, /* Leading edge is the right of the page */ + CUPS_EDGE_BOTTOM = 2, /* Leading edge is the bottom of the page */ + CUPS_EDGE_LEFT = 3 /* Leading edge is the left of the page */ +} cups_edge_t; + +typedef enum cups_jog_e /**** Jog attribute values ****/ +{ + CUPS_JOG_NONE = 0, /* Never move pages */ + CUPS_JOG_FILE = 1, /* Move pages after this file */ + CUPS_JOG_JOB = 2, /* Move pages after this job */ + CUPS_JOG_SET = 3 /* Move pages after this set */ +} cups_jog_t; + +enum cups_mode_e /**** cupsRasterOpen modes ****/ +{ + CUPS_RASTER_READ = 0, /* Open stream for reading */ + CUPS_RASTER_WRITE = 1, /* Open stream for writing */ + CUPS_RASTER_WRITE_COMPRESSED = 2 /* Open stream for compressed writing @since CUPS 1.3/Mac OS X 10.5@ */ +}; + +typedef enum cups_mode_e cups_mode_t; /**** cupsRasterOpen modes ****/ + +typedef enum cups_order_e /**** cupsColorOrder attribute values ****/ +{ + CUPS_ORDER_CHUNKED = 0, /* CMYK CMYK CMYK ... */ + CUPS_ORDER_BANDED = 1, /* CCC MMM YYY KKK ... */ + CUPS_ORDER_PLANAR = 2 /* CCC ... MMM ... YYY ... KKK ... */ +} cups_order_t; + +typedef enum cups_orient_e /**** Orientation attribute values ****/ +{ + CUPS_ORIENT_0 = 0, /* Don't rotate the page */ + CUPS_ORIENT_90 = 1, /* Rotate the page counter-clockwise */ + CUPS_ORIENT_180 = 2, /* Turn the page upside down */ + CUPS_ORIENT_270 = 3 /* Rotate the page clockwise */ +} cups_orient_t; + + +/* + * The page header structure contains the standard PostScript page device + * dictionary, along with some CUPS-specific parameters that are provided + * by the RIPs... + * + * The API supports a "version 1" (from CUPS 1.0 and 1.1) and a "version 2" + * (from CUPS 1.2 and higher) page header, for binary compatibility. + */ + +typedef struct cups_page_header_s /**** Version 1 page header @deprecated@ ****/ +{ + /**** 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 (@link cups_adv_t@) */ + cups_bool_t Collate; /* Collated copies value */ + cups_cut_t CutMedia; /* CutMedia value (@link cups_cut_t@) */ + 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, left, bottom, right, top) */ + cups_bool_t InsertSheet; /* InsertSheet value */ + cups_jog_t Jog; /* Jog value (@link cups_jog_t@) */ + cups_edge_t LeadingEdge; /* LeadingEdge value (@link cups_edge_t@) */ + 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 (@link cups_orient_t@) */ + 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; + +/**** New in CUPS 1.2 ****/ +typedef struct cups_page_header2_s /**** Version 2 page header @since CUPS 1.2/Mac OS X 10.5@ ****/ +{ + /**** 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 (@link cups_adv_t@) */ + cups_bool_t Collate; /* Collated copies value */ + cups_cut_t CutMedia; /* CutMedia value (@link cups_cut_t@) */ + 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, left, bottom, right, top) */ + cups_bool_t InsertSheet; /* InsertSheet value */ + cups_jog_t Jog; /* Jog value (@link cups_jog_t@) */ + cups_edge_t LeadingEdge; /* LeadingEdge value (@link cups_edge_t@) */ + 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 (@link cups_orient_t@) */ + 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 */ + + /**** Version 2 Dictionary Values ****/ + unsigned cupsNumColors; /* Number of color compoents @since CUPS 1.2/Mac OS X 10.5@ */ + float cupsBorderlessScalingFactor; + /* Scaling that was applied to page data @since CUPS 1.2/Mac OS X 10.5@ */ + float cupsPageSize[2]; /* Floating point PageSize (scaling * + * factor not applied) @since CUPS 1.2/Mac OS X 10.5@ */ + float cupsImagingBBox[4]; /* Floating point ImagingBoundingBox + * (scaling factor not applied, left, + * bottom, right, top) @since CUPS 1.2/Mac OS X 10.5@ */ + unsigned cupsInteger[16]; /* User-defined integer values @since CUPS 1.2/Mac OS X 10.5@ */ + float cupsReal[16]; /* User-defined floating-point values @since CUPS 1.2/Mac OS X 10.5@ */ + char cupsString[16][64]; /* User-defined string values @since CUPS 1.2/Mac OS X 10.5@ */ + char cupsMarkerType[64]; /* Ink/toner type @since CUPS 1.2/Mac OS X 10.5@ */ + char cupsRenderingIntent[64];/* Color rendering intent @since CUPS 1.2/Mac OS X 10.5@ */ + char cupsPageSizeName[64]; /* PageSize name @since CUPS 1.2/Mac OS X 10.5@ */ +} cups_page_header2_t; + +typedef struct _cups_raster_s cups_raster_t; + /**** Raster stream data ****/ + +typedef int (*cups_interpret_cb_t)(cups_page_header2_t *header, int preferred_bits); + /**** cupsRasterInterpretPPD callback function + * + * This function is called by + * @link cupsRasterInterpretPPD@ to + * validate (and update, as needed) + * the page header attributes. The + * "preferred_bits" argument provides + * the value of the + * @code cupsPreferredBitsPerColor@ + * key from the PostScript page device + * dictionary and is 0 if undefined. + ****/ + + +/* + * 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) _CUPS_DEPRECATED; +extern unsigned cupsRasterReadPixels(cups_raster_t *r, + unsigned char *p, unsigned len); +extern unsigned cupsRasterWriteHeader(cups_raster_t *r, + cups_page_header_t *h) _CUPS_DEPRECATED; +extern unsigned cupsRasterWritePixels(cups_raster_t *r, + unsigned char *p, unsigned len); + +/**** New in CUPS 1.2 ****/ +extern int cupsRasterInterpretPPD(cups_page_header2_t *h, + ppd_file_t *ppd, + int num_options, + cups_option_t *options, + cups_interpret_cb_t func) _CUPS_API_1_2; +extern unsigned cupsRasterReadHeader2(cups_raster_t *r, + cups_page_header2_t *h) _CUPS_API_1_2; +extern unsigned cupsRasterWriteHeader2(cups_raster_t *r, + cups_page_header2_t *h) _CUPS_API_1_2; + +/**** New in CUPS 1.3 ****/ +extern const char *cupsRasterErrorString(void) _CUPS_API_1_3; + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_RASTER_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/request.c b/cups/request.c new file mode 100644 index 0000000000..56528b50bc --- /dev/null +++ b/cups/request.c @@ -0,0 +1,950 @@ +/* + * "$Id$" + * + * IPP utilities for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsDoFileRequest() - Do an IPP request with a file. + * cupsDoIORequest() - Do an IPP request with file descriptors. + * cupsDoRequest() - Do an IPP request. + * cupsGetResponse() - Get a response to an IPP request. + * cupsReadResponseData() - Read additional data after the IPP response. + * cupsSendRequest() - Send an IPP request. + * cupsWriteRequestData() - Write additional data after an IPP request. + * _cupsSetError() - Set the last IPP status code and status-message. + * _cupsSetHTTPError() - Set the last error using the HTTP status. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include +#include +#include +#include +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif /* O_BINARY */ + + +/* + * 'cupsDoFileRequest()' - Do an IPP request with a file. + * + * This function sends the IPP request to the specified server, retrying + * and authenticating as necessary. The request is freed with @link ippDelete@ + * after receiving a valid IPP response. + */ + +ipp_t * /* O - Response data */ +cupsDoFileRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + ipp_t *request, /* I - IPP request */ + const char *resource, /* I - HTTP resource for POST */ + const char *filename) /* I - File to send or @code NULL@ for none */ +{ + ipp_t *response; /* IPP response data */ + int infile; /* Input file */ + + + DEBUG_printf(("cupsDoFileRequest(http=%p, request=%p(%s), resource=\"%s\", " + "filename=\"%s\")", http, request, + request ? ippOpString(request->request.op.operation_id) : "?", + resource, filename)); + + if (filename) + { + if ((infile = open(filename, O_RDONLY | O_BINARY)) < 0) + { + /* + * Can't get file information! + */ + + _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED, + NULL, 0); + + ippDelete(request); + + return (NULL); + } + } + else + infile = -1; + + response = cupsDoIORequest(http, request, resource, infile, -1); + + if (infile >= 0) + close(infile); + + return (response); +} + + +/* + * 'cupsDoIORequest()' - Do an IPP request with file descriptors. + * + * This function sends the IPP request to the specified server, retrying + * and authenticating as necessary. The request is freed with ippDelete() + * after receiving a valid IPP response. + * + * If "infile" is a valid file descriptor, cupsDoIORequest() copies + * all of the data from the file after the IPP request message. + * + * If "outfile" is a valid file descriptor, cupsDoIORequest() copies + * all of the data after the IPP response message to the file. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +ipp_t * /* O - Response data */ +cupsDoIORequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + ipp_t *request, /* I - IPP request */ + const char *resource, /* I - HTTP resource for POST */ + int infile, /* I - File to read from or -1 for none */ + int outfile) /* I - File to write to or -1 for none */ +{ + ipp_t *response = NULL; /* IPP response data */ + size_t length = 0; /* Content-Length value */ + http_status_t status; /* Status of HTTP request */ + struct stat fileinfo; /* File information */ + int bytes; /* Number of bytes read/written */ + char buffer[32768]; /* Output buffer */ + + + DEBUG_printf(("cupsDoIORequest(http=%p, request=%p(%s), resource=\"%s\", " + "infile=%d, outfile=%d)", http, request, + request ? ippOpString(request->request.op.operation_id) : "?", + resource, infile, outfile)); + + /* + * Range check input... + */ + + if (!request || !resource) + { + ippDelete(request); + + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (NULL); + } + + /* + * Get the default connection as needed... + */ + + if (!http) + if ((http = _cupsConnect()) == NULL) + { + ippDelete(request); + + return (NULL); + } + + /* + * See if we have a file to send... + */ + + if (infile >= 0) + { + if (fstat(infile, &fileinfo)) + { + /* + * Can't get file information! + */ + + _cupsSetError(errno == EBADF ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED, + NULL, 0); + + ippDelete(request); + + return (NULL); + } + +#ifdef WIN32 + if (fileinfo.st_mode & _S_IFDIR) +#else + if (S_ISDIR(fileinfo.st_mode)) +#endif /* WIN32 */ + { + /* + * Can't send a directory... + */ + + ippDelete(request); + + _cupsSetError(IPP_NOT_POSSIBLE, strerror(EISDIR), 0); + + return (NULL); + } + +#ifndef WIN32 + if (!S_ISREG(fileinfo.st_mode)) + length = 0; /* Chunk when piping */ + else +#endif /* !WIN32 */ + length = ippLength(request) + fileinfo.st_size; + } + else + length = ippLength(request); + + DEBUG_printf(("2cupsDoIORequest: Request length=%ld, total length=%ld", + (long)ippLength(request), (long)length)); + + /* + * Clear any "Local" authentication data since it is probably stale... + */ + + if (http->authstring && !strncmp(http->authstring, "Local ", 6)) + httpSetAuthString(http, NULL, NULL); + + /* + * Loop until we can send the request without authorization problems. + */ + + while (response == NULL) + { + DEBUG_puts("2cupsDoIORequest: setup..."); + + /* + * Send the request... + */ + + status = cupsSendRequest(http, request, resource, length); + + DEBUG_printf(("2cupsDoIORequest: status=%d", status)); + + if (status == HTTP_CONTINUE && request->state == IPP_DATA && infile >= 0) + { + DEBUG_puts("2cupsDoIORequest: file write..."); + + /* + * Send the file with the request... + */ + +#ifndef WIN32 + if (S_ISREG(fileinfo.st_mode)) +#endif /* WIN32 */ + lseek(infile, 0, SEEK_SET); + + while ((bytes = (int)read(infile, buffer, sizeof(buffer))) > 0) + { + if (httpCheck(http)) + { + _httpUpdate(http, &status); + + if (status >= HTTP_MULTIPLE_CHOICES) + break; + } + + if (httpWrite2(http, buffer, bytes) < bytes) + break; + } + } + + /* + * Get the server's response... + */ + + if (status == HTTP_CONTINUE || status == HTTP_OK) + { + response = cupsGetResponse(http, resource); + status = http->status; + } + else + httpFlush(http); + + DEBUG_printf(("2cupsDoIORequest: status=%d", status)); + + if (status == HTTP_ERROR || + (status >= HTTP_BAD_REQUEST && status != HTTP_UNAUTHORIZED && + status != HTTP_UPGRADE_REQUIRED)) + { + _cupsSetHTTPError(status); + break; + } + + if (response) + { + if (outfile >= 0) + { + /* + * Write trailing data to file... + */ + + while ((bytes = (int)httpRead2(http, buffer, sizeof(buffer))) > 0) + if (write(outfile, buffer, bytes) < bytes) + break; + } + else + { + /* + * Flush any remaining data... + */ + + httpFlush(http); + } + } + } + + /* + * Delete the original request and return the response... + */ + + ippDelete(request); + + return (response); +} + + +/* + * 'cupsDoRequest()' - Do an IPP request. + * + * This function sends the IPP request to the specified server, retrying + * and authenticating as necessary. The request is freed with ippDelete() + * after receiving a valid IPP response. + */ + +ipp_t * /* O - Response data */ +cupsDoRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + ipp_t *request, /* I - IPP request */ + const char *resource) /* I - HTTP resource for POST */ +{ + DEBUG_printf(("cupsDoRequest(http=%p, request=%p(%s), resource=\"%s\")", + http, request, + request ? ippOpString(request->request.op.operation_id) : "?", + resource)); + + return (cupsDoIORequest(http, request, resource, -1, -1)); +} + + +/* + * 'cupsGetResponse()' - Get a response to an IPP request. + * + * Use this function to get the response for an IPP request sent using + * cupsSendDocument() or cupsSendRequest(). For requests that return + * additional data, use httpRead() after getting a successful response. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ipp_t * /* O - Response or @code NULL@ on HTTP error */ +cupsGetResponse(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *resource) /* I - HTTP resource for POST */ +{ + http_status_t status; /* HTTP status */ + ipp_state_t state; /* IPP read state */ + ipp_t *response = NULL; /* IPP response */ + + + DEBUG_printf(("cupsGetResponse(http=%p, resource=\"%s\")", http, resource)); + + /* + * Connect to the default server as needed... + */ + + if (!http) + http = _cupsConnect(); + + if (!http || (http->state != HTTP_POST_RECV && http->state != HTTP_POST_SEND)) + return (NULL); + + /* + * Check for an unfinished chunked request... + */ + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + { + /* + * Send a 0-length chunk to finish off the request... + */ + + DEBUG_puts("2cupsGetResponse: Finishing chunked POST..."); + + if (httpWrite2(http, "", 0) < 0) + return (NULL); + } + + /* + * Wait for a response from the server... + */ + + DEBUG_printf(("2cupsGetResponse: Update loop, http->status=%d...", + http->status)); + + do + { + status = httpUpdate(http); + } + while (http->state == HTTP_POST_RECV); + + DEBUG_printf(("2cupsGetResponse: status=%d", status)); + + if (status == HTTP_OK) + { + /* + * Get the IPP response... + */ + + response = ippNew(); + + while ((state = ippRead(http, response)) != IPP_DATA) + if (state == IPP_ERROR) + break; + + if (state == IPP_ERROR) + { + /* + * Delete the response... + */ + + DEBUG_puts("1cupsGetResponse: IPP read error!"); + + ippDelete(response); + response = NULL; + + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + } + } + else if (status != HTTP_ERROR) + { + /* + * Flush any error message... + */ + + httpFlush(http); + + /* + * Then handle encryption and authentication... + */ + + if (status == HTTP_UNAUTHORIZED) + { + /* + * See if we can do authentication... + */ + + DEBUG_puts("2cupsGetResponse: Need authorization..."); + + if (!cupsDoAuthentication(http, "POST", resource)) + httpReconnect(http); + else + status = HTTP_AUTHORIZATION_CANCELED; + } + +#ifdef HAVE_SSL + else if (status == HTTP_UPGRADE_REQUIRED) + { + /* + * Force a reconnect with encryption... + */ + + DEBUG_puts("2cupsGetResponse: Need encryption..."); + + if (!httpReconnect(http)) + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); + } +#endif /* HAVE_SSL */ + } + + if (response) + { + ipp_attribute_t *attr; /* status-message attribute */ + + + attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT); + + DEBUG_printf(("1cupsGetResponse: status-code=%s, status-message=\"%s\"", + ippErrorString(response->request.status.status_code), + attr ? attr->values[0].string.text : "")); + + _cupsSetError(response->request.status.status_code, + attr ? attr->values[0].string.text : + ippErrorString(response->request.status.status_code), 0); + } + else if (status != HTTP_OK) + _cupsSetHTTPError(status); + + return (response); +} + + +/* + * 'cupsReadResponseData()' - Read additional data after the IPP response. + * + * This function is used after cupsGetResponse() to read the PPD or document + * files for CUPS_GET_PPD and CUPS_GET_DOCUMENT requests, respectively. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ssize_t /* O - Bytes read, 0 on EOF, -1 on error */ +cupsReadResponseData( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + char *buffer, /* I - Buffer to use */ + size_t length) /* I - Number of bytes to read */ +{ + /* + * Get the default connection as needed... + */ + + DEBUG_printf(("cupsReadResponseData(http=%p, buffer=%p, " + "length=" CUPS_LLFMT ")", http, buffer, CUPS_LLCAST length)); + + if (!http) + { + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + + if ((http = cg->http) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("No active connection"), 1); + return (-1); + } + } + + /* + * Then read from the HTTP connection... + */ + + return (httpRead2(http, buffer, length)); +} + + +/* + * 'cupsSendRequest()' - Send an IPP request. + * + * Use httpWrite() to write any additional data (document, PPD file, etc.) + * for the request, cupsGetResponse() to get the IPP response, and httpRead() + * to read any additional data following the response. Only one request can be + * sent/queued at a time. + * + * Unlike cupsDoFileRequest(), cupsDoIORequest(), and cupsDoRequest(), the + * request is not freed. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +http_status_t /* O - Initial HTTP status */ +cupsSendRequest(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + ipp_t *request, /* I - IPP request */ + const char *resource, /* I - Resource path */ + size_t length) /* I - Length of data to follow or @code CUPS_LENGTH_VARIABLE@ */ +{ + http_status_t status; /* Status of HTTP request */ + int got_status; /* Did we get the status? */ + ipp_state_t state; /* State of IPP processing */ + http_status_t expect; /* Expect: header to use */ + + + DEBUG_printf(("cupsSendRequest(http=%p, request=%p(%s), resource=\"%s\", " + "length=" CUPS_LLFMT ")", http, request, + request ? ippOpString(request->request.op.operation_id) : "?", + resource, CUPS_LLCAST length)); + + /* + * Range check input... + */ + + if (!request || !resource) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (HTTP_ERROR); + } + + /* + * Get the default connection as needed... + */ + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (HTTP_SERVICE_UNAVAILABLE); + +#ifdef HAVE_SSL + /* + * See if we have an auth-info attribute and are communicating over + * a non-local link. If so, encrypt the link so that we can pass + * the authentication information securely... + */ + + if (ippFindAttribute(request, "auth-info", IPP_TAG_TEXT) && + !httpAddrLocalhost(http->hostaddr) && !http->tls && + httpEncryption(http, HTTP_ENCRYPT_REQUIRED)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } +#endif /* HAVE_SSL */ + + /* + * Reconnect if the last response had a "Connection: close"... + */ + + if (!strcasecmp(http->fields[HTTP_FIELD_CONNECTION], "close")) + if (httpReconnect(http)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } + + /* + * Loop until we can send the request without authorization problems. + */ + + expect = HTTP_CONTINUE; + + for (;;) + { + DEBUG_puts("2cupsSendRequest: Setup..."); + + /* + * Setup the HTTP variables needed... + */ + + httpClearFields(http); + httpSetExpect(http, expect); + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); + httpSetLength(http, length); + +#ifdef HAVE_GSSAPI + if (http->authstring && !strncmp(http->authstring, "Negotiate", 9)) + { + /* + * Do not use cached Kerberos credentials since they will look like a + * "replay" attack... + */ + + httpSetField(http, HTTP_FIELD_WWW_AUTHENTICATE, "Negotiate"); + cupsDoAuthentication(http, "POST", resource); + httpSetField(http, HTTP_FIELD_WWW_AUTHENTICATE, ""); + } +#endif /* HAVE_GSSAPI */ + + httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring); + + DEBUG_printf(("2cupsSendRequest: authstring=\"%s\"", http->authstring)); + + /* + * Try the request... + */ + + DEBUG_puts("2cupsSendRequest: Sending HTTP POST..."); + + if (httpPost(http, resource)) + { + if (httpReconnect(http)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } + else + continue; + } + + /* + * Send the IPP data... + */ + + DEBUG_puts("2cupsSendRequest: Writing IPP request..."); + + request->state = IPP_IDLE; + status = HTTP_CONTINUE; + got_status = 0; + + while ((state = ippWrite(http, request)) != IPP_DATA) + if (state == IPP_ERROR) + break; + else if (httpCheck(http)) + { + got_status = 1; + + _httpUpdate(http, &status); + if (status >= HTTP_MULTIPLE_CHOICES) + break; + } + + /* + * Wait up to 1 second to get the 100-continue response as needed... + */ + + if (!got_status) + { + if (expect == HTTP_CONTINUE) + { + DEBUG_puts("2cupsSendRequest: Waiting for 100-continue..."); + + if (httpWait(http, 1000)) + _httpUpdate(http, &status); + } + else if (httpCheck(http)) + _httpUpdate(http, &status); + } + + DEBUG_printf(("2cupsSendRequest: status=%d", status)); + + /* + * Process the current HTTP status... + */ + + if (status >= HTTP_MULTIPLE_CHOICES) + httpFlush(http); + + switch (status) + { + case HTTP_ERROR : + case HTTP_CONTINUE : + case HTTP_OK : + return (status); + + case HTTP_UNAUTHORIZED : + if (cupsDoAuthentication(http, "POST", resource)) + return (HTTP_AUTHORIZATION_CANCELED); + + if (httpReconnect(http)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } + break; + +#ifdef HAVE_SSL + case HTTP_UPGRADE_REQUIRED : + /* + * Flush any error message, reconnect, and then upgrade with + * encryption... + */ + + if (httpReconnect(http)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } + + if (httpEncryption(http, HTTP_ENCRYPT_REQUIRED)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } + break; +#endif /* HAVE_SSL */ + + case HTTP_EXPECTATION_FAILED : + /* + * Don't try using the Expect: header the next time around... + */ + + expect = (http_status_t)0; + + if (httpReconnect(http)) + { + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + return (HTTP_SERVICE_UNAVAILABLE); + } + break; + + default : + /* + * Some other error... + */ + + return (status); + } + } +} + + +/* + * 'cupsWriteRequestData()' - Write additional data after an IPP request. + * + * This function is used after @link cupsSendRequest@ to provide a PPD and + * after @link cupsStartDocument@ to provide a document file. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +http_status_t /* O - @code HTTP_CONTINUE@ if OK or HTTP status on error */ +cupsWriteRequestData( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *buffer, /* I - Bytes to write */ + size_t length) /* I - Number of bytes to write */ +{ + int wused; /* Previous bytes in buffer */ + + + /* + * Get the default connection as needed... + */ + + DEBUG_printf(("cupsWriteRequestData(http=%p, buffer=%p, " + "length=" CUPS_LLFMT ")", http, buffer, CUPS_LLCAST length)); + + if (!http) + { + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + + if ((http = cg->http) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("No active connection"), 1); + return (HTTP_ERROR); + } + } + + /* + * Then write to the HTTP connection... + */ + + wused = http->wused; + + if (httpWrite2(http, buffer, length) < 0) + return (HTTP_ERROR); + + /* + * Finally, check if we have any pending data from the server... + */ + + if (length >= HTTP_MAX_BUFFER || + http->wused < wused || + (wused > 0 && http->wused == length)) + { + /* + * We've written something to the server, so check for response data... + */ + + if (_httpWait(http, 0, 1)) + { + http_status_t status; /* Status from _httpUpdate */ + + _httpUpdate(http, &status); + if (status >= HTTP_MULTIPLE_CHOICES) + httpFlush(http); + + return (status); + } + } + + return (HTTP_CONTINUE); +} + + +/* + * '_cupsSetError()' - Set the last IPP status code and status-message. + */ + +void +_cupsSetError(ipp_status_t status, /* I - IPP status code */ + const char *message, /* I - status-message value */ + int localize) /* I - Localize the message? */ +{ + _cups_globals_t *cg; /* Global data */ + + + if (!message && errno) + { + message = strerror(errno); + localize = 0; + } + + cg = _cupsGlobals(); + cg->last_error = status; + + if (cg->last_status_message) + { + _cupsStrFree(cg->last_status_message); + + cg->last_status_message = NULL; + } + + if (message) + { + if (localize) + { + /* + * Get the message catalog... + */ + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + cg->last_status_message = _cupsStrAlloc(_cupsLangString(cg->lang_default, + message)); + } + else + cg->last_status_message = _cupsStrAlloc(message); + } + + DEBUG_printf(("4_cupsSetError: last_error=%s, last_status_message=\"%s\"", + ippErrorString(cg->last_error), cg->last_status_message)); +} + + +/* + * '_cupsSetHTTPError()' - Set the last error using the HTTP status. + */ + +void +_cupsSetHTTPError(http_status_t status) /* I - HTTP status code */ +{ + switch (status) + { + case HTTP_NOT_FOUND : + _cupsSetError(IPP_NOT_FOUND, httpStatus(status), 0); + break; + + case HTTP_UNAUTHORIZED : + _cupsSetError(IPP_NOT_AUTHENTICATED, httpStatus(status), 0); + break; + + case HTTP_AUTHORIZATION_CANCELED : + case HTTP_FORBIDDEN : + _cupsSetError(IPP_FORBIDDEN, httpStatus(status), 0); + break; + + case HTTP_BAD_REQUEST : + _cupsSetError(IPP_BAD_REQUEST, httpStatus(status), 0); + break; + + case HTTP_REQUEST_TOO_LARGE : + _cupsSetError(IPP_REQUEST_VALUE, httpStatus(status), 0); + break; + + case HTTP_NOT_IMPLEMENTED : + _cupsSetError(IPP_OPERATION_NOT_SUPPORTED, httpStatus(status), 0); + break; + + case HTTP_NOT_SUPPORTED : + _cupsSetError(IPP_VERSION_NOT_SUPPORTED, httpStatus(status), 0); + break; + + default : + DEBUG_printf(("4_cupsSetHTTPError: HTTP error %d mapped to " + "IPP_SERVICE_UNAVAILABLE!", status)); + _cupsSetError(IPP_SERVICE_UNAVAILABLE, httpStatus(status), 0); + break; + } +} + + +/* + * End of "$Id$". + */ diff --git a/cups/sidechannel.c b/cups/sidechannel.c new file mode 100644 index 0000000000..5704c61de6 --- /dev/null +++ b/cups/sidechannel.c @@ -0,0 +1,576 @@ +/* + * "$Id$" + * + * Side-channel API code for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsSideChannelDoRequest() - Send a side-channel command to a backend and + * wait for a response. + * cupsSideChannelRead() - Read a side-channel message. + * cupsSideChannelSNMPGet() - Query a SNMP OID's value. + * cupsSideChannelSNMPWalk() - Query multiple SNMP OID values. + * cupsSideChannelWrite() - Write a side-channel message. + */ + +/* + * Include necessary headers... + */ + +#include "sidechannel.h" +#include "string.h" +#include "debug.h" +#ifdef WIN32 +# include +#else +# include +#endif /* WIN32 */ +#include +#ifdef __hpux +# include +#elif !defined(WIN32) +# include +#endif /* __hpux */ +#ifndef WIN32 +# include +#endif /* !WIN32 */ +#ifdef HAVE_POLL +# include +#endif /* HAVE_POLL */ + + +/* + * 'cupsSideChannelDoRequest()' - Send a side-channel command to a backend and wait for a response. + * + * This function is normally only called by filters, drivers, or port + * monitors in order to communicate with the backend used by the current + * printer. Programs must be prepared to handle timeout or "not + * implemented" status codes, which indicate that the backend or device + * do not support the specified side-channel command. + * + * The "datalen" parameter must be initialized to the size of the buffer + * pointed to by the "data" parameter. cupsSideChannelDoRequest() will + * update the value to contain the number of data bytes in the buffer. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +cups_sc_status_t /* O - Status of command */ +cupsSideChannelDoRequest( + cups_sc_command_t command, /* I - Command to send */ + char *data, /* O - Response data buffer pointer */ + int *datalen, /* IO - Size of data buffer on entry, number of bytes in buffer on return */ + double timeout) /* I - Timeout in seconds */ +{ + cups_sc_status_t status; /* Status of command */ + cups_sc_command_t rcommand; /* Response command */ + + + if (cupsSideChannelWrite(command, CUPS_SC_STATUS_NONE, NULL, 0, timeout)) + return (CUPS_SC_STATUS_TIMEOUT); + + if (cupsSideChannelRead(&rcommand, &status, data, datalen, timeout)) + return (CUPS_SC_STATUS_TIMEOUT); + + if (rcommand != command) + return (CUPS_SC_STATUS_BAD_MESSAGE); + + return (status); +} + + +/* + * 'cupsSideChannelRead()' - Read a side-channel message. + * + * This function is normally only called by backend programs to read + * commands from a filter, driver, or port monitor program. The + * caller must be prepared to handle incomplete or invalid messages + * and return the corresponding status codes. + * + * The "datalen" parameter must be initialized to the size of the buffer + * pointed to by the "data" parameter. cupsSideChannelDoRequest() will + * update the value to contain the number of data bytes in the buffer. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsSideChannelRead( + cups_sc_command_t *command, /* O - Command code */ + cups_sc_status_t *status, /* O - Status code */ + char *data, /* O - Data buffer pointer */ + int *datalen, /* IO - Size of data buffer on entry, number of bytes in buffer on return */ + double timeout) /* I - Timeout in seconds */ +{ + char buffer[16388]; /* Message buffer */ + int bytes; /* Bytes read */ + int templen; /* Data length from message */ + int nfds; /* Number of file descriptors */ +#ifdef HAVE_POLL + struct pollfd pfd; /* Poll structure for poll() */ +#else /* select() */ + fd_set input_set; /* Input set for select() */ + struct timeval stimeout; /* Timeout value for select() */ +#endif /* HAVE_POLL */ + + + DEBUG_printf(("cupsSideChannelRead(command=%p, status=%p, data=%p, " + "datalen=%p(%d), timeout=%.3f)", command, status, data, + datalen, datalen ? *datalen : -1, timeout)); + + /* + * Range check input... + */ + + if (!command || !status) + return (-1); + + /* + * See if we have pending data on the side-channel socket... + */ + +#ifdef HAVE_POLL + pfd.fd = CUPS_SC_FD; + pfd.events = POLLIN; + + while ((nfds = poll(&pfd, 1, + timeout < 0.0 ? -1 : (long)(timeout * 1000))) < 0 && + (errno == EINTR || errno == EAGAIN)) + ; + +#else /* select() */ + FD_ZERO(&input_set); + FD_SET(CUPS_SC_FD, &input_set); + + stimeout.tv_sec = (int)timeout; + stimeout.tv_usec = (int)(timeout * 1000000) % 1000000; + + while ((nfds = select(CUPS_SC_FD + 1, &input_set, NULL, NULL, + timeout < 0.0 ? NULL : &stimeout)) < 0 && + (errno == EINTR || errno == EAGAIN)) + ; + +#endif /* HAVE_POLL */ + + if (nfds < 1) + { + *status = nfds==0 ? CUPS_SC_STATUS_TIMEOUT : CUPS_SC_STATUS_IO_ERROR; + return (-1); + } + + /* + * Read a side-channel message for the format: + * + * Byte(s) Description + * ------- ------------------------------------------- + * 0 Command code + * 1 Status code + * 2-3 Data length (network byte order) <= 16384 + * 4-N Data + */ + + while ((bytes = read(CUPS_SC_FD, buffer, sizeof(buffer))) < 0) + if (errno != EINTR && errno != EAGAIN) + { + DEBUG_printf(("1cupsSideChannelRead: Read error: %s", strerror(errno))); + *command = CUPS_SC_CMD_NONE; + *status = CUPS_SC_STATUS_IO_ERROR; + return (-1); + } + + /* + * Watch for EOF or too few bytes... + */ + + if (bytes < 4) + { + DEBUG_printf(("1cupsSideChannelRead: Short read of %d bytes", bytes)); + *command = CUPS_SC_CMD_NONE; + *status = CUPS_SC_STATUS_BAD_MESSAGE; + return (-1); + } + + /* + * Validate the command code in the message... + */ + + if (buffer[0] < CUPS_SC_CMD_SOFT_RESET || + buffer[0] > CUPS_SC_CMD_SNMP_GET_NEXT) + { + DEBUG_printf(("1cupsSideChannelRead: Bad command %d!", buffer[0])); + *command = CUPS_SC_CMD_NONE; + *status = CUPS_SC_STATUS_BAD_MESSAGE; + return (-1); + } + + *command = (cups_sc_command_t)buffer[0]; + + /* + * Validate the data length in the message... + */ + + templen = ((buffer[2] & 255) << 8) | (buffer[3] & 255); + + if (templen > 0 && (!data || !datalen)) + { + /* + * Either the response is bigger than the provided buffer or the + * response is bigger than we've read... + */ + + *status = CUPS_SC_STATUS_TOO_BIG; + } + else if (!datalen || templen > *datalen || templen > (bytes - 4)) + { + /* + * Either the response is bigger than the provided buffer or the + * response is bigger than we've read... + */ + + *status = CUPS_SC_STATUS_TOO_BIG; + } + else + { + /* + * The response data will fit, copy it over and provide the actual + * length... + */ + + *status = (cups_sc_status_t)buffer[1]; + *datalen = templen; + + memcpy(data, buffer + 4, templen); + } + + DEBUG_printf(("1cupsSideChannelRead: Returning status=%d", *status)); + + return (0); +} + + +/* + * 'cupsSideChannelSNMPGet()' - Query a SNMP OID's value. + * + * This function asks the backend to do a SNMP OID query on behalf of the + * filter, port monitor, or backend using the default community name. + * + * "oid" contains a numeric OID consisting of integers separated by periods, + * for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not + * supported and must be converted to their numeric forms. + * + * On input, "data" and "datalen" provide the location and size of the + * buffer to hold the OID value as a string. HEX-String (binary) values are + * converted to hexadecimal strings representing the binary data, while + * NULL-Value and unknown OID types are returned as the empty string. + * The returned "datalen" does not include the trailing nul. + * + * @code CUPS_SC_STATUS_NOT_IMPLEMENTED@ is returned by backends that do not + * support SNMP queries. @code CUPS_SC_STATUS_NO_RESPONSE@ is returned when + * the printer does not respond to the SNMP query. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +cups_sc_status_t /* O - Query status */ +cupsSideChannelSNMPGet( + const char *oid, /* I - OID to query */ + char *data, /* I - Buffer for OID value */ + int *datalen, /* IO - Size of OID buffer on entry, size of value on return */ + double timeout) /* I - Timeout in seconds */ +{ + cups_sc_status_t status; /* Status of command */ + cups_sc_command_t rcommand; /* Response command */ + char real_data[2048];/* Real data buffer for response */ + int real_datalen, /* Real length of data buffer */ + real_oidlen; /* Length of returned OID string */ + + + DEBUG_printf(("cupsSideChannelSNMPGet(oid=\"%s\", data=%p, datalen=%p(%d), " + "timeout=%.3f)", oid, data, datalen, datalen ? *datalen : -1, + timeout)); + + /* + * Range check input... + */ + + if (!oid || !*oid || !data || !datalen || *datalen < 2) + return (CUPS_SC_STATUS_BAD_MESSAGE); + + *data = '\0'; + + /* + * Send the request to the backend and wait for a response... + */ + + if (cupsSideChannelWrite(CUPS_SC_CMD_SNMP_GET, CUPS_SC_STATUS_NONE, oid, + (int)strlen(oid) + 1, timeout)) + return (CUPS_SC_STATUS_TIMEOUT); + + real_datalen = sizeof(real_data); + if (cupsSideChannelRead(&rcommand, &status, real_data, &real_datalen, timeout)) + return (CUPS_SC_STATUS_TIMEOUT); + + if (rcommand != CUPS_SC_CMD_SNMP_GET) + return (CUPS_SC_STATUS_BAD_MESSAGE); + + if (status == CUPS_SC_STATUS_OK) + { + /* + * Parse the response of the form "oid\0value"... + */ + + real_oidlen = strlen(real_data) + 1; + real_datalen -= real_oidlen; + + if ((real_datalen + 1) > *datalen) + return (CUPS_SC_STATUS_TOO_BIG); + + memcpy(data, real_data + real_oidlen, real_datalen); + data[real_datalen] = '\0'; + + *datalen = real_datalen; + } + + return (status); +} + + +/* + * 'cupsSideChannelSNMPWalk()' - Query multiple SNMP OID values. + * + * This function asks the backend to do multiple SNMP OID queries on behalf + * of the filter, port monitor, or backend using the default community name. + * All OIDs under the "parent" OID are queried and the results are sent to + * the callback function you provide. + * + * "oid" contains a numeric OID consisting of integers separated by periods, + * for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not + * supported and must be converted to their numeric forms. + * + * "timeout" specifies the timeout for each OID query. The total amount of + * time will depend on the number of OID values found and the time required + * for each query. + * + * "cb" provides a function to call for every value that is found. "context" + * is an application-defined pointer that is sent to the callback function + * along with the OID and current data. The data passed to the callback is the + * same as returned by @link cupsSideChannelSNMPGet@. + * + * @code CUPS_SC_STATUS_NOT_IMPLEMENTED@ is returned by backends that do not + * support SNMP queries. @code CUPS_SC_STATUS_NO_RESPONSE@ is returned when + * the printer does not respond to the first SNMP query. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +cups_sc_status_t /* O - Status of first query of @code CUPS_SC_STATUS_OK@ on success */ +cupsSideChannelSNMPWalk( + const char *oid, /* I - First numeric OID to query */ + double timeout, /* I - Timeout for each query in seconds */ + cups_sc_walk_func_t cb, /* I - Function to call with each value */ + void *context) /* I - Application-defined pointer to send to callback */ +{ + cups_sc_status_t status; /* Status of command */ + cups_sc_command_t rcommand; /* Response command */ + char real_data[2048];/* Real data buffer for response */ + int real_datalen, /* Real length of data buffer */ + real_oidlen, /* Length of returned OID string */ + oidlen; /* Length of first OID */ + const char *current_oid; /* Current OID */ + char last_oid[2048]; /* Last OID */ + + + DEBUG_printf(("cupsSideChannelSNMPWalk(oid=\"%s\", timeout=%.3f, cb=%p, " + "context=%p)", oid, timeout, cb, context)); + + /* + * Range check input... + */ + + if (!oid || !*oid || !cb) + return (CUPS_SC_STATUS_BAD_MESSAGE); + + /* + * Loop until the OIDs don't match... + */ + + current_oid = oid; + oidlen = (int)strlen(oid); + last_oid[0] = '\0'; + + do + { + /* + * Send the request to the backend and wait for a response... + */ + + if (cupsSideChannelWrite(CUPS_SC_CMD_SNMP_GET_NEXT, CUPS_SC_STATUS_NONE, + current_oid, (int)strlen(current_oid) + 1, timeout)) + return (CUPS_SC_STATUS_TIMEOUT); + + real_datalen = sizeof(real_data); + if (cupsSideChannelRead(&rcommand, &status, real_data, &real_datalen, + timeout)) + return (CUPS_SC_STATUS_TIMEOUT); + + if (rcommand != CUPS_SC_CMD_SNMP_GET_NEXT) + return (CUPS_SC_STATUS_BAD_MESSAGE); + + if (status == CUPS_SC_STATUS_OK) + { + /* + * Parse the response of the form "oid\0value"... + */ + + if (strncmp(real_data, oid, oidlen) || real_data[oidlen] != '.' || + !strcmp(real_data, last_oid)) + { + /* + * Done with this set of OIDs... + */ + + return (CUPS_SC_STATUS_OK); + } + + if (real_datalen < sizeof(real_data)) + real_data[real_datalen] = '\0'; + + real_oidlen = strlen(real_data) + 1; + real_datalen -= real_oidlen; + + /* + * Call the callback with the OID and data... + */ + + (*cb)(real_data, real_data + real_oidlen, real_datalen, context); + + /* + * Update the current OID... + */ + + current_oid = real_data; + strlcpy(last_oid, current_oid, sizeof(last_oid)); + } + } + while (status == CUPS_SC_STATUS_OK); + + return (status); +} + + +/* + * 'cupsSideChannelWrite()' - Write a side-channel message. + * + * This function is normally only called by backend programs to send + * responses to a filter, driver, or port monitor program. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on error */ +cupsSideChannelWrite( + cups_sc_command_t command, /* I - Command code */ + cups_sc_status_t status, /* I - Status code */ + const char *data, /* I - Data buffer pointer */ + int datalen, /* I - Number of bytes of data */ + double timeout) /* I - Timeout in seconds */ +{ + char buffer[16388]; /* Message buffer */ + int bytes; /* Bytes written */ +#ifdef HAVE_POLL + struct pollfd pfd; /* Poll structure for poll() */ +#else /* select() */ + fd_set output_set; /* Output set for select() */ + struct timeval stimeout; /* Timeout value for select() */ +#endif /* HAVE_POLL */ + + + /* + * Range check input... + */ + + if (command < CUPS_SC_CMD_SOFT_RESET || command > CUPS_SC_CMD_SNMP_GET_NEXT || + datalen < 0 || datalen > 16384 || (datalen > 0 && !data)) + return (-1); + + /* + * See if we can safely write to the side-channel socket... + */ + +#ifdef HAVE_POLL + pfd.fd = CUPS_SC_FD; + pfd.events = POLLOUT; + + if (timeout < 0.0) + { + if (poll(&pfd, 1, -1) < 1) + return (-1); + } + else if (poll(&pfd, 1, (long)(timeout * 1000)) < 1) + return (-1); + +#else /* select() */ + FD_ZERO(&output_set); + FD_SET(CUPS_SC_FD, &output_set); + + if (timeout < 0.0) + { + if (select(CUPS_SC_FD + 1, NULL, &output_set, NULL, NULL) < 1) + return (-1); + } + else + { + stimeout.tv_sec = (int)timeout; + stimeout.tv_usec = (int)(timeout * 1000000) % 1000000; + + if (select(CUPS_SC_FD + 1, NULL, &output_set, NULL, &stimeout) < 1) + return (-1); + } +#endif /* HAVE_POLL */ + + /* + * Write a side-channel message in the format: + * + * Byte(s) Description + * ------- ------------------------------------------- + * 0 Command code + * 1 Status code + * 2-3 Data length (network byte order) <= 16384 + * 4-N Data + */ + + buffer[0] = command; + buffer[1] = status; + buffer[2] = datalen >> 8; + buffer[3] = datalen & 255; + + bytes = 4; + + if (datalen > 0) + { + memcpy(buffer + 4, data, datalen); + bytes += datalen; + } + + while (write(CUPS_SC_FD, buffer, bytes) < 0) + if (errno != EINTR && errno != EAGAIN) + return (-1); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/sidechannel.h b/cups/sidechannel.h new file mode 100644 index 0000000000..6421735844 --- /dev/null +++ b/cups/sidechannel.h @@ -0,0 +1,136 @@ +/* + * "$Id$" + * + * Side-channel API definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_SIDECHANNEL_H_ +# define _CUPS_SIDECHANNEL_H_ + +/* + * Include necessary headers... + */ + +# include "versioning.h" + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Constants... + */ + +#define CUPS_SC_FD 4 /* File descriptor for select/poll */ + + +/* + * Enumerations... + */ + +enum cups_sc_bidi_e /**** Bidirectional capability values ****/ +{ + CUPS_SC_BIDI_NOT_SUPPORTED = 0, /* Bidirectional I/O is not supported */ + CUPS_SC_BIDI_SUPPORTED = 1 /* Bidirectional I/O is supported */ +}; +typedef enum cups_sc_bidi_e cups_sc_bidi_t; + /**** Bidirectional capabilities ****/ + +enum cups_sc_command_e /**** Request command codes ****/ +{ + CUPS_SC_CMD_NONE = 0, /* No command @private@ */ + CUPS_SC_CMD_SOFT_RESET = 1, /* Do a soft reset */ + CUPS_SC_CMD_DRAIN_OUTPUT = 2, /* Drain all pending output */ + CUPS_SC_CMD_GET_BIDI = 3, /* Return bidirectional capabilities */ + CUPS_SC_CMD_GET_DEVICE_ID = 4, /* Return the IEEE-1284 device ID */ + CUPS_SC_CMD_GET_STATE = 5, /* Return the device state */ + CUPS_SC_CMD_SNMP_GET = 6, /* Query an SNMP OID @since CUPS 1.4/Mac OS X 10.6@ */ + CUPS_SC_CMD_SNMP_GET_NEXT = 7 /* Query the next SNMP OID @since CUPS 1.4/Mac OS X 10.6@ */ +}; +typedef enum cups_sc_command_e cups_sc_command_t; + /**** Request command codes ****/ + +enum cups_sc_state_e /**** Printer state bits ****/ +{ + CUPS_SC_STATE_OFFLINE = 0, /* Device is offline */ + CUPS_SC_STATE_ONLINE = 1, /* Device is online */ + CUPS_SC_STATE_BUSY = 2, /* Device is busy */ + CUPS_SC_STATE_ERROR = 4, /* Other error condition */ + CUPS_SC_STATE_MEDIA_LOW = 16, /* Paper low condition */ + CUPS_SC_STATE_MEDIA_EMPTY = 32, /* Paper out condition */ + CUPS_SC_STATE_MARKER_LOW = 64, /* Toner/ink low condition */ + CUPS_SC_STATE_MARKER_EMPTY = 128 /* Toner/ink out condition */ +}; +typedef enum cups_sc_state_e cups_sc_state_t; + /**** Printer state bits ****/ + +enum cups_sc_status_e /**** Response status codes ****/ +{ + CUPS_SC_STATUS_NONE, /* No status */ + CUPS_SC_STATUS_OK, /* Operation succeeded */ + CUPS_SC_STATUS_IO_ERROR, /* An I/O error occurred */ + CUPS_SC_STATUS_TIMEOUT, /* The backend did not respond */ + CUPS_SC_STATUS_NO_RESPONSE, /* The device did not respond */ + CUPS_SC_STATUS_BAD_MESSAGE, /* The command/response message was invalid */ + CUPS_SC_STATUS_TOO_BIG, /* Response too big */ + CUPS_SC_STATUS_NOT_IMPLEMENTED /* Command not implemented */ +}; +typedef enum cups_sc_status_e cups_sc_status_t; + /**** Response status codes ****/ + +typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, + int datalen, void *context); + /**** SNMP walk callback ****/ + + +/* + * Prototypes... + */ + +extern cups_sc_status_t cupsSideChannelDoRequest(cups_sc_command_t command, + char *data, int *datalen, + double timeout) _CUPS_API_1_3; +extern int cupsSideChannelRead(cups_sc_command_t *command, + cups_sc_status_t *status, + char *data, int *datalen, + double timeout) _CUPS_API_1_3; +extern int cupsSideChannelWrite(cups_sc_command_t command, + cups_sc_status_t status, + const char *data, int datalen, + double timeout) _CUPS_API_1_3; + +/**** New in CUPS 1.4 ****/ +extern cups_sc_status_t cupsSideChannelSNMPGet(const char *oid, char *data, + int *datalen, double timeout) + _CUPS_API_1_4; +extern cups_sc_status_t cupsSideChannelSNMPWalk(const char *oid, double timeout, + cups_sc_walk_func_t cb, + void *context) _CUPS_API_1_4; + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_SIDECHANNEL_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/snmp-private.h b/cups/snmp-private.h new file mode 100644 index 0000000000..1745b92593 --- /dev/null +++ b/cups/snmp-private.h @@ -0,0 +1,148 @@ +/* + * "$Id$" + * + * SNMP definitions for the Common UNIX Printing System (CUPS). + * + * This API is PRIVATE and subject to change. No third-party applications + * should use the SNMP API defined in this file. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_SNMP_H_ +# define _CUPS_SNMP_H_ + + +/* + * Include necessary headers. + */ + +#include "http.h" + + +/* + * Constants... + */ + +#define CUPS_SNMP_PORT 161 /* SNMP well-known port */ +#define CUPS_SNMP_MAX_OID 128 /* Maximum number of OID numbers */ +#define CUPS_SNMP_MAX_PACKET 1472 /* Maximum size of SNMP packet */ +#define CUPS_SNMP_MAX_STRING 512 /* Maximum size of string */ +#define CUPS_SNMP_VERSION_1 0 /* SNMPv1 */ + + +/* + * Types... + */ + +enum cups_asn1_e /**** ASN1 request/object types ****/ +{ + CUPS_ASN1_END_OF_CONTENTS = 0x00, /* End-of-contents */ + CUPS_ASN1_BOOLEAN = 0x01, /* BOOLEAN */ + CUPS_ASN1_INTEGER = 0x02, /* INTEGER or ENUMERATION */ + CUPS_ASN1_BIT_STRING = 0x03, /* BIT STRING */ + CUPS_ASN1_OCTET_STRING = 0x04, /* OCTET STRING */ + CUPS_ASN1_NULL_VALUE = 0x05, /* NULL VALUE */ + CUPS_ASN1_OID = 0x06, /* OBJECT IDENTIFIER */ + CUPS_ASN1_SEQUENCE = 0x30, /* SEQUENCE */ + CUPS_ASN1_HEX_STRING = 0x40, /* Binary string aka Hex-STRING */ + CUPS_ASN1_COUNTER = 0x41, /* 32-bit unsigned aka Counter32 */ + CUPS_ASN1_GAUGE = 0x42, /* 32-bit unsigned aka Gauge32 */ + CUPS_ASN1_TIMETICKS = 0x43, /* 32-bit unsigned aka Timeticks32 */ + CUPS_ASN1_GET_REQUEST = 0xa0, /* GetRequest-PDU */ + CUPS_ASN1_GET_NEXT_REQUEST = 0xa1, /* GetNextRequest-PDU */ + CUPS_ASN1_GET_RESPONSE = 0xa2 /* GetResponse-PDU */ +}; +typedef enum cups_asn1_e cups_asn1_t; /**** ASN1 request/object types ****/ + +typedef struct cups_snmp_string_s /**** String value ****/ +{ + unsigned char bytes[CUPS_SNMP_MAX_STRING]; + /* Bytes in string */ + int num_bytes; /* Number of bytes */ +} cups_snmp_string_t; + +union cups_snmp_value_u /**** Object value ****/ +{ + int boolean; /* Boolean value */ + int integer; /* Integer value */ + unsigned counter; /* Counter value */ + unsigned gauge; /* Gauge value */ + unsigned timeticks; /* Timeticks value */ + int oid[CUPS_SNMP_MAX_OID]; /* OID value */ + cups_snmp_string_t string; /* String value */ +}; + +typedef struct cups_snmp_s /**** SNMP data packet ****/ +{ + const char *error; /* Encode/decode error */ + http_addr_t address; /* Source address */ + int version; /* Version number */ + char community[CUPS_SNMP_MAX_STRING]; + /* Community name */ + cups_asn1_t request_type; /* Request type */ + int request_id; /* request-id value */ + int error_status; /* error-status value */ + int error_index; /* error-index value */ + int object_name[CUPS_SNMP_MAX_OID]; + /* object-name value */ + cups_asn1_t object_type; /* object-value type */ + union cups_snmp_value_u + object_value; /* object-value value */ +} cups_snmp_t; + +typedef void (*cups_snmp_cb_t)(cups_snmp_t *packet, void *data); + +/* + * Prototypes... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +extern void _cupsSNMPClose(int fd) _CUPS_API_1_4; +extern int *_cupsSNMPCopyOID(int *dst, const int *src, int dstsize) + _CUPS_API_1_4; +extern const char *_cupsSNMPDefaultCommunity(void) _CUPS_API_1_4; +extern int _cupsSNMPIsOID(cups_snmp_t *packet, const int *oid) + _CUPS_API_1_4; +extern int _cupsSNMPIsOIDPrefixed(cups_snmp_t *packet, + const int *prefix) _CUPS_API_1_4; +extern char *_cupsSNMPOIDToString(const int *src, char *dst, + size_t dstsize) _CUPS_API_1_4; +extern int _cupsSNMPOpen(int family) _CUPS_API_1_4; +extern cups_snmp_t *_cupsSNMPRead(int fd, cups_snmp_t *packet, + double timeout) _CUPS_API_1_4; +extern void _cupsSNMPSetDebug(int level) _CUPS_API_1_4; +extern int *_cupsSNMPStringToOID(const char *src, + int *dst, int dstsize) + _CUPS_API_1_4; +extern int _cupsSNMPWalk(int fd, http_addr_t *address, int version, + const char *community, const int *prefix, + double timeout, cups_snmp_cb_t cb, + void *data) _CUPS_API_1_4; +extern int _cupsSNMPWrite(int fd, http_addr_t *address, int version, + const char *community, + cups_asn1_t request_type, + const unsigned request_id, + const int *oid) _CUPS_API_1_4; + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_SNMP_H_ */ + + +/* + * End of "$Id$". + */ diff --git a/cups/snmp.c b/cups/snmp.c new file mode 100644 index 0000000000..7079878a63 --- /dev/null +++ b/cups/snmp.c @@ -0,0 +1,1741 @@ +/* + * "$Id$" + * + * SNMP functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsSNMPClose() - Close a SNMP socket. + * _cupsSNMPCopyOID() - Copy an OID. + * _cupsSNMPDefaultCommunity() - Get the default SNMP community name. + * _cupsSNMPIsOID() - Test whether a SNMP response contains the + * specified OID. + * _cupsSNMPIsOIDPrefixed() - Test whether a SNMP response uses the + * specified OID prefix. + * _cupsSNMPOIDToString() - Convert an OID to a string. + * _cupsSNMPOpen() - Open a SNMP socket. + * _cupsSNMPRead() - Read and parse a SNMP response. + * _cupsSNMPSetDebug() - Enable/disable debug logging to stderr. + * _cupsSNMPStringToOID() - Convert a numeric OID string to an OID array. + * _cupsSNMPWalk() - Enumerate a group of OIDs. + * _cupsSNMPWrite() - Send an SNMP query packet. + * asn1_debug() - Decode an ASN1-encoded message. + * asn1_decode_snmp() - Decode a SNMP packet. + * asn1_encode_snmp() - Encode a SNMP packet. + * asn1_get_integer() - Get an integer value. + * asn1_get_length() - Get a value length. + * asn1_get_oid() - Get an OID value. + * asn1_get_packed() - Get a packed integer value. + * asn1_get_string() - Get a string value. + * asn1_get_type() - Get a value type. + * asn1_set_integer() - Set an integer value. + * asn1_set_length() - Set a value length. + * asn1_set_oid() - Set an OID value. + * asn1_set_packed() - Set a packed integer value. + * asn1_size_integer() - Figure out the number of bytes needed for an + * integer value. + * asn1_size_length() - Figure out the number of bytes needed for a + * length value. + * asn1_size_oid() - Figure out the numebr of bytes needed for an + * OID value. + * asn1_size_packed() - Figure out the number of bytes needed for a + * packed integer value. + * snmp_set_error() - Set the localized error for a packet. + */ + +/* + * Include necessary headers. + */ + +#include "globals.h" +#include "debug.h" +#include "snmp-private.h" +#include +#ifdef HAVE_POLL +# include +#endif /* HAVE_POLL */ + + +/* + * Local functions... + */ + +static void asn1_debug(const char *prefix, unsigned char *buffer, + size_t len, int indent); +static int asn1_decode_snmp(unsigned char *buffer, size_t len, + cups_snmp_t *packet); +static int asn1_encode_snmp(unsigned char *buffer, size_t len, + cups_snmp_t *packet); +static int asn1_get_integer(unsigned char **buffer, + unsigned char *bufend, + int length); +static int asn1_get_oid(unsigned char **buffer, + unsigned char *bufend, + int length, int *oid, int oidsize); +static int asn1_get_packed(unsigned char **buffer, + unsigned char *bufend); +static char *asn1_get_string(unsigned char **buffer, + unsigned char *bufend, + int length, char *string, + int strsize); +static unsigned asn1_get_length(unsigned char **buffer, + unsigned char *bufend); +static int asn1_get_type(unsigned char **buffer, + unsigned char *bufend); +static void asn1_set_integer(unsigned char **buffer, + int integer); +static void asn1_set_length(unsigned char **buffer, + unsigned length); +static void asn1_set_oid(unsigned char **buffer, + const int *oid); +static void asn1_set_packed(unsigned char **buffer, + int integer); +static int asn1_size_integer(int integer); +static int asn1_size_length(int length); +static int asn1_size_oid(const int *oid); +static int asn1_size_packed(int integer); +static void snmp_set_error(cups_snmp_t *packet, + const char *message); + + +/* + * '_cupsSNMPClose()' - Close a SNMP socket. + */ + +void +_cupsSNMPClose(int fd) /* I - SNMP socket file descriptor */ +{ + DEBUG_printf(("4_cupsSNMPClose(fd=%d)", fd)); + +#ifdef WIN32 + closesocket(fd); +#else + close(fd); +#endif /* WIN32 */ +} + + +/* + * '_cupsSNMPCopyOID()' - Copy an OID. + * + * The array pointed to by "src" is terminated by the value -1. + */ + +int * /* O - New OID */ +_cupsSNMPCopyOID(int *dst, /* I - Destination OID */ + const int *src, /* I - Source OID */ + int dstsize) /* I - Number of integers in dst */ +{ + int i; /* Looping var */ + + + DEBUG_printf(("4_cupsSNMPCopyOID(dst=%p, src=%p, dstsize=%d)", dst, src, + dstsize)); + + for (i = 0, dstsize --; src[i] >= 0 && i < dstsize; i ++) + dst[i] = src[i]; + + dst[i] = -1; + + return (dst); +} + + +/* + * '_cupsSNMPDefaultCommunity()' - Get the default SNMP community name. + * + * The default community name is the first community name found in the + * snmp.conf file. If no community name is defined there, "public" is used. + */ + +const char * /* O - Default community name */ +_cupsSNMPDefaultCommunity(void) +{ + cups_file_t *fp; /* snmp.conf file */ + char line[1024], /* Line from file */ + *value; /* Value from file */ + int linenum; /* Line number in file */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + DEBUG_puts("4_cupsSNMPDefaultCommunity()"); + + if (!cg->snmp_community[0]) + { + strlcpy(cg->snmp_community, "public", sizeof(cg->snmp_community)); + + snprintf(line, sizeof(line), "%s/snmp.conf", cg->cups_serverroot); + if ((fp = cupsFileOpen(line, "r")) != NULL) + { + linenum = 0; + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + if (!strcasecmp(line, "Community") && value) + { + strlcpy(cg->snmp_community, value, sizeof(cg->snmp_community)); + break; + } + + cupsFileClose(fp); + } + } + + DEBUG_printf(("5_cupsSNMPDefaultCommunity: Returning \"%s\"", + cg->snmp_community)); + + return (cg->snmp_community); +} + + +/* + * '_cupsSNMPIsOID()' - Test whether a SNMP response contains the specified OID. + * + * The array pointed to by "oid" is terminated by the value -1. + */ + +int /* O - 1 if equal, 0 if not equal */ +_cupsSNMPIsOID(cups_snmp_t *packet, /* I - Response packet */ + const int *oid) /* I - OID */ +{ + int i; /* Looping var */ + + + /* + * Range check input... + */ + + DEBUG_printf(("4_cupsSNMPIsOID(packet=%p, oid=%p)", packet, oid)); + + if (!packet || !oid) + { + DEBUG_puts("5_cupsSNMPIsOID: Returning 0"); + + return (0); + } + + /* + * Compare OIDs... + */ + + for (i = 0; + i < CUPS_SNMP_MAX_OID && oid[i] >= 0 && packet->object_name[i] >= 0; + i ++) + if (oid[i] != packet->object_name[i]) + { + DEBUG_puts("5_cupsSNMPIsOID: Returning 0"); + + return (0); + } + + DEBUG_printf(("5_cupsSNMPIsOID: Returning %d", + i < CUPS_SNMP_MAX_OID && oid[i] == packet->object_name[i])); + + return (i < CUPS_SNMP_MAX_OID && oid[i] == packet->object_name[i]); +} + + +/* + * '_cupsSNMPIsOIDPrefixed()' - Test whether a SNMP response uses the specified + * OID prefix. + * + * The array pointed to by "prefix" is terminated by the value -1. + */ + +int /* O - 1 if prefixed, 0 if not prefixed */ +_cupsSNMPIsOIDPrefixed( + cups_snmp_t *packet, /* I - Response packet */ + const int *prefix) /* I - OID prefix */ +{ + int i; /* Looping var */ + + + /* + * Range check input... + */ + + DEBUG_printf(("4_cupsSNMPIsOIDPrefixed(packet=%p, prefix=%p)", packet, + prefix)); + + if (!packet || !prefix) + { + DEBUG_puts("5_cupsSNMPIsOIDPrefixed: Returning 0"); + + return (0); + } + + /* + * Compare OIDs... + */ + + for (i = 0; + i < CUPS_SNMP_MAX_OID && prefix[i] >= 0 && packet->object_name[i] >= 0; + i ++) + if (prefix[i] != packet->object_name[i]) + { + DEBUG_puts("5_cupsSNMPIsOIDPrefixed: Returning 0"); + + return (0); + } + + DEBUG_printf(("5_cupsSNMPIsOIDPrefixed: Returning %d", + i < CUPS_SNMP_MAX_OID)); + + return (i < CUPS_SNMP_MAX_OID); +} + + +/* + * '_cupsSNMPOIDToString()' - Convert an OID to a string. + */ + + +char * /* O - New string or @code NULL@ on error */ +_cupsSNMPOIDToString(const int *src, /* I - OID */ + char *dst, /* I - String buffer */ + size_t dstsize) /* I - Size of string buffer */ +{ + char *dstptr, /* Pointer into string buffer */ + *dstend; /* End of string buffer */ + + + DEBUG_printf(("4_cupsSNMPOIDToString(src=%p, dst=%p, dstsize=" CUPS_LLFMT ")", + src, dst, CUPS_LLCAST dstsize)); + + /* + * Range check input... + */ + + if (!src || !dst || dstsize < 4) + return (NULL); + + /* + * Loop through the OID array and build a string... + */ + + for (dstptr = dst, dstend = dstptr + dstsize - 1; + *src >= 0 && dstptr < dstend; + src ++, dstptr += strlen(dstptr)) + snprintf(dstptr, dstend - dstptr + 1, ".%d", *src); + + if (*src >= 0) + return (NULL); + else + return (dst); +} + + +/* + * '_cupsSNMPOpen()' - Open a SNMP socket. + */ + +int /* O - SNMP socket file descriptor */ +_cupsSNMPOpen(int family) /* I - Address family - @code AF_INET@ or @code AF_INET6@ */ +{ + int fd; /* SNMP socket file descriptor */ + int val; /* Socket option value */ + + + /* + * Create the SNMP socket... + */ + + DEBUG_printf(("4_cupsSNMPOpen(family=%d)", family)); + + if ((fd = socket(family, SOCK_DGRAM, 0)) < 0) + { + DEBUG_printf(("5_cupsSNMPOpen: Returning -1 (%s)", strerror(errno))); + + return (-1); + } + + /* + * Set the "broadcast" flag... + */ + + val = 1; + +#ifdef WIN32 + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char *)&val, sizeof(val))) +#else + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) +#endif /* WIN32 */ + { + DEBUG_printf(("5_cupsSNMPOpen: Returning -1 (%s)", strerror(errno))); + + close(fd); + + return (-1); + } + + DEBUG_printf(("5_cupsSNMPOpen: Returning %d", fd)); + + return (fd); +} + + +/* + * '_cupsSNMPRead()' - Read and parse a SNMP response. + * + * If "timeout" is negative, @code _cupsSNMPRead@ will wait for a response + * indefinitely. + */ + +cups_snmp_t * /* O - SNMP packet or @code NULL@ if none */ +_cupsSNMPRead(int fd, /* I - SNMP socket file descriptor */ + cups_snmp_t *packet, /* I - SNMP packet buffer */ + double timeout) /* I - Timeout in seconds */ +{ + unsigned char buffer[CUPS_SNMP_MAX_PACKET]; + /* Data packet */ + int bytes; /* Number of bytes received */ + socklen_t addrlen; /* Source address length */ + http_addr_t address; /* Source address */ + + + /* + * Range check input... + */ + + DEBUG_printf(("4_cupsSNMPRead(fd=%d, packet=%p, timeout=%.1f)", fd, packet, + timeout)); + + if (fd < 0 || !packet) + { + DEBUG_puts("5_cupsSNMPRead: Returning NULL"); + + return (NULL); + } + + /* + * Optionally wait for a response... + */ + + if (timeout >= 0.0) + { + int ready; /* Data ready on socket? */ +#ifdef HAVE_POLL + struct pollfd pfd; /* Polled file descriptor */ + + pfd.fd = fd; + pfd.events = POLLIN; + + while ((ready = poll(&pfd, 1, (int)(timeout * 1000.0))) < 0 && + (errno == EINTR || errno == EAGAIN)); + +#else + fd_set input_set; /* select() input set */ + struct timeval stimeout; /* select() timeout */ + + do + { + FD_ZERO(&input_set); + FD_SET(fd, &input_set); + + stimeout.tv_sec = (int)timeout; + stimeout.tv_usec = (int)((timeout - stimeout.tv_sec) * 1000000); + + ready = select(fd + 1, &input_set, NULL, NULL, &stimeout); + } +# ifdef WIN32 + while (ready < 0 && WSAGetLastError() == WSAEINTR); +# else + while (ready < 0 && (errno == EINTR || errno == EAGAIN)); +# endif /* WIN32 */ +#endif /* HAVE_POLL */ + + /* + * If we don't have any data ready, return right away... + */ + + if (ready <= 0) + { + DEBUG_puts("5_cupsSNMPRead: Returning NULL (timeout)"); + + return (NULL); + } + } + + /* + * Read the response data... + */ + + addrlen = sizeof(address); + + if ((bytes = recvfrom(fd, buffer, sizeof(buffer), 0, (void *)&address, + &addrlen)) < 0) + { + DEBUG_printf(("5_cupsSNMPRead: Returning NULL (%s)", strerror(errno))); + + return (NULL); + } + + /* + * Look for the response status code in the SNMP message header... + */ + + asn1_debug("DEBUG: IN ", buffer, bytes, 0); + + asn1_decode_snmp(buffer, bytes, packet); + + memcpy(&(packet->address), &address, sizeof(packet->address)); + + /* + * Return decoded data packet... + */ + + DEBUG_puts("5_cupsSNMPRead: Returning packet"); + + return (packet); +} + + +/* + * '_cupsSNMPSetDebug()' - Enable/disable debug logging to stderr. + */ + +void +_cupsSNMPSetDebug(int level) /* I - 1 to enable debug output, 0 otherwise */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + DEBUG_printf(("4_cupsSNMPSetDebug(level=%d)", level)); + + cg->snmp_debug = level; +} + + +/* + * '_cupsSNMPStringToOID()' - Convert a numeric OID string to an OID array. + * + * This function converts a string of the form ".N.N.N.N.N" to the + * corresponding OID array terminated by -1. + * + * @code NULL@ is returned if the array is not large enough or the string is + * not a valid OID number. + */ + +int * /* O - Pointer to OID array or @code NULL@ on error */ +_cupsSNMPStringToOID(const char *src, /* I - OID string */ + int *dst, /* I - OID array */ + int dstsize)/* I - Number of integers in OID array */ +{ + int *dstptr, /* Pointer into OID array */ + *dstend; /* End of OID array */ + + + DEBUG_printf(("4_cupsSNMPStringToOID(src=\"%s\", dst=%p, dstsize=%d)", + src, dst, dstsize)); + + /* + * Range check input... + */ + + if (!src || !dst || dstsize < 2) + return (NULL); + + /* + * Skip leading "."... + */ + + if (*src == '.') + src ++; + + /* + * Loop to the end of the string... + */ + + for (dstend = dst + dstsize - 1, dstptr = dst, *dstptr = 0; + *src && dstptr < dstend; + src ++) + { + if (*src == '.') + { + dstptr ++; + *dstptr = 0; + } + else if (isdigit(*src & 255)) + *dstptr = *dstptr * 10 + *src - '0'; + else + break; + } + + if (*src) + return (NULL); + + /* + * Terminate the end of the OID array and return... + */ + + dstptr[1] = -1; + + return (dst); +} + + +/* + * '_cupsSNMPWalk()' - Enumerate a group of OIDs. + * + * This function queries all of the OIDs with the specified OID prefix, + * calling the "cb" function for every response that is received. + * + * The array pointed to by "prefix" is terminated by the value -1. + * + * If "timeout" is negative, @code _cupsSNMPWalk@ will wait for a response + * indefinitely. + */ + +int /* O - Number of OIDs found or -1 on error */ +_cupsSNMPWalk(int fd, /* I - SNMP socket */ + http_addr_t *address, /* I - Address to query */ + int version, /* I - SNMP version */ + const char *community,/* I - Community name */ + const int *prefix, /* I - OID prefix */ + double timeout, /* I - Timeout for each response in seconds */ + cups_snmp_cb_t cb, /* I - Function to call for each response */ + void *data) /* I - User data pointer that is passed to the callback function */ +{ + int count = 0; /* Number of OIDs found */ + int request_id = 0; /* Current request ID */ + cups_snmp_t packet; /* Current response packet */ + int lastoid[CUPS_SNMP_MAX_OID]; + /* Last OID we got */ + + + /* + * Range check input... + */ + + DEBUG_printf(("4_cupsSNMPWalk(fd=%d, address=%p, version=%d, " + "community=\"%s\", prefix=%p, timeout=%.1f, cb=%p, data=%p)", + fd, address, version, community, prefix, timeout, cb, data)); + + if (fd < 0 || !address || version != CUPS_SNMP_VERSION_1 || !community || + !prefix || !cb) + { + DEBUG_puts("5_cupsSNMPWalk: Returning -1"); + + return (-1); + } + + /* + * Copy the OID prefix and then loop until we have no more OIDs... + */ + + _cupsSNMPCopyOID(packet.object_name, prefix, CUPS_SNMP_MAX_OID); + lastoid[0] = -1; + + for (;;) + { + request_id ++; + + if (!_cupsSNMPWrite(fd, address, version, community, + CUPS_ASN1_GET_NEXT_REQUEST, request_id, + packet.object_name)) + { + DEBUG_puts("5_cupsSNMPWalk: Returning -1"); + + return (-1); + } + + if (!_cupsSNMPRead(fd, &packet, timeout)) + { + DEBUG_puts("5_cupsSNMPWalk: Returning -1"); + + return (-1); + } + + if (!_cupsSNMPIsOIDPrefixed(&packet, prefix) || + _cupsSNMPIsOID(&packet, lastoid)) + { + DEBUG_printf(("5_cupsSNMPWalk: Returning %d", count)); + + return (count); + } + + if (packet.error || packet.error_status) + { + DEBUG_printf(("5_cupsSNMPWalk: Returning %d", count > 0 ? count : -1)); + + return (count > 0 ? count : -1); + } + + _cupsSNMPCopyOID(lastoid, packet.object_name, CUPS_SNMP_MAX_OID); + + count ++; + + (*cb)(&packet, data); + } +} + + +/* + * '_cupsSNMPWrite()' - Send an SNMP query packet. + * + * The array pointed to by "oid" is terminated by the value -1. + */ + +int /* O - 1 on success, 0 on error */ +_cupsSNMPWrite( + int fd, /* I - SNMP socket */ + http_addr_t *address, /* I - Address to send to */ + int version, /* I - SNMP version */ + const char *community, /* I - Community name */ + cups_asn1_t request_type, /* I - Request type */ + const unsigned request_id, /* I - Request ID */ + const int *oid) /* I - OID */ +{ + int i; /* Looping var */ + cups_snmp_t packet; /* SNMP message packet */ + unsigned char buffer[CUPS_SNMP_MAX_PACKET]; + /* SNMP message buffer */ + int bytes; /* Size of message */ + http_addr_t temp; /* Copy of address */ + + + /* + * Range check input... + */ + + DEBUG_printf(("4_cupsSNMPWrite(fd=%d, address=%p, version=%d, " + "community=\"%s\", request_type=%d, request_id=%u, oid=%p)", + fd, address, version, community, request_type, request_id, oid)); + + if (fd < 0 || !address || version != CUPS_SNMP_VERSION_1 || !community || + (request_type != CUPS_ASN1_GET_REQUEST && + request_type != CUPS_ASN1_GET_NEXT_REQUEST) || request_id < 1 || !oid) + { + DEBUG_puts("5_cupsSNMPWrite: Returning 0 (bad arguments)"); + + return (0); + } + + /* + * Create the SNMP message... + */ + + memset(&packet, 0, sizeof(packet)); + + packet.version = version; + packet.request_type = request_type; + packet.request_id = request_id; + packet.object_type = CUPS_ASN1_NULL_VALUE; + + strlcpy(packet.community, community, sizeof(packet.community)); + + for (i = 0; oid[i] >= 0 && i < (CUPS_SNMP_MAX_OID - 1); i ++) + packet.object_name[i] = oid[i]; + packet.object_name[i] = -1; + + if (oid[i] >= 0) + { + DEBUG_puts("5_cupsSNMPWrite: Returning 0 (OID too big)"); + + errno = E2BIG; + return (0); + } + + bytes = asn1_encode_snmp(buffer, sizeof(buffer), &packet); + + if (bytes < 0) + { + DEBUG_puts("5_cupsSNMPWrite: Returning 0 (request too big)"); + + errno = E2BIG; + return (0); + } + + asn1_debug("DEBUG: OUT ", buffer, bytes, 0); + + /* + * Send the message... + */ + + temp = *address; + +#ifdef AF_INET6 + if (temp.addr.sa_family == AF_INET6) + temp.ipv6.sin6_port = htons(CUPS_SNMP_PORT); + else +#endif /* AF_INET6 */ + temp.ipv4.sin_port = htons(CUPS_SNMP_PORT); + + return (sendto(fd, buffer, bytes, 0, (void *)&temp, + httpAddrLength(&temp)) == bytes); +} + + +/* + * 'asn1_debug()' - Decode an ASN1-encoded message. + */ + +static void +asn1_debug(const char *prefix, /* I - Prefix string */ + unsigned char *buffer, /* I - Buffer */ + size_t len, /* I - Length of buffer */ + int indent) /* I - Indentation */ +{ + int i; /* Looping var */ + unsigned char *bufend; /* End of buffer */ + int integer; /* Number value */ + int oid[CUPS_SNMP_MAX_OID]; /* OID value */ + char string[CUPS_SNMP_MAX_STRING]; + /* String value */ + unsigned char value_type; /* Type of value */ + int value_length; /* Length of value */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + if (cg->snmp_debug <= 0) + return; + + if (cg->snmp_debug > 1 && indent == 0) + { + /* + * Do a hex dump of the packet... + */ + + int j; + + fprintf(stderr, "%sHex Dump (%d bytes):\n", prefix, (int)len); + + for (i = 0; i < (int)len; i += 16) + { + fprintf(stderr, "%s%04x:", prefix, i); + + for (j = 0; j < 16 && (i + j) < (int)len; j ++) + { + if (j && !(j & 3)) + fprintf(stderr, " %02x", buffer[i + j]); + else + fprintf(stderr, " %02x", buffer[i + j]); + } + + while (j < 16) + { + if (j && !(j & 3)) + fputs(" ", stderr); + else + fputs(" ", stderr); + + j ++; + } + + fputs(" ", stderr); + + for (j = 0; j < 16 && (i + j) < (int)len; j ++) + if (buffer[i + j] < ' ' || buffer[i + j] >= 0x7f) + putc('.', stderr); + else + putc(buffer[i + j], stderr); + + putc('\n', stderr); + } + } + + if (indent == 0) + fprintf(stderr, "%sMessage:\n", prefix); + + bufend = buffer + len; + + while (buffer < bufend) + { + /* + * Get value type... + */ + + value_type = asn1_get_type(&buffer, bufend); + value_length = asn1_get_length(&buffer, bufend); + + switch (value_type) + { + case CUPS_ASN1_BOOLEAN : + integer = asn1_get_integer(&buffer, bufend, value_length); + + fprintf(stderr, "%s%*sBOOLEAN %d bytes %d\n", prefix, indent, "", + value_length, integer); + break; + + case CUPS_ASN1_INTEGER : + integer = asn1_get_integer(&buffer, bufend, value_length); + + fprintf(stderr, "%s%*sINTEGER %d bytes %d\n", prefix, indent, "", + value_length, integer); + break; + + case CUPS_ASN1_COUNTER : + integer = asn1_get_integer(&buffer, bufend, value_length); + + fprintf(stderr, "%s%*sCOUNTER %d bytes %u\n", prefix, indent, "", + value_length, (unsigned)integer); + break; + + case CUPS_ASN1_GAUGE : + integer = asn1_get_integer(&buffer, bufend, value_length); + + fprintf(stderr, "%s%*sGAUGE %d bytes %u\n", prefix, indent, "", + value_length, (unsigned)integer); + break; + + case CUPS_ASN1_TIMETICKS : + integer = asn1_get_integer(&buffer, bufend, value_length); + + fprintf(stderr, "%s%*sTIMETICKS %d bytes %u\n", prefix, indent, "", + value_length, (unsigned)integer); + break; + + case CUPS_ASN1_OCTET_STRING : + fprintf(stderr, "%s%*sOCTET STRING %d bytes \"%s\"\n", prefix, + indent, "", value_length, + asn1_get_string(&buffer, bufend, value_length, string, + sizeof(string))); + break; + + case CUPS_ASN1_HEX_STRING : + asn1_get_string(&buffer, bufend, value_length, string, + sizeof(string)); + fprintf(stderr, "%s%*sHex-STRING %d bytes", prefix, + indent, "", value_length); + for (i = 0; i < value_length; i ++) + fprintf(stderr, " %02X", string[i] & 255); + putc('\n', stderr); + break; + + case CUPS_ASN1_NULL_VALUE : + fprintf(stderr, "%s%*sNULL VALUE %d bytes\n", prefix, indent, "", + value_length); + + buffer += value_length; + break; + + case CUPS_ASN1_OID : + integer = asn1_get_oid(&buffer, bufend, value_length, oid, + CUPS_SNMP_MAX_OID); + + fprintf(stderr, "%s%*sOID %d bytes ", prefix, indent, "", + value_length); + for (i = 0; i < integer; i ++) + fprintf(stderr, ".%d", oid[i]); + putc('\n', stderr); + break; + + case CUPS_ASN1_SEQUENCE : + fprintf(stderr, "%s%*sSEQUENCE %d bytes\n", prefix, indent, "", + value_length); + asn1_debug(prefix, buffer, value_length, indent + 4); + + buffer += value_length; + break; + + case CUPS_ASN1_GET_NEXT_REQUEST : + fprintf(stderr, "%s%*sGet-Next-Request-PDU %d bytes\n", prefix, + indent, "", value_length); + asn1_debug(prefix, buffer, value_length, indent + 4); + + buffer += value_length; + break; + + case CUPS_ASN1_GET_REQUEST : + fprintf(stderr, "%s%*sGet-Request-PDU %d bytes\n", prefix, indent, "", + value_length); + asn1_debug(prefix, buffer, value_length, indent + 4); + + buffer += value_length; + break; + + case CUPS_ASN1_GET_RESPONSE : + fprintf(stderr, "%s%*sGet-Response-PDU %d bytes\n", prefix, indent, + "", value_length); + asn1_debug(prefix, buffer, value_length, indent + 4); + + buffer += value_length; + break; + + default : + fprintf(stderr, "%s%*sUNKNOWN(%x) %d bytes\n", prefix, indent, "", + value_type, value_length); + + buffer += value_length; + break; + } + } +} + + +/* + * 'asn1_decode_snmp()' - Decode a SNMP packet. + */ + +static int /* O - 0 on success, -1 on error */ +asn1_decode_snmp(unsigned char *buffer, /* I - Buffer */ + size_t len, /* I - Size of buffer */ + cups_snmp_t *packet) /* I - SNMP packet */ +{ + unsigned char *bufptr, /* Pointer into the data */ + *bufend; /* End of data */ + int length; /* Length of value */ + + + /* + * Initialize the decoding... + */ + + memset(packet, 0, sizeof(cups_snmp_t)); + packet->object_name[0] = -1; + + bufptr = buffer; + bufend = buffer + len; + + if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_SEQUENCE) + snmp_set_error(packet, _("Packet does not start with SEQUENCE")); + else if (asn1_get_length(&bufptr, bufend) == 0) + snmp_set_error(packet, _("SEQUENCE uses indefinite length")); + else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) + snmp_set_error(packet, _("No version number")); + else if ((length = asn1_get_length(&bufptr, bufend)) == 0) + snmp_set_error(packet, _("Version uses indefinite length")); + else if ((packet->version = asn1_get_integer(&bufptr, bufend, length)) + != CUPS_SNMP_VERSION_1) + snmp_set_error(packet, _("Bad SNMP version number")); + else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_OCTET_STRING) + snmp_set_error(packet, _("No community name")); + else if ((length = asn1_get_length(&bufptr, bufend)) == 0) + snmp_set_error(packet, _("Community name uses indefinite length")); + else + { + asn1_get_string(&bufptr, bufend, length, packet->community, + sizeof(packet->community)); + + if ((packet->request_type = asn1_get_type(&bufptr, bufend)) + != CUPS_ASN1_GET_RESPONSE) + snmp_set_error(packet, _("Packet does not contain a Get-Response-PDU")); + else if (asn1_get_length(&bufptr, bufend) == 0) + snmp_set_error(packet, _("Get-Response-PDU uses indefinite length")); + else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) + snmp_set_error(packet, _("No request-id")); + else if ((length = asn1_get_length(&bufptr, bufend)) == 0) + snmp_set_error(packet, _("request-id uses indefinite length")); + else + { + packet->request_id = asn1_get_integer(&bufptr, bufend, length); + + if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) + snmp_set_error(packet, _("No error-status")); + else if ((length = asn1_get_length(&bufptr, bufend)) == 0) + snmp_set_error(packet, _("error-status uses indefinite length")); + else + { + packet->error_status = asn1_get_integer(&bufptr, bufend, length); + + if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_INTEGER) + snmp_set_error(packet, _("No error-index")); + else if ((length = asn1_get_length(&bufptr, bufend)) == 0) + snmp_set_error(packet, _("error-index uses indefinite length")); + else + { + packet->error_index = asn1_get_integer(&bufptr, bufend, length); + + if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_SEQUENCE) + snmp_set_error(packet, _("No variable-bindings SEQUENCE")); + else if (asn1_get_length(&bufptr, bufend) == 0) + snmp_set_error(packet, + _("variable-bindings uses indefinite length")); + else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_SEQUENCE) + snmp_set_error(packet, _("No VarBind SEQUENCE")); + else if (asn1_get_length(&bufptr, bufend) == 0) + snmp_set_error(packet, _("VarBind uses indefinite length")); + else if (asn1_get_type(&bufptr, bufend) != CUPS_ASN1_OID) + snmp_set_error(packet, _("No name OID")); + else if ((length = asn1_get_length(&bufptr, bufend)) == 0) + snmp_set_error(packet, _("Name OID uses indefinite length")); + else + { + asn1_get_oid(&bufptr, bufend, length, packet->object_name, + CUPS_SNMP_MAX_OID); + + packet->object_type = asn1_get_type(&bufptr, bufend); + + if ((length = asn1_get_length(&bufptr, bufend)) == 0 && + packet->object_type != CUPS_ASN1_NULL_VALUE && + packet->object_type != CUPS_ASN1_OCTET_STRING) + snmp_set_error(packet, _("Value uses indefinite length")); + else + { + switch (packet->object_type) + { + case CUPS_ASN1_BOOLEAN : + packet->object_value.boolean = + asn1_get_integer(&bufptr, bufend, length); + break; + + case CUPS_ASN1_INTEGER : + packet->object_value.integer = + asn1_get_integer(&bufptr, bufend, length); + break; + + case CUPS_ASN1_NULL_VALUE : + break; + + case CUPS_ASN1_OCTET_STRING : + case CUPS_ASN1_BIT_STRING : + case CUPS_ASN1_HEX_STRING : + packet->object_value.string.num_bytes = length; + asn1_get_string(&bufptr, bufend, length, + (char *)packet->object_value.string.bytes, + CUPS_SNMP_MAX_STRING); + break; + + case CUPS_ASN1_OID : + asn1_get_oid(&bufptr, bufend, length, + packet->object_value.oid, CUPS_SNMP_MAX_OID); + break; + + case CUPS_ASN1_COUNTER : + packet->object_value.counter = + asn1_get_integer(&bufptr, bufend, length); + break; + + case CUPS_ASN1_GAUGE : + packet->object_value.gauge = + asn1_get_integer(&bufptr, bufend, length); + break; + + case CUPS_ASN1_TIMETICKS : + packet->object_value.timeticks = + asn1_get_integer(&bufptr, bufend, length); + break; + + default : + snmp_set_error(packet, _("Unsupported value type")); + break; + } + } + } + } + } + } + } + + return (packet->error ? -1 : 0); +} + + +/* + * 'asn1_encode_snmp()' - Encode a SNMP packet. + */ + +static int /* O - Length on success, -1 on error */ +asn1_encode_snmp(unsigned char *buffer, /* I - Buffer */ + size_t bufsize, /* I - Size of buffer */ + cups_snmp_t *packet) /* I - SNMP packet */ +{ + unsigned char *bufptr; /* Pointer into buffer */ + int total, /* Total length */ + msglen, /* Length of entire message */ + commlen, /* Length of community string */ + reqlen, /* Length of request */ + listlen, /* Length of variable list */ + varlen, /* Length of variable */ + namelen, /* Length of object name OID */ + valuelen; /* Length of object value */ + + + /* + * Get the lengths of the community string, OID, and message... + */ + + + namelen = asn1_size_oid(packet->object_name); + + switch (packet->object_type) + { + case CUPS_ASN1_NULL_VALUE : + valuelen = 0; + break; + + case CUPS_ASN1_BOOLEAN : + valuelen = asn1_size_integer(packet->object_value.boolean); + break; + + case CUPS_ASN1_INTEGER : + valuelen = asn1_size_integer(packet->object_value.integer); + break; + + case CUPS_ASN1_OCTET_STRING : + valuelen = packet->object_value.string.num_bytes; + break; + + case CUPS_ASN1_OID : + valuelen = asn1_size_oid(packet->object_value.oid); + break; + + default : + packet->error = "Unknown object type"; + return (-1); + } + + varlen = 1 + asn1_size_length(namelen) + namelen + + 1 + asn1_size_length(valuelen) + valuelen; + listlen = 1 + asn1_size_length(varlen) + varlen; + reqlen = 2 + asn1_size_integer(packet->request_id) + + 2 + asn1_size_integer(packet->error_status) + + 2 + asn1_size_integer(packet->error_index) + + 1 + asn1_size_length(listlen) + listlen; + commlen = strlen(packet->community); + msglen = 2 + asn1_size_integer(packet->version) + + 1 + asn1_size_length(commlen) + commlen + + 1 + asn1_size_length(reqlen) + reqlen; + total = 1 + asn1_size_length(msglen) + msglen; + + if (total > (int)bufsize) + { + packet->error = "Message too large for buffer"; + return (-1); + } + + /* + * Then format the message... + */ + + bufptr = buffer; + + *bufptr++ = CUPS_ASN1_SEQUENCE; /* SNMPv1 message header */ + asn1_set_length(&bufptr, msglen); + + asn1_set_integer(&bufptr, packet->version); + /* version */ + + *bufptr++ = CUPS_ASN1_OCTET_STRING; /* community */ + asn1_set_length(&bufptr, commlen); + memcpy(bufptr, packet->community, commlen); + bufptr += commlen; + + *bufptr++ = packet->request_type; /* Get-Request-PDU/Get-Next-Request-PDU */ + asn1_set_length(&bufptr, reqlen); + + asn1_set_integer(&bufptr, packet->request_id); + + asn1_set_integer(&bufptr, packet->error_status); + + asn1_set_integer(&bufptr, packet->error_index); + + *bufptr++ = CUPS_ASN1_SEQUENCE; /* variable-bindings */ + asn1_set_length(&bufptr, listlen); + + *bufptr++ = CUPS_ASN1_SEQUENCE; /* variable */ + asn1_set_length(&bufptr, varlen); + + asn1_set_oid(&bufptr, packet->object_name); + /* ObjectName */ + + switch (packet->object_type) + { + case CUPS_ASN1_NULL_VALUE : + *bufptr++ = CUPS_ASN1_NULL_VALUE; + /* ObjectValue */ + *bufptr++ = 0; /* Length */ + break; + + case CUPS_ASN1_BOOLEAN : + asn1_set_integer(&bufptr, packet->object_value.boolean); + break; + + case CUPS_ASN1_INTEGER : + asn1_set_integer(&bufptr, packet->object_value.integer); + break; + + case CUPS_ASN1_OCTET_STRING : + *bufptr++ = CUPS_ASN1_OCTET_STRING; + asn1_set_length(&bufptr, valuelen); + memcpy(bufptr, packet->object_value.string.bytes, valuelen); + bufptr += valuelen; + break; + + case CUPS_ASN1_OID : + asn1_set_oid(&bufptr, packet->object_value.oid); + break; + + default : + break; + } + + return (bufptr - buffer); +} + + +/* + * 'asn1_get_integer()' - Get an integer value. + */ + +static int /* O - Integer value */ +asn1_get_integer( + unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned char *bufend, /* I - End of buffer */ + int length) /* I - Length of value */ +{ + int value; /* Integer value */ + + + if (length > sizeof(int)) + { + (*buffer) += length; + return (0); + } + + for (value = (**buffer & 0x80) ? -1 : 0; + length > 0 && *buffer < bufend; + length --, (*buffer) ++) + value = (value << 8) | **buffer; + + return (value); +} + + +/* + * 'asn1_get_length()' - Get a value length. + */ + +static unsigned /* O - Length */ +asn1_get_length(unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned char *bufend) /* I - End of buffer */ +{ + unsigned length; /* Length */ + + + length = **buffer; + (*buffer) ++; + + if (length & 128) + { + int count; /* Number of bytes for length */ + + + if ((count = length & 127) > sizeof(unsigned)) + { + (*buffer) += count; + return (0); + } + + for (length = 0; + count > 0 && *buffer < bufend; + count --, (*buffer) ++) + length = (length << 8) | **buffer; + } + + return (length); +} + + +/* + * 'asn1_get_oid()' - Get an OID value. + */ + +static int /* O - Number of OIDs */ +asn1_get_oid( + unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned char *bufend, /* I - End of buffer */ + int length, /* I - Length of value */ + int *oid, /* I - OID buffer */ + int oidsize) /* I - Size of OID buffer */ +{ + unsigned char *valend; /* End of value */ + int *oidptr, /* Current OID */ + *oidend; /* End of OID buffer */ + int number; /* OID number */ + + + valend = *buffer + length; + oidptr = oid; + oidend = oid + oidsize - 1; + + if (valend > bufend) + valend = bufend; + + number = asn1_get_packed(buffer, bufend); + + if (number < 80) + { + *oidptr++ = number / 40; + number = number % 40; + *oidptr++ = number; + } + else + { + *oidptr++ = 2; + number -= 80; + *oidptr++ = number; + } + + while (*buffer < valend) + { + number = asn1_get_packed(buffer, bufend); + + if (oidptr < oidend) + *oidptr++ = number; + } + + *oidptr = -1; + + return (oidptr - oid); +} + + +/* + * 'asn1_get_packed()' - Get a packed integer value. + */ + +static int /* O - Value */ +asn1_get_packed( + unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned char *bufend) /* I - End of buffer */ +{ + int value; /* Value */ + + + value = 0; + + while ((**buffer & 128) && *buffer < bufend) + { + value = (value << 7) | (**buffer & 127); + (*buffer) ++; + } + + if (*buffer < bufend) + { + value = (value << 7) | **buffer; + (*buffer) ++; + } + + return (value); +} + + +/* + * 'asn1_get_string()' - Get a string value. + */ + +static char * /* O - String */ +asn1_get_string( + unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned char *bufend, /* I - End of buffer */ + int length, /* I - Value length */ + char *string, /* I - String buffer */ + int strsize) /* I - String buffer size */ +{ + if (length < 0) + { + /* + * Disallow negative lengths! + */ + + *string = '\0'; + } + else if (length < strsize) + { + /* + * String is smaller than the buffer... + */ + + if (length > 0) + memcpy(string, *buffer, length); + + string[length] = '\0'; + } + else + { + /* + * String is larger than the buffer... + */ + + memcpy(string, *buffer, strsize - 1); + string[strsize - 1] = '\0'; + } + + if (length > 0) + (*buffer) += length; + + return (length < 0 ? NULL : string); +} + + +/* + * 'asn1_get_type()' - Get a value type. + */ + +static int /* O - Type */ +asn1_get_type(unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned char *bufend) /* I - End of buffer */ +{ + int type; /* Type */ + + + type = **buffer; + (*buffer) ++; + + if ((type & 31) == 31) + type = asn1_get_packed(buffer, bufend); + + return (type); +} + + +/* + * 'asn1_set_integer()' - Set an integer value. + */ + +static void +asn1_set_integer(unsigned char **buffer,/* IO - Pointer in buffer */ + int integer) /* I - Integer value */ +{ + **buffer = CUPS_ASN1_INTEGER; + (*buffer) ++; + + if (integer > 0x7fffff || integer < -0x800000) + { + **buffer = 4; + (*buffer) ++; + **buffer = integer >> 24; + (*buffer) ++; + **buffer = integer >> 16; + (*buffer) ++; + **buffer = integer >> 8; + (*buffer) ++; + **buffer = integer; + (*buffer) ++; + } + else if (integer > 0x7fff || integer < -0x8000) + { + **buffer = 3; + (*buffer) ++; + **buffer = integer >> 16; + (*buffer) ++; + **buffer = integer >> 8; + (*buffer) ++; + **buffer = integer; + (*buffer) ++; + } + else if (integer > 0x7f || integer < -0x80) + { + **buffer = 2; + (*buffer) ++; + **buffer = integer >> 8; + (*buffer) ++; + **buffer = integer; + (*buffer) ++; + } + else + { + **buffer = 1; + (*buffer) ++; + **buffer = integer; + (*buffer) ++; + } +} + + +/* + * 'asn1_set_length()' - Set a value length. + */ + +static void +asn1_set_length(unsigned char **buffer, /* IO - Pointer in buffer */ + unsigned length) /* I - Length value */ +{ + if (length > 255) + { + **buffer = 0x82; /* 2-byte length */ + (*buffer) ++; + **buffer = length >> 8; + (*buffer) ++; + **buffer = length; + (*buffer) ++; + } + else if (length > 127) + { + **buffer = 0x81; /* 1-byte length */ + (*buffer) ++; + **buffer = length; + (*buffer) ++; + } + else + { + **buffer = length; /* Length */ + (*buffer) ++; + } +} + + +/* + * 'asn1_set_oid()' - Set an OID value. + */ + +static void +asn1_set_oid(unsigned char **buffer, /* IO - Pointer in buffer */ + const int *oid) /* I - OID value */ +{ + **buffer = CUPS_ASN1_OID; + (*buffer) ++; + + asn1_set_length(buffer, asn1_size_oid(oid)); + + if (oid[1] < 0) + { + asn1_set_packed(buffer, oid[0] * 40); + return; + } + + asn1_set_packed(buffer, oid[0] * 40 + oid[1]); + + for (oid += 2; *oid >= 0; oid ++) + asn1_set_packed(buffer, *oid); +} + + +/* + * 'asn1_set_packed()' - Set a packed integer value. + */ + +static void +asn1_set_packed(unsigned char **buffer, /* IO - Pointer in buffer */ + int integer) /* I - Integer value */ +{ + if (integer > 0xfffffff) + { + **buffer = ((integer >> 28) & 0x7f) | 0x80; + (*buffer) ++; + } + + if (integer > 0x1fffff) + { + **buffer = ((integer >> 21) & 0x7f) | 0x80; + (*buffer) ++; + } + + if (integer > 0x3fff) + { + **buffer = ((integer >> 14) & 0x7f) | 0x80; + (*buffer) ++; + } + + if (integer > 0x7f) + { + **buffer = ((integer >> 7) & 0x7f) | 0x80; + (*buffer) ++; + } + + **buffer = integer & 0x7f; + (*buffer) ++; +} + + +/* + * 'asn1_size_integer()' - Figure out the number of bytes needed for an + * integer value. + */ + +static int /* O - Size in bytes */ +asn1_size_integer(int integer) /* I - Integer value */ +{ + if (integer > 0x7fffff || integer < -0x800000) + return (4); + else if (integer > 0x7fff || integer < -0x8000) + return (3); + else if (integer > 0x7f || integer < -0x80) + return (2); + else + return (1); +} + + +/* + * 'asn1_size_length()' - Figure out the number of bytes needed for a + * length value. + */ + +static int /* O - Size in bytes */ +asn1_size_length(int length) /* I - Length value */ +{ + if (length > 0xff) + return (3); + else if (length > 0x7f) + return (2); + else + return (1); +} + + +/* + * 'asn1_size_oid()' - Figure out the numebr of bytes needed for an + * OID value. + */ + +static int /* O - Size in bytes */ +asn1_size_oid(const int *oid) /* I - OID value */ +{ + int length; /* Length of value */ + + + if (oid[1] < 0) + return (asn1_size_packed(oid[0] * 40)); + + for (length = asn1_size_packed(oid[0] * 40 + oid[1]), oid += 2; + *oid >= 0; + oid ++) + length += asn1_size_packed(*oid); + + return (length); +} + + +/* + * 'asn1_size_packed()' - Figure out the number of bytes needed for a + * packed integer value. + */ + +static int /* O - Size in bytes */ +asn1_size_packed(int integer) /* I - Integer value */ +{ + if (integer > 0xfffffff) + return (5); + else if (integer > 0x1fffff) + return (4); + else if (integer > 0x3fff) + return (3); + else if (integer > 0x7f) + return (2); + else + return (1); +} + + +/* + * 'snmp_set_error()' - Set the localized error for a packet. + */ + +static void +snmp_set_error(cups_snmp_t *packet, /* I - Packet */ + const char *message) /* I - Error message */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + if (!cg->lang_default) + cg->lang_default = cupsLangDefault(); + + packet->error = _cupsLangString(cg->lang_default, message); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/snprintf.c b/cups/snprintf.c new file mode 100644 index 0000000000..9c3c87ae5d --- /dev/null +++ b/cups/snprintf.c @@ -0,0 +1,364 @@ +/* + * "$Id$" + * + * snprintf functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include +#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 */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + *tptr, /* Pointer into temporary format */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + int bytes; /* Total number of bytes needed */ + + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + bytes = 0; + + while (*format) + { + if (*format == '%') + { + tptr = tformat; + *tptr++ = *format++; + + if (*format == '%') + { + if (bufptr && bufptr < bufend) *bufptr++ = *format; + bytes ++; + format ++; + continue; + } + else if (strchr(" -+#\'", *format)) + { + *tptr++ = *format; + sign = *format++; + } + else + sign = 0; + + if (*format == '*') + { + /* + * Get width from argument... + */ + + format ++; + width = va_arg(ap, int); + + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); + tptr += strlen(tptr); + } + else + { + width = 0; + + while (isdigit(*format & 255)) + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + width = width * 10 + *format++ - '0'; + } + } + + if (*format == '.') + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + format ++; + + if (*format == '*') + { + /* + * Get precision from argument... + */ + + format ++; + prec = va_arg(ap, int); + + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); + tptr += strlen(tptr); + } + else + { + prec = 0; + + while (isdigit(*format & 255)) + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + prec = prec * 10 + *format++ - '0'; + } + } + } + else + prec = -1; + + if (*format == 'l' && format[1] == 'l') + { + size = 'L'; + + if (tptr < (tformat + sizeof(tformat) - 2)) + { + *tptr++ = 'l'; + *tptr++ = 'l'; + } + + format += 2; + } + else if (*format == 'h' || *format == 'l' || *format == 'L') + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + size = *format++; + } + + if (!*format) + break; + + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + type = *format++; + *tptr = '\0'; + + switch (type) + { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, double)); + + bytes += (int)strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + 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 ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, int)); + + bytes += (int)strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'p' : /* Pointer value */ + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, void *)); + + bytes += (int)strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'c' : /* Character or character array */ + bytes += width; + + if (bufptr) + { + if (width <= 1) + *bufptr++ = va_arg(ap, int); + else + { + if ((bufptr + width) > bufend) + width = (int)(bufend - bufptr); + + memcpy(bufptr, va_arg(ap, char *), (size_t)width); + bufptr += width; + } + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) + s = "(null)"; + + slen = (int)strlen(s); + if (slen > width && prec != width) + width = slen; + + bytes += width; + + if (bufptr) + { + if ((bufptr + width) > bufend) + width = (int)(bufend - bufptr); + + if (slen > width) + slen = width; + + if (sign == '-') + { + strncpy(bufptr, s, (size_t)slen); + memset(bufptr + slen, ' ', (size_t)(width - slen)); + } + else + { + memset(bufptr, ' ', (size_t)(width - slen)); + strncpy(bufptr + width - slen, s, (size_t)slen); + } + + bufptr += width; + } + break; + + case 'n' : /* Output number of chars so far */ + *(va_arg(ap, int *)) = bytes; + break; + } + } + else + { + bytes ++; + + if (bufptr && bufptr < bufend) + *bufptr++ = *format; + + format ++; + } + } + + /* + * Nul-terminate the string and return the number of characters needed. + */ + + *bufptr = '\0'; + + return (bytes); +} +#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 0000000000..ec12f82665 --- /dev/null +++ b/cups/string.c @@ -0,0 +1,794 @@ +/* + * "$Id$" + * + * String functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsStrAlloc() - Allocate/reference a string. + * _cupsStrFlush() - Flush the string pool. + * _cupsStrFormatd() - Format a floating-point number. + * _cupsStrFree() - Free/dereference a string. + * _cupsStrRetain() - Increment the reference count of a string. + * _cupsStrScand() - Scan a string for a floating-point number. + * _cupsStrStatistics() - Return allocation statistics for string pool. + * _cups_strcpy() - Copy a string allowing for overlapping strings. + * _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. + * compare_sp_items() - Compare two string pool items... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include "array.h" +#include "debug.h" +#define _CUPS_STRING_C_ +#include "string.h" +#ifdef HAVE_PTHREAD_H +# include +#endif /* HAVE_PTHREAD_H */ + + +/* + * Local globals... + */ + +#ifdef HAVE_PTHREAD_H +static pthread_mutex_t sp_mutex = PTHREAD_MUTEX_INITIALIZER; + /* Mutex to control access to pool */ +#endif /* HAVE_PTHREAD_H */ +static cups_array_t *stringpool = NULL; + /* Global string pool */ + + +/* + * Local functions... + */ + +static int compare_sp_items(_cups_sp_item_t *a, _cups_sp_item_t *b); + + +/* + * '_cupsStrAlloc()' - Allocate/reference a string. + */ + +char * /* O - String pointer */ +_cupsStrAlloc(const char *s) /* I - String */ +{ + _cups_sp_item_t *item, /* String pool item */ + *key; /* Search key */ + + + /* + * Range check input... + */ + + if (!s) + return (NULL); + + /* + * Get the string pool... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + if (!stringpool) + stringpool = cupsArrayNew((cups_array_func_t)compare_sp_items, NULL); + + if (!stringpool) + { +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (NULL); + } + + /* + * See if the string is already in the pool... + */ + + key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str)); + + if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL) + { + /* + * Found it, return the cached string... + */ + + item->ref_count ++; + +#ifdef DEBUG_GUARDS + DEBUG_printf(("5_cupsStrAlloc: Using string %p(%s) for \"%s\", guard=%08x, " + "ref_count=%d", item, item->str, s, item->guard, + item->ref_count)); + + if (item->guard != _CUPS_STR_GUARD) + abort(); +#endif /* DEBUG_GUARDS */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (item->str); + } + + /* + * Not found, so allocate a new one... + */ + + item = (_cups_sp_item_t *)calloc(1, sizeof(_cups_sp_item_t) + strlen(s)); + if (!item) + { +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (NULL); + } + + item->ref_count = 1; + strcpy(item->str, s); + +#ifdef DEBUG_GUARDS + item->guard = _CUPS_STR_GUARD; + + DEBUG_printf(("5_cupsStrAlloc: Created string %p(%s) for \"%s\", guard=%08x, " + "ref_count=%d", item, item->str, s, item->guard, + item->ref_count)); +#endif /* DEBUG_GUARDS */ + + /* + * Add the string to the pool and return it... + */ + + cupsArrayAdd(stringpool, item); + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (item->str); +} + + +/* + * '_cupsStrFlush()' - Flush the string pool. + */ + +void +_cupsStrFlush(void) +{ + _cups_sp_item_t *item; /* Current item */ + + + DEBUG_printf(("4_cupsStrFlush: %d strings in array", + cupsArrayCount(stringpool))); + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + for (item = (_cups_sp_item_t *)cupsArrayFirst(stringpool); + item; + item = (_cups_sp_item_t *)cupsArrayNext(stringpool)) + free(item); + + cupsArrayDelete(stringpool); + stringpool = NULL; + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * '_cupsStrFormatd()' - Format a floating-point number. + */ + +char * /* O - Pointer to end of string */ +_cupsStrFormatd(char *buf, /* I - String */ + char *bufend, /* I - End of string buffer */ + double number, /* I - Number to format */ + struct lconv *loc) /* I - Locale data */ +{ + char *bufptr, /* Pointer into buffer */ + temp[1024], /* Temporary string */ + *tempdec, /* Pointer to decimal point */ + *tempptr; /* Pointer into temporary string */ + const char *dec; /* Decimal point */ + int declen; /* Length of decimal point */ + + + /* + * Format the number using the "%.12f" format and then eliminate + * unnecessary trailing 0's. + */ + + snprintf(temp, sizeof(temp), "%.12f", number); + for (tempptr = temp + strlen(temp) - 1; + tempptr > temp && *tempptr == '0'; + *tempptr-- = '\0'); + + /* + * Next, find the decimal point... + */ + + if (loc && loc->decimal_point) + { + dec = loc->decimal_point; + declen = (int)strlen(dec); + } + else + { + dec = "."; + declen = 1; + } + + if (declen == 1) + tempdec = strchr(temp, *dec); + else + tempdec = strstr(temp, dec); + + /* + * Copy everything up to the decimal point... + */ + + if (tempdec) + { + for (tempptr = temp, bufptr = buf; + tempptr < tempdec && bufptr < bufend; + *bufptr++ = *tempptr++); + + tempptr += declen; + + if (*tempptr && bufptr < bufend) + { + *bufptr++ = '.'; + + while (*tempptr && bufptr < bufend) + *bufptr++ = *tempptr++; + } + + *bufptr = '\0'; + } + else + { + strlcpy(buf, temp, bufend - buf + 1); + bufptr = buf + strlen(buf); + } + + return (bufptr); +} + + +/* + * '_cupsStrFree()' - Free/dereference a string. + */ + +void +_cupsStrFree(const char *s) /* I - String to free */ +{ + _cups_sp_item_t *item, /* String pool item */ + *key; /* Search key */ + + + /* + * Range check input... + */ + + if (!s) + return; + + /* + * Check the string pool... + * + * We don't need to lock the mutex yet, as we only want to know if + * the stringpool is initialized. The rest of the code will still + * work if it is initialized before we lock... + */ + + if (!stringpool) + return; + + /* + * See if the string is already in the pool... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + key = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str)); + +#ifdef DEBUG_GUARDS + if (key->guard != _CUPS_STR_GUARD) + { + DEBUG_printf(("5_cupsStrFree: Freeing string %p(%s), guard=%08x, " + "ref_count=%d", key, key->str, key->guard, key->ref_count)); + abort(); + } +#endif /* DEBUG_GUARDS */ + + if ((item = (_cups_sp_item_t *)cupsArrayFind(stringpool, key)) != NULL && + item == key) + { + /* + * Found it, dereference... + */ + + item->ref_count --; + + if (!item->ref_count) + { + /* + * Remove and free... + */ + + cupsArrayRemove(stringpool, item); + + free(item); + } + } + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * '_cupsStrRetain()' - Increment the reference count of a string. + * + * Note: This function does not verify that the passed pointer is in the + * string pool, so any calls to it MUST know they are passing in a + * good pointer. + */ + +char * /* O - Pointer to string */ +_cupsStrRetain(const char *s) /* I - String to retain */ +{ + _cups_sp_item_t *item; /* Pointer to string pool item */ + + + if (s) + { + item = (_cups_sp_item_t *)(s - offsetof(_cups_sp_item_t, str)); + +#ifdef DEBUG_GUARDS + if (item->guard != _CUPS_STR_GUARD) + { + DEBUG_printf(("5_cupsStrRetain: Retaining string %p(%s), guard=%08x, " + "ref_count=%d", item, s, item->guard, item->ref_count)); + abort(); + } +#endif /* DEBUG_GUARDS */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + item->ref_count ++; + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + } + + return ((char *)s); +} + + +/* + * '_cupsStrScand()' - Scan a string for a floating-point number. + * + * This function handles the locale-specific BS so that a decimal + * point is always the period (".")... + */ + +double /* O - Number */ +_cupsStrScand(const char *buf, /* I - Pointer to number */ + char **bufptr, /* O - New pointer or NULL on error */ + struct lconv *loc) /* I - Locale data */ +{ + char temp[1024], /* Temporary buffer */ + *tempptr; /* Pointer into temporary buffer */ + + + /* + * Range check input... + */ + + if (!buf) + return (0.0); + + /* + * Skip leading whitespace... + */ + + while (_cups_isspace(*buf)) + buf ++; + + /* + * Copy leading sign, numbers, period, and then numbers... + */ + + tempptr = temp; + if (*buf == '-' || *buf == '+') + *tempptr++ = *buf++; + + while (isdigit(*buf & 255)) + if (tempptr < (temp + sizeof(temp) - 1)) + *tempptr++ = *buf++; + else + { + if (bufptr) + *bufptr = NULL; + + return (0.0); + } + + if (*buf == '.') + { + /* + * Read fractional portion of number... + */ + + buf ++; + + if (loc && loc->decimal_point) + { + strlcpy(tempptr, loc->decimal_point, sizeof(temp) - (tempptr - temp)); + tempptr += strlen(tempptr); + } + else if (tempptr < (temp + sizeof(temp) - 1)) + *tempptr++ = '.'; + else + { + if (bufptr) + *bufptr = NULL; + + return (0.0); + } + + while (isdigit(*buf & 255)) + if (tempptr < (temp + sizeof(temp) - 1)) + *tempptr++ = *buf++; + else + { + if (bufptr) + *bufptr = NULL; + + return (0.0); + } + } + + if (*buf == 'e' || *buf == 'E') + { + /* + * Read exponent... + */ + + if (tempptr < (temp + sizeof(temp) - 1)) + *tempptr++ = *buf++; + else + { + if (bufptr) + *bufptr = NULL; + + return (0.0); + } + + if (*buf == '+' || *buf == '-') + { + if (tempptr < (temp + sizeof(temp) - 1)) + *tempptr++ = *buf++; + else + { + if (bufptr) + *bufptr = NULL; + + return (0.0); + } + } + + while (isdigit(*buf & 255)) + if (tempptr < (temp + sizeof(temp) - 1)) + *tempptr++ = *buf++; + else + { + if (bufptr) + *bufptr = NULL; + + return (0.0); + } + } + + /* + * Nul-terminate the temporary string and return the value... + */ + + if (bufptr) + *bufptr = (char *)buf; + + *tempptr = '\0'; + + return (strtod(temp, NULL)); +} + + +/* + * '_cupsStrStatistics()' - Return allocation statistics for string pool. + */ + +size_t /* O - Number of strings */ +_cupsStrStatistics(size_t *alloc_bytes, /* O - Allocated bytes */ + size_t *total_bytes) /* O - Total string bytes */ +{ + size_t count, /* Number of strings */ + abytes, /* Allocated string bytes */ + tbytes, /* Total string bytes */ + len; /* Length of string */ + _cups_sp_item_t *item; /* Current item */ + + + /* + * Loop through strings in pool, counting everything up... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + for (count = 0, abytes = 0, tbytes = 0, + item = (_cups_sp_item_t *)cupsArrayFirst(stringpool); + item; + item = (_cups_sp_item_t *)cupsArrayNext(stringpool)) + { + /* + * Count allocated memory, using a 64-bit aligned buffer as a basis. + */ + + count += item->ref_count; + len = (strlen(item->str) + 8) & ~7; + abytes += sizeof(_cups_sp_item_t) + len; + tbytes += item->ref_count * len; + } + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&sp_mutex); +#endif /* HAVE_PTHREAD_H */ + + /* + * Return values... + */ + + if (alloc_bytes) + *alloc_bytes = abytes; + + if (total_bytes) + *total_bytes = tbytes; + + return (count); +} + + +/* + * '_cups_strcpy()' - Copy a string allowing for overlapping strings. + */ + +void +_cups_strcpy(char *dst, /* I - Destination string */ + const char *src) /* I - Source string */ +{ + while (*src) + *dst++ = *src++; + + *dst = '\0'; +} + + +/* + * '_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 & 255) < tolower(*t & 255)) + return (-1); + else if (tolower(*s & 255) > tolower(*t & 255)) + 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 & 255) < tolower(*t & 255)) + return (-1); + else if (tolower(*s & 255) > tolower(*t & 255)) + 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 */ + + +/* + * 'compare_sp_items()' - Compare two string pool items... + */ + +static int /* O - Result of comparison */ +compare_sp_items(_cups_sp_item_t *a, /* I - First item */ + _cups_sp_item_t *b) /* I - Second item */ +{ + return (strcmp(a->str, b->str)); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/string.h b/cups/string.h new file mode 100644 index 0000000000..6ca08d74e1 --- /dev/null +++ b/cups/string.h @@ -0,0 +1,216 @@ +/* + * "$Id$" + * + * String definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +# include +# include +# include +# include +# include + +# include + +# ifdef HAVE_STRING_H +# include +# endif /* HAVE_STRING_H */ + +# ifdef HAVE_STRINGS_H +# include +# endif /* HAVE_STRINGS_H */ + +# ifdef HAVE_BSTRING_H +# include +# 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 */ + + +/* + * String pool structures... + */ + +# define _CUPS_STR_GUARD 0x12344321 + +typedef struct _cups_sp_item_s /**** String Pool Item ****/ +{ +# ifdef DEBUG_GUARDS + unsigned int guard; /* Guard word */ +# endif /* DEBUG_GUARDS */ + unsigned int ref_count; /* Reference count */ + char str[1]; /* String */ +} _cups_sp_item_t; + + +/* + * Replacements for the ctype macros that are not affected by locale, since we + * really only care about testing for ASCII characters when parsing files, etc. + * These are used only within libcups since the rest of CUPS doesn't call + * setlocale() for LC_CTYPE and doesn't have to worry about third-party + * libraries doing so (and if they do that is a bug: NetSNMP, I'm looking at + * you!) + * + * The _CUPS_INLINE definition controls whether we get an inline function body, + * and external function body, or an external definition. + */ + +# if defined(__GNUC__) || __STDC_VERSION__ >= 199901L +# define _CUPS_INLINE static inline +# elif defined(_MSC_VER) +# define _CUPS_INLINE static __inline +# elif defined(_CUPS_STRING_C_) +# define _CUPS_INLINE +# endif /* __GNUC__ || __STDC_VERSION__ */ + +# ifdef _CUPS_INLINE +_CUPS_INLINE int /* O - 1 on match, 0 otherwise */ +_cups_isalnum(int ch) /* I - Character to test */ +{ + return ((ch >= '0' && ch <= '9') || + (ch >= 'A' && ch <= 'Z') || + (ch >= 'a' && ch <= 'z')); +} + +_CUPS_INLINE int /* O - 1 on match, 0 otherwise */ +_cups_isalpha(int ch) /* I - Character to test */ +{ + return ((ch >= 'A' && ch <= 'Z') || + (ch >= 'a' && ch <= 'z')); +} + +_CUPS_INLINE int /* O - 1 on match, 0 otherwise */ +_cups_isspace(int ch) /* I - Character to test */ +{ + return (ch == ' ' || ch == '\f' || ch == '\n' || ch == '\r' || ch == '\t' || + ch == '\v'); +} + +_CUPS_INLINE int /* O - 1 on match, 0 otherwise */ +_cups_isupper(int ch) /* I - Character to test */ +{ + return (ch >= 'A' && ch <= 'Z'); +} +# else +extern int _cups_isalnum(int ch); +extern int _cups_isalpha(int ch); +extern int _cups_isspace(int ch); +extern int _cups_isupper(int ch); +# endif /* _CUPS_INLINE */ + + +/* + * Prototypes... + */ + +extern void _cups_strcpy(char *dst, const char *src); + +# 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 */ + +/* + * String pool functions... + */ + +extern char *_cupsStrAlloc(const char *s); +extern void _cupsStrFlush(void); +extern void _cupsStrFree(const char *s); +extern char *_cupsStrRetain(const char *s); +extern size_t _cupsStrStatistics(size_t *alloc_bytes, size_t *total_bytes); + + +/* + * Floating point number functions... + */ + +extern char *_cupsStrFormatd(char *buf, char *bufend, double number, + struct lconv *loc); +extern double _cupsStrScand(const char *buf, char **bufptr, + struct lconv *loc); + + +/* + * 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 0000000000..9fb5d8e163 --- /dev/null +++ b/cups/tempfile.c @@ -0,0 +1,235 @@ +/* + * "$Id$" + * + * Temp file utilities for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsTempFd() - Creates a temporary file. + * cupsTempFile() - Generates a temporary filename. + * cupsTempFile2() - Creates a temporary CUPS file. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include +#include +#include +#include +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * 'cupsTempFd()' - Creates a temporary file. + * + * The temporary filename is returned in the filename buffer. + * The temporary file is opened for reading and writing. + */ + +int /* O - New file descriptor or -1 on error */ +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 */ + const char *tmpdir; /* TMPDIR environment var */ +#ifdef WIN32 + char tmppath[1024]; /* Windows temporary directory */ + DWORD curtime; /* Current time */ +#else + struct timeval curtime; /* Current time */ +#endif /* WIN32 */ + + + /* + * See if TMPDIR is defined... + */ + +#ifdef WIN32 + if ((tmpdir = getenv("TEMP")) == NULL) + { + GetTempPath(sizeof(tmppath), tmppath); + tmpdir = tmppath; + } +#else + /* + * Previously we put root temporary files in the default CUPS temporary + * directory under /var/spool/cups. However, since the scheduler cleans + * out temporary files there and runs independently of the user apps, we + * don't want to use it unless specifically told to by cupsd. + */ + + if ((tmpdir = getenv("TMPDIR")) == NULL) +# ifdef __APPLE__ + tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */ +# else + tmpdir = "/tmp"; +# endif /* __APPLE__ */ +#endif /* WIN32 */ + + /* + * Make the temporary name using the specified directory... + */ + + tries = 0; + + do + { +#ifdef WIN32 + /* + * Get the current time of day... + */ + + curtime = GetTickCount() + tries; + + /* + * Format a string using the hex time values... + */ + + snprintf(filename, len - 1, "%s/%05lx%08lx", tmpdir, + GetCurrentProcessId(), curtime); +#else + /* + * Get the current time of day... + */ + + gettimeofday(&curtime, NULL); + + /* + * Format a string using the hex time values... + */ + + snprintf(filename, len - 1, "%s/%05x%08x", tmpdir, (unsigned)getpid(), + (unsigned)(curtime.tv_sec + curtime.tv_usec + tries)); +#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 WIN32 + fd = open(filename, _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY, + _S_IREAD | _S_IWRITE); +#elif defined(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 /* WIN32 */ + + if (fd < 0 && errno != EEXIST) + break; + + tries ++; + } + while (fd < 0 && tries < 1000); + + /* + * Return the file descriptor... + */ + + return (fd); +} + + +/* + * 'cupsTempFile()' - Generates a temporary filename. + * + * The temporary filename is returned in the filename buffer. + * This function is deprecated - use @link cupsTempFd@ or + * @link cupsTempFile2@ instead. + * + * @deprecated@ + */ + +char * /* O - Filename or @code NULL@ on error */ +cupsTempFile(char *filename, /* I - Pointer to buffer */ + int len) /* I - Size of buffer */ +{ + int fd; /* File descriptor for temp file */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * See if a filename was specified... + */ + + if (filename == NULL) + { + filename = cg->tempfile; + len = sizeof(cg->tempfile); + } + + /* + * 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); +} + + +/* + * 'cupsTempFile2()' - Creates a temporary CUPS file. + * + * The temporary filename is returned in the filename buffer. + * The temporary file is opened for writing. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +cups_file_t * /* O - CUPS file or @code NULL@ on error */ +cupsTempFile2(char *filename, /* I - Pointer to buffer */ + int len) /* I - Size of buffer */ +{ + cups_file_t *file; /* CUPS file */ + int fd; /* File descriptor */ + + + if ((fd = cupsTempFd(filename, len)) < 0) + return (NULL); + else if ((file = cupsFileOpenFd(fd, "w")) == NULL) + { + close(fd); + unlink(filename); + return (NULL); + } + else + return (file); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/test.ppd b/cups/test.ppd new file mode 100644 index 0000000000..ed7fe1d1d2 --- /dev/null +++ b/cups/test.ppd @@ -0,0 +1,262 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Test PPD file for CUPS. +*% +*% This file is used to test the CUPS PPD API functions and cannot be +*% used with any known printers. Look on the CUPS web site for working PPD +*% files. +*% +*% If you are a PPD file developer, consider using the PPD compiler (ppdc) +*% to create your PPD files - not only will it save you time, it produces +*% consistently high-quality files. +*% +*% Copyright 2007-2010 by Apple Inc. +*% Copyright 2002-2006 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Apple Inc. 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 +*% file is missing or damaged, see the license at "http://www.cups.org/". +*FormatVersion: "4.3" +*FileVersion: "1.3" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "TEST.PPD" +*Manufacturer: "ESP" +*Product: "(Test)" +*cupsVersion: 1.4 +*ModelName: "Test" +*ShortNickName: "Test" +*NickName: "Test for CUPS" +*PSVersion: "(3010.000) 0" +*LanguageLevel: "3" +*ColorDevice: True +*DefaultColorSpace: RGB +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*TTRasterizer: Type42 +*cupsFilter: "application/vnd.cups-raster 0 -" +*RequiresPageRegion All: True + +*% These constraints are used to test ppdConflicts() and cupsResolveConflicts() +*UIConstraints: *PageSize Letter *InputSlot Envelope +*UIConstraints: *InputSlot Envelope *PageSize Letter +*UIConstraints: *PageRegion Letter *InputSlot Envelope +*UIConstraints: *InputSlot Envelope *PageRegion Letter + +*% These constraints are used to test ppdInstallableConflict() +*UIConstraints: "*Duplex *InstalledDuplexer False" +*UIConstraints: "*InstalledDuplexer False *Duplex" + +*% These attributes test ppdFindAttr/ppdFindNext... +*cupsTest Foo/I Love Foo: "" +*cupsTest Bar/I Love Bar: "" + +*% For PageSize, we have put all of the translations in-line... +*OpenUI *PageSize/Page Size: PickOne +*fr.Translation PageSize/French Page Size: "" +*fr_CA.Translation PageSize/French Canadian Page Size: "" +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter/US Letter: "PageSize=Letter" +*fr.PageSize Letter/French US Letter: "" +*fr_CA.PageSize Letter/French Canadian US Letter: "" +*PageSize Letter.Banner/US Letter Banner: "PageSize=Letter.Banner" +*fr.PageSize Letter.Banner/French US Letter Banner: "" +*fr_CA.PageSize Letter.Banner/French Canadian US Letter Banner: "" +*PageSize Letter.Fullbleed/US Letter Borderless: "PageSize=Letter.Fullbleed" +*fr.PageSize Letter.Fullbleed/French US Letter Borderless: "" +*fr_CA.PageSize Letter.Fullbleed/French Canadian US Letter Borderless: "" +*PageSize A4/A4: "PageSize=A4" +*fr.PageSize A4/French A4: "" +*fr_CA.PageSize A4/French Canadian A4: "" +*PageSize Env10/#10 Envelope: "PageSize=Env10" +*fr.PageSize Env10/French #10 Envelope: "" +*fr_CA.PageSize Env10/French Canadian #10 Envelope: "" +*CloseUI: *PageSize + +*% For PageRegion, we have separated the translations... +*OpenUI *PageRegion/Page Region: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/US Letter: "PageRegion=Letter" +*PageRegion Letter.Banner/US Letter Banner: "PageRegion=Letter.Fullbleed" +*PageRegion Letter.Fullbleed/US Letter Borderless: "PageRegion=Letter.Fullbleed" +*PageRegion A4/A4: "PageRegion=A4" +*PageRegion Env10/#10 Envelope: "PageRegion=Env10" +*CloseUI: *PageRegion + +*fr.Translation PageRegion/French Page Region: "" +*fr.PageRegion Letter/French US Letter: "" +*fr.PageRegion Letter.Banner/French US Letter Banner: "" +*fr.PageRegion Letter.Fullbleed/French US Letter Borderless: "" +*fr.PageRegion A4/French A4: "" +*fr.PageRegion Env10/French #10 Envelope: "" + +*fr_CA.Translation PageRegion/French Canadian Page Region: "" +*fr_CA.PageRegion Letter/French Canadian US Letter: "" +*fr_CA.PageRegion Letter.Banner/French Canadian US Letter Banner: "" +*fr_CA.PageRegion Letter.Fullbleed/French Canadian US Letter Borderless: "" +*fr_CA.PageRegion A4/French Canadian A4: "" +*fr_CA.PageRegion Env10/French Canadian #10 Envelope: "" + +*DefaultImageableArea: Letter +*ImageableArea Letter: "18 36 594 756" +*ImageableArea Letter.Banner: "18 0 594 792" +*ImageableArea Letter.Fullbleed: "0 0 612 792" +*ImageableArea A4: "18 36 577 806" +*ImageableArea Env10: "18 36 279 648" + +*DefaultPaperDimension: Letter +*PaperDimension Letter: "612 792" +*PaperDimension Letter.Banner: "612 792" +*PaperDimension Letter.Fullbleed: "612 792" +*PaperDimension A4: "595 842" +*PaperDimension Env10: "297 684" + +*% Custom page size support +*HWMargins: 0 0 0 0 +*NonUIOrderDependency: 100 AnySetup *CustomPageSize True +*CustomPageSize True/Custom Page Size: "PageSize=Custom" +*ParamCustomPageSize Width: 1 points 36 1080 +*ParamCustomPageSize Height: 2 points 36 86400 +*ParamCustomPageSize WidthOffset/Width Offset: 3 points 0 0 +*ParamCustomPageSize HeightOffset/Height Offset: 4 points 0 0 +*ParamCustomPageSize Orientation: 5 int 0 0 + +*OpenUI *InputSlot/Input Slot: PickOne +*OrderDependency: 20 AnySetup *InputSlot +*DefaultInputSlot: Tray +*InputSlot Tray/Tray: "InputSlot=Tray" +*InputSlot Manual/Manual Feed: "InputSlot=Manual" +*InputSlot Envelope/Envelope Feed: "InputSlot=Envelope" +*CloseUI: *InputSlot + +*OpenUI *MediaType/Media Type: PickOne +*OrderDependency: 25 AnySetup *MediaType +*DefaultMediaType: Plain +*MediaType Plain/Plain Paper: "MediaType=Plain" +*MediaType Matte/Matte Photo: "MediaType=Matte" +*MediaType Glossy/Glossy Photo: "MediaType=Glossy" +*MediaType Transparency/Transparency Film: "MediaType=Transparency" +*CloseUI: *MediaType + +*OpenUI *Duplex/2-Sided Printing: PickOne +*OrderDependency: 10 DocumentSetup *Duplex +*DefaultDuplex: None +*Duplex None/Off: "Duplex=None" +*Duplex DuplexNoTumble/Long Edge: "Duplex=DuplexNoTumble" +*Duplex DuplexTumble/Short Edge: "Duplex=DuplexTumble" +*CloseUI: *Duplex + +*% Installable option... +*OpenGroup: InstallableOptions/Installable Options +*OpenUI InstalledDuplexer/Duplexer Installed: Boolean +*DefaultInstalledDuplexer: False +*InstalledDuplexer False: "" +*InstalledDuplexer True: "" +*CloseUI: *InstalledDuplexer +*CloseGroup: InstallableOptions + +*% Custom options... +*OpenGroup: Extended/Extended Options + +*OpenUI IntOption/Integer: PickOne +*OrderDependency: 30 AnySetup *IntOption +*DefaultIntOption: None +*IntOption None: "" +*IntOption 1: "IntOption=1" +*IntOption 2: "IntOption=2" +*IntOption 3: "IntOption=3" +*CloseUI: *IntOption + +*CustomIntOption True/Custom Integer: "IntOption=Custom" +*ParamCustomIntOption Integer: 1 int -100 100 + +*OpenUI StringOption/String: PickOne +*OrderDependency: 40 AnySetup *StringOption +*DefaultStringOption: None +*StringOption None: "" +*StringOption foo: "StringOption=foo" +*StringOption bar: "StringOption=bar" +*CloseUI: *StringOption + +*CustomStringOption True/Custom String: "StringOption=Custom" +*ParamCustomStringOption String1: 2 string 1 10 +*ParamCustomStringOption String2: 1 string 1 10 + +*CloseGroup: Extended + +*% IPP reasons for ppdLocalizeIPPReason tests +*cupsIPPReason foo/Foo Reason: "http://foo/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/foo/bar.html" +*End +*fr.cupsIPPReason foo/La Foo Reason: "text:La%20Long%20 +text:Foo%20Reason +http://foo/fr/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/fr/foo/bar.html" +*End +*zh_TW.cupsIPPReason foo/Number 1 Foo Reason: "text:Number%201%20 +text:Foo%20Reason +http://foo/zh_TW/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/zh_TW/foo/bar.html" +*End +*zh.cupsIPPReason foo/Number 2 Foo Reason: "text:Number%202%20 +text:Foo%20Reason +http://foo/zh/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/zh/foo/bar.html" +*End + +*% Marker names for ppdLocalizeMarkerName tests +*cupsMarkerName cyan/Cyan Toner: "" +*fr.cupsMarkerName cyan/La Toner Cyan: "" +*zh_TW.cupsMarkerName cyan/Number 1 Cyan Toner: "" +*zh.cupsMarkerName cyan/Number 2 Cyan Toner: "" + +*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/cups/test2.ppd b/cups/test2.ppd new file mode 100644 index 0000000000..e16ea369e2 --- /dev/null +++ b/cups/test2.ppd @@ -0,0 +1,252 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Test PPD file #2 for the Common UNIX Printing System (CUPS). +*% +*% This file is used to test the CUPS PPD API functions and cannot be +*% used with any known printers. Look on the CUPS web site for working PPD +*% files. +*% +*% If you are a PPD file developer, consider using the PPD compiler (ppdc) +*% to create your PPD files - not only will it save you time, it produces +*% consistently high-quality files. +*% +*% Copyright 2007-2009 by Apple Inc. +*% Copyright 2002-2006 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Apple Inc. 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 +*% file is missing or damaged, see the license at "http://www.cups.org/". +*FormatVersion: "4.3" +*FileVersion: "1.3" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "TEST.PPD" +*Manufacturer: "ESP" +*Product: "(Test2)" +*cupsVersion: 1.4 +*ModelName: "Test2" +*ShortNickName: "Test2" +*NickName: "Test2 for CUPS" +*PSVersion: "(3010.000) 0" +*LanguageLevel: "3" +*ColorDevice: True +*DefaultColorSpace: RGB +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*TTRasterizer: Type42 + +*% These constraints are used to test ppdConflicts() and cupsResolveConflicts() +*cupsUIConstraints envelope: "*PageSize Letter *InputSlot Envelope" +*cupsUIConstraints envelope: "*PageSize A4 *InputSlot Envelope" +*cupsUIResolver envelope: "*InputSlot Manual *PageSize Env10" + +*cupsUIConstraints envphoto: "*PageSize Env10 *InputSlot Envelope *Quality Photo" +*cupsUIResolver envphoto: "*Quality Normal" + +*% This constraint is used to test ppdInstallableConflict() +*cupsUIConstraints: "*Duplex *InstalledDuplexer False" + +*% These constraints are used to test the loop detection code in cupsResolveConflicts() +*cupsUIConstraints loop1: "*PageSize A4 *Quality Photo" +*cupsUIResolver loop1: "*Quality Normal" +*cupsUIConstraints loop2: "*PageSize A4 *Quality Normal" +*cupsUIResolver loop2: "*Quality Photo" + +*% For PageSize, we have put all of the translations in-line... +*OpenUI *PageSize/Page Size: PickOne +*fr.Translation PageSize/French Page Size: "" +*fr_CA.Translation PageSize/French Canadian Page Size: "" +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter/US Letter: "PageSize=Letter" +*fr.PageSize Letter/French US Letter: "" +*fr_CA.PageSize Letter/French Canadian US Letter: "" +*PageSize A4/A4: "PageSize=A4" +*fr.PageSize A4/French A4: "" +*fr_CA.PageSize A4/French Canadian A4: "" +*PageSize Env10/#10 Envelope: "PageSize=Env10" +*fr.PageSize Env10/French #10 Envelope: "" +*fr_CA.PageSize Env10/French Canadian #10 Envelope: "" +*CloseUI: *PageSize + +*% For PageRegion, we have separated the translations... +*OpenUI *PageRegion/Page Region: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/US Letter: "PageRegion=Letter" +*PageRegion A4/A4: "PageRegion=A4" +*PageRegion Env10/#10 Envelope: "PageRegion=Env10" +*CloseUI: *PageRegion + +*fr.Translation PageRegion/French Page Region: "" +*fr.PageRegion Letter/French US Letter: "" +*fr.PageRegion A4/French A4: "" +*fr.PageRegion Env10/French #10 Envelope: "" + +*fr_CA.Translation PageRegion/French Canadian Page Region: "" +*fr_CA.PageRegion Letter/French Canadian US Letter: "" +*fr_CA.PageRegion A4/French Canadian A4: "" +*fr_CA.PageRegion Env10/French Canadian #10 Envelope: "" + +*DefaultImageableArea: Letter +*ImageableArea Letter: "18 36 594 756" +*ImageableArea A4: "18 36 577 806" +*ImageableArea Env10: "18 36 279 648" + +*DefaultPaperDimension: Letter +*PaperDimension Letter: "612 792" +*PaperDimension A4: "595 842" +*PaperDimension Env10: "297 684" + +*% Custom page size support +*HWMargins: 0 0 0 0 +*NonUIOrderDependency: 100 AnySetup *CustomPageSize True +*CustomPageSize True/Custom Page Size: "PageSize=Custom" +*ParamCustomPageSize Width: 1 points 36 1080 +*ParamCustomPageSize Height: 2 points 36 86400 +*ParamCustomPageSize WidthOffset/Width Offset: 3 points 0 0 +*ParamCustomPageSize HeightOffset/Height Offset: 4 points 0 0 +*ParamCustomPageSize Orientation: 5 int 0 0 + +*cupsMediaQualifier2: InputSlot +*cupsMediaQualifier3: Quality +*cupsMaxSize .Manual.: "1000 1000" +*cupsMinSize .Manual.: "100 100" +*cupsMinSize .Manual.Photo: "200 200" +*cupsMinSize ..Photo: "300 300" + +*OpenUI *InputSlot/Input Slot: PickOne +*OrderDependency: 20 AnySetup *InputSlot +*DefaultInputSlot: Tray +*InputSlot Tray/Tray: "InputSlot=Tray" +*InputSlot Manual/Manual Feed: "InputSlot=Manual" +*InputSlot Envelope/Envelope Feed: "InputSlot=Envelope" +*CloseUI: *InputSlot + +*OpenUI *Quality/Output Mode: PickOne +*OrderDependency: 20 AnySetup *Quality +*DefaultQuality: Normal +*Quality Draft: "Quality=Draft" +*Quality Normal: "Quality=Normal" +*Quality Photo: "Quality=Photo" +*CloseUI: *Quality + +*OpenUI *Duplex/2-Sided Printing: PickOne +*OrderDependency: 10 DocumentSetup *Duplex +*DefaultDuplex: None +*Duplex None/Off: "Duplex=None" +*Duplex DuplexNoTumble/Long Edge: "Duplex=DuplexNoTumble" +*Duplex DuplexTumble/Short Edge: "Duplex=DuplexTumble" +*CloseUI: *Duplex + +*% Installable option... +*OpenGroup: InstallableOptions/Installable Options +*OpenUI InstalledDuplexer/Duplexer Installed: Boolean +*DefaultInstalledDuplexer: False +*InstalledDuplexer False: "" +*InstalledDuplexer True: "" +*CloseUI: *InstalledDuplexer +*CloseGroup: InstallableOptions + +*% Custom options... +*OpenGroup: Extended/Extended Options + +*OpenUI IntOption/Integer: PickOne +*OrderDependency: 30 AnySetup *IntOption +*DefaultIntOption: None +*IntOption None: "" +*IntOption 1: "IntOption=1" +*IntOption 2: "IntOption=2" +*IntOption 3: "IntOption=3" +*CloseUI: *IntOption + +*CustomIntOption True/Custom Integer: "IntOption=Custom" +*ParamCustomIntOption Integer: 1 int -100 100 + +*OpenUI StringOption/String: PickOne +*OrderDependency: 40 AnySetup *StringOption +*DefaultStringOption: None +*StringOption None: "" +*StringOption foo: "StringOption=foo" +*StringOption bar: "StringOption=bar" +*CloseUI: *StringOption + +*CustomStringOption True/Custom String: "StringOption=Custom" +*ParamCustomStringOption String: 1 string 1 10 + +*CloseGroup: Extended + +*% IPP reasons for ppdLocalizeIPPReason tests +*cupsIPPReason foo/Foo Reason: "http://foo/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/foo/bar.html" +*End +*fr.cupsIPPReason foo/La Foo Reason: "text:La%20Long%20 +text:Foo%20Reason +http://foo/fr/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/fr/foo/bar.html" +*End +*zh_TW.cupsIPPReason foo/Number 1 Foo Reason: "text:Number%201%20 +text:Foo%20Reason +http://foo/zh_TW/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/zh_TW/foo/bar.html" +*End +*zh.cupsIPPReason foo/Number 2 Foo Reason: "text:Number%202%20 +text:Foo%20Reason +http://foo/zh/bar.html +help:anchor='foo'%20bookID=Vendor%20Help +/help/zh/foo/bar.html" +*End + +*% Marker names for ppdLocalizeMarkerName tests +*cupsMarkerName cyan/Cyan Toner: "" +*fr.cupsMarkerName cyan/La Toner Cyan: "" +*zh_TW.cupsMarkerName cyan/Number 1 Cyan Toner: "" +*zh.cupsMarkerName cyan/Number 2 Cyan Toner: "" + +*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/cups/testadmin.c b/cups/testadmin.c new file mode 100644 index 0000000000..7af84b269a --- /dev/null +++ b/cups/testadmin.c @@ -0,0 +1,120 @@ +/* + * "$Id$" + * + * Admin function test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * show_settings() - Show settings in the array... + */ + +/* + * Include necessary headers... + */ + +#include "adminutil.h" +#include "string.h" + + +/* + * Local functions... + */ + +static void show_settings(int num_settings, cups_option_t *settings); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, /* Looping var */ + num_settings; /* Number of settings */ + cups_option_t *settings; /* Settings */ + http_t *http; /* Connection to server */ + + + /* + * Connect to the server using the defaults... + */ + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + /* + * Set the current configuration if we have anything on the command-line... + */ + + if (argc > 1) + { + for (i = 1, num_settings = 0, settings = NULL; i < argc; i ++) + num_settings = cupsParseOptions(argv[i], num_settings, &settings); + + if (cupsAdminSetServerSettings(http, num_settings, settings)) + { + puts("New server settings:"); + cupsFreeOptions(num_settings, settings); + } + else + { + printf("Server settings not changed: %s\n", cupsLastErrorString()); + return (1); + } + } + else + puts("Current server settings:"); + + /* + * Get the current configuration... + */ + + if (cupsAdminGetServerSettings(http, &num_settings, &settings)) + { + show_settings(num_settings, settings); + cupsFreeOptions(num_settings, settings); + return (0); + } + else + { + printf(" %s\n", cupsLastErrorString()); + return (1); + } +} + + +/* + * 'show_settings()' - Show settings in the array... + */ + +static void +show_settings( + int num_settings, /* I - Number of settings */ + cups_option_t *settings) /* I - Settings */ +{ + while (num_settings > 0) + { + printf(" %s=%s\n", settings->name, settings->value); + + settings ++; + num_settings --; + } +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testarray.c b/cups/testarray.c new file mode 100644 index 0000000000..c3bfefc717 --- /dev/null +++ b/cups/testarray.c @@ -0,0 +1,483 @@ +/* + * "$Id$" + * + * Array test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * get_seconds() - Get the current time in seconds... + * load_words() - Load words from a file. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include "array.h" +#include "dir.h" +#include "debug.h" + + +/* + * Local functions... + */ + +static double get_seconds(void); +static int load_words(const char *filename, cups_array_t *array); + + +/* + * '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 */ + cups_array_t *array, /* Test array */ + *dup_array; /* Duplicate array */ + int status; /* Exit status */ + char *text; /* Text from array */ + char word[256]; /* Word from file */ + double start, /* Start time */ + end; /* End time */ + cups_dir_t *dir; /* Current directory */ + cups_dentry_t *dent; /* Directory entry */ + char *saved[32]; /* Saved entries */ + void *data; /* User data for arrays */ + + + /* + * No errors so far... + */ + + status = 0; + + /* + * cupsArrayNew() + */ + + fputs("cupsArrayNew: ", stdout); + + data = (void *)"testarray"; + array = cupsArrayNew((cups_array_func_t)strcmp, data); + + if (array) + puts("PASS"); + else + { + puts("FAIL (returned NULL, expected pointer)"); + status ++; + } + + /* + * cupsArrayUserData() + */ + + fputs("cupsArrayUserData: ", stdout); + if (cupsArrayUserData(array) == data) + puts("PASS"); + else + { + printf("FAIL (returned %p instead of %p!)\n", cupsArrayUserData(array), + data); + status ++; + } + + /* + * cupsArrayAdd() + */ + + fputs("cupsArrayAdd: ", stdout); + + if (!cupsArrayAdd(array, strdup("One Fish"))) + { + puts("FAIL (\"One Fish\")"); + status ++; + } + else + { + if (!cupsArrayAdd(array, strdup("Two Fish"))) + { + puts("FAIL (\"Two Fish\")"); + status ++; + } + else + { + if (!cupsArrayAdd(array, strdup("Red Fish"))) + { + puts("FAIL (\"Red Fish\")"); + status ++; + } + else + { + if (!cupsArrayAdd(array, strdup("Blue Fish"))) + { + puts("FAIL (\"Blue Fish\")"); + status ++; + } + else + puts("PASS"); + } + } + } + + /* + * cupsArrayCount() + */ + + fputs("cupsArrayCount: ", stdout); + if (cupsArrayCount(array) == 4) + puts("PASS"); + else + { + printf("FAIL (returned %d, expected 4)\n", cupsArrayCount(array)); + status ++; + } + + /* + * cupsArrayFirst() + */ + + fputs("cupsArrayFirst: ", stdout); + if ((text = (char *)cupsArrayFirst(array)) != NULL && + !strcmp(text, "Blue Fish")) + puts("PASS"); + else + { + printf("FAIL (returned \"%s\", expected \"Blue Fish\")\n", text); + status ++; + } + + /* + * cupsArrayNext() + */ + + fputs("cupsArrayNext: ", stdout); + if ((text = (char *)cupsArrayNext(array)) != NULL && + !strcmp(text, "One Fish")) + puts("PASS"); + else + { + printf("FAIL (returned \"%s\", expected \"One Fish\")\n", text); + status ++; + } + + /* + * cupsArrayLast() + */ + + fputs("cupsArrayLast: ", stdout); + if ((text = (char *)cupsArrayLast(array)) != NULL && + !strcmp(text, "Two Fish")) + puts("PASS"); + else + { + printf("FAIL (returned \"%s\", expected \"Two Fish\")\n", text); + status ++; + } + + /* + * cupsArrayPrev() + */ + + fputs("cupsArrayPrev: ", stdout); + if ((text = (char *)cupsArrayPrev(array)) != NULL && + !strcmp(text, "Red Fish")) + puts("PASS"); + else + { + printf("FAIL (returned \"%s\", expected \"Red Fish\")\n", text); + status ++; + } + + /* + * cupsArrayFind() + */ + + fputs("cupsArrayFind: ", stdout); + if ((text = (char *)cupsArrayFind(array, (void *)"One Fish")) != NULL && + !strcmp(text, "One Fish")) + puts("PASS"); + else + { + printf("FAIL (returned \"%s\", expected \"One Fish\")\n", text); + status ++; + } + + /* + * cupsArrayCurrent() + */ + + fputs("cupsArrayCurrent: ", stdout); + if ((text = (char *)cupsArrayCurrent(array)) != NULL && + !strcmp(text, "One Fish")) + puts("PASS"); + else + { + printf("FAIL (returned \"%s\", expected \"One Fish\")\n", text); + status ++; + } + + /* + * cupsArrayDup() + */ + + fputs("cupsArrayDup: ", stdout); + if ((dup_array = cupsArrayDup(array)) != NULL && + cupsArrayCount(dup_array) == 4) + puts("PASS"); + else + { + printf("FAIL (returned %p with %d elements, expected pointer with 4 elements)\n", + dup_array, cupsArrayCount(dup_array)); + status ++; + } + + /* + * cupsArrayRemove() + */ + + fputs("cupsArrayRemove: ", stdout); + if (cupsArrayRemove(array, (void *)"One Fish") && + cupsArrayCount(array) == 3) + puts("PASS"); + else + { + printf("FAIL (returned 0 with %d elements, expected 1 with 4 elements)\n", + cupsArrayCount(array)); + status ++; + } + + /* + * cupsArrayClear() + */ + + fputs("cupsArrayClear: ", stdout); + cupsArrayClear(array); + if (cupsArrayCount(array) == 0) + puts("PASS"); + else + { + printf("FAIL (%d elements, expected 0 elements)\n", + cupsArrayCount(array)); + status ++; + } + + /* + * Now load this source file and grab all of the unique words... + */ + + fputs("Load unique words: ", stdout); + fflush(stdout); + + start = get_seconds(); + + if ((dir = cupsDirOpen(".")) == NULL) + { + puts("FAIL (cupsDirOpen failed)"); + status ++; + } + else + { + while ((dent = cupsDirRead(dir)) != NULL) + { + i = strlen(dent->filename) - 2; + + if (i > 0 && dent->filename[i] == '.' && + (dent->filename[i + 1] == 'c' || + dent->filename[i + 1] == 'h')) + load_words(dent->filename, array); + } + + cupsDirClose(dir); + + end = get_seconds(); + + printf("%d words in %.3f seconds (%.0f words/sec), ", cupsArrayCount(array), + end - start, cupsArrayCount(array) / (end - start)); + fflush(stdout); + + for (text = (char *)cupsArrayFirst(array); text;) + { + /* + * Copy this word to the word buffer (safe because we strdup'd from + * the same buffer in the first place... :) + */ + + strcpy(word, text); + + /* + * Grab the next word and compare... + */ + + if ((text = (char *)cupsArrayNext(array)) == NULL) + break; + + if (strcmp(word, text) >= 0) + break; + } + + if (text) + { + printf("FAIL (\"%s\" >= \"%s\"!)\n", word, text); + status ++; + } + else + puts("PASS"); + } + + /* + * Test deleting with iteration... + */ + + fputs("Delete While Iterating: ", stdout); + + text = (char *)cupsArrayFirst(array); + cupsArrayRemove(array, text); + free(text); + + text = (char *)cupsArrayNext(array); + if (!text) + { + puts("FAIL (cupsArrayNext returned NULL!)"); + status ++; + } + else + puts("PASS"); + + /* + * Test save/restore... + */ + + fputs("cupsArraySave: ", stdout); + + for (i = 0, text = (char *)cupsArrayFirst(array); + i < 32; + i ++, text = (char *)cupsArrayNext(array)) + { + saved[i] = text; + + if (!cupsArraySave(array)) + break; + } + + if (i < 32) + printf("FAIL (depth = %d)\n", i); + else + puts("PASS"); + + fputs("cupsArrayRestore: ", stdout); + + while (i > 0) + { + i --; + + text = cupsArrayRestore(array); + if (text != saved[i]) + break; + } + + if (i) + printf("FAIL (depth = %d)\n", i); + else + puts("PASS"); + + /* + * Delete the arrays... + */ + + cupsArrayDelete(array); + cupsArrayDelete(dup_array); + + /* + * Summarize the results and return... + */ + + if (!status) + puts("\nALL TESTS PASSED!"); + else + printf("\n%d TEST(S) FAILED!\n", status); + + return (status); +} + + +/* + * 'get_seconds()' - Get the current time in seconds... + */ + +#ifdef WIN32 +# include + + +static double +get_seconds(void) +{ +} +#else +# include + + +static double +get_seconds(void) +{ + struct timeval curtime; /* Current time */ + + + gettimeofday(&curtime, NULL); + return (curtime.tv_sec + 0.000001 * curtime.tv_usec); +} +#endif /* WIN32 */ + + +/* + * 'load_words()' - Load words from a file. + */ + +static int /* O - 1 on success, 0 on failure */ +load_words(const char *filename, /* I - File to load */ + cups_array_t *array) /* I - Array to add to */ +{ + FILE *fp; /* Test file */ + char word[256]; /* Word from file */ + + + if ((fp = fopen(filename, "r")) == NULL) + { + perror(filename); + return (0); + } + + while (fscanf(fp, "%255s", word) == 1) + { + if (!cupsArrayFind(array, word)) + cupsArrayAdd(array, strdup(word)); + } + + fclose(fp); + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testconflicts.c b/cups/testconflicts.c new file mode 100644 index 0000000000..0d7531bdbb --- /dev/null +++ b/cups/testconflicts.c @@ -0,0 +1,126 @@ +/* + * "$Id$" + * + * PPD constraint test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2008-2009 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include "string.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 */ + ppd_file_t *ppd; /* PPD file loaded from disk */ + char line[256], /* Input buffer */ + *ptr, /* Pointer into buffer */ + *optr, /* Pointer to first option name */ + *cptr; /* Pointer to first choice */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + char *option, /* Current option */ + *choice; /* Current choice */ + + + if (argc != 2) + { + puts("Usage: testconflicts filename.ppd"); + return (1); + } + + if ((ppd = ppdOpenFile(argv[1])) == NULL) + { + ppd_status_t err; /* Last error in file */ + int linenum; /* Line number in file */ + + err = ppdLastError(&linenum); + + printf("Unable to open PPD file \"%s\": %s on line %d\n", argv[1], + ppdErrorString(err), linenum); + return (1); + } + + ppdMarkDefaults(ppd); + + option = NULL; + choice = NULL; + + for (;;) + { + num_options = 0; + options = NULL; + + if (!cupsResolveConflicts(ppd, option, choice, &num_options, &options)) + puts("Unable to resolve conflicts!"); + else if ((!option && num_options > 0) || (option && num_options > 1)) + { + fputs("Resolved conflicts with the following options:\n ", stdout); + for (i = 0; i < num_options; i ++) + if (!option || strcasecmp(option, options[i].name)) + printf(" %s=%s", options[i].name, options[i].value); + putchar('\n'); + + cupsFreeOptions(num_options, options); + } + + if (option) + { + free(option); + free(choice); + } + + printf("\nNew Option(s): "); + fflush(stdout); + if (!fgets(line, sizeof(line), stdin) || line[0] == '\n') + break; + + for (ptr = line; isspace(*ptr & 255); ptr ++); + for (optr = ptr; *ptr && *ptr != '='; ptr ++); + if (!*ptr) + break; + for (*ptr++ = '\0', cptr = ptr; *ptr && !isspace(*ptr & 255); ptr ++); + if (!*ptr) + break; + *ptr++ = '\0'; + + option = strdup(optr); + choice = strdup(cptr); + num_options = cupsParseOptions(ptr, 0, &options); + + ppdMarkOption(ppd, option, choice); + if (cupsMarkOptions(ppd, num_options, options)) + puts("Options Conflict!"); + cupsFreeOptions(num_options, options); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testcups.c b/cups/testcups.c new file mode 100644 index 0000000000..555df69a51 --- /dev/null +++ b/cups/testcups.c @@ -0,0 +1,417 @@ +/* + * "$Id$" + * + * CUPS API test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * dests_equal() - Determine whether two destinations are equal. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include "cups.h" +#include "string.h" +#include + + +/* + * Local functions... + */ + +static int dests_equal(cups_dest_t *a, cups_dest_t *b); +static void show_diffs(cups_dest_t *a, cups_dest_t *b); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int status = 0, /* Exit status */ + i, /* Looping var */ + num_dests; /* Number of destinations */ + cups_dest_t *dests, /* Destinations */ + *dest, /* Current destination */ + *named_dest; /* Current named destination */ + const char *ppdfile; /* PPD file */ + ppd_file_t *ppd; /* PPD file data */ + int num_jobs; /* Number of jobs for queue */ + cups_job_t *jobs; /* Jobs for queue */ + + + if (argc > 1) + { + /* + * ./testcups printer file interval + */ + + int interval, /* Interval between writes */ + job_id; /* Job ID */ + cups_file_t *fp; /* Print file */ + char buffer[16384]; /* Read/write buffer */ + ssize_t bytes; /* Bytes read/written */ + + + if (argc != 4) + { + puts("Usage: ./testcups"); + puts(" ./testcups printer file interval"); + return (1); + } + + if ((fp = cupsFileOpen(argv[2], "r")) == NULL) + { + printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno)); + return (1); + } + + if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[1], "testcups", 0, + NULL)) <= 0) + { + printf("Unable to create print job on %s: %s\n", argv[1], + cupsLastErrorString()); + return (1); + } + + interval = atoi(argv[3]); + + if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2], + CUPS_FORMAT_AUTO, 1) != HTTP_CONTINUE) + { + puts("Unable to start document!"); + return (1); + } + + while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) + { + printf("Writing %d bytes...\n", (int)bytes); + + if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, + bytes) != HTTP_CONTINUE) + { + puts("Unable to write bytes!"); + return (1); + } + + sleep(interval); + } + + cupsFileClose(fp); + + if (cupsFinishDocument(CUPS_HTTP_DEFAULT, argv[1]) != HTTP_OK) + { + puts("Unable to finish document!"); + return (1); + } + + return (0); + } + + /* + * cupsGetDests() + */ + + fputs("cupsGetDests: ", stdout); + fflush(stdout); + + num_dests = cupsGetDests(&dests); + + if (num_dests == 0) + { + puts("FAIL"); + return (1); + } + else + { + printf("PASS (%d dests)\n", num_dests); + + for (i = num_dests, dest = dests; i > 0; i --, dest ++) + { + printf(" %s", dest->name); + + if (dest->instance) + printf(" /%s", dest->instance); + + if (dest->is_default) + puts(" ***DEFAULT***"); + else + putchar('\n'); + } + } + + /* + * cupsGetDest(NULL) + */ + + fputs("cupsGetDest(NULL): ", stdout); + fflush(stdout); + + if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) + { + for (i = num_dests, dest = dests; i > 0; i --, dest ++) + if (dest->is_default) + break; + + if (i) + { + status = 1; + puts("FAIL"); + } + else + puts("PASS (no default)"); + + dest = NULL; + } + else + printf("PASS (%s)\n", dest->name); + + /* + * cupsGetNamedDest(NULL, NULL, NULL) + */ + + fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout); + fflush(stdout); + + if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL || + !dests_equal(dest, named_dest)) + { + if (!dest) + puts("PASS (no default)"); + else if (named_dest) + { + puts("FAIL (different values)"); + show_diffs(dest, named_dest); + status = 1; + } + else + { + puts("FAIL (no default)"); + status = 1; + } + } + else + printf("PASS (%s)\n", named_dest->name); + + if (named_dest) + cupsFreeDests(1, named_dest); + + /* + * cupsGetDest(printer) + */ + + printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name); + fflush(stdout); + + if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests, + dests)) == NULL) + { + puts("FAIL"); + return (1); + } + else + puts("PASS"); + + /* + * cupsGetNamedDest(NULL, printer, instance) + */ + + printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name, + dest->instance ? dest->instance : "(null)"); + fflush(stdout); + + if ((named_dest = cupsGetNamedDest(NULL, dest->name, + dest->instance)) == NULL || + !dests_equal(dest, named_dest)) + { + if (named_dest) + { + puts("FAIL (different values)"); + show_diffs(dest, named_dest); + } + else + puts("FAIL (no destination)"); + + + status = 1; + } + else + puts("PASS"); + + if (named_dest) + cupsFreeDests(1, named_dest); + + /* + * cupsPrintFile() + */ + + fputs("cupsPrintFile: ", stdout); + fflush(stdout); + + if (cupsPrintFile(dest->name, "../data/testprint", "Test Page", + dest->num_options, dest->options) <= 0) + { + printf("FAIL (%s)\n", cupsLastErrorString()); + return (1); + } + else + puts("PASS"); + + /* + * cupsGetPPD(printer) + */ + + fputs("cupsGetPPD(): ", stdout); + fflush(stdout); + + if ((ppdfile = cupsGetPPD(dest->name)) == NULL) + { + puts("FAIL"); + } + else + { + puts("PASS"); + + /* + * ppdOpenFile() + */ + + fputs("ppdOpenFile(): ", stdout); + fflush(stdout); + + if ((ppd = ppdOpenFile(ppdfile)) == NULL) + { + puts("FAIL"); + return (1); + } + else + puts("PASS"); + + ppdClose(ppd); + unlink(ppdfile); + } + + /* + * cupsGetJobs() + */ + + fputs("cupsGetJobs: ", stdout); + fflush(stdout); + + num_jobs = cupsGetJobs(&jobs, NULL, 0, -1); + + if (num_jobs == 0) + { + puts("FAIL"); + return (1); + } + else + puts("PASS"); + + cupsFreeJobs(num_jobs, jobs); + cupsFreeDests(num_dests, dests); + + return (status); +} + + +/* + * 'dests_equal()' - Determine whether two destinations are equal. + */ + +static int /* O - 1 if equal, 0 if not equal */ +dests_equal(cups_dest_t *a, /* I - First destination */ + cups_dest_t *b) /* I - Second destination */ +{ + int i; /* Looping var */ + cups_option_t *aoption; /* Current option */ + const char *bval; /* Option value */ + + + if (a == b) + return (1); + + if (!a || !b) + return (0); + + if (strcasecmp(a->name, b->name) || + (a->instance && !b->instance) || + (!a->instance && b->instance) || + (a->instance && strcasecmp(a->instance, b->instance)) || + a->num_options != b->num_options) + return (0); + + for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++) + if ((bval = cupsGetOption(aoption->name, b->num_options, + b->options)) == NULL || + strcmp(aoption->value, bval)) + return (0); + + return (1); +} + + +/* + * 'show_diffs()' - Show differences between two destinations. + */ + +static void +show_diffs(cups_dest_t *a, /* I - First destination */ + cups_dest_t *b) /* I - Second destination */ +{ + int i; /* Looping var */ + cups_option_t *aoption; /* Current option */ + const char *bval; /* Option value */ + + + if (!a || !b) + return; + + puts(" Item cupsGetDest cupsGetNamedDest"); + puts(" -------------------- -------------------- --------------------"); + + if (strcasecmp(a->name, b->name)) + printf(" name %-20.20s %-20.20s\n", a->name, b->name); + + if ((a->instance && !b->instance) || + (!a->instance && b->instance) || + (a->instance && strcasecmp(a->instance, b->instance))) + printf(" instance %-20.20s %-20.20s\n", + a->instance ? a->instance : "(null)", + b->instance ? b->instance : "(null)"); + + if (a->num_options != b->num_options) + printf(" num_options %-20d %-20d\n", a->num_options, + b->num_options); + + for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++) + if ((bval = cupsGetOption(aoption->name, b->num_options, + b->options)) == NULL || + strcmp(aoption->value, bval)) + printf(" %-20.20s %-20.20s %-20.20s\n", aoption->name, + aoption->value, bval ? bval : "(null)"); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testfile.c b/cups/testfile.c new file mode 100644 index 0000000000..2869f28b0e --- /dev/null +++ b/cups/testfile.c @@ -0,0 +1,823 @@ +/* + * "$Id$" + * + * File test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * count_lines() - Count the number of lines in a file. + * random_tests() - Do random access tests. + * read_write_tests() - Perform read/write tests. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include "string.h" +#include "file.h" +#include "debug.h" +#ifdef HAVE_LIBZ +# include +#endif /* HAVE_LIBZ */ +#ifdef WIN32 +# include +#else +# include +#endif /* WIN32 */ +#include + + +/* + * Local functions... + */ + +static int count_lines(cups_file_t *fp); +static int random_tests(void); +static int read_write_tests(int compression); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int status; /* Exit status */ + char filename[1024]; /* Filename buffer */ + cups_file_t *fp; /* File pointer */ +#ifndef WIN32 + int fds[2]; /* Open file descriptors */ + cups_file_t *fdfile; /* File opened with cupsFileOpenFd() */ +#endif /* !WIN32 */ + int count; /* Number of lines in file */ + + + if (argc == 1) + { + /* + * Do uncompressed file tests... + */ + + status = read_write_tests(0); + +#ifdef HAVE_LIBZ + /* + * Do compressed file tests... + */ + + putchar('\n'); + + status += read_write_tests(1); +#endif /* HAVE_LIBZ */ + + /* + * Do uncompressed random I/O tests... + */ + + status += random_tests(); + +#ifndef WIN32 + /* + * Test fdopen and close without reading... + */ + + pipe(fds); + close(fds[1]); + + fputs("\ncupsFileOpenFd(fd, \"r\"): ", stdout); + fflush(stdout); + + if ((fdfile = cupsFileOpenFd(fds[0], "r")) == NULL) + { + puts("FAIL"); + status ++; + } + else + { + /* + * Able to open file, now close without reading. If we don't return + * before the alarm fires, that is a failure and we will crash on the + * alarm signal... + */ + + puts("PASS"); + fputs("cupsFileClose(no read): ", stdout); + fflush(stdout); + + alarm(5); + cupsFileClose(fdfile); + alarm(0); + + puts("PASS"); + } +#endif /* !WIN32 */ + + /* + * Count lines in euc-jp.txt, rewind, then count again. + */ + + fputs("\ncupsFileOpen(\"../data/euc-jp.txt\", \"r\"): ", stdout); + + if ((fp = cupsFileOpen("../data/euc-jp.txt", "r")) == NULL) + { + puts("FAIL"); + status ++; + } + else + { + puts("PASS"); + fputs("cupsFileGets: ", stdout); + + if ((count = count_lines(fp)) != 15184) + { + printf("FAIL (got %d lines, expected 15184)\n", count); + status ++; + } + else + { + puts("PASS"); + fputs("cupsFileRewind: ", stdout); + + if (cupsFileRewind(fp) != 0) + { + puts("FAIL"); + status ++; + } + else + { + puts("PASS"); + fputs("cupsFileGets: ", stdout); + + if ((count = count_lines(fp)) != 15184) + { + printf("FAIL (got %d lines, expected 15184)\n", count); + status ++; + } + else + puts("PASS"); + } + } + + cupsFileClose(fp); + } + + /* + * Test path functions... + */ + + fputs("\ncupsFileFind: ", stdout); +#ifdef WIN32 + if (cupsFileFind("notepad.exe", "C:/WINDOWS", 1, filename, sizeof(filename)) && + cupsFileFind("notepad.exe", "C:/WINDOWS;C:/WINDOWS/SYSTEM32", 1, filename, sizeof(filename))) +#else + if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) && + cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename))) +#endif /* WIN32 */ + printf("PASS (%s)\n", filename); + else + { + puts("FAIL"); + status ++; + } + + /* + * Summarize the results and return... + */ + + if (!status) + puts("\nALL TESTS PASSED!"); + else + printf("\n%d TEST(S) FAILED!\n", status); + } + else + { + /* + * Cat the filename on the command-line... + */ + + char line[1024]; /* Line from file */ + + if ((fp = cupsFileOpen(argv[1], "r")) == NULL) + { + perror(argv[1]); + status = 1; + } + else + { + status = 0; + + while (cupsFileGets(fp, line, sizeof(line))) + puts(line); + + if (!cupsFileEOF(fp)) + perror(argv[1]); + + cupsFileClose(fp); + } + } + + return (status); +} + + +/* + * 'count_lines()' - Count the number of lines in a file. + */ + +static int /* O - Number of lines */ +count_lines(cups_file_t *fp) /* I - File to read from */ +{ + int count; /* Number of lines */ + char line[1024]; /* Line buffer */ + + + for (count = 0; cupsFileGets(fp, line, sizeof(line)); count ++); + + return (count); +} + + +/* + * 'random_tests()' - Do random access tests. + */ + +static int /* O - Status */ +random_tests(void) +{ + int status, /* Status of tests */ + pass, /* Current pass */ + count, /* Number of records read */ + record, /* Current record */ + num_records; /* Number of records */ + ssize_t pos, /* Position in file */ + expected; /* Expected position in file */ + cups_file_t *fp; /* File */ + char buffer[512]; /* Data buffer */ + + + /* + * Run 4 passes, each time appending to a data file and then reopening the + * file for reading to validate random records in the file. + */ + + for (status = 0, pass = 0; pass < 4; pass ++) + { + /* + * cupsFileOpen(append) + */ + + printf("\ncupsFileOpen(append %d): ", pass); + + if ((fp = cupsFileOpen("testfile.dat", "a")) == NULL) + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + break; + } + else + puts("PASS"); + + /* + * cupsFileTell() + */ + + expected = 256 * sizeof(buffer) * pass; + + fputs("cupsFileTell(): ", stdout); + if ((pos = cupsFileTell(fp)) != expected) + { + printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n", + CUPS_LLCAST pos, CUPS_LLCAST expected); + status ++; + break; + } + else + puts("PASS"); + + /* + * cupsFileWrite() + */ + + fputs("cupsFileWrite(256 512-byte records): ", stdout); + for (record = 0; record < 256; record ++) + { + memset(buffer, record, sizeof(buffer)); + if (cupsFileWrite(fp, buffer, sizeof(buffer)) < sizeof(buffer)) + break; + } + + if (record < 256) + { + printf("FAIL (%d: %s)\n", record, strerror(errno)); + status ++; + break; + } + else + puts("PASS"); + + /* + * cupsFileTell() + */ + + expected += 256 * sizeof(buffer); + + fputs("cupsFileTell(): ", stdout); + if ((pos = cupsFileTell(fp)) != expected) + { + printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n", + CUPS_LLCAST pos, CUPS_LLCAST expected); + status ++; + break; + } + else + puts("PASS"); + + cupsFileClose(fp); + + /* + * cupsFileOpen(read) + */ + + printf("\ncupsFileOpen(read %d): ", pass); + + if ((fp = cupsFileOpen("testfile.dat", "r")) == NULL) + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + break; + } + else + puts("PASS"); + + /* + * cupsFileSeek, cupsFileRead + */ + + fputs("cupsFileSeek(), cupsFileRead(): ", stdout); + + for (num_records = (pass + 1) * 256, count = (pass + 1) * 256, + record = CUPS_RAND() % num_records; + count > 0; + count --, record = (record + (CUPS_RAND() & 31) - 16 + num_records) % + num_records) + { + /* + * The last record is always the first... + */ + + if (count == 1) + record = 0; + + /* + * Try reading the data for the specified record, and validate the + * contents... + */ + + expected = sizeof(buffer) * record; + + if ((pos = cupsFileSeek(fp, expected)) != expected) + { + printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n", + CUPS_LLCAST pos, CUPS_LLCAST expected); + status ++; + break; + } + else + { + if (cupsFileRead(fp, buffer, sizeof(buffer)) != sizeof(buffer)) + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + break; + } + else if ((buffer[0] & 255) != (record & 255) || + memcmp(buffer, buffer + 1, sizeof(buffer) - 1)) + { + printf("FAIL (Bad Data - %d instead of %d)\n", buffer[0] & 255, + record & 255); + status ++; + break; + } + } + } + + if (count == 0) + puts("PASS"); + + cupsFileClose(fp); + } + + /* + * Remove the test file... + */ + + unlink("testfile.dat"); + + /* + * Return the test status... + */ + + return (status); +} + + +/* + * 'read_write_tests()' - Perform read/write tests. + */ + +static int /* O - Status */ +read_write_tests(int compression) /* I - Use compression? */ +{ + int i; /* Looping var */ + cups_file_t *fp; /* File */ + int status; /* Exit status */ + char line[1024], /* Line from file */ + *value; /* Directive value from line */ + int linenum; /* Line number */ + unsigned char readbuf[8192], /* Read buffer */ + writebuf[8192]; /* Write buffer */ + int byte; /* Byte from file */ + off_t length; /* Length of file */ + static const char *partial_line = "partial line"; + /* Partial line */ + + + /* + * No errors so far... + */ + + status = 0; + + /* + * Initialize the write buffer with random data... + */ + + CUPS_SRAND(time(NULL)); + + for (i = 0; i < (int)sizeof(writebuf); i ++) + writebuf[i] = CUPS_RAND(); + + /* + * cupsFileOpen(write) + */ + + printf("cupsFileOpen(write%s): ", compression ? " compressed" : ""); + + fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", + compression ? "w9" : "w"); + if (fp) + { + puts("PASS"); + + /* + * cupsFileCompression() + */ + + fputs("cupsFileCompression(): ", stdout); + + if (cupsFileCompression(fp) == compression) + puts("PASS"); + else + { + printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp), + compression); + status ++; + } + + /* + * cupsFilePuts() + */ + + fputs("cupsFilePuts(): ", stdout); + + if (cupsFilePuts(fp, "# Hello, World\n") > 0) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFilePrintf() + */ + + fputs("cupsFilePrintf(): ", stdout); + + for (i = 0; i < 1000; i ++) + if (cupsFilePrintf(fp, "TestLine %03d\n", i) < 0) + break; + + if (i >= 1000) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFilePutChar() + */ + + fputs("cupsFilePutChar(): ", stdout); + + for (i = 0; i < 256; i ++) + if (cupsFilePutChar(fp, i) < 0) + break; + + if (i >= 256) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileWrite() + */ + + fputs("cupsFileWrite(): ", stdout); + + for (i = 0; i < 10000; i ++) + if (cupsFileWrite(fp, (char *)writebuf, sizeof(writebuf)) < 0) + break; + + if (i >= 10000) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFilePuts() with partial line... + */ + + fputs("cupsFilePuts(\"partial line\"): ", stdout); + + if (cupsFilePuts(fp, partial_line) > 0) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileTell() + */ + + fputs("cupsFileTell(): ", stdout); + + if ((length = cupsFileTell(fp)) == 81933283) + puts("PASS"); + else + { + printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length); + status ++; + } + + /* + * cupsFileClose() + */ + + fputs("cupsFileClose(): ", stdout); + + if (!cupsFileClose(fp)) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + } + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileOpen(read) + */ + + fputs("\ncupsFileOpen(read): ", stdout); + + fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", "r"); + if (fp) + { + puts("PASS"); + + /* + * cupsFileGets() + */ + + fputs("cupsFileGets(): ", stdout); + + if (cupsFileGets(fp, line, sizeof(line))) + { + if (line[0] == '#') + puts("PASS"); + else + { + printf("FAIL (Got line \"%s\", expected comment line)\n", line); + status ++; + } + } + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileCompression() + */ + + fputs("cupsFileCompression(): ", stdout); + + if (cupsFileCompression(fp) == compression) + puts("PASS"); + else + { + printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp), + compression); + status ++; + } + + /* + * cupsFileGetConf() + */ + + linenum = 1; + + fputs("cupsFileGetConf(): ", stdout); + + for (i = 0; i < 1000; i ++) + if (!cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + break; + else if (strcasecmp(line, "TestLine") || !value || atoi(value) != i || + linenum != (i + 2)) + break; + + if (i >= 1000) + puts("PASS"); + else if (line[0]) + { + printf("FAIL (Line %d, directive \"%s\", value \"%s\")\n", linenum, + line, value ? value : "(null)"); + status ++; + } + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileGetChar() + */ + + fputs("cupsFileGetChar(): ", stdout); + + for (i = 0; i < 256; i ++) + if ((byte = cupsFileGetChar(fp)) != i) + break; + + if (i >= 256) + puts("PASS"); + else if (byte >= 0) + { + printf("FAIL (Got %d, expected %d)\n", byte, i); + status ++; + } + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileRead() + */ + + fputs("cupsFileRead(): ", stdout); + + for (i = 0; i < 10000; i ++) + if ((byte = cupsFileRead(fp, (char *)readbuf, sizeof(readbuf))) < 0) + break; + else if (memcmp(readbuf, writebuf, sizeof(readbuf))) + break; + + if (i >= 10000) + puts("PASS"); + else if (byte > 0) + { + printf("FAIL (Pass %d, ", i); + + for (i = 0; i < (int)sizeof(readbuf); i ++) + if (readbuf[i] != writebuf[i]) + break; + + printf("match failed at offset %d - got %02X, expected %02X)\n", + i, readbuf[i], writebuf[i]); + } + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * cupsFileGetChar() with partial line... + */ + + fputs("cupsFileGetChar(partial line): ", stdout); + + for (i = 0; i < (int)strlen(partial_line); i ++) + if ((byte = cupsFileGetChar(fp)) < 0) + break; + else if (byte != partial_line[i]) + break; + + if (!partial_line[i]) + puts("PASS"); + else + { + printf("FAIL (got '%c', expected '%c')\n", byte, partial_line[i]); + status ++; + } + + /* + * cupsFileTell() + */ + + fputs("cupsFileTell(): ", stdout); + + if ((length = cupsFileTell(fp)) == 81933283) + puts("PASS"); + else + { + printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length); + status ++; + } + + /* + * cupsFileClose() + */ + + fputs("cupsFileClose(): ", stdout); + + if (!cupsFileClose(fp)) + puts("PASS"); + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + } + else + { + printf("FAIL (%s)\n", strerror(errno)); + status ++; + } + + /* + * Remove the test file... + */ + + unlink(compression ? "testfile.dat.gz" : "testfile.dat"); + + /* + * Return the test status... + */ + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testhttp.c b/cups/testhttp.c new file mode 100644 index 0000000000..9530d346dd --- /dev/null +++ b/cups/testhttp.c @@ -0,0 +1,576 @@ +/* + * "$Id$" + * + * HTTP test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include "http-private.h" +#include "string.h" + + +/* + * Types and structures... + */ + +typedef struct uri_test_s /**** URI test cases ****/ +{ + http_uri_status_t result; /* Expected return value */ + const char *uri, /* URI */ + *scheme, /* Scheme string */ + *username, /* Username:password string */ + *hostname, /* Hostname string */ + *resource; /* Resource string */ + int port, /* Port number */ + assemble_port; /* Port number for httpAssembleURI() */ +} uri_test_t; + + +/* + * Local globals... + */ + +static uri_test_t uri_tests[] = /* URI test data */ + { + /* Start with valid URIs */ + { HTTP_URI_OK, "file:/filename", + "file", "", "", "/filename", 0, 0 }, + { HTTP_URI_OK, "file:/filename%20with%20spaces", + "file", "", "", "/filename with spaces", 0, 0 }, + { HTTP_URI_OK, "file:///filename", + "file", "", "", "/filename", 0, 0 }, + { HTTP_URI_OK, "file:///filename%20with%20spaces", + "file", "", "", "/filename with spaces", 0, 0 }, + { HTTP_URI_OK, "file://localhost/filename", + "file", "", "localhost", "/filename", 0, 0 }, + { HTTP_URI_OK, "file://localhost/filename%20with%20spaces", + "file", "", "localhost", "/filename with spaces", 0, 0 }, + { HTTP_URI_OK, "http://server/", + "http", "", "server", "/", 80, 0 }, + { HTTP_URI_OK, "http://username@server/", + "http", "username", "server", "/", 80, 0 }, + { HTTP_URI_OK, "http://username:passwor%64@server/", + "http", "username:password", "server", "/", 80, 0 }, + { HTTP_URI_OK, "http://username:passwor%64@server:8080/", + "http", "username:password", "server", "/", 8080, 8080 }, + { HTTP_URI_OK, "http://username:passwor%64@server:8080/directory/filename", + "http", "username:password", "server", "/directory/filename", 8080, 8080 }, + { HTTP_URI_OK, "http://[2000::10:100]:631/ipp", + "http", "", "2000::10:100", "/ipp", 631, 631 }, + { HTTP_URI_OK, "https://username:passwor%64@server/directory/filename", + "https", "username:password", "server", "/directory/filename", 443, 0 }, + { HTTP_URI_OK, "ipp://username:passwor%64@[::1]/ipp", + "ipp", "username:password", "::1", "/ipp", 631, 0 }, + { HTTP_URI_OK, "lpd://server/queue?reserve=yes", + "lpd", "", "server", "/queue?reserve=yes", 515, 0 }, + { HTTP_URI_OK, "mailto:user@domain.com", + "mailto", "", "", "user@domain.com", 0, 0 }, + { HTTP_URI_OK, "socket://server/", + "socket", "", "server", "/", 9100, 0 }, + { HTTP_URI_OK, "socket://192.168.1.1:9101/", + "socket", "", "192.168.1.1", "/", 9101, 9101 }, + { HTTP_URI_OK, "ipp://username:password@[v1.fe80::200:1234:5678:9abc+eth0]:999/ipp", + "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999 }, + { HTTP_URI_OK, "http://server/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", + "http", "", "server", "/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", 80, 0 }, + { HTTP_URI_OK, "lpd://Acme%20Laser%20(01%3A23%3A45).local._tcp._printer/", + "lpd", "", "Acme Laser (01:23:45).local._tcp._printer", "/", 515, 0 }, + + /* Missing scheme */ + { HTTP_URI_MISSING_SCHEME, "/path/to/file/index.html", + "file", "", "", "/path/to/file/index.html", 0, 0 }, + { HTTP_URI_MISSING_SCHEME, "//server/ipp", + "ipp", "", "server", "/ipp", 631, 0 }, + + /* Unknown scheme */ + { HTTP_URI_UNKNOWN_SCHEME, "vendor://server/resource", + "vendor", "", "server", "/resource", 0, 0 }, + + /* Missing resource */ + { HTTP_URI_MISSING_RESOURCE, "socket://[::192.168.2.1]", + "socket", "", "::192.168.2.1", "/", 9100, 0 }, + { HTTP_URI_MISSING_RESOURCE, "socket://192.168.1.1:9101", + "socket", "", "192.168.1.1", "/", 9101 }, + + /* Bad URI */ + { HTTP_URI_BAD_URI, "", + "", "", "", "", 0, 0 }, + + /* Bad scheme */ + { HTTP_URI_BAD_SCHEME, "bad_scheme://server/resource", + "", "", "", "", 0, 0 }, + + /* Bad username */ + { HTTP_URI_BAD_USERNAME, "http://username:passwor%6@server/resource", + "http", "", "", "", 80, 0 }, + + /* Bad hostname */ + { HTTP_URI_BAD_HOSTNAME, "http://[/::1]/index.html", + "http", "", "", "", 80, 0 }, + { HTTP_URI_BAD_HOSTNAME, "http://[", + "http", "", "", "", 80, 0 }, + { HTTP_URI_BAD_HOSTNAME, "http://serve%7/index.html", + "http", "", "", "", 80, 0 }, + + /* Bad port number */ + { HTTP_URI_BAD_PORT, "http://127.0.0.1:9999a/index.html", + "http", "", "127.0.0.1", "", 0, 0 }, + + /* Bad resource */ + { HTTP_URI_BAD_RESOURCE, "http://server/index.html%", + "http", "", "server", "", 80, 0 } + }; +static const char * const base64_tests[][2] = + { + { "A", "QQ==" }, + /* 010000 01 */ + { "AB", "QUI=" }, + /* 010000 010100 0010 */ + { "ABC", "QUJD" }, + /* 010000 010100 001001 000011 */ + { "ABCD", "QUJDRA==" }, + /* 010000 010100 001001 000011 010001 00 */ + { "ABCDE", "QUJDREU=" }, + /* 010000 010100 001001 000011 010001 000100 0101 */ + { "ABCDEF", "QUJDREVG" }, + /* 010000 010100 001001 000011 010001 000100 010101 000110 */ + }; + + +/* + * '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, k; /* Looping vars */ + http_t *http; /* HTTP connection */ + http_status_t status; /* Status of GET command */ + int failures; /* Number of test failures */ + char buffer[8192]; /* Input buffer */ + long bytes; /* Number of bytes read */ + FILE *out; /* Output file */ + char encode[256], /* Base64-encoded string */ + decode[256]; /* Base64-decoded string */ + int decodelen; /* Length of decoded string */ + char scheme[HTTP_MAX_URI], /* Scheme from URI */ + hostname[HTTP_MAX_URI], /* Hostname from URI */ + username[HTTP_MAX_URI], /* Username:password from URI */ + resource[HTTP_MAX_URI]; /* Resource from URI */ + int port; /* Port number from URI */ + http_uri_status_t uri_status; /* Status of URI separation */ + http_addrlist_t *addrlist, /* Address list */ + *addr; /* Current address */ + off_t length, total; /* Length and total bytes */ + time_t start, current; /* Start and end time */ + static const char * const uri_status_strings[] = + { + "HTTP_URI_OVERFLOW", + "HTTP_URI_BAD_ARGUMENTS", + "HTTP_URI_BAD_RESOURCE", + "HTTP_URI_BAD_PORT", + "HTTP_URI_BAD_HOSTNAME", + "HTTP_URI_BAD_USERNAME", + "HTTP_URI_BAD_SCHEME", + "HTTP_URI_BAD_URI", + "HTTP_URI_OK", + "HTTP_URI_MISSING_SCHEME", + "HTTP_URI_UNKNOWN_SCHEME", + "HTTP_URI_MISSING_RESOURCE" + }; + + + /* + * Do API tests if we don't have a URL on the command-line... + */ + + if (argc == 1) + { + failures = 0; + + /* + * httpGetDateString()/httpGetDateTime() + */ + + fputs("httpGetDateString()/httpGetDateTime(): ", stdout); + + start = time(NULL); + strcpy(buffer, httpGetDateString(start)); + current = httpGetDateTime(buffer); + + i = (int)(current - start); + if (i < 0) + i = -i; + + if (!i) + puts("PASS"); + else + { + failures ++; + puts("FAIL"); + printf(" Difference is %d seconds, %02d:%02d:%02d...\n", i, i / 3600, + (i / 60) % 60, i % 60); + printf(" httpGetDateString(%d) returned \"%s\"\n", (int)start, buffer); + printf(" httpGetDateTime(\"%s\") returned %d\n", buffer, (int)current); + printf(" httpGetDateString(%d) returned \"%s\"\n", (int)current, + httpGetDateString(current)); + } + + /* + * httpDecode64_2()/httpEncode64_2() + */ + + fputs("httpDecode64_2()/httpEncode64_2(): ", stdout); + + for (i = 0, j = 0; i < (int)(sizeof(base64_tests) / sizeof(base64_tests[0])); i ++) + { + httpEncode64_2(encode, sizeof(encode), base64_tests[i][0], + (int)strlen(base64_tests[i][0])); + decodelen = (int)sizeof(decode); + httpDecode64_2(decode, &decodelen, base64_tests[i][1]); + + if (strcmp(decode, base64_tests[i][0])) + { + failures ++; + + if (j) + { + puts("FAIL"); + j = 1; + } + + printf(" httpDecode64_2() returned \"%s\", expected \"%s\"...\n", + decode, base64_tests[i][0]); + } + + if (strcmp(encode, base64_tests[i][1])) + { + failures ++; + + if (j) + { + puts("FAIL"); + j = 1; + } + + printf(" httpEncode64_2() returned \"%s\", expected \"%s\"...\n", + encode, base64_tests[i][1]); + } + } + + if (!j) + puts("PASS"); + + /* + * httpGetHostname() + */ + + fputs("httpGetHostname(): ", stdout); + + if (httpGetHostname(NULL, hostname, sizeof(hostname))) + printf("PASS (%s)\n", hostname); + else + { + failures ++; + puts("FAIL"); + } + + /* + * httpAddrGetList() + */ + + printf("httpAddrGetList(%s): ", hostname); + + addrlist = httpAddrGetList(hostname, AF_UNSPEC, NULL); + if (addrlist) + { + for (i = 0, addr = addrlist; addr; i ++, addr = addr->next) + { + char numeric[1024]; /* Numeric IP address */ + + + httpAddrString(&(addr->addr), numeric, sizeof(numeric)); + if (!strcmp(numeric, "UNKNOWN")) + break; + } + + if (addr) + printf("FAIL (bad address for %s)\n", hostname); + else + printf("PASS (%d address(es) for %s)\n", i, hostname); + + httpAddrFreeList(addrlist); + } + else if (isdigit(hostname[0] & 255)) + { + puts("FAIL (ignored because hostname is numeric)"); + } + else + { + failures ++; + puts("FAIL"); + } + + /* + * Test httpSeparateURI()... + */ + + fputs("httpSeparateURI(): ", stdout); + for (i = 0, j = 0; i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); i ++) + { + uri_status = httpSeparateURI(HTTP_URI_CODING_MOST, + uri_tests[i].uri, scheme, sizeof(scheme), + username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + if (uri_status != uri_tests[i].result || + strcmp(scheme, uri_tests[i].scheme) || + strcmp(username, uri_tests[i].username) || + strcmp(hostname, uri_tests[i].hostname) || + port != uri_tests[i].port || + strcmp(resource, uri_tests[i].resource)) + { + failures ++; + + if (!j) + { + puts("FAIL"); + j = 1; + } + + printf(" \"%s\":\n", uri_tests[i].uri); + + if (uri_status != uri_tests[i].result) + printf(" Returned %s instead of %s\n", + uri_status_strings[uri_status + 8], + uri_status_strings[uri_tests[i].result + 8]); + + if (strcmp(scheme, uri_tests[i].scheme)) + printf(" Scheme \"%s\" instead of \"%s\"\n", + scheme, uri_tests[i].scheme); + + if (strcmp(username, uri_tests[i].username)) + printf(" Username \"%s\" instead of \"%s\"\n", + username, uri_tests[i].username); + + if (strcmp(hostname, uri_tests[i].hostname)) + printf(" Hostname \"%s\" instead of \"%s\"\n", + hostname, uri_tests[i].hostname); + + if (port != uri_tests[i].port) + printf(" Port %d instead of %d\n", + port, uri_tests[i].port); + + if (strcmp(resource, uri_tests[i].resource)) + printf(" Resource \"%s\" instead of \"%s\"\n", + resource, uri_tests[i].resource); + } + } + + if (!j) + printf("PASS (%d URIs tested)\n", + (int)(sizeof(uri_tests) / sizeof(uri_tests[0]))); + + /* + * Test httpAssembleURI()... + */ + + fputs("httpAssembleURI(): ", stdout); + for (i = 0, j = 0, k = 0; + i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); + i ++) + if (uri_tests[i].result == HTTP_URI_OK && + !strstr(uri_tests[i].uri, "%64") && + strstr(uri_tests[i].uri, "//")) + { + k ++; + uri_status = httpAssembleURI(HTTP_URI_CODING_MOST, + buffer, sizeof(buffer), + uri_tests[i].scheme, + uri_tests[i].username, + uri_tests[i].hostname, + uri_tests[i].assemble_port, + uri_tests[i].resource); + + if (uri_status != HTTP_URI_OK) + { + failures ++; + + if (!j) + { + puts("FAIL"); + j = 1; + } + + printf(" \"%s\": %s\n", uri_tests[i].uri, + uri_status_strings[uri_status + 8]); + } + else if (strcmp(buffer, uri_tests[i].uri)) + { + failures ++; + + if (!j) + { + puts("FAIL"); + j = 1; + } + + printf(" \"%s\": assembled = \"%s\"\n", uri_tests[i].uri, + buffer); + } + } + + if (!j) + printf("PASS (%d URIs tested)\n", k); + + /* + * Show a summary and return... + */ + + if (failures) + printf("\n%d TESTS FAILED!\n", failures); + else + puts("\nALL TESTS PASSED!"); + + return (failures); + } + else if (strstr(argv[1], "._tcp")) + { + /* + * Test resolving an mDNS name. + */ + + char resolved[1024]; /* Resolved URI */ + + + printf("_httpResolveURI(%s): ", argv[1]); + fflush(stdout); + + if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 1)) + { + puts("FAIL"); + return (1); + } + else + { + printf("PASS (%s)\n", resolved); + return (0); + } + } + else if (!strcmp(argv[1], "-u") && argc == 3) + { + /* + * Test URI separation... + */ + + uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, argv[2], scheme, + sizeof(scheme), username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + printf("uri_status = %s\n", uri_status_strings[uri_status + 8]); + printf("scheme = \"%s\"\n", scheme); + printf("username = \"%s\"\n", username); + printf("hostname = \"%s\"\n", hostname); + printf("port = %d\n", port); + printf("resource = \"%s\"\n", resource); + + return (0); + } + + /* + * Test HTTP GET requests... + */ + + http = NULL; + out = stdout; + + for (i = 1; i < argc; i ++) + { + if (!strcmp(argv[i], "-o")) + { + i ++; + if (i >= argc) + break; + + out = fopen(argv[i], "wb"); + continue; + } + + httpSeparateURI(HTTP_URI_CODING_MOST, argv[i], scheme, sizeof(scheme), + username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + http = httpConnectEncrypt(hostname, port, HTTP_ENCRYPT_IF_REQUESTED); + if (http == NULL) + { + perror(hostname); + 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 = httpGetLength2(http); + total = 0; + + while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0) + { + total += bytes; + fwrite(buffer, bytes, 1, out); + if (out != stdout) + { + current = time(NULL); + if (current == start) current ++; + printf("\r" CUPS_LLFMT "/" CUPS_LLFMT " bytes (" + CUPS_LLFMT " bytes/sec) ", CUPS_LLCAST total, + CUPS_LLCAST length, CUPS_LLCAST (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/testi18n.c b/cups/testi18n.c new file mode 100644 index 0000000000..33b541f2aa --- /dev/null +++ b/cups/testi18n.c @@ -0,0 +1,686 @@ +/* + * "$Id$" + * + * Internationalization test for Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry for internationalization test module. + * print_utf8() - Print UTF-8 string with (optional) message. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include + +#include "i18n.h" +#include "string.h" + + +/* + * Local globals... + */ + +static const char * const 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", "iso-8859-11", + "iso-8859-16", "mac-roman", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "windows-932", "windows-936", + "windows-949", "windows-950", + "windows-1361", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "unknown", "unknown", + "euc-cn", "euc-jp", + "euc-kr", "euc-tw", + "jis-x0213" + }; + + +/* + * Local functions... + */ + +static void print_utf8(const char *msg, const cups_utf8_t *src); + + +/* + * 'main()' - Main entry for internationalization test module. + */ + +int /* O - Exit code */ +main(int argc, /* I - Argument Count */ + char *argv[]) /* I - Arguments */ +{ + FILE *fp; /* File pointer */ + int count; /* File line counter */ + int status, /* Status of current test */ + errors; /* Error count */ + char line[1024]; /* File line source string */ + int len; /* Length (count) of string */ + char legsrc[1024], /* Legacy source string */ + legdest[1024], /* Legacy destination string */ + *legptr; /* Pointer into legacy string */ + cups_utf8_t utf8latin[] = /* UTF-8 Latin-1 source */ + { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xC3, 0x84, 0x2E, 0x00 }; + /* "A != ." - use ISO 8859-1 */ + cups_utf8_t utf8repla[] = /* UTF-8 Latin-1 replacement */ + { 0x41, 0x20, 0xE2, 0x89, 0xA2, 0x20, 0xC3, 0x84, 0x2E, 0x00 }; + /* "A ." */ + cups_utf8_t utf8greek[] = /* UTF-8 Greek source string */ + { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xCE, 0x91, 0x2E, 0x00 }; + /* "A != ." - use ISO 8859-7 */ + cups_utf8_t utf8japan[] = /* UTF-8 Japanese source */ + { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xEE, 0x9C, 0x80, 0x2E, 0x00 }; + /* "A != ." - use Windows 932 or EUC-JP */ + cups_utf8_t utf8taiwan[] = /* UTF-8 Chinese source */ + { 0x41, 0x20, 0x21, 0x3D, 0x20, 0xE4, 0xB9, 0x82, 0x2E, 0x00 }; + /* "A != ." - use Windows 950 (Big5) or EUC-TW */ + cups_utf8_t utf8dest[1024]; /* UTF-8 destination string */ + cups_utf32_t utf32dest[1024]; /* UTF-32 destination string */ + + + if (argc > 1) + { + int i; /* Looping var */ + cups_encoding_t encoding; /* Source encoding */ + + + if (argc != 3) + { + puts("Usage: ./testi18n [filename charset]"); + return (1); + } + + if ((fp = fopen(argv[1], "rb")) == NULL) + { + perror(argv[1]); + return (1); + } + + for (i = 0, encoding = CUPS_AUTO_ENCODING; + i < (int)(sizeof(lang_encodings) / sizeof(lang_encodings[0])); + i ++) + if (!strcasecmp(lang_encodings[i], argv[2])) + { + encoding = (cups_encoding_t)i; + break; + } + + if (encoding == CUPS_AUTO_ENCODING) + { + fprintf(stderr, "%s: Unknown character set!\n", argv[2]); + return (1); + } + + while (fgets(line, sizeof(line), fp)) + { + if (cupsCharsetToUTF8(utf8dest, line, sizeof(utf8dest), encoding) < 0) + { + fprintf(stderr, "%s: Unable to convert line: %s", argv[1], line); + return (1); + } + + fputs((char *)utf8dest, stdout); + } + + fclose(fp); + return (0); + } + + /* + * Make sure we have a symbolic link from the data directory to a + * "charmaps" directory, and then point the library at it... + */ + + if (access("charmaps", 0)) + symlink("../data", "charmaps"); + + putenv("CUPS_DATADIR=."); + + /* + * Start with some conversion tests from a UTF-8 test file. + */ + + errors = 0; + + if ((fp = fopen("utf8demo.txt", "rb")) == NULL) + { + perror("utf8demo.txt"); + return (1); + } + + /* + * cupsUTF8ToUTF32 + */ + + fputs("cupsUTF8ToUTF32 of utfdemo.txt: ", stdout); + + for (count = 0, status = 0; fgets(line, sizeof(line), fp);) + { + count ++; + + if (cupsUTF8ToUTF32(utf32dest, (cups_utf8_t *)line, 1024) < 0) + { + printf("FAIL (UTF-8 to UTF-32 on line %d)\n", count); + errors ++; + status = 1; + break; + } + } + + if (!status) + puts("PASS"); + + /* + * cupsUTF8ToCharset(CUPS_EUC_JP) + */ + + fputs("cupsUTF8ToCharset(CUPS_EUC_JP) of utfdemo.txt: ", stdout); + + rewind(fp); + + for (count = 0, status = 0; fgets(line, sizeof(line), fp);) + { + count ++; + + len = cupsUTF8ToCharset(legdest, (cups_utf8_t *)line, 1024, CUPS_EUC_JP); + if (len < 0) + { + printf("FAIL (UTF-8 to EUC-JP on line %d)\n", count); + errors ++; + status = 1; + break; + } + } + + if (!status) + puts("PASS"); + + fclose(fp); + + /* + * Test charmap load for ISO-8859-1... + */ + + fputs("_cupsCharmapGet(CUPS_ISO8859_1): ", stdout); + + if (!_cupsCharmapGet(CUPS_ISO8859_1)) + { + errors ++; + puts("FAIL"); + } + else + puts("PASS"); + + /* + * Test charmap load for Windows-932 (Shift-JIS)... + */ + + fputs("_cupsCharmapGet(CUPS_WINDOWS_932): ", stdout); + + if (!_cupsCharmapGet(CUPS_WINDOWS_932)) + { + errors ++; + puts("FAIL"); + } + else + puts("PASS"); + + /* + * Test VBCS charmap load for EUC-JP... + */ + + fputs("_cupsCharmapGet(CUPS_EUC_JP): ", stdout); + + if (!_cupsCharmapGet(CUPS_EUC_JP)) + { + errors ++; + puts("FAIL"); + } + else + puts("PASS"); + + /* + * Test VBCS charmap load for EUC-TW... + */ + + fputs("_cupsCharmapGet(CUPS_EUC_TW): ", stdout); + + if (!_cupsCharmapGet(CUPS_EUC_TW)) + { + errors ++; + puts("FAIL"); + } + else + puts("PASS"); + + /* + * Test UTF-8 to legacy charset (ISO 8859-1)... + */ + + fputs("cupsUTF8ToCharset(CUPS_ISO8859_1): ", stdout); + + legdest[0] = 0; + + len = cupsUTF8ToCharset(legdest, utf8latin, 1024, CUPS_ISO8859_1); + if (len < 0) + { + printf("FAIL (len=%d)\n", len); + errors ++; + } + else + puts("PASS"); + + /* + * cupsCharsetToUTF8 + */ + + fputs("cupsCharsetToUTF8(CUPS_ISO8859_1): ", stdout); + + strcpy(legsrc, legdest); + + len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_1); + if (len != strlen((char *)utf8latin)) + { + printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8latin)); + print_utf8(" utf8latin", utf8latin); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (memcmp(utf8latin, utf8dest, len)) + { + puts("FAIL (results do not match)"); + print_utf8(" utf8latin", utf8latin); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (cupsUTF8ToCharset(legdest, utf8repla, 1024, CUPS_ISO8859_1) < 0) + { + puts("FAIL (replacement characters do not work!)"); + errors ++; + } + else + puts("PASS"); + + /* + * Test UTF-8 to/from legacy charset (ISO 8859-7)... + */ + + fputs("cupsUTF8ToCharset(CUPS_ISO8859_7): ", stdout); + + if (cupsUTF8ToCharset(legdest, utf8greek, 1024, CUPS_ISO8859_7) < 0) + { + puts("FAIL"); + errors ++; + } + else + { + for (legptr = legdest; *legptr && *legptr != '?'; legptr ++); + + if (*legptr) + { + puts("FAIL (unknown character)"); + errors ++; + } + else + puts("PASS"); + } + + fputs("cupsCharsetToUTF8(CUPS_ISO8859_7): ", stdout); + + strcpy(legsrc, legdest); + + len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_ISO8859_7); + if (len != strlen((char *)utf8greek)) + { + printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8greek)); + print_utf8(" utf8greek", utf8greek); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (memcmp(utf8greek, utf8dest, len)) + { + puts("FAIL (results do not match)"); + print_utf8(" utf8greek", utf8greek); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else + puts("PASS"); + + /* + * Test UTF-8 to/from legacy charset (Windows 932)... + */ + + fputs("cupsUTF8ToCharset(CUPS_WINDOWS_932): ", stdout); + + if (cupsUTF8ToCharset(legdest, utf8japan, 1024, CUPS_WINDOWS_932) < 0) + { + puts("FAIL"); + errors ++; + } + else + { + for (legptr = legdest; *legptr && *legptr != '?'; legptr ++); + + if (*legptr) + { + puts("FAIL (unknown character)"); + errors ++; + } + else + puts("PASS"); + } + + fputs("cupsCharsetToUTF8(CUPS_WINDOWS_932): ", stdout); + + strcpy(legsrc, legdest); + + len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_932); + if (len != strlen((char *)utf8japan)) + { + printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8japan)); + print_utf8(" utf8japan", utf8japan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (memcmp(utf8japan, utf8dest, len)) + { + puts("FAIL (results do not match)"); + print_utf8(" utf8japan", utf8japan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else + puts("PASS"); + + /* + * Test UTF-8 to/from legacy charset (EUC-JP)... + */ + + fputs("cupsUTF8ToCharset(CUPS_EUC_JP): ", stdout); + + if (cupsUTF8ToCharset(legdest, utf8japan, 1024, CUPS_EUC_JP) < 0) + { + puts("FAIL"); + errors ++; + } + else + { + for (legptr = legdest; *legptr && *legptr != '?'; legptr ++); + + if (*legptr) + { + puts("FAIL (unknown character)"); + errors ++; + } + else + puts("PASS"); + } + + fputs("cupsCharsetToUTF8(CUPS_EUC_JP): ", stdout); + + strcpy(legsrc, legdest); + + len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_JP); + if (len != strlen((char *)utf8japan)) + { + printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8japan)); + print_utf8(" utf8japan", utf8japan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (memcmp(utf8japan, utf8dest, len)) + { + puts("FAIL (results do not match)"); + print_utf8(" utf8japan", utf8japan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else + puts("PASS"); + + /* + * Test UTF-8 to/from legacy charset (Windows 950)... + */ + + fputs("cupsUTF8ToCharset(CUPS_WINDOWS_950): ", stdout); + + if (cupsUTF8ToCharset(legdest, utf8taiwan, 1024, CUPS_WINDOWS_950) < 0) + { + puts("FAIL"); + errors ++; + } + else + { + for (legptr = legdest; *legptr && *legptr != '?'; legptr ++); + + if (*legptr) + { + puts("FAIL (unknown character)"); + errors ++; + } + else + puts("PASS"); + } + + fputs("cupsCharsetToUTF8(CUPS_WINDOWS_950): ", stdout); + + strcpy(legsrc, legdest); + + len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_WINDOWS_950); + if (len != strlen((char *)utf8taiwan)) + { + printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8taiwan)); + print_utf8(" utf8taiwan", utf8taiwan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (memcmp(utf8taiwan, utf8dest, len)) + { + puts("FAIL (results do not match)"); + print_utf8(" utf8taiwan", utf8taiwan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else + puts("PASS"); + + /* + * Test UTF-8 to/from legacy charset (EUC-TW)... + */ + + fputs("cupsUTF8ToCharset(CUPS_EUC_TW): ", stdout); + + if (cupsUTF8ToCharset(legdest, utf8taiwan, 1024, CUPS_EUC_TW) < 0) + { + puts("FAIL"); + errors ++; + } + else + { + for (legptr = legdest; *legptr && *legptr != '?'; legptr ++); + + if (*legptr) + { + puts("FAIL (unknown character)"); + errors ++; + } + else + puts("PASS"); + } + + fputs("cupsCharsetToUTF8(CUPS_EUC_TW): ", stdout); + + strcpy(legsrc, legdest); + + len = cupsCharsetToUTF8(utf8dest, legsrc, 1024, CUPS_EUC_TW); + if (len != strlen((char *)utf8taiwan)) + { + printf("FAIL (len=%d, expected %d)\n", len, (int)strlen((char *)utf8taiwan)); + print_utf8(" utf8taiwan", utf8taiwan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else if (memcmp(utf8taiwan, utf8dest, len)) + { + puts("FAIL (results do not match)"); + print_utf8(" utf8taiwan", utf8taiwan); + print_utf8(" utf8dest", utf8dest); + errors ++; + } + else + puts("PASS"); + +#if 0 + /* + * Test UTF-8 (16-bit) to UTF-32 (w/ BOM)... + */ + if (verbose) + printf("\ntesti18n: Testing UTF-8 to UTF-32 (w/ BOM)...\n"); + len = cupsUTF8ToUTF32(utf32dest, utf8good, 1024); + if (len < 0) + return (1); + if (verbose) + { + print_utf8(" utf8good ", utf8good); + print_utf32(" utf32dest", utf32dest); + } + memcpy (utf32src, utf32dest, (len + 1) * sizeof(cups_utf32_t)); + len = cupsUTF32ToUTF8(utf8dest, utf32src, 1024); + if (len < 0) + return (1); + if (len != strlen ((char *) utf8good)) + return (1); + if (memcmp(utf8good, utf8dest, len) != 0) + return (1); + + /* + * Test invalid UTF-8 (16-bit) to UTF-32 (w/ BOM)... + */ + if (verbose) + printf("\ntesti18n: Testing UTF-8 bad 16-bit source string...\n"); + len = cupsUTF8ToUTF32(utf32dest, utf8bad, 1024); + if (len >= 0) + return (1); + if (verbose) + print_utf8(" utf8bad ", utf8bad); + + /* + * Test _cupsCharmapFlush()... + */ + if (verbose) + printf("\ntesti18n: Testing _cupsCharmapFlush()...\n"); + _cupsCharmapFlush(); + return (0); +#endif /* 0 */ + + return (errors > 0); +} + + +/* + * 'print_utf8()' - Print UTF-8 string with (optional) message. + */ + +static void +print_utf8(const char *msg, /* I - Message String */ + const cups_utf8_t *src) /* I - UTF-8 Source String */ +{ + const char *prefix; /* Prefix string */ + + + if (msg) + printf("%s:", msg); + + for (prefix = " "; *src; src ++) + { + printf("%s%02x", prefix, *src); + + if ((src[0] & 0x80) && (src[1] & 0x80)) + prefix = ""; + else + prefix = " "; + } + + putchar('\n'); +} + + +/* + * End of "$Id$" + */ diff --git a/cups/testipp.c b/cups/testipp.c new file mode 100644 index 0000000000..d09b3aedaf --- /dev/null +++ b/cups/testipp.c @@ -0,0 +1,870 @@ +/* + * "$Id$" + * + * IPP test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * hex_dump() - Produce a hex dump of a buffer. + * print_attributes() - Print the attributes in a request... + * read_cb() - Read data from a buffer. + * write_cb() - Write data into a buffer. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include "ipp-private.h" +#ifdef WIN32 +# include +#else +# include +# include +#endif /* WIN32 */ + + +/* + * Local globals... + */ + +int rpos; /* Current position in buffer */ +ipp_uchar_t wbuffer[8192]; /* Write buffer */ +int wused; /* Number of bytes in buffer */ +ipp_uchar_t collection[] = /* Collection buffer */ + { + 0x01, 0x01, /* IPP version */ + 0x00, 0x02, /* Print-Job operation */ + 0x00, 0x00, 0x00, 0x01, /* Request ID */ + + IPP_TAG_OPERATION, + + IPP_TAG_CHARSET, + 0x00, 0x12, /* Name length + name */ + 'a','t','t','r','i','b','u','t','e','s','-', + 'c','h','a','r','s','e','t', + 0x00, 0x05, /* Value length + value */ + 'u','t','f','-','8', + + IPP_TAG_LANGUAGE, + 0x00, 0x1b, /* Name length + name */ + 'a','t','t','r','i','b','u','t','e','s','-', + 'n','a','t','u','r','a','l','-','l','a','n', + 'g','u','a','g','e', + 0x00, 0x02, /* Value length + value */ + 'e','n', + + IPP_TAG_URI, + 0x00, 0x0b, /* Name length + name */ + 'p','r','i','n','t','e','r','-','u','r','i', + 0x00, 0x1c, /* Value length + value */ + 'i','p','p',':','/','/','l','o','c','a','l', + 'h','o','s','t','/','p','r','i','n','t','e', + 'r','s','/','f','o','o', + + IPP_TAG_JOB, /* job group tag */ + + IPP_TAG_BEGIN_COLLECTION, /* begCollection tag */ + 0x00, 0x09, /* Name length + name */ + 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', + 0x00, 0x00, /* No value */ + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0a, /* Value length + value */ + 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', + IPP_TAG_BEGIN_COLLECTION, /* begCollection tag */ + 0x00, 0x00, /* Name length + name */ + 0x00, 0x00, /* No value */ + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0b, /* Value length + value */ + 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', + IPP_TAG_INTEGER, /* integer tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x04, /* Value length + value */ + 0x00, 0x00, 0x54, 0x56, + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0b, /* Value length + value */ + 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', + IPP_TAG_INTEGER, /* integer tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x04, /* Value length + value */ + 0x00, 0x00, 0x6d, 0x24, + IPP_TAG_END_COLLECTION, /* endCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0b, /* Value length + value */ + 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r', + IPP_TAG_KEYWORD, /* keyword tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x04, /* Value length + value */ + 'b', 'l', 'u', 'e', + + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0a, /* Value length + value */ + 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e', + IPP_TAG_KEYWORD, /* keyword tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x05, /* Value length + value */ + 'p', 'l', 'a', 'i', 'n', + IPP_TAG_END_COLLECTION, /* endCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + + IPP_TAG_BEGIN_COLLECTION, /* begCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0a, /* Value length + value */ + 'm', 'e', 'd', 'i', 'a', '-', 's', 'i', 'z', 'e', + IPP_TAG_BEGIN_COLLECTION, /* begCollection tag */ + 0x00, 0x00, /* Name length + name */ + 0x00, 0x00, /* No value */ + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0b, /* Value length + value */ + 'x', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', + IPP_TAG_INTEGER, /* integer tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x04, /* Value length + value */ + 0x00, 0x00, 0x52, 0x08, + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0b, /* Value length + value */ + 'y', '-', 'd', 'i', 'm', 'e', 'n', 's', 'i', 'o', 'n', + IPP_TAG_INTEGER, /* integer tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x04, /* Value length + value */ + 0x00, 0x00, 0x74, 0x04, + IPP_TAG_END_COLLECTION, /* endCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0b, /* Value length + value */ + 'm', 'e', 'd', 'i', 'a', '-', 'c', 'o', 'l', 'o', 'r', + IPP_TAG_KEYWORD, /* keyword tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x05, /* Value length + value */ + 'p', 'l', 'a', 'i', 'd', + + IPP_TAG_MEMBERNAME, /* memberAttrName tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x0a, /* Value length + value */ + 'm', 'e', 'd', 'i', 'a', '-', 't', 'y', 'p', 'e', + IPP_TAG_KEYWORD, /* keyword tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x06, /* Value length + value */ + 'g', 'l', 'o', 's', 's', 'y', + IPP_TAG_END_COLLECTION, /* endCollection tag */ + 0x00, 0x00, /* No name */ + 0x00, 0x00, /* No value */ + + IPP_TAG_END /* end tag */ + }; + + +/* + * Local functions... + */ + +void hex_dump(const char *title, ipp_uchar_t *buffer, int bytes); +void print_attributes(ipp_t *ipp, int indent); +ssize_t read_cb(void *data, ipp_uchar_t *buffer, size_t bytes); +ssize_t write_cb(void *data, ipp_uchar_t *buffer, size_t bytes); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + ipp_t *cols[2], /* Collections */ + *size; /* media-size collection */ + ipp_t *request; /* Request */ + ipp_attribute_t *media_col, /* media-col attribute */ + *media_size, /* media-size attribute */ + *attr; /* Other attribute */ + ipp_state_t state; /* State */ + int length; /* Length of data */ + cups_file_t *fp; /* File pointer */ + int i; /* Looping var */ + int status; /* Status of tests (0 = success, 1 = fail) */ + + + status = 0; + + if (argc == 1) + { + /* + * Test request generation code... + */ + + printf("Create Sample Request: "); + + request = ippNew(); + request->request.op.version[0] = 0x01; + request->request.op.version[1] = 0x01; + 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, "utf-8"); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, "en"); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, "ipp://localhost/printers/foo"); + + cols[0] = ippNew(); + size = ippNew(); + ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590); + ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940); + ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size); + ippDelete(size); + ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, + "blue"); + ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL, + "plain"); + + cols[1] = ippNew(); + size = ippNew(); + ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000); + ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700); + ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size); + ippDelete(size); + ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL, + "plaid"); + ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL, + "glossy"); + + ippAddCollections(request, IPP_TAG_JOB, "media-col", 2, + (const ipp_t **)cols); + ippDelete(cols[0]); + ippDelete(cols[1]); + + length = ippLength(request); + if (length != sizeof(collection)) + { + printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", + length, (int)sizeof(collection)); + status = 1; + } + else + puts("PASS"); + + /* + * Write test #1... + */ + + printf("Write Sample to Memory: "); + + wused = 0; + while ((state = ippWriteIO(wbuffer, write_cb, 1, NULL, + request)) != IPP_DATA) + if (state == IPP_ERROR) + break; + + if (state != IPP_DATA) + { + printf("FAIL - %d bytes written.\n", wused); + status = 1; + } + else if (wused != sizeof(collection)) + { + printf("FAIL - wrote %d bytes, expected %d bytes!\n", wused, + (int)sizeof(collection)); + hex_dump("Bytes Written", wbuffer, wused); + hex_dump("Baseline", collection, sizeof(collection)); + status = 1; + } + else if (memcmp(wbuffer, collection, wused)) + { + for (i = 0; i < wused; i ++) + if (wbuffer[i] != collection[i]) + break; + + printf("FAIL - output does not match baseline at 0x%04x!\n", i); + hex_dump("Bytes Written", wbuffer, wused); + hex_dump("Baseline", collection, sizeof(collection)); + status = 1; + } + else + puts("PASS"); + + ippDelete(request); + + /* + * Read the data back in and confirm... + */ + + printf("Read Sample from Memory: "); + + request = ippNew(); + rpos = 0; + + while ((state = ippReadIO(wbuffer, read_cb, 1, NULL, request)) != IPP_DATA) + if (state == IPP_ERROR) + break; + + length = ippLength(request); + + if (state != IPP_DATA) + { + printf("FAIL - %d bytes read.\n", rpos); + status = 1; + } + else if (rpos != wused) + { + printf("FAIL - read %d bytes, expected %d bytes!\n", rpos, wused); + print_attributes(request, 8); + status = 1; + } + else if (length != sizeof(collection)) + { + printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n", + length, (int)sizeof(collection)); + print_attributes(request, 8); + status = 1; + } + else + puts("PASS"); + + fputs("ippFindAttribute(media-col): ", stdout); + if ((media_col = ippFindAttribute(request, "media-col", + IPP_TAG_BEGIN_COLLECTION)) == NULL) + { + if ((media_col = ippFindAttribute(request, "media-col", + IPP_TAG_ZERO)) == NULL) + puts("FAIL (not found)"); + else + printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag)); + + status = 1; + } + else if (media_col->num_values != 2) + { + printf("FAIL (wrong count - %d)\n", media_col->num_values); + status = 1; + } + else + puts("PASS"); + + if (media_col) + { + fputs("ippFindAttribute(media-size 1): ", stdout); + if ((media_size = ippFindAttribute(media_col->values[0].collection, + "media-size", + IPP_TAG_BEGIN_COLLECTION)) == NULL) + { + if ((media_size = ippFindAttribute(media_col->values[0].collection, + "media-col", + IPP_TAG_ZERO)) == NULL) + puts("FAIL (not found)"); + else + printf("FAIL (wrong type - %s)\n", + ippTagString(media_size->value_tag)); + + status = 1; + } + else + { + if ((attr = ippFindAttribute(media_size->values[0].collection, + "x-dimension", IPP_TAG_INTEGER)) == NULL) + { + if ((attr = ippFindAttribute(media_size->values[0].collection, + "x-dimension", IPP_TAG_ZERO)) == NULL) + puts("FAIL (missing x-dimension)"); + else + printf("FAIL (wrong type for x-dimension - %s)\n", + ippTagString(attr->value_tag)); + + status = 1; + } + else if (attr->values[0].integer != 21590) + { + printf("FAIL (wrong value for x-dimension - %d)\n", + attr->values[0].integer); + status = 1; + } + else if ((attr = ippFindAttribute(media_size->values[0].collection, + "y-dimension", + IPP_TAG_INTEGER)) == NULL) + { + if ((attr = ippFindAttribute(media_size->values[0].collection, + "y-dimension", IPP_TAG_ZERO)) == NULL) + puts("FAIL (missing y-dimension)"); + else + printf("FAIL (wrong type for y-dimension - %s)\n", + ippTagString(attr->value_tag)); + + status = 1; + } + else if (attr->values[0].integer != 27940) + { + printf("FAIL (wrong value for y-dimension - %d)\n", + attr->values[0].integer); + status = 1; + } + else + puts("PASS"); + } + + fputs("ippFindAttribute(media-size 2): ", stdout); + if ((media_size = ippFindAttribute(media_col->values[1].collection, + "media-size", + IPP_TAG_BEGIN_COLLECTION)) == NULL) + { + if ((media_size = ippFindAttribute(media_col->values[1].collection, + "media-col", + IPP_TAG_ZERO)) == NULL) + puts("FAIL (not found)"); + else + printf("FAIL (wrong type - %s)\n", + ippTagString(media_size->value_tag)); + + status = 1; + } + else + { + if ((attr = ippFindAttribute(media_size->values[0].collection, + "x-dimension", + IPP_TAG_INTEGER)) == NULL) + { + if ((attr = ippFindAttribute(media_size->values[0].collection, + "x-dimension", IPP_TAG_ZERO)) == NULL) + puts("FAIL (missing x-dimension)"); + else + printf("FAIL (wrong type for x-dimension - %s)\n", + ippTagString(attr->value_tag)); + + status = 1; + } + else if (attr->values[0].integer != 21000) + { + printf("FAIL (wrong value for x-dimension - %d)\n", + attr->values[0].integer); + status = 1; + } + else if ((attr = ippFindAttribute(media_size->values[0].collection, + "y-dimension", + IPP_TAG_INTEGER)) == NULL) + { + if ((attr = ippFindAttribute(media_size->values[0].collection, + "y-dimension", IPP_TAG_ZERO)) == NULL) + puts("FAIL (missing y-dimension)"); + else + printf("FAIL (wrong type for y-dimension - %s)\n", + ippTagString(attr->value_tag)); + + status = 1; + } + else if (attr->values[0].integer != 29700) + { + printf("FAIL (wrong value for y-dimension - %d)\n", + attr->values[0].integer); + status = 1; + } + else + puts("PASS"); + } + } + + ippDelete(request); + + /* + * Test _ippFindOption() private API... + */ + + fputs("_ippFindOption(printer-type): ", stdout); + if (_ippFindOption("printer-type")) + puts("PASS"); + else + { + puts("FAIL"); + status = 1; + } + + /* + * Summarize... + */ + + putchar('\n'); + + if (status) + puts("Core IPP tests failed."); + else + puts("Core IPP tests passed."); + } + else + { + /* + * Read IPP files... + */ + + for (i = 1; i < argc; i ++) + { + if ((fp = cupsFileOpen(argv[i], "r")) == NULL) + { + printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno)); + status = 1; + continue; + } + + request = ippNew(); + while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, + request)) == IPP_ATTRIBUTE); + + if (state != IPP_DATA) + { + printf("Error reading IPP message from \"%s\"!\n", argv[i]); + status = 1; + } + else + { + printf("\n%s:\n", argv[i]); + print_attributes(request, 4); + } + + ippDelete(request); + cupsFileClose(fp); + } + } + + return (status); +} + + +/* + * 'hex_dump()' - Produce a hex dump of a buffer. + */ + +void +hex_dump(const char *title, /* I - Title */ + ipp_uchar_t *buffer, /* I - Buffer to dump */ + int bytes) /* I - Number of bytes */ +{ + int i, j; /* Looping vars */ + int ch; /* Current ASCII char */ + + + /* + * Show lines of 16 bytes at a time... + */ + + printf(" %s:\n", title); + + for (i = 0; i < bytes; i += 16) + { + /* + * Show the offset... + */ + + printf(" %04x ", i); + + /* + * Then up to 16 bytes in hex... + */ + + for (j = 0; j < 16; j ++) + if ((i + j) < bytes) + printf(" %02x", buffer[i + j]); + else + printf(" "); + + /* + * Then the ASCII representation of the bytes... + */ + + putchar(' '); + putchar(' '); + + for (j = 0; j < 16 && (i + j) < bytes; j ++) + { + ch = buffer[i + j] & 127; + + if (ch < ' ' || ch == 127) + putchar('.'); + else + putchar(ch); + } + + putchar('\n'); + } +} + + +/* + * 'print_attributes()' - Print the attributes in a request... + */ + +void +print_attributes(ipp_t *ipp, /* I - IPP request */ + int indent) /* I - Indentation */ +{ + int i; /* Looping var */ + ipp_tag_t group; /* Current group */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_value_t *val; /* Current value */ + static const char * const tags[] = /* Value/group tag strings */ + { + "reserved-00", + "operation-attributes-tag", + "job-attributes-tag", + "end-of-attributes-tag", + "printer-attributes-tag", + "unsupported-attributes-tag", + "subscription-attributes-tag", + "event-attributes-tag", + "reserved-08", + "reserved-09", + "reserved-0A", + "reserved-0B", + "reserved-0C", + "reserved-0D", + "reserved-0E", + "reserved-0F", + "unsupported", + "default", + "unknown", + "no-value", + "reserved-14", + "not-settable", + "delete-attr", + "admin-define", + "reserved-18", + "reserved-19", + "reserved-1A", + "reserved-1B", + "reserved-1C", + "reserved-1D", + "reserved-1E", + "reserved-1F", + "reserved-20", + "integer", + "boolean", + "enum", + "reserved-24", + "reserved-25", + "reserved-26", + "reserved-27", + "reserved-28", + "reserved-29", + "reserved-2a", + "reserved-2b", + "reserved-2c", + "reserved-2d", + "reserved-2e", + "reserved-2f", + "octetString", + "dateTime", + "resolution", + "rangeOfInteger", + "begCollection", + "textWithLanguage", + "nameWithLanguage", + "endCollection", + "reserved-38", + "reserved-39", + "reserved-3a", + "reserved-3b", + "reserved-3c", + "reserved-3d", + "reserved-3e", + "reserved-3f", + "reserved-40", + "textWithoutLanguage", + "nameWithoutLanguage", + "reserved-43", + "keyword", + "uri", + "uriScheme", + "charset", + "naturalLanguage", + "mimeMediaType", + "memberName" + }; + + + for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next) + { + if (!attr->name && indent == 4) + { + group = IPP_TAG_ZERO; + putchar('\n'); + continue; + } + + if (group != attr->group_tag) + { + group = attr->group_tag; + + printf("\n%*s%s:\n\n", indent - 4, "", tags[group]); + } + + printf("%*s%s (", indent, "", attr->name ? attr->name : "(null)"); + if (attr->num_values > 1) + printf("1setOf "); + printf("%s):", tags[attr->value_tag]); + + switch (attr->value_tag) + { + case IPP_TAG_ENUM : + case IPP_TAG_INTEGER : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %d", val->integer); + putchar('\n'); + break; + + case IPP_TAG_BOOLEAN : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %s", val->boolean ? "true" : "false"); + putchar('\n'); + break; + + case IPP_TAG_RANGE : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %d-%d", val->range.lower, val->range.upper); + putchar('\n'); + break; + + case IPP_TAG_DATE : + { + time_t vtime; /* Date/Time value */ + struct tm *vdate; /* Date info */ + char vstring[256]; /* Formatted time */ + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + vtime = ippDateToTime(val->date); + vdate = localtime(&vtime); + strftime(vstring, sizeof(vstring), "%c", vdate); + printf(" (%s)", vstring); + } + } + putchar('\n'); + break; + + case IPP_TAG_RESOLUTION : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %dx%d%s", val->resolution.xres, val->resolution.yres, + val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); + putchar('\n'); + break; + + 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 : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" \"%s\"", val->string.text); + putchar('\n'); + break; + + case IPP_TAG_BEGIN_COLLECTION : + putchar('\n'); + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + if (i) + putchar('\n'); + print_attributes(val->collection, indent + 4); + } + break; + + default : + printf("UNKNOWN (%d values)\n", attr->num_values); + break; + } + } +} + + +/* + * 'read_cb()' - Read data from a buffer. + */ + +ssize_t /* O - Number of bytes read */ +read_cb(void *data, /* I - Data */ + ipp_uchar_t *buffer, /* O - Buffer to read */ + size_t bytes) /* I - Number of bytes to read */ +{ + int count; /* Number of bytes */ + + + /* + * Copy bytes from the data buffer to the read buffer... + */ + + for (count = bytes; count > 0 && rpos < wused; count --, rpos ++) + *buffer++ = wbuffer[rpos]; + + /* + * Return the number of bytes read... + */ + + return (bytes - count); +} + + +/* + * 'write_cb()' - Write data into a buffer. + */ + +ssize_t /* O - Number of bytes written */ +write_cb(void *data, /* I - Data */ + ipp_uchar_t *buffer, /* I - Buffer to write */ + size_t bytes) /* I - Number of bytes to write */ +{ + int count; /* Number of bytes */ + + + /* + * Loop until all bytes are written... + */ + + for (count = bytes; count > 0 && wused < sizeof(wbuffer); count --, wused ++) + wbuffer[wused] = *buffer++; + + /* + * Return the number of bytes written... + */ + + return (bytes - count); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testlang.c b/cups/testlang.c new file mode 100644 index 0000000000..ce3bd7655e --- /dev/null +++ b/cups/testlang.c @@ -0,0 +1,116 @@ +/* + * "$Id$" + * + * Localization test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include "i18n.h" +#include "string.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 */ +{ + int i; /* Looping var */ + int errors = 0; /* Number of errors */ + cups_lang_t *language; /* Message catalog */ + cups_lang_t *language2; /* Message catalog */ + struct lconv *loc; /* Locale data */ + char buffer[1024]; /* String buffer */ + double number; /* Number */ + static const char * const tests[] = /* Test strings */ + { + "1", + "-1", + "3", + "5.125" + }; + + + _cupsSetLocale(argv); + + if (argc == 1) + { + language = cupsLangDefault(); + language2 = cupsLangDefault(); + } + else + { + language = cupsLangGet(argv[1]); + language2 = cupsLangGet(argv[1]); + } + + if (language != language2) + { + errors ++; + + puts("**** ERROR: Language cache did not work! ****"); + puts("First result from cupsLangGet:"); + } + + printf("Language = \"%s\"\n", language->language); + printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding)); + printf("No = \"%s\"\n", _cupsLangString(language, "No")); + printf("Yes = \"%s\"\n", _cupsLangString(language, "Yes")); + + if (language != language2) + { + puts("Second result from cupsLangGet:"); + + printf("Language = \"%s\"\n", language2->language); + printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding)); + printf("No = \"%s\"\n", _cupsLangString(language2, "No")); + printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); + } + + loc = localeconv(); + + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) + { + number = _cupsStrScand(tests[i], NULL, loc); + + printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); + + _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); + + printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); + + if (strcmp(buffer, tests[i])) + { + errors ++; + puts("**** ERROR: Bad formatted number! ****"); + } + } + + return (errors > 0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testoptions.c b/cups/testoptions.c new file mode 100644 index 0000000000..39aa0089f4 --- /dev/null +++ b/cups/testoptions.c @@ -0,0 +1,117 @@ +/* + * "$Id$" + * + * Option test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2008 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Test option processing functions. + */ + +/* + * Include necessary headers... + */ + +#include "string.h" +#include "cups.h" + + +/* + * 'main()' - Test option processing functions. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int status = 0, /* Exit status */ + num_options; /* Number of options */ + cups_option_t *options; /* Options */ + const char *value; /* Value of an option */ + + + if (argc == 1) + { + /* + * cupsParseOptions() + */ + + fputs("cupsParseOptions: ", stdout); + + num_options = cupsParseOptions("foo=1234 " + "bar=\"One Fish\",\"Two Fish\",\"Red Fish\"," + "\"Blue Fish\" " + "baz={param1=1 param2=2} " + "foobar=FOO\\ BAR " + "barfoo=barfoo " + "barfoo=\"\'BAR FOO\'\"", 0, &options); + + if (num_options != 5) + { + printf("FAIL (num_options=%d, expected 5)\n", num_options); + status ++; + } + else if ((value = cupsGetOption("foo", num_options, options)) == NULL || + strcmp(value, "1234")) + { + printf("FAIL (foo=\"%s\", expected \"1234\")\n", value); + status ++; + } + else if ((value = cupsGetOption("bar", num_options, options)) == NULL || + strcmp(value, "One Fish,Two Fish,Red Fish,Blue Fish")) + { + printf("FAIL (bar=\"%s\", expected \"One Fish,Two Fish,Red Fish,Blue " + "Fish\")\n", value); + status ++; + } + else if ((value = cupsGetOption("baz", num_options, options)) == NULL || + strcmp(value, "{param1=1 param2=2}")) + { + printf("FAIL (baz=\"%s\", expected \"{param1=1 param2=2}\")\n", value); + status ++; + } + else if ((value = cupsGetOption("foobar", num_options, options)) == NULL || + strcmp(value, "FOO BAR")) + { + printf("FAIL (foobar=\"%s\", expected \"FOO BAR\")\n", value); + status ++; + } + else if ((value = cupsGetOption("barfoo", num_options, options)) == NULL || + strcmp(value, "\'BAR FOO\'")) + { + printf("FAIL (barfoo=\"%s\", expected \"\'BAR FOO\'\")\n", value); + status ++; + } + else + puts("PASS"); + } + else + { + int i; /* Looping var */ + cups_option_t *option; /* Current option */ + + + num_options = cupsParseOptions(argv[1], 0, &options); + + for (i = 0, option = options; i < num_options; i ++, option ++) + printf("options[%d].name=\"%s\", value=\"%s\"\n", i, option->name, + option->value); + } + + exit (status); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testppd.c b/cups/testppd.c new file mode 100644 index 0000000000..53956c9911 --- /dev/null +++ b/cups/testppd.c @@ -0,0 +1,1081 @@ +/* + * "$Id$" + * + * PPD test program for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +# include +#else +# include +# include +#endif /* WIN32 */ + + +/* + * Test data... + */ + +static const char *default_code = + "[{\n" + "%%BeginFeature: *InstalledDuplexer False\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *PageRegion Letter\n" + "PageRegion=Letter\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *InputSlot Tray\n" + "InputSlot=Tray\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *MediaType Plain\n" + "MediaType=Plain\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *IntOption None\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *StringOption None\n" + "%%EndFeature\n" + "} stopped cleartomark\n"; + +static const char *custom_code = + "[{\n" + "%%BeginFeature: *InstalledDuplexer False\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *InputSlot Tray\n" + "InputSlot=Tray\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *MediaType Plain\n" + "MediaType=Plain\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *IntOption None\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *CustomStringOption True\n" + "(value\\0502\\051)\n" + "(value 1)\n" + "StringOption=Custom\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *CustomPageSize True\n" + "400\n" + "500\n" + "0\n" + "0\n" + "0\n" + "PageSize=Custom\n" + "%%EndFeature\n" + "} stopped cleartomark\n"; + +static const char *default2_code = + "[{\n" + "%%BeginFeature: *InstalledDuplexer False\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *InputSlot Tray\n" + "InputSlot=Tray\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *Quality Normal\n" + "Quality=Normal\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *IntOption None\n" + "%%EndFeature\n" + "} stopped cleartomark\n" + "[{\n" + "%%BeginFeature: *StringOption None\n" + "%%EndFeature\n" + "} stopped cleartomark\n"; + + +/* + * '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 */ + ppd_file_t *ppd; /* PPD file loaded from disk */ + int status; /* Status of tests (0 = success, 1 = fail) */ + int conflicts; /* Number of conflicts */ + char *s; /* String */ + char buffer[8192]; /* String buffer */ + const char *text, /* Localized text */ + *val; /* Option value */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + ppd_size_t minsize, /* Minimum size */ + maxsize, /* Maximum size */ + *size; /* Current size */ + ppd_attr_t *attr; /* Current attribute */ + + + status = 0; + + if (argc == 1) + { + /* + * Setup directories for locale stuff... + */ + + if (access("locale", 0)) + { + mkdir("locale", 0777); + mkdir("locale/fr", 0777); + symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po"); + mkdir("locale/zh_TW", 0777); + symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po"); + } + + putenv("LOCALEDIR=locale"); + putenv("SOFTWARE=CUPS"); + + /* + * Do tests with test.ppd... + */ + + fputs("ppdOpenFile(test.ppd): ", stdout); + + if ((ppd = ppdOpenFile("test.ppd")) != NULL) + puts("PASS"); + else + { + ppd_status_t err; /* Last error in file */ + int line; /* Line number in file */ + + + status ++; + err = ppdLastError(&line); + + printf("FAIL (%s on line %d)\n", ppdErrorString(err), line); + } + + fputs("ppdFindAttr(wildcard): ", stdout); + if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL) + { + status ++; + puts("FAIL (not found)"); + } + else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo")) + { + status ++; + printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); + } + else + puts("PASS"); + + fputs("ppdFindNextAttr(wildcard): ", stdout); + if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL) + { + status ++; + puts("FAIL (not found)"); + } + else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar")) + { + status ++; + printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); + } + else + puts("PASS"); + + fputs("ppdFindAttr(Foo): ", stdout); + if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL) + { + status ++; + puts("FAIL (not found)"); + } + else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo")) + { + status ++; + printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); + } + else + puts("PASS"); + + fputs("ppdFindNextAttr(Foo): ", stdout); + if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL) + { + status ++; + printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec); + } + else + puts("PASS"); + + fputs("ppdMarkDefaults: ", stdout); + ppdMarkDefaults(ppd); + + if ((conflicts = ppdConflicts(ppd)) == 0) + puts("PASS"); + else + { + status ++; + printf("FAIL (%d conflicts)\n", conflicts); + } + + fputs("ppdEmitString (defaults): ", stdout); + if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && + !strcmp(s, default_code)) + puts("PASS"); + else + { + status ++; + printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0, + (int)strlen(default_code)); + + if (s) + puts(s); + } + + if (s) + free(s); + + fputs("ppdEmitString (custom size and string): ", stdout); + ppdMarkOption(ppd, "PageSize", "Custom.400x500"); + ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}"); + + if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && + !strcmp(s, custom_code)) + puts("PASS"); + else + { + status ++; + printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0, + (int)strlen(custom_code)); + + if (s) + puts(s); + } + + if (s) + free(s); + + /* + * Test constraints... + */ + + fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout); + ppdMarkOption(ppd, "PageSize", "Letter"); + + num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options); + if (num_options != 2 || + (val = cupsGetOption("PageRegion", num_options, options)) == NULL || + strcasecmp(val, "Letter") || + (val = cupsGetOption("PageSize", num_options, options)) == NULL || + strcasecmp(val, "Letter")) + { + printf("FAIL (%d options:", num_options); + for (i = 0; i < num_options; i ++) + printf(" %s=%s", options[i].name, options[i].value); + puts(")"); + status ++; + } + else + puts("PASS"); + + fputs("ppdConflicts(): ", stdout); + ppdMarkOption(ppd, "InputSlot", "Envelope"); + + if ((conflicts = ppdConflicts(ppd)) == 2) + puts("PASS (2)"); + else + { + printf("FAIL (%d)\n", conflicts); + status ++; + } + + fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout); + num_options = 0; + options = NULL; + if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options, + &options)) + { + puts("FAIL (Unable to resolve)"); + status ++; + } + else if (num_options != 2 || + !cupsGetOption("PageSize", num_options, options)) + { + printf("FAIL (%d options:", num_options); + for (i = 0; i < num_options; i ++) + printf(" %s=%s", options[i].name, options[i].value); + puts(")"); + status ++; + } + else + puts("PASS (Resolved by changing PageSize)"); + + cupsFreeOptions(num_options, options); + + fputs("cupsResolveConflicts(No option/choice): ", stdout); + num_options = 0; + options = NULL; + if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) && + num_options == 1 && !strcasecmp(options[0].name, "InputSlot") && + !strcasecmp(options[0].value, "Tray")) + puts("PASS (Resolved by changing InputSlot)"); + else if (num_options > 0) + { + printf("FAIL (%d options:", num_options); + for (i = 0; i < num_options; i ++) + printf(" %s=%s", options[i].name, options[i].value); + puts(")"); + status ++; + } + else + { + puts("FAIL (Unable to resolve)"); + status ++; + } + cupsFreeOptions(num_options, options); + + fputs("ppdInstallableConflict(): ", stdout); + if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") && + !ppdInstallableConflict(ppd, "Duplex", "None")) + puts("PASS"); + else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble")) + { + puts("FAIL (Duplex=DuplexNoTumble did not conflict)"); + status ++; + } + else + { + puts("FAIL (Duplex=None conflicted)"); + status ++; + } + + /* + * ppdPageSizeLimits + */ + + fputs("ppdPageSizeLimits: ", stdout); + if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) + { + if (minsize.width != 36 || minsize.length != 36 || + maxsize.width != 1080 || maxsize.length != 86400) + { + printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " + "expected min=36x36, max=1080x86400)\n", minsize.width, + minsize.length, maxsize.width, maxsize.length); + status ++; + } + else + puts("PASS"); + } + else + { + puts("FAIL (returned 0)"); + status ++; + } + + /* + * cupsMarkOptions with PWG and IPP size names. + */ + + fputs("cupsMarkOptions(media=iso-a4): ", stdout); + num_options = cupsAddOption("media", "iso-a4", 0, &options); + cupsMarkOptions(ppd, num_options, options); + cupsFreeOptions(num_options, options); + + size = ppdPageSize(ppd, NULL); + if (!size || strcmp(size->name, "A4")) + { + printf("FAIL (%s)\n", size ? size->name : "unknown"); + status ++; + } + else + puts("PASS"); + + fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout); + num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options); + cupsMarkOptions(ppd, num_options, options); + cupsFreeOptions(num_options, options); + + size = ppdPageSize(ppd, NULL); + if (!size || strcmp(size->name, "Letter")) + { + printf("FAIL (%s)\n", size ? size->name : "unknown"); + status ++; + } + else + puts("PASS"); + + fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout); + num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0, + &options); + cupsMarkOptions(ppd, num_options, options); + cupsFreeOptions(num_options, options); + + size = ppdPageSize(ppd, NULL); + if (!size || strcmp(size->name, "Letter.Fullbleed")) + { + printf("FAIL (%s)\n", size ? size->name : "unknown"); + status ++; + } + else + puts("PASS"); + + fputs("cupsMarkOptions(media=A4): ", stdout); + num_options = cupsAddOption("media", "A4", 0, &options); + cupsMarkOptions(ppd, num_options, options); + cupsFreeOptions(num_options, options); + + size = ppdPageSize(ppd, NULL); + if (!size || strcmp(size->name, "A4")) + { + printf("FAIL (%s)\n", size ? size->name : "unknown"); + status ++; + } + else + puts("PASS"); + + /* + * Test localization... + */ + + fputs("ppdLocalizeIPPReason(text): ", stdout); + if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) && + !strcmp(buffer, "Foo Reason")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer); + } + + fputs("ppdLocalizeIPPReason(http): ", stdout); + if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) && + !strcmp(buffer, "http://foo/bar.html")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer); + } + + fputs("ppdLocalizeIPPReason(help): ", stdout); + if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) && + !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer); + } + + fputs("ppdLocalizeIPPReason(file): ", stdout); + if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) && + !strcmp(buffer, "/help/foo/bar.html")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer); + } + + putenv("LANG=fr"); + putenv("LC_ALL=fr"); + putenv("LC_CTYPE=fr"); + putenv("LC_MESSAGES=fr"); + + fputs("ppdLocalizeIPPReason(fr text): ", stdout); + if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) && + !strcmp(buffer, "La Long Foo Reason")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer); + } + + putenv("LANG=zh_TW"); + putenv("LC_ALL=zh_TW"); + putenv("LC_CTYPE=zh_TW"); + putenv("LC_MESSAGES=zh_TW"); + + fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout); + if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) && + !strcmp(buffer, "Number 1 Foo Reason")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer); + } + + /* + * cupsMarkerName localization... + */ + + putenv("LANG=en"); + putenv("LC_ALL=en"); + putenv("LC_CTYPE=en"); + putenv("LC_MESSAGES=en"); + + fputs("ppdLocalizeMarkerName(bogus): ", stdout); + + if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL) + { + status ++; + printf("FAIL (\"%s\" instead of NULL)\n", text); + } + else + puts("PASS"); + + fputs("ppdLocalizeMarkerName(cyan): ", stdout); + + if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL && + !strcmp(text, "Cyan Toner")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n", + text ? text : "(null)"); + } + + putenv("LANG=fr"); + putenv("LC_ALL=fr"); + putenv("LC_CTYPE=fr"); + putenv("LC_MESSAGES=fr"); + + fputs("ppdLocalizeMarkerName(fr cyan): ", stdout); + if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL && + !strcmp(text, "La Toner Cyan")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n", + text ? text : "(null)"); + } + + putenv("LANG=zh_TW"); + putenv("LC_ALL=zh_TW"); + putenv("LC_CTYPE=zh_TW"); + putenv("LC_MESSAGES=zh_TW"); + + fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout); + if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL && + !strcmp(text, "Number 1 Cyan Toner")) + puts("PASS"); + else + { + status ++; + printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n", + text ? text : "(null)"); + } + + ppdClose(ppd); + + /* + * Test new constraints... + */ + + fputs("ppdOpenFile(test2.ppd): ", stdout); + + if ((ppd = ppdOpenFile("test2.ppd")) != NULL) + puts("PASS"); + else + { + ppd_status_t err; /* Last error in file */ + int line; /* Line number in file */ + + + status ++; + err = ppdLastError(&line); + + printf("FAIL (%s on line %d)\n", ppdErrorString(err), line); + } + + fputs("ppdMarkDefaults: ", stdout); + ppdMarkDefaults(ppd); + + if ((conflicts = ppdConflicts(ppd)) == 0) + puts("PASS"); + else + { + status ++; + printf("FAIL (%d conflicts)\n", conflicts); + } + + fputs("ppdEmitString (defaults): ", stdout); + if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL && + !strcmp(s, default2_code)) + puts("PASS"); + else + { + status ++; + printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0, + (int)strlen(default2_code)); + + if (s) + puts(s); + } + + if (s) + free(s); + + fputs("ppdConflicts(): ", stdout); + ppdMarkOption(ppd, "PageSize", "Env10"); + ppdMarkOption(ppd, "InputSlot", "Envelope"); + ppdMarkOption(ppd, "Quality", "Photo"); + + if ((conflicts = ppdConflicts(ppd)) == 1) + puts("PASS (1)"); + else + { + printf("FAIL (%d)\n", conflicts); + status ++; + } + + fputs("cupsResolveConflicts(Quality=Photo): ", stdout); + num_options = 0; + options = NULL; + if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options, + &options)) + { + printf("FAIL (%d options:", num_options); + for (i = 0; i < num_options; i ++) + printf(" %s=%s", options[i].name, options[i].value); + puts(")"); + status ++; + } + else + puts("PASS (Unable to resolve)"); + cupsFreeOptions(num_options, options); + + fputs("cupsResolveConflicts(No option/choice): ", stdout); + num_options = 0; + options = NULL; + if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) && + num_options == 1 && !strcasecmp(options->name, "Quality") && + !strcasecmp(options->value, "Normal")) + puts("PASS"); + else if (num_options > 0) + { + printf("FAIL (%d options:", num_options); + for (i = 0; i < num_options; i ++) + printf(" %s=%s", options[i].name, options[i].value); + puts(")"); + status ++; + } + else + { + puts("FAIL (Unable to resolve!)"); + status ++; + } + cupsFreeOptions(num_options, options); + + fputs("cupsResolveConflicts(loop test): ", stdout); + ppdMarkOption(ppd, "PageSize", "A4"); + ppdMarkOption(ppd, "InputSlot", "Tray"); + ppdMarkOption(ppd, "Quality", "Photo"); + num_options = 0; + options = NULL; + if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options)) + puts("PASS"); + else if (num_options > 0) + { + printf("FAIL (%d options:", num_options); + for (i = 0; i < num_options; i ++) + printf(" %s=%s", options[i].name, options[i].value); + puts(")"); + } + else + puts("FAIL (No conflicts!)"); + + fputs("ppdInstallableConflict(): ", stdout); + if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") && + !ppdInstallableConflict(ppd, "Duplex", "None")) + puts("PASS"); + else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble")) + { + puts("FAIL (Duplex=DuplexNoTumble did not conflict)"); + status ++; + } + else + { + puts("FAIL (Duplex=None conflicted)"); + status ++; + } + + /* + * ppdPageSizeLimits + */ + + ppdMarkDefaults(ppd); + + fputs("ppdPageSizeLimits(default): ", stdout); + if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) + { + if (minsize.width != 36 || minsize.length != 36 || + maxsize.width != 1080 || maxsize.length != 86400) + { + printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " + "expected min=36x36, max=1080x86400)\n", minsize.width, + minsize.length, maxsize.width, maxsize.length); + status ++; + } + else + puts("PASS"); + } + else + { + puts("FAIL (returned 0)"); + status ++; + } + + ppdMarkOption(ppd, "InputSlot", "Manual"); + + fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout); + if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) + { + if (minsize.width != 100 || minsize.length != 100 || + maxsize.width != 1000 || maxsize.length != 1000) + { + printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " + "expected min=100x100, max=1000x1000)\n", minsize.width, + minsize.length, maxsize.width, maxsize.length); + status ++; + } + else + puts("PASS"); + } + else + { + puts("FAIL (returned 0)"); + status ++; + } + + ppdMarkOption(ppd, "Quality", "Photo"); + + fputs("ppdPageSizeLimits(Quality=Photo): ", stdout); + if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) + { + if (minsize.width != 200 || minsize.length != 200 || + maxsize.width != 1000 || maxsize.length != 1000) + { + printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " + "expected min=200x200, max=1000x1000)\n", minsize.width, + minsize.length, maxsize.width, maxsize.length); + status ++; + } + else + puts("PASS"); + } + else + { + puts("FAIL (returned 0)"); + status ++; + } + + ppdMarkOption(ppd, "InputSlot", "Tray"); + + fputs("ppdPageSizeLimits(Quality=Photo): ", stdout); + if (ppdPageSizeLimits(ppd, &minsize, &maxsize)) + { + if (minsize.width != 300 || minsize.length != 300 || + maxsize.width != 1080 || maxsize.length != 86400) + { + printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, " + "expected min=300x300, max=1080x86400)\n", minsize.width, + minsize.length, maxsize.width, maxsize.length); + status ++; + } + else + puts("PASS"); + } + else + { + puts("FAIL (returned 0)"); + status ++; + } + } + else + { + const char *filename; /* PPD filename */ + struct stat fileinfo; /* File information */ + + + if (!strncmp(argv[1], "-d", 2)) + { + const char *printer; /* Printer name */ + + if (argv[1][2]) + printer = argv[1] + 2; + else if (argv[2]) + printer = argv[2]; + else + { + puts("Usage: ./testppd -d printer"); + return (1); + } + + filename = cupsGetPPD(printer); + + if (!filename) + { + printf("%s: %s\n", printer, cupsLastErrorString()); + return (1); + } + } + else + filename = argv[1]; + + if (lstat(filename, &fileinfo)) + { + printf("%s: %s\n", filename, strerror(errno)); + return (1); + } + + if (S_ISLNK(fileinfo.st_mode)) + { + char realfile[1024]; /* Real file path */ + ssize_t realsize; /* Size of real file path */ + + + if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0) + strcpy(realfile, "Unknown"); + else + realfile[realsize] = '\0'; + + if (stat(realfile, &fileinfo)) + printf("%s: symlink to \"%s\", %s\n", filename, realfile, + strerror(errno)); + else + printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile, + (long)fileinfo.st_size); + } + else + printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size); + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + ppd_status_t err; /* Last error in file */ + int line; /* Line number in file */ + + + status ++; + err = ppdLastError(&line); + + printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line); + } + else + { + int j, k; /* Looping vars */ + ppd_group_t *group; /* Option group */ + ppd_option_t *option; /* Option */ + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + ppd_const_t *c; /* UIConstraints */ + char lang[255], /* LANG environment variable */ + lc_all[255], /* LC_ALL environment variable */ + lc_ctype[255], /* LC_CTYPE environment variable */ + lc_messages[255];/* LC_MESSAGES environment variable */ + + + if (argc > 2) + { + snprintf(lang, sizeof(lang), "LANG=%s", argv[2]); + putenv(lang); + snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]); + putenv(lc_all); + snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]); + putenv(lc_ctype); + snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]); + putenv(lc_messages); + } + + ppdLocalize(ppd); + ppdMarkDefaults(ppd); + + if (argc > 3) + { + text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer)); + printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3], + text ? text : "(null)"); + return (text == NULL); + } + + for (i = ppd->num_groups, group = ppd->groups; + i > 0; + i --, group ++) + { + printf("%s (%s):\n", group->name, group->text); + + for (j = group->num_options, option = group->options; + j > 0; + j --, option ++) + { + printf(" %s (%s):\n", option->keyword, option->text); + + for (k = 0; k < option->num_choices; k ++) + printf(" - %s%s (%s)\n", + option->choices[k].marked ? "*" : "", + option->choices[k].choice, option->choices[k].text); + + if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL) + { + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + { + switch (cparam->type) + { + case PPD_CUSTOM_CURVE : + printf(" %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n", + cparam->name, cparam->text, + cparam->minimum.custom_curve, + cparam->maximum.custom_curve); + break; + + case PPD_CUSTOM_INT : + printf(" %s(%s): PPD_CUSTOM_INT (%d to %d)\n", + cparam->name, cparam->text, + cparam->minimum.custom_int, + cparam->maximum.custom_int); + break; + + case PPD_CUSTOM_INVCURVE : + printf(" %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n", + cparam->name, cparam->text, + cparam->minimum.custom_invcurve, + cparam->maximum.custom_invcurve); + break; + + case PPD_CUSTOM_PASSCODE : + printf(" %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n", + cparam->name, cparam->text, + cparam->minimum.custom_passcode, + cparam->maximum.custom_passcode); + break; + + case PPD_CUSTOM_PASSWORD : + printf(" %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n", + cparam->name, cparam->text, + cparam->minimum.custom_password, + cparam->maximum.custom_password); + break; + + case PPD_CUSTOM_POINTS : + printf(" %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n", + cparam->name, cparam->text, + cparam->minimum.custom_points, + cparam->maximum.custom_points); + break; + + case PPD_CUSTOM_REAL : + printf(" %s(%s): PPD_CUSTOM_REAL (%g to %g)\n", + cparam->name, cparam->text, + cparam->minimum.custom_real, + cparam->maximum.custom_real); + break; + + case PPD_CUSTOM_STRING : + printf(" %s(%s): PPD_CUSTOM_STRING (%d to %d)\n", + cparam->name, cparam->text, + cparam->minimum.custom_string, + cparam->maximum.custom_string); + break; + } + } + } + } + } + + puts("\nConstraints:"); + + for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) + printf(" *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1, + c->option2, c->choice2); + if (ppd->num_consts == 0) + puts(" NO CONSTRAINTS"); + + puts("\nFilters:"); + + for (i = 0; i < ppd->num_filters; i ++) + printf(" %s\n", ppd->filters[i]); + + if (ppd->num_filters == 0) + puts(" NO FILTERS"); + + puts("\nAttributes:"); + + for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs); + attr; + attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) + printf(" *%s %s/%s: \"%s\"\n", attr->name, attr->spec, + attr->text, attr->value ? attr->value : ""); + } + + if (!strncmp(argv[1], "-d", 2)) + unlink(filename); + } + +#ifdef __APPLE__ + if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact")) + { + char command[1024]; /* malloc_history command */ + + snprintf(command, sizeof(command), "malloc_history %d -all_by_size", + getpid()); + fflush(stdout); + system(command); + } +#endif /* __APPLE__ */ + + ppdClose(ppd); + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testpwg.c b/cups/testpwg.c new file mode 100644 index 0000000000..f15e11e4c2 --- /dev/null +++ b/cups/testpwg.c @@ -0,0 +1,495 @@ +/* + * "$Id$" + * + * PWG test program for CUPS. + * + * Copyright 2009-2010 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * test_pagesize() - Test the PWG mapping functions. + * test_pwg() - Test the PWG mapping functions. + */ + +/* + * Include necessary headers... + */ + +#include "ppd-private.h" +#include "file-private.h" + + +/* + * Local functions... + */ + +static int test_pwg(_pwg_t *pwg, ppd_file_t *ppd); +static int test_pagesize(_pwg_t *pwg, ppd_file_t *ppd, + const char *ppdsize); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int status; /* Status of tests (0 = success, 1 = fail) */ + const char *ppdfile; /* PPD filename */ + ppd_file_t *ppd; /* PPD file */ + _pwg_t *pwg; /* PWG mapping data */ + _pwg_media_t *pwgmedia; /* PWG media size */ + + + status = 0; + + if (argc < 2 || argc > 3) + { + puts("Usage: ./testpwg filename.ppd [jobfile]"); + return (1); + } + + ppdfile = argv[1]; + + printf("ppdOpenFile(%s): ", ppdfile); + if ((ppd = ppdOpenFile(ppdfile)) == NULL) + { + ppd_status_t err; /* Last error in file */ + int line; /* Line number in file */ + + + err = ppdLastError(&line); + + printf("FAIL (%s on line %d)\n", ppdErrorString(err), line); + + return (1); + } + else + puts("PASS"); + + fputs("_pwgCreateWithPPD(ppd): ", stdout); + if ((pwg = _pwgCreateWithPPD(ppd)) == NULL) + { + puts("FAIL"); + status ++; + } + else + { + puts("PASS"); + status += test_pwg(pwg, ppd); + + if (argc == 3) + { + /* + * Test PageSize mapping code. + */ + + int fd; /* Job file descriptor */ + const char *pagesize; /* PageSize value */ + ipp_t *job; /* Job attributes */ + ipp_attribute_t *media; /* Media attribute */ + + if ((fd = open(argv[2], O_RDONLY)) >= 0) + { + job = ippNew(); + ippReadFile(fd, job); + close(fd); + + if ((media = ippFindAttribute(job, "media", IPP_TAG_ZERO)) != NULL && + media->value_tag != IPP_TAG_NAME && + media->value_tag != IPP_TAG_KEYWORD) + media = NULL; + + if (media) + printf("_pwgGetPageSize(media=%s): ", media->values[0].string.text); + else + fputs("_pwgGetPageSize(media-col): ", stdout); + + fflush(stdout); + + if ((pagesize = _pwgGetPageSize(pwg, job, NULL, NULL)) == NULL) + { + puts("FAIL (Not Found)"); + status = 1; + } + else if (media && strcasecmp(pagesize, media->values[0].string.text)) + { + printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize, + media->values[0].string.text); + status = 1; + } + else + printf("PASS (%s)\n", pagesize); + + ippDelete(job); + } + else + { + perror(argv[2]); + status = 1; + } + } + + /* + * _pwgDestroy should never fail... + */ + + fputs("_pwgDestroy(pwg): ", stdout); + _pwgDestroy(pwg); + puts("PASS"); + } + + fputs("_pwgMediaForPWG(\"iso_a4_210x297mm\"): ", stdout); + if ((pwgmedia = _pwgMediaForPWG("iso_a4_210x297mm")) == NULL) + { + puts("FAIL (not found)"); + status ++; + } + else if (strcmp(pwgmedia->pwg, "iso_a4_210x297mm")) + { + printf("FAIL (%s)\n", pwgmedia->pwg); + status ++; + } + else if (pwgmedia->width != 21000 || pwgmedia->length != 29700) + { + printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length); + status ++; + } + else + puts("PASS"); + + fputs("_pwgMediaForLegacy(\"na-letter\"): ", stdout); + if ((pwgmedia = _pwgMediaForLegacy("na-letter")) == NULL) + { + puts("FAIL (not found)"); + status ++; + } + else if (strcmp(pwgmedia->pwg, "na_letter_8.5x11in")) + { + printf("FAIL (%s)\n", pwgmedia->pwg); + status ++; + } + else if (pwgmedia->width != 21590 || pwgmedia->length != 27940) + { + printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length); + status ++; + } + else + puts("PASS"); + + fputs("_pwgMediaForPPD(\"4x6\"): ", stdout); + if ((pwgmedia = _pwgMediaForPPD("4x6")) == NULL) + { + puts("FAIL (not found)"); + status ++; + } + else if (strcmp(pwgmedia->pwg, "na_index-4x6_4x6in")) + { + printf("FAIL (%s)\n", pwgmedia->pwg); + status ++; + } + else if (pwgmedia->width != 10160 || pwgmedia->length != 15240) + { + printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length); + status ++; + } + else + puts("PASS"); + + fputs("_pwgMediaForPPD(\"10x15cm\"): ", stdout); + if ((pwgmedia = _pwgMediaForPPD("10x15cm")) == NULL) + { + puts("FAIL (not found)"); + status ++; + } + else if (strcmp(pwgmedia->pwg, "om_100x150mm_100x150mm")) + { + printf("FAIL (%s)\n", pwgmedia->pwg); + status ++; + } + else if (pwgmedia->width != 10000 || pwgmedia->length != 15000) + { + printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length); + status ++; + } + else + puts("PASS"); + + fputs("_pwgMediaForPPD(\"Custom.10x15cm\"): ", stdout); + if ((pwgmedia = _pwgMediaForPPD("Custom.10x15cm")) == NULL) + { + puts("FAIL (not found)"); + status ++; + } + else if (strcmp(pwgmedia->pwg, "custom_10x15cm_100x150mm")) + { + printf("FAIL (%s)\n", pwgmedia->pwg); + status ++; + } + else if (pwgmedia->width != 10000 || pwgmedia->length != 15000) + { + printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length); + status ++; + } + else + puts("PASS"); + + fputs("_pwgMediaForSize(29700, 42000): ", stdout); + if ((pwgmedia = _pwgMediaForSize(29700, 42000)) == NULL) + { + puts("FAIL (not found)"); + status ++; + } + else if (strcmp(pwgmedia->pwg, "iso_a3_297x420mm")) + { + printf("FAIL (%s)\n", pwgmedia->pwg); + status ++; + } + else + puts("PASS"); + + return (status); +} + + +/* + * 'test_pagesize()' - Test the PWG mapping functions. + */ + +static int /* O - 1 on failure, 0 on success */ +test_pagesize(_pwg_t *pwg, /* I - PWG mapping data */ + ppd_file_t *ppd, /* I - PPD file */ + const char *ppdsize) /* I - PPD page size */ +{ + int status = 0; /* Return status */ + ipp_t *job; /* Job attributes */ + const char *pagesize; /* PageSize value */ + + + if (ppdPageSize(ppd, ppdsize)) + { + printf("_pwgGetPageSize(keyword=%s): ", ppdsize); + fflush(stdout); + + if ((pagesize = _pwgGetPageSize(pwg, NULL, ppdsize, NULL)) == NULL) + { + puts("FAIL (Not Found)"); + status = 1; + } + else if (strcasecmp(pagesize, ppdsize)) + { + printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize, ppdsize); + status = 1; + } + else + puts("PASS"); + + job = ippNew(); + ippAddString(job, IPP_TAG_JOB, IPP_TAG_KEYWORD, "media", NULL, ppdsize); + + printf("_pwgGetPageSize(media=%s): ", ppdsize); + fflush(stdout); + + if ((pagesize = _pwgGetPageSize(pwg, job, NULL, NULL)) == NULL) + { + puts("FAIL (Not Found)"); + status = 1; + } + else if (strcasecmp(pagesize, ppdsize)) + { + printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize, ppdsize); + status = 1; + } + else + puts("PASS"); + + ippDelete(job); + } + + return (status); +} + + +/* + * 'test_pwg()' - Test the PWG mapping functions. + */ + +static int /* O - 1 on failure, 0 on success */ +test_pwg(_pwg_t *pwg, /* I - PWG mapping data */ + ppd_file_t *ppd) /* I - PPD file */ +{ + int i, /* Looping var */ + status = 0; /* Return status */ + _pwg_t *pwg2; /* Loaded data */ + _pwg_size_t *size, /* Size from original */ + *size2; /* Size from saved */ + _pwg_map_t *map, /* Map from original */ + *map2; /* Map from saved */ + + + /* + * Verify that we can write and read back the same data... + */ + + fputs("_pwgWriteFile(test.pwg): ", stdout); + if (!_pwgWriteFile(pwg, "test.pwg")) + { + puts("FAIL"); + status ++; + } + else + puts("PASS"); + + fputs("_pwgCreateWithFile(test.pwg): ", stdout); + if ((pwg2 = _pwgCreateWithFile("test.pwg")) == NULL) + { + puts("FAIL"); + status ++; + } + else + { + if (pwg2->num_sizes != pwg->num_sizes) + { + if (!status) + puts("FAIL"); + + printf(" SAVED num_sizes=%d, ORIG num_sizes=%d\n", pwg2->num_sizes, + pwg->num_sizes); + + status ++; + } + else + { + for (i = pwg->num_sizes, size = pwg->sizes, size2 = pwg2->sizes; + i > 0; + i --, size ++, size2 ++) + { + if (strcmp(size2->map.pwg, size->map.pwg) || + strcmp(size2->map.ppd, size->map.ppd) || + size2->width != size->width || + size2->length != size->length || + size2->left != size->left || + size2->bottom != size->bottom || + size2->right != size->right || + size2->top != size->top) + { + if (!status) + puts("FAIL"); + + if (strcmp(size->map.pwg, size2->map.pwg)) + printf(" SAVED size->map.pwg=\"%s\", ORIG " + "size->map.pwg=\"%s\"\n", size2->map.pwg, size->map.pwg); + + if (strcmp(size2->map.ppd, size->map.ppd)) + printf(" SAVED size->map.ppd=\"%s\", ORIG " + "size->map.ppd=\"%s\"\n", size2->map.ppd, size->map.ppd); + + if (size2->width != size->width) + printf(" SAVED size->width=%d, ORIG size->width=%d\n", + size2->width, size->width); + + if (size2->length != size->length) + printf(" SAVED size->length=%d, ORIG size->length=%d\n", + size2->length, size->length); + + if (size2->left != size->left) + printf(" SAVED size->left=%d, ORIG size->left=%d\n", + size2->left, size->left); + + if (size2->bottom != size->bottom) + printf(" SAVED size->bottom=%d, ORIG size->bottom=%d\n", + size2->bottom, size->bottom); + + if (size2->right != size->right) + printf(" SAVED size->right=%d, ORIG size->right=%d\n", + size2->right, size->right); + + if (size2->top != size->top) + printf(" SAVED size->top=%d, ORIG size->top=%d\n", + size2->top, size->top); + + status ++; + break; + } + } + + for (i = pwg->num_sources, map = pwg->sources, map2 = pwg2->sources; + i > 0; + i --, map ++, map2 ++) + { + if (strcmp(map2->pwg, map->pwg) || + strcmp(map2->ppd, map->ppd)) + { + if (!status) + puts("FAIL"); + + if (strcmp(map->pwg, map2->pwg)) + printf(" SAVED source->pwg=\"%s\", ORIG source->pwg=\"%s\"\n", + map2->pwg, map->pwg); + + if (strcmp(map2->ppd, map->ppd)) + printf(" SAVED source->ppd=\"%s\", ORIG source->ppd=\"%s\"\n", + map2->ppd, map->ppd); + + status ++; + break; + } + } + + for (i = pwg->num_types, map = pwg->types, map2 = pwg2->types; + i > 0; + i --, map ++, map2 ++) + { + if (strcmp(map2->pwg, map->pwg) || + strcmp(map2->ppd, map->ppd)) + { + if (!status) + puts("FAIL"); + + if (strcmp(map->pwg, map2->pwg)) + printf(" SAVED type->pwg=\"%s\", ORIG type->pwg=\"%s\"\n", + map2->pwg, map->pwg); + + if (strcmp(map2->ppd, map->ppd)) + printf(" SAVED type->ppd=\"%s\", ORIG type->ppd=\"%s\"\n", + map2->ppd, map->ppd); + + status ++; + break; + } + } + } + + if (!status) + puts("PASS"); + + _pwgDestroy(pwg2); + } + + /* + * Test PageSize mapping code... + */ + + status += test_pagesize(pwg, ppd, "Letter"); + status += test_pagesize(pwg, ppd, "na-letter"); + status += test_pagesize(pwg, ppd, "A4"); + status += test_pagesize(pwg, ppd, "iso-a4"); + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testsnmp.c b/cups/testsnmp.c new file mode 100644 index 0000000000..52983a9684 --- /dev/null +++ b/cups/testsnmp.c @@ -0,0 +1,307 @@ +/* + * "$Id$" + * + * SNMP test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2008-2009 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * scan_oid() - Scan an OID value. + * show_oid() - Show the specified OID. + * usage() - Show program usage and exit. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include "string.h" +#include "snmp-private.h" + + +/* + * Local functions... + */ + +static void print_packet(cups_snmp_t *packet, void *data); +static int show_oid(int fd, const char *community, + http_addr_t *addr, const char *s, int walk); +static void usage(void); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int fd = -1; /* SNMP socket */ + http_addrlist_t *host = NULL; /* Address of host */ + int walk = 0; /* Walk OIDs? */ + char *oid = NULL; /* Last OID shown */ + const char *community; /* Community name */ + + + fputs("_cupsSNMPDefaultCommunity: ", stdout); + + if ((community = _cupsSNMPDefaultCommunity()) == NULL) + { + puts("FAIL (NULL community name)"); + return (1); + } + + printf("PASS (%s)\n", community); + + /* + * Query OIDs from the command-line... + */ + + for (i = 1; i < argc; i ++) + if (!strcmp(argv[i], "-c")) + { + i ++; + + if (i >= argc) + usage(); + else + community = argv[i]; + } + else if (!strcmp(argv[i], "-d")) + _cupsSNMPSetDebug(10); + else if (!strcmp(argv[i], "-w")) + walk = 1; + else if (!host) + { + if ((host = httpAddrGetList(argv[i], AF_UNSPEC, "161")) == NULL) + { + printf("testsnmp: Unable to find \"%s\"!\n", argv[1]); + return (1); + } + + if (fd < 0) + { + fputs("_cupsSNMPOpen: ", stdout); + + if ((fd = _cupsSNMPOpen(host->addr.addr.sa_family)) < 0) + { + printf("FAIL (%s)\n", strerror(errno)); + return (1); + } + + puts("PASS"); + } + } + else if (!show_oid(fd, community, &(host->addr), argv[i], walk)) + return (1); + else + oid = argv[i]; + + if (!host) + usage(); + + if (!oid) + { + if (!show_oid(fd, community, &(host->addr), + walk ? ".1.3.6.1.2.1.43" : + ".1.3.6.1.2.1.43.10.2.1.4.1.1", walk)) + return (1); + } + + return (0); +} + + +/* + * 'print_packet()' - Print the contents of the response packet. + */ + +static void +print_packet(cups_snmp_t *packet, /* I - SNMP response packet */ + void *data) /* I - User data pointer (not used) */ +{ + int i; /* Looping var */ + char temp[1024]; /* Temporary OID string */ + + + (void)data; + + printf("%s = ", _cupsSNMPOIDToString(packet->object_name, temp, sizeof(temp))); + + switch (packet->object_type) + { + case CUPS_ASN1_BOOLEAN : + printf("BOOLEAN %s\n", + packet->object_value.boolean ? "TRUE" : "FALSE"); + break; + + case CUPS_ASN1_INTEGER : + printf("INTEGER %d\n", packet->object_value.integer); + break; + + case CUPS_ASN1_BIT_STRING : + printf("BIT-STRING \"%s\"\n", + (char *)packet->object_value.string.bytes); + break; + + case CUPS_ASN1_OCTET_STRING : + printf("OCTET-STRING \"%s\"\n", + (char *)packet->object_value.string.bytes); + break; + + case CUPS_ASN1_NULL_VALUE : + puts("NULL-VALUE"); + break; + + case CUPS_ASN1_OID : + printf("OID %s\n", _cupsSNMPOIDToString(packet->object_value.oid, + temp, sizeof(temp))); + break; + + case CUPS_ASN1_HEX_STRING : + fputs("Hex-STRING", stdout); + for (i = 0; i < packet->object_value.string.num_bytes; i ++) + printf(" %02X", packet->object_value.string.bytes[i]); + putchar('\n'); + break; + + case CUPS_ASN1_COUNTER : + printf("Counter %d\n", packet->object_value.counter); + break; + + case CUPS_ASN1_GAUGE : + printf("Gauge %u\n", packet->object_value.gauge); + break; + + case CUPS_ASN1_TIMETICKS : + printf("Timeticks %u days, %u:%02u:%02u.%02u\n", + packet->object_value.timeticks / 8640000, + (packet->object_value.timeticks / 360000) % 24, + (packet->object_value.timeticks / 6000) % 60, + (packet->object_value.timeticks / 100) % 60, + packet->object_value.timeticks % 100); + break; + + default : + printf("Unknown-%X\n", packet->object_type); + break; + } +} + + +/* + * 'show_oid()' - Show the specified OID. + */ + +static int /* O - 1 on success, 0 on error */ +show_oid(int fd, /* I - SNMP socket */ + const char *community, /* I - Community name */ + http_addr_t *addr, /* I - Address to query */ + const char *s, /* I - OID to query */ + int walk) /* I - Walk OIDs? */ +{ + int i; /* Looping var */ + int oid[CUPS_SNMP_MAX_OID]; /* OID */ + cups_snmp_t packet; /* SNMP packet */ + char temp[1024]; /* Temporary OID string */ + + + if (!_cupsSNMPStringToOID(s, oid, sizeof(oid) / sizeof(oid[0]))) + { + puts("testsnmp: Bad OID"); + return (0); + } + + if (walk) + { + printf("_cupsSNMPWalk(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp))); + + if (_cupsSNMPWalk(fd, addr, CUPS_SNMP_VERSION_1, community, oid, 5.0, + print_packet, NULL) < 0) + { + printf("FAIL (%s)\n", strerror(errno)); + return (0); + } + } + else + { + printf("_cupsSNMPWrite(%s): ", _cupsSNMPOIDToString(oid, temp, sizeof(temp))); + + if (!_cupsSNMPWrite(fd, addr, CUPS_SNMP_VERSION_1, community, + CUPS_ASN1_GET_REQUEST, 1, oid)) + { + printf("FAIL (%s)\n", strerror(errno)); + return (0); + } + + puts("PASS"); + + fputs("_cupsSNMPRead(5.0): ", stdout); + + if (!_cupsSNMPRead(fd, &packet, 5.0)) + { + puts("FAIL (timeout)"); + return (0); + } + + if (!_cupsSNMPIsOID(&packet, oid)) + { + printf("FAIL (bad OID %d", packet.object_name[0]); + for (i = 1; packet.object_name[i] >= 0; i ++) + printf(".%d", packet.object_name[i]); + puts(")"); + return (0); + } + + if (packet.error) + { + printf("FAIL (%s)\n", packet.error); + return (0); + } + + puts("PASS"); + + print_packet(&packet, NULL); + } + + return (1); +} + + +/* + * 'usage()' - Show program usage and exit. + */ + +static void +usage(void) +{ + puts("Usage: testsnmp [options] host-or-ip [oid ...]"); + puts(""); + puts("Options:"); + puts(""); + puts(" -c community Set community name"); + puts(" -d Enable debugging"); + puts(" -w Walk all OIDs under the specified one"); + + exit (1); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/transcode.c b/cups/transcode.c new file mode 100644 index 0000000000..93bd4419d1 --- /dev/null +++ b/cups/transcode.c @@ -0,0 +1,1826 @@ +/* + * "$Id$" + * + * Transcoding support for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsCharmapFlush() - Flush all character set maps out of cache. + * _cupsCharmapFree() - Free a character set map. + * _cupsCharmapGet() - Get a character set map. + * cupsCharsetToUTF8() - Convert legacy character set to UTF-8. + * cupsUTF8ToCharset() - Convert UTF-8 to legacy character set. + * cupsUTF8ToUTF32() - Convert UTF-8 to UTF-32. + * cupsUTF32ToUTF8() - Convert UTF-32 to UTF-8. + * compare_wide() - Compare key for wide (VBCS) match. + * conv_sbcs_to_utf8() - Convert legacy SBCS to UTF-8. + * conv_utf8_to_sbcs() - Convert UTF-8 to legacy SBCS. + * conv_utf8_to_vbcs() - Convert UTF-8 to legacy DBCS/VBCS. + * conv_vbcs_to_utf8() - Convert legacy DBCS/VBCS to UTF-8. + * free_sbcs_charmap() - Free memory used by a single byte character set. + * free_vbcs_charmap() - Free memory used by a variable byte character set. + * get_charmap() - Lookup or get a character set map (private). + * get_charmap_count() - Count lines in a charmap file. + * get_sbcs_charmap() - Get SBCS Charmap. + * get_vbcs_charmap() - Get DBCS/VBCS Charmap. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include +#include +#include +#include + + +/* + * Local globals... + */ + +#ifdef HAVE_PTHREAD_H +static pthread_mutex_t map_mutex = PTHREAD_MUTEX_INITIALIZER; + /* Mutex to control access to maps */ +#endif /* HAVE_PTHREAD_H */ +static _cups_cmap_t *cmap_cache = NULL; + /* SBCS Charmap Cache */ +static _cups_vmap_t *vmap_cache = NULL; + /* VBCS Charmap Cache */ + + +/* + * Local functions... + */ + +static int compare_wide(const void *k1, const void *k2); +static int conv_sbcs_to_utf8(cups_utf8_t *dest, + const cups_sbcs_t *src, + int maxout, + const cups_encoding_t encoding); +static int conv_utf8_to_sbcs(cups_sbcs_t *dest, + const cups_utf8_t *src, + int maxout, + const cups_encoding_t encoding); +static int conv_utf8_to_vbcs(cups_sbcs_t *dest, + const cups_utf8_t *src, + int maxout, + const cups_encoding_t encoding); +static int conv_vbcs_to_utf8(cups_utf8_t *dest, + const cups_sbcs_t *src, + int maxout, + const cups_encoding_t encoding); +static void free_sbcs_charmap(_cups_cmap_t *sbcs); +static void free_vbcs_charmap(_cups_vmap_t *vbcs); +static void *get_charmap(const cups_encoding_t encoding); +static int get_charmap_count(cups_file_t *fp); +static _cups_cmap_t *get_sbcs_charmap(const cups_encoding_t encoding, + const char *filename); +static _cups_vmap_t *get_vbcs_charmap(const cups_encoding_t encoding, + const char *filename); + + +/* + * '_cupsCharmapFlush()' - Flush all character set maps out of cache. + */ + +void +_cupsCharmapFlush(void) +{ + _cups_cmap_t *cmap, /* Legacy SBCS / Unicode Charset Map */ + *cnext; /* Next Legacy SBCS Charset Map */ + _cups_vmap_t *vmap, /* Legacy VBCS / Unicode Charset Map */ + *vnext; /* Next Legacy VBCS Charset Map */ + + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + /* + * Loop through SBCS charset map cache, free all memory... + */ + + for (cmap = cmap_cache; cmap; cmap = cnext) + { + cnext = cmap->next; + + free_sbcs_charmap(cmap); + } + + cmap_cache = NULL; + + /* + * Loop through DBCS/VBCS charset map cache, free all memory... + */ + + for (vmap = vmap_cache; vmap; vmap = vnext) + { + vnext = vmap->next; + + free_vbcs_charmap(vmap); + } + + vmap_cache = NULL; + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * '_cupsCharmapFree()' - Free a character set map. + * + * This does not actually free; use '_cupsCharmapFlush()' for that. + */ + +void +_cupsCharmapFree( + const cups_encoding_t encoding) /* I - Encoding */ +{ + _cups_cmap_t *cmap; /* Legacy SBCS / Unicode Charset Map */ + _cups_vmap_t *vmap; /* Legacy VBCS / Unicode Charset Map */ + + + /* + * See if we already have this SBCS charset map loaded... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + for (cmap = cmap_cache; cmap; cmap = cmap->next) + { + if (cmap->encoding == encoding) + { + if (cmap->used > 0) + cmap->used --; + break; + } + } + + /* + * See if we already have this DBCS/VBCS charset map loaded... + */ + + for (vmap = vmap_cache; vmap; vmap = vmap->next) + { + if (vmap->encoding == encoding) + { + if (vmap->used > 0) + vmap->used --; + break; + } + } + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ +} + + +/* + * '_cupsCharmapGet()' - Get a character set map. + * + * This code handles single-byte (SBCS), double-byte (DBCS), and + * variable-byte (VBCS) character sets _without_ charset escapes... + * This code does not handle multiple-byte character sets (MBCS) + * (such as ISO-2022-JP) with charset switching via escapes... + */ + +void * /* O - Charset map pointer */ +_cupsCharmapGet( + const cups_encoding_t encoding) /* I - Encoding */ +{ + void *charmap; /* Charset map pointer */ + + + DEBUG_printf(("7_cupsCharmapGet(encoding=%d)", encoding)); + + /* + * Check for valid arguments... + */ + + if (encoding < 0 || encoding >= CUPS_ENCODING_VBCS_END) + { + DEBUG_puts("8_cupsCharmapGet: Bad encoding, returning NULL!"); + return (NULL); + } + + /* + * Lookup or get the charset map pointer and return... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + charmap = get_charmap(encoding); + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (charmap); +} + + +/* + * 'cupsCharsetToUTF8()' - Convert legacy character set to UTF-8. + * + * This code handles single-byte (SBCS), double-byte (DBCS), and + * variable-byte (VBCS) character sets _without_ charset escapes... + * This code does not handle multiple-byte character sets (MBCS) + * (such as ISO-2022-JP) with charset switching via escapes... + */ + +int /* O - Count or -1 on error */ +cupsCharsetToUTF8( + cups_utf8_t *dest, /* O - Target string */ + const char *src, /* I - Source string */ + const int maxout, /* I - Max output */ + const cups_encoding_t encoding) /* I - Encoding */ +{ + int bytes; /* Number of bytes converted */ + + + /* + * Check for valid arguments... + */ + + DEBUG_printf(("2cupsCharsetToUTF8(dest=%p, src=\"%s\", maxout=%d, encoding=%d)", + dest, src, maxout, encoding)); + + if (dest) + *dest = '\0'; + + if (!dest || !src || maxout < 1 || maxout > CUPS_MAX_USTRING) + { + DEBUG_puts("3cupsCharsetToUTF8: Bad arguments, returning -1"); + return (-1); + } + + /* + * Handle identity conversions... + */ + + if (encoding == CUPS_UTF8 || encoding <= CUPS_US_ASCII || + encoding < 0 || encoding >= CUPS_ENCODING_VBCS_END) + { + strlcpy((char *)dest, src, maxout); + return ((int)strlen((char *)dest)); + } + + /* + * Handle ISO-8859-1 to UTF-8 directly... + */ + + if (encoding == CUPS_ISO8859_1) + { + int ch; /* Character from string */ + cups_utf8_t *destptr, /* Pointer into UTF-8 buffer */ + *destend; /* End of UTF-8 buffer */ + + + destptr = dest; + destend = dest + maxout - 2; + + while (*src && destptr < destend) + { + ch = *src++ & 255; + + if (ch & 128) + { + *destptr++ = 0xc0 | (ch >> 6); + *destptr++ = 0x80 | (ch & 0x3f); + } + else + *destptr++ = ch; + } + + *destptr = '\0'; + + return ((int)(destptr - dest)); + } + + /* + * Convert input legacy charset to UTF-8... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + if (encoding < CUPS_ENCODING_SBCS_END) + bytes = conv_sbcs_to_utf8(dest, (cups_sbcs_t *)src, maxout, encoding); + else + bytes = conv_vbcs_to_utf8(dest, (cups_sbcs_t *)src, maxout, encoding); + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (bytes); +} + + +/* + * 'cupsUTF8ToCharset()' - Convert UTF-8 to legacy character set. + * + * This code handles single-byte (SBCS), double-byte (DBCS), and + * variable-byte (VBCS) character sets _without_ charset escapes... + * This code does not handle multiple-byte character sets (MBCS) + * (such as ISO-2022-JP) with charset switching via escapes... + */ + +int /* O - Count or -1 on error */ +cupsUTF8ToCharset( + char *dest, /* O - Target string */ + const cups_utf8_t *src, /* I - Source string */ + const int maxout, /* I - Max output */ + const cups_encoding_t encoding) /* I - Encoding */ +{ + int bytes; /* Number of bytes converted */ + + + /* + * Check for valid arguments... + */ + + if (!dest || !src || maxout < 1 || maxout > CUPS_MAX_USTRING) + { + if (dest) + *dest = '\0'; + + return (-1); + } + + /* + * Handle identity conversions... + */ + + if (encoding == CUPS_UTF8 || + encoding < 0 || encoding >= CUPS_ENCODING_VBCS_END) + { + strlcpy(dest, (char *)src, maxout); + return ((int)strlen(dest)); + } + + /* + * Handle UTF-8 to ISO-8859-1 directly... + */ + + if (encoding == CUPS_ISO8859_1 || encoding == CUPS_US_ASCII) + { + int ch, /* Character from string */ + maxch; /* Maximum character for charset */ + char *destptr, /* Pointer into ISO-8859-1 buffer */ + *destend; /* End of ISO-8859-1 buffer */ + + maxch = encoding == CUPS_ISO8859_1 ? 256 : 128; + destptr = dest; + destend = dest + maxout - 1; + + while (*src && destptr < destend) + { + ch = *src++; + + if ((ch & 0xe0) == 0xc0) + { + ch = ((ch & 0x1f) << 6) | (*src++ & 0x3f); + + if (ch < maxch) + *destptr++ = ch; + else + *destptr++ = '?'; + } + else if ((ch & 0xf0) == 0xe0 || + (ch & 0xf8) == 0xf0) + *destptr++ = '?'; + else if (!(ch & 0x80)) + *destptr++ = ch; + } + + *destptr = '\0'; + + return ((int)(destptr - dest)); + } + + /* + * Convert input UTF-8 to legacy charset... + */ + +#ifdef HAVE_PTHREAD_H + pthread_mutex_lock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + if (encoding < CUPS_ENCODING_SBCS_END) + bytes = conv_utf8_to_sbcs((cups_sbcs_t *)dest, src, maxout, encoding); + else + bytes = conv_utf8_to_vbcs((cups_sbcs_t *)dest, src, maxout, encoding); + +#ifdef HAVE_PTHREAD_H + pthread_mutex_unlock(&map_mutex); +#endif /* HAVE_PTHREAD_H */ + + return (bytes); +} + + +/* + * 'cupsUTF8ToUTF32()' - Convert UTF-8 to UTF-32. + * + * 32-bit UTF-32 (actually 21-bit) maps to UTF-8 as follows... + * + * UTF-32 char UTF-8 char(s) + * -------------------------------------------------- + * 0 to 127 = 0xxxxxxx (US-ASCII) + * 128 to 2047 = 110xxxxx 10yyyyyy + * 2048 to 65535 = 1110xxxx 10yyyyyy 10zzzzzz + * > 65535 = 11110xxx 10yyyyyy 10zzzzzz 10xxxxxx + * + * UTF-32 prohibits chars beyond Plane 16 (> 0x10ffff) in UCS-4, + * which would convert to five- or six-octet UTF-8 sequences... + */ + +int /* O - Count or -1 on error */ +cupsUTF8ToUTF32( + cups_utf32_t *dest, /* O - Target string */ + const cups_utf8_t *src, /* I - Source string */ + const int maxout) /* I - Max output */ +{ + int i; /* Looping variable */ + cups_utf8_t ch; /* Character value */ + cups_utf8_t next; /* Next character value */ + cups_utf32_t ch32; /* UTF-32 character value */ + + + /* + * Check for valid arguments and clear output... + */ + + DEBUG_printf(("2cupsUTF8ToUTF32(dest=%p, src=\"%s\", maxout=%d)", dest, + src, maxout)); + + if (dest) + *dest = 0; + + if (!dest || !src || maxout < 1 || maxout > CUPS_MAX_USTRING) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad arguments)"); + + return (-1); + } + + /* + * Convert input UTF-8 to output UTF-32... + */ + + for (i = maxout - 1; *src && i > 0; i --) + { + ch = *src++; + + /* + * Convert UTF-8 character(s) to UTF-32 character... + */ + + if (!(ch & 0x80)) + { + /* + * One-octet UTF-8 <= 127 (US-ASCII)... + */ + + *dest++ = ch; + + DEBUG_printf(("4cupsUTF8ToUTF32: %02x => %08X", src[-1], ch)); + continue; + } + else if ((ch & 0xe0) == 0xc0) + { + /* + * Two-octet UTF-8 <= 2047 (Latin-x)... + */ + + next = *src++; + if ((next & 0xc0) != 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + ch32 = ((ch & 0x1f) << 6) | (next & 0x3f); + + /* + * Check for non-shortest form (invalid UTF-8)... + */ + + if (ch32 < 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + *dest++ = ch32; + + DEBUG_printf(("4cupsUTF8ToUTF32: %02x %02x => %08X", + src[-2], src[-1], (unsigned)ch32)); + } + else if ((ch & 0xf0) == 0xe0) + { + /* + * Three-octet UTF-8 <= 65535 (Plane 0 - BMP)... + */ + + next = *src++; + if ((next & 0xc0) != 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + ch32 = ((ch & 0x0f) << 6) | (next & 0x3f); + + next = *src++; + if ((next & 0xc0) != 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + ch32 = (ch32 << 6) | (next & 0x3f); + + /* + * Check for non-shortest form (invalid UTF-8)... + */ + + if (ch32 < 0x800) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + *dest++ = ch32; + + DEBUG_printf(("4cupsUTF8ToUTF32: %02x %02x %02x => %08X", + src[-3], src[-2], src[-1], (unsigned)ch32)); + } + else if ((ch & 0xf8) == 0xf0) + { + /* + * Four-octet UTF-8... + */ + + next = *src++; + if ((next & 0xc0) != 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + ch32 = ((ch & 0x07) << 6) | (next & 0x3f); + + next = *src++; + if ((next & 0xc0) != 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + ch32 = (ch32 << 6) | (next & 0x3f); + + next = *src++; + if ((next & 0xc0) != 0x80) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + ch32 = (ch32 << 6) | (next & 0x3f); + + /* + * Check for non-shortest form (invalid UTF-8)... + */ + + if (ch32 < 0x10000) + { + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + *dest++ = ch32; + + DEBUG_printf(("4cupsUTF8ToUTF32: %02x %02x %02x %02x => %08X", + src[-4], src[-3], src[-2], src[-1], (unsigned)ch32)); + } + else + { + /* + * More than 4-octet (invalid UTF-8 sequence)... + */ + + DEBUG_puts("3cupsUTF8ToUTF32: Returning -1 (bad UTF-8 sequence)"); + + return (-1); + } + + /* + * Check for UTF-16 surrogate (illegal UTF-8)... + */ + + if (ch32 >= 0xd800 && ch32 <= 0xdfff) + return (-1); + } + + *dest = 0; + + DEBUG_printf(("3cupsUTF8ToUTF32: Returning %d characters", maxout - 1 - i)); + + return (maxout - 1 - i); +} + + +/* + * 'cupsUTF32ToUTF8()' - Convert UTF-32 to UTF-8. + * + * 32-bit UTF-32 (actually 21-bit) maps to UTF-8 as follows... + * + * UTF-32 char UTF-8 char(s) + * -------------------------------------------------- + * 0 to 127 = 0xxxxxxx (US-ASCII) + * 128 to 2047 = 110xxxxx 10yyyyyy + * 2048 to 65535 = 1110xxxx 10yyyyyy 10zzzzzz + * > 65535 = 11110xxx 10yyyyyy 10zzzzzz 10xxxxxx + * + * UTF-32 prohibits chars beyond Plane 16 (> 0x10ffff) in UCS-4, + * which would convert to five- or six-octet UTF-8 sequences... + */ + +int /* O - Count or -1 on error */ +cupsUTF32ToUTF8( + cups_utf8_t *dest, /* O - Target string */ + const cups_utf32_t *src, /* I - Source string */ + const int maxout) /* I - Max output */ +{ + cups_utf8_t *start; /* Start of destination string */ + int i; /* Looping variable */ + int swap; /* Byte-swap input to output */ + cups_utf32_t ch; /* Character value */ + + + /* + * Check for valid arguments and clear output... + */ + + DEBUG_printf(("2cupsUTF32ToUTF8(dest=%p, src=%p, maxout=%d)", dest, src, + maxout)); + + if (dest) + *dest = '\0'; + + if (!dest || !src || maxout < 1) + { + DEBUG_puts("3cupsUTF32ToUTF8: Returning -1 (bad args)"); + + return (-1); + } + + /* + * Check for leading BOM in UTF-32 and inverted BOM... + */ + + start = dest; + swap = *src == 0xfffe0000; + + DEBUG_printf(("4cupsUTF32ToUTF8: swap=%d", swap)); + + if (*src == 0xfffe0000 || *src == 0xfeff) + src ++; + + /* + * Convert input UTF-32 to output UTF-8... + */ + + for (i = maxout - 1; *src && i > 0;) + { + ch = *src++; + + /* + * Byte swap input UTF-32, if necessary... + * (only byte-swapping 24 of 32 bits) + */ + + if (swap) + ch = ((ch >> 24) | ((ch >> 8) & 0xff00) | ((ch << 8) & 0xff0000)); + + /* + * Check for beyond Plane 16 (invalid UTF-32)... + */ + + if (ch > 0x10ffff) + { + DEBUG_puts("3cupsUTF32ToUTF8: Returning -1 (character out of range)"); + + return (-1); + } + + /* + * Convert UTF-32 character to UTF-8 character(s)... + */ + + if (ch < 0x80) + { + /* + * One-octet UTF-8 <= 127 (US-ASCII)... + */ + + *dest++ = (cups_utf8_t)ch; + i --; + + DEBUG_printf(("4cupsUTF32ToUTF8: %08x => %02x", (unsigned)ch, dest[-1])); + } + else if (ch < 0x800) + { + /* + * Two-octet UTF-8 <= 2047 (Latin-x)... + */ + + if (i < 2) + { + DEBUG_puts("3cupsUTF32ToUTF8: Returning -1 (too long 2)"); + + return (-1); + } + + *dest++ = (cups_utf8_t)(0xc0 | ((ch >> 6) & 0x1f)); + *dest++ = (cups_utf8_t)(0x80 | (ch & 0x3f)); + i -= 2; + + DEBUG_printf(("4cupsUTF32ToUTF8: %08x => %02x %02x", (unsigned)ch, + dest[-2], dest[-1])); + } + else if (ch < 0x10000) + { + /* + * Three-octet UTF-8 <= 65535 (Plane 0 - BMP)... + */ + + if (i < 3) + { + DEBUG_puts("3cupsUTF32ToUTF8: Returning -1 (too long 3)"); + + return (-1); + } + + *dest++ = (cups_utf8_t)(0xe0 | ((ch >> 12) & 0x0f)); + *dest++ = (cups_utf8_t)(0x80 | ((ch >> 6) & 0x3f)); + *dest++ = (cups_utf8_t)(0x80 | (ch & 0x3f)); + i -= 3; + + DEBUG_printf(("4cupsUTF32ToUTF8: %08x => %02x %02x %02x", (unsigned)ch, + dest[-3], dest[-2], dest[-1])); + } + else + { + /* + * Four-octet UTF-8... + */ + + if (i < 4) + { + DEBUG_puts("3cupsUTF32ToUTF8: Returning -1 (too long 4)"); + + return (-1); + } + + *dest++ = (cups_utf8_t)(0xf0 | ((ch >> 18) & 0x07)); + *dest++ = (cups_utf8_t)(0x80 | ((ch >> 12) & 0x3f)); + *dest++ = (cups_utf8_t)(0x80 | ((ch >> 6) & 0x3f)); + *dest++ = (cups_utf8_t)(0x80 | (ch & 0x3f)); + i -= 4; + + DEBUG_printf(("4cupsUTF32ToUTF8: %08x => %02x %02x %02x %02x", + (unsigned)ch, dest[-4], dest[-3], dest[-2], dest[-1])); + } + } + + *dest = '\0'; + + DEBUG_printf(("3cupsUTF32ToUTF8: Returning %d", (int)(dest - start))); + + return ((int)(dest - start)); +} + + +/* + * 'compare_wide()' - Compare key for wide (VBCS) match. + */ + +static int +compare_wide(const void *k1, /* I - Key char */ + const void *k2) /* I - Map char */ +{ + cups_vbcs_t key; /* Legacy key character */ + cups_vbcs_t map; /* Legacy map character */ + + + key = *((cups_vbcs_t *)k1); + map = ((_cups_wide2uni_t *)k2)->widechar; + + return ((int)(key - map)); +} + + +/* + * 'conv_sbcs_to_utf8()' - Convert legacy SBCS to UTF-8. + */ + +static int /* O - Count or -1 on error */ +conv_sbcs_to_utf8( + cups_utf8_t *dest, /* O - Target string */ + const cups_sbcs_t *src, /* I - Source string */ + int maxout, /* I - Max output */ + const cups_encoding_t encoding) /* I - Encoding */ +{ + _cups_cmap_t *cmap; /* Legacy SBCS / Unicode Charset Map */ + cups_ucs2_t *crow; /* Pointer to UCS-2 row in 'char2uni' */ + cups_sbcs_t legchar; /* Legacy character value */ + cups_utf32_t work[CUPS_MAX_USTRING], /* Internal UCS-4 string */ + *workptr; /* Pointer into string */ + + + /* + * Find legacy charset map in cache... + */ + + if ((cmap = (_cups_cmap_t *)get_charmap(encoding)) == NULL) + return (-1); + + /* + * Convert input legacy charset to internal UCS-4 (and insert BOM)... + */ + + work[0] = 0xfeff; + for (workptr = work + 1; *src && workptr < (work + CUPS_MAX_USTRING - 1);) + { + legchar = *src++; + + /* + * Convert ASCII verbatim (optimization)... + */ + + if (legchar < 0x80) + *workptr++ = (cups_utf32_t)legchar; + else + { + /* + * Convert unknown character to Replacement Character... + */ + + crow = cmap->char2uni + legchar; + + if (!*crow) + *workptr++ = 0xfffd; + else + *workptr++ = (cups_utf32_t)*crow; + } + } + + *workptr = 0; + + /* + * Convert internal UCS-4 to output UTF-8 (and delete BOM)... + */ + + cmap->used --; + + return (cupsUTF32ToUTF8(dest, work, maxout)); +} + + +/* + * 'conv_utf8_to_sbcs()' - Convert UTF-8 to legacy SBCS. + */ + +static int /* O - Count or -1 on error */ +conv_utf8_to_sbcs( + cups_sbcs_t *dest, /* O - Target string */ + const cups_utf8_t *src, /* I - Source string */ + int maxout, /* I - Max output */ + const cups_encoding_t encoding) /* I - Encoding */ +{ + cups_sbcs_t *start; /* Start of destination string */ + _cups_cmap_t *cmap; /* Legacy SBCS / Unicode Charset Map */ + cups_sbcs_t *srow; /* Pointer to SBCS row in 'uni2char' */ + cups_utf32_t unichar; /* Character value */ + cups_utf32_t work[CUPS_MAX_USTRING], /* Internal UCS-4 string */ + *workptr; /* Pointer into string */ + + + /* + * Find legacy charset map in cache... + */ + + if ((cmap = (_cups_cmap_t *)get_charmap(encoding)) == NULL) + return (-1); + + /* + * Convert input UTF-8 to internal UCS-4 (and insert BOM)... + */ + + if (cupsUTF8ToUTF32(work, src, CUPS_MAX_USTRING) < 0) + return (-1); + + /* + * Convert internal UCS-4 to SBCS legacy charset (and delete BOM)... + */ + + for (workptr = work, start = dest; *workptr && maxout > 0; maxout --) + { + unichar = *workptr++; + if (!unichar) + break; + + /* + * Convert ASCII verbatim (optimization)... + */ + + if (unichar < 0x80) + { + *dest++ = (cups_sbcs_t)unichar; + continue; + } + + /* + * Convert unknown character to visible replacement... + */ + + srow = cmap->uni2char[(int)((unichar >> 8) & 0xff)]; + + if (srow) + srow += (int)(unichar & 0xff); + + if (!srow || !*srow) + *dest++ = '?'; + else + *dest++ = *srow; + } + + *dest = '\0'; + + cmap->used --; + + return ((int)(dest - start)); +} + + +/* + * 'conv_utf8_to_vbcs()' - Convert UTF-8 to legacy DBCS/VBCS. + */ + +static int /* O - Count or -1 on error */ +conv_utf8_to_vbcs( + cups_sbcs_t *dest, /* O - Target string */ + const cups_utf8_t *src, /* I - Source string */ + int maxout, /* I - Max output */ + const cups_encoding_t encoding) /* I - Encoding */ +{ + cups_sbcs_t *start; /* Start of destination string */ + _cups_vmap_t *vmap; /* Legacy DBCS / Unicode Charset Map */ + cups_vbcs_t *vrow; /* Pointer to VBCS row in 'uni2char' */ + cups_utf32_t unichar; /* Character value */ + cups_vbcs_t legchar; /* Legacy character value */ + cups_utf32_t work[CUPS_MAX_USTRING], /* Internal UCS-4 string */ + *workptr; /* Pointer into string */ + + + DEBUG_printf(("7conv_utf8_to_vbcs(dest=%p, src=\"%s\", maxout=%d, " + "encoding=%d)", dest, src, maxout, encoding)); + + /* + * Find legacy charset map in cache... + */ + + if ((vmap = (_cups_vmap_t *)get_charmap(encoding)) == NULL) + { + DEBUG_puts("8conv_utf8_to_vbcs: Returning -1 (no charmap)"); + + return (-1); + } + + /* + * Convert input UTF-8 to internal UCS-4 (and insert BOM)... + */ + + if (cupsUTF8ToUTF32(work, src, CUPS_MAX_USTRING) < 0) + { + DEBUG_puts("8conv_utf8_to_vbcs: Returning -1 (Unable to convert to UTF-32)"); + + return (-1); + } + + /* + * Convert internal UCS-4 to VBCS legacy charset (and delete BOM)... + */ + + for (start = dest, workptr = work; *workptr && maxout > 0; maxout --) + { + unichar = *workptr++; + + /* + * Convert ASCII verbatim (optimization)... + */ + + if (unichar < 0x80) + { + *dest++ = (cups_sbcs_t)unichar; + + DEBUG_printf(("9conv_utf8_to_vbcs: %08x => %02X", (unsigned)unichar, + dest[-1])); + + continue; + } + + /* + * Convert unknown character to visible replacement... + */ + + vrow = vmap->uni2char[(int)((unichar >> 8) & 0xff)]; + + if (vrow) + vrow += (int)(unichar & 0xff); + + if (!vrow || !*vrow) + legchar = (cups_vbcs_t)'?'; + else + legchar = (cups_vbcs_t)*vrow; + + /* + * Save n-byte legacy character... + */ + + if (legchar > 0xffffff) + { + if (maxout < 5) + { + DEBUG_puts("8conv_utf8_to_vbcs: Returning -1 (out of space)"); + + return (-1); + } + + *dest++ = (cups_sbcs_t)(legchar >> 24); + *dest++ = (cups_sbcs_t)(legchar >> 16); + *dest++ = (cups_sbcs_t)(legchar >> 8); + *dest++ = (cups_sbcs_t)legchar; + + maxout -= 3; + + DEBUG_printf(("9conv_utf8_to_vbcs: %08x => %02X %02X %02X %02X", + (unsigned)unichar, dest[-4], dest[-3], dest[-2], dest[-1])); + } + else if (legchar > 0xffff) + { + if (maxout < 4) + { + DEBUG_puts("8conv_utf8_to_vbcs: Returning -1 (out of space)"); + + return (-1); + } + + *dest++ = (cups_sbcs_t)(legchar >> 16); + *dest++ = (cups_sbcs_t)(legchar >> 8); + *dest++ = (cups_sbcs_t)legchar; + + maxout -= 2; + + DEBUG_printf(("9conv_utf8_to_vbcs: %08x => %02X %02X %02X", + (unsigned)unichar, dest[-3], dest[-2], dest[-1])); + } + else if (legchar > 0xff) + { + *dest++ = (cups_sbcs_t)(legchar >> 8); + *dest++ = (cups_sbcs_t)legchar; + + maxout --; + + DEBUG_printf(("9conv_utf8_to_vbcs: %08x => %02X %02X", + (unsigned)unichar, dest[-2], dest[-1])); + } + else + { + *dest++ = (cups_sbcs_t)legchar; + + DEBUG_printf(("9conv_utf8_to_vbcs: %08x => %02X", + (unsigned)unichar, dest[-1])); + } + } + + *dest = '\0'; + + vmap->used --; + + DEBUG_printf(("8conv_utf8_to_vbcs: Returning %d characters", + (int)(dest - start))); + + return ((int)(dest - start)); +} + + +/* + * 'conv_vbcs_to_utf8()' - Convert legacy DBCS/VBCS to UTF-8. + */ + +static int /* O - Count or -1 on error */ +conv_vbcs_to_utf8( + cups_utf8_t *dest, /* O - Target string */ + const cups_sbcs_t *src, /* I - Source string */ + int maxout, /* I - Max output */ + const cups_encoding_t encoding) /* I - Encoding */ +{ + _cups_vmap_t *vmap; /* Legacy VBCS / Unicode Charset Map */ + cups_ucs2_t *crow; /* Pointer to UCS-2 row in 'char2uni' */ + _cups_wide2uni_t *wide2uni; /* Pointer to row in 'wide2uni' */ + cups_sbcs_t leadchar; /* Lead char of n-byte legacy char */ + cups_vbcs_t legchar; /* Legacy character value */ + cups_utf32_t work[CUPS_MAX_USTRING], /* Internal UCS-4 string */ + *workptr; /* Pointer into string */ + + + /* + * Find legacy charset map in cache... + */ + + DEBUG_printf(("7conv_vbcs_to_utf8(dest=%p, src=%p, maxout=%d, encoding=%d)", + dest, src, maxout, encoding)); + + if ((vmap = (_cups_vmap_t *)get_charmap(encoding)) == NULL) + { + DEBUG_puts("8conv_vbcs_to_utf8: Returning -1 (NULL vmap)"); + + return (-1); + } + + /* + * Convert input legacy charset to internal UCS-4 (and insert BOM)... + */ + + work[0] = 0xfeff; + for (workptr = work + 1; *src && workptr < (work + CUPS_MAX_USTRING - 1);) + { + legchar = *src++; + leadchar = (cups_sbcs_t)legchar; + + /* + * Convert ASCII verbatim (optimization)... + */ + + if (legchar < 0x80) + { + *workptr++ = (cups_utf32_t)legchar; + + DEBUG_printf(("9conv_vbcs_to_utf8: %02X => %08X", src[-1], + (unsigned)legchar)); + continue; + } + + /* + * Convert 2-byte legacy character... + */ + + if (vmap->lead2char[(int)leadchar] == leadchar) + { + if (!*src) + { + DEBUG_puts("8conv_vbcs_to_utf8: Returning -1 (short string)"); + + return (-1); + } + + legchar = (legchar << 8) | *src++; + + /* + * Convert unknown character to Replacement Character... + */ + + crow = vmap->char2uni[(int)((legchar >> 8) & 0xff)]; + if (crow) + crow += (int) (legchar & 0xff); + + if (!crow || !*crow) + *workptr++ = 0xfffd; + else + *workptr++ = (cups_utf32_t)*crow; + + DEBUG_printf(("9conv_vbcs_to_utf8: %02X %02X => %08X", + src[-2], src[-1], (unsigned)workptr[-1])); + continue; + } + + /* + * Fetch 3-byte or 4-byte legacy character... + */ + + if (vmap->lead3char[(int)leadchar] == leadchar) + { + if (!*src || !src[1]) + { + DEBUG_puts("8conv_vbcs_to_utf8: Returning -1 (short string 2)"); + + return (-1); + } + + legchar = (legchar << 8) | *src++; + legchar = (legchar << 8) | *src++; + } + else if (vmap->lead4char[(int)leadchar] == leadchar) + { + if (!*src || !src[1] || !src[2]) + { + DEBUG_puts("8conv_vbcs_to_utf8: Returning -1 (short string 3)"); + + return (-1); + } + + legchar = (legchar << 8) | *src++; + legchar = (legchar << 8) | *src++; + legchar = (legchar << 8) | *src++; + } + else + { + DEBUG_puts("8conv_vbcs_to_utf8: Returning -1 (bad character)"); + + return (-1); + } + + /* + * Find 3-byte or 4-byte legacy character... + */ + + wide2uni = (_cups_wide2uni_t *)bsearch(&legchar, + vmap->wide2uni, + vmap->widecount, + sizeof(_cups_wide2uni_t), + compare_wide); + + /* + * Convert unknown character to Replacement Character... + */ + + if (!wide2uni || !wide2uni->unichar) + *workptr++ = 0xfffd; + else + *workptr++ = wide2uni->unichar; + + if (vmap->lead3char[(int)leadchar] == leadchar) + DEBUG_printf(("9conv_vbcs_to_utf8: %02X %02X %02X => %08X", + src[-3], src[-2], src[-1], (unsigned)workptr[-1])); + else + DEBUG_printf(("9conv_vbcs_to_utf8: %02X %02X %02X %02X => %08X", + src[-4], src[-3], src[-2], src[-1], (unsigned)workptr[-1])); + } + + *workptr = 0; + + vmap->used --; + + DEBUG_printf(("9conv_vbcs_to_utf8: Converting %d UTF-32 characters to UTF-8", + (int)(workptr - work))); + + /* + * Convert internal UCS-4 to output UTF-8 (and delete BOM)... + */ + + return (cupsUTF32ToUTF8(dest, work, maxout)); +} + + +/* + * 'free_sbcs_charmap()' - Free memory used by a single byte character set. + */ + +static void +free_sbcs_charmap(_cups_cmap_t *cmap) /* I - Character set */ +{ + int i; /* Looping variable */ + + + for (i = 0; i < 256; i ++) + if (cmap->uni2char[i]) + free(cmap->uni2char[i]); + + free(cmap); +} + + +/* + * 'free_vbcs_charmap()' - Free memory used by a variable byte character set. + */ + +static void +free_vbcs_charmap(_cups_vmap_t *vmap) /* I - Character set */ +{ + int i; /* Looping variable */ + + + for (i = 0; i < 256; i ++) + if (vmap->char2uni[i]) + free(vmap->char2uni[i]); + + for (i = 0; i < 256; i ++) + if (vmap->uni2char[i]) + free(vmap->uni2char[i]); + + if (vmap->wide2uni) + free(vmap->wide2uni); + + free(vmap); +} + + +/* + * 'get_charmap()' - Lookup or get a character set map (private). + * + * This code handles single-byte (SBCS), double-byte (DBCS), and + * variable-byte (VBCS) character sets _without_ charset escapes... + * This code does not handle multiple-byte character sets (MBCS) + * (such as ISO-2022-JP) with charset switching via escapes... + */ + + +static void * /* O - Charset map pointer */ +get_charmap( + const cups_encoding_t encoding) /* I - Encoding */ +{ + char filename[1024]; /* Filename for charset map file */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + + + DEBUG_printf(("7get_charmap(encoding=%d)", encoding)); + + /* + * Get the data directory and charset map name... + */ + + snprintf(filename, sizeof(filename), "%s/charmaps/%s.txt", + cg->cups_datadir, _cupsEncodingName(encoding)); + + DEBUG_printf(("9get_charmap: filename=\"%s\"", filename)); + + /* + * Read charset map input file into cache... + */ + + if (encoding < CUPS_ENCODING_SBCS_END) + return (get_sbcs_charmap(encoding, filename)); + else if (encoding < CUPS_ENCODING_VBCS_END) + return (get_vbcs_charmap(encoding, filename)); + else + return (NULL); +} + + +/* + * 'get_charmap_count()' - Count lines in a charmap file. + */ + +static int /* O - Count or -1 on error */ +get_charmap_count(cups_file_t *fp) /* I - File to read from */ +{ + int count; /* Number of lines */ + char line[256]; /* Line from input map file */ + + + /* + * Count lines in map input file... + */ + + count = 0; + + while (cupsFileGets(fp, line, sizeof(line))) + if (line[0] == '0') + count ++; + + /* + * Return the number of lines... + */ + + if (count > 0) + return (count); + else + return (-1); +} + + +/* + * 'get_sbcs_charmap()' - Get SBCS Charmap. + */ + +static _cups_cmap_t * /* O - Charmap or 0 on error */ +get_sbcs_charmap( + const cups_encoding_t encoding, /* I - Charmap Encoding */ + const char *filename) /* I - Charmap Filename */ +{ + unsigned long legchar; /* Legacy character value */ + cups_utf32_t unichar; /* Unicode character value */ + _cups_cmap_t *cmap; /* Legacy SBCS / Unicode Charset Map */ + cups_file_t *fp; /* Charset map file pointer */ + char *s; /* Line parsing pointer */ + cups_ucs2_t *crow; /* Pointer to UCS-2 row in 'char2uni' */ + cups_sbcs_t *srow; /* Pointer to SBCS row in 'uni2char' */ + char line[256]; /* Line from charset map file */ + + + /* + * See if we already have this SBCS charset map loaded... + */ + + DEBUG_printf(("7get_sbcs_charmap(encoding=%d, filename=\"%s\")", encoding, + filename)); + + for (cmap = cmap_cache; cmap; cmap = cmap->next) + { + if (cmap->encoding == encoding) + { + cmap->used ++; + DEBUG_printf(("8get_sbcs_charmap: Returning existing cmap=%p", cmap)); + + return ((void *)cmap); + } + } + + /* + * Open SBCS charset map input file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + DEBUG_printf(("8get_sbcs_charmap: Returning NULL (%s)", strerror(errno))); + + return (NULL); + } + + /* + * Allocate memory for SBCS charset map... + */ + + if ((cmap = (_cups_cmap_t *)calloc(1, sizeof(_cups_cmap_t))) == NULL) + { + cupsFileClose(fp); + DEBUG_puts("8get_sbcs_charmap: Returning NULL (Unable to allocate memory)"); + + return (NULL); + } + + cmap->used ++; + cmap->encoding = encoding; + + /* + * Save SBCS charset map into memory for transcoding... + */ + + while (cupsFileGets(fp, line, sizeof(line))) + { + if (line[0] != '0') + continue; + + legchar = strtol(line, &s, 16); + if (legchar < 0 || legchar > 0xff) + goto sbcs_error; + + unichar = strtol(s, NULL, 16); + if (unichar < 0 || unichar > 0x10ffff) + goto sbcs_error; + + /* + * Save legacy to Unicode mapping in direct lookup table... + */ + + crow = cmap->char2uni + legchar; + *crow = (cups_ucs2_t)(unichar & 0xffff); + + /* + * Save Unicode to legacy mapping in indirect lookup table... + */ + + srow = cmap->uni2char[(unichar >> 8) & 0xff]; + if (!srow) + { + srow = (cups_sbcs_t *)calloc(256, sizeof(cups_sbcs_t)); + if (!srow) + goto sbcs_error; + + cmap->uni2char[(unichar >> 8) & 0xff] = srow; + } + + srow += unichar & 0xff; + + /* + * Convert Replacement Character to visible replacement... + */ + + if (unichar == 0xfffd) + legchar = (unsigned long)'?'; + + /* + * First (oldest) legacy character uses Unicode mapping cell... + */ + + if (!*srow) + *srow = (cups_sbcs_t)legchar; + } + + cupsFileClose(fp); + + /* + * Add it to the cache and return... + */ + + cmap->next = cmap_cache; + cmap_cache = cmap; + + DEBUG_printf(("8get_sbcs_charmap: Returning new cmap=%p", cmap)); + + return (cmap); + + /* + * If we get here, there was an error in the cmap file... + */ + + sbcs_error: + + free_sbcs_charmap(cmap); + + cupsFileClose(fp); + + DEBUG_puts("8get_sbcs_charmap: Returning NULL (Read/format error)"); + + return (NULL); +} + + +/* + * 'get_vbcs_charmap()' - Get DBCS/VBCS Charmap. + */ + +static _cups_vmap_t * /* O - Charmap or 0 on error */ +get_vbcs_charmap( + const cups_encoding_t encoding, /* I - Charmap Encoding */ + const char *filename) /* I - Charmap Filename */ +{ + _cups_vmap_t *vmap; /* Legacy VBCS / Unicode Charset Map */ + cups_ucs2_t *crow; /* Pointer to UCS-2 row in 'char2uni' */ + cups_vbcs_t *vrow; /* Pointer to VBCS row in 'uni2char' */ + _cups_wide2uni_t *wide2uni; /* Pointer to row in 'wide2uni' */ + cups_sbcs_t leadchar; /* Lead char of 2-byte legacy char */ + unsigned long legchar; /* Legacy character value */ + cups_utf32_t unichar; /* Unicode character value */ + int mapcount; /* Count of lines in charmap file */ + cups_file_t *fp; /* Charset map file pointer */ + char *s; /* Line parsing pointer */ + char line[256]; /* Line from charset map file */ + int i; /* Loop variable */ + int legacy; /* 32-bit legacy char */ + + + DEBUG_printf(("7get_vbcs_charmap(encoding=%d, filename=\"%s\")\n", + encoding, filename)); + + /* + * See if we already have this DBCS/VBCS charset map loaded... + */ + + for (vmap = vmap_cache; vmap; vmap = vmap->next) + { + if (vmap->encoding == encoding) + { + vmap->used ++; + DEBUG_printf(("8get_vbcs_charmap: Returning existing vmap=%p", vmap)); + + return ((void *)vmap); + } + } + + /* + * Open VBCS charset map input file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + DEBUG_printf(("8get_vbcs_charmap: Returning NULL (%s)", strerror(errno))); + + return (NULL); + } + + /* + * Count lines in charmap file... + */ + + if ((mapcount = get_charmap_count(fp)) <= 0) + { + DEBUG_puts("8get_vbcs_charmap: Unable to get charmap count!"); + + cupsFileClose(fp); + + return (NULL); + } + + DEBUG_printf(("8get_vbcs_charmap: mapcount=%d", mapcount)); + + /* + * Allocate memory for DBCS/VBCS charset map... + */ + + if ((vmap = (_cups_vmap_t *)calloc(1, sizeof(_cups_vmap_t))) == NULL) + { + DEBUG_puts("8get_vbcs_charmap: Unable to allocate memory!"); + + cupsFileClose(fp); + + return (NULL); + } + + vmap->used ++; + vmap->encoding = encoding; + + /* + * Save DBCS/VBCS charset map into memory for transcoding... + */ + + wide2uni = NULL; + + cupsFileRewind(fp); + + i = 0; + legacy = 0; + + while (cupsFileGets(fp, line, sizeof(line))) + { + if (line[0] != '0') + continue; + + legchar = strtoul(line, &s, 16); + if (legchar == ULONG_MAX) + goto vbcs_error; + + unichar = strtol(s, NULL, 16); + if (unichar < 0 || unichar > 0x10ffff) + goto vbcs_error; + + i ++; + + DEBUG_printf(("9get_vbcs_charmap: i=%d, legchar=0x%08lx, unichar=0x%04x", i, + legchar, (unsigned)unichar)); + + /* + * Save lead char of 2/3/4-byte legacy char... + */ + + if (legchar > 0xffffff) + { + leadchar = (cups_sbcs_t)(legchar >> 24); + vmap->lead4char[leadchar] = leadchar; + } + else if (legchar > 0xffff) + { + leadchar = (cups_sbcs_t)(legchar >> 16); + vmap->lead3char[leadchar] = leadchar; + } + else + { + leadchar = (cups_sbcs_t)(legchar >> 8); + vmap->lead2char[leadchar] = leadchar; + } + + /* + * Save Legacy to Unicode mapping... + */ + + if (legchar <= 0xffff) + { + /* + * Save DBCS 16-bit to Unicode mapping in indirect lookup table... + */ + + crow = vmap->char2uni[(int)leadchar]; + if (!crow) + { + crow = (cups_ucs2_t *)calloc(256, sizeof(cups_ucs2_t)); + if (!crow) + goto vbcs_error; + + vmap->char2uni[(int)leadchar] = crow; + } + + crow[(int)(legchar & 0xff)] = (cups_ucs2_t)unichar; + } + else + { + /* + * Save VBCS 32-bit to Unicode mapping in sorted list table... + */ + + if (!legacy) + { + legacy = 1; + vmap->widecount = (mapcount - i + 1); + wide2uni = (_cups_wide2uni_t *)calloc(vmap->widecount, + sizeof(_cups_wide2uni_t)); + if (!wide2uni) + goto vbcs_error; + + vmap->wide2uni = wide2uni; + } + + wide2uni->widechar = (cups_vbcs_t)legchar; + wide2uni->unichar = (cups_ucs2_t)unichar; + wide2uni ++; + } + + /* + * Save Unicode to legacy mapping in indirect lookup table... + */ + + vrow = vmap->uni2char[(int)((unichar >> 8) & 0xff)]; + if (!vrow) + { + vrow = (cups_vbcs_t *)calloc(256, sizeof(cups_vbcs_t)); + if (!vrow) + goto vbcs_error; + + vmap->uni2char[(int) ((unichar >> 8) & 0xff)] = vrow; + } + + vrow += (int)(unichar & 0xff); + + /* + * Convert Replacement Character to visible replacement... + */ + + if (unichar == 0xfffd) + legchar = (unsigned long)'?'; + + /* + * First (oldest) legacy character uses Unicode mapping cell... + */ + + if (!*vrow) + *vrow = (cups_vbcs_t)legchar; + } + + vmap->charcount = (i - vmap->widecount); + + cupsFileClose(fp); + + /* + * Add it to the cache and return... + */ + + vmap->next = vmap_cache; + vmap_cache = vmap; + + DEBUG_printf(("8get_vbcs_charmap: Returning new vmap=%p", vmap)); + + return (vmap); + + /* + * If we get here, the file contains errors... + */ + + vbcs_error: + + free_vbcs_charmap(vmap); + + cupsFileClose(fp); + + DEBUG_puts("8get_vbcs_charmap: Returning NULL (Read/format error)"); + + return (NULL); +} + + +/* + * End of "$Id$" + */ diff --git a/cups/transcode.h b/cups/transcode.h new file mode 100644 index 0000000000..e4343e14e8 --- /dev/null +++ b/cups/transcode.h @@ -0,0 +1,81 @@ +/* + * "$Id$" + * + * Transcoding definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_TRANSCODE_H_ +# define _CUPS_TRANSCODE_H_ + +/* + * Include necessary headers... + */ + +# include "language.h" + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Constants... + */ + +# define CUPS_MAX_USTRING 8192 /* Max size of Unicode string */ + + +/* + * Types... + */ + +typedef unsigned char cups_utf8_t; /* UTF-8 Unicode/ISO-10646 unit */ +typedef unsigned long cups_utf32_t; /* UTF-32 Unicode/ISO-10646 unit */ +typedef unsigned short cups_ucs2_t; /* UCS-2 Unicode/ISO-10646 unit */ +typedef unsigned long cups_ucs4_t; /* UCS-4 Unicode/ISO-10646 unit */ +typedef unsigned char cups_sbcs_t; /* SBCS Legacy 8-bit unit */ +typedef unsigned short cups_dbcs_t; /* DBCS Legacy 16-bit unit */ +typedef unsigned long cups_vbcs_t; /* VBCS Legacy 32-bit unit */ + /* EUC uses 8, 16, 24, 32-bit */ + + +/* + * Prototypes... + */ + +extern int cupsCharsetToUTF8(cups_utf8_t *dest, + const char *src, + const int maxout, + const cups_encoding_t encoding) _CUPS_API_1_2; +extern int cupsUTF8ToCharset(char *dest, + const cups_utf8_t *src, + const int maxout, + const cups_encoding_t encoding) _CUPS_API_1_2; +extern int cupsUTF8ToUTF32(cups_utf32_t *dest, + const cups_utf8_t *src, + const int maxout) _CUPS_API_1_2; +extern int cupsUTF32ToUTF8(cups_utf8_t *dest, + const cups_utf32_t *src, + const int maxout) _CUPS_API_1_2; + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_TRANSCODE_H_ */ + + +/* + * End of "$Id$" + */ diff --git a/cups/usersys.c b/cups/usersys.c new file mode 100644 index 0000000000..58d4a8dc23 --- /dev/null +++ b/cups/usersys.c @@ -0,0 +1,620 @@ +/* + * "$Id$" + * + * User, system, and password routines for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsEncryption() - Get the current encryption settings. + * cupsGetPassword() - Get a password from the user. + * cupsGetPassword2() - Get a password from the user using the advanced + * password callback. + * cupsServer() - Return the hostname/address of the current + * server. + * cupsSetEncryption() - Set the encryption preference. + * cupsSetPasswordCB() - Set the password callback for CUPS. + * cupsSetPasswordCB2() - Set the advanced password callback for CUPS. + * cupsSetServer() - Set the default server name and port. + * cupsSetUser() - Set the default user name. + * cupsUser() - Return the current user's name. + * _cupsGetPassword() - Get a password from the user. + * _cupsSetDefaults() - Set the default server, port, and encryption. + * cups_read_client_conf() - Read a client.conf file. + */ + +/* + * Include necessary headers... + */ + +#include "http-private.h" +#include "globals.h" +#include +#include +#ifdef WIN32 +# include +#else +# include +#endif /* WIN32 */ +#include "debug.h" + + +/* + * Local functions... + */ + +static void cups_read_client_conf(cups_file_t *fp, + _cups_globals_t *cg, + const char *cups_encryption, + const char *cups_server); + + +/* + * 'cupsEncryption()' - Get the current encryption settings. + * + * The default encryption setting comes from the CUPS_ENCRYPTION + * environment variable, then the ~/.cups/client.conf file, and finally the + * /etc/cups/client.conf file. If not set, the default is + * @code HTTP_ENCRYPT_IF_REQUESTED@. + * + * Note: The current encryption setting is tracked separately for each thread + * in a program. Multi-threaded programs that override the setting via the + * @link cupsSetEncryption@ function need to do so in each thread for the same + * setting to be used. + */ + +http_encryption_t /* O - Encryption settings */ +cupsEncryption(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (cg->encryption == (http_encryption_t)-1) + _cupsSetDefaults(); + + return (cg->encryption); +} + + +/* + * 'cupsGetPassword()' - Get a password from the user. + * + * Uses the current password callback function. Returns @code NULL@ if the + * user does not provide a password. + * + * Note: The current password callback function is tracked separately for each + * thread in a program. Multi-threaded programs that override the setting via + * the @link cupsSetPasswordCB@ or @link cupsSetPasswordCB2@ functions need to + * do so in each thread for the same function to be used. + */ + +const char * /* O - Password */ +cupsGetPassword(const char *prompt) /* I - Prompt string */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + return ((cg->password_cb)(prompt, NULL, NULL, NULL, cg->password_data)); +} + + +/* + * 'cupsGetPassword2()' - Get a password from the user using the advanced + * password callback. + * + * Uses the current password callback function. Returns @code NULL@ if the + * user does not provide a password. + * + * Note: The current password callback function is tracked separately for each + * thread in a program. Multi-threaded programs that override the setting via + * the @link cupsSetPasswordCB@ or @link cupsSetPasswordCB2@ functions need to + * do so in each thread for the same function to be used. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +const char * /* O - Password */ +cupsGetPassword2(const char *prompt, /* I - Prompt string */ + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *method, /* I - Request method ("GET", "POST", "PUT") */ + const char *resource) /* I - Resource path */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (!http) + http = _cupsConnect(); + + return ((cg->password_cb)(prompt, http, method, resource, cg->password_data)); +} + + +/* + * 'cupsServer()' - Return the hostname/address of the current server. + * + * The default server comes from the CUPS_SERVER environment variable, then the + * ~/.cups/client.conf file, and finally the /etc/cups/client.conf file. If not + * set, the default is the local system - either "localhost" or a domain socket + * path. + * + * The returned value can be a fully-qualified hostname, a numeric IPv4 or IPv6 + * address, or a domain socket pathname. + * + * Note: The current server is tracked separately for each thread in a program. + * Multi-threaded programs that override the server via the + * @link cupsSetServer@ function need to do so in each thread for the same + * server to be used. + */ + +const char * /* O - Server name */ +cupsServer(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (!cg->server[0]) + _cupsSetDefaults(); + + return (cg->server); +} + + +/* + * 'cupsSetEncryption()' - Set the encryption preference. + * + * The default encryption setting comes from the CUPS_ENCRYPTION + * environment variable, then the ~/.cups/client.conf file, and finally the + * /etc/cups/client.conf file. If not set, the default is + * @code HTTP_ENCRYPT_IF_REQUESTED@. + * + * Note: The current encryption setting is tracked separately for each thread + * in a program. Multi-threaded programs that override the setting need to do + * so in each thread for the same setting to be used. + */ + +void +cupsSetEncryption(http_encryption_t e) /* I - New encryption preference */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + cg->encryption = e; + + if (cg->http) + httpEncryption(cg->http, e); +} + + +/* + * 'cupsSetPasswordCB()' - Set the password callback for CUPS. + * + * Pass @code NULL@ to restore the default (console) password callback, which + * reads the password from the console. Programs should call either this + * function or @link cupsSetPasswordCB2@, as only one callback can be registered + * by a program per thread. + * + * Note: The current password callback is tracked separately for each thread + * in a program. Multi-threaded programs that override the callback need to do + * so in each thread for the same callback to be used. + */ + +void +cupsSetPasswordCB(cups_password_cb_t cb)/* I - Callback function */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (cb == (cups_password_cb_t)0) + cg->password_cb = (cups_password_cb2_t)_cupsGetPassword; + else + cg->password_cb = (cups_password_cb2_t)cb; + + cg->password_data = NULL; +} + + +/* + * 'cupsSetPasswordCB2()' - Set the advanced password callback for CUPS. + * + * Pass @code NULL@ to restore the default (console) password callback, which + * reads the password from the console. Programs should call either this + * function or @link cupsSetPasswordCB2@, as only one callback can be registered + * by a program per thread. + * + * Note: The current password callback is tracked separately for each thread + * in a program. Multi-threaded programs that override the callback need to do + * so in each thread for the same callback to be used. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +void +cupsSetPasswordCB2( + cups_password_cb2_t cb, /* I - Callback function */ + void *user_data) /* I - User data pointer */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (cb == (cups_password_cb2_t)0) + cg->password_cb = (cups_password_cb2_t)_cupsGetPassword; + else + cg->password_cb = cb; + + cg->password_data = user_data; +} + + +/* + * 'cupsSetServer()' - Set the default server name and port. + * + * The "server" string can be a fully-qualified hostname, a numeric + * IPv4 or IPv6 address, or a domain socket pathname. Hostnames and numeric IP + * addresses can be optionally followed by a colon and port number to override + * the default port 631, e.g. "hostname:8631". Pass @code NULL@ to restore the + * default server name and port. + * + * Note: The current server is tracked separately for each thread in a program. + * Multi-threaded programs that override the server need to do so in each + * thread for the same server to be used. + */ + +void +cupsSetServer(const char *server) /* I - Server name */ +{ + char *port; /* Pointer to port */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (server) + { + strlcpy(cg->server, server, sizeof(cg->server)); + + if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL && + !strchr(port, ']') && isdigit(port[1] & 255)) + { + *port++ = '\0'; + + cg->ipp_port = atoi(port); + } + + if (cg->server[0] == '/') + strcpy(cg->servername, "localhost"); + else + strlcpy(cg->servername, cg->server, sizeof(cg->servername)); + } + else + { + cg->server[0] = '\0'; + cg->servername[0] = '\0'; + } + + if (cg->http) + { + httpClose(cg->http); + cg->http = NULL; + } +} + + +/* + * 'cupsSetUser()' - Set the default user name. + * + * Pass @code NULL@ to restore the default user name. + * + * Note: The current user name is tracked separately for each thread in a + * program. Multi-threaded programs that override the user name need to do so + * in each thread for the same user name to be used. + */ + +void +cupsSetUser(const char *user) /* I - User name */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (user) + strlcpy(cg->user, user, sizeof(cg->user)); + else + cg->user[0] = '\0'; +} + + +/* + * 'cupsUser()' - Return the current user's name. + * + * Note: The current user name is tracked separately for each thread in a + * program. Multi-threaded programs that override the user name with the + * @link cupsSetUser@ function need to do so in each thread for the same user + * name to be used. + */ + +const char * /* O - User name */ +cupsUser(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + if (!cg->user[0]) + { +#ifdef WIN32 + /* + * Get the current user name from the OS... + */ + + DWORD size; /* Size of string */ + + size = sizeof(cg->user); + if (!GetUserName(cg->user, &size)) +#else + /* + * Get the user name corresponding to the current UID... + */ + + struct passwd *pwd; /* User/password entry */ + + setpwent(); + if ((pwd = getpwuid(getuid())) != NULL) + { + /* + * Found a match! + */ + + strlcpy(cg->user, pwd->pw_name, sizeof(cg->user)); + } + else +#endif /* WIN32 */ + { + /* + * Use the default "unknown" user name... + */ + + strcpy(cg->user, "unknown"); + } + } + + return (cg->user); +} + + +/* + * '_cupsGetPassword()' - Get a password from the user. + */ + +const char * /* O - Password */ +_cupsGetPassword(const char *prompt) /* I - Prompt string */ +{ +#ifdef WIN32 + /* + * Currently no console password support is provided on Windows. + */ + + return (NULL); + +#else + /* + * Use the standard getpass function to get a password from the console. + */ + + return (getpass(prompt)); +#endif /* WIN32 */ +} + + +/* + * '_cupsSetDefaults()' - Set the default server, port, and encryption. + */ + +void +_cupsSetDefaults(void) +{ + cups_file_t *fp; /* File */ + const char *home, /* Home directory of user */ + *cups_encryption, /* CUPS_ENCRYPTION env var */ + *cups_server; /* CUPS_SERVER env var */ + char filename[1024]; /* Filename */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + DEBUG_puts("_cupsSetDefaults()"); + + /* + * First collect environment variables... + */ + + cups_encryption = getenv("CUPS_ENCRYPTION"); + cups_server = getenv("CUPS_SERVER"); + + /* + * Then, if needed, the .cups/client.conf or .cupsrc file in the home + * directory... + */ + + if ((cg->encryption == (http_encryption_t)-1 || !cg->server[0] || + !cg->ipp_port) && (home = getenv("HOME")) != NULL) + { + /* + * Look for ~/.cups/client.conf or ~/.cupsrc... + */ + + snprintf(filename, sizeof(filename), "%s/.cups/client.conf", home); + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + snprintf(filename, sizeof(filename), "%s/.cupsrc", home); + fp = cupsFileOpen(filename, "r"); + } + + if (fp) + { + cups_read_client_conf(fp, cg, cups_encryption, cups_server); + cupsFileClose(fp); + } + } + + if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] || + !cg->ipp_port) + { + /* + * Look for CUPS_SERVERROOT/client.conf... + */ + + snprintf(filename, sizeof(filename), "%s/client.conf", cg->cups_serverroot); + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + cups_read_client_conf(fp, cg, cups_encryption, cups_server); + cupsFileClose(fp); + } + } + + /* + * If we still have things that aren't set, use the compiled in defaults... + */ + + if (cg->encryption == (http_encryption_t)-1) + cg->encryption = HTTP_ENCRYPT_IF_REQUESTED; + + if (!cg->server[0]) + { + if (!cups_server) + { +#ifdef CUPS_DEFAULT_DOMAINSOCKET + /* + * If we are compiled with domain socket support, only use the + * domain socket if it exists and has the right permissions... + */ + + struct stat sockinfo; /* Domain socket information */ + + if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) && + (sockinfo.st_mode & S_IRWXO) == S_IRWXO) + cups_server = CUPS_DEFAULT_DOMAINSOCKET; + else +#endif /* CUPS_DEFAULT_DOMAINSOCKET */ + cups_server = "localhost"; + } + + cupsSetServer(cups_server); + } + + if (!cg->ipp_port) + { + const char *ipp_port; /* IPP_PORT environment variable */ + struct servent *service; /* Port number info */ + + + if ((ipp_port = getenv("IPP_PORT")) != NULL) + { + if ((cg->ipp_port = atoi(ipp_port)) <= 0) + cg->ipp_port = CUPS_DEFAULT_IPP_PORT; + } + else if ((service = getservbyname("ipp", NULL)) == NULL || + service->s_port <= 0) + cg->ipp_port = CUPS_DEFAULT_IPP_PORT; + else + cg->ipp_port = ntohs(service->s_port); + } +} + + +/* + * 'cups_read_client_conf()' - Read a client.conf file. + */ + +static void +cups_read_client_conf( + cups_file_t *fp, /* I - File to read */ + _cups_globals_t *cg, /* I - Global data */ + const char *cups_encryption, /* I - CUPS_ENCRYPTION env var */ + const char *cups_server) /* I - CUPS_SERVER env var */ +{ + int linenum; /* Current line number */ + char line[1024], /* Line from file */ + *value, /* Pointer into line */ + encryption[1024], /* Encryption value */ + server_name[1024]; /* ServerName value */ + + + /* + * Read from the file... + */ + + linenum = 0; + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!cups_encryption && cg->encryption == (http_encryption_t)-1 && + !strcasecmp(line, "Encryption") && value) + { + strlcpy(encryption, value, sizeof(encryption)); + cups_encryption = encryption; + } + else if (!cups_server && (!cg->server[0] || !cg->ipp_port) && + !strcasecmp(line, "ServerName") && value) + { + strlcpy(server_name, value, sizeof(server_name)); + cups_server = server_name; + } + } + + /* + * Set values... + */ + + if (cg->encryption == (http_encryption_t)-1 && cups_encryption) + { + if (!strcasecmp(cups_encryption, "never")) + cg->encryption = HTTP_ENCRYPT_NEVER; + else if (!strcasecmp(cups_encryption, "always")) + cg->encryption = HTTP_ENCRYPT_ALWAYS; + else if (!strcasecmp(cups_encryption, "required")) + cg->encryption = HTTP_ENCRYPT_REQUIRED; + else + cg->encryption = HTTP_ENCRYPT_IF_REQUESTED; + } + + if ((!cg->server[0] || !cg->ipp_port) && cups_server) + { + if (!cg->server[0]) + { + /* + * Copy server name... + */ + + strlcpy(cg->server, cups_server, sizeof(cg->server)); + + if (cg->server[0] != '/' && (value = strrchr(cg->server, ':')) != NULL && + !strchr(value, ']') && isdigit(value[1] & 255)) + *value++ = '\0'; + else + value = NULL; + + if (cg->server[0] == '/') + strcpy(cg->servername, "localhost"); + else + strlcpy(cg->servername, cg->server, sizeof(cg->servername)); + } + else if (cups_server[0] != '/' && + (value = strrchr(cups_server, ':')) != NULL && + !strchr(value, ']') && isdigit(value[1] & 255)) + value ++; + else + value = NULL; + + if (!cg->ipp_port && value) + cg->ipp_port = atoi(value); + } +} + + +/* + * End of "$Id$". + */ diff --git a/cups/utf8demo.txt b/cups/utf8demo.txt new file mode 100644 index 0000000000..03802e4d7a --- /dev/null +++ b/cups/utf8demo.txt @@ -0,0 +1,213 @@ +UTF-8 encoded sample plain-text file +‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +Markus Kuhn [ˈmaʳkʊs kuːn] — 2002-07-25 + + +The ASCII compatible UTF-8 encoding used in this plain-text file +is defined in Unicode, ISO 10646-1, and RFC 2279. + + +Using Unicode/UTF-8, you can write in emails and source code things such as + +Mathematics and sciences: + + ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫ + ⎪⎢⎜│a²+b³ ⎟⎥⎪ + ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪ + ⎪⎢⎜⎷ c₈ ⎟⎥⎪ + ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬ + ⎪⎢⎜ ∞ ⎟⎥⎪ + ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪ + ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪ + 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭ + +Linguistics and dictionaries: + + ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn + Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ] + +APL: + + ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈ + +Nicer typography in plain text files: + + ╔══════════════════════════════════════════╗ + ║ ║ + ║ • ‘single’ and “double” quotes ║ + ║ ║ + ║ • Curly apostrophes: “We’ve been here” ║ + ║ ║ + ║ • Latin-1 apostrophe and accents: '´` ║ + ║ ║ + ║ • ‚deutsche‘ „Anführungszeichen“ ║ + ║ ║ + ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║ + ║ ║ + ║ • ASCII safety test: 1lI|, 0OD, 8B ║ + ║ ╭─────────╮ ║ + ║ • the euro symbol: │ 14.95 € │ ║ + ║ ╰─────────╯ ║ + ╚══════════════════════════════════════════╝ + +Combining characters: + + STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑ + +Greek (in Polytonic): + + The Greek anthem: + + Σὲ γνωρίζω ἀπὸ τὴν κόψη + τοῦ σπαθιοῦ τὴν τρομερή, + σὲ γνωρίζω ἀπὸ τὴν ὄψη + ποὺ μὲ βία μετράει τὴ γῆ. + + ᾿Απ᾿ τὰ κόκκαλα βγαλμένη + τῶν ῾Ελλήνων τὰ ἱερά + καὶ σὰν πρῶτα ἀνδρειωμένη + χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά! + + From a speech of Demosthenes in the 4th century BC: + + Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι, + ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς + λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ + τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ + εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ + πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν + οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι, + οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν + ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον + τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι + γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν + προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους + σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ + τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ + τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς + τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον. + + Δημοσθένους, Γ´ ᾿Ολυνθιακὸς + +Georgian: + + From a Unicode conference invitation: + + გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო + კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს, + ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს + ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი, + ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება + ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში, + ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში. + +Russian: + + From a Unicode conference invitation: + + Зарегистрируйтесь сейчас на Десятую Международную Конференцию по + Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии. + Конференция соберет широкий круг экспертов по вопросам глобального + Интернета и Unicode, локализации и интернационализации, воплощению и + применению Unicode в различных операционных системах и программных + приложениях, шрифтах, верстке и многоязычных компьютерных системах. + +Thai (UCS Level 2): + + Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese + classic 'San Gua'): + + [----------------------------|------------------------] + ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่ + สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา + ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา + โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ + เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ + ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ + พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้ + ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ + + (The above is a two-column text. If combining characters are handled + correctly, the lines of the second column should be aligned with the + | character above.) + +Ethiopian: + + Proverbs in the Amharic language: + + ሰማይ አይታረስ ንጉሥ አይከሰስ። + ብላ ካለኝ እንደአባቴ በቆመጠኝ። + ጌጥ ያለቤቱ ቁምጥና ነው። + ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው። + የአፍ ወለምታ በቅቤ አይታሽም። + አይጥ በበላ ዳዋ ተመታ። + ሲተረጉሙ ይደረግሙ። + ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል። + ድር ቢያብር አንበሳ ያስር። + ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም። + እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም። + የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ። + ሥራ ከመፍታት ልጄን ላፋታት። + ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል። + የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ። + ተንጋሎ ቢተፉ ተመልሶ ባፉ። + ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው። + እግርህን በፍራሽህ ልክ ዘርጋ። + +Runes: + + ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ + + (Old English, which transcribed into Latin reads 'He cwaeth that he + bude thaem lande northweardum with tha Westsae.' and means 'He said + that he lived in the northern land near the Western Sea.') + +Braille: + + ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌ + + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞ + ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎ + ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂ + ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙ + ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ + ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲ + + ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹ + ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞ + ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕ + ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ + ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ + ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎ + ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳ + ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞ + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + (The first couple of paragraphs of "A Christmas Carol" by Dickens) + +Compact font selection example text: + + ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789 + abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ + –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд + ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi?⑀₂ἠḂӥẄɐː⍎אԱა + +Greetings in various languages: + + Hello world, Καλημέρα κόσμε, コンニチハ + +Box drawing alignment tests: █ + ▉ + ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳ + ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳ + ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳ + ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳ + ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎ + ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏ + ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█ + ▝▀▘▙▄▟ + + diff --git a/cups/util.c b/cups/util.c new file mode 100644 index 0000000000..bec14443fd --- /dev/null +++ b/cups/util.c @@ -0,0 +1,1890 @@ +/* + * "$Id$" + * + * Printing utilities for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsCancelJob() - Cancel a print job on the default server. + * cupsCancelJob2() - Cancel or purge a print job. + * cupsCreateJob() - Create an empty job for streaming. + * cupsFinishDocument() - Finish sending a document. + * cupsFreeJobs() - Free memory used by job data. + * cupsGetClasses() - Get a list of printer classes from the default + * server. + * cupsGetDefault() - Get the default printer or class for the default + * server. + * cupsGetDefault2() - Get the default printer or class for the specified + * server. + * cupsGetJobs() - Get the jobs from the default server. + * cupsGetJobs2() - Get the jobs from the specified server. + * cupsGetPPD() - Get the PPD file for a printer on the default + * server. + * cupsGetPPD2() - Get the PPD file for a printer from the specified + * server. + * cupsGetPPD3() - Get the PPD file for a printer on the specified + * server if it has changed. + * cupsGetPrinters() - Get a list of printers from the default server. + * cupsGetServerPPD() - Get an available PPD file from the server. + * cupsLastError() - Return the last IPP status code. + * cupsLastErrorString() - Return the last IPP status-message. + * cupsPrintFile() - Print a file to a printer or class on the default + * server. + * cupsPrintFile2() - Print a file to a printer or class on the + * specified server. + * cupsPrintFiles() - Print one or more files to a printer or class on + * the default server. + * cupsPrintFiles2() - Print one or more files to a printer or class on + * the specified server. + * cupsStartDocument() - Add a document to a job created with + * cupsCreateJob(). + * _cupsConnect() - Get the default server connection... + * cups_get_printer_uri() - Get the printer-uri-supported attribute for the + * first printer in a class. + */ + +/* + * Include necessary headers... + */ + +#include "globals.h" +#include "debug.h" +#include +#include +#include +#include +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * Local functions... + */ + +static int cups_get_printer_uri(http_t *http, const char *name, + char *host, int hostsize, int *port, + char *resource, int resourcesize, + int depth); + + +/* + * 'cupsCancelJob()' - Cancel a print job on the default server. + * + * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@ + * to cancel the current job on the named destination. + * + * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get + * the cause of any failure. + */ + +int /* O - 1 on success, 0 on failure */ +cupsCancelJob(const char *name, /* I - Name of printer or class */ + int job_id) /* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */ +{ + return (cupsCancelJob2(CUPS_HTTP_DEFAULT, name, job_id, 0) + < IPP_REDIRECTION_OTHER_SITE); +} + + +/* + * 'cupsCancelJob2()' - Cancel or purge a print job. + * + * Canceled jobs remain in the job history while purged jobs are removed + * from the job history. + * + * Pass @code CUPS_JOBID_ALL@ to cancel all jobs or @code CUPS_JOBID_CURRENT@ + * to cancel the current job on the named destination. + * + * Use the @link cupsLastError@ and @link cupsLastErrorString@ functions to get + * the cause of any failure. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ipp_status_t /* O - IPP status */ +cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name, /* I - Name of printer or class */ + int job_id, /* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */ + int purge) /* I - 1 to purge, 0 to cancel */ +{ + char uri[HTTP_MAX_URI]; /* Job/printer URI */ + ipp_t *request; /* IPP request */ + + + /* + * Range check input... + */ + + if (job_id < -1 || (!name && job_id == 0)) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + return (0); + } + + /* + * Connect to the default server as needed... + */ + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (IPP_SERVICE_UNAVAILABLE); + + /* + * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * job-uri or printer-uri + job-id + * requesting-user-name + * [purge-job] or [purge-jobs] + */ + + request = ippNewRequest(job_id < 0 ? IPP_PURGE_JOBS : IPP_CANCEL_JOB); + + if (name) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", ippPort(), "/printers/%s", name); + + 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 if (job_id > 0) + { + snprintf(uri, sizeof(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()); + + if (purge && job_id >= 0) + ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1); + else if (!purge && job_id < 0) + ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", 0); + + /* + * Do the request... + */ + + ippDelete(cupsDoRequest(http, request, "/jobs/")); + + return (cupsLastError()); +} + + +/* + * 'cupsCreateJob()' - Create an empty job for streaming. + * + * Use this function when you want to stream print data using the + * @link cupsStartDocument@, @link cupsWriteRequestData@, and + * @link cupsFinishDocument@ functions. If you have one or more files to + * print, use the @link cupsPrintFile2@ or @link cupsPrintFiles2@ function + * instead. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +int /* O - Job ID or 0 on error */ +cupsCreateJob( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name, /* I - Destination name */ + const char *title, /* I - Title of job */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + char printer_uri[1024], /* Printer URI */ + resource[1024]; /* Printer resource */ + ipp_t *request, /* Create-Job request */ + *response; /* Create-Job response */ + ipp_attribute_t *attr; /* job-id attribute */ + int job_id = 0; /* job-id value */ + + + DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", " + "num_options=%d, options=%p)", + http, name, title, num_options, options)); + + /* + * Range check input... + */ + + if (!name) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + return (0); + } + + /* + * Build a Create-Job request... + */ + + if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); + return (0); + } + + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", + NULL, "localhost", ippPort(), "/printers/%s", name); + snprintf(resource, sizeof(resource), "/printers/%s", name); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, printer_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); + cupsEncodeOptions(request, num_options, options); + + /* + * Send the request and get the job-id... + */ + + response = cupsDoRequest(http, request, resource); + + if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) + job_id = attr->values[0].integer; + + ippDelete(response); + + /* + * Return it... + */ + + return (job_id); +} + + +/* + * 'cupsFinishDocument()' - Finish sending a document. + * + * The document must have been started using @link cupsStartDocument@. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +ipp_status_t /* O - Status of document submission */ +cupsFinishDocument(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name) /* I - Destination name */ +{ + char resource[1024]; /* Printer resource */ + + + snprintf(resource, sizeof(resource), "/printers/%s", name); + + ippDelete(cupsGetResponse(http, resource)); + + return (cupsLastError()); +} + + +/* + * '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 */ + cups_job_t *job; /* Current job */ + + + if (num_jobs <= 0 || !jobs) + return; + + for (i = num_jobs, job = jobs; i > 0; i --, job ++) + { + _cupsStrFree(job->dest); + _cupsStrFree(job->user); + _cupsStrFree(job->format); + _cupsStrFree(job->title); + } + + free(jobs); +} + + +/* + * 'cupsGetClasses()' - Get a list of printer classes from the default server. + * + * This function is deprecated - use @link cupsGetDests@ instead. + * + * @deprecated@ + */ + +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 */ + char **temp; /* Temporary pointer */ + http_t *http; /* Connection to server */ + + + if (!classes) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (0); + } + + *classes = NULL; + + if ((http = _cupsConnect()) == NULL) + return (0); + + /* + * Build a CUPS_GET_CLASSES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requested-attributes + */ + + request = ippNewRequest(CUPS_GET_CLASSES); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "printer-name"); + + /* + * Do the request and get back a response... + */ + + n = 0; + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + 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); + } + + return (n); +} + + +/* + * 'cupsGetDefault()' - Get the default printer or class for the default server. + * + * This function returns the default printer or class as defined by + * the LPDEST or PRINTER environment variables. If these environment + * variables are not set, the server default destination is returned. + * Applications should use the @link cupsGetDests@ and @link cupsGetDest@ + * functions to get the user-defined default printer, as this function does + * not support the lpoptions-defined default printer. + */ + +const char * /* O - Default printer or @code NULL@ */ +cupsGetDefault(void) +{ + /* + * Return the default printer... + */ + + return (cupsGetDefault2(CUPS_HTTP_DEFAULT)); +} + + +/* + * 'cupsGetDefault2()' - Get the default printer or class for the specified server. + * + * This function returns the default printer or class as defined by + * the LPDEST or PRINTER environment variables. If these environment + * variables are not set, the server default destination is returned. + * Applications should use the @link cupsGetDests@ and @link cupsGetDest@ + * functions to get the user-defined default printer, as this function does + * not support the lpoptions-defined default printer. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +const char * /* O - Default printer or @code NULL@ */ +cupsGetDefault2(http_t *http) /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * See if we have a user default printer set... + */ + + if (_cupsUserDefault(cg->def_printer, sizeof(cg->def_printer))) + return (cg->def_printer); + + /* + * Connect to the server as needed... + */ + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (NULL); + + /* + * Build a CUPS_GET_DEFAULT request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNewRequest(CUPS_GET_DEFAULT); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if ((attr = ippFindAttribute(response, "printer-name", + IPP_TAG_NAME)) != NULL) + { + strlcpy(cg->def_printer, attr->values[0].string.text, + sizeof(cg->def_printer)); + ippDelete(response); + return (cg->def_printer); + } + + ippDelete(response); + } + + return (NULL); +} + + +/* + * 'cupsGetJobs()' - Get the jobs from the default server. + * + * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless + * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are + * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns + * jobs that are stopped, canceled, aborted, or completed. + */ + +int /* O - Number of jobs */ +cupsGetJobs(cups_job_t **jobs, /* O - Job data */ + const char *name, /* I - @code NULL@ = all destinations, otherwise show jobs for named destination */ + int myjobs, /* I - 0 = all users, 1 = mine */ + int whichjobs) /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */ +{ + /* + * Return the jobs... + */ + + return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, name, myjobs, whichjobs)); +} + + + +/* + * 'cupsGetJobs2()' - Get the jobs from the specified server. + * + * A "whichjobs" value of @code CUPS_WHICHJOBS_ALL@ returns all jobs regardless + * of state, while @code CUPS_WHICHJOBS_ACTIVE@ returns jobs that are + * pending, processing, or held and @code CUPS_WHICHJOBS_COMPLETED@ returns + * jobs that are stopped, canceled, aborted, or completed. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +int /* O - Number of jobs */ +cupsGetJobs2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + cups_job_t **jobs, /* O - Job data */ + const char *name, /* I - @code NULL@ = all destinations, otherwise show jobs for named destination */ + int myjobs, /* I - 0 = all users, 1 = mine */ + int whichjobs) /* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */ +{ + int n; /* Number of jobs */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + 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 */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + static const char * const attrs[] = /* Requested attributes */ + { + "document-format", + "job-id", + "job-k-octets", + "job-name", + "job-originating-user-name", + "job-printer-uri", + "job-priority", + "job-state", + "time-at-completed", + "time-at-creation", + "time-at-processing" + }; + + + /* + * Range check input... + */ + + if (!jobs) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (-1); + } + + /* + * Get the right URI... + */ + + if (name) + { + if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Unable to create printer-uri!"), 1); + + return (-1); + } + } + else + strcpy(uri, "ipp://localhost/"); + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (-1); + + /* + * 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 = ippNewRequest(IPP_GET_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 (whichjobs == CUPS_WHICHJOBS_COMPLETED) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "which-jobs", NULL, "completed"); + else if (whichjobs == CUPS_WHICHJOBS_ALL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "which-jobs", NULL, "all"); + + 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(http, request, "/")) != NULL) + { + for (attr = response->attrs; attr; attr = attr->next) + { + /* + * Skip leading attributes until we hit a job... + */ + + while (attr && attr->group_tag != IPP_TAG_JOB) + attr = attr->next; + + if (!attr) + 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 && attr->group_tag == IPP_TAG_JOB) + { + if (!strcmp(attr->name, "job-id") && + attr->value_tag == IPP_TAG_INTEGER) + id = attr->values[0].integer; + else if (!strcmp(attr->name, "job-state") && + attr->value_tag == IPP_TAG_ENUM) + state = (ipp_jstate_t)attr->values[0].integer; + else if (!strcmp(attr->name, "job-priority") && + attr->value_tag == IPP_TAG_INTEGER) + priority = attr->values[0].integer; + else if (!strcmp(attr->name, "job-k-octets") && + attr->value_tag == IPP_TAG_INTEGER) + size = attr->values[0].integer; + else if (!strcmp(attr->name, "time-at-completed") && + attr->value_tag == IPP_TAG_INTEGER) + completed_time = attr->values[0].integer; + else if (!strcmp(attr->name, "time-at-creation") && + attr->value_tag == IPP_TAG_INTEGER) + creation_time = attr->values[0].integer; + else if (!strcmp(attr->name, "time-at-processing") && + attr->value_tag == IPP_TAG_INTEGER) + processing_time = attr->values[0].integer; + else if (!strcmp(attr->name, "job-printer-uri") && + 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") && + attr->value_tag == IPP_TAG_NAME) + user = attr->values[0].string.text; + else if (!strcmp(attr->name, "document-format") && + attr->value_tag == IPP_TAG_MIMETYPE) + format = attr->values[0].string.text; + else if (!strcmp(attr->name, "job-name") && + (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 || !id) + { + if (!attr) + 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) + { + /* + * Ran out of memory! + */ + + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + + cupsFreeJobs(n, *jobs); + *jobs = NULL; + + ippDelete(response); + + return (-1); + } + + *jobs = temp; + temp += n; + n ++; + + /* + * Copy the data over... + */ + + temp->dest = _cupsStrAlloc(dest); + temp->user = _cupsStrAlloc(user); + temp->format = _cupsStrAlloc(format); + temp->title = _cupsStrAlloc(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) + break; + } + + ippDelete(response); + } + + if (n == 0 && cg->last_error >= IPP_BAD_REQUEST) + return (-1); + else + return (n); +} + + +/* + * 'cupsGetPPD()' - Get the PPD file for a printer on the default server. + * + * For classes, @code cupsGetPPD@ returns the PPD file for the first printer + * in the class. + * + * The returned filename is stored in a static buffer and is overwritten with + * each call to @code cupsGetPPD@ or @link cupsGetPPD2@. The caller "owns" the + * file that is created and must @code unlink@ the returned filename. + */ + +const char * /* O - Filename for PPD file */ +cupsGetPPD(const char *name) /* I - Destination name */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + time_t modtime = 0; /* Modification time */ + + + /* + * Return the PPD file... + */ + + cg->ppd_filename[0] = '\0'; + + if (cupsGetPPD3(CUPS_HTTP_DEFAULT, name, &modtime, cg->ppd_filename, + sizeof(cg->ppd_filename)) == HTTP_OK) + return (cg->ppd_filename); + else + return (NULL); +} + + +/* + * 'cupsGetPPD2()' - Get the PPD file for a printer from the specified server. + * + * For classes, @code cupsGetPPD2@ returns the PPD file for the first printer + * in the class. + * + * The returned filename is stored in a static buffer and is overwritten with + * each call to @link cupsGetPPD@ or @code cupsGetPPD2@. The caller "owns" the + * file that is created and must @code unlink@ the returned filename. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +const char * /* O - Filename for PPD file */ +cupsGetPPD2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name) /* I - Destination name */ +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + time_t modtime = 0; /* Modification time */ + + + cg->ppd_filename[0] = '\0'; + + if (cupsGetPPD3(http, name, &modtime, cg->ppd_filename, + sizeof(cg->ppd_filename)) == HTTP_OK) + return (cg->ppd_filename); + else + return (NULL); +} + + +/* + * 'cupsGetPPD3()' - Get the PPD file for a printer on the specified + * server if it has changed. + * + * The "modtime" parameter contains the modification time of any + * locally-cached content and is updated with the time from the PPD file on + * the server. + * + * The "buffer" parameter contains the local PPD filename. If it contains + * the empty string, a new temporary file is created, otherwise the existing + * file will be overwritten as needed. The caller "owns" the file that is + * created and must @code unlink@ the returned filename. + * + * On success, @code HTTP_OK@ is returned for a new PPD file and + * @code HTTP_NOT_MODIFIED@ if the existing PPD file is up-to-date. Any other + * status is an error. + * + * For classes, @code cupsGetPPD3@ returns the PPD file for the first printer + * in the class. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +http_status_t /* O - HTTP status */ +cupsGetPPD3(http_t *http, /* I - HTTP connection or @code CUPS_HTTP_DEFAULT@ */ + const char *name, /* I - Destination name */ + time_t *modtime, /* IO - Modification time */ + char *buffer, /* I - Filename buffer */ + size_t bufsize) /* I - Size of filename buffer */ +{ + int http_port; /* Port number */ + char http_hostname[HTTP_MAX_HOST]; + /* Hostname associated with connection */ + http_t *http2; /* Alternate HTTP connection */ + int fd; /* PPD file */ + char localhost[HTTP_MAX_URI],/* Local hostname */ + hostname[HTTP_MAX_URI], /* Hostname */ + resource[HTTP_MAX_URI]; /* Resource name */ + int port; /* Port number */ + http_status_t status; /* HTTP status from server */ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * Range check input... + */ + + DEBUG_printf(("cupsGetPPD3(http=%p, name=\"%s\", modtime=%p(%d), buffer=%p, " + "bufsize=%d)", http, name, modtime, + modtime ? (int)*modtime : 0, buffer, (int)bufsize)); + + if (!name) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("No printer name!"), 1); + return (HTTP_NOT_ACCEPTABLE); + } + + if (!modtime) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("No modification time!"), 1); + return (HTTP_NOT_ACCEPTABLE); + } + + if (!buffer || bufsize <= 1) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Bad filename buffer!"), 1); + return (HTTP_NOT_ACCEPTABLE); + } + +#ifndef WIN32 + /* + * See if the PPD file is available locally... + */ + + if (!cg->servername[0]) + cupsServer(); + + if (!strcasecmp(cg->servername, "localhost")) + { + char ppdname[1024]; /* PPD filename */ + struct stat ppdinfo; /* PPD file information */ + + + snprintf(ppdname, sizeof(ppdname), "%s/ppd/%s.ppd", cg->cups_serverroot, + name); + if (!stat(ppdname, &ppdinfo)) + { + /* + * OK, the file exists, use it! + */ + + if (buffer[0]) + { + unlink(buffer); + + if (symlink(ppdname, buffer) && errno != EEXIST) + { + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + + return (HTTP_SERVER_ERROR); + } + } + else + { + int tries; /* Number of tries */ + const char *tmpdir; /* TMPDIR environment variable */ + struct timeval curtime; /* Current time */ + + /* + * Previously we put root temporary files in the default CUPS temporary + * directory under /var/spool/cups. However, since the scheduler cleans + * out temporary files there and runs independently of the user apps, we + * don't want to use it unless specifically told to by cupsd. + */ + + if ((tmpdir = getenv("TMPDIR")) == NULL) +# ifdef __APPLE__ + tmpdir = "/private/tmp"; /* /tmp is a symlink to /private/tmp */ +# else + tmpdir = "/tmp"; +# endif /* __APPLE__ */ + + /* + * Make the temporary name using the specified directory... + */ + + tries = 0; + + do + { + /* + * Get the current time of day... + */ + + gettimeofday(&curtime, NULL); + + /* + * Format a string using the hex time values... + */ + + snprintf(buffer, bufsize, "%s/%08lx%05lx", tmpdir, + (unsigned long)curtime.tv_sec, + (unsigned long)curtime.tv_usec); + + /* + * Try to make a symlink... + */ + + if (!symlink(ppdname, buffer)) + break; + + tries ++; + } + while (tries < 1000); + + if (tries >= 1000) + { + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + + return (HTTP_SERVER_ERROR); + } + } + + if (*modtime >= ppdinfo.st_mtime) + return (HTTP_NOT_MODIFIED); + else + { + *modtime = ppdinfo.st_mtime; + return (HTTP_OK); + } + } + } +#endif /* !WIN32 */ + + /* + * Try finding a printer URI for this printer... + */ + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (HTTP_SERVICE_UNAVAILABLE); + + if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port, + resource, sizeof(resource), 0)) + return (HTTP_NOT_FOUND); + + DEBUG_printf(("2cupsGetPPD3: Printer hostname=\"%s\", port=%d", hostname, + port)); + + /* + * Remap local hostname to localhost... + */ + + httpGetHostname(NULL, localhost, sizeof(localhost)); + + DEBUG_printf(("2cupsGetPPD3: Local hostname=\"%s\"", localhost)); + + if (!strcasecmp(localhost, hostname)) + strcpy(hostname, "localhost"); + + /* + * Get the hostname and port number we are connected to... + */ + + httpGetHostname(http, http_hostname, sizeof(http_hostname)); + http_port = _httpAddrPort(http->hostaddr); + + DEBUG_printf(("2cupsGetPPD3: Connection hostname=\"%s\", port=%d", + http_hostname, http_port)); + + /* + * Reconnect to the correct server as needed... + */ + + if (!strcasecmp(http_hostname, hostname) && port == http_port) + http2 = http; + else if ((http2 = httpConnectEncrypt(hostname, port, + cupsEncryption())) == NULL) + { + DEBUG_puts("1cupsGetPPD3: Unable to connect to server!"); + + return (HTTP_SERVICE_UNAVAILABLE); + } + + /* + * Get a temp file... + */ + + if (buffer[0]) + fd = open(buffer, O_CREAT | O_TRUNC | O_WRONLY, 0600); + else + fd = cupsTempFd(buffer, bufsize); + + if (fd < 0) + { + /* + * Can't open file; close the server connection and return NULL... + */ + + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + + if (http2 != http) + httpClose(http2); + + return (HTTP_SERVER_ERROR); + } + + /* + * And send a request to the HTTP server... + */ + + strlcat(resource, ".ppd", sizeof(resource)); + + if (*modtime > 0) + httpSetField(http2, HTTP_FIELD_IF_MODIFIED_SINCE, + httpGetDateString(*modtime)); + + status = cupsGetFd(http2, resource, fd); + + close(fd); + + /* + * See if we actually got the file or an error... + */ + + if (status == HTTP_OK) + *modtime = httpGetDateTime(httpGetField(http2, HTTP_FIELD_DATE)); + else if (status != HTTP_NOT_MODIFIED) + { + _cupsSetHTTPError(status); + + unlink(cg->ppd_filename); + } + + if (http2 != http) + httpClose(http2); + + /* + * Return the PPD file... + */ + + DEBUG_printf(("1cupsGetPPD3: Returning status %d", status)); + + return (status); +} + + +/* + * 'cupsGetPrinters()' - Get a list of printers from the default server. + * + * This function is deprecated - use @link cupsGetDests@ instead. + * + * @deprecated@ + */ + +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 */ + char **temp; /* Temporary pointer */ + http_t *http; /* Connection to server */ + + + /* + * Range check input... + */ + + if (!printers) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (0); + } + + *printers = NULL; + + /* + * Try to connect to the server... + */ + + if ((http = _cupsConnect()) == NULL) + return (0); + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requested-attributes + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", NULL, "printer-name"); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type", 0); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type-mask", CUPS_PRINTER_CLASS); + + /* + * Do the request and get back a response... + */ + + n = 0; + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + 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); + } + + return (n); +} + + +/* + * 'cupsGetServerPPD()' - Get an available PPD file from the server. + * + * This function returns the named PPD file from the server. The + * list of available PPDs is provided by the IPP @code CUPS_GET_PPDS@ + * operation. + * + * You must remove (unlink) the PPD file when you are finished with + * it. The PPD filename is stored in a static location that will be + * overwritten on the next call to @link cupsGetPPD@, @link cupsGetPPD2@, + * or @link cupsGetServerPPD@. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +char * /* O - Name of PPD file or @code NULL@ on error */ +cupsGetServerPPD(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name) /* I - Name of PPD file ("ppd-name") */ +{ + int fd; /* PPD file descriptor */ + ipp_t *request; /* IPP request */ + _cups_globals_t *cg = _cupsGlobals(); + /* Pointer to library globals */ + + + /* + * Range check input... + */ + + if (!name) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("No PPD name!"), 1); + + return (NULL); + } + + if (!http) + if ((http = _cupsConnect()) == NULL) + return (NULL); + + /* + * Get a temp file... + */ + + if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0) + { + /* + * Can't open file; close the server connection and return NULL... + */ + + _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0); + + return (NULL); + } + + /* + * Get the PPD file... + */ + + request = ippNewRequest(CUPS_GET_PPD); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name", NULL, + name); + + ippDelete(cupsDoIORequest(http, request, "/", -1, fd)); + + close(fd); + + if (cupsLastError() != IPP_OK) + { + unlink(cg->ppd_filename); + return (NULL); + } + else + return (cg->ppd_filename); +} + + +/* + * 'cupsLastError()' - Return the last IPP status code. + */ + +ipp_status_t /* O - IPP status code from last request */ +cupsLastError(void) +{ + return (_cupsGlobals()->last_error); +} + + +/* + * 'cupsLastErrorString()' - Return the last IPP status-message. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +const char * /* O - status-message text from last request */ +cupsLastErrorString(void) +{ + return (_cupsGlobals()->last_status_message); +} + + +/* + * 'cupsPrintFile()' - Print a file to a printer or class on the default server. + */ + +int /* O - Job ID or 0 on error */ +cupsPrintFile(const char *name, /* I - Destination 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(name=\"%s\", filename=\"%s\", " + "title=\"%s\", num_options=%d, options=%p)", + name, filename, title, num_options, options)); + + return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, 1, &filename, title, + num_options, options)); +} + + +/* + * 'cupsPrintFile2()' - Print a file to a printer or class on the specified + * server. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +int /* O - Job ID or 0 on error */ +cupsPrintFile2( + http_t *http, /* I - Connection to server */ + const char *name, /* I - Destination 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(("cupsPrintFile2(http=%p, name=\"%s\", filename=\"%s\", " + "title=\"%s\", num_options=%d, options=%p)", + http, name, filename, title, num_options, options)); + + return (cupsPrintFiles2(http, name, 1, &filename, title, num_options, + options)); +} + + +/* + * 'cupsPrintFiles()' - Print one or more files to a printer or class on the + * default server. + */ + +int /* O - Job ID or 0 on error */ +cupsPrintFiles( + const char *name, /* I - Destination 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 */ +{ + DEBUG_printf(("cupsPrintFiles(name=\"%s\", num_files=%d, " + "files=%p, title=\"%s\", num_options=%d, options=%p)", + name, num_files, files, title, num_options, options)); + + /* + * Print the file(s)... + */ + + return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, num_files, files, title, + num_options, options)); +} + + +/* + * 'cupsPrintFiles2()' - Print one or more files to a printer or class on the + * specified server. + * + * @since CUPS 1.1.21/Mac OS X 10.4@ + */ + +int /* O - Job ID or 0 on error */ +cupsPrintFiles2( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name, /* I - Destination 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 */ + int job_id; /* New job ID */ + const char *docname; /* Basename of current filename */ + const char *format; /* Document format */ + cups_file_t *fp; /* Current file */ + char buffer[8192]; /* Copy buffer */ + ssize_t bytes; /* Bytes in buffer */ + http_status_t status; /* Status of write */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + ipp_status_t cancel_status; /* Status code to preserve */ + char *cancel_message; /* Error message to preserve */ + + + DEBUG_printf(("cupsPrintFiles2(http=%p, name=\"%s\", num_files=%d, " + "files=%p, title=\"%s\", num_options=%d, options=%p)", + http, name, num_files, files, title, num_options, options)); + + /* + * Range check input... + */ + + if (!name || num_files < 1 || !files) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); + + return (0); + } + + /* + * Create the print job... + */ + + if ((job_id = cupsCreateJob(http, name, title, num_options, options)) == 0) + return (0); + + /* + * Send each of the files... + */ + + if (cupsGetOption("raw", num_options, options)) + format = CUPS_FORMAT_RAW; + else if ((format = cupsGetOption("document-format", num_options, + options)) == NULL) + format = CUPS_FORMAT_AUTO; + + for (i = 0; i < num_files; i ++) + { + /* + * Start the next file... + */ + + if ((docname = strrchr(files[i], '/')) != NULL) + docname ++; + else + docname = files[i]; + + if ((fp = cupsFileOpen(files[i], "rb")) == NULL) + { + /* + * Unable to open print file, cancel the job and return... + */ + + _cupsSetError(IPP_DOCUMENT_ACCESS_ERROR, NULL, 0); + goto cancel_job; + } + + status = cupsStartDocument(http, name, job_id, docname, format, + i == (num_files - 1)); + + while (status == HTTP_CONTINUE && + (bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) + status = cupsWriteRequestData(http, buffer, bytes); + + cupsFileClose(fp); + + if (status != HTTP_CONTINUE || cupsFinishDocument(http, name) != IPP_OK) + { + /* + * Unable to queue, cancel the job and return... + */ + + goto cancel_job; + } + } + + return (job_id); + + /* + * If we get here, something happened while sending the print job so we need + * to cancel the job without setting the last error (since we need to preserve + * the current error... + */ + + cancel_job: + + cancel_status = cg->last_error; + cancel_message = cg->last_status_message ? + _cupsStrRetain(cg->last_status_message) : NULL; + + cupsCancelJob2(http, name, job_id, 0); + + cg->last_error = cancel_status; + cg->last_status_message = cancel_message; + + return (0); +} + + +/* + * 'cupsStartDocument()' - Add a document to a job created with cupsCreateJob(). + * + * Use @link cupsWriteRequestData@ to write data for the document and + * @link cupsFinishDocument@ to finish the document and get the submission status. + * + * The MIME type constants @code CUPS_FORMAT_AUTO@, @code CUPS_FORMAT_PDF@, + * @code CUPS_FORMAT_POSTSCRIPT@, @code CUPS_FORMAT_RAW@, and + * @code CUPS_FORMAT_TEXT@ are provided for the "format" argument, although + * any supported MIME type string can be supplied. + * + * @since CUPS 1.4/Mac OS X 10.6@ + */ + +http_status_t /* O - HTTP status of request */ +cupsStartDocument( + http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ + const char *name, /* I - Destination name */ + int job_id, /* I - Job ID from @link cupsCreateJob@ */ + const char *docname, /* I - Name of document */ + const char *format, /* I - MIME type or @code CUPS_FORMAT_foo@ */ + int last_document) /* I - 1 for last document in job, 0 otherwise */ +{ + char resource[1024], /* Resource for destinatio */ + printer_uri[1024]; /* Printer URI */ + ipp_t *request; /* Send-Document request */ + http_status_t status; /* HTTP status */ + + + /* + * Create a Send-Document request... + */ + + if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL) + { + _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); + return (0); + } + + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", + NULL, "localhost", ippPort(), "/printers/%s", name); + snprintf(resource, sizeof(resource), "/printers/%s", name); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, printer_uri); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + if (docname) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", + NULL, docname); + if (format) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, + "document-format", NULL, format); + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document); + + /* + * Send and delete the request, then return the status... + */ + + status = cupsSendRequest(http, request, resource, CUPS_LENGTH_VARIABLE); + + ippDelete(request); + + return (status); +} + + +/* + * '_cupsConnect()' - Get the default server connection... + */ + +http_t * /* O - HTTP connection */ +_cupsConnect(void) +{ + _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + + + /* + * See if we are connected to the same server... + */ + + if (cg->http) + { + /* + * Compare the connection hostname, port, and encryption settings to + * the cached defaults; these were initialized the first time we + * connected... + */ + + if (strcmp(cg->http->hostname, cg->server) || + cg->ipp_port != _httpAddrPort(cg->http->hostaddr) || + (cg->http->encryption != cg->encryption && + cg->http->encryption == HTTP_ENCRYPT_NEVER)) + { + /* + * Need to close the current connection because something has changed... + */ + + httpClose(cg->http); + cg->http = NULL; + } + } + + /* + * (Re)connect as needed... + */ + + if (!cg->http) + { + if ((cg->http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + if (errno) + _cupsSetError(IPP_SERVICE_UNAVAILABLE, NULL, 0); + else + _cupsSetError(IPP_SERVICE_UNAVAILABLE, + _("Unable to connect to host."), 1); + } + } + + /* + * Return the cached connection... + */ + + return (cg->http); +} + + +/* + * 'cups_get_printer_uri()' - Get the printer-uri-supported attribute for the + * first printer in a class. + */ + +static int /* O - 1 on success, 0 on failure */ +cups_get_printer_uri( + http_t *http, /* I - Connection to server */ + const char *name, /* I - Name of printer or class */ + char *host, /* I - Hostname buffer */ + int hostsize, /* I - Size of hostname buffer */ + int *port, /* O - Port number */ + char *resource, /* I - Resource buffer */ + int resourcesize, /* I - Size of resource buffer */ + int depth) /* I - Depth of query */ +{ + int i; /* Looping var */ + int http_port; /* Port number */ + http_t *http2; /* Alternate HTTP connection */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* Current attribute */ + char uri[HTTP_MAX_URI], /* printer-uri attribute */ + scheme[HTTP_MAX_URI], /* Scheme name */ + username[HTTP_MAX_URI], /* Username:password */ + classname[255], /* Temporary class name */ + http_hostname[HTTP_MAX_HOST]; + /* Hostname associated with connection */ + static const char * const requested_attrs[] = + { /* Requested attributes */ + "member-uris", + "printer-uri-supported", + "printer-type" + }; + + + DEBUG_printf(("7cups_get_printer_uri(http=%p, name=\"%s\", host=%p, " + "hostsize=%d, resource=%p, resourcesize=%d, depth=%d)", + http, name, host, hostsize, resource, resourcesize, depth)); + + /* + * Setup the printer URI... + */ + + if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) + { + _cupsSetError(IPP_INTERNAL_ERROR, _("Unable to create printer-uri!"), 1); + + *host = '\0'; + *resource = '\0'; + + return (0); + } + + DEBUG_printf(("9cups_get_printer_uri: printer-uri=\"%s\"", uri)); + + /* + * Get the hostname and port number we are connected to... + */ + + httpGetHostname(http, http_hostname, sizeof(http_hostname)); + http_port = _httpAddrPort(http->hostaddr); + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requested-attributes + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + 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(http, request, "/")) != NULL) + { + if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) + { + /* + * Get the first actual printer name in the class... + */ + + for (i = 0; i < attr->num_values; i ++) + { + httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, + scheme, sizeof(scheme), username, sizeof(username), + host, hostsize, port, resource, resourcesize); + if (!strncmp(resource, "/printers/", 10)) + { + /* + * Found a printer! + */ + + ippDelete(response); + + return (1); + } + } + + /* + * No printers in this class - try recursively looking for a printer, + * but not more than 3 levels deep... + */ + + if (depth < 3) + { + for (i = 0; i < attr->num_values; i ++) + { + httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, + scheme, sizeof(scheme), username, sizeof(username), + host, hostsize, port, resource, resourcesize); + if (!strncmp(resource, "/classes/", 9)) + { + /* + * Found a class! Connect to the right server... + */ + + if (!strcasecmp(http_hostname, host) && *port == http_port) + http2 = http; + else if ((http2 = httpConnectEncrypt(host, *port, + cupsEncryption())) == NULL) + { + DEBUG_puts("8cups_get_printer_uri: Unable to connect to server!"); + + continue; + } + + /* + * Look up printers on that server... + */ + + strlcpy(classname, resource + 9, sizeof(classname)); + + cups_get_printer_uri(http2, classname, host, hostsize, port, + resource, resourcesize, depth + 1); + + /* + * Close the connection as needed... + */ + + if (http2 != http) + httpClose(http2); + + if (*host) + return (1); + } + } + } + } + else if ((attr = ippFindAttribute(response, "printer-uri-supported", + IPP_TAG_URI)) != NULL) + { + httpSeparateURI(HTTP_URI_CODING_ALL, + _httpResolveURI(attr->values[0].string.text, uri, + sizeof(uri), 0), + scheme, sizeof(scheme), username, sizeof(username), + host, hostsize, port, resource, resourcesize); + ippDelete(response); + + if (!strncmp(resource, "/classes/", 9)) + { + _cupsSetError(IPP_INTERNAL_ERROR, + _("No printer-uri found for class!"), 1); + + *host = '\0'; + *resource = '\0'; + + return (0); + } + + return (1); + } + + ippDelete(response); + } + + if (cupsLastError() != IPP_NOT_FOUND) + _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found!"), 1); + + *host = '\0'; + *resource = '\0'; + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/versioning.h b/cups/versioning.h new file mode 100644 index 0000000000..7d506f8935 --- /dev/null +++ b/cups/versioning.h @@ -0,0 +1,80 @@ +/* + * "$Id$" + * + * API versioning definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_VERSIONING_H_ +# define _CUPS_VERSIONING_H_ + +/* + * This header defines several constants - _CUPS_DEPRECATED, + * _CUPS_API_1_1, _CUPS_API_1_1_19, _CUPS_API_1_1_20, _CUPS_API_1_1_21, + * _CUPS_API_1_2, _CUPS_API_1_3, _CUPS_API_1_4 - which add compiler- + * specific attributes that flag functions that are deprecated or added + * in particular releases. + * + * On Mac OS X, the _CUPS_API_* constants are defined based on the values of + * the MAC_OS_X_VERSION_MIN_ALLOWED and MAC_OS_X_VERSION_MAX_ALLOWED constants + * provided by the compiler. + */ + +# if defined(__APPLE__) && !defined(_CUPS_SOURCE) +# include +# ifndef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +# define AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER __attribute__((unavailable)) +# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */ +# ifndef AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +# define AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER __attribute__((unavailable)) +# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER */ +# ifndef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +# define AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER __attribute__((unavailable)) +# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER */ +# ifndef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +# define AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER __attribute__((unavailable)) +# endif /* !AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER */ +# define _CUPS_API_1_1_19 AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER +# define _CUPS_API_1_1_20 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +# define _CUPS_API_1_1_21 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER +# define _CUPS_API_1_2 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +# define _CUPS_API_1_3 AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER +# define _CUPS_API_1_4 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +# else +# define _CUPS_API_1_1_19 +# define _CUPS_API_1_1_20 +# define _CUPS_API_1_1_21 +# define _CUPS_API_1_2 +# define _CUPS_API_1_3 +# define _CUPS_API_1_4 +# endif /* __APPLE__ && !_CUPS_SOURCE */ + +/* + * With GCC 3.0 and higher, we can mark old APIs "deprecated" so you get + * a warning at compile-time. + */ + +# if defined(__GNUC__) && __GNUC__ > 2 +# define _CUPS_DEPRECATED __attribute__ ((__deprecated__)) +# else +# define _CUPS_DEPRECATED +# endif /* __GNUC__ && __GNUC__ > 2 */ + +# ifndef __GNUC__ +# define __attribute__(x) +# endif /* !__GNUC__ */ + +#endif /* !_CUPS_VERSIONING_H_ */ + +/* + * End of "$Id$". + */ diff --git a/data/HPGLprolog b/data/HPGLprolog new file mode 100644 index 0000000000..2ebf985743 --- /dev/null +++ b/data/HPGLprolog @@ -0,0 +1,27 @@ +%%BeginResource: procset hpgltops 1.1 0 +% +% "$Id: HPGLprolog 6649 2007-07-11 21:46:42Z 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 2007 by Apple Inc. +% Copyright 1993-2005 by Easy Software Products +% +% These coded instructions, statements, and computer programs are the +% property of Apple Inc. and are protected by Federal copyright law. +% Distribution and use rights are outlined in the file "LICENSE.txt" +% which is included with the CUPS source distribution. +% +/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 0000000000..422d7083b4 --- /dev/null +++ b/data/Makefile @@ -0,0 +1,215 @@ +# +# "$Id$" +# +# Datafile makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1993-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +# +# Data files... +# + +BANNERS = \ + classified \ + confidential \ + secret \ + standard \ + topsecret \ + unclassified + +CHARMAPS = \ + euc-cn.txt \ + euc-jp.txt \ + euc-kr.txt \ + euc-tw.txt \ + iso-8859-10.txt \ + iso-8859-11.txt \ + iso-8859-13.txt \ + iso-8859-14.txt \ + iso-8859-15.txt \ + iso-8859-16.txt \ + iso-8859-1.txt \ + iso-8859-2.txt \ + iso-8859-3.txt \ + iso-8859-4.txt \ + iso-8859-5.txt \ + iso-8859-6.txt \ + iso-8859-7.txt \ + iso-8859-8.txt \ + iso-8859-9.txt \ + jis-x0213.txt \ + koi8-r.txt \ + koi8-u.txt \ + mac-roman.txt \ + windows-1250.txt \ + windows-1251.txt \ + windows-1252.txt \ + windows-1253.txt \ + windows-1254.txt \ + windows-1255.txt \ + windows-1256.txt \ + windows-1257.txt \ + windows-1258.txt \ + windows-1361.txt \ + windows-874.txt \ + windows-932.txt \ + windows-936.txt \ + windows-949.txt \ + windows-950.txt + +CHARSETS = \ + utf-8 + +DATAFILES = \ + HPGLprolog \ + psglyphs \ + testprint + +PPDCFILES = \ + epson.h \ + escp.h \ + font.defs \ + hp.h \ + label.h \ + media.defs \ + pcl.h \ + raster.defs + + +# +# Make everything... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Dummy depend... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + $(INSTALL_DIR) -m 755 $(DATADIR)/banners + for file in $(BANNERS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/banners; \ + done + $(INSTALL_DIR) -m 755 $(DATADIR)/charmaps + for file in $(CHARMAPS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/charmaps; \ + done + $(INSTALL_DIR) -m 755 $(DATADIR)/charsets + if test "x$(BANNERTOPS)" != x -o "x$(TEXTTOPS)" != x; then \ + for file in $(CHARSETS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/charsets; \ + done; \ + fi + $(INSTALL_DIR) -m 755 $(DATADIR)/data + for file in $(DATAFILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/data; \ + done + $(INSTALL_DIR) -m 755 $(DATADIR)/model + $(INSTALL_DIR) -m 755 $(DATADIR)/ppdc + for file in $(PPDCFILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/ppdc; \ + done + $(INSTALL_DIR) -m 755 $(DATADIR)/profiles + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: + for file in $(BANNERS); do \ + $(RM) $(DATADIR)/banners/$$file; \ + done + for file in $(CHARMAPS); do \ + $(RM) $(DATADIR)/charmaps/$$file; \ + done + for file in $(CHARSETS); do \ + $(RM) $(DATADIR)/charsets/$$file; \ + done + for file in $(DATAFILES); do \ + $(RM) $(DATADIR)/data/$$file; \ + done + for file in $(PPDCFILES); do \ + $(RM) $(DATADIR)/ppdc/$$file; \ + done + -$(RMDIR) $(DATADIR)/profiles + -$(RMDIR) $(DATADIR)/ppdc + -$(RMDIR) $(DATADIR)/model + -$(RMDIR) $(DATADIR)/data + -$(RMDIR) $(DATADIR)/charsets + -$(RMDIR) $(DATADIR)/charmaps + -$(RMDIR) $(DATADIR)/banners + -$(RMDIR) $(DATADIR) + + +# +# End of "$Id$". +# diff --git a/data/classified b/data/classified new file mode 100644 index 0000000000..ca01a13b7d --- /dev/null +++ b/data/classified @@ -0,0 +1,6 @@ +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Classified +Footer Classified +Image images/cups.png + diff --git a/data/confidential b/data/confidential new file mode 100644 index 0000000000..f1f0d854db --- /dev/null +++ b/data/confidential @@ -0,0 +1,6 @@ +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Confidential +Footer Confidential +Image images/cups.png + diff --git a/data/cups.irix b/data/cups.irix new file mode 100644 index 0000000000..476383acb5 --- /dev/null +++ b/data/cups.irix @@ -0,0 +1,3 @@ +#%PAM-1.0 +auth required pam_unix.so shadow nodelay nullok +account required pam_unix.so diff --git a/data/cups.pam b/data/cups.pam new file mode 100644 index 0000000000..f38e70184a --- /dev/null +++ b/data/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/data/cups.suse b/data/cups.suse new file mode 100644 index 0000000000..a9369e1619 --- /dev/null +++ b/data/cups.suse @@ -0,0 +1,2 @@ +auth required pam_unix2.so nullok shadow +account required pam_unix2.so diff --git a/data/epson.h b/data/epson.h new file mode 100644 index 0000000000..13cb1a3464 --- /dev/null +++ b/data/epson.h @@ -0,0 +1,27 @@ +/* + * "$Id$" + * + * This file contains model number definitions for the CUPS sample + * ESC/P driver. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#define EPSON_9PIN 0 /* 9-pin dot matrix */ +#define EPSON_24PIN 1 /* 24-pin dot matrix */ +#define EPSON_COLOR 2 /* Epson Stylus Color with ESC . */ +#define EPSON_PHOTO 3 /* Epson Stylus Photo with ESC . */ +#define EPSON_ICOLOR 4 /* Epson Stylus Color with ESC i */ +#define EPSON_IPHOTO 5 /* Epson Stylus Photo with ESC i */ + + +/* + * End of "$Id$". + */ diff --git a/data/escp.h b/data/escp.h new file mode 100644 index 0000000000..94389f3b93 --- /dev/null +++ b/data/escp.h @@ -0,0 +1,34 @@ +/* + * "$Id$" + * + * This file contains model number definitions for the CUPS unified + * ESC/P driver. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* General ESC/P Support */ +#define ESCP_DOTMATRIX 0x1 /* Dot matrix printer? */ +#define ESCP_MICROWEAVE 0x2 /* Use microweave command? */ +#define ESCP_STAGGER 0x4 /* Are color jets staggered? */ +#define ESCP_ESCK 0x8 /* Use print mode command?*/ +#define ESCP_EXT_UNITS 0x10 /* Use extended unit commands? */ +#define ESCP_EXT_MARGINS 0x20 /* Use extended margin command */ +#define ESCP_USB 0x40 /* Send USB packet mode escape? */ +#define ESCP_PAGE_SIZE 0x80 /* Use page size command */ +#define ESCP_RASTER_ESCI 0x100 /* Use ESC i graphics command */ + +/* Remote mode support */ +#define ESCP_REMOTE 0x1000 /* Use remote mode commands? */ + + +/* + * End of "$Id$". + */ diff --git a/data/euc-cn.txt b/data/euc-cn.txt new file mode 100644 index 0000000000..72726c5fad --- /dev/null +++ b/data/euc-cn.txt @@ -0,0 +1,7536 @@ +# euc-cn.txt - EUC to Unicode charmap +0x00000000 0x0000 # 0 +0x00000001 0x0001 # 0 +0x00000002 0x0002 # 0 +0x00000003 0x0003 # 0 +0x00000004 0x0004 # 0 +0x00000005 0x0005 # 0 +0x00000006 0x0006 # 0 +0x00000007 0x0007 # 0 +0x00000008 0x0008 # 0 +0x00000009 0x0009 # 0 +0x0000000A 0x000A # 0 +0x0000000B 0x000B # 0 +0x0000000C 0x000C # 0 +0x0000000D 0x000D # 0 +0x0000000E 0x000E # 0 +0x0000000F 0x000F # 0 +0x00000010 0x0010 # 0 +0x00000011 0x0011 # 0 +0x00000012 0x0012 # 0 +0x00000013 0x0013 # 0 +0x00000014 0x0014 # 0 +0x00000015 0x0015 # 0 +0x00000016 0x0016 # 0 +0x00000017 0x0017 # 0 +0x00000018 0x0018 # 0 +0x00000019 0x0019 # 0 +0x0000001A 0x001A # 0 +0x0000001B 0x001B # 0 +0x0000001C 0x001C # 0 +0x0000001D 0x001D # 0 +0x0000001E 0x001E # 0 +0x0000001F 0x001F # 0 +0x00000020 0x0020 # 0 +0x00000021 0x0021 # 0 +0x00000022 0x0022 # 0 +0x00000023 0x0023 # 0 +0x00000024 0x0024 # 0 +0x00000025 0x0025 # 0 +0x00000026 0x0026 # 0 +0x00000027 0x0027 # 0 +0x00000028 0x0028 # 0 +0x00000029 0x0029 # 0 +0x0000002A 0x002A # 0 +0x0000002B 0x002B # 0 +0x0000002C 0x002C # 0 +0x0000002D 0x002D # 0 +0x0000002E 0x002E # 0 +0x0000002F 0x002F # 0 +0x00000030 0x0030 # 0 +0x00000031 0x0031 # 0 +0x00000032 0x0032 # 0 +0x00000033 0x0033 # 0 +0x00000034 0x0034 # 0 +0x00000035 0x0035 # 0 +0x00000036 0x0036 # 0 +0x00000037 0x0037 # 0 +0x00000038 0x0038 # 0 +0x00000039 0x0039 # 0 +0x0000003A 0x003A # 0 +0x0000003B 0x003B # 0 +0x0000003C 0x003C # 0 +0x0000003D 0x003D # 0 +0x0000003E 0x003E # 0 +0x0000003F 0x003F # 0 +0x00000040 0x0040 # 0 +0x00000041 0x0041 # 0 +0x00000042 0x0042 # 0 +0x00000043 0x0043 # 0 +0x00000044 0x0044 # 0 +0x00000045 0x0045 # 0 +0x00000046 0x0046 # 0 +0x00000047 0x0047 # 0 +0x00000048 0x0048 # 0 +0x00000049 0x0049 # 0 +0x0000004A 0x004A # 0 +0x0000004B 0x004B # 0 +0x0000004C 0x004C # 0 +0x0000004D 0x004D # 0 +0x0000004E 0x004E # 0 +0x0000004F 0x004F # 0 +0x00000050 0x0050 # 0 +0x00000051 0x0051 # 0 +0x00000052 0x0052 # 0 +0x00000053 0x0053 # 0 +0x00000054 0x0054 # 0 +0x00000055 0x0055 # 0 +0x00000056 0x0056 # 0 +0x00000057 0x0057 # 0 +0x00000058 0x0058 # 0 +0x00000059 0x0059 # 0 +0x0000005A 0x005A # 0 +0x0000005B 0x005B # 0 +0x0000005C 0x005C # 0 +0x0000005D 0x005D # 0 +0x0000005E 0x005E # 0 +0x0000005F 0x005F # 0 +0x00000060 0x0060 # 0 +0x00000061 0x0061 # 0 +0x00000062 0x0062 # 0 +0x00000063 0x0063 # 0 +0x00000064 0x0064 # 0 +0x00000065 0x0065 # 0 +0x00000066 0x0066 # 0 +0x00000067 0x0067 # 0 +0x00000068 0x0068 # 0 +0x00000069 0x0069 # 0 +0x0000006A 0x006A # 0 +0x0000006B 0x006B # 0 +0x0000006C 0x006C # 0 +0x0000006D 0x006D # 0 +0x0000006E 0x006E # 0 +0x0000006F 0x006F # 0 +0x00000070 0x0070 # 0 +0x00000071 0x0071 # 0 +0x00000072 0x0072 # 0 +0x00000073 0x0073 # 0 +0x00000074 0x0074 # 0 +0x00000075 0x0075 # 0 +0x00000076 0x0076 # 0 +0x00000077 0x0077 # 0 +0x00000078 0x0078 # 0 +0x00000079 0x0079 # 0 +0x0000007A 0x007A # 0 +0x0000007B 0x007B # 0 +0x0000007C 0x007C # 0 +0x0000007D 0x007D # 0 +0x0000007E 0x007E # 0 +0x0000007F 0x007F # 0 +0x0000A1A1 0x3000 # 0 +0x0000A1A2 0x3001 # 0 +0x0000A1A3 0x3002 # 0 +0x0000A1A4 0x30FB # 0 +0x0000A1A5 0x203E # 0 +0x0000A1A6 0x02C7 # 0 +0x0000A1A7 0x00A8 # 0 +0x0000A1A8 0x3003 # 0 +0x0000A1A9 0x3005 # 0 +0x0000A1AA 0x2015 # 0 +0x0000A1AB 0x30FC # 0 +0x0000A1AC 0x2225 # 0 +0x0000A1AD 0x2026 # 0 +0x0000A1AE 0x2018 # 0 +0x0000A1AF 0x2019 # 0 +0x0000A1B0 0x201C # 0 +0x0000A1B1 0x201D # 0 +0x0000A1B2 0x3014 # 0 +0x0000A1B3 0x3015 # 0 +0x0000A1B4 0x3008 # 0 +0x0000A1B5 0x3009 # 0 +0x0000A1B6 0x300A # 0 +0x0000A1B7 0x300B # 0 +0x0000A1B8 0x300C # 0 +0x0000A1B9 0x300D # 0 +0x0000A1BA 0x300E # 0 +0x0000A1BB 0x300F # 0 +0x0000A1BC 0x3016 # 0 +0x0000A1BD 0x3017 # 0 +0x0000A1BE 0x3010 # 0 +0x0000A1BF 0x3011 # 0 +0x0000A1C0 0x00B1 # 0 +0x0000A1C1 0x00D7 # 0 +0x0000A1C2 0x00F7 # 0 +0x0000A1C3 0x2236 # 0 +0x0000A1C4 0x2227 # 0 +0x0000A1C5 0x2228 # 0 +0x0000A1C6 0x2211 # 0 +0x0000A1C7 0x220F # 0 +0x0000A1C8 0x222A # 0 +0x0000A1C9 0x2229 # 0 +0x0000A1CA 0x2208 # 0 +0x0000A1CB 0x2237 # 0 +0x0000A1CC 0x221A # 0 +0x0000A1CD 0x22A5 # 0 +0x0000A1CF 0x2220 # 0 +0x0000A1D0 0x2312 # 0 +0x0000A1D1 0x2299 # 0 +0x0000A1D2 0x222B # 0 +0x0000A1D3 0x222E # 0 +0x0000A1D4 0x2261 # 0 +0x0000A1D5 0x224C # 0 +0x0000A1D6 0x2248 # 0 +0x0000A1D7 0x223D # 0 +0x0000A1D8 0x221D # 0 +0x0000A1D9 0x2260 # 0 +0x0000A1DA 0x226E # 0 +0x0000A1DB 0x226F # 0 +0x0000A1DC 0x2264 # 0 +0x0000A1DD 0x2265 # 0 +0x0000A1DE 0x221E # 0 +0x0000A1DF 0x2235 # 0 +0x0000A1E0 0x2234 # 0 +0x0000A1E1 0x2642 # 0 +0x0000A1E2 0x2640 # 0 +0x0000A1E3 0x00B0 # 0 +0x0000A1E4 0x2032 # 0 +0x0000A1E5 0x2033 # 0 +0x0000A1E6 0x2103 # 0 +0x0000A1E8 0x00A4 # 0 +0x0000A1E9 0x00A2 # 0 +0x0000A1EA 0x00A3 # 0 +0x0000A1EB 0x2030 # 0 +0x0000A1EC 0x00A7 # 0 +0x0000A1ED 0x2116 # 0 +0x0000A1EE 0x2606 # 0 +0x0000A1EF 0x2605 # 0 +0x0000A1F0 0x25CB # 0 +0x0000A1F1 0x25CF # 0 +0x0000A1F2 0x25CE # 0 +0x0000A1F3 0x25C7 # 0 +0x0000A1F4 0x25C6 # 0 +0x0000A1F5 0x25A1 # 0 +0x0000A1F6 0x25A0 # 0 +0x0000A1F7 0x25B3 # 0 +0x0000A1F8 0x25B2 # 0 +0x0000A1F9 0x203B # 0 +0x0000A1FA 0x2192 # 0 +0x0000A1FB 0x2190 # 0 +0x0000A1FC 0x2191 # 0 +0x0000A1FD 0x2193 # 0 +0x0000A1FE 0x3013 # 0 +0x0000A2B1 0x2488 # 0 +0x0000A2B2 0x2489 # 0 +0x0000A2B3 0x248A # 0 +0x0000A2B4 0x248B # 0 +0x0000A2B5 0x248C # 0 +0x0000A2B6 0x248D # 0 +0x0000A2B7 0x248E # 0 +0x0000A2B8 0x248F # 0 +0x0000A2B9 0x2490 # 0 +0x0000A2BA 0x2491 # 0 +0x0000A2BB 0x2492 # 0 +0x0000A2BC 0x2493 # 0 +0x0000A2BD 0x2494 # 0 +0x0000A2BE 0x2495 # 0 +0x0000A2BF 0x2496 # 0 +0x0000A2C0 0x2497 # 0 +0x0000A2C1 0x2498 # 0 +0x0000A2C2 0x2499 # 0 +0x0000A2C3 0x249A # 0 +0x0000A2C4 0x249B # 0 +0x0000A2C5 0x2474 # 0 +0x0000A2C6 0x2475 # 0 +0x0000A2C7 0x2476 # 0 +0x0000A2C8 0x2477 # 0 +0x0000A2C9 0x2478 # 0 +0x0000A2CA 0x2479 # 0 +0x0000A2CB 0x247A # 0 +0x0000A2CC 0x247B # 0 +0x0000A2CD 0x247C # 0 +0x0000A2CE 0x247D # 0 +0x0000A2CF 0x247E # 0 +0x0000A2D0 0x247F # 0 +0x0000A2D1 0x2480 # 0 +0x0000A2D2 0x2481 # 0 +0x0000A2D3 0x2482 # 0 +0x0000A2D4 0x2483 # 0 +0x0000A2D5 0x2484 # 0 +0x0000A2D6 0x2485 # 0 +0x0000A2D7 0x2486 # 0 +0x0000A2D8 0x2487 # 0 +0x0000A2D9 0x2460 # 0 +0x0000A2DA 0x2461 # 0 +0x0000A2DB 0x2462 # 0 +0x0000A2DC 0x2463 # 0 +0x0000A2DD 0x2464 # 0 +0x0000A2DE 0x2465 # 0 +0x0000A2DF 0x2466 # 0 +0x0000A2E0 0x2467 # 0 +0x0000A2E1 0x2468 # 0 +0x0000A2E2 0x2469 # 0 +0x0000A2F1 0x2160 # 0 +0x0000A2F2 0x2161 # 0 +0x0000A2F3 0x2162 # 0 +0x0000A2F4 0x2163 # 0 +0x0000A2F5 0x2164 # 0 +0x0000A2F6 0x2165 # 0 +0x0000A2F7 0x2166 # 0 +0x0000A2F8 0x2167 # 0 +0x0000A2F9 0x2168 # 0 +0x0000A2FA 0x2169 # 0 +0x0000A2FB 0x216A # 0 +0x0000A2FC 0x216B # 0 +0x0000A3A1 0xFF01 # 0 +0x0000A3A2 0xFF02 # 0 +0x0000A3A3 0xFF03 # 0 +0x0000A3A4 0xFF04 # 0 +0x0000A3A5 0xFF05 # 0 +0x0000A3A6 0xFF06 # 0 +0x0000A3A7 0xFF07 # 0 +0x0000A3A8 0xFF08 # 0 +0x0000A3A9 0xFF09 # 0 +0x0000A3AA 0xFF0A # 0 +0x0000A3AB 0xFF0B # 0 +0x0000A3AC 0xFF0C # 0 +0x0000A3AD 0xFF0D # 0 +0x0000A3AE 0xFF0E # 0 +0x0000A3AF 0xFF0F # 0 +0x0000A3B0 0xFF10 # 0 +0x0000A3B1 0xFF11 # 0 +0x0000A3B2 0xFF12 # 0 +0x0000A3B3 0xFF13 # 0 +0x0000A3B4 0xFF14 # 0 +0x0000A3B5 0xFF15 # 0 +0x0000A3B6 0xFF16 # 0 +0x0000A3B7 0xFF17 # 0 +0x0000A3B8 0xFF18 # 0 +0x0000A3B9 0xFF19 # 0 +0x0000A3BA 0xFF1A # 0 +0x0000A3BB 0xFF1B # 0 +0x0000A3BC 0xFF1C # 0 +0x0000A3BD 0xFF1D # 0 +0x0000A3BE 0xFF1E # 0 +0x0000A3BF 0xFF1F # 0 +0x0000A3C0 0xFF20 # 0 +0x0000A3C1 0xFF21 # 0 +0x0000A3C2 0xFF22 # 0 +0x0000A3C3 0xFF23 # 0 +0x0000A3C4 0xFF24 # 0 +0x0000A3C5 0xFF25 # 0 +0x0000A3C6 0xFF26 # 0 +0x0000A3C7 0xFF27 # 0 +0x0000A3C8 0xFF28 # 0 +0x0000A3C9 0xFF29 # 0 +0x0000A3CA 0xFF2A # 0 +0x0000A3CB 0xFF2B # 0 +0x0000A3CC 0xFF2C # 0 +0x0000A3CD 0xFF2D # 0 +0x0000A3CE 0xFF2E # 0 +0x0000A3CF 0xFF2F # 0 +0x0000A3D0 0xFF30 # 0 +0x0000A3D1 0xFF31 # 0 +0x0000A3D2 0xFF32 # 0 +0x0000A3D3 0xFF33 # 0 +0x0000A3D4 0xFF34 # 0 +0x0000A3D5 0xFF35 # 0 +0x0000A3D6 0xFF36 # 0 +0x0000A3D7 0xFF37 # 0 +0x0000A3D8 0xFF38 # 0 +0x0000A3D9 0xFF39 # 0 +0x0000A3DA 0xFF3A # 0 +0x0000A3DB 0xFF3B # 0 +0x0000A3DC 0xFF3C # 0 +0x0000A3DD 0xFF3D # 0 +0x0000A3DE 0xFF3E # 0 +0x0000A3DF 0xFF3F # 0 +0x0000A3E0 0xFF40 # 0 +0x0000A3E1 0xFF41 # 0 +0x0000A3E2 0xFF42 # 0 +0x0000A3E3 0xFF43 # 0 +0x0000A3E4 0xFF44 # 0 +0x0000A3E5 0xFF45 # 0 +0x0000A3E6 0xFF46 # 0 +0x0000A3E7 0xFF47 # 0 +0x0000A3E8 0xFF48 # 0 +0x0000A3E9 0xFF49 # 0 +0x0000A3EA 0xFF4A # 0 +0x0000A3EB 0xFF4B # 0 +0x0000A3EC 0xFF4C # 0 +0x0000A3ED 0xFF4D # 0 +0x0000A3EE 0xFF4E # 0 +0x0000A3EF 0xFF4F # 0 +0x0000A3F0 0xFF50 # 0 +0x0000A3F1 0xFF51 # 0 +0x0000A3F2 0xFF52 # 0 +0x0000A3F3 0xFF53 # 0 +0x0000A3F4 0xFF54 # 0 +0x0000A3F5 0xFF55 # 0 +0x0000A3F6 0xFF56 # 0 +0x0000A3F7 0xFF57 # 0 +0x0000A3F8 0xFF58 # 0 +0x0000A3F9 0xFF59 # 0 +0x0000A3FA 0xFF5A # 0 +0x0000A3FB 0xFF5B # 0 +0x0000A3FC 0xFF5C # 0 +0x0000A3FD 0xFF5D # 0 +0x0000A3FE 0xFF5E # 0 +0x0000A4A1 0x3041 # 0 +0x0000A4A2 0x3042 # 0 +0x0000A4A3 0x3043 # 0 +0x0000A4A4 0x3044 # 0 +0x0000A4A5 0x3045 # 0 +0x0000A4A6 0x3046 # 0 +0x0000A4A7 0x3047 # 0 +0x0000A4A8 0x3048 # 0 +0x0000A4A9 0x3049 # 0 +0x0000A4AA 0x304A # 0 +0x0000A4AB 0x304B # 0 +0x0000A4AC 0x304C # 0 +0x0000A4AD 0x304D # 0 +0x0000A4AE 0x304E # 0 +0x0000A4AF 0x304F # 0 +0x0000A4B0 0x3050 # 0 +0x0000A4B1 0x3051 # 0 +0x0000A4B2 0x3052 # 0 +0x0000A4B3 0x3053 # 0 +0x0000A4B4 0x3054 # 0 +0x0000A4B5 0x3055 # 0 +0x0000A4B6 0x3056 # 0 +0x0000A4B7 0x3057 # 0 +0x0000A4B8 0x3058 # 0 +0x0000A4B9 0x3059 # 0 +0x0000A4BA 0x305A # 0 +0x0000A4BB 0x305B # 0 +0x0000A4BC 0x305C # 0 +0x0000A4BD 0x305D # 0 +0x0000A4BE 0x305E # 0 +0x0000A4BF 0x305F # 0 +0x0000A4C0 0x3060 # 0 +0x0000A4C1 0x3061 # 0 +0x0000A4C2 0x3062 # 0 +0x0000A4C3 0x3063 # 0 +0x0000A4C4 0x3064 # 0 +0x0000A4C5 0x3065 # 0 +0x0000A4C6 0x3066 # 0 +0x0000A4C7 0x3067 # 0 +0x0000A4C8 0x3068 # 0 +0x0000A4C9 0x3069 # 0 +0x0000A4CA 0x306A # 0 +0x0000A4CB 0x306B # 0 +0x0000A4CC 0x306C # 0 +0x0000A4CD 0x306D # 0 +0x0000A4CE 0x306E # 0 +0x0000A4CF 0x306F # 0 +0x0000A4D0 0x3070 # 0 +0x0000A4D1 0x3071 # 0 +0x0000A4D2 0x3072 # 0 +0x0000A4D3 0x3073 # 0 +0x0000A4D4 0x3074 # 0 +0x0000A4D5 0x3075 # 0 +0x0000A4D6 0x3076 # 0 +0x0000A4D7 0x3077 # 0 +0x0000A4D8 0x3078 # 0 +0x0000A4D9 0x3079 # 0 +0x0000A4DA 0x307A # 0 +0x0000A4DB 0x307B # 0 +0x0000A4DC 0x307C # 0 +0x0000A4DD 0x307D # 0 +0x0000A4DE 0x307E # 0 +0x0000A4DF 0x307F # 0 +0x0000A4E0 0x3080 # 0 +0x0000A4E1 0x3081 # 0 +0x0000A4E2 0x3082 # 0 +0x0000A4E3 0x3083 # 0 +0x0000A4E4 0x3084 # 0 +0x0000A4E5 0x3085 # 0 +0x0000A4E6 0x3086 # 0 +0x0000A4E7 0x3087 # 0 +0x0000A4E8 0x3088 # 0 +0x0000A4E9 0x3089 # 0 +0x0000A4EA 0x308A # 0 +0x0000A4EB 0x308B # 0 +0x0000A4EC 0x308C # 0 +0x0000A4ED 0x308D # 0 +0x0000A4EE 0x308E # 0 +0x0000A4EF 0x308F # 0 +0x0000A4F0 0x3090 # 0 +0x0000A4F1 0x3091 # 0 +0x0000A4F2 0x3092 # 0 +0x0000A4F3 0x3093 # 0 +0x0000A5A1 0x30A1 # 0 +0x0000A5A2 0x30A2 # 0 +0x0000A5A3 0x30A3 # 0 +0x0000A5A4 0x30A4 # 0 +0x0000A5A5 0x30A5 # 0 +0x0000A5A6 0x30A6 # 0 +0x0000A5A7 0x30A7 # 0 +0x0000A5A8 0x30A8 # 0 +0x0000A5A9 0x30A9 # 0 +0x0000A5AA 0x30AA # 0 +0x0000A5AB 0x30AB # 0 +0x0000A5AC 0x30AC # 0 +0x0000A5AD 0x30AD # 0 +0x0000A5AE 0x30AE # 0 +0x0000A5AF 0x30AF # 0 +0x0000A5B0 0x30B0 # 0 +0x0000A5B1 0x30B1 # 0 +0x0000A5B2 0x30B2 # 0 +0x0000A5B3 0x30B3 # 0 +0x0000A5B4 0x30B4 # 0 +0x0000A5B5 0x30B5 # 0 +0x0000A5B6 0x30B6 # 0 +0x0000A5B7 0x30B7 # 0 +0x0000A5B8 0x30B8 # 0 +0x0000A5B9 0x30B9 # 0 +0x0000A5BA 0x30BA # 0 +0x0000A5BB 0x30BB # 0 +0x0000A5BC 0x30BC # 0 +0x0000A5BD 0x30BD # 0 +0x0000A5BE 0x30BE # 0 +0x0000A5BF 0x30BF # 0 +0x0000A5C0 0x30C0 # 0 +0x0000A5C1 0x30C1 # 0 +0x0000A5C2 0x30C2 # 0 +0x0000A5C3 0x30C3 # 0 +0x0000A5C4 0x30C4 # 0 +0x0000A5C5 0x30C5 # 0 +0x0000A5C6 0x30C6 # 0 +0x0000A5C7 0x30C7 # 0 +0x0000A5C8 0x30C8 # 0 +0x0000A5C9 0x30C9 # 0 +0x0000A5CA 0x30CA # 0 +0x0000A5CB 0x30CB # 0 +0x0000A5CC 0x30CC # 0 +0x0000A5CD 0x30CD # 0 +0x0000A5CE 0x30CE # 0 +0x0000A5CF 0x30CF # 0 +0x0000A5D0 0x30D0 # 0 +0x0000A5D1 0x30D1 # 0 +0x0000A5D2 0x30D2 # 0 +0x0000A5D3 0x30D3 # 0 +0x0000A5D4 0x30D4 # 0 +0x0000A5D5 0x30D5 # 0 +0x0000A5D6 0x30D6 # 0 +0x0000A5D7 0x30D7 # 0 +0x0000A5D8 0x30D8 # 0 +0x0000A5D9 0x30D9 # 0 +0x0000A5DA 0x30DA # 0 +0x0000A5DB 0x30DB # 0 +0x0000A5DC 0x30DC # 0 +0x0000A5DD 0x30DD # 0 +0x0000A5DE 0x30DE # 0 +0x0000A5DF 0x30DF # 0 +0x0000A5E0 0x30E0 # 0 +0x0000A5E1 0x30E1 # 0 +0x0000A5E2 0x30E2 # 0 +0x0000A5E3 0x30E3 # 0 +0x0000A5E4 0x30E4 # 0 +0x0000A5E5 0x30E5 # 0 +0x0000A5E6 0x30E6 # 0 +0x0000A5E7 0x30E7 # 0 +0x0000A5E8 0x30E8 # 0 +0x0000A5E9 0x30E9 # 0 +0x0000A5EA 0x30EA # 0 +0x0000A5EB 0x30EB # 0 +0x0000A5EC 0x30EC # 0 +0x0000A5ED 0x30ED # 0 +0x0000A5EE 0x30EE # 0 +0x0000A5EF 0x30EF # 0 +0x0000A5F0 0x30F0 # 0 +0x0000A5F1 0x30F1 # 0 +0x0000A5F2 0x30F2 # 0 +0x0000A5F3 0x30F3 # 0 +0x0000A5F4 0x30F4 # 0 +0x0000A5F5 0x30F5 # 0 +0x0000A5F6 0x30F6 # 0 +0x0000A6A1 0x0391 # 0 +0x0000A6A2 0x0392 # 0 +0x0000A6A3 0x0393 # 0 +0x0000A6A4 0x0394 # 0 +0x0000A6A5 0x0395 # 0 +0x0000A6A6 0x0396 # 0 +0x0000A6A7 0x0397 # 0 +0x0000A6A8 0x0398 # 0 +0x0000A6A9 0x0399 # 0 +0x0000A6AA 0x039A # 0 +0x0000A6AB 0x039B # 0 +0x0000A6AC 0x039C # 0 +0x0000A6AD 0x039D # 0 +0x0000A6AE 0x039E # 0 +0x0000A6AF 0x039F # 0 +0x0000A6B0 0x03A0 # 0 +0x0000A6B1 0x03A1 # 0 +0x0000A6B2 0x03A3 # 0 +0x0000A6B3 0x03A4 # 0 +0x0000A6B4 0x03A5 # 0 +0x0000A6B5 0x03A6 # 0 +0x0000A6B6 0x03A7 # 0 +0x0000A6B7 0x03A8 # 0 +0x0000A6B8 0x03A9 # 0 +0x0000A6C1 0x03B1 # 0 +0x0000A6C2 0x03B2 # 0 +0x0000A6C3 0x03B3 # 0 +0x0000A6C4 0x03B4 # 0 +0x0000A6C5 0x03B5 # 0 +0x0000A6C6 0x03B6 # 0 +0x0000A6C7 0x03B7 # 0 +0x0000A6C8 0x03B8 # 0 +0x0000A6C9 0x03B9 # 0 +0x0000A6CA 0x03BA # 0 +0x0000A6CB 0x03BB # 0 +0x0000A6CC 0x03BC # 0 +0x0000A6CD 0x03BD # 0 +0x0000A6CE 0x03BE # 0 +0x0000A6CF 0x03BF # 0 +0x0000A6D0 0x03C0 # 0 +0x0000A6D1 0x03C1 # 0 +0x0000A6D2 0x03C3 # 0 +0x0000A6D3 0x03C4 # 0 +0x0000A6D4 0x03C5 # 0 +0x0000A6D5 0x03C6 # 0 +0x0000A6D6 0x03C7 # 0 +0x0000A6D7 0x03C8 # 0 +0x0000A6D8 0x03C9 # 0 +0x0000A7A1 0x0410 # 0 +0x0000A7A2 0x0411 # 0 +0x0000A7A3 0x0412 # 0 +0x0000A7A4 0x0413 # 0 +0x0000A7A5 0x0414 # 0 +0x0000A7A6 0x0415 # 0 +0x0000A7A7 0x0401 # 0 +0x0000A7A8 0x0416 # 0 +0x0000A7A9 0x0417 # 0 +0x0000A7AA 0x0418 # 0 +0x0000A7AB 0x0419 # 0 +0x0000A7AC 0x041A # 0 +0x0000A7AD 0x041B # 0 +0x0000A7AE 0x041C # 0 +0x0000A7AF 0x041D # 0 +0x0000A7B0 0x041E # 0 +0x0000A7B1 0x041F # 0 +0x0000A7B2 0x0420 # 0 +0x0000A7B3 0x0421 # 0 +0x0000A7B4 0x0422 # 0 +0x0000A7B5 0x0423 # 0 +0x0000A7B6 0x0424 # 0 +0x0000A7B7 0x0425 # 0 +0x0000A7B8 0x0426 # 0 +0x0000A7B9 0x0427 # 0 +0x0000A7BA 0x0428 # 0 +0x0000A7BB 0x0429 # 0 +0x0000A7BC 0x042A # 0 +0x0000A7BD 0x042B # 0 +0x0000A7BE 0x042C # 0 +0x0000A7BF 0x042D # 0 +0x0000A7C0 0x042E # 0 +0x0000A7C1 0x042F # 0 +0x0000A7D1 0x0430 # 0 +0x0000A7D2 0x0431 # 0 +0x0000A7D3 0x0432 # 0 +0x0000A7D4 0x0433 # 0 +0x0000A7D5 0x0434 # 0 +0x0000A7D6 0x0435 # 0 +0x0000A7D7 0x0451 # 0 +0x0000A7D8 0x0436 # 0 +0x0000A7D9 0x0437 # 0 +0x0000A7DA 0x0438 # 0 +0x0000A7DB 0x0439 # 0 +0x0000A7DC 0x043A # 0 +0x0000A7DD 0x043B # 0 +0x0000A7DE 0x043C # 0 +0x0000A7DF 0x043D # 0 +0x0000A7E0 0x043E # 0 +0x0000A7E1 0x043F # 0 +0x0000A7E2 0x0440 # 0 +0x0000A7E3 0x0441 # 0 +0x0000A7E4 0x0442 # 0 +0x0000A7E5 0x0443 # 0 +0x0000A7E6 0x0444 # 0 +0x0000A7E7 0x0445 # 0 +0x0000A7E8 0x0446 # 0 +0x0000A7E9 0x0447 # 0 +0x0000A7EA 0x0448 # 0 +0x0000A7EB 0x0449 # 0 +0x0000A7EC 0x044A # 0 +0x0000A7ED 0x044B # 0 +0x0000A7EE 0x044C # 0 +0x0000A7EF 0x044D # 0 +0x0000A7F0 0x044E # 0 +0x0000A7F1 0x044F # 0 +0x0000A8C5 0x3105 # 0 +0x0000A8C6 0x3106 # 0 +0x0000A8C7 0x3107 # 0 +0x0000A8C8 0x3108 # 0 +0x0000A8C9 0x3109 # 0 +0x0000A8CA 0x310A # 0 +0x0000A8CB 0x310B # 0 +0x0000A8CC 0x310C # 0 +0x0000A8CD 0x310D # 0 +0x0000A8CE 0x310E # 0 +0x0000A8CF 0x310F # 0 +0x0000A8D0 0x3110 # 0 +0x0000A8D1 0x3111 # 0 +0x0000A8D2 0x3112 # 0 +0x0000A8D3 0x3113 # 0 +0x0000A8D4 0x3114 # 0 +0x0000A8D5 0x3115 # 0 +0x0000A8D6 0x3116 # 0 +0x0000A8D7 0x3117 # 0 +0x0000A8D8 0x3118 # 0 +0x0000A8D9 0x3119 # 0 +0x0000A8DA 0x311A # 0 +0x0000A8DB 0x311B # 0 +0x0000A8DC 0x311C # 0 +0x0000A8DD 0x311D # 0 +0x0000A8DE 0x311E # 0 +0x0000A8DF 0x311F # 0 +0x0000A8E0 0x3120 # 0 +0x0000A8E1 0x3121 # 0 +0x0000A8E2 0x3122 # 0 +0x0000A8E3 0x3123 # 0 +0x0000A8E4 0x3124 # 0 +0x0000A8E5 0x3125 # 0 +0x0000A8E6 0x3126 # 0 +0x0000A8E7 0x3127 # 0 +0x0000A8E8 0x3128 # 0 +0x0000A8E9 0x3129 # 0 +0x0000A9A4 0x2500 # 0 +0x0000A9A5 0x2501 # 0 +0x0000A9A6 0x2502 # 0 +0x0000A9A7 0x2503 # 0 +0x0000A9A8 0x2504 # 0 +0x0000A9A9 0x2505 # 0 +0x0000A9AA 0x2506 # 0 +0x0000A9AB 0x2507 # 0 +0x0000A9AC 0x2508 # 0 +0x0000A9AD 0x2509 # 0 +0x0000A9AE 0x250A # 0 +0x0000A9AF 0x250B # 0 +0x0000A9B0 0x250C # 0 +0x0000A9B1 0x250D # 0 +0x0000A9B2 0x250E # 0 +0x0000A9B3 0x250F # 0 +0x0000A9B4 0x2510 # 0 +0x0000A9B5 0x2511 # 0 +0x0000A9B6 0x2512 # 0 +0x0000A9B7 0x2513 # 0 +0x0000A9B8 0x2514 # 0 +0x0000A9B9 0x2515 # 0 +0x0000A9BA 0x2516 # 0 +0x0000A9BB 0x2517 # 0 +0x0000A9BC 0x2518 # 0 +0x0000A9BD 0x2519 # 0 +0x0000A9BE 0x251A # 0 +0x0000A9BF 0x251B # 0 +0x0000A9C0 0x251C # 0 +0x0000A9C1 0x251D # 0 +0x0000A9C2 0x251E # 0 +0x0000A9C3 0x251F # 0 +0x0000A9C4 0x2520 # 0 +0x0000A9C5 0x2521 # 0 +0x0000A9C6 0x2522 # 0 +0x0000A9C7 0x2523 # 0 +0x0000A9C8 0x2524 # 0 +0x0000A9C9 0x2525 # 0 +0x0000A9CA 0x2526 # 0 +0x0000A9CB 0x2527 # 0 +0x0000A9CC 0x2528 # 0 +0x0000A9CD 0x2529 # 0 +0x0000A9CE 0x252A # 0 +0x0000A9CF 0x252B # 0 +0x0000A9D0 0x252C # 0 +0x0000A9D1 0x252D # 0 +0x0000A9D2 0x252E # 0 +0x0000A9D3 0x252F # 0 +0x0000A9D4 0x2530 # 0 +0x0000A9D5 0x2531 # 0 +0x0000A9D6 0x2532 # 0 +0x0000A9D7 0x2533 # 0 +0x0000A9D8 0x2534 # 0 +0x0000A9D9 0x2535 # 0 +0x0000A9DA 0x2536 # 0 +0x0000A9DB 0x2537 # 0 +0x0000A9DC 0x2538 # 0 +0x0000A9DD 0x2539 # 0 +0x0000A9DE 0x253A # 0 +0x0000A9DF 0x253B # 0 +0x0000A9E0 0x253C # 0 +0x0000A9E1 0x253D # 0 +0x0000A9E2 0x253E # 0 +0x0000A9E3 0x253F # 0 +0x0000A9E4 0x2540 # 0 +0x0000A9E5 0x2541 # 0 +0x0000A9E6 0x2542 # 0 +0x0000A9E7 0x2543 # 0 +0x0000A9E8 0x2544 # 0 +0x0000A9E9 0x2545 # 0 +0x0000A9EA 0x2546 # 0 +0x0000A9EB 0x2547 # 0 +0x0000A9EC 0x2548 # 0 +0x0000A9ED 0x2549 # 0 +0x0000A9EE 0x254A # 0 +0x0000A9EF 0x254B # 0 +0x0000B0A1 0x554A # 0 +0x0000B0A2 0x963F # 0 +0x0000B0A3 0x57C3 # 0 +0x0000B0A4 0x6328 # 0 +0x0000B0A5 0x54CE # 0 +0x0000B0A6 0x5509 # 0 +0x0000B0A7 0x54C0 # 0 +0x0000B0A8 0x7691 # 0 +0x0000B0A9 0x764C # 0 +0x0000B0AA 0x853C # 0 +0x0000B0AB 0x77EE # 0 +0x0000B0AC 0x827E # 0 +0x0000B0AD 0x788D # 0 +0x0000B0AE 0x7231 # 0 +0x0000B0AF 0x9698 # 0 +0x0000B0B0 0x978D # 0 +0x0000B0B1 0x6C28 # 0 +0x0000B0B2 0x5B89 # 0 +0x0000B0B3 0x4FFA # 0 +0x0000B0B4 0x6309 # 0 +0x0000B0B5 0x6697 # 0 +0x0000B0B6 0x5CB8 # 0 +0x0000B0B7 0x80FA # 0 +0x0000B0B8 0x6848 # 0 +0x0000B0B9 0x80AE # 0 +0x0000B0BA 0x6602 # 0 +0x0000B0BB 0x76CE # 0 +0x0000B0BC 0x51F9 # 0 +0x0000B0BD 0x6556 # 0 +0x0000B0BE 0x71AC # 0 +0x0000B0BF 0x7FF1 # 0 +0x0000B0C0 0x8884 # 0 +0x0000B0C1 0x50B2 # 0 +0x0000B0C2 0x5965 # 0 +0x0000B0C3 0x61CA # 0 +0x0000B0C4 0x6FB3 # 0 +0x0000B0C5 0x82AD # 0 +0x0000B0C6 0x634C # 0 +0x0000B0C7 0x6252 # 0 +0x0000B0C8 0x53ED # 0 +0x0000B0C9 0x5427 # 0 +0x0000B0CA 0x7B06 # 0 +0x0000B0CB 0x516B # 0 +0x0000B0CC 0x75A4 # 0 +0x0000B0CD 0x5DF4 # 0 +0x0000B0CE 0x62D4 # 0 +0x0000B0CF 0x8DCB # 0 +0x0000B0D0 0x9776 # 0 +0x0000B0D1 0x628A # 0 +0x0000B0D2 0x8019 # 0 +0x0000B0D3 0x575D # 0 +0x0000B0D4 0x9738 # 0 +0x0000B0D5 0x7F62 # 0 +0x0000B0D6 0x7238 # 0 +0x0000B0D7 0x767D # 0 +0x0000B0D8 0x67CF # 0 +0x0000B0D9 0x767E # 0 +0x0000B0DA 0x6446 # 0 +0x0000B0DB 0x4F70 # 0 +0x0000B0DC 0x8D25 # 0 +0x0000B0DD 0x62DC # 0 +0x0000B0DE 0x7A17 # 0 +0x0000B0DF 0x6591 # 0 +0x0000B0E0 0x73ED # 0 +0x0000B0E1 0x642C # 0 +0x0000B0E2 0x6273 # 0 +0x0000B0E3 0x822C # 0 +0x0000B0E4 0x9881 # 0 +0x0000B0E5 0x677F # 0 +0x0000B0E6 0x7248 # 0 +0x0000B0E7 0x626E # 0 +0x0000B0E8 0x62CC # 0 +0x0000B0E9 0x4F34 # 0 +0x0000B0EA 0x74E3 # 0 +0x0000B0EB 0x534A # 0 +0x0000B0EC 0x529E # 0 +0x0000B0ED 0x7ECA # 0 +0x0000B0EE 0x90A6 # 0 +0x0000B0EF 0x5E2E # 0 +0x0000B0F0 0x6886 # 0 +0x0000B0F1 0x699C # 0 +0x0000B0F2 0x8180 # 0 +0x0000B0F3 0x7ED1 # 0 +0x0000B0F4 0x68D2 # 0 +0x0000B0F5 0x78C5 # 0 +0x0000B0F6 0x868C # 0 +0x0000B0F7 0x9551 # 0 +0x0000B0F8 0x508D # 0 +0x0000B0F9 0x8C24 # 0 +0x0000B0FA 0x82DE # 0 +0x0000B0FB 0x80DE # 0 +0x0000B0FC 0x5305 # 0 +0x0000B0FD 0x8912 # 0 +0x0000B0FE 0x5265 # 0 +0x0000B1A1 0x8584 # 0 +0x0000B1A2 0x96F9 # 0 +0x0000B1A3 0x4FDD # 0 +0x0000B1A4 0x5821 # 0 +0x0000B1A5 0x9971 # 0 +0x0000B1A6 0x5B9D # 0 +0x0000B1A7 0x62B1 # 0 +0x0000B1A8 0x62A5 # 0 +0x0000B1A9 0x66B4 # 0 +0x0000B1AA 0x8C79 # 0 +0x0000B1AB 0x9C8D # 0 +0x0000B1AC 0x7206 # 0 +0x0000B1AD 0x676F # 0 +0x0000B1AE 0x7891 # 0 +0x0000B1AF 0x60B2 # 0 +0x0000B1B0 0x5351 # 0 +0x0000B1B1 0x5317 # 0 +0x0000B1B2 0x8F88 # 0 +0x0000B1B3 0x80CC # 0 +0x0000B1B4 0x8D1D # 0 +0x0000B1B5 0x94A1 # 0 +0x0000B1B6 0x500D # 0 +0x0000B1B7 0x72C8 # 0 +0x0000B1B8 0x5907 # 0 +0x0000B1B9 0x60EB # 0 +0x0000B1BA 0x7119 # 0 +0x0000B1BB 0x88AB # 0 +0x0000B1BC 0x5954 # 0 +0x0000B1BD 0x82EF # 0 +0x0000B1BE 0x672C # 0 +0x0000B1BF 0x7B28 # 0 +0x0000B1C0 0x5D29 # 0 +0x0000B1C1 0x7EF7 # 0 +0x0000B1C2 0x752D # 0 +0x0000B1C3 0x6CF5 # 0 +0x0000B1C4 0x8E66 # 0 +0x0000B1C5 0x8FF8 # 0 +0x0000B1C6 0x903C # 0 +0x0000B1C7 0x9F3B # 0 +0x0000B1C8 0x6BD4 # 0 +0x0000B1C9 0x9119 # 0 +0x0000B1CA 0x7B14 # 0 +0x0000B1CB 0x5F7C # 0 +0x0000B1CC 0x78A7 # 0 +0x0000B1CD 0x84D6 # 0 +0x0000B1CE 0x853D # 0 +0x0000B1CF 0x6BD5 # 0 +0x0000B1D0 0x6BD9 # 0 +0x0000B1D1 0x6BD6 # 0 +0x0000B1D2 0x5E01 # 0 +0x0000B1D3 0x5E87 # 0 +0x0000B1D4 0x75F9 # 0 +0x0000B1D5 0x95ED # 0 +0x0000B1D6 0x655D # 0 +0x0000B1D7 0x5F0A # 0 +0x0000B1D8 0x5FC5 # 0 +0x0000B1D9 0x8F9F # 0 +0x0000B1DA 0x58C1 # 0 +0x0000B1DB 0x81C2 # 0 +0x0000B1DC 0x907F # 0 +0x0000B1DD 0x965B # 0 +0x0000B1DE 0x97AD # 0 +0x0000B1DF 0x8FB9 # 0 +0x0000B1E0 0x7F16 # 0 +0x0000B1E1 0x8D2C # 0 +0x0000B1E2 0x6241 # 0 +0x0000B1E3 0x4FBF # 0 +0x0000B1E4 0x53D8 # 0 +0x0000B1E5 0x535E # 0 +0x0000B1E6 0x8FA8 # 0 +0x0000B1E7 0x8FA9 # 0 +0x0000B1E8 0x8FAB # 0 +0x0000B1E9 0x904D # 0 +0x0000B1EA 0x6807 # 0 +0x0000B1EB 0x5F6A # 0 +0x0000B1EC 0x8198 # 0 +0x0000B1ED 0x8868 # 0 +0x0000B1EE 0x9CD6 # 0 +0x0000B1EF 0x618B # 0 +0x0000B1F0 0x522B # 0 +0x0000B1F1 0x762A # 0 +0x0000B1F2 0x5F6C # 0 +0x0000B1F3 0x658C # 0 +0x0000B1F4 0x6FD2 # 0 +0x0000B1F5 0x6EE8 # 0 +0x0000B1F6 0x5BBE # 0 +0x0000B1F7 0x6448 # 0 +0x0000B1F8 0x5175 # 0 +0x0000B1F9 0x51B0 # 0 +0x0000B1FA 0x67C4 # 0 +0x0000B1FB 0x4E19 # 0 +0x0000B1FC 0x79C9 # 0 +0x0000B1FD 0x997C # 0 +0x0000B1FE 0x70B3 # 0 +0x0000B2A1 0x75C5 # 0 +0x0000B2A2 0x5E76 # 0 +0x0000B2A3 0x73BB # 0 +0x0000B2A4 0x83E0 # 0 +0x0000B2A5 0x64AD # 0 +0x0000B2A6 0x62E8 # 0 +0x0000B2A7 0x94B5 # 0 +0x0000B2A8 0x6CE2 # 0 +0x0000B2A9 0x535A # 0 +0x0000B2AA 0x52C3 # 0 +0x0000B2AB 0x640F # 0 +0x0000B2AC 0x94C2 # 0 +0x0000B2AD 0x7B94 # 0 +0x0000B2AE 0x4F2F # 0 +0x0000B2AF 0x5E1B # 0 +0x0000B2B0 0x8236 # 0 +0x0000B2B1 0x8116 # 0 +0x0000B2B2 0x818A # 0 +0x0000B2B3 0x6E24 # 0 +0x0000B2B4 0x6CCA # 0 +0x0000B2B5 0x9A73 # 0 +0x0000B2B6 0x6355 # 0 +0x0000B2B7 0x535C # 0 +0x0000B2B8 0x54FA # 0 +0x0000B2B9 0x8865 # 0 +0x0000B2BA 0x57E0 # 0 +0x0000B2BB 0x4E0D # 0 +0x0000B2BC 0x5E03 # 0 +0x0000B2BD 0x6B65 # 0 +0x0000B2BE 0x7C3F # 0 +0x0000B2BF 0x90E8 # 0 +0x0000B2C0 0x6016 # 0 +0x0000B2C1 0x64E6 # 0 +0x0000B2C2 0x731C # 0 +0x0000B2C3 0x88C1 # 0 +0x0000B2C4 0x6750 # 0 +0x0000B2C5 0x624D # 0 +0x0000B2C6 0x8D22 # 0 +0x0000B2C7 0x776C # 0 +0x0000B2C8 0x8E29 # 0 +0x0000B2C9 0x91C7 # 0 +0x0000B2CA 0x5F69 # 0 +0x0000B2CB 0x83DC # 0 +0x0000B2CC 0x8521 # 0 +0x0000B2CD 0x9910 # 0 +0x0000B2CE 0x53C2 # 0 +0x0000B2CF 0x8695 # 0 +0x0000B2D0 0x6B8B # 0 +0x0000B2D1 0x60ED # 0 +0x0000B2D2 0x60E8 # 0 +0x0000B2D3 0x707F # 0 +0x0000B2D4 0x82CD # 0 +0x0000B2D5 0x8231 # 0 +0x0000B2D6 0x4ED3 # 0 +0x0000B2D7 0x6CA7 # 0 +0x0000B2D8 0x85CF # 0 +0x0000B2D9 0x64CD # 0 +0x0000B2DA 0x7CD9 # 0 +0x0000B2DB 0x69FD # 0 +0x0000B2DC 0x66F9 # 0 +0x0000B2DD 0x8349 # 0 +0x0000B2DE 0x5395 # 0 +0x0000B2DF 0x7B56 # 0 +0x0000B2E0 0x4FA7 # 0 +0x0000B2E1 0x518C # 0 +0x0000B2E2 0x6D4B # 0 +0x0000B2E3 0x5C42 # 0 +0x0000B2E4 0x8E6D # 0 +0x0000B2E5 0x63D2 # 0 +0x0000B2E6 0x53C9 # 0 +0x0000B2E7 0x832C # 0 +0x0000B2E8 0x8336 # 0 +0x0000B2E9 0x67E5 # 0 +0x0000B2EA 0x78B4 # 0 +0x0000B2EB 0x643D # 0 +0x0000B2EC 0x5BDF # 0 +0x0000B2ED 0x5C94 # 0 +0x0000B2EE 0x5DEE # 0 +0x0000B2EF 0x8BE7 # 0 +0x0000B2F0 0x62C6 # 0 +0x0000B2F1 0x67F4 # 0 +0x0000B2F2 0x8C7A # 0 +0x0000B2F3 0x6400 # 0 +0x0000B2F4 0x63BA # 0 +0x0000B2F5 0x8749 # 0 +0x0000B2F6 0x998B # 0 +0x0000B2F7 0x8C17 # 0 +0x0000B2F8 0x7F20 # 0 +0x0000B2F9 0x94F2 # 0 +0x0000B2FA 0x4EA7 # 0 +0x0000B2FB 0x9610 # 0 +0x0000B2FC 0x98A4 # 0 +0x0000B2FD 0x660C # 0 +0x0000B2FE 0x7316 # 0 +0x0000B3A1 0x573A # 0 +0x0000B3A2 0x5C1D # 0 +0x0000B3A3 0x5E38 # 0 +0x0000B3A4 0x957F # 0 +0x0000B3A5 0x507F # 0 +0x0000B3A6 0x80A0 # 0 +0x0000B3A7 0x5382 # 0 +0x0000B3A8 0x655E # 0 +0x0000B3A9 0x7545 # 0 +0x0000B3AA 0x5531 # 0 +0x0000B3AB 0x5021 # 0 +0x0000B3AC 0x8D85 # 0 +0x0000B3AD 0x6284 # 0 +0x0000B3AE 0x949E # 0 +0x0000B3AF 0x671D # 0 +0x0000B3B0 0x5632 # 0 +0x0000B3B1 0x6F6E # 0 +0x0000B3B2 0x5DE2 # 0 +0x0000B3B3 0x5435 # 0 +0x0000B3B4 0x7092 # 0 +0x0000B3B5 0x8F66 # 0 +0x0000B3B6 0x626F # 0 +0x0000B3B7 0x64A4 # 0 +0x0000B3B8 0x63A3 # 0 +0x0000B3B9 0x5F7B # 0 +0x0000B3BA 0x6F88 # 0 +0x0000B3BB 0x90F4 # 0 +0x0000B3BC 0x81E3 # 0 +0x0000B3BD 0x8FB0 # 0 +0x0000B3BE 0x5C18 # 0 +0x0000B3BF 0x6668 # 0 +0x0000B3C0 0x5FF1 # 0 +0x0000B3C1 0x6C89 # 0 +0x0000B3C2 0x9648 # 0 +0x0000B3C3 0x8D81 # 0 +0x0000B3C4 0x886C # 0 +0x0000B3C5 0x6491 # 0 +0x0000B3C6 0x79F0 # 0 +0x0000B3C7 0x57CE # 0 +0x0000B3C8 0x6A59 # 0 +0x0000B3C9 0x6210 # 0 +0x0000B3CA 0x5448 # 0 +0x0000B3CB 0x4E58 # 0 +0x0000B3CC 0x7A0B # 0 +0x0000B3CD 0x60E9 # 0 +0x0000B3CE 0x6F84 # 0 +0x0000B3CF 0x8BDA # 0 +0x0000B3D0 0x627F # 0 +0x0000B3D1 0x901E # 0 +0x0000B3D2 0x9A8B # 0 +0x0000B3D3 0x79E4 # 0 +0x0000B3D4 0x5403 # 0 +0x0000B3D5 0x75F4 # 0 +0x0000B3D6 0x6301 # 0 +0x0000B3D7 0x5319 # 0 +0x0000B3D8 0x6C60 # 0 +0x0000B3D9 0x8FDF # 0 +0x0000B3DA 0x5F1B # 0 +0x0000B3DB 0x9A70 # 0 +0x0000B3DC 0x803B # 0 +0x0000B3DD 0x9F7F # 0 +0x0000B3DE 0x4F88 # 0 +0x0000B3DF 0x5C3A # 0 +0x0000B3E0 0x8D64 # 0 +0x0000B3E1 0x7FC5 # 0 +0x0000B3E2 0x65A5 # 0 +0x0000B3E3 0x70BD # 0 +0x0000B3E4 0x5145 # 0 +0x0000B3E5 0x51B2 # 0 +0x0000B3E6 0x866B # 0 +0x0000B3E7 0x5D07 # 0 +0x0000B3E8 0x5BA0 # 0 +0x0000B3E9 0x62BD # 0 +0x0000B3EA 0x916C # 0 +0x0000B3EB 0x7574 # 0 +0x0000B3EC 0x8E0C # 0 +0x0000B3ED 0x7A20 # 0 +0x0000B3EE 0x6101 # 0 +0x0000B3EF 0x7B79 # 0 +0x0000B3F0 0x4EC7 # 0 +0x0000B3F1 0x7EF8 # 0 +0x0000B3F2 0x7785 # 0 +0x0000B3F3 0x4E11 # 0 +0x0000B3F4 0x81ED # 0 +0x0000B3F5 0x521D # 0 +0x0000B3F6 0x51FA # 0 +0x0000B3F7 0x6A71 # 0 +0x0000B3F8 0x53A8 # 0 +0x0000B3F9 0x8E87 # 0 +0x0000B3FA 0x9504 # 0 +0x0000B3FB 0x96CF # 0 +0x0000B3FC 0x6EC1 # 0 +0x0000B3FD 0x9664 # 0 +0x0000B3FE 0x695A # 0 +0x0000B4A1 0x7840 # 0 +0x0000B4A2 0x50A8 # 0 +0x0000B4A3 0x77D7 # 0 +0x0000B4A4 0x6410 # 0 +0x0000B4A5 0x89E6 # 0 +0x0000B4A6 0x5904 # 0 +0x0000B4A7 0x63E3 # 0 +0x0000B4A8 0x5DDD # 0 +0x0000B4A9 0x7A7F # 0 +0x0000B4AA 0x693D # 0 +0x0000B4AB 0x4F20 # 0 +0x0000B4AC 0x8239 # 0 +0x0000B4AD 0x5598 # 0 +0x0000B4AE 0x4E32 # 0 +0x0000B4AF 0x75AE # 0 +0x0000B4B0 0x7A97 # 0 +0x0000B4B1 0x5E62 # 0 +0x0000B4B2 0x5E8A # 0 +0x0000B4B3 0x95EF # 0 +0x0000B4B4 0x521B # 0 +0x0000B4B5 0x5439 # 0 +0x0000B4B6 0x708A # 0 +0x0000B4B7 0x6376 # 0 +0x0000B4B8 0x9524 # 0 +0x0000B4B9 0x5782 # 0 +0x0000B4BA 0x6625 # 0 +0x0000B4BB 0x693F # 0 +0x0000B4BC 0x9187 # 0 +0x0000B4BD 0x5507 # 0 +0x0000B4BE 0x6DF3 # 0 +0x0000B4BF 0x7EAF # 0 +0x0000B4C0 0x8822 # 0 +0x0000B4C1 0x6233 # 0 +0x0000B4C2 0x7EF0 # 0 +0x0000B4C3 0x75B5 # 0 +0x0000B4C4 0x8328 # 0 +0x0000B4C5 0x78C1 # 0 +0x0000B4C6 0x96CC # 0 +0x0000B4C7 0x8F9E # 0 +0x0000B4C8 0x6148 # 0 +0x0000B4C9 0x74F7 # 0 +0x0000B4CA 0x8BCD # 0 +0x0000B4CB 0x6B64 # 0 +0x0000B4CC 0x523A # 0 +0x0000B4CD 0x8D50 # 0 +0x0000B4CE 0x6B21 # 0 +0x0000B4CF 0x806A # 0 +0x0000B4D0 0x8471 # 0 +0x0000B4D1 0x56F1 # 0 +0x0000B4D2 0x5306 # 0 +0x0000B4D3 0x4ECE # 0 +0x0000B4D4 0x4E1B # 0 +0x0000B4D5 0x51D1 # 0 +0x0000B4D6 0x7C97 # 0 +0x0000B4D7 0x918B # 0 +0x0000B4D8 0x7C07 # 0 +0x0000B4D9 0x4FC3 # 0 +0x0000B4DA 0x8E7F # 0 +0x0000B4DB 0x7BE1 # 0 +0x0000B4DC 0x7A9C # 0 +0x0000B4DD 0x6467 # 0 +0x0000B4DE 0x5D14 # 0 +0x0000B4DF 0x50AC # 0 +0x0000B4E0 0x8106 # 0 +0x0000B4E1 0x7601 # 0 +0x0000B4E2 0x7CB9 # 0 +0x0000B4E3 0x6DEC # 0 +0x0000B4E4 0x7FE0 # 0 +0x0000B4E5 0x6751 # 0 +0x0000B4E6 0x5B58 # 0 +0x0000B4E7 0x5BF8 # 0 +0x0000B4E8 0x78CB # 0 +0x0000B4E9 0x64AE # 0 +0x0000B4EA 0x6413 # 0 +0x0000B4EB 0x63AA # 0 +0x0000B4EC 0x632B # 0 +0x0000B4ED 0x9519 # 0 +0x0000B4EE 0x642D # 0 +0x0000B4EF 0x8FBE # 0 +0x0000B4F0 0x7B54 # 0 +0x0000B4F1 0x7629 # 0 +0x0000B4F2 0x6253 # 0 +0x0000B4F3 0x5927 # 0 +0x0000B4F4 0x5446 # 0 +0x0000B4F5 0x6B79 # 0 +0x0000B4F6 0x50A3 # 0 +0x0000B4F7 0x6234 # 0 +0x0000B4F8 0x5E26 # 0 +0x0000B4F9 0x6B86 # 0 +0x0000B4FA 0x4EE3 # 0 +0x0000B4FB 0x8D37 # 0 +0x0000B4FC 0x888B # 0 +0x0000B4FD 0x5F85 # 0 +0x0000B4FE 0x902E # 0 +0x0000B5A1 0x6020 # 0 +0x0000B5A2 0x803D # 0 +0x0000B5A3 0x62C5 # 0 +0x0000B5A4 0x4E39 # 0 +0x0000B5A5 0x5355 # 0 +0x0000B5A6 0x90F8 # 0 +0x0000B5A7 0x63B8 # 0 +0x0000B5A8 0x80C6 # 0 +0x0000B5A9 0x65E6 # 0 +0x0000B5AA 0x6C2E # 0 +0x0000B5AB 0x4F46 # 0 +0x0000B5AC 0x60EE # 0 +0x0000B5AD 0x6DE1 # 0 +0x0000B5AE 0x8BDE # 0 +0x0000B5AF 0x5F39 # 0 +0x0000B5B0 0x86CB # 0 +0x0000B5B1 0x5F53 # 0 +0x0000B5B2 0x6321 # 0 +0x0000B5B3 0x515A # 0 +0x0000B5B4 0x8361 # 0 +0x0000B5B5 0x6863 # 0 +0x0000B5B6 0x5200 # 0 +0x0000B5B7 0x6363 # 0 +0x0000B5B8 0x8E48 # 0 +0x0000B5B9 0x5012 # 0 +0x0000B5BA 0x5C9B # 0 +0x0000B5BB 0x7977 # 0 +0x0000B5BC 0x5BFC # 0 +0x0000B5BD 0x5230 # 0 +0x0000B5BE 0x7A3B # 0 +0x0000B5BF 0x60BC # 0 +0x0000B5C0 0x9053 # 0 +0x0000B5C1 0x76D7 # 0 +0x0000B5C2 0x5FB7 # 0 +0x0000B5C3 0x5F97 # 0 +0x0000B5C4 0x7684 # 0 +0x0000B5C5 0x8E6C # 0 +0x0000B5C6 0x706F # 0 +0x0000B5C7 0x767B # 0 +0x0000B5C8 0x7B49 # 0 +0x0000B5C9 0x77AA # 0 +0x0000B5CA 0x51F3 # 0 +0x0000B5CB 0x9093 # 0 +0x0000B5CC 0x5824 # 0 +0x0000B5CD 0x4F4E # 0 +0x0000B5CE 0x6EF4 # 0 +0x0000B5CF 0x8FEA # 0 +0x0000B5D0 0x654C # 0 +0x0000B5D1 0x7B1B # 0 +0x0000B5D2 0x72C4 # 0 +0x0000B5D3 0x6DA4 # 0 +0x0000B5D4 0x7FDF # 0 +0x0000B5D5 0x5AE1 # 0 +0x0000B5D6 0x62B5 # 0 +0x0000B5D7 0x5E95 # 0 +0x0000B5D8 0x5730 # 0 +0x0000B5D9 0x8482 # 0 +0x0000B5DA 0x7B2C # 0 +0x0000B5DB 0x5E1D # 0 +0x0000B5DC 0x5F1F # 0 +0x0000B5DD 0x9012 # 0 +0x0000B5DE 0x7F14 # 0 +0x0000B5DF 0x98A0 # 0 +0x0000B5E0 0x6382 # 0 +0x0000B5E1 0x6EC7 # 0 +0x0000B5E2 0x7898 # 0 +0x0000B5E3 0x70B9 # 0 +0x0000B5E4 0x5178 # 0 +0x0000B5E5 0x975B # 0 +0x0000B5E6 0x57AB # 0 +0x0000B5E7 0x7535 # 0 +0x0000B5E8 0x4F43 # 0 +0x0000B5E9 0x7538 # 0 +0x0000B5EA 0x5E97 # 0 +0x0000B5EB 0x60E6 # 0 +0x0000B5EC 0x5960 # 0 +0x0000B5ED 0x6DC0 # 0 +0x0000B5EE 0x6BBF # 0 +0x0000B5EF 0x7889 # 0 +0x0000B5F0 0x53FC # 0 +0x0000B5F1 0x96D5 # 0 +0x0000B5F2 0x51CB # 0 +0x0000B5F3 0x5201 # 0 +0x0000B5F4 0x6389 # 0 +0x0000B5F5 0x540A # 0 +0x0000B5F6 0x9493 # 0 +0x0000B5F7 0x8C03 # 0 +0x0000B5F8 0x8DCC # 0 +0x0000B5F9 0x7239 # 0 +0x0000B5FA 0x789F # 0 +0x0000B5FB 0x8776 # 0 +0x0000B5FC 0x8FED # 0 +0x0000B5FD 0x8C0D # 0 +0x0000B5FE 0x53E0 # 0 +0x0000B6A1 0x4E01 # 0 +0x0000B6A2 0x76EF # 0 +0x0000B6A3 0x53EE # 0 +0x0000B6A4 0x9489 # 0 +0x0000B6A5 0x9876 # 0 +0x0000B6A6 0x9F0E # 0 +0x0000B6A7 0x952D # 0 +0x0000B6A8 0x5B9A # 0 +0x0000B6A9 0x8BA2 # 0 +0x0000B6AA 0x4E22 # 0 +0x0000B6AB 0x4E1C # 0 +0x0000B6AC 0x51AC # 0 +0x0000B6AD 0x8463 # 0 +0x0000B6AE 0x61C2 # 0 +0x0000B6AF 0x52A8 # 0 +0x0000B6B0 0x680B # 0 +0x0000B6B1 0x4F97 # 0 +0x0000B6B2 0x606B # 0 +0x0000B6B3 0x51BB # 0 +0x0000B6B4 0x6D1E # 0 +0x0000B6B5 0x515C # 0 +0x0000B6B6 0x6296 # 0 +0x0000B6B7 0x6597 # 0 +0x0000B6B8 0x9661 # 0 +0x0000B6B9 0x8C46 # 0 +0x0000B6BA 0x9017 # 0 +0x0000B6BB 0x75D8 # 0 +0x0000B6BC 0x90FD # 0 +0x0000B6BD 0x7763 # 0 +0x0000B6BE 0x6BD2 # 0 +0x0000B6BF 0x728A # 0 +0x0000B6C0 0x72EC # 0 +0x0000B6C1 0x8BFB # 0 +0x0000B6C2 0x5835 # 0 +0x0000B6C3 0x7779 # 0 +0x0000B6C4 0x8D4C # 0 +0x0000B6C5 0x675C # 0 +0x0000B6C6 0x9540 # 0 +0x0000B6C7 0x809A # 0 +0x0000B6C8 0x5EA6 # 0 +0x0000B6C9 0x6E21 # 0 +0x0000B6CA 0x5992 # 0 +0x0000B6CB 0x7AEF # 0 +0x0000B6CC 0x77ED # 0 +0x0000B6CD 0x953B # 0 +0x0000B6CE 0x6BB5 # 0 +0x0000B6CF 0x65AD # 0 +0x0000B6D0 0x7F0E # 0 +0x0000B6D1 0x5806 # 0 +0x0000B6D2 0x5151 # 0 +0x0000B6D3 0x961F # 0 +0x0000B6D4 0x5BF9 # 0 +0x0000B6D5 0x58A9 # 0 +0x0000B6D6 0x5428 # 0 +0x0000B6D7 0x8E72 # 0 +0x0000B6D8 0x6566 # 0 +0x0000B6D9 0x987F # 0 +0x0000B6DA 0x56E4 # 0 +0x0000B6DB 0x949D # 0 +0x0000B6DC 0x76FE # 0 +0x0000B6DD 0x9041 # 0 +0x0000B6DE 0x6387 # 0 +0x0000B6DF 0x54C6 # 0 +0x0000B6E0 0x591A # 0 +0x0000B6E1 0x593A # 0 +0x0000B6E2 0x579B # 0 +0x0000B6E3 0x8EB2 # 0 +0x0000B6E4 0x6735 # 0 +0x0000B6E5 0x8DFA # 0 +0x0000B6E6 0x8235 # 0 +0x0000B6E7 0x5241 # 0 +0x0000B6E8 0x60F0 # 0 +0x0000B6E9 0x5815 # 0 +0x0000B6EA 0x86FE # 0 +0x0000B6EB 0x5CE8 # 0 +0x0000B6EC 0x9E45 # 0 +0x0000B6ED 0x4FC4 # 0 +0x0000B6EE 0x989D # 0 +0x0000B6EF 0x8BB9 # 0 +0x0000B6F0 0x5A25 # 0 +0x0000B6F1 0x6076 # 0 +0x0000B6F2 0x5384 # 0 +0x0000B6F3 0x627C # 0 +0x0000B6F4 0x904F # 0 +0x0000B6F5 0x9102 # 0 +0x0000B6F6 0x997F # 0 +0x0000B6F7 0x6069 # 0 +0x0000B6F8 0x800C # 0 +0x0000B6F9 0x513F # 0 +0x0000B6FA 0x8033 # 0 +0x0000B6FB 0x5C14 # 0 +0x0000B6FC 0x9975 # 0 +0x0000B6FD 0x6D31 # 0 +0x0000B6FE 0x4E8C # 0 +0x0000B7A1 0x8D30 # 0 +0x0000B7A2 0x53D1 # 0 +0x0000B7A3 0x7F5A # 0 +0x0000B7A4 0x7B4F # 0 +0x0000B7A5 0x4F10 # 0 +0x0000B7A6 0x4E4F # 0 +0x0000B7A7 0x9600 # 0 +0x0000B7A8 0x6CD5 # 0 +0x0000B7A9 0x73D0 # 0 +0x0000B7AA 0x85E9 # 0 +0x0000B7AB 0x5E06 # 0 +0x0000B7AC 0x756A # 0 +0x0000B7AD 0x7FFB # 0 +0x0000B7AE 0x6A0A # 0 +0x0000B7AF 0x77FE # 0 +0x0000B7B0 0x9492 # 0 +0x0000B7B1 0x7E41 # 0 +0x0000B7B2 0x51E1 # 0 +0x0000B7B3 0x70E6 # 0 +0x0000B7B4 0x53CD # 0 +0x0000B7B5 0x8FD4 # 0 +0x0000B7B6 0x8303 # 0 +0x0000B7B7 0x8D29 # 0 +0x0000B7B8 0x72AF # 0 +0x0000B7B9 0x996D # 0 +0x0000B7BA 0x6CDB # 0 +0x0000B7BB 0x574A # 0 +0x0000B7BC 0x82B3 # 0 +0x0000B7BD 0x65B9 # 0 +0x0000B7BE 0x80AA # 0 +0x0000B7BF 0x623F # 0 +0x0000B7C0 0x9632 # 0 +0x0000B7C1 0x59A8 # 0 +0x0000B7C2 0x4EFF # 0 +0x0000B7C3 0x8BBF # 0 +0x0000B7C4 0x7EBA # 0 +0x0000B7C5 0x653E # 0 +0x0000B7C6 0x83F2 # 0 +0x0000B7C7 0x975E # 0 +0x0000B7C8 0x5561 # 0 +0x0000B7C9 0x98DE # 0 +0x0000B7CA 0x80A5 # 0 +0x0000B7CB 0x532A # 0 +0x0000B7CC 0x8BFD # 0 +0x0000B7CD 0x5420 # 0 +0x0000B7CE 0x80BA # 0 +0x0000B7CF 0x5E9F # 0 +0x0000B7D0 0x6CB8 # 0 +0x0000B7D1 0x8D39 # 0 +0x0000B7D2 0x82AC # 0 +0x0000B7D3 0x915A # 0 +0x0000B7D4 0x5429 # 0 +0x0000B7D5 0x6C1B # 0 +0x0000B7D6 0x5206 # 0 +0x0000B7D7 0x7EB7 # 0 +0x0000B7D8 0x575F # 0 +0x0000B7D9 0x711A # 0 +0x0000B7DA 0x6C7E # 0 +0x0000B7DB 0x7C89 # 0 +0x0000B7DC 0x594B # 0 +0x0000B7DD 0x4EFD # 0 +0x0000B7DE 0x5FFF # 0 +0x0000B7DF 0x6124 # 0 +0x0000B7E0 0x7CAA # 0 +0x0000B7E1 0x4E30 # 0 +0x0000B7E2 0x5C01 # 0 +0x0000B7E3 0x67AB # 0 +0x0000B7E4 0x8702 # 0 +0x0000B7E5 0x5CF0 # 0 +0x0000B7E6 0x950B # 0 +0x0000B7E7 0x98CE # 0 +0x0000B7E8 0x75AF # 0 +0x0000B7E9 0x70FD # 0 +0x0000B7EA 0x9022 # 0 +0x0000B7EB 0x51AF # 0 +0x0000B7EC 0x7F1D # 0 +0x0000B7ED 0x8BBD # 0 +0x0000B7EE 0x5949 # 0 +0x0000B7EF 0x51E4 # 0 +0x0000B7F0 0x4F5B # 0 +0x0000B7F1 0x5426 # 0 +0x0000B7F2 0x592B # 0 +0x0000B7F3 0x6577 # 0 +0x0000B7F4 0x80A4 # 0 +0x0000B7F5 0x5B75 # 0 +0x0000B7F6 0x6276 # 0 +0x0000B7F7 0x62C2 # 0 +0x0000B7F8 0x8F90 # 0 +0x0000B7F9 0x5E45 # 0 +0x0000B7FA 0x6C1F # 0 +0x0000B7FB 0x7B26 # 0 +0x0000B7FC 0x4F0F # 0 +0x0000B7FD 0x4FD8 # 0 +0x0000B7FE 0x670D # 0 +0x0000B8A1 0x6D6E # 0 +0x0000B8A2 0x6DAA # 0 +0x0000B8A3 0x798F # 0 +0x0000B8A4 0x88B1 # 0 +0x0000B8A5 0x5F17 # 0 +0x0000B8A6 0x752B # 0 +0x0000B8A7 0x629A # 0 +0x0000B8A8 0x8F85 # 0 +0x0000B8A9 0x4FEF # 0 +0x0000B8AA 0x91DC # 0 +0x0000B8AB 0x65A7 # 0 +0x0000B8AC 0x812F # 0 +0x0000B8AD 0x8151 # 0 +0x0000B8AE 0x5E9C # 0 +0x0000B8AF 0x8150 # 0 +0x0000B8B0 0x8D74 # 0 +0x0000B8B1 0x526F # 0 +0x0000B8B2 0x8986 # 0 +0x0000B8B3 0x8D4B # 0 +0x0000B8B4 0x590D # 0 +0x0000B8B5 0x5085 # 0 +0x0000B8B6 0x4ED8 # 0 +0x0000B8B7 0x961C # 0 +0x0000B8B8 0x7236 # 0 +0x0000B8B9 0x8179 # 0 +0x0000B8BA 0x8D1F # 0 +0x0000B8BB 0x5BCC # 0 +0x0000B8BC 0x8BA3 # 0 +0x0000B8BD 0x9644 # 0 +0x0000B8BE 0x5987 # 0 +0x0000B8BF 0x7F1A # 0 +0x0000B8C0 0x5490 # 0 +0x0000B8C1 0x5676 # 0 +0x0000B8C2 0x560E # 0 +0x0000B8C3 0x8BE5 # 0 +0x0000B8C4 0x6539 # 0 +0x0000B8C5 0x6982 # 0 +0x0000B8C6 0x9499 # 0 +0x0000B8C7 0x76D6 # 0 +0x0000B8C8 0x6E89 # 0 +0x0000B8C9 0x5E72 # 0 +0x0000B8CA 0x7518 # 0 +0x0000B8CB 0x6746 # 0 +0x0000B8CC 0x67D1 # 0 +0x0000B8CD 0x7AFF # 0 +0x0000B8CE 0x809D # 0 +0x0000B8CF 0x8D76 # 0 +0x0000B8D0 0x611F # 0 +0x0000B8D1 0x79C6 # 0 +0x0000B8D2 0x6562 # 0 +0x0000B8D3 0x8D63 # 0 +0x0000B8D4 0x5188 # 0 +0x0000B8D5 0x521A # 0 +0x0000B8D6 0x94A2 # 0 +0x0000B8D7 0x7F38 # 0 +0x0000B8D8 0x809B # 0 +0x0000B8D9 0x7EB2 # 0 +0x0000B8DA 0x5C97 # 0 +0x0000B8DB 0x6E2F # 0 +0x0000B8DC 0x6760 # 0 +0x0000B8DD 0x7BD9 # 0 +0x0000B8DE 0x768B # 0 +0x0000B8DF 0x9AD8 # 0 +0x0000B8E0 0x818F # 0 +0x0000B8E1 0x7F94 # 0 +0x0000B8E2 0x7CD5 # 0 +0x0000B8E3 0x641E # 0 +0x0000B8E4 0x9550 # 0 +0x0000B8E5 0x7A3F # 0 +0x0000B8E6 0x544A # 0 +0x0000B8E7 0x54E5 # 0 +0x0000B8E8 0x6B4C # 0 +0x0000B8E9 0x6401 # 0 +0x0000B8EA 0x6208 # 0 +0x0000B8EB 0x9E3D # 0 +0x0000B8EC 0x80F3 # 0 +0x0000B8ED 0x7599 # 0 +0x0000B8EE 0x5272 # 0 +0x0000B8EF 0x9769 # 0 +0x0000B8F0 0x845B # 0 +0x0000B8F1 0x683C # 0 +0x0000B8F2 0x86E4 # 0 +0x0000B8F3 0x9601 # 0 +0x0000B8F4 0x9694 # 0 +0x0000B8F5 0x94EC # 0 +0x0000B8F6 0x4E2A # 0 +0x0000B8F7 0x5404 # 0 +0x0000B8F8 0x7ED9 # 0 +0x0000B8F9 0x6839 # 0 +0x0000B8FA 0x8DDF # 0 +0x0000B8FB 0x8015 # 0 +0x0000B8FC 0x66F4 # 0 +0x0000B8FD 0x5E9A # 0 +0x0000B8FE 0x7FB9 # 0 +0x0000B9A1 0x57C2 # 0 +0x0000B9A2 0x803F # 0 +0x0000B9A3 0x6897 # 0 +0x0000B9A4 0x5DE5 # 0 +0x0000B9A5 0x653B # 0 +0x0000B9A6 0x529F # 0 +0x0000B9A7 0x606D # 0 +0x0000B9A8 0x9F9A # 0 +0x0000B9A9 0x4F9B # 0 +0x0000B9AA 0x8EAC # 0 +0x0000B9AB 0x516C # 0 +0x0000B9AC 0x5BAB # 0 +0x0000B9AD 0x5F13 # 0 +0x0000B9AE 0x5DE9 # 0 +0x0000B9AF 0x6C5E # 0 +0x0000B9B0 0x62F1 # 0 +0x0000B9B1 0x8D21 # 0 +0x0000B9B2 0x5171 # 0 +0x0000B9B3 0x94A9 # 0 +0x0000B9B4 0x52FE # 0 +0x0000B9B5 0x6C9F # 0 +0x0000B9B6 0x82DF # 0 +0x0000B9B7 0x72D7 # 0 +0x0000B9B8 0x57A2 # 0 +0x0000B9B9 0x6784 # 0 +0x0000B9BA 0x8D2D # 0 +0x0000B9BB 0x591F # 0 +0x0000B9BC 0x8F9C # 0 +0x0000B9BD 0x83C7 # 0 +0x0000B9BE 0x5495 # 0 +0x0000B9BF 0x7B8D # 0 +0x0000B9C0 0x4F30 # 0 +0x0000B9C1 0x6CBD # 0 +0x0000B9C2 0x5B64 # 0 +0x0000B9C3 0x59D1 # 0 +0x0000B9C4 0x9F13 # 0 +0x0000B9C5 0x53E4 # 0 +0x0000B9C6 0x86CA # 0 +0x0000B9C7 0x9AA8 # 0 +0x0000B9C8 0x8C37 # 0 +0x0000B9C9 0x80A1 # 0 +0x0000B9CA 0x6545 # 0 +0x0000B9CB 0x987E # 0 +0x0000B9CC 0x56FA # 0 +0x0000B9CD 0x96C7 # 0 +0x0000B9CE 0x522E # 0 +0x0000B9CF 0x74DC # 0 +0x0000B9D0 0x5250 # 0 +0x0000B9D1 0x5BE1 # 0 +0x0000B9D2 0x6302 # 0 +0x0000B9D3 0x8902 # 0 +0x0000B9D4 0x4E56 # 0 +0x0000B9D5 0x62D0 # 0 +0x0000B9D6 0x602A # 0 +0x0000B9D7 0x68FA # 0 +0x0000B9D8 0x5173 # 0 +0x0000B9D9 0x5B98 # 0 +0x0000B9DA 0x51A0 # 0 +0x0000B9DB 0x89C2 # 0 +0x0000B9DC 0x7BA1 # 0 +0x0000B9DD 0x9986 # 0 +0x0000B9DE 0x7F50 # 0 +0x0000B9DF 0x60EF # 0 +0x0000B9E0 0x704C # 0 +0x0000B9E1 0x8D2F # 0 +0x0000B9E2 0x5149 # 0 +0x0000B9E3 0x5E7F # 0 +0x0000B9E4 0x901B # 0 +0x0000B9E5 0x7470 # 0 +0x0000B9E6 0x89C4 # 0 +0x0000B9E7 0x572D # 0 +0x0000B9E8 0x7845 # 0 +0x0000B9E9 0x5F52 # 0 +0x0000B9EA 0x9F9F # 0 +0x0000B9EB 0x95FA # 0 +0x0000B9EC 0x8F68 # 0 +0x0000B9ED 0x9B3C # 0 +0x0000B9EE 0x8BE1 # 0 +0x0000B9EF 0x7678 # 0 +0x0000B9F0 0x6842 # 0 +0x0000B9F1 0x67DC # 0 +0x0000B9F2 0x8DEA # 0 +0x0000B9F3 0x8D35 # 0 +0x0000B9F4 0x523D # 0 +0x0000B9F5 0x8F8A # 0 +0x0000B9F6 0x6EDA # 0 +0x0000B9F7 0x68CD # 0 +0x0000B9F8 0x9505 # 0 +0x0000B9F9 0x90ED # 0 +0x0000B9FA 0x56FD # 0 +0x0000B9FB 0x679C # 0 +0x0000B9FC 0x88F9 # 0 +0x0000B9FD 0x8FC7 # 0 +0x0000B9FE 0x54C8 # 0 +0x0000BAA1 0x9AB8 # 0 +0x0000BAA2 0x5B69 # 0 +0x0000BAA3 0x6D77 # 0 +0x0000BAA4 0x6C26 # 0 +0x0000BAA5 0x4EA5 # 0 +0x0000BAA6 0x5BB3 # 0 +0x0000BAA7 0x9A87 # 0 +0x0000BAA8 0x9163 # 0 +0x0000BAA9 0x61A8 # 0 +0x0000BAAA 0x90AF # 0 +0x0000BAAB 0x97E9 # 0 +0x0000BAAC 0x542B # 0 +0x0000BAAD 0x6DB5 # 0 +0x0000BAAE 0x5BD2 # 0 +0x0000BAAF 0x51FD # 0 +0x0000BAB0 0x558A # 0 +0x0000BAB1 0x7F55 # 0 +0x0000BAB2 0x7FF0 # 0 +0x0000BAB3 0x64BC # 0 +0x0000BAB4 0x634D # 0 +0x0000BAB5 0x65F1 # 0 +0x0000BAB6 0x61BE # 0 +0x0000BAB7 0x608D # 0 +0x0000BAB8 0x710A # 0 +0x0000BAB9 0x6C57 # 0 +0x0000BABA 0x6C49 # 0 +0x0000BABB 0x592F # 0 +0x0000BABC 0x676D # 0 +0x0000BABD 0x822A # 0 +0x0000BABE 0x58D5 # 0 +0x0000BABF 0x568E # 0 +0x0000BAC0 0x8C6A # 0 +0x0000BAC1 0x6BEB # 0 +0x0000BAC2 0x90DD # 0 +0x0000BAC3 0x597D # 0 +0x0000BAC4 0x8017 # 0 +0x0000BAC5 0x53F7 # 0 +0x0000BAC6 0x6D69 # 0 +0x0000BAC7 0x5475 # 0 +0x0000BAC8 0x559D # 0 +0x0000BAC9 0x8377 # 0 +0x0000BACA 0x83CF # 0 +0x0000BACB 0x6838 # 0 +0x0000BACC 0x79BE # 0 +0x0000BACD 0x548C # 0 +0x0000BACE 0x4F55 # 0 +0x0000BACF 0x5408 # 0 +0x0000BAD0 0x76D2 # 0 +0x0000BAD1 0x8C89 # 0 +0x0000BAD2 0x9602 # 0 +0x0000BAD3 0x6CB3 # 0 +0x0000BAD4 0x6DB8 # 0 +0x0000BAD5 0x8D6B # 0 +0x0000BAD6 0x8910 # 0 +0x0000BAD7 0x9E64 # 0 +0x0000BAD8 0x8D3A # 0 +0x0000BAD9 0x563F # 0 +0x0000BADA 0x9ED1 # 0 +0x0000BADB 0x75D5 # 0 +0x0000BADC 0x5F88 # 0 +0x0000BADD 0x72E0 # 0 +0x0000BADE 0x6068 # 0 +0x0000BADF 0x54FC # 0 +0x0000BAE0 0x4EA8 # 0 +0x0000BAE1 0x6A2A # 0 +0x0000BAE2 0x8861 # 0 +0x0000BAE3 0x6052 # 0 +0x0000BAE4 0x8F70 # 0 +0x0000BAE5 0x54C4 # 0 +0x0000BAE6 0x70D8 # 0 +0x0000BAE7 0x8679 # 0 +0x0000BAE8 0x9E3F # 0 +0x0000BAE9 0x6D2A # 0 +0x0000BAEA 0x5B8F # 0 +0x0000BAEB 0x5F18 # 0 +0x0000BAEC 0x7EA2 # 0 +0x0000BAED 0x5589 # 0 +0x0000BAEE 0x4FAF # 0 +0x0000BAEF 0x7334 # 0 +0x0000BAF0 0x543C # 0 +0x0000BAF1 0x539A # 0 +0x0000BAF2 0x5019 # 0 +0x0000BAF3 0x540E # 0 +0x0000BAF4 0x547C # 0 +0x0000BAF5 0x4E4E # 0 +0x0000BAF6 0x5FFD # 0 +0x0000BAF7 0x745A # 0 +0x0000BAF8 0x58F6 # 0 +0x0000BAF9 0x846B # 0 +0x0000BAFA 0x80E1 # 0 +0x0000BAFB 0x8774 # 0 +0x0000BAFC 0x72D0 # 0 +0x0000BAFD 0x7CCA # 0 +0x0000BAFE 0x6E56 # 0 +0x0000BBA1 0x5F27 # 0 +0x0000BBA2 0x864E # 0 +0x0000BBA3 0x552C # 0 +0x0000BBA4 0x62A4 # 0 +0x0000BBA5 0x4E92 # 0 +0x0000BBA6 0x6CAA # 0 +0x0000BBA7 0x6237 # 0 +0x0000BBA8 0x82B1 # 0 +0x0000BBA9 0x54D7 # 0 +0x0000BBAA 0x534E # 0 +0x0000BBAB 0x733E # 0 +0x0000BBAC 0x6ED1 # 0 +0x0000BBAD 0x753B # 0 +0x0000BBAE 0x5212 # 0 +0x0000BBAF 0x5316 # 0 +0x0000BBB0 0x8BDD # 0 +0x0000BBB1 0x69D0 # 0 +0x0000BBB2 0x5F8A # 0 +0x0000BBB3 0x6000 # 0 +0x0000BBB4 0x6DEE # 0 +0x0000BBB5 0x574F # 0 +0x0000BBB6 0x6B22 # 0 +0x0000BBB7 0x73AF # 0 +0x0000BBB8 0x6853 # 0 +0x0000BBB9 0x8FD8 # 0 +0x0000BBBA 0x7F13 # 0 +0x0000BBBB 0x6362 # 0 +0x0000BBBC 0x60A3 # 0 +0x0000BBBD 0x5524 # 0 +0x0000BBBE 0x75EA # 0 +0x0000BBBF 0x8C62 # 0 +0x0000BBC0 0x7115 # 0 +0x0000BBC1 0x6DA3 # 0 +0x0000BBC2 0x5BA6 # 0 +0x0000BBC3 0x5E7B # 0 +0x0000BBC4 0x8352 # 0 +0x0000BBC5 0x614C # 0 +0x0000BBC6 0x9EC4 # 0 +0x0000BBC7 0x78FA # 0 +0x0000BBC8 0x8757 # 0 +0x0000BBC9 0x7C27 # 0 +0x0000BBCA 0x7687 # 0 +0x0000BBCB 0x51F0 # 0 +0x0000BBCC 0x60F6 # 0 +0x0000BBCD 0x714C # 0 +0x0000BBCE 0x6643 # 0 +0x0000BBCF 0x5E4C # 0 +0x0000BBD0 0x604D # 0 +0x0000BBD1 0x8C0E # 0 +0x0000BBD2 0x7070 # 0 +0x0000BBD3 0x6325 # 0 +0x0000BBD4 0x8F89 # 0 +0x0000BBD5 0x5FBD # 0 +0x0000BBD6 0x6062 # 0 +0x0000BBD7 0x86D4 # 0 +0x0000BBD8 0x56DE # 0 +0x0000BBD9 0x6BC1 # 0 +0x0000BBDA 0x6094 # 0 +0x0000BBDB 0x6167 # 0 +0x0000BBDC 0x5349 # 0 +0x0000BBDD 0x60E0 # 0 +0x0000BBDE 0x6666 # 0 +0x0000BBDF 0x8D3F # 0 +0x0000BBE0 0x79FD # 0 +0x0000BBE1 0x4F1A # 0 +0x0000BBE2 0x70E9 # 0 +0x0000BBE3 0x6C47 # 0 +0x0000BBE4 0x8BB3 # 0 +0x0000BBE5 0x8BF2 # 0 +0x0000BBE6 0x7ED8 # 0 +0x0000BBE7 0x8364 # 0 +0x0000BBE8 0x660F # 0 +0x0000BBE9 0x5A5A # 0 +0x0000BBEA 0x9B42 # 0 +0x0000BBEB 0x6D51 # 0 +0x0000BBEC 0x6DF7 # 0 +0x0000BBED 0x8C41 # 0 +0x0000BBEE 0x6D3B # 0 +0x0000BBEF 0x4F19 # 0 +0x0000BBF0 0x706B # 0 +0x0000BBF1 0x83B7 # 0 +0x0000BBF2 0x6216 # 0 +0x0000BBF3 0x60D1 # 0 +0x0000BBF4 0x970D # 0 +0x0000BBF5 0x8D27 # 0 +0x0000BBF6 0x7978 # 0 +0x0000BBF7 0x51FB # 0 +0x0000BBF8 0x573E # 0 +0x0000BBF9 0x57FA # 0 +0x0000BBFA 0x673A # 0 +0x0000BBFB 0x7578 # 0 +0x0000BBFC 0x7A3D # 0 +0x0000BBFD 0x79EF # 0 +0x0000BBFE 0x7B95 # 0 +0x0000BCA1 0x808C # 0 +0x0000BCA2 0x9965 # 0 +0x0000BCA3 0x8FF9 # 0 +0x0000BCA4 0x6FC0 # 0 +0x0000BCA5 0x8BA5 # 0 +0x0000BCA6 0x9E21 # 0 +0x0000BCA7 0x59EC # 0 +0x0000BCA8 0x7EE9 # 0 +0x0000BCA9 0x7F09 # 0 +0x0000BCAA 0x5409 # 0 +0x0000BCAB 0x6781 # 0 +0x0000BCAC 0x68D8 # 0 +0x0000BCAD 0x8F91 # 0 +0x0000BCAE 0x7C4D # 0 +0x0000BCAF 0x96C6 # 0 +0x0000BCB0 0x53CA # 0 +0x0000BCB1 0x6025 # 0 +0x0000BCB2 0x75BE # 0 +0x0000BCB3 0x6C72 # 0 +0x0000BCB4 0x5373 # 0 +0x0000BCB5 0x5AC9 # 0 +0x0000BCB6 0x7EA7 # 0 +0x0000BCB7 0x6324 # 0 +0x0000BCB8 0x51E0 # 0 +0x0000BCB9 0x810A # 0 +0x0000BCBA 0x5DF1 # 0 +0x0000BCBB 0x84DF # 0 +0x0000BCBC 0x6280 # 0 +0x0000BCBD 0x5180 # 0 +0x0000BCBE 0x5B63 # 0 +0x0000BCBF 0x4F0E # 0 +0x0000BCC0 0x796D # 0 +0x0000BCC1 0x5242 # 0 +0x0000BCC2 0x60B8 # 0 +0x0000BCC3 0x6D4E # 0 +0x0000BCC4 0x5BC4 # 0 +0x0000BCC5 0x5BC2 # 0 +0x0000BCC6 0x8BA1 # 0 +0x0000BCC7 0x8BB0 # 0 +0x0000BCC8 0x65E2 # 0 +0x0000BCC9 0x5FCC # 0 +0x0000BCCA 0x9645 # 0 +0x0000BCCB 0x5993 # 0 +0x0000BCCC 0x7EE7 # 0 +0x0000BCCD 0x7EAA # 0 +0x0000BCCE 0x5609 # 0 +0x0000BCCF 0x67B7 # 0 +0x0000BCD0 0x5939 # 0 +0x0000BCD1 0x4F73 # 0 +0x0000BCD2 0x5BB6 # 0 +0x0000BCD3 0x52A0 # 0 +0x0000BCD4 0x835A # 0 +0x0000BCD5 0x988A # 0 +0x0000BCD6 0x8D3E # 0 +0x0000BCD7 0x7532 # 0 +0x0000BCD8 0x94BE # 0 +0x0000BCD9 0x5047 # 0 +0x0000BCDA 0x7A3C # 0 +0x0000BCDB 0x4EF7 # 0 +0x0000BCDC 0x67B6 # 0 +0x0000BCDD 0x9A7E # 0 +0x0000BCDE 0x5AC1 # 0 +0x0000BCDF 0x6B7C # 0 +0x0000BCE0 0x76D1 # 0 +0x0000BCE1 0x575A # 0 +0x0000BCE2 0x5C16 # 0 +0x0000BCE3 0x7B3A # 0 +0x0000BCE4 0x95F4 # 0 +0x0000BCE5 0x714E # 0 +0x0000BCE6 0x517C # 0 +0x0000BCE7 0x80A9 # 0 +0x0000BCE8 0x8270 # 0 +0x0000BCE9 0x5978 # 0 +0x0000BCEA 0x7F04 # 0 +0x0000BCEB 0x8327 # 0 +0x0000BCEC 0x68C0 # 0 +0x0000BCED 0x67EC # 0 +0x0000BCEE 0x78B1 # 0 +0x0000BCEF 0x7877 # 0 +0x0000BCF0 0x62E3 # 0 +0x0000BCF1 0x6361 # 0 +0x0000BCF2 0x7B80 # 0 +0x0000BCF3 0x4FED # 0 +0x0000BCF4 0x526A # 0 +0x0000BCF5 0x51CF # 0 +0x0000BCF6 0x8350 # 0 +0x0000BCF7 0x69DB # 0 +0x0000BCF8 0x9274 # 0 +0x0000BCF9 0x8DF5 # 0 +0x0000BCFA 0x8D31 # 0 +0x0000BCFB 0x89C1 # 0 +0x0000BCFC 0x952E # 0 +0x0000BCFD 0x7BAD # 0 +0x0000BCFE 0x4EF6 # 0 +0x0000BDA1 0x5065 # 0 +0x0000BDA2 0x8230 # 0 +0x0000BDA3 0x5251 # 0 +0x0000BDA4 0x996F # 0 +0x0000BDA5 0x6E10 # 0 +0x0000BDA6 0x6E85 # 0 +0x0000BDA7 0x6DA7 # 0 +0x0000BDA8 0x5EFA # 0 +0x0000BDA9 0x50F5 # 0 +0x0000BDAA 0x59DC # 0 +0x0000BDAB 0x5C06 # 0 +0x0000BDAC 0x6D46 # 0 +0x0000BDAD 0x6C5F # 0 +0x0000BDAE 0x7586 # 0 +0x0000BDAF 0x848B # 0 +0x0000BDB0 0x6868 # 0 +0x0000BDB1 0x5956 # 0 +0x0000BDB2 0x8BB2 # 0 +0x0000BDB3 0x5320 # 0 +0x0000BDB4 0x9171 # 0 +0x0000BDB5 0x964D # 0 +0x0000BDB6 0x8549 # 0 +0x0000BDB7 0x6912 # 0 +0x0000BDB8 0x7901 # 0 +0x0000BDB9 0x7126 # 0 +0x0000BDBA 0x80F6 # 0 +0x0000BDBB 0x4EA4 # 0 +0x0000BDBC 0x90CA # 0 +0x0000BDBD 0x6D47 # 0 +0x0000BDBE 0x9A84 # 0 +0x0000BDBF 0x5A07 # 0 +0x0000BDC0 0x56BC # 0 +0x0000BDC1 0x6405 # 0 +0x0000BDC2 0x94F0 # 0 +0x0000BDC3 0x77EB # 0 +0x0000BDC4 0x4FA5 # 0 +0x0000BDC5 0x811A # 0 +0x0000BDC6 0x72E1 # 0 +0x0000BDC7 0x89D2 # 0 +0x0000BDC8 0x997A # 0 +0x0000BDC9 0x7F34 # 0 +0x0000BDCA 0x7EDE # 0 +0x0000BDCB 0x527F # 0 +0x0000BDCC 0x6559 # 0 +0x0000BDCD 0x9175 # 0 +0x0000BDCE 0x8F7F # 0 +0x0000BDCF 0x8F83 # 0 +0x0000BDD0 0x53EB # 0 +0x0000BDD1 0x7A96 # 0 +0x0000BDD2 0x63ED # 0 +0x0000BDD3 0x63A5 # 0 +0x0000BDD4 0x7686 # 0 +0x0000BDD5 0x79F8 # 0 +0x0000BDD6 0x8857 # 0 +0x0000BDD7 0x9636 # 0 +0x0000BDD8 0x622A # 0 +0x0000BDD9 0x52AB # 0 +0x0000BDDA 0x8282 # 0 +0x0000BDDB 0x6854 # 0 +0x0000BDDC 0x6770 # 0 +0x0000BDDD 0x6377 # 0 +0x0000BDDE 0x776B # 0 +0x0000BDDF 0x7AED # 0 +0x0000BDE0 0x6D01 # 0 +0x0000BDE1 0x7ED3 # 0 +0x0000BDE2 0x89E3 # 0 +0x0000BDE3 0x59D0 # 0 +0x0000BDE4 0x6212 # 0 +0x0000BDE5 0x85C9 # 0 +0x0000BDE6 0x82A5 # 0 +0x0000BDE7 0x754C # 0 +0x0000BDE8 0x501F # 0 +0x0000BDE9 0x4ECB # 0 +0x0000BDEA 0x75A5 # 0 +0x0000BDEB 0x8BEB # 0 +0x0000BDEC 0x5C4A # 0 +0x0000BDED 0x5DFE # 0 +0x0000BDEE 0x7B4B # 0 +0x0000BDEF 0x65A4 # 0 +0x0000BDF0 0x91D1 # 0 +0x0000BDF1 0x4ECA # 0 +0x0000BDF2 0x6D25 # 0 +0x0000BDF3 0x895F # 0 +0x0000BDF4 0x7D27 # 0 +0x0000BDF5 0x9526 # 0 +0x0000BDF6 0x4EC5 # 0 +0x0000BDF7 0x8C28 # 0 +0x0000BDF8 0x8FDB # 0 +0x0000BDF9 0x9773 # 0 +0x0000BDFA 0x664B # 0 +0x0000BDFB 0x7981 # 0 +0x0000BDFC 0x8FD1 # 0 +0x0000BDFD 0x70EC # 0 +0x0000BDFE 0x6D78 # 0 +0x0000BEA1 0x5C3D # 0 +0x0000BEA2 0x52B2 # 0 +0x0000BEA3 0x8346 # 0 +0x0000BEA4 0x5162 # 0 +0x0000BEA5 0x830E # 0 +0x0000BEA6 0x775B # 0 +0x0000BEA7 0x6676 # 0 +0x0000BEA8 0x9CB8 # 0 +0x0000BEA9 0x4EAC # 0 +0x0000BEAA 0x60CA # 0 +0x0000BEAB 0x7CBE # 0 +0x0000BEAC 0x7CB3 # 0 +0x0000BEAD 0x7ECF # 0 +0x0000BEAE 0x4E95 # 0 +0x0000BEAF 0x8B66 # 0 +0x0000BEB0 0x666F # 0 +0x0000BEB1 0x9888 # 0 +0x0000BEB2 0x9759 # 0 +0x0000BEB3 0x5883 # 0 +0x0000BEB4 0x656C # 0 +0x0000BEB5 0x955C # 0 +0x0000BEB6 0x5F84 # 0 +0x0000BEB7 0x75C9 # 0 +0x0000BEB8 0x9756 # 0 +0x0000BEB9 0x7ADF # 0 +0x0000BEBA 0x7ADE # 0 +0x0000BEBB 0x51C0 # 0 +0x0000BEBC 0x70AF # 0 +0x0000BEBD 0x7A98 # 0 +0x0000BEBE 0x63EA # 0 +0x0000BEBF 0x7A76 # 0 +0x0000BEC0 0x7EA0 # 0 +0x0000BEC1 0x7396 # 0 +0x0000BEC2 0x97ED # 0 +0x0000BEC3 0x4E45 # 0 +0x0000BEC4 0x7078 # 0 +0x0000BEC5 0x4E5D # 0 +0x0000BEC6 0x9152 # 0 +0x0000BEC7 0x53A9 # 0 +0x0000BEC8 0x6551 # 0 +0x0000BEC9 0x65E7 # 0 +0x0000BECA 0x81FC # 0 +0x0000BECB 0x8205 # 0 +0x0000BECC 0x548E # 0 +0x0000BECD 0x5C31 # 0 +0x0000BECE 0x759A # 0 +0x0000BECF 0x97A0 # 0 +0x0000BED0 0x62D8 # 0 +0x0000BED1 0x72D9 # 0 +0x0000BED2 0x75BD # 0 +0x0000BED3 0x5C45 # 0 +0x0000BED4 0x9A79 # 0 +0x0000BED5 0x83CA # 0 +0x0000BED6 0x5C40 # 0 +0x0000BED7 0x5480 # 0 +0x0000BED8 0x77E9 # 0 +0x0000BED9 0x4E3E # 0 +0x0000BEDA 0x6CAE # 0 +0x0000BEDB 0x805A # 0 +0x0000BEDC 0x62D2 # 0 +0x0000BEDD 0x636E # 0 +0x0000BEDE 0x5DE8 # 0 +0x0000BEDF 0x5177 # 0 +0x0000BEE0 0x8DDD # 0 +0x0000BEE1 0x8E1E # 0 +0x0000BEE2 0x952F # 0 +0x0000BEE3 0x4FF1 # 0 +0x0000BEE4 0x53E5 # 0 +0x0000BEE5 0x60E7 # 0 +0x0000BEE6 0x70AC # 0 +0x0000BEE7 0x5267 # 0 +0x0000BEE8 0x6350 # 0 +0x0000BEE9 0x9E43 # 0 +0x0000BEEA 0x5A1F # 0 +0x0000BEEB 0x5026 # 0 +0x0000BEEC 0x7737 # 0 +0x0000BEED 0x5377 # 0 +0x0000BEEE 0x7EE2 # 0 +0x0000BEEF 0x6485 # 0 +0x0000BEF0 0x652B # 0 +0x0000BEF1 0x6289 # 0 +0x0000BEF2 0x6398 # 0 +0x0000BEF3 0x5014 # 0 +0x0000BEF4 0x7235 # 0 +0x0000BEF5 0x89C9 # 0 +0x0000BEF6 0x51B3 # 0 +0x0000BEF7 0x8BC0 # 0 +0x0000BEF8 0x7EDD # 0 +0x0000BEF9 0x5747 # 0 +0x0000BEFA 0x83CC # 0 +0x0000BEFB 0x94A7 # 0 +0x0000BEFC 0x519B # 0 +0x0000BEFD 0x541B # 0 +0x0000BEFE 0x5CFB # 0 +0x0000BFA1 0x4FCA # 0 +0x0000BFA2 0x7AE3 # 0 +0x0000BFA3 0x6D5A # 0 +0x0000BFA4 0x90E1 # 0 +0x0000BFA5 0x9A8F # 0 +0x0000BFA6 0x5580 # 0 +0x0000BFA7 0x5496 # 0 +0x0000BFA8 0x5361 # 0 +0x0000BFA9 0x54AF # 0 +0x0000BFAA 0x5F00 # 0 +0x0000BFAB 0x63E9 # 0 +0x0000BFAC 0x6977 # 0 +0x0000BFAD 0x51EF # 0 +0x0000BFAE 0x6168 # 0 +0x0000BFAF 0x520A # 0 +0x0000BFB0 0x582A # 0 +0x0000BFB1 0x52D8 # 0 +0x0000BFB2 0x574E # 0 +0x0000BFB3 0x780D # 0 +0x0000BFB4 0x770B # 0 +0x0000BFB5 0x5EB7 # 0 +0x0000BFB6 0x6177 # 0 +0x0000BFB7 0x7CE0 # 0 +0x0000BFB8 0x625B # 0 +0x0000BFB9 0x6297 # 0 +0x0000BFBA 0x4EA2 # 0 +0x0000BFBB 0x7095 # 0 +0x0000BFBC 0x8003 # 0 +0x0000BFBD 0x62F7 # 0 +0x0000BFBE 0x70E4 # 0 +0x0000BFBF 0x9760 # 0 +0x0000BFC0 0x5777 # 0 +0x0000BFC1 0x82DB # 0 +0x0000BFC2 0x67EF # 0 +0x0000BFC3 0x68F5 # 0 +0x0000BFC4 0x78D5 # 0 +0x0000BFC5 0x9897 # 0 +0x0000BFC6 0x79D1 # 0 +0x0000BFC7 0x58F3 # 0 +0x0000BFC8 0x54B3 # 0 +0x0000BFC9 0x53EF # 0 +0x0000BFCA 0x6E34 # 0 +0x0000BFCB 0x514B # 0 +0x0000BFCC 0x523B # 0 +0x0000BFCD 0x5BA2 # 0 +0x0000BFCE 0x8BFE # 0 +0x0000BFCF 0x80AF # 0 +0x0000BFD0 0x5543 # 0 +0x0000BFD1 0x57A6 # 0 +0x0000BFD2 0x6073 # 0 +0x0000BFD3 0x5751 # 0 +0x0000BFD4 0x542D # 0 +0x0000BFD5 0x7A7A # 0 +0x0000BFD6 0x6050 # 0 +0x0000BFD7 0x5B54 # 0 +0x0000BFD8 0x63A7 # 0 +0x0000BFD9 0x62A0 # 0 +0x0000BFDA 0x53E3 # 0 +0x0000BFDB 0x6263 # 0 +0x0000BFDC 0x5BC7 # 0 +0x0000BFDD 0x67AF # 0 +0x0000BFDE 0x54ED # 0 +0x0000BFDF 0x7A9F # 0 +0x0000BFE0 0x82E6 # 0 +0x0000BFE1 0x9177 # 0 +0x0000BFE2 0x5E93 # 0 +0x0000BFE3 0x88E4 # 0 +0x0000BFE4 0x5938 # 0 +0x0000BFE5 0x57AE # 0 +0x0000BFE6 0x630E # 0 +0x0000BFE7 0x8DE8 # 0 +0x0000BFE8 0x80EF # 0 +0x0000BFE9 0x5757 # 0 +0x0000BFEA 0x7B77 # 0 +0x0000BFEB 0x4FA9 # 0 +0x0000BFEC 0x5FEB # 0 +0x0000BFED 0x5BBD # 0 +0x0000BFEE 0x6B3E # 0 +0x0000BFEF 0x5321 # 0 +0x0000BFF0 0x7B50 # 0 +0x0000BFF1 0x72C2 # 0 +0x0000BFF2 0x6846 # 0 +0x0000BFF3 0x77FF # 0 +0x0000BFF4 0x7736 # 0 +0x0000BFF5 0x65F7 # 0 +0x0000BFF6 0x51B5 # 0 +0x0000BFF7 0x4E8F # 0 +0x0000BFF8 0x76D4 # 0 +0x0000BFF9 0x5CBF # 0 +0x0000BFFA 0x7AA5 # 0 +0x0000BFFB 0x8475 # 0 +0x0000BFFC 0x594E # 0 +0x0000BFFD 0x9B41 # 0 +0x0000BFFE 0x5080 # 0 +0x0000C0A1 0x9988 # 0 +0x0000C0A2 0x6127 # 0 +0x0000C0A3 0x6E83 # 0 +0x0000C0A4 0x5764 # 0 +0x0000C0A5 0x6606 # 0 +0x0000C0A6 0x6346 # 0 +0x0000C0A7 0x56F0 # 0 +0x0000C0A8 0x62EC # 0 +0x0000C0A9 0x6269 # 0 +0x0000C0AA 0x5ED3 # 0 +0x0000C0AB 0x9614 # 0 +0x0000C0AC 0x5783 # 0 +0x0000C0AD 0x62C9 # 0 +0x0000C0AE 0x5587 # 0 +0x0000C0AF 0x8721 # 0 +0x0000C0B0 0x814A # 0 +0x0000C0B1 0x8FA3 # 0 +0x0000C0B2 0x5566 # 0 +0x0000C0B3 0x83B1 # 0 +0x0000C0B4 0x6765 # 0 +0x0000C0B5 0x8D56 # 0 +0x0000C0B6 0x84DD # 0 +0x0000C0B7 0x5A6A # 0 +0x0000C0B8 0x680F # 0 +0x0000C0B9 0x62E6 # 0 +0x0000C0BA 0x7BEE # 0 +0x0000C0BB 0x9611 # 0 +0x0000C0BC 0x5170 # 0 +0x0000C0BD 0x6F9C # 0 +0x0000C0BE 0x8C30 # 0 +0x0000C0BF 0x63FD # 0 +0x0000C0C0 0x89C8 # 0 +0x0000C0C1 0x61D2 # 0 +0x0000C0C2 0x7F06 # 0 +0x0000C0C3 0x70C2 # 0 +0x0000C0C4 0x6EE5 # 0 +0x0000C0C5 0x7405 # 0 +0x0000C0C6 0x6994 # 0 +0x0000C0C7 0x72FC # 0 +0x0000C0C8 0x5ECA # 0 +0x0000C0C9 0x90CE # 0 +0x0000C0CA 0x6717 # 0 +0x0000C0CB 0x6D6A # 0 +0x0000C0CC 0x635E # 0 +0x0000C0CD 0x52B3 # 0 +0x0000C0CE 0x7262 # 0 +0x0000C0CF 0x8001 # 0 +0x0000C0D0 0x4F6C # 0 +0x0000C0D1 0x59E5 # 0 +0x0000C0D2 0x916A # 0 +0x0000C0D3 0x70D9 # 0 +0x0000C0D4 0x6D9D # 0 +0x0000C0D5 0x52D2 # 0 +0x0000C0D6 0x4E50 # 0 +0x0000C0D7 0x96F7 # 0 +0x0000C0D8 0x956D # 0 +0x0000C0D9 0x857E # 0 +0x0000C0DA 0x78CA # 0 +0x0000C0DB 0x7D2F # 0 +0x0000C0DC 0x5121 # 0 +0x0000C0DD 0x5792 # 0 +0x0000C0DE 0x64C2 # 0 +0x0000C0DF 0x808B # 0 +0x0000C0E0 0x7C7B # 0 +0x0000C0E1 0x6CEA # 0 +0x0000C0E2 0x68F1 # 0 +0x0000C0E3 0x695E # 0 +0x0000C0E4 0x51B7 # 0 +0x0000C0E5 0x5398 # 0 +0x0000C0E6 0x68A8 # 0 +0x0000C0E7 0x7281 # 0 +0x0000C0E8 0x9ECE # 0 +0x0000C0E9 0x7BF1 # 0 +0x0000C0EA 0x72F8 # 0 +0x0000C0EB 0x79BB # 0 +0x0000C0EC 0x6F13 # 0 +0x0000C0ED 0x7406 # 0 +0x0000C0EE 0x674E # 0 +0x0000C0EF 0x91CC # 0 +0x0000C0F0 0x9CA4 # 0 +0x0000C0F1 0x793C # 0 +0x0000C0F2 0x8389 # 0 +0x0000C0F3 0x8354 # 0 +0x0000C0F4 0x540F # 0 +0x0000C0F5 0x6817 # 0 +0x0000C0F6 0x4E3D # 0 +0x0000C0F7 0x5389 # 0 +0x0000C0F8 0x52B1 # 0 +0x0000C0F9 0x783E # 0 +0x0000C0FA 0x5386 # 0 +0x0000C0FB 0x5229 # 0 +0x0000C0FC 0x5088 # 0 +0x0000C0FD 0x4F8B # 0 +0x0000C0FE 0x4FD0 # 0 +0x0000C1A1 0x75E2 # 0 +0x0000C1A2 0x7ACB # 0 +0x0000C1A3 0x7C92 # 0 +0x0000C1A4 0x6CA5 # 0 +0x0000C1A5 0x96B6 # 0 +0x0000C1A6 0x529B # 0 +0x0000C1A7 0x7483 # 0 +0x0000C1A8 0x54E9 # 0 +0x0000C1A9 0x4FE9 # 0 +0x0000C1AA 0x8054 # 0 +0x0000C1AB 0x83B2 # 0 +0x0000C1AC 0x8FDE # 0 +0x0000C1AD 0x9570 # 0 +0x0000C1AE 0x5EC9 # 0 +0x0000C1AF 0x601C # 0 +0x0000C1B0 0x6D9F # 0 +0x0000C1B1 0x5E18 # 0 +0x0000C1B2 0x655B # 0 +0x0000C1B3 0x8138 # 0 +0x0000C1B4 0x94FE # 0 +0x0000C1B5 0x604B # 0 +0x0000C1B6 0x70BC # 0 +0x0000C1B7 0x7EC3 # 0 +0x0000C1B8 0x7CAE # 0 +0x0000C1B9 0x51C9 # 0 +0x0000C1BA 0x6881 # 0 +0x0000C1BB 0x7CB1 # 0 +0x0000C1BC 0x826F # 0 +0x0000C1BD 0x4E24 # 0 +0x0000C1BE 0x8F86 # 0 +0x0000C1BF 0x91CF # 0 +0x0000C1C0 0x667E # 0 +0x0000C1C1 0x4EAE # 0 +0x0000C1C2 0x8C05 # 0 +0x0000C1C3 0x64A9 # 0 +0x0000C1C4 0x804A # 0 +0x0000C1C5 0x50DA # 0 +0x0000C1C6 0x7597 # 0 +0x0000C1C7 0x71CE # 0 +0x0000C1C8 0x5BE5 # 0 +0x0000C1C9 0x8FBD # 0 +0x0000C1CA 0x6F66 # 0 +0x0000C1CB 0x4E86 # 0 +0x0000C1CC 0x6482 # 0 +0x0000C1CD 0x9563 # 0 +0x0000C1CE 0x5ED6 # 0 +0x0000C1CF 0x6599 # 0 +0x0000C1D0 0x5217 # 0 +0x0000C1D1 0x88C2 # 0 +0x0000C1D2 0x70C8 # 0 +0x0000C1D3 0x52A3 # 0 +0x0000C1D4 0x730E # 0 +0x0000C1D5 0x7433 # 0 +0x0000C1D6 0x6797 # 0 +0x0000C1D7 0x78F7 # 0 +0x0000C1D8 0x9716 # 0 +0x0000C1D9 0x4E34 # 0 +0x0000C1DA 0x90BB # 0 +0x0000C1DB 0x9CDE # 0 +0x0000C1DC 0x6DCB # 0 +0x0000C1DD 0x51DB # 0 +0x0000C1DE 0x8D41 # 0 +0x0000C1DF 0x541D # 0 +0x0000C1E0 0x62CE # 0 +0x0000C1E1 0x73B2 # 0 +0x0000C1E2 0x83F1 # 0 +0x0000C1E3 0x96F6 # 0 +0x0000C1E4 0x9F84 # 0 +0x0000C1E5 0x94C3 # 0 +0x0000C1E6 0x4F36 # 0 +0x0000C1E7 0x7F9A # 0 +0x0000C1E8 0x51CC # 0 +0x0000C1E9 0x7075 # 0 +0x0000C1EA 0x9675 # 0 +0x0000C1EB 0x5CAD # 0 +0x0000C1EC 0x9886 # 0 +0x0000C1ED 0x53E6 # 0 +0x0000C1EE 0x4EE4 # 0 +0x0000C1EF 0x6E9C # 0 +0x0000C1F0 0x7409 # 0 +0x0000C1F1 0x69B4 # 0 +0x0000C1F2 0x786B # 0 +0x0000C1F3 0x998F # 0 +0x0000C1F4 0x7559 # 0 +0x0000C1F5 0x5218 # 0 +0x0000C1F6 0x7624 # 0 +0x0000C1F7 0x6D41 # 0 +0x0000C1F8 0x67F3 # 0 +0x0000C1F9 0x516D # 0 +0x0000C1FA 0x9F99 # 0 +0x0000C1FB 0x804B # 0 +0x0000C1FC 0x5499 # 0 +0x0000C1FD 0x7B3C # 0 +0x0000C1FE 0x7ABF # 0 +0x0000C2A1 0x9686 # 0 +0x0000C2A2 0x5784 # 0 +0x0000C2A3 0x62E2 # 0 +0x0000C2A4 0x9647 # 0 +0x0000C2A5 0x697C # 0 +0x0000C2A6 0x5A04 # 0 +0x0000C2A7 0x6402 # 0 +0x0000C2A8 0x7BD3 # 0 +0x0000C2A9 0x6F0F # 0 +0x0000C2AA 0x964B # 0 +0x0000C2AB 0x82A6 # 0 +0x0000C2AC 0x5362 # 0 +0x0000C2AD 0x9885 # 0 +0x0000C2AE 0x5E90 # 0 +0x0000C2AF 0x7089 # 0 +0x0000C2B0 0x63B3 # 0 +0x0000C2B1 0x5364 # 0 +0x0000C2B2 0x864F # 0 +0x0000C2B3 0x9C81 # 0 +0x0000C2B4 0x9E93 # 0 +0x0000C2B5 0x788C # 0 +0x0000C2B6 0x9732 # 0 +0x0000C2B7 0x8DEF # 0 +0x0000C2B8 0x8D42 # 0 +0x0000C2B9 0x9E7F # 0 +0x0000C2BA 0x6F5E # 0 +0x0000C2BB 0x7984 # 0 +0x0000C2BC 0x5F55 # 0 +0x0000C2BD 0x9646 # 0 +0x0000C2BE 0x622E # 0 +0x0000C2BF 0x9A74 # 0 +0x0000C2C0 0x5415 # 0 +0x0000C2C1 0x94DD # 0 +0x0000C2C2 0x4FA3 # 0 +0x0000C2C3 0x65C5 # 0 +0x0000C2C4 0x5C65 # 0 +0x0000C2C5 0x5C61 # 0 +0x0000C2C6 0x7F15 # 0 +0x0000C2C7 0x8651 # 0 +0x0000C2C8 0x6C2F # 0 +0x0000C2C9 0x5F8B # 0 +0x0000C2CA 0x7387 # 0 +0x0000C2CB 0x6EE4 # 0 +0x0000C2CC 0x7EFF # 0 +0x0000C2CD 0x5CE6 # 0 +0x0000C2CE 0x631B # 0 +0x0000C2CF 0x5B6A # 0 +0x0000C2D0 0x6EE6 # 0 +0x0000C2D1 0x5375 # 0 +0x0000C2D2 0x4E71 # 0 +0x0000C2D3 0x63A0 # 0 +0x0000C2D4 0x7565 # 0 +0x0000C2D5 0x62A1 # 0 +0x0000C2D6 0x8F6E # 0 +0x0000C2D7 0x4F26 # 0 +0x0000C2D8 0x4ED1 # 0 +0x0000C2D9 0x6CA6 # 0 +0x0000C2DA 0x7EB6 # 0 +0x0000C2DB 0x8BBA # 0 +0x0000C2DC 0x841D # 0 +0x0000C2DD 0x87BA # 0 +0x0000C2DE 0x7F57 # 0 +0x0000C2DF 0x903B # 0 +0x0000C2E0 0x9523 # 0 +0x0000C2E1 0x7BA9 # 0 +0x0000C2E2 0x9AA1 # 0 +0x0000C2E3 0x88F8 # 0 +0x0000C2E4 0x843D # 0 +0x0000C2E5 0x6D1B # 0 +0x0000C2E6 0x9A86 # 0 +0x0000C2E7 0x7EDC # 0 +0x0000C2E8 0x5988 # 0 +0x0000C2E9 0x9EBB # 0 +0x0000C2EA 0x739B # 0 +0x0000C2EB 0x7801 # 0 +0x0000C2EC 0x8682 # 0 +0x0000C2ED 0x9A6C # 0 +0x0000C2EE 0x9A82 # 0 +0x0000C2EF 0x561B # 0 +0x0000C2F0 0x5417 # 0 +0x0000C2F1 0x57CB # 0 +0x0000C2F2 0x4E70 # 0 +0x0000C2F3 0x9EA6 # 0 +0x0000C2F4 0x5356 # 0 +0x0000C2F5 0x8FC8 # 0 +0x0000C2F6 0x8109 # 0 +0x0000C2F7 0x7792 # 0 +0x0000C2F8 0x9992 # 0 +0x0000C2F9 0x86EE # 0 +0x0000C2FA 0x6EE1 # 0 +0x0000C2FB 0x8513 # 0 +0x0000C2FC 0x66FC # 0 +0x0000C2FD 0x6162 # 0 +0x0000C2FE 0x6F2B # 0 +0x0000C3A1 0x8C29 # 0 +0x0000C3A2 0x8292 # 0 +0x0000C3A3 0x832B # 0 +0x0000C3A4 0x76F2 # 0 +0x0000C3A5 0x6C13 # 0 +0x0000C3A6 0x5FD9 # 0 +0x0000C3A7 0x83BD # 0 +0x0000C3A8 0x732B # 0 +0x0000C3A9 0x8305 # 0 +0x0000C3AA 0x951A # 0 +0x0000C3AB 0x6BDB # 0 +0x0000C3AC 0x77DB # 0 +0x0000C3AD 0x94C6 # 0 +0x0000C3AE 0x536F # 0 +0x0000C3AF 0x8302 # 0 +0x0000C3B0 0x5192 # 0 +0x0000C3B1 0x5E3D # 0 +0x0000C3B2 0x8C8C # 0 +0x0000C3B3 0x8D38 # 0 +0x0000C3B4 0x4E48 # 0 +0x0000C3B5 0x73AB # 0 +0x0000C3B6 0x679A # 0 +0x0000C3B7 0x6885 # 0 +0x0000C3B8 0x9176 # 0 +0x0000C3B9 0x9709 # 0 +0x0000C3BA 0x7164 # 0 +0x0000C3BB 0x6CA1 # 0 +0x0000C3BC 0x7709 # 0 +0x0000C3BD 0x5A92 # 0 +0x0000C3BE 0x9541 # 0 +0x0000C3BF 0x6BCF # 0 +0x0000C3C0 0x7F8E # 0 +0x0000C3C1 0x6627 # 0 +0x0000C3C2 0x5BD0 # 0 +0x0000C3C3 0x59B9 # 0 +0x0000C3C4 0x5A9A # 0 +0x0000C3C5 0x95E8 # 0 +0x0000C3C6 0x95F7 # 0 +0x0000C3C7 0x4EEC # 0 +0x0000C3C8 0x840C # 0 +0x0000C3C9 0x8499 # 0 +0x0000C3CA 0x6AAC # 0 +0x0000C3CB 0x76DF # 0 +0x0000C3CC 0x9530 # 0 +0x0000C3CD 0x731B # 0 +0x0000C3CE 0x68A6 # 0 +0x0000C3CF 0x5B5F # 0 +0x0000C3D0 0x772F # 0 +0x0000C3D1 0x919A # 0 +0x0000C3D2 0x9761 # 0 +0x0000C3D3 0x7CDC # 0 +0x0000C3D4 0x8FF7 # 0 +0x0000C3D5 0x8C1C # 0 +0x0000C3D6 0x5F25 # 0 +0x0000C3D7 0x7C73 # 0 +0x0000C3D8 0x79D8 # 0 +0x0000C3D9 0x89C5 # 0 +0x0000C3DA 0x6CCC # 0 +0x0000C3DB 0x871C # 0 +0x0000C3DC 0x5BC6 # 0 +0x0000C3DD 0x5E42 # 0 +0x0000C3DE 0x68C9 # 0 +0x0000C3DF 0x7720 # 0 +0x0000C3E0 0x7EF5 # 0 +0x0000C3E1 0x5195 # 0 +0x0000C3E2 0x514D # 0 +0x0000C3E3 0x52C9 # 0 +0x0000C3E4 0x5A29 # 0 +0x0000C3E5 0x7F05 # 0 +0x0000C3E6 0x9762 # 0 +0x0000C3E7 0x82D7 # 0 +0x0000C3E8 0x63CF # 0 +0x0000C3E9 0x7784 # 0 +0x0000C3EA 0x85D0 # 0 +0x0000C3EB 0x79D2 # 0 +0x0000C3EC 0x6E3A # 0 +0x0000C3ED 0x5E99 # 0 +0x0000C3EE 0x5999 # 0 +0x0000C3EF 0x8511 # 0 +0x0000C3F0 0x706D # 0 +0x0000C3F1 0x6C11 # 0 +0x0000C3F2 0x62BF # 0 +0x0000C3F3 0x76BF # 0 +0x0000C3F4 0x654F # 0 +0x0000C3F5 0x60AF # 0 +0x0000C3F6 0x95FD # 0 +0x0000C3F7 0x660E # 0 +0x0000C3F8 0x879F # 0 +0x0000C3F9 0x9E23 # 0 +0x0000C3FA 0x94ED # 0 +0x0000C3FB 0x540D # 0 +0x0000C3FC 0x547D # 0 +0x0000C3FD 0x8C2C # 0 +0x0000C3FE 0x6478 # 0 +0x0000C4A1 0x6479 # 0 +0x0000C4A2 0x8611 # 0 +0x0000C4A3 0x6A21 # 0 +0x0000C4A4 0x819C # 0 +0x0000C4A5 0x78E8 # 0 +0x0000C4A6 0x6469 # 0 +0x0000C4A7 0x9B54 # 0 +0x0000C4A8 0x62B9 # 0 +0x0000C4A9 0x672B # 0 +0x0000C4AA 0x83AB # 0 +0x0000C4AB 0x58A8 # 0 +0x0000C4AC 0x9ED8 # 0 +0x0000C4AD 0x6CAB # 0 +0x0000C4AE 0x6F20 # 0 +0x0000C4AF 0x5BDE # 0 +0x0000C4B0 0x964C # 0 +0x0000C4B1 0x8C0B # 0 +0x0000C4B2 0x725F # 0 +0x0000C4B3 0x67D0 # 0 +0x0000C4B4 0x62C7 # 0 +0x0000C4B5 0x7261 # 0 +0x0000C4B6 0x4EA9 # 0 +0x0000C4B7 0x59C6 # 0 +0x0000C4B8 0x6BCD # 0 +0x0000C4B9 0x5893 # 0 +0x0000C4BA 0x66AE # 0 +0x0000C4BB 0x5E55 # 0 +0x0000C4BC 0x52DF # 0 +0x0000C4BD 0x6155 # 0 +0x0000C4BE 0x6728 # 0 +0x0000C4BF 0x76EE # 0 +0x0000C4C0 0x7766 # 0 +0x0000C4C1 0x7267 # 0 +0x0000C4C2 0x7A46 # 0 +0x0000C4C3 0x62FF # 0 +0x0000C4C4 0x54EA # 0 +0x0000C4C5 0x5450 # 0 +0x0000C4C6 0x94A0 # 0 +0x0000C4C7 0x90A3 # 0 +0x0000C4C8 0x5A1C # 0 +0x0000C4C9 0x7EB3 # 0 +0x0000C4CA 0x6C16 # 0 +0x0000C4CB 0x4E43 # 0 +0x0000C4CC 0x5976 # 0 +0x0000C4CD 0x8010 # 0 +0x0000C4CE 0x5948 # 0 +0x0000C4CF 0x5357 # 0 +0x0000C4D0 0x7537 # 0 +0x0000C4D1 0x96BE # 0 +0x0000C4D2 0x56CA # 0 +0x0000C4D3 0x6320 # 0 +0x0000C4D4 0x8111 # 0 +0x0000C4D5 0x607C # 0 +0x0000C4D6 0x95F9 # 0 +0x0000C4D7 0x6DD6 # 0 +0x0000C4D8 0x5462 # 0 +0x0000C4D9 0x9981 # 0 +0x0000C4DA 0x5185 # 0 +0x0000C4DB 0x5AE9 # 0 +0x0000C4DC 0x80FD # 0 +0x0000C4DD 0x59AE # 0 +0x0000C4DE 0x9713 # 0 +0x0000C4DF 0x502A # 0 +0x0000C4E0 0x6CE5 # 0 +0x0000C4E1 0x5C3C # 0 +0x0000C4E2 0x62DF # 0 +0x0000C4E3 0x4F60 # 0 +0x0000C4E4 0x533F # 0 +0x0000C4E5 0x817B # 0 +0x0000C4E6 0x9006 # 0 +0x0000C4E7 0x6EBA # 0 +0x0000C4E8 0x852B # 0 +0x0000C4E9 0x62C8 # 0 +0x0000C4EA 0x5E74 # 0 +0x0000C4EB 0x78BE # 0 +0x0000C4EC 0x64B5 # 0 +0x0000C4ED 0x637B # 0 +0x0000C4EE 0x5FF5 # 0 +0x0000C4EF 0x5A18 # 0 +0x0000C4F0 0x917F # 0 +0x0000C4F1 0x9E1F # 0 +0x0000C4F2 0x5C3F # 0 +0x0000C4F3 0x634F # 0 +0x0000C4F4 0x8042 # 0 +0x0000C4F5 0x5B7D # 0 +0x0000C4F6 0x556E # 0 +0x0000C4F7 0x954A # 0 +0x0000C4F8 0x954D # 0 +0x0000C4F9 0x6D85 # 0 +0x0000C4FA 0x60A8 # 0 +0x0000C4FB 0x67E0 # 0 +0x0000C4FC 0x72DE # 0 +0x0000C4FD 0x51DD # 0 +0x0000C4FE 0x5B81 # 0 +0x0000C5A1 0x62E7 # 0 +0x0000C5A2 0x6CDE # 0 +0x0000C5A3 0x725B # 0 +0x0000C5A4 0x626D # 0 +0x0000C5A5 0x94AE # 0 +0x0000C5A6 0x7EBD # 0 +0x0000C5A7 0x8113 # 0 +0x0000C5A8 0x6D53 # 0 +0x0000C5A9 0x519C # 0 +0x0000C5AA 0x5F04 # 0 +0x0000C5AB 0x5974 # 0 +0x0000C5AC 0x52AA # 0 +0x0000C5AD 0x6012 # 0 +0x0000C5AE 0x5973 # 0 +0x0000C5AF 0x6696 # 0 +0x0000C5B0 0x8650 # 0 +0x0000C5B1 0x759F # 0 +0x0000C5B2 0x632A # 0 +0x0000C5B3 0x61E6 # 0 +0x0000C5B4 0x7CEF # 0 +0x0000C5B5 0x8BFA # 0 +0x0000C5B6 0x54E6 # 0 +0x0000C5B7 0x6B27 # 0 +0x0000C5B8 0x9E25 # 0 +0x0000C5B9 0x6BB4 # 0 +0x0000C5BA 0x85D5 # 0 +0x0000C5BB 0x5455 # 0 +0x0000C5BC 0x5076 # 0 +0x0000C5BD 0x6CA4 # 0 +0x0000C5BE 0x556A # 0 +0x0000C5BF 0x8DB4 # 0 +0x0000C5C0 0x722C # 0 +0x0000C5C1 0x5E15 # 0 +0x0000C5C2 0x6015 # 0 +0x0000C5C3 0x7436 # 0 +0x0000C5C4 0x62CD # 0 +0x0000C5C5 0x6392 # 0 +0x0000C5C6 0x724C # 0 +0x0000C5C7 0x5F98 # 0 +0x0000C5C8 0x6E43 # 0 +0x0000C5C9 0x6D3E # 0 +0x0000C5CA 0x6500 # 0 +0x0000C5CB 0x6F58 # 0 +0x0000C5CC 0x76D8 # 0 +0x0000C5CD 0x78D0 # 0 +0x0000C5CE 0x76FC # 0 +0x0000C5CF 0x7554 # 0 +0x0000C5D0 0x5224 # 0 +0x0000C5D1 0x53DB # 0 +0x0000C5D2 0x4E53 # 0 +0x0000C5D3 0x5E9E # 0 +0x0000C5D4 0x65C1 # 0 +0x0000C5D5 0x802A # 0 +0x0000C5D6 0x80D6 # 0 +0x0000C5D7 0x629B # 0 +0x0000C5D8 0x5486 # 0 +0x0000C5D9 0x5228 # 0 +0x0000C5DA 0x70AE # 0 +0x0000C5DB 0x888D # 0 +0x0000C5DC 0x8DD1 # 0 +0x0000C5DD 0x6CE1 # 0 +0x0000C5DE 0x5478 # 0 +0x0000C5DF 0x80DA # 0 +0x0000C5E0 0x57F9 # 0 +0x0000C5E1 0x88F4 # 0 +0x0000C5E2 0x8D54 # 0 +0x0000C5E3 0x966A # 0 +0x0000C5E4 0x914D # 0 +0x0000C5E5 0x4F69 # 0 +0x0000C5E6 0x6C9B # 0 +0x0000C5E7 0x55B7 # 0 +0x0000C5E8 0x76C6 # 0 +0x0000C5E9 0x7830 # 0 +0x0000C5EA 0x62A8 # 0 +0x0000C5EB 0x70F9 # 0 +0x0000C5EC 0x6F8E # 0 +0x0000C5ED 0x5F6D # 0 +0x0000C5EE 0x84EC # 0 +0x0000C5EF 0x68DA # 0 +0x0000C5F0 0x787C # 0 +0x0000C5F1 0x7BF7 # 0 +0x0000C5F2 0x81A8 # 0 +0x0000C5F3 0x670B # 0 +0x0000C5F4 0x9E4F # 0 +0x0000C5F5 0x6367 # 0 +0x0000C5F6 0x78B0 # 0 +0x0000C5F7 0x576F # 0 +0x0000C5F8 0x7812 # 0 +0x0000C5F9 0x9739 # 0 +0x0000C5FA 0x6279 # 0 +0x0000C5FB 0x62AB # 0 +0x0000C5FC 0x5288 # 0 +0x0000C5FD 0x7435 # 0 +0x0000C5FE 0x6BD7 # 0 +0x0000C6A1 0x5564 # 0 +0x0000C6A2 0x813E # 0 +0x0000C6A3 0x75B2 # 0 +0x0000C6A4 0x76AE # 0 +0x0000C6A5 0x5339 # 0 +0x0000C6A6 0x75DE # 0 +0x0000C6A7 0x50FB # 0 +0x0000C6A8 0x5C41 # 0 +0x0000C6A9 0x8B6C # 0 +0x0000C6AA 0x7BC7 # 0 +0x0000C6AB 0x504F # 0 +0x0000C6AC 0x7247 # 0 +0x0000C6AD 0x9A97 # 0 +0x0000C6AE 0x98D8 # 0 +0x0000C6AF 0x6F02 # 0 +0x0000C6B0 0x74E2 # 0 +0x0000C6B1 0x7968 # 0 +0x0000C6B2 0x6487 # 0 +0x0000C6B3 0x77A5 # 0 +0x0000C6B4 0x62FC # 0 +0x0000C6B5 0x9891 # 0 +0x0000C6B6 0x8D2B # 0 +0x0000C6B7 0x54C1 # 0 +0x0000C6B8 0x8058 # 0 +0x0000C6B9 0x4E52 # 0 +0x0000C6BA 0x576A # 0 +0x0000C6BB 0x82F9 # 0 +0x0000C6BC 0x840D # 0 +0x0000C6BD 0x5E73 # 0 +0x0000C6BE 0x51ED # 0 +0x0000C6BF 0x74F6 # 0 +0x0000C6C0 0x8BC4 # 0 +0x0000C6C1 0x5C4F # 0 +0x0000C6C2 0x5761 # 0 +0x0000C6C3 0x6CFC # 0 +0x0000C6C4 0x9887 # 0 +0x0000C6C5 0x5A46 # 0 +0x0000C6C6 0x7834 # 0 +0x0000C6C7 0x9B44 # 0 +0x0000C6C8 0x8FEB # 0 +0x0000C6C9 0x7C95 # 0 +0x0000C6CA 0x5256 # 0 +0x0000C6CB 0x6251 # 0 +0x0000C6CC 0x94FA # 0 +0x0000C6CD 0x4EC6 # 0 +0x0000C6CE 0x8386 # 0 +0x0000C6CF 0x8461 # 0 +0x0000C6D0 0x83E9 # 0 +0x0000C6D1 0x84B2 # 0 +0x0000C6D2 0x57D4 # 0 +0x0000C6D3 0x6734 # 0 +0x0000C6D4 0x5703 # 0 +0x0000C6D5 0x666E # 0 +0x0000C6D6 0x6D66 # 0 +0x0000C6D7 0x8C31 # 0 +0x0000C6D8 0x66DD # 0 +0x0000C6D9 0x7011 # 0 +0x0000C6DA 0x671F # 0 +0x0000C6DB 0x6B3A # 0 +0x0000C6DC 0x6816 # 0 +0x0000C6DD 0x621A # 0 +0x0000C6DE 0x59BB # 0 +0x0000C6DF 0x4E03 # 0 +0x0000C6E0 0x51C4 # 0 +0x0000C6E1 0x6F06 # 0 +0x0000C6E2 0x67D2 # 0 +0x0000C6E3 0x6C8F # 0 +0x0000C6E4 0x5176 # 0 +0x0000C6E5 0x68CB # 0 +0x0000C6E6 0x5947 # 0 +0x0000C6E7 0x6B67 # 0 +0x0000C6E8 0x7566 # 0 +0x0000C6E9 0x5D0E # 0 +0x0000C6EA 0x8110 # 0 +0x0000C6EB 0x9F50 # 0 +0x0000C6EC 0x65D7 # 0 +0x0000C6ED 0x7948 # 0 +0x0000C6EE 0x7941 # 0 +0x0000C6EF 0x9A91 # 0 +0x0000C6F0 0x8D77 # 0 +0x0000C6F1 0x5C82 # 0 +0x0000C6F2 0x4E5E # 0 +0x0000C6F3 0x4F01 # 0 +0x0000C6F4 0x542F # 0 +0x0000C6F5 0x5951 # 0 +0x0000C6F6 0x780C # 0 +0x0000C6F7 0x5668 # 0 +0x0000C6F8 0x6C14 # 0 +0x0000C6F9 0x8FC4 # 0 +0x0000C6FA 0x5F03 # 0 +0x0000C6FB 0x6C7D # 0 +0x0000C6FC 0x6CE3 # 0 +0x0000C6FD 0x8BAB # 0 +0x0000C6FE 0x6390 # 0 +0x0000C7A1 0x6070 # 0 +0x0000C7A2 0x6D3D # 0 +0x0000C7A3 0x7275 # 0 +0x0000C7A4 0x6266 # 0 +0x0000C7A5 0x948E # 0 +0x0000C7A6 0x94C5 # 0 +0x0000C7A7 0x5343 # 0 +0x0000C7A8 0x8FC1 # 0 +0x0000C7A9 0x7B7E # 0 +0x0000C7AA 0x4EDF # 0 +0x0000C7AB 0x8C26 # 0 +0x0000C7AC 0x4E7E # 0 +0x0000C7AD 0x9ED4 # 0 +0x0000C7AE 0x94B1 # 0 +0x0000C7AF 0x94B3 # 0 +0x0000C7B0 0x524D # 0 +0x0000C7B1 0x6F5C # 0 +0x0000C7B2 0x9063 # 0 +0x0000C7B3 0x6D45 # 0 +0x0000C7B4 0x8C34 # 0 +0x0000C7B5 0x5811 # 0 +0x0000C7B6 0x5D4C # 0 +0x0000C7B7 0x6B20 # 0 +0x0000C7B8 0x6B49 # 0 +0x0000C7B9 0x67AA # 0 +0x0000C7BA 0x545B # 0 +0x0000C7BB 0x8154 # 0 +0x0000C7BC 0x7F8C # 0 +0x0000C7BD 0x5899 # 0 +0x0000C7BE 0x8537 # 0 +0x0000C7BF 0x5F3A # 0 +0x0000C7C0 0x62A2 # 0 +0x0000C7C1 0x6A47 # 0 +0x0000C7C2 0x9539 # 0 +0x0000C7C3 0x6572 # 0 +0x0000C7C4 0x6084 # 0 +0x0000C7C5 0x6865 # 0 +0x0000C7C6 0x77A7 # 0 +0x0000C7C7 0x4E54 # 0 +0x0000C7C8 0x4FA8 # 0 +0x0000C7C9 0x5DE7 # 0 +0x0000C7CA 0x9798 # 0 +0x0000C7CB 0x64AC # 0 +0x0000C7CC 0x7FD8 # 0 +0x0000C7CD 0x5CED # 0 +0x0000C7CE 0x4FCF # 0 +0x0000C7CF 0x7A8D # 0 +0x0000C7D0 0x5207 # 0 +0x0000C7D1 0x8304 # 0 +0x0000C7D2 0x4E14 # 0 +0x0000C7D3 0x602F # 0 +0x0000C7D4 0x7A83 # 0 +0x0000C7D5 0x94A6 # 0 +0x0000C7D6 0x4FB5 # 0 +0x0000C7D7 0x4EB2 # 0 +0x0000C7D8 0x79E6 # 0 +0x0000C7D9 0x7434 # 0 +0x0000C7DA 0x52E4 # 0 +0x0000C7DB 0x82B9 # 0 +0x0000C7DC 0x64D2 # 0 +0x0000C7DD 0x79BD # 0 +0x0000C7DE 0x5BDD # 0 +0x0000C7DF 0x6C81 # 0 +0x0000C7E0 0x9752 # 0 +0x0000C7E1 0x8F7B # 0 +0x0000C7E2 0x6C22 # 0 +0x0000C7E3 0x503E # 0 +0x0000C7E4 0x537F # 0 +0x0000C7E5 0x6E05 # 0 +0x0000C7E6 0x64CE # 0 +0x0000C7E7 0x6674 # 0 +0x0000C7E8 0x6C30 # 0 +0x0000C7E9 0x60C5 # 0 +0x0000C7EA 0x9877 # 0 +0x0000C7EB 0x8BF7 # 0 +0x0000C7EC 0x5E86 # 0 +0x0000C7ED 0x743C # 0 +0x0000C7EE 0x7A77 # 0 +0x0000C7EF 0x79CB # 0 +0x0000C7F0 0x4E18 # 0 +0x0000C7F1 0x90B1 # 0 +0x0000C7F2 0x7403 # 0 +0x0000C7F3 0x6C42 # 0 +0x0000C7F4 0x56DA # 0 +0x0000C7F5 0x914B # 0 +0x0000C7F6 0x6CC5 # 0 +0x0000C7F7 0x8D8B # 0 +0x0000C7F8 0x533A # 0 +0x0000C7F9 0x86C6 # 0 +0x0000C7FA 0x66F2 # 0 +0x0000C7FB 0x8EAF # 0 +0x0000C7FC 0x5C48 # 0 +0x0000C7FD 0x9A71 # 0 +0x0000C7FE 0x6E20 # 0 +0x0000C8A1 0x53D6 # 0 +0x0000C8A2 0x5A36 # 0 +0x0000C8A3 0x9F8B # 0 +0x0000C8A4 0x8DA3 # 0 +0x0000C8A5 0x53BB # 0 +0x0000C8A6 0x5708 # 0 +0x0000C8A7 0x98A7 # 0 +0x0000C8A8 0x6743 # 0 +0x0000C8A9 0x919B # 0 +0x0000C8AA 0x6CC9 # 0 +0x0000C8AB 0x5168 # 0 +0x0000C8AC 0x75CA # 0 +0x0000C8AD 0x62F3 # 0 +0x0000C8AE 0x72AC # 0 +0x0000C8AF 0x5238 # 0 +0x0000C8B0 0x529D # 0 +0x0000C8B1 0x7F3A # 0 +0x0000C8B2 0x7094 # 0 +0x0000C8B3 0x7638 # 0 +0x0000C8B4 0x5374 # 0 +0x0000C8B5 0x9E4A # 0 +0x0000C8B6 0x69B7 # 0 +0x0000C8B7 0x786E # 0 +0x0000C8B8 0x96C0 # 0 +0x0000C8B9 0x88D9 # 0 +0x0000C8BA 0x7FA4 # 0 +0x0000C8BB 0x7136 # 0 +0x0000C8BC 0x71C3 # 0 +0x0000C8BD 0x5189 # 0 +0x0000C8BE 0x67D3 # 0 +0x0000C8BF 0x74E4 # 0 +0x0000C8C0 0x58E4 # 0 +0x0000C8C1 0x6518 # 0 +0x0000C8C2 0x56B7 # 0 +0x0000C8C3 0x8BA9 # 0 +0x0000C8C4 0x9976 # 0 +0x0000C8C5 0x6270 # 0 +0x0000C8C6 0x7ED5 # 0 +0x0000C8C7 0x60F9 # 0 +0x0000C8C8 0x70ED # 0 +0x0000C8C9 0x58EC # 0 +0x0000C8CA 0x4EC1 # 0 +0x0000C8CB 0x4EBA # 0 +0x0000C8CC 0x5FCD # 0 +0x0000C8CD 0x97E7 # 0 +0x0000C8CE 0x4EFB # 0 +0x0000C8CF 0x8BA4 # 0 +0x0000C8D0 0x5203 # 0 +0x0000C8D1 0x598A # 0 +0x0000C8D2 0x7EAB # 0 +0x0000C8D3 0x6254 # 0 +0x0000C8D4 0x4ECD # 0 +0x0000C8D5 0x65E5 # 0 +0x0000C8D6 0x620E # 0 +0x0000C8D7 0x8338 # 0 +0x0000C8D8 0x84C9 # 0 +0x0000C8D9 0x8363 # 0 +0x0000C8DA 0x878D # 0 +0x0000C8DB 0x7194 # 0 +0x0000C8DC 0x6EB6 # 0 +0x0000C8DD 0x5BB9 # 0 +0x0000C8DE 0x7ED2 # 0 +0x0000C8DF 0x5197 # 0 +0x0000C8E0 0x63C9 # 0 +0x0000C8E1 0x67D4 # 0 +0x0000C8E2 0x8089 # 0 +0x0000C8E3 0x8339 # 0 +0x0000C8E4 0x8815 # 0 +0x0000C8E5 0x5112 # 0 +0x0000C8E6 0x5B7A # 0 +0x0000C8E7 0x5982 # 0 +0x0000C8E8 0x8FB1 # 0 +0x0000C8E9 0x4E73 # 0 +0x0000C8EA 0x6C5D # 0 +0x0000C8EB 0x5165 # 0 +0x0000C8EC 0x8925 # 0 +0x0000C8ED 0x8F6F # 0 +0x0000C8EE 0x962E # 0 +0x0000C8EF 0x854A # 0 +0x0000C8F0 0x745E # 0 +0x0000C8F1 0x9510 # 0 +0x0000C8F2 0x95F0 # 0 +0x0000C8F3 0x6DA6 # 0 +0x0000C8F4 0x82E5 # 0 +0x0000C8F5 0x5F31 # 0 +0x0000C8F6 0x6492 # 0 +0x0000C8F7 0x6D12 # 0 +0x0000C8F8 0x8428 # 0 +0x0000C8F9 0x816E # 0 +0x0000C8FA 0x9CC3 # 0 +0x0000C8FB 0x585E # 0 +0x0000C8FC 0x8D5B # 0 +0x0000C8FD 0x4E09 # 0 +0x0000C8FE 0x53C1 # 0 +0x0000C9A1 0x4F1E # 0 +0x0000C9A2 0x6563 # 0 +0x0000C9A3 0x6851 # 0 +0x0000C9A4 0x55D3 # 0 +0x0000C9A5 0x4E27 # 0 +0x0000C9A6 0x6414 # 0 +0x0000C9A7 0x9A9A # 0 +0x0000C9A8 0x626B # 0 +0x0000C9A9 0x5AC2 # 0 +0x0000C9AA 0x745F # 0 +0x0000C9AB 0x8272 # 0 +0x0000C9AC 0x6DA9 # 0 +0x0000C9AD 0x68EE # 0 +0x0000C9AE 0x50E7 # 0 +0x0000C9AF 0x838E # 0 +0x0000C9B0 0x7802 # 0 +0x0000C9B1 0x6740 # 0 +0x0000C9B2 0x5239 # 0 +0x0000C9B3 0x6C99 # 0 +0x0000C9B4 0x7EB1 # 0 +0x0000C9B5 0x50BB # 0 +0x0000C9B6 0x5565 # 0 +0x0000C9B7 0x715E # 0 +0x0000C9B8 0x7B5B # 0 +0x0000C9B9 0x6652 # 0 +0x0000C9BA 0x73CA # 0 +0x0000C9BB 0x82EB # 0 +0x0000C9BC 0x6749 # 0 +0x0000C9BD 0x5C71 # 0 +0x0000C9BE 0x5220 # 0 +0x0000C9BF 0x717D # 0 +0x0000C9C0 0x886B # 0 +0x0000C9C1 0x95EA # 0 +0x0000C9C2 0x9655 # 0 +0x0000C9C3 0x64C5 # 0 +0x0000C9C4 0x8D61 # 0 +0x0000C9C5 0x81B3 # 0 +0x0000C9C6 0x5584 # 0 +0x0000C9C7 0x6C55 # 0 +0x0000C9C8 0x6247 # 0 +0x0000C9C9 0x7F2E # 0 +0x0000C9CA 0x5892 # 0 +0x0000C9CB 0x4F24 # 0 +0x0000C9CC 0x5546 # 0 +0x0000C9CD 0x8D4F # 0 +0x0000C9CE 0x664C # 0 +0x0000C9CF 0x4E0A # 0 +0x0000C9D0 0x5C1A # 0 +0x0000C9D1 0x88F3 # 0 +0x0000C9D2 0x68A2 # 0 +0x0000C9D3 0x634E # 0 +0x0000C9D4 0x7A0D # 0 +0x0000C9D5 0x70E7 # 0 +0x0000C9D6 0x828D # 0 +0x0000C9D7 0x52FA # 0 +0x0000C9D8 0x97F6 # 0 +0x0000C9D9 0x5C11 # 0 +0x0000C9DA 0x54E8 # 0 +0x0000C9DB 0x90B5 # 0 +0x0000C9DC 0x7ECD # 0 +0x0000C9DD 0x5962 # 0 +0x0000C9DE 0x8D4A # 0 +0x0000C9DF 0x86C7 # 0 +0x0000C9E0 0x820C # 0 +0x0000C9E1 0x820D # 0 +0x0000C9E2 0x8D66 # 0 +0x0000C9E3 0x6444 # 0 +0x0000C9E4 0x5C04 # 0 +0x0000C9E5 0x6151 # 0 +0x0000C9E6 0x6D89 # 0 +0x0000C9E7 0x793E # 0 +0x0000C9E8 0x8BBE # 0 +0x0000C9E9 0x7837 # 0 +0x0000C9EA 0x7533 # 0 +0x0000C9EB 0x547B # 0 +0x0000C9EC 0x4F38 # 0 +0x0000C9ED 0x8EAB # 0 +0x0000C9EE 0x6DF1 # 0 +0x0000C9EF 0x5A20 # 0 +0x0000C9F0 0x7EC5 # 0 +0x0000C9F1 0x795E # 0 +0x0000C9F2 0x6C88 # 0 +0x0000C9F3 0x5BA1 # 0 +0x0000C9F4 0x5A76 # 0 +0x0000C9F5 0x751A # 0 +0x0000C9F6 0x80BE # 0 +0x0000C9F7 0x614E # 0 +0x0000C9F8 0x6E17 # 0 +0x0000C9F9 0x58F0 # 0 +0x0000C9FA 0x751F # 0 +0x0000C9FB 0x7525 # 0 +0x0000C9FC 0x7272 # 0 +0x0000C9FD 0x5347 # 0 +0x0000C9FE 0x7EF3 # 0 +0x0000CAA1 0x7701 # 0 +0x0000CAA2 0x76DB # 0 +0x0000CAA3 0x5269 # 0 +0x0000CAA4 0x80DC # 0 +0x0000CAA5 0x5723 # 0 +0x0000CAA6 0x5E08 # 0 +0x0000CAA7 0x5931 # 0 +0x0000CAA8 0x72EE # 0 +0x0000CAA9 0x65BD # 0 +0x0000CAAA 0x6E7F # 0 +0x0000CAAB 0x8BD7 # 0 +0x0000CAAC 0x5C38 # 0 +0x0000CAAD 0x8671 # 0 +0x0000CAAE 0x5341 # 0 +0x0000CAAF 0x77F3 # 0 +0x0000CAB0 0x62FE # 0 +0x0000CAB1 0x65F6 # 0 +0x0000CAB2 0x4EC0 # 0 +0x0000CAB3 0x98DF # 0 +0x0000CAB4 0x8680 # 0 +0x0000CAB5 0x5B9E # 0 +0x0000CAB6 0x8BC6 # 0 +0x0000CAB7 0x53F2 # 0 +0x0000CAB8 0x77E2 # 0 +0x0000CAB9 0x4F7F # 0 +0x0000CABA 0x5C4E # 0 +0x0000CABB 0x9A76 # 0 +0x0000CABC 0x59CB # 0 +0x0000CABD 0x5F0F # 0 +0x0000CABE 0x793A # 0 +0x0000CABF 0x58EB # 0 +0x0000CAC0 0x4E16 # 0 +0x0000CAC1 0x67FF # 0 +0x0000CAC2 0x4E8B # 0 +0x0000CAC3 0x62ED # 0 +0x0000CAC4 0x8A93 # 0 +0x0000CAC5 0x901D # 0 +0x0000CAC6 0x52BF # 0 +0x0000CAC7 0x662F # 0 +0x0000CAC8 0x55DC # 0 +0x0000CAC9 0x566C # 0 +0x0000CACA 0x9002 # 0 +0x0000CACB 0x4ED5 # 0 +0x0000CACC 0x4F8D # 0 +0x0000CACD 0x91CA # 0 +0x0000CACE 0x9970 # 0 +0x0000CACF 0x6C0F # 0 +0x0000CAD0 0x5E02 # 0 +0x0000CAD1 0x6043 # 0 +0x0000CAD2 0x5BA4 # 0 +0x0000CAD3 0x89C6 # 0 +0x0000CAD4 0x8BD5 # 0 +0x0000CAD5 0x6536 # 0 +0x0000CAD6 0x624B # 0 +0x0000CAD7 0x9996 # 0 +0x0000CAD8 0x5B88 # 0 +0x0000CAD9 0x5BFF # 0 +0x0000CADA 0x6388 # 0 +0x0000CADB 0x552E # 0 +0x0000CADC 0x53D7 # 0 +0x0000CADD 0x7626 # 0 +0x0000CADE 0x517D # 0 +0x0000CADF 0x852C # 0 +0x0000CAE0 0x67A2 # 0 +0x0000CAE1 0x68B3 # 0 +0x0000CAE2 0x6B8A # 0 +0x0000CAE3 0x6292 # 0 +0x0000CAE4 0x8F93 # 0 +0x0000CAE5 0x53D4 # 0 +0x0000CAE6 0x8212 # 0 +0x0000CAE7 0x6DD1 # 0 +0x0000CAE8 0x758F # 0 +0x0000CAE9 0x4E66 # 0 +0x0000CAEA 0x8D4E # 0 +0x0000CAEB 0x5B70 # 0 +0x0000CAEC 0x719F # 0 +0x0000CAED 0x85AF # 0 +0x0000CAEE 0x6691 # 0 +0x0000CAEF 0x66D9 # 0 +0x0000CAF0 0x7F72 # 0 +0x0000CAF1 0x8700 # 0 +0x0000CAF2 0x9ECD # 0 +0x0000CAF3 0x9F20 # 0 +0x0000CAF4 0x5C5E # 0 +0x0000CAF5 0x672F # 0 +0x0000CAF6 0x8FF0 # 0 +0x0000CAF7 0x6811 # 0 +0x0000CAF8 0x675F # 0 +0x0000CAF9 0x620D # 0 +0x0000CAFA 0x7AD6 # 0 +0x0000CAFB 0x5885 # 0 +0x0000CAFC 0x5EB6 # 0 +0x0000CAFD 0x6570 # 0 +0x0000CAFE 0x6F31 # 0 +0x0000CBA1 0x6055 # 0 +0x0000CBA2 0x5237 # 0 +0x0000CBA3 0x800D # 0 +0x0000CBA4 0x6454 # 0 +0x0000CBA5 0x8870 # 0 +0x0000CBA6 0x7529 # 0 +0x0000CBA7 0x5E05 # 0 +0x0000CBA8 0x6813 # 0 +0x0000CBA9 0x62F4 # 0 +0x0000CBAA 0x971C # 0 +0x0000CBAB 0x53CC # 0 +0x0000CBAC 0x723D # 0 +0x0000CBAD 0x8C01 # 0 +0x0000CBAE 0x6C34 # 0 +0x0000CBAF 0x7761 # 0 +0x0000CBB0 0x7A0E # 0 +0x0000CBB1 0x542E # 0 +0x0000CBB2 0x77AC # 0 +0x0000CBB3 0x987A # 0 +0x0000CBB4 0x821C # 0 +0x0000CBB5 0x8BF4 # 0 +0x0000CBB6 0x7855 # 0 +0x0000CBB7 0x6714 # 0 +0x0000CBB8 0x70C1 # 0 +0x0000CBB9 0x65AF # 0 +0x0000CBBA 0x6495 # 0 +0x0000CBBB 0x5636 # 0 +0x0000CBBC 0x601D # 0 +0x0000CBBD 0x79C1 # 0 +0x0000CBBE 0x53F8 # 0 +0x0000CBBF 0x4E1D # 0 +0x0000CBC0 0x6B7B # 0 +0x0000CBC1 0x8086 # 0 +0x0000CBC2 0x5BFA # 0 +0x0000CBC3 0x55E3 # 0 +0x0000CBC4 0x56DB # 0 +0x0000CBC5 0x4F3A # 0 +0x0000CBC6 0x4F3C # 0 +0x0000CBC7 0x9972 # 0 +0x0000CBC8 0x5DF3 # 0 +0x0000CBC9 0x677E # 0 +0x0000CBCA 0x8038 # 0 +0x0000CBCB 0x6002 # 0 +0x0000CBCC 0x9882 # 0 +0x0000CBCD 0x9001 # 0 +0x0000CBCE 0x5B8B # 0 +0x0000CBCF 0x8BBC # 0 +0x0000CBD0 0x8BF5 # 0 +0x0000CBD1 0x641C # 0 +0x0000CBD2 0x8258 # 0 +0x0000CBD3 0x64DE # 0 +0x0000CBD4 0x55FD # 0 +0x0000CBD5 0x82CF # 0 +0x0000CBD6 0x9165 # 0 +0x0000CBD7 0x4FD7 # 0 +0x0000CBD8 0x7D20 # 0 +0x0000CBD9 0x901F # 0 +0x0000CBDA 0x7C9F # 0 +0x0000CBDB 0x50F3 # 0 +0x0000CBDC 0x5851 # 0 +0x0000CBDD 0x6EAF # 0 +0x0000CBDE 0x5BBF # 0 +0x0000CBDF 0x8BC9 # 0 +0x0000CBE0 0x8083 # 0 +0x0000CBE1 0x9178 # 0 +0x0000CBE2 0x849C # 0 +0x0000CBE3 0x7B97 # 0 +0x0000CBE4 0x867D # 0 +0x0000CBE5 0x968B # 0 +0x0000CBE6 0x968F # 0 +0x0000CBE7 0x7EE5 # 0 +0x0000CBE8 0x9AD3 # 0 +0x0000CBE9 0x788E # 0 +0x0000CBEA 0x5C81 # 0 +0x0000CBEB 0x7A57 # 0 +0x0000CBEC 0x9042 # 0 +0x0000CBED 0x96A7 # 0 +0x0000CBEE 0x795F # 0 +0x0000CBEF 0x5B59 # 0 +0x0000CBF0 0x635F # 0 +0x0000CBF1 0x7B0B # 0 +0x0000CBF2 0x84D1 # 0 +0x0000CBF3 0x68AD # 0 +0x0000CBF4 0x5506 # 0 +0x0000CBF5 0x7F29 # 0 +0x0000CBF6 0x7410 # 0 +0x0000CBF7 0x7D22 # 0 +0x0000CBF8 0x9501 # 0 +0x0000CBF9 0x6240 # 0 +0x0000CBFA 0x584C # 0 +0x0000CBFB 0x4ED6 # 0 +0x0000CBFC 0x5B83 # 0 +0x0000CBFD 0x5979 # 0 +0x0000CBFE 0x5854 # 0 +0x0000CCA1 0x736D # 0 +0x0000CCA2 0x631E # 0 +0x0000CCA3 0x8E4B # 0 +0x0000CCA4 0x8E0F # 0 +0x0000CCA5 0x80CE # 0 +0x0000CCA6 0x82D4 # 0 +0x0000CCA7 0x62AC # 0 +0x0000CCA8 0x53F0 # 0 +0x0000CCA9 0x6CF0 # 0 +0x0000CCAA 0x915E # 0 +0x0000CCAB 0x592A # 0 +0x0000CCAC 0x6001 # 0 +0x0000CCAD 0x6C70 # 0 +0x0000CCAE 0x574D # 0 +0x0000CCAF 0x644A # 0 +0x0000CCB0 0x8D2A # 0 +0x0000CCB1 0x762B # 0 +0x0000CCB2 0x6EE9 # 0 +0x0000CCB3 0x575B # 0 +0x0000CCB4 0x6A80 # 0 +0x0000CCB5 0x75F0 # 0 +0x0000CCB6 0x6F6D # 0 +0x0000CCB7 0x8C2D # 0 +0x0000CCB8 0x8C08 # 0 +0x0000CCB9 0x5766 # 0 +0x0000CCBA 0x6BEF # 0 +0x0000CCBB 0x8892 # 0 +0x0000CCBC 0x78B3 # 0 +0x0000CCBD 0x63A2 # 0 +0x0000CCBE 0x53F9 # 0 +0x0000CCBF 0x70AD # 0 +0x0000CCC0 0x6C64 # 0 +0x0000CCC1 0x5858 # 0 +0x0000CCC2 0x642A # 0 +0x0000CCC3 0x5802 # 0 +0x0000CCC4 0x68E0 # 0 +0x0000CCC5 0x819B # 0 +0x0000CCC6 0x5510 # 0 +0x0000CCC7 0x7CD6 # 0 +0x0000CCC8 0x5018 # 0 +0x0000CCC9 0x8EBA # 0 +0x0000CCCA 0x6DCC # 0 +0x0000CCCB 0x8D9F # 0 +0x0000CCCC 0x70EB # 0 +0x0000CCCD 0x638F # 0 +0x0000CCCE 0x6D9B # 0 +0x0000CCCF 0x6ED4 # 0 +0x0000CCD0 0x7EE6 # 0 +0x0000CCD1 0x8404 # 0 +0x0000CCD2 0x6843 # 0 +0x0000CCD3 0x9003 # 0 +0x0000CCD4 0x6DD8 # 0 +0x0000CCD5 0x9676 # 0 +0x0000CCD6 0x8BA8 # 0 +0x0000CCD7 0x5957 # 0 +0x0000CCD8 0x7279 # 0 +0x0000CCD9 0x85E4 # 0 +0x0000CCDA 0x817E # 0 +0x0000CCDB 0x75BC # 0 +0x0000CCDC 0x8A8A # 0 +0x0000CCDD 0x68AF # 0 +0x0000CCDE 0x5254 # 0 +0x0000CCDF 0x8E22 # 0 +0x0000CCE0 0x9511 # 0 +0x0000CCE1 0x63D0 # 0 +0x0000CCE2 0x9898 # 0 +0x0000CCE3 0x8E44 # 0 +0x0000CCE4 0x557C # 0 +0x0000CCE5 0x4F53 # 0 +0x0000CCE6 0x66FF # 0 +0x0000CCE7 0x568F # 0 +0x0000CCE8 0x60D5 # 0 +0x0000CCE9 0x6D95 # 0 +0x0000CCEA 0x5243 # 0 +0x0000CCEB 0x5C49 # 0 +0x0000CCEC 0x5929 # 0 +0x0000CCED 0x6DFB # 0 +0x0000CCEE 0x586B # 0 +0x0000CCEF 0x7530 # 0 +0x0000CCF0 0x751C # 0 +0x0000CCF1 0x606C # 0 +0x0000CCF2 0x8214 # 0 +0x0000CCF3 0x8146 # 0 +0x0000CCF4 0x6311 # 0 +0x0000CCF5 0x6761 # 0 +0x0000CCF6 0x8FE2 # 0 +0x0000CCF7 0x773A # 0 +0x0000CCF8 0x8DF3 # 0 +0x0000CCF9 0x8D34 # 0 +0x0000CCFA 0x94C1 # 0 +0x0000CCFB 0x5E16 # 0 +0x0000CCFC 0x5385 # 0 +0x0000CCFD 0x542C # 0 +0x0000CCFE 0x70C3 # 0 +0x0000CDA1 0x6C40 # 0 +0x0000CDA2 0x5EF7 # 0 +0x0000CDA3 0x505C # 0 +0x0000CDA4 0x4EAD # 0 +0x0000CDA5 0x5EAD # 0 +0x0000CDA6 0x633A # 0 +0x0000CDA7 0x8247 # 0 +0x0000CDA8 0x901A # 0 +0x0000CDA9 0x6850 # 0 +0x0000CDAA 0x916E # 0 +0x0000CDAB 0x77B3 # 0 +0x0000CDAC 0x540C # 0 +0x0000CDAD 0x94DC # 0 +0x0000CDAE 0x5F64 # 0 +0x0000CDAF 0x7AE5 # 0 +0x0000CDB0 0x6876 # 0 +0x0000CDB1 0x6345 # 0 +0x0000CDB2 0x7B52 # 0 +0x0000CDB3 0x7EDF # 0 +0x0000CDB4 0x75DB # 0 +0x0000CDB5 0x5077 # 0 +0x0000CDB6 0x6295 # 0 +0x0000CDB7 0x5934 # 0 +0x0000CDB8 0x900F # 0 +0x0000CDB9 0x51F8 # 0 +0x0000CDBA 0x79C3 # 0 +0x0000CDBB 0x7A81 # 0 +0x0000CDBC 0x56FE # 0 +0x0000CDBD 0x5F92 # 0 +0x0000CDBE 0x9014 # 0 +0x0000CDBF 0x6D82 # 0 +0x0000CDC0 0x5C60 # 0 +0x0000CDC1 0x571F # 0 +0x0000CDC2 0x5410 # 0 +0x0000CDC3 0x5154 # 0 +0x0000CDC4 0x6E4D # 0 +0x0000CDC5 0x56E2 # 0 +0x0000CDC6 0x63A8 # 0 +0x0000CDC7 0x9893 # 0 +0x0000CDC8 0x817F # 0 +0x0000CDC9 0x8715 # 0 +0x0000CDCA 0x892A # 0 +0x0000CDCB 0x9000 # 0 +0x0000CDCC 0x541E # 0 +0x0000CDCD 0x5C6F # 0 +0x0000CDCE 0x81C0 # 0 +0x0000CDCF 0x62D6 # 0 +0x0000CDD0 0x6258 # 0 +0x0000CDD1 0x8131 # 0 +0x0000CDD2 0x9E35 # 0 +0x0000CDD3 0x9640 # 0 +0x0000CDD4 0x9A6E # 0 +0x0000CDD5 0x9A7C # 0 +0x0000CDD6 0x692D # 0 +0x0000CDD7 0x59A5 # 0 +0x0000CDD8 0x62D3 # 0 +0x0000CDD9 0x553E # 0 +0x0000CDDA 0x6316 # 0 +0x0000CDDB 0x54C7 # 0 +0x0000CDDC 0x86D9 # 0 +0x0000CDDD 0x6D3C # 0 +0x0000CDDE 0x5A03 # 0 +0x0000CDDF 0x74E6 # 0 +0x0000CDE0 0x889C # 0 +0x0000CDE1 0x6B6A # 0 +0x0000CDE2 0x5916 # 0 +0x0000CDE3 0x8C4C # 0 +0x0000CDE4 0x5F2F # 0 +0x0000CDE5 0x6E7E # 0 +0x0000CDE6 0x73A9 # 0 +0x0000CDE7 0x987D # 0 +0x0000CDE8 0x4E38 # 0 +0x0000CDE9 0x70F7 # 0 +0x0000CDEA 0x5B8C # 0 +0x0000CDEB 0x7897 # 0 +0x0000CDEC 0x633D # 0 +0x0000CDED 0x665A # 0 +0x0000CDEE 0x7696 # 0 +0x0000CDEF 0x60CB # 0 +0x0000CDF0 0x5B9B # 0 +0x0000CDF1 0x5A49 # 0 +0x0000CDF2 0x4E07 # 0 +0x0000CDF3 0x8155 # 0 +0x0000CDF4 0x6C6A # 0 +0x0000CDF5 0x738B # 0 +0x0000CDF6 0x4EA1 # 0 +0x0000CDF7 0x6789 # 0 +0x0000CDF8 0x7F51 # 0 +0x0000CDF9 0x5F80 # 0 +0x0000CDFA 0x65FA # 0 +0x0000CDFB 0x671B # 0 +0x0000CDFC 0x5FD8 # 0 +0x0000CDFD 0x5984 # 0 +0x0000CDFE 0x5A01 # 0 +0x0000CEA1 0x5DCD # 0 +0x0000CEA2 0x5FAE # 0 +0x0000CEA3 0x5371 # 0 +0x0000CEA4 0x97E6 # 0 +0x0000CEA5 0x8FDD # 0 +0x0000CEA6 0x6845 # 0 +0x0000CEA7 0x56F4 # 0 +0x0000CEA8 0x552F # 0 +0x0000CEA9 0x60DF # 0 +0x0000CEAA 0x4E3A # 0 +0x0000CEAB 0x6F4D # 0 +0x0000CEAC 0x7EF4 # 0 +0x0000CEAD 0x82C7 # 0 +0x0000CEAE 0x840E # 0 +0x0000CEAF 0x59D4 # 0 +0x0000CEB0 0x4F1F # 0 +0x0000CEB1 0x4F2A # 0 +0x0000CEB2 0x5C3E # 0 +0x0000CEB3 0x7EAC # 0 +0x0000CEB4 0x672A # 0 +0x0000CEB5 0x851A # 0 +0x0000CEB6 0x5473 # 0 +0x0000CEB7 0x754F # 0 +0x0000CEB8 0x80C3 # 0 +0x0000CEB9 0x5582 # 0 +0x0000CEBA 0x9B4F # 0 +0x0000CEBB 0x4F4D # 0 +0x0000CEBC 0x6E2D # 0 +0x0000CEBD 0x8C13 # 0 +0x0000CEBE 0x5C09 # 0 +0x0000CEBF 0x6170 # 0 +0x0000CEC0 0x536B # 0 +0x0000CEC1 0x761F # 0 +0x0000CEC2 0x6E29 # 0 +0x0000CEC3 0x868A # 0 +0x0000CEC4 0x6587 # 0 +0x0000CEC5 0x95FB # 0 +0x0000CEC6 0x7EB9 # 0 +0x0000CEC7 0x543B # 0 +0x0000CEC8 0x7A33 # 0 +0x0000CEC9 0x7D0A # 0 +0x0000CECA 0x95EE # 0 +0x0000CECB 0x55E1 # 0 +0x0000CECC 0x7FC1 # 0 +0x0000CECD 0x74EE # 0 +0x0000CECE 0x631D # 0 +0x0000CECF 0x8717 # 0 +0x0000CED0 0x6DA1 # 0 +0x0000CED1 0x7A9D # 0 +0x0000CED2 0x6211 # 0 +0x0000CED3 0x65A1 # 0 +0x0000CED4 0x5367 # 0 +0x0000CED5 0x63E1 # 0 +0x0000CED6 0x6C83 # 0 +0x0000CED7 0x5DEB # 0 +0x0000CED8 0x545C # 0 +0x0000CED9 0x94A8 # 0 +0x0000CEDA 0x4E4C # 0 +0x0000CEDB 0x6C61 # 0 +0x0000CEDC 0x8BEC # 0 +0x0000CEDD 0x5C4B # 0 +0x0000CEDE 0x65E0 # 0 +0x0000CEDF 0x829C # 0 +0x0000CEE0 0x68A7 # 0 +0x0000CEE1 0x543E # 0 +0x0000CEE2 0x5434 # 0 +0x0000CEE3 0x6BCB # 0 +0x0000CEE4 0x6B66 # 0 +0x0000CEE5 0x4E94 # 0 +0x0000CEE6 0x6342 # 0 +0x0000CEE7 0x5348 # 0 +0x0000CEE8 0x821E # 0 +0x0000CEE9 0x4F0D # 0 +0x0000CEEA 0x4FAE # 0 +0x0000CEEB 0x575E # 0 +0x0000CEEC 0x620A # 0 +0x0000CEED 0x96FE # 0 +0x0000CEEE 0x6664 # 0 +0x0000CEEF 0x7269 # 0 +0x0000CEF0 0x52FF # 0 +0x0000CEF1 0x52A1 # 0 +0x0000CEF2 0x609F # 0 +0x0000CEF3 0x8BEF # 0 +0x0000CEF4 0x6614 # 0 +0x0000CEF5 0x7199 # 0 +0x0000CEF6 0x6790 # 0 +0x0000CEF7 0x897F # 0 +0x0000CEF8 0x7852 # 0 +0x0000CEF9 0x77FD # 0 +0x0000CEFA 0x6670 # 0 +0x0000CEFB 0x563B # 0 +0x0000CEFC 0x5438 # 0 +0x0000CEFD 0x9521 # 0 +0x0000CEFE 0x727A # 0 +0x0000CFA1 0x7A00 # 0 +0x0000CFA2 0x606F # 0 +0x0000CFA3 0x5E0C # 0 +0x0000CFA4 0x6089 # 0 +0x0000CFA5 0x819D # 0 +0x0000CFA6 0x5915 # 0 +0x0000CFA7 0x60DC # 0 +0x0000CFA8 0x7184 # 0 +0x0000CFA9 0x70EF # 0 +0x0000CFAA 0x6EAA # 0 +0x0000CFAB 0x6C50 # 0 +0x0000CFAC 0x7280 # 0 +0x0000CFAD 0x6A84 # 0 +0x0000CFAE 0x88AD # 0 +0x0000CFAF 0x5E2D # 0 +0x0000CFB0 0x4E60 # 0 +0x0000CFB1 0x5AB3 # 0 +0x0000CFB2 0x559C # 0 +0x0000CFB3 0x94E3 # 0 +0x0000CFB4 0x6D17 # 0 +0x0000CFB5 0x7CFB # 0 +0x0000CFB6 0x9699 # 0 +0x0000CFB7 0x620F # 0 +0x0000CFB8 0x7EC6 # 0 +0x0000CFB9 0x778E # 0 +0x0000CFBA 0x867E # 0 +0x0000CFBB 0x5323 # 0 +0x0000CFBC 0x971E # 0 +0x0000CFBD 0x8F96 # 0 +0x0000CFBE 0x6687 # 0 +0x0000CFBF 0x5CE1 # 0 +0x0000CFC0 0x4FA0 # 0 +0x0000CFC1 0x72ED # 0 +0x0000CFC2 0x4E0B # 0 +0x0000CFC3 0x53A6 # 0 +0x0000CFC4 0x590F # 0 +0x0000CFC5 0x5413 # 0 +0x0000CFC6 0x6380 # 0 +0x0000CFC7 0x9528 # 0 +0x0000CFC8 0x5148 # 0 +0x0000CFC9 0x4ED9 # 0 +0x0000CFCA 0x9C9C # 0 +0x0000CFCB 0x7EA4 # 0 +0x0000CFCC 0x54B8 # 0 +0x0000CFCD 0x8D24 # 0 +0x0000CFCE 0x8854 # 0 +0x0000CFCF 0x8237 # 0 +0x0000CFD0 0x95F2 # 0 +0x0000CFD1 0x6D8E # 0 +0x0000CFD2 0x5F26 # 0 +0x0000CFD3 0x5ACC # 0 +0x0000CFD4 0x663E # 0 +0x0000CFD5 0x9669 # 0 +0x0000CFD6 0x73B0 # 0 +0x0000CFD7 0x732E # 0 +0x0000CFD8 0x53BF # 0 +0x0000CFD9 0x817A # 0 +0x0000CFDA 0x9985 # 0 +0x0000CFDB 0x7FA1 # 0 +0x0000CFDC 0x5BAA # 0 +0x0000CFDD 0x9677 # 0 +0x0000CFDE 0x9650 # 0 +0x0000CFDF 0x7EBF # 0 +0x0000CFE0 0x76F8 # 0 +0x0000CFE1 0x53A2 # 0 +0x0000CFE2 0x9576 # 0 +0x0000CFE3 0x9999 # 0 +0x0000CFE4 0x7BB1 # 0 +0x0000CFE5 0x8944 # 0 +0x0000CFE6 0x6E58 # 0 +0x0000CFE7 0x4E61 # 0 +0x0000CFE8 0x7FD4 # 0 +0x0000CFE9 0x7965 # 0 +0x0000CFEA 0x8BE6 # 0 +0x0000CFEB 0x60F3 # 0 +0x0000CFEC 0x54CD # 0 +0x0000CFED 0x4EAB # 0 +0x0000CFEE 0x9879 # 0 +0x0000CFEF 0x5DF7 # 0 +0x0000CFF0 0x6A61 # 0 +0x0000CFF1 0x50CF # 0 +0x0000CFF2 0x5411 # 0 +0x0000CFF3 0x8C61 # 0 +0x0000CFF4 0x8427 # 0 +0x0000CFF5 0x785D # 0 +0x0000CFF6 0x9704 # 0 +0x0000CFF7 0x524A # 0 +0x0000CFF8 0x54EE # 0 +0x0000CFF9 0x56A3 # 0 +0x0000CFFA 0x9500 # 0 +0x0000CFFB 0x6D88 # 0 +0x0000CFFC 0x5BB5 # 0 +0x0000CFFD 0x6DC6 # 0 +0x0000CFFE 0x6653 # 0 +0x0000D0A1 0x5C0F # 0 +0x0000D0A2 0x5B5D # 0 +0x0000D0A3 0x6821 # 0 +0x0000D0A4 0x8096 # 0 +0x0000D0A5 0x5578 # 0 +0x0000D0A6 0x7B11 # 0 +0x0000D0A7 0x6548 # 0 +0x0000D0A8 0x6954 # 0 +0x0000D0A9 0x4E9B # 0 +0x0000D0AA 0x6B47 # 0 +0x0000D0AB 0x874E # 0 +0x0000D0AC 0x978B # 0 +0x0000D0AD 0x534F # 0 +0x0000D0AE 0x631F # 0 +0x0000D0AF 0x643A # 0 +0x0000D0B0 0x90AA # 0 +0x0000D0B1 0x659C # 0 +0x0000D0B2 0x80C1 # 0 +0x0000D0B3 0x8C10 # 0 +0x0000D0B4 0x5199 # 0 +0x0000D0B5 0x68B0 # 0 +0x0000D0B6 0x5378 # 0 +0x0000D0B7 0x87F9 # 0 +0x0000D0B8 0x61C8 # 0 +0x0000D0B9 0x6CC4 # 0 +0x0000D0BA 0x6CFB # 0 +0x0000D0BB 0x8C22 # 0 +0x0000D0BC 0x5C51 # 0 +0x0000D0BD 0x85AA # 0 +0x0000D0BE 0x82AF # 0 +0x0000D0BF 0x950C # 0 +0x0000D0C0 0x6B23 # 0 +0x0000D0C1 0x8F9B # 0 +0x0000D0C2 0x65B0 # 0 +0x0000D0C3 0x5FFB # 0 +0x0000D0C4 0x5FC3 # 0 +0x0000D0C5 0x4FE1 # 0 +0x0000D0C6 0x8845 # 0 +0x0000D0C7 0x661F # 0 +0x0000D0C8 0x8165 # 0 +0x0000D0C9 0x7329 # 0 +0x0000D0CA 0x60FA # 0 +0x0000D0CB 0x5174 # 0 +0x0000D0CC 0x5211 # 0 +0x0000D0CD 0x578B # 0 +0x0000D0CE 0x5F62 # 0 +0x0000D0CF 0x90A2 # 0 +0x0000D0D0 0x884C # 0 +0x0000D0D1 0x9192 # 0 +0x0000D0D2 0x5E78 # 0 +0x0000D0D3 0x674F # 0 +0x0000D0D4 0x6027 # 0 +0x0000D0D5 0x59D3 # 0 +0x0000D0D6 0x5144 # 0 +0x0000D0D7 0x51F6 # 0 +0x0000D0D8 0x80F8 # 0 +0x0000D0D9 0x5308 # 0 +0x0000D0DA 0x6C79 # 0 +0x0000D0DB 0x96C4 # 0 +0x0000D0DC 0x718A # 0 +0x0000D0DD 0x4F11 # 0 +0x0000D0DE 0x4FEE # 0 +0x0000D0DF 0x7F9E # 0 +0x0000D0E0 0x673D # 0 +0x0000D0E1 0x55C5 # 0 +0x0000D0E2 0x9508 # 0 +0x0000D0E3 0x79C0 # 0 +0x0000D0E4 0x8896 # 0 +0x0000D0E5 0x7EE3 # 0 +0x0000D0E6 0x589F # 0 +0x0000D0E7 0x620C # 0 +0x0000D0E8 0x9700 # 0 +0x0000D0E9 0x865A # 0 +0x0000D0EA 0x5618 # 0 +0x0000D0EB 0x987B # 0 +0x0000D0EC 0x5F90 # 0 +0x0000D0ED 0x8BB8 # 0 +0x0000D0EE 0x84C4 # 0 +0x0000D0EF 0x9157 # 0 +0x0000D0F0 0x53D9 # 0 +0x0000D0F1 0x65ED # 0 +0x0000D0F2 0x5E8F # 0 +0x0000D0F3 0x755C # 0 +0x0000D0F4 0x6064 # 0 +0x0000D0F5 0x7D6E # 0 +0x0000D0F6 0x5A7F # 0 +0x0000D0F7 0x7EEA # 0 +0x0000D0F8 0x7EED # 0 +0x0000D0F9 0x8F69 # 0 +0x0000D0FA 0x55A7 # 0 +0x0000D0FB 0x5BA3 # 0 +0x0000D0FC 0x60AC # 0 +0x0000D0FD 0x65CB # 0 +0x0000D0FE 0x7384 # 0 +0x0000D1A1 0x9009 # 0 +0x0000D1A2 0x7663 # 0 +0x0000D1A3 0x7729 # 0 +0x0000D1A4 0x7EDA # 0 +0x0000D1A5 0x9774 # 0 +0x0000D1A6 0x859B # 0 +0x0000D1A7 0x5B66 # 0 +0x0000D1A8 0x7A74 # 0 +0x0000D1A9 0x96EA # 0 +0x0000D1AA 0x8840 # 0 +0x0000D1AB 0x52CB # 0 +0x0000D1AC 0x718F # 0 +0x0000D1AD 0x5FAA # 0 +0x0000D1AE 0x65EC # 0 +0x0000D1AF 0x8BE2 # 0 +0x0000D1B0 0x5BFB # 0 +0x0000D1B1 0x9A6F # 0 +0x0000D1B2 0x5DE1 # 0 +0x0000D1B3 0x6B89 # 0 +0x0000D1B4 0x6C5B # 0 +0x0000D1B5 0x8BAD # 0 +0x0000D1B6 0x8BAF # 0 +0x0000D1B7 0x900A # 0 +0x0000D1B8 0x8FC5 # 0 +0x0000D1B9 0x538B # 0 +0x0000D1BA 0x62BC # 0 +0x0000D1BB 0x9E26 # 0 +0x0000D1BC 0x9E2D # 0 +0x0000D1BD 0x5440 # 0 +0x0000D1BE 0x4E2B # 0 +0x0000D1BF 0x82BD # 0 +0x0000D1C0 0x7259 # 0 +0x0000D1C1 0x869C # 0 +0x0000D1C2 0x5D16 # 0 +0x0000D1C3 0x8859 # 0 +0x0000D1C4 0x6DAF # 0 +0x0000D1C5 0x96C5 # 0 +0x0000D1C6 0x54D1 # 0 +0x0000D1C7 0x4E9A # 0 +0x0000D1C8 0x8BB6 # 0 +0x0000D1C9 0x7109 # 0 +0x0000D1CA 0x54BD # 0 +0x0000D1CB 0x9609 # 0 +0x0000D1CC 0x70DF # 0 +0x0000D1CD 0x6DF9 # 0 +0x0000D1CE 0x76D0 # 0 +0x0000D1CF 0x4E25 # 0 +0x0000D1D0 0x7814 # 0 +0x0000D1D1 0x8712 # 0 +0x0000D1D2 0x5CA9 # 0 +0x0000D1D3 0x5EF6 # 0 +0x0000D1D4 0x8A00 # 0 +0x0000D1D5 0x989C # 0 +0x0000D1D6 0x960E # 0 +0x0000D1D7 0x708E # 0 +0x0000D1D8 0x6CBF # 0 +0x0000D1D9 0x5944 # 0 +0x0000D1DA 0x63A9 # 0 +0x0000D1DB 0x773C # 0 +0x0000D1DC 0x884D # 0 +0x0000D1DD 0x6F14 # 0 +0x0000D1DE 0x8273 # 0 +0x0000D1DF 0x5830 # 0 +0x0000D1E0 0x71D5 # 0 +0x0000D1E1 0x538C # 0 +0x0000D1E2 0x781A # 0 +0x0000D1E3 0x96C1 # 0 +0x0000D1E4 0x5501 # 0 +0x0000D1E5 0x5F66 # 0 +0x0000D1E6 0x7130 # 0 +0x0000D1E7 0x5BB4 # 0 +0x0000D1E8 0x8C1A # 0 +0x0000D1E9 0x9A8C # 0 +0x0000D1EA 0x6B83 # 0 +0x0000D1EB 0x592E # 0 +0x0000D1EC 0x9E2F # 0 +0x0000D1ED 0x79E7 # 0 +0x0000D1EE 0x6768 # 0 +0x0000D1EF 0x626C # 0 +0x0000D1F0 0x4F6F # 0 +0x0000D1F1 0x75A1 # 0 +0x0000D1F2 0x7F8A # 0 +0x0000D1F3 0x6D0B # 0 +0x0000D1F4 0x9633 # 0 +0x0000D1F5 0x6C27 # 0 +0x0000D1F6 0x4EF0 # 0 +0x0000D1F7 0x75D2 # 0 +0x0000D1F8 0x517B # 0 +0x0000D1F9 0x6837 # 0 +0x0000D1FA 0x6F3E # 0 +0x0000D1FB 0x9080 # 0 +0x0000D1FC 0x8170 # 0 +0x0000D1FD 0x5996 # 0 +0x0000D1FE 0x7476 # 0 +0x0000D2A1 0x6447 # 0 +0x0000D2A2 0x5C27 # 0 +0x0000D2A3 0x9065 # 0 +0x0000D2A4 0x7A91 # 0 +0x0000D2A5 0x8C23 # 0 +0x0000D2A6 0x59DA # 0 +0x0000D2A7 0x54AC # 0 +0x0000D2A8 0x8200 # 0 +0x0000D2A9 0x836F # 0 +0x0000D2AA 0x8981 # 0 +0x0000D2AB 0x8000 # 0 +0x0000D2AC 0x6930 # 0 +0x0000D2AD 0x564E # 0 +0x0000D2AE 0x8036 # 0 +0x0000D2AF 0x7237 # 0 +0x0000D2B0 0x91CE # 0 +0x0000D2B1 0x51B6 # 0 +0x0000D2B2 0x4E5F # 0 +0x0000D2B3 0x9875 # 0 +0x0000D2B4 0x6396 # 0 +0x0000D2B5 0x4E1A # 0 +0x0000D2B6 0x53F6 # 0 +0x0000D2B7 0x66F3 # 0 +0x0000D2B8 0x814B # 0 +0x0000D2B9 0x591C # 0 +0x0000D2BA 0x6DB2 # 0 +0x0000D2BB 0x4E00 # 0 +0x0000D2BC 0x58F9 # 0 +0x0000D2BD 0x533B # 0 +0x0000D2BE 0x63D6 # 0 +0x0000D2BF 0x94F1 # 0 +0x0000D2C0 0x4F9D # 0 +0x0000D2C1 0x4F0A # 0 +0x0000D2C2 0x8863 # 0 +0x0000D2C3 0x9890 # 0 +0x0000D2C4 0x5937 # 0 +0x0000D2C5 0x9057 # 0 +0x0000D2C6 0x79FB # 0 +0x0000D2C7 0x4EEA # 0 +0x0000D2C8 0x80F0 # 0 +0x0000D2C9 0x7591 # 0 +0x0000D2CA 0x6C82 # 0 +0x0000D2CB 0x5B9C # 0 +0x0000D2CC 0x59E8 # 0 +0x0000D2CD 0x5F5D # 0 +0x0000D2CE 0x6905 # 0 +0x0000D2CF 0x8681 # 0 +0x0000D2D0 0x501A # 0 +0x0000D2D1 0x5DF2 # 0 +0x0000D2D2 0x4E59 # 0 +0x0000D2D3 0x77E3 # 0 +0x0000D2D4 0x4EE5 # 0 +0x0000D2D5 0x827A # 0 +0x0000D2D6 0x6291 # 0 +0x0000D2D7 0x6613 # 0 +0x0000D2D8 0x9091 # 0 +0x0000D2D9 0x5C79 # 0 +0x0000D2DA 0x4EBF # 0 +0x0000D2DB 0x5F79 # 0 +0x0000D2DC 0x81C6 # 0 +0x0000D2DD 0x9038 # 0 +0x0000D2DE 0x8084 # 0 +0x0000D2DF 0x75AB # 0 +0x0000D2E0 0x4EA6 # 0 +0x0000D2E1 0x88D4 # 0 +0x0000D2E2 0x610F # 0 +0x0000D2E3 0x6BC5 # 0 +0x0000D2E4 0x5FC6 # 0 +0x0000D2E5 0x4E49 # 0 +0x0000D2E6 0x76CA # 0 +0x0000D2E7 0x6EA2 # 0 +0x0000D2E8 0x8BE3 # 0 +0x0000D2E9 0x8BAE # 0 +0x0000D2EA 0x8C0A # 0 +0x0000D2EB 0x8BD1 # 0 +0x0000D2EC 0x5F02 # 0 +0x0000D2ED 0x7FFC # 0 +0x0000D2EE 0x7FCC # 0 +0x0000D2EF 0x7ECE # 0 +0x0000D2F0 0x8335 # 0 +0x0000D2F1 0x836B # 0 +0x0000D2F2 0x56E0 # 0 +0x0000D2F3 0x6BB7 # 0 +0x0000D2F4 0x97F3 # 0 +0x0000D2F5 0x9634 # 0 +0x0000D2F6 0x59FB # 0 +0x0000D2F7 0x541F # 0 +0x0000D2F8 0x94F6 # 0 +0x0000D2F9 0x6DEB # 0 +0x0000D2FA 0x5BC5 # 0 +0x0000D2FB 0x996E # 0 +0x0000D2FC 0x5C39 # 0 +0x0000D2FD 0x5F15 # 0 +0x0000D2FE 0x9690 # 0 +0x0000D3A1 0x5370 # 0 +0x0000D3A2 0x82F1 # 0 +0x0000D3A3 0x6A31 # 0 +0x0000D3A4 0x5A74 # 0 +0x0000D3A5 0x9E70 # 0 +0x0000D3A6 0x5E94 # 0 +0x0000D3A7 0x7F28 # 0 +0x0000D3A8 0x83B9 # 0 +0x0000D3A9 0x8424 # 0 +0x0000D3AA 0x8425 # 0 +0x0000D3AB 0x8367 # 0 +0x0000D3AC 0x8747 # 0 +0x0000D3AD 0x8FCE # 0 +0x0000D3AE 0x8D62 # 0 +0x0000D3AF 0x76C8 # 0 +0x0000D3B0 0x5F71 # 0 +0x0000D3B1 0x9896 # 0 +0x0000D3B2 0x786C # 0 +0x0000D3B3 0x6620 # 0 +0x0000D3B4 0x54DF # 0 +0x0000D3B5 0x62E5 # 0 +0x0000D3B6 0x4F63 # 0 +0x0000D3B7 0x81C3 # 0 +0x0000D3B8 0x75C8 # 0 +0x0000D3B9 0x5EB8 # 0 +0x0000D3BA 0x96CD # 0 +0x0000D3BB 0x8E0A # 0 +0x0000D3BC 0x86F9 # 0 +0x0000D3BD 0x548F # 0 +0x0000D3BE 0x6CF3 # 0 +0x0000D3BF 0x6D8C # 0 +0x0000D3C0 0x6C38 # 0 +0x0000D3C1 0x607F # 0 +0x0000D3C2 0x52C7 # 0 +0x0000D3C3 0x7528 # 0 +0x0000D3C4 0x5E7D # 0 +0x0000D3C5 0x4F18 # 0 +0x0000D3C6 0x60A0 # 0 +0x0000D3C7 0x5FE7 # 0 +0x0000D3C8 0x5C24 # 0 +0x0000D3C9 0x7531 # 0 +0x0000D3CA 0x90AE # 0 +0x0000D3CB 0x94C0 # 0 +0x0000D3CC 0x72B9 # 0 +0x0000D3CD 0x6CB9 # 0 +0x0000D3CE 0x6E38 # 0 +0x0000D3CF 0x9149 # 0 +0x0000D3D0 0x6709 # 0 +0x0000D3D1 0x53CB # 0 +0x0000D3D2 0x53F3 # 0 +0x0000D3D3 0x4F51 # 0 +0x0000D3D4 0x91C9 # 0 +0x0000D3D5 0x8BF1 # 0 +0x0000D3D6 0x53C8 # 0 +0x0000D3D7 0x5E7C # 0 +0x0000D3D8 0x8FC2 # 0 +0x0000D3D9 0x6DE4 # 0 +0x0000D3DA 0x4E8E # 0 +0x0000D3DB 0x76C2 # 0 +0x0000D3DC 0x6986 # 0 +0x0000D3DD 0x865E # 0 +0x0000D3DE 0x611A # 0 +0x0000D3DF 0x8206 # 0 +0x0000D3E0 0x4F59 # 0 +0x0000D3E1 0x4FDE # 0 +0x0000D3E2 0x903E # 0 +0x0000D3E3 0x9C7C # 0 +0x0000D3E4 0x6109 # 0 +0x0000D3E5 0x6E1D # 0 +0x0000D3E6 0x6E14 # 0 +0x0000D3E7 0x9685 # 0 +0x0000D3E8 0x4E88 # 0 +0x0000D3E9 0x5A31 # 0 +0x0000D3EA 0x96E8 # 0 +0x0000D3EB 0x4E0E # 0 +0x0000D3EC 0x5C7F # 0 +0x0000D3ED 0x79B9 # 0 +0x0000D3EE 0x5B87 # 0 +0x0000D3EF 0x8BED # 0 +0x0000D3F0 0x7FBD # 0 +0x0000D3F1 0x7389 # 0 +0x0000D3F2 0x57DF # 0 +0x0000D3F3 0x828B # 0 +0x0000D3F4 0x90C1 # 0 +0x0000D3F5 0x5401 # 0 +0x0000D3F6 0x9047 # 0 +0x0000D3F7 0x55BB # 0 +0x0000D3F8 0x5CEA # 0 +0x0000D3F9 0x5FA1 # 0 +0x0000D3FA 0x6108 # 0 +0x0000D3FB 0x6B32 # 0 +0x0000D3FC 0x72F1 # 0 +0x0000D3FD 0x80B2 # 0 +0x0000D3FE 0x8A89 # 0 +0x0000D4A1 0x6D74 # 0 +0x0000D4A2 0x5BD3 # 0 +0x0000D4A3 0x88D5 # 0 +0x0000D4A4 0x9884 # 0 +0x0000D4A5 0x8C6B # 0 +0x0000D4A6 0x9A6D # 0 +0x0000D4A7 0x9E33 # 0 +0x0000D4A8 0x6E0A # 0 +0x0000D4A9 0x51A4 # 0 +0x0000D4AA 0x5143 # 0 +0x0000D4AB 0x57A3 # 0 +0x0000D4AC 0x8881 # 0 +0x0000D4AD 0x539F # 0 +0x0000D4AE 0x63F4 # 0 +0x0000D4AF 0x8F95 # 0 +0x0000D4B0 0x56ED # 0 +0x0000D4B1 0x5458 # 0 +0x0000D4B2 0x5706 # 0 +0x0000D4B3 0x733F # 0 +0x0000D4B4 0x6E90 # 0 +0x0000D4B5 0x7F18 # 0 +0x0000D4B6 0x8FDC # 0 +0x0000D4B7 0x82D1 # 0 +0x0000D4B8 0x613F # 0 +0x0000D4B9 0x6028 # 0 +0x0000D4BA 0x9662 # 0 +0x0000D4BB 0x66F0 # 0 +0x0000D4BC 0x7EA6 # 0 +0x0000D4BD 0x8D8A # 0 +0x0000D4BE 0x8DC3 # 0 +0x0000D4BF 0x94A5 # 0 +0x0000D4C0 0x5CB3 # 0 +0x0000D4C1 0x7CA4 # 0 +0x0000D4C2 0x6708 # 0 +0x0000D4C3 0x60A6 # 0 +0x0000D4C4 0x9605 # 0 +0x0000D4C5 0x8018 # 0 +0x0000D4C6 0x4E91 # 0 +0x0000D4C7 0x90E7 # 0 +0x0000D4C8 0x5300 # 0 +0x0000D4C9 0x9668 # 0 +0x0000D4CA 0x5141 # 0 +0x0000D4CB 0x8FD0 # 0 +0x0000D4CC 0x8574 # 0 +0x0000D4CD 0x915D # 0 +0x0000D4CE 0x6655 # 0 +0x0000D4CF 0x97F5 # 0 +0x0000D4D0 0x5B55 # 0 +0x0000D4D1 0x531D # 0 +0x0000D4D2 0x7838 # 0 +0x0000D4D3 0x6742 # 0 +0x0000D4D4 0x683D # 0 +0x0000D4D5 0x54C9 # 0 +0x0000D4D6 0x707E # 0 +0x0000D4D7 0x5BB0 # 0 +0x0000D4D8 0x8F7D # 0 +0x0000D4D9 0x518D # 0 +0x0000D4DA 0x5728 # 0 +0x0000D4DB 0x54B1 # 0 +0x0000D4DC 0x6512 # 0 +0x0000D4DD 0x6682 # 0 +0x0000D4DE 0x8D5E # 0 +0x0000D4DF 0x8D43 # 0 +0x0000D4E0 0x810F # 0 +0x0000D4E1 0x846C # 0 +0x0000D4E2 0x906D # 0 +0x0000D4E3 0x7CDF # 0 +0x0000D4E4 0x51FF # 0 +0x0000D4E5 0x85FB # 0 +0x0000D4E6 0x67A3 # 0 +0x0000D4E7 0x65E9 # 0 +0x0000D4E8 0x6FA1 # 0 +0x0000D4E9 0x86A4 # 0 +0x0000D4EA 0x8E81 # 0 +0x0000D4EB 0x566A # 0 +0x0000D4EC 0x9020 # 0 +0x0000D4ED 0x7682 # 0 +0x0000D4EE 0x7076 # 0 +0x0000D4EF 0x71E5 # 0 +0x0000D4F0 0x8D23 # 0 +0x0000D4F1 0x62E9 # 0 +0x0000D4F2 0x5219 # 0 +0x0000D4F3 0x6CFD # 0 +0x0000D4F4 0x8D3C # 0 +0x0000D4F5 0x600E # 0 +0x0000D4F6 0x589E # 0 +0x0000D4F7 0x618E # 0 +0x0000D4F8 0x66FE # 0 +0x0000D4F9 0x8D60 # 0 +0x0000D4FA 0x624E # 0 +0x0000D4FB 0x55B3 # 0 +0x0000D4FC 0x6E23 # 0 +0x0000D4FD 0x672D # 0 +0x0000D4FE 0x8F67 # 0 +0x0000D5A1 0x94E1 # 0 +0x0000D5A2 0x95F8 # 0 +0x0000D5A3 0x7728 # 0 +0x0000D5A4 0x6805 # 0 +0x0000D5A5 0x69A8 # 0 +0x0000D5A6 0x548B # 0 +0x0000D5A7 0x4E4D # 0 +0x0000D5A8 0x70B8 # 0 +0x0000D5A9 0x8BC8 # 0 +0x0000D5AA 0x6458 # 0 +0x0000D5AB 0x658B # 0 +0x0000D5AC 0x5B85 # 0 +0x0000D5AD 0x7A84 # 0 +0x0000D5AE 0x503A # 0 +0x0000D5AF 0x5BE8 # 0 +0x0000D5B0 0x77BB # 0 +0x0000D5B1 0x6BE1 # 0 +0x0000D5B2 0x8A79 # 0 +0x0000D5B3 0x7C98 # 0 +0x0000D5B4 0x6CBE # 0 +0x0000D5B5 0x76CF # 0 +0x0000D5B6 0x65A9 # 0 +0x0000D5B7 0x8F97 # 0 +0x0000D5B8 0x5D2D # 0 +0x0000D5B9 0x5C55 # 0 +0x0000D5BA 0x8638 # 0 +0x0000D5BB 0x6808 # 0 +0x0000D5BC 0x5360 # 0 +0x0000D5BD 0x6218 # 0 +0x0000D5BE 0x7AD9 # 0 +0x0000D5BF 0x6E5B # 0 +0x0000D5C0 0x7EFD # 0 +0x0000D5C1 0x6A1F # 0 +0x0000D5C2 0x7AE0 # 0 +0x0000D5C3 0x5F70 # 0 +0x0000D5C4 0x6F33 # 0 +0x0000D5C5 0x5F20 # 0 +0x0000D5C6 0x638C # 0 +0x0000D5C7 0x6DA8 # 0 +0x0000D5C8 0x6756 # 0 +0x0000D5C9 0x4E08 # 0 +0x0000D5CA 0x5E10 # 0 +0x0000D5CB 0x8D26 # 0 +0x0000D5CC 0x4ED7 # 0 +0x0000D5CD 0x80C0 # 0 +0x0000D5CE 0x7634 # 0 +0x0000D5CF 0x969C # 0 +0x0000D5D0 0x62DB # 0 +0x0000D5D1 0x662D # 0 +0x0000D5D2 0x627E # 0 +0x0000D5D3 0x6CBC # 0 +0x0000D5D4 0x8D75 # 0 +0x0000D5D5 0x7167 # 0 +0x0000D5D6 0x7F69 # 0 +0x0000D5D7 0x5146 # 0 +0x0000D5D8 0x8087 # 0 +0x0000D5D9 0x53EC # 0 +0x0000D5DA 0x906E # 0 +0x0000D5DB 0x6298 # 0 +0x0000D5DC 0x54F2 # 0 +0x0000D5DD 0x86F0 # 0 +0x0000D5DE 0x8F99 # 0 +0x0000D5DF 0x8005 # 0 +0x0000D5E0 0x9517 # 0 +0x0000D5E1 0x8517 # 0 +0x0000D5E2 0x8FD9 # 0 +0x0000D5E3 0x6D59 # 0 +0x0000D5E4 0x73CD # 0 +0x0000D5E5 0x659F # 0 +0x0000D5E6 0x771F # 0 +0x0000D5E7 0x7504 # 0 +0x0000D5E8 0x7827 # 0 +0x0000D5E9 0x81FB # 0 +0x0000D5EA 0x8D1E # 0 +0x0000D5EB 0x9488 # 0 +0x0000D5EC 0x4FA6 # 0 +0x0000D5ED 0x6795 # 0 +0x0000D5EE 0x75B9 # 0 +0x0000D5EF 0x8BCA # 0 +0x0000D5F0 0x9707 # 0 +0x0000D5F1 0x632F # 0 +0x0000D5F2 0x9547 # 0 +0x0000D5F3 0x9635 # 0 +0x0000D5F4 0x84B8 # 0 +0x0000D5F5 0x6323 # 0 +0x0000D5F6 0x7741 # 0 +0x0000D5F7 0x5F81 # 0 +0x0000D5F8 0x72F0 # 0 +0x0000D5F9 0x4E89 # 0 +0x0000D5FA 0x6014 # 0 +0x0000D5FB 0x6574 # 0 +0x0000D5FC 0x62EF # 0 +0x0000D5FD 0x6B63 # 0 +0x0000D5FE 0x653F # 0 +0x0000D6A1 0x5E27 # 0 +0x0000D6A2 0x75C7 # 0 +0x0000D6A3 0x90D1 # 0 +0x0000D6A4 0x8BC1 # 0 +0x0000D6A5 0x829D # 0 +0x0000D6A6 0x679D # 0 +0x0000D6A7 0x652F # 0 +0x0000D6A8 0x5431 # 0 +0x0000D6A9 0x8718 # 0 +0x0000D6AA 0x77E5 # 0 +0x0000D6AB 0x80A2 # 0 +0x0000D6AC 0x8102 # 0 +0x0000D6AD 0x6C41 # 0 +0x0000D6AE 0x4E4B # 0 +0x0000D6AF 0x7EC7 # 0 +0x0000D6B0 0x804C # 0 +0x0000D6B1 0x76F4 # 0 +0x0000D6B2 0x690D # 0 +0x0000D6B3 0x6B96 # 0 +0x0000D6B4 0x6267 # 0 +0x0000D6B5 0x503C # 0 +0x0000D6B6 0x4F84 # 0 +0x0000D6B7 0x5740 # 0 +0x0000D6B8 0x6307 # 0 +0x0000D6B9 0x6B62 # 0 +0x0000D6BA 0x8DBE # 0 +0x0000D6BB 0x53EA # 0 +0x0000D6BC 0x65E8 # 0 +0x0000D6BD 0x7EB8 # 0 +0x0000D6BE 0x5FD7 # 0 +0x0000D6BF 0x631A # 0 +0x0000D6C0 0x63B7 # 0 +0x0000D6C1 0x81F3 # 0 +0x0000D6C2 0x81F4 # 0 +0x0000D6C3 0x7F6E # 0 +0x0000D6C4 0x5E1C # 0 +0x0000D6C5 0x5CD9 # 0 +0x0000D6C6 0x5236 # 0 +0x0000D6C7 0x667A # 0 +0x0000D6C8 0x79E9 # 0 +0x0000D6C9 0x7A1A # 0 +0x0000D6CA 0x8D28 # 0 +0x0000D6CB 0x7099 # 0 +0x0000D6CC 0x75D4 # 0 +0x0000D6CD 0x6EDE # 0 +0x0000D6CE 0x6CBB # 0 +0x0000D6CF 0x7A92 # 0 +0x0000D6D0 0x4E2D # 0 +0x0000D6D1 0x76C5 # 0 +0x0000D6D2 0x5FE0 # 0 +0x0000D6D3 0x949F # 0 +0x0000D6D4 0x8877 # 0 +0x0000D6D5 0x7EC8 # 0 +0x0000D6D6 0x79CD # 0 +0x0000D6D7 0x80BF # 0 +0x0000D6D8 0x91CD # 0 +0x0000D6D9 0x4EF2 # 0 +0x0000D6DA 0x4F17 # 0 +0x0000D6DB 0x821F # 0 +0x0000D6DC 0x5468 # 0 +0x0000D6DD 0x5DDE # 0 +0x0000D6DE 0x6D32 # 0 +0x0000D6DF 0x8BCC # 0 +0x0000D6E0 0x7CA5 # 0 +0x0000D6E1 0x8F74 # 0 +0x0000D6E2 0x8098 # 0 +0x0000D6E3 0x5E1A # 0 +0x0000D6E4 0x5492 # 0 +0x0000D6E5 0x76B1 # 0 +0x0000D6E6 0x5B99 # 0 +0x0000D6E7 0x663C # 0 +0x0000D6E8 0x9AA4 # 0 +0x0000D6E9 0x73E0 # 0 +0x0000D6EA 0x682A # 0 +0x0000D6EB 0x86DB # 0 +0x0000D6EC 0x6731 # 0 +0x0000D6ED 0x732A # 0 +0x0000D6EE 0x8BF8 # 0 +0x0000D6EF 0x8BDB # 0 +0x0000D6F0 0x9010 # 0 +0x0000D6F1 0x7AF9 # 0 +0x0000D6F2 0x70DB # 0 +0x0000D6F3 0x716E # 0 +0x0000D6F4 0x62C4 # 0 +0x0000D6F5 0x77A9 # 0 +0x0000D6F6 0x5631 # 0 +0x0000D6F7 0x4E3B # 0 +0x0000D6F8 0x8457 # 0 +0x0000D6F9 0x67F1 # 0 +0x0000D6FA 0x52A9 # 0 +0x0000D6FB 0x86C0 # 0 +0x0000D6FC 0x8D2E # 0 +0x0000D6FD 0x94F8 # 0 +0x0000D6FE 0x7B51 # 0 +0x0000D7A1 0x4F4F # 0 +0x0000D7A2 0x6CE8 # 0 +0x0000D7A3 0x795D # 0 +0x0000D7A4 0x9A7B # 0 +0x0000D7A5 0x6293 # 0 +0x0000D7A6 0x722A # 0 +0x0000D7A7 0x62FD # 0 +0x0000D7A8 0x4E13 # 0 +0x0000D7A9 0x7816 # 0 +0x0000D7AA 0x8F6C # 0 +0x0000D7AB 0x64B0 # 0 +0x0000D7AC 0x8D5A # 0 +0x0000D7AD 0x7BC6 # 0 +0x0000D7AE 0x6869 # 0 +0x0000D7AF 0x5E84 # 0 +0x0000D7B0 0x88C5 # 0 +0x0000D7B1 0x5986 # 0 +0x0000D7B2 0x649E # 0 +0x0000D7B3 0x58EE # 0 +0x0000D7B4 0x72B6 # 0 +0x0000D7B5 0x690E # 0 +0x0000D7B6 0x9525 # 0 +0x0000D7B7 0x8FFD # 0 +0x0000D7B8 0x8D58 # 0 +0x0000D7B9 0x5760 # 0 +0x0000D7BA 0x7F00 # 0 +0x0000D7BB 0x8C06 # 0 +0x0000D7BC 0x51C6 # 0 +0x0000D7BD 0x6349 # 0 +0x0000D7BE 0x62D9 # 0 +0x0000D7BF 0x5353 # 0 +0x0000D7C0 0x684C # 0 +0x0000D7C1 0x7422 # 0 +0x0000D7C2 0x8301 # 0 +0x0000D7C3 0x914C # 0 +0x0000D7C4 0x5544 # 0 +0x0000D7C5 0x7740 # 0 +0x0000D7C6 0x707C # 0 +0x0000D7C7 0x6D4A # 0 +0x0000D7C8 0x5179 # 0 +0x0000D7C9 0x54A8 # 0 +0x0000D7CA 0x8D44 # 0 +0x0000D7CB 0x59FF # 0 +0x0000D7CC 0x6ECB # 0 +0x0000D7CD 0x6DC4 # 0 +0x0000D7CE 0x5B5C # 0 +0x0000D7CF 0x7D2B # 0 +0x0000D7D0 0x4ED4 # 0 +0x0000D7D1 0x7C7D # 0 +0x0000D7D2 0x6ED3 # 0 +0x0000D7D3 0x5B50 # 0 +0x0000D7D4 0x81EA # 0 +0x0000D7D5 0x6E0D # 0 +0x0000D7D6 0x5B57 # 0 +0x0000D7D7 0x9B03 # 0 +0x0000D7D8 0x68D5 # 0 +0x0000D7D9 0x8E2A # 0 +0x0000D7DA 0x5B97 # 0 +0x0000D7DB 0x7EFC # 0 +0x0000D7DC 0x603B # 0 +0x0000D7DD 0x7EB5 # 0 +0x0000D7DE 0x90B9 # 0 +0x0000D7DF 0x8D70 # 0 +0x0000D7E0 0x594F # 0 +0x0000D7E1 0x63CD # 0 +0x0000D7E2 0x79DF # 0 +0x0000D7E3 0x8DB3 # 0 +0x0000D7E4 0x5352 # 0 +0x0000D7E5 0x65CF # 0 +0x0000D7E6 0x7956 # 0 +0x0000D7E7 0x8BC5 # 0 +0x0000D7E8 0x963B # 0 +0x0000D7E9 0x7EC4 # 0 +0x0000D7EA 0x94BB # 0 +0x0000D7EB 0x7E82 # 0 +0x0000D7EC 0x5634 # 0 +0x0000D7ED 0x9189 # 0 +0x0000D7EE 0x6700 # 0 +0x0000D7EF 0x7F6A # 0 +0x0000D7F0 0x5C0A # 0 +0x0000D7F1 0x9075 # 0 +0x0000D7F2 0x6628 # 0 +0x0000D7F3 0x5DE6 # 0 +0x0000D7F4 0x4F50 # 0 +0x0000D7F5 0x67DE # 0 +0x0000D7F6 0x505A # 0 +0x0000D7F7 0x4F5C # 0 +0x0000D7F8 0x5750 # 0 +0x0000D7F9 0x5EA7 # 0 +0x0000D8A1 0x4E8D # 0 +0x0000D8A2 0x4E0C # 0 +0x0000D8A3 0x5140 # 0 +0x0000D8A4 0x4E10 # 0 +0x0000D8A5 0x5EFF # 0 +0x0000D8A6 0x5345 # 0 +0x0000D8A7 0x4E15 # 0 +0x0000D8A8 0x4E98 # 0 +0x0000D8A9 0x4E1E # 0 +0x0000D8AA 0x9B32 # 0 +0x0000D8AB 0x5B6C # 0 +0x0000D8AC 0x5669 # 0 +0x0000D8AD 0x4E28 # 0 +0x0000D8AE 0x79BA # 0 +0x0000D8AF 0x4E3F # 0 +0x0000D8B0 0x5315 # 0 +0x0000D8B1 0x4E47 # 0 +0x0000D8B2 0x592D # 0 +0x0000D8B3 0x723B # 0 +0x0000D8B4 0x536E # 0 +0x0000D8B5 0x6C10 # 0 +0x0000D8B6 0x56DF # 0 +0x0000D8B7 0x80E4 # 0 +0x0000D8B8 0x9997 # 0 +0x0000D8B9 0x6BD3 # 0 +0x0000D8BA 0x777E # 0 +0x0000D8BB 0x9F17 # 0 +0x0000D8BC 0x4E36 # 0 +0x0000D8BD 0x4E9F # 0 +0x0000D8BE 0x9F10 # 0 +0x0000D8BF 0x4E5C # 0 +0x0000D8C0 0x4E69 # 0 +0x0000D8C1 0x4E93 # 0 +0x0000D8C2 0x8288 # 0 +0x0000D8C3 0x5B5B # 0 +0x0000D8C4 0x556C # 0 +0x0000D8C5 0x560F # 0 +0x0000D8C6 0x4EC4 # 0 +0x0000D8C7 0x538D # 0 +0x0000D8C8 0x539D # 0 +0x0000D8C9 0x53A3 # 0 +0x0000D8CA 0x53A5 # 0 +0x0000D8CB 0x53AE # 0 +0x0000D8CC 0x9765 # 0 +0x0000D8CD 0x8D5D # 0 +0x0000D8CE 0x531A # 0 +0x0000D8CF 0x53F5 # 0 +0x0000D8D0 0x5326 # 0 +0x0000D8D1 0x532E # 0 +0x0000D8D2 0x533E # 0 +0x0000D8D3 0x8D5C # 0 +0x0000D8D4 0x5366 # 0 +0x0000D8D5 0x5363 # 0 +0x0000D8D6 0x5202 # 0 +0x0000D8D7 0x5208 # 0 +0x0000D8D8 0x520E # 0 +0x0000D8D9 0x522D # 0 +0x0000D8DA 0x5233 # 0 +0x0000D8DB 0x523F # 0 +0x0000D8DC 0x5240 # 0 +0x0000D8DD 0x524C # 0 +0x0000D8DE 0x525E # 0 +0x0000D8DF 0x5261 # 0 +0x0000D8E0 0x525C # 0 +0x0000D8E1 0x84AF # 0 +0x0000D8E2 0x527D # 0 +0x0000D8E3 0x5282 # 0 +0x0000D8E4 0x5281 # 0 +0x0000D8E5 0x5290 # 0 +0x0000D8E6 0x5293 # 0 +0x0000D8E7 0x5182 # 0 +0x0000D8E8 0x7F54 # 0 +0x0000D8E9 0x4EBB # 0 +0x0000D8EA 0x4EC3 # 0 +0x0000D8EB 0x4EC9 # 0 +0x0000D8EC 0x4EC2 # 0 +0x0000D8ED 0x4EE8 # 0 +0x0000D8EE 0x4EE1 # 0 +0x0000D8EF 0x4EEB # 0 +0x0000D8F0 0x4EDE # 0 +0x0000D8F1 0x4F1B # 0 +0x0000D8F2 0x4EF3 # 0 +0x0000D8F3 0x4F22 # 0 +0x0000D8F4 0x4F64 # 0 +0x0000D8F5 0x4EF5 # 0 +0x0000D8F6 0x4F25 # 0 +0x0000D8F7 0x4F27 # 0 +0x0000D8F8 0x4F09 # 0 +0x0000D8F9 0x4F2B # 0 +0x0000D8FA 0x4F5E # 0 +0x0000D8FB 0x4F67 # 0 +0x0000D8FC 0x6538 # 0 +0x0000D8FD 0x4F5A # 0 +0x0000D8FE 0x4F5D # 0 +0x0000D9A1 0x4F5F # 0 +0x0000D9A2 0x4F57 # 0 +0x0000D9A3 0x4F32 # 0 +0x0000D9A4 0x4F3D # 0 +0x0000D9A5 0x4F76 # 0 +0x0000D9A6 0x4F74 # 0 +0x0000D9A7 0x4F91 # 0 +0x0000D9A8 0x4F89 # 0 +0x0000D9A9 0x4F83 # 0 +0x0000D9AA 0x4F8F # 0 +0x0000D9AB 0x4F7E # 0 +0x0000D9AC 0x4F7B # 0 +0x0000D9AD 0x4FAA # 0 +0x0000D9AE 0x4F7C # 0 +0x0000D9AF 0x4FAC # 0 +0x0000D9B0 0x4F94 # 0 +0x0000D9B1 0x4FE6 # 0 +0x0000D9B2 0x4FE8 # 0 +0x0000D9B3 0x4FEA # 0 +0x0000D9B4 0x4FC5 # 0 +0x0000D9B5 0x4FDA # 0 +0x0000D9B6 0x4FE3 # 0 +0x0000D9B7 0x4FDC # 0 +0x0000D9B8 0x4FD1 # 0 +0x0000D9B9 0x4FDF # 0 +0x0000D9BA 0x4FF8 # 0 +0x0000D9BB 0x5029 # 0 +0x0000D9BC 0x504C # 0 +0x0000D9BD 0x4FF3 # 0 +0x0000D9BE 0x502C # 0 +0x0000D9BF 0x500F # 0 +0x0000D9C0 0x502E # 0 +0x0000D9C1 0x502D # 0 +0x0000D9C2 0x4FFE # 0 +0x0000D9C3 0x501C # 0 +0x0000D9C4 0x500C # 0 +0x0000D9C5 0x5025 # 0 +0x0000D9C6 0x5028 # 0 +0x0000D9C7 0x507E # 0 +0x0000D9C8 0x5043 # 0 +0x0000D9C9 0x5055 # 0 +0x0000D9CA 0x5048 # 0 +0x0000D9CB 0x504E # 0 +0x0000D9CC 0x506C # 0 +0x0000D9CD 0x507B # 0 +0x0000D9CE 0x50A5 # 0 +0x0000D9CF 0x50A7 # 0 +0x0000D9D0 0x50A9 # 0 +0x0000D9D1 0x50BA # 0 +0x0000D9D2 0x50D6 # 0 +0x0000D9D3 0x5106 # 0 +0x0000D9D4 0x50ED # 0 +0x0000D9D5 0x50EC # 0 +0x0000D9D6 0x50E6 # 0 +0x0000D9D7 0x50EE # 0 +0x0000D9D8 0x5107 # 0 +0x0000D9D9 0x510B # 0 +0x0000D9DA 0x4EDD # 0 +0x0000D9DB 0x6C3D # 0 +0x0000D9DC 0x4F58 # 0 +0x0000D9DD 0x4F65 # 0 +0x0000D9DE 0x4FCE # 0 +0x0000D9DF 0x9FA0 # 0 +0x0000D9E0 0x6C46 # 0 +0x0000D9E1 0x7C74 # 0 +0x0000D9E2 0x516E # 0 +0x0000D9E3 0x5DFD # 0 +0x0000D9E4 0x9EC9 # 0 +0x0000D9E5 0x9998 # 0 +0x0000D9E6 0x5181 # 0 +0x0000D9E7 0x5914 # 0 +0x0000D9E8 0x52F9 # 0 +0x0000D9E9 0x530D # 0 +0x0000D9EA 0x8A07 # 0 +0x0000D9EB 0x5310 # 0 +0x0000D9EC 0x51EB # 0 +0x0000D9ED 0x5919 # 0 +0x0000D9EE 0x5155 # 0 +0x0000D9EF 0x4EA0 # 0 +0x0000D9F0 0x5156 # 0 +0x0000D9F1 0x4EB3 # 0 +0x0000D9F2 0x886E # 0 +0x0000D9F3 0x88A4 # 0 +0x0000D9F4 0x4EB5 # 0 +0x0000D9F5 0x8114 # 0 +0x0000D9F6 0x88D2 # 0 +0x0000D9F7 0x7980 # 0 +0x0000D9F8 0x5B34 # 0 +0x0000D9F9 0x8803 # 0 +0x0000D9FA 0x7FB8 # 0 +0x0000D9FB 0x51AB # 0 +0x0000D9FC 0x51B1 # 0 +0x0000D9FD 0x51BD # 0 +0x0000D9FE 0x51BC # 0 +0x0000DAA1 0x51C7 # 0 +0x0000DAA2 0x5196 # 0 +0x0000DAA3 0x51A2 # 0 +0x0000DAA4 0x51A5 # 0 +0x0000DAA5 0x8BA0 # 0 +0x0000DAA6 0x8BA6 # 0 +0x0000DAA7 0x8BA7 # 0 +0x0000DAA8 0x8BAA # 0 +0x0000DAA9 0x8BB4 # 0 +0x0000DAAA 0x8BB5 # 0 +0x0000DAAB 0x8BB7 # 0 +0x0000DAAC 0x8BC2 # 0 +0x0000DAAD 0x8BC3 # 0 +0x0000DAAE 0x8BCB # 0 +0x0000DAAF 0x8BCF # 0 +0x0000DAB0 0x8BCE # 0 +0x0000DAB1 0x8BD2 # 0 +0x0000DAB2 0x8BD3 # 0 +0x0000DAB3 0x8BD4 # 0 +0x0000DAB4 0x8BD6 # 0 +0x0000DAB5 0x8BD8 # 0 +0x0000DAB6 0x8BD9 # 0 +0x0000DAB7 0x8BDC # 0 +0x0000DAB8 0x8BDF # 0 +0x0000DAB9 0x8BE0 # 0 +0x0000DABA 0x8BE4 # 0 +0x0000DABB 0x8BE8 # 0 +0x0000DABC 0x8BE9 # 0 +0x0000DABD 0x8BEE # 0 +0x0000DABE 0x8BF0 # 0 +0x0000DABF 0x8BF3 # 0 +0x0000DAC0 0x8BF6 # 0 +0x0000DAC1 0x8BF9 # 0 +0x0000DAC2 0x8BFC # 0 +0x0000DAC3 0x8BFF # 0 +0x0000DAC4 0x8C00 # 0 +0x0000DAC5 0x8C02 # 0 +0x0000DAC6 0x8C04 # 0 +0x0000DAC7 0x8C07 # 0 +0x0000DAC8 0x8C0C # 0 +0x0000DAC9 0x8C0F # 0 +0x0000DACA 0x8C11 # 0 +0x0000DACB 0x8C12 # 0 +0x0000DACC 0x8C14 # 0 +0x0000DACD 0x8C15 # 0 +0x0000DACE 0x8C16 # 0 +0x0000DACF 0x8C19 # 0 +0x0000DAD0 0x8C1B # 0 +0x0000DAD1 0x8C18 # 0 +0x0000DAD2 0x8C1D # 0 +0x0000DAD3 0x8C1F # 0 +0x0000DAD4 0x8C20 # 0 +0x0000DAD5 0x8C21 # 0 +0x0000DAD6 0x8C25 # 0 +0x0000DAD7 0x8C27 # 0 +0x0000DAD8 0x8C2A # 0 +0x0000DAD9 0x8C2B # 0 +0x0000DADA 0x8C2E # 0 +0x0000DADB 0x8C2F # 0 +0x0000DADC 0x8C32 # 0 +0x0000DADD 0x8C33 # 0 +0x0000DADE 0x8C35 # 0 +0x0000DADF 0x8C36 # 0 +0x0000DAE0 0x5369 # 0 +0x0000DAE1 0x537A # 0 +0x0000DAE2 0x961D # 0 +0x0000DAE3 0x9622 # 0 +0x0000DAE4 0x9621 # 0 +0x0000DAE5 0x9631 # 0 +0x0000DAE6 0x962A # 0 +0x0000DAE7 0x963D # 0 +0x0000DAE8 0x963C # 0 +0x0000DAE9 0x9642 # 0 +0x0000DAEA 0x9649 # 0 +0x0000DAEB 0x9654 # 0 +0x0000DAEC 0x965F # 0 +0x0000DAED 0x9667 # 0 +0x0000DAEE 0x966C # 0 +0x0000DAEF 0x9672 # 0 +0x0000DAF0 0x9674 # 0 +0x0000DAF1 0x9688 # 0 +0x0000DAF2 0x968D # 0 +0x0000DAF3 0x9697 # 0 +0x0000DAF4 0x96B0 # 0 +0x0000DAF5 0x9097 # 0 +0x0000DAF6 0x909B # 0 +0x0000DAF7 0x909D # 0 +0x0000DAF8 0x9099 # 0 +0x0000DAF9 0x90AC # 0 +0x0000DAFA 0x90A1 # 0 +0x0000DAFB 0x90B4 # 0 +0x0000DAFC 0x90B3 # 0 +0x0000DAFD 0x90B6 # 0 +0x0000DAFE 0x90BA # 0 +0x0000DBA1 0x90B8 # 0 +0x0000DBA2 0x90B0 # 0 +0x0000DBA3 0x90CF # 0 +0x0000DBA4 0x90C5 # 0 +0x0000DBA5 0x90BE # 0 +0x0000DBA6 0x90D0 # 0 +0x0000DBA7 0x90C4 # 0 +0x0000DBA8 0x90C7 # 0 +0x0000DBA9 0x90D3 # 0 +0x0000DBAA 0x90E6 # 0 +0x0000DBAB 0x90E2 # 0 +0x0000DBAC 0x90DC # 0 +0x0000DBAD 0x90D7 # 0 +0x0000DBAE 0x90DB # 0 +0x0000DBAF 0x90EB # 0 +0x0000DBB0 0x90EF # 0 +0x0000DBB1 0x90FE # 0 +0x0000DBB2 0x9104 # 0 +0x0000DBB3 0x9122 # 0 +0x0000DBB4 0x911E # 0 +0x0000DBB5 0x9123 # 0 +0x0000DBB6 0x9131 # 0 +0x0000DBB7 0x912F # 0 +0x0000DBB8 0x9139 # 0 +0x0000DBB9 0x9143 # 0 +0x0000DBBA 0x9146 # 0 +0x0000DBBB 0x520D # 0 +0x0000DBBC 0x5942 # 0 +0x0000DBBD 0x52A2 # 0 +0x0000DBBE 0x52AC # 0 +0x0000DBBF 0x52AD # 0 +0x0000DBC0 0x52BE # 0 +0x0000DBC1 0x54FF # 0 +0x0000DBC2 0x52D0 # 0 +0x0000DBC3 0x52D6 # 0 +0x0000DBC4 0x52F0 # 0 +0x0000DBC5 0x53DF # 0 +0x0000DBC6 0x71EE # 0 +0x0000DBC7 0x77CD # 0 +0x0000DBC8 0x5EF4 # 0 +0x0000DBC9 0x51F5 # 0 +0x0000DBCA 0x51FC # 0 +0x0000DBCB 0x9B2F # 0 +0x0000DBCC 0x53B6 # 0 +0x0000DBCD 0x5F01 # 0 +0x0000DBCE 0x755A # 0 +0x0000DBCF 0x5DEF # 0 +0x0000DBD0 0x574C # 0 +0x0000DBD1 0x57A9 # 0 +0x0000DBD2 0x57A1 # 0 +0x0000DBD3 0x587E # 0 +0x0000DBD4 0x58BC # 0 +0x0000DBD5 0x58C5 # 0 +0x0000DBD6 0x58D1 # 0 +0x0000DBD7 0x5729 # 0 +0x0000DBD8 0x572C # 0 +0x0000DBD9 0x572A # 0 +0x0000DBDA 0x5733 # 0 +0x0000DBDB 0x5739 # 0 +0x0000DBDC 0x572E # 0 +0x0000DBDD 0x572F # 0 +0x0000DBDE 0x575C # 0 +0x0000DBDF 0x573B # 0 +0x0000DBE0 0x5742 # 0 +0x0000DBE1 0x5769 # 0 +0x0000DBE2 0x5785 # 0 +0x0000DBE3 0x576B # 0 +0x0000DBE4 0x5786 # 0 +0x0000DBE5 0x577C # 0 +0x0000DBE6 0x577B # 0 +0x0000DBE7 0x5768 # 0 +0x0000DBE8 0x576D # 0 +0x0000DBE9 0x5776 # 0 +0x0000DBEA 0x5773 # 0 +0x0000DBEB 0x57AD # 0 +0x0000DBEC 0x57A4 # 0 +0x0000DBED 0x578C # 0 +0x0000DBEE 0x57B2 # 0 +0x0000DBEF 0x57CF # 0 +0x0000DBF0 0x57A7 # 0 +0x0000DBF1 0x57B4 # 0 +0x0000DBF2 0x5793 # 0 +0x0000DBF3 0x57A0 # 0 +0x0000DBF4 0x57D5 # 0 +0x0000DBF5 0x57D8 # 0 +0x0000DBF6 0x57DA # 0 +0x0000DBF7 0x57D9 # 0 +0x0000DBF8 0x57D2 # 0 +0x0000DBF9 0x57B8 # 0 +0x0000DBFA 0x57F4 # 0 +0x0000DBFB 0x57EF # 0 +0x0000DBFC 0x57F8 # 0 +0x0000DBFD 0x57E4 # 0 +0x0000DBFE 0x57DD # 0 +0x0000DCA1 0x580B # 0 +0x0000DCA2 0x580D # 0 +0x0000DCA3 0x57FD # 0 +0x0000DCA4 0x57ED # 0 +0x0000DCA5 0x5800 # 0 +0x0000DCA6 0x581E # 0 +0x0000DCA7 0x5819 # 0 +0x0000DCA8 0x5844 # 0 +0x0000DCA9 0x5820 # 0 +0x0000DCAA 0x5865 # 0 +0x0000DCAB 0x586C # 0 +0x0000DCAC 0x5881 # 0 +0x0000DCAD 0x5889 # 0 +0x0000DCAE 0x589A # 0 +0x0000DCAF 0x5880 # 0 +0x0000DCB0 0x99A8 # 0 +0x0000DCB1 0x9F19 # 0 +0x0000DCB2 0x61FF # 0 +0x0000DCB3 0x8279 # 0 +0x0000DCB4 0x827D # 0 +0x0000DCB5 0x827F # 0 +0x0000DCB6 0x828F # 0 +0x0000DCB7 0x828A # 0 +0x0000DCB8 0x82A8 # 0 +0x0000DCB9 0x8284 # 0 +0x0000DCBA 0x828E # 0 +0x0000DCBB 0x8291 # 0 +0x0000DCBC 0x8297 # 0 +0x0000DCBD 0x8299 # 0 +0x0000DCBE 0x82AB # 0 +0x0000DCBF 0x82B8 # 0 +0x0000DCC0 0x82BE # 0 +0x0000DCC1 0x82B0 # 0 +0x0000DCC2 0x82C8 # 0 +0x0000DCC3 0x82CA # 0 +0x0000DCC4 0x82E3 # 0 +0x0000DCC5 0x8298 # 0 +0x0000DCC6 0x82B7 # 0 +0x0000DCC7 0x82AE # 0 +0x0000DCC8 0x82CB # 0 +0x0000DCC9 0x82CC # 0 +0x0000DCCA 0x82C1 # 0 +0x0000DCCB 0x82A9 # 0 +0x0000DCCC 0x82B4 # 0 +0x0000DCCD 0x82A1 # 0 +0x0000DCCE 0x82AA # 0 +0x0000DCCF 0x829F # 0 +0x0000DCD0 0x82C4 # 0 +0x0000DCD1 0x82CE # 0 +0x0000DCD2 0x82A4 # 0 +0x0000DCD3 0x82E1 # 0 +0x0000DCD4 0x8309 # 0 +0x0000DCD5 0x82F7 # 0 +0x0000DCD6 0x82E4 # 0 +0x0000DCD7 0x830F # 0 +0x0000DCD8 0x8307 # 0 +0x0000DCD9 0x82DC # 0 +0x0000DCDA 0x82F4 # 0 +0x0000DCDB 0x82D2 # 0 +0x0000DCDC 0x82D8 # 0 +0x0000DCDD 0x830C # 0 +0x0000DCDE 0x82FB # 0 +0x0000DCDF 0x82D3 # 0 +0x0000DCE0 0x8311 # 0 +0x0000DCE1 0x831A # 0 +0x0000DCE2 0x8306 # 0 +0x0000DCE3 0x8314 # 0 +0x0000DCE4 0x8315 # 0 +0x0000DCE5 0x82E0 # 0 +0x0000DCE6 0x82D5 # 0 +0x0000DCE7 0x831C # 0 +0x0000DCE8 0x8351 # 0 +0x0000DCE9 0x835B # 0 +0x0000DCEA 0x835C # 0 +0x0000DCEB 0x8308 # 0 +0x0000DCEC 0x8392 # 0 +0x0000DCED 0x833C # 0 +0x0000DCEE 0x8334 # 0 +0x0000DCEF 0x8331 # 0 +0x0000DCF0 0x839B # 0 +0x0000DCF1 0x835E # 0 +0x0000DCF2 0x832F # 0 +0x0000DCF3 0x834F # 0 +0x0000DCF4 0x8347 # 0 +0x0000DCF5 0x8343 # 0 +0x0000DCF6 0x835F # 0 +0x0000DCF7 0x8340 # 0 +0x0000DCF8 0x8317 # 0 +0x0000DCF9 0x8360 # 0 +0x0000DCFA 0x832D # 0 +0x0000DCFB 0x833A # 0 +0x0000DCFC 0x8333 # 0 +0x0000DCFD 0x8366 # 0 +0x0000DCFE 0x8365 # 0 +0x0000DDA1 0x8368 # 0 +0x0000DDA2 0x831B # 0 +0x0000DDA3 0x8369 # 0 +0x0000DDA4 0x836C # 0 +0x0000DDA5 0x836A # 0 +0x0000DDA6 0x836D # 0 +0x0000DDA7 0x836E # 0 +0x0000DDA8 0x83B0 # 0 +0x0000DDA9 0x8378 # 0 +0x0000DDAA 0x83B3 # 0 +0x0000DDAB 0x83B4 # 0 +0x0000DDAC 0x83A0 # 0 +0x0000DDAD 0x83AA # 0 +0x0000DDAE 0x8393 # 0 +0x0000DDAF 0x839C # 0 +0x0000DDB0 0x8385 # 0 +0x0000DDB1 0x837C # 0 +0x0000DDB2 0x83B6 # 0 +0x0000DDB3 0x83A9 # 0 +0x0000DDB4 0x837D # 0 +0x0000DDB5 0x83B8 # 0 +0x0000DDB6 0x837B # 0 +0x0000DDB7 0x8398 # 0 +0x0000DDB8 0x839E # 0 +0x0000DDB9 0x83A8 # 0 +0x0000DDBA 0x83BA # 0 +0x0000DDBB 0x83BC # 0 +0x0000DDBC 0x83C1 # 0 +0x0000DDBD 0x8401 # 0 +0x0000DDBE 0x83E5 # 0 +0x0000DDBF 0x83D8 # 0 +0x0000DDC0 0x5807 # 0 +0x0000DDC1 0x8418 # 0 +0x0000DDC2 0x840B # 0 +0x0000DDC3 0x83DD # 0 +0x0000DDC4 0x83FD # 0 +0x0000DDC5 0x83D6 # 0 +0x0000DDC6 0x841C # 0 +0x0000DDC7 0x8438 # 0 +0x0000DDC8 0x8411 # 0 +0x0000DDC9 0x8406 # 0 +0x0000DDCA 0x83D4 # 0 +0x0000DDCB 0x83DF # 0 +0x0000DDCC 0x840F # 0 +0x0000DDCD 0x8403 # 0 +0x0000DDCE 0x83F8 # 0 +0x0000DDCF 0x83F9 # 0 +0x0000DDD0 0x83EA # 0 +0x0000DDD1 0x83C5 # 0 +0x0000DDD2 0x83C0 # 0 +0x0000DDD3 0x8426 # 0 +0x0000DDD4 0x83F0 # 0 +0x0000DDD5 0x83E1 # 0 +0x0000DDD6 0x845C # 0 +0x0000DDD7 0x8451 # 0 +0x0000DDD8 0x845A # 0 +0x0000DDD9 0x8459 # 0 +0x0000DDDA 0x8473 # 0 +0x0000DDDB 0x8487 # 0 +0x0000DDDC 0x8488 # 0 +0x0000DDDD 0x847A # 0 +0x0000DDDE 0x8489 # 0 +0x0000DDDF 0x8478 # 0 +0x0000DDE0 0x843C # 0 +0x0000DDE1 0x8446 # 0 +0x0000DDE2 0x8469 # 0 +0x0000DDE3 0x8476 # 0 +0x0000DDE4 0x848C # 0 +0x0000DDE5 0x848E # 0 +0x0000DDE6 0x8431 # 0 +0x0000DDE7 0x846D # 0 +0x0000DDE8 0x84C1 # 0 +0x0000DDE9 0x84CD # 0 +0x0000DDEA 0x84D0 # 0 +0x0000DDEB 0x84E6 # 0 +0x0000DDEC 0x84BD # 0 +0x0000DDED 0x84D3 # 0 +0x0000DDEE 0x84CA # 0 +0x0000DDEF 0x84BF # 0 +0x0000DDF0 0x84BA # 0 +0x0000DDF1 0x84E0 # 0 +0x0000DDF2 0x84A1 # 0 +0x0000DDF3 0x84B9 # 0 +0x0000DDF4 0x84B4 # 0 +0x0000DDF5 0x8497 # 0 +0x0000DDF6 0x84E5 # 0 +0x0000DDF7 0x84E3 # 0 +0x0000DDF8 0x850C # 0 +0x0000DDF9 0x750D # 0 +0x0000DDFA 0x8538 # 0 +0x0000DDFB 0x84F0 # 0 +0x0000DDFC 0x8539 # 0 +0x0000DDFD 0x851F # 0 +0x0000DDFE 0x853A # 0 +0x0000DEA1 0x8556 # 0 +0x0000DEA2 0x853B # 0 +0x0000DEA3 0x84FF # 0 +0x0000DEA4 0x84FC # 0 +0x0000DEA5 0x8559 # 0 +0x0000DEA6 0x8548 # 0 +0x0000DEA7 0x8568 # 0 +0x0000DEA8 0x8564 # 0 +0x0000DEA9 0x855E # 0 +0x0000DEAA 0x857A # 0 +0x0000DEAB 0x77A2 # 0 +0x0000DEAC 0x8543 # 0 +0x0000DEAD 0x8572 # 0 +0x0000DEAE 0x857B # 0 +0x0000DEAF 0x85A4 # 0 +0x0000DEB0 0x85A8 # 0 +0x0000DEB1 0x8587 # 0 +0x0000DEB2 0x858F # 0 +0x0000DEB3 0x8579 # 0 +0x0000DEB4 0x85AE # 0 +0x0000DEB5 0x859C # 0 +0x0000DEB6 0x8585 # 0 +0x0000DEB7 0x85B9 # 0 +0x0000DEB8 0x85B7 # 0 +0x0000DEB9 0x85B0 # 0 +0x0000DEBA 0x85D3 # 0 +0x0000DEBB 0x85C1 # 0 +0x0000DEBC 0x85DC # 0 +0x0000DEBD 0x85FF # 0 +0x0000DEBE 0x8627 # 0 +0x0000DEBF 0x8605 # 0 +0x0000DEC0 0x8629 # 0 +0x0000DEC1 0x8616 # 0 +0x0000DEC2 0x863C # 0 +0x0000DEC3 0x5EFE # 0 +0x0000DEC4 0x5F08 # 0 +0x0000DEC5 0x593C # 0 +0x0000DEC6 0x5941 # 0 +0x0000DEC7 0x8037 # 0 +0x0000DEC8 0x5955 # 0 +0x0000DEC9 0x595A # 0 +0x0000DECA 0x5958 # 0 +0x0000DECB 0x530F # 0 +0x0000DECC 0x5C22 # 0 +0x0000DECD 0x5C25 # 0 +0x0000DECE 0x5C2C # 0 +0x0000DECF 0x5C34 # 0 +0x0000DED0 0x624C # 0 +0x0000DED1 0x626A # 0 +0x0000DED2 0x629F # 0 +0x0000DED3 0x62BB # 0 +0x0000DED4 0x62CA # 0 +0x0000DED5 0x62DA # 0 +0x0000DED6 0x62D7 # 0 +0x0000DED7 0x62EE # 0 +0x0000DED8 0x6322 # 0 +0x0000DED9 0x62F6 # 0 +0x0000DEDA 0x6339 # 0 +0x0000DEDB 0x634B # 0 +0x0000DEDC 0x6343 # 0 +0x0000DEDD 0x63AD # 0 +0x0000DEDE 0x63F6 # 0 +0x0000DEDF 0x6371 # 0 +0x0000DEE0 0x637A # 0 +0x0000DEE1 0x638E # 0 +0x0000DEE2 0x63B4 # 0 +0x0000DEE3 0x636D # 0 +0x0000DEE4 0x63AC # 0 +0x0000DEE5 0x638A # 0 +0x0000DEE6 0x6369 # 0 +0x0000DEE7 0x63AE # 0 +0x0000DEE8 0x63BC # 0 +0x0000DEE9 0x63F2 # 0 +0x0000DEEA 0x63F8 # 0 +0x0000DEEB 0x63E0 # 0 +0x0000DEEC 0x63FF # 0 +0x0000DEED 0x63C4 # 0 +0x0000DEEE 0x63DE # 0 +0x0000DEEF 0x63CE # 0 +0x0000DEF0 0x6452 # 0 +0x0000DEF1 0x63C6 # 0 +0x0000DEF2 0x63BE # 0 +0x0000DEF3 0x6445 # 0 +0x0000DEF4 0x6441 # 0 +0x0000DEF5 0x640B # 0 +0x0000DEF6 0x641B # 0 +0x0000DEF7 0x6420 # 0 +0x0000DEF8 0x640C # 0 +0x0000DEF9 0x6426 # 0 +0x0000DEFA 0x6421 # 0 +0x0000DEFB 0x645E # 0 +0x0000DEFC 0x6484 # 0 +0x0000DEFD 0x646D # 0 +0x0000DEFE 0x6496 # 0 +0x0000DFA1 0x647A # 0 +0x0000DFA2 0x64B7 # 0 +0x0000DFA3 0x64B8 # 0 +0x0000DFA4 0x6499 # 0 +0x0000DFA5 0x64BA # 0 +0x0000DFA6 0x64C0 # 0 +0x0000DFA7 0x64D0 # 0 +0x0000DFA8 0x64D7 # 0 +0x0000DFA9 0x64E4 # 0 +0x0000DFAA 0x64E2 # 0 +0x0000DFAB 0x6509 # 0 +0x0000DFAC 0x6525 # 0 +0x0000DFAD 0x652E # 0 +0x0000DFAE 0x5F0B # 0 +0x0000DFAF 0x5FD2 # 0 +0x0000DFB0 0x7519 # 0 +0x0000DFB1 0x5F11 # 0 +0x0000DFB2 0x535F # 0 +0x0000DFB3 0x53F1 # 0 +0x0000DFB4 0x53FD # 0 +0x0000DFB5 0x53E9 # 0 +0x0000DFB6 0x53E8 # 0 +0x0000DFB7 0x53FB # 0 +0x0000DFB8 0x5412 # 0 +0x0000DFB9 0x5416 # 0 +0x0000DFBA 0x5406 # 0 +0x0000DFBB 0x544B # 0 +0x0000DFBC 0x5452 # 0 +0x0000DFBD 0x5453 # 0 +0x0000DFBE 0x5454 # 0 +0x0000DFBF 0x5456 # 0 +0x0000DFC0 0x5443 # 0 +0x0000DFC1 0x5421 # 0 +0x0000DFC2 0x5457 # 0 +0x0000DFC3 0x5459 # 0 +0x0000DFC4 0x5423 # 0 +0x0000DFC5 0x5432 # 0 +0x0000DFC6 0x5482 # 0 +0x0000DFC7 0x5494 # 0 +0x0000DFC8 0x5477 # 0 +0x0000DFC9 0x5471 # 0 +0x0000DFCA 0x5464 # 0 +0x0000DFCB 0x549A # 0 +0x0000DFCC 0x549B # 0 +0x0000DFCD 0x5484 # 0 +0x0000DFCE 0x5476 # 0 +0x0000DFCF 0x5466 # 0 +0x0000DFD0 0x549D # 0 +0x0000DFD1 0x54D0 # 0 +0x0000DFD2 0x54AD # 0 +0x0000DFD3 0x54C2 # 0 +0x0000DFD4 0x54B4 # 0 +0x0000DFD5 0x54D2 # 0 +0x0000DFD6 0x54A7 # 0 +0x0000DFD7 0x54A6 # 0 +0x0000DFD8 0x54D3 # 0 +0x0000DFD9 0x54D4 # 0 +0x0000DFDA 0x5472 # 0 +0x0000DFDB 0x54A3 # 0 +0x0000DFDC 0x54D5 # 0 +0x0000DFDD 0x54BB # 0 +0x0000DFDE 0x54BF # 0 +0x0000DFDF 0x54CC # 0 +0x0000DFE0 0x54D9 # 0 +0x0000DFE1 0x54DA # 0 +0x0000DFE2 0x54DC # 0 +0x0000DFE3 0x54A9 # 0 +0x0000DFE4 0x54AA # 0 +0x0000DFE5 0x54A4 # 0 +0x0000DFE6 0x54DD # 0 +0x0000DFE7 0x54CF # 0 +0x0000DFE8 0x54DE # 0 +0x0000DFE9 0x551B # 0 +0x0000DFEA 0x54E7 # 0 +0x0000DFEB 0x5520 # 0 +0x0000DFEC 0x54FD # 0 +0x0000DFED 0x5514 # 0 +0x0000DFEE 0x54F3 # 0 +0x0000DFEF 0x5522 # 0 +0x0000DFF0 0x5523 # 0 +0x0000DFF1 0x550F # 0 +0x0000DFF2 0x5511 # 0 +0x0000DFF3 0x5527 # 0 +0x0000DFF4 0x552A # 0 +0x0000DFF5 0x5567 # 0 +0x0000DFF6 0x558F # 0 +0x0000DFF7 0x55B5 # 0 +0x0000DFF8 0x5549 # 0 +0x0000DFF9 0x556D # 0 +0x0000DFFA 0x5541 # 0 +0x0000DFFB 0x5555 # 0 +0x0000DFFC 0x553F # 0 +0x0000DFFD 0x5550 # 0 +0x0000DFFE 0x553C # 0 +0x0000E0A1 0x5537 # 0 +0x0000E0A2 0x5556 # 0 +0x0000E0A3 0x5575 # 0 +0x0000E0A4 0x5576 # 0 +0x0000E0A5 0x5577 # 0 +0x0000E0A6 0x5533 # 0 +0x0000E0A7 0x5530 # 0 +0x0000E0A8 0x555C # 0 +0x0000E0A9 0x558B # 0 +0x0000E0AA 0x55D2 # 0 +0x0000E0AB 0x5583 # 0 +0x0000E0AC 0x55B1 # 0 +0x0000E0AD 0x55B9 # 0 +0x0000E0AE 0x5588 # 0 +0x0000E0AF 0x5581 # 0 +0x0000E0B0 0x559F # 0 +0x0000E0B1 0x557E # 0 +0x0000E0B2 0x55D6 # 0 +0x0000E0B3 0x5591 # 0 +0x0000E0B4 0x557B # 0 +0x0000E0B5 0x55DF # 0 +0x0000E0B6 0x55BD # 0 +0x0000E0B7 0x55BE # 0 +0x0000E0B8 0x5594 # 0 +0x0000E0B9 0x5599 # 0 +0x0000E0BA 0x55EA # 0 +0x0000E0BB 0x55F7 # 0 +0x0000E0BC 0x55C9 # 0 +0x0000E0BD 0x561F # 0 +0x0000E0BE 0x55D1 # 0 +0x0000E0BF 0x55EB # 0 +0x0000E0C0 0x55EC # 0 +0x0000E0C1 0x55D4 # 0 +0x0000E0C2 0x55E6 # 0 +0x0000E0C3 0x55DD # 0 +0x0000E0C4 0x55C4 # 0 +0x0000E0C5 0x55EF # 0 +0x0000E0C6 0x55E5 # 0 +0x0000E0C7 0x55F2 # 0 +0x0000E0C8 0x55F3 # 0 +0x0000E0C9 0x55CC # 0 +0x0000E0CA 0x55CD # 0 +0x0000E0CB 0x55E8 # 0 +0x0000E0CC 0x55F5 # 0 +0x0000E0CD 0x55E4 # 0 +0x0000E0CE 0x8F94 # 0 +0x0000E0CF 0x561E # 0 +0x0000E0D0 0x5608 # 0 +0x0000E0D1 0x560C # 0 +0x0000E0D2 0x5601 # 0 +0x0000E0D3 0x5624 # 0 +0x0000E0D4 0x5623 # 0 +0x0000E0D5 0x55FE # 0 +0x0000E0D6 0x5600 # 0 +0x0000E0D7 0x5627 # 0 +0x0000E0D8 0x562D # 0 +0x0000E0D9 0x5658 # 0 +0x0000E0DA 0x5639 # 0 +0x0000E0DB 0x5657 # 0 +0x0000E0DC 0x562C # 0 +0x0000E0DD 0x564D # 0 +0x0000E0DE 0x5662 # 0 +0x0000E0DF 0x5659 # 0 +0x0000E0E0 0x565C # 0 +0x0000E0E1 0x564C # 0 +0x0000E0E2 0x5654 # 0 +0x0000E0E3 0x5686 # 0 +0x0000E0E4 0x5664 # 0 +0x0000E0E5 0x5671 # 0 +0x0000E0E6 0x566B # 0 +0x0000E0E7 0x567B # 0 +0x0000E0E8 0x567C # 0 +0x0000E0E9 0x5685 # 0 +0x0000E0EA 0x5693 # 0 +0x0000E0EB 0x56AF # 0 +0x0000E0EC 0x56D4 # 0 +0x0000E0ED 0x56D7 # 0 +0x0000E0EE 0x56DD # 0 +0x0000E0EF 0x56E1 # 0 +0x0000E0F0 0x56F5 # 0 +0x0000E0F1 0x56EB # 0 +0x0000E0F2 0x56F9 # 0 +0x0000E0F3 0x56FF # 0 +0x0000E0F4 0x5704 # 0 +0x0000E0F5 0x570A # 0 +0x0000E0F6 0x5709 # 0 +0x0000E0F7 0x571C # 0 +0x0000E0F8 0x5E0F # 0 +0x0000E0F9 0x5E19 # 0 +0x0000E0FA 0x5E14 # 0 +0x0000E0FB 0x5E11 # 0 +0x0000E0FC 0x5E31 # 0 +0x0000E0FD 0x5E3B # 0 +0x0000E0FE 0x5E3C # 0 +0x0000E1A1 0x5E37 # 0 +0x0000E1A2 0x5E44 # 0 +0x0000E1A3 0x5E54 # 0 +0x0000E1A4 0x5E5B # 0 +0x0000E1A5 0x5E5E # 0 +0x0000E1A6 0x5E61 # 0 +0x0000E1A7 0x5C8C # 0 +0x0000E1A8 0x5C7A # 0 +0x0000E1A9 0x5C8D # 0 +0x0000E1AA 0x5C90 # 0 +0x0000E1AB 0x5C96 # 0 +0x0000E1AC 0x5C88 # 0 +0x0000E1AD 0x5C98 # 0 +0x0000E1AE 0x5C99 # 0 +0x0000E1AF 0x5C91 # 0 +0x0000E1B0 0x5C9A # 0 +0x0000E1B1 0x5C9C # 0 +0x0000E1B2 0x5CB5 # 0 +0x0000E1B3 0x5CA2 # 0 +0x0000E1B4 0x5CBD # 0 +0x0000E1B5 0x5CAC # 0 +0x0000E1B6 0x5CAB # 0 +0x0000E1B7 0x5CB1 # 0 +0x0000E1B8 0x5CA3 # 0 +0x0000E1B9 0x5CC1 # 0 +0x0000E1BA 0x5CB7 # 0 +0x0000E1BB 0x5CC4 # 0 +0x0000E1BC 0x5CD2 # 0 +0x0000E1BD 0x5CE4 # 0 +0x0000E1BE 0x5CCB # 0 +0x0000E1BF 0x5CE5 # 0 +0x0000E1C0 0x5D02 # 0 +0x0000E1C1 0x5D03 # 0 +0x0000E1C2 0x5D27 # 0 +0x0000E1C3 0x5D26 # 0 +0x0000E1C4 0x5D2E # 0 +0x0000E1C5 0x5D24 # 0 +0x0000E1C6 0x5D1E # 0 +0x0000E1C7 0x5D06 # 0 +0x0000E1C8 0x5D1B # 0 +0x0000E1C9 0x5D58 # 0 +0x0000E1CA 0x5D3E # 0 +0x0000E1CB 0x5D34 # 0 +0x0000E1CC 0x5D3D # 0 +0x0000E1CD 0x5D6C # 0 +0x0000E1CE 0x5D5B # 0 +0x0000E1CF 0x5D6F # 0 +0x0000E1D0 0x5D5D # 0 +0x0000E1D1 0x5D6B # 0 +0x0000E1D2 0x5D4B # 0 +0x0000E1D3 0x5D4A # 0 +0x0000E1D4 0x5D69 # 0 +0x0000E1D5 0x5D74 # 0 +0x0000E1D6 0x5D82 # 0 +0x0000E1D7 0x5D99 # 0 +0x0000E1D8 0x5D9D # 0 +0x0000E1D9 0x8C73 # 0 +0x0000E1DA 0x5DB7 # 0 +0x0000E1DB 0x5DC5 # 0 +0x0000E1DC 0x5F73 # 0 +0x0000E1DD 0x5F77 # 0 +0x0000E1DE 0x5F82 # 0 +0x0000E1DF 0x5F87 # 0 +0x0000E1E0 0x5F89 # 0 +0x0000E1E1 0x5F8C # 0 +0x0000E1E2 0x5F95 # 0 +0x0000E1E3 0x5F99 # 0 +0x0000E1E4 0x5F9C # 0 +0x0000E1E5 0x5FA8 # 0 +0x0000E1E6 0x5FAD # 0 +0x0000E1E7 0x5FB5 # 0 +0x0000E1E8 0x5FBC # 0 +0x0000E1E9 0x8862 # 0 +0x0000E1EA 0x5F61 # 0 +0x0000E1EB 0x72AD # 0 +0x0000E1EC 0x72B0 # 0 +0x0000E1ED 0x72B4 # 0 +0x0000E1EE 0x72B7 # 0 +0x0000E1EF 0x72B8 # 0 +0x0000E1F0 0x72C3 # 0 +0x0000E1F1 0x72C1 # 0 +0x0000E1F2 0x72CE # 0 +0x0000E1F3 0x72CD # 0 +0x0000E1F4 0x72D2 # 0 +0x0000E1F5 0x72E8 # 0 +0x0000E1F6 0x72EF # 0 +0x0000E1F7 0x72E9 # 0 +0x0000E1F8 0x72F2 # 0 +0x0000E1F9 0x72F4 # 0 +0x0000E1FA 0x72F7 # 0 +0x0000E1FB 0x7301 # 0 +0x0000E1FC 0x72F3 # 0 +0x0000E1FD 0x7303 # 0 +0x0000E1FE 0x72FA # 0 +0x0000E2A1 0x72FB # 0 +0x0000E2A2 0x7317 # 0 +0x0000E2A3 0x7313 # 0 +0x0000E2A4 0x7321 # 0 +0x0000E2A5 0x730A # 0 +0x0000E2A6 0x731E # 0 +0x0000E2A7 0x731D # 0 +0x0000E2A8 0x7315 # 0 +0x0000E2A9 0x7322 # 0 +0x0000E2AA 0x7339 # 0 +0x0000E2AB 0x7325 # 0 +0x0000E2AC 0x732C # 0 +0x0000E2AD 0x7338 # 0 +0x0000E2AE 0x7331 # 0 +0x0000E2AF 0x7350 # 0 +0x0000E2B0 0x734D # 0 +0x0000E2B1 0x7357 # 0 +0x0000E2B2 0x7360 # 0 +0x0000E2B3 0x736C # 0 +0x0000E2B4 0x736F # 0 +0x0000E2B5 0x737E # 0 +0x0000E2B6 0x821B # 0 +0x0000E2B7 0x5925 # 0 +0x0000E2B8 0x98E7 # 0 +0x0000E2B9 0x5924 # 0 +0x0000E2BA 0x5902 # 0 +0x0000E2BB 0x9963 # 0 +0x0000E2BC 0x9967 # 0 +0x0000E2BD 0x9968 # 0 +0x0000E2BE 0x9969 # 0 +0x0000E2BF 0x996A # 0 +0x0000E2C0 0x996B # 0 +0x0000E2C1 0x996C # 0 +0x0000E2C2 0x9974 # 0 +0x0000E2C3 0x9977 # 0 +0x0000E2C4 0x997D # 0 +0x0000E2C5 0x9980 # 0 +0x0000E2C6 0x9984 # 0 +0x0000E2C7 0x9987 # 0 +0x0000E2C8 0x998A # 0 +0x0000E2C9 0x998D # 0 +0x0000E2CA 0x9990 # 0 +0x0000E2CB 0x9991 # 0 +0x0000E2CC 0x9993 # 0 +0x0000E2CD 0x9994 # 0 +0x0000E2CE 0x9995 # 0 +0x0000E2CF 0x5E80 # 0 +0x0000E2D0 0x5E91 # 0 +0x0000E2D1 0x5E8B # 0 +0x0000E2D2 0x5E96 # 0 +0x0000E2D3 0x5EA5 # 0 +0x0000E2D4 0x5EA0 # 0 +0x0000E2D5 0x5EB9 # 0 +0x0000E2D6 0x5EB5 # 0 +0x0000E2D7 0x5EBE # 0 +0x0000E2D8 0x5EB3 # 0 +0x0000E2D9 0x8D53 # 0 +0x0000E2DA 0x5ED2 # 0 +0x0000E2DB 0x5ED1 # 0 +0x0000E2DC 0x5EDB # 0 +0x0000E2DD 0x5EE8 # 0 +0x0000E2DE 0x5EEA # 0 +0x0000E2DF 0x81BA # 0 +0x0000E2E0 0x5FC4 # 0 +0x0000E2E1 0x5FC9 # 0 +0x0000E2E2 0x5FD6 # 0 +0x0000E2E3 0x5FCF # 0 +0x0000E2E4 0x6003 # 0 +0x0000E2E5 0x5FEE # 0 +0x0000E2E6 0x6004 # 0 +0x0000E2E7 0x5FE1 # 0 +0x0000E2E8 0x5FE4 # 0 +0x0000E2E9 0x5FFE # 0 +0x0000E2EA 0x6005 # 0 +0x0000E2EB 0x6006 # 0 +0x0000E2EC 0x5FEA # 0 +0x0000E2ED 0x5FED # 0 +0x0000E2EE 0x5FF8 # 0 +0x0000E2EF 0x6019 # 0 +0x0000E2F0 0x6035 # 0 +0x0000E2F1 0x6026 # 0 +0x0000E2F2 0x601B # 0 +0x0000E2F3 0x600F # 0 +0x0000E2F4 0x600D # 0 +0x0000E2F5 0x6029 # 0 +0x0000E2F6 0x602B # 0 +0x0000E2F7 0x600A # 0 +0x0000E2F8 0x603F # 0 +0x0000E2F9 0x6021 # 0 +0x0000E2FA 0x6078 # 0 +0x0000E2FB 0x6079 # 0 +0x0000E2FC 0x607B # 0 +0x0000E2FD 0x607A # 0 +0x0000E2FE 0x6042 # 0 +0x0000E3A1 0x606A # 0 +0x0000E3A2 0x607D # 0 +0x0000E3A3 0x6096 # 0 +0x0000E3A4 0x609A # 0 +0x0000E3A5 0x60AD # 0 +0x0000E3A6 0x609D # 0 +0x0000E3A7 0x6083 # 0 +0x0000E3A8 0x6092 # 0 +0x0000E3A9 0x608C # 0 +0x0000E3AA 0x609B # 0 +0x0000E3AB 0x60EC # 0 +0x0000E3AC 0x60BB # 0 +0x0000E3AD 0x60B1 # 0 +0x0000E3AE 0x60DD # 0 +0x0000E3AF 0x60D8 # 0 +0x0000E3B0 0x60C6 # 0 +0x0000E3B1 0x60DA # 0 +0x0000E3B2 0x60B4 # 0 +0x0000E3B3 0x6120 # 0 +0x0000E3B4 0x6126 # 0 +0x0000E3B5 0x6115 # 0 +0x0000E3B6 0x6123 # 0 +0x0000E3B7 0x60F4 # 0 +0x0000E3B8 0x6100 # 0 +0x0000E3B9 0x610E # 0 +0x0000E3BA 0x612B # 0 +0x0000E3BB 0x614A # 0 +0x0000E3BC 0x6175 # 0 +0x0000E3BD 0x61AC # 0 +0x0000E3BE 0x6194 # 0 +0x0000E3BF 0x61A7 # 0 +0x0000E3C0 0x61B7 # 0 +0x0000E3C1 0x61D4 # 0 +0x0000E3C2 0x61F5 # 0 +0x0000E3C3 0x5FDD # 0 +0x0000E3C4 0x96B3 # 0 +0x0000E3C5 0x95E9 # 0 +0x0000E3C6 0x95EB # 0 +0x0000E3C7 0x95F1 # 0 +0x0000E3C8 0x95F3 # 0 +0x0000E3C9 0x95F5 # 0 +0x0000E3CA 0x95F6 # 0 +0x0000E3CB 0x95FC # 0 +0x0000E3CC 0x95FE # 0 +0x0000E3CD 0x9603 # 0 +0x0000E3CE 0x9604 # 0 +0x0000E3CF 0x9606 # 0 +0x0000E3D0 0x9608 # 0 +0x0000E3D1 0x960A # 0 +0x0000E3D2 0x960B # 0 +0x0000E3D3 0x960C # 0 +0x0000E3D4 0x960D # 0 +0x0000E3D5 0x960F # 0 +0x0000E3D6 0x9612 # 0 +0x0000E3D7 0x9615 # 0 +0x0000E3D8 0x9616 # 0 +0x0000E3D9 0x9617 # 0 +0x0000E3DA 0x9619 # 0 +0x0000E3DB 0x961A # 0 +0x0000E3DC 0x4E2C # 0 +0x0000E3DD 0x723F # 0 +0x0000E3DE 0x6215 # 0 +0x0000E3DF 0x6C35 # 0 +0x0000E3E0 0x6C54 # 0 +0x0000E3E1 0x6C5C # 0 +0x0000E3E2 0x6C4A # 0 +0x0000E3E3 0x6CA3 # 0 +0x0000E3E4 0x6C85 # 0 +0x0000E3E5 0x6C90 # 0 +0x0000E3E6 0x6C94 # 0 +0x0000E3E7 0x6C8C # 0 +0x0000E3E8 0x6C68 # 0 +0x0000E3E9 0x6C69 # 0 +0x0000E3EA 0x6C74 # 0 +0x0000E3EB 0x6C76 # 0 +0x0000E3EC 0x6C86 # 0 +0x0000E3ED 0x6CA9 # 0 +0x0000E3EE 0x6CD0 # 0 +0x0000E3EF 0x6CD4 # 0 +0x0000E3F0 0x6CAD # 0 +0x0000E3F1 0x6CF7 # 0 +0x0000E3F2 0x6CF8 # 0 +0x0000E3F3 0x6CF1 # 0 +0x0000E3F4 0x6CD7 # 0 +0x0000E3F5 0x6CB2 # 0 +0x0000E3F6 0x6CE0 # 0 +0x0000E3F7 0x6CD6 # 0 +0x0000E3F8 0x6CFA # 0 +0x0000E3F9 0x6CEB # 0 +0x0000E3FA 0x6CEE # 0 +0x0000E3FB 0x6CB1 # 0 +0x0000E3FC 0x6CD3 # 0 +0x0000E3FD 0x6CEF # 0 +0x0000E3FE 0x6CFE # 0 +0x0000E4A1 0x6D39 # 0 +0x0000E4A2 0x6D27 # 0 +0x0000E4A3 0x6D0C # 0 +0x0000E4A4 0x6D43 # 0 +0x0000E4A5 0x6D48 # 0 +0x0000E4A6 0x6D07 # 0 +0x0000E4A7 0x6D04 # 0 +0x0000E4A8 0x6D19 # 0 +0x0000E4A9 0x6D0E # 0 +0x0000E4AA 0x6D2B # 0 +0x0000E4AB 0x6D4D # 0 +0x0000E4AC 0x6D2E # 0 +0x0000E4AD 0x6D35 # 0 +0x0000E4AE 0x6D1A # 0 +0x0000E4AF 0x6D4F # 0 +0x0000E4B0 0x6D52 # 0 +0x0000E4B1 0x6D54 # 0 +0x0000E4B2 0x6D33 # 0 +0x0000E4B3 0x6D91 # 0 +0x0000E4B4 0x6D6F # 0 +0x0000E4B5 0x6D9E # 0 +0x0000E4B6 0x6DA0 # 0 +0x0000E4B7 0x6D5E # 0 +0x0000E4B8 0x6D93 # 0 +0x0000E4B9 0x6D94 # 0 +0x0000E4BA 0x6D5C # 0 +0x0000E4BB 0x6D60 # 0 +0x0000E4BC 0x6D7C # 0 +0x0000E4BD 0x6D63 # 0 +0x0000E4BE 0x6E1A # 0 +0x0000E4BF 0x6DC7 # 0 +0x0000E4C0 0x6DC5 # 0 +0x0000E4C1 0x6DDE # 0 +0x0000E4C2 0x6E0E # 0 +0x0000E4C3 0x6DBF # 0 +0x0000E4C4 0x6DE0 # 0 +0x0000E4C5 0x6E11 # 0 +0x0000E4C6 0x6DE6 # 0 +0x0000E4C7 0x6DDD # 0 +0x0000E4C8 0x6DD9 # 0 +0x0000E4C9 0x6E16 # 0 +0x0000E4CA 0x6DAB # 0 +0x0000E4CB 0x6E0C # 0 +0x0000E4CC 0x6DAE # 0 +0x0000E4CD 0x6E2B # 0 +0x0000E4CE 0x6E6E # 0 +0x0000E4CF 0x6E4E # 0 +0x0000E4D0 0x6E6B # 0 +0x0000E4D1 0x6EB2 # 0 +0x0000E4D2 0x6E5F # 0 +0x0000E4D3 0x6E86 # 0 +0x0000E4D4 0x6E53 # 0 +0x0000E4D5 0x6E54 # 0 +0x0000E4D6 0x6E32 # 0 +0x0000E4D7 0x6E25 # 0 +0x0000E4D8 0x6E44 # 0 +0x0000E4D9 0x6EDF # 0 +0x0000E4DA 0x6EB1 # 0 +0x0000E4DB 0x6E98 # 0 +0x0000E4DC 0x6EE0 # 0 +0x0000E4DD 0x6F2D # 0 +0x0000E4DE 0x6EE2 # 0 +0x0000E4DF 0x6EA5 # 0 +0x0000E4E0 0x6EA7 # 0 +0x0000E4E1 0x6EBD # 0 +0x0000E4E2 0x6EBB # 0 +0x0000E4E3 0x6EB7 # 0 +0x0000E4E4 0x6ED7 # 0 +0x0000E4E5 0x6EB4 # 0 +0x0000E4E6 0x6ECF # 0 +0x0000E4E7 0x6E8F # 0 +0x0000E4E8 0x6EC2 # 0 +0x0000E4E9 0x6E9F # 0 +0x0000E4EA 0x6F62 # 0 +0x0000E4EB 0x6F46 # 0 +0x0000E4EC 0x6F47 # 0 +0x0000E4ED 0x6F24 # 0 +0x0000E4EE 0x6F15 # 0 +0x0000E4EF 0x6EF9 # 0 +0x0000E4F0 0x6F2F # 0 +0x0000E4F1 0x6F36 # 0 +0x0000E4F2 0x6F4B # 0 +0x0000E4F3 0x6F74 # 0 +0x0000E4F4 0x6F2A # 0 +0x0000E4F5 0x6F09 # 0 +0x0000E4F6 0x6F29 # 0 +0x0000E4F7 0x6F89 # 0 +0x0000E4F8 0x6F8D # 0 +0x0000E4F9 0x6F8C # 0 +0x0000E4FA 0x6F78 # 0 +0x0000E4FB 0x6F72 # 0 +0x0000E4FC 0x6F7C # 0 +0x0000E4FD 0x6F7A # 0 +0x0000E4FE 0x6FD1 # 0 +0x0000E5A1 0x6FC9 # 0 +0x0000E5A2 0x6FA7 # 0 +0x0000E5A3 0x6FB9 # 0 +0x0000E5A4 0x6FB6 # 0 +0x0000E5A5 0x6FC2 # 0 +0x0000E5A6 0x6FE1 # 0 +0x0000E5A7 0x6FEE # 0 +0x0000E5A8 0x6FDE # 0 +0x0000E5A9 0x6FE0 # 0 +0x0000E5AA 0x6FEF # 0 +0x0000E5AB 0x701A # 0 +0x0000E5AC 0x7023 # 0 +0x0000E5AD 0x701B # 0 +0x0000E5AE 0x7039 # 0 +0x0000E5AF 0x7035 # 0 +0x0000E5B0 0x704F # 0 +0x0000E5B1 0x705E # 0 +0x0000E5B2 0x5B80 # 0 +0x0000E5B3 0x5B84 # 0 +0x0000E5B4 0x5B95 # 0 +0x0000E5B5 0x5B93 # 0 +0x0000E5B6 0x5BA5 # 0 +0x0000E5B7 0x5BB8 # 0 +0x0000E5B8 0x752F # 0 +0x0000E5B9 0x9A9E # 0 +0x0000E5BA 0x6434 # 0 +0x0000E5BB 0x5BE4 # 0 +0x0000E5BC 0x5BEE # 0 +0x0000E5BD 0x8930 # 0 +0x0000E5BE 0x5BF0 # 0 +0x0000E5BF 0x8E47 # 0 +0x0000E5C0 0x8B07 # 0 +0x0000E5C1 0x8FB6 # 0 +0x0000E5C2 0x8FD3 # 0 +0x0000E5C3 0x8FD5 # 0 +0x0000E5C4 0x8FE5 # 0 +0x0000E5C5 0x8FEE # 0 +0x0000E5C6 0x8FE4 # 0 +0x0000E5C7 0x8FE9 # 0 +0x0000E5C8 0x8FE6 # 0 +0x0000E5C9 0x8FF3 # 0 +0x0000E5CA 0x8FE8 # 0 +0x0000E5CB 0x9005 # 0 +0x0000E5CC 0x9004 # 0 +0x0000E5CD 0x900B # 0 +0x0000E5CE 0x9026 # 0 +0x0000E5CF 0x9011 # 0 +0x0000E5D0 0x900D # 0 +0x0000E5D1 0x9016 # 0 +0x0000E5D2 0x9021 # 0 +0x0000E5D3 0x9035 # 0 +0x0000E5D4 0x9036 # 0 +0x0000E5D5 0x902D # 0 +0x0000E5D6 0x902F # 0 +0x0000E5D7 0x9044 # 0 +0x0000E5D8 0x9051 # 0 +0x0000E5D9 0x9052 # 0 +0x0000E5DA 0x9050 # 0 +0x0000E5DB 0x9068 # 0 +0x0000E5DC 0x9058 # 0 +0x0000E5DD 0x9062 # 0 +0x0000E5DE 0x905B # 0 +0x0000E5DF 0x66B9 # 0 +0x0000E5E0 0x9074 # 0 +0x0000E5E1 0x907D # 0 +0x0000E5E2 0x9082 # 0 +0x0000E5E3 0x9088 # 0 +0x0000E5E4 0x9083 # 0 +0x0000E5E5 0x908B # 0 +0x0000E5E6 0x5F50 # 0 +0x0000E5E7 0x5F57 # 0 +0x0000E5E8 0x5F56 # 0 +0x0000E5E9 0x5F58 # 0 +0x0000E5EA 0x5C3B # 0 +0x0000E5EB 0x54AB # 0 +0x0000E5EC 0x5C50 # 0 +0x0000E5ED 0x5C59 # 0 +0x0000E5EE 0x5B71 # 0 +0x0000E5EF 0x5C63 # 0 +0x0000E5F0 0x5C66 # 0 +0x0000E5F1 0x7FBC # 0 +0x0000E5F2 0x5F2A # 0 +0x0000E5F3 0x5F29 # 0 +0x0000E5F4 0x5F2D # 0 +0x0000E5F5 0x8274 # 0 +0x0000E5F6 0x5F3C # 0 +0x0000E5F7 0x9B3B # 0 +0x0000E5F8 0x5C6E # 0 +0x0000E5F9 0x5981 # 0 +0x0000E5FA 0x5983 # 0 +0x0000E5FB 0x598D # 0 +0x0000E5FC 0x59A9 # 0 +0x0000E5FD 0x59AA # 0 +0x0000E5FE 0x59A3 # 0 +0x0000E6A1 0x5997 # 0 +0x0000E6A2 0x59CA # 0 +0x0000E6A3 0x59AB # 0 +0x0000E6A4 0x599E # 0 +0x0000E6A5 0x59A4 # 0 +0x0000E6A6 0x59D2 # 0 +0x0000E6A7 0x59B2 # 0 +0x0000E6A8 0x59AF # 0 +0x0000E6A9 0x59D7 # 0 +0x0000E6AA 0x59BE # 0 +0x0000E6AB 0x5A05 # 0 +0x0000E6AC 0x5A06 # 0 +0x0000E6AD 0x59DD # 0 +0x0000E6AE 0x5A08 # 0 +0x0000E6AF 0x59E3 # 0 +0x0000E6B0 0x59D8 # 0 +0x0000E6B1 0x59F9 # 0 +0x0000E6B2 0x5A0C # 0 +0x0000E6B3 0x5A09 # 0 +0x0000E6B4 0x5A32 # 0 +0x0000E6B5 0x5A34 # 0 +0x0000E6B6 0x5A11 # 0 +0x0000E6B7 0x5A23 # 0 +0x0000E6B8 0x5A13 # 0 +0x0000E6B9 0x5A40 # 0 +0x0000E6BA 0x5A67 # 0 +0x0000E6BB 0x5A4A # 0 +0x0000E6BC 0x5A55 # 0 +0x0000E6BD 0x5A3C # 0 +0x0000E6BE 0x5A62 # 0 +0x0000E6BF 0x5A75 # 0 +0x0000E6C0 0x80EC # 0 +0x0000E6C1 0x5AAA # 0 +0x0000E6C2 0x5A9B # 0 +0x0000E6C3 0x5A77 # 0 +0x0000E6C4 0x5A7A # 0 +0x0000E6C5 0x5ABE # 0 +0x0000E6C6 0x5AEB # 0 +0x0000E6C7 0x5AB2 # 0 +0x0000E6C8 0x5AD2 # 0 +0x0000E6C9 0x5AD4 # 0 +0x0000E6CA 0x5AB8 # 0 +0x0000E6CB 0x5AE0 # 0 +0x0000E6CC 0x5AE3 # 0 +0x0000E6CD 0x5AF1 # 0 +0x0000E6CE 0x5AD6 # 0 +0x0000E6CF 0x5AE6 # 0 +0x0000E6D0 0x5AD8 # 0 +0x0000E6D1 0x5ADC # 0 +0x0000E6D2 0x5B09 # 0 +0x0000E6D3 0x5B17 # 0 +0x0000E6D4 0x5B16 # 0 +0x0000E6D5 0x5B32 # 0 +0x0000E6D6 0x5B37 # 0 +0x0000E6D7 0x5B40 # 0 +0x0000E6D8 0x5C15 # 0 +0x0000E6D9 0x5C1C # 0 +0x0000E6DA 0x5B5A # 0 +0x0000E6DB 0x5B65 # 0 +0x0000E6DC 0x5B73 # 0 +0x0000E6DD 0x5B51 # 0 +0x0000E6DE 0x5B53 # 0 +0x0000E6DF 0x5B62 # 0 +0x0000E6E0 0x9A75 # 0 +0x0000E6E1 0x9A77 # 0 +0x0000E6E2 0x9A78 # 0 +0x0000E6E3 0x9A7A # 0 +0x0000E6E4 0x9A7F # 0 +0x0000E6E5 0x9A7D # 0 +0x0000E6E6 0x9A80 # 0 +0x0000E6E7 0x9A81 # 0 +0x0000E6E8 0x9A85 # 0 +0x0000E6E9 0x9A88 # 0 +0x0000E6EA 0x9A8A # 0 +0x0000E6EB 0x9A90 # 0 +0x0000E6EC 0x9A92 # 0 +0x0000E6ED 0x9A93 # 0 +0x0000E6EE 0x9A96 # 0 +0x0000E6EF 0x9A98 # 0 +0x0000E6F0 0x9A9B # 0 +0x0000E6F1 0x9A9C # 0 +0x0000E6F2 0x9A9D # 0 +0x0000E6F3 0x9A9F # 0 +0x0000E6F4 0x9AA0 # 0 +0x0000E6F5 0x9AA2 # 0 +0x0000E6F6 0x9AA3 # 0 +0x0000E6F7 0x9AA5 # 0 +0x0000E6F8 0x9AA7 # 0 +0x0000E6F9 0x7E9F # 0 +0x0000E6FA 0x7EA1 # 0 +0x0000E6FB 0x7EA3 # 0 +0x0000E6FC 0x7EA5 # 0 +0x0000E6FD 0x7EA8 # 0 +0x0000E6FE 0x7EA9 # 0 +0x0000E7A1 0x7EAD # 0 +0x0000E7A2 0x7EB0 # 0 +0x0000E7A3 0x7EBE # 0 +0x0000E7A4 0x7EC0 # 0 +0x0000E7A5 0x7EC1 # 0 +0x0000E7A6 0x7EC2 # 0 +0x0000E7A7 0x7EC9 # 0 +0x0000E7A8 0x7ECB # 0 +0x0000E7A9 0x7ECC # 0 +0x0000E7AA 0x7ED0 # 0 +0x0000E7AB 0x7ED4 # 0 +0x0000E7AC 0x7ED7 # 0 +0x0000E7AD 0x7EDB # 0 +0x0000E7AE 0x7EE0 # 0 +0x0000E7AF 0x7EE1 # 0 +0x0000E7B0 0x7EE8 # 0 +0x0000E7B1 0x7EEB # 0 +0x0000E7B2 0x7EEE # 0 +0x0000E7B3 0x7EEF # 0 +0x0000E7B4 0x7EF1 # 0 +0x0000E7B5 0x7EF2 # 0 +0x0000E7B6 0x7F0D # 0 +0x0000E7B7 0x7EF6 # 0 +0x0000E7B8 0x7EFA # 0 +0x0000E7B9 0x7EFB # 0 +0x0000E7BA 0x7EFE # 0 +0x0000E7BB 0x7F01 # 0 +0x0000E7BC 0x7F02 # 0 +0x0000E7BD 0x7F03 # 0 +0x0000E7BE 0x7F07 # 0 +0x0000E7BF 0x7F08 # 0 +0x0000E7C0 0x7F0B # 0 +0x0000E7C1 0x7F0C # 0 +0x0000E7C2 0x7F0F # 0 +0x0000E7C3 0x7F11 # 0 +0x0000E7C4 0x7F12 # 0 +0x0000E7C5 0x7F17 # 0 +0x0000E7C6 0x7F19 # 0 +0x0000E7C7 0x7F1C # 0 +0x0000E7C8 0x7F1B # 0 +0x0000E7C9 0x7F1F # 0 +0x0000E7CA 0x7F21 # 0 +0x0000E7CB 0x7F22 # 0 +0x0000E7CC 0x7F23 # 0 +0x0000E7CD 0x7F24 # 0 +0x0000E7CE 0x7F25 # 0 +0x0000E7CF 0x7F26 # 0 +0x0000E7D0 0x7F27 # 0 +0x0000E7D1 0x7F2A # 0 +0x0000E7D2 0x7F2B # 0 +0x0000E7D3 0x7F2C # 0 +0x0000E7D4 0x7F2D # 0 +0x0000E7D5 0x7F2F # 0 +0x0000E7D6 0x7F30 # 0 +0x0000E7D7 0x7F31 # 0 +0x0000E7D8 0x7F32 # 0 +0x0000E7D9 0x7F33 # 0 +0x0000E7DA 0x7F35 # 0 +0x0000E7DB 0x5E7A # 0 +0x0000E7DC 0x757F # 0 +0x0000E7DD 0x5DDB # 0 +0x0000E7DE 0x753E # 0 +0x0000E7DF 0x9095 # 0 +0x0000E7E0 0x738E # 0 +0x0000E7E1 0x7391 # 0 +0x0000E7E2 0x73AE # 0 +0x0000E7E3 0x73A2 # 0 +0x0000E7E4 0x739F # 0 +0x0000E7E5 0x73CF # 0 +0x0000E7E6 0x73C2 # 0 +0x0000E7E7 0x73D1 # 0 +0x0000E7E8 0x73B7 # 0 +0x0000E7E9 0x73B3 # 0 +0x0000E7EA 0x73C0 # 0 +0x0000E7EB 0x73C9 # 0 +0x0000E7EC 0x73C8 # 0 +0x0000E7ED 0x73E5 # 0 +0x0000E7EE 0x73D9 # 0 +0x0000E7EF 0x987C # 0 +0x0000E7F0 0x740A # 0 +0x0000E7F1 0x73E9 # 0 +0x0000E7F2 0x73E7 # 0 +0x0000E7F3 0x73DE # 0 +0x0000E7F4 0x73BA # 0 +0x0000E7F5 0x73F2 # 0 +0x0000E7F6 0x740F # 0 +0x0000E7F7 0x742A # 0 +0x0000E7F8 0x745B # 0 +0x0000E7F9 0x7426 # 0 +0x0000E7FA 0x7425 # 0 +0x0000E7FB 0x7428 # 0 +0x0000E7FC 0x7430 # 0 +0x0000E7FD 0x742E # 0 +0x0000E7FE 0x742C # 0 +0x0000E8A1 0x741B # 0 +0x0000E8A2 0x741A # 0 +0x0000E8A3 0x7441 # 0 +0x0000E8A4 0x745C # 0 +0x0000E8A5 0x7457 # 0 +0x0000E8A6 0x7455 # 0 +0x0000E8A7 0x7459 # 0 +0x0000E8A8 0x7477 # 0 +0x0000E8A9 0x746D # 0 +0x0000E8AA 0x747E # 0 +0x0000E8AB 0x749C # 0 +0x0000E8AC 0x748E # 0 +0x0000E8AD 0x7480 # 0 +0x0000E8AE 0x7481 # 0 +0x0000E8AF 0x7487 # 0 +0x0000E8B0 0x748B # 0 +0x0000E8B1 0x749E # 0 +0x0000E8B2 0x74A8 # 0 +0x0000E8B3 0x74A9 # 0 +0x0000E8B4 0x7490 # 0 +0x0000E8B5 0x74A7 # 0 +0x0000E8B6 0x74D2 # 0 +0x0000E8B7 0x74BA # 0 +0x0000E8B8 0x97EA # 0 +0x0000E8B9 0x97EB # 0 +0x0000E8BA 0x97EC # 0 +0x0000E8BB 0x674C # 0 +0x0000E8BC 0x6753 # 0 +0x0000E8BD 0x675E # 0 +0x0000E8BE 0x6748 # 0 +0x0000E8BF 0x6769 # 0 +0x0000E8C0 0x67A5 # 0 +0x0000E8C1 0x6787 # 0 +0x0000E8C2 0x676A # 0 +0x0000E8C3 0x6773 # 0 +0x0000E8C4 0x6798 # 0 +0x0000E8C5 0x67A7 # 0 +0x0000E8C6 0x6775 # 0 +0x0000E8C7 0x67A8 # 0 +0x0000E8C8 0x679E # 0 +0x0000E8C9 0x67AD # 0 +0x0000E8CA 0x678B # 0 +0x0000E8CB 0x6777 # 0 +0x0000E8CC 0x677C # 0 +0x0000E8CD 0x67F0 # 0 +0x0000E8CE 0x6809 # 0 +0x0000E8CF 0x67D8 # 0 +0x0000E8D0 0x680A # 0 +0x0000E8D1 0x67E9 # 0 +0x0000E8D2 0x67B0 # 0 +0x0000E8D3 0x680C # 0 +0x0000E8D4 0x67D9 # 0 +0x0000E8D5 0x67B5 # 0 +0x0000E8D6 0x67DA # 0 +0x0000E8D7 0x67B3 # 0 +0x0000E8D8 0x67DD # 0 +0x0000E8D9 0x6800 # 0 +0x0000E8DA 0x67C3 # 0 +0x0000E8DB 0x67B8 # 0 +0x0000E8DC 0x67E2 # 0 +0x0000E8DD 0x680E # 0 +0x0000E8DE 0x67C1 # 0 +0x0000E8DF 0x67FD # 0 +0x0000E8E0 0x6832 # 0 +0x0000E8E1 0x6833 # 0 +0x0000E8E2 0x6860 # 0 +0x0000E8E3 0x6861 # 0 +0x0000E8E4 0x684E # 0 +0x0000E8E5 0x6862 # 0 +0x0000E8E6 0x6844 # 0 +0x0000E8E7 0x6864 # 0 +0x0000E8E8 0x6883 # 0 +0x0000E8E9 0x681D # 0 +0x0000E8EA 0x6855 # 0 +0x0000E8EB 0x6866 # 0 +0x0000E8EC 0x6841 # 0 +0x0000E8ED 0x6867 # 0 +0x0000E8EE 0x6840 # 0 +0x0000E8EF 0x683E # 0 +0x0000E8F0 0x684A # 0 +0x0000E8F1 0x6849 # 0 +0x0000E8F2 0x6829 # 0 +0x0000E8F3 0x68B5 # 0 +0x0000E8F4 0x688F # 0 +0x0000E8F5 0x6874 # 0 +0x0000E8F6 0x6877 # 0 +0x0000E8F7 0x6893 # 0 +0x0000E8F8 0x686B # 0 +0x0000E8F9 0x68C2 # 0 +0x0000E8FA 0x696E # 0 +0x0000E8FB 0x68FC # 0 +0x0000E8FC 0x691F # 0 +0x0000E8FD 0x6920 # 0 +0x0000E8FE 0x68F9 # 0 +0x0000E9A1 0x6924 # 0 +0x0000E9A2 0x68F0 # 0 +0x0000E9A3 0x690B # 0 +0x0000E9A4 0x6901 # 0 +0x0000E9A5 0x6957 # 0 +0x0000E9A6 0x68E3 # 0 +0x0000E9A7 0x6910 # 0 +0x0000E9A8 0x6971 # 0 +0x0000E9A9 0x6939 # 0 +0x0000E9AA 0x6960 # 0 +0x0000E9AB 0x6942 # 0 +0x0000E9AC 0x695D # 0 +0x0000E9AD 0x6984 # 0 +0x0000E9AE 0x696B # 0 +0x0000E9AF 0x6980 # 0 +0x0000E9B0 0x6998 # 0 +0x0000E9B1 0x6978 # 0 +0x0000E9B2 0x6934 # 0 +0x0000E9B3 0x69CC # 0 +0x0000E9B4 0x6987 # 0 +0x0000E9B5 0x6988 # 0 +0x0000E9B6 0x69CE # 0 +0x0000E9B7 0x6989 # 0 +0x0000E9B8 0x6966 # 0 +0x0000E9B9 0x6963 # 0 +0x0000E9BA 0x6979 # 0 +0x0000E9BB 0x699B # 0 +0x0000E9BC 0x69A7 # 0 +0x0000E9BD 0x69BB # 0 +0x0000E9BE 0x69AB # 0 +0x0000E9BF 0x69AD # 0 +0x0000E9C0 0x69D4 # 0 +0x0000E9C1 0x69B1 # 0 +0x0000E9C2 0x69C1 # 0 +0x0000E9C3 0x69CA # 0 +0x0000E9C4 0x69DF # 0 +0x0000E9C5 0x6995 # 0 +0x0000E9C6 0x69E0 # 0 +0x0000E9C7 0x698D # 0 +0x0000E9C8 0x69FF # 0 +0x0000E9C9 0x6A2F # 0 +0x0000E9CA 0x69ED # 0 +0x0000E9CB 0x6A17 # 0 +0x0000E9CC 0x6A18 # 0 +0x0000E9CD 0x6A65 # 0 +0x0000E9CE 0x69F2 # 0 +0x0000E9CF 0x6A44 # 0 +0x0000E9D0 0x6A3E # 0 +0x0000E9D1 0x6AA0 # 0 +0x0000E9D2 0x6A50 # 0 +0x0000E9D3 0x6A5B # 0 +0x0000E9D4 0x6A35 # 0 +0x0000E9D5 0x6A8E # 0 +0x0000E9D6 0x6A79 # 0 +0x0000E9D7 0x6A3D # 0 +0x0000E9D8 0x6A28 # 0 +0x0000E9D9 0x6A58 # 0 +0x0000E9DA 0x6A7C # 0 +0x0000E9DB 0x6A91 # 0 +0x0000E9DC 0x6A90 # 0 +0x0000E9DD 0x6AA9 # 0 +0x0000E9DE 0x6A97 # 0 +0x0000E9DF 0x6AAB # 0 +0x0000E9E0 0x7337 # 0 +0x0000E9E1 0x7352 # 0 +0x0000E9E2 0x6B81 # 0 +0x0000E9E3 0x6B82 # 0 +0x0000E9E4 0x6B87 # 0 +0x0000E9E5 0x6B84 # 0 +0x0000E9E6 0x6B92 # 0 +0x0000E9E7 0x6B93 # 0 +0x0000E9E8 0x6B8D # 0 +0x0000E9E9 0x6B9A # 0 +0x0000E9EA 0x6B9B # 0 +0x0000E9EB 0x6BA1 # 0 +0x0000E9EC 0x6BAA # 0 +0x0000E9ED 0x8F6B # 0 +0x0000E9EE 0x8F6D # 0 +0x0000E9EF 0x8F71 # 0 +0x0000E9F0 0x8F72 # 0 +0x0000E9F1 0x8F73 # 0 +0x0000E9F2 0x8F75 # 0 +0x0000E9F3 0x8F76 # 0 +0x0000E9F4 0x8F78 # 0 +0x0000E9F5 0x8F77 # 0 +0x0000E9F6 0x8F79 # 0 +0x0000E9F7 0x8F7A # 0 +0x0000E9F8 0x8F7C # 0 +0x0000E9F9 0x8F7E # 0 +0x0000E9FA 0x8F81 # 0 +0x0000E9FB 0x8F82 # 0 +0x0000E9FC 0x8F84 # 0 +0x0000E9FD 0x8F87 # 0 +0x0000E9FE 0x8F8B # 0 +0x0000EAA1 0x8F8D # 0 +0x0000EAA2 0x8F8E # 0 +0x0000EAA3 0x8F8F # 0 +0x0000EAA4 0x8F98 # 0 +0x0000EAA5 0x8F9A # 0 +0x0000EAA6 0x8ECE # 0 +0x0000EAA7 0x620B # 0 +0x0000EAA8 0x6217 # 0 +0x0000EAA9 0x621B # 0 +0x0000EAAA 0x621F # 0 +0x0000EAAB 0x6222 # 0 +0x0000EAAC 0x6221 # 0 +0x0000EAAD 0x6225 # 0 +0x0000EAAE 0x6224 # 0 +0x0000EAAF 0x622C # 0 +0x0000EAB0 0x81E7 # 0 +0x0000EAB1 0x74EF # 0 +0x0000EAB2 0x74F4 # 0 +0x0000EAB3 0x74FF # 0 +0x0000EAB4 0x750F # 0 +0x0000EAB5 0x7511 # 0 +0x0000EAB6 0x7513 # 0 +0x0000EAB7 0x6534 # 0 +0x0000EAB8 0x65EE # 0 +0x0000EAB9 0x65EF # 0 +0x0000EABA 0x65F0 # 0 +0x0000EABB 0x660A # 0 +0x0000EABC 0x6619 # 0 +0x0000EABD 0x6772 # 0 +0x0000EABE 0x6603 # 0 +0x0000EABF 0x6615 # 0 +0x0000EAC0 0x6600 # 0 +0x0000EAC1 0x7085 # 0 +0x0000EAC2 0x66F7 # 0 +0x0000EAC3 0x661D # 0 +0x0000EAC4 0x6634 # 0 +0x0000EAC5 0x6631 # 0 +0x0000EAC6 0x6636 # 0 +0x0000EAC7 0x6635 # 0 +0x0000EAC8 0x8006 # 0 +0x0000EAC9 0x665F # 0 +0x0000EACA 0x6654 # 0 +0x0000EACB 0x6641 # 0 +0x0000EACC 0x664F # 0 +0x0000EACD 0x6656 # 0 +0x0000EACE 0x6661 # 0 +0x0000EACF 0x6657 # 0 +0x0000EAD0 0x6677 # 0 +0x0000EAD1 0x6684 # 0 +0x0000EAD2 0x668C # 0 +0x0000EAD3 0x66A7 # 0 +0x0000EAD4 0x669D # 0 +0x0000EAD5 0x66BE # 0 +0x0000EAD6 0x66DB # 0 +0x0000EAD7 0x66DC # 0 +0x0000EAD8 0x66E6 # 0 +0x0000EAD9 0x66E9 # 0 +0x0000EADA 0x8D32 # 0 +0x0000EADB 0x8D33 # 0 +0x0000EADC 0x8D36 # 0 +0x0000EADD 0x8D3B # 0 +0x0000EADE 0x8D3D # 0 +0x0000EADF 0x8D40 # 0 +0x0000EAE0 0x8D45 # 0 +0x0000EAE1 0x8D46 # 0 +0x0000EAE2 0x8D48 # 0 +0x0000EAE3 0x8D49 # 0 +0x0000EAE4 0x8D47 # 0 +0x0000EAE5 0x8D4D # 0 +0x0000EAE6 0x8D55 # 0 +0x0000EAE7 0x8D59 # 0 +0x0000EAE8 0x89C7 # 0 +0x0000EAE9 0x89CA # 0 +0x0000EAEA 0x89CB # 0 +0x0000EAEB 0x89CC # 0 +0x0000EAEC 0x89CE # 0 +0x0000EAED 0x89CF # 0 +0x0000EAEE 0x89D0 # 0 +0x0000EAEF 0x89D1 # 0 +0x0000EAF0 0x726E # 0 +0x0000EAF1 0x729F # 0 +0x0000EAF2 0x725D # 0 +0x0000EAF3 0x7266 # 0 +0x0000EAF4 0x726F # 0 +0x0000EAF5 0x727E # 0 +0x0000EAF6 0x727F # 0 +0x0000EAF7 0x7284 # 0 +0x0000EAF8 0x728B # 0 +0x0000EAF9 0x728D # 0 +0x0000EAFA 0x728F # 0 +0x0000EAFB 0x7292 # 0 +0x0000EAFC 0x6308 # 0 +0x0000EAFD 0x6332 # 0 +0x0000EAFE 0x63B0 # 0 +0x0000EBA1 0x643F # 0 +0x0000EBA2 0x64D8 # 0 +0x0000EBA3 0x8004 # 0 +0x0000EBA4 0x6BEA # 0 +0x0000EBA5 0x6BF3 # 0 +0x0000EBA6 0x6BFD # 0 +0x0000EBA7 0x6BF5 # 0 +0x0000EBA8 0x6BF9 # 0 +0x0000EBA9 0x6C05 # 0 +0x0000EBAA 0x6C07 # 0 +0x0000EBAB 0x6C06 # 0 +0x0000EBAC 0x6C0D # 0 +0x0000EBAD 0x6C15 # 0 +0x0000EBAE 0x6C18 # 0 +0x0000EBAF 0x6C19 # 0 +0x0000EBB0 0x6C1A # 0 +0x0000EBB1 0x6C21 # 0 +0x0000EBB2 0x6C29 # 0 +0x0000EBB3 0x6C24 # 0 +0x0000EBB4 0x6C2A # 0 +0x0000EBB5 0x6C32 # 0 +0x0000EBB6 0x6535 # 0 +0x0000EBB7 0x6555 # 0 +0x0000EBB8 0x656B # 0 +0x0000EBB9 0x724D # 0 +0x0000EBBA 0x7252 # 0 +0x0000EBBB 0x7256 # 0 +0x0000EBBC 0x7230 # 0 +0x0000EBBD 0x8662 # 0 +0x0000EBBE 0x5216 # 0 +0x0000EBBF 0x809F # 0 +0x0000EBC0 0x809C # 0 +0x0000EBC1 0x8093 # 0 +0x0000EBC2 0x80BC # 0 +0x0000EBC3 0x670A # 0 +0x0000EBC4 0x80BD # 0 +0x0000EBC5 0x80B1 # 0 +0x0000EBC6 0x80AB # 0 +0x0000EBC7 0x80AD # 0 +0x0000EBC8 0x80B4 # 0 +0x0000EBC9 0x80B7 # 0 +0x0000EBCA 0x80E7 # 0 +0x0000EBCB 0x80E8 # 0 +0x0000EBCC 0x80E9 # 0 +0x0000EBCD 0x80EA # 0 +0x0000EBCE 0x80DB # 0 +0x0000EBCF 0x80C2 # 0 +0x0000EBD0 0x80C4 # 0 +0x0000EBD1 0x80D9 # 0 +0x0000EBD2 0x80CD # 0 +0x0000EBD3 0x80D7 # 0 +0x0000EBD4 0x6710 # 0 +0x0000EBD5 0x80DD # 0 +0x0000EBD6 0x80EB # 0 +0x0000EBD7 0x80F1 # 0 +0x0000EBD8 0x80F4 # 0 +0x0000EBD9 0x80ED # 0 +0x0000EBDA 0x810D # 0 +0x0000EBDB 0x810E # 0 +0x0000EBDC 0x80F2 # 0 +0x0000EBDD 0x80FC # 0 +0x0000EBDE 0x6715 # 0 +0x0000EBDF 0x8112 # 0 +0x0000EBE0 0x8C5A # 0 +0x0000EBE1 0x8136 # 0 +0x0000EBE2 0x811E # 0 +0x0000EBE3 0x812C # 0 +0x0000EBE4 0x8118 # 0 +0x0000EBE5 0x8132 # 0 +0x0000EBE6 0x8148 # 0 +0x0000EBE7 0x814C # 0 +0x0000EBE8 0x8153 # 0 +0x0000EBE9 0x8174 # 0 +0x0000EBEA 0x8159 # 0 +0x0000EBEB 0x815A # 0 +0x0000EBEC 0x8171 # 0 +0x0000EBED 0x8160 # 0 +0x0000EBEE 0x8169 # 0 +0x0000EBEF 0x817C # 0 +0x0000EBF0 0x817D # 0 +0x0000EBF1 0x816D # 0 +0x0000EBF2 0x8167 # 0 +0x0000EBF3 0x584D # 0 +0x0000EBF4 0x5AB5 # 0 +0x0000EBF5 0x8188 # 0 +0x0000EBF6 0x8182 # 0 +0x0000EBF7 0x8191 # 0 +0x0000EBF8 0x6ED5 # 0 +0x0000EBF9 0x81A3 # 0 +0x0000EBFA 0x81AA # 0 +0x0000EBFB 0x81CC # 0 +0x0000EBFC 0x6726 # 0 +0x0000EBFD 0x81CA # 0 +0x0000EBFE 0x81BB # 0 +0x0000ECA1 0x81C1 # 0 +0x0000ECA2 0x81A6 # 0 +0x0000ECA3 0x6B24 # 0 +0x0000ECA4 0x6B37 # 0 +0x0000ECA5 0x6B39 # 0 +0x0000ECA6 0x6B43 # 0 +0x0000ECA7 0x6B46 # 0 +0x0000ECA8 0x6B59 # 0 +0x0000ECA9 0x98D1 # 0 +0x0000ECAA 0x98D2 # 0 +0x0000ECAB 0x98D3 # 0 +0x0000ECAC 0x98D5 # 0 +0x0000ECAD 0x98D9 # 0 +0x0000ECAE 0x98DA # 0 +0x0000ECAF 0x6BB3 # 0 +0x0000ECB0 0x5F40 # 0 +0x0000ECB1 0x6BC2 # 0 +0x0000ECB2 0x89F3 # 0 +0x0000ECB3 0x6590 # 0 +0x0000ECB4 0x9F51 # 0 +0x0000ECB5 0x6593 # 0 +0x0000ECB6 0x65BC # 0 +0x0000ECB7 0x65C6 # 0 +0x0000ECB8 0x65C4 # 0 +0x0000ECB9 0x65C3 # 0 +0x0000ECBA 0x65CC # 0 +0x0000ECBB 0x65CE # 0 +0x0000ECBC 0x65D2 # 0 +0x0000ECBD 0x65D6 # 0 +0x0000ECBE 0x7080 # 0 +0x0000ECBF 0x709C # 0 +0x0000ECC0 0x7096 # 0 +0x0000ECC1 0x709D # 0 +0x0000ECC2 0x70BB # 0 +0x0000ECC3 0x70C0 # 0 +0x0000ECC4 0x70B7 # 0 +0x0000ECC5 0x70AB # 0 +0x0000ECC6 0x70B1 # 0 +0x0000ECC7 0x70E8 # 0 +0x0000ECC8 0x70CA # 0 +0x0000ECC9 0x7110 # 0 +0x0000ECCA 0x7113 # 0 +0x0000ECCB 0x7116 # 0 +0x0000ECCC 0x712F # 0 +0x0000ECCD 0x7131 # 0 +0x0000ECCE 0x7173 # 0 +0x0000ECCF 0x715C # 0 +0x0000ECD0 0x7168 # 0 +0x0000ECD1 0x7145 # 0 +0x0000ECD2 0x7172 # 0 +0x0000ECD3 0x714A # 0 +0x0000ECD4 0x7178 # 0 +0x0000ECD5 0x717A # 0 +0x0000ECD6 0x7198 # 0 +0x0000ECD7 0x71B3 # 0 +0x0000ECD8 0x71B5 # 0 +0x0000ECD9 0x71A8 # 0 +0x0000ECDA 0x71A0 # 0 +0x0000ECDB 0x71E0 # 0 +0x0000ECDC 0x71D4 # 0 +0x0000ECDD 0x71E7 # 0 +0x0000ECDE 0x71F9 # 0 +0x0000ECDF 0x721D # 0 +0x0000ECE0 0x7228 # 0 +0x0000ECE1 0x706C # 0 +0x0000ECE2 0x7118 # 0 +0x0000ECE3 0x7166 # 0 +0x0000ECE4 0x71B9 # 0 +0x0000ECE5 0x623E # 0 +0x0000ECE6 0x623D # 0 +0x0000ECE7 0x6243 # 0 +0x0000ECE8 0x6248 # 0 +0x0000ECE9 0x6249 # 0 +0x0000ECEA 0x793B # 0 +0x0000ECEB 0x7940 # 0 +0x0000ECEC 0x7946 # 0 +0x0000ECED 0x7949 # 0 +0x0000ECEE 0x795B # 0 +0x0000ECEF 0x795C # 0 +0x0000ECF0 0x7953 # 0 +0x0000ECF1 0x795A # 0 +0x0000ECF2 0x7962 # 0 +0x0000ECF3 0x7957 # 0 +0x0000ECF4 0x7960 # 0 +0x0000ECF5 0x796F # 0 +0x0000ECF6 0x7967 # 0 +0x0000ECF7 0x797A # 0 +0x0000ECF8 0x7985 # 0 +0x0000ECF9 0x798A # 0 +0x0000ECFA 0x799A # 0 +0x0000ECFB 0x79A7 # 0 +0x0000ECFC 0x79B3 # 0 +0x0000ECFD 0x5FD1 # 0 +0x0000ECFE 0x5FD0 # 0 +0x0000EDA1 0x603C # 0 +0x0000EDA2 0x605D # 0 +0x0000EDA3 0x605A # 0 +0x0000EDA4 0x6067 # 0 +0x0000EDA5 0x6041 # 0 +0x0000EDA6 0x6059 # 0 +0x0000EDA7 0x6063 # 0 +0x0000EDA8 0x60AB # 0 +0x0000EDA9 0x6106 # 0 +0x0000EDAA 0x610D # 0 +0x0000EDAB 0x615D # 0 +0x0000EDAC 0x61A9 # 0 +0x0000EDAD 0x619D # 0 +0x0000EDAE 0x61CB # 0 +0x0000EDAF 0x61D1 # 0 +0x0000EDB0 0x6206 # 0 +0x0000EDB1 0x8080 # 0 +0x0000EDB2 0x807F # 0 +0x0000EDB3 0x6C93 # 0 +0x0000EDB4 0x6CF6 # 0 +0x0000EDB5 0x6DFC # 0 +0x0000EDB6 0x77F6 # 0 +0x0000EDB7 0x77F8 # 0 +0x0000EDB8 0x7800 # 0 +0x0000EDB9 0x7809 # 0 +0x0000EDBA 0x7817 # 0 +0x0000EDBB 0x7818 # 0 +0x0000EDBC 0x7811 # 0 +0x0000EDBD 0x65AB # 0 +0x0000EDBE 0x782D # 0 +0x0000EDBF 0x781C # 0 +0x0000EDC0 0x781D # 0 +0x0000EDC1 0x7839 # 0 +0x0000EDC2 0x783A # 0 +0x0000EDC3 0x783B # 0 +0x0000EDC4 0x781F # 0 +0x0000EDC5 0x783C # 0 +0x0000EDC6 0x7825 # 0 +0x0000EDC7 0x782C # 0 +0x0000EDC8 0x7823 # 0 +0x0000EDC9 0x7829 # 0 +0x0000EDCA 0x784E # 0 +0x0000EDCB 0x786D # 0 +0x0000EDCC 0x7856 # 0 +0x0000EDCD 0x7857 # 0 +0x0000EDCE 0x7826 # 0 +0x0000EDCF 0x7850 # 0 +0x0000EDD0 0x7847 # 0 +0x0000EDD1 0x784C # 0 +0x0000EDD2 0x786A # 0 +0x0000EDD3 0x789B # 0 +0x0000EDD4 0x7893 # 0 +0x0000EDD5 0x789A # 0 +0x0000EDD6 0x7887 # 0 +0x0000EDD7 0x789C # 0 +0x0000EDD8 0x78A1 # 0 +0x0000EDD9 0x78A3 # 0 +0x0000EDDA 0x78B2 # 0 +0x0000EDDB 0x78B9 # 0 +0x0000EDDC 0x78A5 # 0 +0x0000EDDD 0x78D4 # 0 +0x0000EDDE 0x78D9 # 0 +0x0000EDDF 0x78C9 # 0 +0x0000EDE0 0x78EC # 0 +0x0000EDE1 0x78F2 # 0 +0x0000EDE2 0x7905 # 0 +0x0000EDE3 0x78F4 # 0 +0x0000EDE4 0x7913 # 0 +0x0000EDE5 0x7924 # 0 +0x0000EDE6 0x791E # 0 +0x0000EDE7 0x7934 # 0 +0x0000EDE8 0x9F9B # 0 +0x0000EDE9 0x9EF9 # 0 +0x0000EDEA 0x9EFB # 0 +0x0000EDEB 0x9EFC # 0 +0x0000EDEC 0x76F1 # 0 +0x0000EDED 0x7704 # 0 +0x0000EDEE 0x770D # 0 +0x0000EDEF 0x76F9 # 0 +0x0000EDF0 0x7707 # 0 +0x0000EDF1 0x7708 # 0 +0x0000EDF2 0x771A # 0 +0x0000EDF3 0x7722 # 0 +0x0000EDF4 0x7719 # 0 +0x0000EDF5 0x772D # 0 +0x0000EDF6 0x7726 # 0 +0x0000EDF7 0x7735 # 0 +0x0000EDF8 0x7738 # 0 +0x0000EDF9 0x7750 # 0 +0x0000EDFA 0x7751 # 0 +0x0000EDFB 0x7747 # 0 +0x0000EDFC 0x7743 # 0 +0x0000EDFD 0x775A # 0 +0x0000EDFE 0x7768 # 0 +0x0000EEA1 0x7762 # 0 +0x0000EEA2 0x7765 # 0 +0x0000EEA3 0x777F # 0 +0x0000EEA4 0x778D # 0 +0x0000EEA5 0x777D # 0 +0x0000EEA6 0x7780 # 0 +0x0000EEA7 0x778C # 0 +0x0000EEA8 0x7791 # 0 +0x0000EEA9 0x779F # 0 +0x0000EEAA 0x77A0 # 0 +0x0000EEAB 0x77B0 # 0 +0x0000EEAC 0x77B5 # 0 +0x0000EEAD 0x77BD # 0 +0x0000EEAE 0x753A # 0 +0x0000EEAF 0x7540 # 0 +0x0000EEB0 0x754E # 0 +0x0000EEB1 0x754B # 0 +0x0000EEB2 0x7548 # 0 +0x0000EEB3 0x755B # 0 +0x0000EEB4 0x7572 # 0 +0x0000EEB5 0x7579 # 0 +0x0000EEB6 0x7583 # 0 +0x0000EEB7 0x7F58 # 0 +0x0000EEB8 0x7F61 # 0 +0x0000EEB9 0x7F5F # 0 +0x0000EEBA 0x8A48 # 0 +0x0000EEBB 0x7F68 # 0 +0x0000EEBC 0x7F74 # 0 +0x0000EEBD 0x7F71 # 0 +0x0000EEBE 0x7F79 # 0 +0x0000EEBF 0x7F81 # 0 +0x0000EEC0 0x7F7E # 0 +0x0000EEC1 0x76CD # 0 +0x0000EEC2 0x76E5 # 0 +0x0000EEC3 0x8832 # 0 +0x0000EEC4 0x9485 # 0 +0x0000EEC5 0x9486 # 0 +0x0000EEC6 0x9487 # 0 +0x0000EEC7 0x948B # 0 +0x0000EEC8 0x948A # 0 +0x0000EEC9 0x948C # 0 +0x0000EECA 0x948D # 0 +0x0000EECB 0x948F # 0 +0x0000EECC 0x9490 # 0 +0x0000EECD 0x9494 # 0 +0x0000EECE 0x9497 # 0 +0x0000EECF 0x9495 # 0 +0x0000EED0 0x949A # 0 +0x0000EED1 0x949B # 0 +0x0000EED2 0x949C # 0 +0x0000EED3 0x94A3 # 0 +0x0000EED4 0x94A4 # 0 +0x0000EED5 0x94AB # 0 +0x0000EED6 0x94AA # 0 +0x0000EED7 0x94AD # 0 +0x0000EED8 0x94AC # 0 +0x0000EED9 0x94AF # 0 +0x0000EEDA 0x94B0 # 0 +0x0000EEDB 0x94B2 # 0 +0x0000EEDC 0x94B4 # 0 +0x0000EEDD 0x94B6 # 0 +0x0000EEDE 0x94B7 # 0 +0x0000EEDF 0x94B8 # 0 +0x0000EEE0 0x94B9 # 0 +0x0000EEE1 0x94BA # 0 +0x0000EEE2 0x94BC # 0 +0x0000EEE3 0x94BD # 0 +0x0000EEE4 0x94BF # 0 +0x0000EEE5 0x94C4 # 0 +0x0000EEE6 0x94C8 # 0 +0x0000EEE7 0x94C9 # 0 +0x0000EEE8 0x94CA # 0 +0x0000EEE9 0x94CB # 0 +0x0000EEEA 0x94CC # 0 +0x0000EEEB 0x94CD # 0 +0x0000EEEC 0x94CE # 0 +0x0000EEED 0x94D0 # 0 +0x0000EEEE 0x94D1 # 0 +0x0000EEEF 0x94D2 # 0 +0x0000EEF0 0x94D5 # 0 +0x0000EEF1 0x94D6 # 0 +0x0000EEF2 0x94D7 # 0 +0x0000EEF3 0x94D9 # 0 +0x0000EEF4 0x94D8 # 0 +0x0000EEF5 0x94DB # 0 +0x0000EEF6 0x94DE # 0 +0x0000EEF7 0x94DF # 0 +0x0000EEF8 0x94E0 # 0 +0x0000EEF9 0x94E2 # 0 +0x0000EEFA 0x94E4 # 0 +0x0000EEFB 0x94E5 # 0 +0x0000EEFC 0x94E7 # 0 +0x0000EEFD 0x94E8 # 0 +0x0000EEFE 0x94EA # 0 +0x0000EFA1 0x94E9 # 0 +0x0000EFA2 0x94EB # 0 +0x0000EFA3 0x94EE # 0 +0x0000EFA4 0x94EF # 0 +0x0000EFA5 0x94F3 # 0 +0x0000EFA6 0x94F4 # 0 +0x0000EFA7 0x94F5 # 0 +0x0000EFA8 0x94F7 # 0 +0x0000EFA9 0x94F9 # 0 +0x0000EFAA 0x94FC # 0 +0x0000EFAB 0x94FD # 0 +0x0000EFAC 0x94FF # 0 +0x0000EFAD 0x9503 # 0 +0x0000EFAE 0x9502 # 0 +0x0000EFAF 0x9506 # 0 +0x0000EFB0 0x9507 # 0 +0x0000EFB1 0x9509 # 0 +0x0000EFB2 0x950A # 0 +0x0000EFB3 0x950D # 0 +0x0000EFB4 0x950E # 0 +0x0000EFB5 0x950F # 0 +0x0000EFB6 0x9512 # 0 +0x0000EFB7 0x9513 # 0 +0x0000EFB8 0x9514 # 0 +0x0000EFB9 0x9515 # 0 +0x0000EFBA 0x9516 # 0 +0x0000EFBB 0x9518 # 0 +0x0000EFBC 0x951B # 0 +0x0000EFBD 0x951D # 0 +0x0000EFBE 0x951E # 0 +0x0000EFBF 0x951F # 0 +0x0000EFC0 0x9522 # 0 +0x0000EFC1 0x952A # 0 +0x0000EFC2 0x952B # 0 +0x0000EFC3 0x9529 # 0 +0x0000EFC4 0x952C # 0 +0x0000EFC5 0x9531 # 0 +0x0000EFC6 0x9532 # 0 +0x0000EFC7 0x9534 # 0 +0x0000EFC8 0x9536 # 0 +0x0000EFC9 0x9537 # 0 +0x0000EFCA 0x9538 # 0 +0x0000EFCB 0x953C # 0 +0x0000EFCC 0x953E # 0 +0x0000EFCD 0x953F # 0 +0x0000EFCE 0x9542 # 0 +0x0000EFCF 0x9535 # 0 +0x0000EFD0 0x9544 # 0 +0x0000EFD1 0x9545 # 0 +0x0000EFD2 0x9546 # 0 +0x0000EFD3 0x9549 # 0 +0x0000EFD4 0x954C # 0 +0x0000EFD5 0x954E # 0 +0x0000EFD6 0x954F # 0 +0x0000EFD7 0x9552 # 0 +0x0000EFD8 0x9553 # 0 +0x0000EFD9 0x9554 # 0 +0x0000EFDA 0x9556 # 0 +0x0000EFDB 0x9557 # 0 +0x0000EFDC 0x9558 # 0 +0x0000EFDD 0x9559 # 0 +0x0000EFDE 0x955B # 0 +0x0000EFDF 0x955E # 0 +0x0000EFE0 0x955F # 0 +0x0000EFE1 0x955D # 0 +0x0000EFE2 0x9561 # 0 +0x0000EFE3 0x9562 # 0 +0x0000EFE4 0x9564 # 0 +0x0000EFE5 0x9565 # 0 +0x0000EFE6 0x9566 # 0 +0x0000EFE7 0x9567 # 0 +0x0000EFE8 0x9568 # 0 +0x0000EFE9 0x9569 # 0 +0x0000EFEA 0x956A # 0 +0x0000EFEB 0x956B # 0 +0x0000EFEC 0x956C # 0 +0x0000EFED 0x956F # 0 +0x0000EFEE 0x9571 # 0 +0x0000EFEF 0x9572 # 0 +0x0000EFF0 0x9573 # 0 +0x0000EFF1 0x953A # 0 +0x0000EFF2 0x77E7 # 0 +0x0000EFF3 0x77EC # 0 +0x0000EFF4 0x96C9 # 0 +0x0000EFF5 0x79D5 # 0 +0x0000EFF6 0x79ED # 0 +0x0000EFF7 0x79E3 # 0 +0x0000EFF8 0x79EB # 0 +0x0000EFF9 0x7A06 # 0 +0x0000EFFA 0x5D47 # 0 +0x0000EFFB 0x7A03 # 0 +0x0000EFFC 0x7A02 # 0 +0x0000EFFD 0x7A1E # 0 +0x0000EFFE 0x7A14 # 0 +0x0000F0A1 0x7A39 # 0 +0x0000F0A2 0x7A37 # 0 +0x0000F0A3 0x7A51 # 0 +0x0000F0A4 0x9ECF # 0 +0x0000F0A5 0x99A5 # 0 +0x0000F0A6 0x7A70 # 0 +0x0000F0A7 0x7688 # 0 +0x0000F0A8 0x768E # 0 +0x0000F0A9 0x7693 # 0 +0x0000F0AA 0x7699 # 0 +0x0000F0AB 0x76A4 # 0 +0x0000F0AC 0x74DE # 0 +0x0000F0AD 0x74E0 # 0 +0x0000F0AE 0x752C # 0 +0x0000F0AF 0x9E20 # 0 +0x0000F0B0 0x9E22 # 0 +0x0000F0B1 0x9E28 # 0 +0x0000F0B2 0x9E29 # 0 +0x0000F0B3 0x9E2A # 0 +0x0000F0B4 0x9E2B # 0 +0x0000F0B5 0x9E2C # 0 +0x0000F0B6 0x9E32 # 0 +0x0000F0B7 0x9E31 # 0 +0x0000F0B8 0x9E36 # 0 +0x0000F0B9 0x9E38 # 0 +0x0000F0BA 0x9E37 # 0 +0x0000F0BB 0x9E39 # 0 +0x0000F0BC 0x9E3A # 0 +0x0000F0BD 0x9E3E # 0 +0x0000F0BE 0x9E41 # 0 +0x0000F0BF 0x9E42 # 0 +0x0000F0C0 0x9E44 # 0 +0x0000F0C1 0x9E46 # 0 +0x0000F0C2 0x9E47 # 0 +0x0000F0C3 0x9E48 # 0 +0x0000F0C4 0x9E49 # 0 +0x0000F0C5 0x9E4B # 0 +0x0000F0C6 0x9E4C # 0 +0x0000F0C7 0x9E4E # 0 +0x0000F0C8 0x9E51 # 0 +0x0000F0C9 0x9E55 # 0 +0x0000F0CA 0x9E57 # 0 +0x0000F0CB 0x9E5A # 0 +0x0000F0CC 0x9E5B # 0 +0x0000F0CD 0x9E5C # 0 +0x0000F0CE 0x9E5E # 0 +0x0000F0CF 0x9E63 # 0 +0x0000F0D0 0x9E66 # 0 +0x0000F0D1 0x9E67 # 0 +0x0000F0D2 0x9E68 # 0 +0x0000F0D3 0x9E69 # 0 +0x0000F0D4 0x9E6A # 0 +0x0000F0D5 0x9E6B # 0 +0x0000F0D6 0x9E6C # 0 +0x0000F0D7 0x9E71 # 0 +0x0000F0D8 0x9E6D # 0 +0x0000F0D9 0x9E73 # 0 +0x0000F0DA 0x7592 # 0 +0x0000F0DB 0x7594 # 0 +0x0000F0DC 0x7596 # 0 +0x0000F0DD 0x75A0 # 0 +0x0000F0DE 0x759D # 0 +0x0000F0DF 0x75AC # 0 +0x0000F0E0 0x75A3 # 0 +0x0000F0E1 0x75B3 # 0 +0x0000F0E2 0x75B4 # 0 +0x0000F0E3 0x75B8 # 0 +0x0000F0E4 0x75C4 # 0 +0x0000F0E5 0x75B1 # 0 +0x0000F0E6 0x75B0 # 0 +0x0000F0E7 0x75C3 # 0 +0x0000F0E8 0x75C2 # 0 +0x0000F0E9 0x75D6 # 0 +0x0000F0EA 0x75CD # 0 +0x0000F0EB 0x75E3 # 0 +0x0000F0EC 0x75E8 # 0 +0x0000F0ED 0x75E6 # 0 +0x0000F0EE 0x75E4 # 0 +0x0000F0EF 0x75EB # 0 +0x0000F0F0 0x75E7 # 0 +0x0000F0F1 0x7603 # 0 +0x0000F0F2 0x75F1 # 0 +0x0000F0F3 0x75FC # 0 +0x0000F0F4 0x75FF # 0 +0x0000F0F5 0x7610 # 0 +0x0000F0F6 0x7600 # 0 +0x0000F0F7 0x7605 # 0 +0x0000F0F8 0x760C # 0 +0x0000F0F9 0x7617 # 0 +0x0000F0FA 0x760A # 0 +0x0000F0FB 0x7625 # 0 +0x0000F0FC 0x7618 # 0 +0x0000F0FD 0x7615 # 0 +0x0000F0FE 0x7619 # 0 +0x0000F1A1 0x761B # 0 +0x0000F1A2 0x763C # 0 +0x0000F1A3 0x7622 # 0 +0x0000F1A4 0x7620 # 0 +0x0000F1A5 0x7640 # 0 +0x0000F1A6 0x762D # 0 +0x0000F1A7 0x7630 # 0 +0x0000F1A8 0x763F # 0 +0x0000F1A9 0x7635 # 0 +0x0000F1AA 0x7643 # 0 +0x0000F1AB 0x763E # 0 +0x0000F1AC 0x7633 # 0 +0x0000F1AD 0x764D # 0 +0x0000F1AE 0x765E # 0 +0x0000F1AF 0x7654 # 0 +0x0000F1B0 0x765C # 0 +0x0000F1B1 0x7656 # 0 +0x0000F1B2 0x766B # 0 +0x0000F1B3 0x766F # 0 +0x0000F1B4 0x7FCA # 0 +0x0000F1B5 0x7AE6 # 0 +0x0000F1B6 0x7A78 # 0 +0x0000F1B7 0x7A79 # 0 +0x0000F1B8 0x7A80 # 0 +0x0000F1B9 0x7A86 # 0 +0x0000F1BA 0x7A88 # 0 +0x0000F1BB 0x7A95 # 0 +0x0000F1BC 0x7AA6 # 0 +0x0000F1BD 0x7AA0 # 0 +0x0000F1BE 0x7AAC # 0 +0x0000F1BF 0x7AA8 # 0 +0x0000F1C0 0x7AAD # 0 +0x0000F1C1 0x7AB3 # 0 +0x0000F1C2 0x8864 # 0 +0x0000F1C3 0x8869 # 0 +0x0000F1C4 0x8872 # 0 +0x0000F1C5 0x887D # 0 +0x0000F1C6 0x887F # 0 +0x0000F1C7 0x8882 # 0 +0x0000F1C8 0x88A2 # 0 +0x0000F1C9 0x88C6 # 0 +0x0000F1CA 0x88B7 # 0 +0x0000F1CB 0x88BC # 0 +0x0000F1CC 0x88C9 # 0 +0x0000F1CD 0x88E2 # 0 +0x0000F1CE 0x88CE # 0 +0x0000F1CF 0x88E3 # 0 +0x0000F1D0 0x88E5 # 0 +0x0000F1D1 0x88F1 # 0 +0x0000F1D2 0x891A # 0 +0x0000F1D3 0x88FC # 0 +0x0000F1D4 0x88E8 # 0 +0x0000F1D5 0x88FE # 0 +0x0000F1D6 0x88F0 # 0 +0x0000F1D7 0x8921 # 0 +0x0000F1D8 0x8919 # 0 +0x0000F1D9 0x8913 # 0 +0x0000F1DA 0x891B # 0 +0x0000F1DB 0x890A # 0 +0x0000F1DC 0x8934 # 0 +0x0000F1DD 0x892B # 0 +0x0000F1DE 0x8936 # 0 +0x0000F1DF 0x8941 # 0 +0x0000F1E0 0x8966 # 0 +0x0000F1E1 0x897B # 0 +0x0000F1E2 0x758B # 0 +0x0000F1E3 0x80E5 # 0 +0x0000F1E4 0x76B2 # 0 +0x0000F1E5 0x76B4 # 0 +0x0000F1E6 0x77DC # 0 +0x0000F1E7 0x8012 # 0 +0x0000F1E8 0x8014 # 0 +0x0000F1E9 0x8016 # 0 +0x0000F1EA 0x801C # 0 +0x0000F1EB 0x8020 # 0 +0x0000F1EC 0x8022 # 0 +0x0000F1ED 0x8025 # 0 +0x0000F1EE 0x8026 # 0 +0x0000F1EF 0x8027 # 0 +0x0000F1F0 0x8029 # 0 +0x0000F1F1 0x8028 # 0 +0x0000F1F2 0x8031 # 0 +0x0000F1F3 0x800B # 0 +0x0000F1F4 0x8035 # 0 +0x0000F1F5 0x8043 # 0 +0x0000F1F6 0x8046 # 0 +0x0000F1F7 0x804D # 0 +0x0000F1F8 0x8052 # 0 +0x0000F1F9 0x8069 # 0 +0x0000F1FA 0x8071 # 0 +0x0000F1FB 0x8983 # 0 +0x0000F1FC 0x9878 # 0 +0x0000F1FD 0x9880 # 0 +0x0000F1FE 0x9883 # 0 +0x0000F2A1 0x9889 # 0 +0x0000F2A2 0x988C # 0 +0x0000F2A3 0x988D # 0 +0x0000F2A4 0x988F # 0 +0x0000F2A5 0x9894 # 0 +0x0000F2A6 0x989A # 0 +0x0000F2A7 0x989B # 0 +0x0000F2A8 0x989E # 0 +0x0000F2A9 0x989F # 0 +0x0000F2AA 0x98A1 # 0 +0x0000F2AB 0x98A2 # 0 +0x0000F2AC 0x98A5 # 0 +0x0000F2AD 0x98A6 # 0 +0x0000F2AE 0x864D # 0 +0x0000F2AF 0x8654 # 0 +0x0000F2B0 0x866C # 0 +0x0000F2B1 0x866E # 0 +0x0000F2B2 0x867F # 0 +0x0000F2B3 0x867A # 0 +0x0000F2B4 0x867C # 0 +0x0000F2B5 0x867B # 0 +0x0000F2B6 0x86A8 # 0 +0x0000F2B7 0x868D # 0 +0x0000F2B8 0x868B # 0 +0x0000F2B9 0x86AC # 0 +0x0000F2BA 0x869D # 0 +0x0000F2BB 0x86A7 # 0 +0x0000F2BC 0x86A3 # 0 +0x0000F2BD 0x86AA # 0 +0x0000F2BE 0x8693 # 0 +0x0000F2BF 0x86A9 # 0 +0x0000F2C0 0x86B6 # 0 +0x0000F2C1 0x86C4 # 0 +0x0000F2C2 0x86B5 # 0 +0x0000F2C3 0x86CE # 0 +0x0000F2C4 0x86B0 # 0 +0x0000F2C5 0x86BA # 0 +0x0000F2C6 0x86B1 # 0 +0x0000F2C7 0x86AF # 0 +0x0000F2C8 0x86C9 # 0 +0x0000F2C9 0x86CF # 0 +0x0000F2CA 0x86B4 # 0 +0x0000F2CB 0x86E9 # 0 +0x0000F2CC 0x86F1 # 0 +0x0000F2CD 0x86F2 # 0 +0x0000F2CE 0x86ED # 0 +0x0000F2CF 0x86F3 # 0 +0x0000F2D0 0x86D0 # 0 +0x0000F2D1 0x8713 # 0 +0x0000F2D2 0x86DE # 0 +0x0000F2D3 0x86F4 # 0 +0x0000F2D4 0x86DF # 0 +0x0000F2D5 0x86D8 # 0 +0x0000F2D6 0x86D1 # 0 +0x0000F2D7 0x8703 # 0 +0x0000F2D8 0x8707 # 0 +0x0000F2D9 0x86F8 # 0 +0x0000F2DA 0x8708 # 0 +0x0000F2DB 0x870A # 0 +0x0000F2DC 0x870D # 0 +0x0000F2DD 0x8709 # 0 +0x0000F2DE 0x8723 # 0 +0x0000F2DF 0x873B # 0 +0x0000F2E0 0x871E # 0 +0x0000F2E1 0x8725 # 0 +0x0000F2E2 0x872E # 0 +0x0000F2E3 0x871A # 0 +0x0000F2E4 0x873E # 0 +0x0000F2E5 0x8748 # 0 +0x0000F2E6 0x8734 # 0 +0x0000F2E7 0x8731 # 0 +0x0000F2E8 0x8729 # 0 +0x0000F2E9 0x8737 # 0 +0x0000F2EA 0x873F # 0 +0x0000F2EB 0x8782 # 0 +0x0000F2EC 0x8722 # 0 +0x0000F2ED 0x877D # 0 +0x0000F2EE 0x877E # 0 +0x0000F2EF 0x877B # 0 +0x0000F2F0 0x8760 # 0 +0x0000F2F1 0x8770 # 0 +0x0000F2F2 0x874C # 0 +0x0000F2F3 0x876E # 0 +0x0000F2F4 0x878B # 0 +0x0000F2F5 0x8753 # 0 +0x0000F2F6 0x8763 # 0 +0x0000F2F7 0x877C # 0 +0x0000F2F8 0x8764 # 0 +0x0000F2F9 0x8759 # 0 +0x0000F2FA 0x8765 # 0 +0x0000F2FB 0x8793 # 0 +0x0000F2FC 0x87AF # 0 +0x0000F2FD 0x87A8 # 0 +0x0000F2FE 0x87D2 # 0 +0x0000F3A1 0x87C6 # 0 +0x0000F3A2 0x8788 # 0 +0x0000F3A3 0x8785 # 0 +0x0000F3A4 0x87AD # 0 +0x0000F3A5 0x8797 # 0 +0x0000F3A6 0x8783 # 0 +0x0000F3A7 0x87AB # 0 +0x0000F3A8 0x87E5 # 0 +0x0000F3A9 0x87AC # 0 +0x0000F3AA 0x87B5 # 0 +0x0000F3AB 0x87B3 # 0 +0x0000F3AC 0x87CB # 0 +0x0000F3AD 0x87D3 # 0 +0x0000F3AE 0x87BD # 0 +0x0000F3AF 0x87D1 # 0 +0x0000F3B0 0x87C0 # 0 +0x0000F3B1 0x87CA # 0 +0x0000F3B2 0x87DB # 0 +0x0000F3B3 0x87EA # 0 +0x0000F3B4 0x87E0 # 0 +0x0000F3B5 0x87EE # 0 +0x0000F3B6 0x8816 # 0 +0x0000F3B7 0x8813 # 0 +0x0000F3B8 0x87FE # 0 +0x0000F3B9 0x880A # 0 +0x0000F3BA 0x881B # 0 +0x0000F3BB 0x8821 # 0 +0x0000F3BC 0x8839 # 0 +0x0000F3BD 0x883C # 0 +0x0000F3BE 0x7F36 # 0 +0x0000F3BF 0x7F42 # 0 +0x0000F3C0 0x7F44 # 0 +0x0000F3C1 0x7F45 # 0 +0x0000F3C2 0x8210 # 0 +0x0000F3C3 0x7AFA # 0 +0x0000F3C4 0x7AFD # 0 +0x0000F3C5 0x7B08 # 0 +0x0000F3C6 0x7B03 # 0 +0x0000F3C7 0x7B04 # 0 +0x0000F3C8 0x7B15 # 0 +0x0000F3C9 0x7B0A # 0 +0x0000F3CA 0x7B2B # 0 +0x0000F3CB 0x7B0F # 0 +0x0000F3CC 0x7B47 # 0 +0x0000F3CD 0x7B38 # 0 +0x0000F3CE 0x7B2A # 0 +0x0000F3CF 0x7B19 # 0 +0x0000F3D0 0x7B2E # 0 +0x0000F3D1 0x7B31 # 0 +0x0000F3D2 0x7B20 # 0 +0x0000F3D3 0x7B25 # 0 +0x0000F3D4 0x7B24 # 0 +0x0000F3D5 0x7B33 # 0 +0x0000F3D6 0x7B3E # 0 +0x0000F3D7 0x7B1E # 0 +0x0000F3D8 0x7B58 # 0 +0x0000F3D9 0x7B5A # 0 +0x0000F3DA 0x7B45 # 0 +0x0000F3DB 0x7B75 # 0 +0x0000F3DC 0x7B4C # 0 +0x0000F3DD 0x7B5D # 0 +0x0000F3DE 0x7B60 # 0 +0x0000F3DF 0x7B6E # 0 +0x0000F3E0 0x7B7B # 0 +0x0000F3E1 0x7B62 # 0 +0x0000F3E2 0x7B72 # 0 +0x0000F3E3 0x7B71 # 0 +0x0000F3E4 0x7B90 # 0 +0x0000F3E5 0x7BA6 # 0 +0x0000F3E6 0x7BA7 # 0 +0x0000F3E7 0x7BB8 # 0 +0x0000F3E8 0x7BAC # 0 +0x0000F3E9 0x7B9D # 0 +0x0000F3EA 0x7BA8 # 0 +0x0000F3EB 0x7B85 # 0 +0x0000F3EC 0x7BAA # 0 +0x0000F3ED 0x7B9C # 0 +0x0000F3EE 0x7BA2 # 0 +0x0000F3EF 0x7BAB # 0 +0x0000F3F0 0x7BB4 # 0 +0x0000F3F1 0x7BD1 # 0 +0x0000F3F2 0x7BC1 # 0 +0x0000F3F3 0x7BCC # 0 +0x0000F3F4 0x7BDD # 0 +0x0000F3F5 0x7BDA # 0 +0x0000F3F6 0x7BE5 # 0 +0x0000F3F7 0x7BE6 # 0 +0x0000F3F8 0x7BEA # 0 +0x0000F3F9 0x7C0C # 0 +0x0000F3FA 0x7BFE # 0 +0x0000F3FB 0x7BFC # 0 +0x0000F3FC 0x7C0F # 0 +0x0000F3FD 0x7C16 # 0 +0x0000F3FE 0x7C0B # 0 +0x0000F4A1 0x7C1F # 0 +0x0000F4A2 0x7C2A # 0 +0x0000F4A3 0x7C26 # 0 +0x0000F4A4 0x7C38 # 0 +0x0000F4A5 0x7C41 # 0 +0x0000F4A6 0x7C40 # 0 +0x0000F4A7 0x81FE # 0 +0x0000F4A8 0x8201 # 0 +0x0000F4A9 0x8202 # 0 +0x0000F4AA 0x8204 # 0 +0x0000F4AB 0x81EC # 0 +0x0000F4AC 0x8844 # 0 +0x0000F4AD 0x8221 # 0 +0x0000F4AE 0x8222 # 0 +0x0000F4AF 0x8223 # 0 +0x0000F4B0 0x822D # 0 +0x0000F4B1 0x822F # 0 +0x0000F4B2 0x8228 # 0 +0x0000F4B3 0x822B # 0 +0x0000F4B4 0x8238 # 0 +0x0000F4B5 0x823B # 0 +0x0000F4B6 0x8233 # 0 +0x0000F4B7 0x8234 # 0 +0x0000F4B8 0x823E # 0 +0x0000F4B9 0x8244 # 0 +0x0000F4BA 0x8249 # 0 +0x0000F4BB 0x824B # 0 +0x0000F4BC 0x824F # 0 +0x0000F4BD 0x825A # 0 +0x0000F4BE 0x825F # 0 +0x0000F4BF 0x8268 # 0 +0x0000F4C0 0x887E # 0 +0x0000F4C1 0x8885 # 0 +0x0000F4C2 0x8888 # 0 +0x0000F4C3 0x88D8 # 0 +0x0000F4C4 0x88DF # 0 +0x0000F4C5 0x895E # 0 +0x0000F4C6 0x7F9D # 0 +0x0000F4C7 0x7F9F # 0 +0x0000F4C8 0x7FA7 # 0 +0x0000F4C9 0x7FAF # 0 +0x0000F4CA 0x7FB0 # 0 +0x0000F4CB 0x7FB2 # 0 +0x0000F4CC 0x7C7C # 0 +0x0000F4CD 0x6549 # 0 +0x0000F4CE 0x7C91 # 0 +0x0000F4CF 0x7C9D # 0 +0x0000F4D0 0x7C9C # 0 +0x0000F4D1 0x7C9E # 0 +0x0000F4D2 0x7CA2 # 0 +0x0000F4D3 0x7CB2 # 0 +0x0000F4D4 0x7CBC # 0 +0x0000F4D5 0x7CBD # 0 +0x0000F4D6 0x7CC1 # 0 +0x0000F4D7 0x7CC7 # 0 +0x0000F4D8 0x7CCC # 0 +0x0000F4D9 0x7CCD # 0 +0x0000F4DA 0x7CC8 # 0 +0x0000F4DB 0x7CC5 # 0 +0x0000F4DC 0x7CD7 # 0 +0x0000F4DD 0x7CE8 # 0 +0x0000F4DE 0x826E # 0 +0x0000F4DF 0x66A8 # 0 +0x0000F4E0 0x7FBF # 0 +0x0000F4E1 0x7FCE # 0 +0x0000F4E2 0x7FD5 # 0 +0x0000F4E3 0x7FE5 # 0 +0x0000F4E4 0x7FE1 # 0 +0x0000F4E5 0x7FE6 # 0 +0x0000F4E6 0x7FE9 # 0 +0x0000F4E7 0x7FEE # 0 +0x0000F4E8 0x7FF3 # 0 +0x0000F4E9 0x7CF8 # 0 +0x0000F4EA 0x7D77 # 0 +0x0000F4EB 0x7DA6 # 0 +0x0000F4EC 0x7DAE # 0 +0x0000F4ED 0x7E47 # 0 +0x0000F4EE 0x7E9B # 0 +0x0000F4EF 0x9EB8 # 0 +0x0000F4F0 0x9EB4 # 0 +0x0000F4F1 0x8D73 # 0 +0x0000F4F2 0x8D84 # 0 +0x0000F4F3 0x8D94 # 0 +0x0000F4F4 0x8D91 # 0 +0x0000F4F5 0x8DB1 # 0 +0x0000F4F6 0x8D67 # 0 +0x0000F4F7 0x8D6D # 0 +0x0000F4F8 0x8C47 # 0 +0x0000F4F9 0x8C49 # 0 +0x0000F4FA 0x914A # 0 +0x0000F4FB 0x9150 # 0 +0x0000F4FC 0x914E # 0 +0x0000F4FD 0x914F # 0 +0x0000F4FE 0x9164 # 0 +0x0000F5A1 0x9162 # 0 +0x0000F5A2 0x9161 # 0 +0x0000F5A3 0x9170 # 0 +0x0000F5A4 0x9169 # 0 +0x0000F5A5 0x916F # 0 +0x0000F5A6 0x917D # 0 +0x0000F5A7 0x917E # 0 +0x0000F5A8 0x9172 # 0 +0x0000F5A9 0x9174 # 0 +0x0000F5AA 0x9179 # 0 +0x0000F5AB 0x918C # 0 +0x0000F5AC 0x9185 # 0 +0x0000F5AD 0x9190 # 0 +0x0000F5AE 0x918D # 0 +0x0000F5AF 0x9191 # 0 +0x0000F5B0 0x91A2 # 0 +0x0000F5B1 0x91A3 # 0 +0x0000F5B2 0x91AA # 0 +0x0000F5B3 0x91AD # 0 +0x0000F5B4 0x91AE # 0 +0x0000F5B5 0x91AF # 0 +0x0000F5B6 0x91B5 # 0 +0x0000F5B7 0x91B4 # 0 +0x0000F5B8 0x91BA # 0 +0x0000F5B9 0x8C55 # 0 +0x0000F5BA 0x9E7E # 0 +0x0000F5BB 0x8DB8 # 0 +0x0000F5BC 0x8DEB # 0 +0x0000F5BD 0x8E05 # 0 +0x0000F5BE 0x8E59 # 0 +0x0000F5BF 0x8E69 # 0 +0x0000F5C0 0x8DB5 # 0 +0x0000F5C1 0x8DBF # 0 +0x0000F5C2 0x8DBC # 0 +0x0000F5C3 0x8DBA # 0 +0x0000F5C4 0x8DC4 # 0 +0x0000F5C5 0x8DD6 # 0 +0x0000F5C6 0x8DD7 # 0 +0x0000F5C7 0x8DDA # 0 +0x0000F5C8 0x8DDE # 0 +0x0000F5C9 0x8DCE # 0 +0x0000F5CA 0x8DCF # 0 +0x0000F5CB 0x8DDB # 0 +0x0000F5CC 0x8DC6 # 0 +0x0000F5CD 0x8DEC # 0 +0x0000F5CE 0x8DF7 # 0 +0x0000F5CF 0x8DF8 # 0 +0x0000F5D0 0x8DE3 # 0 +0x0000F5D1 0x8DF9 # 0 +0x0000F5D2 0x8DFB # 0 +0x0000F5D3 0x8DE4 # 0 +0x0000F5D4 0x8E09 # 0 +0x0000F5D5 0x8DFD # 0 +0x0000F5D6 0x8E14 # 0 +0x0000F5D7 0x8E1D # 0 +0x0000F5D8 0x8E1F # 0 +0x0000F5D9 0x8E2C # 0 +0x0000F5DA 0x8E2E # 0 +0x0000F5DB 0x8E23 # 0 +0x0000F5DC 0x8E2F # 0 +0x0000F5DD 0x8E3A # 0 +0x0000F5DE 0x8E40 # 0 +0x0000F5DF 0x8E39 # 0 +0x0000F5E0 0x8E35 # 0 +0x0000F5E1 0x8E3D # 0 +0x0000F5E2 0x8E31 # 0 +0x0000F5E3 0x8E49 # 0 +0x0000F5E4 0x8E41 # 0 +0x0000F5E5 0x8E42 # 0 +0x0000F5E6 0x8E51 # 0 +0x0000F5E7 0x8E52 # 0 +0x0000F5E8 0x8E4A # 0 +0x0000F5E9 0x8E70 # 0 +0x0000F5EA 0x8E76 # 0 +0x0000F5EB 0x8E7C # 0 +0x0000F5EC 0x8E6F # 0 +0x0000F5ED 0x8E74 # 0 +0x0000F5EE 0x8E85 # 0 +0x0000F5EF 0x8E8F # 0 +0x0000F5F0 0x8E94 # 0 +0x0000F5F1 0x8E90 # 0 +0x0000F5F2 0x8E9C # 0 +0x0000F5F3 0x8E9E # 0 +0x0000F5F4 0x8C78 # 0 +0x0000F5F5 0x8C82 # 0 +0x0000F5F6 0x8C8A # 0 +0x0000F5F7 0x8C85 # 0 +0x0000F5F8 0x8C98 # 0 +0x0000F5F9 0x8C94 # 0 +0x0000F5FA 0x659B # 0 +0x0000F5FB 0x89D6 # 0 +0x0000F5FC 0x89DE # 0 +0x0000F5FD 0x89DA # 0 +0x0000F5FE 0x89DC # 0 +0x0000F6A1 0x89E5 # 0 +0x0000F6A2 0x89EB # 0 +0x0000F6A3 0x89EF # 0 +0x0000F6A4 0x8A3E # 0 +0x0000F6A5 0x8B26 # 0 +0x0000F6A6 0x9753 # 0 +0x0000F6A7 0x96E9 # 0 +0x0000F6A8 0x96F3 # 0 +0x0000F6A9 0x96EF # 0 +0x0000F6AA 0x9706 # 0 +0x0000F6AB 0x9701 # 0 +0x0000F6AC 0x9708 # 0 +0x0000F6AD 0x970F # 0 +0x0000F6AE 0x970E # 0 +0x0000F6AF 0x972A # 0 +0x0000F6B0 0x972D # 0 +0x0000F6B1 0x9730 # 0 +0x0000F6B2 0x973E # 0 +0x0000F6B3 0x9F80 # 0 +0x0000F6B4 0x9F83 # 0 +0x0000F6B5 0x9F85 # 0 +0x0000F6B6 0x9F86 # 0 +0x0000F6B7 0x9F87 # 0 +0x0000F6B8 0x9F88 # 0 +0x0000F6B9 0x9F89 # 0 +0x0000F6BA 0x9F8A # 0 +0x0000F6BB 0x9F8C # 0 +0x0000F6BC 0x9EFE # 0 +0x0000F6BD 0x9F0B # 0 +0x0000F6BE 0x9F0D # 0 +0x0000F6BF 0x96B9 # 0 +0x0000F6C0 0x96BC # 0 +0x0000F6C1 0x96BD # 0 +0x0000F6C2 0x96CE # 0 +0x0000F6C3 0x96D2 # 0 +0x0000F6C4 0x77BF # 0 +0x0000F6C5 0x96E0 # 0 +0x0000F6C6 0x928E # 0 +0x0000F6C7 0x92AE # 0 +0x0000F6C8 0x92C8 # 0 +0x0000F6C9 0x933E # 0 +0x0000F6CA 0x936A # 0 +0x0000F6CB 0x93CA # 0 +0x0000F6CC 0x938F # 0 +0x0000F6CD 0x943E # 0 +0x0000F6CE 0x946B # 0 +0x0000F6CF 0x9C7F # 0 +0x0000F6D0 0x9C82 # 0 +0x0000F6D1 0x9C85 # 0 +0x0000F6D2 0x9C86 # 0 +0x0000F6D3 0x9C87 # 0 +0x0000F6D4 0x9C88 # 0 +0x0000F6D5 0x7A23 # 0 +0x0000F6D6 0x9C8B # 0 +0x0000F6D7 0x9C8E # 0 +0x0000F6D8 0x9C90 # 0 +0x0000F6D9 0x9C91 # 0 +0x0000F6DA 0x9C92 # 0 +0x0000F6DB 0x9C94 # 0 +0x0000F6DC 0x9C95 # 0 +0x0000F6DD 0x9C9A # 0 +0x0000F6DE 0x9C9B # 0 +0x0000F6DF 0x9C9E # 0 +0x0000F6E0 0x9C9F # 0 +0x0000F6E1 0x9CA0 # 0 +0x0000F6E2 0x9CA1 # 0 +0x0000F6E3 0x9CA2 # 0 +0x0000F6E4 0x9CA3 # 0 +0x0000F6E5 0x9CA5 # 0 +0x0000F6E6 0x9CA6 # 0 +0x0000F6E7 0x9CA7 # 0 +0x0000F6E8 0x9CA8 # 0 +0x0000F6E9 0x9CA9 # 0 +0x0000F6EA 0x9CAB # 0 +0x0000F6EB 0x9CAD # 0 +0x0000F6EC 0x9CAE # 0 +0x0000F6ED 0x9CB0 # 0 +0x0000F6EE 0x9CB1 # 0 +0x0000F6EF 0x9CB2 # 0 +0x0000F6F0 0x9CB3 # 0 +0x0000F6F1 0x9CB4 # 0 +0x0000F6F2 0x9CB5 # 0 +0x0000F6F3 0x9CB6 # 0 +0x0000F6F4 0x9CB7 # 0 +0x0000F6F5 0x9CBA # 0 +0x0000F6F6 0x9CBB # 0 +0x0000F6F7 0x9CBC # 0 +0x0000F6F8 0x9CBD # 0 +0x0000F6F9 0x9CC4 # 0 +0x0000F6FA 0x9CC5 # 0 +0x0000F6FB 0x9CC6 # 0 +0x0000F6FC 0x9CC7 # 0 +0x0000F6FD 0x9CCA # 0 +0x0000F6FE 0x9CCB # 0 +0x0000F7A1 0x9CCC # 0 +0x0000F7A2 0x9CCD # 0 +0x0000F7A3 0x9CCE # 0 +0x0000F7A4 0x9CCF # 0 +0x0000F7A5 0x9CD0 # 0 +0x0000F7A6 0x9CD3 # 0 +0x0000F7A7 0x9CD4 # 0 +0x0000F7A8 0x9CD5 # 0 +0x0000F7A9 0x9CD7 # 0 +0x0000F7AA 0x9CD8 # 0 +0x0000F7AB 0x9CD9 # 0 +0x0000F7AC 0x9CDC # 0 +0x0000F7AD 0x9CDD # 0 +0x0000F7AE 0x9CDF # 0 +0x0000F7AF 0x9CE2 # 0 +0x0000F7B0 0x977C # 0 +0x0000F7B1 0x9785 # 0 +0x0000F7B2 0x9791 # 0 +0x0000F7B3 0x9792 # 0 +0x0000F7B4 0x9794 # 0 +0x0000F7B5 0x97AF # 0 +0x0000F7B6 0x97AB # 0 +0x0000F7B7 0x97A3 # 0 +0x0000F7B8 0x97B2 # 0 +0x0000F7B9 0x97B4 # 0 +0x0000F7BA 0x9AB1 # 0 +0x0000F7BB 0x9AB0 # 0 +0x0000F7BC 0x9AB7 # 0 +0x0000F7BD 0x9E58 # 0 +0x0000F7BE 0x9AB6 # 0 +0x0000F7BF 0x9ABA # 0 +0x0000F7C0 0x9ABC # 0 +0x0000F7C1 0x9AC1 # 0 +0x0000F7C2 0x9AC0 # 0 +0x0000F7C3 0x9AC5 # 0 +0x0000F7C4 0x9AC2 # 0 +0x0000F7C5 0x9ACB # 0 +0x0000F7C6 0x9ACC # 0 +0x0000F7C7 0x9AD1 # 0 +0x0000F7C8 0x9B45 # 0 +0x0000F7C9 0x9B43 # 0 +0x0000F7CA 0x9B47 # 0 +0x0000F7CB 0x9B49 # 0 +0x0000F7CC 0x9B48 # 0 +0x0000F7CD 0x9B4D # 0 +0x0000F7CE 0x9B51 # 0 +0x0000F7CF 0x98E8 # 0 +0x0000F7D0 0x990D # 0 +0x0000F7D1 0x992E # 0 +0x0000F7D2 0x9955 # 0 +0x0000F7D3 0x9954 # 0 +0x0000F7D4 0x9ADF # 0 +0x0000F7D5 0x9AE1 # 0 +0x0000F7D6 0x9AE6 # 0 +0x0000F7D7 0x9AEF # 0 +0x0000F7D8 0x9AEB # 0 +0x0000F7D9 0x9AFB # 0 +0x0000F7DA 0x9AED # 0 +0x0000F7DB 0x9AF9 # 0 +0x0000F7DC 0x9B08 # 0 +0x0000F7DD 0x9B0F # 0 +0x0000F7DE 0x9B13 # 0 +0x0000F7DF 0x9B1F # 0 +0x0000F7E0 0x9B23 # 0 +0x0000F7E1 0x9EBD # 0 +0x0000F7E2 0x9EBE # 0 +0x0000F7E3 0x7E3B # 0 +0x0000F7E4 0x9E82 # 0 +0x0000F7E5 0x9E87 # 0 +0x0000F7E6 0x9E88 # 0 +0x0000F7E7 0x9E8B # 0 +0x0000F7E8 0x9E92 # 0 +0x0000F7E9 0x93D6 # 0 +0x0000F7EA 0x9E9D # 0 +0x0000F7EB 0x9E9F # 0 +0x0000F7EC 0x9EDB # 0 +0x0000F7ED 0x9EDC # 0 +0x0000F7EE 0x9EDD # 0 +0x0000F7EF 0x9EE0 # 0 +0x0000F7F0 0x9EDF # 0 +0x0000F7F1 0x9EE2 # 0 +0x0000F7F2 0x9EE9 # 0 +0x0000F7F3 0x9EE7 # 0 +0x0000F7F4 0x9EE5 # 0 +0x0000F7F5 0x9EEA # 0 +0x0000F7F6 0x9EEF # 0 +0x0000F7F7 0x9F22 # 0 +0x0000F7F8 0x9F2C # 0 +0x0000F7F9 0x9F2F # 0 +0x0000F7FA 0x9F39 # 0 +0x0000F7FB 0x9F37 # 0 +0x0000F7FC 0x9F3D # 0 +0x0000F7FD 0x9F3E # 0 +0x0000F7FE 0x9F44 # 0 diff --git a/data/euc-jp.txt b/data/euc-jp.txt new file mode 100644 index 0000000000..87af725e32 --- /dev/null +++ b/data/euc-jp.txt @@ -0,0 +1,15184 @@ +# euc-jp.txt - EUC to Unicode charmap +0x00000000 0x0000 # 0 +0x00000001 0x0001 # 0 +0x00000002 0x0002 # 0 +0x00000003 0x0003 # 0 +0x00000004 0x0004 # 0 +0x00000005 0x0005 # 0 +0x00000006 0x0006 # 0 +0x00000007 0x0007 # 0 +0x00000008 0x0008 # 0 +0x00000009 0x0009 # 0 +0x0000000A 0x000A # 0 +0x0000000B 0x000B # 0 +0x0000000C 0x000C # 0 +0x0000000D 0x000D # 0 +0x0000000E 0x000E # 0 +0x0000000F 0x000F # 0 +0x00000010 0x0010 # 0 +0x00000011 0x0011 # 0 +0x00000012 0x0012 # 0 +0x00000013 0x0013 # 0 +0x00000014 0x0014 # 0 +0x00000015 0x0015 # 0 +0x00000016 0x0016 # 0 +0x00000017 0x0017 # 0 +0x00000018 0x0018 # 0 +0x00000019 0x0019 # 0 +0x0000001A 0x001A # 0 +0x0000001B 0x001B # 0 +0x0000001C 0x001C # 0 +0x0000001D 0x001D # 0 +0x0000001E 0x001E # 0 +0x0000001F 0x001F # 0 +0x00000020 0x0020 # 0 +0x00000021 0x0021 # 0 +0x00000022 0x0022 # 0 +0x00000023 0x0023 # 0 +0x00000024 0x0024 # 0 +0x00000025 0x0025 # 0 +0x00000026 0x0026 # 0 +0x00000027 0x0027 # 0 +0x00000028 0x0028 # 0 +0x00000029 0x0029 # 0 +0x0000002A 0x002A # 0 +0x0000002B 0x002B # 0 +0x0000002C 0x002C # 0 +0x0000002D 0x002D # 0 +0x0000002E 0x002E # 0 +0x0000002F 0x002F # 0 +0x00000030 0x0030 # 0 +0x00000031 0x0031 # 0 +0x00000032 0x0032 # 0 +0x00000033 0x0033 # 0 +0x00000034 0x0034 # 0 +0x00000035 0x0035 # 0 +0x00000036 0x0036 # 0 +0x00000037 0x0037 # 0 +0x00000038 0x0038 # 0 +0x00000039 0x0039 # 0 +0x0000003A 0x003A # 0 +0x0000003B 0x003B # 0 +0x0000003C 0x003C # 0 +0x0000003D 0x003D # 0 +0x0000003E 0x003E # 0 +0x0000003F 0x003F # 0 +0x00000040 0x0040 # 0 +0x00000041 0x0041 # 0 +0x00000042 0x0042 # 0 +0x00000043 0x0043 # 0 +0x00000044 0x0044 # 0 +0x00000045 0x0045 # 0 +0x00000046 0x0046 # 0 +0x00000047 0x0047 # 0 +0x00000048 0x0048 # 0 +0x00000049 0x0049 # 0 +0x0000004A 0x004A # 0 +0x0000004B 0x004B # 0 +0x0000004C 0x004C # 0 +0x0000004D 0x004D # 0 +0x0000004E 0x004E # 0 +0x0000004F 0x004F # 0 +0x00000050 0x0050 # 0 +0x00000051 0x0051 # 0 +0x00000052 0x0052 # 0 +0x00000053 0x0053 # 0 +0x00000054 0x0054 # 0 +0x00000055 0x0055 # 0 +0x00000056 0x0056 # 0 +0x00000057 0x0057 # 0 +0x00000058 0x0058 # 0 +0x00000059 0x0059 # 0 +0x0000005A 0x005A # 0 +0x0000005B 0x005B # 0 +0x0000005C 0x005C # 0 +0x0000005D 0x005D # 0 +0x0000005E 0x005E # 0 +0x0000005F 0x005F # 0 +0x00000060 0x0060 # 0 +0x00000061 0x0061 # 0 +0x00000062 0x0062 # 0 +0x00000063 0x0063 # 0 +0x00000064 0x0064 # 0 +0x00000065 0x0065 # 0 +0x00000066 0x0066 # 0 +0x00000067 0x0067 # 0 +0x00000068 0x0068 # 0 +0x00000069 0x0069 # 0 +0x0000006A 0x006A # 0 +0x0000006B 0x006B # 0 +0x0000006C 0x006C # 0 +0x0000006D 0x006D # 0 +0x0000006E 0x006E # 0 +0x0000006F 0x006F # 0 +0x00000070 0x0070 # 0 +0x00000071 0x0071 # 0 +0x00000072 0x0072 # 0 +0x00000073 0x0073 # 0 +0x00000074 0x0074 # 0 +0x00000075 0x0075 # 0 +0x00000076 0x0076 # 0 +0x00000077 0x0077 # 0 +0x00000078 0x0078 # 0 +0x00000079 0x0079 # 0 +0x0000007A 0x007A # 0 +0x0000007B 0x007B # 0 +0x0000007C 0x007C # 0 +0x0000007D 0x007D # 0 +0x0000007E 0x007E # 0 +0x0000007F 0x007F # 0 +0x00008EA1 0xFF61 # 0 +0x00008EA2 0xFF62 # 0 +0x00008EA3 0xFF63 # 0 +0x00008EA4 0xFF64 # 0 +0x00008EA5 0xFF65 # 0 +0x00008EA6 0xFF66 # 0 +0x00008EA7 0xFF67 # 0 +0x00008EA8 0xFF68 # 0 +0x00008EA9 0xFF69 # 0 +0x00008EAA 0xFF6A # 0 +0x00008EAB 0xFF6B # 0 +0x00008EAC 0xFF6C # 0 +0x00008EAD 0xFF6D # 0 +0x00008EAE 0xFF6E # 0 +0x00008EAF 0xFF6F # 0 +0x00008EB0 0xFF70 # 0 +0x00008EB1 0xFF71 # 0 +0x00008EB2 0xFF72 # 0 +0x00008EB3 0xFF73 # 0 +0x00008EB4 0xFF74 # 0 +0x00008EB5 0xFF75 # 0 +0x00008EB6 0xFF76 # 0 +0x00008EB7 0xFF77 # 0 +0x00008EB8 0xFF78 # 0 +0x00008EB9 0xFF79 # 0 +0x00008EBA 0xFF7A # 0 +0x00008EBB 0xFF7B # 0 +0x00008EBC 0xFF7C # 0 +0x00008EBD 0xFF7D # 0 +0x00008EBE 0xFF7E # 0 +0x00008EBF 0xFF7F # 0 +0x00008EC0 0xFF80 # 0 +0x00008EC1 0xFF81 # 0 +0x00008EC2 0xFF82 # 0 +0x00008EC3 0xFF83 # 0 +0x00008EC4 0xFF84 # 0 +0x00008EC5 0xFF85 # 0 +0x00008EC6 0xFF86 # 0 +0x00008EC7 0xFF87 # 0 +0x00008EC8 0xFF88 # 0 +0x00008EC9 0xFF89 # 0 +0x00008ECA 0xFF8A # 0 +0x00008ECB 0xFF8B # 0 +0x00008ECC 0xFF8C # 0 +0x00008ECD 0xFF8D # 0 +0x00008ECE 0xFF8E # 0 +0x00008ECF 0xFF8F # 0 +0x00008ED0 0xFF90 # 0 +0x00008ED1 0xFF91 # 0 +0x00008ED2 0xFF92 # 0 +0x00008ED3 0xFF93 # 0 +0x00008ED4 0xFF94 # 0 +0x00008ED5 0xFF95 # 0 +0x00008ED6 0xFF96 # 0 +0x00008ED7 0xFF97 # 0 +0x00008ED8 0xFF98 # 0 +0x00008ED9 0xFF99 # 0 +0x00008EDA 0xFF9A # 0 +0x00008EDB 0xFF9B # 0 +0x00008EDC 0xFF9C # 0 +0x00008EDD 0xFF9D # 0 +0x00008EDE 0xFF9E # 0 +0x00008EDF 0xFF9F # 0 +0x0000A1A1 0x3000 # 0 +0x0000A1A2 0x3001 # 0 +0x0000A1A3 0x3002 # 0 +0x0000A1A4 0xFF0C # 0 +0x0000A1A5 0xFF0E # 0 +0x0000A1A6 0x30FB # 0 +0x0000A1A7 0xFF1A # 0 +0x0000A1A8 0xFF1B # 0 +0x0000A1A9 0xFF1F # 0 +0x0000A1AA 0xFF01 # 0 +0x0000A1AB 0x309B # 0 +0x0000A1AC 0x309C # 0 +0x0000A1AD 0x00B4 # 0 +0x0000A1AE 0xFF40 # 0 +0x0000A1AF 0x00A8 # 0 +0x0000A1B0 0xFF3E # 0 +0x0000A1B1 0xFFE3 # 0 +0x0000A1B2 0xFF3F # 0 +0x0000A1B3 0x30FD # 0 +0x0000A1B4 0x30FE # 0 +0x0000A1B5 0x309D # 0 +0x0000A1B6 0x309E # 0 +0x0000A1B7 0x3003 # 0 +0x0000A1B8 0x4EDD # 0 +0x0000A1B9 0x3005 # 0 +0x0000A1BA 0x3006 # 0 +0x0000A1BB 0x3007 # 0 +0x0000A1BC 0x30FC # 0 +0x0000A1BD 0x2015 # 0 +0x0000A1BE 0x2010 # 0 +0x0000A1BF 0xFF0F # 0 +0x0000A1C0 0xFF3C # 0 +0x0000A1C1 0x301C # 0 +0x0000A1C2 0x2016 # 0 +0x0000A1C3 0xFF5C # 0 +0x0000A1C4 0x2026 # 0 +0x0000A1C5 0x2025 # 0 +0x0000A1C6 0x2018 # 0 +0x0000A1C7 0x2019 # 0 +0x0000A1C8 0x201C # 0 +0x0000A1C9 0x201D # 0 +0x0000A1CA 0xFF08 # 0 +0x0000A1CB 0xFF09 # 0 +0x0000A1CC 0x3014 # 0 +0x0000A1CD 0x3015 # 0 +0x0000A1CE 0xFF3B # 0 +0x0000A1CF 0xFF3D # 0 +0x0000A1D0 0xFF5B # 0 +0x0000A1D1 0xFF5D # 0 +0x0000A1D2 0x3008 # 0 +0x0000A1D3 0x3009 # 0 +0x0000A1D4 0x300A # 0 +0x0000A1D5 0x300B # 0 +0x0000A1D6 0x300C # 0 +0x0000A1D7 0x300D # 0 +0x0000A1D8 0x300E # 0 +0x0000A1D9 0x300F # 0 +0x0000A1DA 0x3010 # 0 +0x0000A1DB 0x3011 # 0 +0x0000A1DC 0xFF0B # 0 +0x0000A1DD 0x2212 # 0 +0x0000A1DE 0x00B1 # 0 +0x0000A1DF 0x00D7 # 0 +0x0000A1E0 0x00F7 # 0 +0x0000A1E1 0xFF1D # 0 +0x0000A1E2 0x2260 # 0 +0x0000A1E3 0xFF1C # 0 +0x0000A1E4 0xFF1E # 0 +0x0000A1E5 0x2266 # 0 +0x0000A1E6 0x2267 # 0 +0x0000A1E7 0x221E # 0 +0x0000A1E8 0x2234 # 0 +0x0000A1E9 0x2642 # 0 +0x0000A1EA 0x2640 # 0 +0x0000A1EB 0x00B0 # 0 +0x0000A1EC 0x2032 # 0 +0x0000A1ED 0x2033 # 0 +0x0000A1EE 0x2103 # 0 +0x0000A1EF 0xFFE5 # 0 +0x0000A1F0 0xFF04 # 0 +0x0000A1F1 0x00A2 # 0 +0x0000A1F2 0x00A3 # 0 +0x0000A1F3 0xFF05 # 0 +0x0000A1F4 0xFF03 # 0 +0x0000A1F5 0xFF06 # 0 +0x0000A1F6 0xFF0A # 0 +0x0000A1F7 0xFF20 # 0 +0x0000A1F8 0x00A7 # 0 +0x0000A1F9 0x2606 # 0 +0x0000A1FA 0x2605 # 0 +0x0000A1FB 0x25CB # 0 +0x0000A1FC 0x25CF # 0 +0x0000A1FD 0x25CE # 0 +0x0000A1FE 0x25C7 # 0 +0x0000A2A1 0x25C6 # 0 +0x0000A2A2 0x25A1 # 0 +0x0000A2A3 0x25A0 # 0 +0x0000A2A4 0x25B3 # 0 +0x0000A2A5 0x25B2 # 0 +0x0000A2A6 0x25BD # 0 +0x0000A2A7 0x25BC # 0 +0x0000A2A8 0x203B # 0 +0x0000A2A9 0x3012 # 0 +0x0000A2AA 0x2192 # 0 +0x0000A2AB 0x2190 # 0 +0x0000A2AC 0x2191 # 0 +0x0000A2AD 0x2193 # 0 +0x0000A2AE 0x3013 # 0 +0x0000A2BA 0x2208 # 0 +0x0000A2BB 0x220B # 0 +0x0000A2BC 0x2286 # 0 +0x0000A2BD 0x2287 # 0 +0x0000A2BE 0x2282 # 0 +0x0000A2BF 0x2283 # 0 +0x0000A2C0 0x222A # 0 +0x0000A2C1 0x2229 # 0 +0x0000A2CA 0x2227 # 0 +0x0000A2CB 0x2228 # 0 +0x0000A2CC 0x00AC # 0 +0x0000A2CD 0x21D2 # 0 +0x0000A2CE 0x21D4 # 0 +0x0000A2CF 0x2200 # 0 +0x0000A2D0 0x2203 # 0 +0x0000A2DC 0x2220 # 0 +0x0000A2DD 0x22A5 # 0 +0x0000A2DE 0x2312 # 0 +0x0000A2DF 0x2202 # 0 +0x0000A2E0 0x2207 # 0 +0x0000A2E1 0x2261 # 0 +0x0000A2E2 0x2252 # 0 +0x0000A2E3 0x226A # 0 +0x0000A2E4 0x226B # 0 +0x0000A2E5 0x221A # 0 +0x0000A2E6 0x223D # 0 +0x0000A2E7 0x221D # 0 +0x0000A2E8 0x2235 # 0 +0x0000A2E9 0x222B # 0 +0x0000A2EA 0x222C # 0 +0x0000A2F2 0x212B # 0 +0x0000A2F3 0x2030 # 0 +0x0000A2F4 0x266F # 0 +0x0000A2F5 0x266D # 0 +0x0000A2F6 0x266A # 0 +0x0000A2F7 0x2020 # 0 +0x0000A2F8 0x2021 # 0 +0x0000A2F9 0x00B6 # 0 +0x0000A2FE 0x25EF # 0 +0x0000A3B0 0xFF10 # 0 +0x0000A3B1 0xFF11 # 0 +0x0000A3B2 0xFF12 # 0 +0x0000A3B3 0xFF13 # 0 +0x0000A3B4 0xFF14 # 0 +0x0000A3B5 0xFF15 # 0 +0x0000A3B6 0xFF16 # 0 +0x0000A3B7 0xFF17 # 0 +0x0000A3B8 0xFF18 # 0 +0x0000A3B9 0xFF19 # 0 +0x0000A3C1 0xFF21 # 0 +0x0000A3C2 0xFF22 # 0 +0x0000A3C3 0xFF23 # 0 +0x0000A3C4 0xFF24 # 0 +0x0000A3C5 0xFF25 # 0 +0x0000A3C6 0xFF26 # 0 +0x0000A3C7 0xFF27 # 0 +0x0000A3C8 0xFF28 # 0 +0x0000A3C9 0xFF29 # 0 +0x0000A3CA 0xFF2A # 0 +0x0000A3CB 0xFF2B # 0 +0x0000A3CC 0xFF2C # 0 +0x0000A3CD 0xFF2D # 0 +0x0000A3CE 0xFF2E # 0 +0x0000A3CF 0xFF2F # 0 +0x0000A3D0 0xFF30 # 0 +0x0000A3D1 0xFF31 # 0 +0x0000A3D2 0xFF32 # 0 +0x0000A3D3 0xFF33 # 0 +0x0000A3D4 0xFF34 # 0 +0x0000A3D5 0xFF35 # 0 +0x0000A3D6 0xFF36 # 0 +0x0000A3D7 0xFF37 # 0 +0x0000A3D8 0xFF38 # 0 +0x0000A3D9 0xFF39 # 0 +0x0000A3DA 0xFF3A # 0 +0x0000A3E1 0xFF41 # 0 +0x0000A3E2 0xFF42 # 0 +0x0000A3E3 0xFF43 # 0 +0x0000A3E4 0xFF44 # 0 +0x0000A3E5 0xFF45 # 0 +0x0000A3E6 0xFF46 # 0 +0x0000A3E7 0xFF47 # 0 +0x0000A3E8 0xFF48 # 0 +0x0000A3E9 0xFF49 # 0 +0x0000A3EA 0xFF4A # 0 +0x0000A3EB 0xFF4B # 0 +0x0000A3EC 0xFF4C # 0 +0x0000A3ED 0xFF4D # 0 +0x0000A3EE 0xFF4E # 0 +0x0000A3EF 0xFF4F # 0 +0x0000A3F0 0xFF50 # 0 +0x0000A3F1 0xFF51 # 0 +0x0000A3F2 0xFF52 # 0 +0x0000A3F3 0xFF53 # 0 +0x0000A3F4 0xFF54 # 0 +0x0000A3F5 0xFF55 # 0 +0x0000A3F6 0xFF56 # 0 +0x0000A3F7 0xFF57 # 0 +0x0000A3F8 0xFF58 # 0 +0x0000A3F9 0xFF59 # 0 +0x0000A3FA 0xFF5A # 0 +0x0000A4A1 0x3041 # 0 +0x0000A4A2 0x3042 # 0 +0x0000A4A3 0x3043 # 0 +0x0000A4A4 0x3044 # 0 +0x0000A4A5 0x3045 # 0 +0x0000A4A6 0x3046 # 0 +0x0000A4A7 0x3047 # 0 +0x0000A4A8 0x3048 # 0 +0x0000A4A9 0x3049 # 0 +0x0000A4AA 0x304A # 0 +0x0000A4AB 0x304B # 0 +0x0000A4AC 0x304C # 0 +0x0000A4AD 0x304D # 0 +0x0000A4AE 0x304E # 0 +0x0000A4AF 0x304F # 0 +0x0000A4B0 0x3050 # 0 +0x0000A4B1 0x3051 # 0 +0x0000A4B2 0x3052 # 0 +0x0000A4B3 0x3053 # 0 +0x0000A4B4 0x3054 # 0 +0x0000A4B5 0x3055 # 0 +0x0000A4B6 0x3056 # 0 +0x0000A4B7 0x3057 # 0 +0x0000A4B8 0x3058 # 0 +0x0000A4B9 0x3059 # 0 +0x0000A4BA 0x305A # 0 +0x0000A4BB 0x305B # 0 +0x0000A4BC 0x305C # 0 +0x0000A4BD 0x305D # 0 +0x0000A4BE 0x305E # 0 +0x0000A4BF 0x305F # 0 +0x0000A4C0 0x3060 # 0 +0x0000A4C1 0x3061 # 0 +0x0000A4C2 0x3062 # 0 +0x0000A4C3 0x3063 # 0 +0x0000A4C4 0x3064 # 0 +0x0000A4C5 0x3065 # 0 +0x0000A4C6 0x3066 # 0 +0x0000A4C7 0x3067 # 0 +0x0000A4C8 0x3068 # 0 +0x0000A4C9 0x3069 # 0 +0x0000A4CA 0x306A # 0 +0x0000A4CB 0x306B # 0 +0x0000A4CC 0x306C # 0 +0x0000A4CD 0x306D # 0 +0x0000A4CE 0x306E # 0 +0x0000A4CF 0x306F # 0 +0x0000A4D0 0x3070 # 0 +0x0000A4D1 0x3071 # 0 +0x0000A4D2 0x3072 # 0 +0x0000A4D3 0x3073 # 0 +0x0000A4D4 0x3074 # 0 +0x0000A4D5 0x3075 # 0 +0x0000A4D6 0x3076 # 0 +0x0000A4D7 0x3077 # 0 +0x0000A4D8 0x3078 # 0 +0x0000A4D9 0x3079 # 0 +0x0000A4DA 0x307A # 0 +0x0000A4DB 0x307B # 0 +0x0000A4DC 0x307C # 0 +0x0000A4DD 0x307D # 0 +0x0000A4DE 0x307E # 0 +0x0000A4DF 0x307F # 0 +0x0000A4E0 0x3080 # 0 +0x0000A4E1 0x3081 # 0 +0x0000A4E2 0x3082 # 0 +0x0000A4E3 0x3083 # 0 +0x0000A4E4 0x3084 # 0 +0x0000A4E5 0x3085 # 0 +0x0000A4E6 0x3086 # 0 +0x0000A4E7 0x3087 # 0 +0x0000A4E8 0x3088 # 0 +0x0000A4E9 0x3089 # 0 +0x0000A4EA 0x308A # 0 +0x0000A4EB 0x308B # 0 +0x0000A4EC 0x308C # 0 +0x0000A4ED 0x308D # 0 +0x0000A4EE 0x308E # 0 +0x0000A4EF 0x308F # 0 +0x0000A4F0 0x3090 # 0 +0x0000A4F1 0x3091 # 0 +0x0000A4F2 0x3092 # 0 +0x0000A4F3 0x3093 # 0 +0x0000A5A1 0x30A1 # 0 +0x0000A5A2 0x30A2 # 0 +0x0000A5A3 0x30A3 # 0 +0x0000A5A4 0x30A4 # 0 +0x0000A5A5 0x30A5 # 0 +0x0000A5A6 0x30A6 # 0 +0x0000A5A7 0x30A7 # 0 +0x0000A5A8 0x30A8 # 0 +0x0000A5A9 0x30A9 # 0 +0x0000A5AA 0x30AA # 0 +0x0000A5AB 0x30AB # 0 +0x0000A5AC 0x30AC # 0 +0x0000A5AD 0x30AD # 0 +0x0000A5AE 0x30AE # 0 +0x0000A5AF 0x30AF # 0 +0x0000A5B0 0x30B0 # 0 +0x0000A5B1 0x30B1 # 0 +0x0000A5B2 0x30B2 # 0 +0x0000A5B3 0x30B3 # 0 +0x0000A5B4 0x30B4 # 0 +0x0000A5B5 0x30B5 # 0 +0x0000A5B6 0x30B6 # 0 +0x0000A5B7 0x30B7 # 0 +0x0000A5B8 0x30B8 # 0 +0x0000A5B9 0x30B9 # 0 +0x0000A5BA 0x30BA # 0 +0x0000A5BB 0x30BB # 0 +0x0000A5BC 0x30BC # 0 +0x0000A5BD 0x30BD # 0 +0x0000A5BE 0x30BE # 0 +0x0000A5BF 0x30BF # 0 +0x0000A5C0 0x30C0 # 0 +0x0000A5C1 0x30C1 # 0 +0x0000A5C2 0x30C2 # 0 +0x0000A5C3 0x30C3 # 0 +0x0000A5C4 0x30C4 # 0 +0x0000A5C5 0x30C5 # 0 +0x0000A5C6 0x30C6 # 0 +0x0000A5C7 0x30C7 # 0 +0x0000A5C8 0x30C8 # 0 +0x0000A5C9 0x30C9 # 0 +0x0000A5CA 0x30CA # 0 +0x0000A5CB 0x30CB # 0 +0x0000A5CC 0x30CC # 0 +0x0000A5CD 0x30CD # 0 +0x0000A5CE 0x30CE # 0 +0x0000A5CF 0x30CF # 0 +0x0000A5D0 0x30D0 # 0 +0x0000A5D1 0x30D1 # 0 +0x0000A5D2 0x30D2 # 0 +0x0000A5D3 0x30D3 # 0 +0x0000A5D4 0x30D4 # 0 +0x0000A5D5 0x30D5 # 0 +0x0000A5D6 0x30D6 # 0 +0x0000A5D7 0x30D7 # 0 +0x0000A5D8 0x30D8 # 0 +0x0000A5D9 0x30D9 # 0 +0x0000A5DA 0x30DA # 0 +0x0000A5DB 0x30DB # 0 +0x0000A5DC 0x30DC # 0 +0x0000A5DD 0x30DD # 0 +0x0000A5DE 0x30DE # 0 +0x0000A5DF 0x30DF # 0 +0x0000A5E0 0x30E0 # 0 +0x0000A5E1 0x30E1 # 0 +0x0000A5E2 0x30E2 # 0 +0x0000A5E3 0x30E3 # 0 +0x0000A5E4 0x30E4 # 0 +0x0000A5E5 0x30E5 # 0 +0x0000A5E6 0x30E6 # 0 +0x0000A5E7 0x30E7 # 0 +0x0000A5E8 0x30E8 # 0 +0x0000A5E9 0x30E9 # 0 +0x0000A5EA 0x30EA # 0 +0x0000A5EB 0x30EB # 0 +0x0000A5EC 0x30EC # 0 +0x0000A5ED 0x30ED # 0 +0x0000A5EE 0x30EE # 0 +0x0000A5EF 0x30EF # 0 +0x0000A5F0 0x30F0 # 0 +0x0000A5F1 0x30F1 # 0 +0x0000A5F2 0x30F2 # 0 +0x0000A5F3 0x30F3 # 0 +0x0000A5F4 0x30F4 # 0 +0x0000A5F5 0x30F5 # 0 +0x0000A5F6 0x30F6 # 0 +0x0000A6A1 0x0391 # 0 +0x0000A6A2 0x0392 # 0 +0x0000A6A3 0x0393 # 0 +0x0000A6A4 0x0394 # 0 +0x0000A6A5 0x0395 # 0 +0x0000A6A6 0x0396 # 0 +0x0000A6A7 0x0397 # 0 +0x0000A6A8 0x0398 # 0 +0x0000A6A9 0x0399 # 0 +0x0000A6AA 0x039A # 0 +0x0000A6AB 0x039B # 0 +0x0000A6AC 0x039C # 0 +0x0000A6AD 0x039D # 0 +0x0000A6AE 0x039E # 0 +0x0000A6AF 0x039F # 0 +0x0000A6B0 0x03A0 # 0 +0x0000A6B1 0x03A1 # 0 +0x0000A6B2 0x03A3 # 0 +0x0000A6B3 0x03A4 # 0 +0x0000A6B4 0x03A5 # 0 +0x0000A6B5 0x03A6 # 0 +0x0000A6B6 0x03A7 # 0 +0x0000A6B7 0x03A8 # 0 +0x0000A6B8 0x03A9 # 0 +0x0000A6C1 0x03B1 # 0 +0x0000A6C2 0x03B2 # 0 +0x0000A6C3 0x03B3 # 0 +0x0000A6C4 0x03B4 # 0 +0x0000A6C5 0x03B5 # 0 +0x0000A6C6 0x03B6 # 0 +0x0000A6C7 0x03B7 # 0 +0x0000A6C8 0x03B8 # 0 +0x0000A6C9 0x03B9 # 0 +0x0000A6CA 0x03BA # 0 +0x0000A6CB 0x03BB # 0 +0x0000A6CC 0x03BC # 0 +0x0000A6CD 0x03BD # 0 +0x0000A6CE 0x03BE # 0 +0x0000A6CF 0x03BF # 0 +0x0000A6D0 0x03C0 # 0 +0x0000A6D1 0x03C1 # 0 +0x0000A6D2 0x03C3 # 0 +0x0000A6D3 0x03C4 # 0 +0x0000A6D4 0x03C5 # 0 +0x0000A6D5 0x03C6 # 0 +0x0000A6D6 0x03C7 # 0 +0x0000A6D7 0x03C8 # 0 +0x0000A6D8 0x03C9 # 0 +0x0000A7A1 0x0410 # 0 +0x0000A7A2 0x0411 # 0 +0x0000A7A3 0x0412 # 0 +0x0000A7A4 0x0413 # 0 +0x0000A7A5 0x0414 # 0 +0x0000A7A6 0x0415 # 0 +0x0000A7A7 0x0401 # 0 +0x0000A7A8 0x0416 # 0 +0x0000A7A9 0x0417 # 0 +0x0000A7AA 0x0418 # 0 +0x0000A7AB 0x0419 # 0 +0x0000A7AC 0x041A # 0 +0x0000A7AD 0x041B # 0 +0x0000A7AE 0x041C # 0 +0x0000A7AF 0x041D # 0 +0x0000A7B0 0x041E # 0 +0x0000A7B1 0x041F # 0 +0x0000A7B2 0x0420 # 0 +0x0000A7B3 0x0421 # 0 +0x0000A7B4 0x0422 # 0 +0x0000A7B5 0x0423 # 0 +0x0000A7B6 0x0424 # 0 +0x0000A7B7 0x0425 # 0 +0x0000A7B8 0x0426 # 0 +0x0000A7B9 0x0427 # 0 +0x0000A7BA 0x0428 # 0 +0x0000A7BB 0x0429 # 0 +0x0000A7BC 0x042A # 0 +0x0000A7BD 0x042B # 0 +0x0000A7BE 0x042C # 0 +0x0000A7BF 0x042D # 0 +0x0000A7C0 0x042E # 0 +0x0000A7C1 0x042F # 0 +0x0000A7D1 0x0430 # 0 +0x0000A7D2 0x0431 # 0 +0x0000A7D3 0x0432 # 0 +0x0000A7D4 0x0433 # 0 +0x0000A7D5 0x0434 # 0 +0x0000A7D6 0x0435 # 0 +0x0000A7D7 0x0451 # 0 +0x0000A7D8 0x0436 # 0 +0x0000A7D9 0x0437 # 0 +0x0000A7DA 0x0438 # 0 +0x0000A7DB 0x0439 # 0 +0x0000A7DC 0x043A # 0 +0x0000A7DD 0x043B # 0 +0x0000A7DE 0x043C # 0 +0x0000A7DF 0x043D # 0 +0x0000A7E0 0x043E # 0 +0x0000A7E1 0x043F # 0 +0x0000A7E2 0x0440 # 0 +0x0000A7E3 0x0441 # 0 +0x0000A7E4 0x0442 # 0 +0x0000A7E5 0x0443 # 0 +0x0000A7E6 0x0444 # 0 +0x0000A7E7 0x0445 # 0 +0x0000A7E8 0x0446 # 0 +0x0000A7E9 0x0447 # 0 +0x0000A7EA 0x0448 # 0 +0x0000A7EB 0x0449 # 0 +0x0000A7EC 0x044A # 0 +0x0000A7ED 0x044B # 0 +0x0000A7EE 0x044C # 0 +0x0000A7EF 0x044D # 0 +0x0000A7F0 0x044E # 0 +0x0000A7F1 0x044F # 0 +0x0000A8A1 0x2500 # 0 +0x0000A8A2 0x2502 # 0 +0x0000A8A3 0x250C # 0 +0x0000A8A4 0x2510 # 0 +0x0000A8A5 0x2518 # 0 +0x0000A8A6 0x2514 # 0 +0x0000A8A7 0x251C # 0 +0x0000A8A8 0x252C # 0 +0x0000A8A9 0x2524 # 0 +0x0000A8AA 0x2534 # 0 +0x0000A8AB 0x253C # 0 +0x0000A8AC 0x2501 # 0 +0x0000A8AD 0x2503 # 0 +0x0000A8AE 0x250F # 0 +0x0000A8AF 0x2513 # 0 +0x0000A8B0 0x251B # 0 +0x0000A8B1 0x2517 # 0 +0x0000A8B2 0x2523 # 0 +0x0000A8B3 0x2533 # 0 +0x0000A8B4 0x252B # 0 +0x0000A8B5 0x253B # 0 +0x0000A8B6 0x254B # 0 +0x0000A8B7 0x2520 # 0 +0x0000A8B8 0x252F # 0 +0x0000A8B9 0x2528 # 0 +0x0000A8BA 0x2537 # 0 +0x0000A8BB 0x253F # 0 +0x0000A8BC 0x251D # 0 +0x0000A8BD 0x2530 # 0 +0x0000A8BE 0x2525 # 0 +0x0000A8BF 0x2538 # 0 +0x0000A8C0 0x2542 # 0 +0x0000ADA1 0x2460 # 0 +0x0000ADA2 0x2461 # 0 +0x0000ADA3 0x2462 # 0 +0x0000ADA4 0x2463 # 0 +0x0000ADA5 0x2464 # 0 +0x0000ADA6 0x2465 # 0 +0x0000ADA7 0x2466 # 0 +0x0000ADA8 0x2467 # 0 +0x0000ADA9 0x2468 # 0 +0x0000ADAA 0x2469 # 0 +0x0000ADAB 0x246A # 0 +0x0000ADAC 0x246B # 0 +0x0000ADAD 0x246C # 0 +0x0000ADAE 0x246D # 0 +0x0000ADAF 0x246E # 0 +0x0000ADB0 0x246F # 0 +0x0000ADB1 0x2470 # 0 +0x0000ADB2 0x2471 # 0 +0x0000ADB3 0x2472 # 0 +0x0000ADB4 0x2473 # 0 +0x0000ADB5 0x2160 # 0 +0x0000ADB6 0x2161 # 0 +0x0000ADB7 0x2162 # 0 +0x0000ADB8 0x2163 # 0 +0x0000ADB9 0x2164 # 0 +0x0000ADBA 0x2165 # 0 +0x0000ADBB 0x2166 # 0 +0x0000ADBC 0x2167 # 0 +0x0000ADBD 0x2168 # 0 +0x0000ADBE 0x2169 # 0 +0x0000ADC0 0x3349 # 0 +0x0000ADC1 0x3314 # 0 +0x0000ADC2 0x3322 # 0 +0x0000ADC3 0x334D # 0 +0x0000ADC4 0x3318 # 0 +0x0000ADC5 0x3327 # 0 +0x0000ADC6 0x3303 # 0 +0x0000ADC7 0x3336 # 0 +0x0000ADC8 0x3351 # 0 +0x0000ADC9 0x3357 # 0 +0x0000ADCA 0x330D # 0 +0x0000ADCB 0x3326 # 0 +0x0000ADCC 0x3323 # 0 +0x0000ADCD 0x332B # 0 +0x0000ADCE 0x334A # 0 +0x0000ADCF 0x333B # 0 +0x0000ADD0 0x339C # 0 +0x0000ADD1 0x339D # 0 +0x0000ADD2 0x339E # 0 +0x0000ADD3 0x338E # 0 +0x0000ADD4 0x338F # 0 +0x0000ADD5 0x33C4 # 0 +0x0000ADD6 0x33A1 # 0 +0x0000ADDF 0x337B # 0 +0x0000ADE0 0x301D # 0 +0x0000ADE1 0x301F # 0 +0x0000ADE3 0x33CD # 0 +0x0000ADE4 0x2121 # 0 +0x0000ADE5 0x32A4 # 0 +0x0000ADE6 0x32A5 # 0 +0x0000ADE7 0x32A6 # 0 +0x0000ADE8 0x32A7 # 0 +0x0000ADE9 0x32A8 # 0 +0x0000ADEA 0x3231 # 0 +0x0000ADEB 0x3232 # 0 +0x0000ADEC 0x3239 # 0 +0x0000ADED 0x337E # 0 +0x0000ADEE 0x337D # 0 +0x0000ADEF 0x337C # 0 +0x0000ADF3 0x222E # 0 +0x0000ADF4 0x2211 # 0 +0x0000ADF8 0x221F # 0 +0x0000ADF9 0x22BF # 0 +0x0000B0A1 0x4E9C # 0 +0x0000B0A2 0x5516 # 0 +0x0000B0A3 0x5A03 # 0 +0x0000B0A4 0x963F # 0 +0x0000B0A5 0x54C0 # 0 +0x0000B0A6 0x611B # 0 +0x0000B0A7 0x6328 # 0 +0x0000B0A8 0x59F6 # 0 +0x0000B0A9 0x9022 # 0 +0x0000B0AA 0x8475 # 0 +0x0000B0AB 0x831C # 0 +0x0000B0AC 0x7A50 # 0 +0x0000B0AD 0x60AA # 0 +0x0000B0AE 0x63E1 # 0 +0x0000B0AF 0x6E25 # 0 +0x0000B0B0 0x65ED # 0 +0x0000B0B1 0x8466 # 0 +0x0000B0B2 0x82A6 # 0 +0x0000B0B3 0x9BF5 # 0 +0x0000B0B4 0x6893 # 0 +0x0000B0B5 0x5727 # 0 +0x0000B0B6 0x65A1 # 0 +0x0000B0B7 0x6271 # 0 +0x0000B0B8 0x5B9B # 0 +0x0000B0B9 0x59D0 # 0 +0x0000B0BA 0x867B # 0 +0x0000B0BB 0x98F4 # 0 +0x0000B0BC 0x7D62 # 0 +0x0000B0BD 0x7DBE # 0 +0x0000B0BE 0x9B8E # 0 +0x0000B0BF 0x6216 # 0 +0x0000B0C0 0x7C9F # 0 +0x0000B0C1 0x88B7 # 0 +0x0000B0C2 0x5B89 # 0 +0x0000B0C3 0x5EB5 # 0 +0x0000B0C4 0x6309 # 0 +0x0000B0C5 0x6697 # 0 +0x0000B0C6 0x6848 # 0 +0x0000B0C7 0x95C7 # 0 +0x0000B0C8 0x978D # 0 +0x0000B0C9 0x674F # 0 +0x0000B0CA 0x4EE5 # 0 +0x0000B0CB 0x4F0A # 0 +0x0000B0CC 0x4F4D # 0 +0x0000B0CD 0x4F9D # 0 +0x0000B0CE 0x5049 # 0 +0x0000B0CF 0x56F2 # 0 +0x0000B0D0 0x5937 # 0 +0x0000B0D1 0x59D4 # 0 +0x0000B0D2 0x5A01 # 0 +0x0000B0D3 0x5C09 # 0 +0x0000B0D4 0x60DF # 0 +0x0000B0D5 0x610F # 0 +0x0000B0D6 0x6170 # 0 +0x0000B0D7 0x6613 # 0 +0x0000B0D8 0x6905 # 0 +0x0000B0D9 0x70BA # 0 +0x0000B0DA 0x754F # 0 +0x0000B0DB 0x7570 # 0 +0x0000B0DC 0x79FB # 0 +0x0000B0DD 0x7DAD # 0 +0x0000B0DE 0x7DEF # 0 +0x0000B0DF 0x80C3 # 0 +0x0000B0E0 0x840E # 0 +0x0000B0E1 0x8863 # 0 +0x0000B0E2 0x8B02 # 0 +0x0000B0E3 0x9055 # 0 +0x0000B0E4 0x907A # 0 +0x0000B0E5 0x533B # 0 +0x0000B0E6 0x4E95 # 0 +0x0000B0E7 0x4EA5 # 0 +0x0000B0E8 0x57DF # 0 +0x0000B0E9 0x80B2 # 0 +0x0000B0EA 0x90C1 # 0 +0x0000B0EB 0x78EF # 0 +0x0000B0EC 0x4E00 # 0 +0x0000B0ED 0x58F1 # 0 +0x0000B0EE 0x6EA2 # 0 +0x0000B0EF 0x9038 # 0 +0x0000B0F0 0x7A32 # 0 +0x0000B0F1 0x8328 # 0 +0x0000B0F2 0x828B # 0 +0x0000B0F3 0x9C2F # 0 +0x0000B0F4 0x5141 # 0 +0x0000B0F5 0x5370 # 0 +0x0000B0F6 0x54BD # 0 +0x0000B0F7 0x54E1 # 0 +0x0000B0F8 0x56E0 # 0 +0x0000B0F9 0x59FB # 0 +0x0000B0FA 0x5F15 # 0 +0x0000B0FB 0x98F2 # 0 +0x0000B0FC 0x6DEB # 0 +0x0000B0FD 0x80E4 # 0 +0x0000B0FE 0x852D # 0 +0x0000B1A1 0x9662 # 0 +0x0000B1A2 0x9670 # 0 +0x0000B1A3 0x96A0 # 0 +0x0000B1A4 0x97FB # 0 +0x0000B1A5 0x540B # 0 +0x0000B1A6 0x53F3 # 0 +0x0000B1A7 0x5B87 # 0 +0x0000B1A8 0x70CF # 0 +0x0000B1A9 0x7FBD # 0 +0x0000B1AA 0x8FC2 # 0 +0x0000B1AB 0x96E8 # 0 +0x0000B1AC 0x536F # 0 +0x0000B1AD 0x9D5C # 0 +0x0000B1AE 0x7ABA # 0 +0x0000B1AF 0x4E11 # 0 +0x0000B1B0 0x7893 # 0 +0x0000B1B1 0x81FC # 0 +0x0000B1B2 0x6E26 # 0 +0x0000B1B3 0x5618 # 0 +0x0000B1B4 0x5504 # 0 +0x0000B1B5 0x6B1D # 0 +0x0000B1B6 0x851A # 0 +0x0000B1B7 0x9C3B # 0 +0x0000B1B8 0x59E5 # 0 +0x0000B1B9 0x53A9 # 0 +0x0000B1BA 0x6D66 # 0 +0x0000B1BB 0x74DC # 0 +0x0000B1BC 0x958F # 0 +0x0000B1BD 0x5642 # 0 +0x0000B1BE 0x4E91 # 0 +0x0000B1BF 0x904B # 0 +0x0000B1C0 0x96F2 # 0 +0x0000B1C1 0x834F # 0 +0x0000B1C2 0x990C # 0 +0x0000B1C3 0x53E1 # 0 +0x0000B1C4 0x55B6 # 0 +0x0000B1C5 0x5B30 # 0 +0x0000B1C6 0x5F71 # 0 +0x0000B1C7 0x6620 # 0 +0x0000B1C8 0x66F3 # 0 +0x0000B1C9 0x6804 # 0 +0x0000B1CA 0x6C38 # 0 +0x0000B1CB 0x6CF3 # 0 +0x0000B1CC 0x6D29 # 0 +0x0000B1CD 0x745B # 0 +0x0000B1CE 0x76C8 # 0 +0x0000B1CF 0x7A4E # 0 +0x0000B1D0 0x9834 # 0 +0x0000B1D1 0x82F1 # 0 +0x0000B1D2 0x885B # 0 +0x0000B1D3 0x8A60 # 0 +0x0000B1D4 0x92ED # 0 +0x0000B1D5 0x6DB2 # 0 +0x0000B1D6 0x75AB # 0 +0x0000B1D7 0x76CA # 0 +0x0000B1D8 0x99C5 # 0 +0x0000B1D9 0x60A6 # 0 +0x0000B1DA 0x8B01 # 0 +0x0000B1DB 0x8D8A # 0 +0x0000B1DC 0x95B2 # 0 +0x0000B1DD 0x698E # 0 +0x0000B1DE 0x53AD # 0 +0x0000B1DF 0x5186 # 0 +0x0000B1E0 0x5712 # 0 +0x0000B1E1 0x5830 # 0 +0x0000B1E2 0x5944 # 0 +0x0000B1E3 0x5BB4 # 0 +0x0000B1E4 0x5EF6 # 0 +0x0000B1E5 0x6028 # 0 +0x0000B1E6 0x63A9 # 0 +0x0000B1E7 0x63F4 # 0 +0x0000B1E8 0x6CBF # 0 +0x0000B1E9 0x6F14 # 0 +0x0000B1EA 0x708E # 0 +0x0000B1EB 0x7114 # 0 +0x0000B1EC 0x7159 # 0 +0x0000B1ED 0x71D5 # 0 +0x0000B1EE 0x733F # 0 +0x0000B1EF 0x7E01 # 0 +0x0000B1F0 0x8276 # 0 +0x0000B1F1 0x82D1 # 0 +0x0000B1F2 0x8597 # 0 +0x0000B1F3 0x9060 # 0 +0x0000B1F4 0x925B # 0 +0x0000B1F5 0x9D1B # 0 +0x0000B1F6 0x5869 # 0 +0x0000B1F7 0x65BC # 0 +0x0000B1F8 0x6C5A # 0 +0x0000B1F9 0x7525 # 0 +0x0000B1FA 0x51F9 # 0 +0x0000B1FB 0x592E # 0 +0x0000B1FC 0x5965 # 0 +0x0000B1FD 0x5F80 # 0 +0x0000B1FE 0x5FDC # 0 +0x0000B2A1 0x62BC # 0 +0x0000B2A2 0x65FA # 0 +0x0000B2A3 0x6A2A # 0 +0x0000B2A4 0x6B27 # 0 +0x0000B2A5 0x6BB4 # 0 +0x0000B2A6 0x738B # 0 +0x0000B2A7 0x7FC1 # 0 +0x0000B2A8 0x8956 # 0 +0x0000B2A9 0x9D2C # 0 +0x0000B2AA 0x9D0E # 0 +0x0000B2AB 0x9EC4 # 0 +0x0000B2AC 0x5CA1 # 0 +0x0000B2AD 0x6C96 # 0 +0x0000B2AE 0x837B # 0 +0x0000B2AF 0x5104 # 0 +0x0000B2B0 0x5C4B # 0 +0x0000B2B1 0x61B6 # 0 +0x0000B2B2 0x81C6 # 0 +0x0000B2B3 0x6876 # 0 +0x0000B2B4 0x7261 # 0 +0x0000B2B5 0x4E59 # 0 +0x0000B2B6 0x4FFA # 0 +0x0000B2B7 0x5378 # 0 +0x0000B2B8 0x6069 # 0 +0x0000B2B9 0x6E29 # 0 +0x0000B2BA 0x7A4F # 0 +0x0000B2BB 0x97F3 # 0 +0x0000B2BC 0x4E0B # 0 +0x0000B2BD 0x5316 # 0 +0x0000B2BE 0x4EEE # 0 +0x0000B2BF 0x4F55 # 0 +0x0000B2C0 0x4F3D # 0 +0x0000B2C1 0x4FA1 # 0 +0x0000B2C2 0x4F73 # 0 +0x0000B2C3 0x52A0 # 0 +0x0000B2C4 0x53EF # 0 +0x0000B2C5 0x5609 # 0 +0x0000B2C6 0x590F # 0 +0x0000B2C7 0x5AC1 # 0 +0x0000B2C8 0x5BB6 # 0 +0x0000B2C9 0x5BE1 # 0 +0x0000B2CA 0x79D1 # 0 +0x0000B2CB 0x6687 # 0 +0x0000B2CC 0x679C # 0 +0x0000B2CD 0x67B6 # 0 +0x0000B2CE 0x6B4C # 0 +0x0000B2CF 0x6CB3 # 0 +0x0000B2D0 0x706B # 0 +0x0000B2D1 0x73C2 # 0 +0x0000B2D2 0x798D # 0 +0x0000B2D3 0x79BE # 0 +0x0000B2D4 0x7A3C # 0 +0x0000B2D5 0x7B87 # 0 +0x0000B2D6 0x82B1 # 0 +0x0000B2D7 0x82DB # 0 +0x0000B2D8 0x8304 # 0 +0x0000B2D9 0x8377 # 0 +0x0000B2DA 0x83EF # 0 +0x0000B2DB 0x83D3 # 0 +0x0000B2DC 0x8766 # 0 +0x0000B2DD 0x8AB2 # 0 +0x0000B2DE 0x5629 # 0 +0x0000B2DF 0x8CA8 # 0 +0x0000B2E0 0x8FE6 # 0 +0x0000B2E1 0x904E # 0 +0x0000B2E2 0x971E # 0 +0x0000B2E3 0x868A # 0 +0x0000B2E4 0x4FC4 # 0 +0x0000B2E5 0x5CE8 # 0 +0x0000B2E6 0x6211 # 0 +0x0000B2E7 0x7259 # 0 +0x0000B2E8 0x753B # 0 +0x0000B2E9 0x81E5 # 0 +0x0000B2EA 0x82BD # 0 +0x0000B2EB 0x86FE # 0 +0x0000B2EC 0x8CC0 # 0 +0x0000B2ED 0x96C5 # 0 +0x0000B2EE 0x9913 # 0 +0x0000B2EF 0x99D5 # 0 +0x0000B2F0 0x4ECB # 0 +0x0000B2F1 0x4F1A # 0 +0x0000B2F2 0x89E3 # 0 +0x0000B2F3 0x56DE # 0 +0x0000B2F4 0x584A # 0 +0x0000B2F5 0x58CA # 0 +0x0000B2F6 0x5EFB # 0 +0x0000B2F7 0x5FEB # 0 +0x0000B2F8 0x602A # 0 +0x0000B2F9 0x6094 # 0 +0x0000B2FA 0x6062 # 0 +0x0000B2FB 0x61D0 # 0 +0x0000B2FC 0x6212 # 0 +0x0000B2FD 0x62D0 # 0 +0x0000B2FE 0x6539 # 0 +0x0000B3A1 0x9B41 # 0 +0x0000B3A2 0x6666 # 0 +0x0000B3A3 0x68B0 # 0 +0x0000B3A4 0x6D77 # 0 +0x0000B3A5 0x7070 # 0 +0x0000B3A6 0x754C # 0 +0x0000B3A7 0x7686 # 0 +0x0000B3A8 0x7D75 # 0 +0x0000B3A9 0x82A5 # 0 +0x0000B3AA 0x87F9 # 0 +0x0000B3AB 0x958B # 0 +0x0000B3AC 0x968E # 0 +0x0000B3AD 0x8C9D # 0 +0x0000B3AE 0x51F1 # 0 +0x0000B3AF 0x52BE # 0 +0x0000B3B0 0x5916 # 0 +0x0000B3B1 0x54B3 # 0 +0x0000B3B2 0x5BB3 # 0 +0x0000B3B3 0x5D16 # 0 +0x0000B3B4 0x6168 # 0 +0x0000B3B5 0x6982 # 0 +0x0000B3B6 0x6DAF # 0 +0x0000B3B7 0x788D # 0 +0x0000B3B8 0x84CB # 0 +0x0000B3B9 0x8857 # 0 +0x0000B3BA 0x8A72 # 0 +0x0000B3BB 0x93A7 # 0 +0x0000B3BC 0x9AB8 # 0 +0x0000B3BD 0x6D6C # 0 +0x0000B3BE 0x99A8 # 0 +0x0000B3BF 0x86D9 # 0 +0x0000B3C0 0x57A3 # 0 +0x0000B3C1 0x67FF # 0 +0x0000B3C2 0x86CE # 0 +0x0000B3C3 0x920E # 0 +0x0000B3C4 0x5283 # 0 +0x0000B3C5 0x5687 # 0 +0x0000B3C6 0x5404 # 0 +0x0000B3C7 0x5ED3 # 0 +0x0000B3C8 0x62E1 # 0 +0x0000B3C9 0x64B9 # 0 +0x0000B3CA 0x683C # 0 +0x0000B3CB 0x6838 # 0 +0x0000B3CC 0x6BBB # 0 +0x0000B3CD 0x7372 # 0 +0x0000B3CE 0x78BA # 0 +0x0000B3CF 0x7A6B # 0 +0x0000B3D0 0x899A # 0 +0x0000B3D1 0x89D2 # 0 +0x0000B3D2 0x8D6B # 0 +0x0000B3D3 0x8F03 # 0 +0x0000B3D4 0x90ED # 0 +0x0000B3D5 0x95A3 # 0 +0x0000B3D6 0x9694 # 0 +0x0000B3D7 0x9769 # 0 +0x0000B3D8 0x5B66 # 0 +0x0000B3D9 0x5CB3 # 0 +0x0000B3DA 0x697D # 0 +0x0000B3DB 0x984D # 0 +0x0000B3DC 0x984E # 0 +0x0000B3DD 0x639B # 0 +0x0000B3DE 0x7B20 # 0 +0x0000B3DF 0x6A2B # 0 +0x0000B3E0 0x6A7F # 0 +0x0000B3E1 0x68B6 # 0 +0x0000B3E2 0x9C0D # 0 +0x0000B3E3 0x6F5F # 0 +0x0000B3E4 0x5272 # 0 +0x0000B3E5 0x559D # 0 +0x0000B3E6 0x6070 # 0 +0x0000B3E7 0x62EC # 0 +0x0000B3E8 0x6D3B # 0 +0x0000B3E9 0x6E07 # 0 +0x0000B3EA 0x6ED1 # 0 +0x0000B3EB 0x845B # 0 +0x0000B3EC 0x8910 # 0 +0x0000B3ED 0x8F44 # 0 +0x0000B3EE 0x4E14 # 0 +0x0000B3EF 0x9C39 # 0 +0x0000B3F0 0x53F6 # 0 +0x0000B3F1 0x691B # 0 +0x0000B3F2 0x6A3A # 0 +0x0000B3F3 0x9784 # 0 +0x0000B3F4 0x682A # 0 +0x0000B3F5 0x515C # 0 +0x0000B3F6 0x7AC3 # 0 +0x0000B3F7 0x84B2 # 0 +0x0000B3F8 0x91DC # 0 +0x0000B3F9 0x938C # 0 +0x0000B3FA 0x565B # 0 +0x0000B3FB 0x9D28 # 0 +0x0000B3FC 0x6822 # 0 +0x0000B3FD 0x8305 # 0 +0x0000B3FE 0x8431 # 0 +0x0000B4A1 0x7CA5 # 0 +0x0000B4A2 0x5208 # 0 +0x0000B4A3 0x82C5 # 0 +0x0000B4A4 0x74E6 # 0 +0x0000B4A5 0x4E7E # 0 +0x0000B4A6 0x4F83 # 0 +0x0000B4A7 0x51A0 # 0 +0x0000B4A8 0x5BD2 # 0 +0x0000B4A9 0x520A # 0 +0x0000B4AA 0x52D8 # 0 +0x0000B4AB 0x52E7 # 0 +0x0000B4AC 0x5DFB # 0 +0x0000B4AD 0x559A # 0 +0x0000B4AE 0x582A # 0 +0x0000B4AF 0x59E6 # 0 +0x0000B4B0 0x5B8C # 0 +0x0000B4B1 0x5B98 # 0 +0x0000B4B2 0x5BDB # 0 +0x0000B4B3 0x5E72 # 0 +0x0000B4B4 0x5E79 # 0 +0x0000B4B5 0x60A3 # 0 +0x0000B4B6 0x611F # 0 +0x0000B4B7 0x6163 # 0 +0x0000B4B8 0x61BE # 0 +0x0000B4B9 0x63DB # 0 +0x0000B4BA 0x6562 # 0 +0x0000B4BB 0x67D1 # 0 +0x0000B4BC 0x6853 # 0 +0x0000B4BD 0x68FA # 0 +0x0000B4BE 0x6B3E # 0 +0x0000B4BF 0x6B53 # 0 +0x0000B4C0 0x6C57 # 0 +0x0000B4C1 0x6F22 # 0 +0x0000B4C2 0x6F97 # 0 +0x0000B4C3 0x6F45 # 0 +0x0000B4C4 0x74B0 # 0 +0x0000B4C5 0x7518 # 0 +0x0000B4C6 0x76E3 # 0 +0x0000B4C7 0x770B # 0 +0x0000B4C8 0x7AFF # 0 +0x0000B4C9 0x7BA1 # 0 +0x0000B4CA 0x7C21 # 0 +0x0000B4CB 0x7DE9 # 0 +0x0000B4CC 0x7F36 # 0 +0x0000B4CD 0x7FF0 # 0 +0x0000B4CE 0x809D # 0 +0x0000B4CF 0x8266 # 0 +0x0000B4D0 0x839E # 0 +0x0000B4D1 0x89B3 # 0 +0x0000B4D2 0x8ACC # 0 +0x0000B4D3 0x8CAB # 0 +0x0000B4D4 0x9084 # 0 +0x0000B4D5 0x9451 # 0 +0x0000B4D6 0x9593 # 0 +0x0000B4D7 0x9591 # 0 +0x0000B4D8 0x95A2 # 0 +0x0000B4D9 0x9665 # 0 +0x0000B4DA 0x97D3 # 0 +0x0000B4DB 0x9928 # 0 +0x0000B4DC 0x8218 # 0 +0x0000B4DD 0x4E38 # 0 +0x0000B4DE 0x542B # 0 +0x0000B4DF 0x5CB8 # 0 +0x0000B4E0 0x5DCC # 0 +0x0000B4E1 0x73A9 # 0 +0x0000B4E2 0x764C # 0 +0x0000B4E3 0x773C # 0 +0x0000B4E4 0x5CA9 # 0 +0x0000B4E5 0x7FEB # 0 +0x0000B4E6 0x8D0B # 0 +0x0000B4E7 0x96C1 # 0 +0x0000B4E8 0x9811 # 0 +0x0000B4E9 0x9854 # 0 +0x0000B4EA 0x9858 # 0 +0x0000B4EB 0x4F01 # 0 +0x0000B4EC 0x4F0E # 0 +0x0000B4ED 0x5371 # 0 +0x0000B4EE 0x559C # 0 +0x0000B4EF 0x5668 # 0 +0x0000B4F0 0x57FA # 0 +0x0000B4F1 0x5947 # 0 +0x0000B4F2 0x5B09 # 0 +0x0000B4F3 0x5BC4 # 0 +0x0000B4F4 0x5C90 # 0 +0x0000B4F5 0x5E0C # 0 +0x0000B4F6 0x5E7E # 0 +0x0000B4F7 0x5FCC # 0 +0x0000B4F8 0x63EE # 0 +0x0000B4F9 0x673A # 0 +0x0000B4FA 0x65D7 # 0 +0x0000B4FB 0x65E2 # 0 +0x0000B4FC 0x671F # 0 +0x0000B4FD 0x68CB # 0 +0x0000B4FE 0x68C4 # 0 +0x0000B5A1 0x6A5F # 0 +0x0000B5A2 0x5E30 # 0 +0x0000B5A3 0x6BC5 # 0 +0x0000B5A4 0x6C17 # 0 +0x0000B5A5 0x6C7D # 0 +0x0000B5A6 0x757F # 0 +0x0000B5A7 0x7948 # 0 +0x0000B5A8 0x5B63 # 0 +0x0000B5A9 0x7A00 # 0 +0x0000B5AA 0x7D00 # 0 +0x0000B5AB 0x5FBD # 0 +0x0000B5AC 0x898F # 0 +0x0000B5AD 0x8A18 # 0 +0x0000B5AE 0x8CB4 # 0 +0x0000B5AF 0x8D77 # 0 +0x0000B5B0 0x8ECC # 0 +0x0000B5B1 0x8F1D # 0 +0x0000B5B2 0x98E2 # 0 +0x0000B5B3 0x9A0E # 0 +0x0000B5B4 0x9B3C # 0 +0x0000B5B5 0x4E80 # 0 +0x0000B5B6 0x507D # 0 +0x0000B5B7 0x5100 # 0 +0x0000B5B8 0x5993 # 0 +0x0000B5B9 0x5B9C # 0 +0x0000B5BA 0x622F # 0 +0x0000B5BB 0x6280 # 0 +0x0000B5BC 0x64EC # 0 +0x0000B5BD 0x6B3A # 0 +0x0000B5BE 0x72A0 # 0 +0x0000B5BF 0x7591 # 0 +0x0000B5C0 0x7947 # 0 +0x0000B5C1 0x7FA9 # 0 +0x0000B5C2 0x87FB # 0 +0x0000B5C3 0x8ABC # 0 +0x0000B5C4 0x8B70 # 0 +0x0000B5C5 0x63AC # 0 +0x0000B5C6 0x83CA # 0 +0x0000B5C7 0x97A0 # 0 +0x0000B5C8 0x5409 # 0 +0x0000B5C9 0x5403 # 0 +0x0000B5CA 0x55AB # 0 +0x0000B5CB 0x6854 # 0 +0x0000B5CC 0x6A58 # 0 +0x0000B5CD 0x8A70 # 0 +0x0000B5CE 0x7827 # 0 +0x0000B5CF 0x6775 # 0 +0x0000B5D0 0x9ECD # 0 +0x0000B5D1 0x5374 # 0 +0x0000B5D2 0x5BA2 # 0 +0x0000B5D3 0x811A # 0 +0x0000B5D4 0x8650 # 0 +0x0000B5D5 0x9006 # 0 +0x0000B5D6 0x4E18 # 0 +0x0000B5D7 0x4E45 # 0 +0x0000B5D8 0x4EC7 # 0 +0x0000B5D9 0x4F11 # 0 +0x0000B5DA 0x53CA # 0 +0x0000B5DB 0x5438 # 0 +0x0000B5DC 0x5BAE # 0 +0x0000B5DD 0x5F13 # 0 +0x0000B5DE 0x6025 # 0 +0x0000B5DF 0x6551 # 0 +0x0000B5E0 0x673D # 0 +0x0000B5E1 0x6C42 # 0 +0x0000B5E2 0x6C72 # 0 +0x0000B5E3 0x6CE3 # 0 +0x0000B5E4 0x7078 # 0 +0x0000B5E5 0x7403 # 0 +0x0000B5E6 0x7A76 # 0 +0x0000B5E7 0x7AAE # 0 +0x0000B5E8 0x7B08 # 0 +0x0000B5E9 0x7D1A # 0 +0x0000B5EA 0x7CFE # 0 +0x0000B5EB 0x7D66 # 0 +0x0000B5EC 0x65E7 # 0 +0x0000B5ED 0x725B # 0 +0x0000B5EE 0x53BB # 0 +0x0000B5EF 0x5C45 # 0 +0x0000B5F0 0x5DE8 # 0 +0x0000B5F1 0x62D2 # 0 +0x0000B5F2 0x62E0 # 0 +0x0000B5F3 0x6319 # 0 +0x0000B5F4 0x6E20 # 0 +0x0000B5F5 0x865A # 0 +0x0000B5F6 0x8A31 # 0 +0x0000B5F7 0x8DDD # 0 +0x0000B5F8 0x92F8 # 0 +0x0000B5F9 0x6F01 # 0 +0x0000B5FA 0x79A6 # 0 +0x0000B5FB 0x9B5A # 0 +0x0000B5FC 0x4EA8 # 0 +0x0000B5FD 0x4EAB # 0 +0x0000B5FE 0x4EAC # 0 +0x0000B6A1 0x4F9B # 0 +0x0000B6A2 0x4FA0 # 0 +0x0000B6A3 0x50D1 # 0 +0x0000B6A4 0x5147 # 0 +0x0000B6A5 0x7AF6 # 0 +0x0000B6A6 0x5171 # 0 +0x0000B6A7 0x51F6 # 0 +0x0000B6A8 0x5354 # 0 +0x0000B6A9 0x5321 # 0 +0x0000B6AA 0x537F # 0 +0x0000B6AB 0x53EB # 0 +0x0000B6AC 0x55AC # 0 +0x0000B6AD 0x5883 # 0 +0x0000B6AE 0x5CE1 # 0 +0x0000B6AF 0x5F37 # 0 +0x0000B6B0 0x5F4A # 0 +0x0000B6B1 0x602F # 0 +0x0000B6B2 0x6050 # 0 +0x0000B6B3 0x606D # 0 +0x0000B6B4 0x631F # 0 +0x0000B6B5 0x6559 # 0 +0x0000B6B6 0x6A4B # 0 +0x0000B6B7 0x6CC1 # 0 +0x0000B6B8 0x72C2 # 0 +0x0000B6B9 0x72ED # 0 +0x0000B6BA 0x77EF # 0 +0x0000B6BB 0x80F8 # 0 +0x0000B6BC 0x8105 # 0 +0x0000B6BD 0x8208 # 0 +0x0000B6BE 0x854E # 0 +0x0000B6BF 0x90F7 # 0 +0x0000B6C0 0x93E1 # 0 +0x0000B6C1 0x97FF # 0 +0x0000B6C2 0x9957 # 0 +0x0000B6C3 0x9A5A # 0 +0x0000B6C4 0x4EF0 # 0 +0x0000B6C5 0x51DD # 0 +0x0000B6C6 0x5C2D # 0 +0x0000B6C7 0x6681 # 0 +0x0000B6C8 0x696D # 0 +0x0000B6C9 0x5C40 # 0 +0x0000B6CA 0x66F2 # 0 +0x0000B6CB 0x6975 # 0 +0x0000B6CC 0x7389 # 0 +0x0000B6CD 0x6850 # 0 +0x0000B6CE 0x7C81 # 0 +0x0000B6CF 0x50C5 # 0 +0x0000B6D0 0x52E4 # 0 +0x0000B6D1 0x5747 # 0 +0x0000B6D2 0x5DFE # 0 +0x0000B6D3 0x9326 # 0 +0x0000B6D4 0x65A4 # 0 +0x0000B6D5 0x6B23 # 0 +0x0000B6D6 0x6B3D # 0 +0x0000B6D7 0x7434 # 0 +0x0000B6D8 0x7981 # 0 +0x0000B6D9 0x79BD # 0 +0x0000B6DA 0x7B4B # 0 +0x0000B6DB 0x7DCA # 0 +0x0000B6DC 0x82B9 # 0 +0x0000B6DD 0x83CC # 0 +0x0000B6DE 0x887F # 0 +0x0000B6DF 0x895F # 0 +0x0000B6E0 0x8B39 # 0 +0x0000B6E1 0x8FD1 # 0 +0x0000B6E2 0x91D1 # 0 +0x0000B6E3 0x541F # 0 +0x0000B6E4 0x9280 # 0 +0x0000B6E5 0x4E5D # 0 +0x0000B6E6 0x5036 # 0 +0x0000B6E7 0x53E5 # 0 +0x0000B6E8 0x533A # 0 +0x0000B6E9 0x72D7 # 0 +0x0000B6EA 0x7396 # 0 +0x0000B6EB 0x77E9 # 0 +0x0000B6EC 0x82E6 # 0 +0x0000B6ED 0x8EAF # 0 +0x0000B6EE 0x99C6 # 0 +0x0000B6EF 0x99C8 # 0 +0x0000B6F0 0x99D2 # 0 +0x0000B6F1 0x5177 # 0 +0x0000B6F2 0x611A # 0 +0x0000B6F3 0x865E # 0 +0x0000B6F4 0x55B0 # 0 +0x0000B6F5 0x7A7A # 0 +0x0000B6F6 0x5076 # 0 +0x0000B6F7 0x5BD3 # 0 +0x0000B6F8 0x9047 # 0 +0x0000B6F9 0x9685 # 0 +0x0000B6FA 0x4E32 # 0 +0x0000B6FB 0x6ADB # 0 +0x0000B6FC 0x91E7 # 0 +0x0000B6FD 0x5C51 # 0 +0x0000B6FE 0x5C48 # 0 +0x0000B7A1 0x6398 # 0 +0x0000B7A2 0x7A9F # 0 +0x0000B7A3 0x6C93 # 0 +0x0000B7A4 0x9774 # 0 +0x0000B7A5 0x8F61 # 0 +0x0000B7A6 0x7AAA # 0 +0x0000B7A7 0x718A # 0 +0x0000B7A8 0x9688 # 0 +0x0000B7A9 0x7C82 # 0 +0x0000B7AA 0x6817 # 0 +0x0000B7AB 0x7E70 # 0 +0x0000B7AC 0x6851 # 0 +0x0000B7AD 0x936C # 0 +0x0000B7AE 0x52F2 # 0 +0x0000B7AF 0x541B # 0 +0x0000B7B0 0x85AB # 0 +0x0000B7B1 0x8A13 # 0 +0x0000B7B2 0x7FA4 # 0 +0x0000B7B3 0x8ECD # 0 +0x0000B7B4 0x90E1 # 0 +0x0000B7B5 0x5366 # 0 +0x0000B7B6 0x8888 # 0 +0x0000B7B7 0x7941 # 0 +0x0000B7B8 0x4FC2 # 0 +0x0000B7B9 0x50BE # 0 +0x0000B7BA 0x5211 # 0 +0x0000B7BB 0x5144 # 0 +0x0000B7BC 0x5553 # 0 +0x0000B7BD 0x572D # 0 +0x0000B7BE 0x73EA # 0 +0x0000B7BF 0x578B # 0 +0x0000B7C0 0x5951 # 0 +0x0000B7C1 0x5F62 # 0 +0x0000B7C2 0x5F84 # 0 +0x0000B7C3 0x6075 # 0 +0x0000B7C4 0x6176 # 0 +0x0000B7C5 0x6167 # 0 +0x0000B7C6 0x61A9 # 0 +0x0000B7C7 0x63B2 # 0 +0x0000B7C8 0x643A # 0 +0x0000B7C9 0x656C # 0 +0x0000B7CA 0x666F # 0 +0x0000B7CB 0x6842 # 0 +0x0000B7CC 0x6E13 # 0 +0x0000B7CD 0x7566 # 0 +0x0000B7CE 0x7A3D # 0 +0x0000B7CF 0x7CFB # 0 +0x0000B7D0 0x7D4C # 0 +0x0000B7D1 0x7D99 # 0 +0x0000B7D2 0x7E4B # 0 +0x0000B7D3 0x7F6B # 0 +0x0000B7D4 0x830E # 0 +0x0000B7D5 0x834A # 0 +0x0000B7D6 0x86CD # 0 +0x0000B7D7 0x8A08 # 0 +0x0000B7D8 0x8A63 # 0 +0x0000B7D9 0x8B66 # 0 +0x0000B7DA 0x8EFD # 0 +0x0000B7DB 0x981A # 0 +0x0000B7DC 0x9D8F # 0 +0x0000B7DD 0x82B8 # 0 +0x0000B7DE 0x8FCE # 0 +0x0000B7DF 0x9BE8 # 0 +0x0000B7E0 0x5287 # 0 +0x0000B7E1 0x621F # 0 +0x0000B7E2 0x6483 # 0 +0x0000B7E3 0x6FC0 # 0 +0x0000B7E4 0x9699 # 0 +0x0000B7E5 0x6841 # 0 +0x0000B7E6 0x5091 # 0 +0x0000B7E7 0x6B20 # 0 +0x0000B7E8 0x6C7A # 0 +0x0000B7E9 0x6F54 # 0 +0x0000B7EA 0x7A74 # 0 +0x0000B7EB 0x7D50 # 0 +0x0000B7EC 0x8840 # 0 +0x0000B7ED 0x8A23 # 0 +0x0000B7EE 0x6708 # 0 +0x0000B7EF 0x4EF6 # 0 +0x0000B7F0 0x5039 # 0 +0x0000B7F1 0x5026 # 0 +0x0000B7F2 0x5065 # 0 +0x0000B7F3 0x517C # 0 +0x0000B7F4 0x5238 # 0 +0x0000B7F5 0x5263 # 0 +0x0000B7F6 0x55A7 # 0 +0x0000B7F7 0x570F # 0 +0x0000B7F8 0x5805 # 0 +0x0000B7F9 0x5ACC # 0 +0x0000B7FA 0x5EFA # 0 +0x0000B7FB 0x61B2 # 0 +0x0000B7FC 0x61F8 # 0 +0x0000B7FD 0x62F3 # 0 +0x0000B7FE 0x6372 # 0 +0x0000B8A1 0x691C # 0 +0x0000B8A2 0x6A29 # 0 +0x0000B8A3 0x727D # 0 +0x0000B8A4 0x72AC # 0 +0x0000B8A5 0x732E # 0 +0x0000B8A6 0x7814 # 0 +0x0000B8A7 0x786F # 0 +0x0000B8A8 0x7D79 # 0 +0x0000B8A9 0x770C # 0 +0x0000B8AA 0x80A9 # 0 +0x0000B8AB 0x898B # 0 +0x0000B8AC 0x8B19 # 0 +0x0000B8AD 0x8CE2 # 0 +0x0000B8AE 0x8ED2 # 0 +0x0000B8AF 0x9063 # 0 +0x0000B8B0 0x9375 # 0 +0x0000B8B1 0x967A # 0 +0x0000B8B2 0x9855 # 0 +0x0000B8B3 0x9A13 # 0 +0x0000B8B4 0x9E78 # 0 +0x0000B8B5 0x5143 # 0 +0x0000B8B6 0x539F # 0 +0x0000B8B7 0x53B3 # 0 +0x0000B8B8 0x5E7B # 0 +0x0000B8B9 0x5F26 # 0 +0x0000B8BA 0x6E1B # 0 +0x0000B8BB 0x6E90 # 0 +0x0000B8BC 0x7384 # 0 +0x0000B8BD 0x73FE # 0 +0x0000B8BE 0x7D43 # 0 +0x0000B8BF 0x8237 # 0 +0x0000B8C0 0x8A00 # 0 +0x0000B8C1 0x8AFA # 0 +0x0000B8C2 0x9650 # 0 +0x0000B8C3 0x4E4E # 0 +0x0000B8C4 0x500B # 0 +0x0000B8C5 0x53E4 # 0 +0x0000B8C6 0x547C # 0 +0x0000B8C7 0x56FA # 0 +0x0000B8C8 0x59D1 # 0 +0x0000B8C9 0x5B64 # 0 +0x0000B8CA 0x5DF1 # 0 +0x0000B8CB 0x5EAB # 0 +0x0000B8CC 0x5F27 # 0 +0x0000B8CD 0x6238 # 0 +0x0000B8CE 0x6545 # 0 +0x0000B8CF 0x67AF # 0 +0x0000B8D0 0x6E56 # 0 +0x0000B8D1 0x72D0 # 0 +0x0000B8D2 0x7CCA # 0 +0x0000B8D3 0x88B4 # 0 +0x0000B8D4 0x80A1 # 0 +0x0000B8D5 0x80E1 # 0 +0x0000B8D6 0x83F0 # 0 +0x0000B8D7 0x864E # 0 +0x0000B8D8 0x8A87 # 0 +0x0000B8D9 0x8DE8 # 0 +0x0000B8DA 0x9237 # 0 +0x0000B8DB 0x96C7 # 0 +0x0000B8DC 0x9867 # 0 +0x0000B8DD 0x9F13 # 0 +0x0000B8DE 0x4E94 # 0 +0x0000B8DF 0x4E92 # 0 +0x0000B8E0 0x4F0D # 0 +0x0000B8E1 0x5348 # 0 +0x0000B8E2 0x5449 # 0 +0x0000B8E3 0x543E # 0 +0x0000B8E4 0x5A2F # 0 +0x0000B8E5 0x5F8C # 0 +0x0000B8E6 0x5FA1 # 0 +0x0000B8E7 0x609F # 0 +0x0000B8E8 0x68A7 # 0 +0x0000B8E9 0x6A8E # 0 +0x0000B8EA 0x745A # 0 +0x0000B8EB 0x7881 # 0 +0x0000B8EC 0x8A9E # 0 +0x0000B8ED 0x8AA4 # 0 +0x0000B8EE 0x8B77 # 0 +0x0000B8EF 0x9190 # 0 +0x0000B8F0 0x4E5E # 0 +0x0000B8F1 0x9BC9 # 0 +0x0000B8F2 0x4EA4 # 0 +0x0000B8F3 0x4F7C # 0 +0x0000B8F4 0x4FAF # 0 +0x0000B8F5 0x5019 # 0 +0x0000B8F6 0x5016 # 0 +0x0000B8F7 0x5149 # 0 +0x0000B8F8 0x516C # 0 +0x0000B8F9 0x529F # 0 +0x0000B8FA 0x52B9 # 0 +0x0000B8FB 0x52FE # 0 +0x0000B8FC 0x539A # 0 +0x0000B8FD 0x53E3 # 0 +0x0000B8FE 0x5411 # 0 +0x0000B9A1 0x540E # 0 +0x0000B9A2 0x5589 # 0 +0x0000B9A3 0x5751 # 0 +0x0000B9A4 0x57A2 # 0 +0x0000B9A5 0x597D # 0 +0x0000B9A6 0x5B54 # 0 +0x0000B9A7 0x5B5D # 0 +0x0000B9A8 0x5B8F # 0 +0x0000B9A9 0x5DE5 # 0 +0x0000B9AA 0x5DE7 # 0 +0x0000B9AB 0x5DF7 # 0 +0x0000B9AC 0x5E78 # 0 +0x0000B9AD 0x5E83 # 0 +0x0000B9AE 0x5E9A # 0 +0x0000B9AF 0x5EB7 # 0 +0x0000B9B0 0x5F18 # 0 +0x0000B9B1 0x6052 # 0 +0x0000B9B2 0x614C # 0 +0x0000B9B3 0x6297 # 0 +0x0000B9B4 0x62D8 # 0 +0x0000B9B5 0x63A7 # 0 +0x0000B9B6 0x653B # 0 +0x0000B9B7 0x6602 # 0 +0x0000B9B8 0x6643 # 0 +0x0000B9B9 0x66F4 # 0 +0x0000B9BA 0x676D # 0 +0x0000B9BB 0x6821 # 0 +0x0000B9BC 0x6897 # 0 +0x0000B9BD 0x69CB # 0 +0x0000B9BE 0x6C5F # 0 +0x0000B9BF 0x6D2A # 0 +0x0000B9C0 0x6D69 # 0 +0x0000B9C1 0x6E2F # 0 +0x0000B9C2 0x6E9D # 0 +0x0000B9C3 0x7532 # 0 +0x0000B9C4 0x7687 # 0 +0x0000B9C5 0x786C # 0 +0x0000B9C6 0x7A3F # 0 +0x0000B9C7 0x7CE0 # 0 +0x0000B9C8 0x7D05 # 0 +0x0000B9C9 0x7D18 # 0 +0x0000B9CA 0x7D5E # 0 +0x0000B9CB 0x7DB1 # 0 +0x0000B9CC 0x8015 # 0 +0x0000B9CD 0x8003 # 0 +0x0000B9CE 0x80AF # 0 +0x0000B9CF 0x80B1 # 0 +0x0000B9D0 0x8154 # 0 +0x0000B9D1 0x818F # 0 +0x0000B9D2 0x822A # 0 +0x0000B9D3 0x8352 # 0 +0x0000B9D4 0x884C # 0 +0x0000B9D5 0x8861 # 0 +0x0000B9D6 0x8B1B # 0 +0x0000B9D7 0x8CA2 # 0 +0x0000B9D8 0x8CFC # 0 +0x0000B9D9 0x90CA # 0 +0x0000B9DA 0x9175 # 0 +0x0000B9DB 0x9271 # 0 +0x0000B9DC 0x783F # 0 +0x0000B9DD 0x92FC # 0 +0x0000B9DE 0x95A4 # 0 +0x0000B9DF 0x964D # 0 +0x0000B9E0 0x9805 # 0 +0x0000B9E1 0x9999 # 0 +0x0000B9E2 0x9AD8 # 0 +0x0000B9E3 0x9D3B # 0 +0x0000B9E4 0x525B # 0 +0x0000B9E5 0x52AB # 0 +0x0000B9E6 0x53F7 # 0 +0x0000B9E7 0x5408 # 0 +0x0000B9E8 0x58D5 # 0 +0x0000B9E9 0x62F7 # 0 +0x0000B9EA 0x6FE0 # 0 +0x0000B9EB 0x8C6A # 0 +0x0000B9EC 0x8F5F # 0 +0x0000B9ED 0x9EB9 # 0 +0x0000B9EE 0x514B # 0 +0x0000B9EF 0x523B # 0 +0x0000B9F0 0x544A # 0 +0x0000B9F1 0x56FD # 0 +0x0000B9F2 0x7A40 # 0 +0x0000B9F3 0x9177 # 0 +0x0000B9F4 0x9D60 # 0 +0x0000B9F5 0x9ED2 # 0 +0x0000B9F6 0x7344 # 0 +0x0000B9F7 0x6F09 # 0 +0x0000B9F8 0x8170 # 0 +0x0000B9F9 0x7511 # 0 +0x0000B9FA 0x5FFD # 0 +0x0000B9FB 0x60DA # 0 +0x0000B9FC 0x9AA8 # 0 +0x0000B9FD 0x72DB # 0 +0x0000B9FE 0x8FBC # 0 +0x0000BAA1 0x6B64 # 0 +0x0000BAA2 0x9803 # 0 +0x0000BAA3 0x4ECA # 0 +0x0000BAA4 0x56F0 # 0 +0x0000BAA5 0x5764 # 0 +0x0000BAA6 0x58BE # 0 +0x0000BAA7 0x5A5A # 0 +0x0000BAA8 0x6068 # 0 +0x0000BAA9 0x61C7 # 0 +0x0000BAAA 0x660F # 0 +0x0000BAAB 0x6606 # 0 +0x0000BAAC 0x6839 # 0 +0x0000BAAD 0x68B1 # 0 +0x0000BAAE 0x6DF7 # 0 +0x0000BAAF 0x75D5 # 0 +0x0000BAB0 0x7D3A # 0 +0x0000BAB1 0x826E # 0 +0x0000BAB2 0x9B42 # 0 +0x0000BAB3 0x4E9B # 0 +0x0000BAB4 0x4F50 # 0 +0x0000BAB5 0x53C9 # 0 +0x0000BAB6 0x5506 # 0 +0x0000BAB7 0x5D6F # 0 +0x0000BAB8 0x5DE6 # 0 +0x0000BAB9 0x5DEE # 0 +0x0000BABA 0x67FB # 0 +0x0000BABB 0x6C99 # 0 +0x0000BABC 0x7473 # 0 +0x0000BABD 0x7802 # 0 +0x0000BABE 0x8A50 # 0 +0x0000BABF 0x9396 # 0 +0x0000BAC0 0x88DF # 0 +0x0000BAC1 0x5750 # 0 +0x0000BAC2 0x5EA7 # 0 +0x0000BAC3 0x632B # 0 +0x0000BAC4 0x50B5 # 0 +0x0000BAC5 0x50AC # 0 +0x0000BAC6 0x518D # 0 +0x0000BAC7 0x6700 # 0 +0x0000BAC8 0x54C9 # 0 +0x0000BAC9 0x585E # 0 +0x0000BACA 0x59BB # 0 +0x0000BACB 0x5BB0 # 0 +0x0000BACC 0x5F69 # 0 +0x0000BACD 0x624D # 0 +0x0000BACE 0x63A1 # 0 +0x0000BACF 0x683D # 0 +0x0000BAD0 0x6B73 # 0 +0x0000BAD1 0x6E08 # 0 +0x0000BAD2 0x707D # 0 +0x0000BAD3 0x91C7 # 0 +0x0000BAD4 0x7280 # 0 +0x0000BAD5 0x7815 # 0 +0x0000BAD6 0x7826 # 0 +0x0000BAD7 0x796D # 0 +0x0000BAD8 0x658E # 0 +0x0000BAD9 0x7D30 # 0 +0x0000BADA 0x83DC # 0 +0x0000BADB 0x88C1 # 0 +0x0000BADC 0x8F09 # 0 +0x0000BADD 0x969B # 0 +0x0000BADE 0x5264 # 0 +0x0000BADF 0x5728 # 0 +0x0000BAE0 0x6750 # 0 +0x0000BAE1 0x7F6A # 0 +0x0000BAE2 0x8CA1 # 0 +0x0000BAE3 0x51B4 # 0 +0x0000BAE4 0x5742 # 0 +0x0000BAE5 0x962A # 0 +0x0000BAE6 0x583A # 0 +0x0000BAE7 0x698A # 0 +0x0000BAE8 0x80B4 # 0 +0x0000BAE9 0x54B2 # 0 +0x0000BAEA 0x5D0E # 0 +0x0000BAEB 0x57FC # 0 +0x0000BAEC 0x7895 # 0 +0x0000BAED 0x9DFA # 0 +0x0000BAEE 0x4F5C # 0 +0x0000BAEF 0x524A # 0 +0x0000BAF0 0x548B # 0 +0x0000BAF1 0x643E # 0 +0x0000BAF2 0x6628 # 0 +0x0000BAF3 0x6714 # 0 +0x0000BAF4 0x67F5 # 0 +0x0000BAF5 0x7A84 # 0 +0x0000BAF6 0x7B56 # 0 +0x0000BAF7 0x7D22 # 0 +0x0000BAF8 0x932F # 0 +0x0000BAF9 0x685C # 0 +0x0000BAFA 0x9BAD # 0 +0x0000BAFB 0x7B39 # 0 +0x0000BAFC 0x5319 # 0 +0x0000BAFD 0x518A # 0 +0x0000BAFE 0x5237 # 0 +0x0000BBA1 0x5BDF # 0 +0x0000BBA2 0x62F6 # 0 +0x0000BBA3 0x64AE # 0 +0x0000BBA4 0x64E6 # 0 +0x0000BBA5 0x672D # 0 +0x0000BBA6 0x6BBA # 0 +0x0000BBA7 0x85A9 # 0 +0x0000BBA8 0x96D1 # 0 +0x0000BBA9 0x7690 # 0 +0x0000BBAA 0x9BD6 # 0 +0x0000BBAB 0x634C # 0 +0x0000BBAC 0x9306 # 0 +0x0000BBAD 0x9BAB # 0 +0x0000BBAE 0x76BF # 0 +0x0000BBAF 0x6652 # 0 +0x0000BBB0 0x4E09 # 0 +0x0000BBB1 0x5098 # 0 +0x0000BBB2 0x53C2 # 0 +0x0000BBB3 0x5C71 # 0 +0x0000BBB4 0x60E8 # 0 +0x0000BBB5 0x6492 # 0 +0x0000BBB6 0x6563 # 0 +0x0000BBB7 0x685F # 0 +0x0000BBB8 0x71E6 # 0 +0x0000BBB9 0x73CA # 0 +0x0000BBBA 0x7523 # 0 +0x0000BBBB 0x7B97 # 0 +0x0000BBBC 0x7E82 # 0 +0x0000BBBD 0x8695 # 0 +0x0000BBBE 0x8B83 # 0 +0x0000BBBF 0x8CDB # 0 +0x0000BBC0 0x9178 # 0 +0x0000BBC1 0x9910 # 0 +0x0000BBC2 0x65AC # 0 +0x0000BBC3 0x66AB # 0 +0x0000BBC4 0x6B8B # 0 +0x0000BBC5 0x4ED5 # 0 +0x0000BBC6 0x4ED4 # 0 +0x0000BBC7 0x4F3A # 0 +0x0000BBC8 0x4F7F # 0 +0x0000BBC9 0x523A # 0 +0x0000BBCA 0x53F8 # 0 +0x0000BBCB 0x53F2 # 0 +0x0000BBCC 0x55E3 # 0 +0x0000BBCD 0x56DB # 0 +0x0000BBCE 0x58EB # 0 +0x0000BBCF 0x59CB # 0 +0x0000BBD0 0x59C9 # 0 +0x0000BBD1 0x59FF # 0 +0x0000BBD2 0x5B50 # 0 +0x0000BBD3 0x5C4D # 0 +0x0000BBD4 0x5E02 # 0 +0x0000BBD5 0x5E2B # 0 +0x0000BBD6 0x5FD7 # 0 +0x0000BBD7 0x601D # 0 +0x0000BBD8 0x6307 # 0 +0x0000BBD9 0x652F # 0 +0x0000BBDA 0x5B5C # 0 +0x0000BBDB 0x65AF # 0 +0x0000BBDC 0x65BD # 0 +0x0000BBDD 0x65E8 # 0 +0x0000BBDE 0x679D # 0 +0x0000BBDF 0x6B62 # 0 +0x0000BBE0 0x6B7B # 0 +0x0000BBE1 0x6C0F # 0 +0x0000BBE2 0x7345 # 0 +0x0000BBE3 0x7949 # 0 +0x0000BBE4 0x79C1 # 0 +0x0000BBE5 0x7CF8 # 0 +0x0000BBE6 0x7D19 # 0 +0x0000BBE7 0x7D2B # 0 +0x0000BBE8 0x80A2 # 0 +0x0000BBE9 0x8102 # 0 +0x0000BBEA 0x81F3 # 0 +0x0000BBEB 0x8996 # 0 +0x0000BBEC 0x8A5E # 0 +0x0000BBED 0x8A69 # 0 +0x0000BBEE 0x8A66 # 0 +0x0000BBEF 0x8A8C # 0 +0x0000BBF0 0x8AEE # 0 +0x0000BBF1 0x8CC7 # 0 +0x0000BBF2 0x8CDC # 0 +0x0000BBF3 0x96CC # 0 +0x0000BBF4 0x98FC # 0 +0x0000BBF5 0x6B6F # 0 +0x0000BBF6 0x4E8B # 0 +0x0000BBF7 0x4F3C # 0 +0x0000BBF8 0x4F8D # 0 +0x0000BBF9 0x5150 # 0 +0x0000BBFA 0x5B57 # 0 +0x0000BBFB 0x5BFA # 0 +0x0000BBFC 0x6148 # 0 +0x0000BBFD 0x6301 # 0 +0x0000BBFE 0x6642 # 0 +0x0000BCA1 0x6B21 # 0 +0x0000BCA2 0x6ECB # 0 +0x0000BCA3 0x6CBB # 0 +0x0000BCA4 0x723E # 0 +0x0000BCA5 0x74BD # 0 +0x0000BCA6 0x75D4 # 0 +0x0000BCA7 0x78C1 # 0 +0x0000BCA8 0x793A # 0 +0x0000BCA9 0x800C # 0 +0x0000BCAA 0x8033 # 0 +0x0000BCAB 0x81EA # 0 +0x0000BCAC 0x8494 # 0 +0x0000BCAD 0x8F9E # 0 +0x0000BCAE 0x6C50 # 0 +0x0000BCAF 0x9E7F # 0 +0x0000BCB0 0x5F0F # 0 +0x0000BCB1 0x8B58 # 0 +0x0000BCB2 0x9D2B # 0 +0x0000BCB3 0x7AFA # 0 +0x0000BCB4 0x8EF8 # 0 +0x0000BCB5 0x5B8D # 0 +0x0000BCB6 0x96EB # 0 +0x0000BCB7 0x4E03 # 0 +0x0000BCB8 0x53F1 # 0 +0x0000BCB9 0x57F7 # 0 +0x0000BCBA 0x5931 # 0 +0x0000BCBB 0x5AC9 # 0 +0x0000BCBC 0x5BA4 # 0 +0x0000BCBD 0x6089 # 0 +0x0000BCBE 0x6E7F # 0 +0x0000BCBF 0x6F06 # 0 +0x0000BCC0 0x75BE # 0 +0x0000BCC1 0x8CEA # 0 +0x0000BCC2 0x5B9F # 0 +0x0000BCC3 0x8500 # 0 +0x0000BCC4 0x7BE0 # 0 +0x0000BCC5 0x5072 # 0 +0x0000BCC6 0x67F4 # 0 +0x0000BCC7 0x829D # 0 +0x0000BCC8 0x5C61 # 0 +0x0000BCC9 0x854A # 0 +0x0000BCCA 0x7E1E # 0 +0x0000BCCB 0x820E # 0 +0x0000BCCC 0x5199 # 0 +0x0000BCCD 0x5C04 # 0 +0x0000BCCE 0x6368 # 0 +0x0000BCCF 0x8D66 # 0 +0x0000BCD0 0x659C # 0 +0x0000BCD1 0x716E # 0 +0x0000BCD2 0x793E # 0 +0x0000BCD3 0x7D17 # 0 +0x0000BCD4 0x8005 # 0 +0x0000BCD5 0x8B1D # 0 +0x0000BCD6 0x8ECA # 0 +0x0000BCD7 0x906E # 0 +0x0000BCD8 0x86C7 # 0 +0x0000BCD9 0x90AA # 0 +0x0000BCDA 0x501F # 0 +0x0000BCDB 0x52FA # 0 +0x0000BCDC 0x5C3A # 0 +0x0000BCDD 0x6753 # 0 +0x0000BCDE 0x707C # 0 +0x0000BCDF 0x7235 # 0 +0x0000BCE0 0x914C # 0 +0x0000BCE1 0x91C8 # 0 +0x0000BCE2 0x932B # 0 +0x0000BCE3 0x82E5 # 0 +0x0000BCE4 0x5BC2 # 0 +0x0000BCE5 0x5F31 # 0 +0x0000BCE6 0x60F9 # 0 +0x0000BCE7 0x4E3B # 0 +0x0000BCE8 0x53D6 # 0 +0x0000BCE9 0x5B88 # 0 +0x0000BCEA 0x624B # 0 +0x0000BCEB 0x6731 # 0 +0x0000BCEC 0x6B8A # 0 +0x0000BCED 0x72E9 # 0 +0x0000BCEE 0x73E0 # 0 +0x0000BCEF 0x7A2E # 0 +0x0000BCF0 0x816B # 0 +0x0000BCF1 0x8DA3 # 0 +0x0000BCF2 0x9152 # 0 +0x0000BCF3 0x9996 # 0 +0x0000BCF4 0x5112 # 0 +0x0000BCF5 0x53D7 # 0 +0x0000BCF6 0x546A # 0 +0x0000BCF7 0x5BFF # 0 +0x0000BCF8 0x6388 # 0 +0x0000BCF9 0x6A39 # 0 +0x0000BCFA 0x7DAC # 0 +0x0000BCFB 0x9700 # 0 +0x0000BCFC 0x56DA # 0 +0x0000BCFD 0x53CE # 0 +0x0000BCFE 0x5468 # 0 +0x0000BDA1 0x5B97 # 0 +0x0000BDA2 0x5C31 # 0 +0x0000BDA3 0x5DDE # 0 +0x0000BDA4 0x4FEE # 0 +0x0000BDA5 0x6101 # 0 +0x0000BDA6 0x62FE # 0 +0x0000BDA7 0x6D32 # 0 +0x0000BDA8 0x79C0 # 0 +0x0000BDA9 0x79CB # 0 +0x0000BDAA 0x7D42 # 0 +0x0000BDAB 0x7E4D # 0 +0x0000BDAC 0x7FD2 # 0 +0x0000BDAD 0x81ED # 0 +0x0000BDAE 0x821F # 0 +0x0000BDAF 0x8490 # 0 +0x0000BDB0 0x8846 # 0 +0x0000BDB1 0x8972 # 0 +0x0000BDB2 0x8B90 # 0 +0x0000BDB3 0x8E74 # 0 +0x0000BDB4 0x8F2F # 0 +0x0000BDB5 0x9031 # 0 +0x0000BDB6 0x914B # 0 +0x0000BDB7 0x916C # 0 +0x0000BDB8 0x96C6 # 0 +0x0000BDB9 0x919C # 0 +0x0000BDBA 0x4EC0 # 0 +0x0000BDBB 0x4F4F # 0 +0x0000BDBC 0x5145 # 0 +0x0000BDBD 0x5341 # 0 +0x0000BDBE 0x5F93 # 0 +0x0000BDBF 0x620E # 0 +0x0000BDC0 0x67D4 # 0 +0x0000BDC1 0x6C41 # 0 +0x0000BDC2 0x6E0B # 0 +0x0000BDC3 0x7363 # 0 +0x0000BDC4 0x7E26 # 0 +0x0000BDC5 0x91CD # 0 +0x0000BDC6 0x9283 # 0 +0x0000BDC7 0x53D4 # 0 +0x0000BDC8 0x5919 # 0 +0x0000BDC9 0x5BBF # 0 +0x0000BDCA 0x6DD1 # 0 +0x0000BDCB 0x795D # 0 +0x0000BDCC 0x7E2E # 0 +0x0000BDCD 0x7C9B # 0 +0x0000BDCE 0x587E # 0 +0x0000BDCF 0x719F # 0 +0x0000BDD0 0x51FA # 0 +0x0000BDD1 0x8853 # 0 +0x0000BDD2 0x8FF0 # 0 +0x0000BDD3 0x4FCA # 0 +0x0000BDD4 0x5CFB # 0 +0x0000BDD5 0x6625 # 0 +0x0000BDD6 0x77AC # 0 +0x0000BDD7 0x7AE3 # 0 +0x0000BDD8 0x821C # 0 +0x0000BDD9 0x99FF # 0 +0x0000BDDA 0x51C6 # 0 +0x0000BDDB 0x5FAA # 0 +0x0000BDDC 0x65EC # 0 +0x0000BDDD 0x696F # 0 +0x0000BDDE 0x6B89 # 0 +0x0000BDDF 0x6DF3 # 0 +0x0000BDE0 0x6E96 # 0 +0x0000BDE1 0x6F64 # 0 +0x0000BDE2 0x76FE # 0 +0x0000BDE3 0x7D14 # 0 +0x0000BDE4 0x5DE1 # 0 +0x0000BDE5 0x9075 # 0 +0x0000BDE6 0x9187 # 0 +0x0000BDE7 0x9806 # 0 +0x0000BDE8 0x51E6 # 0 +0x0000BDE9 0x521D # 0 +0x0000BDEA 0x6240 # 0 +0x0000BDEB 0x6691 # 0 +0x0000BDEC 0x66D9 # 0 +0x0000BDED 0x6E1A # 0 +0x0000BDEE 0x5EB6 # 0 +0x0000BDEF 0x7DD2 # 0 +0x0000BDF0 0x7F72 # 0 +0x0000BDF1 0x66F8 # 0 +0x0000BDF2 0x85AF # 0 +0x0000BDF3 0x85F7 # 0 +0x0000BDF4 0x8AF8 # 0 +0x0000BDF5 0x52A9 # 0 +0x0000BDF6 0x53D9 # 0 +0x0000BDF7 0x5973 # 0 +0x0000BDF8 0x5E8F # 0 +0x0000BDF9 0x5F90 # 0 +0x0000BDFA 0x6055 # 0 +0x0000BDFB 0x92E4 # 0 +0x0000BDFC 0x9664 # 0 +0x0000BDFD 0x50B7 # 0 +0x0000BDFE 0x511F # 0 +0x0000BEA1 0x52DD # 0 +0x0000BEA2 0x5320 # 0 +0x0000BEA3 0x5347 # 0 +0x0000BEA4 0x53EC # 0 +0x0000BEA5 0x54E8 # 0 +0x0000BEA6 0x5546 # 0 +0x0000BEA7 0x5531 # 0 +0x0000BEA8 0x5617 # 0 +0x0000BEA9 0x5968 # 0 +0x0000BEAA 0x59BE # 0 +0x0000BEAB 0x5A3C # 0 +0x0000BEAC 0x5BB5 # 0 +0x0000BEAD 0x5C06 # 0 +0x0000BEAE 0x5C0F # 0 +0x0000BEAF 0x5C11 # 0 +0x0000BEB0 0x5C1A # 0 +0x0000BEB1 0x5E84 # 0 +0x0000BEB2 0x5E8A # 0 +0x0000BEB3 0x5EE0 # 0 +0x0000BEB4 0x5F70 # 0 +0x0000BEB5 0x627F # 0 +0x0000BEB6 0x6284 # 0 +0x0000BEB7 0x62DB # 0 +0x0000BEB8 0x638C # 0 +0x0000BEB9 0x6377 # 0 +0x0000BEBA 0x6607 # 0 +0x0000BEBB 0x660C # 0 +0x0000BEBC 0x662D # 0 +0x0000BEBD 0x6676 # 0 +0x0000BEBE 0x677E # 0 +0x0000BEBF 0x68A2 # 0 +0x0000BEC0 0x6A1F # 0 +0x0000BEC1 0x6A35 # 0 +0x0000BEC2 0x6CBC # 0 +0x0000BEC3 0x6D88 # 0 +0x0000BEC4 0x6E09 # 0 +0x0000BEC5 0x6E58 # 0 +0x0000BEC6 0x713C # 0 +0x0000BEC7 0x7126 # 0 +0x0000BEC8 0x7167 # 0 +0x0000BEC9 0x75C7 # 0 +0x0000BECA 0x7701 # 0 +0x0000BECB 0x785D # 0 +0x0000BECC 0x7901 # 0 +0x0000BECD 0x7965 # 0 +0x0000BECE 0x79F0 # 0 +0x0000BECF 0x7AE0 # 0 +0x0000BED0 0x7B11 # 0 +0x0000BED1 0x7CA7 # 0 +0x0000BED2 0x7D39 # 0 +0x0000BED3 0x8096 # 0 +0x0000BED4 0x83D6 # 0 +0x0000BED5 0x848B # 0 +0x0000BED6 0x8549 # 0 +0x0000BED7 0x885D # 0 +0x0000BED8 0x88F3 # 0 +0x0000BED9 0x8A1F # 0 +0x0000BEDA 0x8A3C # 0 +0x0000BEDB 0x8A54 # 0 +0x0000BEDC 0x8A73 # 0 +0x0000BEDD 0x8C61 # 0 +0x0000BEDE 0x8CDE # 0 +0x0000BEDF 0x91A4 # 0 +0x0000BEE0 0x9266 # 0 +0x0000BEE1 0x937E # 0 +0x0000BEE2 0x9418 # 0 +0x0000BEE3 0x969C # 0 +0x0000BEE4 0x9798 # 0 +0x0000BEE5 0x4E0A # 0 +0x0000BEE6 0x4E08 # 0 +0x0000BEE7 0x4E1E # 0 +0x0000BEE8 0x4E57 # 0 +0x0000BEE9 0x5197 # 0 +0x0000BEEA 0x5270 # 0 +0x0000BEEB 0x57CE # 0 +0x0000BEEC 0x5834 # 0 +0x0000BEED 0x58CC # 0 +0x0000BEEE 0x5B22 # 0 +0x0000BEEF 0x5E38 # 0 +0x0000BEF0 0x60C5 # 0 +0x0000BEF1 0x64FE # 0 +0x0000BEF2 0x6761 # 0 +0x0000BEF3 0x6756 # 0 +0x0000BEF4 0x6D44 # 0 +0x0000BEF5 0x72B6 # 0 +0x0000BEF6 0x7573 # 0 +0x0000BEF7 0x7A63 # 0 +0x0000BEF8 0x84B8 # 0 +0x0000BEF9 0x8B72 # 0 +0x0000BEFA 0x91B8 # 0 +0x0000BEFB 0x9320 # 0 +0x0000BEFC 0x5631 # 0 +0x0000BEFD 0x57F4 # 0 +0x0000BEFE 0x98FE # 0 +0x0000BFA1 0x62ED # 0 +0x0000BFA2 0x690D # 0 +0x0000BFA3 0x6B96 # 0 +0x0000BFA4 0x71ED # 0 +0x0000BFA5 0x7E54 # 0 +0x0000BFA6 0x8077 # 0 +0x0000BFA7 0x8272 # 0 +0x0000BFA8 0x89E6 # 0 +0x0000BFA9 0x98DF # 0 +0x0000BFAA 0x8755 # 0 +0x0000BFAB 0x8FB1 # 0 +0x0000BFAC 0x5C3B # 0 +0x0000BFAD 0x4F38 # 0 +0x0000BFAE 0x4FE1 # 0 +0x0000BFAF 0x4FB5 # 0 +0x0000BFB0 0x5507 # 0 +0x0000BFB1 0x5A20 # 0 +0x0000BFB2 0x5BDD # 0 +0x0000BFB3 0x5BE9 # 0 +0x0000BFB4 0x5FC3 # 0 +0x0000BFB5 0x614E # 0 +0x0000BFB6 0x632F # 0 +0x0000BFB7 0x65B0 # 0 +0x0000BFB8 0x664B # 0 +0x0000BFB9 0x68EE # 0 +0x0000BFBA 0x699B # 0 +0x0000BFBB 0x6D78 # 0 +0x0000BFBC 0x6DF1 # 0 +0x0000BFBD 0x7533 # 0 +0x0000BFBE 0x75B9 # 0 +0x0000BFBF 0x771F # 0 +0x0000BFC0 0x795E # 0 +0x0000BFC1 0x79E6 # 0 +0x0000BFC2 0x7D33 # 0 +0x0000BFC3 0x81E3 # 0 +0x0000BFC4 0x82AF # 0 +0x0000BFC5 0x85AA # 0 +0x0000BFC6 0x89AA # 0 +0x0000BFC7 0x8A3A # 0 +0x0000BFC8 0x8EAB # 0 +0x0000BFC9 0x8F9B # 0 +0x0000BFCA 0x9032 # 0 +0x0000BFCB 0x91DD # 0 +0x0000BFCC 0x9707 # 0 +0x0000BFCD 0x4EBA # 0 +0x0000BFCE 0x4EC1 # 0 +0x0000BFCF 0x5203 # 0 +0x0000BFD0 0x5875 # 0 +0x0000BFD1 0x58EC # 0 +0x0000BFD2 0x5C0B # 0 +0x0000BFD3 0x751A # 0 +0x0000BFD4 0x5C3D # 0 +0x0000BFD5 0x814E # 0 +0x0000BFD6 0x8A0A # 0 +0x0000BFD7 0x8FC5 # 0 +0x0000BFD8 0x9663 # 0 +0x0000BFD9 0x976D # 0 +0x0000BFDA 0x7B25 # 0 +0x0000BFDB 0x8ACF # 0 +0x0000BFDC 0x9808 # 0 +0x0000BFDD 0x9162 # 0 +0x0000BFDE 0x56F3 # 0 +0x0000BFDF 0x53A8 # 0 +0x0000BFE0 0x9017 # 0 +0x0000BFE1 0x5439 # 0 +0x0000BFE2 0x5782 # 0 +0x0000BFE3 0x5E25 # 0 +0x0000BFE4 0x63A8 # 0 +0x0000BFE5 0x6C34 # 0 +0x0000BFE6 0x708A # 0 +0x0000BFE7 0x7761 # 0 +0x0000BFE8 0x7C8B # 0 +0x0000BFE9 0x7FE0 # 0 +0x0000BFEA 0x8870 # 0 +0x0000BFEB 0x9042 # 0 +0x0000BFEC 0x9154 # 0 +0x0000BFED 0x9310 # 0 +0x0000BFEE 0x9318 # 0 +0x0000BFEF 0x968F # 0 +0x0000BFF0 0x745E # 0 +0x0000BFF1 0x9AC4 # 0 +0x0000BFF2 0x5D07 # 0 +0x0000BFF3 0x5D69 # 0 +0x0000BFF4 0x6570 # 0 +0x0000BFF5 0x67A2 # 0 +0x0000BFF6 0x8DA8 # 0 +0x0000BFF7 0x96DB # 0 +0x0000BFF8 0x636E # 0 +0x0000BFF9 0x6749 # 0 +0x0000BFFA 0x6919 # 0 +0x0000BFFB 0x83C5 # 0 +0x0000BFFC 0x9817 # 0 +0x0000BFFD 0x96C0 # 0 +0x0000BFFE 0x88FE # 0 +0x0000C0A1 0x6F84 # 0 +0x0000C0A2 0x647A # 0 +0x0000C0A3 0x5BF8 # 0 +0x0000C0A4 0x4E16 # 0 +0x0000C0A5 0x702C # 0 +0x0000C0A6 0x755D # 0 +0x0000C0A7 0x662F # 0 +0x0000C0A8 0x51C4 # 0 +0x0000C0A9 0x5236 # 0 +0x0000C0AA 0x52E2 # 0 +0x0000C0AB 0x59D3 # 0 +0x0000C0AC 0x5F81 # 0 +0x0000C0AD 0x6027 # 0 +0x0000C0AE 0x6210 # 0 +0x0000C0AF 0x653F # 0 +0x0000C0B0 0x6574 # 0 +0x0000C0B1 0x661F # 0 +0x0000C0B2 0x6674 # 0 +0x0000C0B3 0x68F2 # 0 +0x0000C0B4 0x6816 # 0 +0x0000C0B5 0x6B63 # 0 +0x0000C0B6 0x6E05 # 0 +0x0000C0B7 0x7272 # 0 +0x0000C0B8 0x751F # 0 +0x0000C0B9 0x76DB # 0 +0x0000C0BA 0x7CBE # 0 +0x0000C0BB 0x8056 # 0 +0x0000C0BC 0x58F0 # 0 +0x0000C0BD 0x88FD # 0 +0x0000C0BE 0x897F # 0 +0x0000C0BF 0x8AA0 # 0 +0x0000C0C0 0x8A93 # 0 +0x0000C0C1 0x8ACB # 0 +0x0000C0C2 0x901D # 0 +0x0000C0C3 0x9192 # 0 +0x0000C0C4 0x9752 # 0 +0x0000C0C5 0x9759 # 0 +0x0000C0C6 0x6589 # 0 +0x0000C0C7 0x7A0E # 0 +0x0000C0C8 0x8106 # 0 +0x0000C0C9 0x96BB # 0 +0x0000C0CA 0x5E2D # 0 +0x0000C0CB 0x60DC # 0 +0x0000C0CC 0x621A # 0 +0x0000C0CD 0x65A5 # 0 +0x0000C0CE 0x6614 # 0 +0x0000C0CF 0x6790 # 0 +0x0000C0D0 0x77F3 # 0 +0x0000C0D1 0x7A4D # 0 +0x0000C0D2 0x7C4D # 0 +0x0000C0D3 0x7E3E # 0 +0x0000C0D4 0x810A # 0 +0x0000C0D5 0x8CAC # 0 +0x0000C0D6 0x8D64 # 0 +0x0000C0D7 0x8DE1 # 0 +0x0000C0D8 0x8E5F # 0 +0x0000C0D9 0x78A9 # 0 +0x0000C0DA 0x5207 # 0 +0x0000C0DB 0x62D9 # 0 +0x0000C0DC 0x63A5 # 0 +0x0000C0DD 0x6442 # 0 +0x0000C0DE 0x6298 # 0 +0x0000C0DF 0x8A2D # 0 +0x0000C0E0 0x7A83 # 0 +0x0000C0E1 0x7BC0 # 0 +0x0000C0E2 0x8AAC # 0 +0x0000C0E3 0x96EA # 0 +0x0000C0E4 0x7D76 # 0 +0x0000C0E5 0x820C # 0 +0x0000C0E6 0x8749 # 0 +0x0000C0E7 0x4ED9 # 0 +0x0000C0E8 0x5148 # 0 +0x0000C0E9 0x5343 # 0 +0x0000C0EA 0x5360 # 0 +0x0000C0EB 0x5BA3 # 0 +0x0000C0EC 0x5C02 # 0 +0x0000C0ED 0x5C16 # 0 +0x0000C0EE 0x5DDD # 0 +0x0000C0EF 0x6226 # 0 +0x0000C0F0 0x6247 # 0 +0x0000C0F1 0x64B0 # 0 +0x0000C0F2 0x6813 # 0 +0x0000C0F3 0x6834 # 0 +0x0000C0F4 0x6CC9 # 0 +0x0000C0F5 0x6D45 # 0 +0x0000C0F6 0x6D17 # 0 +0x0000C0F7 0x67D3 # 0 +0x0000C0F8 0x6F5C # 0 +0x0000C0F9 0x714E # 0 +0x0000C0FA 0x717D # 0 +0x0000C0FB 0x65CB # 0 +0x0000C0FC 0x7A7F # 0 +0x0000C0FD 0x7BAD # 0 +0x0000C0FE 0x7DDA # 0 +0x0000C1A1 0x7E4A # 0 +0x0000C1A2 0x7FA8 # 0 +0x0000C1A3 0x817A # 0 +0x0000C1A4 0x821B # 0 +0x0000C1A5 0x8239 # 0 +0x0000C1A6 0x85A6 # 0 +0x0000C1A7 0x8A6E # 0 +0x0000C1A8 0x8CCE # 0 +0x0000C1A9 0x8DF5 # 0 +0x0000C1AA 0x9078 # 0 +0x0000C1AB 0x9077 # 0 +0x0000C1AC 0x92AD # 0 +0x0000C1AD 0x9291 # 0 +0x0000C1AE 0x9583 # 0 +0x0000C1AF 0x9BAE # 0 +0x0000C1B0 0x524D # 0 +0x0000C1B1 0x5584 # 0 +0x0000C1B2 0x6F38 # 0 +0x0000C1B3 0x7136 # 0 +0x0000C1B4 0x5168 # 0 +0x0000C1B5 0x7985 # 0 +0x0000C1B6 0x7E55 # 0 +0x0000C1B7 0x81B3 # 0 +0x0000C1B8 0x7CCE # 0 +0x0000C1B9 0x564C # 0 +0x0000C1BA 0x5851 # 0 +0x0000C1BB 0x5CA8 # 0 +0x0000C1BC 0x63AA # 0 +0x0000C1BD 0x66FE # 0 +0x0000C1BE 0x66FD # 0 +0x0000C1BF 0x695A # 0 +0x0000C1C0 0x72D9 # 0 +0x0000C1C1 0x758F # 0 +0x0000C1C2 0x758E # 0 +0x0000C1C3 0x790E # 0 +0x0000C1C4 0x7956 # 0 +0x0000C1C5 0x79DF # 0 +0x0000C1C6 0x7C97 # 0 +0x0000C1C7 0x7D20 # 0 +0x0000C1C8 0x7D44 # 0 +0x0000C1C9 0x8607 # 0 +0x0000C1CA 0x8A34 # 0 +0x0000C1CB 0x963B # 0 +0x0000C1CC 0x9061 # 0 +0x0000C1CD 0x9F20 # 0 +0x0000C1CE 0x50E7 # 0 +0x0000C1CF 0x5275 # 0 +0x0000C1D0 0x53CC # 0 +0x0000C1D1 0x53E2 # 0 +0x0000C1D2 0x5009 # 0 +0x0000C1D3 0x55AA # 0 +0x0000C1D4 0x58EE # 0 +0x0000C1D5 0x594F # 0 +0x0000C1D6 0x723D # 0 +0x0000C1D7 0x5B8B # 0 +0x0000C1D8 0x5C64 # 0 +0x0000C1D9 0x531D # 0 +0x0000C1DA 0x60E3 # 0 +0x0000C1DB 0x60F3 # 0 +0x0000C1DC 0x635C # 0 +0x0000C1DD 0x6383 # 0 +0x0000C1DE 0x633F # 0 +0x0000C1DF 0x63BB # 0 +0x0000C1E0 0x64CD # 0 +0x0000C1E1 0x65E9 # 0 +0x0000C1E2 0x66F9 # 0 +0x0000C1E3 0x5DE3 # 0 +0x0000C1E4 0x69CD # 0 +0x0000C1E5 0x69FD # 0 +0x0000C1E6 0x6F15 # 0 +0x0000C1E7 0x71E5 # 0 +0x0000C1E8 0x4E89 # 0 +0x0000C1E9 0x75E9 # 0 +0x0000C1EA 0x76F8 # 0 +0x0000C1EB 0x7A93 # 0 +0x0000C1EC 0x7CDF # 0 +0x0000C1ED 0x7DCF # 0 +0x0000C1EE 0x7D9C # 0 +0x0000C1EF 0x8061 # 0 +0x0000C1F0 0x8349 # 0 +0x0000C1F1 0x8358 # 0 +0x0000C1F2 0x846C # 0 +0x0000C1F3 0x84BC # 0 +0x0000C1F4 0x85FB # 0 +0x0000C1F5 0x88C5 # 0 +0x0000C1F6 0x8D70 # 0 +0x0000C1F7 0x9001 # 0 +0x0000C1F8 0x906D # 0 +0x0000C1F9 0x9397 # 0 +0x0000C1FA 0x971C # 0 +0x0000C1FB 0x9A12 # 0 +0x0000C1FC 0x50CF # 0 +0x0000C1FD 0x5897 # 0 +0x0000C1FE 0x618E # 0 +0x0000C2A1 0x81D3 # 0 +0x0000C2A2 0x8535 # 0 +0x0000C2A3 0x8D08 # 0 +0x0000C2A4 0x9020 # 0 +0x0000C2A5 0x4FC3 # 0 +0x0000C2A6 0x5074 # 0 +0x0000C2A7 0x5247 # 0 +0x0000C2A8 0x5373 # 0 +0x0000C2A9 0x606F # 0 +0x0000C2AA 0x6349 # 0 +0x0000C2AB 0x675F # 0 +0x0000C2AC 0x6E2C # 0 +0x0000C2AD 0x8DB3 # 0 +0x0000C2AE 0x901F # 0 +0x0000C2AF 0x4FD7 # 0 +0x0000C2B0 0x5C5E # 0 +0x0000C2B1 0x8CCA # 0 +0x0000C2B2 0x65CF # 0 +0x0000C2B3 0x7D9A # 0 +0x0000C2B4 0x5352 # 0 +0x0000C2B5 0x8896 # 0 +0x0000C2B6 0x5176 # 0 +0x0000C2B7 0x63C3 # 0 +0x0000C2B8 0x5B58 # 0 +0x0000C2B9 0x5B6B # 0 +0x0000C2BA 0x5C0A # 0 +0x0000C2BB 0x640D # 0 +0x0000C2BC 0x6751 # 0 +0x0000C2BD 0x905C # 0 +0x0000C2BE 0x4ED6 # 0 +0x0000C2BF 0x591A # 0 +0x0000C2C0 0x592A # 0 +0x0000C2C1 0x6C70 # 0 +0x0000C2C2 0x8A51 # 0 +0x0000C2C3 0x553E # 0 +0x0000C2C4 0x5815 # 0 +0x0000C2C5 0x59A5 # 0 +0x0000C2C6 0x60F0 # 0 +0x0000C2C7 0x6253 # 0 +0x0000C2C8 0x67C1 # 0 +0x0000C2C9 0x8235 # 0 +0x0000C2CA 0x6955 # 0 +0x0000C2CB 0x9640 # 0 +0x0000C2CC 0x99C4 # 0 +0x0000C2CD 0x9A28 # 0 +0x0000C2CE 0x4F53 # 0 +0x0000C2CF 0x5806 # 0 +0x0000C2D0 0x5BFE # 0 +0x0000C2D1 0x8010 # 0 +0x0000C2D2 0x5CB1 # 0 +0x0000C2D3 0x5E2F # 0 +0x0000C2D4 0x5F85 # 0 +0x0000C2D5 0x6020 # 0 +0x0000C2D6 0x614B # 0 +0x0000C2D7 0x6234 # 0 +0x0000C2D8 0x66FF # 0 +0x0000C2D9 0x6CF0 # 0 +0x0000C2DA 0x6EDE # 0 +0x0000C2DB 0x80CE # 0 +0x0000C2DC 0x817F # 0 +0x0000C2DD 0x82D4 # 0 +0x0000C2DE 0x888B # 0 +0x0000C2DF 0x8CB8 # 0 +0x0000C2E0 0x9000 # 0 +0x0000C2E1 0x902E # 0 +0x0000C2E2 0x968A # 0 +0x0000C2E3 0x9EDB # 0 +0x0000C2E4 0x9BDB # 0 +0x0000C2E5 0x4EE3 # 0 +0x0000C2E6 0x53F0 # 0 +0x0000C2E7 0x5927 # 0 +0x0000C2E8 0x7B2C # 0 +0x0000C2E9 0x918D # 0 +0x0000C2EA 0x984C # 0 +0x0000C2EB 0x9DF9 # 0 +0x0000C2EC 0x6EDD # 0 +0x0000C2ED 0x7027 # 0 +0x0000C2EE 0x5353 # 0 +0x0000C2EF 0x5544 # 0 +0x0000C2F0 0x5B85 # 0 +0x0000C2F1 0x6258 # 0 +0x0000C2F2 0x629E # 0 +0x0000C2F3 0x62D3 # 0 +0x0000C2F4 0x6CA2 # 0 +0x0000C2F5 0x6FEF # 0 +0x0000C2F6 0x7422 # 0 +0x0000C2F7 0x8A17 # 0 +0x0000C2F8 0x9438 # 0 +0x0000C2F9 0x6FC1 # 0 +0x0000C2FA 0x8AFE # 0 +0x0000C2FB 0x8338 # 0 +0x0000C2FC 0x51E7 # 0 +0x0000C2FD 0x86F8 # 0 +0x0000C2FE 0x53EA # 0 +0x0000C3A1 0x53E9 # 0 +0x0000C3A2 0x4F46 # 0 +0x0000C3A3 0x9054 # 0 +0x0000C3A4 0x8FB0 # 0 +0x0000C3A5 0x596A # 0 +0x0000C3A6 0x8131 # 0 +0x0000C3A7 0x5DFD # 0 +0x0000C3A8 0x7AEA # 0 +0x0000C3A9 0x8FBF # 0 +0x0000C3AA 0x68DA # 0 +0x0000C3AB 0x8C37 # 0 +0x0000C3AC 0x72F8 # 0 +0x0000C3AD 0x9C48 # 0 +0x0000C3AE 0x6A3D # 0 +0x0000C3AF 0x8AB0 # 0 +0x0000C3B0 0x4E39 # 0 +0x0000C3B1 0x5358 # 0 +0x0000C3B2 0x5606 # 0 +0x0000C3B3 0x5766 # 0 +0x0000C3B4 0x62C5 # 0 +0x0000C3B5 0x63A2 # 0 +0x0000C3B6 0x65E6 # 0 +0x0000C3B7 0x6B4E # 0 +0x0000C3B8 0x6DE1 # 0 +0x0000C3B9 0x6E5B # 0 +0x0000C3BA 0x70AD # 0 +0x0000C3BB 0x77ED # 0 +0x0000C3BC 0x7AEF # 0 +0x0000C3BD 0x7BAA # 0 +0x0000C3BE 0x7DBB # 0 +0x0000C3BF 0x803D # 0 +0x0000C3C0 0x80C6 # 0 +0x0000C3C1 0x86CB # 0 +0x0000C3C2 0x8A95 # 0 +0x0000C3C3 0x935B # 0 +0x0000C3C4 0x56E3 # 0 +0x0000C3C5 0x58C7 # 0 +0x0000C3C6 0x5F3E # 0 +0x0000C3C7 0x65AD # 0 +0x0000C3C8 0x6696 # 0 +0x0000C3C9 0x6A80 # 0 +0x0000C3CA 0x6BB5 # 0 +0x0000C3CB 0x7537 # 0 +0x0000C3CC 0x8AC7 # 0 +0x0000C3CD 0x5024 # 0 +0x0000C3CE 0x77E5 # 0 +0x0000C3CF 0x5730 # 0 +0x0000C3D0 0x5F1B # 0 +0x0000C3D1 0x6065 # 0 +0x0000C3D2 0x667A # 0 +0x0000C3D3 0x6C60 # 0 +0x0000C3D4 0x75F4 # 0 +0x0000C3D5 0x7A1A # 0 +0x0000C3D6 0x7F6E # 0 +0x0000C3D7 0x81F4 # 0 +0x0000C3D8 0x8718 # 0 +0x0000C3D9 0x9045 # 0 +0x0000C3DA 0x99B3 # 0 +0x0000C3DB 0x7BC9 # 0 +0x0000C3DC 0x755C # 0 +0x0000C3DD 0x7AF9 # 0 +0x0000C3DE 0x7B51 # 0 +0x0000C3DF 0x84C4 # 0 +0x0000C3E0 0x9010 # 0 +0x0000C3E1 0x79E9 # 0 +0x0000C3E2 0x7A92 # 0 +0x0000C3E3 0x8336 # 0 +0x0000C3E4 0x5AE1 # 0 +0x0000C3E5 0x7740 # 0 +0x0000C3E6 0x4E2D # 0 +0x0000C3E7 0x4EF2 # 0 +0x0000C3E8 0x5B99 # 0 +0x0000C3E9 0x5FE0 # 0 +0x0000C3EA 0x62BD # 0 +0x0000C3EB 0x663C # 0 +0x0000C3EC 0x67F1 # 0 +0x0000C3ED 0x6CE8 # 0 +0x0000C3EE 0x866B # 0 +0x0000C3EF 0x8877 # 0 +0x0000C3F0 0x8A3B # 0 +0x0000C3F1 0x914E # 0 +0x0000C3F2 0x92F3 # 0 +0x0000C3F3 0x99D0 # 0 +0x0000C3F4 0x6A17 # 0 +0x0000C3F5 0x7026 # 0 +0x0000C3F6 0x732A # 0 +0x0000C3F7 0x82E7 # 0 +0x0000C3F8 0x8457 # 0 +0x0000C3F9 0x8CAF # 0 +0x0000C3FA 0x4E01 # 0 +0x0000C3FB 0x5146 # 0 +0x0000C3FC 0x51CB # 0 +0x0000C3FD 0x558B # 0 +0x0000C3FE 0x5BF5 # 0 +0x0000C4A1 0x5E16 # 0 +0x0000C4A2 0x5E33 # 0 +0x0000C4A3 0x5E81 # 0 +0x0000C4A4 0x5F14 # 0 +0x0000C4A5 0x5F35 # 0 +0x0000C4A6 0x5F6B # 0 +0x0000C4A7 0x5FB4 # 0 +0x0000C4A8 0x61F2 # 0 +0x0000C4A9 0x6311 # 0 +0x0000C4AA 0x66A2 # 0 +0x0000C4AB 0x671D # 0 +0x0000C4AC 0x6F6E # 0 +0x0000C4AD 0x7252 # 0 +0x0000C4AE 0x753A # 0 +0x0000C4AF 0x773A # 0 +0x0000C4B0 0x8074 # 0 +0x0000C4B1 0x8139 # 0 +0x0000C4B2 0x8178 # 0 +0x0000C4B3 0x8776 # 0 +0x0000C4B4 0x8ABF # 0 +0x0000C4B5 0x8ADC # 0 +0x0000C4B6 0x8D85 # 0 +0x0000C4B7 0x8DF3 # 0 +0x0000C4B8 0x929A # 0 +0x0000C4B9 0x9577 # 0 +0x0000C4BA 0x9802 # 0 +0x0000C4BB 0x9CE5 # 0 +0x0000C4BC 0x52C5 # 0 +0x0000C4BD 0x6357 # 0 +0x0000C4BE 0x76F4 # 0 +0x0000C4BF 0x6715 # 0 +0x0000C4C0 0x6C88 # 0 +0x0000C4C1 0x73CD # 0 +0x0000C4C2 0x8CC3 # 0 +0x0000C4C3 0x93AE # 0 +0x0000C4C4 0x9673 # 0 +0x0000C4C5 0x6D25 # 0 +0x0000C4C6 0x589C # 0 +0x0000C4C7 0x690E # 0 +0x0000C4C8 0x69CC # 0 +0x0000C4C9 0x8FFD # 0 +0x0000C4CA 0x939A # 0 +0x0000C4CB 0x75DB # 0 +0x0000C4CC 0x901A # 0 +0x0000C4CD 0x585A # 0 +0x0000C4CE 0x6802 # 0 +0x0000C4CF 0x63B4 # 0 +0x0000C4D0 0x69FB # 0 +0x0000C4D1 0x4F43 # 0 +0x0000C4D2 0x6F2C # 0 +0x0000C4D3 0x67D8 # 0 +0x0000C4D4 0x8FBB # 0 +0x0000C4D5 0x8526 # 0 +0x0000C4D6 0x7DB4 # 0 +0x0000C4D7 0x9354 # 0 +0x0000C4D8 0x693F # 0 +0x0000C4D9 0x6F70 # 0 +0x0000C4DA 0x576A # 0 +0x0000C4DB 0x58F7 # 0 +0x0000C4DC 0x5B2C # 0 +0x0000C4DD 0x7D2C # 0 +0x0000C4DE 0x722A # 0 +0x0000C4DF 0x540A # 0 +0x0000C4E0 0x91E3 # 0 +0x0000C4E1 0x9DB4 # 0 +0x0000C4E2 0x4EAD # 0 +0x0000C4E3 0x4F4E # 0 +0x0000C4E4 0x505C # 0 +0x0000C4E5 0x5075 # 0 +0x0000C4E6 0x5243 # 0 +0x0000C4E7 0x8C9E # 0 +0x0000C4E8 0x5448 # 0 +0x0000C4E9 0x5824 # 0 +0x0000C4EA 0x5B9A # 0 +0x0000C4EB 0x5E1D # 0 +0x0000C4EC 0x5E95 # 0 +0x0000C4ED 0x5EAD # 0 +0x0000C4EE 0x5EF7 # 0 +0x0000C4EF 0x5F1F # 0 +0x0000C4F0 0x608C # 0 +0x0000C4F1 0x62B5 # 0 +0x0000C4F2 0x633A # 0 +0x0000C4F3 0x63D0 # 0 +0x0000C4F4 0x68AF # 0 +0x0000C4F5 0x6C40 # 0 +0x0000C4F6 0x7887 # 0 +0x0000C4F7 0x798E # 0 +0x0000C4F8 0x7A0B # 0 +0x0000C4F9 0x7DE0 # 0 +0x0000C4FA 0x8247 # 0 +0x0000C4FB 0x8A02 # 0 +0x0000C4FC 0x8AE6 # 0 +0x0000C4FD 0x8E44 # 0 +0x0000C4FE 0x9013 # 0 +0x0000C5A1 0x90B8 # 0 +0x0000C5A2 0x912D # 0 +0x0000C5A3 0x91D8 # 0 +0x0000C5A4 0x9F0E # 0 +0x0000C5A5 0x6CE5 # 0 +0x0000C5A6 0x6458 # 0 +0x0000C5A7 0x64E2 # 0 +0x0000C5A8 0x6575 # 0 +0x0000C5A9 0x6EF4 # 0 +0x0000C5AA 0x7684 # 0 +0x0000C5AB 0x7B1B # 0 +0x0000C5AC 0x9069 # 0 +0x0000C5AD 0x93D1 # 0 +0x0000C5AE 0x6EBA # 0 +0x0000C5AF 0x54F2 # 0 +0x0000C5B0 0x5FB9 # 0 +0x0000C5B1 0x64A4 # 0 +0x0000C5B2 0x8F4D # 0 +0x0000C5B3 0x8FED # 0 +0x0000C5B4 0x9244 # 0 +0x0000C5B5 0x5178 # 0 +0x0000C5B6 0x586B # 0 +0x0000C5B7 0x5929 # 0 +0x0000C5B8 0x5C55 # 0 +0x0000C5B9 0x5E97 # 0 +0x0000C5BA 0x6DFB # 0 +0x0000C5BB 0x7E8F # 0 +0x0000C5BC 0x751C # 0 +0x0000C5BD 0x8CBC # 0 +0x0000C5BE 0x8EE2 # 0 +0x0000C5BF 0x985B # 0 +0x0000C5C0 0x70B9 # 0 +0x0000C5C1 0x4F1D # 0 +0x0000C5C2 0x6BBF # 0 +0x0000C5C3 0x6FB1 # 0 +0x0000C5C4 0x7530 # 0 +0x0000C5C5 0x96FB # 0 +0x0000C5C6 0x514E # 0 +0x0000C5C7 0x5410 # 0 +0x0000C5C8 0x5835 # 0 +0x0000C5C9 0x5857 # 0 +0x0000C5CA 0x59AC # 0 +0x0000C5CB 0x5C60 # 0 +0x0000C5CC 0x5F92 # 0 +0x0000C5CD 0x6597 # 0 +0x0000C5CE 0x675C # 0 +0x0000C5CF 0x6E21 # 0 +0x0000C5D0 0x767B # 0 +0x0000C5D1 0x83DF # 0 +0x0000C5D2 0x8CED # 0 +0x0000C5D3 0x9014 # 0 +0x0000C5D4 0x90FD # 0 +0x0000C5D5 0x934D # 0 +0x0000C5D6 0x7825 # 0 +0x0000C5D7 0x783A # 0 +0x0000C5D8 0x52AA # 0 +0x0000C5D9 0x5EA6 # 0 +0x0000C5DA 0x571F # 0 +0x0000C5DB 0x5974 # 0 +0x0000C5DC 0x6012 # 0 +0x0000C5DD 0x5012 # 0 +0x0000C5DE 0x515A # 0 +0x0000C5DF 0x51AC # 0 +0x0000C5E0 0x51CD # 0 +0x0000C5E1 0x5200 # 0 +0x0000C5E2 0x5510 # 0 +0x0000C5E3 0x5854 # 0 +0x0000C5E4 0x5858 # 0 +0x0000C5E5 0x5957 # 0 +0x0000C5E6 0x5B95 # 0 +0x0000C5E7 0x5CF6 # 0 +0x0000C5E8 0x5D8B # 0 +0x0000C5E9 0x60BC # 0 +0x0000C5EA 0x6295 # 0 +0x0000C5EB 0x642D # 0 +0x0000C5EC 0x6771 # 0 +0x0000C5ED 0x6843 # 0 +0x0000C5EE 0x68BC # 0 +0x0000C5EF 0x68DF # 0 +0x0000C5F0 0x76D7 # 0 +0x0000C5F1 0x6DD8 # 0 +0x0000C5F2 0x6E6F # 0 +0x0000C5F3 0x6D9B # 0 +0x0000C5F4 0x706F # 0 +0x0000C5F5 0x71C8 # 0 +0x0000C5F6 0x5F53 # 0 +0x0000C5F7 0x75D8 # 0 +0x0000C5F8 0x7977 # 0 +0x0000C5F9 0x7B49 # 0 +0x0000C5FA 0x7B54 # 0 +0x0000C5FB 0x7B52 # 0 +0x0000C5FC 0x7CD6 # 0 +0x0000C5FD 0x7D71 # 0 +0x0000C5FE 0x5230 # 0 +0x0000C6A1 0x8463 # 0 +0x0000C6A2 0x8569 # 0 +0x0000C6A3 0x85E4 # 0 +0x0000C6A4 0x8A0E # 0 +0x0000C6A5 0x8B04 # 0 +0x0000C6A6 0x8C46 # 0 +0x0000C6A7 0x8E0F # 0 +0x0000C6A8 0x9003 # 0 +0x0000C6A9 0x900F # 0 +0x0000C6AA 0x9419 # 0 +0x0000C6AB 0x9676 # 0 +0x0000C6AC 0x982D # 0 +0x0000C6AD 0x9A30 # 0 +0x0000C6AE 0x95D8 # 0 +0x0000C6AF 0x50CD # 0 +0x0000C6B0 0x52D5 # 0 +0x0000C6B1 0x540C # 0 +0x0000C6B2 0x5802 # 0 +0x0000C6B3 0x5C0E # 0 +0x0000C6B4 0x61A7 # 0 +0x0000C6B5 0x649E # 0 +0x0000C6B6 0x6D1E # 0 +0x0000C6B7 0x77B3 # 0 +0x0000C6B8 0x7AE5 # 0 +0x0000C6B9 0x80F4 # 0 +0x0000C6BA 0x8404 # 0 +0x0000C6BB 0x9053 # 0 +0x0000C6BC 0x9285 # 0 +0x0000C6BD 0x5CE0 # 0 +0x0000C6BE 0x9D07 # 0 +0x0000C6BF 0x533F # 0 +0x0000C6C0 0x5F97 # 0 +0x0000C6C1 0x5FB3 # 0 +0x0000C6C2 0x6D9C # 0 +0x0000C6C3 0x7279 # 0 +0x0000C6C4 0x7763 # 0 +0x0000C6C5 0x79BF # 0 +0x0000C6C6 0x7BE4 # 0 +0x0000C6C7 0x6BD2 # 0 +0x0000C6C8 0x72EC # 0 +0x0000C6C9 0x8AAD # 0 +0x0000C6CA 0x6803 # 0 +0x0000C6CB 0x6A61 # 0 +0x0000C6CC 0x51F8 # 0 +0x0000C6CD 0x7A81 # 0 +0x0000C6CE 0x6934 # 0 +0x0000C6CF 0x5C4A # 0 +0x0000C6D0 0x9CF6 # 0 +0x0000C6D1 0x82EB # 0 +0x0000C6D2 0x5BC5 # 0 +0x0000C6D3 0x9149 # 0 +0x0000C6D4 0x701E # 0 +0x0000C6D5 0x5678 # 0 +0x0000C6D6 0x5C6F # 0 +0x0000C6D7 0x60C7 # 0 +0x0000C6D8 0x6566 # 0 +0x0000C6D9 0x6C8C # 0 +0x0000C6DA 0x8C5A # 0 +0x0000C6DB 0x9041 # 0 +0x0000C6DC 0x9813 # 0 +0x0000C6DD 0x5451 # 0 +0x0000C6DE 0x66C7 # 0 +0x0000C6DF 0x920D # 0 +0x0000C6E0 0x5948 # 0 +0x0000C6E1 0x90A3 # 0 +0x0000C6E2 0x5185 # 0 +0x0000C6E3 0x4E4D # 0 +0x0000C6E4 0x51EA # 0 +0x0000C6E5 0x8599 # 0 +0x0000C6E6 0x8B0E # 0 +0x0000C6E7 0x7058 # 0 +0x0000C6E8 0x637A # 0 +0x0000C6E9 0x934B # 0 +0x0000C6EA 0x6962 # 0 +0x0000C6EB 0x99B4 # 0 +0x0000C6EC 0x7E04 # 0 +0x0000C6ED 0x7577 # 0 +0x0000C6EE 0x5357 # 0 +0x0000C6EF 0x6960 # 0 +0x0000C6F0 0x8EDF # 0 +0x0000C6F1 0x96E3 # 0 +0x0000C6F2 0x6C5D # 0 +0x0000C6F3 0x4E8C # 0 +0x0000C6F4 0x5C3C # 0 +0x0000C6F5 0x5F10 # 0 +0x0000C6F6 0x8FE9 # 0 +0x0000C6F7 0x5302 # 0 +0x0000C6F8 0x8CD1 # 0 +0x0000C6F9 0x8089 # 0 +0x0000C6FA 0x8679 # 0 +0x0000C6FB 0x5EFF # 0 +0x0000C6FC 0x65E5 # 0 +0x0000C6FD 0x4E73 # 0 +0x0000C6FE 0x5165 # 0 +0x0000C7A1 0x5982 # 0 +0x0000C7A2 0x5C3F # 0 +0x0000C7A3 0x97EE # 0 +0x0000C7A4 0x4EFB # 0 +0x0000C7A5 0x598A # 0 +0x0000C7A6 0x5FCD # 0 +0x0000C7A7 0x8A8D # 0 +0x0000C7A8 0x6FE1 # 0 +0x0000C7A9 0x79B0 # 0 +0x0000C7AA 0x7962 # 0 +0x0000C7AB 0x5BE7 # 0 +0x0000C7AC 0x8471 # 0 +0x0000C7AD 0x732B # 0 +0x0000C7AE 0x71B1 # 0 +0x0000C7AF 0x5E74 # 0 +0x0000C7B0 0x5FF5 # 0 +0x0000C7B1 0x637B # 0 +0x0000C7B2 0x649A # 0 +0x0000C7B3 0x71C3 # 0 +0x0000C7B4 0x7C98 # 0 +0x0000C7B5 0x4E43 # 0 +0x0000C7B6 0x5EFC # 0 +0x0000C7B7 0x4E4B # 0 +0x0000C7B8 0x57DC # 0 +0x0000C7B9 0x56A2 # 0 +0x0000C7BA 0x60A9 # 0 +0x0000C7BB 0x6FC3 # 0 +0x0000C7BC 0x7D0D # 0 +0x0000C7BD 0x80FD # 0 +0x0000C7BE 0x8133 # 0 +0x0000C7BF 0x81BF # 0 +0x0000C7C0 0x8FB2 # 0 +0x0000C7C1 0x8997 # 0 +0x0000C7C2 0x86A4 # 0 +0x0000C7C3 0x5DF4 # 0 +0x0000C7C4 0x628A # 0 +0x0000C7C5 0x64AD # 0 +0x0000C7C6 0x8987 # 0 +0x0000C7C7 0x6777 # 0 +0x0000C7C8 0x6CE2 # 0 +0x0000C7C9 0x6D3E # 0 +0x0000C7CA 0x7436 # 0 +0x0000C7CB 0x7834 # 0 +0x0000C7CC 0x5A46 # 0 +0x0000C7CD 0x7F75 # 0 +0x0000C7CE 0x82AD # 0 +0x0000C7CF 0x99AC # 0 +0x0000C7D0 0x4FF3 # 0 +0x0000C7D1 0x5EC3 # 0 +0x0000C7D2 0x62DD # 0 +0x0000C7D3 0x6392 # 0 +0x0000C7D4 0x6557 # 0 +0x0000C7D5 0x676F # 0 +0x0000C7D6 0x76C3 # 0 +0x0000C7D7 0x724C # 0 +0x0000C7D8 0x80CC # 0 +0x0000C7D9 0x80BA # 0 +0x0000C7DA 0x8F29 # 0 +0x0000C7DB 0x914D # 0 +0x0000C7DC 0x500D # 0 +0x0000C7DD 0x57F9 # 0 +0x0000C7DE 0x5A92 # 0 +0x0000C7DF 0x6885 # 0 +0x0000C7E0 0x6973 # 0 +0x0000C7E1 0x7164 # 0 +0x0000C7E2 0x72FD # 0 +0x0000C7E3 0x8CB7 # 0 +0x0000C7E4 0x58F2 # 0 +0x0000C7E5 0x8CE0 # 0 +0x0000C7E6 0x966A # 0 +0x0000C7E7 0x9019 # 0 +0x0000C7E8 0x877F # 0 +0x0000C7E9 0x79E4 # 0 +0x0000C7EA 0x77E7 # 0 +0x0000C7EB 0x8429 # 0 +0x0000C7EC 0x4F2F # 0 +0x0000C7ED 0x5265 # 0 +0x0000C7EE 0x535A # 0 +0x0000C7EF 0x62CD # 0 +0x0000C7F0 0x67CF # 0 +0x0000C7F1 0x6CCA # 0 +0x0000C7F2 0x767D # 0 +0x0000C7F3 0x7B94 # 0 +0x0000C7F4 0x7C95 # 0 +0x0000C7F5 0x8236 # 0 +0x0000C7F6 0x8584 # 0 +0x0000C7F7 0x8FEB # 0 +0x0000C7F8 0x66DD # 0 +0x0000C7F9 0x6F20 # 0 +0x0000C7FA 0x7206 # 0 +0x0000C7FB 0x7E1B # 0 +0x0000C7FC 0x83AB # 0 +0x0000C7FD 0x99C1 # 0 +0x0000C7FE 0x9EA6 # 0 +0x0000C8A1 0x51FD # 0 +0x0000C8A2 0x7BB1 # 0 +0x0000C8A3 0x7872 # 0 +0x0000C8A4 0x7BB8 # 0 +0x0000C8A5 0x8087 # 0 +0x0000C8A6 0x7B48 # 0 +0x0000C8A7 0x6AE8 # 0 +0x0000C8A8 0x5E61 # 0 +0x0000C8A9 0x808C # 0 +0x0000C8AA 0x7551 # 0 +0x0000C8AB 0x7560 # 0 +0x0000C8AC 0x516B # 0 +0x0000C8AD 0x9262 # 0 +0x0000C8AE 0x6E8C # 0 +0x0000C8AF 0x767A # 0 +0x0000C8B0 0x9197 # 0 +0x0000C8B1 0x9AEA # 0 +0x0000C8B2 0x4F10 # 0 +0x0000C8B3 0x7F70 # 0 +0x0000C8B4 0x629C # 0 +0x0000C8B5 0x7B4F # 0 +0x0000C8B6 0x95A5 # 0 +0x0000C8B7 0x9CE9 # 0 +0x0000C8B8 0x567A # 0 +0x0000C8B9 0x5859 # 0 +0x0000C8BA 0x86E4 # 0 +0x0000C8BB 0x96BC # 0 +0x0000C8BC 0x4F34 # 0 +0x0000C8BD 0x5224 # 0 +0x0000C8BE 0x534A # 0 +0x0000C8BF 0x53CD # 0 +0x0000C8C0 0x53DB # 0 +0x0000C8C1 0x5E06 # 0 +0x0000C8C2 0x642C # 0 +0x0000C8C3 0x6591 # 0 +0x0000C8C4 0x677F # 0 +0x0000C8C5 0x6C3E # 0 +0x0000C8C6 0x6C4E # 0 +0x0000C8C7 0x7248 # 0 +0x0000C8C8 0x72AF # 0 +0x0000C8C9 0x73ED # 0 +0x0000C8CA 0x7554 # 0 +0x0000C8CB 0x7E41 # 0 +0x0000C8CC 0x822C # 0 +0x0000C8CD 0x85E9 # 0 +0x0000C8CE 0x8CA9 # 0 +0x0000C8CF 0x7BC4 # 0 +0x0000C8D0 0x91C6 # 0 +0x0000C8D1 0x7169 # 0 +0x0000C8D2 0x9812 # 0 +0x0000C8D3 0x98EF # 0 +0x0000C8D4 0x633D # 0 +0x0000C8D5 0x6669 # 0 +0x0000C8D6 0x756A # 0 +0x0000C8D7 0x76E4 # 0 +0x0000C8D8 0x78D0 # 0 +0x0000C8D9 0x8543 # 0 +0x0000C8DA 0x86EE # 0 +0x0000C8DB 0x532A # 0 +0x0000C8DC 0x5351 # 0 +0x0000C8DD 0x5426 # 0 +0x0000C8DE 0x5983 # 0 +0x0000C8DF 0x5E87 # 0 +0x0000C8E0 0x5F7C # 0 +0x0000C8E1 0x60B2 # 0 +0x0000C8E2 0x6249 # 0 +0x0000C8E3 0x6279 # 0 +0x0000C8E4 0x62AB # 0 +0x0000C8E5 0x6590 # 0 +0x0000C8E6 0x6BD4 # 0 +0x0000C8E7 0x6CCC # 0 +0x0000C8E8 0x75B2 # 0 +0x0000C8E9 0x76AE # 0 +0x0000C8EA 0x7891 # 0 +0x0000C8EB 0x79D8 # 0 +0x0000C8EC 0x7DCB # 0 +0x0000C8ED 0x7F77 # 0 +0x0000C8EE 0x80A5 # 0 +0x0000C8EF 0x88AB # 0 +0x0000C8F0 0x8AB9 # 0 +0x0000C8F1 0x8CBB # 0 +0x0000C8F2 0x907F # 0 +0x0000C8F3 0x975E # 0 +0x0000C8F4 0x98DB # 0 +0x0000C8F5 0x6A0B # 0 +0x0000C8F6 0x7C38 # 0 +0x0000C8F7 0x5099 # 0 +0x0000C8F8 0x5C3E # 0 +0x0000C8F9 0x5FAE # 0 +0x0000C8FA 0x6787 # 0 +0x0000C8FB 0x6BD8 # 0 +0x0000C8FC 0x7435 # 0 +0x0000C8FD 0x7709 # 0 +0x0000C8FE 0x7F8E # 0 +0x0000C9A1 0x9F3B # 0 +0x0000C9A2 0x67CA # 0 +0x0000C9A3 0x7A17 # 0 +0x0000C9A4 0x5339 # 0 +0x0000C9A5 0x758B # 0 +0x0000C9A6 0x9AED # 0 +0x0000C9A7 0x5F66 # 0 +0x0000C9A8 0x819D # 0 +0x0000C9A9 0x83F1 # 0 +0x0000C9AA 0x8098 # 0 +0x0000C9AB 0x5F3C # 0 +0x0000C9AC 0x5FC5 # 0 +0x0000C9AD 0x7562 # 0 +0x0000C9AE 0x7B46 # 0 +0x0000C9AF 0x903C # 0 +0x0000C9B0 0x6867 # 0 +0x0000C9B1 0x59EB # 0 +0x0000C9B2 0x5A9B # 0 +0x0000C9B3 0x7D10 # 0 +0x0000C9B4 0x767E # 0 +0x0000C9B5 0x8B2C # 0 +0x0000C9B6 0x4FF5 # 0 +0x0000C9B7 0x5F6A # 0 +0x0000C9B8 0x6A19 # 0 +0x0000C9B9 0x6C37 # 0 +0x0000C9BA 0x6F02 # 0 +0x0000C9BB 0x74E2 # 0 +0x0000C9BC 0x7968 # 0 +0x0000C9BD 0x8868 # 0 +0x0000C9BE 0x8A55 # 0 +0x0000C9BF 0x8C79 # 0 +0x0000C9C0 0x5EDF # 0 +0x0000C9C1 0x63CF # 0 +0x0000C9C2 0x75C5 # 0 +0x0000C9C3 0x79D2 # 0 +0x0000C9C4 0x82D7 # 0 +0x0000C9C5 0x9328 # 0 +0x0000C9C6 0x92F2 # 0 +0x0000C9C7 0x849C # 0 +0x0000C9C8 0x86ED # 0 +0x0000C9C9 0x9C2D # 0 +0x0000C9CA 0x54C1 # 0 +0x0000C9CB 0x5F6C # 0 +0x0000C9CC 0x658C # 0 +0x0000C9CD 0x6D5C # 0 +0x0000C9CE 0x7015 # 0 +0x0000C9CF 0x8CA7 # 0 +0x0000C9D0 0x8CD3 # 0 +0x0000C9D1 0x983B # 0 +0x0000C9D2 0x654F # 0 +0x0000C9D3 0x74F6 # 0 +0x0000C9D4 0x4E0D # 0 +0x0000C9D5 0x4ED8 # 0 +0x0000C9D6 0x57E0 # 0 +0x0000C9D7 0x592B # 0 +0x0000C9D8 0x5A66 # 0 +0x0000C9D9 0x5BCC # 0 +0x0000C9DA 0x51A8 # 0 +0x0000C9DB 0x5E03 # 0 +0x0000C9DC 0x5E9C # 0 +0x0000C9DD 0x6016 # 0 +0x0000C9DE 0x6276 # 0 +0x0000C9DF 0x6577 # 0 +0x0000C9E0 0x65A7 # 0 +0x0000C9E1 0x666E # 0 +0x0000C9E2 0x6D6E # 0 +0x0000C9E3 0x7236 # 0 +0x0000C9E4 0x7B26 # 0 +0x0000C9E5 0x8150 # 0 +0x0000C9E6 0x819A # 0 +0x0000C9E7 0x8299 # 0 +0x0000C9E8 0x8B5C # 0 +0x0000C9E9 0x8CA0 # 0 +0x0000C9EA 0x8CE6 # 0 +0x0000C9EB 0x8D74 # 0 +0x0000C9EC 0x961C # 0 +0x0000C9ED 0x9644 # 0 +0x0000C9EE 0x4FAE # 0 +0x0000C9EF 0x64AB # 0 +0x0000C9F0 0x6B66 # 0 +0x0000C9F1 0x821E # 0 +0x0000C9F2 0x8461 # 0 +0x0000C9F3 0x856A # 0 +0x0000C9F4 0x90E8 # 0 +0x0000C9F5 0x5C01 # 0 +0x0000C9F6 0x6953 # 0 +0x0000C9F7 0x98A8 # 0 +0x0000C9F8 0x847A # 0 +0x0000C9F9 0x8557 # 0 +0x0000C9FA 0x4F0F # 0 +0x0000C9FB 0x526F # 0 +0x0000C9FC 0x5FA9 # 0 +0x0000C9FD 0x5E45 # 0 +0x0000C9FE 0x670D # 0 +0x0000CAA1 0x798F # 0 +0x0000CAA2 0x8179 # 0 +0x0000CAA3 0x8907 # 0 +0x0000CAA4 0x8986 # 0 +0x0000CAA5 0x6DF5 # 0 +0x0000CAA6 0x5F17 # 0 +0x0000CAA7 0x6255 # 0 +0x0000CAA8 0x6CB8 # 0 +0x0000CAA9 0x4ECF # 0 +0x0000CAAA 0x7269 # 0 +0x0000CAAB 0x9B92 # 0 +0x0000CAAC 0x5206 # 0 +0x0000CAAD 0x543B # 0 +0x0000CAAE 0x5674 # 0 +0x0000CAAF 0x58B3 # 0 +0x0000CAB0 0x61A4 # 0 +0x0000CAB1 0x626E # 0 +0x0000CAB2 0x711A # 0 +0x0000CAB3 0x596E # 0 +0x0000CAB4 0x7C89 # 0 +0x0000CAB5 0x7CDE # 0 +0x0000CAB6 0x7D1B # 0 +0x0000CAB7 0x96F0 # 0 +0x0000CAB8 0x6587 # 0 +0x0000CAB9 0x805E # 0 +0x0000CABA 0x4E19 # 0 +0x0000CABB 0x4F75 # 0 +0x0000CABC 0x5175 # 0 +0x0000CABD 0x5840 # 0 +0x0000CABE 0x5E63 # 0 +0x0000CABF 0x5E73 # 0 +0x0000CAC0 0x5F0A # 0 +0x0000CAC1 0x67C4 # 0 +0x0000CAC2 0x4E26 # 0 +0x0000CAC3 0x853D # 0 +0x0000CAC4 0x9589 # 0 +0x0000CAC5 0x965B # 0 +0x0000CAC6 0x7C73 # 0 +0x0000CAC7 0x9801 # 0 +0x0000CAC8 0x50FB # 0 +0x0000CAC9 0x58C1 # 0 +0x0000CACA 0x7656 # 0 +0x0000CACB 0x78A7 # 0 +0x0000CACC 0x5225 # 0 +0x0000CACD 0x77A5 # 0 +0x0000CACE 0x8511 # 0 +0x0000CACF 0x7B86 # 0 +0x0000CAD0 0x504F # 0 +0x0000CAD1 0x5909 # 0 +0x0000CAD2 0x7247 # 0 +0x0000CAD3 0x7BC7 # 0 +0x0000CAD4 0x7DE8 # 0 +0x0000CAD5 0x8FBA # 0 +0x0000CAD6 0x8FD4 # 0 +0x0000CAD7 0x904D # 0 +0x0000CAD8 0x4FBF # 0 +0x0000CAD9 0x52C9 # 0 +0x0000CADA 0x5A29 # 0 +0x0000CADB 0x5F01 # 0 +0x0000CADC 0x97AD # 0 +0x0000CADD 0x4FDD # 0 +0x0000CADE 0x8217 # 0 +0x0000CADF 0x92EA # 0 +0x0000CAE0 0x5703 # 0 +0x0000CAE1 0x6355 # 0 +0x0000CAE2 0x6B69 # 0 +0x0000CAE3 0x752B # 0 +0x0000CAE4 0x88DC # 0 +0x0000CAE5 0x8F14 # 0 +0x0000CAE6 0x7A42 # 0 +0x0000CAE7 0x52DF # 0 +0x0000CAE8 0x5893 # 0 +0x0000CAE9 0x6155 # 0 +0x0000CAEA 0x620A # 0 +0x0000CAEB 0x66AE # 0 +0x0000CAEC 0x6BCD # 0 +0x0000CAED 0x7C3F # 0 +0x0000CAEE 0x83E9 # 0 +0x0000CAEF 0x5023 # 0 +0x0000CAF0 0x4FF8 # 0 +0x0000CAF1 0x5305 # 0 +0x0000CAF2 0x5446 # 0 +0x0000CAF3 0x5831 # 0 +0x0000CAF4 0x5949 # 0 +0x0000CAF5 0x5B9D # 0 +0x0000CAF6 0x5CF0 # 0 +0x0000CAF7 0x5CEF # 0 +0x0000CAF8 0x5D29 # 0 +0x0000CAF9 0x5E96 # 0 +0x0000CAFA 0x62B1 # 0 +0x0000CAFB 0x6367 # 0 +0x0000CAFC 0x653E # 0 +0x0000CAFD 0x65B9 # 0 +0x0000CAFE 0x670B # 0 +0x0000CBA1 0x6CD5 # 0 +0x0000CBA2 0x6CE1 # 0 +0x0000CBA3 0x70F9 # 0 +0x0000CBA4 0x7832 # 0 +0x0000CBA5 0x7E2B # 0 +0x0000CBA6 0x80DE # 0 +0x0000CBA7 0x82B3 # 0 +0x0000CBA8 0x840C # 0 +0x0000CBA9 0x84EC # 0 +0x0000CBAA 0x8702 # 0 +0x0000CBAB 0x8912 # 0 +0x0000CBAC 0x8A2A # 0 +0x0000CBAD 0x8C4A # 0 +0x0000CBAE 0x90A6 # 0 +0x0000CBAF 0x92D2 # 0 +0x0000CBB0 0x98FD # 0 +0x0000CBB1 0x9CF3 # 0 +0x0000CBB2 0x9D6C # 0 +0x0000CBB3 0x4E4F # 0 +0x0000CBB4 0x4EA1 # 0 +0x0000CBB5 0x508D # 0 +0x0000CBB6 0x5256 # 0 +0x0000CBB7 0x574A # 0 +0x0000CBB8 0x59A8 # 0 +0x0000CBB9 0x5E3D # 0 +0x0000CBBA 0x5FD8 # 0 +0x0000CBBB 0x5FD9 # 0 +0x0000CBBC 0x623F # 0 +0x0000CBBD 0x66B4 # 0 +0x0000CBBE 0x671B # 0 +0x0000CBBF 0x67D0 # 0 +0x0000CBC0 0x68D2 # 0 +0x0000CBC1 0x5192 # 0 +0x0000CBC2 0x7D21 # 0 +0x0000CBC3 0x80AA # 0 +0x0000CBC4 0x81A8 # 0 +0x0000CBC5 0x8B00 # 0 +0x0000CBC6 0x8C8C # 0 +0x0000CBC7 0x8CBF # 0 +0x0000CBC8 0x927E # 0 +0x0000CBC9 0x9632 # 0 +0x0000CBCA 0x5420 # 0 +0x0000CBCB 0x982C # 0 +0x0000CBCC 0x5317 # 0 +0x0000CBCD 0x50D5 # 0 +0x0000CBCE 0x535C # 0 +0x0000CBCF 0x58A8 # 0 +0x0000CBD0 0x64B2 # 0 +0x0000CBD1 0x6734 # 0 +0x0000CBD2 0x7267 # 0 +0x0000CBD3 0x7766 # 0 +0x0000CBD4 0x7A46 # 0 +0x0000CBD5 0x91E6 # 0 +0x0000CBD6 0x52C3 # 0 +0x0000CBD7 0x6CA1 # 0 +0x0000CBD8 0x6B86 # 0 +0x0000CBD9 0x5800 # 0 +0x0000CBDA 0x5E4C # 0 +0x0000CBDB 0x5954 # 0 +0x0000CBDC 0x672C # 0 +0x0000CBDD 0x7FFB # 0 +0x0000CBDE 0x51E1 # 0 +0x0000CBDF 0x76C6 # 0 +0x0000CBE0 0x6469 # 0 +0x0000CBE1 0x78E8 # 0 +0x0000CBE2 0x9B54 # 0 +0x0000CBE3 0x9EBB # 0 +0x0000CBE4 0x57CB # 0 +0x0000CBE5 0x59B9 # 0 +0x0000CBE6 0x6627 # 0 +0x0000CBE7 0x679A # 0 +0x0000CBE8 0x6BCE # 0 +0x0000CBE9 0x54E9 # 0 +0x0000CBEA 0x69D9 # 0 +0x0000CBEB 0x5E55 # 0 +0x0000CBEC 0x819C # 0 +0x0000CBED 0x6795 # 0 +0x0000CBEE 0x9BAA # 0 +0x0000CBEF 0x67FE # 0 +0x0000CBF0 0x9C52 # 0 +0x0000CBF1 0x685D # 0 +0x0000CBF2 0x4EA6 # 0 +0x0000CBF3 0x4FE3 # 0 +0x0000CBF4 0x53C8 # 0 +0x0000CBF5 0x62B9 # 0 +0x0000CBF6 0x672B # 0 +0x0000CBF7 0x6CAB # 0 +0x0000CBF8 0x8FC4 # 0 +0x0000CBF9 0x4FAD # 0 +0x0000CBFA 0x7E6D # 0 +0x0000CBFB 0x9EBF # 0 +0x0000CBFC 0x4E07 # 0 +0x0000CBFD 0x6162 # 0 +0x0000CBFE 0x6E80 # 0 +0x0000CCA1 0x6F2B # 0 +0x0000CCA2 0x8513 # 0 +0x0000CCA3 0x5473 # 0 +0x0000CCA4 0x672A # 0 +0x0000CCA5 0x9B45 # 0 +0x0000CCA6 0x5DF3 # 0 +0x0000CCA7 0x7B95 # 0 +0x0000CCA8 0x5CAC # 0 +0x0000CCA9 0x5BC6 # 0 +0x0000CCAA 0x871C # 0 +0x0000CCAB 0x6E4A # 0 +0x0000CCAC 0x84D1 # 0 +0x0000CCAD 0x7A14 # 0 +0x0000CCAE 0x8108 # 0 +0x0000CCAF 0x5999 # 0 +0x0000CCB0 0x7C8D # 0 +0x0000CCB1 0x6C11 # 0 +0x0000CCB2 0x7720 # 0 +0x0000CCB3 0x52D9 # 0 +0x0000CCB4 0x5922 # 0 +0x0000CCB5 0x7121 # 0 +0x0000CCB6 0x725F # 0 +0x0000CCB7 0x77DB # 0 +0x0000CCB8 0x9727 # 0 +0x0000CCB9 0x9D61 # 0 +0x0000CCBA 0x690B # 0 +0x0000CCBB 0x5A7F # 0 +0x0000CCBC 0x5A18 # 0 +0x0000CCBD 0x51A5 # 0 +0x0000CCBE 0x540D # 0 +0x0000CCBF 0x547D # 0 +0x0000CCC0 0x660E # 0 +0x0000CCC1 0x76DF # 0 +0x0000CCC2 0x8FF7 # 0 +0x0000CCC3 0x9298 # 0 +0x0000CCC4 0x9CF4 # 0 +0x0000CCC5 0x59EA # 0 +0x0000CCC6 0x725D # 0 +0x0000CCC7 0x6EC5 # 0 +0x0000CCC8 0x514D # 0 +0x0000CCC9 0x68C9 # 0 +0x0000CCCA 0x7DBF # 0 +0x0000CCCB 0x7DEC # 0 +0x0000CCCC 0x9762 # 0 +0x0000CCCD 0x9EBA # 0 +0x0000CCCE 0x6478 # 0 +0x0000CCCF 0x6A21 # 0 +0x0000CCD0 0x8302 # 0 +0x0000CCD1 0x5984 # 0 +0x0000CCD2 0x5B5F # 0 +0x0000CCD3 0x6BDB # 0 +0x0000CCD4 0x731B # 0 +0x0000CCD5 0x76F2 # 0 +0x0000CCD6 0x7DB2 # 0 +0x0000CCD7 0x8017 # 0 +0x0000CCD8 0x8499 # 0 +0x0000CCD9 0x5132 # 0 +0x0000CCDA 0x6728 # 0 +0x0000CCDB 0x9ED9 # 0 +0x0000CCDC 0x76EE # 0 +0x0000CCDD 0x6762 # 0 +0x0000CCDE 0x52FF # 0 +0x0000CCDF 0x9905 # 0 +0x0000CCE0 0x5C24 # 0 +0x0000CCE1 0x623B # 0 +0x0000CCE2 0x7C7E # 0 +0x0000CCE3 0x8CB0 # 0 +0x0000CCE4 0x554F # 0 +0x0000CCE5 0x60B6 # 0 +0x0000CCE6 0x7D0B # 0 +0x0000CCE7 0x9580 # 0 +0x0000CCE8 0x5301 # 0 +0x0000CCE9 0x4E5F # 0 +0x0000CCEA 0x51B6 # 0 +0x0000CCEB 0x591C # 0 +0x0000CCEC 0x723A # 0 +0x0000CCED 0x8036 # 0 +0x0000CCEE 0x91CE # 0 +0x0000CCEF 0x5F25 # 0 +0x0000CCF0 0x77E2 # 0 +0x0000CCF1 0x5384 # 0 +0x0000CCF2 0x5F79 # 0 +0x0000CCF3 0x7D04 # 0 +0x0000CCF4 0x85AC # 0 +0x0000CCF5 0x8A33 # 0 +0x0000CCF6 0x8E8D # 0 +0x0000CCF7 0x9756 # 0 +0x0000CCF8 0x67F3 # 0 +0x0000CCF9 0x85AE # 0 +0x0000CCFA 0x9453 # 0 +0x0000CCFB 0x6109 # 0 +0x0000CCFC 0x6108 # 0 +0x0000CCFD 0x6CB9 # 0 +0x0000CCFE 0x7652 # 0 +0x0000CDA1 0x8AED # 0 +0x0000CDA2 0x8F38 # 0 +0x0000CDA3 0x552F # 0 +0x0000CDA4 0x4F51 # 0 +0x0000CDA5 0x512A # 0 +0x0000CDA6 0x52C7 # 0 +0x0000CDA7 0x53CB # 0 +0x0000CDA8 0x5BA5 # 0 +0x0000CDA9 0x5E7D # 0 +0x0000CDAA 0x60A0 # 0 +0x0000CDAB 0x6182 # 0 +0x0000CDAC 0x63D6 # 0 +0x0000CDAD 0x6709 # 0 +0x0000CDAE 0x67DA # 0 +0x0000CDAF 0x6E67 # 0 +0x0000CDB0 0x6D8C # 0 +0x0000CDB1 0x7336 # 0 +0x0000CDB2 0x7337 # 0 +0x0000CDB3 0x7531 # 0 +0x0000CDB4 0x7950 # 0 +0x0000CDB5 0x88D5 # 0 +0x0000CDB6 0x8A98 # 0 +0x0000CDB7 0x904A # 0 +0x0000CDB8 0x9091 # 0 +0x0000CDB9 0x90F5 # 0 +0x0000CDBA 0x96C4 # 0 +0x0000CDBB 0x878D # 0 +0x0000CDBC 0x5915 # 0 +0x0000CDBD 0x4E88 # 0 +0x0000CDBE 0x4F59 # 0 +0x0000CDBF 0x4E0E # 0 +0x0000CDC0 0x8A89 # 0 +0x0000CDC1 0x8F3F # 0 +0x0000CDC2 0x9810 # 0 +0x0000CDC3 0x50AD # 0 +0x0000CDC4 0x5E7C # 0 +0x0000CDC5 0x5996 # 0 +0x0000CDC6 0x5BB9 # 0 +0x0000CDC7 0x5EB8 # 0 +0x0000CDC8 0x63DA # 0 +0x0000CDC9 0x63FA # 0 +0x0000CDCA 0x64C1 # 0 +0x0000CDCB 0x66DC # 0 +0x0000CDCC 0x694A # 0 +0x0000CDCD 0x69D8 # 0 +0x0000CDCE 0x6D0B # 0 +0x0000CDCF 0x6EB6 # 0 +0x0000CDD0 0x7194 # 0 +0x0000CDD1 0x7528 # 0 +0x0000CDD2 0x7AAF # 0 +0x0000CDD3 0x7F8A # 0 +0x0000CDD4 0x8000 # 0 +0x0000CDD5 0x8449 # 0 +0x0000CDD6 0x84C9 # 0 +0x0000CDD7 0x8981 # 0 +0x0000CDD8 0x8B21 # 0 +0x0000CDD9 0x8E0A # 0 +0x0000CDDA 0x9065 # 0 +0x0000CDDB 0x967D # 0 +0x0000CDDC 0x990A # 0 +0x0000CDDD 0x617E # 0 +0x0000CDDE 0x6291 # 0 +0x0000CDDF 0x6B32 # 0 +0x0000CDE0 0x6C83 # 0 +0x0000CDE1 0x6D74 # 0 +0x0000CDE2 0x7FCC # 0 +0x0000CDE3 0x7FFC # 0 +0x0000CDE4 0x6DC0 # 0 +0x0000CDE5 0x7F85 # 0 +0x0000CDE6 0x87BA # 0 +0x0000CDE7 0x88F8 # 0 +0x0000CDE8 0x6765 # 0 +0x0000CDE9 0x83B1 # 0 +0x0000CDEA 0x983C # 0 +0x0000CDEB 0x96F7 # 0 +0x0000CDEC 0x6D1B # 0 +0x0000CDED 0x7D61 # 0 +0x0000CDEE 0x843D # 0 +0x0000CDEF 0x916A # 0 +0x0000CDF0 0x4E71 # 0 +0x0000CDF1 0x5375 # 0 +0x0000CDF2 0x5D50 # 0 +0x0000CDF3 0x6B04 # 0 +0x0000CDF4 0x6FEB # 0 +0x0000CDF5 0x85CD # 0 +0x0000CDF6 0x862D # 0 +0x0000CDF7 0x89A7 # 0 +0x0000CDF8 0x5229 # 0 +0x0000CDF9 0x540F # 0 +0x0000CDFA 0x5C65 # 0 +0x0000CDFB 0x674E # 0 +0x0000CDFC 0x68A8 # 0 +0x0000CDFD 0x7406 # 0 +0x0000CDFE 0x7483 # 0 +0x0000CEA1 0x75E2 # 0 +0x0000CEA2 0x88CF # 0 +0x0000CEA3 0x88E1 # 0 +0x0000CEA4 0x91CC # 0 +0x0000CEA5 0x96E2 # 0 +0x0000CEA6 0x9678 # 0 +0x0000CEA7 0x5F8B # 0 +0x0000CEA8 0x7387 # 0 +0x0000CEA9 0x7ACB # 0 +0x0000CEAA 0x844E # 0 +0x0000CEAB 0x63A0 # 0 +0x0000CEAC 0x7565 # 0 +0x0000CEAD 0x5289 # 0 +0x0000CEAE 0x6D41 # 0 +0x0000CEAF 0x6E9C # 0 +0x0000CEB0 0x7409 # 0 +0x0000CEB1 0x7559 # 0 +0x0000CEB2 0x786B # 0 +0x0000CEB3 0x7C92 # 0 +0x0000CEB4 0x9686 # 0 +0x0000CEB5 0x7ADC # 0 +0x0000CEB6 0x9F8D # 0 +0x0000CEB7 0x4FB6 # 0 +0x0000CEB8 0x616E # 0 +0x0000CEB9 0x65C5 # 0 +0x0000CEBA 0x865C # 0 +0x0000CEBB 0x4E86 # 0 +0x0000CEBC 0x4EAE # 0 +0x0000CEBD 0x50DA # 0 +0x0000CEBE 0x4E21 # 0 +0x0000CEBF 0x51CC # 0 +0x0000CEC0 0x5BEE # 0 +0x0000CEC1 0x6599 # 0 +0x0000CEC2 0x6881 # 0 +0x0000CEC3 0x6DBC # 0 +0x0000CEC4 0x731F # 0 +0x0000CEC5 0x7642 # 0 +0x0000CEC6 0x77AD # 0 +0x0000CEC7 0x7A1C # 0 +0x0000CEC8 0x7CE7 # 0 +0x0000CEC9 0x826F # 0 +0x0000CECA 0x8AD2 # 0 +0x0000CECB 0x907C # 0 +0x0000CECC 0x91CF # 0 +0x0000CECD 0x9675 # 0 +0x0000CECE 0x9818 # 0 +0x0000CECF 0x529B # 0 +0x0000CED0 0x7DD1 # 0 +0x0000CED1 0x502B # 0 +0x0000CED2 0x5398 # 0 +0x0000CED3 0x6797 # 0 +0x0000CED4 0x6DCB # 0 +0x0000CED5 0x71D0 # 0 +0x0000CED6 0x7433 # 0 +0x0000CED7 0x81E8 # 0 +0x0000CED8 0x8F2A # 0 +0x0000CED9 0x96A3 # 0 +0x0000CEDA 0x9C57 # 0 +0x0000CEDB 0x9E9F # 0 +0x0000CEDC 0x7460 # 0 +0x0000CEDD 0x5841 # 0 +0x0000CEDE 0x6D99 # 0 +0x0000CEDF 0x7D2F # 0 +0x0000CEE0 0x985E # 0 +0x0000CEE1 0x4EE4 # 0 +0x0000CEE2 0x4F36 # 0 +0x0000CEE3 0x4F8B # 0 +0x0000CEE4 0x51B7 # 0 +0x0000CEE5 0x52B1 # 0 +0x0000CEE6 0x5DBA # 0 +0x0000CEE7 0x601C # 0 +0x0000CEE8 0x73B2 # 0 +0x0000CEE9 0x793C # 0 +0x0000CEEA 0x82D3 # 0 +0x0000CEEB 0x9234 # 0 +0x0000CEEC 0x96B7 # 0 +0x0000CEED 0x96F6 # 0 +0x0000CEEE 0x970A # 0 +0x0000CEEF 0x9E97 # 0 +0x0000CEF0 0x9F62 # 0 +0x0000CEF1 0x66A6 # 0 +0x0000CEF2 0x6B74 # 0 +0x0000CEF3 0x5217 # 0 +0x0000CEF4 0x52A3 # 0 +0x0000CEF5 0x70C8 # 0 +0x0000CEF6 0x88C2 # 0 +0x0000CEF7 0x5EC9 # 0 +0x0000CEF8 0x604B # 0 +0x0000CEF9 0x6190 # 0 +0x0000CEFA 0x6F23 # 0 +0x0000CEFB 0x7149 # 0 +0x0000CEFC 0x7C3E # 0 +0x0000CEFD 0x7DF4 # 0 +0x0000CEFE 0x806F # 0 +0x0000CFA1 0x84EE # 0 +0x0000CFA2 0x9023 # 0 +0x0000CFA3 0x932C # 0 +0x0000CFA4 0x5442 # 0 +0x0000CFA5 0x9B6F # 0 +0x0000CFA6 0x6AD3 # 0 +0x0000CFA7 0x7089 # 0 +0x0000CFA8 0x8CC2 # 0 +0x0000CFA9 0x8DEF # 0 +0x0000CFAA 0x9732 # 0 +0x0000CFAB 0x52B4 # 0 +0x0000CFAC 0x5A41 # 0 +0x0000CFAD 0x5ECA # 0 +0x0000CFAE 0x5F04 # 0 +0x0000CFAF 0x6717 # 0 +0x0000CFB0 0x697C # 0 +0x0000CFB1 0x6994 # 0 +0x0000CFB2 0x6D6A # 0 +0x0000CFB3 0x6F0F # 0 +0x0000CFB4 0x7262 # 0 +0x0000CFB5 0x72FC # 0 +0x0000CFB6 0x7BED # 0 +0x0000CFB7 0x8001 # 0 +0x0000CFB8 0x807E # 0 +0x0000CFB9 0x874B # 0 +0x0000CFBA 0x90CE # 0 +0x0000CFBB 0x516D # 0 +0x0000CFBC 0x9E93 # 0 +0x0000CFBD 0x7984 # 0 +0x0000CFBE 0x808B # 0 +0x0000CFBF 0x9332 # 0 +0x0000CFC0 0x8AD6 # 0 +0x0000CFC1 0x502D # 0 +0x0000CFC2 0x548C # 0 +0x0000CFC3 0x8A71 # 0 +0x0000CFC4 0x6B6A # 0 +0x0000CFC5 0x8CC4 # 0 +0x0000CFC6 0x8107 # 0 +0x0000CFC7 0x60D1 # 0 +0x0000CFC8 0x67A0 # 0 +0x0000CFC9 0x9DF2 # 0 +0x0000CFCA 0x4E99 # 0 +0x0000CFCB 0x4E98 # 0 +0x0000CFCC 0x9C10 # 0 +0x0000CFCD 0x8A6B # 0 +0x0000CFCE 0x85C1 # 0 +0x0000CFCF 0x8568 # 0 +0x0000CFD0 0x6900 # 0 +0x0000CFD1 0x6E7E # 0 +0x0000CFD2 0x7897 # 0 +0x0000CFD3 0x8155 # 0 +0x0000D0A1 0x5F0C # 0 +0x0000D0A2 0x4E10 # 0 +0x0000D0A3 0x4E15 # 0 +0x0000D0A4 0x4E2A # 0 +0x0000D0A5 0x4E31 # 0 +0x0000D0A6 0x4E36 # 0 +0x0000D0A7 0x4E3C # 0 +0x0000D0A8 0x4E3F # 0 +0x0000D0A9 0x4E42 # 0 +0x0000D0AA 0x4E56 # 0 +0x0000D0AB 0x4E58 # 0 +0x0000D0AC 0x4E82 # 0 +0x0000D0AD 0x4E85 # 0 +0x0000D0AE 0x8C6B # 0 +0x0000D0AF 0x4E8A # 0 +0x0000D0B0 0x8212 # 0 +0x0000D0B1 0x5F0D # 0 +0x0000D0B2 0x4E8E # 0 +0x0000D0B3 0x4E9E # 0 +0x0000D0B4 0x4E9F # 0 +0x0000D0B5 0x4EA0 # 0 +0x0000D0B6 0x4EA2 # 0 +0x0000D0B7 0x4EB0 # 0 +0x0000D0B8 0x4EB3 # 0 +0x0000D0B9 0x4EB6 # 0 +0x0000D0BA 0x4ECE # 0 +0x0000D0BB 0x4ECD # 0 +0x0000D0BC 0x4EC4 # 0 +0x0000D0BD 0x4EC6 # 0 +0x0000D0BE 0x4EC2 # 0 +0x0000D0BF 0x4ED7 # 0 +0x0000D0C0 0x4EDE # 0 +0x0000D0C1 0x4EED # 0 +0x0000D0C2 0x4EDF # 0 +0x0000D0C3 0x4EF7 # 0 +0x0000D0C4 0x4F09 # 0 +0x0000D0C5 0x4F5A # 0 +0x0000D0C6 0x4F30 # 0 +0x0000D0C7 0x4F5B # 0 +0x0000D0C8 0x4F5D # 0 +0x0000D0C9 0x4F57 # 0 +0x0000D0CA 0x4F47 # 0 +0x0000D0CB 0x4F76 # 0 +0x0000D0CC 0x4F88 # 0 +0x0000D0CD 0x4F8F # 0 +0x0000D0CE 0x4F98 # 0 +0x0000D0CF 0x4F7B # 0 +0x0000D0D0 0x4F69 # 0 +0x0000D0D1 0x4F70 # 0 +0x0000D0D2 0x4F91 # 0 +0x0000D0D3 0x4F6F # 0 +0x0000D0D4 0x4F86 # 0 +0x0000D0D5 0x4F96 # 0 +0x0000D0D6 0x5118 # 0 +0x0000D0D7 0x4FD4 # 0 +0x0000D0D8 0x4FDF # 0 +0x0000D0D9 0x4FCE # 0 +0x0000D0DA 0x4FD8 # 0 +0x0000D0DB 0x4FDB # 0 +0x0000D0DC 0x4FD1 # 0 +0x0000D0DD 0x4FDA # 0 +0x0000D0DE 0x4FD0 # 0 +0x0000D0DF 0x4FE4 # 0 +0x0000D0E0 0x4FE5 # 0 +0x0000D0E1 0x501A # 0 +0x0000D0E2 0x5028 # 0 +0x0000D0E3 0x5014 # 0 +0x0000D0E4 0x502A # 0 +0x0000D0E5 0x5025 # 0 +0x0000D0E6 0x5005 # 0 +0x0000D0E7 0x4F1C # 0 +0x0000D0E8 0x4FF6 # 0 +0x0000D0E9 0x5021 # 0 +0x0000D0EA 0x5029 # 0 +0x0000D0EB 0x502C # 0 +0x0000D0EC 0x4FFE # 0 +0x0000D0ED 0x4FEF # 0 +0x0000D0EE 0x5011 # 0 +0x0000D0EF 0x5006 # 0 +0x0000D0F0 0x5043 # 0 +0x0000D0F1 0x5047 # 0 +0x0000D0F2 0x6703 # 0 +0x0000D0F3 0x5055 # 0 +0x0000D0F4 0x5050 # 0 +0x0000D0F5 0x5048 # 0 +0x0000D0F6 0x505A # 0 +0x0000D0F7 0x5056 # 0 +0x0000D0F8 0x506C # 0 +0x0000D0F9 0x5078 # 0 +0x0000D0FA 0x5080 # 0 +0x0000D0FB 0x509A # 0 +0x0000D0FC 0x5085 # 0 +0x0000D0FD 0x50B4 # 0 +0x0000D0FE 0x50B2 # 0 +0x0000D1A1 0x50C9 # 0 +0x0000D1A2 0x50CA # 0 +0x0000D1A3 0x50B3 # 0 +0x0000D1A4 0x50C2 # 0 +0x0000D1A5 0x50D6 # 0 +0x0000D1A6 0x50DE # 0 +0x0000D1A7 0x50E5 # 0 +0x0000D1A8 0x50ED # 0 +0x0000D1A9 0x50E3 # 0 +0x0000D1AA 0x50EE # 0 +0x0000D1AB 0x50F9 # 0 +0x0000D1AC 0x50F5 # 0 +0x0000D1AD 0x5109 # 0 +0x0000D1AE 0x5101 # 0 +0x0000D1AF 0x5102 # 0 +0x0000D1B0 0x5116 # 0 +0x0000D1B1 0x5115 # 0 +0x0000D1B2 0x5114 # 0 +0x0000D1B3 0x511A # 0 +0x0000D1B4 0x5121 # 0 +0x0000D1B5 0x513A # 0 +0x0000D1B6 0x5137 # 0 +0x0000D1B7 0x513C # 0 +0x0000D1B8 0x513B # 0 +0x0000D1B9 0x513F # 0 +0x0000D1BA 0x5140 # 0 +0x0000D1BB 0x5152 # 0 +0x0000D1BC 0x514C # 0 +0x0000D1BD 0x5154 # 0 +0x0000D1BE 0x5162 # 0 +0x0000D1BF 0x7AF8 # 0 +0x0000D1C0 0x5169 # 0 +0x0000D1C1 0x516A # 0 +0x0000D1C2 0x516E # 0 +0x0000D1C3 0x5180 # 0 +0x0000D1C4 0x5182 # 0 +0x0000D1C5 0x56D8 # 0 +0x0000D1C6 0x518C # 0 +0x0000D1C7 0x5189 # 0 +0x0000D1C8 0x518F # 0 +0x0000D1C9 0x5191 # 0 +0x0000D1CA 0x5193 # 0 +0x0000D1CB 0x5195 # 0 +0x0000D1CC 0x5196 # 0 +0x0000D1CD 0x51A4 # 0 +0x0000D1CE 0x51A6 # 0 +0x0000D1CF 0x51A2 # 0 +0x0000D1D0 0x51A9 # 0 +0x0000D1D1 0x51AA # 0 +0x0000D1D2 0x51AB # 0 +0x0000D1D3 0x51B3 # 0 +0x0000D1D4 0x51B1 # 0 +0x0000D1D5 0x51B2 # 0 +0x0000D1D6 0x51B0 # 0 +0x0000D1D7 0x51B5 # 0 +0x0000D1D8 0x51BD # 0 +0x0000D1D9 0x51C5 # 0 +0x0000D1DA 0x51C9 # 0 +0x0000D1DB 0x51DB # 0 +0x0000D1DC 0x51E0 # 0 +0x0000D1DD 0x8655 # 0 +0x0000D1DE 0x51E9 # 0 +0x0000D1DF 0x51ED # 0 +0x0000D1E0 0x51F0 # 0 +0x0000D1E1 0x51F5 # 0 +0x0000D1E2 0x51FE # 0 +0x0000D1E3 0x5204 # 0 +0x0000D1E4 0x520B # 0 +0x0000D1E5 0x5214 # 0 +0x0000D1E6 0x520E # 0 +0x0000D1E7 0x5227 # 0 +0x0000D1E8 0x522A # 0 +0x0000D1E9 0x522E # 0 +0x0000D1EA 0x5233 # 0 +0x0000D1EB 0x5239 # 0 +0x0000D1EC 0x524F # 0 +0x0000D1ED 0x5244 # 0 +0x0000D1EE 0x524B # 0 +0x0000D1EF 0x524C # 0 +0x0000D1F0 0x525E # 0 +0x0000D1F1 0x5254 # 0 +0x0000D1F2 0x526A # 0 +0x0000D1F3 0x5274 # 0 +0x0000D1F4 0x5269 # 0 +0x0000D1F5 0x5273 # 0 +0x0000D1F6 0x527F # 0 +0x0000D1F7 0x527D # 0 +0x0000D1F8 0x528D # 0 +0x0000D1F9 0x5294 # 0 +0x0000D1FA 0x5292 # 0 +0x0000D1FB 0x5271 # 0 +0x0000D1FC 0x5288 # 0 +0x0000D1FD 0x5291 # 0 +0x0000D1FE 0x8FA8 # 0 +0x0000D2A1 0x8FA7 # 0 +0x0000D2A2 0x52AC # 0 +0x0000D2A3 0x52AD # 0 +0x0000D2A4 0x52BC # 0 +0x0000D2A5 0x52B5 # 0 +0x0000D2A6 0x52C1 # 0 +0x0000D2A7 0x52CD # 0 +0x0000D2A8 0x52D7 # 0 +0x0000D2A9 0x52DE # 0 +0x0000D2AA 0x52E3 # 0 +0x0000D2AB 0x52E6 # 0 +0x0000D2AC 0x98ED # 0 +0x0000D2AD 0x52E0 # 0 +0x0000D2AE 0x52F3 # 0 +0x0000D2AF 0x52F5 # 0 +0x0000D2B0 0x52F8 # 0 +0x0000D2B1 0x52F9 # 0 +0x0000D2B2 0x5306 # 0 +0x0000D2B3 0x5308 # 0 +0x0000D2B4 0x7538 # 0 +0x0000D2B5 0x530D # 0 +0x0000D2B6 0x5310 # 0 +0x0000D2B7 0x530F # 0 +0x0000D2B8 0x5315 # 0 +0x0000D2B9 0x531A # 0 +0x0000D2BA 0x5323 # 0 +0x0000D2BB 0x532F # 0 +0x0000D2BC 0x5331 # 0 +0x0000D2BD 0x5333 # 0 +0x0000D2BE 0x5338 # 0 +0x0000D2BF 0x5340 # 0 +0x0000D2C0 0x5346 # 0 +0x0000D2C1 0x5345 # 0 +0x0000D2C2 0x4E17 # 0 +0x0000D2C3 0x5349 # 0 +0x0000D2C4 0x534D # 0 +0x0000D2C5 0x51D6 # 0 +0x0000D2C6 0x535E # 0 +0x0000D2C7 0x5369 # 0 +0x0000D2C8 0x536E # 0 +0x0000D2C9 0x5918 # 0 +0x0000D2CA 0x537B # 0 +0x0000D2CB 0x5377 # 0 +0x0000D2CC 0x5382 # 0 +0x0000D2CD 0x5396 # 0 +0x0000D2CE 0x53A0 # 0 +0x0000D2CF 0x53A6 # 0 +0x0000D2D0 0x53A5 # 0 +0x0000D2D1 0x53AE # 0 +0x0000D2D2 0x53B0 # 0 +0x0000D2D3 0x53B6 # 0 +0x0000D2D4 0x53C3 # 0 +0x0000D2D5 0x7C12 # 0 +0x0000D2D6 0x96D9 # 0 +0x0000D2D7 0x53DF # 0 +0x0000D2D8 0x66FC # 0 +0x0000D2D9 0x71EE # 0 +0x0000D2DA 0x53EE # 0 +0x0000D2DB 0x53E8 # 0 +0x0000D2DC 0x53ED # 0 +0x0000D2DD 0x53FA # 0 +0x0000D2DE 0x5401 # 0 +0x0000D2DF 0x543D # 0 +0x0000D2E0 0x5440 # 0 +0x0000D2E1 0x542C # 0 +0x0000D2E2 0x542D # 0 +0x0000D2E3 0x543C # 0 +0x0000D2E4 0x542E # 0 +0x0000D2E5 0x5436 # 0 +0x0000D2E6 0x5429 # 0 +0x0000D2E7 0x541D # 0 +0x0000D2E8 0x544E # 0 +0x0000D2E9 0x548F # 0 +0x0000D2EA 0x5475 # 0 +0x0000D2EB 0x548E # 0 +0x0000D2EC 0x545F # 0 +0x0000D2ED 0x5471 # 0 +0x0000D2EE 0x5477 # 0 +0x0000D2EF 0x5470 # 0 +0x0000D2F0 0x5492 # 0 +0x0000D2F1 0x547B # 0 +0x0000D2F2 0x5480 # 0 +0x0000D2F3 0x5476 # 0 +0x0000D2F4 0x5484 # 0 +0x0000D2F5 0x5490 # 0 +0x0000D2F6 0x5486 # 0 +0x0000D2F7 0x54C7 # 0 +0x0000D2F8 0x54A2 # 0 +0x0000D2F9 0x54B8 # 0 +0x0000D2FA 0x54A5 # 0 +0x0000D2FB 0x54AC # 0 +0x0000D2FC 0x54C4 # 0 +0x0000D2FD 0x54C8 # 0 +0x0000D2FE 0x54A8 # 0 +0x0000D3A1 0x54AB # 0 +0x0000D3A2 0x54C2 # 0 +0x0000D3A3 0x54A4 # 0 +0x0000D3A4 0x54BE # 0 +0x0000D3A5 0x54BC # 0 +0x0000D3A6 0x54D8 # 0 +0x0000D3A7 0x54E5 # 0 +0x0000D3A8 0x54E6 # 0 +0x0000D3A9 0x550F # 0 +0x0000D3AA 0x5514 # 0 +0x0000D3AB 0x54FD # 0 +0x0000D3AC 0x54EE # 0 +0x0000D3AD 0x54ED # 0 +0x0000D3AE 0x54FA # 0 +0x0000D3AF 0x54E2 # 0 +0x0000D3B0 0x5539 # 0 +0x0000D3B1 0x5540 # 0 +0x0000D3B2 0x5563 # 0 +0x0000D3B3 0x554C # 0 +0x0000D3B4 0x552E # 0 +0x0000D3B5 0x555C # 0 +0x0000D3B6 0x5545 # 0 +0x0000D3B7 0x5556 # 0 +0x0000D3B8 0x5557 # 0 +0x0000D3B9 0x5538 # 0 +0x0000D3BA 0x5533 # 0 +0x0000D3BB 0x555D # 0 +0x0000D3BC 0x5599 # 0 +0x0000D3BD 0x5580 # 0 +0x0000D3BE 0x54AF # 0 +0x0000D3BF 0x558A # 0 +0x0000D3C0 0x559F # 0 +0x0000D3C1 0x557B # 0 +0x0000D3C2 0x557E # 0 +0x0000D3C3 0x5598 # 0 +0x0000D3C4 0x559E # 0 +0x0000D3C5 0x55AE # 0 +0x0000D3C6 0x557C # 0 +0x0000D3C7 0x5583 # 0 +0x0000D3C8 0x55A9 # 0 +0x0000D3C9 0x5587 # 0 +0x0000D3CA 0x55A8 # 0 +0x0000D3CB 0x55DA # 0 +0x0000D3CC 0x55C5 # 0 +0x0000D3CD 0x55DF # 0 +0x0000D3CE 0x55C4 # 0 +0x0000D3CF 0x55DC # 0 +0x0000D3D0 0x55E4 # 0 +0x0000D3D1 0x55D4 # 0 +0x0000D3D2 0x5614 # 0 +0x0000D3D3 0x55F7 # 0 +0x0000D3D4 0x5616 # 0 +0x0000D3D5 0x55FE # 0 +0x0000D3D6 0x55FD # 0 +0x0000D3D7 0x561B # 0 +0x0000D3D8 0x55F9 # 0 +0x0000D3D9 0x564E # 0 +0x0000D3DA 0x5650 # 0 +0x0000D3DB 0x71DF # 0 +0x0000D3DC 0x5634 # 0 +0x0000D3DD 0x5636 # 0 +0x0000D3DE 0x5632 # 0 +0x0000D3DF 0x5638 # 0 +0x0000D3E0 0x566B # 0 +0x0000D3E1 0x5664 # 0 +0x0000D3E2 0x562F # 0 +0x0000D3E3 0x566C # 0 +0x0000D3E4 0x566A # 0 +0x0000D3E5 0x5686 # 0 +0x0000D3E6 0x5680 # 0 +0x0000D3E7 0x568A # 0 +0x0000D3E8 0x56A0 # 0 +0x0000D3E9 0x5694 # 0 +0x0000D3EA 0x568F # 0 +0x0000D3EB 0x56A5 # 0 +0x0000D3EC 0x56AE # 0 +0x0000D3ED 0x56B6 # 0 +0x0000D3EE 0x56B4 # 0 +0x0000D3EF 0x56C2 # 0 +0x0000D3F0 0x56BC # 0 +0x0000D3F1 0x56C1 # 0 +0x0000D3F2 0x56C3 # 0 +0x0000D3F3 0x56C0 # 0 +0x0000D3F4 0x56C8 # 0 +0x0000D3F5 0x56CE # 0 +0x0000D3F6 0x56D1 # 0 +0x0000D3F7 0x56D3 # 0 +0x0000D3F8 0x56D7 # 0 +0x0000D3F9 0x56EE # 0 +0x0000D3FA 0x56F9 # 0 +0x0000D3FB 0x5700 # 0 +0x0000D3FC 0x56FF # 0 +0x0000D3FD 0x5704 # 0 +0x0000D3FE 0x5709 # 0 +0x0000D4A1 0x5708 # 0 +0x0000D4A2 0x570B # 0 +0x0000D4A3 0x570D # 0 +0x0000D4A4 0x5713 # 0 +0x0000D4A5 0x5718 # 0 +0x0000D4A6 0x5716 # 0 +0x0000D4A7 0x55C7 # 0 +0x0000D4A8 0x571C # 0 +0x0000D4A9 0x5726 # 0 +0x0000D4AA 0x5737 # 0 +0x0000D4AB 0x5738 # 0 +0x0000D4AC 0x574E # 0 +0x0000D4AD 0x573B # 0 +0x0000D4AE 0x5740 # 0 +0x0000D4AF 0x574F # 0 +0x0000D4B0 0x5769 # 0 +0x0000D4B1 0x57C0 # 0 +0x0000D4B2 0x5788 # 0 +0x0000D4B3 0x5761 # 0 +0x0000D4B4 0x577F # 0 +0x0000D4B5 0x5789 # 0 +0x0000D4B6 0x5793 # 0 +0x0000D4B7 0x57A0 # 0 +0x0000D4B8 0x57B3 # 0 +0x0000D4B9 0x57A4 # 0 +0x0000D4BA 0x57AA # 0 +0x0000D4BB 0x57B0 # 0 +0x0000D4BC 0x57C3 # 0 +0x0000D4BD 0x57C6 # 0 +0x0000D4BE 0x57D4 # 0 +0x0000D4BF 0x57D2 # 0 +0x0000D4C0 0x57D3 # 0 +0x0000D4C1 0x580A # 0 +0x0000D4C2 0x57D6 # 0 +0x0000D4C3 0x57E3 # 0 +0x0000D4C4 0x580B # 0 +0x0000D4C5 0x5819 # 0 +0x0000D4C6 0x581D # 0 +0x0000D4C7 0x5872 # 0 +0x0000D4C8 0x5821 # 0 +0x0000D4C9 0x5862 # 0 +0x0000D4CA 0x584B # 0 +0x0000D4CB 0x5870 # 0 +0x0000D4CC 0x6BC0 # 0 +0x0000D4CD 0x5852 # 0 +0x0000D4CE 0x583D # 0 +0x0000D4CF 0x5879 # 0 +0x0000D4D0 0x5885 # 0 +0x0000D4D1 0x58B9 # 0 +0x0000D4D2 0x589F # 0 +0x0000D4D3 0x58AB # 0 +0x0000D4D4 0x58BA # 0 +0x0000D4D5 0x58DE # 0 +0x0000D4D6 0x58BB # 0 +0x0000D4D7 0x58B8 # 0 +0x0000D4D8 0x58AE # 0 +0x0000D4D9 0x58C5 # 0 +0x0000D4DA 0x58D3 # 0 +0x0000D4DB 0x58D1 # 0 +0x0000D4DC 0x58D7 # 0 +0x0000D4DD 0x58D9 # 0 +0x0000D4DE 0x58D8 # 0 +0x0000D4DF 0x58E5 # 0 +0x0000D4E0 0x58DC # 0 +0x0000D4E1 0x58E4 # 0 +0x0000D4E2 0x58DF # 0 +0x0000D4E3 0x58EF # 0 +0x0000D4E4 0x58FA # 0 +0x0000D4E5 0x58F9 # 0 +0x0000D4E6 0x58FB # 0 +0x0000D4E7 0x58FC # 0 +0x0000D4E8 0x58FD # 0 +0x0000D4E9 0x5902 # 0 +0x0000D4EA 0x590A # 0 +0x0000D4EB 0x5910 # 0 +0x0000D4EC 0x591B # 0 +0x0000D4ED 0x68A6 # 0 +0x0000D4EE 0x5925 # 0 +0x0000D4EF 0x592C # 0 +0x0000D4F0 0x592D # 0 +0x0000D4F1 0x5932 # 0 +0x0000D4F2 0x5938 # 0 +0x0000D4F3 0x593E # 0 +0x0000D4F4 0x7AD2 # 0 +0x0000D4F5 0x5955 # 0 +0x0000D4F6 0x5950 # 0 +0x0000D4F7 0x594E # 0 +0x0000D4F8 0x595A # 0 +0x0000D4F9 0x5958 # 0 +0x0000D4FA 0x5962 # 0 +0x0000D4FB 0x5960 # 0 +0x0000D4FC 0x5967 # 0 +0x0000D4FD 0x596C # 0 +0x0000D4FE 0x5969 # 0 +0x0000D5A1 0x5978 # 0 +0x0000D5A2 0x5981 # 0 +0x0000D5A3 0x599D # 0 +0x0000D5A4 0x4F5E # 0 +0x0000D5A5 0x4FAB # 0 +0x0000D5A6 0x59A3 # 0 +0x0000D5A7 0x59B2 # 0 +0x0000D5A8 0x59C6 # 0 +0x0000D5A9 0x59E8 # 0 +0x0000D5AA 0x59DC # 0 +0x0000D5AB 0x598D # 0 +0x0000D5AC 0x59D9 # 0 +0x0000D5AD 0x59DA # 0 +0x0000D5AE 0x5A25 # 0 +0x0000D5AF 0x5A1F # 0 +0x0000D5B0 0x5A11 # 0 +0x0000D5B1 0x5A1C # 0 +0x0000D5B2 0x5A09 # 0 +0x0000D5B3 0x5A1A # 0 +0x0000D5B4 0x5A40 # 0 +0x0000D5B5 0x5A6C # 0 +0x0000D5B6 0x5A49 # 0 +0x0000D5B7 0x5A35 # 0 +0x0000D5B8 0x5A36 # 0 +0x0000D5B9 0x5A62 # 0 +0x0000D5BA 0x5A6A # 0 +0x0000D5BB 0x5A9A # 0 +0x0000D5BC 0x5ABC # 0 +0x0000D5BD 0x5ABE # 0 +0x0000D5BE 0x5ACB # 0 +0x0000D5BF 0x5AC2 # 0 +0x0000D5C0 0x5ABD # 0 +0x0000D5C1 0x5AE3 # 0 +0x0000D5C2 0x5AD7 # 0 +0x0000D5C3 0x5AE6 # 0 +0x0000D5C4 0x5AE9 # 0 +0x0000D5C5 0x5AD6 # 0 +0x0000D5C6 0x5AFA # 0 +0x0000D5C7 0x5AFB # 0 +0x0000D5C8 0x5B0C # 0 +0x0000D5C9 0x5B0B # 0 +0x0000D5CA 0x5B16 # 0 +0x0000D5CB 0x5B32 # 0 +0x0000D5CC 0x5AD0 # 0 +0x0000D5CD 0x5B2A # 0 +0x0000D5CE 0x5B36 # 0 +0x0000D5CF 0x5B3E # 0 +0x0000D5D0 0x5B43 # 0 +0x0000D5D1 0x5B45 # 0 +0x0000D5D2 0x5B40 # 0 +0x0000D5D3 0x5B51 # 0 +0x0000D5D4 0x5B55 # 0 +0x0000D5D5 0x5B5A # 0 +0x0000D5D6 0x5B5B # 0 +0x0000D5D7 0x5B65 # 0 +0x0000D5D8 0x5B69 # 0 +0x0000D5D9 0x5B70 # 0 +0x0000D5DA 0x5B73 # 0 +0x0000D5DB 0x5B75 # 0 +0x0000D5DC 0x5B78 # 0 +0x0000D5DD 0x6588 # 0 +0x0000D5DE 0x5B7A # 0 +0x0000D5DF 0x5B80 # 0 +0x0000D5E0 0x5B83 # 0 +0x0000D5E1 0x5BA6 # 0 +0x0000D5E2 0x5BB8 # 0 +0x0000D5E3 0x5BC3 # 0 +0x0000D5E4 0x5BC7 # 0 +0x0000D5E5 0x5BC9 # 0 +0x0000D5E6 0x5BD4 # 0 +0x0000D5E7 0x5BD0 # 0 +0x0000D5E8 0x5BE4 # 0 +0x0000D5E9 0x5BE6 # 0 +0x0000D5EA 0x5BE2 # 0 +0x0000D5EB 0x5BDE # 0 +0x0000D5EC 0x5BE5 # 0 +0x0000D5ED 0x5BEB # 0 +0x0000D5EE 0x5BF0 # 0 +0x0000D5EF 0x5BF6 # 0 +0x0000D5F0 0x5BF3 # 0 +0x0000D5F1 0x5C05 # 0 +0x0000D5F2 0x5C07 # 0 +0x0000D5F3 0x5C08 # 0 +0x0000D5F4 0x5C0D # 0 +0x0000D5F5 0x5C13 # 0 +0x0000D5F6 0x5C20 # 0 +0x0000D5F7 0x5C22 # 0 +0x0000D5F8 0x5C28 # 0 +0x0000D5F9 0x5C38 # 0 +0x0000D5FA 0x5C39 # 0 +0x0000D5FB 0x5C41 # 0 +0x0000D5FC 0x5C46 # 0 +0x0000D5FD 0x5C4E # 0 +0x0000D5FE 0x5C53 # 0 +0x0000D6A1 0x5C50 # 0 +0x0000D6A2 0x5C4F # 0 +0x0000D6A3 0x5B71 # 0 +0x0000D6A4 0x5C6C # 0 +0x0000D6A5 0x5C6E # 0 +0x0000D6A6 0x4E62 # 0 +0x0000D6A7 0x5C76 # 0 +0x0000D6A8 0x5C79 # 0 +0x0000D6A9 0x5C8C # 0 +0x0000D6AA 0x5C91 # 0 +0x0000D6AB 0x5C94 # 0 +0x0000D6AC 0x599B # 0 +0x0000D6AD 0x5CAB # 0 +0x0000D6AE 0x5CBB # 0 +0x0000D6AF 0x5CB6 # 0 +0x0000D6B0 0x5CBC # 0 +0x0000D6B1 0x5CB7 # 0 +0x0000D6B2 0x5CC5 # 0 +0x0000D6B3 0x5CBE # 0 +0x0000D6B4 0x5CC7 # 0 +0x0000D6B5 0x5CD9 # 0 +0x0000D6B6 0x5CE9 # 0 +0x0000D6B7 0x5CFD # 0 +0x0000D6B8 0x5CFA # 0 +0x0000D6B9 0x5CED # 0 +0x0000D6BA 0x5D8C # 0 +0x0000D6BB 0x5CEA # 0 +0x0000D6BC 0x5D0B # 0 +0x0000D6BD 0x5D15 # 0 +0x0000D6BE 0x5D17 # 0 +0x0000D6BF 0x5D5C # 0 +0x0000D6C0 0x5D1F # 0 +0x0000D6C1 0x5D1B # 0 +0x0000D6C2 0x5D11 # 0 +0x0000D6C3 0x5D14 # 0 +0x0000D6C4 0x5D22 # 0 +0x0000D6C5 0x5D1A # 0 +0x0000D6C6 0x5D19 # 0 +0x0000D6C7 0x5D18 # 0 +0x0000D6C8 0x5D4C # 0 +0x0000D6C9 0x5D52 # 0 +0x0000D6CA 0x5D4E # 0 +0x0000D6CB 0x5D4B # 0 +0x0000D6CC 0x5D6C # 0 +0x0000D6CD 0x5D73 # 0 +0x0000D6CE 0x5D76 # 0 +0x0000D6CF 0x5D87 # 0 +0x0000D6D0 0x5D84 # 0 +0x0000D6D1 0x5D82 # 0 +0x0000D6D2 0x5DA2 # 0 +0x0000D6D3 0x5D9D # 0 +0x0000D6D4 0x5DAC # 0 +0x0000D6D5 0x5DAE # 0 +0x0000D6D6 0x5DBD # 0 +0x0000D6D7 0x5D90 # 0 +0x0000D6D8 0x5DB7 # 0 +0x0000D6D9 0x5DBC # 0 +0x0000D6DA 0x5DC9 # 0 +0x0000D6DB 0x5DCD # 0 +0x0000D6DC 0x5DD3 # 0 +0x0000D6DD 0x5DD2 # 0 +0x0000D6DE 0x5DD6 # 0 +0x0000D6DF 0x5DDB # 0 +0x0000D6E0 0x5DEB # 0 +0x0000D6E1 0x5DF2 # 0 +0x0000D6E2 0x5DF5 # 0 +0x0000D6E3 0x5E0B # 0 +0x0000D6E4 0x5E1A # 0 +0x0000D6E5 0x5E19 # 0 +0x0000D6E6 0x5E11 # 0 +0x0000D6E7 0x5E1B # 0 +0x0000D6E8 0x5E36 # 0 +0x0000D6E9 0x5E37 # 0 +0x0000D6EA 0x5E44 # 0 +0x0000D6EB 0x5E43 # 0 +0x0000D6EC 0x5E40 # 0 +0x0000D6ED 0x5E4E # 0 +0x0000D6EE 0x5E57 # 0 +0x0000D6EF 0x5E54 # 0 +0x0000D6F0 0x5E5F # 0 +0x0000D6F1 0x5E62 # 0 +0x0000D6F2 0x5E64 # 0 +0x0000D6F3 0x5E47 # 0 +0x0000D6F4 0x5E75 # 0 +0x0000D6F5 0x5E76 # 0 +0x0000D6F6 0x5E7A # 0 +0x0000D6F7 0x9EBC # 0 +0x0000D6F8 0x5E7F # 0 +0x0000D6F9 0x5EA0 # 0 +0x0000D6FA 0x5EC1 # 0 +0x0000D6FB 0x5EC2 # 0 +0x0000D6FC 0x5EC8 # 0 +0x0000D6FD 0x5ED0 # 0 +0x0000D6FE 0x5ECF # 0 +0x0000D7A1 0x5ED6 # 0 +0x0000D7A2 0x5EE3 # 0 +0x0000D7A3 0x5EDD # 0 +0x0000D7A4 0x5EDA # 0 +0x0000D7A5 0x5EDB # 0 +0x0000D7A6 0x5EE2 # 0 +0x0000D7A7 0x5EE1 # 0 +0x0000D7A8 0x5EE8 # 0 +0x0000D7A9 0x5EE9 # 0 +0x0000D7AA 0x5EEC # 0 +0x0000D7AB 0x5EF1 # 0 +0x0000D7AC 0x5EF3 # 0 +0x0000D7AD 0x5EF0 # 0 +0x0000D7AE 0x5EF4 # 0 +0x0000D7AF 0x5EF8 # 0 +0x0000D7B0 0x5EFE # 0 +0x0000D7B1 0x5F03 # 0 +0x0000D7B2 0x5F09 # 0 +0x0000D7B3 0x5F5D # 0 +0x0000D7B4 0x5F5C # 0 +0x0000D7B5 0x5F0B # 0 +0x0000D7B6 0x5F11 # 0 +0x0000D7B7 0x5F16 # 0 +0x0000D7B8 0x5F29 # 0 +0x0000D7B9 0x5F2D # 0 +0x0000D7BA 0x5F38 # 0 +0x0000D7BB 0x5F41 # 0 +0x0000D7BC 0x5F48 # 0 +0x0000D7BD 0x5F4C # 0 +0x0000D7BE 0x5F4E # 0 +0x0000D7BF 0x5F2F # 0 +0x0000D7C0 0x5F51 # 0 +0x0000D7C1 0x5F56 # 0 +0x0000D7C2 0x5F57 # 0 +0x0000D7C3 0x5F59 # 0 +0x0000D7C4 0x5F61 # 0 +0x0000D7C5 0x5F6D # 0 +0x0000D7C6 0x5F73 # 0 +0x0000D7C7 0x5F77 # 0 +0x0000D7C8 0x5F83 # 0 +0x0000D7C9 0x5F82 # 0 +0x0000D7CA 0x5F7F # 0 +0x0000D7CB 0x5F8A # 0 +0x0000D7CC 0x5F88 # 0 +0x0000D7CD 0x5F91 # 0 +0x0000D7CE 0x5F87 # 0 +0x0000D7CF 0x5F9E # 0 +0x0000D7D0 0x5F99 # 0 +0x0000D7D1 0x5F98 # 0 +0x0000D7D2 0x5FA0 # 0 +0x0000D7D3 0x5FA8 # 0 +0x0000D7D4 0x5FAD # 0 +0x0000D7D5 0x5FBC # 0 +0x0000D7D6 0x5FD6 # 0 +0x0000D7D7 0x5FFB # 0 +0x0000D7D8 0x5FE4 # 0 +0x0000D7D9 0x5FF8 # 0 +0x0000D7DA 0x5FF1 # 0 +0x0000D7DB 0x5FDD # 0 +0x0000D7DC 0x60B3 # 0 +0x0000D7DD 0x5FFF # 0 +0x0000D7DE 0x6021 # 0 +0x0000D7DF 0x6060 # 0 +0x0000D7E0 0x6019 # 0 +0x0000D7E1 0x6010 # 0 +0x0000D7E2 0x6029 # 0 +0x0000D7E3 0x600E # 0 +0x0000D7E4 0x6031 # 0 +0x0000D7E5 0x601B # 0 +0x0000D7E6 0x6015 # 0 +0x0000D7E7 0x602B # 0 +0x0000D7E8 0x6026 # 0 +0x0000D7E9 0x600F # 0 +0x0000D7EA 0x603A # 0 +0x0000D7EB 0x605A # 0 +0x0000D7EC 0x6041 # 0 +0x0000D7ED 0x606A # 0 +0x0000D7EE 0x6077 # 0 +0x0000D7EF 0x605F # 0 +0x0000D7F0 0x604A # 0 +0x0000D7F1 0x6046 # 0 +0x0000D7F2 0x604D # 0 +0x0000D7F3 0x6063 # 0 +0x0000D7F4 0x6043 # 0 +0x0000D7F5 0x6064 # 0 +0x0000D7F6 0x6042 # 0 +0x0000D7F7 0x606C # 0 +0x0000D7F8 0x606B # 0 +0x0000D7F9 0x6059 # 0 +0x0000D7FA 0x6081 # 0 +0x0000D7FB 0x608D # 0 +0x0000D7FC 0x60E7 # 0 +0x0000D7FD 0x6083 # 0 +0x0000D7FE 0x609A # 0 +0x0000D8A1 0x6084 # 0 +0x0000D8A2 0x609B # 0 +0x0000D8A3 0x6096 # 0 +0x0000D8A4 0x6097 # 0 +0x0000D8A5 0x6092 # 0 +0x0000D8A6 0x60A7 # 0 +0x0000D8A7 0x608B # 0 +0x0000D8A8 0x60E1 # 0 +0x0000D8A9 0x60B8 # 0 +0x0000D8AA 0x60E0 # 0 +0x0000D8AB 0x60D3 # 0 +0x0000D8AC 0x60B4 # 0 +0x0000D8AD 0x5FF0 # 0 +0x0000D8AE 0x60BD # 0 +0x0000D8AF 0x60C6 # 0 +0x0000D8B0 0x60B5 # 0 +0x0000D8B1 0x60D8 # 0 +0x0000D8B2 0x614D # 0 +0x0000D8B3 0x6115 # 0 +0x0000D8B4 0x6106 # 0 +0x0000D8B5 0x60F6 # 0 +0x0000D8B6 0x60F7 # 0 +0x0000D8B7 0x6100 # 0 +0x0000D8B8 0x60F4 # 0 +0x0000D8B9 0x60FA # 0 +0x0000D8BA 0x6103 # 0 +0x0000D8BB 0x6121 # 0 +0x0000D8BC 0x60FB # 0 +0x0000D8BD 0x60F1 # 0 +0x0000D8BE 0x610D # 0 +0x0000D8BF 0x610E # 0 +0x0000D8C0 0x6147 # 0 +0x0000D8C1 0x613E # 0 +0x0000D8C2 0x6128 # 0 +0x0000D8C3 0x6127 # 0 +0x0000D8C4 0x614A # 0 +0x0000D8C5 0x613F # 0 +0x0000D8C6 0x613C # 0 +0x0000D8C7 0x612C # 0 +0x0000D8C8 0x6134 # 0 +0x0000D8C9 0x613D # 0 +0x0000D8CA 0x6142 # 0 +0x0000D8CB 0x6144 # 0 +0x0000D8CC 0x6173 # 0 +0x0000D8CD 0x6177 # 0 +0x0000D8CE 0x6158 # 0 +0x0000D8CF 0x6159 # 0 +0x0000D8D0 0x615A # 0 +0x0000D8D1 0x616B # 0 +0x0000D8D2 0x6174 # 0 +0x0000D8D3 0x616F # 0 +0x0000D8D4 0x6165 # 0 +0x0000D8D5 0x6171 # 0 +0x0000D8D6 0x615F # 0 +0x0000D8D7 0x615D # 0 +0x0000D8D8 0x6153 # 0 +0x0000D8D9 0x6175 # 0 +0x0000D8DA 0x6199 # 0 +0x0000D8DB 0x6196 # 0 +0x0000D8DC 0x6187 # 0 +0x0000D8DD 0x61AC # 0 +0x0000D8DE 0x6194 # 0 +0x0000D8DF 0x619A # 0 +0x0000D8E0 0x618A # 0 +0x0000D8E1 0x6191 # 0 +0x0000D8E2 0x61AB # 0 +0x0000D8E3 0x61AE # 0 +0x0000D8E4 0x61CC # 0 +0x0000D8E5 0x61CA # 0 +0x0000D8E6 0x61C9 # 0 +0x0000D8E7 0x61F7 # 0 +0x0000D8E8 0x61C8 # 0 +0x0000D8E9 0x61C3 # 0 +0x0000D8EA 0x61C6 # 0 +0x0000D8EB 0x61BA # 0 +0x0000D8EC 0x61CB # 0 +0x0000D8ED 0x7F79 # 0 +0x0000D8EE 0x61CD # 0 +0x0000D8EF 0x61E6 # 0 +0x0000D8F0 0x61E3 # 0 +0x0000D8F1 0x61F6 # 0 +0x0000D8F2 0x61FA # 0 +0x0000D8F3 0x61F4 # 0 +0x0000D8F4 0x61FF # 0 +0x0000D8F5 0x61FD # 0 +0x0000D8F6 0x61FC # 0 +0x0000D8F7 0x61FE # 0 +0x0000D8F8 0x6200 # 0 +0x0000D8F9 0x6208 # 0 +0x0000D8FA 0x6209 # 0 +0x0000D8FB 0x620D # 0 +0x0000D8FC 0x620C # 0 +0x0000D8FD 0x6214 # 0 +0x0000D8FE 0x621B # 0 +0x0000D9A1 0x621E # 0 +0x0000D9A2 0x6221 # 0 +0x0000D9A3 0x622A # 0 +0x0000D9A4 0x622E # 0 +0x0000D9A5 0x6230 # 0 +0x0000D9A6 0x6232 # 0 +0x0000D9A7 0x6233 # 0 +0x0000D9A8 0x6241 # 0 +0x0000D9A9 0x624E # 0 +0x0000D9AA 0x625E # 0 +0x0000D9AB 0x6263 # 0 +0x0000D9AC 0x625B # 0 +0x0000D9AD 0x6260 # 0 +0x0000D9AE 0x6268 # 0 +0x0000D9AF 0x627C # 0 +0x0000D9B0 0x6282 # 0 +0x0000D9B1 0x6289 # 0 +0x0000D9B2 0x627E # 0 +0x0000D9B3 0x6292 # 0 +0x0000D9B4 0x6293 # 0 +0x0000D9B5 0x6296 # 0 +0x0000D9B6 0x62D4 # 0 +0x0000D9B7 0x6283 # 0 +0x0000D9B8 0x6294 # 0 +0x0000D9B9 0x62D7 # 0 +0x0000D9BA 0x62D1 # 0 +0x0000D9BB 0x62BB # 0 +0x0000D9BC 0x62CF # 0 +0x0000D9BD 0x62FF # 0 +0x0000D9BE 0x62C6 # 0 +0x0000D9BF 0x64D4 # 0 +0x0000D9C0 0x62C8 # 0 +0x0000D9C1 0x62DC # 0 +0x0000D9C2 0x62CC # 0 +0x0000D9C3 0x62CA # 0 +0x0000D9C4 0x62C2 # 0 +0x0000D9C5 0x62C7 # 0 +0x0000D9C6 0x629B # 0 +0x0000D9C7 0x62C9 # 0 +0x0000D9C8 0x630C # 0 +0x0000D9C9 0x62EE # 0 +0x0000D9CA 0x62F1 # 0 +0x0000D9CB 0x6327 # 0 +0x0000D9CC 0x6302 # 0 +0x0000D9CD 0x6308 # 0 +0x0000D9CE 0x62EF # 0 +0x0000D9CF 0x62F5 # 0 +0x0000D9D0 0x6350 # 0 +0x0000D9D1 0x633E # 0 +0x0000D9D2 0x634D # 0 +0x0000D9D3 0x641C # 0 +0x0000D9D4 0x634F # 0 +0x0000D9D5 0x6396 # 0 +0x0000D9D6 0x638E # 0 +0x0000D9D7 0x6380 # 0 +0x0000D9D8 0x63AB # 0 +0x0000D9D9 0x6376 # 0 +0x0000D9DA 0x63A3 # 0 +0x0000D9DB 0x638F # 0 +0x0000D9DC 0x6389 # 0 +0x0000D9DD 0x639F # 0 +0x0000D9DE 0x63B5 # 0 +0x0000D9DF 0x636B # 0 +0x0000D9E0 0x6369 # 0 +0x0000D9E1 0x63BE # 0 +0x0000D9E2 0x63E9 # 0 +0x0000D9E3 0x63C0 # 0 +0x0000D9E4 0x63C6 # 0 +0x0000D9E5 0x63E3 # 0 +0x0000D9E6 0x63C9 # 0 +0x0000D9E7 0x63D2 # 0 +0x0000D9E8 0x63F6 # 0 +0x0000D9E9 0x63C4 # 0 +0x0000D9EA 0x6416 # 0 +0x0000D9EB 0x6434 # 0 +0x0000D9EC 0x6406 # 0 +0x0000D9ED 0x6413 # 0 +0x0000D9EE 0x6426 # 0 +0x0000D9EF 0x6436 # 0 +0x0000D9F0 0x651D # 0 +0x0000D9F1 0x6417 # 0 +0x0000D9F2 0x6428 # 0 +0x0000D9F3 0x640F # 0 +0x0000D9F4 0x6467 # 0 +0x0000D9F5 0x646F # 0 +0x0000D9F6 0x6476 # 0 +0x0000D9F7 0x644E # 0 +0x0000D9F8 0x652A # 0 +0x0000D9F9 0x6495 # 0 +0x0000D9FA 0x6493 # 0 +0x0000D9FB 0x64A5 # 0 +0x0000D9FC 0x64A9 # 0 +0x0000D9FD 0x6488 # 0 +0x0000D9FE 0x64BC # 0 +0x0000DAA1 0x64DA # 0 +0x0000DAA2 0x64D2 # 0 +0x0000DAA3 0x64C5 # 0 +0x0000DAA4 0x64C7 # 0 +0x0000DAA5 0x64BB # 0 +0x0000DAA6 0x64D8 # 0 +0x0000DAA7 0x64C2 # 0 +0x0000DAA8 0x64F1 # 0 +0x0000DAA9 0x64E7 # 0 +0x0000DAAA 0x8209 # 0 +0x0000DAAB 0x64E0 # 0 +0x0000DAAC 0x64E1 # 0 +0x0000DAAD 0x62AC # 0 +0x0000DAAE 0x64E3 # 0 +0x0000DAAF 0x64EF # 0 +0x0000DAB0 0x652C # 0 +0x0000DAB1 0x64F6 # 0 +0x0000DAB2 0x64F4 # 0 +0x0000DAB3 0x64F2 # 0 +0x0000DAB4 0x64FA # 0 +0x0000DAB5 0x6500 # 0 +0x0000DAB6 0x64FD # 0 +0x0000DAB7 0x6518 # 0 +0x0000DAB8 0x651C # 0 +0x0000DAB9 0x6505 # 0 +0x0000DABA 0x6524 # 0 +0x0000DABB 0x6523 # 0 +0x0000DABC 0x652B # 0 +0x0000DABD 0x6534 # 0 +0x0000DABE 0x6535 # 0 +0x0000DABF 0x6537 # 0 +0x0000DAC0 0x6536 # 0 +0x0000DAC1 0x6538 # 0 +0x0000DAC2 0x754B # 0 +0x0000DAC3 0x6548 # 0 +0x0000DAC4 0x6556 # 0 +0x0000DAC5 0x6555 # 0 +0x0000DAC6 0x654D # 0 +0x0000DAC7 0x6558 # 0 +0x0000DAC8 0x655E # 0 +0x0000DAC9 0x655D # 0 +0x0000DACA 0x6572 # 0 +0x0000DACB 0x6578 # 0 +0x0000DACC 0x6582 # 0 +0x0000DACD 0x6583 # 0 +0x0000DACE 0x8B8A # 0 +0x0000DACF 0x659B # 0 +0x0000DAD0 0x659F # 0 +0x0000DAD1 0x65AB # 0 +0x0000DAD2 0x65B7 # 0 +0x0000DAD3 0x65C3 # 0 +0x0000DAD4 0x65C6 # 0 +0x0000DAD5 0x65C1 # 0 +0x0000DAD6 0x65C4 # 0 +0x0000DAD7 0x65CC # 0 +0x0000DAD8 0x65D2 # 0 +0x0000DAD9 0x65DB # 0 +0x0000DADA 0x65D9 # 0 +0x0000DADB 0x65E0 # 0 +0x0000DADC 0x65E1 # 0 +0x0000DADD 0x65F1 # 0 +0x0000DADE 0x6772 # 0 +0x0000DADF 0x660A # 0 +0x0000DAE0 0x6603 # 0 +0x0000DAE1 0x65FB # 0 +0x0000DAE2 0x6773 # 0 +0x0000DAE3 0x6635 # 0 +0x0000DAE4 0x6636 # 0 +0x0000DAE5 0x6634 # 0 +0x0000DAE6 0x661C # 0 +0x0000DAE7 0x664F # 0 +0x0000DAE8 0x6644 # 0 +0x0000DAE9 0x6649 # 0 +0x0000DAEA 0x6641 # 0 +0x0000DAEB 0x665E # 0 +0x0000DAEC 0x665D # 0 +0x0000DAED 0x6664 # 0 +0x0000DAEE 0x6667 # 0 +0x0000DAEF 0x6668 # 0 +0x0000DAF0 0x665F # 0 +0x0000DAF1 0x6662 # 0 +0x0000DAF2 0x6670 # 0 +0x0000DAF3 0x6683 # 0 +0x0000DAF4 0x6688 # 0 +0x0000DAF5 0x668E # 0 +0x0000DAF6 0x6689 # 0 +0x0000DAF7 0x6684 # 0 +0x0000DAF8 0x6698 # 0 +0x0000DAF9 0x669D # 0 +0x0000DAFA 0x66C1 # 0 +0x0000DAFB 0x66B9 # 0 +0x0000DAFC 0x66C9 # 0 +0x0000DAFD 0x66BE # 0 +0x0000DAFE 0x66BC # 0 +0x0000DBA1 0x66C4 # 0 +0x0000DBA2 0x66B8 # 0 +0x0000DBA3 0x66D6 # 0 +0x0000DBA4 0x66DA # 0 +0x0000DBA5 0x66E0 # 0 +0x0000DBA6 0x663F # 0 +0x0000DBA7 0x66E6 # 0 +0x0000DBA8 0x66E9 # 0 +0x0000DBA9 0x66F0 # 0 +0x0000DBAA 0x66F5 # 0 +0x0000DBAB 0x66F7 # 0 +0x0000DBAC 0x670F # 0 +0x0000DBAD 0x6716 # 0 +0x0000DBAE 0x671E # 0 +0x0000DBAF 0x6726 # 0 +0x0000DBB0 0x6727 # 0 +0x0000DBB1 0x9738 # 0 +0x0000DBB2 0x672E # 0 +0x0000DBB3 0x673F # 0 +0x0000DBB4 0x6736 # 0 +0x0000DBB5 0x6741 # 0 +0x0000DBB6 0x6738 # 0 +0x0000DBB7 0x6737 # 0 +0x0000DBB8 0x6746 # 0 +0x0000DBB9 0x675E # 0 +0x0000DBBA 0x6760 # 0 +0x0000DBBB 0x6759 # 0 +0x0000DBBC 0x6763 # 0 +0x0000DBBD 0x6764 # 0 +0x0000DBBE 0x6789 # 0 +0x0000DBBF 0x6770 # 0 +0x0000DBC0 0x67A9 # 0 +0x0000DBC1 0x677C # 0 +0x0000DBC2 0x676A # 0 +0x0000DBC3 0x678C # 0 +0x0000DBC4 0x678B # 0 +0x0000DBC5 0x67A6 # 0 +0x0000DBC6 0x67A1 # 0 +0x0000DBC7 0x6785 # 0 +0x0000DBC8 0x67B7 # 0 +0x0000DBC9 0x67EF # 0 +0x0000DBCA 0x67B4 # 0 +0x0000DBCB 0x67EC # 0 +0x0000DBCC 0x67B3 # 0 +0x0000DBCD 0x67E9 # 0 +0x0000DBCE 0x67B8 # 0 +0x0000DBCF 0x67E4 # 0 +0x0000DBD0 0x67DE # 0 +0x0000DBD1 0x67DD # 0 +0x0000DBD2 0x67E2 # 0 +0x0000DBD3 0x67EE # 0 +0x0000DBD4 0x67B9 # 0 +0x0000DBD5 0x67CE # 0 +0x0000DBD6 0x67C6 # 0 +0x0000DBD7 0x67E7 # 0 +0x0000DBD8 0x6A9C # 0 +0x0000DBD9 0x681E # 0 +0x0000DBDA 0x6846 # 0 +0x0000DBDB 0x6829 # 0 +0x0000DBDC 0x6840 # 0 +0x0000DBDD 0x684D # 0 +0x0000DBDE 0x6832 # 0 +0x0000DBDF 0x684E # 0 +0x0000DBE0 0x68B3 # 0 +0x0000DBE1 0x682B # 0 +0x0000DBE2 0x6859 # 0 +0x0000DBE3 0x6863 # 0 +0x0000DBE4 0x6877 # 0 +0x0000DBE5 0x687F # 0 +0x0000DBE6 0x689F # 0 +0x0000DBE7 0x688F # 0 +0x0000DBE8 0x68AD # 0 +0x0000DBE9 0x6894 # 0 +0x0000DBEA 0x689D # 0 +0x0000DBEB 0x689B # 0 +0x0000DBEC 0x6883 # 0 +0x0000DBED 0x6AAE # 0 +0x0000DBEE 0x68B9 # 0 +0x0000DBEF 0x6874 # 0 +0x0000DBF0 0x68B5 # 0 +0x0000DBF1 0x68A0 # 0 +0x0000DBF2 0x68BA # 0 +0x0000DBF3 0x690F # 0 +0x0000DBF4 0x688D # 0 +0x0000DBF5 0x687E # 0 +0x0000DBF6 0x6901 # 0 +0x0000DBF7 0x68CA # 0 +0x0000DBF8 0x6908 # 0 +0x0000DBF9 0x68D8 # 0 +0x0000DBFA 0x6922 # 0 +0x0000DBFB 0x6926 # 0 +0x0000DBFC 0x68E1 # 0 +0x0000DBFD 0x690C # 0 +0x0000DBFE 0x68CD # 0 +0x0000DCA1 0x68D4 # 0 +0x0000DCA2 0x68E7 # 0 +0x0000DCA3 0x68D5 # 0 +0x0000DCA4 0x6936 # 0 +0x0000DCA5 0x6912 # 0 +0x0000DCA6 0x6904 # 0 +0x0000DCA7 0x68D7 # 0 +0x0000DCA8 0x68E3 # 0 +0x0000DCA9 0x6925 # 0 +0x0000DCAA 0x68F9 # 0 +0x0000DCAB 0x68E0 # 0 +0x0000DCAC 0x68EF # 0 +0x0000DCAD 0x6928 # 0 +0x0000DCAE 0x692A # 0 +0x0000DCAF 0x691A # 0 +0x0000DCB0 0x6923 # 0 +0x0000DCB1 0x6921 # 0 +0x0000DCB2 0x68C6 # 0 +0x0000DCB3 0x6979 # 0 +0x0000DCB4 0x6977 # 0 +0x0000DCB5 0x695C # 0 +0x0000DCB6 0x6978 # 0 +0x0000DCB7 0x696B # 0 +0x0000DCB8 0x6954 # 0 +0x0000DCB9 0x697E # 0 +0x0000DCBA 0x696E # 0 +0x0000DCBB 0x6939 # 0 +0x0000DCBC 0x6974 # 0 +0x0000DCBD 0x693D # 0 +0x0000DCBE 0x6959 # 0 +0x0000DCBF 0x6930 # 0 +0x0000DCC0 0x6961 # 0 +0x0000DCC1 0x695E # 0 +0x0000DCC2 0x695D # 0 +0x0000DCC3 0x6981 # 0 +0x0000DCC4 0x696A # 0 +0x0000DCC5 0x69B2 # 0 +0x0000DCC6 0x69AE # 0 +0x0000DCC7 0x69D0 # 0 +0x0000DCC8 0x69BF # 0 +0x0000DCC9 0x69C1 # 0 +0x0000DCCA 0x69D3 # 0 +0x0000DCCB 0x69BE # 0 +0x0000DCCC 0x69CE # 0 +0x0000DCCD 0x5BE8 # 0 +0x0000DCCE 0x69CA # 0 +0x0000DCCF 0x69DD # 0 +0x0000DCD0 0x69BB # 0 +0x0000DCD1 0x69C3 # 0 +0x0000DCD2 0x69A7 # 0 +0x0000DCD3 0x6A2E # 0 +0x0000DCD4 0x6991 # 0 +0x0000DCD5 0x69A0 # 0 +0x0000DCD6 0x699C # 0 +0x0000DCD7 0x6995 # 0 +0x0000DCD8 0x69B4 # 0 +0x0000DCD9 0x69DE # 0 +0x0000DCDA 0x69E8 # 0 +0x0000DCDB 0x6A02 # 0 +0x0000DCDC 0x6A1B # 0 +0x0000DCDD 0x69FF # 0 +0x0000DCDE 0x6B0A # 0 +0x0000DCDF 0x69F9 # 0 +0x0000DCE0 0x69F2 # 0 +0x0000DCE1 0x69E7 # 0 +0x0000DCE2 0x6A05 # 0 +0x0000DCE3 0x69B1 # 0 +0x0000DCE4 0x6A1E # 0 +0x0000DCE5 0x69ED # 0 +0x0000DCE6 0x6A14 # 0 +0x0000DCE7 0x69EB # 0 +0x0000DCE8 0x6A0A # 0 +0x0000DCE9 0x6A12 # 0 +0x0000DCEA 0x6AC1 # 0 +0x0000DCEB 0x6A23 # 0 +0x0000DCEC 0x6A13 # 0 +0x0000DCED 0x6A44 # 0 +0x0000DCEE 0x6A0C # 0 +0x0000DCEF 0x6A72 # 0 +0x0000DCF0 0x6A36 # 0 +0x0000DCF1 0x6A78 # 0 +0x0000DCF2 0x6A47 # 0 +0x0000DCF3 0x6A62 # 0 +0x0000DCF4 0x6A59 # 0 +0x0000DCF5 0x6A66 # 0 +0x0000DCF6 0x6A48 # 0 +0x0000DCF7 0x6A38 # 0 +0x0000DCF8 0x6A22 # 0 +0x0000DCF9 0x6A90 # 0 +0x0000DCFA 0x6A8D # 0 +0x0000DCFB 0x6AA0 # 0 +0x0000DCFC 0x6A84 # 0 +0x0000DCFD 0x6AA2 # 0 +0x0000DCFE 0x6AA3 # 0 +0x0000DDA1 0x6A97 # 0 +0x0000DDA2 0x8617 # 0 +0x0000DDA3 0x6ABB # 0 +0x0000DDA4 0x6AC3 # 0 +0x0000DDA5 0x6AC2 # 0 +0x0000DDA6 0x6AB8 # 0 +0x0000DDA7 0x6AB3 # 0 +0x0000DDA8 0x6AAC # 0 +0x0000DDA9 0x6ADE # 0 +0x0000DDAA 0x6AD1 # 0 +0x0000DDAB 0x6ADF # 0 +0x0000DDAC 0x6AAA # 0 +0x0000DDAD 0x6ADA # 0 +0x0000DDAE 0x6AEA # 0 +0x0000DDAF 0x6AFB # 0 +0x0000DDB0 0x6B05 # 0 +0x0000DDB1 0x8616 # 0 +0x0000DDB2 0x6AFA # 0 +0x0000DDB3 0x6B12 # 0 +0x0000DDB4 0x6B16 # 0 +0x0000DDB5 0x9B31 # 0 +0x0000DDB6 0x6B1F # 0 +0x0000DDB7 0x6B38 # 0 +0x0000DDB8 0x6B37 # 0 +0x0000DDB9 0x76DC # 0 +0x0000DDBA 0x6B39 # 0 +0x0000DDBB 0x98EE # 0 +0x0000DDBC 0x6B47 # 0 +0x0000DDBD 0x6B43 # 0 +0x0000DDBE 0x6B49 # 0 +0x0000DDBF 0x6B50 # 0 +0x0000DDC0 0x6B59 # 0 +0x0000DDC1 0x6B54 # 0 +0x0000DDC2 0x6B5B # 0 +0x0000DDC3 0x6B5F # 0 +0x0000DDC4 0x6B61 # 0 +0x0000DDC5 0x6B78 # 0 +0x0000DDC6 0x6B79 # 0 +0x0000DDC7 0x6B7F # 0 +0x0000DDC8 0x6B80 # 0 +0x0000DDC9 0x6B84 # 0 +0x0000DDCA 0x6B83 # 0 +0x0000DDCB 0x6B8D # 0 +0x0000DDCC 0x6B98 # 0 +0x0000DDCD 0x6B95 # 0 +0x0000DDCE 0x6B9E # 0 +0x0000DDCF 0x6BA4 # 0 +0x0000DDD0 0x6BAA # 0 +0x0000DDD1 0x6BAB # 0 +0x0000DDD2 0x6BAF # 0 +0x0000DDD3 0x6BB2 # 0 +0x0000DDD4 0x6BB1 # 0 +0x0000DDD5 0x6BB3 # 0 +0x0000DDD6 0x6BB7 # 0 +0x0000DDD7 0x6BBC # 0 +0x0000DDD8 0x6BC6 # 0 +0x0000DDD9 0x6BCB # 0 +0x0000DDDA 0x6BD3 # 0 +0x0000DDDB 0x6BDF # 0 +0x0000DDDC 0x6BEC # 0 +0x0000DDDD 0x6BEB # 0 +0x0000DDDE 0x6BF3 # 0 +0x0000DDDF 0x6BEF # 0 +0x0000DDE0 0x9EBE # 0 +0x0000DDE1 0x6C08 # 0 +0x0000DDE2 0x6C13 # 0 +0x0000DDE3 0x6C14 # 0 +0x0000DDE4 0x6C1B # 0 +0x0000DDE5 0x6C24 # 0 +0x0000DDE6 0x6C23 # 0 +0x0000DDE7 0x6C5E # 0 +0x0000DDE8 0x6C55 # 0 +0x0000DDE9 0x6C62 # 0 +0x0000DDEA 0x6C6A # 0 +0x0000DDEB 0x6C82 # 0 +0x0000DDEC 0x6C8D # 0 +0x0000DDED 0x6C9A # 0 +0x0000DDEE 0x6C81 # 0 +0x0000DDEF 0x6C9B # 0 +0x0000DDF0 0x6C7E # 0 +0x0000DDF1 0x6C68 # 0 +0x0000DDF2 0x6C73 # 0 +0x0000DDF3 0x6C92 # 0 +0x0000DDF4 0x6C90 # 0 +0x0000DDF5 0x6CC4 # 0 +0x0000DDF6 0x6CF1 # 0 +0x0000DDF7 0x6CD3 # 0 +0x0000DDF8 0x6CBD # 0 +0x0000DDF9 0x6CD7 # 0 +0x0000DDFA 0x6CC5 # 0 +0x0000DDFB 0x6CDD # 0 +0x0000DDFC 0x6CAE # 0 +0x0000DDFD 0x6CB1 # 0 +0x0000DDFE 0x6CBE # 0 +0x0000DEA1 0x6CBA # 0 +0x0000DEA2 0x6CDB # 0 +0x0000DEA3 0x6CEF # 0 +0x0000DEA4 0x6CD9 # 0 +0x0000DEA5 0x6CEA # 0 +0x0000DEA6 0x6D1F # 0 +0x0000DEA7 0x884D # 0 +0x0000DEA8 0x6D36 # 0 +0x0000DEA9 0x6D2B # 0 +0x0000DEAA 0x6D3D # 0 +0x0000DEAB 0x6D38 # 0 +0x0000DEAC 0x6D19 # 0 +0x0000DEAD 0x6D35 # 0 +0x0000DEAE 0x6D33 # 0 +0x0000DEAF 0x6D12 # 0 +0x0000DEB0 0x6D0C # 0 +0x0000DEB1 0x6D63 # 0 +0x0000DEB2 0x6D93 # 0 +0x0000DEB3 0x6D64 # 0 +0x0000DEB4 0x6D5A # 0 +0x0000DEB5 0x6D79 # 0 +0x0000DEB6 0x6D59 # 0 +0x0000DEB7 0x6D8E # 0 +0x0000DEB8 0x6D95 # 0 +0x0000DEB9 0x6FE4 # 0 +0x0000DEBA 0x6D85 # 0 +0x0000DEBB 0x6DF9 # 0 +0x0000DEBC 0x6E15 # 0 +0x0000DEBD 0x6E0A # 0 +0x0000DEBE 0x6DB5 # 0 +0x0000DEBF 0x6DC7 # 0 +0x0000DEC0 0x6DE6 # 0 +0x0000DEC1 0x6DB8 # 0 +0x0000DEC2 0x6DC6 # 0 +0x0000DEC3 0x6DEC # 0 +0x0000DEC4 0x6DDE # 0 +0x0000DEC5 0x6DCC # 0 +0x0000DEC6 0x6DE8 # 0 +0x0000DEC7 0x6DD2 # 0 +0x0000DEC8 0x6DC5 # 0 +0x0000DEC9 0x6DFA # 0 +0x0000DECA 0x6DD9 # 0 +0x0000DECB 0x6DE4 # 0 +0x0000DECC 0x6DD5 # 0 +0x0000DECD 0x6DEA # 0 +0x0000DECE 0x6DEE # 0 +0x0000DECF 0x6E2D # 0 +0x0000DED0 0x6E6E # 0 +0x0000DED1 0x6E2E # 0 +0x0000DED2 0x6E19 # 0 +0x0000DED3 0x6E72 # 0 +0x0000DED4 0x6E5F # 0 +0x0000DED5 0x6E3E # 0 +0x0000DED6 0x6E23 # 0 +0x0000DED7 0x6E6B # 0 +0x0000DED8 0x6E2B # 0 +0x0000DED9 0x6E76 # 0 +0x0000DEDA 0x6E4D # 0 +0x0000DEDB 0x6E1F # 0 +0x0000DEDC 0x6E43 # 0 +0x0000DEDD 0x6E3A # 0 +0x0000DEDE 0x6E4E # 0 +0x0000DEDF 0x6E24 # 0 +0x0000DEE0 0x6EFF # 0 +0x0000DEE1 0x6E1D # 0 +0x0000DEE2 0x6E38 # 0 +0x0000DEE3 0x6E82 # 0 +0x0000DEE4 0x6EAA # 0 +0x0000DEE5 0x6E98 # 0 +0x0000DEE6 0x6EC9 # 0 +0x0000DEE7 0x6EB7 # 0 +0x0000DEE8 0x6ED3 # 0 +0x0000DEE9 0x6EBD # 0 +0x0000DEEA 0x6EAF # 0 +0x0000DEEB 0x6EC4 # 0 +0x0000DEEC 0x6EB2 # 0 +0x0000DEED 0x6ED4 # 0 +0x0000DEEE 0x6ED5 # 0 +0x0000DEEF 0x6E8F # 0 +0x0000DEF0 0x6EA5 # 0 +0x0000DEF1 0x6EC2 # 0 +0x0000DEF2 0x6E9F # 0 +0x0000DEF3 0x6F41 # 0 +0x0000DEF4 0x6F11 # 0 +0x0000DEF5 0x704C # 0 +0x0000DEF6 0x6EEC # 0 +0x0000DEF7 0x6EF8 # 0 +0x0000DEF8 0x6EFE # 0 +0x0000DEF9 0x6F3F # 0 +0x0000DEFA 0x6EF2 # 0 +0x0000DEFB 0x6F31 # 0 +0x0000DEFC 0x6EEF # 0 +0x0000DEFD 0x6F32 # 0 +0x0000DEFE 0x6ECC # 0 +0x0000DFA1 0x6F3E # 0 +0x0000DFA2 0x6F13 # 0 +0x0000DFA3 0x6EF7 # 0 +0x0000DFA4 0x6F86 # 0 +0x0000DFA5 0x6F7A # 0 +0x0000DFA6 0x6F78 # 0 +0x0000DFA7 0x6F81 # 0 +0x0000DFA8 0x6F80 # 0 +0x0000DFA9 0x6F6F # 0 +0x0000DFAA 0x6F5B # 0 +0x0000DFAB 0x6FF3 # 0 +0x0000DFAC 0x6F6D # 0 +0x0000DFAD 0x6F82 # 0 +0x0000DFAE 0x6F7C # 0 +0x0000DFAF 0x6F58 # 0 +0x0000DFB0 0x6F8E # 0 +0x0000DFB1 0x6F91 # 0 +0x0000DFB2 0x6FC2 # 0 +0x0000DFB3 0x6F66 # 0 +0x0000DFB4 0x6FB3 # 0 +0x0000DFB5 0x6FA3 # 0 +0x0000DFB6 0x6FA1 # 0 +0x0000DFB7 0x6FA4 # 0 +0x0000DFB8 0x6FB9 # 0 +0x0000DFB9 0x6FC6 # 0 +0x0000DFBA 0x6FAA # 0 +0x0000DFBB 0x6FDF # 0 +0x0000DFBC 0x6FD5 # 0 +0x0000DFBD 0x6FEC # 0 +0x0000DFBE 0x6FD4 # 0 +0x0000DFBF 0x6FD8 # 0 +0x0000DFC0 0x6FF1 # 0 +0x0000DFC1 0x6FEE # 0 +0x0000DFC2 0x6FDB # 0 +0x0000DFC3 0x7009 # 0 +0x0000DFC4 0x700B # 0 +0x0000DFC5 0x6FFA # 0 +0x0000DFC6 0x7011 # 0 +0x0000DFC7 0x7001 # 0 +0x0000DFC8 0x700F # 0 +0x0000DFC9 0x6FFE # 0 +0x0000DFCA 0x701B # 0 +0x0000DFCB 0x701A # 0 +0x0000DFCC 0x6F74 # 0 +0x0000DFCD 0x701D # 0 +0x0000DFCE 0x7018 # 0 +0x0000DFCF 0x701F # 0 +0x0000DFD0 0x7030 # 0 +0x0000DFD1 0x703E # 0 +0x0000DFD2 0x7032 # 0 +0x0000DFD3 0x7051 # 0 +0x0000DFD4 0x7063 # 0 +0x0000DFD5 0x7099 # 0 +0x0000DFD6 0x7092 # 0 +0x0000DFD7 0x70AF # 0 +0x0000DFD8 0x70F1 # 0 +0x0000DFD9 0x70AC # 0 +0x0000DFDA 0x70B8 # 0 +0x0000DFDB 0x70B3 # 0 +0x0000DFDC 0x70AE # 0 +0x0000DFDD 0x70DF # 0 +0x0000DFDE 0x70CB # 0 +0x0000DFDF 0x70DD # 0 +0x0000DFE0 0x70D9 # 0 +0x0000DFE1 0x7109 # 0 +0x0000DFE2 0x70FD # 0 +0x0000DFE3 0x711C # 0 +0x0000DFE4 0x7119 # 0 +0x0000DFE5 0x7165 # 0 +0x0000DFE6 0x7155 # 0 +0x0000DFE7 0x7188 # 0 +0x0000DFE8 0x7166 # 0 +0x0000DFE9 0x7162 # 0 +0x0000DFEA 0x714C # 0 +0x0000DFEB 0x7156 # 0 +0x0000DFEC 0x716C # 0 +0x0000DFED 0x718F # 0 +0x0000DFEE 0x71FB # 0 +0x0000DFEF 0x7184 # 0 +0x0000DFF0 0x7195 # 0 +0x0000DFF1 0x71A8 # 0 +0x0000DFF2 0x71AC # 0 +0x0000DFF3 0x71D7 # 0 +0x0000DFF4 0x71B9 # 0 +0x0000DFF5 0x71BE # 0 +0x0000DFF6 0x71D2 # 0 +0x0000DFF7 0x71C9 # 0 +0x0000DFF8 0x71D4 # 0 +0x0000DFF9 0x71CE # 0 +0x0000DFFA 0x71E0 # 0 +0x0000DFFB 0x71EC # 0 +0x0000DFFC 0x71E7 # 0 +0x0000DFFD 0x71F5 # 0 +0x0000DFFE 0x71FC # 0 +0x0000E0A1 0x71F9 # 0 +0x0000E0A2 0x71FF # 0 +0x0000E0A3 0x720D # 0 +0x0000E0A4 0x7210 # 0 +0x0000E0A5 0x721B # 0 +0x0000E0A6 0x7228 # 0 +0x0000E0A7 0x722D # 0 +0x0000E0A8 0x722C # 0 +0x0000E0A9 0x7230 # 0 +0x0000E0AA 0x7232 # 0 +0x0000E0AB 0x723B # 0 +0x0000E0AC 0x723C # 0 +0x0000E0AD 0x723F # 0 +0x0000E0AE 0x7240 # 0 +0x0000E0AF 0x7246 # 0 +0x0000E0B0 0x724B # 0 +0x0000E0B1 0x7258 # 0 +0x0000E0B2 0x7274 # 0 +0x0000E0B3 0x727E # 0 +0x0000E0B4 0x7282 # 0 +0x0000E0B5 0x7281 # 0 +0x0000E0B6 0x7287 # 0 +0x0000E0B7 0x7292 # 0 +0x0000E0B8 0x7296 # 0 +0x0000E0B9 0x72A2 # 0 +0x0000E0BA 0x72A7 # 0 +0x0000E0BB 0x72B9 # 0 +0x0000E0BC 0x72B2 # 0 +0x0000E0BD 0x72C3 # 0 +0x0000E0BE 0x72C6 # 0 +0x0000E0BF 0x72C4 # 0 +0x0000E0C0 0x72CE # 0 +0x0000E0C1 0x72D2 # 0 +0x0000E0C2 0x72E2 # 0 +0x0000E0C3 0x72E0 # 0 +0x0000E0C4 0x72E1 # 0 +0x0000E0C5 0x72F9 # 0 +0x0000E0C6 0x72F7 # 0 +0x0000E0C7 0x500F # 0 +0x0000E0C8 0x7317 # 0 +0x0000E0C9 0x730A # 0 +0x0000E0CA 0x731C # 0 +0x0000E0CB 0x7316 # 0 +0x0000E0CC 0x731D # 0 +0x0000E0CD 0x7334 # 0 +0x0000E0CE 0x732F # 0 +0x0000E0CF 0x7329 # 0 +0x0000E0D0 0x7325 # 0 +0x0000E0D1 0x733E # 0 +0x0000E0D2 0x734E # 0 +0x0000E0D3 0x734F # 0 +0x0000E0D4 0x9ED8 # 0 +0x0000E0D5 0x7357 # 0 +0x0000E0D6 0x736A # 0 +0x0000E0D7 0x7368 # 0 +0x0000E0D8 0x7370 # 0 +0x0000E0D9 0x7378 # 0 +0x0000E0DA 0x7375 # 0 +0x0000E0DB 0x737B # 0 +0x0000E0DC 0x737A # 0 +0x0000E0DD 0x73C8 # 0 +0x0000E0DE 0x73B3 # 0 +0x0000E0DF 0x73CE # 0 +0x0000E0E0 0x73BB # 0 +0x0000E0E1 0x73C0 # 0 +0x0000E0E2 0x73E5 # 0 +0x0000E0E3 0x73EE # 0 +0x0000E0E4 0x73DE # 0 +0x0000E0E5 0x74A2 # 0 +0x0000E0E6 0x7405 # 0 +0x0000E0E7 0x746F # 0 +0x0000E0E8 0x7425 # 0 +0x0000E0E9 0x73F8 # 0 +0x0000E0EA 0x7432 # 0 +0x0000E0EB 0x743A # 0 +0x0000E0EC 0x7455 # 0 +0x0000E0ED 0x743F # 0 +0x0000E0EE 0x745F # 0 +0x0000E0EF 0x7459 # 0 +0x0000E0F0 0x7441 # 0 +0x0000E0F1 0x745C # 0 +0x0000E0F2 0x7469 # 0 +0x0000E0F3 0x7470 # 0 +0x0000E0F4 0x7463 # 0 +0x0000E0F5 0x746A # 0 +0x0000E0F6 0x7476 # 0 +0x0000E0F7 0x747E # 0 +0x0000E0F8 0x748B # 0 +0x0000E0F9 0x749E # 0 +0x0000E0FA 0x74A7 # 0 +0x0000E0FB 0x74CA # 0 +0x0000E0FC 0x74CF # 0 +0x0000E0FD 0x74D4 # 0 +0x0000E0FE 0x73F1 # 0 +0x0000E1A1 0x74E0 # 0 +0x0000E1A2 0x74E3 # 0 +0x0000E1A3 0x74E7 # 0 +0x0000E1A4 0x74E9 # 0 +0x0000E1A5 0x74EE # 0 +0x0000E1A6 0x74F2 # 0 +0x0000E1A7 0x74F0 # 0 +0x0000E1A8 0x74F1 # 0 +0x0000E1A9 0x74F8 # 0 +0x0000E1AA 0x74F7 # 0 +0x0000E1AB 0x7504 # 0 +0x0000E1AC 0x7503 # 0 +0x0000E1AD 0x7505 # 0 +0x0000E1AE 0x750C # 0 +0x0000E1AF 0x750E # 0 +0x0000E1B0 0x750D # 0 +0x0000E1B1 0x7515 # 0 +0x0000E1B2 0x7513 # 0 +0x0000E1B3 0x751E # 0 +0x0000E1B4 0x7526 # 0 +0x0000E1B5 0x752C # 0 +0x0000E1B6 0x753C # 0 +0x0000E1B7 0x7544 # 0 +0x0000E1B8 0x754D # 0 +0x0000E1B9 0x754A # 0 +0x0000E1BA 0x7549 # 0 +0x0000E1BB 0x755B # 0 +0x0000E1BC 0x7546 # 0 +0x0000E1BD 0x755A # 0 +0x0000E1BE 0x7569 # 0 +0x0000E1BF 0x7564 # 0 +0x0000E1C0 0x7567 # 0 +0x0000E1C1 0x756B # 0 +0x0000E1C2 0x756D # 0 +0x0000E1C3 0x7578 # 0 +0x0000E1C4 0x7576 # 0 +0x0000E1C5 0x7586 # 0 +0x0000E1C6 0x7587 # 0 +0x0000E1C7 0x7574 # 0 +0x0000E1C8 0x758A # 0 +0x0000E1C9 0x7589 # 0 +0x0000E1CA 0x7582 # 0 +0x0000E1CB 0x7594 # 0 +0x0000E1CC 0x759A # 0 +0x0000E1CD 0x759D # 0 +0x0000E1CE 0x75A5 # 0 +0x0000E1CF 0x75A3 # 0 +0x0000E1D0 0x75C2 # 0 +0x0000E1D1 0x75B3 # 0 +0x0000E1D2 0x75C3 # 0 +0x0000E1D3 0x75B5 # 0 +0x0000E1D4 0x75BD # 0 +0x0000E1D5 0x75B8 # 0 +0x0000E1D6 0x75BC # 0 +0x0000E1D7 0x75B1 # 0 +0x0000E1D8 0x75CD # 0 +0x0000E1D9 0x75CA # 0 +0x0000E1DA 0x75D2 # 0 +0x0000E1DB 0x75D9 # 0 +0x0000E1DC 0x75E3 # 0 +0x0000E1DD 0x75DE # 0 +0x0000E1DE 0x75FE # 0 +0x0000E1DF 0x75FF # 0 +0x0000E1E0 0x75FC # 0 +0x0000E1E1 0x7601 # 0 +0x0000E1E2 0x75F0 # 0 +0x0000E1E3 0x75FA # 0 +0x0000E1E4 0x75F2 # 0 +0x0000E1E5 0x75F3 # 0 +0x0000E1E6 0x760B # 0 +0x0000E1E7 0x760D # 0 +0x0000E1E8 0x7609 # 0 +0x0000E1E9 0x761F # 0 +0x0000E1EA 0x7627 # 0 +0x0000E1EB 0x7620 # 0 +0x0000E1EC 0x7621 # 0 +0x0000E1ED 0x7622 # 0 +0x0000E1EE 0x7624 # 0 +0x0000E1EF 0x7634 # 0 +0x0000E1F0 0x7630 # 0 +0x0000E1F1 0x763B # 0 +0x0000E1F2 0x7647 # 0 +0x0000E1F3 0x7648 # 0 +0x0000E1F4 0x7646 # 0 +0x0000E1F5 0x765C # 0 +0x0000E1F6 0x7658 # 0 +0x0000E1F7 0x7661 # 0 +0x0000E1F8 0x7662 # 0 +0x0000E1F9 0x7668 # 0 +0x0000E1FA 0x7669 # 0 +0x0000E1FB 0x766A # 0 +0x0000E1FC 0x7667 # 0 +0x0000E1FD 0x766C # 0 +0x0000E1FE 0x7670 # 0 +0x0000E2A1 0x7672 # 0 +0x0000E2A2 0x7676 # 0 +0x0000E2A3 0x7678 # 0 +0x0000E2A4 0x767C # 0 +0x0000E2A5 0x7680 # 0 +0x0000E2A6 0x7683 # 0 +0x0000E2A7 0x7688 # 0 +0x0000E2A8 0x768B # 0 +0x0000E2A9 0x768E # 0 +0x0000E2AA 0x7696 # 0 +0x0000E2AB 0x7693 # 0 +0x0000E2AC 0x7699 # 0 +0x0000E2AD 0x769A # 0 +0x0000E2AE 0x76B0 # 0 +0x0000E2AF 0x76B4 # 0 +0x0000E2B0 0x76B8 # 0 +0x0000E2B1 0x76B9 # 0 +0x0000E2B2 0x76BA # 0 +0x0000E2B3 0x76C2 # 0 +0x0000E2B4 0x76CD # 0 +0x0000E2B5 0x76D6 # 0 +0x0000E2B6 0x76D2 # 0 +0x0000E2B7 0x76DE # 0 +0x0000E2B8 0x76E1 # 0 +0x0000E2B9 0x76E5 # 0 +0x0000E2BA 0x76E7 # 0 +0x0000E2BB 0x76EA # 0 +0x0000E2BC 0x862F # 0 +0x0000E2BD 0x76FB # 0 +0x0000E2BE 0x7708 # 0 +0x0000E2BF 0x7707 # 0 +0x0000E2C0 0x7704 # 0 +0x0000E2C1 0x7729 # 0 +0x0000E2C2 0x7724 # 0 +0x0000E2C3 0x771E # 0 +0x0000E2C4 0x7725 # 0 +0x0000E2C5 0x7726 # 0 +0x0000E2C6 0x771B # 0 +0x0000E2C7 0x7737 # 0 +0x0000E2C8 0x7738 # 0 +0x0000E2C9 0x7747 # 0 +0x0000E2CA 0x775A # 0 +0x0000E2CB 0x7768 # 0 +0x0000E2CC 0x776B # 0 +0x0000E2CD 0x775B # 0 +0x0000E2CE 0x7765 # 0 +0x0000E2CF 0x777F # 0 +0x0000E2D0 0x777E # 0 +0x0000E2D1 0x7779 # 0 +0x0000E2D2 0x778E # 0 +0x0000E2D3 0x778B # 0 +0x0000E2D4 0x7791 # 0 +0x0000E2D5 0x77A0 # 0 +0x0000E2D6 0x779E # 0 +0x0000E2D7 0x77B0 # 0 +0x0000E2D8 0x77B6 # 0 +0x0000E2D9 0x77B9 # 0 +0x0000E2DA 0x77BF # 0 +0x0000E2DB 0x77BC # 0 +0x0000E2DC 0x77BD # 0 +0x0000E2DD 0x77BB # 0 +0x0000E2DE 0x77C7 # 0 +0x0000E2DF 0x77CD # 0 +0x0000E2E0 0x77D7 # 0 +0x0000E2E1 0x77DA # 0 +0x0000E2E2 0x77DC # 0 +0x0000E2E3 0x77E3 # 0 +0x0000E2E4 0x77EE # 0 +0x0000E2E5 0x77FC # 0 +0x0000E2E6 0x780C # 0 +0x0000E2E7 0x7812 # 0 +0x0000E2E8 0x7926 # 0 +0x0000E2E9 0x7820 # 0 +0x0000E2EA 0x792A # 0 +0x0000E2EB 0x7845 # 0 +0x0000E2EC 0x788E # 0 +0x0000E2ED 0x7874 # 0 +0x0000E2EE 0x7886 # 0 +0x0000E2EF 0x787C # 0 +0x0000E2F0 0x789A # 0 +0x0000E2F1 0x788C # 0 +0x0000E2F2 0x78A3 # 0 +0x0000E2F3 0x78B5 # 0 +0x0000E2F4 0x78AA # 0 +0x0000E2F5 0x78AF # 0 +0x0000E2F6 0x78D1 # 0 +0x0000E2F7 0x78C6 # 0 +0x0000E2F8 0x78CB # 0 +0x0000E2F9 0x78D4 # 0 +0x0000E2FA 0x78BE # 0 +0x0000E2FB 0x78BC # 0 +0x0000E2FC 0x78C5 # 0 +0x0000E2FD 0x78CA # 0 +0x0000E2FE 0x78EC # 0 +0x0000E3A1 0x78E7 # 0 +0x0000E3A2 0x78DA # 0 +0x0000E3A3 0x78FD # 0 +0x0000E3A4 0x78F4 # 0 +0x0000E3A5 0x7907 # 0 +0x0000E3A6 0x7912 # 0 +0x0000E3A7 0x7911 # 0 +0x0000E3A8 0x7919 # 0 +0x0000E3A9 0x792C # 0 +0x0000E3AA 0x792B # 0 +0x0000E3AB 0x7940 # 0 +0x0000E3AC 0x7960 # 0 +0x0000E3AD 0x7957 # 0 +0x0000E3AE 0x795F # 0 +0x0000E3AF 0x795A # 0 +0x0000E3B0 0x7955 # 0 +0x0000E3B1 0x7953 # 0 +0x0000E3B2 0x797A # 0 +0x0000E3B3 0x797F # 0 +0x0000E3B4 0x798A # 0 +0x0000E3B5 0x799D # 0 +0x0000E3B6 0x79A7 # 0 +0x0000E3B7 0x9F4B # 0 +0x0000E3B8 0x79AA # 0 +0x0000E3B9 0x79AE # 0 +0x0000E3BA 0x79B3 # 0 +0x0000E3BB 0x79B9 # 0 +0x0000E3BC 0x79BA # 0 +0x0000E3BD 0x79C9 # 0 +0x0000E3BE 0x79D5 # 0 +0x0000E3BF 0x79E7 # 0 +0x0000E3C0 0x79EC # 0 +0x0000E3C1 0x79E1 # 0 +0x0000E3C2 0x79E3 # 0 +0x0000E3C3 0x7A08 # 0 +0x0000E3C4 0x7A0D # 0 +0x0000E3C5 0x7A18 # 0 +0x0000E3C6 0x7A19 # 0 +0x0000E3C7 0x7A20 # 0 +0x0000E3C8 0x7A1F # 0 +0x0000E3C9 0x7980 # 0 +0x0000E3CA 0x7A31 # 0 +0x0000E3CB 0x7A3B # 0 +0x0000E3CC 0x7A3E # 0 +0x0000E3CD 0x7A37 # 0 +0x0000E3CE 0x7A43 # 0 +0x0000E3CF 0x7A57 # 0 +0x0000E3D0 0x7A49 # 0 +0x0000E3D1 0x7A61 # 0 +0x0000E3D2 0x7A62 # 0 +0x0000E3D3 0x7A69 # 0 +0x0000E3D4 0x9F9D # 0 +0x0000E3D5 0x7A70 # 0 +0x0000E3D6 0x7A79 # 0 +0x0000E3D7 0x7A7D # 0 +0x0000E3D8 0x7A88 # 0 +0x0000E3D9 0x7A97 # 0 +0x0000E3DA 0x7A95 # 0 +0x0000E3DB 0x7A98 # 0 +0x0000E3DC 0x7A96 # 0 +0x0000E3DD 0x7AA9 # 0 +0x0000E3DE 0x7AC8 # 0 +0x0000E3DF 0x7AB0 # 0 +0x0000E3E0 0x7AB6 # 0 +0x0000E3E1 0x7AC5 # 0 +0x0000E3E2 0x7AC4 # 0 +0x0000E3E3 0x7ABF # 0 +0x0000E3E4 0x9083 # 0 +0x0000E3E5 0x7AC7 # 0 +0x0000E3E6 0x7ACA # 0 +0x0000E3E7 0x7ACD # 0 +0x0000E3E8 0x7ACF # 0 +0x0000E3E9 0x7AD5 # 0 +0x0000E3EA 0x7AD3 # 0 +0x0000E3EB 0x7AD9 # 0 +0x0000E3EC 0x7ADA # 0 +0x0000E3ED 0x7ADD # 0 +0x0000E3EE 0x7AE1 # 0 +0x0000E3EF 0x7AE2 # 0 +0x0000E3F0 0x7AE6 # 0 +0x0000E3F1 0x7AED # 0 +0x0000E3F2 0x7AF0 # 0 +0x0000E3F3 0x7B02 # 0 +0x0000E3F4 0x7B0F # 0 +0x0000E3F5 0x7B0A # 0 +0x0000E3F6 0x7B06 # 0 +0x0000E3F7 0x7B33 # 0 +0x0000E3F8 0x7B18 # 0 +0x0000E3F9 0x7B19 # 0 +0x0000E3FA 0x7B1E # 0 +0x0000E3FB 0x7B35 # 0 +0x0000E3FC 0x7B28 # 0 +0x0000E3FD 0x7B36 # 0 +0x0000E3FE 0x7B50 # 0 +0x0000E4A1 0x7B7A # 0 +0x0000E4A2 0x7B04 # 0 +0x0000E4A3 0x7B4D # 0 +0x0000E4A4 0x7B0B # 0 +0x0000E4A5 0x7B4C # 0 +0x0000E4A6 0x7B45 # 0 +0x0000E4A7 0x7B75 # 0 +0x0000E4A8 0x7B65 # 0 +0x0000E4A9 0x7B74 # 0 +0x0000E4AA 0x7B67 # 0 +0x0000E4AB 0x7B70 # 0 +0x0000E4AC 0x7B71 # 0 +0x0000E4AD 0x7B6C # 0 +0x0000E4AE 0x7B6E # 0 +0x0000E4AF 0x7B9D # 0 +0x0000E4B0 0x7B98 # 0 +0x0000E4B1 0x7B9F # 0 +0x0000E4B2 0x7B8D # 0 +0x0000E4B3 0x7B9C # 0 +0x0000E4B4 0x7B9A # 0 +0x0000E4B5 0x7B8B # 0 +0x0000E4B6 0x7B92 # 0 +0x0000E4B7 0x7B8F # 0 +0x0000E4B8 0x7B5D # 0 +0x0000E4B9 0x7B99 # 0 +0x0000E4BA 0x7BCB # 0 +0x0000E4BB 0x7BC1 # 0 +0x0000E4BC 0x7BCC # 0 +0x0000E4BD 0x7BCF # 0 +0x0000E4BE 0x7BB4 # 0 +0x0000E4BF 0x7BC6 # 0 +0x0000E4C0 0x7BDD # 0 +0x0000E4C1 0x7BE9 # 0 +0x0000E4C2 0x7C11 # 0 +0x0000E4C3 0x7C14 # 0 +0x0000E4C4 0x7BE6 # 0 +0x0000E4C5 0x7BE5 # 0 +0x0000E4C6 0x7C60 # 0 +0x0000E4C7 0x7C00 # 0 +0x0000E4C8 0x7C07 # 0 +0x0000E4C9 0x7C13 # 0 +0x0000E4CA 0x7BF3 # 0 +0x0000E4CB 0x7BF7 # 0 +0x0000E4CC 0x7C17 # 0 +0x0000E4CD 0x7C0D # 0 +0x0000E4CE 0x7BF6 # 0 +0x0000E4CF 0x7C23 # 0 +0x0000E4D0 0x7C27 # 0 +0x0000E4D1 0x7C2A # 0 +0x0000E4D2 0x7C1F # 0 +0x0000E4D3 0x7C37 # 0 +0x0000E4D4 0x7C2B # 0 +0x0000E4D5 0x7C3D # 0 +0x0000E4D6 0x7C4C # 0 +0x0000E4D7 0x7C43 # 0 +0x0000E4D8 0x7C54 # 0 +0x0000E4D9 0x7C4F # 0 +0x0000E4DA 0x7C40 # 0 +0x0000E4DB 0x7C50 # 0 +0x0000E4DC 0x7C58 # 0 +0x0000E4DD 0x7C5F # 0 +0x0000E4DE 0x7C64 # 0 +0x0000E4DF 0x7C56 # 0 +0x0000E4E0 0x7C65 # 0 +0x0000E4E1 0x7C6C # 0 +0x0000E4E2 0x7C75 # 0 +0x0000E4E3 0x7C83 # 0 +0x0000E4E4 0x7C90 # 0 +0x0000E4E5 0x7CA4 # 0 +0x0000E4E6 0x7CAD # 0 +0x0000E4E7 0x7CA2 # 0 +0x0000E4E8 0x7CAB # 0 +0x0000E4E9 0x7CA1 # 0 +0x0000E4EA 0x7CA8 # 0 +0x0000E4EB 0x7CB3 # 0 +0x0000E4EC 0x7CB2 # 0 +0x0000E4ED 0x7CB1 # 0 +0x0000E4EE 0x7CAE # 0 +0x0000E4EF 0x7CB9 # 0 +0x0000E4F0 0x7CBD # 0 +0x0000E4F1 0x7CC0 # 0 +0x0000E4F2 0x7CC5 # 0 +0x0000E4F3 0x7CC2 # 0 +0x0000E4F4 0x7CD8 # 0 +0x0000E4F5 0x7CD2 # 0 +0x0000E4F6 0x7CDC # 0 +0x0000E4F7 0x7CE2 # 0 +0x0000E4F8 0x9B3B # 0 +0x0000E4F9 0x7CEF # 0 +0x0000E4FA 0x7CF2 # 0 +0x0000E4FB 0x7CF4 # 0 +0x0000E4FC 0x7CF6 # 0 +0x0000E4FD 0x7CFA # 0 +0x0000E4FE 0x7D06 # 0 +0x0000E5A1 0x7D02 # 0 +0x0000E5A2 0x7D1C # 0 +0x0000E5A3 0x7D15 # 0 +0x0000E5A4 0x7D0A # 0 +0x0000E5A5 0x7D45 # 0 +0x0000E5A6 0x7D4B # 0 +0x0000E5A7 0x7D2E # 0 +0x0000E5A8 0x7D32 # 0 +0x0000E5A9 0x7D3F # 0 +0x0000E5AA 0x7D35 # 0 +0x0000E5AB 0x7D46 # 0 +0x0000E5AC 0x7D73 # 0 +0x0000E5AD 0x7D56 # 0 +0x0000E5AE 0x7D4E # 0 +0x0000E5AF 0x7D72 # 0 +0x0000E5B0 0x7D68 # 0 +0x0000E5B1 0x7D6E # 0 +0x0000E5B2 0x7D4F # 0 +0x0000E5B3 0x7D63 # 0 +0x0000E5B4 0x7D93 # 0 +0x0000E5B5 0x7D89 # 0 +0x0000E5B6 0x7D5B # 0 +0x0000E5B7 0x7D8F # 0 +0x0000E5B8 0x7D7D # 0 +0x0000E5B9 0x7D9B # 0 +0x0000E5BA 0x7DBA # 0 +0x0000E5BB 0x7DAE # 0 +0x0000E5BC 0x7DA3 # 0 +0x0000E5BD 0x7DB5 # 0 +0x0000E5BE 0x7DC7 # 0 +0x0000E5BF 0x7DBD # 0 +0x0000E5C0 0x7DAB # 0 +0x0000E5C1 0x7E3D # 0 +0x0000E5C2 0x7DA2 # 0 +0x0000E5C3 0x7DAF # 0 +0x0000E5C4 0x7DDC # 0 +0x0000E5C5 0x7DB8 # 0 +0x0000E5C6 0x7D9F # 0 +0x0000E5C7 0x7DB0 # 0 +0x0000E5C8 0x7DD8 # 0 +0x0000E5C9 0x7DDD # 0 +0x0000E5CA 0x7DE4 # 0 +0x0000E5CB 0x7DDE # 0 +0x0000E5CC 0x7DFB # 0 +0x0000E5CD 0x7DF2 # 0 +0x0000E5CE 0x7DE1 # 0 +0x0000E5CF 0x7E05 # 0 +0x0000E5D0 0x7E0A # 0 +0x0000E5D1 0x7E23 # 0 +0x0000E5D2 0x7E21 # 0 +0x0000E5D3 0x7E12 # 0 +0x0000E5D4 0x7E31 # 0 +0x0000E5D5 0x7E1F # 0 +0x0000E5D6 0x7E09 # 0 +0x0000E5D7 0x7E0B # 0 +0x0000E5D8 0x7E22 # 0 +0x0000E5D9 0x7E46 # 0 +0x0000E5DA 0x7E66 # 0 +0x0000E5DB 0x7E3B # 0 +0x0000E5DC 0x7E35 # 0 +0x0000E5DD 0x7E39 # 0 +0x0000E5DE 0x7E43 # 0 +0x0000E5DF 0x7E37 # 0 +0x0000E5E0 0x7E32 # 0 +0x0000E5E1 0x7E3A # 0 +0x0000E5E2 0x7E67 # 0 +0x0000E5E3 0x7E5D # 0 +0x0000E5E4 0x7E56 # 0 +0x0000E5E5 0x7E5E # 0 +0x0000E5E6 0x7E59 # 0 +0x0000E5E7 0x7E5A # 0 +0x0000E5E8 0x7E79 # 0 +0x0000E5E9 0x7E6A # 0 +0x0000E5EA 0x7E69 # 0 +0x0000E5EB 0x7E7C # 0 +0x0000E5EC 0x7E7B # 0 +0x0000E5ED 0x7E83 # 0 +0x0000E5EE 0x7DD5 # 0 +0x0000E5EF 0x7E7D # 0 +0x0000E5F0 0x8FAE # 0 +0x0000E5F1 0x7E7F # 0 +0x0000E5F2 0x7E88 # 0 +0x0000E5F3 0x7E89 # 0 +0x0000E5F4 0x7E8C # 0 +0x0000E5F5 0x7E92 # 0 +0x0000E5F6 0x7E90 # 0 +0x0000E5F7 0x7E93 # 0 +0x0000E5F8 0x7E94 # 0 +0x0000E5F9 0x7E96 # 0 +0x0000E5FA 0x7E8E # 0 +0x0000E5FB 0x7E9B # 0 +0x0000E5FC 0x7E9C # 0 +0x0000E5FD 0x7F38 # 0 +0x0000E5FE 0x7F3A # 0 +0x0000E6A1 0x7F45 # 0 +0x0000E6A2 0x7F4C # 0 +0x0000E6A3 0x7F4D # 0 +0x0000E6A4 0x7F4E # 0 +0x0000E6A5 0x7F50 # 0 +0x0000E6A6 0x7F51 # 0 +0x0000E6A7 0x7F55 # 0 +0x0000E6A8 0x7F54 # 0 +0x0000E6A9 0x7F58 # 0 +0x0000E6AA 0x7F5F # 0 +0x0000E6AB 0x7F60 # 0 +0x0000E6AC 0x7F68 # 0 +0x0000E6AD 0x7F69 # 0 +0x0000E6AE 0x7F67 # 0 +0x0000E6AF 0x7F78 # 0 +0x0000E6B0 0x7F82 # 0 +0x0000E6B1 0x7F86 # 0 +0x0000E6B2 0x7F83 # 0 +0x0000E6B3 0x7F88 # 0 +0x0000E6B4 0x7F87 # 0 +0x0000E6B5 0x7F8C # 0 +0x0000E6B6 0x7F94 # 0 +0x0000E6B7 0x7F9E # 0 +0x0000E6B8 0x7F9D # 0 +0x0000E6B9 0x7F9A # 0 +0x0000E6BA 0x7FA3 # 0 +0x0000E6BB 0x7FAF # 0 +0x0000E6BC 0x7FB2 # 0 +0x0000E6BD 0x7FB9 # 0 +0x0000E6BE 0x7FAE # 0 +0x0000E6BF 0x7FB6 # 0 +0x0000E6C0 0x7FB8 # 0 +0x0000E6C1 0x8B71 # 0 +0x0000E6C2 0x7FC5 # 0 +0x0000E6C3 0x7FC6 # 0 +0x0000E6C4 0x7FCA # 0 +0x0000E6C5 0x7FD5 # 0 +0x0000E6C6 0x7FD4 # 0 +0x0000E6C7 0x7FE1 # 0 +0x0000E6C8 0x7FE6 # 0 +0x0000E6C9 0x7FE9 # 0 +0x0000E6CA 0x7FF3 # 0 +0x0000E6CB 0x7FF9 # 0 +0x0000E6CC 0x98DC # 0 +0x0000E6CD 0x8006 # 0 +0x0000E6CE 0x8004 # 0 +0x0000E6CF 0x800B # 0 +0x0000E6D0 0x8012 # 0 +0x0000E6D1 0x8018 # 0 +0x0000E6D2 0x8019 # 0 +0x0000E6D3 0x801C # 0 +0x0000E6D4 0x8021 # 0 +0x0000E6D5 0x8028 # 0 +0x0000E6D6 0x803F # 0 +0x0000E6D7 0x803B # 0 +0x0000E6D8 0x804A # 0 +0x0000E6D9 0x8046 # 0 +0x0000E6DA 0x8052 # 0 +0x0000E6DB 0x8058 # 0 +0x0000E6DC 0x805A # 0 +0x0000E6DD 0x805F # 0 +0x0000E6DE 0x8062 # 0 +0x0000E6DF 0x8068 # 0 +0x0000E6E0 0x8073 # 0 +0x0000E6E1 0x8072 # 0 +0x0000E6E2 0x8070 # 0 +0x0000E6E3 0x8076 # 0 +0x0000E6E4 0x8079 # 0 +0x0000E6E5 0x807D # 0 +0x0000E6E6 0x807F # 0 +0x0000E6E7 0x8084 # 0 +0x0000E6E8 0x8086 # 0 +0x0000E6E9 0x8085 # 0 +0x0000E6EA 0x809B # 0 +0x0000E6EB 0x8093 # 0 +0x0000E6EC 0x809A # 0 +0x0000E6ED 0x80AD # 0 +0x0000E6EE 0x5190 # 0 +0x0000E6EF 0x80AC # 0 +0x0000E6F0 0x80DB # 0 +0x0000E6F1 0x80E5 # 0 +0x0000E6F2 0x80D9 # 0 +0x0000E6F3 0x80DD # 0 +0x0000E6F4 0x80C4 # 0 +0x0000E6F5 0x80DA # 0 +0x0000E6F6 0x80D6 # 0 +0x0000E6F7 0x8109 # 0 +0x0000E6F8 0x80EF # 0 +0x0000E6F9 0x80F1 # 0 +0x0000E6FA 0x811B # 0 +0x0000E6FB 0x8129 # 0 +0x0000E6FC 0x8123 # 0 +0x0000E6FD 0x812F # 0 +0x0000E6FE 0x814B # 0 +0x0000E7A1 0x968B # 0 +0x0000E7A2 0x8146 # 0 +0x0000E7A3 0x813E # 0 +0x0000E7A4 0x8153 # 0 +0x0000E7A5 0x8151 # 0 +0x0000E7A6 0x80FC # 0 +0x0000E7A7 0x8171 # 0 +0x0000E7A8 0x816E # 0 +0x0000E7A9 0x8165 # 0 +0x0000E7AA 0x8166 # 0 +0x0000E7AB 0x8174 # 0 +0x0000E7AC 0x8183 # 0 +0x0000E7AD 0x8188 # 0 +0x0000E7AE 0x818A # 0 +0x0000E7AF 0x8180 # 0 +0x0000E7B0 0x8182 # 0 +0x0000E7B1 0x81A0 # 0 +0x0000E7B2 0x8195 # 0 +0x0000E7B3 0x81A4 # 0 +0x0000E7B4 0x81A3 # 0 +0x0000E7B5 0x815F # 0 +0x0000E7B6 0x8193 # 0 +0x0000E7B7 0x81A9 # 0 +0x0000E7B8 0x81B0 # 0 +0x0000E7B9 0x81B5 # 0 +0x0000E7BA 0x81BE # 0 +0x0000E7BB 0x81B8 # 0 +0x0000E7BC 0x81BD # 0 +0x0000E7BD 0x81C0 # 0 +0x0000E7BE 0x81C2 # 0 +0x0000E7BF 0x81BA # 0 +0x0000E7C0 0x81C9 # 0 +0x0000E7C1 0x81CD # 0 +0x0000E7C2 0x81D1 # 0 +0x0000E7C3 0x81D9 # 0 +0x0000E7C4 0x81D8 # 0 +0x0000E7C5 0x81C8 # 0 +0x0000E7C6 0x81DA # 0 +0x0000E7C7 0x81DF # 0 +0x0000E7C8 0x81E0 # 0 +0x0000E7C9 0x81E7 # 0 +0x0000E7CA 0x81FA # 0 +0x0000E7CB 0x81FB # 0 +0x0000E7CC 0x81FE # 0 +0x0000E7CD 0x8201 # 0 +0x0000E7CE 0x8202 # 0 +0x0000E7CF 0x8205 # 0 +0x0000E7D0 0x8207 # 0 +0x0000E7D1 0x820A # 0 +0x0000E7D2 0x820D # 0 +0x0000E7D3 0x8210 # 0 +0x0000E7D4 0x8216 # 0 +0x0000E7D5 0x8229 # 0 +0x0000E7D6 0x822B # 0 +0x0000E7D7 0x8238 # 0 +0x0000E7D8 0x8233 # 0 +0x0000E7D9 0x8240 # 0 +0x0000E7DA 0x8259 # 0 +0x0000E7DB 0x8258 # 0 +0x0000E7DC 0x825D # 0 +0x0000E7DD 0x825A # 0 +0x0000E7DE 0x825F # 0 +0x0000E7DF 0x8264 # 0 +0x0000E7E0 0x8262 # 0 +0x0000E7E1 0x8268 # 0 +0x0000E7E2 0x826A # 0 +0x0000E7E3 0x826B # 0 +0x0000E7E4 0x822E # 0 +0x0000E7E5 0x8271 # 0 +0x0000E7E6 0x8277 # 0 +0x0000E7E7 0x8278 # 0 +0x0000E7E8 0x827E # 0 +0x0000E7E9 0x828D # 0 +0x0000E7EA 0x8292 # 0 +0x0000E7EB 0x82AB # 0 +0x0000E7EC 0x829F # 0 +0x0000E7ED 0x82BB # 0 +0x0000E7EE 0x82AC # 0 +0x0000E7EF 0x82E1 # 0 +0x0000E7F0 0x82E3 # 0 +0x0000E7F1 0x82DF # 0 +0x0000E7F2 0x82D2 # 0 +0x0000E7F3 0x82F4 # 0 +0x0000E7F4 0x82F3 # 0 +0x0000E7F5 0x82FA # 0 +0x0000E7F6 0x8393 # 0 +0x0000E7F7 0x8303 # 0 +0x0000E7F8 0x82FB # 0 +0x0000E7F9 0x82F9 # 0 +0x0000E7FA 0x82DE # 0 +0x0000E7FB 0x8306 # 0 +0x0000E7FC 0x82DC # 0 +0x0000E7FD 0x8309 # 0 +0x0000E7FE 0x82D9 # 0 +0x0000E8A1 0x8335 # 0 +0x0000E8A2 0x8334 # 0 +0x0000E8A3 0x8316 # 0 +0x0000E8A4 0x8332 # 0 +0x0000E8A5 0x8331 # 0 +0x0000E8A6 0x8340 # 0 +0x0000E8A7 0x8339 # 0 +0x0000E8A8 0x8350 # 0 +0x0000E8A9 0x8345 # 0 +0x0000E8AA 0x832F # 0 +0x0000E8AB 0x832B # 0 +0x0000E8AC 0x8317 # 0 +0x0000E8AD 0x8318 # 0 +0x0000E8AE 0x8385 # 0 +0x0000E8AF 0x839A # 0 +0x0000E8B0 0x83AA # 0 +0x0000E8B1 0x839F # 0 +0x0000E8B2 0x83A2 # 0 +0x0000E8B3 0x8396 # 0 +0x0000E8B4 0x8323 # 0 +0x0000E8B5 0x838E # 0 +0x0000E8B6 0x8387 # 0 +0x0000E8B7 0x838A # 0 +0x0000E8B8 0x837C # 0 +0x0000E8B9 0x83B5 # 0 +0x0000E8BA 0x8373 # 0 +0x0000E8BB 0x8375 # 0 +0x0000E8BC 0x83A0 # 0 +0x0000E8BD 0x8389 # 0 +0x0000E8BE 0x83A8 # 0 +0x0000E8BF 0x83F4 # 0 +0x0000E8C0 0x8413 # 0 +0x0000E8C1 0x83EB # 0 +0x0000E8C2 0x83CE # 0 +0x0000E8C3 0x83FD # 0 +0x0000E8C4 0x8403 # 0 +0x0000E8C5 0x83D8 # 0 +0x0000E8C6 0x840B # 0 +0x0000E8C7 0x83C1 # 0 +0x0000E8C8 0x83F7 # 0 +0x0000E8C9 0x8407 # 0 +0x0000E8CA 0x83E0 # 0 +0x0000E8CB 0x83F2 # 0 +0x0000E8CC 0x840D # 0 +0x0000E8CD 0x8422 # 0 +0x0000E8CE 0x8420 # 0 +0x0000E8CF 0x83BD # 0 +0x0000E8D0 0x8438 # 0 +0x0000E8D1 0x8506 # 0 +0x0000E8D2 0x83FB # 0 +0x0000E8D3 0x846D # 0 +0x0000E8D4 0x842A # 0 +0x0000E8D5 0x843C # 0 +0x0000E8D6 0x855A # 0 +0x0000E8D7 0x8484 # 0 +0x0000E8D8 0x8477 # 0 +0x0000E8D9 0x846B # 0 +0x0000E8DA 0x84AD # 0 +0x0000E8DB 0x846E # 0 +0x0000E8DC 0x8482 # 0 +0x0000E8DD 0x8469 # 0 +0x0000E8DE 0x8446 # 0 +0x0000E8DF 0x842C # 0 +0x0000E8E0 0x846F # 0 +0x0000E8E1 0x8479 # 0 +0x0000E8E2 0x8435 # 0 +0x0000E8E3 0x84CA # 0 +0x0000E8E4 0x8462 # 0 +0x0000E8E5 0x84B9 # 0 +0x0000E8E6 0x84BF # 0 +0x0000E8E7 0x849F # 0 +0x0000E8E8 0x84D9 # 0 +0x0000E8E9 0x84CD # 0 +0x0000E8EA 0x84BB # 0 +0x0000E8EB 0x84DA # 0 +0x0000E8EC 0x84D0 # 0 +0x0000E8ED 0x84C1 # 0 +0x0000E8EE 0x84C6 # 0 +0x0000E8EF 0x84D6 # 0 +0x0000E8F0 0x84A1 # 0 +0x0000E8F1 0x8521 # 0 +0x0000E8F2 0x84FF # 0 +0x0000E8F3 0x84F4 # 0 +0x0000E8F4 0x8517 # 0 +0x0000E8F5 0x8518 # 0 +0x0000E8F6 0x852C # 0 +0x0000E8F7 0x851F # 0 +0x0000E8F8 0x8515 # 0 +0x0000E8F9 0x8514 # 0 +0x0000E8FA 0x84FC # 0 +0x0000E8FB 0x8540 # 0 +0x0000E8FC 0x8563 # 0 +0x0000E8FD 0x8558 # 0 +0x0000E8FE 0x8548 # 0 +0x0000E9A1 0x8541 # 0 +0x0000E9A2 0x8602 # 0 +0x0000E9A3 0x854B # 0 +0x0000E9A4 0x8555 # 0 +0x0000E9A5 0x8580 # 0 +0x0000E9A6 0x85A4 # 0 +0x0000E9A7 0x8588 # 0 +0x0000E9A8 0x8591 # 0 +0x0000E9A9 0x858A # 0 +0x0000E9AA 0x85A8 # 0 +0x0000E9AB 0x856D # 0 +0x0000E9AC 0x8594 # 0 +0x0000E9AD 0x859B # 0 +0x0000E9AE 0x85EA # 0 +0x0000E9AF 0x8587 # 0 +0x0000E9B0 0x859C # 0 +0x0000E9B1 0x8577 # 0 +0x0000E9B2 0x857E # 0 +0x0000E9B3 0x8590 # 0 +0x0000E9B4 0x85C9 # 0 +0x0000E9B5 0x85BA # 0 +0x0000E9B6 0x85CF # 0 +0x0000E9B7 0x85B9 # 0 +0x0000E9B8 0x85D0 # 0 +0x0000E9B9 0x85D5 # 0 +0x0000E9BA 0x85DD # 0 +0x0000E9BB 0x85E5 # 0 +0x0000E9BC 0x85DC # 0 +0x0000E9BD 0x85F9 # 0 +0x0000E9BE 0x860A # 0 +0x0000E9BF 0x8613 # 0 +0x0000E9C0 0x860B # 0 +0x0000E9C1 0x85FE # 0 +0x0000E9C2 0x85FA # 0 +0x0000E9C3 0x8606 # 0 +0x0000E9C4 0x8622 # 0 +0x0000E9C5 0x861A # 0 +0x0000E9C6 0x8630 # 0 +0x0000E9C7 0x863F # 0 +0x0000E9C8 0x864D # 0 +0x0000E9C9 0x4E55 # 0 +0x0000E9CA 0x8654 # 0 +0x0000E9CB 0x865F # 0 +0x0000E9CC 0x8667 # 0 +0x0000E9CD 0x8671 # 0 +0x0000E9CE 0x8693 # 0 +0x0000E9CF 0x86A3 # 0 +0x0000E9D0 0x86A9 # 0 +0x0000E9D1 0x86AA # 0 +0x0000E9D2 0x868B # 0 +0x0000E9D3 0x868C # 0 +0x0000E9D4 0x86B6 # 0 +0x0000E9D5 0x86AF # 0 +0x0000E9D6 0x86C4 # 0 +0x0000E9D7 0x86C6 # 0 +0x0000E9D8 0x86B0 # 0 +0x0000E9D9 0x86C9 # 0 +0x0000E9DA 0x8823 # 0 +0x0000E9DB 0x86AB # 0 +0x0000E9DC 0x86D4 # 0 +0x0000E9DD 0x86DE # 0 +0x0000E9DE 0x86E9 # 0 +0x0000E9DF 0x86EC # 0 +0x0000E9E0 0x86DF # 0 +0x0000E9E1 0x86DB # 0 +0x0000E9E2 0x86EF # 0 +0x0000E9E3 0x8712 # 0 +0x0000E9E4 0x8706 # 0 +0x0000E9E5 0x8708 # 0 +0x0000E9E6 0x8700 # 0 +0x0000E9E7 0x8703 # 0 +0x0000E9E8 0x86FB # 0 +0x0000E9E9 0x8711 # 0 +0x0000E9EA 0x8709 # 0 +0x0000E9EB 0x870D # 0 +0x0000E9EC 0x86F9 # 0 +0x0000E9ED 0x870A # 0 +0x0000E9EE 0x8734 # 0 +0x0000E9EF 0x873F # 0 +0x0000E9F0 0x8737 # 0 +0x0000E9F1 0x873B # 0 +0x0000E9F2 0x8725 # 0 +0x0000E9F3 0x8729 # 0 +0x0000E9F4 0x871A # 0 +0x0000E9F5 0x8760 # 0 +0x0000E9F6 0x875F # 0 +0x0000E9F7 0x8778 # 0 +0x0000E9F8 0x874C # 0 +0x0000E9F9 0x874E # 0 +0x0000E9FA 0x8774 # 0 +0x0000E9FB 0x8757 # 0 +0x0000E9FC 0x8768 # 0 +0x0000E9FD 0x876E # 0 +0x0000E9FE 0x8759 # 0 +0x0000EAA1 0x8753 # 0 +0x0000EAA2 0x8763 # 0 +0x0000EAA3 0x876A # 0 +0x0000EAA4 0x8805 # 0 +0x0000EAA5 0x87A2 # 0 +0x0000EAA6 0x879F # 0 +0x0000EAA7 0x8782 # 0 +0x0000EAA8 0x87AF # 0 +0x0000EAA9 0x87CB # 0 +0x0000EAAA 0x87BD # 0 +0x0000EAAB 0x87C0 # 0 +0x0000EAAC 0x87D0 # 0 +0x0000EAAD 0x96D6 # 0 +0x0000EAAE 0x87AB # 0 +0x0000EAAF 0x87C4 # 0 +0x0000EAB0 0x87B3 # 0 +0x0000EAB1 0x87C7 # 0 +0x0000EAB2 0x87C6 # 0 +0x0000EAB3 0x87BB # 0 +0x0000EAB4 0x87EF # 0 +0x0000EAB5 0x87F2 # 0 +0x0000EAB6 0x87E0 # 0 +0x0000EAB7 0x880F # 0 +0x0000EAB8 0x880D # 0 +0x0000EAB9 0x87FE # 0 +0x0000EABA 0x87F6 # 0 +0x0000EABB 0x87F7 # 0 +0x0000EABC 0x880E # 0 +0x0000EABD 0x87D2 # 0 +0x0000EABE 0x8811 # 0 +0x0000EABF 0x8816 # 0 +0x0000EAC0 0x8815 # 0 +0x0000EAC1 0x8822 # 0 +0x0000EAC2 0x8821 # 0 +0x0000EAC3 0x8831 # 0 +0x0000EAC4 0x8836 # 0 +0x0000EAC5 0x8839 # 0 +0x0000EAC6 0x8827 # 0 +0x0000EAC7 0x883B # 0 +0x0000EAC8 0x8844 # 0 +0x0000EAC9 0x8842 # 0 +0x0000EACA 0x8852 # 0 +0x0000EACB 0x8859 # 0 +0x0000EACC 0x885E # 0 +0x0000EACD 0x8862 # 0 +0x0000EACE 0x886B # 0 +0x0000EACF 0x8881 # 0 +0x0000EAD0 0x887E # 0 +0x0000EAD1 0x889E # 0 +0x0000EAD2 0x8875 # 0 +0x0000EAD3 0x887D # 0 +0x0000EAD4 0x88B5 # 0 +0x0000EAD5 0x8872 # 0 +0x0000EAD6 0x8882 # 0 +0x0000EAD7 0x8897 # 0 +0x0000EAD8 0x8892 # 0 +0x0000EAD9 0x88AE # 0 +0x0000EADA 0x8899 # 0 +0x0000EADB 0x88A2 # 0 +0x0000EADC 0x888D # 0 +0x0000EADD 0x88A4 # 0 +0x0000EADE 0x88B0 # 0 +0x0000EADF 0x88BF # 0 +0x0000EAE0 0x88B1 # 0 +0x0000EAE1 0x88C3 # 0 +0x0000EAE2 0x88C4 # 0 +0x0000EAE3 0x88D4 # 0 +0x0000EAE4 0x88D8 # 0 +0x0000EAE5 0x88D9 # 0 +0x0000EAE6 0x88DD # 0 +0x0000EAE7 0x88F9 # 0 +0x0000EAE8 0x8902 # 0 +0x0000EAE9 0x88FC # 0 +0x0000EAEA 0x88F4 # 0 +0x0000EAEB 0x88E8 # 0 +0x0000EAEC 0x88F2 # 0 +0x0000EAED 0x8904 # 0 +0x0000EAEE 0x890C # 0 +0x0000EAEF 0x890A # 0 +0x0000EAF0 0x8913 # 0 +0x0000EAF1 0x8943 # 0 +0x0000EAF2 0x891E # 0 +0x0000EAF3 0x8925 # 0 +0x0000EAF4 0x892A # 0 +0x0000EAF5 0x892B # 0 +0x0000EAF6 0x8941 # 0 +0x0000EAF7 0x8944 # 0 +0x0000EAF8 0x893B # 0 +0x0000EAF9 0x8936 # 0 +0x0000EAFA 0x8938 # 0 +0x0000EAFB 0x894C # 0 +0x0000EAFC 0x891D # 0 +0x0000EAFD 0x8960 # 0 +0x0000EAFE 0x895E # 0 +0x0000EBA1 0x8966 # 0 +0x0000EBA2 0x8964 # 0 +0x0000EBA3 0x896D # 0 +0x0000EBA4 0x896A # 0 +0x0000EBA5 0x896F # 0 +0x0000EBA6 0x8974 # 0 +0x0000EBA7 0x8977 # 0 +0x0000EBA8 0x897E # 0 +0x0000EBA9 0x8983 # 0 +0x0000EBAA 0x8988 # 0 +0x0000EBAB 0x898A # 0 +0x0000EBAC 0x8993 # 0 +0x0000EBAD 0x8998 # 0 +0x0000EBAE 0x89A1 # 0 +0x0000EBAF 0x89A9 # 0 +0x0000EBB0 0x89A6 # 0 +0x0000EBB1 0x89AC # 0 +0x0000EBB2 0x89AF # 0 +0x0000EBB3 0x89B2 # 0 +0x0000EBB4 0x89BA # 0 +0x0000EBB5 0x89BD # 0 +0x0000EBB6 0x89BF # 0 +0x0000EBB7 0x89C0 # 0 +0x0000EBB8 0x89DA # 0 +0x0000EBB9 0x89DC # 0 +0x0000EBBA 0x89DD # 0 +0x0000EBBB 0x89E7 # 0 +0x0000EBBC 0x89F4 # 0 +0x0000EBBD 0x89F8 # 0 +0x0000EBBE 0x8A03 # 0 +0x0000EBBF 0x8A16 # 0 +0x0000EBC0 0x8A10 # 0 +0x0000EBC1 0x8A0C # 0 +0x0000EBC2 0x8A1B # 0 +0x0000EBC3 0x8A1D # 0 +0x0000EBC4 0x8A25 # 0 +0x0000EBC5 0x8A36 # 0 +0x0000EBC6 0x8A41 # 0 +0x0000EBC7 0x8A5B # 0 +0x0000EBC8 0x8A52 # 0 +0x0000EBC9 0x8A46 # 0 +0x0000EBCA 0x8A48 # 0 +0x0000EBCB 0x8A7C # 0 +0x0000EBCC 0x8A6D # 0 +0x0000EBCD 0x8A6C # 0 +0x0000EBCE 0x8A62 # 0 +0x0000EBCF 0x8A85 # 0 +0x0000EBD0 0x8A82 # 0 +0x0000EBD1 0x8A84 # 0 +0x0000EBD2 0x8AA8 # 0 +0x0000EBD3 0x8AA1 # 0 +0x0000EBD4 0x8A91 # 0 +0x0000EBD5 0x8AA5 # 0 +0x0000EBD6 0x8AA6 # 0 +0x0000EBD7 0x8A9A # 0 +0x0000EBD8 0x8AA3 # 0 +0x0000EBD9 0x8AC4 # 0 +0x0000EBDA 0x8ACD # 0 +0x0000EBDB 0x8AC2 # 0 +0x0000EBDC 0x8ADA # 0 +0x0000EBDD 0x8AEB # 0 +0x0000EBDE 0x8AF3 # 0 +0x0000EBDF 0x8AE7 # 0 +0x0000EBE0 0x8AE4 # 0 +0x0000EBE1 0x8AF1 # 0 +0x0000EBE2 0x8B14 # 0 +0x0000EBE3 0x8AE0 # 0 +0x0000EBE4 0x8AE2 # 0 +0x0000EBE5 0x8AF7 # 0 +0x0000EBE6 0x8ADE # 0 +0x0000EBE7 0x8ADB # 0 +0x0000EBE8 0x8B0C # 0 +0x0000EBE9 0x8B07 # 0 +0x0000EBEA 0x8B1A # 0 +0x0000EBEB 0x8AE1 # 0 +0x0000EBEC 0x8B16 # 0 +0x0000EBED 0x8B10 # 0 +0x0000EBEE 0x8B17 # 0 +0x0000EBEF 0x8B20 # 0 +0x0000EBF0 0x8B33 # 0 +0x0000EBF1 0x97AB # 0 +0x0000EBF2 0x8B26 # 0 +0x0000EBF3 0x8B2B # 0 +0x0000EBF4 0x8B3E # 0 +0x0000EBF5 0x8B28 # 0 +0x0000EBF6 0x8B41 # 0 +0x0000EBF7 0x8B4C # 0 +0x0000EBF8 0x8B4F # 0 +0x0000EBF9 0x8B4E # 0 +0x0000EBFA 0x8B49 # 0 +0x0000EBFB 0x8B56 # 0 +0x0000EBFC 0x8B5B # 0 +0x0000EBFD 0x8B5A # 0 +0x0000EBFE 0x8B6B # 0 +0x0000ECA1 0x8B5F # 0 +0x0000ECA2 0x8B6C # 0 +0x0000ECA3 0x8B6F # 0 +0x0000ECA4 0x8B74 # 0 +0x0000ECA5 0x8B7D # 0 +0x0000ECA6 0x8B80 # 0 +0x0000ECA7 0x8B8C # 0 +0x0000ECA8 0x8B8E # 0 +0x0000ECA9 0x8B92 # 0 +0x0000ECAA 0x8B93 # 0 +0x0000ECAB 0x8B96 # 0 +0x0000ECAC 0x8B99 # 0 +0x0000ECAD 0x8B9A # 0 +0x0000ECAE 0x8C3A # 0 +0x0000ECAF 0x8C41 # 0 +0x0000ECB0 0x8C3F # 0 +0x0000ECB1 0x8C48 # 0 +0x0000ECB2 0x8C4C # 0 +0x0000ECB3 0x8C4E # 0 +0x0000ECB4 0x8C50 # 0 +0x0000ECB5 0x8C55 # 0 +0x0000ECB6 0x8C62 # 0 +0x0000ECB7 0x8C6C # 0 +0x0000ECB8 0x8C78 # 0 +0x0000ECB9 0x8C7A # 0 +0x0000ECBA 0x8C82 # 0 +0x0000ECBB 0x8C89 # 0 +0x0000ECBC 0x8C85 # 0 +0x0000ECBD 0x8C8A # 0 +0x0000ECBE 0x8C8D # 0 +0x0000ECBF 0x8C8E # 0 +0x0000ECC0 0x8C94 # 0 +0x0000ECC1 0x8C7C # 0 +0x0000ECC2 0x8C98 # 0 +0x0000ECC3 0x621D # 0 +0x0000ECC4 0x8CAD # 0 +0x0000ECC5 0x8CAA # 0 +0x0000ECC6 0x8CBD # 0 +0x0000ECC7 0x8CB2 # 0 +0x0000ECC8 0x8CB3 # 0 +0x0000ECC9 0x8CAE # 0 +0x0000ECCA 0x8CB6 # 0 +0x0000ECCB 0x8CC8 # 0 +0x0000ECCC 0x8CC1 # 0 +0x0000ECCD 0x8CE4 # 0 +0x0000ECCE 0x8CE3 # 0 +0x0000ECCF 0x8CDA # 0 +0x0000ECD0 0x8CFD # 0 +0x0000ECD1 0x8CFA # 0 +0x0000ECD2 0x8CFB # 0 +0x0000ECD3 0x8D04 # 0 +0x0000ECD4 0x8D05 # 0 +0x0000ECD5 0x8D0A # 0 +0x0000ECD6 0x8D07 # 0 +0x0000ECD7 0x8D0F # 0 +0x0000ECD8 0x8D0D # 0 +0x0000ECD9 0x8D10 # 0 +0x0000ECDA 0x9F4E # 0 +0x0000ECDB 0x8D13 # 0 +0x0000ECDC 0x8CCD # 0 +0x0000ECDD 0x8D14 # 0 +0x0000ECDE 0x8D16 # 0 +0x0000ECDF 0x8D67 # 0 +0x0000ECE0 0x8D6D # 0 +0x0000ECE1 0x8D71 # 0 +0x0000ECE2 0x8D73 # 0 +0x0000ECE3 0x8D81 # 0 +0x0000ECE4 0x8D99 # 0 +0x0000ECE5 0x8DC2 # 0 +0x0000ECE6 0x8DBE # 0 +0x0000ECE7 0x8DBA # 0 +0x0000ECE8 0x8DCF # 0 +0x0000ECE9 0x8DDA # 0 +0x0000ECEA 0x8DD6 # 0 +0x0000ECEB 0x8DCC # 0 +0x0000ECEC 0x8DDB # 0 +0x0000ECED 0x8DCB # 0 +0x0000ECEE 0x8DEA # 0 +0x0000ECEF 0x8DEB # 0 +0x0000ECF0 0x8DDF # 0 +0x0000ECF1 0x8DE3 # 0 +0x0000ECF2 0x8DFC # 0 +0x0000ECF3 0x8E08 # 0 +0x0000ECF4 0x8E09 # 0 +0x0000ECF5 0x8DFF # 0 +0x0000ECF6 0x8E1D # 0 +0x0000ECF7 0x8E1E # 0 +0x0000ECF8 0x8E10 # 0 +0x0000ECF9 0x8E1F # 0 +0x0000ECFA 0x8E42 # 0 +0x0000ECFB 0x8E35 # 0 +0x0000ECFC 0x8E30 # 0 +0x0000ECFD 0x8E34 # 0 +0x0000ECFE 0x8E4A # 0 +0x0000EDA1 0x8E47 # 0 +0x0000EDA2 0x8E49 # 0 +0x0000EDA3 0x8E4C # 0 +0x0000EDA4 0x8E50 # 0 +0x0000EDA5 0x8E48 # 0 +0x0000EDA6 0x8E59 # 0 +0x0000EDA7 0x8E64 # 0 +0x0000EDA8 0x8E60 # 0 +0x0000EDA9 0x8E2A # 0 +0x0000EDAA 0x8E63 # 0 +0x0000EDAB 0x8E55 # 0 +0x0000EDAC 0x8E76 # 0 +0x0000EDAD 0x8E72 # 0 +0x0000EDAE 0x8E7C # 0 +0x0000EDAF 0x8E81 # 0 +0x0000EDB0 0x8E87 # 0 +0x0000EDB1 0x8E85 # 0 +0x0000EDB2 0x8E84 # 0 +0x0000EDB3 0x8E8B # 0 +0x0000EDB4 0x8E8A # 0 +0x0000EDB5 0x8E93 # 0 +0x0000EDB6 0x8E91 # 0 +0x0000EDB7 0x8E94 # 0 +0x0000EDB8 0x8E99 # 0 +0x0000EDB9 0x8EAA # 0 +0x0000EDBA 0x8EA1 # 0 +0x0000EDBB 0x8EAC # 0 +0x0000EDBC 0x8EB0 # 0 +0x0000EDBD 0x8EC6 # 0 +0x0000EDBE 0x8EB1 # 0 +0x0000EDBF 0x8EBE # 0 +0x0000EDC0 0x8EC5 # 0 +0x0000EDC1 0x8EC8 # 0 +0x0000EDC2 0x8ECB # 0 +0x0000EDC3 0x8EDB # 0 +0x0000EDC4 0x8EE3 # 0 +0x0000EDC5 0x8EFC # 0 +0x0000EDC6 0x8EFB # 0 +0x0000EDC7 0x8EEB # 0 +0x0000EDC8 0x8EFE # 0 +0x0000EDC9 0x8F0A # 0 +0x0000EDCA 0x8F05 # 0 +0x0000EDCB 0x8F15 # 0 +0x0000EDCC 0x8F12 # 0 +0x0000EDCD 0x8F19 # 0 +0x0000EDCE 0x8F13 # 0 +0x0000EDCF 0x8F1C # 0 +0x0000EDD0 0x8F1F # 0 +0x0000EDD1 0x8F1B # 0 +0x0000EDD2 0x8F0C # 0 +0x0000EDD3 0x8F26 # 0 +0x0000EDD4 0x8F33 # 0 +0x0000EDD5 0x8F3B # 0 +0x0000EDD6 0x8F39 # 0 +0x0000EDD7 0x8F45 # 0 +0x0000EDD8 0x8F42 # 0 +0x0000EDD9 0x8F3E # 0 +0x0000EDDA 0x8F4C # 0 +0x0000EDDB 0x8F49 # 0 +0x0000EDDC 0x8F46 # 0 +0x0000EDDD 0x8F4E # 0 +0x0000EDDE 0x8F57 # 0 +0x0000EDDF 0x8F5C # 0 +0x0000EDE0 0x8F62 # 0 +0x0000EDE1 0x8F63 # 0 +0x0000EDE2 0x8F64 # 0 +0x0000EDE3 0x8F9C # 0 +0x0000EDE4 0x8F9F # 0 +0x0000EDE5 0x8FA3 # 0 +0x0000EDE6 0x8FAD # 0 +0x0000EDE7 0x8FAF # 0 +0x0000EDE8 0x8FB7 # 0 +0x0000EDE9 0x8FDA # 0 +0x0000EDEA 0x8FE5 # 0 +0x0000EDEB 0x8FE2 # 0 +0x0000EDEC 0x8FEA # 0 +0x0000EDED 0x8FEF # 0 +0x0000EDEE 0x9087 # 0 +0x0000EDEF 0x8FF4 # 0 +0x0000EDF0 0x9005 # 0 +0x0000EDF1 0x8FF9 # 0 +0x0000EDF2 0x8FFA # 0 +0x0000EDF3 0x9011 # 0 +0x0000EDF4 0x9015 # 0 +0x0000EDF5 0x9021 # 0 +0x0000EDF6 0x900D # 0 +0x0000EDF7 0x901E # 0 +0x0000EDF8 0x9016 # 0 +0x0000EDF9 0x900B # 0 +0x0000EDFA 0x9027 # 0 +0x0000EDFB 0x9036 # 0 +0x0000EDFC 0x9035 # 0 +0x0000EDFD 0x9039 # 0 +0x0000EDFE 0x8FF8 # 0 +0x0000EEA1 0x904F # 0 +0x0000EEA2 0x9050 # 0 +0x0000EEA3 0x9051 # 0 +0x0000EEA4 0x9052 # 0 +0x0000EEA5 0x900E # 0 +0x0000EEA6 0x9049 # 0 +0x0000EEA7 0x903E # 0 +0x0000EEA8 0x9056 # 0 +0x0000EEA9 0x9058 # 0 +0x0000EEAA 0x905E # 0 +0x0000EEAB 0x9068 # 0 +0x0000EEAC 0x906F # 0 +0x0000EEAD 0x9076 # 0 +0x0000EEAE 0x96A8 # 0 +0x0000EEAF 0x9072 # 0 +0x0000EEB0 0x9082 # 0 +0x0000EEB1 0x907D # 0 +0x0000EEB2 0x9081 # 0 +0x0000EEB3 0x9080 # 0 +0x0000EEB4 0x908A # 0 +0x0000EEB5 0x9089 # 0 +0x0000EEB6 0x908F # 0 +0x0000EEB7 0x90A8 # 0 +0x0000EEB8 0x90AF # 0 +0x0000EEB9 0x90B1 # 0 +0x0000EEBA 0x90B5 # 0 +0x0000EEBB 0x90E2 # 0 +0x0000EEBC 0x90E4 # 0 +0x0000EEBD 0x6248 # 0 +0x0000EEBE 0x90DB # 0 +0x0000EEBF 0x9102 # 0 +0x0000EEC0 0x9112 # 0 +0x0000EEC1 0x9119 # 0 +0x0000EEC2 0x9132 # 0 +0x0000EEC3 0x9130 # 0 +0x0000EEC4 0x914A # 0 +0x0000EEC5 0x9156 # 0 +0x0000EEC6 0x9158 # 0 +0x0000EEC7 0x9163 # 0 +0x0000EEC8 0x9165 # 0 +0x0000EEC9 0x9169 # 0 +0x0000EECA 0x9173 # 0 +0x0000EECB 0x9172 # 0 +0x0000EECC 0x918B # 0 +0x0000EECD 0x9189 # 0 +0x0000EECE 0x9182 # 0 +0x0000EECF 0x91A2 # 0 +0x0000EED0 0x91AB # 0 +0x0000EED1 0x91AF # 0 +0x0000EED2 0x91AA # 0 +0x0000EED3 0x91B5 # 0 +0x0000EED4 0x91B4 # 0 +0x0000EED5 0x91BA # 0 +0x0000EED6 0x91C0 # 0 +0x0000EED7 0x91C1 # 0 +0x0000EED8 0x91C9 # 0 +0x0000EED9 0x91CB # 0 +0x0000EEDA 0x91D0 # 0 +0x0000EEDB 0x91D6 # 0 +0x0000EEDC 0x91DF # 0 +0x0000EEDD 0x91E1 # 0 +0x0000EEDE 0x91DB # 0 +0x0000EEDF 0x91FC # 0 +0x0000EEE0 0x91F5 # 0 +0x0000EEE1 0x91F6 # 0 +0x0000EEE2 0x921E # 0 +0x0000EEE3 0x91FF # 0 +0x0000EEE4 0x9214 # 0 +0x0000EEE5 0x922C # 0 +0x0000EEE6 0x9215 # 0 +0x0000EEE7 0x9211 # 0 +0x0000EEE8 0x925E # 0 +0x0000EEE9 0x9257 # 0 +0x0000EEEA 0x9245 # 0 +0x0000EEEB 0x9249 # 0 +0x0000EEEC 0x9264 # 0 +0x0000EEED 0x9248 # 0 +0x0000EEEE 0x9295 # 0 +0x0000EEEF 0x923F # 0 +0x0000EEF0 0x924B # 0 +0x0000EEF1 0x9250 # 0 +0x0000EEF2 0x929C # 0 +0x0000EEF3 0x9296 # 0 +0x0000EEF4 0x9293 # 0 +0x0000EEF5 0x929B # 0 +0x0000EEF6 0x925A # 0 +0x0000EEF7 0x92CF # 0 +0x0000EEF8 0x92B9 # 0 +0x0000EEF9 0x92B7 # 0 +0x0000EEFA 0x92E9 # 0 +0x0000EEFB 0x930F # 0 +0x0000EEFC 0x92FA # 0 +0x0000EEFD 0x9344 # 0 +0x0000EEFE 0x932E # 0 +0x0000EFA1 0x9319 # 0 +0x0000EFA2 0x9322 # 0 +0x0000EFA3 0x931A # 0 +0x0000EFA4 0x9323 # 0 +0x0000EFA5 0x933A # 0 +0x0000EFA6 0x9335 # 0 +0x0000EFA7 0x933B # 0 +0x0000EFA8 0x935C # 0 +0x0000EFA9 0x9360 # 0 +0x0000EFAA 0x937C # 0 +0x0000EFAB 0x936E # 0 +0x0000EFAC 0x9356 # 0 +0x0000EFAD 0x93B0 # 0 +0x0000EFAE 0x93AC # 0 +0x0000EFAF 0x93AD # 0 +0x0000EFB0 0x9394 # 0 +0x0000EFB1 0x93B9 # 0 +0x0000EFB2 0x93D6 # 0 +0x0000EFB3 0x93D7 # 0 +0x0000EFB4 0x93E8 # 0 +0x0000EFB5 0x93E5 # 0 +0x0000EFB6 0x93D8 # 0 +0x0000EFB7 0x93C3 # 0 +0x0000EFB8 0x93DD # 0 +0x0000EFB9 0x93D0 # 0 +0x0000EFBA 0x93C8 # 0 +0x0000EFBB 0x93E4 # 0 +0x0000EFBC 0x941A # 0 +0x0000EFBD 0x9414 # 0 +0x0000EFBE 0x9413 # 0 +0x0000EFBF 0x9403 # 0 +0x0000EFC0 0x9407 # 0 +0x0000EFC1 0x9410 # 0 +0x0000EFC2 0x9436 # 0 +0x0000EFC3 0x942B # 0 +0x0000EFC4 0x9435 # 0 +0x0000EFC5 0x9421 # 0 +0x0000EFC6 0x943A # 0 +0x0000EFC7 0x9441 # 0 +0x0000EFC8 0x9452 # 0 +0x0000EFC9 0x9444 # 0 +0x0000EFCA 0x945B # 0 +0x0000EFCB 0x9460 # 0 +0x0000EFCC 0x9462 # 0 +0x0000EFCD 0x945E # 0 +0x0000EFCE 0x946A # 0 +0x0000EFCF 0x9229 # 0 +0x0000EFD0 0x9470 # 0 +0x0000EFD1 0x9475 # 0 +0x0000EFD2 0x9477 # 0 +0x0000EFD3 0x947D # 0 +0x0000EFD4 0x945A # 0 +0x0000EFD5 0x947C # 0 +0x0000EFD6 0x947E # 0 +0x0000EFD7 0x9481 # 0 +0x0000EFD8 0x947F # 0 +0x0000EFD9 0x9582 # 0 +0x0000EFDA 0x9587 # 0 +0x0000EFDB 0x958A # 0 +0x0000EFDC 0x9594 # 0 +0x0000EFDD 0x9596 # 0 +0x0000EFDE 0x9598 # 0 +0x0000EFDF 0x9599 # 0 +0x0000EFE0 0x95A0 # 0 +0x0000EFE1 0x95A8 # 0 +0x0000EFE2 0x95A7 # 0 +0x0000EFE3 0x95AD # 0 +0x0000EFE4 0x95BC # 0 +0x0000EFE5 0x95BB # 0 +0x0000EFE6 0x95B9 # 0 +0x0000EFE7 0x95BE # 0 +0x0000EFE8 0x95CA # 0 +0x0000EFE9 0x6FF6 # 0 +0x0000EFEA 0x95C3 # 0 +0x0000EFEB 0x95CD # 0 +0x0000EFEC 0x95CC # 0 +0x0000EFED 0x95D5 # 0 +0x0000EFEE 0x95D4 # 0 +0x0000EFEF 0x95D6 # 0 +0x0000EFF0 0x95DC # 0 +0x0000EFF1 0x95E1 # 0 +0x0000EFF2 0x95E5 # 0 +0x0000EFF3 0x95E2 # 0 +0x0000EFF4 0x9621 # 0 +0x0000EFF5 0x9628 # 0 +0x0000EFF6 0x962E # 0 +0x0000EFF7 0x962F # 0 +0x0000EFF8 0x9642 # 0 +0x0000EFF9 0x964C # 0 +0x0000EFFA 0x964F # 0 +0x0000EFFB 0x964B # 0 +0x0000EFFC 0x9677 # 0 +0x0000EFFD 0x965C # 0 +0x0000EFFE 0x965E # 0 +0x0000F0A1 0x965D # 0 +0x0000F0A2 0x965F # 0 +0x0000F0A3 0x9666 # 0 +0x0000F0A4 0x9672 # 0 +0x0000F0A5 0x966C # 0 +0x0000F0A6 0x968D # 0 +0x0000F0A7 0x9698 # 0 +0x0000F0A8 0x9695 # 0 +0x0000F0A9 0x9697 # 0 +0x0000F0AA 0x96AA # 0 +0x0000F0AB 0x96A7 # 0 +0x0000F0AC 0x96B1 # 0 +0x0000F0AD 0x96B2 # 0 +0x0000F0AE 0x96B0 # 0 +0x0000F0AF 0x96B4 # 0 +0x0000F0B0 0x96B6 # 0 +0x0000F0B1 0x96B8 # 0 +0x0000F0B2 0x96B9 # 0 +0x0000F0B3 0x96CE # 0 +0x0000F0B4 0x96CB # 0 +0x0000F0B5 0x96C9 # 0 +0x0000F0B6 0x96CD # 0 +0x0000F0B7 0x894D # 0 +0x0000F0B8 0x96DC # 0 +0x0000F0B9 0x970D # 0 +0x0000F0BA 0x96D5 # 0 +0x0000F0BB 0x96F9 # 0 +0x0000F0BC 0x9704 # 0 +0x0000F0BD 0x9706 # 0 +0x0000F0BE 0x9708 # 0 +0x0000F0BF 0x9713 # 0 +0x0000F0C0 0x970E # 0 +0x0000F0C1 0x9711 # 0 +0x0000F0C2 0x970F # 0 +0x0000F0C3 0x9716 # 0 +0x0000F0C4 0x9719 # 0 +0x0000F0C5 0x9724 # 0 +0x0000F0C6 0x972A # 0 +0x0000F0C7 0x9730 # 0 +0x0000F0C8 0x9739 # 0 +0x0000F0C9 0x973D # 0 +0x0000F0CA 0x973E # 0 +0x0000F0CB 0x9744 # 0 +0x0000F0CC 0x9746 # 0 +0x0000F0CD 0x9748 # 0 +0x0000F0CE 0x9742 # 0 +0x0000F0CF 0x9749 # 0 +0x0000F0D0 0x975C # 0 +0x0000F0D1 0x9760 # 0 +0x0000F0D2 0x9764 # 0 +0x0000F0D3 0x9766 # 0 +0x0000F0D4 0x9768 # 0 +0x0000F0D5 0x52D2 # 0 +0x0000F0D6 0x976B # 0 +0x0000F0D7 0x9771 # 0 +0x0000F0D8 0x9779 # 0 +0x0000F0D9 0x9785 # 0 +0x0000F0DA 0x977C # 0 +0x0000F0DB 0x9781 # 0 +0x0000F0DC 0x977A # 0 +0x0000F0DD 0x9786 # 0 +0x0000F0DE 0x978B # 0 +0x0000F0DF 0x978F # 0 +0x0000F0E0 0x9790 # 0 +0x0000F0E1 0x979C # 0 +0x0000F0E2 0x97A8 # 0 +0x0000F0E3 0x97A6 # 0 +0x0000F0E4 0x97A3 # 0 +0x0000F0E5 0x97B3 # 0 +0x0000F0E6 0x97B4 # 0 +0x0000F0E7 0x97C3 # 0 +0x0000F0E8 0x97C6 # 0 +0x0000F0E9 0x97C8 # 0 +0x0000F0EA 0x97CB # 0 +0x0000F0EB 0x97DC # 0 +0x0000F0EC 0x97ED # 0 +0x0000F0ED 0x9F4F # 0 +0x0000F0EE 0x97F2 # 0 +0x0000F0EF 0x7ADF # 0 +0x0000F0F0 0x97F6 # 0 +0x0000F0F1 0x97F5 # 0 +0x0000F0F2 0x980F # 0 +0x0000F0F3 0x980C # 0 +0x0000F0F4 0x9838 # 0 +0x0000F0F5 0x9824 # 0 +0x0000F0F6 0x9821 # 0 +0x0000F0F7 0x9837 # 0 +0x0000F0F8 0x983D # 0 +0x0000F0F9 0x9846 # 0 +0x0000F0FA 0x984F # 0 +0x0000F0FB 0x984B # 0 +0x0000F0FC 0x986B # 0 +0x0000F0FD 0x986F # 0 +0x0000F0FE 0x9870 # 0 +0x0000F1A1 0x9871 # 0 +0x0000F1A2 0x9874 # 0 +0x0000F1A3 0x9873 # 0 +0x0000F1A4 0x98AA # 0 +0x0000F1A5 0x98AF # 0 +0x0000F1A6 0x98B1 # 0 +0x0000F1A7 0x98B6 # 0 +0x0000F1A8 0x98C4 # 0 +0x0000F1A9 0x98C3 # 0 +0x0000F1AA 0x98C6 # 0 +0x0000F1AB 0x98E9 # 0 +0x0000F1AC 0x98EB # 0 +0x0000F1AD 0x9903 # 0 +0x0000F1AE 0x9909 # 0 +0x0000F1AF 0x9912 # 0 +0x0000F1B0 0x9914 # 0 +0x0000F1B1 0x9918 # 0 +0x0000F1B2 0x9921 # 0 +0x0000F1B3 0x991D # 0 +0x0000F1B4 0x991E # 0 +0x0000F1B5 0x9924 # 0 +0x0000F1B6 0x9920 # 0 +0x0000F1B7 0x992C # 0 +0x0000F1B8 0x992E # 0 +0x0000F1B9 0x993D # 0 +0x0000F1BA 0x993E # 0 +0x0000F1BB 0x9942 # 0 +0x0000F1BC 0x9949 # 0 +0x0000F1BD 0x9945 # 0 +0x0000F1BE 0x9950 # 0 +0x0000F1BF 0x994B # 0 +0x0000F1C0 0x9951 # 0 +0x0000F1C1 0x9952 # 0 +0x0000F1C2 0x994C # 0 +0x0000F1C3 0x9955 # 0 +0x0000F1C4 0x9997 # 0 +0x0000F1C5 0x9998 # 0 +0x0000F1C6 0x99A5 # 0 +0x0000F1C7 0x99AD # 0 +0x0000F1C8 0x99AE # 0 +0x0000F1C9 0x99BC # 0 +0x0000F1CA 0x99DF # 0 +0x0000F1CB 0x99DB # 0 +0x0000F1CC 0x99DD # 0 +0x0000F1CD 0x99D8 # 0 +0x0000F1CE 0x99D1 # 0 +0x0000F1CF 0x99ED # 0 +0x0000F1D0 0x99EE # 0 +0x0000F1D1 0x99F1 # 0 +0x0000F1D2 0x99F2 # 0 +0x0000F1D3 0x99FB # 0 +0x0000F1D4 0x99F8 # 0 +0x0000F1D5 0x9A01 # 0 +0x0000F1D6 0x9A0F # 0 +0x0000F1D7 0x9A05 # 0 +0x0000F1D8 0x99E2 # 0 +0x0000F1D9 0x9A19 # 0 +0x0000F1DA 0x9A2B # 0 +0x0000F1DB 0x9A37 # 0 +0x0000F1DC 0x9A45 # 0 +0x0000F1DD 0x9A42 # 0 +0x0000F1DE 0x9A40 # 0 +0x0000F1DF 0x9A43 # 0 +0x0000F1E0 0x9A3E # 0 +0x0000F1E1 0x9A55 # 0 +0x0000F1E2 0x9A4D # 0 +0x0000F1E3 0x9A5B # 0 +0x0000F1E4 0x9A57 # 0 +0x0000F1E5 0x9A5F # 0 +0x0000F1E6 0x9A62 # 0 +0x0000F1E7 0x9A65 # 0 +0x0000F1E8 0x9A64 # 0 +0x0000F1E9 0x9A69 # 0 +0x0000F1EA 0x9A6B # 0 +0x0000F1EB 0x9A6A # 0 +0x0000F1EC 0x9AAD # 0 +0x0000F1ED 0x9AB0 # 0 +0x0000F1EE 0x9ABC # 0 +0x0000F1EF 0x9AC0 # 0 +0x0000F1F0 0x9ACF # 0 +0x0000F1F1 0x9AD1 # 0 +0x0000F1F2 0x9AD3 # 0 +0x0000F1F3 0x9AD4 # 0 +0x0000F1F4 0x9ADE # 0 +0x0000F1F5 0x9ADF # 0 +0x0000F1F6 0x9AE2 # 0 +0x0000F1F7 0x9AE3 # 0 +0x0000F1F8 0x9AE6 # 0 +0x0000F1F9 0x9AEF # 0 +0x0000F1FA 0x9AEB # 0 +0x0000F1FB 0x9AEE # 0 +0x0000F1FC 0x9AF4 # 0 +0x0000F1FD 0x9AF1 # 0 +0x0000F1FE 0x9AF7 # 0 +0x0000F2A1 0x9AFB # 0 +0x0000F2A2 0x9B06 # 0 +0x0000F2A3 0x9B18 # 0 +0x0000F2A4 0x9B1A # 0 +0x0000F2A5 0x9B1F # 0 +0x0000F2A6 0x9B22 # 0 +0x0000F2A7 0x9B23 # 0 +0x0000F2A8 0x9B25 # 0 +0x0000F2A9 0x9B27 # 0 +0x0000F2AA 0x9B28 # 0 +0x0000F2AB 0x9B29 # 0 +0x0000F2AC 0x9B2A # 0 +0x0000F2AD 0x9B2E # 0 +0x0000F2AE 0x9B2F # 0 +0x0000F2AF 0x9B32 # 0 +0x0000F2B0 0x9B44 # 0 +0x0000F2B1 0x9B43 # 0 +0x0000F2B2 0x9B4F # 0 +0x0000F2B3 0x9B4D # 0 +0x0000F2B4 0x9B4E # 0 +0x0000F2B5 0x9B51 # 0 +0x0000F2B6 0x9B58 # 0 +0x0000F2B7 0x9B74 # 0 +0x0000F2B8 0x9B93 # 0 +0x0000F2B9 0x9B83 # 0 +0x0000F2BA 0x9B91 # 0 +0x0000F2BB 0x9B96 # 0 +0x0000F2BC 0x9B97 # 0 +0x0000F2BD 0x9B9F # 0 +0x0000F2BE 0x9BA0 # 0 +0x0000F2BF 0x9BA8 # 0 +0x0000F2C0 0x9BB4 # 0 +0x0000F2C1 0x9BC0 # 0 +0x0000F2C2 0x9BCA # 0 +0x0000F2C3 0x9BB9 # 0 +0x0000F2C4 0x9BC6 # 0 +0x0000F2C5 0x9BCF # 0 +0x0000F2C6 0x9BD1 # 0 +0x0000F2C7 0x9BD2 # 0 +0x0000F2C8 0x9BE3 # 0 +0x0000F2C9 0x9BE2 # 0 +0x0000F2CA 0x9BE4 # 0 +0x0000F2CB 0x9BD4 # 0 +0x0000F2CC 0x9BE1 # 0 +0x0000F2CD 0x9C3A # 0 +0x0000F2CE 0x9BF2 # 0 +0x0000F2CF 0x9BF1 # 0 +0x0000F2D0 0x9BF0 # 0 +0x0000F2D1 0x9C15 # 0 +0x0000F2D2 0x9C14 # 0 +0x0000F2D3 0x9C09 # 0 +0x0000F2D4 0x9C13 # 0 +0x0000F2D5 0x9C0C # 0 +0x0000F2D6 0x9C06 # 0 +0x0000F2D7 0x9C08 # 0 +0x0000F2D8 0x9C12 # 0 +0x0000F2D9 0x9C0A # 0 +0x0000F2DA 0x9C04 # 0 +0x0000F2DB 0x9C2E # 0 +0x0000F2DC 0x9C1B # 0 +0x0000F2DD 0x9C25 # 0 +0x0000F2DE 0x9C24 # 0 +0x0000F2DF 0x9C21 # 0 +0x0000F2E0 0x9C30 # 0 +0x0000F2E1 0x9C47 # 0 +0x0000F2E2 0x9C32 # 0 +0x0000F2E3 0x9C46 # 0 +0x0000F2E4 0x9C3E # 0 +0x0000F2E5 0x9C5A # 0 +0x0000F2E6 0x9C60 # 0 +0x0000F2E7 0x9C67 # 0 +0x0000F2E8 0x9C76 # 0 +0x0000F2E9 0x9C78 # 0 +0x0000F2EA 0x9CE7 # 0 +0x0000F2EB 0x9CEC # 0 +0x0000F2EC 0x9CF0 # 0 +0x0000F2ED 0x9D09 # 0 +0x0000F2EE 0x9D08 # 0 +0x0000F2EF 0x9CEB # 0 +0x0000F2F0 0x9D03 # 0 +0x0000F2F1 0x9D06 # 0 +0x0000F2F2 0x9D2A # 0 +0x0000F2F3 0x9D26 # 0 +0x0000F2F4 0x9DAF # 0 +0x0000F2F5 0x9D23 # 0 +0x0000F2F6 0x9D1F # 0 +0x0000F2F7 0x9D44 # 0 +0x0000F2F8 0x9D15 # 0 +0x0000F2F9 0x9D12 # 0 +0x0000F2FA 0x9D41 # 0 +0x0000F2FB 0x9D3F # 0 +0x0000F2FC 0x9D3E # 0 +0x0000F2FD 0x9D46 # 0 +0x0000F2FE 0x9D48 # 0 +0x0000F3A1 0x9D5D # 0 +0x0000F3A2 0x9D5E # 0 +0x0000F3A3 0x9D64 # 0 +0x0000F3A4 0x9D51 # 0 +0x0000F3A5 0x9D50 # 0 +0x0000F3A6 0x9D59 # 0 +0x0000F3A7 0x9D72 # 0 +0x0000F3A8 0x9D89 # 0 +0x0000F3A9 0x9D87 # 0 +0x0000F3AA 0x9DAB # 0 +0x0000F3AB 0x9D6F # 0 +0x0000F3AC 0x9D7A # 0 +0x0000F3AD 0x9D9A # 0 +0x0000F3AE 0x9DA4 # 0 +0x0000F3AF 0x9DA9 # 0 +0x0000F3B0 0x9DB2 # 0 +0x0000F3B1 0x9DC4 # 0 +0x0000F3B2 0x9DC1 # 0 +0x0000F3B3 0x9DBB # 0 +0x0000F3B4 0x9DB8 # 0 +0x0000F3B5 0x9DBA # 0 +0x0000F3B6 0x9DC6 # 0 +0x0000F3B7 0x9DCF # 0 +0x0000F3B8 0x9DC2 # 0 +0x0000F3B9 0x9DD9 # 0 +0x0000F3BA 0x9DD3 # 0 +0x0000F3BB 0x9DF8 # 0 +0x0000F3BC 0x9DE6 # 0 +0x0000F3BD 0x9DED # 0 +0x0000F3BE 0x9DEF # 0 +0x0000F3BF 0x9DFD # 0 +0x0000F3C0 0x9E1A # 0 +0x0000F3C1 0x9E1B # 0 +0x0000F3C2 0x9E1E # 0 +0x0000F3C3 0x9E75 # 0 +0x0000F3C4 0x9E79 # 0 +0x0000F3C5 0x9E7D # 0 +0x0000F3C6 0x9E81 # 0 +0x0000F3C7 0x9E88 # 0 +0x0000F3C8 0x9E8B # 0 +0x0000F3C9 0x9E8C # 0 +0x0000F3CA 0x9E92 # 0 +0x0000F3CB 0x9E95 # 0 +0x0000F3CC 0x9E91 # 0 +0x0000F3CD 0x9E9D # 0 +0x0000F3CE 0x9EA5 # 0 +0x0000F3CF 0x9EA9 # 0 +0x0000F3D0 0x9EB8 # 0 +0x0000F3D1 0x9EAA # 0 +0x0000F3D2 0x9EAD # 0 +0x0000F3D3 0x9761 # 0 +0x0000F3D4 0x9ECC # 0 +0x0000F3D5 0x9ECE # 0 +0x0000F3D6 0x9ECF # 0 +0x0000F3D7 0x9ED0 # 0 +0x0000F3D8 0x9ED4 # 0 +0x0000F3D9 0x9EDC # 0 +0x0000F3DA 0x9EDE # 0 +0x0000F3DB 0x9EDD # 0 +0x0000F3DC 0x9EE0 # 0 +0x0000F3DD 0x9EE5 # 0 +0x0000F3DE 0x9EE8 # 0 +0x0000F3DF 0x9EEF # 0 +0x0000F3E0 0x9EF4 # 0 +0x0000F3E1 0x9EF6 # 0 +0x0000F3E2 0x9EF7 # 0 +0x0000F3E3 0x9EF9 # 0 +0x0000F3E4 0x9EFB # 0 +0x0000F3E5 0x9EFC # 0 +0x0000F3E6 0x9EFD # 0 +0x0000F3E7 0x9F07 # 0 +0x0000F3E8 0x9F08 # 0 +0x0000F3E9 0x76B7 # 0 +0x0000F3EA 0x9F15 # 0 +0x0000F3EB 0x9F21 # 0 +0x0000F3EC 0x9F2C # 0 +0x0000F3ED 0x9F3E # 0 +0x0000F3EE 0x9F4A # 0 +0x0000F3EF 0x9F52 # 0 +0x0000F3F0 0x9F54 # 0 +0x0000F3F1 0x9F63 # 0 +0x0000F3F2 0x9F5F # 0 +0x0000F3F3 0x9F60 # 0 +0x0000F3F4 0x9F61 # 0 +0x0000F3F5 0x9F66 # 0 +0x0000F3F6 0x9F67 # 0 +0x0000F3F7 0x9F6C # 0 +0x0000F3F8 0x9F6A # 0 +0x0000F3F9 0x9F77 # 0 +0x0000F3FA 0x9F72 # 0 +0x0000F3FB 0x9F76 # 0 +0x0000F3FC 0x9F95 # 0 +0x0000F3FD 0x9F9C # 0 +0x0000F3FE 0x9FA0 # 0 +0x0000F4A1 0x582F # 0 +0x0000F4A2 0x69C7 # 0 +0x0000F4A3 0x9059 # 0 +0x0000F4A4 0x7464 # 0 +0x0000F4A5 0x51DC # 0 +0x0000F4A6 0x7199 # 0 +0x0000F5A1 0xE000 # 0 +0x0000F5A2 0xE001 # 0 +0x0000F5A3 0xE002 # 0 +0x0000F5A4 0xE003 # 0 +0x0000F5A5 0xE004 # 0 +0x0000F5A6 0xE005 # 0 +0x0000F5A7 0xE006 # 0 +0x0000F5A8 0xE007 # 0 +0x0000F5A9 0xE008 # 0 +0x0000F5AA 0xE009 # 0 +0x0000F5AB 0xE00A # 0 +0x0000F5AC 0xE00B # 0 +0x0000F5AD 0xE00C # 0 +0x0000F5AE 0xE00D # 0 +0x0000F5AF 0xE00E # 0 +0x0000F5B0 0xE00F # 0 +0x0000F5B1 0xE010 # 0 +0x0000F5B2 0xE011 # 0 +0x0000F5B3 0xE012 # 0 +0x0000F5B4 0xE013 # 0 +0x0000F5B5 0xE014 # 0 +0x0000F5B6 0xE015 # 0 +0x0000F5B7 0xE016 # 0 +0x0000F5B8 0xE017 # 0 +0x0000F5B9 0xE018 # 0 +0x0000F5BA 0xE019 # 0 +0x0000F5BB 0xE01A # 0 +0x0000F5BC 0xE01B # 0 +0x0000F5BD 0xE01C # 0 +0x0000F5BE 0xE01D # 0 +0x0000F5BF 0xE01E # 0 +0x0000F5C0 0xE01F # 0 +0x0000F5C1 0xE020 # 0 +0x0000F5C2 0xE021 # 0 +0x0000F5C3 0xE022 # 0 +0x0000F5C4 0xE023 # 0 +0x0000F5C5 0xE024 # 0 +0x0000F5C6 0xE025 # 0 +0x0000F5C7 0xE026 # 0 +0x0000F5C8 0xE027 # 0 +0x0000F5C9 0xE028 # 0 +0x0000F5CA 0xE029 # 0 +0x0000F5CB 0xE02A # 0 +0x0000F5CC 0xE02B # 0 +0x0000F5CD 0xE02C # 0 +0x0000F5CE 0xE02D # 0 +0x0000F5CF 0xE02E # 0 +0x0000F5D0 0xE02F # 0 +0x0000F5D1 0xE030 # 0 +0x0000F5D2 0xE031 # 0 +0x0000F5D3 0xE032 # 0 +0x0000F5D4 0xE033 # 0 +0x0000F5D5 0xE034 # 0 +0x0000F5D6 0xE035 # 0 +0x0000F5D7 0xE036 # 0 +0x0000F5D8 0xE037 # 0 +0x0000F5D9 0xE038 # 0 +0x0000F5DA 0xE039 # 0 +0x0000F5DB 0xE03A # 0 +0x0000F5DC 0xE03B # 0 +0x0000F5DD 0xE03C # 0 +0x0000F5DE 0xE03D # 0 +0x0000F5DF 0xE03E # 0 +0x0000F5E0 0xE03F # 0 +0x0000F5E1 0xE040 # 0 +0x0000F5E2 0xE041 # 0 +0x0000F5E3 0xE042 # 0 +0x0000F5E4 0xE043 # 0 +0x0000F5E5 0xE044 # 0 +0x0000F5E6 0xE045 # 0 +0x0000F5E7 0xE046 # 0 +0x0000F5E8 0xE047 # 0 +0x0000F5E9 0xE048 # 0 +0x0000F5EA 0xE049 # 0 +0x0000F5EB 0xE04A # 0 +0x0000F5EC 0xE04B # 0 +0x0000F5ED 0xE04C # 0 +0x0000F5EE 0xE04D # 0 +0x0000F5EF 0xE04E # 0 +0x0000F5F0 0xE04F # 0 +0x0000F5F1 0xE050 # 0 +0x0000F5F2 0xE051 # 0 +0x0000F5F3 0xE052 # 0 +0x0000F5F4 0xE053 # 0 +0x0000F5F5 0xE054 # 0 +0x0000F5F6 0xE055 # 0 +0x0000F5F7 0xE056 # 0 +0x0000F5F8 0xE057 # 0 +0x0000F5F9 0xE058 # 0 +0x0000F5FA 0xE059 # 0 +0x0000F5FB 0xE05A # 0 +0x0000F5FC 0xE05B # 0 +0x0000F5FD 0xE05C # 0 +0x0000F5FE 0xE05D # 0 +0x0000F6A1 0xE05E # 0 +0x0000F6A2 0xE05F # 0 +0x0000F6A3 0xE060 # 0 +0x0000F6A4 0xE061 # 0 +0x0000F6A5 0xE062 # 0 +0x0000F6A6 0xE063 # 0 +0x0000F6A7 0xE064 # 0 +0x0000F6A8 0xE065 # 0 +0x0000F6A9 0xE066 # 0 +0x0000F6AA 0xE067 # 0 +0x0000F6AB 0xE068 # 0 +0x0000F6AC 0xE069 # 0 +0x0000F6AD 0xE06A # 0 +0x0000F6AE 0xE06B # 0 +0x0000F6AF 0xE06C # 0 +0x0000F6B0 0xE06D # 0 +0x0000F6B1 0xE06E # 0 +0x0000F6B2 0xE06F # 0 +0x0000F6B3 0xE070 # 0 +0x0000F6B4 0xE071 # 0 +0x0000F6B5 0xE072 # 0 +0x0000F6B6 0xE073 # 0 +0x0000F6B7 0xE074 # 0 +0x0000F6B8 0xE075 # 0 +0x0000F6B9 0xE076 # 0 +0x0000F6BA 0xE077 # 0 +0x0000F6BB 0xE078 # 0 +0x0000F6BC 0xE079 # 0 +0x0000F6BD 0xE07A # 0 +0x0000F6BE 0xE07B # 0 +0x0000F6BF 0xE07C # 0 +0x0000F6C0 0xE07D # 0 +0x0000F6C1 0xE07E # 0 +0x0000F6C2 0xE07F # 0 +0x0000F6C3 0xE080 # 0 +0x0000F6C4 0xE081 # 0 +0x0000F6C5 0xE082 # 0 +0x0000F6C6 0xE083 # 0 +0x0000F6C7 0xE084 # 0 +0x0000F6C8 0xE085 # 0 +0x0000F6C9 0xE086 # 0 +0x0000F6CA 0xE087 # 0 +0x0000F6CB 0xE088 # 0 +0x0000F6CC 0xE089 # 0 +0x0000F6CD 0xE08A # 0 +0x0000F6CE 0xE08B # 0 +0x0000F6CF 0xE08C # 0 +0x0000F6D0 0xE08D # 0 +0x0000F6D1 0xE08E # 0 +0x0000F6D2 0xE08F # 0 +0x0000F6D3 0xE090 # 0 +0x0000F6D4 0xE091 # 0 +0x0000F6D5 0xE092 # 0 +0x0000F6D6 0xE093 # 0 +0x0000F6D7 0xE094 # 0 +0x0000F6D8 0xE095 # 0 +0x0000F6D9 0xE096 # 0 +0x0000F6DA 0xE097 # 0 +0x0000F6DB 0xE098 # 0 +0x0000F6DC 0xE099 # 0 +0x0000F6DD 0xE09A # 0 +0x0000F6DE 0xE09B # 0 +0x0000F6DF 0xE09C # 0 +0x0000F6E0 0xE09D # 0 +0x0000F6E1 0xE09E # 0 +0x0000F6E2 0xE09F # 0 +0x0000F6E3 0xE0A0 # 0 +0x0000F6E4 0xE0A1 # 0 +0x0000F6E5 0xE0A2 # 0 +0x0000F6E6 0xE0A3 # 0 +0x0000F6E7 0xE0A4 # 0 +0x0000F6E8 0xE0A5 # 0 +0x0000F6E9 0xE0A6 # 0 +0x0000F6EA 0xE0A7 # 0 +0x0000F6EB 0xE0A8 # 0 +0x0000F6EC 0xE0A9 # 0 +0x0000F6ED 0xE0AA # 0 +0x0000F6EE 0xE0AB # 0 +0x0000F6EF 0xE0AC # 0 +0x0000F6F0 0xE0AD # 0 +0x0000F6F1 0xE0AE # 0 +0x0000F6F2 0xE0AF # 0 +0x0000F6F3 0xE0B0 # 0 +0x0000F6F4 0xE0B1 # 0 +0x0000F6F5 0xE0B2 # 0 +0x0000F6F6 0xE0B3 # 0 +0x0000F6F7 0xE0B4 # 0 +0x0000F6F8 0xE0B5 # 0 +0x0000F6F9 0xE0B6 # 0 +0x0000F6FA 0xE0B7 # 0 +0x0000F6FB 0xE0B8 # 0 +0x0000F6FC 0xE0B9 # 0 +0x0000F6FD 0xE0BA # 0 +0x0000F6FE 0xE0BB # 0 +0x0000F7A1 0xE0BC # 0 +0x0000F7A2 0xE0BD # 0 +0x0000F7A3 0xE0BE # 0 +0x0000F7A4 0xE0BF # 0 +0x0000F7A5 0xE0C0 # 0 +0x0000F7A6 0xE0C1 # 0 +0x0000F7A7 0xE0C2 # 0 +0x0000F7A8 0xE0C3 # 0 +0x0000F7A9 0xE0C4 # 0 +0x0000F7AA 0xE0C5 # 0 +0x0000F7AB 0xE0C6 # 0 +0x0000F7AC 0xE0C7 # 0 +0x0000F7AD 0xE0C8 # 0 +0x0000F7AE 0xE0C9 # 0 +0x0000F7AF 0xE0CA # 0 +0x0000F7B0 0xE0CB # 0 +0x0000F7B1 0xE0CC # 0 +0x0000F7B2 0xE0CD # 0 +0x0000F7B3 0xE0CE # 0 +0x0000F7B4 0xE0CF # 0 +0x0000F7B5 0xE0D0 # 0 +0x0000F7B6 0xE0D1 # 0 +0x0000F7B7 0xE0D2 # 0 +0x0000F7B8 0xE0D3 # 0 +0x0000F7B9 0xE0D4 # 0 +0x0000F7BA 0xE0D5 # 0 +0x0000F7BB 0xE0D6 # 0 +0x0000F7BC 0xE0D7 # 0 +0x0000F7BD 0xE0D8 # 0 +0x0000F7BE 0xE0D9 # 0 +0x0000F7BF 0xE0DA # 0 +0x0000F7C0 0xE0DB # 0 +0x0000F7C1 0xE0DC # 0 +0x0000F7C2 0xE0DD # 0 +0x0000F7C3 0xE0DE # 0 +0x0000F7C4 0xE0DF # 0 +0x0000F7C5 0xE0E0 # 0 +0x0000F7C6 0xE0E1 # 0 +0x0000F7C7 0xE0E2 # 0 +0x0000F7C8 0xE0E3 # 0 +0x0000F7C9 0xE0E4 # 0 +0x0000F7CA 0xE0E5 # 0 +0x0000F7CB 0xE0E6 # 0 +0x0000F7CC 0xE0E7 # 0 +0x0000F7CD 0xE0E8 # 0 +0x0000F7CE 0xE0E9 # 0 +0x0000F7CF 0xE0EA # 0 +0x0000F7D0 0xE0EB # 0 +0x0000F7D1 0xE0EC # 0 +0x0000F7D2 0xE0ED # 0 +0x0000F7D3 0xE0EE # 0 +0x0000F7D4 0xE0EF # 0 +0x0000F7D5 0xE0F0 # 0 +0x0000F7D6 0xE0F1 # 0 +0x0000F7D7 0xE0F2 # 0 +0x0000F7D8 0xE0F3 # 0 +0x0000F7D9 0xE0F4 # 0 +0x0000F7DA 0xE0F5 # 0 +0x0000F7DB 0xE0F6 # 0 +0x0000F7DC 0xE0F7 # 0 +0x0000F7DD 0xE0F8 # 0 +0x0000F7DE 0xE0F9 # 0 +0x0000F7DF 0xE0FA # 0 +0x0000F7E0 0xE0FB # 0 +0x0000F7E1 0xE0FC # 0 +0x0000F7E2 0xE0FD # 0 +0x0000F7E3 0xE0FE # 0 +0x0000F7E4 0xE0FF # 0 +0x0000F7E5 0xE100 # 0 +0x0000F7E6 0xE101 # 0 +0x0000F7E7 0xE102 # 0 +0x0000F7E8 0xE103 # 0 +0x0000F7E9 0xE104 # 0 +0x0000F7EA 0xE105 # 0 +0x0000F7EB 0xE106 # 0 +0x0000F7EC 0xE107 # 0 +0x0000F7ED 0xE108 # 0 +0x0000F7EE 0xE109 # 0 +0x0000F7EF 0xE10A # 0 +0x0000F7F0 0xE10B # 0 +0x0000F7F1 0xE10C # 0 +0x0000F7F2 0xE10D # 0 +0x0000F7F3 0xE10E # 0 +0x0000F7F4 0xE10F # 0 +0x0000F7F5 0xE110 # 0 +0x0000F7F6 0xE111 # 0 +0x0000F7F7 0xE112 # 0 +0x0000F7F8 0xE113 # 0 +0x0000F7F9 0xE114 # 0 +0x0000F7FA 0xE115 # 0 +0x0000F7FB 0xE116 # 0 +0x0000F7FC 0xE117 # 0 +0x0000F7FD 0xE118 # 0 +0x0000F7FE 0xE119 # 0 +0x0000F8A1 0xE11A # 0 +0x0000F8A2 0xE11B # 0 +0x0000F8A3 0xE11C # 0 +0x0000F8A4 0xE11D # 0 +0x0000F8A5 0xE11E # 0 +0x0000F8A6 0xE11F # 0 +0x0000F8A7 0xE120 # 0 +0x0000F8A8 0xE121 # 0 +0x0000F8A9 0xE122 # 0 +0x0000F8AA 0xE123 # 0 +0x0000F8AB 0xE124 # 0 +0x0000F8AC 0xE125 # 0 +0x0000F8AD 0xE126 # 0 +0x0000F8AE 0xE127 # 0 +0x0000F8AF 0xE128 # 0 +0x0000F8B0 0xE129 # 0 +0x0000F8B1 0xE12A # 0 +0x0000F8B2 0xE12B # 0 +0x0000F8B3 0xE12C # 0 +0x0000F8B4 0xE12D # 0 +0x0000F8B5 0xE12E # 0 +0x0000F8B6 0xE12F # 0 +0x0000F8B7 0xE130 # 0 +0x0000F8B8 0xE131 # 0 +0x0000F8B9 0xE132 # 0 +0x0000F8BA 0xE133 # 0 +0x0000F8BB 0xE134 # 0 +0x0000F8BC 0xE135 # 0 +0x0000F8BD 0xE136 # 0 +0x0000F8BE 0xE137 # 0 +0x0000F8BF 0xE138 # 0 +0x0000F8C0 0xE139 # 0 +0x0000F8C1 0xE13A # 0 +0x0000F8C2 0xE13B # 0 +0x0000F8C3 0xE13C # 0 +0x0000F8C4 0xE13D # 0 +0x0000F8C5 0xE13E # 0 +0x0000F8C6 0xE13F # 0 +0x0000F8C7 0xE140 # 0 +0x0000F8C8 0xE141 # 0 +0x0000F8C9 0xE142 # 0 +0x0000F8CA 0xE143 # 0 +0x0000F8CB 0xE144 # 0 +0x0000F8CC 0xE145 # 0 +0x0000F8CD 0xE146 # 0 +0x0000F8CE 0xE147 # 0 +0x0000F8CF 0xE148 # 0 +0x0000F8D0 0xE149 # 0 +0x0000F8D1 0xE14A # 0 +0x0000F8D2 0xE14B # 0 +0x0000F8D3 0xE14C # 0 +0x0000F8D4 0xE14D # 0 +0x0000F8D5 0xE14E # 0 +0x0000F8D6 0xE14F # 0 +0x0000F8D7 0xE150 # 0 +0x0000F8D8 0xE151 # 0 +0x0000F8D9 0xE152 # 0 +0x0000F8DA 0xE153 # 0 +0x0000F8DB 0xE154 # 0 +0x0000F8DC 0xE155 # 0 +0x0000F8DD 0xE156 # 0 +0x0000F8DE 0xE157 # 0 +0x0000F8DF 0xE158 # 0 +0x0000F8E0 0xE159 # 0 +0x0000F8E1 0xE15A # 0 +0x0000F8E2 0xE15B # 0 +0x0000F8E3 0xE15C # 0 +0x0000F8E4 0xE15D # 0 +0x0000F8E5 0xE15E # 0 +0x0000F8E6 0xE15F # 0 +0x0000F8E7 0xE160 # 0 +0x0000F8E8 0xE161 # 0 +0x0000F8E9 0xE162 # 0 +0x0000F8EA 0xE163 # 0 +0x0000F8EB 0xE164 # 0 +0x0000F8EC 0xE165 # 0 +0x0000F8ED 0xE166 # 0 +0x0000F8EE 0xE167 # 0 +0x0000F8EF 0xE168 # 0 +0x0000F8F0 0xE169 # 0 +0x0000F8F1 0xE16A # 0 +0x0000F8F2 0xE16B # 0 +0x0000F8F3 0xE16C # 0 +0x0000F8F4 0xE16D # 0 +0x0000F8F5 0xE16E # 0 +0x0000F8F6 0xE16F # 0 +0x0000F8F7 0xE170 # 0 +0x0000F8F8 0xE171 # 0 +0x0000F8F9 0xE172 # 0 +0x0000F8FA 0xE173 # 0 +0x0000F8FB 0xE174 # 0 +0x0000F8FC 0xE175 # 0 +0x0000F8FD 0xE176 # 0 +0x0000F8FE 0xE177 # 0 +0x0000F9A1 0xE178 # 0 +0x0000F9A2 0xE179 # 0 +0x0000F9A3 0xE17A # 0 +0x0000F9A4 0xE17B # 0 +0x0000F9A5 0xE17C # 0 +0x0000F9A6 0xE17D # 0 +0x0000F9A7 0xE17E # 0 +0x0000F9A8 0xE17F # 0 +0x0000F9A9 0xE180 # 0 +0x0000F9AA 0xE181 # 0 +0x0000F9AB 0xE182 # 0 +0x0000F9AC 0xE183 # 0 +0x0000F9AD 0xE184 # 0 +0x0000F9AE 0xE185 # 0 +0x0000F9AF 0xE186 # 0 +0x0000F9B0 0xE187 # 0 +0x0000F9B1 0xE188 # 0 +0x0000F9B2 0xE189 # 0 +0x0000F9B3 0xE18A # 0 +0x0000F9B4 0xE18B # 0 +0x0000F9B5 0xE18C # 0 +0x0000F9B6 0xE18D # 0 +0x0000F9B7 0xE18E # 0 +0x0000F9B8 0xE18F # 0 +0x0000F9B9 0xE190 # 0 +0x0000F9BA 0xE191 # 0 +0x0000F9BB 0xE192 # 0 +0x0000F9BC 0xE193 # 0 +0x0000F9BD 0xE194 # 0 +0x0000F9BE 0xE195 # 0 +0x0000F9BF 0xE196 # 0 +0x0000F9C0 0xE197 # 0 +0x0000F9C1 0xE198 # 0 +0x0000F9C2 0xE199 # 0 +0x0000F9C3 0xE19A # 0 +0x0000F9C4 0xE19B # 0 +0x0000F9C5 0xE19C # 0 +0x0000F9C6 0xE19D # 0 +0x0000F9C7 0xE19E # 0 +0x0000F9C8 0xE19F # 0 +0x0000F9C9 0xE1A0 # 0 +0x0000F9CA 0xE1A1 # 0 +0x0000F9CB 0xE1A2 # 0 +0x0000F9CC 0xE1A3 # 0 +0x0000F9CD 0xE1A4 # 0 +0x0000F9CE 0xE1A5 # 0 +0x0000F9CF 0xE1A6 # 0 +0x0000F9D0 0xE1A7 # 0 +0x0000F9D1 0xE1A8 # 0 +0x0000F9D2 0xE1A9 # 0 +0x0000F9D3 0xE1AA # 0 +0x0000F9D4 0xE1AB # 0 +0x0000F9D5 0xE1AC # 0 +0x0000F9D6 0xE1AD # 0 +0x0000F9D7 0xE1AE # 0 +0x0000F9D8 0xE1AF # 0 +0x0000F9D9 0xE1B0 # 0 +0x0000F9DA 0xE1B1 # 0 +0x0000F9DB 0xE1B2 # 0 +0x0000F9DC 0xE1B3 # 0 +0x0000F9DD 0xE1B4 # 0 +0x0000F9DE 0xE1B5 # 0 +0x0000F9DF 0xE1B6 # 0 +0x0000F9E0 0xE1B7 # 0 +0x0000F9E1 0xE1B8 # 0 +0x0000F9E2 0xE1B9 # 0 +0x0000F9E3 0xE1BA # 0 +0x0000F9E4 0xE1BB # 0 +0x0000F9E5 0xE1BC # 0 +0x0000F9E6 0xE1BD # 0 +0x0000F9E7 0xE1BE # 0 +0x0000F9E8 0xE1BF # 0 +0x0000F9E9 0xE1C0 # 0 +0x0000F9EA 0xE1C1 # 0 +0x0000F9EB 0xE1C2 # 0 +0x0000F9EC 0xE1C3 # 0 +0x0000F9ED 0xE1C4 # 0 +0x0000F9EE 0xE1C5 # 0 +0x0000F9EF 0xE1C6 # 0 +0x0000F9F0 0xE1C7 # 0 +0x0000F9F1 0xE1C8 # 0 +0x0000F9F2 0xE1C9 # 0 +0x0000F9F3 0xE1CA # 0 +0x0000F9F4 0xE1CB # 0 +0x0000F9F5 0xE1CC # 0 +0x0000F9F6 0xE1CD # 0 +0x0000F9F7 0xE1CE # 0 +0x0000F9F8 0xE1CF # 0 +0x0000F9F9 0xE1D0 # 0 +0x0000F9FA 0xE1D1 # 0 +0x0000F9FB 0xE1D2 # 0 +0x0000F9FC 0xE1D3 # 0 +0x0000F9FD 0xE1D4 # 0 +0x0000F9FE 0xE1D5 # 0 +0x0000FAA1 0xE1D6 # 0 +0x0000FAA2 0xE1D7 # 0 +0x0000FAA3 0xE1D8 # 0 +0x0000FAA4 0xE1D9 # 0 +0x0000FAA5 0xE1DA # 0 +0x0000FAA6 0xE1DB # 0 +0x0000FAA7 0xE1DC # 0 +0x0000FAA8 0xE1DD # 0 +0x0000FAA9 0xE1DE # 0 +0x0000FAAA 0xE1DF # 0 +0x0000FAAB 0xE1E0 # 0 +0x0000FAAC 0xE1E1 # 0 +0x0000FAAD 0xE1E2 # 0 +0x0000FAAE 0xE1E3 # 0 +0x0000FAAF 0xE1E4 # 0 +0x0000FAB0 0xE1E5 # 0 +0x0000FAB1 0xE1E6 # 0 +0x0000FAB2 0xE1E7 # 0 +0x0000FAB3 0xE1E8 # 0 +0x0000FAB4 0xE1E9 # 0 +0x0000FAB5 0xE1EA # 0 +0x0000FAB6 0xE1EB # 0 +0x0000FAB7 0xE1EC # 0 +0x0000FAB8 0xE1ED # 0 +0x0000FAB9 0xE1EE # 0 +0x0000FABA 0xE1EF # 0 +0x0000FABB 0xE1F0 # 0 +0x0000FABC 0xE1F1 # 0 +0x0000FABD 0xE1F2 # 0 +0x0000FABE 0xE1F3 # 0 +0x0000FABF 0xE1F4 # 0 +0x0000FAC0 0xE1F5 # 0 +0x0000FAC1 0xE1F6 # 0 +0x0000FAC2 0xE1F7 # 0 +0x0000FAC3 0xE1F8 # 0 +0x0000FAC4 0xE1F9 # 0 +0x0000FAC5 0xE1FA # 0 +0x0000FAC6 0xE1FB # 0 +0x0000FAC7 0xE1FC # 0 +0x0000FAC8 0xE1FD # 0 +0x0000FAC9 0xE1FE # 0 +0x0000FACA 0xE1FF # 0 +0x0000FACB 0xE200 # 0 +0x0000FACC 0xE201 # 0 +0x0000FACD 0xE202 # 0 +0x0000FACE 0xE203 # 0 +0x0000FACF 0xE204 # 0 +0x0000FAD0 0xE205 # 0 +0x0000FAD1 0xE206 # 0 +0x0000FAD2 0xE207 # 0 +0x0000FAD3 0xE208 # 0 +0x0000FAD4 0xE209 # 0 +0x0000FAD5 0xE20A # 0 +0x0000FAD6 0xE20B # 0 +0x0000FAD7 0xE20C # 0 +0x0000FAD8 0xE20D # 0 +0x0000FAD9 0xE20E # 0 +0x0000FADA 0xE20F # 0 +0x0000FADB 0xE210 # 0 +0x0000FADC 0xE211 # 0 +0x0000FADD 0xE212 # 0 +0x0000FADE 0xE213 # 0 +0x0000FADF 0xE214 # 0 +0x0000FAE0 0xE215 # 0 +0x0000FAE1 0xE216 # 0 +0x0000FAE2 0xE217 # 0 +0x0000FAE3 0xE218 # 0 +0x0000FAE4 0xE219 # 0 +0x0000FAE5 0xE21A # 0 +0x0000FAE6 0xE21B # 0 +0x0000FAE7 0xE21C # 0 +0x0000FAE8 0xE21D # 0 +0x0000FAE9 0xE21E # 0 +0x0000FAEA 0xE21F # 0 +0x0000FAEB 0xE220 # 0 +0x0000FAEC 0xE221 # 0 +0x0000FAED 0xE222 # 0 +0x0000FAEE 0xE223 # 0 +0x0000FAEF 0xE224 # 0 +0x0000FAF0 0xE225 # 0 +0x0000FAF1 0xE226 # 0 +0x0000FAF2 0xE227 # 0 +0x0000FAF3 0xE228 # 0 +0x0000FAF4 0xE229 # 0 +0x0000FAF5 0xE22A # 0 +0x0000FAF6 0xE22B # 0 +0x0000FAF7 0xE22C # 0 +0x0000FAF8 0xE22D # 0 +0x0000FAF9 0xE22E # 0 +0x0000FAFA 0xE22F # 0 +0x0000FAFB 0xE230 # 0 +0x0000FAFC 0xE231 # 0 +0x0000FAFD 0xE232 # 0 +0x0000FAFE 0xE233 # 0 +0x0000FBA1 0xE234 # 0 +0x0000FBA2 0xE235 # 0 +0x0000FBA3 0xE236 # 0 +0x0000FBA4 0xE237 # 0 +0x0000FBA5 0xE238 # 0 +0x0000FBA6 0xE239 # 0 +0x0000FBA7 0xE23A # 0 +0x0000FBA8 0xE23B # 0 +0x0000FBA9 0xE23C # 0 +0x0000FBAA 0xE23D # 0 +0x0000FBAB 0xE23E # 0 +0x0000FBAC 0xE23F # 0 +0x0000FBAD 0xE240 # 0 +0x0000FBAE 0xE241 # 0 +0x0000FBAF 0xE242 # 0 +0x0000FBB0 0xE243 # 0 +0x0000FBB1 0xE244 # 0 +0x0000FBB2 0xE245 # 0 +0x0000FBB3 0xE246 # 0 +0x0000FBB4 0xE247 # 0 +0x0000FBB5 0xE248 # 0 +0x0000FBB6 0xE249 # 0 +0x0000FBB7 0xE24A # 0 +0x0000FBB8 0xE24B # 0 +0x0000FBB9 0xE24C # 0 +0x0000FBBA 0xE24D # 0 +0x0000FBBB 0xE24E # 0 +0x0000FBBC 0xE24F # 0 +0x0000FBBD 0xE250 # 0 +0x0000FBBE 0xE251 # 0 +0x0000FBBF 0xE252 # 0 +0x0000FBC0 0xE253 # 0 +0x0000FBC1 0xE254 # 0 +0x0000FBC2 0xE255 # 0 +0x0000FBC3 0xE256 # 0 +0x0000FBC4 0xE257 # 0 +0x0000FBC5 0xE258 # 0 +0x0000FBC6 0xE259 # 0 +0x0000FBC7 0xE25A # 0 +0x0000FBC8 0xE25B # 0 +0x0000FBC9 0xE25C # 0 +0x0000FBCA 0xE25D # 0 +0x0000FBCB 0xE25E # 0 +0x0000FBCC 0xE25F # 0 +0x0000FBCD 0xE260 # 0 +0x0000FBCE 0xE261 # 0 +0x0000FBCF 0xE262 # 0 +0x0000FBD0 0xE263 # 0 +0x0000FBD1 0xE264 # 0 +0x0000FBD2 0xE265 # 0 +0x0000FBD3 0xE266 # 0 +0x0000FBD4 0xE267 # 0 +0x0000FBD5 0xE268 # 0 +0x0000FBD6 0xE269 # 0 +0x0000FBD7 0xE26A # 0 +0x0000FBD8 0xE26B # 0 +0x0000FBD9 0xE26C # 0 +0x0000FBDA 0xE26D # 0 +0x0000FBDB 0xE26E # 0 +0x0000FBDC 0xE26F # 0 +0x0000FBDD 0xE270 # 0 +0x0000FBDE 0xE271 # 0 +0x0000FBDF 0xE272 # 0 +0x0000FBE0 0xE273 # 0 +0x0000FBE1 0xE274 # 0 +0x0000FBE2 0xE275 # 0 +0x0000FBE3 0xE276 # 0 +0x0000FBE4 0xE277 # 0 +0x0000FBE5 0xE278 # 0 +0x0000FBE6 0xE279 # 0 +0x0000FBE7 0xE27A # 0 +0x0000FBE8 0xE27B # 0 +0x0000FBE9 0xE27C # 0 +0x0000FBEA 0xE27D # 0 +0x0000FBEB 0xE27E # 0 +0x0000FBEC 0xE27F # 0 +0x0000FBED 0xE280 # 0 +0x0000FBEE 0xE281 # 0 +0x0000FBEF 0xE282 # 0 +0x0000FBF0 0xE283 # 0 +0x0000FBF1 0xE284 # 0 +0x0000FBF2 0xE285 # 0 +0x0000FBF3 0xE286 # 0 +0x0000FBF4 0xE287 # 0 +0x0000FBF5 0xE288 # 0 +0x0000FBF6 0xE289 # 0 +0x0000FBF7 0xE28A # 0 +0x0000FBF8 0xE28B # 0 +0x0000FBF9 0xE28C # 0 +0x0000FBFA 0xE28D # 0 +0x0000FBFB 0xE28E # 0 +0x0000FBFC 0xE28F # 0 +0x0000FBFD 0xE290 # 0 +0x0000FBFE 0xE291 # 0 +0x0000FCA1 0xE292 # 0 +0x0000FCA2 0xE293 # 0 +0x0000FCA3 0xE294 # 0 +0x0000FCA4 0xE295 # 0 +0x0000FCA5 0xE296 # 0 +0x0000FCA6 0xE297 # 0 +0x0000FCA7 0xE298 # 0 +0x0000FCA8 0xE299 # 0 +0x0000FCA9 0xE29A # 0 +0x0000FCAA 0xE29B # 0 +0x0000FCAB 0xE29C # 0 +0x0000FCAC 0xE29D # 0 +0x0000FCAD 0xE29E # 0 +0x0000FCAE 0xE29F # 0 +0x0000FCAF 0xE2A0 # 0 +0x0000FCB0 0xE2A1 # 0 +0x0000FCB1 0xE2A2 # 0 +0x0000FCB2 0xE2A3 # 0 +0x0000FCB3 0xE2A4 # 0 +0x0000FCB4 0xE2A5 # 0 +0x0000FCB5 0xE2A6 # 0 +0x0000FCB6 0xE2A7 # 0 +0x0000FCB7 0xE2A8 # 0 +0x0000FCB8 0xE2A9 # 0 +0x0000FCB9 0xE2AA # 0 +0x0000FCBA 0xE2AB # 0 +0x0000FCBB 0xE2AC # 0 +0x0000FCBC 0xE2AD # 0 +0x0000FCBD 0xE2AE # 0 +0x0000FCBE 0xE2AF # 0 +0x0000FCBF 0xE2B0 # 0 +0x0000FCC0 0xE2B1 # 0 +0x0000FCC1 0xE2B2 # 0 +0x0000FCC2 0xE2B3 # 0 +0x0000FCC3 0xE2B4 # 0 +0x0000FCC4 0xE2B5 # 0 +0x0000FCC5 0xE2B6 # 0 +0x0000FCC6 0xE2B7 # 0 +0x0000FCC7 0xE2B8 # 0 +0x0000FCC8 0xE2B9 # 0 +0x0000FCC9 0xE2BA # 0 +0x0000FCCA 0xE2BB # 0 +0x0000FCCB 0xE2BC # 0 +0x0000FCCC 0xE2BD # 0 +0x0000FCCD 0xE2BE # 0 +0x0000FCCE 0xE2BF # 0 +0x0000FCCF 0xE2C0 # 0 +0x0000FCD0 0xE2C1 # 0 +0x0000FCD1 0xE2C2 # 0 +0x0000FCD2 0xE2C3 # 0 +0x0000FCD3 0xE2C4 # 0 +0x0000FCD4 0xE2C5 # 0 +0x0000FCD5 0xE2C6 # 0 +0x0000FCD6 0xE2C7 # 0 +0x0000FCD7 0xE2C8 # 0 +0x0000FCD8 0xE2C9 # 0 +0x0000FCD9 0xE2CA # 0 +0x0000FCDA 0xE2CB # 0 +0x0000FCDB 0xE2CC # 0 +0x0000FCDC 0xE2CD # 0 +0x0000FCDD 0xE2CE # 0 +0x0000FCDE 0xE2CF # 0 +0x0000FCDF 0xE2D0 # 0 +0x0000FCE0 0xE2D1 # 0 +0x0000FCE1 0xE2D2 # 0 +0x0000FCE2 0xE2D3 # 0 +0x0000FCE3 0xE2D4 # 0 +0x0000FCE4 0xE2D5 # 0 +0x0000FCE5 0xE2D6 # 0 +0x0000FCE6 0xE2D7 # 0 +0x0000FCE7 0xE2D8 # 0 +0x0000FCE8 0xE2D9 # 0 +0x0000FCE9 0xE2DA # 0 +0x0000FCEA 0xE2DB # 0 +0x0000FCEB 0xE2DC # 0 +0x0000FCEC 0xE2DD # 0 +0x0000FCED 0xE2DE # 0 +0x0000FCEE 0xE2DF # 0 +0x0000FCEF 0xE2E0 # 0 +0x0000FCF0 0xE2E1 # 0 +0x0000FCF1 0xE2E2 # 0 +0x0000FCF2 0xE2E3 # 0 +0x0000FCF3 0xE2E4 # 0 +0x0000FCF4 0xE2E5 # 0 +0x0000FCF5 0xE2E6 # 0 +0x0000FCF6 0xE2E7 # 0 +0x0000FCF7 0xE2E8 # 0 +0x0000FCF8 0xE2E9 # 0 +0x0000FCF9 0xE2EA # 0 +0x0000FCFA 0xE2EB # 0 +0x0000FCFB 0xE2EC # 0 +0x0000FCFC 0xE2ED # 0 +0x0000FCFD 0xE2EE # 0 +0x0000FCFE 0xE2EF # 0 +0x0000FDA1 0xE2F0 # 0 +0x0000FDA2 0xE2F1 # 0 +0x0000FDA3 0xE2F2 # 0 +0x0000FDA4 0xE2F3 # 0 +0x0000FDA5 0xE2F4 # 0 +0x0000FDA6 0xE2F5 # 0 +0x0000FDA7 0xE2F6 # 0 +0x0000FDA8 0xE2F7 # 0 +0x0000FDA9 0xE2F8 # 0 +0x0000FDAA 0xE2F9 # 0 +0x0000FDAB 0xE2FA # 0 +0x0000FDAC 0xE2FB # 0 +0x0000FDAD 0xE2FC # 0 +0x0000FDAE 0xE2FD # 0 +0x0000FDAF 0xE2FE # 0 +0x0000FDB0 0xE2FF # 0 +0x0000FDB1 0xE300 # 0 +0x0000FDB2 0xE301 # 0 +0x0000FDB3 0xE302 # 0 +0x0000FDB4 0xE303 # 0 +0x0000FDB5 0xE304 # 0 +0x0000FDB6 0xE305 # 0 +0x0000FDB7 0xE306 # 0 +0x0000FDB8 0xE307 # 0 +0x0000FDB9 0xE308 # 0 +0x0000FDBA 0xE309 # 0 +0x0000FDBB 0xE30A # 0 +0x0000FDBC 0xE30B # 0 +0x0000FDBD 0xE30C # 0 +0x0000FDBE 0xE30D # 0 +0x0000FDBF 0xE30E # 0 +0x0000FDC0 0xE30F # 0 +0x0000FDC1 0xE310 # 0 +0x0000FDC2 0xE311 # 0 +0x0000FDC3 0xE312 # 0 +0x0000FDC4 0xE313 # 0 +0x0000FDC5 0xE314 # 0 +0x0000FDC6 0xE315 # 0 +0x0000FDC7 0xE316 # 0 +0x0000FDC8 0xE317 # 0 +0x0000FDC9 0xE318 # 0 +0x0000FDCA 0xE319 # 0 +0x0000FDCB 0xE31A # 0 +0x0000FDCC 0xE31B # 0 +0x0000FDCD 0xE31C # 0 +0x0000FDCE 0xE31D # 0 +0x0000FDCF 0xE31E # 0 +0x0000FDD0 0xE31F # 0 +0x0000FDD1 0xE320 # 0 +0x0000FDD2 0xE321 # 0 +0x0000FDD3 0xE322 # 0 +0x0000FDD4 0xE323 # 0 +0x0000FDD5 0xE324 # 0 +0x0000FDD6 0xE325 # 0 +0x0000FDD7 0xE326 # 0 +0x0000FDD8 0xE327 # 0 +0x0000FDD9 0xE328 # 0 +0x0000FDDA 0xE329 # 0 +0x0000FDDB 0xE32A # 0 +0x0000FDDC 0xE32B # 0 +0x0000FDDD 0xE32C # 0 +0x0000FDDE 0xE32D # 0 +0x0000FDDF 0xE32E # 0 +0x0000FDE0 0xE32F # 0 +0x0000FDE1 0xE330 # 0 +0x0000FDE2 0xE331 # 0 +0x0000FDE3 0xE332 # 0 +0x0000FDE4 0xE333 # 0 +0x0000FDE5 0xE334 # 0 +0x0000FDE6 0xE335 # 0 +0x0000FDE7 0xE336 # 0 +0x0000FDE8 0xE337 # 0 +0x0000FDE9 0xE338 # 0 +0x0000FDEA 0xE339 # 0 +0x0000FDEB 0xE33A # 0 +0x0000FDEC 0xE33B # 0 +0x0000FDED 0xE33C # 0 +0x0000FDEE 0xE33D # 0 +0x0000FDEF 0xE33E # 0 +0x0000FDF0 0xE33F # 0 +0x0000FDF1 0xE340 # 0 +0x0000FDF2 0xE341 # 0 +0x0000FDF3 0xE342 # 0 +0x0000FDF4 0xE343 # 0 +0x0000FDF5 0xE344 # 0 +0x0000FDF6 0xE345 # 0 +0x0000FDF7 0xE346 # 0 +0x0000FDF8 0xE347 # 0 +0x0000FDF9 0xE348 # 0 +0x0000FDFA 0xE349 # 0 +0x0000FDFB 0xE34A # 0 +0x0000FDFC 0xE34B # 0 +0x0000FDFD 0xE34C # 0 +0x0000FDFE 0xE34D # 0 +0x0000FEA1 0xE34E # 0 +0x0000FEA2 0xE34F # 0 +0x0000FEA3 0xE350 # 0 +0x0000FEA4 0xE351 # 0 +0x0000FEA5 0xE352 # 0 +0x0000FEA6 0xE353 # 0 +0x0000FEA7 0xE354 # 0 +0x0000FEA8 0xE355 # 0 +0x0000FEA9 0xE356 # 0 +0x0000FEAA 0xE357 # 0 +0x0000FEAB 0xE358 # 0 +0x0000FEAC 0xE359 # 0 +0x0000FEAD 0xE35A # 0 +0x0000FEAE 0xE35B # 0 +0x0000FEAF 0xE35C # 0 +0x0000FEB0 0xE35D # 0 +0x0000FEB1 0xE35E # 0 +0x0000FEB2 0xE35F # 0 +0x0000FEB3 0xE360 # 0 +0x0000FEB4 0xE361 # 0 +0x0000FEB5 0xE362 # 0 +0x0000FEB6 0xE363 # 0 +0x0000FEB7 0xE364 # 0 +0x0000FEB8 0xE365 # 0 +0x0000FEB9 0xE366 # 0 +0x0000FEBA 0xE367 # 0 +0x0000FEBB 0xE368 # 0 +0x0000FEBC 0xE369 # 0 +0x0000FEBD 0xE36A # 0 +0x0000FEBE 0xE36B # 0 +0x0000FEBF 0xE36C # 0 +0x0000FEC0 0xE36D # 0 +0x0000FEC1 0xE36E # 0 +0x0000FEC2 0xE36F # 0 +0x0000FEC3 0xE370 # 0 +0x0000FEC4 0xE371 # 0 +0x0000FEC5 0xE372 # 0 +0x0000FEC6 0xE373 # 0 +0x0000FEC7 0xE374 # 0 +0x0000FEC8 0xE375 # 0 +0x0000FEC9 0xE376 # 0 +0x0000FECA 0xE377 # 0 +0x0000FECB 0xE378 # 0 +0x0000FECC 0xE379 # 0 +0x0000FECD 0xE37A # 0 +0x0000FECE 0xE37B # 0 +0x0000FECF 0xE37C # 0 +0x0000FED0 0xE37D # 0 +0x0000FED1 0xE37E # 0 +0x0000FED2 0xE37F # 0 +0x0000FED3 0xE380 # 0 +0x0000FED4 0xE381 # 0 +0x0000FED5 0xE382 # 0 +0x0000FED6 0xE383 # 0 +0x0000FED7 0xE384 # 0 +0x0000FED8 0xE385 # 0 +0x0000FED9 0xE386 # 0 +0x0000FEDA 0xE387 # 0 +0x0000FEDB 0xE388 # 0 +0x0000FEDC 0xE389 # 0 +0x0000FEDD 0xE38A # 0 +0x0000FEDE 0xE38B # 0 +0x0000FEDF 0xE38C # 0 +0x0000FEE0 0xE38D # 0 +0x0000FEE1 0xE38E # 0 +0x0000FEE2 0xE38F # 0 +0x0000FEE3 0xE390 # 0 +0x0000FEE4 0xE391 # 0 +0x0000FEE5 0xE392 # 0 +0x0000FEE6 0xE393 # 0 +0x0000FEE7 0xE394 # 0 +0x0000FEE8 0xE395 # 0 +0x0000FEE9 0xE396 # 0 +0x0000FEEA 0xE397 # 0 +0x0000FEEB 0xE398 # 0 +0x0000FEEC 0xE399 # 0 +0x0000FEED 0xE39A # 0 +0x0000FEEE 0xE39B # 0 +0x0000FEEF 0xE39C # 0 +0x0000FEF0 0xE39D # 0 +0x0000FEF1 0xE39E # 0 +0x0000FEF2 0xE39F # 0 +0x0000FEF3 0xE3A0 # 0 +0x0000FEF4 0xE3A1 # 0 +0x0000FEF5 0xE3A2 # 0 +0x0000FEF6 0xE3A3 # 0 +0x0000FEF7 0xE3A4 # 0 +0x0000FEF8 0xE3A5 # 0 +0x0000FEF9 0xE3A6 # 0 +0x0000FEFA 0xE3A7 # 0 +0x0000FEFB 0xE3A8 # 0 +0x0000FEFC 0xE3A9 # 0 +0x0000FEFD 0xE3AA # 0 +0x0000FEFE 0xE3AB # 0 +0x008FA2AF 0x02D8 # 0 +0x008FA2B0 0x02C7 # 0 +0x008FA2B1 0x00B8 # 0 +0x008FA2B2 0x02D9 # 0 +0x008FA2B3 0x02DD # 0 +0x008FA2B4 0x00AF # 0 +0x008FA2B5 0x02DB # 0 +0x008FA2B6 0x02DA # 0 +0x008FA2B7 0xFF5E # 0 +0x008FA2B8 0x0384 # 0 +0x008FA2B9 0x0385 # 0 +0x008FA2C2 0x00A1 # 0 +0x008FA2C3 0x00A6 # 0 +0x008FA2C4 0x00BF # 0 +0x008FA2EB 0x00BA # 0 +0x008FA2EC 0x00AA # 0 +0x008FA2ED 0x00A9 # 0 +0x008FA2EE 0x00AE # 0 +0x008FA2EF 0x2122 # 0 +0x008FA2F0 0x00A4 # 0 +0x008FA2F1 0x2116 # 0 +0x008FA6E1 0x0386 # 0 +0x008FA6E2 0x0388 # 0 +0x008FA6E3 0x0389 # 0 +0x008FA6E4 0x038A # 0 +0x008FA6E5 0x03AA # 0 +0x008FA6E7 0x038C # 0 +0x008FA6E9 0x038E # 0 +0x008FA6EA 0x03AB # 0 +0x008FA6EC 0x038F # 0 +0x008FA6F1 0x03AC # 0 +0x008FA6F2 0x03AD # 0 +0x008FA6F3 0x03AE # 0 +0x008FA6F4 0x03AF # 0 +0x008FA6F5 0x03CA # 0 +0x008FA6F6 0x0390 # 0 +0x008FA6F7 0x03CC # 0 +0x008FA6F8 0x03C2 # 0 +0x008FA6F9 0x03CD # 0 +0x008FA6FA 0x03CB # 0 +0x008FA6FB 0x03B0 # 0 +0x008FA6FC 0x03CE # 0 +0x008FA7C2 0x0402 # 0 +0x008FA7C3 0x0403 # 0 +0x008FA7C4 0x0404 # 0 +0x008FA7C5 0x0405 # 0 +0x008FA7C6 0x0406 # 0 +0x008FA7C7 0x0407 # 0 +0x008FA7C8 0x0408 # 0 +0x008FA7C9 0x0409 # 0 +0x008FA7CA 0x040A # 0 +0x008FA7CB 0x040B # 0 +0x008FA7CC 0x040C # 0 +0x008FA7CD 0x040E # 0 +0x008FA7CE 0x040F # 0 +0x008FA7F2 0x0452 # 0 +0x008FA7F3 0x0453 # 0 +0x008FA7F4 0x0454 # 0 +0x008FA7F5 0x0455 # 0 +0x008FA7F6 0x0456 # 0 +0x008FA7F7 0x0457 # 0 +0x008FA7F8 0x0458 # 0 +0x008FA7F9 0x0459 # 0 +0x008FA7FA 0x045A # 0 +0x008FA7FB 0x045B # 0 +0x008FA7FC 0x045C # 0 +0x008FA7FD 0x045E # 0 +0x008FA7FE 0x045F # 0 +0x008FA9A1 0x00C6 # 0 +0x008FA9A2 0x0110 # 0 +0x008FA9A4 0x0126 # 0 +0x008FA9A6 0x0132 # 0 +0x008FA9A8 0x0141 # 0 +0x008FA9A9 0x013F # 0 +0x008FA9AB 0x014A # 0 +0x008FA9AC 0x00D8 # 0 +0x008FA9AD 0x0152 # 0 +0x008FA9AF 0x0166 # 0 +0x008FA9B0 0x00DE # 0 +0x008FA9C1 0x00E6 # 0 +0x008FA9C2 0x0111 # 0 +0x008FA9C3 0x00F0 # 0 +0x008FA9C4 0x0127 # 0 +0x008FA9C5 0x0131 # 0 +0x008FA9C6 0x0133 # 0 +0x008FA9C7 0x0138 # 0 +0x008FA9C8 0x0142 # 0 +0x008FA9C9 0x0140 # 0 +0x008FA9CA 0x0149 # 0 +0x008FA9CB 0x014B # 0 +0x008FA9CC 0x00F8 # 0 +0x008FA9CD 0x0153 # 0 +0x008FA9CE 0x00DF # 0 +0x008FA9CF 0x0167 # 0 +0x008FA9D0 0x00FE # 0 +0x008FAAA1 0x00C1 # 0 +0x008FAAA2 0x00C0 # 0 +0x008FAAA3 0x00C4 # 0 +0x008FAAA4 0x00C2 # 0 +0x008FAAA5 0x0102 # 0 +0x008FAAA6 0x01CD # 0 +0x008FAAA7 0x0100 # 0 +0x008FAAA8 0x0104 # 0 +0x008FAAA9 0x00C5 # 0 +0x008FAAAA 0x00C3 # 0 +0x008FAAAB 0x0106 # 0 +0x008FAAAC 0x0108 # 0 +0x008FAAAD 0x010C # 0 +0x008FAAAE 0x00C7 # 0 +0x008FAAAF 0x010A # 0 +0x008FAAB0 0x010E # 0 +0x008FAAB1 0x00C9 # 0 +0x008FAAB2 0x00C8 # 0 +0x008FAAB3 0x00CB # 0 +0x008FAAB4 0x00CA # 0 +0x008FAAB5 0x011A # 0 +0x008FAAB6 0x0116 # 0 +0x008FAAB7 0x0112 # 0 +0x008FAAB8 0x0118 # 0 +0x008FAABA 0x011C # 0 +0x008FAABB 0x011E # 0 +0x008FAABC 0x0122 # 0 +0x008FAABD 0x0120 # 0 +0x008FAABE 0x0124 # 0 +0x008FAABF 0x00CD # 0 +0x008FAAC0 0x00CC # 0 +0x008FAAC1 0x00CF # 0 +0x008FAAC2 0x00CE # 0 +0x008FAAC3 0x01CF # 0 +0x008FAAC4 0x0130 # 0 +0x008FAAC5 0x012A # 0 +0x008FAAC6 0x012E # 0 +0x008FAAC7 0x0128 # 0 +0x008FAAC8 0x0134 # 0 +0x008FAAC9 0x0136 # 0 +0x008FAACA 0x0139 # 0 +0x008FAACB 0x013D # 0 +0x008FAACC 0x013B # 0 +0x008FAACD 0x0143 # 0 +0x008FAACE 0x0147 # 0 +0x008FAACF 0x0145 # 0 +0x008FAAD0 0x00D1 # 0 +0x008FAAD1 0x00D3 # 0 +0x008FAAD2 0x00D2 # 0 +0x008FAAD3 0x00D6 # 0 +0x008FAAD4 0x00D4 # 0 +0x008FAAD5 0x01D1 # 0 +0x008FAAD6 0x0150 # 0 +0x008FAAD7 0x014C # 0 +0x008FAAD8 0x00D5 # 0 +0x008FAAD9 0x0154 # 0 +0x008FAADA 0x0158 # 0 +0x008FAADB 0x0156 # 0 +0x008FAADC 0x015A # 0 +0x008FAADD 0x015C # 0 +0x008FAADE 0x0160 # 0 +0x008FAADF 0x015E # 0 +0x008FAAE0 0x0164 # 0 +0x008FAAE1 0x0162 # 0 +0x008FAAE2 0x00DA # 0 +0x008FAAE3 0x00D9 # 0 +0x008FAAE4 0x00DC # 0 +0x008FAAE5 0x00DB # 0 +0x008FAAE6 0x016C # 0 +0x008FAAE7 0x01D3 # 0 +0x008FAAE8 0x0170 # 0 +0x008FAAE9 0x016A # 0 +0x008FAAEA 0x0172 # 0 +0x008FAAEB 0x016E # 0 +0x008FAAEC 0x0168 # 0 +0x008FAAED 0x01D7 # 0 +0x008FAAEE 0x01DB # 0 +0x008FAAEF 0x01D9 # 0 +0x008FAAF0 0x01D5 # 0 +0x008FAAF1 0x0174 # 0 +0x008FAAF2 0x00DD # 0 +0x008FAAF3 0x0178 # 0 +0x008FAAF4 0x0176 # 0 +0x008FAAF5 0x0179 # 0 +0x008FAAF6 0x017D # 0 +0x008FAAF7 0x017B # 0 +0x008FABA1 0x00E1 # 0 +0x008FABA2 0x00E0 # 0 +0x008FABA3 0x00E4 # 0 +0x008FABA4 0x00E2 # 0 +0x008FABA5 0x0103 # 0 +0x008FABA6 0x01CE # 0 +0x008FABA7 0x0101 # 0 +0x008FABA8 0x0105 # 0 +0x008FABA9 0x00E5 # 0 +0x008FABAA 0x00E3 # 0 +0x008FABAB 0x0107 # 0 +0x008FABAC 0x0109 # 0 +0x008FABAD 0x010D # 0 +0x008FABAE 0x00E7 # 0 +0x008FABAF 0x010B # 0 +0x008FABB0 0x010F # 0 +0x008FABB1 0x00E9 # 0 +0x008FABB2 0x00E8 # 0 +0x008FABB3 0x00EB # 0 +0x008FABB4 0x00EA # 0 +0x008FABB5 0x011B # 0 +0x008FABB6 0x0117 # 0 +0x008FABB7 0x0113 # 0 +0x008FABB8 0x0119 # 0 +0x008FABB9 0x01F5 # 0 +0x008FABBA 0x011D # 0 +0x008FABBB 0x011F # 0 +0x008FABBD 0x0121 # 0 +0x008FABBE 0x0125 # 0 +0x008FABBF 0x00ED # 0 +0x008FABC0 0x00EC # 0 +0x008FABC1 0x00EF # 0 +0x008FABC2 0x00EE # 0 +0x008FABC3 0x01D0 # 0 +0x008FABC5 0x012B # 0 +0x008FABC6 0x012F # 0 +0x008FABC7 0x0129 # 0 +0x008FABC8 0x0135 # 0 +0x008FABC9 0x0137 # 0 +0x008FABCA 0x013A # 0 +0x008FABCB 0x013E # 0 +0x008FABCC 0x013C # 0 +0x008FABCD 0x0144 # 0 +0x008FABCE 0x0148 # 0 +0x008FABCF 0x0146 # 0 +0x008FABD0 0x00F1 # 0 +0x008FABD1 0x00F3 # 0 +0x008FABD2 0x00F2 # 0 +0x008FABD3 0x00F6 # 0 +0x008FABD4 0x00F4 # 0 +0x008FABD5 0x01D2 # 0 +0x008FABD6 0x0151 # 0 +0x008FABD7 0x014D # 0 +0x008FABD8 0x00F5 # 0 +0x008FABD9 0x0155 # 0 +0x008FABDA 0x0159 # 0 +0x008FABDB 0x0157 # 0 +0x008FABDC 0x015B # 0 +0x008FABDD 0x015D # 0 +0x008FABDE 0x0161 # 0 +0x008FABDF 0x015F # 0 +0x008FABE0 0x0165 # 0 +0x008FABE1 0x0163 # 0 +0x008FABE2 0x00FA # 0 +0x008FABE3 0x00F9 # 0 +0x008FABE4 0x00FC # 0 +0x008FABE5 0x00FB # 0 +0x008FABE6 0x016D # 0 +0x008FABE7 0x01D4 # 0 +0x008FABE8 0x0171 # 0 +0x008FABE9 0x016B # 0 +0x008FABEA 0x0173 # 0 +0x008FABEB 0x016F # 0 +0x008FABEC 0x0169 # 0 +0x008FABED 0x01D8 # 0 +0x008FABEE 0x01DC # 0 +0x008FABEF 0x01DA # 0 +0x008FABF0 0x01D6 # 0 +0x008FABF1 0x0175 # 0 +0x008FABF2 0x00FD # 0 +0x008FABF3 0x00FF # 0 +0x008FABF4 0x0177 # 0 +0x008FABF5 0x017A # 0 +0x008FABF6 0x017E # 0 +0x008FABF7 0x017C # 0 +0x008FB0A1 0x4E02 # 0 +0x008FB0A2 0x4E04 # 0 +0x008FB0A3 0x4E05 # 0 +0x008FB0A4 0x4E0C # 0 +0x008FB0A5 0x4E12 # 0 +0x008FB0A6 0x4E1F # 0 +0x008FB0A7 0x4E23 # 0 +0x008FB0A8 0x4E24 # 0 +0x008FB0A9 0x4E28 # 0 +0x008FB0AA 0x4E2B # 0 +0x008FB0AB 0x4E2E # 0 +0x008FB0AC 0x4E2F # 0 +0x008FB0AD 0x4E30 # 0 +0x008FB0AE 0x4E35 # 0 +0x008FB0AF 0x4E40 # 0 +0x008FB0B0 0x4E41 # 0 +0x008FB0B1 0x4E44 # 0 +0x008FB0B2 0x4E47 # 0 +0x008FB0B3 0x4E51 # 0 +0x008FB0B4 0x4E5A # 0 +0x008FB0B5 0x4E5C # 0 +0x008FB0B6 0x4E63 # 0 +0x008FB0B7 0x4E68 # 0 +0x008FB0B8 0x4E69 # 0 +0x008FB0B9 0x4E74 # 0 +0x008FB0BA 0x4E75 # 0 +0x008FB0BB 0x4E79 # 0 +0x008FB0BC 0x4E7F # 0 +0x008FB0BD 0x4E8D # 0 +0x008FB0BE 0x4E96 # 0 +0x008FB0BF 0x4E97 # 0 +0x008FB0C0 0x4E9D # 0 +0x008FB0C1 0x4EAF # 0 +0x008FB0C2 0x4EB9 # 0 +0x008FB0C3 0x4EC3 # 0 +0x008FB0C4 0x4ED0 # 0 +0x008FB0C5 0x4EDA # 0 +0x008FB0C6 0x4EDB # 0 +0x008FB0C7 0x4EE0 # 0 +0x008FB0C8 0x4EE1 # 0 +0x008FB0C9 0x4EE2 # 0 +0x008FB0CA 0x4EE8 # 0 +0x008FB0CB 0x4EEF # 0 +0x008FB0CC 0x4EF1 # 0 +0x008FB0CD 0x4EF3 # 0 +0x008FB0CE 0x4EF5 # 0 +0x008FB0CF 0x4EFD # 0 +0x008FB0D0 0x4EFE # 0 +0x008FB0D1 0x4EFF # 0 +0x008FB0D2 0x4F00 # 0 +0x008FB0D3 0x4F02 # 0 +0x008FB0D4 0x4F03 # 0 +0x008FB0D5 0x4F08 # 0 +0x008FB0D6 0x4F0B # 0 +0x008FB0D7 0x4F0C # 0 +0x008FB0D8 0x4F12 # 0 +0x008FB0D9 0x4F15 # 0 +0x008FB0DA 0x4F16 # 0 +0x008FB0DB 0x4F17 # 0 +0x008FB0DC 0x4F19 # 0 +0x008FB0DD 0x4F2E # 0 +0x008FB0DE 0x4F31 # 0 +0x008FB0DF 0x4F60 # 0 +0x008FB0E0 0x4F33 # 0 +0x008FB0E1 0x4F35 # 0 +0x008FB0E2 0x4F37 # 0 +0x008FB0E3 0x4F39 # 0 +0x008FB0E4 0x4F3B # 0 +0x008FB0E5 0x4F3E # 0 +0x008FB0E6 0x4F40 # 0 +0x008FB0E7 0x4F42 # 0 +0x008FB0E8 0x4F48 # 0 +0x008FB0E9 0x4F49 # 0 +0x008FB0EA 0x4F4B # 0 +0x008FB0EB 0x4F4C # 0 +0x008FB0EC 0x4F52 # 0 +0x008FB0ED 0x4F54 # 0 +0x008FB0EE 0x4F56 # 0 +0x008FB0EF 0x4F58 # 0 +0x008FB0F0 0x4F5F # 0 +0x008FB0F1 0x4F63 # 0 +0x008FB0F2 0x4F6A # 0 +0x008FB0F3 0x4F6C # 0 +0x008FB0F4 0x4F6E # 0 +0x008FB0F5 0x4F71 # 0 +0x008FB0F6 0x4F77 # 0 +0x008FB0F7 0x4F78 # 0 +0x008FB0F8 0x4F79 # 0 +0x008FB0F9 0x4F7A # 0 +0x008FB0FA 0x4F7D # 0 +0x008FB0FB 0x4F7E # 0 +0x008FB0FC 0x4F81 # 0 +0x008FB0FD 0x4F82 # 0 +0x008FB0FE 0x4F84 # 0 +0x008FB1A1 0x4F85 # 0 +0x008FB1A2 0x4F89 # 0 +0x008FB1A3 0x4F8A # 0 +0x008FB1A4 0x4F8C # 0 +0x008FB1A5 0x4F8E # 0 +0x008FB1A6 0x4F90 # 0 +0x008FB1A7 0x4F92 # 0 +0x008FB1A8 0x4F93 # 0 +0x008FB1A9 0x4F94 # 0 +0x008FB1AA 0x4F97 # 0 +0x008FB1AB 0x4F99 # 0 +0x008FB1AC 0x4F9A # 0 +0x008FB1AD 0x4F9E # 0 +0x008FB1AE 0x4F9F # 0 +0x008FB1AF 0x4FB2 # 0 +0x008FB1B0 0x4FB7 # 0 +0x008FB1B1 0x4FB9 # 0 +0x008FB1B2 0x4FBB # 0 +0x008FB1B3 0x4FBC # 0 +0x008FB1B4 0x4FBD # 0 +0x008FB1B5 0x4FBE # 0 +0x008FB1B6 0x4FC0 # 0 +0x008FB1B7 0x4FC1 # 0 +0x008FB1B8 0x4FC5 # 0 +0x008FB1B9 0x4FC6 # 0 +0x008FB1BA 0x4FC8 # 0 +0x008FB1BB 0x4FC9 # 0 +0x008FB1BC 0x4FCB # 0 +0x008FB1BD 0x4FCC # 0 +0x008FB1BE 0x4FCD # 0 +0x008FB1BF 0x4FCF # 0 +0x008FB1C0 0x4FD2 # 0 +0x008FB1C1 0x4FDC # 0 +0x008FB1C2 0x4FE0 # 0 +0x008FB1C3 0x4FE2 # 0 +0x008FB1C4 0x4FF0 # 0 +0x008FB1C5 0x4FF2 # 0 +0x008FB1C6 0x4FFC # 0 +0x008FB1C7 0x4FFD # 0 +0x008FB1C8 0x4FFF # 0 +0x008FB1C9 0x5000 # 0 +0x008FB1CA 0x5001 # 0 +0x008FB1CB 0x5004 # 0 +0x008FB1CC 0x5007 # 0 +0x008FB1CD 0x500A # 0 +0x008FB1CE 0x500C # 0 +0x008FB1CF 0x500E # 0 +0x008FB1D0 0x5010 # 0 +0x008FB1D1 0x5013 # 0 +0x008FB1D2 0x5017 # 0 +0x008FB1D3 0x5018 # 0 +0x008FB1D4 0x501B # 0 +0x008FB1D5 0x501C # 0 +0x008FB1D6 0x501D # 0 +0x008FB1D7 0x501E # 0 +0x008FB1D8 0x5022 # 0 +0x008FB1D9 0x5027 # 0 +0x008FB1DA 0x502E # 0 +0x008FB1DB 0x5030 # 0 +0x008FB1DC 0x5032 # 0 +0x008FB1DD 0x5033 # 0 +0x008FB1DE 0x5035 # 0 +0x008FB1DF 0x5040 # 0 +0x008FB1E0 0x5041 # 0 +0x008FB1E1 0x5042 # 0 +0x008FB1E2 0x5045 # 0 +0x008FB1E3 0x5046 # 0 +0x008FB1E4 0x504A # 0 +0x008FB1E5 0x504C # 0 +0x008FB1E6 0x504E # 0 +0x008FB1E7 0x5051 # 0 +0x008FB1E8 0x5052 # 0 +0x008FB1E9 0x5053 # 0 +0x008FB1EA 0x5057 # 0 +0x008FB1EB 0x5059 # 0 +0x008FB1EC 0x505F # 0 +0x008FB1ED 0x5060 # 0 +0x008FB1EE 0x5062 # 0 +0x008FB1EF 0x5063 # 0 +0x008FB1F0 0x5066 # 0 +0x008FB1F1 0x5067 # 0 +0x008FB1F2 0x506A # 0 +0x008FB1F3 0x506D # 0 +0x008FB1F4 0x5070 # 0 +0x008FB1F5 0x5071 # 0 +0x008FB1F6 0x503B # 0 +0x008FB1F7 0x5081 # 0 +0x008FB1F8 0x5083 # 0 +0x008FB1F9 0x5084 # 0 +0x008FB1FA 0x5086 # 0 +0x008FB1FB 0x508A # 0 +0x008FB1FC 0x508E # 0 +0x008FB1FD 0x508F # 0 +0x008FB1FE 0x5090 # 0 +0x008FB2A1 0x5092 # 0 +0x008FB2A2 0x5093 # 0 +0x008FB2A3 0x5094 # 0 +0x008FB2A4 0x5096 # 0 +0x008FB2A5 0x509B # 0 +0x008FB2A6 0x509C # 0 +0x008FB2A7 0x509E # 0 +0x008FB2A8 0x509F # 0 +0x008FB2A9 0x50A0 # 0 +0x008FB2AA 0x50A1 # 0 +0x008FB2AB 0x50A2 # 0 +0x008FB2AC 0x50AA # 0 +0x008FB2AD 0x50AF # 0 +0x008FB2AE 0x50B0 # 0 +0x008FB2AF 0x50B9 # 0 +0x008FB2B0 0x50BA # 0 +0x008FB2B1 0x50BD # 0 +0x008FB2B2 0x50C0 # 0 +0x008FB2B3 0x50C3 # 0 +0x008FB2B4 0x50C4 # 0 +0x008FB2B5 0x50C7 # 0 +0x008FB2B6 0x50CC # 0 +0x008FB2B7 0x50CE # 0 +0x008FB2B8 0x50D0 # 0 +0x008FB2B9 0x50D3 # 0 +0x008FB2BA 0x50D4 # 0 +0x008FB2BB 0x50D8 # 0 +0x008FB2BC 0x50DC # 0 +0x008FB2BD 0x50DD # 0 +0x008FB2BE 0x50DF # 0 +0x008FB2BF 0x50E2 # 0 +0x008FB2C0 0x50E4 # 0 +0x008FB2C1 0x50E6 # 0 +0x008FB2C2 0x50E8 # 0 +0x008FB2C3 0x50E9 # 0 +0x008FB2C4 0x50EF # 0 +0x008FB2C5 0x50F1 # 0 +0x008FB2C6 0x50F6 # 0 +0x008FB2C7 0x50FA # 0 +0x008FB2C8 0x50FE # 0 +0x008FB2C9 0x5103 # 0 +0x008FB2CA 0x5106 # 0 +0x008FB2CB 0x5107 # 0 +0x008FB2CC 0x5108 # 0 +0x008FB2CD 0x510B # 0 +0x008FB2CE 0x510C # 0 +0x008FB2CF 0x510D # 0 +0x008FB2D0 0x510E # 0 +0x008FB2D1 0x50F2 # 0 +0x008FB2D2 0x5110 # 0 +0x008FB2D3 0x5117 # 0 +0x008FB2D4 0x5119 # 0 +0x008FB2D5 0x511B # 0 +0x008FB2D6 0x511C # 0 +0x008FB2D7 0x511D # 0 +0x008FB2D8 0x511E # 0 +0x008FB2D9 0x5123 # 0 +0x008FB2DA 0x5127 # 0 +0x008FB2DB 0x5128 # 0 +0x008FB2DC 0x512C # 0 +0x008FB2DD 0x512D # 0 +0x008FB2DE 0x512F # 0 +0x008FB2DF 0x5131 # 0 +0x008FB2E0 0x5133 # 0 +0x008FB2E1 0x5134 # 0 +0x008FB2E2 0x5135 # 0 +0x008FB2E3 0x5138 # 0 +0x008FB2E4 0x5139 # 0 +0x008FB2E5 0x5142 # 0 +0x008FB2E6 0x514A # 0 +0x008FB2E7 0x514F # 0 +0x008FB2E8 0x5153 # 0 +0x008FB2E9 0x5155 # 0 +0x008FB2EA 0x5157 # 0 +0x008FB2EB 0x5158 # 0 +0x008FB2EC 0x515F # 0 +0x008FB2ED 0x5164 # 0 +0x008FB2EE 0x5166 # 0 +0x008FB2EF 0x517E # 0 +0x008FB2F0 0x5183 # 0 +0x008FB2F1 0x5184 # 0 +0x008FB2F2 0x518B # 0 +0x008FB2F3 0x518E # 0 +0x008FB2F4 0x5198 # 0 +0x008FB2F5 0x519D # 0 +0x008FB2F6 0x51A1 # 0 +0x008FB2F7 0x51A3 # 0 +0x008FB2F8 0x51AD # 0 +0x008FB2F9 0x51B8 # 0 +0x008FB2FA 0x51BA # 0 +0x008FB2FB 0x51BC # 0 +0x008FB2FC 0x51BE # 0 +0x008FB2FD 0x51BF # 0 +0x008FB2FE 0x51C2 # 0 +0x008FB3A1 0x51C8 # 0 +0x008FB3A2 0x51CF # 0 +0x008FB3A3 0x51D1 # 0 +0x008FB3A4 0x51D2 # 0 +0x008FB3A5 0x51D3 # 0 +0x008FB3A6 0x51D5 # 0 +0x008FB3A7 0x51D8 # 0 +0x008FB3A8 0x51DE # 0 +0x008FB3A9 0x51E2 # 0 +0x008FB3AA 0x51E5 # 0 +0x008FB3AB 0x51EE # 0 +0x008FB3AC 0x51F2 # 0 +0x008FB3AD 0x51F3 # 0 +0x008FB3AE 0x51F4 # 0 +0x008FB3AF 0x51F7 # 0 +0x008FB3B0 0x5201 # 0 +0x008FB3B1 0x5202 # 0 +0x008FB3B2 0x5205 # 0 +0x008FB3B3 0x5212 # 0 +0x008FB3B4 0x5213 # 0 +0x008FB3B5 0x5215 # 0 +0x008FB3B6 0x5216 # 0 +0x008FB3B7 0x5218 # 0 +0x008FB3B8 0x5222 # 0 +0x008FB3B9 0x5228 # 0 +0x008FB3BA 0x5231 # 0 +0x008FB3BB 0x5232 # 0 +0x008FB3BC 0x5235 # 0 +0x008FB3BD 0x523C # 0 +0x008FB3BE 0x5245 # 0 +0x008FB3BF 0x5249 # 0 +0x008FB3C0 0x5255 # 0 +0x008FB3C1 0x5257 # 0 +0x008FB3C2 0x5258 # 0 +0x008FB3C3 0x525A # 0 +0x008FB3C4 0x525C # 0 +0x008FB3C5 0x525F # 0 +0x008FB3C6 0x5260 # 0 +0x008FB3C7 0x5261 # 0 +0x008FB3C8 0x5266 # 0 +0x008FB3C9 0x526E # 0 +0x008FB3CA 0x5277 # 0 +0x008FB3CB 0x5278 # 0 +0x008FB3CC 0x5279 # 0 +0x008FB3CD 0x5280 # 0 +0x008FB3CE 0x5282 # 0 +0x008FB3CF 0x5285 # 0 +0x008FB3D0 0x528A # 0 +0x008FB3D1 0x528C # 0 +0x008FB3D2 0x5293 # 0 +0x008FB3D3 0x5295 # 0 +0x008FB3D4 0x5296 # 0 +0x008FB3D5 0x5297 # 0 +0x008FB3D6 0x5298 # 0 +0x008FB3D7 0x529A # 0 +0x008FB3D8 0x529C # 0 +0x008FB3D9 0x52A4 # 0 +0x008FB3DA 0x52A5 # 0 +0x008FB3DB 0x52A6 # 0 +0x008FB3DC 0x52A7 # 0 +0x008FB3DD 0x52AF # 0 +0x008FB3DE 0x52B0 # 0 +0x008FB3DF 0x52B6 # 0 +0x008FB3E0 0x52B7 # 0 +0x008FB3E1 0x52B8 # 0 +0x008FB3E2 0x52BA # 0 +0x008FB3E3 0x52BB # 0 +0x008FB3E4 0x52BD # 0 +0x008FB3E5 0x52C0 # 0 +0x008FB3E6 0x52C4 # 0 +0x008FB3E7 0x52C6 # 0 +0x008FB3E8 0x52C8 # 0 +0x008FB3E9 0x52CC # 0 +0x008FB3EA 0x52CF # 0 +0x008FB3EB 0x52D1 # 0 +0x008FB3EC 0x52D4 # 0 +0x008FB3ED 0x52D6 # 0 +0x008FB3EE 0x52DB # 0 +0x008FB3EF 0x52DC # 0 +0x008FB3F0 0x52E1 # 0 +0x008FB3F1 0x52E5 # 0 +0x008FB3F2 0x52E8 # 0 +0x008FB3F3 0x52E9 # 0 +0x008FB3F4 0x52EA # 0 +0x008FB3F5 0x52EC # 0 +0x008FB3F6 0x52F0 # 0 +0x008FB3F7 0x52F1 # 0 +0x008FB3F8 0x52F4 # 0 +0x008FB3F9 0x52F6 # 0 +0x008FB3FA 0x52F7 # 0 +0x008FB3FB 0x5300 # 0 +0x008FB3FC 0x5303 # 0 +0x008FB3FD 0x530A # 0 +0x008FB3FE 0x530B # 0 +0x008FB4A1 0x530C # 0 +0x008FB4A2 0x5311 # 0 +0x008FB4A3 0x5313 # 0 +0x008FB4A4 0x5318 # 0 +0x008FB4A5 0x531B # 0 +0x008FB4A6 0x531C # 0 +0x008FB4A7 0x531E # 0 +0x008FB4A8 0x531F # 0 +0x008FB4A9 0x5325 # 0 +0x008FB4AA 0x5327 # 0 +0x008FB4AB 0x5328 # 0 +0x008FB4AC 0x5329 # 0 +0x008FB4AD 0x532B # 0 +0x008FB4AE 0x532C # 0 +0x008FB4AF 0x532D # 0 +0x008FB4B0 0x5330 # 0 +0x008FB4B1 0x5332 # 0 +0x008FB4B2 0x5335 # 0 +0x008FB4B3 0x533C # 0 +0x008FB4B4 0x533D # 0 +0x008FB4B5 0x533E # 0 +0x008FB4B6 0x5342 # 0 +0x008FB4B7 0x534C # 0 +0x008FB4B8 0x534B # 0 +0x008FB4B9 0x5359 # 0 +0x008FB4BA 0x535B # 0 +0x008FB4BB 0x5361 # 0 +0x008FB4BC 0x5363 # 0 +0x008FB4BD 0x5365 # 0 +0x008FB4BE 0x536C # 0 +0x008FB4BF 0x536D # 0 +0x008FB4C0 0x5372 # 0 +0x008FB4C1 0x5379 # 0 +0x008FB4C2 0x537E # 0 +0x008FB4C3 0x5383 # 0 +0x008FB4C4 0x5387 # 0 +0x008FB4C5 0x5388 # 0 +0x008FB4C6 0x538E # 0 +0x008FB4C7 0x5393 # 0 +0x008FB4C8 0x5394 # 0 +0x008FB4C9 0x5399 # 0 +0x008FB4CA 0x539D # 0 +0x008FB4CB 0x53A1 # 0 +0x008FB4CC 0x53A4 # 0 +0x008FB4CD 0x53AA # 0 +0x008FB4CE 0x53AB # 0 +0x008FB4CF 0x53AF # 0 +0x008FB4D0 0x53B2 # 0 +0x008FB4D1 0x53B4 # 0 +0x008FB4D2 0x53B5 # 0 +0x008FB4D3 0x53B7 # 0 +0x008FB4D4 0x53B8 # 0 +0x008FB4D5 0x53BA # 0 +0x008FB4D6 0x53BD # 0 +0x008FB4D7 0x53C0 # 0 +0x008FB4D8 0x53C5 # 0 +0x008FB4D9 0x53CF # 0 +0x008FB4DA 0x53D2 # 0 +0x008FB4DB 0x53D3 # 0 +0x008FB4DC 0x53D5 # 0 +0x008FB4DD 0x53DA # 0 +0x008FB4DE 0x53DD # 0 +0x008FB4DF 0x53DE # 0 +0x008FB4E0 0x53E0 # 0 +0x008FB4E1 0x53E6 # 0 +0x008FB4E2 0x53E7 # 0 +0x008FB4E3 0x53F5 # 0 +0x008FB4E4 0x5402 # 0 +0x008FB4E5 0x5413 # 0 +0x008FB4E6 0x541A # 0 +0x008FB4E7 0x5421 # 0 +0x008FB4E8 0x5427 # 0 +0x008FB4E9 0x5428 # 0 +0x008FB4EA 0x542A # 0 +0x008FB4EB 0x542F # 0 +0x008FB4EC 0x5431 # 0 +0x008FB4ED 0x5434 # 0 +0x008FB4EE 0x5435 # 0 +0x008FB4EF 0x5443 # 0 +0x008FB4F0 0x5444 # 0 +0x008FB4F1 0x5447 # 0 +0x008FB4F2 0x544D # 0 +0x008FB4F3 0x544F # 0 +0x008FB4F4 0x545E # 0 +0x008FB4F5 0x5462 # 0 +0x008FB4F6 0x5464 # 0 +0x008FB4F7 0x5466 # 0 +0x008FB4F8 0x5467 # 0 +0x008FB4F9 0x5469 # 0 +0x008FB4FA 0x546B # 0 +0x008FB4FB 0x546D # 0 +0x008FB4FC 0x546E # 0 +0x008FB4FD 0x5474 # 0 +0x008FB4FE 0x547F # 0 +0x008FB5A1 0x5481 # 0 +0x008FB5A2 0x5483 # 0 +0x008FB5A3 0x5485 # 0 +0x008FB5A4 0x5488 # 0 +0x008FB5A5 0x5489 # 0 +0x008FB5A6 0x548D # 0 +0x008FB5A7 0x5491 # 0 +0x008FB5A8 0x5495 # 0 +0x008FB5A9 0x5496 # 0 +0x008FB5AA 0x549C # 0 +0x008FB5AB 0x549F # 0 +0x008FB5AC 0x54A1 # 0 +0x008FB5AD 0x54A6 # 0 +0x008FB5AE 0x54A7 # 0 +0x008FB5AF 0x54A9 # 0 +0x008FB5B0 0x54AA # 0 +0x008FB5B1 0x54AD # 0 +0x008FB5B2 0x54AE # 0 +0x008FB5B3 0x54B1 # 0 +0x008FB5B4 0x54B7 # 0 +0x008FB5B5 0x54B9 # 0 +0x008FB5B6 0x54BA # 0 +0x008FB5B7 0x54BB # 0 +0x008FB5B8 0x54BF # 0 +0x008FB5B9 0x54C6 # 0 +0x008FB5BA 0x54CA # 0 +0x008FB5BB 0x54CD # 0 +0x008FB5BC 0x54CE # 0 +0x008FB5BD 0x54E0 # 0 +0x008FB5BE 0x54EA # 0 +0x008FB5BF 0x54EC # 0 +0x008FB5C0 0x54EF # 0 +0x008FB5C1 0x54F6 # 0 +0x008FB5C2 0x54FC # 0 +0x008FB5C3 0x54FE # 0 +0x008FB5C4 0x54FF # 0 +0x008FB5C5 0x5500 # 0 +0x008FB5C6 0x5501 # 0 +0x008FB5C7 0x5505 # 0 +0x008FB5C8 0x5508 # 0 +0x008FB5C9 0x5509 # 0 +0x008FB5CA 0x550C # 0 +0x008FB5CB 0x550D # 0 +0x008FB5CC 0x550E # 0 +0x008FB5CD 0x5515 # 0 +0x008FB5CE 0x552A # 0 +0x008FB5CF 0x552B # 0 +0x008FB5D0 0x5532 # 0 +0x008FB5D1 0x5535 # 0 +0x008FB5D2 0x5536 # 0 +0x008FB5D3 0x553B # 0 +0x008FB5D4 0x553C # 0 +0x008FB5D5 0x553D # 0 +0x008FB5D6 0x5541 # 0 +0x008FB5D7 0x5547 # 0 +0x008FB5D8 0x5549 # 0 +0x008FB5D9 0x554A # 0 +0x008FB5DA 0x554D # 0 +0x008FB5DB 0x5550 # 0 +0x008FB5DC 0x5551 # 0 +0x008FB5DD 0x5558 # 0 +0x008FB5DE 0x555A # 0 +0x008FB5DF 0x555B # 0 +0x008FB5E0 0x555E # 0 +0x008FB5E1 0x5560 # 0 +0x008FB5E2 0x5561 # 0 +0x008FB5E3 0x5564 # 0 +0x008FB5E4 0x5566 # 0 +0x008FB5E5 0x557F # 0 +0x008FB5E6 0x5581 # 0 +0x008FB5E7 0x5582 # 0 +0x008FB5E8 0x5586 # 0 +0x008FB5E9 0x5588 # 0 +0x008FB5EA 0x558E # 0 +0x008FB5EB 0x558F # 0 +0x008FB5EC 0x5591 # 0 +0x008FB5ED 0x5592 # 0 +0x008FB5EE 0x5593 # 0 +0x008FB5EF 0x5594 # 0 +0x008FB5F0 0x5597 # 0 +0x008FB5F1 0x55A3 # 0 +0x008FB5F2 0x55A4 # 0 +0x008FB5F3 0x55AD # 0 +0x008FB5F4 0x55B2 # 0 +0x008FB5F5 0x55BF # 0 +0x008FB5F6 0x55C1 # 0 +0x008FB5F7 0x55C3 # 0 +0x008FB5F8 0x55C6 # 0 +0x008FB5F9 0x55C9 # 0 +0x008FB5FA 0x55CB # 0 +0x008FB5FB 0x55CC # 0 +0x008FB5FC 0x55CE # 0 +0x008FB5FD 0x55D1 # 0 +0x008FB5FE 0x55D2 # 0 +0x008FB6A1 0x55D3 # 0 +0x008FB6A2 0x55D7 # 0 +0x008FB6A3 0x55D8 # 0 +0x008FB6A4 0x55DB # 0 +0x008FB6A5 0x55DE # 0 +0x008FB6A6 0x55E2 # 0 +0x008FB6A7 0x55E9 # 0 +0x008FB6A8 0x55F6 # 0 +0x008FB6A9 0x55FF # 0 +0x008FB6AA 0x5605 # 0 +0x008FB6AB 0x5608 # 0 +0x008FB6AC 0x560A # 0 +0x008FB6AD 0x560D # 0 +0x008FB6AE 0x560E # 0 +0x008FB6AF 0x560F # 0 +0x008FB6B0 0x5610 # 0 +0x008FB6B1 0x5611 # 0 +0x008FB6B2 0x5612 # 0 +0x008FB6B3 0x5619 # 0 +0x008FB6B4 0x562C # 0 +0x008FB6B5 0x5630 # 0 +0x008FB6B6 0x5633 # 0 +0x008FB6B7 0x5635 # 0 +0x008FB6B8 0x5637 # 0 +0x008FB6B9 0x5639 # 0 +0x008FB6BA 0x563B # 0 +0x008FB6BB 0x563C # 0 +0x008FB6BC 0x563D # 0 +0x008FB6BD 0x563F # 0 +0x008FB6BE 0x5640 # 0 +0x008FB6BF 0x5641 # 0 +0x008FB6C0 0x5643 # 0 +0x008FB6C1 0x5644 # 0 +0x008FB6C2 0x5646 # 0 +0x008FB6C3 0x5649 # 0 +0x008FB6C4 0x564B # 0 +0x008FB6C5 0x564D # 0 +0x008FB6C6 0x564F # 0 +0x008FB6C7 0x5654 # 0 +0x008FB6C8 0x565E # 0 +0x008FB6C9 0x5660 # 0 +0x008FB6CA 0x5661 # 0 +0x008FB6CB 0x5662 # 0 +0x008FB6CC 0x5663 # 0 +0x008FB6CD 0x5666 # 0 +0x008FB6CE 0x5669 # 0 +0x008FB6CF 0x566D # 0 +0x008FB6D0 0x566F # 0 +0x008FB6D1 0x5671 # 0 +0x008FB6D2 0x5672 # 0 +0x008FB6D3 0x5675 # 0 +0x008FB6D4 0x5684 # 0 +0x008FB6D5 0x5685 # 0 +0x008FB6D6 0x5688 # 0 +0x008FB6D7 0x568B # 0 +0x008FB6D8 0x568C # 0 +0x008FB6D9 0x5695 # 0 +0x008FB6DA 0x5699 # 0 +0x008FB6DB 0x569A # 0 +0x008FB6DC 0x569D # 0 +0x008FB6DD 0x569E # 0 +0x008FB6DE 0x569F # 0 +0x008FB6DF 0x56A6 # 0 +0x008FB6E0 0x56A7 # 0 +0x008FB6E1 0x56A8 # 0 +0x008FB6E2 0x56A9 # 0 +0x008FB6E3 0x56AB # 0 +0x008FB6E4 0x56AC # 0 +0x008FB6E5 0x56AD # 0 +0x008FB6E6 0x56B1 # 0 +0x008FB6E7 0x56B3 # 0 +0x008FB6E8 0x56B7 # 0 +0x008FB6E9 0x56BE # 0 +0x008FB6EA 0x56C5 # 0 +0x008FB6EB 0x56C9 # 0 +0x008FB6EC 0x56CA # 0 +0x008FB6ED 0x56CB # 0 +0x008FB6EE 0x56CF # 0 +0x008FB6EF 0x56D0 # 0 +0x008FB6F0 0x56CC # 0 +0x008FB6F1 0x56CD # 0 +0x008FB6F2 0x56D9 # 0 +0x008FB6F3 0x56DC # 0 +0x008FB6F4 0x56DD # 0 +0x008FB6F5 0x56DF # 0 +0x008FB6F6 0x56E1 # 0 +0x008FB6F7 0x56E4 # 0 +0x008FB6F8 0x56E5 # 0 +0x008FB6F9 0x56E6 # 0 +0x008FB6FA 0x56E7 # 0 +0x008FB6FB 0x56E8 # 0 +0x008FB6FC 0x56F1 # 0 +0x008FB6FD 0x56EB # 0 +0x008FB6FE 0x56ED # 0 +0x008FB7A1 0x56F6 # 0 +0x008FB7A2 0x56F7 # 0 +0x008FB7A3 0x5701 # 0 +0x008FB7A4 0x5702 # 0 +0x008FB7A5 0x5707 # 0 +0x008FB7A6 0x570A # 0 +0x008FB7A7 0x570C # 0 +0x008FB7A8 0x5711 # 0 +0x008FB7A9 0x5715 # 0 +0x008FB7AA 0x571A # 0 +0x008FB7AB 0x571B # 0 +0x008FB7AC 0x571D # 0 +0x008FB7AD 0x5720 # 0 +0x008FB7AE 0x5722 # 0 +0x008FB7AF 0x5723 # 0 +0x008FB7B0 0x5724 # 0 +0x008FB7B1 0x5725 # 0 +0x008FB7B2 0x5729 # 0 +0x008FB7B3 0x572A # 0 +0x008FB7B4 0x572C # 0 +0x008FB7B5 0x572E # 0 +0x008FB7B6 0x572F # 0 +0x008FB7B7 0x5733 # 0 +0x008FB7B8 0x5734 # 0 +0x008FB7B9 0x573D # 0 +0x008FB7BA 0x573E # 0 +0x008FB7BB 0x573F # 0 +0x008FB7BC 0x5745 # 0 +0x008FB7BD 0x5746 # 0 +0x008FB7BE 0x574C # 0 +0x008FB7BF 0x574D # 0 +0x008FB7C0 0x5752 # 0 +0x008FB7C1 0x5762 # 0 +0x008FB7C2 0x5765 # 0 +0x008FB7C3 0x5767 # 0 +0x008FB7C4 0x5768 # 0 +0x008FB7C5 0x576B # 0 +0x008FB7C6 0x576D # 0 +0x008FB7C7 0x576E # 0 +0x008FB7C8 0x576F # 0 +0x008FB7C9 0x5770 # 0 +0x008FB7CA 0x5771 # 0 +0x008FB7CB 0x5773 # 0 +0x008FB7CC 0x5774 # 0 +0x008FB7CD 0x5775 # 0 +0x008FB7CE 0x5777 # 0 +0x008FB7CF 0x5779 # 0 +0x008FB7D0 0x577A # 0 +0x008FB7D1 0x577B # 0 +0x008FB7D2 0x577C # 0 +0x008FB7D3 0x577E # 0 +0x008FB7D4 0x5781 # 0 +0x008FB7D5 0x5783 # 0 +0x008FB7D6 0x578C # 0 +0x008FB7D7 0x5794 # 0 +0x008FB7D8 0x5797 # 0 +0x008FB7D9 0x5799 # 0 +0x008FB7DA 0x579A # 0 +0x008FB7DB 0x579C # 0 +0x008FB7DC 0x579D # 0 +0x008FB7DD 0x579E # 0 +0x008FB7DE 0x579F # 0 +0x008FB7DF 0x57A1 # 0 +0x008FB7E0 0x5795 # 0 +0x008FB7E1 0x57A7 # 0 +0x008FB7E2 0x57A8 # 0 +0x008FB7E3 0x57A9 # 0 +0x008FB7E4 0x57AC # 0 +0x008FB7E5 0x57B8 # 0 +0x008FB7E6 0x57BD # 0 +0x008FB7E7 0x57C7 # 0 +0x008FB7E8 0x57C8 # 0 +0x008FB7E9 0x57CC # 0 +0x008FB7EA 0x57CF # 0 +0x008FB7EB 0x57D5 # 0 +0x008FB7EC 0x57DD # 0 +0x008FB7ED 0x57DE # 0 +0x008FB7EE 0x57E4 # 0 +0x008FB7EF 0x57E6 # 0 +0x008FB7F0 0x57E7 # 0 +0x008FB7F1 0x57E9 # 0 +0x008FB7F2 0x57ED # 0 +0x008FB7F3 0x57F0 # 0 +0x008FB7F4 0x57F5 # 0 +0x008FB7F5 0x57F6 # 0 +0x008FB7F6 0x57F8 # 0 +0x008FB7F7 0x57FD # 0 +0x008FB7F8 0x57FE # 0 +0x008FB7F9 0x57FF # 0 +0x008FB7FA 0x5803 # 0 +0x008FB7FB 0x5804 # 0 +0x008FB7FC 0x5808 # 0 +0x008FB7FD 0x5809 # 0 +0x008FB7FE 0x57E1 # 0 +0x008FB8A1 0x580C # 0 +0x008FB8A2 0x580D # 0 +0x008FB8A3 0x581B # 0 +0x008FB8A4 0x581E # 0 +0x008FB8A5 0x581F # 0 +0x008FB8A6 0x5820 # 0 +0x008FB8A7 0x5826 # 0 +0x008FB8A8 0x5827 # 0 +0x008FB8A9 0x582D # 0 +0x008FB8AA 0x5832 # 0 +0x008FB8AB 0x5839 # 0 +0x008FB8AC 0x583F # 0 +0x008FB8AD 0x5849 # 0 +0x008FB8AE 0x584C # 0 +0x008FB8AF 0x584D # 0 +0x008FB8B0 0x584F # 0 +0x008FB8B1 0x5850 # 0 +0x008FB8B2 0x5855 # 0 +0x008FB8B3 0x585F # 0 +0x008FB8B4 0x5861 # 0 +0x008FB8B5 0x5864 # 0 +0x008FB8B6 0x5867 # 0 +0x008FB8B7 0x5868 # 0 +0x008FB8B8 0x5878 # 0 +0x008FB8B9 0x587C # 0 +0x008FB8BA 0x587F # 0 +0x008FB8BB 0x5880 # 0 +0x008FB8BC 0x5881 # 0 +0x008FB8BD 0x5887 # 0 +0x008FB8BE 0x5888 # 0 +0x008FB8BF 0x5889 # 0 +0x008FB8C0 0x588A # 0 +0x008FB8C1 0x588C # 0 +0x008FB8C2 0x588D # 0 +0x008FB8C3 0x588F # 0 +0x008FB8C4 0x5890 # 0 +0x008FB8C5 0x5894 # 0 +0x008FB8C6 0x5896 # 0 +0x008FB8C7 0x589D # 0 +0x008FB8C8 0x58A0 # 0 +0x008FB8C9 0x58A1 # 0 +0x008FB8CA 0x58A2 # 0 +0x008FB8CB 0x58A6 # 0 +0x008FB8CC 0x58A9 # 0 +0x008FB8CD 0x58B1 # 0 +0x008FB8CE 0x58B2 # 0 +0x008FB8CF 0x58C4 # 0 +0x008FB8D0 0x58BC # 0 +0x008FB8D1 0x58C2 # 0 +0x008FB8D2 0x58C8 # 0 +0x008FB8D3 0x58CD # 0 +0x008FB8D4 0x58CE # 0 +0x008FB8D5 0x58D0 # 0 +0x008FB8D6 0x58D2 # 0 +0x008FB8D7 0x58D4 # 0 +0x008FB8D8 0x58D6 # 0 +0x008FB8D9 0x58DA # 0 +0x008FB8DA 0x58DD # 0 +0x008FB8DB 0x58E1 # 0 +0x008FB8DC 0x58E2 # 0 +0x008FB8DD 0x58E9 # 0 +0x008FB8DE 0x58F3 # 0 +0x008FB8DF 0x5905 # 0 +0x008FB8E0 0x5906 # 0 +0x008FB8E1 0x590B # 0 +0x008FB8E2 0x590C # 0 +0x008FB8E3 0x5912 # 0 +0x008FB8E4 0x5913 # 0 +0x008FB8E5 0x5914 # 0 +0x008FB8E6 0x8641 # 0 +0x008FB8E7 0x591D # 0 +0x008FB8E8 0x5921 # 0 +0x008FB8E9 0x5923 # 0 +0x008FB8EA 0x5924 # 0 +0x008FB8EB 0x5928 # 0 +0x008FB8EC 0x592F # 0 +0x008FB8ED 0x5930 # 0 +0x008FB8EE 0x5933 # 0 +0x008FB8EF 0x5935 # 0 +0x008FB8F0 0x5936 # 0 +0x008FB8F1 0x593F # 0 +0x008FB8F2 0x5943 # 0 +0x008FB8F3 0x5946 # 0 +0x008FB8F4 0x5952 # 0 +0x008FB8F5 0x5953 # 0 +0x008FB8F6 0x5959 # 0 +0x008FB8F7 0x595B # 0 +0x008FB8F8 0x595D # 0 +0x008FB8F9 0x595E # 0 +0x008FB8FA 0x595F # 0 +0x008FB8FB 0x5961 # 0 +0x008FB8FC 0x5963 # 0 +0x008FB8FD 0x596B # 0 +0x008FB8FE 0x596D # 0 +0x008FB9A1 0x596F # 0 +0x008FB9A2 0x5972 # 0 +0x008FB9A3 0x5975 # 0 +0x008FB9A4 0x5976 # 0 +0x008FB9A5 0x5979 # 0 +0x008FB9A6 0x597B # 0 +0x008FB9A7 0x597C # 0 +0x008FB9A8 0x598B # 0 +0x008FB9A9 0x598C # 0 +0x008FB9AA 0x598E # 0 +0x008FB9AB 0x5992 # 0 +0x008FB9AC 0x5995 # 0 +0x008FB9AD 0x5997 # 0 +0x008FB9AE 0x599F # 0 +0x008FB9AF 0x59A4 # 0 +0x008FB9B0 0x59A7 # 0 +0x008FB9B1 0x59AD # 0 +0x008FB9B2 0x59AE # 0 +0x008FB9B3 0x59AF # 0 +0x008FB9B4 0x59B0 # 0 +0x008FB9B5 0x59B3 # 0 +0x008FB9B6 0x59B7 # 0 +0x008FB9B7 0x59BA # 0 +0x008FB9B8 0x59BC # 0 +0x008FB9B9 0x59C1 # 0 +0x008FB9BA 0x59C3 # 0 +0x008FB9BB 0x59C4 # 0 +0x008FB9BC 0x59C8 # 0 +0x008FB9BD 0x59CA # 0 +0x008FB9BE 0x59CD # 0 +0x008FB9BF 0x59D2 # 0 +0x008FB9C0 0x59DD # 0 +0x008FB9C1 0x59DE # 0 +0x008FB9C2 0x59DF # 0 +0x008FB9C3 0x59E3 # 0 +0x008FB9C4 0x59E4 # 0 +0x008FB9C5 0x59E7 # 0 +0x008FB9C6 0x59EE # 0 +0x008FB9C7 0x59EF # 0 +0x008FB9C8 0x59F1 # 0 +0x008FB9C9 0x59F2 # 0 +0x008FB9CA 0x59F4 # 0 +0x008FB9CB 0x59F7 # 0 +0x008FB9CC 0x5A00 # 0 +0x008FB9CD 0x5A04 # 0 +0x008FB9CE 0x5A0C # 0 +0x008FB9CF 0x5A0D # 0 +0x008FB9D0 0x5A0E # 0 +0x008FB9D1 0x5A12 # 0 +0x008FB9D2 0x5A13 # 0 +0x008FB9D3 0x5A1E # 0 +0x008FB9D4 0x5A23 # 0 +0x008FB9D5 0x5A24 # 0 +0x008FB9D6 0x5A27 # 0 +0x008FB9D7 0x5A28 # 0 +0x008FB9D8 0x5A2A # 0 +0x008FB9D9 0x5A2D # 0 +0x008FB9DA 0x5A30 # 0 +0x008FB9DB 0x5A44 # 0 +0x008FB9DC 0x5A45 # 0 +0x008FB9DD 0x5A47 # 0 +0x008FB9DE 0x5A48 # 0 +0x008FB9DF 0x5A4C # 0 +0x008FB9E0 0x5A50 # 0 +0x008FB9E1 0x5A55 # 0 +0x008FB9E2 0x5A5E # 0 +0x008FB9E3 0x5A63 # 0 +0x008FB9E4 0x5A65 # 0 +0x008FB9E5 0x5A67 # 0 +0x008FB9E6 0x5A6D # 0 +0x008FB9E7 0x5A77 # 0 +0x008FB9E8 0x5A7A # 0 +0x008FB9E9 0x5A7B # 0 +0x008FB9EA 0x5A7E # 0 +0x008FB9EB 0x5A8B # 0 +0x008FB9EC 0x5A90 # 0 +0x008FB9ED 0x5A93 # 0 +0x008FB9EE 0x5A96 # 0 +0x008FB9EF 0x5A99 # 0 +0x008FB9F0 0x5A9C # 0 +0x008FB9F1 0x5A9E # 0 +0x008FB9F2 0x5A9F # 0 +0x008FB9F3 0x5AA0 # 0 +0x008FB9F4 0x5AA2 # 0 +0x008FB9F5 0x5AA7 # 0 +0x008FB9F6 0x5AAC # 0 +0x008FB9F7 0x5AB1 # 0 +0x008FB9F8 0x5AB2 # 0 +0x008FB9F9 0x5AB3 # 0 +0x008FB9FA 0x5AB5 # 0 +0x008FB9FB 0x5AB8 # 0 +0x008FB9FC 0x5ABA # 0 +0x008FB9FD 0x5ABB # 0 +0x008FB9FE 0x5ABF # 0 +0x008FBAA1 0x5AC4 # 0 +0x008FBAA2 0x5AC6 # 0 +0x008FBAA3 0x5AC8 # 0 +0x008FBAA4 0x5ACF # 0 +0x008FBAA5 0x5ADA # 0 +0x008FBAA6 0x5ADC # 0 +0x008FBAA7 0x5AE0 # 0 +0x008FBAA8 0x5AE5 # 0 +0x008FBAA9 0x5AEA # 0 +0x008FBAAA 0x5AEE # 0 +0x008FBAAB 0x5AF5 # 0 +0x008FBAAC 0x5AF6 # 0 +0x008FBAAD 0x5AFD # 0 +0x008FBAAE 0x5B00 # 0 +0x008FBAAF 0x5B01 # 0 +0x008FBAB0 0x5B08 # 0 +0x008FBAB1 0x5B17 # 0 +0x008FBAB2 0x5B34 # 0 +0x008FBAB3 0x5B19 # 0 +0x008FBAB4 0x5B1B # 0 +0x008FBAB5 0x5B1D # 0 +0x008FBAB6 0x5B21 # 0 +0x008FBAB7 0x5B25 # 0 +0x008FBAB8 0x5B2D # 0 +0x008FBAB9 0x5B38 # 0 +0x008FBABA 0x5B41 # 0 +0x008FBABB 0x5B4B # 0 +0x008FBABC 0x5B4C # 0 +0x008FBABD 0x5B52 # 0 +0x008FBABE 0x5B56 # 0 +0x008FBABF 0x5B5E # 0 +0x008FBAC0 0x5B68 # 0 +0x008FBAC1 0x5B6E # 0 +0x008FBAC2 0x5B6F # 0 +0x008FBAC3 0x5B7C # 0 +0x008FBAC4 0x5B7D # 0 +0x008FBAC5 0x5B7E # 0 +0x008FBAC6 0x5B7F # 0 +0x008FBAC7 0x5B81 # 0 +0x008FBAC8 0x5B84 # 0 +0x008FBAC9 0x5B86 # 0 +0x008FBACA 0x5B8A # 0 +0x008FBACB 0x5B8E # 0 +0x008FBACC 0x5B90 # 0 +0x008FBACD 0x5B91 # 0 +0x008FBACE 0x5B93 # 0 +0x008FBACF 0x5B94 # 0 +0x008FBAD0 0x5B96 # 0 +0x008FBAD1 0x5BA8 # 0 +0x008FBAD2 0x5BA9 # 0 +0x008FBAD3 0x5BAC # 0 +0x008FBAD4 0x5BAD # 0 +0x008FBAD5 0x5BAF # 0 +0x008FBAD6 0x5BB1 # 0 +0x008FBAD7 0x5BB2 # 0 +0x008FBAD8 0x5BB7 # 0 +0x008FBAD9 0x5BBA # 0 +0x008FBADA 0x5BBC # 0 +0x008FBADB 0x5BC0 # 0 +0x008FBADC 0x5BC1 # 0 +0x008FBADD 0x5BCD # 0 +0x008FBADE 0x5BCF # 0 +0x008FBADF 0x5BD6 # 0 +0x008FBAE0 0x5BD7 # 0 +0x008FBAE1 0x5BD8 # 0 +0x008FBAE2 0x5BD9 # 0 +0x008FBAE3 0x5BDA # 0 +0x008FBAE4 0x5BE0 # 0 +0x008FBAE5 0x5BEF # 0 +0x008FBAE6 0x5BF1 # 0 +0x008FBAE7 0x5BF4 # 0 +0x008FBAE8 0x5BFD # 0 +0x008FBAE9 0x5C0C # 0 +0x008FBAEA 0x5C17 # 0 +0x008FBAEB 0x5C1E # 0 +0x008FBAEC 0x5C1F # 0 +0x008FBAED 0x5C23 # 0 +0x008FBAEE 0x5C26 # 0 +0x008FBAEF 0x5C29 # 0 +0x008FBAF0 0x5C2B # 0 +0x008FBAF1 0x5C2C # 0 +0x008FBAF2 0x5C2E # 0 +0x008FBAF3 0x5C30 # 0 +0x008FBAF4 0x5C32 # 0 +0x008FBAF5 0x5C35 # 0 +0x008FBAF6 0x5C36 # 0 +0x008FBAF7 0x5C59 # 0 +0x008FBAF8 0x5C5A # 0 +0x008FBAF9 0x5C5C # 0 +0x008FBAFA 0x5C62 # 0 +0x008FBAFB 0x5C63 # 0 +0x008FBAFC 0x5C67 # 0 +0x008FBAFD 0x5C68 # 0 +0x008FBAFE 0x5C69 # 0 +0x008FBBA1 0x5C6D # 0 +0x008FBBA2 0x5C70 # 0 +0x008FBBA3 0x5C74 # 0 +0x008FBBA4 0x5C75 # 0 +0x008FBBA5 0x5C7A # 0 +0x008FBBA6 0x5C7B # 0 +0x008FBBA7 0x5C7C # 0 +0x008FBBA8 0x5C7D # 0 +0x008FBBA9 0x5C87 # 0 +0x008FBBAA 0x5C88 # 0 +0x008FBBAB 0x5C8A # 0 +0x008FBBAC 0x5C8F # 0 +0x008FBBAD 0x5C92 # 0 +0x008FBBAE 0x5C9D # 0 +0x008FBBAF 0x5C9F # 0 +0x008FBBB0 0x5CA0 # 0 +0x008FBBB1 0x5CA2 # 0 +0x008FBBB2 0x5CA3 # 0 +0x008FBBB3 0x5CA6 # 0 +0x008FBBB4 0x5CAA # 0 +0x008FBBB5 0x5CB2 # 0 +0x008FBBB6 0x5CB4 # 0 +0x008FBBB7 0x5CB5 # 0 +0x008FBBB8 0x5CBA # 0 +0x008FBBB9 0x5CC9 # 0 +0x008FBBBA 0x5CCB # 0 +0x008FBBBB 0x5CD2 # 0 +0x008FBBBC 0x5CDD # 0 +0x008FBBBD 0x5CD7 # 0 +0x008FBBBE 0x5CEE # 0 +0x008FBBBF 0x5CF1 # 0 +0x008FBBC0 0x5CF2 # 0 +0x008FBBC1 0x5CF4 # 0 +0x008FBBC2 0x5D01 # 0 +0x008FBBC3 0x5D06 # 0 +0x008FBBC4 0x5D0D # 0 +0x008FBBC5 0x5D12 # 0 +0x008FBBC6 0x5D2B # 0 +0x008FBBC7 0x5D23 # 0 +0x008FBBC8 0x5D24 # 0 +0x008FBBC9 0x5D26 # 0 +0x008FBBCA 0x5D27 # 0 +0x008FBBCB 0x5D31 # 0 +0x008FBBCC 0x5D34 # 0 +0x008FBBCD 0x5D39 # 0 +0x008FBBCE 0x5D3D # 0 +0x008FBBCF 0x5D3F # 0 +0x008FBBD0 0x5D42 # 0 +0x008FBBD1 0x5D43 # 0 +0x008FBBD2 0x5D46 # 0 +0x008FBBD3 0x5D48 # 0 +0x008FBBD4 0x5D55 # 0 +0x008FBBD5 0x5D51 # 0 +0x008FBBD6 0x5D59 # 0 +0x008FBBD7 0x5D4A # 0 +0x008FBBD8 0x5D5F # 0 +0x008FBBD9 0x5D60 # 0 +0x008FBBDA 0x5D61 # 0 +0x008FBBDB 0x5D62 # 0 +0x008FBBDC 0x5D64 # 0 +0x008FBBDD 0x5D6A # 0 +0x008FBBDE 0x5D6D # 0 +0x008FBBDF 0x5D70 # 0 +0x008FBBE0 0x5D79 # 0 +0x008FBBE1 0x5D7A # 0 +0x008FBBE2 0x5D7E # 0 +0x008FBBE3 0x5D7F # 0 +0x008FBBE4 0x5D81 # 0 +0x008FBBE5 0x5D83 # 0 +0x008FBBE6 0x5D88 # 0 +0x008FBBE7 0x5D8A # 0 +0x008FBBE8 0x5D92 # 0 +0x008FBBE9 0x5D93 # 0 +0x008FBBEA 0x5D94 # 0 +0x008FBBEB 0x5D95 # 0 +0x008FBBEC 0x5D99 # 0 +0x008FBBED 0x5D9B # 0 +0x008FBBEE 0x5D9F # 0 +0x008FBBEF 0x5DA0 # 0 +0x008FBBF0 0x5DA7 # 0 +0x008FBBF1 0x5DAB # 0 +0x008FBBF2 0x5DB0 # 0 +0x008FBBF3 0x5DB4 # 0 +0x008FBBF4 0x5DB8 # 0 +0x008FBBF5 0x5DB9 # 0 +0x008FBBF6 0x5DC3 # 0 +0x008FBBF7 0x5DC7 # 0 +0x008FBBF8 0x5DCB # 0 +0x008FBBF9 0x5DD0 # 0 +0x008FBBFA 0x5DCE # 0 +0x008FBBFB 0x5DD8 # 0 +0x008FBBFC 0x5DD9 # 0 +0x008FBBFD 0x5DE0 # 0 +0x008FBBFE 0x5DE4 # 0 +0x008FBCA1 0x5DE9 # 0 +0x008FBCA2 0x5DF8 # 0 +0x008FBCA3 0x5DF9 # 0 +0x008FBCA4 0x5E00 # 0 +0x008FBCA5 0x5E07 # 0 +0x008FBCA6 0x5E0D # 0 +0x008FBCA7 0x5E12 # 0 +0x008FBCA8 0x5E14 # 0 +0x008FBCA9 0x5E15 # 0 +0x008FBCAA 0x5E18 # 0 +0x008FBCAB 0x5E1F # 0 +0x008FBCAC 0x5E20 # 0 +0x008FBCAD 0x5E2E # 0 +0x008FBCAE 0x5E28 # 0 +0x008FBCAF 0x5E32 # 0 +0x008FBCB0 0x5E35 # 0 +0x008FBCB1 0x5E3E # 0 +0x008FBCB2 0x5E4B # 0 +0x008FBCB3 0x5E50 # 0 +0x008FBCB4 0x5E49 # 0 +0x008FBCB5 0x5E51 # 0 +0x008FBCB6 0x5E56 # 0 +0x008FBCB7 0x5E58 # 0 +0x008FBCB8 0x5E5B # 0 +0x008FBCB9 0x5E5C # 0 +0x008FBCBA 0x5E5E # 0 +0x008FBCBB 0x5E68 # 0 +0x008FBCBC 0x5E6A # 0 +0x008FBCBD 0x5E6B # 0 +0x008FBCBE 0x5E6C # 0 +0x008FBCBF 0x5E6D # 0 +0x008FBCC0 0x5E6E # 0 +0x008FBCC1 0x5E70 # 0 +0x008FBCC2 0x5E80 # 0 +0x008FBCC3 0x5E8B # 0 +0x008FBCC4 0x5E8E # 0 +0x008FBCC5 0x5EA2 # 0 +0x008FBCC6 0x5EA4 # 0 +0x008FBCC7 0x5EA5 # 0 +0x008FBCC8 0x5EA8 # 0 +0x008FBCC9 0x5EAA # 0 +0x008FBCCA 0x5EAC # 0 +0x008FBCCB 0x5EB1 # 0 +0x008FBCCC 0x5EB3 # 0 +0x008FBCCD 0x5EBD # 0 +0x008FBCCE 0x5EBE # 0 +0x008FBCCF 0x5EBF # 0 +0x008FBCD0 0x5EC6 # 0 +0x008FBCD1 0x5ECC # 0 +0x008FBCD2 0x5ECB # 0 +0x008FBCD3 0x5ECE # 0 +0x008FBCD4 0x5ED1 # 0 +0x008FBCD5 0x5ED2 # 0 +0x008FBCD6 0x5ED4 # 0 +0x008FBCD7 0x5ED5 # 0 +0x008FBCD8 0x5EDC # 0 +0x008FBCD9 0x5EDE # 0 +0x008FBCDA 0x5EE5 # 0 +0x008FBCDB 0x5EEB # 0 +0x008FBCDC 0x5F02 # 0 +0x008FBCDD 0x5F06 # 0 +0x008FBCDE 0x5F07 # 0 +0x008FBCDF 0x5F08 # 0 +0x008FBCE0 0x5F0E # 0 +0x008FBCE1 0x5F19 # 0 +0x008FBCE2 0x5F1C # 0 +0x008FBCE3 0x5F1D # 0 +0x008FBCE4 0x5F21 # 0 +0x008FBCE5 0x5F22 # 0 +0x008FBCE6 0x5F23 # 0 +0x008FBCE7 0x5F24 # 0 +0x008FBCE8 0x5F28 # 0 +0x008FBCE9 0x5F2B # 0 +0x008FBCEA 0x5F2C # 0 +0x008FBCEB 0x5F2E # 0 +0x008FBCEC 0x5F30 # 0 +0x008FBCED 0x5F34 # 0 +0x008FBCEE 0x5F36 # 0 +0x008FBCEF 0x5F3B # 0 +0x008FBCF0 0x5F3D # 0 +0x008FBCF1 0x5F3F # 0 +0x008FBCF2 0x5F40 # 0 +0x008FBCF3 0x5F44 # 0 +0x008FBCF4 0x5F45 # 0 +0x008FBCF5 0x5F47 # 0 +0x008FBCF6 0x5F4D # 0 +0x008FBCF7 0x5F50 # 0 +0x008FBCF8 0x5F54 # 0 +0x008FBCF9 0x5F58 # 0 +0x008FBCFA 0x5F5B # 0 +0x008FBCFB 0x5F60 # 0 +0x008FBCFC 0x5F63 # 0 +0x008FBCFD 0x5F64 # 0 +0x008FBCFE 0x5F67 # 0 +0x008FBDA1 0x5F6F # 0 +0x008FBDA2 0x5F72 # 0 +0x008FBDA3 0x5F74 # 0 +0x008FBDA4 0x5F75 # 0 +0x008FBDA5 0x5F78 # 0 +0x008FBDA6 0x5F7A # 0 +0x008FBDA7 0x5F7D # 0 +0x008FBDA8 0x5F7E # 0 +0x008FBDA9 0x5F89 # 0 +0x008FBDAA 0x5F8D # 0 +0x008FBDAB 0x5F8F # 0 +0x008FBDAC 0x5F96 # 0 +0x008FBDAD 0x5F9C # 0 +0x008FBDAE 0x5F9D # 0 +0x008FBDAF 0x5FA2 # 0 +0x008FBDB0 0x5FA7 # 0 +0x008FBDB1 0x5FAB # 0 +0x008FBDB2 0x5FA4 # 0 +0x008FBDB3 0x5FAC # 0 +0x008FBDB4 0x5FAF # 0 +0x008FBDB5 0x5FB0 # 0 +0x008FBDB6 0x5FB1 # 0 +0x008FBDB7 0x5FB8 # 0 +0x008FBDB8 0x5FC4 # 0 +0x008FBDB9 0x5FC7 # 0 +0x008FBDBA 0x5FC8 # 0 +0x008FBDBB 0x5FC9 # 0 +0x008FBDBC 0x5FCB # 0 +0x008FBDBD 0x5FD0 # 0 +0x008FBDBE 0x5FD1 # 0 +0x008FBDBF 0x5FD2 # 0 +0x008FBDC0 0x5FD3 # 0 +0x008FBDC1 0x5FD4 # 0 +0x008FBDC2 0x5FDE # 0 +0x008FBDC3 0x5FE1 # 0 +0x008FBDC4 0x5FE2 # 0 +0x008FBDC5 0x5FE8 # 0 +0x008FBDC6 0x5FE9 # 0 +0x008FBDC7 0x5FEA # 0 +0x008FBDC8 0x5FEC # 0 +0x008FBDC9 0x5FED # 0 +0x008FBDCA 0x5FEE # 0 +0x008FBDCB 0x5FEF # 0 +0x008FBDCC 0x5FF2 # 0 +0x008FBDCD 0x5FF3 # 0 +0x008FBDCE 0x5FF6 # 0 +0x008FBDCF 0x5FFA # 0 +0x008FBDD0 0x5FFC # 0 +0x008FBDD1 0x6007 # 0 +0x008FBDD2 0x600A # 0 +0x008FBDD3 0x600D # 0 +0x008FBDD4 0x6013 # 0 +0x008FBDD5 0x6014 # 0 +0x008FBDD6 0x6017 # 0 +0x008FBDD7 0x6018 # 0 +0x008FBDD8 0x601A # 0 +0x008FBDD9 0x601F # 0 +0x008FBDDA 0x6024 # 0 +0x008FBDDB 0x602D # 0 +0x008FBDDC 0x6033 # 0 +0x008FBDDD 0x6035 # 0 +0x008FBDDE 0x6040 # 0 +0x008FBDDF 0x6047 # 0 +0x008FBDE0 0x6048 # 0 +0x008FBDE1 0x6049 # 0 +0x008FBDE2 0x604C # 0 +0x008FBDE3 0x6051 # 0 +0x008FBDE4 0x6054 # 0 +0x008FBDE5 0x6056 # 0 +0x008FBDE6 0x6057 # 0 +0x008FBDE7 0x605D # 0 +0x008FBDE8 0x6061 # 0 +0x008FBDE9 0x6067 # 0 +0x008FBDEA 0x6071 # 0 +0x008FBDEB 0x607E # 0 +0x008FBDEC 0x607F # 0 +0x008FBDED 0x6082 # 0 +0x008FBDEE 0x6086 # 0 +0x008FBDEF 0x6088 # 0 +0x008FBDF0 0x608A # 0 +0x008FBDF1 0x608E # 0 +0x008FBDF2 0x6091 # 0 +0x008FBDF3 0x6093 # 0 +0x008FBDF4 0x6095 # 0 +0x008FBDF5 0x6098 # 0 +0x008FBDF6 0x609D # 0 +0x008FBDF7 0x609E # 0 +0x008FBDF8 0x60A2 # 0 +0x008FBDF9 0x60A4 # 0 +0x008FBDFA 0x60A5 # 0 +0x008FBDFB 0x60A8 # 0 +0x008FBDFC 0x60B0 # 0 +0x008FBDFD 0x60B1 # 0 +0x008FBDFE 0x60B7 # 0 +0x008FBEA1 0x60BB # 0 +0x008FBEA2 0x60BE # 0 +0x008FBEA3 0x60C2 # 0 +0x008FBEA4 0x60C4 # 0 +0x008FBEA5 0x60C8 # 0 +0x008FBEA6 0x60C9 # 0 +0x008FBEA7 0x60CA # 0 +0x008FBEA8 0x60CB # 0 +0x008FBEA9 0x60CE # 0 +0x008FBEAA 0x60CF # 0 +0x008FBEAB 0x60D4 # 0 +0x008FBEAC 0x60D5 # 0 +0x008FBEAD 0x60D9 # 0 +0x008FBEAE 0x60DB # 0 +0x008FBEAF 0x60DD # 0 +0x008FBEB0 0x60DE # 0 +0x008FBEB1 0x60E2 # 0 +0x008FBEB2 0x60E5 # 0 +0x008FBEB3 0x60F2 # 0 +0x008FBEB4 0x60F5 # 0 +0x008FBEB5 0x60F8 # 0 +0x008FBEB6 0x60FC # 0 +0x008FBEB7 0x60FD # 0 +0x008FBEB8 0x6102 # 0 +0x008FBEB9 0x6107 # 0 +0x008FBEBA 0x610A # 0 +0x008FBEBB 0x610C # 0 +0x008FBEBC 0x6110 # 0 +0x008FBEBD 0x6111 # 0 +0x008FBEBE 0x6112 # 0 +0x008FBEBF 0x6113 # 0 +0x008FBEC0 0x6114 # 0 +0x008FBEC1 0x6116 # 0 +0x008FBEC2 0x6117 # 0 +0x008FBEC3 0x6119 # 0 +0x008FBEC4 0x611C # 0 +0x008FBEC5 0x611E # 0 +0x008FBEC6 0x6122 # 0 +0x008FBEC7 0x612A # 0 +0x008FBEC8 0x612B # 0 +0x008FBEC9 0x6130 # 0 +0x008FBECA 0x6131 # 0 +0x008FBECB 0x6135 # 0 +0x008FBECC 0x6136 # 0 +0x008FBECD 0x6137 # 0 +0x008FBECE 0x6139 # 0 +0x008FBECF 0x6141 # 0 +0x008FBED0 0x6145 # 0 +0x008FBED1 0x6146 # 0 +0x008FBED2 0x6149 # 0 +0x008FBED3 0x615E # 0 +0x008FBED4 0x6160 # 0 +0x008FBED5 0x616C # 0 +0x008FBED6 0x6172 # 0 +0x008FBED7 0x6178 # 0 +0x008FBED8 0x617B # 0 +0x008FBED9 0x617C # 0 +0x008FBEDA 0x617F # 0 +0x008FBEDB 0x6180 # 0 +0x008FBEDC 0x6181 # 0 +0x008FBEDD 0x6183 # 0 +0x008FBEDE 0x6184 # 0 +0x008FBEDF 0x618B # 0 +0x008FBEE0 0x618D # 0 +0x008FBEE1 0x6192 # 0 +0x008FBEE2 0x6193 # 0 +0x008FBEE3 0x6197 # 0 +0x008FBEE4 0x6198 # 0 +0x008FBEE5 0x619C # 0 +0x008FBEE6 0x619D # 0 +0x008FBEE7 0x619F # 0 +0x008FBEE8 0x61A0 # 0 +0x008FBEE9 0x61A5 # 0 +0x008FBEEA 0x61A8 # 0 +0x008FBEEB 0x61AA # 0 +0x008FBEEC 0x61AD # 0 +0x008FBEED 0x61B8 # 0 +0x008FBEEE 0x61B9 # 0 +0x008FBEEF 0x61BC # 0 +0x008FBEF0 0x61C0 # 0 +0x008FBEF1 0x61C1 # 0 +0x008FBEF2 0x61C2 # 0 +0x008FBEF3 0x61CE # 0 +0x008FBEF4 0x61CF # 0 +0x008FBEF5 0x61D5 # 0 +0x008FBEF6 0x61DC # 0 +0x008FBEF7 0x61DD # 0 +0x008FBEF8 0x61DE # 0 +0x008FBEF9 0x61DF # 0 +0x008FBEFA 0x61E1 # 0 +0x008FBEFB 0x61E2 # 0 +0x008FBEFC 0x61E7 # 0 +0x008FBEFD 0x61E9 # 0 +0x008FBEFE 0x61E5 # 0 +0x008FBFA1 0x61EC # 0 +0x008FBFA2 0x61ED # 0 +0x008FBFA3 0x61EF # 0 +0x008FBFA4 0x6201 # 0 +0x008FBFA5 0x6203 # 0 +0x008FBFA6 0x6204 # 0 +0x008FBFA7 0x6207 # 0 +0x008FBFA8 0x6213 # 0 +0x008FBFA9 0x6215 # 0 +0x008FBFAA 0x621C # 0 +0x008FBFAB 0x6220 # 0 +0x008FBFAC 0x6222 # 0 +0x008FBFAD 0x6223 # 0 +0x008FBFAE 0x6227 # 0 +0x008FBFAF 0x6229 # 0 +0x008FBFB0 0x622B # 0 +0x008FBFB1 0x6239 # 0 +0x008FBFB2 0x623D # 0 +0x008FBFB3 0x6242 # 0 +0x008FBFB4 0x6243 # 0 +0x008FBFB5 0x6244 # 0 +0x008FBFB6 0x6246 # 0 +0x008FBFB7 0x624C # 0 +0x008FBFB8 0x6250 # 0 +0x008FBFB9 0x6251 # 0 +0x008FBFBA 0x6252 # 0 +0x008FBFBB 0x6254 # 0 +0x008FBFBC 0x6256 # 0 +0x008FBFBD 0x625A # 0 +0x008FBFBE 0x625C # 0 +0x008FBFBF 0x6264 # 0 +0x008FBFC0 0x626D # 0 +0x008FBFC1 0x626F # 0 +0x008FBFC2 0x6273 # 0 +0x008FBFC3 0x627A # 0 +0x008FBFC4 0x627D # 0 +0x008FBFC5 0x628D # 0 +0x008FBFC6 0x628E # 0 +0x008FBFC7 0x628F # 0 +0x008FBFC8 0x6290 # 0 +0x008FBFC9 0x62A6 # 0 +0x008FBFCA 0x62A8 # 0 +0x008FBFCB 0x62B3 # 0 +0x008FBFCC 0x62B6 # 0 +0x008FBFCD 0x62B7 # 0 +0x008FBFCE 0x62BA # 0 +0x008FBFCF 0x62BE # 0 +0x008FBFD0 0x62BF # 0 +0x008FBFD1 0x62C4 # 0 +0x008FBFD2 0x62CE # 0 +0x008FBFD3 0x62D5 # 0 +0x008FBFD4 0x62D6 # 0 +0x008FBFD5 0x62DA # 0 +0x008FBFD6 0x62EA # 0 +0x008FBFD7 0x62F2 # 0 +0x008FBFD8 0x62F4 # 0 +0x008FBFD9 0x62FC # 0 +0x008FBFDA 0x62FD # 0 +0x008FBFDB 0x6303 # 0 +0x008FBFDC 0x6304 # 0 +0x008FBFDD 0x630A # 0 +0x008FBFDE 0x630B # 0 +0x008FBFDF 0x630D # 0 +0x008FBFE0 0x6310 # 0 +0x008FBFE1 0x6313 # 0 +0x008FBFE2 0x6316 # 0 +0x008FBFE3 0x6318 # 0 +0x008FBFE4 0x6329 # 0 +0x008FBFE5 0x632A # 0 +0x008FBFE6 0x632D # 0 +0x008FBFE7 0x6335 # 0 +0x008FBFE8 0x6336 # 0 +0x008FBFE9 0x6339 # 0 +0x008FBFEA 0x633C # 0 +0x008FBFEB 0x6341 # 0 +0x008FBFEC 0x6342 # 0 +0x008FBFED 0x6343 # 0 +0x008FBFEE 0x6344 # 0 +0x008FBFEF 0x6346 # 0 +0x008FBFF0 0x634A # 0 +0x008FBFF1 0x634B # 0 +0x008FBFF2 0x634E # 0 +0x008FBFF3 0x6352 # 0 +0x008FBFF4 0x6353 # 0 +0x008FBFF5 0x6354 # 0 +0x008FBFF6 0x6358 # 0 +0x008FBFF7 0x635B # 0 +0x008FBFF8 0x6365 # 0 +0x008FBFF9 0x6366 # 0 +0x008FBFFA 0x636C # 0 +0x008FBFFB 0x636D # 0 +0x008FBFFC 0x6371 # 0 +0x008FBFFD 0x6374 # 0 +0x008FBFFE 0x6375 # 0 +0x008FC0A1 0x6378 # 0 +0x008FC0A2 0x637C # 0 +0x008FC0A3 0x637D # 0 +0x008FC0A4 0x637F # 0 +0x008FC0A5 0x6382 # 0 +0x008FC0A6 0x6384 # 0 +0x008FC0A7 0x6387 # 0 +0x008FC0A8 0x638A # 0 +0x008FC0A9 0x6390 # 0 +0x008FC0AA 0x6394 # 0 +0x008FC0AB 0x6395 # 0 +0x008FC0AC 0x6399 # 0 +0x008FC0AD 0x639A # 0 +0x008FC0AE 0x639E # 0 +0x008FC0AF 0x63A4 # 0 +0x008FC0B0 0x63A6 # 0 +0x008FC0B1 0x63AD # 0 +0x008FC0B2 0x63AE # 0 +0x008FC0B3 0x63AF # 0 +0x008FC0B4 0x63BD # 0 +0x008FC0B5 0x63C1 # 0 +0x008FC0B6 0x63C5 # 0 +0x008FC0B7 0x63C8 # 0 +0x008FC0B8 0x63CE # 0 +0x008FC0B9 0x63D1 # 0 +0x008FC0BA 0x63D3 # 0 +0x008FC0BB 0x63D4 # 0 +0x008FC0BC 0x63D5 # 0 +0x008FC0BD 0x63DC # 0 +0x008FC0BE 0x63E0 # 0 +0x008FC0BF 0x63E5 # 0 +0x008FC0C0 0x63EA # 0 +0x008FC0C1 0x63EC # 0 +0x008FC0C2 0x63F2 # 0 +0x008FC0C3 0x63F3 # 0 +0x008FC0C4 0x63F5 # 0 +0x008FC0C5 0x63F8 # 0 +0x008FC0C6 0x63F9 # 0 +0x008FC0C7 0x6409 # 0 +0x008FC0C8 0x640A # 0 +0x008FC0C9 0x6410 # 0 +0x008FC0CA 0x6412 # 0 +0x008FC0CB 0x6414 # 0 +0x008FC0CC 0x6418 # 0 +0x008FC0CD 0x641E # 0 +0x008FC0CE 0x6420 # 0 +0x008FC0CF 0x6422 # 0 +0x008FC0D0 0x6424 # 0 +0x008FC0D1 0x6425 # 0 +0x008FC0D2 0x6429 # 0 +0x008FC0D3 0x642A # 0 +0x008FC0D4 0x642F # 0 +0x008FC0D5 0x6430 # 0 +0x008FC0D6 0x6435 # 0 +0x008FC0D7 0x643D # 0 +0x008FC0D8 0x643F # 0 +0x008FC0D9 0x644B # 0 +0x008FC0DA 0x644F # 0 +0x008FC0DB 0x6451 # 0 +0x008FC0DC 0x6452 # 0 +0x008FC0DD 0x6453 # 0 +0x008FC0DE 0x6454 # 0 +0x008FC0DF 0x645A # 0 +0x008FC0E0 0x645B # 0 +0x008FC0E1 0x645C # 0 +0x008FC0E2 0x645D # 0 +0x008FC0E3 0x645F # 0 +0x008FC0E4 0x6460 # 0 +0x008FC0E5 0x6461 # 0 +0x008FC0E6 0x6463 # 0 +0x008FC0E7 0x646D # 0 +0x008FC0E8 0x6473 # 0 +0x008FC0E9 0x6474 # 0 +0x008FC0EA 0x647B # 0 +0x008FC0EB 0x647D # 0 +0x008FC0EC 0x6485 # 0 +0x008FC0ED 0x6487 # 0 +0x008FC0EE 0x648F # 0 +0x008FC0EF 0x6490 # 0 +0x008FC0F0 0x6491 # 0 +0x008FC0F1 0x6498 # 0 +0x008FC0F2 0x6499 # 0 +0x008FC0F3 0x649B # 0 +0x008FC0F4 0x649D # 0 +0x008FC0F5 0x649F # 0 +0x008FC0F6 0x64A1 # 0 +0x008FC0F7 0x64A3 # 0 +0x008FC0F8 0x64A6 # 0 +0x008FC0F9 0x64A8 # 0 +0x008FC0FA 0x64AC # 0 +0x008FC0FB 0x64B3 # 0 +0x008FC0FC 0x64BD # 0 +0x008FC0FD 0x64BE # 0 +0x008FC0FE 0x64BF # 0 +0x008FC1A1 0x64C4 # 0 +0x008FC1A2 0x64C9 # 0 +0x008FC1A3 0x64CA # 0 +0x008FC1A4 0x64CB # 0 +0x008FC1A5 0x64CC # 0 +0x008FC1A6 0x64CE # 0 +0x008FC1A7 0x64D0 # 0 +0x008FC1A8 0x64D1 # 0 +0x008FC1A9 0x64D5 # 0 +0x008FC1AA 0x64D7 # 0 +0x008FC1AB 0x64E4 # 0 +0x008FC1AC 0x64E5 # 0 +0x008FC1AD 0x64E9 # 0 +0x008FC1AE 0x64EA # 0 +0x008FC1AF 0x64ED # 0 +0x008FC1B0 0x64F0 # 0 +0x008FC1B1 0x64F5 # 0 +0x008FC1B2 0x64F7 # 0 +0x008FC1B3 0x64FB # 0 +0x008FC1B4 0x64FF # 0 +0x008FC1B5 0x6501 # 0 +0x008FC1B6 0x6504 # 0 +0x008FC1B7 0x6508 # 0 +0x008FC1B8 0x6509 # 0 +0x008FC1B9 0x650A # 0 +0x008FC1BA 0x650F # 0 +0x008FC1BB 0x6513 # 0 +0x008FC1BC 0x6514 # 0 +0x008FC1BD 0x6516 # 0 +0x008FC1BE 0x6519 # 0 +0x008FC1BF 0x651B # 0 +0x008FC1C0 0x651E # 0 +0x008FC1C1 0x651F # 0 +0x008FC1C2 0x6522 # 0 +0x008FC1C3 0x6526 # 0 +0x008FC1C4 0x6529 # 0 +0x008FC1C5 0x652E # 0 +0x008FC1C6 0x6531 # 0 +0x008FC1C7 0x653A # 0 +0x008FC1C8 0x653C # 0 +0x008FC1C9 0x653D # 0 +0x008FC1CA 0x6543 # 0 +0x008FC1CB 0x6547 # 0 +0x008FC1CC 0x6549 # 0 +0x008FC1CD 0x6550 # 0 +0x008FC1CE 0x6552 # 0 +0x008FC1CF 0x6554 # 0 +0x008FC1D0 0x655F # 0 +0x008FC1D1 0x6560 # 0 +0x008FC1D2 0x6567 # 0 +0x008FC1D3 0x656B # 0 +0x008FC1D4 0x657A # 0 +0x008FC1D5 0x657D # 0 +0x008FC1D6 0x6581 # 0 +0x008FC1D7 0x6585 # 0 +0x008FC1D8 0x658A # 0 +0x008FC1D9 0x6592 # 0 +0x008FC1DA 0x6595 # 0 +0x008FC1DB 0x6598 # 0 +0x008FC1DC 0x659D # 0 +0x008FC1DD 0x65A0 # 0 +0x008FC1DE 0x65A3 # 0 +0x008FC1DF 0x65A6 # 0 +0x008FC1E0 0x65AE # 0 +0x008FC1E1 0x65B2 # 0 +0x008FC1E2 0x65B3 # 0 +0x008FC1E3 0x65B4 # 0 +0x008FC1E4 0x65BF # 0 +0x008FC1E5 0x65C2 # 0 +0x008FC1E6 0x65C8 # 0 +0x008FC1E7 0x65C9 # 0 +0x008FC1E8 0x65CE # 0 +0x008FC1E9 0x65D0 # 0 +0x008FC1EA 0x65D4 # 0 +0x008FC1EB 0x65D6 # 0 +0x008FC1EC 0x65D8 # 0 +0x008FC1ED 0x65DF # 0 +0x008FC1EE 0x65F0 # 0 +0x008FC1EF 0x65F2 # 0 +0x008FC1F0 0x65F4 # 0 +0x008FC1F1 0x65F5 # 0 +0x008FC1F2 0x65F9 # 0 +0x008FC1F3 0x65FE # 0 +0x008FC1F4 0x65FF # 0 +0x008FC1F5 0x6600 # 0 +0x008FC1F6 0x6604 # 0 +0x008FC1F7 0x6608 # 0 +0x008FC1F8 0x6609 # 0 +0x008FC1F9 0x660D # 0 +0x008FC1FA 0x6611 # 0 +0x008FC1FB 0x6612 # 0 +0x008FC1FC 0x6615 # 0 +0x008FC1FD 0x6616 # 0 +0x008FC1FE 0x661D # 0 +0x008FC2A1 0x661E # 0 +0x008FC2A2 0x6621 # 0 +0x008FC2A3 0x6622 # 0 +0x008FC2A4 0x6623 # 0 +0x008FC2A5 0x6624 # 0 +0x008FC2A6 0x6626 # 0 +0x008FC2A7 0x6629 # 0 +0x008FC2A8 0x662A # 0 +0x008FC2A9 0x662B # 0 +0x008FC2AA 0x662C # 0 +0x008FC2AB 0x662E # 0 +0x008FC2AC 0x6630 # 0 +0x008FC2AD 0x6631 # 0 +0x008FC2AE 0x6633 # 0 +0x008FC2AF 0x6639 # 0 +0x008FC2B0 0x6637 # 0 +0x008FC2B1 0x6640 # 0 +0x008FC2B2 0x6645 # 0 +0x008FC2B3 0x6646 # 0 +0x008FC2B4 0x664A # 0 +0x008FC2B5 0x664C # 0 +0x008FC2B6 0x6651 # 0 +0x008FC2B7 0x664E # 0 +0x008FC2B8 0x6657 # 0 +0x008FC2B9 0x6658 # 0 +0x008FC2BA 0x6659 # 0 +0x008FC2BB 0x665B # 0 +0x008FC2BC 0x665C # 0 +0x008FC2BD 0x6660 # 0 +0x008FC2BE 0x6661 # 0 +0x008FC2BF 0x66FB # 0 +0x008FC2C0 0x666A # 0 +0x008FC2C1 0x666B # 0 +0x008FC2C2 0x666C # 0 +0x008FC2C3 0x667E # 0 +0x008FC2C4 0x6673 # 0 +0x008FC2C5 0x6675 # 0 +0x008FC2C6 0x667F # 0 +0x008FC2C7 0x6677 # 0 +0x008FC2C8 0x6678 # 0 +0x008FC2C9 0x6679 # 0 +0x008FC2CA 0x667B # 0 +0x008FC2CB 0x6680 # 0 +0x008FC2CC 0x667C # 0 +0x008FC2CD 0x668B # 0 +0x008FC2CE 0x668C # 0 +0x008FC2CF 0x668D # 0 +0x008FC2D0 0x6690 # 0 +0x008FC2D1 0x6692 # 0 +0x008FC2D2 0x6699 # 0 +0x008FC2D3 0x669A # 0 +0x008FC2D4 0x669B # 0 +0x008FC2D5 0x669C # 0 +0x008FC2D6 0x669F # 0 +0x008FC2D7 0x66A0 # 0 +0x008FC2D8 0x66A4 # 0 +0x008FC2D9 0x66AD # 0 +0x008FC2DA 0x66B1 # 0 +0x008FC2DB 0x66B2 # 0 +0x008FC2DC 0x66B5 # 0 +0x008FC2DD 0x66BB # 0 +0x008FC2DE 0x66BF # 0 +0x008FC2DF 0x66C0 # 0 +0x008FC2E0 0x66C2 # 0 +0x008FC2E1 0x66C3 # 0 +0x008FC2E2 0x66C8 # 0 +0x008FC2E3 0x66CC # 0 +0x008FC2E4 0x66CE # 0 +0x008FC2E5 0x66CF # 0 +0x008FC2E6 0x66D4 # 0 +0x008FC2E7 0x66DB # 0 +0x008FC2E8 0x66DF # 0 +0x008FC2E9 0x66E8 # 0 +0x008FC2EA 0x66EB # 0 +0x008FC2EB 0x66EC # 0 +0x008FC2EC 0x66EE # 0 +0x008FC2ED 0x66FA # 0 +0x008FC2EE 0x6705 # 0 +0x008FC2EF 0x6707 # 0 +0x008FC2F0 0x670E # 0 +0x008FC2F1 0x6713 # 0 +0x008FC2F2 0x6719 # 0 +0x008FC2F3 0x671C # 0 +0x008FC2F4 0x6720 # 0 +0x008FC2F5 0x6722 # 0 +0x008FC2F6 0x6733 # 0 +0x008FC2F7 0x673E # 0 +0x008FC2F8 0x6745 # 0 +0x008FC2F9 0x6747 # 0 +0x008FC2FA 0x6748 # 0 +0x008FC2FB 0x674C # 0 +0x008FC2FC 0x6754 # 0 +0x008FC2FD 0x6755 # 0 +0x008FC2FE 0x675D # 0 +0x008FC3A1 0x6766 # 0 +0x008FC3A2 0x676C # 0 +0x008FC3A3 0x676E # 0 +0x008FC3A4 0x6774 # 0 +0x008FC3A5 0x6776 # 0 +0x008FC3A6 0x677B # 0 +0x008FC3A7 0x6781 # 0 +0x008FC3A8 0x6784 # 0 +0x008FC3A9 0x678E # 0 +0x008FC3AA 0x678F # 0 +0x008FC3AB 0x6791 # 0 +0x008FC3AC 0x6793 # 0 +0x008FC3AD 0x6796 # 0 +0x008FC3AE 0x6798 # 0 +0x008FC3AF 0x6799 # 0 +0x008FC3B0 0x679B # 0 +0x008FC3B1 0x67B0 # 0 +0x008FC3B2 0x67B1 # 0 +0x008FC3B3 0x67B2 # 0 +0x008FC3B4 0x67B5 # 0 +0x008FC3B5 0x67BB # 0 +0x008FC3B6 0x67BC # 0 +0x008FC3B7 0x67BD # 0 +0x008FC3B8 0x67F9 # 0 +0x008FC3B9 0x67C0 # 0 +0x008FC3BA 0x67C2 # 0 +0x008FC3BB 0x67C3 # 0 +0x008FC3BC 0x67C5 # 0 +0x008FC3BD 0x67C8 # 0 +0x008FC3BE 0x67C9 # 0 +0x008FC3BF 0x67D2 # 0 +0x008FC3C0 0x67D7 # 0 +0x008FC3C1 0x67D9 # 0 +0x008FC3C2 0x67DC # 0 +0x008FC3C3 0x67E1 # 0 +0x008FC3C4 0x67E6 # 0 +0x008FC3C5 0x67F0 # 0 +0x008FC3C6 0x67F2 # 0 +0x008FC3C7 0x67F6 # 0 +0x008FC3C8 0x67F7 # 0 +0x008FC3C9 0x6852 # 0 +0x008FC3CA 0x6814 # 0 +0x008FC3CB 0x6819 # 0 +0x008FC3CC 0x681D # 0 +0x008FC3CD 0x681F # 0 +0x008FC3CE 0x6828 # 0 +0x008FC3CF 0x6827 # 0 +0x008FC3D0 0x682C # 0 +0x008FC3D1 0x682D # 0 +0x008FC3D2 0x682F # 0 +0x008FC3D3 0x6830 # 0 +0x008FC3D4 0x6831 # 0 +0x008FC3D5 0x6833 # 0 +0x008FC3D6 0x683B # 0 +0x008FC3D7 0x683F # 0 +0x008FC3D8 0x6844 # 0 +0x008FC3D9 0x6845 # 0 +0x008FC3DA 0x684A # 0 +0x008FC3DB 0x684C # 0 +0x008FC3DC 0x6855 # 0 +0x008FC3DD 0x6857 # 0 +0x008FC3DE 0x6858 # 0 +0x008FC3DF 0x685B # 0 +0x008FC3E0 0x686B # 0 +0x008FC3E1 0x686E # 0 +0x008FC3E2 0x686F # 0 +0x008FC3E3 0x6870 # 0 +0x008FC3E4 0x6871 # 0 +0x008FC3E5 0x6872 # 0 +0x008FC3E6 0x6875 # 0 +0x008FC3E7 0x6879 # 0 +0x008FC3E8 0x687A # 0 +0x008FC3E9 0x687B # 0 +0x008FC3EA 0x687C # 0 +0x008FC3EB 0x6882 # 0 +0x008FC3EC 0x6884 # 0 +0x008FC3ED 0x6886 # 0 +0x008FC3EE 0x6888 # 0 +0x008FC3EF 0x6896 # 0 +0x008FC3F0 0x6898 # 0 +0x008FC3F1 0x689A # 0 +0x008FC3F2 0x689C # 0 +0x008FC3F3 0x68A1 # 0 +0x008FC3F4 0x68A3 # 0 +0x008FC3F5 0x68A5 # 0 +0x008FC3F6 0x68A9 # 0 +0x008FC3F7 0x68AA # 0 +0x008FC3F8 0x68AE # 0 +0x008FC3F9 0x68B2 # 0 +0x008FC3FA 0x68BB # 0 +0x008FC3FB 0x68C5 # 0 +0x008FC3FC 0x68C8 # 0 +0x008FC3FD 0x68CC # 0 +0x008FC3FE 0x68CF # 0 +0x008FC4A1 0x68D0 # 0 +0x008FC4A2 0x68D1 # 0 +0x008FC4A3 0x68D3 # 0 +0x008FC4A4 0x68D6 # 0 +0x008FC4A5 0x68D9 # 0 +0x008FC4A6 0x68DC # 0 +0x008FC4A7 0x68DD # 0 +0x008FC4A8 0x68E5 # 0 +0x008FC4A9 0x68E8 # 0 +0x008FC4AA 0x68EA # 0 +0x008FC4AB 0x68EB # 0 +0x008FC4AC 0x68EC # 0 +0x008FC4AD 0x68ED # 0 +0x008FC4AE 0x68F0 # 0 +0x008FC4AF 0x68F1 # 0 +0x008FC4B0 0x68F5 # 0 +0x008FC4B1 0x68F6 # 0 +0x008FC4B2 0x68FB # 0 +0x008FC4B3 0x68FC # 0 +0x008FC4B4 0x68FD # 0 +0x008FC4B5 0x6906 # 0 +0x008FC4B6 0x6909 # 0 +0x008FC4B7 0x690A # 0 +0x008FC4B8 0x6910 # 0 +0x008FC4B9 0x6911 # 0 +0x008FC4BA 0x6913 # 0 +0x008FC4BB 0x6916 # 0 +0x008FC4BC 0x6917 # 0 +0x008FC4BD 0x6931 # 0 +0x008FC4BE 0x6933 # 0 +0x008FC4BF 0x6935 # 0 +0x008FC4C0 0x6938 # 0 +0x008FC4C1 0x693B # 0 +0x008FC4C2 0x6942 # 0 +0x008FC4C3 0x6945 # 0 +0x008FC4C4 0x6949 # 0 +0x008FC4C5 0x694E # 0 +0x008FC4C6 0x6957 # 0 +0x008FC4C7 0x695B # 0 +0x008FC4C8 0x6963 # 0 +0x008FC4C9 0x6964 # 0 +0x008FC4CA 0x6965 # 0 +0x008FC4CB 0x6966 # 0 +0x008FC4CC 0x6968 # 0 +0x008FC4CD 0x6969 # 0 +0x008FC4CE 0x696C # 0 +0x008FC4CF 0x6970 # 0 +0x008FC4D0 0x6971 # 0 +0x008FC4D1 0x6972 # 0 +0x008FC4D2 0x697A # 0 +0x008FC4D3 0x697B # 0 +0x008FC4D4 0x697F # 0 +0x008FC4D5 0x6980 # 0 +0x008FC4D6 0x698D # 0 +0x008FC4D7 0x6992 # 0 +0x008FC4D8 0x6996 # 0 +0x008FC4D9 0x6998 # 0 +0x008FC4DA 0x69A1 # 0 +0x008FC4DB 0x69A5 # 0 +0x008FC4DC 0x69A6 # 0 +0x008FC4DD 0x69A8 # 0 +0x008FC4DE 0x69AB # 0 +0x008FC4DF 0x69AD # 0 +0x008FC4E0 0x69AF # 0 +0x008FC4E1 0x69B7 # 0 +0x008FC4E2 0x69B8 # 0 +0x008FC4E3 0x69BA # 0 +0x008FC4E4 0x69BC # 0 +0x008FC4E5 0x69C5 # 0 +0x008FC4E6 0x69C8 # 0 +0x008FC4E7 0x69D1 # 0 +0x008FC4E8 0x69D6 # 0 +0x008FC4E9 0x69D7 # 0 +0x008FC4EA 0x69E2 # 0 +0x008FC4EB 0x69E5 # 0 +0x008FC4EC 0x69EE # 0 +0x008FC4ED 0x69EF # 0 +0x008FC4EE 0x69F1 # 0 +0x008FC4EF 0x69F3 # 0 +0x008FC4F0 0x69F5 # 0 +0x008FC4F1 0x69FE # 0 +0x008FC4F2 0x6A00 # 0 +0x008FC4F3 0x6A01 # 0 +0x008FC4F4 0x6A03 # 0 +0x008FC4F5 0x6A0F # 0 +0x008FC4F6 0x6A11 # 0 +0x008FC4F7 0x6A15 # 0 +0x008FC4F8 0x6A1A # 0 +0x008FC4F9 0x6A1D # 0 +0x008FC4FA 0x6A20 # 0 +0x008FC4FB 0x6A24 # 0 +0x008FC4FC 0x6A28 # 0 +0x008FC4FD 0x6A30 # 0 +0x008FC4FE 0x6A32 # 0 +0x008FC5A1 0x6A34 # 0 +0x008FC5A2 0x6A37 # 0 +0x008FC5A3 0x6A3B # 0 +0x008FC5A4 0x6A3E # 0 +0x008FC5A5 0x6A3F # 0 +0x008FC5A6 0x6A45 # 0 +0x008FC5A7 0x6A46 # 0 +0x008FC5A8 0x6A49 # 0 +0x008FC5A9 0x6A4A # 0 +0x008FC5AA 0x6A4E # 0 +0x008FC5AB 0x6A50 # 0 +0x008FC5AC 0x6A51 # 0 +0x008FC5AD 0x6A52 # 0 +0x008FC5AE 0x6A55 # 0 +0x008FC5AF 0x6A56 # 0 +0x008FC5B0 0x6A5B # 0 +0x008FC5B1 0x6A64 # 0 +0x008FC5B2 0x6A67 # 0 +0x008FC5B3 0x6A6A # 0 +0x008FC5B4 0x6A71 # 0 +0x008FC5B5 0x6A73 # 0 +0x008FC5B6 0x6A7E # 0 +0x008FC5B7 0x6A81 # 0 +0x008FC5B8 0x6A83 # 0 +0x008FC5B9 0x6A86 # 0 +0x008FC5BA 0x6A87 # 0 +0x008FC5BB 0x6A89 # 0 +0x008FC5BC 0x6A8B # 0 +0x008FC5BD 0x6A91 # 0 +0x008FC5BE 0x6A9B # 0 +0x008FC5BF 0x6A9D # 0 +0x008FC5C0 0x6A9E # 0 +0x008FC5C1 0x6A9F # 0 +0x008FC5C2 0x6AA5 # 0 +0x008FC5C3 0x6AAB # 0 +0x008FC5C4 0x6AAF # 0 +0x008FC5C5 0x6AB0 # 0 +0x008FC5C6 0x6AB1 # 0 +0x008FC5C7 0x6AB4 # 0 +0x008FC5C8 0x6ABD # 0 +0x008FC5C9 0x6ABE # 0 +0x008FC5CA 0x6ABF # 0 +0x008FC5CB 0x6AC6 # 0 +0x008FC5CC 0x6AC9 # 0 +0x008FC5CD 0x6AC8 # 0 +0x008FC5CE 0x6ACC # 0 +0x008FC5CF 0x6AD0 # 0 +0x008FC5D0 0x6AD4 # 0 +0x008FC5D1 0x6AD5 # 0 +0x008FC5D2 0x6AD6 # 0 +0x008FC5D3 0x6ADC # 0 +0x008FC5D4 0x6ADD # 0 +0x008FC5D5 0x6AE4 # 0 +0x008FC5D6 0x6AE7 # 0 +0x008FC5D7 0x6AEC # 0 +0x008FC5D8 0x6AF0 # 0 +0x008FC5D9 0x6AF1 # 0 +0x008FC5DA 0x6AF2 # 0 +0x008FC5DB 0x6AFC # 0 +0x008FC5DC 0x6AFD # 0 +0x008FC5DD 0x6B02 # 0 +0x008FC5DE 0x6B03 # 0 +0x008FC5DF 0x6B06 # 0 +0x008FC5E0 0x6B07 # 0 +0x008FC5E1 0x6B09 # 0 +0x008FC5E2 0x6B0F # 0 +0x008FC5E3 0x6B10 # 0 +0x008FC5E4 0x6B11 # 0 +0x008FC5E5 0x6B17 # 0 +0x008FC5E6 0x6B1B # 0 +0x008FC5E7 0x6B1E # 0 +0x008FC5E8 0x6B24 # 0 +0x008FC5E9 0x6B28 # 0 +0x008FC5EA 0x6B2B # 0 +0x008FC5EB 0x6B2C # 0 +0x008FC5EC 0x6B2F # 0 +0x008FC5ED 0x6B35 # 0 +0x008FC5EE 0x6B36 # 0 +0x008FC5EF 0x6B3B # 0 +0x008FC5F0 0x6B3F # 0 +0x008FC5F1 0x6B46 # 0 +0x008FC5F2 0x6B4A # 0 +0x008FC5F3 0x6B4D # 0 +0x008FC5F4 0x6B52 # 0 +0x008FC5F5 0x6B56 # 0 +0x008FC5F6 0x6B58 # 0 +0x008FC5F7 0x6B5D # 0 +0x008FC5F8 0x6B60 # 0 +0x008FC5F9 0x6B67 # 0 +0x008FC5FA 0x6B6B # 0 +0x008FC5FB 0x6B6E # 0 +0x008FC5FC 0x6B70 # 0 +0x008FC5FD 0x6B75 # 0 +0x008FC5FE 0x6B7D # 0 +0x008FC6A1 0x6B7E # 0 +0x008FC6A2 0x6B82 # 0 +0x008FC6A3 0x6B85 # 0 +0x008FC6A4 0x6B97 # 0 +0x008FC6A5 0x6B9B # 0 +0x008FC6A6 0x6B9F # 0 +0x008FC6A7 0x6BA0 # 0 +0x008FC6A8 0x6BA2 # 0 +0x008FC6A9 0x6BA3 # 0 +0x008FC6AA 0x6BA8 # 0 +0x008FC6AB 0x6BA9 # 0 +0x008FC6AC 0x6BAC # 0 +0x008FC6AD 0x6BAD # 0 +0x008FC6AE 0x6BAE # 0 +0x008FC6AF 0x6BB0 # 0 +0x008FC6B0 0x6BB8 # 0 +0x008FC6B1 0x6BB9 # 0 +0x008FC6B2 0x6BBD # 0 +0x008FC6B3 0x6BBE # 0 +0x008FC6B4 0x6BC3 # 0 +0x008FC6B5 0x6BC4 # 0 +0x008FC6B6 0x6BC9 # 0 +0x008FC6B7 0x6BCC # 0 +0x008FC6B8 0x6BD6 # 0 +0x008FC6B9 0x6BDA # 0 +0x008FC6BA 0x6BE1 # 0 +0x008FC6BB 0x6BE3 # 0 +0x008FC6BC 0x6BE6 # 0 +0x008FC6BD 0x6BE7 # 0 +0x008FC6BE 0x6BEE # 0 +0x008FC6BF 0x6BF1 # 0 +0x008FC6C0 0x6BF7 # 0 +0x008FC6C1 0x6BF9 # 0 +0x008FC6C2 0x6BFF # 0 +0x008FC6C3 0x6C02 # 0 +0x008FC6C4 0x6C04 # 0 +0x008FC6C5 0x6C05 # 0 +0x008FC6C6 0x6C09 # 0 +0x008FC6C7 0x6C0D # 0 +0x008FC6C8 0x6C0E # 0 +0x008FC6C9 0x6C10 # 0 +0x008FC6CA 0x6C12 # 0 +0x008FC6CB 0x6C19 # 0 +0x008FC6CC 0x6C1F # 0 +0x008FC6CD 0x6C26 # 0 +0x008FC6CE 0x6C27 # 0 +0x008FC6CF 0x6C28 # 0 +0x008FC6D0 0x6C2C # 0 +0x008FC6D1 0x6C2E # 0 +0x008FC6D2 0x6C33 # 0 +0x008FC6D3 0x6C35 # 0 +0x008FC6D4 0x6C36 # 0 +0x008FC6D5 0x6C3A # 0 +0x008FC6D6 0x6C3B # 0 +0x008FC6D7 0x6C3F # 0 +0x008FC6D8 0x6C4A # 0 +0x008FC6D9 0x6C4B # 0 +0x008FC6DA 0x6C4D # 0 +0x008FC6DB 0x6C4F # 0 +0x008FC6DC 0x6C52 # 0 +0x008FC6DD 0x6C54 # 0 +0x008FC6DE 0x6C59 # 0 +0x008FC6DF 0x6C5B # 0 +0x008FC6E0 0x6C5C # 0 +0x008FC6E1 0x6C6B # 0 +0x008FC6E2 0x6C6D # 0 +0x008FC6E3 0x6C6F # 0 +0x008FC6E4 0x6C74 # 0 +0x008FC6E5 0x6C76 # 0 +0x008FC6E6 0x6C78 # 0 +0x008FC6E7 0x6C79 # 0 +0x008FC6E8 0x6C7B # 0 +0x008FC6E9 0x6C85 # 0 +0x008FC6EA 0x6C86 # 0 +0x008FC6EB 0x6C87 # 0 +0x008FC6EC 0x6C89 # 0 +0x008FC6ED 0x6C94 # 0 +0x008FC6EE 0x6C95 # 0 +0x008FC6EF 0x6C97 # 0 +0x008FC6F0 0x6C98 # 0 +0x008FC6F1 0x6C9C # 0 +0x008FC6F2 0x6C9F # 0 +0x008FC6F3 0x6CB0 # 0 +0x008FC6F4 0x6CB2 # 0 +0x008FC6F5 0x6CB4 # 0 +0x008FC6F6 0x6CC2 # 0 +0x008FC6F7 0x6CC6 # 0 +0x008FC6F8 0x6CCD # 0 +0x008FC6F9 0x6CCF # 0 +0x008FC6FA 0x6CD0 # 0 +0x008FC6FB 0x6CD1 # 0 +0x008FC6FC 0x6CD2 # 0 +0x008FC6FD 0x6CD4 # 0 +0x008FC6FE 0x6CD6 # 0 +0x008FC7A1 0x6CDA # 0 +0x008FC7A2 0x6CDC # 0 +0x008FC7A3 0x6CE0 # 0 +0x008FC7A4 0x6CE7 # 0 +0x008FC7A5 0x6CE9 # 0 +0x008FC7A6 0x6CEB # 0 +0x008FC7A7 0x6CEC # 0 +0x008FC7A8 0x6CEE # 0 +0x008FC7A9 0x6CF2 # 0 +0x008FC7AA 0x6CF4 # 0 +0x008FC7AB 0x6D04 # 0 +0x008FC7AC 0x6D07 # 0 +0x008FC7AD 0x6D0A # 0 +0x008FC7AE 0x6D0E # 0 +0x008FC7AF 0x6D0F # 0 +0x008FC7B0 0x6D11 # 0 +0x008FC7B1 0x6D13 # 0 +0x008FC7B2 0x6D1A # 0 +0x008FC7B3 0x6D26 # 0 +0x008FC7B4 0x6D27 # 0 +0x008FC7B5 0x6D28 # 0 +0x008FC7B6 0x6C67 # 0 +0x008FC7B7 0x6D2E # 0 +0x008FC7B8 0x6D2F # 0 +0x008FC7B9 0x6D31 # 0 +0x008FC7BA 0x6D39 # 0 +0x008FC7BB 0x6D3C # 0 +0x008FC7BC 0x6D3F # 0 +0x008FC7BD 0x6D57 # 0 +0x008FC7BE 0x6D5E # 0 +0x008FC7BF 0x6D5F # 0 +0x008FC7C0 0x6D61 # 0 +0x008FC7C1 0x6D65 # 0 +0x008FC7C2 0x6D67 # 0 +0x008FC7C3 0x6D6F # 0 +0x008FC7C4 0x6D70 # 0 +0x008FC7C5 0x6D7C # 0 +0x008FC7C6 0x6D82 # 0 +0x008FC7C7 0x6D87 # 0 +0x008FC7C8 0x6D91 # 0 +0x008FC7C9 0x6D92 # 0 +0x008FC7CA 0x6D94 # 0 +0x008FC7CB 0x6D96 # 0 +0x008FC7CC 0x6D97 # 0 +0x008FC7CD 0x6D98 # 0 +0x008FC7CE 0x6DAA # 0 +0x008FC7CF 0x6DAC # 0 +0x008FC7D0 0x6DB4 # 0 +0x008FC7D1 0x6DB7 # 0 +0x008FC7D2 0x6DB9 # 0 +0x008FC7D3 0x6DBD # 0 +0x008FC7D4 0x6DBF # 0 +0x008FC7D5 0x6DC4 # 0 +0x008FC7D6 0x6DC8 # 0 +0x008FC7D7 0x6DCA # 0 +0x008FC7D8 0x6DCE # 0 +0x008FC7D9 0x6DCF # 0 +0x008FC7DA 0x6DD6 # 0 +0x008FC7DB 0x6DDB # 0 +0x008FC7DC 0x6DDD # 0 +0x008FC7DD 0x6DDF # 0 +0x008FC7DE 0x6DE0 # 0 +0x008FC7DF 0x6DE2 # 0 +0x008FC7E0 0x6DE5 # 0 +0x008FC7E1 0x6DE9 # 0 +0x008FC7E2 0x6DEF # 0 +0x008FC7E3 0x6DF0 # 0 +0x008FC7E4 0x6DF4 # 0 +0x008FC7E5 0x6DF6 # 0 +0x008FC7E6 0x6DFC # 0 +0x008FC7E7 0x6E00 # 0 +0x008FC7E8 0x6E04 # 0 +0x008FC7E9 0x6E1E # 0 +0x008FC7EA 0x6E22 # 0 +0x008FC7EB 0x6E27 # 0 +0x008FC7EC 0x6E32 # 0 +0x008FC7ED 0x6E36 # 0 +0x008FC7EE 0x6E39 # 0 +0x008FC7EF 0x6E3B # 0 +0x008FC7F0 0x6E3C # 0 +0x008FC7F1 0x6E44 # 0 +0x008FC7F2 0x6E45 # 0 +0x008FC7F3 0x6E48 # 0 +0x008FC7F4 0x6E49 # 0 +0x008FC7F5 0x6E4B # 0 +0x008FC7F6 0x6E4F # 0 +0x008FC7F7 0x6E51 # 0 +0x008FC7F8 0x6E52 # 0 +0x008FC7F9 0x6E53 # 0 +0x008FC7FA 0x6E54 # 0 +0x008FC7FB 0x6E57 # 0 +0x008FC7FC 0x6E5C # 0 +0x008FC7FD 0x6E5D # 0 +0x008FC7FE 0x6E5E # 0 +0x008FC8A1 0x6E62 # 0 +0x008FC8A2 0x6E63 # 0 +0x008FC8A3 0x6E68 # 0 +0x008FC8A4 0x6E73 # 0 +0x008FC8A5 0x6E7B # 0 +0x008FC8A6 0x6E7D # 0 +0x008FC8A7 0x6E8D # 0 +0x008FC8A8 0x6E93 # 0 +0x008FC8A9 0x6E99 # 0 +0x008FC8AA 0x6EA0 # 0 +0x008FC8AB 0x6EA7 # 0 +0x008FC8AC 0x6EAD # 0 +0x008FC8AD 0x6EAE # 0 +0x008FC8AE 0x6EB1 # 0 +0x008FC8AF 0x6EB3 # 0 +0x008FC8B0 0x6EBB # 0 +0x008FC8B1 0x6EBF # 0 +0x008FC8B2 0x6EC0 # 0 +0x008FC8B3 0x6EC1 # 0 +0x008FC8B4 0x6EC3 # 0 +0x008FC8B5 0x6EC7 # 0 +0x008FC8B6 0x6EC8 # 0 +0x008FC8B7 0x6ECA # 0 +0x008FC8B8 0x6ECD # 0 +0x008FC8B9 0x6ECE # 0 +0x008FC8BA 0x6ECF # 0 +0x008FC8BB 0x6EEB # 0 +0x008FC8BC 0x6EED # 0 +0x008FC8BD 0x6EEE # 0 +0x008FC8BE 0x6EF9 # 0 +0x008FC8BF 0x6EFB # 0 +0x008FC8C0 0x6EFD # 0 +0x008FC8C1 0x6F04 # 0 +0x008FC8C2 0x6F08 # 0 +0x008FC8C3 0x6F0A # 0 +0x008FC8C4 0x6F0C # 0 +0x008FC8C5 0x6F0D # 0 +0x008FC8C6 0x6F16 # 0 +0x008FC8C7 0x6F18 # 0 +0x008FC8C8 0x6F1A # 0 +0x008FC8C9 0x6F1B # 0 +0x008FC8CA 0x6F26 # 0 +0x008FC8CB 0x6F29 # 0 +0x008FC8CC 0x6F2A # 0 +0x008FC8CD 0x6F2F # 0 +0x008FC8CE 0x6F30 # 0 +0x008FC8CF 0x6F33 # 0 +0x008FC8D0 0x6F36 # 0 +0x008FC8D1 0x6F3B # 0 +0x008FC8D2 0x6F3C # 0 +0x008FC8D3 0x6F2D # 0 +0x008FC8D4 0x6F4F # 0 +0x008FC8D5 0x6F51 # 0 +0x008FC8D6 0x6F52 # 0 +0x008FC8D7 0x6F53 # 0 +0x008FC8D8 0x6F57 # 0 +0x008FC8D9 0x6F59 # 0 +0x008FC8DA 0x6F5A # 0 +0x008FC8DB 0x6F5D # 0 +0x008FC8DC 0x6F5E # 0 +0x008FC8DD 0x6F61 # 0 +0x008FC8DE 0x6F62 # 0 +0x008FC8DF 0x6F68 # 0 +0x008FC8E0 0x6F6C # 0 +0x008FC8E1 0x6F7D # 0 +0x008FC8E2 0x6F7E # 0 +0x008FC8E3 0x6F83 # 0 +0x008FC8E4 0x6F87 # 0 +0x008FC8E5 0x6F88 # 0 +0x008FC8E6 0x6F8B # 0 +0x008FC8E7 0x6F8C # 0 +0x008FC8E8 0x6F8D # 0 +0x008FC8E9 0x6F90 # 0 +0x008FC8EA 0x6F92 # 0 +0x008FC8EB 0x6F93 # 0 +0x008FC8EC 0x6F94 # 0 +0x008FC8ED 0x6F96 # 0 +0x008FC8EE 0x6F9A # 0 +0x008FC8EF 0x6F9F # 0 +0x008FC8F0 0x6FA0 # 0 +0x008FC8F1 0x6FA5 # 0 +0x008FC8F2 0x6FA6 # 0 +0x008FC8F3 0x6FA7 # 0 +0x008FC8F4 0x6FA8 # 0 +0x008FC8F5 0x6FAE # 0 +0x008FC8F6 0x6FAF # 0 +0x008FC8F7 0x6FB0 # 0 +0x008FC8F8 0x6FB5 # 0 +0x008FC8F9 0x6FB6 # 0 +0x008FC8FA 0x6FBC # 0 +0x008FC8FB 0x6FC5 # 0 +0x008FC8FC 0x6FC7 # 0 +0x008FC8FD 0x6FC8 # 0 +0x008FC8FE 0x6FCA # 0 +0x008FC9A1 0x6FDA # 0 +0x008FC9A2 0x6FDE # 0 +0x008FC9A3 0x6FE8 # 0 +0x008FC9A4 0x6FE9 # 0 +0x008FC9A5 0x6FF0 # 0 +0x008FC9A6 0x6FF5 # 0 +0x008FC9A7 0x6FF9 # 0 +0x008FC9A8 0x6FFC # 0 +0x008FC9A9 0x6FFD # 0 +0x008FC9AA 0x7000 # 0 +0x008FC9AB 0x7005 # 0 +0x008FC9AC 0x7006 # 0 +0x008FC9AD 0x7007 # 0 +0x008FC9AE 0x700D # 0 +0x008FC9AF 0x7017 # 0 +0x008FC9B0 0x7020 # 0 +0x008FC9B1 0x7023 # 0 +0x008FC9B2 0x702F # 0 +0x008FC9B3 0x7034 # 0 +0x008FC9B4 0x7037 # 0 +0x008FC9B5 0x7039 # 0 +0x008FC9B6 0x703C # 0 +0x008FC9B7 0x7043 # 0 +0x008FC9B8 0x7044 # 0 +0x008FC9B9 0x7048 # 0 +0x008FC9BA 0x7049 # 0 +0x008FC9BB 0x704A # 0 +0x008FC9BC 0x704B # 0 +0x008FC9BD 0x7054 # 0 +0x008FC9BE 0x7055 # 0 +0x008FC9BF 0x705D # 0 +0x008FC9C0 0x705E # 0 +0x008FC9C1 0x704E # 0 +0x008FC9C2 0x7064 # 0 +0x008FC9C3 0x7065 # 0 +0x008FC9C4 0x706C # 0 +0x008FC9C5 0x706E # 0 +0x008FC9C6 0x7075 # 0 +0x008FC9C7 0x7076 # 0 +0x008FC9C8 0x707E # 0 +0x008FC9C9 0x7081 # 0 +0x008FC9CA 0x7085 # 0 +0x008FC9CB 0x7086 # 0 +0x008FC9CC 0x7094 # 0 +0x008FC9CD 0x7095 # 0 +0x008FC9CE 0x7096 # 0 +0x008FC9CF 0x7097 # 0 +0x008FC9D0 0x7098 # 0 +0x008FC9D1 0x709B # 0 +0x008FC9D2 0x70A4 # 0 +0x008FC9D3 0x70AB # 0 +0x008FC9D4 0x70B0 # 0 +0x008FC9D5 0x70B1 # 0 +0x008FC9D6 0x70B4 # 0 +0x008FC9D7 0x70B7 # 0 +0x008FC9D8 0x70CA # 0 +0x008FC9D9 0x70D1 # 0 +0x008FC9DA 0x70D3 # 0 +0x008FC9DB 0x70D4 # 0 +0x008FC9DC 0x70D5 # 0 +0x008FC9DD 0x70D6 # 0 +0x008FC9DE 0x70D8 # 0 +0x008FC9DF 0x70DC # 0 +0x008FC9E0 0x70E4 # 0 +0x008FC9E1 0x70FA # 0 +0x008FC9E2 0x7103 # 0 +0x008FC9E3 0x7104 # 0 +0x008FC9E4 0x7105 # 0 +0x008FC9E5 0x7106 # 0 +0x008FC9E6 0x7107 # 0 +0x008FC9E7 0x710B # 0 +0x008FC9E8 0x710C # 0 +0x008FC9E9 0x710F # 0 +0x008FC9EA 0x711E # 0 +0x008FC9EB 0x7120 # 0 +0x008FC9EC 0x712B # 0 +0x008FC9ED 0x712D # 0 +0x008FC9EE 0x712F # 0 +0x008FC9EF 0x7130 # 0 +0x008FC9F0 0x7131 # 0 +0x008FC9F1 0x7138 # 0 +0x008FC9F2 0x7141 # 0 +0x008FC9F3 0x7145 # 0 +0x008FC9F4 0x7146 # 0 +0x008FC9F5 0x7147 # 0 +0x008FC9F6 0x714A # 0 +0x008FC9F7 0x714B # 0 +0x008FC9F8 0x7150 # 0 +0x008FC9F9 0x7152 # 0 +0x008FC9FA 0x7157 # 0 +0x008FC9FB 0x715A # 0 +0x008FC9FC 0x715C # 0 +0x008FC9FD 0x715E # 0 +0x008FC9FE 0x7160 # 0 +0x008FCAA1 0x7168 # 0 +0x008FCAA2 0x7179 # 0 +0x008FCAA3 0x7180 # 0 +0x008FCAA4 0x7185 # 0 +0x008FCAA5 0x7187 # 0 +0x008FCAA6 0x718C # 0 +0x008FCAA7 0x7192 # 0 +0x008FCAA8 0x719A # 0 +0x008FCAA9 0x719B # 0 +0x008FCAAA 0x71A0 # 0 +0x008FCAAB 0x71A2 # 0 +0x008FCAAC 0x71AF # 0 +0x008FCAAD 0x71B0 # 0 +0x008FCAAE 0x71B2 # 0 +0x008FCAAF 0x71B3 # 0 +0x008FCAB0 0x71BA # 0 +0x008FCAB1 0x71BF # 0 +0x008FCAB2 0x71C0 # 0 +0x008FCAB3 0x71C1 # 0 +0x008FCAB4 0x71C4 # 0 +0x008FCAB5 0x71CB # 0 +0x008FCAB6 0x71CC # 0 +0x008FCAB7 0x71D3 # 0 +0x008FCAB8 0x71D6 # 0 +0x008FCAB9 0x71D9 # 0 +0x008FCABA 0x71DA # 0 +0x008FCABB 0x71DC # 0 +0x008FCABC 0x71F8 # 0 +0x008FCABD 0x71FE # 0 +0x008FCABE 0x7200 # 0 +0x008FCABF 0x7207 # 0 +0x008FCAC0 0x7208 # 0 +0x008FCAC1 0x7209 # 0 +0x008FCAC2 0x7213 # 0 +0x008FCAC3 0x7217 # 0 +0x008FCAC4 0x721A # 0 +0x008FCAC5 0x721D # 0 +0x008FCAC6 0x721F # 0 +0x008FCAC7 0x7224 # 0 +0x008FCAC8 0x722B # 0 +0x008FCAC9 0x722F # 0 +0x008FCACA 0x7234 # 0 +0x008FCACB 0x7238 # 0 +0x008FCACC 0x7239 # 0 +0x008FCACD 0x7241 # 0 +0x008FCACE 0x7242 # 0 +0x008FCACF 0x7243 # 0 +0x008FCAD0 0x7245 # 0 +0x008FCAD1 0x724E # 0 +0x008FCAD2 0x724F # 0 +0x008FCAD3 0x7250 # 0 +0x008FCAD4 0x7253 # 0 +0x008FCAD5 0x7255 # 0 +0x008FCAD6 0x7256 # 0 +0x008FCAD7 0x725A # 0 +0x008FCAD8 0x725C # 0 +0x008FCAD9 0x725E # 0 +0x008FCADA 0x7260 # 0 +0x008FCADB 0x7263 # 0 +0x008FCADC 0x7268 # 0 +0x008FCADD 0x726B # 0 +0x008FCADE 0x726E # 0 +0x008FCADF 0x726F # 0 +0x008FCAE0 0x7271 # 0 +0x008FCAE1 0x7277 # 0 +0x008FCAE2 0x7278 # 0 +0x008FCAE3 0x727B # 0 +0x008FCAE4 0x727C # 0 +0x008FCAE5 0x727F # 0 +0x008FCAE6 0x7284 # 0 +0x008FCAE7 0x7289 # 0 +0x008FCAE8 0x728D # 0 +0x008FCAE9 0x728E # 0 +0x008FCAEA 0x7293 # 0 +0x008FCAEB 0x729B # 0 +0x008FCAEC 0x72A8 # 0 +0x008FCAED 0x72AD # 0 +0x008FCAEE 0x72AE # 0 +0x008FCAEF 0x72B1 # 0 +0x008FCAF0 0x72B4 # 0 +0x008FCAF1 0x72BE # 0 +0x008FCAF2 0x72C1 # 0 +0x008FCAF3 0x72C7 # 0 +0x008FCAF4 0x72C9 # 0 +0x008FCAF5 0x72CC # 0 +0x008FCAF6 0x72D5 # 0 +0x008FCAF7 0x72D6 # 0 +0x008FCAF8 0x72D8 # 0 +0x008FCAF9 0x72DF # 0 +0x008FCAFA 0x72E5 # 0 +0x008FCAFB 0x72F3 # 0 +0x008FCAFC 0x72F4 # 0 +0x008FCAFD 0x72FA # 0 +0x008FCAFE 0x72FB # 0 +0x008FCBA1 0x72FE # 0 +0x008FCBA2 0x7302 # 0 +0x008FCBA3 0x7304 # 0 +0x008FCBA4 0x7305 # 0 +0x008FCBA5 0x7307 # 0 +0x008FCBA6 0x730B # 0 +0x008FCBA7 0x730D # 0 +0x008FCBA8 0x7312 # 0 +0x008FCBA9 0x7313 # 0 +0x008FCBAA 0x7318 # 0 +0x008FCBAB 0x7319 # 0 +0x008FCBAC 0x731E # 0 +0x008FCBAD 0x7322 # 0 +0x008FCBAE 0x7324 # 0 +0x008FCBAF 0x7327 # 0 +0x008FCBB0 0x7328 # 0 +0x008FCBB1 0x732C # 0 +0x008FCBB2 0x7331 # 0 +0x008FCBB3 0x7332 # 0 +0x008FCBB4 0x7335 # 0 +0x008FCBB5 0x733A # 0 +0x008FCBB6 0x733B # 0 +0x008FCBB7 0x733D # 0 +0x008FCBB8 0x7343 # 0 +0x008FCBB9 0x734D # 0 +0x008FCBBA 0x7350 # 0 +0x008FCBBB 0x7352 # 0 +0x008FCBBC 0x7356 # 0 +0x008FCBBD 0x7358 # 0 +0x008FCBBE 0x735D # 0 +0x008FCBBF 0x735E # 0 +0x008FCBC0 0x735F # 0 +0x008FCBC1 0x7360 # 0 +0x008FCBC2 0x7366 # 0 +0x008FCBC3 0x7367 # 0 +0x008FCBC4 0x7369 # 0 +0x008FCBC5 0x736B # 0 +0x008FCBC6 0x736C # 0 +0x008FCBC7 0x736E # 0 +0x008FCBC8 0x736F # 0 +0x008FCBC9 0x7371 # 0 +0x008FCBCA 0x7377 # 0 +0x008FCBCB 0x7379 # 0 +0x008FCBCC 0x737C # 0 +0x008FCBCD 0x7380 # 0 +0x008FCBCE 0x7381 # 0 +0x008FCBCF 0x7383 # 0 +0x008FCBD0 0x7385 # 0 +0x008FCBD1 0x7386 # 0 +0x008FCBD2 0x738E # 0 +0x008FCBD3 0x7390 # 0 +0x008FCBD4 0x7393 # 0 +0x008FCBD5 0x7395 # 0 +0x008FCBD6 0x7397 # 0 +0x008FCBD7 0x7398 # 0 +0x008FCBD8 0x739C # 0 +0x008FCBD9 0x739E # 0 +0x008FCBDA 0x739F # 0 +0x008FCBDB 0x73A0 # 0 +0x008FCBDC 0x73A2 # 0 +0x008FCBDD 0x73A5 # 0 +0x008FCBDE 0x73A6 # 0 +0x008FCBDF 0x73AA # 0 +0x008FCBE0 0x73AB # 0 +0x008FCBE1 0x73AD # 0 +0x008FCBE2 0x73B5 # 0 +0x008FCBE3 0x73B7 # 0 +0x008FCBE4 0x73B9 # 0 +0x008FCBE5 0x73BC # 0 +0x008FCBE6 0x73BD # 0 +0x008FCBE7 0x73BF # 0 +0x008FCBE8 0x73C5 # 0 +0x008FCBE9 0x73C6 # 0 +0x008FCBEA 0x73C9 # 0 +0x008FCBEB 0x73CB # 0 +0x008FCBEC 0x73CC # 0 +0x008FCBED 0x73CF # 0 +0x008FCBEE 0x73D2 # 0 +0x008FCBEF 0x73D3 # 0 +0x008FCBF0 0x73D6 # 0 +0x008FCBF1 0x73D9 # 0 +0x008FCBF2 0x73DD # 0 +0x008FCBF3 0x73E1 # 0 +0x008FCBF4 0x73E3 # 0 +0x008FCBF5 0x73E6 # 0 +0x008FCBF6 0x73E7 # 0 +0x008FCBF7 0x73E9 # 0 +0x008FCBF8 0x73F4 # 0 +0x008FCBF9 0x73F5 # 0 +0x008FCBFA 0x73F7 # 0 +0x008FCBFB 0x73F9 # 0 +0x008FCBFC 0x73FA # 0 +0x008FCBFD 0x73FB # 0 +0x008FCBFE 0x73FD # 0 +0x008FCCA1 0x73FF # 0 +0x008FCCA2 0x7400 # 0 +0x008FCCA3 0x7401 # 0 +0x008FCCA4 0x7404 # 0 +0x008FCCA5 0x7407 # 0 +0x008FCCA6 0x740A # 0 +0x008FCCA7 0x7411 # 0 +0x008FCCA8 0x741A # 0 +0x008FCCA9 0x741B # 0 +0x008FCCAA 0x7424 # 0 +0x008FCCAB 0x7426 # 0 +0x008FCCAC 0x7428 # 0 +0x008FCCAD 0x7429 # 0 +0x008FCCAE 0x742A # 0 +0x008FCCAF 0x742B # 0 +0x008FCCB0 0x742C # 0 +0x008FCCB1 0x742D # 0 +0x008FCCB2 0x742E # 0 +0x008FCCB3 0x742F # 0 +0x008FCCB4 0x7430 # 0 +0x008FCCB5 0x7431 # 0 +0x008FCCB6 0x7439 # 0 +0x008FCCB7 0x7440 # 0 +0x008FCCB8 0x7443 # 0 +0x008FCCB9 0x7444 # 0 +0x008FCCBA 0x7446 # 0 +0x008FCCBB 0x7447 # 0 +0x008FCCBC 0x744B # 0 +0x008FCCBD 0x744D # 0 +0x008FCCBE 0x7451 # 0 +0x008FCCBF 0x7452 # 0 +0x008FCCC0 0x7457 # 0 +0x008FCCC1 0x745D # 0 +0x008FCCC2 0x7462 # 0 +0x008FCCC3 0x7466 # 0 +0x008FCCC4 0x7467 # 0 +0x008FCCC5 0x7468 # 0 +0x008FCCC6 0x746B # 0 +0x008FCCC7 0x746D # 0 +0x008FCCC8 0x746E # 0 +0x008FCCC9 0x7471 # 0 +0x008FCCCA 0x7472 # 0 +0x008FCCCB 0x7480 # 0 +0x008FCCCC 0x7481 # 0 +0x008FCCCD 0x7485 # 0 +0x008FCCCE 0x7486 # 0 +0x008FCCCF 0x7487 # 0 +0x008FCCD0 0x7489 # 0 +0x008FCCD1 0x748F # 0 +0x008FCCD2 0x7490 # 0 +0x008FCCD3 0x7491 # 0 +0x008FCCD4 0x7492 # 0 +0x008FCCD5 0x7498 # 0 +0x008FCCD6 0x7499 # 0 +0x008FCCD7 0x749A # 0 +0x008FCCD8 0x749C # 0 +0x008FCCD9 0x749F # 0 +0x008FCCDA 0x74A0 # 0 +0x008FCCDB 0x74A1 # 0 +0x008FCCDC 0x74A3 # 0 +0x008FCCDD 0x74A6 # 0 +0x008FCCDE 0x74A8 # 0 +0x008FCCDF 0x74A9 # 0 +0x008FCCE0 0x74AA # 0 +0x008FCCE1 0x74AB # 0 +0x008FCCE2 0x74AE # 0 +0x008FCCE3 0x74AF # 0 +0x008FCCE4 0x74B1 # 0 +0x008FCCE5 0x74B2 # 0 +0x008FCCE6 0x74B5 # 0 +0x008FCCE7 0x74B9 # 0 +0x008FCCE8 0x74BB # 0 +0x008FCCE9 0x74BF # 0 +0x008FCCEA 0x74C8 # 0 +0x008FCCEB 0x74C9 # 0 +0x008FCCEC 0x74CC # 0 +0x008FCCED 0x74D0 # 0 +0x008FCCEE 0x74D3 # 0 +0x008FCCEF 0x74D8 # 0 +0x008FCCF0 0x74DA # 0 +0x008FCCF1 0x74DB # 0 +0x008FCCF2 0x74DE # 0 +0x008FCCF3 0x74DF # 0 +0x008FCCF4 0x74E4 # 0 +0x008FCCF5 0x74E8 # 0 +0x008FCCF6 0x74EA # 0 +0x008FCCF7 0x74EB # 0 +0x008FCCF8 0x74EF # 0 +0x008FCCF9 0x74F4 # 0 +0x008FCCFA 0x74FA # 0 +0x008FCCFB 0x74FB # 0 +0x008FCCFC 0x74FC # 0 +0x008FCCFD 0x74FF # 0 +0x008FCCFE 0x7506 # 0 +0x008FCDA1 0x7512 # 0 +0x008FCDA2 0x7516 # 0 +0x008FCDA3 0x7517 # 0 +0x008FCDA4 0x7520 # 0 +0x008FCDA5 0x7521 # 0 +0x008FCDA6 0x7524 # 0 +0x008FCDA7 0x7527 # 0 +0x008FCDA8 0x7529 # 0 +0x008FCDA9 0x752A # 0 +0x008FCDAA 0x752F # 0 +0x008FCDAB 0x7536 # 0 +0x008FCDAC 0x7539 # 0 +0x008FCDAD 0x753D # 0 +0x008FCDAE 0x753E # 0 +0x008FCDAF 0x753F # 0 +0x008FCDB0 0x7540 # 0 +0x008FCDB1 0x7543 # 0 +0x008FCDB2 0x7547 # 0 +0x008FCDB3 0x7548 # 0 +0x008FCDB4 0x754E # 0 +0x008FCDB5 0x7550 # 0 +0x008FCDB6 0x7552 # 0 +0x008FCDB7 0x7557 # 0 +0x008FCDB8 0x755E # 0 +0x008FCDB9 0x755F # 0 +0x008FCDBA 0x7561 # 0 +0x008FCDBB 0x756F # 0 +0x008FCDBC 0x7571 # 0 +0x008FCDBD 0x7579 # 0 +0x008FCDBE 0x757A # 0 +0x008FCDBF 0x757B # 0 +0x008FCDC0 0x757C # 0 +0x008FCDC1 0x757D # 0 +0x008FCDC2 0x757E # 0 +0x008FCDC3 0x7581 # 0 +0x008FCDC4 0x7585 # 0 +0x008FCDC5 0x7590 # 0 +0x008FCDC6 0x7592 # 0 +0x008FCDC7 0x7593 # 0 +0x008FCDC8 0x7595 # 0 +0x008FCDC9 0x7599 # 0 +0x008FCDCA 0x759C # 0 +0x008FCDCB 0x75A2 # 0 +0x008FCDCC 0x75A4 # 0 +0x008FCDCD 0x75B4 # 0 +0x008FCDCE 0x75BA # 0 +0x008FCDCF 0x75BF # 0 +0x008FCDD0 0x75C0 # 0 +0x008FCDD1 0x75C1 # 0 +0x008FCDD2 0x75C4 # 0 +0x008FCDD3 0x75C6 # 0 +0x008FCDD4 0x75CC # 0 +0x008FCDD5 0x75CE # 0 +0x008FCDD6 0x75CF # 0 +0x008FCDD7 0x75D7 # 0 +0x008FCDD8 0x75DC # 0 +0x008FCDD9 0x75DF # 0 +0x008FCDDA 0x75E0 # 0 +0x008FCDDB 0x75E1 # 0 +0x008FCDDC 0x75E4 # 0 +0x008FCDDD 0x75E7 # 0 +0x008FCDDE 0x75EC # 0 +0x008FCDDF 0x75EE # 0 +0x008FCDE0 0x75EF # 0 +0x008FCDE1 0x75F1 # 0 +0x008FCDE2 0x75F9 # 0 +0x008FCDE3 0x7600 # 0 +0x008FCDE4 0x7602 # 0 +0x008FCDE5 0x7603 # 0 +0x008FCDE6 0x7604 # 0 +0x008FCDE7 0x7607 # 0 +0x008FCDE8 0x7608 # 0 +0x008FCDE9 0x760A # 0 +0x008FCDEA 0x760C # 0 +0x008FCDEB 0x760F # 0 +0x008FCDEC 0x7612 # 0 +0x008FCDED 0x7613 # 0 +0x008FCDEE 0x7615 # 0 +0x008FCDEF 0x7616 # 0 +0x008FCDF0 0x7619 # 0 +0x008FCDF1 0x761B # 0 +0x008FCDF2 0x761C # 0 +0x008FCDF3 0x761D # 0 +0x008FCDF4 0x761E # 0 +0x008FCDF5 0x7623 # 0 +0x008FCDF6 0x7625 # 0 +0x008FCDF7 0x7626 # 0 +0x008FCDF8 0x7629 # 0 +0x008FCDF9 0x762D # 0 +0x008FCDFA 0x7632 # 0 +0x008FCDFB 0x7633 # 0 +0x008FCDFC 0x7635 # 0 +0x008FCDFD 0x7638 # 0 +0x008FCDFE 0x7639 # 0 +0x008FCEA1 0x763A # 0 +0x008FCEA2 0x763C # 0 +0x008FCEA3 0x764A # 0 +0x008FCEA4 0x7640 # 0 +0x008FCEA5 0x7641 # 0 +0x008FCEA6 0x7643 # 0 +0x008FCEA7 0x7644 # 0 +0x008FCEA8 0x7645 # 0 +0x008FCEA9 0x7649 # 0 +0x008FCEAA 0x764B # 0 +0x008FCEAB 0x7655 # 0 +0x008FCEAC 0x7659 # 0 +0x008FCEAD 0x765F # 0 +0x008FCEAE 0x7664 # 0 +0x008FCEAF 0x7665 # 0 +0x008FCEB0 0x766D # 0 +0x008FCEB1 0x766E # 0 +0x008FCEB2 0x766F # 0 +0x008FCEB3 0x7671 # 0 +0x008FCEB4 0x7674 # 0 +0x008FCEB5 0x7681 # 0 +0x008FCEB6 0x7685 # 0 +0x008FCEB7 0x768C # 0 +0x008FCEB8 0x768D # 0 +0x008FCEB9 0x7695 # 0 +0x008FCEBA 0x769B # 0 +0x008FCEBB 0x769C # 0 +0x008FCEBC 0x769D # 0 +0x008FCEBD 0x769F # 0 +0x008FCEBE 0x76A0 # 0 +0x008FCEBF 0x76A2 # 0 +0x008FCEC0 0x76A3 # 0 +0x008FCEC1 0x76A4 # 0 +0x008FCEC2 0x76A5 # 0 +0x008FCEC3 0x76A6 # 0 +0x008FCEC4 0x76A7 # 0 +0x008FCEC5 0x76A8 # 0 +0x008FCEC6 0x76AA # 0 +0x008FCEC7 0x76AD # 0 +0x008FCEC8 0x76BD # 0 +0x008FCEC9 0x76C1 # 0 +0x008FCECA 0x76C5 # 0 +0x008FCECB 0x76C9 # 0 +0x008FCECC 0x76CB # 0 +0x008FCECD 0x76CC # 0 +0x008FCECE 0x76CE # 0 +0x008FCECF 0x76D4 # 0 +0x008FCED0 0x76D9 # 0 +0x008FCED1 0x76E0 # 0 +0x008FCED2 0x76E6 # 0 +0x008FCED3 0x76E8 # 0 +0x008FCED4 0x76EC # 0 +0x008FCED5 0x76F0 # 0 +0x008FCED6 0x76F1 # 0 +0x008FCED7 0x76F6 # 0 +0x008FCED8 0x76F9 # 0 +0x008FCED9 0x76FC # 0 +0x008FCEDA 0x7700 # 0 +0x008FCEDB 0x7706 # 0 +0x008FCEDC 0x770A # 0 +0x008FCEDD 0x770E # 0 +0x008FCEDE 0x7712 # 0 +0x008FCEDF 0x7714 # 0 +0x008FCEE0 0x7715 # 0 +0x008FCEE1 0x7717 # 0 +0x008FCEE2 0x7719 # 0 +0x008FCEE3 0x771A # 0 +0x008FCEE4 0x771C # 0 +0x008FCEE5 0x7722 # 0 +0x008FCEE6 0x7728 # 0 +0x008FCEE7 0x772D # 0 +0x008FCEE8 0x772E # 0 +0x008FCEE9 0x772F # 0 +0x008FCEEA 0x7734 # 0 +0x008FCEEB 0x7735 # 0 +0x008FCEEC 0x7736 # 0 +0x008FCEED 0x7739 # 0 +0x008FCEEE 0x773D # 0 +0x008FCEEF 0x773E # 0 +0x008FCEF0 0x7742 # 0 +0x008FCEF1 0x7745 # 0 +0x008FCEF2 0x7746 # 0 +0x008FCEF3 0x774A # 0 +0x008FCEF4 0x774D # 0 +0x008FCEF5 0x774E # 0 +0x008FCEF6 0x774F # 0 +0x008FCEF7 0x7752 # 0 +0x008FCEF8 0x7756 # 0 +0x008FCEF9 0x7757 # 0 +0x008FCEFA 0x775C # 0 +0x008FCEFB 0x775E # 0 +0x008FCEFC 0x775F # 0 +0x008FCEFD 0x7760 # 0 +0x008FCEFE 0x7762 # 0 +0x008FCFA1 0x7764 # 0 +0x008FCFA2 0x7767 # 0 +0x008FCFA3 0x776A # 0 +0x008FCFA4 0x776C # 0 +0x008FCFA5 0x7770 # 0 +0x008FCFA6 0x7772 # 0 +0x008FCFA7 0x7773 # 0 +0x008FCFA8 0x7774 # 0 +0x008FCFA9 0x777A # 0 +0x008FCFAA 0x777D # 0 +0x008FCFAB 0x7780 # 0 +0x008FCFAC 0x7784 # 0 +0x008FCFAD 0x778C # 0 +0x008FCFAE 0x778D # 0 +0x008FCFAF 0x7794 # 0 +0x008FCFB0 0x7795 # 0 +0x008FCFB1 0x7796 # 0 +0x008FCFB2 0x779A # 0 +0x008FCFB3 0x779F # 0 +0x008FCFB4 0x77A2 # 0 +0x008FCFB5 0x77A7 # 0 +0x008FCFB6 0x77AA # 0 +0x008FCFB7 0x77AE # 0 +0x008FCFB8 0x77AF # 0 +0x008FCFB9 0x77B1 # 0 +0x008FCFBA 0x77B5 # 0 +0x008FCFBB 0x77BE # 0 +0x008FCFBC 0x77C3 # 0 +0x008FCFBD 0x77C9 # 0 +0x008FCFBE 0x77D1 # 0 +0x008FCFBF 0x77D2 # 0 +0x008FCFC0 0x77D5 # 0 +0x008FCFC1 0x77D9 # 0 +0x008FCFC2 0x77DE # 0 +0x008FCFC3 0x77DF # 0 +0x008FCFC4 0x77E0 # 0 +0x008FCFC5 0x77E4 # 0 +0x008FCFC6 0x77E6 # 0 +0x008FCFC7 0x77EA # 0 +0x008FCFC8 0x77EC # 0 +0x008FCFC9 0x77F0 # 0 +0x008FCFCA 0x77F1 # 0 +0x008FCFCB 0x77F4 # 0 +0x008FCFCC 0x77F8 # 0 +0x008FCFCD 0x77FB # 0 +0x008FCFCE 0x7805 # 0 +0x008FCFCF 0x7806 # 0 +0x008FCFD0 0x7809 # 0 +0x008FCFD1 0x780D # 0 +0x008FCFD2 0x780E # 0 +0x008FCFD3 0x7811 # 0 +0x008FCFD4 0x781D # 0 +0x008FCFD5 0x7821 # 0 +0x008FCFD6 0x7822 # 0 +0x008FCFD7 0x7823 # 0 +0x008FCFD8 0x782D # 0 +0x008FCFD9 0x782E # 0 +0x008FCFDA 0x7830 # 0 +0x008FCFDB 0x7835 # 0 +0x008FCFDC 0x7837 # 0 +0x008FCFDD 0x7843 # 0 +0x008FCFDE 0x7844 # 0 +0x008FCFDF 0x7847 # 0 +0x008FCFE0 0x7848 # 0 +0x008FCFE1 0x784C # 0 +0x008FCFE2 0x784E # 0 +0x008FCFE3 0x7852 # 0 +0x008FCFE4 0x785C # 0 +0x008FCFE5 0x785E # 0 +0x008FCFE6 0x7860 # 0 +0x008FCFE7 0x7861 # 0 +0x008FCFE8 0x7863 # 0 +0x008FCFE9 0x7864 # 0 +0x008FCFEA 0x7868 # 0 +0x008FCFEB 0x786A # 0 +0x008FCFEC 0x786E # 0 +0x008FCFED 0x787A # 0 +0x008FCFEE 0x787E # 0 +0x008FCFEF 0x788A # 0 +0x008FCFF0 0x788F # 0 +0x008FCFF1 0x7894 # 0 +0x008FCFF2 0x7898 # 0 +0x008FCFF3 0x78A1 # 0 +0x008FCFF4 0x789D # 0 +0x008FCFF5 0x789E # 0 +0x008FCFF6 0x789F # 0 +0x008FCFF7 0x78A4 # 0 +0x008FCFF8 0x78A8 # 0 +0x008FCFF9 0x78AC # 0 +0x008FCFFA 0x78AD # 0 +0x008FCFFB 0x78B0 # 0 +0x008FCFFC 0x78B1 # 0 +0x008FCFFD 0x78B2 # 0 +0x008FCFFE 0x78B3 # 0 +0x008FD0A1 0x78BB # 0 +0x008FD0A2 0x78BD # 0 +0x008FD0A3 0x78BF # 0 +0x008FD0A4 0x78C7 # 0 +0x008FD0A5 0x78C8 # 0 +0x008FD0A6 0x78C9 # 0 +0x008FD0A7 0x78CC # 0 +0x008FD0A8 0x78CE # 0 +0x008FD0A9 0x78D2 # 0 +0x008FD0AA 0x78D3 # 0 +0x008FD0AB 0x78D5 # 0 +0x008FD0AC 0x78D6 # 0 +0x008FD0AD 0x78E4 # 0 +0x008FD0AE 0x78DB # 0 +0x008FD0AF 0x78DF # 0 +0x008FD0B0 0x78E0 # 0 +0x008FD0B1 0x78E1 # 0 +0x008FD0B2 0x78E6 # 0 +0x008FD0B3 0x78EA # 0 +0x008FD0B4 0x78F2 # 0 +0x008FD0B5 0x78F3 # 0 +0x008FD0B6 0x7900 # 0 +0x008FD0B7 0x78F6 # 0 +0x008FD0B8 0x78F7 # 0 +0x008FD0B9 0x78FA # 0 +0x008FD0BA 0x78FB # 0 +0x008FD0BB 0x78FF # 0 +0x008FD0BC 0x7906 # 0 +0x008FD0BD 0x790C # 0 +0x008FD0BE 0x7910 # 0 +0x008FD0BF 0x791A # 0 +0x008FD0C0 0x791C # 0 +0x008FD0C1 0x791E # 0 +0x008FD0C2 0x791F # 0 +0x008FD0C3 0x7920 # 0 +0x008FD0C4 0x7925 # 0 +0x008FD0C5 0x7927 # 0 +0x008FD0C6 0x7929 # 0 +0x008FD0C7 0x792D # 0 +0x008FD0C8 0x7931 # 0 +0x008FD0C9 0x7934 # 0 +0x008FD0CA 0x7935 # 0 +0x008FD0CB 0x793B # 0 +0x008FD0CC 0x793D # 0 +0x008FD0CD 0x793F # 0 +0x008FD0CE 0x7944 # 0 +0x008FD0CF 0x7945 # 0 +0x008FD0D0 0x7946 # 0 +0x008FD0D1 0x794A # 0 +0x008FD0D2 0x794B # 0 +0x008FD0D3 0x794F # 0 +0x008FD0D4 0x7951 # 0 +0x008FD0D5 0x7954 # 0 +0x008FD0D6 0x7958 # 0 +0x008FD0D7 0x795B # 0 +0x008FD0D8 0x795C # 0 +0x008FD0D9 0x7967 # 0 +0x008FD0DA 0x7969 # 0 +0x008FD0DB 0x796B # 0 +0x008FD0DC 0x7972 # 0 +0x008FD0DD 0x7979 # 0 +0x008FD0DE 0x797B # 0 +0x008FD0DF 0x797C # 0 +0x008FD0E0 0x797E # 0 +0x008FD0E1 0x798B # 0 +0x008FD0E2 0x798C # 0 +0x008FD0E3 0x7991 # 0 +0x008FD0E4 0x7993 # 0 +0x008FD0E5 0x7994 # 0 +0x008FD0E6 0x7995 # 0 +0x008FD0E7 0x7996 # 0 +0x008FD0E8 0x7998 # 0 +0x008FD0E9 0x799B # 0 +0x008FD0EA 0x799C # 0 +0x008FD0EB 0x79A1 # 0 +0x008FD0EC 0x79A8 # 0 +0x008FD0ED 0x79A9 # 0 +0x008FD0EE 0x79AB # 0 +0x008FD0EF 0x79AF # 0 +0x008FD0F0 0x79B1 # 0 +0x008FD0F1 0x79B4 # 0 +0x008FD0F2 0x79B8 # 0 +0x008FD0F3 0x79BB # 0 +0x008FD0F4 0x79C2 # 0 +0x008FD0F5 0x79C4 # 0 +0x008FD0F6 0x79C7 # 0 +0x008FD0F7 0x79C8 # 0 +0x008FD0F8 0x79CA # 0 +0x008FD0F9 0x79CF # 0 +0x008FD0FA 0x79D4 # 0 +0x008FD0FB 0x79D6 # 0 +0x008FD0FC 0x79DA # 0 +0x008FD0FD 0x79DD # 0 +0x008FD0FE 0x79DE # 0 +0x008FD1A1 0x79E0 # 0 +0x008FD1A2 0x79E2 # 0 +0x008FD1A3 0x79E5 # 0 +0x008FD1A4 0x79EA # 0 +0x008FD1A5 0x79EB # 0 +0x008FD1A6 0x79ED # 0 +0x008FD1A7 0x79F1 # 0 +0x008FD1A8 0x79F8 # 0 +0x008FD1A9 0x79FC # 0 +0x008FD1AA 0x7A02 # 0 +0x008FD1AB 0x7A03 # 0 +0x008FD1AC 0x7A07 # 0 +0x008FD1AD 0x7A09 # 0 +0x008FD1AE 0x7A0A # 0 +0x008FD1AF 0x7A0C # 0 +0x008FD1B0 0x7A11 # 0 +0x008FD1B1 0x7A15 # 0 +0x008FD1B2 0x7A1B # 0 +0x008FD1B3 0x7A1E # 0 +0x008FD1B4 0x7A21 # 0 +0x008FD1B5 0x7A27 # 0 +0x008FD1B6 0x7A2B # 0 +0x008FD1B7 0x7A2D # 0 +0x008FD1B8 0x7A2F # 0 +0x008FD1B9 0x7A30 # 0 +0x008FD1BA 0x7A34 # 0 +0x008FD1BB 0x7A35 # 0 +0x008FD1BC 0x7A38 # 0 +0x008FD1BD 0x7A39 # 0 +0x008FD1BE 0x7A3A # 0 +0x008FD1BF 0x7A44 # 0 +0x008FD1C0 0x7A45 # 0 +0x008FD1C1 0x7A47 # 0 +0x008FD1C2 0x7A48 # 0 +0x008FD1C3 0x7A4C # 0 +0x008FD1C4 0x7A55 # 0 +0x008FD1C5 0x7A56 # 0 +0x008FD1C6 0x7A59 # 0 +0x008FD1C7 0x7A5C # 0 +0x008FD1C8 0x7A5D # 0 +0x008FD1C9 0x7A5F # 0 +0x008FD1CA 0x7A60 # 0 +0x008FD1CB 0x7A65 # 0 +0x008FD1CC 0x7A67 # 0 +0x008FD1CD 0x7A6A # 0 +0x008FD1CE 0x7A6D # 0 +0x008FD1CF 0x7A75 # 0 +0x008FD1D0 0x7A78 # 0 +0x008FD1D1 0x7A7E # 0 +0x008FD1D2 0x7A80 # 0 +0x008FD1D3 0x7A82 # 0 +0x008FD1D4 0x7A85 # 0 +0x008FD1D5 0x7A86 # 0 +0x008FD1D6 0x7A8A # 0 +0x008FD1D7 0x7A8B # 0 +0x008FD1D8 0x7A90 # 0 +0x008FD1D9 0x7A91 # 0 +0x008FD1DA 0x7A94 # 0 +0x008FD1DB 0x7A9E # 0 +0x008FD1DC 0x7AA0 # 0 +0x008FD1DD 0x7AA3 # 0 +0x008FD1DE 0x7AAC # 0 +0x008FD1DF 0x7AB3 # 0 +0x008FD1E0 0x7AB5 # 0 +0x008FD1E1 0x7AB9 # 0 +0x008FD1E2 0x7ABB # 0 +0x008FD1E3 0x7ABC # 0 +0x008FD1E4 0x7AC6 # 0 +0x008FD1E5 0x7AC9 # 0 +0x008FD1E6 0x7ACC # 0 +0x008FD1E7 0x7ACE # 0 +0x008FD1E8 0x7AD1 # 0 +0x008FD1E9 0x7ADB # 0 +0x008FD1EA 0x7AE8 # 0 +0x008FD1EB 0x7AE9 # 0 +0x008FD1EC 0x7AEB # 0 +0x008FD1ED 0x7AEC # 0 +0x008FD1EE 0x7AF1 # 0 +0x008FD1EF 0x7AF4 # 0 +0x008FD1F0 0x7AFB # 0 +0x008FD1F1 0x7AFD # 0 +0x008FD1F2 0x7AFE # 0 +0x008FD1F3 0x7B07 # 0 +0x008FD1F4 0x7B14 # 0 +0x008FD1F5 0x7B1F # 0 +0x008FD1F6 0x7B23 # 0 +0x008FD1F7 0x7B27 # 0 +0x008FD1F8 0x7B29 # 0 +0x008FD1F9 0x7B2A # 0 +0x008FD1FA 0x7B2B # 0 +0x008FD1FB 0x7B2D # 0 +0x008FD1FC 0x7B2E # 0 +0x008FD1FD 0x7B2F # 0 +0x008FD1FE 0x7B30 # 0 +0x008FD2A1 0x7B31 # 0 +0x008FD2A2 0x7B34 # 0 +0x008FD2A3 0x7B3D # 0 +0x008FD2A4 0x7B3F # 0 +0x008FD2A5 0x7B40 # 0 +0x008FD2A6 0x7B41 # 0 +0x008FD2A7 0x7B47 # 0 +0x008FD2A8 0x7B4E # 0 +0x008FD2A9 0x7B55 # 0 +0x008FD2AA 0x7B60 # 0 +0x008FD2AB 0x7B64 # 0 +0x008FD2AC 0x7B66 # 0 +0x008FD2AD 0x7B69 # 0 +0x008FD2AE 0x7B6A # 0 +0x008FD2AF 0x7B6D # 0 +0x008FD2B0 0x7B6F # 0 +0x008FD2B1 0x7B72 # 0 +0x008FD2B2 0x7B73 # 0 +0x008FD2B3 0x7B77 # 0 +0x008FD2B4 0x7B84 # 0 +0x008FD2B5 0x7B89 # 0 +0x008FD2B6 0x7B8E # 0 +0x008FD2B7 0x7B90 # 0 +0x008FD2B8 0x7B91 # 0 +0x008FD2B9 0x7B96 # 0 +0x008FD2BA 0x7B9B # 0 +0x008FD2BB 0x7B9E # 0 +0x008FD2BC 0x7BA0 # 0 +0x008FD2BD 0x7BA5 # 0 +0x008FD2BE 0x7BAC # 0 +0x008FD2BF 0x7BAF # 0 +0x008FD2C0 0x7BB0 # 0 +0x008FD2C1 0x7BB2 # 0 +0x008FD2C2 0x7BB5 # 0 +0x008FD2C3 0x7BB6 # 0 +0x008FD2C4 0x7BBA # 0 +0x008FD2C5 0x7BBB # 0 +0x008FD2C6 0x7BBC # 0 +0x008FD2C7 0x7BBD # 0 +0x008FD2C8 0x7BC2 # 0 +0x008FD2C9 0x7BC5 # 0 +0x008FD2CA 0x7BC8 # 0 +0x008FD2CB 0x7BCA # 0 +0x008FD2CC 0x7BD4 # 0 +0x008FD2CD 0x7BD6 # 0 +0x008FD2CE 0x7BD7 # 0 +0x008FD2CF 0x7BD9 # 0 +0x008FD2D0 0x7BDA # 0 +0x008FD2D1 0x7BDB # 0 +0x008FD2D2 0x7BE8 # 0 +0x008FD2D3 0x7BEA # 0 +0x008FD2D4 0x7BF2 # 0 +0x008FD2D5 0x7BF4 # 0 +0x008FD2D6 0x7BF5 # 0 +0x008FD2D7 0x7BF8 # 0 +0x008FD2D8 0x7BF9 # 0 +0x008FD2D9 0x7BFA # 0 +0x008FD2DA 0x7BFC # 0 +0x008FD2DB 0x7BFE # 0 +0x008FD2DC 0x7C01 # 0 +0x008FD2DD 0x7C02 # 0 +0x008FD2DE 0x7C03 # 0 +0x008FD2DF 0x7C04 # 0 +0x008FD2E0 0x7C06 # 0 +0x008FD2E1 0x7C09 # 0 +0x008FD2E2 0x7C0B # 0 +0x008FD2E3 0x7C0C # 0 +0x008FD2E4 0x7C0E # 0 +0x008FD2E5 0x7C0F # 0 +0x008FD2E6 0x7C19 # 0 +0x008FD2E7 0x7C1B # 0 +0x008FD2E8 0x7C20 # 0 +0x008FD2E9 0x7C25 # 0 +0x008FD2EA 0x7C26 # 0 +0x008FD2EB 0x7C28 # 0 +0x008FD2EC 0x7C2C # 0 +0x008FD2ED 0x7C31 # 0 +0x008FD2EE 0x7C33 # 0 +0x008FD2EF 0x7C34 # 0 +0x008FD2F0 0x7C36 # 0 +0x008FD2F1 0x7C39 # 0 +0x008FD2F2 0x7C3A # 0 +0x008FD2F3 0x7C46 # 0 +0x008FD2F4 0x7C4A # 0 +0x008FD2F5 0x7C55 # 0 +0x008FD2F6 0x7C51 # 0 +0x008FD2F7 0x7C52 # 0 +0x008FD2F8 0x7C53 # 0 +0x008FD2F9 0x7C59 # 0 +0x008FD2FA 0x7C5A # 0 +0x008FD2FB 0x7C5B # 0 +0x008FD2FC 0x7C5C # 0 +0x008FD2FD 0x7C5D # 0 +0x008FD2FE 0x7C5E # 0 +0x008FD3A1 0x7C61 # 0 +0x008FD3A2 0x7C63 # 0 +0x008FD3A3 0x7C67 # 0 +0x008FD3A4 0x7C69 # 0 +0x008FD3A5 0x7C6D # 0 +0x008FD3A6 0x7C6E # 0 +0x008FD3A7 0x7C70 # 0 +0x008FD3A8 0x7C72 # 0 +0x008FD3A9 0x7C79 # 0 +0x008FD3AA 0x7C7C # 0 +0x008FD3AB 0x7C7D # 0 +0x008FD3AC 0x7C86 # 0 +0x008FD3AD 0x7C87 # 0 +0x008FD3AE 0x7C8F # 0 +0x008FD3AF 0x7C94 # 0 +0x008FD3B0 0x7C9E # 0 +0x008FD3B1 0x7CA0 # 0 +0x008FD3B2 0x7CA6 # 0 +0x008FD3B3 0x7CB0 # 0 +0x008FD3B4 0x7CB6 # 0 +0x008FD3B5 0x7CB7 # 0 +0x008FD3B6 0x7CBA # 0 +0x008FD3B7 0x7CBB # 0 +0x008FD3B8 0x7CBC # 0 +0x008FD3B9 0x7CBF # 0 +0x008FD3BA 0x7CC4 # 0 +0x008FD3BB 0x7CC7 # 0 +0x008FD3BC 0x7CC8 # 0 +0x008FD3BD 0x7CC9 # 0 +0x008FD3BE 0x7CCD # 0 +0x008FD3BF 0x7CCF # 0 +0x008FD3C0 0x7CD3 # 0 +0x008FD3C1 0x7CD4 # 0 +0x008FD3C2 0x7CD5 # 0 +0x008FD3C3 0x7CD7 # 0 +0x008FD3C4 0x7CD9 # 0 +0x008FD3C5 0x7CDA # 0 +0x008FD3C6 0x7CDD # 0 +0x008FD3C7 0x7CE6 # 0 +0x008FD3C8 0x7CE9 # 0 +0x008FD3C9 0x7CEB # 0 +0x008FD3CA 0x7CF5 # 0 +0x008FD3CB 0x7D03 # 0 +0x008FD3CC 0x7D07 # 0 +0x008FD3CD 0x7D08 # 0 +0x008FD3CE 0x7D09 # 0 +0x008FD3CF 0x7D0F # 0 +0x008FD3D0 0x7D11 # 0 +0x008FD3D1 0x7D12 # 0 +0x008FD3D2 0x7D13 # 0 +0x008FD3D3 0x7D16 # 0 +0x008FD3D4 0x7D1D # 0 +0x008FD3D5 0x7D1E # 0 +0x008FD3D6 0x7D23 # 0 +0x008FD3D7 0x7D26 # 0 +0x008FD3D8 0x7D2A # 0 +0x008FD3D9 0x7D2D # 0 +0x008FD3DA 0x7D31 # 0 +0x008FD3DB 0x7D3C # 0 +0x008FD3DC 0x7D3D # 0 +0x008FD3DD 0x7D3E # 0 +0x008FD3DE 0x7D40 # 0 +0x008FD3DF 0x7D41 # 0 +0x008FD3E0 0x7D47 # 0 +0x008FD3E1 0x7D48 # 0 +0x008FD3E2 0x7D4D # 0 +0x008FD3E3 0x7D51 # 0 +0x008FD3E4 0x7D53 # 0 +0x008FD3E5 0x7D57 # 0 +0x008FD3E6 0x7D59 # 0 +0x008FD3E7 0x7D5A # 0 +0x008FD3E8 0x7D5C # 0 +0x008FD3E9 0x7D5D # 0 +0x008FD3EA 0x7D65 # 0 +0x008FD3EB 0x7D67 # 0 +0x008FD3EC 0x7D6A # 0 +0x008FD3ED 0x7D70 # 0 +0x008FD3EE 0x7D78 # 0 +0x008FD3EF 0x7D7A # 0 +0x008FD3F0 0x7D7B # 0 +0x008FD3F1 0x7D7F # 0 +0x008FD3F2 0x7D81 # 0 +0x008FD3F3 0x7D82 # 0 +0x008FD3F4 0x7D83 # 0 +0x008FD3F5 0x7D85 # 0 +0x008FD3F6 0x7D86 # 0 +0x008FD3F7 0x7D88 # 0 +0x008FD3F8 0x7D8B # 0 +0x008FD3F9 0x7D8C # 0 +0x008FD3FA 0x7D8D # 0 +0x008FD3FB 0x7D91 # 0 +0x008FD3FC 0x7D96 # 0 +0x008FD3FD 0x7D97 # 0 +0x008FD3FE 0x7D9D # 0 +0x008FD4A1 0x7D9E # 0 +0x008FD4A2 0x7DA6 # 0 +0x008FD4A3 0x7DA7 # 0 +0x008FD4A4 0x7DAA # 0 +0x008FD4A5 0x7DB3 # 0 +0x008FD4A6 0x7DB6 # 0 +0x008FD4A7 0x7DB7 # 0 +0x008FD4A8 0x7DB9 # 0 +0x008FD4A9 0x7DC2 # 0 +0x008FD4AA 0x7DC3 # 0 +0x008FD4AB 0x7DC4 # 0 +0x008FD4AC 0x7DC5 # 0 +0x008FD4AD 0x7DC6 # 0 +0x008FD4AE 0x7DCC # 0 +0x008FD4AF 0x7DCD # 0 +0x008FD4B0 0x7DCE # 0 +0x008FD4B1 0x7DD7 # 0 +0x008FD4B2 0x7DD9 # 0 +0x008FD4B3 0x7E00 # 0 +0x008FD4B4 0x7DE2 # 0 +0x008FD4B5 0x7DE5 # 0 +0x008FD4B6 0x7DE6 # 0 +0x008FD4B7 0x7DEA # 0 +0x008FD4B8 0x7DEB # 0 +0x008FD4B9 0x7DED # 0 +0x008FD4BA 0x7DF1 # 0 +0x008FD4BB 0x7DF5 # 0 +0x008FD4BC 0x7DF6 # 0 +0x008FD4BD 0x7DF9 # 0 +0x008FD4BE 0x7DFA # 0 +0x008FD4BF 0x7E08 # 0 +0x008FD4C0 0x7E10 # 0 +0x008FD4C1 0x7E11 # 0 +0x008FD4C2 0x7E15 # 0 +0x008FD4C3 0x7E17 # 0 +0x008FD4C4 0x7E1C # 0 +0x008FD4C5 0x7E1D # 0 +0x008FD4C6 0x7E20 # 0 +0x008FD4C7 0x7E27 # 0 +0x008FD4C8 0x7E28 # 0 +0x008FD4C9 0x7E2C # 0 +0x008FD4CA 0x7E2D # 0 +0x008FD4CB 0x7E2F # 0 +0x008FD4CC 0x7E33 # 0 +0x008FD4CD 0x7E36 # 0 +0x008FD4CE 0x7E3F # 0 +0x008FD4CF 0x7E44 # 0 +0x008FD4D0 0x7E45 # 0 +0x008FD4D1 0x7E47 # 0 +0x008FD4D2 0x7E4E # 0 +0x008FD4D3 0x7E50 # 0 +0x008FD4D4 0x7E52 # 0 +0x008FD4D5 0x7E58 # 0 +0x008FD4D6 0x7E5F # 0 +0x008FD4D7 0x7E61 # 0 +0x008FD4D8 0x7E62 # 0 +0x008FD4D9 0x7E65 # 0 +0x008FD4DA 0x7E6B # 0 +0x008FD4DB 0x7E6E # 0 +0x008FD4DC 0x7E6F # 0 +0x008FD4DD 0x7E73 # 0 +0x008FD4DE 0x7E78 # 0 +0x008FD4DF 0x7E7E # 0 +0x008FD4E0 0x7E81 # 0 +0x008FD4E1 0x7E86 # 0 +0x008FD4E2 0x7E87 # 0 +0x008FD4E3 0x7E8A # 0 +0x008FD4E4 0x7E8D # 0 +0x008FD4E5 0x7E91 # 0 +0x008FD4E6 0x7E95 # 0 +0x008FD4E7 0x7E98 # 0 +0x008FD4E8 0x7E9A # 0 +0x008FD4E9 0x7E9D # 0 +0x008FD4EA 0x7E9E # 0 +0x008FD4EB 0x7F3C # 0 +0x008FD4EC 0x7F3B # 0 +0x008FD4ED 0x7F3D # 0 +0x008FD4EE 0x7F3E # 0 +0x008FD4EF 0x7F3F # 0 +0x008FD4F0 0x7F43 # 0 +0x008FD4F1 0x7F44 # 0 +0x008FD4F2 0x7F47 # 0 +0x008FD4F3 0x7F4F # 0 +0x008FD4F4 0x7F52 # 0 +0x008FD4F5 0x7F53 # 0 +0x008FD4F6 0x7F5B # 0 +0x008FD4F7 0x7F5C # 0 +0x008FD4F8 0x7F5D # 0 +0x008FD4F9 0x7F61 # 0 +0x008FD4FA 0x7F63 # 0 +0x008FD4FB 0x7F64 # 0 +0x008FD4FC 0x7F65 # 0 +0x008FD4FD 0x7F66 # 0 +0x008FD4FE 0x7F6D # 0 +0x008FD5A1 0x7F71 # 0 +0x008FD5A2 0x7F7D # 0 +0x008FD5A3 0x7F7E # 0 +0x008FD5A4 0x7F7F # 0 +0x008FD5A5 0x7F80 # 0 +0x008FD5A6 0x7F8B # 0 +0x008FD5A7 0x7F8D # 0 +0x008FD5A8 0x7F8F # 0 +0x008FD5A9 0x7F90 # 0 +0x008FD5AA 0x7F91 # 0 +0x008FD5AB 0x7F96 # 0 +0x008FD5AC 0x7F97 # 0 +0x008FD5AD 0x7F9C # 0 +0x008FD5AE 0x7FA1 # 0 +0x008FD5AF 0x7FA2 # 0 +0x008FD5B0 0x7FA6 # 0 +0x008FD5B1 0x7FAA # 0 +0x008FD5B2 0x7FAD # 0 +0x008FD5B3 0x7FB4 # 0 +0x008FD5B4 0x7FBC # 0 +0x008FD5B5 0x7FBF # 0 +0x008FD5B6 0x7FC0 # 0 +0x008FD5B7 0x7FC3 # 0 +0x008FD5B8 0x7FC8 # 0 +0x008FD5B9 0x7FCE # 0 +0x008FD5BA 0x7FCF # 0 +0x008FD5BB 0x7FDB # 0 +0x008FD5BC 0x7FDF # 0 +0x008FD5BD 0x7FE3 # 0 +0x008FD5BE 0x7FE5 # 0 +0x008FD5BF 0x7FE8 # 0 +0x008FD5C0 0x7FEC # 0 +0x008FD5C1 0x7FEE # 0 +0x008FD5C2 0x7FEF # 0 +0x008FD5C3 0x7FF2 # 0 +0x008FD5C4 0x7FFA # 0 +0x008FD5C5 0x7FFD # 0 +0x008FD5C6 0x7FFE # 0 +0x008FD5C7 0x7FFF # 0 +0x008FD5C8 0x8007 # 0 +0x008FD5C9 0x8008 # 0 +0x008FD5CA 0x800A # 0 +0x008FD5CB 0x800D # 0 +0x008FD5CC 0x800E # 0 +0x008FD5CD 0x800F # 0 +0x008FD5CE 0x8011 # 0 +0x008FD5CF 0x8013 # 0 +0x008FD5D0 0x8014 # 0 +0x008FD5D1 0x8016 # 0 +0x008FD5D2 0x801D # 0 +0x008FD5D3 0x801E # 0 +0x008FD5D4 0x801F # 0 +0x008FD5D5 0x8020 # 0 +0x008FD5D6 0x8024 # 0 +0x008FD5D7 0x8026 # 0 +0x008FD5D8 0x802C # 0 +0x008FD5D9 0x802E # 0 +0x008FD5DA 0x8030 # 0 +0x008FD5DB 0x8034 # 0 +0x008FD5DC 0x8035 # 0 +0x008FD5DD 0x8037 # 0 +0x008FD5DE 0x8039 # 0 +0x008FD5DF 0x803A # 0 +0x008FD5E0 0x803C # 0 +0x008FD5E1 0x803E # 0 +0x008FD5E2 0x8040 # 0 +0x008FD5E3 0x8044 # 0 +0x008FD5E4 0x8060 # 0 +0x008FD5E5 0x8064 # 0 +0x008FD5E6 0x8066 # 0 +0x008FD5E7 0x806D # 0 +0x008FD5E8 0x8071 # 0 +0x008FD5E9 0x8075 # 0 +0x008FD5EA 0x8081 # 0 +0x008FD5EB 0x8088 # 0 +0x008FD5EC 0x808E # 0 +0x008FD5ED 0x809C # 0 +0x008FD5EE 0x809E # 0 +0x008FD5EF 0x80A6 # 0 +0x008FD5F0 0x80A7 # 0 +0x008FD5F1 0x80AB # 0 +0x008FD5F2 0x80B8 # 0 +0x008FD5F3 0x80B9 # 0 +0x008FD5F4 0x80C8 # 0 +0x008FD5F5 0x80CD # 0 +0x008FD5F6 0x80CF # 0 +0x008FD5F7 0x80D2 # 0 +0x008FD5F8 0x80D4 # 0 +0x008FD5F9 0x80D5 # 0 +0x008FD5FA 0x80D7 # 0 +0x008FD5FB 0x80D8 # 0 +0x008FD5FC 0x80E0 # 0 +0x008FD5FD 0x80ED # 0 +0x008FD5FE 0x80EE # 0 +0x008FD6A1 0x80F0 # 0 +0x008FD6A2 0x80F2 # 0 +0x008FD6A3 0x80F3 # 0 +0x008FD6A4 0x80F6 # 0 +0x008FD6A5 0x80F9 # 0 +0x008FD6A6 0x80FA # 0 +0x008FD6A7 0x80FE # 0 +0x008FD6A8 0x8103 # 0 +0x008FD6A9 0x810B # 0 +0x008FD6AA 0x8116 # 0 +0x008FD6AB 0x8117 # 0 +0x008FD6AC 0x8118 # 0 +0x008FD6AD 0x811C # 0 +0x008FD6AE 0x811E # 0 +0x008FD6AF 0x8120 # 0 +0x008FD6B0 0x8124 # 0 +0x008FD6B1 0x8127 # 0 +0x008FD6B2 0x812C # 0 +0x008FD6B3 0x8130 # 0 +0x008FD6B4 0x8135 # 0 +0x008FD6B5 0x813A # 0 +0x008FD6B6 0x813C # 0 +0x008FD6B7 0x8145 # 0 +0x008FD6B8 0x8147 # 0 +0x008FD6B9 0x814A # 0 +0x008FD6BA 0x814C # 0 +0x008FD6BB 0x8152 # 0 +0x008FD6BC 0x8157 # 0 +0x008FD6BD 0x8160 # 0 +0x008FD6BE 0x8161 # 0 +0x008FD6BF 0x8167 # 0 +0x008FD6C0 0x8168 # 0 +0x008FD6C1 0x8169 # 0 +0x008FD6C2 0x816D # 0 +0x008FD6C3 0x816F # 0 +0x008FD6C4 0x8177 # 0 +0x008FD6C5 0x8181 # 0 +0x008FD6C6 0x8190 # 0 +0x008FD6C7 0x8184 # 0 +0x008FD6C8 0x8185 # 0 +0x008FD6C9 0x8186 # 0 +0x008FD6CA 0x818B # 0 +0x008FD6CB 0x818E # 0 +0x008FD6CC 0x8196 # 0 +0x008FD6CD 0x8198 # 0 +0x008FD6CE 0x819B # 0 +0x008FD6CF 0x819E # 0 +0x008FD6D0 0x81A2 # 0 +0x008FD6D1 0x81AE # 0 +0x008FD6D2 0x81B2 # 0 +0x008FD6D3 0x81B4 # 0 +0x008FD6D4 0x81BB # 0 +0x008FD6D5 0x81CB # 0 +0x008FD6D6 0x81C3 # 0 +0x008FD6D7 0x81C5 # 0 +0x008FD6D8 0x81CA # 0 +0x008FD6D9 0x81CE # 0 +0x008FD6DA 0x81CF # 0 +0x008FD6DB 0x81D5 # 0 +0x008FD6DC 0x81D7 # 0 +0x008FD6DD 0x81DB # 0 +0x008FD6DE 0x81DD # 0 +0x008FD6DF 0x81DE # 0 +0x008FD6E0 0x81E1 # 0 +0x008FD6E1 0x81E4 # 0 +0x008FD6E2 0x81EB # 0 +0x008FD6E3 0x81EC # 0 +0x008FD6E4 0x81F0 # 0 +0x008FD6E5 0x81F1 # 0 +0x008FD6E6 0x81F2 # 0 +0x008FD6E7 0x81F5 # 0 +0x008FD6E8 0x81F6 # 0 +0x008FD6E9 0x81F8 # 0 +0x008FD6EA 0x81F9 # 0 +0x008FD6EB 0x81FD # 0 +0x008FD6EC 0x81FF # 0 +0x008FD6ED 0x8200 # 0 +0x008FD6EE 0x8203 # 0 +0x008FD6EF 0x820F # 0 +0x008FD6F0 0x8213 # 0 +0x008FD6F1 0x8214 # 0 +0x008FD6F2 0x8219 # 0 +0x008FD6F3 0x821A # 0 +0x008FD6F4 0x821D # 0 +0x008FD6F5 0x8221 # 0 +0x008FD6F6 0x8222 # 0 +0x008FD6F7 0x8228 # 0 +0x008FD6F8 0x8232 # 0 +0x008FD6F9 0x8234 # 0 +0x008FD6FA 0x823A # 0 +0x008FD6FB 0x8243 # 0 +0x008FD6FC 0x8244 # 0 +0x008FD6FD 0x8245 # 0 +0x008FD6FE 0x8246 # 0 +0x008FD7A1 0x824B # 0 +0x008FD7A2 0x824E # 0 +0x008FD7A3 0x824F # 0 +0x008FD7A4 0x8251 # 0 +0x008FD7A5 0x8256 # 0 +0x008FD7A6 0x825C # 0 +0x008FD7A7 0x8260 # 0 +0x008FD7A8 0x8263 # 0 +0x008FD7A9 0x8267 # 0 +0x008FD7AA 0x826D # 0 +0x008FD7AB 0x8274 # 0 +0x008FD7AC 0x827B # 0 +0x008FD7AD 0x827D # 0 +0x008FD7AE 0x827F # 0 +0x008FD7AF 0x8280 # 0 +0x008FD7B0 0x8281 # 0 +0x008FD7B1 0x8283 # 0 +0x008FD7B2 0x8284 # 0 +0x008FD7B3 0x8287 # 0 +0x008FD7B4 0x8289 # 0 +0x008FD7B5 0x828A # 0 +0x008FD7B6 0x828E # 0 +0x008FD7B7 0x8291 # 0 +0x008FD7B8 0x8294 # 0 +0x008FD7B9 0x8296 # 0 +0x008FD7BA 0x8298 # 0 +0x008FD7BB 0x829A # 0 +0x008FD7BC 0x829B # 0 +0x008FD7BD 0x82A0 # 0 +0x008FD7BE 0x82A1 # 0 +0x008FD7BF 0x82A3 # 0 +0x008FD7C0 0x82A4 # 0 +0x008FD7C1 0x82A7 # 0 +0x008FD7C2 0x82A8 # 0 +0x008FD7C3 0x82A9 # 0 +0x008FD7C4 0x82AA # 0 +0x008FD7C5 0x82AE # 0 +0x008FD7C6 0x82B0 # 0 +0x008FD7C7 0x82B2 # 0 +0x008FD7C8 0x82B4 # 0 +0x008FD7C9 0x82B7 # 0 +0x008FD7CA 0x82BA # 0 +0x008FD7CB 0x82BC # 0 +0x008FD7CC 0x82BE # 0 +0x008FD7CD 0x82BF # 0 +0x008FD7CE 0x82C6 # 0 +0x008FD7CF 0x82D0 # 0 +0x008FD7D0 0x82D5 # 0 +0x008FD7D1 0x82DA # 0 +0x008FD7D2 0x82E0 # 0 +0x008FD7D3 0x82E2 # 0 +0x008FD7D4 0x82E4 # 0 +0x008FD7D5 0x82E8 # 0 +0x008FD7D6 0x82EA # 0 +0x008FD7D7 0x82ED # 0 +0x008FD7D8 0x82EF # 0 +0x008FD7D9 0x82F6 # 0 +0x008FD7DA 0x82F7 # 0 +0x008FD7DB 0x82FD # 0 +0x008FD7DC 0x82FE # 0 +0x008FD7DD 0x8300 # 0 +0x008FD7DE 0x8301 # 0 +0x008FD7DF 0x8307 # 0 +0x008FD7E0 0x8308 # 0 +0x008FD7E1 0x830A # 0 +0x008FD7E2 0x830B # 0 +0x008FD7E3 0x8354 # 0 +0x008FD7E4 0x831B # 0 +0x008FD7E5 0x831D # 0 +0x008FD7E6 0x831E # 0 +0x008FD7E7 0x831F # 0 +0x008FD7E8 0x8321 # 0 +0x008FD7E9 0x8322 # 0 +0x008FD7EA 0x832C # 0 +0x008FD7EB 0x832D # 0 +0x008FD7EC 0x832E # 0 +0x008FD7ED 0x8330 # 0 +0x008FD7EE 0x8333 # 0 +0x008FD7EF 0x8337 # 0 +0x008FD7F0 0x833A # 0 +0x008FD7F1 0x833C # 0 +0x008FD7F2 0x833D # 0 +0x008FD7F3 0x8342 # 0 +0x008FD7F4 0x8343 # 0 +0x008FD7F5 0x8344 # 0 +0x008FD7F6 0x8347 # 0 +0x008FD7F7 0x834D # 0 +0x008FD7F8 0x834E # 0 +0x008FD7F9 0x8351 # 0 +0x008FD7FA 0x8355 # 0 +0x008FD7FB 0x8356 # 0 +0x008FD7FC 0x8357 # 0 +0x008FD7FD 0x8370 # 0 +0x008FD7FE 0x8378 # 0 +0x008FD8A1 0x837D # 0 +0x008FD8A2 0x837F # 0 +0x008FD8A3 0x8380 # 0 +0x008FD8A4 0x8382 # 0 +0x008FD8A5 0x8384 # 0 +0x008FD8A6 0x8386 # 0 +0x008FD8A7 0x838D # 0 +0x008FD8A8 0x8392 # 0 +0x008FD8A9 0x8394 # 0 +0x008FD8AA 0x8395 # 0 +0x008FD8AB 0x8398 # 0 +0x008FD8AC 0x8399 # 0 +0x008FD8AD 0x839B # 0 +0x008FD8AE 0x839C # 0 +0x008FD8AF 0x839D # 0 +0x008FD8B0 0x83A6 # 0 +0x008FD8B1 0x83A7 # 0 +0x008FD8B2 0x83A9 # 0 +0x008FD8B3 0x83AC # 0 +0x008FD8B4 0x83BE # 0 +0x008FD8B5 0x83BF # 0 +0x008FD8B6 0x83C0 # 0 +0x008FD8B7 0x83C7 # 0 +0x008FD8B8 0x83C9 # 0 +0x008FD8B9 0x83CF # 0 +0x008FD8BA 0x83D0 # 0 +0x008FD8BB 0x83D1 # 0 +0x008FD8BC 0x83D4 # 0 +0x008FD8BD 0x83DD # 0 +0x008FD8BE 0x8353 # 0 +0x008FD8BF 0x83E8 # 0 +0x008FD8C0 0x83EA # 0 +0x008FD8C1 0x83F6 # 0 +0x008FD8C2 0x83F8 # 0 +0x008FD8C3 0x83F9 # 0 +0x008FD8C4 0x83FC # 0 +0x008FD8C5 0x8401 # 0 +0x008FD8C6 0x8406 # 0 +0x008FD8C7 0x840A # 0 +0x008FD8C8 0x840F # 0 +0x008FD8C9 0x8411 # 0 +0x008FD8CA 0x8415 # 0 +0x008FD8CB 0x8419 # 0 +0x008FD8CC 0x83AD # 0 +0x008FD8CD 0x842F # 0 +0x008FD8CE 0x8439 # 0 +0x008FD8CF 0x8445 # 0 +0x008FD8D0 0x8447 # 0 +0x008FD8D1 0x8448 # 0 +0x008FD8D2 0x844A # 0 +0x008FD8D3 0x844D # 0 +0x008FD8D4 0x844F # 0 +0x008FD8D5 0x8451 # 0 +0x008FD8D6 0x8452 # 0 +0x008FD8D7 0x8456 # 0 +0x008FD8D8 0x8458 # 0 +0x008FD8D9 0x8459 # 0 +0x008FD8DA 0x845A # 0 +0x008FD8DB 0x845C # 0 +0x008FD8DC 0x8460 # 0 +0x008FD8DD 0x8464 # 0 +0x008FD8DE 0x8465 # 0 +0x008FD8DF 0x8467 # 0 +0x008FD8E0 0x846A # 0 +0x008FD8E1 0x8470 # 0 +0x008FD8E2 0x8473 # 0 +0x008FD8E3 0x8474 # 0 +0x008FD8E4 0x8476 # 0 +0x008FD8E5 0x8478 # 0 +0x008FD8E6 0x847C # 0 +0x008FD8E7 0x847D # 0 +0x008FD8E8 0x8481 # 0 +0x008FD8E9 0x8485 # 0 +0x008FD8EA 0x8492 # 0 +0x008FD8EB 0x8493 # 0 +0x008FD8EC 0x8495 # 0 +0x008FD8ED 0x849E # 0 +0x008FD8EE 0x84A6 # 0 +0x008FD8EF 0x84A8 # 0 +0x008FD8F0 0x84A9 # 0 +0x008FD8F1 0x84AA # 0 +0x008FD8F2 0x84AF # 0 +0x008FD8F3 0x84B1 # 0 +0x008FD8F4 0x84B4 # 0 +0x008FD8F5 0x84BA # 0 +0x008FD8F6 0x84BD # 0 +0x008FD8F7 0x84BE # 0 +0x008FD8F8 0x84C0 # 0 +0x008FD8F9 0x84C2 # 0 +0x008FD8FA 0x84C7 # 0 +0x008FD8FB 0x84C8 # 0 +0x008FD8FC 0x84CC # 0 +0x008FD8FD 0x84CF # 0 +0x008FD8FE 0x84D3 # 0 +0x008FD9A1 0x84DC # 0 +0x008FD9A2 0x84E7 # 0 +0x008FD9A3 0x84EA # 0 +0x008FD9A4 0x84EF # 0 +0x008FD9A5 0x84F0 # 0 +0x008FD9A6 0x84F1 # 0 +0x008FD9A7 0x84F2 # 0 +0x008FD9A8 0x84F7 # 0 +0x008FD9A9 0x8532 # 0 +0x008FD9AA 0x84FA # 0 +0x008FD9AB 0x84FB # 0 +0x008FD9AC 0x84FD # 0 +0x008FD9AD 0x8502 # 0 +0x008FD9AE 0x8503 # 0 +0x008FD9AF 0x8507 # 0 +0x008FD9B0 0x850C # 0 +0x008FD9B1 0x850E # 0 +0x008FD9B2 0x8510 # 0 +0x008FD9B3 0x851C # 0 +0x008FD9B4 0x851E # 0 +0x008FD9B5 0x8522 # 0 +0x008FD9B6 0x8523 # 0 +0x008FD9B7 0x8524 # 0 +0x008FD9B8 0x8525 # 0 +0x008FD9B9 0x8527 # 0 +0x008FD9BA 0x852A # 0 +0x008FD9BB 0x852B # 0 +0x008FD9BC 0x852F # 0 +0x008FD9BD 0x8533 # 0 +0x008FD9BE 0x8534 # 0 +0x008FD9BF 0x8536 # 0 +0x008FD9C0 0x853F # 0 +0x008FD9C1 0x8546 # 0 +0x008FD9C2 0x854F # 0 +0x008FD9C3 0x8550 # 0 +0x008FD9C4 0x8551 # 0 +0x008FD9C5 0x8552 # 0 +0x008FD9C6 0x8553 # 0 +0x008FD9C7 0x8556 # 0 +0x008FD9C8 0x8559 # 0 +0x008FD9C9 0x855C # 0 +0x008FD9CA 0x855D # 0 +0x008FD9CB 0x855E # 0 +0x008FD9CC 0x855F # 0 +0x008FD9CD 0x8560 # 0 +0x008FD9CE 0x8561 # 0 +0x008FD9CF 0x8562 # 0 +0x008FD9D0 0x8564 # 0 +0x008FD9D1 0x856B # 0 +0x008FD9D2 0x856F # 0 +0x008FD9D3 0x8579 # 0 +0x008FD9D4 0x857A # 0 +0x008FD9D5 0x857B # 0 +0x008FD9D6 0x857D # 0 +0x008FD9D7 0x857F # 0 +0x008FD9D8 0x8581 # 0 +0x008FD9D9 0x8585 # 0 +0x008FD9DA 0x8586 # 0 +0x008FD9DB 0x8589 # 0 +0x008FD9DC 0x858B # 0 +0x008FD9DD 0x858C # 0 +0x008FD9DE 0x858F # 0 +0x008FD9DF 0x8593 # 0 +0x008FD9E0 0x8598 # 0 +0x008FD9E1 0x859D # 0 +0x008FD9E2 0x859F # 0 +0x008FD9E3 0x85A0 # 0 +0x008FD9E4 0x85A2 # 0 +0x008FD9E5 0x85A5 # 0 +0x008FD9E6 0x85A7 # 0 +0x008FD9E7 0x85B4 # 0 +0x008FD9E8 0x85B6 # 0 +0x008FD9E9 0x85B7 # 0 +0x008FD9EA 0x85B8 # 0 +0x008FD9EB 0x85BC # 0 +0x008FD9EC 0x85BD # 0 +0x008FD9ED 0x85BE # 0 +0x008FD9EE 0x85BF # 0 +0x008FD9EF 0x85C2 # 0 +0x008FD9F0 0x85C7 # 0 +0x008FD9F1 0x85CA # 0 +0x008FD9F2 0x85CB # 0 +0x008FD9F3 0x85CE # 0 +0x008FD9F4 0x85AD # 0 +0x008FD9F5 0x85D8 # 0 +0x008FD9F6 0x85DA # 0 +0x008FD9F7 0x85DF # 0 +0x008FD9F8 0x85E0 # 0 +0x008FD9F9 0x85E6 # 0 +0x008FD9FA 0x85E8 # 0 +0x008FD9FB 0x85ED # 0 +0x008FD9FC 0x85F3 # 0 +0x008FD9FD 0x85F6 # 0 +0x008FD9FE 0x85FC # 0 +0x008FDAA1 0x85FF # 0 +0x008FDAA2 0x8600 # 0 +0x008FDAA3 0x8604 # 0 +0x008FDAA4 0x8605 # 0 +0x008FDAA5 0x860D # 0 +0x008FDAA6 0x860E # 0 +0x008FDAA7 0x8610 # 0 +0x008FDAA8 0x8611 # 0 +0x008FDAA9 0x8612 # 0 +0x008FDAAA 0x8618 # 0 +0x008FDAAB 0x8619 # 0 +0x008FDAAC 0x861B # 0 +0x008FDAAD 0x861E # 0 +0x008FDAAE 0x8621 # 0 +0x008FDAAF 0x8627 # 0 +0x008FDAB0 0x8629 # 0 +0x008FDAB1 0x8636 # 0 +0x008FDAB2 0x8638 # 0 +0x008FDAB3 0x863A # 0 +0x008FDAB4 0x863C # 0 +0x008FDAB5 0x863D # 0 +0x008FDAB6 0x8640 # 0 +0x008FDAB7 0x8642 # 0 +0x008FDAB8 0x8646 # 0 +0x008FDAB9 0x8652 # 0 +0x008FDABA 0x8653 # 0 +0x008FDABB 0x8656 # 0 +0x008FDABC 0x8657 # 0 +0x008FDABD 0x8658 # 0 +0x008FDABE 0x8659 # 0 +0x008FDABF 0x865D # 0 +0x008FDAC0 0x8660 # 0 +0x008FDAC1 0x8661 # 0 +0x008FDAC2 0x8662 # 0 +0x008FDAC3 0x8663 # 0 +0x008FDAC4 0x8664 # 0 +0x008FDAC5 0x8669 # 0 +0x008FDAC6 0x866C # 0 +0x008FDAC7 0x866F # 0 +0x008FDAC8 0x8675 # 0 +0x008FDAC9 0x8676 # 0 +0x008FDACA 0x8677 # 0 +0x008FDACB 0x867A # 0 +0x008FDACC 0x868D # 0 +0x008FDACD 0x8691 # 0 +0x008FDACE 0x8696 # 0 +0x008FDACF 0x8698 # 0 +0x008FDAD0 0x869A # 0 +0x008FDAD1 0x869C # 0 +0x008FDAD2 0x86A1 # 0 +0x008FDAD3 0x86A6 # 0 +0x008FDAD4 0x86A7 # 0 +0x008FDAD5 0x86A8 # 0 +0x008FDAD6 0x86AD # 0 +0x008FDAD7 0x86B1 # 0 +0x008FDAD8 0x86B3 # 0 +0x008FDAD9 0x86B4 # 0 +0x008FDADA 0x86B5 # 0 +0x008FDADB 0x86B7 # 0 +0x008FDADC 0x86B8 # 0 +0x008FDADD 0x86B9 # 0 +0x008FDADE 0x86BF # 0 +0x008FDADF 0x86C0 # 0 +0x008FDAE0 0x86C1 # 0 +0x008FDAE1 0x86C3 # 0 +0x008FDAE2 0x86C5 # 0 +0x008FDAE3 0x86D1 # 0 +0x008FDAE4 0x86D2 # 0 +0x008FDAE5 0x86D5 # 0 +0x008FDAE6 0x86D7 # 0 +0x008FDAE7 0x86DA # 0 +0x008FDAE8 0x86DC # 0 +0x008FDAE9 0x86E0 # 0 +0x008FDAEA 0x86E3 # 0 +0x008FDAEB 0x86E5 # 0 +0x008FDAEC 0x86E7 # 0 +0x008FDAED 0x8688 # 0 +0x008FDAEE 0x86FA # 0 +0x008FDAEF 0x86FC # 0 +0x008FDAF0 0x86FD # 0 +0x008FDAF1 0x8704 # 0 +0x008FDAF2 0x8705 # 0 +0x008FDAF3 0x8707 # 0 +0x008FDAF4 0x870B # 0 +0x008FDAF5 0x870E # 0 +0x008FDAF6 0x870F # 0 +0x008FDAF7 0x8710 # 0 +0x008FDAF8 0x8713 # 0 +0x008FDAF9 0x8714 # 0 +0x008FDAFA 0x8719 # 0 +0x008FDAFB 0x871E # 0 +0x008FDAFC 0x871F # 0 +0x008FDAFD 0x8721 # 0 +0x008FDAFE 0x8723 # 0 +0x008FDBA1 0x8728 # 0 +0x008FDBA2 0x872E # 0 +0x008FDBA3 0x872F # 0 +0x008FDBA4 0x8731 # 0 +0x008FDBA5 0x8732 # 0 +0x008FDBA6 0x8739 # 0 +0x008FDBA7 0x873A # 0 +0x008FDBA8 0x873C # 0 +0x008FDBA9 0x873D # 0 +0x008FDBAA 0x873E # 0 +0x008FDBAB 0x8740 # 0 +0x008FDBAC 0x8743 # 0 +0x008FDBAD 0x8745 # 0 +0x008FDBAE 0x874D # 0 +0x008FDBAF 0x8758 # 0 +0x008FDBB0 0x875D # 0 +0x008FDBB1 0x8761 # 0 +0x008FDBB2 0x8764 # 0 +0x008FDBB3 0x8765 # 0 +0x008FDBB4 0x876F # 0 +0x008FDBB5 0x8771 # 0 +0x008FDBB6 0x8772 # 0 +0x008FDBB7 0x877B # 0 +0x008FDBB8 0x8783 # 0 +0x008FDBB9 0x8784 # 0 +0x008FDBBA 0x8785 # 0 +0x008FDBBB 0x8786 # 0 +0x008FDBBC 0x8787 # 0 +0x008FDBBD 0x8788 # 0 +0x008FDBBE 0x8789 # 0 +0x008FDBBF 0x878B # 0 +0x008FDBC0 0x878C # 0 +0x008FDBC1 0x8790 # 0 +0x008FDBC2 0x8793 # 0 +0x008FDBC3 0x8795 # 0 +0x008FDBC4 0x8797 # 0 +0x008FDBC5 0x8798 # 0 +0x008FDBC6 0x8799 # 0 +0x008FDBC7 0x879E # 0 +0x008FDBC8 0x87A0 # 0 +0x008FDBC9 0x87A3 # 0 +0x008FDBCA 0x87A7 # 0 +0x008FDBCB 0x87AC # 0 +0x008FDBCC 0x87AD # 0 +0x008FDBCD 0x87AE # 0 +0x008FDBCE 0x87B1 # 0 +0x008FDBCF 0x87B5 # 0 +0x008FDBD0 0x87BE # 0 +0x008FDBD1 0x87BF # 0 +0x008FDBD2 0x87C1 # 0 +0x008FDBD3 0x87C8 # 0 +0x008FDBD4 0x87C9 # 0 +0x008FDBD5 0x87CA # 0 +0x008FDBD6 0x87CE # 0 +0x008FDBD7 0x87D5 # 0 +0x008FDBD8 0x87D6 # 0 +0x008FDBD9 0x87D9 # 0 +0x008FDBDA 0x87DA # 0 +0x008FDBDB 0x87DC # 0 +0x008FDBDC 0x87DF # 0 +0x008FDBDD 0x87E2 # 0 +0x008FDBDE 0x87E3 # 0 +0x008FDBDF 0x87E4 # 0 +0x008FDBE0 0x87EA # 0 +0x008FDBE1 0x87EB # 0 +0x008FDBE2 0x87ED # 0 +0x008FDBE3 0x87F1 # 0 +0x008FDBE4 0x87F3 # 0 +0x008FDBE5 0x87F8 # 0 +0x008FDBE6 0x87FA # 0 +0x008FDBE7 0x87FF # 0 +0x008FDBE8 0x8801 # 0 +0x008FDBE9 0x8803 # 0 +0x008FDBEA 0x8806 # 0 +0x008FDBEB 0x8809 # 0 +0x008FDBEC 0x880A # 0 +0x008FDBED 0x880B # 0 +0x008FDBEE 0x8810 # 0 +0x008FDBEF 0x8819 # 0 +0x008FDBF0 0x8812 # 0 +0x008FDBF1 0x8813 # 0 +0x008FDBF2 0x8814 # 0 +0x008FDBF3 0x8818 # 0 +0x008FDBF4 0x881A # 0 +0x008FDBF5 0x881B # 0 +0x008FDBF6 0x881C # 0 +0x008FDBF7 0x881E # 0 +0x008FDBF8 0x881F # 0 +0x008FDBF9 0x8828 # 0 +0x008FDBFA 0x882D # 0 +0x008FDBFB 0x882E # 0 +0x008FDBFC 0x8830 # 0 +0x008FDBFD 0x8832 # 0 +0x008FDBFE 0x8835 # 0 +0x008FDCA1 0x883A # 0 +0x008FDCA2 0x883C # 0 +0x008FDCA3 0x8841 # 0 +0x008FDCA4 0x8843 # 0 +0x008FDCA5 0x8845 # 0 +0x008FDCA6 0x8848 # 0 +0x008FDCA7 0x8849 # 0 +0x008FDCA8 0x884A # 0 +0x008FDCA9 0x884B # 0 +0x008FDCAA 0x884E # 0 +0x008FDCAB 0x8851 # 0 +0x008FDCAC 0x8855 # 0 +0x008FDCAD 0x8856 # 0 +0x008FDCAE 0x8858 # 0 +0x008FDCAF 0x885A # 0 +0x008FDCB0 0x885C # 0 +0x008FDCB1 0x885F # 0 +0x008FDCB2 0x8860 # 0 +0x008FDCB3 0x8864 # 0 +0x008FDCB4 0x8869 # 0 +0x008FDCB5 0x8871 # 0 +0x008FDCB6 0x8879 # 0 +0x008FDCB7 0x887B # 0 +0x008FDCB8 0x8880 # 0 +0x008FDCB9 0x8898 # 0 +0x008FDCBA 0x889A # 0 +0x008FDCBB 0x889B # 0 +0x008FDCBC 0x889C # 0 +0x008FDCBD 0x889F # 0 +0x008FDCBE 0x88A0 # 0 +0x008FDCBF 0x88A8 # 0 +0x008FDCC0 0x88AA # 0 +0x008FDCC1 0x88BA # 0 +0x008FDCC2 0x88BD # 0 +0x008FDCC3 0x88BE # 0 +0x008FDCC4 0x88C0 # 0 +0x008FDCC5 0x88CA # 0 +0x008FDCC6 0x88CB # 0 +0x008FDCC7 0x88CC # 0 +0x008FDCC8 0x88CD # 0 +0x008FDCC9 0x88CE # 0 +0x008FDCCA 0x88D1 # 0 +0x008FDCCB 0x88D2 # 0 +0x008FDCCC 0x88D3 # 0 +0x008FDCCD 0x88DB # 0 +0x008FDCCE 0x88DE # 0 +0x008FDCCF 0x88E7 # 0 +0x008FDCD0 0x88EF # 0 +0x008FDCD1 0x88F0 # 0 +0x008FDCD2 0x88F1 # 0 +0x008FDCD3 0x88F5 # 0 +0x008FDCD4 0x88F7 # 0 +0x008FDCD5 0x8901 # 0 +0x008FDCD6 0x8906 # 0 +0x008FDCD7 0x890D # 0 +0x008FDCD8 0x890E # 0 +0x008FDCD9 0x890F # 0 +0x008FDCDA 0x8915 # 0 +0x008FDCDB 0x8916 # 0 +0x008FDCDC 0x8918 # 0 +0x008FDCDD 0x8919 # 0 +0x008FDCDE 0x891A # 0 +0x008FDCDF 0x891C # 0 +0x008FDCE0 0x8920 # 0 +0x008FDCE1 0x8926 # 0 +0x008FDCE2 0x8927 # 0 +0x008FDCE3 0x8928 # 0 +0x008FDCE4 0x8930 # 0 +0x008FDCE5 0x8931 # 0 +0x008FDCE6 0x8932 # 0 +0x008FDCE7 0x8935 # 0 +0x008FDCE8 0x8939 # 0 +0x008FDCE9 0x893A # 0 +0x008FDCEA 0x893E # 0 +0x008FDCEB 0x8940 # 0 +0x008FDCEC 0x8942 # 0 +0x008FDCED 0x8945 # 0 +0x008FDCEE 0x8946 # 0 +0x008FDCEF 0x8949 # 0 +0x008FDCF0 0x894F # 0 +0x008FDCF1 0x8952 # 0 +0x008FDCF2 0x8957 # 0 +0x008FDCF3 0x895A # 0 +0x008FDCF4 0x895B # 0 +0x008FDCF5 0x895C # 0 +0x008FDCF6 0x8961 # 0 +0x008FDCF7 0x8962 # 0 +0x008FDCF8 0x8963 # 0 +0x008FDCF9 0x896B # 0 +0x008FDCFA 0x896E # 0 +0x008FDCFB 0x8970 # 0 +0x008FDCFC 0x8973 # 0 +0x008FDCFD 0x8975 # 0 +0x008FDCFE 0x897A # 0 +0x008FDDA1 0x897B # 0 +0x008FDDA2 0x897C # 0 +0x008FDDA3 0x897D # 0 +0x008FDDA4 0x8989 # 0 +0x008FDDA5 0x898D # 0 +0x008FDDA6 0x8990 # 0 +0x008FDDA7 0x8994 # 0 +0x008FDDA8 0x8995 # 0 +0x008FDDA9 0x899B # 0 +0x008FDDAA 0x899C # 0 +0x008FDDAB 0x899F # 0 +0x008FDDAC 0x89A0 # 0 +0x008FDDAD 0x89A5 # 0 +0x008FDDAE 0x89B0 # 0 +0x008FDDAF 0x89B4 # 0 +0x008FDDB0 0x89B5 # 0 +0x008FDDB1 0x89B6 # 0 +0x008FDDB2 0x89B7 # 0 +0x008FDDB3 0x89BC # 0 +0x008FDDB4 0x89D4 # 0 +0x008FDDB5 0x89D5 # 0 +0x008FDDB6 0x89D6 # 0 +0x008FDDB7 0x89D7 # 0 +0x008FDDB8 0x89D8 # 0 +0x008FDDB9 0x89E5 # 0 +0x008FDDBA 0x89E9 # 0 +0x008FDDBB 0x89EB # 0 +0x008FDDBC 0x89ED # 0 +0x008FDDBD 0x89F1 # 0 +0x008FDDBE 0x89F3 # 0 +0x008FDDBF 0x89F6 # 0 +0x008FDDC0 0x89F9 # 0 +0x008FDDC1 0x89FD # 0 +0x008FDDC2 0x89FF # 0 +0x008FDDC3 0x8A04 # 0 +0x008FDDC4 0x8A05 # 0 +0x008FDDC5 0x8A07 # 0 +0x008FDDC6 0x8A0F # 0 +0x008FDDC7 0x8A11 # 0 +0x008FDDC8 0x8A12 # 0 +0x008FDDC9 0x8A14 # 0 +0x008FDDCA 0x8A15 # 0 +0x008FDDCB 0x8A1E # 0 +0x008FDDCC 0x8A20 # 0 +0x008FDDCD 0x8A22 # 0 +0x008FDDCE 0x8A24 # 0 +0x008FDDCF 0x8A26 # 0 +0x008FDDD0 0x8A2B # 0 +0x008FDDD1 0x8A2C # 0 +0x008FDDD2 0x8A2F # 0 +0x008FDDD3 0x8A35 # 0 +0x008FDDD4 0x8A37 # 0 +0x008FDDD5 0x8A3D # 0 +0x008FDDD6 0x8A3E # 0 +0x008FDDD7 0x8A40 # 0 +0x008FDDD8 0x8A43 # 0 +0x008FDDD9 0x8A45 # 0 +0x008FDDDA 0x8A47 # 0 +0x008FDDDB 0x8A49 # 0 +0x008FDDDC 0x8A4D # 0 +0x008FDDDD 0x8A4E # 0 +0x008FDDDE 0x8A53 # 0 +0x008FDDDF 0x8A56 # 0 +0x008FDDE0 0x8A57 # 0 +0x008FDDE1 0x8A58 # 0 +0x008FDDE2 0x8A5C # 0 +0x008FDDE3 0x8A5D # 0 +0x008FDDE4 0x8A61 # 0 +0x008FDDE5 0x8A65 # 0 +0x008FDDE6 0x8A67 # 0 +0x008FDDE7 0x8A75 # 0 +0x008FDDE8 0x8A76 # 0 +0x008FDDE9 0x8A77 # 0 +0x008FDDEA 0x8A79 # 0 +0x008FDDEB 0x8A7A # 0 +0x008FDDEC 0x8A7B # 0 +0x008FDDED 0x8A7E # 0 +0x008FDDEE 0x8A7F # 0 +0x008FDDEF 0x8A80 # 0 +0x008FDDF0 0x8A83 # 0 +0x008FDDF1 0x8A86 # 0 +0x008FDDF2 0x8A8B # 0 +0x008FDDF3 0x8A8F # 0 +0x008FDDF4 0x8A90 # 0 +0x008FDDF5 0x8A92 # 0 +0x008FDDF6 0x8A96 # 0 +0x008FDDF7 0x8A97 # 0 +0x008FDDF8 0x8A99 # 0 +0x008FDDF9 0x8A9F # 0 +0x008FDDFA 0x8AA7 # 0 +0x008FDDFB 0x8AA9 # 0 +0x008FDDFC 0x8AAE # 0 +0x008FDDFD 0x8AAF # 0 +0x008FDDFE 0x8AB3 # 0 +0x008FDEA1 0x8AB6 # 0 +0x008FDEA2 0x8AB7 # 0 +0x008FDEA3 0x8ABB # 0 +0x008FDEA4 0x8ABE # 0 +0x008FDEA5 0x8AC3 # 0 +0x008FDEA6 0x8AC6 # 0 +0x008FDEA7 0x8AC8 # 0 +0x008FDEA8 0x8AC9 # 0 +0x008FDEA9 0x8ACA # 0 +0x008FDEAA 0x8AD1 # 0 +0x008FDEAB 0x8AD3 # 0 +0x008FDEAC 0x8AD4 # 0 +0x008FDEAD 0x8AD5 # 0 +0x008FDEAE 0x8AD7 # 0 +0x008FDEAF 0x8ADD # 0 +0x008FDEB0 0x8ADF # 0 +0x008FDEB1 0x8AEC # 0 +0x008FDEB2 0x8AF0 # 0 +0x008FDEB3 0x8AF4 # 0 +0x008FDEB4 0x8AF5 # 0 +0x008FDEB5 0x8AF6 # 0 +0x008FDEB6 0x8AFC # 0 +0x008FDEB7 0x8AFF # 0 +0x008FDEB8 0x8B05 # 0 +0x008FDEB9 0x8B06 # 0 +0x008FDEBA 0x8B0B # 0 +0x008FDEBB 0x8B11 # 0 +0x008FDEBC 0x8B1C # 0 +0x008FDEBD 0x8B1E # 0 +0x008FDEBE 0x8B1F # 0 +0x008FDEBF 0x8B0A # 0 +0x008FDEC0 0x8B2D # 0 +0x008FDEC1 0x8B30 # 0 +0x008FDEC2 0x8B37 # 0 +0x008FDEC3 0x8B3C # 0 +0x008FDEC4 0x8B42 # 0 +0x008FDEC5 0x8B43 # 0 +0x008FDEC6 0x8B44 # 0 +0x008FDEC7 0x8B45 # 0 +0x008FDEC8 0x8B46 # 0 +0x008FDEC9 0x8B48 # 0 +0x008FDECA 0x8B52 # 0 +0x008FDECB 0x8B53 # 0 +0x008FDECC 0x8B54 # 0 +0x008FDECD 0x8B59 # 0 +0x008FDECE 0x8B4D # 0 +0x008FDECF 0x8B5E # 0 +0x008FDED0 0x8B63 # 0 +0x008FDED1 0x8B6D # 0 +0x008FDED2 0x8B76 # 0 +0x008FDED3 0x8B78 # 0 +0x008FDED4 0x8B79 # 0 +0x008FDED5 0x8B7C # 0 +0x008FDED6 0x8B7E # 0 +0x008FDED7 0x8B81 # 0 +0x008FDED8 0x8B84 # 0 +0x008FDED9 0x8B85 # 0 +0x008FDEDA 0x8B8B # 0 +0x008FDEDB 0x8B8D # 0 +0x008FDEDC 0x8B8F # 0 +0x008FDEDD 0x8B94 # 0 +0x008FDEDE 0x8B95 # 0 +0x008FDEDF 0x8B9C # 0 +0x008FDEE0 0x8B9E # 0 +0x008FDEE1 0x8B9F # 0 +0x008FDEE2 0x8C38 # 0 +0x008FDEE3 0x8C39 # 0 +0x008FDEE4 0x8C3D # 0 +0x008FDEE5 0x8C3E # 0 +0x008FDEE6 0x8C45 # 0 +0x008FDEE7 0x8C47 # 0 +0x008FDEE8 0x8C49 # 0 +0x008FDEE9 0x8C4B # 0 +0x008FDEEA 0x8C4F # 0 +0x008FDEEB 0x8C51 # 0 +0x008FDEEC 0x8C53 # 0 +0x008FDEED 0x8C54 # 0 +0x008FDEEE 0x8C57 # 0 +0x008FDEEF 0x8C58 # 0 +0x008FDEF0 0x8C5B # 0 +0x008FDEF1 0x8C5D # 0 +0x008FDEF2 0x8C59 # 0 +0x008FDEF3 0x8C63 # 0 +0x008FDEF4 0x8C64 # 0 +0x008FDEF5 0x8C66 # 0 +0x008FDEF6 0x8C68 # 0 +0x008FDEF7 0x8C69 # 0 +0x008FDEF8 0x8C6D # 0 +0x008FDEF9 0x8C73 # 0 +0x008FDEFA 0x8C75 # 0 +0x008FDEFB 0x8C76 # 0 +0x008FDEFC 0x8C7B # 0 +0x008FDEFD 0x8C7E # 0 +0x008FDEFE 0x8C86 # 0 +0x008FDFA1 0x8C87 # 0 +0x008FDFA2 0x8C8B # 0 +0x008FDFA3 0x8C90 # 0 +0x008FDFA4 0x8C92 # 0 +0x008FDFA5 0x8C93 # 0 +0x008FDFA6 0x8C99 # 0 +0x008FDFA7 0x8C9B # 0 +0x008FDFA8 0x8C9C # 0 +0x008FDFA9 0x8CA4 # 0 +0x008FDFAA 0x8CB9 # 0 +0x008FDFAB 0x8CBA # 0 +0x008FDFAC 0x8CC5 # 0 +0x008FDFAD 0x8CC6 # 0 +0x008FDFAE 0x8CC9 # 0 +0x008FDFAF 0x8CCB # 0 +0x008FDFB0 0x8CCF # 0 +0x008FDFB1 0x8CD6 # 0 +0x008FDFB2 0x8CD5 # 0 +0x008FDFB3 0x8CD9 # 0 +0x008FDFB4 0x8CDD # 0 +0x008FDFB5 0x8CE1 # 0 +0x008FDFB6 0x8CE8 # 0 +0x008FDFB7 0x8CEC # 0 +0x008FDFB8 0x8CEF # 0 +0x008FDFB9 0x8CF0 # 0 +0x008FDFBA 0x8CF2 # 0 +0x008FDFBB 0x8CF5 # 0 +0x008FDFBC 0x8CF7 # 0 +0x008FDFBD 0x8CF8 # 0 +0x008FDFBE 0x8CFE # 0 +0x008FDFBF 0x8CFF # 0 +0x008FDFC0 0x8D01 # 0 +0x008FDFC1 0x8D03 # 0 +0x008FDFC2 0x8D09 # 0 +0x008FDFC3 0x8D12 # 0 +0x008FDFC4 0x8D17 # 0 +0x008FDFC5 0x8D1B # 0 +0x008FDFC6 0x8D65 # 0 +0x008FDFC7 0x8D69 # 0 +0x008FDFC8 0x8D6C # 0 +0x008FDFC9 0x8D6E # 0 +0x008FDFCA 0x8D7F # 0 +0x008FDFCB 0x8D82 # 0 +0x008FDFCC 0x8D84 # 0 +0x008FDFCD 0x8D88 # 0 +0x008FDFCE 0x8D8D # 0 +0x008FDFCF 0x8D90 # 0 +0x008FDFD0 0x8D91 # 0 +0x008FDFD1 0x8D95 # 0 +0x008FDFD2 0x8D9E # 0 +0x008FDFD3 0x8D9F # 0 +0x008FDFD4 0x8DA0 # 0 +0x008FDFD5 0x8DA6 # 0 +0x008FDFD6 0x8DAB # 0 +0x008FDFD7 0x8DAC # 0 +0x008FDFD8 0x8DAF # 0 +0x008FDFD9 0x8DB2 # 0 +0x008FDFDA 0x8DB5 # 0 +0x008FDFDB 0x8DB7 # 0 +0x008FDFDC 0x8DB9 # 0 +0x008FDFDD 0x8DBB # 0 +0x008FDFDE 0x8DC0 # 0 +0x008FDFDF 0x8DC5 # 0 +0x008FDFE0 0x8DC6 # 0 +0x008FDFE1 0x8DC7 # 0 +0x008FDFE2 0x8DC8 # 0 +0x008FDFE3 0x8DCA # 0 +0x008FDFE4 0x8DCE # 0 +0x008FDFE5 0x8DD1 # 0 +0x008FDFE6 0x8DD4 # 0 +0x008FDFE7 0x8DD5 # 0 +0x008FDFE8 0x8DD7 # 0 +0x008FDFE9 0x8DD9 # 0 +0x008FDFEA 0x8DE4 # 0 +0x008FDFEB 0x8DE5 # 0 +0x008FDFEC 0x8DE7 # 0 +0x008FDFED 0x8DEC # 0 +0x008FDFEE 0x8DF0 # 0 +0x008FDFEF 0x8DBC # 0 +0x008FDFF0 0x8DF1 # 0 +0x008FDFF1 0x8DF2 # 0 +0x008FDFF2 0x8DF4 # 0 +0x008FDFF3 0x8DFD # 0 +0x008FDFF4 0x8E01 # 0 +0x008FDFF5 0x8E04 # 0 +0x008FDFF6 0x8E05 # 0 +0x008FDFF7 0x8E06 # 0 +0x008FDFF8 0x8E0B # 0 +0x008FDFF9 0x8E11 # 0 +0x008FDFFA 0x8E14 # 0 +0x008FDFFB 0x8E16 # 0 +0x008FDFFC 0x8E20 # 0 +0x008FDFFD 0x8E21 # 0 +0x008FDFFE 0x8E22 # 0 +0x008FE0A1 0x8E23 # 0 +0x008FE0A2 0x8E26 # 0 +0x008FE0A3 0x8E27 # 0 +0x008FE0A4 0x8E31 # 0 +0x008FE0A5 0x8E33 # 0 +0x008FE0A6 0x8E36 # 0 +0x008FE0A7 0x8E37 # 0 +0x008FE0A8 0x8E38 # 0 +0x008FE0A9 0x8E39 # 0 +0x008FE0AA 0x8E3D # 0 +0x008FE0AB 0x8E40 # 0 +0x008FE0AC 0x8E41 # 0 +0x008FE0AD 0x8E4B # 0 +0x008FE0AE 0x8E4D # 0 +0x008FE0AF 0x8E4E # 0 +0x008FE0B0 0x8E4F # 0 +0x008FE0B1 0x8E54 # 0 +0x008FE0B2 0x8E5B # 0 +0x008FE0B3 0x8E5C # 0 +0x008FE0B4 0x8E5D # 0 +0x008FE0B5 0x8E5E # 0 +0x008FE0B6 0x8E61 # 0 +0x008FE0B7 0x8E62 # 0 +0x008FE0B8 0x8E69 # 0 +0x008FE0B9 0x8E6C # 0 +0x008FE0BA 0x8E6D # 0 +0x008FE0BB 0x8E6F # 0 +0x008FE0BC 0x8E70 # 0 +0x008FE0BD 0x8E71 # 0 +0x008FE0BE 0x8E79 # 0 +0x008FE0BF 0x8E7A # 0 +0x008FE0C0 0x8E7B # 0 +0x008FE0C1 0x8E82 # 0 +0x008FE0C2 0x8E83 # 0 +0x008FE0C3 0x8E89 # 0 +0x008FE0C4 0x8E90 # 0 +0x008FE0C5 0x8E92 # 0 +0x008FE0C6 0x8E95 # 0 +0x008FE0C7 0x8E9A # 0 +0x008FE0C8 0x8E9B # 0 +0x008FE0C9 0x8E9D # 0 +0x008FE0CA 0x8E9E # 0 +0x008FE0CB 0x8EA2 # 0 +0x008FE0CC 0x8EA7 # 0 +0x008FE0CD 0x8EA9 # 0 +0x008FE0CE 0x8EAD # 0 +0x008FE0CF 0x8EAE # 0 +0x008FE0D0 0x8EB3 # 0 +0x008FE0D1 0x8EB5 # 0 +0x008FE0D2 0x8EBA # 0 +0x008FE0D3 0x8EBB # 0 +0x008FE0D4 0x8EC0 # 0 +0x008FE0D5 0x8EC1 # 0 +0x008FE0D6 0x8EC3 # 0 +0x008FE0D7 0x8EC4 # 0 +0x008FE0D8 0x8EC7 # 0 +0x008FE0D9 0x8ECF # 0 +0x008FE0DA 0x8ED1 # 0 +0x008FE0DB 0x8ED4 # 0 +0x008FE0DC 0x8EDC # 0 +0x008FE0DD 0x8EE8 # 0 +0x008FE0DE 0x8EEE # 0 +0x008FE0DF 0x8EF0 # 0 +0x008FE0E0 0x8EF1 # 0 +0x008FE0E1 0x8EF7 # 0 +0x008FE0E2 0x8EF9 # 0 +0x008FE0E3 0x8EFA # 0 +0x008FE0E4 0x8EED # 0 +0x008FE0E5 0x8F00 # 0 +0x008FE0E6 0x8F02 # 0 +0x008FE0E7 0x8F07 # 0 +0x008FE0E8 0x8F08 # 0 +0x008FE0E9 0x8F0F # 0 +0x008FE0EA 0x8F10 # 0 +0x008FE0EB 0x8F16 # 0 +0x008FE0EC 0x8F17 # 0 +0x008FE0ED 0x8F18 # 0 +0x008FE0EE 0x8F1E # 0 +0x008FE0EF 0x8F20 # 0 +0x008FE0F0 0x8F21 # 0 +0x008FE0F1 0x8F23 # 0 +0x008FE0F2 0x8F25 # 0 +0x008FE0F3 0x8F27 # 0 +0x008FE0F4 0x8F28 # 0 +0x008FE0F5 0x8F2C # 0 +0x008FE0F6 0x8F2D # 0 +0x008FE0F7 0x8F2E # 0 +0x008FE0F8 0x8F34 # 0 +0x008FE0F9 0x8F35 # 0 +0x008FE0FA 0x8F36 # 0 +0x008FE0FB 0x8F37 # 0 +0x008FE0FC 0x8F3A # 0 +0x008FE0FD 0x8F40 # 0 +0x008FE0FE 0x8F41 # 0 +0x008FE1A1 0x8F43 # 0 +0x008FE1A2 0x8F47 # 0 +0x008FE1A3 0x8F4F # 0 +0x008FE1A4 0x8F51 # 0 +0x008FE1A5 0x8F52 # 0 +0x008FE1A6 0x8F53 # 0 +0x008FE1A7 0x8F54 # 0 +0x008FE1A8 0x8F55 # 0 +0x008FE1A9 0x8F58 # 0 +0x008FE1AA 0x8F5D # 0 +0x008FE1AB 0x8F5E # 0 +0x008FE1AC 0x8F65 # 0 +0x008FE1AD 0x8F9D # 0 +0x008FE1AE 0x8FA0 # 0 +0x008FE1AF 0x8FA1 # 0 +0x008FE1B0 0x8FA4 # 0 +0x008FE1B1 0x8FA5 # 0 +0x008FE1B2 0x8FA6 # 0 +0x008FE1B3 0x8FB5 # 0 +0x008FE1B4 0x8FB6 # 0 +0x008FE1B5 0x8FB8 # 0 +0x008FE1B6 0x8FBE # 0 +0x008FE1B7 0x8FC0 # 0 +0x008FE1B8 0x8FC1 # 0 +0x008FE1B9 0x8FC6 # 0 +0x008FE1BA 0x8FCA # 0 +0x008FE1BB 0x8FCB # 0 +0x008FE1BC 0x8FCD # 0 +0x008FE1BD 0x8FD0 # 0 +0x008FE1BE 0x8FD2 # 0 +0x008FE1BF 0x8FD3 # 0 +0x008FE1C0 0x8FD5 # 0 +0x008FE1C1 0x8FE0 # 0 +0x008FE1C2 0x8FE3 # 0 +0x008FE1C3 0x8FE4 # 0 +0x008FE1C4 0x8FE8 # 0 +0x008FE1C5 0x8FEE # 0 +0x008FE1C6 0x8FF1 # 0 +0x008FE1C7 0x8FF5 # 0 +0x008FE1C8 0x8FF6 # 0 +0x008FE1C9 0x8FFB # 0 +0x008FE1CA 0x8FFE # 0 +0x008FE1CB 0x9002 # 0 +0x008FE1CC 0x9004 # 0 +0x008FE1CD 0x9008 # 0 +0x008FE1CE 0x900C # 0 +0x008FE1CF 0x9018 # 0 +0x008FE1D0 0x901B # 0 +0x008FE1D1 0x9028 # 0 +0x008FE1D2 0x9029 # 0 +0x008FE1D3 0x902F # 0 +0x008FE1D4 0x902A # 0 +0x008FE1D5 0x902C # 0 +0x008FE1D6 0x902D # 0 +0x008FE1D7 0x9033 # 0 +0x008FE1D8 0x9034 # 0 +0x008FE1D9 0x9037 # 0 +0x008FE1DA 0x903F # 0 +0x008FE1DB 0x9043 # 0 +0x008FE1DC 0x9044 # 0 +0x008FE1DD 0x904C # 0 +0x008FE1DE 0x905B # 0 +0x008FE1DF 0x905D # 0 +0x008FE1E0 0x9062 # 0 +0x008FE1E1 0x9066 # 0 +0x008FE1E2 0x9067 # 0 +0x008FE1E3 0x906C # 0 +0x008FE1E4 0x9070 # 0 +0x008FE1E5 0x9074 # 0 +0x008FE1E6 0x9079 # 0 +0x008FE1E7 0x9085 # 0 +0x008FE1E8 0x9088 # 0 +0x008FE1E9 0x908B # 0 +0x008FE1EA 0x908C # 0 +0x008FE1EB 0x908E # 0 +0x008FE1EC 0x9090 # 0 +0x008FE1ED 0x9095 # 0 +0x008FE1EE 0x9097 # 0 +0x008FE1EF 0x9098 # 0 +0x008FE1F0 0x9099 # 0 +0x008FE1F1 0x909B # 0 +0x008FE1F2 0x90A0 # 0 +0x008FE1F3 0x90A1 # 0 +0x008FE1F4 0x90A2 # 0 +0x008FE1F5 0x90A5 # 0 +0x008FE1F6 0x90B0 # 0 +0x008FE1F7 0x90B2 # 0 +0x008FE1F8 0x90B3 # 0 +0x008FE1F9 0x90B4 # 0 +0x008FE1FA 0x90B6 # 0 +0x008FE1FB 0x90BD # 0 +0x008FE1FC 0x90CC # 0 +0x008FE1FD 0x90BE # 0 +0x008FE1FE 0x90C3 # 0 +0x008FE2A1 0x90C4 # 0 +0x008FE2A2 0x90C5 # 0 +0x008FE2A3 0x90C7 # 0 +0x008FE2A4 0x90C8 # 0 +0x008FE2A5 0x90D5 # 0 +0x008FE2A6 0x90D7 # 0 +0x008FE2A7 0x90D8 # 0 +0x008FE2A8 0x90D9 # 0 +0x008FE2A9 0x90DC # 0 +0x008FE2AA 0x90DD # 0 +0x008FE2AB 0x90DF # 0 +0x008FE2AC 0x90E5 # 0 +0x008FE2AD 0x90D2 # 0 +0x008FE2AE 0x90F6 # 0 +0x008FE2AF 0x90EB # 0 +0x008FE2B0 0x90EF # 0 +0x008FE2B1 0x90F0 # 0 +0x008FE2B2 0x90F4 # 0 +0x008FE2B3 0x90FE # 0 +0x008FE2B4 0x90FF # 0 +0x008FE2B5 0x9100 # 0 +0x008FE2B6 0x9104 # 0 +0x008FE2B7 0x9105 # 0 +0x008FE2B8 0x9106 # 0 +0x008FE2B9 0x9108 # 0 +0x008FE2BA 0x910D # 0 +0x008FE2BB 0x9110 # 0 +0x008FE2BC 0x9114 # 0 +0x008FE2BD 0x9116 # 0 +0x008FE2BE 0x9117 # 0 +0x008FE2BF 0x9118 # 0 +0x008FE2C0 0x911A # 0 +0x008FE2C1 0x911C # 0 +0x008FE2C2 0x911E # 0 +0x008FE2C3 0x9120 # 0 +0x008FE2C4 0x9125 # 0 +0x008FE2C5 0x9122 # 0 +0x008FE2C6 0x9123 # 0 +0x008FE2C7 0x9127 # 0 +0x008FE2C8 0x9129 # 0 +0x008FE2C9 0x912E # 0 +0x008FE2CA 0x912F # 0 +0x008FE2CB 0x9131 # 0 +0x008FE2CC 0x9134 # 0 +0x008FE2CD 0x9136 # 0 +0x008FE2CE 0x9137 # 0 +0x008FE2CF 0x9139 # 0 +0x008FE2D0 0x913A # 0 +0x008FE2D1 0x913C # 0 +0x008FE2D2 0x913D # 0 +0x008FE2D3 0x9143 # 0 +0x008FE2D4 0x9147 # 0 +0x008FE2D5 0x9148 # 0 +0x008FE2D6 0x914F # 0 +0x008FE2D7 0x9153 # 0 +0x008FE2D8 0x9157 # 0 +0x008FE2D9 0x9159 # 0 +0x008FE2DA 0x915A # 0 +0x008FE2DB 0x915B # 0 +0x008FE2DC 0x9161 # 0 +0x008FE2DD 0x9164 # 0 +0x008FE2DE 0x9167 # 0 +0x008FE2DF 0x916D # 0 +0x008FE2E0 0x9174 # 0 +0x008FE2E1 0x9179 # 0 +0x008FE2E2 0x917A # 0 +0x008FE2E3 0x917B # 0 +0x008FE2E4 0x9181 # 0 +0x008FE2E5 0x9183 # 0 +0x008FE2E6 0x9185 # 0 +0x008FE2E7 0x9186 # 0 +0x008FE2E8 0x918A # 0 +0x008FE2E9 0x918E # 0 +0x008FE2EA 0x9191 # 0 +0x008FE2EB 0x9193 # 0 +0x008FE2EC 0x9194 # 0 +0x008FE2ED 0x9195 # 0 +0x008FE2EE 0x9198 # 0 +0x008FE2EF 0x919E # 0 +0x008FE2F0 0x91A1 # 0 +0x008FE2F1 0x91A6 # 0 +0x008FE2F2 0x91A8 # 0 +0x008FE2F3 0x91AC # 0 +0x008FE2F4 0x91AD # 0 +0x008FE2F5 0x91AE # 0 +0x008FE2F6 0x91B0 # 0 +0x008FE2F7 0x91B1 # 0 +0x008FE2F8 0x91B2 # 0 +0x008FE2F9 0x91B3 # 0 +0x008FE2FA 0x91B6 # 0 +0x008FE2FB 0x91BB # 0 +0x008FE2FC 0x91BC # 0 +0x008FE2FD 0x91BD # 0 +0x008FE2FE 0x91BF # 0 +0x008FE3A1 0x91C2 # 0 +0x008FE3A2 0x91C3 # 0 +0x008FE3A3 0x91C5 # 0 +0x008FE3A4 0x91D3 # 0 +0x008FE3A5 0x91D4 # 0 +0x008FE3A6 0x91D7 # 0 +0x008FE3A7 0x91D9 # 0 +0x008FE3A8 0x91DA # 0 +0x008FE3A9 0x91DE # 0 +0x008FE3AA 0x91E4 # 0 +0x008FE3AB 0x91E5 # 0 +0x008FE3AC 0x91E9 # 0 +0x008FE3AD 0x91EA # 0 +0x008FE3AE 0x91EC # 0 +0x008FE3AF 0x91ED # 0 +0x008FE3B0 0x91EE # 0 +0x008FE3B1 0x91EF # 0 +0x008FE3B2 0x91F0 # 0 +0x008FE3B3 0x91F1 # 0 +0x008FE3B4 0x91F7 # 0 +0x008FE3B5 0x91F9 # 0 +0x008FE3B6 0x91FB # 0 +0x008FE3B7 0x91FD # 0 +0x008FE3B8 0x9200 # 0 +0x008FE3B9 0x9201 # 0 +0x008FE3BA 0x9204 # 0 +0x008FE3BB 0x9205 # 0 +0x008FE3BC 0x9206 # 0 +0x008FE3BD 0x9207 # 0 +0x008FE3BE 0x9209 # 0 +0x008FE3BF 0x920A # 0 +0x008FE3C0 0x920C # 0 +0x008FE3C1 0x9210 # 0 +0x008FE3C2 0x9212 # 0 +0x008FE3C3 0x9213 # 0 +0x008FE3C4 0x9216 # 0 +0x008FE3C5 0x9218 # 0 +0x008FE3C6 0x921C # 0 +0x008FE3C7 0x921D # 0 +0x008FE3C8 0x9223 # 0 +0x008FE3C9 0x9224 # 0 +0x008FE3CA 0x9225 # 0 +0x008FE3CB 0x9226 # 0 +0x008FE3CC 0x9228 # 0 +0x008FE3CD 0x922E # 0 +0x008FE3CE 0x922F # 0 +0x008FE3CF 0x9230 # 0 +0x008FE3D0 0x9233 # 0 +0x008FE3D1 0x9235 # 0 +0x008FE3D2 0x9236 # 0 +0x008FE3D3 0x9238 # 0 +0x008FE3D4 0x9239 # 0 +0x008FE3D5 0x923A # 0 +0x008FE3D6 0x923C # 0 +0x008FE3D7 0x923E # 0 +0x008FE3D8 0x9240 # 0 +0x008FE3D9 0x9242 # 0 +0x008FE3DA 0x9243 # 0 +0x008FE3DB 0x9246 # 0 +0x008FE3DC 0x9247 # 0 +0x008FE3DD 0x924A # 0 +0x008FE3DE 0x924D # 0 +0x008FE3DF 0x924E # 0 +0x008FE3E0 0x924F # 0 +0x008FE3E1 0x9251 # 0 +0x008FE3E2 0x9258 # 0 +0x008FE3E3 0x9259 # 0 +0x008FE3E4 0x925C # 0 +0x008FE3E5 0x925D # 0 +0x008FE3E6 0x9260 # 0 +0x008FE3E7 0x9261 # 0 +0x008FE3E8 0x9265 # 0 +0x008FE3E9 0x9267 # 0 +0x008FE3EA 0x9268 # 0 +0x008FE3EB 0x9269 # 0 +0x008FE3EC 0x926E # 0 +0x008FE3ED 0x926F # 0 +0x008FE3EE 0x9270 # 0 +0x008FE3EF 0x9275 # 0 +0x008FE3F0 0x9276 # 0 +0x008FE3F1 0x9277 # 0 +0x008FE3F2 0x9278 # 0 +0x008FE3F3 0x9279 # 0 +0x008FE3F4 0x927B # 0 +0x008FE3F5 0x927C # 0 +0x008FE3F6 0x927D # 0 +0x008FE3F7 0x927F # 0 +0x008FE3F8 0x9288 # 0 +0x008FE3F9 0x9289 # 0 +0x008FE3FA 0x928A # 0 +0x008FE3FB 0x928D # 0 +0x008FE3FC 0x928E # 0 +0x008FE3FD 0x9292 # 0 +0x008FE3FE 0x9297 # 0 +0x008FE4A1 0x9299 # 0 +0x008FE4A2 0x929F # 0 +0x008FE4A3 0x92A0 # 0 +0x008FE4A4 0x92A4 # 0 +0x008FE4A5 0x92A5 # 0 +0x008FE4A6 0x92A7 # 0 +0x008FE4A7 0x92A8 # 0 +0x008FE4A8 0x92AB # 0 +0x008FE4A9 0x92AF # 0 +0x008FE4AA 0x92B2 # 0 +0x008FE4AB 0x92B6 # 0 +0x008FE4AC 0x92B8 # 0 +0x008FE4AD 0x92BA # 0 +0x008FE4AE 0x92BB # 0 +0x008FE4AF 0x92BC # 0 +0x008FE4B0 0x92BD # 0 +0x008FE4B1 0x92BF # 0 +0x008FE4B2 0x92C0 # 0 +0x008FE4B3 0x92C1 # 0 +0x008FE4B4 0x92C2 # 0 +0x008FE4B5 0x92C3 # 0 +0x008FE4B6 0x92C5 # 0 +0x008FE4B7 0x92C6 # 0 +0x008FE4B8 0x92C7 # 0 +0x008FE4B9 0x92C8 # 0 +0x008FE4BA 0x92CB # 0 +0x008FE4BB 0x92CC # 0 +0x008FE4BC 0x92CD # 0 +0x008FE4BD 0x92CE # 0 +0x008FE4BE 0x92D0 # 0 +0x008FE4BF 0x92D3 # 0 +0x008FE4C0 0x92D5 # 0 +0x008FE4C1 0x92D7 # 0 +0x008FE4C2 0x92D8 # 0 +0x008FE4C3 0x92D9 # 0 +0x008FE4C4 0x92DC # 0 +0x008FE4C5 0x92DD # 0 +0x008FE4C6 0x92DF # 0 +0x008FE4C7 0x92E0 # 0 +0x008FE4C8 0x92E1 # 0 +0x008FE4C9 0x92E3 # 0 +0x008FE4CA 0x92E5 # 0 +0x008FE4CB 0x92E7 # 0 +0x008FE4CC 0x92E8 # 0 +0x008FE4CD 0x92EC # 0 +0x008FE4CE 0x92EE # 0 +0x008FE4CF 0x92F0 # 0 +0x008FE4D0 0x92F9 # 0 +0x008FE4D1 0x92FB # 0 +0x008FE4D2 0x92FF # 0 +0x008FE4D3 0x9300 # 0 +0x008FE4D4 0x9302 # 0 +0x008FE4D5 0x9308 # 0 +0x008FE4D6 0x930D # 0 +0x008FE4D7 0x9311 # 0 +0x008FE4D8 0x9314 # 0 +0x008FE4D9 0x9315 # 0 +0x008FE4DA 0x931C # 0 +0x008FE4DB 0x931D # 0 +0x008FE4DC 0x931E # 0 +0x008FE4DD 0x931F # 0 +0x008FE4DE 0x9321 # 0 +0x008FE4DF 0x9324 # 0 +0x008FE4E0 0x9325 # 0 +0x008FE4E1 0x9327 # 0 +0x008FE4E2 0x9329 # 0 +0x008FE4E3 0x932A # 0 +0x008FE4E4 0x9333 # 0 +0x008FE4E5 0x9334 # 0 +0x008FE4E6 0x9336 # 0 +0x008FE4E7 0x9337 # 0 +0x008FE4E8 0x9347 # 0 +0x008FE4E9 0x9348 # 0 +0x008FE4EA 0x9349 # 0 +0x008FE4EB 0x9350 # 0 +0x008FE4EC 0x9351 # 0 +0x008FE4ED 0x9352 # 0 +0x008FE4EE 0x9355 # 0 +0x008FE4EF 0x9357 # 0 +0x008FE4F0 0x9358 # 0 +0x008FE4F1 0x935A # 0 +0x008FE4F2 0x935E # 0 +0x008FE4F3 0x9364 # 0 +0x008FE4F4 0x9365 # 0 +0x008FE4F5 0x9367 # 0 +0x008FE4F6 0x9369 # 0 +0x008FE4F7 0x936A # 0 +0x008FE4F8 0x936D # 0 +0x008FE4F9 0x936F # 0 +0x008FE4FA 0x9370 # 0 +0x008FE4FB 0x9371 # 0 +0x008FE4FC 0x9373 # 0 +0x008FE4FD 0x9374 # 0 +0x008FE4FE 0x9376 # 0 +0x008FE5A1 0x937A # 0 +0x008FE5A2 0x937D # 0 +0x008FE5A3 0x937F # 0 +0x008FE5A4 0x9380 # 0 +0x008FE5A5 0x9381 # 0 +0x008FE5A6 0x9382 # 0 +0x008FE5A7 0x9388 # 0 +0x008FE5A8 0x938A # 0 +0x008FE5A9 0x938B # 0 +0x008FE5AA 0x938D # 0 +0x008FE5AB 0x938F # 0 +0x008FE5AC 0x9392 # 0 +0x008FE5AD 0x9395 # 0 +0x008FE5AE 0x9398 # 0 +0x008FE5AF 0x939B # 0 +0x008FE5B0 0x939E # 0 +0x008FE5B1 0x93A1 # 0 +0x008FE5B2 0x93A3 # 0 +0x008FE5B3 0x93A4 # 0 +0x008FE5B4 0x93A6 # 0 +0x008FE5B5 0x93A8 # 0 +0x008FE5B6 0x93AB # 0 +0x008FE5B7 0x93B4 # 0 +0x008FE5B8 0x93B5 # 0 +0x008FE5B9 0x93B6 # 0 +0x008FE5BA 0x93BA # 0 +0x008FE5BB 0x93A9 # 0 +0x008FE5BC 0x93C1 # 0 +0x008FE5BD 0x93C4 # 0 +0x008FE5BE 0x93C5 # 0 +0x008FE5BF 0x93C6 # 0 +0x008FE5C0 0x93C7 # 0 +0x008FE5C1 0x93C9 # 0 +0x008FE5C2 0x93CA # 0 +0x008FE5C3 0x93CB # 0 +0x008FE5C4 0x93CC # 0 +0x008FE5C5 0x93CD # 0 +0x008FE5C6 0x93D3 # 0 +0x008FE5C7 0x93D9 # 0 +0x008FE5C8 0x93DC # 0 +0x008FE5C9 0x93DE # 0 +0x008FE5CA 0x93DF # 0 +0x008FE5CB 0x93E2 # 0 +0x008FE5CC 0x93E6 # 0 +0x008FE5CD 0x93E7 # 0 +0x008FE5CE 0x93F9 # 0 +0x008FE5CF 0x93F7 # 0 +0x008FE5D0 0x93F8 # 0 +0x008FE5D1 0x93FA # 0 +0x008FE5D2 0x93FB # 0 +0x008FE5D3 0x93FD # 0 +0x008FE5D4 0x9401 # 0 +0x008FE5D5 0x9402 # 0 +0x008FE5D6 0x9404 # 0 +0x008FE5D7 0x9408 # 0 +0x008FE5D8 0x9409 # 0 +0x008FE5D9 0x940D # 0 +0x008FE5DA 0x940E # 0 +0x008FE5DB 0x940F # 0 +0x008FE5DC 0x9415 # 0 +0x008FE5DD 0x9416 # 0 +0x008FE5DE 0x9417 # 0 +0x008FE5DF 0x941F # 0 +0x008FE5E0 0x942E # 0 +0x008FE5E1 0x942F # 0 +0x008FE5E2 0x9431 # 0 +0x008FE5E3 0x9432 # 0 +0x008FE5E4 0x9433 # 0 +0x008FE5E5 0x9434 # 0 +0x008FE5E6 0x943B # 0 +0x008FE5E7 0x943F # 0 +0x008FE5E8 0x943D # 0 +0x008FE5E9 0x9443 # 0 +0x008FE5EA 0x9445 # 0 +0x008FE5EB 0x9448 # 0 +0x008FE5EC 0x944A # 0 +0x008FE5ED 0x944C # 0 +0x008FE5EE 0x9455 # 0 +0x008FE5EF 0x9459 # 0 +0x008FE5F0 0x945C # 0 +0x008FE5F1 0x945F # 0 +0x008FE5F2 0x9461 # 0 +0x008FE5F3 0x9463 # 0 +0x008FE5F4 0x9468 # 0 +0x008FE5F5 0x946B # 0 +0x008FE5F6 0x946D # 0 +0x008FE5F7 0x946E # 0 +0x008FE5F8 0x946F # 0 +0x008FE5F9 0x9471 # 0 +0x008FE5FA 0x9472 # 0 +0x008FE5FB 0x9484 # 0 +0x008FE5FC 0x9483 # 0 +0x008FE5FD 0x9578 # 0 +0x008FE5FE 0x9579 # 0 +0x008FE6A1 0x957E # 0 +0x008FE6A2 0x9584 # 0 +0x008FE6A3 0x9588 # 0 +0x008FE6A4 0x958C # 0 +0x008FE6A5 0x958D # 0 +0x008FE6A6 0x958E # 0 +0x008FE6A7 0x959D # 0 +0x008FE6A8 0x959E # 0 +0x008FE6A9 0x959F # 0 +0x008FE6AA 0x95A1 # 0 +0x008FE6AB 0x95A6 # 0 +0x008FE6AC 0x95A9 # 0 +0x008FE6AD 0x95AB # 0 +0x008FE6AE 0x95AC # 0 +0x008FE6AF 0x95B4 # 0 +0x008FE6B0 0x95B6 # 0 +0x008FE6B1 0x95BA # 0 +0x008FE6B2 0x95BD # 0 +0x008FE6B3 0x95BF # 0 +0x008FE6B4 0x95C6 # 0 +0x008FE6B5 0x95C8 # 0 +0x008FE6B6 0x95C9 # 0 +0x008FE6B7 0x95CB # 0 +0x008FE6B8 0x95D0 # 0 +0x008FE6B9 0x95D1 # 0 +0x008FE6BA 0x95D2 # 0 +0x008FE6BB 0x95D3 # 0 +0x008FE6BC 0x95D9 # 0 +0x008FE6BD 0x95DA # 0 +0x008FE6BE 0x95DD # 0 +0x008FE6BF 0x95DE # 0 +0x008FE6C0 0x95DF # 0 +0x008FE6C1 0x95E0 # 0 +0x008FE6C2 0x95E4 # 0 +0x008FE6C3 0x95E6 # 0 +0x008FE6C4 0x961D # 0 +0x008FE6C5 0x961E # 0 +0x008FE6C6 0x9622 # 0 +0x008FE6C7 0x9624 # 0 +0x008FE6C8 0x9625 # 0 +0x008FE6C9 0x9626 # 0 +0x008FE6CA 0x962C # 0 +0x008FE6CB 0x9631 # 0 +0x008FE6CC 0x9633 # 0 +0x008FE6CD 0x9637 # 0 +0x008FE6CE 0x9638 # 0 +0x008FE6CF 0x9639 # 0 +0x008FE6D0 0x963A # 0 +0x008FE6D1 0x963C # 0 +0x008FE6D2 0x963D # 0 +0x008FE6D3 0x9641 # 0 +0x008FE6D4 0x9652 # 0 +0x008FE6D5 0x9654 # 0 +0x008FE6D6 0x9656 # 0 +0x008FE6D7 0x9657 # 0 +0x008FE6D8 0x9658 # 0 +0x008FE6D9 0x9661 # 0 +0x008FE6DA 0x966E # 0 +0x008FE6DB 0x9674 # 0 +0x008FE6DC 0x967B # 0 +0x008FE6DD 0x967C # 0 +0x008FE6DE 0x967E # 0 +0x008FE6DF 0x967F # 0 +0x008FE6E0 0x9681 # 0 +0x008FE6E1 0x9682 # 0 +0x008FE6E2 0x9683 # 0 +0x008FE6E3 0x9684 # 0 +0x008FE6E4 0x9689 # 0 +0x008FE6E5 0x9691 # 0 +0x008FE6E6 0x9696 # 0 +0x008FE6E7 0x969A # 0 +0x008FE6E8 0x969D # 0 +0x008FE6E9 0x969F # 0 +0x008FE6EA 0x96A4 # 0 +0x008FE6EB 0x96A5 # 0 +0x008FE6EC 0x96A6 # 0 +0x008FE6ED 0x96A9 # 0 +0x008FE6EE 0x96AE # 0 +0x008FE6EF 0x96AF # 0 +0x008FE6F0 0x96B3 # 0 +0x008FE6F1 0x96BA # 0 +0x008FE6F2 0x96CA # 0 +0x008FE6F3 0x96D2 # 0 +0x008FE6F4 0x5DB2 # 0 +0x008FE6F5 0x96D8 # 0 +0x008FE6F6 0x96DA # 0 +0x008FE6F7 0x96DD # 0 +0x008FE6F8 0x96DE # 0 +0x008FE6F9 0x96DF # 0 +0x008FE6FA 0x96E9 # 0 +0x008FE6FB 0x96EF # 0 +0x008FE6FC 0x96F1 # 0 +0x008FE6FD 0x96FA # 0 +0x008FE6FE 0x9702 # 0 +0x008FE7A1 0x9703 # 0 +0x008FE7A2 0x9705 # 0 +0x008FE7A3 0x9709 # 0 +0x008FE7A4 0x971A # 0 +0x008FE7A5 0x971B # 0 +0x008FE7A6 0x971D # 0 +0x008FE7A7 0x9721 # 0 +0x008FE7A8 0x9722 # 0 +0x008FE7A9 0x9723 # 0 +0x008FE7AA 0x9728 # 0 +0x008FE7AB 0x9731 # 0 +0x008FE7AC 0x9733 # 0 +0x008FE7AD 0x9741 # 0 +0x008FE7AE 0x9743 # 0 +0x008FE7AF 0x974A # 0 +0x008FE7B0 0x974E # 0 +0x008FE7B1 0x974F # 0 +0x008FE7B2 0x9755 # 0 +0x008FE7B3 0x9757 # 0 +0x008FE7B4 0x9758 # 0 +0x008FE7B5 0x975A # 0 +0x008FE7B6 0x975B # 0 +0x008FE7B7 0x9763 # 0 +0x008FE7B8 0x9767 # 0 +0x008FE7B9 0x976A # 0 +0x008FE7BA 0x976E # 0 +0x008FE7BB 0x9773 # 0 +0x008FE7BC 0x9776 # 0 +0x008FE7BD 0x9777 # 0 +0x008FE7BE 0x9778 # 0 +0x008FE7BF 0x977B # 0 +0x008FE7C0 0x977D # 0 +0x008FE7C1 0x977F # 0 +0x008FE7C2 0x9780 # 0 +0x008FE7C3 0x9789 # 0 +0x008FE7C4 0x9795 # 0 +0x008FE7C5 0x9796 # 0 +0x008FE7C6 0x9797 # 0 +0x008FE7C7 0x9799 # 0 +0x008FE7C8 0x979A # 0 +0x008FE7C9 0x979E # 0 +0x008FE7CA 0x979F # 0 +0x008FE7CB 0x97A2 # 0 +0x008FE7CC 0x97AC # 0 +0x008FE7CD 0x97AE # 0 +0x008FE7CE 0x97B1 # 0 +0x008FE7CF 0x97B2 # 0 +0x008FE7D0 0x97B5 # 0 +0x008FE7D1 0x97B6 # 0 +0x008FE7D2 0x97B8 # 0 +0x008FE7D3 0x97B9 # 0 +0x008FE7D4 0x97BA # 0 +0x008FE7D5 0x97BC # 0 +0x008FE7D6 0x97BE # 0 +0x008FE7D7 0x97BF # 0 +0x008FE7D8 0x97C1 # 0 +0x008FE7D9 0x97C4 # 0 +0x008FE7DA 0x97C5 # 0 +0x008FE7DB 0x97C7 # 0 +0x008FE7DC 0x97C9 # 0 +0x008FE7DD 0x97CA # 0 +0x008FE7DE 0x97CC # 0 +0x008FE7DF 0x97CD # 0 +0x008FE7E0 0x97CE # 0 +0x008FE7E1 0x97D0 # 0 +0x008FE7E2 0x97D1 # 0 +0x008FE7E3 0x97D4 # 0 +0x008FE7E4 0x97D7 # 0 +0x008FE7E5 0x97D8 # 0 +0x008FE7E6 0x97D9 # 0 +0x008FE7E7 0x97DD # 0 +0x008FE7E8 0x97DE # 0 +0x008FE7E9 0x97E0 # 0 +0x008FE7EA 0x97DB # 0 +0x008FE7EB 0x97E1 # 0 +0x008FE7EC 0x97E4 # 0 +0x008FE7ED 0x97EF # 0 +0x008FE7EE 0x97F1 # 0 +0x008FE7EF 0x97F4 # 0 +0x008FE7F0 0x97F7 # 0 +0x008FE7F1 0x97F8 # 0 +0x008FE7F2 0x97FA # 0 +0x008FE7F3 0x9807 # 0 +0x008FE7F4 0x980A # 0 +0x008FE7F5 0x9819 # 0 +0x008FE7F6 0x980D # 0 +0x008FE7F7 0x980E # 0 +0x008FE7F8 0x9814 # 0 +0x008FE7F9 0x9816 # 0 +0x008FE7FA 0x981C # 0 +0x008FE7FB 0x981E # 0 +0x008FE7FC 0x9820 # 0 +0x008FE7FD 0x9823 # 0 +0x008FE7FE 0x9826 # 0 +0x008FE8A1 0x982B # 0 +0x008FE8A2 0x982E # 0 +0x008FE8A3 0x982F # 0 +0x008FE8A4 0x9830 # 0 +0x008FE8A5 0x9832 # 0 +0x008FE8A6 0x9833 # 0 +0x008FE8A7 0x9835 # 0 +0x008FE8A8 0x9825 # 0 +0x008FE8A9 0x983E # 0 +0x008FE8AA 0x9844 # 0 +0x008FE8AB 0x9847 # 0 +0x008FE8AC 0x984A # 0 +0x008FE8AD 0x9851 # 0 +0x008FE8AE 0x9852 # 0 +0x008FE8AF 0x9853 # 0 +0x008FE8B0 0x9856 # 0 +0x008FE8B1 0x9857 # 0 +0x008FE8B2 0x9859 # 0 +0x008FE8B3 0x985A # 0 +0x008FE8B4 0x9862 # 0 +0x008FE8B5 0x9863 # 0 +0x008FE8B6 0x9865 # 0 +0x008FE8B7 0x9866 # 0 +0x008FE8B8 0x986A # 0 +0x008FE8B9 0x986C # 0 +0x008FE8BA 0x98AB # 0 +0x008FE8BB 0x98AD # 0 +0x008FE8BC 0x98AE # 0 +0x008FE8BD 0x98B0 # 0 +0x008FE8BE 0x98B4 # 0 +0x008FE8BF 0x98B7 # 0 +0x008FE8C0 0x98B8 # 0 +0x008FE8C1 0x98BA # 0 +0x008FE8C2 0x98BB # 0 +0x008FE8C3 0x98BF # 0 +0x008FE8C4 0x98C2 # 0 +0x008FE8C5 0x98C5 # 0 +0x008FE8C6 0x98C8 # 0 +0x008FE8C7 0x98CC # 0 +0x008FE8C8 0x98E1 # 0 +0x008FE8C9 0x98E3 # 0 +0x008FE8CA 0x98E5 # 0 +0x008FE8CB 0x98E6 # 0 +0x008FE8CC 0x98E7 # 0 +0x008FE8CD 0x98EA # 0 +0x008FE8CE 0x98F3 # 0 +0x008FE8CF 0x98F6 # 0 +0x008FE8D0 0x9902 # 0 +0x008FE8D1 0x9907 # 0 +0x008FE8D2 0x9908 # 0 +0x008FE8D3 0x9911 # 0 +0x008FE8D4 0x9915 # 0 +0x008FE8D5 0x9916 # 0 +0x008FE8D6 0x9917 # 0 +0x008FE8D7 0x991A # 0 +0x008FE8D8 0x991B # 0 +0x008FE8D9 0x991C # 0 +0x008FE8DA 0x991F # 0 +0x008FE8DB 0x9922 # 0 +0x008FE8DC 0x9926 # 0 +0x008FE8DD 0x9927 # 0 +0x008FE8DE 0x992B # 0 +0x008FE8DF 0x9931 # 0 +0x008FE8E0 0x9932 # 0 +0x008FE8E1 0x9933 # 0 +0x008FE8E2 0x9934 # 0 +0x008FE8E3 0x9935 # 0 +0x008FE8E4 0x9939 # 0 +0x008FE8E5 0x993A # 0 +0x008FE8E6 0x993B # 0 +0x008FE8E7 0x993C # 0 +0x008FE8E8 0x9940 # 0 +0x008FE8E9 0x9941 # 0 +0x008FE8EA 0x9946 # 0 +0x008FE8EB 0x9947 # 0 +0x008FE8EC 0x9948 # 0 +0x008FE8ED 0x994D # 0 +0x008FE8EE 0x994E # 0 +0x008FE8EF 0x9954 # 0 +0x008FE8F0 0x9958 # 0 +0x008FE8F1 0x9959 # 0 +0x008FE8F2 0x995B # 0 +0x008FE8F3 0x995C # 0 +0x008FE8F4 0x995E # 0 +0x008FE8F5 0x995F # 0 +0x008FE8F6 0x9960 # 0 +0x008FE8F7 0x999B # 0 +0x008FE8F8 0x999D # 0 +0x008FE8F9 0x999F # 0 +0x008FE8FA 0x99A6 # 0 +0x008FE8FB 0x99B0 # 0 +0x008FE8FC 0x99B1 # 0 +0x008FE8FD 0x99B2 # 0 +0x008FE8FE 0x99B5 # 0 +0x008FE9A1 0x99B9 # 0 +0x008FE9A2 0x99BA # 0 +0x008FE9A3 0x99BD # 0 +0x008FE9A4 0x99BF # 0 +0x008FE9A5 0x99C3 # 0 +0x008FE9A6 0x99C9 # 0 +0x008FE9A7 0x99D3 # 0 +0x008FE9A8 0x99D4 # 0 +0x008FE9A9 0x99D9 # 0 +0x008FE9AA 0x99DA # 0 +0x008FE9AB 0x99DC # 0 +0x008FE9AC 0x99DE # 0 +0x008FE9AD 0x99E7 # 0 +0x008FE9AE 0x99EA # 0 +0x008FE9AF 0x99EB # 0 +0x008FE9B0 0x99EC # 0 +0x008FE9B1 0x99F0 # 0 +0x008FE9B2 0x99F4 # 0 +0x008FE9B3 0x99F5 # 0 +0x008FE9B4 0x99F9 # 0 +0x008FE9B5 0x99FD # 0 +0x008FE9B6 0x99FE # 0 +0x008FE9B7 0x9A02 # 0 +0x008FE9B8 0x9A03 # 0 +0x008FE9B9 0x9A04 # 0 +0x008FE9BA 0x9A0B # 0 +0x008FE9BB 0x9A0C # 0 +0x008FE9BC 0x9A10 # 0 +0x008FE9BD 0x9A11 # 0 +0x008FE9BE 0x9A16 # 0 +0x008FE9BF 0x9A1E # 0 +0x008FE9C0 0x9A20 # 0 +0x008FE9C1 0x9A22 # 0 +0x008FE9C2 0x9A23 # 0 +0x008FE9C3 0x9A24 # 0 +0x008FE9C4 0x9A27 # 0 +0x008FE9C5 0x9A2D # 0 +0x008FE9C6 0x9A2E # 0 +0x008FE9C7 0x9A33 # 0 +0x008FE9C8 0x9A35 # 0 +0x008FE9C9 0x9A36 # 0 +0x008FE9CA 0x9A38 # 0 +0x008FE9CB 0x9A47 # 0 +0x008FE9CC 0x9A41 # 0 +0x008FE9CD 0x9A44 # 0 +0x008FE9CE 0x9A4A # 0 +0x008FE9CF 0x9A4B # 0 +0x008FE9D0 0x9A4C # 0 +0x008FE9D1 0x9A4E # 0 +0x008FE9D2 0x9A51 # 0 +0x008FE9D3 0x9A54 # 0 +0x008FE9D4 0x9A56 # 0 +0x008FE9D5 0x9A5D # 0 +0x008FE9D6 0x9AAA # 0 +0x008FE9D7 0x9AAC # 0 +0x008FE9D8 0x9AAE # 0 +0x008FE9D9 0x9AAF # 0 +0x008FE9DA 0x9AB2 # 0 +0x008FE9DB 0x9AB4 # 0 +0x008FE9DC 0x9AB5 # 0 +0x008FE9DD 0x9AB6 # 0 +0x008FE9DE 0x9AB9 # 0 +0x008FE9DF 0x9ABB # 0 +0x008FE9E0 0x9ABE # 0 +0x008FE9E1 0x9ABF # 0 +0x008FE9E2 0x9AC1 # 0 +0x008FE9E3 0x9AC3 # 0 +0x008FE9E4 0x9AC6 # 0 +0x008FE9E5 0x9AC8 # 0 +0x008FE9E6 0x9ACE # 0 +0x008FE9E7 0x9AD0 # 0 +0x008FE9E8 0x9AD2 # 0 +0x008FE9E9 0x9AD5 # 0 +0x008FE9EA 0x9AD6 # 0 +0x008FE9EB 0x9AD7 # 0 +0x008FE9EC 0x9ADB # 0 +0x008FE9ED 0x9ADC # 0 +0x008FE9EE 0x9AE0 # 0 +0x008FE9EF 0x9AE4 # 0 +0x008FE9F0 0x9AE5 # 0 +0x008FE9F1 0x9AE7 # 0 +0x008FE9F2 0x9AE9 # 0 +0x008FE9F3 0x9AEC # 0 +0x008FE9F4 0x9AF2 # 0 +0x008FE9F5 0x9AF3 # 0 +0x008FE9F6 0x9AF5 # 0 +0x008FE9F7 0x9AF9 # 0 +0x008FE9F8 0x9AFA # 0 +0x008FE9F9 0x9AFD # 0 +0x008FE9FA 0x9AFF # 0 +0x008FE9FB 0x9B00 # 0 +0x008FE9FC 0x9B01 # 0 +0x008FE9FD 0x9B02 # 0 +0x008FE9FE 0x9B03 # 0 +0x008FEAA1 0x9B04 # 0 +0x008FEAA2 0x9B05 # 0 +0x008FEAA3 0x9B08 # 0 +0x008FEAA4 0x9B09 # 0 +0x008FEAA5 0x9B0B # 0 +0x008FEAA6 0x9B0C # 0 +0x008FEAA7 0x9B0D # 0 +0x008FEAA8 0x9B0E # 0 +0x008FEAA9 0x9B10 # 0 +0x008FEAAA 0x9B12 # 0 +0x008FEAAB 0x9B16 # 0 +0x008FEAAC 0x9B19 # 0 +0x008FEAAD 0x9B1B # 0 +0x008FEAAE 0x9B1C # 0 +0x008FEAAF 0x9B20 # 0 +0x008FEAB0 0x9B26 # 0 +0x008FEAB1 0x9B2B # 0 +0x008FEAB2 0x9B2D # 0 +0x008FEAB3 0x9B33 # 0 +0x008FEAB4 0x9B34 # 0 +0x008FEAB5 0x9B35 # 0 +0x008FEAB6 0x9B37 # 0 +0x008FEAB7 0x9B39 # 0 +0x008FEAB8 0x9B3A # 0 +0x008FEAB9 0x9B3D # 0 +0x008FEABA 0x9B48 # 0 +0x008FEABB 0x9B4B # 0 +0x008FEABC 0x9B4C # 0 +0x008FEABD 0x9B55 # 0 +0x008FEABE 0x9B56 # 0 +0x008FEABF 0x9B57 # 0 +0x008FEAC0 0x9B5B # 0 +0x008FEAC1 0x9B5E # 0 +0x008FEAC2 0x9B61 # 0 +0x008FEAC3 0x9B63 # 0 +0x008FEAC4 0x9B65 # 0 +0x008FEAC5 0x9B66 # 0 +0x008FEAC6 0x9B68 # 0 +0x008FEAC7 0x9B6A # 0 +0x008FEAC8 0x9B6B # 0 +0x008FEAC9 0x9B6C # 0 +0x008FEACA 0x9B6D # 0 +0x008FEACB 0x9B6E # 0 +0x008FEACC 0x9B73 # 0 +0x008FEACD 0x9B75 # 0 +0x008FEACE 0x9B77 # 0 +0x008FEACF 0x9B78 # 0 +0x008FEAD0 0x9B79 # 0 +0x008FEAD1 0x9B7F # 0 +0x008FEAD2 0x9B80 # 0 +0x008FEAD3 0x9B84 # 0 +0x008FEAD4 0x9B85 # 0 +0x008FEAD5 0x9B86 # 0 +0x008FEAD6 0x9B87 # 0 +0x008FEAD7 0x9B89 # 0 +0x008FEAD8 0x9B8A # 0 +0x008FEAD9 0x9B8B # 0 +0x008FEADA 0x9B8D # 0 +0x008FEADB 0x9B8F # 0 +0x008FEADC 0x9B90 # 0 +0x008FEADD 0x9B94 # 0 +0x008FEADE 0x9B9A # 0 +0x008FEADF 0x9B9D # 0 +0x008FEAE0 0x9B9E # 0 +0x008FEAE1 0x9BA6 # 0 +0x008FEAE2 0x9BA7 # 0 +0x008FEAE3 0x9BA9 # 0 +0x008FEAE4 0x9BAC # 0 +0x008FEAE5 0x9BB0 # 0 +0x008FEAE6 0x9BB1 # 0 +0x008FEAE7 0x9BB2 # 0 +0x008FEAE8 0x9BB7 # 0 +0x008FEAE9 0x9BB8 # 0 +0x008FEAEA 0x9BBB # 0 +0x008FEAEB 0x9BBC # 0 +0x008FEAEC 0x9BBE # 0 +0x008FEAED 0x9BBF # 0 +0x008FEAEE 0x9BC1 # 0 +0x008FEAEF 0x9BC7 # 0 +0x008FEAF0 0x9BC8 # 0 +0x008FEAF1 0x9BCE # 0 +0x008FEAF2 0x9BD0 # 0 +0x008FEAF3 0x9BD7 # 0 +0x008FEAF4 0x9BD8 # 0 +0x008FEAF5 0x9BDD # 0 +0x008FEAF6 0x9BDF # 0 +0x008FEAF7 0x9BE5 # 0 +0x008FEAF8 0x9BE7 # 0 +0x008FEAF9 0x9BEA # 0 +0x008FEAFA 0x9BEB # 0 +0x008FEAFB 0x9BEF # 0 +0x008FEAFC 0x9BF3 # 0 +0x008FEAFD 0x9BF7 # 0 +0x008FEAFE 0x9BF8 # 0 +0x008FEBA1 0x9BF9 # 0 +0x008FEBA2 0x9BFA # 0 +0x008FEBA3 0x9BFD # 0 +0x008FEBA4 0x9BFF # 0 +0x008FEBA5 0x9C00 # 0 +0x008FEBA6 0x9C02 # 0 +0x008FEBA7 0x9C0B # 0 +0x008FEBA8 0x9C0F # 0 +0x008FEBA9 0x9C11 # 0 +0x008FEBAA 0x9C16 # 0 +0x008FEBAB 0x9C18 # 0 +0x008FEBAC 0x9C19 # 0 +0x008FEBAD 0x9C1A # 0 +0x008FEBAE 0x9C1C # 0 +0x008FEBAF 0x9C1E # 0 +0x008FEBB0 0x9C22 # 0 +0x008FEBB1 0x9C23 # 0 +0x008FEBB2 0x9C26 # 0 +0x008FEBB3 0x9C27 # 0 +0x008FEBB4 0x9C28 # 0 +0x008FEBB5 0x9C29 # 0 +0x008FEBB6 0x9C2A # 0 +0x008FEBB7 0x9C31 # 0 +0x008FEBB8 0x9C35 # 0 +0x008FEBB9 0x9C36 # 0 +0x008FEBBA 0x9C37 # 0 +0x008FEBBB 0x9C3D # 0 +0x008FEBBC 0x9C41 # 0 +0x008FEBBD 0x9C43 # 0 +0x008FEBBE 0x9C44 # 0 +0x008FEBBF 0x9C45 # 0 +0x008FEBC0 0x9C49 # 0 +0x008FEBC1 0x9C4A # 0 +0x008FEBC2 0x9C4E # 0 +0x008FEBC3 0x9C4F # 0 +0x008FEBC4 0x9C50 # 0 +0x008FEBC5 0x9C53 # 0 +0x008FEBC6 0x9C54 # 0 +0x008FEBC7 0x9C56 # 0 +0x008FEBC8 0x9C58 # 0 +0x008FEBC9 0x9C5B # 0 +0x008FEBCA 0x9C5D # 0 +0x008FEBCB 0x9C5E # 0 +0x008FEBCC 0x9C5F # 0 +0x008FEBCD 0x9C63 # 0 +0x008FEBCE 0x9C69 # 0 +0x008FEBCF 0x9C6A # 0 +0x008FEBD0 0x9C5C # 0 +0x008FEBD1 0x9C6B # 0 +0x008FEBD2 0x9C68 # 0 +0x008FEBD3 0x9C6E # 0 +0x008FEBD4 0x9C70 # 0 +0x008FEBD5 0x9C72 # 0 +0x008FEBD6 0x9C75 # 0 +0x008FEBD7 0x9C77 # 0 +0x008FEBD8 0x9C7B # 0 +0x008FEBD9 0x9CE6 # 0 +0x008FEBDA 0x9CF2 # 0 +0x008FEBDB 0x9CF7 # 0 +0x008FEBDC 0x9CF9 # 0 +0x008FEBDD 0x9D0B # 0 +0x008FEBDE 0x9D02 # 0 +0x008FEBDF 0x9D11 # 0 +0x008FEBE0 0x9D17 # 0 +0x008FEBE1 0x9D18 # 0 +0x008FEBE2 0x9D1C # 0 +0x008FEBE3 0x9D1D # 0 +0x008FEBE4 0x9D1E # 0 +0x008FEBE5 0x9D2F # 0 +0x008FEBE6 0x9D30 # 0 +0x008FEBE7 0x9D32 # 0 +0x008FEBE8 0x9D33 # 0 +0x008FEBE9 0x9D34 # 0 +0x008FEBEA 0x9D3A # 0 +0x008FEBEB 0x9D3C # 0 +0x008FEBEC 0x9D45 # 0 +0x008FEBED 0x9D3D # 0 +0x008FEBEE 0x9D42 # 0 +0x008FEBEF 0x9D43 # 0 +0x008FEBF0 0x9D47 # 0 +0x008FEBF1 0x9D4A # 0 +0x008FEBF2 0x9D53 # 0 +0x008FEBF3 0x9D54 # 0 +0x008FEBF4 0x9D5F # 0 +0x008FEBF5 0x9D63 # 0 +0x008FEBF6 0x9D62 # 0 +0x008FEBF7 0x9D65 # 0 +0x008FEBF8 0x9D69 # 0 +0x008FEBF9 0x9D6A # 0 +0x008FEBFA 0x9D6B # 0 +0x008FEBFB 0x9D70 # 0 +0x008FEBFC 0x9D76 # 0 +0x008FEBFD 0x9D77 # 0 +0x008FEBFE 0x9D7B # 0 +0x008FECA1 0x9D7C # 0 +0x008FECA2 0x9D7E # 0 +0x008FECA3 0x9D83 # 0 +0x008FECA4 0x9D84 # 0 +0x008FECA5 0x9D86 # 0 +0x008FECA6 0x9D8A # 0 +0x008FECA7 0x9D8D # 0 +0x008FECA8 0x9D8E # 0 +0x008FECA9 0x9D92 # 0 +0x008FECAA 0x9D93 # 0 +0x008FECAB 0x9D95 # 0 +0x008FECAC 0x9D96 # 0 +0x008FECAD 0x9D97 # 0 +0x008FECAE 0x9D98 # 0 +0x008FECAF 0x9DA1 # 0 +0x008FECB0 0x9DAA # 0 +0x008FECB1 0x9DAC # 0 +0x008FECB2 0x9DAE # 0 +0x008FECB3 0x9DB1 # 0 +0x008FECB4 0x9DB5 # 0 +0x008FECB5 0x9DB9 # 0 +0x008FECB6 0x9DBC # 0 +0x008FECB7 0x9DBF # 0 +0x008FECB8 0x9DC3 # 0 +0x008FECB9 0x9DC7 # 0 +0x008FECBA 0x9DC9 # 0 +0x008FECBB 0x9DCA # 0 +0x008FECBC 0x9DD4 # 0 +0x008FECBD 0x9DD5 # 0 +0x008FECBE 0x9DD6 # 0 +0x008FECBF 0x9DD7 # 0 +0x008FECC0 0x9DDA # 0 +0x008FECC1 0x9DDE # 0 +0x008FECC2 0x9DDF # 0 +0x008FECC3 0x9DE0 # 0 +0x008FECC4 0x9DE5 # 0 +0x008FECC5 0x9DE7 # 0 +0x008FECC6 0x9DE9 # 0 +0x008FECC7 0x9DEB # 0 +0x008FECC8 0x9DEE # 0 +0x008FECC9 0x9DF0 # 0 +0x008FECCA 0x9DF3 # 0 +0x008FECCB 0x9DF4 # 0 +0x008FECCC 0x9DFE # 0 +0x008FECCD 0x9E0A # 0 +0x008FECCE 0x9E02 # 0 +0x008FECCF 0x9E07 # 0 +0x008FECD0 0x9E0E # 0 +0x008FECD1 0x9E10 # 0 +0x008FECD2 0x9E11 # 0 +0x008FECD3 0x9E12 # 0 +0x008FECD4 0x9E15 # 0 +0x008FECD5 0x9E16 # 0 +0x008FECD6 0x9E19 # 0 +0x008FECD7 0x9E1C # 0 +0x008FECD8 0x9E1D # 0 +0x008FECD9 0x9E7A # 0 +0x008FECDA 0x9E7B # 0 +0x008FECDB 0x9E7C # 0 +0x008FECDC 0x9E80 # 0 +0x008FECDD 0x9E82 # 0 +0x008FECDE 0x9E83 # 0 +0x008FECDF 0x9E84 # 0 +0x008FECE0 0x9E85 # 0 +0x008FECE1 0x9E87 # 0 +0x008FECE2 0x9E8E # 0 +0x008FECE3 0x9E8F # 0 +0x008FECE4 0x9E96 # 0 +0x008FECE5 0x9E98 # 0 +0x008FECE6 0x9E9B # 0 +0x008FECE7 0x9E9E # 0 +0x008FECE8 0x9EA4 # 0 +0x008FECE9 0x9EA8 # 0 +0x008FECEA 0x9EAC # 0 +0x008FECEB 0x9EAE # 0 +0x008FECEC 0x9EAF # 0 +0x008FECED 0x9EB0 # 0 +0x008FECEE 0x9EB3 # 0 +0x008FECEF 0x9EB4 # 0 +0x008FECF0 0x9EB5 # 0 +0x008FECF1 0x9EC6 # 0 +0x008FECF2 0x9EC8 # 0 +0x008FECF3 0x9ECB # 0 +0x008FECF4 0x9ED5 # 0 +0x008FECF5 0x9EDF # 0 +0x008FECF6 0x9EE4 # 0 +0x008FECF7 0x9EE7 # 0 +0x008FECF8 0x9EEC # 0 +0x008FECF9 0x9EED # 0 +0x008FECFA 0x9EEE # 0 +0x008FECFB 0x9EF0 # 0 +0x008FECFC 0x9EF1 # 0 +0x008FECFD 0x9EF2 # 0 +0x008FECFE 0x9EF5 # 0 +0x008FEDA1 0x9EF8 # 0 +0x008FEDA2 0x9EFF # 0 +0x008FEDA3 0x9F02 # 0 +0x008FEDA4 0x9F03 # 0 +0x008FEDA5 0x9F09 # 0 +0x008FEDA6 0x9F0F # 0 +0x008FEDA7 0x9F10 # 0 +0x008FEDA8 0x9F11 # 0 +0x008FEDA9 0x9F12 # 0 +0x008FEDAA 0x9F14 # 0 +0x008FEDAB 0x9F16 # 0 +0x008FEDAC 0x9F17 # 0 +0x008FEDAD 0x9F19 # 0 +0x008FEDAE 0x9F1A # 0 +0x008FEDAF 0x9F1B # 0 +0x008FEDB0 0x9F1F # 0 +0x008FEDB1 0x9F22 # 0 +0x008FEDB2 0x9F26 # 0 +0x008FEDB3 0x9F2A # 0 +0x008FEDB4 0x9F2B # 0 +0x008FEDB5 0x9F2F # 0 +0x008FEDB6 0x9F31 # 0 +0x008FEDB7 0x9F32 # 0 +0x008FEDB8 0x9F34 # 0 +0x008FEDB9 0x9F37 # 0 +0x008FEDBA 0x9F39 # 0 +0x008FEDBB 0x9F3A # 0 +0x008FEDBC 0x9F3C # 0 +0x008FEDBD 0x9F3D # 0 +0x008FEDBE 0x9F3F # 0 +0x008FEDBF 0x9F41 # 0 +0x008FEDC0 0x9F43 # 0 +0x008FEDC1 0x9F44 # 0 +0x008FEDC2 0x9F45 # 0 +0x008FEDC3 0x9F46 # 0 +0x008FEDC4 0x9F47 # 0 +0x008FEDC5 0x9F53 # 0 +0x008FEDC6 0x9F55 # 0 +0x008FEDC7 0x9F56 # 0 +0x008FEDC8 0x9F57 # 0 +0x008FEDC9 0x9F58 # 0 +0x008FEDCA 0x9F5A # 0 +0x008FEDCB 0x9F5D # 0 +0x008FEDCC 0x9F5E # 0 +0x008FEDCD 0x9F68 # 0 +0x008FEDCE 0x9F69 # 0 +0x008FEDCF 0x9F6D # 0 +0x008FEDD0 0x9F6E # 0 +0x008FEDD1 0x9F6F # 0 +0x008FEDD2 0x9F70 # 0 +0x008FEDD3 0x9F71 # 0 +0x008FEDD4 0x9F73 # 0 +0x008FEDD5 0x9F75 # 0 +0x008FEDD6 0x9F7A # 0 +0x008FEDD7 0x9F7D # 0 +0x008FEDD8 0x9F8F # 0 +0x008FEDD9 0x9F90 # 0 +0x008FEDDA 0x9F91 # 0 +0x008FEDDB 0x9F92 # 0 +0x008FEDDC 0x9F94 # 0 +0x008FEDDD 0x9F96 # 0 +0x008FEDDE 0x9F97 # 0 +0x008FEDDF 0x9F9E # 0 +0x008FEDE0 0x9FA1 # 0 +0x008FEDE1 0x9FA2 # 0 +0x008FEDE2 0x9FA3 # 0 +0x008FEDE3 0x9FA5 # 0 +0x008FF3F3 0x2170 # 0 +0x008FF3F4 0x2171 # 0 +0x008FF3F5 0x2172 # 0 +0x008FF3F6 0x2173 # 0 +0x008FF3F7 0x2174 # 0 +0x008FF3F8 0x2175 # 0 +0x008FF3F9 0x2176 # 0 +0x008FF3FA 0x2177 # 0 +0x008FF3FB 0x2178 # 0 +0x008FF3FC 0x2179 # 0 +0x008FF4A9 0xFF07 # 0 +0x008FF4AA 0xFF02 # 0 +0x008FF4AE 0x70BB # 0 +0x008FF4AF 0x4EFC # 0 +0x008FF4B0 0x50F4 # 0 +0x008FF4B1 0x51EC # 0 +0x008FF4B2 0x5307 # 0 +0x008FF4B3 0x5324 # 0 +0x008FF4B4 0xFA0E # 0 +0x008FF4B5 0x548A # 0 +0x008FF4B6 0x5759 # 0 +0x008FF4B7 0xFA0F # 0 +0x008FF4B8 0xFA10 # 0 +0x008FF4B9 0x589E # 0 +0x008FF4BA 0x5BEC # 0 +0x008FF4BB 0x5CF5 # 0 +0x008FF4BC 0x5D53 # 0 +0x008FF4BD 0xFA11 # 0 +0x008FF4BE 0x5FB7 # 0 +0x008FF4BF 0x6085 # 0 +0x008FF4C0 0x6120 # 0 +0x008FF4C1 0x654E # 0 +0x008FF4C2 0x663B # 0 +0x008FF4C3 0x6665 # 0 +0x008FF4C4 0xFA12 # 0 +0x008FF4C5 0xF929 # 0 +0x008FF4C6 0x6801 # 0 +0x008FF4C7 0xFA13 # 0 +0x008FF4C8 0xFA14 # 0 +0x008FF4C9 0x6A6B # 0 +0x008FF4CA 0x6AE2 # 0 +0x008FF4CB 0x6DF8 # 0 +0x008FF4CC 0x6DF2 # 0 +0x008FF4CD 0x7028 # 0 +0x008FF4CE 0xFA15 # 0 +0x008FF4CF 0xFA16 # 0 +0x008FF4D0 0x7501 # 0 +0x008FF4D1 0x7682 # 0 +0x008FF4D2 0x769E # 0 +0x008FF4D3 0xFA17 # 0 +0x008FF4D4 0x7930 # 0 +0x008FF4D5 0xFA18 # 0 +0x008FF4D6 0xFA19 # 0 +0x008FF4D7 0xFA1A # 0 +0x008FF4D8 0xFA1B # 0 +0x008FF4D9 0x7AE7 # 0 +0x008FF4DA 0xFA1C # 0 +0x008FF4DB 0xFA1D # 0 +0x008FF4DC 0x7DA0 # 0 +0x008FF4DD 0x7DD6 # 0 +0x008FF4DE 0xFA1E # 0 +0x008FF4DF 0x8362 # 0 +0x008FF4E0 0xFA1F # 0 +0x008FF4E1 0x85B0 # 0 +0x008FF4E2 0xFA20 # 0 +0x008FF4E3 0xFA21 # 0 +0x008FF4E4 0x8807 # 0 +0x008FF4E5 0xFA22 # 0 +0x008FF4E6 0x8B7F # 0 +0x008FF4E7 0x8CF4 # 0 +0x008FF4E8 0x8D76 # 0 +0x008FF4E9 0xFA23 # 0 +0x008FF4EA 0xFA24 # 0 +0x008FF4EB 0xFA25 # 0 +0x008FF4EC 0x90DE # 0 +0x008FF4ED 0xFA26 # 0 +0x008FF4EE 0x9115 # 0 +0x008FF4EF 0xFA27 # 0 +0x008FF4F0 0xFA28 # 0 +0x008FF4F1 0x9592 # 0 +0x008FF4F2 0xF9DC # 0 +0x008FF4F3 0xFA29 # 0 +0x008FF4F4 0x973B # 0 +0x008FF4F5 0x974D # 0 +0x008FF4F6 0x9751 # 0 +0x008FF4F7 0xFA2A # 0 +0x008FF4F8 0xFA2B # 0 +0x008FF4F9 0xFA2C # 0 +0x008FF4FA 0x999E # 0 +0x008FF4FB 0x9AD9 # 0 +0x008FF4FC 0x9B72 # 0 +0x008FF4FD 0xFA2D # 0 +0x008FF4FE 0x9ED1 # 0 +0x008FF5A1 0xE3AC # 0 +0x008FF5A2 0xE3AD # 0 +0x008FF5A3 0xE3AE # 0 +0x008FF5A4 0xE3AF # 0 +0x008FF5A5 0xE3B0 # 0 +0x008FF5A6 0xE3B1 # 0 +0x008FF5A7 0xE3B2 # 0 +0x008FF5A8 0xE3B3 # 0 +0x008FF5A9 0xE3B4 # 0 +0x008FF5AA 0xE3B5 # 0 +0x008FF5AB 0xE3B6 # 0 +0x008FF5AC 0xE3B7 # 0 +0x008FF5AD 0xE3B8 # 0 +0x008FF5AE 0xE3B9 # 0 +0x008FF5AF 0xE3BA # 0 +0x008FF5B0 0xE3BB # 0 +0x008FF5B1 0xE3BC # 0 +0x008FF5B2 0xE3BD # 0 +0x008FF5B3 0xE3BE # 0 +0x008FF5B4 0xE3BF # 0 +0x008FF5B5 0xE3C0 # 0 +0x008FF5B6 0xE3C1 # 0 +0x008FF5B7 0xE3C2 # 0 +0x008FF5B8 0xE3C3 # 0 +0x008FF5B9 0xE3C4 # 0 +0x008FF5BA 0xE3C5 # 0 +0x008FF5BB 0xE3C6 # 0 +0x008FF5BC 0xE3C7 # 0 +0x008FF5BD 0xE3C8 # 0 +0x008FF5BE 0xE3C9 # 0 +0x008FF5BF 0xE3CA # 0 +0x008FF5C0 0xE3CB # 0 +0x008FF5C1 0xE3CC # 0 +0x008FF5C2 0xE3CD # 0 +0x008FF5C3 0xE3CE # 0 +0x008FF5C4 0xE3CF # 0 +0x008FF5C5 0xE3D0 # 0 +0x008FF5C6 0xE3D1 # 0 +0x008FF5C7 0xE3D2 # 0 +0x008FF5C8 0xE3D3 # 0 +0x008FF5C9 0xE3D4 # 0 +0x008FF5CA 0xE3D5 # 0 +0x008FF5CB 0xE3D6 # 0 +0x008FF5CC 0xE3D7 # 0 +0x008FF5CD 0xE3D8 # 0 +0x008FF5CE 0xE3D9 # 0 +0x008FF5CF 0xE3DA # 0 +0x008FF5D0 0xE3DB # 0 +0x008FF5D1 0xE3DC # 0 +0x008FF5D2 0xE3DD # 0 +0x008FF5D3 0xE3DE # 0 +0x008FF5D4 0xE3DF # 0 +0x008FF5D5 0xE3E0 # 0 +0x008FF5D6 0xE3E1 # 0 +0x008FF5D7 0xE3E2 # 0 +0x008FF5D8 0xE3E3 # 0 +0x008FF5D9 0xE3E4 # 0 +0x008FF5DA 0xE3E5 # 0 +0x008FF5DB 0xE3E6 # 0 +0x008FF5DC 0xE3E7 # 0 +0x008FF5DD 0xE3E8 # 0 +0x008FF5DE 0xE3E9 # 0 +0x008FF5DF 0xE3EA # 0 +0x008FF5E0 0xE3EB # 0 +0x008FF5E1 0xE3EC # 0 +0x008FF5E2 0xE3ED # 0 +0x008FF5E3 0xE3EE # 0 +0x008FF5E4 0xE3EF # 0 +0x008FF5E5 0xE3F0 # 0 +0x008FF5E6 0xE3F1 # 0 +0x008FF5E7 0xE3F2 # 0 +0x008FF5E8 0xE3F3 # 0 +0x008FF5E9 0xE3F4 # 0 +0x008FF5EA 0xE3F5 # 0 +0x008FF5EB 0xE3F6 # 0 +0x008FF5EC 0xE3F7 # 0 +0x008FF5ED 0xE3F8 # 0 +0x008FF5EE 0xE3F9 # 0 +0x008FF5EF 0xE3FA # 0 +0x008FF5F0 0xE3FB # 0 +0x008FF5F1 0xE3FC # 0 +0x008FF5F2 0xE3FD # 0 +0x008FF5F3 0xE3FE # 0 +0x008FF5F4 0xE3FF # 0 +0x008FF5F5 0xE400 # 0 +0x008FF5F6 0xE401 # 0 +0x008FF5F7 0xE402 # 0 +0x008FF5F8 0xE403 # 0 +0x008FF5F9 0xE404 # 0 +0x008FF5FA 0xE405 # 0 +0x008FF5FB 0xE406 # 0 +0x008FF5FC 0xE407 # 0 +0x008FF5FD 0xE408 # 0 +0x008FF5FE 0xE409 # 0 +0x008FF6A1 0xE40A # 0 +0x008FF6A2 0xE40B # 0 +0x008FF6A3 0xE40C # 0 +0x008FF6A4 0xE40D # 0 +0x008FF6A5 0xE40E # 0 +0x008FF6A6 0xE40F # 0 +0x008FF6A7 0xE410 # 0 +0x008FF6A8 0xE411 # 0 +0x008FF6A9 0xE412 # 0 +0x008FF6AA 0xE413 # 0 +0x008FF6AB 0xE414 # 0 +0x008FF6AC 0xE415 # 0 +0x008FF6AD 0xE416 # 0 +0x008FF6AE 0xE417 # 0 +0x008FF6AF 0xE418 # 0 +0x008FF6B0 0xE419 # 0 +0x008FF6B1 0xE41A # 0 +0x008FF6B2 0xE41B # 0 +0x008FF6B3 0xE41C # 0 +0x008FF6B4 0xE41D # 0 +0x008FF6B5 0xE41E # 0 +0x008FF6B6 0xE41F # 0 +0x008FF6B7 0xE420 # 0 +0x008FF6B8 0xE421 # 0 +0x008FF6B9 0xE422 # 0 +0x008FF6BA 0xE423 # 0 +0x008FF6BB 0xE424 # 0 +0x008FF6BC 0xE425 # 0 +0x008FF6BD 0xE426 # 0 +0x008FF6BE 0xE427 # 0 +0x008FF6BF 0xE428 # 0 +0x008FF6C0 0xE429 # 0 +0x008FF6C1 0xE42A # 0 +0x008FF6C2 0xE42B # 0 +0x008FF6C3 0xE42C # 0 +0x008FF6C4 0xE42D # 0 +0x008FF6C5 0xE42E # 0 +0x008FF6C6 0xE42F # 0 +0x008FF6C7 0xE430 # 0 +0x008FF6C8 0xE431 # 0 +0x008FF6C9 0xE432 # 0 +0x008FF6CA 0xE433 # 0 +0x008FF6CB 0xE434 # 0 +0x008FF6CC 0xE435 # 0 +0x008FF6CD 0xE436 # 0 +0x008FF6CE 0xE437 # 0 +0x008FF6CF 0xE438 # 0 +0x008FF6D0 0xE439 # 0 +0x008FF6D1 0xE43A # 0 +0x008FF6D2 0xE43B # 0 +0x008FF6D3 0xE43C # 0 +0x008FF6D4 0xE43D # 0 +0x008FF6D5 0xE43E # 0 +0x008FF6D6 0xE43F # 0 +0x008FF6D7 0xE440 # 0 +0x008FF6D8 0xE441 # 0 +0x008FF6D9 0xE442 # 0 +0x008FF6DA 0xE443 # 0 +0x008FF6DB 0xE444 # 0 +0x008FF6DC 0xE445 # 0 +0x008FF6DD 0xE446 # 0 +0x008FF6DE 0xE447 # 0 +0x008FF6DF 0xE448 # 0 +0x008FF6E0 0xE449 # 0 +0x008FF6E1 0xE44A # 0 +0x008FF6E2 0xE44B # 0 +0x008FF6E3 0xE44C # 0 +0x008FF6E4 0xE44D # 0 +0x008FF6E5 0xE44E # 0 +0x008FF6E6 0xE44F # 0 +0x008FF6E7 0xE450 # 0 +0x008FF6E8 0xE451 # 0 +0x008FF6E9 0xE452 # 0 +0x008FF6EA 0xE453 # 0 +0x008FF6EB 0xE454 # 0 +0x008FF6EC 0xE455 # 0 +0x008FF6ED 0xE456 # 0 +0x008FF6EE 0xE457 # 0 +0x008FF6EF 0xE458 # 0 +0x008FF6F0 0xE459 # 0 +0x008FF6F1 0xE45A # 0 +0x008FF6F2 0xE45B # 0 +0x008FF6F3 0xE45C # 0 +0x008FF6F4 0xE45D # 0 +0x008FF6F5 0xE45E # 0 +0x008FF6F6 0xE45F # 0 +0x008FF6F7 0xE460 # 0 +0x008FF6F8 0xE461 # 0 +0x008FF6F9 0xE462 # 0 +0x008FF6FA 0xE463 # 0 +0x008FF6FB 0xE464 # 0 +0x008FF6FC 0xE465 # 0 +0x008FF6FD 0xE466 # 0 +0x008FF6FE 0xE467 # 0 +0x008FF7A1 0xE468 # 0 +0x008FF7A2 0xE469 # 0 +0x008FF7A3 0xE46A # 0 +0x008FF7A4 0xE46B # 0 +0x008FF7A5 0xE46C # 0 +0x008FF7A6 0xE46D # 0 +0x008FF7A7 0xE46E # 0 +0x008FF7A8 0xE46F # 0 +0x008FF7A9 0xE470 # 0 +0x008FF7AA 0xE471 # 0 +0x008FF7AB 0xE472 # 0 +0x008FF7AC 0xE473 # 0 +0x008FF7AD 0xE474 # 0 +0x008FF7AE 0xE475 # 0 +0x008FF7AF 0xE476 # 0 +0x008FF7B0 0xE477 # 0 +0x008FF7B1 0xE478 # 0 +0x008FF7B2 0xE479 # 0 +0x008FF7B3 0xE47A # 0 +0x008FF7B4 0xE47B # 0 +0x008FF7B5 0xE47C # 0 +0x008FF7B6 0xE47D # 0 +0x008FF7B7 0xE47E # 0 +0x008FF7B8 0xE47F # 0 +0x008FF7B9 0xE480 # 0 +0x008FF7BA 0xE481 # 0 +0x008FF7BB 0xE482 # 0 +0x008FF7BC 0xE483 # 0 +0x008FF7BD 0xE484 # 0 +0x008FF7BE 0xE485 # 0 +0x008FF7BF 0xE486 # 0 +0x008FF7C0 0xE487 # 0 +0x008FF7C1 0xE488 # 0 +0x008FF7C2 0xE489 # 0 +0x008FF7C3 0xE48A # 0 +0x008FF7C4 0xE48B # 0 +0x008FF7C5 0xE48C # 0 +0x008FF7C6 0xE48D # 0 +0x008FF7C7 0xE48E # 0 +0x008FF7C8 0xE48F # 0 +0x008FF7C9 0xE490 # 0 +0x008FF7CA 0xE491 # 0 +0x008FF7CB 0xE492 # 0 +0x008FF7CC 0xE493 # 0 +0x008FF7CD 0xE494 # 0 +0x008FF7CE 0xE495 # 0 +0x008FF7CF 0xE496 # 0 +0x008FF7D0 0xE497 # 0 +0x008FF7D1 0xE498 # 0 +0x008FF7D2 0xE499 # 0 +0x008FF7D3 0xE49A # 0 +0x008FF7D4 0xE49B # 0 +0x008FF7D5 0xE49C # 0 +0x008FF7D6 0xE49D # 0 +0x008FF7D7 0xE49E # 0 +0x008FF7D8 0xE49F # 0 +0x008FF7D9 0xE4A0 # 0 +0x008FF7DA 0xE4A1 # 0 +0x008FF7DB 0xE4A2 # 0 +0x008FF7DC 0xE4A3 # 0 +0x008FF7DD 0xE4A4 # 0 +0x008FF7DE 0xE4A5 # 0 +0x008FF7DF 0xE4A6 # 0 +0x008FF7E0 0xE4A7 # 0 +0x008FF7E1 0xE4A8 # 0 +0x008FF7E2 0xE4A9 # 0 +0x008FF7E3 0xE4AA # 0 +0x008FF7E4 0xE4AB # 0 +0x008FF7E5 0xE4AC # 0 +0x008FF7E6 0xE4AD # 0 +0x008FF7E7 0xE4AE # 0 +0x008FF7E8 0xE4AF # 0 +0x008FF7E9 0xE4B0 # 0 +0x008FF7EA 0xE4B1 # 0 +0x008FF7EB 0xE4B2 # 0 +0x008FF7EC 0xE4B3 # 0 +0x008FF7ED 0xE4B4 # 0 +0x008FF7EE 0xE4B5 # 0 +0x008FF7EF 0xE4B6 # 0 +0x008FF7F0 0xE4B7 # 0 +0x008FF7F1 0xE4B8 # 0 +0x008FF7F2 0xE4B9 # 0 +0x008FF7F3 0xE4BA # 0 +0x008FF7F4 0xE4BB # 0 +0x008FF7F5 0xE4BC # 0 +0x008FF7F6 0xE4BD # 0 +0x008FF7F7 0xE4BE # 0 +0x008FF7F8 0xE4BF # 0 +0x008FF7F9 0xE4C0 # 0 +0x008FF7FA 0xE4C1 # 0 +0x008FF7FB 0xE4C2 # 0 +0x008FF7FC 0xE4C3 # 0 +0x008FF7FD 0xE4C4 # 0 +0x008FF7FE 0xE4C5 # 0 +0x008FF8A1 0xE4C6 # 0 +0x008FF8A2 0xE4C7 # 0 +0x008FF8A3 0xE4C8 # 0 +0x008FF8A4 0xE4C9 # 0 +0x008FF8A5 0xE4CA # 0 +0x008FF8A6 0xE4CB # 0 +0x008FF8A7 0xE4CC # 0 +0x008FF8A8 0xE4CD # 0 +0x008FF8A9 0xE4CE # 0 +0x008FF8AA 0xE4CF # 0 +0x008FF8AB 0xE4D0 # 0 +0x008FF8AC 0xE4D1 # 0 +0x008FF8AD 0xE4D2 # 0 +0x008FF8AE 0xE4D3 # 0 +0x008FF8AF 0xE4D4 # 0 +0x008FF8B0 0xE4D5 # 0 +0x008FF8B1 0xE4D6 # 0 +0x008FF8B2 0xE4D7 # 0 +0x008FF8B3 0xE4D8 # 0 +0x008FF8B4 0xE4D9 # 0 +0x008FF8B5 0xE4DA # 0 +0x008FF8B6 0xE4DB # 0 +0x008FF8B7 0xE4DC # 0 +0x008FF8B8 0xE4DD # 0 +0x008FF8B9 0xE4DE # 0 +0x008FF8BA 0xE4DF # 0 +0x008FF8BB 0xE4E0 # 0 +0x008FF8BC 0xE4E1 # 0 +0x008FF8BD 0xE4E2 # 0 +0x008FF8BE 0xE4E3 # 0 +0x008FF8BF 0xE4E4 # 0 +0x008FF8C0 0xE4E5 # 0 +0x008FF8C1 0xE4E6 # 0 +0x008FF8C2 0xE4E7 # 0 +0x008FF8C3 0xE4E8 # 0 +0x008FF8C4 0xE4E9 # 0 +0x008FF8C5 0xE4EA # 0 +0x008FF8C6 0xE4EB # 0 +0x008FF8C7 0xE4EC # 0 +0x008FF8C8 0xE4ED # 0 +0x008FF8C9 0xE4EE # 0 +0x008FF8CA 0xE4EF # 0 +0x008FF8CB 0xE4F0 # 0 +0x008FF8CC 0xE4F1 # 0 +0x008FF8CD 0xE4F2 # 0 +0x008FF8CE 0xE4F3 # 0 +0x008FF8CF 0xE4F4 # 0 +0x008FF8D0 0xE4F5 # 0 +0x008FF8D1 0xE4F6 # 0 +0x008FF8D2 0xE4F7 # 0 +0x008FF8D3 0xE4F8 # 0 +0x008FF8D4 0xE4F9 # 0 +0x008FF8D5 0xE4FA # 0 +0x008FF8D6 0xE4FB # 0 +0x008FF8D7 0xE4FC # 0 +0x008FF8D8 0xE4FD # 0 +0x008FF8D9 0xE4FE # 0 +0x008FF8DA 0xE4FF # 0 +0x008FF8DB 0xE500 # 0 +0x008FF8DC 0xE501 # 0 +0x008FF8DD 0xE502 # 0 +0x008FF8DE 0xE503 # 0 +0x008FF8DF 0xE504 # 0 +0x008FF8E0 0xE505 # 0 +0x008FF8E1 0xE506 # 0 +0x008FF8E2 0xE507 # 0 +0x008FF8E3 0xE508 # 0 +0x008FF8E4 0xE509 # 0 +0x008FF8E5 0xE50A # 0 +0x008FF8E6 0xE50B # 0 +0x008FF8E7 0xE50C # 0 +0x008FF8E8 0xE50D # 0 +0x008FF8E9 0xE50E # 0 +0x008FF8EA 0xE50F # 0 +0x008FF8EB 0xE510 # 0 +0x008FF8EC 0xE511 # 0 +0x008FF8ED 0xE512 # 0 +0x008FF8EE 0xE513 # 0 +0x008FF8EF 0xE514 # 0 +0x008FF8F0 0xE515 # 0 +0x008FF8F1 0xE516 # 0 +0x008FF8F2 0xE517 # 0 +0x008FF8F3 0xE518 # 0 +0x008FF8F4 0xE519 # 0 +0x008FF8F5 0xE51A # 0 +0x008FF8F6 0xE51B # 0 +0x008FF8F7 0xE51C # 0 +0x008FF8F8 0xE51D # 0 +0x008FF8F9 0xE51E # 0 +0x008FF8FA 0xE51F # 0 +0x008FF8FB 0xE520 # 0 +0x008FF8FC 0xE521 # 0 +0x008FF8FD 0xE522 # 0 +0x008FF8FE 0xE523 # 0 +0x008FF9A1 0xE524 # 0 +0x008FF9A2 0xE525 # 0 +0x008FF9A3 0xE526 # 0 +0x008FF9A4 0xE527 # 0 +0x008FF9A5 0xE528 # 0 +0x008FF9A6 0xE529 # 0 +0x008FF9A7 0xE52A # 0 +0x008FF9A8 0xE52B # 0 +0x008FF9A9 0xE52C # 0 +0x008FF9AA 0xE52D # 0 +0x008FF9AB 0xE52E # 0 +0x008FF9AC 0xE52F # 0 +0x008FF9AD 0xE530 # 0 +0x008FF9AE 0xE531 # 0 +0x008FF9AF 0xE532 # 0 +0x008FF9B0 0xE533 # 0 +0x008FF9B1 0xE534 # 0 +0x008FF9B2 0xE535 # 0 +0x008FF9B3 0xE536 # 0 +0x008FF9B4 0xE537 # 0 +0x008FF9B5 0xE538 # 0 +0x008FF9B6 0xE539 # 0 +0x008FF9B7 0xE53A # 0 +0x008FF9B8 0xE53B # 0 +0x008FF9B9 0xE53C # 0 +0x008FF9BA 0xE53D # 0 +0x008FF9BB 0xE53E # 0 +0x008FF9BC 0xE53F # 0 +0x008FF9BD 0xE540 # 0 +0x008FF9BE 0xE541 # 0 +0x008FF9BF 0xE542 # 0 +0x008FF9C0 0xE543 # 0 +0x008FF9C1 0xE544 # 0 +0x008FF9C2 0xE545 # 0 +0x008FF9C3 0xE546 # 0 +0x008FF9C4 0xE547 # 0 +0x008FF9C5 0xE548 # 0 +0x008FF9C6 0xE549 # 0 +0x008FF9C7 0xE54A # 0 +0x008FF9C8 0xE54B # 0 +0x008FF9C9 0xE54C # 0 +0x008FF9CA 0xE54D # 0 +0x008FF9CB 0xE54E # 0 +0x008FF9CC 0xE54F # 0 +0x008FF9CD 0xE550 # 0 +0x008FF9CE 0xE551 # 0 +0x008FF9CF 0xE552 # 0 +0x008FF9D0 0xE553 # 0 +0x008FF9D1 0xE554 # 0 +0x008FF9D2 0xE555 # 0 +0x008FF9D3 0xE556 # 0 +0x008FF9D4 0xE557 # 0 +0x008FF9D5 0xE558 # 0 +0x008FF9D6 0xE559 # 0 +0x008FF9D7 0xE55A # 0 +0x008FF9D8 0xE55B # 0 +0x008FF9D9 0xE55C # 0 +0x008FF9DA 0xE55D # 0 +0x008FF9DB 0xE55E # 0 +0x008FF9DC 0xE55F # 0 +0x008FF9DD 0xE560 # 0 +0x008FF9DE 0xE561 # 0 +0x008FF9DF 0xE562 # 0 +0x008FF9E0 0xE563 # 0 +0x008FF9E1 0xE564 # 0 +0x008FF9E2 0xE565 # 0 +0x008FF9E3 0xE566 # 0 +0x008FF9E4 0xE567 # 0 +0x008FF9E5 0xE568 # 0 +0x008FF9E6 0xE569 # 0 +0x008FF9E7 0xE56A # 0 +0x008FF9E8 0xE56B # 0 +0x008FF9E9 0xE56C # 0 +0x008FF9EA 0xE56D # 0 +0x008FF9EB 0xE56E # 0 +0x008FF9EC 0xE56F # 0 +0x008FF9ED 0xE570 # 0 +0x008FF9EE 0xE571 # 0 +0x008FF9EF 0xE572 # 0 +0x008FF9F0 0xE573 # 0 +0x008FF9F1 0xE574 # 0 +0x008FF9F2 0xE575 # 0 +0x008FF9F3 0xE576 # 0 +0x008FF9F4 0xE577 # 0 +0x008FF9F5 0xE578 # 0 +0x008FF9F6 0xE579 # 0 +0x008FF9F7 0xE57A # 0 +0x008FF9F8 0xE57B # 0 +0x008FF9F9 0xE57C # 0 +0x008FF9FA 0xE57D # 0 +0x008FF9FB 0xE57E # 0 +0x008FF9FC 0xE57F # 0 +0x008FF9FD 0xE580 # 0 +0x008FF9FE 0xE581 # 0 +0x008FFAA1 0xE582 # 0 +0x008FFAA2 0xE583 # 0 +0x008FFAA3 0xE584 # 0 +0x008FFAA4 0xE585 # 0 +0x008FFAA5 0xE586 # 0 +0x008FFAA6 0xE587 # 0 +0x008FFAA7 0xE588 # 0 +0x008FFAA8 0xE589 # 0 +0x008FFAA9 0xE58A # 0 +0x008FFAAA 0xE58B # 0 +0x008FFAAB 0xE58C # 0 +0x008FFAAC 0xE58D # 0 +0x008FFAAD 0xE58E # 0 +0x008FFAAE 0xE58F # 0 +0x008FFAAF 0xE590 # 0 +0x008FFAB0 0xE591 # 0 +0x008FFAB1 0xE592 # 0 +0x008FFAB2 0xE593 # 0 +0x008FFAB3 0xE594 # 0 +0x008FFAB4 0xE595 # 0 +0x008FFAB5 0xE596 # 0 +0x008FFAB6 0xE597 # 0 +0x008FFAB7 0xE598 # 0 +0x008FFAB8 0xE599 # 0 +0x008FFAB9 0xE59A # 0 +0x008FFABA 0xE59B # 0 +0x008FFABB 0xE59C # 0 +0x008FFABC 0xE59D # 0 +0x008FFABD 0xE59E # 0 +0x008FFABE 0xE59F # 0 +0x008FFABF 0xE5A0 # 0 +0x008FFAC0 0xE5A1 # 0 +0x008FFAC1 0xE5A2 # 0 +0x008FFAC2 0xE5A3 # 0 +0x008FFAC3 0xE5A4 # 0 +0x008FFAC4 0xE5A5 # 0 +0x008FFAC5 0xE5A6 # 0 +0x008FFAC6 0xE5A7 # 0 +0x008FFAC7 0xE5A8 # 0 +0x008FFAC8 0xE5A9 # 0 +0x008FFAC9 0xE5AA # 0 +0x008FFACA 0xE5AB # 0 +0x008FFACB 0xE5AC # 0 +0x008FFACC 0xE5AD # 0 +0x008FFACD 0xE5AE # 0 +0x008FFACE 0xE5AF # 0 +0x008FFACF 0xE5B0 # 0 +0x008FFAD0 0xE5B1 # 0 +0x008FFAD1 0xE5B2 # 0 +0x008FFAD2 0xE5B3 # 0 +0x008FFAD3 0xE5B4 # 0 +0x008FFAD4 0xE5B5 # 0 +0x008FFAD5 0xE5B6 # 0 +0x008FFAD6 0xE5B7 # 0 +0x008FFAD7 0xE5B8 # 0 +0x008FFAD8 0xE5B9 # 0 +0x008FFAD9 0xE5BA # 0 +0x008FFADA 0xE5BB # 0 +0x008FFADB 0xE5BC # 0 +0x008FFADC 0xE5BD # 0 +0x008FFADD 0xE5BE # 0 +0x008FFADE 0xE5BF # 0 +0x008FFADF 0xE5C0 # 0 +0x008FFAE0 0xE5C1 # 0 +0x008FFAE1 0xE5C2 # 0 +0x008FFAE2 0xE5C3 # 0 +0x008FFAE3 0xE5C4 # 0 +0x008FFAE4 0xE5C5 # 0 +0x008FFAE5 0xE5C6 # 0 +0x008FFAE6 0xE5C7 # 0 +0x008FFAE7 0xE5C8 # 0 +0x008FFAE8 0xE5C9 # 0 +0x008FFAE9 0xE5CA # 0 +0x008FFAEA 0xE5CB # 0 +0x008FFAEB 0xE5CC # 0 +0x008FFAEC 0xE5CD # 0 +0x008FFAED 0xE5CE # 0 +0x008FFAEE 0xE5CF # 0 +0x008FFAEF 0xE5D0 # 0 +0x008FFAF0 0xE5D1 # 0 +0x008FFAF1 0xE5D2 # 0 +0x008FFAF2 0xE5D3 # 0 +0x008FFAF3 0xE5D4 # 0 +0x008FFAF4 0xE5D5 # 0 +0x008FFAF5 0xE5D6 # 0 +0x008FFAF6 0xE5D7 # 0 +0x008FFAF7 0xE5D8 # 0 +0x008FFAF8 0xE5D9 # 0 +0x008FFAF9 0xE5DA # 0 +0x008FFAFA 0xE5DB # 0 +0x008FFAFB 0xE5DC # 0 +0x008FFAFC 0xE5DD # 0 +0x008FFAFD 0xE5DE # 0 +0x008FFAFE 0xE5DF # 0 +0x008FFBA1 0xE5E0 # 0 +0x008FFBA2 0xE5E1 # 0 +0x008FFBA3 0xE5E2 # 0 +0x008FFBA4 0xE5E3 # 0 +0x008FFBA5 0xE5E4 # 0 +0x008FFBA6 0xE5E5 # 0 +0x008FFBA7 0xE5E6 # 0 +0x008FFBA8 0xE5E7 # 0 +0x008FFBA9 0xE5E8 # 0 +0x008FFBAA 0xE5E9 # 0 +0x008FFBAB 0xE5EA # 0 +0x008FFBAC 0xE5EB # 0 +0x008FFBAD 0xE5EC # 0 +0x008FFBAE 0xE5ED # 0 +0x008FFBAF 0xE5EE # 0 +0x008FFBB0 0xE5EF # 0 +0x008FFBB1 0xE5F0 # 0 +0x008FFBB2 0xE5F1 # 0 +0x008FFBB3 0xE5F2 # 0 +0x008FFBB4 0xE5F3 # 0 +0x008FFBB5 0xE5F4 # 0 +0x008FFBB6 0xE5F5 # 0 +0x008FFBB7 0xE5F6 # 0 +0x008FFBB8 0xE5F7 # 0 +0x008FFBB9 0xE5F8 # 0 +0x008FFBBA 0xE5F9 # 0 +0x008FFBBB 0xE5FA # 0 +0x008FFBBC 0xE5FB # 0 +0x008FFBBD 0xE5FC # 0 +0x008FFBBE 0xE5FD # 0 +0x008FFBBF 0xE5FE # 0 +0x008FFBC0 0xE5FF # 0 +0x008FFBC1 0xE600 # 0 +0x008FFBC2 0xE601 # 0 +0x008FFBC3 0xE602 # 0 +0x008FFBC4 0xE603 # 0 +0x008FFBC5 0xE604 # 0 +0x008FFBC6 0xE605 # 0 +0x008FFBC7 0xE606 # 0 +0x008FFBC8 0xE607 # 0 +0x008FFBC9 0xE608 # 0 +0x008FFBCA 0xE609 # 0 +0x008FFBCB 0xE60A # 0 +0x008FFBCC 0xE60B # 0 +0x008FFBCD 0xE60C # 0 +0x008FFBCE 0xE60D # 0 +0x008FFBCF 0xE60E # 0 +0x008FFBD0 0xE60F # 0 +0x008FFBD1 0xE610 # 0 +0x008FFBD2 0xE611 # 0 +0x008FFBD3 0xE612 # 0 +0x008FFBD4 0xE613 # 0 +0x008FFBD5 0xE614 # 0 +0x008FFBD6 0xE615 # 0 +0x008FFBD7 0xE616 # 0 +0x008FFBD8 0xE617 # 0 +0x008FFBD9 0xE618 # 0 +0x008FFBDA 0xE619 # 0 +0x008FFBDB 0xE61A # 0 +0x008FFBDC 0xE61B # 0 +0x008FFBDD 0xE61C # 0 +0x008FFBDE 0xE61D # 0 +0x008FFBDF 0xE61E # 0 +0x008FFBE0 0xE61F # 0 +0x008FFBE1 0xE620 # 0 +0x008FFBE2 0xE621 # 0 +0x008FFBE3 0xE622 # 0 +0x008FFBE4 0xE623 # 0 +0x008FFBE5 0xE624 # 0 +0x008FFBE6 0xE625 # 0 +0x008FFBE7 0xE626 # 0 +0x008FFBE8 0xE627 # 0 +0x008FFBE9 0xE628 # 0 +0x008FFBEA 0xE629 # 0 +0x008FFBEB 0xE62A # 0 +0x008FFBEC 0xE62B # 0 +0x008FFBED 0xE62C # 0 +0x008FFBEE 0xE62D # 0 +0x008FFBEF 0xE62E # 0 +0x008FFBF0 0xE62F # 0 +0x008FFBF1 0xE630 # 0 +0x008FFBF2 0xE631 # 0 +0x008FFBF3 0xE632 # 0 +0x008FFBF4 0xE633 # 0 +0x008FFBF5 0xE634 # 0 +0x008FFBF6 0xE635 # 0 +0x008FFBF7 0xE636 # 0 +0x008FFBF8 0xE637 # 0 +0x008FFBF9 0xE638 # 0 +0x008FFBFA 0xE639 # 0 +0x008FFBFB 0xE63A # 0 +0x008FFBFC 0xE63B # 0 +0x008FFBFD 0xE63C # 0 +0x008FFBFE 0xE63D # 0 +0x008FFCA1 0xE63E # 0 +0x008FFCA2 0xE63F # 0 +0x008FFCA3 0xE640 # 0 +0x008FFCA4 0xE641 # 0 +0x008FFCA5 0xE642 # 0 +0x008FFCA6 0xE643 # 0 +0x008FFCA7 0xE644 # 0 +0x008FFCA8 0xE645 # 0 +0x008FFCA9 0xE646 # 0 +0x008FFCAA 0xE647 # 0 +0x008FFCAB 0xE648 # 0 +0x008FFCAC 0xE649 # 0 +0x008FFCAD 0xE64A # 0 +0x008FFCAE 0xE64B # 0 +0x008FFCAF 0xE64C # 0 +0x008FFCB0 0xE64D # 0 +0x008FFCB1 0xE64E # 0 +0x008FFCB2 0xE64F # 0 +0x008FFCB3 0xE650 # 0 +0x008FFCB4 0xE651 # 0 +0x008FFCB5 0xE652 # 0 +0x008FFCB6 0xE653 # 0 +0x008FFCB7 0xE654 # 0 +0x008FFCB8 0xE655 # 0 +0x008FFCB9 0xE656 # 0 +0x008FFCBA 0xE657 # 0 +0x008FFCBB 0xE658 # 0 +0x008FFCBC 0xE659 # 0 +0x008FFCBD 0xE65A # 0 +0x008FFCBE 0xE65B # 0 +0x008FFCBF 0xE65C # 0 +0x008FFCC0 0xE65D # 0 +0x008FFCC1 0xE65E # 0 +0x008FFCC2 0xE65F # 0 +0x008FFCC3 0xE660 # 0 +0x008FFCC4 0xE661 # 0 +0x008FFCC5 0xE662 # 0 +0x008FFCC6 0xE663 # 0 +0x008FFCC7 0xE664 # 0 +0x008FFCC8 0xE665 # 0 +0x008FFCC9 0xE666 # 0 +0x008FFCCA 0xE667 # 0 +0x008FFCCB 0xE668 # 0 +0x008FFCCC 0xE669 # 0 +0x008FFCCD 0xE66A # 0 +0x008FFCCE 0xE66B # 0 +0x008FFCCF 0xE66C # 0 +0x008FFCD0 0xE66D # 0 +0x008FFCD1 0xE66E # 0 +0x008FFCD2 0xE66F # 0 +0x008FFCD3 0xE670 # 0 +0x008FFCD4 0xE671 # 0 +0x008FFCD5 0xE672 # 0 +0x008FFCD6 0xE673 # 0 +0x008FFCD7 0xE674 # 0 +0x008FFCD8 0xE675 # 0 +0x008FFCD9 0xE676 # 0 +0x008FFCDA 0xE677 # 0 +0x008FFCDB 0xE678 # 0 +0x008FFCDC 0xE679 # 0 +0x008FFCDD 0xE67A # 0 +0x008FFCDE 0xE67B # 0 +0x008FFCDF 0xE67C # 0 +0x008FFCE0 0xE67D # 0 +0x008FFCE1 0xE67E # 0 +0x008FFCE2 0xE67F # 0 +0x008FFCE3 0xE680 # 0 +0x008FFCE4 0xE681 # 0 +0x008FFCE5 0xE682 # 0 +0x008FFCE6 0xE683 # 0 +0x008FFCE7 0xE684 # 0 +0x008FFCE8 0xE685 # 0 +0x008FFCE9 0xE686 # 0 +0x008FFCEA 0xE687 # 0 +0x008FFCEB 0xE688 # 0 +0x008FFCEC 0xE689 # 0 +0x008FFCED 0xE68A # 0 +0x008FFCEE 0xE68B # 0 +0x008FFCEF 0xE68C # 0 +0x008FFCF0 0xE68D # 0 +0x008FFCF1 0xE68E # 0 +0x008FFCF2 0xE68F # 0 +0x008FFCF3 0xE690 # 0 +0x008FFCF4 0xE691 # 0 +0x008FFCF5 0xE692 # 0 +0x008FFCF6 0xE693 # 0 +0x008FFCF7 0xE694 # 0 +0x008FFCF8 0xE695 # 0 +0x008FFCF9 0xE696 # 0 +0x008FFCFA 0xE697 # 0 +0x008FFCFB 0xE698 # 0 +0x008FFCFC 0xE699 # 0 +0x008FFCFD 0xE69A # 0 +0x008FFCFE 0xE69B # 0 +0x008FFDA1 0xE69C # 0 +0x008FFDA2 0xE69D # 0 +0x008FFDA3 0xE69E # 0 +0x008FFDA4 0xE69F # 0 +0x008FFDA5 0xE6A0 # 0 +0x008FFDA6 0xE6A1 # 0 +0x008FFDA7 0xE6A2 # 0 +0x008FFDA8 0xE6A3 # 0 +0x008FFDA9 0xE6A4 # 0 +0x008FFDAA 0xE6A5 # 0 +0x008FFDAB 0xE6A6 # 0 +0x008FFDAC 0xE6A7 # 0 +0x008FFDAD 0xE6A8 # 0 +0x008FFDAE 0xE6A9 # 0 +0x008FFDAF 0xE6AA # 0 +0x008FFDB0 0xE6AB # 0 +0x008FFDB1 0xE6AC # 0 +0x008FFDB2 0xE6AD # 0 +0x008FFDB3 0xE6AE # 0 +0x008FFDB4 0xE6AF # 0 +0x008FFDB5 0xE6B0 # 0 +0x008FFDB6 0xE6B1 # 0 +0x008FFDB7 0xE6B2 # 0 +0x008FFDB8 0xE6B3 # 0 +0x008FFDB9 0xE6B4 # 0 +0x008FFDBA 0xE6B5 # 0 +0x008FFDBB 0xE6B6 # 0 +0x008FFDBC 0xE6B7 # 0 +0x008FFDBD 0xE6B8 # 0 +0x008FFDBE 0xE6B9 # 0 +0x008FFDBF 0xE6BA # 0 +0x008FFDC0 0xE6BB # 0 +0x008FFDC1 0xE6BC # 0 +0x008FFDC2 0xE6BD # 0 +0x008FFDC3 0xE6BE # 0 +0x008FFDC4 0xE6BF # 0 +0x008FFDC5 0xE6C0 # 0 +0x008FFDC6 0xE6C1 # 0 +0x008FFDC7 0xE6C2 # 0 +0x008FFDC8 0xE6C3 # 0 +0x008FFDC9 0xE6C4 # 0 +0x008FFDCA 0xE6C5 # 0 +0x008FFDCB 0xE6C6 # 0 +0x008FFDCC 0xE6C7 # 0 +0x008FFDCD 0xE6C8 # 0 +0x008FFDCE 0xE6C9 # 0 +0x008FFDCF 0xE6CA # 0 +0x008FFDD0 0xE6CB # 0 +0x008FFDD1 0xE6CC # 0 +0x008FFDD2 0xE6CD # 0 +0x008FFDD3 0xE6CE # 0 +0x008FFDD4 0xE6CF # 0 +0x008FFDD5 0xE6D0 # 0 +0x008FFDD6 0xE6D1 # 0 +0x008FFDD7 0xE6D2 # 0 +0x008FFDD8 0xE6D3 # 0 +0x008FFDD9 0xE6D4 # 0 +0x008FFDDA 0xE6D5 # 0 +0x008FFDDB 0xE6D6 # 0 +0x008FFDDC 0xE6D7 # 0 +0x008FFDDD 0xE6D8 # 0 +0x008FFDDE 0xE6D9 # 0 +0x008FFDDF 0xE6DA # 0 +0x008FFDE0 0xE6DB # 0 +0x008FFDE1 0xE6DC # 0 +0x008FFDE2 0xE6DD # 0 +0x008FFDE3 0xE6DE # 0 +0x008FFDE4 0xE6DF # 0 +0x008FFDE5 0xE6E0 # 0 +0x008FFDE6 0xE6E1 # 0 +0x008FFDE7 0xE6E2 # 0 +0x008FFDE8 0xE6E3 # 0 +0x008FFDE9 0xE6E4 # 0 +0x008FFDEA 0xE6E5 # 0 +0x008FFDEB 0xE6E6 # 0 +0x008FFDEC 0xE6E7 # 0 +0x008FFDED 0xE6E8 # 0 +0x008FFDEE 0xE6E9 # 0 +0x008FFDEF 0xE6EA # 0 +0x008FFDF0 0xE6EB # 0 +0x008FFDF1 0xE6EC # 0 +0x008FFDF2 0xE6ED # 0 +0x008FFDF3 0xE6EE # 0 +0x008FFDF4 0xE6EF # 0 +0x008FFDF5 0xE6F0 # 0 +0x008FFDF6 0xE6F1 # 0 +0x008FFDF7 0xE6F2 # 0 +0x008FFDF8 0xE6F3 # 0 +0x008FFDF9 0xE6F4 # 0 +0x008FFDFA 0xE6F5 # 0 +0x008FFDFB 0xE6F6 # 0 +0x008FFDFC 0xE6F7 # 0 +0x008FFDFD 0xE6F8 # 0 +0x008FFDFE 0xE6F9 # 0 +0x008FFEA1 0xE6FA # 0 +0x008FFEA2 0xE6FB # 0 +0x008FFEA3 0xE6FC # 0 +0x008FFEA4 0xE6FD # 0 +0x008FFEA5 0xE6FE # 0 +0x008FFEA6 0xE6FF # 0 +0x008FFEA7 0xE700 # 0 +0x008FFEA8 0xE701 # 0 +0x008FFEA9 0xE702 # 0 +0x008FFEAA 0xE703 # 0 +0x008FFEAB 0xE704 # 0 +0x008FFEAC 0xE705 # 0 +0x008FFEAD 0xE706 # 0 +0x008FFEAE 0xE707 # 0 +0x008FFEAF 0xE708 # 0 +0x008FFEB0 0xE709 # 0 +0x008FFEB1 0xE70A # 0 +0x008FFEB2 0xE70B # 0 +0x008FFEB3 0xE70C # 0 +0x008FFEB4 0xE70D # 0 +0x008FFEB5 0xE70E # 0 +0x008FFEB6 0xE70F # 0 +0x008FFEB7 0xE710 # 0 +0x008FFEB8 0xE711 # 0 +0x008FFEB9 0xE712 # 0 +0x008FFEBA 0xE713 # 0 +0x008FFEBB 0xE714 # 0 +0x008FFEBC 0xE715 # 0 +0x008FFEBD 0xE716 # 0 +0x008FFEBE 0xE717 # 0 +0x008FFEBF 0xE718 # 0 +0x008FFEC0 0xE719 # 0 +0x008FFEC1 0xE71A # 0 +0x008FFEC2 0xE71B # 0 +0x008FFEC3 0xE71C # 0 +0x008FFEC4 0xE71D # 0 +0x008FFEC5 0xE71E # 0 +0x008FFEC6 0xE71F # 0 +0x008FFEC7 0xE720 # 0 +0x008FFEC8 0xE721 # 0 +0x008FFEC9 0xE722 # 0 +0x008FFECA 0xE723 # 0 +0x008FFECB 0xE724 # 0 +0x008FFECC 0xE725 # 0 +0x008FFECD 0xE726 # 0 +0x008FFECE 0xE727 # 0 +0x008FFECF 0xE728 # 0 +0x008FFED0 0xE729 # 0 +0x008FFED1 0xE72A # 0 +0x008FFED2 0xE72B # 0 +0x008FFED3 0xE72C # 0 +0x008FFED4 0xE72D # 0 +0x008FFED5 0xE72E # 0 +0x008FFED6 0xE72F # 0 +0x008FFED7 0xE730 # 0 +0x008FFED8 0xE731 # 0 +0x008FFED9 0xE732 # 0 +0x008FFEDA 0xE733 # 0 +0x008FFEDB 0xE734 # 0 +0x008FFEDC 0xE735 # 0 +0x008FFEDD 0xE736 # 0 +0x008FFEDE 0xE737 # 0 +0x008FFEDF 0xE738 # 0 +0x008FFEE0 0xE739 # 0 +0x008FFEE1 0xE73A # 0 +0x008FFEE2 0xE73B # 0 +0x008FFEE3 0xE73C # 0 +0x008FFEE4 0xE73D # 0 +0x008FFEE5 0xE73E # 0 +0x008FFEE6 0xE73F # 0 +0x008FFEE7 0xE740 # 0 +0x008FFEE8 0xE741 # 0 +0x008FFEE9 0xE742 # 0 +0x008FFEEA 0xE743 # 0 +0x008FFEEB 0xE744 # 0 +0x008FFEEC 0xE745 # 0 +0x008FFEED 0xE746 # 0 +0x008FFEEE 0xE747 # 0 +0x008FFEEF 0xE748 # 0 +0x008FFEF0 0xE749 # 0 +0x008FFEF1 0xE74A # 0 +0x008FFEF2 0xE74B # 0 +0x008FFEF3 0xE74C # 0 +0x008FFEF4 0xE74D # 0 +0x008FFEF5 0xE74E # 0 +0x008FFEF6 0xE74F # 0 +0x008FFEF7 0xE750 # 0 +0x008FFEF8 0xE751 # 0 +0x008FFEF9 0xE752 # 0 +0x008FFEFA 0xE753 # 0 +0x008FFEFB 0xE754 # 0 +0x008FFEFC 0xE755 # 0 +0x008FFEFD 0xE756 # 0 +0x008FFEFE 0xE757 # 0 diff --git a/data/euc-kr.txt b/data/euc-kr.txt new file mode 100644 index 0000000000..7ea5503602 --- /dev/null +++ b/data/euc-kr.txt @@ -0,0 +1,8371 @@ +# euc-kr.txt - EUC to Unicode charmap +0x00000000 0x0000 # 0 +0x00000001 0x0001 # 0 +0x00000002 0x0002 # 0 +0x00000003 0x0003 # 0 +0x00000004 0x0004 # 0 +0x00000005 0x0005 # 0 +0x00000006 0x0006 # 0 +0x00000007 0x0007 # 0 +0x00000008 0x0008 # 0 +0x00000009 0x0009 # 0 +0x0000000A 0x000A # 0 +0x0000000B 0x000B # 0 +0x0000000C 0x000C # 0 +0x0000000D 0x000D # 0 +0x0000000E 0x000E # 0 +0x0000000F 0x000F # 0 +0x00000010 0x0010 # 0 +0x00000011 0x0011 # 0 +0x00000012 0x0012 # 0 +0x00000013 0x0013 # 0 +0x00000014 0x0014 # 0 +0x00000015 0x0015 # 0 +0x00000016 0x0016 # 0 +0x00000017 0x0017 # 0 +0x00000018 0x0018 # 0 +0x00000019 0x0019 # 0 +0x0000001A 0x001A # 0 +0x0000001B 0x001B # 0 +0x0000001C 0x001C # 0 +0x0000001D 0x001D # 0 +0x0000001E 0x001E # 0 +0x0000001F 0x001F # 0 +0x00000020 0x0020 # 0 +0x00000021 0x0021 # 0 +0x00000022 0x0022 # 0 +0x00000023 0x0023 # 0 +0x00000024 0x0024 # 0 +0x00000025 0x0025 # 0 +0x00000026 0x0026 # 0 +0x00000027 0x0027 # 0 +0x00000028 0x0028 # 0 +0x00000029 0x0029 # 0 +0x0000002A 0x002A # 0 +0x0000002B 0x002B # 0 +0x0000002C 0x002C # 0 +0x0000002D 0x002D # 0 +0x0000002E 0x002E # 0 +0x0000002F 0x002F # 0 +0x00000030 0x0030 # 0 +0x00000031 0x0031 # 0 +0x00000032 0x0032 # 0 +0x00000033 0x0033 # 0 +0x00000034 0x0034 # 0 +0x00000035 0x0035 # 0 +0x00000036 0x0036 # 0 +0x00000037 0x0037 # 0 +0x00000038 0x0038 # 0 +0x00000039 0x0039 # 0 +0x0000003A 0x003A # 0 +0x0000003B 0x003B # 0 +0x0000003C 0x003C # 0 +0x0000003D 0x003D # 0 +0x0000003E 0x003E # 0 +0x0000003F 0x003F # 0 +0x00000040 0x0040 # 0 +0x00000041 0x0041 # 0 +0x00000042 0x0042 # 0 +0x00000043 0x0043 # 0 +0x00000044 0x0044 # 0 +0x00000045 0x0045 # 0 +0x00000046 0x0046 # 0 +0x00000047 0x0047 # 0 +0x00000048 0x0048 # 0 +0x00000049 0x0049 # 0 +0x0000004A 0x004A # 0 +0x0000004B 0x004B # 0 +0x0000004C 0x004C # 0 +0x0000004D 0x004D # 0 +0x0000004E 0x004E # 0 +0x0000004F 0x004F # 0 +0x00000050 0x0050 # 0 +0x00000051 0x0051 # 0 +0x00000052 0x0052 # 0 +0x00000053 0x0053 # 0 +0x00000054 0x0054 # 0 +0x00000055 0x0055 # 0 +0x00000056 0x0056 # 0 +0x00000057 0x0057 # 0 +0x00000058 0x0058 # 0 +0x00000059 0x0059 # 0 +0x0000005A 0x005A # 0 +0x0000005B 0x005B # 0 +0x0000005C 0x005C # 0 +0x0000005D 0x005D # 0 +0x0000005E 0x005E # 0 +0x0000005F 0x005F # 0 +0x00000060 0x0060 # 0 +0x00000061 0x0061 # 0 +0x00000062 0x0062 # 0 +0x00000063 0x0063 # 0 +0x00000064 0x0064 # 0 +0x00000065 0x0065 # 0 +0x00000066 0x0066 # 0 +0x00000067 0x0067 # 0 +0x00000068 0x0068 # 0 +0x00000069 0x0069 # 0 +0x0000006A 0x006A # 0 +0x0000006B 0x006B # 0 +0x0000006C 0x006C # 0 +0x0000006D 0x006D # 0 +0x0000006E 0x006E # 0 +0x0000006F 0x006F # 0 +0x00000070 0x0070 # 0 +0x00000071 0x0071 # 0 +0x00000072 0x0072 # 0 +0x00000073 0x0073 # 0 +0x00000074 0x0074 # 0 +0x00000075 0x0075 # 0 +0x00000076 0x0076 # 0 +0x00000077 0x0077 # 0 +0x00000078 0x0078 # 0 +0x00000079 0x0079 # 0 +0x0000007A 0x007A # 0 +0x0000007B 0x007B # 0 +0x0000007C 0x007C # 0 +0x0000007D 0x007D # 0 +0x0000007E 0x007E # 0 +0x0000007F 0x007F # 0 +0x0000A1A1 0x3000 # 0 +0x0000A1A2 0x3001 # 0 +0x0000A1A3 0x3002 # 0 +0x0000A1A4 0x30FB # 0 +0x0000A1A5 0x2025 # 0 +0x0000A1A6 0x2026 # 0 +0x0000A1A8 0x3003 # 0 +0x0000A1A9 0x2013 # 0 +0x0000A1AA 0x2014 # 0 +0x0000A1AB 0x2016 # 0 +0x0000A1AC 0xFF3C # 0 +0x0000A1AD 0xFF5E # 0 +0x0000A1AE 0x2018 # 0 +0x0000A1AF 0x2019 # 0 +0x0000A1B0 0x201C # 0 +0x0000A1B1 0x201D # 0 +0x0000A1B2 0x3014 # 0 +0x0000A1B3 0x3015 # 0 +0x0000A1B4 0x3008 # 0 +0x0000A1B5 0x3009 # 0 +0x0000A1B6 0x300A # 0 +0x0000A1B7 0x300B # 0 +0x0000A1B8 0x300C # 0 +0x0000A1B9 0x300D # 0 +0x0000A1BA 0x300E # 0 +0x0000A1BB 0x300F # 0 +0x0000A1BC 0x3010 # 0 +0x0000A1BD 0x3011 # 0 +0x0000A1C1 0x2260 # 0 +0x0000A1C2 0x2264 # 0 +0x0000A1C3 0x2265 # 0 +0x0000A1C4 0x221E # 0 +0x0000A1C5 0x2234 # 0 +0x0000A1C7 0x2032 # 0 +0x0000A1C8 0x2033 # 0 +0x0000A1C9 0x2103 # 0 +0x0000A1CA 0x212B # 0 +0x0000A1CB 0xFFE0 # 0 +0x0000A1CC 0xFFE1 # 0 +0x0000A1CD 0xFFE5 # 0 +0x0000A1CE 0x2642 # 0 +0x0000A1CF 0x2640 # 0 +0x0000A1D0 0x2220 # 0 +0x0000A1D1 0x22A5 # 0 +0x0000A1D2 0x2312 # 0 +0x0000A1D3 0x2202 # 0 +0x0000A1D4 0x2207 # 0 +0x0000A1D5 0x2261 # 0 +0x0000A1D6 0x2252 # 0 +0x0000A1D8 0x203B # 0 +0x0000A1D9 0x2606 # 0 +0x0000A1DA 0x2605 # 0 +0x0000A1DB 0x25CB # 0 +0x0000A1DC 0x25CF # 0 +0x0000A1DD 0x25CE # 0 +0x0000A1DE 0x25C7 # 0 +0x0000A1DF 0x25C6 # 0 +0x0000A1E0 0x25A1 # 0 +0x0000A1E1 0x25A0 # 0 +0x0000A1E2 0x25B3 # 0 +0x0000A1E3 0x25B2 # 0 +0x0000A1E4 0x25BD # 0 +0x0000A1E5 0x25BC # 0 +0x0000A1E6 0x2192 # 0 +0x0000A1E7 0x2190 # 0 +0x0000A1E8 0x2191 # 0 +0x0000A1E9 0x2193 # 0 +0x0000A1EA 0x2194 # 0 +0x0000A1EB 0x3013 # 0 +0x0000A1EE 0x221A # 0 +0x0000A1EF 0x223D # 0 +0x0000A1F0 0x221D # 0 +0x0000A1F1 0x2235 # 0 +0x0000A1F2 0x222B # 0 +0x0000A1F3 0x222C # 0 +0x0000A1F4 0x2208 # 0 +0x0000A1F5 0x220B # 0 +0x0000A1F6 0x2286 # 0 +0x0000A1F7 0x2287 # 0 +0x0000A1F8 0x2282 # 0 +0x0000A1F9 0x2283 # 0 +0x0000A1FA 0x222A # 0 +0x0000A1FB 0x2229 # 0 +0x0000A1FC 0x2227 # 0 +0x0000A1FD 0x2228 # 0 +0x0000A1FE 0xFFE2 # 0 +0x0000A2A1 0x21D2 # 0 +0x0000A2A2 0x21D4 # 0 +0x0000A2A3 0x2200 # 0 +0x0000A2A4 0x2203 # 0 +0x0000A2B0 0x2236 # 0 +0x0000A2B1 0x222E # 0 +0x0000A2B2 0x2211 # 0 +0x0000A2B3 0x220F # 0 +0x0000A2B5 0x2109 # 0 +0x0000A2B6 0x2030 # 0 +0x0000A2B7 0x25C1 # 0 +0x0000A2B8 0x25C0 # 0 +0x0000A2B9 0x25B7 # 0 +0x0000A2BA 0x25B6 # 0 +0x0000A2BB 0x2664 # 0 +0x0000A2BC 0x2660 # 0 +0x0000A2BD 0x2661 # 0 +0x0000A2BE 0x2665 # 0 +0x0000A2BF 0x2667 # 0 +0x0000A2C0 0x2663 # 0 +0x0000A2C1 0x25C9 # 0 +0x0000A2C2 0x25C8 # 0 +0x0000A2C3 0x25A3 # 0 +0x0000A2C4 0x25D0 # 0 +0x0000A2C5 0x25D1 # 0 +0x0000A2C6 0x2592 # 0 +0x0000A2C7 0x25A4 # 0 +0x0000A2C8 0x25A5 # 0 +0x0000A2C9 0x25A8 # 0 +0x0000A2CA 0x25A7 # 0 +0x0000A2CB 0x25A6 # 0 +0x0000A2CC 0x25A9 # 0 +0x0000A2CD 0x2668 # 0 +0x0000A2CE 0x260F # 0 +0x0000A2CF 0x260E # 0 +0x0000A2D0 0x261C # 0 +0x0000A2D1 0x261E # 0 +0x0000A2D3 0x2020 # 0 +0x0000A2D4 0x2021 # 0 +0x0000A2D5 0x2195 # 0 +0x0000A2D6 0x2197 # 0 +0x0000A2D7 0x2199 # 0 +0x0000A2D8 0x2196 # 0 +0x0000A2D9 0x2198 # 0 +0x0000A2DA 0x266D # 0 +0x0000A2DB 0x2669 # 0 +0x0000A2DC 0x266A # 0 +0x0000A2DD 0x266C # 0 +0x0000A2DE 0x327F # 0 +0x0000A2DF 0x321C # 0 +0x0000A2E0 0x2116 # 0 +0x0000A2E1 0x33C7 # 0 +0x0000A2E2 0x2122 # 0 +0x0000A2E3 0x33C2 # 0 +0x0000A2E4 0x33D8 # 0 +0x0000A2E5 0x2121 # 0 +0x0000A3A1 0xFF01 # 0 +0x0000A3A2 0xFF02 # 0 +0x0000A3A3 0xFF03 # 0 +0x0000A3A4 0xFF04 # 0 +0x0000A3A5 0xFF05 # 0 +0x0000A3A6 0xFF06 # 0 +0x0000A3A7 0xFF07 # 0 +0x0000A3A8 0xFF08 # 0 +0x0000A3A9 0xFF09 # 0 +0x0000A3AA 0xFF0A # 0 +0x0000A3AB 0xFF0B # 0 +0x0000A3AC 0xFF0C # 0 +0x0000A3AD 0xFF0D # 0 +0x0000A3AE 0xFF0E # 0 +0x0000A3AF 0xFF0F # 0 +0x0000A3B0 0xFF10 # 0 +0x0000A3B1 0xFF11 # 0 +0x0000A3B2 0xFF12 # 0 +0x0000A3B3 0xFF13 # 0 +0x0000A3B4 0xFF14 # 0 +0x0000A3B5 0xFF15 # 0 +0x0000A3B6 0xFF16 # 0 +0x0000A3B7 0xFF17 # 0 +0x0000A3B8 0xFF18 # 0 +0x0000A3B9 0xFF19 # 0 +0x0000A3BA 0xFF1A # 0 +0x0000A3BB 0xFF1B # 0 +0x0000A3BC 0xFF1C # 0 +0x0000A3BD 0xFF1D # 0 +0x0000A3BE 0xFF1E # 0 +0x0000A3BF 0xFF1F # 0 +0x0000A3C0 0xFF20 # 0 +0x0000A3C1 0xFF21 # 0 +0x0000A3C2 0xFF22 # 0 +0x0000A3C3 0xFF23 # 0 +0x0000A3C4 0xFF24 # 0 +0x0000A3C5 0xFF25 # 0 +0x0000A3C6 0xFF26 # 0 +0x0000A3C7 0xFF27 # 0 +0x0000A3C8 0xFF28 # 0 +0x0000A3C9 0xFF29 # 0 +0x0000A3CA 0xFF2A # 0 +0x0000A3CB 0xFF2B # 0 +0x0000A3CC 0xFF2C # 0 +0x0000A3CD 0xFF2D # 0 +0x0000A3CE 0xFF2E # 0 +0x0000A3CF 0xFF2F # 0 +0x0000A3D0 0xFF30 # 0 +0x0000A3D1 0xFF31 # 0 +0x0000A3D2 0xFF32 # 0 +0x0000A3D3 0xFF33 # 0 +0x0000A3D4 0xFF34 # 0 +0x0000A3D5 0xFF35 # 0 +0x0000A3D6 0xFF36 # 0 +0x0000A3D7 0xFF37 # 0 +0x0000A3D8 0xFF38 # 0 +0x0000A3D9 0xFF39 # 0 +0x0000A3DA 0xFF3A # 0 +0x0000A3DB 0xFF3B # 0 +0x0000A3DC 0xFFE6 # 0 +0x0000A3DD 0xFF3D # 0 +0x0000A3DE 0xFF3E # 0 +0x0000A3DF 0xFF3F # 0 +0x0000A3E0 0xFF40 # 0 +0x0000A3E1 0xFF41 # 0 +0x0000A3E2 0xFF42 # 0 +0x0000A3E3 0xFF43 # 0 +0x0000A3E4 0xFF44 # 0 +0x0000A3E5 0xFF45 # 0 +0x0000A3E6 0xFF46 # 0 +0x0000A3E7 0xFF47 # 0 +0x0000A3E8 0xFF48 # 0 +0x0000A3E9 0xFF49 # 0 +0x0000A3EA 0xFF4A # 0 +0x0000A3EB 0xFF4B # 0 +0x0000A3EC 0xFF4C # 0 +0x0000A3ED 0xFF4D # 0 +0x0000A3EE 0xFF4E # 0 +0x0000A3EF 0xFF4F # 0 +0x0000A3F0 0xFF50 # 0 +0x0000A3F1 0xFF51 # 0 +0x0000A3F2 0xFF52 # 0 +0x0000A3F3 0xFF53 # 0 +0x0000A3F4 0xFF54 # 0 +0x0000A3F5 0xFF55 # 0 +0x0000A3F6 0xFF56 # 0 +0x0000A3F7 0xFF57 # 0 +0x0000A3F8 0xFF58 # 0 +0x0000A3F9 0xFF59 # 0 +0x0000A3FA 0xFF5A # 0 +0x0000A3FB 0xFF5B # 0 +0x0000A3FC 0xFF5C # 0 +0x0000A3FD 0xFF5D # 0 +0x0000A3FE 0xFFE3 # 0 +0x0000A4A1 0x3131 # 0 +0x0000A4A2 0x3132 # 0 +0x0000A4A3 0x3133 # 0 +0x0000A4A4 0x3134 # 0 +0x0000A4A5 0x3135 # 0 +0x0000A4A6 0x3136 # 0 +0x0000A4A7 0x3137 # 0 +0x0000A4A8 0x3138 # 0 +0x0000A4A9 0x3139 # 0 +0x0000A4AA 0x313A # 0 +0x0000A4AB 0x313B # 0 +0x0000A4AC 0x313C # 0 +0x0000A4AD 0x313D # 0 +0x0000A4AE 0x313E # 0 +0x0000A4AF 0x313F # 0 +0x0000A4B0 0x3140 # 0 +0x0000A4B1 0x3141 # 0 +0x0000A4B2 0x3142 # 0 +0x0000A4B3 0x3143 # 0 +0x0000A4B4 0x3144 # 0 +0x0000A4B5 0x3145 # 0 +0x0000A4B6 0x3146 # 0 +0x0000A4B7 0x3147 # 0 +0x0000A4B8 0x3148 # 0 +0x0000A4B9 0x3149 # 0 +0x0000A4BA 0x314A # 0 +0x0000A4BB 0x314B # 0 +0x0000A4BC 0x314C # 0 +0x0000A4BD 0x314D # 0 +0x0000A4BE 0x314E # 0 +0x0000A4BF 0x314F # 0 +0x0000A4C0 0x3150 # 0 +0x0000A4C1 0x3151 # 0 +0x0000A4C2 0x3152 # 0 +0x0000A4C3 0x3153 # 0 +0x0000A4C4 0x3154 # 0 +0x0000A4C5 0x3155 # 0 +0x0000A4C6 0x3156 # 0 +0x0000A4C7 0x3157 # 0 +0x0000A4C8 0x3158 # 0 +0x0000A4C9 0x3159 # 0 +0x0000A4CA 0x315A # 0 +0x0000A4CB 0x315B # 0 +0x0000A4CC 0x315C # 0 +0x0000A4CD 0x315D # 0 +0x0000A4CE 0x315E # 0 +0x0000A4CF 0x315F # 0 +0x0000A4D0 0x3160 # 0 +0x0000A4D1 0x3161 # 0 +0x0000A4D2 0x3162 # 0 +0x0000A4D3 0x3163 # 0 +0x0000A4D4 0x3164 # 0 +0x0000A4D5 0x3165 # 0 +0x0000A4D6 0x3166 # 0 +0x0000A4D7 0x3167 # 0 +0x0000A4D8 0x3168 # 0 +0x0000A4D9 0x3169 # 0 +0x0000A4DA 0x316A # 0 +0x0000A4DB 0x316B # 0 +0x0000A4DC 0x316C # 0 +0x0000A4DD 0x316D # 0 +0x0000A4DE 0x316E # 0 +0x0000A4DF 0x316F # 0 +0x0000A4E0 0x3170 # 0 +0x0000A4E1 0x3171 # 0 +0x0000A4E2 0x3172 # 0 +0x0000A4E3 0x3173 # 0 +0x0000A4E4 0x3174 # 0 +0x0000A4E5 0x3175 # 0 +0x0000A4E6 0x3176 # 0 +0x0000A4E7 0x3177 # 0 +0x0000A4E8 0x3178 # 0 +0x0000A4E9 0x3179 # 0 +0x0000A4EA 0x317A # 0 +0x0000A4EB 0x317B # 0 +0x0000A4EC 0x317C # 0 +0x0000A4ED 0x317D # 0 +0x0000A4EE 0x317E # 0 +0x0000A4EF 0x317F # 0 +0x0000A4F0 0x3180 # 0 +0x0000A4F1 0x3181 # 0 +0x0000A4F2 0x3182 # 0 +0x0000A4F3 0x3183 # 0 +0x0000A4F4 0x3184 # 0 +0x0000A4F5 0x3185 # 0 +0x0000A4F6 0x3186 # 0 +0x0000A4F7 0x3187 # 0 +0x0000A4F8 0x3188 # 0 +0x0000A4F9 0x3189 # 0 +0x0000A4FA 0x318A # 0 +0x0000A4FB 0x318B # 0 +0x0000A4FC 0x318C # 0 +0x0000A4FD 0x318D # 0 +0x0000A4FE 0x318E # 0 +0x0000A5A1 0x2170 # 0 +0x0000A5A2 0x2171 # 0 +0x0000A5A3 0x2172 # 0 +0x0000A5A4 0x2173 # 0 +0x0000A5A5 0x2174 # 0 +0x0000A5A6 0x2175 # 0 +0x0000A5A7 0x2176 # 0 +0x0000A5A8 0x2177 # 0 +0x0000A5A9 0x2178 # 0 +0x0000A5AA 0x2179 # 0 +0x0000A5B0 0x2160 # 0 +0x0000A5B1 0x2161 # 0 +0x0000A5B2 0x2162 # 0 +0x0000A5B3 0x2163 # 0 +0x0000A5B4 0x2164 # 0 +0x0000A5B5 0x2165 # 0 +0x0000A5B6 0x2166 # 0 +0x0000A5B7 0x2167 # 0 +0x0000A5B8 0x2168 # 0 +0x0000A5B9 0x2169 # 0 +0x0000A6A1 0x2500 # 0 +0x0000A6A2 0x2502 # 0 +0x0000A6A3 0x250C # 0 +0x0000A6A4 0x2510 # 0 +0x0000A6A5 0x2518 # 0 +0x0000A6A6 0x2514 # 0 +0x0000A6A7 0x251C # 0 +0x0000A6A8 0x252C # 0 +0x0000A6A9 0x2524 # 0 +0x0000A6AA 0x2534 # 0 +0x0000A6AB 0x253C # 0 +0x0000A6AC 0x2501 # 0 +0x0000A6AD 0x2503 # 0 +0x0000A6AE 0x250F # 0 +0x0000A6AF 0x2513 # 0 +0x0000A6B0 0x251B # 0 +0x0000A6B1 0x2517 # 0 +0x0000A6B2 0x2523 # 0 +0x0000A6B3 0x2533 # 0 +0x0000A6B4 0x252B # 0 +0x0000A6B5 0x253B # 0 +0x0000A6B6 0x254B # 0 +0x0000A6B7 0x2520 # 0 +0x0000A6B8 0x252F # 0 +0x0000A6B9 0x2528 # 0 +0x0000A6BA 0x2537 # 0 +0x0000A6BB 0x253F # 0 +0x0000A6BC 0x251D # 0 +0x0000A6BD 0x2530 # 0 +0x0000A6BE 0x2525 # 0 +0x0000A6BF 0x2538 # 0 +0x0000A6C0 0x2542 # 0 +0x0000A6C1 0x2512 # 0 +0x0000A6C2 0x2511 # 0 +0x0000A6C3 0x251A # 0 +0x0000A6C4 0x2519 # 0 +0x0000A6C5 0x2516 # 0 +0x0000A6C6 0x2515 # 0 +0x0000A6C7 0x250E # 0 +0x0000A6C8 0x250D # 0 +0x0000A6C9 0x251E # 0 +0x0000A6CA 0x251F # 0 +0x0000A6CB 0x2521 # 0 +0x0000A6CC 0x2522 # 0 +0x0000A6CD 0x2526 # 0 +0x0000A6CE 0x2527 # 0 +0x0000A6CF 0x2529 # 0 +0x0000A6D0 0x252A # 0 +0x0000A6D1 0x252D # 0 +0x0000A6D2 0x252E # 0 +0x0000A6D3 0x2531 # 0 +0x0000A6D4 0x2532 # 0 +0x0000A6D5 0x2535 # 0 +0x0000A6D6 0x2536 # 0 +0x0000A6D7 0x2539 # 0 +0x0000A6D8 0x253A # 0 +0x0000A6D9 0x253D # 0 +0x0000A6DA 0x253E # 0 +0x0000A6DB 0x2540 # 0 +0x0000A6DC 0x2541 # 0 +0x0000A6DD 0x2543 # 0 +0x0000A6DE 0x2544 # 0 +0x0000A6DF 0x2545 # 0 +0x0000A6E0 0x2546 # 0 +0x0000A6E1 0x2547 # 0 +0x0000A6E2 0x2548 # 0 +0x0000A6E3 0x2549 # 0 +0x0000A6E4 0x254A # 0 +0x0000A7A1 0x3395 # 0 +0x0000A7A2 0x3396 # 0 +0x0000A7A3 0x3397 # 0 +0x0000A7A4 0x2113 # 0 +0x0000A7A5 0x3398 # 0 +0x0000A7A6 0x33C4 # 0 +0x0000A7A7 0x33A3 # 0 +0x0000A7A8 0x33A4 # 0 +0x0000A7A9 0x33A5 # 0 +0x0000A7AA 0x33A6 # 0 +0x0000A7AB 0x3399 # 0 +0x0000A7AC 0x339A # 0 +0x0000A7AD 0x339B # 0 +0x0000A7AE 0x339C # 0 +0x0000A7AF 0x339D # 0 +0x0000A7B0 0x339E # 0 +0x0000A7B1 0x339F # 0 +0x0000A7B2 0x33A0 # 0 +0x0000A7B3 0x33A1 # 0 +0x0000A7B4 0x33A2 # 0 +0x0000A7B5 0x33CA # 0 +0x0000A7B6 0x338D # 0 +0x0000A7B7 0x338E # 0 +0x0000A7B8 0x338F # 0 +0x0000A7B9 0x33CF # 0 +0x0000A7BA 0x3388 # 0 +0x0000A7BB 0x3389 # 0 +0x0000A7BC 0x33C8 # 0 +0x0000A7BD 0x33A7 # 0 +0x0000A7BE 0x33A8 # 0 +0x0000A7BF 0x33B0 # 0 +0x0000A7C0 0x33B1 # 0 +0x0000A7C1 0x33B2 # 0 +0x0000A7C2 0x33B3 # 0 +0x0000A7C3 0x33B4 # 0 +0x0000A7C4 0x33B5 # 0 +0x0000A7C5 0x33B6 # 0 +0x0000A7C6 0x33B7 # 0 +0x0000A7C7 0x33B8 # 0 +0x0000A7C8 0x33B9 # 0 +0x0000A7C9 0x3380 # 0 +0x0000A7CA 0x3381 # 0 +0x0000A7CB 0x3382 # 0 +0x0000A7CC 0x3383 # 0 +0x0000A7CD 0x3384 # 0 +0x0000A7CE 0x33BA # 0 +0x0000A7CF 0x33BB # 0 +0x0000A7D0 0x33BC # 0 +0x0000A7D1 0x33BD # 0 +0x0000A7D2 0x33BE # 0 +0x0000A7D3 0x33BF # 0 +0x0000A7D4 0x3390 # 0 +0x0000A7D5 0x3391 # 0 +0x0000A7D6 0x3392 # 0 +0x0000A7D7 0x3393 # 0 +0x0000A7D8 0x3394 # 0 +0x0000A7D9 0x2126 # 0 +0x0000A7DA 0x33C0 # 0 +0x0000A7DB 0x33C1 # 0 +0x0000A7DC 0x338A # 0 +0x0000A7DD 0x338B # 0 +0x0000A7DE 0x338C # 0 +0x0000A7DF 0x33D6 # 0 +0x0000A7E0 0x33C5 # 0 +0x0000A7E1 0x33AD # 0 +0x0000A7E2 0x33AE # 0 +0x0000A7E3 0x33AF # 0 +0x0000A7E4 0x33DB # 0 +0x0000A7E5 0x33A9 # 0 +0x0000A7E6 0x33AA # 0 +0x0000A7E7 0x33AB # 0 +0x0000A7E8 0x33AC # 0 +0x0000A7E9 0x33DD # 0 +0x0000A7EA 0x33D0 # 0 +0x0000A7EB 0x33D3 # 0 +0x0000A7EC 0x33C3 # 0 +0x0000A7ED 0x33C9 # 0 +0x0000A7EE 0x33DC # 0 +0x0000A7EF 0x33C6 # 0 +0x0000A8B1 0x3260 # 0 +0x0000A8B2 0x3261 # 0 +0x0000A8B3 0x3262 # 0 +0x0000A8B4 0x3263 # 0 +0x0000A8B5 0x3264 # 0 +0x0000A8B6 0x3265 # 0 +0x0000A8B7 0x3266 # 0 +0x0000A8B8 0x3267 # 0 +0x0000A8B9 0x3268 # 0 +0x0000A8BA 0x3269 # 0 +0x0000A8BB 0x326A # 0 +0x0000A8BC 0x326B # 0 +0x0000A8BD 0x326C # 0 +0x0000A8BE 0x326D # 0 +0x0000A8BF 0x326E # 0 +0x0000A8C0 0x326F # 0 +0x0000A8C1 0x3270 # 0 +0x0000A8C2 0x3271 # 0 +0x0000A8C3 0x3272 # 0 +0x0000A8C4 0x3273 # 0 +0x0000A8C5 0x3274 # 0 +0x0000A8C6 0x3275 # 0 +0x0000A8C7 0x3276 # 0 +0x0000A8C8 0x3277 # 0 +0x0000A8C9 0x3278 # 0 +0x0000A8CA 0x3279 # 0 +0x0000A8CB 0x327A # 0 +0x0000A8CC 0x327B # 0 +0x0000A8CD 0x24D0 # 0 +0x0000A8CE 0x24D1 # 0 +0x0000A8CF 0x24D2 # 0 +0x0000A8D0 0x24D3 # 0 +0x0000A8D1 0x24D4 # 0 +0x0000A8D2 0x24D5 # 0 +0x0000A8D3 0x24D6 # 0 +0x0000A8D4 0x24D7 # 0 +0x0000A8D5 0x24D8 # 0 +0x0000A8D6 0x24D9 # 0 +0x0000A8D7 0x24DA # 0 +0x0000A8D8 0x24DB # 0 +0x0000A8D9 0x24DC # 0 +0x0000A8DA 0x24DD # 0 +0x0000A8DB 0x24DE # 0 +0x0000A8DC 0x24DF # 0 +0x0000A8DD 0x24E0 # 0 +0x0000A8DE 0x24E1 # 0 +0x0000A8DF 0x24E2 # 0 +0x0000A8E0 0x24E3 # 0 +0x0000A8E1 0x24E4 # 0 +0x0000A8E2 0x24E5 # 0 +0x0000A8E3 0x24E6 # 0 +0x0000A8E4 0x24E7 # 0 +0x0000A8E5 0x24E8 # 0 +0x0000A8E6 0x24E9 # 0 +0x0000A8E7 0x2460 # 0 +0x0000A8E8 0x2461 # 0 +0x0000A8E9 0x2462 # 0 +0x0000A8EA 0x2463 # 0 +0x0000A8EB 0x2464 # 0 +0x0000A8EC 0x2465 # 0 +0x0000A8ED 0x2466 # 0 +0x0000A8EE 0x2467 # 0 +0x0000A8EF 0x2468 # 0 +0x0000A8F0 0x2469 # 0 +0x0000A8F1 0x246A # 0 +0x0000A8F2 0x246B # 0 +0x0000A8F3 0x246C # 0 +0x0000A8F4 0x246D # 0 +0x0000A8F5 0x246E # 0 +0x0000A8F7 0x2153 # 0 +0x0000A8F8 0x2154 # 0 +0x0000A8FB 0x215B # 0 +0x0000A8FC 0x215C # 0 +0x0000A8FD 0x215D # 0 +0x0000A8FE 0x215E # 0 +0x0000A9B1 0x3200 # 0 +0x0000A9B2 0x3201 # 0 +0x0000A9B3 0x3202 # 0 +0x0000A9B4 0x3203 # 0 +0x0000A9B5 0x3204 # 0 +0x0000A9B6 0x3205 # 0 +0x0000A9B7 0x3206 # 0 +0x0000A9B8 0x3207 # 0 +0x0000A9B9 0x3208 # 0 +0x0000A9BA 0x3209 # 0 +0x0000A9BB 0x320A # 0 +0x0000A9BC 0x320B # 0 +0x0000A9BD 0x320C # 0 +0x0000A9BE 0x320D # 0 +0x0000A9BF 0x320E # 0 +0x0000A9C0 0x320F # 0 +0x0000A9C1 0x3210 # 0 +0x0000A9C2 0x3211 # 0 +0x0000A9C3 0x3212 # 0 +0x0000A9C4 0x3213 # 0 +0x0000A9C5 0x3214 # 0 +0x0000A9C6 0x3215 # 0 +0x0000A9C7 0x3216 # 0 +0x0000A9C8 0x3217 # 0 +0x0000A9C9 0x3218 # 0 +0x0000A9CA 0x3219 # 0 +0x0000A9CB 0x321A # 0 +0x0000A9CC 0x321B # 0 +0x0000A9CD 0x249C # 0 +0x0000A9CE 0x249D # 0 +0x0000A9CF 0x249E # 0 +0x0000A9D0 0x249F # 0 +0x0000A9D1 0x24A0 # 0 +0x0000A9D2 0x24A1 # 0 +0x0000A9D3 0x24A2 # 0 +0x0000A9D4 0x24A3 # 0 +0x0000A9D5 0x24A4 # 0 +0x0000A9D6 0x24A5 # 0 +0x0000A9D7 0x24A6 # 0 +0x0000A9D8 0x24A7 # 0 +0x0000A9D9 0x24A8 # 0 +0x0000A9DA 0x24A9 # 0 +0x0000A9DB 0x24AA # 0 +0x0000A9DC 0x24AB # 0 +0x0000A9DD 0x24AC # 0 +0x0000A9DE 0x24AD # 0 +0x0000A9DF 0x24AE # 0 +0x0000A9E0 0x24AF # 0 +0x0000A9E1 0x24B0 # 0 +0x0000A9E2 0x24B1 # 0 +0x0000A9E3 0x24B2 # 0 +0x0000A9E4 0x24B3 # 0 +0x0000A9E5 0x24B4 # 0 +0x0000A9E6 0x24B5 # 0 +0x0000A9E7 0x2474 # 0 +0x0000A9E8 0x2475 # 0 +0x0000A9E9 0x2476 # 0 +0x0000A9EA 0x2477 # 0 +0x0000A9EB 0x2478 # 0 +0x0000A9EC 0x2479 # 0 +0x0000A9ED 0x247A # 0 +0x0000A9EE 0x247B # 0 +0x0000A9EF 0x247C # 0 +0x0000A9F0 0x247D # 0 +0x0000A9F1 0x247E # 0 +0x0000A9F2 0x247F # 0 +0x0000A9F3 0x2480 # 0 +0x0000A9F4 0x2481 # 0 +0x0000A9F5 0x2482 # 0 +0x0000A9F9 0x2074 # 0 +0x0000A9FA 0x207F # 0 +0x0000A9FB 0x2081 # 0 +0x0000A9FC 0x2082 # 0 +0x0000A9FD 0x2083 # 0 +0x0000A9FE 0x2084 # 0 +0x0000AAA1 0x3041 # 0 +0x0000AAA2 0x3042 # 0 +0x0000AAA3 0x3043 # 0 +0x0000AAA4 0x3044 # 0 +0x0000AAA5 0x3045 # 0 +0x0000AAA6 0x3046 # 0 +0x0000AAA7 0x3047 # 0 +0x0000AAA8 0x3048 # 0 +0x0000AAA9 0x3049 # 0 +0x0000AAAA 0x304A # 0 +0x0000AAAB 0x304B # 0 +0x0000AAAC 0x304C # 0 +0x0000AAAD 0x304D # 0 +0x0000AAAE 0x304E # 0 +0x0000AAAF 0x304F # 0 +0x0000AAB0 0x3050 # 0 +0x0000AAB1 0x3051 # 0 +0x0000AAB2 0x3052 # 0 +0x0000AAB3 0x3053 # 0 +0x0000AAB4 0x3054 # 0 +0x0000AAB5 0x3055 # 0 +0x0000AAB6 0x3056 # 0 +0x0000AAB7 0x3057 # 0 +0x0000AAB8 0x3058 # 0 +0x0000AAB9 0x3059 # 0 +0x0000AABA 0x305A # 0 +0x0000AABB 0x305B # 0 +0x0000AABC 0x305C # 0 +0x0000AABD 0x305D # 0 +0x0000AABE 0x305E # 0 +0x0000AABF 0x305F # 0 +0x0000AAC0 0x3060 # 0 +0x0000AAC1 0x3061 # 0 +0x0000AAC2 0x3062 # 0 +0x0000AAC3 0x3063 # 0 +0x0000AAC4 0x3064 # 0 +0x0000AAC5 0x3065 # 0 +0x0000AAC6 0x3066 # 0 +0x0000AAC7 0x3067 # 0 +0x0000AAC8 0x3068 # 0 +0x0000AAC9 0x3069 # 0 +0x0000AACA 0x306A # 0 +0x0000AACB 0x306B # 0 +0x0000AACC 0x306C # 0 +0x0000AACD 0x306D # 0 +0x0000AACE 0x306E # 0 +0x0000AACF 0x306F # 0 +0x0000AAD0 0x3070 # 0 +0x0000AAD1 0x3071 # 0 +0x0000AAD2 0x3072 # 0 +0x0000AAD3 0x3073 # 0 +0x0000AAD4 0x3074 # 0 +0x0000AAD5 0x3075 # 0 +0x0000AAD6 0x3076 # 0 +0x0000AAD7 0x3077 # 0 +0x0000AAD8 0x3078 # 0 +0x0000AAD9 0x3079 # 0 +0x0000AADA 0x307A # 0 +0x0000AADB 0x307B # 0 +0x0000AADC 0x307C # 0 +0x0000AADD 0x307D # 0 +0x0000AADE 0x307E # 0 +0x0000AADF 0x307F # 0 +0x0000AAE0 0x3080 # 0 +0x0000AAE1 0x3081 # 0 +0x0000AAE2 0x3082 # 0 +0x0000AAE3 0x3083 # 0 +0x0000AAE4 0x3084 # 0 +0x0000AAE5 0x3085 # 0 +0x0000AAE6 0x3086 # 0 +0x0000AAE7 0x3087 # 0 +0x0000AAE8 0x3088 # 0 +0x0000AAE9 0x3089 # 0 +0x0000AAEA 0x308A # 0 +0x0000AAEB 0x308B # 0 +0x0000AAEC 0x308C # 0 +0x0000AAED 0x308D # 0 +0x0000AAEE 0x308E # 0 +0x0000AAEF 0x308F # 0 +0x0000AAF0 0x3090 # 0 +0x0000AAF1 0x3091 # 0 +0x0000AAF2 0x3092 # 0 +0x0000AAF3 0x3093 # 0 +0x0000ABA1 0x30A1 # 0 +0x0000ABA2 0x30A2 # 0 +0x0000ABA3 0x30A3 # 0 +0x0000ABA4 0x30A4 # 0 +0x0000ABA5 0x30A5 # 0 +0x0000ABA6 0x30A6 # 0 +0x0000ABA7 0x30A7 # 0 +0x0000ABA8 0x30A8 # 0 +0x0000ABA9 0x30A9 # 0 +0x0000ABAA 0x30AA # 0 +0x0000ABAB 0x30AB # 0 +0x0000ABAC 0x30AC # 0 +0x0000ABAD 0x30AD # 0 +0x0000ABAE 0x30AE # 0 +0x0000ABAF 0x30AF # 0 +0x0000ABB0 0x30B0 # 0 +0x0000ABB1 0x30B1 # 0 +0x0000ABB2 0x30B2 # 0 +0x0000ABB3 0x30B3 # 0 +0x0000ABB4 0x30B4 # 0 +0x0000ABB5 0x30B5 # 0 +0x0000ABB6 0x30B6 # 0 +0x0000ABB7 0x30B7 # 0 +0x0000ABB8 0x30B8 # 0 +0x0000ABB9 0x30B9 # 0 +0x0000ABBA 0x30BA # 0 +0x0000ABBB 0x30BB # 0 +0x0000ABBC 0x30BC # 0 +0x0000ABBD 0x30BD # 0 +0x0000ABBE 0x30BE # 0 +0x0000ABBF 0x30BF # 0 +0x0000ABC0 0x30C0 # 0 +0x0000ABC1 0x30C1 # 0 +0x0000ABC2 0x30C2 # 0 +0x0000ABC3 0x30C3 # 0 +0x0000ABC4 0x30C4 # 0 +0x0000ABC5 0x30C5 # 0 +0x0000ABC6 0x30C6 # 0 +0x0000ABC7 0x30C7 # 0 +0x0000ABC8 0x30C8 # 0 +0x0000ABC9 0x30C9 # 0 +0x0000ABCA 0x30CA # 0 +0x0000ABCB 0x30CB # 0 +0x0000ABCC 0x30CC # 0 +0x0000ABCD 0x30CD # 0 +0x0000ABCE 0x30CE # 0 +0x0000ABCF 0x30CF # 0 +0x0000ABD0 0x30D0 # 0 +0x0000ABD1 0x30D1 # 0 +0x0000ABD2 0x30D2 # 0 +0x0000ABD3 0x30D3 # 0 +0x0000ABD4 0x30D4 # 0 +0x0000ABD5 0x30D5 # 0 +0x0000ABD6 0x30D6 # 0 +0x0000ABD7 0x30D7 # 0 +0x0000ABD8 0x30D8 # 0 +0x0000ABD9 0x30D9 # 0 +0x0000ABDA 0x30DA # 0 +0x0000ABDB 0x30DB # 0 +0x0000ABDC 0x30DC # 0 +0x0000ABDD 0x30DD # 0 +0x0000ABDE 0x30DE # 0 +0x0000ABDF 0x30DF # 0 +0x0000ABE0 0x30E0 # 0 +0x0000ABE1 0x30E1 # 0 +0x0000ABE2 0x30E2 # 0 +0x0000ABE3 0x30E3 # 0 +0x0000ABE4 0x30E4 # 0 +0x0000ABE5 0x30E5 # 0 +0x0000ABE6 0x30E6 # 0 +0x0000ABE7 0x30E7 # 0 +0x0000ABE8 0x30E8 # 0 +0x0000ABE9 0x30E9 # 0 +0x0000ABEA 0x30EA # 0 +0x0000ABEB 0x30EB # 0 +0x0000ABEC 0x30EC # 0 +0x0000ABED 0x30ED # 0 +0x0000ABEE 0x30EE # 0 +0x0000ABEF 0x30EF # 0 +0x0000ABF0 0x30F0 # 0 +0x0000ABF1 0x30F1 # 0 +0x0000ABF2 0x30F2 # 0 +0x0000ABF3 0x30F3 # 0 +0x0000ABF4 0x30F4 # 0 +0x0000ABF5 0x30F5 # 0 +0x0000ABF6 0x30F6 # 0 +0x0000B0A1 0xAC00 # 0 +0x0000B0A2 0xAC01 # 0 +0x0000B0A3 0xAC04 # 0 +0x0000B0A4 0xAC07 # 0 +0x0000B0A5 0xAC08 # 0 +0x0000B0A6 0xAC09 # 0 +0x0000B0A7 0xAC0A # 0 +0x0000B0A8 0xAC10 # 0 +0x0000B0A9 0xAC11 # 0 +0x0000B0AA 0xAC12 # 0 +0x0000B0AB 0xAC13 # 0 +0x0000B0AC 0xAC14 # 0 +0x0000B0AD 0xAC15 # 0 +0x0000B0AE 0xAC16 # 0 +0x0000B0AF 0xAC17 # 0 +0x0000B0B0 0xAC19 # 0 +0x0000B0B1 0xAC1A # 0 +0x0000B0B2 0xAC1B # 0 +0x0000B0B3 0xAC1C # 0 +0x0000B0B4 0xAC1D # 0 +0x0000B0B5 0xAC20 # 0 +0x0000B0B6 0xAC24 # 0 +0x0000B0B7 0xAC2C # 0 +0x0000B0B8 0xAC2D # 0 +0x0000B0B9 0xAC2F # 0 +0x0000B0BA 0xAC30 # 0 +0x0000B0BB 0xAC31 # 0 +0x0000B0BC 0xAC38 # 0 +0x0000B0BD 0xAC39 # 0 +0x0000B0BE 0xAC3C # 0 +0x0000B0BF 0xAC40 # 0 +0x0000B0C0 0xAC4B # 0 +0x0000B0C1 0xAC4D # 0 +0x0000B0C2 0xAC54 # 0 +0x0000B0C3 0xAC58 # 0 +0x0000B0C4 0xAC5C # 0 +0x0000B0C5 0xAC70 # 0 +0x0000B0C6 0xAC71 # 0 +0x0000B0C7 0xAC74 # 0 +0x0000B0C8 0xAC77 # 0 +0x0000B0C9 0xAC78 # 0 +0x0000B0CA 0xAC7A # 0 +0x0000B0CB 0xAC80 # 0 +0x0000B0CC 0xAC81 # 0 +0x0000B0CD 0xAC83 # 0 +0x0000B0CE 0xAC84 # 0 +0x0000B0CF 0xAC85 # 0 +0x0000B0D0 0xAC86 # 0 +0x0000B0D1 0xAC89 # 0 +0x0000B0D2 0xAC8A # 0 +0x0000B0D3 0xAC8B # 0 +0x0000B0D4 0xAC8C # 0 +0x0000B0D5 0xAC90 # 0 +0x0000B0D6 0xAC94 # 0 +0x0000B0D7 0xAC9C # 0 +0x0000B0D8 0xAC9D # 0 +0x0000B0D9 0xAC9F # 0 +0x0000B0DA 0xACA0 # 0 +0x0000B0DB 0xACA1 # 0 +0x0000B0DC 0xACA8 # 0 +0x0000B0DD 0xACA9 # 0 +0x0000B0DE 0xACAA # 0 +0x0000B0DF 0xACAC # 0 +0x0000B0E0 0xACAF # 0 +0x0000B0E1 0xACB0 # 0 +0x0000B0E2 0xACB8 # 0 +0x0000B0E3 0xACB9 # 0 +0x0000B0E4 0xACBB # 0 +0x0000B0E5 0xACBC # 0 +0x0000B0E6 0xACBD # 0 +0x0000B0E7 0xACC1 # 0 +0x0000B0E8 0xACC4 # 0 +0x0000B0E9 0xACC8 # 0 +0x0000B0EA 0xACCC # 0 +0x0000B0EB 0xACD5 # 0 +0x0000B0EC 0xACD7 # 0 +0x0000B0ED 0xACE0 # 0 +0x0000B0EE 0xACE1 # 0 +0x0000B0EF 0xACE4 # 0 +0x0000B0F0 0xACE7 # 0 +0x0000B0F1 0xACE8 # 0 +0x0000B0F2 0xACEA # 0 +0x0000B0F3 0xACEC # 0 +0x0000B0F4 0xACEF # 0 +0x0000B0F5 0xACF0 # 0 +0x0000B0F6 0xACF1 # 0 +0x0000B0F7 0xACF3 # 0 +0x0000B0F8 0xACF5 # 0 +0x0000B0F9 0xACF6 # 0 +0x0000B0FA 0xACFC # 0 +0x0000B0FB 0xACFD # 0 +0x0000B0FC 0xAD00 # 0 +0x0000B0FD 0xAD04 # 0 +0x0000B0FE 0xAD06 # 0 +0x0000B1A1 0xAD0C # 0 +0x0000B1A2 0xAD0D # 0 +0x0000B1A3 0xAD0F # 0 +0x0000B1A4 0xAD11 # 0 +0x0000B1A5 0xAD18 # 0 +0x0000B1A6 0xAD1C # 0 +0x0000B1A7 0xAD20 # 0 +0x0000B1A8 0xAD29 # 0 +0x0000B1A9 0xAD2C # 0 +0x0000B1AA 0xAD2D # 0 +0x0000B1AB 0xAD34 # 0 +0x0000B1AC 0xAD35 # 0 +0x0000B1AD 0xAD38 # 0 +0x0000B1AE 0xAD3C # 0 +0x0000B1AF 0xAD44 # 0 +0x0000B1B0 0xAD45 # 0 +0x0000B1B1 0xAD47 # 0 +0x0000B1B2 0xAD49 # 0 +0x0000B1B3 0xAD50 # 0 +0x0000B1B4 0xAD54 # 0 +0x0000B1B5 0xAD58 # 0 +0x0000B1B6 0xAD61 # 0 +0x0000B1B7 0xAD63 # 0 +0x0000B1B8 0xAD6C # 0 +0x0000B1B9 0xAD6D # 0 +0x0000B1BA 0xAD70 # 0 +0x0000B1BB 0xAD73 # 0 +0x0000B1BC 0xAD74 # 0 +0x0000B1BD 0xAD75 # 0 +0x0000B1BE 0xAD76 # 0 +0x0000B1BF 0xAD7B # 0 +0x0000B1C0 0xAD7C # 0 +0x0000B1C1 0xAD7D # 0 +0x0000B1C2 0xAD7F # 0 +0x0000B1C3 0xAD81 # 0 +0x0000B1C4 0xAD82 # 0 +0x0000B1C5 0xAD88 # 0 +0x0000B1C6 0xAD89 # 0 +0x0000B1C7 0xAD8C # 0 +0x0000B1C8 0xAD90 # 0 +0x0000B1C9 0xAD9C # 0 +0x0000B1CA 0xAD9D # 0 +0x0000B1CB 0xADA4 # 0 +0x0000B1CC 0xADB7 # 0 +0x0000B1CD 0xADC0 # 0 +0x0000B1CE 0xADC1 # 0 +0x0000B1CF 0xADC4 # 0 +0x0000B1D0 0xADC8 # 0 +0x0000B1D1 0xADD0 # 0 +0x0000B1D2 0xADD1 # 0 +0x0000B1D3 0xADD3 # 0 +0x0000B1D4 0xADDC # 0 +0x0000B1D5 0xADE0 # 0 +0x0000B1D6 0xADE4 # 0 +0x0000B1D7 0xADF8 # 0 +0x0000B1D8 0xADF9 # 0 +0x0000B1D9 0xADFC # 0 +0x0000B1DA 0xADFF # 0 +0x0000B1DB 0xAE00 # 0 +0x0000B1DC 0xAE01 # 0 +0x0000B1DD 0xAE08 # 0 +0x0000B1DE 0xAE09 # 0 +0x0000B1DF 0xAE0B # 0 +0x0000B1E0 0xAE0D # 0 +0x0000B1E1 0xAE14 # 0 +0x0000B1E2 0xAE30 # 0 +0x0000B1E3 0xAE31 # 0 +0x0000B1E4 0xAE34 # 0 +0x0000B1E5 0xAE37 # 0 +0x0000B1E6 0xAE38 # 0 +0x0000B1E7 0xAE3A # 0 +0x0000B1E8 0xAE40 # 0 +0x0000B1E9 0xAE41 # 0 +0x0000B1EA 0xAE43 # 0 +0x0000B1EB 0xAE45 # 0 +0x0000B1EC 0xAE46 # 0 +0x0000B1ED 0xAE4A # 0 +0x0000B1EE 0xAE4C # 0 +0x0000B1EF 0xAE4D # 0 +0x0000B1F0 0xAE4E # 0 +0x0000B1F1 0xAE50 # 0 +0x0000B1F2 0xAE54 # 0 +0x0000B1F3 0xAE56 # 0 +0x0000B1F4 0xAE5C # 0 +0x0000B1F5 0xAE5D # 0 +0x0000B1F6 0xAE5F # 0 +0x0000B1F7 0xAE60 # 0 +0x0000B1F8 0xAE61 # 0 +0x0000B1F9 0xAE65 # 0 +0x0000B1FA 0xAE68 # 0 +0x0000B1FB 0xAE69 # 0 +0x0000B1FC 0xAE6C # 0 +0x0000B1FD 0xAE70 # 0 +0x0000B1FE 0xAE78 # 0 +0x0000B2A1 0xAE79 # 0 +0x0000B2A2 0xAE7B # 0 +0x0000B2A3 0xAE7C # 0 +0x0000B2A4 0xAE7D # 0 +0x0000B2A5 0xAE84 # 0 +0x0000B2A6 0xAE85 # 0 +0x0000B2A7 0xAE8C # 0 +0x0000B2A8 0xAEBC # 0 +0x0000B2A9 0xAEBD # 0 +0x0000B2AA 0xAEBE # 0 +0x0000B2AB 0xAEC0 # 0 +0x0000B2AC 0xAEC4 # 0 +0x0000B2AD 0xAECC # 0 +0x0000B2AE 0xAECD # 0 +0x0000B2AF 0xAECF # 0 +0x0000B2B0 0xAED0 # 0 +0x0000B2B1 0xAED1 # 0 +0x0000B2B2 0xAED8 # 0 +0x0000B2B3 0xAED9 # 0 +0x0000B2B4 0xAEDC # 0 +0x0000B2B5 0xAEE8 # 0 +0x0000B2B6 0xAEEB # 0 +0x0000B2B7 0xAEED # 0 +0x0000B2B8 0xAEF4 # 0 +0x0000B2B9 0xAEF8 # 0 +0x0000B2BA 0xAEFC # 0 +0x0000B2BB 0xAF07 # 0 +0x0000B2BC 0xAF08 # 0 +0x0000B2BD 0xAF0D # 0 +0x0000B2BE 0xAF10 # 0 +0x0000B2BF 0xAF2C # 0 +0x0000B2C0 0xAF2D # 0 +0x0000B2C1 0xAF30 # 0 +0x0000B2C2 0xAF32 # 0 +0x0000B2C3 0xAF34 # 0 +0x0000B2C4 0xAF3C # 0 +0x0000B2C5 0xAF3D # 0 +0x0000B2C6 0xAF3F # 0 +0x0000B2C7 0xAF41 # 0 +0x0000B2C8 0xAF42 # 0 +0x0000B2C9 0xAF43 # 0 +0x0000B2CA 0xAF48 # 0 +0x0000B2CB 0xAF49 # 0 +0x0000B2CC 0xAF50 # 0 +0x0000B2CD 0xAF5C # 0 +0x0000B2CE 0xAF5D # 0 +0x0000B2CF 0xAF64 # 0 +0x0000B2D0 0xAF65 # 0 +0x0000B2D1 0xAF79 # 0 +0x0000B2D2 0xAF80 # 0 +0x0000B2D3 0xAF84 # 0 +0x0000B2D4 0xAF88 # 0 +0x0000B2D5 0xAF90 # 0 +0x0000B2D6 0xAF91 # 0 +0x0000B2D7 0xAF95 # 0 +0x0000B2D8 0xAF9C # 0 +0x0000B2D9 0xAFB8 # 0 +0x0000B2DA 0xAFB9 # 0 +0x0000B2DB 0xAFBC # 0 +0x0000B2DC 0xAFC0 # 0 +0x0000B2DD 0xAFC7 # 0 +0x0000B2DE 0xAFC8 # 0 +0x0000B2DF 0xAFC9 # 0 +0x0000B2E0 0xAFCB # 0 +0x0000B2E1 0xAFCD # 0 +0x0000B2E2 0xAFCE # 0 +0x0000B2E3 0xAFD4 # 0 +0x0000B2E4 0xAFDC # 0 +0x0000B2E5 0xAFE8 # 0 +0x0000B2E6 0xAFE9 # 0 +0x0000B2E7 0xAFF0 # 0 +0x0000B2E8 0xAFF1 # 0 +0x0000B2E9 0xAFF4 # 0 +0x0000B2EA 0xAFF8 # 0 +0x0000B2EB 0xB000 # 0 +0x0000B2EC 0xB001 # 0 +0x0000B2ED 0xB004 # 0 +0x0000B2EE 0xB00C # 0 +0x0000B2EF 0xB010 # 0 +0x0000B2F0 0xB014 # 0 +0x0000B2F1 0xB01C # 0 +0x0000B2F2 0xB01D # 0 +0x0000B2F3 0xB028 # 0 +0x0000B2F4 0xB044 # 0 +0x0000B2F5 0xB045 # 0 +0x0000B2F6 0xB048 # 0 +0x0000B2F7 0xB04A # 0 +0x0000B2F8 0xB04C # 0 +0x0000B2F9 0xB04E # 0 +0x0000B2FA 0xB053 # 0 +0x0000B2FB 0xB054 # 0 +0x0000B2FC 0xB055 # 0 +0x0000B2FD 0xB057 # 0 +0x0000B2FE 0xB059 # 0 +0x0000B3A1 0xB05D # 0 +0x0000B3A2 0xB07C # 0 +0x0000B3A3 0xB07D # 0 +0x0000B3A4 0xB080 # 0 +0x0000B3A5 0xB084 # 0 +0x0000B3A6 0xB08C # 0 +0x0000B3A7 0xB08D # 0 +0x0000B3A8 0xB08F # 0 +0x0000B3A9 0xB091 # 0 +0x0000B3AA 0xB098 # 0 +0x0000B3AB 0xB099 # 0 +0x0000B3AC 0xB09A # 0 +0x0000B3AD 0xB09C # 0 +0x0000B3AE 0xB09F # 0 +0x0000B3AF 0xB0A0 # 0 +0x0000B3B0 0xB0A1 # 0 +0x0000B3B1 0xB0A2 # 0 +0x0000B3B2 0xB0A8 # 0 +0x0000B3B3 0xB0A9 # 0 +0x0000B3B4 0xB0AB # 0 +0x0000B3B5 0xB0AC # 0 +0x0000B3B6 0xB0AD # 0 +0x0000B3B7 0xB0AE # 0 +0x0000B3B8 0xB0AF # 0 +0x0000B3B9 0xB0B1 # 0 +0x0000B3BA 0xB0B3 # 0 +0x0000B3BB 0xB0B4 # 0 +0x0000B3BC 0xB0B5 # 0 +0x0000B3BD 0xB0B8 # 0 +0x0000B3BE 0xB0BC # 0 +0x0000B3BF 0xB0C4 # 0 +0x0000B3C0 0xB0C5 # 0 +0x0000B3C1 0xB0C7 # 0 +0x0000B3C2 0xB0C8 # 0 +0x0000B3C3 0xB0C9 # 0 +0x0000B3C4 0xB0D0 # 0 +0x0000B3C5 0xB0D1 # 0 +0x0000B3C6 0xB0D4 # 0 +0x0000B3C7 0xB0D8 # 0 +0x0000B3C8 0xB0E0 # 0 +0x0000B3C9 0xB0E5 # 0 +0x0000B3CA 0xB108 # 0 +0x0000B3CB 0xB109 # 0 +0x0000B3CC 0xB10B # 0 +0x0000B3CD 0xB10C # 0 +0x0000B3CE 0xB110 # 0 +0x0000B3CF 0xB112 # 0 +0x0000B3D0 0xB113 # 0 +0x0000B3D1 0xB118 # 0 +0x0000B3D2 0xB119 # 0 +0x0000B3D3 0xB11B # 0 +0x0000B3D4 0xB11C # 0 +0x0000B3D5 0xB11D # 0 +0x0000B3D6 0xB123 # 0 +0x0000B3D7 0xB124 # 0 +0x0000B3D8 0xB125 # 0 +0x0000B3D9 0xB128 # 0 +0x0000B3DA 0xB12C # 0 +0x0000B3DB 0xB134 # 0 +0x0000B3DC 0xB135 # 0 +0x0000B3DD 0xB137 # 0 +0x0000B3DE 0xB138 # 0 +0x0000B3DF 0xB139 # 0 +0x0000B3E0 0xB140 # 0 +0x0000B3E1 0xB141 # 0 +0x0000B3E2 0xB144 # 0 +0x0000B3E3 0xB148 # 0 +0x0000B3E4 0xB150 # 0 +0x0000B3E5 0xB151 # 0 +0x0000B3E6 0xB154 # 0 +0x0000B3E7 0xB155 # 0 +0x0000B3E8 0xB158 # 0 +0x0000B3E9 0xB15C # 0 +0x0000B3EA 0xB160 # 0 +0x0000B3EB 0xB178 # 0 +0x0000B3EC 0xB179 # 0 +0x0000B3ED 0xB17C # 0 +0x0000B3EE 0xB180 # 0 +0x0000B3EF 0xB182 # 0 +0x0000B3F0 0xB188 # 0 +0x0000B3F1 0xB189 # 0 +0x0000B3F2 0xB18B # 0 +0x0000B3F3 0xB18D # 0 +0x0000B3F4 0xB192 # 0 +0x0000B3F5 0xB193 # 0 +0x0000B3F6 0xB194 # 0 +0x0000B3F7 0xB198 # 0 +0x0000B3F8 0xB19C # 0 +0x0000B3F9 0xB1A8 # 0 +0x0000B3FA 0xB1CC # 0 +0x0000B3FB 0xB1D0 # 0 +0x0000B3FC 0xB1D4 # 0 +0x0000B3FD 0xB1DC # 0 +0x0000B3FE 0xB1DD # 0 +0x0000B4A1 0xB1DF # 0 +0x0000B4A2 0xB1E8 # 0 +0x0000B4A3 0xB1E9 # 0 +0x0000B4A4 0xB1EC # 0 +0x0000B4A5 0xB1F0 # 0 +0x0000B4A6 0xB1F9 # 0 +0x0000B4A7 0xB1FB # 0 +0x0000B4A8 0xB1FD # 0 +0x0000B4A9 0xB204 # 0 +0x0000B4AA 0xB205 # 0 +0x0000B4AB 0xB208 # 0 +0x0000B4AC 0xB20B # 0 +0x0000B4AD 0xB20C # 0 +0x0000B4AE 0xB214 # 0 +0x0000B4AF 0xB215 # 0 +0x0000B4B0 0xB217 # 0 +0x0000B4B1 0xB219 # 0 +0x0000B4B2 0xB220 # 0 +0x0000B4B3 0xB234 # 0 +0x0000B4B4 0xB23C # 0 +0x0000B4B5 0xB258 # 0 +0x0000B4B6 0xB25C # 0 +0x0000B4B7 0xB260 # 0 +0x0000B4B8 0xB268 # 0 +0x0000B4B9 0xB269 # 0 +0x0000B4BA 0xB274 # 0 +0x0000B4BB 0xB275 # 0 +0x0000B4BC 0xB27C # 0 +0x0000B4BD 0xB284 # 0 +0x0000B4BE 0xB285 # 0 +0x0000B4BF 0xB289 # 0 +0x0000B4C0 0xB290 # 0 +0x0000B4C1 0xB291 # 0 +0x0000B4C2 0xB294 # 0 +0x0000B4C3 0xB298 # 0 +0x0000B4C4 0xB299 # 0 +0x0000B4C5 0xB29A # 0 +0x0000B4C6 0xB2A0 # 0 +0x0000B4C7 0xB2A1 # 0 +0x0000B4C8 0xB2A3 # 0 +0x0000B4C9 0xB2A5 # 0 +0x0000B4CA 0xB2A6 # 0 +0x0000B4CB 0xB2AA # 0 +0x0000B4CC 0xB2AC # 0 +0x0000B4CD 0xB2B0 # 0 +0x0000B4CE 0xB2B4 # 0 +0x0000B4CF 0xB2C8 # 0 +0x0000B4D0 0xB2C9 # 0 +0x0000B4D1 0xB2CC # 0 +0x0000B4D2 0xB2D0 # 0 +0x0000B4D3 0xB2D2 # 0 +0x0000B4D4 0xB2D8 # 0 +0x0000B4D5 0xB2D9 # 0 +0x0000B4D6 0xB2DB # 0 +0x0000B4D7 0xB2DD # 0 +0x0000B4D8 0xB2E2 # 0 +0x0000B4D9 0xB2E4 # 0 +0x0000B4DA 0xB2E5 # 0 +0x0000B4DB 0xB2E6 # 0 +0x0000B4DC 0xB2E8 # 0 +0x0000B4DD 0xB2EB # 0 +0x0000B4DE 0xB2EC # 0 +0x0000B4DF 0xB2ED # 0 +0x0000B4E0 0xB2EE # 0 +0x0000B4E1 0xB2EF # 0 +0x0000B4E2 0xB2F3 # 0 +0x0000B4E3 0xB2F4 # 0 +0x0000B4E4 0xB2F5 # 0 +0x0000B4E5 0xB2F7 # 0 +0x0000B4E6 0xB2F8 # 0 +0x0000B4E7 0xB2F9 # 0 +0x0000B4E8 0xB2FA # 0 +0x0000B4E9 0xB2FB # 0 +0x0000B4EA 0xB2FF # 0 +0x0000B4EB 0xB300 # 0 +0x0000B4EC 0xB301 # 0 +0x0000B4ED 0xB304 # 0 +0x0000B4EE 0xB308 # 0 +0x0000B4EF 0xB310 # 0 +0x0000B4F0 0xB311 # 0 +0x0000B4F1 0xB313 # 0 +0x0000B4F2 0xB314 # 0 +0x0000B4F3 0xB315 # 0 +0x0000B4F4 0xB31C # 0 +0x0000B4F5 0xB354 # 0 +0x0000B4F6 0xB355 # 0 +0x0000B4F7 0xB356 # 0 +0x0000B4F8 0xB358 # 0 +0x0000B4F9 0xB35B # 0 +0x0000B4FA 0xB35C # 0 +0x0000B4FB 0xB35E # 0 +0x0000B4FC 0xB35F # 0 +0x0000B4FD 0xB364 # 0 +0x0000B4FE 0xB365 # 0 +0x0000B5A1 0xB367 # 0 +0x0000B5A2 0xB369 # 0 +0x0000B5A3 0xB36B # 0 +0x0000B5A4 0xB36E # 0 +0x0000B5A5 0xB370 # 0 +0x0000B5A6 0xB371 # 0 +0x0000B5A7 0xB374 # 0 +0x0000B5A8 0xB378 # 0 +0x0000B5A9 0xB380 # 0 +0x0000B5AA 0xB381 # 0 +0x0000B5AB 0xB383 # 0 +0x0000B5AC 0xB384 # 0 +0x0000B5AD 0xB385 # 0 +0x0000B5AE 0xB38C # 0 +0x0000B5AF 0xB390 # 0 +0x0000B5B0 0xB394 # 0 +0x0000B5B1 0xB3A0 # 0 +0x0000B5B2 0xB3A1 # 0 +0x0000B5B3 0xB3A8 # 0 +0x0000B5B4 0xB3AC # 0 +0x0000B5B5 0xB3C4 # 0 +0x0000B5B6 0xB3C5 # 0 +0x0000B5B7 0xB3C8 # 0 +0x0000B5B8 0xB3CB # 0 +0x0000B5B9 0xB3CC # 0 +0x0000B5BA 0xB3CE # 0 +0x0000B5BB 0xB3D0 # 0 +0x0000B5BC 0xB3D4 # 0 +0x0000B5BD 0xB3D5 # 0 +0x0000B5BE 0xB3D7 # 0 +0x0000B5BF 0xB3D9 # 0 +0x0000B5C0 0xB3DB # 0 +0x0000B5C1 0xB3DD # 0 +0x0000B5C2 0xB3E0 # 0 +0x0000B5C3 0xB3E4 # 0 +0x0000B5C4 0xB3E8 # 0 +0x0000B5C5 0xB3FC # 0 +0x0000B5C6 0xB410 # 0 +0x0000B5C7 0xB418 # 0 +0x0000B5C8 0xB41C # 0 +0x0000B5C9 0xB420 # 0 +0x0000B5CA 0xB428 # 0 +0x0000B5CB 0xB429 # 0 +0x0000B5CC 0xB42B # 0 +0x0000B5CD 0xB434 # 0 +0x0000B5CE 0xB450 # 0 +0x0000B5CF 0xB451 # 0 +0x0000B5D0 0xB454 # 0 +0x0000B5D1 0xB458 # 0 +0x0000B5D2 0xB460 # 0 +0x0000B5D3 0xB461 # 0 +0x0000B5D4 0xB463 # 0 +0x0000B5D5 0xB465 # 0 +0x0000B5D6 0xB46C # 0 +0x0000B5D7 0xB480 # 0 +0x0000B5D8 0xB488 # 0 +0x0000B5D9 0xB49D # 0 +0x0000B5DA 0xB4A4 # 0 +0x0000B5DB 0xB4A8 # 0 +0x0000B5DC 0xB4AC # 0 +0x0000B5DD 0xB4B5 # 0 +0x0000B5DE 0xB4B7 # 0 +0x0000B5DF 0xB4B9 # 0 +0x0000B5E0 0xB4C0 # 0 +0x0000B5E1 0xB4C4 # 0 +0x0000B5E2 0xB4C8 # 0 +0x0000B5E3 0xB4D0 # 0 +0x0000B5E4 0xB4D5 # 0 +0x0000B5E5 0xB4DC # 0 +0x0000B5E6 0xB4DD # 0 +0x0000B5E7 0xB4E0 # 0 +0x0000B5E8 0xB4E3 # 0 +0x0000B5E9 0xB4E4 # 0 +0x0000B5EA 0xB4E6 # 0 +0x0000B5EB 0xB4EC # 0 +0x0000B5EC 0xB4ED # 0 +0x0000B5ED 0xB4EF # 0 +0x0000B5EE 0xB4F1 # 0 +0x0000B5EF 0xB4F8 # 0 +0x0000B5F0 0xB514 # 0 +0x0000B5F1 0xB515 # 0 +0x0000B5F2 0xB518 # 0 +0x0000B5F3 0xB51B # 0 +0x0000B5F4 0xB51C # 0 +0x0000B5F5 0xB524 # 0 +0x0000B5F6 0xB525 # 0 +0x0000B5F7 0xB527 # 0 +0x0000B5F8 0xB528 # 0 +0x0000B5F9 0xB529 # 0 +0x0000B5FA 0xB52A # 0 +0x0000B5FB 0xB530 # 0 +0x0000B5FC 0xB531 # 0 +0x0000B5FD 0xB534 # 0 +0x0000B5FE 0xB538 # 0 +0x0000B6A1 0xB540 # 0 +0x0000B6A2 0xB541 # 0 +0x0000B6A3 0xB543 # 0 +0x0000B6A4 0xB544 # 0 +0x0000B6A5 0xB545 # 0 +0x0000B6A6 0xB54B # 0 +0x0000B6A7 0xB54C # 0 +0x0000B6A8 0xB54D # 0 +0x0000B6A9 0xB550 # 0 +0x0000B6AA 0xB554 # 0 +0x0000B6AB 0xB55C # 0 +0x0000B6AC 0xB55D # 0 +0x0000B6AD 0xB55F # 0 +0x0000B6AE 0xB560 # 0 +0x0000B6AF 0xB561 # 0 +0x0000B6B0 0xB5A0 # 0 +0x0000B6B1 0xB5A1 # 0 +0x0000B6B2 0xB5A4 # 0 +0x0000B6B3 0xB5A8 # 0 +0x0000B6B4 0xB5AA # 0 +0x0000B6B5 0xB5AB # 0 +0x0000B6B6 0xB5B0 # 0 +0x0000B6B7 0xB5B1 # 0 +0x0000B6B8 0xB5B3 # 0 +0x0000B6B9 0xB5B4 # 0 +0x0000B6BA 0xB5B5 # 0 +0x0000B6BB 0xB5BB # 0 +0x0000B6BC 0xB5BC # 0 +0x0000B6BD 0xB5BD # 0 +0x0000B6BE 0xB5C0 # 0 +0x0000B6BF 0xB5C4 # 0 +0x0000B6C0 0xB5CC # 0 +0x0000B6C1 0xB5CD # 0 +0x0000B6C2 0xB5CF # 0 +0x0000B6C3 0xB5D0 # 0 +0x0000B6C4 0xB5D1 # 0 +0x0000B6C5 0xB5D8 # 0 +0x0000B6C6 0xB5EC # 0 +0x0000B6C7 0xB610 # 0 +0x0000B6C8 0xB611 # 0 +0x0000B6C9 0xB614 # 0 +0x0000B6CA 0xB618 # 0 +0x0000B6CB 0xB625 # 0 +0x0000B6CC 0xB62C # 0 +0x0000B6CD 0xB634 # 0 +0x0000B6CE 0xB648 # 0 +0x0000B6CF 0xB664 # 0 +0x0000B6D0 0xB668 # 0 +0x0000B6D1 0xB69C # 0 +0x0000B6D2 0xB69D # 0 +0x0000B6D3 0xB6A0 # 0 +0x0000B6D4 0xB6A4 # 0 +0x0000B6D5 0xB6AB # 0 +0x0000B6D6 0xB6AC # 0 +0x0000B6D7 0xB6B1 # 0 +0x0000B6D8 0xB6D4 # 0 +0x0000B6D9 0xB6F0 # 0 +0x0000B6DA 0xB6F4 # 0 +0x0000B6DB 0xB6F8 # 0 +0x0000B6DC 0xB700 # 0 +0x0000B6DD 0xB701 # 0 +0x0000B6DE 0xB705 # 0 +0x0000B6DF 0xB728 # 0 +0x0000B6E0 0xB729 # 0 +0x0000B6E1 0xB72C # 0 +0x0000B6E2 0xB72F # 0 +0x0000B6E3 0xB730 # 0 +0x0000B6E4 0xB738 # 0 +0x0000B6E5 0xB739 # 0 +0x0000B6E6 0xB73B # 0 +0x0000B6E7 0xB744 # 0 +0x0000B6E8 0xB748 # 0 +0x0000B6E9 0xB74C # 0 +0x0000B6EA 0xB754 # 0 +0x0000B6EB 0xB755 # 0 +0x0000B6EC 0xB760 # 0 +0x0000B6ED 0xB764 # 0 +0x0000B6EE 0xB768 # 0 +0x0000B6EF 0xB770 # 0 +0x0000B6F0 0xB771 # 0 +0x0000B6F1 0xB773 # 0 +0x0000B6F2 0xB775 # 0 +0x0000B6F3 0xB77C # 0 +0x0000B6F4 0xB77D # 0 +0x0000B6F5 0xB780 # 0 +0x0000B6F6 0xB784 # 0 +0x0000B6F7 0xB78C # 0 +0x0000B6F8 0xB78D # 0 +0x0000B6F9 0xB78F # 0 +0x0000B6FA 0xB790 # 0 +0x0000B6FB 0xB791 # 0 +0x0000B6FC 0xB792 # 0 +0x0000B6FD 0xB796 # 0 +0x0000B6FE 0xB797 # 0 +0x0000B7A1 0xB798 # 0 +0x0000B7A2 0xB799 # 0 +0x0000B7A3 0xB79C # 0 +0x0000B7A4 0xB7A0 # 0 +0x0000B7A5 0xB7A8 # 0 +0x0000B7A6 0xB7A9 # 0 +0x0000B7A7 0xB7AB # 0 +0x0000B7A8 0xB7AC # 0 +0x0000B7A9 0xB7AD # 0 +0x0000B7AA 0xB7B4 # 0 +0x0000B7AB 0xB7B5 # 0 +0x0000B7AC 0xB7B8 # 0 +0x0000B7AD 0xB7C7 # 0 +0x0000B7AE 0xB7C9 # 0 +0x0000B7AF 0xB7EC # 0 +0x0000B7B0 0xB7ED # 0 +0x0000B7B1 0xB7F0 # 0 +0x0000B7B2 0xB7F4 # 0 +0x0000B7B3 0xB7FC # 0 +0x0000B7B4 0xB7FD # 0 +0x0000B7B5 0xB7FF # 0 +0x0000B7B6 0xB800 # 0 +0x0000B7B7 0xB801 # 0 +0x0000B7B8 0xB807 # 0 +0x0000B7B9 0xB808 # 0 +0x0000B7BA 0xB809 # 0 +0x0000B7BB 0xB80C # 0 +0x0000B7BC 0xB810 # 0 +0x0000B7BD 0xB818 # 0 +0x0000B7BE 0xB819 # 0 +0x0000B7BF 0xB81B # 0 +0x0000B7C0 0xB81D # 0 +0x0000B7C1 0xB824 # 0 +0x0000B7C2 0xB825 # 0 +0x0000B7C3 0xB828 # 0 +0x0000B7C4 0xB82C # 0 +0x0000B7C5 0xB834 # 0 +0x0000B7C6 0xB835 # 0 +0x0000B7C7 0xB837 # 0 +0x0000B7C8 0xB838 # 0 +0x0000B7C9 0xB839 # 0 +0x0000B7CA 0xB840 # 0 +0x0000B7CB 0xB844 # 0 +0x0000B7CC 0xB851 # 0 +0x0000B7CD 0xB853 # 0 +0x0000B7CE 0xB85C # 0 +0x0000B7CF 0xB85D # 0 +0x0000B7D0 0xB860 # 0 +0x0000B7D1 0xB864 # 0 +0x0000B7D2 0xB86C # 0 +0x0000B7D3 0xB86D # 0 +0x0000B7D4 0xB86F # 0 +0x0000B7D5 0xB871 # 0 +0x0000B7D6 0xB878 # 0 +0x0000B7D7 0xB87C # 0 +0x0000B7D8 0xB88D # 0 +0x0000B7D9 0xB8A8 # 0 +0x0000B7DA 0xB8B0 # 0 +0x0000B7DB 0xB8B4 # 0 +0x0000B7DC 0xB8B8 # 0 +0x0000B7DD 0xB8C0 # 0 +0x0000B7DE 0xB8C1 # 0 +0x0000B7DF 0xB8C3 # 0 +0x0000B7E0 0xB8C5 # 0 +0x0000B7E1 0xB8CC # 0 +0x0000B7E2 0xB8D0 # 0 +0x0000B7E3 0xB8D4 # 0 +0x0000B7E4 0xB8DD # 0 +0x0000B7E5 0xB8DF # 0 +0x0000B7E6 0xB8E1 # 0 +0x0000B7E7 0xB8E8 # 0 +0x0000B7E8 0xB8E9 # 0 +0x0000B7E9 0xB8EC # 0 +0x0000B7EA 0xB8F0 # 0 +0x0000B7EB 0xB8F8 # 0 +0x0000B7EC 0xB8F9 # 0 +0x0000B7ED 0xB8FB # 0 +0x0000B7EE 0xB8FD # 0 +0x0000B7EF 0xB904 # 0 +0x0000B7F0 0xB918 # 0 +0x0000B7F1 0xB920 # 0 +0x0000B7F2 0xB93C # 0 +0x0000B7F3 0xB93D # 0 +0x0000B7F4 0xB940 # 0 +0x0000B7F5 0xB944 # 0 +0x0000B7F6 0xB94C # 0 +0x0000B7F7 0xB94F # 0 +0x0000B7F8 0xB951 # 0 +0x0000B7F9 0xB958 # 0 +0x0000B7FA 0xB959 # 0 +0x0000B7FB 0xB95C # 0 +0x0000B7FC 0xB960 # 0 +0x0000B7FD 0xB968 # 0 +0x0000B7FE 0xB969 # 0 +0x0000B8A1 0xB96B # 0 +0x0000B8A2 0xB96D # 0 +0x0000B8A3 0xB974 # 0 +0x0000B8A4 0xB975 # 0 +0x0000B8A5 0xB978 # 0 +0x0000B8A6 0xB97C # 0 +0x0000B8A7 0xB984 # 0 +0x0000B8A8 0xB985 # 0 +0x0000B8A9 0xB987 # 0 +0x0000B8AA 0xB989 # 0 +0x0000B8AB 0xB98A # 0 +0x0000B8AC 0xB98D # 0 +0x0000B8AD 0xB98E # 0 +0x0000B8AE 0xB9AC # 0 +0x0000B8AF 0xB9AD # 0 +0x0000B8B0 0xB9B0 # 0 +0x0000B8B1 0xB9B4 # 0 +0x0000B8B2 0xB9BC # 0 +0x0000B8B3 0xB9BD # 0 +0x0000B8B4 0xB9BF # 0 +0x0000B8B5 0xB9C1 # 0 +0x0000B8B6 0xB9C8 # 0 +0x0000B8B7 0xB9C9 # 0 +0x0000B8B8 0xB9CC # 0 +0x0000B8B9 0xB9CE # 0 +0x0000B8BA 0xB9CF # 0 +0x0000B8BB 0xB9D0 # 0 +0x0000B8BC 0xB9D1 # 0 +0x0000B8BD 0xB9D2 # 0 +0x0000B8BE 0xB9D8 # 0 +0x0000B8BF 0xB9D9 # 0 +0x0000B8C0 0xB9DB # 0 +0x0000B8C1 0xB9DD # 0 +0x0000B8C2 0xB9DE # 0 +0x0000B8C3 0xB9E1 # 0 +0x0000B8C4 0xB9E3 # 0 +0x0000B8C5 0xB9E4 # 0 +0x0000B8C6 0xB9E5 # 0 +0x0000B8C7 0xB9E8 # 0 +0x0000B8C8 0xB9EC # 0 +0x0000B8C9 0xB9F4 # 0 +0x0000B8CA 0xB9F5 # 0 +0x0000B8CB 0xB9F7 # 0 +0x0000B8CC 0xB9F8 # 0 +0x0000B8CD 0xB9F9 # 0 +0x0000B8CE 0xB9FA # 0 +0x0000B8CF 0xBA00 # 0 +0x0000B8D0 0xBA01 # 0 +0x0000B8D1 0xBA08 # 0 +0x0000B8D2 0xBA15 # 0 +0x0000B8D3 0xBA38 # 0 +0x0000B8D4 0xBA39 # 0 +0x0000B8D5 0xBA3C # 0 +0x0000B8D6 0xBA40 # 0 +0x0000B8D7 0xBA42 # 0 +0x0000B8D8 0xBA48 # 0 +0x0000B8D9 0xBA49 # 0 +0x0000B8DA 0xBA4B # 0 +0x0000B8DB 0xBA4D # 0 +0x0000B8DC 0xBA4E # 0 +0x0000B8DD 0xBA53 # 0 +0x0000B8DE 0xBA54 # 0 +0x0000B8DF 0xBA55 # 0 +0x0000B8E0 0xBA58 # 0 +0x0000B8E1 0xBA5C # 0 +0x0000B8E2 0xBA64 # 0 +0x0000B8E3 0xBA65 # 0 +0x0000B8E4 0xBA67 # 0 +0x0000B8E5 0xBA68 # 0 +0x0000B8E6 0xBA69 # 0 +0x0000B8E7 0xBA70 # 0 +0x0000B8E8 0xBA71 # 0 +0x0000B8E9 0xBA74 # 0 +0x0000B8EA 0xBA78 # 0 +0x0000B8EB 0xBA83 # 0 +0x0000B8EC 0xBA84 # 0 +0x0000B8ED 0xBA85 # 0 +0x0000B8EE 0xBA87 # 0 +0x0000B8EF 0xBA8C # 0 +0x0000B8F0 0xBAA8 # 0 +0x0000B8F1 0xBAA9 # 0 +0x0000B8F2 0xBAAB # 0 +0x0000B8F3 0xBAAC # 0 +0x0000B8F4 0xBAB0 # 0 +0x0000B8F5 0xBAB2 # 0 +0x0000B8F6 0xBAB8 # 0 +0x0000B8F7 0xBAB9 # 0 +0x0000B8F8 0xBABB # 0 +0x0000B8F9 0xBABD # 0 +0x0000B8FA 0xBAC4 # 0 +0x0000B8FB 0xBAC8 # 0 +0x0000B8FC 0xBAD8 # 0 +0x0000B8FD 0xBAD9 # 0 +0x0000B8FE 0xBAFC # 0 +0x0000B9A1 0xBB00 # 0 +0x0000B9A2 0xBB04 # 0 +0x0000B9A3 0xBB0D # 0 +0x0000B9A4 0xBB0F # 0 +0x0000B9A5 0xBB11 # 0 +0x0000B9A6 0xBB18 # 0 +0x0000B9A7 0xBB1C # 0 +0x0000B9A8 0xBB20 # 0 +0x0000B9A9 0xBB29 # 0 +0x0000B9AA 0xBB2B # 0 +0x0000B9AB 0xBB34 # 0 +0x0000B9AC 0xBB35 # 0 +0x0000B9AD 0xBB36 # 0 +0x0000B9AE 0xBB38 # 0 +0x0000B9AF 0xBB3B # 0 +0x0000B9B0 0xBB3C # 0 +0x0000B9B1 0xBB3D # 0 +0x0000B9B2 0xBB3E # 0 +0x0000B9B3 0xBB44 # 0 +0x0000B9B4 0xBB45 # 0 +0x0000B9B5 0xBB47 # 0 +0x0000B9B6 0xBB49 # 0 +0x0000B9B7 0xBB4D # 0 +0x0000B9B8 0xBB4F # 0 +0x0000B9B9 0xBB50 # 0 +0x0000B9BA 0xBB54 # 0 +0x0000B9BB 0xBB58 # 0 +0x0000B9BC 0xBB61 # 0 +0x0000B9BD 0xBB63 # 0 +0x0000B9BE 0xBB6C # 0 +0x0000B9BF 0xBB88 # 0 +0x0000B9C0 0xBB8C # 0 +0x0000B9C1 0xBB90 # 0 +0x0000B9C2 0xBBA4 # 0 +0x0000B9C3 0xBBA8 # 0 +0x0000B9C4 0xBBAC # 0 +0x0000B9C5 0xBBB4 # 0 +0x0000B9C6 0xBBB7 # 0 +0x0000B9C7 0xBBC0 # 0 +0x0000B9C8 0xBBC4 # 0 +0x0000B9C9 0xBBC8 # 0 +0x0000B9CA 0xBBD0 # 0 +0x0000B9CB 0xBBD3 # 0 +0x0000B9CC 0xBBF8 # 0 +0x0000B9CD 0xBBF9 # 0 +0x0000B9CE 0xBBFC # 0 +0x0000B9CF 0xBBFF # 0 +0x0000B9D0 0xBC00 # 0 +0x0000B9D1 0xBC02 # 0 +0x0000B9D2 0xBC08 # 0 +0x0000B9D3 0xBC09 # 0 +0x0000B9D4 0xBC0B # 0 +0x0000B9D5 0xBC0C # 0 +0x0000B9D6 0xBC0D # 0 +0x0000B9D7 0xBC0F # 0 +0x0000B9D8 0xBC11 # 0 +0x0000B9D9 0xBC14 # 0 +0x0000B9DA 0xBC15 # 0 +0x0000B9DB 0xBC16 # 0 +0x0000B9DC 0xBC17 # 0 +0x0000B9DD 0xBC18 # 0 +0x0000B9DE 0xBC1B # 0 +0x0000B9DF 0xBC1C # 0 +0x0000B9E0 0xBC1D # 0 +0x0000B9E1 0xBC1E # 0 +0x0000B9E2 0xBC1F # 0 +0x0000B9E3 0xBC24 # 0 +0x0000B9E4 0xBC25 # 0 +0x0000B9E5 0xBC27 # 0 +0x0000B9E6 0xBC29 # 0 +0x0000B9E7 0xBC2D # 0 +0x0000B9E8 0xBC30 # 0 +0x0000B9E9 0xBC31 # 0 +0x0000B9EA 0xBC34 # 0 +0x0000B9EB 0xBC38 # 0 +0x0000B9EC 0xBC40 # 0 +0x0000B9ED 0xBC41 # 0 +0x0000B9EE 0xBC43 # 0 +0x0000B9EF 0xBC44 # 0 +0x0000B9F0 0xBC45 # 0 +0x0000B9F1 0xBC49 # 0 +0x0000B9F2 0xBC4C # 0 +0x0000B9F3 0xBC4D # 0 +0x0000B9F4 0xBC50 # 0 +0x0000B9F5 0xBC5D # 0 +0x0000B9F6 0xBC84 # 0 +0x0000B9F7 0xBC85 # 0 +0x0000B9F8 0xBC88 # 0 +0x0000B9F9 0xBC8B # 0 +0x0000B9FA 0xBC8C # 0 +0x0000B9FB 0xBC8E # 0 +0x0000B9FC 0xBC94 # 0 +0x0000B9FD 0xBC95 # 0 +0x0000B9FE 0xBC97 # 0 +0x0000BAA1 0xBC99 # 0 +0x0000BAA2 0xBC9A # 0 +0x0000BAA3 0xBCA0 # 0 +0x0000BAA4 0xBCA1 # 0 +0x0000BAA5 0xBCA4 # 0 +0x0000BAA6 0xBCA7 # 0 +0x0000BAA7 0xBCA8 # 0 +0x0000BAA8 0xBCB0 # 0 +0x0000BAA9 0xBCB1 # 0 +0x0000BAAA 0xBCB3 # 0 +0x0000BAAB 0xBCB4 # 0 +0x0000BAAC 0xBCB5 # 0 +0x0000BAAD 0xBCBC # 0 +0x0000BAAE 0xBCBD # 0 +0x0000BAAF 0xBCC0 # 0 +0x0000BAB0 0xBCC4 # 0 +0x0000BAB1 0xBCCD # 0 +0x0000BAB2 0xBCCF # 0 +0x0000BAB3 0xBCD0 # 0 +0x0000BAB4 0xBCD1 # 0 +0x0000BAB5 0xBCD5 # 0 +0x0000BAB6 0xBCD8 # 0 +0x0000BAB7 0xBCDC # 0 +0x0000BAB8 0xBCF4 # 0 +0x0000BAB9 0xBCF5 # 0 +0x0000BABA 0xBCF6 # 0 +0x0000BABB 0xBCF8 # 0 +0x0000BABC 0xBCFC # 0 +0x0000BABD 0xBD04 # 0 +0x0000BABE 0xBD05 # 0 +0x0000BABF 0xBD07 # 0 +0x0000BAC0 0xBD09 # 0 +0x0000BAC1 0xBD10 # 0 +0x0000BAC2 0xBD14 # 0 +0x0000BAC3 0xBD24 # 0 +0x0000BAC4 0xBD2C # 0 +0x0000BAC5 0xBD40 # 0 +0x0000BAC6 0xBD48 # 0 +0x0000BAC7 0xBD49 # 0 +0x0000BAC8 0xBD4C # 0 +0x0000BAC9 0xBD50 # 0 +0x0000BACA 0xBD58 # 0 +0x0000BACB 0xBD59 # 0 +0x0000BACC 0xBD64 # 0 +0x0000BACD 0xBD68 # 0 +0x0000BACE 0xBD80 # 0 +0x0000BACF 0xBD81 # 0 +0x0000BAD0 0xBD84 # 0 +0x0000BAD1 0xBD87 # 0 +0x0000BAD2 0xBD88 # 0 +0x0000BAD3 0xBD89 # 0 +0x0000BAD4 0xBD8A # 0 +0x0000BAD5 0xBD90 # 0 +0x0000BAD6 0xBD91 # 0 +0x0000BAD7 0xBD93 # 0 +0x0000BAD8 0xBD95 # 0 +0x0000BAD9 0xBD99 # 0 +0x0000BADA 0xBD9A # 0 +0x0000BADB 0xBD9C # 0 +0x0000BADC 0xBDA4 # 0 +0x0000BADD 0xBDB0 # 0 +0x0000BADE 0xBDB8 # 0 +0x0000BADF 0xBDD4 # 0 +0x0000BAE0 0xBDD5 # 0 +0x0000BAE1 0xBDD8 # 0 +0x0000BAE2 0xBDDC # 0 +0x0000BAE3 0xBDE9 # 0 +0x0000BAE4 0xBDF0 # 0 +0x0000BAE5 0xBDF4 # 0 +0x0000BAE6 0xBDF8 # 0 +0x0000BAE7 0xBE00 # 0 +0x0000BAE8 0xBE03 # 0 +0x0000BAE9 0xBE05 # 0 +0x0000BAEA 0xBE0C # 0 +0x0000BAEB 0xBE0D # 0 +0x0000BAEC 0xBE10 # 0 +0x0000BAED 0xBE14 # 0 +0x0000BAEE 0xBE1C # 0 +0x0000BAEF 0xBE1D # 0 +0x0000BAF0 0xBE1F # 0 +0x0000BAF1 0xBE44 # 0 +0x0000BAF2 0xBE45 # 0 +0x0000BAF3 0xBE48 # 0 +0x0000BAF4 0xBE4C # 0 +0x0000BAF5 0xBE4E # 0 +0x0000BAF6 0xBE54 # 0 +0x0000BAF7 0xBE55 # 0 +0x0000BAF8 0xBE57 # 0 +0x0000BAF9 0xBE59 # 0 +0x0000BAFA 0xBE5A # 0 +0x0000BAFB 0xBE5B # 0 +0x0000BAFC 0xBE60 # 0 +0x0000BAFD 0xBE61 # 0 +0x0000BAFE 0xBE64 # 0 +0x0000BBA1 0xBE68 # 0 +0x0000BBA2 0xBE6A # 0 +0x0000BBA3 0xBE70 # 0 +0x0000BBA4 0xBE71 # 0 +0x0000BBA5 0xBE73 # 0 +0x0000BBA6 0xBE74 # 0 +0x0000BBA7 0xBE75 # 0 +0x0000BBA8 0xBE7B # 0 +0x0000BBA9 0xBE7C # 0 +0x0000BBAA 0xBE7D # 0 +0x0000BBAB 0xBE80 # 0 +0x0000BBAC 0xBE84 # 0 +0x0000BBAD 0xBE8C # 0 +0x0000BBAE 0xBE8D # 0 +0x0000BBAF 0xBE8F # 0 +0x0000BBB0 0xBE90 # 0 +0x0000BBB1 0xBE91 # 0 +0x0000BBB2 0xBE98 # 0 +0x0000BBB3 0xBE99 # 0 +0x0000BBB4 0xBEA8 # 0 +0x0000BBB5 0xBED0 # 0 +0x0000BBB6 0xBED1 # 0 +0x0000BBB7 0xBED4 # 0 +0x0000BBB8 0xBED7 # 0 +0x0000BBB9 0xBED8 # 0 +0x0000BBBA 0xBEE0 # 0 +0x0000BBBB 0xBEE3 # 0 +0x0000BBBC 0xBEE4 # 0 +0x0000BBBD 0xBEE5 # 0 +0x0000BBBE 0xBEEC # 0 +0x0000BBBF 0xBF01 # 0 +0x0000BBC0 0xBF08 # 0 +0x0000BBC1 0xBF09 # 0 +0x0000BBC2 0xBF18 # 0 +0x0000BBC3 0xBF19 # 0 +0x0000BBC4 0xBF1B # 0 +0x0000BBC5 0xBF1C # 0 +0x0000BBC6 0xBF1D # 0 +0x0000BBC7 0xBF40 # 0 +0x0000BBC8 0xBF41 # 0 +0x0000BBC9 0xBF44 # 0 +0x0000BBCA 0xBF48 # 0 +0x0000BBCB 0xBF50 # 0 +0x0000BBCC 0xBF51 # 0 +0x0000BBCD 0xBF55 # 0 +0x0000BBCE 0xBF94 # 0 +0x0000BBCF 0xBFB0 # 0 +0x0000BBD0 0xBFC5 # 0 +0x0000BBD1 0xBFCC # 0 +0x0000BBD2 0xBFCD # 0 +0x0000BBD3 0xBFD0 # 0 +0x0000BBD4 0xBFD4 # 0 +0x0000BBD5 0xBFDC # 0 +0x0000BBD6 0xBFDF # 0 +0x0000BBD7 0xBFE1 # 0 +0x0000BBD8 0xC03C # 0 +0x0000BBD9 0xC051 # 0 +0x0000BBDA 0xC058 # 0 +0x0000BBDB 0xC05C # 0 +0x0000BBDC 0xC060 # 0 +0x0000BBDD 0xC068 # 0 +0x0000BBDE 0xC069 # 0 +0x0000BBDF 0xC090 # 0 +0x0000BBE0 0xC091 # 0 +0x0000BBE1 0xC094 # 0 +0x0000BBE2 0xC098 # 0 +0x0000BBE3 0xC0A0 # 0 +0x0000BBE4 0xC0A1 # 0 +0x0000BBE5 0xC0A3 # 0 +0x0000BBE6 0xC0A5 # 0 +0x0000BBE7 0xC0AC # 0 +0x0000BBE8 0xC0AD # 0 +0x0000BBE9 0xC0AF # 0 +0x0000BBEA 0xC0B0 # 0 +0x0000BBEB 0xC0B3 # 0 +0x0000BBEC 0xC0B4 # 0 +0x0000BBED 0xC0B5 # 0 +0x0000BBEE 0xC0B6 # 0 +0x0000BBEF 0xC0BC # 0 +0x0000BBF0 0xC0BD # 0 +0x0000BBF1 0xC0BF # 0 +0x0000BBF2 0xC0C0 # 0 +0x0000BBF3 0xC0C1 # 0 +0x0000BBF4 0xC0C5 # 0 +0x0000BBF5 0xC0C8 # 0 +0x0000BBF6 0xC0C9 # 0 +0x0000BBF7 0xC0CC # 0 +0x0000BBF8 0xC0D0 # 0 +0x0000BBF9 0xC0D8 # 0 +0x0000BBFA 0xC0D9 # 0 +0x0000BBFB 0xC0DB # 0 +0x0000BBFC 0xC0DC # 0 +0x0000BBFD 0xC0DD # 0 +0x0000BBFE 0xC0E4 # 0 +0x0000BCA1 0xC0E5 # 0 +0x0000BCA2 0xC0E8 # 0 +0x0000BCA3 0xC0EC # 0 +0x0000BCA4 0xC0F4 # 0 +0x0000BCA5 0xC0F5 # 0 +0x0000BCA6 0xC0F7 # 0 +0x0000BCA7 0xC0F9 # 0 +0x0000BCA8 0xC100 # 0 +0x0000BCA9 0xC104 # 0 +0x0000BCAA 0xC108 # 0 +0x0000BCAB 0xC110 # 0 +0x0000BCAC 0xC115 # 0 +0x0000BCAD 0xC11C # 0 +0x0000BCAE 0xC11D # 0 +0x0000BCAF 0xC11E # 0 +0x0000BCB0 0xC11F # 0 +0x0000BCB1 0xC120 # 0 +0x0000BCB2 0xC123 # 0 +0x0000BCB3 0xC124 # 0 +0x0000BCB4 0xC126 # 0 +0x0000BCB5 0xC127 # 0 +0x0000BCB6 0xC12C # 0 +0x0000BCB7 0xC12D # 0 +0x0000BCB8 0xC12F # 0 +0x0000BCB9 0xC130 # 0 +0x0000BCBA 0xC131 # 0 +0x0000BCBB 0xC136 # 0 +0x0000BCBC 0xC138 # 0 +0x0000BCBD 0xC139 # 0 +0x0000BCBE 0xC13C # 0 +0x0000BCBF 0xC140 # 0 +0x0000BCC0 0xC148 # 0 +0x0000BCC1 0xC149 # 0 +0x0000BCC2 0xC14B # 0 +0x0000BCC3 0xC14C # 0 +0x0000BCC4 0xC14D # 0 +0x0000BCC5 0xC154 # 0 +0x0000BCC6 0xC155 # 0 +0x0000BCC7 0xC158 # 0 +0x0000BCC8 0xC15C # 0 +0x0000BCC9 0xC164 # 0 +0x0000BCCA 0xC165 # 0 +0x0000BCCB 0xC167 # 0 +0x0000BCCC 0xC168 # 0 +0x0000BCCD 0xC169 # 0 +0x0000BCCE 0xC170 # 0 +0x0000BCCF 0xC174 # 0 +0x0000BCD0 0xC178 # 0 +0x0000BCD1 0xC185 # 0 +0x0000BCD2 0xC18C # 0 +0x0000BCD3 0xC18D # 0 +0x0000BCD4 0xC18E # 0 +0x0000BCD5 0xC190 # 0 +0x0000BCD6 0xC194 # 0 +0x0000BCD7 0xC196 # 0 +0x0000BCD8 0xC19C # 0 +0x0000BCD9 0xC19D # 0 +0x0000BCDA 0xC19F # 0 +0x0000BCDB 0xC1A1 # 0 +0x0000BCDC 0xC1A5 # 0 +0x0000BCDD 0xC1A8 # 0 +0x0000BCDE 0xC1A9 # 0 +0x0000BCDF 0xC1AC # 0 +0x0000BCE0 0xC1B0 # 0 +0x0000BCE1 0xC1BD # 0 +0x0000BCE2 0xC1C4 # 0 +0x0000BCE3 0xC1C8 # 0 +0x0000BCE4 0xC1CC # 0 +0x0000BCE5 0xC1D4 # 0 +0x0000BCE6 0xC1D7 # 0 +0x0000BCE7 0xC1D8 # 0 +0x0000BCE8 0xC1E0 # 0 +0x0000BCE9 0xC1E4 # 0 +0x0000BCEA 0xC1E8 # 0 +0x0000BCEB 0xC1F0 # 0 +0x0000BCEC 0xC1F1 # 0 +0x0000BCED 0xC1F3 # 0 +0x0000BCEE 0xC1FC # 0 +0x0000BCEF 0xC1FD # 0 +0x0000BCF0 0xC200 # 0 +0x0000BCF1 0xC204 # 0 +0x0000BCF2 0xC20C # 0 +0x0000BCF3 0xC20D # 0 +0x0000BCF4 0xC20F # 0 +0x0000BCF5 0xC211 # 0 +0x0000BCF6 0xC218 # 0 +0x0000BCF7 0xC219 # 0 +0x0000BCF8 0xC21C # 0 +0x0000BCF9 0xC21F # 0 +0x0000BCFA 0xC220 # 0 +0x0000BCFB 0xC228 # 0 +0x0000BCFC 0xC229 # 0 +0x0000BCFD 0xC22B # 0 +0x0000BCFE 0xC22D # 0 +0x0000BDA1 0xC22F # 0 +0x0000BDA2 0xC231 # 0 +0x0000BDA3 0xC232 # 0 +0x0000BDA4 0xC234 # 0 +0x0000BDA5 0xC248 # 0 +0x0000BDA6 0xC250 # 0 +0x0000BDA7 0xC251 # 0 +0x0000BDA8 0xC254 # 0 +0x0000BDA9 0xC258 # 0 +0x0000BDAA 0xC260 # 0 +0x0000BDAB 0xC265 # 0 +0x0000BDAC 0xC26C # 0 +0x0000BDAD 0xC26D # 0 +0x0000BDAE 0xC270 # 0 +0x0000BDAF 0xC274 # 0 +0x0000BDB0 0xC27C # 0 +0x0000BDB1 0xC27D # 0 +0x0000BDB2 0xC27F # 0 +0x0000BDB3 0xC281 # 0 +0x0000BDB4 0xC288 # 0 +0x0000BDB5 0xC289 # 0 +0x0000BDB6 0xC290 # 0 +0x0000BDB7 0xC298 # 0 +0x0000BDB8 0xC29B # 0 +0x0000BDB9 0xC29D # 0 +0x0000BDBA 0xC2A4 # 0 +0x0000BDBB 0xC2A5 # 0 +0x0000BDBC 0xC2A8 # 0 +0x0000BDBD 0xC2AC # 0 +0x0000BDBE 0xC2AD # 0 +0x0000BDBF 0xC2B4 # 0 +0x0000BDC0 0xC2B5 # 0 +0x0000BDC1 0xC2B7 # 0 +0x0000BDC2 0xC2B9 # 0 +0x0000BDC3 0xC2DC # 0 +0x0000BDC4 0xC2DD # 0 +0x0000BDC5 0xC2E0 # 0 +0x0000BDC6 0xC2E3 # 0 +0x0000BDC7 0xC2E4 # 0 +0x0000BDC8 0xC2EB # 0 +0x0000BDC9 0xC2EC # 0 +0x0000BDCA 0xC2ED # 0 +0x0000BDCB 0xC2EF # 0 +0x0000BDCC 0xC2F1 # 0 +0x0000BDCD 0xC2F6 # 0 +0x0000BDCE 0xC2F8 # 0 +0x0000BDCF 0xC2F9 # 0 +0x0000BDD0 0xC2FB # 0 +0x0000BDD1 0xC2FC # 0 +0x0000BDD2 0xC300 # 0 +0x0000BDD3 0xC308 # 0 +0x0000BDD4 0xC309 # 0 +0x0000BDD5 0xC30C # 0 +0x0000BDD6 0xC30D # 0 +0x0000BDD7 0xC313 # 0 +0x0000BDD8 0xC314 # 0 +0x0000BDD9 0xC315 # 0 +0x0000BDDA 0xC318 # 0 +0x0000BDDB 0xC31C # 0 +0x0000BDDC 0xC324 # 0 +0x0000BDDD 0xC325 # 0 +0x0000BDDE 0xC328 # 0 +0x0000BDDF 0xC329 # 0 +0x0000BDE0 0xC345 # 0 +0x0000BDE1 0xC368 # 0 +0x0000BDE2 0xC369 # 0 +0x0000BDE3 0xC36C # 0 +0x0000BDE4 0xC370 # 0 +0x0000BDE5 0xC372 # 0 +0x0000BDE6 0xC378 # 0 +0x0000BDE7 0xC379 # 0 +0x0000BDE8 0xC37C # 0 +0x0000BDE9 0xC37D # 0 +0x0000BDEA 0xC384 # 0 +0x0000BDEB 0xC388 # 0 +0x0000BDEC 0xC38C # 0 +0x0000BDED 0xC3C0 # 0 +0x0000BDEE 0xC3D8 # 0 +0x0000BDEF 0xC3D9 # 0 +0x0000BDF0 0xC3DC # 0 +0x0000BDF1 0xC3DF # 0 +0x0000BDF2 0xC3E0 # 0 +0x0000BDF3 0xC3E2 # 0 +0x0000BDF4 0xC3E8 # 0 +0x0000BDF5 0xC3E9 # 0 +0x0000BDF6 0xC3ED # 0 +0x0000BDF7 0xC3F4 # 0 +0x0000BDF8 0xC3F5 # 0 +0x0000BDF9 0xC3F8 # 0 +0x0000BDFA 0xC408 # 0 +0x0000BDFB 0xC410 # 0 +0x0000BDFC 0xC424 # 0 +0x0000BDFD 0xC42C # 0 +0x0000BDFE 0xC430 # 0 +0x0000BEA1 0xC434 # 0 +0x0000BEA2 0xC43C # 0 +0x0000BEA3 0xC43D # 0 +0x0000BEA4 0xC448 # 0 +0x0000BEA5 0xC464 # 0 +0x0000BEA6 0xC465 # 0 +0x0000BEA7 0xC468 # 0 +0x0000BEA8 0xC46C # 0 +0x0000BEA9 0xC474 # 0 +0x0000BEAA 0xC475 # 0 +0x0000BEAB 0xC479 # 0 +0x0000BEAC 0xC480 # 0 +0x0000BEAD 0xC494 # 0 +0x0000BEAE 0xC49C # 0 +0x0000BEAF 0xC4B8 # 0 +0x0000BEB0 0xC4BC # 0 +0x0000BEB1 0xC4E9 # 0 +0x0000BEB2 0xC4F0 # 0 +0x0000BEB3 0xC4F1 # 0 +0x0000BEB4 0xC4F4 # 0 +0x0000BEB5 0xC4F8 # 0 +0x0000BEB6 0xC4FA # 0 +0x0000BEB7 0xC4FF # 0 +0x0000BEB8 0xC500 # 0 +0x0000BEB9 0xC501 # 0 +0x0000BEBA 0xC50C # 0 +0x0000BEBB 0xC510 # 0 +0x0000BEBC 0xC514 # 0 +0x0000BEBD 0xC51C # 0 +0x0000BEBE 0xC528 # 0 +0x0000BEBF 0xC529 # 0 +0x0000BEC0 0xC52C # 0 +0x0000BEC1 0xC530 # 0 +0x0000BEC2 0xC538 # 0 +0x0000BEC3 0xC539 # 0 +0x0000BEC4 0xC53B # 0 +0x0000BEC5 0xC53D # 0 +0x0000BEC6 0xC544 # 0 +0x0000BEC7 0xC545 # 0 +0x0000BEC8 0xC548 # 0 +0x0000BEC9 0xC549 # 0 +0x0000BECA 0xC54A # 0 +0x0000BECB 0xC54C # 0 +0x0000BECC 0xC54D # 0 +0x0000BECD 0xC54E # 0 +0x0000BECE 0xC553 # 0 +0x0000BECF 0xC554 # 0 +0x0000BED0 0xC555 # 0 +0x0000BED1 0xC557 # 0 +0x0000BED2 0xC558 # 0 +0x0000BED3 0xC559 # 0 +0x0000BED4 0xC55D # 0 +0x0000BED5 0xC55E # 0 +0x0000BED6 0xC560 # 0 +0x0000BED7 0xC561 # 0 +0x0000BED8 0xC564 # 0 +0x0000BED9 0xC568 # 0 +0x0000BEDA 0xC570 # 0 +0x0000BEDB 0xC571 # 0 +0x0000BEDC 0xC573 # 0 +0x0000BEDD 0xC574 # 0 +0x0000BEDE 0xC575 # 0 +0x0000BEDF 0xC57C # 0 +0x0000BEE0 0xC57D # 0 +0x0000BEE1 0xC580 # 0 +0x0000BEE2 0xC584 # 0 +0x0000BEE3 0xC587 # 0 +0x0000BEE4 0xC58C # 0 +0x0000BEE5 0xC58D # 0 +0x0000BEE6 0xC58F # 0 +0x0000BEE7 0xC591 # 0 +0x0000BEE8 0xC595 # 0 +0x0000BEE9 0xC597 # 0 +0x0000BEEA 0xC598 # 0 +0x0000BEEB 0xC59C # 0 +0x0000BEEC 0xC5A0 # 0 +0x0000BEED 0xC5A9 # 0 +0x0000BEEE 0xC5B4 # 0 +0x0000BEEF 0xC5B5 # 0 +0x0000BEF0 0xC5B8 # 0 +0x0000BEF1 0xC5B9 # 0 +0x0000BEF2 0xC5BB # 0 +0x0000BEF3 0xC5BC # 0 +0x0000BEF4 0xC5BD # 0 +0x0000BEF5 0xC5BE # 0 +0x0000BEF6 0xC5C4 # 0 +0x0000BEF7 0xC5C5 # 0 +0x0000BEF8 0xC5C6 # 0 +0x0000BEF9 0xC5C7 # 0 +0x0000BEFA 0xC5C8 # 0 +0x0000BEFB 0xC5C9 # 0 +0x0000BEFC 0xC5CA # 0 +0x0000BEFD 0xC5CC # 0 +0x0000BEFE 0xC5CE # 0 +0x0000BFA1 0xC5D0 # 0 +0x0000BFA2 0xC5D1 # 0 +0x0000BFA3 0xC5D4 # 0 +0x0000BFA4 0xC5D8 # 0 +0x0000BFA5 0xC5E0 # 0 +0x0000BFA6 0xC5E1 # 0 +0x0000BFA7 0xC5E3 # 0 +0x0000BFA8 0xC5E5 # 0 +0x0000BFA9 0xC5EC # 0 +0x0000BFAA 0xC5ED # 0 +0x0000BFAB 0xC5EE # 0 +0x0000BFAC 0xC5F0 # 0 +0x0000BFAD 0xC5F4 # 0 +0x0000BFAE 0xC5F6 # 0 +0x0000BFAF 0xC5F7 # 0 +0x0000BFB0 0xC5FC # 0 +0x0000BFB1 0xC5FD # 0 +0x0000BFB2 0xC5FE # 0 +0x0000BFB3 0xC5FF # 0 +0x0000BFB4 0xC600 # 0 +0x0000BFB5 0xC601 # 0 +0x0000BFB6 0xC605 # 0 +0x0000BFB7 0xC606 # 0 +0x0000BFB8 0xC607 # 0 +0x0000BFB9 0xC608 # 0 +0x0000BFBA 0xC60C # 0 +0x0000BFBB 0xC610 # 0 +0x0000BFBC 0xC618 # 0 +0x0000BFBD 0xC619 # 0 +0x0000BFBE 0xC61B # 0 +0x0000BFBF 0xC61C # 0 +0x0000BFC0 0xC624 # 0 +0x0000BFC1 0xC625 # 0 +0x0000BFC2 0xC628 # 0 +0x0000BFC3 0xC62C # 0 +0x0000BFC4 0xC62D # 0 +0x0000BFC5 0xC62E # 0 +0x0000BFC6 0xC630 # 0 +0x0000BFC7 0xC633 # 0 +0x0000BFC8 0xC634 # 0 +0x0000BFC9 0xC635 # 0 +0x0000BFCA 0xC637 # 0 +0x0000BFCB 0xC639 # 0 +0x0000BFCC 0xC63B # 0 +0x0000BFCD 0xC640 # 0 +0x0000BFCE 0xC641 # 0 +0x0000BFCF 0xC644 # 0 +0x0000BFD0 0xC648 # 0 +0x0000BFD1 0xC650 # 0 +0x0000BFD2 0xC651 # 0 +0x0000BFD3 0xC653 # 0 +0x0000BFD4 0xC654 # 0 +0x0000BFD5 0xC655 # 0 +0x0000BFD6 0xC65C # 0 +0x0000BFD7 0xC65D # 0 +0x0000BFD8 0xC660 # 0 +0x0000BFD9 0xC66C # 0 +0x0000BFDA 0xC66F # 0 +0x0000BFDB 0xC671 # 0 +0x0000BFDC 0xC678 # 0 +0x0000BFDD 0xC679 # 0 +0x0000BFDE 0xC67C # 0 +0x0000BFDF 0xC680 # 0 +0x0000BFE0 0xC688 # 0 +0x0000BFE1 0xC689 # 0 +0x0000BFE2 0xC68B # 0 +0x0000BFE3 0xC68D # 0 +0x0000BFE4 0xC694 # 0 +0x0000BFE5 0xC695 # 0 +0x0000BFE6 0xC698 # 0 +0x0000BFE7 0xC69C # 0 +0x0000BFE8 0xC6A4 # 0 +0x0000BFE9 0xC6A5 # 0 +0x0000BFEA 0xC6A7 # 0 +0x0000BFEB 0xC6A9 # 0 +0x0000BFEC 0xC6B0 # 0 +0x0000BFED 0xC6B1 # 0 +0x0000BFEE 0xC6B4 # 0 +0x0000BFEF 0xC6B8 # 0 +0x0000BFF0 0xC6B9 # 0 +0x0000BFF1 0xC6BA # 0 +0x0000BFF2 0xC6C0 # 0 +0x0000BFF3 0xC6C1 # 0 +0x0000BFF4 0xC6C3 # 0 +0x0000BFF5 0xC6C5 # 0 +0x0000BFF6 0xC6CC # 0 +0x0000BFF7 0xC6CD # 0 +0x0000BFF8 0xC6D0 # 0 +0x0000BFF9 0xC6D4 # 0 +0x0000BFFA 0xC6DC # 0 +0x0000BFFB 0xC6DD # 0 +0x0000BFFC 0xC6E0 # 0 +0x0000BFFD 0xC6E1 # 0 +0x0000BFFE 0xC6E8 # 0 +0x0000C0A1 0xC6E9 # 0 +0x0000C0A2 0xC6EC # 0 +0x0000C0A3 0xC6F0 # 0 +0x0000C0A4 0xC6F8 # 0 +0x0000C0A5 0xC6F9 # 0 +0x0000C0A6 0xC6FD # 0 +0x0000C0A7 0xC704 # 0 +0x0000C0A8 0xC705 # 0 +0x0000C0A9 0xC708 # 0 +0x0000C0AA 0xC70C # 0 +0x0000C0AB 0xC714 # 0 +0x0000C0AC 0xC715 # 0 +0x0000C0AD 0xC717 # 0 +0x0000C0AE 0xC719 # 0 +0x0000C0AF 0xC720 # 0 +0x0000C0B0 0xC721 # 0 +0x0000C0B1 0xC724 # 0 +0x0000C0B2 0xC728 # 0 +0x0000C0B3 0xC730 # 0 +0x0000C0B4 0xC731 # 0 +0x0000C0B5 0xC733 # 0 +0x0000C0B6 0xC735 # 0 +0x0000C0B7 0xC737 # 0 +0x0000C0B8 0xC73C # 0 +0x0000C0B9 0xC73D # 0 +0x0000C0BA 0xC740 # 0 +0x0000C0BB 0xC744 # 0 +0x0000C0BC 0xC74A # 0 +0x0000C0BD 0xC74C # 0 +0x0000C0BE 0xC74D # 0 +0x0000C0BF 0xC74F # 0 +0x0000C0C0 0xC751 # 0 +0x0000C0C1 0xC752 # 0 +0x0000C0C2 0xC753 # 0 +0x0000C0C3 0xC754 # 0 +0x0000C0C4 0xC755 # 0 +0x0000C0C5 0xC756 # 0 +0x0000C0C6 0xC757 # 0 +0x0000C0C7 0xC758 # 0 +0x0000C0C8 0xC75C # 0 +0x0000C0C9 0xC760 # 0 +0x0000C0CA 0xC768 # 0 +0x0000C0CB 0xC76B # 0 +0x0000C0CC 0xC774 # 0 +0x0000C0CD 0xC775 # 0 +0x0000C0CE 0xC778 # 0 +0x0000C0CF 0xC77C # 0 +0x0000C0D0 0xC77D # 0 +0x0000C0D1 0xC77E # 0 +0x0000C0D2 0xC783 # 0 +0x0000C0D3 0xC784 # 0 +0x0000C0D4 0xC785 # 0 +0x0000C0D5 0xC787 # 0 +0x0000C0D6 0xC788 # 0 +0x0000C0D7 0xC789 # 0 +0x0000C0D8 0xC78A # 0 +0x0000C0D9 0xC78E # 0 +0x0000C0DA 0xC790 # 0 +0x0000C0DB 0xC791 # 0 +0x0000C0DC 0xC794 # 0 +0x0000C0DD 0xC796 # 0 +0x0000C0DE 0xC797 # 0 +0x0000C0DF 0xC798 # 0 +0x0000C0E0 0xC79A # 0 +0x0000C0E1 0xC7A0 # 0 +0x0000C0E2 0xC7A1 # 0 +0x0000C0E3 0xC7A3 # 0 +0x0000C0E4 0xC7A4 # 0 +0x0000C0E5 0xC7A5 # 0 +0x0000C0E6 0xC7A6 # 0 +0x0000C0E7 0xC7AC # 0 +0x0000C0E8 0xC7AD # 0 +0x0000C0E9 0xC7B0 # 0 +0x0000C0EA 0xC7B4 # 0 +0x0000C0EB 0xC7BC # 0 +0x0000C0EC 0xC7BD # 0 +0x0000C0ED 0xC7BF # 0 +0x0000C0EE 0xC7C0 # 0 +0x0000C0EF 0xC7C1 # 0 +0x0000C0F0 0xC7C8 # 0 +0x0000C0F1 0xC7C9 # 0 +0x0000C0F2 0xC7CC # 0 +0x0000C0F3 0xC7CE # 0 +0x0000C0F4 0xC7D0 # 0 +0x0000C0F5 0xC7D8 # 0 +0x0000C0F6 0xC7DD # 0 +0x0000C0F7 0xC7E4 # 0 +0x0000C0F8 0xC7E8 # 0 +0x0000C0F9 0xC7EC # 0 +0x0000C0FA 0xC800 # 0 +0x0000C0FB 0xC801 # 0 +0x0000C0FC 0xC804 # 0 +0x0000C0FD 0xC808 # 0 +0x0000C0FE 0xC80A # 0 +0x0000C1A1 0xC810 # 0 +0x0000C1A2 0xC811 # 0 +0x0000C1A3 0xC813 # 0 +0x0000C1A4 0xC815 # 0 +0x0000C1A5 0xC816 # 0 +0x0000C1A6 0xC81C # 0 +0x0000C1A7 0xC81D # 0 +0x0000C1A8 0xC820 # 0 +0x0000C1A9 0xC824 # 0 +0x0000C1AA 0xC82C # 0 +0x0000C1AB 0xC82D # 0 +0x0000C1AC 0xC82F # 0 +0x0000C1AD 0xC831 # 0 +0x0000C1AE 0xC838 # 0 +0x0000C1AF 0xC83C # 0 +0x0000C1B0 0xC840 # 0 +0x0000C1B1 0xC848 # 0 +0x0000C1B2 0xC849 # 0 +0x0000C1B3 0xC84C # 0 +0x0000C1B4 0xC84D # 0 +0x0000C1B5 0xC854 # 0 +0x0000C1B6 0xC870 # 0 +0x0000C1B7 0xC871 # 0 +0x0000C1B8 0xC874 # 0 +0x0000C1B9 0xC878 # 0 +0x0000C1BA 0xC87A # 0 +0x0000C1BB 0xC880 # 0 +0x0000C1BC 0xC881 # 0 +0x0000C1BD 0xC883 # 0 +0x0000C1BE 0xC885 # 0 +0x0000C1BF 0xC886 # 0 +0x0000C1C0 0xC887 # 0 +0x0000C1C1 0xC88B # 0 +0x0000C1C2 0xC88C # 0 +0x0000C1C3 0xC88D # 0 +0x0000C1C4 0xC894 # 0 +0x0000C1C5 0xC89D # 0 +0x0000C1C6 0xC89F # 0 +0x0000C1C7 0xC8A1 # 0 +0x0000C1C8 0xC8A8 # 0 +0x0000C1C9 0xC8BC # 0 +0x0000C1CA 0xC8BD # 0 +0x0000C1CB 0xC8C4 # 0 +0x0000C1CC 0xC8C8 # 0 +0x0000C1CD 0xC8CC # 0 +0x0000C1CE 0xC8D4 # 0 +0x0000C1CF 0xC8D5 # 0 +0x0000C1D0 0xC8D7 # 0 +0x0000C1D1 0xC8D9 # 0 +0x0000C1D2 0xC8E0 # 0 +0x0000C1D3 0xC8E1 # 0 +0x0000C1D4 0xC8E4 # 0 +0x0000C1D5 0xC8F5 # 0 +0x0000C1D6 0xC8FC # 0 +0x0000C1D7 0xC8FD # 0 +0x0000C1D8 0xC900 # 0 +0x0000C1D9 0xC904 # 0 +0x0000C1DA 0xC905 # 0 +0x0000C1DB 0xC906 # 0 +0x0000C1DC 0xC90C # 0 +0x0000C1DD 0xC90D # 0 +0x0000C1DE 0xC90F # 0 +0x0000C1DF 0xC911 # 0 +0x0000C1E0 0xC918 # 0 +0x0000C1E1 0xC92C # 0 +0x0000C1E2 0xC934 # 0 +0x0000C1E3 0xC950 # 0 +0x0000C1E4 0xC951 # 0 +0x0000C1E5 0xC954 # 0 +0x0000C1E6 0xC958 # 0 +0x0000C1E7 0xC960 # 0 +0x0000C1E8 0xC961 # 0 +0x0000C1E9 0xC963 # 0 +0x0000C1EA 0xC96C # 0 +0x0000C1EB 0xC970 # 0 +0x0000C1EC 0xC974 # 0 +0x0000C1ED 0xC97C # 0 +0x0000C1EE 0xC988 # 0 +0x0000C1EF 0xC989 # 0 +0x0000C1F0 0xC98C # 0 +0x0000C1F1 0xC990 # 0 +0x0000C1F2 0xC998 # 0 +0x0000C1F3 0xC999 # 0 +0x0000C1F4 0xC99B # 0 +0x0000C1F5 0xC99D # 0 +0x0000C1F6 0xC9C0 # 0 +0x0000C1F7 0xC9C1 # 0 +0x0000C1F8 0xC9C4 # 0 +0x0000C1F9 0xC9C7 # 0 +0x0000C1FA 0xC9C8 # 0 +0x0000C1FB 0xC9CA # 0 +0x0000C1FC 0xC9D0 # 0 +0x0000C1FD 0xC9D1 # 0 +0x0000C1FE 0xC9D3 # 0 +0x0000C2A1 0xC9D5 # 0 +0x0000C2A2 0xC9D6 # 0 +0x0000C2A3 0xC9D9 # 0 +0x0000C2A4 0xC9DA # 0 +0x0000C2A5 0xC9DC # 0 +0x0000C2A6 0xC9DD # 0 +0x0000C2A7 0xC9E0 # 0 +0x0000C2A8 0xC9E2 # 0 +0x0000C2A9 0xC9E4 # 0 +0x0000C2AA 0xC9E7 # 0 +0x0000C2AB 0xC9EC # 0 +0x0000C2AC 0xC9ED # 0 +0x0000C2AD 0xC9EF # 0 +0x0000C2AE 0xC9F0 # 0 +0x0000C2AF 0xC9F1 # 0 +0x0000C2B0 0xC9F8 # 0 +0x0000C2B1 0xC9F9 # 0 +0x0000C2B2 0xC9FC # 0 +0x0000C2B3 0xCA00 # 0 +0x0000C2B4 0xCA08 # 0 +0x0000C2B5 0xCA09 # 0 +0x0000C2B6 0xCA0B # 0 +0x0000C2B7 0xCA0C # 0 +0x0000C2B8 0xCA0D # 0 +0x0000C2B9 0xCA14 # 0 +0x0000C2BA 0xCA18 # 0 +0x0000C2BB 0xCA29 # 0 +0x0000C2BC 0xCA4C # 0 +0x0000C2BD 0xCA4D # 0 +0x0000C2BE 0xCA50 # 0 +0x0000C2BF 0xCA54 # 0 +0x0000C2C0 0xCA5C # 0 +0x0000C2C1 0xCA5D # 0 +0x0000C2C2 0xCA5F # 0 +0x0000C2C3 0xCA60 # 0 +0x0000C2C4 0xCA61 # 0 +0x0000C2C5 0xCA68 # 0 +0x0000C2C6 0xCA7D # 0 +0x0000C2C7 0xCA84 # 0 +0x0000C2C8 0xCA98 # 0 +0x0000C2C9 0xCABC # 0 +0x0000C2CA 0xCABD # 0 +0x0000C2CB 0xCAC0 # 0 +0x0000C2CC 0xCAC4 # 0 +0x0000C2CD 0xCACC # 0 +0x0000C2CE 0xCACD # 0 +0x0000C2CF 0xCACF # 0 +0x0000C2D0 0xCAD1 # 0 +0x0000C2D1 0xCAD3 # 0 +0x0000C2D2 0xCAD8 # 0 +0x0000C2D3 0xCAD9 # 0 +0x0000C2D4 0xCAE0 # 0 +0x0000C2D5 0xCAEC # 0 +0x0000C2D6 0xCAF4 # 0 +0x0000C2D7 0xCB08 # 0 +0x0000C2D8 0xCB10 # 0 +0x0000C2D9 0xCB14 # 0 +0x0000C2DA 0xCB18 # 0 +0x0000C2DB 0xCB20 # 0 +0x0000C2DC 0xCB21 # 0 +0x0000C2DD 0xCB41 # 0 +0x0000C2DE 0xCB48 # 0 +0x0000C2DF 0xCB49 # 0 +0x0000C2E0 0xCB4C # 0 +0x0000C2E1 0xCB50 # 0 +0x0000C2E2 0xCB58 # 0 +0x0000C2E3 0xCB59 # 0 +0x0000C2E4 0xCB5D # 0 +0x0000C2E5 0xCB64 # 0 +0x0000C2E6 0xCB78 # 0 +0x0000C2E7 0xCB79 # 0 +0x0000C2E8 0xCB9C # 0 +0x0000C2E9 0xCBB8 # 0 +0x0000C2EA 0xCBD4 # 0 +0x0000C2EB 0xCBE4 # 0 +0x0000C2EC 0xCBE7 # 0 +0x0000C2ED 0xCBE9 # 0 +0x0000C2EE 0xCC0C # 0 +0x0000C2EF 0xCC0D # 0 +0x0000C2F0 0xCC10 # 0 +0x0000C2F1 0xCC14 # 0 +0x0000C2F2 0xCC1C # 0 +0x0000C2F3 0xCC1D # 0 +0x0000C2F4 0xCC21 # 0 +0x0000C2F5 0xCC22 # 0 +0x0000C2F6 0xCC27 # 0 +0x0000C2F7 0xCC28 # 0 +0x0000C2F8 0xCC29 # 0 +0x0000C2F9 0xCC2C # 0 +0x0000C2FA 0xCC2E # 0 +0x0000C2FB 0xCC30 # 0 +0x0000C2FC 0xCC38 # 0 +0x0000C2FD 0xCC39 # 0 +0x0000C2FE 0xCC3B # 0 +0x0000C3A1 0xCC3C # 0 +0x0000C3A2 0xCC3D # 0 +0x0000C3A3 0xCC3E # 0 +0x0000C3A4 0xCC44 # 0 +0x0000C3A5 0xCC45 # 0 +0x0000C3A6 0xCC48 # 0 +0x0000C3A7 0xCC4C # 0 +0x0000C3A8 0xCC54 # 0 +0x0000C3A9 0xCC55 # 0 +0x0000C3AA 0xCC57 # 0 +0x0000C3AB 0xCC58 # 0 +0x0000C3AC 0xCC59 # 0 +0x0000C3AD 0xCC60 # 0 +0x0000C3AE 0xCC64 # 0 +0x0000C3AF 0xCC66 # 0 +0x0000C3B0 0xCC68 # 0 +0x0000C3B1 0xCC70 # 0 +0x0000C3B2 0xCC75 # 0 +0x0000C3B3 0xCC98 # 0 +0x0000C3B4 0xCC99 # 0 +0x0000C3B5 0xCC9C # 0 +0x0000C3B6 0xCCA0 # 0 +0x0000C3B7 0xCCA8 # 0 +0x0000C3B8 0xCCA9 # 0 +0x0000C3B9 0xCCAB # 0 +0x0000C3BA 0xCCAC # 0 +0x0000C3BB 0xCCAD # 0 +0x0000C3BC 0xCCB4 # 0 +0x0000C3BD 0xCCB5 # 0 +0x0000C3BE 0xCCB8 # 0 +0x0000C3BF 0xCCBC # 0 +0x0000C3C0 0xCCC4 # 0 +0x0000C3C1 0xCCC5 # 0 +0x0000C3C2 0xCCC7 # 0 +0x0000C3C3 0xCCC9 # 0 +0x0000C3C4 0xCCD0 # 0 +0x0000C3C5 0xCCD4 # 0 +0x0000C3C6 0xCCE4 # 0 +0x0000C3C7 0xCCEC # 0 +0x0000C3C8 0xCCF0 # 0 +0x0000C3C9 0xCD01 # 0 +0x0000C3CA 0xCD08 # 0 +0x0000C3CB 0xCD09 # 0 +0x0000C3CC 0xCD0C # 0 +0x0000C3CD 0xCD10 # 0 +0x0000C3CE 0xCD18 # 0 +0x0000C3CF 0xCD19 # 0 +0x0000C3D0 0xCD1B # 0 +0x0000C3D1 0xCD1D # 0 +0x0000C3D2 0xCD24 # 0 +0x0000C3D3 0xCD28 # 0 +0x0000C3D4 0xCD2C # 0 +0x0000C3D5 0xCD39 # 0 +0x0000C3D6 0xCD5C # 0 +0x0000C3D7 0xCD60 # 0 +0x0000C3D8 0xCD64 # 0 +0x0000C3D9 0xCD6C # 0 +0x0000C3DA 0xCD6D # 0 +0x0000C3DB 0xCD6F # 0 +0x0000C3DC 0xCD71 # 0 +0x0000C3DD 0xCD78 # 0 +0x0000C3DE 0xCD88 # 0 +0x0000C3DF 0xCD94 # 0 +0x0000C3E0 0xCD95 # 0 +0x0000C3E1 0xCD98 # 0 +0x0000C3E2 0xCD9C # 0 +0x0000C3E3 0xCDA4 # 0 +0x0000C3E4 0xCDA5 # 0 +0x0000C3E5 0xCDA7 # 0 +0x0000C3E6 0xCDA9 # 0 +0x0000C3E7 0xCDB0 # 0 +0x0000C3E8 0xCDC4 # 0 +0x0000C3E9 0xCDCC # 0 +0x0000C3EA 0xCDD0 # 0 +0x0000C3EB 0xCDE8 # 0 +0x0000C3EC 0xCDEC # 0 +0x0000C3ED 0xCDF0 # 0 +0x0000C3EE 0xCDF8 # 0 +0x0000C3EF 0xCDF9 # 0 +0x0000C3F0 0xCDFB # 0 +0x0000C3F1 0xCDFD # 0 +0x0000C3F2 0xCE04 # 0 +0x0000C3F3 0xCE08 # 0 +0x0000C3F4 0xCE0C # 0 +0x0000C3F5 0xCE14 # 0 +0x0000C3F6 0xCE19 # 0 +0x0000C3F7 0xCE20 # 0 +0x0000C3F8 0xCE21 # 0 +0x0000C3F9 0xCE24 # 0 +0x0000C3FA 0xCE28 # 0 +0x0000C3FB 0xCE30 # 0 +0x0000C3FC 0xCE31 # 0 +0x0000C3FD 0xCE33 # 0 +0x0000C3FE 0xCE35 # 0 +0x0000C4A1 0xCE58 # 0 +0x0000C4A2 0xCE59 # 0 +0x0000C4A3 0xCE5C # 0 +0x0000C4A4 0xCE5F # 0 +0x0000C4A5 0xCE60 # 0 +0x0000C4A6 0xCE61 # 0 +0x0000C4A7 0xCE68 # 0 +0x0000C4A8 0xCE69 # 0 +0x0000C4A9 0xCE6B # 0 +0x0000C4AA 0xCE6D # 0 +0x0000C4AB 0xCE74 # 0 +0x0000C4AC 0xCE75 # 0 +0x0000C4AD 0xCE78 # 0 +0x0000C4AE 0xCE7C # 0 +0x0000C4AF 0xCE84 # 0 +0x0000C4B0 0xCE85 # 0 +0x0000C4B1 0xCE87 # 0 +0x0000C4B2 0xCE89 # 0 +0x0000C4B3 0xCE90 # 0 +0x0000C4B4 0xCE91 # 0 +0x0000C4B5 0xCE94 # 0 +0x0000C4B6 0xCE98 # 0 +0x0000C4B7 0xCEA0 # 0 +0x0000C4B8 0xCEA1 # 0 +0x0000C4B9 0xCEA3 # 0 +0x0000C4BA 0xCEA4 # 0 +0x0000C4BB 0xCEA5 # 0 +0x0000C4BC 0xCEAC # 0 +0x0000C4BD 0xCEAD # 0 +0x0000C4BE 0xCEC1 # 0 +0x0000C4BF 0xCEE4 # 0 +0x0000C4C0 0xCEE5 # 0 +0x0000C4C1 0xCEE8 # 0 +0x0000C4C2 0xCEEB # 0 +0x0000C4C3 0xCEEC # 0 +0x0000C4C4 0xCEF4 # 0 +0x0000C4C5 0xCEF5 # 0 +0x0000C4C6 0xCEF7 # 0 +0x0000C4C7 0xCEF8 # 0 +0x0000C4C8 0xCEF9 # 0 +0x0000C4C9 0xCF00 # 0 +0x0000C4CA 0xCF01 # 0 +0x0000C4CB 0xCF04 # 0 +0x0000C4CC 0xCF08 # 0 +0x0000C4CD 0xCF10 # 0 +0x0000C4CE 0xCF11 # 0 +0x0000C4CF 0xCF13 # 0 +0x0000C4D0 0xCF15 # 0 +0x0000C4D1 0xCF1C # 0 +0x0000C4D2 0xCF20 # 0 +0x0000C4D3 0xCF24 # 0 +0x0000C4D4 0xCF2C # 0 +0x0000C4D5 0xCF2D # 0 +0x0000C4D6 0xCF2F # 0 +0x0000C4D7 0xCF30 # 0 +0x0000C4D8 0xCF31 # 0 +0x0000C4D9 0xCF38 # 0 +0x0000C4DA 0xCF54 # 0 +0x0000C4DB 0xCF55 # 0 +0x0000C4DC 0xCF58 # 0 +0x0000C4DD 0xCF5C # 0 +0x0000C4DE 0xCF64 # 0 +0x0000C4DF 0xCF65 # 0 +0x0000C4E0 0xCF67 # 0 +0x0000C4E1 0xCF69 # 0 +0x0000C4E2 0xCF70 # 0 +0x0000C4E3 0xCF71 # 0 +0x0000C4E4 0xCF74 # 0 +0x0000C4E5 0xCF78 # 0 +0x0000C4E6 0xCF80 # 0 +0x0000C4E7 0xCF85 # 0 +0x0000C4E8 0xCF8C # 0 +0x0000C4E9 0xCFA1 # 0 +0x0000C4EA 0xCFA8 # 0 +0x0000C4EB 0xCFB0 # 0 +0x0000C4EC 0xCFC4 # 0 +0x0000C4ED 0xCFE0 # 0 +0x0000C4EE 0xCFE1 # 0 +0x0000C4EF 0xCFE4 # 0 +0x0000C4F0 0xCFE8 # 0 +0x0000C4F1 0xCFF0 # 0 +0x0000C4F2 0xCFF1 # 0 +0x0000C4F3 0xCFF3 # 0 +0x0000C4F4 0xCFF5 # 0 +0x0000C4F5 0xCFFC # 0 +0x0000C4F6 0xD000 # 0 +0x0000C4F7 0xD004 # 0 +0x0000C4F8 0xD011 # 0 +0x0000C4F9 0xD018 # 0 +0x0000C4FA 0xD02D # 0 +0x0000C4FB 0xD034 # 0 +0x0000C4FC 0xD035 # 0 +0x0000C4FD 0xD038 # 0 +0x0000C4FE 0xD03C # 0 +0x0000C5A1 0xD044 # 0 +0x0000C5A2 0xD045 # 0 +0x0000C5A3 0xD047 # 0 +0x0000C5A4 0xD049 # 0 +0x0000C5A5 0xD050 # 0 +0x0000C5A6 0xD054 # 0 +0x0000C5A7 0xD058 # 0 +0x0000C5A8 0xD060 # 0 +0x0000C5A9 0xD06C # 0 +0x0000C5AA 0xD06D # 0 +0x0000C5AB 0xD070 # 0 +0x0000C5AC 0xD074 # 0 +0x0000C5AD 0xD07C # 0 +0x0000C5AE 0xD07D # 0 +0x0000C5AF 0xD081 # 0 +0x0000C5B0 0xD0A4 # 0 +0x0000C5B1 0xD0A5 # 0 +0x0000C5B2 0xD0A8 # 0 +0x0000C5B3 0xD0AC # 0 +0x0000C5B4 0xD0B4 # 0 +0x0000C5B5 0xD0B5 # 0 +0x0000C5B6 0xD0B7 # 0 +0x0000C5B7 0xD0B9 # 0 +0x0000C5B8 0xD0C0 # 0 +0x0000C5B9 0xD0C1 # 0 +0x0000C5BA 0xD0C4 # 0 +0x0000C5BB 0xD0C8 # 0 +0x0000C5BC 0xD0C9 # 0 +0x0000C5BD 0xD0D0 # 0 +0x0000C5BE 0xD0D1 # 0 +0x0000C5BF 0xD0D3 # 0 +0x0000C5C0 0xD0D4 # 0 +0x0000C5C1 0xD0D5 # 0 +0x0000C5C2 0xD0DC # 0 +0x0000C5C3 0xD0DD # 0 +0x0000C5C4 0xD0E0 # 0 +0x0000C5C5 0xD0E4 # 0 +0x0000C5C6 0xD0EC # 0 +0x0000C5C7 0xD0ED # 0 +0x0000C5C8 0xD0EF # 0 +0x0000C5C9 0xD0F0 # 0 +0x0000C5CA 0xD0F1 # 0 +0x0000C5CB 0xD0F8 # 0 +0x0000C5CC 0xD10D # 0 +0x0000C5CD 0xD130 # 0 +0x0000C5CE 0xD131 # 0 +0x0000C5CF 0xD134 # 0 +0x0000C5D0 0xD138 # 0 +0x0000C5D1 0xD13A # 0 +0x0000C5D2 0xD140 # 0 +0x0000C5D3 0xD141 # 0 +0x0000C5D4 0xD143 # 0 +0x0000C5D5 0xD144 # 0 +0x0000C5D6 0xD145 # 0 +0x0000C5D7 0xD14C # 0 +0x0000C5D8 0xD14D # 0 +0x0000C5D9 0xD150 # 0 +0x0000C5DA 0xD154 # 0 +0x0000C5DB 0xD15C # 0 +0x0000C5DC 0xD15D # 0 +0x0000C5DD 0xD15F # 0 +0x0000C5DE 0xD161 # 0 +0x0000C5DF 0xD168 # 0 +0x0000C5E0 0xD16C # 0 +0x0000C5E1 0xD17C # 0 +0x0000C5E2 0xD184 # 0 +0x0000C5E3 0xD188 # 0 +0x0000C5E4 0xD1A0 # 0 +0x0000C5E5 0xD1A1 # 0 +0x0000C5E6 0xD1A4 # 0 +0x0000C5E7 0xD1A8 # 0 +0x0000C5E8 0xD1B0 # 0 +0x0000C5E9 0xD1B1 # 0 +0x0000C5EA 0xD1B3 # 0 +0x0000C5EB 0xD1B5 # 0 +0x0000C5EC 0xD1BA # 0 +0x0000C5ED 0xD1BC # 0 +0x0000C5EE 0xD1C0 # 0 +0x0000C5EF 0xD1D8 # 0 +0x0000C5F0 0xD1F4 # 0 +0x0000C5F1 0xD1F8 # 0 +0x0000C5F2 0xD207 # 0 +0x0000C5F3 0xD209 # 0 +0x0000C5F4 0xD210 # 0 +0x0000C5F5 0xD22C # 0 +0x0000C5F6 0xD22D # 0 +0x0000C5F7 0xD230 # 0 +0x0000C5F8 0xD234 # 0 +0x0000C5F9 0xD23C # 0 +0x0000C5FA 0xD23D # 0 +0x0000C5FB 0xD23F # 0 +0x0000C5FC 0xD241 # 0 +0x0000C5FD 0xD248 # 0 +0x0000C5FE 0xD25C # 0 +0x0000C6A1 0xD264 # 0 +0x0000C6A2 0xD280 # 0 +0x0000C6A3 0xD281 # 0 +0x0000C6A4 0xD284 # 0 +0x0000C6A5 0xD288 # 0 +0x0000C6A6 0xD290 # 0 +0x0000C6A7 0xD291 # 0 +0x0000C6A8 0xD295 # 0 +0x0000C6A9 0xD29C # 0 +0x0000C6AA 0xD2A0 # 0 +0x0000C6AB 0xD2A4 # 0 +0x0000C6AC 0xD2AC # 0 +0x0000C6AD 0xD2B1 # 0 +0x0000C6AE 0xD2B8 # 0 +0x0000C6AF 0xD2B9 # 0 +0x0000C6B0 0xD2BC # 0 +0x0000C6B1 0xD2BF # 0 +0x0000C6B2 0xD2C0 # 0 +0x0000C6B3 0xD2C2 # 0 +0x0000C6B4 0xD2C8 # 0 +0x0000C6B5 0xD2C9 # 0 +0x0000C6B6 0xD2CB # 0 +0x0000C6B7 0xD2D4 # 0 +0x0000C6B8 0xD2D8 # 0 +0x0000C6B9 0xD2DC # 0 +0x0000C6BA 0xD2E4 # 0 +0x0000C6BB 0xD2E5 # 0 +0x0000C6BC 0xD2F0 # 0 +0x0000C6BD 0xD2F1 # 0 +0x0000C6BE 0xD2F4 # 0 +0x0000C6BF 0xD2F8 # 0 +0x0000C6C0 0xD300 # 0 +0x0000C6C1 0xD301 # 0 +0x0000C6C2 0xD303 # 0 +0x0000C6C3 0xD305 # 0 +0x0000C6C4 0xD30C # 0 +0x0000C6C5 0xD30D # 0 +0x0000C6C6 0xD30E # 0 +0x0000C6C7 0xD310 # 0 +0x0000C6C8 0xD314 # 0 +0x0000C6C9 0xD316 # 0 +0x0000C6CA 0xD31C # 0 +0x0000C6CB 0xD31D # 0 +0x0000C6CC 0xD31F # 0 +0x0000C6CD 0xD320 # 0 +0x0000C6CE 0xD321 # 0 +0x0000C6CF 0xD325 # 0 +0x0000C6D0 0xD328 # 0 +0x0000C6D1 0xD329 # 0 +0x0000C6D2 0xD32C # 0 +0x0000C6D3 0xD330 # 0 +0x0000C6D4 0xD338 # 0 +0x0000C6D5 0xD339 # 0 +0x0000C6D6 0xD33B # 0 +0x0000C6D7 0xD33C # 0 +0x0000C6D8 0xD33D # 0 +0x0000C6D9 0xD344 # 0 +0x0000C6DA 0xD345 # 0 +0x0000C6DB 0xD37C # 0 +0x0000C6DC 0xD37D # 0 +0x0000C6DD 0xD380 # 0 +0x0000C6DE 0xD384 # 0 +0x0000C6DF 0xD38C # 0 +0x0000C6E0 0xD38D # 0 +0x0000C6E1 0xD38F # 0 +0x0000C6E2 0xD390 # 0 +0x0000C6E3 0xD391 # 0 +0x0000C6E4 0xD398 # 0 +0x0000C6E5 0xD399 # 0 +0x0000C6E6 0xD39C # 0 +0x0000C6E7 0xD3A0 # 0 +0x0000C6E8 0xD3A8 # 0 +0x0000C6E9 0xD3A9 # 0 +0x0000C6EA 0xD3AB # 0 +0x0000C6EB 0xD3AD # 0 +0x0000C6EC 0xD3B4 # 0 +0x0000C6ED 0xD3B8 # 0 +0x0000C6EE 0xD3BC # 0 +0x0000C6EF 0xD3C4 # 0 +0x0000C6F0 0xD3C5 # 0 +0x0000C6F1 0xD3C8 # 0 +0x0000C6F2 0xD3C9 # 0 +0x0000C6F3 0xD3D0 # 0 +0x0000C6F4 0xD3D8 # 0 +0x0000C6F5 0xD3E1 # 0 +0x0000C6F6 0xD3E3 # 0 +0x0000C6F7 0xD3EC # 0 +0x0000C6F8 0xD3ED # 0 +0x0000C6F9 0xD3F0 # 0 +0x0000C6FA 0xD3F4 # 0 +0x0000C6FB 0xD3FC # 0 +0x0000C6FC 0xD3FD # 0 +0x0000C6FD 0xD3FF # 0 +0x0000C6FE 0xD401 # 0 +0x0000C7A1 0xD408 # 0 +0x0000C7A2 0xD41D # 0 +0x0000C7A3 0xD440 # 0 +0x0000C7A4 0xD444 # 0 +0x0000C7A5 0xD45C # 0 +0x0000C7A6 0xD460 # 0 +0x0000C7A7 0xD464 # 0 +0x0000C7A8 0xD46D # 0 +0x0000C7A9 0xD46F # 0 +0x0000C7AA 0xD478 # 0 +0x0000C7AB 0xD479 # 0 +0x0000C7AC 0xD47C # 0 +0x0000C7AD 0xD47F # 0 +0x0000C7AE 0xD480 # 0 +0x0000C7AF 0xD482 # 0 +0x0000C7B0 0xD488 # 0 +0x0000C7B1 0xD489 # 0 +0x0000C7B2 0xD48B # 0 +0x0000C7B3 0xD48D # 0 +0x0000C7B4 0xD494 # 0 +0x0000C7B5 0xD4A9 # 0 +0x0000C7B6 0xD4CC # 0 +0x0000C7B7 0xD4D0 # 0 +0x0000C7B8 0xD4D4 # 0 +0x0000C7B9 0xD4DC # 0 +0x0000C7BA 0xD4DF # 0 +0x0000C7BB 0xD4E8 # 0 +0x0000C7BC 0xD4EC # 0 +0x0000C7BD 0xD4F0 # 0 +0x0000C7BE 0xD4F8 # 0 +0x0000C7BF 0xD4FB # 0 +0x0000C7C0 0xD4FD # 0 +0x0000C7C1 0xD504 # 0 +0x0000C7C2 0xD508 # 0 +0x0000C7C3 0xD50C # 0 +0x0000C7C4 0xD514 # 0 +0x0000C7C5 0xD515 # 0 +0x0000C7C6 0xD517 # 0 +0x0000C7C7 0xD53C # 0 +0x0000C7C8 0xD53D # 0 +0x0000C7C9 0xD540 # 0 +0x0000C7CA 0xD544 # 0 +0x0000C7CB 0xD54C # 0 +0x0000C7CC 0xD54D # 0 +0x0000C7CD 0xD54F # 0 +0x0000C7CE 0xD551 # 0 +0x0000C7CF 0xD558 # 0 +0x0000C7D0 0xD559 # 0 +0x0000C7D1 0xD55C # 0 +0x0000C7D2 0xD560 # 0 +0x0000C7D3 0xD565 # 0 +0x0000C7D4 0xD568 # 0 +0x0000C7D5 0xD569 # 0 +0x0000C7D6 0xD56B # 0 +0x0000C7D7 0xD56D # 0 +0x0000C7D8 0xD574 # 0 +0x0000C7D9 0xD575 # 0 +0x0000C7DA 0xD578 # 0 +0x0000C7DB 0xD57C # 0 +0x0000C7DC 0xD584 # 0 +0x0000C7DD 0xD585 # 0 +0x0000C7DE 0xD587 # 0 +0x0000C7DF 0xD588 # 0 +0x0000C7E0 0xD589 # 0 +0x0000C7E1 0xD590 # 0 +0x0000C7E2 0xD5A5 # 0 +0x0000C7E3 0xD5C8 # 0 +0x0000C7E4 0xD5C9 # 0 +0x0000C7E5 0xD5CC # 0 +0x0000C7E6 0xD5D0 # 0 +0x0000C7E7 0xD5D2 # 0 +0x0000C7E8 0xD5D8 # 0 +0x0000C7E9 0xD5D9 # 0 +0x0000C7EA 0xD5DB # 0 +0x0000C7EB 0xD5DD # 0 +0x0000C7EC 0xD5E4 # 0 +0x0000C7ED 0xD5E5 # 0 +0x0000C7EE 0xD5E8 # 0 +0x0000C7EF 0xD5EC # 0 +0x0000C7F0 0xD5F4 # 0 +0x0000C7F1 0xD5F5 # 0 +0x0000C7F2 0xD5F7 # 0 +0x0000C7F3 0xD5F9 # 0 +0x0000C7F4 0xD600 # 0 +0x0000C7F5 0xD601 # 0 +0x0000C7F6 0xD604 # 0 +0x0000C7F7 0xD608 # 0 +0x0000C7F8 0xD610 # 0 +0x0000C7F9 0xD611 # 0 +0x0000C7FA 0xD613 # 0 +0x0000C7FB 0xD614 # 0 +0x0000C7FC 0xD615 # 0 +0x0000C7FD 0xD61C # 0 +0x0000C7FE 0xD620 # 0 +0x0000C8A1 0xD624 # 0 +0x0000C8A2 0xD62D # 0 +0x0000C8A3 0xD638 # 0 +0x0000C8A4 0xD639 # 0 +0x0000C8A5 0xD63C # 0 +0x0000C8A6 0xD640 # 0 +0x0000C8A7 0xD645 # 0 +0x0000C8A8 0xD648 # 0 +0x0000C8A9 0xD649 # 0 +0x0000C8AA 0xD64B # 0 +0x0000C8AB 0xD64D # 0 +0x0000C8AC 0xD651 # 0 +0x0000C8AD 0xD654 # 0 +0x0000C8AE 0xD655 # 0 +0x0000C8AF 0xD658 # 0 +0x0000C8B0 0xD65C # 0 +0x0000C8B1 0xD667 # 0 +0x0000C8B2 0xD669 # 0 +0x0000C8B3 0xD670 # 0 +0x0000C8B4 0xD671 # 0 +0x0000C8B5 0xD674 # 0 +0x0000C8B6 0xD683 # 0 +0x0000C8B7 0xD685 # 0 +0x0000C8B8 0xD68C # 0 +0x0000C8B9 0xD68D # 0 +0x0000C8BA 0xD690 # 0 +0x0000C8BB 0xD694 # 0 +0x0000C8BC 0xD69D # 0 +0x0000C8BD 0xD69F # 0 +0x0000C8BE 0xD6A1 # 0 +0x0000C8BF 0xD6A8 # 0 +0x0000C8C0 0xD6AC # 0 +0x0000C8C1 0xD6B0 # 0 +0x0000C8C2 0xD6B9 # 0 +0x0000C8C3 0xD6BB # 0 +0x0000C8C4 0xD6C4 # 0 +0x0000C8C5 0xD6C5 # 0 +0x0000C8C6 0xD6C8 # 0 +0x0000C8C7 0xD6CC # 0 +0x0000C8C8 0xD6D1 # 0 +0x0000C8C9 0xD6D4 # 0 +0x0000C8CA 0xD6D7 # 0 +0x0000C8CB 0xD6D9 # 0 +0x0000C8CC 0xD6E0 # 0 +0x0000C8CD 0xD6E4 # 0 +0x0000C8CE 0xD6E8 # 0 +0x0000C8CF 0xD6F0 # 0 +0x0000C8D0 0xD6F5 # 0 +0x0000C8D1 0xD6FC # 0 +0x0000C8D2 0xD6FD # 0 +0x0000C8D3 0xD700 # 0 +0x0000C8D4 0xD704 # 0 +0x0000C8D5 0xD711 # 0 +0x0000C8D6 0xD718 # 0 +0x0000C8D7 0xD719 # 0 +0x0000C8D8 0xD71C # 0 +0x0000C8D9 0xD720 # 0 +0x0000C8DA 0xD728 # 0 +0x0000C8DB 0xD729 # 0 +0x0000C8DC 0xD72B # 0 +0x0000C8DD 0xD72D # 0 +0x0000C8DE 0xD734 # 0 +0x0000C8DF 0xD735 # 0 +0x0000C8E0 0xD738 # 0 +0x0000C8E1 0xD73C # 0 +0x0000C8E2 0xD744 # 0 +0x0000C8E3 0xD747 # 0 +0x0000C8E4 0xD749 # 0 +0x0000C8E5 0xD750 # 0 +0x0000C8E6 0xD751 # 0 +0x0000C8E7 0xD754 # 0 +0x0000C8E8 0xD756 # 0 +0x0000C8E9 0xD757 # 0 +0x0000C8EA 0xD758 # 0 +0x0000C8EB 0xD759 # 0 +0x0000C8EC 0xD760 # 0 +0x0000C8ED 0xD761 # 0 +0x0000C8EE 0xD763 # 0 +0x0000C8EF 0xD765 # 0 +0x0000C8F0 0xD769 # 0 +0x0000C8F1 0xD76C # 0 +0x0000C8F2 0xD770 # 0 +0x0000C8F3 0xD774 # 0 +0x0000C8F4 0xD77C # 0 +0x0000C8F5 0xD77D # 0 +0x0000C8F6 0xD781 # 0 +0x0000C8F7 0xD788 # 0 +0x0000C8F8 0xD789 # 0 +0x0000C8F9 0xD78C # 0 +0x0000C8FA 0xD790 # 0 +0x0000C8FB 0xD798 # 0 +0x0000C8FC 0xD799 # 0 +0x0000C8FD 0xD79B # 0 +0x0000C8FE 0xD79D # 0 +0x0000C9A1 0xF700 # 0 +0x0000C9A2 0xF701 # 0 +0x0000C9A3 0xF702 # 0 +0x0000C9A4 0xF703 # 0 +0x0000C9A5 0xF704 # 0 +0x0000C9A6 0xF705 # 0 +0x0000C9A7 0xF706 # 0 +0x0000C9A8 0xF707 # 0 +0x0000C9A9 0xF708 # 0 +0x0000C9AA 0xF709 # 0 +0x0000C9AB 0xF70A # 0 +0x0000C9AC 0xF70B # 0 +0x0000C9AD 0xF70C # 0 +0x0000C9AE 0xF70D # 0 +0x0000C9AF 0xF70E # 0 +0x0000C9B0 0xF70F # 0 +0x0000C9B1 0xF710 # 0 +0x0000C9B2 0xF711 # 0 +0x0000C9B3 0xF712 # 0 +0x0000C9B4 0xF713 # 0 +0x0000C9B5 0xF714 # 0 +0x0000C9B6 0xF715 # 0 +0x0000C9B7 0xF716 # 0 +0x0000C9B8 0xF717 # 0 +0x0000C9B9 0xF718 # 0 +0x0000C9BA 0xF719 # 0 +0x0000C9BB 0xF71A # 0 +0x0000C9BC 0xF71B # 0 +0x0000C9BD 0xF71C # 0 +0x0000C9BE 0xF71D # 0 +0x0000C9BF 0xF71E # 0 +0x0000C9C0 0xF71F # 0 +0x0000C9C1 0xF720 # 0 +0x0000C9C2 0xF721 # 0 +0x0000C9C3 0xF722 # 0 +0x0000C9C4 0xF723 # 0 +0x0000C9C5 0xF724 # 0 +0x0000C9C6 0xF725 # 0 +0x0000C9C7 0xF726 # 0 +0x0000C9C8 0xF727 # 0 +0x0000C9C9 0xF728 # 0 +0x0000C9CA 0xF729 # 0 +0x0000C9CB 0xF72A # 0 +0x0000C9CC 0xF72B # 0 +0x0000C9CD 0xF72C # 0 +0x0000C9CE 0xF72D # 0 +0x0000C9CF 0xF72E # 0 +0x0000C9D0 0xF72F # 0 +0x0000C9D1 0xF730 # 0 +0x0000C9D2 0xF731 # 0 +0x0000C9D3 0xF732 # 0 +0x0000C9D4 0xF733 # 0 +0x0000C9D5 0xF734 # 0 +0x0000C9D6 0xF735 # 0 +0x0000C9D7 0xF736 # 0 +0x0000C9D8 0xF737 # 0 +0x0000C9D9 0xF738 # 0 +0x0000C9DA 0xF739 # 0 +0x0000C9DB 0xF73A # 0 +0x0000C9DC 0xF73B # 0 +0x0000C9DD 0xF73C # 0 +0x0000C9DE 0xF73D # 0 +0x0000C9DF 0xF73E # 0 +0x0000C9E0 0xF73F # 0 +0x0000C9E1 0xF740 # 0 +0x0000C9E2 0xF741 # 0 +0x0000C9E3 0xF742 # 0 +0x0000C9E4 0xF743 # 0 +0x0000C9E5 0xF744 # 0 +0x0000C9E6 0xF745 # 0 +0x0000C9E7 0xF746 # 0 +0x0000C9E8 0xF747 # 0 +0x0000C9E9 0xF748 # 0 +0x0000C9EA 0xF749 # 0 +0x0000C9EB 0xF74A # 0 +0x0000C9EC 0xF74B # 0 +0x0000C9ED 0xF74C # 0 +0x0000C9EE 0xF74D # 0 +0x0000C9EF 0xF74E # 0 +0x0000C9F0 0xF74F # 0 +0x0000C9F1 0xF750 # 0 +0x0000C9F2 0xF751 # 0 +0x0000C9F3 0xF752 # 0 +0x0000C9F4 0xF753 # 0 +0x0000C9F5 0xF754 # 0 +0x0000C9F6 0xF755 # 0 +0x0000C9F7 0xF756 # 0 +0x0000C9F8 0xF757 # 0 +0x0000C9F9 0xF758 # 0 +0x0000C9FA 0xF759 # 0 +0x0000C9FB 0xF75A # 0 +0x0000C9FC 0xF75B # 0 +0x0000C9FD 0xF75C # 0 +0x0000C9FE 0xF75D # 0 +0x0000CAA1 0x4F3D # 0 +0x0000CAA2 0x4F73 # 0 +0x0000CAA3 0x5047 # 0 +0x0000CAA4 0x50F9 # 0 +0x0000CAA5 0x52A0 # 0 +0x0000CAA6 0x53EF # 0 +0x0000CAA7 0x5475 # 0 +0x0000CAA8 0x54E5 # 0 +0x0000CAA9 0x5609 # 0 +0x0000CAAA 0x5AC1 # 0 +0x0000CAAB 0x5BB6 # 0 +0x0000CAAC 0x6687 # 0 +0x0000CAAD 0x67B6 # 0 +0x0000CAAE 0x67B7 # 0 +0x0000CAAF 0x67EF # 0 +0x0000CAB0 0x6B4C # 0 +0x0000CAB1 0x73C2 # 0 +0x0000CAB2 0x75C2 # 0 +0x0000CAB3 0x7A3C # 0 +0x0000CAB4 0x82DB # 0 +0x0000CAB5 0x8304 # 0 +0x0000CAB6 0x8857 # 0 +0x0000CAB7 0x8888 # 0 +0x0000CAB8 0x8A36 # 0 +0x0000CAB9 0x8CC8 # 0 +0x0000CABA 0x8DCF # 0 +0x0000CABB 0x8EFB # 0 +0x0000CABC 0x8FE6 # 0 +0x0000CABD 0x99D5 # 0 +0x0000CABE 0x523B # 0 +0x0000CABF 0x5374 # 0 +0x0000CAC0 0x5404 # 0 +0x0000CAC1 0x606A # 0 +0x0000CAC2 0x6164 # 0 +0x0000CAC3 0x6BBC # 0 +0x0000CAC4 0x73CF # 0 +0x0000CAC5 0x811A # 0 +0x0000CAC6 0x89BA # 0 +0x0000CAC7 0x89D2 # 0 +0x0000CAC8 0x95A3 # 0 +0x0000CAC9 0x4F83 # 0 +0x0000CACA 0x520A # 0 +0x0000CACB 0x58BE # 0 +0x0000CACC 0x5978 # 0 +0x0000CACD 0x59E6 # 0 +0x0000CACE 0x5E72 # 0 +0x0000CACF 0x5E79 # 0 +0x0000CAD0 0x61C7 # 0 +0x0000CAD1 0x63C0 # 0 +0x0000CAD2 0x6746 # 0 +0x0000CAD3 0x67EC # 0 +0x0000CAD4 0x687F # 0 +0x0000CAD5 0x6F97 # 0 +0x0000CAD6 0x764E # 0 +0x0000CAD7 0x770B # 0 +0x0000CAD8 0x78F5 # 0 +0x0000CAD9 0x7A08 # 0 +0x0000CADA 0x7AFF # 0 +0x0000CADB 0x7C21 # 0 +0x0000CADC 0x809D # 0 +0x0000CADD 0x826E # 0 +0x0000CADE 0x8271 # 0 +0x0000CADF 0x8AEB # 0 +0x0000CAE0 0x9593 # 0 +0x0000CAE1 0x4E6B # 0 +0x0000CAE2 0x559D # 0 +0x0000CAE3 0x66F7 # 0 +0x0000CAE4 0x6E34 # 0 +0x0000CAE5 0x78A3 # 0 +0x0000CAE6 0x7AED # 0 +0x0000CAE7 0x845B # 0 +0x0000CAE8 0x8910 # 0 +0x0000CAE9 0x874E # 0 +0x0000CAEA 0x97A8 # 0 +0x0000CAEB 0x52D8 # 0 +0x0000CAEC 0x574E # 0 +0x0000CAED 0x582A # 0 +0x0000CAEE 0x5D4C # 0 +0x0000CAEF 0x611F # 0 +0x0000CAF0 0x61BE # 0 +0x0000CAF1 0x6221 # 0 +0x0000CAF2 0x6562 # 0 +0x0000CAF3 0x67D1 # 0 +0x0000CAF4 0x6A44 # 0 +0x0000CAF5 0x6E1B # 0 +0x0000CAF6 0x7518 # 0 +0x0000CAF7 0x75B3 # 0 +0x0000CAF8 0x76E3 # 0 +0x0000CAF9 0x77B0 # 0 +0x0000CAFA 0x7D3A # 0 +0x0000CAFB 0x90AF # 0 +0x0000CAFC 0x9451 # 0 +0x0000CAFD 0x9452 # 0 +0x0000CAFE 0x9F95 # 0 +0x0000CBA1 0x5323 # 0 +0x0000CBA2 0x5CAC # 0 +0x0000CBA3 0x7532 # 0 +0x0000CBA4 0x80DB # 0 +0x0000CBA5 0x9240 # 0 +0x0000CBA6 0x9598 # 0 +0x0000CBA7 0x525B # 0 +0x0000CBA8 0x5808 # 0 +0x0000CBA9 0x59DC # 0 +0x0000CBAA 0x5CA1 # 0 +0x0000CBAB 0x5D17 # 0 +0x0000CBAC 0x5EB7 # 0 +0x0000CBAD 0x5F3A # 0 +0x0000CBAE 0x5F4A # 0 +0x0000CBAF 0x6177 # 0 +0x0000CBB0 0x6C5F # 0 +0x0000CBB1 0x757A # 0 +0x0000CBB2 0x7586 # 0 +0x0000CBB3 0x7CE0 # 0 +0x0000CBB4 0x7D73 # 0 +0x0000CBB5 0x7DB1 # 0 +0x0000CBB6 0x7F8C # 0 +0x0000CBB7 0x8154 # 0 +0x0000CBB8 0x8221 # 0 +0x0000CBB9 0x8591 # 0 +0x0000CBBA 0x8941 # 0 +0x0000CBBB 0x8B1B # 0 +0x0000CBBC 0x92FC # 0 +0x0000CBBD 0x964D # 0 +0x0000CBBE 0x9C47 # 0 +0x0000CBBF 0x4ECB # 0 +0x0000CBC0 0x4EF7 # 0 +0x0000CBC1 0x500B # 0 +0x0000CBC2 0x51F1 # 0 +0x0000CBC3 0x584F # 0 +0x0000CBC4 0x6137 # 0 +0x0000CBC5 0x613E # 0 +0x0000CBC6 0x6168 # 0 +0x0000CBC7 0x6539 # 0 +0x0000CBC8 0x69EA # 0 +0x0000CBC9 0x6F11 # 0 +0x0000CBCA 0x75A5 # 0 +0x0000CBCB 0x7686 # 0 +0x0000CBCC 0x76D6 # 0 +0x0000CBCD 0x7B87 # 0 +0x0000CBCE 0x82A5 # 0 +0x0000CBCF 0x84CB # 0 +0x0000CBD0 0xF900 # 0 +0x0000CBD1 0x93A7 # 0 +0x0000CBD2 0x958B # 0 +0x0000CBD3 0x5580 # 0 +0x0000CBD4 0x5BA2 # 0 +0x0000CBD5 0x5751 # 0 +0x0000CBD6 0xF901 # 0 +0x0000CBD7 0x7CB3 # 0 +0x0000CBD8 0x7FB9 # 0 +0x0000CBD9 0x91B5 # 0 +0x0000CBDA 0x5028 # 0 +0x0000CBDB 0x53BB # 0 +0x0000CBDC 0x5C45 # 0 +0x0000CBDD 0x5DE8 # 0 +0x0000CBDE 0x62D2 # 0 +0x0000CBDF 0x636E # 0 +0x0000CBE0 0x64DA # 0 +0x0000CBE1 0x64E7 # 0 +0x0000CBE2 0x6E20 # 0 +0x0000CBE3 0x70AC # 0 +0x0000CBE4 0x795B # 0 +0x0000CBE5 0x8DDD # 0 +0x0000CBE6 0x8E1E # 0 +0x0000CBE7 0xF902 # 0 +0x0000CBE8 0x907D # 0 +0x0000CBE9 0x9245 # 0 +0x0000CBEA 0x92F8 # 0 +0x0000CBEB 0x4E7E # 0 +0x0000CBEC 0x4EF6 # 0 +0x0000CBED 0x5065 # 0 +0x0000CBEE 0x5DFE # 0 +0x0000CBEF 0x5EFA # 0 +0x0000CBF0 0x6106 # 0 +0x0000CBF1 0x6957 # 0 +0x0000CBF2 0x8171 # 0 +0x0000CBF3 0x8654 # 0 +0x0000CBF4 0x8E47 # 0 +0x0000CBF5 0x9375 # 0 +0x0000CBF6 0x9A2B # 0 +0x0000CBF7 0x4E5E # 0 +0x0000CBF8 0x5091 # 0 +0x0000CBF9 0x6770 # 0 +0x0000CBFA 0x6840 # 0 +0x0000CBFB 0x5109 # 0 +0x0000CBFC 0x528D # 0 +0x0000CBFD 0x5292 # 0 +0x0000CBFE 0x6AA2 # 0 +0x0000CCA1 0x77BC # 0 +0x0000CCA2 0x9210 # 0 +0x0000CCA3 0x9ED4 # 0 +0x0000CCA4 0x52AB # 0 +0x0000CCA5 0x602F # 0 +0x0000CCA6 0x8FF2 # 0 +0x0000CCA7 0x5048 # 0 +0x0000CCA8 0x61A9 # 0 +0x0000CCA9 0x63ED # 0 +0x0000CCAA 0x64CA # 0 +0x0000CCAB 0x683C # 0 +0x0000CCAC 0x6A84 # 0 +0x0000CCAD 0x6FC0 # 0 +0x0000CCAE 0x8188 # 0 +0x0000CCAF 0x89A1 # 0 +0x0000CCB0 0x9694 # 0 +0x0000CCB1 0x5805 # 0 +0x0000CCB2 0x727D # 0 +0x0000CCB3 0x72AC # 0 +0x0000CCB4 0x7504 # 0 +0x0000CCB5 0x7D79 # 0 +0x0000CCB6 0x7E6D # 0 +0x0000CCB7 0x80A9 # 0 +0x0000CCB8 0x898B # 0 +0x0000CCB9 0x8B74 # 0 +0x0000CCBA 0x9063 # 0 +0x0000CCBB 0x9D51 # 0 +0x0000CCBC 0x6289 # 0 +0x0000CCBD 0x6C7A # 0 +0x0000CCBE 0x6F54 # 0 +0x0000CCBF 0x7D50 # 0 +0x0000CCC0 0x7F3A # 0 +0x0000CCC1 0x8A23 # 0 +0x0000CCC2 0x517C # 0 +0x0000CCC3 0x614A # 0 +0x0000CCC4 0x7B9D # 0 +0x0000CCC5 0x8B19 # 0 +0x0000CCC6 0x9257 # 0 +0x0000CCC7 0x938C # 0 +0x0000CCC8 0x4EAC # 0 +0x0000CCC9 0x4FD3 # 0 +0x0000CCCA 0x501E # 0 +0x0000CCCB 0x50BE # 0 +0x0000CCCC 0x5106 # 0 +0x0000CCCD 0x52C1 # 0 +0x0000CCCE 0x52CD # 0 +0x0000CCCF 0x537F # 0 +0x0000CCD0 0x5770 # 0 +0x0000CCD1 0x5883 # 0 +0x0000CCD2 0x5E9A # 0 +0x0000CCD3 0x5F91 # 0 +0x0000CCD4 0x6176 # 0 +0x0000CCD5 0x61AC # 0 +0x0000CCD6 0x64CE # 0 +0x0000CCD7 0x656C # 0 +0x0000CCD8 0x666F # 0 +0x0000CCD9 0x66BB # 0 +0x0000CCDA 0x66F4 # 0 +0x0000CCDB 0x6897 # 0 +0x0000CCDC 0x6D87 # 0 +0x0000CCDD 0x7085 # 0 +0x0000CCDE 0x70F1 # 0 +0x0000CCDF 0x749F # 0 +0x0000CCE0 0x74A5 # 0 +0x0000CCE1 0x74CA # 0 +0x0000CCE2 0x75D9 # 0 +0x0000CCE3 0x786C # 0 +0x0000CCE4 0x78EC # 0 +0x0000CCE5 0x7ADF # 0 +0x0000CCE6 0x7AF6 # 0 +0x0000CCE7 0x7D45 # 0 +0x0000CCE8 0x7D93 # 0 +0x0000CCE9 0x8015 # 0 +0x0000CCEA 0x803F # 0 +0x0000CCEB 0x811B # 0 +0x0000CCEC 0x8396 # 0 +0x0000CCED 0x8B66 # 0 +0x0000CCEE 0x8F15 # 0 +0x0000CCEF 0x9015 # 0 +0x0000CCF0 0x93E1 # 0 +0x0000CCF1 0x9803 # 0 +0x0000CCF2 0x9838 # 0 +0x0000CCF3 0x9A5A # 0 +0x0000CCF4 0x9BE8 # 0 +0x0000CCF5 0x4FC2 # 0 +0x0000CCF6 0x5553 # 0 +0x0000CCF7 0x583A # 0 +0x0000CCF8 0x5951 # 0 +0x0000CCF9 0x5B63 # 0 +0x0000CCFA 0x5C46 # 0 +0x0000CCFB 0x60B8 # 0 +0x0000CCFC 0x6212 # 0 +0x0000CCFD 0x6842 # 0 +0x0000CCFE 0x68B0 # 0 +0x0000CDA1 0x68E8 # 0 +0x0000CDA2 0x6EAA # 0 +0x0000CDA3 0x754C # 0 +0x0000CDA4 0x7678 # 0 +0x0000CDA5 0x78CE # 0 +0x0000CDA6 0x7A3D # 0 +0x0000CDA7 0x7CFB # 0 +0x0000CDA8 0x7E6B # 0 +0x0000CDA9 0x7E7C # 0 +0x0000CDAA 0x8A08 # 0 +0x0000CDAB 0x8AA1 # 0 +0x0000CDAC 0x8C3F # 0 +0x0000CDAD 0x968E # 0 +0x0000CDAE 0x9DC4 # 0 +0x0000CDAF 0x53E4 # 0 +0x0000CDB0 0x53E9 # 0 +0x0000CDB1 0x544A # 0 +0x0000CDB2 0x5471 # 0 +0x0000CDB3 0x56FA # 0 +0x0000CDB4 0x59D1 # 0 +0x0000CDB5 0x5B64 # 0 +0x0000CDB6 0x5C3B # 0 +0x0000CDB7 0x5EAB # 0 +0x0000CDB8 0x62F7 # 0 +0x0000CDB9 0x6537 # 0 +0x0000CDBA 0x6545 # 0 +0x0000CDBB 0x6572 # 0 +0x0000CDBC 0x66A0 # 0 +0x0000CDBD 0x67AF # 0 +0x0000CDBE 0x69C1 # 0 +0x0000CDBF 0x6CBD # 0 +0x0000CDC0 0x75FC # 0 +0x0000CDC1 0x7690 # 0 +0x0000CDC2 0x777E # 0 +0x0000CDC3 0x7A3F # 0 +0x0000CDC4 0x7F94 # 0 +0x0000CDC5 0x8003 # 0 +0x0000CDC6 0x80A1 # 0 +0x0000CDC7 0x818F # 0 +0x0000CDC8 0x82E6 # 0 +0x0000CDC9 0x82FD # 0 +0x0000CDCA 0x83F0 # 0 +0x0000CDCB 0x85C1 # 0 +0x0000CDCC 0x8831 # 0 +0x0000CDCD 0x88B4 # 0 +0x0000CDCE 0x8AA5 # 0 +0x0000CDCF 0xF903 # 0 +0x0000CDD0 0x8F9C # 0 +0x0000CDD1 0x932E # 0 +0x0000CDD2 0x96C7 # 0 +0x0000CDD3 0x9867 # 0 +0x0000CDD4 0x9AD8 # 0 +0x0000CDD5 0x9F13 # 0 +0x0000CDD6 0x54ED # 0 +0x0000CDD7 0x659B # 0 +0x0000CDD8 0x66F2 # 0 +0x0000CDD9 0x688F # 0 +0x0000CDDA 0x7A40 # 0 +0x0000CDDB 0x8C37 # 0 +0x0000CDDC 0x9D60 # 0 +0x0000CDDD 0x56F0 # 0 +0x0000CDDE 0x5764 # 0 +0x0000CDDF 0x5D11 # 0 +0x0000CDE0 0x6606 # 0 +0x0000CDE1 0x68B1 # 0 +0x0000CDE2 0x68CD # 0 +0x0000CDE3 0x6EFE # 0 +0x0000CDE4 0x7428 # 0 +0x0000CDE5 0x889E # 0 +0x0000CDE6 0x9BE4 # 0 +0x0000CDE7 0x6C68 # 0 +0x0000CDE8 0xF904 # 0 +0x0000CDE9 0x9AA8 # 0 +0x0000CDEA 0x4F9B # 0 +0x0000CDEB 0x516C # 0 +0x0000CDEC 0x5171 # 0 +0x0000CDED 0x529F # 0 +0x0000CDEE 0x5B54 # 0 +0x0000CDEF 0x5DE5 # 0 +0x0000CDF0 0x6050 # 0 +0x0000CDF1 0x606D # 0 +0x0000CDF2 0x62F1 # 0 +0x0000CDF3 0x63A7 # 0 +0x0000CDF4 0x653B # 0 +0x0000CDF5 0x73D9 # 0 +0x0000CDF6 0x7A7A # 0 +0x0000CDF7 0x86A3 # 0 +0x0000CDF8 0x8CA2 # 0 +0x0000CDF9 0x978F # 0 +0x0000CDFA 0x4E32 # 0 +0x0000CDFB 0x5BE1 # 0 +0x0000CDFC 0x6208 # 0 +0x0000CDFD 0x679C # 0 +0x0000CDFE 0x74DC # 0 +0x0000CEA1 0x79D1 # 0 +0x0000CEA2 0x83D3 # 0 +0x0000CEA3 0x8A87 # 0 +0x0000CEA4 0x8AB2 # 0 +0x0000CEA5 0x8DE8 # 0 +0x0000CEA6 0x904E # 0 +0x0000CEA7 0x934B # 0 +0x0000CEA8 0x9846 # 0 +0x0000CEA9 0x5ED3 # 0 +0x0000CEAA 0x69E8 # 0 +0x0000CEAB 0x85FF # 0 +0x0000CEAC 0x90ED # 0 +0x0000CEAD 0xF905 # 0 +0x0000CEAE 0x51A0 # 0 +0x0000CEAF 0x5B98 # 0 +0x0000CEB0 0x5BEC # 0 +0x0000CEB1 0x6163 # 0 +0x0000CEB2 0x68FA # 0 +0x0000CEB3 0x6B3E # 0 +0x0000CEB4 0x704C # 0 +0x0000CEB5 0x742F # 0 +0x0000CEB6 0x74D8 # 0 +0x0000CEB7 0x7BA1 # 0 +0x0000CEB8 0x7F50 # 0 +0x0000CEB9 0x83C5 # 0 +0x0000CEBA 0x89C0 # 0 +0x0000CEBB 0x8CAB # 0 +0x0000CEBC 0x95DC # 0 +0x0000CEBD 0x9928 # 0 +0x0000CEBE 0x522E # 0 +0x0000CEBF 0x605D # 0 +0x0000CEC0 0x62EC # 0 +0x0000CEC1 0x9002 # 0 +0x0000CEC2 0x4F8A # 0 +0x0000CEC3 0x5149 # 0 +0x0000CEC4 0x5321 # 0 +0x0000CEC5 0x58D9 # 0 +0x0000CEC6 0x5EE3 # 0 +0x0000CEC7 0x66E0 # 0 +0x0000CEC8 0x6D38 # 0 +0x0000CEC9 0x709A # 0 +0x0000CECA 0x72C2 # 0 +0x0000CECB 0x73D6 # 0 +0x0000CECC 0x7B50 # 0 +0x0000CECD 0x80F1 # 0 +0x0000CECE 0x945B # 0 +0x0000CECF 0x5366 # 0 +0x0000CED0 0x639B # 0 +0x0000CED1 0x7F6B # 0 +0x0000CED2 0x4E56 # 0 +0x0000CED3 0x5080 # 0 +0x0000CED4 0x584A # 0 +0x0000CED5 0x58DE # 0 +0x0000CED6 0x602A # 0 +0x0000CED7 0x6127 # 0 +0x0000CED8 0x62D0 # 0 +0x0000CED9 0x69D0 # 0 +0x0000CEDA 0x9B41 # 0 +0x0000CEDB 0x5B8F # 0 +0x0000CEDC 0x7D18 # 0 +0x0000CEDD 0x80B1 # 0 +0x0000CEDE 0x8F5F # 0 +0x0000CEDF 0x4EA4 # 0 +0x0000CEE0 0x50D1 # 0 +0x0000CEE1 0x54AC # 0 +0x0000CEE2 0x55AC # 0 +0x0000CEE3 0x5B0C # 0 +0x0000CEE4 0x5DA0 # 0 +0x0000CEE5 0x5DE7 # 0 +0x0000CEE6 0x652A # 0 +0x0000CEE7 0x654E # 0 +0x0000CEE8 0x6821 # 0 +0x0000CEE9 0x6A4B # 0 +0x0000CEEA 0x72E1 # 0 +0x0000CEEB 0x768E # 0 +0x0000CEEC 0x77EF # 0 +0x0000CEED 0x7D5E # 0 +0x0000CEEE 0x7FF9 # 0 +0x0000CEEF 0x81A0 # 0 +0x0000CEF0 0x854E # 0 +0x0000CEF1 0x86DF # 0 +0x0000CEF2 0x8F03 # 0 +0x0000CEF3 0x8F4E # 0 +0x0000CEF4 0x90CA # 0 +0x0000CEF5 0x9903 # 0 +0x0000CEF6 0x9A55 # 0 +0x0000CEF7 0x9BAB # 0 +0x0000CEF8 0x4E18 # 0 +0x0000CEF9 0x4E45 # 0 +0x0000CEFA 0x4E5D # 0 +0x0000CEFB 0x4EC7 # 0 +0x0000CEFC 0x4FF1 # 0 +0x0000CEFD 0x5177 # 0 +0x0000CEFE 0x52FE # 0 +0x0000CFA1 0x5340 # 0 +0x0000CFA2 0x53E3 # 0 +0x0000CFA3 0x53E5 # 0 +0x0000CFA4 0x548E # 0 +0x0000CFA5 0x5614 # 0 +0x0000CFA6 0x5775 # 0 +0x0000CFA7 0x57A2 # 0 +0x0000CFA8 0x5BC7 # 0 +0x0000CFA9 0x5D87 # 0 +0x0000CFAA 0x5ED0 # 0 +0x0000CFAB 0x61FC # 0 +0x0000CFAC 0x62D8 # 0 +0x0000CFAD 0x6551 # 0 +0x0000CFAE 0x67B8 # 0 +0x0000CFAF 0x67E9 # 0 +0x0000CFB0 0x69CB # 0 +0x0000CFB1 0x6B50 # 0 +0x0000CFB2 0x6BC6 # 0 +0x0000CFB3 0x6BEC # 0 +0x0000CFB4 0x6C42 # 0 +0x0000CFB5 0x6E9D # 0 +0x0000CFB6 0x7078 # 0 +0x0000CFB7 0x72D7 # 0 +0x0000CFB8 0x7396 # 0 +0x0000CFB9 0x7403 # 0 +0x0000CFBA 0x77BF # 0 +0x0000CFBB 0x77E9 # 0 +0x0000CFBC 0x7A76 # 0 +0x0000CFBD 0x7D7F # 0 +0x0000CFBE 0x8009 # 0 +0x0000CFBF 0x81FC # 0 +0x0000CFC0 0x8205 # 0 +0x0000CFC1 0x820A # 0 +0x0000CFC2 0x82DF # 0 +0x0000CFC3 0x8862 # 0 +0x0000CFC4 0x8B33 # 0 +0x0000CFC5 0x8CFC # 0 +0x0000CFC6 0x8EC0 # 0 +0x0000CFC7 0x9011 # 0 +0x0000CFC8 0x90B1 # 0 +0x0000CFC9 0x9264 # 0 +0x0000CFCA 0x92B6 # 0 +0x0000CFCB 0x99D2 # 0 +0x0000CFCC 0x9A45 # 0 +0x0000CFCD 0x9CE9 # 0 +0x0000CFCE 0x9DD7 # 0 +0x0000CFCF 0x9F9C # 0 +0x0000CFD0 0x570B # 0 +0x0000CFD1 0x5C40 # 0 +0x0000CFD2 0x83CA # 0 +0x0000CFD3 0x97A0 # 0 +0x0000CFD4 0x97AB # 0 +0x0000CFD5 0x9EB4 # 0 +0x0000CFD6 0x541B # 0 +0x0000CFD7 0x7A98 # 0 +0x0000CFD8 0x7FA4 # 0 +0x0000CFD9 0x88D9 # 0 +0x0000CFDA 0x8ECD # 0 +0x0000CFDB 0x90E1 # 0 +0x0000CFDC 0x5800 # 0 +0x0000CFDD 0x5C48 # 0 +0x0000CFDE 0x6398 # 0 +0x0000CFDF 0x7A9F # 0 +0x0000CFE0 0x5BAE # 0 +0x0000CFE1 0x5F13 # 0 +0x0000CFE2 0x7A79 # 0 +0x0000CFE3 0x7AAE # 0 +0x0000CFE4 0x828E # 0 +0x0000CFE5 0x8EAC # 0 +0x0000CFE6 0x5026 # 0 +0x0000CFE7 0x5238 # 0 +0x0000CFE8 0x52F8 # 0 +0x0000CFE9 0x5377 # 0 +0x0000CFEA 0x5708 # 0 +0x0000CFEB 0x62F3 # 0 +0x0000CFEC 0x6372 # 0 +0x0000CFED 0x6B0A # 0 +0x0000CFEE 0x6DC3 # 0 +0x0000CFEF 0x7737 # 0 +0x0000CFF0 0x53A5 # 0 +0x0000CFF1 0x7357 # 0 +0x0000CFF2 0x8568 # 0 +0x0000CFF3 0x8E76 # 0 +0x0000CFF4 0x95D5 # 0 +0x0000CFF5 0x673A # 0 +0x0000CFF6 0x6AC3 # 0 +0x0000CFF7 0x6F70 # 0 +0x0000CFF8 0x8A6D # 0 +0x0000CFF9 0x8ECC # 0 +0x0000CFFA 0x994B # 0 +0x0000CFFB 0xF906 # 0 +0x0000CFFC 0x6677 # 0 +0x0000CFFD 0x6B78 # 0 +0x0000CFFE 0x8CB4 # 0 +0x0000D0A1 0x9B3C # 0 +0x0000D0A2 0xF907 # 0 +0x0000D0A3 0x53EB # 0 +0x0000D0A4 0x572D # 0 +0x0000D0A5 0x594E # 0 +0x0000D0A6 0x63C6 # 0 +0x0000D0A7 0x69FB # 0 +0x0000D0A8 0x73EA # 0 +0x0000D0A9 0x7845 # 0 +0x0000D0AA 0x7ABA # 0 +0x0000D0AB 0x7AC5 # 0 +0x0000D0AC 0x7CFE # 0 +0x0000D0AD 0x8475 # 0 +0x0000D0AE 0x898F # 0 +0x0000D0AF 0x8D73 # 0 +0x0000D0B0 0x9035 # 0 +0x0000D0B1 0x95A8 # 0 +0x0000D0B2 0x52FB # 0 +0x0000D0B3 0x5747 # 0 +0x0000D0B4 0x7547 # 0 +0x0000D0B5 0x7B60 # 0 +0x0000D0B6 0x83CC # 0 +0x0000D0B7 0x921E # 0 +0x0000D0B8 0xF908 # 0 +0x0000D0B9 0x6A58 # 0 +0x0000D0BA 0x514B # 0 +0x0000D0BB 0x524B # 0 +0x0000D0BC 0x5287 # 0 +0x0000D0BD 0x621F # 0 +0x0000D0BE 0x68D8 # 0 +0x0000D0BF 0x6975 # 0 +0x0000D0C0 0x9699 # 0 +0x0000D0C1 0x50C5 # 0 +0x0000D0C2 0x52A4 # 0 +0x0000D0C3 0x52E4 # 0 +0x0000D0C4 0x61C3 # 0 +0x0000D0C5 0x65A4 # 0 +0x0000D0C6 0x6839 # 0 +0x0000D0C7 0x69FF # 0 +0x0000D0C8 0x747E # 0 +0x0000D0C9 0x7B4B # 0 +0x0000D0CA 0x82B9 # 0 +0x0000D0CB 0x83EB # 0 +0x0000D0CC 0x89B2 # 0 +0x0000D0CD 0x8B39 # 0 +0x0000D0CE 0x8FD1 # 0 +0x0000D0CF 0x9949 # 0 +0x0000D0D0 0xF909 # 0 +0x0000D0D1 0x4ECA # 0 +0x0000D0D2 0x5997 # 0 +0x0000D0D3 0x64D2 # 0 +0x0000D0D4 0x6611 # 0 +0x0000D0D5 0x6A8E # 0 +0x0000D0D6 0x7434 # 0 +0x0000D0D7 0x7981 # 0 +0x0000D0D8 0x79BD # 0 +0x0000D0D9 0x82A9 # 0 +0x0000D0DA 0x887E # 0 +0x0000D0DB 0x887F # 0 +0x0000D0DC 0x895F # 0 +0x0000D0DD 0xF90A # 0 +0x0000D0DE 0x9326 # 0 +0x0000D0DF 0x4F0B # 0 +0x0000D0E0 0x53CA # 0 +0x0000D0E1 0x6025 # 0 +0x0000D0E2 0x6271 # 0 +0x0000D0E3 0x6C72 # 0 +0x0000D0E4 0x7D1A # 0 +0x0000D0E5 0x7D66 # 0 +0x0000D0E6 0x4E98 # 0 +0x0000D0E7 0x5162 # 0 +0x0000D0E8 0x77DC # 0 +0x0000D0E9 0x80AF # 0 +0x0000D0EA 0x4F01 # 0 +0x0000D0EB 0x4F0E # 0 +0x0000D0EC 0x5176 # 0 +0x0000D0ED 0x5180 # 0 +0x0000D0EE 0x55DC # 0 +0x0000D0EF 0x5668 # 0 +0x0000D0F0 0x573B # 0 +0x0000D0F1 0x57FA # 0 +0x0000D0F2 0x57FC # 0 +0x0000D0F3 0x5914 # 0 +0x0000D0F4 0x5947 # 0 +0x0000D0F5 0x5993 # 0 +0x0000D0F6 0x5BC4 # 0 +0x0000D0F7 0x5C90 # 0 +0x0000D0F8 0x5D0E # 0 +0x0000D0F9 0x5DF1 # 0 +0x0000D0FA 0x5E7E # 0 +0x0000D0FB 0x5FCC # 0 +0x0000D0FC 0x6280 # 0 +0x0000D0FD 0x65D7 # 0 +0x0000D0FE 0x65E3 # 0 +0x0000D1A1 0x671E # 0 +0x0000D1A2 0x671F # 0 +0x0000D1A3 0x675E # 0 +0x0000D1A4 0x68CB # 0 +0x0000D1A5 0x68C4 # 0 +0x0000D1A6 0x6A5F # 0 +0x0000D1A7 0x6B3A # 0 +0x0000D1A8 0x6C23 # 0 +0x0000D1A9 0x6C7D # 0 +0x0000D1AA 0x6C82 # 0 +0x0000D1AB 0x6DC7 # 0 +0x0000D1AC 0x7398 # 0 +0x0000D1AD 0x7426 # 0 +0x0000D1AE 0x742A # 0 +0x0000D1AF 0x7482 # 0 +0x0000D1B0 0x74A3 # 0 +0x0000D1B1 0x7578 # 0 +0x0000D1B2 0x757F # 0 +0x0000D1B3 0x7881 # 0 +0x0000D1B4 0x78EF # 0 +0x0000D1B5 0x7941 # 0 +0x0000D1B6 0x7947 # 0 +0x0000D1B7 0x7948 # 0 +0x0000D1B8 0x797A # 0 +0x0000D1B9 0x7B95 # 0 +0x0000D1BA 0x7D00 # 0 +0x0000D1BB 0x7DBA # 0 +0x0000D1BC 0x7F88 # 0 +0x0000D1BD 0x8006 # 0 +0x0000D1BE 0x802D # 0 +0x0000D1BF 0x808C # 0 +0x0000D1C0 0x8A18 # 0 +0x0000D1C1 0x8B4F # 0 +0x0000D1C2 0x8C48 # 0 +0x0000D1C3 0x8D77 # 0 +0x0000D1C4 0x9321 # 0 +0x0000D1C5 0x9324 # 0 +0x0000D1C6 0x98E2 # 0 +0x0000D1C7 0x9951 # 0 +0x0000D1C8 0x9A0E # 0 +0x0000D1C9 0x9A0F # 0 +0x0000D1CA 0x9A65 # 0 +0x0000D1CB 0x9E92 # 0 +0x0000D1CC 0x7DCA # 0 +0x0000D1CD 0x4F76 # 0 +0x0000D1CE 0x5409 # 0 +0x0000D1CF 0x62EE # 0 +0x0000D1D0 0x6854 # 0 +0x0000D1D1 0x91D1 # 0 +0x0000D1D2 0x55AB # 0 +0x0000D1D3 0x513A # 0 +0x0000D1D4 0xF90B # 0 +0x0000D1D5 0xF90C # 0 +0x0000D1D6 0x5A1C # 0 +0x0000D1D7 0x61E6 # 0 +0x0000D1D8 0xF90D # 0 +0x0000D1D9 0x62CF # 0 +0x0000D1DA 0x62FF # 0 +0x0000D1DB 0xF90E # 0 +0x0000D1DC 0xF90F # 0 +0x0000D1DD 0xF910 # 0 +0x0000D1DE 0xF911 # 0 +0x0000D1DF 0xF912 # 0 +0x0000D1E0 0xF913 # 0 +0x0000D1E1 0x90A3 # 0 +0x0000D1E2 0xF914 # 0 +0x0000D1E3 0xF915 # 0 +0x0000D1E4 0xF916 # 0 +0x0000D1E5 0xF917 # 0 +0x0000D1E6 0xF918 # 0 +0x0000D1E7 0x8AFE # 0 +0x0000D1E8 0xF919 # 0 +0x0000D1E9 0xF91A # 0 +0x0000D1EA 0xF91B # 0 +0x0000D1EB 0xF91C # 0 +0x0000D1EC 0x6696 # 0 +0x0000D1ED 0xF91D # 0 +0x0000D1EE 0x7156 # 0 +0x0000D1EF 0xF91E # 0 +0x0000D1F0 0xF91F # 0 +0x0000D1F1 0x96E3 # 0 +0x0000D1F2 0xF920 # 0 +0x0000D1F3 0x634F # 0 +0x0000D1F4 0x637A # 0 +0x0000D1F5 0x5357 # 0 +0x0000D1F6 0xF921 # 0 +0x0000D1F7 0x678F # 0 +0x0000D1F8 0x6960 # 0 +0x0000D1F9 0x6E73 # 0 +0x0000D1FA 0xF922 # 0 +0x0000D1FB 0x7537 # 0 +0x0000D1FC 0xF923 # 0 +0x0000D1FD 0xF924 # 0 +0x0000D1FE 0xF925 # 0 +0x0000D2A1 0x7D0D # 0 +0x0000D2A2 0xF926 # 0 +0x0000D2A3 0xF927 # 0 +0x0000D2A4 0x8872 # 0 +0x0000D2A5 0x56CA # 0 +0x0000D2A6 0x5A18 # 0 +0x0000D2A7 0xF928 # 0 +0x0000D2A8 0xF929 # 0 +0x0000D2A9 0xF92A # 0 +0x0000D2AA 0xF92B # 0 +0x0000D2AB 0xF92C # 0 +0x0000D2AC 0x4E43 # 0 +0x0000D2AD 0xF92D # 0 +0x0000D2AE 0x5167 # 0 +0x0000D2AF 0x5948 # 0 +0x0000D2B0 0x67F0 # 0 +0x0000D2B1 0x8010 # 0 +0x0000D2B2 0xF92E # 0 +0x0000D2B3 0x5973 # 0 +0x0000D2B4 0x5E74 # 0 +0x0000D2B5 0x649A # 0 +0x0000D2B6 0x79CA # 0 +0x0000D2B7 0x5FF5 # 0 +0x0000D2B8 0x606C # 0 +0x0000D2B9 0x62C8 # 0 +0x0000D2BA 0x637B # 0 +0x0000D2BB 0x5BE7 # 0 +0x0000D2BC 0x5BD7 # 0 +0x0000D2BD 0x52AA # 0 +0x0000D2BE 0xF92F # 0 +0x0000D2BF 0x5974 # 0 +0x0000D2C0 0x5F29 # 0 +0x0000D2C1 0x6012 # 0 +0x0000D2C2 0xF930 # 0 +0x0000D2C3 0xF931 # 0 +0x0000D2C4 0xF932 # 0 +0x0000D2C5 0x7459 # 0 +0x0000D2C6 0xF933 # 0 +0x0000D2C7 0xF934 # 0 +0x0000D2C8 0xF935 # 0 +0x0000D2C9 0xF936 # 0 +0x0000D2CA 0xF937 # 0 +0x0000D2CB 0xF938 # 0 +0x0000D2CC 0x99D1 # 0 +0x0000D2CD 0xF939 # 0 +0x0000D2CE 0xF93A # 0 +0x0000D2CF 0xF93B # 0 +0x0000D2D0 0xF93C # 0 +0x0000D2D1 0xF93D # 0 +0x0000D2D2 0xF93E # 0 +0x0000D2D3 0xF93F # 0 +0x0000D2D4 0xF940 # 0 +0x0000D2D5 0xF941 # 0 +0x0000D2D6 0xF942 # 0 +0x0000D2D7 0xF943 # 0 +0x0000D2D8 0x6FC3 # 0 +0x0000D2D9 0xF944 # 0 +0x0000D2DA 0xF945 # 0 +0x0000D2DB 0x81BF # 0 +0x0000D2DC 0x8FB2 # 0 +0x0000D2DD 0x60F1 # 0 +0x0000D2DE 0xF946 # 0 +0x0000D2DF 0xF947 # 0 +0x0000D2E0 0x8166 # 0 +0x0000D2E1 0xF948 # 0 +0x0000D2E2 0xF949 # 0 +0x0000D2E3 0x5C3F # 0 +0x0000D2E4 0xF94A # 0 +0x0000D2E5 0xF94B # 0 +0x0000D2E6 0xF94C # 0 +0x0000D2E7 0xF94D # 0 +0x0000D2E8 0xF94E # 0 +0x0000D2E9 0xF94F # 0 +0x0000D2EA 0xF950 # 0 +0x0000D2EB 0xF951 # 0 +0x0000D2EC 0x5AE9 # 0 +0x0000D2ED 0x8A25 # 0 +0x0000D2EE 0x677B # 0 +0x0000D2EF 0x7D10 # 0 +0x0000D2F0 0xF952 # 0 +0x0000D2F1 0xF953 # 0 +0x0000D2F2 0xF954 # 0 +0x0000D2F3 0xF955 # 0 +0x0000D2F4 0xF956 # 0 +0x0000D2F5 0xF957 # 0 +0x0000D2F6 0x80FD # 0 +0x0000D2F7 0xF958 # 0 +0x0000D2F8 0xF959 # 0 +0x0000D2F9 0x5C3C # 0 +0x0000D2FA 0x6CE5 # 0 +0x0000D2FB 0x533F # 0 +0x0000D2FC 0x6EBA # 0 +0x0000D2FD 0x591A # 0 +0x0000D2FE 0x8336 # 0 +0x0000D3A1 0x4E39 # 0 +0x0000D3A2 0x4EB6 # 0 +0x0000D3A3 0x4F46 # 0 +0x0000D3A4 0x55AE # 0 +0x0000D3A5 0x5718 # 0 +0x0000D3A6 0x58C7 # 0 +0x0000D3A7 0x5F56 # 0 +0x0000D3A8 0x65B7 # 0 +0x0000D3A9 0x65E6 # 0 +0x0000D3AA 0x6A80 # 0 +0x0000D3AB 0x6BB5 # 0 +0x0000D3AC 0x6E4D # 0 +0x0000D3AD 0x77ED # 0 +0x0000D3AE 0x7AEF # 0 +0x0000D3AF 0x7C1E # 0 +0x0000D3B0 0x7DDE # 0 +0x0000D3B1 0x86CB # 0 +0x0000D3B2 0x8892 # 0 +0x0000D3B3 0x9132 # 0 +0x0000D3B4 0x935B # 0 +0x0000D3B5 0x64BB # 0 +0x0000D3B6 0x6FBE # 0 +0x0000D3B7 0x737A # 0 +0x0000D3B8 0x75B8 # 0 +0x0000D3B9 0x9054 # 0 +0x0000D3BA 0x5556 # 0 +0x0000D3BB 0x574D # 0 +0x0000D3BC 0x61BA # 0 +0x0000D3BD 0x64D4 # 0 +0x0000D3BE 0x66C7 # 0 +0x0000D3BF 0x6DE1 # 0 +0x0000D3C0 0x6E5B # 0 +0x0000D3C1 0x6F6D # 0 +0x0000D3C2 0x6FB9 # 0 +0x0000D3C3 0x75F0 # 0 +0x0000D3C4 0x8043 # 0 +0x0000D3C5 0x81BD # 0 +0x0000D3C6 0x8541 # 0 +0x0000D3C7 0x8983 # 0 +0x0000D3C8 0x8AC7 # 0 +0x0000D3C9 0x8B5A # 0 +0x0000D3CA 0x931F # 0 +0x0000D3CB 0x6C93 # 0 +0x0000D3CC 0x7553 # 0 +0x0000D3CD 0x7B54 # 0 +0x0000D3CE 0x8E0F # 0 +0x0000D3CF 0x905D # 0 +0x0000D3D0 0x5510 # 0 +0x0000D3D1 0x5802 # 0 +0x0000D3D2 0x5858 # 0 +0x0000D3D3 0x5E62 # 0 +0x0000D3D4 0x6207 # 0 +0x0000D3D5 0x649E # 0 +0x0000D3D6 0x68E0 # 0 +0x0000D3D7 0x7576 # 0 +0x0000D3D8 0x7CD6 # 0 +0x0000D3D9 0x87B3 # 0 +0x0000D3DA 0x9EE8 # 0 +0x0000D3DB 0x4EE3 # 0 +0x0000D3DC 0x5788 # 0 +0x0000D3DD 0x576E # 0 +0x0000D3DE 0x5927 # 0 +0x0000D3DF 0x5C0D # 0 +0x0000D3E0 0x5CB1 # 0 +0x0000D3E1 0x5E36 # 0 +0x0000D3E2 0x5F85 # 0 +0x0000D3E3 0x6234 # 0 +0x0000D3E4 0x64E1 # 0 +0x0000D3E5 0x73B3 # 0 +0x0000D3E6 0x81FA # 0 +0x0000D3E7 0x888B # 0 +0x0000D3E8 0x8CB8 # 0 +0x0000D3E9 0x968A # 0 +0x0000D3EA 0x9EDB # 0 +0x0000D3EB 0x5B85 # 0 +0x0000D3EC 0x5FB7 # 0 +0x0000D3ED 0x60B3 # 0 +0x0000D3EE 0x5012 # 0 +0x0000D3EF 0x5200 # 0 +0x0000D3F0 0x5230 # 0 +0x0000D3F1 0x5716 # 0 +0x0000D3F2 0x5835 # 0 +0x0000D3F3 0x5857 # 0 +0x0000D3F4 0x5C0E # 0 +0x0000D3F5 0x5C60 # 0 +0x0000D3F6 0x5CF6 # 0 +0x0000D3F7 0x5D8B # 0 +0x0000D3F8 0x5EA6 # 0 +0x0000D3F9 0x5F92 # 0 +0x0000D3FA 0x60BC # 0 +0x0000D3FB 0x6311 # 0 +0x0000D3FC 0x6389 # 0 +0x0000D3FD 0x6417 # 0 +0x0000D3FE 0x6843 # 0 +0x0000D4A1 0x68F9 # 0 +0x0000D4A2 0x6AC2 # 0 +0x0000D4A3 0x6DD8 # 0 +0x0000D4A4 0x6E21 # 0 +0x0000D4A5 0x6ED4 # 0 +0x0000D4A6 0x6FE4 # 0 +0x0000D4A7 0x71FE # 0 +0x0000D4A8 0x76DC # 0 +0x0000D4A9 0x7779 # 0 +0x0000D4AA 0x79B1 # 0 +0x0000D4AB 0x7A3B # 0 +0x0000D4AC 0x8404 # 0 +0x0000D4AD 0x89A9 # 0 +0x0000D4AE 0x8CED # 0 +0x0000D4AF 0x8DF3 # 0 +0x0000D4B0 0x8E48 # 0 +0x0000D4B1 0x9003 # 0 +0x0000D4B2 0x9014 # 0 +0x0000D4B3 0x9053 # 0 +0x0000D4B4 0x90FD # 0 +0x0000D4B5 0x934D # 0 +0x0000D4B6 0x9676 # 0 +0x0000D4B7 0x97DC # 0 +0x0000D4B8 0x6BD2 # 0 +0x0000D4B9 0x7006 # 0 +0x0000D4BA 0x7258 # 0 +0x0000D4BB 0x72A2 # 0 +0x0000D4BC 0x7368 # 0 +0x0000D4BD 0x7763 # 0 +0x0000D4BE 0x79BF # 0 +0x0000D4BF 0x7BE4 # 0 +0x0000D4C0 0x7E9B # 0 +0x0000D4C1 0x8B80 # 0 +0x0000D4C2 0x58A9 # 0 +0x0000D4C3 0x60C7 # 0 +0x0000D4C4 0x6566 # 0 +0x0000D4C5 0x65FD # 0 +0x0000D4C6 0x66BE # 0 +0x0000D4C7 0x6C8C # 0 +0x0000D4C8 0x711E # 0 +0x0000D4C9 0x71C9 # 0 +0x0000D4CA 0x8C5A # 0 +0x0000D4CB 0x9813 # 0 +0x0000D4CC 0x4E6D # 0 +0x0000D4CD 0x7A81 # 0 +0x0000D4CE 0x4EDD # 0 +0x0000D4CF 0x51AC # 0 +0x0000D4D0 0x51CD # 0 +0x0000D4D1 0x52D5 # 0 +0x0000D4D2 0x540C # 0 +0x0000D4D3 0x61A7 # 0 +0x0000D4D4 0x6771 # 0 +0x0000D4D5 0x6850 # 0 +0x0000D4D6 0x68DF # 0 +0x0000D4D7 0x6D1E # 0 +0x0000D4D8 0x6F7C # 0 +0x0000D4D9 0x75BC # 0 +0x0000D4DA 0x77B3 # 0 +0x0000D4DB 0x7AE5 # 0 +0x0000D4DC 0x80F4 # 0 +0x0000D4DD 0x8463 # 0 +0x0000D4DE 0x9285 # 0 +0x0000D4DF 0x515C # 0 +0x0000D4E0 0x6597 # 0 +0x0000D4E1 0x675C # 0 +0x0000D4E2 0x6793 # 0 +0x0000D4E3 0x75D8 # 0 +0x0000D4E4 0x7AC7 # 0 +0x0000D4E5 0x8373 # 0 +0x0000D4E6 0xF95A # 0 +0x0000D4E7 0x8C46 # 0 +0x0000D4E8 0x9017 # 0 +0x0000D4E9 0x982D # 0 +0x0000D4EA 0x5C6F # 0 +0x0000D4EB 0x81C0 # 0 +0x0000D4EC 0x829A # 0 +0x0000D4ED 0x9041 # 0 +0x0000D4EE 0x906F # 0 +0x0000D4EF 0x920D # 0 +0x0000D4F0 0x5F97 # 0 +0x0000D4F1 0x5D9D # 0 +0x0000D4F2 0x6A59 # 0 +0x0000D4F3 0x71C8 # 0 +0x0000D4F4 0x767B # 0 +0x0000D4F5 0x7B49 # 0 +0x0000D4F6 0x85E4 # 0 +0x0000D4F7 0x8B04 # 0 +0x0000D4F8 0x9127 # 0 +0x0000D4F9 0x9A30 # 0 +0x0000D4FA 0x5587 # 0 +0x0000D4FB 0x61F6 # 0 +0x0000D4FC 0xF95B # 0 +0x0000D4FD 0x7669 # 0 +0x0000D4FE 0x7F85 # 0 +0x0000D5A1 0x863F # 0 +0x0000D5A2 0x87BA # 0 +0x0000D5A3 0x88F8 # 0 +0x0000D5A4 0x908F # 0 +0x0000D5A5 0xF95C # 0 +0x0000D5A6 0x6D1B # 0 +0x0000D5A7 0x70D9 # 0 +0x0000D5A8 0x73DE # 0 +0x0000D5A9 0x7D61 # 0 +0x0000D5AA 0x843D # 0 +0x0000D5AB 0xF95D # 0 +0x0000D5AC 0x916A # 0 +0x0000D5AD 0x99F1 # 0 +0x0000D5AE 0xF95E # 0 +0x0000D5AF 0x4E82 # 0 +0x0000D5B0 0x5375 # 0 +0x0000D5B1 0x6B04 # 0 +0x0000D5B2 0x6B12 # 0 +0x0000D5B3 0x703E # 0 +0x0000D5B4 0x721B # 0 +0x0000D5B5 0x862D # 0 +0x0000D5B6 0x9E1E # 0 +0x0000D5B7 0x524C # 0 +0x0000D5B8 0x8FA3 # 0 +0x0000D5B9 0x5D50 # 0 +0x0000D5BA 0x64E5 # 0 +0x0000D5BB 0x652C # 0 +0x0000D5BC 0x6B16 # 0 +0x0000D5BD 0x6FEB # 0 +0x0000D5BE 0x7C43 # 0 +0x0000D5BF 0x7E9C # 0 +0x0000D5C0 0x85CD # 0 +0x0000D5C1 0x8964 # 0 +0x0000D5C2 0x89BD # 0 +0x0000D5C3 0x62C9 # 0 +0x0000D5C4 0x81D8 # 0 +0x0000D5C5 0x881F # 0 +0x0000D5C6 0x5ECA # 0 +0x0000D5C7 0x6717 # 0 +0x0000D5C8 0x6D6A # 0 +0x0000D5C9 0x72FC # 0 +0x0000D5CA 0x7405 # 0 +0x0000D5CB 0x746F # 0 +0x0000D5CC 0x8782 # 0 +0x0000D5CD 0x90DE # 0 +0x0000D5CE 0x4F86 # 0 +0x0000D5CF 0x5D0D # 0 +0x0000D5D0 0x5FA0 # 0 +0x0000D5D1 0x840A # 0 +0x0000D5D2 0x51B7 # 0 +0x0000D5D3 0x63A0 # 0 +0x0000D5D4 0x7565 # 0 +0x0000D5D5 0x4EAE # 0 +0x0000D5D6 0x5006 # 0 +0x0000D5D7 0x5169 # 0 +0x0000D5D8 0x51C9 # 0 +0x0000D5D9 0x6881 # 0 +0x0000D5DA 0x6A11 # 0 +0x0000D5DB 0x7CAE # 0 +0x0000D5DC 0x7CB1 # 0 +0x0000D5DD 0x7CE7 # 0 +0x0000D5DE 0x826F # 0 +0x0000D5DF 0x8AD2 # 0 +0x0000D5E0 0x8F1B # 0 +0x0000D5E1 0x91CF # 0 +0x0000D5E2 0x4FB6 # 0 +0x0000D5E3 0x5137 # 0 +0x0000D5E4 0x52F5 # 0 +0x0000D5E5 0x5442 # 0 +0x0000D5E6 0x5EEC # 0 +0x0000D5E7 0x616E # 0 +0x0000D5E8 0x623E # 0 +0x0000D5E9 0x65C5 # 0 +0x0000D5EA 0x6ADA # 0 +0x0000D5EB 0x6FFE # 0 +0x0000D5EC 0x792A # 0 +0x0000D5ED 0x85DC # 0 +0x0000D5EE 0x8823 # 0 +0x0000D5EF 0x95AD # 0 +0x0000D5F0 0x9A62 # 0 +0x0000D5F1 0x9A6A # 0 +0x0000D5F2 0x9E97 # 0 +0x0000D5F3 0x9ECE # 0 +0x0000D5F4 0x529B # 0 +0x0000D5F5 0x66C6 # 0 +0x0000D5F6 0x6B77 # 0 +0x0000D5F7 0x701D # 0 +0x0000D5F8 0x792B # 0 +0x0000D5F9 0x8F62 # 0 +0x0000D5FA 0x9742 # 0 +0x0000D5FB 0x6190 # 0 +0x0000D5FC 0x6200 # 0 +0x0000D5FD 0x6523 # 0 +0x0000D5FE 0x6F23 # 0 +0x0000D6A1 0x7149 # 0 +0x0000D6A2 0x7489 # 0 +0x0000D6A3 0x7DF4 # 0 +0x0000D6A4 0x806F # 0 +0x0000D6A5 0x84EE # 0 +0x0000D6A6 0x8F26 # 0 +0x0000D6A7 0x9023 # 0 +0x0000D6A8 0x934A # 0 +0x0000D6A9 0x51BD # 0 +0x0000D6AA 0x5217 # 0 +0x0000D6AB 0x52A3 # 0 +0x0000D6AC 0x6D0C # 0 +0x0000D6AD 0x70C8 # 0 +0x0000D6AE 0x88C2 # 0 +0x0000D6AF 0x5EC9 # 0 +0x0000D6B0 0x6582 # 0 +0x0000D6B1 0x6BAE # 0 +0x0000D6B2 0x6FC2 # 0 +0x0000D6B3 0x7C3E # 0 +0x0000D6B4 0x7375 # 0 +0x0000D6B5 0x4EE4 # 0 +0x0000D6B6 0x4F36 # 0 +0x0000D6B7 0x56F9 # 0 +0x0000D6B8 0xF95F # 0 +0x0000D6B9 0x5CBA # 0 +0x0000D6BA 0x5DBA # 0 +0x0000D6BB 0x601C # 0 +0x0000D6BC 0x73B2 # 0 +0x0000D6BD 0x7B2D # 0 +0x0000D6BE 0x7F9A # 0 +0x0000D6BF 0x7FCE # 0 +0x0000D6C0 0x8046 # 0 +0x0000D6C1 0x901E # 0 +0x0000D6C2 0x9234 # 0 +0x0000D6C3 0x96F6 # 0 +0x0000D6C4 0x9748 # 0 +0x0000D6C5 0x9818 # 0 +0x0000D6C6 0x9F61 # 0 +0x0000D6C7 0x4F8B # 0 +0x0000D6C8 0x6FA7 # 0 +0x0000D6C9 0x79AE # 0 +0x0000D6CA 0x91B4 # 0 +0x0000D6CB 0x96B7 # 0 +0x0000D6CC 0x52DE # 0 +0x0000D6CD 0xF960 # 0 +0x0000D6CE 0x6488 # 0 +0x0000D6CF 0x64C4 # 0 +0x0000D6D0 0x6AD3 # 0 +0x0000D6D1 0x6F5E # 0 +0x0000D6D2 0x7018 # 0 +0x0000D6D3 0x7210 # 0 +0x0000D6D4 0x76E7 # 0 +0x0000D6D5 0x8001 # 0 +0x0000D6D6 0x8606 # 0 +0x0000D6D7 0x865C # 0 +0x0000D6D8 0x8DEF # 0 +0x0000D6D9 0x8F05 # 0 +0x0000D6DA 0x9732 # 0 +0x0000D6DB 0x9B6F # 0 +0x0000D6DC 0x9DFA # 0 +0x0000D6DD 0x9E75 # 0 +0x0000D6DE 0x788C # 0 +0x0000D6DF 0x797F # 0 +0x0000D6E0 0x7DA0 # 0 +0x0000D6E1 0x83C9 # 0 +0x0000D6E2 0x9304 # 0 +0x0000D6E3 0x9E7F # 0 +0x0000D6E4 0x9E93 # 0 +0x0000D6E5 0x8AD6 # 0 +0x0000D6E6 0x58DF # 0 +0x0000D6E7 0x5F04 # 0 +0x0000D6E8 0x6727 # 0 +0x0000D6E9 0x7027 # 0 +0x0000D6EA 0x74CF # 0 +0x0000D6EB 0x7C60 # 0 +0x0000D6EC 0x807E # 0 +0x0000D6ED 0x5121 # 0 +0x0000D6EE 0x7028 # 0 +0x0000D6EF 0x7262 # 0 +0x0000D6F0 0x78CA # 0 +0x0000D6F1 0x8CC2 # 0 +0x0000D6F2 0x8CDA # 0 +0x0000D6F3 0x8CF4 # 0 +0x0000D6F4 0x96F7 # 0 +0x0000D6F5 0x4E86 # 0 +0x0000D6F6 0x50DA # 0 +0x0000D6F7 0x5BEE # 0 +0x0000D6F8 0x5ED6 # 0 +0x0000D6F9 0x6599 # 0 +0x0000D6FA 0x71CE # 0 +0x0000D6FB 0x7642 # 0 +0x0000D6FC 0x77AD # 0 +0x0000D6FD 0x804A # 0 +0x0000D6FE 0x84FC # 0 +0x0000D7A1 0x907C # 0 +0x0000D7A2 0x9B27 # 0 +0x0000D7A3 0x9F8D # 0 +0x0000D7A4 0x58D8 # 0 +0x0000D7A5 0x5A41 # 0 +0x0000D7A6 0x5C62 # 0 +0x0000D7A7 0x6A13 # 0 +0x0000D7A8 0x6DDA # 0 +0x0000D7A9 0x6F0F # 0 +0x0000D7AA 0x763B # 0 +0x0000D7AB 0x7D2F # 0 +0x0000D7AC 0x7E37 # 0 +0x0000D7AD 0x851E # 0 +0x0000D7AE 0x8938 # 0 +0x0000D7AF 0x93E4 # 0 +0x0000D7B0 0x964B # 0 +0x0000D7B1 0x5289 # 0 +0x0000D7B2 0x65D2 # 0 +0x0000D7B3 0x67F3 # 0 +0x0000D7B4 0x69B4 # 0 +0x0000D7B5 0x6D41 # 0 +0x0000D7B6 0x6E9C # 0 +0x0000D7B7 0x700F # 0 +0x0000D7B8 0x7409 # 0 +0x0000D7B9 0x7460 # 0 +0x0000D7BA 0x7559 # 0 +0x0000D7BB 0x7624 # 0 +0x0000D7BC 0x786B # 0 +0x0000D7BD 0x8B2C # 0 +0x0000D7BE 0x985E # 0 +0x0000D7BF 0x516D # 0 +0x0000D7C0 0x622E # 0 +0x0000D7C1 0x9678 # 0 +0x0000D7C2 0x4F96 # 0 +0x0000D7C3 0x502B # 0 +0x0000D7C4 0x5D19 # 0 +0x0000D7C5 0x6DEA # 0 +0x0000D7C6 0x7DB8 # 0 +0x0000D7C7 0x8F2A # 0 +0x0000D7C8 0x5F8B # 0 +0x0000D7C9 0x6144 # 0 +0x0000D7CA 0x6817 # 0 +0x0000D7CB 0xF961 # 0 +0x0000D7CC 0x9686 # 0 +0x0000D7CD 0x52D2 # 0 +0x0000D7CE 0x808B # 0 +0x0000D7CF 0x51DC # 0 +0x0000D7D0 0x51CC # 0 +0x0000D7D1 0x695E # 0 +0x0000D7D2 0x7A1C # 0 +0x0000D7D3 0x7DBE # 0 +0x0000D7D4 0x83F1 # 0 +0x0000D7D5 0x9675 # 0 +0x0000D7D6 0x4FDA # 0 +0x0000D7D7 0x5229 # 0 +0x0000D7D8 0x5398 # 0 +0x0000D7D9 0x540F # 0 +0x0000D7DA 0x550E # 0 +0x0000D7DB 0x5C65 # 0 +0x0000D7DC 0x60A7 # 0 +0x0000D7DD 0x674E # 0 +0x0000D7DE 0x68A8 # 0 +0x0000D7DF 0x6D6C # 0 +0x0000D7E0 0x7281 # 0 +0x0000D7E1 0x72F8 # 0 +0x0000D7E2 0x7406 # 0 +0x0000D7E3 0x7483 # 0 +0x0000D7E4 0xF962 # 0 +0x0000D7E5 0x75E2 # 0 +0x0000D7E6 0x7C6C # 0 +0x0000D7E7 0x7F79 # 0 +0x0000D7E8 0x7FB8 # 0 +0x0000D7E9 0x8389 # 0 +0x0000D7EA 0x88CF # 0 +0x0000D7EB 0x88E1 # 0 +0x0000D7EC 0x91CC # 0 +0x0000D7ED 0x91D0 # 0 +0x0000D7EE 0x96E2 # 0 +0x0000D7EF 0x9BC9 # 0 +0x0000D7F0 0x541D # 0 +0x0000D7F1 0x6F7E # 0 +0x0000D7F2 0x71D0 # 0 +0x0000D7F3 0x7498 # 0 +0x0000D7F4 0x85FA # 0 +0x0000D7F5 0x8EAA # 0 +0x0000D7F6 0x96A3 # 0 +0x0000D7F7 0x9C57 # 0 +0x0000D7F8 0x9E9F # 0 +0x0000D7F9 0x6797 # 0 +0x0000D7FA 0x6DCB # 0 +0x0000D7FB 0x7433 # 0 +0x0000D7FC 0x81E8 # 0 +0x0000D7FD 0x9716 # 0 +0x0000D7FE 0x782C # 0 +0x0000D8A1 0x7ACB # 0 +0x0000D8A2 0x7B20 # 0 +0x0000D8A3 0x7C92 # 0 +0x0000D8A4 0x6469 # 0 +0x0000D8A5 0x746A # 0 +0x0000D8A6 0x75F2 # 0 +0x0000D8A7 0x78BC # 0 +0x0000D8A8 0x78E8 # 0 +0x0000D8A9 0x99AC # 0 +0x0000D8AA 0x9B54 # 0 +0x0000D8AB 0x9EBB # 0 +0x0000D8AC 0x5BDE # 0 +0x0000D8AD 0x5E55 # 0 +0x0000D8AE 0x6F20 # 0 +0x0000D8AF 0x819C # 0 +0x0000D8B0 0x83AB # 0 +0x0000D8B1 0x9088 # 0 +0x0000D8B2 0x4E07 # 0 +0x0000D8B3 0x534D # 0 +0x0000D8B4 0x5A29 # 0 +0x0000D8B5 0x5DD2 # 0 +0x0000D8B6 0x5F4E # 0 +0x0000D8B7 0x6162 # 0 +0x0000D8B8 0x633D # 0 +0x0000D8B9 0x6669 # 0 +0x0000D8BA 0x66FC # 0 +0x0000D8BB 0x6EFF # 0 +0x0000D8BC 0x6F2B # 0 +0x0000D8BD 0x7063 # 0 +0x0000D8BE 0x779E # 0 +0x0000D8BF 0x842C # 0 +0x0000D8C0 0x8513 # 0 +0x0000D8C1 0x883B # 0 +0x0000D8C2 0x8F13 # 0 +0x0000D8C3 0x9945 # 0 +0x0000D8C4 0x9C3B # 0 +0x0000D8C5 0x551C # 0 +0x0000D8C6 0x62B9 # 0 +0x0000D8C7 0x672B # 0 +0x0000D8C8 0x6CAB # 0 +0x0000D8C9 0x8309 # 0 +0x0000D8CA 0x896A # 0 +0x0000D8CB 0x977A # 0 +0x0000D8CC 0x4EA1 # 0 +0x0000D8CD 0x5984 # 0 +0x0000D8CE 0x5FD8 # 0 +0x0000D8CF 0x5FD9 # 0 +0x0000D8D0 0x671B # 0 +0x0000D8D1 0x7DB2 # 0 +0x0000D8D2 0x7F54 # 0 +0x0000D8D3 0x8292 # 0 +0x0000D8D4 0x832B # 0 +0x0000D8D5 0x83BD # 0 +0x0000D8D6 0x8F1E # 0 +0x0000D8D7 0x9099 # 0 +0x0000D8D8 0x57CB # 0 +0x0000D8D9 0x59B9 # 0 +0x0000D8DA 0x5A92 # 0 +0x0000D8DB 0x5BD0 # 0 +0x0000D8DC 0x6627 # 0 +0x0000D8DD 0x679A # 0 +0x0000D8DE 0x6885 # 0 +0x0000D8DF 0x6BCF # 0 +0x0000D8E0 0x7164 # 0 +0x0000D8E1 0x7F75 # 0 +0x0000D8E2 0x8CB7 # 0 +0x0000D8E3 0x8CE3 # 0 +0x0000D8E4 0x9081 # 0 +0x0000D8E5 0x9B45 # 0 +0x0000D8E6 0x8108 # 0 +0x0000D8E7 0x8C8A # 0 +0x0000D8E8 0x964C # 0 +0x0000D8E9 0x9A40 # 0 +0x0000D8EA 0x9EA5 # 0 +0x0000D8EB 0x5B5F # 0 +0x0000D8EC 0x6C13 # 0 +0x0000D8ED 0x731B # 0 +0x0000D8EE 0x76F2 # 0 +0x0000D8EF 0x76DF # 0 +0x0000D8F0 0x840C # 0 +0x0000D8F1 0x51AA # 0 +0x0000D8F2 0x8993 # 0 +0x0000D8F3 0x514D # 0 +0x0000D8F4 0x5195 # 0 +0x0000D8F5 0x52C9 # 0 +0x0000D8F6 0x68C9 # 0 +0x0000D8F7 0x6C94 # 0 +0x0000D8F8 0x7704 # 0 +0x0000D8F9 0x7720 # 0 +0x0000D8FA 0x7DBF # 0 +0x0000D8FB 0x7DEC # 0 +0x0000D8FC 0x9762 # 0 +0x0000D8FD 0x9EB5 # 0 +0x0000D8FE 0x6EC5 # 0 +0x0000D9A1 0x8511 # 0 +0x0000D9A2 0x51A5 # 0 +0x0000D9A3 0x540D # 0 +0x0000D9A4 0x547D # 0 +0x0000D9A5 0x660E # 0 +0x0000D9A6 0x669D # 0 +0x0000D9A7 0x6927 # 0 +0x0000D9A8 0x6E9F # 0 +0x0000D9A9 0x76BF # 0 +0x0000D9AA 0x7791 # 0 +0x0000D9AB 0x8317 # 0 +0x0000D9AC 0x84C2 # 0 +0x0000D9AD 0x879F # 0 +0x0000D9AE 0x9169 # 0 +0x0000D9AF 0x9298 # 0 +0x0000D9B0 0x9CF4 # 0 +0x0000D9B1 0x8882 # 0 +0x0000D9B2 0x4FAE # 0 +0x0000D9B3 0x5192 # 0 +0x0000D9B4 0x52DF # 0 +0x0000D9B5 0x59C6 # 0 +0x0000D9B6 0x5E3D # 0 +0x0000D9B7 0x6155 # 0 +0x0000D9B8 0x6478 # 0 +0x0000D9B9 0x6479 # 0 +0x0000D9BA 0x66AE # 0 +0x0000D9BB 0x67D0 # 0 +0x0000D9BC 0x6A21 # 0 +0x0000D9BD 0x6BCD # 0 +0x0000D9BE 0x6BDB # 0 +0x0000D9BF 0x725F # 0 +0x0000D9C0 0x7261 # 0 +0x0000D9C1 0x7441 # 0 +0x0000D9C2 0x7738 # 0 +0x0000D9C3 0x77DB # 0 +0x0000D9C4 0x8017 # 0 +0x0000D9C5 0x82BC # 0 +0x0000D9C6 0x8305 # 0 +0x0000D9C7 0x8B00 # 0 +0x0000D9C8 0x8B28 # 0 +0x0000D9C9 0x8C8C # 0 +0x0000D9CA 0x6728 # 0 +0x0000D9CB 0x6C90 # 0 +0x0000D9CC 0x7267 # 0 +0x0000D9CD 0x76EE # 0 +0x0000D9CE 0x7766 # 0 +0x0000D9CF 0x7A46 # 0 +0x0000D9D0 0x9DA9 # 0 +0x0000D9D1 0x6B7F # 0 +0x0000D9D2 0x6C92 # 0 +0x0000D9D3 0x5922 # 0 +0x0000D9D4 0x6726 # 0 +0x0000D9D5 0x8499 # 0 +0x0000D9D6 0x536F # 0 +0x0000D9D7 0x5893 # 0 +0x0000D9D8 0x5999 # 0 +0x0000D9D9 0x5EDF # 0 +0x0000D9DA 0x63CF # 0 +0x0000D9DB 0x6634 # 0 +0x0000D9DC 0x6773 # 0 +0x0000D9DD 0x6E3A # 0 +0x0000D9DE 0x732B # 0 +0x0000D9DF 0x7AD7 # 0 +0x0000D9E0 0x82D7 # 0 +0x0000D9E1 0x9328 # 0 +0x0000D9E2 0x52D9 # 0 +0x0000D9E3 0x5DEB # 0 +0x0000D9E4 0x61AE # 0 +0x0000D9E5 0x61CB # 0 +0x0000D9E6 0x620A # 0 +0x0000D9E7 0x62C7 # 0 +0x0000D9E8 0x64AB # 0 +0x0000D9E9 0x65E0 # 0 +0x0000D9EA 0x6959 # 0 +0x0000D9EB 0x6B66 # 0 +0x0000D9EC 0x6BCB # 0 +0x0000D9ED 0x7121 # 0 +0x0000D9EE 0x73F7 # 0 +0x0000D9EF 0x755D # 0 +0x0000D9F0 0x7E46 # 0 +0x0000D9F1 0x821E # 0 +0x0000D9F2 0x8302 # 0 +0x0000D9F3 0x856A # 0 +0x0000D9F4 0x8AA3 # 0 +0x0000D9F5 0x8CBF # 0 +0x0000D9F6 0x9727 # 0 +0x0000D9F7 0x9D61 # 0 +0x0000D9F8 0x58A8 # 0 +0x0000D9F9 0x9ED8 # 0 +0x0000D9FA 0x5011 # 0 +0x0000D9FB 0x520E # 0 +0x0000D9FC 0x543B # 0 +0x0000D9FD 0x554F # 0 +0x0000D9FE 0x6587 # 0 +0x0000DAA1 0x6C76 # 0 +0x0000DAA2 0x7D0A # 0 +0x0000DAA3 0x7D0B # 0 +0x0000DAA4 0x805E # 0 +0x0000DAA5 0x868A # 0 +0x0000DAA6 0x9580 # 0 +0x0000DAA7 0x96EF # 0 +0x0000DAA8 0x52FF # 0 +0x0000DAA9 0x6C95 # 0 +0x0000DAAA 0x7269 # 0 +0x0000DAAB 0x5473 # 0 +0x0000DAAC 0x5A9A # 0 +0x0000DAAD 0x5C3E # 0 +0x0000DAAE 0x5D4B # 0 +0x0000DAAF 0x5F4C # 0 +0x0000DAB0 0x5FAE # 0 +0x0000DAB1 0x672A # 0 +0x0000DAB2 0x68B6 # 0 +0x0000DAB3 0x6963 # 0 +0x0000DAB4 0x6E3C # 0 +0x0000DAB5 0x6E44 # 0 +0x0000DAB6 0x7709 # 0 +0x0000DAB7 0x7C73 # 0 +0x0000DAB8 0x7F8E # 0 +0x0000DAB9 0x8587 # 0 +0x0000DABA 0x8B0E # 0 +0x0000DABB 0x8FF7 # 0 +0x0000DABC 0x9761 # 0 +0x0000DABD 0x9EF4 # 0 +0x0000DABE 0x5CB7 # 0 +0x0000DABF 0x60B6 # 0 +0x0000DAC0 0x610D # 0 +0x0000DAC1 0x61AB # 0 +0x0000DAC2 0x654F # 0 +0x0000DAC3 0x65FB # 0 +0x0000DAC4 0x65FC # 0 +0x0000DAC5 0x6C11 # 0 +0x0000DAC6 0x6CEF # 0 +0x0000DAC7 0x739F # 0 +0x0000DAC8 0x73C9 # 0 +0x0000DAC9 0x7DE1 # 0 +0x0000DACA 0x9594 # 0 +0x0000DACB 0x5BC6 # 0 +0x0000DACC 0x871C # 0 +0x0000DACD 0x8B10 # 0 +0x0000DACE 0x525D # 0 +0x0000DACF 0x535A # 0 +0x0000DAD0 0x62CD # 0 +0x0000DAD1 0x640F # 0 +0x0000DAD2 0x64B2 # 0 +0x0000DAD3 0x6734 # 0 +0x0000DAD4 0x6A38 # 0 +0x0000DAD5 0x6CCA # 0 +0x0000DAD6 0x73C0 # 0 +0x0000DAD7 0x749E # 0 +0x0000DAD8 0x7B94 # 0 +0x0000DAD9 0x7C95 # 0 +0x0000DADA 0x7E1B # 0 +0x0000DADB 0x818A # 0 +0x0000DADC 0x8236 # 0 +0x0000DADD 0x8584 # 0 +0x0000DADE 0x8FEB # 0 +0x0000DADF 0x96F9 # 0 +0x0000DAE0 0x99C1 # 0 +0x0000DAE1 0x4F34 # 0 +0x0000DAE2 0x534A # 0 +0x0000DAE3 0x53CD # 0 +0x0000DAE4 0x53DB # 0 +0x0000DAE5 0x62CC # 0 +0x0000DAE6 0x642C # 0 +0x0000DAE7 0x6500 # 0 +0x0000DAE8 0x6591 # 0 +0x0000DAE9 0x69C3 # 0 +0x0000DAEA 0x6CEE # 0 +0x0000DAEB 0x6F58 # 0 +0x0000DAEC 0x73ED # 0 +0x0000DAED 0x7554 # 0 +0x0000DAEE 0x7622 # 0 +0x0000DAEF 0x76E4 # 0 +0x0000DAF0 0x76FC # 0 +0x0000DAF1 0x78D0 # 0 +0x0000DAF2 0x78FB # 0 +0x0000DAF3 0x792C # 0 +0x0000DAF4 0x7D46 # 0 +0x0000DAF5 0x822C # 0 +0x0000DAF6 0x87E0 # 0 +0x0000DAF7 0x8FD4 # 0 +0x0000DAF8 0x9812 # 0 +0x0000DAF9 0x98EF # 0 +0x0000DAFA 0x52C3 # 0 +0x0000DAFB 0x62D4 # 0 +0x0000DAFC 0x64A5 # 0 +0x0000DAFD 0x6E24 # 0 +0x0000DAFE 0x6F51 # 0 +0x0000DBA1 0x767C # 0 +0x0000DBA2 0x8DCB # 0 +0x0000DBA3 0x91B1 # 0 +0x0000DBA4 0x9262 # 0 +0x0000DBA5 0x9AEE # 0 +0x0000DBA6 0x9B43 # 0 +0x0000DBA7 0x5023 # 0 +0x0000DBA8 0x508D # 0 +0x0000DBA9 0x574A # 0 +0x0000DBAA 0x59A8 # 0 +0x0000DBAB 0x5C28 # 0 +0x0000DBAC 0x5E47 # 0 +0x0000DBAD 0x5F77 # 0 +0x0000DBAE 0x623F # 0 +0x0000DBAF 0x653E # 0 +0x0000DBB0 0x65B9 # 0 +0x0000DBB1 0x65C1 # 0 +0x0000DBB2 0x6609 # 0 +0x0000DBB3 0x678B # 0 +0x0000DBB4 0x699C # 0 +0x0000DBB5 0x6EC2 # 0 +0x0000DBB6 0x78C5 # 0 +0x0000DBB7 0x7D21 # 0 +0x0000DBB8 0x80AA # 0 +0x0000DBB9 0x8180 # 0 +0x0000DBBA 0x822B # 0 +0x0000DBBB 0x82B3 # 0 +0x0000DBBC 0x84A1 # 0 +0x0000DBBD 0x868C # 0 +0x0000DBBE 0x8A2A # 0 +0x0000DBBF 0x8B17 # 0 +0x0000DBC0 0x90A6 # 0 +0x0000DBC1 0x9632 # 0 +0x0000DBC2 0x9F90 # 0 +0x0000DBC3 0x500D # 0 +0x0000DBC4 0x4FF3 # 0 +0x0000DBC5 0xF963 # 0 +0x0000DBC6 0x57F9 # 0 +0x0000DBC7 0x5F98 # 0 +0x0000DBC8 0x62DC # 0 +0x0000DBC9 0x6392 # 0 +0x0000DBCA 0x676F # 0 +0x0000DBCB 0x6E43 # 0 +0x0000DBCC 0x7119 # 0 +0x0000DBCD 0x76C3 # 0 +0x0000DBCE 0x80CC # 0 +0x0000DBCF 0x80DA # 0 +0x0000DBD0 0x88F4 # 0 +0x0000DBD1 0x88F5 # 0 +0x0000DBD2 0x8919 # 0 +0x0000DBD3 0x8CE0 # 0 +0x0000DBD4 0x8F29 # 0 +0x0000DBD5 0x914D # 0 +0x0000DBD6 0x966A # 0 +0x0000DBD7 0x4F2F # 0 +0x0000DBD8 0x4F70 # 0 +0x0000DBD9 0x5E1B # 0 +0x0000DBDA 0x67CF # 0 +0x0000DBDB 0x6822 # 0 +0x0000DBDC 0x767D # 0 +0x0000DBDD 0x767E # 0 +0x0000DBDE 0x9B44 # 0 +0x0000DBDF 0x5E61 # 0 +0x0000DBE0 0x6A0A # 0 +0x0000DBE1 0x7169 # 0 +0x0000DBE2 0x71D4 # 0 +0x0000DBE3 0x756A # 0 +0x0000DBE4 0xF964 # 0 +0x0000DBE5 0x7E41 # 0 +0x0000DBE6 0x8543 # 0 +0x0000DBE7 0x85E9 # 0 +0x0000DBE8 0x98DC # 0 +0x0000DBE9 0x4F10 # 0 +0x0000DBEA 0x7B4F # 0 +0x0000DBEB 0x7F70 # 0 +0x0000DBEC 0x95A5 # 0 +0x0000DBED 0x51E1 # 0 +0x0000DBEE 0x5E06 # 0 +0x0000DBEF 0x68B5 # 0 +0x0000DBF0 0x6C3E # 0 +0x0000DBF1 0x6C4E # 0 +0x0000DBF2 0x6CDB # 0 +0x0000DBF3 0x72AF # 0 +0x0000DBF4 0x7BC4 # 0 +0x0000DBF5 0x8303 # 0 +0x0000DBF6 0x6CD5 # 0 +0x0000DBF7 0x743A # 0 +0x0000DBF8 0x50FB # 0 +0x0000DBF9 0x5288 # 0 +0x0000DBFA 0x58C1 # 0 +0x0000DBFB 0x64D8 # 0 +0x0000DBFC 0x6A97 # 0 +0x0000DBFD 0x74A7 # 0 +0x0000DBFE 0x7656 # 0 +0x0000DCA1 0x78A7 # 0 +0x0000DCA2 0x8617 # 0 +0x0000DCA3 0x95E2 # 0 +0x0000DCA4 0x9739 # 0 +0x0000DCA5 0xF965 # 0 +0x0000DCA6 0x535E # 0 +0x0000DCA7 0x5F01 # 0 +0x0000DCA8 0x8B8A # 0 +0x0000DCA9 0x8FA8 # 0 +0x0000DCAA 0x8FAF # 0 +0x0000DCAB 0x908A # 0 +0x0000DCAC 0x5225 # 0 +0x0000DCAD 0x77A5 # 0 +0x0000DCAE 0x9C49 # 0 +0x0000DCAF 0x9F08 # 0 +0x0000DCB0 0x4E19 # 0 +0x0000DCB1 0x5002 # 0 +0x0000DCB2 0x5175 # 0 +0x0000DCB3 0x5C5B # 0 +0x0000DCB4 0x5E77 # 0 +0x0000DCB5 0x661E # 0 +0x0000DCB6 0x663A # 0 +0x0000DCB7 0x67C4 # 0 +0x0000DCB8 0x68C5 # 0 +0x0000DCB9 0x70B3 # 0 +0x0000DCBA 0x7501 # 0 +0x0000DCBB 0x75C5 # 0 +0x0000DCBC 0x79C9 # 0 +0x0000DCBD 0x7ADD # 0 +0x0000DCBE 0x8F27 # 0 +0x0000DCBF 0x9920 # 0 +0x0000DCC0 0x9A08 # 0 +0x0000DCC1 0x4FDD # 0 +0x0000DCC2 0x5821 # 0 +0x0000DCC3 0x5831 # 0 +0x0000DCC4 0x5BF6 # 0 +0x0000DCC5 0x666E # 0 +0x0000DCC6 0x6B65 # 0 +0x0000DCC7 0x6D11 # 0 +0x0000DCC8 0x6E7A # 0 +0x0000DCC9 0x6F7D # 0 +0x0000DCCA 0x73E4 # 0 +0x0000DCCB 0x752B # 0 +0x0000DCCC 0x83E9 # 0 +0x0000DCCD 0x88DC # 0 +0x0000DCCE 0x8913 # 0 +0x0000DCCF 0x8B5C # 0 +0x0000DCD0 0x8F14 # 0 +0x0000DCD1 0x4F0F # 0 +0x0000DCD2 0x50D5 # 0 +0x0000DCD3 0x5310 # 0 +0x0000DCD4 0x535C # 0 +0x0000DCD5 0x5B93 # 0 +0x0000DCD6 0x5FA9 # 0 +0x0000DCD7 0x670D # 0 +0x0000DCD8 0x798F # 0 +0x0000DCD9 0x8179 # 0 +0x0000DCDA 0x832F # 0 +0x0000DCDB 0x8514 # 0 +0x0000DCDC 0x8907 # 0 +0x0000DCDD 0x8986 # 0 +0x0000DCDE 0x8F39 # 0 +0x0000DCDF 0x8F3B # 0 +0x0000DCE0 0x99A5 # 0 +0x0000DCE1 0x9C12 # 0 +0x0000DCE2 0x672C # 0 +0x0000DCE3 0x4E76 # 0 +0x0000DCE4 0x4FF8 # 0 +0x0000DCE5 0x5949 # 0 +0x0000DCE6 0x5C01 # 0 +0x0000DCE7 0x5CEF # 0 +0x0000DCE8 0x5CF0 # 0 +0x0000DCE9 0x6367 # 0 +0x0000DCEA 0x68D2 # 0 +0x0000DCEB 0x70FD # 0 +0x0000DCEC 0x71A2 # 0 +0x0000DCED 0x742B # 0 +0x0000DCEE 0x7E2B # 0 +0x0000DCEF 0x84EC # 0 +0x0000DCF0 0x8702 # 0 +0x0000DCF1 0x9022 # 0 +0x0000DCF2 0x92D2 # 0 +0x0000DCF3 0x9CF3 # 0 +0x0000DCF4 0x4E0D # 0 +0x0000DCF5 0x4ED8 # 0 +0x0000DCF6 0x4FEF # 0 +0x0000DCF7 0x5085 # 0 +0x0000DCF8 0x5256 # 0 +0x0000DCF9 0x526F # 0 +0x0000DCFA 0x5426 # 0 +0x0000DCFB 0x5490 # 0 +0x0000DCFC 0x57E0 # 0 +0x0000DCFD 0x592B # 0 +0x0000DCFE 0x5A66 # 0 +0x0000DDA1 0x5B5A # 0 +0x0000DDA2 0x5B75 # 0 +0x0000DDA3 0x5BCC # 0 +0x0000DDA4 0x5E9C # 0 +0x0000DDA5 0xF966 # 0 +0x0000DDA6 0x6276 # 0 +0x0000DDA7 0x6577 # 0 +0x0000DDA8 0x65A7 # 0 +0x0000DDA9 0x6D6E # 0 +0x0000DDAA 0x6EA5 # 0 +0x0000DDAB 0x7236 # 0 +0x0000DDAC 0x7B26 # 0 +0x0000DDAD 0x7C3F # 0 +0x0000DDAE 0x7F36 # 0 +0x0000DDAF 0x8150 # 0 +0x0000DDB0 0x8151 # 0 +0x0000DDB1 0x819A # 0 +0x0000DDB2 0x8240 # 0 +0x0000DDB3 0x8299 # 0 +0x0000DDB4 0x83A9 # 0 +0x0000DDB5 0x8A03 # 0 +0x0000DDB6 0x8CA0 # 0 +0x0000DDB7 0x8CE6 # 0 +0x0000DDB8 0x8CFB # 0 +0x0000DDB9 0x8D74 # 0 +0x0000DDBA 0x8DBA # 0 +0x0000DDBB 0x90E8 # 0 +0x0000DDBC 0x91DC # 0 +0x0000DDBD 0x961C # 0 +0x0000DDBE 0x9644 # 0 +0x0000DDBF 0x99D9 # 0 +0x0000DDC0 0x9CE7 # 0 +0x0000DDC1 0x5317 # 0 +0x0000DDC2 0x5206 # 0 +0x0000DDC3 0x5429 # 0 +0x0000DDC4 0x5674 # 0 +0x0000DDC5 0x58B3 # 0 +0x0000DDC6 0x5954 # 0 +0x0000DDC7 0x596E # 0 +0x0000DDC8 0x5FFF # 0 +0x0000DDC9 0x61A4 # 0 +0x0000DDCA 0x626E # 0 +0x0000DDCB 0x6610 # 0 +0x0000DDCC 0x6C7E # 0 +0x0000DDCD 0x711A # 0 +0x0000DDCE 0x76C6 # 0 +0x0000DDCF 0x7C89 # 0 +0x0000DDD0 0x7CDE # 0 +0x0000DDD1 0x7D1B # 0 +0x0000DDD2 0x82AC # 0 +0x0000DDD3 0x8CC1 # 0 +0x0000DDD4 0x96F0 # 0 +0x0000DDD5 0xF967 # 0 +0x0000DDD6 0x4F5B # 0 +0x0000DDD7 0x5F17 # 0 +0x0000DDD8 0x5F7F # 0 +0x0000DDD9 0x62C2 # 0 +0x0000DDDA 0x5D29 # 0 +0x0000DDDB 0x670B # 0 +0x0000DDDC 0x68DA # 0 +0x0000DDDD 0x787C # 0 +0x0000DDDE 0x7E43 # 0 +0x0000DDDF 0x9D6C # 0 +0x0000DDE0 0x4E15 # 0 +0x0000DDE1 0x5099 # 0 +0x0000DDE2 0x5315 # 0 +0x0000DDE3 0x532A # 0 +0x0000DDE4 0x5351 # 0 +0x0000DDE5 0x5983 # 0 +0x0000DDE6 0x5A62 # 0 +0x0000DDE7 0x5E87 # 0 +0x0000DDE8 0x60B2 # 0 +0x0000DDE9 0x618A # 0 +0x0000DDEA 0x6249 # 0 +0x0000DDEB 0x6279 # 0 +0x0000DDEC 0x6590 # 0 +0x0000DDED 0x6787 # 0 +0x0000DDEE 0x69A7 # 0 +0x0000DDEF 0x6BD4 # 0 +0x0000DDF0 0x6BD6 # 0 +0x0000DDF1 0x6BD7 # 0 +0x0000DDF2 0x6BD8 # 0 +0x0000DDF3 0x6CB8 # 0 +0x0000DDF4 0xF968 # 0 +0x0000DDF5 0x7435 # 0 +0x0000DDF6 0x75FA # 0 +0x0000DDF7 0x7812 # 0 +0x0000DDF8 0x7891 # 0 +0x0000DDF9 0x79D5 # 0 +0x0000DDFA 0x79D8 # 0 +0x0000DDFB 0x7C83 # 0 +0x0000DDFC 0x7DCB # 0 +0x0000DDFD 0x7FE1 # 0 +0x0000DDFE 0x80A5 # 0 +0x0000DEA1 0x813E # 0 +0x0000DEA2 0x81C2 # 0 +0x0000DEA3 0x83F2 # 0 +0x0000DEA4 0x871A # 0 +0x0000DEA5 0x88E8 # 0 +0x0000DEA6 0x8AB9 # 0 +0x0000DEA7 0x8B6C # 0 +0x0000DEA8 0x8CBB # 0 +0x0000DEA9 0x9119 # 0 +0x0000DEAA 0x975E # 0 +0x0000DEAB 0x98DB # 0 +0x0000DEAC 0x9F3B # 0 +0x0000DEAD 0x56AC # 0 +0x0000DEAE 0x5B2A # 0 +0x0000DEAF 0x5F6C # 0 +0x0000DEB0 0x658C # 0 +0x0000DEB1 0x6AB3 # 0 +0x0000DEB2 0x6BAF # 0 +0x0000DEB3 0x6D5C # 0 +0x0000DEB4 0x6FF1 # 0 +0x0000DEB5 0x7015 # 0 +0x0000DEB6 0x725D # 0 +0x0000DEB7 0x73AD # 0 +0x0000DEB8 0x8CA7 # 0 +0x0000DEB9 0x8CD3 # 0 +0x0000DEBA 0x983B # 0 +0x0000DEBB 0x6191 # 0 +0x0000DEBC 0x6C37 # 0 +0x0000DEBD 0x8058 # 0 +0x0000DEBE 0x9A01 # 0 +0x0000DEBF 0x4E4D # 0 +0x0000DEC0 0x4E8B # 0 +0x0000DEC1 0x4E9B # 0 +0x0000DEC2 0x4ED5 # 0 +0x0000DEC3 0x4F3A # 0 +0x0000DEC4 0x4F3C # 0 +0x0000DEC5 0x4F7F # 0 +0x0000DEC6 0x4FDF # 0 +0x0000DEC7 0x50FF # 0 +0x0000DEC8 0x53F2 # 0 +0x0000DEC9 0x53F8 # 0 +0x0000DECA 0x5506 # 0 +0x0000DECB 0x55E3 # 0 +0x0000DECC 0x56DB # 0 +0x0000DECD 0x58EB # 0 +0x0000DECE 0x5962 # 0 +0x0000DECF 0x5A11 # 0 +0x0000DED0 0x5BEB # 0 +0x0000DED1 0x5BFA # 0 +0x0000DED2 0x5C04 # 0 +0x0000DED3 0x5DF3 # 0 +0x0000DED4 0x5E2B # 0 +0x0000DED5 0x5F99 # 0 +0x0000DED6 0x601D # 0 +0x0000DED7 0x6368 # 0 +0x0000DED8 0x659C # 0 +0x0000DED9 0x65AF # 0 +0x0000DEDA 0x67F6 # 0 +0x0000DEDB 0x67FB # 0 +0x0000DEDC 0x68AD # 0 +0x0000DEDD 0x6B7B # 0 +0x0000DEDE 0x6C99 # 0 +0x0000DEDF 0x6CD7 # 0 +0x0000DEE0 0x6E23 # 0 +0x0000DEE1 0x7009 # 0 +0x0000DEE2 0x7345 # 0 +0x0000DEE3 0x7802 # 0 +0x0000DEE4 0x793E # 0 +0x0000DEE5 0x7940 # 0 +0x0000DEE6 0x7960 # 0 +0x0000DEE7 0x79C1 # 0 +0x0000DEE8 0x7BE9 # 0 +0x0000DEE9 0x7D17 # 0 +0x0000DEEA 0x7D72 # 0 +0x0000DEEB 0x8086 # 0 +0x0000DEEC 0x820D # 0 +0x0000DEED 0x838E # 0 +0x0000DEEE 0x84D1 # 0 +0x0000DEEF 0x86C7 # 0 +0x0000DEF0 0x88DF # 0 +0x0000DEF1 0x8A50 # 0 +0x0000DEF2 0x8A5E # 0 +0x0000DEF3 0x8B1D # 0 +0x0000DEF4 0x8CDC # 0 +0x0000DEF5 0x8D66 # 0 +0x0000DEF6 0x8FAD # 0 +0x0000DEF7 0x90AA # 0 +0x0000DEF8 0x98FC # 0 +0x0000DEF9 0x99DF # 0 +0x0000DEFA 0x9E9D # 0 +0x0000DEFB 0x524A # 0 +0x0000DEFC 0xF969 # 0 +0x0000DEFD 0x6714 # 0 +0x0000DEFE 0xF96A # 0 +0x0000DFA1 0x5098 # 0 +0x0000DFA2 0x522A # 0 +0x0000DFA3 0x5C71 # 0 +0x0000DFA4 0x6563 # 0 +0x0000DFA5 0x6C55 # 0 +0x0000DFA6 0x73CA # 0 +0x0000DFA7 0x7523 # 0 +0x0000DFA8 0x759D # 0 +0x0000DFA9 0x7B97 # 0 +0x0000DFAA 0x849C # 0 +0x0000DFAB 0x9178 # 0 +0x0000DFAC 0x9730 # 0 +0x0000DFAD 0x4E77 # 0 +0x0000DFAE 0x6492 # 0 +0x0000DFAF 0x6BBA # 0 +0x0000DFB0 0x715E # 0 +0x0000DFB1 0x85A9 # 0 +0x0000DFB2 0x4E09 # 0 +0x0000DFB3 0xF96B # 0 +0x0000DFB4 0x6749 # 0 +0x0000DFB5 0x68EE # 0 +0x0000DFB6 0x6E17 # 0 +0x0000DFB7 0x829F # 0 +0x0000DFB8 0x8518 # 0 +0x0000DFB9 0x886B # 0 +0x0000DFBA 0x63F7 # 0 +0x0000DFBB 0x6F81 # 0 +0x0000DFBC 0x9212 # 0 +0x0000DFBD 0x98AF # 0 +0x0000DFBE 0x4E0A # 0 +0x0000DFBF 0x50B7 # 0 +0x0000DFC0 0x50CF # 0 +0x0000DFC1 0x511F # 0 +0x0000DFC2 0x5546 # 0 +0x0000DFC3 0x55AA # 0 +0x0000DFC4 0x5617 # 0 +0x0000DFC5 0x5B40 # 0 +0x0000DFC6 0x5C19 # 0 +0x0000DFC7 0x5CE0 # 0 +0x0000DFC8 0x5E38 # 0 +0x0000DFC9 0x5E8A # 0 +0x0000DFCA 0x5EA0 # 0 +0x0000DFCB 0x5EC2 # 0 +0x0000DFCC 0x60F3 # 0 +0x0000DFCD 0x6851 # 0 +0x0000DFCE 0x6A61 # 0 +0x0000DFCF 0x6E58 # 0 +0x0000DFD0 0x723D # 0 +0x0000DFD1 0x7240 # 0 +0x0000DFD2 0x72C0 # 0 +0x0000DFD3 0x76F8 # 0 +0x0000DFD4 0x7965 # 0 +0x0000DFD5 0x7BB1 # 0 +0x0000DFD6 0x7FD4 # 0 +0x0000DFD7 0x88F3 # 0 +0x0000DFD8 0x89F4 # 0 +0x0000DFD9 0x8A73 # 0 +0x0000DFDA 0x8C61 # 0 +0x0000DFDB 0x8CDE # 0 +0x0000DFDC 0x971C # 0 +0x0000DFDD 0x585E # 0 +0x0000DFDE 0x74BD # 0 +0x0000DFDF 0x8CFD # 0 +0x0000DFE0 0x55C7 # 0 +0x0000DFE1 0xF96C # 0 +0x0000DFE2 0x7A61 # 0 +0x0000DFE3 0x7D22 # 0 +0x0000DFE4 0x8272 # 0 +0x0000DFE5 0x7272 # 0 +0x0000DFE6 0x751F # 0 +0x0000DFE7 0x7525 # 0 +0x0000DFE8 0xF96D # 0 +0x0000DFE9 0x7B19 # 0 +0x0000DFEA 0x5885 # 0 +0x0000DFEB 0x58FB # 0 +0x0000DFEC 0x5DBC # 0 +0x0000DFED 0x5E8F # 0 +0x0000DFEE 0x5EB6 # 0 +0x0000DFEF 0x5F90 # 0 +0x0000DFF0 0x6055 # 0 +0x0000DFF1 0x6292 # 0 +0x0000DFF2 0x637F # 0 +0x0000DFF3 0x654D # 0 +0x0000DFF4 0x6691 # 0 +0x0000DFF5 0x66D9 # 0 +0x0000DFF6 0x66F8 # 0 +0x0000DFF7 0x6816 # 0 +0x0000DFF8 0x68F2 # 0 +0x0000DFF9 0x7280 # 0 +0x0000DFFA 0x745E # 0 +0x0000DFFB 0x7B6E # 0 +0x0000DFFC 0x7D6E # 0 +0x0000DFFD 0x7DD6 # 0 +0x0000DFFE 0x7F72 # 0 +0x0000E0A1 0x80E5 # 0 +0x0000E0A2 0x8212 # 0 +0x0000E0A3 0x85AF # 0 +0x0000E0A4 0x897F # 0 +0x0000E0A5 0x8A93 # 0 +0x0000E0A6 0x901D # 0 +0x0000E0A7 0x92E4 # 0 +0x0000E0A8 0x9ECD # 0 +0x0000E0A9 0x9F20 # 0 +0x0000E0AA 0x5915 # 0 +0x0000E0AB 0x596D # 0 +0x0000E0AC 0x5E2D # 0 +0x0000E0AD 0x60DC # 0 +0x0000E0AE 0x6614 # 0 +0x0000E0AF 0x6673 # 0 +0x0000E0B0 0x6790 # 0 +0x0000E0B1 0x6C50 # 0 +0x0000E0B2 0x6DC5 # 0 +0x0000E0B3 0x6F5F # 0 +0x0000E0B4 0x77F3 # 0 +0x0000E0B5 0x78A9 # 0 +0x0000E0B6 0x84C6 # 0 +0x0000E0B7 0x91CB # 0 +0x0000E0B8 0x932B # 0 +0x0000E0B9 0x4ED9 # 0 +0x0000E0BA 0x50CA # 0 +0x0000E0BB 0x5148 # 0 +0x0000E0BC 0x5584 # 0 +0x0000E0BD 0x5B0B # 0 +0x0000E0BE 0x5BA3 # 0 +0x0000E0BF 0x6247 # 0 +0x0000E0C0 0x657E # 0 +0x0000E0C1 0x65CB # 0 +0x0000E0C2 0x6E32 # 0 +0x0000E0C3 0x717D # 0 +0x0000E0C4 0x7401 # 0 +0x0000E0C5 0x7444 # 0 +0x0000E0C6 0x7487 # 0 +0x0000E0C7 0x74BF # 0 +0x0000E0C8 0x766C # 0 +0x0000E0C9 0x79AA # 0 +0x0000E0CA 0x7DDA # 0 +0x0000E0CB 0x7E55 # 0 +0x0000E0CC 0x7FA8 # 0 +0x0000E0CD 0x817A # 0 +0x0000E0CE 0x81B3 # 0 +0x0000E0CF 0x8239 # 0 +0x0000E0D0 0x861A # 0 +0x0000E0D1 0x87EC # 0 +0x0000E0D2 0x8A75 # 0 +0x0000E0D3 0x8DE3 # 0 +0x0000E0D4 0x9078 # 0 +0x0000E0D5 0x9291 # 0 +0x0000E0D6 0x9425 # 0 +0x0000E0D7 0x994D # 0 +0x0000E0D8 0x9BAE # 0 +0x0000E0D9 0x5368 # 0 +0x0000E0DA 0x5C51 # 0 +0x0000E0DB 0x6954 # 0 +0x0000E0DC 0x6CC4 # 0 +0x0000E0DD 0x6D29 # 0 +0x0000E0DE 0x6E2B # 0 +0x0000E0DF 0x820C # 0 +0x0000E0E0 0x859B # 0 +0x0000E0E1 0x893B # 0 +0x0000E0E2 0x8A2D # 0 +0x0000E0E3 0x8AAA # 0 +0x0000E0E4 0x96EA # 0 +0x0000E0E5 0x9F67 # 0 +0x0000E0E6 0x5261 # 0 +0x0000E0E7 0x66B9 # 0 +0x0000E0E8 0x6BB2 # 0 +0x0000E0E9 0x7E96 # 0 +0x0000E0EA 0x87FE # 0 +0x0000E0EB 0x8D0D # 0 +0x0000E0EC 0x9583 # 0 +0x0000E0ED 0x965D # 0 +0x0000E0EE 0x651D # 0 +0x0000E0EF 0x6D89 # 0 +0x0000E0F0 0x71EE # 0 +0x0000E0F1 0xF96E # 0 +0x0000E0F2 0x57CE # 0 +0x0000E0F3 0x59D3 # 0 +0x0000E0F4 0x5BAC # 0 +0x0000E0F5 0x6027 # 0 +0x0000E0F6 0x60FA # 0 +0x0000E0F7 0x6210 # 0 +0x0000E0F8 0x661F # 0 +0x0000E0F9 0x665F # 0 +0x0000E0FA 0x7329 # 0 +0x0000E0FB 0x73F9 # 0 +0x0000E0FC 0x76DB # 0 +0x0000E0FD 0x7701 # 0 +0x0000E0FE 0x7B6C # 0 +0x0000E1A1 0x8056 # 0 +0x0000E1A2 0x8072 # 0 +0x0000E1A3 0x8165 # 0 +0x0000E1A4 0x8AA0 # 0 +0x0000E1A5 0x9192 # 0 +0x0000E1A6 0x4E16 # 0 +0x0000E1A7 0x52E2 # 0 +0x0000E1A8 0x6B72 # 0 +0x0000E1A9 0x6D17 # 0 +0x0000E1AA 0x7A05 # 0 +0x0000E1AB 0x7B39 # 0 +0x0000E1AC 0x7D30 # 0 +0x0000E1AD 0xF96F # 0 +0x0000E1AE 0x8CB0 # 0 +0x0000E1AF 0x53EC # 0 +0x0000E1B0 0x562F # 0 +0x0000E1B1 0x5851 # 0 +0x0000E1B2 0x5BB5 # 0 +0x0000E1B3 0x5C0F # 0 +0x0000E1B4 0x5C11 # 0 +0x0000E1B5 0x5DE2 # 0 +0x0000E1B6 0x6240 # 0 +0x0000E1B7 0x6383 # 0 +0x0000E1B8 0x6414 # 0 +0x0000E1B9 0x662D # 0 +0x0000E1BA 0x68B3 # 0 +0x0000E1BB 0x6CBC # 0 +0x0000E1BC 0x6D88 # 0 +0x0000E1BD 0x6EAF # 0 +0x0000E1BE 0x701F # 0 +0x0000E1BF 0x70A4 # 0 +0x0000E1C0 0x71D2 # 0 +0x0000E1C1 0x7526 # 0 +0x0000E1C2 0x758F # 0 +0x0000E1C3 0x758E # 0 +0x0000E1C4 0x7619 # 0 +0x0000E1C5 0x7B11 # 0 +0x0000E1C6 0x7BE0 # 0 +0x0000E1C7 0x7C2B # 0 +0x0000E1C8 0x7D20 # 0 +0x0000E1C9 0x7D39 # 0 +0x0000E1CA 0x852C # 0 +0x0000E1CB 0x856D # 0 +0x0000E1CC 0x8607 # 0 +0x0000E1CD 0x8A34 # 0 +0x0000E1CE 0x900D # 0 +0x0000E1CF 0x9061 # 0 +0x0000E1D0 0x90B5 # 0 +0x0000E1D1 0x92B7 # 0 +0x0000E1D2 0x97F6 # 0 +0x0000E1D3 0x9A37 # 0 +0x0000E1D4 0x4FD7 # 0 +0x0000E1D5 0x5C6C # 0 +0x0000E1D6 0x675F # 0 +0x0000E1D7 0x6D91 # 0 +0x0000E1D8 0x7C9F # 0 +0x0000E1D9 0x7E8C # 0 +0x0000E1DA 0x8B16 # 0 +0x0000E1DB 0x8D16 # 0 +0x0000E1DC 0x901F # 0 +0x0000E1DD 0x5B6B # 0 +0x0000E1DE 0x5DFD # 0 +0x0000E1DF 0x640D # 0 +0x0000E1E0 0x84C0 # 0 +0x0000E1E1 0x905C # 0 +0x0000E1E2 0x98E1 # 0 +0x0000E1E3 0x7387 # 0 +0x0000E1E4 0x5B8B # 0 +0x0000E1E5 0x609A # 0 +0x0000E1E6 0x677E # 0 +0x0000E1E7 0x6DDE # 0 +0x0000E1E8 0x8A1F # 0 +0x0000E1E9 0x8AA6 # 0 +0x0000E1EA 0x9001 # 0 +0x0000E1EB 0x980C # 0 +0x0000E1EC 0x5237 # 0 +0x0000E1ED 0xF970 # 0 +0x0000E1EE 0x7051 # 0 +0x0000E1EF 0x788E # 0 +0x0000E1F0 0x9396 # 0 +0x0000E1F1 0x8870 # 0 +0x0000E1F2 0x91D7 # 0 +0x0000E1F3 0x4FEE # 0 +0x0000E1F4 0x53D7 # 0 +0x0000E1F5 0x55FD # 0 +0x0000E1F6 0x56DA # 0 +0x0000E1F7 0x5782 # 0 +0x0000E1F8 0x58FD # 0 +0x0000E1F9 0x5AC2 # 0 +0x0000E1FA 0x5B88 # 0 +0x0000E1FB 0x5CAB # 0 +0x0000E1FC 0x5CC0 # 0 +0x0000E1FD 0x5E25 # 0 +0x0000E1FE 0x6101 # 0 +0x0000E2A1 0x620D # 0 +0x0000E2A2 0x624B # 0 +0x0000E2A3 0x6388 # 0 +0x0000E2A4 0x641C # 0 +0x0000E2A5 0x6536 # 0 +0x0000E2A6 0x6578 # 0 +0x0000E2A7 0x6A39 # 0 +0x0000E2A8 0x6B8A # 0 +0x0000E2A9 0x6C34 # 0 +0x0000E2AA 0x6D19 # 0 +0x0000E2AB 0x6F31 # 0 +0x0000E2AC 0x71E7 # 0 +0x0000E2AD 0x72E9 # 0 +0x0000E2AE 0x7378 # 0 +0x0000E2AF 0x7407 # 0 +0x0000E2B0 0x74B2 # 0 +0x0000E2B1 0x7626 # 0 +0x0000E2B2 0x7761 # 0 +0x0000E2B3 0x79C0 # 0 +0x0000E2B4 0x7A57 # 0 +0x0000E2B5 0x7AEA # 0 +0x0000E2B6 0x7CB9 # 0 +0x0000E2B7 0x7D8F # 0 +0x0000E2B8 0x7DAC # 0 +0x0000E2B9 0x7E61 # 0 +0x0000E2BA 0x7F9E # 0 +0x0000E2BB 0x8129 # 0 +0x0000E2BC 0x8331 # 0 +0x0000E2BD 0x8490 # 0 +0x0000E2BE 0x84DA # 0 +0x0000E2BF 0x85EA # 0 +0x0000E2C0 0x8896 # 0 +0x0000E2C1 0x8AB0 # 0 +0x0000E2C2 0x8B90 # 0 +0x0000E2C3 0x8F38 # 0 +0x0000E2C4 0x9042 # 0 +0x0000E2C5 0x9083 # 0 +0x0000E2C6 0x916C # 0 +0x0000E2C7 0x9296 # 0 +0x0000E2C8 0x92B9 # 0 +0x0000E2C9 0x968B # 0 +0x0000E2CA 0x96A7 # 0 +0x0000E2CB 0x96A8 # 0 +0x0000E2CC 0x96D6 # 0 +0x0000E2CD 0x9700 # 0 +0x0000E2CE 0x9808 # 0 +0x0000E2CF 0x9996 # 0 +0x0000E2D0 0x9AD3 # 0 +0x0000E2D1 0x9B1A # 0 +0x0000E2D2 0x53D4 # 0 +0x0000E2D3 0x587E # 0 +0x0000E2D4 0x5919 # 0 +0x0000E2D5 0x5B70 # 0 +0x0000E2D6 0x5BBF # 0 +0x0000E2D7 0x6DD1 # 0 +0x0000E2D8 0x6F5A # 0 +0x0000E2D9 0x719F # 0 +0x0000E2DA 0x7421 # 0 +0x0000E2DB 0x74B9 # 0 +0x0000E2DC 0x8085 # 0 +0x0000E2DD 0x83FD # 0 +0x0000E2DE 0x5DE1 # 0 +0x0000E2DF 0x5F87 # 0 +0x0000E2E0 0x5FAA # 0 +0x0000E2E1 0x6042 # 0 +0x0000E2E2 0x65EC # 0 +0x0000E2E3 0x6812 # 0 +0x0000E2E4 0x696F # 0 +0x0000E2E5 0x6A53 # 0 +0x0000E2E6 0x6B89 # 0 +0x0000E2E7 0x6D35 # 0 +0x0000E2E8 0x6DF3 # 0 +0x0000E2E9 0x73E3 # 0 +0x0000E2EA 0x76FE # 0 +0x0000E2EB 0x77AC # 0 +0x0000E2EC 0x7B4D # 0 +0x0000E2ED 0x7D14 # 0 +0x0000E2EE 0x8123 # 0 +0x0000E2EF 0x821C # 0 +0x0000E2F0 0x8340 # 0 +0x0000E2F1 0x84F4 # 0 +0x0000E2F2 0x8563 # 0 +0x0000E2F3 0x8A62 # 0 +0x0000E2F4 0x8AC4 # 0 +0x0000E2F5 0x9187 # 0 +0x0000E2F6 0x931E # 0 +0x0000E2F7 0x9806 # 0 +0x0000E2F8 0x99B4 # 0 +0x0000E2F9 0x620C # 0 +0x0000E2FA 0x8853 # 0 +0x0000E2FB 0x8FF0 # 0 +0x0000E2FC 0x9265 # 0 +0x0000E2FD 0x5D07 # 0 +0x0000E2FE 0x5D27 # 0 +0x0000E3A1 0x5D69 # 0 +0x0000E3A2 0x745F # 0 +0x0000E3A3 0x819D # 0 +0x0000E3A4 0x8768 # 0 +0x0000E3A5 0x6FD5 # 0 +0x0000E3A6 0x62FE # 0 +0x0000E3A7 0x7FD2 # 0 +0x0000E3A8 0x8936 # 0 +0x0000E3A9 0x8972 # 0 +0x0000E3AA 0x4E1E # 0 +0x0000E3AB 0x4E58 # 0 +0x0000E3AC 0x50E7 # 0 +0x0000E3AD 0x52DD # 0 +0x0000E3AE 0x5347 # 0 +0x0000E3AF 0x627F # 0 +0x0000E3B0 0x6607 # 0 +0x0000E3B1 0x7E69 # 0 +0x0000E3B2 0x8805 # 0 +0x0000E3B3 0x965E # 0 +0x0000E3B4 0x4F8D # 0 +0x0000E3B5 0x5319 # 0 +0x0000E3B6 0x5636 # 0 +0x0000E3B7 0x59CB # 0 +0x0000E3B8 0x5AA4 # 0 +0x0000E3B9 0x5C38 # 0 +0x0000E3BA 0x5C4E # 0 +0x0000E3BB 0x5C4D # 0 +0x0000E3BC 0x5E02 # 0 +0x0000E3BD 0x5F11 # 0 +0x0000E3BE 0x6043 # 0 +0x0000E3BF 0x65BD # 0 +0x0000E3C0 0x662F # 0 +0x0000E3C1 0x6642 # 0 +0x0000E3C2 0x67BE # 0 +0x0000E3C3 0x67F4 # 0 +0x0000E3C4 0x731C # 0 +0x0000E3C5 0x77E2 # 0 +0x0000E3C6 0x793A # 0 +0x0000E3C7 0x7FC5 # 0 +0x0000E3C8 0x8494 # 0 +0x0000E3C9 0x84CD # 0 +0x0000E3CA 0x8996 # 0 +0x0000E3CB 0x8A66 # 0 +0x0000E3CC 0x8A69 # 0 +0x0000E3CD 0x8AE1 # 0 +0x0000E3CE 0x8C55 # 0 +0x0000E3CF 0x8C7A # 0 +0x0000E3D0 0x57F4 # 0 +0x0000E3D1 0x5BD4 # 0 +0x0000E3D2 0x5F0F # 0 +0x0000E3D3 0x606F # 0 +0x0000E3D4 0x62ED # 0 +0x0000E3D5 0x690D # 0 +0x0000E3D6 0x6B96 # 0 +0x0000E3D7 0x6E5C # 0 +0x0000E3D8 0x7184 # 0 +0x0000E3D9 0x7BD2 # 0 +0x0000E3DA 0x8755 # 0 +0x0000E3DB 0x8B58 # 0 +0x0000E3DC 0x8EFE # 0 +0x0000E3DD 0x98DF # 0 +0x0000E3DE 0x98FE # 0 +0x0000E3DF 0x4F38 # 0 +0x0000E3E0 0x4F81 # 0 +0x0000E3E1 0x4FE1 # 0 +0x0000E3E2 0x547B # 0 +0x0000E3E3 0x5A20 # 0 +0x0000E3E4 0x5BB8 # 0 +0x0000E3E5 0x613C # 0 +0x0000E3E6 0x65B0 # 0 +0x0000E3E7 0x6668 # 0 +0x0000E3E8 0x71FC # 0 +0x0000E3E9 0x7533 # 0 +0x0000E3EA 0x795E # 0 +0x0000E3EB 0x7D33 # 0 +0x0000E3EC 0x814E # 0 +0x0000E3ED 0x81E3 # 0 +0x0000E3EE 0x8398 # 0 +0x0000E3EF 0x85AA # 0 +0x0000E3F0 0x85CE # 0 +0x0000E3F1 0x8703 # 0 +0x0000E3F2 0x8A0A # 0 +0x0000E3F3 0x8EAB # 0 +0x0000E3F4 0x8F9B # 0 +0x0000E3F5 0xF971 # 0 +0x0000E3F6 0x8FC5 # 0 +0x0000E3F7 0x5931 # 0 +0x0000E3F8 0x5BA4 # 0 +0x0000E3F9 0x5BE6 # 0 +0x0000E3FA 0x6089 # 0 +0x0000E3FB 0x5BE9 # 0 +0x0000E3FC 0x5C0B # 0 +0x0000E3FD 0x5FC3 # 0 +0x0000E3FE 0x6C81 # 0 +0x0000E4A1 0xF972 # 0 +0x0000E4A2 0x6DF1 # 0 +0x0000E4A3 0x700B # 0 +0x0000E4A4 0x751A # 0 +0x0000E4A5 0x82AF # 0 +0x0000E4A6 0x8AF6 # 0 +0x0000E4A7 0x4EC0 # 0 +0x0000E4A8 0x5341 # 0 +0x0000E4A9 0xF973 # 0 +0x0000E4AA 0x96D9 # 0 +0x0000E4AB 0x6C0F # 0 +0x0000E4AC 0x4E9E # 0 +0x0000E4AD 0x4FC4 # 0 +0x0000E4AE 0x5152 # 0 +0x0000E4AF 0x555E # 0 +0x0000E4B0 0x5A25 # 0 +0x0000E4B1 0x5CE8 # 0 +0x0000E4B2 0x6211 # 0 +0x0000E4B3 0x7259 # 0 +0x0000E4B4 0x82BD # 0 +0x0000E4B5 0x83AA # 0 +0x0000E4B6 0x86FE # 0 +0x0000E4B7 0x8859 # 0 +0x0000E4B8 0x8A1D # 0 +0x0000E4B9 0x963F # 0 +0x0000E4BA 0x96C5 # 0 +0x0000E4BB 0x9913 # 0 +0x0000E4BC 0x9D09 # 0 +0x0000E4BD 0x9D5D # 0 +0x0000E4BE 0x580A # 0 +0x0000E4BF 0x5CB3 # 0 +0x0000E4C0 0x5DBD # 0 +0x0000E4C1 0x5E44 # 0 +0x0000E4C2 0x60E1 # 0 +0x0000E4C3 0x6115 # 0 +0x0000E4C4 0x63E1 # 0 +0x0000E4C5 0x6A02 # 0 +0x0000E4C6 0x6E25 # 0 +0x0000E4C7 0x9102 # 0 +0x0000E4C8 0x9354 # 0 +0x0000E4C9 0x984E # 0 +0x0000E4CA 0x9C10 # 0 +0x0000E4CB 0x9F77 # 0 +0x0000E4CC 0x5B89 # 0 +0x0000E4CD 0x5CB8 # 0 +0x0000E4CE 0x6309 # 0 +0x0000E4CF 0x664F # 0 +0x0000E4D0 0x6848 # 0 +0x0000E4D1 0x773C # 0 +0x0000E4D2 0x96C1 # 0 +0x0000E4D3 0x978D # 0 +0x0000E4D4 0x9854 # 0 +0x0000E4D5 0x9B9F # 0 +0x0000E4D6 0x65A1 # 0 +0x0000E4D7 0x8B01 # 0 +0x0000E4D8 0x8ECB # 0 +0x0000E4D9 0x95BC # 0 +0x0000E4DA 0x5535 # 0 +0x0000E4DB 0x5CA9 # 0 +0x0000E4DC 0x5DD6 # 0 +0x0000E4DD 0x5EB5 # 0 +0x0000E4DE 0x6697 # 0 +0x0000E4DF 0x764C # 0 +0x0000E4E0 0x83F4 # 0 +0x0000E4E1 0x95C7 # 0 +0x0000E4E2 0x58D3 # 0 +0x0000E4E3 0x62BC # 0 +0x0000E4E4 0x72CE # 0 +0x0000E4E5 0x9D28 # 0 +0x0000E4E6 0x4EF0 # 0 +0x0000E4E7 0x592E # 0 +0x0000E4E8 0x600F # 0 +0x0000E4E9 0x663B # 0 +0x0000E4EA 0x6B83 # 0 +0x0000E4EB 0x79E7 # 0 +0x0000E4EC 0x9D26 # 0 +0x0000E4ED 0x5393 # 0 +0x0000E4EE 0x54C0 # 0 +0x0000E4EF 0x57C3 # 0 +0x0000E4F0 0x5D16 # 0 +0x0000E4F1 0x611B # 0 +0x0000E4F2 0x66D6 # 0 +0x0000E4F3 0x6DAF # 0 +0x0000E4F4 0x788D # 0 +0x0000E4F5 0x827E # 0 +0x0000E4F6 0x9698 # 0 +0x0000E4F7 0x9744 # 0 +0x0000E4F8 0x5384 # 0 +0x0000E4F9 0x627C # 0 +0x0000E4FA 0x6396 # 0 +0x0000E4FB 0x6DB2 # 0 +0x0000E4FC 0x7E0A # 0 +0x0000E4FD 0x814B # 0 +0x0000E4FE 0x984D # 0 +0x0000E5A1 0x6AFB # 0 +0x0000E5A2 0x7F4C # 0 +0x0000E5A3 0x9DAF # 0 +0x0000E5A4 0x9E1A # 0 +0x0000E5A5 0x4E5F # 0 +0x0000E5A6 0x503B # 0 +0x0000E5A7 0x51B6 # 0 +0x0000E5A8 0x591C # 0 +0x0000E5A9 0x60F9 # 0 +0x0000E5AA 0x63F6 # 0 +0x0000E5AB 0x6930 # 0 +0x0000E5AC 0x723A # 0 +0x0000E5AD 0x8036 # 0 +0x0000E5AE 0xF974 # 0 +0x0000E5AF 0x91CE # 0 +0x0000E5B0 0x5F31 # 0 +0x0000E5B1 0xF975 # 0 +0x0000E5B2 0xF976 # 0 +0x0000E5B3 0x7D04 # 0 +0x0000E5B4 0x82E5 # 0 +0x0000E5B5 0x846F # 0 +0x0000E5B6 0x84BB # 0 +0x0000E5B7 0x85E5 # 0 +0x0000E5B8 0x8E8D # 0 +0x0000E5B9 0xF977 # 0 +0x0000E5BA 0x4F6F # 0 +0x0000E5BB 0xF978 # 0 +0x0000E5BC 0xF979 # 0 +0x0000E5BD 0x58E4 # 0 +0x0000E5BE 0x5B43 # 0 +0x0000E5BF 0x6059 # 0 +0x0000E5C0 0x63DA # 0 +0x0000E5C1 0x6518 # 0 +0x0000E5C2 0x656D # 0 +0x0000E5C3 0x6698 # 0 +0x0000E5C4 0xF97A # 0 +0x0000E5C5 0x694A # 0 +0x0000E5C6 0x6A23 # 0 +0x0000E5C7 0x6D0B # 0 +0x0000E5C8 0x7001 # 0 +0x0000E5C9 0x716C # 0 +0x0000E5CA 0x75D2 # 0 +0x0000E5CB 0x760D # 0 +0x0000E5CC 0x79B3 # 0 +0x0000E5CD 0x7A70 # 0 +0x0000E5CE 0xF97B # 0 +0x0000E5CF 0x7F8A # 0 +0x0000E5D0 0xF97C # 0 +0x0000E5D1 0x8944 # 0 +0x0000E5D2 0xF97D # 0 +0x0000E5D3 0x8B93 # 0 +0x0000E5D4 0x91C0 # 0 +0x0000E5D5 0x967D # 0 +0x0000E5D6 0xF97E # 0 +0x0000E5D7 0x990A # 0 +0x0000E5D8 0x5704 # 0 +0x0000E5D9 0x5FA1 # 0 +0x0000E5DA 0x65BC # 0 +0x0000E5DB 0x6F01 # 0 +0x0000E5DC 0x7600 # 0 +0x0000E5DD 0x79A6 # 0 +0x0000E5DE 0x8A9E # 0 +0x0000E5DF 0x99AD # 0 +0x0000E5E0 0x9B5A # 0 +0x0000E5E1 0x9F6C # 0 +0x0000E5E2 0x5104 # 0 +0x0000E5E3 0x61B6 # 0 +0x0000E5E4 0x6291 # 0 +0x0000E5E5 0x6A8D # 0 +0x0000E5E6 0x81C6 # 0 +0x0000E5E7 0x5043 # 0 +0x0000E5E8 0x5830 # 0 +0x0000E5E9 0x5F66 # 0 +0x0000E5EA 0x7109 # 0 +0x0000E5EB 0x8A00 # 0 +0x0000E5EC 0x8AFA # 0 +0x0000E5ED 0x5B7C # 0 +0x0000E5EE 0x8616 # 0 +0x0000E5EF 0x4FFA # 0 +0x0000E5F0 0x513C # 0 +0x0000E5F1 0x56B4 # 0 +0x0000E5F2 0x5944 # 0 +0x0000E5F3 0x63A9 # 0 +0x0000E5F4 0x6DF9 # 0 +0x0000E5F5 0x5DAA # 0 +0x0000E5F6 0x696D # 0 +0x0000E5F7 0x5186 # 0 +0x0000E5F8 0x4E88 # 0 +0x0000E5F9 0x4F59 # 0 +0x0000E5FA 0xF97F # 0 +0x0000E5FB 0xF980 # 0 +0x0000E5FC 0xF981 # 0 +0x0000E5FD 0x5982 # 0 +0x0000E5FE 0xF982 # 0 +0x0000E6A1 0xF983 # 0 +0x0000E6A2 0x6B5F # 0 +0x0000E6A3 0x6C5D # 0 +0x0000E6A4 0xF984 # 0 +0x0000E6A5 0x74B5 # 0 +0x0000E6A6 0x7916 # 0 +0x0000E6A7 0xF985 # 0 +0x0000E6A8 0x8207 # 0 +0x0000E6A9 0x8245 # 0 +0x0000E6AA 0x8339 # 0 +0x0000E6AB 0x8F3F # 0 +0x0000E6AC 0x8F5D # 0 +0x0000E6AD 0xF986 # 0 +0x0000E6AE 0x9918 # 0 +0x0000E6AF 0xF987 # 0 +0x0000E6B0 0xF988 # 0 +0x0000E6B1 0xF989 # 0 +0x0000E6B2 0x4EA6 # 0 +0x0000E6B3 0xF98A # 0 +0x0000E6B4 0x57DF # 0 +0x0000E6B5 0x5F79 # 0 +0x0000E6B6 0x6613 # 0 +0x0000E6B7 0xF98B # 0 +0x0000E6B8 0xF98C # 0 +0x0000E6B9 0x75AB # 0 +0x0000E6BA 0x7E79 # 0 +0x0000E6BB 0x8B6F # 0 +0x0000E6BC 0xF98D # 0 +0x0000E6BD 0x9006 # 0 +0x0000E6BE 0x9A5B # 0 +0x0000E6BF 0x56A5 # 0 +0x0000E6C0 0x5827 # 0 +0x0000E6C1 0x59F8 # 0 +0x0000E6C2 0x5A1F # 0 +0x0000E6C3 0x5BB4 # 0 +0x0000E6C4 0xF98E # 0 +0x0000E6C5 0x5EF6 # 0 +0x0000E6C6 0xF98F # 0 +0x0000E6C7 0xF990 # 0 +0x0000E6C8 0x6350 # 0 +0x0000E6C9 0x633B # 0 +0x0000E6CA 0xF991 # 0 +0x0000E6CB 0x693D # 0 +0x0000E6CC 0x6C87 # 0 +0x0000E6CD 0x6CBF # 0 +0x0000E6CE 0x6D8E # 0 +0x0000E6CF 0x6D93 # 0 +0x0000E6D0 0x6DF5 # 0 +0x0000E6D1 0x6F14 # 0 +0x0000E6D2 0xF992 # 0 +0x0000E6D3 0x70DF # 0 +0x0000E6D4 0x7136 # 0 +0x0000E6D5 0x7159 # 0 +0x0000E6D6 0xF993 # 0 +0x0000E6D7 0x71C3 # 0 +0x0000E6D8 0x71D5 # 0 +0x0000E6D9 0xF994 # 0 +0x0000E6DA 0x784F # 0 +0x0000E6DB 0x786F # 0 +0x0000E6DC 0xF995 # 0 +0x0000E6DD 0x7B75 # 0 +0x0000E6DE 0x7DE3 # 0 +0x0000E6DF 0xF996 # 0 +0x0000E6E0 0x7E2F # 0 +0x0000E6E1 0xF997 # 0 +0x0000E6E2 0x884D # 0 +0x0000E6E3 0x8EDF # 0 +0x0000E6E4 0xF998 # 0 +0x0000E6E5 0xF999 # 0 +0x0000E6E6 0xF99A # 0 +0x0000E6E7 0x925B # 0 +0x0000E6E8 0xF99B # 0 +0x0000E6E9 0x9CF6 # 0 +0x0000E6EA 0xF99C # 0 +0x0000E6EB 0xF99D # 0 +0x0000E6EC 0xF99E # 0 +0x0000E6ED 0x6085 # 0 +0x0000E6EE 0x6D85 # 0 +0x0000E6EF 0xF99F # 0 +0x0000E6F0 0x71B1 # 0 +0x0000E6F1 0xF9A0 # 0 +0x0000E6F2 0xF9A1 # 0 +0x0000E6F3 0x95B1 # 0 +0x0000E6F4 0x53AD # 0 +0x0000E6F5 0xF9A2 # 0 +0x0000E6F6 0xF9A3 # 0 +0x0000E6F7 0xF9A4 # 0 +0x0000E6F8 0x67D3 # 0 +0x0000E6F9 0xF9A5 # 0 +0x0000E6FA 0x708E # 0 +0x0000E6FB 0x7130 # 0 +0x0000E6FC 0x7430 # 0 +0x0000E6FD 0x8276 # 0 +0x0000E6FE 0x82D2 # 0 +0x0000E7A1 0xF9A6 # 0 +0x0000E7A2 0x95BB # 0 +0x0000E7A3 0x9AE5 # 0 +0x0000E7A4 0x9E7D # 0 +0x0000E7A5 0x66C4 # 0 +0x0000E7A6 0xF9A7 # 0 +0x0000E7A7 0x71C1 # 0 +0x0000E7A8 0x8449 # 0 +0x0000E7A9 0xF9A8 # 0 +0x0000E7AA 0xF9A9 # 0 +0x0000E7AB 0x584B # 0 +0x0000E7AC 0xF9AA # 0 +0x0000E7AD 0xF9AB # 0 +0x0000E7AE 0x5DB8 # 0 +0x0000E7AF 0x5F71 # 0 +0x0000E7B0 0xF9AC # 0 +0x0000E7B1 0x6620 # 0 +0x0000E7B2 0x668E # 0 +0x0000E7B3 0x6979 # 0 +0x0000E7B4 0x69AE # 0 +0x0000E7B5 0x6C38 # 0 +0x0000E7B6 0x6CF3 # 0 +0x0000E7B7 0x6E36 # 0 +0x0000E7B8 0x6F41 # 0 +0x0000E7B9 0x6FDA # 0 +0x0000E7BA 0x701B # 0 +0x0000E7BB 0x702F # 0 +0x0000E7BC 0x7150 # 0 +0x0000E7BD 0x71DF # 0 +0x0000E7BE 0x7370 # 0 +0x0000E7BF 0xF9AD # 0 +0x0000E7C0 0x745B # 0 +0x0000E7C1 0xF9AE # 0 +0x0000E7C2 0x74D4 # 0 +0x0000E7C3 0x76C8 # 0 +0x0000E7C4 0x7A4E # 0 +0x0000E7C5 0x7E93 # 0 +0x0000E7C6 0xF9AF # 0 +0x0000E7C7 0xF9B0 # 0 +0x0000E7C8 0x82F1 # 0 +0x0000E7C9 0x8A60 # 0 +0x0000E7CA 0x8FCE # 0 +0x0000E7CB 0xF9B1 # 0 +0x0000E7CC 0x9348 # 0 +0x0000E7CD 0xF9B2 # 0 +0x0000E7CE 0x9719 # 0 +0x0000E7CF 0xF9B3 # 0 +0x0000E7D0 0xF9B4 # 0 +0x0000E7D1 0x4E42 # 0 +0x0000E7D2 0x502A # 0 +0x0000E7D3 0xF9B5 # 0 +0x0000E7D4 0x5208 # 0 +0x0000E7D5 0x53E1 # 0 +0x0000E7D6 0x66F3 # 0 +0x0000E7D7 0x6C6D # 0 +0x0000E7D8 0x6FCA # 0 +0x0000E7D9 0x730A # 0 +0x0000E7DA 0x777F # 0 +0x0000E7DB 0x7A62 # 0 +0x0000E7DC 0x82AE # 0 +0x0000E7DD 0x85DD # 0 +0x0000E7DE 0x8602 # 0 +0x0000E7DF 0xF9B6 # 0 +0x0000E7E0 0x88D4 # 0 +0x0000E7E1 0x8A63 # 0 +0x0000E7E2 0x8B7D # 0 +0x0000E7E3 0x8C6B # 0 +0x0000E7E4 0xF9B7 # 0 +0x0000E7E5 0x92B3 # 0 +0x0000E7E6 0xF9B8 # 0 +0x0000E7E7 0x9713 # 0 +0x0000E7E8 0x9810 # 0 +0x0000E7E9 0x4E94 # 0 +0x0000E7EA 0x4F0D # 0 +0x0000E7EB 0x4FC9 # 0 +0x0000E7EC 0x50B2 # 0 +0x0000E7ED 0x5348 # 0 +0x0000E7EE 0x543E # 0 +0x0000E7EF 0x5433 # 0 +0x0000E7F0 0x55DA # 0 +0x0000E7F1 0x5862 # 0 +0x0000E7F2 0x58BA # 0 +0x0000E7F3 0x5967 # 0 +0x0000E7F4 0x5A1B # 0 +0x0000E7F5 0x5BE4 # 0 +0x0000E7F6 0x609F # 0 +0x0000E7F7 0xF9B9 # 0 +0x0000E7F8 0x61CA # 0 +0x0000E7F9 0x6556 # 0 +0x0000E7FA 0x65FF # 0 +0x0000E7FB 0x6664 # 0 +0x0000E7FC 0x68A7 # 0 +0x0000E7FD 0x6C5A # 0 +0x0000E7FE 0x6FB3 # 0 +0x0000E8A1 0x70CF # 0 +0x0000E8A2 0x71AC # 0 +0x0000E8A3 0x7352 # 0 +0x0000E8A4 0x7B7D # 0 +0x0000E8A5 0x8708 # 0 +0x0000E8A6 0x8AA4 # 0 +0x0000E8A7 0x9C32 # 0 +0x0000E8A8 0x9F07 # 0 +0x0000E8A9 0x5C4B # 0 +0x0000E8AA 0x6C83 # 0 +0x0000E8AB 0x7344 # 0 +0x0000E8AC 0x7389 # 0 +0x0000E8AD 0x923A # 0 +0x0000E8AE 0x6EAB # 0 +0x0000E8AF 0x7465 # 0 +0x0000E8B0 0x761F # 0 +0x0000E8B1 0x7A69 # 0 +0x0000E8B2 0x7E15 # 0 +0x0000E8B3 0x860A # 0 +0x0000E8B4 0x5140 # 0 +0x0000E8B5 0x58C5 # 0 +0x0000E8B6 0x64C1 # 0 +0x0000E8B7 0x74EE # 0 +0x0000E8B8 0x7515 # 0 +0x0000E8B9 0x7670 # 0 +0x0000E8BA 0x7FC1 # 0 +0x0000E8BB 0x9095 # 0 +0x0000E8BC 0x96CD # 0 +0x0000E8BD 0x9954 # 0 +0x0000E8BE 0x6E26 # 0 +0x0000E8BF 0x74E6 # 0 +0x0000E8C0 0x7AA9 # 0 +0x0000E8C1 0x7AAA # 0 +0x0000E8C2 0x81E5 # 0 +0x0000E8C3 0x86D9 # 0 +0x0000E8C4 0x8778 # 0 +0x0000E8C5 0x8A1B # 0 +0x0000E8C6 0x5A49 # 0 +0x0000E8C7 0x5B8C # 0 +0x0000E8C8 0x5B9B # 0 +0x0000E8C9 0x68A1 # 0 +0x0000E8CA 0x6900 # 0 +0x0000E8CB 0x6D63 # 0 +0x0000E8CC 0x73A9 # 0 +0x0000E8CD 0x7413 # 0 +0x0000E8CE 0x742C # 0 +0x0000E8CF 0x7897 # 0 +0x0000E8D0 0x7DE9 # 0 +0x0000E8D1 0x7FEB # 0 +0x0000E8D2 0x8118 # 0 +0x0000E8D3 0x8155 # 0 +0x0000E8D4 0x839E # 0 +0x0000E8D5 0x8C4C # 0 +0x0000E8D6 0x962E # 0 +0x0000E8D7 0x9811 # 0 +0x0000E8D8 0x66F0 # 0 +0x0000E8D9 0x5F80 # 0 +0x0000E8DA 0x65FA # 0 +0x0000E8DB 0x6789 # 0 +0x0000E8DC 0x6C6A # 0 +0x0000E8DD 0x738B # 0 +0x0000E8DE 0x502D # 0 +0x0000E8DF 0x5A03 # 0 +0x0000E8E0 0x6B6A # 0 +0x0000E8E1 0x77EE # 0 +0x0000E8E2 0x5916 # 0 +0x0000E8E3 0x5D6C # 0 +0x0000E8E4 0x5DCD # 0 +0x0000E8E5 0x7325 # 0 +0x0000E8E6 0x754F # 0 +0x0000E8E7 0xF9BA # 0 +0x0000E8E8 0xF9BB # 0 +0x0000E8E9 0x50E5 # 0 +0x0000E8EA 0x51F9 # 0 +0x0000E8EB 0x582F # 0 +0x0000E8EC 0x592D # 0 +0x0000E8ED 0x5996 # 0 +0x0000E8EE 0x59DA # 0 +0x0000E8EF 0x5BE5 # 0 +0x0000E8F0 0xF9BC # 0 +0x0000E8F1 0xF9BD # 0 +0x0000E8F2 0x5DA2 # 0 +0x0000E8F3 0x62D7 # 0 +0x0000E8F4 0x6416 # 0 +0x0000E8F5 0x6493 # 0 +0x0000E8F6 0x64FE # 0 +0x0000E8F7 0xF9BE # 0 +0x0000E8F8 0x66DC # 0 +0x0000E8F9 0xF9BF # 0 +0x0000E8FA 0x6A48 # 0 +0x0000E8FB 0xF9C0 # 0 +0x0000E8FC 0x71FF # 0 +0x0000E8FD 0x7464 # 0 +0x0000E8FE 0xF9C1 # 0 +0x0000E9A1 0x7A88 # 0 +0x0000E9A2 0x7AAF # 0 +0x0000E9A3 0x7E47 # 0 +0x0000E9A4 0x7E5E # 0 +0x0000E9A5 0x8000 # 0 +0x0000E9A6 0x8170 # 0 +0x0000E9A7 0xF9C2 # 0 +0x0000E9A8 0x87EF # 0 +0x0000E9A9 0x8981 # 0 +0x0000E9AA 0x8B20 # 0 +0x0000E9AB 0x9059 # 0 +0x0000E9AC 0xF9C3 # 0 +0x0000E9AD 0x9080 # 0 +0x0000E9AE 0x9952 # 0 +0x0000E9AF 0x617E # 0 +0x0000E9B0 0x6B32 # 0 +0x0000E9B1 0x6D74 # 0 +0x0000E9B2 0x7E1F # 0 +0x0000E9B3 0x8925 # 0 +0x0000E9B4 0x8FB1 # 0 +0x0000E9B5 0x4FD1 # 0 +0x0000E9B6 0x50AD # 0 +0x0000E9B7 0x5197 # 0 +0x0000E9B8 0x52C7 # 0 +0x0000E9B9 0x57C7 # 0 +0x0000E9BA 0x5889 # 0 +0x0000E9BB 0x5BB9 # 0 +0x0000E9BC 0x5EB8 # 0 +0x0000E9BD 0x6142 # 0 +0x0000E9BE 0x6995 # 0 +0x0000E9BF 0x6D8C # 0 +0x0000E9C0 0x6E67 # 0 +0x0000E9C1 0x6EB6 # 0 +0x0000E9C2 0x7194 # 0 +0x0000E9C3 0x7462 # 0 +0x0000E9C4 0x7528 # 0 +0x0000E9C5 0x752C # 0 +0x0000E9C6 0x8073 # 0 +0x0000E9C7 0x8338 # 0 +0x0000E9C8 0x84C9 # 0 +0x0000E9C9 0x8E0A # 0 +0x0000E9CA 0x9394 # 0 +0x0000E9CB 0x93DE # 0 +0x0000E9CC 0xF9C4 # 0 +0x0000E9CD 0x4E8E # 0 +0x0000E9CE 0x4F51 # 0 +0x0000E9CF 0x5076 # 0 +0x0000E9D0 0x512A # 0 +0x0000E9D1 0x53C8 # 0 +0x0000E9D2 0x53CB # 0 +0x0000E9D3 0x53F3 # 0 +0x0000E9D4 0x5B87 # 0 +0x0000E9D5 0x5BD3 # 0 +0x0000E9D6 0x5C24 # 0 +0x0000E9D7 0x611A # 0 +0x0000E9D8 0x6182 # 0 +0x0000E9D9 0x65F4 # 0 +0x0000E9DA 0x725B # 0 +0x0000E9DB 0x7397 # 0 +0x0000E9DC 0x7440 # 0 +0x0000E9DD 0x76C2 # 0 +0x0000E9DE 0x7950 # 0 +0x0000E9DF 0x7991 # 0 +0x0000E9E0 0x79B9 # 0 +0x0000E9E1 0x7D06 # 0 +0x0000E9E2 0x7FBD # 0 +0x0000E9E3 0x828B # 0 +0x0000E9E4 0x85D5 # 0 +0x0000E9E5 0x865E # 0 +0x0000E9E6 0x8FC2 # 0 +0x0000E9E7 0x9047 # 0 +0x0000E9E8 0x90F5 # 0 +0x0000E9E9 0x91EA # 0 +0x0000E9EA 0x9685 # 0 +0x0000E9EB 0x96E8 # 0 +0x0000E9EC 0x96E9 # 0 +0x0000E9ED 0x52D6 # 0 +0x0000E9EE 0x5F67 # 0 +0x0000E9EF 0x65ED # 0 +0x0000E9F0 0x6631 # 0 +0x0000E9F1 0x682F # 0 +0x0000E9F2 0x715C # 0 +0x0000E9F3 0x7A36 # 0 +0x0000E9F4 0x90C1 # 0 +0x0000E9F5 0x980A # 0 +0x0000E9F6 0x4E91 # 0 +0x0000E9F7 0xF9C5 # 0 +0x0000E9F8 0x6A52 # 0 +0x0000E9F9 0x6B9E # 0 +0x0000E9FA 0x6F90 # 0 +0x0000E9FB 0x7189 # 0 +0x0000E9FC 0x8018 # 0 +0x0000E9FD 0x82B8 # 0 +0x0000E9FE 0x8553 # 0 +0x0000EAA1 0x904B # 0 +0x0000EAA2 0x9695 # 0 +0x0000EAA3 0x96F2 # 0 +0x0000EAA4 0x97FB # 0 +0x0000EAA5 0x851A # 0 +0x0000EAA6 0x9B31 # 0 +0x0000EAA7 0x4E90 # 0 +0x0000EAA8 0x718A # 0 +0x0000EAA9 0x96C4 # 0 +0x0000EAAA 0x5143 # 0 +0x0000EAAB 0x539F # 0 +0x0000EAAC 0x54E1 # 0 +0x0000EAAD 0x5713 # 0 +0x0000EAAE 0x5712 # 0 +0x0000EAAF 0x57A3 # 0 +0x0000EAB0 0x5A9B # 0 +0x0000EAB1 0x5AC4 # 0 +0x0000EAB2 0x5BC3 # 0 +0x0000EAB3 0x6028 # 0 +0x0000EAB4 0x613F # 0 +0x0000EAB5 0x63F4 # 0 +0x0000EAB6 0x6C85 # 0 +0x0000EAB7 0x6D39 # 0 +0x0000EAB8 0x6E72 # 0 +0x0000EAB9 0x6E90 # 0 +0x0000EABA 0x7230 # 0 +0x0000EABB 0x733F # 0 +0x0000EABC 0x7457 # 0 +0x0000EABD 0x82D1 # 0 +0x0000EABE 0x8881 # 0 +0x0000EABF 0x8F45 # 0 +0x0000EAC0 0x9060 # 0 +0x0000EAC1 0xF9C6 # 0 +0x0000EAC2 0x9662 # 0 +0x0000EAC3 0x9858 # 0 +0x0000EAC4 0x9D1B # 0 +0x0000EAC5 0x6708 # 0 +0x0000EAC6 0x8D8A # 0 +0x0000EAC7 0x925E # 0 +0x0000EAC8 0x4F4D # 0 +0x0000EAC9 0x5049 # 0 +0x0000EACA 0x50DE # 0 +0x0000EACB 0x5371 # 0 +0x0000EACC 0x570D # 0 +0x0000EACD 0x59D4 # 0 +0x0000EACE 0x5A01 # 0 +0x0000EACF 0x5C09 # 0 +0x0000EAD0 0x6170 # 0 +0x0000EAD1 0x6690 # 0 +0x0000EAD2 0x6E2D # 0 +0x0000EAD3 0x7232 # 0 +0x0000EAD4 0x744B # 0 +0x0000EAD5 0x7DEF # 0 +0x0000EAD6 0x80C3 # 0 +0x0000EAD7 0x840E # 0 +0x0000EAD8 0x8466 # 0 +0x0000EAD9 0x853F # 0 +0x0000EADA 0x875F # 0 +0x0000EADB 0x885B # 0 +0x0000EADC 0x8918 # 0 +0x0000EADD 0x8B02 # 0 +0x0000EADE 0x9055 # 0 +0x0000EADF 0x97CB # 0 +0x0000EAE0 0x9B4F # 0 +0x0000EAE1 0x4E73 # 0 +0x0000EAE2 0x4F91 # 0 +0x0000EAE3 0x5112 # 0 +0x0000EAE4 0x516A # 0 +0x0000EAE5 0xF9C7 # 0 +0x0000EAE6 0x552F # 0 +0x0000EAE7 0x55A9 # 0 +0x0000EAE8 0x5B7A # 0 +0x0000EAE9 0x5BA5 # 0 +0x0000EAEA 0x5E7C # 0 +0x0000EAEB 0x5E7D # 0 +0x0000EAEC 0x5EBE # 0 +0x0000EAED 0x60A0 # 0 +0x0000EAEE 0x60DF # 0 +0x0000EAEF 0x6108 # 0 +0x0000EAF0 0x6109 # 0 +0x0000EAF1 0x63C4 # 0 +0x0000EAF2 0x6538 # 0 +0x0000EAF3 0x6709 # 0 +0x0000EAF4 0xF9C8 # 0 +0x0000EAF5 0x67D4 # 0 +0x0000EAF6 0x67DA # 0 +0x0000EAF7 0xF9C9 # 0 +0x0000EAF8 0x6961 # 0 +0x0000EAF9 0x6962 # 0 +0x0000EAFA 0x6CB9 # 0 +0x0000EAFB 0x6D27 # 0 +0x0000EAFC 0xF9CA # 0 +0x0000EAFD 0x6E38 # 0 +0x0000EAFE 0xF9CB # 0 +0x0000EBA1 0x6FE1 # 0 +0x0000EBA2 0x7336 # 0 +0x0000EBA3 0x7337 # 0 +0x0000EBA4 0xF9CC # 0 +0x0000EBA5 0x745C # 0 +0x0000EBA6 0x7531 # 0 +0x0000EBA7 0xF9CD # 0 +0x0000EBA8 0x7652 # 0 +0x0000EBA9 0xF9CE # 0 +0x0000EBAA 0xF9CF # 0 +0x0000EBAB 0x7DAD # 0 +0x0000EBAC 0x81FE # 0 +0x0000EBAD 0x8438 # 0 +0x0000EBAE 0x88D5 # 0 +0x0000EBAF 0x8A98 # 0 +0x0000EBB0 0x8ADB # 0 +0x0000EBB1 0x8AED # 0 +0x0000EBB2 0x8E30 # 0 +0x0000EBB3 0x8E42 # 0 +0x0000EBB4 0x904A # 0 +0x0000EBB5 0x903E # 0 +0x0000EBB6 0x907A # 0 +0x0000EBB7 0x9149 # 0 +0x0000EBB8 0x91C9 # 0 +0x0000EBB9 0x936E # 0 +0x0000EBBA 0xF9D0 # 0 +0x0000EBBB 0xF9D1 # 0 +0x0000EBBC 0x5809 # 0 +0x0000EBBD 0xF9D2 # 0 +0x0000EBBE 0x6BD3 # 0 +0x0000EBBF 0x8089 # 0 +0x0000EBC0 0x80B2 # 0 +0x0000EBC1 0xF9D3 # 0 +0x0000EBC2 0xF9D4 # 0 +0x0000EBC3 0x5141 # 0 +0x0000EBC4 0x596B # 0 +0x0000EBC5 0x5C39 # 0 +0x0000EBC6 0xF9D5 # 0 +0x0000EBC7 0xF9D6 # 0 +0x0000EBC8 0x6F64 # 0 +0x0000EBC9 0x73A7 # 0 +0x0000EBCA 0x80E4 # 0 +0x0000EBCB 0x8D07 # 0 +0x0000EBCC 0xF9D7 # 0 +0x0000EBCD 0x9217 # 0 +0x0000EBCE 0x958F # 0 +0x0000EBCF 0xF9D8 # 0 +0x0000EBD0 0xF9D9 # 0 +0x0000EBD1 0xF9DA # 0 +0x0000EBD2 0xF9DB # 0 +0x0000EBD3 0x807F # 0 +0x0000EBD4 0x620E # 0 +0x0000EBD5 0x701C # 0 +0x0000EBD6 0x7D68 # 0 +0x0000EBD7 0x878D # 0 +0x0000EBD8 0xF9DC # 0 +0x0000EBD9 0x57A0 # 0 +0x0000EBDA 0x6069 # 0 +0x0000EBDB 0x6147 # 0 +0x0000EBDC 0x6BB7 # 0 +0x0000EBDD 0x8ABE # 0 +0x0000EBDE 0x9280 # 0 +0x0000EBDF 0x96B1 # 0 +0x0000EBE0 0x4E59 # 0 +0x0000EBE1 0x541F # 0 +0x0000EBE2 0x6DEB # 0 +0x0000EBE3 0x852D # 0 +0x0000EBE4 0x9670 # 0 +0x0000EBE5 0x97F3 # 0 +0x0000EBE6 0x98EE # 0 +0x0000EBE7 0x63D6 # 0 +0x0000EBE8 0x6CE3 # 0 +0x0000EBE9 0x9091 # 0 +0x0000EBEA 0x51DD # 0 +0x0000EBEB 0x61C9 # 0 +0x0000EBEC 0x81BA # 0 +0x0000EBED 0x9DF9 # 0 +0x0000EBEE 0x4F9D # 0 +0x0000EBEF 0x501A # 0 +0x0000EBF0 0x5100 # 0 +0x0000EBF1 0x5B9C # 0 +0x0000EBF2 0x610F # 0 +0x0000EBF3 0x61FF # 0 +0x0000EBF4 0x64EC # 0 +0x0000EBF5 0x6905 # 0 +0x0000EBF6 0x6BC5 # 0 +0x0000EBF7 0x7591 # 0 +0x0000EBF8 0x77E3 # 0 +0x0000EBF9 0x7FA9 # 0 +0x0000EBFA 0x8264 # 0 +0x0000EBFB 0x858F # 0 +0x0000EBFC 0x87FB # 0 +0x0000EBFD 0x8863 # 0 +0x0000EBFE 0x8ABC # 0 +0x0000ECA1 0x8B70 # 0 +0x0000ECA2 0x91AB # 0 +0x0000ECA3 0x4E8C # 0 +0x0000ECA4 0x4EE5 # 0 +0x0000ECA5 0x4F0A # 0 +0x0000ECA6 0xF9DD # 0 +0x0000ECA7 0xF9DE # 0 +0x0000ECA8 0x5937 # 0 +0x0000ECA9 0x59E8 # 0 +0x0000ECAA 0xF9DF # 0 +0x0000ECAB 0x5DF2 # 0 +0x0000ECAC 0x5F1B # 0 +0x0000ECAD 0x5F5B # 0 +0x0000ECAE 0x6021 # 0 +0x0000ECAF 0xF9E0 # 0 +0x0000ECB0 0xF9E1 # 0 +0x0000ECB1 0xF9E2 # 0 +0x0000ECB2 0xF9E3 # 0 +0x0000ECB3 0x723E # 0 +0x0000ECB4 0x73E5 # 0 +0x0000ECB5 0xF9E4 # 0 +0x0000ECB6 0x7570 # 0 +0x0000ECB7 0x75CD # 0 +0x0000ECB8 0xF9E5 # 0 +0x0000ECB9 0x79FB # 0 +0x0000ECBA 0xF9E6 # 0 +0x0000ECBB 0x800C # 0 +0x0000ECBC 0x8033 # 0 +0x0000ECBD 0x8084 # 0 +0x0000ECBE 0x82E1 # 0 +0x0000ECBF 0x8351 # 0 +0x0000ECC0 0xF9E7 # 0 +0x0000ECC1 0xF9E8 # 0 +0x0000ECC2 0x8CBD # 0 +0x0000ECC3 0x8CB3 # 0 +0x0000ECC4 0x9087 # 0 +0x0000ECC5 0xF9E9 # 0 +0x0000ECC6 0xF9EA # 0 +0x0000ECC7 0x98F4 # 0 +0x0000ECC8 0x990C # 0 +0x0000ECC9 0xF9EB # 0 +0x0000ECCA 0xF9EC # 0 +0x0000ECCB 0x7037 # 0 +0x0000ECCC 0x76CA # 0 +0x0000ECCD 0x7FCA # 0 +0x0000ECCE 0x7FCC # 0 +0x0000ECCF 0x7FFC # 0 +0x0000ECD0 0x8B1A # 0 +0x0000ECD1 0x4EBA # 0 +0x0000ECD2 0x4EC1 # 0 +0x0000ECD3 0x5203 # 0 +0x0000ECD4 0x5370 # 0 +0x0000ECD5 0xF9ED # 0 +0x0000ECD6 0x54BD # 0 +0x0000ECD7 0x56E0 # 0 +0x0000ECD8 0x59FB # 0 +0x0000ECD9 0x5BC5 # 0 +0x0000ECDA 0x5F15 # 0 +0x0000ECDB 0x5FCD # 0 +0x0000ECDC 0x6E6E # 0 +0x0000ECDD 0xF9EE # 0 +0x0000ECDE 0xF9EF # 0 +0x0000ECDF 0x7D6A # 0 +0x0000ECE0 0x8335 # 0 +0x0000ECE1 0xF9F0 # 0 +0x0000ECE2 0x8693 # 0 +0x0000ECE3 0x8A8D # 0 +0x0000ECE4 0xF9F1 # 0 +0x0000ECE5 0x976D # 0 +0x0000ECE6 0x9777 # 0 +0x0000ECE7 0xF9F2 # 0 +0x0000ECE8 0xF9F3 # 0 +0x0000ECE9 0x4E00 # 0 +0x0000ECEA 0x4F5A # 0 +0x0000ECEB 0x4F7E # 0 +0x0000ECEC 0x58F9 # 0 +0x0000ECED 0x65E5 # 0 +0x0000ECEE 0x6EA2 # 0 +0x0000ECEF 0x9038 # 0 +0x0000ECF0 0x93B0 # 0 +0x0000ECF1 0x99B9 # 0 +0x0000ECF2 0x4EFB # 0 +0x0000ECF3 0x58EC # 0 +0x0000ECF4 0x598A # 0 +0x0000ECF5 0x59D9 # 0 +0x0000ECF6 0x6041 # 0 +0x0000ECF7 0xF9F4 # 0 +0x0000ECF8 0xF9F5 # 0 +0x0000ECF9 0x7A14 # 0 +0x0000ECFA 0xF9F6 # 0 +0x0000ECFB 0x834F # 0 +0x0000ECFC 0x8CC3 # 0 +0x0000ECFD 0x5165 # 0 +0x0000ECFE 0x5344 # 0 +0x0000EDA1 0xF9F7 # 0 +0x0000EDA2 0xF9F8 # 0 +0x0000EDA3 0xF9F9 # 0 +0x0000EDA4 0x4ECD # 0 +0x0000EDA5 0x5269 # 0 +0x0000EDA6 0x5B55 # 0 +0x0000EDA7 0x82BF # 0 +0x0000EDA8 0x4ED4 # 0 +0x0000EDA9 0x523A # 0 +0x0000EDAA 0x54A8 # 0 +0x0000EDAB 0x59C9 # 0 +0x0000EDAC 0x59FF # 0 +0x0000EDAD 0x5B50 # 0 +0x0000EDAE 0x5B57 # 0 +0x0000EDAF 0x5B5C # 0 +0x0000EDB0 0x6063 # 0 +0x0000EDB1 0x6148 # 0 +0x0000EDB2 0x6ECB # 0 +0x0000EDB3 0x7099 # 0 +0x0000EDB4 0x716E # 0 +0x0000EDB5 0x7386 # 0 +0x0000EDB6 0x74F7 # 0 +0x0000EDB7 0x75B5 # 0 +0x0000EDB8 0x78C1 # 0 +0x0000EDB9 0x7D2B # 0 +0x0000EDBA 0x8005 # 0 +0x0000EDBB 0x81EA # 0 +0x0000EDBC 0x8328 # 0 +0x0000EDBD 0x8517 # 0 +0x0000EDBE 0x85C9 # 0 +0x0000EDBF 0x8AEE # 0 +0x0000EDC0 0x8CC7 # 0 +0x0000EDC1 0x96CC # 0 +0x0000EDC2 0x4F5C # 0 +0x0000EDC3 0x52FA # 0 +0x0000EDC4 0x56BC # 0 +0x0000EDC5 0x65AB # 0 +0x0000EDC6 0x6628 # 0 +0x0000EDC7 0x707C # 0 +0x0000EDC8 0x70B8 # 0 +0x0000EDC9 0x7235 # 0 +0x0000EDCA 0x7DBD # 0 +0x0000EDCB 0x828D # 0 +0x0000EDCC 0x914C # 0 +0x0000EDCD 0x96C0 # 0 +0x0000EDCE 0x9D72 # 0 +0x0000EDCF 0x5B71 # 0 +0x0000EDD0 0x68E7 # 0 +0x0000EDD1 0x6B98 # 0 +0x0000EDD2 0x6F7A # 0 +0x0000EDD3 0x76DE # 0 +0x0000EDD4 0x5C91 # 0 +0x0000EDD5 0x66AB # 0 +0x0000EDD6 0x6F5B # 0 +0x0000EDD7 0x7BB4 # 0 +0x0000EDD8 0x7C2A # 0 +0x0000EDD9 0x8836 # 0 +0x0000EDDA 0x96DC # 0 +0x0000EDDB 0x4E08 # 0 +0x0000EDDC 0x4ED7 # 0 +0x0000EDDD 0x5320 # 0 +0x0000EDDE 0x5834 # 0 +0x0000EDDF 0x58BB # 0 +0x0000EDE0 0x58EF # 0 +0x0000EDE1 0x596C # 0 +0x0000EDE2 0x5C07 # 0 +0x0000EDE3 0x5E33 # 0 +0x0000EDE4 0x5E84 # 0 +0x0000EDE5 0x5F35 # 0 +0x0000EDE6 0x638C # 0 +0x0000EDE7 0x66B2 # 0 +0x0000EDE8 0x6756 # 0 +0x0000EDE9 0x6A1F # 0 +0x0000EDEA 0x6AA3 # 0 +0x0000EDEB 0x6B0C # 0 +0x0000EDEC 0x6F3F # 0 +0x0000EDED 0x7246 # 0 +0x0000EDEE 0xF9FA # 0 +0x0000EDEF 0x7350 # 0 +0x0000EDF0 0x748B # 0 +0x0000EDF1 0x7AE0 # 0 +0x0000EDF2 0x7CA7 # 0 +0x0000EDF3 0x8178 # 0 +0x0000EDF4 0x81DF # 0 +0x0000EDF5 0x81E7 # 0 +0x0000EDF6 0x838A # 0 +0x0000EDF7 0x846C # 0 +0x0000EDF8 0x8523 # 0 +0x0000EDF9 0x8594 # 0 +0x0000EDFA 0x85CF # 0 +0x0000EDFB 0x88DD # 0 +0x0000EDFC 0x8D13 # 0 +0x0000EDFD 0x91AC # 0 +0x0000EDFE 0x9577 # 0 +0x0000EEA1 0x969C # 0 +0x0000EEA2 0x518D # 0 +0x0000EEA3 0x54C9 # 0 +0x0000EEA4 0x5728 # 0 +0x0000EEA5 0x5BB0 # 0 +0x0000EEA6 0x624D # 0 +0x0000EEA7 0x6750 # 0 +0x0000EEA8 0x683D # 0 +0x0000EEA9 0x6893 # 0 +0x0000EEAA 0x6E3D # 0 +0x0000EEAB 0x6ED3 # 0 +0x0000EEAC 0x707D # 0 +0x0000EEAD 0x7E21 # 0 +0x0000EEAE 0x88C1 # 0 +0x0000EEAF 0x8CA1 # 0 +0x0000EEB0 0x8F09 # 0 +0x0000EEB1 0x9F4B # 0 +0x0000EEB2 0x9F4E # 0 +0x0000EEB3 0x722D # 0 +0x0000EEB4 0x7B8F # 0 +0x0000EEB5 0x8ACD # 0 +0x0000EEB6 0x931A # 0 +0x0000EEB7 0x4F47 # 0 +0x0000EEB8 0x4F4E # 0 +0x0000EEB9 0x5132 # 0 +0x0000EEBA 0x5480 # 0 +0x0000EEBB 0x59D0 # 0 +0x0000EEBC 0x5E95 # 0 +0x0000EEBD 0x62B5 # 0 +0x0000EEBE 0x6775 # 0 +0x0000EEBF 0x696E # 0 +0x0000EEC0 0x6A17 # 0 +0x0000EEC1 0x6CAE # 0 +0x0000EEC2 0x6E1A # 0 +0x0000EEC3 0x72D9 # 0 +0x0000EEC4 0x732A # 0 +0x0000EEC5 0x75BD # 0 +0x0000EEC6 0x7BB8 # 0 +0x0000EEC7 0x7D35 # 0 +0x0000EEC8 0x82E7 # 0 +0x0000EEC9 0x83F9 # 0 +0x0000EECA 0x8457 # 0 +0x0000EECB 0x85F7 # 0 +0x0000EECC 0x8A5B # 0 +0x0000EECD 0x8CAF # 0 +0x0000EECE 0x8E87 # 0 +0x0000EECF 0x9019 # 0 +0x0000EED0 0x90B8 # 0 +0x0000EED1 0x96CE # 0 +0x0000EED2 0x9F5F # 0 +0x0000EED3 0x52E3 # 0 +0x0000EED4 0x540A # 0 +0x0000EED5 0x5AE1 # 0 +0x0000EED6 0x5BC2 # 0 +0x0000EED7 0x6458 # 0 +0x0000EED8 0x6575 # 0 +0x0000EED9 0x6EF4 # 0 +0x0000EEDA 0x72C4 # 0 +0x0000EEDB 0xF9FB # 0 +0x0000EEDC 0x7684 # 0 +0x0000EEDD 0x7A4D # 0 +0x0000EEDE 0x7B1B # 0 +0x0000EEDF 0x7C4D # 0 +0x0000EEE0 0x7E3E # 0 +0x0000EEE1 0x7FDF # 0 +0x0000EEE2 0x837B # 0 +0x0000EEE3 0x8B2B # 0 +0x0000EEE4 0x8CCA # 0 +0x0000EEE5 0x8D64 # 0 +0x0000EEE6 0x8DE1 # 0 +0x0000EEE7 0x8E5F # 0 +0x0000EEE8 0x8FEA # 0 +0x0000EEE9 0x8FF9 # 0 +0x0000EEEA 0x9069 # 0 +0x0000EEEB 0x93D1 # 0 +0x0000EEEC 0x4F43 # 0 +0x0000EEED 0x4F7A # 0 +0x0000EEEE 0x50B3 # 0 +0x0000EEEF 0x5168 # 0 +0x0000EEF0 0x5178 # 0 +0x0000EEF1 0x524D # 0 +0x0000EEF2 0x526A # 0 +0x0000EEF3 0x5861 # 0 +0x0000EEF4 0x587C # 0 +0x0000EEF5 0x5960 # 0 +0x0000EEF6 0x5C08 # 0 +0x0000EEF7 0x5C55 # 0 +0x0000EEF8 0x5EDB # 0 +0x0000EEF9 0x609B # 0 +0x0000EEFA 0x6230 # 0 +0x0000EEFB 0x6813 # 0 +0x0000EEFC 0x6BBF # 0 +0x0000EEFD 0x6C08 # 0 +0x0000EEFE 0x6FB1 # 0 +0x0000EFA1 0x714E # 0 +0x0000EFA2 0x7420 # 0 +0x0000EFA3 0x7530 # 0 +0x0000EFA4 0x7538 # 0 +0x0000EFA5 0x7551 # 0 +0x0000EFA6 0x7672 # 0 +0x0000EFA7 0x7B4C # 0 +0x0000EFA8 0x7B8B # 0 +0x0000EFA9 0x7BAD # 0 +0x0000EFAA 0x7BC6 # 0 +0x0000EFAB 0x7E8F # 0 +0x0000EFAC 0x8A6E # 0 +0x0000EFAD 0x8F3E # 0 +0x0000EFAE 0x8F49 # 0 +0x0000EFAF 0x923F # 0 +0x0000EFB0 0x9293 # 0 +0x0000EFB1 0x9322 # 0 +0x0000EFB2 0x942B # 0 +0x0000EFB3 0x96FB # 0 +0x0000EFB4 0x985A # 0 +0x0000EFB5 0x986B # 0 +0x0000EFB6 0x991E # 0 +0x0000EFB7 0x5207 # 0 +0x0000EFB8 0x622A # 0 +0x0000EFB9 0x6298 # 0 +0x0000EFBA 0x6D59 # 0 +0x0000EFBB 0x7664 # 0 +0x0000EFBC 0x7ACA # 0 +0x0000EFBD 0x7BC0 # 0 +0x0000EFBE 0x7D76 # 0 +0x0000EFBF 0x5360 # 0 +0x0000EFC0 0x5CBE # 0 +0x0000EFC1 0x5E97 # 0 +0x0000EFC2 0x6F38 # 0 +0x0000EFC3 0x70B9 # 0 +0x0000EFC4 0x7C98 # 0 +0x0000EFC5 0x9711 # 0 +0x0000EFC6 0x9B8E # 0 +0x0000EFC7 0x9EDE # 0 +0x0000EFC8 0x63A5 # 0 +0x0000EFC9 0x647A # 0 +0x0000EFCA 0x8776 # 0 +0x0000EFCB 0x4E01 # 0 +0x0000EFCC 0x4E95 # 0 +0x0000EFCD 0x4EAD # 0 +0x0000EFCE 0x505C # 0 +0x0000EFCF 0x5075 # 0 +0x0000EFD0 0x5448 # 0 +0x0000EFD1 0x59C3 # 0 +0x0000EFD2 0x5B9A # 0 +0x0000EFD3 0x5E40 # 0 +0x0000EFD4 0x5EAD # 0 +0x0000EFD5 0x5EF7 # 0 +0x0000EFD6 0x5F81 # 0 +0x0000EFD7 0x60C5 # 0 +0x0000EFD8 0x633A # 0 +0x0000EFD9 0x653F # 0 +0x0000EFDA 0x6574 # 0 +0x0000EFDB 0x65CC # 0 +0x0000EFDC 0x6676 # 0 +0x0000EFDD 0x6678 # 0 +0x0000EFDE 0x67FE # 0 +0x0000EFDF 0x6968 # 0 +0x0000EFE0 0x6A89 # 0 +0x0000EFE1 0x6B63 # 0 +0x0000EFE2 0x6C40 # 0 +0x0000EFE3 0x6DC0 # 0 +0x0000EFE4 0x6DE8 # 0 +0x0000EFE5 0x6E1F # 0 +0x0000EFE6 0x6E5E # 0 +0x0000EFE7 0x701E # 0 +0x0000EFE8 0x70A1 # 0 +0x0000EFE9 0x738E # 0 +0x0000EFEA 0x73FD # 0 +0x0000EFEB 0x753A # 0 +0x0000EFEC 0x775B # 0 +0x0000EFED 0x7887 # 0 +0x0000EFEE 0x798E # 0 +0x0000EFEF 0x7A0B # 0 +0x0000EFF0 0x7A7D # 0 +0x0000EFF1 0x7CBE # 0 +0x0000EFF2 0x7D8E # 0 +0x0000EFF3 0x8247 # 0 +0x0000EFF4 0x8A02 # 0 +0x0000EFF5 0x8AEA # 0 +0x0000EFF6 0x8C9E # 0 +0x0000EFF7 0x912D # 0 +0x0000EFF8 0x914A # 0 +0x0000EFF9 0x91D8 # 0 +0x0000EFFA 0x9266 # 0 +0x0000EFFB 0x92CC # 0 +0x0000EFFC 0x9320 # 0 +0x0000EFFD 0x9706 # 0 +0x0000EFFE 0x9756 # 0 +0x0000F0A1 0x975C # 0 +0x0000F0A2 0x9802 # 0 +0x0000F0A3 0x9F0E # 0 +0x0000F0A4 0x5236 # 0 +0x0000F0A5 0x5291 # 0 +0x0000F0A6 0x557C # 0 +0x0000F0A7 0x5824 # 0 +0x0000F0A8 0x5E1D # 0 +0x0000F0A9 0x5F1F # 0 +0x0000F0AA 0x608C # 0 +0x0000F0AB 0x63D0 # 0 +0x0000F0AC 0x68AF # 0 +0x0000F0AD 0x6FDF # 0 +0x0000F0AE 0x796D # 0 +0x0000F0AF 0x7B2C # 0 +0x0000F0B0 0x81CD # 0 +0x0000F0B1 0x85BA # 0 +0x0000F0B2 0x88FD # 0 +0x0000F0B3 0x8AF8 # 0 +0x0000F0B4 0x8E44 # 0 +0x0000F0B5 0x918D # 0 +0x0000F0B6 0x9664 # 0 +0x0000F0B7 0x969B # 0 +0x0000F0B8 0x973D # 0 +0x0000F0B9 0x984C # 0 +0x0000F0BA 0x9F4A # 0 +0x0000F0BB 0x4FCE # 0 +0x0000F0BC 0x5146 # 0 +0x0000F0BD 0x51CB # 0 +0x0000F0BE 0x52A9 # 0 +0x0000F0BF 0x5632 # 0 +0x0000F0C0 0x5F14 # 0 +0x0000F0C1 0x5F6B # 0 +0x0000F0C2 0x63AA # 0 +0x0000F0C3 0x64CD # 0 +0x0000F0C4 0x65E9 # 0 +0x0000F0C5 0x6641 # 0 +0x0000F0C6 0x66FA # 0 +0x0000F0C7 0x66F9 # 0 +0x0000F0C8 0x671D # 0 +0x0000F0C9 0x689D # 0 +0x0000F0CA 0x68D7 # 0 +0x0000F0CB 0x69FD # 0 +0x0000F0CC 0x6F15 # 0 +0x0000F0CD 0x6F6E # 0 +0x0000F0CE 0x7167 # 0 +0x0000F0CF 0x71E5 # 0 +0x0000F0D0 0x722A # 0 +0x0000F0D1 0x74AA # 0 +0x0000F0D2 0x773A # 0 +0x0000F0D3 0x7956 # 0 +0x0000F0D4 0x795A # 0 +0x0000F0D5 0x79DF # 0 +0x0000F0D6 0x7A20 # 0 +0x0000F0D7 0x7A95 # 0 +0x0000F0D8 0x7C97 # 0 +0x0000F0D9 0x7CDF # 0 +0x0000F0DA 0x7D44 # 0 +0x0000F0DB 0x7E70 # 0 +0x0000F0DC 0x8087 # 0 +0x0000F0DD 0x85FB # 0 +0x0000F0DE 0x86A4 # 0 +0x0000F0DF 0x8A54 # 0 +0x0000F0E0 0x8ABF # 0 +0x0000F0E1 0x8D99 # 0 +0x0000F0E2 0x8E81 # 0 +0x0000F0E3 0x9020 # 0 +0x0000F0E4 0x906D # 0 +0x0000F0E5 0x91E3 # 0 +0x0000F0E6 0x963B # 0 +0x0000F0E7 0x96D5 # 0 +0x0000F0E8 0x9CE5 # 0 +0x0000F0E9 0x65CF # 0 +0x0000F0EA 0x7C07 # 0 +0x0000F0EB 0x8DB3 # 0 +0x0000F0EC 0x93C3 # 0 +0x0000F0ED 0x5B58 # 0 +0x0000F0EE 0x5C0A # 0 +0x0000F0EF 0x5352 # 0 +0x0000F0F0 0x62D9 # 0 +0x0000F0F1 0x731D # 0 +0x0000F0F2 0x5027 # 0 +0x0000F0F3 0x5B97 # 0 +0x0000F0F4 0x5F9E # 0 +0x0000F0F5 0x60B0 # 0 +0x0000F0F6 0x616B # 0 +0x0000F0F7 0x68D5 # 0 +0x0000F0F8 0x6DD9 # 0 +0x0000F0F9 0x742E # 0 +0x0000F0FA 0x7A2E # 0 +0x0000F0FB 0x7D42 # 0 +0x0000F0FC 0x7D9C # 0 +0x0000F0FD 0x7E31 # 0 +0x0000F0FE 0x816B # 0 +0x0000F1A1 0x8E2A # 0 +0x0000F1A2 0x8E35 # 0 +0x0000F1A3 0x937E # 0 +0x0000F1A4 0x9418 # 0 +0x0000F1A5 0x4F50 # 0 +0x0000F1A6 0x5750 # 0 +0x0000F1A7 0x5DE6 # 0 +0x0000F1A8 0x5EA7 # 0 +0x0000F1A9 0x632B # 0 +0x0000F1AA 0x7F6A # 0 +0x0000F1AB 0x4E3B # 0 +0x0000F1AC 0x4F4F # 0 +0x0000F1AD 0x4F8F # 0 +0x0000F1AE 0x505A # 0 +0x0000F1AF 0x59DD # 0 +0x0000F1B0 0x80C4 # 0 +0x0000F1B1 0x546A # 0 +0x0000F1B2 0x5468 # 0 +0x0000F1B3 0x55FE # 0 +0x0000F1B4 0x594F # 0 +0x0000F1B5 0x5B99 # 0 +0x0000F1B6 0x5DDE # 0 +0x0000F1B7 0x5EDA # 0 +0x0000F1B8 0x665D # 0 +0x0000F1B9 0x6731 # 0 +0x0000F1BA 0x67F1 # 0 +0x0000F1BB 0x682A # 0 +0x0000F1BC 0x6CE8 # 0 +0x0000F1BD 0x6D32 # 0 +0x0000F1BE 0x6E4A # 0 +0x0000F1BF 0x6F8D # 0 +0x0000F1C0 0x70B7 # 0 +0x0000F1C1 0x73E0 # 0 +0x0000F1C2 0x7587 # 0 +0x0000F1C3 0x7C4C # 0 +0x0000F1C4 0x7D02 # 0 +0x0000F1C5 0x7D2C # 0 +0x0000F1C6 0x7DA2 # 0 +0x0000F1C7 0x821F # 0 +0x0000F1C8 0x86DB # 0 +0x0000F1C9 0x8A3B # 0 +0x0000F1CA 0x8A85 # 0 +0x0000F1CB 0x8D70 # 0 +0x0000F1CC 0x8E8A # 0 +0x0000F1CD 0x8F33 # 0 +0x0000F1CE 0x9031 # 0 +0x0000F1CF 0x914E # 0 +0x0000F1D0 0x9152 # 0 +0x0000F1D1 0x9444 # 0 +0x0000F1D2 0x99D0 # 0 +0x0000F1D3 0x7AF9 # 0 +0x0000F1D4 0x7CA5 # 0 +0x0000F1D5 0x4FCA # 0 +0x0000F1D6 0x5101 # 0 +0x0000F1D7 0x51C6 # 0 +0x0000F1D8 0x57C8 # 0 +0x0000F1D9 0x5BEF # 0 +0x0000F1DA 0x5CFB # 0 +0x0000F1DB 0x6659 # 0 +0x0000F1DC 0x6A3D # 0 +0x0000F1DD 0x6D5A # 0 +0x0000F1DE 0x6E96 # 0 +0x0000F1DF 0x6FEC # 0 +0x0000F1E0 0x710C # 0 +0x0000F1E1 0x756F # 0 +0x0000F1E2 0x7AE3 # 0 +0x0000F1E3 0x8822 # 0 +0x0000F1E4 0x9021 # 0 +0x0000F1E5 0x9075 # 0 +0x0000F1E6 0x96CB # 0 +0x0000F1E7 0x99FF # 0 +0x0000F1E8 0x8301 # 0 +0x0000F1E9 0x4E2D # 0 +0x0000F1EA 0x4EF2 # 0 +0x0000F1EB 0x8846 # 0 +0x0000F1EC 0x91CD # 0 +0x0000F1ED 0x537D # 0 +0x0000F1EE 0x6ADB # 0 +0x0000F1EF 0x696B # 0 +0x0000F1F0 0x6C41 # 0 +0x0000F1F1 0x847A # 0 +0x0000F1F2 0x589E # 0 +0x0000F1F3 0x618E # 0 +0x0000F1F4 0x66FE # 0 +0x0000F1F5 0x62EF # 0 +0x0000F1F6 0x70DD # 0 +0x0000F1F7 0x7511 # 0 +0x0000F1F8 0x75C7 # 0 +0x0000F1F9 0x7E52 # 0 +0x0000F1FA 0x84B8 # 0 +0x0000F1FB 0x8B49 # 0 +0x0000F1FC 0x8D08 # 0 +0x0000F1FD 0x4E4B # 0 +0x0000F1FE 0x53EA # 0 +0x0000F2A1 0x54AB # 0 +0x0000F2A2 0x5730 # 0 +0x0000F2A3 0x5740 # 0 +0x0000F2A4 0x5FD7 # 0 +0x0000F2A5 0x6301 # 0 +0x0000F2A6 0x6307 # 0 +0x0000F2A7 0x646F # 0 +0x0000F2A8 0x652F # 0 +0x0000F2A9 0x65E8 # 0 +0x0000F2AA 0x667A # 0 +0x0000F2AB 0x679D # 0 +0x0000F2AC 0x67B3 # 0 +0x0000F2AD 0x6B62 # 0 +0x0000F2AE 0x6C60 # 0 +0x0000F2AF 0x6C9A # 0 +0x0000F2B0 0x6F2C # 0 +0x0000F2B1 0x77E5 # 0 +0x0000F2B2 0x7825 # 0 +0x0000F2B3 0x7949 # 0 +0x0000F2B4 0x7957 # 0 +0x0000F2B5 0x7D19 # 0 +0x0000F2B6 0x80A2 # 0 +0x0000F2B7 0x8102 # 0 +0x0000F2B8 0x81F3 # 0 +0x0000F2B9 0x829D # 0 +0x0000F2BA 0x82B7 # 0 +0x0000F2BB 0x8718 # 0 +0x0000F2BC 0x8A8C # 0 +0x0000F2BD 0xF9FC # 0 +0x0000F2BE 0x8D04 # 0 +0x0000F2BF 0x8DBE # 0 +0x0000F2C0 0x9072 # 0 +0x0000F2C1 0x76F4 # 0 +0x0000F2C2 0x7A19 # 0 +0x0000F2C3 0x7A37 # 0 +0x0000F2C4 0x7E54 # 0 +0x0000F2C5 0x8077 # 0 +0x0000F2C6 0x5507 # 0 +0x0000F2C7 0x55D4 # 0 +0x0000F2C8 0x5875 # 0 +0x0000F2C9 0x632F # 0 +0x0000F2CA 0x6422 # 0 +0x0000F2CB 0x6649 # 0 +0x0000F2CC 0x664B # 0 +0x0000F2CD 0x686D # 0 +0x0000F2CE 0x699B # 0 +0x0000F2CF 0x6B84 # 0 +0x0000F2D0 0x6D25 # 0 +0x0000F2D1 0x6EB1 # 0 +0x0000F2D2 0x73CD # 0 +0x0000F2D3 0x7468 # 0 +0x0000F2D4 0x74A1 # 0 +0x0000F2D5 0x755B # 0 +0x0000F2D6 0x75B9 # 0 +0x0000F2D7 0x76E1 # 0 +0x0000F2D8 0x771E # 0 +0x0000F2D9 0x778B # 0 +0x0000F2DA 0x79E6 # 0 +0x0000F2DB 0x7E09 # 0 +0x0000F2DC 0x7E1D # 0 +0x0000F2DD 0x81FB # 0 +0x0000F2DE 0x852F # 0 +0x0000F2DF 0x8897 # 0 +0x0000F2E0 0x8A3A # 0 +0x0000F2E1 0x8CD1 # 0 +0x0000F2E2 0x8EEB # 0 +0x0000F2E3 0x8FB0 # 0 +0x0000F2E4 0x9032 # 0 +0x0000F2E5 0x93AD # 0 +0x0000F2E6 0x9663 # 0 +0x0000F2E7 0x9673 # 0 +0x0000F2E8 0x9707 # 0 +0x0000F2E9 0x4F84 # 0 +0x0000F2EA 0x53F1 # 0 +0x0000F2EB 0x59EA # 0 +0x0000F2EC 0x5AC9 # 0 +0x0000F2ED 0x5E19 # 0 +0x0000F2EE 0x684E # 0 +0x0000F2EF 0x74C6 # 0 +0x0000F2F0 0x75BE # 0 +0x0000F2F1 0x79E9 # 0 +0x0000F2F2 0x7A92 # 0 +0x0000F2F3 0x81A3 # 0 +0x0000F2F4 0x86ED # 0 +0x0000F2F5 0x8CEA # 0 +0x0000F2F6 0x8DCC # 0 +0x0000F2F7 0x8FED # 0 +0x0000F2F8 0x659F # 0 +0x0000F2F9 0x6715 # 0 +0x0000F2FA 0xF9FD # 0 +0x0000F2FB 0x57F7 # 0 +0x0000F2FC 0x6F57 # 0 +0x0000F2FD 0x7DDD # 0 +0x0000F2FE 0x8F2F # 0 +0x0000F3A1 0x93F6 # 0 +0x0000F3A2 0x96C6 # 0 +0x0000F3A3 0x5FB5 # 0 +0x0000F3A4 0x61F2 # 0 +0x0000F3A5 0x6F84 # 0 +0x0000F3A6 0x4E14 # 0 +0x0000F3A7 0x4F98 # 0 +0x0000F3A8 0x501F # 0 +0x0000F3A9 0x53C9 # 0 +0x0000F3AA 0x55DF # 0 +0x0000F3AB 0x5D6F # 0 +0x0000F3AC 0x5DEE # 0 +0x0000F3AD 0x6B21 # 0 +0x0000F3AE 0x6B64 # 0 +0x0000F3AF 0x78CB # 0 +0x0000F3B0 0x7B9A # 0 +0x0000F3B1 0xF9FE # 0 +0x0000F3B2 0x8E49 # 0 +0x0000F3B3 0x8ECA # 0 +0x0000F3B4 0x906E # 0 +0x0000F3B5 0x6349 # 0 +0x0000F3B6 0x643E # 0 +0x0000F3B7 0x7740 # 0 +0x0000F3B8 0x7A84 # 0 +0x0000F3B9 0x932F # 0 +0x0000F3BA 0x947F # 0 +0x0000F3BB 0x9F6A # 0 +0x0000F3BC 0x64B0 # 0 +0x0000F3BD 0x6FAF # 0 +0x0000F3BE 0x71E6 # 0 +0x0000F3BF 0x74A8 # 0 +0x0000F3C0 0x74DA # 0 +0x0000F3C1 0x7AC4 # 0 +0x0000F3C2 0x7C12 # 0 +0x0000F3C3 0x7E82 # 0 +0x0000F3C4 0x7CB2 # 0 +0x0000F3C5 0x7E98 # 0 +0x0000F3C6 0x8B9A # 0 +0x0000F3C7 0x8D0A # 0 +0x0000F3C8 0x947D # 0 +0x0000F3C9 0x9910 # 0 +0x0000F3CA 0x994C # 0 +0x0000F3CB 0x5239 # 0 +0x0000F3CC 0x5BDF # 0 +0x0000F3CD 0x64E6 # 0 +0x0000F3CE 0x672D # 0 +0x0000F3CF 0x7D2E # 0 +0x0000F3D0 0x50ED # 0 +0x0000F3D1 0x53C3 # 0 +0x0000F3D2 0x5879 # 0 +0x0000F3D3 0x6158 # 0 +0x0000F3D4 0x6159 # 0 +0x0000F3D5 0x61FA # 0 +0x0000F3D6 0x65AC # 0 +0x0000F3D7 0x7AD9 # 0 +0x0000F3D8 0x8B92 # 0 +0x0000F3D9 0x8B96 # 0 +0x0000F3DA 0x5009 # 0 +0x0000F3DB 0x5021 # 0 +0x0000F3DC 0x5275 # 0 +0x0000F3DD 0x5531 # 0 +0x0000F3DE 0x5A3C # 0 +0x0000F3DF 0x5EE0 # 0 +0x0000F3E0 0x5F70 # 0 +0x0000F3E1 0x6134 # 0 +0x0000F3E2 0x655E # 0 +0x0000F3E3 0x660C # 0 +0x0000F3E4 0x6636 # 0 +0x0000F3E5 0x66A2 # 0 +0x0000F3E6 0x69CD # 0 +0x0000F3E7 0x6EC4 # 0 +0x0000F3E8 0x6F32 # 0 +0x0000F3E9 0x7316 # 0 +0x0000F3EA 0x7621 # 0 +0x0000F3EB 0x7A93 # 0 +0x0000F3EC 0x8139 # 0 +0x0000F3ED 0x8259 # 0 +0x0000F3EE 0x83D6 # 0 +0x0000F3EF 0x84BC # 0 +0x0000F3F0 0x50B5 # 0 +0x0000F3F1 0x57F0 # 0 +0x0000F3F2 0x5BC0 # 0 +0x0000F3F3 0x5BE8 # 0 +0x0000F3F4 0x5F69 # 0 +0x0000F3F5 0x63A1 # 0 +0x0000F3F6 0x7826 # 0 +0x0000F3F7 0x7DB5 # 0 +0x0000F3F8 0x83DC # 0 +0x0000F3F9 0x8521 # 0 +0x0000F3FA 0x91C7 # 0 +0x0000F3FB 0x91F5 # 0 +0x0000F3FC 0x518A # 0 +0x0000F3FD 0x67F5 # 0 +0x0000F3FE 0x7B56 # 0 +0x0000F4A1 0x8CAC # 0 +0x0000F4A2 0x51C4 # 0 +0x0000F4A3 0x59BB # 0 +0x0000F4A4 0x60BD # 0 +0x0000F4A5 0x8655 # 0 +0x0000F4A6 0x501C # 0 +0x0000F4A7 0xF9FF # 0 +0x0000F4A8 0x5254 # 0 +0x0000F4A9 0x5C3A # 0 +0x0000F4AA 0x617D # 0 +0x0000F4AB 0x621A # 0 +0x0000F4AC 0x62D3 # 0 +0x0000F4AD 0x64F2 # 0 +0x0000F4AE 0x65A5 # 0 +0x0000F4AF 0x6ECC # 0 +0x0000F4B0 0x7620 # 0 +0x0000F4B1 0x810A # 0 +0x0000F4B2 0x8E60 # 0 +0x0000F4B3 0x965F # 0 +0x0000F4B4 0x96BB # 0 +0x0000F4B5 0x4EDF # 0 +0x0000F4B6 0x5343 # 0 +0x0000F4B7 0x5598 # 0 +0x0000F4B8 0x5929 # 0 +0x0000F4B9 0x5DDD # 0 +0x0000F4BA 0x64C5 # 0 +0x0000F4BB 0x6CC9 # 0 +0x0000F4BC 0x6DFA # 0 +0x0000F4BD 0x7394 # 0 +0x0000F4BE 0x7A7F # 0 +0x0000F4BF 0x821B # 0 +0x0000F4C0 0x85A6 # 0 +0x0000F4C1 0x8CE4 # 0 +0x0000F4C2 0x8E10 # 0 +0x0000F4C3 0x9077 # 0 +0x0000F4C4 0x91E7 # 0 +0x0000F4C5 0x95E1 # 0 +0x0000F4C6 0x9621 # 0 +0x0000F4C7 0x97C6 # 0 +0x0000F4C8 0x51F8 # 0 +0x0000F4C9 0x54F2 # 0 +0x0000F4CA 0x5586 # 0 +0x0000F4CB 0x5FB9 # 0 +0x0000F4CC 0x64A4 # 0 +0x0000F4CD 0x6F88 # 0 +0x0000F4CE 0x7DB4 # 0 +0x0000F4CF 0x8F1F # 0 +0x0000F4D0 0x8F4D # 0 +0x0000F4D1 0x9435 # 0 +0x0000F4D2 0x50C9 # 0 +0x0000F4D3 0x5C16 # 0 +0x0000F4D4 0x6CBE # 0 +0x0000F4D5 0x6DFB # 0 +0x0000F4D6 0x751B # 0 +0x0000F4D7 0x77BB # 0 +0x0000F4D8 0x7C3D # 0 +0x0000F4D9 0x7C64 # 0 +0x0000F4DA 0x8A79 # 0 +0x0000F4DB 0x8AC2 # 0 +0x0000F4DC 0x581E # 0 +0x0000F4DD 0x59BE # 0 +0x0000F4DE 0x5E16 # 0 +0x0000F4DF 0x6377 # 0 +0x0000F4E0 0x7252 # 0 +0x0000F4E1 0x758A # 0 +0x0000F4E2 0x776B # 0 +0x0000F4E3 0x8ADC # 0 +0x0000F4E4 0x8CBC # 0 +0x0000F4E5 0x8F12 # 0 +0x0000F4E6 0x5EF3 # 0 +0x0000F4E7 0x6674 # 0 +0x0000F4E8 0x6DF8 # 0 +0x0000F4E9 0x807D # 0 +0x0000F4EA 0x83C1 # 0 +0x0000F4EB 0x8ACB # 0 +0x0000F4EC 0x9751 # 0 +0x0000F4ED 0x9BD6 # 0 +0x0000F4EE 0xFA00 # 0 +0x0000F4EF 0x5243 # 0 +0x0000F4F0 0x66FF # 0 +0x0000F4F1 0x6D95 # 0 +0x0000F4F2 0x6EEF # 0 +0x0000F4F3 0x7DE0 # 0 +0x0000F4F4 0x8AE6 # 0 +0x0000F4F5 0x902E # 0 +0x0000F4F6 0x905E # 0 +0x0000F4F7 0x9AD4 # 0 +0x0000F4F8 0x521D # 0 +0x0000F4F9 0x527F # 0 +0x0000F4FA 0x54E8 # 0 +0x0000F4FB 0x6194 # 0 +0x0000F4FC 0x6284 # 0 +0x0000F4FD 0x62DB # 0 +0x0000F4FE 0x68A2 # 0 +0x0000F5A1 0x6912 # 0 +0x0000F5A2 0x695A # 0 +0x0000F5A3 0x6A35 # 0 +0x0000F5A4 0x7092 # 0 +0x0000F5A5 0x7126 # 0 +0x0000F5A6 0x785D # 0 +0x0000F5A7 0x7901 # 0 +0x0000F5A8 0x790E # 0 +0x0000F5A9 0x79D2 # 0 +0x0000F5AA 0x7A0D # 0 +0x0000F5AB 0x8096 # 0 +0x0000F5AC 0x8278 # 0 +0x0000F5AD 0x82D5 # 0 +0x0000F5AE 0x8349 # 0 +0x0000F5AF 0x8549 # 0 +0x0000F5B0 0x8C82 # 0 +0x0000F5B1 0x8D85 # 0 +0x0000F5B2 0x9162 # 0 +0x0000F5B3 0x918B # 0 +0x0000F5B4 0x91AE # 0 +0x0000F5B5 0x4FC3 # 0 +0x0000F5B6 0x56D1 # 0 +0x0000F5B7 0x71ED # 0 +0x0000F5B8 0x77D7 # 0 +0x0000F5B9 0x8700 # 0 +0x0000F5BA 0x89F8 # 0 +0x0000F5BB 0x5BF8 # 0 +0x0000F5BC 0x5FD6 # 0 +0x0000F5BD 0x6751 # 0 +0x0000F5BE 0x90A8 # 0 +0x0000F5BF 0x53E2 # 0 +0x0000F5C0 0x585A # 0 +0x0000F5C1 0x5BF5 # 0 +0x0000F5C2 0x60A4 # 0 +0x0000F5C3 0x6181 # 0 +0x0000F5C4 0x6460 # 0 +0x0000F5C5 0x7E3D # 0 +0x0000F5C6 0x8070 # 0 +0x0000F5C7 0x8525 # 0 +0x0000F5C8 0x9283 # 0 +0x0000F5C9 0x64AE # 0 +0x0000F5CA 0x50AC # 0 +0x0000F5CB 0x5D14 # 0 +0x0000F5CC 0x6700 # 0 +0x0000F5CD 0x589C # 0 +0x0000F5CE 0x62BD # 0 +0x0000F5CF 0x63A8 # 0 +0x0000F5D0 0x690E # 0 +0x0000F5D1 0x6978 # 0 +0x0000F5D2 0x6A1E # 0 +0x0000F5D3 0x6E6B # 0 +0x0000F5D4 0x76BA # 0 +0x0000F5D5 0x79CB # 0 +0x0000F5D6 0x82BB # 0 +0x0000F5D7 0x8429 # 0 +0x0000F5D8 0x8ACF # 0 +0x0000F5D9 0x8DA8 # 0 +0x0000F5DA 0x8FFD # 0 +0x0000F5DB 0x9112 # 0 +0x0000F5DC 0x914B # 0 +0x0000F5DD 0x919C # 0 +0x0000F5DE 0x9310 # 0 +0x0000F5DF 0x9318 # 0 +0x0000F5E0 0x939A # 0 +0x0000F5E1 0x96DB # 0 +0x0000F5E2 0x9A36 # 0 +0x0000F5E3 0x9C0D # 0 +0x0000F5E4 0x4E11 # 0 +0x0000F5E5 0x755C # 0 +0x0000F5E6 0x795D # 0 +0x0000F5E7 0x7AFA # 0 +0x0000F5E8 0x7B51 # 0 +0x0000F5E9 0x7BC9 # 0 +0x0000F5EA 0x7E2E # 0 +0x0000F5EB 0x84C4 # 0 +0x0000F5EC 0x8E59 # 0 +0x0000F5ED 0x8E74 # 0 +0x0000F5EE 0x8EF8 # 0 +0x0000F5EF 0x9010 # 0 +0x0000F5F0 0x6625 # 0 +0x0000F5F1 0x693F # 0 +0x0000F5F2 0x7443 # 0 +0x0000F5F3 0x51FA # 0 +0x0000F5F4 0x672E # 0 +0x0000F5F5 0x9EDC # 0 +0x0000F5F6 0x5145 # 0 +0x0000F5F7 0x5FE0 # 0 +0x0000F5F8 0x6C96 # 0 +0x0000F5F9 0x87F2 # 0 +0x0000F5FA 0x885D # 0 +0x0000F5FB 0x8877 # 0 +0x0000F5FC 0x60B4 # 0 +0x0000F5FD 0x81B5 # 0 +0x0000F5FE 0x8403 # 0 +0x0000F6A1 0x8D05 # 0 +0x0000F6A2 0x53D6 # 0 +0x0000F6A3 0x5439 # 0 +0x0000F6A4 0x5634 # 0 +0x0000F6A5 0x5A36 # 0 +0x0000F6A6 0x5C31 # 0 +0x0000F6A7 0x708A # 0 +0x0000F6A8 0x7FE0 # 0 +0x0000F6A9 0x805A # 0 +0x0000F6AA 0x8106 # 0 +0x0000F6AB 0x81ED # 0 +0x0000F6AC 0x8DA3 # 0 +0x0000F6AD 0x9189 # 0 +0x0000F6AE 0x9A5F # 0 +0x0000F6AF 0x9DF2 # 0 +0x0000F6B0 0x5074 # 0 +0x0000F6B1 0x4EC4 # 0 +0x0000F6B2 0x53A0 # 0 +0x0000F6B3 0x60FB # 0 +0x0000F6B4 0x6E2C # 0 +0x0000F6B5 0x5C64 # 0 +0x0000F6B6 0x4F88 # 0 +0x0000F6B7 0x5024 # 0 +0x0000F6B8 0x55E4 # 0 +0x0000F6B9 0x5CD9 # 0 +0x0000F6BA 0x5E5F # 0 +0x0000F6BB 0x6065 # 0 +0x0000F6BC 0x6894 # 0 +0x0000F6BD 0x6CBB # 0 +0x0000F6BE 0x6DC4 # 0 +0x0000F6BF 0x71BE # 0 +0x0000F6C0 0x75D4 # 0 +0x0000F6C1 0x75F4 # 0 +0x0000F6C2 0x7661 # 0 +0x0000F6C3 0x7A1A # 0 +0x0000F6C4 0x7A49 # 0 +0x0000F6C5 0x7DC7 # 0 +0x0000F6C6 0x7DFB # 0 +0x0000F6C7 0x7F6E # 0 +0x0000F6C8 0x81F4 # 0 +0x0000F6C9 0x86A9 # 0 +0x0000F6CA 0x8F1C # 0 +0x0000F6CB 0x96C9 # 0 +0x0000F6CC 0x99B3 # 0 +0x0000F6CD 0x9F52 # 0 +0x0000F6CE 0x5247 # 0 +0x0000F6CF 0x52C5 # 0 +0x0000F6D0 0x98ED # 0 +0x0000F6D1 0x89AA # 0 +0x0000F6D2 0x4E03 # 0 +0x0000F6D3 0x67D2 # 0 +0x0000F6D4 0x6F06 # 0 +0x0000F6D5 0x4FB5 # 0 +0x0000F6D6 0x5BE2 # 0 +0x0000F6D7 0x6795 # 0 +0x0000F6D8 0x6C88 # 0 +0x0000F6D9 0x6D78 # 0 +0x0000F6DA 0x741B # 0 +0x0000F6DB 0x7827 # 0 +0x0000F6DC 0x91DD # 0 +0x0000F6DD 0x937C # 0 +0x0000F6DE 0x87C4 # 0 +0x0000F6DF 0x79E4 # 0 +0x0000F6E0 0x7A31 # 0 +0x0000F6E1 0x5FEB # 0 +0x0000F6E2 0x4ED6 # 0 +0x0000F6E3 0x54A4 # 0 +0x0000F6E4 0x553E # 0 +0x0000F6E5 0x58AE # 0 +0x0000F6E6 0x59A5 # 0 +0x0000F6E7 0x60F0 # 0 +0x0000F6E8 0x6253 # 0 +0x0000F6E9 0x62D6 # 0 +0x0000F6EA 0x6736 # 0 +0x0000F6EB 0x6955 # 0 +0x0000F6EC 0x8235 # 0 +0x0000F6ED 0x9640 # 0 +0x0000F6EE 0x99B1 # 0 +0x0000F6EF 0x99DD # 0 +0x0000F6F0 0x502C # 0 +0x0000F6F1 0x5353 # 0 +0x0000F6F2 0x5544 # 0 +0x0000F6F3 0x577C # 0 +0x0000F6F4 0xFA01 # 0 +0x0000F6F5 0x6258 # 0 +0x0000F6F6 0xFA02 # 0 +0x0000F6F7 0x64E2 # 0 +0x0000F6F8 0x666B # 0 +0x0000F6F9 0x67DD # 0 +0x0000F6FA 0x6FC1 # 0 +0x0000F6FB 0x6FEF # 0 +0x0000F6FC 0x7422 # 0 +0x0000F6FD 0x7438 # 0 +0x0000F6FE 0x8A17 # 0 +0x0000F7A1 0x9438 # 0 +0x0000F7A2 0x5451 # 0 +0x0000F7A3 0x5606 # 0 +0x0000F7A4 0x5766 # 0 +0x0000F7A5 0x5F48 # 0 +0x0000F7A6 0x619A # 0 +0x0000F7A7 0x6B4E # 0 +0x0000F7A8 0x7058 # 0 +0x0000F7A9 0x70AD # 0 +0x0000F7AA 0x7DBB # 0 +0x0000F7AB 0x8A95 # 0 +0x0000F7AC 0x596A # 0 +0x0000F7AD 0x812B # 0 +0x0000F7AE 0x63A2 # 0 +0x0000F7AF 0x7708 # 0 +0x0000F7B0 0x803D # 0 +0x0000F7B1 0x8CAA # 0 +0x0000F7B2 0x5854 # 0 +0x0000F7B3 0x642D # 0 +0x0000F7B4 0x69BB # 0 +0x0000F7B5 0x5B95 # 0 +0x0000F7B6 0x5E11 # 0 +0x0000F7B7 0x6E6F # 0 +0x0000F7B8 0xFA03 # 0 +0x0000F7B9 0x8569 # 0 +0x0000F7BA 0x514C # 0 +0x0000F7BB 0x53F0 # 0 +0x0000F7BC 0x592A # 0 +0x0000F7BD 0x6020 # 0 +0x0000F7BE 0x614B # 0 +0x0000F7BF 0x6B86 # 0 +0x0000F7C0 0x6C70 # 0 +0x0000F7C1 0x6CF0 # 0 +0x0000F7C2 0x7B1E # 0 +0x0000F7C3 0x80CE # 0 +0x0000F7C4 0x82D4 # 0 +0x0000F7C5 0x8DC6 # 0 +0x0000F7C6 0x90B0 # 0 +0x0000F7C7 0x98B1 # 0 +0x0000F7C8 0xFA04 # 0 +0x0000F7C9 0x64C7 # 0 +0x0000F7CA 0x6FA4 # 0 +0x0000F7CB 0x6491 # 0 +0x0000F7CC 0x6504 # 0 +0x0000F7CD 0x514E # 0 +0x0000F7CE 0x5410 # 0 +0x0000F7CF 0x571F # 0 +0x0000F7D0 0x8A0E # 0 +0x0000F7D1 0x615F # 0 +0x0000F7D2 0x6876 # 0 +0x0000F7D3 0xFA05 # 0 +0x0000F7D4 0x75DB # 0 +0x0000F7D5 0x7B52 # 0 +0x0000F7D6 0x7D71 # 0 +0x0000F7D7 0x901A # 0 +0x0000F7D8 0x5806 # 0 +0x0000F7D9 0x69CC # 0 +0x0000F7DA 0x817F # 0 +0x0000F7DB 0x892A # 0 +0x0000F7DC 0x9000 # 0 +0x0000F7DD 0x9839 # 0 +0x0000F7DE 0x5078 # 0 +0x0000F7DF 0x5957 # 0 +0x0000F7E0 0x59AC # 0 +0x0000F7E1 0x6295 # 0 +0x0000F7E2 0x900F # 0 +0x0000F7E3 0x9B2A # 0 +0x0000F7E4 0x615D # 0 +0x0000F7E5 0x7279 # 0 +0x0000F7E6 0x95D6 # 0 +0x0000F7E7 0x5761 # 0 +0x0000F7E8 0x5A46 # 0 +0x0000F7E9 0x5DF4 # 0 +0x0000F7EA 0x628A # 0 +0x0000F7EB 0x64AD # 0 +0x0000F7EC 0x64FA # 0 +0x0000F7ED 0x6777 # 0 +0x0000F7EE 0x6CE2 # 0 +0x0000F7EF 0x6D3E # 0 +0x0000F7F0 0x722C # 0 +0x0000F7F1 0x7436 # 0 +0x0000F7F2 0x7834 # 0 +0x0000F7F3 0x7F77 # 0 +0x0000F7F4 0x82AD # 0 +0x0000F7F5 0x8DDB # 0 +0x0000F7F6 0x9817 # 0 +0x0000F7F7 0x5224 # 0 +0x0000F7F8 0x5742 # 0 +0x0000F7F9 0x677F # 0 +0x0000F7FA 0x7248 # 0 +0x0000F7FB 0x74E3 # 0 +0x0000F7FC 0x8CA9 # 0 +0x0000F7FD 0x8FA6 # 0 +0x0000F7FE 0x9211 # 0 +0x0000F8A1 0x962A # 0 +0x0000F8A2 0x516B # 0 +0x0000F8A3 0x53ED # 0 +0x0000F8A4 0x634C # 0 +0x0000F8A5 0x4F69 # 0 +0x0000F8A6 0x5504 # 0 +0x0000F8A7 0x6096 # 0 +0x0000F8A8 0x6557 # 0 +0x0000F8A9 0x6C9B # 0 +0x0000F8AA 0x6D7F # 0 +0x0000F8AB 0x724C # 0 +0x0000F8AC 0x72FD # 0 +0x0000F8AD 0x7A17 # 0 +0x0000F8AE 0x8987 # 0 +0x0000F8AF 0x8C9D # 0 +0x0000F8B0 0x5F6D # 0 +0x0000F8B1 0x6F8E # 0 +0x0000F8B2 0x70F9 # 0 +0x0000F8B3 0x81A8 # 0 +0x0000F8B4 0x610E # 0 +0x0000F8B5 0x4FBF # 0 +0x0000F8B6 0x504F # 0 +0x0000F8B7 0x6241 # 0 +0x0000F8B8 0x7247 # 0 +0x0000F8B9 0x7BC7 # 0 +0x0000F8BA 0x7DE8 # 0 +0x0000F8BB 0x7FE9 # 0 +0x0000F8BC 0x904D # 0 +0x0000F8BD 0x97AD # 0 +0x0000F8BE 0x9A19 # 0 +0x0000F8BF 0x8CB6 # 0 +0x0000F8C0 0x576A # 0 +0x0000F8C1 0x5E73 # 0 +0x0000F8C2 0x67B0 # 0 +0x0000F8C3 0x840D # 0 +0x0000F8C4 0x8A55 # 0 +0x0000F8C5 0x5420 # 0 +0x0000F8C6 0x5B16 # 0 +0x0000F8C7 0x5E63 # 0 +0x0000F8C8 0x5EE2 # 0 +0x0000F8C9 0x5F0A # 0 +0x0000F8CA 0x6583 # 0 +0x0000F8CB 0x80BA # 0 +0x0000F8CC 0x853D # 0 +0x0000F8CD 0x9589 # 0 +0x0000F8CE 0x965B # 0 +0x0000F8CF 0x4F48 # 0 +0x0000F8D0 0x5305 # 0 +0x0000F8D1 0x530D # 0 +0x0000F8D2 0x530F # 0 +0x0000F8D3 0x5486 # 0 +0x0000F8D4 0x54FA # 0 +0x0000F8D5 0x5703 # 0 +0x0000F8D6 0x5E03 # 0 +0x0000F8D7 0x6016 # 0 +0x0000F8D8 0x629B # 0 +0x0000F8D9 0x62B1 # 0 +0x0000F8DA 0x6355 # 0 +0x0000F8DB 0xFA06 # 0 +0x0000F8DC 0x6CE1 # 0 +0x0000F8DD 0x6D66 # 0 +0x0000F8DE 0x75B1 # 0 +0x0000F8DF 0x7832 # 0 +0x0000F8E0 0x80DE # 0 +0x0000F8E1 0x812F # 0 +0x0000F8E2 0x82DE # 0 +0x0000F8E3 0x8461 # 0 +0x0000F8E4 0x84B2 # 0 +0x0000F8E5 0x888D # 0 +0x0000F8E6 0x8912 # 0 +0x0000F8E7 0x900B # 0 +0x0000F8E8 0x92EA # 0 +0x0000F8E9 0x98FD # 0 +0x0000F8EA 0x9B91 # 0 +0x0000F8EB 0x5E45 # 0 +0x0000F8EC 0x66B4 # 0 +0x0000F8ED 0x66DD # 0 +0x0000F8EE 0x7011 # 0 +0x0000F8EF 0x7206 # 0 +0x0000F8F0 0xFA07 # 0 +0x0000F8F1 0x4FF5 # 0 +0x0000F8F2 0x527D # 0 +0x0000F8F3 0x5F6A # 0 +0x0000F8F4 0x6153 # 0 +0x0000F8F5 0x6753 # 0 +0x0000F8F6 0x6A19 # 0 +0x0000F8F7 0x6F02 # 0 +0x0000F8F8 0x74E2 # 0 +0x0000F8F9 0x7968 # 0 +0x0000F8FA 0x8868 # 0 +0x0000F8FB 0x8C79 # 0 +0x0000F8FC 0x98C7 # 0 +0x0000F8FD 0x98C4 # 0 +0x0000F8FE 0x9A43 # 0 +0x0000F9A1 0x54C1 # 0 +0x0000F9A2 0x7A1F # 0 +0x0000F9A3 0x6953 # 0 +0x0000F9A4 0x8AF7 # 0 +0x0000F9A5 0x8C4A # 0 +0x0000F9A6 0x98A8 # 0 +0x0000F9A7 0x99AE # 0 +0x0000F9A8 0x5F7C # 0 +0x0000F9A9 0x62AB # 0 +0x0000F9AA 0x75B2 # 0 +0x0000F9AB 0x76AE # 0 +0x0000F9AC 0x88AB # 0 +0x0000F9AD 0x907F # 0 +0x0000F9AE 0x9642 # 0 +0x0000F9AF 0x5339 # 0 +0x0000F9B0 0x5F3C # 0 +0x0000F9B1 0x5FC5 # 0 +0x0000F9B2 0x6CCC # 0 +0x0000F9B3 0x73CC # 0 +0x0000F9B4 0x7562 # 0 +0x0000F9B5 0x758B # 0 +0x0000F9B6 0x7B46 # 0 +0x0000F9B7 0x82FE # 0 +0x0000F9B8 0x999D # 0 +0x0000F9B9 0x4E4F # 0 +0x0000F9BA 0x903C # 0 +0x0000F9BB 0x4E0B # 0 +0x0000F9BC 0x4F55 # 0 +0x0000F9BD 0x53A6 # 0 +0x0000F9BE 0x590F # 0 +0x0000F9BF 0x5EC8 # 0 +0x0000F9C0 0x6630 # 0 +0x0000F9C1 0x6CB3 # 0 +0x0000F9C2 0x7455 # 0 +0x0000F9C3 0x8377 # 0 +0x0000F9C4 0x8766 # 0 +0x0000F9C5 0x8CC0 # 0 +0x0000F9C6 0x9050 # 0 +0x0000F9C7 0x971E # 0 +0x0000F9C8 0x9C15 # 0 +0x0000F9C9 0x58D1 # 0 +0x0000F9CA 0x5B78 # 0 +0x0000F9CB 0x8650 # 0 +0x0000F9CC 0x8B14 # 0 +0x0000F9CD 0x9DB4 # 0 +0x0000F9CE 0x5BD2 # 0 +0x0000F9CF 0x6068 # 0 +0x0000F9D0 0x608D # 0 +0x0000F9D1 0x65F1 # 0 +0x0000F9D2 0x6C57 # 0 +0x0000F9D3 0x6F22 # 0 +0x0000F9D4 0x6FA3 # 0 +0x0000F9D5 0x701A # 0 +0x0000F9D6 0x7F55 # 0 +0x0000F9D7 0x7FF0 # 0 +0x0000F9D8 0x9591 # 0 +0x0000F9D9 0x9592 # 0 +0x0000F9DA 0x9650 # 0 +0x0000F9DB 0x97D3 # 0 +0x0000F9DC 0x5272 # 0 +0x0000F9DD 0x8F44 # 0 +0x0000F9DE 0x51FD # 0 +0x0000F9DF 0x542B # 0 +0x0000F9E0 0x54B8 # 0 +0x0000F9E1 0x5563 # 0 +0x0000F9E2 0x558A # 0 +0x0000F9E3 0x6ABB # 0 +0x0000F9E4 0x6DB5 # 0 +0x0000F9E5 0x7DD8 # 0 +0x0000F9E6 0x8266 # 0 +0x0000F9E7 0x929C # 0 +0x0000F9E8 0x9677 # 0 +0x0000F9E9 0x9E79 # 0 +0x0000F9EA 0x5408 # 0 +0x0000F9EB 0x54C8 # 0 +0x0000F9EC 0x76D2 # 0 +0x0000F9ED 0x86E4 # 0 +0x0000F9EE 0x95A4 # 0 +0x0000F9EF 0x95D4 # 0 +0x0000F9F0 0x965C # 0 +0x0000F9F1 0x4EA2 # 0 +0x0000F9F2 0x4F09 # 0 +0x0000F9F3 0x59EE # 0 +0x0000F9F4 0x5AE6 # 0 +0x0000F9F5 0x5DF7 # 0 +0x0000F9F6 0x6052 # 0 +0x0000F9F7 0x6297 # 0 +0x0000F9F8 0x676D # 0 +0x0000F9F9 0x6841 # 0 +0x0000F9FA 0x6C86 # 0 +0x0000F9FB 0x6E2F # 0 +0x0000F9FC 0x7F38 # 0 +0x0000F9FD 0x809B # 0 +0x0000F9FE 0x822A # 0 +0x0000FAA1 0xFA08 # 0 +0x0000FAA2 0xFA09 # 0 +0x0000FAA3 0x9805 # 0 +0x0000FAA4 0x4EA5 # 0 +0x0000FAA5 0x5055 # 0 +0x0000FAA6 0x54B3 # 0 +0x0000FAA7 0x5793 # 0 +0x0000FAA8 0x595A # 0 +0x0000FAA9 0x5B69 # 0 +0x0000FAAA 0x5BB3 # 0 +0x0000FAAB 0x61C8 # 0 +0x0000FAAC 0x6977 # 0 +0x0000FAAD 0x6D77 # 0 +0x0000FAAE 0x7023 # 0 +0x0000FAAF 0x87F9 # 0 +0x0000FAB0 0x89E3 # 0 +0x0000FAB1 0x8A72 # 0 +0x0000FAB2 0x8AE7 # 0 +0x0000FAB3 0x9082 # 0 +0x0000FAB4 0x99ED # 0 +0x0000FAB5 0x9AB8 # 0 +0x0000FAB6 0x52BE # 0 +0x0000FAB7 0x6838 # 0 +0x0000FAB8 0x5016 # 0 +0x0000FAB9 0x5E78 # 0 +0x0000FABA 0x674F # 0 +0x0000FABB 0x8347 # 0 +0x0000FABC 0x884C # 0 +0x0000FABD 0x4EAB # 0 +0x0000FABE 0x5411 # 0 +0x0000FABF 0x56AE # 0 +0x0000FAC0 0x73E6 # 0 +0x0000FAC1 0x9115 # 0 +0x0000FAC2 0x97FF # 0 +0x0000FAC3 0x9909 # 0 +0x0000FAC4 0x9957 # 0 +0x0000FAC5 0x9999 # 0 +0x0000FAC6 0x5653 # 0 +0x0000FAC7 0x589F # 0 +0x0000FAC8 0x865B # 0 +0x0000FAC9 0x8A31 # 0 +0x0000FACA 0x61B2 # 0 +0x0000FACB 0x6AF6 # 0 +0x0000FACC 0x737B # 0 +0x0000FACD 0x8ED2 # 0 +0x0000FACE 0x6B47 # 0 +0x0000FACF 0x96AA # 0 +0x0000FAD0 0x9A57 # 0 +0x0000FAD1 0x5955 # 0 +0x0000FAD2 0x7200 # 0 +0x0000FAD3 0x8D6B # 0 +0x0000FAD4 0x9769 # 0 +0x0000FAD5 0x4FD4 # 0 +0x0000FAD6 0x5CF4 # 0 +0x0000FAD7 0x5F26 # 0 +0x0000FAD8 0x61F8 # 0 +0x0000FAD9 0x665B # 0 +0x0000FADA 0x6CEB # 0 +0x0000FADB 0x70AB # 0 +0x0000FADC 0x7384 # 0 +0x0000FADD 0x73B9 # 0 +0x0000FADE 0x73FE # 0 +0x0000FADF 0x7729 # 0 +0x0000FAE0 0x774D # 0 +0x0000FAE1 0x7D43 # 0 +0x0000FAE2 0x7D62 # 0 +0x0000FAE3 0x7E23 # 0 +0x0000FAE4 0x8237 # 0 +0x0000FAE5 0x8852 # 0 +0x0000FAE6 0xFA0A # 0 +0x0000FAE7 0x8CE2 # 0 +0x0000FAE8 0x9249 # 0 +0x0000FAE9 0x986F # 0 +0x0000FAEA 0x5B51 # 0 +0x0000FAEB 0x7A74 # 0 +0x0000FAEC 0x8840 # 0 +0x0000FAED 0x9801 # 0 +0x0000FAEE 0x5ACC # 0 +0x0000FAEF 0x4FE0 # 0 +0x0000FAF0 0x5354 # 0 +0x0000FAF1 0x593E # 0 +0x0000FAF2 0x5CFD # 0 +0x0000FAF3 0x633E # 0 +0x0000FAF4 0x6D79 # 0 +0x0000FAF5 0x72F9 # 0 +0x0000FAF6 0x8105 # 0 +0x0000FAF7 0x8107 # 0 +0x0000FAF8 0x83A2 # 0 +0x0000FAF9 0x92CF # 0 +0x0000FAFA 0x9830 # 0 +0x0000FAFB 0x4EA8 # 0 +0x0000FAFC 0x5144 # 0 +0x0000FAFD 0x5211 # 0 +0x0000FAFE 0x578B # 0 +0x0000FBA1 0x5F62 # 0 +0x0000FBA2 0x6CC2 # 0 +0x0000FBA3 0x6ECE # 0 +0x0000FBA4 0x7005 # 0 +0x0000FBA5 0x7050 # 0 +0x0000FBA6 0x70AF # 0 +0x0000FBA7 0x7192 # 0 +0x0000FBA8 0x73E9 # 0 +0x0000FBA9 0x7469 # 0 +0x0000FBAA 0x834A # 0 +0x0000FBAB 0x87A2 # 0 +0x0000FBAC 0x8861 # 0 +0x0000FBAD 0x9008 # 0 +0x0000FBAE 0x90A2 # 0 +0x0000FBAF 0x93A3 # 0 +0x0000FBB0 0x99A8 # 0 +0x0000FBB1 0x516E # 0 +0x0000FBB2 0x5F57 # 0 +0x0000FBB3 0x60E0 # 0 +0x0000FBB4 0x6167 # 0 +0x0000FBB5 0x66B3 # 0 +0x0000FBB6 0x8559 # 0 +0x0000FBB7 0x8E4A # 0 +0x0000FBB8 0x91AF # 0 +0x0000FBB9 0x978B # 0 +0x0000FBBA 0x4E4E # 0 +0x0000FBBB 0x4E92 # 0 +0x0000FBBC 0x547C # 0 +0x0000FBBD 0x58D5 # 0 +0x0000FBBE 0x58FA # 0 +0x0000FBBF 0x597D # 0 +0x0000FBC0 0x5CB5 # 0 +0x0000FBC1 0x5F27 # 0 +0x0000FBC2 0x6236 # 0 +0x0000FBC3 0x6248 # 0 +0x0000FBC4 0x660A # 0 +0x0000FBC5 0x6667 # 0 +0x0000FBC6 0x6BEB # 0 +0x0000FBC7 0x6D69 # 0 +0x0000FBC8 0x6DCF # 0 +0x0000FBC9 0x6E56 # 0 +0x0000FBCA 0x6EF8 # 0 +0x0000FBCB 0x6F94 # 0 +0x0000FBCC 0x6FE0 # 0 +0x0000FBCD 0x6FE9 # 0 +0x0000FBCE 0x705D # 0 +0x0000FBCF 0x72D0 # 0 +0x0000FBD0 0x7425 # 0 +0x0000FBD1 0x745A # 0 +0x0000FBD2 0x74E0 # 0 +0x0000FBD3 0x7693 # 0 +0x0000FBD4 0x795C # 0 +0x0000FBD5 0x7CCA # 0 +0x0000FBD6 0x7E1E # 0 +0x0000FBD7 0x80E1 # 0 +0x0000FBD8 0x82A6 # 0 +0x0000FBD9 0x846B # 0 +0x0000FBDA 0x84BF # 0 +0x0000FBDB 0x864E # 0 +0x0000FBDC 0x865F # 0 +0x0000FBDD 0x8774 # 0 +0x0000FBDE 0x8B77 # 0 +0x0000FBDF 0x8C6A # 0 +0x0000FBE0 0x93AC # 0 +0x0000FBE1 0x9800 # 0 +0x0000FBE2 0x9865 # 0 +0x0000FBE3 0x60D1 # 0 +0x0000FBE4 0x6216 # 0 +0x0000FBE5 0x9177 # 0 +0x0000FBE6 0x5A5A # 0 +0x0000FBE7 0x660F # 0 +0x0000FBE8 0x6DF7 # 0 +0x0000FBE9 0x6E3E # 0 +0x0000FBEA 0x743F # 0 +0x0000FBEB 0x9B42 # 0 +0x0000FBEC 0x5FFD # 0 +0x0000FBED 0x60DA # 0 +0x0000FBEE 0x7B0F # 0 +0x0000FBEF 0x54C4 # 0 +0x0000FBF0 0x5F18 # 0 +0x0000FBF1 0x6C5E # 0 +0x0000FBF2 0x6CD3 # 0 +0x0000FBF3 0x6D2A # 0 +0x0000FBF4 0x70D8 # 0 +0x0000FBF5 0x7D05 # 0 +0x0000FBF6 0x8679 # 0 +0x0000FBF7 0x8A0C # 0 +0x0000FBF8 0x9D3B # 0 +0x0000FBF9 0x5316 # 0 +0x0000FBFA 0x548C # 0 +0x0000FBFB 0x5B05 # 0 +0x0000FBFC 0x6A3A # 0 +0x0000FBFD 0x706B # 0 +0x0000FBFE 0x7575 # 0 +0x0000FCA1 0x798D # 0 +0x0000FCA2 0x79BE # 0 +0x0000FCA3 0x82B1 # 0 +0x0000FCA4 0x83EF # 0 +0x0000FCA5 0x8A71 # 0 +0x0000FCA6 0x8B41 # 0 +0x0000FCA7 0x8CA8 # 0 +0x0000FCA8 0x9774 # 0 +0x0000FCA9 0xFA0B # 0 +0x0000FCAA 0x64F4 # 0 +0x0000FCAB 0x652B # 0 +0x0000FCAC 0x78BA # 0 +0x0000FCAD 0x78BB # 0 +0x0000FCAE 0x7A6B # 0 +0x0000FCAF 0x4E38 # 0 +0x0000FCB0 0x559A # 0 +0x0000FCB1 0x5950 # 0 +0x0000FCB2 0x5BA6 # 0 +0x0000FCB3 0x5E7B # 0 +0x0000FCB4 0x60A3 # 0 +0x0000FCB5 0x63DB # 0 +0x0000FCB6 0x6B61 # 0 +0x0000FCB7 0x6665 # 0 +0x0000FCB8 0x6853 # 0 +0x0000FCB9 0x6E19 # 0 +0x0000FCBA 0x7165 # 0 +0x0000FCBB 0x74B0 # 0 +0x0000FCBC 0x7D08 # 0 +0x0000FCBD 0x9084 # 0 +0x0000FCBE 0x9A69 # 0 +0x0000FCBF 0x9C25 # 0 +0x0000FCC0 0x6D3B # 0 +0x0000FCC1 0x6ED1 # 0 +0x0000FCC2 0x733E # 0 +0x0000FCC3 0x8C41 # 0 +0x0000FCC4 0x95CA # 0 +0x0000FCC5 0x51F0 # 0 +0x0000FCC6 0x5E4C # 0 +0x0000FCC7 0x5FA8 # 0 +0x0000FCC8 0x604D # 0 +0x0000FCC9 0x60F6 # 0 +0x0000FCCA 0x6130 # 0 +0x0000FCCB 0x614C # 0 +0x0000FCCC 0x6643 # 0 +0x0000FCCD 0x6644 # 0 +0x0000FCCE 0x69A5 # 0 +0x0000FCCF 0x6CC1 # 0 +0x0000FCD0 0x6E5F # 0 +0x0000FCD1 0x6EC9 # 0 +0x0000FCD2 0x6F62 # 0 +0x0000FCD3 0x714C # 0 +0x0000FCD4 0x749C # 0 +0x0000FCD5 0x7687 # 0 +0x0000FCD6 0x7BC1 # 0 +0x0000FCD7 0x7C27 # 0 +0x0000FCD8 0x8352 # 0 +0x0000FCD9 0x8757 # 0 +0x0000FCDA 0x9051 # 0 +0x0000FCDB 0x968D # 0 +0x0000FCDC 0x9EC3 # 0 +0x0000FCDD 0x532F # 0 +0x0000FCDE 0x56DE # 0 +0x0000FCDF 0x5EFB # 0 +0x0000FCE0 0x5F8A # 0 +0x0000FCE1 0x6062 # 0 +0x0000FCE2 0x6094 # 0 +0x0000FCE3 0x61F7 # 0 +0x0000FCE4 0x6666 # 0 +0x0000FCE5 0x6703 # 0 +0x0000FCE6 0x6A9C # 0 +0x0000FCE7 0x6DEE # 0 +0x0000FCE8 0x6FAE # 0 +0x0000FCE9 0x7070 # 0 +0x0000FCEA 0x736A # 0 +0x0000FCEB 0x7E6A # 0 +0x0000FCEC 0x81BE # 0 +0x0000FCED 0x8334 # 0 +0x0000FCEE 0x86D4 # 0 +0x0000FCEF 0x8AA8 # 0 +0x0000FCF0 0x8CC4 # 0 +0x0000FCF1 0x5283 # 0 +0x0000FCF2 0x7372 # 0 +0x0000FCF3 0x5B96 # 0 +0x0000FCF4 0x6A6B # 0 +0x0000FCF5 0x9404 # 0 +0x0000FCF6 0x54EE # 0 +0x0000FCF7 0x5686 # 0 +0x0000FCF8 0x5B5D # 0 +0x0000FCF9 0x6548 # 0 +0x0000FCFA 0x6585 # 0 +0x0000FCFB 0x66C9 # 0 +0x0000FCFC 0x689F # 0 +0x0000FCFD 0x6D8D # 0 +0x0000FCFE 0x6DC6 # 0 +0x0000FDA1 0x723B # 0 +0x0000FDA2 0x80B4 # 0 +0x0000FDA3 0x9175 # 0 +0x0000FDA4 0x9A4D # 0 +0x0000FDA5 0x4FAF # 0 +0x0000FDA6 0x5019 # 0 +0x0000FDA7 0x539A # 0 +0x0000FDA8 0x540E # 0 +0x0000FDA9 0x543C # 0 +0x0000FDAA 0x5589 # 0 +0x0000FDAB 0x55C5 # 0 +0x0000FDAC 0x5E3F # 0 +0x0000FDAD 0x5F8C # 0 +0x0000FDAE 0x673D # 0 +0x0000FDAF 0x7166 # 0 +0x0000FDB0 0x73DD # 0 +0x0000FDB1 0x9005 # 0 +0x0000FDB2 0x52DB # 0 +0x0000FDB3 0x52F3 # 0 +0x0000FDB4 0x5864 # 0 +0x0000FDB5 0x58CE # 0 +0x0000FDB6 0x7104 # 0 +0x0000FDB7 0x718F # 0 +0x0000FDB8 0x71FB # 0 +0x0000FDB9 0x85B0 # 0 +0x0000FDBA 0x8A13 # 0 +0x0000FDBB 0x6688 # 0 +0x0000FDBC 0x85A8 # 0 +0x0000FDBD 0x55A7 # 0 +0x0000FDBE 0x6684 # 0 +0x0000FDBF 0x714A # 0 +0x0000FDC0 0x8431 # 0 +0x0000FDC1 0x5349 # 0 +0x0000FDC2 0x5599 # 0 +0x0000FDC3 0x6BC1 # 0 +0x0000FDC4 0x5F59 # 0 +0x0000FDC5 0x5FBD # 0 +0x0000FDC6 0x63EE # 0 +0x0000FDC7 0x6689 # 0 +0x0000FDC8 0x7147 # 0 +0x0000FDC9 0x8AF1 # 0 +0x0000FDCA 0x8F1D # 0 +0x0000FDCB 0x9EBE # 0 +0x0000FDCC 0x4F11 # 0 +0x0000FDCD 0x643A # 0 +0x0000FDCE 0x70CB # 0 +0x0000FDCF 0x7566 # 0 +0x0000FDD0 0x8667 # 0 +0x0000FDD1 0x6064 # 0 +0x0000FDD2 0x8B4E # 0 +0x0000FDD3 0x9DF8 # 0 +0x0000FDD4 0x5147 # 0 +0x0000FDD5 0x51F6 # 0 +0x0000FDD6 0x5308 # 0 +0x0000FDD7 0x6D36 # 0 +0x0000FDD8 0x80F8 # 0 +0x0000FDD9 0x9ED1 # 0 +0x0000FDDA 0x6615 # 0 +0x0000FDDB 0x6B23 # 0 +0x0000FDDC 0x7098 # 0 +0x0000FDDD 0x75D5 # 0 +0x0000FDDE 0x5403 # 0 +0x0000FDDF 0x5C79 # 0 +0x0000FDE0 0x7D07 # 0 +0x0000FDE1 0x8A16 # 0 +0x0000FDE2 0x6B20 # 0 +0x0000FDE3 0x6B3D # 0 +0x0000FDE4 0x6B46 # 0 +0x0000FDE5 0x5438 # 0 +0x0000FDE6 0x6070 # 0 +0x0000FDE7 0x6D3D # 0 +0x0000FDE8 0x7FD5 # 0 +0x0000FDE9 0x8208 # 0 +0x0000FDEA 0x50D6 # 0 +0x0000FDEB 0x51DE # 0 +0x0000FDEC 0x559C # 0 +0x0000FDED 0x566B # 0 +0x0000FDEE 0x56CD # 0 +0x0000FDEF 0x59EC # 0 +0x0000FDF0 0x5B09 # 0 +0x0000FDF1 0x5E0C # 0 +0x0000FDF2 0x6199 # 0 +0x0000FDF3 0x6198 # 0 +0x0000FDF4 0x6231 # 0 +0x0000FDF5 0x665E # 0 +0x0000FDF6 0x66E6 # 0 +0x0000FDF7 0x7199 # 0 +0x0000FDF8 0x71B9 # 0 +0x0000FDF9 0x71BA # 0 +0x0000FDFA 0x72A7 # 0 +0x0000FDFB 0x79A7 # 0 +0x0000FDFC 0x7A00 # 0 +0x0000FDFD 0x7FB2 # 0 +0x0000FDFE 0x8A70 # 0 +0x0000FEA1 0xF75E # 0 +0x0000FEA2 0xF75F # 0 +0x0000FEA3 0xF760 # 0 +0x0000FEA4 0xF761 # 0 +0x0000FEA5 0xF762 # 0 +0x0000FEA6 0xF763 # 0 +0x0000FEA7 0xF764 # 0 +0x0000FEA8 0xF765 # 0 +0x0000FEA9 0xF766 # 0 +0x0000FEAA 0xF767 # 0 +0x0000FEAB 0xF768 # 0 +0x0000FEAC 0xF769 # 0 +0x0000FEAD 0xF76A # 0 +0x0000FEAE 0xF76B # 0 +0x0000FEAF 0xF76C # 0 +0x0000FEB0 0xF76D # 0 +0x0000FEB1 0xF76E # 0 +0x0000FEB2 0xF76F # 0 +0x0000FEB3 0xF770 # 0 +0x0000FEB4 0xF771 # 0 +0x0000FEB5 0xF772 # 0 +0x0000FEB6 0xF773 # 0 +0x0000FEB7 0xF774 # 0 +0x0000FEB8 0xF775 # 0 +0x0000FEB9 0xF776 # 0 +0x0000FEBA 0xF777 # 0 +0x0000FEBB 0xF778 # 0 +0x0000FEBC 0xF779 # 0 +0x0000FEBD 0xF77A # 0 +0x0000FEBE 0xF77B # 0 +0x0000FEBF 0xF77C # 0 +0x0000FEC0 0xF77D # 0 +0x0000FEC1 0xF77E # 0 +0x0000FEC2 0xF77F # 0 +0x0000FEC3 0xF780 # 0 +0x0000FEC4 0xF781 # 0 +0x0000FEC5 0xF782 # 0 +0x0000FEC6 0xF783 # 0 +0x0000FEC7 0xF784 # 0 +0x0000FEC8 0xF785 # 0 +0x0000FEC9 0xF786 # 0 +0x0000FECA 0xF787 # 0 +0x0000FECB 0xF788 # 0 +0x0000FECC 0xF789 # 0 +0x0000FECD 0xF78A # 0 +0x0000FECE 0xF78B # 0 +0x0000FECF 0xF78C # 0 +0x0000FED0 0xF78D # 0 +0x0000FED1 0xF78E # 0 +0x0000FED2 0xF78F # 0 +0x0000FED3 0xF790 # 0 +0x0000FED4 0xF791 # 0 +0x0000FED5 0xF792 # 0 +0x0000FED6 0xF793 # 0 +0x0000FED7 0xF794 # 0 +0x0000FED8 0xF795 # 0 +0x0000FED9 0xF796 # 0 +0x0000FEDA 0xF797 # 0 +0x0000FEDB 0xF798 # 0 +0x0000FEDC 0xF799 # 0 +0x0000FEDD 0xF79A # 0 +0x0000FEDE 0xF79B # 0 +0x0000FEDF 0xF79C # 0 +0x0000FEE0 0xF79D # 0 +0x0000FEE1 0xF79E # 0 +0x0000FEE2 0xF79F # 0 +0x0000FEE3 0xF7A0 # 0 +0x0000FEE4 0xF7A1 # 0 +0x0000FEE5 0xF7A2 # 0 +0x0000FEE6 0xF7A3 # 0 +0x0000FEE7 0xF7A4 # 0 +0x0000FEE8 0xF7A5 # 0 +0x0000FEE9 0xF7A6 # 0 +0x0000FEEA 0xF7A7 # 0 +0x0000FEEB 0xF7A8 # 0 +0x0000FEEC 0xF7A9 # 0 +0x0000FEED 0xF7AA # 0 +0x0000FEEE 0xF7AB # 0 +0x0000FEEF 0xF7AC # 0 +0x0000FEF0 0xF7AD # 0 +0x0000FEF1 0xF7AE # 0 +0x0000FEF2 0xF7AF # 0 +0x0000FEF3 0xF7B0 # 0 +0x0000FEF4 0xF7B1 # 0 +0x0000FEF5 0xF7B2 # 0 +0x0000FEF6 0xF7B3 # 0 +0x0000FEF7 0xF7B4 # 0 +0x0000FEF8 0xF7B5 # 0 +0x0000FEF9 0xF7B6 # 0 +0x0000FEFA 0xF7B7 # 0 +0x0000FEFB 0xF7B8 # 0 +0x0000FEFC 0xF7B9 # 0 +0x0000FEFD 0xF7BA # 0 +0x0000FEFE 0xF7BB # 0 diff --git a/data/euc-tw.txt b/data/euc-tw.txt new file mode 100644 index 0000000000..98a2ab5d86 --- /dev/null +++ b/data/euc-tw.txt @@ -0,0 +1,17840 @@ +# euc-tw.txt - EUC to Unicode charmap +0x00000000 0x0000 # 0 +0x00000001 0x0001 # 0 +0x00000002 0x0002 # 0 +0x00000003 0x0003 # 0 +0x00000004 0x0004 # 0 +0x00000005 0x0005 # 0 +0x00000006 0x0006 # 0 +0x00000007 0x0007 # 0 +0x00000008 0x0008 # 0 +0x00000009 0x0009 # 0 +0x0000000A 0x000A # 0 +0x0000000B 0x000B # 0 +0x0000000C 0x000C # 0 +0x0000000D 0x000D # 0 +0x0000000E 0x000E # 0 +0x0000000F 0x000F # 0 +0x00000010 0x0010 # 0 +0x00000011 0x0011 # 0 +0x00000012 0x0012 # 0 +0x00000013 0x0013 # 0 +0x00000014 0x0014 # 0 +0x00000015 0x0015 # 0 +0x00000016 0x0016 # 0 +0x00000017 0x0017 # 0 +0x00000018 0x0018 # 0 +0x00000019 0x0019 # 0 +0x0000001A 0x001A # 0 +0x0000001B 0x001B # 0 +0x0000001C 0x001C # 0 +0x0000001D 0x001D # 0 +0x0000001E 0x001E # 0 +0x0000001F 0x001F # 0 +0x00000020 0x0020 # 0 +0x00000021 0x0021 # 0 +0x00000022 0x0022 # 0 +0x00000023 0x0023 # 0 +0x00000024 0x0024 # 0 +0x00000025 0x0025 # 0 +0x00000026 0x0026 # 0 +0x00000027 0x0027 # 0 +0x00000028 0x0028 # 0 +0x00000029 0x0029 # 0 +0x0000002A 0x002A # 0 +0x0000002B 0x002B # 0 +0x0000002C 0x002C # 0 +0x0000002D 0x002D # 0 +0x0000002E 0x002E # 0 +0x0000002F 0x002F # 0 +0x00000030 0x0030 # 0 +0x00000031 0x0031 # 0 +0x00000032 0x0032 # 0 +0x00000033 0x0033 # 0 +0x00000034 0x0034 # 0 +0x00000035 0x0035 # 0 +0x00000036 0x0036 # 0 +0x00000037 0x0037 # 0 +0x00000038 0x0038 # 0 +0x00000039 0x0039 # 0 +0x0000003A 0x003A # 0 +0x0000003B 0x003B # 0 +0x0000003C 0x003C # 0 +0x0000003D 0x003D # 0 +0x0000003E 0x003E # 0 +0x0000003F 0x003F # 0 +0x00000040 0x0040 # 0 +0x00000041 0x0041 # 0 +0x00000042 0x0042 # 0 +0x00000043 0x0043 # 0 +0x00000044 0x0044 # 0 +0x00000045 0x0045 # 0 +0x00000046 0x0046 # 0 +0x00000047 0x0047 # 0 +0x00000048 0x0048 # 0 +0x00000049 0x0049 # 0 +0x0000004A 0x004A # 0 +0x0000004B 0x004B # 0 +0x0000004C 0x004C # 0 +0x0000004D 0x004D # 0 +0x0000004E 0x004E # 0 +0x0000004F 0x004F # 0 +0x00000050 0x0050 # 0 +0x00000051 0x0051 # 0 +0x00000052 0x0052 # 0 +0x00000053 0x0053 # 0 +0x00000054 0x0054 # 0 +0x00000055 0x0055 # 0 +0x00000056 0x0056 # 0 +0x00000057 0x0057 # 0 +0x00000058 0x0058 # 0 +0x00000059 0x0059 # 0 +0x0000005A 0x005A # 0 +0x0000005B 0x005B # 0 +0x0000005C 0x005C # 0 +0x0000005D 0x005D # 0 +0x0000005E 0x005E # 0 +0x0000005F 0x005F # 0 +0x00000060 0x0060 # 0 +0x00000061 0x0061 # 0 +0x00000062 0x0062 # 0 +0x00000063 0x0063 # 0 +0x00000064 0x0064 # 0 +0x00000065 0x0065 # 0 +0x00000066 0x0066 # 0 +0x00000067 0x0067 # 0 +0x00000068 0x0068 # 0 +0x00000069 0x0069 # 0 +0x0000006A 0x006A # 0 +0x0000006B 0x006B # 0 +0x0000006C 0x006C # 0 +0x0000006D 0x006D # 0 +0x0000006E 0x006E # 0 +0x0000006F 0x006F # 0 +0x00000070 0x0070 # 0 +0x00000071 0x0071 # 0 +0x00000072 0x0072 # 0 +0x00000073 0x0073 # 0 +0x00000074 0x0074 # 0 +0x00000075 0x0075 # 0 +0x00000076 0x0076 # 0 +0x00000077 0x0077 # 0 +0x00000078 0x0078 # 0 +0x00000079 0x0079 # 0 +0x0000007A 0x007A # 0 +0x0000007B 0x007B # 0 +0x0000007C 0x007C # 0 +0x0000007D 0x007D # 0 +0x0000007E 0x007E # 0 +0x0000007F 0x007F # 0 +0x0000A1A1 0x3000 # 0 +0x0000A1A2 0xFF0C # 0 +0x0000A1A3 0x3001 # 0 +0x0000A1A4 0x3002 # 0 +0x0000A1A5 0xFF0E # 0 +0x0000A1A6 0x30FB # 0 +0x0000A1A7 0xFF1B # 0 +0x0000A1A8 0xFF1A # 0 +0x0000A1A9 0xFF1F # 0 +0x0000A1AA 0xFF01 # 0 +0x0000A1AB 0xFE30 # 0 +0x0000A1AC 0x2026 # 0 +0x0000A1AD 0x2025 # 0 +0x0000A1AE 0xFE50 # 0 +0x0000A1AF 0xFE51 # 0 +0x0000A1B0 0xFE52 # 0 +0x0000A1B1 0x00B7 # 0 +0x0000A1B2 0xFE54 # 0 +0x0000A1B3 0xFE55 # 0 +0x0000A1B4 0xFE56 # 0 +0x0000A1B5 0xFE57 # 0 +0x0000A1B6 0xFE31 # 0 +0x0000A1B7 0x2014 # 0 +0x0000A1B8 0xFE32 # 0 +0x0000A1B9 0x2013 # 0 +0x0000A1BE 0xFF08 # 0 +0x0000A1BF 0xFF09 # 0 +0x0000A1C0 0xFE35 # 0 +0x0000A1C1 0xFE36 # 0 +0x0000A1C2 0xFF5B # 0 +0x0000A1C3 0xFF5D # 0 +0x0000A1C4 0xFE37 # 0 +0x0000A1C5 0xFE38 # 0 +0x0000A1C6 0x3014 # 0 +0x0000A1C7 0x3015 # 0 +0x0000A1C8 0xFE39 # 0 +0x0000A1C9 0xFE3A # 0 +0x0000A1CA 0x3010 # 0 +0x0000A1CB 0x3011 # 0 +0x0000A1CC 0xFE3B # 0 +0x0000A1CD 0xFE3C # 0 +0x0000A1CE 0x300A # 0 +0x0000A1CF 0x300B # 0 +0x0000A1D0 0xFE3D # 0 +0x0000A1D1 0xFE3E # 0 +0x0000A1D2 0x3008 # 0 +0x0000A1D3 0x3009 # 0 +0x0000A1D4 0xFE3F # 0 +0x0000A1D5 0xFE40 # 0 +0x0000A1D6 0x300C # 0 +0x0000A1D7 0x300D # 0 +0x0000A1D8 0xFE41 # 0 +0x0000A1D9 0xFE42 # 0 +0x0000A1DA 0x300E # 0 +0x0000A1DB 0x300F # 0 +0x0000A1DC 0xFE43 # 0 +0x0000A1DD 0xFE44 # 0 +0x0000A1DE 0xFE59 # 0 +0x0000A1DF 0xFE5A # 0 +0x0000A1E0 0xFE5B # 0 +0x0000A1E1 0xFE5C # 0 +0x0000A1E2 0xFE5D # 0 +0x0000A1E3 0xFE5E # 0 +0x0000A1E4 0x2018 # 0 +0x0000A1E5 0x2019 # 0 +0x0000A1E6 0x201C # 0 +0x0000A1E7 0x201D # 0 +0x0000A1E8 0x301D # 0 +0x0000A1E9 0x301E # 0 +0x0000A1EA 0x2032 # 0 +0x0000A1EB 0x2035 # 0 +0x0000A1EC 0xFF03 # 0 +0x0000A1ED 0xFF06 # 0 +0x0000A1EE 0xFF0A # 0 +0x0000A1EF 0x203B # 0 +0x0000A1F0 0x00A7 # 0 +0x0000A1F1 0x3003 # 0 +0x0000A1F2 0x25CB # 0 +0x0000A1F3 0x25CF # 0 +0x0000A1F4 0x25B3 # 0 +0x0000A1F5 0x25B2 # 0 +0x0000A1F6 0x25CE # 0 +0x0000A1F7 0x2606 # 0 +0x0000A1F8 0x2605 # 0 +0x0000A1F9 0x25C7 # 0 +0x0000A1FA 0x25C6 # 0 +0x0000A1FB 0x25A1 # 0 +0x0000A1FC 0x25A0 # 0 +0x0000A1FD 0x25BD # 0 +0x0000A1FE 0x25BC # 0 +0x0000A2A1 0x32A3 # 0 +0x0000A2A2 0x2105 # 0 +0x0000A2A3 0x203E # 0 +0x0000A2A5 0xFF3F # 0 +0x0000A2A7 0xFE49 # 0 +0x0000A2A8 0xFE4A # 0 +0x0000A2A9 0xFE4D # 0 +0x0000A2AA 0xFE4E # 0 +0x0000A2AB 0xFE4B # 0 +0x0000A2AC 0xFE4C # 0 +0x0000A2AD 0xFE5F # 0 +0x0000A2AE 0xFE60 # 0 +0x0000A2AF 0xFE61 # 0 +0x0000A2B0 0xFF0B # 0 +0x0000A2B1 0xFF0D # 0 +0x0000A2B2 0x00D7 # 0 +0x0000A2B3 0x00F7 # 0 +0x0000A2B4 0x00B1 # 0 +0x0000A2B5 0x221A # 0 +0x0000A2B6 0xFF1C # 0 +0x0000A2B7 0xFF1E # 0 +0x0000A2B8 0xFF1D # 0 +0x0000A2B9 0x2266 # 0 +0x0000A2BA 0x2267 # 0 +0x0000A2BB 0x2260 # 0 +0x0000A2BC 0x221E # 0 +0x0000A2BD 0x2252 # 0 +0x0000A2BE 0x2261 # 0 +0x0000A2BF 0xFE62 # 0 +0x0000A2C0 0xFE63 # 0 +0x0000A2C1 0xFE64 # 0 +0x0000A2C2 0xFE66 # 0 +0x0000A2C3 0xFE65 # 0 +0x0000A2C4 0x223C # 0 +0x0000A2C5 0x2229 # 0 +0x0000A2C6 0x222A # 0 +0x0000A2C7 0x22A5 # 0 +0x0000A2C8 0x2220 # 0 +0x0000A2C9 0x221F # 0 +0x0000A2CA 0x22BF # 0 +0x0000A2CB 0x33D2 # 0 +0x0000A2CC 0x33D1 # 0 +0x0000A2CD 0x222B # 0 +0x0000A2CE 0x222E # 0 +0x0000A2CF 0x2235 # 0 +0x0000A2D0 0x2234 # 0 +0x0000A2D1 0x2640 # 0 +0x0000A2D2 0x2642 # 0 +0x0000A2D3 0x2641 # 0 +0x0000A2D4 0x2609 # 0 +0x0000A2D5 0x2191 # 0 +0x0000A2D6 0x2193 # 0 +0x0000A2D7 0x2192 # 0 +0x0000A2D8 0x2190 # 0 +0x0000A2D9 0x2196 # 0 +0x0000A2DA 0x2197 # 0 +0x0000A2DB 0x2199 # 0 +0x0000A2DC 0x2198 # 0 +0x0000A2DD 0x2016 # 0 +0x0000A2DE 0xFF5C # 0 +0x0000A2DF 0xFF0F # 0 +0x0000A2E0 0xFF3C # 0 +0x0000A2E1 0x2215 # 0 +0x0000A2E2 0xFE68 # 0 +0x0000A2E3 0xFF04 # 0 +0x0000A2E4 0xFFE5 # 0 +0x0000A2E5 0x3012 # 0 +0x0000A2E6 0xFFE0 # 0 +0x0000A2E7 0xFFE1 # 0 +0x0000A2E8 0xFF05 # 0 +0x0000A2E9 0xFF20 # 0 +0x0000A2EA 0x2103 # 0 +0x0000A2EB 0x2109 # 0 +0x0000A2EC 0xFE69 # 0 +0x0000A2ED 0xFE6A # 0 +0x0000A2EE 0xFE6B # 0 +0x0000A2EF 0x33D5 # 0 +0x0000A2F0 0x339C # 0 +0x0000A2F1 0x339D # 0 +0x0000A2F2 0x339E # 0 +0x0000A2F3 0x33CE # 0 +0x0000A2F4 0x33A1 # 0 +0x0000A2F5 0x338E # 0 +0x0000A2F6 0x338F # 0 +0x0000A2F7 0x33C4 # 0 +0x0000A2F8 0x00B0 # 0 +0x0000A2F9 0x5159 # 0 +0x0000A2FA 0x515B # 0 +0x0000A2FB 0x515E # 0 +0x0000A2FC 0x515D # 0 +0x0000A2FD 0x5161 # 0 +0x0000A2FE 0x5163 # 0 +0x0000A3A1 0x55E7 # 0 +0x0000A3A2 0x74E9 # 0 +0x0000A3A3 0x7CCE # 0 +0x0000A3A4 0x2581 # 0 +0x0000A3A5 0x2582 # 0 +0x0000A3A6 0x2583 # 0 +0x0000A3A7 0x2584 # 0 +0x0000A3A8 0x2585 # 0 +0x0000A3A9 0x2586 # 0 +0x0000A3AA 0x2587 # 0 +0x0000A3AB 0x2588 # 0 +0x0000A3AC 0x258F # 0 +0x0000A3AD 0x258E # 0 +0x0000A3AE 0x258D # 0 +0x0000A3AF 0x258C # 0 +0x0000A3B0 0x258B # 0 +0x0000A3B1 0x258A # 0 +0x0000A3B2 0x2589 # 0 +0x0000A3B3 0x253C # 0 +0x0000A3B4 0x2534 # 0 +0x0000A3B5 0x252C # 0 +0x0000A3B6 0x2524 # 0 +0x0000A3B7 0x251C # 0 +0x0000A3B8 0x2594 # 0 +0x0000A3B9 0x2500 # 0 +0x0000A3BA 0x2502 # 0 +0x0000A3BB 0x2595 # 0 +0x0000A3BC 0x250C # 0 +0x0000A3BD 0x2510 # 0 +0x0000A3BE 0x2514 # 0 +0x0000A3BF 0x2518 # 0 +0x0000A3C0 0x256D # 0 +0x0000A3C1 0x256E # 0 +0x0000A3C2 0x2570 # 0 +0x0000A3C3 0x256F # 0 +0x0000A3C4 0x2550 # 0 +0x0000A3C5 0x255E # 0 +0x0000A3C6 0x256A # 0 +0x0000A3C7 0x2561 # 0 +0x0000A3C8 0x25E2 # 0 +0x0000A3C9 0x25E3 # 0 +0x0000A3CA 0x25E5 # 0 +0x0000A3CB 0x25E4 # 0 +0x0000A3CC 0x2571 # 0 +0x0000A3CD 0x2572 # 0 +0x0000A3CE 0x2573 # 0 +0x0000A4A1 0xFF10 # 0 +0x0000A4A2 0xFF11 # 0 +0x0000A4A3 0xFF12 # 0 +0x0000A4A4 0xFF13 # 0 +0x0000A4A5 0xFF14 # 0 +0x0000A4A6 0xFF15 # 0 +0x0000A4A7 0xFF16 # 0 +0x0000A4A8 0xFF17 # 0 +0x0000A4A9 0xFF18 # 0 +0x0000A4AA 0xFF19 # 0 +0x0000A4AB 0x2160 # 0 +0x0000A4AC 0x2161 # 0 +0x0000A4AD 0x2162 # 0 +0x0000A4AE 0x2163 # 0 +0x0000A4AF 0x2164 # 0 +0x0000A4B0 0x2165 # 0 +0x0000A4B1 0x2166 # 0 +0x0000A4B2 0x2167 # 0 +0x0000A4B3 0x2168 # 0 +0x0000A4B4 0x2169 # 0 +0x0000A4B5 0x3021 # 0 +0x0000A4B6 0x3022 # 0 +0x0000A4B7 0x3023 # 0 +0x0000A4B8 0x3024 # 0 +0x0000A4B9 0x3025 # 0 +0x0000A4BA 0x3026 # 0 +0x0000A4BB 0x3027 # 0 +0x0000A4BC 0x3028 # 0 +0x0000A4BD 0x3029 # 0 +0x0000A4BF 0x5344 # 0 +0x0000A4C1 0xFF21 # 0 +0x0000A4C2 0xFF22 # 0 +0x0000A4C3 0xFF23 # 0 +0x0000A4C4 0xFF24 # 0 +0x0000A4C5 0xFF25 # 0 +0x0000A4C6 0xFF26 # 0 +0x0000A4C7 0xFF27 # 0 +0x0000A4C8 0xFF28 # 0 +0x0000A4C9 0xFF29 # 0 +0x0000A4CA 0xFF2A # 0 +0x0000A4CB 0xFF2B # 0 +0x0000A4CC 0xFF2C # 0 +0x0000A4CD 0xFF2D # 0 +0x0000A4CE 0xFF2E # 0 +0x0000A4CF 0xFF2F # 0 +0x0000A4D0 0xFF30 # 0 +0x0000A4D1 0xFF31 # 0 +0x0000A4D2 0xFF32 # 0 +0x0000A4D3 0xFF33 # 0 +0x0000A4D4 0xFF34 # 0 +0x0000A4D5 0xFF35 # 0 +0x0000A4D6 0xFF36 # 0 +0x0000A4D7 0xFF37 # 0 +0x0000A4D8 0xFF38 # 0 +0x0000A4D9 0xFF39 # 0 +0x0000A4DA 0xFF3A # 0 +0x0000A4DB 0xFF41 # 0 +0x0000A4DC 0xFF42 # 0 +0x0000A4DD 0xFF43 # 0 +0x0000A4DE 0xFF44 # 0 +0x0000A4DF 0xFF45 # 0 +0x0000A4E0 0xFF46 # 0 +0x0000A4E1 0xFF47 # 0 +0x0000A4E2 0xFF48 # 0 +0x0000A4E3 0xFF49 # 0 +0x0000A4E4 0xFF4A # 0 +0x0000A4E5 0xFF4B # 0 +0x0000A4E6 0xFF4C # 0 +0x0000A4E7 0xFF4D # 0 +0x0000A4E8 0xFF4E # 0 +0x0000A4E9 0xFF4F # 0 +0x0000A4EA 0xFF50 # 0 +0x0000A4EB 0xFF51 # 0 +0x0000A4EC 0xFF52 # 0 +0x0000A4ED 0xFF53 # 0 +0x0000A4EE 0xFF54 # 0 +0x0000A4EF 0xFF55 # 0 +0x0000A4F0 0xFF56 # 0 +0x0000A4F1 0xFF57 # 0 +0x0000A4F2 0xFF58 # 0 +0x0000A4F3 0xFF59 # 0 +0x0000A4F4 0xFF5A # 0 +0x0000A4F5 0x0391 # 0 +0x0000A4F6 0x0392 # 0 +0x0000A4F7 0x0393 # 0 +0x0000A4F8 0x0394 # 0 +0x0000A4F9 0x0395 # 0 +0x0000A4FA 0x0396 # 0 +0x0000A4FB 0x0397 # 0 +0x0000A4FC 0x0398 # 0 +0x0000A4FD 0x0399 # 0 +0x0000A4FE 0x039A # 0 +0x0000A5A1 0x039B # 0 +0x0000A5A2 0x039C # 0 +0x0000A5A3 0x039D # 0 +0x0000A5A4 0x039E # 0 +0x0000A5A5 0x039F # 0 +0x0000A5A6 0x03A0 # 0 +0x0000A5A7 0x03A1 # 0 +0x0000A5A8 0x03A3 # 0 +0x0000A5A9 0x03A4 # 0 +0x0000A5AA 0x03A5 # 0 +0x0000A5AB 0x03A6 # 0 +0x0000A5AC 0x03A7 # 0 +0x0000A5AD 0x03A8 # 0 +0x0000A5AE 0x03A9 # 0 +0x0000A5AF 0x03B1 # 0 +0x0000A5B0 0x03B2 # 0 +0x0000A5B1 0x03B3 # 0 +0x0000A5B2 0x03B4 # 0 +0x0000A5B3 0x03B5 # 0 +0x0000A5B4 0x03B6 # 0 +0x0000A5B5 0x03B7 # 0 +0x0000A5B6 0x03B8 # 0 +0x0000A5B7 0x03B9 # 0 +0x0000A5B8 0x03BA # 0 +0x0000A5B9 0x03BB # 0 +0x0000A5BA 0x03BC # 0 +0x0000A5BB 0x03BD # 0 +0x0000A5BC 0x03BE # 0 +0x0000A5BD 0x03BF # 0 +0x0000A5BE 0x03C0 # 0 +0x0000A5BF 0x03C1 # 0 +0x0000A5C0 0x03C3 # 0 +0x0000A5C1 0x03C4 # 0 +0x0000A5C2 0x03C5 # 0 +0x0000A5C3 0x03C6 # 0 +0x0000A5C4 0x03C7 # 0 +0x0000A5C5 0x03C8 # 0 +0x0000A5C6 0x03C9 # 0 +0x0000A5C7 0x3105 # 0 +0x0000A5C8 0x3106 # 0 +0x0000A5C9 0x3107 # 0 +0x0000A5CA 0x3108 # 0 +0x0000A5CB 0x3109 # 0 +0x0000A5CC 0x310A # 0 +0x0000A5CD 0x310B # 0 +0x0000A5CE 0x310C # 0 +0x0000A5CF 0x310D # 0 +0x0000A5D0 0x310E # 0 +0x0000A5D1 0x310F # 0 +0x0000A5D2 0x3110 # 0 +0x0000A5D3 0x3111 # 0 +0x0000A5D4 0x3112 # 0 +0x0000A5D5 0x3113 # 0 +0x0000A5D6 0x3114 # 0 +0x0000A5D7 0x3115 # 0 +0x0000A5D8 0x3116 # 0 +0x0000A5D9 0x3117 # 0 +0x0000A5DA 0x3118 # 0 +0x0000A5DB 0x3119 # 0 +0x0000A5DC 0x311A # 0 +0x0000A5DD 0x311B # 0 +0x0000A5DE 0x311C # 0 +0x0000A5DF 0x311D # 0 +0x0000A5E0 0x311E # 0 +0x0000A5E1 0x311F # 0 +0x0000A5E2 0x3120 # 0 +0x0000A5E3 0x3121 # 0 +0x0000A5E4 0x3122 # 0 +0x0000A5E5 0x3123 # 0 +0x0000A5E6 0x3124 # 0 +0x0000A5E7 0x3125 # 0 +0x0000A5E8 0x3126 # 0 +0x0000A5E9 0x3127 # 0 +0x0000A5EA 0x3128 # 0 +0x0000A5EB 0x3129 # 0 +0x0000A5EC 0x02D9 # 0 +0x0000A5ED 0x02C9 # 0 +0x0000A5EE 0x02CA # 0 +0x0000A5EF 0x02C7 # 0 +0x0000A5F0 0x02CB # 0 +0x0000A6A1 0x2460 # 0 +0x0000A6A2 0x2461 # 0 +0x0000A6A3 0x2462 # 0 +0x0000A6A4 0x2463 # 0 +0x0000A6A5 0x2464 # 0 +0x0000A6A6 0x2465 # 0 +0x0000A6A7 0x2466 # 0 +0x0000A6A8 0x2467 # 0 +0x0000A6A9 0x2468 # 0 +0x0000A6AA 0x2469 # 0 +0x0000A6AB 0x2474 # 0 +0x0000A6AC 0x2475 # 0 +0x0000A6AD 0x2476 # 0 +0x0000A6AE 0x2477 # 0 +0x0000A6AF 0x2478 # 0 +0x0000A6B0 0x2479 # 0 +0x0000A6B1 0x247A # 0 +0x0000A6B2 0x247B # 0 +0x0000A6B3 0x247C # 0 +0x0000A6B4 0x247D # 0 +0x0000A6B5 0x2170 # 0 +0x0000A6B6 0x2171 # 0 +0x0000A6B7 0x2172 # 0 +0x0000A6B8 0x2173 # 0 +0x0000A6B9 0x2174 # 0 +0x0000A6BA 0x2175 # 0 +0x0000A6BB 0x2176 # 0 +0x0000A6BC 0x2177 # 0 +0x0000A6BD 0x2178 # 0 +0x0000A6BE 0x2179 # 0 +0x0000C2A1 0x2400 # 0 +0x0000C2A2 0x2401 # 0 +0x0000C2A3 0x2402 # 0 +0x0000C2A4 0x2403 # 0 +0x0000C2A5 0x2404 # 0 +0x0000C2A6 0x2405 # 0 +0x0000C2A7 0x2406 # 0 +0x0000C2A8 0x2407 # 0 +0x0000C2A9 0x2408 # 0 +0x0000C2AA 0x2409 # 0 +0x0000C2AB 0x240A # 0 +0x0000C2AC 0x240B # 0 +0x0000C2AD 0x240C # 0 +0x0000C2AE 0x240D # 0 +0x0000C2AF 0x240E # 0 +0x0000C2B0 0x240F # 0 +0x0000C2B1 0x2410 # 0 +0x0000C2B2 0x2411 # 0 +0x0000C2B3 0x2412 # 0 +0x0000C2B4 0x2413 # 0 +0x0000C2B5 0x2414 # 0 +0x0000C2B6 0x2415 # 0 +0x0000C2B7 0x2416 # 0 +0x0000C2B8 0x2417 # 0 +0x0000C2B9 0x2418 # 0 +0x0000C2BA 0x2419 # 0 +0x0000C2BB 0x241A # 0 +0x0000C2BC 0x241B # 0 +0x0000C2BD 0x241C # 0 +0x0000C2BE 0x241D # 0 +0x0000C2BF 0x241E # 0 +0x0000C2C0 0x241F # 0 +0x0000C2C1 0x2421 # 0 +0x0000C4A1 0x4E00 # 0 +0x0000C4A2 0x4E59 # 0 +0x0000C4A3 0x4E01 # 0 +0x0000C4A4 0x4E03 # 0 +0x0000C4A5 0x4E43 # 0 +0x0000C4A6 0x4E5D # 0 +0x0000C4A7 0x4E86 # 0 +0x0000C4A8 0x4E8C # 0 +0x0000C4A9 0x4EBA # 0 +0x0000C4AA 0x513F # 0 +0x0000C4AB 0x5165 # 0 +0x0000C4AC 0x516B # 0 +0x0000C4AD 0x51E0 # 0 +0x0000C4AE 0x5200 # 0 +0x0000C4AF 0x5201 # 0 +0x0000C4B0 0x529B # 0 +0x0000C4B1 0x5315 # 0 +0x0000C4B2 0x5341 # 0 +0x0000C4B3 0x535C # 0 +0x0000C4B4 0x53C8 # 0 +0x0000C4B5 0x4E09 # 0 +0x0000C4B6 0x4E0B # 0 +0x0000C4B7 0x4E08 # 0 +0x0000C4B8 0x4E0A # 0 +0x0000C4B9 0x4E2B # 0 +0x0000C4BA 0x4E38 # 0 +0x0000C4BB 0x51E1 # 0 +0x0000C4BC 0x4E45 # 0 +0x0000C4BD 0x4E48 # 0 +0x0000C4BE 0x4E5F # 0 +0x0000C4BF 0x4E5E # 0 +0x0000C4C0 0x4E8E # 0 +0x0000C4C1 0x4EA1 # 0 +0x0000C4C2 0x5140 # 0 +0x0000C4C3 0x5203 # 0 +0x0000C4C4 0x52FA # 0 +0x0000C4C5 0x5343 # 0 +0x0000C4C6 0x53C9 # 0 +0x0000C4C7 0x53E3 # 0 +0x0000C4C8 0x571F # 0 +0x0000C4C9 0x58EB # 0 +0x0000C4CA 0x5915 # 0 +0x0000C4CB 0x5927 # 0 +0x0000C4CC 0x5973 # 0 +0x0000C4CD 0x5B50 # 0 +0x0000C4CE 0x5B51 # 0 +0x0000C4CF 0x5B53 # 0 +0x0000C4D0 0x5BF8 # 0 +0x0000C4D1 0x5C0F # 0 +0x0000C4D2 0x5C22 # 0 +0x0000C4D3 0x5C38 # 0 +0x0000C4D4 0x5C71 # 0 +0x0000C4D5 0x5DDD # 0 +0x0000C4D6 0x5DE5 # 0 +0x0000C4D7 0x5DF1 # 0 +0x0000C4D8 0x5DF2 # 0 +0x0000C4D9 0x5DF3 # 0 +0x0000C4DA 0x5DFE # 0 +0x0000C4DB 0x5E72 # 0 +0x0000C4DC 0x5EFE # 0 +0x0000C4DD 0x5F0B # 0 +0x0000C4DE 0x5F13 # 0 +0x0000C4DF 0x624D # 0 +0x0000C4E0 0x4E11 # 0 +0x0000C4E1 0x4E10 # 0 +0x0000C4E2 0x4E0D # 0 +0x0000C4E3 0x4E2D # 0 +0x0000C4E4 0x4E30 # 0 +0x0000C4E5 0x4E39 # 0 +0x0000C4E6 0x4E4B # 0 +0x0000C4E7 0x5C39 # 0 +0x0000C4E8 0x4E88 # 0 +0x0000C4E9 0x4E91 # 0 +0x0000C4EA 0x4E95 # 0 +0x0000C4EB 0x4E92 # 0 +0x0000C4EC 0x4E94 # 0 +0x0000C4ED 0x4EA2 # 0 +0x0000C4EE 0x4EC1 # 0 +0x0000C4EF 0x4EC0 # 0 +0x0000C4F0 0x4EC3 # 0 +0x0000C4F1 0x4EC6 # 0 +0x0000C4F2 0x4EC7 # 0 +0x0000C4F3 0x4ECD # 0 +0x0000C4F4 0x4ECA # 0 +0x0000C4F5 0x4ECB # 0 +0x0000C4F6 0x4EC4 # 0 +0x0000C4F7 0x5143 # 0 +0x0000C4F8 0x5141 # 0 +0x0000C4F9 0x5167 # 0 +0x0000C4FA 0x516D # 0 +0x0000C4FB 0x516E # 0 +0x0000C4FC 0x516C # 0 +0x0000C4FD 0x5197 # 0 +0x0000C4FE 0x51F6 # 0 +0x0000C5A1 0x5206 # 0 +0x0000C5A2 0x5207 # 0 +0x0000C5A3 0x5208 # 0 +0x0000C5A4 0x52FB # 0 +0x0000C5A5 0x52FE # 0 +0x0000C5A6 0x52FF # 0 +0x0000C5A7 0x5316 # 0 +0x0000C5A8 0x5339 # 0 +0x0000C5A9 0x5348 # 0 +0x0000C5AA 0x5347 # 0 +0x0000C5AB 0x5345 # 0 +0x0000C5AC 0x535E # 0 +0x0000C5AD 0x5384 # 0 +0x0000C5AE 0x53CB # 0 +0x0000C5AF 0x53CA # 0 +0x0000C5B0 0x53CD # 0 +0x0000C5B1 0x58EC # 0 +0x0000C5B2 0x5929 # 0 +0x0000C5B3 0x592B # 0 +0x0000C5B4 0x592A # 0 +0x0000C5B5 0x592D # 0 +0x0000C5B6 0x5B54 # 0 +0x0000C5B7 0x5C11 # 0 +0x0000C5B8 0x5C24 # 0 +0x0000C5B9 0x5C3A # 0 +0x0000C5BA 0x5C6F # 0 +0x0000C5BB 0x5DF4 # 0 +0x0000C5BC 0x5E7B # 0 +0x0000C5BD 0x5EFF # 0 +0x0000C5BE 0x5F14 # 0 +0x0000C5BF 0x5F15 # 0 +0x0000C5C0 0x5FC3 # 0 +0x0000C5C1 0x6208 # 0 +0x0000C5C2 0x6236 # 0 +0x0000C5C3 0x624B # 0 +0x0000C5C4 0x624E # 0 +0x0000C5C5 0x652F # 0 +0x0000C5C6 0x6587 # 0 +0x0000C5C7 0x6597 # 0 +0x0000C5C8 0x65A4 # 0 +0x0000C5C9 0x65B9 # 0 +0x0000C5CA 0x65E5 # 0 +0x0000C5CB 0x66F0 # 0 +0x0000C5CC 0x6708 # 0 +0x0000C5CD 0x6728 # 0 +0x0000C5CE 0x6B20 # 0 +0x0000C5CF 0x6B62 # 0 +0x0000C5D0 0x6B79 # 0 +0x0000C5D1 0x6BCB # 0 +0x0000C5D2 0x6BD4 # 0 +0x0000C5D3 0x6BDB # 0 +0x0000C5D4 0x6C0F # 0 +0x0000C5D5 0x6C34 # 0 +0x0000C5D6 0x706B # 0 +0x0000C5D7 0x722A # 0 +0x0000C5D8 0x7236 # 0 +0x0000C5D9 0x723B # 0 +0x0000C5DA 0x7247 # 0 +0x0000C5DB 0x7259 # 0 +0x0000C5DC 0x725B # 0 +0x0000C5DD 0x72AC # 0 +0x0000C5DE 0x738B # 0 +0x0000C5DF 0x4E19 # 0 +0x0000C5E0 0x4E16 # 0 +0x0000C5E1 0x4E15 # 0 +0x0000C5E2 0x4E14 # 0 +0x0000C5E3 0x4E18 # 0 +0x0000C5E4 0x4E3B # 0 +0x0000C5E5 0x4E4D # 0 +0x0000C5E6 0x4E4F # 0 +0x0000C5E7 0x4E4E # 0 +0x0000C5E8 0x4EE5 # 0 +0x0000C5E9 0x4ED8 # 0 +0x0000C5EA 0x4ED4 # 0 +0x0000C5EB 0x4ED5 # 0 +0x0000C5EC 0x4ED6 # 0 +0x0000C5ED 0x4ED7 # 0 +0x0000C5EE 0x4EE3 # 0 +0x0000C5EF 0x4EE4 # 0 +0x0000C5F0 0x4ED9 # 0 +0x0000C5F1 0x4EDE # 0 +0x0000C5F2 0x5145 # 0 +0x0000C5F3 0x5144 # 0 +0x0000C5F4 0x5189 # 0 +0x0000C5F5 0x518A # 0 +0x0000C5F6 0x51AC # 0 +0x0000C5F7 0x51F9 # 0 +0x0000C5F8 0x51FA # 0 +0x0000C5F9 0x51F8 # 0 +0x0000C5FA 0x520A # 0 +0x0000C5FB 0x52A0 # 0 +0x0000C5FC 0x529F # 0 +0x0000C5FD 0x5305 # 0 +0x0000C5FE 0x5306 # 0 +0x0000C6A1 0x5317 # 0 +0x0000C6A2 0x531D # 0 +0x0000C6A3 0x4EDF # 0 +0x0000C6A4 0x534A # 0 +0x0000C6A5 0x5349 # 0 +0x0000C6A6 0x5361 # 0 +0x0000C6A7 0x5360 # 0 +0x0000C6A8 0x536F # 0 +0x0000C6A9 0x536E # 0 +0x0000C6AA 0x53BB # 0 +0x0000C6AB 0x53EF # 0 +0x0000C6AC 0x53E4 # 0 +0x0000C6AD 0x53F3 # 0 +0x0000C6AE 0x53EC # 0 +0x0000C6AF 0x53EE # 0 +0x0000C6B0 0x53E9 # 0 +0x0000C6B1 0x53E8 # 0 +0x0000C6B2 0x53FC # 0 +0x0000C6B3 0x53F8 # 0 +0x0000C6B4 0x53F5 # 0 +0x0000C6B5 0x53EB # 0 +0x0000C6B6 0x53E6 # 0 +0x0000C6B7 0x53EA # 0 +0x0000C6B8 0x53F2 # 0 +0x0000C6B9 0x53F1 # 0 +0x0000C6BA 0x53F0 # 0 +0x0000C6BB 0x53E5 # 0 +0x0000C6BC 0x53ED # 0 +0x0000C6BD 0x53FB # 0 +0x0000C6BE 0x56DB # 0 +0x0000C6BF 0x56DA # 0 +0x0000C6C0 0x5916 # 0 +0x0000C6C1 0x592E # 0 +0x0000C6C2 0x5931 # 0 +0x0000C6C3 0x5974 # 0 +0x0000C6C4 0x5976 # 0 +0x0000C6C5 0x5B55 # 0 +0x0000C6C6 0x5B83 # 0 +0x0000C6C7 0x5C3C # 0 +0x0000C6C8 0x5DE8 # 0 +0x0000C6C9 0x5DE7 # 0 +0x0000C6CA 0x5DE6 # 0 +0x0000C6CB 0x5E02 # 0 +0x0000C6CC 0x5E03 # 0 +0x0000C6CD 0x5E73 # 0 +0x0000C6CE 0x5E7C # 0 +0x0000C6CF 0x5F01 # 0 +0x0000C6D0 0x5F18 # 0 +0x0000C6D1 0x5F17 # 0 +0x0000C6D2 0x5FC5 # 0 +0x0000C6D3 0x620A # 0 +0x0000C6D4 0x6253 # 0 +0x0000C6D5 0x6254 # 0 +0x0000C6D6 0x6252 # 0 +0x0000C6D7 0x6251 # 0 +0x0000C6D8 0x65A5 # 0 +0x0000C6D9 0x65E6 # 0 +0x0000C6DA 0x672E # 0 +0x0000C6DB 0x672C # 0 +0x0000C6DC 0x672A # 0 +0x0000C6DD 0x672B # 0 +0x0000C6DE 0x672D # 0 +0x0000C6DF 0x6B63 # 0 +0x0000C6E0 0x6BCD # 0 +0x0000C6E1 0x6C11 # 0 +0x0000C6E2 0x6C10 # 0 +0x0000C6E3 0x6C38 # 0 +0x0000C6E4 0x6C41 # 0 +0x0000C6E5 0x6C40 # 0 +0x0000C6E6 0x6C3E # 0 +0x0000C6E7 0x72AF # 0 +0x0000C6E8 0x7384 # 0 +0x0000C6E9 0x7389 # 0 +0x0000C6EA 0x74DC # 0 +0x0000C6EB 0x74E6 # 0 +0x0000C6EC 0x7518 # 0 +0x0000C6ED 0x751F # 0 +0x0000C6EE 0x7528 # 0 +0x0000C6EF 0x7529 # 0 +0x0000C6F0 0x7530 # 0 +0x0000C6F1 0x7531 # 0 +0x0000C6F2 0x7532 # 0 +0x0000C6F3 0x7533 # 0 +0x0000C6F4 0x758B # 0 +0x0000C6F5 0x767D # 0 +0x0000C6F6 0x76AE # 0 +0x0000C6F7 0x76BF # 0 +0x0000C6F8 0x76EE # 0 +0x0000C6F9 0x77DB # 0 +0x0000C6FA 0x77E2 # 0 +0x0000C6FB 0x77F3 # 0 +0x0000C6FC 0x793A # 0 +0x0000C6FD 0x79BE # 0 +0x0000C6FE 0x7A74 # 0 +0x0000C7A1 0x7ACB # 0 +0x0000C7A2 0x4E1E # 0 +0x0000C7A3 0x4E1F # 0 +0x0000C7A4 0x4E52 # 0 +0x0000C7A5 0x4E53 # 0 +0x0000C7A6 0x4E69 # 0 +0x0000C7A7 0x4E99 # 0 +0x0000C7A8 0x4EA4 # 0 +0x0000C7A9 0x4EA6 # 0 +0x0000C7AA 0x4EA5 # 0 +0x0000C7AB 0x4EFF # 0 +0x0000C7AC 0x4F09 # 0 +0x0000C7AD 0x4F19 # 0 +0x0000C7AE 0x4F0A # 0 +0x0000C7AF 0x4F15 # 0 +0x0000C7B0 0x4F0D # 0 +0x0000C7B1 0x4F10 # 0 +0x0000C7B2 0x4F11 # 0 +0x0000C7B3 0x4F0F # 0 +0x0000C7B4 0x4EF2 # 0 +0x0000C7B5 0x4EF6 # 0 +0x0000C7B6 0x4EFB # 0 +0x0000C7B7 0x4EF0 # 0 +0x0000C7B8 0x4EF3 # 0 +0x0000C7B9 0x4EFD # 0 +0x0000C7BA 0x4F01 # 0 +0x0000C7BB 0x4F0B # 0 +0x0000C7BC 0x5149 # 0 +0x0000C7BD 0x5147 # 0 +0x0000C7BE 0x5146 # 0 +0x0000C7BF 0x5148 # 0 +0x0000C7C0 0x5168 # 0 +0x0000C7C1 0x5171 # 0 +0x0000C7C2 0x518D # 0 +0x0000C7C3 0x51B0 # 0 +0x0000C7C4 0x5217 # 0 +0x0000C7C5 0x5211 # 0 +0x0000C7C6 0x5212 # 0 +0x0000C7C7 0x520E # 0 +0x0000C7C8 0x5216 # 0 +0x0000C7C9 0x52A3 # 0 +0x0000C7CA 0x5308 # 0 +0x0000C7CB 0x5321 # 0 +0x0000C7CC 0x5320 # 0 +0x0000C7CD 0x5370 # 0 +0x0000C7CE 0x5371 # 0 +0x0000C7CF 0x5409 # 0 +0x0000C7D0 0x540F # 0 +0x0000C7D1 0x540C # 0 +0x0000C7D2 0x540A # 0 +0x0000C7D3 0x5410 # 0 +0x0000C7D4 0x5401 # 0 +0x0000C7D5 0x540B # 0 +0x0000C7D6 0x5404 # 0 +0x0000C7D7 0x5411 # 0 +0x0000C7D8 0x540D # 0 +0x0000C7D9 0x5408 # 0 +0x0000C7DA 0x5403 # 0 +0x0000C7DB 0x540E # 0 +0x0000C7DC 0x5406 # 0 +0x0000C7DD 0x5412 # 0 +0x0000C7DE 0x56E0 # 0 +0x0000C7DF 0x56DE # 0 +0x0000C7E0 0x56DD # 0 +0x0000C7E1 0x5733 # 0 +0x0000C7E2 0x5730 # 0 +0x0000C7E3 0x5728 # 0 +0x0000C7E4 0x572D # 0 +0x0000C7E5 0x572C # 0 +0x0000C7E6 0x572F # 0 +0x0000C7E7 0x5729 # 0 +0x0000C7E8 0x5919 # 0 +0x0000C7E9 0x591A # 0 +0x0000C7EA 0x5937 # 0 +0x0000C7EB 0x5938 # 0 +0x0000C7EC 0x5984 # 0 +0x0000C7ED 0x5978 # 0 +0x0000C7EE 0x5983 # 0 +0x0000C7EF 0x597D # 0 +0x0000C7F0 0x5979 # 0 +0x0000C7F1 0x5982 # 0 +0x0000C7F2 0x5981 # 0 +0x0000C7F3 0x5B57 # 0 +0x0000C7F4 0x5B58 # 0 +0x0000C7F5 0x5B87 # 0 +0x0000C7F6 0x5B88 # 0 +0x0000C7F7 0x5B85 # 0 +0x0000C7F8 0x5B89 # 0 +0x0000C7F9 0x5BFA # 0 +0x0000C7FA 0x5C16 # 0 +0x0000C7FB 0x5C79 # 0 +0x0000C7FC 0x5DDE # 0 +0x0000C7FD 0x5E06 # 0 +0x0000C7FE 0x5E76 # 0 +0x0000C8A1 0x5E74 # 0 +0x0000C8A2 0x5F0F # 0 +0x0000C8A3 0x5F1B # 0 +0x0000C8A4 0x5FD9 # 0 +0x0000C8A5 0x5FD6 # 0 +0x0000C8A6 0x620E # 0 +0x0000C8A7 0x620C # 0 +0x0000C8A8 0x620D # 0 +0x0000C8A9 0x6210 # 0 +0x0000C8AA 0x6263 # 0 +0x0000C8AB 0x625B # 0 +0x0000C8AC 0x6258 # 0 +0x0000C8AD 0x6536 # 0 +0x0000C8AE 0x65E9 # 0 +0x0000C8AF 0x65E8 # 0 +0x0000C8B0 0x65EC # 0 +0x0000C8B1 0x65ED # 0 +0x0000C8B2 0x66F2 # 0 +0x0000C8B3 0x66F3 # 0 +0x0000C8B4 0x6709 # 0 +0x0000C8B5 0x673D # 0 +0x0000C8B6 0x6734 # 0 +0x0000C8B7 0x6731 # 0 +0x0000C8B8 0x6735 # 0 +0x0000C8B9 0x6B21 # 0 +0x0000C8BA 0x6B64 # 0 +0x0000C8BB 0x6B7B # 0 +0x0000C8BC 0x6C16 # 0 +0x0000C8BD 0x6C5D # 0 +0x0000C8BE 0x6C57 # 0 +0x0000C8BF 0x6C59 # 0 +0x0000C8C0 0x6C5F # 0 +0x0000C8C1 0x6C60 # 0 +0x0000C8C2 0x6C50 # 0 +0x0000C8C3 0x6C55 # 0 +0x0000C8C4 0x6C61 # 0 +0x0000C8C5 0x6C5B # 0 +0x0000C8C6 0x6C4D # 0 +0x0000C8C7 0x6C4E # 0 +0x0000C8C8 0x7070 # 0 +0x0000C8C9 0x725F # 0 +0x0000C8CA 0x725D # 0 +0x0000C8CB 0x767E # 0 +0x0000C8CC 0x7AF9 # 0 +0x0000C8CD 0x7C73 # 0 +0x0000C8CE 0x7CF8 # 0 +0x0000C8CF 0x7F36 # 0 +0x0000C8D0 0x7F8A # 0 +0x0000C8D1 0x7FBD # 0 +0x0000C8D2 0x8001 # 0 +0x0000C8D3 0x8003 # 0 +0x0000C8D4 0x800C # 0 +0x0000C8D5 0x8012 # 0 +0x0000C8D6 0x8033 # 0 +0x0000C8D7 0x807F # 0 +0x0000C8D8 0x8089 # 0 +0x0000C8D9 0x808B # 0 +0x0000C8DA 0x808C # 0 +0x0000C8DB 0x81E3 # 0 +0x0000C8DC 0x81EA # 0 +0x0000C8DD 0x81F3 # 0 +0x0000C8DE 0x81FC # 0 +0x0000C8DF 0x820C # 0 +0x0000C8E0 0x821B # 0 +0x0000C8E1 0x821F # 0 +0x0000C8E2 0x826E # 0 +0x0000C8E3 0x8272 # 0 +0x0000C8E4 0x827E # 0 +0x0000C8E5 0x866B # 0 +0x0000C8E6 0x8840 # 0 +0x0000C8E7 0x884C # 0 +0x0000C8E8 0x8863 # 0 +0x0000C8E9 0x897F # 0 +0x0000C8EA 0x9621 # 0 +0x0000C8EB 0x4E32 # 0 +0x0000C8EC 0x4EA8 # 0 +0x0000C8ED 0x4F4D # 0 +0x0000C8EE 0x4F4F # 0 +0x0000C8EF 0x4F47 # 0 +0x0000C8F0 0x4F57 # 0 +0x0000C8F1 0x4F5E # 0 +0x0000C8F2 0x4F34 # 0 +0x0000C8F3 0x4F5B # 0 +0x0000C8F4 0x4F55 # 0 +0x0000C8F5 0x4F30 # 0 +0x0000C8F6 0x4F50 # 0 +0x0000C8F7 0x4F51 # 0 +0x0000C8F8 0x4F3D # 0 +0x0000C8F9 0x4F3A # 0 +0x0000C8FA 0x4F38 # 0 +0x0000C8FB 0x4F43 # 0 +0x0000C8FC 0x4F54 # 0 +0x0000C8FD 0x4F3C # 0 +0x0000C8FE 0x4F46 # 0 +0x0000C9A1 0x4F63 # 0 +0x0000C9A2 0x4F5C # 0 +0x0000C9A3 0x4F60 # 0 +0x0000C9A4 0x4F2F # 0 +0x0000C9A5 0x4F4E # 0 +0x0000C9A6 0x4F36 # 0 +0x0000C9A7 0x4F59 # 0 +0x0000C9A8 0x4F5D # 0 +0x0000C9A9 0x4F48 # 0 +0x0000C9AA 0x4F5A # 0 +0x0000C9AB 0x514C # 0 +0x0000C9AC 0x514B # 0 +0x0000C9AD 0x514D # 0 +0x0000C9AE 0x5175 # 0 +0x0000C9AF 0x51B6 # 0 +0x0000C9B0 0x51B7 # 0 +0x0000C9B1 0x5225 # 0 +0x0000C9B2 0x5224 # 0 +0x0000C9B3 0x5229 # 0 +0x0000C9B4 0x522A # 0 +0x0000C9B5 0x5228 # 0 +0x0000C9B6 0x52AB # 0 +0x0000C9B7 0x52A9 # 0 +0x0000C9B8 0x52AA # 0 +0x0000C9B9 0x52AC # 0 +0x0000C9BA 0x5323 # 0 +0x0000C9BB 0x5373 # 0 +0x0000C9BC 0x5375 # 0 +0x0000C9BD 0x541D # 0 +0x0000C9BE 0x542D # 0 +0x0000C9BF 0x541E # 0 +0x0000C9C0 0x543E # 0 +0x0000C9C1 0x5426 # 0 +0x0000C9C2 0x544E # 0 +0x0000C9C3 0x5427 # 0 +0x0000C9C4 0x5446 # 0 +0x0000C9C5 0x5443 # 0 +0x0000C9C6 0x5433 # 0 +0x0000C9C7 0x5448 # 0 +0x0000C9C8 0x5442 # 0 +0x0000C9C9 0x541B # 0 +0x0000C9CA 0x5429 # 0 +0x0000C9CB 0x544A # 0 +0x0000C9CC 0x5439 # 0 +0x0000C9CD 0x543B # 0 +0x0000C9CE 0x5438 # 0 +0x0000C9CF 0x542E # 0 +0x0000C9D0 0x5435 # 0 +0x0000C9D1 0x5436 # 0 +0x0000C9D2 0x5420 # 0 +0x0000C9D3 0x543C # 0 +0x0000C9D4 0x5440 # 0 +0x0000C9D5 0x5431 # 0 +0x0000C9D6 0x542B # 0 +0x0000C9D7 0x541F # 0 +0x0000C9D8 0x542C # 0 +0x0000C9D9 0x56EA # 0 +0x0000C9DA 0x56F0 # 0 +0x0000C9DB 0x56E4 # 0 +0x0000C9DC 0x56EB # 0 +0x0000C9DD 0x574A # 0 +0x0000C9DE 0x5751 # 0 +0x0000C9DF 0x5740 # 0 +0x0000C9E0 0x574D # 0 +0x0000C9E1 0x5747 # 0 +0x0000C9E2 0x574E # 0 +0x0000C9E3 0x573E # 0 +0x0000C9E4 0x5750 # 0 +0x0000C9E5 0x574F # 0 +0x0000C9E6 0x573B # 0 +0x0000C9E7 0x58EF # 0 +0x0000C9E8 0x593E # 0 +0x0000C9E9 0x599D # 0 +0x0000C9EA 0x5992 # 0 +0x0000C9EB 0x59A8 # 0 +0x0000C9EC 0x599E # 0 +0x0000C9ED 0x59A3 # 0 +0x0000C9EE 0x5999 # 0 +0x0000C9EF 0x5996 # 0 +0x0000C9F0 0x598D # 0 +0x0000C9F1 0x59A4 # 0 +0x0000C9F2 0x5993 # 0 +0x0000C9F3 0x598A # 0 +0x0000C9F4 0x59A5 # 0 +0x0000C9F5 0x5B5D # 0 +0x0000C9F6 0x5B5C # 0 +0x0000C9F7 0x5B5A # 0 +0x0000C9F8 0x5B5B # 0 +0x0000C9F9 0x5B8C # 0 +0x0000C9FA 0x5B8B # 0 +0x0000C9FB 0x5B8F # 0 +0x0000C9FC 0x5C2C # 0 +0x0000C9FD 0x5C40 # 0 +0x0000C9FE 0x5C41 # 0 +0x0000CAA1 0x5C3F # 0 +0x0000CAA2 0x5C3E # 0 +0x0000CAA3 0x5C90 # 0 +0x0000CAA4 0x5C91 # 0 +0x0000CAA5 0x5C94 # 0 +0x0000CAA6 0x5C8C # 0 +0x0000CAA7 0x5DEB # 0 +0x0000CAA8 0x5E0C # 0 +0x0000CAA9 0x5E8F # 0 +0x0000CAAA 0x5E87 # 0 +0x0000CAAB 0x5E8A # 0 +0x0000CAAC 0x5EF7 # 0 +0x0000CAAD 0x5F04 # 0 +0x0000CAAE 0x5F1F # 0 +0x0000CAAF 0x5F64 # 0 +0x0000CAB0 0x5F62 # 0 +0x0000CAB1 0x5F77 # 0 +0x0000CAB2 0x5F79 # 0 +0x0000CAB3 0x5FD8 # 0 +0x0000CAB4 0x5FCC # 0 +0x0000CAB5 0x5FD7 # 0 +0x0000CAB6 0x5FCD # 0 +0x0000CAB7 0x5FF1 # 0 +0x0000CAB8 0x5FEB # 0 +0x0000CAB9 0x5FF8 # 0 +0x0000CABA 0x5FEA # 0 +0x0000CABB 0x6212 # 0 +0x0000CABC 0x6211 # 0 +0x0000CABD 0x6284 # 0 +0x0000CABE 0x6297 # 0 +0x0000CABF 0x6296 # 0 +0x0000CAC0 0x6280 # 0 +0x0000CAC1 0x6276 # 0 +0x0000CAC2 0x6289 # 0 +0x0000CAC3 0x626D # 0 +0x0000CAC4 0x628A # 0 +0x0000CAC5 0x627C # 0 +0x0000CAC6 0x627E # 0 +0x0000CAC7 0x6279 # 0 +0x0000CAC8 0x6273 # 0 +0x0000CAC9 0x6292 # 0 +0x0000CACA 0x626F # 0 +0x0000CACB 0x6298 # 0 +0x0000CACC 0x626E # 0 +0x0000CACD 0x6295 # 0 +0x0000CACE 0x6293 # 0 +0x0000CACF 0x6291 # 0 +0x0000CAD0 0x6286 # 0 +0x0000CAD1 0x6539 # 0 +0x0000CAD2 0x653B # 0 +0x0000CAD3 0x6538 # 0 +0x0000CAD4 0x65F1 # 0 +0x0000CAD5 0x66F4 # 0 +0x0000CAD6 0x675F # 0 +0x0000CAD7 0x674E # 0 +0x0000CAD8 0x674F # 0 +0x0000CAD9 0x6750 # 0 +0x0000CADA 0x6751 # 0 +0x0000CADB 0x675C # 0 +0x0000CADC 0x6756 # 0 +0x0000CADD 0x675E # 0 +0x0000CADE 0x6749 # 0 +0x0000CADF 0x6746 # 0 +0x0000CAE0 0x6760 # 0 +0x0000CAE1 0x6753 # 0 +0x0000CAE2 0x6757 # 0 +0x0000CAE3 0x6B65 # 0 +0x0000CAE4 0x6BCF # 0 +0x0000CAE5 0x6C42 # 0 +0x0000CAE6 0x6C5E # 0 +0x0000CAE7 0x6C99 # 0 +0x0000CAE8 0x6C81 # 0 +0x0000CAE9 0x6C88 # 0 +0x0000CAEA 0x6C89 # 0 +0x0000CAEB 0x6C85 # 0 +0x0000CAEC 0x6C9B # 0 +0x0000CAED 0x6C6A # 0 +0x0000CAEE 0x6C7A # 0 +0x0000CAEF 0x6C90 # 0 +0x0000CAF0 0x6C70 # 0 +0x0000CAF1 0x6C8C # 0 +0x0000CAF2 0x6C68 # 0 +0x0000CAF3 0x6C96 # 0 +0x0000CAF4 0x6C92 # 0 +0x0000CAF5 0x6C7D # 0 +0x0000CAF6 0x6C83 # 0 +0x0000CAF7 0x6C72 # 0 +0x0000CAF8 0x6C7E # 0 +0x0000CAF9 0x6C74 # 0 +0x0000CAFA 0x6C86 # 0 +0x0000CAFB 0x6C76 # 0 +0x0000CAFC 0x6C8D # 0 +0x0000CAFD 0x6C94 # 0 +0x0000CAFE 0x6C98 # 0 +0x0000CBA1 0x6C82 # 0 +0x0000CBA2 0x7076 # 0 +0x0000CBA3 0x707C # 0 +0x0000CBA4 0x707D # 0 +0x0000CBA5 0x7078 # 0 +0x0000CBA6 0x7262 # 0 +0x0000CBA7 0x7261 # 0 +0x0000CBA8 0x7260 # 0 +0x0000CBA9 0x72C4 # 0 +0x0000CBAA 0x72C2 # 0 +0x0000CBAB 0x7396 # 0 +0x0000CBAC 0x752C # 0 +0x0000CBAD 0x752B # 0 +0x0000CBAE 0x7537 # 0 +0x0000CBAF 0x7538 # 0 +0x0000CBB0 0x7682 # 0 +0x0000CBB1 0x76EF # 0 +0x0000CBB2 0x77E3 # 0 +0x0000CBB3 0x79C1 # 0 +0x0000CBB4 0x79C0 # 0 +0x0000CBB5 0x79BF # 0 +0x0000CBB6 0x7A76 # 0 +0x0000CBB7 0x7CFB # 0 +0x0000CBB8 0x7F55 # 0 +0x0000CBB9 0x8096 # 0 +0x0000CBBA 0x8093 # 0 +0x0000CBBB 0x809D # 0 +0x0000CBBC 0x8098 # 0 +0x0000CBBD 0x809B # 0 +0x0000CBBE 0x809A # 0 +0x0000CBBF 0x80B2 # 0 +0x0000CBC0 0x826F # 0 +0x0000CBC1 0x8292 # 0 +0x0000CBC2 0x828B # 0 +0x0000CBC3 0x828D # 0 +0x0000CBC4 0x898B # 0 +0x0000CBC5 0x89D2 # 0 +0x0000CBC6 0x8A00 # 0 +0x0000CBC7 0x8C37 # 0 +0x0000CBC8 0x8C46 # 0 +0x0000CBC9 0x8C55 # 0 +0x0000CBCA 0x8C9D # 0 +0x0000CBCB 0x8D64 # 0 +0x0000CBCC 0x8D70 # 0 +0x0000CBCD 0x8DB3 # 0 +0x0000CBCE 0x8EAB # 0 +0x0000CBCF 0x8ECA # 0 +0x0000CBD0 0x8F9B # 0 +0x0000CBD1 0x8FB0 # 0 +0x0000CBD2 0x8FC2 # 0 +0x0000CBD3 0x8FC6 # 0 +0x0000CBD4 0x8FC5 # 0 +0x0000CBD5 0x8FC4 # 0 +0x0000CBD6 0x5DE1 # 0 +0x0000CBD7 0x9091 # 0 +0x0000CBD8 0x90A2 # 0 +0x0000CBD9 0x90AA # 0 +0x0000CBDA 0x90A6 # 0 +0x0000CBDB 0x90A3 # 0 +0x0000CBDC 0x9149 # 0 +0x0000CBDD 0x91C6 # 0 +0x0000CBDE 0x91CC # 0 +0x0000CBDF 0x9632 # 0 +0x0000CBE0 0x962E # 0 +0x0000CBE1 0x9631 # 0 +0x0000CBE2 0x962A # 0 +0x0000CBE3 0x962C # 0 +0x0000CBE4 0x4E26 # 0 +0x0000CBE5 0x4E56 # 0 +0x0000CBE6 0x4E73 # 0 +0x0000CBE7 0x4E8B # 0 +0x0000CBE8 0x4E9B # 0 +0x0000CBE9 0x4E9E # 0 +0x0000CBEA 0x4EAB # 0 +0x0000CBEB 0x4EAC # 0 +0x0000CBEC 0x4F6F # 0 +0x0000CBED 0x4F9D # 0 +0x0000CBEE 0x4F8D # 0 +0x0000CBEF 0x4F73 # 0 +0x0000CBF0 0x4F7F # 0 +0x0000CBF1 0x4F6C # 0 +0x0000CBF2 0x4F9B # 0 +0x0000CBF3 0x4F8B # 0 +0x0000CBF4 0x4F86 # 0 +0x0000CBF5 0x4F83 # 0 +0x0000CBF6 0x4F70 # 0 +0x0000CBF7 0x4F75 # 0 +0x0000CBF8 0x4F88 # 0 +0x0000CBF9 0x4F69 # 0 +0x0000CBFA 0x4F7B # 0 +0x0000CBFB 0x4F96 # 0 +0x0000CBFC 0x4F7E # 0 +0x0000CBFD 0x4F8F # 0 +0x0000CBFE 0x4F91 # 0 +0x0000CCA1 0x4F7A # 0 +0x0000CCA2 0x5154 # 0 +0x0000CCA3 0x5152 # 0 +0x0000CCA4 0x5155 # 0 +0x0000CCA5 0x5169 # 0 +0x0000CCA6 0x5177 # 0 +0x0000CCA7 0x5176 # 0 +0x0000CCA8 0x5178 # 0 +0x0000CCA9 0x51BD # 0 +0x0000CCAA 0x51FD # 0 +0x0000CCAB 0x523B # 0 +0x0000CCAC 0x5238 # 0 +0x0000CCAD 0x5237 # 0 +0x0000CCAE 0x523A # 0 +0x0000CCAF 0x5230 # 0 +0x0000CCB0 0x522E # 0 +0x0000CCB1 0x5236 # 0 +0x0000CCB2 0x5241 # 0 +0x0000CCB3 0x52BE # 0 +0x0000CCB4 0x52BB # 0 +0x0000CCB5 0x5352 # 0 +0x0000CCB6 0x5354 # 0 +0x0000CCB7 0x5353 # 0 +0x0000CCB8 0x5351 # 0 +0x0000CCB9 0x5366 # 0 +0x0000CCBA 0x5377 # 0 +0x0000CCBB 0x5378 # 0 +0x0000CCBC 0x5379 # 0 +0x0000CCBD 0x53D6 # 0 +0x0000CCBE 0x53D4 # 0 +0x0000CCBF 0x53D7 # 0 +0x0000CCC0 0x5473 # 0 +0x0000CCC1 0x5475 # 0 +0x0000CCC2 0x5496 # 0 +0x0000CCC3 0x5478 # 0 +0x0000CCC4 0x5495 # 0 +0x0000CCC5 0x5480 # 0 +0x0000CCC6 0x547B # 0 +0x0000CCC7 0x5477 # 0 +0x0000CCC8 0x5484 # 0 +0x0000CCC9 0x5492 # 0 +0x0000CCCA 0x5486 # 0 +0x0000CCCB 0x547C # 0 +0x0000CCCC 0x5490 # 0 +0x0000CCCD 0x5471 # 0 +0x0000CCCE 0x5476 # 0 +0x0000CCCF 0x548C # 0 +0x0000CCD0 0x549A # 0 +0x0000CCD1 0x5462 # 0 +0x0000CCD2 0x5468 # 0 +0x0000CCD3 0x548B # 0 +0x0000CCD4 0x547D # 0 +0x0000CCD5 0x548E # 0 +0x0000CCD6 0x56FA # 0 +0x0000CCD7 0x5783 # 0 +0x0000CCD8 0x5777 # 0 +0x0000CCD9 0x576A # 0 +0x0000CCDA 0x5769 # 0 +0x0000CCDB 0x5761 # 0 +0x0000CCDC 0x5766 # 0 +0x0000CCDD 0x5764 # 0 +0x0000CCDE 0x577C # 0 +0x0000CCDF 0x591C # 0 +0x0000CCE0 0x5949 # 0 +0x0000CCE1 0x5947 # 0 +0x0000CCE2 0x5948 # 0 +0x0000CCE3 0x5944 # 0 +0x0000CCE4 0x5954 # 0 +0x0000CCE5 0x59BE # 0 +0x0000CCE6 0x59BB # 0 +0x0000CCE7 0x59D4 # 0 +0x0000CCE8 0x59B9 # 0 +0x0000CCE9 0x59AE # 0 +0x0000CCEA 0x59D1 # 0 +0x0000CCEB 0x59C6 # 0 +0x0000CCEC 0x59D0 # 0 +0x0000CCED 0x59CD # 0 +0x0000CCEE 0x59CB # 0 +0x0000CCEF 0x59D3 # 0 +0x0000CCF0 0x59CA # 0 +0x0000CCF1 0x59AF # 0 +0x0000CCF2 0x59B3 # 0 +0x0000CCF3 0x59D2 # 0 +0x0000CCF4 0x59C5 # 0 +0x0000CCF5 0x5B5F # 0 +0x0000CCF6 0x5B64 # 0 +0x0000CCF7 0x5B63 # 0 +0x0000CCF8 0x5B97 # 0 +0x0000CCF9 0x5B9A # 0 +0x0000CCFA 0x5B98 # 0 +0x0000CCFB 0x5B9C # 0 +0x0000CCFC 0x5B99 # 0 +0x0000CCFD 0x5B9B # 0 +0x0000CCFE 0x5C1A # 0 +0x0000CDA1 0x5C48 # 0 +0x0000CDA2 0x5C45 # 0 +0x0000CDA3 0x5C46 # 0 +0x0000CDA4 0x5CB7 # 0 +0x0000CDA5 0x5CA1 # 0 +0x0000CDA6 0x5CB8 # 0 +0x0000CDA7 0x5CA9 # 0 +0x0000CDA8 0x5CAB # 0 +0x0000CDA9 0x5CB1 # 0 +0x0000CDAA 0x5CB3 # 0 +0x0000CDAB 0x5E18 # 0 +0x0000CDAC 0x5E1A # 0 +0x0000CDAD 0x5E16 # 0 +0x0000CDAE 0x5E15 # 0 +0x0000CDAF 0x5E1B # 0 +0x0000CDB0 0x5E11 # 0 +0x0000CDB1 0x5E78 # 0 +0x0000CDB2 0x5E9A # 0 +0x0000CDB3 0x5E97 # 0 +0x0000CDB4 0x5E9C # 0 +0x0000CDB5 0x5E95 # 0 +0x0000CDB6 0x5E96 # 0 +0x0000CDB7 0x5EF6 # 0 +0x0000CDB8 0x5F26 # 0 +0x0000CDB9 0x5F27 # 0 +0x0000CDBA 0x5F29 # 0 +0x0000CDBB 0x5F80 # 0 +0x0000CDBC 0x5F81 # 0 +0x0000CDBD 0x5F7F # 0 +0x0000CDBE 0x5F7C # 0 +0x0000CDBF 0x5FDD # 0 +0x0000CDC0 0x5FE0 # 0 +0x0000CDC1 0x5FFD # 0 +0x0000CDC2 0x5FF5 # 0 +0x0000CDC3 0x5FFF # 0 +0x0000CDC4 0x600F # 0 +0x0000CDC5 0x6014 # 0 +0x0000CDC6 0x602F # 0 +0x0000CDC7 0x6035 # 0 +0x0000CDC8 0x6016 # 0 +0x0000CDC9 0x602A # 0 +0x0000CDCA 0x6015 # 0 +0x0000CDCB 0x6021 # 0 +0x0000CDCC 0x6027 # 0 +0x0000CDCD 0x6029 # 0 +0x0000CDCE 0x602B # 0 +0x0000CDCF 0x601B # 0 +0x0000CDD0 0x6216 # 0 +0x0000CDD1 0x6215 # 0 +0x0000CDD2 0x623F # 0 +0x0000CDD3 0x623E # 0 +0x0000CDD4 0x6240 # 0 +0x0000CDD5 0x627F # 0 +0x0000CDD6 0x62C9 # 0 +0x0000CDD7 0x62CC # 0 +0x0000CDD8 0x62C4 # 0 +0x0000CDD9 0x62BF # 0 +0x0000CDDA 0x62C2 # 0 +0x0000CDDB 0x62B9 # 0 +0x0000CDDC 0x62D2 # 0 +0x0000CDDD 0x62DB # 0 +0x0000CDDE 0x62AB # 0 +0x0000CDDF 0x62D3 # 0 +0x0000CDE0 0x62D4 # 0 +0x0000CDE1 0x62CB # 0 +0x0000CDE2 0x62C8 # 0 +0x0000CDE3 0x62A8 # 0 +0x0000CDE4 0x62BD # 0 +0x0000CDE5 0x62BC # 0 +0x0000CDE6 0x62D0 # 0 +0x0000CDE7 0x62D9 # 0 +0x0000CDE8 0x62C7 # 0 +0x0000CDE9 0x62CD # 0 +0x0000CDEA 0x62B5 # 0 +0x0000CDEB 0x62DA # 0 +0x0000CDEC 0x62B1 # 0 +0x0000CDED 0x62D8 # 0 +0x0000CDEE 0x62D6 # 0 +0x0000CDEF 0x62D7 # 0 +0x0000CDF0 0x62C6 # 0 +0x0000CDF1 0x62AC # 0 +0x0000CDF2 0x62CE # 0 +0x0000CDF3 0x653E # 0 +0x0000CDF4 0x65A7 # 0 +0x0000CDF5 0x65BC # 0 +0x0000CDF6 0x65FA # 0 +0x0000CDF7 0x6614 # 0 +0x0000CDF8 0x6613 # 0 +0x0000CDF9 0x660C # 0 +0x0000CDFA 0x6606 # 0 +0x0000CDFB 0x6602 # 0 +0x0000CDFC 0x660E # 0 +0x0000CDFD 0x6600 # 0 +0x0000CDFE 0x660F # 0 +0x0000CEA1 0x6615 # 0 +0x0000CEA2 0x660A # 0 +0x0000CEA3 0x6607 # 0 +0x0000CEA4 0x670D # 0 +0x0000CEA5 0x670B # 0 +0x0000CEA6 0x676D # 0 +0x0000CEA7 0x678B # 0 +0x0000CEA8 0x6795 # 0 +0x0000CEA9 0x6771 # 0 +0x0000CEAA 0x679C # 0 +0x0000CEAB 0x6773 # 0 +0x0000CEAC 0x6777 # 0 +0x0000CEAD 0x6787 # 0 +0x0000CEAE 0x679D # 0 +0x0000CEAF 0x6797 # 0 +0x0000CEB0 0x676F # 0 +0x0000CEB1 0x6770 # 0 +0x0000CEB2 0x677F # 0 +0x0000CEB3 0x6789 # 0 +0x0000CEB4 0x677E # 0 +0x0000CEB5 0x6790 # 0 +0x0000CEB6 0x6775 # 0 +0x0000CEB7 0x679A # 0 +0x0000CEB8 0x6793 # 0 +0x0000CEB9 0x677C # 0 +0x0000CEBA 0x676A # 0 +0x0000CEBB 0x6772 # 0 +0x0000CEBC 0x6B23 # 0 +0x0000CEBD 0x6B66 # 0 +0x0000CEBE 0x6B67 # 0 +0x0000CEBF 0x6B7F # 0 +0x0000CEC0 0x6C13 # 0 +0x0000CEC1 0x6C1B # 0 +0x0000CEC2 0x6CE3 # 0 +0x0000CEC3 0x6CE8 # 0 +0x0000CEC4 0x6CF3 # 0 +0x0000CEC5 0x6CB1 # 0 +0x0000CEC6 0x6CCC # 0 +0x0000CEC7 0x6CE5 # 0 +0x0000CEC8 0x6CB3 # 0 +0x0000CEC9 0x6CBD # 0 +0x0000CECA 0x6CBE # 0 +0x0000CECB 0x6CBC # 0 +0x0000CECC 0x6CE2 # 0 +0x0000CECD 0x6CAB # 0 +0x0000CECE 0x6CD5 # 0 +0x0000CECF 0x6CD3 # 0 +0x0000CED0 0x6CB8 # 0 +0x0000CED1 0x6CC4 # 0 +0x0000CED2 0x6CB9 # 0 +0x0000CED3 0x6CC1 # 0 +0x0000CED4 0x6CAE # 0 +0x0000CED5 0x6CD7 # 0 +0x0000CED6 0x6CC5 # 0 +0x0000CED7 0x6CF1 # 0 +0x0000CED8 0x6CBF # 0 +0x0000CED9 0x6CBB # 0 +0x0000CEDA 0x6CE1 # 0 +0x0000CEDB 0x6CDB # 0 +0x0000CEDC 0x6CCA # 0 +0x0000CEDD 0x6CAC # 0 +0x0000CEDE 0x6CEF # 0 +0x0000CEDF 0x6CDC # 0 +0x0000CEE0 0x6CD6 # 0 +0x0000CEE1 0x6CE0 # 0 +0x0000CEE2 0x7095 # 0 +0x0000CEE3 0x708E # 0 +0x0000CEE4 0x7092 # 0 +0x0000CEE5 0x708A # 0 +0x0000CEE6 0x7099 # 0 +0x0000CEE7 0x722C # 0 +0x0000CEE8 0x722D # 0 +0x0000CEE9 0x7238 # 0 +0x0000CEEA 0x7248 # 0 +0x0000CEEB 0x7267 # 0 +0x0000CEEC 0x7269 # 0 +0x0000CEED 0x72C0 # 0 +0x0000CEEE 0x72CE # 0 +0x0000CEEF 0x72D9 # 0 +0x0000CEF0 0x72D7 # 0 +0x0000CEF1 0x72D0 # 0 +0x0000CEF2 0x73A9 # 0 +0x0000CEF3 0x73A8 # 0 +0x0000CEF4 0x739F # 0 +0x0000CEF5 0x73AB # 0 +0x0000CEF6 0x73A5 # 0 +0x0000CEF7 0x753D # 0 +0x0000CEF8 0x759D # 0 +0x0000CEF9 0x7599 # 0 +0x0000CEFA 0x759A # 0 +0x0000CEFB 0x7684 # 0 +0x0000CEFC 0x76C2 # 0 +0x0000CEFD 0x76F2 # 0 +0x0000CEFE 0x76F4 # 0 +0x0000CFA1 0x77E5 # 0 +0x0000CFA2 0x77FD # 0 +0x0000CFA3 0x793E # 0 +0x0000CFA4 0x7940 # 0 +0x0000CFA5 0x7941 # 0 +0x0000CFA6 0x79C9 # 0 +0x0000CFA7 0x79C8 # 0 +0x0000CFA8 0x7A7A # 0 +0x0000CFA9 0x7A79 # 0 +0x0000CFAA 0x7AFA # 0 +0x0000CFAB 0x7CFE # 0 +0x0000CFAC 0x7F54 # 0 +0x0000CFAD 0x7F8C # 0 +0x0000CFAE 0x7F8B # 0 +0x0000CFAF 0x8005 # 0 +0x0000CFB0 0x80BA # 0 +0x0000CFB1 0x80A5 # 0 +0x0000CFB2 0x80A2 # 0 +0x0000CFB3 0x80B1 # 0 +0x0000CFB4 0x80A1 # 0 +0x0000CFB5 0x80AB # 0 +0x0000CFB6 0x80A9 # 0 +0x0000CFB7 0x80B4 # 0 +0x0000CFB8 0x80AA # 0 +0x0000CFB9 0x80AF # 0 +0x0000CFBA 0x81E5 # 0 +0x0000CFBB 0x81FE # 0 +0x0000CFBC 0x820D # 0 +0x0000CFBD 0x82B3 # 0 +0x0000CFBE 0x829D # 0 +0x0000CFBF 0x8299 # 0 +0x0000CFC0 0x82AD # 0 +0x0000CFC1 0x82BD # 0 +0x0000CFC2 0x829F # 0 +0x0000CFC3 0x82B9 # 0 +0x0000CFC4 0x82B1 # 0 +0x0000CFC5 0x82AC # 0 +0x0000CFC6 0x82A5 # 0 +0x0000CFC7 0x82AF # 0 +0x0000CFC8 0x82B8 # 0 +0x0000CFC9 0x82A3 # 0 +0x0000CFCA 0x82B0 # 0 +0x0000CFCB 0x82BE # 0 +0x0000CFCC 0x82B7 # 0 +0x0000CFCD 0x864E # 0 +0x0000CFCE 0x8671 # 0 +0x0000CFCF 0x521D # 0 +0x0000CFD0 0x8868 # 0 +0x0000CFD1 0x8ECB # 0 +0x0000CFD2 0x8FCE # 0 +0x0000CFD3 0x8FD4 # 0 +0x0000CFD4 0x8FD1 # 0 +0x0000CFD5 0x90B5 # 0 +0x0000CFD6 0x90B8 # 0 +0x0000CFD7 0x90B1 # 0 +0x0000CFD8 0x90B6 # 0 +0x0000CFD9 0x91C7 # 0 +0x0000CFDA 0x91D1 # 0 +0x0000CFDB 0x9577 # 0 +0x0000CFDC 0x9580 # 0 +0x0000CFDD 0x961C # 0 +0x0000CFDE 0x9640 # 0 +0x0000CFDF 0x963F # 0 +0x0000CFE0 0x963B # 0 +0x0000CFE1 0x9644 # 0 +0x0000CFE2 0x9642 # 0 +0x0000CFE3 0x96B9 # 0 +0x0000CFE4 0x96E8 # 0 +0x0000CFE5 0x9752 # 0 +0x0000CFE6 0x975E # 0 +0x0000CFE7 0x4E9F # 0 +0x0000CFE8 0x4EAD # 0 +0x0000CFE9 0x4EAE # 0 +0x0000CFEA 0x4FE1 # 0 +0x0000CFEB 0x4FB5 # 0 +0x0000CFEC 0x4FAF # 0 +0x0000CFED 0x4FBF # 0 +0x0000CFEE 0x4FE0 # 0 +0x0000CFEF 0x4FD1 # 0 +0x0000CFF0 0x4FCF # 0 +0x0000CFF1 0x4FDD # 0 +0x0000CFF2 0x4FC3 # 0 +0x0000CFF3 0x4FB6 # 0 +0x0000CFF4 0x4FD8 # 0 +0x0000CFF5 0x4FDF # 0 +0x0000CFF6 0x4FCA # 0 +0x0000CFF7 0x4FD7 # 0 +0x0000CFF8 0x4FAE # 0 +0x0000CFF9 0x4FD0 # 0 +0x0000CFFA 0x4FC4 # 0 +0x0000CFFB 0x4FC2 # 0 +0x0000CFFC 0x4FDA # 0 +0x0000CFFD 0x4FCE # 0 +0x0000CFFE 0x4FDE # 0 +0x0000D0A1 0x4FB7 # 0 +0x0000D0A2 0x5157 # 0 +0x0000D0A3 0x5192 # 0 +0x0000D0A4 0x5191 # 0 +0x0000D0A5 0x51A0 # 0 +0x0000D0A6 0x524E # 0 +0x0000D0A7 0x5243 # 0 +0x0000D0A8 0x524A # 0 +0x0000D0A9 0x524D # 0 +0x0000D0AA 0x524C # 0 +0x0000D0AB 0x524B # 0 +0x0000D0AC 0x5247 # 0 +0x0000D0AD 0x52C7 # 0 +0x0000D0AE 0x52C9 # 0 +0x0000D0AF 0x52C3 # 0 +0x0000D0B0 0x52C1 # 0 +0x0000D0B1 0x530D # 0 +0x0000D0B2 0x5357 # 0 +0x0000D0B3 0x537B # 0 +0x0000D0B4 0x539A # 0 +0x0000D0B5 0x53DB # 0 +0x0000D0B6 0x54AC # 0 +0x0000D0B7 0x54C0 # 0 +0x0000D0B8 0x54A8 # 0 +0x0000D0B9 0x54CE # 0 +0x0000D0BA 0x54C9 # 0 +0x0000D0BB 0x54B8 # 0 +0x0000D0BC 0x54A6 # 0 +0x0000D0BD 0x54B3 # 0 +0x0000D0BE 0x54C7 # 0 +0x0000D0BF 0x54C2 # 0 +0x0000D0C0 0x54BD # 0 +0x0000D0C1 0x54AA # 0 +0x0000D0C2 0x54C1 # 0 +0x0000D0C3 0x54C4 # 0 +0x0000D0C4 0x54C8 # 0 +0x0000D0C5 0x54AF # 0 +0x0000D0C6 0x54AB # 0 +0x0000D0C7 0x54B1 # 0 +0x0000D0C8 0x54BB # 0 +0x0000D0C9 0x54A9 # 0 +0x0000D0CA 0x54A7 # 0 +0x0000D0CB 0x54BF # 0 +0x0000D0CC 0x56FF # 0 +0x0000D0CD 0x5782 # 0 +0x0000D0CE 0x578B # 0 +0x0000D0CF 0x57A0 # 0 +0x0000D0D0 0x57A3 # 0 +0x0000D0D1 0x57A2 # 0 +0x0000D0D2 0x57CE # 0 +0x0000D0D3 0x57AE # 0 +0x0000D0D4 0x5793 # 0 +0x0000D0D5 0x5955 # 0 +0x0000D0D6 0x5951 # 0 +0x0000D0D7 0x594F # 0 +0x0000D0D8 0x594E # 0 +0x0000D0D9 0x5950 # 0 +0x0000D0DA 0x59DC # 0 +0x0000D0DB 0x59D8 # 0 +0x0000D0DC 0x59FF # 0 +0x0000D0DD 0x59E3 # 0 +0x0000D0DE 0x59E8 # 0 +0x0000D0DF 0x5A03 # 0 +0x0000D0E0 0x59E5 # 0 +0x0000D0E1 0x59EA # 0 +0x0000D0E2 0x59DA # 0 +0x0000D0E3 0x59E6 # 0 +0x0000D0E4 0x5A01 # 0 +0x0000D0E5 0x59FB # 0 +0x0000D0E6 0x5B69 # 0 +0x0000D0E7 0x5BA3 # 0 +0x0000D0E8 0x5BA6 # 0 +0x0000D0E9 0x5BA4 # 0 +0x0000D0EA 0x5BA2 # 0 +0x0000D0EB 0x5BA5 # 0 +0x0000D0EC 0x5C01 # 0 +0x0000D0ED 0x5C4E # 0 +0x0000D0EE 0x5C4F # 0 +0x0000D0EF 0x5C4D # 0 +0x0000D0F0 0x5C4B # 0 +0x0000D0F1 0x5CD9 # 0 +0x0000D0F2 0x5CD2 # 0 +0x0000D0F3 0x5DF7 # 0 +0x0000D0F4 0x5E1D # 0 +0x0000D0F5 0x5E25 # 0 +0x0000D0F6 0x5E1F # 0 +0x0000D0F7 0x5E7D # 0 +0x0000D0F8 0x5EA0 # 0 +0x0000D0F9 0x5EA6 # 0 +0x0000D0FA 0x5EFA # 0 +0x0000D0FB 0x5F08 # 0 +0x0000D0FC 0x5F2D # 0 +0x0000D0FD 0x5F65 # 0 +0x0000D0FE 0x5F88 # 0 +0x0000D1A1 0x5F85 # 0 +0x0000D1A2 0x5F8A # 0 +0x0000D1A3 0x5F8B # 0 +0x0000D1A4 0x5F87 # 0 +0x0000D1A5 0x5F8C # 0 +0x0000D1A6 0x5F89 # 0 +0x0000D1A7 0x6012 # 0 +0x0000D1A8 0x601D # 0 +0x0000D1A9 0x6020 # 0 +0x0000D1AA 0x6025 # 0 +0x0000D1AB 0x600E # 0 +0x0000D1AC 0x6028 # 0 +0x0000D1AD 0x604D # 0 +0x0000D1AE 0x6070 # 0 +0x0000D1AF 0x6068 # 0 +0x0000D1B0 0x6062 # 0 +0x0000D1B1 0x6046 # 0 +0x0000D1B2 0x6043 # 0 +0x0000D1B3 0x606C # 0 +0x0000D1B4 0x606B # 0 +0x0000D1B5 0x606A # 0 +0x0000D1B6 0x6064 # 0 +0x0000D1B7 0x6241 # 0 +0x0000D1B8 0x62DC # 0 +0x0000D1B9 0x6316 # 0 +0x0000D1BA 0x6309 # 0 +0x0000D1BB 0x62FC # 0 +0x0000D1BC 0x62ED # 0 +0x0000D1BD 0x6301 # 0 +0x0000D1BE 0x62EE # 0 +0x0000D1BF 0x62FD # 0 +0x0000D1C0 0x6307 # 0 +0x0000D1C1 0x62F1 # 0 +0x0000D1C2 0x62F7 # 0 +0x0000D1C3 0x62EF # 0 +0x0000D1C4 0x62EC # 0 +0x0000D1C5 0x62FE # 0 +0x0000D1C6 0x62F4 # 0 +0x0000D1C7 0x6311 # 0 +0x0000D1C8 0x6302 # 0 +0x0000D1C9 0x653F # 0 +0x0000D1CA 0x6545 # 0 +0x0000D1CB 0x65AB # 0 +0x0000D1CC 0x65BD # 0 +0x0000D1CD 0x65E2 # 0 +0x0000D1CE 0x6625 # 0 +0x0000D1CF 0x662D # 0 +0x0000D1D0 0x6620 # 0 +0x0000D1D1 0x6627 # 0 +0x0000D1D2 0x662F # 0 +0x0000D1D3 0x661F # 0 +0x0000D1D4 0x6628 # 0 +0x0000D1D5 0x6631 # 0 +0x0000D1D6 0x6624 # 0 +0x0000D1D7 0x66F7 # 0 +0x0000D1D8 0x67FF # 0 +0x0000D1D9 0x67D3 # 0 +0x0000D1DA 0x67F1 # 0 +0x0000D1DB 0x67D4 # 0 +0x0000D1DC 0x67D0 # 0 +0x0000D1DD 0x67EC # 0 +0x0000D1DE 0x67B6 # 0 +0x0000D1DF 0x67AF # 0 +0x0000D1E0 0x67F5 # 0 +0x0000D1E1 0x67E9 # 0 +0x0000D1E2 0x67EF # 0 +0x0000D1E3 0x67C4 # 0 +0x0000D1E4 0x67D1 # 0 +0x0000D1E5 0x67B4 # 0 +0x0000D1E6 0x67DA # 0 +0x0000D1E7 0x67E5 # 0 +0x0000D1E8 0x67B8 # 0 +0x0000D1E9 0x67CF # 0 +0x0000D1EA 0x67DE # 0 +0x0000D1EB 0x67F3 # 0 +0x0000D1EC 0x67B0 # 0 +0x0000D1ED 0x67D9 # 0 +0x0000D1EE 0x67E2 # 0 +0x0000D1EF 0x67DD # 0 +0x0000D1F0 0x67D2 # 0 +0x0000D1F1 0x6B6A # 0 +0x0000D1F2 0x6B83 # 0 +0x0000D1F3 0x6B86 # 0 +0x0000D1F4 0x6BB5 # 0 +0x0000D1F5 0x6BD2 # 0 +0x0000D1F6 0x6BD7 # 0 +0x0000D1F7 0x6C1F # 0 +0x0000D1F8 0x6CC9 # 0 +0x0000D1F9 0x6D0B # 0 +0x0000D1FA 0x6D32 # 0 +0x0000D1FB 0x6D2A # 0 +0x0000D1FC 0x6D41 # 0 +0x0000D1FD 0x6D25 # 0 +0x0000D1FE 0x6D0C # 0 +0x0000D2A1 0x6D31 # 0 +0x0000D2A2 0x6D1E # 0 +0x0000D2A3 0x6D17 # 0 +0x0000D2A4 0x6D3B # 0 +0x0000D2A5 0x6D3D # 0 +0x0000D2A6 0x6D3E # 0 +0x0000D2A7 0x6D36 # 0 +0x0000D2A8 0x6D1B # 0 +0x0000D2A9 0x6CF5 # 0 +0x0000D2AA 0x6D39 # 0 +0x0000D2AB 0x6D27 # 0 +0x0000D2AC 0x6D38 # 0 +0x0000D2AD 0x6D29 # 0 +0x0000D2AE 0x6D2E # 0 +0x0000D2AF 0x6D35 # 0 +0x0000D2B0 0x6D0E # 0 +0x0000D2B1 0x6D2B # 0 +0x0000D2B2 0x70AB # 0 +0x0000D2B3 0x70BA # 0 +0x0000D2B4 0x70B3 # 0 +0x0000D2B5 0x70AC # 0 +0x0000D2B6 0x70AF # 0 +0x0000D2B7 0x70AD # 0 +0x0000D2B8 0x70B8 # 0 +0x0000D2B9 0x70AE # 0 +0x0000D2BA 0x70A4 # 0 +0x0000D2BB 0x7230 # 0 +0x0000D2BC 0x7272 # 0 +0x0000D2BD 0x726F # 0 +0x0000D2BE 0x7274 # 0 +0x0000D2BF 0x72E9 # 0 +0x0000D2C0 0x72E0 # 0 +0x0000D2C1 0x72E1 # 0 +0x0000D2C2 0x73B7 # 0 +0x0000D2C3 0x73CA # 0 +0x0000D2C4 0x73BB # 0 +0x0000D2C5 0x73B2 # 0 +0x0000D2C6 0x73CD # 0 +0x0000D2C7 0x73C0 # 0 +0x0000D2C8 0x73B3 # 0 +0x0000D2C9 0x751A # 0 +0x0000D2CA 0x752D # 0 +0x0000D2CB 0x754F # 0 +0x0000D2CC 0x754C # 0 +0x0000D2CD 0x754E # 0 +0x0000D2CE 0x754B # 0 +0x0000D2CF 0x75AB # 0 +0x0000D2D0 0x75A4 # 0 +0x0000D2D1 0x75A5 # 0 +0x0000D2D2 0x75A2 # 0 +0x0000D2D3 0x75A3 # 0 +0x0000D2D4 0x7678 # 0 +0x0000D2D5 0x7686 # 0 +0x0000D2D6 0x7687 # 0 +0x0000D2D7 0x7688 # 0 +0x0000D2D8 0x76C8 # 0 +0x0000D2D9 0x76C6 # 0 +0x0000D2DA 0x76C3 # 0 +0x0000D2DB 0x76C5 # 0 +0x0000D2DC 0x7701 # 0 +0x0000D2DD 0x76F9 # 0 +0x0000D2DE 0x76F8 # 0 +0x0000D2DF 0x7709 # 0 +0x0000D2E0 0x770B # 0 +0x0000D2E1 0x76FE # 0 +0x0000D2E2 0x76FC # 0 +0x0000D2E3 0x7707 # 0 +0x0000D2E4 0x77DC # 0 +0x0000D2E5 0x7802 # 0 +0x0000D2E6 0x7814 # 0 +0x0000D2E7 0x780C # 0 +0x0000D2E8 0x780D # 0 +0x0000D2E9 0x7946 # 0 +0x0000D2EA 0x7949 # 0 +0x0000D2EB 0x7948 # 0 +0x0000D2EC 0x7947 # 0 +0x0000D2ED 0x79B9 # 0 +0x0000D2EE 0x79BA # 0 +0x0000D2EF 0x79D1 # 0 +0x0000D2F0 0x79D2 # 0 +0x0000D2F1 0x79CB # 0 +0x0000D2F2 0x7A7F # 0 +0x0000D2F3 0x7A81 # 0 +0x0000D2F4 0x7AFF # 0 +0x0000D2F5 0x7AFD # 0 +0x0000D2F6 0x7C7D # 0 +0x0000D2F7 0x7D02 # 0 +0x0000D2F8 0x7D05 # 0 +0x0000D2F9 0x7D00 # 0 +0x0000D2FA 0x7D09 # 0 +0x0000D2FB 0x7D07 # 0 +0x0000D2FC 0x7D04 # 0 +0x0000D2FD 0x7D06 # 0 +0x0000D2FE 0x7F38 # 0 +0x0000D3A1 0x7F8E # 0 +0x0000D3A2 0x7FBF # 0 +0x0000D3A3 0x8010 # 0 +0x0000D3A4 0x800D # 0 +0x0000D3A5 0x8011 # 0 +0x0000D3A6 0x8036 # 0 +0x0000D3A7 0x80D6 # 0 +0x0000D3A8 0x80E5 # 0 +0x0000D3A9 0x80DA # 0 +0x0000D3AA 0x80C3 # 0 +0x0000D3AB 0x80C4 # 0 +0x0000D3AC 0x80CC # 0 +0x0000D3AD 0x80E1 # 0 +0x0000D3AE 0x80DB # 0 +0x0000D3AF 0x80CE # 0 +0x0000D3B0 0x80DE # 0 +0x0000D3B1 0x80E4 # 0 +0x0000D3B2 0x80DD # 0 +0x0000D3B3 0x81F4 # 0 +0x0000D3B4 0x8222 # 0 +0x0000D3B5 0x82E7 # 0 +0x0000D3B6 0x8303 # 0 +0x0000D3B7 0x8305 # 0 +0x0000D3B8 0x82E3 # 0 +0x0000D3B9 0x82DB # 0 +0x0000D3BA 0x82E6 # 0 +0x0000D3BB 0x8304 # 0 +0x0000D3BC 0x82E5 # 0 +0x0000D3BD 0x8302 # 0 +0x0000D3BE 0x8309 # 0 +0x0000D3BF 0x82D2 # 0 +0x0000D3C0 0x82D7 # 0 +0x0000D3C1 0x82F1 # 0 +0x0000D3C2 0x8301 # 0 +0x0000D3C3 0x82DC # 0 +0x0000D3C4 0x82D4 # 0 +0x0000D3C5 0x82D1 # 0 +0x0000D3C6 0x82DE # 0 +0x0000D3C7 0x82D3 # 0 +0x0000D3C8 0x82DF # 0 +0x0000D3C9 0x82EF # 0 +0x0000D3CA 0x8306 # 0 +0x0000D3CB 0x8650 # 0 +0x0000D3CC 0x8679 # 0 +0x0000D3CD 0x867B # 0 +0x0000D3CE 0x867A # 0 +0x0000D3CF 0x884D # 0 +0x0000D3D0 0x886B # 0 +0x0000D3D1 0x8981 # 0 +0x0000D3D2 0x89D4 # 0 +0x0000D3D3 0x8A08 # 0 +0x0000D3D4 0x8A02 # 0 +0x0000D3D5 0x8A03 # 0 +0x0000D3D6 0x8C9E # 0 +0x0000D3D7 0x8CA0 # 0 +0x0000D3D8 0x8D74 # 0 +0x0000D3D9 0x8D73 # 0 +0x0000D3DA 0x8DB4 # 0 +0x0000D3DB 0x8ECD # 0 +0x0000D3DC 0x8ECC # 0 +0x0000D3DD 0x8FF0 # 0 +0x0000D3DE 0x8FE6 # 0 +0x0000D3DF 0x8FE2 # 0 +0x0000D3E0 0x8FEA # 0 +0x0000D3E1 0x8FE5 # 0 +0x0000D3E2 0x8FED # 0 +0x0000D3E3 0x8FEB # 0 +0x0000D3E4 0x8FE4 # 0 +0x0000D3E5 0x8FE8 # 0 +0x0000D3E6 0x90CA # 0 +0x0000D3E7 0x90CE # 0 +0x0000D3E8 0x90C1 # 0 +0x0000D3E9 0x90C3 # 0 +0x0000D3EA 0x914B # 0 +0x0000D3EB 0x914A # 0 +0x0000D3EC 0x91CD # 0 +0x0000D3ED 0x9582 # 0 +0x0000D3EE 0x9650 # 0 +0x0000D3EF 0x964B # 0 +0x0000D3F0 0x964C # 0 +0x0000D3F1 0x964D # 0 +0x0000D3F2 0x9762 # 0 +0x0000D3F3 0x9769 # 0 +0x0000D3F4 0x97CB # 0 +0x0000D3F5 0x97ED # 0 +0x0000D3F6 0x97F3 # 0 +0x0000D3F7 0x9801 # 0 +0x0000D3F8 0x98A8 # 0 +0x0000D3F9 0x98DB # 0 +0x0000D3FA 0x98DF # 0 +0x0000D3FB 0x9996 # 0 +0x0000D3FC 0x9999 # 0 +0x0000D3FD 0x4E58 # 0 +0x0000D3FE 0x4EB3 # 0 +0x0000D4A1 0x500C # 0 +0x0000D4A2 0x500D # 0 +0x0000D4A3 0x5023 # 0 +0x0000D4A4 0x4FEF # 0 +0x0000D4A5 0x5026 # 0 +0x0000D4A6 0x5025 # 0 +0x0000D4A7 0x4FF8 # 0 +0x0000D4A8 0x5029 # 0 +0x0000D4A9 0x5016 # 0 +0x0000D4AA 0x5006 # 0 +0x0000D4AB 0x503C # 0 +0x0000D4AC 0x501F # 0 +0x0000D4AD 0x501A # 0 +0x0000D4AE 0x5012 # 0 +0x0000D4AF 0x5011 # 0 +0x0000D4B0 0x4FFA # 0 +0x0000D4B1 0x5000 # 0 +0x0000D4B2 0x5014 # 0 +0x0000D4B3 0x5028 # 0 +0x0000D4B4 0x4FF1 # 0 +0x0000D4B5 0x5021 # 0 +0x0000D4B6 0x500B # 0 +0x0000D4B7 0x5019 # 0 +0x0000D4B8 0x5018 # 0 +0x0000D4B9 0x4FF3 # 0 +0x0000D4BA 0x4FEE # 0 +0x0000D4BB 0x502D # 0 +0x0000D4BC 0x502A # 0 +0x0000D4BD 0x4FFE # 0 +0x0000D4BE 0x502B # 0 +0x0000D4BF 0x5009 # 0 +0x0000D4C0 0x517C # 0 +0x0000D4C1 0x51A4 # 0 +0x0000D4C2 0x51A5 # 0 +0x0000D4C3 0x51A2 # 0 +0x0000D4C4 0x51CD # 0 +0x0000D4C5 0x51CC # 0 +0x0000D4C6 0x51C6 # 0 +0x0000D4C7 0x51CB # 0 +0x0000D4C8 0x5256 # 0 +0x0000D4C9 0x525C # 0 +0x0000D4CA 0x5254 # 0 +0x0000D4CB 0x525B # 0 +0x0000D4CC 0x525D # 0 +0x0000D4CD 0x532A # 0 +0x0000D4CE 0x537F # 0 +0x0000D4CF 0x539F # 0 +0x0000D4D0 0x539D # 0 +0x0000D4D1 0x53DF # 0 +0x0000D4D2 0x54E8 # 0 +0x0000D4D3 0x5510 # 0 +0x0000D4D4 0x5501 # 0 +0x0000D4D5 0x5537 # 0 +0x0000D4D6 0x54FC # 0 +0x0000D4D7 0x54E5 # 0 +0x0000D4D8 0x54F2 # 0 +0x0000D4D9 0x5506 # 0 +0x0000D4DA 0x54FA # 0 +0x0000D4DB 0x5514 # 0 +0x0000D4DC 0x54E9 # 0 +0x0000D4DD 0x54ED # 0 +0x0000D4DE 0x54E1 # 0 +0x0000D4DF 0x5509 # 0 +0x0000D4E0 0x54EE # 0 +0x0000D4E1 0x54EA # 0 +0x0000D4E2 0x54E6 # 0 +0x0000D4E3 0x5527 # 0 +0x0000D4E4 0x5507 # 0 +0x0000D4E5 0x54FD # 0 +0x0000D4E6 0x550F # 0 +0x0000D4E7 0x5703 # 0 +0x0000D4E8 0x5704 # 0 +0x0000D4E9 0x57C2 # 0 +0x0000D4EA 0x57D4 # 0 +0x0000D4EB 0x57CB # 0 +0x0000D4EC 0x57C3 # 0 +0x0000D4ED 0x5809 # 0 +0x0000D4EE 0x590F # 0 +0x0000D4EF 0x5957 # 0 +0x0000D4F0 0x5958 # 0 +0x0000D4F1 0x595A # 0 +0x0000D4F2 0x5A11 # 0 +0x0000D4F3 0x5A18 # 0 +0x0000D4F4 0x5A1C # 0 +0x0000D4F5 0x5A1F # 0 +0x0000D4F6 0x5A1B # 0 +0x0000D4F7 0x5A13 # 0 +0x0000D4F8 0x59EC # 0 +0x0000D4F9 0x5A20 # 0 +0x0000D4FA 0x5A23 # 0 +0x0000D4FB 0x5A29 # 0 +0x0000D4FC 0x5A25 # 0 +0x0000D4FD 0x5A0C # 0 +0x0000D4FE 0x5A09 # 0 +0x0000D5A1 0x5B6B # 0 +0x0000D5A2 0x5C58 # 0 +0x0000D5A3 0x5BB0 # 0 +0x0000D5A4 0x5BB3 # 0 +0x0000D5A5 0x5BB6 # 0 +0x0000D5A6 0x5BB4 # 0 +0x0000D5A7 0x5BAE # 0 +0x0000D5A8 0x5BB5 # 0 +0x0000D5A9 0x5BB9 # 0 +0x0000D5AA 0x5BB8 # 0 +0x0000D5AB 0x5C04 # 0 +0x0000D5AC 0x5C51 # 0 +0x0000D5AD 0x5C55 # 0 +0x0000D5AE 0x5C50 # 0 +0x0000D5AF 0x5CED # 0 +0x0000D5B0 0x5CFD # 0 +0x0000D5B1 0x5CFB # 0 +0x0000D5B2 0x5CEA # 0 +0x0000D5B3 0x5CE8 # 0 +0x0000D5B4 0x5CF0 # 0 +0x0000D5B5 0x5CF6 # 0 +0x0000D5B6 0x5D01 # 0 +0x0000D5B7 0x5CF4 # 0 +0x0000D5B8 0x5DEE # 0 +0x0000D5B9 0x5E2D # 0 +0x0000D5BA 0x5E2B # 0 +0x0000D5BB 0x5EAB # 0 +0x0000D5BC 0x5EAD # 0 +0x0000D5BD 0x5EA7 # 0 +0x0000D5BE 0x5F31 # 0 +0x0000D5BF 0x5F92 # 0 +0x0000D5C0 0x5F91 # 0 +0x0000D5C1 0x5F90 # 0 +0x0000D5C2 0x6059 # 0 +0x0000D5C3 0x6063 # 0 +0x0000D5C4 0x6065 # 0 +0x0000D5C5 0x6050 # 0 +0x0000D5C6 0x6055 # 0 +0x0000D5C7 0x606D # 0 +0x0000D5C8 0x6069 # 0 +0x0000D5C9 0x606F # 0 +0x0000D5CA 0x6084 # 0 +0x0000D5CB 0x609F # 0 +0x0000D5CC 0x609A # 0 +0x0000D5CD 0x608D # 0 +0x0000D5CE 0x6094 # 0 +0x0000D5CF 0x608C # 0 +0x0000D5D0 0x6085 # 0 +0x0000D5D1 0x6096 # 0 +0x0000D5D2 0x6247 # 0 +0x0000D5D3 0x62F3 # 0 +0x0000D5D4 0x6308 # 0 +0x0000D5D5 0x62FF # 0 +0x0000D5D6 0x634E # 0 +0x0000D5D7 0x633E # 0 +0x0000D5D8 0x632F # 0 +0x0000D5D9 0x6355 # 0 +0x0000D5DA 0x6342 # 0 +0x0000D5DB 0x6346 # 0 +0x0000D5DC 0x634F # 0 +0x0000D5DD 0x6349 # 0 +0x0000D5DE 0x633A # 0 +0x0000D5DF 0x6350 # 0 +0x0000D5E0 0x633D # 0 +0x0000D5E1 0x632A # 0 +0x0000D5E2 0x632B # 0 +0x0000D5E3 0x6328 # 0 +0x0000D5E4 0x634D # 0 +0x0000D5E5 0x634C # 0 +0x0000D5E6 0x6548 # 0 +0x0000D5E7 0x6549 # 0 +0x0000D5E8 0x6599 # 0 +0x0000D5E9 0x65C1 # 0 +0x0000D5EA 0x65C5 # 0 +0x0000D5EB 0x6642 # 0 +0x0000D5EC 0x6649 # 0 +0x0000D5ED 0x664F # 0 +0x0000D5EE 0x6643 # 0 +0x0000D5EF 0x6652 # 0 +0x0000D5F0 0x664C # 0 +0x0000D5F1 0x6645 # 0 +0x0000D5F2 0x6641 # 0 +0x0000D5F3 0x66F8 # 0 +0x0000D5F4 0x6714 # 0 +0x0000D5F5 0x6715 # 0 +0x0000D5F6 0x6717 # 0 +0x0000D5F7 0x6821 # 0 +0x0000D5F8 0x6838 # 0 +0x0000D5F9 0x6848 # 0 +0x0000D5FA 0x6846 # 0 +0x0000D5FB 0x6853 # 0 +0x0000D5FC 0x6839 # 0 +0x0000D5FD 0x6842 # 0 +0x0000D5FE 0x6854 # 0 +0x0000D6A1 0x6829 # 0 +0x0000D6A2 0x68B3 # 0 +0x0000D6A3 0x6817 # 0 +0x0000D6A4 0x684C # 0 +0x0000D6A5 0x6851 # 0 +0x0000D6A6 0x683D # 0 +0x0000D6A7 0x67F4 # 0 +0x0000D6A8 0x6850 # 0 +0x0000D6A9 0x6840 # 0 +0x0000D6AA 0x683C # 0 +0x0000D6AB 0x6843 # 0 +0x0000D6AC 0x682A # 0 +0x0000D6AD 0x6845 # 0 +0x0000D6AE 0x6813 # 0 +0x0000D6AF 0x6818 # 0 +0x0000D6B0 0x6841 # 0 +0x0000D6B1 0x6B8A # 0 +0x0000D6B2 0x6B89 # 0 +0x0000D6B3 0x6BB7 # 0 +0x0000D6B4 0x6C23 # 0 +0x0000D6B5 0x6C27 # 0 +0x0000D6B6 0x6C28 # 0 +0x0000D6B7 0x6C26 # 0 +0x0000D6B8 0x6C24 # 0 +0x0000D6B9 0x6CF0 # 0 +0x0000D6BA 0x6D6A # 0 +0x0000D6BB 0x6D95 # 0 +0x0000D6BC 0x6D88 # 0 +0x0000D6BD 0x6D87 # 0 +0x0000D6BE 0x6D66 # 0 +0x0000D6BF 0x6D78 # 0 +0x0000D6C0 0x6D77 # 0 +0x0000D6C1 0x6D59 # 0 +0x0000D6C2 0x6D93 # 0 +0x0000D6C3 0x6D6C # 0 +0x0000D6C4 0x6D89 # 0 +0x0000D6C5 0x6D6E # 0 +0x0000D6C6 0x6D5A # 0 +0x0000D6C7 0x6D74 # 0 +0x0000D6C8 0x6D69 # 0 +0x0000D6C9 0x6D8C # 0 +0x0000D6CA 0x6D8A # 0 +0x0000D6CB 0x6D79 # 0 +0x0000D6CC 0x6D85 # 0 +0x0000D6CD 0x6D65 # 0 +0x0000D6CE 0x6D94 # 0 +0x0000D6CF 0x70CA # 0 +0x0000D6D0 0x70D8 # 0 +0x0000D6D1 0x70E4 # 0 +0x0000D6D2 0x70D9 # 0 +0x0000D6D3 0x70C8 # 0 +0x0000D6D4 0x70CF # 0 +0x0000D6D5 0x7239 # 0 +0x0000D6D6 0x7279 # 0 +0x0000D6D7 0x72FC # 0 +0x0000D6D8 0x72F9 # 0 +0x0000D6D9 0x72FD # 0 +0x0000D6DA 0x72F8 # 0 +0x0000D6DB 0x72F7 # 0 +0x0000D6DC 0x7386 # 0 +0x0000D6DD 0x73ED # 0 +0x0000D6DE 0x7409 # 0 +0x0000D6DF 0x73EE # 0 +0x0000D6E0 0x73E0 # 0 +0x0000D6E1 0x73EA # 0 +0x0000D6E2 0x73DE # 0 +0x0000D6E3 0x7554 # 0 +0x0000D6E4 0x755D # 0 +0x0000D6E5 0x755C # 0 +0x0000D6E6 0x755A # 0 +0x0000D6E7 0x7559 # 0 +0x0000D6E8 0x75BE # 0 +0x0000D6E9 0x75C5 # 0 +0x0000D6EA 0x75C7 # 0 +0x0000D6EB 0x75B2 # 0 +0x0000D6EC 0x75B3 # 0 +0x0000D6ED 0x75BD # 0 +0x0000D6EE 0x75BC # 0 +0x0000D6EF 0x75B9 # 0 +0x0000D6F0 0x75C2 # 0 +0x0000D6F1 0x75B8 # 0 +0x0000D6F2 0x768B # 0 +0x0000D6F3 0x76B0 # 0 +0x0000D6F4 0x76CA # 0 +0x0000D6F5 0x76CD # 0 +0x0000D6F6 0x76CE # 0 +0x0000D6F7 0x7729 # 0 +0x0000D6F8 0x771F # 0 +0x0000D6F9 0x7720 # 0 +0x0000D6FA 0x7728 # 0 +0x0000D6FB 0x77E9 # 0 +0x0000D6FC 0x7830 # 0 +0x0000D6FD 0x7827 # 0 +0x0000D6FE 0x7838 # 0 +0x0000D7A1 0x781D # 0 +0x0000D7A2 0x7834 # 0 +0x0000D7A3 0x7837 # 0 +0x0000D7A4 0x7825 # 0 +0x0000D7A5 0x782D # 0 +0x0000D7A6 0x7820 # 0 +0x0000D7A7 0x781F # 0 +0x0000D7A8 0x7832 # 0 +0x0000D7A9 0x7955 # 0 +0x0000D7AA 0x7950 # 0 +0x0000D7AB 0x7960 # 0 +0x0000D7AC 0x795F # 0 +0x0000D7AD 0x7956 # 0 +0x0000D7AE 0x795E # 0 +0x0000D7AF 0x795D # 0 +0x0000D7B0 0x7957 # 0 +0x0000D7B1 0x795A # 0 +0x0000D7B2 0x79E4 # 0 +0x0000D7B3 0x79E3 # 0 +0x0000D7B4 0x79E7 # 0 +0x0000D7B5 0x79DF # 0 +0x0000D7B6 0x79E6 # 0 +0x0000D7B7 0x79E9 # 0 +0x0000D7B8 0x79D8 # 0 +0x0000D7B9 0x7A84 # 0 +0x0000D7BA 0x7A88 # 0 +0x0000D7BB 0x7AD9 # 0 +0x0000D7BC 0x7B06 # 0 +0x0000D7BD 0x7B11 # 0 +0x0000D7BE 0x7C89 # 0 +0x0000D7BF 0x7D21 # 0 +0x0000D7C0 0x7D17 # 0 +0x0000D7C1 0x7D0B # 0 +0x0000D7C2 0x7D0A # 0 +0x0000D7C3 0x7D20 # 0 +0x0000D7C4 0x7D22 # 0 +0x0000D7C5 0x7D14 # 0 +0x0000D7C6 0x7D10 # 0 +0x0000D7C7 0x7D15 # 0 +0x0000D7C8 0x7D1A # 0 +0x0000D7C9 0x7D1C # 0 +0x0000D7CA 0x7D0D # 0 +0x0000D7CB 0x7D19 # 0 +0x0000D7CC 0x7D1B # 0 +0x0000D7CD 0x7F3A # 0 +0x0000D7CE 0x7F5F # 0 +0x0000D7CF 0x7F94 # 0 +0x0000D7D0 0x7FC5 # 0 +0x0000D7D1 0x7FC1 # 0 +0x0000D7D2 0x8006 # 0 +0x0000D7D3 0x8004 # 0 +0x0000D7D4 0x8018 # 0 +0x0000D7D5 0x8015 # 0 +0x0000D7D6 0x8019 # 0 +0x0000D7D7 0x8017 # 0 +0x0000D7D8 0x803D # 0 +0x0000D7D9 0x803F # 0 +0x0000D7DA 0x80F1 # 0 +0x0000D7DB 0x8102 # 0 +0x0000D7DC 0x80F0 # 0 +0x0000D7DD 0x8105 # 0 +0x0000D7DE 0x80ED # 0 +0x0000D7DF 0x80F4 # 0 +0x0000D7E0 0x8106 # 0 +0x0000D7E1 0x80F8 # 0 +0x0000D7E2 0x80F3 # 0 +0x0000D7E3 0x8108 # 0 +0x0000D7E4 0x80FD # 0 +0x0000D7E5 0x810A # 0 +0x0000D7E6 0x80FC # 0 +0x0000D7E7 0x80EF # 0 +0x0000D7E8 0x81ED # 0 +0x0000D7E9 0x81EC # 0 +0x0000D7EA 0x8200 # 0 +0x0000D7EB 0x8210 # 0 +0x0000D7EC 0x822A # 0 +0x0000D7ED 0x822B # 0 +0x0000D7EE 0x8228 # 0 +0x0000D7EF 0x822C # 0 +0x0000D7F0 0x82BB # 0 +0x0000D7F1 0x832B # 0 +0x0000D7F2 0x8352 # 0 +0x0000D7F3 0x8354 # 0 +0x0000D7F4 0x834A # 0 +0x0000D7F5 0x8338 # 0 +0x0000D7F6 0x8350 # 0 +0x0000D7F7 0x8349 # 0 +0x0000D7F8 0x8335 # 0 +0x0000D7F9 0x8334 # 0 +0x0000D7FA 0x834F # 0 +0x0000D7FB 0x8332 # 0 +0x0000D7FC 0x8339 # 0 +0x0000D7FD 0x8336 # 0 +0x0000D7FE 0x8317 # 0 +0x0000D8A1 0x8340 # 0 +0x0000D8A2 0x8331 # 0 +0x0000D8A3 0x8328 # 0 +0x0000D8A4 0x8343 # 0 +0x0000D8A5 0x8654 # 0 +0x0000D8A6 0x868A # 0 +0x0000D8A7 0x86AA # 0 +0x0000D8A8 0x8693 # 0 +0x0000D8A9 0x86A4 # 0 +0x0000D8AA 0x86A9 # 0 +0x0000D8AB 0x868C # 0 +0x0000D8AC 0x86A3 # 0 +0x0000D8AD 0x869C # 0 +0x0000D8AE 0x8870 # 0 +0x0000D8AF 0x8877 # 0 +0x0000D8B0 0x8881 # 0 +0x0000D8B1 0x8882 # 0 +0x0000D8B2 0x887D # 0 +0x0000D8B3 0x8879 # 0 +0x0000D8B4 0x8A18 # 0 +0x0000D8B5 0x8A10 # 0 +0x0000D8B6 0x8A0E # 0 +0x0000D8B7 0x8A0C # 0 +0x0000D8B8 0x8A15 # 0 +0x0000D8B9 0x8A0A # 0 +0x0000D8BA 0x8A17 # 0 +0x0000D8BB 0x8A13 # 0 +0x0000D8BC 0x8A16 # 0 +0x0000D8BD 0x8A0F # 0 +0x0000D8BE 0x8A11 # 0 +0x0000D8BF 0x8C48 # 0 +0x0000D8C0 0x8C7A # 0 +0x0000D8C1 0x8C79 # 0 +0x0000D8C2 0x8CA1 # 0 +0x0000D8C3 0x8CA2 # 0 +0x0000D8C4 0x8D77 # 0 +0x0000D8C5 0x8EAC # 0 +0x0000D8C6 0x8ED2 # 0 +0x0000D8C7 0x8ED4 # 0 +0x0000D8C8 0x8ECF # 0 +0x0000D8C9 0x8FB1 # 0 +0x0000D8CA 0x9001 # 0 +0x0000D8CB 0x9006 # 0 +0x0000D8CC 0x8FF7 # 0 +0x0000D8CD 0x9000 # 0 +0x0000D8CE 0x8FFA # 0 +0x0000D8CF 0x8FF4 # 0 +0x0000D8D0 0x9003 # 0 +0x0000D8D1 0x8FFD # 0 +0x0000D8D2 0x9005 # 0 +0x0000D8D3 0x8FF8 # 0 +0x0000D8D4 0x9095 # 0 +0x0000D8D5 0x90E1 # 0 +0x0000D8D6 0x90DD # 0 +0x0000D8D7 0x90E2 # 0 +0x0000D8D8 0x9152 # 0 +0x0000D8D9 0x914D # 0 +0x0000D8DA 0x914C # 0 +0x0000D8DB 0x91D8 # 0 +0x0000D8DC 0x91DD # 0 +0x0000D8DD 0x91D7 # 0 +0x0000D8DE 0x91DC # 0 +0x0000D8DF 0x91D9 # 0 +0x0000D8E0 0x9583 # 0 +0x0000D8E1 0x9662 # 0 +0x0000D8E2 0x9663 # 0 +0x0000D8E3 0x9661 # 0 +0x0000D8E4 0x965B # 0 +0x0000D8E5 0x965D # 0 +0x0000D8E6 0x9664 # 0 +0x0000D8E7 0x9658 # 0 +0x0000D8E8 0x965E # 0 +0x0000D8E9 0x96BB # 0 +0x0000D8EA 0x98E2 # 0 +0x0000D8EB 0x99AC # 0 +0x0000D8EC 0x9AA8 # 0 +0x0000D8ED 0x9AD8 # 0 +0x0000D8EE 0x9B25 # 0 +0x0000D8EF 0x9B32 # 0 +0x0000D8F0 0x9B3C # 0 +0x0000D8F1 0x4E7E # 0 +0x0000D8F2 0x507A # 0 +0x0000D8F3 0x507D # 0 +0x0000D8F4 0x505C # 0 +0x0000D8F5 0x5047 # 0 +0x0000D8F6 0x5043 # 0 +0x0000D8F7 0x504C # 0 +0x0000D8F8 0x505A # 0 +0x0000D8F9 0x5049 # 0 +0x0000D8FA 0x5065 # 0 +0x0000D8FB 0x5076 # 0 +0x0000D8FC 0x504E # 0 +0x0000D8FD 0x5055 # 0 +0x0000D8FE 0x5075 # 0 +0x0000D9A1 0x5074 # 0 +0x0000D9A2 0x5077 # 0 +0x0000D9A3 0x504F # 0 +0x0000D9A4 0x500F # 0 +0x0000D9A5 0x506F # 0 +0x0000D9A6 0x506D # 0 +0x0000D9A7 0x515C # 0 +0x0000D9A8 0x5195 # 0 +0x0000D9A9 0x51F0 # 0 +0x0000D9AA 0x526A # 0 +0x0000D9AB 0x526F # 0 +0x0000D9AC 0x52D2 # 0 +0x0000D9AD 0x52D9 # 0 +0x0000D9AE 0x52D8 # 0 +0x0000D9AF 0x52D5 # 0 +0x0000D9B0 0x5310 # 0 +0x0000D9B1 0x530F # 0 +0x0000D9B2 0x5319 # 0 +0x0000D9B3 0x533F # 0 +0x0000D9B4 0x5340 # 0 +0x0000D9B5 0x533E # 0 +0x0000D9B6 0x53C3 # 0 +0x0000D9B7 0x66FC # 0 +0x0000D9B8 0x5546 # 0 +0x0000D9B9 0x556A # 0 +0x0000D9BA 0x5566 # 0 +0x0000D9BB 0x5544 # 0 +0x0000D9BC 0x555E # 0 +0x0000D9BD 0x5561 # 0 +0x0000D9BE 0x5543 # 0 +0x0000D9BF 0x554A # 0 +0x0000D9C0 0x5531 # 0 +0x0000D9C1 0x5556 # 0 +0x0000D9C2 0x554F # 0 +0x0000D9C3 0x5555 # 0 +0x0000D9C4 0x552F # 0 +0x0000D9C5 0x5564 # 0 +0x0000D9C6 0x5538 # 0 +0x0000D9C7 0x552E # 0 +0x0000D9C8 0x555C # 0 +0x0000D9C9 0x552C # 0 +0x0000D9CA 0x5563 # 0 +0x0000D9CB 0x5533 # 0 +0x0000D9CC 0x5541 # 0 +0x0000D9CD 0x5557 # 0 +0x0000D9CE 0x5708 # 0 +0x0000D9CF 0x570B # 0 +0x0000D9D0 0x5709 # 0 +0x0000D9D1 0x57DF # 0 +0x0000D9D2 0x5805 # 0 +0x0000D9D3 0x580A # 0 +0x0000D9D4 0x5806 # 0 +0x0000D9D5 0x57E0 # 0 +0x0000D9D6 0x57E4 # 0 +0x0000D9D7 0x57FA # 0 +0x0000D9D8 0x5802 # 0 +0x0000D9D9 0x5835 # 0 +0x0000D9DA 0x57F7 # 0 +0x0000D9DB 0x57F9 # 0 +0x0000D9DC 0x5920 # 0 +0x0000D9DD 0x5962 # 0 +0x0000D9DE 0x5A36 # 0 +0x0000D9DF 0x5A41 # 0 +0x0000D9E0 0x5A49 # 0 +0x0000D9E1 0x5A66 # 0 +0x0000D9E2 0x5A6A # 0 +0x0000D9E3 0x5A40 # 0 +0x0000D9E4 0x5A3C # 0 +0x0000D9E5 0x5A62 # 0 +0x0000D9E6 0x5A5A # 0 +0x0000D9E7 0x5A46 # 0 +0x0000D9E8 0x5A4A # 0 +0x0000D9E9 0x5B70 # 0 +0x0000D9EA 0x5BC7 # 0 +0x0000D9EB 0x5BC5 # 0 +0x0000D9EC 0x5BC4 # 0 +0x0000D9ED 0x5BC2 # 0 +0x0000D9EE 0x5BBF # 0 +0x0000D9EF 0x5BC6 # 0 +0x0000D9F0 0x5C09 # 0 +0x0000D9F1 0x5C08 # 0 +0x0000D9F2 0x5C07 # 0 +0x0000D9F3 0x5C60 # 0 +0x0000D9F4 0x5C5C # 0 +0x0000D9F5 0x5C5D # 0 +0x0000D9F6 0x5D07 # 0 +0x0000D9F7 0x5D06 # 0 +0x0000D9F8 0x5D0E # 0 +0x0000D9F9 0x5D1B # 0 +0x0000D9FA 0x5D16 # 0 +0x0000D9FB 0x5D22 # 0 +0x0000D9FC 0x5D11 # 0 +0x0000D9FD 0x5D29 # 0 +0x0000D9FE 0x5D14 # 0 +0x0000DAA1 0x5D19 # 0 +0x0000DAA2 0x5D24 # 0 +0x0000DAA3 0x5D27 # 0 +0x0000DAA4 0x5D17 # 0 +0x0000DAA5 0x5DE2 # 0 +0x0000DAA6 0x5E38 # 0 +0x0000DAA7 0x5E36 # 0 +0x0000DAA8 0x5E33 # 0 +0x0000DAA9 0x5E37 # 0 +0x0000DAAA 0x5EB7 # 0 +0x0000DAAB 0x5EB8 # 0 +0x0000DAAC 0x5EB6 # 0 +0x0000DAAD 0x5EB5 # 0 +0x0000DAAE 0x5EBE # 0 +0x0000DAAF 0x5F35 # 0 +0x0000DAB0 0x5F37 # 0 +0x0000DAB1 0x5F57 # 0 +0x0000DAB2 0x5F6C # 0 +0x0000DAB3 0x5F69 # 0 +0x0000DAB4 0x5F6B # 0 +0x0000DAB5 0x5F97 # 0 +0x0000DAB6 0x5F99 # 0 +0x0000DAB7 0x5F9E # 0 +0x0000DAB8 0x5F98 # 0 +0x0000DAB9 0x5FA1 # 0 +0x0000DABA 0x5FA0 # 0 +0x0000DABB 0x5F9C # 0 +0x0000DABC 0x607F # 0 +0x0000DABD 0x60A3 # 0 +0x0000DABE 0x6089 # 0 +0x0000DABF 0x60A0 # 0 +0x0000DAC0 0x60A8 # 0 +0x0000DAC1 0x60CB # 0 +0x0000DAC2 0x60B4 # 0 +0x0000DAC3 0x60E6 # 0 +0x0000DAC4 0x60BD # 0 +0x0000DAC5 0x60C5 # 0 +0x0000DAC6 0x60BB # 0 +0x0000DAC7 0x60B5 # 0 +0x0000DAC8 0x60DC # 0 +0x0000DAC9 0x60BC # 0 +0x0000DACA 0x60D8 # 0 +0x0000DACB 0x60D5 # 0 +0x0000DACC 0x60C6 # 0 +0x0000DACD 0x60DF # 0 +0x0000DACE 0x60B8 # 0 +0x0000DACF 0x60DA # 0 +0x0000DAD0 0x60C7 # 0 +0x0000DAD1 0x621A # 0 +0x0000DAD2 0x621B # 0 +0x0000DAD3 0x6248 # 0 +0x0000DAD4 0x63A0 # 0 +0x0000DAD5 0x63A7 # 0 +0x0000DAD6 0x6372 # 0 +0x0000DAD7 0x6396 # 0 +0x0000DAD8 0x63A2 # 0 +0x0000DAD9 0x63A5 # 0 +0x0000DADA 0x6377 # 0 +0x0000DADB 0x6367 # 0 +0x0000DADC 0x6398 # 0 +0x0000DADD 0x63AA # 0 +0x0000DADE 0x6371 # 0 +0x0000DADF 0x63A9 # 0 +0x0000DAE0 0x6389 # 0 +0x0000DAE1 0x6383 # 0 +0x0000DAE2 0x639B # 0 +0x0000DAE3 0x636B # 0 +0x0000DAE4 0x63A8 # 0 +0x0000DAE5 0x6384 # 0 +0x0000DAE6 0x6388 # 0 +0x0000DAE7 0x6399 # 0 +0x0000DAE8 0x63A1 # 0 +0x0000DAE9 0x63AC # 0 +0x0000DAEA 0x6392 # 0 +0x0000DAEB 0x638F # 0 +0x0000DAEC 0x6380 # 0 +0x0000DAED 0x637B # 0 +0x0000DAEE 0x6369 # 0 +0x0000DAEF 0x6368 # 0 +0x0000DAF0 0x637A # 0 +0x0000DAF1 0x655D # 0 +0x0000DAF2 0x6556 # 0 +0x0000DAF3 0x6551 # 0 +0x0000DAF4 0x6559 # 0 +0x0000DAF5 0x6557 # 0 +0x0000DAF6 0x555F # 0 +0x0000DAF7 0x654F # 0 +0x0000DAF8 0x6558 # 0 +0x0000DAF9 0x6555 # 0 +0x0000DAFA 0x6554 # 0 +0x0000DAFB 0x659C # 0 +0x0000DAFC 0x659B # 0 +0x0000DAFD 0x65AC # 0 +0x0000DAFE 0x65CF # 0 +0x0000DBA1 0x65CB # 0 +0x0000DBA2 0x65CC # 0 +0x0000DBA3 0x65CE # 0 +0x0000DBA4 0x665D # 0 +0x0000DBA5 0x665A # 0 +0x0000DBA6 0x6664 # 0 +0x0000DBA7 0x6668 # 0 +0x0000DBA8 0x6666 # 0 +0x0000DBA9 0x665E # 0 +0x0000DBAA 0x66F9 # 0 +0x0000DBAB 0x52D7 # 0 +0x0000DBAC 0x671B # 0 +0x0000DBAD 0x6881 # 0 +0x0000DBAE 0x68AF # 0 +0x0000DBAF 0x68A2 # 0 +0x0000DBB0 0x6893 # 0 +0x0000DBB1 0x68B5 # 0 +0x0000DBB2 0x687F # 0 +0x0000DBB3 0x6876 # 0 +0x0000DBB4 0x68B1 # 0 +0x0000DBB5 0x68A7 # 0 +0x0000DBB6 0x6897 # 0 +0x0000DBB7 0x68B0 # 0 +0x0000DBB8 0x6883 # 0 +0x0000DBB9 0x68C4 # 0 +0x0000DBBA 0x68AD # 0 +0x0000DBBB 0x6886 # 0 +0x0000DBBC 0x6885 # 0 +0x0000DBBD 0x6894 # 0 +0x0000DBBE 0x689D # 0 +0x0000DBBF 0x68A8 # 0 +0x0000DBC0 0x689F # 0 +0x0000DBC1 0x68A1 # 0 +0x0000DBC2 0x6882 # 0 +0x0000DBC3 0x6B32 # 0 +0x0000DBC4 0x6BBA # 0 +0x0000DBC5 0x6BEB # 0 +0x0000DBC6 0x6BEC # 0 +0x0000DBC7 0x6C2B # 0 +0x0000DBC8 0x6D8E # 0 +0x0000DBC9 0x6DBC # 0 +0x0000DBCA 0x6DF3 # 0 +0x0000DBCB 0x6DD9 # 0 +0x0000DBCC 0x6DB2 # 0 +0x0000DBCD 0x6DE1 # 0 +0x0000DBCE 0x6DCC # 0 +0x0000DBCF 0x6DE4 # 0 +0x0000DBD0 0x6DFB # 0 +0x0000DBD1 0x6DFA # 0 +0x0000DBD2 0x6E05 # 0 +0x0000DBD3 0x6DC7 # 0 +0x0000DBD4 0x6DCB # 0 +0x0000DBD5 0x6DAF # 0 +0x0000DBD6 0x6DD1 # 0 +0x0000DBD7 0x6DAE # 0 +0x0000DBD8 0x6DDE # 0 +0x0000DBD9 0x6DF9 # 0 +0x0000DBDA 0x6DB8 # 0 +0x0000DBDB 0x6DF7 # 0 +0x0000DBDC 0x6DF5 # 0 +0x0000DBDD 0x6DC5 # 0 +0x0000DBDE 0x6DD2 # 0 +0x0000DBDF 0x6E1A # 0 +0x0000DBE0 0x6DB5 # 0 +0x0000DBE1 0x6DDA # 0 +0x0000DBE2 0x6DEB # 0 +0x0000DBE3 0x6DD8 # 0 +0x0000DBE4 0x6DEA # 0 +0x0000DBE5 0x6DF1 # 0 +0x0000DBE6 0x6DEE # 0 +0x0000DBE7 0x6DE8 # 0 +0x0000DBE8 0x6DC6 # 0 +0x0000DBE9 0x6DC4 # 0 +0x0000DBEA 0x6DAA # 0 +0x0000DBEB 0x6DEC # 0 +0x0000DBEC 0x6DBF # 0 +0x0000DBED 0x6DE6 # 0 +0x0000DBEE 0x70F9 # 0 +0x0000DBEF 0x7109 # 0 +0x0000DBF0 0x710A # 0 +0x0000DBF1 0x70FD # 0 +0x0000DBF2 0x70EF # 0 +0x0000DBF3 0x723D # 0 +0x0000DBF4 0x727D # 0 +0x0000DBF5 0x7281 # 0 +0x0000DBF6 0x731C # 0 +0x0000DBF7 0x731B # 0 +0x0000DBF8 0x7316 # 0 +0x0000DBF9 0x7313 # 0 +0x0000DBFA 0x7319 # 0 +0x0000DBFB 0x7387 # 0 +0x0000DBFC 0x7405 # 0 +0x0000DBFD 0x740A # 0 +0x0000DBFE 0x7403 # 0 +0x0000DCA1 0x7406 # 0 +0x0000DCA2 0x73FE # 0 +0x0000DCA3 0x740D # 0 +0x0000DCA4 0x74E0 # 0 +0x0000DCA5 0x74F6 # 0 +0x0000DCA6 0x74F7 # 0 +0x0000DCA7 0x751C # 0 +0x0000DCA8 0x7522 # 0 +0x0000DCA9 0x7565 # 0 +0x0000DCAA 0x7566 # 0 +0x0000DCAB 0x7562 # 0 +0x0000DCAC 0x7570 # 0 +0x0000DCAD 0x758F # 0 +0x0000DCAE 0x75D4 # 0 +0x0000DCAF 0x75D5 # 0 +0x0000DCB0 0x75B5 # 0 +0x0000DCB1 0x75CA # 0 +0x0000DCB2 0x75CD # 0 +0x0000DCB3 0x768E # 0 +0x0000DCB4 0x76D4 # 0 +0x0000DCB5 0x76D2 # 0 +0x0000DCB6 0x76DB # 0 +0x0000DCB7 0x7737 # 0 +0x0000DCB8 0x773E # 0 +0x0000DCB9 0x773C # 0 +0x0000DCBA 0x7736 # 0 +0x0000DCBB 0x7738 # 0 +0x0000DCBC 0x773A # 0 +0x0000DCBD 0x786B # 0 +0x0000DCBE 0x7843 # 0 +0x0000DCBF 0x784E # 0 +0x0000DCC0 0x7965 # 0 +0x0000DCC1 0x7968 # 0 +0x0000DCC2 0x796D # 0 +0x0000DCC3 0x79FB # 0 +0x0000DCC4 0x7A92 # 0 +0x0000DCC5 0x7A95 # 0 +0x0000DCC6 0x7B20 # 0 +0x0000DCC7 0x7B28 # 0 +0x0000DCC8 0x7B1B # 0 +0x0000DCC9 0x7B2C # 0 +0x0000DCCA 0x7B26 # 0 +0x0000DCCB 0x7B19 # 0 +0x0000DCCC 0x7B1E # 0 +0x0000DCCD 0x7B2E # 0 +0x0000DCCE 0x7C92 # 0 +0x0000DCCF 0x7C97 # 0 +0x0000DCD0 0x7C95 # 0 +0x0000DCD1 0x7D46 # 0 +0x0000DCD2 0x7D43 # 0 +0x0000DCD3 0x7D71 # 0 +0x0000DCD4 0x7D2E # 0 +0x0000DCD5 0x7D39 # 0 +0x0000DCD6 0x7D3C # 0 +0x0000DCD7 0x7D40 # 0 +0x0000DCD8 0x7D30 # 0 +0x0000DCD9 0x7D33 # 0 +0x0000DCDA 0x7D44 # 0 +0x0000DCDB 0x7D2F # 0 +0x0000DCDC 0x7D42 # 0 +0x0000DCDD 0x7D32 # 0 +0x0000DCDE 0x7D31 # 0 +0x0000DCDF 0x7F3D # 0 +0x0000DCE0 0x7F9E # 0 +0x0000DCE1 0x7F9A # 0 +0x0000DCE2 0x7FCC # 0 +0x0000DCE3 0x7FCE # 0 +0x0000DCE4 0x7FD2 # 0 +0x0000DCE5 0x801C # 0 +0x0000DCE6 0x804A # 0 +0x0000DCE7 0x8046 # 0 +0x0000DCE8 0x812F # 0 +0x0000DCE9 0x8116 # 0 +0x0000DCEA 0x8123 # 0 +0x0000DCEB 0x812B # 0 +0x0000DCEC 0x8129 # 0 +0x0000DCED 0x8130 # 0 +0x0000DCEE 0x8124 # 0 +0x0000DCEF 0x8202 # 0 +0x0000DCF0 0x8235 # 0 +0x0000DCF1 0x8237 # 0 +0x0000DCF2 0x8236 # 0 +0x0000DCF3 0x8239 # 0 +0x0000DCF4 0x838E # 0 +0x0000DCF5 0x839E # 0 +0x0000DCF6 0x8398 # 0 +0x0000DCF7 0x8378 # 0 +0x0000DCF8 0x83A2 # 0 +0x0000DCF9 0x8396 # 0 +0x0000DCFA 0x83BD # 0 +0x0000DCFB 0x83AB # 0 +0x0000DCFC 0x8392 # 0 +0x0000DCFD 0x838A # 0 +0x0000DCFE 0x8393 # 0 +0x0000DDA1 0x8389 # 0 +0x0000DDA2 0x83A0 # 0 +0x0000DDA3 0x8377 # 0 +0x0000DDA4 0x837B # 0 +0x0000DDA5 0x837C # 0 +0x0000DDA6 0x8386 # 0 +0x0000DDA7 0x83A7 # 0 +0x0000DDA8 0x8655 # 0 +0x0000DDA9 0x5F6A # 0 +0x0000DDAA 0x86C7 # 0 +0x0000DDAB 0x86C0 # 0 +0x0000DDAC 0x86B6 # 0 +0x0000DDAD 0x86C4 # 0 +0x0000DDAE 0x86B5 # 0 +0x0000DDAF 0x86C6 # 0 +0x0000DDB0 0x86CB # 0 +0x0000DDB1 0x86B1 # 0 +0x0000DDB2 0x86AF # 0 +0x0000DDB3 0x86C9 # 0 +0x0000DDB4 0x8853 # 0 +0x0000DDB5 0x889E # 0 +0x0000DDB6 0x8888 # 0 +0x0000DDB7 0x88AB # 0 +0x0000DDB8 0x8892 # 0 +0x0000DDB9 0x8896 # 0 +0x0000DDBA 0x888D # 0 +0x0000DDBB 0x888B # 0 +0x0000DDBC 0x8993 # 0 +0x0000DDBD 0x898F # 0 +0x0000DDBE 0x8A2A # 0 +0x0000DDBF 0x8A1D # 0 +0x0000DDC0 0x8A23 # 0 +0x0000DDC1 0x8A25 # 0 +0x0000DDC2 0x8A31 # 0 +0x0000DDC3 0x8A2D # 0 +0x0000DDC4 0x8A1F # 0 +0x0000DDC5 0x8A1B # 0 +0x0000DDC6 0x8A22 # 0 +0x0000DDC7 0x8C49 # 0 +0x0000DDC8 0x8C5A # 0 +0x0000DDC9 0x8CA9 # 0 +0x0000DDCA 0x8CAC # 0 +0x0000DDCB 0x8CAB # 0 +0x0000DDCC 0x8CA8 # 0 +0x0000DDCD 0x8CAA # 0 +0x0000DDCE 0x8CA7 # 0 +0x0000DDCF 0x8D67 # 0 +0x0000DDD0 0x8D66 # 0 +0x0000DDD1 0x8DBE # 0 +0x0000DDD2 0x8DBA # 0 +0x0000DDD3 0x8EDB # 0 +0x0000DDD4 0x8EDF # 0 +0x0000DDD5 0x9019 # 0 +0x0000DDD6 0x900D # 0 +0x0000DDD7 0x901A # 0 +0x0000DDD8 0x9017 # 0 +0x0000DDD9 0x9023 # 0 +0x0000DDDA 0x901F # 0 +0x0000DDDB 0x901D # 0 +0x0000DDDC 0x9010 # 0 +0x0000DDDD 0x9015 # 0 +0x0000DDDE 0x901E # 0 +0x0000DDDF 0x9020 # 0 +0x0000DDE0 0x900F # 0 +0x0000DDE1 0x9022 # 0 +0x0000DDE2 0x9016 # 0 +0x0000DDE3 0x901B # 0 +0x0000DDE4 0x9014 # 0 +0x0000DDE5 0x90E8 # 0 +0x0000DDE6 0x90ED # 0 +0x0000DDE7 0x90FD # 0 +0x0000DDE8 0x9157 # 0 +0x0000DDE9 0x91CE # 0 +0x0000DDEA 0x91F5 # 0 +0x0000DDEB 0x91E6 # 0 +0x0000DDEC 0x91E3 # 0 +0x0000DDED 0x91E7 # 0 +0x0000DDEE 0x91ED # 0 +0x0000DDEF 0x91E9 # 0 +0x0000DDF0 0x9589 # 0 +0x0000DDF1 0x966A # 0 +0x0000DDF2 0x9675 # 0 +0x0000DDF3 0x9673 # 0 +0x0000DDF4 0x9678 # 0 +0x0000DDF5 0x9670 # 0 +0x0000DDF6 0x9674 # 0 +0x0000DDF7 0x9676 # 0 +0x0000DDF8 0x9677 # 0 +0x0000DDF9 0x966C # 0 +0x0000DDFA 0x96C0 # 0 +0x0000DDFB 0x96EA # 0 +0x0000DDFC 0x96E9 # 0 +0x0000DDFD 0x7AE0 # 0 +0x0000DDFE 0x7ADF # 0 +0x0000DEA1 0x9802 # 0 +0x0000DEA2 0x9803 # 0 +0x0000DEA3 0x9B5A # 0 +0x0000DEA4 0x9CE5 # 0 +0x0000DEA5 0x9E75 # 0 +0x0000DEA6 0x9E7F # 0 +0x0000DEA7 0x9EA5 # 0 +0x0000DEA8 0x9EBB # 0 +0x0000DEA9 0x50A2 # 0 +0x0000DEAA 0x508D # 0 +0x0000DEAB 0x5085 # 0 +0x0000DEAC 0x5099 # 0 +0x0000DEAD 0x5091 # 0 +0x0000DEAE 0x5080 # 0 +0x0000DEAF 0x5096 # 0 +0x0000DEB0 0x5098 # 0 +0x0000DEB1 0x509A # 0 +0x0000DEB2 0x6700 # 0 +0x0000DEB3 0x51F1 # 0 +0x0000DEB4 0x5272 # 0 +0x0000DEB5 0x5274 # 0 +0x0000DEB6 0x5275 # 0 +0x0000DEB7 0x5269 # 0 +0x0000DEB8 0x52DE # 0 +0x0000DEB9 0x52DD # 0 +0x0000DEBA 0x52DB # 0 +0x0000DEBB 0x535A # 0 +0x0000DEBC 0x53A5 # 0 +0x0000DEBD 0x557B # 0 +0x0000DEBE 0x5580 # 0 +0x0000DEBF 0x55A7 # 0 +0x0000DEC0 0x557C # 0 +0x0000DEC1 0x558A # 0 +0x0000DEC2 0x559D # 0 +0x0000DEC3 0x5598 # 0 +0x0000DEC4 0x5582 # 0 +0x0000DEC5 0x559C # 0 +0x0000DEC6 0x55AA # 0 +0x0000DEC7 0x5594 # 0 +0x0000DEC8 0x5587 # 0 +0x0000DEC9 0x558B # 0 +0x0000DECA 0x5583 # 0 +0x0000DECB 0x55B3 # 0 +0x0000DECC 0x55AE # 0 +0x0000DECD 0x559F # 0 +0x0000DECE 0x553E # 0 +0x0000DECF 0x55B2 # 0 +0x0000DED0 0x559A # 0 +0x0000DED1 0x55BB # 0 +0x0000DED2 0x55AC # 0 +0x0000DED3 0x55B1 # 0 +0x0000DED4 0x557E # 0 +0x0000DED5 0x5589 # 0 +0x0000DED6 0x55AB # 0 +0x0000DED7 0x5599 # 0 +0x0000DED8 0x570D # 0 +0x0000DED9 0x582F # 0 +0x0000DEDA 0x582A # 0 +0x0000DEDB 0x5834 # 0 +0x0000DEDC 0x5824 # 0 +0x0000DEDD 0x5830 # 0 +0x0000DEDE 0x5831 # 0 +0x0000DEDF 0x5821 # 0 +0x0000DEE0 0x581D # 0 +0x0000DEE1 0x5820 # 0 +0x0000DEE2 0x58F9 # 0 +0x0000DEE3 0x58FA # 0 +0x0000DEE4 0x5960 # 0 +0x0000DEE5 0x5A77 # 0 +0x0000DEE6 0x5A9A # 0 +0x0000DEE7 0x5A7F # 0 +0x0000DEE8 0x5A92 # 0 +0x0000DEE9 0x5A9B # 0 +0x0000DEEA 0x5AA7 # 0 +0x0000DEEB 0x5B73 # 0 +0x0000DEEC 0x5B71 # 0 +0x0000DEED 0x5BD2 # 0 +0x0000DEEE 0x5BCC # 0 +0x0000DEEF 0x5BD3 # 0 +0x0000DEF0 0x5BD0 # 0 +0x0000DEF1 0x5C0A # 0 +0x0000DEF2 0x5C0B # 0 +0x0000DEF3 0x5C31 # 0 +0x0000DEF4 0x5D4C # 0 +0x0000DEF5 0x5D50 # 0 +0x0000DEF6 0x5D34 # 0 +0x0000DEF7 0x5D47 # 0 +0x0000DEF8 0x5DFD # 0 +0x0000DEF9 0x5E45 # 0 +0x0000DEFA 0x5E3D # 0 +0x0000DEFB 0x5E40 # 0 +0x0000DEFC 0x5E43 # 0 +0x0000DEFD 0x5E7E # 0 +0x0000DEFE 0x5ECA # 0 +0x0000DFA1 0x5EC1 # 0 +0x0000DFA2 0x5EC2 # 0 +0x0000DFA3 0x5EC4 # 0 +0x0000DFA4 0x5F3C # 0 +0x0000DFA5 0x5F6D # 0 +0x0000DFA6 0x5FA9 # 0 +0x0000DFA7 0x5FAA # 0 +0x0000DFA8 0x5FA8 # 0 +0x0000DFA9 0x60D1 # 0 +0x0000DFAA 0x60E1 # 0 +0x0000DFAB 0x60B2 # 0 +0x0000DFAC 0x60B6 # 0 +0x0000DFAD 0x60E0 # 0 +0x0000DFAE 0x611C # 0 +0x0000DFAF 0x6123 # 0 +0x0000DFB0 0x60FA # 0 +0x0000DFB1 0x6115 # 0 +0x0000DFB2 0x60F0 # 0 +0x0000DFB3 0x60FB # 0 +0x0000DFB4 0x60F4 # 0 +0x0000DFB5 0x6168 # 0 +0x0000DFB6 0x60F1 # 0 +0x0000DFB7 0x610E # 0 +0x0000DFB8 0x60F6 # 0 +0x0000DFB9 0x6109 # 0 +0x0000DFBA 0x6100 # 0 +0x0000DFBB 0x6112 # 0 +0x0000DFBC 0x621F # 0 +0x0000DFBD 0x6249 # 0 +0x0000DFBE 0x63A3 # 0 +0x0000DFBF 0x638C # 0 +0x0000DFC0 0x63CF # 0 +0x0000DFC1 0x63C0 # 0 +0x0000DFC2 0x63E9 # 0 +0x0000DFC3 0x63C9 # 0 +0x0000DFC4 0x63C6 # 0 +0x0000DFC5 0x63CD # 0 +0x0000DFC6 0x63D2 # 0 +0x0000DFC7 0x63E3 # 0 +0x0000DFC8 0x63D0 # 0 +0x0000DFC9 0x63E1 # 0 +0x0000DFCA 0x63D6 # 0 +0x0000DFCB 0x63ED # 0 +0x0000DFCC 0x63EE # 0 +0x0000DFCD 0x6376 # 0 +0x0000DFCE 0x63F4 # 0 +0x0000DFCF 0x63EA # 0 +0x0000DFD0 0x63DB # 0 +0x0000DFD1 0x6452 # 0 +0x0000DFD2 0x63DA # 0 +0x0000DFD3 0x63F9 # 0 +0x0000DFD4 0x655E # 0 +0x0000DFD5 0x6566 # 0 +0x0000DFD6 0x6562 # 0 +0x0000DFD7 0x6563 # 0 +0x0000DFD8 0x6591 # 0 +0x0000DFD9 0x6590 # 0 +0x0000DFDA 0x65AF # 0 +0x0000DFDB 0x666E # 0 +0x0000DFDC 0x6670 # 0 +0x0000DFDD 0x6674 # 0 +0x0000DFDE 0x6676 # 0 +0x0000DFDF 0x666F # 0 +0x0000DFE0 0x6691 # 0 +0x0000DFE1 0x667A # 0 +0x0000DFE2 0x667E # 0 +0x0000DFE3 0x6677 # 0 +0x0000DFE4 0x66FE # 0 +0x0000DFE5 0x66FF # 0 +0x0000DFE6 0x671F # 0 +0x0000DFE7 0x671D # 0 +0x0000DFE8 0x68FA # 0 +0x0000DFE9 0x68D5 # 0 +0x0000DFEA 0x68E0 # 0 +0x0000DFEB 0x68D8 # 0 +0x0000DFEC 0x68D7 # 0 +0x0000DFED 0x6905 # 0 +0x0000DFEE 0x68DF # 0 +0x0000DFEF 0x68F5 # 0 +0x0000DFF0 0x68EE # 0 +0x0000DFF1 0x68E7 # 0 +0x0000DFF2 0x68F9 # 0 +0x0000DFF3 0x68D2 # 0 +0x0000DFF4 0x68F2 # 0 +0x0000DFF5 0x68E3 # 0 +0x0000DFF6 0x68CB # 0 +0x0000DFF7 0x68CD # 0 +0x0000DFF8 0x690D # 0 +0x0000DFF9 0x6912 # 0 +0x0000DFFA 0x690E # 0 +0x0000DFFB 0x68C9 # 0 +0x0000DFFC 0x68DA # 0 +0x0000DFFD 0x696E # 0 +0x0000DFFE 0x68FB # 0 +0x0000E0A1 0x6B3E # 0 +0x0000E0A2 0x6B3A # 0 +0x0000E0A3 0x6B3D # 0 +0x0000E0A4 0x6B98 # 0 +0x0000E0A5 0x6B96 # 0 +0x0000E0A6 0x6BBC # 0 +0x0000E0A7 0x6BEF # 0 +0x0000E0A8 0x6C2E # 0 +0x0000E0A9 0x6C2F # 0 +0x0000E0AA 0x6C2C # 0 +0x0000E0AB 0x6E2F # 0 +0x0000E0AC 0x6E38 # 0 +0x0000E0AD 0x6E54 # 0 +0x0000E0AE 0x6E21 # 0 +0x0000E0AF 0x6E32 # 0 +0x0000E0B0 0x6E67 # 0 +0x0000E0B1 0x6E4A # 0 +0x0000E0B2 0x6E20 # 0 +0x0000E0B3 0x6E25 # 0 +0x0000E0B4 0x6E23 # 0 +0x0000E0B5 0x6E1B # 0 +0x0000E0B6 0x6E5B # 0 +0x0000E0B7 0x6E58 # 0 +0x0000E0B8 0x6E24 # 0 +0x0000E0B9 0x6E56 # 0 +0x0000E0BA 0x6E6E # 0 +0x0000E0BB 0x6E2D # 0 +0x0000E0BC 0x6E26 # 0 +0x0000E0BD 0x6E6F # 0 +0x0000E0BE 0x6E34 # 0 +0x0000E0BF 0x6E4D # 0 +0x0000E0C0 0x6E3A # 0 +0x0000E0C1 0x6E2C # 0 +0x0000E0C2 0x6E43 # 0 +0x0000E0C3 0x6E1D # 0 +0x0000E0C4 0x6E3E # 0 +0x0000E0C5 0x6ECB # 0 +0x0000E0C6 0x6E89 # 0 +0x0000E0C7 0x6E19 # 0 +0x0000E0C8 0x6E4E # 0 +0x0000E0C9 0x6E63 # 0 +0x0000E0CA 0x6E44 # 0 +0x0000E0CB 0x6E72 # 0 +0x0000E0CC 0x6E69 # 0 +0x0000E0CD 0x6E5F # 0 +0x0000E0CE 0x7119 # 0 +0x0000E0CF 0x711A # 0 +0x0000E0D0 0x7126 # 0 +0x0000E0D1 0x7130 # 0 +0x0000E0D2 0x7121 # 0 +0x0000E0D3 0x7136 # 0 +0x0000E0D4 0x716E # 0 +0x0000E0D5 0x711C # 0 +0x0000E0D6 0x724C # 0 +0x0000E0D7 0x7284 # 0 +0x0000E0D8 0x7280 # 0 +0x0000E0D9 0x7336 # 0 +0x0000E0DA 0x7325 # 0 +0x0000E0DB 0x7334 # 0 +0x0000E0DC 0x7329 # 0 +0x0000E0DD 0x743A # 0 +0x0000E0DE 0x742A # 0 +0x0000E0DF 0x7433 # 0 +0x0000E0E0 0x7422 # 0 +0x0000E0E1 0x7425 # 0 +0x0000E0E2 0x7435 # 0 +0x0000E0E3 0x7436 # 0 +0x0000E0E4 0x7434 # 0 +0x0000E0E5 0x742F # 0 +0x0000E0E6 0x741B # 0 +0x0000E0E7 0x7426 # 0 +0x0000E0E8 0x7428 # 0 +0x0000E0E9 0x7525 # 0 +0x0000E0EA 0x7526 # 0 +0x0000E0EB 0x756B # 0 +0x0000E0EC 0x756A # 0 +0x0000E0ED 0x75E2 # 0 +0x0000E0EE 0x75DB # 0 +0x0000E0EF 0x75E3 # 0 +0x0000E0F0 0x75D9 # 0 +0x0000E0F1 0x75D8 # 0 +0x0000E0F2 0x75DE # 0 +0x0000E0F3 0x75E0 # 0 +0x0000E0F4 0x767B # 0 +0x0000E0F5 0x767C # 0 +0x0000E0F6 0x7696 # 0 +0x0000E0F7 0x7693 # 0 +0x0000E0F8 0x76B4 # 0 +0x0000E0F9 0x76DC # 0 +0x0000E0FA 0x774F # 0 +0x0000E0FB 0x77ED # 0 +0x0000E0FC 0x785D # 0 +0x0000E0FD 0x786C # 0 +0x0000E0FE 0x786F # 0 +0x0000E1A1 0x7A0D # 0 +0x0000E1A2 0x7A08 # 0 +0x0000E1A3 0x7A0B # 0 +0x0000E1A4 0x7A05 # 0 +0x0000E1A5 0x7A00 # 0 +0x0000E1A6 0x7A98 # 0 +0x0000E1A7 0x7A97 # 0 +0x0000E1A8 0x7A96 # 0 +0x0000E1A9 0x7AE5 # 0 +0x0000E1AA 0x7AE3 # 0 +0x0000E1AB 0x7B49 # 0 +0x0000E1AC 0x7B56 # 0 +0x0000E1AD 0x7B46 # 0 +0x0000E1AE 0x7B50 # 0 +0x0000E1AF 0x7B52 # 0 +0x0000E1B0 0x7B54 # 0 +0x0000E1B1 0x7B4D # 0 +0x0000E1B2 0x7B4B # 0 +0x0000E1B3 0x7B4F # 0 +0x0000E1B4 0x7B51 # 0 +0x0000E1B5 0x7C9F # 0 +0x0000E1B6 0x7CA5 # 0 +0x0000E1B7 0x7D5E # 0 +0x0000E1B8 0x7D50 # 0 +0x0000E1B9 0x7D68 # 0 +0x0000E1BA 0x7D55 # 0 +0x0000E1BB 0x7D2B # 0 +0x0000E1BC 0x7D6E # 0 +0x0000E1BD 0x7D72 # 0 +0x0000E1BE 0x7D61 # 0 +0x0000E1BF 0x7D66 # 0 +0x0000E1C0 0x7D62 # 0 +0x0000E1C1 0x7D70 # 0 +0x0000E1C2 0x7D73 # 0 +0x0000E1C3 0x5584 # 0 +0x0000E1C4 0x7FD4 # 0 +0x0000E1C5 0x7FD5 # 0 +0x0000E1C6 0x800B # 0 +0x0000E1C7 0x8052 # 0 +0x0000E1C8 0x8085 # 0 +0x0000E1C9 0x8155 # 0 +0x0000E1CA 0x8154 # 0 +0x0000E1CB 0x814B # 0 +0x0000E1CC 0x8151 # 0 +0x0000E1CD 0x814E # 0 +0x0000E1CE 0x8139 # 0 +0x0000E1CF 0x8146 # 0 +0x0000E1D0 0x813E # 0 +0x0000E1D1 0x814C # 0 +0x0000E1D2 0x8153 # 0 +0x0000E1D3 0x8174 # 0 +0x0000E1D4 0x8212 # 0 +0x0000E1D5 0x821C # 0 +0x0000E1D6 0x83E9 # 0 +0x0000E1D7 0x8403 # 0 +0x0000E1D8 0x83F8 # 0 +0x0000E1D9 0x840D # 0 +0x0000E1DA 0x83E0 # 0 +0x0000E1DB 0x83C5 # 0 +0x0000E1DC 0x840B # 0 +0x0000E1DD 0x83C1 # 0 +0x0000E1DE 0x83EF # 0 +0x0000E1DF 0x83F1 # 0 +0x0000E1E0 0x83F4 # 0 +0x0000E1E1 0x8457 # 0 +0x0000E1E2 0x840A # 0 +0x0000E1E3 0x83F0 # 0 +0x0000E1E4 0x840C # 0 +0x0000E1E5 0x83CC # 0 +0x0000E1E6 0x83FD # 0 +0x0000E1E7 0x83F2 # 0 +0x0000E1E8 0x83CA # 0 +0x0000E1E9 0x8438 # 0 +0x0000E1EA 0x840E # 0 +0x0000E1EB 0x8404 # 0 +0x0000E1EC 0x83DC # 0 +0x0000E1ED 0x8407 # 0 +0x0000E1EE 0x83D4 # 0 +0x0000E1EF 0x83DF # 0 +0x0000E1F0 0x865B # 0 +0x0000E1F1 0x86DF # 0 +0x0000E1F2 0x86D9 # 0 +0x0000E1F3 0x86ED # 0 +0x0000E1F4 0x86D4 # 0 +0x0000E1F5 0x86DB # 0 +0x0000E1F6 0x86E4 # 0 +0x0000E1F7 0x86D0 # 0 +0x0000E1F8 0x86DE # 0 +0x0000E1F9 0x8857 # 0 +0x0000E1FA 0x88C1 # 0 +0x0000E1FB 0x88C2 # 0 +0x0000E1FC 0x88B1 # 0 +0x0000E1FD 0x8983 # 0 +0x0000E1FE 0x8996 # 0 +0x0000E2A1 0x8A3B # 0 +0x0000E2A2 0x8A60 # 0 +0x0000E2A3 0x8A55 # 0 +0x0000E2A4 0x8A5E # 0 +0x0000E2A5 0x8A3C # 0 +0x0000E2A6 0x8A41 # 0 +0x0000E2A7 0x8A54 # 0 +0x0000E2A8 0x8A5B # 0 +0x0000E2A9 0x8A50 # 0 +0x0000E2AA 0x8A46 # 0 +0x0000E2AB 0x8A34 # 0 +0x0000E2AC 0x8A3A # 0 +0x0000E2AD 0x8A36 # 0 +0x0000E2AE 0x8A56 # 0 +0x0000E2AF 0x8C61 # 0 +0x0000E2B0 0x8C82 # 0 +0x0000E2B1 0x8CAF # 0 +0x0000E2B2 0x8CBC # 0 +0x0000E2B3 0x8CB3 # 0 +0x0000E2B4 0x8CBD # 0 +0x0000E2B5 0x8CC1 # 0 +0x0000E2B6 0x8CBB # 0 +0x0000E2B7 0x8CC0 # 0 +0x0000E2B8 0x8CB4 # 0 +0x0000E2B9 0x8CB7 # 0 +0x0000E2BA 0x8CB6 # 0 +0x0000E2BB 0x8CBF # 0 +0x0000E2BC 0x8CB8 # 0 +0x0000E2BD 0x8D8A # 0 +0x0000E2BE 0x8D85 # 0 +0x0000E2BF 0x8D81 # 0 +0x0000E2C0 0x8DCE # 0 +0x0000E2C1 0x8DDD # 0 +0x0000E2C2 0x8DCB # 0 +0x0000E2C3 0x8DDA # 0 +0x0000E2C4 0x8DD1 # 0 +0x0000E2C5 0x8DCC # 0 +0x0000E2C6 0x8DDB # 0 +0x0000E2C7 0x8DC6 # 0 +0x0000E2C8 0x8EFB # 0 +0x0000E2C9 0x8EF8 # 0 +0x0000E2CA 0x8EFC # 0 +0x0000E2CB 0x8F9C # 0 +0x0000E2CC 0x902E # 0 +0x0000E2CD 0x9035 # 0 +0x0000E2CE 0x9031 # 0 +0x0000E2CF 0x9038 # 0 +0x0000E2D0 0x9032 # 0 +0x0000E2D1 0x9036 # 0 +0x0000E2D2 0x9102 # 0 +0x0000E2D3 0x90F5 # 0 +0x0000E2D4 0x9109 # 0 +0x0000E2D5 0x90FE # 0 +0x0000E2D6 0x9163 # 0 +0x0000E2D7 0x9165 # 0 +0x0000E2D8 0x91CF # 0 +0x0000E2D9 0x9214 # 0 +0x0000E2DA 0x9215 # 0 +0x0000E2DB 0x9223 # 0 +0x0000E2DC 0x9209 # 0 +0x0000E2DD 0x921E # 0 +0x0000E2DE 0x920D # 0 +0x0000E2DF 0x9210 # 0 +0x0000E2E0 0x9207 # 0 +0x0000E2E1 0x9211 # 0 +0x0000E2E2 0x9594 # 0 +0x0000E2E3 0x958F # 0 +0x0000E2E4 0x958B # 0 +0x0000E2E5 0x9591 # 0 +0x0000E2E6 0x9593 # 0 +0x0000E2E7 0x9592 # 0 +0x0000E2E8 0x958E # 0 +0x0000E2E9 0x968A # 0 +0x0000E2EA 0x968E # 0 +0x0000E2EB 0x968B # 0 +0x0000E2EC 0x967D # 0 +0x0000E2ED 0x9685 # 0 +0x0000E2EE 0x9686 # 0 +0x0000E2EF 0x968D # 0 +0x0000E2F0 0x9672 # 0 +0x0000E2F1 0x9684 # 0 +0x0000E2F2 0x96C1 # 0 +0x0000E2F3 0x96C5 # 0 +0x0000E2F4 0x96C4 # 0 +0x0000E2F5 0x96C6 # 0 +0x0000E2F6 0x96C7 # 0 +0x0000E2F7 0x96EF # 0 +0x0000E2F8 0x96F2 # 0 +0x0000E2F9 0x97CC # 0 +0x0000E2FA 0x9805 # 0 +0x0000E2FB 0x9806 # 0 +0x0000E2FC 0x9808 # 0 +0x0000E2FD 0x98E7 # 0 +0x0000E2FE 0x98EA # 0 +0x0000E3A1 0x98EF # 0 +0x0000E3A2 0x98E9 # 0 +0x0000E3A3 0x98F2 # 0 +0x0000E3A4 0x98ED # 0 +0x0000E3A5 0x99AE # 0 +0x0000E3A6 0x99AD # 0 +0x0000E3A7 0x9EC3 # 0 +0x0000E3A8 0x9ECD # 0 +0x0000E3A9 0x9ED1 # 0 +0x0000E3AA 0x4E82 # 0 +0x0000E3AB 0x50AD # 0 +0x0000E3AC 0x50B5 # 0 +0x0000E3AD 0x50B2 # 0 +0x0000E3AE 0x50B3 # 0 +0x0000E3AF 0x50C5 # 0 +0x0000E3B0 0x50BE # 0 +0x0000E3B1 0x50AC # 0 +0x0000E3B2 0x50B7 # 0 +0x0000E3B3 0x50BB # 0 +0x0000E3B4 0x50AF # 0 +0x0000E3B5 0x50C7 # 0 +0x0000E3B6 0x527F # 0 +0x0000E3B7 0x5277 # 0 +0x0000E3B8 0x527D # 0 +0x0000E3B9 0x52DF # 0 +0x0000E3BA 0x52E6 # 0 +0x0000E3BB 0x52E4 # 0 +0x0000E3BC 0x52E2 # 0 +0x0000E3BD 0x52E3 # 0 +0x0000E3BE 0x532F # 0 +0x0000E3BF 0x55DF # 0 +0x0000E3C0 0x55E8 # 0 +0x0000E3C1 0x55D3 # 0 +0x0000E3C2 0x55E6 # 0 +0x0000E3C3 0x55CE # 0 +0x0000E3C4 0x55DC # 0 +0x0000E3C5 0x55C7 # 0 +0x0000E3C6 0x55D1 # 0 +0x0000E3C7 0x55E3 # 0 +0x0000E3C8 0x55E4 # 0 +0x0000E3C9 0x55EF # 0 +0x0000E3CA 0x55DA # 0 +0x0000E3CB 0x55E1 # 0 +0x0000E3CC 0x55C5 # 0 +0x0000E3CD 0x55C6 # 0 +0x0000E3CE 0x55E5 # 0 +0x0000E3CF 0x55C9 # 0 +0x0000E3D0 0x5712 # 0 +0x0000E3D1 0x5713 # 0 +0x0000E3D2 0x585E # 0 +0x0000E3D3 0x5851 # 0 +0x0000E3D4 0x5858 # 0 +0x0000E3D5 0x5857 # 0 +0x0000E3D6 0x585A # 0 +0x0000E3D7 0x5854 # 0 +0x0000E3D8 0x586B # 0 +0x0000E3D9 0x584C # 0 +0x0000E3DA 0x586D # 0 +0x0000E3DB 0x584A # 0 +0x0000E3DC 0x5862 # 0 +0x0000E3DD 0x5852 # 0 +0x0000E3DE 0x584B # 0 +0x0000E3DF 0x5967 # 0 +0x0000E3E0 0x5AC1 # 0 +0x0000E3E1 0x5AC9 # 0 +0x0000E3E2 0x5ACC # 0 +0x0000E3E3 0x5ABE # 0 +0x0000E3E4 0x5ABD # 0 +0x0000E3E5 0x5ABC # 0 +0x0000E3E6 0x5AB3 # 0 +0x0000E3E7 0x5AC2 # 0 +0x0000E3E8 0x5AB2 # 0 +0x0000E3E9 0x5D69 # 0 +0x0000E3EA 0x5D6F # 0 +0x0000E3EB 0x5E4C # 0 +0x0000E3EC 0x5E79 # 0 +0x0000E3ED 0x5EC9 # 0 +0x0000E3EE 0x5EC8 # 0 +0x0000E3EF 0x5F12 # 0 +0x0000E3F0 0x5F59 # 0 +0x0000E3F1 0x5FAC # 0 +0x0000E3F2 0x5FAE # 0 +0x0000E3F3 0x611A # 0 +0x0000E3F4 0x610F # 0 +0x0000E3F5 0x6148 # 0 +0x0000E3F6 0x611F # 0 +0x0000E3F7 0x60F3 # 0 +0x0000E3F8 0x611B # 0 +0x0000E3F9 0x60F9 # 0 +0x0000E3FA 0x6101 # 0 +0x0000E3FB 0x6108 # 0 +0x0000E3FC 0x614E # 0 +0x0000E3FD 0x614C # 0 +0x0000E3FE 0x6144 # 0 +0x0000E4A1 0x614D # 0 +0x0000E4A2 0x613E # 0 +0x0000E4A3 0x6134 # 0 +0x0000E4A4 0x6127 # 0 +0x0000E4A5 0x610D # 0 +0x0000E4A6 0x6106 # 0 +0x0000E4A7 0x6137 # 0 +0x0000E4A8 0x6221 # 0 +0x0000E4A9 0x6222 # 0 +0x0000E4AA 0x6413 # 0 +0x0000E4AB 0x643E # 0 +0x0000E4AC 0x641E # 0 +0x0000E4AD 0x642A # 0 +0x0000E4AE 0x642D # 0 +0x0000E4AF 0x643D # 0 +0x0000E4B0 0x642C # 0 +0x0000E4B1 0x640F # 0 +0x0000E4B2 0x641C # 0 +0x0000E4B3 0x6414 # 0 +0x0000E4B4 0x640D # 0 +0x0000E4B5 0x6436 # 0 +0x0000E4B6 0x6416 # 0 +0x0000E4B7 0x6417 # 0 +0x0000E4B8 0x6406 # 0 +0x0000E4B9 0x656C # 0 +0x0000E4BA 0x659F # 0 +0x0000E4BB 0x65B0 # 0 +0x0000E4BC 0x6697 # 0 +0x0000E4BD 0x6689 # 0 +0x0000E4BE 0x6687 # 0 +0x0000E4BF 0x6688 # 0 +0x0000E4C0 0x6696 # 0 +0x0000E4C1 0x6684 # 0 +0x0000E4C2 0x6698 # 0 +0x0000E4C3 0x668D # 0 +0x0000E4C4 0x6703 # 0 +0x0000E4C5 0x6994 # 0 +0x0000E4C6 0x696D # 0 +0x0000E4C7 0x695A # 0 +0x0000E4C8 0x6977 # 0 +0x0000E4C9 0x6960 # 0 +0x0000E4CA 0x6954 # 0 +0x0000E4CB 0x6975 # 0 +0x0000E4CC 0x6930 # 0 +0x0000E4CD 0x6982 # 0 +0x0000E4CE 0x694A # 0 +0x0000E4CF 0x6968 # 0 +0x0000E4D0 0x696B # 0 +0x0000E4D1 0x695E # 0 +0x0000E4D2 0x6953 # 0 +0x0000E4D3 0x6979 # 0 +0x0000E4D4 0x6986 # 0 +0x0000E4D5 0x695D # 0 +0x0000E4D6 0x6963 # 0 +0x0000E4D7 0x695B # 0 +0x0000E4D8 0x6B47 # 0 +0x0000E4D9 0x6B72 # 0 +0x0000E4DA 0x6BC0 # 0 +0x0000E4DB 0x6BBF # 0 +0x0000E4DC 0x6BD3 # 0 +0x0000E4DD 0x6BFD # 0 +0x0000E4DE 0x6EA2 # 0 +0x0000E4DF 0x6EAF # 0 +0x0000E4E0 0x6ED3 # 0 +0x0000E4E1 0x6EB6 # 0 +0x0000E4E2 0x6EC2 # 0 +0x0000E4E3 0x6E90 # 0 +0x0000E4E4 0x6E9D # 0 +0x0000E4E5 0x6EC7 # 0 +0x0000E4E6 0x6EC5 # 0 +0x0000E4E7 0x6EA5 # 0 +0x0000E4E8 0x6E98 # 0 +0x0000E4E9 0x6EBC # 0 +0x0000E4EA 0x6EBA # 0 +0x0000E4EB 0x6EAB # 0 +0x0000E4EC 0x6ED1 # 0 +0x0000E4ED 0x6E96 # 0 +0x0000E4EE 0x6E9C # 0 +0x0000E4EF 0x6EC4 # 0 +0x0000E4F0 0x6ED4 # 0 +0x0000E4F1 0x6EAA # 0 +0x0000E4F2 0x6EA7 # 0 +0x0000E4F3 0x6EB4 # 0 +0x0000E4F4 0x714E # 0 +0x0000E4F5 0x7159 # 0 +0x0000E4F6 0x7169 # 0 +0x0000E4F7 0x7164 # 0 +0x0000E4F8 0x7149 # 0 +0x0000E4F9 0x7167 # 0 +0x0000E4FA 0x715C # 0 +0x0000E4FB 0x716C # 0 +0x0000E4FC 0x7166 # 0 +0x0000E4FD 0x714C # 0 +0x0000E4FE 0x7165 # 0 +0x0000E5A1 0x715E # 0 +0x0000E5A2 0x7146 # 0 +0x0000E5A3 0x7168 # 0 +0x0000E5A4 0x7156 # 0 +0x0000E5A5 0x723A # 0 +0x0000E5A6 0x7252 # 0 +0x0000E5A7 0x7337 # 0 +0x0000E5A8 0x7345 # 0 +0x0000E5A9 0x733F # 0 +0x0000E5AA 0x733E # 0 +0x0000E5AB 0x746F # 0 +0x0000E5AC 0x745A # 0 +0x0000E5AD 0x7455 # 0 +0x0000E5AE 0x745F # 0 +0x0000E5AF 0x745E # 0 +0x0000E5B0 0x7441 # 0 +0x0000E5B1 0x743F # 0 +0x0000E5B2 0x7459 # 0 +0x0000E5B3 0x745B # 0 +0x0000E5B4 0x745C # 0 +0x0000E5B5 0x7576 # 0 +0x0000E5B6 0x7578 # 0 +0x0000E5B7 0x7600 # 0 +0x0000E5B8 0x75F0 # 0 +0x0000E5B9 0x7601 # 0 +0x0000E5BA 0x75F2 # 0 +0x0000E5BB 0x75F1 # 0 +0x0000E5BC 0x75FA # 0 +0x0000E5BD 0x75FF # 0 +0x0000E5BE 0x75F4 # 0 +0x0000E5BF 0x75F3 # 0 +0x0000E5C0 0x76DE # 0 +0x0000E5C1 0x76DF # 0 +0x0000E5C2 0x775B # 0 +0x0000E5C3 0x776B # 0 +0x0000E5C4 0x7766 # 0 +0x0000E5C5 0x775E # 0 +0x0000E5C6 0x7763 # 0 +0x0000E5C7 0x7779 # 0 +0x0000E5C8 0x776A # 0 +0x0000E5C9 0x776C # 0 +0x0000E5CA 0x775C # 0 +0x0000E5CB 0x7765 # 0 +0x0000E5CC 0x7768 # 0 +0x0000E5CD 0x7762 # 0 +0x0000E5CE 0x77EE # 0 +0x0000E5CF 0x788E # 0 +0x0000E5D0 0x78B0 # 0 +0x0000E5D1 0x7897 # 0 +0x0000E5D2 0x7898 # 0 +0x0000E5D3 0x788C # 0 +0x0000E5D4 0x7889 # 0 +0x0000E5D5 0x787C # 0 +0x0000E5D6 0x7891 # 0 +0x0000E5D7 0x7893 # 0 +0x0000E5D8 0x787F # 0 +0x0000E5D9 0x797A # 0 +0x0000E5DA 0x797F # 0 +0x0000E5DB 0x7981 # 0 +0x0000E5DC 0x842C # 0 +0x0000E5DD 0x79BD # 0 +0x0000E5DE 0x7A1C # 0 +0x0000E5DF 0x7A1A # 0 +0x0000E5E0 0x7A20 # 0 +0x0000E5E1 0x7A14 # 0 +0x0000E5E2 0x7A1F # 0 +0x0000E5E3 0x7A1E # 0 +0x0000E5E4 0x7A9F # 0 +0x0000E5E5 0x7AA0 # 0 +0x0000E5E6 0x7B77 # 0 +0x0000E5E7 0x7BC0 # 0 +0x0000E5E8 0x7B60 # 0 +0x0000E5E9 0x7B6E # 0 +0x0000E5EA 0x7B67 # 0 +0x0000E5EB 0x7CB1 # 0 +0x0000E5EC 0x7CB3 # 0 +0x0000E5ED 0x7CB5 # 0 +0x0000E5EE 0x7D93 # 0 +0x0000E5EF 0x7D79 # 0 +0x0000E5F0 0x7D91 # 0 +0x0000E5F1 0x7D81 # 0 +0x0000E5F2 0x7D8F # 0 +0x0000E5F3 0x7D5B # 0 +0x0000E5F4 0x7F6E # 0 +0x0000E5F5 0x7F69 # 0 +0x0000E5F6 0x7F6A # 0 +0x0000E5F7 0x7F72 # 0 +0x0000E5F8 0x7FA9 # 0 +0x0000E5F9 0x7FA8 # 0 +0x0000E5FA 0x7FA4 # 0 +0x0000E5FB 0x8056 # 0 +0x0000E5FC 0x8058 # 0 +0x0000E5FD 0x8086 # 0 +0x0000E5FE 0x8084 # 0 +0x0000E6A1 0x8171 # 0 +0x0000E6A2 0x8170 # 0 +0x0000E6A3 0x8178 # 0 +0x0000E6A4 0x8165 # 0 +0x0000E6A5 0x816E # 0 +0x0000E6A6 0x8173 # 0 +0x0000E6A7 0x816B # 0 +0x0000E6A8 0x8179 # 0 +0x0000E6A9 0x817A # 0 +0x0000E6AA 0x8166 # 0 +0x0000E6AB 0x8205 # 0 +0x0000E6AC 0x8247 # 0 +0x0000E6AD 0x8482 # 0 +0x0000E6AE 0x8477 # 0 +0x0000E6AF 0x843D # 0 +0x0000E6B0 0x8431 # 0 +0x0000E6B1 0x8475 # 0 +0x0000E6B2 0x8466 # 0 +0x0000E6B3 0x846B # 0 +0x0000E6B4 0x8449 # 0 +0x0000E6B5 0x846C # 0 +0x0000E6B6 0x845B # 0 +0x0000E6B7 0x843C # 0 +0x0000E6B8 0x8435 # 0 +0x0000E6B9 0x8461 # 0 +0x0000E6BA 0x8463 # 0 +0x0000E6BB 0x8469 # 0 +0x0000E6BC 0x846D # 0 +0x0000E6BD 0x8446 # 0 +0x0000E6BE 0x865E # 0 +0x0000E6BF 0x865C # 0 +0x0000E6C0 0x865F # 0 +0x0000E6C1 0x86F9 # 0 +0x0000E6C2 0x8713 # 0 +0x0000E6C3 0x8708 # 0 +0x0000E6C4 0x8707 # 0 +0x0000E6C5 0x8700 # 0 +0x0000E6C6 0x86FE # 0 +0x0000E6C7 0x86FB # 0 +0x0000E6C8 0x8702 # 0 +0x0000E6C9 0x8703 # 0 +0x0000E6CA 0x8706 # 0 +0x0000E6CB 0x870A # 0 +0x0000E6CC 0x8859 # 0 +0x0000E6CD 0x88DF # 0 +0x0000E6CE 0x88D4 # 0 +0x0000E6CF 0x88D9 # 0 +0x0000E6D0 0x88DC # 0 +0x0000E6D1 0x88D8 # 0 +0x0000E6D2 0x88DD # 0 +0x0000E6D3 0x88E1 # 0 +0x0000E6D4 0x88CA # 0 +0x0000E6D5 0x88D5 # 0 +0x0000E6D6 0x88D2 # 0 +0x0000E6D7 0x899C # 0 +0x0000E6D8 0x89E3 # 0 +0x0000E6D9 0x8A6B # 0 +0x0000E6DA 0x8A72 # 0 +0x0000E6DB 0x8A73 # 0 +0x0000E6DC 0x8A66 # 0 +0x0000E6DD 0x8A69 # 0 +0x0000E6DE 0x8A70 # 0 +0x0000E6DF 0x8A87 # 0 +0x0000E6E0 0x8A7C # 0 +0x0000E6E1 0x8A63 # 0 +0x0000E6E2 0x8AA0 # 0 +0x0000E6E3 0x8A71 # 0 +0x0000E6E4 0x8A85 # 0 +0x0000E6E5 0x8A6D # 0 +0x0000E6E6 0x8A62 # 0 +0x0000E6E7 0x8A6E # 0 +0x0000E6E8 0x8A6C # 0 +0x0000E6E9 0x8A79 # 0 +0x0000E6EA 0x8A7B # 0 +0x0000E6EB 0x8A3E # 0 +0x0000E6EC 0x8A68 # 0 +0x0000E6ED 0x8C62 # 0 +0x0000E6EE 0x8C8A # 0 +0x0000E6EF 0x8C89 # 0 +0x0000E6F0 0x8CCA # 0 +0x0000E6F1 0x8CC7 # 0 +0x0000E6F2 0x8CC8 # 0 +0x0000E6F3 0x8CC4 # 0 +0x0000E6F4 0x8CB2 # 0 +0x0000E6F5 0x8CC3 # 0 +0x0000E6F6 0x8CC2 # 0 +0x0000E6F7 0x8CC5 # 0 +0x0000E6F8 0x8DE1 # 0 +0x0000E6F9 0x8DDF # 0 +0x0000E6FA 0x8DE8 # 0 +0x0000E6FB 0x8DEF # 0 +0x0000E6FC 0x8DF3 # 0 +0x0000E6FD 0x8DFA # 0 +0x0000E6FE 0x8DEA # 0 +0x0000E7A1 0x8DE4 # 0 +0x0000E7A2 0x8DE6 # 0 +0x0000E7A3 0x8EB2 # 0 +0x0000E7A4 0x8F03 # 0 +0x0000E7A5 0x8F09 # 0 +0x0000E7A6 0x8EFE # 0 +0x0000E7A7 0x8F0A # 0 +0x0000E7A8 0x8F9F # 0 +0x0000E7A9 0x8FB2 # 0 +0x0000E7AA 0x904B # 0 +0x0000E7AB 0x904A # 0 +0x0000E7AC 0x9053 # 0 +0x0000E7AD 0x9042 # 0 +0x0000E7AE 0x9054 # 0 +0x0000E7AF 0x903C # 0 +0x0000E7B0 0x9055 # 0 +0x0000E7B1 0x9050 # 0 +0x0000E7B2 0x9047 # 0 +0x0000E7B3 0x904F # 0 +0x0000E7B4 0x904E # 0 +0x0000E7B5 0x904D # 0 +0x0000E7B6 0x9051 # 0 +0x0000E7B7 0x903E # 0 +0x0000E7B8 0x9041 # 0 +0x0000E7B9 0x9112 # 0 +0x0000E7BA 0x9117 # 0 +0x0000E7BB 0x916C # 0 +0x0000E7BC 0x916A # 0 +0x0000E7BD 0x9169 # 0 +0x0000E7BE 0x91C9 # 0 +0x0000E7BF 0x9237 # 0 +0x0000E7C0 0x9257 # 0 +0x0000E7C1 0x9238 # 0 +0x0000E7C2 0x923D # 0 +0x0000E7C3 0x9240 # 0 +0x0000E7C4 0x923E # 0 +0x0000E7C5 0x925B # 0 +0x0000E7C6 0x924B # 0 +0x0000E7C7 0x9264 # 0 +0x0000E7C8 0x9251 # 0 +0x0000E7C9 0x9234 # 0 +0x0000E7CA 0x9249 # 0 +0x0000E7CB 0x924D # 0 +0x0000E7CC 0x9245 # 0 +0x0000E7CD 0x9239 # 0 +0x0000E7CE 0x923F # 0 +0x0000E7CF 0x925A # 0 +0x0000E7D0 0x9598 # 0 +0x0000E7D1 0x9698 # 0 +0x0000E7D2 0x9694 # 0 +0x0000E7D3 0x9695 # 0 +0x0000E7D4 0x96CD # 0 +0x0000E7D5 0x96CB # 0 +0x0000E7D6 0x96C9 # 0 +0x0000E7D7 0x96CA # 0 +0x0000E7D8 0x96F7 # 0 +0x0000E7D9 0x96FB # 0 +0x0000E7DA 0x96F9 # 0 +0x0000E7DB 0x96F6 # 0 +0x0000E7DC 0x9756 # 0 +0x0000E7DD 0x9774 # 0 +0x0000E7DE 0x9776 # 0 +0x0000E7DF 0x9810 # 0 +0x0000E7E0 0x9811 # 0 +0x0000E7E1 0x9813 # 0 +0x0000E7E2 0x980A # 0 +0x0000E7E3 0x9812 # 0 +0x0000E7E4 0x980C # 0 +0x0000E7E5 0x98FC # 0 +0x0000E7E6 0x98F4 # 0 +0x0000E7E7 0x98FD # 0 +0x0000E7E8 0x98FE # 0 +0x0000E7E9 0x99B3 # 0 +0x0000E7EA 0x99B1 # 0 +0x0000E7EB 0x99B4 # 0 +0x0000E7EC 0x9AE1 # 0 +0x0000E7ED 0x9CE9 # 0 +0x0000E7EE 0x9E82 # 0 +0x0000E7EF 0x9F0E # 0 +0x0000E7F0 0x9F13 # 0 +0x0000E7F1 0x9F20 # 0 +0x0000E7F2 0x50E7 # 0 +0x0000E7F3 0x50EE # 0 +0x0000E7F4 0x50E5 # 0 +0x0000E7F5 0x50D6 # 0 +0x0000E7F6 0x50ED # 0 +0x0000E7F7 0x50DA # 0 +0x0000E7F8 0x50D5 # 0 +0x0000E7F9 0x50CF # 0 +0x0000E7FA 0x50D1 # 0 +0x0000E7FB 0x50F1 # 0 +0x0000E7FC 0x50CE # 0 +0x0000E7FD 0x50E9 # 0 +0x0000E7FE 0x5162 # 0 +0x0000E8A1 0x51F3 # 0 +0x0000E8A2 0x5283 # 0 +0x0000E8A3 0x5282 # 0 +0x0000E8A4 0x5331 # 0 +0x0000E8A5 0x53AD # 0 +0x0000E8A6 0x55FE # 0 +0x0000E8A7 0x5600 # 0 +0x0000E8A8 0x561B # 0 +0x0000E8A9 0x5617 # 0 +0x0000E8AA 0x55FD # 0 +0x0000E8AB 0x5614 # 0 +0x0000E8AC 0x5606 # 0 +0x0000E8AD 0x5609 # 0 +0x0000E8AE 0x560D # 0 +0x0000E8AF 0x560E # 0 +0x0000E8B0 0x55F7 # 0 +0x0000E8B1 0x5616 # 0 +0x0000E8B2 0x561F # 0 +0x0000E8B3 0x5608 # 0 +0x0000E8B4 0x5610 # 0 +0x0000E8B5 0x55F6 # 0 +0x0000E8B6 0x5718 # 0 +0x0000E8B7 0x5716 # 0 +0x0000E8B8 0x5875 # 0 +0x0000E8B9 0x587E # 0 +0x0000E8BA 0x5883 # 0 +0x0000E8BB 0x5893 # 0 +0x0000E8BC 0x588A # 0 +0x0000E8BD 0x5879 # 0 +0x0000E8BE 0x5885 # 0 +0x0000E8BF 0x587D # 0 +0x0000E8C0 0x58FD # 0 +0x0000E8C1 0x5925 # 0 +0x0000E8C2 0x5922 # 0 +0x0000E8C3 0x5924 # 0 +0x0000E8C4 0x596A # 0 +0x0000E8C5 0x5969 # 0 +0x0000E8C6 0x5AE1 # 0 +0x0000E8C7 0x5AE6 # 0 +0x0000E8C8 0x5AE9 # 0 +0x0000E8C9 0x5AD7 # 0 +0x0000E8CA 0x5AD6 # 0 +0x0000E8CB 0x5AD8 # 0 +0x0000E8CC 0x5AE3 # 0 +0x0000E8CD 0x5B75 # 0 +0x0000E8CE 0x5BDE # 0 +0x0000E8CF 0x5BE7 # 0 +0x0000E8D0 0x5BE1 # 0 +0x0000E8D1 0x5BE5 # 0 +0x0000E8D2 0x5BE6 # 0 +0x0000E8D3 0x5BE8 # 0 +0x0000E8D4 0x5BE2 # 0 +0x0000E8D5 0x5BE4 # 0 +0x0000E8D6 0x5BDF # 0 +0x0000E8D7 0x5C0D # 0 +0x0000E8D8 0x5C62 # 0 +0x0000E8D9 0x5D84 # 0 +0x0000E8DA 0x5D87 # 0 +0x0000E8DB 0x5E5B # 0 +0x0000E8DC 0x5E63 # 0 +0x0000E8DD 0x5E55 # 0 +0x0000E8DE 0x5E57 # 0 +0x0000E8DF 0x5E54 # 0 +0x0000E8E0 0x5ED3 # 0 +0x0000E8E1 0x5ED6 # 0 +0x0000E8E2 0x5F0A # 0 +0x0000E8E3 0x5F46 # 0 +0x0000E8E4 0x5F70 # 0 +0x0000E8E5 0x5FB9 # 0 +0x0000E8E6 0x6147 # 0 +0x0000E8E7 0x613F # 0 +0x0000E8E8 0x614B # 0 +0x0000E8E9 0x6177 # 0 +0x0000E8EA 0x6162 # 0 +0x0000E8EB 0x6163 # 0 +0x0000E8EC 0x615F # 0 +0x0000E8ED 0x615A # 0 +0x0000E8EE 0x6158 # 0 +0x0000E8EF 0x6175 # 0 +0x0000E8F0 0x622A # 0 +0x0000E8F1 0x6487 # 0 +0x0000E8F2 0x6458 # 0 +0x0000E8F3 0x6454 # 0 +0x0000E8F4 0x64A4 # 0 +0x0000E8F5 0x6478 # 0 +0x0000E8F6 0x645F # 0 +0x0000E8F7 0x647A # 0 +0x0000E8F8 0x6451 # 0 +0x0000E8F9 0x6467 # 0 +0x0000E8FA 0x6434 # 0 +0x0000E8FB 0x646D # 0 +0x0000E8FC 0x647B # 0 +0x0000E8FD 0x6572 # 0 +0x0000E8FE 0x65A1 # 0 +0x0000E9A1 0x65D7 # 0 +0x0000E9A2 0x65D6 # 0 +0x0000E9A3 0x66A2 # 0 +0x0000E9A4 0x66A8 # 0 +0x0000E9A5 0x669D # 0 +0x0000E9A6 0x699C # 0 +0x0000E9A7 0x69A8 # 0 +0x0000E9A8 0x6995 # 0 +0x0000E9A9 0x69C1 # 0 +0x0000E9AA 0x69AE # 0 +0x0000E9AB 0x69D3 # 0 +0x0000E9AC 0x69CB # 0 +0x0000E9AD 0x699B # 0 +0x0000E9AE 0x69B7 # 0 +0x0000E9AF 0x69BB # 0 +0x0000E9B0 0x69AB # 0 +0x0000E9B1 0x69B4 # 0 +0x0000E9B2 0x69D0 # 0 +0x0000E9B3 0x69CD # 0 +0x0000E9B4 0x69AD # 0 +0x0000E9B5 0x69CC # 0 +0x0000E9B6 0x69A6 # 0 +0x0000E9B7 0x69C3 # 0 +0x0000E9B8 0x69A3 # 0 +0x0000E9B9 0x6B49 # 0 +0x0000E9BA 0x6B4C # 0 +0x0000E9BB 0x6C33 # 0 +0x0000E9BC 0x6F33 # 0 +0x0000E9BD 0x6F14 # 0 +0x0000E9BE 0x6EFE # 0 +0x0000E9BF 0x6F13 # 0 +0x0000E9C0 0x6EF4 # 0 +0x0000E9C1 0x6F29 # 0 +0x0000E9C2 0x6F3E # 0 +0x0000E9C3 0x6F20 # 0 +0x0000E9C4 0x6F2C # 0 +0x0000E9C5 0x6F0F # 0 +0x0000E9C6 0x6F02 # 0 +0x0000E9C7 0x6F22 # 0 +0x0000E9C8 0x6EFF # 0 +0x0000E9C9 0x6EEF # 0 +0x0000E9CA 0x6F06 # 0 +0x0000E9CB 0x6F31 # 0 +0x0000E9CC 0x6F38 # 0 +0x0000E9CD 0x6F32 # 0 +0x0000E9CE 0x6F23 # 0 +0x0000E9CF 0x6F15 # 0 +0x0000E9D0 0x6F2B # 0 +0x0000E9D1 0x6F2F # 0 +0x0000E9D2 0x6F88 # 0 +0x0000E9D3 0x6F2A # 0 +0x0000E9D4 0x6EEC # 0 +0x0000E9D5 0x6F01 # 0 +0x0000E9D6 0x6EF2 # 0 +0x0000E9D7 0x6ECC # 0 +0x0000E9D8 0x6EF7 # 0 +0x0000E9D9 0x7194 # 0 +0x0000E9DA 0x7199 # 0 +0x0000E9DB 0x717D # 0 +0x0000E9DC 0x718A # 0 +0x0000E9DD 0x7184 # 0 +0x0000E9DE 0x7192 # 0 +0x0000E9DF 0x723E # 0 +0x0000E9E0 0x7292 # 0 +0x0000E9E1 0x7296 # 0 +0x0000E9E2 0x7344 # 0 +0x0000E9E3 0x7350 # 0 +0x0000E9E4 0x7464 # 0 +0x0000E9E5 0x7463 # 0 +0x0000E9E6 0x746A # 0 +0x0000E9E7 0x7470 # 0 +0x0000E9E8 0x746D # 0 +0x0000E9E9 0x7504 # 0 +0x0000E9EA 0x7591 # 0 +0x0000E9EB 0x7627 # 0 +0x0000E9EC 0x760D # 0 +0x0000E9ED 0x760B # 0 +0x0000E9EE 0x7609 # 0 +0x0000E9EF 0x7613 # 0 +0x0000E9F0 0x76E1 # 0 +0x0000E9F1 0x76E3 # 0 +0x0000E9F2 0x7784 # 0 +0x0000E9F3 0x777D # 0 +0x0000E9F4 0x777F # 0 +0x0000E9F5 0x7761 # 0 +0x0000E9F6 0x78C1 # 0 +0x0000E9F7 0x789F # 0 +0x0000E9F8 0x78A7 # 0 +0x0000E9F9 0x78B3 # 0 +0x0000E9FA 0x78A9 # 0 +0x0000E9FB 0x78A3 # 0 +0x0000E9FC 0x798E # 0 +0x0000E9FD 0x798F # 0 +0x0000E9FE 0x798D # 0 +0x0000EAA1 0x7A2E # 0 +0x0000EAA2 0x7A31 # 0 +0x0000EAA3 0x7AAA # 0 +0x0000EAA4 0x7AA9 # 0 +0x0000EAA5 0x7AED # 0 +0x0000EAA6 0x7AEF # 0 +0x0000EAA7 0x7BA1 # 0 +0x0000EAA8 0x7B95 # 0 +0x0000EAA9 0x7B8B # 0 +0x0000EAAA 0x7B75 # 0 +0x0000EAAB 0x7B97 # 0 +0x0000EAAC 0x7B9D # 0 +0x0000EAAD 0x7B94 # 0 +0x0000EAAE 0x7B8F # 0 +0x0000EAAF 0x7BB8 # 0 +0x0000EAB0 0x7B87 # 0 +0x0000EAB1 0x7B84 # 0 +0x0000EAB2 0x7CB9 # 0 +0x0000EAB3 0x7CBD # 0 +0x0000EAB4 0x7CBE # 0 +0x0000EAB5 0x7DBB # 0 +0x0000EAB6 0x7DB0 # 0 +0x0000EAB7 0x7D9C # 0 +0x0000EAB8 0x7DBD # 0 +0x0000EAB9 0x7DBE # 0 +0x0000EABA 0x7DA0 # 0 +0x0000EABB 0x7DCA # 0 +0x0000EABC 0x7DB4 # 0 +0x0000EABD 0x7DB2 # 0 +0x0000EABE 0x7DB1 # 0 +0x0000EABF 0x7DBA # 0 +0x0000EAC0 0x7DA2 # 0 +0x0000EAC1 0x7DBF # 0 +0x0000EAC2 0x7DB5 # 0 +0x0000EAC3 0x7DB8 # 0 +0x0000EAC4 0x7DAD # 0 +0x0000EAC5 0x7DD2 # 0 +0x0000EAC6 0x7DC7 # 0 +0x0000EAC7 0x7DAC # 0 +0x0000EAC8 0x7F70 # 0 +0x0000EAC9 0x7FE0 # 0 +0x0000EACA 0x7FE1 # 0 +0x0000EACB 0x7FDF # 0 +0x0000EACC 0x805E # 0 +0x0000EACD 0x805A # 0 +0x0000EACE 0x8087 # 0 +0x0000EACF 0x8150 # 0 +0x0000EAD0 0x8180 # 0 +0x0000EAD1 0x818F # 0 +0x0000EAD2 0x8188 # 0 +0x0000EAD3 0x818A # 0 +0x0000EAD4 0x817F # 0 +0x0000EAD5 0x8182 # 0 +0x0000EAD6 0x81E7 # 0 +0x0000EAD7 0x81FA # 0 +0x0000EAD8 0x8207 # 0 +0x0000EAD9 0x8214 # 0 +0x0000EADA 0x821E # 0 +0x0000EADB 0x824B # 0 +0x0000EADC 0x84C9 # 0 +0x0000EADD 0x84BF # 0 +0x0000EADE 0x84C6 # 0 +0x0000EADF 0x84C4 # 0 +0x0000EAE0 0x8499 # 0 +0x0000EAE1 0x849E # 0 +0x0000EAE2 0x84B2 # 0 +0x0000EAE3 0x849C # 0 +0x0000EAE4 0x84CB # 0 +0x0000EAE5 0x84B8 # 0 +0x0000EAE6 0x84C0 # 0 +0x0000EAE7 0x84D3 # 0 +0x0000EAE8 0x8490 # 0 +0x0000EAE9 0x84BC # 0 +0x0000EAEA 0x84D1 # 0 +0x0000EAEB 0x84CA # 0 +0x0000EAEC 0x873F # 0 +0x0000EAED 0x871C # 0 +0x0000EAEE 0x873B # 0 +0x0000EAEF 0x8722 # 0 +0x0000EAF0 0x8725 # 0 +0x0000EAF1 0x8734 # 0 +0x0000EAF2 0x8718 # 0 +0x0000EAF3 0x8755 # 0 +0x0000EAF4 0x8737 # 0 +0x0000EAF5 0x8729 # 0 +0x0000EAF6 0x88F3 # 0 +0x0000EAF7 0x8902 # 0 +0x0000EAF8 0x88F4 # 0 +0x0000EAF9 0x88F9 # 0 +0x0000EAFA 0x88F8 # 0 +0x0000EAFB 0x88FD # 0 +0x0000EAFC 0x88E8 # 0 +0x0000EAFD 0x891A # 0 +0x0000EAFE 0x88EF # 0 +0x0000EBA1 0x8AA6 # 0 +0x0000EBA2 0x8A8C # 0 +0x0000EBA3 0x8A9E # 0 +0x0000EBA4 0x8AA3 # 0 +0x0000EBA5 0x8A8D # 0 +0x0000EBA6 0x8AA1 # 0 +0x0000EBA7 0x8A93 # 0 +0x0000EBA8 0x8AA4 # 0 +0x0000EBA9 0x8AAA # 0 +0x0000EBAA 0x8AA5 # 0 +0x0000EBAB 0x8AA8 # 0 +0x0000EBAC 0x8A98 # 0 +0x0000EBAD 0x8A91 # 0 +0x0000EBAE 0x8A9A # 0 +0x0000EBAF 0x8AA7 # 0 +0x0000EBB0 0x8C6A # 0 +0x0000EBB1 0x8C8D # 0 +0x0000EBB2 0x8C8C # 0 +0x0000EBB3 0x8CD3 # 0 +0x0000EBB4 0x8CD1 # 0 +0x0000EBB5 0x8CD2 # 0 +0x0000EBB6 0x8D6B # 0 +0x0000EBB7 0x8D99 # 0 +0x0000EBB8 0x8D95 # 0 +0x0000EBB9 0x8DFC # 0 +0x0000EBBA 0x8F14 # 0 +0x0000EBBB 0x8F12 # 0 +0x0000EBBC 0x8F15 # 0 +0x0000EBBD 0x8F13 # 0 +0x0000EBBE 0x8FA3 # 0 +0x0000EBBF 0x9060 # 0 +0x0000EBC0 0x9058 # 0 +0x0000EBC1 0x905C # 0 +0x0000EBC2 0x9063 # 0 +0x0000EBC3 0x9059 # 0 +0x0000EBC4 0x905E # 0 +0x0000EBC5 0x9062 # 0 +0x0000EBC6 0x905D # 0 +0x0000EBC7 0x905B # 0 +0x0000EBC8 0x9119 # 0 +0x0000EBC9 0x9118 # 0 +0x0000EBCA 0x911E # 0 +0x0000EBCB 0x9175 # 0 +0x0000EBCC 0x9178 # 0 +0x0000EBCD 0x9177 # 0 +0x0000EBCE 0x9174 # 0 +0x0000EBCF 0x9278 # 0 +0x0000EBD0 0x92AC # 0 +0x0000EBD1 0x9280 # 0 +0x0000EBD2 0x9285 # 0 +0x0000EBD3 0x9298 # 0 +0x0000EBD4 0x9296 # 0 +0x0000EBD5 0x927B # 0 +0x0000EBD6 0x9293 # 0 +0x0000EBD7 0x929C # 0 +0x0000EBD8 0x92A8 # 0 +0x0000EBD9 0x927C # 0 +0x0000EBDA 0x9291 # 0 +0x0000EBDB 0x95A1 # 0 +0x0000EBDC 0x95A8 # 0 +0x0000EBDD 0x95A9 # 0 +0x0000EBDE 0x95A3 # 0 +0x0000EBDF 0x95A5 # 0 +0x0000EBE0 0x95A4 # 0 +0x0000EBE1 0x9699 # 0 +0x0000EBE2 0x969C # 0 +0x0000EBE3 0x969B # 0 +0x0000EBE4 0x96CC # 0 +0x0000EBE5 0x96D2 # 0 +0x0000EBE6 0x9700 # 0 +0x0000EBE7 0x977C # 0 +0x0000EBE8 0x9785 # 0 +0x0000EBE9 0x97F6 # 0 +0x0000EBEA 0x9817 # 0 +0x0000EBEB 0x9818 # 0 +0x0000EBEC 0x98AF # 0 +0x0000EBED 0x98B1 # 0 +0x0000EBEE 0x9903 # 0 +0x0000EBEF 0x9905 # 0 +0x0000EBF0 0x990C # 0 +0x0000EBF1 0x9909 # 0 +0x0000EBF2 0x99C1 # 0 +0x0000EBF3 0x9AAF # 0 +0x0000EBF4 0x9AB0 # 0 +0x0000EBF5 0x9AE6 # 0 +0x0000EBF6 0x9B41 # 0 +0x0000EBF7 0x9B42 # 0 +0x0000EBF8 0x9CF4 # 0 +0x0000EBF9 0x9CF6 # 0 +0x0000EBFA 0x9CF3 # 0 +0x0000EBFB 0x9EBC # 0 +0x0000EBFC 0x9F3B # 0 +0x0000EBFD 0x9F4A # 0 +0x0000EBFE 0x5104 # 0 +0x0000ECA1 0x5100 # 0 +0x0000ECA2 0x50FB # 0 +0x0000ECA3 0x50F5 # 0 +0x0000ECA4 0x50F9 # 0 +0x0000ECA5 0x5102 # 0 +0x0000ECA6 0x5108 # 0 +0x0000ECA7 0x5109 # 0 +0x0000ECA8 0x5105 # 0 +0x0000ECA9 0x51DC # 0 +0x0000ECAA 0x5287 # 0 +0x0000ECAB 0x5288 # 0 +0x0000ECAC 0x5289 # 0 +0x0000ECAD 0x528D # 0 +0x0000ECAE 0x528A # 0 +0x0000ECAF 0x52F0 # 0 +0x0000ECB0 0x53B2 # 0 +0x0000ECB1 0x562E # 0 +0x0000ECB2 0x563B # 0 +0x0000ECB3 0x5639 # 0 +0x0000ECB4 0x5632 # 0 +0x0000ECB5 0x563F # 0 +0x0000ECB6 0x5634 # 0 +0x0000ECB7 0x5629 # 0 +0x0000ECB8 0x5653 # 0 +0x0000ECB9 0x564E # 0 +0x0000ECBA 0x5657 # 0 +0x0000ECBB 0x5674 # 0 +0x0000ECBC 0x5636 # 0 +0x0000ECBD 0x562F # 0 +0x0000ECBE 0x5630 # 0 +0x0000ECBF 0x5880 # 0 +0x0000ECC0 0x589F # 0 +0x0000ECC1 0x589E # 0 +0x0000ECC2 0x58B3 # 0 +0x0000ECC3 0x589C # 0 +0x0000ECC4 0x58AE # 0 +0x0000ECC5 0x58A9 # 0 +0x0000ECC6 0x58A6 # 0 +0x0000ECC7 0x596D # 0 +0x0000ECC8 0x5B09 # 0 +0x0000ECC9 0x5AFB # 0 +0x0000ECCA 0x5B0B # 0 +0x0000ECCB 0x5AF5 # 0 +0x0000ECCC 0x5B0C # 0 +0x0000ECCD 0x5B08 # 0 +0x0000ECCE 0x5BEE # 0 +0x0000ECCF 0x5BEC # 0 +0x0000ECD0 0x5BE9 # 0 +0x0000ECD1 0x5BEB # 0 +0x0000ECD2 0x5C64 # 0 +0x0000ECD3 0x5C65 # 0 +0x0000ECD4 0x5D9D # 0 +0x0000ECD5 0x5D94 # 0 +0x0000ECD6 0x5E62 # 0 +0x0000ECD7 0x5E5F # 0 +0x0000ECD8 0x5E61 # 0 +0x0000ECD9 0x5EE2 # 0 +0x0000ECDA 0x5EDA # 0 +0x0000ECDB 0x5EDF # 0 +0x0000ECDC 0x5EDD # 0 +0x0000ECDD 0x5EE3 # 0 +0x0000ECDE 0x5EE0 # 0 +0x0000ECDF 0x5F48 # 0 +0x0000ECE0 0x5F71 # 0 +0x0000ECE1 0x5FB7 # 0 +0x0000ECE2 0x5FB5 # 0 +0x0000ECE3 0x6176 # 0 +0x0000ECE4 0x6167 # 0 +0x0000ECE5 0x616E # 0 +0x0000ECE6 0x615D # 0 +0x0000ECE7 0x6155 # 0 +0x0000ECE8 0x6182 # 0 +0x0000ECE9 0x617C # 0 +0x0000ECEA 0x6170 # 0 +0x0000ECEB 0x616B # 0 +0x0000ECEC 0x617E # 0 +0x0000ECED 0x61A7 # 0 +0x0000ECEE 0x6190 # 0 +0x0000ECEF 0x61AB # 0 +0x0000ECF0 0x618E # 0 +0x0000ECF1 0x61AC # 0 +0x0000ECF2 0x619A # 0 +0x0000ECF3 0x61A4 # 0 +0x0000ECF4 0x6194 # 0 +0x0000ECF5 0x61AE # 0 +0x0000ECF6 0x622E # 0 +0x0000ECF7 0x6469 # 0 +0x0000ECF8 0x646F # 0 +0x0000ECF9 0x6479 # 0 +0x0000ECFA 0x649E # 0 +0x0000ECFB 0x64B2 # 0 +0x0000ECFC 0x6488 # 0 +0x0000ECFD 0x6490 # 0 +0x0000ECFE 0x64B0 # 0 +0x0000EDA1 0x64A5 # 0 +0x0000EDA2 0x6493 # 0 +0x0000EDA3 0x6495 # 0 +0x0000EDA4 0x64A9 # 0 +0x0000EDA5 0x6492 # 0 +0x0000EDA6 0x64AE # 0 +0x0000EDA7 0x64AD # 0 +0x0000EDA8 0x64AB # 0 +0x0000EDA9 0x649A # 0 +0x0000EDAA 0x64AC # 0 +0x0000EDAB 0x6499 # 0 +0x0000EDAC 0x64A2 # 0 +0x0000EDAD 0x64B3 # 0 +0x0000EDAE 0x6575 # 0 +0x0000EDAF 0x6577 # 0 +0x0000EDB0 0x6578 # 0 +0x0000EDB1 0x66AE # 0 +0x0000EDB2 0x66AB # 0 +0x0000EDB3 0x66B4 # 0 +0x0000EDB4 0x66B1 # 0 +0x0000EDB5 0x6A23 # 0 +0x0000EDB6 0x6A1F # 0 +0x0000EDB7 0x69E8 # 0 +0x0000EDB8 0x6A01 # 0 +0x0000EDB9 0x6A1E # 0 +0x0000EDBA 0x6A19 # 0 +0x0000EDBB 0x69FD # 0 +0x0000EDBC 0x6A21 # 0 +0x0000EDBD 0x6A13 # 0 +0x0000EDBE 0x6A0A # 0 +0x0000EDBF 0x69F3 # 0 +0x0000EDC0 0x6A02 # 0 +0x0000EDC1 0x6A05 # 0 +0x0000EDC2 0x69ED # 0 +0x0000EDC3 0x6A11 # 0 +0x0000EDC4 0x6B50 # 0 +0x0000EDC5 0x6B4E # 0 +0x0000EDC6 0x6BA4 # 0 +0x0000EDC7 0x6BC5 # 0 +0x0000EDC8 0x6BC6 # 0 +0x0000EDC9 0x6F3F # 0 +0x0000EDCA 0x6F7C # 0 +0x0000EDCB 0x6F84 # 0 +0x0000EDCC 0x6F51 # 0 +0x0000EDCD 0x6F66 # 0 +0x0000EDCE 0x6F54 # 0 +0x0000EDCF 0x6F86 # 0 +0x0000EDD0 0x6F6D # 0 +0x0000EDD1 0x6F5B # 0 +0x0000EDD2 0x6F78 # 0 +0x0000EDD3 0x6F6E # 0 +0x0000EDD4 0x6F8E # 0 +0x0000EDD5 0x6F7A # 0 +0x0000EDD6 0x6F70 # 0 +0x0000EDD7 0x6F64 # 0 +0x0000EDD8 0x6F97 # 0 +0x0000EDD9 0x6F58 # 0 +0x0000EDDA 0x6ED5 # 0 +0x0000EDDB 0x6F6F # 0 +0x0000EDDC 0x6F60 # 0 +0x0000EDDD 0x6F5F # 0 +0x0000EDDE 0x719F # 0 +0x0000EDDF 0x71AC # 0 +0x0000EDE0 0x71B1 # 0 +0x0000EDE1 0x71A8 # 0 +0x0000EDE2 0x7256 # 0 +0x0000EDE3 0x729B # 0 +0x0000EDE4 0x734E # 0 +0x0000EDE5 0x7357 # 0 +0x0000EDE6 0x7469 # 0 +0x0000EDE7 0x748B # 0 +0x0000EDE8 0x7483 # 0 +0x0000EDE9 0x747E # 0 +0x0000EDEA 0x7480 # 0 +0x0000EDEB 0x757F # 0 +0x0000EDEC 0x7620 # 0 +0x0000EDED 0x7629 # 0 +0x0000EDEE 0x761F # 0 +0x0000EDEF 0x7624 # 0 +0x0000EDF0 0x7626 # 0 +0x0000EDF1 0x7621 # 0 +0x0000EDF2 0x7622 # 0 +0x0000EDF3 0x769A # 0 +0x0000EDF4 0x76BA # 0 +0x0000EDF5 0x76E4 # 0 +0x0000EDF6 0x778E # 0 +0x0000EDF7 0x7787 # 0 +0x0000EDF8 0x778C # 0 +0x0000EDF9 0x7791 # 0 +0x0000EDFA 0x778B # 0 +0x0000EDFB 0x78CB # 0 +0x0000EDFC 0x78C5 # 0 +0x0000EDFD 0x78BA # 0 +0x0000EDFE 0x78CA # 0 +0x0000EEA1 0x78BE # 0 +0x0000EEA2 0x78D5 # 0 +0x0000EEA3 0x78BC # 0 +0x0000EEA4 0x78D0 # 0 +0x0000EEA5 0x7A3F # 0 +0x0000EEA6 0x7A3C # 0 +0x0000EEA7 0x7A40 # 0 +0x0000EEA8 0x7A3D # 0 +0x0000EEA9 0x7A37 # 0 +0x0000EEAA 0x7A3B # 0 +0x0000EEAB 0x7AAF # 0 +0x0000EEAC 0x7AAE # 0 +0x0000EEAD 0x7BAD # 0 +0x0000EEAE 0x7BB1 # 0 +0x0000EEAF 0x7BC4 # 0 +0x0000EEB0 0x7BB4 # 0 +0x0000EEB1 0x7BC6 # 0 +0x0000EEB2 0x7BC7 # 0 +0x0000EEB3 0x7BC1 # 0 +0x0000EEB4 0x7BA0 # 0 +0x0000EEB5 0x7BCC # 0 +0x0000EEB6 0x7CCA # 0 +0x0000EEB7 0x7DE0 # 0 +0x0000EEB8 0x7DF4 # 0 +0x0000EEB9 0x7DEF # 0 +0x0000EEBA 0x7DFB # 0 +0x0000EEBB 0x7DD8 # 0 +0x0000EEBC 0x7DEC # 0 +0x0000EEBD 0x7DDD # 0 +0x0000EEBE 0x7DE8 # 0 +0x0000EEBF 0x7DE3 # 0 +0x0000EEC0 0x7DDA # 0 +0x0000EEC1 0x7DDE # 0 +0x0000EEC2 0x7DE9 # 0 +0x0000EEC3 0x7D9E # 0 +0x0000EEC4 0x7DD9 # 0 +0x0000EEC5 0x7DF2 # 0 +0x0000EEC6 0x7DF9 # 0 +0x0000EEC7 0x7F75 # 0 +0x0000EEC8 0x7F77 # 0 +0x0000EEC9 0x7FAF # 0 +0x0000EECA 0x7FE9 # 0 +0x0000EECB 0x8026 # 0 +0x0000EECC 0x819B # 0 +0x0000EECD 0x819C # 0 +0x0000EECE 0x819D # 0 +0x0000EECF 0x81A0 # 0 +0x0000EED0 0x819A # 0 +0x0000EED1 0x8198 # 0 +0x0000EED2 0x8517 # 0 +0x0000EED3 0x853D # 0 +0x0000EED4 0x851A # 0 +0x0000EED5 0x84EE # 0 +0x0000EED6 0x852C # 0 +0x0000EED7 0x852D # 0 +0x0000EED8 0x8513 # 0 +0x0000EED9 0x8511 # 0 +0x0000EEDA 0x8523 # 0 +0x0000EEDB 0x8521 # 0 +0x0000EEDC 0x8514 # 0 +0x0000EEDD 0x84EC # 0 +0x0000EEDE 0x8525 # 0 +0x0000EEDF 0x84FF # 0 +0x0000EEE0 0x8506 # 0 +0x0000EEE1 0x8782 # 0 +0x0000EEE2 0x8774 # 0 +0x0000EEE3 0x8776 # 0 +0x0000EEE4 0x8760 # 0 +0x0000EEE5 0x8766 # 0 +0x0000EEE6 0x8778 # 0 +0x0000EEE7 0x8768 # 0 +0x0000EEE8 0x8759 # 0 +0x0000EEE9 0x8757 # 0 +0x0000EEEA 0x874C # 0 +0x0000EEEB 0x8753 # 0 +0x0000EEEC 0x885B # 0 +0x0000EEED 0x885D # 0 +0x0000EEEE 0x8910 # 0 +0x0000EEEF 0x8907 # 0 +0x0000EEF0 0x8912 # 0 +0x0000EEF1 0x8913 # 0 +0x0000EEF2 0x8915 # 0 +0x0000EEF3 0x890A # 0 +0x0000EEF4 0x8ABC # 0 +0x0000EEF5 0x8AD2 # 0 +0x0000EEF6 0x8AC7 # 0 +0x0000EEF7 0x8AC4 # 0 +0x0000EEF8 0x8A95 # 0 +0x0000EEF9 0x8ACB # 0 +0x0000EEFA 0x8AF8 # 0 +0x0000EEFB 0x8AB2 # 0 +0x0000EEFC 0x8AC9 # 0 +0x0000EEFD 0x8AC2 # 0 +0x0000EEFE 0x8ABF # 0 +0x0000EFA1 0x8AB0 # 0 +0x0000EFA2 0x8AD6 # 0 +0x0000EFA3 0x8ACD # 0 +0x0000EFA4 0x8AB6 # 0 +0x0000EFA5 0x8AB9 # 0 +0x0000EFA6 0x8ADB # 0 +0x0000EFA7 0x8C4C # 0 +0x0000EFA8 0x8C4E # 0 +0x0000EFA9 0x8C6C # 0 +0x0000EFAA 0x8CE0 # 0 +0x0000EFAB 0x8CDE # 0 +0x0000EFAC 0x8CE6 # 0 +0x0000EFAD 0x8CE4 # 0 +0x0000EFAE 0x8CEC # 0 +0x0000EFAF 0x8CED # 0 +0x0000EFB0 0x8CE2 # 0 +0x0000EFB1 0x8CE3 # 0 +0x0000EFB2 0x8CDC # 0 +0x0000EFB3 0x8CEA # 0 +0x0000EFB4 0x8CE1 # 0 +0x0000EFB5 0x8D6D # 0 +0x0000EFB6 0x8D9F # 0 +0x0000EFB7 0x8DA3 # 0 +0x0000EFB8 0x8E2B # 0 +0x0000EFB9 0x8E10 # 0 +0x0000EFBA 0x8E1D # 0 +0x0000EFBB 0x8E22 # 0 +0x0000EFBC 0x8E0F # 0 +0x0000EFBD 0x8E29 # 0 +0x0000EFBE 0x8E1F # 0 +0x0000EFBF 0x8E21 # 0 +0x0000EFC0 0x8E1E # 0 +0x0000EFC1 0x8EBA # 0 +0x0000EFC2 0x8F1D # 0 +0x0000EFC3 0x8F1B # 0 +0x0000EFC4 0x8F1F # 0 +0x0000EFC5 0x8F29 # 0 +0x0000EFC6 0x8F26 # 0 +0x0000EFC7 0x8F2A # 0 +0x0000EFC8 0x8F1C # 0 +0x0000EFC9 0x8F1E # 0 +0x0000EFCA 0x8F25 # 0 +0x0000EFCB 0x9069 # 0 +0x0000EFCC 0x906E # 0 +0x0000EFCD 0x9068 # 0 +0x0000EFCE 0x906D # 0 +0x0000EFCF 0x9077 # 0 +0x0000EFD0 0x9130 # 0 +0x0000EFD1 0x912D # 0 +0x0000EFD2 0x9127 # 0 +0x0000EFD3 0x9131 # 0 +0x0000EFD4 0x9187 # 0 +0x0000EFD5 0x9189 # 0 +0x0000EFD6 0x918B # 0 +0x0000EFD7 0x9183 # 0 +0x0000EFD8 0x92C5 # 0 +0x0000EFD9 0x92BB # 0 +0x0000EFDA 0x92B7 # 0 +0x0000EFDB 0x92EA # 0 +0x0000EFDC 0x92E4 # 0 +0x0000EFDD 0x92C1 # 0 +0x0000EFDE 0x92B3 # 0 +0x0000EFDF 0x92BC # 0 +0x0000EFE0 0x92D2 # 0 +0x0000EFE1 0x92C7 # 0 +0x0000EFE2 0x92F0 # 0 +0x0000EFE3 0x92B2 # 0 +0x0000EFE4 0x95AD # 0 +0x0000EFE5 0x95B1 # 0 +0x0000EFE6 0x9704 # 0 +0x0000EFE7 0x9706 # 0 +0x0000EFE8 0x9707 # 0 +0x0000EFE9 0x9709 # 0 +0x0000EFEA 0x9760 # 0 +0x0000EFEB 0x978D # 0 +0x0000EFEC 0x978B # 0 +0x0000EFED 0x978F # 0 +0x0000EFEE 0x9821 # 0 +0x0000EFEF 0x982B # 0 +0x0000EFF0 0x981C # 0 +0x0000EFF1 0x98B3 # 0 +0x0000EFF2 0x990A # 0 +0x0000EFF3 0x9913 # 0 +0x0000EFF4 0x9912 # 0 +0x0000EFF5 0x9918 # 0 +0x0000EFF6 0x99DD # 0 +0x0000EFF7 0x99D0 # 0 +0x0000EFF8 0x99DF # 0 +0x0000EFF9 0x99DB # 0 +0x0000EFFA 0x99D1 # 0 +0x0000EFFB 0x99D5 # 0 +0x0000EFFC 0x99D2 # 0 +0x0000EFFD 0x99D9 # 0 +0x0000EFFE 0x9AB7 # 0 +0x0000F0A1 0x9AEE # 0 +0x0000F0A2 0x9AEF # 0 +0x0000F0A3 0x9B27 # 0 +0x0000F0A4 0x9B45 # 0 +0x0000F0A5 0x9B44 # 0 +0x0000F0A6 0x9B77 # 0 +0x0000F0A7 0x9B6F # 0 +0x0000F0A8 0x9D06 # 0 +0x0000F0A9 0x9D09 # 0 +0x0000F0AA 0x9D03 # 0 +0x0000F0AB 0x9EA9 # 0 +0x0000F0AC 0x9EBE # 0 +0x0000F0AD 0x9ECE # 0 +0x0000F0AE 0x58A8 # 0 +0x0000F0AF 0x9F52 # 0 +0x0000F0B0 0x5112 # 0 +0x0000F0B1 0x5118 # 0 +0x0000F0B2 0x5114 # 0 +0x0000F0B3 0x5110 # 0 +0x0000F0B4 0x5115 # 0 +0x0000F0B5 0x5180 # 0 +0x0000F0B6 0x51AA # 0 +0x0000F0B7 0x51DD # 0 +0x0000F0B8 0x5291 # 0 +0x0000F0B9 0x5293 # 0 +0x0000F0BA 0x52F3 # 0 +0x0000F0BB 0x5659 # 0 +0x0000F0BC 0x566B # 0 +0x0000F0BD 0x5679 # 0 +0x0000F0BE 0x5669 # 0 +0x0000F0BF 0x5664 # 0 +0x0000F0C0 0x5678 # 0 +0x0000F0C1 0x566A # 0 +0x0000F0C2 0x5668 # 0 +0x0000F0C3 0x5665 # 0 +0x0000F0C4 0x5671 # 0 +0x0000F0C5 0x566F # 0 +0x0000F0C6 0x566C # 0 +0x0000F0C7 0x5662 # 0 +0x0000F0C8 0x5676 # 0 +0x0000F0C9 0x58C1 # 0 +0x0000F0CA 0x58BE # 0 +0x0000F0CB 0x58C7 # 0 +0x0000F0CC 0x58C5 # 0 +0x0000F0CD 0x596E # 0 +0x0000F0CE 0x5B1D # 0 +0x0000F0CF 0x5B34 # 0 +0x0000F0D0 0x5B78 # 0 +0x0000F0D1 0x5BF0 # 0 +0x0000F0D2 0x5C0E # 0 +0x0000F0D3 0x5F4A # 0 +0x0000F0D4 0x61B2 # 0 +0x0000F0D5 0x6191 # 0 +0x0000F0D6 0x61A9 # 0 +0x0000F0D7 0x618A # 0 +0x0000F0D8 0x61CD # 0 +0x0000F0D9 0x61B6 # 0 +0x0000F0DA 0x61BE # 0 +0x0000F0DB 0x61CA # 0 +0x0000F0DC 0x61C8 # 0 +0x0000F0DD 0x6230 # 0 +0x0000F0DE 0x64C5 # 0 +0x0000F0DF 0x64C1 # 0 +0x0000F0E0 0x64CB # 0 +0x0000F0E1 0x64BB # 0 +0x0000F0E2 0x64BC # 0 +0x0000F0E3 0x64DA # 0 +0x0000F0E4 0x64C4 # 0 +0x0000F0E5 0x64C7 # 0 +0x0000F0E6 0x64C2 # 0 +0x0000F0E7 0x64CD # 0 +0x0000F0E8 0x64BF # 0 +0x0000F0E9 0x64D2 # 0 +0x0000F0EA 0x64D4 # 0 +0x0000F0EB 0x64BE # 0 +0x0000F0EC 0x6574 # 0 +0x0000F0ED 0x66C6 # 0 +0x0000F0EE 0x66C9 # 0 +0x0000F0EF 0x66B9 # 0 +0x0000F0F0 0x66C4 # 0 +0x0000F0F1 0x66C7 # 0 +0x0000F0F2 0x66B8 # 0 +0x0000F0F3 0x6A3D # 0 +0x0000F0F4 0x6A38 # 0 +0x0000F0F5 0x6A3A # 0 +0x0000F0F6 0x6A59 # 0 +0x0000F0F7 0x6A6B # 0 +0x0000F0F8 0x6A58 # 0 +0x0000F0F9 0x6A39 # 0 +0x0000F0FA 0x6A44 # 0 +0x0000F0FB 0x6A62 # 0 +0x0000F0FC 0x6A61 # 0 +0x0000F0FD 0x6A4B # 0 +0x0000F0FE 0x6A47 # 0 +0x0000F1A1 0x6A35 # 0 +0x0000F1A2 0x6A5F # 0 +0x0000F1A3 0x6A48 # 0 +0x0000F1A4 0x6B59 # 0 +0x0000F1A5 0x6B77 # 0 +0x0000F1A6 0x6C05 # 0 +0x0000F1A7 0x6FC2 # 0 +0x0000F1A8 0x6FB1 # 0 +0x0000F1A9 0x6FA1 # 0 +0x0000F1AA 0x6FC3 # 0 +0x0000F1AB 0x6FA4 # 0 +0x0000F1AC 0x6FC1 # 0 +0x0000F1AD 0x6FA7 # 0 +0x0000F1AE 0x6FB3 # 0 +0x0000F1AF 0x6FC0 # 0 +0x0000F1B0 0x6FB9 # 0 +0x0000F1B1 0x6FB6 # 0 +0x0000F1B2 0x6FA6 # 0 +0x0000F1B3 0x6FA0 # 0 +0x0000F1B4 0x6FB4 # 0 +0x0000F1B5 0x71BE # 0 +0x0000F1B6 0x71C9 # 0 +0x0000F1B7 0x71D0 # 0 +0x0000F1B8 0x71D2 # 0 +0x0000F1B9 0x71C8 # 0 +0x0000F1BA 0x71D5 # 0 +0x0000F1BB 0x71B9 # 0 +0x0000F1BC 0x71CE # 0 +0x0000F1BD 0x71D9 # 0 +0x0000F1BE 0x71DC # 0 +0x0000F1BF 0x71C3 # 0 +0x0000F1C0 0x71C4 # 0 +0x0000F1C1 0x7368 # 0 +0x0000F1C2 0x749C # 0 +0x0000F1C3 0x74A3 # 0 +0x0000F1C4 0x7498 # 0 +0x0000F1C5 0x749F # 0 +0x0000F1C6 0x749E # 0 +0x0000F1C7 0x74E2 # 0 +0x0000F1C8 0x750C # 0 +0x0000F1C9 0x750D # 0 +0x0000F1CA 0x7634 # 0 +0x0000F1CB 0x7638 # 0 +0x0000F1CC 0x763A # 0 +0x0000F1CD 0x76E7 # 0 +0x0000F1CE 0x76E5 # 0 +0x0000F1CF 0x77A0 # 0 +0x0000F1D0 0x779E # 0 +0x0000F1D1 0x779F # 0 +0x0000F1D2 0x77A5 # 0 +0x0000F1D3 0x78E8 # 0 +0x0000F1D4 0x78DA # 0 +0x0000F1D5 0x78EC # 0 +0x0000F1D6 0x78E7 # 0 +0x0000F1D7 0x79A6 # 0 +0x0000F1D8 0x7A4D # 0 +0x0000F1D9 0x7A4E # 0 +0x0000F1DA 0x7A46 # 0 +0x0000F1DB 0x7A4C # 0 +0x0000F1DC 0x7A4B # 0 +0x0000F1DD 0x7ABA # 0 +0x0000F1DE 0x7BD9 # 0 +0x0000F1DF 0x7C11 # 0 +0x0000F1E0 0x7BC9 # 0 +0x0000F1E1 0x7BE4 # 0 +0x0000F1E2 0x7BDB # 0 +0x0000F1E3 0x7BE1 # 0 +0x0000F1E4 0x7BE9 # 0 +0x0000F1E5 0x7BE6 # 0 +0x0000F1E6 0x7CD5 # 0 +0x0000F1E7 0x7CD6 # 0 +0x0000F1E8 0x7E0A # 0 +0x0000F1E9 0x7E11 # 0 +0x0000F1EA 0x7E08 # 0 +0x0000F1EB 0x7E1B # 0 +0x0000F1EC 0x7E23 # 0 +0x0000F1ED 0x7E1E # 0 +0x0000F1EE 0x7E1D # 0 +0x0000F1EF 0x7E09 # 0 +0x0000F1F0 0x7E10 # 0 +0x0000F1F1 0x7F79 # 0 +0x0000F1F2 0x7FB2 # 0 +0x0000F1F3 0x7FF0 # 0 +0x0000F1F4 0x7FF1 # 0 +0x0000F1F5 0x7FEE # 0 +0x0000F1F6 0x8028 # 0 +0x0000F1F7 0x81B3 # 0 +0x0000F1F8 0x81A9 # 0 +0x0000F1F9 0x81A8 # 0 +0x0000F1FA 0x81FB # 0 +0x0000F1FB 0x8208 # 0 +0x0000F1FC 0x8258 # 0 +0x0000F1FD 0x8259 # 0 +0x0000F1FE 0x854A # 0 +0x0000F2A1 0x8559 # 0 +0x0000F2A2 0x8548 # 0 +0x0000F2A3 0x8568 # 0 +0x0000F2A4 0x8569 # 0 +0x0000F2A5 0x8543 # 0 +0x0000F2A6 0x8549 # 0 +0x0000F2A7 0x856D # 0 +0x0000F2A8 0x856A # 0 +0x0000F2A9 0x855E # 0 +0x0000F2AA 0x8783 # 0 +0x0000F2AB 0x879F # 0 +0x0000F2AC 0x879E # 0 +0x0000F2AD 0x87A2 # 0 +0x0000F2AE 0x878D # 0 +0x0000F2AF 0x8861 # 0 +0x0000F2B0 0x892A # 0 +0x0000F2B1 0x8932 # 0 +0x0000F2B2 0x8925 # 0 +0x0000F2B3 0x892B # 0 +0x0000F2B4 0x8921 # 0 +0x0000F2B5 0x89AA # 0 +0x0000F2B6 0x89A6 # 0 +0x0000F2B7 0x8AE6 # 0 +0x0000F2B8 0x8AFA # 0 +0x0000F2B9 0x8AEB # 0 +0x0000F2BA 0x8AF1 # 0 +0x0000F2BB 0x8B00 # 0 +0x0000F2BC 0x8ADC # 0 +0x0000F2BD 0x8AE7 # 0 +0x0000F2BE 0x8AEE # 0 +0x0000F2BF 0x8AFE # 0 +0x0000F2C0 0x8B01 # 0 +0x0000F2C1 0x8B02 # 0 +0x0000F2C2 0x8AF7 # 0 +0x0000F2C3 0x8AED # 0 +0x0000F2C4 0x8AF3 # 0 +0x0000F2C5 0x8AF6 # 0 +0x0000F2C6 0x8AFC # 0 +0x0000F2C7 0x8C6B # 0 +0x0000F2C8 0x8C6D # 0 +0x0000F2C9 0x8C93 # 0 +0x0000F2CA 0x8CF4 # 0 +0x0000F2CB 0x8E44 # 0 +0x0000F2CC 0x8E31 # 0 +0x0000F2CD 0x8E34 # 0 +0x0000F2CE 0x8E42 # 0 +0x0000F2CF 0x8E39 # 0 +0x0000F2D0 0x8E35 # 0 +0x0000F2D1 0x8F3B # 0 +0x0000F2D2 0x8F2F # 0 +0x0000F2D3 0x8F38 # 0 +0x0000F2D4 0x8F33 # 0 +0x0000F2D5 0x8FA8 # 0 +0x0000F2D6 0x8FA6 # 0 +0x0000F2D7 0x9075 # 0 +0x0000F2D8 0x9074 # 0 +0x0000F2D9 0x9078 # 0 +0x0000F2DA 0x9072 # 0 +0x0000F2DB 0x907C # 0 +0x0000F2DC 0x907A # 0 +0x0000F2DD 0x9134 # 0 +0x0000F2DE 0x9192 # 0 +0x0000F2DF 0x9320 # 0 +0x0000F2E0 0x9336 # 0 +0x0000F2E1 0x92F8 # 0 +0x0000F2E2 0x9333 # 0 +0x0000F2E3 0x932F # 0 +0x0000F2E4 0x9322 # 0 +0x0000F2E5 0x92FC # 0 +0x0000F2E6 0x932B # 0 +0x0000F2E7 0x9304 # 0 +0x0000F2E8 0x931A # 0 +0x0000F2E9 0x9310 # 0 +0x0000F2EA 0x9326 # 0 +0x0000F2EB 0x9321 # 0 +0x0000F2EC 0x9315 # 0 +0x0000F2ED 0x932E # 0 +0x0000F2EE 0x9319 # 0 +0x0000F2EF 0x95BB # 0 +0x0000F2F0 0x96A7 # 0 +0x0000F2F1 0x96A8 # 0 +0x0000F2F2 0x96AA # 0 +0x0000F2F3 0x96D5 # 0 +0x0000F2F4 0x970E # 0 +0x0000F2F5 0x9711 # 0 +0x0000F2F6 0x9716 # 0 +0x0000F2F7 0x970D # 0 +0x0000F2F8 0x9713 # 0 +0x0000F2F9 0x970F # 0 +0x0000F2FA 0x975B # 0 +0x0000F2FB 0x975C # 0 +0x0000F2FC 0x9766 # 0 +0x0000F2FD 0x9798 # 0 +0x0000F2FE 0x9830 # 0 +0x0000F3A1 0x9838 # 0 +0x0000F3A2 0x983B # 0 +0x0000F3A3 0x9837 # 0 +0x0000F3A4 0x982D # 0 +0x0000F3A5 0x9839 # 0 +0x0000F3A6 0x9824 # 0 +0x0000F3A7 0x9910 # 0 +0x0000F3A8 0x9928 # 0 +0x0000F3A9 0x991E # 0 +0x0000F3AA 0x991B # 0 +0x0000F3AB 0x9921 # 0 +0x0000F3AC 0x991A # 0 +0x0000F3AD 0x99ED # 0 +0x0000F3AE 0x99E2 # 0 +0x0000F3AF 0x99F1 # 0 +0x0000F3B0 0x9AB8 # 0 +0x0000F3B1 0x9ABC # 0 +0x0000F3B2 0x9AFB # 0 +0x0000F3B3 0x9AED # 0 +0x0000F3B4 0x9B28 # 0 +0x0000F3B5 0x9B91 # 0 +0x0000F3B6 0x9D15 # 0 +0x0000F3B7 0x9D23 # 0 +0x0000F3B8 0x9D26 # 0 +0x0000F3B9 0x9D28 # 0 +0x0000F3BA 0x9D12 # 0 +0x0000F3BB 0x9D1B # 0 +0x0000F3BC 0x9ED8 # 0 +0x0000F3BD 0x9ED4 # 0 +0x0000F3BE 0x9F8D # 0 +0x0000F3BF 0x9F9C # 0 +0x0000F3C0 0x512A # 0 +0x0000F3C1 0x511F # 0 +0x0000F3C2 0x5121 # 0 +0x0000F3C3 0x5132 # 0 +0x0000F3C4 0x52F5 # 0 +0x0000F3C5 0x568E # 0 +0x0000F3C6 0x5680 # 0 +0x0000F3C7 0x5690 # 0 +0x0000F3C8 0x5685 # 0 +0x0000F3C9 0x5687 # 0 +0x0000F3CA 0x568F # 0 +0x0000F3CB 0x58D5 # 0 +0x0000F3CC 0x58D3 # 0 +0x0000F3CD 0x58D1 # 0 +0x0000F3CE 0x58CE # 0 +0x0000F3CF 0x5B30 # 0 +0x0000F3D0 0x5B2A # 0 +0x0000F3D1 0x5B24 # 0 +0x0000F3D2 0x5B7A # 0 +0x0000F3D3 0x5C37 # 0 +0x0000F3D4 0x5C68 # 0 +0x0000F3D5 0x5DBC # 0 +0x0000F3D6 0x5DBA # 0 +0x0000F3D7 0x5DBD # 0 +0x0000F3D8 0x5DB8 # 0 +0x0000F3D9 0x5E6B # 0 +0x0000F3DA 0x5F4C # 0 +0x0000F3DB 0x5FBD # 0 +0x0000F3DC 0x61C9 # 0 +0x0000F3DD 0x61C2 # 0 +0x0000F3DE 0x61C7 # 0 +0x0000F3DF 0x61E6 # 0 +0x0000F3E0 0x61CB # 0 +0x0000F3E1 0x6232 # 0 +0x0000F3E2 0x6234 # 0 +0x0000F3E3 0x64CE # 0 +0x0000F3E4 0x64CA # 0 +0x0000F3E5 0x64D8 # 0 +0x0000F3E6 0x64E0 # 0 +0x0000F3E7 0x64F0 # 0 +0x0000F3E8 0x64E6 # 0 +0x0000F3E9 0x64EC # 0 +0x0000F3EA 0x64F1 # 0 +0x0000F3EB 0x64E2 # 0 +0x0000F3EC 0x64ED # 0 +0x0000F3ED 0x6582 # 0 +0x0000F3EE 0x6583 # 0 +0x0000F3EF 0x66D9 # 0 +0x0000F3F0 0x66D6 # 0 +0x0000F3F1 0x6A80 # 0 +0x0000F3F2 0x6A94 # 0 +0x0000F3F3 0x6A84 # 0 +0x0000F3F4 0x6AA2 # 0 +0x0000F3F5 0x6A9C # 0 +0x0000F3F6 0x6ADB # 0 +0x0000F3F7 0x6AA3 # 0 +0x0000F3F8 0x6A7E # 0 +0x0000F3F9 0x6A97 # 0 +0x0000F3FA 0x6A90 # 0 +0x0000F3FB 0x6AA0 # 0 +0x0000F3FC 0x6B5C # 0 +0x0000F3FD 0x6BAE # 0 +0x0000F3FE 0x6BDA # 0 +0x0000F4A1 0x6C08 # 0 +0x0000F4A2 0x6FD8 # 0 +0x0000F4A3 0x6FF1 # 0 +0x0000F4A4 0x6FDF # 0 +0x0000F4A5 0x6FE0 # 0 +0x0000F4A6 0x6FDB # 0 +0x0000F4A7 0x6FE4 # 0 +0x0000F4A8 0x6FEB # 0 +0x0000F4A9 0x6FEF # 0 +0x0000F4AA 0x6F80 # 0 +0x0000F4AB 0x6FEC # 0 +0x0000F4AC 0x6FE1 # 0 +0x0000F4AD 0x6FE9 # 0 +0x0000F4AE 0x6FD5 # 0 +0x0000F4AF 0x6FEE # 0 +0x0000F4B0 0x6FF0 # 0 +0x0000F4B1 0x71E7 # 0 +0x0000F4B2 0x71DF # 0 +0x0000F4B3 0x71EE # 0 +0x0000F4B4 0x71E6 # 0 +0x0000F4B5 0x71E5 # 0 +0x0000F4B6 0x71ED # 0 +0x0000F4B7 0x71EC # 0 +0x0000F4B8 0x71F4 # 0 +0x0000F4B9 0x71E0 # 0 +0x0000F4BA 0x7235 # 0 +0x0000F4BB 0x7246 # 0 +0x0000F4BC 0x7370 # 0 +0x0000F4BD 0x7372 # 0 +0x0000F4BE 0x74A9 # 0 +0x0000F4BF 0x74B0 # 0 +0x0000F4C0 0x74A6 # 0 +0x0000F4C1 0x74A8 # 0 +0x0000F4C2 0x7646 # 0 +0x0000F4C3 0x7642 # 0 +0x0000F4C4 0x764C # 0 +0x0000F4C5 0x76EA # 0 +0x0000F4C6 0x77B3 # 0 +0x0000F4C7 0x77AA # 0 +0x0000F4C8 0x77B0 # 0 +0x0000F4C9 0x77AC # 0 +0x0000F4CA 0x77A7 # 0 +0x0000F4CB 0x77AD # 0 +0x0000F4CC 0x77EF # 0 +0x0000F4CD 0x78F7 # 0 +0x0000F4CE 0x78FA # 0 +0x0000F4CF 0x78F4 # 0 +0x0000F4D0 0x78EF # 0 +0x0000F4D1 0x7901 # 0 +0x0000F4D2 0x79A7 # 0 +0x0000F4D3 0x79AA # 0 +0x0000F4D4 0x7A57 # 0 +0x0000F4D5 0x7ABF # 0 +0x0000F4D6 0x7C07 # 0 +0x0000F4D7 0x7C0D # 0 +0x0000F4D8 0x7BFE # 0 +0x0000F4D9 0x7BF7 # 0 +0x0000F4DA 0x7C0C # 0 +0x0000F4DB 0x7BE0 # 0 +0x0000F4DC 0x7CE0 # 0 +0x0000F4DD 0x7CDC # 0 +0x0000F4DE 0x7CDE # 0 +0x0000F4DF 0x7CE2 # 0 +0x0000F4E0 0x7CDF # 0 +0x0000F4E1 0x7CD9 # 0 +0x0000F4E2 0x7CDD # 0 +0x0000F4E3 0x7E2E # 0 +0x0000F4E4 0x7E3E # 0 +0x0000F4E5 0x7E46 # 0 +0x0000F4E6 0x7E37 # 0 +0x0000F4E7 0x7E32 # 0 +0x0000F4E8 0x7E43 # 0 +0x0000F4E9 0x7E2B # 0 +0x0000F4EA 0x7E3D # 0 +0x0000F4EB 0x7E31 # 0 +0x0000F4EC 0x7E45 # 0 +0x0000F4ED 0x7E41 # 0 +0x0000F4EE 0x7E34 # 0 +0x0000F4EF 0x7E39 # 0 +0x0000F4F0 0x7E48 # 0 +0x0000F4F1 0x7E35 # 0 +0x0000F4F2 0x7E3F # 0 +0x0000F4F3 0x7E2F # 0 +0x0000F4F4 0x7F44 # 0 +0x0000F4F5 0x7FF3 # 0 +0x0000F4F6 0x7FFC # 0 +0x0000F4F7 0x8071 # 0 +0x0000F4F8 0x8072 # 0 +0x0000F4F9 0x8070 # 0 +0x0000F4FA 0x806F # 0 +0x0000F4FB 0x8073 # 0 +0x0000F4FC 0x81C6 # 0 +0x0000F4FD 0x81C3 # 0 +0x0000F4FE 0x81BA # 0 +0x0000F5A1 0x81C2 # 0 +0x0000F5A2 0x81C0 # 0 +0x0000F5A3 0x81BF # 0 +0x0000F5A4 0x81BD # 0 +0x0000F5A5 0x81C9 # 0 +0x0000F5A6 0x81BE # 0 +0x0000F5A7 0x81E8 # 0 +0x0000F5A8 0x8209 # 0 +0x0000F5A9 0x8271 # 0 +0x0000F5AA 0x85AA # 0 +0x0000F5AB 0x8584 # 0 +0x0000F5AC 0x857E # 0 +0x0000F5AD 0x859C # 0 +0x0000F5AE 0x8591 # 0 +0x0000F5AF 0x8594 # 0 +0x0000F5B0 0x85AF # 0 +0x0000F5B1 0x859B # 0 +0x0000F5B2 0x8587 # 0 +0x0000F5B3 0x85A8 # 0 +0x0000F5B4 0x858A # 0 +0x0000F5B5 0x85A6 # 0 +0x0000F5B6 0x8667 # 0 +0x0000F5B7 0x87C0 # 0 +0x0000F5B8 0x87D1 # 0 +0x0000F5B9 0x87B3 # 0 +0x0000F5BA 0x87D2 # 0 +0x0000F5BB 0x87C6 # 0 +0x0000F5BC 0x87AB # 0 +0x0000F5BD 0x87BB # 0 +0x0000F5BE 0x87BA # 0 +0x0000F5BF 0x87C8 # 0 +0x0000F5C0 0x87CB # 0 +0x0000F5C1 0x893B # 0 +0x0000F5C2 0x8936 # 0 +0x0000F5C3 0x8944 # 0 +0x0000F5C4 0x8938 # 0 +0x0000F5C5 0x893D # 0 +0x0000F5C6 0x89AC # 0 +0x0000F5C7 0x8B0E # 0 +0x0000F5C8 0x8B17 # 0 +0x0000F5C9 0x8B19 # 0 +0x0000F5CA 0x8B1B # 0 +0x0000F5CB 0x8B0A # 0 +0x0000F5CC 0x8B20 # 0 +0x0000F5CD 0x8B1D # 0 +0x0000F5CE 0x8B04 # 0 +0x0000F5CF 0x8B10 # 0 +0x0000F5D0 0x8C41 # 0 +0x0000F5D1 0x8C3F # 0 +0x0000F5D2 0x8C73 # 0 +0x0000F5D3 0x8CFA # 0 +0x0000F5D4 0x8CFD # 0 +0x0000F5D5 0x8CFC # 0 +0x0000F5D6 0x8CF8 # 0 +0x0000F5D7 0x8CFB # 0 +0x0000F5D8 0x8DA8 # 0 +0x0000F5D9 0x8E49 # 0 +0x0000F5DA 0x8E4B # 0 +0x0000F5DB 0x8E48 # 0 +0x0000F5DC 0x8E4A # 0 +0x0000F5DD 0x8F44 # 0 +0x0000F5DE 0x8F3E # 0 +0x0000F5DF 0x8F42 # 0 +0x0000F5E0 0x8F45 # 0 +0x0000F5E1 0x8F3F # 0 +0x0000F5E2 0x907F # 0 +0x0000F5E3 0x907D # 0 +0x0000F5E4 0x9084 # 0 +0x0000F5E5 0x9081 # 0 +0x0000F5E6 0x9082 # 0 +0x0000F5E7 0x9080 # 0 +0x0000F5E8 0x9139 # 0 +0x0000F5E9 0x91A3 # 0 +0x0000F5EA 0x919E # 0 +0x0000F5EB 0x919C # 0 +0x0000F5EC 0x934D # 0 +0x0000F5ED 0x9382 # 0 +0x0000F5EE 0x9328 # 0 +0x0000F5EF 0x9375 # 0 +0x0000F5F0 0x934A # 0 +0x0000F5F1 0x9365 # 0 +0x0000F5F2 0x934B # 0 +0x0000F5F3 0x9318 # 0 +0x0000F5F4 0x937E # 0 +0x0000F5F5 0x936C # 0 +0x0000F5F6 0x935B # 0 +0x0000F5F7 0x9370 # 0 +0x0000F5F8 0x935A # 0 +0x0000F5F9 0x9354 # 0 +0x0000F5FA 0x95CA # 0 +0x0000F5FB 0x95CB # 0 +0x0000F5FC 0x95CC # 0 +0x0000F5FD 0x95C8 # 0 +0x0000F5FE 0x95C6 # 0 +0x0000F6A1 0x96B1 # 0 +0x0000F6A2 0x96B8 # 0 +0x0000F6A3 0x96D6 # 0 +0x0000F6A4 0x971C # 0 +0x0000F6A5 0x971E # 0 +0x0000F6A6 0x97A0 # 0 +0x0000F6A7 0x97D3 # 0 +0x0000F6A8 0x9846 # 0 +0x0000F6A9 0x98B6 # 0 +0x0000F6AA 0x9935 # 0 +0x0000F6AB 0x9A01 # 0 +0x0000F6AC 0x99FF # 0 +0x0000F6AD 0x9BAE # 0 +0x0000F6AE 0x9BAB # 0 +0x0000F6AF 0x9BAA # 0 +0x0000F6B0 0x9BAD # 0 +0x0000F6B1 0x9D3B # 0 +0x0000F6B2 0x9D3F # 0 +0x0000F6B3 0x9E8B # 0 +0x0000F6B4 0x9ECF # 0 +0x0000F6B5 0x9EDE # 0 +0x0000F6B6 0x9EDC # 0 +0x0000F6B7 0x9EDD # 0 +0x0000F6B8 0x9EDB # 0 +0x0000F6B9 0x9F3E # 0 +0x0000F6BA 0x9F4B # 0 +0x0000F6BB 0x53E2 # 0 +0x0000F6BC 0x5695 # 0 +0x0000F6BD 0x56AE # 0 +0x0000F6BE 0x58D9 # 0 +0x0000F6BF 0x58D8 # 0 +0x0000F6C0 0x5B38 # 0 +0x0000F6C1 0x5F5E # 0 +0x0000F6C2 0x61E3 # 0 +0x0000F6C3 0x6233 # 0 +0x0000F6C4 0x64F4 # 0 +0x0000F6C5 0x64F2 # 0 +0x0000F6C6 0x64FE # 0 +0x0000F6C7 0x6506 # 0 +0x0000F6C8 0x64FA # 0 +0x0000F6C9 0x64FB # 0 +0x0000F6CA 0x64F7 # 0 +0x0000F6CB 0x65B7 # 0 +0x0000F6CC 0x66DC # 0 +0x0000F6CD 0x6726 # 0 +0x0000F6CE 0x6AB3 # 0 +0x0000F6CF 0x6AAC # 0 +0x0000F6D0 0x6AC3 # 0 +0x0000F6D1 0x6ABB # 0 +0x0000F6D2 0x6AB8 # 0 +0x0000F6D3 0x6AC2 # 0 +0x0000F6D4 0x6AAE # 0 +0x0000F6D5 0x6AAF # 0 +0x0000F6D6 0x6B5F # 0 +0x0000F6D7 0x6B78 # 0 +0x0000F6D8 0x6BAF # 0 +0x0000F6D9 0x7009 # 0 +0x0000F6DA 0x700B # 0 +0x0000F6DB 0x6FFE # 0 +0x0000F6DC 0x7006 # 0 +0x0000F6DD 0x6FFA # 0 +0x0000F6DE 0x7011 # 0 +0x0000F6DF 0x700F # 0 +0x0000F6E0 0x71FB # 0 +0x0000F6E1 0x71FC # 0 +0x0000F6E2 0x71FE # 0 +0x0000F6E3 0x71F8 # 0 +0x0000F6E4 0x7377 # 0 +0x0000F6E5 0x7375 # 0 +0x0000F6E6 0x74A7 # 0 +0x0000F6E7 0x74BF # 0 +0x0000F6E8 0x7515 # 0 +0x0000F6E9 0x7656 # 0 +0x0000F6EA 0x7658 # 0 +0x0000F6EB 0x7652 # 0 +0x0000F6EC 0x77BD # 0 +0x0000F6ED 0x77BF # 0 +0x0000F6EE 0x77BB # 0 +0x0000F6EF 0x77BC # 0 +0x0000F6F0 0x790E # 0 +0x0000F6F1 0x79AE # 0 +0x0000F6F2 0x7A61 # 0 +0x0000F6F3 0x7A62 # 0 +0x0000F6F4 0x7A60 # 0 +0x0000F6F5 0x7AC4 # 0 +0x0000F6F6 0x7AC5 # 0 +0x0000F6F7 0x7C2B # 0 +0x0000F6F8 0x7C27 # 0 +0x0000F6F9 0x7C2A # 0 +0x0000F6FA 0x7C1E # 0 +0x0000F6FB 0x7C23 # 0 +0x0000F6FC 0x7C21 # 0 +0x0000F6FD 0x7CE7 # 0 +0x0000F6FE 0x7E54 # 0 +0x0000F7A1 0x7E55 # 0 +0x0000F7A2 0x7E5E # 0 +0x0000F7A3 0x7E5A # 0 +0x0000F7A4 0x7E61 # 0 +0x0000F7A5 0x7E52 # 0 +0x0000F7A6 0x7E59 # 0 +0x0000F7A7 0x7F48 # 0 +0x0000F7A8 0x7FF9 # 0 +0x0000F7A9 0x7FFB # 0 +0x0000F7AA 0x8077 # 0 +0x0000F7AB 0x8076 # 0 +0x0000F7AC 0x81CD # 0 +0x0000F7AD 0x81CF # 0 +0x0000F7AE 0x820A # 0 +0x0000F7AF 0x85CF # 0 +0x0000F7B0 0x85A9 # 0 +0x0000F7B1 0x85CD # 0 +0x0000F7B2 0x85D0 # 0 +0x0000F7B3 0x85C9 # 0 +0x0000F7B4 0x85B0 # 0 +0x0000F7B5 0x85BA # 0 +0x0000F7B6 0x85B9 # 0 +0x0000F7B7 0x87EF # 0 +0x0000F7B8 0x87EC # 0 +0x0000F7B9 0x87F2 # 0 +0x0000F7BA 0x87E0 # 0 +0x0000F7BB 0x8986 # 0 +0x0000F7BC 0x89B2 # 0 +0x0000F7BD 0x89F4 # 0 +0x0000F7BE 0x8B28 # 0 +0x0000F7BF 0x8B39 # 0 +0x0000F7C0 0x8B2C # 0 +0x0000F7C1 0x8B2B # 0 +0x0000F7C2 0x8C50 # 0 +0x0000F7C3 0x8D05 # 0 +0x0000F7C4 0x8E59 # 0 +0x0000F7C5 0x8E63 # 0 +0x0000F7C6 0x8E66 # 0 +0x0000F7C7 0x8E64 # 0 +0x0000F7C8 0x8E5F # 0 +0x0000F7C9 0x8E55 # 0 +0x0000F7CA 0x8EC0 # 0 +0x0000F7CB 0x8F49 # 0 +0x0000F7CC 0x8F4D # 0 +0x0000F7CD 0x9087 # 0 +0x0000F7CE 0x9083 # 0 +0x0000F7CF 0x9088 # 0 +0x0000F7D0 0x91AB # 0 +0x0000F7D1 0x91AC # 0 +0x0000F7D2 0x91D0 # 0 +0x0000F7D3 0x9394 # 0 +0x0000F7D4 0x938A # 0 +0x0000F7D5 0x9396 # 0 +0x0000F7D6 0x93A2 # 0 +0x0000F7D7 0x93B3 # 0 +0x0000F7D8 0x93AE # 0 +0x0000F7D9 0x93AC # 0 +0x0000F7DA 0x93B0 # 0 +0x0000F7DB 0x9398 # 0 +0x0000F7DC 0x939A # 0 +0x0000F7DD 0x9397 # 0 +0x0000F7DE 0x95D4 # 0 +0x0000F7DF 0x95D6 # 0 +0x0000F7E0 0x95D0 # 0 +0x0000F7E1 0x95D5 # 0 +0x0000F7E2 0x96E2 # 0 +0x0000F7E3 0x96DC # 0 +0x0000F7E4 0x96D9 # 0 +0x0000F7E5 0x96DB # 0 +0x0000F7E6 0x96DE # 0 +0x0000F7E7 0x9724 # 0 +0x0000F7E8 0x97A3 # 0 +0x0000F7E9 0x97A6 # 0 +0x0000F7EA 0x97AD # 0 +0x0000F7EB 0x97F9 # 0 +0x0000F7EC 0x984D # 0 +0x0000F7ED 0x984F # 0 +0x0000F7EE 0x984C # 0 +0x0000F7EF 0x984E # 0 +0x0000F7F0 0x9853 # 0 +0x0000F7F1 0x98BA # 0 +0x0000F7F2 0x993E # 0 +0x0000F7F3 0x993F # 0 +0x0000F7F4 0x993D # 0 +0x0000F7F5 0x992E # 0 +0x0000F7F6 0x99A5 # 0 +0x0000F7F7 0x9A0E # 0 +0x0000F7F8 0x9AC1 # 0 +0x0000F7F9 0x9B03 # 0 +0x0000F7FA 0x9B06 # 0 +0x0000F7FB 0x9B4F # 0 +0x0000F7FC 0x9B4E # 0 +0x0000F7FD 0x9B4D # 0 +0x0000F7FE 0x9BCA # 0 +0x0000F8A1 0x9BC9 # 0 +0x0000F8A2 0x9BFD # 0 +0x0000F8A3 0x9BC8 # 0 +0x0000F8A4 0x9BC0 # 0 +0x0000F8A5 0x9D51 # 0 +0x0000F8A6 0x9D5D # 0 +0x0000F8A7 0x9D60 # 0 +0x0000F8A8 0x9EE0 # 0 +0x0000F8A9 0x9F15 # 0 +0x0000F8AA 0x9F2C # 0 +0x0000F8AB 0x5133 # 0 +0x0000F8AC 0x56A5 # 0 +0x0000F8AD 0x56A8 # 0 +0x0000F8AE 0x58DE # 0 +0x0000F8AF 0x58DF # 0 +0x0000F8B0 0x58E2 # 0 +0x0000F8B1 0x5BF5 # 0 +0x0000F8B2 0x9F90 # 0 +0x0000F8B3 0x5EEC # 0 +0x0000F8B4 0x61F2 # 0 +0x0000F8B5 0x61F7 # 0 +0x0000F8B6 0x61F6 # 0 +0x0000F8B7 0x61F5 # 0 +0x0000F8B8 0x6500 # 0 +0x0000F8B9 0x650F # 0 +0x0000F8BA 0x66E0 # 0 +0x0000F8BB 0x66DD # 0 +0x0000F8BC 0x6AE5 # 0 +0x0000F8BD 0x6ADD # 0 +0x0000F8BE 0x6ADA # 0 +0x0000F8BF 0x6AD3 # 0 +0x0000F8C0 0x701B # 0 +0x0000F8C1 0x701F # 0 +0x0000F8C2 0x7028 # 0 +0x0000F8C3 0x701A # 0 +0x0000F8C4 0x701D # 0 +0x0000F8C5 0x7015 # 0 +0x0000F8C6 0x7018 # 0 +0x0000F8C7 0x7206 # 0 +0x0000F8C8 0x720D # 0 +0x0000F8C9 0x7258 # 0 +0x0000F8CA 0x72A2 # 0 +0x0000F8CB 0x7378 # 0 +0x0000F8CC 0x737A # 0 +0x0000F8CD 0x74BD # 0 +0x0000F8CE 0x74CA # 0 +0x0000F8CF 0x74E3 # 0 +0x0000F8D0 0x7587 # 0 +0x0000F8D1 0x7586 # 0 +0x0000F8D2 0x765F # 0 +0x0000F8D3 0x7661 # 0 +0x0000F8D4 0x77C7 # 0 +0x0000F8D5 0x7919 # 0 +0x0000F8D6 0x79B1 # 0 +0x0000F8D7 0x7A6B # 0 +0x0000F8D8 0x7A69 # 0 +0x0000F8D9 0x7C3E # 0 +0x0000F8DA 0x7C3F # 0 +0x0000F8DB 0x7C38 # 0 +0x0000F8DC 0x7C3D # 0 +0x0000F8DD 0x7C37 # 0 +0x0000F8DE 0x7C40 # 0 +0x0000F8DF 0x7E6B # 0 +0x0000F8E0 0x7E6D # 0 +0x0000F8E1 0x7E79 # 0 +0x0000F8E2 0x7E69 # 0 +0x0000F8E3 0x7E6A # 0 +0x0000F8E4 0x7E73 # 0 +0x0000F8E5 0x7F85 # 0 +0x0000F8E6 0x7FB6 # 0 +0x0000F8E7 0x7FB9 # 0 +0x0000F8E8 0x7FB8 # 0 +0x0000F8E9 0x81D8 # 0 +0x0000F8EA 0x85E9 # 0 +0x0000F8EB 0x85DD # 0 +0x0000F8EC 0x85EA # 0 +0x0000F8ED 0x85D5 # 0 +0x0000F8EE 0x85E4 # 0 +0x0000F8EF 0x85E5 # 0 +0x0000F8F0 0x85F7 # 0 +0x0000F8F1 0x87FB # 0 +0x0000F8F2 0x8805 # 0 +0x0000F8F3 0x880D # 0 +0x0000F8F4 0x87F9 # 0 +0x0000F8F5 0x87FE # 0 +0x0000F8F6 0x8960 # 0 +0x0000F8F7 0x895F # 0 +0x0000F8F8 0x8956 # 0 +0x0000F8F9 0x895E # 0 +0x0000F8FA 0x8B41 # 0 +0x0000F8FB 0x8B5C # 0 +0x0000F8FC 0x8B58 # 0 +0x0000F8FD 0x8B49 # 0 +0x0000F8FE 0x8B5A # 0 +0x0000F9A1 0x8B4E # 0 +0x0000F9A2 0x8B4F # 0 +0x0000F9A3 0x8B46 # 0 +0x0000F9A4 0x8B59 # 0 +0x0000F9A5 0x8D08 # 0 +0x0000F9A6 0x8D0A # 0 +0x0000F9A7 0x8E7C # 0 +0x0000F9A8 0x8E72 # 0 +0x0000F9A9 0x8E87 # 0 +0x0000F9AA 0x8E76 # 0 +0x0000F9AB 0x8E6C # 0 +0x0000F9AC 0x8E7A # 0 +0x0000F9AD 0x8E74 # 0 +0x0000F9AE 0x8F54 # 0 +0x0000F9AF 0x8F4E # 0 +0x0000F9B0 0x8FAD # 0 +0x0000F9B1 0x908A # 0 +0x0000F9B2 0x908B # 0 +0x0000F9B3 0x91B1 # 0 +0x0000F9B4 0x91AE # 0 +0x0000F9B5 0x93E1 # 0 +0x0000F9B6 0x93D1 # 0 +0x0000F9B7 0x93DF # 0 +0x0000F9B8 0x93C3 # 0 +0x0000F9B9 0x93C8 # 0 +0x0000F9BA 0x93DC # 0 +0x0000F9BB 0x93DD # 0 +0x0000F9BC 0x93D6 # 0 +0x0000F9BD 0x93E2 # 0 +0x0000F9BE 0x93CD # 0 +0x0000F9BF 0x93D8 # 0 +0x0000F9C0 0x93E4 # 0 +0x0000F9C1 0x93D7 # 0 +0x0000F9C2 0x93E8 # 0 +0x0000F9C3 0x95DC # 0 +0x0000F9C4 0x96B4 # 0 +0x0000F9C5 0x96E3 # 0 +0x0000F9C6 0x972A # 0 +0x0000F9C7 0x9727 # 0 +0x0000F9C8 0x9761 # 0 +0x0000F9C9 0x97DC # 0 +0x0000F9CA 0x97FB # 0 +0x0000F9CB 0x985E # 0 +0x0000F9CC 0x9858 # 0 +0x0000F9CD 0x985B # 0 +0x0000F9CE 0x98BC # 0 +0x0000F9CF 0x9945 # 0 +0x0000F9D0 0x9949 # 0 +0x0000F9D1 0x9A16 # 0 +0x0000F9D2 0x9A19 # 0 +0x0000F9D3 0x9B0D # 0 +0x0000F9D4 0x9BE8 # 0 +0x0000F9D5 0x9BE7 # 0 +0x0000F9D6 0x9BD6 # 0 +0x0000F9D7 0x9BDB # 0 +0x0000F9D8 0x9D89 # 0 +0x0000F9D9 0x9D61 # 0 +0x0000F9DA 0x9D72 # 0 +0x0000F9DB 0x9D6A # 0 +0x0000F9DC 0x9D6C # 0 +0x0000F9DD 0x9E92 # 0 +0x0000F9DE 0x9E97 # 0 +0x0000F9DF 0x9E93 # 0 +0x0000F9E0 0x9EB4 # 0 +0x0000F9E1 0x52F8 # 0 +0x0000F9E2 0x56B7 # 0 +0x0000F9E3 0x56B6 # 0 +0x0000F9E4 0x56B4 # 0 +0x0000F9E5 0x56BC # 0 +0x0000F9E6 0x58E4 # 0 +0x0000F9E7 0x5B40 # 0 +0x0000F9E8 0x5B43 # 0 +0x0000F9E9 0x5B7D # 0 +0x0000F9EA 0x5BF6 # 0 +0x0000F9EB 0x5DC9 # 0 +0x0000F9EC 0x61F8 # 0 +0x0000F9ED 0x61FA # 0 +0x0000F9EE 0x6518 # 0 +0x0000F9EF 0x6514 # 0 +0x0000F9F0 0x6519 # 0 +0x0000F9F1 0x66E6 # 0 +0x0000F9F2 0x6727 # 0 +0x0000F9F3 0x6AEC # 0 +0x0000F9F4 0x703E # 0 +0x0000F9F5 0x7030 # 0 +0x0000F9F6 0x7032 # 0 +0x0000F9F7 0x7210 # 0 +0x0000F9F8 0x737B # 0 +0x0000F9F9 0x74CF # 0 +0x0000F9FA 0x7662 # 0 +0x0000F9FB 0x7665 # 0 +0x0000F9FC 0x7926 # 0 +0x0000F9FD 0x792A # 0 +0x0000F9FE 0x792C # 0 +0x0000FAA1 0x792B # 0 +0x0000FAA2 0x7AC7 # 0 +0x0000FAA3 0x7AF6 # 0 +0x0000FAA4 0x7C4C # 0 +0x0000FAA5 0x7C43 # 0 +0x0000FAA6 0x7C4D # 0 +0x0000FAA7 0x7CEF # 0 +0x0000FAA8 0x7CF0 # 0 +0x0000FAA9 0x8FAE # 0 +0x0000FAAA 0x7E7D # 0 +0x0000FAAB 0x7E7C # 0 +0x0000FAAC 0x7E82 # 0 +0x0000FAAD 0x7F4C # 0 +0x0000FAAE 0x8000 # 0 +0x0000FAAF 0x81DA # 0 +0x0000FAB0 0x8266 # 0 +0x0000FAB1 0x85FB # 0 +0x0000FAB2 0x85F9 # 0 +0x0000FAB3 0x8611 # 0 +0x0000FAB4 0x85FA # 0 +0x0000FAB5 0x8606 # 0 +0x0000FAB6 0x860B # 0 +0x0000FAB7 0x8607 # 0 +0x0000FAB8 0x860A # 0 +0x0000FAB9 0x8814 # 0 +0x0000FABA 0x8815 # 0 +0x0000FABB 0x8964 # 0 +0x0000FABC 0x89BA # 0 +0x0000FABD 0x89F8 # 0 +0x0000FABE 0x8B70 # 0 +0x0000FABF 0x8B6C # 0 +0x0000FAC0 0x8B66 # 0 +0x0000FAC1 0x8B6F # 0 +0x0000FAC2 0x8B5F # 0 +0x0000FAC3 0x8B6B # 0 +0x0000FAC4 0x8D0F # 0 +0x0000FAC5 0x8D0D # 0 +0x0000FAC6 0x8E89 # 0 +0x0000FAC7 0x8E81 # 0 +0x0000FAC8 0x8E85 # 0 +0x0000FAC9 0x8E82 # 0 +0x0000FACA 0x91B4 # 0 +0x0000FACB 0x91CB # 0 +0x0000FACC 0x9418 # 0 +0x0000FACD 0x9403 # 0 +0x0000FACE 0x93FD # 0 +0x0000FACF 0x95E1 # 0 +0x0000FAD0 0x9730 # 0 +0x0000FAD1 0x98C4 # 0 +0x0000FAD2 0x9952 # 0 +0x0000FAD3 0x9951 # 0 +0x0000FAD4 0x99A8 # 0 +0x0000FAD5 0x9A2B # 0 +0x0000FAD6 0x9A30 # 0 +0x0000FAD7 0x9A37 # 0 +0x0000FAD8 0x9A35 # 0 +0x0000FAD9 0x9C13 # 0 +0x0000FADA 0x9C0D # 0 +0x0000FADB 0x9E79 # 0 +0x0000FADC 0x9EB5 # 0 +0x0000FADD 0x9EE8 # 0 +0x0000FADE 0x9F2F # 0 +0x0000FADF 0x9F5F # 0 +0x0000FAE0 0x9F63 # 0 +0x0000FAE1 0x9F61 # 0 +0x0000FAE2 0x5137 # 0 +0x0000FAE3 0x5138 # 0 +0x0000FAE4 0x56C1 # 0 +0x0000FAE5 0x56C0 # 0 +0x0000FAE6 0x56C2 # 0 +0x0000FAE7 0x5914 # 0 +0x0000FAE8 0x5C6C # 0 +0x0000FAE9 0x5DCD # 0 +0x0000FAEA 0x61FC # 0 +0x0000FAEB 0x61FE # 0 +0x0000FAEC 0x651D # 0 +0x0000FAED 0x651C # 0 +0x0000FAEE 0x6595 # 0 +0x0000FAEF 0x66E9 # 0 +0x0000FAF0 0x6AFB # 0 +0x0000FAF1 0x6B04 # 0 +0x0000FAF2 0x6AFA # 0 +0x0000FAF3 0x6BB2 # 0 +0x0000FAF4 0x704C # 0 +0x0000FAF5 0x721B # 0 +0x0000FAF6 0x72A7 # 0 +0x0000FAF7 0x74D6 # 0 +0x0000FAF8 0x74D4 # 0 +0x0000FAF9 0x7669 # 0 +0x0000FAFA 0x77D3 # 0 +0x0000FAFB 0x7C50 # 0 +0x0000FAFC 0x7E8F # 0 +0x0000FAFD 0x7E8C # 0 +0x0000FAFE 0x7FBC # 0 +0x0000FBA1 0x8617 # 0 +0x0000FBA2 0x862D # 0 +0x0000FBA3 0x861A # 0 +0x0000FBA4 0x8823 # 0 +0x0000FBA5 0x8822 # 0 +0x0000FBA6 0x8821 # 0 +0x0000FBA7 0x881F # 0 +0x0000FBA8 0x896A # 0 +0x0000FBA9 0x896C # 0 +0x0000FBAA 0x89BD # 0 +0x0000FBAB 0x8B74 # 0 +0x0000FBAC 0x8B77 # 0 +0x0000FBAD 0x8B7D # 0 +0x0000FBAE 0x8D13 # 0 +0x0000FBAF 0x8E8A # 0 +0x0000FBB0 0x8E8D # 0 +0x0000FBB1 0x8E8B # 0 +0x0000FBB2 0x8F5F # 0 +0x0000FBB3 0x8FAF # 0 +0x0000FBB4 0x91BA # 0 +0x0000FBB5 0x942E # 0 +0x0000FBB6 0x9433 # 0 +0x0000FBB7 0x9435 # 0 +0x0000FBB8 0x943A # 0 +0x0000FBB9 0x9438 # 0 +0x0000FBBA 0x9432 # 0 +0x0000FBBB 0x942B # 0 +0x0000FBBC 0x95E2 # 0 +0x0000FBBD 0x9738 # 0 +0x0000FBBE 0x9739 # 0 +0x0000FBBF 0x9732 # 0 +0x0000FBC0 0x97FF # 0 +0x0000FBC1 0x9867 # 0 +0x0000FBC2 0x9865 # 0 +0x0000FBC3 0x9957 # 0 +0x0000FBC4 0x9A45 # 0 +0x0000FBC5 0x9A43 # 0 +0x0000FBC6 0x9A40 # 0 +0x0000FBC7 0x9A3E # 0 +0x0000FBC8 0x9ACF # 0 +0x0000FBC9 0x9B54 # 0 +0x0000FBCA 0x9B51 # 0 +0x0000FBCB 0x9C2D # 0 +0x0000FBCC 0x9C25 # 0 +0x0000FBCD 0x9DAF # 0 +0x0000FBCE 0x9DB4 # 0 +0x0000FBCF 0x9DC2 # 0 +0x0000FBD0 0x9DB8 # 0 +0x0000FBD1 0x9E9D # 0 +0x0000FBD2 0x9EEF # 0 +0x0000FBD3 0x9F19 # 0 +0x0000FBD4 0x9F5C # 0 +0x0000FBD5 0x9F66 # 0 +0x0000FBD6 0x9F67 # 0 +0x0000FBD7 0x513C # 0 +0x0000FBD8 0x513B # 0 +0x0000FBD9 0x56C8 # 0 +0x0000FBDA 0x56CA # 0 +0x0000FBDB 0x56C9 # 0 +0x0000FBDC 0x5B7F # 0 +0x0000FBDD 0x5DD4 # 0 +0x0000FBDE 0x5DD2 # 0 +0x0000FBDF 0x5F4E # 0 +0x0000FBE0 0x61FF # 0 +0x0000FBE1 0x6524 # 0 +0x0000FBE2 0x6B0A # 0 +0x0000FBE3 0x6B61 # 0 +0x0000FBE4 0x7051 # 0 +0x0000FBE5 0x7058 # 0 +0x0000FBE6 0x7380 # 0 +0x0000FBE7 0x74E4 # 0 +0x0000FBE8 0x758A # 0 +0x0000FBE9 0x766E # 0 +0x0000FBEA 0x766C # 0 +0x0000FBEB 0x79B3 # 0 +0x0000FBEC 0x7C60 # 0 +0x0000FBED 0x7C5F # 0 +0x0000FBEE 0x807E # 0 +0x0000FBEF 0x807D # 0 +0x0000FBF0 0x81DF # 0 +0x0000FBF1 0x8972 # 0 +0x0000FBF2 0x896F # 0 +0x0000FBF3 0x89FC # 0 +0x0000FBF4 0x8B80 # 0 +0x0000FBF5 0x8D16 # 0 +0x0000FBF6 0x8D17 # 0 +0x0000FBF7 0x8E91 # 0 +0x0000FBF8 0x8E93 # 0 +0x0000FBF9 0x8F61 # 0 +0x0000FBFA 0x9148 # 0 +0x0000FBFB 0x9444 # 0 +0x0000FBFC 0x9451 # 0 +0x0000FBFD 0x9452 # 0 +0x0000FBFE 0x973D # 0 +0x0000FCA1 0x973E # 0 +0x0000FCA2 0x97C3 # 0 +0x0000FCA3 0x97C1 # 0 +0x0000FCA4 0x986B # 0 +0x0000FCA5 0x9955 # 0 +0x0000FCA6 0x9A55 # 0 +0x0000FCA7 0x9A4D # 0 +0x0000FCA8 0x9AD2 # 0 +0x0000FCA9 0x9B1A # 0 +0x0000FCAA 0x9C49 # 0 +0x0000FCAB 0x9C31 # 0 +0x0000FCAC 0x9C3E # 0 +0x0000FCAD 0x9C3B # 0 +0x0000FCAE 0x9DD3 # 0 +0x0000FCAF 0x9DD7 # 0 +0x0000FCB0 0x9F34 # 0 +0x0000FCB1 0x9F6C # 0 +0x0000FCB2 0x9F6A # 0 +0x0000FCB3 0x9F94 # 0 +0x0000FCB4 0x56CC # 0 +0x0000FCB5 0x5DD6 # 0 +0x0000FCB6 0x6200 # 0 +0x0000FCB7 0x6523 # 0 +0x0000FCB8 0x652B # 0 +0x0000FCB9 0x652A # 0 +0x0000FCBA 0x66EC # 0 +0x0000FCBB 0x6B10 # 0 +0x0000FCBC 0x74DA # 0 +0x0000FCBD 0x7ACA # 0 +0x0000FCBE 0x7C64 # 0 +0x0000FCBF 0x7C63 # 0 +0x0000FCC0 0x7C65 # 0 +0x0000FCC1 0x7E93 # 0 +0x0000FCC2 0x7E96 # 0 +0x0000FCC3 0x7E94 # 0 +0x0000FCC4 0x81E2 # 0 +0x0000FCC5 0x8638 # 0 +0x0000FCC6 0x863F # 0 +0x0000FCC7 0x8831 # 0 +0x0000FCC8 0x8B8A # 0 +0x0000FCC9 0x9090 # 0 +0x0000FCCA 0x908F # 0 +0x0000FCCB 0x9463 # 0 +0x0000FCCC 0x9460 # 0 +0x0000FCCD 0x9464 # 0 +0x0000FCCE 0x9768 # 0 +0x0000FCCF 0x986F # 0 +0x0000FCD0 0x995C # 0 +0x0000FCD1 0x9A5A # 0 +0x0000FCD2 0x9A5B # 0 +0x0000FCD3 0x9A57 # 0 +0x0000FCD4 0x9AD3 # 0 +0x0000FCD5 0x9AD4 # 0 +0x0000FCD6 0x9AD1 # 0 +0x0000FCD7 0x9C54 # 0 +0x0000FCD8 0x9C57 # 0 +0x0000FCD9 0x9C56 # 0 +0x0000FCDA 0x9DE5 # 0 +0x0000FCDB 0x9E9F # 0 +0x0000FCDC 0x9EF4 # 0 +0x0000FCDD 0x56D1 # 0 +0x0000FCDE 0x58E9 # 0 +0x0000FCDF 0x652C # 0 +0x0000FCE0 0x705E # 0 +0x0000FCE1 0x7671 # 0 +0x0000FCE2 0x7672 # 0 +0x0000FCE3 0x77D7 # 0 +0x0000FCE4 0x7F50 # 0 +0x0000FCE5 0x7F88 # 0 +0x0000FCE6 0x8836 # 0 +0x0000FCE7 0x8839 # 0 +0x0000FCE8 0x8862 # 0 +0x0000FCE9 0x8B93 # 0 +0x0000FCEA 0x8B92 # 0 +0x0000FCEB 0x8B96 # 0 +0x0000FCEC 0x8277 # 0 +0x0000FCED 0x8D1B # 0 +0x0000FCEE 0x91C0 # 0 +0x0000FCEF 0x946A # 0 +0x0000FCF0 0x9742 # 0 +0x0000FCF1 0x9748 # 0 +0x0000FCF2 0x9744 # 0 +0x0000FCF3 0x97C6 # 0 +0x0000FCF4 0x9870 # 0 +0x0000FCF5 0x9A5F # 0 +0x0000FCF6 0x9B22 # 0 +0x0000FCF7 0x9B58 # 0 +0x0000FCF8 0x9C5F # 0 +0x0000FCF9 0x9DF9 # 0 +0x0000FCFA 0x9DFA # 0 +0x0000FCFB 0x9E7C # 0 +0x0000FCFC 0x9E7D # 0 +0x0000FCFD 0x9F07 # 0 +0x0000FCFE 0x9F77 # 0 +0x0000FDA1 0x9F72 # 0 +0x0000FDA2 0x5EF3 # 0 +0x0000FDA3 0x6B16 # 0 +0x0000FDA4 0x7063 # 0 +0x0000FDA5 0x7C6C # 0 +0x0000FDA6 0x7C6E # 0 +0x0000FDA7 0x883B # 0 +0x0000FDA8 0x89C0 # 0 +0x0000FDA9 0x8EA1 # 0 +0x0000FDAA 0x91C1 # 0 +0x0000FDAB 0x9472 # 0 +0x0000FDAC 0x9470 # 0 +0x0000FDAD 0x9871 # 0 +0x0000FDAE 0x995E # 0 +0x0000FDAF 0x9AD6 # 0 +0x0000FDB0 0x9B23 # 0 +0x0000FDB1 0x9ECC # 0 +0x0000FDB2 0x7064 # 0 +0x0000FDB3 0x77DA # 0 +0x0000FDB4 0x8B9A # 0 +0x0000FDB5 0x9477 # 0 +0x0000FDB6 0x97C9 # 0 +0x0000FDB7 0x9A62 # 0 +0x0000FDB8 0x9A65 # 0 +0x0000FDB9 0x7E9C # 0 +0x0000FDBA 0x8B9C # 0 +0x0000FDBB 0x8EAA # 0 +0x0000FDBC 0x91C5 # 0 +0x0000FDBD 0x947D # 0 +0x0000FDBE 0x947E # 0 +0x0000FDBF 0x947C # 0 +0x0000FDC0 0x9C77 # 0 +0x0000FDC1 0x9C78 # 0 +0x0000FDC2 0x9EF7 # 0 +0x0000FDC3 0x8C54 # 0 +0x0000FDC4 0x947F # 0 +0x0000FDC5 0x9E1A # 0 +0x0000FDC6 0x7228 # 0 +0x0000FDC7 0x9A6A # 0 +0x0000FDC8 0x9B31 # 0 +0x0000FDC9 0x9E1B # 0 +0x0000FDCA 0x9E1E # 0 +0x0000FDCB 0x7C72 # 0 +0x8EA2A1A1 0x4E42 # 0 +0x8EA2A1A2 0x4E5C # 0 +0x8EA2A1A3 0x51F5 # 0 +0x8EA2A1A4 0x531A # 0 +0x8EA2A1A5 0x5382 # 0 +0x8EA2A1A6 0x4E07 # 0 +0x8EA2A1A7 0x4E0C # 0 +0x8EA2A1A8 0x4E47 # 0 +0x8EA2A1A9 0x4E8D # 0 +0x8EA2A1AA 0x56D7 # 0 +0x8EA2A1AB 0x5C6E # 0 +0x8EA2A1AC 0x5F73 # 0 +0x8EA2A1AD 0x4E0F # 0 +0x8EA2A1AE 0x5187 # 0 +0x8EA2A1AF 0x4E0E # 0 +0x8EA2A1B0 0x4E2E # 0 +0x8EA2A1B1 0x4E93 # 0 +0x8EA2A1B2 0x4EC2 # 0 +0x8EA2A1B3 0x4EC9 # 0 +0x8EA2A1B4 0x4EC8 # 0 +0x8EA2A1B5 0x5198 # 0 +0x8EA2A1B6 0x52FC # 0 +0x8EA2A1B7 0x536C # 0 +0x8EA2A1B8 0x53B9 # 0 +0x8EA2A1B9 0x5720 # 0 +0x8EA2A1BA 0x5903 # 0 +0x8EA2A1BB 0x592C # 0 +0x8EA2A1BC 0x5C10 # 0 +0x8EA2A1BD 0x5DFF # 0 +0x8EA2A1BE 0x65E1 # 0 +0x8EA2A1BF 0x6BB3 # 0 +0x8EA2A1C0 0x6BCC # 0 +0x8EA2A1C1 0x6C14 # 0 +0x8EA2A1C2 0x723F # 0 +0x8EA2A1C3 0x4E31 # 0 +0x8EA2A1C4 0x4E3C # 0 +0x8EA2A1C5 0x4EE8 # 0 +0x8EA2A1C6 0x4EDC # 0 +0x8EA2A1C7 0x4EE9 # 0 +0x8EA2A1C8 0x4EE1 # 0 +0x8EA2A1C9 0x4EDD # 0 +0x8EA2A1CA 0x4EDA # 0 +0x8EA2A1CB 0x520C # 0 +0x8EA2A1CC 0x5209 # 0 +0x8EA2A1CD 0x531C # 0 +0x8EA2A1CE 0x534C # 0 +0x8EA2A1CF 0x5722 # 0 +0x8EA2A1D0 0x5723 # 0 +0x8EA2A1D1 0x5917 # 0 +0x8EA2A1D2 0x592F # 0 +0x8EA2A1D3 0x5B81 # 0 +0x8EA2A1D4 0x5B84 # 0 +0x8EA2A1D5 0x5C12 # 0 +0x8EA2A1D6 0x5C3B # 0 +0x8EA2A1D7 0x5C74 # 0 +0x8EA2A1D8 0x5C73 # 0 +0x8EA2A1D9 0x5E04 # 0 +0x8EA2A1DA 0x5E80 # 0 +0x8EA2A1DB 0x5E82 # 0 +0x8EA2A1DC 0x5FC9 # 0 +0x8EA2A1DD 0x6209 # 0 +0x8EA2A1DE 0x6250 # 0 +0x8EA2A1DF 0x6C15 # 0 +0x8EA2A1E0 0x6C36 # 0 +0x8EA2A1E1 0x6C43 # 0 +0x8EA2A1E2 0x6C3F # 0 +0x8EA2A1E3 0x6C3B # 0 +0x8EA2A1E4 0x72AE # 0 +0x8EA2A1E5 0x72B0 # 0 +0x8EA2A1E6 0x738A # 0 +0x8EA2A1E7 0x79B8 # 0 +0x8EA2A1E8 0x808A # 0 +0x8EA2A1E9 0x961E # 0 +0x8EA2A1EA 0x4F0E # 0 +0x8EA2A1EB 0x4F18 # 0 +0x8EA2A1EC 0x4F2C # 0 +0x8EA2A1ED 0x4EF5 # 0 +0x8EA2A1EE 0x4F14 # 0 +0x8EA2A1EF 0x4EF1 # 0 +0x8EA2A1F0 0x4F00 # 0 +0x8EA2A1F1 0x4EF7 # 0 +0x8EA2A1F2 0x4F08 # 0 +0x8EA2A1F3 0x4F1D # 0 +0x8EA2A1F4 0x4F02 # 0 +0x8EA2A1F5 0x4F05 # 0 +0x8EA2A1F6 0x4F22 # 0 +0x8EA2A1F7 0x4F13 # 0 +0x8EA2A1F8 0x4F04 # 0 +0x8EA2A1F9 0x4EF4 # 0 +0x8EA2A1FA 0x4F12 # 0 +0x8EA2A1FB 0x51B1 # 0 +0x8EA2A1FC 0x5213 # 0 +0x8EA2A1FD 0x5210 # 0 +0x8EA2A1FE 0x52A6 # 0 +0x8EA2A2A1 0x5322 # 0 +0x8EA2A2A2 0x531F # 0 +0x8EA2A2A3 0x534D # 0 +0x8EA2A2A4 0x538A # 0 +0x8EA2A2A5 0x5407 # 0 +0x8EA2A2A6 0x56E1 # 0 +0x8EA2A2A7 0x56DF # 0 +0x8EA2A2A8 0x572E # 0 +0x8EA2A2A9 0x572A # 0 +0x8EA2A2AA 0x5734 # 0 +0x8EA2A2AB 0x593C # 0 +0x8EA2A2AC 0x5980 # 0 +0x8EA2A2AD 0x597C # 0 +0x8EA2A2AE 0x5985 # 0 +0x8EA2A2AF 0x597B # 0 +0x8EA2A2B0 0x597E # 0 +0x8EA2A2B1 0x5977 # 0 +0x8EA2A2B2 0x597F # 0 +0x8EA2A2B3 0x5B56 # 0 +0x8EA2A2B4 0x5C15 # 0 +0x8EA2A2B5 0x5C25 # 0 +0x8EA2A2B6 0x5C7C # 0 +0x8EA2A2B7 0x5C7A # 0 +0x8EA2A2B8 0x5C7B # 0 +0x8EA2A2B9 0x5C7E # 0 +0x8EA2A2BA 0x5DDF # 0 +0x8EA2A2BB 0x5E75 # 0 +0x8EA2A2BC 0x5E84 # 0 +0x8EA2A2BD 0x5F02 # 0 +0x8EA2A2BE 0x5F1A # 0 +0x8EA2A2BF 0x5F74 # 0 +0x8EA2A2C0 0x5FD5 # 0 +0x8EA2A2C1 0x5FD4 # 0 +0x8EA2A2C2 0x5FCF # 0 +0x8EA2A2C3 0x625C # 0 +0x8EA2A2C4 0x625E # 0 +0x8EA2A2C5 0x6264 # 0 +0x8EA2A2C6 0x6261 # 0 +0x8EA2A2C7 0x6266 # 0 +0x8EA2A2C8 0x6262 # 0 +0x8EA2A2C9 0x6259 # 0 +0x8EA2A2CA 0x6260 # 0 +0x8EA2A2CB 0x625A # 0 +0x8EA2A2CC 0x6265 # 0 +0x8EA2A2CD 0x6537 # 0 +0x8EA2A2CE 0x65EF # 0 +0x8EA2A2CF 0x65EE # 0 +0x8EA2A2D0 0x673E # 0 +0x8EA2A2D1 0x6739 # 0 +0x8EA2A2D2 0x6738 # 0 +0x8EA2A2D3 0x673B # 0 +0x8EA2A2D4 0x673A # 0 +0x8EA2A2D5 0x673F # 0 +0x8EA2A2D6 0x673C # 0 +0x8EA2A2D7 0x6733 # 0 +0x8EA2A2D8 0x6C18 # 0 +0x8EA2A2D9 0x6C46 # 0 +0x8EA2A2DA 0x6C52 # 0 +0x8EA2A2DB 0x6C5C # 0 +0x8EA2A2DC 0x6C4F # 0 +0x8EA2A2DD 0x6C4A # 0 +0x8EA2A2DE 0x6C54 # 0 +0x8EA2A2DF 0x6C4B # 0 +0x8EA2A2E0 0x6C4C # 0 +0x8EA2A2E1 0x7071 # 0 +0x8EA2A2E2 0x725E # 0 +0x8EA2A2E3 0x72B4 # 0 +0x8EA2A2E4 0x72B5 # 0 +0x8EA2A2E5 0x738E # 0 +0x8EA2A2E6 0x752A # 0 +0x8EA2A2E7 0x767F # 0 +0x8EA2A2E8 0x7A75 # 0 +0x8EA2A2E9 0x7F51 # 0 +0x8EA2A2EA 0x8278 # 0 +0x8EA2A2EB 0x827C # 0 +0x8EA2A2EC 0x8280 # 0 +0x8EA2A2ED 0x827D # 0 +0x8EA2A2EE 0x827F # 0 +0x8EA2A2EF 0x864D # 0 +0x8EA2A2F0 0x897E # 0 +0x8EA2A2F1 0x9099 # 0 +0x8EA2A2F2 0x9097 # 0 +0x8EA2A2F3 0x9098 # 0 +0x8EA2A2F4 0x909B # 0 +0x8EA2A2F5 0x9094 # 0 +0x8EA2A2F6 0x9622 # 0 +0x8EA2A2F7 0x9624 # 0 +0x8EA2A2F8 0x9620 # 0 +0x8EA2A2F9 0x9623 # 0 +0x8EA2A2FA 0x4F56 # 0 +0x8EA2A2FB 0x4F3B # 0 +0x8EA2A2FC 0x4F62 # 0 +0x8EA2A2FD 0x4F49 # 0 +0x8EA2A2FE 0x4F53 # 0 +0x8EA2A3A1 0x4F64 # 0 +0x8EA2A3A2 0x4F3E # 0 +0x8EA2A3A3 0x4F67 # 0 +0x8EA2A3A4 0x4F52 # 0 +0x8EA2A3A5 0x4F5F # 0 +0x8EA2A3A6 0x4F41 # 0 +0x8EA2A3A7 0x4F58 # 0 +0x8EA2A3A8 0x4F2D # 0 +0x8EA2A3A9 0x4F33 # 0 +0x8EA2A3AA 0x4F3F # 0 +0x8EA2A3AB 0x4F61 # 0 +0x8EA2A3AC 0x518F # 0 +0x8EA2A3AD 0x51B9 # 0 +0x8EA2A3AE 0x521C # 0 +0x8EA2A3AF 0x521E # 0 +0x8EA2A3B0 0x5221 # 0 +0x8EA2A3B1 0x52AD # 0 +0x8EA2A3B2 0x52AE # 0 +0x8EA2A3B3 0x5309 # 0 +0x8EA2A3B4 0x5363 # 0 +0x8EA2A3B5 0x5372 # 0 +0x8EA2A3B6 0x538E # 0 +0x8EA2A3B7 0x538F # 0 +0x8EA2A3B8 0x5430 # 0 +0x8EA2A3B9 0x5437 # 0 +0x8EA2A3BA 0x542A # 0 +0x8EA2A3BB 0x5454 # 0 +0x8EA2A3BC 0x5445 # 0 +0x8EA2A3BD 0x5419 # 0 +0x8EA2A3BE 0x541C # 0 +0x8EA2A3BF 0x5425 # 0 +0x8EA2A3C0 0x5418 # 0 +0x8EA2A3C1 0x543D # 0 +0x8EA2A3C2 0x544F # 0 +0x8EA2A3C3 0x5441 # 0 +0x8EA2A3C4 0x5428 # 0 +0x8EA2A3C5 0x5424 # 0 +0x8EA2A3C6 0x5447 # 0 +0x8EA2A3C7 0x56EE # 0 +0x8EA2A3C8 0x56E7 # 0 +0x8EA2A3C9 0x56E5 # 0 +0x8EA2A3CA 0x5741 # 0 +0x8EA2A3CB 0x5745 # 0 +0x8EA2A3CC 0x574C # 0 +0x8EA2A3CD 0x5749 # 0 +0x8EA2A3CE 0x574B # 0 +0x8EA2A3CF 0x5752 # 0 +0x8EA2A3D0 0x5906 # 0 +0x8EA2A3D1 0x5940 # 0 +0x8EA2A3D2 0x59A6 # 0 +0x8EA2A3D3 0x5998 # 0 +0x8EA2A3D4 0x59A0 # 0 +0x8EA2A3D5 0x5997 # 0 +0x8EA2A3D6 0x598E # 0 +0x8EA2A3D7 0x59A2 # 0 +0x8EA2A3D8 0x5990 # 0 +0x8EA2A3D9 0x598F # 0 +0x8EA2A3DA 0x59A7 # 0 +0x8EA2A3DB 0x59A1 # 0 +0x8EA2A3DC 0x5B8E # 0 +0x8EA2A3DD 0x5B92 # 0 +0x8EA2A3DE 0x5C28 # 0 +0x8EA2A3DF 0x5C2A # 0 +0x8EA2A3E0 0x5C8D # 0 +0x8EA2A3E1 0x5C8F # 0 +0x8EA2A3E2 0x5C88 # 0 +0x8EA2A3E3 0x5C8B # 0 +0x8EA2A3E4 0x5C89 # 0 +0x8EA2A3E5 0x5C92 # 0 +0x8EA2A3E6 0x5C8A # 0 +0x8EA2A3E7 0x5C86 # 0 +0x8EA2A3E8 0x5C93 # 0 +0x8EA2A3E9 0x5C95 # 0 +0x8EA2A3EA 0x5DE0 # 0 +0x8EA2A3EB 0x5E0A # 0 +0x8EA2A3EC 0x5E0E # 0 +0x8EA2A3ED 0x5E8B # 0 +0x8EA2A3EE 0x5E89 # 0 +0x8EA2A3EF 0x5E8C # 0 +0x8EA2A3F0 0x5E88 # 0 +0x8EA2A3F1 0x5E8D # 0 +0x8EA2A3F2 0x5F05 # 0 +0x8EA2A3F3 0x5F1D # 0 +0x8EA2A3F4 0x5F78 # 0 +0x8EA2A3F5 0x5F76 # 0 +0x8EA2A3F6 0x5FD2 # 0 +0x8EA2A3F7 0x5FD1 # 0 +0x8EA2A3F8 0x5FD0 # 0 +0x8EA2A3F9 0x5FED # 0 +0x8EA2A3FA 0x5FE8 # 0 +0x8EA2A3FB 0x5FEE # 0 +0x8EA2A3FC 0x5FF3 # 0 +0x8EA2A3FD 0x5FE1 # 0 +0x8EA2A3FE 0x5FE4 # 0 +0x8EA2A4A1 0x5FE3 # 0 +0x8EA2A4A2 0x5FFA # 0 +0x8EA2A4A3 0x5FEF # 0 +0x8EA2A4A4 0x5FF7 # 0 +0x8EA2A4A5 0x5FFB # 0 +0x8EA2A4A6 0x6000 # 0 +0x8EA2A4A7 0x5FF4 # 0 +0x8EA2A4A8 0x623A # 0 +0x8EA2A4A9 0x6283 # 0 +0x8EA2A4AA 0x628C # 0 +0x8EA2A4AB 0x628E # 0 +0x8EA2A4AC 0x628F # 0 +0x8EA2A4AD 0x6294 # 0 +0x8EA2A4AE 0x6287 # 0 +0x8EA2A4AF 0x6271 # 0 +0x8EA2A4B0 0x627B # 0 +0x8EA2A4B1 0x627A # 0 +0x8EA2A4B2 0x6270 # 0 +0x8EA2A4B3 0x6281 # 0 +0x8EA2A4B4 0x6288 # 0 +0x8EA2A4B5 0x6277 # 0 +0x8EA2A4B6 0x627D # 0 +0x8EA2A4B7 0x6272 # 0 +0x8EA2A4B8 0x6274 # 0 +0x8EA2A4B9 0x65F0 # 0 +0x8EA2A4BA 0x65F4 # 0 +0x8EA2A4BB 0x65F3 # 0 +0x8EA2A4BC 0x65F2 # 0 +0x8EA2A4BD 0x65F5 # 0 +0x8EA2A4BE 0x6745 # 0 +0x8EA2A4BF 0x6747 # 0 +0x8EA2A4C0 0x6759 # 0 +0x8EA2A4C1 0x6755 # 0 +0x8EA2A4C2 0x674C # 0 +0x8EA2A4C3 0x6748 # 0 +0x8EA2A4C4 0x675D # 0 +0x8EA2A4C5 0x674D # 0 +0x8EA2A4C6 0x675A # 0 +0x8EA2A4C7 0x674B # 0 +0x8EA2A4C8 0x6BD0 # 0 +0x8EA2A4C9 0x6C19 # 0 +0x8EA2A4CA 0x6C1A # 0 +0x8EA2A4CB 0x6C78 # 0 +0x8EA2A4CC 0x6C67 # 0 +0x8EA2A4CD 0x6C6B # 0 +0x8EA2A4CE 0x6C84 # 0 +0x8EA2A4CF 0x6C8B # 0 +0x8EA2A4D0 0x6C8F # 0 +0x8EA2A4D1 0x6C71 # 0 +0x8EA2A4D2 0x6C6F # 0 +0x8EA2A4D3 0x6C69 # 0 +0x8EA2A4D4 0x6C9A # 0 +0x8EA2A4D5 0x6C6D # 0 +0x8EA2A4D6 0x6C87 # 0 +0x8EA2A4D7 0x6C95 # 0 +0x8EA2A4D8 0x6C9C # 0 +0x8EA2A4D9 0x6C66 # 0 +0x8EA2A4DA 0x6C73 # 0 +0x8EA2A4DB 0x6C65 # 0 +0x8EA2A4DC 0x6C7B # 0 +0x8EA2A4DD 0x6C8E # 0 +0x8EA2A4DE 0x7074 # 0 +0x8EA2A4DF 0x707A # 0 +0x8EA2A4E0 0x7263 # 0 +0x8EA2A4E1 0x72BF # 0 +0x8EA2A4E2 0x72BD # 0 +0x8EA2A4E3 0x72C3 # 0 +0x8EA2A4E4 0x72C6 # 0 +0x8EA2A4E5 0x72C1 # 0 +0x8EA2A4E6 0x72BA # 0 +0x8EA2A4E7 0x72C5 # 0 +0x8EA2A4E8 0x7395 # 0 +0x8EA2A4E9 0x7397 # 0 +0x8EA2A4EA 0x7393 # 0 +0x8EA2A4EB 0x7394 # 0 +0x8EA2A4EC 0x7392 # 0 +0x8EA2A4ED 0x753A # 0 +0x8EA2A4EE 0x7539 # 0 +0x8EA2A4EF 0x7594 # 0 +0x8EA2A4F0 0x7595 # 0 +0x8EA2A4F1 0x7681 # 0 +0x8EA2A4F2 0x793D # 0 +0x8EA2A4F3 0x8034 # 0 +0x8EA2A4F4 0x8095 # 0 +0x8EA2A4F5 0x8099 # 0 +0x8EA2A4F6 0x8090 # 0 +0x8EA2A4F7 0x8092 # 0 +0x8EA2A4F8 0x809C # 0 +0x8EA2A4F9 0x8290 # 0 +0x8EA2A4FA 0x828F # 0 +0x8EA2A4FB 0x8285 # 0 +0x8EA2A4FC 0x828E # 0 +0x8EA2A4FD 0x8291 # 0 +0x8EA2A4FE 0x8293 # 0 +0x8EA2A5A1 0x828A # 0 +0x8EA2A5A2 0x8283 # 0 +0x8EA2A5A3 0x8284 # 0 +0x8EA2A5A4 0x8C78 # 0 +0x8EA2A5A5 0x8FC9 # 0 +0x8EA2A5A6 0x8FBF # 0 +0x8EA2A5A7 0x909F # 0 +0x8EA2A5A8 0x90A1 # 0 +0x8EA2A5A9 0x90A5 # 0 +0x8EA2A5AA 0x909E # 0 +0x8EA2A5AB 0x90A7 # 0 +0x8EA2A5AC 0x90A0 # 0 +0x8EA2A5AD 0x9630 # 0 +0x8EA2A5AE 0x9628 # 0 +0x8EA2A5AF 0x962F # 0 +0x8EA2A5B0 0x962D # 0 +0x8EA2A5B1 0x4E33 # 0 +0x8EA2A5B2 0x4F98 # 0 +0x8EA2A5B3 0x4F7C # 0 +0x8EA2A5B4 0x4F85 # 0 +0x8EA2A5B5 0x4F7D # 0 +0x8EA2A5B6 0x4F80 # 0 +0x8EA2A5B7 0x4F87 # 0 +0x8EA2A5B8 0x4F76 # 0 +0x8EA2A5B9 0x4F74 # 0 +0x8EA2A5BA 0x4F89 # 0 +0x8EA2A5BB 0x4F84 # 0 +0x8EA2A5BC 0x4F77 # 0 +0x8EA2A5BD 0x4F4C # 0 +0x8EA2A5BE 0x4F97 # 0 +0x8EA2A5BF 0x4F6A # 0 +0x8EA2A5C0 0x4F9A # 0 +0x8EA2A5C1 0x4F79 # 0 +0x8EA2A5C2 0x4F81 # 0 +0x8EA2A5C3 0x4F78 # 0 +0x8EA2A5C4 0x4F90 # 0 +0x8EA2A5C5 0x4F9C # 0 +0x8EA2A5C6 0x4F94 # 0 +0x8EA2A5C7 0x4F9E # 0 +0x8EA2A5C8 0x4F92 # 0 +0x8EA2A5C9 0x4F82 # 0 +0x8EA2A5CA 0x4F95 # 0 +0x8EA2A5CB 0x4F6B # 0 +0x8EA2A5CC 0x4F6E # 0 +0x8EA2A5CD 0x519E # 0 +0x8EA2A5CE 0x51BC # 0 +0x8EA2A5CF 0x51BE # 0 +0x8EA2A5D0 0x5235 # 0 +0x8EA2A5D1 0x5232 # 0 +0x8EA2A5D2 0x5233 # 0 +0x8EA2A5D3 0x5246 # 0 +0x8EA2A5D4 0x5231 # 0 +0x8EA2A5D5 0x52BC # 0 +0x8EA2A5D6 0x530A # 0 +0x8EA2A5D7 0x530B # 0 +0x8EA2A5D8 0x533C # 0 +0x8EA2A5D9 0x5392 # 0 +0x8EA2A5DA 0x5394 # 0 +0x8EA2A5DB 0x5487 # 0 +0x8EA2A5DC 0x547F # 0 +0x8EA2A5DD 0x5481 # 0 +0x8EA2A5DE 0x5491 # 0 +0x8EA2A5DF 0x5482 # 0 +0x8EA2A5E0 0x5488 # 0 +0x8EA2A5E1 0x546B # 0 +0x8EA2A5E2 0x547A # 0 +0x8EA2A5E3 0x547E # 0 +0x8EA2A5E4 0x5465 # 0 +0x8EA2A5E5 0x546C # 0 +0x8EA2A5E6 0x5474 # 0 +0x8EA2A5E7 0x5466 # 0 +0x8EA2A5E8 0x548D # 0 +0x8EA2A5E9 0x546F # 0 +0x8EA2A5EA 0x5461 # 0 +0x8EA2A5EB 0x5460 # 0 +0x8EA2A5EC 0x5498 # 0 +0x8EA2A5ED 0x5463 # 0 +0x8EA2A5EE 0x5467 # 0 +0x8EA2A5EF 0x5464 # 0 +0x8EA2A5F0 0x56F7 # 0 +0x8EA2A5F1 0x56F9 # 0 +0x8EA2A5F2 0x576F # 0 +0x8EA2A5F3 0x5772 # 0 +0x8EA2A5F4 0x576D # 0 +0x8EA2A5F5 0x576B # 0 +0x8EA2A5F6 0x5771 # 0 +0x8EA2A5F7 0x5770 # 0 +0x8EA2A5F8 0x5776 # 0 +0x8EA2A5F9 0x5780 # 0 +0x8EA2A5FA 0x5775 # 0 +0x8EA2A5FB 0x577B # 0 +0x8EA2A5FC 0x5773 # 0 +0x8EA2A5FD 0x5774 # 0 +0x8EA2A5FE 0x5762 # 0 +0x8EA2A6A1 0x5768 # 0 +0x8EA2A6A2 0x577D # 0 +0x8EA2A6A3 0x590C # 0 +0x8EA2A6A4 0x5945 # 0 +0x8EA2A6A5 0x59B5 # 0 +0x8EA2A6A6 0x59BA # 0 +0x8EA2A6A7 0x59CF # 0 +0x8EA2A6A8 0x59CE # 0 +0x8EA2A6A9 0x59B2 # 0 +0x8EA2A6AA 0x59CC # 0 +0x8EA2A6AB 0x59C1 # 0 +0x8EA2A6AC 0x59B6 # 0 +0x8EA2A6AD 0x59BC # 0 +0x8EA2A6AE 0x59C3 # 0 +0x8EA2A6AF 0x59D6 # 0 +0x8EA2A6B0 0x59B1 # 0 +0x8EA2A6B1 0x59BD # 0 +0x8EA2A6B2 0x59C0 # 0 +0x8EA2A6B3 0x59C8 # 0 +0x8EA2A6B4 0x59B4 # 0 +0x8EA2A6B5 0x59C7 # 0 +0x8EA2A6B6 0x5B62 # 0 +0x8EA2A6B7 0x5B65 # 0 +0x8EA2A6B8 0x5B93 # 0 +0x8EA2A6B9 0x5B95 # 0 +0x8EA2A6BA 0x5C44 # 0 +0x8EA2A6BB 0x5C47 # 0 +0x8EA2A6BC 0x5CAE # 0 +0x8EA2A6BD 0x5CA4 # 0 +0x8EA2A6BE 0x5CA0 # 0 +0x8EA2A6BF 0x5CB5 # 0 +0x8EA2A6C0 0x5CAF # 0 +0x8EA2A6C1 0x5CA8 # 0 +0x8EA2A6C2 0x5CAC # 0 +0x8EA2A6C3 0x5C9F # 0 +0x8EA2A6C4 0x5CA3 # 0 +0x8EA2A6C5 0x5CAD # 0 +0x8EA2A6C6 0x5CA2 # 0 +0x8EA2A6C7 0x5CAA # 0 +0x8EA2A6C8 0x5CA7 # 0 +0x8EA2A6C9 0x5C9D # 0 +0x8EA2A6CA 0x5CA5 # 0 +0x8EA2A6CB 0x5CB6 # 0 +0x8EA2A6CC 0x5CB0 # 0 +0x8EA2A6CD 0x5CA6 # 0 +0x8EA2A6CE 0x5E17 # 0 +0x8EA2A6CF 0x5E14 # 0 +0x8EA2A6D0 0x5E19 # 0 +0x8EA2A6D1 0x5F28 # 0 +0x8EA2A6D2 0x5F22 # 0 +0x8EA2A6D3 0x5F23 # 0 +0x8EA2A6D4 0x5F24 # 0 +0x8EA2A6D5 0x5F54 # 0 +0x8EA2A6D6 0x5F82 # 0 +0x8EA2A6D7 0x5F7E # 0 +0x8EA2A6D8 0x5F7D # 0 +0x8EA2A6D9 0x5FDE # 0 +0x8EA2A6DA 0x5FE5 # 0 +0x8EA2A6DB 0x602D # 0 +0x8EA2A6DC 0x6026 # 0 +0x8EA2A6DD 0x6019 # 0 +0x8EA2A6DE 0x6032 # 0 +0x8EA2A6DF 0x600B # 0 +0x8EA2A6E0 0x6034 # 0 +0x8EA2A6E1 0x600A # 0 +0x8EA2A6E2 0x6017 # 0 +0x8EA2A6E3 0x6033 # 0 +0x8EA2A6E4 0x601A # 0 +0x8EA2A6E5 0x601E # 0 +0x8EA2A6E6 0x602C # 0 +0x8EA2A6E7 0x6022 # 0 +0x8EA2A6E8 0x600D # 0 +0x8EA2A6E9 0x6010 # 0 +0x8EA2A6EA 0x602E # 0 +0x8EA2A6EB 0x6013 # 0 +0x8EA2A6EC 0x6011 # 0 +0x8EA2A6ED 0x600C # 0 +0x8EA2A6EE 0x6009 # 0 +0x8EA2A6EF 0x601C # 0 +0x8EA2A6F0 0x6214 # 0 +0x8EA2A6F1 0x623D # 0 +0x8EA2A6F2 0x62AD # 0 +0x8EA2A6F3 0x62B4 # 0 +0x8EA2A6F4 0x62D1 # 0 +0x8EA2A6F5 0x62BE # 0 +0x8EA2A6F6 0x62AA # 0 +0x8EA2A6F7 0x62B6 # 0 +0x8EA2A6F8 0x62CA # 0 +0x8EA2A6F9 0x62AE # 0 +0x8EA2A6FA 0x62B3 # 0 +0x8EA2A6FB 0x62AF # 0 +0x8EA2A6FC 0x62BB # 0 +0x8EA2A6FD 0x62A9 # 0 +0x8EA2A6FE 0x62B0 # 0 +0x8EA2A7A1 0x62B8 # 0 +0x8EA2A7A2 0x653D # 0 +0x8EA2A7A3 0x65A8 # 0 +0x8EA2A7A4 0x65BB # 0 +0x8EA2A7A5 0x6609 # 0 +0x8EA2A7A6 0x65FC # 0 +0x8EA2A7A7 0x6604 # 0 +0x8EA2A7A8 0x6612 # 0 +0x8EA2A7A9 0x6608 # 0 +0x8EA2A7AA 0x65FB # 0 +0x8EA2A7AB 0x6603 # 0 +0x8EA2A7AC 0x660B # 0 +0x8EA2A7AD 0x660D # 0 +0x8EA2A7AE 0x6605 # 0 +0x8EA2A7AF 0x65FD # 0 +0x8EA2A7B0 0x6611 # 0 +0x8EA2A7B1 0x6610 # 0 +0x8EA2A7B2 0x66F6 # 0 +0x8EA2A7B3 0x670A # 0 +0x8EA2A7B4 0x6785 # 0 +0x8EA2A7B5 0x676C # 0 +0x8EA2A7B6 0x678E # 0 +0x8EA2A7B7 0x6792 # 0 +0x8EA2A7B8 0x6776 # 0 +0x8EA2A7B9 0x677B # 0 +0x8EA2A7BA 0x6798 # 0 +0x8EA2A7BB 0x6786 # 0 +0x8EA2A7BC 0x6784 # 0 +0x8EA2A7BD 0x6774 # 0 +0x8EA2A7BE 0x678D # 0 +0x8EA2A7BF 0x678C # 0 +0x8EA2A7C0 0x677A # 0 +0x8EA2A7C1 0x679F # 0 +0x8EA2A7C2 0x6791 # 0 +0x8EA2A7C3 0x6799 # 0 +0x8EA2A7C4 0x6783 # 0 +0x8EA2A7C5 0x677D # 0 +0x8EA2A7C6 0x6781 # 0 +0x8EA2A7C7 0x6778 # 0 +0x8EA2A7C8 0x6779 # 0 +0x8EA2A7C9 0x6794 # 0 +0x8EA2A7CA 0x6B25 # 0 +0x8EA2A7CB 0x6B80 # 0 +0x8EA2A7CC 0x6B7E # 0 +0x8EA2A7CD 0x6BDE # 0 +0x8EA2A7CE 0x6C1D # 0 +0x8EA2A7CF 0x6C93 # 0 +0x8EA2A7D0 0x6CEC # 0 +0x8EA2A7D1 0x6CEB # 0 +0x8EA2A7D2 0x6CEE # 0 +0x8EA2A7D3 0x6CD9 # 0 +0x8EA2A7D4 0x6CB6 # 0 +0x8EA2A7D5 0x6CD4 # 0 +0x8EA2A7D6 0x6CAD # 0 +0x8EA2A7D7 0x6CE7 # 0 +0x8EA2A7D8 0x6CB7 # 0 +0x8EA2A7D9 0x6CD0 # 0 +0x8EA2A7DA 0x6CC2 # 0 +0x8EA2A7DB 0x6CBA # 0 +0x8EA2A7DC 0x6CC3 # 0 +0x8EA2A7DD 0x6CC6 # 0 +0x8EA2A7DE 0x6CED # 0 +0x8EA2A7DF 0x6CF2 # 0 +0x8EA2A7E0 0x6CD2 # 0 +0x8EA2A7E1 0x6CDD # 0 +0x8EA2A7E2 0x6CB4 # 0 +0x8EA2A7E3 0x6C8A # 0 +0x8EA2A7E4 0x6C9D # 0 +0x8EA2A7E5 0x6C80 # 0 +0x8EA2A7E6 0x6CDE # 0 +0x8EA2A7E7 0x6CC0 # 0 +0x8EA2A7E8 0x6D30 # 0 +0x8EA2A7E9 0x6CCD # 0 +0x8EA2A7EA 0x6CC7 # 0 +0x8EA2A7EB 0x6CB0 # 0 +0x8EA2A7EC 0x6CF9 # 0 +0x8EA2A7ED 0x6CCF # 0 +0x8EA2A7EE 0x6CE9 # 0 +0x8EA2A7EF 0x6CD1 # 0 +0x8EA2A7F0 0x7094 # 0 +0x8EA2A7F1 0x7098 # 0 +0x8EA2A7F2 0x7085 # 0 +0x8EA2A7F3 0x7093 # 0 +0x8EA2A7F4 0x7086 # 0 +0x8EA2A7F5 0x7084 # 0 +0x8EA2A7F6 0x7091 # 0 +0x8EA2A7F7 0x7096 # 0 +0x8EA2A7F8 0x7082 # 0 +0x8EA2A7F9 0x709A # 0 +0x8EA2A7FA 0x7083 # 0 +0x8EA2A7FB 0x726A # 0 +0x8EA2A7FC 0x72D6 # 0 +0x8EA2A7FD 0x72CB # 0 +0x8EA2A7FE 0x72D8 # 0 +0x8EA2A8A1 0x72C9 # 0 +0x8EA2A8A2 0x72DC # 0 +0x8EA2A8A3 0x72D2 # 0 +0x8EA2A8A4 0x72D4 # 0 +0x8EA2A8A5 0x72DA # 0 +0x8EA2A8A6 0x72CC # 0 +0x8EA2A8A7 0x72D1 # 0 +0x8EA2A8A8 0x73A4 # 0 +0x8EA2A8A9 0x73A1 # 0 +0x8EA2A8AA 0x73AD # 0 +0x8EA2A8AB 0x73A6 # 0 +0x8EA2A8AC 0x73A2 # 0 +0x8EA2A8AD 0x73A0 # 0 +0x8EA2A8AE 0x73AC # 0 +0x8EA2A8AF 0x739D # 0 +0x8EA2A8B0 0x74DD # 0 +0x8EA2A8B1 0x74E8 # 0 +0x8EA2A8B2 0x753F # 0 +0x8EA2A8B3 0x7540 # 0 +0x8EA2A8B4 0x753E # 0 +0x8EA2A8B5 0x758C # 0 +0x8EA2A8B6 0x7598 # 0 +0x8EA2A8B7 0x76AF # 0 +0x8EA2A8B8 0x76F3 # 0 +0x8EA2A8B9 0x76F1 # 0 +0x8EA2A8BA 0x76F0 # 0 +0x8EA2A8BB 0x76F5 # 0 +0x8EA2A8BC 0x77F8 # 0 +0x8EA2A8BD 0x77FC # 0 +0x8EA2A8BE 0x77F9 # 0 +0x8EA2A8BF 0x77FB # 0 +0x8EA2A8C0 0x77FA # 0 +0x8EA2A8C1 0x77F7 # 0 +0x8EA2A8C2 0x7942 # 0 +0x8EA2A8C3 0x793F # 0 +0x8EA2A8C4 0x79C5 # 0 +0x8EA2A8C5 0x7A78 # 0 +0x8EA2A8C6 0x7A7B # 0 +0x8EA2A8C7 0x7AFB # 0 +0x8EA2A8C8 0x7C75 # 0 +0x8EA2A8C9 0x7CFD # 0 +0x8EA2A8CA 0x8035 # 0 +0x8EA2A8CB 0x808F # 0 +0x8EA2A8CC 0x80AE # 0 +0x8EA2A8CD 0x80A3 # 0 +0x8EA2A8CE 0x80B8 # 0 +0x8EA2A8CF 0x80B5 # 0 +0x8EA2A8D0 0x80AD # 0 +0x8EA2A8D1 0x8220 # 0 +0x8EA2A8D2 0x82A0 # 0 +0x8EA2A8D3 0x82C0 # 0 +0x8EA2A8D4 0x82AB # 0 +0x8EA2A8D5 0x829A # 0 +0x8EA2A8D6 0x8298 # 0 +0x8EA2A8D7 0x829B # 0 +0x8EA2A8D8 0x82B5 # 0 +0x8EA2A8D9 0x82A7 # 0 +0x8EA2A8DA 0x82AE # 0 +0x8EA2A8DB 0x82BC # 0 +0x8EA2A8DC 0x829E # 0 +0x8EA2A8DD 0x82BA # 0 +0x8EA2A8DE 0x82B4 # 0 +0x8EA2A8DF 0x82A8 # 0 +0x8EA2A8E0 0x82A1 # 0 +0x8EA2A8E1 0x82A9 # 0 +0x8EA2A8E2 0x82C2 # 0 +0x8EA2A8E3 0x82A4 # 0 +0x8EA2A8E4 0x82C3 # 0 +0x8EA2A8E5 0x82B6 # 0 +0x8EA2A8E6 0x82A2 # 0 +0x8EA2A8E7 0x8670 # 0 +0x8EA2A8E8 0x866F # 0 +0x8EA2A8E9 0x866D # 0 +0x8EA2A8EA 0x866E # 0 +0x8EA2A8EB 0x8C56 # 0 +0x8EA2A8EC 0x8FD2 # 0 +0x8EA2A8ED 0x8FCB # 0 +0x8EA2A8EE 0x8FD3 # 0 +0x8EA2A8EF 0x8FCD # 0 +0x8EA2A8F0 0x8FD6 # 0 +0x8EA2A8F1 0x8FD5 # 0 +0x8EA2A8F2 0x8FD7 # 0 +0x8EA2A8F3 0x90B2 # 0 +0x8EA2A8F4 0x90B4 # 0 +0x8EA2A8F5 0x90AF # 0 +0x8EA2A8F6 0x90B3 # 0 +0x8EA2A8F7 0x90B0 # 0 +0x8EA2A8F8 0x9639 # 0 +0x8EA2A8F9 0x963D # 0 +0x8EA2A8FA 0x963C # 0 +0x8EA2A8FB 0x963A # 0 +0x8EA2A8FC 0x9643 # 0 +0x8EA2A8FD 0x4FCD # 0 +0x8EA2A8FE 0x4FC5 # 0 +0x8EA2A9A1 0x4FD3 # 0 +0x8EA2A9A2 0x4FB2 # 0 +0x8EA2A9A3 0x4FC9 # 0 +0x8EA2A9A4 0x4FCB # 0 +0x8EA2A9A5 0x4FC1 # 0 +0x8EA2A9A6 0x4FD4 # 0 +0x8EA2A9A7 0x4FDC # 0 +0x8EA2A9A8 0x4FD9 # 0 +0x8EA2A9A9 0x4FBB # 0 +0x8EA2A9AA 0x4FB3 # 0 +0x8EA2A9AB 0x4FDB # 0 +0x8EA2A9AC 0x4FC7 # 0 +0x8EA2A9AD 0x4FD6 # 0 +0x8EA2A9AE 0x4FBA # 0 +0x8EA2A9AF 0x4FC0 # 0 +0x8EA2A9B0 0x4FB9 # 0 +0x8EA2A9B1 0x4FEC # 0 +0x8EA2A9B2 0x5244 # 0 +0x8EA2A9B3 0x5249 # 0 +0x8EA2A9B4 0x52C0 # 0 +0x8EA2A9B5 0x52C2 # 0 +0x8EA2A9B6 0x533D # 0 +0x8EA2A9B7 0x537C # 0 +0x8EA2A9B8 0x5397 # 0 +0x8EA2A9B9 0x5396 # 0 +0x8EA2A9BA 0x5399 # 0 +0x8EA2A9BB 0x5398 # 0 +0x8EA2A9BC 0x54BA # 0 +0x8EA2A9BD 0x54A1 # 0 +0x8EA2A9BE 0x54AD # 0 +0x8EA2A9BF 0x54A5 # 0 +0x8EA2A9C0 0x54CF # 0 +0x8EA2A9C1 0x54C3 # 0 +0x8EA2A9C2 0x830D # 0 +0x8EA2A9C3 0x54B7 # 0 +0x8EA2A9C4 0x54AE # 0 +0x8EA2A9C5 0x54D6 # 0 +0x8EA2A9C6 0x54B6 # 0 +0x8EA2A9C7 0x54C5 # 0 +0x8EA2A9C8 0x54C6 # 0 +0x8EA2A9C9 0x54A0 # 0 +0x8EA2A9CA 0x5470 # 0 +0x8EA2A9CB 0x54BC # 0 +0x8EA2A9CC 0x54A2 # 0 +0x8EA2A9CD 0x54BE # 0 +0x8EA2A9CE 0x5472 # 0 +0x8EA2A9CF 0x54DE # 0 +0x8EA2A9D0 0x54B0 # 0 +0x8EA2A9D1 0x57B5 # 0 +0x8EA2A9D2 0x579E # 0 +0x8EA2A9D3 0x579F # 0 +0x8EA2A9D4 0x57A4 # 0 +0x8EA2A9D5 0x578C # 0 +0x8EA2A9D6 0x5797 # 0 +0x8EA2A9D7 0x579D # 0 +0x8EA2A9D8 0x579B # 0 +0x8EA2A9D9 0x5794 # 0 +0x8EA2A9DA 0x5798 # 0 +0x8EA2A9DB 0x578F # 0 +0x8EA2A9DC 0x5799 # 0 +0x8EA2A9DD 0x57A5 # 0 +0x8EA2A9DE 0x579A # 0 +0x8EA2A9DF 0x5795 # 0 +0x8EA2A9E0 0x58F4 # 0 +0x8EA2A9E1 0x590D # 0 +0x8EA2A9E2 0x5953 # 0 +0x8EA2A9E3 0x59E1 # 0 +0x8EA2A9E4 0x59DE # 0 +0x8EA2A9E5 0x59EE # 0 +0x8EA2A9E6 0x5A00 # 0 +0x8EA2A9E7 0x59F1 # 0 +0x8EA2A9E8 0x59DD # 0 +0x8EA2A9E9 0x59FA # 0 +0x8EA2A9EA 0x59FD # 0 +0x8EA2A9EB 0x59FC # 0 +0x8EA2A9EC 0x59F6 # 0 +0x8EA2A9ED 0x59E4 # 0 +0x8EA2A9EE 0x59F2 # 0 +0x8EA2A9EF 0x59F7 # 0 +0x8EA2A9F0 0x59DB # 0 +0x8EA2A9F1 0x59E9 # 0 +0x8EA2A9F2 0x59F3 # 0 +0x8EA2A9F3 0x59F5 # 0 +0x8EA2A9F4 0x59E0 # 0 +0x8EA2A9F5 0x59FE # 0 +0x8EA2A9F6 0x59F4 # 0 +0x8EA2A9F7 0x59ED # 0 +0x8EA2A9F8 0x5BA8 # 0 +0x8EA2A9F9 0x5C4C # 0 +0x8EA2A9FA 0x5CD0 # 0 +0x8EA2A9FB 0x5CD8 # 0 +0x8EA2A9FC 0x5CCC # 0 +0x8EA2A9FD 0x5CD7 # 0 +0x8EA2A9FE 0x5CCB # 0 +0x8EA2AAA1 0x5CDB # 0 +0x8EA2AAA2 0x5CDE # 0 +0x8EA2AAA3 0x5CDA # 0 +0x8EA2AAA4 0x5CC9 # 0 +0x8EA2AAA5 0x5CC7 # 0 +0x8EA2AAA6 0x5CCA # 0 +0x8EA2AAA7 0x5CD6 # 0 +0x8EA2AAA8 0x5CD3 # 0 +0x8EA2AAA9 0x5CD4 # 0 +0x8EA2AAAA 0x5CCF # 0 +0x8EA2AAAB 0x5CC8 # 0 +0x8EA2AAAC 0x5CC6 # 0 +0x8EA2AAAD 0x5CCE # 0 +0x8EA2AAAE 0x5CDF # 0 +0x8EA2AAAF 0x5CF8 # 0 +0x8EA2AAB0 0x5DF9 # 0 +0x8EA2AAB1 0x5E21 # 0 +0x8EA2AAB2 0x5E22 # 0 +0x8EA2AAB3 0x5E23 # 0 +0x8EA2AAB4 0x5E20 # 0 +0x8EA2AAB5 0x5E24 # 0 +0x8EA2AAB6 0x5EB0 # 0 +0x8EA2AAB7 0x5EA4 # 0 +0x8EA2AAB8 0x5EA2 # 0 +0x8EA2AAB9 0x5E9B # 0 +0x8EA2AABA 0x5EA3 # 0 +0x8EA2AABB 0x5EA5 # 0 +0x8EA2AABC 0x5F07 # 0 +0x8EA2AABD 0x5F2E # 0 +0x8EA2AABE 0x5F56 # 0 +0x8EA2AABF 0x5F86 # 0 +0x8EA2AAC0 0x6037 # 0 +0x8EA2AAC1 0x6039 # 0 +0x8EA2AAC2 0x6054 # 0 +0x8EA2AAC3 0x6072 # 0 +0x8EA2AAC4 0x605E # 0 +0x8EA2AAC5 0x6045 # 0 +0x8EA2AAC6 0x6053 # 0 +0x8EA2AAC7 0x6047 # 0 +0x8EA2AAC8 0x6049 # 0 +0x8EA2AAC9 0x605B # 0 +0x8EA2AACA 0x604C # 0 +0x8EA2AACB 0x6040 # 0 +0x8EA2AACC 0x6042 # 0 +0x8EA2AACD 0x605F # 0 +0x8EA2AACE 0x6024 # 0 +0x8EA2AACF 0x6044 # 0 +0x8EA2AAD0 0x6058 # 0 +0x8EA2AAD1 0x6066 # 0 +0x8EA2AAD2 0x606E # 0 +0x8EA2AAD3 0x6242 # 0 +0x8EA2AAD4 0x6243 # 0 +0x8EA2AAD5 0x62CF # 0 +0x8EA2AAD6 0x630D # 0 +0x8EA2AAD7 0x630B # 0 +0x8EA2AAD8 0x62F5 # 0 +0x8EA2AAD9 0x630E # 0 +0x8EA2AADA 0x6303 # 0 +0x8EA2AADB 0x62EB # 0 +0x8EA2AADC 0x62F9 # 0 +0x8EA2AADD 0x630F # 0 +0x8EA2AADE 0x630C # 0 +0x8EA2AADF 0x62F8 # 0 +0x8EA2AAE0 0x62F6 # 0 +0x8EA2AAE1 0x6300 # 0 +0x8EA2AAE2 0x6313 # 0 +0x8EA2AAE3 0x6314 # 0 +0x8EA2AAE4 0x62FA # 0 +0x8EA2AAE5 0x6315 # 0 +0x8EA2AAE6 0x62FB # 0 +0x8EA2AAE7 0x62F0 # 0 +0x8EA2AAE8 0x6541 # 0 +0x8EA2AAE9 0x6543 # 0 +0x8EA2AAEA 0x65AA # 0 +0x8EA2AAEB 0x65BF # 0 +0x8EA2AAEC 0x6636 # 0 +0x8EA2AAED 0x6621 # 0 +0x8EA2AAEE 0x6632 # 0 +0x8EA2AAEF 0x6635 # 0 +0x8EA2AAF0 0x661C # 0 +0x8EA2AAF1 0x6626 # 0 +0x8EA2AAF2 0x6622 # 0 +0x8EA2AAF3 0x6633 # 0 +0x8EA2AAF4 0x662B # 0 +0x8EA2AAF5 0x663A # 0 +0x8EA2AAF6 0x661D # 0 +0x8EA2AAF7 0x6634 # 0 +0x8EA2AAF8 0x6639 # 0 +0x8EA2AAF9 0x662E # 0 +0x8EA2AAFA 0x670F # 0 +0x8EA2AAFB 0x6710 # 0 +0x8EA2AAFC 0x67C1 # 0 +0x8EA2AAFD 0x67F2 # 0 +0x8EA2AAFE 0x67C8 # 0 +0x8EA2ABA1 0x67BA # 0 +0x8EA2ABA2 0x67DC # 0 +0x8EA2ABA3 0x67BB # 0 +0x8EA2ABA4 0x67F8 # 0 +0x8EA2ABA5 0x67D8 # 0 +0x8EA2ABA6 0x67C0 # 0 +0x8EA2ABA7 0x67B7 # 0 +0x8EA2ABA8 0x67C5 # 0 +0x8EA2ABA9 0x67EB # 0 +0x8EA2ABAA 0x67E4 # 0 +0x8EA2ABAB 0x67DF # 0 +0x8EA2ABAC 0x67B5 # 0 +0x8EA2ABAD 0x67CD # 0 +0x8EA2ABAE 0x67B3 # 0 +0x8EA2ABAF 0x67F7 # 0 +0x8EA2ABB0 0x67F6 # 0 +0x8EA2ABB1 0x67EE # 0 +0x8EA2ABB2 0x67E3 # 0 +0x8EA2ABB3 0x67C2 # 0 +0x8EA2ABB4 0x67B9 # 0 +0x8EA2ABB5 0x67CE # 0 +0x8EA2ABB6 0x67E7 # 0 +0x8EA2ABB7 0x67F0 # 0 +0x8EA2ABB8 0x67B2 # 0 +0x8EA2ABB9 0x67FC # 0 +0x8EA2ABBA 0x67C6 # 0 +0x8EA2ABBB 0x67ED # 0 +0x8EA2ABBC 0x67CC # 0 +0x8EA2ABBD 0x67AE # 0 +0x8EA2ABBE 0x67E6 # 0 +0x8EA2ABBF 0x67DB # 0 +0x8EA2ABC0 0x67FA # 0 +0x8EA2ABC1 0x67C9 # 0 +0x8EA2ABC2 0x67CA # 0 +0x8EA2ABC3 0x67C3 # 0 +0x8EA2ABC4 0x67EA # 0 +0x8EA2ABC5 0x67CB # 0 +0x8EA2ABC6 0x6B28 # 0 +0x8EA2ABC7 0x6B82 # 0 +0x8EA2ABC8 0x6B84 # 0 +0x8EA2ABC9 0x6BB6 # 0 +0x8EA2ABCA 0x6BD6 # 0 +0x8EA2ABCB 0x6BD8 # 0 +0x8EA2ABCC 0x6BE0 # 0 +0x8EA2ABCD 0x6C20 # 0 +0x8EA2ABCE 0x6C21 # 0 +0x8EA2ABCF 0x6D28 # 0 +0x8EA2ABD0 0x6D34 # 0 +0x8EA2ABD1 0x6D2D # 0 +0x8EA2ABD2 0x6D1F # 0 +0x8EA2ABD3 0x6D3C # 0 +0x8EA2ABD4 0x6D3F # 0 +0x8EA2ABD5 0x6D12 # 0 +0x8EA2ABD6 0x6D0A # 0 +0x8EA2ABD7 0x6CDA # 0 +0x8EA2ABD8 0x6D33 # 0 +0x8EA2ABD9 0x6D04 # 0 +0x8EA2ABDA 0x6D19 # 0 +0x8EA2ABDB 0x6D3A # 0 +0x8EA2ABDC 0x6D1A # 0 +0x8EA2ABDD 0x6D11 # 0 +0x8EA2ABDE 0x6D00 # 0 +0x8EA2ABDF 0x6D1D # 0 +0x8EA2ABE0 0x6D42 # 0 +0x8EA2ABE1 0x6D01 # 0 +0x8EA2ABE2 0x6D18 # 0 +0x8EA2ABE3 0x6D37 # 0 +0x8EA2ABE4 0x6D03 # 0 +0x8EA2ABE5 0x6D0F # 0 +0x8EA2ABE6 0x6D40 # 0 +0x8EA2ABE7 0x6D07 # 0 +0x8EA2ABE8 0x6D20 # 0 +0x8EA2ABE9 0x6D2C # 0 +0x8EA2ABEA 0x6D08 # 0 +0x8EA2ABEB 0x6D22 # 0 +0x8EA2ABEC 0x6D09 # 0 +0x8EA2ABED 0x6D10 # 0 +0x8EA2ABEE 0x70B7 # 0 +0x8EA2ABEF 0x709F # 0 +0x8EA2ABF0 0x70BE # 0 +0x8EA2ABF1 0x70B1 # 0 +0x8EA2ABF2 0x70B0 # 0 +0x8EA2ABF3 0x70A1 # 0 +0x8EA2ABF4 0x70B4 # 0 +0x8EA2ABF5 0x70B5 # 0 +0x8EA2ABF6 0x70A9 # 0 +0x8EA2ABF7 0x7241 # 0 +0x8EA2ABF8 0x7249 # 0 +0x8EA2ABF9 0x724A # 0 +0x8EA2ABFA 0x726C # 0 +0x8EA2ABFB 0x7270 # 0 +0x8EA2ABFC 0x7273 # 0 +0x8EA2ABFD 0x726E # 0 +0x8EA2ABFE 0x72CA # 0 +0x8EA2ACA1 0x72E4 # 0 +0x8EA2ACA2 0x72E8 # 0 +0x8EA2ACA3 0x72EB # 0 +0x8EA2ACA4 0x72DF # 0 +0x8EA2ACA5 0x72EA # 0 +0x8EA2ACA6 0x72E6 # 0 +0x8EA2ACA7 0x72E3 # 0 +0x8EA2ACA8 0x7385 # 0 +0x8EA2ACA9 0x73CC # 0 +0x8EA2ACAA 0x73C2 # 0 +0x8EA2ACAB 0x73C8 # 0 +0x8EA2ACAC 0x73C5 # 0 +0x8EA2ACAD 0x73B9 # 0 +0x8EA2ACAE 0x73B6 # 0 +0x8EA2ACAF 0x73B5 # 0 +0x8EA2ACB0 0x73B4 # 0 +0x8EA2ACB1 0x73EB # 0 +0x8EA2ACB2 0x73BF # 0 +0x8EA2ACB3 0x73C7 # 0 +0x8EA2ACB4 0x73BE # 0 +0x8EA2ACB5 0x73C3 # 0 +0x8EA2ACB6 0x73C6 # 0 +0x8EA2ACB7 0x73B8 # 0 +0x8EA2ACB8 0x73CB # 0 +0x8EA2ACB9 0x74EC # 0 +0x8EA2ACBA 0x74EE # 0 +0x8EA2ACBB 0x752E # 0 +0x8EA2ACBC 0x7547 # 0 +0x8EA2ACBD 0x7548 # 0 +0x8EA2ACBE 0x75A7 # 0 +0x8EA2ACBF 0x75AA # 0 +0x8EA2ACC0 0x7679 # 0 +0x8EA2ACC1 0x76C4 # 0 +0x8EA2ACC2 0x7708 # 0 +0x8EA2ACC3 0x7703 # 0 +0x8EA2ACC4 0x7704 # 0 +0x8EA2ACC5 0x7705 # 0 +0x8EA2ACC6 0x770A # 0 +0x8EA2ACC7 0x76F7 # 0 +0x8EA2ACC8 0x76FB # 0 +0x8EA2ACC9 0x76FA # 0 +0x8EA2ACCA 0x77E7 # 0 +0x8EA2ACCB 0x77E8 # 0 +0x8EA2ACCC 0x7806 # 0 +0x8EA2ACCD 0x7811 # 0 +0x8EA2ACCE 0x7812 # 0 +0x8EA2ACCF 0x7805 # 0 +0x8EA2ACD0 0x7810 # 0 +0x8EA2ACD1 0x780F # 0 +0x8EA2ACD2 0x780E # 0 +0x8EA2ACD3 0x7809 # 0 +0x8EA2ACD4 0x7803 # 0 +0x8EA2ACD5 0x7813 # 0 +0x8EA2ACD6 0x794A # 0 +0x8EA2ACD7 0x794C # 0 +0x8EA2ACD8 0x794B # 0 +0x8EA2ACD9 0x7945 # 0 +0x8EA2ACDA 0x7944 # 0 +0x8EA2ACDB 0x79D5 # 0 +0x8EA2ACDC 0x79CD # 0 +0x8EA2ACDD 0x79CF # 0 +0x8EA2ACDE 0x79D6 # 0 +0x8EA2ACDF 0x79CE # 0 +0x8EA2ACE0 0x7A80 # 0 +0x8EA2ACE1 0x7A7E # 0 +0x8EA2ACE2 0x7AD1 # 0 +0x8EA2ACE3 0x7B00 # 0 +0x8EA2ACE4 0x7B01 # 0 +0x8EA2ACE5 0x7C7A # 0 +0x8EA2ACE6 0x7C78 # 0 +0x8EA2ACE7 0x7C79 # 0 +0x8EA2ACE8 0x7C7F # 0 +0x8EA2ACE9 0x7C80 # 0 +0x8EA2ACEA 0x7C81 # 0 +0x8EA2ACEB 0x7D03 # 0 +0x8EA2ACEC 0x7D08 # 0 +0x8EA2ACED 0x7D01 # 0 +0x8EA2ACEE 0x7F58 # 0 +0x8EA2ACEF 0x7F91 # 0 +0x8EA2ACF0 0x7F8D # 0 +0x8EA2ACF1 0x7FBE # 0 +0x8EA2ACF2 0x8007 # 0 +0x8EA2ACF3 0x800E # 0 +0x8EA2ACF4 0x800F # 0 +0x8EA2ACF5 0x8014 # 0 +0x8EA2ACF6 0x8037 # 0 +0x8EA2ACF7 0x80D8 # 0 +0x8EA2ACF8 0x80C7 # 0 +0x8EA2ACF9 0x80E0 # 0 +0x8EA2ACFA 0x80D1 # 0 +0x8EA2ACFB 0x80C8 # 0 +0x8EA2ACFC 0x80C2 # 0 +0x8EA2ACFD 0x80D0 # 0 +0x8EA2ACFE 0x80C5 # 0 +0x8EA2ADA1 0x80E3 # 0 +0x8EA2ADA2 0x80D9 # 0 +0x8EA2ADA3 0x80DC # 0 +0x8EA2ADA4 0x80CA # 0 +0x8EA2ADA5 0x80D5 # 0 +0x8EA2ADA6 0x80C9 # 0 +0x8EA2ADA7 0x80CF # 0 +0x8EA2ADA8 0x80D7 # 0 +0x8EA2ADA9 0x80E6 # 0 +0x8EA2ADAA 0x80CD # 0 +0x8EA2ADAB 0x81FF # 0 +0x8EA2ADAC 0x8221 # 0 +0x8EA2ADAD 0x8294 # 0 +0x8EA2ADAE 0x82D9 # 0 +0x8EA2ADAF 0x82FE # 0 +0x8EA2ADB0 0x82F9 # 0 +0x8EA2ADB1 0x8307 # 0 +0x8EA2ADB2 0x82E8 # 0 +0x8EA2ADB3 0x8300 # 0 +0x8EA2ADB4 0x82D5 # 0 +0x8EA2ADB5 0x833A # 0 +0x8EA2ADB6 0x82EB # 0 +0x8EA2ADB7 0x82D6 # 0 +0x8EA2ADB8 0x82F4 # 0 +0x8EA2ADB9 0x82EC # 0 +0x8EA2ADBA 0x82E1 # 0 +0x8EA2ADBB 0x82F2 # 0 +0x8EA2ADBC 0x82F5 # 0 +0x8EA2ADBD 0x830C # 0 +0x8EA2ADBE 0x82FB # 0 +0x8EA2ADBF 0x82F6 # 0 +0x8EA2ADC0 0x82F0 # 0 +0x8EA2ADC1 0x82EA # 0 +0x8EA2ADC2 0x82E4 # 0 +0x8EA2ADC3 0x82E0 # 0 +0x8EA2ADC4 0x82FA # 0 +0x8EA2ADC5 0x82F3 # 0 +0x8EA2ADC6 0x82ED # 0 +0x8EA2ADC7 0x8677 # 0 +0x8EA2ADC8 0x8674 # 0 +0x8EA2ADC9 0x867C # 0 +0x8EA2ADCA 0x8673 # 0 +0x8EA2ADCB 0x8841 # 0 +0x8EA2ADCC 0x884E # 0 +0x8EA2ADCD 0x8867 # 0 +0x8EA2ADCE 0x886A # 0 +0x8EA2ADCF 0x8869 # 0 +0x8EA2ADD0 0x89D3 # 0 +0x8EA2ADD1 0x8A04 # 0 +0x8EA2ADD2 0x8A07 # 0 +0x8EA2ADD3 0x8D72 # 0 +0x8EA2ADD4 0x8FE3 # 0 +0x8EA2ADD5 0x8FE1 # 0 +0x8EA2ADD6 0x8FEE # 0 +0x8EA2ADD7 0x8FE0 # 0 +0x8EA2ADD8 0x90F1 # 0 +0x8EA2ADD9 0x90BD # 0 +0x8EA2ADDA 0x90BF # 0 +0x8EA2ADDB 0x90D5 # 0 +0x8EA2ADDC 0x90C5 # 0 +0x8EA2ADDD 0x90BE # 0 +0x8EA2ADDE 0x90C7 # 0 +0x8EA2ADDF 0x90CB # 0 +0x8EA2ADE0 0x90C8 # 0 +0x8EA2ADE1 0x91D4 # 0 +0x8EA2ADE2 0x91D3 # 0 +0x8EA2ADE3 0x9654 # 0 +0x8EA2ADE4 0x964F # 0 +0x8EA2ADE5 0x9651 # 0 +0x8EA2ADE6 0x9653 # 0 +0x8EA2ADE7 0x964A # 0 +0x8EA2ADE8 0x964E # 0 +0x8EA2ADE9 0x501E # 0 +0x8EA2ADEA 0x5005 # 0 +0x8EA2ADEB 0x5007 # 0 +0x8EA2ADEC 0x5013 # 0 +0x8EA2ADED 0x5022 # 0 +0x8EA2ADEE 0x5030 # 0 +0x8EA2ADEF 0x501B # 0 +0x8EA2ADF0 0x4FF5 # 0 +0x8EA2ADF1 0x4FF4 # 0 +0x8EA2ADF2 0x5033 # 0 +0x8EA2ADF3 0x5037 # 0 +0x8EA2ADF4 0x502C # 0 +0x8EA2ADF5 0x4FF6 # 0 +0x8EA2ADF6 0x4FF7 # 0 +0x8EA2ADF7 0x5017 # 0 +0x8EA2ADF8 0x501C # 0 +0x8EA2ADF9 0x5020 # 0 +0x8EA2ADFA 0x5027 # 0 +0x8EA2ADFB 0x5035 # 0 +0x8EA2ADFC 0x502F # 0 +0x8EA2ADFD 0x5031 # 0 +0x8EA2ADFE 0x500E # 0 +0x8EA2AEA1 0x515A # 0 +0x8EA2AEA2 0x5194 # 0 +0x8EA2AEA3 0x5193 # 0 +0x8EA2AEA4 0x51CA # 0 +0x8EA2AEA5 0x51C4 # 0 +0x8EA2AEA6 0x51C5 # 0 +0x8EA2AEA7 0x51C8 # 0 +0x8EA2AEA8 0x51CE # 0 +0x8EA2AEA9 0x5261 # 0 +0x8EA2AEAA 0x525A # 0 +0x8EA2AEAB 0x5252 # 0 +0x8EA2AEAC 0x525E # 0 +0x8EA2AEAD 0x525F # 0 +0x8EA2AEAE 0x5255 # 0 +0x8EA2AEAF 0x5262 # 0 +0x8EA2AEB0 0x52CD # 0 +0x8EA2AEB1 0x530E # 0 +0x8EA2AEB2 0x539E # 0 +0x8EA2AEB3 0x5526 # 0 +0x8EA2AEB4 0x54E2 # 0 +0x8EA2AEB5 0x5517 # 0 +0x8EA2AEB6 0x5512 # 0 +0x8EA2AEB7 0x54E7 # 0 +0x8EA2AEB8 0x54F3 # 0 +0x8EA2AEB9 0x54E4 # 0 +0x8EA2AEBA 0x551A # 0 +0x8EA2AEBB 0x54FF # 0 +0x8EA2AEBC 0x5504 # 0 +0x8EA2AEBD 0x5508 # 0 +0x8EA2AEBE 0x54EB # 0 +0x8EA2AEBF 0x5511 # 0 +0x8EA2AEC0 0x5505 # 0 +0x8EA2AEC1 0x54F1 # 0 +0x8EA2AEC2 0x550A # 0 +0x8EA2AEC3 0x54FB # 0 +0x8EA2AEC4 0x54F7 # 0 +0x8EA2AEC5 0x54F8 # 0 +0x8EA2AEC6 0x54E0 # 0 +0x8EA2AEC7 0x550E # 0 +0x8EA2AEC8 0x5503 # 0 +0x8EA2AEC9 0x550B # 0 +0x8EA2AECA 0x5701 # 0 +0x8EA2AECB 0x5702 # 0 +0x8EA2AECC 0x57CC # 0 +0x8EA2AECD 0x5832 # 0 +0x8EA2AECE 0x57D5 # 0 +0x8EA2AECF 0x57D2 # 0 +0x8EA2AED0 0x57BA # 0 +0x8EA2AED1 0x57C6 # 0 +0x8EA2AED2 0x57BD # 0 +0x8EA2AED3 0x57BC # 0 +0x8EA2AED4 0x57B8 # 0 +0x8EA2AED5 0x57B6 # 0 +0x8EA2AED6 0x57BF # 0 +0x8EA2AED7 0x57C7 # 0 +0x8EA2AED8 0x57D0 # 0 +0x8EA2AED9 0x57B9 # 0 +0x8EA2AEDA 0x57C1 # 0 +0x8EA2AEDB 0x590E # 0 +0x8EA2AEDC 0x594A # 0 +0x8EA2AEDD 0x5A19 # 0 +0x8EA2AEDE 0x5A16 # 0 +0x8EA2AEDF 0x5A2D # 0 +0x8EA2AEE0 0x5A2E # 0 +0x8EA2AEE1 0x5A15 # 0 +0x8EA2AEE2 0x5A0F # 0 +0x8EA2AEE3 0x5A17 # 0 +0x8EA2AEE4 0x5A0A # 0 +0x8EA2AEE5 0x5A1E # 0 +0x8EA2AEE6 0x5A33 # 0 +0x8EA2AEE7 0x5B6C # 0 +0x8EA2AEE8 0x5BA7 # 0 +0x8EA2AEE9 0x5BAD # 0 +0x8EA2AEEA 0x5BAC # 0 +0x8EA2AEEB 0x5C03 # 0 +0x8EA2AEEC 0x5C56 # 0 +0x8EA2AEED 0x5C54 # 0 +0x8EA2AEEE 0x5CEC # 0 +0x8EA2AEEF 0x5CFF # 0 +0x8EA2AEF0 0x5CEE # 0 +0x8EA2AEF1 0x5CF1 # 0 +0x8EA2AEF2 0x5CF7 # 0 +0x8EA2AEF3 0x5D00 # 0 +0x8EA2AEF4 0x5CF9 # 0 +0x8EA2AEF5 0x5E29 # 0 +0x8EA2AEF6 0x5E28 # 0 +0x8EA2AEF7 0x5EA8 # 0 +0x8EA2AEF8 0x5EAE # 0 +0x8EA2AEF9 0x5EAA # 0 +0x8EA2AEFA 0x5EAC # 0 +0x8EA2AEFB 0x5F33 # 0 +0x8EA2AEFC 0x5F30 # 0 +0x8EA2AEFD 0x5F67 # 0 +0x8EA2AEFE 0x605D # 0 +0x8EA2AFA1 0x605A # 0 +0x8EA2AFA2 0x6067 # 0 +0x8EA2AFA3 0x6041 # 0 +0x8EA2AFA4 0x60A2 # 0 +0x8EA2AFA5 0x6088 # 0 +0x8EA2AFA6 0x6080 # 0 +0x8EA2AFA7 0x6092 # 0 +0x8EA2AFA8 0x6081 # 0 +0x8EA2AFA9 0x609D # 0 +0x8EA2AFAA 0x6083 # 0 +0x8EA2AFAB 0x6095 # 0 +0x8EA2AFAC 0x609B # 0 +0x8EA2AFAD 0x6097 # 0 +0x8EA2AFAE 0x6087 # 0 +0x8EA2AFAF 0x609C # 0 +0x8EA2AFB0 0x608E # 0 +0x8EA2AFB1 0x6219 # 0 +0x8EA2AFB2 0x6246 # 0 +0x8EA2AFB3 0x62F2 # 0 +0x8EA2AFB4 0x6310 # 0 +0x8EA2AFB5 0x6356 # 0 +0x8EA2AFB6 0x632C # 0 +0x8EA2AFB7 0x6344 # 0 +0x8EA2AFB8 0x6345 # 0 +0x8EA2AFB9 0x6336 # 0 +0x8EA2AFBA 0x6343 # 0 +0x8EA2AFBB 0x63E4 # 0 +0x8EA2AFBC 0x6339 # 0 +0x8EA2AFBD 0x634B # 0 +0x8EA2AFBE 0x634A # 0 +0x8EA2AFBF 0x633C # 0 +0x8EA2AFC0 0x6329 # 0 +0x8EA2AFC1 0x6341 # 0 +0x8EA2AFC2 0x6334 # 0 +0x8EA2AFC3 0x6358 # 0 +0x8EA2AFC4 0x6354 # 0 +0x8EA2AFC5 0x6359 # 0 +0x8EA2AFC6 0x632D # 0 +0x8EA2AFC7 0x6347 # 0 +0x8EA2AFC8 0x6333 # 0 +0x8EA2AFC9 0x635A # 0 +0x8EA2AFCA 0x6351 # 0 +0x8EA2AFCB 0x6338 # 0 +0x8EA2AFCC 0x6357 # 0 +0x8EA2AFCD 0x6340 # 0 +0x8EA2AFCE 0x6348 # 0 +0x8EA2AFCF 0x654A # 0 +0x8EA2AFD0 0x6546 # 0 +0x8EA2AFD1 0x65C6 # 0 +0x8EA2AFD2 0x65C3 # 0 +0x8EA2AFD3 0x65C4 # 0 +0x8EA2AFD4 0x65C2 # 0 +0x8EA2AFD5 0x664A # 0 +0x8EA2AFD6 0x665F # 0 +0x8EA2AFD7 0x6647 # 0 +0x8EA2AFD8 0x6651 # 0 +0x8EA2AFD9 0x6712 # 0 +0x8EA2AFDA 0x6713 # 0 +0x8EA2AFDB 0x681F # 0 +0x8EA2AFDC 0x681A # 0 +0x8EA2AFDD 0x6849 # 0 +0x8EA2AFDE 0x6832 # 0 +0x8EA2AFDF 0x6833 # 0 +0x8EA2AFE0 0x683B # 0 +0x8EA2AFE1 0x684B # 0 +0x8EA2AFE2 0x684F # 0 +0x8EA2AFE3 0x6816 # 0 +0x8EA2AFE4 0x6831 # 0 +0x8EA2AFE5 0x681C # 0 +0x8EA2AFE6 0x6835 # 0 +0x8EA2AFE7 0x682B # 0 +0x8EA2AFE8 0x682D # 0 +0x8EA2AFE9 0x682F # 0 +0x8EA2AFEA 0x684E # 0 +0x8EA2AFEB 0x6844 # 0 +0x8EA2AFEC 0x6834 # 0 +0x8EA2AFED 0x681D # 0 +0x8EA2AFEE 0x6812 # 0 +0x8EA2AFEF 0x6814 # 0 +0x8EA2AFF0 0x6826 # 0 +0x8EA2AFF1 0x6828 # 0 +0x8EA2AFF2 0x682E # 0 +0x8EA2AFF3 0x684D # 0 +0x8EA2AFF4 0x683A # 0 +0x8EA2AFF5 0x6825 # 0 +0x8EA2AFF6 0x6820 # 0 +0x8EA2AFF7 0x6B2C # 0 +0x8EA2AFF8 0x6B2F # 0 +0x8EA2AFF9 0x6B2D # 0 +0x8EA2AFFA 0x6B31 # 0 +0x8EA2AFFB 0x6B34 # 0 +0x8EA2AFFC 0x6B6D # 0 +0x8EA2AFFD 0x8082 # 0 +0x8EA2AFFE 0x6B88 # 0 +0x8EA2B0A1 0x6BE6 # 0 +0x8EA2B0A2 0x6BE4 # 0 +0x8EA2B0A3 0x6BE8 # 0 +0x8EA2B0A4 0x6BE3 # 0 +0x8EA2B0A5 0x6BE2 # 0 +0x8EA2B0A6 0x6BE7 # 0 +0x8EA2B0A7 0x6C25 # 0 +0x8EA2B0A8 0x6D7A # 0 +0x8EA2B0A9 0x6D63 # 0 +0x8EA2B0AA 0x6D64 # 0 +0x8EA2B0AB 0x6D76 # 0 +0x8EA2B0AC 0x6D0D # 0 +0x8EA2B0AD 0x6D61 # 0 +0x8EA2B0AE 0x6D92 # 0 +0x8EA2B0AF 0x6D58 # 0 +0x8EA2B0B0 0x6D62 # 0 +0x8EA2B0B1 0x6D6D # 0 +0x8EA2B0B2 0x6D6F # 0 +0x8EA2B0B3 0x6D91 # 0 +0x8EA2B0B4 0x6D8D # 0 +0x8EA2B0B5 0x6DEF # 0 +0x8EA2B0B6 0x6D7F # 0 +0x8EA2B0B7 0x6D86 # 0 +0x8EA2B0B8 0x6D5E # 0 +0x8EA2B0B9 0x6D67 # 0 +0x8EA2B0BA 0x6D60 # 0 +0x8EA2B0BB 0x6D97 # 0 +0x8EA2B0BC 0x6D70 # 0 +0x8EA2B0BD 0x6D7C # 0 +0x8EA2B0BE 0x6D5F # 0 +0x8EA2B0BF 0x6D82 # 0 +0x8EA2B0C0 0x6D98 # 0 +0x8EA2B0C1 0x6D2F # 0 +0x8EA2B0C2 0x6D68 # 0 +0x8EA2B0C3 0x6D8B # 0 +0x8EA2B0C4 0x6D7E # 0 +0x8EA2B0C5 0x6D80 # 0 +0x8EA2B0C6 0x6D84 # 0 +0x8EA2B0C7 0x6D16 # 0 +0x8EA2B0C8 0x6D83 # 0 +0x8EA2B0C9 0x6D7B # 0 +0x8EA2B0CA 0x6D7D # 0 +0x8EA2B0CB 0x6D75 # 0 +0x8EA2B0CC 0x6D90 # 0 +0x8EA2B0CD 0x70DC # 0 +0x8EA2B0CE 0x70D3 # 0 +0x8EA2B0CF 0x70D1 # 0 +0x8EA2B0D0 0x70DD # 0 +0x8EA2B0D1 0x70CB # 0 +0x8EA2B0D2 0x7F39 # 0 +0x8EA2B0D3 0x70E2 # 0 +0x8EA2B0D4 0x70D7 # 0 +0x8EA2B0D5 0x70D2 # 0 +0x8EA2B0D6 0x70DE # 0 +0x8EA2B0D7 0x70E0 # 0 +0x8EA2B0D8 0x70D4 # 0 +0x8EA2B0D9 0x70CD # 0 +0x8EA2B0DA 0x70C5 # 0 +0x8EA2B0DB 0x70C6 # 0 +0x8EA2B0DC 0x70C7 # 0 +0x8EA2B0DD 0x70DA # 0 +0x8EA2B0DE 0x70CE # 0 +0x8EA2B0DF 0x70E1 # 0 +0x8EA2B0E0 0x7242 # 0 +0x8EA2B0E1 0x7278 # 0 +0x8EA2B0E2 0x7277 # 0 +0x8EA2B0E3 0x7276 # 0 +0x8EA2B0E4 0x7300 # 0 +0x8EA2B0E5 0x72FA # 0 +0x8EA2B0E6 0x72F4 # 0 +0x8EA2B0E7 0x72FE # 0 +0x8EA2B0E8 0x72F6 # 0 +0x8EA2B0E9 0x72F3 # 0 +0x8EA2B0EA 0x72FB # 0 +0x8EA2B0EB 0x7301 # 0 +0x8EA2B0EC 0x73D3 # 0 +0x8EA2B0ED 0x73D9 # 0 +0x8EA2B0EE 0x73E5 # 0 +0x8EA2B0EF 0x73D6 # 0 +0x8EA2B0F0 0x73BC # 0 +0x8EA2B0F1 0x73E7 # 0 +0x8EA2B0F2 0x73E3 # 0 +0x8EA2B0F3 0x73E9 # 0 +0x8EA2B0F4 0x73DC # 0 +0x8EA2B0F5 0x73D2 # 0 +0x8EA2B0F6 0x73DB # 0 +0x8EA2B0F7 0x73D4 # 0 +0x8EA2B0F8 0x73DD # 0 +0x8EA2B0F9 0x73DA # 0 +0x8EA2B0FA 0x73D7 # 0 +0x8EA2B0FB 0x73D8 # 0 +0x8EA2B0FC 0x73E8 # 0 +0x8EA2B0FD 0x74DE # 0 +0x8EA2B0FE 0x74DF # 0 +0x8EA2B1A1 0x74F4 # 0 +0x8EA2B1A2 0x74F5 # 0 +0x8EA2B1A3 0x7521 # 0 +0x8EA2B1A4 0x755B # 0 +0x8EA2B1A5 0x755F # 0 +0x8EA2B1A6 0x75B0 # 0 +0x8EA2B1A7 0x75C1 # 0 +0x8EA2B1A8 0x75BB # 0 +0x8EA2B1A9 0x75C4 # 0 +0x8EA2B1AA 0x75C0 # 0 +0x8EA2B1AB 0x75BF # 0 +0x8EA2B1AC 0x75B6 # 0 +0x8EA2B1AD 0x75BA # 0 +0x8EA2B1AE 0x768A # 0 +0x8EA2B1AF 0x76C9 # 0 +0x8EA2B1B0 0x771D # 0 +0x8EA2B1B1 0x771B # 0 +0x8EA2B1B2 0x7710 # 0 +0x8EA2B1B3 0x7713 # 0 +0x8EA2B1B4 0x7712 # 0 +0x8EA2B1B5 0x7723 # 0 +0x8EA2B1B6 0x7711 # 0 +0x8EA2B1B7 0x7715 # 0 +0x8EA2B1B8 0x7719 # 0 +0x8EA2B1B9 0x771A # 0 +0x8EA2B1BA 0x7722 # 0 +0x8EA2B1BB 0x7727 # 0 +0x8EA2B1BC 0x7823 # 0 +0x8EA2B1BD 0x782C # 0 +0x8EA2B1BE 0x7822 # 0 +0x8EA2B1BF 0x7835 # 0 +0x8EA2B1C0 0x782F # 0 +0x8EA2B1C1 0x7828 # 0 +0x8EA2B1C2 0x782E # 0 +0x8EA2B1C3 0x782B # 0 +0x8EA2B1C4 0x7821 # 0 +0x8EA2B1C5 0x7829 # 0 +0x8EA2B1C6 0x7833 # 0 +0x8EA2B1C7 0x782A # 0 +0x8EA2B1C8 0x7831 # 0 +0x8EA2B1C9 0x7954 # 0 +0x8EA2B1CA 0x795B # 0 +0x8EA2B1CB 0x794F # 0 +0x8EA2B1CC 0x795C # 0 +0x8EA2B1CD 0x7953 # 0 +0x8EA2B1CE 0x7952 # 0 +0x8EA2B1CF 0x7951 # 0 +0x8EA2B1D0 0x79EB # 0 +0x8EA2B1D1 0x79EC # 0 +0x8EA2B1D2 0x79E0 # 0 +0x8EA2B1D3 0x79EE # 0 +0x8EA2B1D4 0x79ED # 0 +0x8EA2B1D5 0x79EA # 0 +0x8EA2B1D6 0x79DC # 0 +0x8EA2B1D7 0x79DE # 0 +0x8EA2B1D8 0x79DD # 0 +0x8EA2B1D9 0x7A86 # 0 +0x8EA2B1DA 0x7A89 # 0 +0x8EA2B1DB 0x7A85 # 0 +0x8EA2B1DC 0x7A8B # 0 +0x8EA2B1DD 0x7A8C # 0 +0x8EA2B1DE 0x7A8A # 0 +0x8EA2B1DF 0x7A87 # 0 +0x8EA2B1E0 0x7AD8 # 0 +0x8EA2B1E1 0x7B10 # 0 +0x8EA2B1E2 0x7B04 # 0 +0x8EA2B1E3 0x7B13 # 0 +0x8EA2B1E4 0x7B05 # 0 +0x8EA2B1E5 0x7B0F # 0 +0x8EA2B1E6 0x7B08 # 0 +0x8EA2B1E7 0x7B0A # 0 +0x8EA2B1E8 0x7B0E # 0 +0x8EA2B1E9 0x7B09 # 0 +0x8EA2B1EA 0x7B12 # 0 +0x8EA2B1EB 0x7C84 # 0 +0x8EA2B1EC 0x7C91 # 0 +0x8EA2B1ED 0x7C8A # 0 +0x8EA2B1EE 0x7C8C # 0 +0x8EA2B1EF 0x7C88 # 0 +0x8EA2B1F0 0x7C8D # 0 +0x8EA2B1F1 0x7C85 # 0 +0x8EA2B1F2 0x7D1E # 0 +0x8EA2B1F3 0x7D1D # 0 +0x8EA2B1F4 0x7D11 # 0 +0x8EA2B1F5 0x7D0E # 0 +0x8EA2B1F6 0x7D18 # 0 +0x8EA2B1F7 0x7D16 # 0 +0x8EA2B1F8 0x7D13 # 0 +0x8EA2B1F9 0x7D1F # 0 +0x8EA2B1FA 0x7D12 # 0 +0x8EA2B1FB 0x7D0F # 0 +0x8EA2B1FC 0x7D0C # 0 +0x8EA2B1FD 0x7F5C # 0 +0x8EA2B1FE 0x7F61 # 0 +0x8EA2B2A1 0x7F5E # 0 +0x8EA2B2A2 0x7F60 # 0 +0x8EA2B2A3 0x7F5D # 0 +0x8EA2B2A4 0x7F5B # 0 +0x8EA2B2A5 0x7F96 # 0 +0x8EA2B2A6 0x7F92 # 0 +0x8EA2B2A7 0x7FC3 # 0 +0x8EA2B2A8 0x7FC2 # 0 +0x8EA2B2A9 0x7FC0 # 0 +0x8EA2B2AA 0x8016 # 0 +0x8EA2B2AB 0x803E # 0 +0x8EA2B2AC 0x8039 # 0 +0x8EA2B2AD 0x80FA # 0 +0x8EA2B2AE 0x80F2 # 0 +0x8EA2B2AF 0x80F9 # 0 +0x8EA2B2B0 0x80F5 # 0 +0x8EA2B2B1 0x8101 # 0 +0x8EA2B2B2 0x80FB # 0 +0x8EA2B2B3 0x8100 # 0 +0x8EA2B2B4 0x8201 # 0 +0x8EA2B2B5 0x822F # 0 +0x8EA2B2B6 0x8225 # 0 +0x8EA2B2B7 0x8333 # 0 +0x8EA2B2B8 0x832D # 0 +0x8EA2B2B9 0x8344 # 0 +0x8EA2B2BA 0x8319 # 0 +0x8EA2B2BB 0x8351 # 0 +0x8EA2B2BC 0x8325 # 0 +0x8EA2B2BD 0x8356 # 0 +0x8EA2B2BE 0x833F # 0 +0x8EA2B2BF 0x8341 # 0 +0x8EA2B2C0 0x8326 # 0 +0x8EA2B2C1 0x831C # 0 +0x8EA2B2C2 0x8322 # 0 +0x8EA2B2C3 0x8342 # 0 +0x8EA2B2C4 0x834E # 0 +0x8EA2B2C5 0x831B # 0 +0x8EA2B2C6 0x832A # 0 +0x8EA2B2C7 0x8308 # 0 +0x8EA2B2C8 0x833C # 0 +0x8EA2B2C9 0x834D # 0 +0x8EA2B2CA 0x8316 # 0 +0x8EA2B2CB 0x8324 # 0 +0x8EA2B2CC 0x8320 # 0 +0x8EA2B2CD 0x8337 # 0 +0x8EA2B2CE 0x832F # 0 +0x8EA2B2CF 0x8329 # 0 +0x8EA2B2D0 0x8347 # 0 +0x8EA2B2D1 0x8345 # 0 +0x8EA2B2D2 0x834C # 0 +0x8EA2B2D3 0x8353 # 0 +0x8EA2B2D4 0x831E # 0 +0x8EA2B2D5 0x832C # 0 +0x8EA2B2D6 0x834B # 0 +0x8EA2B2D7 0x8327 # 0 +0x8EA2B2D8 0x8348 # 0 +0x8EA2B2D9 0x8653 # 0 +0x8EA2B2DA 0x8652 # 0 +0x8EA2B2DB 0x86A2 # 0 +0x8EA2B2DC 0x86A8 # 0 +0x8EA2B2DD 0x8696 # 0 +0x8EA2B2DE 0x868D # 0 +0x8EA2B2DF 0x8691 # 0 +0x8EA2B2E0 0x869E # 0 +0x8EA2B2E1 0x8687 # 0 +0x8EA2B2E2 0x8697 # 0 +0x8EA2B2E3 0x8686 # 0 +0x8EA2B2E4 0x868B # 0 +0x8EA2B2E5 0x869A # 0 +0x8EA2B2E6 0x8685 # 0 +0x8EA2B2E7 0x86A5 # 0 +0x8EA2B2E8 0x8699 # 0 +0x8EA2B2E9 0x86A1 # 0 +0x8EA2B2EA 0x86A7 # 0 +0x8EA2B2EB 0x8695 # 0 +0x8EA2B2EC 0x8698 # 0 +0x8EA2B2ED 0x868E # 0 +0x8EA2B2EE 0x869D # 0 +0x8EA2B2EF 0x8690 # 0 +0x8EA2B2F0 0x8694 # 0 +0x8EA2B2F1 0x8843 # 0 +0x8EA2B2F2 0x8844 # 0 +0x8EA2B2F3 0x886D # 0 +0x8EA2B2F4 0x8875 # 0 +0x8EA2B2F5 0x8876 # 0 +0x8EA2B2F6 0x8872 # 0 +0x8EA2B2F7 0x8880 # 0 +0x8EA2B2F8 0x8871 # 0 +0x8EA2B2F9 0x887F # 0 +0x8EA2B2FA 0x886F # 0 +0x8EA2B2FB 0x8883 # 0 +0x8EA2B2FC 0x887E # 0 +0x8EA2B2FD 0x8874 # 0 +0x8EA2B2FE 0x887C # 0 +0x8EA2B3A1 0x8A12 # 0 +0x8EA2B3A2 0x8C47 # 0 +0x8EA2B3A3 0x8C57 # 0 +0x8EA2B3A4 0x8C7B # 0 +0x8EA2B3A5 0x8CA4 # 0 +0x8EA2B3A6 0x8CA3 # 0 +0x8EA2B3A7 0x8D76 # 0 +0x8EA2B3A8 0x8D78 # 0 +0x8EA2B3A9 0x8DB5 # 0 +0x8EA2B3AA 0x8DB7 # 0 +0x8EA2B3AB 0x8DB6 # 0 +0x8EA2B3AC 0x8ED1 # 0 +0x8EA2B3AD 0x8ED3 # 0 +0x8EA2B3AE 0x8FFE # 0 +0x8EA2B3AF 0x8FF5 # 0 +0x8EA2B3B0 0x9002 # 0 +0x8EA2B3B1 0x8FFF # 0 +0x8EA2B3B2 0x8FFB # 0 +0x8EA2B3B3 0x9004 # 0 +0x8EA2B3B4 0x8FFC # 0 +0x8EA2B3B5 0x8FF6 # 0 +0x8EA2B3B6 0x90D6 # 0 +0x8EA2B3B7 0x90E0 # 0 +0x8EA2B3B8 0x90D9 # 0 +0x8EA2B3B9 0x90DA # 0 +0x8EA2B3BA 0x90E3 # 0 +0x8EA2B3BB 0x90DF # 0 +0x8EA2B3BC 0x90E5 # 0 +0x8EA2B3BD 0x90D8 # 0 +0x8EA2B3BE 0x90DB # 0 +0x8EA2B3BF 0x90D7 # 0 +0x8EA2B3C0 0x90DC # 0 +0x8EA2B3C1 0x90E4 # 0 +0x8EA2B3C2 0x9150 # 0 +0x8EA2B3C3 0x914E # 0 +0x8EA2B3C4 0x914F # 0 +0x8EA2B3C5 0x91D5 # 0 +0x8EA2B3C6 0x91E2 # 0 +0x8EA2B3C7 0x91DA # 0 +0x8EA2B3C8 0x965C # 0 +0x8EA2B3C9 0x965F # 0 +0x8EA2B3CA 0x96BC # 0 +0x8EA2B3CB 0x98E3 # 0 +0x8EA2B3CC 0x9ADF # 0 +0x8EA2B3CD 0x9B2F # 0 +0x8EA2B3CE 0x4E7F # 0 +0x8EA2B3CF 0x5070 # 0 +0x8EA2B3D0 0x506A # 0 +0x8EA2B3D1 0x5061 # 0 +0x8EA2B3D2 0x505E # 0 +0x8EA2B3D3 0x5060 # 0 +0x8EA2B3D4 0x5053 # 0 +0x8EA2B3D5 0x504B # 0 +0x8EA2B3D6 0x505D # 0 +0x8EA2B3D7 0x5072 # 0 +0x8EA2B3D8 0x5048 # 0 +0x8EA2B3D9 0x504D # 0 +0x8EA2B3DA 0x5041 # 0 +0x8EA2B3DB 0x505B # 0 +0x8EA2B3DC 0x504A # 0 +0x8EA2B3DD 0x5062 # 0 +0x8EA2B3DE 0x5015 # 0 +0x8EA2B3DF 0x5045 # 0 +0x8EA2B3E0 0x505F # 0 +0x8EA2B3E1 0x5069 # 0 +0x8EA2B3E2 0x506B # 0 +0x8EA2B3E3 0x5063 # 0 +0x8EA2B3E4 0x5064 # 0 +0x8EA2B3E5 0x5046 # 0 +0x8EA2B3E6 0x5040 # 0 +0x8EA2B3E7 0x506E # 0 +0x8EA2B3E8 0x5073 # 0 +0x8EA2B3E9 0x5057 # 0 +0x8EA2B3EA 0x5051 # 0 +0x8EA2B3EB 0x51D0 # 0 +0x8EA2B3EC 0x526B # 0 +0x8EA2B3ED 0x526D # 0 +0x8EA2B3EE 0x526C # 0 +0x8EA2B3EF 0x526E # 0 +0x8EA2B3F0 0x52D6 # 0 +0x8EA2B3F1 0x52D3 # 0 +0x8EA2B3F2 0x532D # 0 +0x8EA2B3F3 0x539C # 0 +0x8EA2B3F4 0x5575 # 0 +0x8EA2B3F5 0x5576 # 0 +0x8EA2B3F6 0x553C # 0 +0x8EA2B3F7 0x554D # 0 +0x8EA2B3F8 0x5550 # 0 +0x8EA2B3F9 0x5534 # 0 +0x8EA2B3FA 0x552A # 0 +0x8EA2B3FB 0x5551 # 0 +0x8EA2B3FC 0x5562 # 0 +0x8EA2B3FD 0x5536 # 0 +0x8EA2B3FE 0x5535 # 0 +0x8EA2B4A1 0x5530 # 0 +0x8EA2B4A2 0x5552 # 0 +0x8EA2B4A3 0x5545 # 0 +0x8EA2B4A4 0x550C # 0 +0x8EA2B4A5 0x5532 # 0 +0x8EA2B4A6 0x5565 # 0 +0x8EA2B4A7 0x554E # 0 +0x8EA2B4A8 0x5539 # 0 +0x8EA2B4A9 0x5548 # 0 +0x8EA2B4AA 0x552D # 0 +0x8EA2B4AB 0x553B # 0 +0x8EA2B4AC 0x5540 # 0 +0x8EA2B4AD 0x554B # 0 +0x8EA2B4AE 0x570A # 0 +0x8EA2B4AF 0x5707 # 0 +0x8EA2B4B0 0x57FB # 0 +0x8EA2B4B1 0x5814 # 0 +0x8EA2B4B2 0x57E2 # 0 +0x8EA2B4B3 0x57F6 # 0 +0x8EA2B4B4 0x57DC # 0 +0x8EA2B4B5 0x57F4 # 0 +0x8EA2B4B6 0x5800 # 0 +0x8EA2B4B7 0x57ED # 0 +0x8EA2B4B8 0x57FD # 0 +0x8EA2B4B9 0x5808 # 0 +0x8EA2B4BA 0x57F8 # 0 +0x8EA2B4BB 0x580B # 0 +0x8EA2B4BC 0x57F3 # 0 +0x8EA2B4BD 0x57CF # 0 +0x8EA2B4BE 0x5807 # 0 +0x8EA2B4BF 0x57EE # 0 +0x8EA2B4C0 0x57E3 # 0 +0x8EA2B4C1 0x57F2 # 0 +0x8EA2B4C2 0x57E5 # 0 +0x8EA2B4C3 0x57EC # 0 +0x8EA2B4C4 0x57E1 # 0 +0x8EA2B4C5 0x580E # 0 +0x8EA2B4C6 0x57FC # 0 +0x8EA2B4C7 0x5810 # 0 +0x8EA2B4C8 0x57E7 # 0 +0x8EA2B4C9 0x5801 # 0 +0x8EA2B4CA 0x580C # 0 +0x8EA2B4CB 0x57F1 # 0 +0x8EA2B4CC 0x57E9 # 0 +0x8EA2B4CD 0x57F0 # 0 +0x8EA2B4CE 0x580D # 0 +0x8EA2B4CF 0x5804 # 0 +0x8EA2B4D0 0x595C # 0 +0x8EA2B4D1 0x5A60 # 0 +0x8EA2B4D2 0x5A58 # 0 +0x8EA2B4D3 0x5A55 # 0 +0x8EA2B4D4 0x5A67 # 0 +0x8EA2B4D5 0x5A5E # 0 +0x8EA2B4D6 0x5A38 # 0 +0x8EA2B4D7 0x5A35 # 0 +0x8EA2B4D8 0x5A6D # 0 +0x8EA2B4D9 0x5A50 # 0 +0x8EA2B4DA 0x5A5F # 0 +0x8EA2B4DB 0x5A65 # 0 +0x8EA2B4DC 0x5A6C # 0 +0x8EA2B4DD 0x5A53 # 0 +0x8EA2B4DE 0x5A64 # 0 +0x8EA2B4DF 0x5A57 # 0 +0x8EA2B4E0 0x5A43 # 0 +0x8EA2B4E1 0x5A5D # 0 +0x8EA2B4E2 0x5A52 # 0 +0x8EA2B4E3 0x5A44 # 0 +0x8EA2B4E4 0x5A5B # 0 +0x8EA2B4E5 0x5A48 # 0 +0x8EA2B4E6 0x5A8E # 0 +0x8EA2B4E7 0x5A3E # 0 +0x8EA2B4E8 0x5A4D # 0 +0x8EA2B4E9 0x5A39 # 0 +0x8EA2B4EA 0x5A4C # 0 +0x8EA2B4EB 0x5A70 # 0 +0x8EA2B4EC 0x5A69 # 0 +0x8EA2B4ED 0x5A47 # 0 +0x8EA2B4EE 0x5A51 # 0 +0x8EA2B4EF 0x5A56 # 0 +0x8EA2B4F0 0x5A42 # 0 +0x8EA2B4F1 0x5A5C # 0 +0x8EA2B4F2 0x5B72 # 0 +0x8EA2B4F3 0x5B6E # 0 +0x8EA2B4F4 0x5BC1 # 0 +0x8EA2B4F5 0x5BC0 # 0 +0x8EA2B4F6 0x5C59 # 0 +0x8EA2B4F7 0x5D1E # 0 +0x8EA2B4F8 0x5D0B # 0 +0x8EA2B4F9 0x5D1D # 0 +0x8EA2B4FA 0x5D1A # 0 +0x8EA2B4FB 0x5D20 # 0 +0x8EA2B4FC 0x5D0C # 0 +0x8EA2B4FD 0x5D28 # 0 +0x8EA2B4FE 0x5D0D # 0 +0x8EA2B5A1 0x5D26 # 0 +0x8EA2B5A2 0x5D25 # 0 +0x8EA2B5A3 0x5D0F # 0 +0x8EA2B5A4 0x5D30 # 0 +0x8EA2B5A5 0x5D12 # 0 +0x8EA2B5A6 0x5D23 # 0 +0x8EA2B5A7 0x5D1F # 0 +0x8EA2B5A8 0x5D2E # 0 +0x8EA2B5A9 0x5E3E # 0 +0x8EA2B5AA 0x5E34 # 0 +0x8EA2B5AB 0x5EB1 # 0 +0x8EA2B5AC 0x5EB4 # 0 +0x8EA2B5AD 0x5EB9 # 0 +0x8EA2B5AE 0x5EB2 # 0 +0x8EA2B5AF 0x5EB3 # 0 +0x8EA2B5B0 0x5F36 # 0 +0x8EA2B5B1 0x5F38 # 0 +0x8EA2B5B2 0x5F9B # 0 +0x8EA2B5B3 0x5F96 # 0 +0x8EA2B5B4 0x5F9F # 0 +0x8EA2B5B5 0x608A # 0 +0x8EA2B5B6 0x6090 # 0 +0x8EA2B5B7 0x6086 # 0 +0x8EA2B5B8 0x60BE # 0 +0x8EA2B5B9 0x60B0 # 0 +0x8EA2B5BA 0x60BA # 0 +0x8EA2B5BB 0x60D3 # 0 +0x8EA2B5BC 0x60D4 # 0 +0x8EA2B5BD 0x60CF # 0 +0x8EA2B5BE 0x60E4 # 0 +0x8EA2B5BF 0x60D9 # 0 +0x8EA2B5C0 0x60DD # 0 +0x8EA2B5C1 0x60C8 # 0 +0x8EA2B5C2 0x60B1 # 0 +0x8EA2B5C3 0x60DB # 0 +0x8EA2B5C4 0x60B7 # 0 +0x8EA2B5C5 0x60CA # 0 +0x8EA2B5C6 0x60BF # 0 +0x8EA2B5C7 0x60C3 # 0 +0x8EA2B5C8 0x60CD # 0 +0x8EA2B5C9 0x60C0 # 0 +0x8EA2B5CA 0x6332 # 0 +0x8EA2B5CB 0x6365 # 0 +0x8EA2B5CC 0x638A # 0 +0x8EA2B5CD 0x6382 # 0 +0x8EA2B5CE 0x637D # 0 +0x8EA2B5CF 0x63BD # 0 +0x8EA2B5D0 0x639E # 0 +0x8EA2B5D1 0x63AD # 0 +0x8EA2B5D2 0x639D # 0 +0x8EA2B5D3 0x6397 # 0 +0x8EA2B5D4 0x63AB # 0 +0x8EA2B5D5 0x638E # 0 +0x8EA2B5D6 0x636F # 0 +0x8EA2B5D7 0x6387 # 0 +0x8EA2B5D8 0x6390 # 0 +0x8EA2B5D9 0x636E # 0 +0x8EA2B5DA 0x63AF # 0 +0x8EA2B5DB 0x6375 # 0 +0x8EA2B5DC 0x639C # 0 +0x8EA2B5DD 0x636D # 0 +0x8EA2B5DE 0x63AE # 0 +0x8EA2B5DF 0x637C # 0 +0x8EA2B5E0 0x63A4 # 0 +0x8EA2B5E1 0x633B # 0 +0x8EA2B5E2 0x639F # 0 +0x8EA2B5E3 0x6378 # 0 +0x8EA2B5E4 0x6385 # 0 +0x8EA2B5E5 0x6381 # 0 +0x8EA2B5E6 0x6391 # 0 +0x8EA2B5E7 0x638D # 0 +0x8EA2B5E8 0x6370 # 0 +0x8EA2B5E9 0x6553 # 0 +0x8EA2B5EA 0x65CD # 0 +0x8EA2B5EB 0x6665 # 0 +0x8EA2B5EC 0x6661 # 0 +0x8EA2B5ED 0x665B # 0 +0x8EA2B5EE 0x6659 # 0 +0x8EA2B5EF 0x665C # 0 +0x8EA2B5F0 0x6662 # 0 +0x8EA2B5F1 0x6718 # 0 +0x8EA2B5F2 0x6879 # 0 +0x8EA2B5F3 0x6887 # 0 +0x8EA2B5F4 0x6890 # 0 +0x8EA2B5F5 0x689C # 0 +0x8EA2B5F6 0x686D # 0 +0x8EA2B5F7 0x686E # 0 +0x8EA2B5F8 0x68AE # 0 +0x8EA2B5F9 0x68AB # 0 +0x8EA2B5FA 0x6956 # 0 +0x8EA2B5FB 0x686F # 0 +0x8EA2B5FC 0x68A3 # 0 +0x8EA2B5FD 0x68AC # 0 +0x8EA2B5FE 0x68A9 # 0 +0x8EA2B6A1 0x6875 # 0 +0x8EA2B6A2 0x6874 # 0 +0x8EA2B6A3 0x68B2 # 0 +0x8EA2B6A4 0x688F # 0 +0x8EA2B6A5 0x6877 # 0 +0x8EA2B6A6 0x6892 # 0 +0x8EA2B6A7 0x687C # 0 +0x8EA2B6A8 0x686B # 0 +0x8EA2B6A9 0x6872 # 0 +0x8EA2B6AA 0x68AA # 0 +0x8EA2B6AB 0x6880 # 0 +0x8EA2B6AC 0x6871 # 0 +0x8EA2B6AD 0x687E # 0 +0x8EA2B6AE 0x689B # 0 +0x8EA2B6AF 0x6896 # 0 +0x8EA2B6B0 0x688B # 0 +0x8EA2B6B1 0x68A0 # 0 +0x8EA2B6B2 0x6889 # 0 +0x8EA2B6B3 0x68A4 # 0 +0x8EA2B6B4 0x6878 # 0 +0x8EA2B6B5 0x687B # 0 +0x8EA2B6B6 0x6891 # 0 +0x8EA2B6B7 0x688C # 0 +0x8EA2B6B8 0x688A # 0 +0x8EA2B6B9 0x687D # 0 +0x8EA2B6BA 0x6B36 # 0 +0x8EA2B6BB 0x6B33 # 0 +0x8EA2B6BC 0x6B37 # 0 +0x8EA2B6BD 0x6B38 # 0 +0x8EA2B6BE 0x6B91 # 0 +0x8EA2B6BF 0x6B8F # 0 +0x8EA2B6C0 0x6B8D # 0 +0x8EA2B6C1 0x6B8E # 0 +0x8EA2B6C2 0x6B8C # 0 +0x8EA2B6C3 0x6C2A # 0 +0x8EA2B6C4 0x6DC0 # 0 +0x8EA2B6C5 0x6DAB # 0 +0x8EA2B6C6 0x6DB4 # 0 +0x8EA2B6C7 0x6DB3 # 0 +0x8EA2B6C8 0x6E74 # 0 +0x8EA2B6C9 0x6DAC # 0 +0x8EA2B6CA 0x6DE9 # 0 +0x8EA2B6CB 0x6DE2 # 0 +0x8EA2B6CC 0x6DB7 # 0 +0x8EA2B6CD 0x6DF6 # 0 +0x8EA2B6CE 0x6DD4 # 0 +0x8EA2B6CF 0x6E00 # 0 +0x8EA2B6D0 0x6DC8 # 0 +0x8EA2B6D1 0x6DE0 # 0 +0x8EA2B6D2 0x6DDF # 0 +0x8EA2B6D3 0x6DD6 # 0 +0x8EA2B6D4 0x6DBE # 0 +0x8EA2B6D5 0x6DE5 # 0 +0x8EA2B6D6 0x6DDC # 0 +0x8EA2B6D7 0x6DDD # 0 +0x8EA2B6D8 0x6DDB # 0 +0x8EA2B6D9 0x6DF4 # 0 +0x8EA2B6DA 0x6DCA # 0 +0x8EA2B6DB 0x6DBD # 0 +0x8EA2B6DC 0x6DED # 0 +0x8EA2B6DD 0x6DF0 # 0 +0x8EA2B6DE 0x6DBA # 0 +0x8EA2B6DF 0x6DD5 # 0 +0x8EA2B6E0 0x6DC2 # 0 +0x8EA2B6E1 0x6DCF # 0 +0x8EA2B6E2 0x6DC9 # 0 +0x8EA2B6E3 0x6DD0 # 0 +0x8EA2B6E4 0x6DF2 # 0 +0x8EA2B6E5 0x6DD3 # 0 +0x8EA2B6E6 0x6DFD # 0 +0x8EA2B6E7 0x6DD7 # 0 +0x8EA2B6E8 0x6DCD # 0 +0x8EA2B6E9 0x6DE3 # 0 +0x8EA2B6EA 0x6DBB # 0 +0x8EA2B6EB 0x70FA # 0 +0x8EA2B6EC 0x710D # 0 +0x8EA2B6ED 0x70F7 # 0 +0x8EA2B6EE 0x7117 # 0 +0x8EA2B6EF 0x70F4 # 0 +0x8EA2B6F0 0x710C # 0 +0x8EA2B6F1 0x70F0 # 0 +0x8EA2B6F2 0x7104 # 0 +0x8EA2B6F3 0x70F3 # 0 +0x8EA2B6F4 0x7110 # 0 +0x8EA2B6F5 0x70FC # 0 +0x8EA2B6F6 0x70FF # 0 +0x8EA2B6F7 0x7106 # 0 +0x8EA2B6F8 0x7113 # 0 +0x8EA2B6F9 0x7100 # 0 +0x8EA2B6FA 0x70F8 # 0 +0x8EA2B6FB 0x70F6 # 0 +0x8EA2B6FC 0x710B # 0 +0x8EA2B6FD 0x7102 # 0 +0x8EA2B6FE 0x710E # 0 +0x8EA2B7A1 0x727E # 0 +0x8EA2B7A2 0x727B # 0 +0x8EA2B7A3 0x727C # 0 +0x8EA2B7A4 0x727F # 0 +0x8EA2B7A5 0x731D # 0 +0x8EA2B7A6 0x7317 # 0 +0x8EA2B7A7 0x7307 # 0 +0x8EA2B7A8 0x7311 # 0 +0x8EA2B7A9 0x7318 # 0 +0x8EA2B7AA 0x730A # 0 +0x8EA2B7AB 0x7308 # 0 +0x8EA2B7AC 0x72FF # 0 +0x8EA2B7AD 0x730F # 0 +0x8EA2B7AE 0x731E # 0 +0x8EA2B7AF 0x7388 # 0 +0x8EA2B7B0 0x73F6 # 0 +0x8EA2B7B1 0x73F8 # 0 +0x8EA2B7B2 0x73F5 # 0 +0x8EA2B7B3 0x7404 # 0 +0x8EA2B7B4 0x7401 # 0 +0x8EA2B7B5 0x73FD # 0 +0x8EA2B7B6 0x7407 # 0 +0x8EA2B7B7 0x7400 # 0 +0x8EA2B7B8 0x73FA # 0 +0x8EA2B7B9 0x73FC # 0 +0x8EA2B7BA 0x73FF # 0 +0x8EA2B7BB 0x740C # 0 +0x8EA2B7BC 0x740B # 0 +0x8EA2B7BD 0x73F4 # 0 +0x8EA2B7BE 0x7408 # 0 +0x8EA2B7BF 0x7564 # 0 +0x8EA2B7C0 0x7563 # 0 +0x8EA2B7C1 0x75CE # 0 +0x8EA2B7C2 0x75D2 # 0 +0x8EA2B7C3 0x75CF # 0 +0x8EA2B7C4 0x75CB # 0 +0x8EA2B7C5 0x75CC # 0 +0x8EA2B7C6 0x75D1 # 0 +0x8EA2B7C7 0x75D0 # 0 +0x8EA2B7C8 0x768F # 0 +0x8EA2B7C9 0x7689 # 0 +0x8EA2B7CA 0x76D3 # 0 +0x8EA2B7CB 0x7739 # 0 +0x8EA2B7CC 0x772F # 0 +0x8EA2B7CD 0x772D # 0 +0x8EA2B7CE 0x7731 # 0 +0x8EA2B7CF 0x7732 # 0 +0x8EA2B7D0 0x7734 # 0 +0x8EA2B7D1 0x7733 # 0 +0x8EA2B7D2 0x773D # 0 +0x8EA2B7D3 0x7725 # 0 +0x8EA2B7D4 0x773B # 0 +0x8EA2B7D5 0x7735 # 0 +0x8EA2B7D6 0x7848 # 0 +0x8EA2B7D7 0x7852 # 0 +0x8EA2B7D8 0x7849 # 0 +0x8EA2B7D9 0x784D # 0 +0x8EA2B7DA 0x784A # 0 +0x8EA2B7DB 0x784C # 0 +0x8EA2B7DC 0x7826 # 0 +0x8EA2B7DD 0x7845 # 0 +0x8EA2B7DE 0x7850 # 0 +0x8EA2B7DF 0x7964 # 0 +0x8EA2B7E0 0x7967 # 0 +0x8EA2B7E1 0x7969 # 0 +0x8EA2B7E2 0x796A # 0 +0x8EA2B7E3 0x7963 # 0 +0x8EA2B7E4 0x796B # 0 +0x8EA2B7E5 0x7961 # 0 +0x8EA2B7E6 0x79BB # 0 +0x8EA2B7E7 0x79FA # 0 +0x8EA2B7E8 0x79F8 # 0 +0x8EA2B7E9 0x79F6 # 0 +0x8EA2B7EA 0x79F7 # 0 +0x8EA2B7EB 0x7A8F # 0 +0x8EA2B7EC 0x7A94 # 0 +0x8EA2B7ED 0x7A90 # 0 +0x8EA2B7EE 0x7B35 # 0 +0x8EA2B7EF 0x7B3B # 0 +0x8EA2B7F0 0x7B34 # 0 +0x8EA2B7F1 0x7B25 # 0 +0x8EA2B7F2 0x7B30 # 0 +0x8EA2B7F3 0x7B22 # 0 +0x8EA2B7F4 0x7B24 # 0 +0x8EA2B7F5 0x7B33 # 0 +0x8EA2B7F6 0x7B18 # 0 +0x8EA2B7F7 0x7B2A # 0 +0x8EA2B7F8 0x7B1D # 0 +0x8EA2B7F9 0x7B31 # 0 +0x8EA2B7FA 0x7B2B # 0 +0x8EA2B7FB 0x7B2D # 0 +0x8EA2B7FC 0x7B2F # 0 +0x8EA2B7FD 0x7B32 # 0 +0x8EA2B7FE 0x7B38 # 0 +0x8EA2B8A1 0x7B1A # 0 +0x8EA2B8A2 0x7B23 # 0 +0x8EA2B8A3 0x7C94 # 0 +0x8EA2B8A4 0x7C98 # 0 +0x8EA2B8A5 0x7C96 # 0 +0x8EA2B8A6 0x7CA3 # 0 +0x8EA2B8A7 0x7D35 # 0 +0x8EA2B8A8 0x7D3D # 0 +0x8EA2B8A9 0x7D38 # 0 +0x8EA2B8AA 0x7D36 # 0 +0x8EA2B8AB 0x7D3A # 0 +0x8EA2B8AC 0x7D45 # 0 +0x8EA2B8AD 0x7D2C # 0 +0x8EA2B8AE 0x7D29 # 0 +0x8EA2B8AF 0x7D41 # 0 +0x8EA2B8B0 0x7D47 # 0 +0x8EA2B8B1 0x7D3E # 0 +0x8EA2B8B2 0x7D3F # 0 +0x8EA2B8B3 0x7D4A # 0 +0x8EA2B8B4 0x7D3B # 0 +0x8EA2B8B5 0x7D28 # 0 +0x8EA2B8B6 0x7F63 # 0 +0x8EA2B8B7 0x7F95 # 0 +0x8EA2B8B8 0x7F9C # 0 +0x8EA2B8B9 0x7F9D # 0 +0x8EA2B8BA 0x7F9B # 0 +0x8EA2B8BB 0x7FCA # 0 +0x8EA2B8BC 0x7FCB # 0 +0x8EA2B8BD 0x7FCD # 0 +0x8EA2B8BE 0x7FD0 # 0 +0x8EA2B8BF 0x7FD1 # 0 +0x8EA2B8C0 0x7FC7 # 0 +0x8EA2B8C1 0x7FCF # 0 +0x8EA2B8C2 0x7FC9 # 0 +0x8EA2B8C3 0x801F # 0 +0x8EA2B8C4 0x801E # 0 +0x8EA2B8C5 0x801B # 0 +0x8EA2B8C6 0x8047 # 0 +0x8EA2B8C7 0x8043 # 0 +0x8EA2B8C8 0x8048 # 0 +0x8EA2B8C9 0x8118 # 0 +0x8EA2B8CA 0x8125 # 0 +0x8EA2B8CB 0x8119 # 0 +0x8EA2B8CC 0x811B # 0 +0x8EA2B8CD 0x812D # 0 +0x8EA2B8CE 0x811F # 0 +0x8EA2B8CF 0x812C # 0 +0x8EA2B8D0 0x811E # 0 +0x8EA2B8D1 0x8121 # 0 +0x8EA2B8D2 0x8115 # 0 +0x8EA2B8D3 0x8127 # 0 +0x8EA2B8D4 0x811D # 0 +0x8EA2B8D5 0x8122 # 0 +0x8EA2B8D6 0x8211 # 0 +0x8EA2B8D7 0x8238 # 0 +0x8EA2B8D8 0x8233 # 0 +0x8EA2B8D9 0x823A # 0 +0x8EA2B8DA 0x8234 # 0 +0x8EA2B8DB 0x8232 # 0 +0x8EA2B8DC 0x8274 # 0 +0x8EA2B8DD 0x8390 # 0 +0x8EA2B8DE 0x83A3 # 0 +0x8EA2B8DF 0x83A8 # 0 +0x8EA2B8E0 0x838D # 0 +0x8EA2B8E1 0x837A # 0 +0x8EA2B8E2 0x8373 # 0 +0x8EA2B8E3 0x83A4 # 0 +0x8EA2B8E4 0x8374 # 0 +0x8EA2B8E5 0x838F # 0 +0x8EA2B8E6 0x8381 # 0 +0x8EA2B8E7 0x8395 # 0 +0x8EA2B8E8 0x8399 # 0 +0x8EA2B8E9 0x8375 # 0 +0x8EA2B8EA 0x8394 # 0 +0x8EA2B8EB 0x83A9 # 0 +0x8EA2B8EC 0x837D # 0 +0x8EA2B8ED 0x8383 # 0 +0x8EA2B8EE 0x838C # 0 +0x8EA2B8EF 0x839D # 0 +0x8EA2B8F0 0x839B # 0 +0x8EA2B8F1 0x83AA # 0 +0x8EA2B8F2 0x838B # 0 +0x8EA2B8F3 0x837E # 0 +0x8EA2B8F4 0x83A5 # 0 +0x8EA2B8F5 0x83AF # 0 +0x8EA2B8F6 0x8388 # 0 +0x8EA2B8F7 0x8397 # 0 +0x8EA2B8F8 0x83B0 # 0 +0x8EA2B8F9 0x837F # 0 +0x8EA2B8FA 0x83A6 # 0 +0x8EA2B8FB 0x8387 # 0 +0x8EA2B8FC 0x83AE # 0 +0x8EA2B8FD 0x8376 # 0 +0x8EA2B8FE 0x8659 # 0 +0x8EA2B9A1 0x8656 # 0 +0x8EA2B9A2 0x86BF # 0 +0x8EA2B9A3 0x86B7 # 0 +0x8EA2B9A4 0x86C2 # 0 +0x8EA2B9A5 0x86C1 # 0 +0x8EA2B9A6 0x86C5 # 0 +0x8EA2B9A7 0x86BA # 0 +0x8EA2B9A8 0x86B0 # 0 +0x8EA2B9A9 0x86C8 # 0 +0x8EA2B9AA 0x86B9 # 0 +0x8EA2B9AB 0x86B3 # 0 +0x8EA2B9AC 0x86B8 # 0 +0x8EA2B9AD 0x86CC # 0 +0x8EA2B9AE 0x86B4 # 0 +0x8EA2B9AF 0x86BB # 0 +0x8EA2B9B0 0x86BC # 0 +0x8EA2B9B1 0x86C3 # 0 +0x8EA2B9B2 0x86BD # 0 +0x8EA2B9B3 0x86BE # 0 +0x8EA2B9B4 0x8852 # 0 +0x8EA2B9B5 0x8889 # 0 +0x8EA2B9B6 0x8895 # 0 +0x8EA2B9B7 0x88A8 # 0 +0x8EA2B9B8 0x88A2 # 0 +0x8EA2B9B9 0x88AA # 0 +0x8EA2B9BA 0x889A # 0 +0x8EA2B9BB 0x8891 # 0 +0x8EA2B9BC 0x88A1 # 0 +0x8EA2B9BD 0x889F # 0 +0x8EA2B9BE 0x8898 # 0 +0x8EA2B9BF 0x88A7 # 0 +0x8EA2B9C0 0x8899 # 0 +0x8EA2B9C1 0x889B # 0 +0x8EA2B9C2 0x8897 # 0 +0x8EA2B9C3 0x88A4 # 0 +0x8EA2B9C4 0x88AC # 0 +0x8EA2B9C5 0x888C # 0 +0x8EA2B9C6 0x8893 # 0 +0x8EA2B9C7 0x888E # 0 +0x8EA2B9C8 0x8982 # 0 +0x8EA2B9C9 0x89D6 # 0 +0x8EA2B9CA 0x89D9 # 0 +0x8EA2B9CB 0x89D5 # 0 +0x8EA2B9CC 0x8A30 # 0 +0x8EA2B9CD 0x8A27 # 0 +0x8EA2B9CE 0x8A2C # 0 +0x8EA2B9CF 0x8A1E # 0 +0x8EA2B9D0 0x8C39 # 0 +0x8EA2B9D1 0x8C3B # 0 +0x8EA2B9D2 0x8C5C # 0 +0x8EA2B9D3 0x8C5D # 0 +0x8EA2B9D4 0x8C7D # 0 +0x8EA2B9D5 0x8CA5 # 0 +0x8EA2B9D6 0x8D7D # 0 +0x8EA2B9D7 0x8D7B # 0 +0x8EA2B9D8 0x8D79 # 0 +0x8EA2B9D9 0x8DBC # 0 +0x8EA2B9DA 0x8DC2 # 0 +0x8EA2B9DB 0x8DB9 # 0 +0x8EA2B9DC 0x8DBF # 0 +0x8EA2B9DD 0x8DC1 # 0 +0x8EA2B9DE 0x8ED8 # 0 +0x8EA2B9DF 0x8EDE # 0 +0x8EA2B9E0 0x8EDD # 0 +0x8EA2B9E1 0x8EDC # 0 +0x8EA2B9E2 0x8ED7 # 0 +0x8EA2B9E3 0x8EE0 # 0 +0x8EA2B9E4 0x8EE1 # 0 +0x8EA2B9E5 0x9024 # 0 +0x8EA2B9E6 0x900B # 0 +0x8EA2B9E7 0x9011 # 0 +0x8EA2B9E8 0x901C # 0 +0x8EA2B9E9 0x900C # 0 +0x8EA2B9EA 0x9021 # 0 +0x8EA2B9EB 0x90EF # 0 +0x8EA2B9EC 0x90EA # 0 +0x8EA2B9ED 0x90F0 # 0 +0x8EA2B9EE 0x90F4 # 0 +0x8EA2B9EF 0x90F2 # 0 +0x8EA2B9F0 0x90F3 # 0 +0x8EA2B9F1 0x90D4 # 0 +0x8EA2B9F2 0x90EB # 0 +0x8EA2B9F3 0x90EC # 0 +0x8EA2B9F4 0x90E9 # 0 +0x8EA2B9F5 0x9156 # 0 +0x8EA2B9F6 0x9158 # 0 +0x8EA2B9F7 0x915A # 0 +0x8EA2B9F8 0x9153 # 0 +0x8EA2B9F9 0x9155 # 0 +0x8EA2B9FA 0x91EC # 0 +0x8EA2B9FB 0x91F4 # 0 +0x8EA2B9FC 0x91F1 # 0 +0x8EA2B9FD 0x91F3 # 0 +0x8EA2B9FE 0x91F8 # 0 +0x8EA2BAA1 0x91E4 # 0 +0x8EA2BAA2 0x91F9 # 0 +0x8EA2BAA3 0x91EA # 0 +0x8EA2BAA4 0x91EB # 0 +0x8EA2BAA5 0x91F7 # 0 +0x8EA2BAA6 0x91E8 # 0 +0x8EA2BAA7 0x91EE # 0 +0x8EA2BAA8 0x957A # 0 +0x8EA2BAA9 0x9586 # 0 +0x8EA2BAAA 0x9588 # 0 +0x8EA2BAAB 0x967C # 0 +0x8EA2BAAC 0x966D # 0 +0x8EA2BAAD 0x966B # 0 +0x8EA2BAAE 0x9671 # 0 +0x8EA2BAAF 0x966F # 0 +0x8EA2BAB0 0x96BF # 0 +0x8EA2BAB1 0x976A # 0 +0x8EA2BAB2 0x9804 # 0 +0x8EA2BAB3 0x98E5 # 0 +0x8EA2BAB4 0x9997 # 0 +0x8EA2BAB5 0x509B # 0 +0x8EA2BAB6 0x5095 # 0 +0x8EA2BAB7 0x5094 # 0 +0x8EA2BAB8 0x509E # 0 +0x8EA2BAB9 0x508B # 0 +0x8EA2BABA 0x50A3 # 0 +0x8EA2BABB 0x5083 # 0 +0x8EA2BABC 0x508C # 0 +0x8EA2BABD 0x508E # 0 +0x8EA2BABE 0x509D # 0 +0x8EA2BABF 0x5068 # 0 +0x8EA2BAC0 0x509C # 0 +0x8EA2BAC1 0x5092 # 0 +0x8EA2BAC2 0x5082 # 0 +0x8EA2BAC3 0x5087 # 0 +0x8EA2BAC4 0x515F # 0 +0x8EA2BAC5 0x51D4 # 0 +0x8EA2BAC6 0x5312 # 0 +0x8EA2BAC7 0x5311 # 0 +0x8EA2BAC8 0x53A4 # 0 +0x8EA2BAC9 0x53A7 # 0 +0x8EA2BACA 0x5591 # 0 +0x8EA2BACB 0x55A8 # 0 +0x8EA2BACC 0x55A5 # 0 +0x8EA2BACD 0x55AD # 0 +0x8EA2BACE 0x5577 # 0 +0x8EA2BACF 0x5645 # 0 +0x8EA2BAD0 0x55A2 # 0 +0x8EA2BAD1 0x5593 # 0 +0x8EA2BAD2 0x5588 # 0 +0x8EA2BAD3 0x558F # 0 +0x8EA2BAD4 0x55B5 # 0 +0x8EA2BAD5 0x5581 # 0 +0x8EA2BAD6 0x55A3 # 0 +0x8EA2BAD7 0x5592 # 0 +0x8EA2BAD8 0x55A4 # 0 +0x8EA2BAD9 0x557D # 0 +0x8EA2BADA 0x558C # 0 +0x8EA2BADB 0x55A6 # 0 +0x8EA2BADC 0x557F # 0 +0x8EA2BADD 0x5595 # 0 +0x8EA2BADE 0x55A1 # 0 +0x8EA2BADF 0x558E # 0 +0x8EA2BAE0 0x570C # 0 +0x8EA2BAE1 0x5829 # 0 +0x8EA2BAE2 0x5837 # 0 +0x8EA2BAE3 0x5819 # 0 +0x8EA2BAE4 0x581E # 0 +0x8EA2BAE5 0x5827 # 0 +0x8EA2BAE6 0x5823 # 0 +0x8EA2BAE7 0x5828 # 0 +0x8EA2BAE8 0x57F5 # 0 +0x8EA2BAE9 0x5848 # 0 +0x8EA2BAEA 0x5825 # 0 +0x8EA2BAEB 0x581C # 0 +0x8EA2BAEC 0x581B # 0 +0x8EA2BAED 0x5833 # 0 +0x8EA2BAEE 0x583F # 0 +0x8EA2BAEF 0x5836 # 0 +0x8EA2BAF0 0x582E # 0 +0x8EA2BAF1 0x5839 # 0 +0x8EA2BAF2 0x5838 # 0 +0x8EA2BAF3 0x582D # 0 +0x8EA2BAF4 0x582C # 0 +0x8EA2BAF5 0x583B # 0 +0x8EA2BAF6 0x5961 # 0 +0x8EA2BAF7 0x5AAF # 0 +0x8EA2BAF8 0x5A94 # 0 +0x8EA2BAF9 0x5A9F # 0 +0x8EA2BAFA 0x5A7A # 0 +0x8EA2BAFB 0x5AA2 # 0 +0x8EA2BAFC 0x5A9E # 0 +0x8EA2BAFD 0x5A78 # 0 +0x8EA2BAFE 0x5AA6 # 0 +0x8EA2BBA1 0x5A7C # 0 +0x8EA2BBA2 0x5AA5 # 0 +0x8EA2BBA3 0x5AAC # 0 +0x8EA2BBA4 0x5A95 # 0 +0x8EA2BBA5 0x5AAE # 0 +0x8EA2BBA6 0x5A37 # 0 +0x8EA2BBA7 0x5A84 # 0 +0x8EA2BBA8 0x5A8A # 0 +0x8EA2BBA9 0x5A97 # 0 +0x8EA2BBAA 0x5A83 # 0 +0x8EA2BBAB 0x5A8B # 0 +0x8EA2BBAC 0x5AA9 # 0 +0x8EA2BBAD 0x5A7B # 0 +0x8EA2BBAE 0x5A7D # 0 +0x8EA2BBAF 0x5A8C # 0 +0x8EA2BBB0 0x5A9C # 0 +0x8EA2BBB1 0x5A8F # 0 +0x8EA2BBB2 0x5A93 # 0 +0x8EA2BBB3 0x5A9D # 0 +0x8EA2BBB4 0x5BEA # 0 +0x8EA2BBB5 0x5BCD # 0 +0x8EA2BBB6 0x5BCB # 0 +0x8EA2BBB7 0x5BD4 # 0 +0x8EA2BBB8 0x5BD1 # 0 +0x8EA2BBB9 0x5BCA # 0 +0x8EA2BBBA 0x5BCE # 0 +0x8EA2BBBB 0x5C0C # 0 +0x8EA2BBBC 0x5C30 # 0 +0x8EA2BBBD 0x5D37 # 0 +0x8EA2BBBE 0x5D43 # 0 +0x8EA2BBBF 0x5D6B # 0 +0x8EA2BBC0 0x5D41 # 0 +0x8EA2BBC1 0x5D4B # 0 +0x8EA2BBC2 0x5D3F # 0 +0x8EA2BBC3 0x5D35 # 0 +0x8EA2BBC4 0x5D51 # 0 +0x8EA2BBC5 0x5D4E # 0 +0x8EA2BBC6 0x5D55 # 0 +0x8EA2BBC7 0x5D33 # 0 +0x8EA2BBC8 0x5D3A # 0 +0x8EA2BBC9 0x5D52 # 0 +0x8EA2BBCA 0x5D3D # 0 +0x8EA2BBCB 0x5D31 # 0 +0x8EA2BBCC 0x5D59 # 0 +0x8EA2BBCD 0x5D42 # 0 +0x8EA2BBCE 0x5D39 # 0 +0x8EA2BBCF 0x5D49 # 0 +0x8EA2BBD0 0x5D38 # 0 +0x8EA2BBD1 0x5D3C # 0 +0x8EA2BBD2 0x5D32 # 0 +0x8EA2BBD3 0x5D36 # 0 +0x8EA2BBD4 0x5D40 # 0 +0x8EA2BBD5 0x5D45 # 0 +0x8EA2BBD6 0x5E44 # 0 +0x8EA2BBD7 0x5E41 # 0 +0x8EA2BBD8 0x5F58 # 0 +0x8EA2BBD9 0x5FA6 # 0 +0x8EA2BBDA 0x5FA5 # 0 +0x8EA2BBDB 0x5FAB # 0 +0x8EA2BBDC 0x60C9 # 0 +0x8EA2BBDD 0x60B9 # 0 +0x8EA2BBDE 0x60CC # 0 +0x8EA2BBDF 0x60E2 # 0 +0x8EA2BBE0 0x60CE # 0 +0x8EA2BBE1 0x60C4 # 0 +0x8EA2BBE2 0x6114 # 0 +0x8EA2BBE3 0x60F2 # 0 +0x8EA2BBE4 0x610A # 0 +0x8EA2BBE5 0x6116 # 0 +0x8EA2BBE6 0x6105 # 0 +0x8EA2BBE7 0x60F5 # 0 +0x8EA2BBE8 0x6113 # 0 +0x8EA2BBE9 0x60F8 # 0 +0x8EA2BBEA 0x60FC # 0 +0x8EA2BBEB 0x60FE # 0 +0x8EA2BBEC 0x60C1 # 0 +0x8EA2BBED 0x6103 # 0 +0x8EA2BBEE 0x6118 # 0 +0x8EA2BBEF 0x611D # 0 +0x8EA2BBF0 0x6110 # 0 +0x8EA2BBF1 0x60FF # 0 +0x8EA2BBF2 0x6104 # 0 +0x8EA2BBF3 0x610B # 0 +0x8EA2BBF4 0x624A # 0 +0x8EA2BBF5 0x6394 # 0 +0x8EA2BBF6 0x63B1 # 0 +0x8EA2BBF7 0x63B0 # 0 +0x8EA2BBF8 0x63CE # 0 +0x8EA2BBF9 0x63E5 # 0 +0x8EA2BBFA 0x63E8 # 0 +0x8EA2BBFB 0x63EF # 0 +0x8EA2BBFC 0x63C3 # 0 +0x8EA2BBFD 0x649D # 0 +0x8EA2BBFE 0x63F3 # 0 +0x8EA2BCA1 0x63CA # 0 +0x8EA2BCA2 0x63E0 # 0 +0x8EA2BCA3 0x63F6 # 0 +0x8EA2BCA4 0x63D5 # 0 +0x8EA2BCA5 0x63F2 # 0 +0x8EA2BCA6 0x63F5 # 0 +0x8EA2BCA7 0x6461 # 0 +0x8EA2BCA8 0x63DF # 0 +0x8EA2BCA9 0x63BE # 0 +0x8EA2BCAA 0x63DD # 0 +0x8EA2BCAB 0x63DC # 0 +0x8EA2BCAC 0x63C4 # 0 +0x8EA2BCAD 0x63D8 # 0 +0x8EA2BCAE 0x63D3 # 0 +0x8EA2BCAF 0x63C2 # 0 +0x8EA2BCB0 0x63C7 # 0 +0x8EA2BCB1 0x63CC # 0 +0x8EA2BCB2 0x63CB # 0 +0x8EA2BCB3 0x63C8 # 0 +0x8EA2BCB4 0x63F0 # 0 +0x8EA2BCB5 0x63D7 # 0 +0x8EA2BCB6 0x63D9 # 0 +0x8EA2BCB7 0x6532 # 0 +0x8EA2BCB8 0x6567 # 0 +0x8EA2BCB9 0x656A # 0 +0x8EA2BCBA 0x6564 # 0 +0x8EA2BCBB 0x655C # 0 +0x8EA2BCBC 0x6568 # 0 +0x8EA2BCBD 0x6565 # 0 +0x8EA2BCBE 0x658C # 0 +0x8EA2BCBF 0x659D # 0 +0x8EA2BCC0 0x659E # 0 +0x8EA2BCC1 0x65AE # 0 +0x8EA2BCC2 0x65D0 # 0 +0x8EA2BCC3 0x65D2 # 0 +0x8EA2BCC4 0x667C # 0 +0x8EA2BCC5 0x666C # 0 +0x8EA2BCC6 0x667B # 0 +0x8EA2BCC7 0x6680 # 0 +0x8EA2BCC8 0x6671 # 0 +0x8EA2BCC9 0x6679 # 0 +0x8EA2BCCA 0x666A # 0 +0x8EA2BCCB 0x6672 # 0 +0x8EA2BCCC 0x6701 # 0 +0x8EA2BCCD 0x690C # 0 +0x8EA2BCCE 0x68D3 # 0 +0x8EA2BCCF 0x6904 # 0 +0x8EA2BCD0 0x68DC # 0 +0x8EA2BCD1 0x692A # 0 +0x8EA2BCD2 0x68EC # 0 +0x8EA2BCD3 0x68EA # 0 +0x8EA2BCD4 0x68F1 # 0 +0x8EA2BCD5 0x690F # 0 +0x8EA2BCD6 0x68D6 # 0 +0x8EA2BCD7 0x68F7 # 0 +0x8EA2BCD8 0x68EB # 0 +0x8EA2BCD9 0x68E4 # 0 +0x8EA2BCDA 0x68F6 # 0 +0x8EA2BCDB 0x6913 # 0 +0x8EA2BCDC 0x6910 # 0 +0x8EA2BCDD 0x68F3 # 0 +0x8EA2BCDE 0x68E1 # 0 +0x8EA2BCDF 0x6907 # 0 +0x8EA2BCE0 0x68CC # 0 +0x8EA2BCE1 0x6908 # 0 +0x8EA2BCE2 0x6970 # 0 +0x8EA2BCE3 0x68B4 # 0 +0x8EA2BCE4 0x6911 # 0 +0x8EA2BCE5 0x68EF # 0 +0x8EA2BCE6 0x68C6 # 0 +0x8EA2BCE7 0x6914 # 0 +0x8EA2BCE8 0x68F8 # 0 +0x8EA2BCE9 0x68D0 # 0 +0x8EA2BCEA 0x68FD # 0 +0x8EA2BCEB 0x68FC # 0 +0x8EA2BCEC 0x68E8 # 0 +0x8EA2BCED 0x690B # 0 +0x8EA2BCEE 0x690A # 0 +0x8EA2BCEF 0x6917 # 0 +0x8EA2BCF0 0x68CE # 0 +0x8EA2BCF1 0x68C8 # 0 +0x8EA2BCF2 0x68DD # 0 +0x8EA2BCF3 0x68DE # 0 +0x8EA2BCF4 0x68E6 # 0 +0x8EA2BCF5 0x68F4 # 0 +0x8EA2BCF6 0x68D1 # 0 +0x8EA2BCF7 0x6906 # 0 +0x8EA2BCF8 0x68D4 # 0 +0x8EA2BCF9 0x68E9 # 0 +0x8EA2BCFA 0x6915 # 0 +0x8EA2BCFB 0x6925 # 0 +0x8EA2BCFC 0x68C7 # 0 +0x8EA2BCFD 0x6B39 # 0 +0x8EA2BCFE 0x6B3B # 0 +0x8EA2BDA1 0x6B3F # 0 +0x8EA2BDA2 0x6B3C # 0 +0x8EA2BDA3 0x6B94 # 0 +0x8EA2BDA4 0x6B97 # 0 +0x8EA2BDA5 0x6B99 # 0 +0x8EA2BDA6 0x6B95 # 0 +0x8EA2BDA7 0x6BBD # 0 +0x8EA2BDA8 0x6BF0 # 0 +0x8EA2BDA9 0x6BF2 # 0 +0x8EA2BDAA 0x6BF3 # 0 +0x8EA2BDAB 0x6C30 # 0 +0x8EA2BDAC 0x6DFC # 0 +0x8EA2BDAD 0x6E46 # 0 +0x8EA2BDAE 0x6E47 # 0 +0x8EA2BDAF 0x6E1F # 0 +0x8EA2BDB0 0x6E49 # 0 +0x8EA2BDB1 0x6E88 # 0 +0x8EA2BDB2 0x6E3C # 0 +0x8EA2BDB3 0x6E3D # 0 +0x8EA2BDB4 0x6E45 # 0 +0x8EA2BDB5 0x6E62 # 0 +0x8EA2BDB6 0x6E2B # 0 +0x8EA2BDB7 0x6E3F # 0 +0x8EA2BDB8 0x6E41 # 0 +0x8EA2BDB9 0x6E5D # 0 +0x8EA2BDBA 0x6E73 # 0 +0x8EA2BDBB 0x6E1C # 0 +0x8EA2BDBC 0x6E33 # 0 +0x8EA2BDBD 0x6E4B # 0 +0x8EA2BDBE 0x6E40 # 0 +0x8EA2BDBF 0x6E51 # 0 +0x8EA2BDC0 0x6E3B # 0 +0x8EA2BDC1 0x6E03 # 0 +0x8EA2BDC2 0x6E2E # 0 +0x8EA2BDC3 0x6E5E # 0 +0x8EA2BDC4 0x6E68 # 0 +0x8EA2BDC5 0x6E5C # 0 +0x8EA2BDC6 0x6E61 # 0 +0x8EA2BDC7 0x6E31 # 0 +0x8EA2BDC8 0x6E28 # 0 +0x8EA2BDC9 0x6E60 # 0 +0x8EA2BDCA 0x6E71 # 0 +0x8EA2BDCB 0x6E6B # 0 +0x8EA2BDCC 0x6E39 # 0 +0x8EA2BDCD 0x6E22 # 0 +0x8EA2BDCE 0x6E30 # 0 +0x8EA2BDCF 0x6E53 # 0 +0x8EA2BDD0 0x6E65 # 0 +0x8EA2BDD1 0x6E27 # 0 +0x8EA2BDD2 0x6E78 # 0 +0x8EA2BDD3 0x6E64 # 0 +0x8EA2BDD4 0x6E77 # 0 +0x8EA2BDD5 0x6E55 # 0 +0x8EA2BDD6 0x6E79 # 0 +0x8EA2BDD7 0x6E52 # 0 +0x8EA2BDD8 0x6E66 # 0 +0x8EA2BDD9 0x6E35 # 0 +0x8EA2BDDA 0x6E36 # 0 +0x8EA2BDDB 0x6E5A # 0 +0x8EA2BDDC 0x7120 # 0 +0x8EA2BDDD 0x711E # 0 +0x8EA2BDDE 0x712F # 0 +0x8EA2BDDF 0x70FB # 0 +0x8EA2BDE0 0x712E # 0 +0x8EA2BDE1 0x7131 # 0 +0x8EA2BDE2 0x7123 # 0 +0x8EA2BDE3 0x7125 # 0 +0x8EA2BDE4 0x7122 # 0 +0x8EA2BDE5 0x7132 # 0 +0x8EA2BDE6 0x711F # 0 +0x8EA2BDE7 0x7128 # 0 +0x8EA2BDE8 0x713A # 0 +0x8EA2BDE9 0x711B # 0 +0x8EA2BDEA 0x724B # 0 +0x8EA2BDEB 0x725A # 0 +0x8EA2BDEC 0x7288 # 0 +0x8EA2BDED 0x7289 # 0 +0x8EA2BDEE 0x7286 # 0 +0x8EA2BDEF 0x7285 # 0 +0x8EA2BDF0 0x728B # 0 +0x8EA2BDF1 0x7312 # 0 +0x8EA2BDF2 0x730B # 0 +0x8EA2BDF3 0x7330 # 0 +0x8EA2BDF4 0x7322 # 0 +0x8EA2BDF5 0x7331 # 0 +0x8EA2BDF6 0x7333 # 0 +0x8EA2BDF7 0x7327 # 0 +0x8EA2BDF8 0x7332 # 0 +0x8EA2BDF9 0x732D # 0 +0x8EA2BDFA 0x7326 # 0 +0x8EA2BDFB 0x7323 # 0 +0x8EA2BDFC 0x7335 # 0 +0x8EA2BDFD 0x730C # 0 +0x8EA2BDFE 0x742E # 0 +0x8EA2BEA1 0x742C # 0 +0x8EA2BEA2 0x7430 # 0 +0x8EA2BEA3 0x742B # 0 +0x8EA2BEA4 0x7416 # 0 +0x8EA2BEA5 0x741A # 0 +0x8EA2BEA6 0x7421 # 0 +0x8EA2BEA7 0x742D # 0 +0x8EA2BEA8 0x7431 # 0 +0x8EA2BEA9 0x7424 # 0 +0x8EA2BEAA 0x7423 # 0 +0x8EA2BEAB 0x741D # 0 +0x8EA2BEAC 0x7429 # 0 +0x8EA2BEAD 0x7420 # 0 +0x8EA2BEAE 0x7432 # 0 +0x8EA2BEAF 0x74FB # 0 +0x8EA2BEB0 0x752F # 0 +0x8EA2BEB1 0x756F # 0 +0x8EA2BEB2 0x756C # 0 +0x8EA2BEB3 0x75E7 # 0 +0x8EA2BEB4 0x75DA # 0 +0x8EA2BEB5 0x75E1 # 0 +0x8EA2BEB6 0x75E6 # 0 +0x8EA2BEB7 0x75DD # 0 +0x8EA2BEB8 0x75DF # 0 +0x8EA2BEB9 0x75E4 # 0 +0x8EA2BEBA 0x75D7 # 0 +0x8EA2BEBB 0x7695 # 0 +0x8EA2BEBC 0x7692 # 0 +0x8EA2BEBD 0x76DA # 0 +0x8EA2BEBE 0x7746 # 0 +0x8EA2BEBF 0x7747 # 0 +0x8EA2BEC0 0x7744 # 0 +0x8EA2BEC1 0x774D # 0 +0x8EA2BEC2 0x7745 # 0 +0x8EA2BEC3 0x774A # 0 +0x8EA2BEC4 0x774E # 0 +0x8EA2BEC5 0x774B # 0 +0x8EA2BEC6 0x774C # 0 +0x8EA2BEC7 0x77DE # 0 +0x8EA2BEC8 0x77EC # 0 +0x8EA2BEC9 0x7860 # 0 +0x8EA2BECA 0x7864 # 0 +0x8EA2BECB 0x7865 # 0 +0x8EA2BECC 0x785C # 0 +0x8EA2BECD 0x786D # 0 +0x8EA2BECE 0x7871 # 0 +0x8EA2BECF 0x786A # 0 +0x8EA2BED0 0x786E # 0 +0x8EA2BED1 0x7870 # 0 +0x8EA2BED2 0x7869 # 0 +0x8EA2BED3 0x7868 # 0 +0x8EA2BED4 0x785E # 0 +0x8EA2BED5 0x7862 # 0 +0x8EA2BED6 0x7974 # 0 +0x8EA2BED7 0x7973 # 0 +0x8EA2BED8 0x7972 # 0 +0x8EA2BED9 0x7970 # 0 +0x8EA2BEDA 0x7A02 # 0 +0x8EA2BEDB 0x7A0A # 0 +0x8EA2BEDC 0x7A03 # 0 +0x8EA2BEDD 0x7A0C # 0 +0x8EA2BEDE 0x7A04 # 0 +0x8EA2BEDF 0x7A99 # 0 +0x8EA2BEE0 0x7AE6 # 0 +0x8EA2BEE1 0x7AE4 # 0 +0x8EA2BEE2 0x7B4A # 0 +0x8EA2BEE3 0x7B47 # 0 +0x8EA2BEE4 0x7B44 # 0 +0x8EA2BEE5 0x7B48 # 0 +0x8EA2BEE6 0x7B4C # 0 +0x8EA2BEE7 0x7B4E # 0 +0x8EA2BEE8 0x7B40 # 0 +0x8EA2BEE9 0x7B58 # 0 +0x8EA2BEEA 0x7B45 # 0 +0x8EA2BEEB 0x7CA2 # 0 +0x8EA2BEEC 0x7C9E # 0 +0x8EA2BEED 0x7CA8 # 0 +0x8EA2BEEE 0x7CA1 # 0 +0x8EA2BEEF 0x7D58 # 0 +0x8EA2BEF0 0x7D6F # 0 +0x8EA2BEF1 0x7D63 # 0 +0x8EA2BEF2 0x7D53 # 0 +0x8EA2BEF3 0x7D56 # 0 +0x8EA2BEF4 0x7D67 # 0 +0x8EA2BEF5 0x7D6A # 0 +0x8EA2BEF6 0x7D4F # 0 +0x8EA2BEF7 0x7D6D # 0 +0x8EA2BEF8 0x7D5C # 0 +0x8EA2BEF9 0x7D6B # 0 +0x8EA2BEFA 0x7D52 # 0 +0x8EA2BEFB 0x7D54 # 0 +0x8EA2BEFC 0x7D69 # 0 +0x8EA2BEFD 0x7D51 # 0 +0x8EA2BEFE 0x7D5F # 0 +0x8EA2BFA1 0x7D4E # 0 +0x8EA2BFA2 0x7F3E # 0 +0x8EA2BFA3 0x7F3F # 0 +0x8EA2BFA4 0x7F65 # 0 +0x8EA2BFA5 0x7F66 # 0 +0x8EA2BFA6 0x7FA2 # 0 +0x8EA2BFA7 0x7FA0 # 0 +0x8EA2BFA8 0x7FA1 # 0 +0x8EA2BFA9 0x7FD7 # 0 +0x8EA2BFAA 0x8051 # 0 +0x8EA2BFAB 0x804F # 0 +0x8EA2BFAC 0x8050 # 0 +0x8EA2BFAD 0x80FE # 0 +0x8EA2BFAE 0x80D4 # 0 +0x8EA2BFAF 0x8143 # 0 +0x8EA2BFB0 0x814A # 0 +0x8EA2BFB1 0x8152 # 0 +0x8EA2BFB2 0x814F # 0 +0x8EA2BFB3 0x8147 # 0 +0x8EA2BFB4 0x813D # 0 +0x8EA2BFB5 0x814D # 0 +0x8EA2BFB6 0x813A # 0 +0x8EA2BFB7 0x81E6 # 0 +0x8EA2BFB8 0x81EE # 0 +0x8EA2BFB9 0x81F7 # 0 +0x8EA2BFBA 0x81F8 # 0 +0x8EA2BFBB 0x81F9 # 0 +0x8EA2BFBC 0x8204 # 0 +0x8EA2BFBD 0x823C # 0 +0x8EA2BFBE 0x823D # 0 +0x8EA2BFBF 0x823F # 0 +0x8EA2BFC0 0x8275 # 0 +0x8EA2BFC1 0x833B # 0 +0x8EA2BFC2 0x83CF # 0 +0x8EA2BFC3 0x83F9 # 0 +0x8EA2BFC4 0x8423 # 0 +0x8EA2BFC5 0x83C0 # 0 +0x8EA2BFC6 0x83E8 # 0 +0x8EA2BFC7 0x8412 # 0 +0x8EA2BFC8 0x83E7 # 0 +0x8EA2BFC9 0x83E4 # 0 +0x8EA2BFCA 0x83FC # 0 +0x8EA2BFCB 0x83F6 # 0 +0x8EA2BFCC 0x8410 # 0 +0x8EA2BFCD 0x83C6 # 0 +0x8EA2BFCE 0x83C8 # 0 +0x8EA2BFCF 0x83EB # 0 +0x8EA2BFD0 0x83E3 # 0 +0x8EA2BFD1 0x83BF # 0 +0x8EA2BFD2 0x8401 # 0 +0x8EA2BFD3 0x83DD # 0 +0x8EA2BFD4 0x83E5 # 0 +0x8EA2BFD5 0x83D8 # 0 +0x8EA2BFD6 0x83FF # 0 +0x8EA2BFD7 0x83E1 # 0 +0x8EA2BFD8 0x83CB # 0 +0x8EA2BFD9 0x83CE # 0 +0x8EA2BFDA 0x83D6 # 0 +0x8EA2BFDB 0x83F5 # 0 +0x8EA2BFDC 0x83C9 # 0 +0x8EA2BFDD 0x8409 # 0 +0x8EA2BFDE 0x840F # 0 +0x8EA2BFDF 0x83DE # 0 +0x8EA2BFE0 0x8411 # 0 +0x8EA2BFE1 0x8406 # 0 +0x8EA2BFE2 0x83C2 # 0 +0x8EA2BFE3 0x83F3 # 0 +0x8EA2BFE4 0x83D5 # 0 +0x8EA2BFE5 0x83FA # 0 +0x8EA2BFE6 0x83C7 # 0 +0x8EA2BFE7 0x83D1 # 0 +0x8EA2BFE8 0x83EA # 0 +0x8EA2BFE9 0x8413 # 0 +0x8EA2BFEA 0x839A # 0 +0x8EA2BFEB 0x83C3 # 0 +0x8EA2BFEC 0x83EC # 0 +0x8EA2BFED 0x83EE # 0 +0x8EA2BFEE 0x83C4 # 0 +0x8EA2BFEF 0x83FB # 0 +0x8EA2BFF0 0x83D7 # 0 +0x8EA2BFF1 0x83E2 # 0 +0x8EA2BFF2 0x841B # 0 +0x8EA2BFF3 0x83DB # 0 +0x8EA2BFF4 0x83FE # 0 +0x8EA2BFF5 0x86D8 # 0 +0x8EA2BFF6 0x86E2 # 0 +0x8EA2BFF7 0x86E6 # 0 +0x8EA2BFF8 0x86D3 # 0 +0x8EA2BFF9 0x86E3 # 0 +0x8EA2BFFA 0x86DA # 0 +0x8EA2BFFB 0x86EA # 0 +0x8EA2BFFC 0x86DD # 0 +0x8EA2BFFD 0x86EB # 0 +0x8EA2BFFE 0x86DC # 0 +0x8EA2C0A1 0x86EC # 0 +0x8EA2C0A2 0x86E9 # 0 +0x8EA2C0A3 0x86D7 # 0 +0x8EA2C0A4 0x86E8 # 0 +0x8EA2C0A5 0x86D1 # 0 +0x8EA2C0A6 0x8848 # 0 +0x8EA2C0A7 0x8856 # 0 +0x8EA2C0A8 0x8855 # 0 +0x8EA2C0A9 0x88BA # 0 +0x8EA2C0AA 0x88D7 # 0 +0x8EA2C0AB 0x88B9 # 0 +0x8EA2C0AC 0x88B8 # 0 +0x8EA2C0AD 0x88C0 # 0 +0x8EA2C0AE 0x88BE # 0 +0x8EA2C0AF 0x88B6 # 0 +0x8EA2C0B0 0x88BC # 0 +0x8EA2C0B1 0x88B7 # 0 +0x8EA2C0B2 0x88BD # 0 +0x8EA2C0B3 0x88B2 # 0 +0x8EA2C0B4 0x8901 # 0 +0x8EA2C0B5 0x88C9 # 0 +0x8EA2C0B6 0x8995 # 0 +0x8EA2C0B7 0x8998 # 0 +0x8EA2C0B8 0x8997 # 0 +0x8EA2C0B9 0x89DD # 0 +0x8EA2C0BA 0x89DA # 0 +0x8EA2C0BB 0x89DB # 0 +0x8EA2C0BC 0x8A4E # 0 +0x8EA2C0BD 0x8A4D # 0 +0x8EA2C0BE 0x8A39 # 0 +0x8EA2C0BF 0x8A59 # 0 +0x8EA2C0C0 0x8A40 # 0 +0x8EA2C0C1 0x8A57 # 0 +0x8EA2C0C2 0x8A58 # 0 +0x8EA2C0C3 0x8A44 # 0 +0x8EA2C0C4 0x8A45 # 0 +0x8EA2C0C5 0x8A52 # 0 +0x8EA2C0C6 0x8A48 # 0 +0x8EA2C0C7 0x8A51 # 0 +0x8EA2C0C8 0x8A4A # 0 +0x8EA2C0C9 0x8A4C # 0 +0x8EA2C0CA 0x8A4F # 0 +0x8EA2C0CB 0x8C5F # 0 +0x8EA2C0CC 0x8C81 # 0 +0x8EA2C0CD 0x8C80 # 0 +0x8EA2C0CE 0x8CBA # 0 +0x8EA2C0CF 0x8CBE # 0 +0x8EA2C0D0 0x8CB0 # 0 +0x8EA2C0D1 0x8CB9 # 0 +0x8EA2C0D2 0x8CB5 # 0 +0x8EA2C0D3 0x8D84 # 0 +0x8EA2C0D4 0x8D80 # 0 +0x8EA2C0D5 0x8D89 # 0 +0x8EA2C0D6 0x8DD8 # 0 +0x8EA2C0D7 0x8DD3 # 0 +0x8EA2C0D8 0x8DCD # 0 +0x8EA2C0D9 0x8DC7 # 0 +0x8EA2C0DA 0x8DD6 # 0 +0x8EA2C0DB 0x8DDC # 0 +0x8EA2C0DC 0x8DCF # 0 +0x8EA2C0DD 0x8DD5 # 0 +0x8EA2C0DE 0x8DD9 # 0 +0x8EA2C0DF 0x8DC8 # 0 +0x8EA2C0E0 0x8DD7 # 0 +0x8EA2C0E1 0x8DC5 # 0 +0x8EA2C0E2 0x8EEF # 0 +0x8EA2C0E3 0x8EF7 # 0 +0x8EA2C0E4 0x8EFA # 0 +0x8EA2C0E5 0x8EF9 # 0 +0x8EA2C0E6 0x8EE6 # 0 +0x8EA2C0E7 0x8EEE # 0 +0x8EA2C0E8 0x8EE5 # 0 +0x8EA2C0E9 0x8EF5 # 0 +0x8EA2C0EA 0x8EE7 # 0 +0x8EA2C0EB 0x8EE8 # 0 +0x8EA2C0EC 0x8EF6 # 0 +0x8EA2C0ED 0x8EEB # 0 +0x8EA2C0EE 0x8EF1 # 0 +0x8EA2C0EF 0x8EEC # 0 +0x8EA2C0F0 0x8EF4 # 0 +0x8EA2C0F1 0x8EE9 # 0 +0x8EA2C0F2 0x902D # 0 +0x8EA2C0F3 0x9034 # 0 +0x8EA2C0F4 0x902F # 0 +0x8EA2C0F5 0x9106 # 0 +0x8EA2C0F6 0x912C # 0 +0x8EA2C0F7 0x9104 # 0 +0x8EA2C0F8 0x90FF # 0 +0x8EA2C0F9 0x90FC # 0 +0x8EA2C0FA 0x9108 # 0 +0x8EA2C0FB 0x90F9 # 0 +0x8EA2C0FC 0x90FB # 0 +0x8EA2C0FD 0x9101 # 0 +0x8EA2C0FE 0x9100 # 0 +0x8EA2C1A1 0x9107 # 0 +0x8EA2C1A2 0x9105 # 0 +0x8EA2C1A3 0x9103 # 0 +0x8EA2C1A4 0x9161 # 0 +0x8EA2C1A5 0x9164 # 0 +0x8EA2C1A6 0x915F # 0 +0x8EA2C1A7 0x9162 # 0 +0x8EA2C1A8 0x9160 # 0 +0x8EA2C1A9 0x9201 # 0 +0x8EA2C1AA 0x920A # 0 +0x8EA2C1AB 0x9225 # 0 +0x8EA2C1AC 0x9203 # 0 +0x8EA2C1AD 0x921A # 0 +0x8EA2C1AE 0x9226 # 0 +0x8EA2C1AF 0x920F # 0 +0x8EA2C1B0 0x920C # 0 +0x8EA2C1B1 0x9200 # 0 +0x8EA2C1B2 0x9212 # 0 +0x8EA2C1B3 0x91FF # 0 +0x8EA2C1B4 0x91FD # 0 +0x8EA2C1B5 0x9206 # 0 +0x8EA2C1B6 0x9204 # 0 +0x8EA2C1B7 0x9227 # 0 +0x8EA2C1B8 0x9202 # 0 +0x8EA2C1B9 0x921C # 0 +0x8EA2C1BA 0x9224 # 0 +0x8EA2C1BB 0x9219 # 0 +0x8EA2C1BC 0x9217 # 0 +0x8EA2C1BD 0x9205 # 0 +0x8EA2C1BE 0x9216 # 0 +0x8EA2C1BF 0x957B # 0 +0x8EA2C1C0 0x958D # 0 +0x8EA2C1C1 0x958C # 0 +0x8EA2C1C2 0x9590 # 0 +0x8EA2C1C3 0x9687 # 0 +0x8EA2C1C4 0x967E # 0 +0x8EA2C1C5 0x9688 # 0 +0x8EA2C1C6 0x9689 # 0 +0x8EA2C1C7 0x9683 # 0 +0x8EA2C1C8 0x9680 # 0 +0x8EA2C1C9 0x96C2 # 0 +0x8EA2C1CA 0x96C8 # 0 +0x8EA2C1CB 0x96C3 # 0 +0x8EA2C1CC 0x96F1 # 0 +0x8EA2C1CD 0x96F0 # 0 +0x8EA2C1CE 0x976C # 0 +0x8EA2C1CF 0x9770 # 0 +0x8EA2C1D0 0x976E # 0 +0x8EA2C1D1 0x9807 # 0 +0x8EA2C1D2 0x98A9 # 0 +0x8EA2C1D3 0x98EB # 0 +0x8EA2C1D4 0x9CE6 # 0 +0x8EA2C1D5 0x9EF9 # 0 +0x8EA2C1D6 0x4E83 # 0 +0x8EA2C1D7 0x4E84 # 0 +0x8EA2C1D8 0x4EB6 # 0 +0x8EA2C1D9 0x50BD # 0 +0x8EA2C1DA 0x50BF # 0 +0x8EA2C1DB 0x50C6 # 0 +0x8EA2C1DC 0x50AE # 0 +0x8EA2C1DD 0x50C4 # 0 +0x8EA2C1DE 0x50CA # 0 +0x8EA2C1DF 0x50B4 # 0 +0x8EA2C1E0 0x50C8 # 0 +0x8EA2C1E1 0x50C2 # 0 +0x8EA2C1E2 0x50B0 # 0 +0x8EA2C1E3 0x50C1 # 0 +0x8EA2C1E4 0x50BA # 0 +0x8EA2C1E5 0x50B1 # 0 +0x8EA2C1E6 0x50CB # 0 +0x8EA2C1E7 0x50C9 # 0 +0x8EA2C1E8 0x50B6 # 0 +0x8EA2C1E9 0x50B8 # 0 +0x8EA2C1EA 0x51D7 # 0 +0x8EA2C1EB 0x527A # 0 +0x8EA2C1EC 0x5278 # 0 +0x8EA2C1ED 0x527B # 0 +0x8EA2C1EE 0x527C # 0 +0x8EA2C1EF 0x55C3 # 0 +0x8EA2C1F0 0x55DB # 0 +0x8EA2C1F1 0x55CC # 0 +0x8EA2C1F2 0x55D0 # 0 +0x8EA2C1F3 0x55CB # 0 +0x8EA2C1F4 0x55CA # 0 +0x8EA2C1F5 0x55DD # 0 +0x8EA2C1F6 0x55C0 # 0 +0x8EA2C1F7 0x55D4 # 0 +0x8EA2C1F8 0x55C4 # 0 +0x8EA2C1F9 0x55E9 # 0 +0x8EA2C1FA 0x55BF # 0 +0x8EA2C1FB 0x55D2 # 0 +0x8EA2C1FC 0x558D # 0 +0x8EA2C1FD 0x55CF # 0 +0x8EA2C1FE 0x55D5 # 0 +0x8EA2C2A1 0x55E2 # 0 +0x8EA2C2A2 0x55D6 # 0 +0x8EA2C2A3 0x55C8 # 0 +0x8EA2C2A4 0x55F2 # 0 +0x8EA2C2A5 0x55CD # 0 +0x8EA2C2A6 0x55D9 # 0 +0x8EA2C2A7 0x55C2 # 0 +0x8EA2C2A8 0x5714 # 0 +0x8EA2C2A9 0x5853 # 0 +0x8EA2C2AA 0x5868 # 0 +0x8EA2C2AB 0x5864 # 0 +0x8EA2C2AC 0x584F # 0 +0x8EA2C2AD 0x584D # 0 +0x8EA2C2AE 0x5849 # 0 +0x8EA2C2AF 0x586F # 0 +0x8EA2C2B0 0x5855 # 0 +0x8EA2C2B1 0x584E # 0 +0x8EA2C2B2 0x585D # 0 +0x8EA2C2B3 0x5859 # 0 +0x8EA2C2B4 0x5865 # 0 +0x8EA2C2B5 0x585B # 0 +0x8EA2C2B6 0x583D # 0 +0x8EA2C2B7 0x5863 # 0 +0x8EA2C2B8 0x5871 # 0 +0x8EA2C2B9 0x58FC # 0 +0x8EA2C2BA 0x5AC7 # 0 +0x8EA2C2BB 0x5AC4 # 0 +0x8EA2C2BC 0x5ACB # 0 +0x8EA2C2BD 0x5ABA # 0 +0x8EA2C2BE 0x5AB8 # 0 +0x8EA2C2BF 0x5AB1 # 0 +0x8EA2C2C0 0x5AB5 # 0 +0x8EA2C2C1 0x5AB0 # 0 +0x8EA2C2C2 0x5ABF # 0 +0x8EA2C2C3 0x5AC8 # 0 +0x8EA2C2C4 0x5ABB # 0 +0x8EA2C2C5 0x5AC6 # 0 +0x8EA2C2C6 0x5AB7 # 0 +0x8EA2C2C7 0x5AC0 # 0 +0x8EA2C2C8 0x5ACA # 0 +0x8EA2C2C9 0x5AB4 # 0 +0x8EA2C2CA 0x5AB6 # 0 +0x8EA2C2CB 0x5ACD # 0 +0x8EA2C2CC 0x5AB9 # 0 +0x8EA2C2CD 0x5A90 # 0 +0x8EA2C2CE 0x5BD6 # 0 +0x8EA2C2CF 0x5BD8 # 0 +0x8EA2C2D0 0x5BD9 # 0 +0x8EA2C2D1 0x5C1F # 0 +0x8EA2C2D2 0x5C33 # 0 +0x8EA2C2D3 0x5D71 # 0 +0x8EA2C2D4 0x5D63 # 0 +0x8EA2C2D5 0x5D4A # 0 +0x8EA2C2D6 0x5D65 # 0 +0x8EA2C2D7 0x5D72 # 0 +0x8EA2C2D8 0x5D6C # 0 +0x8EA2C2D9 0x5D5E # 0 +0x8EA2C2DA 0x5D68 # 0 +0x8EA2C2DB 0x5D67 # 0 +0x8EA2C2DC 0x5D62 # 0 +0x8EA2C2DD 0x5DF0 # 0 +0x8EA2C2DE 0x5E4F # 0 +0x8EA2C2DF 0x5E4E # 0 +0x8EA2C2E0 0x5E4A # 0 +0x8EA2C2E1 0x5E4D # 0 +0x8EA2C2E2 0x5E4B # 0 +0x8EA2C2E3 0x5EC5 # 0 +0x8EA2C2E4 0x5ECC # 0 +0x8EA2C2E5 0x5EC6 # 0 +0x8EA2C2E6 0x5ECB # 0 +0x8EA2C2E7 0x5EC7 # 0 +0x8EA2C2E8 0x5F40 # 0 +0x8EA2C2E9 0x5FAF # 0 +0x8EA2C2EA 0x5FAD # 0 +0x8EA2C2EB 0x60F7 # 0 +0x8EA2C2EC 0x6149 # 0 +0x8EA2C2ED 0x614A # 0 +0x8EA2C2EE 0x612B # 0 +0x8EA2C2EF 0x6145 # 0 +0x8EA2C2F0 0x6136 # 0 +0x8EA2C2F1 0x6132 # 0 +0x8EA2C2F2 0x612E # 0 +0x8EA2C2F3 0x6146 # 0 +0x8EA2C2F4 0x612F # 0 +0x8EA2C2F5 0x614F # 0 +0x8EA2C2F6 0x6129 # 0 +0x8EA2C2F7 0x6140 # 0 +0x8EA2C2F8 0x6220 # 0 +0x8EA2C2F9 0x9168 # 0 +0x8EA2C2FA 0x6223 # 0 +0x8EA2C2FB 0x6225 # 0 +0x8EA2C2FC 0x6224 # 0 +0x8EA2C2FD 0x63C5 # 0 +0x8EA2C2FE 0x63F1 # 0 +0x8EA2C3A1 0x63EB # 0 +0x8EA2C3A2 0x6410 # 0 +0x8EA2C3A3 0x6412 # 0 +0x8EA2C3A4 0x6409 # 0 +0x8EA2C3A5 0x6420 # 0 +0x8EA2C3A6 0x6424 # 0 +0x8EA2C3A7 0x6433 # 0 +0x8EA2C3A8 0x6443 # 0 +0x8EA2C3A9 0x641F # 0 +0x8EA2C3AA 0x6415 # 0 +0x8EA2C3AB 0x6418 # 0 +0x8EA2C3AC 0x6439 # 0 +0x8EA2C3AD 0x6437 # 0 +0x8EA2C3AE 0x6422 # 0 +0x8EA2C3AF 0x6423 # 0 +0x8EA2C3B0 0x640C # 0 +0x8EA2C3B1 0x6426 # 0 +0x8EA2C3B2 0x6430 # 0 +0x8EA2C3B3 0x6428 # 0 +0x8EA2C3B4 0x6441 # 0 +0x8EA2C3B5 0x6435 # 0 +0x8EA2C3B6 0x642F # 0 +0x8EA2C3B7 0x640A # 0 +0x8EA2C3B8 0x641A # 0 +0x8EA2C3B9 0x6440 # 0 +0x8EA2C3BA 0x6425 # 0 +0x8EA2C3BB 0x6427 # 0 +0x8EA2C3BC 0x640B # 0 +0x8EA2C3BD 0x63E7 # 0 +0x8EA2C3BE 0x641B # 0 +0x8EA2C3BF 0x642E # 0 +0x8EA2C3C0 0x6421 # 0 +0x8EA2C3C1 0x640E # 0 +0x8EA2C3C2 0x656F # 0 +0x8EA2C3C3 0x6592 # 0 +0x8EA2C3C4 0x65D3 # 0 +0x8EA2C3C5 0x6686 # 0 +0x8EA2C3C6 0x668C # 0 +0x8EA2C3C7 0x6695 # 0 +0x8EA2C3C8 0x6690 # 0 +0x8EA2C3C9 0x668B # 0 +0x8EA2C3CA 0x668A # 0 +0x8EA2C3CB 0x6699 # 0 +0x8EA2C3CC 0x6694 # 0 +0x8EA2C3CD 0x6678 # 0 +0x8EA2C3CE 0x6720 # 0 +0x8EA2C3CF 0x6966 # 0 +0x8EA2C3D0 0x695F # 0 +0x8EA2C3D1 0x6938 # 0 +0x8EA2C3D2 0x694E # 0 +0x8EA2C3D3 0x6962 # 0 +0x8EA2C3D4 0x6971 # 0 +0x8EA2C3D5 0x693F # 0 +0x8EA2C3D6 0x6945 # 0 +0x8EA2C3D7 0x696A # 0 +0x8EA2C3D8 0x6939 # 0 +0x8EA2C3D9 0x6942 # 0 +0x8EA2C3DA 0x6957 # 0 +0x8EA2C3DB 0x6959 # 0 +0x8EA2C3DC 0x697A # 0 +0x8EA2C3DD 0x6948 # 0 +0x8EA2C3DE 0x6949 # 0 +0x8EA2C3DF 0x6935 # 0 +0x8EA2C3E0 0x696C # 0 +0x8EA2C3E1 0x6933 # 0 +0x8EA2C3E2 0x693D # 0 +0x8EA2C3E3 0x6965 # 0 +0x8EA2C3E4 0x68F0 # 0 +0x8EA2C3E5 0x6978 # 0 +0x8EA2C3E6 0x6934 # 0 +0x8EA2C3E7 0x6969 # 0 +0x8EA2C3E8 0x6940 # 0 +0x8EA2C3E9 0x696F # 0 +0x8EA2C3EA 0x6944 # 0 +0x8EA2C3EB 0x6976 # 0 +0x8EA2C3EC 0x6958 # 0 +0x8EA2C3ED 0x6941 # 0 +0x8EA2C3EE 0x6974 # 0 +0x8EA2C3EF 0x694C # 0 +0x8EA2C3F0 0x693B # 0 +0x8EA2C3F1 0x694B # 0 +0x8EA2C3F2 0x6937 # 0 +0x8EA2C3F3 0x695C # 0 +0x8EA2C3F4 0x694F # 0 +0x8EA2C3F5 0x6951 # 0 +0x8EA2C3F6 0x6932 # 0 +0x8EA2C3F7 0x6952 # 0 +0x8EA2C3F8 0x692F # 0 +0x8EA2C3F9 0x697B # 0 +0x8EA2C3FA 0x693C # 0 +0x8EA2C3FB 0x6B46 # 0 +0x8EA2C3FC 0x6B45 # 0 +0x8EA2C3FD 0x6B43 # 0 +0x8EA2C3FE 0x6B42 # 0 +0x8EA2C4A1 0x6B48 # 0 +0x8EA2C4A2 0x6B41 # 0 +0x8EA2C4A3 0x6B9B # 0 +0x8EA2C4A4 0x6BFB # 0 +0x8EA2C4A5 0x6BFC # 0 +0x8EA2C4A6 0x6BF9 # 0 +0x8EA2C4A7 0x6BF7 # 0 +0x8EA2C4A8 0x6BF8 # 0 +0x8EA2C4A9 0x6E9B # 0 +0x8EA2C4AA 0x6ED6 # 0 +0x8EA2C4AB 0x6EC8 # 0 +0x8EA2C4AC 0x6E8F # 0 +0x8EA2C4AD 0x6EC0 # 0 +0x8EA2C4AE 0x6E9F # 0 +0x8EA2C4AF 0x6E93 # 0 +0x8EA2C4B0 0x6E94 # 0 +0x8EA2C4B1 0x6EA0 # 0 +0x8EA2C4B2 0x6EB1 # 0 +0x8EA2C4B3 0x6EB9 # 0 +0x8EA2C4B4 0x6EC6 # 0 +0x8EA2C4B5 0x6ED2 # 0 +0x8EA2C4B6 0x6EBD # 0 +0x8EA2C4B7 0x6EC1 # 0 +0x8EA2C4B8 0x6E9E # 0 +0x8EA2C4B9 0x6EC9 # 0 +0x8EA2C4BA 0x6EB7 # 0 +0x8EA2C4BB 0x6EB0 # 0 +0x8EA2C4BC 0x6ECD # 0 +0x8EA2C4BD 0x6EA6 # 0 +0x8EA2C4BE 0x6ECF # 0 +0x8EA2C4BF 0x6EB2 # 0 +0x8EA2C4C0 0x6EBE # 0 +0x8EA2C4C1 0x6EC3 # 0 +0x8EA2C4C2 0x6EDC # 0 +0x8EA2C4C3 0x6ED8 # 0 +0x8EA2C4C4 0x6E99 # 0 +0x8EA2C4C5 0x6E92 # 0 +0x8EA2C4C6 0x6E8E # 0 +0x8EA2C4C7 0x6E8D # 0 +0x8EA2C4C8 0x6EA4 # 0 +0x8EA2C4C9 0x6EA1 # 0 +0x8EA2C4CA 0x6EBF # 0 +0x8EA2C4CB 0x6EB3 # 0 +0x8EA2C4CC 0x6ED0 # 0 +0x8EA2C4CD 0x6ECA # 0 +0x8EA2C4CE 0x6E97 # 0 +0x8EA2C4CF 0x6EAE # 0 +0x8EA2C4D0 0x6EA3 # 0 +0x8EA2C4D1 0x7147 # 0 +0x8EA2C4D2 0x7154 # 0 +0x8EA2C4D3 0x7152 # 0 +0x8EA2C4D4 0x7163 # 0 +0x8EA2C4D5 0x7160 # 0 +0x8EA2C4D6 0x7141 # 0 +0x8EA2C4D7 0x715D # 0 +0x8EA2C4D8 0x7162 # 0 +0x8EA2C4D9 0x7172 # 0 +0x8EA2C4DA 0x7178 # 0 +0x8EA2C4DB 0x716A # 0 +0x8EA2C4DC 0x7161 # 0 +0x8EA2C4DD 0x7142 # 0 +0x8EA2C4DE 0x7158 # 0 +0x8EA2C4DF 0x7143 # 0 +0x8EA2C4E0 0x714B # 0 +0x8EA2C4E1 0x7170 # 0 +0x8EA2C4E2 0x715F # 0 +0x8EA2C4E3 0x7150 # 0 +0x8EA2C4E4 0x7153 # 0 +0x8EA2C4E5 0x7144 # 0 +0x8EA2C4E6 0x714D # 0 +0x8EA2C4E7 0x715A # 0 +0x8EA2C4E8 0x724F # 0 +0x8EA2C4E9 0x728D # 0 +0x8EA2C4EA 0x728C # 0 +0x8EA2C4EB 0x7291 # 0 +0x8EA2C4EC 0x7290 # 0 +0x8EA2C4ED 0x728E # 0 +0x8EA2C4EE 0x733C # 0 +0x8EA2C4EF 0x7342 # 0 +0x8EA2C4F0 0x733B # 0 +0x8EA2C4F1 0x733A # 0 +0x8EA2C4F2 0x7340 # 0 +0x8EA2C4F3 0x734A # 0 +0x8EA2C4F4 0x7349 # 0 +0x8EA2C4F5 0x7444 # 0 +0x8EA2C4F6 0x744A # 0 +0x8EA2C4F7 0x744B # 0 +0x8EA2C4F8 0x7452 # 0 +0x8EA2C4F9 0x7451 # 0 +0x8EA2C4FA 0x7457 # 0 +0x8EA2C4FB 0x7440 # 0 +0x8EA2C4FC 0x744F # 0 +0x8EA2C4FD 0x7450 # 0 +0x8EA2C4FE 0x744E # 0 +0x8EA2C5A1 0x7442 # 0 +0x8EA2C5A2 0x7446 # 0 +0x8EA2C5A3 0x744D # 0 +0x8EA2C5A4 0x7454 # 0 +0x8EA2C5A5 0x74E1 # 0 +0x8EA2C5A6 0x74FF # 0 +0x8EA2C5A7 0x74FE # 0 +0x8EA2C5A8 0x74FD # 0 +0x8EA2C5A9 0x751D # 0 +0x8EA2C5AA 0x7579 # 0 +0x8EA2C5AB 0x7577 # 0 +0x8EA2C5AC 0x6983 # 0 +0x8EA2C5AD 0x75EF # 0 +0x8EA2C5AE 0x760F # 0 +0x8EA2C5AF 0x7603 # 0 +0x8EA2C5B0 0x75F7 # 0 +0x8EA2C5B1 0x75FE # 0 +0x8EA2C5B2 0x75FC # 0 +0x8EA2C5B3 0x75F9 # 0 +0x8EA2C5B4 0x75F8 # 0 +0x8EA2C5B5 0x7610 # 0 +0x8EA2C5B6 0x75FB # 0 +0x8EA2C5B7 0x75F6 # 0 +0x8EA2C5B8 0x75ED # 0 +0x8EA2C5B9 0x75F5 # 0 +0x8EA2C5BA 0x75FD # 0 +0x8EA2C5BB 0x7699 # 0 +0x8EA2C5BC 0x76B5 # 0 +0x8EA2C5BD 0x76DD # 0 +0x8EA2C5BE 0x7755 # 0 +0x8EA2C5BF 0x775F # 0 +0x8EA2C5C0 0x7760 # 0 +0x8EA2C5C1 0x7752 # 0 +0x8EA2C5C2 0x7756 # 0 +0x8EA2C5C3 0x775A # 0 +0x8EA2C5C4 0x7769 # 0 +0x8EA2C5C5 0x7767 # 0 +0x8EA2C5C6 0x7754 # 0 +0x8EA2C5C7 0x7759 # 0 +0x8EA2C5C8 0x776D # 0 +0x8EA2C5C9 0x77E0 # 0 +0x8EA2C5CA 0x7887 # 0 +0x8EA2C5CB 0x789A # 0 +0x8EA2C5CC 0x7894 # 0 +0x8EA2C5CD 0x788F # 0 +0x8EA2C5CE 0x7884 # 0 +0x8EA2C5CF 0x7895 # 0 +0x8EA2C5D0 0x7885 # 0 +0x8EA2C5D1 0x7886 # 0 +0x8EA2C5D2 0x78A1 # 0 +0x8EA2C5D3 0x7883 # 0 +0x8EA2C5D4 0x7879 # 0 +0x8EA2C5D5 0x7899 # 0 +0x8EA2C5D6 0x7880 # 0 +0x8EA2C5D7 0x7896 # 0 +0x8EA2C5D8 0x787B # 0 +0x8EA2C5D9 0x797C # 0 +0x8EA2C5DA 0x7982 # 0 +0x8EA2C5DB 0x797D # 0 +0x8EA2C5DC 0x7979 # 0 +0x8EA2C5DD 0x7A11 # 0 +0x8EA2C5DE 0x7A18 # 0 +0x8EA2C5DF 0x7A19 # 0 +0x8EA2C5E0 0x7A12 # 0 +0x8EA2C5E1 0x7A17 # 0 +0x8EA2C5E2 0x7A15 # 0 +0x8EA2C5E3 0x7A22 # 0 +0x8EA2C5E4 0x7A13 # 0 +0x8EA2C5E5 0x7A1B # 0 +0x8EA2C5E6 0x7A10 # 0 +0x8EA2C5E7 0x7AA3 # 0 +0x8EA2C5E8 0x7AA2 # 0 +0x8EA2C5E9 0x7A9E # 0 +0x8EA2C5EA 0x7AEB # 0 +0x8EA2C5EB 0x7B66 # 0 +0x8EA2C5EC 0x7B64 # 0 +0x8EA2C5ED 0x7B6D # 0 +0x8EA2C5EE 0x7B74 # 0 +0x8EA2C5EF 0x7B69 # 0 +0x8EA2C5F0 0x7B72 # 0 +0x8EA2C5F1 0x7B65 # 0 +0x8EA2C5F2 0x7B73 # 0 +0x8EA2C5F3 0x7B71 # 0 +0x8EA2C5F4 0x7B70 # 0 +0x8EA2C5F5 0x7B61 # 0 +0x8EA2C5F6 0x7B78 # 0 +0x8EA2C5F7 0x7B76 # 0 +0x8EA2C5F8 0x7B63 # 0 +0x8EA2C5F9 0x7CB2 # 0 +0x8EA2C5FA 0x7CB4 # 0 +0x8EA2C5FB 0x7CAF # 0 +0x8EA2C5FC 0x7D88 # 0 +0x8EA2C5FD 0x7D86 # 0 +0x8EA2C5FE 0x7D80 # 0 +0x8EA2C6A1 0x7D8D # 0 +0x8EA2C6A2 0x7D7F # 0 +0x8EA2C6A3 0x7D85 # 0 +0x8EA2C6A4 0x7D7A # 0 +0x8EA2C6A5 0x7D8E # 0 +0x8EA2C6A6 0x7D7B # 0 +0x8EA2C6A7 0x7D83 # 0 +0x8EA2C6A8 0x7D7C # 0 +0x8EA2C6A9 0x7D8C # 0 +0x8EA2C6AA 0x7D94 # 0 +0x8EA2C6AB 0x7D84 # 0 +0x8EA2C6AC 0x7D7D # 0 +0x8EA2C6AD 0x7D92 # 0 +0x8EA2C6AE 0x7F6D # 0 +0x8EA2C6AF 0x7F6B # 0 +0x8EA2C6B0 0x7F67 # 0 +0x8EA2C6B1 0x7F68 # 0 +0x8EA2C6B2 0x7F6C # 0 +0x8EA2C6B3 0x7FA6 # 0 +0x8EA2C6B4 0x7FA5 # 0 +0x8EA2C6B5 0x7FA7 # 0 +0x8EA2C6B6 0x7FDB # 0 +0x8EA2C6B7 0x7FDC # 0 +0x8EA2C6B8 0x8021 # 0 +0x8EA2C6B9 0x8164 # 0 +0x8EA2C6BA 0x8160 # 0 +0x8EA2C6BB 0x8177 # 0 +0x8EA2C6BC 0x815C # 0 +0x8EA2C6BD 0x8169 # 0 +0x8EA2C6BE 0x815B # 0 +0x8EA2C6BF 0x8162 # 0 +0x8EA2C6C0 0x8172 # 0 +0x8EA2C6C1 0x6721 # 0 +0x8EA2C6C2 0x815E # 0 +0x8EA2C6C3 0x8176 # 0 +0x8EA2C6C4 0x8167 # 0 +0x8EA2C6C5 0x816F # 0 +0x8EA2C6C6 0x8144 # 0 +0x8EA2C6C7 0x8161 # 0 +0x8EA2C6C8 0x821D # 0 +0x8EA2C6C9 0x8249 # 0 +0x8EA2C6CA 0x8244 # 0 +0x8EA2C6CB 0x8240 # 0 +0x8EA2C6CC 0x8242 # 0 +0x8EA2C6CD 0x8245 # 0 +0x8EA2C6CE 0x84F1 # 0 +0x8EA2C6CF 0x843F # 0 +0x8EA2C6D0 0x8456 # 0 +0x8EA2C6D1 0x8476 # 0 +0x8EA2C6D2 0x8479 # 0 +0x8EA2C6D3 0x848F # 0 +0x8EA2C6D4 0x848D # 0 +0x8EA2C6D5 0x8465 # 0 +0x8EA2C6D6 0x8451 # 0 +0x8EA2C6D7 0x8440 # 0 +0x8EA2C6D8 0x8486 # 0 +0x8EA2C6D9 0x8467 # 0 +0x8EA2C6DA 0x8430 # 0 +0x8EA2C6DB 0x844D # 0 +0x8EA2C6DC 0x847D # 0 +0x8EA2C6DD 0x845A # 0 +0x8EA2C6DE 0x8459 # 0 +0x8EA2C6DF 0x8474 # 0 +0x8EA2C6E0 0x8473 # 0 +0x8EA2C6E1 0x845D # 0 +0x8EA2C6E2 0x8507 # 0 +0x8EA2C6E3 0x845E # 0 +0x8EA2C6E4 0x8437 # 0 +0x8EA2C6E5 0x843A # 0 +0x8EA2C6E6 0x8434 # 0 +0x8EA2C6E7 0x847A # 0 +0x8EA2C6E8 0x8443 # 0 +0x8EA2C6E9 0x8478 # 0 +0x8EA2C6EA 0x8432 # 0 +0x8EA2C6EB 0x8445 # 0 +0x8EA2C6EC 0x8429 # 0 +0x8EA2C6ED 0x83D9 # 0 +0x8EA2C6EE 0x844B # 0 +0x8EA2C6EF 0x842F # 0 +0x8EA2C6F0 0x8442 # 0 +0x8EA2C6F1 0x842D # 0 +0x8EA2C6F2 0x845F # 0 +0x8EA2C6F3 0x8470 # 0 +0x8EA2C6F4 0x8439 # 0 +0x8EA2C6F5 0x844E # 0 +0x8EA2C6F6 0x844C # 0 +0x8EA2C6F7 0x8452 # 0 +0x8EA2C6F8 0x846F # 0 +0x8EA2C6F9 0x84C5 # 0 +0x8EA2C6FA 0x848E # 0 +0x8EA2C6FB 0x843B # 0 +0x8EA2C6FC 0x8447 # 0 +0x8EA2C6FD 0x8436 # 0 +0x8EA2C6FE 0x8433 # 0 +0x8EA2C7A1 0x8468 # 0 +0x8EA2C7A2 0x847E # 0 +0x8EA2C7A3 0x8444 # 0 +0x8EA2C7A4 0x842B # 0 +0x8EA2C7A5 0x8460 # 0 +0x8EA2C7A6 0x8454 # 0 +0x8EA2C7A7 0x846E # 0 +0x8EA2C7A8 0x8450 # 0 +0x8EA2C7A9 0x870B # 0 +0x8EA2C7AA 0x8704 # 0 +0x8EA2C7AB 0x86F7 # 0 +0x8EA2C7AC 0x870C # 0 +0x8EA2C7AD 0x86FA # 0 +0x8EA2C7AE 0x86D6 # 0 +0x8EA2C7AF 0x86F5 # 0 +0x8EA2C7B0 0x874D # 0 +0x8EA2C7B1 0x86F8 # 0 +0x8EA2C7B2 0x870E # 0 +0x8EA2C7B3 0x8709 # 0 +0x8EA2C7B4 0x8701 # 0 +0x8EA2C7B5 0x86F6 # 0 +0x8EA2C7B6 0x870D # 0 +0x8EA2C7B7 0x8705 # 0 +0x8EA2C7B8 0x88D6 # 0 +0x8EA2C7B9 0x88CB # 0 +0x8EA2C7BA 0x88CD # 0 +0x8EA2C7BB 0x88CE # 0 +0x8EA2C7BC 0x88DE # 0 +0x8EA2C7BD 0x88DB # 0 +0x8EA2C7BE 0x88DA # 0 +0x8EA2C7BF 0x88CC # 0 +0x8EA2C7C0 0x88D0 # 0 +0x8EA2C7C1 0x8985 # 0 +0x8EA2C7C2 0x899B # 0 +0x8EA2C7C3 0x89DF # 0 +0x8EA2C7C4 0x89E5 # 0 +0x8EA2C7C5 0x89E4 # 0 +0x8EA2C7C6 0x89E1 # 0 +0x8EA2C7C7 0x89E0 # 0 +0x8EA2C7C8 0x89E2 # 0 +0x8EA2C7C9 0x89DC # 0 +0x8EA2C7CA 0x89E6 # 0 +0x8EA2C7CB 0x8A76 # 0 +0x8EA2C7CC 0x8A86 # 0 +0x8EA2C7CD 0x8A7F # 0 +0x8EA2C7CE 0x8A61 # 0 +0x8EA2C7CF 0x8A3F # 0 +0x8EA2C7D0 0x8A77 # 0 +0x8EA2C7D1 0x8A82 # 0 +0x8EA2C7D2 0x8A84 # 0 +0x8EA2C7D3 0x8A75 # 0 +0x8EA2C7D4 0x8A83 # 0 +0x8EA2C7D5 0x8A81 # 0 +0x8EA2C7D6 0x8A74 # 0 +0x8EA2C7D7 0x8A7A # 0 +0x8EA2C7D8 0x8C3C # 0 +0x8EA2C7D9 0x8C4B # 0 +0x8EA2C7DA 0x8C4A # 0 +0x8EA2C7DB 0x8C65 # 0 +0x8EA2C7DC 0x8C64 # 0 +0x8EA2C7DD 0x8C66 # 0 +0x8EA2C7DE 0x8C86 # 0 +0x8EA2C7DF 0x8C84 # 0 +0x8EA2C7E0 0x8C85 # 0 +0x8EA2C7E1 0x8CCC # 0 +0x8EA2C7E2 0x8D68 # 0 +0x8EA2C7E3 0x8D69 # 0 +0x8EA2C7E4 0x8D91 # 0 +0x8EA2C7E5 0x8D8C # 0 +0x8EA2C7E6 0x8D8E # 0 +0x8EA2C7E7 0x8D8F # 0 +0x8EA2C7E8 0x8D8D # 0 +0x8EA2C7E9 0x8D93 # 0 +0x8EA2C7EA 0x8D94 # 0 +0x8EA2C7EB 0x8D90 # 0 +0x8EA2C7EC 0x8D92 # 0 +0x8EA2C7ED 0x8DF0 # 0 +0x8EA2C7EE 0x8DE0 # 0 +0x8EA2C7EF 0x8DEC # 0 +0x8EA2C7F0 0x8DF1 # 0 +0x8EA2C7F1 0x8DEE # 0 +0x8EA2C7F2 0x8DD0 # 0 +0x8EA2C7F3 0x8DE9 # 0 +0x8EA2C7F4 0x8DE3 # 0 +0x8EA2C7F5 0x8DE2 # 0 +0x8EA2C7F6 0x8DE7 # 0 +0x8EA2C7F7 0x8DF2 # 0 +0x8EA2C7F8 0x8DEB # 0 +0x8EA2C7F9 0x8DF4 # 0 +0x8EA2C7FA 0x8F06 # 0 +0x8EA2C7FB 0x8EFF # 0 +0x8EA2C7FC 0x8F01 # 0 +0x8EA2C7FD 0x8F00 # 0 +0x8EA2C7FE 0x8F05 # 0 +0x8EA2C8A1 0x8F07 # 0 +0x8EA2C8A2 0x8F08 # 0 +0x8EA2C8A3 0x8F02 # 0 +0x8EA2C8A4 0x8F0B # 0 +0x8EA2C8A5 0x9052 # 0 +0x8EA2C8A6 0x903F # 0 +0x8EA2C8A7 0x9044 # 0 +0x8EA2C8A8 0x9049 # 0 +0x8EA2C8A9 0x903D # 0 +0x8EA2C8AA 0x9110 # 0 +0x8EA2C8AB 0x910D # 0 +0x8EA2C8AC 0x910F # 0 +0x8EA2C8AD 0x9111 # 0 +0x8EA2C8AE 0x9116 # 0 +0x8EA2C8AF 0x9114 # 0 +0x8EA2C8B0 0x910B # 0 +0x8EA2C8B1 0x910E # 0 +0x8EA2C8B2 0x916E # 0 +0x8EA2C8B3 0x916F # 0 +0x8EA2C8B4 0x9248 # 0 +0x8EA2C8B5 0x9252 # 0 +0x8EA2C8B6 0x9230 # 0 +0x8EA2C8B7 0x923A # 0 +0x8EA2C8B8 0x9266 # 0 +0x8EA2C8B9 0x9233 # 0 +0x8EA2C8BA 0x9265 # 0 +0x8EA2C8BB 0x925E # 0 +0x8EA2C8BC 0x9283 # 0 +0x8EA2C8BD 0x922E # 0 +0x8EA2C8BE 0x924A # 0 +0x8EA2C8BF 0x9246 # 0 +0x8EA2C8C0 0x926D # 0 +0x8EA2C8C1 0x926C # 0 +0x8EA2C8C2 0x924F # 0 +0x8EA2C8C3 0x9260 # 0 +0x8EA2C8C4 0x9267 # 0 +0x8EA2C8C5 0x926F # 0 +0x8EA2C8C6 0x9236 # 0 +0x8EA2C8C7 0x9261 # 0 +0x8EA2C8C8 0x9270 # 0 +0x8EA2C8C9 0x9231 # 0 +0x8EA2C8CA 0x9254 # 0 +0x8EA2C8CB 0x9263 # 0 +0x8EA2C8CC 0x9250 # 0 +0x8EA2C8CD 0x9272 # 0 +0x8EA2C8CE 0x924E # 0 +0x8EA2C8CF 0x9253 # 0 +0x8EA2C8D0 0x924C # 0 +0x8EA2C8D1 0x9256 # 0 +0x8EA2C8D2 0x9232 # 0 +0x8EA2C8D3 0x959F # 0 +0x8EA2C8D4 0x959C # 0 +0x8EA2C8D5 0x959E # 0 +0x8EA2C8D6 0x959B # 0 +0x8EA2C8D7 0x9692 # 0 +0x8EA2C8D8 0x9693 # 0 +0x8EA2C8D9 0x9691 # 0 +0x8EA2C8DA 0x9697 # 0 +0x8EA2C8DB 0x96CE # 0 +0x8EA2C8DC 0x96FA # 0 +0x8EA2C8DD 0x96FD # 0 +0x8EA2C8DE 0x96F8 # 0 +0x8EA2C8DF 0x96F5 # 0 +0x8EA2C8E0 0x9773 # 0 +0x8EA2C8E1 0x9777 # 0 +0x8EA2C8E2 0x9778 # 0 +0x8EA2C8E3 0x9772 # 0 +0x8EA2C8E4 0x980F # 0 +0x8EA2C8E5 0x980D # 0 +0x8EA2C8E6 0x980E # 0 +0x8EA2C8E7 0x98AC # 0 +0x8EA2C8E8 0x98F6 # 0 +0x8EA2C8E9 0x98F9 # 0 +0x8EA2C8EA 0x99AF # 0 +0x8EA2C8EB 0x99B2 # 0 +0x8EA2C8EC 0x99B0 # 0 +0x8EA2C8ED 0x99B5 # 0 +0x8EA2C8EE 0x9AAD # 0 +0x8EA2C8EF 0x9AAB # 0 +0x8EA2C8F0 0x9B5B # 0 +0x8EA2C8F1 0x9CEA # 0 +0x8EA2C8F2 0x9CED # 0 +0x8EA2C8F3 0x9CE7 # 0 +0x8EA2C8F4 0x9E80 # 0 +0x8EA2C8F5 0x9EFD # 0 +0x8EA2C8F6 0x50E6 # 0 +0x8EA2C8F7 0x50D4 # 0 +0x8EA2C8F8 0x50D7 # 0 +0x8EA2C8F9 0x50E8 # 0 +0x8EA2C8FA 0x50F3 # 0 +0x8EA2C8FB 0x50DB # 0 +0x8EA2C8FC 0x50EA # 0 +0x8EA2C8FD 0x50DD # 0 +0x8EA2C8FE 0x50E4 # 0 +0x8EA2C9A1 0x50D3 # 0 +0x8EA2C9A2 0x50EC # 0 +0x8EA2C9A3 0x50F0 # 0 +0x8EA2C9A4 0x50EF # 0 +0x8EA2C9A5 0x50E3 # 0 +0x8EA2C9A6 0x50E0 # 0 +0x8EA2C9A7 0x51D8 # 0 +0x8EA2C9A8 0x5280 # 0 +0x8EA2C9A9 0x5281 # 0 +0x8EA2C9AA 0x52E9 # 0 +0x8EA2C9AB 0x52EB # 0 +0x8EA2C9AC 0x5330 # 0 +0x8EA2C9AD 0x53AC # 0 +0x8EA2C9AE 0x5627 # 0 +0x8EA2C9AF 0x5615 # 0 +0x8EA2C9B0 0x560C # 0 +0x8EA2C9B1 0x5612 # 0 +0x8EA2C9B2 0x55FC # 0 +0x8EA2C9B3 0x560F # 0 +0x8EA2C9B4 0x561C # 0 +0x8EA2C9B5 0x5601 # 0 +0x8EA2C9B6 0x5613 # 0 +0x8EA2C9B7 0x5602 # 0 +0x8EA2C9B8 0x55FA # 0 +0x8EA2C9B9 0x561D # 0 +0x8EA2C9BA 0x5604 # 0 +0x8EA2C9BB 0x55FF # 0 +0x8EA2C9BC 0x55F9 # 0 +0x8EA2C9BD 0x5889 # 0 +0x8EA2C9BE 0x587C # 0 +0x8EA2C9BF 0x5890 # 0 +0x8EA2C9C0 0x5898 # 0 +0x8EA2C9C1 0x5886 # 0 +0x8EA2C9C2 0x5881 # 0 +0x8EA2C9C3 0x587F # 0 +0x8EA2C9C4 0x5874 # 0 +0x8EA2C9C5 0x588B # 0 +0x8EA2C9C6 0x587A # 0 +0x8EA2C9C7 0x5887 # 0 +0x8EA2C9C8 0x5891 # 0 +0x8EA2C9C9 0x588E # 0 +0x8EA2C9CA 0x5876 # 0 +0x8EA2C9CB 0x5882 # 0 +0x8EA2C9CC 0x5888 # 0 +0x8EA2C9CD 0x587B # 0 +0x8EA2C9CE 0x5894 # 0 +0x8EA2C9CF 0x588F # 0 +0x8EA2C9D0 0x58FE # 0 +0x8EA2C9D1 0x596B # 0 +0x8EA2C9D2 0x5ADC # 0 +0x8EA2C9D3 0x5AEE # 0 +0x8EA2C9D4 0x5AE5 # 0 +0x8EA2C9D5 0x5AD5 # 0 +0x8EA2C9D6 0x5AEA # 0 +0x8EA2C9D7 0x5ADA # 0 +0x8EA2C9D8 0x5AED # 0 +0x8EA2C9D9 0x5AEB # 0 +0x8EA2C9DA 0x5AF3 # 0 +0x8EA2C9DB 0x5AE2 # 0 +0x8EA2C9DC 0x5AE0 # 0 +0x8EA2C9DD 0x5ADB # 0 +0x8EA2C9DE 0x5AEC # 0 +0x8EA2C9DF 0x5ADE # 0 +0x8EA2C9E0 0x5ADD # 0 +0x8EA2C9E1 0x5AD9 # 0 +0x8EA2C9E2 0x5AE8 # 0 +0x8EA2C9E3 0x5ADF # 0 +0x8EA2C9E4 0x5B77 # 0 +0x8EA2C9E5 0x5BE0 # 0 +0x8EA2C9E6 0x5BE3 # 0 +0x8EA2C9E7 0x5C63 # 0 +0x8EA2C9E8 0x5D82 # 0 +0x8EA2C9E9 0x5D80 # 0 +0x8EA2C9EA 0x5D7D # 0 +0x8EA2C9EB 0x5D86 # 0 +0x8EA2C9EC 0x5D7A # 0 +0x8EA2C9ED 0x5D81 # 0 +0x8EA2C9EE 0x5D77 # 0 +0x8EA2C9EF 0x5D8A # 0 +0x8EA2C9F0 0x5D89 # 0 +0x8EA2C9F1 0x5D88 # 0 +0x8EA2C9F2 0x5D7E # 0 +0x8EA2C9F3 0x5D7C # 0 +0x8EA2C9F4 0x5D8D # 0 +0x8EA2C9F5 0x5D79 # 0 +0x8EA2C9F6 0x5D7F # 0 +0x8EA2C9F7 0x5E58 # 0 +0x8EA2C9F8 0x5E59 # 0 +0x8EA2C9F9 0x5E53 # 0 +0x8EA2C9FA 0x5ED8 # 0 +0x8EA2C9FB 0x5ED1 # 0 +0x8EA2C9FC 0x5ED7 # 0 +0x8EA2C9FD 0x5ECE # 0 +0x8EA2C9FE 0x5EDC # 0 +0x8EA2CAA1 0x5ED5 # 0 +0x8EA2CAA2 0x5ED9 # 0 +0x8EA2CAA3 0x5ED2 # 0 +0x8EA2CAA4 0x5ED4 # 0 +0x8EA2CAA5 0x5F44 # 0 +0x8EA2CAA6 0x5F43 # 0 +0x8EA2CAA7 0x5F6F # 0 +0x8EA2CAA8 0x5FB6 # 0 +0x8EA2CAA9 0x612C # 0 +0x8EA2CAAA 0x6128 # 0 +0x8EA2CAAB 0x6141 # 0 +0x8EA2CAAC 0x615E # 0 +0x8EA2CAAD 0x6171 # 0 +0x8EA2CAAE 0x6173 # 0 +0x8EA2CAAF 0x6152 # 0 +0x8EA2CAB0 0x6153 # 0 +0x8EA2CAB1 0x6172 # 0 +0x8EA2CAB2 0x616C # 0 +0x8EA2CAB3 0x6180 # 0 +0x8EA2CAB4 0x6174 # 0 +0x8EA2CAB5 0x6154 # 0 +0x8EA2CAB6 0x617A # 0 +0x8EA2CAB7 0x615B # 0 +0x8EA2CAB8 0x6165 # 0 +0x8EA2CAB9 0x613B # 0 +0x8EA2CABA 0x616A # 0 +0x8EA2CABB 0x6161 # 0 +0x8EA2CABC 0x6156 # 0 +0x8EA2CABD 0x6229 # 0 +0x8EA2CABE 0x6227 # 0 +0x8EA2CABF 0x622B # 0 +0x8EA2CAC0 0x642B # 0 +0x8EA2CAC1 0x644D # 0 +0x8EA2CAC2 0x645B # 0 +0x8EA2CAC3 0x645D # 0 +0x8EA2CAC4 0x6474 # 0 +0x8EA2CAC5 0x6476 # 0 +0x8EA2CAC6 0x6472 # 0 +0x8EA2CAC7 0x6473 # 0 +0x8EA2CAC8 0x647D # 0 +0x8EA2CAC9 0x6475 # 0 +0x8EA2CACA 0x6466 # 0 +0x8EA2CACB 0x64A6 # 0 +0x8EA2CACC 0x644E # 0 +0x8EA2CACD 0x6482 # 0 +0x8EA2CACE 0x645E # 0 +0x8EA2CACF 0x645C # 0 +0x8EA2CAD0 0x644B # 0 +0x8EA2CAD1 0x6453 # 0 +0x8EA2CAD2 0x6460 # 0 +0x8EA2CAD3 0x6450 # 0 +0x8EA2CAD4 0x647F # 0 +0x8EA2CAD5 0x643F # 0 +0x8EA2CAD6 0x646C # 0 +0x8EA2CAD7 0x646B # 0 +0x8EA2CAD8 0x6459 # 0 +0x8EA2CAD9 0x6465 # 0 +0x8EA2CADA 0x6477 # 0 +0x8EA2CADB 0x6573 # 0 +0x8EA2CADC 0x65A0 # 0 +0x8EA2CADD 0x66A1 # 0 +0x8EA2CADE 0x66A0 # 0 +0x8EA2CADF 0x669F # 0 +0x8EA2CAE0 0x6705 # 0 +0x8EA2CAE1 0x6704 # 0 +0x8EA2CAE2 0x6722 # 0 +0x8EA2CAE3 0x69B1 # 0 +0x8EA2CAE4 0x69B6 # 0 +0x8EA2CAE5 0x69C9 # 0 +0x8EA2CAE6 0x69A0 # 0 +0x8EA2CAE7 0x69CE # 0 +0x8EA2CAE8 0x6996 # 0 +0x8EA2CAE9 0x69B0 # 0 +0x8EA2CAEA 0x69AC # 0 +0x8EA2CAEB 0x69BC # 0 +0x8EA2CAEC 0x6991 # 0 +0x8EA2CAED 0x6999 # 0 +0x8EA2CAEE 0x698E # 0 +0x8EA2CAEF 0x69A7 # 0 +0x8EA2CAF0 0x698D # 0 +0x8EA2CAF1 0x69A9 # 0 +0x8EA2CAF2 0x69BE # 0 +0x8EA2CAF3 0x69AF # 0 +0x8EA2CAF4 0x69BF # 0 +0x8EA2CAF5 0x69C4 # 0 +0x8EA2CAF6 0x69BD # 0 +0x8EA2CAF7 0x69A4 # 0 +0x8EA2CAF8 0x69D4 # 0 +0x8EA2CAF9 0x69B9 # 0 +0x8EA2CAFA 0x69CA # 0 +0x8EA2CAFB 0x699A # 0 +0x8EA2CAFC 0x69CF # 0 +0x8EA2CAFD 0x69B3 # 0 +0x8EA2CAFE 0x6993 # 0 +0x8EA2CBA1 0x69AA # 0 +0x8EA2CBA2 0x69A1 # 0 +0x8EA2CBA3 0x699E # 0 +0x8EA2CBA4 0x69D9 # 0 +0x8EA2CBA5 0x6997 # 0 +0x8EA2CBA6 0x6990 # 0 +0x8EA2CBA7 0x69C2 # 0 +0x8EA2CBA8 0x69B5 # 0 +0x8EA2CBA9 0x69A5 # 0 +0x8EA2CBAA 0x69C6 # 0 +0x8EA2CBAB 0x6B4A # 0 +0x8EA2CBAC 0x6B4D # 0 +0x8EA2CBAD 0x6B4B # 0 +0x8EA2CBAE 0x6B9E # 0 +0x8EA2CBAF 0x6B9F # 0 +0x8EA2CBB0 0x6BA0 # 0 +0x8EA2CBB1 0x6BC3 # 0 +0x8EA2CBB2 0x6BC4 # 0 +0x8EA2CBB3 0x6BFE # 0 +0x8EA2CBB4 0x6ECE # 0 +0x8EA2CBB5 0x6EF5 # 0 +0x8EA2CBB6 0x6EF1 # 0 +0x8EA2CBB7 0x6F03 # 0 +0x8EA2CBB8 0x6F25 # 0 +0x8EA2CBB9 0x6EF8 # 0 +0x8EA2CBBA 0x6F37 # 0 +0x8EA2CBBB 0x6EFB # 0 +0x8EA2CBBC 0x6F2E # 0 +0x8EA2CBBD 0x6F09 # 0 +0x8EA2CBBE 0x6F4E # 0 +0x8EA2CBBF 0x6F19 # 0 +0x8EA2CBC0 0x6F1A # 0 +0x8EA2CBC1 0x6F27 # 0 +0x8EA2CBC2 0x6F18 # 0 +0x8EA2CBC3 0x6F3B # 0 +0x8EA2CBC4 0x6F12 # 0 +0x8EA2CBC5 0x6EED # 0 +0x8EA2CBC6 0x6F0A # 0 +0x8EA2CBC7 0x6F36 # 0 +0x8EA2CBC8 0x6F73 # 0 +0x8EA2CBC9 0x6EF9 # 0 +0x8EA2CBCA 0x6EEE # 0 +0x8EA2CBCB 0x6F2D # 0 +0x8EA2CBCC 0x6F40 # 0 +0x8EA2CBCD 0x6F30 # 0 +0x8EA2CBCE 0x6F3C # 0 +0x8EA2CBCF 0x6F35 # 0 +0x8EA2CBD0 0x6EEB # 0 +0x8EA2CBD1 0x6F07 # 0 +0x8EA2CBD2 0x6F0E # 0 +0x8EA2CBD3 0x6F43 # 0 +0x8EA2CBD4 0x6F05 # 0 +0x8EA2CBD5 0x6EFD # 0 +0x8EA2CBD6 0x6EF6 # 0 +0x8EA2CBD7 0x6F39 # 0 +0x8EA2CBD8 0x6F1C # 0 +0x8EA2CBD9 0x6EFC # 0 +0x8EA2CBDA 0x6F3A # 0 +0x8EA2CBDB 0x6F1F # 0 +0x8EA2CBDC 0x6F0D # 0 +0x8EA2CBDD 0x6F1E # 0 +0x8EA2CBDE 0x6F08 # 0 +0x8EA2CBDF 0x6F21 # 0 +0x8EA2CBE0 0x7187 # 0 +0x8EA2CBE1 0x7190 # 0 +0x8EA2CBE2 0x7189 # 0 +0x8EA2CBE3 0x7180 # 0 +0x8EA2CBE4 0x7185 # 0 +0x8EA2CBE5 0x7182 # 0 +0x8EA2CBE6 0x718F # 0 +0x8EA2CBE7 0x717B # 0 +0x8EA2CBE8 0x7186 # 0 +0x8EA2CBE9 0x7181 # 0 +0x8EA2CBEA 0x7197 # 0 +0x8EA2CBEB 0x7244 # 0 +0x8EA2CBEC 0x7253 # 0 +0x8EA2CBED 0x7297 # 0 +0x8EA2CBEE 0x7295 # 0 +0x8EA2CBEF 0x7293 # 0 +0x8EA2CBF0 0x7343 # 0 +0x8EA2CBF1 0x734D # 0 +0x8EA2CBF2 0x7351 # 0 +0x8EA2CBF3 0x734C # 0 +0x8EA2CBF4 0x7462 # 0 +0x8EA2CBF5 0x7473 # 0 +0x8EA2CBF6 0x7471 # 0 +0x8EA2CBF7 0x7475 # 0 +0x8EA2CBF8 0x7472 # 0 +0x8EA2CBF9 0x7467 # 0 +0x8EA2CBFA 0x746E # 0 +0x8EA2CBFB 0x7500 # 0 +0x8EA2CBFC 0x7502 # 0 +0x8EA2CBFD 0x7503 # 0 +0x8EA2CBFE 0x757D # 0 +0x8EA2CCA1 0x7590 # 0 +0x8EA2CCA2 0x7616 # 0 +0x8EA2CCA3 0x7608 # 0 +0x8EA2CCA4 0x760C # 0 +0x8EA2CCA5 0x7615 # 0 +0x8EA2CCA6 0x7611 # 0 +0x8EA2CCA7 0x760A # 0 +0x8EA2CCA8 0x7614 # 0 +0x8EA2CCA9 0x76B8 # 0 +0x8EA2CCAA 0x7781 # 0 +0x8EA2CCAB 0x777C # 0 +0x8EA2CCAC 0x7785 # 0 +0x8EA2CCAD 0x7782 # 0 +0x8EA2CCAE 0x776E # 0 +0x8EA2CCAF 0x7780 # 0 +0x8EA2CCB0 0x776F # 0 +0x8EA2CCB1 0x777E # 0 +0x8EA2CCB2 0x7783 # 0 +0x8EA2CCB3 0x78B2 # 0 +0x8EA2CCB4 0x78AA # 0 +0x8EA2CCB5 0x78B4 # 0 +0x8EA2CCB6 0x78AD # 0 +0x8EA2CCB7 0x78A8 # 0 +0x8EA2CCB8 0x787E # 0 +0x8EA2CCB9 0x78AB # 0 +0x8EA2CCBA 0x789E # 0 +0x8EA2CCBB 0x78A5 # 0 +0x8EA2CCBC 0x78A0 # 0 +0x8EA2CCBD 0x78AC # 0 +0x8EA2CCBE 0x78A2 # 0 +0x8EA2CCBF 0x78A4 # 0 +0x8EA2CCC0 0x7998 # 0 +0x8EA2CCC1 0x798A # 0 +0x8EA2CCC2 0x798B # 0 +0x8EA2CCC3 0x7996 # 0 +0x8EA2CCC4 0x7995 # 0 +0x8EA2CCC5 0x7994 # 0 +0x8EA2CCC6 0x7993 # 0 +0x8EA2CCC7 0x7997 # 0 +0x8EA2CCC8 0x7988 # 0 +0x8EA2CCC9 0x7992 # 0 +0x8EA2CCCA 0x7990 # 0 +0x8EA2CCCB 0x7A2B # 0 +0x8EA2CCCC 0x7A4A # 0 +0x8EA2CCCD 0x7A30 # 0 +0x8EA2CCCE 0x7A2F # 0 +0x8EA2CCCF 0x7A28 # 0 +0x8EA2CCD0 0x7A26 # 0 +0x8EA2CCD1 0x7AA8 # 0 +0x8EA2CCD2 0x7AAB # 0 +0x8EA2CCD3 0x7AAC # 0 +0x8EA2CCD4 0x7AEE # 0 +0x8EA2CCD5 0x7B88 # 0 +0x8EA2CCD6 0x7B9C # 0 +0x8EA2CCD7 0x7B8A # 0 +0x8EA2CCD8 0x7B91 # 0 +0x8EA2CCD9 0x7B90 # 0 +0x8EA2CCDA 0x7B96 # 0 +0x8EA2CCDB 0x7B8D # 0 +0x8EA2CCDC 0x7B8C # 0 +0x8EA2CCDD 0x7B9B # 0 +0x8EA2CCDE 0x7B8E # 0 +0x8EA2CCDF 0x7B85 # 0 +0x8EA2CCE0 0x7B98 # 0 +0x8EA2CCE1 0x5284 # 0 +0x8EA2CCE2 0x7B99 # 0 +0x8EA2CCE3 0x7BA4 # 0 +0x8EA2CCE4 0x7B82 # 0 +0x8EA2CCE5 0x7CBB # 0 +0x8EA2CCE6 0x7CBF # 0 +0x8EA2CCE7 0x7CBC # 0 +0x8EA2CCE8 0x7CBA # 0 +0x8EA2CCE9 0x7DA7 # 0 +0x8EA2CCEA 0x7DB7 # 0 +0x8EA2CCEB 0x7DC2 # 0 +0x8EA2CCEC 0x7DA3 # 0 +0x8EA2CCED 0x7DAA # 0 +0x8EA2CCEE 0x7DC1 # 0 +0x8EA2CCEF 0x7DC0 # 0 +0x8EA2CCF0 0x7DC5 # 0 +0x8EA2CCF1 0x7D9D # 0 +0x8EA2CCF2 0x7DCE # 0 +0x8EA2CCF3 0x7DC4 # 0 +0x8EA2CCF4 0x7DC6 # 0 +0x8EA2CCF5 0x7DCB # 0 +0x8EA2CCF6 0x7DCC # 0 +0x8EA2CCF7 0x7DAF # 0 +0x8EA2CCF8 0x7DB9 # 0 +0x8EA2CCF9 0x7D96 # 0 +0x8EA2CCFA 0x7DBC # 0 +0x8EA2CCFB 0x7D9F # 0 +0x8EA2CCFC 0x7DA6 # 0 +0x8EA2CCFD 0x7DAE # 0 +0x8EA2CCFE 0x7DA9 # 0 +0x8EA2CDA1 0x7DA1 # 0 +0x8EA2CDA2 0x7DC9 # 0 +0x8EA2CDA3 0x7F73 # 0 +0x8EA2CDA4 0x7FE2 # 0 +0x8EA2CDA5 0x7FE3 # 0 +0x8EA2CDA6 0x7FE5 # 0 +0x8EA2CDA7 0x7FDE # 0 +0x8EA2CDA8 0x8024 # 0 +0x8EA2CDA9 0x805D # 0 +0x8EA2CDAA 0x805C # 0 +0x8EA2CDAB 0x8189 # 0 +0x8EA2CDAC 0x8186 # 0 +0x8EA2CDAD 0x8183 # 0 +0x8EA2CDAE 0x8187 # 0 +0x8EA2CDAF 0x818D # 0 +0x8EA2CDB0 0x818C # 0 +0x8EA2CDB1 0x818B # 0 +0x8EA2CDB2 0x8215 # 0 +0x8EA2CDB3 0x8497 # 0 +0x8EA2CDB4 0x84A4 # 0 +0x8EA2CDB5 0x84A1 # 0 +0x8EA2CDB6 0x849F # 0 +0x8EA2CDB7 0x84BA # 0 +0x8EA2CDB8 0x84CE # 0 +0x8EA2CDB9 0x84C2 # 0 +0x8EA2CDBA 0x84AC # 0 +0x8EA2CDBB 0x84AE # 0 +0x8EA2CDBC 0x84AB # 0 +0x8EA2CDBD 0x84B9 # 0 +0x8EA2CDBE 0x84B4 # 0 +0x8EA2CDBF 0x84C1 # 0 +0x8EA2CDC0 0x84CD # 0 +0x8EA2CDC1 0x84AA # 0 +0x8EA2CDC2 0x849A # 0 +0x8EA2CDC3 0x84B1 # 0 +0x8EA2CDC4 0x84D0 # 0 +0x8EA2CDC5 0x849D # 0 +0x8EA2CDC6 0x84A7 # 0 +0x8EA2CDC7 0x84BB # 0 +0x8EA2CDC8 0x84A2 # 0 +0x8EA2CDC9 0x8494 # 0 +0x8EA2CDCA 0x84C7 # 0 +0x8EA2CDCB 0x84CC # 0 +0x8EA2CDCC 0x849B # 0 +0x8EA2CDCD 0x84A9 # 0 +0x8EA2CDCE 0x84AF # 0 +0x8EA2CDCF 0x84A8 # 0 +0x8EA2CDD0 0x84D6 # 0 +0x8EA2CDD1 0x8498 # 0 +0x8EA2CDD2 0x84B6 # 0 +0x8EA2CDD3 0x84CF # 0 +0x8EA2CDD4 0x84A0 # 0 +0x8EA2CDD5 0x84D7 # 0 +0x8EA2CDD6 0x84D4 # 0 +0x8EA2CDD7 0x84D2 # 0 +0x8EA2CDD8 0x84DB # 0 +0x8EA2CDD9 0x84B0 # 0 +0x8EA2CDDA 0x8491 # 0 +0x8EA2CDDB 0x8661 # 0 +0x8EA2CDDC 0x8733 # 0 +0x8EA2CDDD 0x8723 # 0 +0x8EA2CDDE 0x8728 # 0 +0x8EA2CDDF 0x876B # 0 +0x8EA2CDE0 0x8740 # 0 +0x8EA2CDE1 0x872E # 0 +0x8EA2CDE2 0x871E # 0 +0x8EA2CDE3 0x8721 # 0 +0x8EA2CDE4 0x8719 # 0 +0x8EA2CDE5 0x871B # 0 +0x8EA2CDE6 0x8743 # 0 +0x8EA2CDE7 0x872C # 0 +0x8EA2CDE8 0x8741 # 0 +0x8EA2CDE9 0x873E # 0 +0x8EA2CDEA 0x8746 # 0 +0x8EA2CDEB 0x8720 # 0 +0x8EA2CDEC 0x8732 # 0 +0x8EA2CDED 0x872A # 0 +0x8EA2CDEE 0x872D # 0 +0x8EA2CDEF 0x873C # 0 +0x8EA2CDF0 0x8712 # 0 +0x8EA2CDF1 0x873A # 0 +0x8EA2CDF2 0x8731 # 0 +0x8EA2CDF3 0x8735 # 0 +0x8EA2CDF4 0x8742 # 0 +0x8EA2CDF5 0x8726 # 0 +0x8EA2CDF6 0x8727 # 0 +0x8EA2CDF7 0x8738 # 0 +0x8EA2CDF8 0x8724 # 0 +0x8EA2CDF9 0x871A # 0 +0x8EA2CDFA 0x8730 # 0 +0x8EA2CDFB 0x8711 # 0 +0x8EA2CDFC 0x88F7 # 0 +0x8EA2CDFD 0x88E7 # 0 +0x8EA2CDFE 0x88F1 # 0 +0x8EA2CEA1 0x88F2 # 0 +0x8EA2CEA2 0x88FA # 0 +0x8EA2CEA3 0x88FE # 0 +0x8EA2CEA4 0x88EE # 0 +0x8EA2CEA5 0x88FC # 0 +0x8EA2CEA6 0x88F6 # 0 +0x8EA2CEA7 0x88FB # 0 +0x8EA2CEA8 0x88F0 # 0 +0x8EA2CEA9 0x88EC # 0 +0x8EA2CEAA 0x88EB # 0 +0x8EA2CEAB 0x899D # 0 +0x8EA2CEAC 0x89A1 # 0 +0x8EA2CEAD 0x899F # 0 +0x8EA2CEAE 0x899E # 0 +0x8EA2CEAF 0x89E9 # 0 +0x8EA2CEB0 0x89EB # 0 +0x8EA2CEB1 0x89E8 # 0 +0x8EA2CEB2 0x8AAB # 0 +0x8EA2CEB3 0x8A99 # 0 +0x8EA2CEB4 0x8A8B # 0 +0x8EA2CEB5 0x8A92 # 0 +0x8EA2CEB6 0x8A8F # 0 +0x8EA2CEB7 0x8A96 # 0 +0x8EA2CEB8 0x8C3D # 0 +0x8EA2CEB9 0x8C68 # 0 +0x8EA2CEBA 0x8C69 # 0 +0x8EA2CEBB 0x8CD5 # 0 +0x8EA2CEBC 0x8CCF # 0 +0x8EA2CEBD 0x8CD7 # 0 +0x8EA2CEBE 0x8D96 # 0 +0x8EA2CEBF 0x8E09 # 0 +0x8EA2CEC0 0x8E02 # 0 +0x8EA2CEC1 0x8DFF # 0 +0x8EA2CEC2 0x8E0D # 0 +0x8EA2CEC3 0x8DFD # 0 +0x8EA2CEC4 0x8E0A # 0 +0x8EA2CEC5 0x8E03 # 0 +0x8EA2CEC6 0x8E07 # 0 +0x8EA2CEC7 0x8E06 # 0 +0x8EA2CEC8 0x8E05 # 0 +0x8EA2CEC9 0x8DFE # 0 +0x8EA2CECA 0x8E00 # 0 +0x8EA2CECB 0x8E04 # 0 +0x8EA2CECC 0x8F10 # 0 +0x8EA2CECD 0x8F11 # 0 +0x8EA2CECE 0x8F0E # 0 +0x8EA2CECF 0x8F0D # 0 +0x8EA2CED0 0x9123 # 0 +0x8EA2CED1 0x911C # 0 +0x8EA2CED2 0x9120 # 0 +0x8EA2CED3 0x9122 # 0 +0x8EA2CED4 0x911F # 0 +0x8EA2CED5 0x911D # 0 +0x8EA2CED6 0x911A # 0 +0x8EA2CED7 0x9124 # 0 +0x8EA2CED8 0x9121 # 0 +0x8EA2CED9 0x911B # 0 +0x8EA2CEDA 0x917A # 0 +0x8EA2CEDB 0x9172 # 0 +0x8EA2CEDC 0x9179 # 0 +0x8EA2CEDD 0x9173 # 0 +0x8EA2CEDE 0x92A5 # 0 +0x8EA2CEDF 0x92A4 # 0 +0x8EA2CEE0 0x9276 # 0 +0x8EA2CEE1 0x929B # 0 +0x8EA2CEE2 0x927A # 0 +0x8EA2CEE3 0x92A0 # 0 +0x8EA2CEE4 0x9294 # 0 +0x8EA2CEE5 0x92AA # 0 +0x8EA2CEE6 0x928D # 0 +0x8EA2CEE7 0x92A6 # 0 +0x8EA2CEE8 0x929A # 0 +0x8EA2CEE9 0x92AB # 0 +0x8EA2CEEA 0x9279 # 0 +0x8EA2CEEB 0x9297 # 0 +0x8EA2CEEC 0x927F # 0 +0x8EA2CEED 0x92A3 # 0 +0x8EA2CEEE 0x92EE # 0 +0x8EA2CEEF 0x928E # 0 +0x8EA2CEF0 0x9282 # 0 +0x8EA2CEF1 0x9295 # 0 +0x8EA2CEF2 0x92A2 # 0 +0x8EA2CEF3 0x927D # 0 +0x8EA2CEF4 0x9288 # 0 +0x8EA2CEF5 0x92A1 # 0 +0x8EA2CEF6 0x928A # 0 +0x8EA2CEF7 0x9286 # 0 +0x8EA2CEF8 0x928C # 0 +0x8EA2CEF9 0x9299 # 0 +0x8EA2CEFA 0x92A7 # 0 +0x8EA2CEFB 0x927E # 0 +0x8EA2CEFC 0x9287 # 0 +0x8EA2CEFD 0x92A9 # 0 +0x8EA2CEFE 0x929D # 0 +0x8EA2CFA1 0x928B # 0 +0x8EA2CFA2 0x922D # 0 +0x8EA2CFA3 0x969E # 0 +0x8EA2CFA4 0x96A1 # 0 +0x8EA2CFA5 0x96FF # 0 +0x8EA2CFA6 0x9758 # 0 +0x8EA2CFA7 0x977D # 0 +0x8EA2CFA8 0x977A # 0 +0x8EA2CFA9 0x977E # 0 +0x8EA2CFAA 0x9783 # 0 +0x8EA2CFAB 0x9780 # 0 +0x8EA2CFAC 0x9782 # 0 +0x8EA2CFAD 0x977B # 0 +0x8EA2CFAE 0x9784 # 0 +0x8EA2CFAF 0x9781 # 0 +0x8EA2CFB0 0x977F # 0 +0x8EA2CFB1 0x97CE # 0 +0x8EA2CFB2 0x97CD # 0 +0x8EA2CFB3 0x9816 # 0 +0x8EA2CFB4 0x98AD # 0 +0x8EA2CFB5 0x98AE # 0 +0x8EA2CFB6 0x9902 # 0 +0x8EA2CFB7 0x9900 # 0 +0x8EA2CFB8 0x9907 # 0 +0x8EA2CFB9 0x999D # 0 +0x8EA2CFBA 0x999C # 0 +0x8EA2CFBB 0x99C3 # 0 +0x8EA2CFBC 0x99B9 # 0 +0x8EA2CFBD 0x99BB # 0 +0x8EA2CFBE 0x99BA # 0 +0x8EA2CFBF 0x99C2 # 0 +0x8EA2CFC0 0x99BD # 0 +0x8EA2CFC1 0x99C7 # 0 +0x8EA2CFC2 0x9AB1 # 0 +0x8EA2CFC3 0x9AE3 # 0 +0x8EA2CFC4 0x9AE7 # 0 +0x8EA2CFC5 0x9B3E # 0 +0x8EA2CFC6 0x9B3F # 0 +0x8EA2CFC7 0x9B60 # 0 +0x8EA2CFC8 0x9B61 # 0 +0x8EA2CFC9 0x9B5F # 0 +0x8EA2CFCA 0x9CF1 # 0 +0x8EA2CFCB 0x9CF2 # 0 +0x8EA2CFCC 0x9CF5 # 0 +0x8EA2CFCD 0x9EA7 # 0 +0x8EA2CFCE 0x50FF # 0 +0x8EA2CFCF 0x5103 # 0 +0x8EA2CFD0 0x5130 # 0 +0x8EA2CFD1 0x50F8 # 0 +0x8EA2CFD2 0x5106 # 0 +0x8EA2CFD3 0x5107 # 0 +0x8EA2CFD4 0x50F6 # 0 +0x8EA2CFD5 0x50FE # 0 +0x8EA2CFD6 0x510B # 0 +0x8EA2CFD7 0x510C # 0 +0x8EA2CFD8 0x50FD # 0 +0x8EA2CFD9 0x510A # 0 +0x8EA2CFDA 0x528B # 0 +0x8EA2CFDB 0x528C # 0 +0x8EA2CFDC 0x52F1 # 0 +0x8EA2CFDD 0x52EF # 0 +0x8EA2CFDE 0x5648 # 0 +0x8EA2CFDF 0x5642 # 0 +0x8EA2CFE0 0x564C # 0 +0x8EA2CFE1 0x5635 # 0 +0x8EA2CFE2 0x5641 # 0 +0x8EA2CFE3 0x564A # 0 +0x8EA2CFE4 0x5649 # 0 +0x8EA2CFE5 0x5646 # 0 +0x8EA2CFE6 0x5658 # 0 +0x8EA2CFE7 0x565A # 0 +0x8EA2CFE8 0x5640 # 0 +0x8EA2CFE9 0x5633 # 0 +0x8EA2CFEA 0x563D # 0 +0x8EA2CFEB 0x562C # 0 +0x8EA2CFEC 0x563E # 0 +0x8EA2CFED 0x5638 # 0 +0x8EA2CFEE 0x562A # 0 +0x8EA2CFEF 0x563A # 0 +0x8EA2CFF0 0x571A # 0 +0x8EA2CFF1 0x58AB # 0 +0x8EA2CFF2 0x589D # 0 +0x8EA2CFF3 0x58B1 # 0 +0x8EA2CFF4 0x58A0 # 0 +0x8EA2CFF5 0x58A3 # 0 +0x8EA2CFF6 0x58AF # 0 +0x8EA2CFF7 0x58AC # 0 +0x8EA2CFF8 0x58A5 # 0 +0x8EA2CFF9 0x58A1 # 0 +0x8EA2CFFA 0x58FF # 0 +0x8EA2CFFB 0x5AFF # 0 +0x8EA2CFFC 0x5AF4 # 0 +0x8EA2CFFD 0x5AFD # 0 +0x8EA2CFFE 0x5AF7 # 0 +0x8EA2D0A1 0x5AF6 # 0 +0x8EA2D0A2 0x5B03 # 0 +0x8EA2D0A3 0x5AF8 # 0 +0x8EA2D0A4 0x5B02 # 0 +0x8EA2D0A5 0x5AF9 # 0 +0x8EA2D0A6 0x5B01 # 0 +0x8EA2D0A7 0x5B07 # 0 +0x8EA2D0A8 0x5B05 # 0 +0x8EA2D0A9 0x5B0F # 0 +0x8EA2D0AA 0x5C67 # 0 +0x8EA2D0AB 0x5D99 # 0 +0x8EA2D0AC 0x5D97 # 0 +0x8EA2D0AD 0x5D9F # 0 +0x8EA2D0AE 0x5D92 # 0 +0x8EA2D0AF 0x5DA2 # 0 +0x8EA2D0B0 0x5D93 # 0 +0x8EA2D0B1 0x5D95 # 0 +0x8EA2D0B2 0x5DA0 # 0 +0x8EA2D0B3 0x5D9C # 0 +0x8EA2D0B4 0x5DA1 # 0 +0x8EA2D0B5 0x5D9A # 0 +0x8EA2D0B6 0x5D9E # 0 +0x8EA2D0B7 0x5E69 # 0 +0x8EA2D0B8 0x5E5D # 0 +0x8EA2D0B9 0x5E60 # 0 +0x8EA2D0BA 0x5E5C # 0 +0x8EA2D0BB 0x7DF3 # 0 +0x8EA2D0BC 0x5EDB # 0 +0x8EA2D0BD 0x5EDE # 0 +0x8EA2D0BE 0x5EE1 # 0 +0x8EA2D0BF 0x5F49 # 0 +0x8EA2D0C0 0x5FB2 # 0 +0x8EA2D0C1 0x618B # 0 +0x8EA2D0C2 0x6183 # 0 +0x8EA2D0C3 0x6179 # 0 +0x8EA2D0C4 0x61B1 # 0 +0x8EA2D0C5 0x61B0 # 0 +0x8EA2D0C6 0x61A2 # 0 +0x8EA2D0C7 0x6189 # 0 +0x8EA2D0C8 0x619B # 0 +0x8EA2D0C9 0x6193 # 0 +0x8EA2D0CA 0x61AF # 0 +0x8EA2D0CB 0x61AD # 0 +0x8EA2D0CC 0x619F # 0 +0x8EA2D0CD 0x6192 # 0 +0x8EA2D0CE 0x61AA # 0 +0x8EA2D0CF 0x61A1 # 0 +0x8EA2D0D0 0x618D # 0 +0x8EA2D0D1 0x6166 # 0 +0x8EA2D0D2 0x61B3 # 0 +0x8EA2D0D3 0x622D # 0 +0x8EA2D0D4 0x646E # 0 +0x8EA2D0D5 0x6470 # 0 +0x8EA2D0D6 0x6496 # 0 +0x8EA2D0D7 0x64A0 # 0 +0x8EA2D0D8 0x6485 # 0 +0x8EA2D0D9 0x6497 # 0 +0x8EA2D0DA 0x649C # 0 +0x8EA2D0DB 0x648F # 0 +0x8EA2D0DC 0x648B # 0 +0x8EA2D0DD 0x648A # 0 +0x8EA2D0DE 0x648C # 0 +0x8EA2D0DF 0x64A3 # 0 +0x8EA2D0E0 0x649F # 0 +0x8EA2D0E1 0x6468 # 0 +0x8EA2D0E2 0x64B1 # 0 +0x8EA2D0E3 0x6498 # 0 +0x8EA2D0E4 0x6576 # 0 +0x8EA2D0E5 0x657A # 0 +0x8EA2D0E6 0x6579 # 0 +0x8EA2D0E7 0x657B # 0 +0x8EA2D0E8 0x65B2 # 0 +0x8EA2D0E9 0x65B3 # 0 +0x8EA2D0EA 0x66B5 # 0 +0x8EA2D0EB 0x66B0 # 0 +0x8EA2D0EC 0x66A9 # 0 +0x8EA2D0ED 0x66B2 # 0 +0x8EA2D0EE 0x66B7 # 0 +0x8EA2D0EF 0x66AA # 0 +0x8EA2D0F0 0x66AF # 0 +0x8EA2D0F1 0x6A00 # 0 +0x8EA2D0F2 0x6A06 # 0 +0x8EA2D0F3 0x6A17 # 0 +0x8EA2D0F4 0x69E5 # 0 +0x8EA2D0F5 0x69F8 # 0 +0x8EA2D0F6 0x6A15 # 0 +0x8EA2D0F7 0x69F1 # 0 +0x8EA2D0F8 0x69E4 # 0 +0x8EA2D0F9 0x6A20 # 0 +0x8EA2D0FA 0x69FF # 0 +0x8EA2D0FB 0x69EC # 0 +0x8EA2D0FC 0x69E2 # 0 +0x8EA2D0FD 0x6A1B # 0 +0x8EA2D0FE 0x6A1D # 0 +0x8EA2D1A1 0x69FE # 0 +0x8EA2D1A2 0x6A27 # 0 +0x8EA2D1A3 0x69F2 # 0 +0x8EA2D1A4 0x69EE # 0 +0x8EA2D1A5 0x6A14 # 0 +0x8EA2D1A6 0x69F7 # 0 +0x8EA2D1A7 0x69E7 # 0 +0x8EA2D1A8 0x6A40 # 0 +0x8EA2D1A9 0x6A08 # 0 +0x8EA2D1AA 0x69E6 # 0 +0x8EA2D1AB 0x69FB # 0 +0x8EA2D1AC 0x6A0D # 0 +0x8EA2D1AD 0x69FC # 0 +0x8EA2D1AE 0x69EB # 0 +0x8EA2D1AF 0x6A09 # 0 +0x8EA2D1B0 0x6A04 # 0 +0x8EA2D1B1 0x6A18 # 0 +0x8EA2D1B2 0x6A25 # 0 +0x8EA2D1B3 0x6A0F # 0 +0x8EA2D1B4 0x69F6 # 0 +0x8EA2D1B5 0x6A26 # 0 +0x8EA2D1B6 0x6A07 # 0 +0x8EA2D1B7 0x69F4 # 0 +0x8EA2D1B8 0x6A16 # 0 +0x8EA2D1B9 0x6B51 # 0 +0x8EA2D1BA 0x6BA5 # 0 +0x8EA2D1BB 0x6BA3 # 0 +0x8EA2D1BC 0x6BA2 # 0 +0x8EA2D1BD 0x6BA6 # 0 +0x8EA2D1BE 0x6C01 # 0 +0x8EA2D1BF 0x6C00 # 0 +0x8EA2D1C0 0x6BFF # 0 +0x8EA2D1C1 0x6C02 # 0 +0x8EA2D1C2 0x6F41 # 0 +0x8EA2D1C3 0x6F26 # 0 +0x8EA2D1C4 0x6F7E # 0 +0x8EA2D1C5 0x6F87 # 0 +0x8EA2D1C6 0x6FC6 # 0 +0x8EA2D1C7 0x6F92 # 0 +0x8EA2D1C8 0x6F8D # 0 +0x8EA2D1C9 0x6F89 # 0 +0x8EA2D1CA 0x6F8C # 0 +0x8EA2D1CB 0x6F62 # 0 +0x8EA2D1CC 0x6F4F # 0 +0x8EA2D1CD 0x6F85 # 0 +0x8EA2D1CE 0x6F5A # 0 +0x8EA2D1CF 0x6F96 # 0 +0x8EA2D1D0 0x6F76 # 0 +0x8EA2D1D1 0x6F6C # 0 +0x8EA2D1D2 0x6F82 # 0 +0x8EA2D1D3 0x6F55 # 0 +0x8EA2D1D4 0x6F72 # 0 +0x8EA2D1D5 0x6F52 # 0 +0x8EA2D1D6 0x6F50 # 0 +0x8EA2D1D7 0x6F57 # 0 +0x8EA2D1D8 0x6F94 # 0 +0x8EA2D1D9 0x6F93 # 0 +0x8EA2D1DA 0x6F5D # 0 +0x8EA2D1DB 0x6F00 # 0 +0x8EA2D1DC 0x6F61 # 0 +0x8EA2D1DD 0x6F6B # 0 +0x8EA2D1DE 0x6F7D # 0 +0x8EA2D1DF 0x6F67 # 0 +0x8EA2D1E0 0x6F90 # 0 +0x8EA2D1E1 0x6F53 # 0 +0x8EA2D1E2 0x6F8B # 0 +0x8EA2D1E3 0x6F69 # 0 +0x8EA2D1E4 0x6F7F # 0 +0x8EA2D1E5 0x6F95 # 0 +0x8EA2D1E6 0x6F63 # 0 +0x8EA2D1E7 0x6F77 # 0 +0x8EA2D1E8 0x6F6A # 0 +0x8EA2D1E9 0x6F7B # 0 +0x8EA2D1EA 0x71B2 # 0 +0x8EA2D1EB 0x71AF # 0 +0x8EA2D1EC 0x719B # 0 +0x8EA2D1ED 0x71B0 # 0 +0x8EA2D1EE 0x71A0 # 0 +0x8EA2D1EF 0x719A # 0 +0x8EA2D1F0 0x71A9 # 0 +0x8EA2D1F1 0x71B5 # 0 +0x8EA2D1F2 0x719D # 0 +0x8EA2D1F3 0x71A5 # 0 +0x8EA2D1F4 0x719E # 0 +0x8EA2D1F5 0x71A4 # 0 +0x8EA2D1F6 0x71A1 # 0 +0x8EA2D1F7 0x71AA # 0 +0x8EA2D1F8 0x719C # 0 +0x8EA2D1F9 0x71A7 # 0 +0x8EA2D1FA 0x71B3 # 0 +0x8EA2D1FB 0x7298 # 0 +0x8EA2D1FC 0x729A # 0 +0x8EA2D1FD 0x7358 # 0 +0x8EA2D1FE 0x7352 # 0 +0x8EA2D2A1 0x735E # 0 +0x8EA2D2A2 0x735F # 0 +0x8EA2D2A3 0x7360 # 0 +0x8EA2D2A4 0x735D # 0 +0x8EA2D2A5 0x735B # 0 +0x8EA2D2A6 0x7361 # 0 +0x8EA2D2A7 0x735A # 0 +0x8EA2D2A8 0x7359 # 0 +0x8EA2D2A9 0x7362 # 0 +0x8EA2D2AA 0x7487 # 0 +0x8EA2D2AB 0x7489 # 0 +0x8EA2D2AC 0x748A # 0 +0x8EA2D2AD 0x7486 # 0 +0x8EA2D2AE 0x7481 # 0 +0x8EA2D2AF 0x747D # 0 +0x8EA2D2B0 0x7485 # 0 +0x8EA2D2B1 0x7488 # 0 +0x8EA2D2B2 0x747C # 0 +0x8EA2D2B3 0x7479 # 0 +0x8EA2D2B4 0x7508 # 0 +0x8EA2D2B5 0x7507 # 0 +0x8EA2D2B6 0x757E # 0 +0x8EA2D2B7 0x7625 # 0 +0x8EA2D2B8 0x761E # 0 +0x8EA2D2B9 0x7619 # 0 +0x8EA2D2BA 0x761D # 0 +0x8EA2D2BB 0x761C # 0 +0x8EA2D2BC 0x7623 # 0 +0x8EA2D2BD 0x761A # 0 +0x8EA2D2BE 0x7628 # 0 +0x8EA2D2BF 0x761B # 0 +0x8EA2D2C0 0x769C # 0 +0x8EA2D2C1 0x769D # 0 +0x8EA2D2C2 0x769E # 0 +0x8EA2D2C3 0x769B # 0 +0x8EA2D2C4 0x778D # 0 +0x8EA2D2C5 0x778F # 0 +0x8EA2D2C6 0x7789 # 0 +0x8EA2D2C7 0x7788 # 0 +0x8EA2D2C8 0x78CD # 0 +0x8EA2D2C9 0x78BB # 0 +0x8EA2D2CA 0x78CF # 0 +0x8EA2D2CB 0x78CC # 0 +0x8EA2D2CC 0x78D1 # 0 +0x8EA2D2CD 0x78CE # 0 +0x8EA2D2CE 0x78D4 # 0 +0x8EA2D2CF 0x78C8 # 0 +0x8EA2D2D0 0x78C3 # 0 +0x8EA2D2D1 0x78C4 # 0 +0x8EA2D2D2 0x78C9 # 0 +0x8EA2D2D3 0x799A # 0 +0x8EA2D2D4 0x79A1 # 0 +0x8EA2D2D5 0x79A0 # 0 +0x8EA2D2D6 0x799C # 0 +0x8EA2D2D7 0x79A2 # 0 +0x8EA2D2D8 0x799B # 0 +0x8EA2D2D9 0x6B76 # 0 +0x8EA2D2DA 0x7A39 # 0 +0x8EA2D2DB 0x7AB2 # 0 +0x8EA2D2DC 0x7AB4 # 0 +0x8EA2D2DD 0x7AB3 # 0 +0x8EA2D2DE 0x7BB7 # 0 +0x8EA2D2DF 0x7BCB # 0 +0x8EA2D2E0 0x7BBE # 0 +0x8EA2D2E1 0x7BAC # 0 +0x8EA2D2E2 0x7BCE # 0 +0x8EA2D2E3 0x7BAF # 0 +0x8EA2D2E4 0x7BB9 # 0 +0x8EA2D2E5 0x7BCA # 0 +0x8EA2D2E6 0x7BB5 # 0 +0x8EA2D2E7 0x7CC5 # 0 +0x8EA2D2E8 0x7CC8 # 0 +0x8EA2D2E9 0x7CCC # 0 +0x8EA2D2EA 0x7CCB # 0 +0x8EA2D2EB 0x7DF7 # 0 +0x8EA2D2EC 0x7DDB # 0 +0x8EA2D2ED 0x7DEA # 0 +0x8EA2D2EE 0x7DE7 # 0 +0x8EA2D2EF 0x7DD7 # 0 +0x8EA2D2F0 0x7DE1 # 0 +0x8EA2D2F1 0x7E03 # 0 +0x8EA2D2F2 0x7DFA # 0 +0x8EA2D2F3 0x7DE6 # 0 +0x8EA2D2F4 0x7DF6 # 0 +0x8EA2D2F5 0x7DF1 # 0 +0x8EA2D2F6 0x7DF0 # 0 +0x8EA2D2F7 0x7DEE # 0 +0x8EA2D2F8 0x7DDF # 0 +0x8EA2D2F9 0x7F76 # 0 +0x8EA2D2FA 0x7FAC # 0 +0x8EA2D2FB 0x7FB0 # 0 +0x8EA2D2FC 0x7FAD # 0 +0x8EA2D2FD 0x7FED # 0 +0x8EA2D2FE 0x7FEB # 0 +0x8EA2D3A1 0x7FEA # 0 +0x8EA2D3A2 0x7FEC # 0 +0x8EA2D3A3 0x7FE6 # 0 +0x8EA2D3A4 0x7FE8 # 0 +0x8EA2D3A5 0x8064 # 0 +0x8EA2D3A6 0x8067 # 0 +0x8EA2D3A7 0x81A3 # 0 +0x8EA2D3A8 0x819F # 0 +0x8EA2D3A9 0x819E # 0 +0x8EA2D3AA 0x8195 # 0 +0x8EA2D3AB 0x81A2 # 0 +0x8EA2D3AC 0x8199 # 0 +0x8EA2D3AD 0x8197 # 0 +0x8EA2D3AE 0x8216 # 0 +0x8EA2D3AF 0x824F # 0 +0x8EA2D3B0 0x8253 # 0 +0x8EA2D3B1 0x8252 # 0 +0x8EA2D3B2 0x8250 # 0 +0x8EA2D3B3 0x824E # 0 +0x8EA2D3B4 0x8251 # 0 +0x8EA2D3B5 0x8524 # 0 +0x8EA2D3B6 0x853B # 0 +0x8EA2D3B7 0x850F # 0 +0x8EA2D3B8 0x8500 # 0 +0x8EA2D3B9 0x8529 # 0 +0x8EA2D3BA 0x850E # 0 +0x8EA2D3BB 0x8509 # 0 +0x8EA2D3BC 0x850D # 0 +0x8EA2D3BD 0x851F # 0 +0x8EA2D3BE 0x850A # 0 +0x8EA2D3BF 0x8527 # 0 +0x8EA2D3C0 0x851C # 0 +0x8EA2D3C1 0x84FB # 0 +0x8EA2D3C2 0x852B # 0 +0x8EA2D3C3 0x84FA # 0 +0x8EA2D3C4 0x8508 # 0 +0x8EA2D3C5 0x850C # 0 +0x8EA2D3C6 0x84F4 # 0 +0x8EA2D3C7 0x852A # 0 +0x8EA2D3C8 0x84F2 # 0 +0x8EA2D3C9 0x8515 # 0 +0x8EA2D3CA 0x84F7 # 0 +0x8EA2D3CB 0x84EB # 0 +0x8EA2D3CC 0x84F3 # 0 +0x8EA2D3CD 0x84FC # 0 +0x8EA2D3CE 0x8512 # 0 +0x8EA2D3CF 0x84EA # 0 +0x8EA2D3D0 0x84E9 # 0 +0x8EA2D3D1 0x8516 # 0 +0x8EA2D3D2 0x84FE # 0 +0x8EA2D3D3 0x8528 # 0 +0x8EA2D3D4 0x851D # 0 +0x8EA2D3D5 0x852E # 0 +0x8EA2D3D6 0x8502 # 0 +0x8EA2D3D7 0x84FD # 0 +0x8EA2D3D8 0x851E # 0 +0x8EA2D3D9 0x84F6 # 0 +0x8EA2D3DA 0x8531 # 0 +0x8EA2D3DB 0x8526 # 0 +0x8EA2D3DC 0x84E7 # 0 +0x8EA2D3DD 0x84E8 # 0 +0x8EA2D3DE 0x84F0 # 0 +0x8EA2D3DF 0x84EF # 0 +0x8EA2D3E0 0x84F9 # 0 +0x8EA2D3E1 0x8518 # 0 +0x8EA2D3E2 0x8520 # 0 +0x8EA2D3E3 0x8530 # 0 +0x8EA2D3E4 0x850B # 0 +0x8EA2D3E5 0x8519 # 0 +0x8EA2D3E6 0x852F # 0 +0x8EA2D3E7 0x8662 # 0 +0x8EA2D3E8 0x8756 # 0 +0x8EA2D3E9 0x8763 # 0 +0x8EA2D3EA 0x8764 # 0 +0x8EA2D3EB 0x8777 # 0 +0x8EA2D3EC 0x87E1 # 0 +0x8EA2D3ED 0x8773 # 0 +0x8EA2D3EE 0x8758 # 0 +0x8EA2D3EF 0x8754 # 0 +0x8EA2D3F0 0x875B # 0 +0x8EA2D3F1 0x8752 # 0 +0x8EA2D3F2 0x8761 # 0 +0x8EA2D3F3 0x875A # 0 +0x8EA2D3F4 0x8751 # 0 +0x8EA2D3F5 0x875E # 0 +0x8EA2D3F6 0x876D # 0 +0x8EA2D3F7 0x876A # 0 +0x8EA2D3F8 0x8750 # 0 +0x8EA2D3F9 0x874E # 0 +0x8EA2D3FA 0x875F # 0 +0x8EA2D3FB 0x875D # 0 +0x8EA2D3FC 0x876F # 0 +0x8EA2D3FD 0x876C # 0 +0x8EA2D3FE 0x877A # 0 +0x8EA2D4A1 0x876E # 0 +0x8EA2D4A2 0x875C # 0 +0x8EA2D4A3 0x8765 # 0 +0x8EA2D4A4 0x874F # 0 +0x8EA2D4A5 0x877B # 0 +0x8EA2D4A6 0x8775 # 0 +0x8EA2D4A7 0x8762 # 0 +0x8EA2D4A8 0x8767 # 0 +0x8EA2D4A9 0x8769 # 0 +0x8EA2D4AA 0x885A # 0 +0x8EA2D4AB 0x8905 # 0 +0x8EA2D4AC 0x890C # 0 +0x8EA2D4AD 0x8914 # 0 +0x8EA2D4AE 0x890B # 0 +0x8EA2D4AF 0x8917 # 0 +0x8EA2D4B0 0x8918 # 0 +0x8EA2D4B1 0x8919 # 0 +0x8EA2D4B2 0x8906 # 0 +0x8EA2D4B3 0x8916 # 0 +0x8EA2D4B4 0x8911 # 0 +0x8EA2D4B5 0x890E # 0 +0x8EA2D4B6 0x8909 # 0 +0x8EA2D4B7 0x89A2 # 0 +0x8EA2D4B8 0x89A4 # 0 +0x8EA2D4B9 0x89A3 # 0 +0x8EA2D4BA 0x89ED # 0 +0x8EA2D4BB 0x89F0 # 0 +0x8EA2D4BC 0x89EC # 0 +0x8EA2D4BD 0x8ACF # 0 +0x8EA2D4BE 0x8AC6 # 0 +0x8EA2D4BF 0x8AB8 # 0 +0x8EA2D4C0 0x8AD3 # 0 +0x8EA2D4C1 0x8AD1 # 0 +0x8EA2D4C2 0x8AD4 # 0 +0x8EA2D4C3 0x8AD5 # 0 +0x8EA2D4C4 0x8ABB # 0 +0x8EA2D4C5 0x8AD7 # 0 +0x8EA2D4C6 0x8ABE # 0 +0x8EA2D4C7 0x8AC0 # 0 +0x8EA2D4C8 0x8AC5 # 0 +0x8EA2D4C9 0x8AD8 # 0 +0x8EA2D4CA 0x8AC3 # 0 +0x8EA2D4CB 0x8ABA # 0 +0x8EA2D4CC 0x8ABD # 0 +0x8EA2D4CD 0x8AD9 # 0 +0x8EA2D4CE 0x8C3E # 0 +0x8EA2D4CF 0x8C4D # 0 +0x8EA2D4D0 0x8C8F # 0 +0x8EA2D4D1 0x8CE5 # 0 +0x8EA2D4D2 0x8CDF # 0 +0x8EA2D4D3 0x8CD9 # 0 +0x8EA2D4D4 0x8CE8 # 0 +0x8EA2D4D5 0x8CDA # 0 +0x8EA2D4D6 0x8CDD # 0 +0x8EA2D4D7 0x8CE7 # 0 +0x8EA2D4D8 0x8DA0 # 0 +0x8EA2D4D9 0x8D9C # 0 +0x8EA2D4DA 0x8DA1 # 0 +0x8EA2D4DB 0x8D9B # 0 +0x8EA2D4DC 0x8E20 # 0 +0x8EA2D4DD 0x8E23 # 0 +0x8EA2D4DE 0x8E25 # 0 +0x8EA2D4DF 0x8E24 # 0 +0x8EA2D4E0 0x8E2E # 0 +0x8EA2D4E1 0x8E15 # 0 +0x8EA2D4E2 0x8E1B # 0 +0x8EA2D4E3 0x8E16 # 0 +0x8EA2D4E4 0x8E11 # 0 +0x8EA2D4E5 0x8E19 # 0 +0x8EA2D4E6 0x8E26 # 0 +0x8EA2D4E7 0x8E27 # 0 +0x8EA2D4E8 0x8E14 # 0 +0x8EA2D4E9 0x8E12 # 0 +0x8EA2D4EA 0x8E18 # 0 +0x8EA2D4EB 0x8E13 # 0 +0x8EA2D4EC 0x8E1C # 0 +0x8EA2D4ED 0x8E17 # 0 +0x8EA2D4EE 0x8E1A # 0 +0x8EA2D4EF 0x8F2C # 0 +0x8EA2D4F0 0x8F24 # 0 +0x8EA2D4F1 0x8F18 # 0 +0x8EA2D4F2 0x8F1A # 0 +0x8EA2D4F3 0x8F20 # 0 +0x8EA2D4F4 0x8F23 # 0 +0x8EA2D4F5 0x8F16 # 0 +0x8EA2D4F6 0x8F17 # 0 +0x8EA2D4F7 0x9073 # 0 +0x8EA2D4F8 0x9070 # 0 +0x8EA2D4F9 0x906F # 0 +0x8EA2D4FA 0x9067 # 0 +0x8EA2D4FB 0x906B # 0 +0x8EA2D4FC 0x912F # 0 +0x8EA2D4FD 0x912B # 0 +0x8EA2D4FE 0x9129 # 0 +0x8EA2D5A1 0x912A # 0 +0x8EA2D5A2 0x9132 # 0 +0x8EA2D5A3 0x9126 # 0 +0x8EA2D5A4 0x912E # 0 +0x8EA2D5A5 0x9185 # 0 +0x8EA2D5A6 0x9186 # 0 +0x8EA2D5A7 0x918A # 0 +0x8EA2D5A8 0x9181 # 0 +0x8EA2D5A9 0x9182 # 0 +0x8EA2D5AA 0x9184 # 0 +0x8EA2D5AB 0x9180 # 0 +0x8EA2D5AC 0x92D0 # 0 +0x8EA2D5AD 0x92C3 # 0 +0x8EA2D5AE 0x92C4 # 0 +0x8EA2D5AF 0x92C0 # 0 +0x8EA2D5B0 0x92D9 # 0 +0x8EA2D5B1 0x92B6 # 0 +0x8EA2D5B2 0x92CF # 0 +0x8EA2D5B3 0x92F1 # 0 +0x8EA2D5B4 0x92DF # 0 +0x8EA2D5B5 0x92D8 # 0 +0x8EA2D5B6 0x92E9 # 0 +0x8EA2D5B7 0x92D7 # 0 +0x8EA2D5B8 0x92DD # 0 +0x8EA2D5B9 0x92CC # 0 +0x8EA2D5BA 0x92EF # 0 +0x8EA2D5BB 0x92C2 # 0 +0x8EA2D5BC 0x92E8 # 0 +0x8EA2D5BD 0x92CA # 0 +0x8EA2D5BE 0x92C8 # 0 +0x8EA2D5BF 0x92CE # 0 +0x8EA2D5C0 0x92E6 # 0 +0x8EA2D5C1 0x92CD # 0 +0x8EA2D5C2 0x92D5 # 0 +0x8EA2D5C3 0x92C9 # 0 +0x8EA2D5C4 0x92E0 # 0 +0x8EA2D5C5 0x92DE # 0 +0x8EA2D5C6 0x92E7 # 0 +0x8EA2D5C7 0x92D1 # 0 +0x8EA2D5C8 0x92D3 # 0 +0x8EA2D5C9 0x92B5 # 0 +0x8EA2D5CA 0x92E1 # 0 +0x8EA2D5CB 0x9325 # 0 +0x8EA2D5CC 0x92C6 # 0 +0x8EA2D5CD 0x92B4 # 0 +0x8EA2D5CE 0x957C # 0 +0x8EA2D5CF 0x95AC # 0 +0x8EA2D5D0 0x95AB # 0 +0x8EA2D5D1 0x95AE # 0 +0x8EA2D5D2 0x95B0 # 0 +0x8EA2D5D3 0x96A4 # 0 +0x8EA2D5D4 0x96A2 # 0 +0x8EA2D5D5 0x96D3 # 0 +0x8EA2D5D6 0x9705 # 0 +0x8EA2D5D7 0x9708 # 0 +0x8EA2D5D8 0x9702 # 0 +0x8EA2D5D9 0x975A # 0 +0x8EA2D5DA 0x978A # 0 +0x8EA2D5DB 0x978E # 0 +0x8EA2D5DC 0x9788 # 0 +0x8EA2D5DD 0x97D0 # 0 +0x8EA2D5DE 0x97CF # 0 +0x8EA2D5DF 0x981E # 0 +0x8EA2D5E0 0x981D # 0 +0x8EA2D5E1 0x9826 # 0 +0x8EA2D5E2 0x9829 # 0 +0x8EA2D5E3 0x9828 # 0 +0x8EA2D5E4 0x9820 # 0 +0x8EA2D5E5 0x981B # 0 +0x8EA2D5E6 0x9827 # 0 +0x8EA2D5E7 0x98B2 # 0 +0x8EA2D5E8 0x9908 # 0 +0x8EA2D5E9 0x98FA # 0 +0x8EA2D5EA 0x9911 # 0 +0x8EA2D5EB 0x9914 # 0 +0x8EA2D5EC 0x9916 # 0 +0x8EA2D5ED 0x9917 # 0 +0x8EA2D5EE 0x9915 # 0 +0x8EA2D5EF 0x99DC # 0 +0x8EA2D5F0 0x99CD # 0 +0x8EA2D5F1 0x99CF # 0 +0x8EA2D5F2 0x99D3 # 0 +0x8EA2D5F3 0x99D4 # 0 +0x8EA2D5F4 0x99CE # 0 +0x8EA2D5F5 0x99C9 # 0 +0x8EA2D5F6 0x99D6 # 0 +0x8EA2D5F7 0x99D8 # 0 +0x8EA2D5F8 0x99CB # 0 +0x8EA2D5F9 0x99D7 # 0 +0x8EA2D5FA 0x99CC # 0 +0x8EA2D5FB 0x9AB3 # 0 +0x8EA2D5FC 0x9AEC # 0 +0x8EA2D5FD 0x9AEB # 0 +0x8EA2D5FE 0x9AF3 # 0 +0x8EA2D6A1 0x9AF2 # 0 +0x8EA2D6A2 0x9AF1 # 0 +0x8EA2D6A3 0x9B46 # 0 +0x8EA2D6A4 0x9B43 # 0 +0x8EA2D6A5 0x9B67 # 0 +0x8EA2D6A6 0x9B74 # 0 +0x8EA2D6A7 0x9B71 # 0 +0x8EA2D6A8 0x9B66 # 0 +0x8EA2D6A9 0x9B76 # 0 +0x8EA2D6AA 0x9B75 # 0 +0x8EA2D6AB 0x9B70 # 0 +0x8EA2D6AC 0x9B68 # 0 +0x8EA2D6AD 0x9B64 # 0 +0x8EA2D6AE 0x9B6C # 0 +0x8EA2D6AF 0x9CFC # 0 +0x8EA2D6B0 0x9CFA # 0 +0x8EA2D6B1 0x9CFD # 0 +0x8EA2D6B2 0x9CFF # 0 +0x8EA2D6B3 0x9CF7 # 0 +0x8EA2D6B4 0x9D07 # 0 +0x8EA2D6B5 0x9D00 # 0 +0x8EA2D6B6 0x9CF9 # 0 +0x8EA2D6B7 0x9CFB # 0 +0x8EA2D6B8 0x9D08 # 0 +0x8EA2D6B9 0x9D05 # 0 +0x8EA2D6BA 0x9D04 # 0 +0x8EA2D6BB 0x9E83 # 0 +0x8EA2D6BC 0x9ED3 # 0 +0x8EA2D6BD 0x9F0F # 0 +0x8EA2D6BE 0x9F10 # 0 +0x8EA2D6BF 0x511C # 0 +0x8EA2D6C0 0x5113 # 0 +0x8EA2D6C1 0x5117 # 0 +0x8EA2D6C2 0x511A # 0 +0x8EA2D6C3 0x5111 # 0 +0x8EA2D6C4 0x51DE # 0 +0x8EA2D6C5 0x5334 # 0 +0x8EA2D6C6 0x53E1 # 0 +0x8EA2D6C7 0x5670 # 0 +0x8EA2D6C8 0x5660 # 0 +0x8EA2D6C9 0x566E # 0 +0x8EA2D6CA 0x5673 # 0 +0x8EA2D6CB 0x5666 # 0 +0x8EA2D6CC 0x5663 # 0 +0x8EA2D6CD 0x566D # 0 +0x8EA2D6CE 0x5672 # 0 +0x8EA2D6CF 0x565E # 0 +0x8EA2D6D0 0x5677 # 0 +0x8EA2D6D1 0x571C # 0 +0x8EA2D6D2 0x571B # 0 +0x8EA2D6D3 0x58C8 # 0 +0x8EA2D6D4 0x58BD # 0 +0x8EA2D6D5 0x58C9 # 0 +0x8EA2D6D6 0x58BF # 0 +0x8EA2D6D7 0x58BA # 0 +0x8EA2D6D8 0x58C2 # 0 +0x8EA2D6D9 0x58BC # 0 +0x8EA2D6DA 0x58C6 # 0 +0x8EA2D6DB 0x5B17 # 0 +0x8EA2D6DC 0x5B19 # 0 +0x8EA2D6DD 0x5B1B # 0 +0x8EA2D6DE 0x5B21 # 0 +0x8EA2D6DF 0x5B14 # 0 +0x8EA2D6E0 0x5B13 # 0 +0x8EA2D6E1 0x5B10 # 0 +0x8EA2D6E2 0x5B16 # 0 +0x8EA2D6E3 0x5B28 # 0 +0x8EA2D6E4 0x5B1A # 0 +0x8EA2D6E5 0x5B20 # 0 +0x8EA2D6E6 0x5B1E # 0 +0x8EA2D6E7 0x5BEF # 0 +0x8EA2D6E8 0x5DAC # 0 +0x8EA2D6E9 0x5DB1 # 0 +0x8EA2D6EA 0x5DA9 # 0 +0x8EA2D6EB 0x5DA7 # 0 +0x8EA2D6EC 0x5DB5 # 0 +0x8EA2D6ED 0x5DB0 # 0 +0x8EA2D6EE 0x5DAE # 0 +0x8EA2D6EF 0x5DAA # 0 +0x8EA2D6F0 0x5DA8 # 0 +0x8EA2D6F1 0x5DB2 # 0 +0x8EA2D6F2 0x5DAD # 0 +0x8EA2D6F3 0x5DAF # 0 +0x8EA2D6F4 0x5DB4 # 0 +0x8EA2D6F5 0x5E67 # 0 +0x8EA2D6F6 0x5E68 # 0 +0x8EA2D6F7 0x5E66 # 0 +0x8EA2D6F8 0x5E6F # 0 +0x8EA2D6F9 0x5EE9 # 0 +0x8EA2D6FA 0x5EE7 # 0 +0x8EA2D6FB 0x5EE6 # 0 +0x8EA2D6FC 0x5EE8 # 0 +0x8EA2D6FD 0x5EE5 # 0 +0x8EA2D6FE 0x5F4B # 0 +0x8EA2D7A1 0x5FBC # 0 +0x8EA2D7A2 0x5FBB # 0 +0x8EA2D7A3 0x619D # 0 +0x8EA2D7A4 0x61A8 # 0 +0x8EA2D7A5 0x6196 # 0 +0x8EA2D7A6 0x61C5 # 0 +0x8EA2D7A7 0x61B4 # 0 +0x8EA2D7A8 0x61C6 # 0 +0x8EA2D7A9 0x61C1 # 0 +0x8EA2D7AA 0x61CC # 0 +0x8EA2D7AB 0x61BA # 0 +0x8EA2D7AC 0x61BF # 0 +0x8EA2D7AD 0x61B8 # 0 +0x8EA2D7AE 0x618C # 0 +0x8EA2D7AF 0x64D7 # 0 +0x8EA2D7B0 0x64D6 # 0 +0x8EA2D7B1 0x64D0 # 0 +0x8EA2D7B2 0x64CF # 0 +0x8EA2D7B3 0x64C9 # 0 +0x8EA2D7B4 0x64BD # 0 +0x8EA2D7B5 0x6489 # 0 +0x8EA2D7B6 0x64C3 # 0 +0x8EA2D7B7 0x64DB # 0 +0x8EA2D7B8 0x64F3 # 0 +0x8EA2D7B9 0x64D9 # 0 +0x8EA2D7BA 0x6533 # 0 +0x8EA2D7BB 0x657F # 0 +0x8EA2D7BC 0x657C # 0 +0x8EA2D7BD 0x65A2 # 0 +0x8EA2D7BE 0x66C8 # 0 +0x8EA2D7BF 0x66BE # 0 +0x8EA2D7C0 0x66C0 # 0 +0x8EA2D7C1 0x66CA # 0 +0x8EA2D7C2 0x66CB # 0 +0x8EA2D7C3 0x66CF # 0 +0x8EA2D7C4 0x66BD # 0 +0x8EA2D7C5 0x66BB # 0 +0x8EA2D7C6 0x66BA # 0 +0x8EA2D7C7 0x66CC # 0 +0x8EA2D7C8 0x6723 # 0 +0x8EA2D7C9 0x6A34 # 0 +0x8EA2D7CA 0x6A66 # 0 +0x8EA2D7CB 0x6A49 # 0 +0x8EA2D7CC 0x6A67 # 0 +0x8EA2D7CD 0x6A32 # 0 +0x8EA2D7CE 0x6A68 # 0 +0x8EA2D7CF 0x6A3E # 0 +0x8EA2D7D0 0x6A5D # 0 +0x8EA2D7D1 0x6A6D # 0 +0x8EA2D7D2 0x6A76 # 0 +0x8EA2D7D3 0x6A5B # 0 +0x8EA2D7D4 0x6A51 # 0 +0x8EA2D7D5 0x6A28 # 0 +0x8EA2D7D6 0x6A5A # 0 +0x8EA2D7D7 0x6A3B # 0 +0x8EA2D7D8 0x6A3F # 0 +0x8EA2D7D9 0x6A41 # 0 +0x8EA2D7DA 0x6A6A # 0 +0x8EA2D7DB 0x6A64 # 0 +0x8EA2D7DC 0x6A50 # 0 +0x8EA2D7DD 0x6A4F # 0 +0x8EA2D7DE 0x6A54 # 0 +0x8EA2D7DF 0x6A6F # 0 +0x8EA2D7E0 0x6A69 # 0 +0x8EA2D7E1 0x6A60 # 0 +0x8EA2D7E2 0x6A3C # 0 +0x8EA2D7E3 0x6A5E # 0 +0x8EA2D7E4 0x6A56 # 0 +0x8EA2D7E5 0x6A55 # 0 +0x8EA2D7E6 0x6A4D # 0 +0x8EA2D7E7 0x6A4E # 0 +0x8EA2D7E8 0x6A46 # 0 +0x8EA2D7E9 0x6B55 # 0 +0x8EA2D7EA 0x6B54 # 0 +0x8EA2D7EB 0x6B56 # 0 +0x8EA2D7EC 0x6BA7 # 0 +0x8EA2D7ED 0x6BAA # 0 +0x8EA2D7EE 0x6BAB # 0 +0x8EA2D7EF 0x6BC8 # 0 +0x8EA2D7F0 0x6BC7 # 0 +0x8EA2D7F1 0x6C04 # 0 +0x8EA2D7F2 0x6C03 # 0 +0x8EA2D7F3 0x6C06 # 0 +0x8EA2D7F4 0x6FAD # 0 +0x8EA2D7F5 0x6FCB # 0 +0x8EA2D7F6 0x6FA3 # 0 +0x8EA2D7F7 0x6FC7 # 0 +0x8EA2D7F8 0x6FBC # 0 +0x8EA2D7F9 0x6FCE # 0 +0x8EA2D7FA 0x6FC8 # 0 +0x8EA2D7FB 0x6F5E # 0 +0x8EA2D7FC 0x6FC4 # 0 +0x8EA2D7FD 0x6FBD # 0 +0x8EA2D7FE 0x6F9E # 0 +0x8EA2D8A1 0x6FCA # 0 +0x8EA2D8A2 0x6FA8 # 0 +0x8EA2D8A3 0x7004 # 0 +0x8EA2D8A4 0x6FA5 # 0 +0x8EA2D8A5 0x6FAE # 0 +0x8EA2D8A6 0x6FBA # 0 +0x8EA2D8A7 0x6FAC # 0 +0x8EA2D8A8 0x6FAA # 0 +0x8EA2D8A9 0x6FCF # 0 +0x8EA2D8AA 0x6FBF # 0 +0x8EA2D8AB 0x6FB8 # 0 +0x8EA2D8AC 0x6FA2 # 0 +0x8EA2D8AD 0x6FC9 # 0 +0x8EA2D8AE 0x6FAB # 0 +0x8EA2D8AF 0x6FCD # 0 +0x8EA2D8B0 0x6FAF # 0 +0x8EA2D8B1 0x6FB2 # 0 +0x8EA2D8B2 0x6FB0 # 0 +0x8EA2D8B3 0x71C5 # 0 +0x8EA2D8B4 0x71C2 # 0 +0x8EA2D8B5 0x71BF # 0 +0x8EA2D8B6 0x71B8 # 0 +0x8EA2D8B7 0x71D6 # 0 +0x8EA2D8B8 0x71C0 # 0 +0x8EA2D8B9 0x71C1 # 0 +0x8EA2D8BA 0x71CB # 0 +0x8EA2D8BB 0x71D4 # 0 +0x8EA2D8BC 0x71CA # 0 +0x8EA2D8BD 0x71C7 # 0 +0x8EA2D8BE 0x71CF # 0 +0x8EA2D8BF 0x71BD # 0 +0x8EA2D8C0 0x71D8 # 0 +0x8EA2D8C1 0x71BC # 0 +0x8EA2D8C2 0x71C6 # 0 +0x8EA2D8C3 0x71DA # 0 +0x8EA2D8C4 0x71DB # 0 +0x8EA2D8C5 0x729D # 0 +0x8EA2D8C6 0x729E # 0 +0x8EA2D8C7 0x7369 # 0 +0x8EA2D8C8 0x7366 # 0 +0x8EA2D8C9 0x7367 # 0 +0x8EA2D8CA 0x736C # 0 +0x8EA2D8CB 0x7365 # 0 +0x8EA2D8CC 0x736B # 0 +0x8EA2D8CD 0x736A # 0 +0x8EA2D8CE 0x747F # 0 +0x8EA2D8CF 0x749A # 0 +0x8EA2D8D0 0x74A0 # 0 +0x8EA2D8D1 0x7494 # 0 +0x8EA2D8D2 0x7492 # 0 +0x8EA2D8D3 0x7495 # 0 +0x8EA2D8D4 0x74A1 # 0 +0x8EA2D8D5 0x750B # 0 +0x8EA2D8D6 0x7580 # 0 +0x8EA2D8D7 0x762F # 0 +0x8EA2D8D8 0x762D # 0 +0x8EA2D8D9 0x7631 # 0 +0x8EA2D8DA 0x763D # 0 +0x8EA2D8DB 0x7633 # 0 +0x8EA2D8DC 0x763C # 0 +0x8EA2D8DD 0x7635 # 0 +0x8EA2D8DE 0x7632 # 0 +0x8EA2D8DF 0x7630 # 0 +0x8EA2D8E0 0x76BB # 0 +0x8EA2D8E1 0x76E6 # 0 +0x8EA2D8E2 0x779A # 0 +0x8EA2D8E3 0x779D # 0 +0x8EA2D8E4 0x77A1 # 0 +0x8EA2D8E5 0x779C # 0 +0x8EA2D8E6 0x779B # 0 +0x8EA2D8E7 0x77A2 # 0 +0x8EA2D8E8 0x77A3 # 0 +0x8EA2D8E9 0x7795 # 0 +0x8EA2D8EA 0x7799 # 0 +0x8EA2D8EB 0x7797 # 0 +0x8EA2D8EC 0x78DD # 0 +0x8EA2D8ED 0x78E9 # 0 +0x8EA2D8EE 0x78E5 # 0 +0x8EA2D8EF 0x78EA # 0 +0x8EA2D8F0 0x78DE # 0 +0x8EA2D8F1 0x78E3 # 0 +0x8EA2D8F2 0x78DB # 0 +0x8EA2D8F3 0x78E1 # 0 +0x8EA2D8F4 0x78E2 # 0 +0x8EA2D8F5 0x78ED # 0 +0x8EA2D8F6 0x78DF # 0 +0x8EA2D8F7 0x78E0 # 0 +0x8EA2D8F8 0x79A4 # 0 +0x8EA2D8F9 0x7A44 # 0 +0x8EA2D8FA 0x7A48 # 0 +0x8EA2D8FB 0x7A47 # 0 +0x8EA2D8FC 0x7AB6 # 0 +0x8EA2D8FD 0x7AB8 # 0 +0x8EA2D8FE 0x7AB5 # 0 +0x8EA2D9A1 0x7AB1 # 0 +0x8EA2D9A2 0x7AB7 # 0 +0x8EA2D9A3 0x7BDE # 0 +0x8EA2D9A4 0x7BE3 # 0 +0x8EA2D9A5 0x7BE7 # 0 +0x8EA2D9A6 0x7BDD # 0 +0x8EA2D9A7 0x7BD5 # 0 +0x8EA2D9A8 0x7BE5 # 0 +0x8EA2D9A9 0x7BDA # 0 +0x8EA2D9AA 0x7BE8 # 0 +0x8EA2D9AB 0x7BF9 # 0 +0x8EA2D9AC 0x7BD4 # 0 +0x8EA2D9AD 0x7BEA # 0 +0x8EA2D9AE 0x7BE2 # 0 +0x8EA2D9AF 0x7BDC # 0 +0x8EA2D9B0 0x7BEB # 0 +0x8EA2D9B1 0x7BD8 # 0 +0x8EA2D9B2 0x7BDF # 0 +0x8EA2D9B3 0x7CD2 # 0 +0x8EA2D9B4 0x7CD4 # 0 +0x8EA2D9B5 0x7CD7 # 0 +0x8EA2D9B6 0x7CD0 # 0 +0x8EA2D9B7 0x7CD1 # 0 +0x8EA2D9B8 0x7E12 # 0 +0x8EA2D9B9 0x7E21 # 0 +0x8EA2D9BA 0x7E17 # 0 +0x8EA2D9BB 0x7E0C # 0 +0x8EA2D9BC 0x7E1F # 0 +0x8EA2D9BD 0x7E20 # 0 +0x8EA2D9BE 0x7E13 # 0 +0x8EA2D9BF 0x7E0E # 0 +0x8EA2D9C0 0x7E1C # 0 +0x8EA2D9C1 0x7E15 # 0 +0x8EA2D9C2 0x7E1A # 0 +0x8EA2D9C3 0x7E22 # 0 +0x8EA2D9C4 0x7E0B # 0 +0x8EA2D9C5 0x7E0F # 0 +0x8EA2D9C6 0x7E16 # 0 +0x8EA2D9C7 0x7E0D # 0 +0x8EA2D9C8 0x7E14 # 0 +0x8EA2D9C9 0x7E25 # 0 +0x8EA2D9CA 0x7E24 # 0 +0x8EA2D9CB 0x7F43 # 0 +0x8EA2D9CC 0x7F7B # 0 +0x8EA2D9CD 0x7F7C # 0 +0x8EA2D9CE 0x7F7A # 0 +0x8EA2D9CF 0x7FB1 # 0 +0x8EA2D9D0 0x7FEF # 0 +0x8EA2D9D1 0x802A # 0 +0x8EA2D9D2 0x8029 # 0 +0x8EA2D9D3 0x806C # 0 +0x8EA2D9D4 0x81B1 # 0 +0x8EA2D9D5 0x81A6 # 0 +0x8EA2D9D6 0x81AE # 0 +0x8EA2D9D7 0x81B9 # 0 +0x8EA2D9D8 0x81B5 # 0 +0x8EA2D9D9 0x81AB # 0 +0x8EA2D9DA 0x81B0 # 0 +0x8EA2D9DB 0x81AC # 0 +0x8EA2D9DC 0x81B4 # 0 +0x8EA2D9DD 0x81B2 # 0 +0x8EA2D9DE 0x81B7 # 0 +0x8EA2D9DF 0x81A7 # 0 +0x8EA2D9E0 0x81F2 # 0 +0x8EA2D9E1 0x8255 # 0 +0x8EA2D9E2 0x8256 # 0 +0x8EA2D9E3 0x8257 # 0 +0x8EA2D9E4 0x8556 # 0 +0x8EA2D9E5 0x8545 # 0 +0x8EA2D9E6 0x856B # 0 +0x8EA2D9E7 0x854D # 0 +0x8EA2D9E8 0x8553 # 0 +0x8EA2D9E9 0x8561 # 0 +0x8EA2D9EA 0x8558 # 0 +0x8EA2D9EB 0x8540 # 0 +0x8EA2D9EC 0x8546 # 0 +0x8EA2D9ED 0x8564 # 0 +0x8EA2D9EE 0x8541 # 0 +0x8EA2D9EF 0x8562 # 0 +0x8EA2D9F0 0x8544 # 0 +0x8EA2D9F1 0x8551 # 0 +0x8EA2D9F2 0x8547 # 0 +0x8EA2D9F3 0x8563 # 0 +0x8EA2D9F4 0x853E # 0 +0x8EA2D9F5 0x855B # 0 +0x8EA2D9F6 0x8571 # 0 +0x8EA2D9F7 0x854E # 0 +0x8EA2D9F8 0x856E # 0 +0x8EA2D9F9 0x8575 # 0 +0x8EA2D9FA 0x8555 # 0 +0x8EA2D9FB 0x8567 # 0 +0x8EA2D9FC 0x8560 # 0 +0x8EA2D9FD 0x858C # 0 +0x8EA2D9FE 0x8566 # 0 +0x8EA2DAA1 0x855D # 0 +0x8EA2DAA2 0x8554 # 0 +0x8EA2DAA3 0x8565 # 0 +0x8EA2DAA4 0x856C # 0 +0x8EA2DAA5 0x8663 # 0 +0x8EA2DAA6 0x8665 # 0 +0x8EA2DAA7 0x8664 # 0 +0x8EA2DAA8 0x87A4 # 0 +0x8EA2DAA9 0x879B # 0 +0x8EA2DAAA 0x878F # 0 +0x8EA2DAAB 0x8797 # 0 +0x8EA2DAAC 0x8793 # 0 +0x8EA2DAAD 0x8792 # 0 +0x8EA2DAAE 0x8788 # 0 +0x8EA2DAAF 0x8781 # 0 +0x8EA2DAB0 0x8796 # 0 +0x8EA2DAB1 0x8798 # 0 +0x8EA2DAB2 0x8779 # 0 +0x8EA2DAB3 0x8787 # 0 +0x8EA2DAB4 0x87A3 # 0 +0x8EA2DAB5 0x8785 # 0 +0x8EA2DAB6 0x8790 # 0 +0x8EA2DAB7 0x8791 # 0 +0x8EA2DAB8 0x879D # 0 +0x8EA2DAB9 0x8784 # 0 +0x8EA2DABA 0x8794 # 0 +0x8EA2DABB 0x879C # 0 +0x8EA2DABC 0x879A # 0 +0x8EA2DABD 0x8789 # 0 +0x8EA2DABE 0x891E # 0 +0x8EA2DABF 0x8926 # 0 +0x8EA2DAC0 0x8930 # 0 +0x8EA2DAC1 0x892D # 0 +0x8EA2DAC2 0x892E # 0 +0x8EA2DAC3 0x8927 # 0 +0x8EA2DAC4 0x8931 # 0 +0x8EA2DAC5 0x8922 # 0 +0x8EA2DAC6 0x8929 # 0 +0x8EA2DAC7 0x8923 # 0 +0x8EA2DAC8 0x892F # 0 +0x8EA2DAC9 0x892C # 0 +0x8EA2DACA 0x891F # 0 +0x8EA2DACB 0x89F1 # 0 +0x8EA2DACC 0x8AE0 # 0 +0x8EA2DACD 0x8AE2 # 0 +0x8EA2DACE 0x8AF2 # 0 +0x8EA2DACF 0x8AF4 # 0 +0x8EA2DAD0 0x8AF5 # 0 +0x8EA2DAD1 0x8ADD # 0 +0x8EA2DAD2 0x8B14 # 0 +0x8EA2DAD3 0x8AE4 # 0 +0x8EA2DAD4 0x8ADF # 0 +0x8EA2DAD5 0x8AF0 # 0 +0x8EA2DAD6 0x8AC8 # 0 +0x8EA2DAD7 0x8ADE # 0 +0x8EA2DAD8 0x8AE1 # 0 +0x8EA2DAD9 0x8AE8 # 0 +0x8EA2DADA 0x8AFF # 0 +0x8EA2DADB 0x8AEF # 0 +0x8EA2DADC 0x8AFB # 0 +0x8EA2DADD 0x8C91 # 0 +0x8EA2DADE 0x8C92 # 0 +0x8EA2DADF 0x8C90 # 0 +0x8EA2DAE0 0x8CF5 # 0 +0x8EA2DAE1 0x8CEE # 0 +0x8EA2DAE2 0x8CF1 # 0 +0x8EA2DAE3 0x8CF0 # 0 +0x8EA2DAE4 0x8CF3 # 0 +0x8EA2DAE5 0x8D6C # 0 +0x8EA2DAE6 0x8D6E # 0 +0x8EA2DAE7 0x8DA5 # 0 +0x8EA2DAE8 0x8DA7 # 0 +0x8EA2DAE9 0x8E33 # 0 +0x8EA2DAEA 0x8E3E # 0 +0x8EA2DAEB 0x8E38 # 0 +0x8EA2DAEC 0x8E40 # 0 +0x8EA2DAED 0x8E45 # 0 +0x8EA2DAEE 0x8E36 # 0 +0x8EA2DAEF 0x8E3C # 0 +0x8EA2DAF0 0x8E3D # 0 +0x8EA2DAF1 0x8E41 # 0 +0x8EA2DAF2 0x8E30 # 0 +0x8EA2DAF3 0x8E3F # 0 +0x8EA2DAF4 0x8EBD # 0 +0x8EA2DAF5 0x8F36 # 0 +0x8EA2DAF6 0x8F2E # 0 +0x8EA2DAF7 0x8F35 # 0 +0x8EA2DAF8 0x8F32 # 0 +0x8EA2DAF9 0x8F39 # 0 +0x8EA2DAFA 0x8F37 # 0 +0x8EA2DAFB 0x8F34 # 0 +0x8EA2DAFC 0x9076 # 0 +0x8EA2DAFD 0x9079 # 0 +0x8EA2DAFE 0x907B # 0 +0x8EA2DBA1 0x9086 # 0 +0x8EA2DBA2 0x90FA # 0 +0x8EA2DBA3 0x9133 # 0 +0x8EA2DBA4 0x9135 # 0 +0x8EA2DBA5 0x9136 # 0 +0x8EA2DBA6 0x9193 # 0 +0x8EA2DBA7 0x9190 # 0 +0x8EA2DBA8 0x9191 # 0 +0x8EA2DBA9 0x918D # 0 +0x8EA2DBAA 0x918F # 0 +0x8EA2DBAB 0x9327 # 0 +0x8EA2DBAC 0x931E # 0 +0x8EA2DBAD 0x9308 # 0 +0x8EA2DBAE 0x931F # 0 +0x8EA2DBAF 0x9306 # 0 +0x8EA2DBB0 0x930F # 0 +0x8EA2DBB1 0x937A # 0 +0x8EA2DBB2 0x9338 # 0 +0x8EA2DBB3 0x933C # 0 +0x8EA2DBB4 0x931B # 0 +0x8EA2DBB5 0x9323 # 0 +0x8EA2DBB6 0x9312 # 0 +0x8EA2DBB7 0x9301 # 0 +0x8EA2DBB8 0x9346 # 0 +0x8EA2DBB9 0x932D # 0 +0x8EA2DBBA 0x930E # 0 +0x8EA2DBBB 0x930D # 0 +0x8EA2DBBC 0x92CB # 0 +0x8EA2DBBD 0x931D # 0 +0x8EA2DBBE 0x92FA # 0 +0x8EA2DBBF 0x9313 # 0 +0x8EA2DBC0 0x92F9 # 0 +0x8EA2DBC1 0x92F7 # 0 +0x8EA2DBC2 0x9334 # 0 +0x8EA2DBC3 0x9302 # 0 +0x8EA2DBC4 0x9324 # 0 +0x8EA2DBC5 0x92FF # 0 +0x8EA2DBC6 0x9329 # 0 +0x8EA2DBC7 0x9339 # 0 +0x8EA2DBC8 0x9335 # 0 +0x8EA2DBC9 0x932A # 0 +0x8EA2DBCA 0x9314 # 0 +0x8EA2DBCB 0x930C # 0 +0x8EA2DBCC 0x930B # 0 +0x8EA2DBCD 0x92FE # 0 +0x8EA2DBCE 0x9309 # 0 +0x8EA2DBCF 0x9300 # 0 +0x8EA2DBD0 0x92FB # 0 +0x8EA2DBD1 0x9316 # 0 +0x8EA2DBD2 0x95BC # 0 +0x8EA2DBD3 0x95CD # 0 +0x8EA2DBD4 0x95BE # 0 +0x8EA2DBD5 0x95B9 # 0 +0x8EA2DBD6 0x95BA # 0 +0x8EA2DBD7 0x95B6 # 0 +0x8EA2DBD8 0x95BF # 0 +0x8EA2DBD9 0x95B5 # 0 +0x8EA2DBDA 0x95BD # 0 +0x8EA2DBDB 0x96A9 # 0 +0x8EA2DBDC 0x96D4 # 0 +0x8EA2DBDD 0x970B # 0 +0x8EA2DBDE 0x9712 # 0 +0x8EA2DBDF 0x9710 # 0 +0x8EA2DBE0 0x9799 # 0 +0x8EA2DBE1 0x9797 # 0 +0x8EA2DBE2 0x9794 # 0 +0x8EA2DBE3 0x97F0 # 0 +0x8EA2DBE4 0x97F8 # 0 +0x8EA2DBE5 0x9835 # 0 +0x8EA2DBE6 0x982F # 0 +0x8EA2DBE7 0x9832 # 0 +0x8EA2DBE8 0x9924 # 0 +0x8EA2DBE9 0x991F # 0 +0x8EA2DBEA 0x9927 # 0 +0x8EA2DBEB 0x9929 # 0 +0x8EA2DBEC 0x999E # 0 +0x8EA2DBED 0x99EE # 0 +0x8EA2DBEE 0x99EC # 0 +0x8EA2DBEF 0x99E5 # 0 +0x8EA2DBF0 0x99E4 # 0 +0x8EA2DBF1 0x99F0 # 0 +0x8EA2DBF2 0x99E3 # 0 +0x8EA2DBF3 0x99EA # 0 +0x8EA2DBF4 0x99E9 # 0 +0x8EA2DBF5 0x99E7 # 0 +0x8EA2DBF6 0x9AB9 # 0 +0x8EA2DBF7 0x9ABF # 0 +0x8EA2DBF8 0x9AB4 # 0 +0x8EA2DBF9 0x9ABB # 0 +0x8EA2DBFA 0x9AF6 # 0 +0x8EA2DBFB 0x9AFA # 0 +0x8EA2DBFC 0x9AF9 # 0 +0x8EA2DBFD 0x9AF7 # 0 +0x8EA2DBFE 0x9B33 # 0 +0x8EA2DCA1 0x9B80 # 0 +0x8EA2DCA2 0x9B85 # 0 +0x8EA2DCA3 0x9B87 # 0 +0x8EA2DCA4 0x9B7C # 0 +0x8EA2DCA5 0x9B7E # 0 +0x8EA2DCA6 0x9B7B # 0 +0x8EA2DCA7 0x9B82 # 0 +0x8EA2DCA8 0x9B93 # 0 +0x8EA2DCA9 0x9B92 # 0 +0x8EA2DCAA 0x9B90 # 0 +0x8EA2DCAB 0x9B7A # 0 +0x8EA2DCAC 0x9B95 # 0 +0x8EA2DCAD 0x9B7D # 0 +0x8EA2DCAE 0x9B88 # 0 +0x8EA2DCAF 0x9D25 # 0 +0x8EA2DCB0 0x9D17 # 0 +0x8EA2DCB1 0x9D20 # 0 +0x8EA2DCB2 0x9D1E # 0 +0x8EA2DCB3 0x9D14 # 0 +0x8EA2DCB4 0x9D29 # 0 +0x8EA2DCB5 0x9D1D # 0 +0x8EA2DCB6 0x9D18 # 0 +0x8EA2DCB7 0x9D22 # 0 +0x8EA2DCB8 0x9D10 # 0 +0x8EA2DCB9 0x9D19 # 0 +0x8EA2DCBA 0x9D1F # 0 +0x8EA2DCBB 0x9E88 # 0 +0x8EA2DCBC 0x9E86 # 0 +0x8EA2DCBD 0x9E87 # 0 +0x8EA2DCBE 0x9EAE # 0 +0x8EA2DCBF 0x9EAD # 0 +0x8EA2DCC0 0x9ED5 # 0 +0x8EA2DCC1 0x9ED6 # 0 +0x8EA2DCC2 0x9EFA # 0 +0x8EA2DCC3 0x9F12 # 0 +0x8EA2DCC4 0x9F3D # 0 +0x8EA2DCC5 0x5126 # 0 +0x8EA2DCC6 0x5125 # 0 +0x8EA2DCC7 0x5122 # 0 +0x8EA2DCC8 0x5124 # 0 +0x8EA2DCC9 0x5120 # 0 +0x8EA2DCCA 0x5129 # 0 +0x8EA2DCCB 0x52F4 # 0 +0x8EA2DCCC 0x5693 # 0 +0x8EA2DCCD 0x568C # 0 +0x8EA2DCCE 0x568D # 0 +0x8EA2DCCF 0x5686 # 0 +0x8EA2DCD0 0x5684 # 0 +0x8EA2DCD1 0x5683 # 0 +0x8EA2DCD2 0x567E # 0 +0x8EA2DCD3 0x5682 # 0 +0x8EA2DCD4 0x567F # 0 +0x8EA2DCD5 0x5681 # 0 +0x8EA2DCD6 0x58D6 # 0 +0x8EA2DCD7 0x58D4 # 0 +0x8EA2DCD8 0x58CF # 0 +0x8EA2DCD9 0x58D2 # 0 +0x8EA2DCDA 0x5B2D # 0 +0x8EA2DCDB 0x5B25 # 0 +0x8EA2DCDC 0x5B32 # 0 +0x8EA2DCDD 0x5B23 # 0 +0x8EA2DCDE 0x5B2C # 0 +0x8EA2DCDF 0x5B27 # 0 +0x8EA2DCE0 0x5B26 # 0 +0x8EA2DCE1 0x5B2F # 0 +0x8EA2DCE2 0x5B2E # 0 +0x8EA2DCE3 0x5B7B # 0 +0x8EA2DCE4 0x5BF1 # 0 +0x8EA2DCE5 0x5BF2 # 0 +0x8EA2DCE6 0x5DB7 # 0 +0x8EA2DCE7 0x5E6C # 0 +0x8EA2DCE8 0x5E6A # 0 +0x8EA2DCE9 0x5FBE # 0 +0x8EA2DCEA 0x61C3 # 0 +0x8EA2DCEB 0x61B5 # 0 +0x8EA2DCEC 0x61BC # 0 +0x8EA2DCED 0x61E7 # 0 +0x8EA2DCEE 0x61E0 # 0 +0x8EA2DCEF 0x61E5 # 0 +0x8EA2DCF0 0x61E4 # 0 +0x8EA2DCF1 0x61E8 # 0 +0x8EA2DCF2 0x61DE # 0 +0x8EA2DCF3 0x64EF # 0 +0x8EA2DCF4 0x64E9 # 0 +0x8EA2DCF5 0x64E3 # 0 +0x8EA2DCF6 0x64EB # 0 +0x8EA2DCF7 0x64E4 # 0 +0x8EA2DCF8 0x64E8 # 0 +0x8EA2DCF9 0x6581 # 0 +0x8EA2DCFA 0x6580 # 0 +0x8EA2DCFB 0x65B6 # 0 +0x8EA2DCFC 0x65DA # 0 +0x8EA2DCFD 0x66D2 # 0 +0x8EA2DCFE 0x6A8D # 0 +0x8EA2DDA1 0x6A96 # 0 +0x8EA2DDA2 0x6A81 # 0 +0x8EA2DDA3 0x6AA5 # 0 +0x8EA2DDA4 0x6A89 # 0 +0x8EA2DDA5 0x6A9F # 0 +0x8EA2DDA6 0x6A9B # 0 +0x8EA2DDA7 0x6AA1 # 0 +0x8EA2DDA8 0x6A9E # 0 +0x8EA2DDA9 0x6A87 # 0 +0x8EA2DDAA 0x6A93 # 0 +0x8EA2DDAB 0x6A8E # 0 +0x8EA2DDAC 0x6A95 # 0 +0x8EA2DDAD 0x6A83 # 0 +0x8EA2DDAE 0x6AA8 # 0 +0x8EA2DDAF 0x6AA4 # 0 +0x8EA2DDB0 0x6A91 # 0 +0x8EA2DDB1 0x6A7F # 0 +0x8EA2DDB2 0x6AA6 # 0 +0x8EA2DDB3 0x6A9A # 0 +0x8EA2DDB4 0x6A85 # 0 +0x8EA2DDB5 0x6A8C # 0 +0x8EA2DDB6 0x6A92 # 0 +0x8EA2DDB7 0x6B5B # 0 +0x8EA2DDB8 0x6BAD # 0 +0x8EA2DDB9 0x6C09 # 0 +0x8EA2DDBA 0x6FCC # 0 +0x8EA2DDBB 0x6FA9 # 0 +0x8EA2DDBC 0x6FF4 # 0 +0x8EA2DDBD 0x6FD4 # 0 +0x8EA2DDBE 0x6FE3 # 0 +0x8EA2DDBF 0x6FDC # 0 +0x8EA2DDC0 0x6FED # 0 +0x8EA2DDC1 0x6FE7 # 0 +0x8EA2DDC2 0x6FE6 # 0 +0x8EA2DDC3 0x6FDE # 0 +0x8EA2DDC4 0x6FF2 # 0 +0x8EA2DDC5 0x6FDD # 0 +0x8EA2DDC6 0x6FE2 # 0 +0x8EA2DDC7 0x6FE8 # 0 +0x8EA2DDC8 0x71E1 # 0 +0x8EA2DDC9 0x71F1 # 0 +0x8EA2DDCA 0x71E8 # 0 +0x8EA2DDCB 0x71F2 # 0 +0x8EA2DDCC 0x71E4 # 0 +0x8EA2DDCD 0x71F0 # 0 +0x8EA2DDCE 0x71E2 # 0 +0x8EA2DDCF 0x7373 # 0 +0x8EA2DDD0 0x736E # 0 +0x8EA2DDD1 0x736F # 0 +0x8EA2DDD2 0x7497 # 0 +0x8EA2DDD3 0x74B2 # 0 +0x8EA2DDD4 0x74AB # 0 +0x8EA2DDD5 0x7490 # 0 +0x8EA2DDD6 0x74AA # 0 +0x8EA2DDD7 0x74AD # 0 +0x8EA2DDD8 0x74B1 # 0 +0x8EA2DDD9 0x74A5 # 0 +0x8EA2DDDA 0x74AF # 0 +0x8EA2DDDB 0x7510 # 0 +0x8EA2DDDC 0x7511 # 0 +0x8EA2DDDD 0x7512 # 0 +0x8EA2DDDE 0x750F # 0 +0x8EA2DDDF 0x7584 # 0 +0x8EA2DDE0 0x7643 # 0 +0x8EA2DDE1 0x7648 # 0 +0x8EA2DDE2 0x7649 # 0 +0x8EA2DDE3 0x7647 # 0 +0x8EA2DDE4 0x76A4 # 0 +0x8EA2DDE5 0x76E9 # 0 +0x8EA2DDE6 0x77B5 # 0 +0x8EA2DDE7 0x77AB # 0 +0x8EA2DDE8 0x77B2 # 0 +0x8EA2DDE9 0x77B7 # 0 +0x8EA2DDEA 0x77B6 # 0 +0x8EA2DDEB 0x77B4 # 0 +0x8EA2DDEC 0x77B1 # 0 +0x8EA2DDED 0x77A8 # 0 +0x8EA2DDEE 0x77F0 # 0 +0x8EA2DDEF 0x78F3 # 0 +0x8EA2DDF0 0x78FD # 0 +0x8EA2DDF1 0x7902 # 0 +0x8EA2DDF2 0x78FB # 0 +0x8EA2DDF3 0x78FC # 0 +0x8EA2DDF4 0x78FF # 0 +0x8EA2DDF5 0x78F2 # 0 +0x8EA2DDF6 0x7905 # 0 +0x8EA2DDF7 0x78F9 # 0 +0x8EA2DDF8 0x78FE # 0 +0x8EA2DDF9 0x7904 # 0 +0x8EA2DDFA 0x79AB # 0 +0x8EA2DDFB 0x79A8 # 0 +0x8EA2DDFC 0x7A5C # 0 +0x8EA2DDFD 0x7A5B # 0 +0x8EA2DDFE 0x7A56 # 0 +0x8EA2DEA1 0x7A58 # 0 +0x8EA2DEA2 0x7A54 # 0 +0x8EA2DEA3 0x7A5A # 0 +0x8EA2DEA4 0x7ABE # 0 +0x8EA2DEA5 0x7AC0 # 0 +0x8EA2DEA6 0x7AC1 # 0 +0x8EA2DEA7 0x7C05 # 0 +0x8EA2DEA8 0x7C0F # 0 +0x8EA2DEA9 0x7BF2 # 0 +0x8EA2DEAA 0x7C00 # 0 +0x8EA2DEAB 0x7BFF # 0 +0x8EA2DEAC 0x7BFB # 0 +0x8EA2DEAD 0x7C0E # 0 +0x8EA2DEAE 0x7BF4 # 0 +0x8EA2DEAF 0x7C0B # 0 +0x8EA2DEB0 0x7BF3 # 0 +0x8EA2DEB1 0x7C02 # 0 +0x8EA2DEB2 0x7C09 # 0 +0x8EA2DEB3 0x7C03 # 0 +0x8EA2DEB4 0x7C01 # 0 +0x8EA2DEB5 0x7BF8 # 0 +0x8EA2DEB6 0x7BFD # 0 +0x8EA2DEB7 0x7C06 # 0 +0x8EA2DEB8 0x7BF0 # 0 +0x8EA2DEB9 0x7BF1 # 0 +0x8EA2DEBA 0x7C10 # 0 +0x8EA2DEBB 0x7C0A # 0 +0x8EA2DEBC 0x7CE8 # 0 +0x8EA2DEBD 0x7E2D # 0 +0x8EA2DEBE 0x7E3C # 0 +0x8EA2DEBF 0x7E42 # 0 +0x8EA2DEC0 0x7E33 # 0 +0x8EA2DEC1 0x9848 # 0 +0x8EA2DEC2 0x7E38 # 0 +0x8EA2DEC3 0x7E2A # 0 +0x8EA2DEC4 0x7E49 # 0 +0x8EA2DEC5 0x7E40 # 0 +0x8EA2DEC6 0x7E47 # 0 +0x8EA2DEC7 0x7E29 # 0 +0x8EA2DEC8 0x7E4C # 0 +0x8EA2DEC9 0x7E30 # 0 +0x8EA2DECA 0x7E3B # 0 +0x8EA2DECB 0x7E36 # 0 +0x8EA2DECC 0x7E44 # 0 +0x8EA2DECD 0x7E3A # 0 +0x8EA2DECE 0x7F45 # 0 +0x8EA2DECF 0x7F7F # 0 +0x8EA2DED0 0x7F7E # 0 +0x8EA2DED1 0x7F7D # 0 +0x8EA2DED2 0x7FF4 # 0 +0x8EA2DED3 0x7FF2 # 0 +0x8EA2DED4 0x802C # 0 +0x8EA2DED5 0x81BB # 0 +0x8EA2DED6 0x81C4 # 0 +0x8EA2DED7 0x81CC # 0 +0x8EA2DED8 0x81CA # 0 +0x8EA2DED9 0x81C5 # 0 +0x8EA2DEDA 0x81C7 # 0 +0x8EA2DEDB 0x81BC # 0 +0x8EA2DEDC 0x81E9 # 0 +0x8EA2DEDD 0x825B # 0 +0x8EA2DEDE 0x825A # 0 +0x8EA2DEDF 0x825C # 0 +0x8EA2DEE0 0x8583 # 0 +0x8EA2DEE1 0x8580 # 0 +0x8EA2DEE2 0x858F # 0 +0x8EA2DEE3 0x85A7 # 0 +0x8EA2DEE4 0x8595 # 0 +0x8EA2DEE5 0x85A0 # 0 +0x8EA2DEE6 0x858B # 0 +0x8EA2DEE7 0x85A3 # 0 +0x8EA2DEE8 0x857B # 0 +0x8EA2DEE9 0x85A4 # 0 +0x8EA2DEEA 0x859A # 0 +0x8EA2DEEB 0x859E # 0 +0x8EA2DEEC 0x8577 # 0 +0x8EA2DEED 0x857C # 0 +0x8EA2DEEE 0x8589 # 0 +0x8EA2DEEF 0x85A1 # 0 +0x8EA2DEF0 0x857A # 0 +0x8EA2DEF1 0x8578 # 0 +0x8EA2DEF2 0x8557 # 0 +0x8EA2DEF3 0x858E # 0 +0x8EA2DEF4 0x8596 # 0 +0x8EA2DEF5 0x8586 # 0 +0x8EA2DEF6 0x858D # 0 +0x8EA2DEF7 0x8599 # 0 +0x8EA2DEF8 0x859D # 0 +0x8EA2DEF9 0x8581 # 0 +0x8EA2DEFA 0x85A2 # 0 +0x8EA2DEFB 0x8582 # 0 +0x8EA2DEFC 0x8588 # 0 +0x8EA2DEFD 0x8585 # 0 +0x8EA2DEFE 0x8579 # 0 +0x8EA2DFA1 0x8576 # 0 +0x8EA2DFA2 0x8598 # 0 +0x8EA2DFA3 0x8590 # 0 +0x8EA2DFA4 0x859F # 0 +0x8EA2DFA5 0x8668 # 0 +0x8EA2DFA6 0x87BE # 0 +0x8EA2DFA7 0x87AA # 0 +0x8EA2DFA8 0x87AD # 0 +0x8EA2DFA9 0x87C5 # 0 +0x8EA2DFAA 0x87B0 # 0 +0x8EA2DFAB 0x87AC # 0 +0x8EA2DFAC 0x87B9 # 0 +0x8EA2DFAD 0x87B5 # 0 +0x8EA2DFAE 0x87BC # 0 +0x8EA2DFAF 0x87AE # 0 +0x8EA2DFB0 0x87C9 # 0 +0x8EA2DFB1 0x87C3 # 0 +0x8EA2DFB2 0x87C2 # 0 +0x8EA2DFB3 0x87CC # 0 +0x8EA2DFB4 0x87B7 # 0 +0x8EA2DFB5 0x87AF # 0 +0x8EA2DFB6 0x87C4 # 0 +0x8EA2DFB7 0x87CA # 0 +0x8EA2DFB8 0x87B4 # 0 +0x8EA2DFB9 0x87B6 # 0 +0x8EA2DFBA 0x87BF # 0 +0x8EA2DFBB 0x87B8 # 0 +0x8EA2DFBC 0x87BD # 0 +0x8EA2DFBD 0x87DE # 0 +0x8EA2DFBE 0x87B2 # 0 +0x8EA2DFBF 0x8935 # 0 +0x8EA2DFC0 0x8933 # 0 +0x8EA2DFC1 0x893C # 0 +0x8EA2DFC2 0x893E # 0 +0x8EA2DFC3 0x8941 # 0 +0x8EA2DFC4 0x8952 # 0 +0x8EA2DFC5 0x8937 # 0 +0x8EA2DFC6 0x8942 # 0 +0x8EA2DFC7 0x89AD # 0 +0x8EA2DFC8 0x89AF # 0 +0x8EA2DFC9 0x89AE # 0 +0x8EA2DFCA 0x89F2 # 0 +0x8EA2DFCB 0x89F3 # 0 +0x8EA2DFCC 0x8B1E # 0 +0x8EA2DFCD 0x8B18 # 0 +0x8EA2DFCE 0x8B16 # 0 +0x8EA2DFCF 0x8B11 # 0 +0x8EA2DFD0 0x8B05 # 0 +0x8EA2DFD1 0x8B0B # 0 +0x8EA2DFD2 0x8B22 # 0 +0x8EA2DFD3 0x8B0F # 0 +0x8EA2DFD4 0x8B12 # 0 +0x8EA2DFD5 0x8B15 # 0 +0x8EA2DFD6 0x8B07 # 0 +0x8EA2DFD7 0x8B0D # 0 +0x8EA2DFD8 0x8B08 # 0 +0x8EA2DFD9 0x8B06 # 0 +0x8EA2DFDA 0x8B1C # 0 +0x8EA2DFDB 0x8B13 # 0 +0x8EA2DFDC 0x8B1A # 0 +0x8EA2DFDD 0x8C4F # 0 +0x8EA2DFDE 0x8C70 # 0 +0x8EA2DFDF 0x8C72 # 0 +0x8EA2DFE0 0x8C71 # 0 +0x8EA2DFE1 0x8C6F # 0 +0x8EA2DFE2 0x8C95 # 0 +0x8EA2DFE3 0x8C94 # 0 +0x8EA2DFE4 0x8CF9 # 0 +0x8EA2DFE5 0x8D6F # 0 +0x8EA2DFE6 0x8E4E # 0 +0x8EA2DFE7 0x8E4D # 0 +0x8EA2DFE8 0x8E53 # 0 +0x8EA2DFE9 0x8E50 # 0 +0x8EA2DFEA 0x8E4C # 0 +0x8EA2DFEB 0x8E47 # 0 +0x8EA2DFEC 0x8F43 # 0 +0x8EA2DFED 0x8F40 # 0 +0x8EA2DFEE 0x9085 # 0 +0x8EA2DFEF 0x907E # 0 +0x8EA2DFF0 0x9138 # 0 +0x8EA2DFF1 0x919A # 0 +0x8EA2DFF2 0x91A2 # 0 +0x8EA2DFF3 0x919B # 0 +0x8EA2DFF4 0x9199 # 0 +0x8EA2DFF5 0x919F # 0 +0x8EA2DFF6 0x91A1 # 0 +0x8EA2DFF7 0x919D # 0 +0x8EA2DFF8 0x91A0 # 0 +0x8EA2DFF9 0x93A1 # 0 +0x8EA2DFFA 0x9383 # 0 +0x8EA2DFFB 0x93AF # 0 +0x8EA2DFFC 0x9364 # 0 +0x8EA2DFFD 0x9356 # 0 +0x8EA2DFFE 0x9347 # 0 +0x8EA2E0A1 0x937C # 0 +0x8EA2E0A2 0x9358 # 0 +0x8EA2E0A3 0x935C # 0 +0x8EA2E0A4 0x9376 # 0 +0x8EA2E0A5 0x9349 # 0 +0x8EA2E0A6 0x9350 # 0 +0x8EA2E0A7 0x9351 # 0 +0x8EA2E0A8 0x9360 # 0 +0x8EA2E0A9 0x936D # 0 +0x8EA2E0AA 0x938F # 0 +0x8EA2E0AB 0x934C # 0 +0x8EA2E0AC 0x936A # 0 +0x8EA2E0AD 0x9379 # 0 +0x8EA2E0AE 0x9357 # 0 +0x8EA2E0AF 0x9355 # 0 +0x8EA2E0B0 0x9352 # 0 +0x8EA2E0B1 0x934F # 0 +0x8EA2E0B2 0x9371 # 0 +0x8EA2E0B3 0x9377 # 0 +0x8EA2E0B4 0x937B # 0 +0x8EA2E0B5 0x9361 # 0 +0x8EA2E0B6 0x935E # 0 +0x8EA2E0B7 0x9363 # 0 +0x8EA2E0B8 0x9367 # 0 +0x8EA2E0B9 0x934E # 0 +0x8EA2E0BA 0x9359 # 0 +0x8EA2E0BB 0x95C7 # 0 +0x8EA2E0BC 0x95C0 # 0 +0x8EA2E0BD 0x95C9 # 0 +0x8EA2E0BE 0x95C3 # 0 +0x8EA2E0BF 0x95C5 # 0 +0x8EA2E0C0 0x95B7 # 0 +0x8EA2E0C1 0x96AE # 0 +0x8EA2E0C2 0x96B0 # 0 +0x8EA2E0C3 0x96AC # 0 +0x8EA2E0C4 0x9720 # 0 +0x8EA2E0C5 0x971F # 0 +0x8EA2E0C6 0x9718 # 0 +0x8EA2E0C7 0x971D # 0 +0x8EA2E0C8 0x9719 # 0 +0x8EA2E0C9 0x979A # 0 +0x8EA2E0CA 0x97A1 # 0 +0x8EA2E0CB 0x979C # 0 +0x8EA2E0CC 0x979E # 0 +0x8EA2E0CD 0x979D # 0 +0x8EA2E0CE 0x97D5 # 0 +0x8EA2E0CF 0x97D4 # 0 +0x8EA2E0D0 0x97F1 # 0 +0x8EA2E0D1 0x9841 # 0 +0x8EA2E0D2 0x9844 # 0 +0x8EA2E0D3 0x984A # 0 +0x8EA2E0D4 0x9849 # 0 +0x8EA2E0D5 0x9845 # 0 +0x8EA2E0D6 0x9843 # 0 +0x8EA2E0D7 0x9925 # 0 +0x8EA2E0D8 0x992B # 0 +0x8EA2E0D9 0x992C # 0 +0x8EA2E0DA 0x992A # 0 +0x8EA2E0DB 0x9933 # 0 +0x8EA2E0DC 0x9932 # 0 +0x8EA2E0DD 0x992F # 0 +0x8EA2E0DE 0x992D # 0 +0x8EA2E0DF 0x9931 # 0 +0x8EA2E0E0 0x9930 # 0 +0x8EA2E0E1 0x9998 # 0 +0x8EA2E0E2 0x99A3 # 0 +0x8EA2E0E3 0x99A1 # 0 +0x8EA2E0E4 0x9A02 # 0 +0x8EA2E0E5 0x99FA # 0 +0x8EA2E0E6 0x99F4 # 0 +0x8EA2E0E7 0x99F7 # 0 +0x8EA2E0E8 0x99F9 # 0 +0x8EA2E0E9 0x99F8 # 0 +0x8EA2E0EA 0x99F6 # 0 +0x8EA2E0EB 0x99FB # 0 +0x8EA2E0EC 0x99FD # 0 +0x8EA2E0ED 0x99FE # 0 +0x8EA2E0EE 0x99FC # 0 +0x8EA2E0EF 0x9A03 # 0 +0x8EA2E0F0 0x9ABE # 0 +0x8EA2E0F1 0x9AFE # 0 +0x8EA2E0F2 0x9AFD # 0 +0x8EA2E0F3 0x9B01 # 0 +0x8EA2E0F4 0x9AFC # 0 +0x8EA2E0F5 0x9B48 # 0 +0x8EA2E0F6 0x9B9A # 0 +0x8EA2E0F7 0x9BA8 # 0 +0x8EA2E0F8 0x9B9E # 0 +0x8EA2E0F9 0x9B9B # 0 +0x8EA2E0FA 0x9BA6 # 0 +0x8EA2E0FB 0x9BA1 # 0 +0x8EA2E0FC 0x9BA5 # 0 +0x8EA2E0FD 0x9BA4 # 0 +0x8EA2E0FE 0x9B86 # 0 +0x8EA2E1A1 0x9BA2 # 0 +0x8EA2E1A2 0x9BA0 # 0 +0x8EA2E1A3 0x9BAF # 0 +0x8EA2E1A4 0x9D33 # 0 +0x8EA2E1A5 0x9D41 # 0 +0x8EA2E1A6 0x9D67 # 0 +0x8EA2E1A7 0x9D36 # 0 +0x8EA2E1A8 0x9D2E # 0 +0x8EA2E1A9 0x9D2F # 0 +0x8EA2E1AA 0x9D31 # 0 +0x8EA2E1AB 0x9D38 # 0 +0x8EA2E1AC 0x9D30 # 0 +0x8EA2E1AD 0x9D45 # 0 +0x8EA2E1AE 0x9D42 # 0 +0x8EA2E1AF 0x9D43 # 0 +0x8EA2E1B0 0x9D3E # 0 +0x8EA2E1B1 0x9D37 # 0 +0x8EA2E1B2 0x9D40 # 0 +0x8EA2E1B3 0x9D3D # 0 +0x8EA2E1B4 0x7FF5 # 0 +0x8EA2E1B5 0x9D2D # 0 +0x8EA2E1B6 0x9E8A # 0 +0x8EA2E1B7 0x9E89 # 0 +0x8EA2E1B8 0x9E8D # 0 +0x8EA2E1B9 0x9EB0 # 0 +0x8EA2E1BA 0x9EC8 # 0 +0x8EA2E1BB 0x9EDA # 0 +0x8EA2E1BC 0x9EFB # 0 +0x8EA2E1BD 0x9EFF # 0 +0x8EA2E1BE 0x9F24 # 0 +0x8EA2E1BF 0x9F23 # 0 +0x8EA2E1C0 0x9F22 # 0 +0x8EA2E1C1 0x9F54 # 0 +0x8EA2E1C2 0x9FA0 # 0 +0x8EA2E1C3 0x5131 # 0 +0x8EA2E1C4 0x512D # 0 +0x8EA2E1C5 0x512E # 0 +0x8EA2E1C6 0x5698 # 0 +0x8EA2E1C7 0x569C # 0 +0x8EA2E1C8 0x5697 # 0 +0x8EA2E1C9 0x569A # 0 +0x8EA2E1CA 0x569D # 0 +0x8EA2E1CB 0x5699 # 0 +0x8EA2E1CC 0x5970 # 0 +0x8EA2E1CD 0x5B3C # 0 +0x8EA2E1CE 0x5C69 # 0 +0x8EA2E1CF 0x5C6A # 0 +0x8EA2E1D0 0x5DC0 # 0 +0x8EA2E1D1 0x5E6D # 0 +0x8EA2E1D2 0x5E6E # 0 +0x8EA2E1D3 0x61D8 # 0 +0x8EA2E1D4 0x61DF # 0 +0x8EA2E1D5 0x61ED # 0 +0x8EA2E1D6 0x61EE # 0 +0x8EA2E1D7 0x61F1 # 0 +0x8EA2E1D8 0x61EA # 0 +0x8EA2E1D9 0x61F0 # 0 +0x8EA2E1DA 0x61EB # 0 +0x8EA2E1DB 0x61D6 # 0 +0x8EA2E1DC 0x61E9 # 0 +0x8EA2E1DD 0x64FF # 0 +0x8EA2E1DE 0x6504 # 0 +0x8EA2E1DF 0x64FD # 0 +0x8EA2E1E0 0x64F8 # 0 +0x8EA2E1E1 0x6501 # 0 +0x8EA2E1E2 0x6503 # 0 +0x8EA2E1E3 0x64FC # 0 +0x8EA2E1E4 0x6594 # 0 +0x8EA2E1E5 0x65DB # 0 +0x8EA2E1E6 0x66DA # 0 +0x8EA2E1E7 0x66DB # 0 +0x8EA2E1E8 0x66D8 # 0 +0x8EA2E1E9 0x6AC5 # 0 +0x8EA2E1EA 0x6AB9 # 0 +0x8EA2E1EB 0x6ABD # 0 +0x8EA2E1EC 0x6AE1 # 0 +0x8EA2E1ED 0x6AC6 # 0 +0x8EA2E1EE 0x6ABA # 0 +0x8EA2E1EF 0x6AB6 # 0 +0x8EA2E1F0 0x6AB7 # 0 +0x8EA2E1F1 0x6AC7 # 0 +0x8EA2E1F2 0x6AB4 # 0 +0x8EA2E1F3 0x6AAD # 0 +0x8EA2E1F4 0x6B5E # 0 +0x8EA2E1F5 0x6BC9 # 0 +0x8EA2E1F6 0x6C0B # 0 +0x8EA2E1F7 0x7007 # 0 +0x8EA2E1F8 0x700C # 0 +0x8EA2E1F9 0x700D # 0 +0x8EA2E1FA 0x7001 # 0 +0x8EA2E1FB 0x7005 # 0 +0x8EA2E1FC 0x7014 # 0 +0x8EA2E1FD 0x700E # 0 +0x8EA2E1FE 0x6FFF # 0 +0x8EA2E2A1 0x7000 # 0 +0x8EA2E2A2 0x6FFB # 0 +0x8EA2E2A3 0x7026 # 0 +0x8EA2E2A4 0x6FFC # 0 +0x8EA2E2A5 0x6FF7 # 0 +0x8EA2E2A6 0x700A # 0 +0x8EA2E2A7 0x7201 # 0 +0x8EA2E2A8 0x71FF # 0 +0x8EA2E2A9 0x71F9 # 0 +0x8EA2E2AA 0x7203 # 0 +0x8EA2E2AB 0x71FD # 0 +0x8EA2E2AC 0x7376 # 0 +0x8EA2E2AD 0x74B8 # 0 +0x8EA2E2AE 0x74C0 # 0 +0x8EA2E2AF 0x74B5 # 0 +0x8EA2E2B0 0x74C1 # 0 +0x8EA2E2B1 0x74BE # 0 +0x8EA2E2B2 0x74B6 # 0 +0x8EA2E2B3 0x74BB # 0 +0x8EA2E2B4 0x74C2 # 0 +0x8EA2E2B5 0x7514 # 0 +0x8EA2E2B6 0x7513 # 0 +0x8EA2E2B7 0x765C # 0 +0x8EA2E2B8 0x7664 # 0 +0x8EA2E2B9 0x7659 # 0 +0x8EA2E2BA 0x7650 # 0 +0x8EA2E2BB 0x7653 # 0 +0x8EA2E2BC 0x7657 # 0 +0x8EA2E2BD 0x765A # 0 +0x8EA2E2BE 0x76A6 # 0 +0x8EA2E2BF 0x76BD # 0 +0x8EA2E2C0 0x76EC # 0 +0x8EA2E2C1 0x77C2 # 0 +0x8EA2E2C2 0x77BA # 0 +0x8EA2E2C3 0x790C # 0 +0x8EA2E2C4 0x7913 # 0 +0x8EA2E2C5 0x7914 # 0 +0x8EA2E2C6 0x7909 # 0 +0x8EA2E2C7 0x7910 # 0 +0x8EA2E2C8 0x7912 # 0 +0x8EA2E2C9 0x7911 # 0 +0x8EA2E2CA 0x79AD # 0 +0x8EA2E2CB 0x79AC # 0 +0x8EA2E2CC 0x7A5F # 0 +0x8EA2E2CD 0x7C1C # 0 +0x8EA2E2CE 0x7C29 # 0 +0x8EA2E2CF 0x7C19 # 0 +0x8EA2E2D0 0x7C20 # 0 +0x8EA2E2D1 0x7C1F # 0 +0x8EA2E2D2 0x7C2D # 0 +0x8EA2E2D3 0x7C1D # 0 +0x8EA2E2D4 0x7C26 # 0 +0x8EA2E2D5 0x7C28 # 0 +0x8EA2E2D6 0x7C22 # 0 +0x8EA2E2D7 0x7C25 # 0 +0x8EA2E2D8 0x7C30 # 0 +0x8EA2E2D9 0x7E5C # 0 +0x8EA2E2DA 0x7E50 # 0 +0x8EA2E2DB 0x7E56 # 0 +0x8EA2E2DC 0x7E63 # 0 +0x8EA2E2DD 0x7E58 # 0 +0x8EA2E2DE 0x7E62 # 0 +0x8EA2E2DF 0x7E5F # 0 +0x8EA2E2E0 0x7E51 # 0 +0x8EA2E2E1 0x7E60 # 0 +0x8EA2E2E2 0x7E57 # 0 +0x8EA2E2E3 0x7E53 # 0 +0x8EA2E2E4 0x7FB5 # 0 +0x8EA2E2E5 0x7FB3 # 0 +0x8EA2E2E6 0x7FF7 # 0 +0x8EA2E2E7 0x7FF8 # 0 +0x8EA2E2E8 0x8075 # 0 +0x8EA2E2E9 0x81D1 # 0 +0x8EA2E2EA 0x81D2 # 0 +0x8EA2E2EB 0x81D0 # 0 +0x8EA2E2EC 0x825F # 0 +0x8EA2E2ED 0x825E # 0 +0x8EA2E2EE 0x85B4 # 0 +0x8EA2E2EF 0x85C6 # 0 +0x8EA2E2F0 0x85C0 # 0 +0x8EA2E2F1 0x85C3 # 0 +0x8EA2E2F2 0x85C2 # 0 +0x8EA2E2F3 0x85B3 # 0 +0x8EA2E2F4 0x85B5 # 0 +0x8EA2E2F5 0x85BD # 0 +0x8EA2E2F6 0x85C7 # 0 +0x8EA2E2F7 0x85C4 # 0 +0x8EA2E2F8 0x85BF # 0 +0x8EA2E2F9 0x85CB # 0 +0x8EA2E2FA 0x85CE # 0 +0x8EA2E2FB 0x85C8 # 0 +0x8EA2E2FC 0x85C5 # 0 +0x8EA2E2FD 0x85B1 # 0 +0x8EA2E2FE 0x85B6 # 0 +0x8EA2E3A1 0x85D2 # 0 +0x8EA2E3A2 0x8624 # 0 +0x8EA2E3A3 0x85B8 # 0 +0x8EA2E3A4 0x85B7 # 0 +0x8EA2E3A5 0x85BE # 0 +0x8EA2E3A6 0x8669 # 0 +0x8EA2E3A7 0x87E7 # 0 +0x8EA2E3A8 0x87E6 # 0 +0x8EA2E3A9 0x87E2 # 0 +0x8EA2E3AA 0x87DB # 0 +0x8EA2E3AB 0x87EB # 0 +0x8EA2E3AC 0x87EA # 0 +0x8EA2E3AD 0x87E5 # 0 +0x8EA2E3AE 0x87DF # 0 +0x8EA2E3AF 0x87F3 # 0 +0x8EA2E3B0 0x87E4 # 0 +0x8EA2E3B1 0x87D4 # 0 +0x8EA2E3B2 0x87DC # 0 +0x8EA2E3B3 0x87D3 # 0 +0x8EA2E3B4 0x87ED # 0 +0x8EA2E3B5 0x87D8 # 0 +0x8EA2E3B6 0x87E3 # 0 +0x8EA2E3B7 0x87D7 # 0 +0x8EA2E3B8 0x87D9 # 0 +0x8EA2E3B9 0x8801 # 0 +0x8EA2E3BA 0x87F4 # 0 +0x8EA2E3BB 0x87E8 # 0 +0x8EA2E3BC 0x87DD # 0 +0x8EA2E3BD 0x8953 # 0 +0x8EA2E3BE 0x894B # 0 +0x8EA2E3BF 0x894F # 0 +0x8EA2E3C0 0x894C # 0 +0x8EA2E3C1 0x8946 # 0 +0x8EA2E3C2 0x8950 # 0 +0x8EA2E3C3 0x8951 # 0 +0x8EA2E3C4 0x8949 # 0 +0x8EA2E3C5 0x8B2A # 0 +0x8EA2E3C6 0x8B27 # 0 +0x8EA2E3C7 0x8B23 # 0 +0x8EA2E3C8 0x8B33 # 0 +0x8EA2E3C9 0x8B30 # 0 +0x8EA2E3CA 0x8B35 # 0 +0x8EA2E3CB 0x8B47 # 0 +0x8EA2E3CC 0x8B2F # 0 +0x8EA2E3CD 0x8B3C # 0 +0x8EA2E3CE 0x8B3E # 0 +0x8EA2E3CF 0x8B31 # 0 +0x8EA2E3D0 0x8B25 # 0 +0x8EA2E3D1 0x8B37 # 0 +0x8EA2E3D2 0x8B26 # 0 +0x8EA2E3D3 0x8B36 # 0 +0x8EA2E3D4 0x8B2E # 0 +0x8EA2E3D5 0x8B24 # 0 +0x8EA2E3D6 0x8B3B # 0 +0x8EA2E3D7 0x8B3D # 0 +0x8EA2E3D8 0x8B3A # 0 +0x8EA2E3D9 0x8C42 # 0 +0x8EA2E3DA 0x8C75 # 0 +0x8EA2E3DB 0x8C99 # 0 +0x8EA2E3DC 0x8C98 # 0 +0x8EA2E3DD 0x8C97 # 0 +0x8EA2E3DE 0x8CFE # 0 +0x8EA2E3DF 0x8D04 # 0 +0x8EA2E3E0 0x8D02 # 0 +0x8EA2E3E1 0x8D00 # 0 +0x8EA2E3E2 0x8E5C # 0 +0x8EA2E3E3 0x8E62 # 0 +0x8EA2E3E4 0x8E60 # 0 +0x8EA2E3E5 0x8E57 # 0 +0x8EA2E3E6 0x8E56 # 0 +0x8EA2E3E7 0x8E5E # 0 +0x8EA2E3E8 0x8E65 # 0 +0x8EA2E3E9 0x8E67 # 0 +0x8EA2E3EA 0x8E5B # 0 +0x8EA2E3EB 0x8E5A # 0 +0x8EA2E3EC 0x8E61 # 0 +0x8EA2E3ED 0x8E5D # 0 +0x8EA2E3EE 0x8E69 # 0 +0x8EA2E3EF 0x8E54 # 0 +0x8EA2E3F0 0x8F46 # 0 +0x8EA2E3F1 0x8F47 # 0 +0x8EA2E3F2 0x8F48 # 0 +0x8EA2E3F3 0x8F4B # 0 +0x8EA2E3F4 0x9128 # 0 +0x8EA2E3F5 0x913A # 0 +0x8EA2E3F6 0x913B # 0 +0x8EA2E3F7 0x913E # 0 +0x8EA2E3F8 0x91A8 # 0 +0x8EA2E3F9 0x91A5 # 0 +0x8EA2E3FA 0x91A7 # 0 +0x8EA2E3FB 0x91AF # 0 +0x8EA2E3FC 0x91AA # 0 +0x8EA2E3FD 0x93B5 # 0 +0x8EA2E3FE 0x938C # 0 +0x8EA2E4A1 0x9392 # 0 +0x8EA2E4A2 0x93B7 # 0 +0x8EA2E4A3 0x939B # 0 +0x8EA2E4A4 0x939D # 0 +0x8EA2E4A5 0x9389 # 0 +0x8EA2E4A6 0x93A7 # 0 +0x8EA2E4A7 0x938E # 0 +0x8EA2E4A8 0x93AA # 0 +0x8EA2E4A9 0x939E # 0 +0x8EA2E4AA 0x93A6 # 0 +0x8EA2E4AB 0x9395 # 0 +0x8EA2E4AC 0x9388 # 0 +0x8EA2E4AD 0x9399 # 0 +0x8EA2E4AE 0x939F # 0 +0x8EA2E4AF 0x9380 # 0 +0x8EA2E4B0 0x938D # 0 +0x8EA2E4B1 0x93B1 # 0 +0x8EA2E4B2 0x9391 # 0 +0x8EA2E4B3 0x93B2 # 0 +0x8EA2E4B4 0x93A4 # 0 +0x8EA2E4B5 0x93A8 # 0 +0x8EA2E4B6 0x93B4 # 0 +0x8EA2E4B7 0x93A3 # 0 +0x8EA2E4B8 0x95D2 # 0 +0x8EA2E4B9 0x95D3 # 0 +0x8EA2E4BA 0x95D1 # 0 +0x8EA2E4BB 0x96B3 # 0 +0x8EA2E4BC 0x96D7 # 0 +0x8EA2E4BD 0x96DA # 0 +0x8EA2E4BE 0x5DC2 # 0 +0x8EA2E4BF 0x96DF # 0 +0x8EA2E4C0 0x96D8 # 0 +0x8EA2E4C1 0x96DD # 0 +0x8EA2E4C2 0x9723 # 0 +0x8EA2E4C3 0x9722 # 0 +0x8EA2E4C4 0x9725 # 0 +0x8EA2E4C5 0x97AC # 0 +0x8EA2E4C6 0x97AE # 0 +0x8EA2E4C7 0x97A8 # 0 +0x8EA2E4C8 0x97AB # 0 +0x8EA2E4C9 0x97A4 # 0 +0x8EA2E4CA 0x97AA # 0 +0x8EA2E4CB 0x97A2 # 0 +0x8EA2E4CC 0x97A5 # 0 +0x8EA2E4CD 0x97D7 # 0 +0x8EA2E4CE 0x97D9 # 0 +0x8EA2E4CF 0x97D6 # 0 +0x8EA2E4D0 0x97D8 # 0 +0x8EA2E4D1 0x97FA # 0 +0x8EA2E4D2 0x9850 # 0 +0x8EA2E4D3 0x9851 # 0 +0x8EA2E4D4 0x9852 # 0 +0x8EA2E4D5 0x98B8 # 0 +0x8EA2E4D6 0x9941 # 0 +0x8EA2E4D7 0x993C # 0 +0x8EA2E4D8 0x993A # 0 +0x8EA2E4D9 0x9A0F # 0 +0x8EA2E4DA 0x9A0B # 0 +0x8EA2E4DB 0x9A09 # 0 +0x8EA2E4DC 0x9A0D # 0 +0x8EA2E4DD 0x9A04 # 0 +0x8EA2E4DE 0x9A11 # 0 +0x8EA2E4DF 0x9A0A # 0 +0x8EA2E4E0 0x9A05 # 0 +0x8EA2E4E1 0x9A07 # 0 +0x8EA2E4E2 0x9A06 # 0 +0x8EA2E4E3 0x9AC0 # 0 +0x8EA2E4E4 0x9ADC # 0 +0x8EA2E4E5 0x9B08 # 0 +0x8EA2E4E6 0x9B04 # 0 +0x8EA2E4E7 0x9B05 # 0 +0x8EA2E4E8 0x9B29 # 0 +0x8EA2E4E9 0x9B35 # 0 +0x8EA2E4EA 0x9B4A # 0 +0x8EA2E4EB 0x9B4C # 0 +0x8EA2E4EC 0x9B4B # 0 +0x8EA2E4ED 0x9BC7 # 0 +0x8EA2E4EE 0x9BC6 # 0 +0x8EA2E4EF 0x9BC3 # 0 +0x8EA2E4F0 0x9BBF # 0 +0x8EA2E4F1 0x9BC1 # 0 +0x8EA2E4F2 0x9BB5 # 0 +0x8EA2E4F3 0x9BB8 # 0 +0x8EA2E4F4 0x9BD3 # 0 +0x8EA2E4F5 0x9BB6 # 0 +0x8EA2E4F6 0x9BC4 # 0 +0x8EA2E4F7 0x9BB9 # 0 +0x8EA2E4F8 0x9BBD # 0 +0x8EA2E4F9 0x9D5C # 0 +0x8EA2E4FA 0x9D53 # 0 +0x8EA2E4FB 0x9D4F # 0 +0x8EA2E4FC 0x9D4A # 0 +0x8EA2E4FD 0x9D5B # 0 +0x8EA2E4FE 0x9D4B # 0 +0x8EA2E5A1 0x9D59 # 0 +0x8EA2E5A2 0x9D56 # 0 +0x8EA2E5A3 0x9D4C # 0 +0x8EA2E5A4 0x9D57 # 0 +0x8EA2E5A5 0x9D52 # 0 +0x8EA2E5A6 0x9D54 # 0 +0x8EA2E5A7 0x9D5F # 0 +0x8EA2E5A8 0x9D58 # 0 +0x8EA2E5A9 0x9D5A # 0 +0x8EA2E5AA 0x9E8E # 0 +0x8EA2E5AB 0x9E8C # 0 +0x8EA2E5AC 0x9EDF # 0 +0x8EA2E5AD 0x9F01 # 0 +0x8EA2E5AE 0x9F00 # 0 +0x8EA2E5AF 0x9F16 # 0 +0x8EA2E5B0 0x9F25 # 0 +0x8EA2E5B1 0x9F2B # 0 +0x8EA2E5B2 0x9F2A # 0 +0x8EA2E5B3 0x9F29 # 0 +0x8EA2E5B4 0x9F28 # 0 +0x8EA2E5B5 0x9F4C # 0 +0x8EA2E5B6 0x9F55 # 0 +0x8EA2E5B7 0x5134 # 0 +0x8EA2E5B8 0x5135 # 0 +0x8EA2E5B9 0x5296 # 0 +0x8EA2E5BA 0x52F7 # 0 +0x8EA2E5BB 0x53B4 # 0 +0x8EA2E5BC 0x56AB # 0 +0x8EA2E5BD 0x56AD # 0 +0x8EA2E5BE 0x56A6 # 0 +0x8EA2E5BF 0x56A7 # 0 +0x8EA2E5C0 0x56AA # 0 +0x8EA2E5C1 0x56AC # 0 +0x8EA2E5C2 0x58DA # 0 +0x8EA2E5C3 0x58DD # 0 +0x8EA2E5C4 0x58DB # 0 +0x8EA2E5C5 0x5912 # 0 +0x8EA2E5C6 0x5B3D # 0 +0x8EA2E5C7 0x5B3E # 0 +0x8EA2E5C8 0x5B3F # 0 +0x8EA2E5C9 0x5DC3 # 0 +0x8EA2E5CA 0x5E70 # 0 +0x8EA2E5CB 0x5FBF # 0 +0x8EA2E5CC 0x61FB # 0 +0x8EA2E5CD 0x6507 # 0 +0x8EA2E5CE 0x6510 # 0 +0x8EA2E5CF 0x650D # 0 +0x8EA2E5D0 0x6509 # 0 +0x8EA2E5D1 0x650C # 0 +0x8EA2E5D2 0x650E # 0 +0x8EA2E5D3 0x6584 # 0 +0x8EA2E5D4 0x65DE # 0 +0x8EA2E5D5 0x65DD # 0 +0x8EA2E5D6 0x66DE # 0 +0x8EA2E5D7 0x6AE7 # 0 +0x8EA2E5D8 0x6AE0 # 0 +0x8EA2E5D9 0x6ACC # 0 +0x8EA2E5DA 0x6AD1 # 0 +0x8EA2E5DB 0x6AD9 # 0 +0x8EA2E5DC 0x6ACB # 0 +0x8EA2E5DD 0x6ADF # 0 +0x8EA2E5DE 0x6ADC # 0 +0x8EA2E5DF 0x6AD0 # 0 +0x8EA2E5E0 0x6AEB # 0 +0x8EA2E5E1 0x6ACF # 0 +0x8EA2E5E2 0x6ACD # 0 +0x8EA2E5E3 0x6ADE # 0 +0x8EA2E5E4 0x6B60 # 0 +0x8EA2E5E5 0x6BB0 # 0 +0x8EA2E5E6 0x6C0C # 0 +0x8EA2E5E7 0x7019 # 0 +0x8EA2E5E8 0x7027 # 0 +0x8EA2E5E9 0x7020 # 0 +0x8EA2E5EA 0x7016 # 0 +0x8EA2E5EB 0x702B # 0 +0x8EA2E5EC 0x7021 # 0 +0x8EA2E5ED 0x7022 # 0 +0x8EA2E5EE 0x7023 # 0 +0x8EA2E5EF 0x7029 # 0 +0x8EA2E5F0 0x7017 # 0 +0x8EA2E5F1 0x7024 # 0 +0x8EA2E5F2 0x701C # 0 +0x8EA2E5F3 0x720C # 0 +0x8EA2E5F4 0x720A # 0 +0x8EA2E5F5 0x7207 # 0 +0x8EA2E5F6 0x7202 # 0 +0x8EA2E5F7 0x7205 # 0 +0x8EA2E5F8 0x72A5 # 0 +0x8EA2E5F9 0x72A6 # 0 +0x8EA2E5FA 0x72A4 # 0 +0x8EA2E5FB 0x72A3 # 0 +0x8EA2E5FC 0x72A1 # 0 +0x8EA2E5FD 0x74CB # 0 +0x8EA2E5FE 0x74C5 # 0 +0x8EA2E6A1 0x74B7 # 0 +0x8EA2E6A2 0x74C3 # 0 +0x8EA2E6A3 0x7516 # 0 +0x8EA2E6A4 0x7660 # 0 +0x8EA2E6A5 0x77C9 # 0 +0x8EA2E6A6 0x77CA # 0 +0x8EA2E6A7 0x77C4 # 0 +0x8EA2E6A8 0x77F1 # 0 +0x8EA2E6A9 0x791D # 0 +0x8EA2E6AA 0x791B # 0 +0x8EA2E6AB 0x7921 # 0 +0x8EA2E6AC 0x791C # 0 +0x8EA2E6AD 0x7917 # 0 +0x8EA2E6AE 0x791E # 0 +0x8EA2E6AF 0x79B0 # 0 +0x8EA2E6B0 0x7A67 # 0 +0x8EA2E6B1 0x7A68 # 0 +0x8EA2E6B2 0x7C33 # 0 +0x8EA2E6B3 0x7C3C # 0 +0x8EA2E6B4 0x7C39 # 0 +0x8EA2E6B5 0x7C2C # 0 +0x8EA2E6B6 0x7C3B # 0 +0x8EA2E6B7 0x7CEC # 0 +0x8EA2E6B8 0x7CEA # 0 +0x8EA2E6B9 0x7E76 # 0 +0x8EA2E6BA 0x7E75 # 0 +0x8EA2E6BB 0x7E78 # 0 +0x8EA2E6BC 0x7E70 # 0 +0x8EA2E6BD 0x7E77 # 0 +0x8EA2E6BE 0x7E6F # 0 +0x8EA2E6BF 0x7E7A # 0 +0x8EA2E6C0 0x7E72 # 0 +0x8EA2E6C1 0x7E74 # 0 +0x8EA2E6C2 0x7E68 # 0 +0x8EA2E6C3 0x7F4B # 0 +0x8EA2E6C4 0x7F4A # 0 +0x8EA2E6C5 0x7F83 # 0 +0x8EA2E6C6 0x7F86 # 0 +0x8EA2E6C7 0x7FB7 # 0 +0x8EA2E6C8 0x7FFD # 0 +0x8EA2E6C9 0x7FFE # 0 +0x8EA2E6CA 0x8078 # 0 +0x8EA2E6CB 0x81D7 # 0 +0x8EA2E6CC 0x81D5 # 0 +0x8EA2E6CD 0x820B # 0 +0x8EA2E6CE 0x8264 # 0 +0x8EA2E6CF 0x8261 # 0 +0x8EA2E6D0 0x8263 # 0 +0x8EA2E6D1 0x85EB # 0 +0x8EA2E6D2 0x85F1 # 0 +0x8EA2E6D3 0x85ED # 0 +0x8EA2E6D4 0x85D9 # 0 +0x8EA2E6D5 0x85E1 # 0 +0x8EA2E6D6 0x85E8 # 0 +0x8EA2E6D7 0x85DA # 0 +0x8EA2E6D8 0x85D7 # 0 +0x8EA2E6D9 0x85EC # 0 +0x8EA2E6DA 0x85F2 # 0 +0x8EA2E6DB 0x85F8 # 0 +0x8EA2E6DC 0x85D8 # 0 +0x8EA2E6DD 0x85DF # 0 +0x8EA2E6DE 0x85E3 # 0 +0x8EA2E6DF 0x85DC # 0 +0x8EA2E6E0 0x85D1 # 0 +0x8EA2E6E1 0x85F0 # 0 +0x8EA2E6E2 0x85E6 # 0 +0x8EA2E6E3 0x85EF # 0 +0x8EA2E6E4 0x85DE # 0 +0x8EA2E6E5 0x85E2 # 0 +0x8EA2E6E6 0x8800 # 0 +0x8EA2E6E7 0x87FA # 0 +0x8EA2E6E8 0x8803 # 0 +0x8EA2E6E9 0x87F6 # 0 +0x8EA2E6EA 0x87F7 # 0 +0x8EA2E6EB 0x8809 # 0 +0x8EA2E6EC 0x880C # 0 +0x8EA2E6ED 0x880B # 0 +0x8EA2E6EE 0x8806 # 0 +0x8EA2E6EF 0x87FC # 0 +0x8EA2E6F0 0x8808 # 0 +0x8EA2E6F1 0x87FF # 0 +0x8EA2E6F2 0x880A # 0 +0x8EA2E6F3 0x8802 # 0 +0x8EA2E6F4 0x8962 # 0 +0x8EA2E6F5 0x895A # 0 +0x8EA2E6F6 0x895B # 0 +0x8EA2E6F7 0x8957 # 0 +0x8EA2E6F8 0x8961 # 0 +0x8EA2E6F9 0x895C # 0 +0x8EA2E6FA 0x8958 # 0 +0x8EA2E6FB 0x895D # 0 +0x8EA2E6FC 0x8959 # 0 +0x8EA2E6FD 0x8988 # 0 +0x8EA2E6FE 0x89B7 # 0 +0x8EA2E7A1 0x89B6 # 0 +0x8EA2E7A2 0x89F6 # 0 +0x8EA2E7A3 0x8B50 # 0 +0x8EA2E7A4 0x8B48 # 0 +0x8EA2E7A5 0x8B4A # 0 +0x8EA2E7A6 0x8B40 # 0 +0x8EA2E7A7 0x8B53 # 0 +0x8EA2E7A8 0x8B56 # 0 +0x8EA2E7A9 0x8B54 # 0 +0x8EA2E7AA 0x8B4B # 0 +0x8EA2E7AB 0x8B55 # 0 +0x8EA2E7AC 0x8B51 # 0 +0x8EA2E7AD 0x8B42 # 0 +0x8EA2E7AE 0x8B52 # 0 +0x8EA2E7AF 0x8B57 # 0 +0x8EA2E7B0 0x8C43 # 0 +0x8EA2E7B1 0x8C77 # 0 +0x8EA2E7B2 0x8C76 # 0 +0x8EA2E7B3 0x8C9A # 0 +0x8EA2E7B4 0x8D06 # 0 +0x8EA2E7B5 0x8D07 # 0 +0x8EA2E7B6 0x8D09 # 0 +0x8EA2E7B7 0x8DAC # 0 +0x8EA2E7B8 0x8DAA # 0 +0x8EA2E7B9 0x8DAD # 0 +0x8EA2E7BA 0x8DAB # 0 +0x8EA2E7BB 0x8E6D # 0 +0x8EA2E7BC 0x8E78 # 0 +0x8EA2E7BD 0x8E73 # 0 +0x8EA2E7BE 0x8E6A # 0 +0x8EA2E7BF 0x8E6F # 0 +0x8EA2E7C0 0x8E7B # 0 +0x8EA2E7C1 0x8EC2 # 0 +0x8EA2E7C2 0x8F52 # 0 +0x8EA2E7C3 0x8F51 # 0 +0x8EA2E7C4 0x8F4F # 0 +0x8EA2E7C5 0x8F50 # 0 +0x8EA2E7C6 0x8F53 # 0 +0x8EA2E7C7 0x8FB4 # 0 +0x8EA2E7C8 0x9140 # 0 +0x8EA2E7C9 0x913F # 0 +0x8EA2E7CA 0x91B0 # 0 +0x8EA2E7CB 0x91AD # 0 +0x8EA2E7CC 0x93DE # 0 +0x8EA2E7CD 0x93C7 # 0 +0x8EA2E7CE 0x93CF # 0 +0x8EA2E7CF 0x93C2 # 0 +0x8EA2E7D0 0x93DA # 0 +0x8EA2E7D1 0x93D0 # 0 +0x8EA2E7D2 0x93F9 # 0 +0x8EA2E7D3 0x93EC # 0 +0x8EA2E7D4 0x93CC # 0 +0x8EA2E7D5 0x93D9 # 0 +0x8EA2E7D6 0x93A9 # 0 +0x8EA2E7D7 0x93E6 # 0 +0x8EA2E7D8 0x93CA # 0 +0x8EA2E7D9 0x93D4 # 0 +0x8EA2E7DA 0x93EE # 0 +0x8EA2E7DB 0x93E3 # 0 +0x8EA2E7DC 0x93D5 # 0 +0x8EA2E7DD 0x93C4 # 0 +0x8EA2E7DE 0x93CE # 0 +0x8EA2E7DF 0x93C0 # 0 +0x8EA2E7E0 0x93D2 # 0 +0x8EA2E7E1 0x93A5 # 0 +0x8EA2E7E2 0x93E7 # 0 +0x8EA2E7E3 0x957D # 0 +0x8EA2E7E4 0x95DA # 0 +0x8EA2E7E5 0x95DB # 0 +0x8EA2E7E6 0x96E1 # 0 +0x8EA2E7E7 0x9729 # 0 +0x8EA2E7E8 0x972B # 0 +0x8EA2E7E9 0x972C # 0 +0x8EA2E7EA 0x9728 # 0 +0x8EA2E7EB 0x9726 # 0 +0x8EA2E7EC 0x97B3 # 0 +0x8EA2E7ED 0x97B7 # 0 +0x8EA2E7EE 0x97B6 # 0 +0x8EA2E7EF 0x97DD # 0 +0x8EA2E7F0 0x97DE # 0 +0x8EA2E7F1 0x97DF # 0 +0x8EA2E7F2 0x985C # 0 +0x8EA2E7F3 0x9859 # 0 +0x8EA2E7F4 0x985D # 0 +0x8EA2E7F5 0x9857 # 0 +0x8EA2E7F6 0x98BF # 0 +0x8EA2E7F7 0x98BD # 0 +0x8EA2E7F8 0x98BB # 0 +0x8EA2E7F9 0x98BE # 0 +0x8EA2E7FA 0x9948 # 0 +0x8EA2E7FB 0x9947 # 0 +0x8EA2E7FC 0x9943 # 0 +0x8EA2E7FD 0x99A6 # 0 +0x8EA2E7FE 0x99A7 # 0 +0x8EA2E8A1 0x9A1A # 0 +0x8EA2E8A2 0x9A15 # 0 +0x8EA2E8A3 0x9A25 # 0 +0x8EA2E8A4 0x9A1D # 0 +0x8EA2E8A5 0x9A24 # 0 +0x8EA2E8A6 0x9A1B # 0 +0x8EA2E8A7 0x9A22 # 0 +0x8EA2E8A8 0x9A20 # 0 +0x8EA2E8A9 0x9A27 # 0 +0x8EA2E8AA 0x9A23 # 0 +0x8EA2E8AB 0x9A1E # 0 +0x8EA2E8AC 0x9A1C # 0 +0x8EA2E8AD 0x9A14 # 0 +0x8EA2E8AE 0x9AC2 # 0 +0x8EA2E8AF 0x9B0B # 0 +0x8EA2E8B0 0x9B0A # 0 +0x8EA2E8B1 0x9B0E # 0 +0x8EA2E8B2 0x9B0C # 0 +0x8EA2E8B3 0x9B37 # 0 +0x8EA2E8B4 0x9BEA # 0 +0x8EA2E8B5 0x9BEB # 0 +0x8EA2E8B6 0x9BE0 # 0 +0x8EA2E8B7 0x9BDE # 0 +0x8EA2E8B8 0x9BE4 # 0 +0x8EA2E8B9 0x9BE6 # 0 +0x8EA2E8BA 0x9BE2 # 0 +0x8EA2E8BB 0x9BF0 # 0 +0x8EA2E8BC 0x9BD4 # 0 +0x8EA2E8BD 0x9BD7 # 0 +0x8EA2E8BE 0x9BEC # 0 +0x8EA2E8BF 0x9BDC # 0 +0x8EA2E8C0 0x9BD9 # 0 +0x8EA2E8C1 0x9BE5 # 0 +0x8EA2E8C2 0x9BD5 # 0 +0x8EA2E8C3 0x9BE1 # 0 +0x8EA2E8C4 0x9BDA # 0 +0x8EA2E8C5 0x9D77 # 0 +0x8EA2E8C6 0x9D81 # 0 +0x8EA2E8C7 0x9D8A # 0 +0x8EA2E8C8 0x9D84 # 0 +0x8EA2E8C9 0x9D88 # 0 +0x8EA2E8CA 0x9D71 # 0 +0x8EA2E8CB 0x9D80 # 0 +0x8EA2E8CC 0x9D78 # 0 +0x8EA2E8CD 0x9D86 # 0 +0x8EA2E8CE 0x9D8B # 0 +0x8EA2E8CF 0x9D8C # 0 +0x8EA2E8D0 0x9D7D # 0 +0x8EA2E8D1 0x9D6B # 0 +0x8EA2E8D2 0x9D74 # 0 +0x8EA2E8D3 0x9D75 # 0 +0x8EA2E8D4 0x9D70 # 0 +0x8EA2E8D5 0x9D69 # 0 +0x8EA2E8D6 0x9D85 # 0 +0x8EA2E8D7 0x9D73 # 0 +0x8EA2E8D8 0x9D7B # 0 +0x8EA2E8D9 0x9D82 # 0 +0x8EA2E8DA 0x9D6F # 0 +0x8EA2E8DB 0x9D79 # 0 +0x8EA2E8DC 0x9D7F # 0 +0x8EA2E8DD 0x9D87 # 0 +0x8EA2E8DE 0x9D68 # 0 +0x8EA2E8DF 0x9E94 # 0 +0x8EA2E8E0 0x9E91 # 0 +0x8EA2E8E1 0x9EC0 # 0 +0x8EA2E8E2 0x9EFC # 0 +0x8EA2E8E3 0x9F2D # 0 +0x8EA2E8E4 0x9F40 # 0 +0x8EA2E8E5 0x9F41 # 0 +0x8EA2E8E6 0x9F4D # 0 +0x8EA2E8E7 0x9F56 # 0 +0x8EA2E8E8 0x9F57 # 0 +0x8EA2E8E9 0x9F58 # 0 +0x8EA2E8EA 0x5337 # 0 +0x8EA2E8EB 0x56B2 # 0 +0x8EA2E8EC 0x56B5 # 0 +0x8EA2E8ED 0x56B3 # 0 +0x8EA2E8EE 0x58E3 # 0 +0x8EA2E8EF 0x5B45 # 0 +0x8EA2E8F0 0x5DC6 # 0 +0x8EA2E8F1 0x5DC7 # 0 +0x8EA2E8F2 0x5EEE # 0 +0x8EA2E8F3 0x5EEF # 0 +0x8EA2E8F4 0x5FC0 # 0 +0x8EA2E8F5 0x5FC1 # 0 +0x8EA2E8F6 0x61F9 # 0 +0x8EA2E8F7 0x6517 # 0 +0x8EA2E8F8 0x6516 # 0 +0x8EA2E8F9 0x6515 # 0 +0x8EA2E8FA 0x6513 # 0 +0x8EA2E8FB 0x65DF # 0 +0x8EA2E8FC 0x66E8 # 0 +0x8EA2E8FD 0x66E3 # 0 +0x8EA2E8FE 0x66E4 # 0 +0x8EA2E9A1 0x6AF3 # 0 +0x8EA2E9A2 0x6AF0 # 0 +0x8EA2E9A3 0x6AEA # 0 +0x8EA2E9A4 0x6AE8 # 0 +0x8EA2E9A5 0x6AF9 # 0 +0x8EA2E9A6 0x6AF1 # 0 +0x8EA2E9A7 0x6AEE # 0 +0x8EA2E9A8 0x6AEF # 0 +0x8EA2E9A9 0x703C # 0 +0x8EA2E9AA 0x7035 # 0 +0x8EA2E9AB 0x702F # 0 +0x8EA2E9AC 0x7037 # 0 +0x8EA2E9AD 0x7034 # 0 +0x8EA2E9AE 0x7031 # 0 +0x8EA2E9AF 0x7042 # 0 +0x8EA2E9B0 0x7038 # 0 +0x8EA2E9B1 0x703F # 0 +0x8EA2E9B2 0x703A # 0 +0x8EA2E9B3 0x7039 # 0 +0x8EA2E9B4 0x702A # 0 +0x8EA2E9B5 0x7040 # 0 +0x8EA2E9B6 0x703B # 0 +0x8EA2E9B7 0x7033 # 0 +0x8EA2E9B8 0x7041 # 0 +0x8EA2E9B9 0x7213 # 0 +0x8EA2E9BA 0x7214 # 0 +0x8EA2E9BB 0x72A8 # 0 +0x8EA2E9BC 0x737D # 0 +0x8EA2E9BD 0x737C # 0 +0x8EA2E9BE 0x74BA # 0 +0x8EA2E9BF 0x76AB # 0 +0x8EA2E9C0 0x76AA # 0 +0x8EA2E9C1 0x76BE # 0 +0x8EA2E9C2 0x76ED # 0 +0x8EA2E9C3 0x77CC # 0 +0x8EA2E9C4 0x77CE # 0 +0x8EA2E9C5 0x77CF # 0 +0x8EA2E9C6 0x77CD # 0 +0x8EA2E9C7 0x77F2 # 0 +0x8EA2E9C8 0x7925 # 0 +0x8EA2E9C9 0x7923 # 0 +0x8EA2E9CA 0x7927 # 0 +0x8EA2E9CB 0x7928 # 0 +0x8EA2E9CC 0x7924 # 0 +0x8EA2E9CD 0x7929 # 0 +0x8EA2E9CE 0x79B2 # 0 +0x8EA2E9CF 0x7A6E # 0 +0x8EA2E9D0 0x7A6C # 0 +0x8EA2E9D1 0x7A6D # 0 +0x8EA2E9D2 0x7AF7 # 0 +0x8EA2E9D3 0x7C49 # 0 +0x8EA2E9D4 0x7C48 # 0 +0x8EA2E9D5 0x7C4A # 0 +0x8EA2E9D6 0x7C47 # 0 +0x8EA2E9D7 0x7C45 # 0 +0x8EA2E9D8 0x7CEE # 0 +0x8EA2E9D9 0x7E7B # 0 +0x8EA2E9DA 0x7E7E # 0 +0x8EA2E9DB 0x7E81 # 0 +0x8EA2E9DC 0x7E80 # 0 +0x8EA2E9DD 0x7FBA # 0 +0x8EA2E9DE 0x7FFF # 0 +0x8EA2E9DF 0x8079 # 0 +0x8EA2E9E0 0x81DB # 0 +0x8EA2E9E1 0x81D9 # 0 +0x8EA2E9E2 0x8268 # 0 +0x8EA2E9E3 0x8269 # 0 +0x8EA2E9E4 0x8622 # 0 +0x8EA2E9E5 0x85FF # 0 +0x8EA2E9E6 0x8601 # 0 +0x8EA2E9E7 0x85FE # 0 +0x8EA2E9E8 0x861B # 0 +0x8EA2E9E9 0x8600 # 0 +0x8EA2E9EA 0x85F6 # 0 +0x8EA2E9EB 0x8604 # 0 +0x8EA2E9EC 0x8609 # 0 +0x8EA2E9ED 0x8605 # 0 +0x8EA2E9EE 0x860C # 0 +0x8EA2E9EF 0x85FD # 0 +0x8EA2E9F0 0x8819 # 0 +0x8EA2E9F1 0x8810 # 0 +0x8EA2E9F2 0x8811 # 0 +0x8EA2E9F3 0x8817 # 0 +0x8EA2E9F4 0x8813 # 0 +0x8EA2E9F5 0x8816 # 0 +0x8EA2E9F6 0x8963 # 0 +0x8EA2E9F7 0x8966 # 0 +0x8EA2E9F8 0x89B9 # 0 +0x8EA2E9F9 0x89F7 # 0 +0x8EA2E9FA 0x8B60 # 0 +0x8EA2E9FB 0x8B6A # 0 +0x8EA2E9FC 0x8B5D # 0 +0x8EA2E9FD 0x8B68 # 0 +0x8EA2E9FE 0x8B63 # 0 +0x8EA2EAA1 0x8B65 # 0 +0x8EA2EAA2 0x8B67 # 0 +0x8EA2EAA3 0x8B6D # 0 +0x8EA2EAA4 0x8DAE # 0 +0x8EA2EAA5 0x8E86 # 0 +0x8EA2EAA6 0x8E88 # 0 +0x8EA2EAA7 0x8E84 # 0 +0x8EA2EAA8 0x8F59 # 0 +0x8EA2EAA9 0x8F56 # 0 +0x8EA2EAAA 0x8F57 # 0 +0x8EA2EAAB 0x8F55 # 0 +0x8EA2EAAC 0x8F58 # 0 +0x8EA2EAAD 0x8F5A # 0 +0x8EA2EAAE 0x908D # 0 +0x8EA2EAAF 0x9143 # 0 +0x8EA2EAB0 0x9141 # 0 +0x8EA2EAB1 0x91B7 # 0 +0x8EA2EAB2 0x91B5 # 0 +0x8EA2EAB3 0x91B2 # 0 +0x8EA2EAB4 0x91B3 # 0 +0x8EA2EAB5 0x940B # 0 +0x8EA2EAB6 0x9413 # 0 +0x8EA2EAB7 0x93FB # 0 +0x8EA2EAB8 0x9420 # 0 +0x8EA2EAB9 0x940F # 0 +0x8EA2EABA 0x9414 # 0 +0x8EA2EABB 0x93FE # 0 +0x8EA2EABC 0x9415 # 0 +0x8EA2EABD 0x9410 # 0 +0x8EA2EABE 0x9428 # 0 +0x8EA2EABF 0x9419 # 0 +0x8EA2EAC0 0x940D # 0 +0x8EA2EAC1 0x93F5 # 0 +0x8EA2EAC2 0x9400 # 0 +0x8EA2EAC3 0x93F7 # 0 +0x8EA2EAC4 0x9407 # 0 +0x8EA2EAC5 0x940E # 0 +0x8EA2EAC6 0x9416 # 0 +0x8EA2EAC7 0x9412 # 0 +0x8EA2EAC8 0x93FA # 0 +0x8EA2EAC9 0x9409 # 0 +0x8EA2EACA 0x93F8 # 0 +0x8EA2EACB 0x943C # 0 +0x8EA2EACC 0x940A # 0 +0x8EA2EACD 0x93FF # 0 +0x8EA2EACE 0x93FC # 0 +0x8EA2EACF 0x940C # 0 +0x8EA2EAD0 0x93F6 # 0 +0x8EA2EAD1 0x9411 # 0 +0x8EA2EAD2 0x9406 # 0 +0x8EA2EAD3 0x95DE # 0 +0x8EA2EAD4 0x95E0 # 0 +0x8EA2EAD5 0x95DF # 0 +0x8EA2EAD6 0x972E # 0 +0x8EA2EAD7 0x972F # 0 +0x8EA2EAD8 0x97B9 # 0 +0x8EA2EAD9 0x97BB # 0 +0x8EA2EADA 0x97FD # 0 +0x8EA2EADB 0x97FE # 0 +0x8EA2EADC 0x9860 # 0 +0x8EA2EADD 0x9862 # 0 +0x8EA2EADE 0x9863 # 0 +0x8EA2EADF 0x985F # 0 +0x8EA2EAE0 0x98C1 # 0 +0x8EA2EAE1 0x98C2 # 0 +0x8EA2EAE2 0x9950 # 0 +0x8EA2EAE3 0x994E # 0 +0x8EA2EAE4 0x9959 # 0 +0x8EA2EAE5 0x994C # 0 +0x8EA2EAE6 0x994B # 0 +0x8EA2EAE7 0x9953 # 0 +0x8EA2EAE8 0x9A32 # 0 +0x8EA2EAE9 0x9A34 # 0 +0x8EA2EAEA 0x9A31 # 0 +0x8EA2EAEB 0x9A2C # 0 +0x8EA2EAEC 0x9A2A # 0 +0x8EA2EAED 0x9A36 # 0 +0x8EA2EAEE 0x9A29 # 0 +0x8EA2EAEF 0x9A2E # 0 +0x8EA2EAF0 0x9A38 # 0 +0x8EA2EAF1 0x9A2D # 0 +0x8EA2EAF2 0x9AC7 # 0 +0x8EA2EAF3 0x9ACA # 0 +0x8EA2EAF4 0x9AC6 # 0 +0x8EA2EAF5 0x9B10 # 0 +0x8EA2EAF6 0x9B12 # 0 +0x8EA2EAF7 0x9B11 # 0 +0x8EA2EAF8 0x9C0B # 0 +0x8EA2EAF9 0x9C08 # 0 +0x8EA2EAFA 0x9BF7 # 0 +0x8EA2EAFB 0x9C05 # 0 +0x8EA2EAFC 0x9C12 # 0 +0x8EA2EAFD 0x9BF8 # 0 +0x8EA2EAFE 0x9C40 # 0 +0x8EA2EBA1 0x9C07 # 0 +0x8EA2EBA2 0x9C0E # 0 +0x8EA2EBA3 0x9C06 # 0 +0x8EA2EBA4 0x9C17 # 0 +0x8EA2EBA5 0x9C14 # 0 +0x8EA2EBA6 0x9C09 # 0 +0x8EA2EBA7 0x9D9F # 0 +0x8EA2EBA8 0x9D99 # 0 +0x8EA2EBA9 0x9DA4 # 0 +0x8EA2EBAA 0x9D9D # 0 +0x8EA2EBAB 0x9D92 # 0 +0x8EA2EBAC 0x9D98 # 0 +0x8EA2EBAD 0x9D90 # 0 +0x8EA2EBAE 0x9D9B # 0 +0x8EA2EBAF 0x9DA0 # 0 +0x8EA2EBB0 0x9D94 # 0 +0x8EA2EBB1 0x9D9C # 0 +0x8EA2EBB2 0x9DAA # 0 +0x8EA2EBB3 0x9D97 # 0 +0x8EA2EBB4 0x9DA1 # 0 +0x8EA2EBB5 0x9D9A # 0 +0x8EA2EBB6 0x9DA2 # 0 +0x8EA2EBB7 0x9DA8 # 0 +0x8EA2EBB8 0x9D9E # 0 +0x8EA2EBB9 0x9DA3 # 0 +0x8EA2EBBA 0x9DBF # 0 +0x8EA2EBBB 0x9DA9 # 0 +0x8EA2EBBC 0x9D96 # 0 +0x8EA2EBBD 0x9DA6 # 0 +0x8EA2EBBE 0x9DA7 # 0 +0x8EA2EBBF 0x9E99 # 0 +0x8EA2EBC0 0x9E9B # 0 +0x8EA2EBC1 0x9E9A # 0 +0x8EA2EBC2 0x9EE5 # 0 +0x8EA2EBC3 0x9EE4 # 0 +0x8EA2EBC4 0x9EE7 # 0 +0x8EA2EBC5 0x9EE6 # 0 +0x8EA2EBC6 0x9F30 # 0 +0x8EA2EBC7 0x9F2E # 0 +0x8EA2EBC8 0x9F5B # 0 +0x8EA2EBC9 0x9F60 # 0 +0x8EA2EBCA 0x9F5E # 0 +0x8EA2EBCB 0x9F5D # 0 +0x8EA2EBCC 0x9F59 # 0 +0x8EA2EBCD 0x9F91 # 0 +0x8EA2EBCE 0x513A # 0 +0x8EA2EBCF 0x5139 # 0 +0x8EA2EBD0 0x5298 # 0 +0x8EA2EBD1 0x5297 # 0 +0x8EA2EBD2 0x56C3 # 0 +0x8EA2EBD3 0x56BD # 0 +0x8EA2EBD4 0x56BE # 0 +0x8EA2EBD5 0x5B48 # 0 +0x8EA2EBD6 0x5B47 # 0 +0x8EA2EBD7 0x5DCB # 0 +0x8EA2EBD8 0x5DCF # 0 +0x8EA2EBD9 0x5EF1 # 0 +0x8EA2EBDA 0x61FD # 0 +0x8EA2EBDB 0x651B # 0 +0x8EA2EBDC 0x6B02 # 0 +0x8EA2EBDD 0x6AFC # 0 +0x8EA2EBDE 0x6B03 # 0 +0x8EA2EBDF 0x6AF8 # 0 +0x8EA2EBE0 0x6B00 # 0 +0x8EA2EBE1 0x7043 # 0 +0x8EA2EBE2 0x7044 # 0 +0x8EA2EBE3 0x704A # 0 +0x8EA2EBE4 0x7048 # 0 +0x8EA2EBE5 0x7049 # 0 +0x8EA2EBE6 0x7045 # 0 +0x8EA2EBE7 0x7046 # 0 +0x8EA2EBE8 0x721D # 0 +0x8EA2EBE9 0x721A # 0 +0x8EA2EBEA 0x7219 # 0 +0x8EA2EBEB 0x737E # 0 +0x8EA2EBEC 0x7517 # 0 +0x8EA2EBED 0x766A # 0 +0x8EA2EBEE 0x77D0 # 0 +0x8EA2EBEF 0x792D # 0 +0x8EA2EBF0 0x7931 # 0 +0x8EA2EBF1 0x792F # 0 +0x8EA2EBF2 0x7C54 # 0 +0x8EA2EBF3 0x7C53 # 0 +0x8EA2EBF4 0x7CF2 # 0 +0x8EA2EBF5 0x7E8A # 0 +0x8EA2EBF6 0x7E87 # 0 +0x8EA2EBF7 0x7E88 # 0 +0x8EA2EBF8 0x7E8B # 0 +0x8EA2EBF9 0x7E86 # 0 +0x8EA2EBFA 0x7E8D # 0 +0x8EA2EBFB 0x7F4D # 0 +0x8EA2EBFC 0x7FBB # 0 +0x8EA2EBFD 0x8030 # 0 +0x8EA2EBFE 0x81DD # 0 +0x8EA2ECA1 0x8618 # 0 +0x8EA2ECA2 0x862A # 0 +0x8EA2ECA3 0x8626 # 0 +0x8EA2ECA4 0x861F # 0 +0x8EA2ECA5 0x8623 # 0 +0x8EA2ECA6 0x861C # 0 +0x8EA2ECA7 0x8619 # 0 +0x8EA2ECA8 0x8627 # 0 +0x8EA2ECA9 0x862E # 0 +0x8EA2ECAA 0x8621 # 0 +0x8EA2ECAB 0x8620 # 0 +0x8EA2ECAC 0x8629 # 0 +0x8EA2ECAD 0x861E # 0 +0x8EA2ECAE 0x8625 # 0 +0x8EA2ECAF 0x8829 # 0 +0x8EA2ECB0 0x881D # 0 +0x8EA2ECB1 0x881B # 0 +0x8EA2ECB2 0x8820 # 0 +0x8EA2ECB3 0x8824 # 0 +0x8EA2ECB4 0x881C # 0 +0x8EA2ECB5 0x882B # 0 +0x8EA2ECB6 0x884A # 0 +0x8EA2ECB7 0x896D # 0 +0x8EA2ECB8 0x8969 # 0 +0x8EA2ECB9 0x896E # 0 +0x8EA2ECBA 0x896B # 0 +0x8EA2ECBB 0x89FA # 0 +0x8EA2ECBC 0x8B79 # 0 +0x8EA2ECBD 0x8B78 # 0 +0x8EA2ECBE 0x8B45 # 0 +0x8EA2ECBF 0x8B7A # 0 +0x8EA2ECC0 0x8B7B # 0 +0x8EA2ECC1 0x8D10 # 0 +0x8EA2ECC2 0x8D14 # 0 +0x8EA2ECC3 0x8DAF # 0 +0x8EA2ECC4 0x8E8E # 0 +0x8EA2ECC5 0x8E8C # 0 +0x8EA2ECC6 0x8F5E # 0 +0x8EA2ECC7 0x8F5B # 0 +0x8EA2ECC8 0x8F5D # 0 +0x8EA2ECC9 0x9146 # 0 +0x8EA2ECCA 0x9144 # 0 +0x8EA2ECCB 0x9145 # 0 +0x8EA2ECCC 0x91B9 # 0 +0x8EA2ECCD 0x943F # 0 +0x8EA2ECCE 0x943B # 0 +0x8EA2ECCF 0x9436 # 0 +0x8EA2ECD0 0x9429 # 0 +0x8EA2ECD1 0x943D # 0 +0x8EA2ECD2 0x9430 # 0 +0x8EA2ECD3 0x9439 # 0 +0x8EA2ECD4 0x942A # 0 +0x8EA2ECD5 0x9437 # 0 +0x8EA2ECD6 0x942C # 0 +0x8EA2ECD7 0x9440 # 0 +0x8EA2ECD8 0x9431 # 0 +0x8EA2ECD9 0x95E5 # 0 +0x8EA2ECDA 0x95E4 # 0 +0x8EA2ECDB 0x95E3 # 0 +0x8EA2ECDC 0x9735 # 0 +0x8EA2ECDD 0x973A # 0 +0x8EA2ECDE 0x97BF # 0 +0x8EA2ECDF 0x97E1 # 0 +0x8EA2ECE0 0x9864 # 0 +0x8EA2ECE1 0x98C9 # 0 +0x8EA2ECE2 0x98C6 # 0 +0x8EA2ECE3 0x98C0 # 0 +0x8EA2ECE4 0x9958 # 0 +0x8EA2ECE5 0x9956 # 0 +0x8EA2ECE6 0x9A39 # 0 +0x8EA2ECE7 0x9A3D # 0 +0x8EA2ECE8 0x9A46 # 0 +0x8EA2ECE9 0x9A44 # 0 +0x8EA2ECEA 0x9A42 # 0 +0x8EA2ECEB 0x9A41 # 0 +0x8EA2ECEC 0x9A3A # 0 +0x8EA2ECED 0x9A3F # 0 +0x8EA2ECEE 0x9ACD # 0 +0x8EA2ECEF 0x9B15 # 0 +0x8EA2ECF0 0x9B17 # 0 +0x8EA2ECF1 0x9B18 # 0 +0x8EA2ECF2 0x9B16 # 0 +0x8EA2ECF3 0x9B3A # 0 +0x8EA2ECF4 0x9B52 # 0 +0x8EA2ECF5 0x9C2B # 0 +0x8EA2ECF6 0x9C1D # 0 +0x8EA2ECF7 0x9C1C # 0 +0x8EA2ECF8 0x9C2C # 0 +0x8EA2ECF9 0x9C23 # 0 +0x8EA2ECFA 0x9C28 # 0 +0x8EA2ECFB 0x9C29 # 0 +0x8EA2ECFC 0x9C24 # 0 +0x8EA2ECFD 0x9C21 # 0 +0x8EA2ECFE 0x9DB7 # 0 +0x8EA2EDA1 0x9DB6 # 0 +0x8EA2EDA2 0x9DBC # 0 +0x8EA2EDA3 0x9DC1 # 0 +0x8EA2EDA4 0x9DC7 # 0 +0x8EA2EDA5 0x9DCA # 0 +0x8EA2EDA6 0x9DCF # 0 +0x8EA2EDA7 0x9DBE # 0 +0x8EA2EDA8 0x9DC5 # 0 +0x8EA2EDA9 0x9DC3 # 0 +0x8EA2EDAA 0x9DBB # 0 +0x8EA2EDAB 0x9DB5 # 0 +0x8EA2EDAC 0x9DCE # 0 +0x8EA2EDAD 0x9DB9 # 0 +0x8EA2EDAE 0x9DBA # 0 +0x8EA2EDAF 0x9DAC # 0 +0x8EA2EDB0 0x9DC8 # 0 +0x8EA2EDB1 0x9DB1 # 0 +0x8EA2EDB2 0x9DAD # 0 +0x8EA2EDB3 0x9DCC # 0 +0x8EA2EDB4 0x9DB3 # 0 +0x8EA2EDB5 0x9DCD # 0 +0x8EA2EDB6 0x9DB2 # 0 +0x8EA2EDB7 0x9E7A # 0 +0x8EA2EDB8 0x9E9C # 0 +0x8EA2EDB9 0x9EEB # 0 +0x8EA2EDBA 0x9EEE # 0 +0x8EA2EDBB 0x9EED # 0 +0x8EA2EDBC 0x9F1B # 0 +0x8EA2EDBD 0x9F18 # 0 +0x8EA2EDBE 0x9F1A # 0 +0x8EA2EDBF 0x9F31 # 0 +0x8EA2EDC0 0x9F4E # 0 +0x8EA2EDC1 0x9F65 # 0 +0x8EA2EDC2 0x9F64 # 0 +0x8EA2EDC3 0x9F92 # 0 +0x8EA2EDC4 0x4EB9 # 0 +0x8EA2EDC5 0x56C6 # 0 +0x8EA2EDC6 0x56C5 # 0 +0x8EA2EDC7 0x56CB # 0 +0x8EA2EDC8 0x5971 # 0 +0x8EA2EDC9 0x5B4B # 0 +0x8EA2EDCA 0x5B4C # 0 +0x8EA2EDCB 0x5DD5 # 0 +0x8EA2EDCC 0x5DD1 # 0 +0x8EA2EDCD 0x5EF2 # 0 +0x8EA2EDCE 0x6521 # 0 +0x8EA2EDCF 0x6520 # 0 +0x8EA2EDD0 0x6526 # 0 +0x8EA2EDD1 0x6522 # 0 +0x8EA2EDD2 0x6B0B # 0 +0x8EA2EDD3 0x6B08 # 0 +0x8EA2EDD4 0x6B09 # 0 +0x8EA2EDD5 0x6C0D # 0 +0x8EA2EDD6 0x7055 # 0 +0x8EA2EDD7 0x7056 # 0 +0x8EA2EDD8 0x7057 # 0 +0x8EA2EDD9 0x7052 # 0 +0x8EA2EDDA 0x721E # 0 +0x8EA2EDDB 0x721F # 0 +0x8EA2EDDC 0x72A9 # 0 +0x8EA2EDDD 0x737F # 0 +0x8EA2EDDE 0x74D8 # 0 +0x8EA2EDDF 0x74D5 # 0 +0x8EA2EDE0 0x74D9 # 0 +0x8EA2EDE1 0x74D7 # 0 +0x8EA2EDE2 0x766D # 0 +0x8EA2EDE3 0x76AD # 0 +0x8EA2EDE4 0x7935 # 0 +0x8EA2EDE5 0x79B4 # 0 +0x8EA2EDE6 0x7A70 # 0 +0x8EA2EDE7 0x7A71 # 0 +0x8EA2EDE8 0x7C57 # 0 +0x8EA2EDE9 0x7C5C # 0 +0x8EA2EDEA 0x7C59 # 0 +0x8EA2EDEB 0x7C5B # 0 +0x8EA2EDEC 0x7C5A # 0 +0x8EA2EDED 0x7CF4 # 0 +0x8EA2EDEE 0x7CF1 # 0 +0x8EA2EDEF 0x7E91 # 0 +0x8EA2EDF0 0x7F4F # 0 +0x8EA2EDF1 0x7F87 # 0 +0x8EA2EDF2 0x81DE # 0 +0x8EA2EDF3 0x826B # 0 +0x8EA2EDF4 0x8634 # 0 +0x8EA2EDF5 0x8635 # 0 +0x8EA2EDF6 0x8633 # 0 +0x8EA2EDF7 0x862C # 0 +0x8EA2EDF8 0x8632 # 0 +0x8EA2EDF9 0x8636 # 0 +0x8EA2EDFA 0x882C # 0 +0x8EA2EDFB 0x8828 # 0 +0x8EA2EDFC 0x8826 # 0 +0x8EA2EDFD 0x882A # 0 +0x8EA2EDFE 0x8825 # 0 +0x8EA2EEA1 0x8971 # 0 +0x8EA2EEA2 0x89BF # 0 +0x8EA2EEA3 0x89BE # 0 +0x8EA2EEA4 0x89FB # 0 +0x8EA2EEA5 0x8B7E # 0 +0x8EA2EEA6 0x8B84 # 0 +0x8EA2EEA7 0x8B82 # 0 +0x8EA2EEA8 0x8B86 # 0 +0x8EA2EEA9 0x8B85 # 0 +0x8EA2EEAA 0x8B7F # 0 +0x8EA2EEAB 0x8D15 # 0 +0x8EA2EEAC 0x8E95 # 0 +0x8EA2EEAD 0x8E94 # 0 +0x8EA2EEAE 0x8E9A # 0 +0x8EA2EEAF 0x8E92 # 0 +0x8EA2EEB0 0x8E90 # 0 +0x8EA2EEB1 0x8E96 # 0 +0x8EA2EEB2 0x8E97 # 0 +0x8EA2EEB3 0x8F60 # 0 +0x8EA2EEB4 0x8F62 # 0 +0x8EA2EEB5 0x9147 # 0 +0x8EA2EEB6 0x944C # 0 +0x8EA2EEB7 0x9450 # 0 +0x8EA2EEB8 0x944A # 0 +0x8EA2EEB9 0x944B # 0 +0x8EA2EEBA 0x944F # 0 +0x8EA2EEBB 0x9447 # 0 +0x8EA2EEBC 0x9445 # 0 +0x8EA2EEBD 0x9448 # 0 +0x8EA2EEBE 0x9449 # 0 +0x8EA2EEBF 0x9446 # 0 +0x8EA2EEC0 0x973F # 0 +0x8EA2EEC1 0x97E3 # 0 +0x8EA2EEC2 0x986A # 0 +0x8EA2EEC3 0x9869 # 0 +0x8EA2EEC4 0x98CB # 0 +0x8EA2EEC5 0x9954 # 0 +0x8EA2EEC6 0x995B # 0 +0x8EA2EEC7 0x9A4E # 0 +0x8EA2EEC8 0x9A53 # 0 +0x8EA2EEC9 0x9A54 # 0 +0x8EA2EECA 0x9A4C # 0 +0x8EA2EECB 0x9A4F # 0 +0x8EA2EECC 0x9A48 # 0 +0x8EA2EECD 0x9A4A # 0 +0x8EA2EECE 0x9A49 # 0 +0x8EA2EECF 0x9A52 # 0 +0x8EA2EED0 0x9A50 # 0 +0x8EA2EED1 0x9AD0 # 0 +0x8EA2EED2 0x9B19 # 0 +0x8EA2EED3 0x9B2B # 0 +0x8EA2EED4 0x9B3B # 0 +0x8EA2EED5 0x9B56 # 0 +0x8EA2EED6 0x9B55 # 0 +0x8EA2EED7 0x9C46 # 0 +0x8EA2EED8 0x9C48 # 0 +0x8EA2EED9 0x9C3F # 0 +0x8EA2EEDA 0x9C44 # 0 +0x8EA2EEDB 0x9C39 # 0 +0x8EA2EEDC 0x9C33 # 0 +0x8EA2EEDD 0x9C41 # 0 +0x8EA2EEDE 0x9C3C # 0 +0x8EA2EEDF 0x9C37 # 0 +0x8EA2EEE0 0x9C34 # 0 +0x8EA2EEE1 0x9C32 # 0 +0x8EA2EEE2 0x9C3D # 0 +0x8EA2EEE3 0x9C36 # 0 +0x8EA2EEE4 0x9DDB # 0 +0x8EA2EEE5 0x9DD2 # 0 +0x8EA2EEE6 0x9DDE # 0 +0x8EA2EEE7 0x9DDA # 0 +0x8EA2EEE8 0x9DCB # 0 +0x8EA2EEE9 0x9DD0 # 0 +0x8EA2EEEA 0x9DDC # 0 +0x8EA2EEEB 0x9DD1 # 0 +0x8EA2EEEC 0x9DDF # 0 +0x8EA2EEED 0x9DE9 # 0 +0x8EA2EEEE 0x9DD9 # 0 +0x8EA2EEEF 0x9DD8 # 0 +0x8EA2EEF0 0x9DD6 # 0 +0x8EA2EEF1 0x9DF5 # 0 +0x8EA2EEF2 0x9DD5 # 0 +0x8EA2EEF3 0x9DDD # 0 +0x8EA2EEF4 0x9EB6 # 0 +0x8EA2EEF5 0x9EF0 # 0 +0x8EA2EEF6 0x9F35 # 0 +0x8EA2EEF7 0x9F33 # 0 +0x8EA2EEF8 0x9F32 # 0 +0x8EA2EEF9 0x9F42 # 0 +0x8EA2EEFA 0x9F6B # 0 +0x8EA2EEFB 0x9F95 # 0 +0x8EA2EEFC 0x9FA2 # 0 +0x8EA2EEFD 0x513D # 0 +0x8EA2EEFE 0x5299 # 0 +0x8EA2EFA1 0x58E8 # 0 +0x8EA2EFA2 0x58E7 # 0 +0x8EA2EFA3 0x5972 # 0 +0x8EA2EFA4 0x5B4D # 0 +0x8EA2EFA5 0x5DD8 # 0 +0x8EA2EFA6 0x882F # 0 +0x8EA2EFA7 0x5F4F # 0 +0x8EA2EFA8 0x6201 # 0 +0x8EA2EFA9 0x6203 # 0 +0x8EA2EFAA 0x6204 # 0 +0x8EA2EFAB 0x6529 # 0 +0x8EA2EFAC 0x6525 # 0 +0x8EA2EFAD 0x6596 # 0 +0x8EA2EFAE 0x66EB # 0 +0x8EA2EFAF 0x6B11 # 0 +0x8EA2EFB0 0x6B12 # 0 +0x8EA2EFB1 0x6B0F # 0 +0x8EA2EFB2 0x6BCA # 0 +0x8EA2EFB3 0x705B # 0 +0x8EA2EFB4 0x705A # 0 +0x8EA2EFB5 0x7222 # 0 +0x8EA2EFB6 0x7382 # 0 +0x8EA2EFB7 0x7381 # 0 +0x8EA2EFB8 0x7383 # 0 +0x8EA2EFB9 0x7670 # 0 +0x8EA2EFBA 0x77D4 # 0 +0x8EA2EFBB 0x7C67 # 0 +0x8EA2EFBC 0x7C66 # 0 +0x8EA2EFBD 0x7E95 # 0 +0x8EA2EFBE 0x826C # 0 +0x8EA2EFBF 0x863A # 0 +0x8EA2EFC0 0x8640 # 0 +0x8EA2EFC1 0x8639 # 0 +0x8EA2EFC2 0x863C # 0 +0x8EA2EFC3 0x8631 # 0 +0x8EA2EFC4 0x863B # 0 +0x8EA2EFC5 0x863E # 0 +0x8EA2EFC6 0x8830 # 0 +0x8EA2EFC7 0x8832 # 0 +0x8EA2EFC8 0x882E # 0 +0x8EA2EFC9 0x8833 # 0 +0x8EA2EFCA 0x8976 # 0 +0x8EA2EFCB 0x8974 # 0 +0x8EA2EFCC 0x8973 # 0 +0x8EA2EFCD 0x89FE # 0 +0x8EA2EFCE 0x8B8C # 0 +0x8EA2EFCF 0x8B8E # 0 +0x8EA2EFD0 0x8B8B # 0 +0x8EA2EFD1 0x8B88 # 0 +0x8EA2EFD2 0x8C45 # 0 +0x8EA2EFD3 0x8D19 # 0 +0x8EA2EFD4 0x8E98 # 0 +0x8EA2EFD5 0x8F64 # 0 +0x8EA2EFD6 0x8F63 # 0 +0x8EA2EFD7 0x91BC # 0 +0x8EA2EFD8 0x9462 # 0 +0x8EA2EFD9 0x9455 # 0 +0x8EA2EFDA 0x945D # 0 +0x8EA2EFDB 0x9457 # 0 +0x8EA2EFDC 0x945E # 0 +0x8EA2EFDD 0x97C4 # 0 +0x8EA2EFDE 0x97C5 # 0 +0x8EA2EFDF 0x9800 # 0 +0x8EA2EFE0 0x9A56 # 0 +0x8EA2EFE1 0x9A59 # 0 +0x8EA2EFE2 0x9B1E # 0 +0x8EA2EFE3 0x9B1F # 0 +0x8EA2EFE4 0x9B20 # 0 +0x8EA2EFE5 0x9C52 # 0 +0x8EA2EFE6 0x9C58 # 0 +0x8EA2EFE7 0x9C50 # 0 +0x8EA2EFE8 0x9C4A # 0 +0x8EA2EFE9 0x9C4D # 0 +0x8EA2EFEA 0x9C4B # 0 +0x8EA2EFEB 0x9C55 # 0 +0x8EA2EFEC 0x9C59 # 0 +0x8EA2EFED 0x9C4C # 0 +0x8EA2EFEE 0x9C4E # 0 +0x8EA2EFEF 0x9DFB # 0 +0x8EA2EFF0 0x9DF7 # 0 +0x8EA2EFF1 0x9DEF # 0 +0x8EA2EFF2 0x9DE3 # 0 +0x8EA2EFF3 0x9DEB # 0 +0x8EA2EFF4 0x9DF8 # 0 +0x8EA2EFF5 0x9DE4 # 0 +0x8EA2EFF6 0x9DF6 # 0 +0x8EA2EFF7 0x9DE1 # 0 +0x8EA2EFF8 0x9DEE # 0 +0x8EA2EFF9 0x9DE6 # 0 +0x8EA2EFFA 0x9DF2 # 0 +0x8EA2EFFB 0x9DF0 # 0 +0x8EA2EFFC 0x9DE2 # 0 +0x8EA2EFFD 0x9DEC # 0 +0x8EA2EFFE 0x9DF4 # 0 +0x8EA2F0A1 0x9DF3 # 0 +0x8EA2F0A2 0x9DE8 # 0 +0x8EA2F0A3 0x9DED # 0 +0x8EA2F0A4 0x9EC2 # 0 +0x8EA2F0A5 0x9ED0 # 0 +0x8EA2F0A6 0x9EF2 # 0 +0x8EA2F0A7 0x9EF3 # 0 +0x8EA2F0A8 0x9F06 # 0 +0x8EA2F0A9 0x9F1C # 0 +0x8EA2F0AA 0x9F38 # 0 +0x8EA2F0AB 0x9F37 # 0 +0x8EA2F0AC 0x9F36 # 0 +0x8EA2F0AD 0x9F43 # 0 +0x8EA2F0AE 0x9F4F # 0 +0x8EA2F0AF 0x9F71 # 0 +0x8EA2F0B0 0x9F70 # 0 +0x8EA2F0B1 0x9F6E # 0 +0x8EA2F0B2 0x9F6F # 0 +0x8EA2F0B3 0x56D3 # 0 +0x8EA2F0B4 0x56CD # 0 +0x8EA2F0B5 0x5B4E # 0 +0x8EA2F0B6 0x5C6D # 0 +0x8EA2F0B7 0x652D # 0 +0x8EA2F0B8 0x66ED # 0 +0x8EA2F0B9 0x66EE # 0 +0x8EA2F0BA 0x6B13 # 0 +0x8EA2F0BB 0x705F # 0 +0x8EA2F0BC 0x7061 # 0 +0x8EA2F0BD 0x705D # 0 +0x8EA2F0BE 0x7060 # 0 +0x8EA2F0BF 0x7223 # 0 +0x8EA2F0C0 0x74DB # 0 +0x8EA2F0C1 0x74E5 # 0 +0x8EA2F0C2 0x77D5 # 0 +0x8EA2F0C3 0x7938 # 0 +0x8EA2F0C4 0x79B7 # 0 +0x8EA2F0C5 0x79B6 # 0 +0x8EA2F0C6 0x7C6A # 0 +0x8EA2F0C7 0x7E97 # 0 +0x8EA2F0C8 0x7F89 # 0 +0x8EA2F0C9 0x826D # 0 +0x8EA2F0CA 0x8643 # 0 +0x8EA2F0CB 0x8838 # 0 +0x8EA2F0CC 0x8837 # 0 +0x8EA2F0CD 0x8835 # 0 +0x8EA2F0CE 0x884B # 0 +0x8EA2F0CF 0x8B94 # 0 +0x8EA2F0D0 0x8B95 # 0 +0x8EA2F0D1 0x8E9E # 0 +0x8EA2F0D2 0x8E9F # 0 +0x8EA2F0D3 0x8EA0 # 0 +0x8EA2F0D4 0x8E9D # 0 +0x8EA2F0D5 0x91BE # 0 +0x8EA2F0D6 0x91BD # 0 +0x8EA2F0D7 0x91C2 # 0 +0x8EA2F0D8 0x946B # 0 +0x8EA2F0D9 0x9468 # 0 +0x8EA2F0DA 0x9469 # 0 +0x8EA2F0DB 0x96E5 # 0 +0x8EA2F0DC 0x9746 # 0 +0x8EA2F0DD 0x9743 # 0 +0x8EA2F0DE 0x9747 # 0 +0x8EA2F0DF 0x97C7 # 0 +0x8EA2F0E0 0x97E5 # 0 +0x8EA2F0E1 0x9A5E # 0 +0x8EA2F0E2 0x9AD5 # 0 +0x8EA2F0E3 0x9B59 # 0 +0x8EA2F0E4 0x9C63 # 0 +0x8EA2F0E5 0x9C67 # 0 +0x8EA2F0E6 0x9C66 # 0 +0x8EA2F0E7 0x9C62 # 0 +0x8EA2F0E8 0x9C5E # 0 +0x8EA2F0E9 0x9C60 # 0 +0x8EA2F0EA 0x9E02 # 0 +0x8EA2F0EB 0x9DFE # 0 +0x8EA2F0EC 0x9E07 # 0 +0x8EA2F0ED 0x9E03 # 0 +0x8EA2F0EE 0x9E06 # 0 +0x8EA2F0EF 0x9E05 # 0 +0x8EA2F0F0 0x9E00 # 0 +0x8EA2F0F1 0x9E01 # 0 +0x8EA2F0F2 0x9E09 # 0 +0x8EA2F0F3 0x9DFF # 0 +0x8EA2F0F4 0x9DFD # 0 +0x8EA2F0F5 0x9E04 # 0 +0x8EA2F0F6 0x9EA0 # 0 +0x8EA2F0F7 0x9F1E # 0 +0x8EA2F0F8 0x9F46 # 0 +0x8EA2F0F9 0x9F74 # 0 +0x8EA2F0FA 0x9F75 # 0 +0x8EA2F0FB 0x9F76 # 0 +0x8EA2F0FC 0x56D4 # 0 +0x8EA2F0FD 0x652E # 0 +0x8EA2F0FE 0x65B8 # 0 +0x8EA2F1A1 0x6B18 # 0 +0x8EA2F1A2 0x6B19 # 0 +0x8EA2F1A3 0x6B17 # 0 +0x8EA2F1A4 0x6B1A # 0 +0x8EA2F1A5 0x7062 # 0 +0x8EA2F1A6 0x7226 # 0 +0x8EA2F1A7 0x72AA # 0 +0x8EA2F1A8 0x77D8 # 0 +0x8EA2F1A9 0x77D9 # 0 +0x8EA2F1AA 0x7939 # 0 +0x8EA2F1AB 0x7C69 # 0 +0x8EA2F1AC 0x7C6B # 0 +0x8EA2F1AD 0x7CF6 # 0 +0x8EA2F1AE 0x7E9A # 0 +0x8EA2F1AF 0x7E98 # 0 +0x8EA2F1B0 0x7E9B # 0 +0x8EA2F1B1 0x7E99 # 0 +0x8EA2F1B2 0x81E0 # 0 +0x8EA2F1B3 0x81E1 # 0 +0x8EA2F1B4 0x8646 # 0 +0x8EA2F1B5 0x8647 # 0 +0x8EA2F1B6 0x8648 # 0 +0x8EA2F1B7 0x8979 # 0 +0x8EA2F1B8 0x897A # 0 +0x8EA2F1B9 0x897C # 0 +0x8EA2F1BA 0x897B # 0 +0x8EA2F1BB 0x89FF # 0 +0x8EA2F1BC 0x8B98 # 0 +0x8EA2F1BD 0x8B99 # 0 +0x8EA2F1BE 0x8EA5 # 0 +0x8EA2F1BF 0x8EA4 # 0 +0x8EA2F1C0 0x8EA3 # 0 +0x8EA2F1C1 0x946E # 0 +0x8EA2F1C2 0x946D # 0 +0x8EA2F1C3 0x946F # 0 +0x8EA2F1C4 0x9471 # 0 +0x8EA2F1C5 0x9473 # 0 +0x8EA2F1C6 0x9749 # 0 +0x8EA2F1C7 0x9872 # 0 +0x8EA2F1C8 0x995F # 0 +0x8EA2F1C9 0x9C68 # 0 +0x8EA2F1CA 0x9C6E # 0 +0x8EA2F1CB 0x9C6D # 0 +0x8EA2F1CC 0x9E0B # 0 +0x8EA2F1CD 0x9E0D # 0 +0x8EA2F1CE 0x9E10 # 0 +0x8EA2F1CF 0x9E0F # 0 +0x8EA2F1D0 0x9E12 # 0 +0x8EA2F1D1 0x9E11 # 0 +0x8EA2F1D2 0x9EA1 # 0 +0x8EA2F1D3 0x9EF5 # 0 +0x8EA2F1D4 0x9F09 # 0 +0x8EA2F1D5 0x9F47 # 0 +0x8EA2F1D6 0x9F78 # 0 +0x8EA2F1D7 0x9F7B # 0 +0x8EA2F1D8 0x9F7A # 0 +0x8EA2F1D9 0x9F79 # 0 +0x8EA2F1DA 0x571E # 0 +0x8EA2F1DB 0x7066 # 0 +0x8EA2F1DC 0x7C6F # 0 +0x8EA2F1DD 0x883C # 0 +0x8EA2F1DE 0x8DB2 # 0 +0x8EA2F1DF 0x8EA6 # 0 +0x8EA2F1E0 0x91C3 # 0 +0x8EA2F1E1 0x9474 # 0 +0x8EA2F1E2 0x9478 # 0 +0x8EA2F1E3 0x9476 # 0 +0x8EA2F1E4 0x9475 # 0 +0x8EA2F1E5 0x9A60 # 0 +0x8EA2F1E6 0x9B2E # 0 +0x8EA2F1E7 0x9C74 # 0 +0x8EA2F1E8 0x9C73 # 0 +0x8EA2F1E9 0x9C71 # 0 +0x8EA2F1EA 0x9C75 # 0 +0x8EA2F1EB 0x9E14 # 0 +0x8EA2F1EC 0x9E13 # 0 +0x8EA2F1ED 0x9EF6 # 0 +0x8EA2F1EE 0x9F0A # 0 +0x8EA2F1EF 0x9FA4 # 0 +0x8EA2F1F0 0x7068 # 0 +0x8EA2F1F1 0x7065 # 0 +0x8EA2F1F2 0x7CF7 # 0 +0x8EA2F1F3 0x866A # 0 +0x8EA2F1F4 0x883E # 0 +0x8EA2F1F5 0x883D # 0 +0x8EA2F1F6 0x883F # 0 +0x8EA2F1F7 0x8B9E # 0 +0x8EA2F1F8 0x8C9C # 0 +0x8EA2F1F9 0x8EA9 # 0 +0x8EA2F1FA 0x8EC9 # 0 +0x8EA2F1FB 0x974B # 0 +0x8EA2F1FC 0x9873 # 0 +0x8EA2F1FD 0x9874 # 0 +0x8EA2F1FE 0x98CC # 0 +0x8EA2F2A1 0x9961 # 0 +0x8EA2F2A2 0x99AB # 0 +0x8EA2F2A3 0x9A64 # 0 +0x8EA2F2A4 0x9A66 # 0 +0x8EA2F2A5 0x9A67 # 0 +0x8EA2F2A6 0x9B24 # 0 +0x8EA2F2A7 0x9E15 # 0 +0x8EA2F2A8 0x9E17 # 0 +0x8EA2F2A9 0x9F48 # 0 +0x8EA2F2AA 0x6207 # 0 +0x8EA2F2AB 0x6B1E # 0 +0x8EA2F2AC 0x7227 # 0 +0x8EA2F2AD 0x864C # 0 +0x8EA2F2AE 0x8EA8 # 0 +0x8EA2F2AF 0x9482 # 0 +0x8EA2F2B0 0x9480 # 0 +0x8EA2F2B1 0x9481 # 0 +0x8EA2F2B2 0x9A69 # 0 +0x8EA2F2B3 0x9A68 # 0 +0x8EA2F2B4 0x9E19 # 0 +0x8EA2F2B5 0x864B # 0 +0x8EA2F2B6 0x8B9F # 0 +0x8EA2F2B7 0x9483 # 0 +0x8EA2F2B8 0x9C79 # 0 +0x8EA2F2B9 0x9EB7 # 0 +0x8EA2F2BA 0x7675 # 0 +0x8EA2F2BB 0x9A6B # 0 +0x8EA2F2BC 0x9C7A # 0 +0x8EA2F2BD 0x9E1D # 0 +0x8EA2F2BE 0x7069 # 0 +0x8EA2F2BF 0x706A # 0 +0x8EA2F2C0 0x7229 # 0 +0x8EA2F2C1 0x9EA4 # 0 +0x8EA2F2C2 0x9F7E # 0 +0x8EA2F2C3 0x9F49 # 0 +0x8EA2F2C4 0x9F98 # 0 +0x8EA3A1A1 0x4E28 # 0 +0x8EA3A1A2 0x4E36 # 0 +0x8EA3A1A3 0x4E3F # 0 +0x8EA3A1A4 0x4E85 # 0 +0x8EA3A1A5 0x4E05 # 0 +0x8EA3A1A6 0x4E04 # 0 +0x8EA3A1A7 0x5182 # 0 +0x8EA3A1A8 0x5196 # 0 +0x8EA3A1A9 0x5338 # 0 +0x8EA3A1AA 0x5369 # 0 +0x8EA3A1AB 0x53B6 # 0 +0x8EA3A1AC 0x4E2A # 0 +0x8EA3A1AD 0x4E87 # 0 +0x8EA3A1AE 0x4E49 # 0 +0x8EA3A1AF 0x51E2 # 0 +0x8EA3A1B0 0x4E46 # 0 +0x8EA3A1B1 0x4E8F # 0 +0x8EA3A1B2 0x4EBC # 0 +0x8EA3A1B3 0x4EBE # 0 +0x8EA3A1B4 0x5166 # 0 +0x8EA3A1B5 0x51E3 # 0 +0x8EA3A1B6 0x5204 # 0 +0x8EA3A1B7 0x529C # 0 +0x8EA3A1B9 0x5902 # 0 +0x8EA3A1BA 0x590A # 0 +0x8EA3A1BB 0x5B80 # 0 +0x8EA3A1BC 0x5DDB # 0 +0x8EA3A1BD 0x5E7A # 0 +0x8EA3A1BE 0x5E7F # 0 +0x8EA3A1BF 0x5EF4 # 0 +0x8EA3A1C0 0x5F50 # 0 +0x8EA3A1C1 0x5F51 # 0 +0x8EA3A1C2 0x5F61 # 0 +0x8EA3A1C3 0x961D # 0 +0x8EA3A1C5 0x4E63 # 0 +0x8EA3A1C6 0x4E62 # 0 +0x8EA3A1C7 0x4EA3 # 0 +0x8EA3A1C8 0x5185 # 0 +0x8EA3A1C9 0x4EC5 # 0 +0x8EA3A1CA 0x4ECF # 0 +0x8EA3A1CB 0x4ECE # 0 +0x8EA3A1CC 0x4ECC # 0 +0x8EA3A1CD 0x5184 # 0 +0x8EA3A1CE 0x5186 # 0 +0x8EA3A1D1 0x51E4 # 0 +0x8EA3A1D2 0x5205 # 0 +0x8EA3A1D3 0x529E # 0 +0x8EA3A1D4 0x529D # 0 +0x8EA3A1D5 0x52FD # 0 +0x8EA3A1D6 0x5300 # 0 +0x8EA3A1D7 0x533A # 0 +0x8EA3A1D9 0x5346 # 0 +0x8EA3A1DA 0x535D # 0 +0x8EA3A1DB 0x5386 # 0 +0x8EA3A1DC 0x53B7 # 0 +0x8EA3A1DE 0x53CC # 0 +0x8EA3A1E0 0x53CE # 0 +0x8EA3A1E1 0x5721 # 0 +0x8EA3A1E3 0x5E00 # 0 +0x8EA3A1E4 0x5F0C # 0 +0x8EA3A1E5 0x6237 # 0 +0x8EA3A1E6 0x6238 # 0 +0x8EA3A1E7 0x6534 # 0 +0x8EA3A1E8 0x6535 # 0 +0x8EA3A1E9 0x65E0 # 0 +0x8EA3A1EB 0x738D # 0 +0x8EA3A1EC 0x4E97 # 0 +0x8EA3A1ED 0x4EE0 # 0 +0x8EA3A1F0 0x4EE7 # 0 +0x8EA3A1F2 0x4EE6 # 0 +0x8EA3A1F7 0x56D8 # 0 +0x8EA3A1F8 0x518B # 0 +0x8EA3A1F9 0x518C # 0 +0x8EA3A1FA 0x5199 # 0 +0x8EA3A1FB 0x51E5 # 0 +0x8EA3A1FD 0x520B # 0 +0x8EA3A2A2 0x5304 # 0 +0x8EA3A2A3 0x5303 # 0 +0x8EA3A2A4 0x5307 # 0 +0x8EA3A2A6 0x531E # 0 +0x8EA3A2A7 0x535F # 0 +0x8EA3A2A8 0x536D # 0 +0x8EA3A2A9 0x5389 # 0 +0x8EA3A2AA 0x53BA # 0 +0x8EA3A2AB 0x53D0 # 0 +0x8EA3A2AD 0x53F6 # 0 +0x8EA3A2AE 0x53F7 # 0 +0x8EA3A2AF 0x53F9 # 0 +0x8EA3A2B1 0x53F4 # 0 +0x8EA3A2B4 0x5724 # 0 +0x8EA3A2B5 0x5904 # 0 +0x8EA3A2B6 0x5918 # 0 +0x8EA3A2B7 0x5932 # 0 +0x8EA3A2B8 0x5930 # 0 +0x8EA3A2B9 0x5934 # 0 +0x8EA3A2BB 0x5975 # 0 +0x8EA3A2BD 0x5B82 # 0 +0x8EA3A2BE 0x5BF9 # 0 +0x8EA3A2BF 0x5C14 # 0 +0x8EA3A2C7 0x5E81 # 0 +0x8EA3A2C8 0x5E83 # 0 +0x8EA3A2C9 0x5F0D # 0 +0x8EA3A2CA 0x5F52 # 0 +0x8EA3A2CC 0x5FCA # 0 +0x8EA3A2CD 0x5FC7 # 0 +0x8EA3A2CE 0x6239 # 0 +0x8EA3A2D0 0x624F # 0 +0x8EA3A2D1 0x65E7 # 0 +0x8EA3A2D2 0x672F # 0 +0x8EA3A2D3 0x6B7A # 0 +0x8EA3A2D4 0x6C39 # 0 +0x8EA3A2D7 0x6C37 # 0 +0x8EA3A2D8 0x6C44 # 0 +0x8EA3A2D9 0x6C45 # 0 +0x8EA3A2DA 0x738C # 0 +0x8EA3A2DB 0x7592 # 0 +0x8EA3A2DC 0x7676 # 0 +0x8EA3A2DD 0x9093 # 0 +0x8EA3A2DE 0x9092 # 0 +0x8EA3A2E1 0x4E21 # 0 +0x8EA3A2E2 0x4E20 # 0 +0x8EA3A2E3 0x4E22 # 0 +0x8EA3A2E4 0x4E68 # 0 +0x8EA3A2E5 0x4E89 # 0 +0x8EA3A2E6 0x4E98 # 0 +0x8EA3A2E7 0x4EF9 # 0 +0x8EA3A2E8 0x4EEF # 0 +0x8EA3A2EB 0x4EF8 # 0 +0x8EA3A2EC 0x4F06 # 0 +0x8EA3A2ED 0x4F03 # 0 +0x8EA3A2EE 0x4EFC # 0 +0x8EA3A2EF 0x4EEE # 0 +0x8EA3A2F0 0x4F16 # 0 +0x8EA3A2F2 0x4F28 # 0 +0x8EA3A2F3 0x4F1C # 0 +0x8EA3A2F4 0x4F07 # 0 +0x8EA3A2F5 0x4F1A # 0 +0x8EA3A2F6 0x4EFA # 0 +0x8EA3A2F7 0x4F17 # 0 +0x8EA3A2F8 0x514A # 0 +0x8EA3A2FA 0x5172 # 0 +0x8EA3A2FC 0x51B4 # 0 +0x8EA3A2FD 0x51B3 # 0 +0x8EA3A2FE 0x51B2 # 0 +0x8EA3A3A2 0x51E8 # 0 +0x8EA3A3A4 0x5214 # 0 +0x8EA3A3A5 0x520F # 0 +0x8EA3A3A6 0x5215 # 0 +0x8EA3A3A7 0x5218 # 0 +0x8EA3A3A8 0x52A8 # 0 +0x8EA3A3AA 0x534B # 0 +0x8EA3A3AB 0x534F # 0 +0x8EA3A3AD 0x5350 # 0 +0x8EA3A3AF 0x538B # 0 +0x8EA3A3B1 0x53BE # 0 +0x8EA3A3B3 0x53D2 # 0 +0x8EA3A3B4 0x5416 # 0 +0x8EA3A3B5 0x53FF # 0 +0x8EA3A3B7 0x5400 # 0 +0x8EA3A3B9 0x5405 # 0 +0x8EA3A3BA 0x5413 # 0 +0x8EA3A3BB 0x5415 # 0 +0x8EA3A3BE 0x56E3 # 0 +0x8EA3A3BF 0x5735 # 0 +0x8EA3A3C0 0x5736 # 0 +0x8EA3A3C1 0x5731 # 0 +0x8EA3A3C2 0x5732 # 0 +0x8EA3A3C3 0x58EE # 0 +0x8EA3A3C4 0x5905 # 0 +0x8EA3A3C5 0x4E54 # 0 +0x8EA3A3C7 0x5936 # 0 +0x8EA3A3CB 0x597A # 0 +0x8EA3A3CD 0x5986 # 0 +0x8EA3A3D0 0x5B86 # 0 +0x8EA3A3D1 0x5F53 # 0 +0x8EA3A3D2 0x5C18 # 0 +0x8EA3A3D4 0x5C3D # 0 +0x8EA3A3D5 0x5C78 # 0 +0x8EA3A3DA 0x5C80 # 0 +0x8EA3A3DC 0x5E08 # 0 +0x8EA3A3E1 0x5EF5 # 0 +0x8EA3A3E2 0x5F0E # 0 +0x8EA3A3E6 0x5FD3 # 0 +0x8EA3A3E7 0x5FDA # 0 +0x8EA3A3E9 0x5FDB # 0 +0x8EA3A3EB 0x620F # 0 +0x8EA3A3EC 0x625D # 0 +0x8EA3A3ED 0x625F # 0 +0x8EA3A3EE 0x6267 # 0 +0x8EA3A3EF 0x6257 # 0 +0x8EA3A3F0 0x9F50 # 0 +0x8EA3A3F2 0x65EB # 0 +0x8EA3A3F3 0x65EA # 0 +0x8EA3A3F5 0x6737 # 0 +0x8EA3A3F7 0x6732 # 0 +0x8EA3A3F8 0x6736 # 0 +0x8EA3A3F9 0x6B22 # 0 +0x8EA3A3FA 0x6BCE # 0 +0x8EA3A3FC 0x6C58 # 0 +0x8EA3A3FD 0x6C51 # 0 +0x8EA3A3FE 0x6C77 # 0 +0x8EA3A4A1 0x6C3C # 0 +0x8EA3A4A3 0x6C5A # 0 +0x8EA3A4A5 0x6C53 # 0 +0x8EA3A4A6 0x706F # 0 +0x8EA3A4A7 0x7072 # 0 +0x8EA3A4A8 0x706E # 0 +0x8EA3A4AB 0x7073 # 0 +0x8EA3A4AC 0x72B1 # 0 +0x8EA3A4AD 0x72B2 # 0 +0x8EA3A4AF 0x738F # 0 +0x8EA3A4B3 0x793C # 0 +0x8EA3A4B5 0x808D # 0 +0x8EA3A4B6 0x808E # 0 +0x8EA3A4B8 0x827B # 0 +0x8EA3A4BA 0x8D71 # 0 +0x8EA3A4BB 0x8FB9 # 0 +0x8EA3A4BC 0x9096 # 0 +0x8EA3A4BD 0x909A # 0 +0x8EA3A4BF 0x4E24 # 0 +0x8EA3A4C0 0x4E71 # 0 +0x8EA3A4C2 0x4E9C # 0 +0x8EA3A4C3 0x4F45 # 0 +0x8EA3A4C4 0x4F4A # 0 +0x8EA3A4C5 0x4F39 # 0 +0x8EA3A4C6 0x4F37 # 0 +0x8EA3A4C8 0x4F32 # 0 +0x8EA3A4C9 0x4F42 # 0 +0x8EA3A4CB 0x4F44 # 0 +0x8EA3A4CC 0x4F4B # 0 +0x8EA3A4CE 0x4F40 # 0 +0x8EA3A4CF 0x4F35 # 0 +0x8EA3A4D0 0x4F31 # 0 +0x8EA3A4D1 0x5151 # 0 +0x8EA3A4D3 0x5150 # 0 +0x8EA3A4D4 0x514E # 0 +0x8EA3A4D7 0x519D # 0 +0x8EA3A4D9 0x51B5 # 0 +0x8EA3A4DA 0x51B8 # 0 +0x8EA3A4DB 0x51EC # 0 +0x8EA3A4DC 0x5223 # 0 +0x8EA3A4DD 0x5227 # 0 +0x8EA3A4DE 0x5226 # 0 +0x8EA3A4DF 0x521F # 0 +0x8EA3A4E0 0x522B # 0 +0x8EA3A4E1 0x5220 # 0 +0x8EA3A4E2 0x52B4 # 0 +0x8EA3A4E3 0x52B3 # 0 +0x8EA3A4E5 0x5325 # 0 +0x8EA3A4E6 0x533B # 0 +0x8EA3A4E7 0x5374 # 0 +0x8EA3A4ED 0x544D # 0 +0x8EA3A4F0 0x543A # 0 +0x8EA3A4F3 0x5444 # 0 +0x8EA3A4F4 0x544C # 0 +0x8EA3A4F5 0x5423 # 0 +0x8EA3A4F6 0x541A # 0 +0x8EA3A4F7 0x5432 # 0 +0x8EA3A4F8 0x544B # 0 +0x8EA3A4F9 0x5421 # 0 +0x8EA3A4FB 0x5434 # 0 +0x8EA3A4FC 0x5449 # 0 +0x8EA3A4FD 0x5450 # 0 +0x8EA3A4FE 0x5422 # 0 +0x8EA3A5A1 0x543F # 0 +0x8EA3A5A2 0x5451 # 0 +0x8EA3A5A3 0x545A # 0 +0x8EA3A5A4 0x542F # 0 +0x8EA3A5A6 0x56E9 # 0 +0x8EA3A5A7 0x56F2 # 0 +0x8EA3A5A8 0x56F3 # 0 +0x8EA3A5A9 0x56EF # 0 +0x8EA3A5AA 0x56ED # 0 +0x8EA3A5AB 0x56EC # 0 +0x8EA3A5AC 0x56E6 # 0 +0x8EA3A5AD 0x5748 # 0 +0x8EA3A5AF 0x5744 # 0 +0x8EA3A5B0 0x573F # 0 +0x8EA3A5B1 0x573C # 0 +0x8EA3A5B2 0x5753 # 0 +0x8EA3A5B3 0x5756 # 0 +0x8EA3A5B5 0x575F # 0 +0x8EA3A5B6 0x5743 # 0 +0x8EA3A5B7 0x5758 # 0 +0x8EA3A5B8 0x5757 # 0 +0x8EA3A5BC 0x5746 # 0 +0x8EA3A5BE 0x573D # 0 +0x8EA3A5C0 0x5742 # 0 +0x8EA3A5C1 0x5754 # 0 +0x8EA3A5C2 0x5755 # 0 +0x8EA3A5C3 0x58F1 # 0 +0x8EA3A5C4 0x58F2 # 0 +0x8EA3A5C5 0x58F0 # 0 +0x8EA3A5C6 0x590B # 0 +0x8EA3A5C7 0x9EA6 # 0 +0x8EA3A5C8 0x56F1 # 0 +0x8EA3A5C9 0x593D # 0 +0x8EA3A5CB 0x5994 # 0 +0x8EA3A5CC 0x598C # 0 +0x8EA3A5CE 0x599C # 0 +0x8EA3A5D1 0x599F # 0 +0x8EA3A5D3 0x599B # 0 +0x8EA3A5D5 0x5989 # 0 +0x8EA3A5D6 0x599A # 0 +0x8EA3A5D8 0x6588 # 0 +0x8EA3A5DA 0x5B8D # 0 +0x8EA3A5DC 0x5BFE # 0 +0x8EA3A5DD 0x5BFF # 0 +0x8EA3A5DE 0x5BFD # 0 +0x8EA3A5DF 0x5C2B # 0 +0x8EA3A5E1 0x5C84 # 0 +0x8EA3A5E2 0x5C8E # 0 +0x8EA3A5E3 0x5C9C # 0 +0x8EA3A5E6 0x5C85 # 0 +0x8EA3A5E7 0x5DF5 # 0 +0x8EA3A5E8 0x5E09 # 0 +0x8EA3A5EB 0x5E0B # 0 +0x8EA3A5ED 0x5E92 # 0 +0x8EA3A5EE 0x5E90 # 0 +0x8EA3A5EF 0x5F03 # 0 +0x8EA3A5F1 0x5F1E # 0 +0x8EA3A5F2 0x5F63 # 0 +0x8EA3A5F4 0x5FE7 # 0 +0x8EA3A5F5 0x5FFE # 0 +0x8EA3A5F6 0x5FE6 # 0 +0x8EA3A5F7 0x5FDC # 0 +0x8EA3A5F8 0x5FCE # 0 +0x8EA3A5FA 0x5FFC # 0 +0x8EA3A5FB 0x5FDF # 0 +0x8EA3A5FC 0x5FEC # 0 +0x8EA3A5FD 0x5FF6 # 0 +0x8EA3A6A1 0x5FF2 # 0 +0x8EA3A6A2 0x5FF0 # 0 +0x8EA3A6A3 0x5FF9 # 0 +0x8EA3A6A5 0x6213 # 0 +0x8EA3A6A8 0x623B # 0 +0x8EA3A6A9 0x623C # 0 +0x8EA3A6AA 0x6282 # 0 +0x8EA3A6AE 0x6278 # 0 +0x8EA3A6AF 0x628B # 0 +0x8EA3A6B1 0x629E # 0 +0x8EA3A6B2 0x62A5 # 0 +0x8EA3A6B3 0x629B # 0 +0x8EA3A6B4 0x629C # 0 +0x8EA3A6B5 0x6299 # 0 +0x8EA3A6B6 0x628D # 0 +0x8EA3A6B7 0x6285 # 0 +0x8EA3A6B8 0x629D # 0 +0x8EA3A6B9 0x6275 # 0 +0x8EA3A6BD 0x65F6 # 0 +0x8EA3A6C1 0x66F5 # 0 +0x8EA3A6C2 0x675B # 0 +0x8EA3A6C4 0x6754 # 0 +0x8EA3A6C5 0x6752 # 0 +0x8EA3A6C7 0x6758 # 0 +0x8EA3A6C8 0x6744 # 0 +0x8EA3A6C9 0x674A # 0 +0x8EA3A6CA 0x6761 # 0 +0x8EA3A6CC 0x6C7F # 0 +0x8EA3A6CD 0x6C91 # 0 +0x8EA3A6CE 0x6C9E # 0 +0x8EA3A6D0 0x6C6E # 0 +0x8EA3A6D1 0x6C7C # 0 +0x8EA3A6D2 0x6C9F # 0 +0x8EA3A6D3 0x6C75 # 0 +0x8EA3A6D5 0x6C56 # 0 +0x8EA3A6D6 0x6CA2 # 0 +0x8EA3A6D7 0x6C79 # 0 +0x8EA3A6D9 0x6CA1 # 0 +0x8EA3A6DB 0x6CAA # 0 +0x8EA3A6DC 0x6CA0 # 0 +0x8EA3A6DE 0x7079 # 0 +0x8EA3A6DF 0x7077 # 0 +0x8EA3A6E0 0x707E # 0 +0x8EA3A6E2 0x7075 # 0 +0x8EA3A6E3 0x707B # 0 +0x8EA3A6E4 0x7264 # 0 +0x8EA3A6E6 0x72BB # 0 +0x8EA3A6E7 0x72BC # 0 +0x8EA3A6E8 0x72C7 # 0 +0x8EA3A6E9 0x72B9 # 0 +0x8EA3A6EA 0x72BE # 0 +0x8EA3A6EB 0x72B6 # 0 +0x8EA3A6EE 0x7398 # 0 +0x8EA3A6F3 0x7593 # 0 +0x8EA3A6F4 0x7680 # 0 +0x8EA3A6F6 0x7683 # 0 +0x8EA3A6F7 0x76C0 # 0 +0x8EA3A6F8 0x76C1 # 0 +0x8EA3A6FB 0x77F4 # 0 +0x8EA3A6FC 0x77F5 # 0 +0x8EA3A6FE 0x7ACC # 0 +0x8EA3A7A1 0x7ACD # 0 +0x8EA3A7A2 0x7CFA # 0 +0x8EA3A7A3 0x809F # 0 +0x8EA3A7A4 0x8091 # 0 +0x8EA3A7A5 0x8097 # 0 +0x8EA3A7A6 0x8094 # 0 +0x8EA3A7A8 0x8286 # 0 +0x8EA3A7A9 0x828C # 0 +0x8EA3A7AB 0x8295 # 0 +0x8EA3A7AD 0x866C # 0 +0x8EA3A7AF 0x8FB5 # 0 +0x8EA3A7B0 0x8FBE # 0 +0x8EA3A7B1 0x8FC7 # 0 +0x8EA3A7B3 0x8FC1 # 0 +0x8EA3A7B4 0x90A9 # 0 +0x8EA3A7B5 0x90A4 # 0 +0x8EA3A7B9 0x90A8 # 0 +0x8EA3A7BA 0x9627 # 0 +0x8EA3A7BB 0x9626 # 0 +0x8EA3A7BC 0x962B # 0 +0x8EA3A7BD 0x9633 # 0 +0x8EA3A7BE 0x9634 # 0 +0x8EA3A7BF 0x9629 # 0 +0x8EA3A7C0 0x4E3D # 0 +0x8EA3A7C2 0x4E9D # 0 +0x8EA3A7C3 0x4F93 # 0 +0x8EA3A7C4 0x4F8A # 0 +0x8EA3A7C7 0x4F6D # 0 +0x8EA3A7C8 0x4F8E # 0 +0x8EA3A7C9 0x4FA0 # 0 +0x8EA3A7CA 0x4FA2 # 0 +0x8EA3A7CB 0x4FA1 # 0 +0x8EA3A7CC 0x4F9F # 0 +0x8EA3A7CD 0x4FA3 # 0 +0x8EA3A7CF 0x4F72 # 0 +0x8EA3A7D1 0x4F8C # 0 +0x8EA3A7D2 0x5156 # 0 +0x8EA3A7D5 0x5190 # 0 +0x8EA3A7D9 0x51ED # 0 +0x8EA3A7DA 0x51FE # 0 +0x8EA3A7DB 0x522F # 0 +0x8EA3A7DD 0x523C # 0 +0x8EA3A7DE 0x5234 # 0 +0x8EA3A7DF 0x5239 # 0 +0x8EA3A7E0 0x52B9 # 0 +0x8EA3A7E1 0x52B5 # 0 +0x8EA3A7E2 0x52BF # 0 +0x8EA3A7E3 0x5355 # 0 +0x8EA3A7E5 0x5376 # 0 +0x8EA3A7E6 0x537A # 0 +0x8EA3A7E7 0x5393 # 0 +0x8EA3A7E9 0x53C1 # 0 +0x8EA3A7EA 0x53C2 # 0 +0x8EA3A7EB 0x53D5 # 0 +0x8EA3A7EC 0x5485 # 0 +0x8EA3A7EE 0x545F # 0 +0x8EA3A7EF 0x5493 # 0 +0x8EA3A7F0 0x5489 # 0 +0x8EA3A7F1 0x5479 # 0 +0x8EA3A7F2 0x9EFE # 0 +0x8EA3A7F3 0x548F # 0 +0x8EA3A7F4 0x5469 # 0 +0x8EA3A7F5 0x546D # 0 +0x8EA3A7F7 0x5494 # 0 +0x8EA3A7F8 0x546A # 0 +0x8EA3A7F9 0x548A # 0 +0x8EA3A7FB 0x56FD # 0 +0x8EA3A7FC 0x56FB # 0 +0x8EA3A7FD 0x56F8 # 0 +0x8EA3A8A1 0x56FC # 0 +0x8EA3A8A2 0x56F6 # 0 +0x8EA3A8A3 0x5765 # 0 +0x8EA3A8A4 0x5781 # 0 +0x8EA3A8A5 0x5763 # 0 +0x8EA3A8A6 0x5767 # 0 +0x8EA3A8A8 0x576E # 0 +0x8EA3A8A9 0x5778 # 0 +0x8EA3A8AA 0x577F # 0 +0x8EA3A8AD 0x58F3 # 0 +0x8EA3A8AE 0x594B # 0 +0x8EA3A8AF 0x594C # 0 +0x8EA3A8B3 0x59AD # 0 +0x8EA3A8B5 0x59C4 # 0 +0x8EA3A8B7 0x59C2 # 0 +0x8EA3A8B8 0x59B0 # 0 +0x8EA3A8BD 0x59BF # 0 +0x8EA3A8BF 0x59C9 # 0 +0x8EA3A8C0 0x59B8 # 0 +0x8EA3A8C1 0x59AC # 0 +0x8EA3A8C5 0x59B7 # 0 +0x8EA3A8C6 0x59D7 # 0 +0x8EA3A8C8 0x5B60 # 0 +0x8EA3A8CA 0x5B96 # 0 +0x8EA3A8CB 0x5B9E # 0 +0x8EA3A8CC 0x5B94 # 0 +0x8EA3A8CD 0x5B9F # 0 +0x8EA3A8CE 0x5B9D # 0 +0x8EA3A8D0 0x5C00 # 0 +0x8EA3A8D1 0x5C19 # 0 +0x8EA3A8D4 0x5C49 # 0 +0x8EA3A8D5 0x5C4A # 0 +0x8EA3A8D7 0x5CBB # 0 +0x8EA3A8D8 0x5CC1 # 0 +0x8EA3A8DC 0x5CB9 # 0 +0x8EA3A8DD 0x5C9E # 0 +0x8EA3A8DE 0x5CB4 # 0 +0x8EA3A8DF 0x5CBA # 0 +0x8EA3A8E0 0x5DF6 # 0 +0x8EA3A8E1 0x5E13 # 0 +0x8EA3A8E2 0x5E12 # 0 +0x8EA3A8E3 0x5E77 # 0 +0x8EA3A8E5 0x5E98 # 0 +0x8EA3A8E7 0x5E99 # 0 +0x8EA3A8E8 0x5E9D # 0 +0x8EA3A8E9 0x5EF8 # 0 +0x8EA3A8EB 0x5EF9 # 0 +0x8EA3A8ED 0x5F06 # 0 +0x8EA3A8EE 0x5F21 # 0 +0x8EA3A8F0 0x5F25 # 0 +0x8EA3A8F1 0x5F55 # 0 +0x8EA3A8F5 0x5F84 # 0 +0x8EA3A8F6 0x5F83 # 0 +0x8EA3A8F7 0x6030 # 0 +0x8EA3A8F8 0x6007 # 0 +0x8EA3A8FA 0x6036 # 0 +0x8EA3A8FE 0x5FE9 # 0 +0x8EA3A9A1 0x603D # 0 +0x8EA3A9A2 0x6008 # 0 +0x8EA3A9A5 0x62BA # 0 +0x8EA3A9A6 0x62B2 # 0 +0x8EA3A9A8 0x62B7 # 0 +0x8EA3A9A9 0x62E4 # 0 +0x8EA3A9AA 0x62A7 # 0 +0x8EA3A9AE 0x62D5 # 0 +0x8EA3A9AF 0x62E1 # 0 +0x8EA3A9B0 0x62DD # 0 +0x8EA3A9B1 0x62A6 # 0 +0x8EA3A9B2 0x62C1 # 0 +0x8EA3A9B3 0x62C5 # 0 +0x8EA3A9B4 0x62C0 # 0 +0x8EA3A9B5 0x62DF # 0 +0x8EA3A9B6 0x62E0 # 0 +0x8EA3A9B7 0x62DE # 0 +0x8EA3A9B9 0x6589 # 0 +0x8EA3A9BB 0x65A6 # 0 +0x8EA3A9BC 0x65BA # 0 +0x8EA3A9BE 0x65FF # 0 +0x8EA3A9C0 0x6617 # 0 +0x8EA3A9C1 0x6618 # 0 +0x8EA3A9C2 0x6601 # 0 +0x8EA3A9C3 0x65FE # 0 +0x8EA3A9C5 0x670C # 0 +0x8EA3A9C7 0x676B # 0 +0x8EA3A9C8 0x6796 # 0 +0x8EA3A9C9 0x6782 # 0 +0x8EA3A9CA 0x678A # 0 +0x8EA3A9CC 0x67A3 # 0 +0x8EA3A9CE 0x67A2 # 0 +0x8EA3A9CF 0x678F # 0 +0x8EA3A9D1 0x67F9 # 0 +0x8EA3A9D2 0x6780 # 0 +0x8EA3A9D3 0x6B26 # 0 +0x8EA3A9D4 0x6B27 # 0 +0x8EA3A9D5 0x6B68 # 0 +0x8EA3A9D6 0x6B69 # 0 +0x8EA3A9D8 0x6B81 # 0 +0x8EA3A9D9 0x6BB4 # 0 +0x8EA3A9DA 0x6BD1 # 0 +0x8EA3A9DD 0x6C1C # 0 +0x8EA3A9E3 0x6C97 # 0 +0x8EA3A9E4 0x6C6C # 0 +0x8EA3A9E5 0x6CDF # 0 +0x8EA3A9E7 0x6CEA # 0 +0x8EA3A9E9 0x6CE4 # 0 +0x8EA3A9EA 0x6CD8 # 0 +0x8EA3A9EB 0x6CB2 # 0 +0x8EA3A9EC 0x6CCE # 0 +0x8EA3A9ED 0x6CC8 # 0 +0x8EA3A9EF 0x708B # 0 +0x8EA3A9F0 0x7088 # 0 +0x8EA3A9F1 0x7090 # 0 +0x8EA3A9F2 0x708F # 0 +0x8EA3A9F4 0x7087 # 0 +0x8EA3A9F5 0x7089 # 0 +0x8EA3A9F6 0x708D # 0 +0x8EA3A9F7 0x7081 # 0 +0x8EA3A9F9 0x708C # 0 +0x8EA3A9FC 0x7240 # 0 +0x8EA3AAA1 0x7265 # 0 +0x8EA3AAA2 0x7266 # 0 +0x8EA3AAA3 0x7268 # 0 +0x8EA3AAA6 0x72CD # 0 +0x8EA3AAA7 0x72D3 # 0 +0x8EA3AAA8 0x72DB # 0 +0x8EA3AAAA 0x72CF # 0 +0x8EA3AAAB 0x73A7 # 0 +0x8EA3AAAC 0x73A3 # 0 +0x8EA3AAAD 0x739E # 0 +0x8EA3AAAF 0x73AF # 0 +0x8EA3AAB2 0x73AA # 0 +0x8EA3AAB3 0x739C # 0 +0x8EA3AAB5 0x7542 # 0 +0x8EA3AAB6 0x7544 # 0 +0x8EA3AAB7 0x753B # 0 +0x8EA3AAB8 0x7541 # 0 +0x8EA3AABA 0x759B # 0 +0x8EA3AABB 0x759E # 0 +0x8EA3AABD 0x79C4 # 0 +0x8EA3AABE 0x79C3 # 0 +0x8EA3AABF 0x79C6 # 0 +0x8EA3AAC2 0x79C7 # 0 +0x8EA3AAC4 0x79CA # 0 +0x8EA3AAC7 0x7ACF # 0 +0x8EA3AAC8 0x7C76 # 0 +0x8EA3AAC9 0x7C74 # 0 +0x8EA3AACA 0x7CFF # 0 +0x8EA3AACB 0x7CFC # 0 +0x8EA3AACE 0x7F59 # 0 +0x8EA3AACF 0x80A8 # 0 +0x8EA3AAD2 0x80B0 # 0 +0x8EA3AAD4 0x80B3 # 0 +0x8EA3AAD6 0x80A4 # 0 +0x8EA3AAD7 0x80B6 # 0 +0x8EA3AAD8 0x80A7 # 0 +0x8EA3AAD9 0x80AC # 0 +0x8EA3AADB 0x80A6 # 0 +0x8EA3AADC 0x5367 # 0 +0x8EA3AADD 0x820E # 0 +0x8EA3AADE 0x82C4 # 0 +0x8EA3AADF 0x833E # 0 +0x8EA3AAE0 0x829C # 0 +0x8EA3AAE6 0x82AA # 0 +0x8EA3AAE8 0x82C9 # 0 +0x8EA3AAEB 0x82A6 # 0 +0x8EA3AAEC 0x82B2 # 0 +0x8EA3AAF0 0x8FCC # 0 +0x8EA3AAF1 0x8FD9 # 0 +0x8EA3AAF2 0x8FCA # 0 +0x8EA3AAF3 0x8FD8 # 0 +0x8EA3AAF4 0x8FCF # 0 +0x8EA3AAF5 0x90B7 # 0 +0x8EA3AAF7 0x90AD # 0 +0x8EA3AAF8 0x90B9 # 0 +0x8EA3AAF9 0x9637 # 0 +0x8EA3AAFB 0x9641 # 0 +0x8EA3AAFC 0x963E # 0 +0x8EA3AAFD 0x96B6 # 0 +0x8EA3AAFE 0x9751 # 0 +0x8EA3ABA1 0x9763 # 0 +0x8EA3ABA2 0x4E57 # 0 +0x8EA3ABA3 0x4E79 # 0 +0x8EA3ABA4 0x4EB2 # 0 +0x8EA3ABA5 0x4EB0 # 0 +0x8EA3ABA6 0x4EAF # 0 +0x8EA3ABA7 0x4EB1 # 0 +0x8EA3ABA8 0x4FD2 # 0 +0x8EA3ABA9 0x4FD5 # 0 +0x8EA3ABAB 0x4FBE # 0 +0x8EA3ABAC 0x4FB8 # 0 +0x8EA3ABAD 0x4FB0 # 0 +0x8EA3ABAE 0x4FB1 # 0 +0x8EA3ABAF 0x4FC8 # 0 +0x8EA3ABB2 0x4FC6 # 0 +0x8EA3ABB3 0x4FCC # 0 +0x8EA3ABB4 0x4FE5 # 0 +0x8EA3ABB5 0x4FE3 # 0 +0x8EA3ABB6 0x4FB4 # 0 +0x8EA3ABB7 0x516A # 0 +0x8EA3ABB9 0x519F # 0 +0x8EA3ABBB 0x51C1 # 0 +0x8EA3ABBD 0x51C2 # 0 +0x8EA3ABBE 0x51C3 # 0 +0x8EA3ABBF 0x5245 # 0 +0x8EA3ABC0 0x5248 # 0 +0x8EA3ABC3 0x524F # 0 +0x8EA3ABC6 0x52C5 # 0 +0x8EA3ABC7 0x52CA # 0 +0x8EA3ABC8 0x52C4 # 0 +0x8EA3ABC9 0x5327 # 0 +0x8EA3ABCA 0x5358 # 0 +0x8EA3ABCB 0x537D # 0 +0x8EA3ABCD 0x53DD # 0 +0x8EA3ABCE 0x53DC # 0 +0x8EA3ABCF 0x53DA # 0 +0x8EA3ABD0 0x53D9 # 0 +0x8EA3ABD1 0x54B9 # 0 +0x8EA3ABD3 0x54D0 # 0 +0x8EA3ABD4 0x54B4 # 0 +0x8EA3ABD5 0x54CA # 0 +0x8EA3ABD7 0x54A3 # 0 +0x8EA3ABD8 0x54DA # 0 +0x8EA3ABD9 0x54A4 # 0 +0x8EA3ABDB 0x54B2 # 0 +0x8EA3ABDC 0x549E # 0 +0x8EA3ABDD 0x549F # 0 +0x8EA3ABDE 0x54B5 # 0 +0x8EA3ABE1 0x54CD # 0 +0x8EA3ABE3 0x54CC # 0 +0x8EA3ABE5 0x5700 # 0 +0x8EA3ABE6 0x57AC # 0 +0x8EA3ABE7 0x5791 # 0 +0x8EA3ABE8 0x578E # 0 +0x8EA3ABE9 0x578D # 0 +0x8EA3ABEA 0x5792 # 0 +0x8EA3ABEB 0x57A1 # 0 +0x8EA3ABEC 0x5790 # 0 +0x8EA3ABED 0x57A6 # 0 +0x8EA3ABEE 0x57A8 # 0 +0x8EA3ABF0 0x579C # 0 +0x8EA3ABF1 0x5796 # 0 +0x8EA3ABF2 0x57A7 # 0 +0x8EA3ABF7 0x58F5 # 0 +0x8EA3ABF9 0x5909 # 0 +0x8EA3ABFA 0x5908 # 0 +0x8EA3ABFC 0x5952 # 0 +0x8EA3ACA1 0x59DF # 0 +0x8EA3ACA3 0x59EB # 0 +0x8EA3ACA4 0x59EF # 0 +0x8EA3ACA5 0x59F0 # 0 +0x8EA3ACA6 0x59D5 # 0 +0x8EA3ACA7 0x5A0D # 0 +0x8EA3ACA8 0x5A04 # 0 +0x8EA3ACA9 0x59F9 # 0 +0x8EA3ACAA 0x5A02 # 0 +0x8EA3ACAB 0x59F8 # 0 +0x8EA3ACAC 0x59E2 # 0 +0x8EA3ACAD 0x59D9 # 0 +0x8EA3ACAE 0x59E7 # 0 +0x8EA3ACAF 0x5B6A # 0 +0x8EA3ACB2 0x5BAB # 0 +0x8EA3ACB4 0x5C1B # 0 +0x8EA3ACB5 0x5C2F # 0 +0x8EA3ACB7 0x663C # 0 +0x8EA3ACBB 0x5CD1 # 0 +0x8EA3ACBC 0x5CDC # 0 +0x8EA3ACBD 0x5CE6 # 0 +0x8EA3ACBE 0x5CE1 # 0 +0x8EA3ACBF 0x5CCD # 0 +0x8EA3ACC1 0x5CE2 # 0 +0x8EA3ACC2 0x5CDD # 0 +0x8EA3ACC3 0x5CE5 # 0 +0x8EA3ACC4 0x5DFB # 0 +0x8EA3ACC5 0x5DFA # 0 +0x8EA3ACC6 0x5E1E # 0 +0x8EA3ACC8 0x5EA1 # 0 +0x8EA3ACCB 0x5EFC # 0 +0x8EA3ACCC 0x5EFB # 0 +0x8EA3ACCD 0x5F2F # 0 +0x8EA3ACD0 0x5F66 # 0 +0x8EA3ACD4 0x605C # 0 +0x8EA3ACD6 0x604E # 0 +0x8EA3ACD7 0x6051 # 0 +0x8EA3ACDA 0x6023 # 0 +0x8EA3ACDB 0x6031 # 0 +0x8EA3ACDC 0x607C # 0 +0x8EA3ACDD 0x6052 # 0 +0x8EA3ACDF 0x6060 # 0 +0x8EA3ACE0 0x604A # 0 +0x8EA3ACE1 0x6061 # 0 +0x8EA3ACE3 0x6218 # 0 +0x8EA3ACEB 0x631F # 0 +0x8EA3ACEC 0x6317 # 0 +0x8EA3ACED 0x62EA # 0 +0x8EA3ACEE 0x6321 # 0 +0x8EA3ACEF 0x6304 # 0 +0x8EA3ACF0 0x6305 # 0 +0x8EA3ACF2 0x6531 # 0 +0x8EA3ACF3 0x6544 # 0 +0x8EA3ACF4 0x6540 # 0 +0x8EA3ACF6 0x6542 # 0 +0x8EA3ACF7 0x65BE # 0 +0x8EA3ACF9 0x6629 # 0 +0x8EA3ACFA 0x661B # 0 +0x8EA3ACFC 0x6623 # 0 +0x8EA3ACFD 0x662C # 0 +0x8EA3ACFE 0x661A # 0 +0x8EA3ADA1 0x6630 # 0 +0x8EA3ADA2 0x663B # 0 +0x8EA3ADA3 0x661E # 0 +0x8EA3ADA4 0x6637 # 0 +0x8EA3ADA5 0x6638 # 0 +0x8EA3ADA7 0x670E # 0 +0x8EA3ADAA 0x67E8 # 0 +0x8EA3ADAB 0x67D6 # 0 +0x8EA3ADAD 0x67C7 # 0 +0x8EA3ADAE 0x67BC # 0 +0x8EA3ADAF 0x6852 # 0 +0x8EA3ADB0 0x67BF # 0 +0x8EA3ADB1 0x67D5 # 0 +0x8EA3ADB2 0x67FE # 0 +0x8EA3ADB3 0x8363 # 0 +0x8EA3ADB4 0x67FB # 0 +0x8EA3ADB6 0x67B1 # 0 +0x8EA3ADB7 0x6801 # 0 +0x8EA3ADB8 0x6805 # 0 +0x8EA3ADB9 0x6800 # 0 +0x8EA3ADBA 0x67D7 # 0 +0x8EA3ADBC 0x6B2A # 0 +0x8EA3ADBD 0x6B6B # 0 +0x8EA3ADC2 0x6BE1 # 0 +0x8EA3ADC5 0x6D23 # 0 +0x8EA3ADC6 0x6CFF # 0 +0x8EA3ADC7 0x6D14 # 0 +0x8EA3ADC8 0x6D05 # 0 +0x8EA3ADC9 0x6D13 # 0 +0x8EA3ADCA 0x6D06 # 0 +0x8EA3ADCB 0x6D21 # 0 +0x8EA3ADCD 0x6D15 # 0 +0x8EA3ADCE 0x6CAF # 0 +0x8EA3ADCF 0x6CF4 # 0 +0x8EA3ADD0 0x6D02 # 0 +0x8EA3ADD1 0x6D45 # 0 +0x8EA3ADD3 0x6D26 # 0 +0x8EA3ADD5 0x6D44 # 0 +0x8EA3ADD7 0x6D24 # 0 +0x8EA3ADD8 0x70A5 # 0 +0x8EA3ADDA 0x70A3 # 0 +0x8EA3ADDC 0x70A2 # 0 +0x8EA3ADDD 0x70BB # 0 +0x8EA3ADDE 0x70A0 # 0 +0x8EA3ADDF 0x70AA # 0 +0x8EA3ADE2 0x70A8 # 0 +0x8EA3ADE3 0x70B6 # 0 +0x8EA3ADE4 0x70B2 # 0 +0x8EA3ADE5 0x70A7 # 0 +0x8EA3ADE8 0x70B9 # 0 +0x8EA3ADE9 0x722E # 0 +0x8EA3ADEB 0x723C # 0 +0x8EA3ADED 0x726D # 0 +0x8EA3ADF0 0x72E7 # 0 +0x8EA3ADF1 0x72ED # 0 +0x8EA3ADF3 0x72EC # 0 +0x8EA3ADF4 0x72E5 # 0 +0x8EA3ADF5 0x72E2 # 0 +0x8EA3ADF7 0x73C4 # 0 +0x8EA3ADF8 0x73BD # 0 +0x8EA3ADF9 0x73CF # 0 +0x8EA3ADFA 0x73C9 # 0 +0x8EA3ADFB 0x73C1 # 0 +0x8EA3ADFC 0x73D0 # 0 +0x8EA3ADFE 0x73CE # 0 +0x8EA3AEA1 0x74ED # 0 +0x8EA3AEA2 0x74EB # 0 +0x8EA3AEA4 0x74EF # 0 +0x8EA3AEA5 0x7549 # 0 +0x8EA3AEA6 0x7550 # 0 +0x8EA3AEA7 0x7546 # 0 +0x8EA3AEA8 0x754A # 0 +0x8EA3AEAA 0x754D # 0 +0x8EA3AEAB 0x75A6 # 0 +0x8EA3AEAF 0x75A8 # 0 +0x8EA3AEB2 0x76C7 # 0 +0x8EA3AEB3 0x76FF # 0 +0x8EA3AEB5 0x76FD # 0 +0x8EA3AEB6 0x77E6 # 0 +0x8EA3AEB7 0x780A # 0 +0x8EA3AEB9 0x7804 # 0 +0x8EA3AEBA 0x780B # 0 +0x8EA3AEBB 0x7807 # 0 +0x8EA3AEBD 0x7815 # 0 +0x8EA3AEBE 0x7808 # 0 +0x8EA3AEC0 0x79D3 # 0 +0x8EA3AEC1 0x79D4 # 0 +0x8EA3AEC2 0x79D0 # 0 +0x8EA3AEC3 0x79D7 # 0 +0x8EA3AEC4 0x7A7C # 0 +0x8EA3AEC7 0x7A7D # 0 +0x8EA3AEC8 0x7A83 # 0 +0x8EA3AEC9 0x7A82 # 0 +0x8EA3AECB 0x7AD4 # 0 +0x8EA3AECC 0x7AD5 # 0 +0x8EA3AECD 0x7AD3 # 0 +0x8EA3AECE 0x7AD0 # 0 +0x8EA3AECF 0x7AD2 # 0 +0x8EA3AED0 0x7AFE # 0 +0x8EA3AED1 0x7AFC # 0 +0x8EA3AED2 0x7C77 # 0 +0x8EA3AED3 0x7C7C # 0 +0x8EA3AED4 0x7C7B # 0 +0x8EA3AEDD 0x7F8F # 0 +0x8EA3AEDE 0x80D3 # 0 +0x8EA3AEE0 0x80CB # 0 +0x8EA3AEE1 0x80D2 # 0 +0x8EA3AEE3 0x8109 # 0 +0x8EA3AEE4 0x80E2 # 0 +0x8EA3AEE5 0x80DF # 0 +0x8EA3AEE6 0x80C6 # 0 +0x8EA3AEE8 0x8224 # 0 +0x8EA3AEE9 0x82F7 # 0 +0x8EA3AEEA 0x82D8 # 0 +0x8EA3AEEB 0x82DD # 0 +0x8EA3AEEE 0x82F8 # 0 +0x8EA3AEEF 0x82FC # 0 +0x8EA3AEF2 0x82E9 # 0 +0x8EA3AEF4 0x82EE # 0 +0x8EA3AEF6 0x82D0 # 0 +0x8EA3AEF7 0x830E # 0 +0x8EA3AEF8 0x82E2 # 0 +0x8EA3AEF9 0x830B # 0 +0x8EA3AEFA 0x82FD # 0 +0x8EA3AEFB 0x5179 # 0 +0x8EA3AEFC 0x8676 # 0 +0x8EA3AEFE 0x8678 # 0 +0x8EA3AFA3 0x8675 # 0 +0x8EA3AFA4 0x867D # 0 +0x8EA3AFA6 0x8842 # 0 +0x8EA3AFA7 0x8866 # 0 +0x8EA3AFA9 0x898C # 0 +0x8EA3AFAA 0x8A05 # 0 +0x8EA3AFAC 0x8A06 # 0 +0x8EA3AFAE 0x8C9F # 0 +0x8EA3AFB0 0x8FF1 # 0 +0x8EA3AFB1 0x8FE7 # 0 +0x8EA3AFB2 0x8FE9 # 0 +0x8EA3AFB3 0x8FEF # 0 +0x8EA3AFB4 0x90C2 # 0 +0x8EA3AFB5 0x90BC # 0 +0x8EA3AFB7 0x90C6 # 0 +0x8EA3AFB8 0x90C0 # 0 +0x8EA3AFBB 0x90CD # 0 +0x8EA3AFBC 0x90C9 # 0 +0x8EA3AFBE 0x90C4 # 0 +0x8EA3AFC0 0x9581 # 0 +0x8EA3AFC2 0x9CEC # 0 +0x8EA3AFC3 0x5032 # 0 +0x8EA3AFC4 0x4FF9 # 0 +0x8EA3AFC5 0x501D # 0 +0x8EA3AFC6 0x4FFF # 0 +0x8EA3AFC7 0x5004 # 0 +0x8EA3AFC8 0x4FF0 # 0 +0x8EA3AFC9 0x5003 # 0 +0x8EA3AFCB 0x5002 # 0 +0x8EA3AFCC 0x4FFC # 0 +0x8EA3AFCD 0x4FF2 # 0 +0x8EA3AFCE 0x5024 # 0 +0x8EA3AFCF 0x5008 # 0 +0x8EA3AFD0 0x5036 # 0 +0x8EA3AFD1 0x502E # 0 +0x8EA3AFD3 0x5010 # 0 +0x8EA3AFD4 0x5038 # 0 +0x8EA3AFD5 0x5039 # 0 +0x8EA3AFD6 0x4FFD # 0 +0x8EA3AFD7 0x5056 # 0 +0x8EA3AFD8 0x4FFB # 0 +0x8EA3AFD9 0x51A3 # 0 +0x8EA3AFDA 0x51A6 # 0 +0x8EA3AFDB 0x51A1 # 0 +0x8EA3AFDE 0x51C7 # 0 +0x8EA3AFDF 0x51C9 # 0 +0x8EA3AFE0 0x5260 # 0 +0x8EA3AFE1 0x5264 # 0 +0x8EA3AFE2 0x5259 # 0 +0x8EA3AFE3 0x5265 # 0 +0x8EA3AFE4 0x5267 # 0 +0x8EA3AFE5 0x5257 # 0 +0x8EA3AFE6 0x5263 # 0 +0x8EA3AFE8 0x5253 # 0 +0x8EA3AFEA 0x52CF # 0 +0x8EA3AFEC 0x52CE # 0 +0x8EA3AFED 0x52D0 # 0 +0x8EA3AFEE 0x52D1 # 0 +0x8EA3AFEF 0x52CC # 0 +0x8EA3AFF3 0x550D # 0 +0x8EA3AFF4 0x54F4 # 0 +0x8EA3AFF6 0x5513 # 0 +0x8EA3AFF7 0x54EF # 0 +0x8EA3AFF8 0x54F5 # 0 +0x8EA3AFF9 0x54F9 # 0 +0x8EA3AFFA 0x5502 # 0 +0x8EA3AFFB 0x5500 # 0 +0x8EA3AFFE 0x5518 # 0 +0x8EA3B0A1 0x54F0 # 0 +0x8EA3B0A2 0x54F6 # 0 +0x8EA3B0A5 0x5519 # 0 +0x8EA3B0A7 0x5705 # 0 +0x8EA3B0A8 0x57C9 # 0 +0x8EA3B0AA 0x57B7 # 0 +0x8EA3B0AB 0x57CD # 0 +0x8EA3B0AF 0x57BE # 0 +0x8EA3B0B0 0x57BB # 0 +0x8EA3B0B2 0x57DB # 0 +0x8EA3B0B3 0x57C8 # 0 +0x8EA3B0B4 0x57C4 # 0 +0x8EA3B0B5 0x57C5 # 0 +0x8EA3B0B6 0x57D1 # 0 +0x8EA3B0B7 0x57CA # 0 +0x8EA3B0B8 0x57C0 # 0 +0x8EA3B0BB 0x5A21 # 0 +0x8EA3B0BC 0x5A2A # 0 +0x8EA3B0BE 0x5A1D # 0 +0x8EA3B0C0 0x5A0B # 0 +0x8EA3B0C5 0x5A22 # 0 +0x8EA3B0C8 0x5A24 # 0 +0x8EA3B0CA 0x5A14 # 0 +0x8EA3B0CB 0x5A31 # 0 +0x8EA3B0CD 0x5A2F # 0 +0x8EA3B0CE 0x5A1A # 0 +0x8EA3B0CF 0x5A12 # 0 +0x8EA3B0D2 0x5A26 # 0 +0x8EA3B0D5 0x5BBC # 0 +0x8EA3B0D6 0x5BBB # 0 +0x8EA3B0D7 0x5BB7 # 0 +0x8EA3B0D8 0x5C05 # 0 +0x8EA3B0D9 0x5C06 # 0 +0x8EA3B0DA 0x5C52 # 0 +0x8EA3B0DB 0x5C53 # 0 +0x8EA3B0DE 0x5CFA # 0 +0x8EA3B0DF 0x5CEB # 0 +0x8EA3B0E1 0x5CF3 # 0 +0x8EA3B0E2 0x5CF5 # 0 +0x8EA3B0E3 0x5CE9 # 0 +0x8EA3B0E4 0x5CEF # 0 +0x8EA3B0E6 0x5E2A # 0 +0x8EA3B0E7 0x5E30 # 0 +0x8EA3B0E8 0x5E2E # 0 +0x8EA3B0E9 0x5E2C # 0 +0x8EA3B0EA 0x5E2F # 0 +0x8EA3B0EB 0x5EAF # 0 +0x8EA3B0EC 0x5EA9 # 0 +0x8EA3B0EE 0x5EFD # 0 +0x8EA3B0EF 0x5F32 # 0 +0x8EA3B0F0 0x5F8E # 0 +0x8EA3B0F1 0x5F93 # 0 +0x8EA3B0F2 0x5F8F # 0 +0x8EA3B0F3 0x604F # 0 +0x8EA3B0F4 0x6099 # 0 +0x8EA3B0F6 0x607E # 0 +0x8EA3B0F8 0x6074 # 0 +0x8EA3B0F9 0x604B # 0 +0x8EA3B0FA 0x6073 # 0 +0x8EA3B0FB 0x6075 # 0 +0x8EA3B0FE 0x6056 # 0 +0x8EA3B1A1 0x60A9 # 0 +0x8EA3B1A2 0x608B # 0 +0x8EA3B1A3 0x60A6 # 0 +0x8EA3B1A5 0x6093 # 0 +0x8EA3B1A6 0x60AE # 0 +0x8EA3B1A7 0x609E # 0 +0x8EA3B1A8 0x60A7 # 0 +0x8EA3B1A9 0x6245 # 0 +0x8EA3B1AC 0x632E # 0 +0x8EA3B1AE 0x6352 # 0 +0x8EA3B1AF 0x6330 # 0 +0x8EA3B1B0 0x635B # 0 +0x8EA3B1B2 0x6319 # 0 +0x8EA3B1B3 0x631B # 0 +0x8EA3B1B5 0x6331 # 0 +0x8EA3B1B6 0x635D # 0 +0x8EA3B1B7 0x6337 # 0 +0x8EA3B1B8 0x6335 # 0 +0x8EA3B1B9 0x6353 # 0 +0x8EA3B1BB 0x635C # 0 +0x8EA3B1BC 0x633F # 0 +0x8EA3B1BD 0x654B # 0 +0x8EA3B1C0 0x658B # 0 +0x8EA3B1C2 0x659A # 0 +0x8EA3B1C3 0x6650 # 0 +0x8EA3B1C4 0x6646 # 0 +0x8EA3B1C5 0x664E # 0 +0x8EA3B1C6 0x6640 # 0 +0x8EA3B1C8 0x664B # 0 +0x8EA3B1C9 0x6648 # 0 +0x8EA3B1CB 0x6660 # 0 +0x8EA3B1CC 0x6644 # 0 +0x8EA3B1CD 0x664D # 0 +0x8EA3B1CF 0x6837 # 0 +0x8EA3B1D0 0x6824 # 0 +0x8EA3B1D3 0x681B # 0 +0x8EA3B1D4 0x6836 # 0 +0x8EA3B1D6 0x682C # 0 +0x8EA3B1D7 0x6819 # 0 +0x8EA3B1D8 0x6856 # 0 +0x8EA3B1D9 0x6847 # 0 +0x8EA3B1DA 0x683E # 0 +0x8EA3B1DB 0x681E # 0 +0x8EA3B1DD 0x6815 # 0 +0x8EA3B1DE 0x6822 # 0 +0x8EA3B1DF 0x6827 # 0 +0x8EA3B1E0 0x6859 # 0 +0x8EA3B1E1 0x6858 # 0 +0x8EA3B1E2 0x6855 # 0 +0x8EA3B1E3 0x6830 # 0 +0x8EA3B1E4 0x6823 # 0 +0x8EA3B1E5 0x6B2E # 0 +0x8EA3B1E6 0x6B2B # 0 +0x8EA3B1E7 0x6B30 # 0 +0x8EA3B1E8 0x6B6C # 0 +0x8EA3B1EA 0x6B8B # 0 +0x8EA3B1EC 0x6BE9 # 0 +0x8EA3B1ED 0x6BEA # 0 +0x8EA3B1EE 0x6BE5 # 0 +0x8EA3B1EF 0x6D6B # 0 +0x8EA3B1F2 0x6D73 # 0 +0x8EA3B1F3 0x6D57 # 0 +0x8EA3B1F6 0x6D5D # 0 +0x8EA3B1F7 0x6D56 # 0 +0x8EA3B1F8 0x6D8F # 0 +0x8EA3B1F9 0x6D5B # 0 +0x8EA3B1FA 0x6D1C # 0 +0x8EA3B1FB 0x6D9A # 0 +0x8EA3B1FC 0x6D9B # 0 +0x8EA3B1FD 0x6D99 # 0 +0x8EA3B2A1 0x6D81 # 0 +0x8EA3B2A2 0x6D71 # 0 +0x8EA3B2A5 0x6D72 # 0 +0x8EA3B2A6 0x6D5C # 0 +0x8EA3B2A7 0x6D96 # 0 +0x8EA3B2A8 0x70C4 # 0 +0x8EA3B2A9 0x70DB # 0 +0x8EA3B2AA 0x70CC # 0 +0x8EA3B2AB 0x70D0 # 0 +0x8EA3B2AC 0x70E3 # 0 +0x8EA3B2AD 0x70DF # 0 +0x8EA3B2AF 0x70D6 # 0 +0x8EA3B2B0 0x70EE # 0 +0x8EA3B2B1 0x70D5 # 0 +0x8EA3B2B6 0x727A # 0 +0x8EA3B2B8 0x72F5 # 0 +0x8EA3B2B9 0x7302 # 0 +0x8EA3B2BC 0x73E2 # 0 +0x8EA3B2BD 0x73EC # 0 +0x8EA3B2BE 0x73D5 # 0 +0x8EA3B2BF 0x73F9 # 0 +0x8EA3B2C0 0x73DF # 0 +0x8EA3B2C1 0x73E6 # 0 +0x8EA3B2C6 0x73E4 # 0 +0x8EA3B2C7 0x73E1 # 0 +0x8EA3B2C8 0x74F3 # 0 +0x8EA3B2CD 0x7556 # 0 +0x8EA3B2CE 0x7555 # 0 +0x8EA3B2CF 0x7558 # 0 +0x8EA3B2D0 0x7557 # 0 +0x8EA3B2D1 0x755E # 0 +0x8EA3B2D2 0x75C3 # 0 +0x8EA3B2D5 0x75B4 # 0 +0x8EA3B2D7 0x75B1 # 0 +0x8EA3B2DA 0x76CB # 0 +0x8EA3B2DB 0x76CC # 0 +0x8EA3B2DC 0x772A # 0 +0x8EA3B2DE 0x7716 # 0 +0x8EA3B2DF 0x770F # 0 +0x8EA3B2E2 0x773F # 0 +0x8EA3B2E3 0x772B # 0 +0x8EA3B2E4 0x770E # 0 +0x8EA3B2E5 0x7724 # 0 +0x8EA3B2E7 0x7721 # 0 +0x8EA3B2E8 0x7718 # 0 +0x8EA3B2E9 0x77DD # 0 +0x8EA3B2EC 0x7824 # 0 +0x8EA3B2ED 0x7836 # 0 +0x8EA3B2EF 0x7958 # 0 +0x8EA3B2F0 0x7959 # 0 +0x8EA3B2F2 0x7962 # 0 +0x8EA3B2F3 0x79DA # 0 +0x8EA3B2F4 0x79D9 # 0 +0x8EA3B2F6 0x79E1 # 0 +0x8EA3B2F7 0x79E5 # 0 +0x8EA3B2F8 0x79E8 # 0 +0x8EA3B2F9 0x79DB # 0 +0x8EA3B2FB 0x79E2 # 0 +0x8EA3B2FC 0x79F0 # 0 +0x8EA3B3A3 0x7ADA # 0 +0x8EA3B3A4 0x7ADD # 0 +0x8EA3B3A6 0x7ADB # 0 +0x8EA3B3A7 0x7ADC # 0 +0x8EA3B3AA 0x7B0D # 0 +0x8EA3B3AB 0x7B0B # 0 +0x8EA3B3AC 0x7B14 # 0 +0x8EA3B3AD 0x7C8E # 0 +0x8EA3B3AE 0x7C86 # 0 +0x8EA3B3B0 0x7C87 # 0 +0x8EA3B3B1 0x7C83 # 0 +0x8EA3B3B2 0x7C8B # 0 +0x8EA3B3B7 0x7D24 # 0 +0x8EA3B3BB 0x7D25 # 0 +0x8EA3B3BC 0x7F62 # 0 +0x8EA3B3BD 0x7F93 # 0 +0x8EA3B3BE 0x7F99 # 0 +0x8EA3B3BF 0x7F97 # 0 +0x8EA3B3C2 0x7FC4 # 0 +0x8EA3B3C3 0x7FC6 # 0 +0x8EA3B3C4 0x800A # 0 +0x8EA3B3C7 0x8040 # 0 +0x8EA3B3C8 0x803C # 0 +0x8EA3B3C9 0x803B # 0 +0x8EA3B3CA 0x80F6 # 0 +0x8EA3B3CB 0x80FF # 0 +0x8EA3B3CC 0x80EE # 0 +0x8EA3B3CD 0x8104 # 0 +0x8EA3B3CE 0x8103 # 0 +0x8EA3B3CF 0x8107 # 0 +0x8EA3B3D2 0x80F7 # 0 +0x8EA3B3D5 0x822D # 0 +0x8EA3B3D7 0x8227 # 0 +0x8EA3B3D8 0x8229 # 0 +0x8EA3B3D9 0x831F # 0 +0x8EA3B3DA 0x8357 # 0 +0x8EA3B3DF 0x8321 # 0 +0x8EA3B3E2 0x8318 # 0 +0x8EA3B3E3 0x8358 # 0 +0x8EA3B3E9 0x8684 # 0 +0x8EA3B3EA 0x869F # 0 +0x8EA3B3EB 0x869B # 0 +0x8EA3B3EC 0x8689 # 0 +0x8EA3B3ED 0x86A6 # 0 +0x8EA3B3EE 0x8692 # 0 +0x8EA3B3EF 0x868F # 0 +0x8EA3B3F0 0x86A0 # 0 +0x8EA3B3F1 0x884F # 0 +0x8EA3B3F2 0x8878 # 0 +0x8EA3B3F3 0x887A # 0 +0x8EA3B3F4 0x886E # 0 +0x8EA3B3F5 0x887B # 0 +0x8EA3B3F6 0x8884 # 0 +0x8EA3B3F7 0x8873 # 0 +0x8EA3B3FA 0x8A0D # 0 +0x8EA3B3FB 0x8A0B # 0 +0x8EA3B3FC 0x8A19 # 0 +0x8EA3B4A5 0x8FF9 # 0 +0x8EA3B4A6 0x9009 # 0 +0x8EA3B4A7 0x9008 # 0 +0x8EA3B4A9 0x90DE # 0 +0x8EA3B4AA 0x9151 # 0 +0x8EA3B4AD 0x91DB # 0 +0x8EA3B4AE 0x91DF # 0 +0x8EA3B4AF 0x91DE # 0 +0x8EA3B4B0 0x91D6 # 0 +0x8EA3B4B1 0x91E0 # 0 +0x8EA3B4B2 0x9585 # 0 +0x8EA3B4B3 0x9660 # 0 +0x8EA3B4B4 0x9659 # 0 +0x8EA3B4B6 0x9656 # 0 +0x8EA3B4B9 0x96BD # 0 +0x8EA3B4BC 0x5042 # 0 +0x8EA3B4BD 0x5059 # 0 +0x8EA3B4BF 0x5044 # 0 +0x8EA3B4C0 0x5066 # 0 +0x8EA3B4C1 0x5052 # 0 +0x8EA3B4C2 0x5054 # 0 +0x8EA3B4C3 0x5071 # 0 +0x8EA3B4C4 0x5050 # 0 +0x8EA3B4C5 0x507B # 0 +0x8EA3B4C6 0x507C # 0 +0x8EA3B4C7 0x5058 # 0 +0x8EA3B4CA 0x5079 # 0 +0x8EA3B4CB 0x506C # 0 +0x8EA3B4CC 0x5078 # 0 +0x8EA3B4CD 0x51A8 # 0 +0x8EA3B4CE 0x51D1 # 0 +0x8EA3B4CF 0x51CF # 0 +0x8EA3B4D0 0x5268 # 0 +0x8EA3B4D1 0x5276 # 0 +0x8EA3B4D2 0x52D4 # 0 +0x8EA3B4D4 0x53A0 # 0 +0x8EA3B4D5 0x53C4 # 0 +0x8EA3B4D7 0x5558 # 0 +0x8EA3B4D8 0x554C # 0 +0x8EA3B4D9 0x5568 # 0 +0x8EA3B4DB 0x5549 # 0 +0x8EA3B4DE 0x555D # 0 +0x8EA3B4DF 0x5529 # 0 +0x8EA3B4E1 0x5554 # 0 +0x8EA3B4E2 0x5553 # 0 +0x8EA3B4E4 0x555A # 0 +0x8EA3B4E6 0x553A # 0 +0x8EA3B4E7 0x553F # 0 +0x8EA3B4E8 0x552B # 0 +0x8EA3B4E9 0x57EA # 0 +0x8EA3B4EB 0x57EF # 0 +0x8EA3B4EE 0x57DD # 0 +0x8EA3B4EF 0x57FE # 0 +0x8EA3B4F1 0x57DE # 0 +0x8EA3B4F2 0x57E6 # 0 +0x8EA3B4F4 0x57E8 # 0 +0x8EA3B4F5 0x57FF # 0 +0x8EA3B4F6 0x5803 # 0 +0x8EA3B4F7 0x58F7 # 0 +0x8EA3B4F8 0x68A6 # 0 +0x8EA3B4F9 0x591F # 0 +0x8EA3B4FB 0x595B # 0 +0x8EA3B4FC 0x595D # 0 +0x8EA3B4FD 0x595E # 0 +0x8EA3B5A2 0x5A2B # 0 +0x8EA3B5A4 0x5A3B # 0 +0x8EA3B5A7 0x5A61 # 0 +0x8EA3B5A8 0x5A3A # 0 +0x8EA3B5A9 0x5A6E # 0 +0x8EA3B5AA 0x5A4B # 0 +0x8EA3B5AB 0x5A6B # 0 +0x8EA3B5AE 0x5A45 # 0 +0x8EA3B5AF 0x5A4E # 0 +0x8EA3B5B0 0x5A68 # 0 +0x8EA3B5B1 0x5A3D # 0 +0x8EA3B5B2 0x5A71 # 0 +0x8EA3B5B3 0x5A3F # 0 +0x8EA3B5B4 0x5A6F # 0 +0x8EA3B5B5 0x5A75 # 0 +0x8EA3B5B7 0x5A73 # 0 +0x8EA3B5B8 0x5A2C # 0 +0x8EA3B5B9 0x5A59 # 0 +0x8EA3B5BA 0x5A54 # 0 +0x8EA3B5BB 0x5A4F # 0 +0x8EA3B5BC 0x5A63 # 0 +0x8EA3B5BF 0x5BC8 # 0 +0x8EA3B5C1 0x5BC3 # 0 +0x8EA3B5C3 0x5C5B # 0 +0x8EA3B5C4 0x5C61 # 0 +0x8EA3B5C6 0x5D21 # 0 +0x8EA3B5C7 0x5D0A # 0 +0x8EA3B5C8 0x5D09 # 0 +0x8EA3B5CA 0x5D2C # 0 +0x8EA3B5CB 0x5D08 # 0 +0x8EA3B5CE 0x5D2A # 0 +0x8EA3B5CF 0x5D15 # 0 +0x8EA3B5D1 0x5D10 # 0 +0x8EA3B5D2 0x5D13 # 0 +0x8EA3B5D4 0x5D2F # 0 +0x8EA3B5D5 0x5D18 # 0 +0x8EA3B5D7 0x5DE3 # 0 +0x8EA3B5D8 0x5E39 # 0 +0x8EA3B5D9 0x5E35 # 0 +0x8EA3B5DA 0x5E3A # 0 +0x8EA3B5DB 0x5E32 # 0 +0x8EA3B5E0 0x5EBB # 0 +0x8EA3B5E1 0x5EBA # 0 +0x8EA3B5E2 0x5F34 # 0 +0x8EA3B5E3 0x5F39 # 0 +0x8EA3B5E8 0x6098 # 0 +0x8EA3B5EA 0x60D0 # 0 +0x8EA3B5EE 0x60D7 # 0 +0x8EA3B5EF 0x60AA # 0 +0x8EA3B5F1 0x60A1 # 0 +0x8EA3B5F2 0x60A4 # 0 +0x8EA3B5F4 0x60EE # 0 +0x8EA3B5F6 0x60E7 # 0 +0x8EA3B5F9 0x60DE # 0 +0x8EA3B5FC 0x637E # 0 +0x8EA3B5FD 0x638B # 0 +0x8EA3B6A2 0x6379 # 0 +0x8EA3B6A3 0x6386 # 0 +0x8EA3B6A4 0x6393 # 0 +0x8EA3B6A6 0x6373 # 0 +0x8EA3B6A7 0x636A # 0 +0x8EA3B6A9 0x636C # 0 +0x8EA3B6AB 0x637F # 0 +0x8EA3B6AD 0x63B2 # 0 +0x8EA3B6AE 0x63BA # 0 +0x8EA3B6B1 0x6366 # 0 +0x8EA3B6B2 0x6374 # 0 +0x8EA3B6B4 0x655A # 0 +0x8EA3B6B6 0x654E # 0 +0x8EA3B6B7 0x654D # 0 +0x8EA3B6B8 0x658D # 0 +0x8EA3B6B9 0x658E # 0 +0x8EA3B6BA 0x65AD # 0 +0x8EA3B6BC 0x65C7 # 0 +0x8EA3B6BD 0x65CA # 0 +0x8EA3B6BF 0x65C9 # 0 +0x8EA3B6C1 0x65E3 # 0 +0x8EA3B6C2 0x6657 # 0 +0x8EA3B6C4 0x6663 # 0 +0x8EA3B6C5 0x6667 # 0 +0x8EA3B6C6 0x671A # 0 +0x8EA3B6C7 0x6719 # 0 +0x8EA3B6C8 0x6716 # 0 +0x8EA3B6CB 0x689E # 0 +0x8EA3B6CC 0x68B6 # 0 +0x8EA3B6CD 0x6898 # 0 +0x8EA3B6CE 0x6873 # 0 +0x8EA3B6D0 0x689A # 0 +0x8EA3B6D1 0x688E # 0 +0x8EA3B6D2 0x68B7 # 0 +0x8EA3B6D3 0x68DB # 0 +0x8EA3B6D4 0x68A5 # 0 +0x8EA3B6D5 0x686C # 0 +0x8EA3B6D6 0x68C1 # 0 +0x8EA3B6D7 0x6884 # 0 +0x8EA3B6DA 0x6895 # 0 +0x8EA3B6DB 0x687A # 0 +0x8EA3B6DC 0x6899 # 0 +0x8EA3B6DE 0x68B8 # 0 +0x8EA3B6DF 0x68B9 # 0 +0x8EA3B6E0 0x6870 # 0 +0x8EA3B6E2 0x6B35 # 0 +0x8EA3B6E4 0x6B90 # 0 +0x8EA3B6E5 0x6BBB # 0 +0x8EA3B6E6 0x6BED # 0 +0x8EA3B6EA 0x6DC1 # 0 +0x8EA3B6EB 0x6DC3 # 0 +0x8EA3B6EC 0x6DCE # 0 +0x8EA3B6EF 0x6DAD # 0 +0x8EA3B6F0 0x6E04 # 0 +0x8EA3B6F2 0x6DB9 # 0 +0x8EA3B6F4 0x6DE7 # 0 +0x8EA3B6F6 0x6E08 # 0 +0x8EA3B6F7 0x6E06 # 0 +0x8EA3B6F9 0x6E0A # 0 +0x8EA3B6FA 0x6DB0 # 0 +0x8EA3B6FC 0x6DF8 # 0 +0x8EA3B6FD 0x6E0C # 0 +0x8EA3B7A1 0x6DB1 # 0 +0x8EA3B7A3 0x6E02 # 0 +0x8EA3B7A4 0x6E07 # 0 +0x8EA3B7A5 0x6E09 # 0 +0x8EA3B7A6 0x6E01 # 0 +0x8EA3B7A7 0x6E17 # 0 +0x8EA3B7A8 0x6DFF # 0 +0x8EA3B7A9 0x6E12 # 0 +0x8EA3B7AC 0x7103 # 0 +0x8EA3B7AD 0x7107 # 0 +0x8EA3B7AE 0x7101 # 0 +0x8EA3B7AF 0x70F5 # 0 +0x8EA3B7B0 0x70F1 # 0 +0x8EA3B7B1 0x7108 # 0 +0x8EA3B7B2 0x70F2 # 0 +0x8EA3B7B3 0x710F # 0 +0x8EA3B7B5 0x70FE # 0 +0x8EA3B7B9 0x731A # 0 +0x8EA3B7BA 0x7310 # 0 +0x8EA3B7BB 0x730E # 0 +0x8EA3B7BC 0x7402 # 0 +0x8EA3B7BD 0x73F3 # 0 +0x8EA3B7C0 0x73FB # 0 +0x8EA3B7C4 0x751B # 0 +0x8EA3B7C5 0x7523 # 0 +0x8EA3B7C6 0x7561 # 0 +0x8EA3B7C7 0x7568 # 0 +0x8EA3B7C9 0x7567 # 0 +0x8EA3B7CA 0x75D3 # 0 +0x8EA3B7CD 0x7690 # 0 +0x8EA3B7D0 0x76D5 # 0 +0x8EA3B7D1 0x76D7 # 0 +0x8EA3B7D2 0x76D6 # 0 +0x8EA3B7D3 0x7730 # 0 +0x8EA3B7D5 0x7726 # 0 +0x8EA3B7D7 0x7740 # 0 +0x8EA3B7D9 0x771E # 0 +0x8EA3B7DD 0x7847 # 0 +0x8EA3B7DF 0x784B # 0 +0x8EA3B7E0 0x7851 # 0 +0x8EA3B7E1 0x784F # 0 +0x8EA3B7E2 0x7842 # 0 +0x8EA3B7E3 0x7846 # 0 +0x8EA3B7E5 0x796E # 0 +0x8EA3B7E6 0x796C # 0 +0x8EA3B7E7 0x79F2 # 0 +0x8EA3B7E9 0x79F1 # 0 +0x8EA3B7EA 0x79F5 # 0 +0x8EA3B7EB 0x79F3 # 0 +0x8EA3B7EC 0x79F9 # 0 +0x8EA3B7F0 0x7A9A # 0 +0x8EA3B7F1 0x7A93 # 0 +0x8EA3B7F2 0x7A91 # 0 +0x8EA3B7F3 0x7AE1 # 0 +0x8EA3B7F6 0x7B21 # 0 +0x8EA3B7F7 0x7B1C # 0 +0x8EA3B7F8 0x7B16 # 0 +0x8EA3B7F9 0x7B17 # 0 +0x8EA3B7FA 0x7B36 # 0 +0x8EA3B7FB 0x7B1F # 0 +0x8EA3B7FD 0x7C93 # 0 +0x8EA3B7FE 0x7C99 # 0 +0x8EA3B8A1 0x7C9A # 0 +0x8EA3B8A2 0x7C9C # 0 +0x8EA3B8A4 0x7D49 # 0 +0x8EA3B8A6 0x7D34 # 0 +0x8EA3B8A7 0x7D37 # 0 +0x8EA3B8A9 0x7D2D # 0 +0x8EA3B8AB 0x7D4C # 0 +0x8EA3B8AE 0x7D48 # 0 +0x8EA3B8B1 0x7F3B # 0 +0x8EA3B8B6 0x8008 # 0 +0x8EA3B8B7 0x801A # 0 +0x8EA3B8B9 0x801D # 0 +0x8EA3B8BB 0x8049 # 0 +0x8EA3B8BC 0x8045 # 0 +0x8EA3B8BD 0x8044 # 0 +0x8EA3B8BE 0x7C9B # 0 +0x8EA3B8C1 0x812A # 0 +0x8EA3B8C2 0x812E # 0 +0x8EA3B8C5 0x8131 # 0 +0x8EA3B8C7 0x811A # 0 +0x8EA3B8C8 0x8134 # 0 +0x8EA3B8C9 0x8117 # 0 +0x8EA3B8CD 0x831D # 0 +0x8EA3B8CE 0x8371 # 0 +0x8EA3B8CF 0x8384 # 0 +0x8EA3B8D0 0x8380 # 0 +0x8EA3B8D1 0x8372 # 0 +0x8EA3B8D2 0x83A1 # 0 +0x8EA3B8D4 0x8379 # 0 +0x8EA3B8D5 0x8391 # 0 +0x8EA3B8D7 0x839F # 0 +0x8EA3B8D8 0x83AD # 0 +0x8EA3B8DB 0x8323 # 0 +0x8EA3B8DD 0x8385 # 0 +0x8EA3B8DE 0x839C # 0 +0x8EA3B8DF 0x83B7 # 0 +0x8EA3B8E0 0x8658 # 0 +0x8EA3B8E1 0x865A # 0 +0x8EA3B8E3 0x8657 # 0 +0x8EA3B8E4 0x86B2 # 0 +0x8EA3B8E6 0x86AE # 0 +0x8EA3B8EA 0x8845 # 0 +0x8EA3B8EB 0x889C # 0 +0x8EA3B8EC 0x8894 # 0 +0x8EA3B8ED 0x88A3 # 0 +0x8EA3B8EE 0x888F # 0 +0x8EA3B8EF 0x88A5 # 0 +0x8EA3B8F0 0x88A9 # 0 +0x8EA3B8F1 0x88A6 # 0 +0x8EA3B8F2 0x888A # 0 +0x8EA3B8F3 0x88A0 # 0 +0x8EA3B8F4 0x8890 # 0 +0x8EA3B8F5 0x8992 # 0 +0x8EA3B8F6 0x8991 # 0 +0x8EA3B8F7 0x8994 # 0 +0x8EA3B8F9 0x8A26 # 0 +0x8EA3B8FA 0x8A32 # 0 +0x8EA3B8FB 0x8A28 # 0 +0x8EA3B8FE 0x8A1C # 0 +0x8EA3B9A2 0x8A2B # 0 +0x8EA3B9A3 0x8A20 # 0 +0x8EA3B9A5 0x8A29 # 0 +0x8EA3B9A9 0x8A21 # 0 +0x8EA3B9AA 0x8C3A # 0 +0x8EA3B9AC 0x8C5B # 0 +0x8EA3B9AD 0x8C58 # 0 +0x8EA3B9AE 0x8C7C # 0 +0x8EA3B9B0 0x8CA6 # 0 +0x8EA3B9B1 0x8CAE # 0 +0x8EA3B9B2 0x8CAD # 0 +0x8EA3B9B3 0x8D65 # 0 +0x8EA3B9B5 0x8D7E # 0 +0x8EA3B9B7 0x8D7C # 0 +0x8EA3B9B8 0x8D7F # 0 +0x8EA3B9B9 0x8D7A # 0 +0x8EA3B9BA 0x8DBD # 0 +0x8EA3B9BD 0x8DC0 # 0 +0x8EA3B9BE 0x8DBB # 0 +0x8EA3B9BF 0x8EAD # 0 +0x8EA3B9C0 0x8EAF # 0 +0x8EA3B9C1 0x8ED6 # 0 +0x8EA3B9C7 0x8ED9 # 0 +0x8EA3B9CA 0x9012 # 0 +0x8EA3B9CB 0x900E # 0 +0x8EA3B9CC 0x9025 # 0 +0x8EA3B9CE 0x9013 # 0 +0x8EA3B9CF 0x90EE # 0 +0x8EA3B9D1 0x90AB # 0 +0x8EA3B9D2 0x90F7 # 0 +0x8EA3B9D4 0x9159 # 0 +0x8EA3B9D5 0x9154 # 0 +0x8EA3B9D6 0x91F2 # 0 +0x8EA3B9D7 0x91F0 # 0 +0x8EA3B9D8 0x91E5 # 0 +0x8EA3B9D9 0x91F6 # 0 +0x8EA3B9DC 0x9587 # 0 +0x8EA3B9DE 0x965A # 0 +0x8EA3B9E1 0x966E # 0 +0x8EA3B9E5 0x9679 # 0 +0x8EA3B9E7 0x98E1 # 0 +0x8EA3B9E8 0x98E6 # 0 +0x8EA3B9EA 0x9EC4 # 0 +0x8EA3B9EB 0x9ED2 # 0 +0x8EA3B9EC 0x4E80 # 0 +0x8EA3B9EE 0x4E81 # 0 +0x8EA3B9EF 0x508F # 0 +0x8EA3B9F0 0x5097 # 0 +0x8EA3B9F1 0x5088 # 0 +0x8EA3B9F2 0x5089 # 0 +0x8EA3B9F5 0x5081 # 0 +0x8EA3B9F6 0x5160 # 0 +0x8EA3B9F9 0x5E42 # 0 +0x8EA3B9FA 0x51D3 # 0 +0x8EA3B9FD 0x51D2 # 0 +0x8EA3B9FE 0x51D6 # 0 +0x8EA3BAA1 0x5273 # 0 +0x8EA3BAA3 0x5270 # 0 +0x8EA3BAA7 0x53A8 # 0 +0x8EA3BAA8 0x53A6 # 0 +0x8EA3BAA9 0x53C5 # 0 +0x8EA3BAAA 0x5597 # 0 +0x8EA3BAAB 0x55DE # 0 +0x8EA3BAAE 0x5596 # 0 +0x8EA3BAAF 0x55B4 # 0 +0x8EA3BAB1 0x5585 # 0 +0x8EA3BAB3 0x559B # 0 +0x8EA3BAB4 0x55A0 # 0 +0x8EA3BAB6 0x5559 # 0 +0x8EA3BAB8 0x5586 # 0 +0x8EA3BABB 0x55AF # 0 +0x8EA3BABC 0x557A # 0 +0x8EA3BAC0 0x559E # 0 +0x8EA3BAC2 0x55A9 # 0 +0x8EA3BAC3 0x570F # 0 +0x8EA3BAC4 0x570E # 0 +0x8EA3BAC5 0x581A # 0 +0x8EA3BAC7 0x581F # 0 +0x8EA3BAC9 0x583C # 0 +0x8EA3BACA 0x5818 # 0 +0x8EA3BACB 0x583E # 0 +0x8EA3BACC 0x5826 # 0 +0x8EA3BACE 0x583A # 0 +0x8EA3BAD0 0x5822 # 0 +0x8EA3BAD2 0x58FB # 0 +0x8EA3BAD3 0x5963 # 0 +0x8EA3BAD4 0x5964 # 0 +0x8EA3BAD6 0x5AA8 # 0 +0x8EA3BAD7 0x5AA3 # 0 +0x8EA3BAD8 0x5A82 # 0 +0x8EA3BAD9 0x5A88 # 0 +0x8EA3BADA 0x5AA1 # 0 +0x8EA3BADB 0x5A85 # 0 +0x8EA3BADC 0x5A98 # 0 +0x8EA3BADE 0x5A99 # 0 +0x8EA3BAE0 0x5A89 # 0 +0x8EA3BAE1 0x5A81 # 0 +0x8EA3BAE2 0x5A96 # 0 +0x8EA3BAE3 0x5A80 # 0 +0x8EA3BAE6 0x5A91 # 0 +0x8EA3BAEB 0x5ACF # 0 +0x8EA3BAF2 0x5A87 # 0 +0x8EA3BAF3 0x5AA0 # 0 +0x8EA3BAF5 0x5A79 # 0 +0x8EA3BAF7 0x5A86 # 0 +0x8EA3BAF8 0x5AAB # 0 +0x8EA3BAF9 0x5AAA # 0 +0x8EA3BAFA 0x5AA4 # 0 +0x8EA3BAFB 0x5A8D # 0 +0x8EA3BAFC 0x5A7E # 0 +0x8EA3BAFE 0x5BD5 # 0 +0x8EA3BBA4 0x5C1E # 0 +0x8EA3BBA5 0x5C5F # 0 +0x8EA3BBA6 0x5C5E # 0 +0x8EA3BBA7 0x5D44 # 0 +0x8EA3BBA8 0x5D3E # 0 +0x8EA3BBAA 0x5D48 # 0 +0x8EA3BBAB 0x5D1C # 0 +0x8EA3BBAD 0x5D5B # 0 +0x8EA3BBAE 0x5D4D # 0 +0x8EA3BBB1 0x5D57 # 0 +0x8EA3BBB3 0x5D53 # 0 +0x8EA3BBB4 0x5D4F # 0 +0x8EA3BBB6 0x5D3B # 0 +0x8EA3BBB7 0x5D46 # 0 +0x8EA3BBBA 0x5E46 # 0 +0x8EA3BBBB 0x5E47 # 0 +0x8EA3BBBD 0x5E48 # 0 +0x8EA3BBBE 0x5EC0 # 0 +0x8EA3BBBF 0x5EBD # 0 +0x8EA3BBC0 0x5EBF # 0 +0x8EA3BBC2 0x5F11 # 0 +0x8EA3BBC4 0x5F3E # 0 +0x8EA3BBC5 0x5F3B # 0 +0x8EA3BBC7 0x5F3A # 0 +0x8EA3BBCB 0x5FA7 # 0 +0x8EA3BBCD 0x60EA # 0 +0x8EA3BBCF 0x6107 # 0 +0x8EA3BBD0 0x6122 # 0 +0x8EA3BBD1 0x610C # 0 +0x8EA3BBD4 0x60B3 # 0 +0x8EA3BBD5 0x60D6 # 0 +0x8EA3BBD6 0x60D2 # 0 +0x8EA3BBD8 0x60E3 # 0 +0x8EA3BBD9 0x60E5 # 0 +0x8EA3BBDA 0x60E9 # 0 +0x8EA3BBDD 0x6111 # 0 +0x8EA3BBDE 0x60FD # 0 +0x8EA3BBE1 0x611E # 0 +0x8EA3BBE2 0x6120 # 0 +0x8EA3BBE3 0x6121 # 0 +0x8EA3BBE4 0x621E # 0 +0x8EA3BBE6 0x63E2 # 0 +0x8EA3BBE7 0x63DE # 0 +0x8EA3BBE8 0x63E6 # 0 +0x8EA3BBED 0x63F8 # 0 +0x8EA3BBEF 0x63FE # 0 +0x8EA3BBF0 0x63C1 # 0 +0x8EA3BBF1 0x63BF # 0 +0x8EA3BBF2 0x63F7 # 0 +0x8EA3BBF3 0x63D1 # 0 +0x8EA3BBF4 0x655F # 0 +0x8EA3BBF5 0x6560 # 0 +0x8EA3BBF6 0x6561 # 0 +0x8EA3BBF9 0x65D1 # 0 +0x8EA3BBFC 0x667D # 0 +0x8EA3BBFD 0x666B # 0 +0x8EA3BBFE 0x667F # 0 +0x8EA3BCA3 0x6673 # 0 +0x8EA3BCA4 0x6681 # 0 +0x8EA3BCA5 0x666D # 0 +0x8EA3BCA6 0x6669 # 0 +0x8EA3BCA9 0x671E # 0 +0x8EA3BCAA 0x68ED # 0 +0x8EA3BCAF 0x6903 # 0 +0x8EA3BCB1 0x68FE # 0 +0x8EA3BCB2 0x68E5 # 0 +0x8EA3BCB3 0x691E # 0 +0x8EA3BCB4 0x6902 # 0 +0x8EA3BCB7 0x6909 # 0 +0x8EA3BCB8 0x68CA # 0 +0x8EA3BCB9 0x6900 # 0 +0x8EA3BCBB 0x6901 # 0 +0x8EA3BCBC 0x6918 # 0 +0x8EA3BCBD 0x68E2 # 0 +0x8EA3BCBE 0x68CF # 0 +0x8EA3BCC0 0x692E # 0 +0x8EA3BCC1 0x68C5 # 0 +0x8EA3BCC2 0x68FF # 0 +0x8EA3BCC4 0x691C # 0 +0x8EA3BCC5 0x68C3 # 0 +0x8EA3BCC7 0x6B6F # 0 +0x8EA3BCC9 0x6B6E # 0 +0x8EA3BCCB 0x6BBE # 0 +0x8EA3BCCD 0x6BF4 # 0 +0x8EA3BCCE 0x6C2D # 0 +0x8EA3BCD0 0x6DB6 # 0 +0x8EA3BCD1 0x6E75 # 0 +0x8EA3BCD2 0x6E1E # 0 +0x8EA3BCD4 0x6E18 # 0 +0x8EA3BCD6 0x6E48 # 0 +0x8EA3BCD8 0x6E4F # 0 +0x8EA3BCDA 0x6E42 # 0 +0x8EA3BCDB 0x6E6A # 0 +0x8EA3BCDC 0x6E70 # 0 +0x8EA3BCDD 0x6DFE # 0 +0x8EA3BCE0 0x6E6D # 0 +0x8EA3BCE2 0x6E7B # 0 +0x8EA3BCE3 0x6E7E # 0 +0x8EA3BCE4 0x6E59 # 0 +0x8EA3BCE6 0x6E57 # 0 +0x8EA3BCE8 0x6E80 # 0 +0x8EA3BCE9 0x6E50 # 0 +0x8EA3BCEB 0x6E29 # 0 +0x8EA3BCEC 0x6E76 # 0 +0x8EA3BCED 0x6E2A # 0 +0x8EA3BCEE 0x6E4C # 0 +0x8EA3BCEF 0x712A # 0 +0x8EA3BCF1 0x7135 # 0 +0x8EA3BCF2 0x712C # 0 +0x8EA3BCF3 0x7137 # 0 +0x8EA3BCF4 0x711D # 0 +0x8EA3BCF7 0x7138 # 0 +0x8EA3BCF9 0x7134 # 0 +0x8EA3BCFA 0x712B # 0 +0x8EA3BCFB 0x7133 # 0 +0x8EA3BCFC 0x7127 # 0 +0x8EA3BCFD 0x7124 # 0 +0x8EA3BDA1 0x712D # 0 +0x8EA3BDA2 0x7232 # 0 +0x8EA3BDA3 0x7283 # 0 +0x8EA3BDA4 0x7282 # 0 +0x8EA3BDA5 0x7287 # 0 +0x8EA3BDA6 0x7306 # 0 +0x8EA3BDA7 0x7324 # 0 +0x8EA3BDA8 0x7338 # 0 +0x8EA3BDA9 0x732A # 0 +0x8EA3BDAA 0x732C # 0 +0x8EA3BDAB 0x732B # 0 +0x8EA3BDAD 0x732F # 0 +0x8EA3BDAE 0x7328 # 0 +0x8EA3BDAF 0x7417 # 0 +0x8EA3BDB2 0x7419 # 0 +0x8EA3BDB3 0x7438 # 0 +0x8EA3BDB5 0x741F # 0 +0x8EA3BDB6 0x7414 # 0 +0x8EA3BDB7 0x743C # 0 +0x8EA3BDB8 0x73F7 # 0 +0x8EA3BDB9 0x741C # 0 +0x8EA3BDBA 0x7415 # 0 +0x8EA3BDBB 0x7418 # 0 +0x8EA3BDBC 0x7439 # 0 +0x8EA3BDBD 0x74F9 # 0 +0x8EA3BDBE 0x7524 # 0 +0x8EA3BDC2 0x756E # 0 +0x8EA3BDC3 0x756D # 0 +0x8EA3BDC4 0x7571 # 0 +0x8EA3BDC5 0x758E # 0 +0x8EA3BDC7 0x75E5 # 0 +0x8EA3BDCC 0x7694 # 0 +0x8EA3BDCD 0x76B3 # 0 +0x8EA3BDCF 0x76D9 # 0 +0x8EA3BDD1 0x7748 # 0 +0x8EA3BDD2 0x7749 # 0 +0x8EA3BDD3 0x7743 # 0 +0x8EA3BDD6 0x7742 # 0 +0x8EA3BDD7 0x77DF # 0 +0x8EA3BDD9 0x7863 # 0 +0x8EA3BDDA 0x7876 # 0 +0x8EA3BDDC 0x785F # 0 +0x8EA3BDDD 0x7866 # 0 +0x8EA3BDDE 0x7966 # 0 +0x8EA3BDDF 0x7971 # 0 +0x8EA3BDE2 0x7976 # 0 +0x8EA3BDE3 0x7984 # 0 +0x8EA3BDE4 0x7975 # 0 +0x8EA3BDE5 0x79FF # 0 +0x8EA3BDE6 0x7A07 # 0 +0x8EA3BDE8 0x7A0E # 0 +0x8EA3BDE9 0x7A09 # 0 +0x8EA3BDF0 0x7AE7 # 0 +0x8EA3BDF1 0x7AE2 # 0 +0x8EA3BDF2 0x7B55 # 0 +0x8EA3BDF5 0x7B43 # 0 +0x8EA3BDF6 0x7B57 # 0 +0x8EA3BDF7 0x7B6C # 0 +0x8EA3BDF8 0x7B42 # 0 +0x8EA3BDF9 0x7B53 # 0 +0x8EA3BDFB 0x7B41 # 0 +0x8EA3BDFE 0x7CA7 # 0 +0x8EA3BEA1 0x7CA0 # 0 +0x8EA3BEA2 0x7CA6 # 0 +0x8EA3BEA3 0x7CA4 # 0 +0x8EA3BEA4 0x7D74 # 0 +0x8EA3BEA6 0x7D59 # 0 +0x8EA3BEA8 0x7D60 # 0 +0x8EA3BEA9 0x7D57 # 0 +0x8EA3BEAA 0x7D6C # 0 +0x8EA3BEAB 0x7D7E # 0 +0x8EA3BEAC 0x7D64 # 0 +0x8EA3BEAE 0x7D5A # 0 +0x8EA3BEAF 0x7D5D # 0 +0x8EA3BEB3 0x7D76 # 0 +0x8EA3BEB4 0x7D4D # 0 +0x8EA3BEB5 0x7D75 # 0 +0x8EA3BEB7 0x7FD3 # 0 +0x8EA3BEB8 0x7FD6 # 0 +0x8EA3BEBB 0x8060 # 0 +0x8EA3BEBC 0x804E # 0 +0x8EA3BEBD 0x8145 # 0 +0x8EA3BEBE 0x813B # 0 +0x8EA3BEC0 0x8148 # 0 +0x8EA3BEC1 0x8142 # 0 +0x8EA3BEC2 0x8149 # 0 +0x8EA3BEC3 0x8140 # 0 +0x8EA3BEC4 0x8114 # 0 +0x8EA3BEC5 0x8141 # 0 +0x8EA3BEC7 0x81EF # 0 +0x8EA3BEC8 0x81F6 # 0 +0x8EA3BEC9 0x8203 # 0 +0x8EA3BECB 0x83ED # 0 +0x8EA3BECD 0x83DA # 0 +0x8EA3BECE 0x8418 # 0 +0x8EA3BECF 0x83D2 # 0 +0x8EA3BED0 0x8408 # 0 +0x8EA3BED2 0x8400 # 0 +0x8EA3BED6 0x8417 # 0 +0x8EA3BED7 0x8346 # 0 +0x8EA3BED8 0x8414 # 0 +0x8EA3BED9 0x83D3 # 0 +0x8EA3BEDA 0x8405 # 0 +0x8EA3BEDB 0x841F # 0 +0x8EA3BEDC 0x8402 # 0 +0x8EA3BEDD 0x8416 # 0 +0x8EA3BEDE 0x83CD # 0 +0x8EA3BEDF 0x83E6 # 0 +0x8EA3BEE1 0x865D # 0 +0x8EA3BEE2 0x86D5 # 0 +0x8EA3BEE3 0x86E1 # 0 +0x8EA3BEE8 0x86EE # 0 +0x8EA3BEE9 0x8847 # 0 +0x8EA3BEEA 0x8846 # 0 +0x8EA3BEED 0x88BB # 0 +0x8EA3BEEF 0x88BF # 0 +0x8EA3BEF0 0x88B4 # 0 +0x8EA3BEF2 0x88B5 # 0 +0x8EA3BEF4 0x899A # 0 +0x8EA3BEF5 0x8A43 # 0 +0x8EA3BEF8 0x8A5A # 0 +0x8EA3BEFC 0x8A35 # 0 +0x8EA3BEFD 0x8A38 # 0 +0x8EA3BEFE 0x8A42 # 0 +0x8EA3BFA1 0x8A49 # 0 +0x8EA3BFA2 0x8A5D # 0 +0x8EA3BFA3 0x8A4B # 0 +0x8EA3BFA4 0x8A3D # 0 +0x8EA3BFA9 0x8C60 # 0 +0x8EA3BFAA 0x8C5E # 0 +0x8EA3BFAB 0x8C7F # 0 +0x8EA3BFAC 0x8C7E # 0 +0x8EA3BFAD 0x8C83 # 0 +0x8EA3BFAF 0x8CB1 # 0 +0x8EA3BFB0 0x8D87 # 0 +0x8EA3BFB3 0x8D88 # 0 +0x8EA3BFB4 0x8D83 # 0 +0x8EA3BFB7 0x8D86 # 0 +0x8EA3BFB8 0x8D8B # 0 +0x8EA3BFB9 0x8D82 # 0 +0x8EA3BFBA 0x8DCA # 0 +0x8EA3BFBB 0x8DD2 # 0 +0x8EA3BFBE 0x8DD4 # 0 +0x8EA3BFBF 0x8DC9 # 0 +0x8EA3BFC0 0x8EB0 # 0 +0x8EA3BFC4 0x8EF2 # 0 +0x8EA3BFC5 0x8EE4 # 0 +0x8EA3BFC6 0x8EF3 # 0 +0x8EA3BFC7 0x8EEA # 0 +0x8EA3BFC9 0x8EFD # 0 +0x8EA3BFCB 0x8F9D # 0 +0x8EA3BFCC 0x902B # 0 +0x8EA3BFCD 0x902A # 0 +0x8EA3BFCF 0x9028 # 0 +0x8EA3BFD0 0x9029 # 0 +0x8EA3BFD1 0x902C # 0 +0x8EA3BFD4 0x903A # 0 +0x8EA3BFD5 0x9030 # 0 +0x8EA3BFD6 0x9037 # 0 +0x8EA3BFD7 0x903B # 0 +0x8EA3BFD9 0x910A # 0 +0x8EA3BFDD 0x91FE # 0 +0x8EA3BFDE 0x9220 # 0 +0x8EA3BFE0 0x920B # 0 +0x8EA3BFE2 0x9218 # 0 +0x8EA3BFE3 0x9222 # 0 +0x8EA3BFE5 0x921B # 0 +0x8EA3BFE6 0x9208 # 0 +0x8EA3BFE8 0x920E # 0 +0x8EA3BFE9 0x9213 # 0 +0x8EA3BFEC 0x9595 # 0 +0x8EA3BFF0 0x968C # 0 +0x8EA3BFF1 0x967B # 0 +0x8EA3BFF2 0x967F # 0 +0x8EA3BFF3 0x9681 # 0 +0x8EA3BFF5 0x9682 # 0 +0x8EA3BFFB 0x96EE # 0 +0x8EA3BFFC 0x96ED # 0 +0x8EA3BFFE 0x96EC # 0 +0x8EA3C0A1 0x975F # 0 +0x8EA3C0A2 0x976F # 0 +0x8EA3C0A4 0x976D # 0 +0x8EA3C0AB 0x98F0 # 0 +0x8EA3C0AF 0x9AA9 # 0 +0x8EA3C0B2 0x9AE0 # 0 +0x8EA3C0B3 0x4EB7 # 0 +0x8EA3C0B6 0x50CC # 0 +0x8EA3C0B7 0x50BC # 0 +0x8EA3C0B9 0x50AA # 0 +0x8EA3C0BA 0x50B9 # 0 +0x8EA3C0BC 0x50AB # 0 +0x8EA3C0BD 0x50C3 # 0 +0x8EA3C0BE 0x50CD # 0 +0x8EA3C0BF 0x517E # 0 +0x8EA3C0C0 0x527E # 0 +0x8EA3C0C1 0x5279 # 0 +0x8EA3C0C4 0x52E1 # 0 +0x8EA3C0C5 0x52E0 # 0 +0x8EA3C0C6 0x52E7 # 0 +0x8EA3C0C7 0x5380 # 0 +0x8EA3C0C8 0x53AB # 0 +0x8EA3C0C9 0x53AA # 0 +0x8EA3C0CA 0x53A9 # 0 +0x8EA3C0CB 0x53E0 # 0 +0x8EA3C0CC 0x55EA # 0 +0x8EA3C0CE 0x55D7 # 0 +0x8EA3C0D1 0x55C1 # 0 +0x8EA3C0D2 0x5715 # 0 +0x8EA3C0D4 0x586C # 0 +0x8EA3C0D6 0x585C # 0 +0x8EA3C0D7 0x5850 # 0 +0x8EA3C0D8 0x5861 # 0 +0x8EA3C0D9 0x586A # 0 +0x8EA3C0DA 0x5869 # 0 +0x8EA3C0DB 0x5856 # 0 +0x8EA3C0DC 0x5860 # 0 +0x8EA3C0DD 0x5866 # 0 +0x8EA3C0DE 0x585F # 0 +0x8EA3C0DF 0x5923 # 0 +0x8EA3C0E0 0x5966 # 0 +0x8EA3C0E1 0x5968 # 0 +0x8EA3C0E4 0x5ACE # 0 +0x8EA3C0E6 0x5AC5 # 0 +0x8EA3C0E7 0x5AC3 # 0 +0x8EA3C0EA 0x5AD0 # 0 +0x8EA3C0F1 0x5B74 # 0 +0x8EA3C0F2 0x5B76 # 0 +0x8EA3C0F3 0x5BDC # 0 +0x8EA3C0F4 0x5BD7 # 0 +0x8EA3C0F5 0x5BDA # 0 +0x8EA3C0F6 0x5BDB # 0 +0x8EA3C0F8 0x5C20 # 0 +0x8EA3C0F9 0x5D6D # 0 +0x8EA3C0FA 0x5D66 # 0 +0x8EA3C0FC 0x5D64 # 0 +0x8EA3C0FD 0x5D6E # 0 +0x8EA3C1A1 0x5D60 # 0 +0x8EA3C1A2 0x5F42 # 0 +0x8EA3C1A3 0x5F5A # 0 +0x8EA3C1A4 0x5F6E # 0 +0x8EA3C1A7 0x6130 # 0 +0x8EA3C1A8 0x613A # 0 +0x8EA3C1A9 0x612A # 0 +0x8EA3C1AA 0x6143 # 0 +0x8EA3C1AB 0x6119 # 0 +0x8EA3C1AC 0x6131 # 0 +0x8EA3C1AE 0x613D # 0 +0x8EA3C1B2 0x6408 # 0 +0x8EA3C1B3 0x6432 # 0 +0x8EA3C1B4 0x6438 # 0 +0x8EA3C1B6 0x6431 # 0 +0x8EA3C1B8 0x6419 # 0 +0x8EA3C1BA 0x6411 # 0 +0x8EA3C1BD 0x6429 # 0 +0x8EA3C1BE 0x641D # 0 +0x8EA3C1C2 0x643C # 0 +0x8EA3C1C4 0x6446 # 0 +0x8EA3C1C5 0x6447 # 0 +0x8EA3C1C8 0x643A # 0 +0x8EA3C1C9 0x6407 # 0 +0x8EA3C1CB 0x656B # 0 +0x8EA3C1CD 0x6570 # 0 +0x8EA3C1CE 0x656D # 0 +0x8EA3C1D0 0x65E4 # 0 +0x8EA3C1D1 0x6693 # 0 +0x8EA3C1D6 0x668F # 0 +0x8EA3C1D9 0x6692 # 0 +0x8EA3C1DB 0x668E # 0 +0x8EA3C1DD 0x6946 # 0 +0x8EA3C1E5 0x6931 # 0 +0x8EA3C1E8 0x693E # 0 +0x8EA3C1EA 0x697C # 0 +0x8EA3C1EB 0x6943 # 0 +0x8EA3C1ED 0x6973 # 0 +0x8EA3C1EF 0x6955 # 0 +0x8EA3C1F2 0x6985 # 0 +0x8EA3C1F3 0x694D # 0 +0x8EA3C1F4 0x6950 # 0 +0x8EA3C1F5 0x6947 # 0 +0x8EA3C1F6 0x6967 # 0 +0x8EA3C1F7 0x6936 # 0 +0x8EA3C1F8 0x6964 # 0 +0x8EA3C1F9 0x6961 # 0 +0x8EA3C1FB 0x697D # 0 +0x8EA3C1FC 0x6B44 # 0 +0x8EA3C1FD 0x6B40 # 0 +0x8EA3C1FE 0x6B71 # 0 +0x8EA3C2A1 0x6B73 # 0 +0x8EA3C2A2 0x6B9C # 0 +0x8EA3C2A6 0x6BC1 # 0 +0x8EA3C2A8 0x6BFA # 0 +0x8EA3C2A9 0x6C31 # 0 +0x8EA3C2AA 0x6C32 # 0 +0x8EA3C2AD 0x6EB8 # 0 +0x8EA3C2AE 0x6EA8 # 0 +0x8EA3C2B0 0x6E91 # 0 +0x8EA3C2B1 0x6EBB # 0 +0x8EA3C2B3 0x6E9A # 0 +0x8EA3C2B6 0x6EA9 # 0 +0x8EA3C2B9 0x6EB5 # 0 +0x8EA3C2BA 0x6E6C # 0 +0x8EA3C2BB 0x6EE8 # 0 +0x8EA3C2BD 0x6EDD # 0 +0x8EA3C2BE 0x6EDA # 0 +0x8EA3C2BF 0x6EE6 # 0 +0x8EA3C2C0 0x6EAC # 0 +0x8EA3C2C4 0x6ED9 # 0 +0x8EA3C2C5 0x6EE3 # 0 +0x8EA3C2C6 0x6EE9 # 0 +0x8EA3C2C7 0x6EDB # 0 +0x8EA3C2C9 0x716F # 0 +0x8EA3C2CC 0x7148 # 0 +0x8EA3C2CE 0x714A # 0 +0x8EA3C2CF 0x716B # 0 +0x8EA3C2D1 0x714F # 0 +0x8EA3C2D2 0x7157 # 0 +0x8EA3C2D3 0x7174 # 0 +0x8EA3C2D7 0x7145 # 0 +0x8EA3C2D8 0x7151 # 0 +0x8EA3C2D9 0x716D # 0 +0x8EA3C2DB 0x7251 # 0 +0x8EA3C2DC 0x7250 # 0 +0x8EA3C2DD 0x724E # 0 +0x8EA3C2DF 0x7341 # 0 +0x8EA3C2E1 0x732E # 0 +0x8EA3C2E2 0x7346 # 0 +0x8EA3C2E4 0x7427 # 0 +0x8EA3C2E6 0x7448 # 0 +0x8EA3C2E7 0x7453 # 0 +0x8EA3C2E8 0x743D # 0 +0x8EA3C2EA 0x745D # 0 +0x8EA3C2EB 0x7456 # 0 +0x8EA3C2ED 0x741E # 0 +0x8EA3C2EE 0x7447 # 0 +0x8EA3C2EF 0x7443 # 0 +0x8EA3C2F0 0x7458 # 0 +0x8EA3C2F1 0x7449 # 0 +0x8EA3C2F3 0x744C # 0 +0x8EA3C2F4 0x7445 # 0 +0x8EA3C2F5 0x743E # 0 +0x8EA3C2F7 0x7501 # 0 +0x8EA3C2F8 0x751E # 0 +0x8EA3C2FB 0x757A # 0 +0x8EA3C2FC 0x75EE # 0 +0x8EA3C2FD 0x7602 # 0 +0x8EA3C2FE 0x7697 # 0 +0x8EA3C3A1 0x7698 # 0 +0x8EA3C3A5 0x775D # 0 +0x8EA3C3A6 0x7764 # 0 +0x8EA3C3A7 0x7753 # 0 +0x8EA3C3A8 0x7758 # 0 +0x8EA3C3A9 0x7882 # 0 +0x8EA3C3AA 0x7890 # 0 +0x8EA3C3AB 0x788A # 0 +0x8EA3C3AD 0x787A # 0 +0x8EA3C3AE 0x787D # 0 +0x8EA3C3B0 0x788B # 0 +0x8EA3C3B1 0x7878 # 0 +0x8EA3C3B4 0x788D # 0 +0x8EA3C3B5 0x7888 # 0 +0x8EA3C3B6 0x7892 # 0 +0x8EA3C3B7 0x7881 # 0 +0x8EA3C3B8 0x797E # 0 +0x8EA3C3B9 0x7983 # 0 +0x8EA3C3BD 0x7980 # 0 +0x8EA3C3C1 0x7A0F # 0 +0x8EA3C3C4 0x7A1D # 0 +0x8EA3C3C6 0x7AA1 # 0 +0x8EA3C3C7 0x7AA4 # 0 +0x8EA3C3C9 0x7AE9 # 0 +0x8EA3C3CA 0x7AEA # 0 +0x8EA3C3CC 0x7B62 # 0 +0x8EA3C3CD 0x7B6B # 0 +0x8EA3C3CF 0x7B5E # 0 +0x8EA3C3D1 0x7B79 # 0 +0x8EA3C3D4 0x7B6F # 0 +0x8EA3C3D5 0x7B68 # 0 +0x8EA3C3D8 0x7CAE # 0 +0x8EA3C3DC 0x7CB0 # 0 +0x8EA3C3DE 0x7D90 # 0 +0x8EA3C3E0 0x7D8A # 0 +0x8EA3C3E2 0x7D8B # 0 +0x8EA3C3E3 0x7D99 # 0 +0x8EA3C3E4 0x7D95 # 0 +0x8EA3C3E6 0x7D87 # 0 +0x8EA3C3E7 0x7D78 # 0 +0x8EA3C3E8 0x7D97 # 0 +0x8EA3C3E9 0x7D89 # 0 +0x8EA3C3EA 0x7D98 # 0 +0x8EA3C3EE 0x7FA3 # 0 +0x8EA3C3F2 0x7FDD # 0 +0x8EA3C3F3 0x8057 # 0 +0x8EA3C3F5 0x8163 # 0 +0x8EA3C3F6 0x816A # 0 +0x8EA3C3F7 0x816C # 0 +0x8EA3C3FB 0x815D # 0 +0x8EA3C3FC 0x8175 # 0 +0x8EA3C3FE 0x815F # 0 +0x8EA3C4A2 0x817D # 0 +0x8EA3C4A3 0x816D # 0 +0x8EA3C4A6 0x8241 # 0 +0x8EA3C4A7 0x844F # 0 +0x8EA3C4A8 0x8484 # 0 +0x8EA3C4AA 0x847F # 0 +0x8EA3C4AC 0x8448 # 0 +0x8EA3C4AD 0x842A # 0 +0x8EA3C4AE 0x847B # 0 +0x8EA3C4AF 0x8472 # 0 +0x8EA3C4B0 0x8464 # 0 +0x8EA3C4B1 0x842E # 0 +0x8EA3C4B2 0x845C # 0 +0x8EA3C4B3 0x8453 # 0 +0x8EA3C4B5 0x8441 # 0 +0x8EA3C4B6 0x84C8 # 0 +0x8EA3C4B8 0x8462 # 0 +0x8EA3C4B9 0x8480 # 0 +0x8EA3C4BA 0x843E # 0 +0x8EA3C4BB 0x8483 # 0 +0x8EA3C4BC 0x8471 # 0 +0x8EA3C4BE 0x844A # 0 +0x8EA3C4BF 0x8455 # 0 +0x8EA3C4C0 0x8458 # 0 +0x8EA3C4C4 0x86FC # 0 +0x8EA3C4C5 0x86FD # 0 +0x8EA3C4C6 0x8715 # 0 +0x8EA3C4C8 0x8716 # 0 +0x8EA3C4C9 0x86FF # 0 +0x8EA3C4CD 0x8858 # 0 +0x8EA3C4CE 0x88CF # 0 +0x8EA3C4CF 0x88E0 # 0 +0x8EA3C4D4 0x89E7 # 0 +0x8EA3C4D5 0x8A6A # 0 +0x8EA3C4D6 0x8A80 # 0 +0x8EA3C4D8 0x8A6F # 0 +0x8EA3C4D9 0x8A65 # 0 +0x8EA3C4DB 0x8A78 # 0 +0x8EA3C4DC 0x8A7D # 0 +0x8EA3C4DD 0x8A88 # 0 +0x8EA3C4E0 0x8A64 # 0 +0x8EA3C4E1 0x8A7E # 0 +0x8EA3C4E3 0x8A67 # 0 +0x8EA3C4E4 0x8C63 # 0 +0x8EA3C4E5 0x8C88 # 0 +0x8EA3C4E7 0x8CCD # 0 +0x8EA3C4E9 0x8CC9 # 0 +0x8EA3C4EB 0x8DED # 0 +0x8EA3C4F3 0x8EB1 # 0 +0x8EA3C4F6 0x8F04 # 0 +0x8EA3C4F7 0x8F9E # 0 +0x8EA3C4F8 0x8FA0 # 0 +0x8EA3C4F9 0x9043 # 0 +0x8EA3C4FA 0x9046 # 0 +0x8EA3C4FB 0x9048 # 0 +0x8EA3C4FC 0x9045 # 0 +0x8EA3C4FD 0x9040 # 0 +0x8EA3C4FE 0x904C # 0 +0x8EA3C5A3 0x910C # 0 +0x8EA3C5A4 0x9113 # 0 +0x8EA3C5A5 0x9115 # 0 +0x8EA3C5A7 0x916B # 0 +0x8EA3C5A8 0x9167 # 0 +0x8EA3C5A9 0x925D # 0 +0x8EA3C5AA 0x9255 # 0 +0x8EA3C5AB 0x9235 # 0 +0x8EA3C5AD 0x9259 # 0 +0x8EA3C5AE 0x922F # 0 +0x8EA3C5AF 0x923C # 0 +0x8EA3C5B0 0x928F # 0 +0x8EA3C5B1 0x925C # 0 +0x8EA3C5B2 0x926A # 0 +0x8EA3C5B3 0x9262 # 0 +0x8EA3C5B4 0x925F # 0 +0x8EA3C5B5 0x926B # 0 +0x8EA3C5B6 0x926E # 0 +0x8EA3C5B7 0x923B # 0 +0x8EA3C5B8 0x9244 # 0 +0x8EA3C5B9 0x9241 # 0 +0x8EA3C5BA 0x959A # 0 +0x8EA3C5BC 0x9599 # 0 +0x8EA3C5C0 0x968F # 0 +0x8EA3C5C2 0x9696 # 0 +0x8EA3C5C6 0x96F4 # 0 +0x8EA3C5C7 0x96FC # 0 +0x8EA3C5C9 0x9755 # 0 +0x8EA3C5CB 0x9779 # 0 +0x8EA3C5CF 0x97EE # 0 +0x8EA3C5D0 0x97F5 # 0 +0x8EA3C5D2 0x980B # 0 +0x8EA3C5D4 0x98F3 # 0 +0x8EA3C5D7 0x98F7 # 0 +0x8EA3C5D8 0x98FF # 0 +0x8EA3C5D9 0x98F5 # 0 +0x8EA3C5DB 0x98EC # 0 +0x8EA3C5DC 0x98F1 # 0 +0x8EA3C5DF 0x999A # 0 +0x8EA3C5E1 0x9AE2 # 0 +0x8EA3C5E2 0x9B3D # 0 +0x8EA3C5E3 0x9B5D # 0 +0x8EA3C5E4 0x9CE8 # 0 +0x8EA3C5E6 0x9CEB # 0 +0x8EA3C5E7 0x9CEF # 0 +0x8EA3C5E8 0x9CEE # 0 +0x8EA3C5E9 0x9E81 # 0 +0x8EA3C5EA 0x9F14 # 0 +0x8EA3C5EB 0x50D0 # 0 +0x8EA3C5EC 0x50D9 # 0 +0x8EA3C5ED 0x50DC # 0 +0x8EA3C5EE 0x50D8 # 0 +0x8EA3C5F0 0x50E1 # 0 +0x8EA3C5F1 0x50EB # 0 +0x8EA3C5F4 0x50F4 # 0 +0x8EA3C5F5 0x50E2 # 0 +0x8EA3C5F6 0x50DE # 0 +0x8EA3C5FA 0x51F4 # 0 +0x8EA3C5FE 0x52ED # 0 +0x8EA3C6A1 0x52EA # 0 +0x8EA3C6A3 0x5332 # 0 +0x8EA3C6A5 0x53AE # 0 +0x8EA3C6A6 0x53B0 # 0 +0x8EA3C6A8 0x55FB # 0 +0x8EA3C6A9 0x5603 # 0 +0x8EA3C6AA 0x560B # 0 +0x8EA3C6AC 0x5607 # 0 +0x8EA3C6AE 0x55F8 # 0 +0x8EA3C6B0 0x5628 # 0 +0x8EA3C6B1 0x561E # 0 +0x8EA3C6B3 0x5618 # 0 +0x8EA3C6B4 0x5611 # 0 +0x8EA3C6B5 0x5651 # 0 +0x8EA3C6B6 0x5605 # 0 +0x8EA3C6B7 0x5717 # 0 +0x8EA3C6B8 0x5892 # 0 +0x8EA3C6BA 0x588C # 0 +0x8EA3C6BC 0x5878 # 0 +0x8EA3C6BD 0x5884 # 0 +0x8EA3C6BE 0x5873 # 0 +0x8EA3C6BF 0x58AD # 0 +0x8EA3C6C0 0x5897 # 0 +0x8EA3C6C1 0x5895 # 0 +0x8EA3C6C2 0x5877 # 0 +0x8EA3C6C3 0x5872 # 0 +0x8EA3C6C4 0x5896 # 0 +0x8EA3C6C5 0x588D # 0 +0x8EA3C6C6 0x5910 # 0 +0x8EA3C6C8 0x596C # 0 +0x8EA3C6CA 0x5AE7 # 0 +0x8EA3C6CC 0x5AE4 # 0 +0x8EA3C6CF 0x5AEF # 0 +0x8EA3C6D0 0x5626 # 0 +0x8EA3C6D3 0x5AF0 # 0 +0x8EA3C6D4 0x5D7B # 0 +0x8EA3C6D6 0x5D83 # 0 +0x8EA3C6D9 0x5D8B # 0 +0x8EA3C6DA 0x5D8C # 0 +0x8EA3C6DC 0x5D78 # 0 +0x8EA3C6DD 0x5E52 # 0 +0x8EA3C6E0 0x5ED0 # 0 +0x8EA3C6E1 0x5ECF # 0 +0x8EA3C6E3 0x5FB3 # 0 +0x8EA3C6E4 0x5FB4 # 0 +0x8EA3C6E8 0x617B # 0 +0x8EA3C6EA 0x616F # 0 +0x8EA3C6EB 0x6181 # 0 +0x8EA3C6EC 0x613C # 0 +0x8EA3C6ED 0x6142 # 0 +0x8EA3C6EE 0x6138 # 0 +0x8EA3C6EF 0x6133 # 0 +0x8EA3C6F1 0x6160 # 0 +0x8EA3C6F2 0x6169 # 0 +0x8EA3C6F3 0x617D # 0 +0x8EA3C6F4 0x6186 # 0 +0x8EA3C6F5 0x622C # 0 +0x8EA3C6F6 0x6228 # 0 +0x8EA3C6F8 0x644C # 0 +0x8EA3C6FA 0x6457 # 0 +0x8EA3C6FB 0x647C # 0 +0x8EA3C6FE 0x6455 # 0 +0x8EA3C7A1 0x6462 # 0 +0x8EA3C7A2 0x6471 # 0 +0x8EA3C7A3 0x646A # 0 +0x8EA3C7A4 0x6456 # 0 +0x8EA3C7A5 0x643B # 0 +0x8EA3C7A6 0x6481 # 0 +0x8EA3C7A8 0x644F # 0 +0x8EA3C7A9 0x647E # 0 +0x8EA3C7AA 0x6464 # 0 +0x8EA3C7B0 0x6571 # 0 +0x8EA3C7B3 0x66A5 # 0 +0x8EA3C7B4 0x669A # 0 +0x8EA3C7B5 0x669C # 0 +0x8EA3C7B7 0x66A6 # 0 +0x8EA3C7B9 0x66A4 # 0 +0x8EA3C7BA 0x698F # 0 +0x8EA3C7BB 0x69C5 # 0 +0x8EA3C7BC 0x69C8 # 0 +0x8EA3C7BD 0x6992 # 0 +0x8EA3C7BE 0x69B2 # 0 +0x8EA3C7C2 0x69E3 # 0 +0x8EA3C7C3 0x69C0 # 0 +0x8EA3C7C4 0x69D6 # 0 +0x8EA3C7C5 0x69D1 # 0 +0x8EA3C7C6 0x699F # 0 +0x8EA3C7C7 0x69A2 # 0 +0x8EA3C7C8 0x69D2 # 0 +0x8EA3C7CC 0x69E1 # 0 +0x8EA3C7CD 0x69D5 # 0 +0x8EA3C7CE 0x699D # 0 +0x8EA3C7D1 0x6998 # 0 +0x8EA3C7D3 0x6B74 # 0 +0x8EA3C7D4 0x6BA1 # 0 +0x8EA3C7D6 0x6EF0 # 0 +0x8EA3C7D7 0x6EF3 # 0 +0x8EA3C7DA 0x6F1B # 0 +0x8EA3C7DB 0x6F0C # 0 +0x8EA3C7DC 0x6F1D # 0 +0x8EA3C7DD 0x6F34 # 0 +0x8EA3C7DE 0x6F28 # 0 +0x8EA3C7DF 0x6F17 # 0 +0x8EA3C7E1 0x6F44 # 0 +0x8EA3C7E2 0x6F42 # 0 +0x8EA3C7E3 0x6F04 # 0 +0x8EA3C7E4 0x6F11 # 0 +0x8EA3C7E5 0x6EFA # 0 +0x8EA3C7E6 0x6F4A # 0 +0x8EA3C7E7 0x7191 # 0 +0x8EA3C7E8 0x718E # 0 +0x8EA3C7EA 0x718B # 0 +0x8EA3C7EB 0x718D # 0 +0x8EA3C7EC 0x717F # 0 +0x8EA3C7ED 0x718C # 0 +0x8EA3C7EE 0x717E # 0 +0x8EA3C7EF 0x717C # 0 +0x8EA3C7F0 0x7183 # 0 +0x8EA3C7F2 0x7188 # 0 +0x8EA3C7F5 0x7294 # 0 +0x8EA3C7F7 0x7355 # 0 +0x8EA3C7F8 0x7353 # 0 +0x8EA3C7F9 0x734F # 0 +0x8EA3C7FA 0x7354 # 0 +0x8EA3C7FB 0x746C # 0 +0x8EA3C7FC 0x7465 # 0 +0x8EA3C7FD 0x7466 # 0 +0x8EA3C7FE 0x7461 # 0 +0x8EA3C8A1 0x746B # 0 +0x8EA3C8A2 0x7468 # 0 +0x8EA3C8A3 0x7476 # 0 +0x8EA3C8A5 0x7460 # 0 +0x8EA3C8A7 0x7474 # 0 +0x8EA3C8A8 0x7506 # 0 +0x8EA3C8A9 0x760E # 0 +0x8EA3C8AB 0x7607 # 0 +0x8EA3C8AE 0x76B9 # 0 +0x8EA3C8B0 0x76B7 # 0 +0x8EA3C8B1 0x76E2 # 0 +0x8EA3C8B3 0x7774 # 0 +0x8EA3C8B4 0x7777 # 0 +0x8EA3C8B5 0x7776 # 0 +0x8EA3C8B6 0x7775 # 0 +0x8EA3C8B8 0x7778 # 0 +0x8EA3C8B9 0x7771 # 0 +0x8EA3C8BB 0x777A # 0 +0x8EA3C8BC 0x715B # 0 +0x8EA3C8BD 0x777B # 0 +0x8EA3C8BE 0x78A6 # 0 +0x8EA3C8BF 0x78AE # 0 +0x8EA3C8C0 0x78B8 # 0 +0x8EA3C8C4 0x78B1 # 0 +0x8EA3C8C5 0x78AF # 0 +0x8EA3C8C7 0x7989 # 0 +0x8EA3C8C8 0x7987 # 0 +0x8EA3C8CB 0x7A29 # 0 +0x8EA3C8CD 0x7A2A # 0 +0x8EA3C8CF 0x7A2D # 0 +0x8EA3C8D0 0x7A2C # 0 +0x8EA3C8D2 0x7A32 # 0 +0x8EA3C8D4 0x7AEC # 0 +0x8EA3C8D5 0x7AF0 # 0 +0x8EA3C8D6 0x7B81 # 0 +0x8EA3C8D7 0x7B9E # 0 +0x8EA3C8D8 0x7B83 # 0 +0x8EA3C8DA 0x7B92 # 0 +0x8EA3C8DC 0x7BA3 # 0 +0x8EA3C8DD 0x7B9F # 0 +0x8EA3C8DE 0x7B93 # 0 +0x8EA3C8E0 0x7B86 # 0 +0x8EA3C8E1 0x7CB8 # 0 +0x8EA3C8E2 0x7CB7 # 0 +0x8EA3C8E8 0x7DC8 # 0 +0x8EA3C8E9 0x7DB6 # 0 +0x8EA3C8EB 0x7DD1 # 0 +0x8EA3C8ED 0x7DA8 # 0 +0x8EA3C8EE 0x7DAB # 0 +0x8EA3C8F0 0x7DB3 # 0 +0x8EA3C8F1 0x7DCD # 0 +0x8EA3C8F3 0x7DCF # 0 +0x8EA3C8F4 0x7DA4 # 0 +0x8EA3C8F7 0x7F41 # 0 +0x8EA3C8F8 0x7F6F # 0 +0x8EA3C8F9 0x7F71 # 0 +0x8EA3C9A2 0x8023 # 0 +0x8EA3C9A3 0x805B # 0 +0x8EA3C9A5 0x8061 # 0 +0x8EA3C9A6 0x805F # 0 +0x8EA3C9A7 0x8181 # 0 +0x8EA3C9AA 0x8184 # 0 +0x8EA3C9AB 0x8213 # 0 +0x8EA3C9AD 0x824A # 0 +0x8EA3C9AE 0x824C # 0 +0x8EA3C9B2 0x84BD # 0 +0x8EA3C9B3 0x8495 # 0 +0x8EA3C9B5 0x8492 # 0 +0x8EA3C9B6 0x84C3 # 0 +0x8EA3C9B8 0x8496 # 0 +0x8EA3C9B9 0x84A5 # 0 +0x8EA3C9BA 0x84B5 # 0 +0x8EA3C9BB 0x84B3 # 0 +0x8EA3C9BC 0x84A3 # 0 +0x8EA3C9BD 0x84E4 # 0 +0x8EA3C9BE 0x84D8 # 0 +0x8EA3C9BF 0x84D5 # 0 +0x8EA3C9C1 0x84B7 # 0 +0x8EA3C9C2 0x84AD # 0 +0x8EA3C9C3 0x84DA # 0 +0x8EA3C9C4 0x8493 # 0 +0x8EA3C9C5 0x8736 # 0 +0x8EA3C9C9 0x873D # 0 +0x8EA3C9CA 0x872B # 0 +0x8EA3C9CB 0x8747 # 0 +0x8EA3C9CC 0x8739 # 0 +0x8EA3C9CE 0x8745 # 0 +0x8EA3C9CF 0x871D # 0 +0x8EA3C9D1 0x88FF # 0 +0x8EA3C9D2 0x88EA # 0 +0x8EA3C9D4 0x88F5 # 0 +0x8EA3C9D6 0x8900 # 0 +0x8EA3C9D7 0x88ED # 0 +0x8EA3C9D8 0x8903 # 0 +0x8EA3C9D9 0x88E9 # 0 +0x8EA3C9DC 0x89EA # 0 +0x8EA3C9DE 0x8A9B # 0 +0x8EA3C9DF 0x8A8E # 0 +0x8EA3C9E0 0x8AA2 # 0 +0x8EA3C9E2 0x8A9C # 0 +0x8EA3C9E3 0x8A94 # 0 +0x8EA3C9E4 0x8A90 # 0 +0x8EA3C9E5 0x8AA9 # 0 +0x8EA3C9E6 0x8AAC # 0 +0x8EA3C9E8 0x8A9F # 0 +0x8EA3C9EB 0x8A9D # 0 +0x8EA3C9ED 0x8C67 # 0 +0x8EA3C9F0 0x8CD0 # 0 +0x8EA3C9F1 0x8CD6 # 0 +0x8EA3C9F2 0x8CD4 # 0 +0x8EA3C9F3 0x8D98 # 0 +0x8EA3C9F4 0x8D9A # 0 +0x8EA3C9F5 0x8D97 # 0 +0x8EA3C9F9 0x8E0B # 0 +0x8EA3C9FA 0x8E08 # 0 +0x8EA3C9FB 0x8E01 # 0 +0x8EA3C9FC 0x8EB4 # 0 +0x8EA3C9FD 0x8EB3 # 0 +0x8EA3CAA1 0x8FA1 # 0 +0x8EA3CAA2 0x8FA2 # 0 +0x8EA3CAA4 0x905A # 0 +0x8EA3CAA6 0x9061 # 0 +0x8EA3CAA7 0x905F # 0 +0x8EA3CAAA 0x9125 # 0 +0x8EA3CAAB 0x917B # 0 +0x8EA3CAAC 0x9176 # 0 +0x8EA3CAAD 0x917C # 0 +0x8EA3CAAF 0x9289 # 0 +0x8EA3CAB0 0x92F6 # 0 +0x8EA3CAB1 0x92B1 # 0 +0x8EA3CAB2 0x92AD # 0 +0x8EA3CAB3 0x9292 # 0 +0x8EA3CAB4 0x9281 # 0 +0x8EA3CAB5 0x9284 # 0 +0x8EA3CAB7 0x92AE # 0 +0x8EA3CAB8 0x9290 # 0 +0x8EA3CAB9 0x929E # 0 +0x8EA3CABD 0x95A2 # 0 +0x8EA3CABE 0x95A7 # 0 +0x8EA3CAC4 0x96A0 # 0 +0x8EA3CAC5 0x969D # 0 +0x8EA3CAC6 0x969F # 0 +0x8EA3CAC7 0x96D0 # 0 +0x8EA3CAC9 0x96D1 # 0 +0x8EA3CACC 0x9759 # 0 +0x8EA3CACE 0x9764 # 0 +0x8EA3CAD2 0x9819 # 0 +0x8EA3CAD4 0x9814 # 0 +0x8EA3CAD5 0x9815 # 0 +0x8EA3CAD6 0x981A # 0 +0x8EA3CADB 0x9906 # 0 +0x8EA3CADD 0x98F8 # 0 +0x8EA3CADE 0x9901 # 0 +0x8EA3CAE0 0x99BE # 0 +0x8EA3CAE1 0x99BC # 0 +0x8EA3CAE2 0x99B7 # 0 +0x8EA3CAE3 0x99B6 # 0 +0x8EA3CAE4 0x99C0 # 0 +0x8EA3CAE6 0x99B8 # 0 +0x8EA3CAEA 0x99C4 # 0 +0x8EA3CAEC 0x99BF # 0 +0x8EA3CAEE 0x9ADA # 0 +0x8EA3CAEF 0x9AE4 # 0 +0x8EA3CAF0 0x9AE9 # 0 +0x8EA3CAF1 0x9AE8 # 0 +0x8EA3CAF2 0x9AEA # 0 +0x8EA3CAF3 0x9AE5 # 0 +0x8EA3CAF5 0x9B26 # 0 +0x8EA3CAF8 0x9B40 # 0 +0x8EA3CBA2 0x9EBD # 0 +0x8EA3CBA7 0x510E # 0 +0x8EA3CBA9 0x50F7 # 0 +0x8EA3CBAB 0x50FC # 0 +0x8EA3CBAC 0x510D # 0 +0x8EA3CBAD 0x5101 # 0 +0x8EA3CBAE 0x51DA # 0 +0x8EA3CBAF 0x51D9 # 0 +0x8EA3CBB0 0x51DB # 0 +0x8EA3CBB1 0x5286 # 0 +0x8EA3CBB2 0x528E # 0 +0x8EA3CBB3 0x52EE # 0 +0x8EA3CBB4 0x5333 # 0 +0x8EA3CBB5 0x53B1 # 0 +0x8EA3CBB7 0x5647 # 0 +0x8EA3CBB8 0x562D # 0 +0x8EA3CBB9 0x5654 # 0 +0x8EA3CBBB 0x564B # 0 +0x8EA3CBBC 0x5652 # 0 +0x8EA3CBBD 0x5631 # 0 +0x8EA3CBBE 0x5644 # 0 +0x8EA3CBBF 0x5656 # 0 +0x8EA3CBC0 0x5650 # 0 +0x8EA3CBC1 0x562B # 0 +0x8EA3CBC3 0x564D # 0 +0x8EA3CBC4 0x5637 # 0 +0x8EA3CBC5 0x564F # 0 +0x8EA3CBC6 0x58A2 # 0 +0x8EA3CBC7 0x58B7 # 0 +0x8EA3CBC9 0x58B2 # 0 +0x8EA3CBCB 0x58AA # 0 +0x8EA3CBCC 0x58B5 # 0 +0x8EA3CBCD 0x58B0 # 0 +0x8EA3CBCF 0x58B4 # 0 +0x8EA3CBD0 0x58A4 # 0 +0x8EA3CBD1 0x58A7 # 0 +0x8EA3CBD3 0x5926 # 0 +0x8EA3CBD4 0x5AFE # 0 +0x8EA3CBD6 0x5B04 # 0 +0x8EA3CBD8 0x5AFC # 0 +0x8EA3CBDA 0x5B06 # 0 +0x8EA3CBDB 0x5B0A # 0 +0x8EA3CBDC 0x5AFA # 0 +0x8EA3CBDD 0x5B0D # 0 +0x8EA3CBDE 0x5B00 # 0 +0x8EA3CBDF 0x5B0E # 0 +0x8EA3CBE3 0x5D91 # 0 +0x8EA3CBE5 0x5D8F # 0 +0x8EA3CBE6 0x5D90 # 0 +0x8EA3CBE7 0x5D98 # 0 +0x8EA3CBE8 0x5DA4 # 0 +0x8EA3CBE9 0x5D9B # 0 +0x8EA3CBEA 0x5DA3 # 0 +0x8EA3CBEB 0x5D96 # 0 +0x8EA3CBEC 0x5DE4 # 0 +0x8EA3CBED 0x5E5A # 0 +0x8EA3CBF0 0x5E5E # 0 +0x8EA3CBF2 0x5FB8 # 0 +0x8EA3CBF3 0x6157 # 0 +0x8EA3CBF4 0x615C # 0 +0x8EA3CBF5 0x61A6 # 0 +0x8EA3CBF6 0x6195 # 0 +0x8EA3CBF7 0x6188 # 0 +0x8EA3CBF9 0x61A3 # 0 +0x8EA3CBFA 0x618F # 0 +0x8EA3CBFC 0x6164 # 0 +0x8EA3CBFE 0x6159 # 0 +0x8EA3CCA1 0x6178 # 0 +0x8EA3CCA3 0x6185 # 0 +0x8EA3CCA4 0x6187 # 0 +0x8EA3CCA5 0x619E # 0 +0x8EA3CCA8 0x6198 # 0 +0x8EA3CCA9 0x619C # 0 +0x8EA3CCAC 0x622F # 0 +0x8EA3CCAD 0x6480 # 0 +0x8EA3CCAE 0x649B # 0 +0x8EA3CCAF 0x648E # 0 +0x8EA3CCB0 0x648D # 0 +0x8EA3CCB1 0x6494 # 0 +0x8EA3CCB2 0x64C6 # 0 +0x8EA3CCB4 0x64A8 # 0 +0x8EA3CCB5 0x6483 # 0 +0x8EA3CCB7 0x64B9 # 0 +0x8EA3CCB8 0x6486 # 0 +0x8EA3CCB9 0x64B4 # 0 +0x8EA3CCBA 0x64AF # 0 +0x8EA3CCBB 0x6491 # 0 +0x8EA3CCBD 0x64AA # 0 +0x8EA3CCBE 0x64A1 # 0 +0x8EA3CCBF 0x64A7 # 0 +0x8EA3CCC0 0x66B6 # 0 +0x8EA3CCC1 0x66B3 # 0 +0x8EA3CCC3 0x66BC # 0 +0x8EA3CCC4 0x66AC # 0 +0x8EA3CCC6 0x66AD # 0 +0x8EA3CCC7 0x6A0E # 0 +0x8EA3CCC9 0x6A1C # 0 +0x8EA3CCCA 0x6A1A # 0 +0x8EA3CCCD 0x6A0B # 0 +0x8EA3CCCF 0x69EF # 0 +0x8EA3CCD0 0x6A0C # 0 +0x8EA3CCD1 0x69F0 # 0 +0x8EA3CCD2 0x6A22 # 0 +0x8EA3CCD4 0x69D8 # 0 +0x8EA3CCD6 0x6A12 # 0 +0x8EA3CCD7 0x69FA # 0 +0x8EA3CCD9 0x6A2A # 0 +0x8EA3CCDB 0x6A10 # 0 +0x8EA3CCDE 0x6A29 # 0 +0x8EA3CCDF 0x69F9 # 0 +0x8EA3CCE0 0x69EA # 0 +0x8EA3CCE1 0x6A2C # 0 +0x8EA3CCE2 0x6A24 # 0 +0x8EA3CCE4 0x69E9 # 0 +0x8EA3CCE5 0x6B52 # 0 +0x8EA3CCE6 0x6B4F # 0 +0x8EA3CCE7 0x6B53 # 0 +0x8EA3CCEA 0x6F10 # 0 +0x8EA3CCEB 0x6F65 # 0 +0x8EA3CCEC 0x6F75 # 0 +0x8EA3CCF1 0x6FD0 # 0 +0x8EA3CCF3 0x6F5C # 0 +0x8EA3CCF4 0x6F3D # 0 +0x8EA3CCF5 0x6F71 # 0 +0x8EA3CCF7 0x6F91 # 0 +0x8EA3CCF8 0x6F0B # 0 +0x8EA3CCF9 0x6F79 # 0 +0x8EA3CCFA 0x6F81 # 0 +0x8EA3CCFB 0x6F8F # 0 +0x8EA3CCFD 0x6F59 # 0 +0x8EA3CCFE 0x6F74 # 0 +0x8EA3CDA2 0x71AE # 0 +0x8EA3CDA4 0x71A3 # 0 +0x8EA3CDA5 0x71AD # 0 +0x8EA3CDA8 0x71AB # 0 +0x8EA3CDA9 0x71A6 # 0 +0x8EA3CDAA 0x71A2 # 0 +0x8EA3CDAC 0x52F2 # 0 +0x8EA3CDAD 0x7257 # 0 +0x8EA3CDAE 0x7255 # 0 +0x8EA3CDAF 0x7299 # 0 +0x8EA3CDB0 0x734B # 0 +0x8EA3CDB1 0x747A # 0 +0x8EA3CDB5 0x748C # 0 +0x8EA3CDB6 0x7484 # 0 +0x8EA3CDB9 0x7482 # 0 +0x8EA3CDBA 0x7493 # 0 +0x8EA3CDBB 0x747B # 0 +0x8EA3CDBD 0x7509 # 0 +0x8EA3CDC4 0x778A # 0 +0x8EA3CDC6 0x7790 # 0 +0x8EA3CDC8 0x78C6 # 0 +0x8EA3CDC9 0x78D3 # 0 +0x8EA3CDCA 0x78C0 # 0 +0x8EA3CDCB 0x78D2 # 0 +0x8EA3CDCC 0x78C7 # 0 +0x8EA3CDCD 0x78C2 # 0 +0x8EA3CDCF 0x799F # 0 +0x8EA3CDD0 0x799D # 0 +0x8EA3CDD1 0x799E # 0 +0x8EA3CDD3 0x7A41 # 0 +0x8EA3CDD5 0x7A38 # 0 +0x8EA3CDD6 0x7A3A # 0 +0x8EA3CDD7 0x7A42 # 0 +0x8EA3CDDA 0x7A3E # 0 +0x8EA3CDDB 0x7AB0 # 0 +0x8EA3CDDC 0x7BAE # 0 +0x8EA3CDDD 0x7BB3 # 0 +0x8EA3CDE0 0x7BBF # 0 +0x8EA3CDE3 0x7BCD # 0 +0x8EA3CDE5 0x7BB2 # 0 +0x8EA3CDED 0x7CC4 # 0 +0x8EA3CDEE 0x7CCD # 0 +0x8EA3CDEF 0x7CC2 # 0 +0x8EA3CDF0 0x7CC6 # 0 +0x8EA3CDF1 0x7CC3 # 0 +0x8EA3CDF2 0x7CC9 # 0 +0x8EA3CDF3 0x7CC7 # 0 +0x8EA3CDF5 0x7DF8 # 0 +0x8EA3CDF7 0x7DED # 0 +0x8EA3CDF8 0x7DE2 # 0 +0x8EA3CDFC 0x7DDC # 0 +0x8EA3CDFD 0x7E02 # 0 +0x8EA3CDFE 0x7E01 # 0 +0x8EA3CEA2 0x7DD6 # 0 +0x8EA3CEA4 0x7DE4 # 0 +0x8EA3CEA5 0x7DFE # 0 +0x8EA3CEA7 0x7E00 # 0 +0x8EA3CEA8 0x7DFC # 0 +0x8EA3CEA9 0x7DFD # 0 +0x8EA3CEAB 0x7DF5 # 0 +0x8EA3CEAC 0x7DFF # 0 +0x8EA3CEAE 0x7DEB # 0 +0x8EA3CEAF 0x7DE5 # 0 +0x8EA3CEB0 0x7F78 # 0 +0x8EA3CEB1 0x7FAE # 0 +0x8EA3CEB2 0x7FE7 # 0 +0x8EA3CEB4 0x8065 # 0 +0x8EA3CEB5 0x806A # 0 +0x8EA3CEB6 0x8066 # 0 +0x8EA3CEB7 0x8068 # 0 +0x8EA3CEB8 0x806B # 0 +0x8EA3CEB9 0x8194 # 0 +0x8EA3CEBA 0x81A1 # 0 +0x8EA3CEBB 0x8192 # 0 +0x8EA3CEBC 0x8196 # 0 +0x8EA3CEBD 0x8193 # 0 +0x8EA3CEC0 0x8501 # 0 +0x8EA3CEC2 0x84F8 # 0 +0x8EA3CEC4 0x84F5 # 0 +0x8EA3CEC6 0x8504 # 0 +0x8EA3CECB 0x851B # 0 +0x8EA3CECC 0x8503 # 0 +0x8EA3CECD 0x8533 # 0 +0x8EA3CECE 0x8534 # 0 +0x8EA3CECF 0x84ED # 0 +0x8EA3CED2 0x8535 # 0 +0x8EA3CED4 0x8505 # 0 +0x8EA3CED9 0x877D # 0 +0x8EA3CEDD 0x8771 # 0 +0x8EA3CEDF 0x885C # 0 +0x8EA3CEE0 0x88E6 # 0 +0x8EA3CEE1 0x890F # 0 +0x8EA3CEE2 0x891B # 0 +0x8EA3CEE4 0x89A9 # 0 +0x8EA3CEE5 0x89A5 # 0 +0x8EA3CEE6 0x89EE # 0 +0x8EA3CEE7 0x8AB1 # 0 +0x8EA3CEE9 0x8ACC # 0 +0x8EA3CEEA 0x8ACE # 0 +0x8EA3CEEC 0x8AB7 # 0 +0x8EA3CEEE 0x8AB5 # 0 +0x8EA3CEEF 0x8AE9 # 0 +0x8EA3CEF0 0x8AB4 # 0 +0x8EA3CEF2 0x8AB3 # 0 +0x8EA3CEF3 0x8AC1 # 0 +0x8EA3CEF4 0x8AAF # 0 +0x8EA3CEF5 0x8ACA # 0 +0x8EA3CEF6 0x8AD0 # 0 +0x8EA3CEFA 0x8C8E # 0 +0x8EA3CEFD 0x8CE9 # 0 +0x8EA3CEFE 0x8CDB # 0 +0x8EA3CFA2 0x8CEB # 0 +0x8EA3CFA3 0x8DA4 # 0 +0x8EA3CFA5 0x8DA2 # 0 +0x8EA3CFA6 0x8D9D # 0 +0x8EA3CFAB 0x8E2A # 0 +0x8EA3CFAC 0x8E28 # 0 +0x8EA3CFAF 0x8EB8 # 0 +0x8EA3CFB0 0x8EB6 # 0 +0x8EA3CFB1 0x8EB9 # 0 +0x8EA3CFB2 0x8EB7 # 0 +0x8EA3CFB3 0x8F22 # 0 +0x8EA3CFB4 0x8F2B # 0 +0x8EA3CFB5 0x8F27 # 0 +0x8EA3CFB6 0x8F19 # 0 +0x8EA3CFB7 0x8FA4 # 0 +0x8EA3CFB9 0x8FB3 # 0 +0x8EA3CFBB 0x9071 # 0 +0x8EA3CFBC 0x906A # 0 +0x8EA3CFBF 0x9188 # 0 +0x8EA3CFC0 0x918C # 0 +0x8EA3CFC1 0x92BF # 0 +0x8EA3CFC2 0x92B8 # 0 +0x8EA3CFC3 0x92BE # 0 +0x8EA3CFC4 0x92DC # 0 +0x8EA3CFC5 0x92E5 # 0 +0x8EA3CFC8 0x92D4 # 0 +0x8EA3CFC9 0x92D6 # 0 +0x8EA3CFCB 0x92DA # 0 +0x8EA3CFCC 0x92ED # 0 +0x8EA3CFCD 0x92F3 # 0 +0x8EA3CFCE 0x92DB # 0 +0x8EA3CFD0 0x92B9 # 0 +0x8EA3CFD1 0x92E2 # 0 +0x8EA3CFD2 0x92EB # 0 +0x8EA3CFD3 0x95AF # 0 +0x8EA3CFD5 0x95B2 # 0 +0x8EA3CFD6 0x95B3 # 0 +0x8EA3CFDA 0x96A3 # 0 +0x8EA3CFDB 0x96A5 # 0 +0x8EA3CFE0 0x970A # 0 +0x8EA3CFE2 0x9787 # 0 +0x8EA3CFE3 0x9789 # 0 +0x8EA3CFE4 0x978C # 0 +0x8EA3CFE5 0x97EF # 0 +0x8EA3CFE6 0x982A # 0 +0x8EA3CFE7 0x9822 # 0 +0x8EA3CFE9 0x981F # 0 +0x8EA3CFEB 0x9919 # 0 +0x8EA3CFED 0x99CA # 0 +0x8EA3CFEE 0x99DA # 0 +0x8EA3CFF2 0x99DE # 0 +0x8EA3CFF3 0x99C8 # 0 +0x8EA3CFF4 0x99E0 # 0 +0x8EA3CFF6 0x9AB6 # 0 +0x8EA3CFF7 0x9AB5 # 0 +0x8EA3CFF9 0x9AF4 # 0 +0x8EA3CFFB 0x9B6B # 0 +0x8EA3CFFC 0x9B69 # 0 +0x8EA3CFFD 0x9B72 # 0 +0x8EA3CFFE 0x9B63 # 0 +0x8EA3D0A2 0x9D0D # 0 +0x8EA3D0A4 0x9D01 # 0 +0x8EA3D0A5 0x9D0C # 0 +0x8EA3D0A7 0x9CF8 # 0 +0x8EA3D0AA 0x9CFE # 0 +0x8EA3D0AB 0x9D02 # 0 +0x8EA3D0AC 0x9E84 # 0 +0x8EA3D0AE 0x9EAB # 0 +0x8EA3D0AF 0x9EAA # 0 +0x8EA3D0B0 0x511D # 0 +0x8EA3D0B1 0x5116 # 0 +0x8EA3D0B3 0x512B # 0 +0x8EA3D0B4 0x511E # 0 +0x8EA3D0B5 0x511B # 0 +0x8EA3D0B6 0x5290 # 0 +0x8EA3D0B7 0x5294 # 0 +0x8EA3D0B8 0x5314 # 0 +0x8EA3D0BB 0x5667 # 0 +0x8EA3D0BD 0x567B # 0 +0x8EA3D0BF 0x565F # 0 +0x8EA3D0C0 0x5661 # 0 +0x8EA3D0C8 0x58C3 # 0 +0x8EA3D0C9 0x58CA # 0 +0x8EA3D0CA 0x58BB # 0 +0x8EA3D0CB 0x58C0 # 0 +0x8EA3D0CC 0x58C4 # 0 +0x8EA3D0CD 0x5901 # 0 +0x8EA3D0CE 0x5B1F # 0 +0x8EA3D0CF 0x5B18 # 0 +0x8EA3D0D0 0x5B11 # 0 +0x8EA3D0D1 0x5B15 # 0 +0x8EA3D0D3 0x5B12 # 0 +0x8EA3D0D4 0x5B1C # 0 +0x8EA3D0D6 0x5B22 # 0 +0x8EA3D0D7 0x5B79 # 0 +0x8EA3D0D8 0x5DA6 # 0 +0x8EA3D0DA 0x5DB3 # 0 +0x8EA3D0DB 0x5DAB # 0 +0x8EA3D0DC 0x5EEA # 0 +0x8EA3D0DE 0x5F5B # 0 +0x8EA3D0E1 0x61B7 # 0 +0x8EA3D0E2 0x61CE # 0 +0x8EA3D0E3 0x61B9 # 0 +0x8EA3D0E4 0x61BD # 0 +0x8EA3D0E5 0x61CF # 0 +0x8EA3D0E6 0x61C0 # 0 +0x8EA3D0E7 0x6199 # 0 +0x8EA3D0E8 0x6197 # 0 +0x8EA3D0EA 0x61BB # 0 +0x8EA3D0EB 0x61D0 # 0 +0x8EA3D0EC 0x61C4 # 0 +0x8EA3D0ED 0x6231 # 0 +0x8EA3D0EF 0x64D3 # 0 +0x8EA3D0F0 0x64C0 # 0 +0x8EA3D0F5 0x64DC # 0 +0x8EA3D0F6 0x64D1 # 0 +0x8EA3D0F7 0x64C8 # 0 +0x8EA3D0F9 0x64D5 # 0 +0x8EA3D0FA 0x66C3 # 0 +0x8EA3D0FD 0x66BF # 0 +0x8EA3D0FE 0x66C5 # 0 +0x8EA3D1A2 0x66CD # 0 +0x8EA3D1A3 0x66C1 # 0 +0x8EA3D1A4 0x6706 # 0 +0x8EA3D1A6 0x6724 # 0 +0x8EA3D1A7 0x6A63 # 0 +0x8EA3D1A8 0x6A42 # 0 +0x8EA3D1A9 0x6A52 # 0 +0x8EA3D1AB 0x6A43 # 0 +0x8EA3D1AC 0x6A33 # 0 +0x8EA3D1AE 0x6A6C # 0 +0x8EA3D1AF 0x6A57 # 0 +0x8EA3D1B1 0x6A4C # 0 +0x8EA3D1B2 0x6A6E # 0 +0x8EA3D1B8 0x6A37 # 0 +0x8EA3D1BA 0x6A71 # 0 +0x8EA3D1BB 0x6A4A # 0 +0x8EA3D1BC 0x6A36 # 0 +0x8EA3D1BE 0x6A53 # 0 +0x8EA3D1C0 0x6A45 # 0 +0x8EA3D1C1 0x6A70 # 0 +0x8EA3D1C4 0x6A5C # 0 +0x8EA3D1C5 0x6B58 # 0 +0x8EA3D1C6 0x6B57 # 0 +0x8EA3D1CD 0x6FBB # 0 +0x8EA3D1D0 0x6FBE # 0 +0x8EA3D1D4 0x6FB5 # 0 +0x8EA3D1D5 0x6FD3 # 0 +0x8EA3D1D6 0x6F9F # 0 +0x8EA3D1D8 0x6FB7 # 0 +0x8EA3D1D9 0x6FF5 # 0 +0x8EA3D1DA 0x71B7 # 0 +0x8EA3D1DC 0x71BB # 0 +0x8EA3D1DE 0x71D1 # 0 +0x8EA3D1E0 0x71BA # 0 +0x8EA3D1E2 0x71B6 # 0 +0x8EA3D1E3 0x71CC # 0 +0x8EA3D1E6 0x71D3 # 0 +0x8EA3D1E7 0x749B # 0 +0x8EA3D1EA 0x7496 # 0 +0x8EA3D1EB 0x74A2 # 0 +0x8EA3D1EC 0x749D # 0 +0x8EA3D1ED 0x750A # 0 +0x8EA3D1EE 0x750E # 0 +0x8EA3D1F0 0x7581 # 0 +0x8EA3D1F1 0x762C # 0 +0x8EA3D1F2 0x7637 # 0 +0x8EA3D1F3 0x7636 # 0 +0x8EA3D1F4 0x763B # 0 +0x8EA3D1F6 0x76A1 # 0 +0x8EA3D1F9 0x7798 # 0 +0x8EA3D1FB 0x7796 # 0 +0x8EA3D2A1 0x78D6 # 0 +0x8EA3D2A2 0x78EB # 0 +0x8EA3D2A4 0x78DC # 0 +0x8EA3D2A6 0x79A5 # 0 +0x8EA3D2A7 0x79A9 # 0 +0x8EA3D2A8 0x9834 # 0 +0x8EA3D2A9 0x7A53 # 0 +0x8EA3D2AA 0x7A45 # 0 +0x8EA3D2AC 0x7A4F # 0 +0x8EA3D2AE 0x7ABD # 0 +0x8EA3D2AF 0x7ABB # 0 +0x8EA3D2B0 0x7AF1 # 0 +0x8EA3D2B3 0x7BEC # 0 +0x8EA3D2B4 0x7BED # 0 +0x8EA3D2B7 0x7CD3 # 0 +0x8EA3D2B9 0x7CE1 # 0 +0x8EA3D2BB 0x7E19 # 0 +0x8EA3D2BF 0x7E27 # 0 +0x8EA3D2C0 0x7E26 # 0 +0x8EA3D2C3 0x806E # 0 +0x8EA3D2C4 0x81AF # 0 +0x8EA3D2C7 0x81AD # 0 +0x8EA3D2C9 0x81AA # 0 +0x8EA3D2CA 0x8218 # 0 +0x8EA3D2CF 0x856F # 0 +0x8EA3D2D0 0x854C # 0 +0x8EA3D2D2 0x8542 # 0 +0x8EA3D2D4 0x855C # 0 +0x8EA3D2D5 0x8570 # 0 +0x8EA3D2D6 0x855F # 0 +0x8EA3D2D8 0x855A # 0 +0x8EA3D2D9 0x854B # 0 +0x8EA3D2DA 0x853F # 0 +0x8EA3D2DB 0x878A # 0 +0x8EA3D2DD 0x878B # 0 +0x8EA3D2DE 0x87A1 # 0 +0x8EA3D2DF 0x878E # 0 +0x8EA3D2E2 0x8799 # 0 +0x8EA3D2E3 0x885E # 0 +0x8EA3D2E4 0x885F # 0 +0x8EA3D2E5 0x8924 # 0 +0x8EA3D2E6 0x89A7 # 0 +0x8EA3D2E7 0x8AEA # 0 +0x8EA3D2E8 0x8AFD # 0 +0x8EA3D2E9 0x8AF9 # 0 +0x8EA3D2EA 0x8AE3 # 0 +0x8EA3D2EB 0x8AE5 # 0 +0x8EA3D2EE 0x8AEC # 0 +0x8EA3D2F3 0x8CF2 # 0 +0x8EA3D2F5 0x8CEF # 0 +0x8EA3D2F7 0x8DA6 # 0 +0x8EA3D2FB 0x8E3B # 0 +0x8EA3D2FC 0x8E43 # 0 +0x8EA3D2FE 0x8E32 # 0 +0x8EA3D3A1 0x8F31 # 0 +0x8EA3D3A2 0x8F30 # 0 +0x8EA3D3A4 0x8F2D # 0 +0x8EA3D3A5 0x8F3C # 0 +0x8EA3D3A6 0x8FA7 # 0 +0x8EA3D3A7 0x8FA5 # 0 +0x8EA3D3AB 0x9137 # 0 +0x8EA3D3AC 0x9195 # 0 +0x8EA3D3AD 0x918E # 0 +0x8EA3D3AF 0x9196 # 0 +0x8EA3D3B1 0x9345 # 0 +0x8EA3D3B2 0x930A # 0 +0x8EA3D3B5 0x92FD # 0 +0x8EA3D3B6 0x9317 # 0 +0x8EA3D3B7 0x931C # 0 +0x8EA3D3B8 0x9307 # 0 +0x8EA3D3B9 0x9331 # 0 +0x8EA3D3BA 0x9332 # 0 +0x8EA3D3BB 0x932C # 0 +0x8EA3D3BC 0x9330 # 0 +0x8EA3D3BD 0x9303 # 0 +0x8EA3D3BE 0x9305 # 0 +0x8EA3D3C0 0x95C2 # 0 +0x8EA3D3C2 0x95B8 # 0 +0x8EA3D3C4 0x95C1 # 0 +0x8EA3D3C8 0x96AB # 0 +0x8EA3D3C9 0x96B7 # 0 +0x8EA3D3CC 0x9715 # 0 +0x8EA3D3CD 0x9714 # 0 +0x8EA3D3D0 0x970C # 0 +0x8EA3D3D1 0x9717 # 0 +0x8EA3D3D3 0x9793 # 0 +0x8EA3D3D5 0x97D2 # 0 +0x8EA3D3D8 0x9836 # 0 +0x8EA3D3D9 0x9831 # 0 +0x8EA3D3DA 0x9833 # 0 +0x8EA3D3DB 0x983C # 0 +0x8EA3D3DC 0x982E # 0 +0x8EA3D3DD 0x983A # 0 +0x8EA3D3DF 0x983D # 0 +0x8EA3D3E1 0x98B5 # 0 +0x8EA3D3E2 0x9922 # 0 +0x8EA3D3E3 0x9923 # 0 +0x8EA3D3E4 0x9920 # 0 +0x8EA3D3E5 0x991C # 0 +0x8EA3D3E6 0x991D # 0 +0x8EA3D3E8 0x99A0 # 0 +0x8EA3D3EA 0x99EF # 0 +0x8EA3D3EB 0x99E8 # 0 +0x8EA3D3EC 0x99EB # 0 +0x8EA3D3F0 0x99E1 # 0 +0x8EA3D3F1 0x99E6 # 0 +0x8EA3D3F4 0x9AF8 # 0 +0x8EA3D3F5 0x9AF5 # 0 +0x8EA3D3F8 0x9B83 # 0 +0x8EA3D3F9 0x9B94 # 0 +0x8EA3D3FA 0x9B84 # 0 +0x8EA3D3FC 0x9B8B # 0 +0x8EA3D3FD 0x9B8F # 0 +0x8EA3D4A1 0x9B8C # 0 +0x8EA3D4A3 0x9B89 # 0 +0x8EA3D4A5 0x9B8E # 0 +0x8EA3D4A9 0x9D24 # 0 +0x8EA3D4AA 0x9D0F # 0 +0x8EA3D4AC 0x9D13 # 0 +0x8EA3D4AD 0x9D0A # 0 +0x8EA3D4B2 0x9D2A # 0 +0x8EA3D4B3 0x9D1A # 0 +0x8EA3D4B5 0x9D27 # 0 +0x8EA3D4B6 0x9D16 # 0 +0x8EA3D4B7 0x9D21 # 0 +0x8EA3D4B9 0x9E85 # 0 +0x8EA3D4BA 0x9EAC # 0 +0x8EA3D4BB 0x9EC6 # 0 +0x8EA3D4BC 0x9EC5 # 0 +0x8EA3D4BD 0x9ED7 # 0 +0x8EA3D4BE 0x9F53 # 0 +0x8EA3D4C0 0x5128 # 0 +0x8EA3D4C1 0x5127 # 0 +0x8EA3D4C2 0x51DF # 0 +0x8EA3D4C4 0x5335 # 0 +0x8EA3D4C5 0x53B3 # 0 +0x8EA3D4C7 0x568A # 0 +0x8EA3D4C8 0x567D # 0 +0x8EA3D4C9 0x5689 # 0 +0x8EA3D4CB 0x58CD # 0 +0x8EA3D4CC 0x58D0 # 0 +0x8EA3D4CE 0x5B2B # 0 +0x8EA3D4CF 0x5B33 # 0 +0x8EA3D4D0 0x5B29 # 0 +0x8EA3D4D1 0x5B35 # 0 +0x8EA3D4D2 0x5B31 # 0 +0x8EA3D4D3 0x5B37 # 0 +0x8EA3D4D4 0x5C36 # 0 +0x8EA3D4D5 0x5DBE # 0 +0x8EA3D4D7 0x5DB9 # 0 +0x8EA3D4D9 0x5DBB # 0 +0x8EA3D4DB 0x61E2 # 0 +0x8EA3D4DC 0x61DB # 0 +0x8EA3D4DD 0x61DD # 0 +0x8EA3D4DE 0x61DC # 0 +0x8EA3D4DF 0x61DA # 0 +0x8EA3D4E1 0x61D9 # 0 +0x8EA3D4E4 0x64DF # 0 +0x8EA3D4E7 0x64E1 # 0 +0x8EA3D4E9 0x64EE # 0 +0x8EA3D4EB 0x65B5 # 0 +0x8EA3D4EC 0x66D4 # 0 +0x8EA3D4ED 0x66D5 # 0 +0x8EA3D4EF 0x66D0 # 0 +0x8EA3D4F0 0x66D1 # 0 +0x8EA3D4F1 0x66CE # 0 +0x8EA3D4F2 0x66D7 # 0 +0x8EA3D4F5 0x6A7D # 0 +0x8EA3D4F6 0x6A8A # 0 +0x8EA3D4F8 0x6AA7 # 0 +0x8EA3D4FA 0x6A99 # 0 +0x8EA3D4FB 0x6A82 # 0 +0x8EA3D4FC 0x6A88 # 0 +0x8EA3D5A1 0x6A86 # 0 +0x8EA3D5A3 0x6A98 # 0 +0x8EA3D5A4 0x6A9D # 0 +0x8EA3D5A7 0x6A8F # 0 +0x8EA3D5A9 0x6AAA # 0 +0x8EA3D5AB 0x6B5D # 0 +0x8EA3D5AD 0x6C0A # 0 +0x8EA3D5AF 0x6FD7 # 0 +0x8EA3D5B0 0x6FD6 # 0 +0x8EA3D5B1 0x6FE5 # 0 +0x8EA3D5B5 0x6FD9 # 0 +0x8EA3D5B6 0x6FDA # 0 +0x8EA3D5B7 0x6FEA # 0 +0x8EA3D5B9 0x6FF6 # 0 +0x8EA3D5BC 0x71E3 # 0 +0x8EA3D5BE 0x71E9 # 0 +0x8EA3D5C0 0x71EB # 0 +0x8EA3D5C1 0x71EF # 0 +0x8EA3D5C2 0x71F3 # 0 +0x8EA3D5C3 0x71EA # 0 +0x8EA3D5C9 0x7371 # 0 +0x8EA3D5CB 0x74AE # 0 +0x8EA3D5CD 0x74B3 # 0 +0x8EA3D5CF 0x74AC # 0 +0x8EA3D5D2 0x7583 # 0 +0x8EA3D5D3 0x7645 # 0 +0x8EA3D5D4 0x764E # 0 +0x8EA3D5D5 0x7644 # 0 +0x8EA3D5D6 0x76A3 # 0 +0x8EA3D5D7 0x76A5 # 0 +0x8EA3D5D8 0x77A6 # 0 +0x8EA3D5D9 0x77A4 # 0 +0x8EA3D5DB 0x77A9 # 0 +0x8EA3D5DC 0x77AF # 0 +0x8EA3D5E0 0x78F0 # 0 +0x8EA3D5E1 0x78F8 # 0 +0x8EA3D5E2 0x78F1 # 0 +0x8EA3D5E4 0x7A49 # 0 +0x8EA3D5E8 0x7AC2 # 0 +0x8EA3D5E9 0x7AF2 # 0 +0x8EA3D5EA 0x7AF3 # 0 +0x8EA3D5EB 0x7BFA # 0 +0x8EA3D5ED 0x7BF6 # 0 +0x8EA3D5EE 0x7BFC # 0 +0x8EA3D5EF 0x7C18 # 0 +0x8EA3D5F0 0x7C08 # 0 +0x8EA3D5F1 0x7C12 # 0 +0x8EA3D5F4 0x7CDB # 0 +0x8EA3D5F5 0x7CDA # 0 +0x8EA3D5F9 0x7E2C # 0 +0x8EA3D5FA 0x7E4D # 0 +0x8EA3D5FD 0x7F46 # 0 +0x8EA3D5FE 0x7FF6 # 0 +0x8EA3D6A1 0x802B # 0 +0x8EA3D6A2 0x8074 # 0 +0x8EA3D6A3 0x81B8 # 0 +0x8EA3D6A4 0x81C8 # 0 +0x8EA3D6A8 0x8592 # 0 +0x8EA3D6A9 0x8593 # 0 +0x8EA3D6AB 0x857F # 0 +0x8EA3D6AC 0x85AB # 0 +0x8EA3D6AD 0x8597 # 0 +0x8EA3D6B0 0x85AC # 0 +0x8EA3D6B4 0x87CE # 0 +0x8EA3D6B6 0x87CD # 0 +0x8EA3D6B9 0x87C1 # 0 +0x8EA3D6BA 0x87B1 # 0 +0x8EA3D6BB 0x87C7 # 0 +0x8EA3D6BD 0x8940 # 0 +0x8EA3D6BF 0x893F # 0 +0x8EA3D6C0 0x8939 # 0 +0x8EA3D6C2 0x8943 # 0 +0x8EA3D6C6 0x89AB # 0 +0x8EA3D6C8 0x8B1F # 0 +0x8EA3D6C9 0x8B09 # 0 +0x8EA3D6CA 0x8B0C # 0 +0x8EA3D6CD 0x8C40 # 0 +0x8EA3D6CF 0x8C96 # 0 +0x8EA3D6D1 0x8CF6 # 0 +0x8EA3D6D2 0x8CF7 # 0 +0x8EA3D6D4 0x8E46 # 0 +0x8EA3D6D5 0x8E4F # 0 +0x8EA3D6D9 0x8F3D # 0 +0x8EA3D6DA 0x8F41 # 0 +0x8EA3D6DB 0x9366 # 0 +0x8EA3D6DC 0x9378 # 0 +0x8EA3D6DD 0x935D # 0 +0x8EA3D6DE 0x9369 # 0 +0x8EA3D6DF 0x9374 # 0 +0x8EA3D6E0 0x937D # 0 +0x8EA3D6E1 0x936E # 0 +0x8EA3D6E2 0x9372 # 0 +0x8EA3D6E3 0x9373 # 0 +0x8EA3D6E4 0x9362 # 0 +0x8EA3D6E5 0x9348 # 0 +0x8EA3D6E6 0x9353 # 0 +0x8EA3D6E7 0x935F # 0 +0x8EA3D6E8 0x9368 # 0 +0x8EA3D6EA 0x937F # 0 +0x8EA3D6EB 0x936B # 0 +0x8EA3D6ED 0x95C4 # 0 +0x8EA3D6EF 0x96AF # 0 +0x8EA3D6F0 0x96AD # 0 +0x8EA3D6F1 0x96B2 # 0 +0x8EA3D6F4 0x971A # 0 +0x8EA3D6F5 0x971B # 0 +0x8EA3D6FA 0x979B # 0 +0x8EA3D6FB 0x979F # 0 +0x8EA3D7A6 0x9840 # 0 +0x8EA3D7A8 0x9847 # 0 +0x8EA3D7AA 0x98B7 # 0 +0x8EA3D7B0 0x99A2 # 0 +0x8EA3D7B3 0x9A00 # 0 +0x8EA3D7B4 0x99F3 # 0 +0x8EA3D7B7 0x99F5 # 0 +0x8EA3D7BA 0x9ABD # 0 +0x8EA3D7BB 0x9B00 # 0 +0x8EA3D7BC 0x9B02 # 0 +0x8EA3D7BE 0x9B34 # 0 +0x8EA3D7BF 0x9B49 # 0 +0x8EA3D7C0 0x9B9F # 0 +0x8EA3D7C2 0x9BA3 # 0 +0x8EA3D7C3 0x9BCD # 0 +0x8EA3D7C4 0x9B99 # 0 +0x8EA3D7C5 0x9B9D # 0 +0x8EA3D7C8 0x9D39 # 0 +0x8EA3D7CA 0x9D44 # 0 +0x8EA3D7CD 0x9D35 # 0 +0x8EA3D7D0 0x9EAF # 0 +0x8EA3D7D2 0x512F # 0 +0x8EA3D7D5 0x9F8E # 0 +0x8EA3D7D7 0x569F # 0 +0x8EA3D7D8 0x569B # 0 +0x8EA3D7D9 0x569E # 0 +0x8EA3D7DA 0x5696 # 0 +0x8EA3D7DB 0x5694 # 0 +0x8EA3D7DC 0x56A0 # 0 +0x8EA3D7DE 0x5B3B # 0 +0x8EA3D7E1 0x5B3A # 0 +0x8EA3D7E2 0x5DC1 # 0 +0x8EA3D7E3 0x5F4D # 0 +0x8EA3D7E4 0x5F5D # 0 +0x8EA3D7E5 0x61F3 # 0 +0x8EA3D7EA 0x64F6 # 0 +0x8EA3D7EB 0x64E5 # 0 +0x8EA3D7EC 0x64EA # 0 +0x8EA3D7ED 0x64E7 # 0 +0x8EA3D7EE 0x6505 # 0 +0x8EA3D7F0 0x64F9 # 0 +0x8EA3D7F4 0x6AAB # 0 +0x8EA3D7F5 0x6AED # 0 +0x8EA3D7F6 0x6AB2 # 0 +0x8EA3D7F7 0x6AB0 # 0 +0x8EA3D7F8 0x6AB5 # 0 +0x8EA3D7F9 0x6ABE # 0 +0x8EA3D7FA 0x6AC1 # 0 +0x8EA3D7FB 0x6AC8 # 0 +0x8EA3D7FD 0x6AC0 # 0 +0x8EA3D7FE 0x6ABC # 0 +0x8EA3D8A1 0x6AB1 # 0 +0x8EA3D8A2 0x6AC4 # 0 +0x8EA3D8A3 0x6ABF # 0 +0x8EA3D8A6 0x7008 # 0 +0x8EA3D8A7 0x7003 # 0 +0x8EA3D8A8 0x6FFD # 0 +0x8EA3D8A9 0x7010 # 0 +0x8EA3D8AA 0x7002 # 0 +0x8EA3D8AB 0x7013 # 0 +0x8EA3D8AD 0x71FA # 0 +0x8EA3D8AE 0x7200 # 0 +0x8EA3D8AF 0x74B9 # 0 +0x8EA3D8B0 0x74BC # 0 +0x8EA3D8B2 0x765B # 0 +0x8EA3D8B3 0x7651 # 0 +0x8EA3D8B4 0x764F # 0 +0x8EA3D8B5 0x76EB # 0 +0x8EA3D8B6 0x77B8 # 0 +0x8EA3D8B8 0x77B9 # 0 +0x8EA3D8B9 0x77C1 # 0 +0x8EA3D8BA 0x77C0 # 0 +0x8EA3D8BB 0x77BE # 0 +0x8EA3D8BC 0x790B # 0 +0x8EA3D8BE 0x7907 # 0 +0x8EA3D8BF 0x790A # 0 +0x8EA3D8C0 0x7908 # 0 +0x8EA3D8C2 0x790D # 0 +0x8EA3D8C3 0x7906 # 0 +0x8EA3D8C4 0x7915 # 0 +0x8EA3D8C5 0x79AF # 0 +0x8EA3D8C9 0x7AF5 # 0 +0x8EA3D8CC 0x7C2E # 0 +0x8EA3D8CE 0x7C1B # 0 +0x8EA3D8D0 0x7C1A # 0 +0x8EA3D8D1 0x7C24 # 0 +0x8EA3D8D4 0x7CE6 # 0 +0x8EA3D8D5 0x7CE3 # 0 +0x8EA3D8D8 0x7E5D # 0 +0x8EA3D8D9 0x7E4F # 0 +0x8EA3D8DA 0x7E66 # 0 +0x8EA3D8DB 0x7E5B # 0 +0x8EA3D8DC 0x7F47 # 0 +0x8EA3D8DD 0x7FB4 # 0 +0x8EA3D8E1 0x7FFA # 0 +0x8EA3D8E2 0x802E # 0 +0x8EA3D8E5 0x81CE # 0 +0x8EA3D8E8 0x8219 # 0 +0x8EA3D8EB 0x85CC # 0 +0x8EA3D8EC 0x85B2 # 0 +0x8EA3D8EE 0x85BB # 0 +0x8EA3D8EF 0x85C1 # 0 +0x8EA3D8F3 0x87E9 # 0 +0x8EA3D8F4 0x87EE # 0 +0x8EA3D8F5 0x87F0 # 0 +0x8EA3D8F6 0x87D6 # 0 +0x8EA3D8F7 0x880E # 0 +0x8EA3D8F8 0x87DA # 0 +0x8EA3D8F9 0x8948 # 0 +0x8EA3D8FA 0x894A # 0 +0x8EA3D8FB 0x894E # 0 +0x8EA3D8FC 0x894D # 0 +0x8EA3D8FD 0x89B1 # 0 +0x8EA3D8FE 0x89B0 # 0 +0x8EA3D9A1 0x89B3 # 0 +0x8EA3D9A3 0x8B38 # 0 +0x8EA3D9A4 0x8B32 # 0 +0x8EA3D9A6 0x8B2D # 0 +0x8EA3D9A8 0x8B34 # 0 +0x8EA3D9AA 0x8B29 # 0 +0x8EA3D9AB 0x8C74 # 0 +0x8EA3D9AE 0x8D03 # 0 +0x8EA3D9B1 0x8DA9 # 0 +0x8EA3D9B2 0x8E58 # 0 +0x8EA3D9B5 0x8EBF # 0 +0x8EA3D9B6 0x8EC1 # 0 +0x8EA3D9B7 0x8F4A # 0 +0x8EA3D9B8 0x8FAC # 0 +0x8EA3D9BA 0x9089 # 0 +0x8EA3D9BB 0x913D # 0 +0x8EA3D9BC 0x913C # 0 +0x8EA3D9BD 0x91A9 # 0 +0x8EA3D9BE 0x93A0 # 0 +0x8EA3D9C0 0x9390 # 0 +0x8EA3D9C2 0x9393 # 0 +0x8EA3D9C3 0x938B # 0 +0x8EA3D9C4 0x93AD # 0 +0x8EA3D9C5 0x93BB # 0 +0x8EA3D9C6 0x93B8 # 0 +0x8EA3D9C9 0x939C # 0 +0x8EA3D9CA 0x95D8 # 0 +0x8EA3D9CB 0x95D7 # 0 +0x8EA3D9CF 0x975D # 0 +0x8EA3D9D0 0x97A9 # 0 +0x8EA3D9D1 0x97DA # 0 +0x8EA3D9D6 0x9854 # 0 +0x8EA3D9D8 0x9855 # 0 +0x8EA3D9D9 0x984B # 0 +0x8EA3D9DB 0x983F # 0 +0x8EA3D9DC 0x98B9 # 0 +0x8EA3D9E1 0x9938 # 0 +0x8EA3D9E2 0x9936 # 0 +0x8EA3D9E3 0x9940 # 0 +0x8EA3D9E5 0x993B # 0 +0x8EA3D9E6 0x9939 # 0 +0x8EA3D9E7 0x99A4 # 0 +0x8EA3D9EA 0x9A08 # 0 +0x8EA3D9EB 0x9A0C # 0 +0x8EA3D9ED 0x9A10 # 0 +0x8EA3D9EF 0x9B07 # 0 +0x8EA3D9F1 0x9BD2 # 0 +0x8EA3D9F3 0x9BC2 # 0 +0x8EA3D9F4 0x9BBB # 0 +0x8EA3D9F5 0x9BCC # 0 +0x8EA3D9F6 0x9BCB # 0 +0x8EA3D9F9 0x9D4D # 0 +0x8EA3D9FA 0x9D63 # 0 +0x8EA3D9FB 0x9D4E # 0 +0x8EA3D9FD 0x9D50 # 0 +0x8EA3D9FE 0x9D55 # 0 +0x8EA3DAA2 0x9D5E # 0 +0x8EA3DAA4 0x9E90 # 0 +0x8EA3DAA5 0x9EB2 # 0 +0x8EA3DAA6 0x9EB1 # 0 +0x8EA3DAA8 0x9ECA # 0 +0x8EA3DAA9 0x9F02 # 0 +0x8EA3DAAA 0x9F27 # 0 +0x8EA3DAAB 0x9F26 # 0 +0x8EA3DAAD 0x56AF # 0 +0x8EA3DAAE 0x58E0 # 0 +0x8EA3DAAF 0x58DC # 0 +0x8EA3DAB1 0x5B39 # 0 +0x8EA3DAB4 0x5B7C # 0 +0x8EA3DAB5 0x5BF3 # 0 +0x8EA3DAB8 0x5C6B # 0 +0x8EA3DAB9 0x5DC4 # 0 +0x8EA3DABA 0x650B # 0 +0x8EA3DABB 0x6508 # 0 +0x8EA3DABC 0x650A # 0 +0x8EA3DABF 0x65DC # 0 +0x8EA3DAC2 0x66E1 # 0 +0x8EA3DAC3 0x66DF # 0 +0x8EA3DAC4 0x6ACE # 0 +0x8EA3DAC5 0x6AD4 # 0 +0x8EA3DAC6 0x6AE3 # 0 +0x8EA3DAC7 0x6AD7 # 0 +0x8EA3DAC8 0x6AE2 # 0 +0x8EA3DACD 0x6AD8 # 0 +0x8EA3DACE 0x6AD5 # 0 +0x8EA3DACF 0x6AD2 # 0 +0x8EA3DAD2 0x701E # 0 +0x8EA3DAD3 0x702C # 0 +0x8EA3DAD4 0x7025 # 0 +0x8EA3DAD5 0x6FF3 # 0 +0x8EA3DAD6 0x7204 # 0 +0x8EA3DAD7 0x7208 # 0 +0x8EA3DAD8 0x7215 # 0 +0x8EA3DADA 0x74C4 # 0 +0x8EA3DADB 0x74C9 # 0 +0x8EA3DADC 0x74C7 # 0 +0x8EA3DADD 0x74C8 # 0 +0x8EA3DADE 0x76A9 # 0 +0x8EA3DADF 0x77C6 # 0 +0x8EA3DAE0 0x77C5 # 0 +0x8EA3DAE1 0x7918 # 0 +0x8EA3DAE2 0x791A # 0 +0x8EA3DAE3 0x7920 # 0 +0x8EA3DAE5 0x7A66 # 0 +0x8EA3DAE6 0x7A64 # 0 +0x8EA3DAE7 0x7A6A # 0 +0x8EA3DAEE 0x7C35 # 0 +0x8EA3DAEF 0x7C34 # 0 +0x8EA3DAF2 0x7E6C # 0 +0x8EA3DAF4 0x7E6E # 0 +0x8EA3DAF5 0x7E71 # 0 +0x8EA3DAF7 0x81D4 # 0 +0x8EA3DAF8 0x81D6 # 0 +0x8EA3DAF9 0x821A # 0 +0x8EA3DAFA 0x8262 # 0 +0x8EA3DAFB 0x8265 # 0 +0x8EA3DAFC 0x8276 # 0 +0x8EA3DAFD 0x85DB # 0 +0x8EA3DAFE 0x85D6 # 0 +0x8EA3DBA2 0x85E7 # 0 +0x8EA3DBA5 0x85F4 # 0 +0x8EA3DBA7 0x87FD # 0 +0x8EA3DBA8 0x87D5 # 0 +0x8EA3DBA9 0x8807 # 0 +0x8EA3DBAB 0x880F # 0 +0x8EA3DBAC 0x87F8 # 0 +0x8EA3DBAF 0x8987 # 0 +0x8EA3DBB1 0x89B5 # 0 +0x8EA3DBB2 0x89F5 # 0 +0x8EA3DBB4 0x8B3F # 0 +0x8EA3DBB5 0x8B43 # 0 +0x8EA3DBB6 0x8B4C # 0 +0x8EA3DBB8 0x8D0B # 0 +0x8EA3DBB9 0x8E6B # 0 +0x8EA3DBBA 0x8E68 # 0 +0x8EA3DBBB 0x8E70 # 0 +0x8EA3DBBC 0x8E75 # 0 +0x8EA3DBBD 0x8E77 # 0 +0x8EA3DBBF 0x8EC3 # 0 +0x8EA3DBC1 0x93E9 # 0 +0x8EA3DBC2 0x93EA # 0 +0x8EA3DBC3 0x93CB # 0 +0x8EA3DBC4 0x93C5 # 0 +0x8EA3DBC5 0x93C6 # 0 +0x8EA3DBC7 0x93ED # 0 +0x8EA3DBC8 0x93D3 # 0 +0x8EA3DBCA 0x93E5 # 0 +0x8EA3DBCD 0x93DB # 0 +0x8EA3DBCE 0x93EB # 0 +0x8EA3DBCF 0x93E0 # 0 +0x8EA3DBD0 0x93C1 # 0 +0x8EA3DBD3 0x95DD # 0 +0x8EA3DBDD 0x97B2 # 0 +0x8EA3DBDE 0x97B4 # 0 +0x8EA3DBDF 0x97B1 # 0 +0x8EA3DBE0 0x97B5 # 0 +0x8EA3DBE1 0x97F2 # 0 +0x8EA3DBE5 0x9856 # 0 +0x8EA3DBE9 0x9944 # 0 +0x8EA3DBEB 0x9A26 # 0 +0x8EA3DBEC 0x9A1F # 0 +0x8EA3DBED 0x9A18 # 0 +0x8EA3DBEE 0x9A21 # 0 +0x8EA3DBEF 0x9A17 # 0 +0x8EA3DBF1 0x9B09 # 0 +0x8EA3DBF4 0x9BC5 # 0 +0x8EA3DBF5 0x9BDF # 0 +0x8EA3DBF7 0x9BE3 # 0 +0x8EA3DBF9 0x9BE9 # 0 +0x8EA3DBFA 0x9BEE # 0 +0x8EA3DBFD 0x9D66 # 0 +0x8EA3DBFE 0x9D7A # 0 +0x8EA3DCA2 0x9D6E # 0 +0x8EA3DCA3 0x9D91 # 0 +0x8EA3DCA4 0x9D83 # 0 +0x8EA3DCA5 0x9D76 # 0 +0x8EA3DCA6 0x9D7E # 0 +0x8EA3DCA7 0x9D6D # 0 +0x8EA3DCA9 0x9E95 # 0 +0x8EA3DCAA 0x9EE3 # 0 +0x8EA3DCAD 0x9F03 # 0 +0x8EA3DCAE 0x9F04 # 0 +0x8EA3DCB0 0x9F17 # 0 +0x8EA3DCB2 0x5136 # 0 +0x8EA3DCB4 0x5336 # 0 +0x8EA3DCB6 0x5B42 # 0 +0x8EA3DCB9 0x5B44 # 0 +0x8EA3DCBA 0x5B46 # 0 +0x8EA3DCBB 0x5B7E # 0 +0x8EA3DCBC 0x5DCA # 0 +0x8EA3DCBD 0x5DC8 # 0 +0x8EA3DCBE 0x5DCC # 0 +0x8EA3DCBF 0x5EF0 # 0 +0x8EA3DCC1 0x6585 # 0 +0x8EA3DCC2 0x66E5 # 0 +0x8EA3DCC3 0x66E7 # 0 +0x8EA3DCC7 0x6AF4 # 0 +0x8EA3DCC9 0x6AE9 # 0 +0x8EA3DCCF 0x703D # 0 +0x8EA3DCD1 0x7036 # 0 +0x8EA3DCD3 0x7216 # 0 +0x8EA3DCD5 0x7212 # 0 +0x8EA3DCD6 0x720F # 0 +0x8EA3DCD7 0x7217 # 0 +0x8EA3DCD8 0x7211 # 0 +0x8EA3DCD9 0x720B # 0 +0x8EA3DCDC 0x74CD # 0 +0x8EA3DCDD 0x74D0 # 0 +0x8EA3DCDE 0x74CC # 0 +0x8EA3DCDF 0x74CE # 0 +0x8EA3DCE0 0x74D1 # 0 +0x8EA3DCE2 0x7589 # 0 +0x8EA3DCE4 0x7A6F # 0 +0x8EA3DCE5 0x7C4B # 0 +0x8EA3DCE6 0x7C44 # 0 +0x8EA3DCEC 0x7E7F # 0 +0x8EA3DCED 0x8B71 # 0 +0x8EA3DCEF 0x802F # 0 +0x8EA3DCF0 0x807A # 0 +0x8EA3DCF1 0x807B # 0 +0x8EA3DCF2 0x807C # 0 +0x8EA3DCF6 0x85FC # 0 +0x8EA3DCF7 0x8610 # 0 +0x8EA3DCF8 0x8602 # 0 +0x8EA3DCFB 0x85EE # 0 +0x8EA3DCFC 0x8603 # 0 +0x8EA3DCFE 0x860D # 0 +0x8EA3DDA1 0x8613 # 0 +0x8EA3DDA2 0x8608 # 0 +0x8EA3DDA3 0x860F # 0 +0x8EA3DDA4 0x8818 # 0 +0x8EA3DDA5 0x8812 # 0 +0x8EA3DDA8 0x8967 # 0 +0x8EA3DDA9 0x8965 # 0 +0x8EA3DDAA 0x89BB # 0 +0x8EA3DDAB 0x8B69 # 0 +0x8EA3DDAC 0x8B62 # 0 +0x8EA3DDAE 0x8B6E # 0 +0x8EA3DDB0 0x8B61 # 0 +0x8EA3DDB2 0x8B64 # 0 +0x8EA3DDB3 0x8B4D # 0 +0x8EA3DDB4 0x8C51 # 0 +0x8EA3DDB7 0x8E83 # 0 +0x8EA3DDB8 0x8EC6 # 0 +0x8EA3DDBA 0x941F # 0 +0x8EA3DDBC 0x9404 # 0 +0x8EA3DDBD 0x9417 # 0 +0x8EA3DDBE 0x9408 # 0 +0x8EA3DDBF 0x9405 # 0 +0x8EA3DDC1 0x93F3 # 0 +0x8EA3DDC2 0x941E # 0 +0x8EA3DDC3 0x9402 # 0 +0x8EA3DDC4 0x941A # 0 +0x8EA3DDC5 0x941B # 0 +0x8EA3DDC6 0x9427 # 0 +0x8EA3DDC7 0x941C # 0 +0x8EA3DDC9 0x96B5 # 0 +0x8EA3DDCC 0x9733 # 0 +0x8EA3DDCE 0x9734 # 0 +0x8EA3DDCF 0x9731 # 0 +0x8EA3DDD0 0x97B8 # 0 +0x8EA3DDD1 0x97BA # 0 +0x8EA3DDD3 0x97FC # 0 +0x8EA3DDD6 0x98C3 # 0 +0x8EA3DDD8 0x994D # 0 +0x8EA3DDDA 0x9A2F # 0 +0x8EA3DDDE 0x9AC9 # 0 +0x8EA3DDE0 0x9AC8 # 0 +0x8EA3DDE1 0x9AC4 # 0 +0x8EA3DDE2 0x9B2A # 0 +0x8EA3DDE3 0x9B38 # 0 +0x8EA3DDE4 0x9B50 # 0 +0x8EA3DDE6 0x9C0A # 0 +0x8EA3DDE7 0x9BFB # 0 +0x8EA3DDE8 0x9C04 # 0 +0x8EA3DDE9 0x9BFC # 0 +0x8EA3DDEA 0x9BFE # 0 +0x8EA3DDEE 0x9C02 # 0 +0x8EA3DDEF 0x9BF6 # 0 +0x8EA3DDF0 0x9C1B # 0 +0x8EA3DDF1 0x9BF9 # 0 +0x8EA3DDF2 0x9C15 # 0 +0x8EA3DDF3 0x9C10 # 0 +0x8EA3DDF4 0x9BFF # 0 +0x8EA3DDF5 0x9C00 # 0 +0x8EA3DDF6 0x9C0C # 0 +0x8EA3DDF9 0x9D95 # 0 +0x8EA3DDFA 0x9DA5 # 0 +0x8EA3DEA1 0x9E98 # 0 +0x8EA3DEA2 0x9EC1 # 0 +0x8EA3DEA4 0x9F5A # 0 +0x8EA3DEA5 0x5164 # 0 +0x8EA3DEA6 0x56BB # 0 +0x8EA3DEA8 0x58E6 # 0 +0x8EA3DEA9 0x5B49 # 0 +0x8EA3DEAA 0x5BF7 # 0 +0x8EA3DEAD 0x5DD0 # 0 +0x8EA3DEAF 0x5FC2 # 0 +0x8EA3DEB1 0x6511 # 0 +0x8EA3DEB3 0x6AFF # 0 +0x8EA3DEB4 0x6AFE # 0 +0x8EA3DEB5 0x6AFD # 0 +0x8EA3DEB7 0x6B01 # 0 +0x8EA3DEBA 0x704B # 0 +0x8EA3DEBB 0x704D # 0 +0x8EA3DEBC 0x7047 # 0 +0x8EA3DEBD 0x74D3 # 0 +0x8EA3DEBE 0x7668 # 0 +0x8EA3DEBF 0x7667 # 0 +0x8EA3DEC2 0x77D1 # 0 +0x8EA3DEC3 0x7930 # 0 +0x8EA3DEC4 0x7932 # 0 +0x8EA3DEC5 0x792E # 0 +0x8EA3DEC7 0x9F9D # 0 +0x8EA3DEC8 0x7AC9 # 0 +0x8EA3DEC9 0x7AC8 # 0 +0x8EA3DECB 0x7C56 # 0 +0x8EA3DECC 0x7C51 # 0 +0x8EA3DED0 0x7E85 # 0 +0x8EA3DED1 0x7E89 # 0 +0x8EA3DED2 0x7E8E # 0 +0x8EA3DED3 0x7E84 # 0 +0x8EA3DED5 0x826A # 0 +0x8EA3DED6 0x862B # 0 +0x8EA3DED7 0x862F # 0 +0x8EA3DED8 0x8628 # 0 +0x8EA3DEDA 0x8616 # 0 +0x8EA3DEDB 0x8615 # 0 +0x8EA3DEDC 0x861D # 0 +0x8EA3DEDD 0x881A # 0 +0x8EA3DEE1 0x89BC # 0 +0x8EA3DEE2 0x8B75 # 0 +0x8EA3DEE3 0x8B7C # 0 +0x8EA3DEE5 0x8D11 # 0 +0x8EA3DEE6 0x8D12 # 0 +0x8EA3DEE7 0x8F5C # 0 +0x8EA3DEE8 0x91BB # 0 +0x8EA3DEEA 0x93F4 # 0 +0x8EA3DEED 0x942D # 0 +0x8EA3DEF0 0x96E4 # 0 +0x8EA3DEF1 0x9737 # 0 +0x8EA3DEF2 0x9736 # 0 +0x8EA3DEF3 0x9767 # 0 +0x8EA3DEF4 0x97BE # 0 +0x8EA3DEF5 0x97BD # 0 +0x8EA3DEF6 0x97E2 # 0 +0x8EA3DEF7 0x9868 # 0 +0x8EA3DEF8 0x9866 # 0 +0x8EA3DEF9 0x98C8 # 0 +0x8EA3DEFA 0x98CA # 0 +0x8EA3DEFB 0x98C7 # 0 +0x8EA3DEFC 0x98DC # 0 +0x8EA3DEFE 0x994F # 0 +0x8EA3DFA1 0x99A9 # 0 +0x8EA3DFA2 0x9A3C # 0 +0x8EA3DFA4 0x9A3B # 0 +0x8EA3DFA5 0x9ACE # 0 +0x8EA3DFA7 0x9B14 # 0 +0x8EA3DFA8 0x9B53 # 0 +0x8EA3DFAA 0x9C2E # 0 +0x8EA3DFAC 0x9C1F # 0 +0x8EA3DFB1 0x9DB0 # 0 +0x8EA3DFB2 0x9DBD # 0 +0x8EA3DFB5 0x9DAE # 0 +0x8EA3DFB6 0x9DC4 # 0 +0x8EA3DFB7 0x9E7B # 0 +0x8EA3DFBA 0x9E9E # 0 +0x8EA3DFBC 0x9F05 # 0 +0x8EA3DFBE 0x9F69 # 0 +0x8EA3DFBF 0x9FA1 # 0 +0x8EA3DFC0 0x56C7 # 0 +0x8EA3DFC1 0x571D # 0 +0x8EA3DFC2 0x5B4A # 0 +0x8EA3DFC3 0x5DD3 # 0 +0x8EA3DFC5 0x5F72 # 0 +0x8EA3DFC6 0x6202 # 0 +0x8EA3DFC8 0x6235 # 0 +0x8EA3DFC9 0x6527 # 0 +0x8EA3DFCA 0x651E # 0 +0x8EA3DFCB 0x651F # 0 +0x8EA3DFCE 0x6B07 # 0 +0x8EA3DFCF 0x6B06 # 0 +0x8EA3DFD2 0x7054 # 0 +0x8EA3DFD3 0x721C # 0 +0x8EA3DFD4 0x7220 # 0 +0x8EA3DFD5 0x7AF8 # 0 +0x8EA3DFD7 0x7C5D # 0 +0x8EA3DFD8 0x7C58 # 0 +0x8EA3DFDA 0x7E92 # 0 +0x8EA3DFDB 0x7F4E # 0 +0x8EA3DFDF 0x8827 # 0 +0x8EA3DFE1 0x8B81 # 0 +0x8EA3DFE2 0x8B83 # 0 +0x8EA3DFE4 0x8C44 # 0 +0x8EA3DFE9 0x9442 # 0 +0x8EA3DFEA 0x944D # 0 +0x8EA3DFEB 0x9454 # 0 +0x8EA3DFEC 0x944E # 0 +0x8EA3DFEE 0x9443 # 0 +0x8EA3DFF1 0x973C # 0 +0x8EA3DFF2 0x9740 # 0 +0x8EA3DFF3 0x97C0 # 0 +0x8EA3DFF8 0x995A # 0 +0x8EA3DFF9 0x9A51 # 0 +0x8EA3DFFB 0x9ADD # 0 +0x8EA3DFFE 0x9C38 # 0 +0x8EA3E0A2 0x9C45 # 0 +0x8EA3E0A3 0x9C3A # 0 +0x8EA3E0A5 0x9C35 # 0 +0x8EA3E0A9 0x9EF1 # 0 +0x8EA3E0AB 0x9F93 # 0 +0x8EA3E0AC 0x529A # 0 +0x8EA3E0AF 0x8641 # 0 +0x8EA3E0B0 0x5DD7 # 0 +0x8EA3E0B2 0x6528 # 0 +0x8EA3E0B6 0x7053 # 0 +0x8EA3E0B7 0x7059 # 0 +0x8EA3E0B9 0x7221 # 0 +0x8EA3E0BB 0x766F # 0 +0x8EA3E0BC 0x7937 # 0 +0x8EA3E0BD 0x79B5 # 0 +0x8EA3E0BE 0x7C62 # 0 +0x8EA3E0BF 0x7C5E # 0 +0x8EA3E0C0 0x7CF5 # 0 +0x8EA3E0C3 0x863D # 0 +0x8EA3E0C5 0x882D # 0 +0x8EA3E0C6 0x8989 # 0 +0x8EA3E0C7 0x8B8D # 0 +0x8EA3E0C8 0x8B87 # 0 +0x8EA3E0C9 0x8B90 # 0 +0x8EA3E0CA 0x8D1A # 0 +0x8EA3E0CB 0x8E99 # 0 +0x8EA3E0CF 0x945F # 0 +0x8EA3E0D2 0x9456 # 0 +0x8EA3E0D3 0x9461 # 0 +0x8EA3E0D4 0x945B # 0 +0x8EA3E0D5 0x945A # 0 +0x8EA3E0D6 0x945C # 0 +0x8EA3E0D7 0x9465 # 0 +0x8EA3E0D9 0x9741 # 0 +0x8EA3E0DC 0x986E # 0 +0x8EA3E0DD 0x986C # 0 +0x8EA3E0DE 0x986D # 0 +0x8EA3E0E0 0x99AA # 0 +0x8EA3E0E1 0x9A5C # 0 +0x8EA3E0E2 0x9A58 # 0 +0x8EA3E0E3 0x9ADE # 0 +0x8EA3E0E5 0x9C4F # 0 +0x8EA3E0E6 0x9C51 # 0 +0x8EA3E0E8 0x9C53 # 0 +0x8EA3E0EC 0x9DFC # 0 +0x8EA3E0ED 0x9F39 # 0 +0x8EA3E0EF 0x513E # 0 +0x8EA3E0F1 0x56D2 # 0 +0x8EA3E0F3 0x5B4F # 0 +0x8EA3E0F4 0x6B14 # 0 +0x8EA3E0F6 0x7A72 # 0 +0x8EA3E0F7 0x7A73 # 0 +0x8EA3E0FB 0x8B91 # 0 +0x8EA3E0FE 0x91BF # 0 +0x8EA3E1A2 0x946C # 0 +0x8EA3E1A5 0x96E6 # 0 +0x8EA3E1A6 0x9745 # 0 +0x8EA3E1A8 0x97C8 # 0 +0x8EA3E1A9 0x97E4 # 0 +0x8EA3E1AA 0x995D # 0 +0x8EA3E1AC 0x9B21 # 0 +0x8EA3E1AE 0x9B2C # 0 +0x8EA3E1AF 0x9B57 # 0 +0x8EA3E1B2 0x9C5D # 0 +0x8EA3E1B3 0x9C61 # 0 +0x8EA3E1B4 0x9C65 # 0 +0x8EA3E1B5 0x9E08 # 0 +0x8EA3E1BB 0x9F45 # 0 +0x8EA3E1BE 0x6205 # 0 +0x8EA3E1BF 0x66EF # 0 +0x8EA3E1C0 0x6B1B # 0 +0x8EA3E1C1 0x6B1D # 0 +0x8EA3E1C2 0x7225 # 0 +0x8EA3E1C3 0x7224 # 0 +0x8EA3E1C4 0x7C6D # 0 +0x8EA3E1C6 0x8642 # 0 +0x8EA3E1C7 0x8649 # 0 +0x8EA3E1C9 0x8978 # 0 +0x8EA3E1CA 0x898A # 0 +0x8EA3E1CB 0x8B97 # 0 +0x8EA3E1CD 0x8C9B # 0 +0x8EA3E1CE 0x8D1C # 0 +0x8EA3E1D0 0x8EA2 # 0 +0x8EA3E1D9 0x9C6C # 0 +0x8EA3E1DB 0x9C6F # 0 +0x8EA3E1DD 0x9E0E # 0 +0x8EA3E1DF 0x9F08 # 0 +0x8EA3E1E0 0x9F1D # 0 +0x8EA3E1E1 0x9FA3 # 0 +0x8EA3E1E4 0x5F60 # 0 +0x8EA3E1E5 0x6B1C # 0 +0x8EA3E1E9 0x7CF3 # 0 +0x8EA3E1EB 0x8B9B # 0 +0x8EA3E1EC 0x8EA7 # 0 +0x8EA3E1ED 0x91C4 # 0 +0x8EA3E1EF 0x947A # 0 +0x8EA3E1F2 0x9A61 # 0 +0x8EA3E1F3 0x9A63 # 0 +0x8EA3E1F4 0x9AD7 # 0 +0x8EA3E1F5 0x9C76 # 0 +0x8EA3E1F7 0x9FA5 # 0 +0x8EA3E1F9 0x7067 # 0 +0x8EA3E1FB 0x72AB # 0 +0x8EA3E1FC 0x864A # 0 +0x8EA3E1FD 0x897D # 0 +0x8EA3E1FE 0x8B9D # 0 +0x8EA3E2A1 0x8C53 # 0 +0x8EA3E2A2 0x8F65 # 0 +0x8EA3E2A3 0x947B # 0 +0x8EA3E2A5 0x98CD # 0 +0x8EA3E2A6 0x98DD # 0 +0x8EA3E2A8 0x9B30 # 0 +0x8EA3E2A9 0x9E16 # 0 +0x8EA3E2AF 0x96E7 # 0 +0x8EA3E2B0 0x9E18 # 0 +0x8EA3E2B1 0x9EA2 # 0 +0x8EA3E2B3 0x9F7C # 0 +0x8EA3E2B5 0x7E9E # 0 +0x8EA3E2B6 0x9484 # 0 +0x8EA3E2B8 0x9E1C # 0 +0x8EA3E2BA 0x7C71 # 0 +0x8EA3E2BB 0x97CA # 0 +0x8EA3E2BF 0x9EA3 # 0 +0x8EA3E2C1 0x9C7B # 0 +0x8EA3E2C2 0x9F97 # 0 +0x8EA3E2C5 0x9750 # 0 +0x8EA3E2C9 0x5727 # 0 +0x8EA3E2CA 0x5C13 # 0 +0x8EA3E2D1 0x5FC8 # 0 +0x8EA3E2D7 0x6765 # 0 +0x8EA3E2DA 0x52BD # 0 +0x8EA3E2DC 0x5B66 # 0 +0x8EA3E2DE 0x65F9 # 0 +0x8EA3E2DF 0x6788 # 0 +0x8EA3E2E0 0x6CE6 # 0 +0x8EA3E2E1 0x6CCB # 0 +0x8EA3E2E3 0x4FBD # 0 +0x8EA3E2E4 0x5F8D # 0 +0x8EA3E2E6 0x6018 # 0 +0x8EA3E2E7 0x6048 # 0 +0x8EA3E2E9 0x6B29 # 0 +0x8EA3E2EA 0x70A6 # 0 +0x8EA3E2EC 0x7706 # 0 +0x8EA3E2F0 0x5A10 # 0 +0x8EA3E2F1 0x5CFC # 0 +0x8EA3E2F2 0x5CFE # 0 +0x8EA3E2F9 0x70C9 # 0 +0x8EA3E3A3 0x9579 # 0 +0x8EA3E3A5 0x96BA # 0 +0x8EA3E3AD 0x7B29 # 0 +0x8EA3E3AE 0x8128 # 0 +0x8EA3E3B0 0x8A2E # 0 +0x8EA3E3B4 0x9AD9 # 0 +0x8EA3E3B6 0x582B # 0 +0x8EA3E3B7 0x5845 # 0 +0x8EA3E3B9 0x63FA # 0 +0x8EA3E3BD 0x6E86 # 0 +0x8EA3E3C3 0x5867 # 0 +0x8EA3E3C5 0x5BDD # 0 +0x8EA3E3C6 0x656E # 0 +0x8EA3E3CA 0x8C87 # 0 +0x8EA3E3CC 0x50D2 # 0 +0x8EA3E3CD 0x50DF # 0 +0x8EA3E3D2 0x69BA # 0 +0x8EA3E3D4 0x6B9D # 0 +0x8EA3E3D6 0x8059 # 0 +0x8EA3E3E3 0x6F8A # 0 +0x8EA3E3E6 0x7BC3 # 0 +0x8EA3E3E7 0x7BC2 # 0 +0x8EA3E3EC 0x90F6 # 0 +0x8EA3E3EE 0x9823 # 0 +0x8EA3E3F4 0x71CD # 0 +0x8EA3E3F5 0x7499 # 0 +0x8EA3E3FB 0x9842 # 0 +0x8EA3E4A2 0x7F84 # 0 +0x8EA3E4A8 0x8D0E # 0 +0x8EA3E4AA 0x9861 # 0 +0x8EA3E4AD 0x8B73 # 0 +0x8EA3E4AF 0x9C27 # 0 +0x8EA3E4B1 0x9458 # 0 +0x8EA3E4B2 0x77D6 # 0 +0x8EA3E4B3 0x9B2D # 0 +0x8EA3E4C8 0x4F66 # 0 +0x8EA3E4C9 0x4F68 # 0 +0x8EA3E4CA 0x4FE7 # 0 +0x8EA3E4CB 0x503F # 0 +0x8EA3E4CD 0x50A6 # 0 +0x8EA3E4CE 0x510F # 0 +0x8EA3E4CF 0x523E # 0 +0x8EA3E4D0 0x5324 # 0 +0x8EA3E4D1 0x5365 # 0 +0x8EA3E4D2 0x539B # 0 +0x8EA3E4D3 0x517F # 0 +0x8EA3E4D4 0x54CB # 0 +0x8EA3E4D5 0x5573 # 0 +0x8EA3E4D6 0x5571 # 0 +0x8EA3E4D7 0x556B # 0 +0x8EA3E4D8 0x55F4 # 0 +0x8EA3E4D9 0x5622 # 0 +0x8EA3E4DA 0x5620 # 0 +0x8EA3E4DB 0x5692 # 0 +0x8EA3E4DC 0x56BA # 0 +0x8EA3E4DD 0x5691 # 0 +0x8EA3E4DE 0x56B0 # 0 +0x8EA3E4DF 0x5759 # 0 +0x8EA3E4E0 0x578A # 0 +0x8EA3E4E1 0x580F # 0 +0x8EA3E4E2 0x5812 # 0 +0x8EA3E4E3 0x5813 # 0 +0x8EA3E4E4 0x5847 # 0 +0x8EA3E4E5 0x589B # 0 +0x8EA3E4E6 0x5900 # 0 +0x8EA3E4E7 0x594D # 0 +0x8EA3E4E8 0x5AD1 # 0 +0x8EA3E4E9 0x5AD3 # 0 +0x8EA3E4EA 0x5B67 # 0 +0x8EA3E4EB 0x5C57 # 0 +0x8EA3E4EC 0x5C77 # 0 +0x8EA3E4ED 0x5CD5 # 0 +0x8EA3E4EE 0x5D75 # 0 +0x8EA3E4EF 0x5D8E # 0 +0x8EA3E4F0 0x5DA5 # 0 +0x8EA3E4F1 0x5DB6 # 0 +0x8EA3E4F2 0x5DBF # 0 +0x8EA3E4F3 0x5E65 # 0 +0x8EA3E4F4 0x5ECD # 0 +0x8EA3E4F5 0x5EED # 0 +0x8EA3E4F6 0x5F94 # 0 +0x8EA3E4F7 0x5F9A # 0 +0x8EA3E4F8 0x5FBA # 0 +0x8EA3E4F9 0x6125 # 0 +0x8EA3E4FA 0x6150 # 0 +0x8EA3E4FB 0x62A3 # 0 +0x8EA3E4FC 0x6360 # 0 +0x8EA3E4FD 0x6364 # 0 +0x8EA3E4FE 0x63B6 # 0 +0x8EA3E5A1 0x6403 # 0 +0x8EA3E5A2 0x64B6 # 0 +0x8EA3E5A3 0x651A # 0 +0x8EA3E5A4 0x7A25 # 0 +0x8EA3E5A5 0x5C21 # 0 +0x8EA3E5A6 0x66E2 # 0 +0x8EA3E5A7 0x6702 # 0 +0x8EA3E5A8 0x67A4 # 0 +0x8EA3E5A9 0x67AC # 0 +0x8EA3E5AA 0x6810 # 0 +0x8EA3E5AB 0x6806 # 0 +0x8EA3E5AC 0x685E # 0 +0x8EA3E5AD 0x685A # 0 +0x8EA3E5AE 0x692C # 0 +0x8EA3E5AF 0x6929 # 0 +0x8EA3E5B0 0x6A2D # 0 +0x8EA3E5B1 0x6A77 # 0 +0x8EA3E5B2 0x6A7A # 0 +0x8EA3E5B3 0x6ACA # 0 +0x8EA3E5B4 0x6AE6 # 0 +0x8EA3E5B5 0x6AF5 # 0 +0x8EA3E5B6 0x6B0D # 0 +0x8EA3E5B7 0x6B0E # 0 +0x8EA3E5B8 0x6BDC # 0 +0x8EA3E5B9 0x6BDD # 0 +0x8EA3E5BA 0x6BF6 # 0 +0x8EA3E5BB 0x6C1E # 0 +0x8EA3E5BC 0x6C63 # 0 +0x8EA3E5BD 0x6DA5 # 0 +0x8EA3E5BE 0x6E0F # 0 +0x8EA3E5BF 0x6E8A # 0 +0x8EA3E5C0 0x6E84 # 0 +0x8EA3E5C1 0x6E8B # 0 +0x8EA3E5C2 0x6E7C # 0 +0x8EA3E5C3 0x6F4C # 0 +0x8EA3E5C4 0x6F48 # 0 +0x8EA3E5C5 0x6F49 # 0 +0x8EA3E5C6 0x6F9D # 0 +0x8EA3E5C7 0x6F99 # 0 +0x8EA3E5C8 0x6FF8 # 0 +0x8EA3E5C9 0x702E # 0 +0x8EA3E5CA 0x702D # 0 +0x8EA3E5CB 0x705C # 0 +0x8EA3E5CC 0x79CC # 0 +0x8EA3E5CD 0x70BF # 0 +0x8EA3E5CE 0x70EA # 0 +0x8EA3E5CF 0x70E5 # 0 +0x8EA3E5D0 0x7111 # 0 +0x8EA3E5D1 0x7112 # 0 +0x8EA3E5D2 0x713F # 0 +0x8EA3E5D3 0x7139 # 0 +0x8EA3E5D4 0x713B # 0 +0x8EA3E5D5 0x713D # 0 +0x8EA3E5D6 0x7177 # 0 +0x8EA3E5D7 0x7175 # 0 +0x8EA3E5D8 0x7176 # 0 +0x8EA3E5D9 0x7171 # 0 +0x8EA3E5DA 0x7196 # 0 +0x8EA3E5DB 0x7193 # 0 +0x8EA3E5DC 0x71B4 # 0 +0x8EA3E5DD 0x71DD # 0 +0x8EA3E5DE 0x71DE # 0 +0x8EA3E5DF 0x720E # 0 +0x8EA3E5E0 0x5911 # 0 +0x8EA3E5E1 0x7218 # 0 +0x8EA3E5E2 0x7347 # 0 +0x8EA3E5E3 0x7348 # 0 +0x8EA3E5E4 0x73EF # 0 +0x8EA3E5E5 0x7412 # 0 +0x8EA3E5E6 0x743B # 0 +0x8EA3E5E7 0x74A4 # 0 +0x8EA3E5E8 0x748D # 0 +0x8EA3E5E9 0x74B4 # 0 +0x8EA3E5EA 0x7673 # 0 +0x8EA3E5EB 0x7677 # 0 +0x8EA3E5EC 0x76BC # 0 +0x8EA3E5ED 0x7819 # 0 +0x8EA3E5EE 0x781B # 0 +0x8EA3E5EF 0x783D # 0 +0x8EA3E5F0 0x7853 # 0 +0x8EA3E5F1 0x7854 # 0 +0x8EA3E5F2 0x7858 # 0 +0x8EA3E5F3 0x78B7 # 0 +0x8EA3E5F4 0x78D8 # 0 +0x8EA3E5F5 0x78EE # 0 +0x8EA3E5F6 0x7922 # 0 +0x8EA3E5F7 0x794D # 0 +0x8EA3E5F8 0x7986 # 0 +0x8EA3E5F9 0x7999 # 0 +0x8EA3E5FA 0x79A3 # 0 +0x8EA3E5FB 0x79BC # 0 +0x8EA3E5FC 0x7AA7 # 0 +0x8EA3E5FD 0x7B37 # 0 +0x8EA3E5FE 0x7B59 # 0 +0x8EA3E6A1 0x7BD0 # 0 +0x8EA3E6A2 0x7C2F # 0 +0x8EA3E6A3 0x7C32 # 0 +0x8EA3E6A4 0x7C42 # 0 +0x8EA3E6A5 0x7C4E # 0 +0x8EA3E6A6 0x7C68 # 0 +0x8EA3E6A7 0x7CA9 # 0 +0x8EA3E6A8 0x7CED # 0 +0x8EA3E6A9 0x7DD0 # 0 +0x8EA3E6AA 0x7E07 # 0 +0x8EA3E6AB 0x7DD3 # 0 +0x8EA3E6AC 0x7E64 # 0 +0x8EA3E6AD 0x7F40 # 0 +0x8EA3E6AF 0x8041 # 0 +0x8EA3E6B0 0x8063 # 0 +0x8EA3E6B1 0x80BB # 0 +0x8EA3E6B2 0x6711 # 0 +0x8EA3E6B3 0x6725 # 0 +0x8EA3E6B4 0x8248 # 0 +0x8EA3E6B5 0x8310 # 0 +0x8EA3E6B6 0x8362 # 0 +0x8EA3E6B7 0x8312 # 0 +0x8EA3E6B8 0x8421 # 0 +0x8EA3E6B9 0x841E # 0 +0x8EA3E6BA 0x84E2 # 0 +0x8EA3E6BB 0x84DE # 0 +0x8EA3E6BC 0x84E1 # 0 +0x8EA3E6BD 0x8573 # 0 +0x8EA3E6BE 0x85D4 # 0 +0x8EA3E6BF 0x85F5 # 0 +0x8EA3E6C0 0x8637 # 0 +0x8EA3E6C1 0x8645 # 0 +0x8EA3E6C2 0x8672 # 0 +0x8EA3E6C3 0x874A # 0 +0x8EA3E6C4 0x87A9 # 0 +0x8EA3E6C5 0x87A5 # 0 +0x8EA3E6C6 0x87F5 # 0 +0x8EA3E6C7 0x8834 # 0 +0x8EA3E6C8 0x8850 # 0 +0x8EA3E6C9 0x8887 # 0 +0x8EA3E6CA 0x8954 # 0 +0x8EA3E6CB 0x8984 # 0 +0x8EA3E6CC 0x8B03 # 0 +0x8EA3E6CD 0x8C52 # 0 +0x8EA3E6CE 0x8CD8 # 0 +0x8EA3E6CF 0x8D0C # 0 +0x8EA3E6D0 0x8D18 # 0 +0x8EA3E6D1 0x8DB0 # 0 +0x8EA3E6D2 0x8EBC # 0 +0x8EA3E6D3 0x8ED5 # 0 +0x8EA3E6D4 0x8FAA # 0 +0x8EA3E6D5 0x909C # 0 +0x8EA3E6D7 0x915C # 0 +0x8EA3E6D8 0x922B # 0 +0x8EA3E6D9 0x9221 # 0 +0x8EA3E6DA 0x9273 # 0 +0x8EA3E6DB 0x92F4 # 0 +0x8EA3E6DC 0x92F5 # 0 +0x8EA3E6DD 0x933F # 0 +0x8EA3E6DE 0x9342 # 0 +0x8EA3E6DF 0x9386 # 0 +0x8EA3E6E0 0x93BE # 0 +0x8EA3E6E1 0x93BC # 0 +0x8EA3E6E2 0x93BD # 0 +0x8EA3E6E3 0x93F1 # 0 +0x8EA3E6E4 0x93F2 # 0 +0x8EA3E6E5 0x93EF # 0 +0x8EA3E6E6 0x9422 # 0 +0x8EA3E6E7 0x9423 # 0 +0x8EA3E6E8 0x9424 # 0 +0x8EA3E6E9 0x9467 # 0 +0x8EA3E6EA 0x9466 # 0 +0x8EA3E6EB 0x9597 # 0 +0x8EA3E6EC 0x95CE # 0 +0x8EA3E6ED 0x95E7 # 0 +0x8EA3E6EE 0x973B # 0 +0x8EA3E6EF 0x974D # 0 +0x8EA3E6F0 0x98E4 # 0 +0x8EA3E6F1 0x9942 # 0 +0x8EA3E6F2 0x9B1D # 0 +0x8EA3E6F3 0x9B98 # 0 +0x8EA3E6F5 0x9D49 # 0 +0x8EA3E6F6 0x6449 # 0 +0x8EA3E6F7 0x5E71 # 0 +0x8EA3E6F8 0x5E85 # 0 +0x8EA3E6F9 0x61D3 # 0 +0x8EA3E6FA 0x990E # 0 +0x8EA3E6FB 0x8002 # 0 +0x8EA3E6FC 0x781E # 0 +0x8EA3E7A1 0x5528 # 0 +0x8EA3E7A2 0x5572 # 0 +0x8EA3E7A3 0x55BA # 0 +0x8EA3E7A4 0x55F0 # 0 +0x8EA3E7A5 0x55EE # 0 +0x8EA3E7A6 0x56B8 # 0 +0x8EA3E7A7 0x56B9 # 0 +0x8EA3E7A8 0x56C4 # 0 +0x8EA3E7A9 0x8053 # 0 +0x8EA3E7AA 0x92B0 # 0 diff --git a/data/font.defs b/data/font.defs new file mode 100644 index 0000000000..ee4559e82e --- /dev/null +++ b/data/font.defs @@ -0,0 +1,55 @@ +/* + * "$Id: font.defs 343 2007-07-13 19:52:48Z mike $" + * + * Standard ESP Ghostscript font definitions for the CUPS PPD file + * compiler. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#font AvantGarde-Book Standard "(1.05)" Standard ROM +#font AvantGarde-BookOblique Standard "(1.05)" Standard ROM +#font AvantGarde-Demi Standard "(1.05)" Standard ROM +#font AvantGarde-DemiOblique Standard "(1.05)" Standard ROM +#font Bookman-Demi Standard "(1.05)" Standard ROM +#font Bookman-DemiItalic Standard "(1.05)" Standard ROM +#font Bookman-Light Standard "(1.05)" Standard ROM +#font Bookman-LightItalic Standard "(1.05)" Standard ROM +#font Courier Standard "(1.05)" Standard ROM +#font Courier-Bold Standard "(1.05)" Standard ROM +#font Courier-BoldOblique Standard "(1.05)" Standard ROM +#font Courier-Oblique Standard "(1.05)" Standard ROM +#font Helvetica Standard "(1.05)" Standard ROM +#font Helvetica-Bold Standard "(1.05)" Standard ROM +#font Helvetica-BoldOblique Standard "(1.05)" Standard ROM +#font Helvetica-Narrow Standard "(1.05)" Standard ROM +#font Helvetica-Narrow-Bold Standard "(1.05)" Standard ROM +#font Helvetica-Narrow-BoldOblique Standard "(1.05)" Standard ROM +#font Helvetica-Narrow-Oblique Standard "(1.05)" Standard ROM +#font Helvetica-Oblique Standard "(1.05)" Standard ROM +#font NewCenturySchlbk-Bold Standard "(1.05)" Standard ROM +#font NewCenturySchlbk-BoldItalic Standard "(1.05)" Standard ROM +#font NewCenturySchlbk-Italic Standard "(1.05)" Standard ROM +#font NewCenturySchlbk-Roman Standard "(1.05)" Standard ROM +#font Palatino-Bold Standard "(1.05)" Standard ROM +#font Palatino-BoldItalic Standard "(1.05)" Standard ROM +#font Palatino-Italic Standard "(1.05)" Standard ROM +#font Palatino-Roman Standard "(1.05)" Standard ROM +#font Symbol Special "(001.005)" Special ROM +#font Times-Bold Standard "(1.05)" Standard ROM +#font Times-BoldItalic Standard "(1.05)" Standard ROM +#font Times-Italic Standard "(1.05)" Standard ROM +#font Times-Roman Standard "(1.05)" Standard ROM +#font ZapfChancery-MediumItalic Standard "(1.05)" Standard ROM +#font ZapfDingbats Special "(001.005)" Special ROM + +/* + * End of "$Id: font.defs 343 2007-07-13 19:52:48Z mike $". + */ diff --git a/data/hp.h b/data/hp.h new file mode 100644 index 0000000000..c700343163 --- /dev/null +++ b/data/hp.h @@ -0,0 +1,24 @@ +/* + * "$Id$" + * + * This file contains model number definitions for the CUPS sample + * HP driver. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#define HP_LASERJET 0 /* HP LaserJet */ +#define HP_DESKJET 1 /* HP DeskJet with simple color */ +#define HP_DESKJET2 2 /* HP DeskJet with CRet color */ + + +/* + * End of "$Id$". + */ diff --git a/data/iso-8859-1.txt b/data/iso-8859-1.txt new file mode 100644 index 0000000000..473ecabc17 --- /dev/null +++ b/data/iso-8859-1.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-1:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-1:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-1 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-1 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic) +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic) +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic) +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic) +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/data/iso-8859-10.txt b/data/iso-8859-10.txt new file mode 100644 index 0000000000..374a42b1a5 --- /dev/null +++ b/data/iso-8859-10.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-10:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.1 +# Table format: Format A +# Date: 1999 October 11 +# Authors: Ken Whistler +# +# Copyright (c) 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-10:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-10 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-10 order. +# +# Version history +# 1.0 version new. +# 1.1 corrected mistake in mapping of 0xA4 +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x0112 # LATIN CAPITAL LETTER E WITH MACRON +0xA3 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA +0xA4 0x012A # LATIN CAPITAL LETTER I WITH MACRON +0xA5 0x0128 # LATIN CAPITAL LETTER I WITH TILDE +0xA6 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA +0xA7 0x00A7 # SECTION SIGN +0xA8 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA +0xA9 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xAA 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAB 0x0166 # LATIN CAPITAL LETTER T WITH STROKE +0xAC 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xAF 0x014A # LATIN CAPITAL LETTER ENG +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x0113 # LATIN SMALL LETTER E WITH MACRON +0xB3 0x0123 # LATIN SMALL LETTER G WITH CEDILLA +0xB4 0x012B # LATIN SMALL LETTER I WITH MACRON +0xB5 0x0129 # LATIN SMALL LETTER I WITH TILDE +0xB6 0x0137 # LATIN SMALL LETTER K WITH CEDILLA +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x013C # LATIN SMALL LETTER L WITH CEDILLA +0xB9 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xBA 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBB 0x0167 # LATIN SMALL LETTER T WITH STROKE +0xBC 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBD 0x2015 # HORIZONTAL BAR +0xBE 0x016B # LATIN SMALL LETTER U WITH MACRON +0xBF 0x014B # LATIN SMALL LETTER ENG +0xC0 0x0100 # LATIN CAPITAL LETTER A WITH MACRON +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x012E # LATIN CAPITAL LETTER I WITH OGONEK +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH (Icelandic) +0xD1 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xD2 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x0168 # LATIN CAPITAL LETTER U WITH TILDE +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN (Icelandic) +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x0101 # LATIN SMALL LETTER A WITH MACRON +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x012F # LATIN SMALL LETTER I WITH OGONEK +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH (Icelandic) +0xF1 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xF2 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x0169 # LATIN SMALL LETTER U WITH TILDE +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x0173 # LATIN SMALL LETTER U WITH OGONEK +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN (Icelandic) +0xFF 0x0138 # LATIN SMALL LETTER KRA diff --git a/data/iso-8859-11.txt b/data/iso-8859-11.txt new file mode 100644 index 0000000000..cfbcc5fdf0 --- /dev/null +++ b/data/iso-8859-11.txt @@ -0,0 +1,249 @@ +# 8859-11.txt - Legacy SBCS to Unicode charmap +0x00 0x0000 # 0 +0x01 0x0001 # 0 +0x02 0x0002 # 0 +0x03 0x0003 # 0 +0x04 0x0004 # 0 +0x05 0x0005 # 0 +0x06 0x0006 # 0 +0x07 0x0007 # 0 +0x08 0x0008 # 0 +0x09 0x0009 # 0 +0x0A 0x000A # 0 +0x0B 0x000B # 0 +0x0C 0x000C # 0 +0x0D 0x000D # 0 +0x0E 0x000E # 0 +0x0F 0x000F # 0 +0x10 0x0010 # 0 +0x11 0x0011 # 0 +0x12 0x0012 # 0 +0x13 0x0013 # 0 +0x14 0x0014 # 0 +0x15 0x0015 # 0 +0x16 0x0016 # 0 +0x17 0x0017 # 0 +0x18 0x0018 # 0 +0x19 0x0019 # 0 +0x1A 0x001A # 0 +0x1B 0x001B # 0 +0x1C 0x001C # 0 +0x1D 0x001D # 0 +0x1E 0x001E # 0 +0x1F 0x001F # 0 +0x20 0x0020 # 0 +0x21 0x0021 # 0 +0x22 0x0022 # 0 +0x23 0x0023 # 0 +0x24 0x0024 # 0 +0x25 0x0025 # 0 +0x26 0x0026 # 0 +0x27 0x0027 # 0 +0x28 0x0028 # 0 +0x29 0x0029 # 0 +0x2A 0x002A # 0 +0x2B 0x002B # 0 +0x2C 0x002C # 0 +0x2D 0x002D # 0 +0x2E 0x002E # 0 +0x2F 0x002F # 0 +0x30 0x0030 # 0 +0x31 0x0031 # 0 +0x32 0x0032 # 0 +0x33 0x0033 # 0 +0x34 0x0034 # 0 +0x35 0x0035 # 0 +0x36 0x0036 # 0 +0x37 0x0037 # 0 +0x38 0x0038 # 0 +0x39 0x0039 # 0 +0x3A 0x003A # 0 +0x3B 0x003B # 0 +0x3C 0x003C # 0 +0x3D 0x003D # 0 +0x3E 0x003E # 0 +0x3F 0x003F # 0 +0x40 0x0040 # 0 +0x41 0x0041 # 0 +0x42 0x0042 # 0 +0x43 0x0043 # 0 +0x44 0x0044 # 0 +0x45 0x0045 # 0 +0x46 0x0046 # 0 +0x47 0x0047 # 0 +0x48 0x0048 # 0 +0x49 0x0049 # 0 +0x4A 0x004A # 0 +0x4B 0x004B # 0 +0x4C 0x004C # 0 +0x4D 0x004D # 0 +0x4E 0x004E # 0 +0x4F 0x004F # 0 +0x50 0x0050 # 0 +0x51 0x0051 # 0 +0x52 0x0052 # 0 +0x53 0x0053 # 0 +0x54 0x0054 # 0 +0x55 0x0055 # 0 +0x56 0x0056 # 0 +0x57 0x0057 # 0 +0x58 0x0058 # 0 +0x59 0x0059 # 0 +0x5A 0x005A # 0 +0x5B 0x005B # 0 +0x5C 0x005C # 0 +0x5D 0x005D # 0 +0x5E 0x005E # 0 +0x5F 0x005F # 0 +0x60 0x0060 # 0 +0x61 0x0061 # 0 +0x62 0x0062 # 0 +0x63 0x0063 # 0 +0x64 0x0064 # 0 +0x65 0x0065 # 0 +0x66 0x0066 # 0 +0x67 0x0067 # 0 +0x68 0x0068 # 0 +0x69 0x0069 # 0 +0x6A 0x006A # 0 +0x6B 0x006B # 0 +0x6C 0x006C # 0 +0x6D 0x006D # 0 +0x6E 0x006E # 0 +0x6F 0x006F # 0 +0x70 0x0070 # 0 +0x71 0x0071 # 0 +0x72 0x0072 # 0 +0x73 0x0073 # 0 +0x74 0x0074 # 0 +0x75 0x0075 # 0 +0x76 0x0076 # 0 +0x77 0x0077 # 0 +0x78 0x0078 # 0 +0x79 0x0079 # 0 +0x7A 0x007A # 0 +0x7B 0x007B # 0 +0x7C 0x007C # 0 +0x7D 0x007D # 0 +0x7E 0x007E # 0 +0x7F 0x007F # 0 +0x80 0x0080 # 0 +0x81 0x0081 # 0 +0x82 0x0082 # 0 +0x83 0x0083 # 0 +0x84 0x0084 # 0 +0x85 0x0085 # 0 +0x86 0x0086 # 0 +0x87 0x0087 # 0 +0x88 0x0088 # 0 +0x89 0x0089 # 0 +0x8A 0x008A # 0 +0x8B 0x008B # 0 +0x8C 0x008C # 0 +0x8D 0x008D # 0 +0x8E 0x008E # 0 +0x8F 0x008F # 0 +0x90 0x0090 # 0 +0x91 0x0091 # 0 +0x92 0x0092 # 0 +0x93 0x0093 # 0 +0x94 0x0094 # 0 +0x95 0x0095 # 0 +0x96 0x0096 # 0 +0x97 0x0097 # 0 +0x98 0x0098 # 0 +0x99 0x0099 # 0 +0x9A 0x009A # 0 +0x9B 0x009B # 0 +0x9C 0x009C # 0 +0x9D 0x009D # 0 +0x9E 0x009E # 0 +0x9F 0x009F # 0 +0xA0 0x00A0 # 0 +0xA1 0x0E01 # 0 +0xA2 0x0E02 # 0 +0xA3 0x0E03 # 0 +0xA4 0x0E04 # 0 +0xA5 0x0E05 # 0 +0xA6 0x0E06 # 0 +0xA7 0x0E07 # 0 +0xA8 0x0E08 # 0 +0xA9 0x0E09 # 0 +0xAA 0x0E0A # 0 +0xAB 0x0E0B # 0 +0xAC 0x0E0C # 0 +0xAD 0x0E0D # 0 +0xAE 0x0E0E # 0 +0xAF 0x0E0F # 0 +0xB0 0x0E10 # 0 +0xB1 0x0E11 # 0 +0xB2 0x0E12 # 0 +0xB3 0x0E13 # 0 +0xB4 0x0E14 # 0 +0xB5 0x0E15 # 0 +0xB6 0x0E16 # 0 +0xB7 0x0E17 # 0 +0xB8 0x0E18 # 0 +0xB9 0x0E19 # 0 +0xBA 0x0E1A # 0 +0xBB 0x0E1B # 0 +0xBC 0x0E1C # 0 +0xBD 0x0E1D # 0 +0xBE 0x0E1E # 0 +0xBF 0x0E1F # 0 +0xC0 0x0E20 # 0 +0xC1 0x0E21 # 0 +0xC2 0x0E22 # 0 +0xC3 0x0E23 # 0 +0xC4 0x0E24 # 0 +0xC5 0x0E25 # 0 +0xC6 0x0E26 # 0 +0xC7 0x0E27 # 0 +0xC8 0x0E28 # 0 +0xC9 0x0E29 # 0 +0xCA 0x0E2A # 0 +0xCB 0x0E2B # 0 +0xCC 0x0E2C # 0 +0xCD 0x0E2D # 0 +0xCE 0x0E2E # 0 +0xCF 0x0E2F # 0 +0xD0 0x0E30 # 0 +0xD1 0x0E31 # 0 +0xD2 0x0E32 # 0 +0xD3 0x0E33 # 0 +0xD4 0x0E34 # 0 +0xD5 0x0E35 # 0 +0xD6 0x0E36 # 0 +0xD7 0x0E37 # 0 +0xD8 0x0E38 # 0 +0xD9 0x0E39 # 0 +0xDA 0x0E3A # 0 +0xDF 0x0E3F # 0 +0xE0 0x0E40 # 0 +0xE1 0x0E41 # 0 +0xE2 0x0E42 # 0 +0xE3 0x0E43 # 0 +0xE4 0x0E44 # 0 +0xE5 0x0E45 # 0 +0xE6 0x0E46 # 0 +0xE7 0x0E47 # 0 +0xE8 0x0E48 # 0 +0xE9 0x0E49 # 0 +0xEA 0x0E4A # 0 +0xEB 0x0E4B # 0 +0xEC 0x0E4C # 0 +0xED 0x0E4D # 0 +0xEE 0x0E4E # 0 +0xEF 0x0E4F # 0 +0xF0 0x0E50 # 0 +0xF1 0x0E51 # 0 +0xF2 0x0E52 # 0 +0xF3 0x0E53 # 0 +0xF4 0x0E54 # 0 +0xF5 0x0E55 # 0 +0xF6 0x0E56 # 0 +0xF7 0x0E57 # 0 +0xF8 0x0E58 # 0 +0xF9 0x0E59 # 0 +0xFA 0x0E5A # 0 +0xFB 0x0E5B # 0 diff --git a/data/iso-8859-13.txt b/data/iso-8859-13.txt new file mode 100644 index 0000000000..cd11b53fd7 --- /dev/null +++ b/data/iso-8859-13.txt @@ -0,0 +1,299 @@ +# +# Name: ISO/IEC 8859-13:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-13:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-13 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-13 order. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x201D # RIGHT DOUBLE QUOTATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x0156 # LATIN CAPITAL LETTER R WITH CEDILLA +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00C6 # LATIN CAPITAL LETTER AE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x201C # LEFT DOUBLE QUOTATION MARK +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x0157 # LATIN SMALL LETTER R WITH CEDILLA +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00E6 # LATIN SMALL LETTER AE +0xC0 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xC1 0x012E # LATIN CAPITAL LETTER I WITH OGONEK +0xC2 0x0100 # LATIN CAPITAL LETTER A WITH MACRON +0xC3 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xC7 0x0112 # LATIN CAPITAL LETTER E WITH MACRON +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xCB 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCC 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA +0xCD 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA +0xCE 0x012A # LATIN CAPITAL LETTER I WITH MACRON +0xCF 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA +0xD0 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK +0xD9 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xDA 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xDB 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xDE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xDF 0x00DF # LATIN SMALL LETTER SHARP S (German) +0xE0 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xE1 0x012F # LATIN SMALL LETTER I WITH OGONEK +0xE2 0x0101 # LATIN SMALL LETTER A WITH MACRON +0xE3 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xE7 0x0113 # LATIN SMALL LETTER E WITH MACRON +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xEB 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE +0xEC 0x0123 # LATIN SMALL LETTER G WITH CEDILLA +0xED 0x0137 # LATIN SMALL LETTER K WITH CEDILLA +0xEE 0x012B # LATIN SMALL LETTER I WITH MACRON +0xEF 0x013C # LATIN SMALL LETTER L WITH CEDILLA +0xF0 0x0161 # LATIN SMALL LETTER S WITH CARON +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x0173 # LATIN SMALL LETTER U WITH OGONEK +0xF9 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xFA 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xFB 0x016B # LATIN SMALL LETTER U WITH MACRON +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xFE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xFF 0x2019 # RIGHT SINGLE QUOTATION MARK diff --git a/data/iso-8859-14.txt b/data/iso-8859-14.txt new file mode 100644 index 0000000000..36038f413a --- /dev/null +++ b/data/iso-8859-14.txt @@ -0,0 +1,301 @@ +# +# Name: ISO/IEC 8859-14:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Markus Kuhn +# Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-14:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-14 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-14 order. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x1E02 # LATIN CAPITAL LETTER B WITH DOT ABOVE +0xA2 0x1E03 # LATIN SMALL LETTER B WITH DOT ABOVE +0xA3 0x00A3 # POUND SIGN +0xA4 0x010A # LATIN CAPITAL LETTER C WITH DOT ABOVE +0xA5 0x010B # LATIN SMALL LETTER C WITH DOT ABOVE +0xA6 0x1E0A # LATIN CAPITAL LETTER D WITH DOT ABOVE +0xA7 0x00A7 # SECTION SIGN +0xA8 0x1E80 # LATIN CAPITAL LETTER W WITH GRAVE +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x1E82 # LATIN CAPITAL LETTER W WITH ACUTE +0xAB 0x1E0B # LATIN SMALL LETTER D WITH DOT ABOVE +0xAC 0x1EF2 # LATIN CAPITAL LETTER Y WITH GRAVE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xB0 0x1E1E # LATIN CAPITAL LETTER F WITH DOT ABOVE +0xB1 0x1E1F # LATIN SMALL LETTER F WITH DOT ABOVE +0xB2 0x0120 # LATIN CAPITAL LETTER G WITH DOT ABOVE +0xB3 0x0121 # LATIN SMALL LETTER G WITH DOT ABOVE +0xB4 0x1E40 # LATIN CAPITAL LETTER M WITH DOT ABOVE +0xB5 0x1E41 # LATIN SMALL LETTER M WITH DOT ABOVE +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x1E56 # LATIN CAPITAL LETTER P WITH DOT ABOVE +0xB8 0x1E81 # LATIN SMALL LETTER W WITH GRAVE +0xB9 0x1E57 # LATIN SMALL LETTER P WITH DOT ABOVE +0xBA 0x1E83 # LATIN SMALL LETTER W WITH ACUTE +0xBB 0x1E60 # LATIN CAPITAL LETTER S WITH DOT ABOVE +0xBC 0x1EF3 # LATIN SMALL LETTER Y WITH GRAVE +0xBD 0x1E84 # LATIN CAPITAL LETTER W WITH DIAERESIS +0xBE 0x1E85 # LATIN SMALL LETTER W WITH DIAERESIS +0xBF 0x1E61 # LATIN SMALL LETTER S WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x0174 # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x1E6A # LATIN CAPITAL LETTER T WITH DOT ABOVE +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0176 # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x0175 # LATIN SMALL LETTER W WITH CIRCUMFLEX +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x1E6B # LATIN SMALL LETTER T WITH DOT ABOVE +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0177 # LATIN SMALL LETTER Y WITH CIRCUMFLEX +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS + diff --git a/data/iso-8859-15.txt b/data/iso-8859-15.txt new file mode 100644 index 0000000000..1e319707d4 --- /dev/null +++ b/data/iso-8859-15.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-15:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Markus Kuhn +# Ken Whistler +# +# Copyright (c) 1998 - 1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-15:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-15 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-15 order. +# +# Version history +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x20AC # EURO SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xA7 0x00A7 # SECTION SIGN +0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0152 # LATIN CAPITAL LIGATURE OE +0xBD 0x0153 # LATIN SMALL LIGATURE OE +0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 # LATIN CAPITAL LETTER ETH +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE # LATIN CAPITAL LETTER THORN +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 # LATIN SMALL LETTER ETH +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE # LATIN SMALL LETTER THORN +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS + diff --git a/data/iso-8859-16.txt b/data/iso-8859-16.txt new file mode 100644 index 0000000000..5353d747b4 --- /dev/null +++ b/data/iso-8859-16.txt @@ -0,0 +1,299 @@ +# +# Name: ISO/IEC 8859-16:2001 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 2001 July 26 +# Authors: Markus Kuhn +# +# Copyright (c) 1999-2001 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-16:2001 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-16 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-16 order. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x20AC # EURO SIGN +0xA5 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xA6 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xA7 0x00A7 # SECTION SIGN +0xA8 0x0161 # LATIN SMALL LETTER S WITH CARON +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x0218 # LATIN CAPITAL LETTER S WITH COMMA BELOW +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xB4 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xB5 0x201D # RIGHT DOUBLE QUOTATION MARK +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x017E # LATIN SMALL LETTER Z WITH CARON +0xB9 0x010D # LATIN SMALL LETTER C WITH CARON +0xBA 0x0219 # LATIN SMALL LETTER S WITH COMMA BELOW +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0152 # LATIN CAPITAL LIGATURE OE +0xBD 0x0153 # LATIN SMALL LIGATURE OE +0xBE 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xD8 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xDE 0x021A # LATIN CAPITAL LETTER T WITH COMMA BELOW +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xF8 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xFE 0x021B # LATIN SMALL LETTER T WITH COMMA BELOW +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/data/iso-8859-2.txt b/data/iso-8859-2.txt new file mode 100644 index 0000000000..e45df25eb8 --- /dev/null +++ b/data/iso-8859-2.txt @@ -0,0 +1,303 @@ +# +# Name: ISO 8859-2:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-2:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-2 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-2 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x02D8 # BREVE +0xA3 0x0141 # LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x013D # LATIN CAPITAL LETTER L WITH CARON +0xA6 0x015A # LATIN CAPITAL LETTER S WITH ACUTE +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x0164 # LATIN CAPITAL LETTER T WITH CARON +0xAC 0x0179 # LATIN CAPITAL LETTER Z WITH ACUTE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x02DB # OGONEK +0xB3 0x0142 # LATIN SMALL LETTER L WITH STROKE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x013E # LATIN SMALL LETTER L WITH CARON +0xB6 0x015B # LATIN SMALL LETTER S WITH ACUTE +0xB7 0x02C7 # CARON +0xB8 0x00B8 # CEDILLA +0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x0165 # LATIN SMALL LETTER T WITH CARON +0xBC 0x017A # LATIN SMALL LETTER Z WITH ACUTE +0xBD 0x02DD # DOUBLE ACUTE ACCENT +0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x0154 # LATIN CAPITAL LETTER R WITH ACUTE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 # LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0139 # LATIN CAPITAL LETTER L WITH ACUTE +0xC6 0x0106 # LATIN CAPITAL LETTER C WITH ACUTE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x011A # LATIN CAPITAL LETTER E WITH CARON +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x010E # LATIN CAPITAL LETTER D WITH CARON +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 # LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0147 # LATIN CAPITAL LETTER N WITH CARON +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x0158 # LATIN CAPITAL LETTER R WITH CARON +0xD9 0x016E # LATIN CAPITAL LETTER U WITH RING ABOVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x0170 # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD # LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0162 # LATIN CAPITAL LETTER T WITH CEDILLA +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x0155 # LATIN SMALL LETTER R WITH ACUTE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 # LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x013A # LATIN SMALL LETTER L WITH ACUTE +0xE6 0x0107 # LATIN SMALL LETTER C WITH ACUTE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x011B # LATIN SMALL LETTER E WITH CARON +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x010F # LATIN SMALL LETTER D WITH CARON +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 # LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0148 # LATIN SMALL LETTER N WITH CARON +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x0159 # LATIN SMALL LETTER R WITH CARON +0xF9 0x016F # LATIN SMALL LETTER U WITH RING ABOVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x0171 # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD # LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0163 # LATIN SMALL LETTER T WITH CEDILLA +0xFF 0x02D9 # DOT ABOVE diff --git a/data/iso-8859-3.txt b/data/iso-8859-3.txt new file mode 100644 index 0000000000..9b6ac69dd8 --- /dev/null +++ b/data/iso-8859-3.txt @@ -0,0 +1,296 @@ +# +# Name: ISO/IEC 8859-3:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-3:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-3 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-3 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0126 # LATIN CAPITAL LETTER H WITH STROKE +0xA2 0x02D8 # BREVE +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA6 0x0124 # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xAA 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x011E # LATIN CAPITAL LETTER G WITH BREVE +0xAC 0x0134 # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0xAD 0x00AD # SOFT HYPHEN +0xAF 0x017B # LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0127 # LATIN SMALL LETTER H WITH STROKE +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x0125 # LATIN SMALL LETTER H WITH CIRCUMFLEX +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x0131 # LATIN SMALL LETTER DOTLESS I +0xBA 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x011F # LATIN SMALL LETTER G WITH BREVE +0xBC 0x0135 # LATIN SMALL LETTER J WITH CIRCUMFLEX +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBF 0x017C # LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x010A # LATIN CAPITAL LETTER C WITH DOT ABOVE +0xC6 0x0108 # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0120 # LATIN CAPITAL LETTER G WITH DOT ABOVE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x011C # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x016C # LATIN CAPITAL LETTER U WITH BREVE +0xDE 0x015C # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x010B # LATIN SMALL LETTER C WITH DOT ABOVE +0xE6 0x0109 # LATIN SMALL LETTER C WITH CIRCUMFLEX +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0121 # LATIN SMALL LETTER G WITH DOT ABOVE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x011D # LATIN SMALL LETTER G WITH CIRCUMFLEX +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x016D # LATIN SMALL LETTER U WITH BREVE +0xFE 0x015D # LATIN SMALL LETTER S WITH CIRCUMFLEX +0xFF 0x02D9 # DOT ABOVE diff --git a/data/iso-8859-4.txt b/data/iso-8859-4.txt new file mode 100644 index 0000000000..662e698ab2 --- /dev/null +++ b/data/iso-8859-4.txt @@ -0,0 +1,303 @@ +# +# Name: ISO/IEC 8859-4:1998 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-4:1998 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-4 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-4 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0104 # LATIN CAPITAL LETTER A WITH OGONEK +0xA2 0x0138 # LATIN SMALL LETTER KRA +0xA3 0x0156 # LATIN CAPITAL LETTER R WITH CEDILLA +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x0128 # LATIN CAPITAL LETTER I WITH TILDE +0xA6 0x013B # LATIN CAPITAL LETTER L WITH CEDILLA +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x0160 # LATIN CAPITAL LETTER S WITH CARON +0xAA 0x0112 # LATIN CAPITAL LETTER E WITH MACRON +0xAB 0x0122 # LATIN CAPITAL LETTER G WITH CEDILLA +0xAC 0x0166 # LATIN CAPITAL LETTER T WITH STROKE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x017D # LATIN CAPITAL LETTER Z WITH CARON +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x0105 # LATIN SMALL LETTER A WITH OGONEK +0xB2 0x02DB # OGONEK +0xB3 0x0157 # LATIN SMALL LETTER R WITH CEDILLA +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x0129 # LATIN SMALL LETTER I WITH TILDE +0xB6 0x013C # LATIN SMALL LETTER L WITH CEDILLA +0xB7 0x02C7 # CARON +0xB8 0x00B8 # CEDILLA +0xB9 0x0161 # LATIN SMALL LETTER S WITH CARON +0xBA 0x0113 # LATIN SMALL LETTER E WITH MACRON +0xBB 0x0123 # LATIN SMALL LETTER G WITH CEDILLA +0xBC 0x0167 # LATIN SMALL LETTER T WITH STROKE +0xBD 0x014A # LATIN CAPITAL LETTER ENG +0xBE 0x017E # LATIN SMALL LETTER Z WITH CARON +0xBF 0x014B # LATIN SMALL LETTER ENG +0xC0 0x0100 # LATIN CAPITAL LETTER A WITH MACRON +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x012E # LATIN CAPITAL LETTER I WITH OGONEK +0xC8 0x010C # LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 # LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x0116 # LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x012A # LATIN CAPITAL LETTER I WITH MACRON +0xD0 0x0110 # LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0145 # LATIN CAPITAL LETTER N WITH CEDILLA +0xD2 0x014C # LATIN CAPITAL LETTER O WITH MACRON +0xD3 0x0136 # LATIN CAPITAL LETTER K WITH CEDILLA +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x0172 # LATIN CAPITAL LETTER U WITH OGONEK +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0168 # LATIN CAPITAL LETTER U WITH TILDE +0xDE 0x016A # LATIN CAPITAL LETTER U WITH MACRON +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x0101 # LATIN SMALL LETTER A WITH MACRON +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x012F # LATIN SMALL LETTER I WITH OGONEK +0xE8 0x010D # LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 # LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x0117 # LATIN SMALL LETTER E WITH DOT ABOVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x012B # LATIN SMALL LETTER I WITH MACRON +0xF0 0x0111 # LATIN SMALL LETTER D WITH STROKE +0xF1 0x0146 # LATIN SMALL LETTER N WITH CEDILLA +0xF2 0x014D # LATIN SMALL LETTER O WITH MACRON +0xF3 0x0137 # LATIN SMALL LETTER K WITH CEDILLA +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x0173 # LATIN SMALL LETTER U WITH OGONEK +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0169 # LATIN SMALL LETTER U WITH TILDE +0xFE 0x016B # LATIN SMALL LETTER U WITH MACRON +0xFF 0x02D9 # DOT ABOVE diff --git a/data/iso-8859-5.txt b/data/iso-8859-5.txt new file mode 100644 index 0000000000..a7ed1ce2ab --- /dev/null +++ b/data/iso-8859-5.txt @@ -0,0 +1,303 @@ +# +# Name: ISO 8859-5:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-5:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-5 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-5 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x0401 # CYRILLIC CAPITAL LETTER IO +0xA2 0x0402 # CYRILLIC CAPITAL LETTER DJE +0xA3 0x0403 # CYRILLIC CAPITAL LETTER GJE +0xA4 0x0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xA5 0x0405 # CYRILLIC CAPITAL LETTER DZE +0xA6 0x0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0xA7 0x0407 # CYRILLIC CAPITAL LETTER YI +0xA8 0x0408 # CYRILLIC CAPITAL LETTER JE +0xA9 0x0409 # CYRILLIC CAPITAL LETTER LJE +0xAA 0x040A # CYRILLIC CAPITAL LETTER NJE +0xAB 0x040B # CYRILLIC CAPITAL LETTER TSHE +0xAC 0x040C # CYRILLIC CAPITAL LETTER KJE +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x040E # CYRILLIC CAPITAL LETTER SHORT U +0xAF 0x040F # CYRILLIC CAPITAL LETTER DZHE +0xB0 0x0410 # CYRILLIC CAPITAL LETTER A +0xB1 0x0411 # CYRILLIC CAPITAL LETTER BE +0xB2 0x0412 # CYRILLIC CAPITAL LETTER VE +0xB3 0x0413 # CYRILLIC CAPITAL LETTER GHE +0xB4 0x0414 # CYRILLIC CAPITAL LETTER DE +0xB5 0x0415 # CYRILLIC CAPITAL LETTER IE +0xB6 0x0416 # CYRILLIC CAPITAL LETTER ZHE +0xB7 0x0417 # CYRILLIC CAPITAL LETTER ZE +0xB8 0x0418 # CYRILLIC CAPITAL LETTER I +0xB9 0x0419 # CYRILLIC CAPITAL LETTER SHORT I +0xBA 0x041A # CYRILLIC CAPITAL LETTER KA +0xBB 0x041B # CYRILLIC CAPITAL LETTER EL +0xBC 0x041C # CYRILLIC CAPITAL LETTER EM +0xBD 0x041D # CYRILLIC CAPITAL LETTER EN +0xBE 0x041E # CYRILLIC CAPITAL LETTER O +0xBF 0x041F # CYRILLIC CAPITAL LETTER PE +0xC0 0x0420 # CYRILLIC CAPITAL LETTER ER +0xC1 0x0421 # CYRILLIC CAPITAL LETTER ES +0xC2 0x0422 # CYRILLIC CAPITAL LETTER TE +0xC3 0x0423 # CYRILLIC CAPITAL LETTER U +0xC4 0x0424 # CYRILLIC CAPITAL LETTER EF +0xC5 0x0425 # CYRILLIC CAPITAL LETTER HA +0xC6 0x0426 # CYRILLIC CAPITAL LETTER TSE +0xC7 0x0427 # CYRILLIC CAPITAL LETTER CHE +0xC8 0x0428 # CYRILLIC CAPITAL LETTER SHA +0xC9 0x0429 # CYRILLIC CAPITAL LETTER SHCHA +0xCA 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN +0xCB 0x042B # CYRILLIC CAPITAL LETTER YERU +0xCC 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN +0xCD 0x042D # CYRILLIC CAPITAL LETTER E +0xCE 0x042E # CYRILLIC CAPITAL LETTER YU +0xCF 0x042F # CYRILLIC CAPITAL LETTER YA +0xD0 0x0430 # CYRILLIC SMALL LETTER A +0xD1 0x0431 # CYRILLIC SMALL LETTER BE +0xD2 0x0432 # CYRILLIC SMALL LETTER VE +0xD3 0x0433 # CYRILLIC SMALL LETTER GHE +0xD4 0x0434 # CYRILLIC SMALL LETTER DE +0xD5 0x0435 # CYRILLIC SMALL LETTER IE +0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE +0xD7 0x0437 # CYRILLIC SMALL LETTER ZE +0xD8 0x0438 # CYRILLIC SMALL LETTER I +0xD9 0x0439 # CYRILLIC SMALL LETTER SHORT I +0xDA 0x043A # CYRILLIC SMALL LETTER KA +0xDB 0x043B # CYRILLIC SMALL LETTER EL +0xDC 0x043C # CYRILLIC SMALL LETTER EM +0xDD 0x043D # CYRILLIC SMALL LETTER EN +0xDE 0x043E # CYRILLIC SMALL LETTER O +0xDF 0x043F # CYRILLIC SMALL LETTER PE +0xE0 0x0440 # CYRILLIC SMALL LETTER ER +0xE1 0x0441 # CYRILLIC SMALL LETTER ES +0xE2 0x0442 # CYRILLIC SMALL LETTER TE +0xE3 0x0443 # CYRILLIC SMALL LETTER U +0xE4 0x0444 # CYRILLIC SMALL LETTER EF +0xE5 0x0445 # CYRILLIC SMALL LETTER HA +0xE6 0x0446 # CYRILLIC SMALL LETTER TSE +0xE7 0x0447 # CYRILLIC SMALL LETTER CHE +0xE8 0x0448 # CYRILLIC SMALL LETTER SHA +0xE9 0x0449 # CYRILLIC SMALL LETTER SHCHA +0xEA 0x044A # CYRILLIC SMALL LETTER HARD SIGN +0xEB 0x044B # CYRILLIC SMALL LETTER YERU +0xEC 0x044C # CYRILLIC SMALL LETTER SOFT SIGN +0xED 0x044D # CYRILLIC SMALL LETTER E +0xEE 0x044E # CYRILLIC SMALL LETTER YU +0xEF 0x044F # CYRILLIC SMALL LETTER YA +0xF0 0x2116 # NUMERO SIGN +0xF1 0x0451 # CYRILLIC SMALL LETTER IO +0xF2 0x0452 # CYRILLIC SMALL LETTER DJE +0xF3 0x0453 # CYRILLIC SMALL LETTER GJE +0xF4 0x0454 # CYRILLIC SMALL LETTER UKRAINIAN IE +0xF5 0x0455 # CYRILLIC SMALL LETTER DZE +0xF6 0x0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0xF7 0x0457 # CYRILLIC SMALL LETTER YI +0xF8 0x0458 # CYRILLIC SMALL LETTER JE +0xF9 0x0459 # CYRILLIC SMALL LETTER LJE +0xFA 0x045A # CYRILLIC SMALL LETTER NJE +0xFB 0x045B # CYRILLIC SMALL LETTER TSHE +0xFC 0x045C # CYRILLIC SMALL LETTER KJE +0xFD 0x00A7 # SECTION SIGN +0xFE 0x045E # CYRILLIC SMALL LETTER SHORT U +0xFF 0x045F # CYRILLIC SMALL LETTER DZHE diff --git a/data/iso-8859-6.txt b/data/iso-8859-6.txt new file mode 100644 index 0000000000..69ac7f5894 --- /dev/null +++ b/data/iso-8859-6.txt @@ -0,0 +1,260 @@ +# +# Name: ISO 8859-6:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-6:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-6 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-6 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# 0x30..0x39 remapped to the ASCII digits (U+0030..U+0039) instead +# of the Arabic digits (U+0660..U+0669). +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA4 0x00A4 # CURRENCY SIGN +0xAC 0x060C # ARABIC COMMA +0xAD 0x00AD # SOFT HYPHEN +0xBB 0x061B # ARABIC SEMICOLON +0xBF 0x061F # ARABIC QUESTION MARK +0xC1 0x0621 # ARABIC LETTER HAMZA +0xC2 0x0622 # ARABIC LETTER ALEF WITH MADDA ABOVE +0xC3 0x0623 # ARABIC LETTER ALEF WITH HAMZA ABOVE +0xC4 0x0624 # ARABIC LETTER WAW WITH HAMZA ABOVE +0xC5 0x0625 # ARABIC LETTER ALEF WITH HAMZA BELOW +0xC6 0x0626 # ARABIC LETTER YEH WITH HAMZA ABOVE +0xC7 0x0627 # ARABIC LETTER ALEF +0xC8 0x0628 # ARABIC LETTER BEH +0xC9 0x0629 # ARABIC LETTER TEH MARBUTA +0xCA 0x062A # ARABIC LETTER TEH +0xCB 0x062B # ARABIC LETTER THEH +0xCC 0x062C # ARABIC LETTER JEEM +0xCD 0x062D # ARABIC LETTER HAH +0xCE 0x062E # ARABIC LETTER KHAH +0xCF 0x062F # ARABIC LETTER DAL +0xD0 0x0630 # ARABIC LETTER THAL +0xD1 0x0631 # ARABIC LETTER REH +0xD2 0x0632 # ARABIC LETTER ZAIN +0xD3 0x0633 # ARABIC LETTER SEEN +0xD4 0x0634 # ARABIC LETTER SHEEN +0xD5 0x0635 # ARABIC LETTER SAD +0xD6 0x0636 # ARABIC LETTER DAD +0xD7 0x0637 # ARABIC LETTER TAH +0xD8 0x0638 # ARABIC LETTER ZAH +0xD9 0x0639 # ARABIC LETTER AIN +0xDA 0x063A # ARABIC LETTER GHAIN +0xE0 0x0640 # ARABIC TATWEEL +0xE1 0x0641 # ARABIC LETTER FEH +0xE2 0x0642 # ARABIC LETTER QAF +0xE3 0x0643 # ARABIC LETTER KAF +0xE4 0x0644 # ARABIC LETTER LAM +0xE5 0x0645 # ARABIC LETTER MEEM +0xE6 0x0646 # ARABIC LETTER NOON +0xE7 0x0647 # ARABIC LETTER HEH +0xE8 0x0648 # ARABIC LETTER WAW +0xE9 0x0649 # ARABIC LETTER ALEF MAKSURA +0xEA 0x064A # ARABIC LETTER YEH +0xEB 0x064B # ARABIC FATHATAN +0xEC 0x064C # ARABIC DAMMATAN +0xED 0x064D # ARABIC KASRATAN +0xEE 0x064E # ARABIC FATHA +0xEF 0x064F # ARABIC DAMMA +0xF0 0x0650 # ARABIC KASRA +0xF1 0x0651 # ARABIC SHADDA +0xF2 0x0652 # ARABIC SUKUN diff --git a/data/iso-8859-7.txt b/data/iso-8859-7.txt new file mode 100644 index 0000000000..52c42d08a7 --- /dev/null +++ b/data/iso-8859-7.txt @@ -0,0 +1,302 @@ +# +# Name: ISO 8859-7:1987 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO 8859-7:1987 characters map into Unicode. +# +# ISO 8859-7:1987 is equivalent to ISO-IR-126, ELOT 928, +# and ECMA 118. +# +# Format: Three tab-separated columns +# Column #1 is the ISO 8859-7 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO 8859-7 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# Remap 0xA1 to U+2018 (instead of 0x02BD) to match text of 8859-7 +# Remap 0xA2 to U+2019 (instead of 0x02BC) to match text of 8859-7 +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x2018 # LEFT SINGLE QUOTATION MARK +0xA2 0x2019 # RIGHT SINGLE QUOTATION MARK +0xA3 0x00A3 # POUND SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAF 0x2015 # HORIZONTAL BAR +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x0384 # GREEK TONOS +0xB5 0x0385 # GREEK DIALYTIKA TONOS +0xB6 0x0386 # GREEK CAPITAL LETTER ALPHA WITH TONOS +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x0388 # GREEK CAPITAL LETTER EPSILON WITH TONOS +0xB9 0x0389 # GREEK CAPITAL LETTER ETA WITH TONOS +0xBA 0x038A # GREEK CAPITAL LETTER IOTA WITH TONOS +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x038C # GREEK CAPITAL LETTER OMICRON WITH TONOS +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x038E # GREEK CAPITAL LETTER UPSILON WITH TONOS +0xBF 0x038F # GREEK CAPITAL LETTER OMEGA WITH TONOS +0xC0 0x0390 # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0xC1 0x0391 # GREEK CAPITAL LETTER ALPHA +0xC2 0x0392 # GREEK CAPITAL LETTER BETA +0xC3 0x0393 # GREEK CAPITAL LETTER GAMMA +0xC4 0x0394 # GREEK CAPITAL LETTER DELTA +0xC5 0x0395 # GREEK CAPITAL LETTER EPSILON +0xC6 0x0396 # GREEK CAPITAL LETTER ZETA +0xC7 0x0397 # GREEK CAPITAL LETTER ETA +0xC8 0x0398 # GREEK CAPITAL LETTER THETA +0xC9 0x0399 # GREEK CAPITAL LETTER IOTA +0xCA 0x039A # GREEK CAPITAL LETTER KAPPA +0xCB 0x039B # GREEK CAPITAL LETTER LAMDA +0xCC 0x039C # GREEK CAPITAL LETTER MU +0xCD 0x039D # GREEK CAPITAL LETTER NU +0xCE 0x039E # GREEK CAPITAL LETTER XI +0xCF 0x039F # GREEK CAPITAL LETTER OMICRON +0xD0 0x03A0 # GREEK CAPITAL LETTER PI +0xD1 0x03A1 # GREEK CAPITAL LETTER RHO +0xD3 0x03A3 # GREEK CAPITAL LETTER SIGMA +0xD4 0x03A4 # GREEK CAPITAL LETTER TAU +0xD5 0x03A5 # GREEK CAPITAL LETTER UPSILON +0xD6 0x03A6 # GREEK CAPITAL LETTER PHI +0xD7 0x03A7 # GREEK CAPITAL LETTER CHI +0xD8 0x03A8 # GREEK CAPITAL LETTER PSI +0xD9 0x03A9 # GREEK CAPITAL LETTER OMEGA +0xDA 0x03AA # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +0xDB 0x03AB # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +0xDC 0x03AC # GREEK SMALL LETTER ALPHA WITH TONOS +0xDD 0x03AD # GREEK SMALL LETTER EPSILON WITH TONOS +0xDE 0x03AE # GREEK SMALL LETTER ETA WITH TONOS +0xDF 0x03AF # GREEK SMALL LETTER IOTA WITH TONOS +0xE0 0x03B0 # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +0xE1 0x03B1 # GREEK SMALL LETTER ALPHA +0xE2 0x03B2 # GREEK SMALL LETTER BETA +0xE3 0x03B3 # GREEK SMALL LETTER GAMMA +0xE4 0x03B4 # GREEK SMALL LETTER DELTA +0xE5 0x03B5 # GREEK SMALL LETTER EPSILON +0xE6 0x03B6 # GREEK SMALL LETTER ZETA +0xE7 0x03B7 # GREEK SMALL LETTER ETA +0xE8 0x03B8 # GREEK SMALL LETTER THETA +0xE9 0x03B9 # GREEK SMALL LETTER IOTA +0xEA 0x03BA # GREEK SMALL LETTER KAPPA +0xEB 0x03BB # GREEK SMALL LETTER LAMDA +0xEC 0x03BC # GREEK SMALL LETTER MU +0xED 0x03BD # GREEK SMALL LETTER NU +0xEE 0x03BE # GREEK SMALL LETTER XI +0xEF 0x03BF # GREEK SMALL LETTER OMICRON +0xF0 0x03C0 # GREEK SMALL LETTER PI +0xF1 0x03C1 # GREEK SMALL LETTER RHO +0xF2 0x03C2 # GREEK SMALL LETTER FINAL SIGMA +0xF3 0x03C3 # GREEK SMALL LETTER SIGMA +0xF4 0x03C4 # GREEK SMALL LETTER TAU +0xF5 0x03C5 # GREEK SMALL LETTER UPSILON +0xF6 0x03C6 # GREEK SMALL LETTER PHI +0xF7 0x03C7 # GREEK SMALL LETTER CHI +0xF8 0x03C8 # GREEK SMALL LETTER PSI +0xF9 0x03C9 # GREEK SMALL LETTER OMEGA +0xFA 0x03CA # GREEK SMALL LETTER IOTA WITH DIALYTIKA +0xFB 0x03CB # GREEK SMALL LETTER UPSILON WITH DIALYTIKA +0xFC 0x03CC # GREEK SMALL LETTER OMICRON WITH TONOS +0xFD 0x03CD # GREEK SMALL LETTER UPSILON WITH TONOS +0xFE 0x03CE # GREEK SMALL LETTER OMEGA WITH TONOS diff --git a/data/iso-8859-8.txt b/data/iso-8859-8.txt new file mode 100644 index 0000000000..bc8da4c7fd --- /dev/null +++ b/data/iso-8859-8.txt @@ -0,0 +1,270 @@ +# +# Name: ISO/IEC 8859-8:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.1 +# Table format: Format A +# Date: 2000-Jan-03 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on optical media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-8:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-8 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-8 order. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# 1.1 version updates to the published 8859-8:1999, correcting +# the mapping of 0xAF and adding mappings for LRM and RLM. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00D7 # MULTIPLICATION SIGN +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00F7 # DIVISION SIGN +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xDF 0x2017 # DOUBLE LOW LINE +0xE0 0x05D0 # HEBREW LETTER ALEF +0xE1 0x05D1 # HEBREW LETTER BET +0xE2 0x05D2 # HEBREW LETTER GIMEL +0xE3 0x05D3 # HEBREW LETTER DALET +0xE4 0x05D4 # HEBREW LETTER HE +0xE5 0x05D5 # HEBREW LETTER VAV +0xE6 0x05D6 # HEBREW LETTER ZAYIN +0xE7 0x05D7 # HEBREW LETTER HET +0xE8 0x05D8 # HEBREW LETTER TET +0xE9 0x05D9 # HEBREW LETTER YOD +0xEA 0x05DA # HEBREW LETTER FINAL KAF +0xEB 0x05DB # HEBREW LETTER KAF +0xEC 0x05DC # HEBREW LETTER LAMED +0xED 0x05DD # HEBREW LETTER FINAL MEM +0xEE 0x05DE # HEBREW LETTER MEM +0xEF 0x05DF # HEBREW LETTER FINAL NUN +0xF0 0x05E0 # HEBREW LETTER NUN +0xF1 0x05E1 # HEBREW LETTER SAMEKH +0xF2 0x05E2 # HEBREW LETTER AYIN +0xF3 0x05E3 # HEBREW LETTER FINAL PE +0xF4 0x05E4 # HEBREW LETTER PE +0xF5 0x05E5 # HEBREW LETTER FINAL TSADI +0xF6 0x05E6 # HEBREW LETTER TSADI +0xF7 0x05E7 # HEBREW LETTER QOF +0xF8 0x05E8 # HEBREW LETTER RESH +0xF9 0x05E9 # HEBREW LETTER SHIN +0xFA 0x05EA # HEBREW LETTER TAV +0xFD 0x200E # LEFT-TO-RIGHT MARK +0xFE 0x200F # RIGHT-TO-LEFT MARK + diff --git a/data/iso-8859-9.txt b/data/iso-8859-9.txt new file mode 100644 index 0000000000..22901f1077 --- /dev/null +++ b/data/iso-8859-9.txt @@ -0,0 +1,307 @@ +# +# Name: ISO/IEC 8859-9:1999 to Unicode +# Unicode version: 3.0 +# Table version: 1.0 +# Table format: Format A +# Date: 1999 July 27 +# Authors: Ken Whistler +# +# Copyright (c) 1991-1999 Unicode, Inc. All Rights reserved. +# +# This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +# No claims are made as to fitness for any particular purpose. No +# warranties of any kind are expressed or implied. The recipient +# agrees to determine applicability of information provided. If this +# file has been provided on magnetic media by Unicode, Inc., the sole +# remedy for any claim will be exchange of defective media within 90 +# days of receipt. +# +# Unicode, Inc. hereby grants the right to freely use the information +# supplied in this file in the creation of products supporting the +# Unicode Standard, and to make copies of this file in any form for +# internal or external distribution as long as this notice remains +# attached. +# +# General notes: +# +# This table contains the data the Unicode Consortium has on how +# ISO/IEC 8859-9:1999 characters map into Unicode. +# +# Format: Three tab-separated columns +# Column #1 is the ISO/IEC 8859-9 code (in hex as 0xXX) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 the Unicode name (follows a comment sign, '#') +# +# The entries are in ISO/IEC 8859-9 order. +# +# ISO/IEC 8859-9 is also equivalent to ISO-IR-148. +# +# Version history +# 1.0 version updates 0.1 version by adding mappings for all +# control characters. +# +# Updated versions of this file may be found in: +# +# +# Any comments or problems, contact +# Please note that is an archival address; +# notices will be checked, but do not expect an immediate response. +# +0x00 0x0000 # NULL +0x01 0x0001 # START OF HEADING +0x02 0x0002 # START OF TEXT +0x03 0x0003 # END OF TEXT +0x04 0x0004 # END OF TRANSMISSION +0x05 0x0005 # ENQUIRY +0x06 0x0006 # ACKNOWLEDGE +0x07 0x0007 # BELL +0x08 0x0008 # BACKSPACE +0x09 0x0009 # HORIZONTAL TABULATION +0x0A 0x000A # LINE FEED +0x0B 0x000B # VERTICAL TABULATION +0x0C 0x000C # FORM FEED +0x0D 0x000D # CARRIAGE RETURN +0x0E 0x000E # SHIFT OUT +0x0F 0x000F # SHIFT IN +0x10 0x0010 # DATA LINK ESCAPE +0x11 0x0011 # DEVICE CONTROL ONE +0x12 0x0012 # DEVICE CONTROL TWO +0x13 0x0013 # DEVICE CONTROL THREE +0x14 0x0014 # DEVICE CONTROL FOUR +0x15 0x0015 # NEGATIVE ACKNOWLEDGE +0x16 0x0016 # SYNCHRONOUS IDLE +0x17 0x0017 # END OF TRANSMISSION BLOCK +0x18 0x0018 # CANCEL +0x19 0x0019 # END OF MEDIUM +0x1A 0x001A # SUBSTITUTE +0x1B 0x001B # ESCAPE +0x1C 0x001C # FILE SEPARATOR +0x1D 0x001D # GROUP SEPARATOR +0x1E 0x001E # RECORD SEPARATOR +0x1F 0x001F # UNIT SEPARATOR +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x7F 0x007F # DELETE +0x80 0x0080 # +0x81 0x0081 # +0x82 0x0082 # +0x83 0x0083 # +0x84 0x0084 # +0x85 0x0085 # +0x86 0x0086 # +0x87 0x0087 # +0x88 0x0088 # +0x89 0x0089 # +0x8A 0x008A # +0x8B 0x008B # +0x8C 0x008C # +0x8D 0x008D # +0x8E 0x008E # +0x8F 0x008F # +0x90 0x0090 # +0x91 0x0091 # +0x92 0x0092 # +0x93 0x0093 # +0x94 0x0094 # +0x95 0x0095 # +0x96 0x0096 # +0x97 0x0097 # +0x98 0x0098 # +0x99 0x0099 # +0x9A 0x009A # +0x9B 0x009B # +0x9C 0x009C # +0x9D 0x009D # +0x9E 0x009E # +0x9F 0x009F # +0xA0 0x00A0 # NO-BREAK SPACE +0xA1 0x00A1 # INVERTED EXCLAMATION MARK +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A4 # CURRENCY SIGN +0xA5 0x00A5 # YEN SIGN +0xA6 0x00A6 # BROKEN BAR +0xA7 0x00A7 # SECTION SIGN +0xA8 0x00A8 # DIAERESIS +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x00AA # FEMININE ORDINAL INDICATOR +0xAB 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC # NOT SIGN +0xAD 0x00AD # SOFT HYPHEN +0xAE 0x00AE # REGISTERED SIGN +0xAF 0x00AF # MACRON +0xB0 0x00B0 # DEGREE SIGN +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x00B2 # SUPERSCRIPT TWO +0xB3 0x00B3 # SUPERSCRIPT THREE +0xB4 0x00B4 # ACUTE ACCENT +0xB5 0x00B5 # MICRO SIGN +0xB6 0x00B6 # PILCROW SIGN +0xB7 0x00B7 # MIDDLE DOT +0xB8 0x00B8 # CEDILLA +0xB9 0x00B9 # SUPERSCRIPT ONE +0xBA 0x00BA # MASCULINE ORDINAL INDICATOR +0xBB 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC # VULGAR FRACTION ONE QUARTER +0xBD 0x00BD # VULGAR FRACTION ONE HALF +0xBE 0x00BE # VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF # INVERTED QUESTION MARK +0xC0 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 # LATIN CAPITAL LETTER AE +0xC7 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x011E # LATIN CAPITAL LETTER G WITH BREVE +0xD1 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 # MULTIPLICATION SIGN +0xD8 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0130 # LATIN CAPITAL LETTER I WITH DOT ABOVE +0xDE 0x015E # LATIN CAPITAL LETTER S WITH CEDILLA +0xDF 0x00DF # LATIN SMALL LETTER SHARP S +0xE0 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 # LATIN SMALL LETTER AE +0xE7 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x011F # LATIN SMALL LETTER G WITH BREVE +0xF1 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 # DIVISION SIGN +0xF8 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0131 # LATIN SMALL LETTER DOTLESS I +0xFE 0x015F # LATIN SMALL LETTER S WITH CEDILLA +0xFF 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS + + diff --git a/data/jis-x0213.txt b/data/jis-x0213.txt new file mode 100644 index 0000000000..826c9b6d43 --- /dev/null +++ b/data/jis-x0213.txt @@ -0,0 +1,11425 @@ +# JIS-X0213 aka Shift JIS character mapping table +0x00 0x0000 +0x01 0x0001 +0x02 0x0002 +0x03 0x0003 +0x04 0x0004 +0x05 0x0005 +0x06 0x0006 +0x07 0x0007 +0x08 0x0008 +0x09 0x0009 +0x0a 0x000a +0x0b 0x000b +0x0c 0x000c +0x0d 0x000d +0x0e 0x000e +0x0f 0x000f +0x10 0x0010 +0x11 0x0011 +0x12 0x0012 +0x13 0x0013 +0x14 0x0014 +0x15 0x0015 +0x16 0x0016 +0x17 0x0017 +0x18 0x0018 +0x19 0x0019 +0x1a 0x001a +0x1b 0x001b +0x1c 0x001c +0x1d 0x001d +0x1e 0x001e +0x1f 0x001f +0x20 0x0020 +0x21 0x0021 +0x22 0x0022 +0x23 0x0023 +0x24 0x0024 +0x25 0x0025 +0x26 0x0026 +0x27 0x0027 +0x28 0x0028 +0x29 0x0029 +0x2a 0x002a +0x2b 0x002b +0x2c 0x002c +0x2d 0x002d +0x2e 0x002e +0x2f 0x002f +0x30 0x0030 +0x31 0x0031 +0x32 0x0032 +0x33 0x0033 +0x34 0x0034 +0x35 0x0035 +0x36 0x0036 +0x37 0x0037 +0x38 0x0038 +0x39 0x0039 +0x3a 0x003a +0x3b 0x003b +0x3c 0x003c +0x3d 0x003d +0x3e 0x003e +0x3f 0x003f +0x40 0x0040 +0x41 0x0041 +0x42 0x0042 +0x43 0x0043 +0x44 0x0044 +0x45 0x0045 +0x46 0x0046 +0x47 0x0047 +0x48 0x0048 +0x49 0x0049 +0x4a 0x004a +0x4b 0x004b +0x4c 0x004c +0x4d 0x004d +0x4e 0x004e +0x4f 0x004f +0x50 0x0050 +0x51 0x0051 +0x52 0x0052 +0x53 0x0053 +0x54 0x0054 +0x55 0x0055 +0x56 0x0056 +0x57 0x0057 +0x58 0x0058 +0x59 0x0059 +0x5a 0x005a +0x5b 0x005b +0x5c 0x00a5 +0x5d 0x005d +0x5e 0x005e +0x5f 0x005f +0x60 0x0060 +0x61 0x0061 +0x62 0x0062 +0x63 0x0063 +0x64 0x0064 +0x65 0x0065 +0x66 0x0066 +0x67 0x0067 +0x68 0x0068 +0x69 0x0069 +0x6a 0x006a +0x6b 0x006b +0x6c 0x006c +0x6d 0x006d +0x6e 0x006e +0x6f 0x006f +0x70 0x0070 +0x71 0x0071 +0x72 0x0072 +0x73 0x0073 +0x74 0x0074 +0x75 0x0075 +0x76 0x0076 +0x77 0x0077 +0x78 0x0078 +0x79 0x0079 +0x7a 0x007a +0x7b 0x007b +0x7c 0x007c +0x7d 0x007d +0x7e 0x203e +0x7f 0x007f +0xa1 0xff61 +0xa2 0xff62 +0xa3 0xff63 +0xa4 0xff64 +0xa5 0xff65 +0xa6 0xff66 +0xa7 0xff67 +0xa8 0xff68 +0xa9 0xff69 +0xaa 0xff6a +0xab 0xff6b +0xac 0xff6c +0xad 0xff6d +0xae 0xff6e +0xaf 0xff6f +0xb0 0xff70 +0xb1 0xff71 +0xb2 0xff72 +0xb3 0xff73 +0xb4 0xff74 +0xb5 0xff75 +0xb6 0xff76 +0xb7 0xff77 +0xb8 0xff78 +0xb9 0xff79 +0xba 0xff7a +0xbb 0xff7b +0xbc 0xff7c +0xbd 0xff7d +0xbe 0xff7e +0xbf 0xff7f +0xc0 0xff80 +0xc1 0xff81 +0xc2 0xff82 +0xc3 0xff83 +0xc4 0xff84 +0xc5 0xff85 +0xc6 0xff86 +0xc7 0xff87 +0xc8 0xff88 +0xc9 0xff89 +0xca 0xff8a +0xcb 0xff8b +0xcc 0xff8c +0xcd 0xff8d +0xce 0xff8e +0xcf 0xff8f +0xd0 0xff90 +0xd1 0xff91 +0xd2 0xff92 +0xd3 0xff93 +0xd4 0xff94 +0xd5 0xff95 +0xd6 0xff96 +0xd7 0xff97 +0xd8 0xff98 +0xd9 0xff99 +0xda 0xff9a +0xdb 0xff9b +0xdc 0xff9c +0xdd 0xff9d +0xde 0xff9e +0xdf 0xff9f +0x8140 0x3000 +0x8141 0x3001 +0x8142 0x3002 +0x8143 0xff0c +0x8144 0xff0e +0x8145 0x30fb +0x8146 0xff1a +0x8147 0xff1b +0x8148 0xff1f +0x8149 0xff01 +0x814a 0x309b +0x814b 0x309c +0x814c 0x00b4 +0x814d 0xff40 +0x814e 0x00a8 +0x814f 0xff3e +0x8150 0xffe3 +0x8151 0xff3f +0x8152 0x30fd +0x8153 0x30fe +0x8154 0x309d +0x8155 0x309e +0x8156 0x3003 +0x8157 0x4edd +0x8158 0x3005 +0x8159 0x3006 +0x815a 0x3007 +0x815b 0x30fc +0x815c 0x2014 +0x815d 0x2010 +0x815e 0xff0f +0x815f 0x005c +0x8160 0x301c +0x8161 0x2016 +0x8162 0xff5c +0x8163 0x2026 +0x8164 0x2025 +0x8165 0x2018 +0x8166 0x2019 +0x8167 0x201c +0x8168 0x201d +0x8169 0xff08 +0x816a 0xff09 +0x816b 0x3014 +0x816c 0x3015 +0x816d 0xff3b +0x816e 0xff3d +0x816f 0xff5b +0x8170 0xff5d +0x8171 0x3008 +0x8172 0x3009 +0x8173 0x300a +0x8174 0x300b +0x8175 0x300c +0x8176 0x300d +0x8177 0x300e +0x8178 0x300f +0x8179 0x3010 +0x817a 0x3011 +0x817b 0xff0b +0x817c 0x2212 +0x817d 0x00b1 +0x817e 0x00d7 +0x8180 0x00f7 +0x8181 0xff1d +0x8182 0x2260 +0x8183 0xff1c +0x8184 0xff1e +0x8185 0x2266 +0x8186 0x2267 +0x8187 0x221e +0x8188 0x2234 +0x8189 0x2642 +0x818a 0x2640 +0x818b 0x00b0 +0x818c 0x2032 +0x818d 0x2033 +0x818e 0x2103 +0x818f 0xffe5 +0x8190 0xff04 +0x8191 0x00a2 +0x8192 0x00a3 +0x8193 0xff05 +0x8194 0xff03 +0x8195 0xff06 +0x8196 0xff0a +0x8197 0xff20 +0x8198 0x00a7 +0x8199 0x2606 +0x819a 0x2605 +0x819b 0x25cb +0x819c 0x25cf +0x819d 0x25ce +0x819e 0x25c7 +0x819f 0x25c6 +0x81a0 0x25a1 +0x81a1 0x25a0 +0x81a2 0x25b3 +0x81a3 0x25b2 +0x81a4 0x25bd +0x81a5 0x25bc +0x81a6 0x203b +0x81a7 0x3012 +0x81a8 0x2192 +0x81a9 0x2190 +0x81aa 0x2191 +0x81ab 0x2193 +0x81ac 0x3013 +0x81ad 0xff07 +0x81ae 0xff02 +0x81af 0xff0d +0x81b0 0x007e +0x81b1 0x3033 +0x81b2 0x3034 +0x81b3 0x3035 +0x81b4 0x303b +0x81b5 0x303c +0x81b6 0x30ff +0x81b7 0x309f +0x81b8 0x2208 +0x81b9 0x220b +0x81ba 0x2286 +0x81bb 0x2287 +0x81bc 0x2282 +0x81bd 0x2283 +0x81be 0x222a +0x81bf 0x2229 +0x81c0 0x2284 +0x81c1 0x2285 +0x81c2 0x228a +0x81c3 0x228b +0x81c4 0x2209 +0x81c5 0x2205 +0x81c6 0x2305 +0x81c7 0x2306 +0x81c8 0x2227 +0x81c9 0x2228 +0x81ca 0x00ac +0x81cb 0x21d2 +0x81cc 0x21d4 +0x81cd 0x2200 +0x81ce 0x2203 +0x81cf 0x2295 +0x81d0 0x2296 +0x81d1 0x2297 +0x81d2 0x2225 +0x81d3 0x2226 +0x81d4 0xff5f +0x81d5 0xff60 +0x81d6 0x3018 +0x81d7 0x3019 +0x81d8 0x3016 +0x81d9 0x3017 +0x81da 0x2220 +0x81db 0x22a5 +0x81dc 0x2312 +0x81dd 0x2202 +0x81de 0x2207 +0x81df 0x2261 +0x81e0 0x2252 +0x81e1 0x226a +0x81e2 0x226b +0x81e3 0x221a +0x81e4 0x223d +0x81e5 0x221d +0x81e6 0x2235 +0x81e7 0x222b +0x81e8 0x222c +0x81e9 0x2262 +0x81ea 0x2243 +0x81eb 0x2245 +0x81ec 0x2248 +0x81ed 0x2276 +0x81ee 0x2277 +0x81ef 0x2194 +0x81f0 0x212b +0x81f1 0x2030 +0x81f2 0x266f +0x81f3 0x266d +0x81f4 0x266a +0x81f5 0x2020 +0x81f6 0x2021 +0x81f7 0x00b6 +0x81f8 0x266e +0x81f9 0x266b +0x81fa 0x266c +0x81fb 0x2669 +0x81fc 0x25ef +0x8240 0x25b7 +0x8241 0x25b6 +0x8242 0x25c1 +0x8243 0x25c0 +0x8244 0x2197 +0x8245 0x2198 +0x8246 0x2196 +0x8247 0x2199 +0x8248 0x21c4 +0x8249 0x21e8 +0x824a 0x21e6 +0x824b 0x21e7 +0x824c 0x21e9 +0x824d 0x2934 +0x824e 0x2935 +0x824f 0xff10 +0x8250 0xff11 +0x8251 0xff12 +0x8252 0xff13 +0x8253 0xff14 +0x8254 0xff15 +0x8255 0xff16 +0x8256 0xff17 +0x8257 0xff18 +0x8258 0xff19 +0x8259 0x29bf +0x825a 0x25c9 +0x825b 0x303d +0x825c 0xfe46 +0x825d 0xfe45 +0x825e 0x25e6 +0x825f 0x2022 +0x8260 0xff21 +0x8261 0xff22 +0x8262 0xff23 +0x8263 0xff24 +0x8264 0xff25 +0x8265 0xff26 +0x8266 0xff27 +0x8267 0xff28 +0x8268 0xff29 +0x8269 0xff2a +0x826a 0xff2b +0x826b 0xff2c +0x826c 0xff2d +0x826d 0xff2e +0x826e 0xff2f +0x826f 0xff30 +0x8270 0xff31 +0x8271 0xff32 +0x8272 0xff33 +0x8273 0xff34 +0x8274 0xff35 +0x8275 0xff36 +0x8276 0xff37 +0x8277 0xff38 +0x8278 0xff39 +0x8279 0xff3a +0x827a 0x2213 +0x827b 0x2135 +0x827c 0x210f +0x827d 0x33cb +0x827e 0x2113 +0x8280 0x2127 +0x8281 0xff41 +0x8282 0xff42 +0x8283 0xff43 +0x8284 0xff44 +0x8285 0xff45 +0x8286 0xff46 +0x8287 0xff47 +0x8288 0xff48 +0x8289 0xff49 +0x828a 0xff4a +0x828b 0xff4b +0x828c 0xff4c +0x828d 0xff4d +0x828e 0xff4e +0x828f 0xff4f +0x8290 0xff50 +0x8291 0xff51 +0x8292 0xff52 +0x8293 0xff53 +0x8294 0xff54 +0x8295 0xff55 +0x8296 0xff56 +0x8297 0xff57 +0x8298 0xff58 +0x8299 0xff59 +0x829a 0xff5a +0x829b 0x30a0 +0x829c 0x2013 +0x829d 0x29fa +0x829e 0x29fb +0x829f 0x3041 +0x82a0 0x3042 +0x82a1 0x3043 +0x82a2 0x3044 +0x82a3 0x3045 +0x82a4 0x3046 +0x82a5 0x3047 +0x82a6 0x3048 +0x82a7 0x3049 +0x82a8 0x304a +0x82a9 0x304b +0x82aa 0x304c +0x82ab 0x304d +0x82ac 0x304e +0x82ad 0x304f +0x82ae 0x3050 +0x82af 0x3051 +0x82b0 0x3052 +0x82b1 0x3053 +0x82b2 0x3054 +0x82b3 0x3055 +0x82b4 0x3056 +0x82b5 0x3057 +0x82b6 0x3058 +0x82b7 0x3059 +0x82b8 0x305a +0x82b9 0x305b +0x82ba 0x305c +0x82bb 0x305d +0x82bc 0x305e +0x82bd 0x305f +0x82be 0x3060 +0x82bf 0x3061 +0x82c0 0x3062 +0x82c1 0x3063 +0x82c2 0x3064 +0x82c3 0x3065 +0x82c4 0x3066 +0x82c5 0x3067 +0x82c6 0x3068 +0x82c7 0x3069 +0x82c8 0x306a +0x82c9 0x306b +0x82ca 0x306c +0x82cb 0x306d +0x82cc 0x306e +0x82cd 0x306f +0x82ce 0x3070 +0x82cf 0x3071 +0x82d0 0x3072 +0x82d1 0x3073 +0x82d2 0x3074 +0x82d3 0x3075 +0x82d4 0x3076 +0x82d5 0x3077 +0x82d6 0x3078 +0x82d7 0x3079 +0x82d8 0x307a +0x82d9 0x307b +0x82da 0x307c +0x82db 0x307d +0x82dc 0x307e +0x82dd 0x307f +0x82de 0x3080 +0x82df 0x3081 +0x82e0 0x3082 +0x82e1 0x3083 +0x82e2 0x3084 +0x82e3 0x3085 +0x82e4 0x3086 +0x82e5 0x3087 +0x82e6 0x3088 +0x82e7 0x3089 +0x82e8 0x308a +0x82e9 0x308b +0x82ea 0x308c +0x82eb 0x308d +0x82ec 0x308e +0x82ed 0x308f +0x82ee 0x3090 +0x82ef 0x3091 +0x82f0 0x3092 +0x82f1 0x3093 +0x82f2 0x3094 +0x82f3 0x3095 +0x82f4 0x3096 +0x82f5 0x304b +0x82f6 0x304d +0x82f7 0x304f +0x82f8 0x3051 +0x82f9 0x3053 +0x8340 0x30a1 +0x8341 0x30a2 +0x8342 0x30a3 +0x8343 0x30a4 +0x8344 0x30a5 +0x8345 0x30a6 +0x8346 0x30a7 +0x8347 0x30a8 +0x8348 0x30a9 +0x8349 0x30aa +0x834a 0x30ab +0x834b 0x30ac +0x834c 0x30ad +0x834d 0x30ae +0x834e 0x30af +0x834f 0x30b0 +0x8350 0x30b1 +0x8351 0x30b2 +0x8352 0x30b3 +0x8353 0x30b4 +0x8354 0x30b5 +0x8355 0x30b6 +0x8356 0x30b7 +0x8357 0x30b8 +0x8358 0x30b9 +0x8359 0x30ba +0x835a 0x30bb +0x835b 0x30bc +0x835c 0x30bd +0x835d 0x30be +0x835e 0x30bf +0x835f 0x30c0 +0x8360 0x30c1 +0x8361 0x30c2 +0x8362 0x30c3 +0x8363 0x30c4 +0x8364 0x30c5 +0x8365 0x30c6 +0x8366 0x30c7 +0x8367 0x30c8 +0x8368 0x30c9 +0x8369 0x30ca +0x836a 0x30cb +0x836b 0x30cc +0x836c 0x30cd +0x836d 0x30ce +0x836e 0x30cf +0x836f 0x30d0 +0x8370 0x30d1 +0x8371 0x30d2 +0x8372 0x30d3 +0x8373 0x30d4 +0x8374 0x30d5 +0x8375 0x30d6 +0x8376 0x30d7 +0x8377 0x30d8 +0x8378 0x30d9 +0x8379 0x30da +0x837a 0x30db +0x837b 0x30dc +0x837c 0x30dd +0x837d 0x30de +0x837e 0x30df +0x8380 0x30e0 +0x8381 0x30e1 +0x8382 0x30e2 +0x8383 0x30e3 +0x8384 0x30e4 +0x8385 0x30e5 +0x8386 0x30e6 +0x8387 0x30e7 +0x8388 0x30e8 +0x8389 0x30e9 +0x838a 0x30ea +0x838b 0x30eb +0x838c 0x30ec +0x838d 0x30ed +0x838e 0x30ee +0x838f 0x30ef +0x8390 0x30f0 +0x8391 0x30f1 +0x8392 0x30f2 +0x8393 0x30f3 +0x8394 0x30f4 +0x8395 0x30f5 +0x8396 0x30f6 +0x8397 0x30ab +0x8398 0x30ad +0x8399 0x30af +0x839a 0x30b1 +0x839b 0x30b3 +0x839c 0x30bb +0x839d 0x30c4 +0x839e 0x30c8 +0x839f 0x0391 +0x83a0 0x0392 +0x83a1 0x0393 +0x83a2 0x0394 +0x83a3 0x0395 +0x83a4 0x0396 +0x83a5 0x0397 +0x83a6 0x0398 +0x83a7 0x0399 +0x83a8 0x039a +0x83a9 0x039b +0x83aa 0x039c +0x83ab 0x039d +0x83ac 0x039e +0x83ad 0x039f +0x83ae 0x03a0 +0x83af 0x03a1 +0x83b0 0x03a3 +0x83b1 0x03a4 +0x83b2 0x03a5 +0x83b3 0x03a6 +0x83b4 0x03a7 +0x83b5 0x03a8 +0x83b6 0x03a9 +0x83b7 0x2664 +0x83b8 0x2660 +0x83b9 0x2662 +0x83ba 0x2666 +0x83bb 0x2661 +0x83bc 0x2665 +0x83bd 0x2667 +0x83be 0x2663 +0x83bf 0x03b1 +0x83c0 0x03b2 +0x83c1 0x03b3 +0x83c2 0x03b4 +0x83c3 0x03b5 +0x83c4 0x03b6 +0x83c5 0x03b7 +0x83c6 0x03b8 +0x83c7 0x03b9 +0x83c8 0x03ba +0x83c9 0x03bb +0x83ca 0x03bc +0x83cb 0x03bd +0x83cc 0x03be +0x83cd 0x03bf +0x83ce 0x03c0 +0x83cf 0x03c1 +0x83d0 0x03c3 +0x83d1 0x03c4 +0x83d2 0x03c5 +0x83d3 0x03c6 +0x83d4 0x03c7 +0x83d5 0x03c8 +0x83d6 0x03c9 +0x83d7 0x03c2 +0x83d8 0x24f5 +0x83d9 0x24f6 +0x83da 0x24f7 +0x83db 0x24f8 +0x83dc 0x24f9 +0x83dd 0x24fa +0x83de 0x24fb +0x83df 0x24fc +0x83e0 0x24fd +0x83e1 0x24fe +0x83e2 0x2616 +0x83e3 0x2617 +0x83e4 0x3020 +0x83e5 0x260e +0x83e6 0x2600 +0x83e7 0x2601 +0x83e8 0x2602 +0x83e9 0x2603 +0x83ea 0x2668 +0x83eb 0x25b1 +0x83ec 0x31f0 +0x83ed 0x31f1 +0x83ee 0x31f2 +0x83ef 0x31f3 +0x83f0 0x31f4 +0x83f1 0x31f5 +0x83f2 0x31f6 +0x83f3 0x31f7 +0x83f4 0x31f8 +0x83f5 0x31f9 +0x83f6 0x31f7 +0x83f7 0x31fa +0x83f8 0x31fb +0x83f9 0x31fc +0x83fa 0x31fd +0x83fb 0x31fe +0x83fc 0x31ff +0x8440 0x0410 +0x8441 0x0411 +0x8442 0x0412 +0x8443 0x0413 +0x8444 0x0414 +0x8445 0x0415 +0x8446 0x0401 +0x8447 0x0416 +0x8448 0x0417 +0x8449 0x0418 +0x844a 0x0419 +0x844b 0x041a +0x844c 0x041b +0x844d 0x041c +0x844e 0x041d +0x844f 0x041e +0x8450 0x041f +0x8451 0x0420 +0x8452 0x0421 +0x8453 0x0422 +0x8454 0x0423 +0x8455 0x0424 +0x8456 0x0425 +0x8457 0x0426 +0x8458 0x0427 +0x8459 0x0428 +0x845a 0x0429 +0x845b 0x042a +0x845c 0x042b +0x845d 0x042c +0x845e 0x042d +0x845f 0x042e +0x8460 0x042f +0x8461 0x23be +0x8462 0x23bf +0x8463 0x23c0 +0x8464 0x23c1 +0x8465 0x23c2 +0x8466 0x23c3 +0x8467 0x23c4 +0x8468 0x23c5 +0x8469 0x23c6 +0x846a 0x23c7 +0x846b 0x23c8 +0x846c 0x23c9 +0x846d 0x23ca +0x846e 0x23cb +0x846f 0x23cc +0x8470 0x0430 +0x8471 0x0431 +0x8472 0x0432 +0x8473 0x0433 +0x8474 0x0434 +0x8475 0x0435 +0x8476 0x0451 +0x8477 0x0436 +0x8478 0x0437 +0x8479 0x0438 +0x847a 0x0439 +0x847b 0x043a +0x847c 0x043b +0x847d 0x043c +0x847e 0x043d +0x8480 0x043e +0x8481 0x043f +0x8482 0x0440 +0x8483 0x0441 +0x8484 0x0442 +0x8485 0x0443 +0x8486 0x0444 +0x8487 0x0445 +0x8488 0x0446 +0x8489 0x0447 +0x848a 0x0448 +0x848b 0x0449 +0x848c 0x044a +0x848d 0x044b +0x848e 0x044c +0x848f 0x044d +0x8490 0x044e +0x8491 0x044f +0x8492 0x30f7 +0x8493 0x30f8 +0x8494 0x30f9 +0x8495 0x30fa +0x8496 0x22da +0x8497 0x22db +0x8498 0x2153 +0x8499 0x2154 +0x849a 0x2155 +0x849b 0x2713 +0x849c 0x2318 +0x849d 0x2423 +0x849e 0x23ce +0x849f 0x2500 +0x84a0 0x2502 +0x84a1 0x250c +0x84a2 0x2510 +0x84a3 0x2518 +0x84a4 0x2514 +0x84a5 0x251c +0x84a6 0x252c +0x84a7 0x2524 +0x84a8 0x2534 +0x84a9 0x253c +0x84aa 0x2501 +0x84ab 0x2503 +0x84ac 0x250f +0x84ad 0x2513 +0x84ae 0x251b +0x84af 0x2517 +0x84b0 0x2523 +0x84b1 0x2533 +0x84b2 0x252b +0x84b3 0x253b +0x84b4 0x254b +0x84b5 0x2520 +0x84b6 0x252f +0x84b7 0x2528 +0x84b8 0x2537 +0x84b9 0x253f +0x84ba 0x251d +0x84bb 0x2530 +0x84bc 0x2525 +0x84bd 0x2538 +0x84be 0x2542 +0x84bf 0x3251 +0x84c0 0x3252 +0x84c1 0x3253 +0x84c2 0x3254 +0x84c3 0x3255 +0x84c4 0x3256 +0x84c5 0x3257 +0x84c6 0x3258 +0x84c7 0x3259 +0x84c8 0x325a +0x84c9 0x325b +0x84ca 0x325c +0x84cb 0x325d +0x84cc 0x325e +0x84cd 0x325f +0x84ce 0x32b1 +0x84cf 0x32b2 +0x84d0 0x32b3 +0x84d1 0x32b4 +0x84d2 0x32b5 +0x84d3 0x32b6 +0x84d4 0x32b7 +0x84d5 0x32b8 +0x84d6 0x32b9 +0x84d7 0x32ba +0x84d8 0x32bb +0x84d9 0x32bc +0x84da 0x32bd +0x84db 0x32be +0x84dc 0x32bf +0x84e5 0x25d0 +0x84e6 0x25d1 +0x84e7 0x25d2 +0x84e8 0x25d3 +0x84e9 0x203c +0x84ea 0x2047 +0x84eb 0x2048 +0x84ec 0x2049 +0x84ed 0x01cd +0x84ee 0x01ce +0x84ef 0x01d0 +0x84f0 0x1e3e +0x84f1 0x1e3f +0x84f2 0x01f8 +0x84f3 0x01f9 +0x84f4 0x01d1 +0x84f5 0x01d2 +0x84f6 0x01d4 +0x84f7 0x01d6 +0x84f8 0x01d8 +0x84f9 0x01da +0x84fa 0x01dc +0x8540 0x20ac +0x8541 0x00a0 +0x8542 0x00a1 +0x8543 0x00a4 +0x8544 0x00a6 +0x8545 0x00a9 +0x8546 0x00aa +0x8547 0x00ab +0x8548 0x00ad +0x8549 0x00ae +0x854a 0x00af +0x854b 0x00b2 +0x854c 0x00b3 +0x854d 0x00b7 +0x854e 0x00b8 +0x854f 0x00b9 +0x8550 0x00ba +0x8551 0x00bb +0x8552 0x00bc +0x8553 0x00bd +0x8554 0x00be +0x8555 0x00bf +0x8556 0x00c0 +0x8557 0x00c1 +0x8558 0x00c2 +0x8559 0x00c3 +0x855a 0x00c4 +0x855b 0x00c5 +0x855c 0x00c6 +0x855d 0x00c7 +0x855e 0x00c8 +0x855f 0x00c9 +0x8560 0x00ca +0x8561 0x00cb +0x8562 0x00cc +0x8563 0x00cd +0x8564 0x00ce +0x8565 0x00cf +0x8566 0x00d0 +0x8567 0x00d1 +0x8568 0x00d2 +0x8569 0x00d3 +0x856a 0x00d4 +0x856b 0x00d5 +0x856c 0x00d6 +0x856d 0x00d8 +0x856e 0x00d9 +0x856f 0x00da +0x8570 0x00db +0x8571 0x00dc +0x8572 0x00dd +0x8573 0x00de +0x8574 0x00df +0x8575 0x00e0 +0x8576 0x00e1 +0x8577 0x00e2 +0x8578 0x00e3 +0x8579 0x00e4 +0x857a 0x00e5 +0x857b 0x00e6 +0x857c 0x00e7 +0x857d 0x00e8 +0x857e 0x00e9 +0x8580 0x00ea +0x8581 0x00eb +0x8582 0x00ec +0x8583 0x00ed +0x8584 0x00ee +0x8585 0x00ef +0x8586 0x00f0 +0x8587 0x00f1 +0x8588 0x00f2 +0x8589 0x00f3 +0x858a 0x00f4 +0x858b 0x00f5 +0x858c 0x00f6 +0x858d 0x00f8 +0x858e 0x00f9 +0x858f 0x00fa +0x8590 0x00fb +0x8591 0x00fc +0x8592 0x00fd +0x8593 0x00fe +0x8594 0x00ff +0x8595 0x0100 +0x8596 0x012a +0x8597 0x016a +0x8598 0x0112 +0x8599 0x014c +0x859a 0x0101 +0x859b 0x012b +0x859c 0x016b +0x859d 0x0113 +0x859e 0x014d +0x859f 0x0104 +0x85a0 0x02d8 +0x85a1 0x0141 +0x85a2 0x013d +0x85a3 0x015a +0x85a4 0x0160 +0x85a5 0x015e +0x85a6 0x0164 +0x85a7 0x0179 +0x85a8 0x017d +0x85a9 0x017b +0x85aa 0x0105 +0x85ab 0x02db +0x85ac 0x0142 +0x85ad 0x013e +0x85ae 0x015b +0x85af 0x02c7 +0x85b0 0x0161 +0x85b1 0x015f +0x85b2 0x0165 +0x85b3 0x017a +0x85b4 0x02dd +0x85b5 0x017e +0x85b6 0x017c +0x85b7 0x0154 +0x85b8 0x0102 +0x85b9 0x0139 +0x85ba 0x0106 +0x85bb 0x010c +0x85bc 0x0118 +0x85bd 0x011a +0x85be 0x010e +0x85bf 0x0143 +0x85c0 0x0147 +0x85c1 0x0150 +0x85c2 0x0158 +0x85c3 0x016e +0x85c4 0x0170 +0x85c5 0x0162 +0x85c6 0x0155 +0x85c7 0x0103 +0x85c8 0x013a +0x85c9 0x0107 +0x85ca 0x010d +0x85cb 0x0119 +0x85cc 0x011b +0x85cd 0x010f +0x85ce 0x0111 +0x85cf 0x0144 +0x85d0 0x0148 +0x85d1 0x0151 +0x85d2 0x0159 +0x85d3 0x016f +0x85d4 0x0171 +0x85d5 0x0163 +0x85d6 0x02d9 +0x85d7 0x0108 +0x85d8 0x011c +0x85d9 0x0124 +0x85da 0x0134 +0x85db 0x015c +0x85dc 0x016c +0x85dd 0x0109 +0x85de 0x011d +0x85df 0x0125 +0x85e0 0x0135 +0x85e1 0x015d +0x85e2 0x016d +0x85e3 0x0271 +0x85e4 0x028b +0x85e5 0x027e +0x85e6 0x0283 +0x85e7 0x0292 +0x85e8 0x026c +0x85e9 0x026e +0x85ea 0x0279 +0x85eb 0x0288 +0x85ec 0x0256 +0x85ed 0x0273 +0x85ee 0x027d +0x85ef 0x0282 +0x85f0 0x0290 +0x85f1 0x027b +0x85f2 0x026d +0x85f3 0x025f +0x85f4 0x0272 +0x85f5 0x029d +0x85f6 0x028e +0x85f7 0x0261 +0x85f8 0x014b +0x85f9 0x0270 +0x85fa 0x0281 +0x85fb 0x0127 +0x85fc 0x0295 +0x8640 0x0294 +0x8641 0x0266 +0x8642 0x0298 +0x8643 0x01c2 +0x8644 0x0253 +0x8645 0x0257 +0x8646 0x0284 +0x8647 0x0260 +0x8648 0x0193 +0x8649 0x0153 +0x864a 0x0152 +0x864b 0x0268 +0x864c 0x0289 +0x864d 0x0258 +0x864e 0x0275 +0x864f 0x0259 +0x8650 0x025c +0x8651 0x025e +0x8652 0x0250 +0x8653 0x026f +0x8654 0x028a +0x8655 0x0264 +0x8656 0x028c +0x8657 0x0254 +0x8658 0x0251 +0x8659 0x0252 +0x865a 0x028d +0x865b 0x0265 +0x865c 0x02a2 +0x865d 0x02a1 +0x865e 0x0255 +0x865f 0x0291 +0x8660 0x027a +0x8661 0x0267 +0x8662 0x025a +0x8663 0x00e6 +0x8664 0x01fd +0x8665 0x1f70 +0x8666 0x1f71 +0x8667 0x0254 +0x8668 0x0254 +0x8669 0x028c +0x866a 0x028c +0x866b 0x0259 +0x866c 0x0259 +0x866d 0x025a +0x866e 0x025a +0x866f 0x1f72 +0x8670 0x1f73 +0x8671 0x0361 +0x8672 0x02c8 +0x8673 0x02cc +0x8674 0x02d0 +0x8675 0x02d1 +0x8676 0x0306 +0x8677 0x203f +0x8678 0x030b +0x8679 0x0301 +0x867a 0x0304 +0x867b 0x0300 +0x867c 0x030f +0x867d 0x030c +0x867e 0x0302 +0x8680 0x02e5 +0x8681 0x02e6 +0x8682 0x02e7 +0x8683 0x02e8 +0x8684 0x02e9 +0x8685 0x02e9 +0x8686 0x02e5 +0x8687 0x0325 +0x8688 0x032c +0x8689 0x0339 +0x868a 0x031c +0x868b 0x031f +0x868c 0x0320 +0x868d 0x0308 +0x868e 0x033d +0x868f 0x0329 +0x8690 0x032f +0x8691 0x02de +0x8692 0x0324 +0x8693 0x0330 +0x8694 0x033c +0x8695 0x0334 +0x8696 0x031d +0x8697 0x031e +0x8698 0x0318 +0x8699 0x0319 +0x869a 0x032a +0x869b 0x033a +0x869c 0x033b +0x869d 0x0303 +0x869e 0x031a +0x869f 0x2776 +0x86a0 0x2777 +0x86a1 0x2778 +0x86a2 0x2779 +0x86a3 0x277a +0x86a4 0x277b +0x86a5 0x277c +0x86a6 0x277d +0x86a7 0x277e +0x86a8 0x277f +0x86a9 0x24eb +0x86aa 0x24ec +0x86ab 0x24ed +0x86ac 0x24ee +0x86ad 0x24ef +0x86ae 0x24f0 +0x86af 0x24f1 +0x86b0 0x24f2 +0x86b1 0x24f3 +0x86b2 0x24f4 +0x86b3 0x2170 +0x86b4 0x2171 +0x86b5 0x2172 +0x86b6 0x2173 +0x86b7 0x2174 +0x86b8 0x2175 +0x86b9 0x2176 +0x86ba 0x2177 +0x86bb 0x2178 +0x86bc 0x2179 +0x86bd 0x217a +0x86be 0x217b +0x86bf 0x24d0 +0x86c0 0x24d1 +0x86c1 0x24d2 +0x86c2 0x24d3 +0x86c3 0x24d4 +0x86c4 0x24d5 +0x86c5 0x24d6 +0x86c6 0x24d7 +0x86c7 0x24d8 +0x86c8 0x24d9 +0x86c9 0x24da +0x86ca 0x24db +0x86cb 0x24dc +0x86cc 0x24dd +0x86cd 0x24de +0x86ce 0x24df +0x86cf 0x24e0 +0x86d0 0x24e1 +0x86d1 0x24e2 +0x86d2 0x24e3 +0x86d3 0x24e4 +0x86d4 0x24e5 +0x86d5 0x24e6 +0x86d6 0x24e7 +0x86d7 0x24e8 +0x86d8 0x24e9 +0x86d9 0x32d0 +0x86da 0x32d1 +0x86db 0x32d2 +0x86dc 0x32d3 +0x86dd 0x32d4 +0x86de 0x32d5 +0x86df 0x32d6 +0x86e0 0x32d7 +0x86e1 0x32d8 +0x86e2 0x32d9 +0x86e3 0x32da +0x86e4 0x32db +0x86e5 0x32dc +0x86e6 0x32dd +0x86e7 0x32de +0x86e8 0x32df +0x86e9 0x32e0 +0x86ea 0x32e1 +0x86eb 0x32e2 +0x86ec 0x32e3 +0x86ed 0x32fa +0x86ee 0x32e9 +0x86ef 0x32e5 +0x86f0 0x32ed +0x86f1 0x32ec +0x86fb 0x2051 +0x86fc 0x2042 +0x8740 0x2460 +0x8741 0x2461 +0x8742 0x2462 +0x8743 0x2463 +0x8744 0x2464 +0x8745 0x2465 +0x8746 0x2466 +0x8747 0x2467 +0x8748 0x2468 +0x8749 0x2469 +0x874a 0x246a +0x874b 0x246b +0x874c 0x246c +0x874d 0x246d +0x874e 0x246e +0x874f 0x246f +0x8750 0x2470 +0x8751 0x2471 +0x8752 0x2472 +0x8753 0x2473 +0x8754 0x2160 +0x8755 0x2161 +0x8756 0x2162 +0x8757 0x2163 +0x8758 0x2164 +0x8759 0x2165 +0x875a 0x2166 +0x875b 0x2167 +0x875c 0x2168 +0x875d 0x2169 +0x875e 0x216a +0x875f 0x3349 +0x8760 0x3314 +0x8761 0x3322 +0x8762 0x334d +0x8763 0x3318 +0x8764 0x3327 +0x8765 0x3303 +0x8766 0x3336 +0x8767 0x3351 +0x8768 0x3357 +0x8769 0x330d +0x876a 0x3326 +0x876b 0x3323 +0x876c 0x332b +0x876d 0x334a +0x876e 0x333b +0x876f 0x339c +0x8770 0x339d +0x8771 0x339e +0x8772 0x338e +0x8773 0x338f +0x8774 0x33c4 +0x8775 0x33a1 +0x8776 0x216b +0x877e 0x337b +0x8780 0x301d +0x8781 0x301f +0x8782 0x2116 +0x8783 0x33cd +0x8784 0x2121 +0x8785 0x32a4 +0x8786 0x32a5 +0x8787 0x32a6 +0x8788 0x32a7 +0x8789 0x32a8 +0x878a 0x3231 +0x878b 0x3232 +0x878c 0x3239 +0x878d 0x337e +0x878e 0x337d +0x878f 0x337c +0x8793 0x222e +0x8798 0x221f +0x8799 0x22bf +0x879d 0x2756 +0x879e 0x261e +0x879f 0x4ff1 +0x87a0 0x2000b +0x87a1 0x3402 +0x87a2 0x4e28 +0x87a3 0x4e2f +0x87a4 0x4e30 +0x87a5 0x4e8d +0x87a6 0x4ee1 +0x87a7 0x4efd +0x87a8 0x4eff +0x87a9 0x4f03 +0x87aa 0x4f0b +0x87ab 0x4f60 +0x87ac 0x4f48 +0x87ad 0x4f49 +0x87ae 0x4f56 +0x87af 0x4f5f +0x87b0 0x4f6a +0x87b1 0x4f6c +0x87b2 0x4f7e +0x87b3 0x4f8a +0x87b4 0x4f94 +0x87b5 0x4f97 +0x87b6 0xfa30 +0x87b7 0x4fc9 +0x87b8 0x4fe0 +0x87b9 0x5001 +0x87ba 0x5002 +0x87bb 0x500e +0x87bc 0x5018 +0x87bd 0x5027 +0x87be 0x502e +0x87bf 0x5040 +0x87c0 0x503b +0x87c1 0x5041 +0x87c2 0x5094 +0x87c3 0x50cc +0x87c4 0x50f2 +0x87c5 0x50d0 +0x87c6 0x50e6 +0x87c7 0xfa31 +0x87c8 0x5106 +0x87c9 0x5103 +0x87ca 0x510b +0x87cb 0x511e +0x87cc 0x5135 +0x87cd 0x514a +0x87ce 0xfa32 +0x87cf 0x5155 +0x87d0 0x5157 +0x87d1 0x34b5 +0x87d2 0x519d +0x87d3 0x51c3 +0x87d4 0x51ca +0x87d5 0x51de +0x87d6 0x51e2 +0x87d7 0x51ee +0x87d8 0x5201 +0x87d9 0x34db +0x87da 0x5213 +0x87db 0x5215 +0x87dc 0x5249 +0x87dd 0x5257 +0x87de 0x5261 +0x87df 0x5293 +0x87e0 0x52c8 +0x87e1 0xfa33 +0x87e2 0x52cc +0x87e3 0x52d0 +0x87e4 0x52d6 +0x87e5 0x52db +0x87e6 0xfa34 +0x87e7 0x52f0 +0x87e8 0x52fb +0x87e9 0x5300 +0x87ea 0x5307 +0x87eb 0x531c +0x87ec 0xfa35 +0x87ed 0x5361 +0x87ee 0x5363 +0x87ef 0x537d +0x87f0 0x5393 +0x87f1 0x539d +0x87f2 0x53b2 +0x87f3 0x5412 +0x87f4 0x5427 +0x87f5 0x544d +0x87f6 0x549c +0x87f7 0x546b +0x87f8 0x5474 +0x87f9 0x547f +0x87fa 0x5488 +0x87fb 0x5496 +0x87fc 0x54a1 +0x8840 0x54a9 +0x8841 0x54c6 +0x8842 0x54ff +0x8843 0x550e +0x8844 0x552b +0x8845 0x5535 +0x8846 0x5550 +0x8847 0x555e +0x8848 0x5581 +0x8849 0x5586 +0x884a 0x558e +0x884b 0xfa36 +0x884c 0x55ad +0x884d 0x55ce +0x884e 0xfa37 +0x884f 0x5608 +0x8850 0x560e +0x8851 0x563b +0x8852 0x5649 +0x8853 0x5676 +0x8854 0x5666 +0x8855 0xfa38 +0x8856 0x566f +0x8857 0x5671 +0x8858 0x5672 +0x8859 0x5699 +0x885a 0x569e +0x885b 0x56a9 +0x885c 0x56ac +0x885d 0x56b3 +0x885e 0x56c9 +0x885f 0x56ca +0x8860 0x570a +0x8861 0x2123d +0x8862 0x5721 +0x8863 0x572f +0x8864 0x5733 +0x8865 0x5734 +0x8866 0x5770 +0x8867 0x5777 +0x8868 0x577c +0x8869 0x579c +0x886a 0xfa0f +0x886b 0x2131b +0x886c 0x57b8 +0x886d 0x57c7 +0x886e 0x57c8 +0x886f 0x57cf +0x8870 0x57e4 +0x8871 0x57ed +0x8872 0x57f5 +0x8873 0x57f6 +0x8874 0x57ff +0x8875 0x5809 +0x8876 0xfa10 +0x8877 0x5861 +0x8878 0x5864 +0x8879 0xfa39 +0x887a 0x587c +0x887b 0x5889 +0x887c 0x589e +0x887d 0xfa3a +0x887e 0x58a9 +0x8880 0x2146e +0x8881 0x58d2 +0x8882 0x58ce +0x8883 0x58d4 +0x8884 0x58da +0x8885 0x58e0 +0x8886 0x58e9 +0x8887 0x590c +0x8888 0x8641 +0x8889 0x595d +0x888a 0x596d +0x888b 0x598b +0x888c 0x5992 +0x888d 0x59a4 +0x888e 0x59c3 +0x888f 0x59d2 +0x8890 0x59dd +0x8891 0x5a13 +0x8892 0x5a23 +0x8893 0x5a67 +0x8894 0x5a6d +0x8895 0x5a77 +0x8896 0x5a7e +0x8897 0x5a84 +0x8898 0x5a9e +0x8899 0x5aa7 +0x889a 0x5ac4 +0x889b 0x218bd +0x889c 0x5b19 +0x889d 0x5b25 +0x889e 0x525d +0x889f 0x4e9c +0x88a0 0x5516 +0x88a1 0x5a03 +0x88a2 0x963f +0x88a3 0x54c0 +0x88a4 0x611b +0x88a5 0x6328 +0x88a6 0x59f6 +0x88a7 0x9022 +0x88a8 0x8475 +0x88a9 0x831c +0x88aa 0x7a50 +0x88ab 0x60aa +0x88ac 0x63e1 +0x88ad 0x6e25 +0x88ae 0x65ed +0x88af 0x8466 +0x88b0 0x82a6 +0x88b1 0x9bf5 +0x88b2 0x6893 +0x88b3 0x5727 +0x88b4 0x65a1 +0x88b5 0x6271 +0x88b6 0x5b9b +0x88b7 0x59d0 +0x88b8 0x867b +0x88b9 0x98f4 +0x88ba 0x7d62 +0x88bb 0x7dbe +0x88bc 0x9b8e +0x88bd 0x6216 +0x88be 0x7c9f +0x88bf 0x88b7 +0x88c0 0x5b89 +0x88c1 0x5eb5 +0x88c2 0x6309 +0x88c3 0x6697 +0x88c4 0x6848 +0x88c5 0x95c7 +0x88c6 0x978d +0x88c7 0x674f +0x88c8 0x4ee5 +0x88c9 0x4f0a +0x88ca 0x4f4d +0x88cb 0x4f9d +0x88cc 0x5049 +0x88cd 0x56f2 +0x88ce 0x5937 +0x88cf 0x59d4 +0x88d0 0x5a01 +0x88d1 0x5c09 +0x88d2 0x60df +0x88d3 0x610f +0x88d4 0x6170 +0x88d5 0x6613 +0x88d6 0x6905 +0x88d7 0x70ba +0x88d8 0x754f +0x88d9 0x7570 +0x88da 0x79fb +0x88db 0x7dad +0x88dc 0x7def +0x88dd 0x80c3 +0x88de 0x840e +0x88df 0x8863 +0x88e0 0x8b02 +0x88e1 0x9055 +0x88e2 0x907a +0x88e3 0x533b +0x88e4 0x4e95 +0x88e5 0x4ea5 +0x88e6 0x57df +0x88e7 0x80b2 +0x88e8 0x90c1 +0x88e9 0x78ef +0x88ea 0x4e00 +0x88eb 0x58f1 +0x88ec 0x6ea2 +0x88ed 0x9038 +0x88ee 0x7a32 +0x88ef 0x8328 +0x88f0 0x828b +0x88f1 0x9c2f +0x88f2 0x5141 +0x88f3 0x5370 +0x88f4 0x54bd +0x88f5 0x54e1 +0x88f6 0x56e0 +0x88f7 0x59fb +0x88f8 0x5f15 +0x88f9 0x98f2 +0x88fa 0x6deb +0x88fb 0x80e4 +0x88fc 0x852d +0x8940 0x9662 +0x8941 0x9670 +0x8942 0x96a0 +0x8943 0x97fb +0x8944 0x540b +0x8945 0x53f3 +0x8946 0x5b87 +0x8947 0x70cf +0x8948 0x7fbd +0x8949 0x8fc2 +0x894a 0x96e8 +0x894b 0x536f +0x894c 0x9d5c +0x894d 0x7aba +0x894e 0x4e11 +0x894f 0x7893 +0x8950 0x81fc +0x8951 0x6e26 +0x8952 0x5618 +0x8953 0x5504 +0x8954 0x6b1d +0x8955 0x851a +0x8956 0x9c3b +0x8957 0x59e5 +0x8958 0x53a9 +0x8959 0x6d66 +0x895a 0x74dc +0x895b 0x958f +0x895c 0x5642 +0x895d 0x4e91 +0x895e 0x904b +0x895f 0x96f2 +0x8960 0x834f +0x8961 0x990c +0x8962 0x53e1 +0x8963 0x55b6 +0x8964 0x5b30 +0x8965 0x5f71 +0x8966 0x6620 +0x8967 0x66f3 +0x8968 0x6804 +0x8969 0x6c38 +0x896a 0x6cf3 +0x896b 0x6d29 +0x896c 0x745b +0x896d 0x76c8 +0x896e 0x7a4e +0x896f 0x9834 +0x8970 0x82f1 +0x8971 0x885b +0x8972 0x8a60 +0x8973 0x92ed +0x8974 0x6db2 +0x8975 0x75ab +0x8976 0x76ca +0x8977 0x99c5 +0x8978 0x60a6 +0x8979 0x8b01 +0x897a 0x8d8a +0x897b 0x95b2 +0x897c 0x698e +0x897d 0x53ad +0x897e 0x5186 +0x8980 0x5712 +0x8981 0x5830 +0x8982 0x5944 +0x8983 0x5bb4 +0x8984 0x5ef6 +0x8985 0x6028 +0x8986 0x63a9 +0x8987 0x63f4 +0x8988 0x6cbf +0x8989 0x6f14 +0x898a 0x708e +0x898b 0x7114 +0x898c 0x7159 +0x898d 0x71d5 +0x898e 0x733f +0x898f 0x7e01 +0x8990 0x8276 +0x8991 0x82d1 +0x8992 0x8597 +0x8993 0x9060 +0x8994 0x925b +0x8995 0x9d1b +0x8996 0x5869 +0x8997 0x65bc +0x8998 0x6c5a +0x8999 0x7525 +0x899a 0x51f9 +0x899b 0x592e +0x899c 0x5965 +0x899d 0x5f80 +0x899e 0x5fdc +0x899f 0x62bc +0x89a0 0x65fa +0x89a1 0x6a2a +0x89a2 0x6b27 +0x89a3 0x6bb4 +0x89a4 0x738b +0x89a5 0x7fc1 +0x89a6 0x8956 +0x89a7 0x9d2c +0x89a8 0x9d0e +0x89a9 0x9ec4 +0x89aa 0x5ca1 +0x89ab 0x6c96 +0x89ac 0x837b +0x89ad 0x5104 +0x89ae 0x5c4b +0x89af 0x61b6 +0x89b0 0x81c6 +0x89b1 0x6876 +0x89b2 0x7261 +0x89b3 0x4e59 +0x89b4 0x4ffa +0x89b5 0x5378 +0x89b6 0x6069 +0x89b7 0x6e29 +0x89b8 0x7a4f +0x89b9 0x97f3 +0x89ba 0x4e0b +0x89bb 0x5316 +0x89bc 0x4eee +0x89bd 0x4f55 +0x89be 0x4f3d +0x89bf 0x4fa1 +0x89c0 0x4f73 +0x89c1 0x52a0 +0x89c2 0x53ef +0x89c3 0x5609 +0x89c4 0x590f +0x89c5 0x5ac1 +0x89c6 0x5bb6 +0x89c7 0x5be1 +0x89c8 0x79d1 +0x89c9 0x6687 +0x89ca 0x679c +0x89cb 0x67b6 +0x89cc 0x6b4c +0x89cd 0x6cb3 +0x89ce 0x706b +0x89cf 0x73c2 +0x89d0 0x798d +0x89d1 0x79be +0x89d2 0x7a3c +0x89d3 0x7b87 +0x89d4 0x82b1 +0x89d5 0x82db +0x89d6 0x8304 +0x89d7 0x8377 +0x89d8 0x83ef +0x89d9 0x83d3 +0x89da 0x8766 +0x89db 0x8ab2 +0x89dc 0x5629 +0x89dd 0x8ca8 +0x89de 0x8fe6 +0x89df 0x904e +0x89e0 0x971e +0x89e1 0x868a +0x89e2 0x4fc4 +0x89e3 0x5ce8 +0x89e4 0x6211 +0x89e5 0x7259 +0x89e6 0x753b +0x89e7 0x81e5 +0x89e8 0x82bd +0x89e9 0x86fe +0x89ea 0x8cc0 +0x89eb 0x96c5 +0x89ec 0x9913 +0x89ed 0x99d5 +0x89ee 0x4ecb +0x89ef 0x4f1a +0x89f0 0x89e3 +0x89f1 0x56de +0x89f2 0x584a +0x89f3 0x58ca +0x89f4 0x5efb +0x89f5 0x5feb +0x89f6 0x602a +0x89f7 0x6094 +0x89f8 0x6062 +0x89f9 0x61d0 +0x89fa 0x6212 +0x89fb 0x62d0 +0x89fc 0x6539 +0x8a40 0x9b41 +0x8a41 0x6666 +0x8a42 0x68b0 +0x8a43 0x6d77 +0x8a44 0x7070 +0x8a45 0x754c +0x8a46 0x7686 +0x8a47 0x7d75 +0x8a48 0x82a5 +0x8a49 0x87f9 +0x8a4a 0x958b +0x8a4b 0x968e +0x8a4c 0x8c9d +0x8a4d 0x51f1 +0x8a4e 0x52be +0x8a4f 0x5916 +0x8a50 0x54b3 +0x8a51 0x5bb3 +0x8a52 0x5d16 +0x8a53 0x6168 +0x8a54 0x6982 +0x8a55 0x6daf +0x8a56 0x788d +0x8a57 0x84cb +0x8a58 0x8857 +0x8a59 0x8a72 +0x8a5a 0x93a7 +0x8a5b 0x9ab8 +0x8a5c 0x6d6c +0x8a5d 0x99a8 +0x8a5e 0x86d9 +0x8a5f 0x57a3 +0x8a60 0x67ff +0x8a61 0x86ce +0x8a62 0x920e +0x8a63 0x5283 +0x8a64 0x5687 +0x8a65 0x5404 +0x8a66 0x5ed3 +0x8a67 0x62e1 +0x8a68 0x64b9 +0x8a69 0x683c +0x8a6a 0x6838 +0x8a6b 0x6bbb +0x8a6c 0x7372 +0x8a6d 0x78ba +0x8a6e 0x7a6b +0x8a6f 0x899a +0x8a70 0x89d2 +0x8a71 0x8d6b +0x8a72 0x8f03 +0x8a73 0x90ed +0x8a74 0x95a3 +0x8a75 0x9694 +0x8a76 0x9769 +0x8a77 0x5b66 +0x8a78 0x5cb3 +0x8a79 0x697d +0x8a7a 0x984d +0x8a7b 0x984e +0x8a7c 0x639b +0x8a7d 0x7b20 +0x8a7e 0x6a2b +0x8a80 0x6a7f +0x8a81 0x68b6 +0x8a82 0x9c0d +0x8a83 0x6f5f +0x8a84 0x5272 +0x8a85 0x559d +0x8a86 0x6070 +0x8a87 0x62ec +0x8a88 0x6d3b +0x8a89 0x6e07 +0x8a8a 0x6ed1 +0x8a8b 0x845b +0x8a8c 0x8910 +0x8a8d 0x8f44 +0x8a8e 0x4e14 +0x8a8f 0x9c39 +0x8a90 0x53f6 +0x8a91 0x691b +0x8a92 0x6a3a +0x8a93 0x9784 +0x8a94 0x682a +0x8a95 0x515c +0x8a96 0x7ac3 +0x8a97 0x84b2 +0x8a98 0x91dc +0x8a99 0x938c +0x8a9a 0x565b +0x8a9b 0x9d28 +0x8a9c 0x6822 +0x8a9d 0x8305 +0x8a9e 0x8431 +0x8a9f 0x7ca5 +0x8aa0 0x5208 +0x8aa1 0x82c5 +0x8aa2 0x74e6 +0x8aa3 0x4e7e +0x8aa4 0x4f83 +0x8aa5 0x51a0 +0x8aa6 0x5bd2 +0x8aa7 0x520a +0x8aa8 0x52d8 +0x8aa9 0x52e7 +0x8aaa 0x5dfb +0x8aab 0x559a +0x8aac 0x582a +0x8aad 0x59e6 +0x8aae 0x5b8c +0x8aaf 0x5b98 +0x8ab0 0x5bdb +0x8ab1 0x5e72 +0x8ab2 0x5e79 +0x8ab3 0x60a3 +0x8ab4 0x611f +0x8ab5 0x6163 +0x8ab6 0x61be +0x8ab7 0x63db +0x8ab8 0x6562 +0x8ab9 0x67d1 +0x8aba 0x6853 +0x8abb 0x68fa +0x8abc 0x6b3e +0x8abd 0x6b53 +0x8abe 0x6c57 +0x8abf 0x6f22 +0x8ac0 0x6f97 +0x8ac1 0x6f45 +0x8ac2 0x74b0 +0x8ac3 0x7518 +0x8ac4 0x76e3 +0x8ac5 0x770b +0x8ac6 0x7aff +0x8ac7 0x7ba1 +0x8ac8 0x7c21 +0x8ac9 0x7de9 +0x8aca 0x7f36 +0x8acb 0x7ff0 +0x8acc 0x809d +0x8acd 0x8266 +0x8ace 0x839e +0x8acf 0x89b3 +0x8ad0 0x8acc +0x8ad1 0x8cab +0x8ad2 0x9084 +0x8ad3 0x9451 +0x8ad4 0x9593 +0x8ad5 0x9591 +0x8ad6 0x95a2 +0x8ad7 0x9665 +0x8ad8 0x97d3 +0x8ad9 0x9928 +0x8ada 0x8218 +0x8adb 0x4e38 +0x8adc 0x542b +0x8add 0x5cb8 +0x8ade 0x5dcc +0x8adf 0x73a9 +0x8ae0 0x764c +0x8ae1 0x773c +0x8ae2 0x5ca9 +0x8ae3 0x7feb +0x8ae4 0x8d0b +0x8ae5 0x96c1 +0x8ae6 0x9811 +0x8ae7 0x9854 +0x8ae8 0x9858 +0x8ae9 0x4f01 +0x8aea 0x4f0e +0x8aeb 0x5371 +0x8aec 0x559c +0x8aed 0x5668 +0x8aee 0x57fa +0x8aef 0x5947 +0x8af0 0x5b09 +0x8af1 0x5bc4 +0x8af2 0x5c90 +0x8af3 0x5e0c +0x8af4 0x5e7e +0x8af5 0x5fcc +0x8af6 0x63ee +0x8af7 0x673a +0x8af8 0x65d7 +0x8af9 0x65e2 +0x8afa 0x671f +0x8afb 0x68cb +0x8afc 0x68c4 +0x8b40 0x6a5f +0x8b41 0x5e30 +0x8b42 0x6bc5 +0x8b43 0x6c17 +0x8b44 0x6c7d +0x8b45 0x757f +0x8b46 0x7948 +0x8b47 0x5b63 +0x8b48 0x7a00 +0x8b49 0x7d00 +0x8b4a 0x5fbd +0x8b4b 0x898f +0x8b4c 0x8a18 +0x8b4d 0x8cb4 +0x8b4e 0x8d77 +0x8b4f 0x8ecc +0x8b50 0x8f1d +0x8b51 0x98e2 +0x8b52 0x9a0e +0x8b53 0x9b3c +0x8b54 0x4e80 +0x8b55 0x507d +0x8b56 0x5100 +0x8b57 0x5993 +0x8b58 0x5b9c +0x8b59 0x622f +0x8b5a 0x6280 +0x8b5b 0x64ec +0x8b5c 0x6b3a +0x8b5d 0x72a0 +0x8b5e 0x7591 +0x8b5f 0x7947 +0x8b60 0x7fa9 +0x8b61 0x87fb +0x8b62 0x8abc +0x8b63 0x8b70 +0x8b64 0x63ac +0x8b65 0x83ca +0x8b66 0x97a0 +0x8b67 0x5409 +0x8b68 0x5403 +0x8b69 0x55ab +0x8b6a 0x6854 +0x8b6b 0x6a58 +0x8b6c 0x8a70 +0x8b6d 0x7827 +0x8b6e 0x6775 +0x8b6f 0x9ecd +0x8b70 0x5374 +0x8b71 0x5ba2 +0x8b72 0x811a +0x8b73 0x8650 +0x8b74 0x9006 +0x8b75 0x4e18 +0x8b76 0x4e45 +0x8b77 0x4ec7 +0x8b78 0x4f11 +0x8b79 0x53ca +0x8b7a 0x5438 +0x8b7b 0x5bae +0x8b7c 0x5f13 +0x8b7d 0x6025 +0x8b7e 0x6551 +0x8b80 0x673d +0x8b81 0x6c42 +0x8b82 0x6c72 +0x8b83 0x6ce3 +0x8b84 0x7078 +0x8b85 0x7403 +0x8b86 0x7a76 +0x8b87 0x7aae +0x8b88 0x7b08 +0x8b89 0x7d1a +0x8b8a 0x7cfe +0x8b8b 0x7d66 +0x8b8c 0x65e7 +0x8b8d 0x725b +0x8b8e 0x53bb +0x8b8f 0x5c45 +0x8b90 0x5de8 +0x8b91 0x62d2 +0x8b92 0x62e0 +0x8b93 0x6319 +0x8b94 0x6e20 +0x8b95 0x865a +0x8b96 0x8a31 +0x8b97 0x8ddd +0x8b98 0x92f8 +0x8b99 0x6f01 +0x8b9a 0x79a6 +0x8b9b 0x9b5a +0x8b9c 0x4ea8 +0x8b9d 0x4eab +0x8b9e 0x4eac +0x8b9f 0x4f9b +0x8ba0 0x4fa0 +0x8ba1 0x50d1 +0x8ba2 0x5147 +0x8ba3 0x7af6 +0x8ba4 0x5171 +0x8ba5 0x51f6 +0x8ba6 0x5354 +0x8ba7 0x5321 +0x8ba8 0x537f +0x8ba9 0x53eb +0x8baa 0x55ac +0x8bab 0x5883 +0x8bac 0x5ce1 +0x8bad 0x5f37 +0x8bae 0x5f4a +0x8baf 0x602f +0x8bb0 0x6050 +0x8bb1 0x606d +0x8bb2 0x631f +0x8bb3 0x6559 +0x8bb4 0x6a4b +0x8bb5 0x6cc1 +0x8bb6 0x72c2 +0x8bb7 0x72ed +0x8bb8 0x77ef +0x8bb9 0x80f8 +0x8bba 0x8105 +0x8bbb 0x8208 +0x8bbc 0x854e +0x8bbd 0x90f7 +0x8bbe 0x93e1 +0x8bbf 0x97ff +0x8bc0 0x9957 +0x8bc1 0x9a5a +0x8bc2 0x4ef0 +0x8bc3 0x51dd +0x8bc4 0x5c2d +0x8bc5 0x6681 +0x8bc6 0x696d +0x8bc7 0x5c40 +0x8bc8 0x66f2 +0x8bc9 0x6975 +0x8bca 0x7389 +0x8bcb 0x6850 +0x8bcc 0x7c81 +0x8bcd 0x50c5 +0x8bce 0x52e4 +0x8bcf 0x5747 +0x8bd0 0x5dfe +0x8bd1 0x9326 +0x8bd2 0x65a4 +0x8bd3 0x6b23 +0x8bd4 0x6b3d +0x8bd5 0x7434 +0x8bd6 0x7981 +0x8bd7 0x79bd +0x8bd8 0x7b4b +0x8bd9 0x7dca +0x8bda 0x82b9 +0x8bdb 0x83cc +0x8bdc 0x887f +0x8bdd 0x895f +0x8bde 0x8b39 +0x8bdf 0x8fd1 +0x8be0 0x91d1 +0x8be1 0x541f +0x8be2 0x9280 +0x8be3 0x4e5d +0x8be4 0x5036 +0x8be5 0x53e5 +0x8be6 0x533a +0x8be7 0x72d7 +0x8be8 0x7396 +0x8be9 0x77e9 +0x8bea 0x82e6 +0x8beb 0x8eaf +0x8bec 0x99c6 +0x8bed 0x99c8 +0x8bee 0x99d2 +0x8bef 0x5177 +0x8bf0 0x611a +0x8bf1 0x865e +0x8bf2 0x55b0 +0x8bf3 0x7a7a +0x8bf4 0x5076 +0x8bf5 0x5bd3 +0x8bf6 0x9047 +0x8bf7 0x9685 +0x8bf8 0x4e32 +0x8bf9 0x6adb +0x8bfa 0x91e7 +0x8bfb 0x5c51 +0x8bfc 0x5c48 +0x8c40 0x6398 +0x8c41 0x7a9f +0x8c42 0x6c93 +0x8c43 0x9774 +0x8c44 0x8f61 +0x8c45 0x7aaa +0x8c46 0x718a +0x8c47 0x9688 +0x8c48 0x7c82 +0x8c49 0x6817 +0x8c4a 0x7e70 +0x8c4b 0x6851 +0x8c4c 0x936c +0x8c4d 0x52f2 +0x8c4e 0x541b +0x8c4f 0x85ab +0x8c50 0x8a13 +0x8c51 0x7fa4 +0x8c52 0x8ecd +0x8c53 0x90e1 +0x8c54 0x5366 +0x8c55 0x8888 +0x8c56 0x7941 +0x8c57 0x4fc2 +0x8c58 0x50be +0x8c59 0x5211 +0x8c5a 0x5144 +0x8c5b 0x5553 +0x8c5c 0x572d +0x8c5d 0x73ea +0x8c5e 0x578b +0x8c5f 0x5951 +0x8c60 0x5f62 +0x8c61 0x5f84 +0x8c62 0x6075 +0x8c63 0x6176 +0x8c64 0x6167 +0x8c65 0x61a9 +0x8c66 0x63b2 +0x8c67 0x643a +0x8c68 0x656c +0x8c69 0x666f +0x8c6a 0x6842 +0x8c6b 0x6e13 +0x8c6c 0x7566 +0x8c6d 0x7a3d +0x8c6e 0x7cfb +0x8c6f 0x7d4c +0x8c70 0x7d99 +0x8c71 0x7e4b +0x8c72 0x7f6b +0x8c73 0x830e +0x8c74 0x834a +0x8c75 0x86cd +0x8c76 0x8a08 +0x8c77 0x8a63 +0x8c78 0x8b66 +0x8c79 0x8efd +0x8c7a 0x981a +0x8c7b 0x9d8f +0x8c7c 0x82b8 +0x8c7d 0x8fce +0x8c7e 0x9be8 +0x8c80 0x5287 +0x8c81 0x621f +0x8c82 0x6483 +0x8c83 0x6fc0 +0x8c84 0x9699 +0x8c85 0x6841 +0x8c86 0x5091 +0x8c87 0x6b20 +0x8c88 0x6c7a +0x8c89 0x6f54 +0x8c8a 0x7a74 +0x8c8b 0x7d50 +0x8c8c 0x8840 +0x8c8d 0x8a23 +0x8c8e 0x6708 +0x8c8f 0x4ef6 +0x8c90 0x5039 +0x8c91 0x5026 +0x8c92 0x5065 +0x8c93 0x517c +0x8c94 0x5238 +0x8c95 0x5263 +0x8c96 0x55a7 +0x8c97 0x570f +0x8c98 0x5805 +0x8c99 0x5acc +0x8c9a 0x5efa +0x8c9b 0x61b2 +0x8c9c 0x61f8 +0x8c9d 0x62f3 +0x8c9e 0x6372 +0x8c9f 0x691c +0x8ca0 0x6a29 +0x8ca1 0x727d +0x8ca2 0x72ac +0x8ca3 0x732e +0x8ca4 0x7814 +0x8ca5 0x786f +0x8ca6 0x7d79 +0x8ca7 0x770c +0x8ca8 0x80a9 +0x8ca9 0x898b +0x8caa 0x8b19 +0x8cab 0x8ce2 +0x8cac 0x8ed2 +0x8cad 0x9063 +0x8cae 0x9375 +0x8caf 0x967a +0x8cb0 0x9855 +0x8cb1 0x9a13 +0x8cb2 0x9e78 +0x8cb3 0x5143 +0x8cb4 0x539f +0x8cb5 0x53b3 +0x8cb6 0x5e7b +0x8cb7 0x5f26 +0x8cb8 0x6e1b +0x8cb9 0x6e90 +0x8cba 0x7384 +0x8cbb 0x73fe +0x8cbc 0x7d43 +0x8cbd 0x8237 +0x8cbe 0x8a00 +0x8cbf 0x8afa +0x8cc0 0x9650 +0x8cc1 0x4e4e +0x8cc2 0x500b +0x8cc3 0x53e4 +0x8cc4 0x547c +0x8cc5 0x56fa +0x8cc6 0x59d1 +0x8cc7 0x5b64 +0x8cc8 0x5df1 +0x8cc9 0x5eab +0x8cca 0x5f27 +0x8ccb 0x6238 +0x8ccc 0x6545 +0x8ccd 0x67af +0x8cce 0x6e56 +0x8ccf 0x72d0 +0x8cd0 0x7cca +0x8cd1 0x88b4 +0x8cd2 0x80a1 +0x8cd3 0x80e1 +0x8cd4 0x83f0 +0x8cd5 0x864e +0x8cd6 0x8a87 +0x8cd7 0x8de8 +0x8cd8 0x9237 +0x8cd9 0x96c7 +0x8cda 0x9867 +0x8cdb 0x9f13 +0x8cdc 0x4e94 +0x8cdd 0x4e92 +0x8cde 0x4f0d +0x8cdf 0x5348 +0x8ce0 0x5449 +0x8ce1 0x543e +0x8ce2 0x5a2f +0x8ce3 0x5f8c +0x8ce4 0x5fa1 +0x8ce5 0x609f +0x8ce6 0x68a7 +0x8ce7 0x6a8e +0x8ce8 0x745a +0x8ce9 0x7881 +0x8cea 0x8a9e +0x8ceb 0x8aa4 +0x8cec 0x8b77 +0x8ced 0x9190 +0x8cee 0x4e5e +0x8cef 0x9bc9 +0x8cf0 0x4ea4 +0x8cf1 0x4f7c +0x8cf2 0x4faf +0x8cf3 0x5019 +0x8cf4 0x5016 +0x8cf5 0x5149 +0x8cf6 0x516c +0x8cf7 0x529f +0x8cf8 0x52b9 +0x8cf9 0x52fe +0x8cfa 0x539a +0x8cfb 0x53e3 +0x8cfc 0x5411 +0x8d40 0x540e +0x8d41 0x5589 +0x8d42 0x5751 +0x8d43 0x57a2 +0x8d44 0x597d +0x8d45 0x5b54 +0x8d46 0x5b5d +0x8d47 0x5b8f +0x8d48 0x5de5 +0x8d49 0x5de7 +0x8d4a 0x5df7 +0x8d4b 0x5e78 +0x8d4c 0x5e83 +0x8d4d 0x5e9a +0x8d4e 0x5eb7 +0x8d4f 0x5f18 +0x8d50 0x6052 +0x8d51 0x614c +0x8d52 0x6297 +0x8d53 0x62d8 +0x8d54 0x63a7 +0x8d55 0x653b +0x8d56 0x6602 +0x8d57 0x6643 +0x8d58 0x66f4 +0x8d59 0x676d +0x8d5a 0x6821 +0x8d5b 0x6897 +0x8d5c 0x69cb +0x8d5d 0x6c5f +0x8d5e 0x6d2a +0x8d5f 0x6d69 +0x8d60 0x6e2f +0x8d61 0x6e9d +0x8d62 0x7532 +0x8d63 0x7687 +0x8d64 0x786c +0x8d65 0x7a3f +0x8d66 0x7ce0 +0x8d67 0x7d05 +0x8d68 0x7d18 +0x8d69 0x7d5e +0x8d6a 0x7db1 +0x8d6b 0x8015 +0x8d6c 0x8003 +0x8d6d 0x80af +0x8d6e 0x80b1 +0x8d6f 0x8154 +0x8d70 0x818f +0x8d71 0x822a +0x8d72 0x8352 +0x8d73 0x884c +0x8d74 0x8861 +0x8d75 0x8b1b +0x8d76 0x8ca2 +0x8d77 0x8cfc +0x8d78 0x90ca +0x8d79 0x9175 +0x8d7a 0x9271 +0x8d7b 0x783f +0x8d7c 0x92fc +0x8d7d 0x95a4 +0x8d7e 0x964d +0x8d80 0x9805 +0x8d81 0x9999 +0x8d82 0x9ad8 +0x8d83 0x9d3b +0x8d84 0x525b +0x8d85 0x52ab +0x8d86 0x53f7 +0x8d87 0x5408 +0x8d88 0x58d5 +0x8d89 0x62f7 +0x8d8a 0x6fe0 +0x8d8b 0x8c6a +0x8d8c 0x8f5f +0x8d8d 0x9eb9 +0x8d8e 0x514b +0x8d8f 0x523b +0x8d90 0x544a +0x8d91 0x56fd +0x8d92 0x7a40 +0x8d93 0x9177 +0x8d94 0x9d60 +0x8d95 0x9ed2 +0x8d96 0x7344 +0x8d97 0x6f09 +0x8d98 0x8170 +0x8d99 0x7511 +0x8d9a 0x5ffd +0x8d9b 0x60da +0x8d9c 0x9aa8 +0x8d9d 0x72db +0x8d9e 0x8fbc +0x8d9f 0x6b64 +0x8da0 0x9803 +0x8da1 0x4eca +0x8da2 0x56f0 +0x8da3 0x5764 +0x8da4 0x58be +0x8da5 0x5a5a +0x8da6 0x6068 +0x8da7 0x61c7 +0x8da8 0x660f +0x8da9 0x6606 +0x8daa 0x6839 +0x8dab 0x68b1 +0x8dac 0x6df7 +0x8dad 0x75d5 +0x8dae 0x7d3a +0x8daf 0x826e +0x8db0 0x9b42 +0x8db1 0x4e9b +0x8db2 0x4f50 +0x8db3 0x53c9 +0x8db4 0x5506 +0x8db5 0x5d6f +0x8db6 0x5de6 +0x8db7 0x5dee +0x8db8 0x67fb +0x8db9 0x6c99 +0x8dba 0x7473 +0x8dbb 0x7802 +0x8dbc 0x8a50 +0x8dbd 0x9396 +0x8dbe 0x88df +0x8dbf 0x5750 +0x8dc0 0x5ea7 +0x8dc1 0x632b +0x8dc2 0x50b5 +0x8dc3 0x50ac +0x8dc4 0x518d +0x8dc5 0x6700 +0x8dc6 0x54c9 +0x8dc7 0x585e +0x8dc8 0x59bb +0x8dc9 0x5bb0 +0x8dca 0x5f69 +0x8dcb 0x624d +0x8dcc 0x63a1 +0x8dcd 0x683d +0x8dce 0x6b73 +0x8dcf 0x6e08 +0x8dd0 0x707d +0x8dd1 0x91c7 +0x8dd2 0x7280 +0x8dd3 0x7815 +0x8dd4 0x7826 +0x8dd5 0x796d +0x8dd6 0x658e +0x8dd7 0x7d30 +0x8dd8 0x83dc +0x8dd9 0x88c1 +0x8dda 0x8f09 +0x8ddb 0x969b +0x8ddc 0x5264 +0x8ddd 0x5728 +0x8dde 0x6750 +0x8ddf 0x7f6a +0x8de0 0x8ca1 +0x8de1 0x51b4 +0x8de2 0x5742 +0x8de3 0x962a +0x8de4 0x583a +0x8de5 0x698a +0x8de6 0x80b4 +0x8de7 0x54b2 +0x8de8 0x5d0e +0x8de9 0x57fc +0x8dea 0x7895 +0x8deb 0x9dfa +0x8dec 0x4f5c +0x8ded 0x524a +0x8dee 0x548b +0x8def 0x643e +0x8df0 0x6628 +0x8df1 0x6714 +0x8df2 0x67f5 +0x8df3 0x7a84 +0x8df4 0x7b56 +0x8df5 0x7d22 +0x8df6 0x932f +0x8df7 0x685c +0x8df8 0x9bad +0x8df9 0x7b39 +0x8dfa 0x5319 +0x8dfb 0x518a +0x8dfc 0x5237 +0x8e40 0x5bdf +0x8e41 0x62f6 +0x8e42 0x64ae +0x8e43 0x64e6 +0x8e44 0x672d +0x8e45 0x6bba +0x8e46 0x85a9 +0x8e47 0x96d1 +0x8e48 0x7690 +0x8e49 0x9bd6 +0x8e4a 0x634c +0x8e4b 0x9306 +0x8e4c 0x9bab +0x8e4d 0x76bf +0x8e4e 0x6652 +0x8e4f 0x4e09 +0x8e50 0x5098 +0x8e51 0x53c2 +0x8e52 0x5c71 +0x8e53 0x60e8 +0x8e54 0x6492 +0x8e55 0x6563 +0x8e56 0x685f +0x8e57 0x71e6 +0x8e58 0x73ca +0x8e59 0x7523 +0x8e5a 0x7b97 +0x8e5b 0x7e82 +0x8e5c 0x8695 +0x8e5d 0x8b83 +0x8e5e 0x8cdb +0x8e5f 0x9178 +0x8e60 0x9910 +0x8e61 0x65ac +0x8e62 0x66ab +0x8e63 0x6b8b +0x8e64 0x4ed5 +0x8e65 0x4ed4 +0x8e66 0x4f3a +0x8e67 0x4f7f +0x8e68 0x523a +0x8e69 0x53f8 +0x8e6a 0x53f2 +0x8e6b 0x55e3 +0x8e6c 0x56db +0x8e6d 0x58eb +0x8e6e 0x59cb +0x8e6f 0x59c9 +0x8e70 0x59ff +0x8e71 0x5b50 +0x8e72 0x5c4d +0x8e73 0x5e02 +0x8e74 0x5e2b +0x8e75 0x5fd7 +0x8e76 0x601d +0x8e77 0x6307 +0x8e78 0x652f +0x8e79 0x5b5c +0x8e7a 0x65af +0x8e7b 0x65bd +0x8e7c 0x65e8 +0x8e7d 0x679d +0x8e7e 0x6b62 +0x8e80 0x6b7b +0x8e81 0x6c0f +0x8e82 0x7345 +0x8e83 0x7949 +0x8e84 0x79c1 +0x8e85 0x7cf8 +0x8e86 0x7d19 +0x8e87 0x7d2b +0x8e88 0x80a2 +0x8e89 0x8102 +0x8e8a 0x81f3 +0x8e8b 0x8996 +0x8e8c 0x8a5e +0x8e8d 0x8a69 +0x8e8e 0x8a66 +0x8e8f 0x8a8c +0x8e90 0x8aee +0x8e91 0x8cc7 +0x8e92 0x8cdc +0x8e93 0x96cc +0x8e94 0x98fc +0x8e95 0x6b6f +0x8e96 0x4e8b +0x8e97 0x4f3c +0x8e98 0x4f8d +0x8e99 0x5150 +0x8e9a 0x5b57 +0x8e9b 0x5bfa +0x8e9c 0x6148 +0x8e9d 0x6301 +0x8e9e 0x6642 +0x8e9f 0x6b21 +0x8ea0 0x6ecb +0x8ea1 0x6cbb +0x8ea2 0x723e +0x8ea3 0x74bd +0x8ea4 0x75d4 +0x8ea5 0x78c1 +0x8ea6 0x793a +0x8ea7 0x800c +0x8ea8 0x8033 +0x8ea9 0x81ea +0x8eaa 0x8494 +0x8eab 0x8f9e +0x8eac 0x6c50 +0x8ead 0x9e7f +0x8eae 0x5f0f +0x8eaf 0x8b58 +0x8eb0 0x9d2b +0x8eb1 0x7afa +0x8eb2 0x8ef8 +0x8eb3 0x5b8d +0x8eb4 0x96eb +0x8eb5 0x4e03 +0x8eb6 0x53f1 +0x8eb7 0x57f7 +0x8eb8 0x5931 +0x8eb9 0x5ac9 +0x8eba 0x5ba4 +0x8ebb 0x6089 +0x8ebc 0x6e7f +0x8ebd 0x6f06 +0x8ebe 0x75be +0x8ebf 0x8cea +0x8ec0 0x5b9f +0x8ec1 0x8500 +0x8ec2 0x7be0 +0x8ec3 0x5072 +0x8ec4 0x67f4 +0x8ec5 0x829d +0x8ec6 0x5c61 +0x8ec7 0x854a +0x8ec8 0x7e1e +0x8ec9 0x820e +0x8eca 0x5199 +0x8ecb 0x5c04 +0x8ecc 0x6368 +0x8ecd 0x8d66 +0x8ece 0x659c +0x8ecf 0x716e +0x8ed0 0x793e +0x8ed1 0x7d17 +0x8ed2 0x8005 +0x8ed3 0x8b1d +0x8ed4 0x8eca +0x8ed5 0x906e +0x8ed6 0x86c7 +0x8ed7 0x90aa +0x8ed8 0x501f +0x8ed9 0x52fa +0x8eda 0x5c3a +0x8edb 0x6753 +0x8edc 0x707c +0x8edd 0x7235 +0x8ede 0x914c +0x8edf 0x91c8 +0x8ee0 0x932b +0x8ee1 0x82e5 +0x8ee2 0x5bc2 +0x8ee3 0x5f31 +0x8ee4 0x60f9 +0x8ee5 0x4e3b +0x8ee6 0x53d6 +0x8ee7 0x5b88 +0x8ee8 0x624b +0x8ee9 0x6731 +0x8eea 0x6b8a +0x8eeb 0x72e9 +0x8eec 0x73e0 +0x8eed 0x7a2e +0x8eee 0x816b +0x8eef 0x8da3 +0x8ef0 0x9152 +0x8ef1 0x9996 +0x8ef2 0x5112 +0x8ef3 0x53d7 +0x8ef4 0x546a +0x8ef5 0x5bff +0x8ef6 0x6388 +0x8ef7 0x6a39 +0x8ef8 0x7dac +0x8ef9 0x9700 +0x8efa 0x56da +0x8efb 0x53ce +0x8efc 0x5468 +0x8f40 0x5b97 +0x8f41 0x5c31 +0x8f42 0x5dde +0x8f43 0x4fee +0x8f44 0x6101 +0x8f45 0x62fe +0x8f46 0x6d32 +0x8f47 0x79c0 +0x8f48 0x79cb +0x8f49 0x7d42 +0x8f4a 0x7e4d +0x8f4b 0x7fd2 +0x8f4c 0x81ed +0x8f4d 0x821f +0x8f4e 0x8490 +0x8f4f 0x8846 +0x8f50 0x8972 +0x8f51 0x8b90 +0x8f52 0x8e74 +0x8f53 0x8f2f +0x8f54 0x9031 +0x8f55 0x914b +0x8f56 0x916c +0x8f57 0x96c6 +0x8f58 0x919c +0x8f59 0x4ec0 +0x8f5a 0x4f4f +0x8f5b 0x5145 +0x8f5c 0x5341 +0x8f5d 0x5f93 +0x8f5e 0x620e +0x8f5f 0x67d4 +0x8f60 0x6c41 +0x8f61 0x6e0b +0x8f62 0x7363 +0x8f63 0x7e26 +0x8f64 0x91cd +0x8f65 0x9283 +0x8f66 0x53d4 +0x8f67 0x5919 +0x8f68 0x5bbf +0x8f69 0x6dd1 +0x8f6a 0x795d +0x8f6b 0x7e2e +0x8f6c 0x7c9b +0x8f6d 0x587e +0x8f6e 0x719f +0x8f6f 0x51fa +0x8f70 0x8853 +0x8f71 0x8ff0 +0x8f72 0x4fca +0x8f73 0x5cfb +0x8f74 0x6625 +0x8f75 0x77ac +0x8f76 0x7ae3 +0x8f77 0x821c +0x8f78 0x99ff +0x8f79 0x51c6 +0x8f7a 0x5faa +0x8f7b 0x65ec +0x8f7c 0x696f +0x8f7d 0x6b89 +0x8f7e 0x6df3 +0x8f80 0x6e96 +0x8f81 0x6f64 +0x8f82 0x76fe +0x8f83 0x7d14 +0x8f84 0x5de1 +0x8f85 0x9075 +0x8f86 0x9187 +0x8f87 0x9806 +0x8f88 0x51e6 +0x8f89 0x521d +0x8f8a 0x6240 +0x8f8b 0x6691 +0x8f8c 0x66d9 +0x8f8d 0x6e1a +0x8f8e 0x5eb6 +0x8f8f 0x7dd2 +0x8f90 0x7f72 +0x8f91 0x66f8 +0x8f92 0x85af +0x8f93 0x85f7 +0x8f94 0x8af8 +0x8f95 0x52a9 +0x8f96 0x53d9 +0x8f97 0x5973 +0x8f98 0x5e8f +0x8f99 0x5f90 +0x8f9a 0x6055 +0x8f9b 0x92e4 +0x8f9c 0x9664 +0x8f9d 0x50b7 +0x8f9e 0x511f +0x8f9f 0x52dd +0x8fa0 0x5320 +0x8fa1 0x5347 +0x8fa2 0x53ec +0x8fa3 0x54e8 +0x8fa4 0x5546 +0x8fa5 0x5531 +0x8fa6 0x5617 +0x8fa7 0x5968 +0x8fa8 0x59be +0x8fa9 0x5a3c +0x8faa 0x5bb5 +0x8fab 0x5c06 +0x8fac 0x5c0f +0x8fad 0x5c11 +0x8fae 0x5c1a +0x8faf 0x5e84 +0x8fb0 0x5e8a +0x8fb1 0x5ee0 +0x8fb2 0x5f70 +0x8fb3 0x627f +0x8fb4 0x6284 +0x8fb5 0x62db +0x8fb6 0x638c +0x8fb7 0x6377 +0x8fb8 0x6607 +0x8fb9 0x660c +0x8fba 0x662d +0x8fbb 0x6676 +0x8fbc 0x677e +0x8fbd 0x68a2 +0x8fbe 0x6a1f +0x8fbf 0x6a35 +0x8fc0 0x6cbc +0x8fc1 0x6d88 +0x8fc2 0x6e09 +0x8fc3 0x6e58 +0x8fc4 0x713c +0x8fc5 0x7126 +0x8fc6 0x7167 +0x8fc7 0x75c7 +0x8fc8 0x7701 +0x8fc9 0x785d +0x8fca 0x7901 +0x8fcb 0x7965 +0x8fcc 0x79f0 +0x8fcd 0x7ae0 +0x8fce 0x7b11 +0x8fcf 0x7ca7 +0x8fd0 0x7d39 +0x8fd1 0x8096 +0x8fd2 0x83d6 +0x8fd3 0x848b +0x8fd4 0x8549 +0x8fd5 0x885d +0x8fd6 0x88f3 +0x8fd7 0x8a1f +0x8fd8 0x8a3c +0x8fd9 0x8a54 +0x8fda 0x8a73 +0x8fdb 0x8c61 +0x8fdc 0x8cde +0x8fdd 0x91a4 +0x8fde 0x9266 +0x8fdf 0x937e +0x8fe0 0x9418 +0x8fe1 0x969c +0x8fe2 0x9798 +0x8fe3 0x4e0a +0x8fe4 0x4e08 +0x8fe5 0x4e1e +0x8fe6 0x4e57 +0x8fe7 0x5197 +0x8fe8 0x5270 +0x8fe9 0x57ce +0x8fea 0x5834 +0x8feb 0x58cc +0x8fec 0x5b22 +0x8fed 0x5e38 +0x8fee 0x60c5 +0x8fef 0x64fe +0x8ff0 0x6761 +0x8ff1 0x6756 +0x8ff2 0x6d44 +0x8ff3 0x72b6 +0x8ff4 0x7573 +0x8ff5 0x7a63 +0x8ff6 0x84b8 +0x8ff7 0x8b72 +0x8ff8 0x91b8 +0x8ff9 0x9320 +0x8ffa 0x5631 +0x8ffb 0x57f4 +0x8ffc 0x98fe +0x9040 0x62ed +0x9041 0x690d +0x9042 0x6b96 +0x9043 0x71ed +0x9044 0x7e54 +0x9045 0x8077 +0x9046 0x8272 +0x9047 0x89e6 +0x9048 0x98df +0x9049 0x8755 +0x904a 0x8fb1 +0x904b 0x5c3b +0x904c 0x4f38 +0x904d 0x4fe1 +0x904e 0x4fb5 +0x904f 0x5507 +0x9050 0x5a20 +0x9051 0x5bdd +0x9052 0x5be9 +0x9053 0x5fc3 +0x9054 0x614e +0x9055 0x632f +0x9056 0x65b0 +0x9057 0x664b +0x9058 0x68ee +0x9059 0x699b +0x905a 0x6d78 +0x905b 0x6df1 +0x905c 0x7533 +0x905d 0x75b9 +0x905e 0x771f +0x905f 0x795e +0x9060 0x79e6 +0x9061 0x7d33 +0x9062 0x81e3 +0x9063 0x82af +0x9064 0x85aa +0x9065 0x89aa +0x9066 0x8a3a +0x9067 0x8eab +0x9068 0x8f9b +0x9069 0x9032 +0x906a 0x91dd +0x906b 0x9707 +0x906c 0x4eba +0x906d 0x4ec1 +0x906e 0x5203 +0x906f 0x5875 +0x9070 0x58ec +0x9071 0x5c0b +0x9072 0x751a +0x9073 0x5c3d +0x9074 0x814e +0x9075 0x8a0a +0x9076 0x8fc5 +0x9077 0x9663 +0x9078 0x976d +0x9079 0x7b25 +0x907a 0x8acf +0x907b 0x9808 +0x907c 0x9162 +0x907d 0x56f3 +0x907e 0x53a8 +0x9080 0x9017 +0x9081 0x5439 +0x9082 0x5782 +0x9083 0x5e25 +0x9084 0x63a8 +0x9085 0x6c34 +0x9086 0x708a +0x9087 0x7761 +0x9088 0x7c8b +0x9089 0x7fe0 +0x908a 0x8870 +0x908b 0x9042 +0x908c 0x9154 +0x908d 0x9310 +0x908e 0x9318 +0x908f 0x968f +0x9090 0x745e +0x9091 0x9ac4 +0x9092 0x5d07 +0x9093 0x5d69 +0x9094 0x6570 +0x9095 0x67a2 +0x9096 0x8da8 +0x9097 0x96db +0x9098 0x636e +0x9099 0x6749 +0x909a 0x6919 +0x909b 0x83c5 +0x909c 0x9817 +0x909d 0x96c0 +0x909e 0x88fe +0x909f 0x6f84 +0x90a0 0x647a +0x90a1 0x5bf8 +0x90a2 0x4e16 +0x90a3 0x702c +0x90a4 0x755d +0x90a5 0x662f +0x90a6 0x51c4 +0x90a7 0x5236 +0x90a8 0x52e2 +0x90a9 0x59d3 +0x90aa 0x5f81 +0x90ab 0x6027 +0x90ac 0x6210 +0x90ad 0x653f +0x90ae 0x6574 +0x90af 0x661f +0x90b0 0x6674 +0x90b1 0x68f2 +0x90b2 0x6816 +0x90b3 0x6b63 +0x90b4 0x6e05 +0x90b5 0x7272 +0x90b6 0x751f +0x90b7 0x76db +0x90b8 0x7cbe +0x90b9 0x8056 +0x90ba 0x58f0 +0x90bb 0x88fd +0x90bc 0x897f +0x90bd 0x8aa0 +0x90be 0x8a93 +0x90bf 0x8acb +0x90c0 0x901d +0x90c1 0x9192 +0x90c2 0x9752 +0x90c3 0x9759 +0x90c4 0x6589 +0x90c5 0x7a0e +0x90c6 0x8106 +0x90c7 0x96bb +0x90c8 0x5e2d +0x90c9 0x60dc +0x90ca 0x621a +0x90cb 0x65a5 +0x90cc 0x6614 +0x90cd 0x6790 +0x90ce 0x77f3 +0x90cf 0x7a4d +0x90d0 0x7c4d +0x90d1 0x7e3e +0x90d2 0x810a +0x90d3 0x8cac +0x90d4 0x8d64 +0x90d5 0x8de1 +0x90d6 0x8e5f +0x90d7 0x78a9 +0x90d8 0x5207 +0x90d9 0x62d9 +0x90da 0x63a5 +0x90db 0x6442 +0x90dc 0x6298 +0x90dd 0x8a2d +0x90de 0x7a83 +0x90df 0x7bc0 +0x90e0 0x8aac +0x90e1 0x96ea +0x90e2 0x7d76 +0x90e3 0x820c +0x90e4 0x8749 +0x90e5 0x4ed9 +0x90e6 0x5148 +0x90e7 0x5343 +0x90e8 0x5360 +0x90e9 0x5ba3 +0x90ea 0x5c02 +0x90eb 0x5c16 +0x90ec 0x5ddd +0x90ed 0x6226 +0x90ee 0x6247 +0x90ef 0x64b0 +0x90f0 0x6813 +0x90f1 0x6834 +0x90f2 0x6cc9 +0x90f3 0x6d45 +0x90f4 0x6d17 +0x90f5 0x67d3 +0x90f6 0x6f5c +0x90f7 0x714e +0x90f8 0x717d +0x90f9 0x65cb +0x90fa 0x7a7f +0x90fb 0x7bad +0x90fc 0x7dda +0x9140 0x7e4a +0x9141 0x7fa8 +0x9142 0x817a +0x9143 0x821b +0x9144 0x8239 +0x9145 0x85a6 +0x9146 0x8a6e +0x9147 0x8cce +0x9148 0x8df5 +0x9149 0x9078 +0x914a 0x9077 +0x914b 0x92ad +0x914c 0x9291 +0x914d 0x9583 +0x914e 0x9bae +0x914f 0x524d +0x9150 0x5584 +0x9151 0x6f38 +0x9152 0x7136 +0x9153 0x5168 +0x9154 0x7985 +0x9155 0x7e55 +0x9156 0x81b3 +0x9157 0x7cce +0x9158 0x564c +0x9159 0x5851 +0x915a 0x5ca8 +0x915b 0x63aa +0x915c 0x66fe +0x915d 0x66fd +0x915e 0x695a +0x915f 0x72d9 +0x9160 0x758f +0x9161 0x758e +0x9162 0x790e +0x9163 0x7956 +0x9164 0x79df +0x9165 0x7c97 +0x9166 0x7d20 +0x9167 0x7d44 +0x9168 0x8607 +0x9169 0x8a34 +0x916a 0x963b +0x916b 0x9061 +0x916c 0x9f20 +0x916d 0x50e7 +0x916e 0x5275 +0x916f 0x53cc +0x9170 0x53e2 +0x9171 0x5009 +0x9172 0x55aa +0x9173 0x58ee +0x9174 0x594f +0x9175 0x723d +0x9176 0x5b8b +0x9177 0x5c64 +0x9178 0x531d +0x9179 0x60e3 +0x917a 0x60f3 +0x917b 0x635c +0x917c 0x6383 +0x917d 0x633f +0x917e 0x63bb +0x9180 0x64cd +0x9181 0x65e9 +0x9182 0x66f9 +0x9183 0x5de3 +0x9184 0x69cd +0x9185 0x69fd +0x9186 0x6f15 +0x9187 0x71e5 +0x9188 0x4e89 +0x9189 0x75e9 +0x918a 0x76f8 +0x918b 0x7a93 +0x918c 0x7cdf +0x918d 0x7dcf +0x918e 0x7d9c +0x918f 0x8061 +0x9190 0x8349 +0x9191 0x8358 +0x9192 0x846c +0x9193 0x84bc +0x9194 0x85fb +0x9195 0x88c5 +0x9196 0x8d70 +0x9197 0x9001 +0x9198 0x906d +0x9199 0x9397 +0x919a 0x971c +0x919b 0x9a12 +0x919c 0x50cf +0x919d 0x5897 +0x919e 0x618e +0x919f 0x81d3 +0x91a0 0x8535 +0x91a1 0x8d08 +0x91a2 0x9020 +0x91a3 0x4fc3 +0x91a4 0x5074 +0x91a5 0x5247 +0x91a6 0x5373 +0x91a7 0x606f +0x91a8 0x6349 +0x91a9 0x675f +0x91aa 0x6e2c +0x91ab 0x8db3 +0x91ac 0x901f +0x91ad 0x4fd7 +0x91ae 0x5c5e +0x91af 0x8cca +0x91b0 0x65cf +0x91b1 0x7d9a +0x91b2 0x5352 +0x91b3 0x8896 +0x91b4 0x5176 +0x91b5 0x63c3 +0x91b6 0x5b58 +0x91b7 0x5b6b +0x91b8 0x5c0a +0x91b9 0x640d +0x91ba 0x6751 +0x91bb 0x905c +0x91bc 0x4ed6 +0x91bd 0x591a +0x91be 0x592a +0x91bf 0x6c70 +0x91c0 0x8a51 +0x91c1 0x553e +0x91c2 0x5815 +0x91c3 0x59a5 +0x91c4 0x60f0 +0x91c5 0x6253 +0x91c6 0x67c1 +0x91c7 0x8235 +0x91c8 0x6955 +0x91c9 0x9640 +0x91ca 0x99c4 +0x91cb 0x9a28 +0x91cc 0x4f53 +0x91cd 0x5806 +0x91ce 0x5bfe +0x91cf 0x8010 +0x91d0 0x5cb1 +0x91d1 0x5e2f +0x91d2 0x5f85 +0x91d3 0x6020 +0x91d4 0x614b +0x91d5 0x6234 +0x91d6 0x66ff +0x91d7 0x6cf0 +0x91d8 0x6ede +0x91d9 0x80ce +0x91da 0x817f +0x91db 0x82d4 +0x91dc 0x888b +0x91dd 0x8cb8 +0x91de 0x9000 +0x91df 0x902e +0x91e0 0x968a +0x91e1 0x9edb +0x91e2 0x9bdb +0x91e3 0x4ee3 +0x91e4 0x53f0 +0x91e5 0x5927 +0x91e6 0x7b2c +0x91e7 0x918d +0x91e8 0x984c +0x91e9 0x9df9 +0x91ea 0x6edd +0x91eb 0x7027 +0x91ec 0x5353 +0x91ed 0x5544 +0x91ee 0x5b85 +0x91ef 0x6258 +0x91f0 0x629e +0x91f1 0x62d3 +0x91f2 0x6ca2 +0x91f3 0x6fef +0x91f4 0x7422 +0x91f5 0x8a17 +0x91f6 0x9438 +0x91f7 0x6fc1 +0x91f8 0x8afe +0x91f9 0x8338 +0x91fa 0x51e7 +0x91fb 0x86f8 +0x91fc 0x53ea +0x9240 0x53e9 +0x9241 0x4f46 +0x9242 0x9054 +0x9243 0x8fb0 +0x9244 0x596a +0x9245 0x8131 +0x9246 0x5dfd +0x9247 0x7aea +0x9248 0x8fbf +0x9249 0x68da +0x924a 0x8c37 +0x924b 0x72f8 +0x924c 0x9c48 +0x924d 0x6a3d +0x924e 0x8ab0 +0x924f 0x4e39 +0x9250 0x5358 +0x9251 0x5606 +0x9252 0x5766 +0x9253 0x62c5 +0x9254 0x63a2 +0x9255 0x65e6 +0x9256 0x6b4e +0x9257 0x6de1 +0x9258 0x6e5b +0x9259 0x70ad +0x925a 0x77ed +0x925b 0x7aef +0x925c 0x7baa +0x925d 0x7dbb +0x925e 0x803d +0x925f 0x80c6 +0x9260 0x86cb +0x9261 0x8a95 +0x9262 0x935b +0x9263 0x56e3 +0x9264 0x58c7 +0x9265 0x5f3e +0x9266 0x65ad +0x9267 0x6696 +0x9268 0x6a80 +0x9269 0x6bb5 +0x926a 0x7537 +0x926b 0x8ac7 +0x926c 0x5024 +0x926d 0x77e5 +0x926e 0x5730 +0x926f 0x5f1b +0x9270 0x6065 +0x9271 0x667a +0x9272 0x6c60 +0x9273 0x75f4 +0x9274 0x7a1a +0x9275 0x7f6e +0x9276 0x81f4 +0x9277 0x8718 +0x9278 0x9045 +0x9279 0x99b3 +0x927a 0x7bc9 +0x927b 0x755c +0x927c 0x7af9 +0x927d 0x7b51 +0x927e 0x84c4 +0x9280 0x9010 +0x9281 0x79e9 +0x9282 0x7a92 +0x9283 0x8336 +0x9284 0x5ae1 +0x9285 0x7740 +0x9286 0x4e2d +0x9287 0x4ef2 +0x9288 0x5b99 +0x9289 0x5fe0 +0x928a 0x62bd +0x928b 0x663c +0x928c 0x67f1 +0x928d 0x6ce8 +0x928e 0x866b +0x928f 0x8877 +0x9290 0x8a3b +0x9291 0x914e +0x9292 0x92f3 +0x9293 0x99d0 +0x9294 0x6a17 +0x9295 0x7026 +0x9296 0x732a +0x9297 0x82e7 +0x9298 0x8457 +0x9299 0x8caf +0x929a 0x4e01 +0x929b 0x5146 +0x929c 0x51cb +0x929d 0x558b +0x929e 0x5bf5 +0x929f 0x5e16 +0x92a0 0x5e33 +0x92a1 0x5e81 +0x92a2 0x5f14 +0x92a3 0x5f35 +0x92a4 0x5f6b +0x92a5 0x5fb4 +0x92a6 0x61f2 +0x92a7 0x6311 +0x92a8 0x66a2 +0x92a9 0x671d +0x92aa 0x6f6e +0x92ab 0x7252 +0x92ac 0x753a +0x92ad 0x773a +0x92ae 0x8074 +0x92af 0x8139 +0x92b0 0x8178 +0x92b1 0x8776 +0x92b2 0x8abf +0x92b3 0x8adc +0x92b4 0x8d85 +0x92b5 0x8df3 +0x92b6 0x929a +0x92b7 0x9577 +0x92b8 0x9802 +0x92b9 0x9ce5 +0x92ba 0x52c5 +0x92bb 0x6357 +0x92bc 0x76f4 +0x92bd 0x6715 +0x92be 0x6c88 +0x92bf 0x73cd +0x92c0 0x8cc3 +0x92c1 0x93ae +0x92c2 0x9673 +0x92c3 0x6d25 +0x92c4 0x589c +0x92c5 0x690e +0x92c6 0x69cc +0x92c7 0x8ffd +0x92c8 0x939a +0x92c9 0x75db +0x92ca 0x901a +0x92cb 0x585a +0x92cc 0x6802 +0x92cd 0x63b4 +0x92ce 0x69fb +0x92cf 0x4f43 +0x92d0 0x6f2c +0x92d1 0x67d8 +0x92d2 0x8fbb +0x92d3 0x8526 +0x92d4 0x7db4 +0x92d5 0x9354 +0x92d6 0x693f +0x92d7 0x6f70 +0x92d8 0x576a +0x92d9 0x58f7 +0x92da 0x5b2c +0x92db 0x7d2c +0x92dc 0x722a +0x92dd 0x540a +0x92de 0x91e3 +0x92df 0x9db4 +0x92e0 0x4ead +0x92e1 0x4f4e +0x92e2 0x505c +0x92e3 0x5075 +0x92e4 0x5243 +0x92e5 0x8c9e +0x92e6 0x5448 +0x92e7 0x5824 +0x92e8 0x5b9a +0x92e9 0x5e1d +0x92ea 0x5e95 +0x92eb 0x5ead +0x92ec 0x5ef7 +0x92ed 0x5f1f +0x92ee 0x608c +0x92ef 0x62b5 +0x92f0 0x633a +0x92f1 0x63d0 +0x92f2 0x68af +0x92f3 0x6c40 +0x92f4 0x7887 +0x92f5 0x798e +0x92f6 0x7a0b +0x92f7 0x7de0 +0x92f8 0x8247 +0x92f9 0x8a02 +0x92fa 0x8ae6 +0x92fb 0x8e44 +0x92fc 0x9013 +0x9340 0x90b8 +0x9341 0x912d +0x9342 0x91d8 +0x9343 0x9f0e +0x9344 0x6ce5 +0x9345 0x6458 +0x9346 0x64e2 +0x9347 0x6575 +0x9348 0x6ef4 +0x9349 0x7684 +0x934a 0x7b1b +0x934b 0x9069 +0x934c 0x93d1 +0x934d 0x6eba +0x934e 0x54f2 +0x934f 0x5fb9 +0x9350 0x64a4 +0x9351 0x8f4d +0x9352 0x8fed +0x9353 0x9244 +0x9354 0x5178 +0x9355 0x586b +0x9356 0x5929 +0x9357 0x5c55 +0x9358 0x5e97 +0x9359 0x6dfb +0x935a 0x7e8f +0x935b 0x751c +0x935c 0x8cbc +0x935d 0x8ee2 +0x935e 0x985b +0x935f 0x70b9 +0x9360 0x4f1d +0x9361 0x6bbf +0x9362 0x6fb1 +0x9363 0x7530 +0x9364 0x96fb +0x9365 0x514e +0x9366 0x5410 +0x9367 0x5835 +0x9368 0x5857 +0x9369 0x59ac +0x936a 0x5c60 +0x936b 0x5f92 +0x936c 0x6597 +0x936d 0x675c +0x936e 0x6e21 +0x936f 0x767b +0x9370 0x83df +0x9371 0x8ced +0x9372 0x9014 +0x9373 0x90fd +0x9374 0x934d +0x9375 0x7825 +0x9376 0x783a +0x9377 0x52aa +0x9378 0x5ea6 +0x9379 0x571f +0x937a 0x5974 +0x937b 0x6012 +0x937c 0x5012 +0x937d 0x515a +0x937e 0x51ac +0x9380 0x51cd +0x9381 0x5200 +0x9382 0x5510 +0x9383 0x5854 +0x9384 0x5858 +0x9385 0x5957 +0x9386 0x5b95 +0x9387 0x5cf6 +0x9388 0x5d8b +0x9389 0x60bc +0x938a 0x6295 +0x938b 0x642d +0x938c 0x6771 +0x938d 0x6843 +0x938e 0x68bc +0x938f 0x68df +0x9390 0x76d7 +0x9391 0x6dd8 +0x9392 0x6e6f +0x9393 0x6d9b +0x9394 0x706f +0x9395 0x71c8 +0x9396 0x5f53 +0x9397 0x75d8 +0x9398 0x7977 +0x9399 0x7b49 +0x939a 0x7b54 +0x939b 0x7b52 +0x939c 0x7cd6 +0x939d 0x7d71 +0x939e 0x5230 +0x939f 0x8463 +0x93a0 0x8569 +0x93a1 0x85e4 +0x93a2 0x8a0e +0x93a3 0x8b04 +0x93a4 0x8c46 +0x93a5 0x8e0f +0x93a6 0x9003 +0x93a7 0x900f +0x93a8 0x9419 +0x93a9 0x9676 +0x93aa 0x982d +0x93ab 0x9a30 +0x93ac 0x95d8 +0x93ad 0x50cd +0x93ae 0x52d5 +0x93af 0x540c +0x93b0 0x5802 +0x93b1 0x5c0e +0x93b2 0x61a7 +0x93b3 0x649e +0x93b4 0x6d1e +0x93b5 0x77b3 +0x93b6 0x7ae5 +0x93b7 0x80f4 +0x93b8 0x8404 +0x93b9 0x9053 +0x93ba 0x9285 +0x93bb 0x5ce0 +0x93bc 0x9d07 +0x93bd 0x533f +0x93be 0x5f97 +0x93bf 0x5fb3 +0x93c0 0x6d9c +0x93c1 0x7279 +0x93c2 0x7763 +0x93c3 0x79bf +0x93c4 0x7be4 +0x93c5 0x6bd2 +0x93c6 0x72ec +0x93c7 0x8aad +0x93c8 0x6803 +0x93c9 0x6a61 +0x93ca 0x51f8 +0x93cb 0x7a81 +0x93cc 0x6934 +0x93cd 0x5c4a +0x93ce 0x9cf6 +0x93cf 0x82eb +0x93d0 0x5bc5 +0x93d1 0x9149 +0x93d2 0x701e +0x93d3 0x5678 +0x93d4 0x5c6f +0x93d5 0x60c7 +0x93d6 0x6566 +0x93d7 0x6c8c +0x93d8 0x8c5a +0x93d9 0x9041 +0x93da 0x9813 +0x93db 0x5451 +0x93dc 0x66c7 +0x93dd 0x920d +0x93de 0x5948 +0x93df 0x90a3 +0x93e0 0x5185 +0x93e1 0x4e4d +0x93e2 0x51ea +0x93e3 0x8599 +0x93e4 0x8b0e +0x93e5 0x7058 +0x93e6 0x637a +0x93e7 0x934b +0x93e8 0x6962 +0x93e9 0x99b4 +0x93ea 0x7e04 +0x93eb 0x7577 +0x93ec 0x5357 +0x93ed 0x6960 +0x93ee 0x8edf +0x93ef 0x96e3 +0x93f0 0x6c5d +0x93f1 0x4e8c +0x93f2 0x5c3c +0x93f3 0x5f10 +0x93f4 0x8fe9 +0x93f5 0x5302 +0x93f6 0x8cd1 +0x93f7 0x8089 +0x93f8 0x8679 +0x93f9 0x5eff +0x93fa 0x65e5 +0x93fb 0x4e73 +0x93fc 0x5165 +0x9440 0x5982 +0x9441 0x5c3f +0x9442 0x97ee +0x9443 0x4efb +0x9444 0x598a +0x9445 0x5fcd +0x9446 0x8a8d +0x9447 0x6fe1 +0x9448 0x79b0 +0x9449 0x7962 +0x944a 0x5be7 +0x944b 0x8471 +0x944c 0x732b +0x944d 0x71b1 +0x944e 0x5e74 +0x944f 0x5ff5 +0x9450 0x637b +0x9451 0x649a +0x9452 0x71c3 +0x9453 0x7c98 +0x9454 0x4e43 +0x9455 0x5efc +0x9456 0x4e4b +0x9457 0x57dc +0x9458 0x56a2 +0x9459 0x60a9 +0x945a 0x6fc3 +0x945b 0x7d0d +0x945c 0x80fd +0x945d 0x8133 +0x945e 0x81bf +0x945f 0x8fb2 +0x9460 0x8997 +0x9461 0x86a4 +0x9462 0x5df4 +0x9463 0x628a +0x9464 0x64ad +0x9465 0x8987 +0x9466 0x6777 +0x9467 0x6ce2 +0x9468 0x6d3e +0x9469 0x7436 +0x946a 0x7834 +0x946b 0x5a46 +0x946c 0x7f75 +0x946d 0x82ad +0x946e 0x99ac +0x946f 0x4ff3 +0x9470 0x5ec3 +0x9471 0x62dd +0x9472 0x6392 +0x9473 0x6557 +0x9474 0x676f +0x9475 0x76c3 +0x9476 0x724c +0x9477 0x80cc +0x9478 0x80ba +0x9479 0x8f29 +0x947a 0x914d +0x947b 0x500d +0x947c 0x57f9 +0x947d 0x5a92 +0x947e 0x6885 +0x9480 0x6973 +0x9481 0x7164 +0x9482 0x72fd +0x9483 0x8cb7 +0x9484 0x58f2 +0x9485 0x8ce0 +0x9486 0x966a +0x9487 0x9019 +0x9488 0x877f +0x9489 0x79e4 +0x948a 0x77e7 +0x948b 0x8429 +0x948c 0x4f2f +0x948d 0x5265 +0x948e 0x535a +0x948f 0x62cd +0x9490 0x67cf +0x9491 0x6cca +0x9492 0x767d +0x9493 0x7b94 +0x9494 0x7c95 +0x9495 0x8236 +0x9496 0x8584 +0x9497 0x8feb +0x9498 0x66dd +0x9499 0x6f20 +0x949a 0x7206 +0x949b 0x7e1b +0x949c 0x83ab +0x949d 0x99c1 +0x949e 0x9ea6 +0x949f 0x51fd +0x94a0 0x7bb1 +0x94a1 0x7872 +0x94a2 0x7bb8 +0x94a3 0x8087 +0x94a4 0x7b48 +0x94a5 0x6ae8 +0x94a6 0x5e61 +0x94a7 0x808c +0x94a8 0x7551 +0x94a9 0x7560 +0x94aa 0x516b +0x94ab 0x9262 +0x94ac 0x6e8c +0x94ad 0x767a +0x94ae 0x9197 +0x94af 0x9aea +0x94b0 0x4f10 +0x94b1 0x7f70 +0x94b2 0x629c +0x94b3 0x7b4f +0x94b4 0x95a5 +0x94b5 0x9ce9 +0x94b6 0x567a +0x94b7 0x5859 +0x94b8 0x86e4 +0x94b9 0x96bc +0x94ba 0x4f34 +0x94bb 0x5224 +0x94bc 0x534a +0x94bd 0x53cd +0x94be 0x53db +0x94bf 0x5e06 +0x94c0 0x642c +0x94c1 0x6591 +0x94c2 0x677f +0x94c3 0x6c3e +0x94c4 0x6c4e +0x94c5 0x7248 +0x94c6 0x72af +0x94c7 0x73ed +0x94c8 0x7554 +0x94c9 0x7e41 +0x94ca 0x822c +0x94cb 0x85e9 +0x94cc 0x8ca9 +0x94cd 0x7bc4 +0x94ce 0x91c6 +0x94cf 0x7169 +0x94d0 0x9812 +0x94d1 0x98ef +0x94d2 0x633d +0x94d3 0x6669 +0x94d4 0x756a +0x94d5 0x76e4 +0x94d6 0x78d0 +0x94d7 0x8543 +0x94d8 0x86ee +0x94d9 0x532a +0x94da 0x5351 +0x94db 0x5426 +0x94dc 0x5983 +0x94dd 0x5e87 +0x94de 0x5f7c +0x94df 0x60b2 +0x94e0 0x6249 +0x94e1 0x6279 +0x94e2 0x62ab +0x94e3 0x6590 +0x94e4 0x6bd4 +0x94e5 0x6ccc +0x94e6 0x75b2 +0x94e7 0x76ae +0x94e8 0x7891 +0x94e9 0x79d8 +0x94ea 0x7dcb +0x94eb 0x7f77 +0x94ec 0x80a5 +0x94ed 0x88ab +0x94ee 0x8ab9 +0x94ef 0x8cbb +0x94f0 0x907f +0x94f1 0x975e +0x94f2 0x98db +0x94f3 0x6a0b +0x94f4 0x7c38 +0x94f5 0x5099 +0x94f6 0x5c3e +0x94f7 0x5fae +0x94f8 0x6787 +0x94f9 0x6bd8 +0x94fa 0x7435 +0x94fb 0x7709 +0x94fc 0x7f8e +0x9540 0x9f3b +0x9541 0x67ca +0x9542 0x7a17 +0x9543 0x5339 +0x9544 0x758b +0x9545 0x9aed +0x9546 0x5f66 +0x9547 0x819d +0x9548 0x83f1 +0x9549 0x8098 +0x954a 0x5f3c +0x954b 0x5fc5 +0x954c 0x7562 +0x954d 0x7b46 +0x954e 0x903c +0x954f 0x6867 +0x9550 0x59eb +0x9551 0x5a9b +0x9552 0x7d10 +0x9553 0x767e +0x9554 0x8b2c +0x9555 0x4ff5 +0x9556 0x5f6a +0x9557 0x6a19 +0x9558 0x6c37 +0x9559 0x6f02 +0x955a 0x74e2 +0x955b 0x7968 +0x955c 0x8868 +0x955d 0x8a55 +0x955e 0x8c79 +0x955f 0x5edf +0x9560 0x63cf +0x9561 0x75c5 +0x9562 0x79d2 +0x9563 0x82d7 +0x9564 0x9328 +0x9565 0x92f2 +0x9566 0x849c +0x9567 0x86ed +0x9568 0x9c2d +0x9569 0x54c1 +0x956a 0x5f6c +0x956b 0x658c +0x956c 0x6d5c +0x956d 0x7015 +0x956e 0x8ca7 +0x956f 0x8cd3 +0x9570 0x983b +0x9571 0x654f +0x9572 0x74f6 +0x9573 0x4e0d +0x9574 0x4ed8 +0x9575 0x57e0 +0x9576 0x592b +0x9577 0x5a66 +0x9578 0x5bcc +0x9579 0x51a8 +0x957a 0x5e03 +0x957b 0x5e9c +0x957c 0x6016 +0x957d 0x6276 +0x957e 0x6577 +0x9580 0x65a7 +0x9581 0x666e +0x9582 0x6d6e +0x9583 0x7236 +0x9584 0x7b26 +0x9585 0x8150 +0x9586 0x819a +0x9587 0x8299 +0x9588 0x8b5c +0x9589 0x8ca0 +0x958a 0x8ce6 +0x958b 0x8d74 +0x958c 0x961c +0x958d 0x9644 +0x958e 0x4fae +0x958f 0x64ab +0x9590 0x6b66 +0x9591 0x821e +0x9592 0x8461 +0x9593 0x856a +0x9594 0x90e8 +0x9595 0x5c01 +0x9596 0x6953 +0x9597 0x98a8 +0x9598 0x847a +0x9599 0x8557 +0x959a 0x4f0f +0x959b 0x526f +0x959c 0x5fa9 +0x959d 0x5e45 +0x959e 0x670d +0x959f 0x798f +0x95a0 0x8179 +0x95a1 0x8907 +0x95a2 0x8986 +0x95a3 0x6df5 +0x95a4 0x5f17 +0x95a5 0x6255 +0x95a6 0x6cb8 +0x95a7 0x4ecf +0x95a8 0x7269 +0x95a9 0x9b92 +0x95aa 0x5206 +0x95ab 0x543b +0x95ac 0x5674 +0x95ad 0x58b3 +0x95ae 0x61a4 +0x95af 0x626e +0x95b0 0x711a +0x95b1 0x596e +0x95b2 0x7c89 +0x95b3 0x7cde +0x95b4 0x7d1b +0x95b5 0x96f0 +0x95b6 0x6587 +0x95b7 0x805e +0x95b8 0x4e19 +0x95b9 0x4f75 +0x95ba 0x5175 +0x95bb 0x5840 +0x95bc 0x5e63 +0x95bd 0x5e73 +0x95be 0x5f0a +0x95bf 0x67c4 +0x95c0 0x4e26 +0x95c1 0x853d +0x95c2 0x9589 +0x95c3 0x965b +0x95c4 0x7c73 +0x95c5 0x9801 +0x95c6 0x50fb +0x95c7 0x58c1 +0x95c8 0x7656 +0x95c9 0x78a7 +0x95ca 0x5225 +0x95cb 0x77a5 +0x95cc 0x8511 +0x95cd 0x7b86 +0x95ce 0x504f +0x95cf 0x5909 +0x95d0 0x7247 +0x95d1 0x7bc7 +0x95d2 0x7de8 +0x95d3 0x8fba +0x95d4 0x8fd4 +0x95d5 0x904d +0x95d6 0x4fbf +0x95d7 0x52c9 +0x95d8 0x5a29 +0x95d9 0x5f01 +0x95da 0x97ad +0x95db 0x4fdd +0x95dc 0x8217 +0x95dd 0x92ea +0x95de 0x5703 +0x95df 0x6355 +0x95e0 0x6b69 +0x95e1 0x752b +0x95e2 0x88dc +0x95e3 0x8f14 +0x95e4 0x7a42 +0x95e5 0x52df +0x95e6 0x5893 +0x95e7 0x6155 +0x95e8 0x620a +0x95e9 0x66ae +0x95ea 0x6bcd +0x95eb 0x7c3f +0x95ec 0x83e9 +0x95ed 0x5023 +0x95ee 0x4ff8 +0x95ef 0x5305 +0x95f0 0x5446 +0x95f1 0x5831 +0x95f2 0x5949 +0x95f3 0x5b9d +0x95f4 0x5cf0 +0x95f5 0x5cef +0x95f6 0x5d29 +0x95f7 0x5e96 +0x95f8 0x62b1 +0x95f9 0x6367 +0x95fa 0x653e +0x95fb 0x65b9 +0x95fc 0x670b +0x9640 0x6cd5 +0x9641 0x6ce1 +0x9642 0x70f9 +0x9643 0x7832 +0x9644 0x7e2b +0x9645 0x80de +0x9646 0x82b3 +0x9647 0x840c +0x9648 0x84ec +0x9649 0x8702 +0x964a 0x8912 +0x964b 0x8a2a +0x964c 0x8c4a +0x964d 0x90a6 +0x964e 0x92d2 +0x964f 0x98fd +0x9650 0x9cf3 +0x9651 0x9d6c +0x9652 0x4e4f +0x9653 0x4ea1 +0x9654 0x508d +0x9655 0x5256 +0x9656 0x574a +0x9657 0x59a8 +0x9658 0x5e3d +0x9659 0x5fd8 +0x965a 0x5fd9 +0x965b 0x623f +0x965c 0x66b4 +0x965d 0x671b +0x965e 0x67d0 +0x965f 0x68d2 +0x9660 0x5192 +0x9661 0x7d21 +0x9662 0x80aa +0x9663 0x81a8 +0x9664 0x8b00 +0x9665 0x8c8c +0x9666 0x8cbf +0x9667 0x927e +0x9668 0x9632 +0x9669 0x5420 +0x966a 0x982c +0x966b 0x5317 +0x966c 0x50d5 +0x966d 0x535c +0x966e 0x58a8 +0x966f 0x64b2 +0x9670 0x6734 +0x9671 0x7267 +0x9672 0x7766 +0x9673 0x7a46 +0x9674 0x91e6 +0x9675 0x52c3 +0x9676 0x6ca1 +0x9677 0x6b86 +0x9678 0x5800 +0x9679 0x5e4c +0x967a 0x5954 +0x967b 0x672c +0x967c 0x7ffb +0x967d 0x51e1 +0x967e 0x76c6 +0x9680 0x6469 +0x9681 0x78e8 +0x9682 0x9b54 +0x9683 0x9ebb +0x9684 0x57cb +0x9685 0x59b9 +0x9686 0x6627 +0x9687 0x679a +0x9688 0x6bce +0x9689 0x54e9 +0x968a 0x69d9 +0x968b 0x5e55 +0x968c 0x819c +0x968d 0x6795 +0x968e 0x9baa +0x968f 0x67fe +0x9690 0x9c52 +0x9691 0x685d +0x9692 0x4ea6 +0x9693 0x4fe3 +0x9694 0x53c8 +0x9695 0x62b9 +0x9696 0x672b +0x9697 0x6cab +0x9698 0x8fc4 +0x9699 0x4fad +0x969a 0x7e6d +0x969b 0x9ebf +0x969c 0x4e07 +0x969d 0x6162 +0x969e 0x6e80 +0x969f 0x6f2b +0x96a0 0x8513 +0x96a1 0x5473 +0x96a2 0x672a +0x96a3 0x9b45 +0x96a4 0x5df3 +0x96a5 0x7b95 +0x96a6 0x5cac +0x96a7 0x5bc6 +0x96a8 0x871c +0x96a9 0x6e4a +0x96aa 0x84d1 +0x96ab 0x7a14 +0x96ac 0x8108 +0x96ad 0x5999 +0x96ae 0x7c8d +0x96af 0x6c11 +0x96b0 0x7720 +0x96b1 0x52d9 +0x96b2 0x5922 +0x96b3 0x7121 +0x96b4 0x725f +0x96b5 0x77db +0x96b6 0x9727 +0x96b7 0x9d61 +0x96b8 0x690b +0x96b9 0x5a7f +0x96ba 0x5a18 +0x96bb 0x51a5 +0x96bc 0x540d +0x96bd 0x547d +0x96be 0x660e +0x96bf 0x76df +0x96c0 0x8ff7 +0x96c1 0x9298 +0x96c2 0x9cf4 +0x96c3 0x59ea +0x96c4 0x725d +0x96c5 0x6ec5 +0x96c6 0x514d +0x96c7 0x68c9 +0x96c8 0x7dbf +0x96c9 0x7dec +0x96ca 0x9762 +0x96cb 0x9eba +0x96cc 0x6478 +0x96cd 0x6a21 +0x96ce 0x8302 +0x96cf 0x5984 +0x96d0 0x5b5f +0x96d1 0x6bdb +0x96d2 0x731b +0x96d3 0x76f2 +0x96d4 0x7db2 +0x96d5 0x8017 +0x96d6 0x8499 +0x96d7 0x5132 +0x96d8 0x6728 +0x96d9 0x9ed9 +0x96da 0x76ee +0x96db 0x6762 +0x96dc 0x52ff +0x96dd 0x9905 +0x96de 0x5c24 +0x96df 0x623b +0x96e0 0x7c7e +0x96e1 0x8cb0 +0x96e2 0x554f +0x96e3 0x60b6 +0x96e4 0x7d0b +0x96e5 0x9580 +0x96e6 0x5301 +0x96e7 0x4e5f +0x96e8 0x51b6 +0x96e9 0x591c +0x96ea 0x723a +0x96eb 0x8036 +0x96ec 0x91ce +0x96ed 0x5f25 +0x96ee 0x77e2 +0x96ef 0x5384 +0x96f0 0x5f79 +0x96f1 0x7d04 +0x96f2 0x85ac +0x96f3 0x8a33 +0x96f4 0x8e8d +0x96f5 0x9756 +0x96f6 0x67f3 +0x96f7 0x85ae +0x96f8 0x9453 +0x96f9 0x6109 +0x96fa 0x6108 +0x96fb 0x6cb9 +0x96fc 0x7652 +0x9740 0x8aed +0x9741 0x8f38 +0x9742 0x552f +0x9743 0x4f51 +0x9744 0x512a +0x9745 0x52c7 +0x9746 0x53cb +0x9747 0x5ba5 +0x9748 0x5e7d +0x9749 0x60a0 +0x974a 0x6182 +0x974b 0x63d6 +0x974c 0x6709 +0x974d 0x67da +0x974e 0x6e67 +0x974f 0x6d8c +0x9750 0x7336 +0x9751 0x7337 +0x9752 0x7531 +0x9753 0x7950 +0x9754 0x88d5 +0x9755 0x8a98 +0x9756 0x904a +0x9757 0x9091 +0x9758 0x90f5 +0x9759 0x96c4 +0x975a 0x878d +0x975b 0x5915 +0x975c 0x4e88 +0x975d 0x4f59 +0x975e 0x4e0e +0x975f 0x8a89 +0x9760 0x8f3f +0x9761 0x9810 +0x9762 0x50ad +0x9763 0x5e7c +0x9764 0x5996 +0x9765 0x5bb9 +0x9766 0x5eb8 +0x9767 0x63da +0x9768 0x63fa +0x9769 0x64c1 +0x976a 0x66dc +0x976b 0x694a +0x976c 0x69d8 +0x976d 0x6d0b +0x976e 0x6eb6 +0x976f 0x7194 +0x9770 0x7528 +0x9771 0x7aaf +0x9772 0x7f8a +0x9773 0x8000 +0x9774 0x8449 +0x9775 0x84c9 +0x9776 0x8981 +0x9777 0x8b21 +0x9778 0x8e0a +0x9779 0x9065 +0x977a 0x967d +0x977b 0x990a +0x977c 0x617e +0x977d 0x6291 +0x977e 0x6b32 +0x9780 0x6c83 +0x9781 0x6d74 +0x9782 0x7fcc +0x9783 0x7ffc +0x9784 0x6dc0 +0x9785 0x7f85 +0x9786 0x87ba +0x9787 0x88f8 +0x9788 0x6765 +0x9789 0x83b1 +0x978a 0x983c +0x978b 0x96f7 +0x978c 0x6d1b +0x978d 0x7d61 +0x978e 0x843d +0x978f 0x916a +0x9790 0x4e71 +0x9791 0x5375 +0x9792 0x5d50 +0x9793 0x6b04 +0x9794 0x6feb +0x9795 0x85cd +0x9796 0x862d +0x9797 0x89a7 +0x9798 0x5229 +0x9799 0x540f +0x979a 0x5c65 +0x979b 0x674e +0x979c 0x68a8 +0x979d 0x7406 +0x979e 0x7483 +0x979f 0x75e2 +0x97a0 0x88cf +0x97a1 0x88e1 +0x97a2 0x91cc +0x97a3 0x96e2 +0x97a4 0x9678 +0x97a5 0x5f8b +0x97a6 0x7387 +0x97a7 0x7acb +0x97a8 0x844e +0x97a9 0x63a0 +0x97aa 0x7565 +0x97ab 0x5289 +0x97ac 0x6d41 +0x97ad 0x6e9c +0x97ae 0x7409 +0x97af 0x7559 +0x97b0 0x786b +0x97b1 0x7c92 +0x97b2 0x9686 +0x97b3 0x7adc +0x97b4 0x9f8d +0x97b5 0x4fb6 +0x97b6 0x616e +0x97b7 0x65c5 +0x97b8 0x865c +0x97b9 0x4e86 +0x97ba 0x4eae +0x97bb 0x50da +0x97bc 0x4e21 +0x97bd 0x51cc +0x97be 0x5bee +0x97bf 0x6599 +0x97c0 0x6881 +0x97c1 0x6dbc +0x97c2 0x731f +0x97c3 0x7642 +0x97c4 0x77ad +0x97c5 0x7a1c +0x97c6 0x7ce7 +0x97c7 0x826f +0x97c8 0x8ad2 +0x97c9 0x907c +0x97ca 0x91cf +0x97cb 0x9675 +0x97cc 0x9818 +0x97cd 0x529b +0x97ce 0x7dd1 +0x97cf 0x502b +0x97d0 0x5398 +0x97d1 0x6797 +0x97d2 0x6dcb +0x97d3 0x71d0 +0x97d4 0x7433 +0x97d5 0x81e8 +0x97d6 0x8f2a +0x97d7 0x96a3 +0x97d8 0x9c57 +0x97d9 0x9e9f +0x97da 0x7460 +0x97db 0x5841 +0x97dc 0x6d99 +0x97dd 0x7d2f +0x97de 0x985e +0x97df 0x4ee4 +0x97e0 0x4f36 +0x97e1 0x4f8b +0x97e2 0x51b7 +0x97e3 0x52b1 +0x97e4 0x5dba +0x97e5 0x601c +0x97e6 0x73b2 +0x97e7 0x793c +0x97e8 0x82d3 +0x97e9 0x9234 +0x97ea 0x96b7 +0x97eb 0x96f6 +0x97ec 0x970a +0x97ed 0x9e97 +0x97ee 0x9f62 +0x97ef 0x66a6 +0x97f0 0x6b74 +0x97f1 0x5217 +0x97f2 0x52a3 +0x97f3 0x70c8 +0x97f4 0x88c2 +0x97f5 0x5ec9 +0x97f6 0x604b +0x97f7 0x6190 +0x97f8 0x6f23 +0x97f9 0x7149 +0x97fa 0x7c3e +0x97fb 0x7df4 +0x97fc 0x806f +0x9840 0x84ee +0x9841 0x9023 +0x9842 0x932c +0x9843 0x5442 +0x9844 0x9b6f +0x9845 0x6ad3 +0x9846 0x7089 +0x9847 0x8cc2 +0x9848 0x8def +0x9849 0x9732 +0x984a 0x52b4 +0x984b 0x5a41 +0x984c 0x5eca +0x984d 0x5f04 +0x984e 0x6717 +0x984f 0x697c +0x9850 0x6994 +0x9851 0x6d6a +0x9852 0x6f0f +0x9853 0x7262 +0x9854 0x72fc +0x9855 0x7bed +0x9856 0x8001 +0x9857 0x807e +0x9858 0x874b +0x9859 0x90ce +0x985a 0x516d +0x985b 0x9e93 +0x985c 0x7984 +0x985d 0x808b +0x985e 0x9332 +0x985f 0x8ad6 +0x9860 0x502d +0x9861 0x548c +0x9862 0x8a71 +0x9863 0x6b6a +0x9864 0x8cc4 +0x9865 0x8107 +0x9866 0x60d1 +0x9867 0x67a0 +0x9868 0x9df2 +0x9869 0x4e99 +0x986a 0x4e98 +0x986b 0x9c10 +0x986c 0x8a6b +0x986d 0x85c1 +0x986e 0x8568 +0x986f 0x6900 +0x9870 0x6e7e +0x9871 0x7897 +0x9872 0x8155 +0x9873 0x20b9f +0x9874 0x5b41 +0x9875 0x5b56 +0x9876 0x5b7d +0x9877 0x5b93 +0x9878 0x5bd8 +0x9879 0x5bec +0x987a 0x5c12 +0x987b 0x5c1e +0x987c 0x5c23 +0x987d 0x5c2b +0x987e 0x378d +0x9880 0x5c62 +0x9881 0xfa3b +0x9882 0xfa3c +0x9883 0x216b4 +0x9884 0x5c7a +0x9885 0x5c8f +0x9886 0x5c9f +0x9887 0x5ca3 +0x9888 0x5caa +0x9889 0x5cba +0x988a 0x5ccb +0x988b 0x5cd0 +0x988c 0x5cd2 +0x988d 0x5cf4 +0x988e 0x21e34 +0x988f 0x37e2 +0x9890 0x5d0d +0x9891 0x5d27 +0x9892 0xfa11 +0x9893 0x5d46 +0x9894 0x5d47 +0x9895 0x5d53 +0x9896 0x5d4a +0x9897 0x5d6d +0x9898 0x5d81 +0x9899 0x5da0 +0x989a 0x5da4 +0x989b 0x5da7 +0x989c 0x5db8 +0x989d 0x5dcb +0x989e 0x541e +0x989f 0x5f0c +0x98a0 0x4e10 +0x98a1 0x4e15 +0x98a2 0x4e2a +0x98a3 0x4e31 +0x98a4 0x4e36 +0x98a5 0x4e3c +0x98a6 0x4e3f +0x98a7 0x4e42 +0x98a8 0x4e56 +0x98a9 0x4e58 +0x98aa 0x4e82 +0x98ab 0x4e85 +0x98ac 0x8c6b +0x98ad 0x4e8a +0x98ae 0x8212 +0x98af 0x5f0d +0x98b0 0x4e8e +0x98b1 0x4e9e +0x98b2 0x4e9f +0x98b3 0x4ea0 +0x98b4 0x4ea2 +0x98b5 0x4eb0 +0x98b6 0x4eb3 +0x98b7 0x4eb6 +0x98b8 0x4ece +0x98b9 0x4ecd +0x98ba 0x4ec4 +0x98bb 0x4ec6 +0x98bc 0x4ec2 +0x98bd 0x4ed7 +0x98be 0x4ede +0x98bf 0x4eed +0x98c0 0x4edf +0x98c1 0x4ef7 +0x98c2 0x4f09 +0x98c3 0x4f5a +0x98c4 0x4f30 +0x98c5 0x4f5b +0x98c6 0x4f5d +0x98c7 0x4f57 +0x98c8 0x4f47 +0x98c9 0x4f76 +0x98ca 0x4f88 +0x98cb 0x4f8f +0x98cc 0x4f98 +0x98cd 0x4f7b +0x98ce 0x4f69 +0x98cf 0x4f70 +0x98d0 0x4f91 +0x98d1 0x4f6f +0x98d2 0x4f86 +0x98d3 0x4f96 +0x98d4 0x5118 +0x98d5 0x4fd4 +0x98d6 0x4fdf +0x98d7 0x4fce +0x98d8 0x4fd8 +0x98d9 0x4fdb +0x98da 0x4fd1 +0x98db 0x4fda +0x98dc 0x4fd0 +0x98dd 0x4fe4 +0x98de 0x4fe5 +0x98df 0x501a +0x98e0 0x5028 +0x98e1 0x5014 +0x98e2 0x502a +0x98e3 0x5025 +0x98e4 0x5005 +0x98e5 0x4f1c +0x98e6 0x4ff6 +0x98e7 0x5021 +0x98e8 0x5029 +0x98e9 0x502c +0x98ea 0x4ffe +0x98eb 0x4fef +0x98ec 0x5011 +0x98ed 0x5006 +0x98ee 0x5043 +0x98ef 0x5047 +0x98f0 0x6703 +0x98f1 0x5055 +0x98f2 0x5050 +0x98f3 0x5048 +0x98f4 0x505a +0x98f5 0x5056 +0x98f6 0x506c +0x98f7 0x5078 +0x98f8 0x5080 +0x98f9 0x509a +0x98fa 0x5085 +0x98fb 0x50b4 +0x98fc 0x50b2 +0x9940 0x50c9 +0x9941 0x50ca +0x9942 0x50b3 +0x9943 0x50c2 +0x9944 0x50d6 +0x9945 0x50de +0x9946 0x50e5 +0x9947 0x50ed +0x9948 0x50e3 +0x9949 0x50ee +0x994a 0x50f9 +0x994b 0x50f5 +0x994c 0x5109 +0x994d 0x5101 +0x994e 0x5102 +0x994f 0x5116 +0x9950 0x5115 +0x9951 0x5114 +0x9952 0x511a +0x9953 0x5121 +0x9954 0x513a +0x9955 0x5137 +0x9956 0x513c +0x9957 0x513b +0x9958 0x513f +0x9959 0x5140 +0x995a 0x5152 +0x995b 0x514c +0x995c 0x5154 +0x995d 0x5162 +0x995e 0x7af8 +0x995f 0x5169 +0x9960 0x516a +0x9961 0x516e +0x9962 0x5180 +0x9963 0x5182 +0x9964 0x56d8 +0x9965 0x518c +0x9966 0x5189 +0x9967 0x518f +0x9968 0x5191 +0x9969 0x5193 +0x996a 0x5195 +0x996b 0x5196 +0x996c 0x51a4 +0x996d 0x51a6 +0x996e 0x51a2 +0x996f 0x51a9 +0x9970 0x51aa +0x9971 0x51ab +0x9972 0x51b3 +0x9973 0x51b1 +0x9974 0x51b2 +0x9975 0x51b0 +0x9976 0x51b5 +0x9977 0x51bd +0x9978 0x51c5 +0x9979 0x51c9 +0x997a 0x51db +0x997b 0x51e0 +0x997c 0x8655 +0x997d 0x51e9 +0x997e 0x51ed +0x9980 0x51f0 +0x9981 0x51f5 +0x9982 0x51fe +0x9983 0x5204 +0x9984 0x520b +0x9985 0x5214 +0x9986 0x520e +0x9987 0x5227 +0x9988 0x522a +0x9989 0x522e +0x998a 0x5233 +0x998b 0x5239 +0x998c 0x524f +0x998d 0x5244 +0x998e 0x524b +0x998f 0x524c +0x9990 0x525e +0x9991 0x5254 +0x9992 0x526a +0x9993 0x5274 +0x9994 0x5269 +0x9995 0x5273 +0x9996 0x527f +0x9997 0x527d +0x9998 0x528d +0x9999 0x5294 +0x999a 0x5292 +0x999b 0x5271 +0x999c 0x5288 +0x999d 0x5291 +0x999e 0x8fa8 +0x999f 0x8fa7 +0x99a0 0x52ac +0x99a1 0x52ad +0x99a2 0x52bc +0x99a3 0x52b5 +0x99a4 0x52c1 +0x99a5 0x52cd +0x99a6 0x52d7 +0x99a7 0x52de +0x99a8 0x52e3 +0x99a9 0x52e6 +0x99aa 0x98ed +0x99ab 0x52e0 +0x99ac 0x52f3 +0x99ad 0x52f5 +0x99ae 0x52f8 +0x99af 0x52f9 +0x99b0 0x5306 +0x99b1 0x5308 +0x99b2 0x7538 +0x99b3 0x530d +0x99b4 0x5310 +0x99b5 0x530f +0x99b6 0x5315 +0x99b7 0x531a +0x99b8 0x5323 +0x99b9 0x532f +0x99ba 0x5331 +0x99bb 0x5333 +0x99bc 0x5338 +0x99bd 0x5340 +0x99be 0x5346 +0x99bf 0x5345 +0x99c0 0x4e17 +0x99c1 0x5349 +0x99c2 0x534d +0x99c3 0x51d6 +0x99c4 0x535e +0x99c5 0x5369 +0x99c6 0x536e +0x99c7 0x5918 +0x99c8 0x537b +0x99c9 0x5377 +0x99ca 0x5382 +0x99cb 0x5396 +0x99cc 0x53a0 +0x99cd 0x53a6 +0x99ce 0x53a5 +0x99cf 0x53ae +0x99d0 0x53b0 +0x99d1 0x53b6 +0x99d2 0x53c3 +0x99d3 0x7c12 +0x99d4 0x96d9 +0x99d5 0x53df +0x99d6 0x66fc +0x99d7 0x71ee +0x99d8 0x53ee +0x99d9 0x53e8 +0x99da 0x53ed +0x99db 0x53fa +0x99dc 0x5401 +0x99dd 0x543d +0x99de 0x5440 +0x99df 0x542c +0x99e0 0x542d +0x99e1 0x543c +0x99e2 0x542e +0x99e3 0x5436 +0x99e4 0x5429 +0x99e5 0x541d +0x99e6 0x544e +0x99e7 0x548f +0x99e8 0x5475 +0x99e9 0x548e +0x99ea 0x545f +0x99eb 0x5471 +0x99ec 0x5477 +0x99ed 0x5470 +0x99ee 0x5492 +0x99ef 0x547b +0x99f0 0x5480 +0x99f1 0x5476 +0x99f2 0x5484 +0x99f3 0x5490 +0x99f4 0x5486 +0x99f5 0x54c7 +0x99f6 0x54a2 +0x99f7 0x54b8 +0x99f8 0x54a5 +0x99f9 0x54ac +0x99fa 0x54c4 +0x99fb 0x54c8 +0x99fc 0x54a8 +0x9a40 0x54ab +0x9a41 0x54c2 +0x9a42 0x54a4 +0x9a43 0x54be +0x9a44 0x54bc +0x9a45 0x54d8 +0x9a46 0x54e5 +0x9a47 0x54e6 +0x9a48 0x550f +0x9a49 0x5514 +0x9a4a 0x54fd +0x9a4b 0x54ee +0x9a4c 0x54ed +0x9a4d 0x54fa +0x9a4e 0x54e2 +0x9a4f 0x5539 +0x9a50 0x5540 +0x9a51 0x5563 +0x9a52 0x554c +0x9a53 0x552e +0x9a54 0x555c +0x9a55 0x5545 +0x9a56 0x5556 +0x9a57 0x5557 +0x9a58 0x5538 +0x9a59 0x5533 +0x9a5a 0x555d +0x9a5b 0x5599 +0x9a5c 0x5580 +0x9a5d 0x54af +0x9a5e 0x558a +0x9a5f 0x559f +0x9a60 0x557b +0x9a61 0x557e +0x9a62 0x5598 +0x9a63 0x559e +0x9a64 0x55ae +0x9a65 0x557c +0x9a66 0x5583 +0x9a67 0x55a9 +0x9a68 0x5587 +0x9a69 0x55a8 +0x9a6a 0x55da +0x9a6b 0x55c5 +0x9a6c 0x55df +0x9a6d 0x55c4 +0x9a6e 0x55dc +0x9a6f 0x55e4 +0x9a70 0x55d4 +0x9a71 0x5614 +0x9a72 0x55f7 +0x9a73 0x5616 +0x9a74 0x55fe +0x9a75 0x55fd +0x9a76 0x561b +0x9a77 0x55f9 +0x9a78 0x564e +0x9a79 0x5650 +0x9a7a 0x71df +0x9a7b 0x5634 +0x9a7c 0x5636 +0x9a7d 0x5632 +0x9a7e 0x5638 +0x9a80 0x566b +0x9a81 0x5664 +0x9a82 0x562f +0x9a83 0x566c +0x9a84 0x566a +0x9a85 0x5686 +0x9a86 0x5680 +0x9a87 0x568a +0x9a88 0x56a0 +0x9a89 0x5694 +0x9a8a 0x568f +0x9a8b 0x56a5 +0x9a8c 0x56ae +0x9a8d 0x56b6 +0x9a8e 0x56b4 +0x9a8f 0x56c2 +0x9a90 0x56bc +0x9a91 0x56c1 +0x9a92 0x56c3 +0x9a93 0x56c0 +0x9a94 0x56c8 +0x9a95 0x56ce +0x9a96 0x56d1 +0x9a97 0x56d3 +0x9a98 0x56d7 +0x9a99 0x56ee +0x9a9a 0x56f9 +0x9a9b 0x5700 +0x9a9c 0x56ff +0x9a9d 0x5704 +0x9a9e 0x5709 +0x9a9f 0x5708 +0x9aa0 0x570b +0x9aa1 0x570d +0x9aa2 0x5713 +0x9aa3 0x5718 +0x9aa4 0x5716 +0x9aa5 0x55c7 +0x9aa6 0x571c +0x9aa7 0x5726 +0x9aa8 0x5737 +0x9aa9 0x5738 +0x9aaa 0x574e +0x9aab 0x573b +0x9aac 0x5740 +0x9aad 0x574f +0x9aae 0x5769 +0x9aaf 0x57c0 +0x9ab0 0x5788 +0x9ab1 0x5761 +0x9ab2 0x577f +0x9ab3 0x5789 +0x9ab4 0x5793 +0x9ab5 0x57a0 +0x9ab6 0x57b3 +0x9ab7 0x57a4 +0x9ab8 0x57aa +0x9ab9 0x57b0 +0x9aba 0x57c3 +0x9abb 0x57c6 +0x9abc 0x57d4 +0x9abd 0x57d2 +0x9abe 0x57d3 +0x9abf 0x580a +0x9ac0 0x57d6 +0x9ac1 0x57e3 +0x9ac2 0x580b +0x9ac3 0x5819 +0x9ac4 0x581d +0x9ac5 0x5872 +0x9ac6 0x5821 +0x9ac7 0x5862 +0x9ac8 0x584b +0x9ac9 0x5870 +0x9aca 0x6bc0 +0x9acb 0x5852 +0x9acc 0x583d +0x9acd 0x5879 +0x9ace 0x5885 +0x9acf 0x58b9 +0x9ad0 0x589f +0x9ad1 0x58ab +0x9ad2 0x58ba +0x9ad3 0x58de +0x9ad4 0x58bb +0x9ad5 0x58b8 +0x9ad6 0x58ae +0x9ad7 0x58c5 +0x9ad8 0x58d3 +0x9ad9 0x58d1 +0x9ada 0x58d7 +0x9adb 0x58d9 +0x9adc 0x58d8 +0x9add 0x58e5 +0x9ade 0x58dc +0x9adf 0x58e4 +0x9ae0 0x58df +0x9ae1 0x58ef +0x9ae2 0x58fa +0x9ae3 0x58f9 +0x9ae4 0x58fb +0x9ae5 0x58fc +0x9ae6 0x58fd +0x9ae7 0x5902 +0x9ae8 0x590a +0x9ae9 0x5910 +0x9aea 0x591b +0x9aeb 0x68a6 +0x9aec 0x5925 +0x9aed 0x592c +0x9aee 0x592d +0x9aef 0x5932 +0x9af0 0x5938 +0x9af1 0x593e +0x9af2 0x7ad2 +0x9af3 0x5955 +0x9af4 0x5950 +0x9af5 0x594e +0x9af6 0x595a +0x9af7 0x5958 +0x9af8 0x5962 +0x9af9 0x5960 +0x9afa 0x5967 +0x9afb 0x596c +0x9afc 0x5969 +0x9b40 0x5978 +0x9b41 0x5981 +0x9b42 0x599d +0x9b43 0x4f5e +0x9b44 0x4fab +0x9b45 0x59a3 +0x9b46 0x59b2 +0x9b47 0x59c6 +0x9b48 0x59e8 +0x9b49 0x59dc +0x9b4a 0x598d +0x9b4b 0x59d9 +0x9b4c 0x59da +0x9b4d 0x5a25 +0x9b4e 0x5a1f +0x9b4f 0x5a11 +0x9b50 0x5a1c +0x9b51 0x5a09 +0x9b52 0x5a1a +0x9b53 0x5a40 +0x9b54 0x5a6c +0x9b55 0x5a49 +0x9b56 0x5a35 +0x9b57 0x5a36 +0x9b58 0x5a62 +0x9b59 0x5a6a +0x9b5a 0x5a9a +0x9b5b 0x5abc +0x9b5c 0x5abe +0x9b5d 0x5acb +0x9b5e 0x5ac2 +0x9b5f 0x5abd +0x9b60 0x5ae3 +0x9b61 0x5ad7 +0x9b62 0x5ae6 +0x9b63 0x5ae9 +0x9b64 0x5ad6 +0x9b65 0x5afa +0x9b66 0x5afb +0x9b67 0x5b0c +0x9b68 0x5b0b +0x9b69 0x5b16 +0x9b6a 0x5b32 +0x9b6b 0x5ad0 +0x9b6c 0x5b2a +0x9b6d 0x5b36 +0x9b6e 0x5b3e +0x9b6f 0x5b43 +0x9b70 0x5b45 +0x9b71 0x5b40 +0x9b72 0x5b51 +0x9b73 0x5b55 +0x9b74 0x5b5a +0x9b75 0x5b5b +0x9b76 0x5b65 +0x9b77 0x5b69 +0x9b78 0x5b70 +0x9b79 0x5b73 +0x9b7a 0x5b75 +0x9b7b 0x5b78 +0x9b7c 0x6588 +0x9b7d 0x5b7a +0x9b7e 0x5b80 +0x9b80 0x5b83 +0x9b81 0x5ba6 +0x9b82 0x5bb8 +0x9b83 0x5bc3 +0x9b84 0x5bc7 +0x9b85 0x5bc9 +0x9b86 0x5bd4 +0x9b87 0x5bd0 +0x9b88 0x5be4 +0x9b89 0x5be6 +0x9b8a 0x5be2 +0x9b8b 0x5bde +0x9b8c 0x5be5 +0x9b8d 0x5beb +0x9b8e 0x5bf0 +0x9b8f 0x5bf6 +0x9b90 0x5bf3 +0x9b91 0x5c05 +0x9b92 0x5c07 +0x9b93 0x5c08 +0x9b94 0x5c0d +0x9b95 0x5c13 +0x9b96 0x5c20 +0x9b97 0x5c22 +0x9b98 0x5c28 +0x9b99 0x5c38 +0x9b9a 0x5c39 +0x9b9b 0x5c41 +0x9b9c 0x5c46 +0x9b9d 0x5c4e +0x9b9e 0x5c53 +0x9b9f 0x5c50 +0x9ba0 0x5c4f +0x9ba1 0x5b71 +0x9ba2 0x5c6c +0x9ba3 0x5c6e +0x9ba4 0x4e62 +0x9ba5 0x5c76 +0x9ba6 0x5c79 +0x9ba7 0x5c8c +0x9ba8 0x5c91 +0x9ba9 0x5c94 +0x9baa 0x599b +0x9bab 0x5cab +0x9bac 0x5cbb +0x9bad 0x5cb6 +0x9bae 0x5cbc +0x9baf 0x5cb7 +0x9bb0 0x5cc5 +0x9bb1 0x5cbe +0x9bb2 0x5cc7 +0x9bb3 0x5cd9 +0x9bb4 0x5ce9 +0x9bb5 0x5cfd +0x9bb6 0x5cfa +0x9bb7 0x5ced +0x9bb8 0x5d8c +0x9bb9 0x5cea +0x9bba 0x5d0b +0x9bbb 0x5d15 +0x9bbc 0x5d17 +0x9bbd 0x5d5c +0x9bbe 0x5d1f +0x9bbf 0x5d1b +0x9bc0 0x5d11 +0x9bc1 0x5d14 +0x9bc2 0x5d22 +0x9bc3 0x5d1a +0x9bc4 0x5d19 +0x9bc5 0x5d18 +0x9bc6 0x5d4c +0x9bc7 0x5d52 +0x9bc8 0x5d4e +0x9bc9 0x5d4b +0x9bca 0x5d6c +0x9bcb 0x5d73 +0x9bcc 0x5d76 +0x9bcd 0x5d87 +0x9bce 0x5d84 +0x9bcf 0x5d82 +0x9bd0 0x5da2 +0x9bd1 0x5d9d +0x9bd2 0x5dac +0x9bd3 0x5dae +0x9bd4 0x5dbd +0x9bd5 0x5d90 +0x9bd6 0x5db7 +0x9bd7 0x5dbc +0x9bd8 0x5dc9 +0x9bd9 0x5dcd +0x9bda 0x5dd3 +0x9bdb 0x5dd2 +0x9bdc 0x5dd6 +0x9bdd 0x5ddb +0x9bde 0x5deb +0x9bdf 0x5df2 +0x9be0 0x5df5 +0x9be1 0x5e0b +0x9be2 0x5e1a +0x9be3 0x5e19 +0x9be4 0x5e11 +0x9be5 0x5e1b +0x9be6 0x5e36 +0x9be7 0x5e37 +0x9be8 0x5e44 +0x9be9 0x5e43 +0x9bea 0x5e40 +0x9beb 0x5e4e +0x9bec 0x5e57 +0x9bed 0x5e54 +0x9bee 0x5e5f +0x9bef 0x5e62 +0x9bf0 0x5e64 +0x9bf1 0x5e47 +0x9bf2 0x5e75 +0x9bf3 0x5e76 +0x9bf4 0x5e7a +0x9bf5 0x9ebc +0x9bf6 0x5e7f +0x9bf7 0x5ea0 +0x9bf8 0x5ec1 +0x9bf9 0x5ec2 +0x9bfa 0x5ec8 +0x9bfb 0x5ed0 +0x9bfc 0x5ecf +0x9c40 0x5ed6 +0x9c41 0x5ee3 +0x9c42 0x5edd +0x9c43 0x5eda +0x9c44 0x5edb +0x9c45 0x5ee2 +0x9c46 0x5ee1 +0x9c47 0x5ee8 +0x9c48 0x5ee9 +0x9c49 0x5eec +0x9c4a 0x5ef1 +0x9c4b 0x5ef3 +0x9c4c 0x5ef0 +0x9c4d 0x5ef4 +0x9c4e 0x5ef8 +0x9c4f 0x5efe +0x9c50 0x5f03 +0x9c51 0x5f09 +0x9c52 0x5f5d +0x9c53 0x5f5c +0x9c54 0x5f0b +0x9c55 0x5f11 +0x9c56 0x5f16 +0x9c57 0x5f29 +0x9c58 0x5f2d +0x9c59 0x5f38 +0x9c5a 0x5f41 +0x9c5b 0x5f48 +0x9c5c 0x5f4c +0x9c5d 0x5f4e +0x9c5e 0x5f2f +0x9c5f 0x5f51 +0x9c60 0x5f56 +0x9c61 0x5f57 +0x9c62 0x5f59 +0x9c63 0x5f61 +0x9c64 0x5f6d +0x9c65 0x5f73 +0x9c66 0x5f77 +0x9c67 0x5f83 +0x9c68 0x5f82 +0x9c69 0x5f7f +0x9c6a 0x5f8a +0x9c6b 0x5f88 +0x9c6c 0x5f91 +0x9c6d 0x5f87 +0x9c6e 0x5f9e +0x9c6f 0x5f99 +0x9c70 0x5f98 +0x9c71 0x5fa0 +0x9c72 0x5fa8 +0x9c73 0x5fad +0x9c74 0x5fbc +0x9c75 0x5fd6 +0x9c76 0x5ffb +0x9c77 0x5fe4 +0x9c78 0x5ff8 +0x9c79 0x5ff1 +0x9c7a 0x5fdd +0x9c7b 0x60b3 +0x9c7c 0x5fff +0x9c7d 0x6021 +0x9c7e 0x6060 +0x9c80 0x6019 +0x9c81 0x6010 +0x9c82 0x6029 +0x9c83 0x600e +0x9c84 0x6031 +0x9c85 0x601b +0x9c86 0x6015 +0x9c87 0x602b +0x9c88 0x6026 +0x9c89 0x600f +0x9c8a 0x603a +0x9c8b 0x605a +0x9c8c 0x6041 +0x9c8d 0x606a +0x9c8e 0x6077 +0x9c8f 0x605f +0x9c90 0x604a +0x9c91 0x6046 +0x9c92 0x604d +0x9c93 0x6063 +0x9c94 0x6043 +0x9c95 0x6064 +0x9c96 0x6042 +0x9c97 0x606c +0x9c98 0x606b +0x9c99 0x6059 +0x9c9a 0x6081 +0x9c9b 0x608d +0x9c9c 0x60e7 +0x9c9d 0x6083 +0x9c9e 0x609a +0x9c9f 0x6084 +0x9ca0 0x609b +0x9ca1 0x6096 +0x9ca2 0x6097 +0x9ca3 0x6092 +0x9ca4 0x60a7 +0x9ca5 0x608b +0x9ca6 0x60e1 +0x9ca7 0x60b8 +0x9ca8 0x60e0 +0x9ca9 0x60d3 +0x9caa 0x60b4 +0x9cab 0x5ff0 +0x9cac 0x60bd +0x9cad 0x60c6 +0x9cae 0x60b5 +0x9caf 0x60d8 +0x9cb0 0x614d +0x9cb1 0x6115 +0x9cb2 0x6106 +0x9cb3 0x60f6 +0x9cb4 0x60f7 +0x9cb5 0x6100 +0x9cb6 0x60f4 +0x9cb7 0x60fa +0x9cb8 0x6103 +0x9cb9 0x6121 +0x9cba 0x60fb +0x9cbb 0x60f1 +0x9cbc 0x610d +0x9cbd 0x610e +0x9cbe 0x6147 +0x9cbf 0x613e +0x9cc0 0x6128 +0x9cc1 0x6127 +0x9cc2 0x614a +0x9cc3 0x613f +0x9cc4 0x613c +0x9cc5 0x612c +0x9cc6 0x6134 +0x9cc7 0x613d +0x9cc8 0x6142 +0x9cc9 0x6144 +0x9cca 0x6173 +0x9ccb 0x6177 +0x9ccc 0x6158 +0x9ccd 0x6159 +0x9cce 0x615a +0x9ccf 0x616b +0x9cd0 0x6174 +0x9cd1 0x616f +0x9cd2 0x6165 +0x9cd3 0x6171 +0x9cd4 0x615f +0x9cd5 0x615d +0x9cd6 0x6153 +0x9cd7 0x6175 +0x9cd8 0x6199 +0x9cd9 0x6196 +0x9cda 0x6187 +0x9cdb 0x61ac +0x9cdc 0x6194 +0x9cdd 0x619a +0x9cde 0x618a +0x9cdf 0x6191 +0x9ce0 0x61ab +0x9ce1 0x61ae +0x9ce2 0x61cc +0x9ce3 0x61ca +0x9ce4 0x61c9 +0x9ce5 0x61f7 +0x9ce6 0x61c8 +0x9ce7 0x61c3 +0x9ce8 0x61c6 +0x9ce9 0x61ba +0x9cea 0x61cb +0x9ceb 0x7f79 +0x9cec 0x61cd +0x9ced 0x61e6 +0x9cee 0x61e3 +0x9cef 0x61f6 +0x9cf0 0x61fa +0x9cf1 0x61f4 +0x9cf2 0x61ff +0x9cf3 0x61fd +0x9cf4 0x61fc +0x9cf5 0x61fe +0x9cf6 0x6200 +0x9cf7 0x6208 +0x9cf8 0x6209 +0x9cf9 0x620d +0x9cfa 0x620c +0x9cfb 0x6214 +0x9cfc 0x621b +0x9d40 0x621e +0x9d41 0x6221 +0x9d42 0x622a +0x9d43 0x622e +0x9d44 0x6230 +0x9d45 0x6232 +0x9d46 0x6233 +0x9d47 0x6241 +0x9d48 0x624e +0x9d49 0x625e +0x9d4a 0x6263 +0x9d4b 0x625b +0x9d4c 0x6260 +0x9d4d 0x6268 +0x9d4e 0x627c +0x9d4f 0x6282 +0x9d50 0x6289 +0x9d51 0x627e +0x9d52 0x6292 +0x9d53 0x6293 +0x9d54 0x6296 +0x9d55 0x62d4 +0x9d56 0x6283 +0x9d57 0x6294 +0x9d58 0x62d7 +0x9d59 0x62d1 +0x9d5a 0x62bb +0x9d5b 0x62cf +0x9d5c 0x62ff +0x9d5d 0x62c6 +0x9d5e 0x64d4 +0x9d5f 0x62c8 +0x9d60 0x62dc +0x9d61 0x62cc +0x9d62 0x62ca +0x9d63 0x62c2 +0x9d64 0x62c7 +0x9d65 0x629b +0x9d66 0x62c9 +0x9d67 0x630c +0x9d68 0x62ee +0x9d69 0x62f1 +0x9d6a 0x6327 +0x9d6b 0x6302 +0x9d6c 0x6308 +0x9d6d 0x62ef +0x9d6e 0x62f5 +0x9d6f 0x6350 +0x9d70 0x633e +0x9d71 0x634d +0x9d72 0x641c +0x9d73 0x634f +0x9d74 0x6396 +0x9d75 0x638e +0x9d76 0x6380 +0x9d77 0x63ab +0x9d78 0x6376 +0x9d79 0x63a3 +0x9d7a 0x638f +0x9d7b 0x6389 +0x9d7c 0x639f +0x9d7d 0x63b5 +0x9d7e 0x636b +0x9d80 0x6369 +0x9d81 0x63be +0x9d82 0x63e9 +0x9d83 0x63c0 +0x9d84 0x63c6 +0x9d85 0x63e3 +0x9d86 0x63c9 +0x9d87 0x63d2 +0x9d88 0x63f6 +0x9d89 0x63c4 +0x9d8a 0x6416 +0x9d8b 0x6434 +0x9d8c 0x6406 +0x9d8d 0x6413 +0x9d8e 0x6426 +0x9d8f 0x6436 +0x9d90 0x651d +0x9d91 0x6417 +0x9d92 0x6428 +0x9d93 0x640f +0x9d94 0x6467 +0x9d95 0x646f +0x9d96 0x6476 +0x9d97 0x644e +0x9d98 0x652a +0x9d99 0x6495 +0x9d9a 0x6493 +0x9d9b 0x64a5 +0x9d9c 0x64a9 +0x9d9d 0x6488 +0x9d9e 0x64bc +0x9d9f 0x64da +0x9da0 0x64d2 +0x9da1 0x64c5 +0x9da2 0x64c7 +0x9da3 0x64bb +0x9da4 0x64d8 +0x9da5 0x64c2 +0x9da6 0x64f1 +0x9da7 0x64e7 +0x9da8 0x8209 +0x9da9 0x64e0 +0x9daa 0x64e1 +0x9dab 0x62ac +0x9dac 0x64e3 +0x9dad 0x64ef +0x9dae 0x652c +0x9daf 0x64f6 +0x9db0 0x64f4 +0x9db1 0x64f2 +0x9db2 0x64fa +0x9db3 0x6500 +0x9db4 0x64fd +0x9db5 0x6518 +0x9db6 0x651c +0x9db7 0x6505 +0x9db8 0x6524 +0x9db9 0x6523 +0x9dba 0x652b +0x9dbb 0x6534 +0x9dbc 0x6535 +0x9dbd 0x6537 +0x9dbe 0x6536 +0x9dbf 0x6538 +0x9dc0 0x754b +0x9dc1 0x6548 +0x9dc2 0x6556 +0x9dc3 0x6555 +0x9dc4 0x654d +0x9dc5 0x6558 +0x9dc6 0x655e +0x9dc7 0x655d +0x9dc8 0x6572 +0x9dc9 0x6578 +0x9dca 0x6582 +0x9dcb 0x6583 +0x9dcc 0x8b8a +0x9dcd 0x659b +0x9dce 0x659f +0x9dcf 0x65ab +0x9dd0 0x65b7 +0x9dd1 0x65c3 +0x9dd2 0x65c6 +0x9dd3 0x65c1 +0x9dd4 0x65c4 +0x9dd5 0x65cc +0x9dd6 0x65d2 +0x9dd7 0x65db +0x9dd8 0x65d9 +0x9dd9 0x65e0 +0x9dda 0x65e1 +0x9ddb 0x65f1 +0x9ddc 0x6772 +0x9ddd 0x660a +0x9dde 0x6603 +0x9ddf 0x65fb +0x9de0 0x6773 +0x9de1 0x6635 +0x9de2 0x6636 +0x9de3 0x6634 +0x9de4 0x661c +0x9de5 0x664f +0x9de6 0x6644 +0x9de7 0x6649 +0x9de8 0x6641 +0x9de9 0x665e +0x9dea 0x665d +0x9deb 0x6664 +0x9dec 0x6667 +0x9ded 0x6668 +0x9dee 0x665f +0x9def 0x6662 +0x9df0 0x6670 +0x9df1 0x6683 +0x9df2 0x6688 +0x9df3 0x668e +0x9df4 0x6689 +0x9df5 0x6684 +0x9df6 0x6698 +0x9df7 0x669d +0x9df8 0x66c1 +0x9df9 0x66b9 +0x9dfa 0x66c9 +0x9dfb 0x66be +0x9dfc 0x66bc +0x9e40 0x66c4 +0x9e41 0x66b8 +0x9e42 0x66d6 +0x9e43 0x66da +0x9e44 0x66e0 +0x9e45 0x663f +0x9e46 0x66e6 +0x9e47 0x66e9 +0x9e48 0x66f0 +0x9e49 0x66f5 +0x9e4a 0x66f7 +0x9e4b 0x670f +0x9e4c 0x6716 +0x9e4d 0x671e +0x9e4e 0x6726 +0x9e4f 0x6727 +0x9e50 0x9738 +0x9e51 0x672e +0x9e52 0x673f +0x9e53 0x6736 +0x9e54 0x6741 +0x9e55 0x6738 +0x9e56 0x6737 +0x9e57 0x6746 +0x9e58 0x675e +0x9e59 0x6760 +0x9e5a 0x6759 +0x9e5b 0x6763 +0x9e5c 0x6764 +0x9e5d 0x6789 +0x9e5e 0x6770 +0x9e5f 0x67a9 +0x9e60 0x677c +0x9e61 0x676a +0x9e62 0x678c +0x9e63 0x678b +0x9e64 0x67a6 +0x9e65 0x67a1 +0x9e66 0x6785 +0x9e67 0x67b7 +0x9e68 0x67ef +0x9e69 0x67b4 +0x9e6a 0x67ec +0x9e6b 0x67b3 +0x9e6c 0x67e9 +0x9e6d 0x67b8 +0x9e6e 0x67e4 +0x9e6f 0x67de +0x9e70 0x67dd +0x9e71 0x67e2 +0x9e72 0x67ee +0x9e73 0x67b9 +0x9e74 0x67ce +0x9e75 0x67c6 +0x9e76 0x67e7 +0x9e77 0x6a9c +0x9e78 0x681e +0x9e79 0x6846 +0x9e7a 0x6829 +0x9e7b 0x6840 +0x9e7c 0x684d +0x9e7d 0x6832 +0x9e7e 0x684e +0x9e80 0x68b3 +0x9e81 0x682b +0x9e82 0x6859 +0x9e83 0x6863 +0x9e84 0x6877 +0x9e85 0x687f +0x9e86 0x689f +0x9e87 0x688f +0x9e88 0x68ad +0x9e89 0x6894 +0x9e8a 0x689d +0x9e8b 0x689b +0x9e8c 0x6883 +0x9e8d 0x6aae +0x9e8e 0x68b9 +0x9e8f 0x6874 +0x9e90 0x68b5 +0x9e91 0x68a0 +0x9e92 0x68ba +0x9e93 0x690f +0x9e94 0x688d +0x9e95 0x687e +0x9e96 0x6901 +0x9e97 0x68ca +0x9e98 0x6908 +0x9e99 0x68d8 +0x9e9a 0x6922 +0x9e9b 0x6926 +0x9e9c 0x68e1 +0x9e9d 0x690c +0x9e9e 0x68cd +0x9e9f 0x68d4 +0x9ea0 0x68e7 +0x9ea1 0x68d5 +0x9ea2 0x6936 +0x9ea3 0x6912 +0x9ea4 0x6904 +0x9ea5 0x68d7 +0x9ea6 0x68e3 +0x9ea7 0x6925 +0x9ea8 0x68f9 +0x9ea9 0x68e0 +0x9eaa 0x68ef +0x9eab 0x6928 +0x9eac 0x692a +0x9ead 0x691a +0x9eae 0x6923 +0x9eaf 0x6921 +0x9eb0 0x68c6 +0x9eb1 0x6979 +0x9eb2 0x6977 +0x9eb3 0x695c +0x9eb4 0x6978 +0x9eb5 0x696b +0x9eb6 0x6954 +0x9eb7 0x697e +0x9eb8 0x696e +0x9eb9 0x6939 +0x9eba 0x6974 +0x9ebb 0x693d +0x9ebc 0x6959 +0x9ebd 0x6930 +0x9ebe 0x6961 +0x9ebf 0x695e +0x9ec0 0x695d +0x9ec1 0x6981 +0x9ec2 0x696a +0x9ec3 0x69b2 +0x9ec4 0x69ae +0x9ec5 0x69d0 +0x9ec6 0x69bf +0x9ec7 0x69c1 +0x9ec8 0x69d3 +0x9ec9 0x69be +0x9eca 0x69ce +0x9ecb 0x5be8 +0x9ecc 0x69ca +0x9ecd 0x69dd +0x9ece 0x69bb +0x9ecf 0x69c3 +0x9ed0 0x69a7 +0x9ed1 0x6a2e +0x9ed2 0x6991 +0x9ed3 0x69a0 +0x9ed4 0x699c +0x9ed5 0x6995 +0x9ed6 0x69b4 +0x9ed7 0x69de +0x9ed8 0x69e8 +0x9ed9 0x6a02 +0x9eda 0x6a1b +0x9edb 0x69ff +0x9edc 0x6b0a +0x9edd 0x69f9 +0x9ede 0x69f2 +0x9edf 0x69e7 +0x9ee0 0x6a05 +0x9ee1 0x69b1 +0x9ee2 0x6a1e +0x9ee3 0x69ed +0x9ee4 0x6a14 +0x9ee5 0x69eb +0x9ee6 0x6a0a +0x9ee7 0x6a12 +0x9ee8 0x6ac1 +0x9ee9 0x6a23 +0x9eea 0x6a13 +0x9eeb 0x6a44 +0x9eec 0x6a0c +0x9eed 0x6a72 +0x9eee 0x6a36 +0x9eef 0x6a78 +0x9ef0 0x6a47 +0x9ef1 0x6a62 +0x9ef2 0x6a59 +0x9ef3 0x6a66 +0x9ef4 0x6a48 +0x9ef5 0x6a38 +0x9ef6 0x6a22 +0x9ef7 0x6a90 +0x9ef8 0x6a8d +0x9ef9 0x6aa0 +0x9efa 0x6a84 +0x9efb 0x6aa2 +0x9efc 0x6aa3 +0x9f40 0x6a97 +0x9f41 0x8617 +0x9f42 0x6abb +0x9f43 0x6ac3 +0x9f44 0x6ac2 +0x9f45 0x6ab8 +0x9f46 0x6ab3 +0x9f47 0x6aac +0x9f48 0x6ade +0x9f49 0x6ad1 +0x9f4a 0x6adf +0x9f4b 0x6aaa +0x9f4c 0x6ada +0x9f4d 0x6aea +0x9f4e 0x6afb +0x9f4f 0x6b05 +0x9f50 0x8616 +0x9f51 0x6afa +0x9f52 0x6b12 +0x9f53 0x6b16 +0x9f54 0x9b31 +0x9f55 0x6b1f +0x9f56 0x6b38 +0x9f57 0x6b37 +0x9f58 0x76dc +0x9f59 0x6b39 +0x9f5a 0x98ee +0x9f5b 0x6b47 +0x9f5c 0x6b43 +0x9f5d 0x6b49 +0x9f5e 0x6b50 +0x9f5f 0x6b59 +0x9f60 0x6b54 +0x9f61 0x6b5b +0x9f62 0x6b5f +0x9f63 0x6b61 +0x9f64 0x6b78 +0x9f65 0x6b79 +0x9f66 0x6b7f +0x9f67 0x6b80 +0x9f68 0x6b84 +0x9f69 0x6b83 +0x9f6a 0x6b8d +0x9f6b 0x6b98 +0x9f6c 0x6b95 +0x9f6d 0x6b9e +0x9f6e 0x6ba4 +0x9f6f 0x6baa +0x9f70 0x6bab +0x9f71 0x6baf +0x9f72 0x6bb2 +0x9f73 0x6bb1 +0x9f74 0x6bb3 +0x9f75 0x6bb7 +0x9f76 0x6bbc +0x9f77 0x6bc6 +0x9f78 0x6bcb +0x9f79 0x6bd3 +0x9f7a 0x6bdf +0x9f7b 0x6bec +0x9f7c 0x6beb +0x9f7d 0x6bf3 +0x9f7e 0x6bef +0x9f80 0x9ebe +0x9f81 0x6c08 +0x9f82 0x6c13 +0x9f83 0x6c14 +0x9f84 0x6c1b +0x9f85 0x6c24 +0x9f86 0x6c23 +0x9f87 0x6c5e +0x9f88 0x6c55 +0x9f89 0x6c62 +0x9f8a 0x6c6a +0x9f8b 0x6c82 +0x9f8c 0x6c8d +0x9f8d 0x6c9a +0x9f8e 0x6c81 +0x9f8f 0x6c9b +0x9f90 0x6c7e +0x9f91 0x6c68 +0x9f92 0x6c73 +0x9f93 0x6c92 +0x9f94 0x6c90 +0x9f95 0x6cc4 +0x9f96 0x6cf1 +0x9f97 0x6cd3 +0x9f98 0x6cbd +0x9f99 0x6cd7 +0x9f9a 0x6cc5 +0x9f9b 0x6cdd +0x9f9c 0x6cae +0x9f9d 0x6cb1 +0x9f9e 0x6cbe +0x9f9f 0x6cba +0x9fa0 0x6cdb +0x9fa1 0x6cef +0x9fa2 0x6cd9 +0x9fa3 0x6cea +0x9fa4 0x6d1f +0x9fa5 0x884d +0x9fa6 0x6d36 +0x9fa7 0x6d2b +0x9fa8 0x6d3d +0x9fa9 0x6d38 +0x9faa 0x6d19 +0x9fab 0x6d35 +0x9fac 0x6d33 +0x9fad 0x6d12 +0x9fae 0x6d0c +0x9faf 0x6d63 +0x9fb0 0x6d93 +0x9fb1 0x6d64 +0x9fb2 0x6d5a +0x9fb3 0x6d79 +0x9fb4 0x6d59 +0x9fb5 0x6d8e +0x9fb6 0x6d95 +0x9fb7 0x6fe4 +0x9fb8 0x6d85 +0x9fb9 0x6df9 +0x9fba 0x6e15 +0x9fbb 0x6e0a +0x9fbc 0x6db5 +0x9fbd 0x6dc7 +0x9fbe 0x6de6 +0x9fbf 0x6db8 +0x9fc0 0x6dc6 +0x9fc1 0x6dec +0x9fc2 0x6dde +0x9fc3 0x6dcc +0x9fc4 0x6de8 +0x9fc5 0x6dd2 +0x9fc6 0x6dc5 +0x9fc7 0x6dfa +0x9fc8 0x6dd9 +0x9fc9 0x6de4 +0x9fca 0x6dd5 +0x9fcb 0x6dea +0x9fcc 0x6dee +0x9fcd 0x6e2d +0x9fce 0x6e6e +0x9fcf 0x6e2e +0x9fd0 0x6e19 +0x9fd1 0x6e72 +0x9fd2 0x6e5f +0x9fd3 0x6e3e +0x9fd4 0x6e23 +0x9fd5 0x6e6b +0x9fd6 0x6e2b +0x9fd7 0x6e76 +0x9fd8 0x6e4d +0x9fd9 0x6e1f +0x9fda 0x6e43 +0x9fdb 0x6e3a +0x9fdc 0x6e4e +0x9fdd 0x6e24 +0x9fde 0x6eff +0x9fdf 0x6e1d +0x9fe0 0x6e38 +0x9fe1 0x6e82 +0x9fe2 0x6eaa +0x9fe3 0x6e98 +0x9fe4 0x6ec9 +0x9fe5 0x6eb7 +0x9fe6 0x6ed3 +0x9fe7 0x6ebd +0x9fe8 0x6eaf +0x9fe9 0x6ec4 +0x9fea 0x6eb2 +0x9feb 0x6ed4 +0x9fec 0x6ed5 +0x9fed 0x6e8f +0x9fee 0x6ea5 +0x9fef 0x6ec2 +0x9ff0 0x6e9f +0x9ff1 0x6f41 +0x9ff2 0x6f11 +0x9ff3 0x704c +0x9ff4 0x6eec +0x9ff5 0x6ef8 +0x9ff6 0x6efe +0x9ff7 0x6f3f +0x9ff8 0x6ef2 +0x9ff9 0x6f31 +0x9ffa 0x6eef +0x9ffb 0x6f32 +0x9ffc 0x6ecc +0xe040 0x6f3e +0xe041 0x6f13 +0xe042 0x6ef7 +0xe043 0x6f86 +0xe044 0x6f7a +0xe045 0x6f78 +0xe046 0x6f81 +0xe047 0x6f80 +0xe048 0x6f6f +0xe049 0x6f5b +0xe04a 0x6ff3 +0xe04b 0x6f6d +0xe04c 0x6f82 +0xe04d 0x6f7c +0xe04e 0x6f58 +0xe04f 0x6f8e +0xe050 0x6f91 +0xe051 0x6fc2 +0xe052 0x6f66 +0xe053 0x6fb3 +0xe054 0x6fa3 +0xe055 0x6fa1 +0xe056 0x6fa4 +0xe057 0x6fb9 +0xe058 0x6fc6 +0xe059 0x6faa +0xe05a 0x6fdf +0xe05b 0x6fd5 +0xe05c 0x6fec +0xe05d 0x6fd4 +0xe05e 0x6fd8 +0xe05f 0x6ff1 +0xe060 0x6fee +0xe061 0x6fdb +0xe062 0x7009 +0xe063 0x700b +0xe064 0x6ffa +0xe065 0x7011 +0xe066 0x7001 +0xe067 0x700f +0xe068 0x6ffe +0xe069 0x701b +0xe06a 0x701a +0xe06b 0x6f74 +0xe06c 0x701d +0xe06d 0x7018 +0xe06e 0x701f +0xe06f 0x7030 +0xe070 0x703e +0xe071 0x7032 +0xe072 0x7051 +0xe073 0x7063 +0xe074 0x7099 +0xe075 0x7092 +0xe076 0x70af +0xe077 0x70f1 +0xe078 0x70ac +0xe079 0x70b8 +0xe07a 0x70b3 +0xe07b 0x70ae +0xe07c 0x70df +0xe07d 0x70cb +0xe07e 0x70dd +0xe080 0x70d9 +0xe081 0x7109 +0xe082 0x70fd +0xe083 0x711c +0xe084 0x7119 +0xe085 0x7165 +0xe086 0x7155 +0xe087 0x7188 +0xe088 0x7166 +0xe089 0x7162 +0xe08a 0x714c +0xe08b 0x7156 +0xe08c 0x716c +0xe08d 0x718f +0xe08e 0x71fb +0xe08f 0x7184 +0xe090 0x7195 +0xe091 0x71a8 +0xe092 0x71ac +0xe093 0x71d7 +0xe094 0x71b9 +0xe095 0x71be +0xe096 0x71d2 +0xe097 0x71c9 +0xe098 0x71d4 +0xe099 0x71ce +0xe09a 0x71e0 +0xe09b 0x71ec +0xe09c 0x71e7 +0xe09d 0x71f5 +0xe09e 0x71fc +0xe09f 0x71f9 +0xe0a0 0x71ff +0xe0a1 0x720d +0xe0a2 0x7210 +0xe0a3 0x721b +0xe0a4 0x7228 +0xe0a5 0x722d +0xe0a6 0x722c +0xe0a7 0x7230 +0xe0a8 0x7232 +0xe0a9 0x723b +0xe0aa 0x723c +0xe0ab 0x723f +0xe0ac 0x7240 +0xe0ad 0x7246 +0xe0ae 0x724b +0xe0af 0x7258 +0xe0b0 0x7274 +0xe0b1 0x727e +0xe0b2 0x7282 +0xe0b3 0x7281 +0xe0b4 0x7287 +0xe0b5 0x7292 +0xe0b6 0x7296 +0xe0b7 0x72a2 +0xe0b8 0x72a7 +0xe0b9 0x72b9 +0xe0ba 0x72b2 +0xe0bb 0x72c3 +0xe0bc 0x72c6 +0xe0bd 0x72c4 +0xe0be 0x72ce +0xe0bf 0x72d2 +0xe0c0 0x72e2 +0xe0c1 0x72e0 +0xe0c2 0x72e1 +0xe0c3 0x72f9 +0xe0c4 0x72f7 +0xe0c5 0x500f +0xe0c6 0x7317 +0xe0c7 0x730a +0xe0c8 0x731c +0xe0c9 0x7316 +0xe0ca 0x731d +0xe0cb 0x7334 +0xe0cc 0x732f +0xe0cd 0x7329 +0xe0ce 0x7325 +0xe0cf 0x733e +0xe0d0 0x734e +0xe0d1 0x734f +0xe0d2 0x9ed8 +0xe0d3 0x7357 +0xe0d4 0x736a +0xe0d5 0x7368 +0xe0d6 0x7370 +0xe0d7 0x7378 +0xe0d8 0x7375 +0xe0d9 0x737b +0xe0da 0x737a +0xe0db 0x73c8 +0xe0dc 0x73b3 +0xe0dd 0x73ce +0xe0de 0x73bb +0xe0df 0x73c0 +0xe0e0 0x73e5 +0xe0e1 0x73ee +0xe0e2 0x73de +0xe0e3 0x74a2 +0xe0e4 0x7405 +0xe0e5 0x746f +0xe0e6 0x7425 +0xe0e7 0x73f8 +0xe0e8 0x7432 +0xe0e9 0x743a +0xe0ea 0x7455 +0xe0eb 0x743f +0xe0ec 0x745f +0xe0ed 0x7459 +0xe0ee 0x7441 +0xe0ef 0x745c +0xe0f0 0x7469 +0xe0f1 0x7470 +0xe0f2 0x7463 +0xe0f3 0x746a +0xe0f4 0x7476 +0xe0f5 0x747e +0xe0f6 0x748b +0xe0f7 0x749e +0xe0f8 0x74a7 +0xe0f9 0x74ca +0xe0fa 0x74cf +0xe0fb 0x74d4 +0xe0fc 0x73f1 +0xe140 0x74e0 +0xe141 0x74e3 +0xe142 0x74e7 +0xe143 0x74e9 +0xe144 0x74ee +0xe145 0x74f2 +0xe146 0x74f0 +0xe147 0x74f1 +0xe148 0x74f8 +0xe149 0x74f7 +0xe14a 0x7504 +0xe14b 0x7503 +0xe14c 0x7505 +0xe14d 0x750c +0xe14e 0x750e +0xe14f 0x750d +0xe150 0x7515 +0xe151 0x7513 +0xe152 0x751e +0xe153 0x7526 +0xe154 0x752c +0xe155 0x753c +0xe156 0x7544 +0xe157 0x754d +0xe158 0x754a +0xe159 0x7549 +0xe15a 0x755b +0xe15b 0x7546 +0xe15c 0x755a +0xe15d 0x7569 +0xe15e 0x7564 +0xe15f 0x7567 +0xe160 0x756b +0xe161 0x756d +0xe162 0x7578 +0xe163 0x7576 +0xe164 0x7586 +0xe165 0x7587 +0xe166 0x7574 +0xe167 0x758a +0xe168 0x7589 +0xe169 0x7582 +0xe16a 0x7594 +0xe16b 0x759a +0xe16c 0x759d +0xe16d 0x75a5 +0xe16e 0x75a3 +0xe16f 0x75c2 +0xe170 0x75b3 +0xe171 0x75c3 +0xe172 0x75b5 +0xe173 0x75bd +0xe174 0x75b8 +0xe175 0x75bc +0xe176 0x75b1 +0xe177 0x75cd +0xe178 0x75ca +0xe179 0x75d2 +0xe17a 0x75d9 +0xe17b 0x75e3 +0xe17c 0x75de +0xe17d 0x75fe +0xe17e 0x75ff +0xe180 0x75fc +0xe181 0x7601 +0xe182 0x75f0 +0xe183 0x75fa +0xe184 0x75f2 +0xe185 0x75f3 +0xe186 0x760b +0xe187 0x760d +0xe188 0x7609 +0xe189 0x761f +0xe18a 0x7627 +0xe18b 0x7620 +0xe18c 0x7621 +0xe18d 0x7622 +0xe18e 0x7624 +0xe18f 0x7634 +0xe190 0x7630 +0xe191 0x763b +0xe192 0x7647 +0xe193 0x7648 +0xe194 0x7646 +0xe195 0x765c +0xe196 0x7658 +0xe197 0x7661 +0xe198 0x7662 +0xe199 0x7668 +0xe19a 0x7669 +0xe19b 0x766a +0xe19c 0x7667 +0xe19d 0x766c +0xe19e 0x7670 +0xe19f 0x7672 +0xe1a0 0x7676 +0xe1a1 0x7678 +0xe1a2 0x767c +0xe1a3 0x7680 +0xe1a4 0x7683 +0xe1a5 0x7688 +0xe1a6 0x768b +0xe1a7 0x768e +0xe1a8 0x7696 +0xe1a9 0x7693 +0xe1aa 0x7699 +0xe1ab 0x769a +0xe1ac 0x76b0 +0xe1ad 0x76b4 +0xe1ae 0x76b8 +0xe1af 0x76b9 +0xe1b0 0x76ba +0xe1b1 0x76c2 +0xe1b2 0x76cd +0xe1b3 0x76d6 +0xe1b4 0x76d2 +0xe1b5 0x76de +0xe1b6 0x76e1 +0xe1b7 0x76e5 +0xe1b8 0x76e7 +0xe1b9 0x76ea +0xe1ba 0x862f +0xe1bb 0x76fb +0xe1bc 0x7708 +0xe1bd 0x7707 +0xe1be 0x7704 +0xe1bf 0x7729 +0xe1c0 0x7724 +0xe1c1 0x771e +0xe1c2 0x7725 +0xe1c3 0x7726 +0xe1c4 0x771b +0xe1c5 0x7737 +0xe1c6 0x7738 +0xe1c7 0x7747 +0xe1c8 0x775a +0xe1c9 0x7768 +0xe1ca 0x776b +0xe1cb 0x775b +0xe1cc 0x7765 +0xe1cd 0x777f +0xe1ce 0x777e +0xe1cf 0x7779 +0xe1d0 0x778e +0xe1d1 0x778b +0xe1d2 0x7791 +0xe1d3 0x77a0 +0xe1d4 0x779e +0xe1d5 0x77b0 +0xe1d6 0x77b6 +0xe1d7 0x77b9 +0xe1d8 0x77bf +0xe1d9 0x77bc +0xe1da 0x77bd +0xe1db 0x77bb +0xe1dc 0x77c7 +0xe1dd 0x77cd +0xe1de 0x77d7 +0xe1df 0x77da +0xe1e0 0x77dc +0xe1e1 0x77e3 +0xe1e2 0x77ee +0xe1e3 0x77fc +0xe1e4 0x780c +0xe1e5 0x7812 +0xe1e6 0x7926 +0xe1e7 0x7820 +0xe1e8 0x792a +0xe1e9 0x7845 +0xe1ea 0x788e +0xe1eb 0x7874 +0xe1ec 0x7886 +0xe1ed 0x787c +0xe1ee 0x789a +0xe1ef 0x788c +0xe1f0 0x78a3 +0xe1f1 0x78b5 +0xe1f2 0x78aa +0xe1f3 0x78af +0xe1f4 0x78d1 +0xe1f5 0x78c6 +0xe1f6 0x78cb +0xe1f7 0x78d4 +0xe1f8 0x78be +0xe1f9 0x78bc +0xe1fa 0x78c5 +0xe1fb 0x78ca +0xe1fc 0x78ec +0xe240 0x78e7 +0xe241 0x78da +0xe242 0x78fd +0xe243 0x78f4 +0xe244 0x7907 +0xe245 0x7912 +0xe246 0x7911 +0xe247 0x7919 +0xe248 0x792c +0xe249 0x792b +0xe24a 0x7940 +0xe24b 0x7960 +0xe24c 0x7957 +0xe24d 0x795f +0xe24e 0x795a +0xe24f 0x7955 +0xe250 0x7953 +0xe251 0x797a +0xe252 0x797f +0xe253 0x798a +0xe254 0x799d +0xe255 0x79a7 +0xe256 0x9f4b +0xe257 0x79aa +0xe258 0x79ae +0xe259 0x79b3 +0xe25a 0x79b9 +0xe25b 0x79ba +0xe25c 0x79c9 +0xe25d 0x79d5 +0xe25e 0x79e7 +0xe25f 0x79ec +0xe260 0x79e1 +0xe261 0x79e3 +0xe262 0x7a08 +0xe263 0x7a0d +0xe264 0x7a18 +0xe265 0x7a19 +0xe266 0x7a20 +0xe267 0x7a1f +0xe268 0x7980 +0xe269 0x7a31 +0xe26a 0x7a3b +0xe26b 0x7a3e +0xe26c 0x7a37 +0xe26d 0x7a43 +0xe26e 0x7a57 +0xe26f 0x7a49 +0xe270 0x7a61 +0xe271 0x7a62 +0xe272 0x7a69 +0xe273 0x9f9d +0xe274 0x7a70 +0xe275 0x7a79 +0xe276 0x7a7d +0xe277 0x7a88 +0xe278 0x7a97 +0xe279 0x7a95 +0xe27a 0x7a98 +0xe27b 0x7a96 +0xe27c 0x7aa9 +0xe27d 0x7ac8 +0xe27e 0x7ab0 +0xe280 0x7ab6 +0xe281 0x7ac5 +0xe282 0x7ac4 +0xe283 0x7abf +0xe284 0x9083 +0xe285 0x7ac7 +0xe286 0x7aca +0xe287 0x7acd +0xe288 0x7acf +0xe289 0x7ad5 +0xe28a 0x7ad3 +0xe28b 0x7ad9 +0xe28c 0x7ada +0xe28d 0x7add +0xe28e 0x7ae1 +0xe28f 0x7ae2 +0xe290 0x7ae6 +0xe291 0x7aed +0xe292 0x7af0 +0xe293 0x7b02 +0xe294 0x7b0f +0xe295 0x7b0a +0xe296 0x7b06 +0xe297 0x7b33 +0xe298 0x7b18 +0xe299 0x7b19 +0xe29a 0x7b1e +0xe29b 0x7b35 +0xe29c 0x7b28 +0xe29d 0x7b36 +0xe29e 0x7b50 +0xe29f 0x7b7a +0xe2a0 0x7b04 +0xe2a1 0x7b4d +0xe2a2 0x7b0b +0xe2a3 0x7b4c +0xe2a4 0x7b45 +0xe2a5 0x7b75 +0xe2a6 0x7b65 +0xe2a7 0x7b74 +0xe2a8 0x7b67 +0xe2a9 0x7b70 +0xe2aa 0x7b71 +0xe2ab 0x7b6c +0xe2ac 0x7b6e +0xe2ad 0x7b9d +0xe2ae 0x7b98 +0xe2af 0x7b9f +0xe2b0 0x7b8d +0xe2b1 0x7b9c +0xe2b2 0x7b9a +0xe2b3 0x7b8b +0xe2b4 0x7b92 +0xe2b5 0x7b8f +0xe2b6 0x7b5d +0xe2b7 0x7b99 +0xe2b8 0x7bcb +0xe2b9 0x7bc1 +0xe2ba 0x7bcc +0xe2bb 0x7bcf +0xe2bc 0x7bb4 +0xe2bd 0x7bc6 +0xe2be 0x7bdd +0xe2bf 0x7be9 +0xe2c0 0x7c11 +0xe2c1 0x7c14 +0xe2c2 0x7be6 +0xe2c3 0x7be5 +0xe2c4 0x7c60 +0xe2c5 0x7c00 +0xe2c6 0x7c07 +0xe2c7 0x7c13 +0xe2c8 0x7bf3 +0xe2c9 0x7bf7 +0xe2ca 0x7c17 +0xe2cb 0x7c0d +0xe2cc 0x7bf6 +0xe2cd 0x7c23 +0xe2ce 0x7c27 +0xe2cf 0x7c2a +0xe2d0 0x7c1f +0xe2d1 0x7c37 +0xe2d2 0x7c2b +0xe2d3 0x7c3d +0xe2d4 0x7c4c +0xe2d5 0x7c43 +0xe2d6 0x7c54 +0xe2d7 0x7c4f +0xe2d8 0x7c40 +0xe2d9 0x7c50 +0xe2da 0x7c58 +0xe2db 0x7c5f +0xe2dc 0x7c64 +0xe2dd 0x7c56 +0xe2de 0x7c65 +0xe2df 0x7c6c +0xe2e0 0x7c75 +0xe2e1 0x7c83 +0xe2e2 0x7c90 +0xe2e3 0x7ca4 +0xe2e4 0x7cad +0xe2e5 0x7ca2 +0xe2e6 0x7cab +0xe2e7 0x7ca1 +0xe2e8 0x7ca8 +0xe2e9 0x7cb3 +0xe2ea 0x7cb2 +0xe2eb 0x7cb1 +0xe2ec 0x7cae +0xe2ed 0x7cb9 +0xe2ee 0x7cbd +0xe2ef 0x7cc0 +0xe2f0 0x7cc5 +0xe2f1 0x7cc2 +0xe2f2 0x7cd8 +0xe2f3 0x7cd2 +0xe2f4 0x7cdc +0xe2f5 0x7ce2 +0xe2f6 0x9b3b +0xe2f7 0x7cef +0xe2f8 0x7cf2 +0xe2f9 0x7cf4 +0xe2fa 0x7cf6 +0xe2fb 0x7cfa +0xe2fc 0x7d06 +0xe340 0x7d02 +0xe341 0x7d1c +0xe342 0x7d15 +0xe343 0x7d0a +0xe344 0x7d45 +0xe345 0x7d4b +0xe346 0x7d2e +0xe347 0x7d32 +0xe348 0x7d3f +0xe349 0x7d35 +0xe34a 0x7d46 +0xe34b 0x7d73 +0xe34c 0x7d56 +0xe34d 0x7d4e +0xe34e 0x7d72 +0xe34f 0x7d68 +0xe350 0x7d6e +0xe351 0x7d4f +0xe352 0x7d63 +0xe353 0x7d93 +0xe354 0x7d89 +0xe355 0x7d5b +0xe356 0x7d8f +0xe357 0x7d7d +0xe358 0x7d9b +0xe359 0x7dba +0xe35a 0x7dae +0xe35b 0x7da3 +0xe35c 0x7db5 +0xe35d 0x7dc7 +0xe35e 0x7dbd +0xe35f 0x7dab +0xe360 0x7e3d +0xe361 0x7da2 +0xe362 0x7daf +0xe363 0x7ddc +0xe364 0x7db8 +0xe365 0x7d9f +0xe366 0x7db0 +0xe367 0x7dd8 +0xe368 0x7ddd +0xe369 0x7de4 +0xe36a 0x7dde +0xe36b 0x7dfb +0xe36c 0x7df2 +0xe36d 0x7de1 +0xe36e 0x7e05 +0xe36f 0x7e0a +0xe370 0x7e23 +0xe371 0x7e21 +0xe372 0x7e12 +0xe373 0x7e31 +0xe374 0x7e1f +0xe375 0x7e09 +0xe376 0x7e0b +0xe377 0x7e22 +0xe378 0x7e46 +0xe379 0x7e66 +0xe37a 0x7e3b +0xe37b 0x7e35 +0xe37c 0x7e39 +0xe37d 0x7e43 +0xe37e 0x7e37 +0xe380 0x7e32 +0xe381 0x7e3a +0xe382 0x7e67 +0xe383 0x7e5d +0xe384 0x7e56 +0xe385 0x7e5e +0xe386 0x7e59 +0xe387 0x7e5a +0xe388 0x7e79 +0xe389 0x7e6a +0xe38a 0x7e69 +0xe38b 0x7e7c +0xe38c 0x7e7b +0xe38d 0x7e83 +0xe38e 0x7dd5 +0xe38f 0x7e7d +0xe390 0x8fae +0xe391 0x7e7f +0xe392 0x7e88 +0xe393 0x7e89 +0xe394 0x7e8c +0xe395 0x7e92 +0xe396 0x7e90 +0xe397 0x7e93 +0xe398 0x7e94 +0xe399 0x7e96 +0xe39a 0x7e8e +0xe39b 0x7e9b +0xe39c 0x7e9c +0xe39d 0x7f38 +0xe39e 0x7f3a +0xe39f 0x7f45 +0xe3a0 0x7f4c +0xe3a1 0x7f4d +0xe3a2 0x7f4e +0xe3a3 0x7f50 +0xe3a4 0x7f51 +0xe3a5 0x7f55 +0xe3a6 0x7f54 +0xe3a7 0x7f58 +0xe3a8 0x7f5f +0xe3a9 0x7f60 +0xe3aa 0x7f68 +0xe3ab 0x7f69 +0xe3ac 0x7f67 +0xe3ad 0x7f78 +0xe3ae 0x7f82 +0xe3af 0x7f86 +0xe3b0 0x7f83 +0xe3b1 0x7f88 +0xe3b2 0x7f87 +0xe3b3 0x7f8c +0xe3b4 0x7f94 +0xe3b5 0x7f9e +0xe3b6 0x7f9d +0xe3b7 0x7f9a +0xe3b8 0x7fa3 +0xe3b9 0x7faf +0xe3ba 0x7fb2 +0xe3bb 0x7fb9 +0xe3bc 0x7fae +0xe3bd 0x7fb6 +0xe3be 0x7fb8 +0xe3bf 0x8b71 +0xe3c0 0x7fc5 +0xe3c1 0x7fc6 +0xe3c2 0x7fca +0xe3c3 0x7fd5 +0xe3c4 0x7fd4 +0xe3c5 0x7fe1 +0xe3c6 0x7fe6 +0xe3c7 0x7fe9 +0xe3c8 0x7ff3 +0xe3c9 0x7ff9 +0xe3ca 0x98dc +0xe3cb 0x8006 +0xe3cc 0x8004 +0xe3cd 0x800b +0xe3ce 0x8012 +0xe3cf 0x8018 +0xe3d0 0x8019 +0xe3d1 0x801c +0xe3d2 0x8021 +0xe3d3 0x8028 +0xe3d4 0x803f +0xe3d5 0x803b +0xe3d6 0x804a +0xe3d7 0x8046 +0xe3d8 0x8052 +0xe3d9 0x8058 +0xe3da 0x805a +0xe3db 0x805f +0xe3dc 0x8062 +0xe3dd 0x8068 +0xe3de 0x8073 +0xe3df 0x8072 +0xe3e0 0x8070 +0xe3e1 0x8076 +0xe3e2 0x8079 +0xe3e3 0x807d +0xe3e4 0x807f +0xe3e5 0x8084 +0xe3e6 0x8086 +0xe3e7 0x8085 +0xe3e8 0x809b +0xe3e9 0x8093 +0xe3ea 0x809a +0xe3eb 0x80ad +0xe3ec 0x5190 +0xe3ed 0x80ac +0xe3ee 0x80db +0xe3ef 0x80e5 +0xe3f0 0x80d9 +0xe3f1 0x80dd +0xe3f2 0x80c4 +0xe3f3 0x80da +0xe3f4 0x80d6 +0xe3f5 0x8109 +0xe3f6 0x80ef +0xe3f7 0x80f1 +0xe3f8 0x811b +0xe3f9 0x8129 +0xe3fa 0x8123 +0xe3fb 0x812f +0xe3fc 0x814b +0xe440 0x968b +0xe441 0x8146 +0xe442 0x813e +0xe443 0x8153 +0xe444 0x8151 +0xe445 0x80fc +0xe446 0x8171 +0xe447 0x816e +0xe448 0x8165 +0xe449 0x8166 +0xe44a 0x8174 +0xe44b 0x8183 +0xe44c 0x8188 +0xe44d 0x818a +0xe44e 0x8180 +0xe44f 0x8182 +0xe450 0x81a0 +0xe451 0x8195 +0xe452 0x81a4 +0xe453 0x81a3 +0xe454 0x815f +0xe455 0x8193 +0xe456 0x81a9 +0xe457 0x81b0 +0xe458 0x81b5 +0xe459 0x81be +0xe45a 0x81b8 +0xe45b 0x81bd +0xe45c 0x81c0 +0xe45d 0x81c2 +0xe45e 0x81ba +0xe45f 0x81c9 +0xe460 0x81cd +0xe461 0x81d1 +0xe462 0x81d9 +0xe463 0x81d8 +0xe464 0x81c8 +0xe465 0x81da +0xe466 0x81df +0xe467 0x81e0 +0xe468 0x81e7 +0xe469 0x81fa +0xe46a 0x81fb +0xe46b 0x81fe +0xe46c 0x8201 +0xe46d 0x8202 +0xe46e 0x8205 +0xe46f 0x8207 +0xe470 0x820a +0xe471 0x820d +0xe472 0x8210 +0xe473 0x8216 +0xe474 0x8229 +0xe475 0x822b +0xe476 0x8238 +0xe477 0x8233 +0xe478 0x8240 +0xe479 0x8259 +0xe47a 0x8258 +0xe47b 0x825d +0xe47c 0x825a +0xe47d 0x825f +0xe47e 0x8264 +0xe480 0x8262 +0xe481 0x8268 +0xe482 0x826a +0xe483 0x826b +0xe484 0x822e +0xe485 0x8271 +0xe486 0x8277 +0xe487 0x8278 +0xe488 0x827e +0xe489 0x828d +0xe48a 0x8292 +0xe48b 0x82ab +0xe48c 0x829f +0xe48d 0x82bb +0xe48e 0x82ac +0xe48f 0x82e1 +0xe490 0x82e3 +0xe491 0x82df +0xe492 0x82d2 +0xe493 0x82f4 +0xe494 0x82f3 +0xe495 0x82fa +0xe496 0x8393 +0xe497 0x8303 +0xe498 0x82fb +0xe499 0x82f9 +0xe49a 0x82de +0xe49b 0x8306 +0xe49c 0x82dc +0xe49d 0x8309 +0xe49e 0x82d9 +0xe49f 0x8335 +0xe4a0 0x8334 +0xe4a1 0x8316 +0xe4a2 0x8332 +0xe4a3 0x8331 +0xe4a4 0x8340 +0xe4a5 0x8339 +0xe4a6 0x8350 +0xe4a7 0x8345 +0xe4a8 0x832f +0xe4a9 0x832b +0xe4aa 0x8317 +0xe4ab 0x8318 +0xe4ac 0x8385 +0xe4ad 0x839a +0xe4ae 0x83aa +0xe4af 0x839f +0xe4b0 0x83a2 +0xe4b1 0x8396 +0xe4b2 0x8323 +0xe4b3 0x838e +0xe4b4 0x8387 +0xe4b5 0x838a +0xe4b6 0x837c +0xe4b7 0x83b5 +0xe4b8 0x8373 +0xe4b9 0x8375 +0xe4ba 0x83a0 +0xe4bb 0x8389 +0xe4bc 0x83a8 +0xe4bd 0x83f4 +0xe4be 0x8413 +0xe4bf 0x83eb +0xe4c0 0x83ce +0xe4c1 0x83fd +0xe4c2 0x8403 +0xe4c3 0x83d8 +0xe4c4 0x840b +0xe4c5 0x83c1 +0xe4c6 0x83f7 +0xe4c7 0x8407 +0xe4c8 0x83e0 +0xe4c9 0x83f2 +0xe4ca 0x840d +0xe4cb 0x8422 +0xe4cc 0x8420 +0xe4cd 0x83bd +0xe4ce 0x8438 +0xe4cf 0x8506 +0xe4d0 0x83fb +0xe4d1 0x846d +0xe4d2 0x842a +0xe4d3 0x843c +0xe4d4 0x855a +0xe4d5 0x8484 +0xe4d6 0x8477 +0xe4d7 0x846b +0xe4d8 0x84ad +0xe4d9 0x846e +0xe4da 0x8482 +0xe4db 0x8469 +0xe4dc 0x8446 +0xe4dd 0x842c +0xe4de 0x846f +0xe4df 0x8479 +0xe4e0 0x8435 +0xe4e1 0x84ca +0xe4e2 0x8462 +0xe4e3 0x84b9 +0xe4e4 0x84bf +0xe4e5 0x849f +0xe4e6 0x84d9 +0xe4e7 0x84cd +0xe4e8 0x84bb +0xe4e9 0x84da +0xe4ea 0x84d0 +0xe4eb 0x84c1 +0xe4ec 0x84c6 +0xe4ed 0x84d6 +0xe4ee 0x84a1 +0xe4ef 0x8521 +0xe4f0 0x84ff +0xe4f1 0x84f4 +0xe4f2 0x8517 +0xe4f3 0x8518 +0xe4f4 0x852c +0xe4f5 0x851f +0xe4f6 0x8515 +0xe4f7 0x8514 +0xe4f8 0x84fc +0xe4f9 0x8540 +0xe4fa 0x8563 +0xe4fb 0x8558 +0xe4fc 0x8548 +0xe540 0x8541 +0xe541 0x8602 +0xe542 0x854b +0xe543 0x8555 +0xe544 0x8580 +0xe545 0x85a4 +0xe546 0x8588 +0xe547 0x8591 +0xe548 0x858a +0xe549 0x85a8 +0xe54a 0x856d +0xe54b 0x8594 +0xe54c 0x859b +0xe54d 0x85ea +0xe54e 0x8587 +0xe54f 0x859c +0xe550 0x8577 +0xe551 0x857e +0xe552 0x8590 +0xe553 0x85c9 +0xe554 0x85ba +0xe555 0x85cf +0xe556 0x85b9 +0xe557 0x85d0 +0xe558 0x85d5 +0xe559 0x85dd +0xe55a 0x85e5 +0xe55b 0x85dc +0xe55c 0x85f9 +0xe55d 0x860a +0xe55e 0x8613 +0xe55f 0x860b +0xe560 0x85fe +0xe561 0x85fa +0xe562 0x8606 +0xe563 0x8622 +0xe564 0x861a +0xe565 0x8630 +0xe566 0x863f +0xe567 0x864d +0xe568 0x4e55 +0xe569 0x8654 +0xe56a 0x865f +0xe56b 0x8667 +0xe56c 0x8671 +0xe56d 0x8693 +0xe56e 0x86a3 +0xe56f 0x86a9 +0xe570 0x86aa +0xe571 0x868b +0xe572 0x868c +0xe573 0x86b6 +0xe574 0x86af +0xe575 0x86c4 +0xe576 0x86c6 +0xe577 0x86b0 +0xe578 0x86c9 +0xe579 0x8823 +0xe57a 0x86ab +0xe57b 0x86d4 +0xe57c 0x86de +0xe57d 0x86e9 +0xe57e 0x86ec +0xe580 0x86df +0xe581 0x86db +0xe582 0x86ef +0xe583 0x8712 +0xe584 0x8706 +0xe585 0x8708 +0xe586 0x8700 +0xe587 0x8703 +0xe588 0x86fb +0xe589 0x8711 +0xe58a 0x8709 +0xe58b 0x870d +0xe58c 0x86f9 +0xe58d 0x870a +0xe58e 0x8734 +0xe58f 0x873f +0xe590 0x8737 +0xe591 0x873b +0xe592 0x8725 +0xe593 0x8729 +0xe594 0x871a +0xe595 0x8760 +0xe596 0x875f +0xe597 0x8778 +0xe598 0x874c +0xe599 0x874e +0xe59a 0x8774 +0xe59b 0x8757 +0xe59c 0x8768 +0xe59d 0x876e +0xe59e 0x8759 +0xe59f 0x8753 +0xe5a0 0x8763 +0xe5a1 0x876a +0xe5a2 0x8805 +0xe5a3 0x87a2 +0xe5a4 0x879f +0xe5a5 0x8782 +0xe5a6 0x87af +0xe5a7 0x87cb +0xe5a8 0x87bd +0xe5a9 0x87c0 +0xe5aa 0x87d0 +0xe5ab 0x96d6 +0xe5ac 0x87ab +0xe5ad 0x87c4 +0xe5ae 0x87b3 +0xe5af 0x87c7 +0xe5b0 0x87c6 +0xe5b1 0x87bb +0xe5b2 0x87ef +0xe5b3 0x87f2 +0xe5b4 0x87e0 +0xe5b5 0x880f +0xe5b6 0x880d +0xe5b7 0x87fe +0xe5b8 0x87f6 +0xe5b9 0x87f7 +0xe5ba 0x880e +0xe5bb 0x87d2 +0xe5bc 0x8811 +0xe5bd 0x8816 +0xe5be 0x8815 +0xe5bf 0x8822 +0xe5c0 0x8821 +0xe5c1 0x8831 +0xe5c2 0x8836 +0xe5c3 0x8839 +0xe5c4 0x8827 +0xe5c5 0x883b +0xe5c6 0x8844 +0xe5c7 0x8842 +0xe5c8 0x8852 +0xe5c9 0x8859 +0xe5ca 0x885e +0xe5cb 0x8862 +0xe5cc 0x886b +0xe5cd 0x8881 +0xe5ce 0x887e +0xe5cf 0x889e +0xe5d0 0x8875 +0xe5d1 0x887d +0xe5d2 0x88b5 +0xe5d3 0x8872 +0xe5d4 0x8882 +0xe5d5 0x8897 +0xe5d6 0x8892 +0xe5d7 0x88ae +0xe5d8 0x8899 +0xe5d9 0x88a2 +0xe5da 0x888d +0xe5db 0x88a4 +0xe5dc 0x88b0 +0xe5dd 0x88bf +0xe5de 0x88b1 +0xe5df 0x88c3 +0xe5e0 0x88c4 +0xe5e1 0x88d4 +0xe5e2 0x88d8 +0xe5e3 0x88d9 +0xe5e4 0x88dd +0xe5e5 0x88f9 +0xe5e6 0x8902 +0xe5e7 0x88fc +0xe5e8 0x88f4 +0xe5e9 0x88e8 +0xe5ea 0x88f2 +0xe5eb 0x8904 +0xe5ec 0x890c +0xe5ed 0x890a +0xe5ee 0x8913 +0xe5ef 0x8943 +0xe5f0 0x891e +0xe5f1 0x8925 +0xe5f2 0x892a +0xe5f3 0x892b +0xe5f4 0x8941 +0xe5f5 0x8944 +0xe5f6 0x893b +0xe5f7 0x8936 +0xe5f8 0x8938 +0xe5f9 0x894c +0xe5fa 0x891d +0xe5fb 0x8960 +0xe5fc 0x895e +0xe640 0x8966 +0xe641 0x8964 +0xe642 0x896d +0xe643 0x896a +0xe644 0x896f +0xe645 0x8974 +0xe646 0x8977 +0xe647 0x897e +0xe648 0x8983 +0xe649 0x8988 +0xe64a 0x898a +0xe64b 0x8993 +0xe64c 0x8998 +0xe64d 0x89a1 +0xe64e 0x89a9 +0xe64f 0x89a6 +0xe650 0x89ac +0xe651 0x89af +0xe652 0x89b2 +0xe653 0x89ba +0xe654 0x89bd +0xe655 0x89bf +0xe656 0x89c0 +0xe657 0x89da +0xe658 0x89dc +0xe659 0x89dd +0xe65a 0x89e7 +0xe65b 0x89f4 +0xe65c 0x89f8 +0xe65d 0x8a03 +0xe65e 0x8a16 +0xe65f 0x8a10 +0xe660 0x8a0c +0xe661 0x8a1b +0xe662 0x8a1d +0xe663 0x8a25 +0xe664 0x8a36 +0xe665 0x8a41 +0xe666 0x8a5b +0xe667 0x8a52 +0xe668 0x8a46 +0xe669 0x8a48 +0xe66a 0x8a7c +0xe66b 0x8a6d +0xe66c 0x8a6c +0xe66d 0x8a62 +0xe66e 0x8a85 +0xe66f 0x8a82 +0xe670 0x8a84 +0xe671 0x8aa8 +0xe672 0x8aa1 +0xe673 0x8a91 +0xe674 0x8aa5 +0xe675 0x8aa6 +0xe676 0x8a9a +0xe677 0x8aa3 +0xe678 0x8ac4 +0xe679 0x8acd +0xe67a 0x8ac2 +0xe67b 0x8ada +0xe67c 0x8aeb +0xe67d 0x8af3 +0xe67e 0x8ae7 +0xe680 0x8ae4 +0xe681 0x8af1 +0xe682 0x8b14 +0xe683 0x8ae0 +0xe684 0x8ae2 +0xe685 0x8af7 +0xe686 0x8ade +0xe687 0x8adb +0xe688 0x8b0c +0xe689 0x8b07 +0xe68a 0x8b1a +0xe68b 0x8ae1 +0xe68c 0x8b16 +0xe68d 0x8b10 +0xe68e 0x8b17 +0xe68f 0x8b20 +0xe690 0x8b33 +0xe691 0x97ab +0xe692 0x8b26 +0xe693 0x8b2b +0xe694 0x8b3e +0xe695 0x8b28 +0xe696 0x8b41 +0xe697 0x8b4c +0xe698 0x8b4f +0xe699 0x8b4e +0xe69a 0x8b49 +0xe69b 0x8b56 +0xe69c 0x8b5b +0xe69d 0x8b5a +0xe69e 0x8b6b +0xe69f 0x8b5f +0xe6a0 0x8b6c +0xe6a1 0x8b6f +0xe6a2 0x8b74 +0xe6a3 0x8b7d +0xe6a4 0x8b80 +0xe6a5 0x8b8c +0xe6a6 0x8b8e +0xe6a7 0x8b92 +0xe6a8 0x8b93 +0xe6a9 0x8b96 +0xe6aa 0x8b99 +0xe6ab 0x8b9a +0xe6ac 0x8c3a +0xe6ad 0x8c41 +0xe6ae 0x8c3f +0xe6af 0x8c48 +0xe6b0 0x8c4c +0xe6b1 0x8c4e +0xe6b2 0x8c50 +0xe6b3 0x8c55 +0xe6b4 0x8c62 +0xe6b5 0x8c6c +0xe6b6 0x8c78 +0xe6b7 0x8c7a +0xe6b8 0x8c82 +0xe6b9 0x8c89 +0xe6ba 0x8c85 +0xe6bb 0x8c8a +0xe6bc 0x8c8d +0xe6bd 0x8c8e +0xe6be 0x8c94 +0xe6bf 0x8c7c +0xe6c0 0x8c98 +0xe6c1 0x621d +0xe6c2 0x8cad +0xe6c3 0x8caa +0xe6c4 0x8cbd +0xe6c5 0x8cb2 +0xe6c6 0x8cb3 +0xe6c7 0x8cae +0xe6c8 0x8cb6 +0xe6c9 0x8cc8 +0xe6ca 0x8cc1 +0xe6cb 0x8ce4 +0xe6cc 0x8ce3 +0xe6cd 0x8cda +0xe6ce 0x8cfd +0xe6cf 0x8cfa +0xe6d0 0x8cfb +0xe6d1 0x8d04 +0xe6d2 0x8d05 +0xe6d3 0x8d0a +0xe6d4 0x8d07 +0xe6d5 0x8d0f +0xe6d6 0x8d0d +0xe6d7 0x8d10 +0xe6d8 0x9f4e +0xe6d9 0x8d13 +0xe6da 0x8ccd +0xe6db 0x8d14 +0xe6dc 0x8d16 +0xe6dd 0x8d67 +0xe6de 0x8d6d +0xe6df 0x8d71 +0xe6e0 0x8d73 +0xe6e1 0x8d81 +0xe6e2 0x8d99 +0xe6e3 0x8dc2 +0xe6e4 0x8dbe +0xe6e5 0x8dba +0xe6e6 0x8dcf +0xe6e7 0x8dda +0xe6e8 0x8dd6 +0xe6e9 0x8dcc +0xe6ea 0x8ddb +0xe6eb 0x8dcb +0xe6ec 0x8dea +0xe6ed 0x8deb +0xe6ee 0x8ddf +0xe6ef 0x8de3 +0xe6f0 0x8dfc +0xe6f1 0x8e08 +0xe6f2 0x8e09 +0xe6f3 0x8dff +0xe6f4 0x8e1d +0xe6f5 0x8e1e +0xe6f6 0x8e10 +0xe6f7 0x8e1f +0xe6f8 0x8e42 +0xe6f9 0x8e35 +0xe6fa 0x8e30 +0xe6fb 0x8e34 +0xe6fc 0x8e4a +0xe740 0x8e47 +0xe741 0x8e49 +0xe742 0x8e4c +0xe743 0x8e50 +0xe744 0x8e48 +0xe745 0x8e59 +0xe746 0x8e64 +0xe747 0x8e60 +0xe748 0x8e2a +0xe749 0x8e63 +0xe74a 0x8e55 +0xe74b 0x8e76 +0xe74c 0x8e72 +0xe74d 0x8e7c +0xe74e 0x8e81 +0xe74f 0x8e87 +0xe750 0x8e85 +0xe751 0x8e84 +0xe752 0x8e8b +0xe753 0x8e8a +0xe754 0x8e93 +0xe755 0x8e91 +0xe756 0x8e94 +0xe757 0x8e99 +0xe758 0x8eaa +0xe759 0x8ea1 +0xe75a 0x8eac +0xe75b 0x8eb0 +0xe75c 0x8ec6 +0xe75d 0x8eb1 +0xe75e 0x8ebe +0xe75f 0x8ec5 +0xe760 0x8ec8 +0xe761 0x8ecb +0xe762 0x8edb +0xe763 0x8ee3 +0xe764 0x8efc +0xe765 0x8efb +0xe766 0x8eeb +0xe767 0x8efe +0xe768 0x8f0a +0xe769 0x8f05 +0xe76a 0x8f15 +0xe76b 0x8f12 +0xe76c 0x8f19 +0xe76d 0x8f13 +0xe76e 0x8f1c +0xe76f 0x8f1f +0xe770 0x8f1b +0xe771 0x8f0c +0xe772 0x8f26 +0xe773 0x8f33 +0xe774 0x8f3b +0xe775 0x8f39 +0xe776 0x8f45 +0xe777 0x8f42 +0xe778 0x8f3e +0xe779 0x8f4c +0xe77a 0x8f49 +0xe77b 0x8f46 +0xe77c 0x8f4e +0xe77d 0x8f57 +0xe77e 0x8f5c +0xe780 0x8f62 +0xe781 0x8f63 +0xe782 0x8f64 +0xe783 0x8f9c +0xe784 0x8f9f +0xe785 0x8fa3 +0xe786 0x8fad +0xe787 0x8faf +0xe788 0x8fb7 +0xe789 0x8fda +0xe78a 0x8fe5 +0xe78b 0x8fe2 +0xe78c 0x8fea +0xe78d 0x8fef +0xe78e 0x9087 +0xe78f 0x8ff4 +0xe790 0x9005 +0xe791 0x8ff9 +0xe792 0x8ffa +0xe793 0x9011 +0xe794 0x9015 +0xe795 0x9021 +0xe796 0x900d +0xe797 0x901e +0xe798 0x9016 +0xe799 0x900b +0xe79a 0x9027 +0xe79b 0x9036 +0xe79c 0x9035 +0xe79d 0x9039 +0xe79e 0x8ff8 +0xe79f 0x904f +0xe7a0 0x9050 +0xe7a1 0x9051 +0xe7a2 0x9052 +0xe7a3 0x900e +0xe7a4 0x9049 +0xe7a5 0x903e +0xe7a6 0x9056 +0xe7a7 0x9058 +0xe7a8 0x905e +0xe7a9 0x9068 +0xe7aa 0x906f +0xe7ab 0x9076 +0xe7ac 0x96a8 +0xe7ad 0x9072 +0xe7ae 0x9082 +0xe7af 0x907d +0xe7b0 0x9081 +0xe7b1 0x9080 +0xe7b2 0x908a +0xe7b3 0x9089 +0xe7b4 0x908f +0xe7b5 0x90a8 +0xe7b6 0x90af +0xe7b7 0x90b1 +0xe7b8 0x90b5 +0xe7b9 0x90e2 +0xe7ba 0x90e4 +0xe7bb 0x6248 +0xe7bc 0x90db +0xe7bd 0x9102 +0xe7be 0x9112 +0xe7bf 0x9119 +0xe7c0 0x9132 +0xe7c1 0x9130 +0xe7c2 0x914a +0xe7c3 0x9156 +0xe7c4 0x9158 +0xe7c5 0x9163 +0xe7c6 0x9165 +0xe7c7 0x9169 +0xe7c8 0x9173 +0xe7c9 0x9172 +0xe7ca 0x918b +0xe7cb 0x9189 +0xe7cc 0x9182 +0xe7cd 0x91a2 +0xe7ce 0x91ab +0xe7cf 0x91af +0xe7d0 0x91aa +0xe7d1 0x91b5 +0xe7d2 0x91b4 +0xe7d3 0x91ba +0xe7d4 0x91c0 +0xe7d5 0x91c1 +0xe7d6 0x91c9 +0xe7d7 0x91cb +0xe7d8 0x91d0 +0xe7d9 0x91d6 +0xe7da 0x91df +0xe7db 0x91e1 +0xe7dc 0x91db +0xe7dd 0x91fc +0xe7de 0x91f5 +0xe7df 0x91f6 +0xe7e0 0x921e +0xe7e1 0x91ff +0xe7e2 0x9214 +0xe7e3 0x922c +0xe7e4 0x9215 +0xe7e5 0x9211 +0xe7e6 0x925e +0xe7e7 0x9257 +0xe7e8 0x9245 +0xe7e9 0x9249 +0xe7ea 0x9264 +0xe7eb 0x9248 +0xe7ec 0x9295 +0xe7ed 0x923f +0xe7ee 0x924b +0xe7ef 0x9250 +0xe7f0 0x929c +0xe7f1 0x9296 +0xe7f2 0x9293 +0xe7f3 0x929b +0xe7f4 0x925a +0xe7f5 0x92cf +0xe7f6 0x92b9 +0xe7f7 0x92b7 +0xe7f8 0x92e9 +0xe7f9 0x930f +0xe7fa 0x92fa +0xe7fb 0x9344 +0xe7fc 0x932e +0xe840 0x9319 +0xe841 0x9322 +0xe842 0x931a +0xe843 0x9323 +0xe844 0x933a +0xe845 0x9335 +0xe846 0x933b +0xe847 0x935c +0xe848 0x9360 +0xe849 0x937c +0xe84a 0x936e +0xe84b 0x9356 +0xe84c 0x93b0 +0xe84d 0x93ac +0xe84e 0x93ad +0xe84f 0x9394 +0xe850 0x93b9 +0xe851 0x93d6 +0xe852 0x93d7 +0xe853 0x93e8 +0xe854 0x93e5 +0xe855 0x93d8 +0xe856 0x93c3 +0xe857 0x93dd +0xe858 0x93d0 +0xe859 0x93c8 +0xe85a 0x93e4 +0xe85b 0x941a +0xe85c 0x9414 +0xe85d 0x9413 +0xe85e 0x9403 +0xe85f 0x9407 +0xe860 0x9410 +0xe861 0x9436 +0xe862 0x942b +0xe863 0x9435 +0xe864 0x9421 +0xe865 0x943a +0xe866 0x9441 +0xe867 0x9452 +0xe868 0x9444 +0xe869 0x945b +0xe86a 0x9460 +0xe86b 0x9462 +0xe86c 0x945e +0xe86d 0x946a +0xe86e 0x9229 +0xe86f 0x9470 +0xe870 0x9475 +0xe871 0x9477 +0xe872 0x947d +0xe873 0x945a +0xe874 0x947c +0xe875 0x947e +0xe876 0x9481 +0xe877 0x947f +0xe878 0x9582 +0xe879 0x9587 +0xe87a 0x958a +0xe87b 0x9594 +0xe87c 0x9596 +0xe87d 0x9598 +0xe87e 0x9599 +0xe880 0x95a0 +0xe881 0x95a8 +0xe882 0x95a7 +0xe883 0x95ad +0xe884 0x95bc +0xe885 0x95bb +0xe886 0x95b9 +0xe887 0x95be +0xe888 0x95ca +0xe889 0x6ff6 +0xe88a 0x95c3 +0xe88b 0x95cd +0xe88c 0x95cc +0xe88d 0x95d5 +0xe88e 0x95d4 +0xe88f 0x95d6 +0xe890 0x95dc +0xe891 0x95e1 +0xe892 0x95e5 +0xe893 0x95e2 +0xe894 0x9621 +0xe895 0x9628 +0xe896 0x962e +0xe897 0x962f +0xe898 0x9642 +0xe899 0x964c +0xe89a 0x964f +0xe89b 0x964b +0xe89c 0x9677 +0xe89d 0x965c +0xe89e 0x965e +0xe89f 0x965d +0xe8a0 0x965f +0xe8a1 0x9666 +0xe8a2 0x9672 +0xe8a3 0x966c +0xe8a4 0x968d +0xe8a5 0x9698 +0xe8a6 0x9695 +0xe8a7 0x9697 +0xe8a8 0x96aa +0xe8a9 0x96a7 +0xe8aa 0x96b1 +0xe8ab 0x96b2 +0xe8ac 0x96b0 +0xe8ad 0x96b4 +0xe8ae 0x96b6 +0xe8af 0x96b8 +0xe8b0 0x96b9 +0xe8b1 0x96ce +0xe8b2 0x96cb +0xe8b3 0x96c9 +0xe8b4 0x96cd +0xe8b5 0x894d +0xe8b6 0x96dc +0xe8b7 0x970d +0xe8b8 0x96d5 +0xe8b9 0x96f9 +0xe8ba 0x9704 +0xe8bb 0x9706 +0xe8bc 0x9708 +0xe8bd 0x9713 +0xe8be 0x970e +0xe8bf 0x9711 +0xe8c0 0x970f +0xe8c1 0x9716 +0xe8c2 0x9719 +0xe8c3 0x9724 +0xe8c4 0x972a +0xe8c5 0x9730 +0xe8c6 0x9739 +0xe8c7 0x973d +0xe8c8 0x973e +0xe8c9 0x9744 +0xe8ca 0x9746 +0xe8cb 0x9748 +0xe8cc 0x9742 +0xe8cd 0x9749 +0xe8ce 0x975c +0xe8cf 0x9760 +0xe8d0 0x9764 +0xe8d1 0x9766 +0xe8d2 0x9768 +0xe8d3 0x52d2 +0xe8d4 0x976b +0xe8d5 0x9771 +0xe8d6 0x9779 +0xe8d7 0x9785 +0xe8d8 0x977c +0xe8d9 0x9781 +0xe8da 0x977a +0xe8db 0x9786 +0xe8dc 0x978b +0xe8dd 0x978f +0xe8de 0x9790 +0xe8df 0x979c +0xe8e0 0x97a8 +0xe8e1 0x97a6 +0xe8e2 0x97a3 +0xe8e3 0x97b3 +0xe8e4 0x97b4 +0xe8e5 0x97c3 +0xe8e6 0x97c6 +0xe8e7 0x97c8 +0xe8e8 0x97cb +0xe8e9 0x97dc +0xe8ea 0x97ed +0xe8eb 0x9f4f +0xe8ec 0x97f2 +0xe8ed 0x7adf +0xe8ee 0x97f6 +0xe8ef 0x97f5 +0xe8f0 0x980f +0xe8f1 0x980c +0xe8f2 0x9838 +0xe8f3 0x9824 +0xe8f4 0x9821 +0xe8f5 0x9837 +0xe8f6 0x983d +0xe8f7 0x9846 +0xe8f8 0x984f +0xe8f9 0x984b +0xe8fa 0x986b +0xe8fb 0x986f +0xe8fc 0x9870 +0xe940 0x9871 +0xe941 0x9874 +0xe942 0x9873 +0xe943 0x98aa +0xe944 0x98af +0xe945 0x98b1 +0xe946 0x98b6 +0xe947 0x98c4 +0xe948 0x98c3 +0xe949 0x98c6 +0xe94a 0x98e9 +0xe94b 0x98eb +0xe94c 0x9903 +0xe94d 0x9909 +0xe94e 0x9912 +0xe94f 0x9914 +0xe950 0x9918 +0xe951 0x9921 +0xe952 0x991d +0xe953 0x991e +0xe954 0x9924 +0xe955 0x9920 +0xe956 0x992c +0xe957 0x992e +0xe958 0x993d +0xe959 0x993e +0xe95a 0x9942 +0xe95b 0x9949 +0xe95c 0x9945 +0xe95d 0x9950 +0xe95e 0x994b +0xe95f 0x9951 +0xe960 0x9952 +0xe961 0x994c +0xe962 0x9955 +0xe963 0x9997 +0xe964 0x9998 +0xe965 0x99a5 +0xe966 0x99ad +0xe967 0x99ae +0xe968 0x99bc +0xe969 0x99df +0xe96a 0x99db +0xe96b 0x99dd +0xe96c 0x99d8 +0xe96d 0x99d1 +0xe96e 0x99ed +0xe96f 0x99ee +0xe970 0x99f1 +0xe971 0x99f2 +0xe972 0x99fb +0xe973 0x99f8 +0xe974 0x9a01 +0xe975 0x9a0f +0xe976 0x9a05 +0xe977 0x99e2 +0xe978 0x9a19 +0xe979 0x9a2b +0xe97a 0x9a37 +0xe97b 0x9a45 +0xe97c 0x9a42 +0xe97d 0x9a40 +0xe97e 0x9a43 +0xe980 0x9a3e +0xe981 0x9a55 +0xe982 0x9a4d +0xe983 0x9a5b +0xe984 0x9a57 +0xe985 0x9a5f +0xe986 0x9a62 +0xe987 0x9a65 +0xe988 0x9a64 +0xe989 0x9a69 +0xe98a 0x9a6b +0xe98b 0x9a6a +0xe98c 0x9aad +0xe98d 0x9ab0 +0xe98e 0x9abc +0xe98f 0x9ac0 +0xe990 0x9acf +0xe991 0x9ad1 +0xe992 0x9ad3 +0xe993 0x9ad4 +0xe994 0x9ade +0xe995 0x9adf +0xe996 0x9ae2 +0xe997 0x9ae3 +0xe998 0x9ae6 +0xe999 0x9aef +0xe99a 0x9aeb +0xe99b 0x9aee +0xe99c 0x9af4 +0xe99d 0x9af1 +0xe99e 0x9af7 +0xe99f 0x9afb +0xe9a0 0x9b06 +0xe9a1 0x9b18 +0xe9a2 0x9b1a +0xe9a3 0x9b1f +0xe9a4 0x9b22 +0xe9a5 0x9b23 +0xe9a6 0x9b25 +0xe9a7 0x9b27 +0xe9a8 0x9b28 +0xe9a9 0x9b29 +0xe9aa 0x9b2a +0xe9ab 0x9b2e +0xe9ac 0x9b2f +0xe9ad 0x9b32 +0xe9ae 0x9b44 +0xe9af 0x9b43 +0xe9b0 0x9b4f +0xe9b1 0x9b4d +0xe9b2 0x9b4e +0xe9b3 0x9b51 +0xe9b4 0x9b58 +0xe9b5 0x9b74 +0xe9b6 0x9b93 +0xe9b7 0x9b83 +0xe9b8 0x9b91 +0xe9b9 0x9b96 +0xe9ba 0x9b97 +0xe9bb 0x9b9f +0xe9bc 0x9ba0 +0xe9bd 0x9ba8 +0xe9be 0x9bb4 +0xe9bf 0x9bc0 +0xe9c0 0x9bca +0xe9c1 0x9bb9 +0xe9c2 0x9bc6 +0xe9c3 0x9bcf +0xe9c4 0x9bd1 +0xe9c5 0x9bd2 +0xe9c6 0x9be3 +0xe9c7 0x9be2 +0xe9c8 0x9be4 +0xe9c9 0x9bd4 +0xe9ca 0x9be1 +0xe9cb 0x9c3a +0xe9cc 0x9bf2 +0xe9cd 0x9bf1 +0xe9ce 0x9bf0 +0xe9cf 0x9c15 +0xe9d0 0x9c14 +0xe9d1 0x9c09 +0xe9d2 0x9c13 +0xe9d3 0x9c0c +0xe9d4 0x9c06 +0xe9d5 0x9c08 +0xe9d6 0x9c12 +0xe9d7 0x9c0a +0xe9d8 0x9c04 +0xe9d9 0x9c2e +0xe9da 0x9c1b +0xe9db 0x9c25 +0xe9dc 0x9c24 +0xe9dd 0x9c21 +0xe9de 0x9c30 +0xe9df 0x9c47 +0xe9e0 0x9c32 +0xe9e1 0x9c46 +0xe9e2 0x9c3e +0xe9e3 0x9c5a +0xe9e4 0x9c60 +0xe9e5 0x9c67 +0xe9e6 0x9c76 +0xe9e7 0x9c78 +0xe9e8 0x9ce7 +0xe9e9 0x9cec +0xe9ea 0x9cf0 +0xe9eb 0x9d09 +0xe9ec 0x9d08 +0xe9ed 0x9ceb +0xe9ee 0x9d03 +0xe9ef 0x9d06 +0xe9f0 0x9d2a +0xe9f1 0x9d26 +0xe9f2 0x9daf +0xe9f3 0x9d23 +0xe9f4 0x9d1f +0xe9f5 0x9d44 +0xe9f6 0x9d15 +0xe9f7 0x9d12 +0xe9f8 0x9d41 +0xe9f9 0x9d3f +0xe9fa 0x9d3e +0xe9fb 0x9d46 +0xe9fc 0x9d48 +0xea40 0x9d5d +0xea41 0x9d5e +0xea42 0x9d64 +0xea43 0x9d51 +0xea44 0x9d50 +0xea45 0x9d59 +0xea46 0x9d72 +0xea47 0x9d89 +0xea48 0x9d87 +0xea49 0x9dab +0xea4a 0x9d6f +0xea4b 0x9d7a +0xea4c 0x9d9a +0xea4d 0x9da4 +0xea4e 0x9da9 +0xea4f 0x9db2 +0xea50 0x9dc4 +0xea51 0x9dc1 +0xea52 0x9dbb +0xea53 0x9db8 +0xea54 0x9dba +0xea55 0x9dc6 +0xea56 0x9dcf +0xea57 0x9dc2 +0xea58 0x9dd9 +0xea59 0x9dd3 +0xea5a 0x9df8 +0xea5b 0x9de6 +0xea5c 0x9ded +0xea5d 0x9def +0xea5e 0x9dfd +0xea5f 0x9e1a +0xea60 0x9e1b +0xea61 0x9e1e +0xea62 0x9e75 +0xea63 0x9e79 +0xea64 0x9e7d +0xea65 0x9e81 +0xea66 0x9e88 +0xea67 0x9e8b +0xea68 0x9e8c +0xea69 0x9e92 +0xea6a 0x9e95 +0xea6b 0x9e91 +0xea6c 0x9e9d +0xea6d 0x9ea5 +0xea6e 0x9ea9 +0xea6f 0x9eb8 +0xea70 0x9eaa +0xea71 0x9ead +0xea72 0x9761 +0xea73 0x9ecc +0xea74 0x9ece +0xea75 0x9ecf +0xea76 0x9ed0 +0xea77 0x9ed4 +0xea78 0x9edc +0xea79 0x9ede +0xea7a 0x9edd +0xea7b 0x9ee0 +0xea7c 0x9ee5 +0xea7d 0x9ee8 +0xea7e 0x9eef +0xea80 0x9ef4 +0xea81 0x9ef6 +0xea82 0x9ef7 +0xea83 0x9ef9 +0xea84 0x9efb +0xea85 0x9efc +0xea86 0x9efd +0xea87 0x9f07 +0xea88 0x9f08 +0xea89 0x76b7 +0xea8a 0x9f15 +0xea8b 0x9f21 +0xea8c 0x9f2c +0xea8d 0x9f3e +0xea8e 0x9f4a +0xea8f 0x9f52 +0xea90 0x9f54 +0xea91 0x9f63 +0xea92 0x9f5f +0xea93 0x9f60 +0xea94 0x9f61 +0xea95 0x9f66 +0xea96 0x9f67 +0xea97 0x9f6c +0xea98 0x9f6a +0xea99 0x9f77 +0xea9a 0x9f72 +0xea9b 0x9f76 +0xea9c 0x9f95 +0xea9d 0x9f9c +0xea9e 0x9fa0 +0xea9f 0x582f +0xeaa0 0x69c7 +0xeaa1 0x9059 +0xeaa2 0x7464 +0xeaa3 0x51dc +0xeaa4 0x7199 +0xeaa5 0x5653 +0xeaa6 0x5de2 +0xeaa7 0x5e14 +0xeaa8 0x5e18 +0xeaa9 0x5e58 +0xeaaa 0x5e5e +0xeaab 0x5ebe +0xeaac 0xf928 +0xeaad 0x5ecb +0xeaae 0x5ef9 +0xeaaf 0x5f00 +0xeab0 0x5f02 +0xeab1 0x5f07 +0xeab2 0x5f1d +0xeab3 0x5f23 +0xeab4 0x5f34 +0xeab5 0x5f36 +0xeab6 0x5f3d +0xeab7 0x5f40 +0xeab8 0x5f45 +0xeab9 0x5f54 +0xeaba 0x5f58 +0xeabb 0x5f64 +0xeabc 0x5f67 +0xeabd 0x5f7d +0xeabe 0x5f89 +0xeabf 0x5f9c +0xeac0 0x5fa7 +0xeac1 0x5faf +0xeac2 0x5fb5 +0xeac3 0x5fb7 +0xeac4 0x5fc9 +0xeac5 0x5fde +0xeac6 0x5fe1 +0xeac7 0x5fe9 +0xeac8 0x600d +0xeac9 0x6014 +0xeaca 0x6018 +0xeacb 0x6033 +0xeacc 0x6035 +0xeacd 0x6047 +0xeace 0xfa3d +0xeacf 0x609d +0xead0 0x609e +0xead1 0x60cb +0xead2 0x60d4 +0xead3 0x60d5 +0xead4 0x60dd +0xead5 0x60f8 +0xead6 0x611c +0xead7 0x612b +0xead8 0x6130 +0xead9 0x6137 +0xeada 0xfa3e +0xeadb 0x618d +0xeadc 0xfa3f +0xeadd 0x61bc +0xeade 0x61b9 +0xeadf 0xfa40 +0xeae0 0x6222 +0xeae1 0x623e +0xeae2 0x6243 +0xeae3 0x6256 +0xeae4 0x625a +0xeae5 0x626f +0xeae6 0x6285 +0xeae7 0x62c4 +0xeae8 0x62d6 +0xeae9 0x62fc +0xeaea 0x630a +0xeaeb 0x6318 +0xeaec 0x6339 +0xeaed 0x6343 +0xeaee 0x6365 +0xeaef 0x637c +0xeaf0 0x63e5 +0xeaf1 0x63ed +0xeaf2 0x63f5 +0xeaf3 0x6410 +0xeaf4 0x6414 +0xeaf5 0x6422 +0xeaf6 0x6479 +0xeaf7 0x6451 +0xeaf8 0x6460 +0xeaf9 0x646d +0xeafa 0x64ce +0xeafb 0x64be +0xeafc 0x64bf +0xeb40 0x64c4 +0xeb41 0x64ca +0xeb42 0x64d0 +0xeb43 0x64f7 +0xeb44 0x64fb +0xeb45 0x6522 +0xeb46 0x6529 +0xeb47 0xfa41 +0xeb48 0x6567 +0xeb49 0x659d +0xeb4a 0xfa42 +0xeb4b 0x6600 +0xeb4c 0x6609 +0xeb4d 0x6615 +0xeb4e 0x661e +0xeb4f 0x663a +0xeb50 0x6622 +0xeb51 0x6624 +0xeb52 0x662b +0xeb53 0x6630 +0xeb54 0x6631 +0xeb55 0x6633 +0xeb56 0x66fb +0xeb57 0x6648 +0xeb58 0x664c +0xeb59 0x231c4 +0xeb5a 0x6659 +0xeb5b 0x665a +0xeb5c 0x6661 +0xeb5d 0x6665 +0xeb5e 0x6673 +0xeb5f 0x6677 +0xeb60 0x6678 +0xeb61 0x668d +0xeb62 0xfa43 +0xeb63 0x66a0 +0xeb64 0x66b2 +0xeb65 0x66bb +0xeb66 0x66c6 +0xeb67 0x66c8 +0xeb68 0x3b22 +0xeb69 0x66db +0xeb6a 0x66e8 +0xeb6b 0x66fa +0xeb6c 0x6713 +0xeb6d 0xf929 +0xeb6e 0x6733 +0xeb6f 0x6766 +0xeb70 0x6747 +0xeb71 0x6748 +0xeb72 0x677b +0xeb73 0x6781 +0xeb74 0x6793 +0xeb75 0x6798 +0xeb76 0x679b +0xeb77 0x67bb +0xeb78 0x67f9 +0xeb79 0x67c0 +0xeb7a 0x67d7 +0xeb7b 0x67fc +0xeb7c 0x6801 +0xeb7d 0x6852 +0xeb7e 0x681d +0xeb80 0x682c +0xeb81 0x6831 +0xeb82 0x685b +0xeb83 0x6872 +0xeb84 0x6875 +0xeb85 0xfa44 +0xeb86 0x68a3 +0xeb87 0x68a5 +0xeb88 0x68b2 +0xeb89 0x68c8 +0xeb8a 0x68d0 +0xeb8b 0x68e8 +0xeb8c 0x68ed +0xeb8d 0x68f0 +0xeb8e 0x68f1 +0xeb8f 0x68fc +0xeb90 0x690a +0xeb91 0x6949 +0xeb92 0x235c4 +0xeb93 0x6935 +0xeb94 0x6942 +0xeb95 0x6957 +0xeb96 0x6963 +0xeb97 0x6964 +0xeb98 0x6968 +0xeb99 0x6980 +0xeb9a 0xfa14 +0xeb9b 0x69a5 +0xeb9c 0x69ad +0xeb9d 0x69cf +0xeb9e 0x3bb6 +0xeb9f 0x3bc3 +0xeba0 0x69e2 +0xeba1 0x69e9 +0xeba2 0x69ea +0xeba3 0x69f5 +0xeba4 0x69f6 +0xeba5 0x6a0f +0xeba6 0x6a15 +0xeba7 0x2373f +0xeba8 0x6a3b +0xeba9 0x6a3e +0xebaa 0x6a45 +0xebab 0x6a50 +0xebac 0x6a56 +0xebad 0x6a5b +0xebae 0x6a6b +0xebaf 0x6a73 +0xebb0 0x23763 +0xebb1 0x6a89 +0xebb2 0x6a94 +0xebb3 0x6a9d +0xebb4 0x6a9e +0xebb5 0x6aa5 +0xebb6 0x6ae4 +0xebb7 0x6ae7 +0xebb8 0x3c0f +0xebb9 0xf91d +0xebba 0x6b1b +0xebbb 0x6b1e +0xebbc 0x6b2c +0xebbd 0x6b35 +0xebbe 0x6b46 +0xebbf 0x6b56 +0xebc0 0x6b60 +0xebc1 0x6b65 +0xebc2 0x6b67 +0xebc3 0x6b77 +0xebc4 0x6b82 +0xebc5 0x6ba9 +0xebc6 0x6bad +0xebc7 0xf970 +0xebc8 0x6bcf +0xebc9 0x6bd6 +0xebca 0x6bd7 +0xebcb 0x6bff +0xebcc 0x6c05 +0xebcd 0x6c10 +0xebce 0x6c33 +0xebcf 0x6c59 +0xebd0 0x6c5c +0xebd1 0x6caa +0xebd2 0x6c74 +0xebd3 0x6c76 +0xebd4 0x6c85 +0xebd5 0x6c86 +0xebd6 0x6c98 +0xebd7 0x6c9c +0xebd8 0x6cfb +0xebd9 0x6cc6 +0xebda 0x6cd4 +0xebdb 0x6ce0 +0xebdc 0x6ceb +0xebdd 0x6cee +0xebde 0x23cfe +0xebdf 0x6d04 +0xebe0 0x6d0e +0xebe1 0x6d2e +0xebe2 0x6d31 +0xebe3 0x6d39 +0xebe4 0x6d3f +0xebe5 0x6d58 +0xebe6 0x6d65 +0xebe7 0xfa45 +0xebe8 0x6d82 +0xebe9 0x6d87 +0xebea 0x6d89 +0xebeb 0x6d94 +0xebec 0x6daa +0xebed 0x6dac +0xebee 0x6dbf +0xebef 0x6dc4 +0xebf0 0x6dd6 +0xebf1 0x6dda +0xebf2 0x6ddb +0xebf3 0x6ddd +0xebf4 0x6dfc +0xebf5 0xfa46 +0xebf6 0x6e34 +0xebf7 0x6e44 +0xebf8 0x6e5c +0xebf9 0x6e5e +0xebfa 0x6eab +0xebfb 0x6eb1 +0xebfc 0x6ec1 +0xec40 0x6ec7 +0xec41 0x6ece +0xec42 0x6f10 +0xec43 0x6f1a +0xec44 0xfa47 +0xec45 0x6f2a +0xec46 0x6f2f +0xec47 0x6f33 +0xec48 0x6f51 +0xec49 0x6f59 +0xec4a 0x6f5e +0xec4b 0x6f61 +0xec4c 0x6f62 +0xec4d 0x6f7e +0xec4e 0x6f88 +0xec4f 0x6f8c +0xec50 0x6f8d +0xec51 0x6f94 +0xec52 0x6fa0 +0xec53 0x6fa7 +0xec54 0x6fb6 +0xec55 0x6fbc +0xec56 0x6fc7 +0xec57 0x6fca +0xec58 0x6ff9 +0xec59 0x6ff0 +0xec5a 0x6ff5 +0xec5b 0x7005 +0xec5c 0x7006 +0xec5d 0x7028 +0xec5e 0x704a +0xec5f 0x705d +0xec60 0x705e +0xec61 0x704e +0xec62 0x7064 +0xec63 0x7075 +0xec64 0x7085 +0xec65 0x70a4 +0xec66 0x70ab +0xec67 0x70b7 +0xec68 0x70d4 +0xec69 0x70d8 +0xec6a 0x70e4 +0xec6b 0x710f +0xec6c 0x712b +0xec6d 0x711e +0xec6e 0x7120 +0xec6f 0x712e +0xec70 0x7130 +0xec71 0x7146 +0xec72 0x7147 +0xec73 0x7151 +0xec74 0xfa48 +0xec75 0x7152 +0xec76 0x715c +0xec77 0x7160 +0xec78 0x7168 +0xec79 0xfa15 +0xec7a 0x7185 +0xec7b 0x7187 +0xec7c 0x7192 +0xec7d 0x71c1 +0xec7e 0x71ba +0xec80 0x71c4 +0xec81 0x71fe +0xec82 0x7200 +0xec83 0x7215 +0xec84 0x7255 +0xec85 0x7256 +0xec86 0x3e3f +0xec87 0x728d +0xec88 0x729b +0xec89 0x72be +0xec8a 0x72c0 +0xec8b 0x72fb +0xec8c 0x247f1 +0xec8d 0x7327 +0xec8e 0x7328 +0xec8f 0xfa16 +0xec90 0x7350 +0xec91 0x7366 +0xec92 0x737c +0xec93 0x7395 +0xec94 0x739f +0xec95 0x73a0 +0xec96 0x73a2 +0xec97 0x73a6 +0xec98 0x73ab +0xec99 0x73c9 +0xec9a 0x73cf +0xec9b 0x73d6 +0xec9c 0x73d9 +0xec9d 0x73e3 +0xec9e 0x73e9 +0xec9f 0x7407 +0xeca0 0x740a +0xeca1 0x741a +0xeca2 0x741b +0xeca3 0xfa4a +0xeca4 0x7426 +0xeca5 0x7428 +0xeca6 0x742a +0xeca7 0x742b +0xeca8 0x742c +0xeca9 0x742e +0xecaa 0x742f +0xecab 0x7430 +0xecac 0x7444 +0xecad 0x7446 +0xecae 0x7447 +0xecaf 0x744b +0xecb0 0x7457 +0xecb1 0x7462 +0xecb2 0x746b +0xecb3 0x746d +0xecb4 0x7486 +0xecb5 0x7487 +0xecb6 0x7489 +0xecb7 0x7498 +0xecb8 0x749c +0xecb9 0x749f +0xecba 0x74a3 +0xecbb 0x7490 +0xecbc 0x74a6 +0xecbd 0x74a8 +0xecbe 0x74a9 +0xecbf 0x74b5 +0xecc0 0x74bf +0xecc1 0x74c8 +0xecc2 0x74c9 +0xecc3 0x74da +0xecc4 0x74ff +0xecc5 0x7501 +0xecc6 0x7517 +0xecc7 0x752f +0xecc8 0x756f +0xecc9 0x7579 +0xecca 0x7592 +0xeccb 0x3f72 +0xeccc 0x75ce +0xeccd 0x75e4 +0xecce 0x7600 +0xeccf 0x7602 +0xecd0 0x7608 +0xecd1 0x7615 +0xecd2 0x7616 +0xecd3 0x7619 +0xecd4 0x761e +0xecd5 0x762d +0xecd6 0x7635 +0xecd7 0x7643 +0xecd8 0x764b +0xecd9 0x7664 +0xecda 0x7665 +0xecdb 0x766d +0xecdc 0x766f +0xecdd 0x7671 +0xecde 0x7681 +0xecdf 0x769b +0xece0 0x769d +0xece1 0x769e +0xece2 0x76a6 +0xece3 0x76aa +0xece4 0x76b6 +0xece5 0x76c5 +0xece6 0x76cc +0xece7 0x76ce +0xece8 0x76d4 +0xece9 0x76e6 +0xecea 0x76f1 +0xeceb 0x76fc +0xecec 0x770a +0xeced 0x7719 +0xecee 0x7734 +0xecef 0x7736 +0xecf0 0x7746 +0xecf1 0x774d +0xecf2 0x774e +0xecf3 0x775c +0xecf4 0x775f +0xecf5 0x7762 +0xecf6 0x777a +0xecf7 0x7780 +0xecf8 0x7794 +0xecf9 0x77aa +0xecfa 0x77e0 +0xecfb 0x782d +0xecfc 0x2548e +0xed40 0x7843 +0xed41 0x784e +0xed42 0x784f +0xed43 0x7851 +0xed44 0x7868 +0xed45 0x786e +0xed46 0xfa4b +0xed47 0x78b0 +0xed48 0x2550e +0xed49 0x78ad +0xed4a 0x78e4 +0xed4b 0x78f2 +0xed4c 0x7900 +0xed4d 0x78f7 +0xed4e 0x791c +0xed4f 0x792e +0xed50 0x7931 +0xed51 0x7934 +0xed52 0xfa4c +0xed53 0xfa4d +0xed54 0x7945 +0xed55 0x7946 +0xed56 0xfa4e +0xed57 0xfa4f +0xed58 0xfa50 +0xed59 0x795c +0xed5a 0xfa51 +0xed5b 0xfa19 +0xed5c 0xfa1a +0xed5d 0x7979 +0xed5e 0xfa52 +0xed5f 0xfa53 +0xed60 0xfa1b +0xed61 0x7998 +0xed62 0x79b1 +0xed63 0x79b8 +0xed64 0x79c8 +0xed65 0x79ca +0xed66 0x25771 +0xed67 0x79d4 +0xed68 0x79de +0xed69 0x79eb +0xed6a 0x79ed +0xed6b 0x7a03 +0xed6c 0xfa54 +0xed6d 0x7a39 +0xed6e 0x7a5d +0xed6f 0x7a6d +0xed70 0xfa55 +0xed71 0x7a85 +0xed72 0x7aa0 +0xed73 0x259c4 +0xed74 0x7ab3 +0xed75 0x7abb +0xed76 0x7ace +0xed77 0x7aeb +0xed78 0x7afd +0xed79 0x7b12 +0xed7a 0x7b2d +0xed7b 0x7b3b +0xed7c 0x7b47 +0xed7d 0x7b4e +0xed7e 0x7b60 +0xed80 0x7b6d +0xed81 0x7b6f +0xed82 0x7b72 +0xed83 0x7b9e +0xed84 0xfa56 +0xed85 0x7bd7 +0xed86 0x7bd9 +0xed87 0x7c01 +0xed88 0x7c31 +0xed89 0x7c1e +0xed8a 0x7c20 +0xed8b 0x7c33 +0xed8c 0x7c36 +0xed8d 0x4264 +0xed8e 0x25da1 +0xed8f 0x7c59 +0xed90 0x7c6d +0xed91 0x7c79 +0xed92 0x7c8f +0xed93 0x7c94 +0xed94 0x7ca0 +0xed95 0x7cbc +0xed96 0x7cd5 +0xed97 0x7cd9 +0xed98 0x7cdd +0xed99 0x7d07 +0xed9a 0x7d08 +0xed9b 0x7d13 +0xed9c 0x7d1d +0xed9d 0x7d23 +0xed9e 0x7d31 +0xed9f 0x7d41 +0xeda0 0x7d48 +0xeda1 0x7d53 +0xeda2 0x7d5c +0xeda3 0x7d7a +0xeda4 0x7d83 +0xeda5 0x7d8b +0xeda6 0x7da0 +0xeda7 0x7da6 +0xeda8 0x7dc2 +0xeda9 0x7dcc +0xedaa 0x7dd6 +0xedab 0x7de3 +0xedac 0xfa57 +0xedad 0x7e28 +0xedae 0x7e08 +0xedaf 0x7e11 +0xedb0 0x7e15 +0xedb1 0xfa59 +0xedb2 0x7e47 +0xedb3 0x7e52 +0xedb4 0x7e61 +0xedb5 0x7e8a +0xedb6 0x7e8d +0xedb7 0x7f47 +0xedb8 0xfa5a +0xedb9 0x7f91 +0xedba 0x7f97 +0xedbb 0x7fbf +0xedbc 0x7fce +0xedbd 0x7fdb +0xedbe 0x7fdf +0xedbf 0x7fec +0xedc0 0x7fee +0xedc1 0x7ffa +0xedc2 0xfa5b +0xedc3 0x8014 +0xedc4 0x8026 +0xedc5 0x8035 +0xedc6 0x8037 +0xedc7 0x803c +0xedc8 0x80ca +0xedc9 0x80d7 +0xedca 0x80e0 +0xedcb 0x80f3 +0xedcc 0x8118 +0xedcd 0x814a +0xedce 0x8160 +0xedcf 0x8167 +0xedd0 0x8168 +0xedd1 0x816d +0xedd2 0x81bb +0xedd3 0x81ca +0xedd4 0x81cf +0xedd5 0x81d7 +0xedd6 0xfa5c +0xedd7 0x4453 +0xedd8 0x445b +0xedd9 0x8260 +0xedda 0x8274 +0xeddb 0x26aff +0xeddc 0x828e +0xeddd 0x82a1 +0xedde 0x82a3 +0xeddf 0x82a4 +0xede0 0x82a9 +0xede1 0x82ae +0xede2 0x82b7 +0xede3 0x82be +0xede4 0x82bf +0xede5 0x82c6 +0xede6 0x82d5 +0xede7 0x82fd +0xede8 0x82fe +0xede9 0x8300 +0xedea 0x8301 +0xedeb 0x8362 +0xedec 0x8322 +0xeded 0x832d +0xedee 0x833a +0xedef 0x8343 +0xedf0 0x8347 +0xedf1 0x8351 +0xedf2 0x8355 +0xedf3 0x837d +0xedf4 0x8386 +0xedf5 0x8392 +0xedf6 0x8398 +0xedf7 0x83a7 +0xedf8 0x83a9 +0xedf9 0x83bf +0xedfa 0x83c0 +0xedfb 0x83c7 +0xedfc 0x83cf +0xee40 0x83d1 +0xee41 0x83e1 +0xee42 0x83ea +0xee43 0x8401 +0xee44 0x8406 +0xee45 0x840a +0xee46 0xfa5f +0xee47 0x8448 +0xee48 0x845f +0xee49 0x8470 +0xee4a 0x8473 +0xee4b 0x8485 +0xee4c 0x849e +0xee4d 0x84af +0xee4e 0x84b4 +0xee4f 0x84ba +0xee50 0x84c0 +0xee51 0x84c2 +0xee52 0x26e40 +0xee53 0x8532 +0xee54 0x851e +0xee55 0x8523 +0xee56 0x852f +0xee57 0x8559 +0xee58 0x8564 +0xee59 0xfa1f +0xee5a 0x85ad +0xee5b 0x857a +0xee5c 0x858c +0xee5d 0x858f +0xee5e 0x85a2 +0xee5f 0x85b0 +0xee60 0x85cb +0xee61 0x85ce +0xee62 0x85ed +0xee63 0x8612 +0xee64 0x85ff +0xee65 0x8604 +0xee66 0x8605 +0xee67 0x8610 +0xee68 0x270f4 +0xee69 0x8618 +0xee6a 0x8629 +0xee6b 0x8638 +0xee6c 0x8657 +0xee6d 0x865b +0xee6e 0xf936 +0xee6f 0x8662 +0xee70 0x459d +0xee71 0x866c +0xee72 0x8675 +0xee73 0x8698 +0xee74 0x86b8 +0xee75 0x86fa +0xee76 0x86fc +0xee77 0x86fd +0xee78 0x870b +0xee79 0x8771 +0xee7a 0x8787 +0xee7b 0x8788 +0xee7c 0x87ac +0xee7d 0x87ad +0xee7e 0x87b5 +0xee80 0x45ea +0xee81 0x87d6 +0xee82 0x87ec +0xee83 0x8806 +0xee84 0x880a +0xee85 0x8810 +0xee86 0x8814 +0xee87 0x881f +0xee88 0x8898 +0xee89 0x88aa +0xee8a 0x88ca +0xee8b 0x88ce +0xee8c 0x27684 +0xee8d 0x88f5 +0xee8e 0x891c +0xee8f 0xfa60 +0xee90 0x8918 +0xee91 0x8919 +0xee92 0x891a +0xee93 0x8927 +0xee94 0x8930 +0xee95 0x8932 +0xee96 0x8939 +0xee97 0x8940 +0xee98 0x8994 +0xee99 0xfa61 +0xee9a 0x89d4 +0xee9b 0x89e5 +0xee9c 0x89f6 +0xee9d 0x8a12 +0xee9e 0x8a15 +0xee9f 0x8a22 +0xeea0 0x8a37 +0xeea1 0x8a47 +0xeea2 0x8a4e +0xeea3 0x8a5d +0xeea4 0x8a61 +0xeea5 0x8a75 +0xeea6 0x8a79 +0xeea7 0x8aa7 +0xeea8 0x8ad0 +0xeea9 0x8adf +0xeeaa 0x8af4 +0xeeab 0x8af6 +0xeeac 0xfa22 +0xeead 0xfa62 +0xeeae 0xfa63 +0xeeaf 0x8b46 +0xeeb0 0x8b54 +0xeeb1 0x8b59 +0xeeb2 0x8b69 +0xeeb3 0x8b9d +0xeeb4 0x8c49 +0xeeb5 0x8c68 +0xeeb6 0xfa64 +0xeeb7 0x8ce1 +0xeeb8 0x8cf4 +0xeeb9 0x8cf8 +0xeeba 0x8cfe +0xeebb 0xfa65 +0xeebc 0x8d12 +0xeebd 0x8d1b +0xeebe 0x8daf +0xeebf 0x8dce +0xeec0 0x8dd1 +0xeec1 0x8dd7 +0xeec2 0x8e20 +0xeec3 0x8e23 +0xeec4 0x8e3d +0xeec5 0x8e70 +0xeec6 0x8e7b +0xeec7 0x28277 +0xeec8 0x8ec0 +0xeec9 0x4844 +0xeeca 0x8efa +0xeecb 0x8f1e +0xeecc 0x8f2d +0xeecd 0x8f36 +0xeece 0x8f54 +0xeecf 0x283cd +0xeed0 0x8fa6 +0xeed1 0x8fb5 +0xeed2 0x8fe4 +0xeed3 0x8fe8 +0xeed4 0x8fee +0xeed5 0x9008 +0xeed6 0x902d +0xeed7 0xfa67 +0xeed8 0x9088 +0xeed9 0x9095 +0xeeda 0x9097 +0xeedb 0x9099 +0xeedc 0x909b +0xeedd 0x90a2 +0xeede 0x90b3 +0xeedf 0x90be +0xeee0 0x90c4 +0xeee1 0x90c5 +0xeee2 0x90c7 +0xeee3 0x90d7 +0xeee4 0x90dd +0xeee5 0x90de +0xeee6 0x90ef +0xeee7 0x90f4 +0xeee8 0xfa26 +0xeee9 0x9114 +0xeeea 0x9115 +0xeeeb 0x9116 +0xeeec 0x9122 +0xeeed 0x9123 +0xeeee 0x9127 +0xeeef 0x912f +0xeef0 0x9131 +0xeef1 0x9134 +0xeef2 0x913d +0xeef3 0x9148 +0xeef4 0x915b +0xeef5 0x9183 +0xeef6 0x919e +0xeef7 0x91ac +0xeef8 0x91b1 +0xeef9 0x91bc +0xeefa 0x91d7 +0xeefb 0x91fb +0xeefc 0x91e4 +0xef40 0x91e5 +0xef41 0x91ed +0xef42 0x91f1 +0xef43 0x9207 +0xef44 0x9210 +0xef45 0x9238 +0xef46 0x9239 +0xef47 0x923a +0xef48 0x923c +0xef49 0x9240 +0xef4a 0x9243 +0xef4b 0x924f +0xef4c 0x9278 +0xef4d 0x9288 +0xef4e 0x92c2 +0xef4f 0x92cb +0xef50 0x92cc +0xef51 0x92d3 +0xef52 0x92e0 +0xef53 0x92ff +0xef54 0x9304 +0xef55 0x931f +0xef56 0x9321 +0xef57 0x9325 +0xef58 0x9348 +0xef59 0x9349 +0xef5a 0x934a +0xef5b 0x9364 +0xef5c 0x9365 +0xef5d 0x936a +0xef5e 0x9370 +0xef5f 0x939b +0xef60 0x93a3 +0xef61 0x93ba +0xef62 0x93c6 +0xef63 0x93de +0xef64 0x93df +0xef65 0x9404 +0xef66 0x93fd +0xef67 0x9433 +0xef68 0x944a +0xef69 0x9463 +0xef6a 0x946b +0xef6b 0x9471 +0xef6c 0x9472 +0xef6d 0x958e +0xef6e 0x959f +0xef6f 0x95a6 +0xef70 0x95a9 +0xef71 0x95ac +0xef72 0x95b6 +0xef73 0x95bd +0xef74 0x95cb +0xef75 0x95d0 +0xef76 0x95d3 +0xef77 0x49b0 +0xef78 0x95da +0xef79 0x95de +0xef7a 0x9658 +0xef7b 0x9684 +0xef7c 0xf9dc +0xef7d 0x969d +0xef7e 0x96a4 +0xef80 0x96a5 +0xef81 0x96d2 +0xef82 0x96de +0xef83 0xfa68 +0xef84 0x96e9 +0xef85 0x96ef +0xef86 0x9733 +0xef87 0x973b +0xef88 0x974d +0xef89 0x974e +0xef8a 0x974f +0xef8b 0x975a +0xef8c 0x976e +0xef8d 0x9773 +0xef8e 0x9795 +0xef8f 0x97ae +0xef90 0x97ba +0xef91 0x97c1 +0xef92 0x97c9 +0xef93 0x97de +0xef94 0x97db +0xef95 0x97f4 +0xef96 0xfa69 +0xef97 0x980a +0xef98 0x981e +0xef99 0x982b +0xef9a 0x9830 +0xef9b 0xfa6a +0xef9c 0x9852 +0xef9d 0x9853 +0xef9e 0x9856 +0xef9f 0x9857 +0xefa0 0x9859 +0xefa1 0x985a +0xefa2 0xf9d0 +0xefa3 0x9865 +0xefa4 0x986c +0xefa5 0x98ba +0xefa6 0x98c8 +0xefa7 0x98e7 +0xefa8 0x9958 +0xefa9 0x999e +0xefaa 0x9a02 +0xefab 0x9a03 +0xefac 0x9a24 +0xefad 0x9a2d +0xefae 0x9a2e +0xefaf 0x9a38 +0xefb0 0x9a4a +0xefb1 0x9a4e +0xefb2 0x9a52 +0xefb3 0x9ab6 +0xefb4 0x9ac1 +0xefb5 0x9ac3 +0xefb6 0x9ace +0xefb7 0x9ad6 +0xefb8 0x9af9 +0xefb9 0x9b02 +0xefba 0x9b08 +0xefbb 0x9b20 +0xefbc 0x4c17 +0xefbd 0x9b2d +0xefbe 0x9b5e +0xefbf 0x9b79 +0xefc0 0x9b66 +0xefc1 0x9b72 +0xefc2 0x9b75 +0xefc3 0x9b84 +0xefc4 0x9b8a +0xefc5 0x9b8f +0xefc6 0x9b9e +0xefc7 0x9ba7 +0xefc8 0x9bc1 +0xefc9 0x9bce +0xefca 0x9be5 +0xefcb 0x9bf8 +0xefcc 0x9bfd +0xefcd 0x9c00 +0xefce 0x9c23 +0xefcf 0x9c41 +0xefd0 0x9c4f +0xefd1 0x9c50 +0xefd2 0x9c53 +0xefd3 0x9c63 +0xefd4 0x9c65 +0xefd5 0x9c77 +0xefd6 0x9d1d +0xefd7 0x9d1e +0xefd8 0x9d43 +0xefd9 0x9d47 +0xefda 0x9d52 +0xefdb 0x9d63 +0xefdc 0x9d70 +0xefdd 0x9d7c +0xefde 0x9d8a +0xefdf 0x9d96 +0xefe0 0x9dc0 +0xefe1 0x9dac +0xefe2 0x9dbc +0xefe3 0x9dd7 +0xefe4 0x2a190 +0xefe5 0x9de7 +0xefe6 0x9e07 +0xefe7 0x9e15 +0xefe8 0x9e7c +0xefe9 0x9e9e +0xefea 0x9ea4 +0xefeb 0x9eac +0xefec 0x9eaf +0xefed 0x9eb4 +0xefee 0x9eb5 +0xefef 0x9ec3 +0xeff0 0x9ed1 +0xeff1 0x9f10 +0xeff2 0x9f39 +0xeff3 0x9f57 +0xeff4 0x9f90 +0xeff5 0x9f94 +0xeff6 0x9f97 +0xeff7 0x9fa2 +0xeff8 0x59f8 +0xeff9 0x5c5b +0xeffa 0x5e77 +0xeffb 0x7626 +0xeffc 0x7e6b +0xf040 0x20089 +0xf041 0x4e02 +0xf042 0x4e0f +0xf043 0x4e12 +0xf044 0x4e29 +0xf045 0x4e2b +0xf046 0x4e2e +0xf047 0x4e40 +0xf048 0x4e47 +0xf049 0x4e48 +0xf04a 0x200a2 +0xf04b 0x4e51 +0xf04c 0x3406 +0xf04d 0x200a4 +0xf04e 0x4e5a +0xf04f 0x4e69 +0xf050 0x4e9d +0xf051 0x342c +0xf052 0x342e +0xf053 0x4eb9 +0xf054 0x4ebb +0xf055 0x201a2 +0xf056 0x4ebc +0xf057 0x4ec3 +0xf058 0x4ec8 +0xf059 0x4ed0 +0xf05a 0x4eeb +0xf05b 0x4eda +0xf05c 0x4ef1 +0xf05d 0x4ef5 +0xf05e 0x4f00 +0xf05f 0x4f16 +0xf060 0x4f64 +0xf061 0x4f37 +0xf062 0x4f3e +0xf063 0x4f54 +0xf064 0x4f58 +0xf065 0x20213 +0xf066 0x4f77 +0xf067 0x4f78 +0xf068 0x4f7a +0xf069 0x4f7d +0xf06a 0x4f82 +0xf06b 0x4f85 +0xf06c 0x4f92 +0xf06d 0x4f9a +0xf06e 0x4fe6 +0xf06f 0x4fb2 +0xf070 0x4fbe +0xf071 0x4fc5 +0xf072 0x4fcb +0xf073 0x4fcf +0xf074 0x4fd2 +0xf075 0x346a +0xf076 0x4ff2 +0xf077 0x5000 +0xf078 0x5010 +0xf079 0x5013 +0xf07a 0x501c +0xf07b 0x501e +0xf07c 0x5022 +0xf07d 0x3468 +0xf07e 0x5042 +0xf080 0x5046 +0xf081 0x504e +0xf082 0x5053 +0xf083 0x5057 +0xf084 0x5063 +0xf085 0x5066 +0xf086 0x506a +0xf087 0x5070 +0xf088 0x50a3 +0xf089 0x5088 +0xf08a 0x5092 +0xf08b 0x5093 +0xf08c 0x5095 +0xf08d 0x5096 +0xf08e 0x509c +0xf08f 0x50aa +0xf090 0x2032b +0xf091 0x50b1 +0xf092 0x50ba +0xf093 0x50bb +0xf094 0x50c4 +0xf095 0x50c7 +0xf096 0x50f3 +0xf097 0x20381 +0xf098 0x50ce +0xf099 0x20371 +0xf09a 0x50d4 +0xf09b 0x50d9 +0xf09c 0x50e1 +0xf09d 0x50e9 +0xf09e 0x3492 +0xf140 0x5108 +0xf141 0x203f9 +0xf142 0x5117 +0xf143 0x511b +0xf144 0x2044a +0xf145 0x5160 +0xf146 0x20509 +0xf147 0x5173 +0xf148 0x5183 +0xf149 0x518b +0xf14a 0x34bc +0xf14b 0x5198 +0xf14c 0x51a3 +0xf14d 0x51ad +0xf14e 0x34c7 +0xf14f 0x51bc +0xf150 0x205d6 +0xf151 0x20628 +0xf152 0x51f3 +0xf153 0x51f4 +0xf154 0x5202 +0xf155 0x5212 +0xf156 0x5216 +0xf157 0x2074f +0xf158 0x5255 +0xf159 0x525c +0xf15a 0x526c +0xf15b 0x5277 +0xf15c 0x5284 +0xf15d 0x5282 +0xf15e 0x20807 +0xf15f 0x5298 +0xf160 0x2083a +0xf161 0x52a4 +0xf162 0x52a6 +0xf163 0x52af +0xf164 0x52ba +0xf165 0x52bb +0xf166 0x52ca +0xf167 0x351f +0xf168 0x52d1 +0xf169 0x208b9 +0xf16a 0x52f7 +0xf16b 0x530a +0xf16c 0x530b +0xf16d 0x5324 +0xf16e 0x5335 +0xf16f 0x533e +0xf170 0x5342 +0xf171 0x2097c +0xf172 0x2099d +0xf173 0x5367 +0xf174 0x536c +0xf175 0x537a +0xf176 0x53a4 +0xf177 0x53b4 +0xf178 0x20ad3 +0xf179 0x53b7 +0xf17a 0x53c0 +0xf17b 0x20b1d +0xf17c 0x355d +0xf17d 0x355e +0xf17e 0x53d5 +0xf180 0x53da +0xf181 0x3563 +0xf182 0x53f4 +0xf183 0x53f5 +0xf184 0x5455 +0xf185 0x5424 +0xf186 0x5428 +0xf187 0x356e +0xf188 0x5443 +0xf189 0x5462 +0xf18a 0x5466 +0xf18b 0x546c +0xf18c 0x548a +0xf18d 0x548d +0xf18e 0x5495 +0xf18f 0x54a0 +0xf190 0x54a6 +0xf191 0x54ad +0xf192 0x54ae +0xf193 0x54b7 +0xf194 0x54ba +0xf195 0x54bf +0xf196 0x54c3 +0xf197 0x20d45 +0xf198 0x54ec +0xf199 0x54ef +0xf19a 0x54f1 +0xf19b 0x54f3 +0xf19c 0x5500 +0xf19d 0x5501 +0xf19e 0x5509 +0xf19f 0x553c +0xf1a0 0x5541 +0xf1a1 0x35a6 +0xf1a2 0x5547 +0xf1a3 0x554a +0xf1a4 0x35a8 +0xf1a5 0x5560 +0xf1a6 0x5561 +0xf1a7 0x5564 +0xf1a8 0x20de1 +0xf1a9 0x557d +0xf1aa 0x5582 +0xf1ab 0x5588 +0xf1ac 0x5591 +0xf1ad 0x35c5 +0xf1ae 0x55d2 +0xf1af 0x20e95 +0xf1b0 0x20e6d +0xf1b1 0x55bf +0xf1b2 0x55c9 +0xf1b3 0x55cc +0xf1b4 0x55d1 +0xf1b5 0x55dd +0xf1b6 0x35da +0xf1b7 0x55e2 +0xf1b8 0x20e64 +0xf1b9 0x55e9 +0xf1ba 0x5628 +0xf1bb 0x20f5f +0xf1bc 0x5607 +0xf1bd 0x5610 +0xf1be 0x5630 +0xf1bf 0x5637 +0xf1c0 0x35f4 +0xf1c1 0x563d +0xf1c2 0x563f +0xf1c3 0x5640 +0xf1c4 0x5647 +0xf1c5 0x565e +0xf1c6 0x5660 +0xf1c7 0x566d +0xf1c8 0x3605 +0xf1c9 0x5688 +0xf1ca 0x568c +0xf1cb 0x5695 +0xf1cc 0x569a +0xf1cd 0x569d +0xf1ce 0x56a8 +0xf1cf 0x56ad +0xf1d0 0x56b2 +0xf1d1 0x56c5 +0xf1d2 0x56cd +0xf1d3 0x56df +0xf1d4 0x56e8 +0xf1d5 0x56f6 +0xf1d6 0x56f7 +0xf1d7 0x21201 +0xf1d8 0x5715 +0xf1d9 0x5723 +0xf1da 0x21255 +0xf1db 0x5729 +0xf1dc 0x2127b +0xf1dd 0x5745 +0xf1de 0x5746 +0xf1df 0x574c +0xf1e0 0x574d +0xf1e1 0x21274 +0xf1e2 0x5768 +0xf1e3 0x576f +0xf1e4 0x5773 +0xf1e5 0x5774 +0xf1e6 0x5775 +0xf1e7 0x577b +0xf1e8 0x212e4 +0xf1e9 0x212d7 +0xf1ea 0x57ac +0xf1eb 0x579a +0xf1ec 0x579d +0xf1ed 0x579e +0xf1ee 0x57a8 +0xf1ef 0x57d7 +0xf1f0 0x212fd +0xf1f1 0x57cc +0xf1f2 0x21336 +0xf1f3 0x21344 +0xf1f4 0x57de +0xf1f5 0x57e6 +0xf1f6 0x57f0 +0xf1f7 0x364a +0xf1f8 0x57f8 +0xf1f9 0x57fb +0xf1fa 0x57fd +0xf1fb 0x5804 +0xf1fc 0x581e +0xf240 0x5820 +0xf241 0x5827 +0xf242 0x5832 +0xf243 0x5839 +0xf244 0x213c4 +0xf245 0x5849 +0xf246 0x584c +0xf247 0x5867 +0xf248 0x588a +0xf249 0x588b +0xf24a 0x588d +0xf24b 0x588f +0xf24c 0x5890 +0xf24d 0x5894 +0xf24e 0x589d +0xf24f 0x58aa +0xf250 0x58b1 +0xf251 0x2146d +0xf252 0x58c3 +0xf253 0x58cd +0xf254 0x58e2 +0xf255 0x58f3 +0xf256 0x58f4 +0xf257 0x5905 +0xf258 0x5906 +0xf259 0x590b +0xf25a 0x590d +0xf25b 0x5914 +0xf25c 0x5924 +0xf25d 0x215d7 +0xf25e 0x3691 +0xf25f 0x593d +0xf260 0x3699 +0xf261 0x5946 +0xf262 0x3696 +0xf263 0x26c29 +0xf264 0x595b +0xf265 0x595f +0xf266 0x21647 +0xf267 0x5975 +0xf268 0x5976 +0xf269 0x597c +0xf26a 0x599f +0xf26b 0x59ae +0xf26c 0x59bc +0xf26d 0x59c8 +0xf26e 0x59cd +0xf26f 0x59de +0xf270 0x59e3 +0xf271 0x59e4 +0xf272 0x59e7 +0xf273 0x59ee +0xf274 0x21706 +0xf275 0x21742 +0xf276 0x36cf +0xf277 0x5a0c +0xf278 0x5a0d +0xf279 0x5a17 +0xf27a 0x5a27 +0xf27b 0x5a2d +0xf27c 0x5a55 +0xf27d 0x5a65 +0xf27e 0x5a7a +0xf280 0x5a8b +0xf281 0x5a9c +0xf282 0x5a9f +0xf283 0x5aa0 +0xf284 0x5aa2 +0xf285 0x5ab1 +0xf286 0x5ab3 +0xf287 0x5ab5 +0xf288 0x5aba +0xf289 0x5abf +0xf28a 0x5ada +0xf28b 0x5adc +0xf28c 0x5ae0 +0xf28d 0x5ae5 +0xf28e 0x5af0 +0xf28f 0x5aee +0xf290 0x5af5 +0xf291 0x5b00 +0xf292 0x5b08 +0xf293 0x5b17 +0xf294 0x5b34 +0xf295 0x5b2d +0xf296 0x5b4c +0xf297 0x5b52 +0xf298 0x5b68 +0xf299 0x5b6f +0xf29a 0x5b7c +0xf29b 0x5b7f +0xf29c 0x5b81 +0xf29d 0x5b84 +0xf29e 0x219c3 +0xf09f 0x5b96 +0xf0a0 0x5bac +0xf0a1 0x3761 +0xf0a2 0x5bc0 +0xf0a3 0x3762 +0xf0a4 0x5bce +0xf0a5 0x5bd6 +0xf0a6 0x376c +0xf0a7 0x376b +0xf0a8 0x5bf1 +0xf0a9 0x5bfd +0xf0aa 0x3775 +0xf0ab 0x5c03 +0xf0ac 0x5c29 +0xf0ad 0x5c30 +0xf0ae 0x21c56 +0xf0af 0x5c5f +0xf0b0 0x5c63 +0xf0b1 0x5c67 +0xf0b2 0x5c68 +0xf0b3 0x5c69 +0xf0b4 0x5c70 +0xf0b5 0x21d2d +0xf0b6 0x21d45 +0xf0b7 0x5c7c +0xf0b8 0x21d78 +0xf0b9 0x21d62 +0xf0ba 0x5c88 +0xf0bb 0x5c8a +0xf0bc 0x37c1 +0xf0bd 0x21da1 +0xf0be 0x21d9c +0xf0bf 0x5ca0 +0xf0c0 0x5ca2 +0xf0c1 0x5ca6 +0xf0c2 0x5ca7 +0xf0c3 0x21d92 +0xf0c4 0x5cad +0xf0c5 0x5cb5 +0xf0c6 0x21db7 +0xf0c7 0x5cc9 +0xf0c8 0x21de0 +0xf0c9 0x21e33 +0xf0ca 0x5d06 +0xf0cb 0x5d10 +0xf0cc 0x5d2b +0xf0cd 0x5d1d +0xf0ce 0x5d20 +0xf0cf 0x5d24 +0xf0d0 0x5d26 +0xf0d1 0x5d31 +0xf0d2 0x5d39 +0xf0d3 0x5d42 +0xf0d4 0x37e8 +0xf0d5 0x5d61 +0xf0d6 0x5d6a +0xf0d7 0x37f4 +0xf0d8 0x5d70 +0xf0d9 0x21f1e +0xf0da 0x37fd +0xf0db 0x5d88 +0xf0dc 0x3800 +0xf0dd 0x5d92 +0xf0de 0x5d94 +0xf0df 0x5d97 +0xf0e0 0x5d99 +0xf0e1 0x5db0 +0xf0e2 0x5db2 +0xf0e3 0x5db4 +0xf0e4 0x21f76 +0xf0e5 0x5db9 +0xf0e6 0x5dd1 +0xf0e7 0x5dd7 +0xf0e8 0x5dd8 +0xf0e9 0x5de0 +0xf0ea 0x21ffa +0xf0eb 0x5de4 +0xf0ec 0x5de9 +0xf0ed 0x382f +0xf0ee 0x5e00 +0xf0ef 0x3836 +0xf0f0 0x5e12 +0xf0f1 0x5e15 +0xf0f2 0x3840 +0xf0f3 0x5e1f +0xf0f4 0x5e2e +0xf0f5 0x5e3e +0xf0f6 0x5e49 +0xf0f7 0x385c +0xf0f8 0x5e56 +0xf0f9 0x3861 +0xf0fa 0x5e6b +0xf0fb 0x5e6c +0xf0fc 0x5e6d +0xf29f 0x5e6e +0xf2a0 0x2217b +0xf2a1 0x5ea5 +0xf2a2 0x5eaa +0xf2a3 0x5eac +0xf2a4 0x5eb9 +0xf2a5 0x5ebf +0xf2a6 0x5ec6 +0xf2a7 0x5ed2 +0xf2a8 0x5ed9 +0xf2a9 0x2231e +0xf2aa 0x5efd +0xf2ab 0x5f08 +0xf2ac 0x5f0e +0xf2ad 0x5f1c +0xf2ae 0x223ad +0xf2af 0x5f1e +0xf2b0 0x5f47 +0xf2b1 0x5f63 +0xf2b2 0x5f72 +0xf2b3 0x5f7e +0xf2b4 0x5f8f +0xf2b5 0x5fa2 +0xf2b6 0x5fa4 +0xf2b7 0x5fb8 +0xf2b8 0x5fc4 +0xf2b9 0x38fa +0xf2ba 0x5fc7 +0xf2bb 0x5fcb +0xf2bc 0x5fd2 +0xf2bd 0x5fd3 +0xf2be 0x5fd4 +0xf2bf 0x5fe2 +0xf2c0 0x5fee +0xf2c1 0x5fef +0xf2c2 0x5ff3 +0xf2c3 0x5ffc +0xf2c4 0x3917 +0xf2c5 0x6017 +0xf2c6 0x6022 +0xf2c7 0x6024 +0xf2c8 0x391a +0xf2c9 0x604c +0xf2ca 0x607f +0xf2cb 0x608a +0xf2cc 0x6095 +0xf2cd 0x60a8 +0xf2ce 0x226f3 +0xf2cf 0x60b0 +0xf2d0 0x60b1 +0xf2d1 0x60be +0xf2d2 0x60c8 +0xf2d3 0x60d9 +0xf2d4 0x60db +0xf2d5 0x60ee +0xf2d6 0x60f2 +0xf2d7 0x60f5 +0xf2d8 0x6110 +0xf2d9 0x6112 +0xf2da 0x6113 +0xf2db 0x6119 +0xf2dc 0x611e +0xf2dd 0x613a +0xf2de 0x396f +0xf2df 0x6141 +0xf2e0 0x6146 +0xf2e1 0x6160 +0xf2e2 0x617c +0xf2e3 0x2285b +0xf2e4 0x6192 +0xf2e5 0x6193 +0xf2e6 0x6197 +0xf2e7 0x6198 +0xf2e8 0x61a5 +0xf2e9 0x61a8 +0xf2ea 0x61ad +0xf2eb 0x228ab +0xf2ec 0x61d5 +0xf2ed 0x61dd +0xf2ee 0x61df +0xf2ef 0x61f5 +0xf2f0 0x2298f +0xf2f1 0x6215 +0xf2f2 0x6223 +0xf2f3 0x6229 +0xf2f4 0x6246 +0xf2f5 0x624c +0xf2f6 0x6251 +0xf2f7 0x6252 +0xf2f8 0x6261 +0xf2f9 0x6264 +0xf2fa 0x627b +0xf2fb 0x626d +0xf2fc 0x6273 +0xf340 0x6299 +0xf341 0x62a6 +0xf342 0x62d5 +0xf343 0x22ab8 +0xf344 0x62fd +0xf345 0x6303 +0xf346 0x630d +0xf347 0x6310 +0xf348 0x22b4f +0xf349 0x22b50 +0xf34a 0x6332 +0xf34b 0x6335 +0xf34c 0x633b +0xf34d 0x633c +0xf34e 0x6341 +0xf34f 0x6344 +0xf350 0x634e +0xf351 0x22b46 +0xf352 0x6359 +0xf353 0x22c1d +0xf354 0x22ba6 +0xf355 0x636c +0xf356 0x6384 +0xf357 0x6399 +0xf358 0x22c24 +0xf359 0x6394 +0xf35a 0x63bd +0xf35b 0x63f7 +0xf35c 0x63d4 +0xf35d 0x63d5 +0xf35e 0x63dc +0xf35f 0x63e0 +0xf360 0x63eb +0xf361 0x63ec +0xf362 0x63f2 +0xf363 0x6409 +0xf364 0x641e +0xf365 0x6425 +0xf366 0x6429 +0xf367 0x642f +0xf368 0x645a +0xf369 0x645b +0xf36a 0x645d +0xf36b 0x6473 +0xf36c 0x647d +0xf36d 0x6487 +0xf36e 0x6491 +0xf36f 0x649d +0xf370 0x649f +0xf371 0x64cb +0xf372 0x64cc +0xf373 0x64d5 +0xf374 0x64d7 +0xf375 0x22de1 +0xf376 0x64e4 +0xf377 0x64e5 +0xf378 0x64ff +0xf379 0x6504 +0xf37a 0x3a6e +0xf37b 0x650f +0xf37c 0x6514 +0xf37d 0x6516 +0xf37e 0x3a73 +0xf380 0x651e +0xf381 0x6532 +0xf382 0x6544 +0xf383 0x6554 +0xf384 0x656b +0xf385 0x657a +0xf386 0x6581 +0xf387 0x6584 +0xf388 0x6585 +0xf389 0x658a +0xf38a 0x65b2 +0xf38b 0x65b5 +0xf38c 0x65b8 +0xf38d 0x65bf +0xf38e 0x65c2 +0xf38f 0x65c9 +0xf390 0x65d4 +0xf391 0x3ad6 +0xf392 0x65f2 +0xf393 0x65f9 +0xf394 0x65fc +0xf395 0x6604 +0xf396 0x6608 +0xf397 0x6621 +0xf398 0x662a +0xf399 0x6645 +0xf39a 0x6651 +0xf39b 0x664e +0xf39c 0x3aea +0xf39d 0x231c3 +0xf39e 0x6657 +0xf39f 0x665b +0xf3a0 0x6663 +0xf3a1 0x231f5 +0xf3a2 0x231b6 +0xf3a3 0x666a +0xf3a4 0x666b +0xf3a5 0x666c +0xf3a6 0x666d +0xf3a7 0x667b +0xf3a8 0x6680 +0xf3a9 0x6690 +0xf3aa 0x6692 +0xf3ab 0x6699 +0xf3ac 0x3b0e +0xf3ad 0x66ad +0xf3ae 0x66b1 +0xf3af 0x66b5 +0xf3b0 0x3b1a +0xf3b1 0x66bf +0xf3b2 0x3b1c +0xf3b3 0x66ec +0xf3b4 0x3ad7 +0xf3b5 0x6701 +0xf3b6 0x6705 +0xf3b7 0x6712 +0xf3b8 0x23372 +0xf3b9 0x6719 +0xf3ba 0x233d3 +0xf3bb 0x233d2 +0xf3bc 0x674c +0xf3bd 0x674d +0xf3be 0x6754 +0xf3bf 0x675d +0xf3c0 0x233d0 +0xf3c1 0x233e4 +0xf3c2 0x233d5 +0xf3c3 0x6774 +0xf3c4 0x6776 +0xf3c5 0x233da +0xf3c6 0x6792 +0xf3c7 0x233df +0xf3c8 0x8363 +0xf3c9 0x6810 +0xf3ca 0x67b0 +0xf3cb 0x67b2 +0xf3cc 0x67c3 +0xf3cd 0x67c8 +0xf3ce 0x67d2 +0xf3cf 0x67d9 +0xf3d0 0x67db +0xf3d1 0x67f0 +0xf3d2 0x67f7 +0xf3d3 0x2344a +0xf3d4 0x23451 +0xf3d5 0x2344b +0xf3d6 0x6818 +0xf3d7 0x681f +0xf3d8 0x682d +0xf3d9 0x23465 +0xf3da 0x6833 +0xf3db 0x683b +0xf3dc 0x683e +0xf3dd 0x6844 +0xf3de 0x6845 +0xf3df 0x6849 +0xf3e0 0x684c +0xf3e1 0x6855 +0xf3e2 0x6857 +0xf3e3 0x3b77 +0xf3e4 0x686b +0xf3e5 0x686e +0xf3e6 0x687a +0xf3e7 0x687c +0xf3e8 0x6882 +0xf3e9 0x6890 +0xf3ea 0x6896 +0xf3eb 0x3b6d +0xf3ec 0x6898 +0xf3ed 0x6899 +0xf3ee 0x689a +0xf3ef 0x689c +0xf3f0 0x68aa +0xf3f1 0x68ab +0xf3f2 0x68b4 +0xf3f3 0x68bb +0xf3f4 0x68fb +0xf3f5 0x234e4 +0xf3f6 0x2355a +0xf3f7 0xfa13 +0xf3f8 0x68c3 +0xf3f9 0x68c5 +0xf3fa 0x68cc +0xf3fb 0x68cf +0xf3fc 0x68d6 +0xf440 0x68d9 +0xf441 0x68e4 +0xf442 0x68e5 +0xf443 0x68ec +0xf444 0x68f7 +0xf445 0x6903 +0xf446 0x6907 +0xf447 0x3b87 +0xf448 0x3b88 +0xf449 0x23594 +0xf44a 0x693b +0xf44b 0x3b8d +0xf44c 0x6946 +0xf44d 0x6969 +0xf44e 0x696c +0xf44f 0x6972 +0xf450 0x697a +0xf451 0x697f +0xf452 0x6992 +0xf453 0x3ba4 +0xf454 0x6996 +0xf455 0x6998 +0xf456 0x69a6 +0xf457 0x69b0 +0xf458 0x69b7 +0xf459 0x69ba +0xf45a 0x69bc +0xf45b 0x69c0 +0xf45c 0x69d1 +0xf45d 0x69d6 +0xf45e 0x23639 +0xf45f 0x23647 +0xf460 0x6a30 +0xf461 0x23638 +0xf462 0x2363a +0xf463 0x69e3 +0xf464 0x69ee +0xf465 0x69ef +0xf466 0x69f3 +0xf467 0x3bcd +0xf468 0x69f4 +0xf469 0x69fe +0xf46a 0x6a11 +0xf46b 0x6a1a +0xf46c 0x6a1d +0xf46d 0x2371c +0xf46e 0x6a32 +0xf46f 0x6a33 +0xf470 0x6a34 +0xf471 0x6a3f +0xf472 0x6a46 +0xf473 0x6a49 +0xf474 0x6a7a +0xf475 0x6a4e +0xf476 0x6a52 +0xf477 0x6a64 +0xf478 0x2370c +0xf479 0x6a7e +0xf47a 0x6a83 +0xf47b 0x6a8b +0xf47c 0x3bf0 +0xf47d 0x6a91 +0xf47e 0x6a9f +0xf480 0x6aa1 +0xf481 0x23764 +0xf482 0x6aab +0xf483 0x6abd +0xf484 0x6ac6 +0xf485 0x6ad4 +0xf486 0x6ad0 +0xf487 0x6adc +0xf488 0x6add +0xf489 0x237ff +0xf48a 0x237e7 +0xf48b 0x6aec +0xf48c 0x6af1 +0xf48d 0x6af2 +0xf48e 0x6af3 +0xf48f 0x6afd +0xf490 0x23824 +0xf491 0x6b0b +0xf492 0x6b0f +0xf493 0x6b10 +0xf494 0x6b11 +0xf495 0x2383d +0xf496 0x6b17 +0xf497 0x3c26 +0xf498 0x6b2f +0xf499 0x6b4a +0xf49a 0x6b58 +0xf49b 0x6b6c +0xf49c 0x6b75 +0xf49d 0x6b7a +0xf49e 0x6b81 +0xf49f 0x6b9b +0xf4a0 0x6bae +0xf4a1 0x23a98 +0xf4a2 0x6bbd +0xf4a3 0x6bbe +0xf4a4 0x6bc7 +0xf4a5 0x6bc8 +0xf4a6 0x6bc9 +0xf4a7 0x6bda +0xf4a8 0x6be6 +0xf4a9 0x6be7 +0xf4aa 0x6bee +0xf4ab 0x6bf1 +0xf4ac 0x6c02 +0xf4ad 0x6c0a +0xf4ae 0x6c0e +0xf4af 0x6c35 +0xf4b0 0x6c36 +0xf4b1 0x6c3a +0xf4b2 0x23c7f +0xf4b3 0x6c3f +0xf4b4 0x6c4d +0xf4b5 0x6c5b +0xf4b6 0x6c6d +0xf4b7 0x6c84 +0xf4b8 0x6c89 +0xf4b9 0x3cc3 +0xf4ba 0x6c94 +0xf4bb 0x6c95 +0xf4bc 0x6c97 +0xf4bd 0x6cad +0xf4be 0x6cc2 +0xf4bf 0x6cd0 +0xf4c0 0x3cd2 +0xf4c1 0x6cd6 +0xf4c2 0x6cda +0xf4c3 0x6cdc +0xf4c4 0x6ce9 +0xf4c5 0x6cec +0xf4c6 0x6ced +0xf4c7 0x23d00 +0xf4c8 0x6d00 +0xf4c9 0x6d0a +0xf4ca 0x6d24 +0xf4cb 0x6d26 +0xf4cc 0x6d27 +0xf4cd 0x6c67 +0xf4ce 0x6d2f +0xf4cf 0x6d3c +0xf4d0 0x6d5b +0xf4d1 0x6d5e +0xf4d2 0x6d60 +0xf4d3 0x6d70 +0xf4d4 0x6d80 +0xf4d5 0x6d81 +0xf4d6 0x6d8a +0xf4d7 0x6d8d +0xf4d8 0x6d91 +0xf4d9 0x6d98 +0xf4da 0x23d40 +0xf4db 0x6e17 +0xf4dc 0x23dfa +0xf4dd 0x23df9 +0xf4de 0x23dd3 +0xf4df 0x6dab +0xf4e0 0x6dae +0xf4e1 0x6db4 +0xf4e2 0x6dc2 +0xf4e3 0x6d34 +0xf4e4 0x6dc8 +0xf4e5 0x6dce +0xf4e6 0x6dcf +0xf4e7 0x6dd0 +0xf4e8 0x6ddf +0xf4e9 0x6de9 +0xf4ea 0x6df6 +0xf4eb 0x6e36 +0xf4ec 0x6e1e +0xf4ed 0x6e22 +0xf4ee 0x6e27 +0xf4ef 0x3d11 +0xf4f0 0x6e32 +0xf4f1 0x6e3c +0xf4f2 0x6e48 +0xf4f3 0x6e49 +0xf4f4 0x6e4b +0xf4f5 0x6e4c +0xf4f6 0x6e4f +0xf4f7 0x6e51 +0xf4f8 0x6e53 +0xf4f9 0x6e54 +0xf4fa 0x6e57 +0xf4fb 0x6e63 +0xf4fc 0x3d1e +0xf540 0x6e93 +0xf541 0x6ea7 +0xf542 0x6eb4 +0xf543 0x6ebf +0xf544 0x6ec3 +0xf545 0x6eca +0xf546 0x6ed9 +0xf547 0x6f35 +0xf548 0x6eeb +0xf549 0x6ef9 +0xf54a 0x6efb +0xf54b 0x6f0a +0xf54c 0x6f0c +0xf54d 0x6f18 +0xf54e 0x6f25 +0xf54f 0x6f36 +0xf550 0x6f3c +0xf551 0x23f7e +0xf552 0x6f52 +0xf553 0x6f57 +0xf554 0x6f5a +0xf555 0x6f60 +0xf556 0x6f68 +0xf557 0x6f98 +0xf558 0x6f7d +0xf559 0x6f90 +0xf55a 0x6f96 +0xf55b 0x6fbe +0xf55c 0x6f9f +0xf55d 0x6fa5 +0xf55e 0x6faf +0xf55f 0x3d64 +0xf560 0x6fb5 +0xf561 0x6fc8 +0xf562 0x6fc9 +0xf563 0x6fda +0xf564 0x6fde +0xf565 0x6fe9 +0xf566 0x24096 +0xf567 0x6ffc +0xf568 0x7000 +0xf569 0x7007 +0xf56a 0x700a +0xf56b 0x7023 +0xf56c 0x24103 +0xf56d 0x7039 +0xf56e 0x703a +0xf56f 0x703c +0xf570 0x7043 +0xf571 0x7047 +0xf572 0x704b +0xf573 0x3d9a +0xf574 0x7054 +0xf575 0x7065 +0xf576 0x7069 +0xf577 0x706c +0xf578 0x706e +0xf579 0x7076 +0xf57a 0x707e +0xf57b 0x7081 +0xf57c 0x7086 +0xf57d 0x7095 +0xf57e 0x7097 +0xf580 0x70bb +0xf581 0x241c6 +0xf582 0x709f +0xf583 0x70b1 +0xf584 0x241fe +0xf585 0x70ec +0xf586 0x70ca +0xf587 0x70d1 +0xf588 0x70d3 +0xf589 0x70dc +0xf58a 0x7103 +0xf58b 0x7104 +0xf58c 0x7106 +0xf58d 0x7107 +0xf58e 0x7108 +0xf58f 0x710c +0xf590 0x3dc0 +0xf591 0x712f +0xf592 0x7131 +0xf593 0x7150 +0xf594 0x714a +0xf595 0x7153 +0xf596 0x715e +0xf597 0x3dd4 +0xf598 0x7196 +0xf599 0x7180 +0xf59a 0x719b +0xf59b 0x71a0 +0xf59c 0x71a2 +0xf59d 0x71ae +0xf59e 0x71af +0xf59f 0x71b3 +0xf5a0 0x243bc +0xf5a1 0x71cb +0xf5a2 0x71d3 +0xf5a3 0x71d9 +0xf5a4 0x71dc +0xf5a5 0x7207 +0xf5a6 0x3e05 +0xf5a7 0xfa49 +0xf5a8 0x722b +0xf5a9 0x7234 +0xf5aa 0x7238 +0xf5ab 0x7239 +0xf5ac 0x4e2c +0xf5ad 0x7242 +0xf5ae 0x7253 +0xf5af 0x7257 +0xf5b0 0x7263 +0xf5b1 0x24629 +0xf5b2 0x726e +0xf5b3 0x726f +0xf5b4 0x7278 +0xf5b5 0x727f +0xf5b6 0x728e +0xf5b7 0x246a5 +0xf5b8 0x72ad +0xf5b9 0x72ae +0xf5ba 0x72b0 +0xf5bb 0x72b1 +0xf5bc 0x72c1 +0xf5bd 0x3e60 +0xf5be 0x72cc +0xf5bf 0x3e66 +0xf5c0 0x3e68 +0xf5c1 0x72f3 +0xf5c2 0x72fa +0xf5c3 0x7307 +0xf5c4 0x7312 +0xf5c5 0x7318 +0xf5c6 0x7319 +0xf5c7 0x3e83 +0xf5c8 0x7339 +0xf5c9 0x732c +0xf5ca 0x7331 +0xf5cb 0x7333 +0xf5cc 0x733d +0xf5cd 0x7352 +0xf5ce 0x3e94 +0xf5cf 0x736b +0xf5d0 0x736c +0xf5d1 0x24896 +0xf5d2 0x736e +0xf5d3 0x736f +0xf5d4 0x7371 +0xf5d5 0x7377 +0xf5d6 0x7381 +0xf5d7 0x7385 +0xf5d8 0x738a +0xf5d9 0x7394 +0xf5da 0x7398 +0xf5db 0x739c +0xf5dc 0x739e +0xf5dd 0x73a5 +0xf5de 0x73a8 +0xf5df 0x73b5 +0xf5e0 0x73b7 +0xf5e1 0x73b9 +0xf5e2 0x73bc +0xf5e3 0x73bf +0xf5e4 0x73c5 +0xf5e5 0x73cb +0xf5e6 0x73e1 +0xf5e7 0x73e7 +0xf5e8 0x73f9 +0xf5e9 0x7413 +0xf5ea 0x73fa +0xf5eb 0x7401 +0xf5ec 0x7424 +0xf5ed 0x7431 +0xf5ee 0x7439 +0xf5ef 0x7453 +0xf5f0 0x7440 +0xf5f1 0x7443 +0xf5f2 0x744d +0xf5f3 0x7452 +0xf5f4 0x745d +0xf5f5 0x7471 +0xf5f6 0x7481 +0xf5f7 0x7485 +0xf5f8 0x7488 +0xf5f9 0x24a4d +0xf5fa 0x7492 +0xf5fb 0x7497 +0xf5fc 0x7499 +0xf640 0x74a0 +0xf641 0x74a1 +0xf642 0x74a5 +0xf643 0x74aa +0xf644 0x74ab +0xf645 0x74b9 +0xf646 0x74bb +0xf647 0x74ba +0xf648 0x74d6 +0xf649 0x74d8 +0xf64a 0x74de +0xf64b 0x74ef +0xf64c 0x74eb +0xf64d 0x24b56 +0xf64e 0x74fa +0xf64f 0x24b6f +0xf650 0x7520 +0xf651 0x7524 +0xf652 0x752a +0xf653 0x3f57 +0xf654 0x24c16 +0xf655 0x753d +0xf656 0x753e +0xf657 0x7540 +0xf658 0x7548 +0xf659 0x754e +0xf65a 0x7550 +0xf65b 0x7552 +0xf65c 0x756c +0xf65d 0x7572 +0xf65e 0x7571 +0xf65f 0x757a +0xf660 0x757d +0xf661 0x757e +0xf662 0x7581 +0xf663 0x24d14 +0xf664 0x758c +0xf665 0x3f75 +0xf666 0x75a2 +0xf667 0x3f77 +0xf668 0x75b0 +0xf669 0x75b7 +0xf66a 0x75bf +0xf66b 0x75c0 +0xf66c 0x75c6 +0xf66d 0x75cf +0xf66e 0x75d3 +0xf66f 0x75dd +0xf670 0x75df +0xf671 0x75e0 +0xf672 0x75e7 +0xf673 0x75ec +0xf674 0x75ee +0xf675 0x75f1 +0xf676 0x75f9 +0xf677 0x7603 +0xf678 0x7618 +0xf679 0x7607 +0xf67a 0x760f +0xf67b 0x3fae +0xf67c 0x24e0e +0xf67d 0x7613 +0xf67e 0x761b +0xf680 0x761c +0xf681 0x24e37 +0xf682 0x7625 +0xf683 0x7628 +0xf684 0x763c +0xf685 0x7633 +0xf686 0x24e6a +0xf687 0x3fc9 +0xf688 0x7641 +0xf689 0x24e8b +0xf68a 0x7649 +0xf68b 0x7655 +0xf68c 0x3fd7 +0xf68d 0x766e +0xf68e 0x7695 +0xf68f 0x769c +0xf690 0x76a1 +0xf691 0x76a0 +0xf692 0x76a7 +0xf693 0x76a8 +0xf694 0x76af +0xf695 0x2504a +0xf696 0x76c9 +0xf697 0x25055 +0xf698 0x76e8 +0xf699 0x76ec +0xf69a 0x25122 +0xf69b 0x7717 +0xf69c 0x771a +0xf69d 0x772d +0xf69e 0x7735 +0xf69f 0x251a9 +0xf6a0 0x4039 +0xf6a1 0x251e5 +0xf6a2 0x251cd +0xf6a3 0x7758 +0xf6a4 0x7760 +0xf6a5 0x776a +0xf6a6 0x2521e +0xf6a7 0x7772 +0xf6a8 0x777c +0xf6a9 0x777d +0xf6aa 0x2524c +0xf6ab 0x4058 +0xf6ac 0x779a +0xf6ad 0x779f +0xf6ae 0x77a2 +0xf6af 0x77a4 +0xf6b0 0x77a9 +0xf6b1 0x77de +0xf6b2 0x77df +0xf6b3 0x77e4 +0xf6b4 0x77e6 +0xf6b5 0x77ea +0xf6b6 0x77ec +0xf6b7 0x4093 +0xf6b8 0x77f0 +0xf6b9 0x77f4 +0xf6ba 0x77fb +0xf6bb 0x2542e +0xf6bc 0x7805 +0xf6bd 0x7806 +0xf6be 0x7809 +0xf6bf 0x780d +0xf6c0 0x7819 +0xf6c1 0x7821 +0xf6c2 0x782c +0xf6c3 0x7847 +0xf6c4 0x7864 +0xf6c5 0x786a +0xf6c6 0x254d9 +0xf6c7 0x788a +0xf6c8 0x7894 +0xf6c9 0x78a4 +0xf6ca 0x789d +0xf6cb 0x789e +0xf6cc 0x789f +0xf6cd 0x78bb +0xf6ce 0x78c8 +0xf6cf 0x78cc +0xf6d0 0x78ce +0xf6d1 0x78d5 +0xf6d2 0x78e0 +0xf6d3 0x78e1 +0xf6d4 0x78e6 +0xf6d5 0x78f9 +0xf6d6 0x78fa +0xf6d7 0x78fb +0xf6d8 0x78fe +0xf6d9 0x255a7 +0xf6da 0x7910 +0xf6db 0x791b +0xf6dc 0x7930 +0xf6dd 0x7925 +0xf6de 0x793b +0xf6df 0x794a +0xf6e0 0x7958 +0xf6e1 0x795b +0xf6e2 0x4105 +0xf6e3 0x7967 +0xf6e4 0x7972 +0xf6e5 0x7994 +0xf6e6 0x7995 +0xf6e7 0x7996 +0xf6e8 0x799b +0xf6e9 0x79a1 +0xf6ea 0x79a9 +0xf6eb 0x79b4 +0xf6ec 0x79bb +0xf6ed 0x79c2 +0xf6ee 0x79c7 +0xf6ef 0x79cc +0xf6f0 0x79cd +0xf6f1 0x79d6 +0xf6f2 0x4148 +0xf6f3 0x257a9 +0xf6f4 0x257b4 +0xf6f5 0x414f +0xf6f6 0x7a0a +0xf6f7 0x7a11 +0xf6f8 0x7a15 +0xf6f9 0x7a1b +0xf6fa 0x7a1e +0xf6fb 0x4163 +0xf6fc 0x7a2d +0xf740 0x7a38 +0xf741 0x7a47 +0xf742 0x7a4c +0xf743 0x7a56 +0xf744 0x7a59 +0xf745 0x7a5c +0xf746 0x7a5f +0xf747 0x7a60 +0xf748 0x7a67 +0xf749 0x7a6a +0xf74a 0x7a75 +0xf74b 0x7a78 +0xf74c 0x7a82 +0xf74d 0x7a8a +0xf74e 0x7a90 +0xf74f 0x7aa3 +0xf750 0x7aac +0xf751 0x259d4 +0xf752 0x41b4 +0xf753 0x7ab9 +0xf754 0x7abc +0xf755 0x7abe +0xf756 0x41bf +0xf757 0x7acc +0xf758 0x7ad1 +0xf759 0x7ae7 +0xf75a 0x7ae8 +0xf75b 0x7af4 +0xf75c 0x25ae4 +0xf75d 0x25ae3 +0xf75e 0x7b07 +0xf75f 0x25af1 +0xf760 0x7b3d +0xf761 0x7b27 +0xf762 0x7b2a +0xf763 0x7b2e +0xf764 0x7b2f +0xf765 0x7b31 +0xf766 0x41e6 +0xf767 0x41f3 +0xf768 0x7b7f +0xf769 0x7b41 +0xf76a 0x41ee +0xf76b 0x7b55 +0xf76c 0x7b79 +0xf76d 0x7b64 +0xf76e 0x7b66 +0xf76f 0x7b69 +0xf770 0x7b73 +0xf771 0x25bb2 +0xf772 0x4207 +0xf773 0x7b90 +0xf774 0x7b91 +0xf775 0x7b9b +0xf776 0x420e +0xf777 0x7baf +0xf778 0x7bb5 +0xf779 0x7bbc +0xf77a 0x7bc5 +0xf77b 0x7bca +0xf77c 0x25c4b +0xf77d 0x25c64 +0xf77e 0x7bd4 +0xf780 0x7bd6 +0xf781 0x7bda +0xf782 0x7bea +0xf783 0x7bf0 +0xf784 0x7c03 +0xf785 0x7c0b +0xf786 0x7c0e +0xf787 0x7c0f +0xf788 0x7c26 +0xf789 0x7c45 +0xf78a 0x7c4a +0xf78b 0x7c51 +0xf78c 0x7c57 +0xf78d 0x7c5e +0xf78e 0x7c61 +0xf78f 0x7c69 +0xf790 0x7c6e +0xf791 0x7c6f +0xf792 0x7c70 +0xf793 0x25e2e +0xf794 0x25e56 +0xf795 0x25e65 +0xf796 0x7ca6 +0xf797 0x25e62 +0xf798 0x7cb6 +0xf799 0x7cb7 +0xf79a 0x7cbf +0xf79b 0x25ed8 +0xf79c 0x7cc4 +0xf79d 0x25ec2 +0xf79e 0x7cc8 +0xf79f 0x7ccd +0xf7a0 0x25ee8 +0xf7a1 0x7cd7 +0xf7a2 0x25f23 +0xf7a3 0x7ce6 +0xf7a4 0x7ceb +0xf7a5 0x25f5c +0xf7a6 0x7cf5 +0xf7a7 0x7d03 +0xf7a8 0x7d09 +0xf7a9 0x42c6 +0xf7aa 0x7d12 +0xf7ab 0x7d1e +0xf7ac 0x25fe0 +0xf7ad 0x25fd4 +0xf7ae 0x7d3d +0xf7af 0x7d3e +0xf7b0 0x7d40 +0xf7b1 0x7d47 +0xf7b2 0x2600c +0xf7b3 0x25ffb +0xf7b4 0x42d6 +0xf7b5 0x7d59 +0xf7b6 0x7d5a +0xf7b7 0x7d6a +0xf7b8 0x7d70 +0xf7b9 0x42dd +0xf7ba 0x7d7f +0xf7bb 0x26017 +0xf7bc 0x7d86 +0xf7bd 0x7d88 +0xf7be 0x7d8c +0xf7bf 0x7d97 +0xf7c0 0x26060 +0xf7c1 0x7d9d +0xf7c2 0x7da7 +0xf7c3 0x7daa +0xf7c4 0x7db6 +0xf7c5 0x7db7 +0xf7c6 0x7dc0 +0xf7c7 0x7dd7 +0xf7c8 0x7dd9 +0xf7c9 0x7de6 +0xf7ca 0x7df1 +0xf7cb 0x7df9 +0xf7cc 0x4302 +0xf7cd 0x260ed +0xf7ce 0xfa58 +0xf7cf 0x7e10 +0xf7d0 0x7e17 +0xf7d1 0x7e1d +0xf7d2 0x7e20 +0xf7d3 0x7e27 +0xf7d4 0x7e2c +0xf7d5 0x7e45 +0xf7d6 0x7e73 +0xf7d7 0x7e75 +0xf7d8 0x7e7e +0xf7d9 0x7e86 +0xf7da 0x7e87 +0xf7db 0x432b +0xf7dc 0x7e91 +0xf7dd 0x7e98 +0xf7de 0x7e9a +0xf7df 0x4343 +0xf7e0 0x7f3c +0xf7e1 0x7f3b +0xf7e2 0x7f3e +0xf7e3 0x7f43 +0xf7e4 0x7f44 +0xf7e5 0x7f4f +0xf7e6 0x34c1 +0xf7e7 0x26270 +0xf7e8 0x7f52 +0xf7e9 0x26286 +0xf7ea 0x7f61 +0xf7eb 0x7f63 +0xf7ec 0x7f64 +0xf7ed 0x7f6d +0xf7ee 0x7f7d +0xf7ef 0x7f7e +0xf7f0 0x2634c +0xf7f1 0x7f90 +0xf7f2 0x517b +0xf7f3 0x23d0e +0xf7f4 0x7f96 +0xf7f5 0x7f9c +0xf7f6 0x7fad +0xf7f7 0x26402 +0xf7f8 0x7fc3 +0xf7f9 0x7fcf +0xf7fa 0x7fe3 +0xf7fb 0x7fe5 +0xf7fc 0x7fef +0xf840 0x7ff2 +0xf841 0x8002 +0xf842 0x800a +0xf843 0x8008 +0xf844 0x800e +0xf845 0x8011 +0xf846 0x8016 +0xf847 0x8024 +0xf848 0x802c +0xf849 0x8030 +0xf84a 0x8043 +0xf84b 0x8066 +0xf84c 0x8071 +0xf84d 0x8075 +0xf84e 0x807b +0xf84f 0x8099 +0xf850 0x809c +0xf851 0x80a4 +0xf852 0x80a7 +0xf853 0x80b8 +0xf854 0x2667e +0xf855 0x80c5 +0xf856 0x80d5 +0xf857 0x80d8 +0xf858 0x80e6 +0xf859 0x266b0 +0xf85a 0x810d +0xf85b 0x80f5 +0xf85c 0x80fb +0xf85d 0x43ee +0xf85e 0x8135 +0xf85f 0x8116 +0xf860 0x811e +0xf861 0x43f0 +0xf862 0x8124 +0xf863 0x8127 +0xf864 0x812c +0xf865 0x2671d +0xf866 0x813d +0xf867 0x4408 +0xf868 0x8169 +0xf869 0x4417 +0xf86a 0x8181 +0xf86b 0x441c +0xf86c 0x8184 +0xf86d 0x8185 +0xf86e 0x4422 +0xf86f 0x8198 +0xf870 0x81b2 +0xf871 0x81c1 +0xf872 0x81c3 +0xf873 0x81d6 +0xf874 0x81db +0xf875 0x268dd +0xf876 0x81e4 +0xf877 0x268ea +0xf878 0x81ec +0xf879 0x26951 +0xf87a 0x81fd +0xf87b 0x81ff +0xf87c 0x2696f +0xf87d 0x8204 +0xf87e 0x269dd +0xf880 0x8219 +0xf881 0x8221 +0xf882 0x8222 +0xf883 0x26a1e +0xf884 0x8232 +0xf885 0x8234 +0xf886 0x823c +0xf887 0x8246 +0xf888 0x8249 +0xf889 0x8245 +0xf88a 0x26a58 +0xf88b 0x824b +0xf88c 0x4476 +0xf88d 0x824f +0xf88e 0x447a +0xf88f 0x8257 +0xf890 0x26a8c +0xf891 0x825c +0xf892 0x8263 +0xf893 0x26ab7 +0xf894 0xfa5d +0xf895 0xfa5e +0xf896 0x8279 +0xf897 0x4491 +0xf898 0x827d +0xf899 0x827f +0xf89a 0x8283 +0xf89b 0x828a +0xf89c 0x8293 +0xf89d 0x82a7 +0xf89e 0x82a8 +0xf89f 0x82b2 +0xf8a0 0x82b4 +0xf8a1 0x82ba +0xf8a2 0x82bc +0xf8a3 0x82e2 +0xf8a4 0x82e8 +0xf8a5 0x82f7 +0xf8a6 0x8307 +0xf8a7 0x8308 +0xf8a8 0x830c +0xf8a9 0x8354 +0xf8aa 0x831b +0xf8ab 0x831d +0xf8ac 0x8330 +0xf8ad 0x833c +0xf8ae 0x8344 +0xf8af 0x8357 +0xf8b0 0x44be +0xf8b1 0x837f +0xf8b2 0x44d4 +0xf8b3 0x44b3 +0xf8b4 0x838d +0xf8b5 0x8394 +0xf8b6 0x8395 +0xf8b7 0x839b +0xf8b8 0x839d +0xf8b9 0x83c9 +0xf8ba 0x83d0 +0xf8bb 0x83d4 +0xf8bc 0x83dd +0xf8bd 0x83e5 +0xf8be 0x83f9 +0xf8bf 0x840f +0xf8c0 0x8411 +0xf8c1 0x8415 +0xf8c2 0x26c73 +0xf8c3 0x8417 +0xf8c4 0x8439 +0xf8c5 0x844a +0xf8c6 0x844f +0xf8c7 0x8451 +0xf8c8 0x8452 +0xf8c9 0x8459 +0xf8ca 0x845a +0xf8cb 0x845c +0xf8cc 0x26cdd +0xf8cd 0x8465 +0xf8ce 0x8476 +0xf8cf 0x8478 +0xf8d0 0x847c +0xf8d1 0x8481 +0xf8d2 0x450d +0xf8d3 0x84dc +0xf8d4 0x8497 +0xf8d5 0x84a6 +0xf8d6 0x84be +0xf8d7 0x4508 +0xf8d8 0x84ce +0xf8d9 0x84cf +0xf8da 0x84d3 +0xf8db 0x26e65 +0xf8dc 0x84e7 +0xf8dd 0x84ea +0xf8de 0x84ef +0xf8df 0x84f0 +0xf8e0 0x84f1 +0xf8e1 0x84fa +0xf8e2 0x84fd +0xf8e3 0x850c +0xf8e4 0x851b +0xf8e5 0x8524 +0xf8e6 0x8525 +0xf8e7 0x852b +0xf8e8 0x8534 +0xf8e9 0x854f +0xf8ea 0x856f +0xf8eb 0x4525 +0xf8ec 0x4543 +0xf8ed 0x853e +0xf8ee 0x8551 +0xf8ef 0x8553 +0xf8f0 0x855e +0xf8f1 0x8561 +0xf8f2 0x8562 +0xf8f3 0x26f94 +0xf8f4 0x857b +0xf8f5 0x857d +0xf8f6 0x857f +0xf8f7 0x8581 +0xf8f8 0x8586 +0xf8f9 0x8593 +0xf8fa 0x859d +0xf8fb 0x859f +0xf8fc 0x26ff8 +0xf940 0x26ff6 +0xf941 0x26ff7 +0xf942 0x85b7 +0xf943 0x85bc +0xf944 0x85c7 +0xf945 0x85ca +0xf946 0x85d8 +0xf947 0x85d9 +0xf948 0x85df +0xf949 0x85e1 +0xf94a 0x85e6 +0xf94b 0x85f6 +0xf94c 0x8600 +0xf94d 0x8611 +0xf94e 0x861e +0xf94f 0x8621 +0xf950 0x8624 +0xf951 0x8627 +0xf952 0x2710d +0xf953 0x8639 +0xf954 0x863c +0xf955 0x27139 +0xf956 0x8640 +0xf957 0xfa20 +0xf958 0x8653 +0xf959 0x8656 +0xf95a 0x866f +0xf95b 0x8677 +0xf95c 0x867a +0xf95d 0x8687 +0xf95e 0x8689 +0xf95f 0x868d +0xf960 0x8691 +0xf961 0x869c +0xf962 0x869d +0xf963 0x86a8 +0xf964 0xfa21 +0xf965 0x86b1 +0xf966 0x86b3 +0xf967 0x86c1 +0xf968 0x86c3 +0xf969 0x86d1 +0xf96a 0x86d5 +0xf96b 0x86d7 +0xf96c 0x86e3 +0xf96d 0x86e6 +0xf96e 0x45b8 +0xf96f 0x8705 +0xf970 0x8707 +0xf971 0x870e +0xf972 0x8710 +0xf973 0x8713 +0xf974 0x8719 +0xf975 0x871f +0xf976 0x8721 +0xf977 0x8723 +0xf978 0x8731 +0xf979 0x873a +0xf97a 0x873e +0xf97b 0x8740 +0xf97c 0x8743 +0xf97d 0x8751 +0xf97e 0x8758 +0xf980 0x8764 +0xf981 0x8765 +0xf982 0x8772 +0xf983 0x877c +0xf984 0x273db +0xf985 0x273da +0xf986 0x87a7 +0xf987 0x8789 +0xf988 0x878b +0xf989 0x8793 +0xf98a 0x87a0 +0xf98b 0x273fe +0xf98c 0x45e5 +0xf98d 0x87be +0xf98e 0x27410 +0xf98f 0x87c1 +0xf990 0x87ce +0xf991 0x87f5 +0xf992 0x87df +0xf993 0x27449 +0xf994 0x87e3 +0xf995 0x87e5 +0xf996 0x87e6 +0xf997 0x87ea +0xf998 0x87eb +0xf999 0x87ed +0xf99a 0x8801 +0xf99b 0x8803 +0xf99c 0x880b +0xf99d 0x8813 +0xf99e 0x8828 +0xf99f 0x882e +0xf9a0 0x8832 +0xf9a1 0x883c +0xf9a2 0x460f +0xf9a3 0x884a +0xf9a4 0x8858 +0xf9a5 0x885f +0xf9a6 0x8864 +0xf9a7 0x27615 +0xf9a8 0x27614 +0xf9a9 0x8869 +0xf9aa 0x27631 +0xf9ab 0x886f +0xf9ac 0x88a0 +0xf9ad 0x88bc +0xf9ae 0x88bd +0xf9af 0x88be +0xf9b0 0x88c0 +0xf9b1 0x88d2 +0xf9b2 0x27693 +0xf9b3 0x88d1 +0xf9b4 0x88d3 +0xf9b5 0x88db +0xf9b6 0x88f0 +0xf9b7 0x88f1 +0xf9b8 0x4641 +0xf9b9 0x8901 +0xf9ba 0x2770e +0xf9bb 0x8937 +0xf9bc 0x27723 +0xf9bd 0x8942 +0xf9be 0x8945 +0xf9bf 0x8949 +0xf9c0 0x27752 +0xf9c1 0x4665 +0xf9c2 0x8962 +0xf9c3 0x8980 +0xf9c4 0x8989 +0xf9c5 0x8990 +0xf9c6 0x899f +0xf9c7 0x89b0 +0xf9c8 0x89b7 +0xf9c9 0x89d6 +0xf9ca 0x89d8 +0xf9cb 0x89eb +0xf9cc 0x46a1 +0xf9cd 0x89f1 +0xf9ce 0x89f3 +0xf9cf 0x89fd +0xf9d0 0x89ff +0xf9d1 0x46af +0xf9d2 0x8a11 +0xf9d3 0x8a14 +0xf9d4 0x27985 +0xf9d5 0x8a21 +0xf9d6 0x8a35 +0xf9d7 0x8a3e +0xf9d8 0x8a45 +0xf9d9 0x8a4d +0xf9da 0x8a58 +0xf9db 0x8aae +0xf9dc 0x8a90 +0xf9dd 0x8ab7 +0xf9de 0x8abe +0xf9df 0x8ad7 +0xf9e0 0x8afc +0xf9e1 0x27a84 +0xf9e2 0x8b0a +0xf9e3 0x8b05 +0xf9e4 0x8b0d +0xf9e5 0x8b1c +0xf9e6 0x8b1f +0xf9e7 0x8b2d +0xf9e8 0x8b43 +0xf9e9 0x470c +0xf9ea 0x8b51 +0xf9eb 0x8b5e +0xf9ec 0x8b76 +0xf9ed 0x8b7f +0xf9ee 0x8b81 +0xf9ef 0x8b8b +0xf9f0 0x8b94 +0xf9f1 0x8b95 +0xf9f2 0x8b9c +0xf9f3 0x8b9e +0xf9f4 0x8c39 +0xf9f5 0x27bb3 +0xf9f6 0x8c3d +0xf9f7 0x27bbe +0xf9f8 0x27bc7 +0xf9f9 0x8c45 +0xf9fa 0x8c47 +0xf9fb 0x8c4f +0xf9fc 0x8c54 +0xfa40 0x8c57 +0xfa41 0x8c69 +0xfa42 0x8c6d +0xfa43 0x8c73 +0xfa44 0x27cb8 +0xfa45 0x8c93 +0xfa46 0x8c92 +0xfa47 0x8c99 +0xfa48 0x4764 +0xfa49 0x8c9b +0xfa4a 0x8ca4 +0xfa4b 0x8cd6 +0xfa4c 0x8cd5 +0xfa4d 0x8cd9 +0xfa4e 0x27da0 +0xfa4f 0x8cf0 +0xfa50 0x8cf1 +0xfa51 0x27e10 +0xfa52 0x8d09 +0xfa53 0x8d0e +0xfa54 0x8d6c +0xfa55 0x8d84 +0xfa56 0x8d95 +0xfa57 0x8da6 +0xfa58 0x27fb7 +0xfa59 0x8dc6 +0xfa5a 0x8dc8 +0xfa5b 0x8dd9 +0xfa5c 0x8dec +0xfa5d 0x8e0c +0xfa5e 0x47fd +0xfa5f 0x8dfd +0xfa60 0x8e06 +0xfa61 0x2808a +0xfa62 0x8e14 +0xfa63 0x8e16 +0xfa64 0x8e21 +0xfa65 0x8e22 +0xfa66 0x8e27 +0xfa67 0x280bb +0xfa68 0x4816 +0xfa69 0x8e36 +0xfa6a 0x8e39 +0xfa6b 0x8e4b +0xfa6c 0x8e54 +0xfa6d 0x8e62 +0xfa6e 0x8e6c +0xfa6f 0x8e6d +0xfa70 0x8e6f +0xfa71 0x8e98 +0xfa72 0x8e9e +0xfa73 0x8eae +0xfa74 0x8eb3 +0xfa75 0x8eb5 +0xfa76 0x8eb6 +0xfa77 0x8ebb +0xfa78 0x28282 +0xfa79 0x8ed1 +0xfa7a 0x8ed4 +0xfa7b 0x484e +0xfa7c 0x8ef9 +0xfa7d 0x282f3 +0xfa7e 0x8f00 +0xfa80 0x8f08 +0xfa81 0x8f17 +0xfa82 0x8f2b +0xfa83 0x8f40 +0xfa84 0x8f4a +0xfa85 0x8f58 +0xfa86 0x2840c +0xfa87 0x8fa4 +0xfa88 0x8fb4 +0xfa89 0xfa66 +0xfa8a 0x8fb6 +0xfa8b 0x28455 +0xfa8c 0x8fc1 +0xfa8d 0x8fc6 +0xfa8e 0xfa24 +0xfa8f 0x8fca +0xfa90 0x8fcd +0xfa91 0x8fd3 +0xfa92 0x8fd5 +0xfa93 0x8fe0 +0xfa94 0x8ff1 +0xfa95 0x8ff5 +0xfa96 0x8ffb +0xfa97 0x9002 +0xfa98 0x900c +0xfa99 0x9037 +0xfa9a 0x2856b +0xfa9b 0x9043 +0xfa9c 0x9044 +0xfa9d 0x905d +0xfa9e 0x285c8 +0xfa9f 0x285c9 +0xfaa0 0x9085 +0xfaa1 0x908c +0xfaa2 0x9090 +0xfaa3 0x961d +0xfaa4 0x90a1 +0xfaa5 0x48b5 +0xfaa6 0x90b0 +0xfaa7 0x90b6 +0xfaa8 0x90c3 +0xfaa9 0x90c8 +0xfaaa 0x286d7 +0xfaab 0x90dc +0xfaac 0x90df +0xfaad 0x286fa +0xfaae 0x90f6 +0xfaaf 0x90f2 +0xfab0 0x9100 +0xfab1 0x90eb +0xfab2 0x90fe +0xfab3 0x90ff +0xfab4 0x9104 +0xfab5 0x9106 +0xfab6 0x9118 +0xfab7 0x911c +0xfab8 0x911e +0xfab9 0x9137 +0xfaba 0x9139 +0xfabb 0x913a +0xfabc 0x9146 +0xfabd 0x9147 +0xfabe 0x9157 +0xfabf 0x9159 +0xfac0 0x9161 +0xfac1 0x9164 +0xfac2 0x9174 +0xfac3 0x9179 +0xfac4 0x9185 +0xfac5 0x918e +0xfac6 0x91a8 +0xfac7 0x91ae +0xfac8 0x91b3 +0xfac9 0x91b6 +0xfaca 0x91c3 +0xfacb 0x91c4 +0xfacc 0x91da +0xfacd 0x28949 +0xface 0x28946 +0xfacf 0x91ec +0xfad0 0x91ee +0xfad1 0x9201 +0xfad2 0x920a +0xfad3 0x9216 +0xfad4 0x9217 +0xfad5 0x2896b +0xfad6 0x9233 +0xfad7 0x9242 +0xfad8 0x9247 +0xfad9 0x924a +0xfada 0x924e +0xfadb 0x9251 +0xfadc 0x9256 +0xfadd 0x9259 +0xfade 0x9260 +0xfadf 0x9261 +0xfae0 0x9265 +0xfae1 0x9267 +0xfae2 0x9268 +0xfae3 0x28987 +0xfae4 0x28988 +0xfae5 0x927c +0xfae6 0x927d +0xfae7 0x927f +0xfae8 0x9289 +0xfae9 0x928d +0xfaea 0x9297 +0xfaeb 0x9299 +0xfaec 0x929f +0xfaed 0x92a7 +0xfaee 0x92ab +0xfaef 0x289ba +0xfaf0 0x289bb +0xfaf1 0x92b2 +0xfaf2 0x92bf +0xfaf3 0x92c0 +0xfaf4 0x92c6 +0xfaf5 0x92ce +0xfaf6 0x92d0 +0xfaf7 0x92d7 +0xfaf8 0x92d9 +0xfaf9 0x92e5 +0xfafa 0x92e7 +0xfafb 0x9311 +0xfafc 0x28a1e +0xfb40 0x28a29 +0xfb41 0x92f7 +0xfb42 0x92f9 +0xfb43 0x92fb +0xfb44 0x9302 +0xfb45 0x930d +0xfb46 0x9315 +0xfb47 0x931d +0xfb48 0x931e +0xfb49 0x9327 +0xfb4a 0x9329 +0xfb4b 0x28a71 +0xfb4c 0x28a43 +0xfb4d 0x9347 +0xfb4e 0x9351 +0xfb4f 0x9357 +0xfb50 0x935a +0xfb51 0x936b +0xfb52 0x9371 +0xfb53 0x9373 +0xfb54 0x93a1 +0xfb55 0x28a99 +0xfb56 0x28acd +0xfb57 0x9388 +0xfb58 0x938b +0xfb59 0x938f +0xfb5a 0x939e +0xfb5b 0x93f5 +0xfb5c 0x28ae4 +0xfb5d 0x28add +0xfb5e 0x93f1 +0xfb5f 0x93c1 +0xfb60 0x93c7 +0xfb61 0x93dc +0xfb62 0x93e2 +0xfb63 0x93e7 +0xfb64 0x9409 +0xfb65 0x940f +0xfb66 0x9416 +0xfb67 0x9417 +0xfb68 0x93fb +0xfb69 0x9432 +0xfb6a 0x9434 +0xfb6b 0x943b +0xfb6c 0x9445 +0xfb6d 0x28bc1 +0xfb6e 0x28bef +0xfb6f 0x946d +0xfb70 0x946f +0xfb71 0x9578 +0xfb72 0x9579 +0xfb73 0x9586 +0xfb74 0x958c +0xfb75 0x958d +0xfb76 0x28d10 +0xfb77 0x95ab +0xfb78 0x95b4 +0xfb79 0x28d71 +0xfb7a 0x95c8 +0xfb7b 0x28dfb +0xfb7c 0x28e1f +0xfb7d 0x962c +0xfb7e 0x9633 +0xfb80 0x9634 +0xfb81 0x28e36 +0xfb82 0x963c +0xfb83 0x9641 +0xfb84 0x9661 +0xfb85 0x28e89 +0xfb86 0x9682 +0xfb87 0x28eeb +0xfb88 0x969a +0xfb89 0x28f32 +0xfb8a 0x49e7 +0xfb8b 0x96a9 +0xfb8c 0x96af +0xfb8d 0x96b3 +0xfb8e 0x96ba +0xfb8f 0x96bd +0xfb90 0x49fa +0xfb91 0x28ff8 +0xfb92 0x96d8 +0xfb93 0x96da +0xfb94 0x96dd +0xfb95 0x4a04 +0xfb96 0x9714 +0xfb97 0x9723 +0xfb98 0x4a29 +0xfb99 0x9736 +0xfb9a 0x9741 +0xfb9b 0x9747 +0xfb9c 0x9755 +0xfb9d 0x9757 +0xfb9e 0x975b +0xfb9f 0x976a +0xfba0 0x292a0 +0xfba1 0x292b1 +0xfba2 0x9796 +0xfba3 0x979a +0xfba4 0x979e +0xfba5 0x97a2 +0xfba6 0x97b1 +0xfba7 0x97b2 +0xfba8 0x97be +0xfba9 0x97cc +0xfbaa 0x97d1 +0xfbab 0x97d4 +0xfbac 0x97d8 +0xfbad 0x97d9 +0xfbae 0x97e1 +0xfbaf 0x97f1 +0xfbb0 0x9804 +0xfbb1 0x980d +0xfbb2 0x980e +0xfbb3 0x9814 +0xfbb4 0x9816 +0xfbb5 0x4abc +0xfbb6 0x29490 +0xfbb7 0x9823 +0xfbb8 0x9832 +0xfbb9 0x9833 +0xfbba 0x9825 +0xfbbb 0x9847 +0xfbbc 0x9866 +0xfbbd 0x98ab +0xfbbe 0x98ad +0xfbbf 0x98b0 +0xfbc0 0x295cf +0xfbc1 0x98b7 +0xfbc2 0x98b8 +0xfbc3 0x98bb +0xfbc4 0x98bc +0xfbc5 0x98bf +0xfbc6 0x98c2 +0xfbc7 0x98c7 +0xfbc8 0x98cb +0xfbc9 0x98e0 +0xfbca 0x2967f +0xfbcb 0x98e1 +0xfbcc 0x98e3 +0xfbcd 0x98e5 +0xfbce 0x98ea +0xfbcf 0x98f0 +0xfbd0 0x98f1 +0xfbd1 0x98f3 +0xfbd2 0x9908 +0xfbd3 0x4b3b +0xfbd4 0x296f0 +0xfbd5 0x9916 +0xfbd6 0x9917 +0xfbd7 0x29719 +0xfbd8 0x991a +0xfbd9 0x991b +0xfbda 0x991c +0xfbdb 0x29750 +0xfbdc 0x9931 +0xfbdd 0x9932 +0xfbde 0x9933 +0xfbdf 0x993a +0xfbe0 0x993b +0xfbe1 0x993c +0xfbe2 0x9940 +0xfbe3 0x9941 +0xfbe4 0x9946 +0xfbe5 0x994d +0xfbe6 0x994e +0xfbe7 0x995c +0xfbe8 0x995f +0xfbe9 0x9960 +0xfbea 0x99a3 +0xfbeb 0x99a6 +0xfbec 0x99b9 +0xfbed 0x99bd +0xfbee 0x99bf +0xfbef 0x99c3 +0xfbf0 0x99c9 +0xfbf1 0x99d4 +0xfbf2 0x99d9 +0xfbf3 0x99de +0xfbf4 0x298c6 +0xfbf5 0x99f0 +0xfbf6 0x99f9 +0xfbf7 0x99fc +0xfbf8 0x9a0a +0xfbf9 0x9a11 +0xfbfa 0x9a16 +0xfbfb 0x9a1a +0xfbfc 0x9a20 +0xfc40 0x9a31 +0xfc41 0x9a36 +0xfc42 0x9a44 +0xfc43 0x9a4c +0xfc44 0x9a58 +0xfc45 0x4bc2 +0xfc46 0x9aaf +0xfc47 0x4bca +0xfc48 0x9ab7 +0xfc49 0x4bd2 +0xfc4a 0x9ab9 +0xfc4b 0x29a72 +0xfc4c 0x9ac6 +0xfc4d 0x9ad0 +0xfc4e 0x9ad2 +0xfc4f 0x9ad5 +0xfc50 0x4be8 +0xfc51 0x9adc +0xfc52 0x9ae0 +0xfc53 0x9ae5 +0xfc54 0x9ae9 +0xfc55 0x9b03 +0xfc56 0x9b0c +0xfc57 0x9b10 +0xfc58 0x9b12 +0xfc59 0x9b16 +0xfc5a 0x9b1c +0xfc5b 0x9b2b +0xfc5c 0x9b33 +0xfc5d 0x9b3d +0xfc5e 0x4c20 +0xfc5f 0x9b4b +0xfc60 0x9b63 +0xfc61 0x9b65 +0xfc62 0x9b6b +0xfc63 0x9b6c +0xfc64 0x9b73 +0xfc65 0x9b76 +0xfc66 0x9b77 +0xfc67 0x9ba6 +0xfc68 0x9bac +0xfc69 0x9bb1 +0xfc6a 0x29ddb +0xfc6b 0x29e3d +0xfc6c 0x9bb2 +0xfc6d 0x9bb8 +0xfc6e 0x9bbe +0xfc6f 0x9bc7 +0xfc70 0x9bf3 +0xfc71 0x9bd8 +0xfc72 0x9bdd +0xfc73 0x9be7 +0xfc74 0x9bea +0xfc75 0x9beb +0xfc76 0x9bef +0xfc77 0x9bee +0xfc78 0x29e15 +0xfc79 0x9bfa +0xfc7a 0x29e8a +0xfc7b 0x9bf7 +0xfc7c 0x29e49 +0xfc7d 0x9c16 +0xfc7e 0x9c18 +0xfc80 0x9c19 +0xfc81 0x9c1a +0xfc82 0x9c1d +0xfc83 0x9c22 +0xfc84 0x9c27 +0xfc85 0x9c29 +0xfc86 0x9c2a +0xfc87 0x29ec4 +0xfc88 0x9c31 +0xfc89 0x9c36 +0xfc8a 0x9c37 +0xfc8b 0x9c45 +0xfc8c 0x9c5c +0xfc8d 0x29ee9 +0xfc8e 0x9c49 +0xfc8f 0x9c4a +0xfc90 0x29edb +0xfc91 0x9c54 +0xfc92 0x9c58 +0xfc93 0x9c5b +0xfc94 0x9c5d +0xfc95 0x9c5f +0xfc96 0x9c69 +0xfc97 0x9c6a +0xfc98 0x9c6b +0xfc99 0x9c6d +0xfc9a 0x9c6e +0xfc9b 0x9c70 +0xfc9c 0x9c72 +0xfc9d 0x9c75 +0xfc9e 0x9c7a +0xfc9f 0x9ce6 +0xfca0 0x9cf2 +0xfca1 0x9d0b +0xfca2 0x9d02 +0xfca3 0x29fce +0xfca4 0x9d11 +0xfca5 0x9d17 +0xfca6 0x9d18 +0xfca7 0x2a02f +0xfca8 0x4cc4 +0xfca9 0x2a01a +0xfcaa 0x9d32 +0xfcab 0x4cd1 +0xfcac 0x9d42 +0xfcad 0x9d4a +0xfcae 0x9d5f +0xfcaf 0x9d62 +0xfcb0 0x2a0f9 +0xfcb1 0x9d69 +0xfcb2 0x9d6b +0xfcb3 0x2a082 +0xfcb4 0x9d73 +0xfcb5 0x9d76 +0xfcb6 0x9d77 +0xfcb7 0x9d7e +0xfcb8 0x9d84 +0xfcb9 0x9d8d +0xfcba 0x9d99 +0xfcbb 0x9da1 +0xfcbc 0x9dbf +0xfcbd 0x9db5 +0xfcbe 0x9db9 +0xfcbf 0x9dbd +0xfcc0 0x9dc3 +0xfcc1 0x9dc7 +0xfcc2 0x9dc9 +0xfcc3 0x9dd6 +0xfcc4 0x9dda +0xfcc5 0x9ddf +0xfcc6 0x9de0 +0xfcc7 0x9de3 +0xfcc8 0x9df4 +0xfcc9 0x4d07 +0xfcca 0x9e0a +0xfccb 0x9e02 +0xfccc 0x9e0d +0xfccd 0x9e19 +0xfcce 0x9e1c +0xfccf 0x9e1d +0xfcd0 0x9e7b +0xfcd1 0x22218 +0xfcd2 0x9e80 +0xfcd3 0x9e85 +0xfcd4 0x9e9b +0xfcd5 0x9ea8 +0xfcd6 0x2a38c +0xfcd7 0x9ebd +0xfcd8 0x2a437 +0xfcd9 0x9edf +0xfcda 0x9ee7 +0xfcdb 0x9eee +0xfcdc 0x9eff +0xfcdd 0x9f02 +0xfcde 0x4d77 +0xfcdf 0x9f03 +0xfce0 0x9f17 +0xfce1 0x9f19 +0xfce2 0x9f2f +0xfce3 0x9f37 +0xfce4 0x9f3a +0xfce5 0x9f3d +0xfce6 0x9f41 +0xfce7 0x9f45 +0xfce8 0x9f46 +0xfce9 0x9f53 +0xfcea 0x9f55 +0xfceb 0x9f58 +0xfcec 0x2a5f1 +0xfced 0x9f5d +0xfcee 0x2a602 +0xfcef 0x9f69 +0xfcf0 0x2a61a +0xfcf1 0x9f6d +0xfcf2 0x9f70 +0xfcf3 0x9f75 +0xfcf4 0x2a6b2 diff --git a/data/koi8-r.txt b/data/koi8-r.txt new file mode 100644 index 0000000000..173f520a10 --- /dev/null +++ b/data/koi8-r.txt @@ -0,0 +1,257 @@ +# koi8-r.txt - Legacy SBCS to Unicode charmap +0x00 0x0000 # 0 +0x01 0x0001 # 0 +0x02 0x0002 # 0 +0x03 0x0003 # 0 +0x04 0x0004 # 0 +0x05 0x0005 # 0 +0x06 0x0006 # 0 +0x07 0x0007 # 0 +0x08 0x0008 # 0 +0x09 0x0009 # 0 +0x0A 0x000A # 0 +0x0B 0x000B # 0 +0x0C 0x000C # 0 +0x0D 0x000D # 0 +0x0E 0x000E # 0 +0x0F 0x000F # 0 +0x10 0x0010 # 0 +0x11 0x0011 # 0 +0x12 0x0012 # 0 +0x13 0x0013 # 0 +0x14 0x0014 # 0 +0x15 0x0015 # 0 +0x16 0x0016 # 0 +0x17 0x0017 # 0 +0x18 0x0018 # 0 +0x19 0x0019 # 0 +0x1A 0x001A # 0 +0x1B 0x001B # 0 +0x1C 0x001C # 0 +0x1D 0x001D # 0 +0x1E 0x001E # 0 +0x1F 0x001F # 0 +0x20 0x0020 # 0 +0x21 0x0021 # 0 +0x22 0x0022 # 0 +0x23 0x0023 # 0 +0x24 0x0024 # 0 +0x25 0x0025 # 0 +0x26 0x0026 # 0 +0x27 0x0027 # 0 +0x28 0x0028 # 0 +0x29 0x0029 # 0 +0x2A 0x002A # 0 +0x2B 0x002B # 0 +0x2C 0x002C # 0 +0x2D 0x002D # 0 +0x2E 0x002E # 0 +0x2F 0x002F # 0 +0x30 0x0030 # 0 +0x31 0x0031 # 0 +0x32 0x0032 # 0 +0x33 0x0033 # 0 +0x34 0x0034 # 0 +0x35 0x0035 # 0 +0x36 0x0036 # 0 +0x37 0x0037 # 0 +0x38 0x0038 # 0 +0x39 0x0039 # 0 +0x3A 0x003A # 0 +0x3B 0x003B # 0 +0x3C 0x003C # 0 +0x3D 0x003D # 0 +0x3E 0x003E # 0 +0x3F 0x003F # 0 +0x40 0x0040 # 0 +0x41 0x0041 # 0 +0x42 0x0042 # 0 +0x43 0x0043 # 0 +0x44 0x0044 # 0 +0x45 0x0045 # 0 +0x46 0x0046 # 0 +0x47 0x0047 # 0 +0x48 0x0048 # 0 +0x49 0x0049 # 0 +0x4A 0x004A # 0 +0x4B 0x004B # 0 +0x4C 0x004C # 0 +0x4D 0x004D # 0 +0x4E 0x004E # 0 +0x4F 0x004F # 0 +0x50 0x0050 # 0 +0x51 0x0051 # 0 +0x52 0x0052 # 0 +0x53 0x0053 # 0 +0x54 0x0054 # 0 +0x55 0x0055 # 0 +0x56 0x0056 # 0 +0x57 0x0057 # 0 +0x58 0x0058 # 0 +0x59 0x0059 # 0 +0x5A 0x005A # 0 +0x5B 0x005B # 0 +0x5C 0x005C # 0 +0x5D 0x005D # 0 +0x5E 0x005E # 0 +0x5F 0x005F # 0 +0x60 0x0060 # 0 +0x61 0x0061 # 0 +0x62 0x0062 # 0 +0x63 0x0063 # 0 +0x64 0x0064 # 0 +0x65 0x0065 # 0 +0x66 0x0066 # 0 +0x67 0x0067 # 0 +0x68 0x0068 # 0 +0x69 0x0069 # 0 +0x6A 0x006A # 0 +0x6B 0x006B # 0 +0x6C 0x006C # 0 +0x6D 0x006D # 0 +0x6E 0x006E # 0 +0x6F 0x006F # 0 +0x70 0x0070 # 0 +0x71 0x0071 # 0 +0x72 0x0072 # 0 +0x73 0x0073 # 0 +0x74 0x0074 # 0 +0x75 0x0075 # 0 +0x76 0x0076 # 0 +0x77 0x0077 # 0 +0x78 0x0078 # 0 +0x79 0x0079 # 0 +0x7A 0x007A # 0 +0x7B 0x007B # 0 +0x7C 0x007C # 0 +0x7D 0x007D # 0 +0x7E 0x007E # 0 +0x7F 0x007F # 0 +0x80 0x2500 # 0 +0x81 0x2502 # 0 +0x82 0x250C # 0 +0x83 0x2510 # 0 +0x84 0x2514 # 0 +0x85 0x2518 # 0 +0x86 0x251C # 0 +0x87 0x2524 # 0 +0x88 0x252C # 0 +0x89 0x2534 # 0 +0x8A 0x253C # 0 +0x8B 0x2580 # 0 +0x8C 0x2584 # 0 +0x8D 0x2588 # 0 +0x8E 0x258C # 0 +0x8F 0x2590 # 0 +0x90 0x2591 # 0 +0x91 0x2592 # 0 +0x92 0x2593 # 0 +0x93 0x2320 # 0 +0x94 0x25A0 # 0 +0x95 0x2022 # 0 +0x96 0x221A # 0 +0x97 0x2248 # 0 +0x98 0x2264 # 0 +0x99 0x2265 # 0 +0x9A 0x00A0 # 0 +0x9B 0x2321 # 0 +0x9C 0x00B0 # 0 +0x9D 0x00B2 # 0 +0x9E 0x00B7 # 0 +0x9F 0x00F7 # 0 +0xA0 0x2550 # 0 +0xA1 0x2551 # 0 +0xA2 0x2552 # 0 +0xA3 0x0451 # 0 +0xA4 0x2553 # 0 +0xA5 0x2554 # 0 +0xA6 0x2555 # 0 +0xA7 0x2556 # 0 +0xA8 0x2557 # 0 +0xA9 0x2558 # 0 +0xAA 0x2559 # 0 +0xAB 0x255A # 0 +0xAC 0x255B # 0 +0xAD 0x255C # 0 +0xAE 0x255D # 0 +0xAF 0x255E # 0 +0xB0 0x255F # 0 +0xB1 0x2560 # 0 +0xB2 0x2561 # 0 +0xB3 0x0401 # 0 +0xB4 0x2562 # 0 +0xB5 0x2563 # 0 +0xB6 0x2564 # 0 +0xB7 0x2565 # 0 +0xB8 0x2566 # 0 +0xB9 0x2567 # 0 +0xBA 0x2568 # 0 +0xBB 0x2569 # 0 +0xBC 0x256A # 0 +0xBD 0x256B # 0 +0xBE 0x256C # 0 +0xBF 0x00A9 # 0 +0xC0 0x044E # 0 +0xC1 0x0430 # 0 +0xC2 0x0431 # 0 +0xC3 0x0446 # 0 +0xC4 0x0434 # 0 +0xC5 0x0435 # 0 +0xC6 0x0444 # 0 +0xC7 0x0433 # 0 +0xC8 0x0445 # 0 +0xC9 0x0438 # 0 +0xCA 0x0439 # 0 +0xCB 0x043A # 0 +0xCC 0x043B # 0 +0xCD 0x043C # 0 +0xCE 0x043D # 0 +0xCF 0x043E # 0 +0xD0 0x043F # 0 +0xD1 0x044F # 0 +0xD2 0x0440 # 0 +0xD3 0x0441 # 0 +0xD4 0x0442 # 0 +0xD5 0x0443 # 0 +0xD6 0x0436 # 0 +0xD7 0x0432 # 0 +0xD8 0x044C # 0 +0xD9 0x044B # 0 +0xDA 0x0437 # 0 +0xDB 0x0448 # 0 +0xDC 0x044D # 0 +0xDD 0x0449 # 0 +0xDE 0x0447 # 0 +0xDF 0x044A # 0 +0xE0 0x042E # 0 +0xE1 0x0410 # 0 +0xE2 0x0411 # 0 +0xE3 0x0426 # 0 +0xE4 0x0414 # 0 +0xE5 0x0415 # 0 +0xE6 0x0424 # 0 +0xE7 0x0413 # 0 +0xE8 0x0425 # 0 +0xE9 0x0418 # 0 +0xEA 0x0419 # 0 +0xEB 0x041A # 0 +0xEC 0x041B # 0 +0xED 0x041C # 0 +0xEE 0x041D # 0 +0xEF 0x041E # 0 +0xF0 0x041F # 0 +0xF1 0x042F # 0 +0xF2 0x0420 # 0 +0xF3 0x0421 # 0 +0xF4 0x0422 # 0 +0xF5 0x0423 # 0 +0xF6 0x0416 # 0 +0xF7 0x0412 # 0 +0xF8 0x042C # 0 +0xF9 0x042B # 0 +0xFA 0x0417 # 0 +0xFB 0x0428 # 0 +0xFC 0x042D # 0 +0xFD 0x0429 # 0 +0xFE 0x0427 # 0 +0xFF 0x042A # 0 diff --git a/data/koi8-u.txt b/data/koi8-u.txt new file mode 100644 index 0000000000..9942e2192c --- /dev/null +++ b/data/koi8-u.txt @@ -0,0 +1,257 @@ +# koi8-u.txt - Legacy SBCS to Unicode charmap +0x00 0x0000 # 0 +0x01 0x0001 # 0 +0x02 0x0002 # 0 +0x03 0x0003 # 0 +0x04 0x0004 # 0 +0x05 0x0005 # 0 +0x06 0x0006 # 0 +0x07 0x0007 # 0 +0x08 0x0008 # 0 +0x09 0x0009 # 0 +0x0A 0x000A # 0 +0x0B 0x000B # 0 +0x0C 0x000C # 0 +0x0D 0x000D # 0 +0x0E 0x000E # 0 +0x0F 0x000F # 0 +0x10 0x0010 # 0 +0x11 0x0011 # 0 +0x12 0x0012 # 0 +0x13 0x0013 # 0 +0x14 0x0014 # 0 +0x15 0x0015 # 0 +0x16 0x0016 # 0 +0x17 0x0017 # 0 +0x18 0x0018 # 0 +0x19 0x0019 # 0 +0x1A 0x001A # 0 +0x1B 0x001B # 0 +0x1C 0x001C # 0 +0x1D 0x001D # 0 +0x1E 0x001E # 0 +0x1F 0x001F # 0 +0x20 0x0020 # 0 +0x21 0x0021 # 0 +0x22 0x0022 # 0 +0x23 0x0023 # 0 +0x24 0x0024 # 0 +0x25 0x0025 # 0 +0x26 0x0026 # 0 +0x27 0x0027 # 0 +0x28 0x0028 # 0 +0x29 0x0029 # 0 +0x2A 0x002A # 0 +0x2B 0x002B # 0 +0x2C 0x002C # 0 +0x2D 0x002D # 0 +0x2E 0x002E # 0 +0x2F 0x002F # 0 +0x30 0x0030 # 0 +0x31 0x0031 # 0 +0x32 0x0032 # 0 +0x33 0x0033 # 0 +0x34 0x0034 # 0 +0x35 0x0035 # 0 +0x36 0x0036 # 0 +0x37 0x0037 # 0 +0x38 0x0038 # 0 +0x39 0x0039 # 0 +0x3A 0x003A # 0 +0x3B 0x003B # 0 +0x3C 0x003C # 0 +0x3D 0x003D # 0 +0x3E 0x003E # 0 +0x3F 0x003F # 0 +0x40 0x0040 # 0 +0x41 0x0041 # 0 +0x42 0x0042 # 0 +0x43 0x0043 # 0 +0x44 0x0044 # 0 +0x45 0x0045 # 0 +0x46 0x0046 # 0 +0x47 0x0047 # 0 +0x48 0x0048 # 0 +0x49 0x0049 # 0 +0x4A 0x004A # 0 +0x4B 0x004B # 0 +0x4C 0x004C # 0 +0x4D 0x004D # 0 +0x4E 0x004E # 0 +0x4F 0x004F # 0 +0x50 0x0050 # 0 +0x51 0x0051 # 0 +0x52 0x0052 # 0 +0x53 0x0053 # 0 +0x54 0x0054 # 0 +0x55 0x0055 # 0 +0x56 0x0056 # 0 +0x57 0x0057 # 0 +0x58 0x0058 # 0 +0x59 0x0059 # 0 +0x5A 0x005A # 0 +0x5B 0x005B # 0 +0x5C 0x005C # 0 +0x5D 0x005D # 0 +0x5E 0x005E # 0 +0x5F 0x005F # 0 +0x60 0x0060 # 0 +0x61 0x0061 # 0 +0x62 0x0062 # 0 +0x63 0x0063 # 0 +0x64 0x0064 # 0 +0x65 0x0065 # 0 +0x66 0x0066 # 0 +0x67 0x0067 # 0 +0x68 0x0068 # 0 +0x69 0x0069 # 0 +0x6A 0x006A # 0 +0x6B 0x006B # 0 +0x6C 0x006C # 0 +0x6D 0x006D # 0 +0x6E 0x006E # 0 +0x6F 0x006F # 0 +0x70 0x0070 # 0 +0x71 0x0071 # 0 +0x72 0x0072 # 0 +0x73 0x0073 # 0 +0x74 0x0074 # 0 +0x75 0x0075 # 0 +0x76 0x0076 # 0 +0x77 0x0077 # 0 +0x78 0x0078 # 0 +0x79 0x0079 # 0 +0x7A 0x007A # 0 +0x7B 0x007B # 0 +0x7C 0x007C # 0 +0x7D 0x007D # 0 +0x7E 0x007E # 0 +0x7F 0x007F # 0 +0x80 0x2500 # 0 +0x81 0x2502 # 0 +0x82 0x250C # 0 +0x83 0x2510 # 0 +0x84 0x2514 # 0 +0x85 0x2518 # 0 +0x86 0x251C # 0 +0x87 0x2524 # 0 +0x88 0x252C # 0 +0x89 0x2534 # 0 +0x8A 0x253C # 0 +0x8B 0x2580 # 0 +0x8C 0x2584 # 0 +0x8D 0x2588 # 0 +0x8E 0x258C # 0 +0x8F 0x2590 # 0 +0x90 0x2591 # 0 +0x91 0x2592 # 0 +0x92 0x2593 # 0 +0x93 0x2320 # 0 +0x94 0x25A0 # 0 +0x95 0x2019 # 0 +0x96 0x221A # 0 +0x97 0x2248 # 0 +0x98 0x2264 # 0 +0x99 0x2265 # 0 +0x9A 0x00A0 # 0 +0x9B 0x2321 # 0 +0x9C 0x00B0 # 0 +0x9D 0x00B2 # 0 +0x9E 0x00B7 # 0 +0x9F 0x00F7 # 0 +0xA0 0x2550 # 0 +0xA1 0x2551 # 0 +0xA2 0x2552 # 0 +0xA3 0x0451 # 0 +0xA4 0x0454 # 0 +0xA5 0x2554 # 0 +0xA6 0x0456 # 0 +0xA7 0x0457 # 0 +0xA8 0x2557 # 0 +0xA9 0x2558 # 0 +0xAA 0x2559 # 0 +0xAB 0x255A # 0 +0xAC 0x255B # 0 +0xAD 0x0491 # 0 +0xAE 0x255D # 0 +0xAF 0x255E # 0 +0xB0 0x255F # 0 +0xB1 0x2560 # 0 +0xB2 0x2561 # 0 +0xB3 0x0401 # 0 +0xB4 0x0404 # 0 +0xB5 0x2563 # 0 +0xB6 0x0406 # 0 +0xB7 0x0407 # 0 +0xB8 0x2566 # 0 +0xB9 0x2567 # 0 +0xBA 0x2568 # 0 +0xBB 0x2569 # 0 +0xBC 0x256A # 0 +0xBD 0x0490 # 0 +0xBE 0x256C # 0 +0xBF 0x00A9 # 0 +0xC0 0x044E # 0 +0xC1 0x0430 # 0 +0xC2 0x0431 # 0 +0xC3 0x0446 # 0 +0xC4 0x0434 # 0 +0xC5 0x0435 # 0 +0xC6 0x0444 # 0 +0xC7 0x0433 # 0 +0xC8 0x0445 # 0 +0xC9 0x0438 # 0 +0xCA 0x0439 # 0 +0xCB 0x043A # 0 +0xCC 0x043B # 0 +0xCD 0x043C # 0 +0xCE 0x043D # 0 +0xCF 0x043E # 0 +0xD0 0x043F # 0 +0xD1 0x044F # 0 +0xD2 0x0440 # 0 +0xD3 0x0441 # 0 +0xD4 0x0442 # 0 +0xD5 0x0443 # 0 +0xD6 0x0436 # 0 +0xD7 0x0432 # 0 +0xD8 0x044C # 0 +0xD9 0x044B # 0 +0xDA 0x0437 # 0 +0xDB 0x0448 # 0 +0xDC 0x044D # 0 +0xDD 0x0449 # 0 +0xDE 0x0447 # 0 +0xDF 0x044A # 0 +0xE0 0x042E # 0 +0xE1 0x0410 # 0 +0xE2 0x0411 # 0 +0xE3 0x0426 # 0 +0xE4 0x0414 # 0 +0xE5 0x0415 # 0 +0xE6 0x0424 # 0 +0xE7 0x0413 # 0 +0xE8 0x0425 # 0 +0xE9 0x0418 # 0 +0xEA 0x0419 # 0 +0xEB 0x041A # 0 +0xEC 0x041B # 0 +0xED 0x041C # 0 +0xEE 0x041D # 0 +0xEF 0x041E # 0 +0xF0 0x041F # 0 +0xF1 0x042F # 0 +0xF2 0x0420 # 0 +0xF3 0x0421 # 0 +0xF4 0x0422 # 0 +0xF5 0x0423 # 0 +0xF6 0x0416 # 0 +0xF7 0x0412 # 0 +0xF8 0x042C # 0 +0xF9 0x042B # 0 +0xFA 0x0417 # 0 +0xFB 0x0428 # 0 +0xFC 0x042D # 0 +0xFD 0x0429 # 0 +0xFE 0x0427 # 0 +0xFF 0x042A # 0 diff --git a/data/label.h b/data/label.h new file mode 100644 index 0000000000..4b6fba64ff --- /dev/null +++ b/data/label.h @@ -0,0 +1,28 @@ +/* + * "$Id$" + * + * This file contains model number definitions for the CUPS sample + * label printer driver. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#define DYMO_3x0 0 /* Dymo Labelwriter 300/330/330 Turbo */ + +#define ZEBRA_EPL_LINE 0x10 /* Zebra EPL line mode printers */ +#define ZEBRA_EPL_PAGE 0x11 /* Zebra EPL page mode printers */ +#define ZEBRA_ZPL 0x12 /* Zebra ZPL-based printers */ +#define ZEBRA_CPCL 0x13 /* Zebra CPCL-based printers */ + +#define INTELLITECH_PCL 0x20 /* Intellitech PCL-based printers */ + +/* + * End of "$Id$". + */ diff --git a/data/mac-roman.txt b/data/mac-roman.txt new file mode 100644 index 0000000000..6e68beac5d --- /dev/null +++ b/data/mac-roman.txt @@ -0,0 +1,223 @@ +0x20 0x0020 # SPACE +0x21 0x0021 # EXCLAMATION MARK +0x22 0x0022 # QUOTATION MARK +0x23 0x0023 # NUMBER SIGN +0x24 0x0024 # DOLLAR SIGN +0x25 0x0025 # PERCENT SIGN +0x26 0x0026 # AMPERSAND +0x27 0x0027 # APOSTROPHE +0x28 0x0028 # LEFT PARENTHESIS +0x29 0x0029 # RIGHT PARENTHESIS +0x2A 0x002A # ASTERISK +0x2B 0x002B # PLUS SIGN +0x2C 0x002C # COMMA +0x2D 0x002D # HYPHEN-MINUS +0x2E 0x002E # FULL STOP +0x2F 0x002F # SOLIDUS +0x30 0x0030 # DIGIT ZERO +0x31 0x0031 # DIGIT ONE +0x32 0x0032 # DIGIT TWO +0x33 0x0033 # DIGIT THREE +0x34 0x0034 # DIGIT FOUR +0x35 0x0035 # DIGIT FIVE +0x36 0x0036 # DIGIT SIX +0x37 0x0037 # DIGIT SEVEN +0x38 0x0038 # DIGIT EIGHT +0x39 0x0039 # DIGIT NINE +0x3A 0x003A # COLON +0x3B 0x003B # SEMICOLON +0x3C 0x003C # LESS-THAN SIGN +0x3D 0x003D # EQUALS SIGN +0x3E 0x003E # GREATER-THAN SIGN +0x3F 0x003F # QUESTION MARK +0x40 0x0040 # COMMERCIAL AT +0x41 0x0041 # LATIN CAPITAL LETTER A +0x42 0x0042 # LATIN CAPITAL LETTER B +0x43 0x0043 # LATIN CAPITAL LETTER C +0x44 0x0044 # LATIN CAPITAL LETTER D +0x45 0x0045 # LATIN CAPITAL LETTER E +0x46 0x0046 # LATIN CAPITAL LETTER F +0x47 0x0047 # LATIN CAPITAL LETTER G +0x48 0x0048 # LATIN CAPITAL LETTER H +0x49 0x0049 # LATIN CAPITAL LETTER I +0x4A 0x004A # LATIN CAPITAL LETTER J +0x4B 0x004B # LATIN CAPITAL LETTER K +0x4C 0x004C # LATIN CAPITAL LETTER L +0x4D 0x004D # LATIN CAPITAL LETTER M +0x4E 0x004E # LATIN CAPITAL LETTER N +0x4F 0x004F # LATIN CAPITAL LETTER O +0x50 0x0050 # LATIN CAPITAL LETTER P +0x51 0x0051 # LATIN CAPITAL LETTER Q +0x52 0x0052 # LATIN CAPITAL LETTER R +0x53 0x0053 # LATIN CAPITAL LETTER S +0x54 0x0054 # LATIN CAPITAL LETTER T +0x55 0x0055 # LATIN CAPITAL LETTER U +0x56 0x0056 # LATIN CAPITAL LETTER V +0x57 0x0057 # LATIN CAPITAL LETTER W +0x58 0x0058 # LATIN CAPITAL LETTER X +0x59 0x0059 # LATIN CAPITAL LETTER Y +0x5A 0x005A # LATIN CAPITAL LETTER Z +0x5B 0x005B # LEFT SQUARE BRACKET +0x5C 0x005C # REVERSE SOLIDUS +0x5D 0x005D # RIGHT SQUARE BRACKET +0x5E 0x005E # CIRCUMFLEX ACCENT +0x5F 0x005F # LOW LINE +0x60 0x0060 # GRAVE ACCENT +0x61 0x0061 # LATIN SMALL LETTER A +0x62 0x0062 # LATIN SMALL LETTER B +0x63 0x0063 # LATIN SMALL LETTER C +0x64 0x0064 # LATIN SMALL LETTER D +0x65 0x0065 # LATIN SMALL LETTER E +0x66 0x0066 # LATIN SMALL LETTER F +0x67 0x0067 # LATIN SMALL LETTER G +0x68 0x0068 # LATIN SMALL LETTER H +0x69 0x0069 # LATIN SMALL LETTER I +0x6A 0x006A # LATIN SMALL LETTER J +0x6B 0x006B # LATIN SMALL LETTER K +0x6C 0x006C # LATIN SMALL LETTER L +0x6D 0x006D # LATIN SMALL LETTER M +0x6E 0x006E # LATIN SMALL LETTER N +0x6F 0x006F # LATIN SMALL LETTER O +0x70 0x0070 # LATIN SMALL LETTER P +0x71 0x0071 # LATIN SMALL LETTER Q +0x72 0x0072 # LATIN SMALL LETTER R +0x73 0x0073 # LATIN SMALL LETTER S +0x74 0x0074 # LATIN SMALL LETTER T +0x75 0x0075 # LATIN SMALL LETTER U +0x76 0x0076 # LATIN SMALL LETTER V +0x77 0x0077 # LATIN SMALL LETTER W +0x78 0x0078 # LATIN SMALL LETTER X +0x79 0x0079 # LATIN SMALL LETTER Y +0x7A 0x007A # LATIN SMALL LETTER Z +0x7B 0x007B # LEFT CURLY BRACKET +0x7C 0x007C # VERTICAL LINE +0x7D 0x007D # RIGHT CURLY BRACKET +0x7E 0x007E # TILDE +0x80 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS +0x81 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE +0x82 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA +0x83 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE +0x84 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE +0x85 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS +0x86 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS +0x87 0x00E1 # LATIN SMALL LETTER A WITH ACUTE +0x88 0x00E0 # LATIN SMALL LETTER A WITH GRAVE +0x89 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX +0x8A 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS +0x8B 0x00E3 # LATIN SMALL LETTER A WITH TILDE +0x8C 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE +0x8D 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA +0x8E 0x00E9 # LATIN SMALL LETTER E WITH ACUTE +0x8F 0x00E8 # LATIN SMALL LETTER E WITH GRAVE +0x90 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX +0x91 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS +0x92 0x00ED # LATIN SMALL LETTER I WITH ACUTE +0x93 0x00EC # LATIN SMALL LETTER I WITH GRAVE +0x94 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX +0x95 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS +0x96 0x00F1 # LATIN SMALL LETTER N WITH TILDE +0x97 0x00F3 # LATIN SMALL LETTER O WITH ACUTE +0x98 0x00F2 # LATIN SMALL LETTER O WITH GRAVE +0x99 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX +0x9A 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS +0x9B 0x00F5 # LATIN SMALL LETTER O WITH TILDE +0x9C 0x00FA # LATIN SMALL LETTER U WITH ACUTE +0x9D 0x00F9 # LATIN SMALL LETTER U WITH GRAVE +0x9E 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX +0x9F 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS +0xA0 0x2020 # DAGGER +0xA1 0x00B0 # DEGREE SIGN +0xA2 0x00A2 # CENT SIGN +0xA3 0x00A3 # POUND SIGN +0xA4 0x00A7 # SECTION SIGN +0xA5 0x2022 # BULLET +0xA6 0x00B6 # PILCROW SIGN +0xA7 0x00DF # LATIN SMALL LETTER SHARP S +0xA8 0x00AE # REGISTERED SIGN +0xA9 0x00A9 # COPYRIGHT SIGN +0xAA 0x2122 # TRADE MARK SIGN +0xAB 0x00B4 # ACUTE ACCENT +0xAC 0x00A8 # DIAERESIS +0xAD 0x2260 # NOT EQUAL TO +0xAE 0x00C6 # LATIN CAPITAL LETTER AE +0xAF 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE +0xB0 0x221E # INFINITY +0xB1 0x00B1 # PLUS-MINUS SIGN +0xB2 0x2264 # LESS-THAN OR EQUAL TO +0xB3 0x2265 # GREATER-THAN OR EQUAL TO +0xB4 0x00A5 # YEN SIGN +0xB5 0x00B5 # MICRO SIGN +0xB6 0x2202 # PARTIAL DIFFERENTIAL +0xB7 0x2211 # N-ARY SUMMATION +0xB8 0x220F # N-ARY PRODUCT +0xB9 0x03C0 # GREEK SMALL LETTER PI +0xBA 0x222B # INTEGRAL +0xBB 0x00AA # FEMININE ORDINAL INDICATOR +0xBC 0x00BA # MASCULINE ORDINAL INDICATOR +0xBD 0x2126 # OHM SIGN +0xBE 0x00E6 # LATIN SMALL LETTER AE +0xBF 0x00F8 # LATIN SMALL LETTER O WITH STROKE +0xC0 0x00BF # INVERTED QUESTION MARK +0xC1 0x00A1 # INVERTED EXCLAMATION MARK +0xC2 0x00AC # NOT SIGN +0xC3 0x221A # SQUARE ROOT +0xC4 0x0192 # LATIN SMALL LETTER F WITH HOOK +0xC5 0x2248 # ALMOST EQUAL TO +0xC6 0x2206 # INCREMENT +0xC7 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC8 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xC9 0x2026 # HORIZONTAL ELLIPSIS +0xCA 0x00A0 # NO-BREAK SPACE +0xCB 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE +0xCC 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE +0xCD 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE +0xCE 0x0152 # LATIN CAPITAL LIGATURE OE +0xCF 0x0153 # LATIN SMALL LIGATURE OE +0xD0 0x2013 # EN DASH +0xD1 0x2014 # EM DASH +0xD2 0x201C # LEFT DOUBLE QUOTATION MARK +0xD3 0x201D # RIGHT DOUBLE QUOTATION MARK +0xD4 0x2018 # LEFT SINGLE QUOTATION MARK +0xD5 0x2019 # RIGHT SINGLE QUOTATION MARK +0xD6 0x00F7 # DIVISION SIGN +0xD7 0x25CA # LOZENGE +0xD8 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS +0xD9 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS +0xDA 0x2044 # FRACTION SLASH +0xDB 0x00A4 # CURRENCY SIGN +0xDC 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0xDD 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0xDE 0xFB01 # LATIN SMALL LIGATURE FI +0xDF 0xFB02 # LATIN SMALL LIGATURE FL +0xE0 0x2021 # DOUBLE DAGGER +0xE1 0x00B7 # MIDDLE DOT +0xE2 0x201A # SINGLE LOW-9 QUOTATION MARK +0xE3 0x201E # DOUBLE LOW-9 QUOTATION MARK +0xE4 0x2030 # PER MILLE SIGN +0xE5 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xE6 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xE7 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE +0xE8 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS +0xE9 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE +0xEA 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE +0xEB 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xEC 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS +0xED 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE +0xEE 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE +0xEF 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xF0 0x2665 # BLACK HEART SUIT +0xF1 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE +0xF2 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE +0xF3 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xF4 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE +0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I +0xF6 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT +0xF7 0x02DC # SMALL TILDE +0xF8 0x00AF # MACRON +0xF9 0x02D8 # BREVE +0xFA 0x02D9 # DOT ABOVE +0xFB 0x02DA # RING ABOVE +0xFC 0x00B8 # CEDILLA +0xFD 0x02DD # DOUBLE ACUTE ACCENT +0xFE 0x02DB # OGONEK +0xFF 0x02C7 # CARON diff --git a/data/media.defs b/data/media.defs new file mode 100644 index 0000000000..88036937d9 --- /dev/null +++ b/data/media.defs @@ -0,0 +1,206 @@ +/* + * "$Id: media.defs 343 2007-07-13 19:52:48Z mike $" + * + * Adobe standard media size definitions for the CUPS PPD file compiler. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These codedinstructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * copyright law. Distribution and use rights are outlinedin the file + * "LICENSE.txt" which should have beenincluded with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#media "10x11/10 x 11\"" 720 792 +#media "10x13/10 x 13\"" 720 936 +#media "10x14/10 x 14\"" 720 1008 +#media "12x11/12 x 11\"" 864 792 +#media "15x11/15 x 11\"" 1080 792 +#media "7x9/7 x 9\"" 504 648 +#media "8x10/8 x 10\"" 576 720 +#media "9x11/9 x 11\"" 648 792 +#media "9x12/9 x 12\"" 648 864 +#media "A0/A0" 2384 3370 +#media "A0.Transverse/A0" 3370 2384 +#media "A1/A1" 1684 2384 +#media "A1.Transverse/A1" 2384 1684 +#media "A2/A2" 1191 1684 +#media "A2.Transverse/A2" 1684 1191 +#media "A3/A3" 842 1191 +#media "A3.Transverse/A3" 1191 842 +#media "A3Extra/A3 (Oversize)" 913 1262 +#media "A3Extra.Transverse/A3 (Oversize)" 913 1262 +#media "A3Rotated/A3" 1191 842 +#media "A4/A4" 595 842 +#media "A4Extra/A4 (Oversize)" 667 914 +#media "A4Plus/A4 (Oversize)" 595 936 +#media "A4Rotated/A4" 842 595 +#media "A4Small/A4 (Small)" 595 842 +#media "A4.Transverse/A4" 842 595 +#media "A5/A5" 420 595 +#media "A5Extra/A5 (Oversize)" 492 668 +#media "A5Rotated/A5" 595 420 +#media "A5.Transverse/A5" 595 420 +#media "A6/A6" 297 420 +#media "A6Rotated/A6" 420 297 +#media "A7/A7" 210 297 +#media "A8/A8" 148 210 +#media "A9/A9" 105 148 +#media "A10/A10" 73 105 +#media "AnsiA/ANSI A" 612 792 +#media "AnsiB/ANSI B" 792 1224 +#media "AnsiC/ANSI C" 1224 1584 +#media "AnsiD/ANSI D" 1584 2448 +#media "AnsiE/ANSI E" 2448 3168 +#media "ARCHA/ARCH A" 648 864 +#media "ARCHA.Transverse/ARCH A" 864 648 +#media "ARCHB/ARCH B" 864 1296 +#media "ARCHB.Transverse/ARCH B" 1296 864 +#media "ARCHC/ARCH C" 1296 1728 +#media "ARCHC.Transverse/ARCH C" 1728 1296 +#media "ARCHD/ARCH D" 1728 2592 +#media "ARCHD.Transverse/ARCH D" 2592 1728 +#media "ARCHE/ARCH E" 2592 3456 +#media "ARCHE.Transverse/ARCH E" 3456 2592 +#media "B0/B0" 2920 4127 +#media "B10/B10" 91 127 +#media "B1/B1" 2064 2918 +#media "B1/B1" 2064 2920 +#media "B2/B2" 1460 2064 +#media "B3/B3" 1032 1460 +#media "B4/B4" 729 1032 +#media "B4Rotated/B4" 1032 729 +#media "B5/B5" 516 729 +#media "B5Rotated/B5" 729 516 +#media "B5.Transverse/B5" 516 729 +#media "B6/B6" 363 516 +#media "B6Rotated/B6" 516 363 +#media "B7/B7" 258 363 +#media "B8/B8" 181 258 +#media "B9/B9" 127 181 +#media "C4/C4" 649 918 +#media "C5/C5" 459 649 +#media "C6/C6" 323 459 +#media "DL/DL" 312 624 +#media "DoublePostcard/Double Postcard" 567 420 +#media "DoublePostcardRotated/Double Postcard" 420 567 +#media "Env10/#10 Envelope" 297 684 +#media "Env11/#11 Envelope" 324 747 +#media "Env12/#12 Envelope" 342 792 +#media "Env14/#14 Envelope" 360 828 +#media "Env9/#9 Envelope" 279 639 +#media "EnvC0/C0 Envelope" 2599 3676 +#media "EnvC1/C1 Envelope" 1837 2599 +#media "EnvC2/C2 Envelope" 1298 1837 +#media "EnvC3/C3 Envelope" 918 1296 +#media "EnvC4/C4 Envelope" 649 918 +#media "EnvC5/C5 Envelope" 459 649 +#media "EnvC65/C65 Envelope" 324 648 +#media "EnvC6/C6 Envelope" 323 459 +#media "EnvC7/C7 Envelope" 230 323 +#media "EnvChou3/Chou3 Envelope" 340 666 +#media "EnvChou3Rotated/Chou3 Envelope" 666 340 +#media "EnvChou4/Chou4 Envelope" 255 581 +#media "EnvChou4Rotated/Chou4 Envelope" 581 255 +#media "EnvDL/DL Envelope" 312 624 +#media "EnvInvite/Invite Envelope" 624 624 +#media "EnvISOB4/ISO B4 Envelope" 708 1001 +#media "EnvISOB5/ISO B5 Envelope" 499 709 +#media "EnvISOB6/ISO B6 Envelope" 499 354 +#media "EnvItalian/Italian Envelope" 312 652 +#media "EnvKaku2/Kaku2 Envelope" 680 941 +#media "EnvKaku2Rotated/Kaku2 Envelope" 941 680 +#media "EnvKaku3/Kaku3 Envelope" 612 785 +#media "EnvKaku3Rotated/Kaku3 Envelope" 785 612 +#media "EnvMonarch/Monarch Envelope" 279 540 +#media "EnvPersonal/Personal Envelope" 261 468 +#media "EnvPRC1/PRC1 Envelope" 289 468 +#media "EnvPRC1Rotated/PRC1 Envelope" 468 289 +#media "EnvPRC2/PRC2 Envelope" 289 499 +#media "EnvPRC2Rotated/PRC2 Envelope" 499 289 +#media "EnvPRC3/PRC3 Envelope" 354 499 +#media "EnvPRC3Rotated/PRC3 Envelope" 499 354 +#media "EnvPRC4/PRC4 Envelope" 312 590 +#media "EnvPRC4Rotated/PRC4 Envelope" 590 312 +#media "EnvPRC5/PRC5 Envelope" 312 624 +#media "EnvPRC5Rotated/PRC5 Envelope" 624 312 +#media "EnvPRC6/PRC6 Envelope" 340 652 +#media "EnvPRC6Rotated/PRC6 Envelope" 652 340 +#media "EnvPRC7/PRC7 Envelope" 454 652 +#media "EnvPRC7Rotated/PRC7 Envelope" 652 454 +#media "EnvPRC8/PRC8 Envelope" 340 876 +#media "EnvPRC8Rotated/PRC8 Envelope" 876 340 +#media "EnvPRC9/PRC9 Envelope" 649 918 +#media "EnvPRC9Rotated/PRC9 Envelope" 918 649 +#media "EnvPRC10/PRC10 Envelope" 918 1298 +#media "EnvPRC10Rotated/PRC10 Envelope" 1298 918 +#media "EnvYou4/You4 Envelope" 298 666 +#media "EnvYou4Rotated/You4 Envelope" 666 298 +#media "Executive/US Executive" 522 756 +#media "FanFoldGerman/German FanFold" 612 864 +#media "FanFoldGermanLegal/German FanFold Legal" 612 936 +#media "FanFoldUS/US Fanfold" 1071 792 +#media "Folio/Folio" 595 935 +#media "ISOB0/ISO B0" 2835 4008 +#media "ISOB1/ISO B1" 2004 2835 +#media "ISOB2/ISO B2" 1417 2004 +#media "ISOB3/ISO B3" 1001 1417 +#media "ISOB4/ISO B4" 709 1001 +#media "ISOB5/ISO B5" 499 709 +#media "ISOB5Extra/ISO B5 (Oversize)" 570 782 +#media "ISOB6/ISO B6" 354 499 +#media "ISOB7/ISO B7" 249 354 +#media "ISOB8/ISO B8" 176 249 +#media "ISOB9/ISO B9" 125 176 +#media "ISOB10/ISO B10" 88 125 +#media "Ledger/US Ledger" 1224 792 +#media "Legal/US Legal" 612 1008 +#media "LegalExtra/US Legal (Oversize)" 684 1080 +#media "Letter/US Letter" 612 792 +#media "Letter.Transverse/US Letter" 792 612 +#media "LetterExtra/US Letter (Oversize)" 684 864 +#media "LetterExtra.Transverse/US Letter (Oversize)" 864 684 +#media "LetterPlus/US Letter (Oversize)" 612 914 +#media "LetterRotated/US Letter" 792 612 +#media "LetterSmall/US Letter (Small)" 612 792 +#media "Monarch/Monarch" 279 540 +#media "Note/Note" 612 792 +#media "Postcard/Postcard" 284 419 +#media "PostcardRotated/Postcard" 419 284 +#media "PRC16K/PRC16K" 414 610 +#media "PRC16KRotated/PRC16K" 610 414 +#media "PRC32K/PRC32K" 275 428 +#media "PRC32KBig/PRC32K (Oversize)" 275 428 +#media "PRC32KBigRotated/PRC32K (Oversize)" 428 275 +#media "PRC32KRotated/PRC32K" 428 275 +#media "Quarto/Quarto" 610 780 +#media "Statement/Statement" 396 612 +#media "SuperA/Super A" 643 1009 +#media "SuperB/Super B" 864 1380 +#media "Tabloid/Tabloid" 792 1224 +#media "TabloidExtra/Tabloid (Oversize)" 864 1296 + +/* + * Non-standard sizes... + */ + +#media "Photo4x6/Photo" 288 432 +#media "PhotoLabel/Photo Labels" 288 468 +#media "w288h418/Photo" 288 418 +#media "w936h1368/Super B/A3" 936 1368 +#media "w81h252/Address" 81 252 +#media "w101h252/Large Address" 101 252 +#media "w54h144/Return Address" 54 144 +#media "w167h288/Shipping Address" 167 288 +#media "w162h540/Internet Postage 2-Part" 162 540 +#media "w162h504/Internet Postage 3-Part" 162 504 +#media "w41h248/File Folder" 41 248 +#media "w41h144/Hanging Folder" 41 144 +#media "w153h198/3.5\" Disk" 153 198 + + +/* + * End of "$Id: media.defs 343 2007-07-13 19:52:48Z mike $". + */ diff --git a/data/pcl.h b/data/pcl.h new file mode 100644 index 0000000000..0cb1effe5c --- /dev/null +++ b/data/pcl.h @@ -0,0 +1,38 @@ +/* + * "$Id$" + * + * This file contains model number definitions for the CUPS unified + * PCL driver. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* General PCL Support */ +#define PCL_PAPER_SIZE 0x1 /* Use ESC&l#A */ +#define PCL_INKJET 0x2 /* Use inkjet commands */ + +/* Raster Support */ +#define PCL_RASTER_END_COLOR 0x100 /* Use ESC*rC */ +#define PCL_RASTER_CID 0x200 /* Use ESC*v#W */ +#define PCL_RASTER_CRD 0x400 /* Use ESC*g#W */ +#define PCL_RASTER_SIMPLE 0x800 /* Use ESC*r#U */ +#define PCL_RASTER_RGB24 0x1000 /* Use 24-bit RGB mode */ + +/* PJL Support */ +#define PCL_PJL 0x10000 /* Use PJL Commands */ +#define PCL_PJL_PAPERWIDTH 0x20000 /* Use PJL PAPERWIDTH/LENGTH */ +#define PCL_PJL_HPGL2 0x40000 /* Enter HPGL2 */ +#define PCL_PJL_PCL3GUI 0x80000 /* Enter PCL3GUI */ +#define PCL_PJL_RESOLUTION 0x100000 /* Use PJL SET RESOLUTION */ + + +/* + * End of "$Id$". + */ diff --git a/data/psglyphs b/data/psglyphs new file mode 100644 index 0000000000..c4a902c66c --- /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 minus +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 hyphen +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/raster.defs b/data/raster.defs new file mode 100644 index 0000000000..486165f012 --- /dev/null +++ b/data/raster.defs @@ -0,0 +1,94 @@ +/* + * "$Id: raster.defs 343 2007-07-13 19:52:48Z mike $" + * + * This file contains the standard definitions for enumerated attributes + * in the CUPS raster page device dictionary. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* Jog values */ +#define CUPS_JOG_NONE 0 /* Never move pages */ +#define CUPS_JOG_FILE 1 /* Move pages after this file */ +#define CUPS_JOG_JOB 2 /* Move pages after this job */ +#define CUPS_JOG_SET 3 /* Move pages after this set */ + +/* Orientation values */ +#define CUPS_ORIENT_0 0 /* Don't rotate the page */ +#define CUPS_ORIENT_90 1 /* Rotate the page counter-clockwise */ +#define CUPS_ORIENT_180 2 /* Turn the page upside down */ +#define CUPS_ORIENT_270 3 /* Rotate the page clockwise */ + +/* CutMedia values */ +#define CUPS_CUT_NONE 0 /* Never cut the roll */ +#define CUPS_CUT_FILE 1 /* Cut the roll after this file */ +#define CUPS_CUT_JOB 2 /* Cut the roll after this job */ +#define CUPS_CUT_SET 3 /* Cut the roll after this set */ +#define CUPS_CUT_PAGE 4 /* Cut the roll after this page */ + +/* AdvanceMedia values */ +#define CUPS_ADVANCE_NONE 0 /* Never advance the roll */ +#define CUPS_ADVANCE_FILE 1 /* Advance the roll after this file */ +#define CUPS_ADVANCE_JOB 2 /* Advance the roll after this job */ +#define CUPS_ADVANCE_SET 3 /* Advance the roll after this set */ +#define CUPS_ADVANCE_PAGE 4 /* Advance the roll after this page */ + +/* LeadingEdge values */ +#define CUPS_EDGE_TOP 0 /* Leading edge is the top of the page */ +#define CUPS_EDGE_RIGHT 1 /* Leading edge is the right of the page */ +#define CUPS_EDGE_BOTTOM 2 /* Leading edge is the bottom of the page */ +#define CUPS_EDGE_LEFT 3 /* Leading edge is the left of the page */ + +/* cupsColorOrder values */ +#define CUPS_ORDER_CHUNKED 0 /* CMYK CMYK CMYK ... */ +#define CUPS_ORDER_BANDED 1 /* CCC MMM YYY KKK ... */ +#define CUPS_ORDER_PLANAR 2 /* CCC ... MMM ... YYY ... KKK ... */ + +/* cupsColorSpace values */ +#define CUPS_CSPACE_W 0 /* Luminance */ +#define CUPS_CSPACE_RGB 1 /* Red, green, blue */ +#define CUPS_CSPACE_RGBA 2 /* Red, green, blue, alpha */ +#define CUPS_CSPACE_K 3 /* Black */ +#define CUPS_CSPACE_CMY 4 /* Cyan, magenta, yellow */ +#define CUPS_CSPACE_YMC 5 /* Yellow, magenta, cyan */ +#define CUPS_CSPACE_CMYK 6 /* Cyan, magenta, yellow, black */ +#define CUPS_CSPACE_YMCK 7 /* Yellow, magenta, cyan, black */ +#define CUPS_CSPACE_KCMY 8 /* Black, cyan, magenta, yellow */ +#define CUPS_CSPACE_KCMYcm 9 /* Black, cyan, magenta, yellow, * + * light-cyan, light-magenta */ +#define CUPS_CSPACE_GMCK 10 /* Gold, magenta, yellow, black */ +#define CUPS_CSPACE_GMCS 11 /* Gold, magenta, yellow, silver */ +#define CUPS_CSPACE_WHITE 12 /* White ink (as black) */ +#define CUPS_CSPACE_GOLD 13 /* Gold foil */ +#define CUPS_CSPACE_SILVER 14 /* Silver foil */ + +#define CUPS_CSPACE_CIEXYZ 15 /* CIE XYZ */ +#define CUPS_CSPACE_CIELab 16 /* CIE Lab */ + +#define CUPS_CSPACE_ICC1 32 /* ICC-based, 1 color */ +#define CUPS_CSPACE_ICC2 33 /* ICC-based, 2 colors */ +#define CUPS_CSPACE_ICC3 34 /* ICC-based, 3 colors */ +#define CUPS_CSPACE_ICC4 35 /* ICC-based, 4 colors */ +#define CUPS_CSPACE_ICC5 36 /* ICC-based, 5 colors */ +#define CUPS_CSPACE_ICC6 37 /* ICC-based, 6 colors */ +#define CUPS_CSPACE_ICC7 38 /* ICC-based, 7 colors */ +#define CUPS_CSPACE_ICC8 39 /* ICC-based, 8 colors */ +#define CUPS_CSPACE_ICC9 40 /* ICC-based, 9 colors */ +#define CUPS_CSPACE_ICCA 41 /* ICC-based, 10 colors */ +#define CUPS_CSPACE_ICCB 42 /* ICC-based, 11 colors */ +#define CUPS_CSPACE_ICCC 43 /* ICC-based, 12 colors */ +#define CUPS_CSPACE_ICCD 44 /* ICC-based, 13 colors */ +#define CUPS_CSPACE_ICCE 45 /* ICC-based, 14 colors */ +#define CUPS_CSPACE_ICCF 46 /* ICC-based, 15 colors */ + + +/* + * End of "$Id: raster.defs 343 2007-07-13 19:52:48Z mike $". + */ diff --git a/data/secret b/data/secret new file mode 100644 index 0000000000..66a0e8a919 --- /dev/null +++ b/data/secret @@ -0,0 +1,6 @@ +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Secret +Footer Secret +Image images/cups.png + diff --git a/data/smiley.ps b/data/smiley.ps new file mode 100644 index 0000000000..6ff31fdfbe --- /dev/null +++ b/data/smiley.ps @@ -0,0 +1,28 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 36 36 576 756 +%%Pages: 1 +%%LanguageLevel: 2 +%%EndComments +%%Page: (1) 1 +% Draw a black box around the page +0 setgray +1 setlinewidth +36 36 540 720 rectstroke + +% Draw a two inch blue circle in the middle of the page +0 0 1 setrgbcolor +306 396 144 0 360 arc closepath fill + +% Draw two half inch yellow circles for eyes +1 1 0 setrgbcolor +252 432 36 0 360 arc closepath fill +360 432 36 0 360 arc closepath fill + +% Draw the smile +1 setlinecap +18 setlinewidth +306 396 99 200 340 arc stroke + +% Print it! +showpage +%%EOF diff --git a/data/standard b/data/standard new file mode 100644 index 0000000000..31c68a08ed --- /dev/null +++ b/data/standard @@ -0,0 +1,6 @@ +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Cover Page +Footer Cover Page +Image images/cups.png + diff --git a/data/testprint.in b/data/testprint.in new file mode 100644 index 0000000000..5eff731400 --- /dev/null +++ b/data/testprint.in @@ -0,0 +1,8 @@ +#CUPS-BANNER +Show printer-name printer-info printer-location printer-make-and-model printer-driver-name printer-driver-version paper-size imageable-area +Header Printer Test Page +Footer Printer Test Page +Notice This test page was produced by CUPS @CUPS_VERSION@. +Image images/cups.png +Image images/color-wheel.png + diff --git a/data/topsecret b/data/topsecret new file mode 100644 index 0000000000..d2b87fabb9 --- /dev/null +++ b/data/topsecret @@ -0,0 +1,6 @@ +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Top Secret +Footer Top Secret +Image images/cups.png + diff --git a/data/unclassified b/data/unclassified new file mode 100644 index 0000000000..2d1a7d0f97 --- /dev/null +++ b/data/unclassified @@ -0,0 +1,6 @@ +#CUPS-BANNER +Show job-id job-name job-originating-user-name job-originating-host-name job-billing +Header Unclassified +Footer Unclassified +Image images/cups.png + diff --git a/data/utf-8 b/data/utf-8 new file mode 100644 index 0000000000..044691b46d --- /dev/null +++ b/data/utf-8 @@ -0,0 +1,40 @@ +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 Monospace 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. +# +# 1000 10ff ltor single Monospace +# +# Each font that is listed will be downloaded to the printer when used. +# + +0000 00FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +0100 01FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +0200 02FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +0300 03FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +0400 04FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +1E00 1EFF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +2000 20FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +2300 23FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +2400 24FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +2500 25FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique +2600 26FF ltor single Monospace Monospace-Bold Monospace-Oblique Monospace-BoldOblique diff --git a/data/windows-1250.txt b/data/windows-1250.txt new file mode 100644 index 0000000000..081d7763b3 --- /dev/null +++ b/data/windows-1250.txt @@ -0,0 +1,274 @@ +# +# Name: cp1250 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1250 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1250 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 #UNDEFINED +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 #UNDEFINED +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x015A #LATIN CAPITAL LETTER S WITH ACUTE +0x8D 0x0164 #LATIN CAPITAL LETTER T WITH CARON +0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON +0x8F 0x0179 #LATIN CAPITAL LETTER Z WITH ACUTE +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x015B #LATIN SMALL LETTER S WITH ACUTE +0x9D 0x0165 #LATIN SMALL LETTER T WITH CARON +0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON +0x9F 0x017A #LATIN SMALL LETTER Z WITH ACUTE +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x02C7 #CARON +0xA2 0x02D8 #BREVE +0xA3 0x0141 #LATIN CAPITAL LETTER L WITH STROKE +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x0104 #LATIN CAPITAL LETTER A WITH OGONEK +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x015E #LATIN CAPITAL LETTER S WITH CEDILLA +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x017B #LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x02DB #OGONEK +0xB3 0x0142 #LATIN SMALL LETTER L WITH STROKE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x0105 #LATIN SMALL LETTER A WITH OGONEK +0xBA 0x015F #LATIN SMALL LETTER S WITH CEDILLA +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x013D #LATIN CAPITAL LETTER L WITH CARON +0xBD 0x02DD #DOUBLE ACUTE ACCENT +0xBE 0x013E #LATIN SMALL LETTER L WITH CARON +0xBF 0x017C #LATIN SMALL LETTER Z WITH DOT ABOVE +0xC0 0x0154 #LATIN CAPITAL LETTER R WITH ACUTE +0xC1 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 #LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x0139 #LATIN CAPITAL LETTER L WITH ACUTE +0xC6 0x0106 #LATIN CAPITAL LETTER C WITH ACUTE +0xC7 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x010C #LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0118 #LATIN CAPITAL LETTER E WITH OGONEK +0xCB 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x011A #LATIN CAPITAL LETTER E WITH CARON +0xCD 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x010E #LATIN CAPITAL LETTER D WITH CARON +0xD0 0x0110 #LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x0143 #LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0147 #LATIN CAPITAL LETTER N WITH CARON +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x0150 #LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x0158 #LATIN CAPITAL LETTER R WITH CARON +0xD9 0x016E #LATIN CAPITAL LETTER U WITH RING ABOVE +0xDA 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x0170 #LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x0162 #LATIN CAPITAL LETTER T WITH CEDILLA +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x0155 #LATIN SMALL LETTER R WITH ACUTE +0xE1 0x00E1 #LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 #LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x013A #LATIN SMALL LETTER L WITH ACUTE +0xE6 0x0107 #LATIN SMALL LETTER C WITH ACUTE +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x010D #LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x0119 #LATIN SMALL LETTER E WITH OGONEK +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x011B #LATIN SMALL LETTER E WITH CARON +0xED 0x00ED #LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x010F #LATIN SMALL LETTER D WITH CARON +0xF0 0x0111 #LATIN SMALL LETTER D WITH STROKE +0xF1 0x0144 #LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0148 #LATIN SMALL LETTER N WITH CARON +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x0151 #LATIN SMALL LETTER O WITH DOUBLE ACUTE +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x0159 #LATIN SMALL LETTER R WITH CARON +0xF9 0x016F #LATIN SMALL LETTER U WITH RING ABOVE +0xFA 0x00FA #LATIN SMALL LETTER U WITH ACUTE +0xFB 0x0171 #LATIN SMALL LETTER U WITH DOUBLE ACUTE +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x0163 #LATIN SMALL LETTER T WITH CEDILLA +0xFF 0x02D9 #DOT ABOVE diff --git a/data/windows-1251.txt b/data/windows-1251.txt new file mode 100644 index 0000000000..37eadbdbc9 --- /dev/null +++ b/data/windows-1251.txt @@ -0,0 +1,274 @@ +# +# Name: cp1251 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1251 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1251 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x0402 #CYRILLIC CAPITAL LETTER DJE +0x81 0x0403 #CYRILLIC CAPITAL LETTER GJE +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0453 #CYRILLIC SMALL LETTER GJE +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x20AC #EURO SIGN +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0409 #CYRILLIC CAPITAL LETTER LJE +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x040A #CYRILLIC CAPITAL LETTER NJE +0x8D 0x040C #CYRILLIC CAPITAL LETTER KJE +0x8E 0x040B #CYRILLIC CAPITAL LETTER TSHE +0x8F 0x040F #CYRILLIC CAPITAL LETTER DZHE +0x90 0x0452 #CYRILLIC SMALL LETTER DJE +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0459 #CYRILLIC SMALL LETTER LJE +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x045A #CYRILLIC SMALL LETTER NJE +0x9D 0x045C #CYRILLIC SMALL LETTER KJE +0x9E 0x045B #CYRILLIC SMALL LETTER TSHE +0x9F 0x045F #CYRILLIC SMALL LETTER DZHE +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x040E #CYRILLIC CAPITAL LETTER SHORT U +0xA2 0x045E #CYRILLIC SMALL LETTER SHORT U +0xA3 0x0408 #CYRILLIC CAPITAL LETTER JE +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x0490 #CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x0401 #CYRILLIC CAPITAL LETTER IO +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x0407 #CYRILLIC CAPITAL LETTER YI +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x0406 #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0xB3 0x0456 #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0xB4 0x0491 #CYRILLIC SMALL LETTER GHE WITH UPTURN +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x0451 #CYRILLIC SMALL LETTER IO +0xB9 0x2116 #NUMERO SIGN +0xBA 0x0454 #CYRILLIC SMALL LETTER UKRAINIAN IE +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x0458 #CYRILLIC SMALL LETTER JE +0xBD 0x0405 #CYRILLIC CAPITAL LETTER DZE +0xBE 0x0455 #CYRILLIC SMALL LETTER DZE +0xBF 0x0457 #CYRILLIC SMALL LETTER YI +0xC0 0x0410 #CYRILLIC CAPITAL LETTER A +0xC1 0x0411 #CYRILLIC CAPITAL LETTER BE +0xC2 0x0412 #CYRILLIC CAPITAL LETTER VE +0xC3 0x0413 #CYRILLIC CAPITAL LETTER GHE +0xC4 0x0414 #CYRILLIC CAPITAL LETTER DE +0xC5 0x0415 #CYRILLIC CAPITAL LETTER IE +0xC6 0x0416 #CYRILLIC CAPITAL LETTER ZHE +0xC7 0x0417 #CYRILLIC CAPITAL LETTER ZE +0xC8 0x0418 #CYRILLIC CAPITAL LETTER I +0xC9 0x0419 #CYRILLIC CAPITAL LETTER SHORT I +0xCA 0x041A #CYRILLIC CAPITAL LETTER KA +0xCB 0x041B #CYRILLIC CAPITAL LETTER EL +0xCC 0x041C #CYRILLIC CAPITAL LETTER EM +0xCD 0x041D #CYRILLIC CAPITAL LETTER EN +0xCE 0x041E #CYRILLIC CAPITAL LETTER O +0xCF 0x041F #CYRILLIC CAPITAL LETTER PE +0xD0 0x0420 #CYRILLIC CAPITAL LETTER ER +0xD1 0x0421 #CYRILLIC CAPITAL LETTER ES +0xD2 0x0422 #CYRILLIC CAPITAL LETTER TE +0xD3 0x0423 #CYRILLIC CAPITAL LETTER U +0xD4 0x0424 #CYRILLIC CAPITAL LETTER EF +0xD5 0x0425 #CYRILLIC CAPITAL LETTER HA +0xD6 0x0426 #CYRILLIC CAPITAL LETTER TSE +0xD7 0x0427 #CYRILLIC CAPITAL LETTER CHE +0xD8 0x0428 #CYRILLIC CAPITAL LETTER SHA +0xD9 0x0429 #CYRILLIC CAPITAL LETTER SHCHA +0xDA 0x042A #CYRILLIC CAPITAL LETTER HARD SIGN +0xDB 0x042B #CYRILLIC CAPITAL LETTER YERU +0xDC 0x042C #CYRILLIC CAPITAL LETTER SOFT SIGN +0xDD 0x042D #CYRILLIC CAPITAL LETTER E +0xDE 0x042E #CYRILLIC CAPITAL LETTER YU +0xDF 0x042F #CYRILLIC CAPITAL LETTER YA +0xE0 0x0430 #CYRILLIC SMALL LETTER A +0xE1 0x0431 #CYRILLIC SMALL LETTER BE +0xE2 0x0432 #CYRILLIC SMALL LETTER VE +0xE3 0x0433 #CYRILLIC SMALL LETTER GHE +0xE4 0x0434 #CYRILLIC SMALL LETTER DE +0xE5 0x0435 #CYRILLIC SMALL LETTER IE +0xE6 0x0436 #CYRILLIC SMALL LETTER ZHE +0xE7 0x0437 #CYRILLIC SMALL LETTER ZE +0xE8 0x0438 #CYRILLIC SMALL LETTER I +0xE9 0x0439 #CYRILLIC SMALL LETTER SHORT I +0xEA 0x043A #CYRILLIC SMALL LETTER KA +0xEB 0x043B #CYRILLIC SMALL LETTER EL +0xEC 0x043C #CYRILLIC SMALL LETTER EM +0xED 0x043D #CYRILLIC SMALL LETTER EN +0xEE 0x043E #CYRILLIC SMALL LETTER O +0xEF 0x043F #CYRILLIC SMALL LETTER PE +0xF0 0x0440 #CYRILLIC SMALL LETTER ER +0xF1 0x0441 #CYRILLIC SMALL LETTER ES +0xF2 0x0442 #CYRILLIC SMALL LETTER TE +0xF3 0x0443 #CYRILLIC SMALL LETTER U +0xF4 0x0444 #CYRILLIC SMALL LETTER EF +0xF5 0x0445 #CYRILLIC SMALL LETTER HA +0xF6 0x0446 #CYRILLIC SMALL LETTER TSE +0xF7 0x0447 #CYRILLIC SMALL LETTER CHE +0xF8 0x0448 #CYRILLIC SMALL LETTER SHA +0xF9 0x0449 #CYRILLIC SMALL LETTER SHCHA +0xFA 0x044A #CYRILLIC SMALL LETTER HARD SIGN +0xFB 0x044B #CYRILLIC SMALL LETTER YERU +0xFC 0x044C #CYRILLIC SMALL LETTER SOFT SIGN +0xFD 0x044D #CYRILLIC SMALL LETTER E +0xFE 0x044E #CYRILLIC SMALL LETTER YU +0xFF 0x044F #CYRILLIC SMALL LETTER YA diff --git a/data/windows-1252.txt b/data/windows-1252.txt new file mode 100644 index 0000000000..2ca4486eb8 --- /dev/null +++ b/data/windows-1252.txt @@ -0,0 +1,274 @@ +# +# Name: cp1252 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1252 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1252 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +0x8D #UNDEFINED +0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 0x02DC #SMALL TILDE +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x0153 #LATIN SMALL LIGATURE OE +0x9D #UNDEFINED +0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON +0x9F 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x00A1 #INVERTED EXCLAMATION MARK +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x00AA #FEMININE ORDINAL INDICATOR +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00AF #MACRON +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x00BA #MASCULINE ORDINAL INDICATOR +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF #INVERTED QUESTION MARK +0xC0 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 #LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 #LATIN CAPITAL LETTER AE +0xC7 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC #LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x00D0 #LATIN CAPITAL LETTER ETH +0xD1 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 #LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE +0xDE 0x00DE #LATIN CAPITAL LETTER THORN +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x00E0 #LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 #LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 #LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 #LATIN SMALL LETTER AE +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 #LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC #LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED #LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x00F0 #LATIN SMALL LETTER ETH +0xF1 0x00F1 #LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 #LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 #LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x00F8 #LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 #LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA #LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE +0xFE 0x00FE #LATIN SMALL LETTER THORN +0xFF 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/data/windows-1253.txt b/data/windows-1253.txt new file mode 100644 index 0000000000..2ba51a0c8f --- /dev/null +++ b/data/windows-1253.txt @@ -0,0 +1,274 @@ +# +# Name: cp1253 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1253 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1253 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 #UNDEFINED +0x89 0x2030 #PER MILLE SIGN +0x8A #UNDEFINED +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C #UNDEFINED +0x8D #UNDEFINED +0x8E #UNDEFINED +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 0x2122 #TRADE MARK SIGN +0x9A #UNDEFINED +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C #UNDEFINED +0x9D #UNDEFINED +0x9E #UNDEFINED +0x9F #UNDEFINED +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x0385 #GREEK DIALYTIKA TONOS +0xA2 0x0386 #GREEK CAPITAL LETTER ALPHA WITH TONOS +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA #UNDEFINED +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x2015 #HORIZONTAL BAR +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x0384 #GREEK TONOS +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x0388 #GREEK CAPITAL LETTER EPSILON WITH TONOS +0xB9 0x0389 #GREEK CAPITAL LETTER ETA WITH TONOS +0xBA 0x038A #GREEK CAPITAL LETTER IOTA WITH TONOS +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x038C #GREEK CAPITAL LETTER OMICRON WITH TONOS +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x038E #GREEK CAPITAL LETTER UPSILON WITH TONOS +0xBF 0x038F #GREEK CAPITAL LETTER OMEGA WITH TONOS +0xC0 0x0390 #GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0xC1 0x0391 #GREEK CAPITAL LETTER ALPHA +0xC2 0x0392 #GREEK CAPITAL LETTER BETA +0xC3 0x0393 #GREEK CAPITAL LETTER GAMMA +0xC4 0x0394 #GREEK CAPITAL LETTER DELTA +0xC5 0x0395 #GREEK CAPITAL LETTER EPSILON +0xC6 0x0396 #GREEK CAPITAL LETTER ZETA +0xC7 0x0397 #GREEK CAPITAL LETTER ETA +0xC8 0x0398 #GREEK CAPITAL LETTER THETA +0xC9 0x0399 #GREEK CAPITAL LETTER IOTA +0xCA 0x039A #GREEK CAPITAL LETTER KAPPA +0xCB 0x039B #GREEK CAPITAL LETTER LAMDA +0xCC 0x039C #GREEK CAPITAL LETTER MU +0xCD 0x039D #GREEK CAPITAL LETTER NU +0xCE 0x039E #GREEK CAPITAL LETTER XI +0xCF 0x039F #GREEK CAPITAL LETTER OMICRON +0xD0 0x03A0 #GREEK CAPITAL LETTER PI +0xD1 0x03A1 #GREEK CAPITAL LETTER RHO +0xD2 #UNDEFINED +0xD3 0x03A3 #GREEK CAPITAL LETTER SIGMA +0xD4 0x03A4 #GREEK CAPITAL LETTER TAU +0xD5 0x03A5 #GREEK CAPITAL LETTER UPSILON +0xD6 0x03A6 #GREEK CAPITAL LETTER PHI +0xD7 0x03A7 #GREEK CAPITAL LETTER CHI +0xD8 0x03A8 #GREEK CAPITAL LETTER PSI +0xD9 0x03A9 #GREEK CAPITAL LETTER OMEGA +0xDA 0x03AA #GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +0xDB 0x03AB #GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +0xDC 0x03AC #GREEK SMALL LETTER ALPHA WITH TONOS +0xDD 0x03AD #GREEK SMALL LETTER EPSILON WITH TONOS +0xDE 0x03AE #GREEK SMALL LETTER ETA WITH TONOS +0xDF 0x03AF #GREEK SMALL LETTER IOTA WITH TONOS +0xE0 0x03B0 #GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +0xE1 0x03B1 #GREEK SMALL LETTER ALPHA +0xE2 0x03B2 #GREEK SMALL LETTER BETA +0xE3 0x03B3 #GREEK SMALL LETTER GAMMA +0xE4 0x03B4 #GREEK SMALL LETTER DELTA +0xE5 0x03B5 #GREEK SMALL LETTER EPSILON +0xE6 0x03B6 #GREEK SMALL LETTER ZETA +0xE7 0x03B7 #GREEK SMALL LETTER ETA +0xE8 0x03B8 #GREEK SMALL LETTER THETA +0xE9 0x03B9 #GREEK SMALL LETTER IOTA +0xEA 0x03BA #GREEK SMALL LETTER KAPPA +0xEB 0x03BB #GREEK SMALL LETTER LAMDA +0xEC 0x03BC #GREEK SMALL LETTER MU +0xED 0x03BD #GREEK SMALL LETTER NU +0xEE 0x03BE #GREEK SMALL LETTER XI +0xEF 0x03BF #GREEK SMALL LETTER OMICRON +0xF0 0x03C0 #GREEK SMALL LETTER PI +0xF1 0x03C1 #GREEK SMALL LETTER RHO +0xF2 0x03C2 #GREEK SMALL LETTER FINAL SIGMA +0xF3 0x03C3 #GREEK SMALL LETTER SIGMA +0xF4 0x03C4 #GREEK SMALL LETTER TAU +0xF5 0x03C5 #GREEK SMALL LETTER UPSILON +0xF6 0x03C6 #GREEK SMALL LETTER PHI +0xF7 0x03C7 #GREEK SMALL LETTER CHI +0xF8 0x03C8 #GREEK SMALL LETTER PSI +0xF9 0x03C9 #GREEK SMALL LETTER OMEGA +0xFA 0x03CA #GREEK SMALL LETTER IOTA WITH DIALYTIKA +0xFB 0x03CB #GREEK SMALL LETTER UPSILON WITH DIALYTIKA +0xFC 0x03CC #GREEK SMALL LETTER OMICRON WITH TONOS +0xFD 0x03CD #GREEK SMALL LETTER UPSILON WITH TONOS +0xFE 0x03CE #GREEK SMALL LETTER OMEGA WITH TONOS +0xFF #UNDEFINED diff --git a/data/windows-1254.txt b/data/windows-1254.txt new file mode 100644 index 0000000000..ca1a1ebdb8 --- /dev/null +++ b/data/windows-1254.txt @@ -0,0 +1,274 @@ +# +# Name: cp1254 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1254 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1254 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +0x8D #UNDEFINED +0x8E #UNDEFINED +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 0x02DC #SMALL TILDE +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x0153 #LATIN SMALL LIGATURE OE +0x9D #UNDEFINED +0x9E #UNDEFINED +0x9F 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x00A1 #INVERTED EXCLAMATION MARK +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x00AA #FEMININE ORDINAL INDICATOR +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00AF #MACRON +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x00BA #MASCULINE ORDINAL INDICATOR +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF #INVERTED QUESTION MARK +0xC0 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x00C3 #LATIN CAPITAL LETTER A WITH TILDE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 #LATIN CAPITAL LETTER AE +0xC7 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x00CC #LATIN CAPITAL LETTER I WITH GRAVE +0xCD 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x011E #LATIN CAPITAL LETTER G WITH BREVE +0xD1 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x00D2 #LATIN CAPITAL LETTER O WITH GRAVE +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x0130 #LATIN CAPITAL LETTER I WITH DOT ABOVE +0xDE 0x015E #LATIN CAPITAL LETTER S WITH CEDILLA +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x00E0 #LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 #LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x00E3 #LATIN SMALL LETTER A WITH TILDE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 #LATIN SMALL LETTER AE +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 #LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x00EC #LATIN SMALL LETTER I WITH GRAVE +0xED 0x00ED #LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x011F #LATIN SMALL LETTER G WITH BREVE +0xF1 0x00F1 #LATIN SMALL LETTER N WITH TILDE +0xF2 0x00F2 #LATIN SMALL LETTER O WITH GRAVE +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x00F5 #LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x00F8 #LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 #LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA #LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x0131 #LATIN SMALL LETTER DOTLESS I +0xFE 0x015F #LATIN SMALL LETTER S WITH CEDILLA +0xFF 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/data/windows-1255.txt b/data/windows-1255.txt new file mode 100644 index 0000000000..341517f119 --- /dev/null +++ b/data/windows-1255.txt @@ -0,0 +1,274 @@ +# +# Name: cp1255 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 1/7/2000 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1255 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1255 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x89 0x2030 #PER MILLE SIGN +0x8A #UNDEFINED +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C #UNDEFINED +0x8D #UNDEFINED +0x8E #UNDEFINED +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 0x02DC #SMALL TILDE +0x99 0x2122 #TRADE MARK SIGN +0x9A #UNDEFINED +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C #UNDEFINED +0x9D #UNDEFINED +0x9E #UNDEFINED +0x9F #UNDEFINED +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x00A1 #INVERTED EXCLAMATION MARK +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x20AA #NEW SHEQEL SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x00D7 #MULTIPLICATION SIGN +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00AF #MACRON +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x00F7 #DIVISION SIGN +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF #INVERTED QUESTION MARK +0xC0 0x05B0 #HEBREW POINT SHEVA +0xC1 0x05B1 #HEBREW POINT HATAF SEGOL +0xC2 0x05B2 #HEBREW POINT HATAF PATAH +0xC3 0x05B3 #HEBREW POINT HATAF QAMATS +0xC4 0x05B4 #HEBREW POINT HIRIQ +0xC5 0x05B5 #HEBREW POINT TSERE +0xC6 0x05B6 #HEBREW POINT SEGOL +0xC7 0x05B7 #HEBREW POINT PATAH +0xC8 0x05B8 #HEBREW POINT QAMATS +0xC9 0x05B9 #HEBREW POINT HOLAM +0xCA #UNDEFINED +0xCB 0x05BB #HEBREW POINT QUBUTS +0xCC 0x05BC #HEBREW POINT DAGESH OR MAPIQ +0xCD 0x05BD #HEBREW POINT METEG +0xCE 0x05BE #HEBREW PUNCTUATION MAQAF +0xCF 0x05BF #HEBREW POINT RAFE +0xD0 0x05C0 #HEBREW PUNCTUATION PASEQ +0xD1 0x05C1 #HEBREW POINT SHIN DOT +0xD2 0x05C2 #HEBREW POINT SIN DOT +0xD3 0x05C3 #HEBREW PUNCTUATION SOF PASUQ +0xD4 0x05F0 #HEBREW LIGATURE YIDDISH DOUBLE VAV +0xD5 0x05F1 #HEBREW LIGATURE YIDDISH VAV YOD +0xD6 0x05F2 #HEBREW LIGATURE YIDDISH DOUBLE YOD +0xD7 0x05F3 #HEBREW PUNCTUATION GERESH +0xD8 0x05F4 #HEBREW PUNCTUATION GERSHAYIM +0xD9 #UNDEFINED +0xDA #UNDEFINED +0xDB #UNDEFINED +0xDC #UNDEFINED +0xDD #UNDEFINED +0xDE #UNDEFINED +0xDF #UNDEFINED +0xE0 0x05D0 #HEBREW LETTER ALEF +0xE1 0x05D1 #HEBREW LETTER BET +0xE2 0x05D2 #HEBREW LETTER GIMEL +0xE3 0x05D3 #HEBREW LETTER DALET +0xE4 0x05D4 #HEBREW LETTER HE +0xE5 0x05D5 #HEBREW LETTER VAV +0xE6 0x05D6 #HEBREW LETTER ZAYIN +0xE7 0x05D7 #HEBREW LETTER HET +0xE8 0x05D8 #HEBREW LETTER TET +0xE9 0x05D9 #HEBREW LETTER YOD +0xEA 0x05DA #HEBREW LETTER FINAL KAF +0xEB 0x05DB #HEBREW LETTER KAF +0xEC 0x05DC #HEBREW LETTER LAMED +0xED 0x05DD #HEBREW LETTER FINAL MEM +0xEE 0x05DE #HEBREW LETTER MEM +0xEF 0x05DF #HEBREW LETTER FINAL NUN +0xF0 0x05E0 #HEBREW LETTER NUN +0xF1 0x05E1 #HEBREW LETTER SAMEKH +0xF2 0x05E2 #HEBREW LETTER AYIN +0xF3 0x05E3 #HEBREW LETTER FINAL PE +0xF4 0x05E4 #HEBREW LETTER PE +0xF5 0x05E5 #HEBREW LETTER FINAL TSADI +0xF6 0x05E6 #HEBREW LETTER TSADI +0xF7 0x05E7 #HEBREW LETTER QOF +0xF8 0x05E8 #HEBREW LETTER RESH +0xF9 0x05E9 #HEBREW LETTER SHIN +0xFA 0x05EA #HEBREW LETTER TAV +0xFB #UNDEFINED +0xFC #UNDEFINED +0xFD 0x200E #LEFT-TO-RIGHT MARK +0xFE 0x200F #RIGHT-TO-LEFT MARK +0xFF #UNDEFINED diff --git a/data/windows-1256.txt b/data/windows-1256.txt new file mode 100644 index 0000000000..0edd081b92 --- /dev/null +++ b/data/windows-1256.txt @@ -0,0 +1,274 @@ +# +# Name: cp1256 to Unicode table +# Unicode version: 2.1 +# Table version: 2.01 +# Table format: Format A +# Date: 01/5/99 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1256 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1256 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 0x067E #ARABIC LETTER PEH +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x89 0x2030 #PER MILLE SIGN +0x8A 0x0679 #ARABIC LETTER TTEH +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +0x8D 0x0686 #ARABIC LETTER TCHEH +0x8E 0x0698 #ARABIC LETTER JEH +0x8F 0x0688 #ARABIC LETTER DDAL +0x90 0x06AF #ARABIC LETTER GAF +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 0x06A9 #ARABIC LETTER KEHEH +0x99 0x2122 #TRADE MARK SIGN +0x9A 0x0691 #ARABIC LETTER RREH +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x0153 #LATIN SMALL LIGATURE OE +0x9D 0x200C #ZERO WIDTH NON-JOINER +0x9E 0x200D #ZERO WIDTH JOINER +0x9F 0x06BA #ARABIC LETTER NOON GHUNNA +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x060C #ARABIC COMMA +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x06BE #ARABIC LETTER HEH DOACHASHMEE +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00AF #MACRON +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x061B #ARABIC SEMICOLON +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x061F #ARABIC QUESTION MARK +0xC0 0x06C1 #ARABIC LETTER HEH GOAL +0xC1 0x0621 #ARABIC LETTER HAMZA +0xC2 0x0622 #ARABIC LETTER ALEF WITH MADDA ABOVE +0xC3 0x0623 #ARABIC LETTER ALEF WITH HAMZA ABOVE +0xC4 0x0624 #ARABIC LETTER WAW WITH HAMZA ABOVE +0xC5 0x0625 #ARABIC LETTER ALEF WITH HAMZA BELOW +0xC6 0x0626 #ARABIC LETTER YEH WITH HAMZA ABOVE +0xC7 0x0627 #ARABIC LETTER ALEF +0xC8 0x0628 #ARABIC LETTER BEH +0xC9 0x0629 #ARABIC LETTER TEH MARBUTA +0xCA 0x062A #ARABIC LETTER TEH +0xCB 0x062B #ARABIC LETTER THEH +0xCC 0x062C #ARABIC LETTER JEEM +0xCD 0x062D #ARABIC LETTER HAH +0xCE 0x062E #ARABIC LETTER KHAH +0xCF 0x062F #ARABIC LETTER DAL +0xD0 0x0630 #ARABIC LETTER THAL +0xD1 0x0631 #ARABIC LETTER REH +0xD2 0x0632 #ARABIC LETTER ZAIN +0xD3 0x0633 #ARABIC LETTER SEEN +0xD4 0x0634 #ARABIC LETTER SHEEN +0xD5 0x0635 #ARABIC LETTER SAD +0xD6 0x0636 #ARABIC LETTER DAD +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x0637 #ARABIC LETTER TAH +0xD9 0x0638 #ARABIC LETTER ZAH +0xDA 0x0639 #ARABIC LETTER AIN +0xDB 0x063A #ARABIC LETTER GHAIN +0xDC 0x0640 #ARABIC TATWEEL +0xDD 0x0641 #ARABIC LETTER FEH +0xDE 0x0642 #ARABIC LETTER QAF +0xDF 0x0643 #ARABIC LETTER KAF +0xE0 0x00E0 #LATIN SMALL LETTER A WITH GRAVE +0xE1 0x0644 #ARABIC LETTER LAM +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0645 #ARABIC LETTER MEEM +0xE4 0x0646 #ARABIC LETTER NOON +0xE5 0x0647 #ARABIC LETTER HEH +0xE6 0x0648 #ARABIC LETTER WAW +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 #LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x0649 #ARABIC LETTER ALEF MAKSURA +0xED 0x064A #ARABIC LETTER YEH +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x064B #ARABIC FATHATAN +0xF1 0x064C #ARABIC DAMMATAN +0xF2 0x064D #ARABIC KASRATAN +0xF3 0x064E #ARABIC FATHA +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x064F #ARABIC DAMMA +0xF6 0x0650 #ARABIC KASRA +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x0651 #ARABIC SHADDA +0xF9 0x00F9 #LATIN SMALL LETTER U WITH GRAVE +0xFA 0x0652 #ARABIC SUKUN +0xFB 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x200E #LEFT-TO-RIGHT MARK +0xFE 0x200F #RIGHT-TO-LEFT MARK +0xFF 0x06D2 #ARABIC LETTER YEH BARREE diff --git a/data/windows-1257.txt b/data/windows-1257.txt new file mode 100644 index 0000000000..97979d9319 --- /dev/null +++ b/data/windows-1257.txt @@ -0,0 +1,274 @@ +# +# Name: cp1257 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1257 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1257 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 #UNDEFINED +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 #UNDEFINED +0x89 0x2030 #PER MILLE SIGN +0x8A #UNDEFINED +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C #UNDEFINED +0x8D 0x00A8 #DIAERESIS +0x8E 0x02C7 #CARON +0x8F 0x00B8 #CEDILLA +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 0x2122 #TRADE MARK SIGN +0x9A #UNDEFINED +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C #UNDEFINED +0x9D 0x00AF #MACRON +0x9E 0x02DB #OGONEK +0x9F #UNDEFINED +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 #UNDEFINED +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 #UNDEFINED +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x0156 #LATIN CAPITAL LETTER R WITH CEDILLA +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00C6 #LATIN CAPITAL LETTER AE +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00F8 #LATIN SMALL LETTER O WITH STROKE +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x0157 #LATIN SMALL LETTER R WITH CEDILLA +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x00E6 #LATIN SMALL LETTER AE +0xC0 0x0104 #LATIN CAPITAL LETTER A WITH OGONEK +0xC1 0x012E #LATIN CAPITAL LETTER I WITH OGONEK +0xC2 0x0100 #LATIN CAPITAL LETTER A WITH MACRON +0xC3 0x0106 #LATIN CAPITAL LETTER C WITH ACUTE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x0118 #LATIN CAPITAL LETTER E WITH OGONEK +0xC7 0x0112 #LATIN CAPITAL LETTER E WITH MACRON +0xC8 0x010C #LATIN CAPITAL LETTER C WITH CARON +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x0179 #LATIN CAPITAL LETTER Z WITH ACUTE +0xCB 0x0116 #LATIN CAPITAL LETTER E WITH DOT ABOVE +0xCC 0x0122 #LATIN CAPITAL LETTER G WITH CEDILLA +0xCD 0x0136 #LATIN CAPITAL LETTER K WITH CEDILLA +0xCE 0x012A #LATIN CAPITAL LETTER I WITH MACRON +0xCF 0x013B #LATIN CAPITAL LETTER L WITH CEDILLA +0xD0 0x0160 #LATIN CAPITAL LETTER S WITH CARON +0xD1 0x0143 #LATIN CAPITAL LETTER N WITH ACUTE +0xD2 0x0145 #LATIN CAPITAL LETTER N WITH CEDILLA +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x014C #LATIN CAPITAL LETTER O WITH MACRON +0xD5 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x0172 #LATIN CAPITAL LETTER U WITH OGONEK +0xD9 0x0141 #LATIN CAPITAL LETTER L WITH STROKE +0xDA 0x015A #LATIN CAPITAL LETTER S WITH ACUTE +0xDB 0x016A #LATIN CAPITAL LETTER U WITH MACRON +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x017B #LATIN CAPITAL LETTER Z WITH DOT ABOVE +0xDE 0x017D #LATIN CAPITAL LETTER Z WITH CARON +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x0105 #LATIN SMALL LETTER A WITH OGONEK +0xE1 0x012F #LATIN SMALL LETTER I WITH OGONEK +0xE2 0x0101 #LATIN SMALL LETTER A WITH MACRON +0xE3 0x0107 #LATIN SMALL LETTER C WITH ACUTE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x0119 #LATIN SMALL LETTER E WITH OGONEK +0xE7 0x0113 #LATIN SMALL LETTER E WITH MACRON +0xE8 0x010D #LATIN SMALL LETTER C WITH CARON +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x017A #LATIN SMALL LETTER Z WITH ACUTE +0xEB 0x0117 #LATIN SMALL LETTER E WITH DOT ABOVE +0xEC 0x0123 #LATIN SMALL LETTER G WITH CEDILLA +0xED 0x0137 #LATIN SMALL LETTER K WITH CEDILLA +0xEE 0x012B #LATIN SMALL LETTER I WITH MACRON +0xEF 0x013C #LATIN SMALL LETTER L WITH CEDILLA +0xF0 0x0161 #LATIN SMALL LETTER S WITH CARON +0xF1 0x0144 #LATIN SMALL LETTER N WITH ACUTE +0xF2 0x0146 #LATIN SMALL LETTER N WITH CEDILLA +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x014D #LATIN SMALL LETTER O WITH MACRON +0xF5 0x00F5 #LATIN SMALL LETTER O WITH TILDE +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x0173 #LATIN SMALL LETTER U WITH OGONEK +0xF9 0x0142 #LATIN SMALL LETTER L WITH STROKE +0xFA 0x015B #LATIN SMALL LETTER S WITH ACUTE +0xFB 0x016B #LATIN SMALL LETTER U WITH MACRON +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x017C #LATIN SMALL LETTER Z WITH DOT ABOVE +0xFE 0x017E #LATIN SMALL LETTER Z WITH CARON +0xFF 0x02D9 #DOT ABOVE diff --git a/data/windows-1258.txt b/data/windows-1258.txt new file mode 100644 index 0000000000..392310a8ca --- /dev/null +++ b/data/windows-1258.txt @@ -0,0 +1,274 @@ +# +# Name: cp1258 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 04/15/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp1258 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp1258 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 0x201A #SINGLE LOW-9 QUOTATION MARK +0x83 0x0192 #LATIN SMALL LETTER F WITH HOOK +0x84 0x201E #DOUBLE LOW-9 QUOTATION MARK +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 0x2020 #DAGGER +0x87 0x2021 #DOUBLE DAGGER +0x88 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT +0x89 0x2030 #PER MILLE SIGN +0x8A #UNDEFINED +0x8B 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +0x8D #UNDEFINED +0x8E #UNDEFINED +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 0x02DC #SMALL TILDE +0x99 0x2122 #TRADE MARK SIGN +0x9A #UNDEFINED +0x9B 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x9C 0x0153 #LATIN SMALL LIGATURE OE +0x9D #UNDEFINED +0x9E #UNDEFINED +0x9F 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x00A1 #INVERTED EXCLAMATION MARK +0xA2 0x00A2 #CENT SIGN +0xA3 0x00A3 #POUND SIGN +0xA4 0x00A4 #CURRENCY SIGN +0xA5 0x00A5 #YEN SIGN +0xA6 0x00A6 #BROKEN BAR +0xA7 0x00A7 #SECTION SIGN +0xA8 0x00A8 #DIAERESIS +0xA9 0x00A9 #COPYRIGHT SIGN +0xAA 0x00AA #FEMININE ORDINAL INDICATOR +0xAB 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0xAC 0x00AC #NOT SIGN +0xAD 0x00AD #SOFT HYPHEN +0xAE 0x00AE #REGISTERED SIGN +0xAF 0x00AF #MACRON +0xB0 0x00B0 #DEGREE SIGN +0xB1 0x00B1 #PLUS-MINUS SIGN +0xB2 0x00B2 #SUPERSCRIPT TWO +0xB3 0x00B3 #SUPERSCRIPT THREE +0xB4 0x00B4 #ACUTE ACCENT +0xB5 0x00B5 #MICRO SIGN +0xB6 0x00B6 #PILCROW SIGN +0xB7 0x00B7 #MIDDLE DOT +0xB8 0x00B8 #CEDILLA +0xB9 0x00B9 #SUPERSCRIPT ONE +0xBA 0x00BA #MASCULINE ORDINAL INDICATOR +0xBB 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +0xBD 0x00BD #VULGAR FRACTION ONE HALF +0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +0xBF 0x00BF #INVERTED QUESTION MARK +0xC0 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE +0xC1 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE +0xC2 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0xC3 0x0102 #LATIN CAPITAL LETTER A WITH BREVE +0xC4 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS +0xC5 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE +0xC6 0x00C6 #LATIN CAPITAL LETTER AE +0xC7 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA +0xC8 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE +0xC9 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE +0xCA 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX +0xCB 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS +0xCC 0x0300 #COMBINING GRAVE ACCENT +0xCD 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE +0xCE 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0xCF 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS +0xD0 0x0110 #LATIN CAPITAL LETTER D WITH STROKE +0xD1 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE +0xD2 0x0309 #COMBINING HOOK ABOVE +0xD3 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE +0xD4 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0xD5 0x01A0 #LATIN CAPITAL LETTER O WITH HORN +0xD6 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS +0xD7 0x00D7 #MULTIPLICATION SIGN +0xD8 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE +0xD9 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE +0xDA 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE +0xDB 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX +0xDC 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS +0xDD 0x01AF #LATIN CAPITAL LETTER U WITH HORN +0xDE 0x0303 #COMBINING TILDE +0xDF 0x00DF #LATIN SMALL LETTER SHARP S +0xE0 0x00E0 #LATIN SMALL LETTER A WITH GRAVE +0xE1 0x00E1 #LATIN SMALL LETTER A WITH ACUTE +0xE2 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0xE3 0x0103 #LATIN SMALL LETTER A WITH BREVE +0xE4 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS +0xE5 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE +0xE6 0x00E6 #LATIN SMALL LETTER AE +0xE7 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA +0xE8 0x00E8 #LATIN SMALL LETTER E WITH GRAVE +0xE9 0x00E9 #LATIN SMALL LETTER E WITH ACUTE +0xEA 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX +0xEB 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS +0xEC 0x0301 #COMBINING ACUTE ACCENT +0xED 0x00ED #LATIN SMALL LETTER I WITH ACUTE +0xEE 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX +0xEF 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS +0xF0 0x0111 #LATIN SMALL LETTER D WITH STROKE +0xF1 0x00F1 #LATIN SMALL LETTER N WITH TILDE +0xF2 0x0323 #COMBINING DOT BELOW +0xF3 0x00F3 #LATIN SMALL LETTER O WITH ACUTE +0xF4 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0xF5 0x01A1 #LATIN SMALL LETTER O WITH HORN +0xF6 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS +0xF7 0x00F7 #DIVISION SIGN +0xF8 0x00F8 #LATIN SMALL LETTER O WITH STROKE +0xF9 0x00F9 #LATIN SMALL LETTER U WITH GRAVE +0xFA 0x00FA #LATIN SMALL LETTER U WITH ACUTE +0xFB 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX +0xFC 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS +0xFD 0x01B0 #LATIN SMALL LETTER U WITH HORN +0xFE 0x20AB #DONG SIGN +0xFF 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS diff --git a/data/windows-1361.txt b/data/windows-1361.txt new file mode 100644 index 0000000000..3024f5870f --- /dev/null +++ b/data/windows-1361.txt @@ -0,0 +1,17396 @@ +# cp1361.txt - Legacy to Unicode charmap +0x0000 0x0000 # 0 +0x0001 0x0001 # 0 +0x0002 0x0002 # 0 +0x0003 0x0003 # 0 +0x0004 0x0004 # 0 +0x0005 0x0005 # 0 +0x0006 0x0006 # 0 +0x0007 0x0007 # 0 +0x0008 0x0008 # 0 +0x0009 0x0009 # 0 +0x000A 0x000A # 0 +0x000B 0x000B # 0 +0x000C 0x000C # 0 +0x000D 0x000D # 0 +0x000E 0x000E # 0 +0x000F 0x000F # 0 +0x0010 0x0010 # 0 +0x0011 0x0011 # 0 +0x0012 0x0012 # 0 +0x0013 0x0013 # 0 +0x0014 0x0014 # 0 +0x0015 0x0015 # 0 +0x0016 0x0016 # 0 +0x0017 0x0017 # 0 +0x0018 0x0018 # 0 +0x0019 0x0019 # 0 +0x001A 0x001A # 0 +0x001B 0x001B # 0 +0x001C 0x001C # 0 +0x001D 0x001D # 0 +0x001E 0x001E # 0 +0x001F 0x001F # 0 +0x0020 0x0020 # 0 +0x0021 0x0021 # 0 +0x0022 0x0022 # 0 +0x0023 0x0023 # 0 +0x0024 0x0024 # 0 +0x0025 0x0025 # 0 +0x0026 0x0026 # 0 +0x0027 0x0027 # 0 +0x0028 0x0028 # 0 +0x0029 0x0029 # 0 +0x002A 0x002A # 0 +0x002B 0x002B # 0 +0x002C 0x002C # 0 +0x002D 0x002D # 0 +0x002E 0x002E # 0 +0x002F 0x002F # 0 +0x0030 0x0030 # 0 +0x0031 0x0031 # 0 +0x0032 0x0032 # 0 +0x0033 0x0033 # 0 +0x0034 0x0034 # 0 +0x0035 0x0035 # 0 +0x0036 0x0036 # 0 +0x0037 0x0037 # 0 +0x0038 0x0038 # 0 +0x0039 0x0039 # 0 +0x003A 0x003A # 0 +0x003B 0x003B # 0 +0x003C 0x003C # 0 +0x003D 0x003D # 0 +0x003E 0x003E # 0 +0x003F 0x003F # 0 +0x0040 0x0040 # 0 +0x0041 0x0041 # 0 +0x0042 0x0042 # 0 +0x0043 0x0043 # 0 +0x0044 0x0044 # 0 +0x0045 0x0045 # 0 +0x0046 0x0046 # 0 +0x0047 0x0047 # 0 +0x0048 0x0048 # 0 +0x0049 0x0049 # 0 +0x004A 0x004A # 0 +0x004B 0x004B # 0 +0x004C 0x004C # 0 +0x004D 0x004D # 0 +0x004E 0x004E # 0 +0x004F 0x004F # 0 +0x0050 0x0050 # 0 +0x0051 0x0051 # 0 +0x0052 0x0052 # 0 +0x0053 0x0053 # 0 +0x0054 0x0054 # 0 +0x0055 0x0055 # 0 +0x0056 0x0056 # 0 +0x0057 0x0057 # 0 +0x0058 0x0058 # 0 +0x0059 0x0059 # 0 +0x005A 0x005A # 0 +0x005B 0x005B # 0 +0x005C 0x005C # 0 +0x005D 0x005D # 0 +0x005E 0x005E # 0 +0x005F 0x005F # 0 +0x0060 0x0060 # 0 +0x0061 0x0061 # 0 +0x0062 0x0062 # 0 +0x0063 0x0063 # 0 +0x0064 0x0064 # 0 +0x0065 0x0065 # 0 +0x0066 0x0066 # 0 +0x0067 0x0067 # 0 +0x0068 0x0068 # 0 +0x0069 0x0069 # 0 +0x006A 0x006A # 0 +0x006B 0x006B # 0 +0x006C 0x006C # 0 +0x006D 0x006D # 0 +0x006E 0x006E # 0 +0x006F 0x006F # 0 +0x0070 0x0070 # 0 +0x0071 0x0071 # 0 +0x0072 0x0072 # 0 +0x0073 0x0073 # 0 +0x0074 0x0074 # 0 +0x0075 0x0075 # 0 +0x0076 0x0076 # 0 +0x0077 0x0077 # 0 +0x0078 0x0078 # 0 +0x0079 0x0079 # 0 +0x007A 0x007A # 0 +0x007B 0x007B # 0 +0x007C 0x007C # 0 +0x007D 0x007D # 0 +0x007E 0x007E # 0 +0x007F 0x007F # 0 +0x0080 0x0080 # 0 +0x0081 0x0081 # 0 +0x0082 0x0082 # 0 +0x0083 0x0083 # 0 +0x00D4 0xF8EC # 0 +0x00D5 0xF8ED # 0 +0x00D6 0xF8EE # 0 +0x00D7 0xF8EF # 0 +0x00DF 0xF8F0 # 0 +0x00FA 0xF8F1 # 0 +0x00FB 0xF8F2 # 0 +0x00FC 0xF8F3 # 0 +0x00FD 0xF8F4 # 0 +0x00FE 0xF8F5 # 0 +0x00FF 0xF8F6 # 0 +0x8442 0x11A8 # 0 +0x8443 0x11A9 # 0 +0x8444 0x11AA # 0 +0x8445 0x11AB # 0 +0x8446 0x11AC # 0 +0x8447 0x11AD # 0 +0x8448 0x11AE # 0 +0x8449 0x11AF # 0 +0x844A 0x11B0 # 0 +0x844B 0x11B1 # 0 +0x844C 0x11B2 # 0 +0x844D 0x11B3 # 0 +0x844E 0x11B4 # 0 +0x844F 0x11B5 # 0 +0x8450 0x11B6 # 0 +0x8451 0x11B7 # 0 +0x8453 0x11B8 # 0 +0x8454 0x11B9 # 0 +0x8455 0x11BA # 0 +0x8456 0x11BB # 0 +0x8457 0x11BC # 0 +0x8458 0x11BD # 0 +0x8459 0x11BE # 0 +0x845A 0x11BF # 0 +0x845B 0x11C0 # 0 +0x845C 0x11C1 # 0 +0x845D 0x11C2 # 0 +0x8461 0x1161 # 0 +0x8481 0x1162 # 0 +0x84A1 0x1163 # 0 +0x84C1 0x1164 # 0 +0x84E1 0x1165 # 0 +0x8541 0x1166 # 0 +0x8561 0x1167 # 0 +0x8581 0x1168 # 0 +0x85A1 0x1169 # 0 +0x85C1 0x116A # 0 +0x85E1 0x116B # 0 +0x8641 0x116C # 0 +0x8661 0x116D # 0 +0x8681 0x116E # 0 +0x86A1 0x116F # 0 +0x86C1 0x1170 # 0 +0x86E1 0x1171 # 0 +0x8741 0x1172 # 0 +0x8761 0x1173 # 0 +0x8781 0x1174 # 0 +0x87A1 0x1175 # 0 +0x8841 0x1100 # 0 +0x8861 0xAC00 # 0 +0x8862 0xAC01 # 0 +0x8863 0xAC02 # 0 +0x8864 0xAC03 # 0 +0x8865 0xAC04 # 0 +0x8866 0xAC05 # 0 +0x8867 0xAC06 # 0 +0x8868 0xAC07 # 0 +0x8869 0xAC08 # 0 +0x886A 0xAC09 # 0 +0x886B 0xAC0A # 0 +0x886C 0xAC0B # 0 +0x886D 0xAC0C # 0 +0x886E 0xAC0D # 0 +0x886F 0xAC0E # 0 +0x8870 0xAC0F # 0 +0x8871 0xAC10 # 0 +0x8873 0xAC11 # 0 +0x8874 0xAC12 # 0 +0x8875 0xAC13 # 0 +0x8876 0xAC14 # 0 +0x8877 0xAC15 # 0 +0x8878 0xAC16 # 0 +0x8879 0xAC17 # 0 +0x887A 0xAC18 # 0 +0x887B 0xAC19 # 0 +0x887C 0xAC1A # 0 +0x887D 0xAC1B # 0 +0x8881 0xAC1C # 0 +0x8882 0xAC1D # 0 +0x8883 0xAC1E # 0 +0x8884 0xAC1F # 0 +0x8885 0xAC20 # 0 +0x8886 0xAC21 # 0 +0x8887 0xAC22 # 0 +0x8888 0xAC23 # 0 +0x8889 0xAC24 # 0 +0x888A 0xAC25 # 0 +0x888B 0xAC26 # 0 +0x888C 0xAC27 # 0 +0x888D 0xAC28 # 0 +0x888E 0xAC29 # 0 +0x888F 0xAC2A # 0 +0x8890 0xAC2B # 0 +0x8891 0xAC2C # 0 +0x8893 0xAC2D # 0 +0x8894 0xAC2E # 0 +0x8895 0xAC2F # 0 +0x8896 0xAC30 # 0 +0x8897 0xAC31 # 0 +0x8898 0xAC32 # 0 +0x8899 0xAC33 # 0 +0x889A 0xAC34 # 0 +0x889B 0xAC35 # 0 +0x889C 0xAC36 # 0 +0x889D 0xAC37 # 0 +0x88A1 0xAC38 # 0 +0x88A2 0xAC39 # 0 +0x88A3 0xAC3A # 0 +0x88A4 0xAC3B # 0 +0x88A5 0xAC3C # 0 +0x88A6 0xAC3D # 0 +0x88A7 0xAC3E # 0 +0x88A8 0xAC3F # 0 +0x88A9 0xAC40 # 0 +0x88AA 0xAC41 # 0 +0x88AB 0xAC42 # 0 +0x88AC 0xAC43 # 0 +0x88AD 0xAC44 # 0 +0x88AE 0xAC45 # 0 +0x88AF 0xAC46 # 0 +0x88B0 0xAC47 # 0 +0x88B1 0xAC48 # 0 +0x88B3 0xAC49 # 0 +0x88B4 0xAC4A # 0 +0x88B5 0xAC4B # 0 +0x88B6 0xAC4C # 0 +0x88B7 0xAC4D # 0 +0x88B8 0xAC4E # 0 +0x88B9 0xAC4F # 0 +0x88BA 0xAC50 # 0 +0x88BB 0xAC51 # 0 +0x88BC 0xAC52 # 0 +0x88BD 0xAC53 # 0 +0x88C1 0xAC54 # 0 +0x88C2 0xAC55 # 0 +0x88C3 0xAC56 # 0 +0x88C4 0xAC57 # 0 +0x88C5 0xAC58 # 0 +0x88C6 0xAC59 # 0 +0x88C7 0xAC5A # 0 +0x88C8 0xAC5B # 0 +0x88C9 0xAC5C # 0 +0x88CA 0xAC5D # 0 +0x88CB 0xAC5E # 0 +0x88CC 0xAC5F # 0 +0x88CD 0xAC60 # 0 +0x88CE 0xAC61 # 0 +0x88CF 0xAC62 # 0 +0x88D0 0xAC63 # 0 +0x88D1 0xAC64 # 0 +0x88D3 0xAC65 # 0 +0x88D4 0xAC66 # 0 +0x88D5 0xAC67 # 0 +0x88D6 0xAC68 # 0 +0x88D7 0xAC69 # 0 +0x88D8 0xAC6A # 0 +0x88D9 0xAC6B # 0 +0x88DA 0xAC6C # 0 +0x88DB 0xAC6D # 0 +0x88DC 0xAC6E # 0 +0x88DD 0xAC6F # 0 +0x88E1 0xAC70 # 0 +0x88E2 0xAC71 # 0 +0x88E3 0xAC72 # 0 +0x88E4 0xAC73 # 0 +0x88E5 0xAC74 # 0 +0x88E6 0xAC75 # 0 +0x88E7 0xAC76 # 0 +0x88E8 0xAC77 # 0 +0x88E9 0xAC78 # 0 +0x88EA 0xAC79 # 0 +0x88EB 0xAC7A # 0 +0x88EC 0xAC7B # 0 +0x88ED 0xAC7C # 0 +0x88EE 0xAC7D # 0 +0x88EF 0xAC7E # 0 +0x88F0 0xAC7F # 0 +0x88F1 0xAC80 # 0 +0x88F3 0xAC81 # 0 +0x88F4 0xAC82 # 0 +0x88F5 0xAC83 # 0 +0x88F6 0xAC84 # 0 +0x88F7 0xAC85 # 0 +0x88F8 0xAC86 # 0 +0x88F9 0xAC87 # 0 +0x88FA 0xAC88 # 0 +0x88FB 0xAC89 # 0 +0x88FC 0xAC8A # 0 +0x88FD 0xAC8B # 0 +0x8941 0xAC8C # 0 +0x8942 0xAC8D # 0 +0x8943 0xAC8E # 0 +0x8944 0xAC8F # 0 +0x8945 0xAC90 # 0 +0x8946 0xAC91 # 0 +0x8947 0xAC92 # 0 +0x8948 0xAC93 # 0 +0x8949 0xAC94 # 0 +0x894A 0xAC95 # 0 +0x894B 0xAC96 # 0 +0x894C 0xAC97 # 0 +0x894D 0xAC98 # 0 +0x894E 0xAC99 # 0 +0x894F 0xAC9A # 0 +0x8950 0xAC9B # 0 +0x8951 0xAC9C # 0 +0x8953 0xAC9D # 0 +0x8954 0xAC9E # 0 +0x8955 0xAC9F # 0 +0x8956 0xACA0 # 0 +0x8957 0xACA1 # 0 +0x8958 0xACA2 # 0 +0x8959 0xACA3 # 0 +0x895A 0xACA4 # 0 +0x895B 0xACA5 # 0 +0x895C 0xACA6 # 0 +0x895D 0xACA7 # 0 +0x8961 0xACA8 # 0 +0x8962 0xACA9 # 0 +0x8963 0xACAA # 0 +0x8964 0xACAB # 0 +0x8965 0xACAC # 0 +0x8966 0xACAD # 0 +0x8967 0xACAE # 0 +0x8968 0xACAF # 0 +0x8969 0xACB0 # 0 +0x896A 0xACB1 # 0 +0x896B 0xACB2 # 0 +0x896C 0xACB3 # 0 +0x896D 0xACB4 # 0 +0x896E 0xACB5 # 0 +0x896F 0xACB6 # 0 +0x8970 0xACB7 # 0 +0x8971 0xACB8 # 0 +0x8973 0xACB9 # 0 +0x8974 0xACBA # 0 +0x8975 0xACBB # 0 +0x8976 0xACBC # 0 +0x8977 0xACBD # 0 +0x8978 0xACBE # 0 +0x8979 0xACBF # 0 +0x897A 0xACC0 # 0 +0x897B 0xACC1 # 0 +0x897C 0xACC2 # 0 +0x897D 0xACC3 # 0 +0x8981 0xACC4 # 0 +0x8982 0xACC5 # 0 +0x8983 0xACC6 # 0 +0x8984 0xACC7 # 0 +0x8985 0xACC8 # 0 +0x8986 0xACC9 # 0 +0x8987 0xACCA # 0 +0x8988 0xACCB # 0 +0x8989 0xACCC # 0 +0x898A 0xACCD # 0 +0x898B 0xACCE # 0 +0x898C 0xACCF # 0 +0x898D 0xACD0 # 0 +0x898E 0xACD1 # 0 +0x898F 0xACD2 # 0 +0x8990 0xACD3 # 0 +0x8991 0xACD4 # 0 +0x8993 0xACD5 # 0 +0x8994 0xACD6 # 0 +0x8995 0xACD7 # 0 +0x8996 0xACD8 # 0 +0x8997 0xACD9 # 0 +0x8998 0xACDA # 0 +0x8999 0xACDB # 0 +0x899A 0xACDC # 0 +0x899B 0xACDD # 0 +0x899C 0xACDE # 0 +0x899D 0xACDF # 0 +0x89A1 0xACE0 # 0 +0x89A2 0xACE1 # 0 +0x89A3 0xACE2 # 0 +0x89A4 0xACE3 # 0 +0x89A5 0xACE4 # 0 +0x89A6 0xACE5 # 0 +0x89A7 0xACE6 # 0 +0x89A8 0xACE7 # 0 +0x89A9 0xACE8 # 0 +0x89AA 0xACE9 # 0 +0x89AB 0xACEA # 0 +0x89AC 0xACEB # 0 +0x89AD 0xACEC # 0 +0x89AE 0xACED # 0 +0x89AF 0xACEE # 0 +0x89B0 0xACEF # 0 +0x89B1 0xACF0 # 0 +0x89B3 0xACF1 # 0 +0x89B4 0xACF2 # 0 +0x89B5 0xACF3 # 0 +0x89B6 0xACF4 # 0 +0x89B7 0xACF5 # 0 +0x89B8 0xACF6 # 0 +0x89B9 0xACF7 # 0 +0x89BA 0xACF8 # 0 +0x89BB 0xACF9 # 0 +0x89BC 0xACFA # 0 +0x89BD 0xACFB # 0 +0x89C1 0xACFC # 0 +0x89C2 0xACFD # 0 +0x89C3 0xACFE # 0 +0x89C4 0xACFF # 0 +0x89C5 0xAD00 # 0 +0x89C6 0xAD01 # 0 +0x89C7 0xAD02 # 0 +0x89C8 0xAD03 # 0 +0x89C9 0xAD04 # 0 +0x89CA 0xAD05 # 0 +0x89CB 0xAD06 # 0 +0x89CC 0xAD07 # 0 +0x89CD 0xAD08 # 0 +0x89CE 0xAD09 # 0 +0x89CF 0xAD0A # 0 +0x89D0 0xAD0B # 0 +0x89D1 0xAD0C # 0 +0x89D3 0xAD0D # 0 +0x89D4 0xAD0E # 0 +0x89D5 0xAD0F # 0 +0x89D6 0xAD10 # 0 +0x89D7 0xAD11 # 0 +0x89D8 0xAD12 # 0 +0x89D9 0xAD13 # 0 +0x89DA 0xAD14 # 0 +0x89DB 0xAD15 # 0 +0x89DC 0xAD16 # 0 +0x89DD 0xAD17 # 0 +0x89E1 0xAD18 # 0 +0x89E2 0xAD19 # 0 +0x89E3 0xAD1A # 0 +0x89E4 0xAD1B # 0 +0x89E5 0xAD1C # 0 +0x89E6 0xAD1D # 0 +0x89E7 0xAD1E # 0 +0x89E8 0xAD1F # 0 +0x89E9 0xAD20 # 0 +0x89EA 0xAD21 # 0 +0x89EB 0xAD22 # 0 +0x89EC 0xAD23 # 0 +0x89ED 0xAD24 # 0 +0x89EE 0xAD25 # 0 +0x89EF 0xAD26 # 0 +0x89F0 0xAD27 # 0 +0x89F1 0xAD28 # 0 +0x89F3 0xAD29 # 0 +0x89F4 0xAD2A # 0 +0x89F5 0xAD2B # 0 +0x89F6 0xAD2C # 0 +0x89F7 0xAD2D # 0 +0x89F8 0xAD2E # 0 +0x89F9 0xAD2F # 0 +0x89FA 0xAD30 # 0 +0x89FB 0xAD31 # 0 +0x89FC 0xAD32 # 0 +0x89FD 0xAD33 # 0 +0x8A41 0xAD34 # 0 +0x8A42 0xAD35 # 0 +0x8A43 0xAD36 # 0 +0x8A44 0xAD37 # 0 +0x8A45 0xAD38 # 0 +0x8A46 0xAD39 # 0 +0x8A47 0xAD3A # 0 +0x8A48 0xAD3B # 0 +0x8A49 0xAD3C # 0 +0x8A4A 0xAD3D # 0 +0x8A4B 0xAD3E # 0 +0x8A4C 0xAD3F # 0 +0x8A4D 0xAD40 # 0 +0x8A4E 0xAD41 # 0 +0x8A4F 0xAD42 # 0 +0x8A50 0xAD43 # 0 +0x8A51 0xAD44 # 0 +0x8A53 0xAD45 # 0 +0x8A54 0xAD46 # 0 +0x8A55 0xAD47 # 0 +0x8A56 0xAD48 # 0 +0x8A57 0xAD49 # 0 +0x8A58 0xAD4A # 0 +0x8A59 0xAD4B # 0 +0x8A5A 0xAD4C # 0 +0x8A5B 0xAD4D # 0 +0x8A5C 0xAD4E # 0 +0x8A5D 0xAD4F # 0 +0x8A61 0xAD50 # 0 +0x8A62 0xAD51 # 0 +0x8A63 0xAD52 # 0 +0x8A64 0xAD53 # 0 +0x8A65 0xAD54 # 0 +0x8A66 0xAD55 # 0 +0x8A67 0xAD56 # 0 +0x8A68 0xAD57 # 0 +0x8A69 0xAD58 # 0 +0x8A6A 0xAD59 # 0 +0x8A6B 0xAD5A # 0 +0x8A6C 0xAD5B # 0 +0x8A6D 0xAD5C # 0 +0x8A6E 0xAD5D # 0 +0x8A6F 0xAD5E # 0 +0x8A70 0xAD5F # 0 +0x8A71 0xAD60 # 0 +0x8A73 0xAD61 # 0 +0x8A74 0xAD62 # 0 +0x8A75 0xAD63 # 0 +0x8A76 0xAD64 # 0 +0x8A77 0xAD65 # 0 +0x8A78 0xAD66 # 0 +0x8A79 0xAD67 # 0 +0x8A7A 0xAD68 # 0 +0x8A7B 0xAD69 # 0 +0x8A7C 0xAD6A # 0 +0x8A7D 0xAD6B # 0 +0x8A81 0xAD6C # 0 +0x8A82 0xAD6D # 0 +0x8A83 0xAD6E # 0 +0x8A84 0xAD6F # 0 +0x8A85 0xAD70 # 0 +0x8A86 0xAD71 # 0 +0x8A87 0xAD72 # 0 +0x8A88 0xAD73 # 0 +0x8A89 0xAD74 # 0 +0x8A8A 0xAD75 # 0 +0x8A8B 0xAD76 # 0 +0x8A8C 0xAD77 # 0 +0x8A8D 0xAD78 # 0 +0x8A8E 0xAD79 # 0 +0x8A8F 0xAD7A # 0 +0x8A90 0xAD7B # 0 +0x8A91 0xAD7C # 0 +0x8A93 0xAD7D # 0 +0x8A94 0xAD7E # 0 +0x8A95 0xAD7F # 0 +0x8A96 0xAD80 # 0 +0x8A97 0xAD81 # 0 +0x8A98 0xAD82 # 0 +0x8A99 0xAD83 # 0 +0x8A9A 0xAD84 # 0 +0x8A9B 0xAD85 # 0 +0x8A9C 0xAD86 # 0 +0x8A9D 0xAD87 # 0 +0x8AA1 0xAD88 # 0 +0x8AA2 0xAD89 # 0 +0x8AA3 0xAD8A # 0 +0x8AA4 0xAD8B # 0 +0x8AA5 0xAD8C # 0 +0x8AA6 0xAD8D # 0 +0x8AA7 0xAD8E # 0 +0x8AA8 0xAD8F # 0 +0x8AA9 0xAD90 # 0 +0x8AAA 0xAD91 # 0 +0x8AAB 0xAD92 # 0 +0x8AAC 0xAD93 # 0 +0x8AAD 0xAD94 # 0 +0x8AAE 0xAD95 # 0 +0x8AAF 0xAD96 # 0 +0x8AB0 0xAD97 # 0 +0x8AB1 0xAD98 # 0 +0x8AB3 0xAD99 # 0 +0x8AB4 0xAD9A # 0 +0x8AB5 0xAD9B # 0 +0x8AB6 0xAD9C # 0 +0x8AB7 0xAD9D # 0 +0x8AB8 0xAD9E # 0 +0x8AB9 0xAD9F # 0 +0x8ABA 0xADA0 # 0 +0x8ABB 0xADA1 # 0 +0x8ABC 0xADA2 # 0 +0x8ABD 0xADA3 # 0 +0x8AC1 0xADA4 # 0 +0x8AC2 0xADA5 # 0 +0x8AC3 0xADA6 # 0 +0x8AC4 0xADA7 # 0 +0x8AC5 0xADA8 # 0 +0x8AC6 0xADA9 # 0 +0x8AC7 0xADAA # 0 +0x8AC8 0xADAB # 0 +0x8AC9 0xADAC # 0 +0x8ACA 0xADAD # 0 +0x8ACB 0xADAE # 0 +0x8ACC 0xADAF # 0 +0x8ACD 0xADB0 # 0 +0x8ACE 0xADB1 # 0 +0x8ACF 0xADB2 # 0 +0x8AD0 0xADB3 # 0 +0x8AD1 0xADB4 # 0 +0x8AD3 0xADB5 # 0 +0x8AD4 0xADB6 # 0 +0x8AD5 0xADB7 # 0 +0x8AD6 0xADB8 # 0 +0x8AD7 0xADB9 # 0 +0x8AD8 0xADBA # 0 +0x8AD9 0xADBB # 0 +0x8ADA 0xADBC # 0 +0x8ADB 0xADBD # 0 +0x8ADC 0xADBE # 0 +0x8ADD 0xADBF # 0 +0x8AE1 0xADC0 # 0 +0x8AE2 0xADC1 # 0 +0x8AE3 0xADC2 # 0 +0x8AE4 0xADC3 # 0 +0x8AE5 0xADC4 # 0 +0x8AE6 0xADC5 # 0 +0x8AE7 0xADC6 # 0 +0x8AE8 0xADC7 # 0 +0x8AE9 0xADC8 # 0 +0x8AEA 0xADC9 # 0 +0x8AEB 0xADCA # 0 +0x8AEC 0xADCB # 0 +0x8AED 0xADCC # 0 +0x8AEE 0xADCD # 0 +0x8AEF 0xADCE # 0 +0x8AF0 0xADCF # 0 +0x8AF1 0xADD0 # 0 +0x8AF3 0xADD1 # 0 +0x8AF4 0xADD2 # 0 +0x8AF5 0xADD3 # 0 +0x8AF6 0xADD4 # 0 +0x8AF7 0xADD5 # 0 +0x8AF8 0xADD6 # 0 +0x8AF9 0xADD7 # 0 +0x8AFA 0xADD8 # 0 +0x8AFB 0xADD9 # 0 +0x8AFC 0xADDA # 0 +0x8AFD 0xADDB # 0 +0x8B41 0xADDC # 0 +0x8B42 0xADDD # 0 +0x8B43 0xADDE # 0 +0x8B44 0xADDF # 0 +0x8B45 0xADE0 # 0 +0x8B46 0xADE1 # 0 +0x8B47 0xADE2 # 0 +0x8B48 0xADE3 # 0 +0x8B49 0xADE4 # 0 +0x8B4A 0xADE5 # 0 +0x8B4B 0xADE6 # 0 +0x8B4C 0xADE7 # 0 +0x8B4D 0xADE8 # 0 +0x8B4E 0xADE9 # 0 +0x8B4F 0xADEA # 0 +0x8B50 0xADEB # 0 +0x8B51 0xADEC # 0 +0x8B53 0xADED # 0 +0x8B54 0xADEE # 0 +0x8B55 0xADEF # 0 +0x8B56 0xADF0 # 0 +0x8B57 0xADF1 # 0 +0x8B58 0xADF2 # 0 +0x8B59 0xADF3 # 0 +0x8B5A 0xADF4 # 0 +0x8B5B 0xADF5 # 0 +0x8B5C 0xADF6 # 0 +0x8B5D 0xADF7 # 0 +0x8B61 0xADF8 # 0 +0x8B62 0xADF9 # 0 +0x8B63 0xADFA # 0 +0x8B64 0xADFB # 0 +0x8B65 0xADFC # 0 +0x8B66 0xADFD # 0 +0x8B67 0xADFE # 0 +0x8B68 0xADFF # 0 +0x8B69 0xAE00 # 0 +0x8B6A 0xAE01 # 0 +0x8B6B 0xAE02 # 0 +0x8B6C 0xAE03 # 0 +0x8B6D 0xAE04 # 0 +0x8B6E 0xAE05 # 0 +0x8B6F 0xAE06 # 0 +0x8B70 0xAE07 # 0 +0x8B71 0xAE08 # 0 +0x8B73 0xAE09 # 0 +0x8B74 0xAE0A # 0 +0x8B75 0xAE0B # 0 +0x8B76 0xAE0C # 0 +0x8B77 0xAE0D # 0 +0x8B78 0xAE0E # 0 +0x8B79 0xAE0F # 0 +0x8B7A 0xAE10 # 0 +0x8B7B 0xAE11 # 0 +0x8B7C 0xAE12 # 0 +0x8B7D 0xAE13 # 0 +0x8B81 0xAE14 # 0 +0x8B82 0xAE15 # 0 +0x8B83 0xAE16 # 0 +0x8B84 0xAE17 # 0 +0x8B85 0xAE18 # 0 +0x8B86 0xAE19 # 0 +0x8B87 0xAE1A # 0 +0x8B88 0xAE1B # 0 +0x8B89 0xAE1C # 0 +0x8B8A 0xAE1D # 0 +0x8B8B 0xAE1E # 0 +0x8B8C 0xAE1F # 0 +0x8B8D 0xAE20 # 0 +0x8B8E 0xAE21 # 0 +0x8B8F 0xAE22 # 0 +0x8B90 0xAE23 # 0 +0x8B91 0xAE24 # 0 +0x8B93 0xAE25 # 0 +0x8B94 0xAE26 # 0 +0x8B95 0xAE27 # 0 +0x8B96 0xAE28 # 0 +0x8B97 0xAE29 # 0 +0x8B98 0xAE2A # 0 +0x8B99 0xAE2B # 0 +0x8B9A 0xAE2C # 0 +0x8B9B 0xAE2D # 0 +0x8B9C 0xAE2E # 0 +0x8B9D 0xAE2F # 0 +0x8BA1 0xAE30 # 0 +0x8BA2 0xAE31 # 0 +0x8BA3 0xAE32 # 0 +0x8BA4 0xAE33 # 0 +0x8BA5 0xAE34 # 0 +0x8BA6 0xAE35 # 0 +0x8BA7 0xAE36 # 0 +0x8BA8 0xAE37 # 0 +0x8BA9 0xAE38 # 0 +0x8BAA 0xAE39 # 0 +0x8BAB 0xAE3A # 0 +0x8BAC 0xAE3B # 0 +0x8BAD 0xAE3C # 0 +0x8BAE 0xAE3D # 0 +0x8BAF 0xAE3E # 0 +0x8BB0 0xAE3F # 0 +0x8BB1 0xAE40 # 0 +0x8BB3 0xAE41 # 0 +0x8BB4 0xAE42 # 0 +0x8BB5 0xAE43 # 0 +0x8BB6 0xAE44 # 0 +0x8BB7 0xAE45 # 0 +0x8BB8 0xAE46 # 0 +0x8BB9 0xAE47 # 0 +0x8BBA 0xAE48 # 0 +0x8BBB 0xAE49 # 0 +0x8BBC 0xAE4A # 0 +0x8BBD 0xAE4B # 0 +0x8C41 0x1101 # 0 +0x8C61 0xAE4C # 0 +0x8C62 0xAE4D # 0 +0x8C63 0xAE4E # 0 +0x8C64 0xAE4F # 0 +0x8C65 0xAE50 # 0 +0x8C66 0xAE51 # 0 +0x8C67 0xAE52 # 0 +0x8C68 0xAE53 # 0 +0x8C69 0xAE54 # 0 +0x8C6A 0xAE55 # 0 +0x8C6B 0xAE56 # 0 +0x8C6C 0xAE57 # 0 +0x8C6D 0xAE58 # 0 +0x8C6E 0xAE59 # 0 +0x8C6F 0xAE5A # 0 +0x8C70 0xAE5B # 0 +0x8C71 0xAE5C # 0 +0x8C73 0xAE5D # 0 +0x8C74 0xAE5E # 0 +0x8C75 0xAE5F # 0 +0x8C76 0xAE60 # 0 +0x8C77 0xAE61 # 0 +0x8C78 0xAE62 # 0 +0x8C79 0xAE63 # 0 +0x8C7A 0xAE64 # 0 +0x8C7B 0xAE65 # 0 +0x8C7C 0xAE66 # 0 +0x8C7D 0xAE67 # 0 +0x8C81 0xAE68 # 0 +0x8C82 0xAE69 # 0 +0x8C83 0xAE6A # 0 +0x8C84 0xAE6B # 0 +0x8C85 0xAE6C # 0 +0x8C86 0xAE6D # 0 +0x8C87 0xAE6E # 0 +0x8C88 0xAE6F # 0 +0x8C89 0xAE70 # 0 +0x8C8A 0xAE71 # 0 +0x8C8B 0xAE72 # 0 +0x8C8C 0xAE73 # 0 +0x8C8D 0xAE74 # 0 +0x8C8E 0xAE75 # 0 +0x8C8F 0xAE76 # 0 +0x8C90 0xAE77 # 0 +0x8C91 0xAE78 # 0 +0x8C93 0xAE79 # 0 +0x8C94 0xAE7A # 0 +0x8C95 0xAE7B # 0 +0x8C96 0xAE7C # 0 +0x8C97 0xAE7D # 0 +0x8C98 0xAE7E # 0 +0x8C99 0xAE7F # 0 +0x8C9A 0xAE80 # 0 +0x8C9B 0xAE81 # 0 +0x8C9C 0xAE82 # 0 +0x8C9D 0xAE83 # 0 +0x8CA1 0xAE84 # 0 +0x8CA2 0xAE85 # 0 +0x8CA3 0xAE86 # 0 +0x8CA4 0xAE87 # 0 +0x8CA5 0xAE88 # 0 +0x8CA6 0xAE89 # 0 +0x8CA7 0xAE8A # 0 +0x8CA8 0xAE8B # 0 +0x8CA9 0xAE8C # 0 +0x8CAA 0xAE8D # 0 +0x8CAB 0xAE8E # 0 +0x8CAC 0xAE8F # 0 +0x8CAD 0xAE90 # 0 +0x8CAE 0xAE91 # 0 +0x8CAF 0xAE92 # 0 +0x8CB0 0xAE93 # 0 +0x8CB1 0xAE94 # 0 +0x8CB3 0xAE95 # 0 +0x8CB4 0xAE96 # 0 +0x8CB5 0xAE97 # 0 +0x8CB6 0xAE98 # 0 +0x8CB7 0xAE99 # 0 +0x8CB8 0xAE9A # 0 +0x8CB9 0xAE9B # 0 +0x8CBA 0xAE9C # 0 +0x8CBB 0xAE9D # 0 +0x8CBC 0xAE9E # 0 +0x8CBD 0xAE9F # 0 +0x8CC1 0xAEA0 # 0 +0x8CC2 0xAEA1 # 0 +0x8CC3 0xAEA2 # 0 +0x8CC4 0xAEA3 # 0 +0x8CC5 0xAEA4 # 0 +0x8CC6 0xAEA5 # 0 +0x8CC7 0xAEA6 # 0 +0x8CC8 0xAEA7 # 0 +0x8CC9 0xAEA8 # 0 +0x8CCA 0xAEA9 # 0 +0x8CCB 0xAEAA # 0 +0x8CCC 0xAEAB # 0 +0x8CCD 0xAEAC # 0 +0x8CCE 0xAEAD # 0 +0x8CCF 0xAEAE # 0 +0x8CD0 0xAEAF # 0 +0x8CD1 0xAEB0 # 0 +0x8CD3 0xAEB1 # 0 +0x8CD4 0xAEB2 # 0 +0x8CD5 0xAEB3 # 0 +0x8CD6 0xAEB4 # 0 +0x8CD7 0xAEB5 # 0 +0x8CD8 0xAEB6 # 0 +0x8CD9 0xAEB7 # 0 +0x8CDA 0xAEB8 # 0 +0x8CDB 0xAEB9 # 0 +0x8CDC 0xAEBA # 0 +0x8CDD 0xAEBB # 0 +0x8CE1 0xAEBC # 0 +0x8CE2 0xAEBD # 0 +0x8CE3 0xAEBE # 0 +0x8CE4 0xAEBF # 0 +0x8CE5 0xAEC0 # 0 +0x8CE6 0xAEC1 # 0 +0x8CE7 0xAEC2 # 0 +0x8CE8 0xAEC3 # 0 +0x8CE9 0xAEC4 # 0 +0x8CEA 0xAEC5 # 0 +0x8CEB 0xAEC6 # 0 +0x8CEC 0xAEC7 # 0 +0x8CED 0xAEC8 # 0 +0x8CEE 0xAEC9 # 0 +0x8CEF 0xAECA # 0 +0x8CF0 0xAECB # 0 +0x8CF1 0xAECC # 0 +0x8CF3 0xAECD # 0 +0x8CF4 0xAECE # 0 +0x8CF5 0xAECF # 0 +0x8CF6 0xAED0 # 0 +0x8CF7 0xAED1 # 0 +0x8CF8 0xAED2 # 0 +0x8CF9 0xAED3 # 0 +0x8CFA 0xAED4 # 0 +0x8CFB 0xAED5 # 0 +0x8CFC 0xAED6 # 0 +0x8CFD 0xAED7 # 0 +0x8D41 0xAED8 # 0 +0x8D42 0xAED9 # 0 +0x8D43 0xAEDA # 0 +0x8D44 0xAEDB # 0 +0x8D45 0xAEDC # 0 +0x8D46 0xAEDD # 0 +0x8D47 0xAEDE # 0 +0x8D48 0xAEDF # 0 +0x8D49 0xAEE0 # 0 +0x8D4A 0xAEE1 # 0 +0x8D4B 0xAEE2 # 0 +0x8D4C 0xAEE3 # 0 +0x8D4D 0xAEE4 # 0 +0x8D4E 0xAEE5 # 0 +0x8D4F 0xAEE6 # 0 +0x8D50 0xAEE7 # 0 +0x8D51 0xAEE8 # 0 +0x8D53 0xAEE9 # 0 +0x8D54 0xAEEA # 0 +0x8D55 0xAEEB # 0 +0x8D56 0xAEEC # 0 +0x8D57 0xAEED # 0 +0x8D58 0xAEEE # 0 +0x8D59 0xAEEF # 0 +0x8D5A 0xAEF0 # 0 +0x8D5B 0xAEF1 # 0 +0x8D5C 0xAEF2 # 0 +0x8D5D 0xAEF3 # 0 +0x8D61 0xAEF4 # 0 +0x8D62 0xAEF5 # 0 +0x8D63 0xAEF6 # 0 +0x8D64 0xAEF7 # 0 +0x8D65 0xAEF8 # 0 +0x8D66 0xAEF9 # 0 +0x8D67 0xAEFA # 0 +0x8D68 0xAEFB # 0 +0x8D69 0xAEFC # 0 +0x8D6A 0xAEFD # 0 +0x8D6B 0xAEFE # 0 +0x8D6C 0xAEFF # 0 +0x8D6D 0xAF00 # 0 +0x8D6E 0xAF01 # 0 +0x8D6F 0xAF02 # 0 +0x8D70 0xAF03 # 0 +0x8D71 0xAF04 # 0 +0x8D73 0xAF05 # 0 +0x8D74 0xAF06 # 0 +0x8D75 0xAF07 # 0 +0x8D76 0xAF08 # 0 +0x8D77 0xAF09 # 0 +0x8D78 0xAF0A # 0 +0x8D79 0xAF0B # 0 +0x8D7A 0xAF0C # 0 +0x8D7B 0xAF0D # 0 +0x8D7C 0xAF0E # 0 +0x8D7D 0xAF0F # 0 +0x8D81 0xAF10 # 0 +0x8D82 0xAF11 # 0 +0x8D83 0xAF12 # 0 +0x8D84 0xAF13 # 0 +0x8D85 0xAF14 # 0 +0x8D86 0xAF15 # 0 +0x8D87 0xAF16 # 0 +0x8D88 0xAF17 # 0 +0x8D89 0xAF18 # 0 +0x8D8A 0xAF19 # 0 +0x8D8B 0xAF1A # 0 +0x8D8C 0xAF1B # 0 +0x8D8D 0xAF1C # 0 +0x8D8E 0xAF1D # 0 +0x8D8F 0xAF1E # 0 +0x8D90 0xAF1F # 0 +0x8D91 0xAF20 # 0 +0x8D93 0xAF21 # 0 +0x8D94 0xAF22 # 0 +0x8D95 0xAF23 # 0 +0x8D96 0xAF24 # 0 +0x8D97 0xAF25 # 0 +0x8D98 0xAF26 # 0 +0x8D99 0xAF27 # 0 +0x8D9A 0xAF28 # 0 +0x8D9B 0xAF29 # 0 +0x8D9C 0xAF2A # 0 +0x8D9D 0xAF2B # 0 +0x8DA1 0xAF2C # 0 +0x8DA2 0xAF2D # 0 +0x8DA3 0xAF2E # 0 +0x8DA4 0xAF2F # 0 +0x8DA5 0xAF30 # 0 +0x8DA6 0xAF31 # 0 +0x8DA7 0xAF32 # 0 +0x8DA8 0xAF33 # 0 +0x8DA9 0xAF34 # 0 +0x8DAA 0xAF35 # 0 +0x8DAB 0xAF36 # 0 +0x8DAC 0xAF37 # 0 +0x8DAD 0xAF38 # 0 +0x8DAE 0xAF39 # 0 +0x8DAF 0xAF3A # 0 +0x8DB0 0xAF3B # 0 +0x8DB1 0xAF3C # 0 +0x8DB3 0xAF3D # 0 +0x8DB4 0xAF3E # 0 +0x8DB5 0xAF3F # 0 +0x8DB6 0xAF40 # 0 +0x8DB7 0xAF41 # 0 +0x8DB8 0xAF42 # 0 +0x8DB9 0xAF43 # 0 +0x8DBA 0xAF44 # 0 +0x8DBB 0xAF45 # 0 +0x8DBC 0xAF46 # 0 +0x8DBD 0xAF47 # 0 +0x8DC1 0xAF48 # 0 +0x8DC2 0xAF49 # 0 +0x8DC3 0xAF4A # 0 +0x8DC4 0xAF4B # 0 +0x8DC5 0xAF4C # 0 +0x8DC6 0xAF4D # 0 +0x8DC7 0xAF4E # 0 +0x8DC8 0xAF4F # 0 +0x8DC9 0xAF50 # 0 +0x8DCA 0xAF51 # 0 +0x8DCB 0xAF52 # 0 +0x8DCC 0xAF53 # 0 +0x8DCD 0xAF54 # 0 +0x8DCE 0xAF55 # 0 +0x8DCF 0xAF56 # 0 +0x8DD0 0xAF57 # 0 +0x8DD1 0xAF58 # 0 +0x8DD3 0xAF59 # 0 +0x8DD4 0xAF5A # 0 +0x8DD5 0xAF5B # 0 +0x8DD6 0xAF5C # 0 +0x8DD7 0xAF5D # 0 +0x8DD8 0xAF5E # 0 +0x8DD9 0xAF5F # 0 +0x8DDA 0xAF60 # 0 +0x8DDB 0xAF61 # 0 +0x8DDC 0xAF62 # 0 +0x8DDD 0xAF63 # 0 +0x8DE1 0xAF64 # 0 +0x8DE2 0xAF65 # 0 +0x8DE3 0xAF66 # 0 +0x8DE4 0xAF67 # 0 +0x8DE5 0xAF68 # 0 +0x8DE6 0xAF69 # 0 +0x8DE7 0xAF6A # 0 +0x8DE8 0xAF6B # 0 +0x8DE9 0xAF6C # 0 +0x8DEA 0xAF6D # 0 +0x8DEB 0xAF6E # 0 +0x8DEC 0xAF6F # 0 +0x8DED 0xAF70 # 0 +0x8DEE 0xAF71 # 0 +0x8DEF 0xAF72 # 0 +0x8DF0 0xAF73 # 0 +0x8DF1 0xAF74 # 0 +0x8DF3 0xAF75 # 0 +0x8DF4 0xAF76 # 0 +0x8DF5 0xAF77 # 0 +0x8DF6 0xAF78 # 0 +0x8DF7 0xAF79 # 0 +0x8DF8 0xAF7A # 0 +0x8DF9 0xAF7B # 0 +0x8DFA 0xAF7C # 0 +0x8DFB 0xAF7D # 0 +0x8DFC 0xAF7E # 0 +0x8DFD 0xAF7F # 0 +0x8E41 0xAF80 # 0 +0x8E42 0xAF81 # 0 +0x8E43 0xAF82 # 0 +0x8E44 0xAF83 # 0 +0x8E45 0xAF84 # 0 +0x8E46 0xAF85 # 0 +0x8E47 0xAF86 # 0 +0x8E48 0xAF87 # 0 +0x8E49 0xAF88 # 0 +0x8E4A 0xAF89 # 0 +0x8E4B 0xAF8A # 0 +0x8E4C 0xAF8B # 0 +0x8E4D 0xAF8C # 0 +0x8E4E 0xAF8D # 0 +0x8E4F 0xAF8E # 0 +0x8E50 0xAF8F # 0 +0x8E51 0xAF90 # 0 +0x8E53 0xAF91 # 0 +0x8E54 0xAF92 # 0 +0x8E55 0xAF93 # 0 +0x8E56 0xAF94 # 0 +0x8E57 0xAF95 # 0 +0x8E58 0xAF96 # 0 +0x8E59 0xAF97 # 0 +0x8E5A 0xAF98 # 0 +0x8E5B 0xAF99 # 0 +0x8E5C 0xAF9A # 0 +0x8E5D 0xAF9B # 0 +0x8E61 0xAF9C # 0 +0x8E62 0xAF9D # 0 +0x8E63 0xAF9E # 0 +0x8E64 0xAF9F # 0 +0x8E65 0xAFA0 # 0 +0x8E66 0xAFA1 # 0 +0x8E67 0xAFA2 # 0 +0x8E68 0xAFA3 # 0 +0x8E69 0xAFA4 # 0 +0x8E6A 0xAFA5 # 0 +0x8E6B 0xAFA6 # 0 +0x8E6C 0xAFA7 # 0 +0x8E6D 0xAFA8 # 0 +0x8E6E 0xAFA9 # 0 +0x8E6F 0xAFAA # 0 +0x8E70 0xAFAB # 0 +0x8E71 0xAFAC # 0 +0x8E73 0xAFAD # 0 +0x8E74 0xAFAE # 0 +0x8E75 0xAFAF # 0 +0x8E76 0xAFB0 # 0 +0x8E77 0xAFB1 # 0 +0x8E78 0xAFB2 # 0 +0x8E79 0xAFB3 # 0 +0x8E7A 0xAFB4 # 0 +0x8E7B 0xAFB5 # 0 +0x8E7C 0xAFB6 # 0 +0x8E7D 0xAFB7 # 0 +0x8E81 0xAFB8 # 0 +0x8E82 0xAFB9 # 0 +0x8E83 0xAFBA # 0 +0x8E84 0xAFBB # 0 +0x8E85 0xAFBC # 0 +0x8E86 0xAFBD # 0 +0x8E87 0xAFBE # 0 +0x8E88 0xAFBF # 0 +0x8E89 0xAFC0 # 0 +0x8E8A 0xAFC1 # 0 +0x8E8B 0xAFC2 # 0 +0x8E8C 0xAFC3 # 0 +0x8E8D 0xAFC4 # 0 +0x8E8E 0xAFC5 # 0 +0x8E8F 0xAFC6 # 0 +0x8E90 0xAFC7 # 0 +0x8E91 0xAFC8 # 0 +0x8E93 0xAFC9 # 0 +0x8E94 0xAFCA # 0 +0x8E95 0xAFCB # 0 +0x8E96 0xAFCC # 0 +0x8E97 0xAFCD # 0 +0x8E98 0xAFCE # 0 +0x8E99 0xAFCF # 0 +0x8E9A 0xAFD0 # 0 +0x8E9B 0xAFD1 # 0 +0x8E9C 0xAFD2 # 0 +0x8E9D 0xAFD3 # 0 +0x8EA1 0xAFD4 # 0 +0x8EA2 0xAFD5 # 0 +0x8EA3 0xAFD6 # 0 +0x8EA4 0xAFD7 # 0 +0x8EA5 0xAFD8 # 0 +0x8EA6 0xAFD9 # 0 +0x8EA7 0xAFDA # 0 +0x8EA8 0xAFDB # 0 +0x8EA9 0xAFDC # 0 +0x8EAA 0xAFDD # 0 +0x8EAB 0xAFDE # 0 +0x8EAC 0xAFDF # 0 +0x8EAD 0xAFE0 # 0 +0x8EAE 0xAFE1 # 0 +0x8EAF 0xAFE2 # 0 +0x8EB0 0xAFE3 # 0 +0x8EB1 0xAFE4 # 0 +0x8EB3 0xAFE5 # 0 +0x8EB4 0xAFE6 # 0 +0x8EB5 0xAFE7 # 0 +0x8EB6 0xAFE8 # 0 +0x8EB7 0xAFE9 # 0 +0x8EB8 0xAFEA # 0 +0x8EB9 0xAFEB # 0 +0x8EBA 0xAFEC # 0 +0x8EBB 0xAFED # 0 +0x8EBC 0xAFEE # 0 +0x8EBD 0xAFEF # 0 +0x8EC1 0xAFF0 # 0 +0x8EC2 0xAFF1 # 0 +0x8EC3 0xAFF2 # 0 +0x8EC4 0xAFF3 # 0 +0x8EC5 0xAFF4 # 0 +0x8EC6 0xAFF5 # 0 +0x8EC7 0xAFF6 # 0 +0x8EC8 0xAFF7 # 0 +0x8EC9 0xAFF8 # 0 +0x8ECA 0xAFF9 # 0 +0x8ECB 0xAFFA # 0 +0x8ECC 0xAFFB # 0 +0x8ECD 0xAFFC # 0 +0x8ECE 0xAFFD # 0 +0x8ECF 0xAFFE # 0 +0x8ED0 0xAFFF # 0 +0x8ED1 0xB000 # 0 +0x8ED3 0xB001 # 0 +0x8ED4 0xB002 # 0 +0x8ED5 0xB003 # 0 +0x8ED6 0xB004 # 0 +0x8ED7 0xB005 # 0 +0x8ED8 0xB006 # 0 +0x8ED9 0xB007 # 0 +0x8EDA 0xB008 # 0 +0x8EDB 0xB009 # 0 +0x8EDC 0xB00A # 0 +0x8EDD 0xB00B # 0 +0x8EE1 0xB00C # 0 +0x8EE2 0xB00D # 0 +0x8EE3 0xB00E # 0 +0x8EE4 0xB00F # 0 +0x8EE5 0xB010 # 0 +0x8EE6 0xB011 # 0 +0x8EE7 0xB012 # 0 +0x8EE8 0xB013 # 0 +0x8EE9 0xB014 # 0 +0x8EEA 0xB015 # 0 +0x8EEB 0xB016 # 0 +0x8EEC 0xB017 # 0 +0x8EED 0xB018 # 0 +0x8EEE 0xB019 # 0 +0x8EEF 0xB01A # 0 +0x8EF0 0xB01B # 0 +0x8EF1 0xB01C # 0 +0x8EF3 0xB01D # 0 +0x8EF4 0xB01E # 0 +0x8EF5 0xB01F # 0 +0x8EF6 0xB020 # 0 +0x8EF7 0xB021 # 0 +0x8EF8 0xB022 # 0 +0x8EF9 0xB023 # 0 +0x8EFA 0xB024 # 0 +0x8EFB 0xB025 # 0 +0x8EFC 0xB026 # 0 +0x8EFD 0xB027 # 0 +0x8F41 0xB028 # 0 +0x8F42 0xB029 # 0 +0x8F43 0xB02A # 0 +0x8F44 0xB02B # 0 +0x8F45 0xB02C # 0 +0x8F46 0xB02D # 0 +0x8F47 0xB02E # 0 +0x8F48 0xB02F # 0 +0x8F49 0xB030 # 0 +0x8F4A 0xB031 # 0 +0x8F4B 0xB032 # 0 +0x8F4C 0xB033 # 0 +0x8F4D 0xB034 # 0 +0x8F4E 0xB035 # 0 +0x8F4F 0xB036 # 0 +0x8F50 0xB037 # 0 +0x8F51 0xB038 # 0 +0x8F53 0xB039 # 0 +0x8F54 0xB03A # 0 +0x8F55 0xB03B # 0 +0x8F56 0xB03C # 0 +0x8F57 0xB03D # 0 +0x8F58 0xB03E # 0 +0x8F59 0xB03F # 0 +0x8F5A 0xB040 # 0 +0x8F5B 0xB041 # 0 +0x8F5C 0xB042 # 0 +0x8F5D 0xB043 # 0 +0x8F61 0xB044 # 0 +0x8F62 0xB045 # 0 +0x8F63 0xB046 # 0 +0x8F64 0xB047 # 0 +0x8F65 0xB048 # 0 +0x8F66 0xB049 # 0 +0x8F67 0xB04A # 0 +0x8F68 0xB04B # 0 +0x8F69 0xB04C # 0 +0x8F6A 0xB04D # 0 +0x8F6B 0xB04E # 0 +0x8F6C 0xB04F # 0 +0x8F6D 0xB050 # 0 +0x8F6E 0xB051 # 0 +0x8F6F 0xB052 # 0 +0x8F70 0xB053 # 0 +0x8F71 0xB054 # 0 +0x8F73 0xB055 # 0 +0x8F74 0xB056 # 0 +0x8F75 0xB057 # 0 +0x8F76 0xB058 # 0 +0x8F77 0xB059 # 0 +0x8F78 0xB05A # 0 +0x8F79 0xB05B # 0 +0x8F7A 0xB05C # 0 +0x8F7B 0xB05D # 0 +0x8F7C 0xB05E # 0 +0x8F7D 0xB05F # 0 +0x8F81 0xB060 # 0 +0x8F82 0xB061 # 0 +0x8F83 0xB062 # 0 +0x8F84 0xB063 # 0 +0x8F85 0xB064 # 0 +0x8F86 0xB065 # 0 +0x8F87 0xB066 # 0 +0x8F88 0xB067 # 0 +0x8F89 0xB068 # 0 +0x8F8A 0xB069 # 0 +0x8F8B 0xB06A # 0 +0x8F8C 0xB06B # 0 +0x8F8D 0xB06C # 0 +0x8F8E 0xB06D # 0 +0x8F8F 0xB06E # 0 +0x8F90 0xB06F # 0 +0x8F91 0xB070 # 0 +0x8F93 0xB071 # 0 +0x8F94 0xB072 # 0 +0x8F95 0xB073 # 0 +0x8F96 0xB074 # 0 +0x8F97 0xB075 # 0 +0x8F98 0xB076 # 0 +0x8F99 0xB077 # 0 +0x8F9A 0xB078 # 0 +0x8F9B 0xB079 # 0 +0x8F9C 0xB07A # 0 +0x8F9D 0xB07B # 0 +0x8FA1 0xB07C # 0 +0x8FA2 0xB07D # 0 +0x8FA3 0xB07E # 0 +0x8FA4 0xB07F # 0 +0x8FA5 0xB080 # 0 +0x8FA6 0xB081 # 0 +0x8FA7 0xB082 # 0 +0x8FA8 0xB083 # 0 +0x8FA9 0xB084 # 0 +0x8FAA 0xB085 # 0 +0x8FAB 0xB086 # 0 +0x8FAC 0xB087 # 0 +0x8FAD 0xB088 # 0 +0x8FAE 0xB089 # 0 +0x8FAF 0xB08A # 0 +0x8FB0 0xB08B # 0 +0x8FB1 0xB08C # 0 +0x8FB3 0xB08D # 0 +0x8FB4 0xB08E # 0 +0x8FB5 0xB08F # 0 +0x8FB6 0xB090 # 0 +0x8FB7 0xB091 # 0 +0x8FB8 0xB092 # 0 +0x8FB9 0xB093 # 0 +0x8FBA 0xB094 # 0 +0x8FBB 0xB095 # 0 +0x8FBC 0xB096 # 0 +0x8FBD 0xB097 # 0 +0x9041 0x1102 # 0 +0x9061 0xB098 # 0 +0x9062 0xB099 # 0 +0x9063 0xB09A # 0 +0x9064 0xB09B # 0 +0x9065 0xB09C # 0 +0x9066 0xB09D # 0 +0x9067 0xB09E # 0 +0x9068 0xB09F # 0 +0x9069 0xB0A0 # 0 +0x906A 0xB0A1 # 0 +0x906B 0xB0A2 # 0 +0x906C 0xB0A3 # 0 +0x906D 0xB0A4 # 0 +0x906E 0xB0A5 # 0 +0x906F 0xB0A6 # 0 +0x9070 0xB0A7 # 0 +0x9071 0xB0A8 # 0 +0x9073 0xB0A9 # 0 +0x9074 0xB0AA # 0 +0x9075 0xB0AB # 0 +0x9076 0xB0AC # 0 +0x9077 0xB0AD # 0 +0x9078 0xB0AE # 0 +0x9079 0xB0AF # 0 +0x907A 0xB0B0 # 0 +0x907B 0xB0B1 # 0 +0x907C 0xB0B2 # 0 +0x907D 0xB0B3 # 0 +0x9081 0xB0B4 # 0 +0x9082 0xB0B5 # 0 +0x9083 0xB0B6 # 0 +0x9084 0xB0B7 # 0 +0x9085 0xB0B8 # 0 +0x9086 0xB0B9 # 0 +0x9087 0xB0BA # 0 +0x9088 0xB0BB # 0 +0x9089 0xB0BC # 0 +0x908A 0xB0BD # 0 +0x908B 0xB0BE # 0 +0x908C 0xB0BF # 0 +0x908D 0xB0C0 # 0 +0x908E 0xB0C1 # 0 +0x908F 0xB0C2 # 0 +0x9090 0xB0C3 # 0 +0x9091 0xB0C4 # 0 +0x9093 0xB0C5 # 0 +0x9094 0xB0C6 # 0 +0x9095 0xB0C7 # 0 +0x9096 0xB0C8 # 0 +0x9097 0xB0C9 # 0 +0x9098 0xB0CA # 0 +0x9099 0xB0CB # 0 +0x909A 0xB0CC # 0 +0x909B 0xB0CD # 0 +0x909C 0xB0CE # 0 +0x909D 0xB0CF # 0 +0x90A1 0xB0D0 # 0 +0x90A2 0xB0D1 # 0 +0x90A3 0xB0D2 # 0 +0x90A4 0xB0D3 # 0 +0x90A5 0xB0D4 # 0 +0x90A6 0xB0D5 # 0 +0x90A7 0xB0D6 # 0 +0x90A8 0xB0D7 # 0 +0x90A9 0xB0D8 # 0 +0x90AA 0xB0D9 # 0 +0x90AB 0xB0DA # 0 +0x90AC 0xB0DB # 0 +0x90AD 0xB0DC # 0 +0x90AE 0xB0DD # 0 +0x90AF 0xB0DE # 0 +0x90B0 0xB0DF # 0 +0x90B1 0xB0E0 # 0 +0x90B3 0xB0E1 # 0 +0x90B4 0xB0E2 # 0 +0x90B5 0xB0E3 # 0 +0x90B6 0xB0E4 # 0 +0x90B7 0xB0E5 # 0 +0x90B8 0xB0E6 # 0 +0x90B9 0xB0E7 # 0 +0x90BA 0xB0E8 # 0 +0x90BB 0xB0E9 # 0 +0x90BC 0xB0EA # 0 +0x90BD 0xB0EB # 0 +0x90C1 0xB0EC # 0 +0x90C2 0xB0ED # 0 +0x90C3 0xB0EE # 0 +0x90C4 0xB0EF # 0 +0x90C5 0xB0F0 # 0 +0x90C6 0xB0F1 # 0 +0x90C7 0xB0F2 # 0 +0x90C8 0xB0F3 # 0 +0x90C9 0xB0F4 # 0 +0x90CA 0xB0F5 # 0 +0x90CB 0xB0F6 # 0 +0x90CC 0xB0F7 # 0 +0x90CD 0xB0F8 # 0 +0x90CE 0xB0F9 # 0 +0x90CF 0xB0FA # 0 +0x90D0 0xB0FB # 0 +0x90D1 0xB0FC # 0 +0x90D3 0xB0FD # 0 +0x90D4 0xB0FE # 0 +0x90D5 0xB0FF # 0 +0x90D6 0xB100 # 0 +0x90D7 0xB101 # 0 +0x90D8 0xB102 # 0 +0x90D9 0xB103 # 0 +0x90DA 0xB104 # 0 +0x90DB 0xB105 # 0 +0x90DC 0xB106 # 0 +0x90DD 0xB107 # 0 +0x90E1 0xB108 # 0 +0x90E2 0xB109 # 0 +0x90E3 0xB10A # 0 +0x90E4 0xB10B # 0 +0x90E5 0xB10C # 0 +0x90E6 0xB10D # 0 +0x90E7 0xB10E # 0 +0x90E8 0xB10F # 0 +0x90E9 0xB110 # 0 +0x90EA 0xB111 # 0 +0x90EB 0xB112 # 0 +0x90EC 0xB113 # 0 +0x90ED 0xB114 # 0 +0x90EE 0xB115 # 0 +0x90EF 0xB116 # 0 +0x90F0 0xB117 # 0 +0x90F1 0xB118 # 0 +0x90F3 0xB119 # 0 +0x90F4 0xB11A # 0 +0x90F5 0xB11B # 0 +0x90F6 0xB11C # 0 +0x90F7 0xB11D # 0 +0x90F8 0xB11E # 0 +0x90F9 0xB11F # 0 +0x90FA 0xB120 # 0 +0x90FB 0xB121 # 0 +0x90FC 0xB122 # 0 +0x90FD 0xB123 # 0 +0x9141 0xB124 # 0 +0x9142 0xB125 # 0 +0x9143 0xB126 # 0 +0x9144 0xB127 # 0 +0x9145 0xB128 # 0 +0x9146 0xB129 # 0 +0x9147 0xB12A # 0 +0x9148 0xB12B # 0 +0x9149 0xB12C # 0 +0x914A 0xB12D # 0 +0x914B 0xB12E # 0 +0x914C 0xB12F # 0 +0x914D 0xB130 # 0 +0x914E 0xB131 # 0 +0x914F 0xB132 # 0 +0x9150 0xB133 # 0 +0x9151 0xB134 # 0 +0x9153 0xB135 # 0 +0x9154 0xB136 # 0 +0x9155 0xB137 # 0 +0x9156 0xB138 # 0 +0x9157 0xB139 # 0 +0x9158 0xB13A # 0 +0x9159 0xB13B # 0 +0x915A 0xB13C # 0 +0x915B 0xB13D # 0 +0x915C 0xB13E # 0 +0x915D 0xB13F # 0 +0x9161 0xB140 # 0 +0x9162 0xB141 # 0 +0x9163 0xB142 # 0 +0x9164 0xB143 # 0 +0x9165 0xB144 # 0 +0x9166 0xB145 # 0 +0x9167 0xB146 # 0 +0x9168 0xB147 # 0 +0x9169 0xB148 # 0 +0x916A 0xB149 # 0 +0x916B 0xB14A # 0 +0x916C 0xB14B # 0 +0x916D 0xB14C # 0 +0x916E 0xB14D # 0 +0x916F 0xB14E # 0 +0x9170 0xB14F # 0 +0x9171 0xB150 # 0 +0x9173 0xB151 # 0 +0x9174 0xB152 # 0 +0x9175 0xB153 # 0 +0x9176 0xB154 # 0 +0x9177 0xB155 # 0 +0x9178 0xB156 # 0 +0x9179 0xB157 # 0 +0x917A 0xB158 # 0 +0x917B 0xB159 # 0 +0x917C 0xB15A # 0 +0x917D 0xB15B # 0 +0x9181 0xB15C # 0 +0x9182 0xB15D # 0 +0x9183 0xB15E # 0 +0x9184 0xB15F # 0 +0x9185 0xB160 # 0 +0x9186 0xB161 # 0 +0x9187 0xB162 # 0 +0x9188 0xB163 # 0 +0x9189 0xB164 # 0 +0x918A 0xB165 # 0 +0x918B 0xB166 # 0 +0x918C 0xB167 # 0 +0x918D 0xB168 # 0 +0x918E 0xB169 # 0 +0x918F 0xB16A # 0 +0x9190 0xB16B # 0 +0x9191 0xB16C # 0 +0x9193 0xB16D # 0 +0x9194 0xB16E # 0 +0x9195 0xB16F # 0 +0x9196 0xB170 # 0 +0x9197 0xB171 # 0 +0x9198 0xB172 # 0 +0x9199 0xB173 # 0 +0x919A 0xB174 # 0 +0x919B 0xB175 # 0 +0x919C 0xB176 # 0 +0x919D 0xB177 # 0 +0x91A1 0xB178 # 0 +0x91A2 0xB179 # 0 +0x91A3 0xB17A # 0 +0x91A4 0xB17B # 0 +0x91A5 0xB17C # 0 +0x91A6 0xB17D # 0 +0x91A7 0xB17E # 0 +0x91A8 0xB17F # 0 +0x91A9 0xB180 # 0 +0x91AA 0xB181 # 0 +0x91AB 0xB182 # 0 +0x91AC 0xB183 # 0 +0x91AD 0xB184 # 0 +0x91AE 0xB185 # 0 +0x91AF 0xB186 # 0 +0x91B0 0xB187 # 0 +0x91B1 0xB188 # 0 +0x91B3 0xB189 # 0 +0x91B4 0xB18A # 0 +0x91B5 0xB18B # 0 +0x91B6 0xB18C # 0 +0x91B7 0xB18D # 0 +0x91B8 0xB18E # 0 +0x91B9 0xB18F # 0 +0x91BA 0xB190 # 0 +0x91BB 0xB191 # 0 +0x91BC 0xB192 # 0 +0x91BD 0xB193 # 0 +0x91C1 0xB194 # 0 +0x91C2 0xB195 # 0 +0x91C3 0xB196 # 0 +0x91C4 0xB197 # 0 +0x91C5 0xB198 # 0 +0x91C6 0xB199 # 0 +0x91C7 0xB19A # 0 +0x91C8 0xB19B # 0 +0x91C9 0xB19C # 0 +0x91CA 0xB19D # 0 +0x91CB 0xB19E # 0 +0x91CC 0xB19F # 0 +0x91CD 0xB1A0 # 0 +0x91CE 0xB1A1 # 0 +0x91CF 0xB1A2 # 0 +0x91D0 0xB1A3 # 0 +0x91D1 0xB1A4 # 0 +0x91D3 0xB1A5 # 0 +0x91D4 0xB1A6 # 0 +0x91D5 0xB1A7 # 0 +0x91D6 0xB1A8 # 0 +0x91D7 0xB1A9 # 0 +0x91D8 0xB1AA # 0 +0x91D9 0xB1AB # 0 +0x91DA 0xB1AC # 0 +0x91DB 0xB1AD # 0 +0x91DC 0xB1AE # 0 +0x91DD 0xB1AF # 0 +0x91E1 0xB1B0 # 0 +0x91E2 0xB1B1 # 0 +0x91E3 0xB1B2 # 0 +0x91E4 0xB1B3 # 0 +0x91E5 0xB1B4 # 0 +0x91E6 0xB1B5 # 0 +0x91E7 0xB1B6 # 0 +0x91E8 0xB1B7 # 0 +0x91E9 0xB1B8 # 0 +0x91EA 0xB1B9 # 0 +0x91EB 0xB1BA # 0 +0x91EC 0xB1BB # 0 +0x91ED 0xB1BC # 0 +0x91EE 0xB1BD # 0 +0x91EF 0xB1BE # 0 +0x91F0 0xB1BF # 0 +0x91F1 0xB1C0 # 0 +0x91F3 0xB1C1 # 0 +0x91F4 0xB1C2 # 0 +0x91F5 0xB1C3 # 0 +0x91F6 0xB1C4 # 0 +0x91F7 0xB1C5 # 0 +0x91F8 0xB1C6 # 0 +0x91F9 0xB1C7 # 0 +0x91FA 0xB1C8 # 0 +0x91FB 0xB1C9 # 0 +0x91FC 0xB1CA # 0 +0x91FD 0xB1CB # 0 +0x9241 0xB1CC # 0 +0x9242 0xB1CD # 0 +0x9243 0xB1CE # 0 +0x9244 0xB1CF # 0 +0x9245 0xB1D0 # 0 +0x9246 0xB1D1 # 0 +0x9247 0xB1D2 # 0 +0x9248 0xB1D3 # 0 +0x9249 0xB1D4 # 0 +0x924A 0xB1D5 # 0 +0x924B 0xB1D6 # 0 +0x924C 0xB1D7 # 0 +0x924D 0xB1D8 # 0 +0x924E 0xB1D9 # 0 +0x924F 0xB1DA # 0 +0x9250 0xB1DB # 0 +0x9251 0xB1DC # 0 +0x9253 0xB1DD # 0 +0x9254 0xB1DE # 0 +0x9255 0xB1DF # 0 +0x9256 0xB1E0 # 0 +0x9257 0xB1E1 # 0 +0x9258 0xB1E2 # 0 +0x9259 0xB1E3 # 0 +0x925A 0xB1E4 # 0 +0x925B 0xB1E5 # 0 +0x925C 0xB1E6 # 0 +0x925D 0xB1E7 # 0 +0x9261 0xB1E8 # 0 +0x9262 0xB1E9 # 0 +0x9263 0xB1EA # 0 +0x9264 0xB1EB # 0 +0x9265 0xB1EC # 0 +0x9266 0xB1ED # 0 +0x9267 0xB1EE # 0 +0x9268 0xB1EF # 0 +0x9269 0xB1F0 # 0 +0x926A 0xB1F1 # 0 +0x926B 0xB1F2 # 0 +0x926C 0xB1F3 # 0 +0x926D 0xB1F4 # 0 +0x926E 0xB1F5 # 0 +0x926F 0xB1F6 # 0 +0x9270 0xB1F7 # 0 +0x9271 0xB1F8 # 0 +0x9273 0xB1F9 # 0 +0x9274 0xB1FA # 0 +0x9275 0xB1FB # 0 +0x9276 0xB1FC # 0 +0x9277 0xB1FD # 0 +0x9278 0xB1FE # 0 +0x9279 0xB1FF # 0 +0x927A 0xB200 # 0 +0x927B 0xB201 # 0 +0x927C 0xB202 # 0 +0x927D 0xB203 # 0 +0x9281 0xB204 # 0 +0x9282 0xB205 # 0 +0x9283 0xB206 # 0 +0x9284 0xB207 # 0 +0x9285 0xB208 # 0 +0x9286 0xB209 # 0 +0x9287 0xB20A # 0 +0x9288 0xB20B # 0 +0x9289 0xB20C # 0 +0x928A 0xB20D # 0 +0x928B 0xB20E # 0 +0x928C 0xB20F # 0 +0x928D 0xB210 # 0 +0x928E 0xB211 # 0 +0x928F 0xB212 # 0 +0x9290 0xB213 # 0 +0x9291 0xB214 # 0 +0x9293 0xB215 # 0 +0x9294 0xB216 # 0 +0x9295 0xB217 # 0 +0x9296 0xB218 # 0 +0x9297 0xB219 # 0 +0x9298 0xB21A # 0 +0x9299 0xB21B # 0 +0x929A 0xB21C # 0 +0x929B 0xB21D # 0 +0x929C 0xB21E # 0 +0x929D 0xB21F # 0 +0x92A1 0xB220 # 0 +0x92A2 0xB221 # 0 +0x92A3 0xB222 # 0 +0x92A4 0xB223 # 0 +0x92A5 0xB224 # 0 +0x92A6 0xB225 # 0 +0x92A7 0xB226 # 0 +0x92A8 0xB227 # 0 +0x92A9 0xB228 # 0 +0x92AA 0xB229 # 0 +0x92AB 0xB22A # 0 +0x92AC 0xB22B # 0 +0x92AD 0xB22C # 0 +0x92AE 0xB22D # 0 +0x92AF 0xB22E # 0 +0x92B0 0xB22F # 0 +0x92B1 0xB230 # 0 +0x92B3 0xB231 # 0 +0x92B4 0xB232 # 0 +0x92B5 0xB233 # 0 +0x92B6 0xB234 # 0 +0x92B7 0xB235 # 0 +0x92B8 0xB236 # 0 +0x92B9 0xB237 # 0 +0x92BA 0xB238 # 0 +0x92BB 0xB239 # 0 +0x92BC 0xB23A # 0 +0x92BD 0xB23B # 0 +0x92C1 0xB23C # 0 +0x92C2 0xB23D # 0 +0x92C3 0xB23E # 0 +0x92C4 0xB23F # 0 +0x92C5 0xB240 # 0 +0x92C6 0xB241 # 0 +0x92C7 0xB242 # 0 +0x92C8 0xB243 # 0 +0x92C9 0xB244 # 0 +0x92CA 0xB245 # 0 +0x92CB 0xB246 # 0 +0x92CC 0xB247 # 0 +0x92CD 0xB248 # 0 +0x92CE 0xB249 # 0 +0x92CF 0xB24A # 0 +0x92D0 0xB24B # 0 +0x92D1 0xB24C # 0 +0x92D3 0xB24D # 0 +0x92D4 0xB24E # 0 +0x92D5 0xB24F # 0 +0x92D6 0xB250 # 0 +0x92D7 0xB251 # 0 +0x92D8 0xB252 # 0 +0x92D9 0xB253 # 0 +0x92DA 0xB254 # 0 +0x92DB 0xB255 # 0 +0x92DC 0xB256 # 0 +0x92DD 0xB257 # 0 +0x92E1 0xB258 # 0 +0x92E2 0xB259 # 0 +0x92E3 0xB25A # 0 +0x92E4 0xB25B # 0 +0x92E5 0xB25C # 0 +0x92E6 0xB25D # 0 +0x92E7 0xB25E # 0 +0x92E8 0xB25F # 0 +0x92E9 0xB260 # 0 +0x92EA 0xB261 # 0 +0x92EB 0xB262 # 0 +0x92EC 0xB263 # 0 +0x92ED 0xB264 # 0 +0x92EE 0xB265 # 0 +0x92EF 0xB266 # 0 +0x92F0 0xB267 # 0 +0x92F1 0xB268 # 0 +0x92F3 0xB269 # 0 +0x92F4 0xB26A # 0 +0x92F5 0xB26B # 0 +0x92F6 0xB26C # 0 +0x92F7 0xB26D # 0 +0x92F8 0xB26E # 0 +0x92F9 0xB26F # 0 +0x92FA 0xB270 # 0 +0x92FB 0xB271 # 0 +0x92FC 0xB272 # 0 +0x92FD 0xB273 # 0 +0x9341 0xB274 # 0 +0x9342 0xB275 # 0 +0x9343 0xB276 # 0 +0x9344 0xB277 # 0 +0x9345 0xB278 # 0 +0x9346 0xB279 # 0 +0x9347 0xB27A # 0 +0x9348 0xB27B # 0 +0x9349 0xB27C # 0 +0x934A 0xB27D # 0 +0x934B 0xB27E # 0 +0x934C 0xB27F # 0 +0x934D 0xB280 # 0 +0x934E 0xB281 # 0 +0x934F 0xB282 # 0 +0x9350 0xB283 # 0 +0x9351 0xB284 # 0 +0x9353 0xB285 # 0 +0x9354 0xB286 # 0 +0x9355 0xB287 # 0 +0x9356 0xB288 # 0 +0x9357 0xB289 # 0 +0x9358 0xB28A # 0 +0x9359 0xB28B # 0 +0x935A 0xB28C # 0 +0x935B 0xB28D # 0 +0x935C 0xB28E # 0 +0x935D 0xB28F # 0 +0x9361 0xB290 # 0 +0x9362 0xB291 # 0 +0x9363 0xB292 # 0 +0x9364 0xB293 # 0 +0x9365 0xB294 # 0 +0x9366 0xB295 # 0 +0x9367 0xB296 # 0 +0x9368 0xB297 # 0 +0x9369 0xB298 # 0 +0x936A 0xB299 # 0 +0x936B 0xB29A # 0 +0x936C 0xB29B # 0 +0x936D 0xB29C # 0 +0x936E 0xB29D # 0 +0x936F 0xB29E # 0 +0x9370 0xB29F # 0 +0x9371 0xB2A0 # 0 +0x9373 0xB2A1 # 0 +0x9374 0xB2A2 # 0 +0x9375 0xB2A3 # 0 +0x9376 0xB2A4 # 0 +0x9377 0xB2A5 # 0 +0x9378 0xB2A6 # 0 +0x9379 0xB2A7 # 0 +0x937A 0xB2A8 # 0 +0x937B 0xB2A9 # 0 +0x937C 0xB2AA # 0 +0x937D 0xB2AB # 0 +0x9381 0xB2AC # 0 +0x9382 0xB2AD # 0 +0x9383 0xB2AE # 0 +0x9384 0xB2AF # 0 +0x9385 0xB2B0 # 0 +0x9386 0xB2B1 # 0 +0x9387 0xB2B2 # 0 +0x9388 0xB2B3 # 0 +0x9389 0xB2B4 # 0 +0x938A 0xB2B5 # 0 +0x938B 0xB2B6 # 0 +0x938C 0xB2B7 # 0 +0x938D 0xB2B8 # 0 +0x938E 0xB2B9 # 0 +0x938F 0xB2BA # 0 +0x9390 0xB2BB # 0 +0x9391 0xB2BC # 0 +0x9393 0xB2BD # 0 +0x9394 0xB2BE # 0 +0x9395 0xB2BF # 0 +0x9396 0xB2C0 # 0 +0x9397 0xB2C1 # 0 +0x9398 0xB2C2 # 0 +0x9399 0xB2C3 # 0 +0x939A 0xB2C4 # 0 +0x939B 0xB2C5 # 0 +0x939C 0xB2C6 # 0 +0x939D 0xB2C7 # 0 +0x93A1 0xB2C8 # 0 +0x93A2 0xB2C9 # 0 +0x93A3 0xB2CA # 0 +0x93A4 0xB2CB # 0 +0x93A5 0xB2CC # 0 +0x93A6 0xB2CD # 0 +0x93A7 0xB2CE # 0 +0x93A8 0xB2CF # 0 +0x93A9 0xB2D0 # 0 +0x93AA 0xB2D1 # 0 +0x93AB 0xB2D2 # 0 +0x93AC 0xB2D3 # 0 +0x93AD 0xB2D4 # 0 +0x93AE 0xB2D5 # 0 +0x93AF 0xB2D6 # 0 +0x93B0 0xB2D7 # 0 +0x93B1 0xB2D8 # 0 +0x93B3 0xB2D9 # 0 +0x93B4 0xB2DA # 0 +0x93B5 0xB2DB # 0 +0x93B6 0xB2DC # 0 +0x93B7 0xB2DD # 0 +0x93B8 0xB2DE # 0 +0x93B9 0xB2DF # 0 +0x93BA 0xB2E0 # 0 +0x93BB 0xB2E1 # 0 +0x93BC 0xB2E2 # 0 +0x93BD 0xB2E3 # 0 +0x9441 0x1103 # 0 +0x9461 0xB2E4 # 0 +0x9462 0xB2E5 # 0 +0x9463 0xB2E6 # 0 +0x9464 0xB2E7 # 0 +0x9465 0xB2E8 # 0 +0x9466 0xB2E9 # 0 +0x9467 0xB2EA # 0 +0x9468 0xB2EB # 0 +0x9469 0xB2EC # 0 +0x946A 0xB2ED # 0 +0x946B 0xB2EE # 0 +0x946C 0xB2EF # 0 +0x946D 0xB2F0 # 0 +0x946E 0xB2F1 # 0 +0x946F 0xB2F2 # 0 +0x9470 0xB2F3 # 0 +0x9471 0xB2F4 # 0 +0x9473 0xB2F5 # 0 +0x9474 0xB2F6 # 0 +0x9475 0xB2F7 # 0 +0x9476 0xB2F8 # 0 +0x9477 0xB2F9 # 0 +0x9478 0xB2FA # 0 +0x9479 0xB2FB # 0 +0x947A 0xB2FC # 0 +0x947B 0xB2FD # 0 +0x947C 0xB2FE # 0 +0x947D 0xB2FF # 0 +0x9481 0xB300 # 0 +0x9482 0xB301 # 0 +0x9483 0xB302 # 0 +0x9484 0xB303 # 0 +0x9485 0xB304 # 0 +0x9486 0xB305 # 0 +0x9487 0xB306 # 0 +0x9488 0xB307 # 0 +0x9489 0xB308 # 0 +0x948A 0xB309 # 0 +0x948B 0xB30A # 0 +0x948C 0xB30B # 0 +0x948D 0xB30C # 0 +0x948E 0xB30D # 0 +0x948F 0xB30E # 0 +0x9490 0xB30F # 0 +0x9491 0xB310 # 0 +0x9493 0xB311 # 0 +0x9494 0xB312 # 0 +0x9495 0xB313 # 0 +0x9496 0xB314 # 0 +0x9497 0xB315 # 0 +0x9498 0xB316 # 0 +0x9499 0xB317 # 0 +0x949A 0xB318 # 0 +0x949B 0xB319 # 0 +0x949C 0xB31A # 0 +0x949D 0xB31B # 0 +0x94A1 0xB31C # 0 +0x94A2 0xB31D # 0 +0x94A3 0xB31E # 0 +0x94A4 0xB31F # 0 +0x94A5 0xB320 # 0 +0x94A6 0xB321 # 0 +0x94A7 0xB322 # 0 +0x94A8 0xB323 # 0 +0x94A9 0xB324 # 0 +0x94AA 0xB325 # 0 +0x94AB 0xB326 # 0 +0x94AC 0xB327 # 0 +0x94AD 0xB328 # 0 +0x94AE 0xB329 # 0 +0x94AF 0xB32A # 0 +0x94B0 0xB32B # 0 +0x94B1 0xB32C # 0 +0x94B3 0xB32D # 0 +0x94B4 0xB32E # 0 +0x94B5 0xB32F # 0 +0x94B6 0xB330 # 0 +0x94B7 0xB331 # 0 +0x94B8 0xB332 # 0 +0x94B9 0xB333 # 0 +0x94BA 0xB334 # 0 +0x94BB 0xB335 # 0 +0x94BC 0xB336 # 0 +0x94BD 0xB337 # 0 +0x94C1 0xB338 # 0 +0x94C2 0xB339 # 0 +0x94C3 0xB33A # 0 +0x94C4 0xB33B # 0 +0x94C5 0xB33C # 0 +0x94C6 0xB33D # 0 +0x94C7 0xB33E # 0 +0x94C8 0xB33F # 0 +0x94C9 0xB340 # 0 +0x94CA 0xB341 # 0 +0x94CB 0xB342 # 0 +0x94CC 0xB343 # 0 +0x94CD 0xB344 # 0 +0x94CE 0xB345 # 0 +0x94CF 0xB346 # 0 +0x94D0 0xB347 # 0 +0x94D1 0xB348 # 0 +0x94D3 0xB349 # 0 +0x94D4 0xB34A # 0 +0x94D5 0xB34B # 0 +0x94D6 0xB34C # 0 +0x94D7 0xB34D # 0 +0x94D8 0xB34E # 0 +0x94D9 0xB34F # 0 +0x94DA 0xB350 # 0 +0x94DB 0xB351 # 0 +0x94DC 0xB352 # 0 +0x94DD 0xB353 # 0 +0x94E1 0xB354 # 0 +0x94E2 0xB355 # 0 +0x94E3 0xB356 # 0 +0x94E4 0xB357 # 0 +0x94E5 0xB358 # 0 +0x94E6 0xB359 # 0 +0x94E7 0xB35A # 0 +0x94E8 0xB35B # 0 +0x94E9 0xB35C # 0 +0x94EA 0xB35D # 0 +0x94EB 0xB35E # 0 +0x94EC 0xB35F # 0 +0x94ED 0xB360 # 0 +0x94EE 0xB361 # 0 +0x94EF 0xB362 # 0 +0x94F0 0xB363 # 0 +0x94F1 0xB364 # 0 +0x94F3 0xB365 # 0 +0x94F4 0xB366 # 0 +0x94F5 0xB367 # 0 +0x94F6 0xB368 # 0 +0x94F7 0xB369 # 0 +0x94F8 0xB36A # 0 +0x94F9 0xB36B # 0 +0x94FA 0xB36C # 0 +0x94FB 0xB36D # 0 +0x94FC 0xB36E # 0 +0x94FD 0xB36F # 0 +0x9541 0xB370 # 0 +0x9542 0xB371 # 0 +0x9543 0xB372 # 0 +0x9544 0xB373 # 0 +0x9545 0xB374 # 0 +0x9546 0xB375 # 0 +0x9547 0xB376 # 0 +0x9548 0xB377 # 0 +0x9549 0xB378 # 0 +0x954A 0xB379 # 0 +0x954B 0xB37A # 0 +0x954C 0xB37B # 0 +0x954D 0xB37C # 0 +0x954E 0xB37D # 0 +0x954F 0xB37E # 0 +0x9550 0xB37F # 0 +0x9551 0xB380 # 0 +0x9553 0xB381 # 0 +0x9554 0xB382 # 0 +0x9555 0xB383 # 0 +0x9556 0xB384 # 0 +0x9557 0xB385 # 0 +0x9558 0xB386 # 0 +0x9559 0xB387 # 0 +0x955A 0xB388 # 0 +0x955B 0xB389 # 0 +0x955C 0xB38A # 0 +0x955D 0xB38B # 0 +0x9561 0xB38C # 0 +0x9562 0xB38D # 0 +0x9563 0xB38E # 0 +0x9564 0xB38F # 0 +0x9565 0xB390 # 0 +0x9566 0xB391 # 0 +0x9567 0xB392 # 0 +0x9568 0xB393 # 0 +0x9569 0xB394 # 0 +0x956A 0xB395 # 0 +0x956B 0xB396 # 0 +0x956C 0xB397 # 0 +0x956D 0xB398 # 0 +0x956E 0xB399 # 0 +0x956F 0xB39A # 0 +0x9570 0xB39B # 0 +0x9571 0xB39C # 0 +0x9573 0xB39D # 0 +0x9574 0xB39E # 0 +0x9575 0xB39F # 0 +0x9576 0xB3A0 # 0 +0x9577 0xB3A1 # 0 +0x9578 0xB3A2 # 0 +0x9579 0xB3A3 # 0 +0x957A 0xB3A4 # 0 +0x957B 0xB3A5 # 0 +0x957C 0xB3A6 # 0 +0x957D 0xB3A7 # 0 +0x9581 0xB3A8 # 0 +0x9582 0xB3A9 # 0 +0x9583 0xB3AA # 0 +0x9584 0xB3AB # 0 +0x9585 0xB3AC # 0 +0x9586 0xB3AD # 0 +0x9587 0xB3AE # 0 +0x9588 0xB3AF # 0 +0x9589 0xB3B0 # 0 +0x958A 0xB3B1 # 0 +0x958B 0xB3B2 # 0 +0x958C 0xB3B3 # 0 +0x958D 0xB3B4 # 0 +0x958E 0xB3B5 # 0 +0x958F 0xB3B6 # 0 +0x9590 0xB3B7 # 0 +0x9591 0xB3B8 # 0 +0x9593 0xB3B9 # 0 +0x9594 0xB3BA # 0 +0x9595 0xB3BB # 0 +0x9596 0xB3BC # 0 +0x9597 0xB3BD # 0 +0x9598 0xB3BE # 0 +0x9599 0xB3BF # 0 +0x959A 0xB3C0 # 0 +0x959B 0xB3C1 # 0 +0x959C 0xB3C2 # 0 +0x959D 0xB3C3 # 0 +0x95A1 0xB3C4 # 0 +0x95A2 0xB3C5 # 0 +0x95A3 0xB3C6 # 0 +0x95A4 0xB3C7 # 0 +0x95A5 0xB3C8 # 0 +0x95A6 0xB3C9 # 0 +0x95A7 0xB3CA # 0 +0x95A8 0xB3CB # 0 +0x95A9 0xB3CC # 0 +0x95AA 0xB3CD # 0 +0x95AB 0xB3CE # 0 +0x95AC 0xB3CF # 0 +0x95AD 0xB3D0 # 0 +0x95AE 0xB3D1 # 0 +0x95AF 0xB3D2 # 0 +0x95B0 0xB3D3 # 0 +0x95B1 0xB3D4 # 0 +0x95B3 0xB3D5 # 0 +0x95B4 0xB3D6 # 0 +0x95B5 0xB3D7 # 0 +0x95B6 0xB3D8 # 0 +0x95B7 0xB3D9 # 0 +0x95B8 0xB3DA # 0 +0x95B9 0xB3DB # 0 +0x95BA 0xB3DC # 0 +0x95BB 0xB3DD # 0 +0x95BC 0xB3DE # 0 +0x95BD 0xB3DF # 0 +0x95C1 0xB3E0 # 0 +0x95C2 0xB3E1 # 0 +0x95C3 0xB3E2 # 0 +0x95C4 0xB3E3 # 0 +0x95C5 0xB3E4 # 0 +0x95C6 0xB3E5 # 0 +0x95C7 0xB3E6 # 0 +0x95C8 0xB3E7 # 0 +0x95C9 0xB3E8 # 0 +0x95CA 0xB3E9 # 0 +0x95CB 0xB3EA # 0 +0x95CC 0xB3EB # 0 +0x95CD 0xB3EC # 0 +0x95CE 0xB3ED # 0 +0x95CF 0xB3EE # 0 +0x95D0 0xB3EF # 0 +0x95D1 0xB3F0 # 0 +0x95D3 0xB3F1 # 0 +0x95D4 0xB3F2 # 0 +0x95D5 0xB3F3 # 0 +0x95D6 0xB3F4 # 0 +0x95D7 0xB3F5 # 0 +0x95D8 0xB3F6 # 0 +0x95D9 0xB3F7 # 0 +0x95DA 0xB3F8 # 0 +0x95DB 0xB3F9 # 0 +0x95DC 0xB3FA # 0 +0x95DD 0xB3FB # 0 +0x95E1 0xB3FC # 0 +0x95E2 0xB3FD # 0 +0x95E3 0xB3FE # 0 +0x95E4 0xB3FF # 0 +0x95E5 0xB400 # 0 +0x95E6 0xB401 # 0 +0x95E7 0xB402 # 0 +0x95E8 0xB403 # 0 +0x95E9 0xB404 # 0 +0x95EA 0xB405 # 0 +0x95EB 0xB406 # 0 +0x95EC 0xB407 # 0 +0x95ED 0xB408 # 0 +0x95EE 0xB409 # 0 +0x95EF 0xB40A # 0 +0x95F0 0xB40B # 0 +0x95F1 0xB40C # 0 +0x95F3 0xB40D # 0 +0x95F4 0xB40E # 0 +0x95F5 0xB40F # 0 +0x95F6 0xB410 # 0 +0x95F7 0xB411 # 0 +0x95F8 0xB412 # 0 +0x95F9 0xB413 # 0 +0x95FA 0xB414 # 0 +0x95FB 0xB415 # 0 +0x95FC 0xB416 # 0 +0x95FD 0xB417 # 0 +0x9641 0xB418 # 0 +0x9642 0xB419 # 0 +0x9643 0xB41A # 0 +0x9644 0xB41B # 0 +0x9645 0xB41C # 0 +0x9646 0xB41D # 0 +0x9647 0xB41E # 0 +0x9648 0xB41F # 0 +0x9649 0xB420 # 0 +0x964A 0xB421 # 0 +0x964B 0xB422 # 0 +0x964C 0xB423 # 0 +0x964D 0xB424 # 0 +0x964E 0xB425 # 0 +0x964F 0xB426 # 0 +0x9650 0xB427 # 0 +0x9651 0xB428 # 0 +0x9653 0xB429 # 0 +0x9654 0xB42A # 0 +0x9655 0xB42B # 0 +0x9656 0xB42C # 0 +0x9657 0xB42D # 0 +0x9658 0xB42E # 0 +0x9659 0xB42F # 0 +0x965A 0xB430 # 0 +0x965B 0xB431 # 0 +0x965C 0xB432 # 0 +0x965D 0xB433 # 0 +0x9661 0xB434 # 0 +0x9662 0xB435 # 0 +0x9663 0xB436 # 0 +0x9664 0xB437 # 0 +0x9665 0xB438 # 0 +0x9666 0xB439 # 0 +0x9667 0xB43A # 0 +0x9668 0xB43B # 0 +0x9669 0xB43C # 0 +0x966A 0xB43D # 0 +0x966B 0xB43E # 0 +0x966C 0xB43F # 0 +0x966D 0xB440 # 0 +0x966E 0xB441 # 0 +0x966F 0xB442 # 0 +0x9670 0xB443 # 0 +0x9671 0xB444 # 0 +0x9673 0xB445 # 0 +0x9674 0xB446 # 0 +0x9675 0xB447 # 0 +0x9676 0xB448 # 0 +0x9677 0xB449 # 0 +0x9678 0xB44A # 0 +0x9679 0xB44B # 0 +0x967A 0xB44C # 0 +0x967B 0xB44D # 0 +0x967C 0xB44E # 0 +0x967D 0xB44F # 0 +0x9681 0xB450 # 0 +0x9682 0xB451 # 0 +0x9683 0xB452 # 0 +0x9684 0xB453 # 0 +0x9685 0xB454 # 0 +0x9686 0xB455 # 0 +0x9687 0xB456 # 0 +0x9688 0xB457 # 0 +0x9689 0xB458 # 0 +0x968A 0xB459 # 0 +0x968B 0xB45A # 0 +0x968C 0xB45B # 0 +0x968D 0xB45C # 0 +0x968E 0xB45D # 0 +0x968F 0xB45E # 0 +0x9690 0xB45F # 0 +0x9691 0xB460 # 0 +0x9693 0xB461 # 0 +0x9694 0xB462 # 0 +0x9695 0xB463 # 0 +0x9696 0xB464 # 0 +0x9697 0xB465 # 0 +0x9698 0xB466 # 0 +0x9699 0xB467 # 0 +0x969A 0xB468 # 0 +0x969B 0xB469 # 0 +0x969C 0xB46A # 0 +0x969D 0xB46B # 0 +0x96A1 0xB46C # 0 +0x96A2 0xB46D # 0 +0x96A3 0xB46E # 0 +0x96A4 0xB46F # 0 +0x96A5 0xB470 # 0 +0x96A6 0xB471 # 0 +0x96A7 0xB472 # 0 +0x96A8 0xB473 # 0 +0x96A9 0xB474 # 0 +0x96AA 0xB475 # 0 +0x96AB 0xB476 # 0 +0x96AC 0xB477 # 0 +0x96AD 0xB478 # 0 +0x96AE 0xB479 # 0 +0x96AF 0xB47A # 0 +0x96B0 0xB47B # 0 +0x96B1 0xB47C # 0 +0x96B3 0xB47D # 0 +0x96B4 0xB47E # 0 +0x96B5 0xB47F # 0 +0x96B6 0xB480 # 0 +0x96B7 0xB481 # 0 +0x96B8 0xB482 # 0 +0x96B9 0xB483 # 0 +0x96BA 0xB484 # 0 +0x96BB 0xB485 # 0 +0x96BC 0xB486 # 0 +0x96BD 0xB487 # 0 +0x96C1 0xB488 # 0 +0x96C2 0xB489 # 0 +0x96C3 0xB48A # 0 +0x96C4 0xB48B # 0 +0x96C5 0xB48C # 0 +0x96C6 0xB48D # 0 +0x96C7 0xB48E # 0 +0x96C8 0xB48F # 0 +0x96C9 0xB490 # 0 +0x96CA 0xB491 # 0 +0x96CB 0xB492 # 0 +0x96CC 0xB493 # 0 +0x96CD 0xB494 # 0 +0x96CE 0xB495 # 0 +0x96CF 0xB496 # 0 +0x96D0 0xB497 # 0 +0x96D1 0xB498 # 0 +0x96D3 0xB499 # 0 +0x96D4 0xB49A # 0 +0x96D5 0xB49B # 0 +0x96D6 0xB49C # 0 +0x96D7 0xB49D # 0 +0x96D8 0xB49E # 0 +0x96D9 0xB49F # 0 +0x96DA 0xB4A0 # 0 +0x96DB 0xB4A1 # 0 +0x96DC 0xB4A2 # 0 +0x96DD 0xB4A3 # 0 +0x96E1 0xB4A4 # 0 +0x96E2 0xB4A5 # 0 +0x96E3 0xB4A6 # 0 +0x96E4 0xB4A7 # 0 +0x96E5 0xB4A8 # 0 +0x96E6 0xB4A9 # 0 +0x96E7 0xB4AA # 0 +0x96E8 0xB4AB # 0 +0x96E9 0xB4AC # 0 +0x96EA 0xB4AD # 0 +0x96EB 0xB4AE # 0 +0x96EC 0xB4AF # 0 +0x96ED 0xB4B0 # 0 +0x96EE 0xB4B1 # 0 +0x96EF 0xB4B2 # 0 +0x96F0 0xB4B3 # 0 +0x96F1 0xB4B4 # 0 +0x96F3 0xB4B5 # 0 +0x96F4 0xB4B6 # 0 +0x96F5 0xB4B7 # 0 +0x96F6 0xB4B8 # 0 +0x96F7 0xB4B9 # 0 +0x96F8 0xB4BA # 0 +0x96F9 0xB4BB # 0 +0x96FA 0xB4BC # 0 +0x96FB 0xB4BD # 0 +0x96FC 0xB4BE # 0 +0x96FD 0xB4BF # 0 +0x9741 0xB4C0 # 0 +0x9742 0xB4C1 # 0 +0x9743 0xB4C2 # 0 +0x9744 0xB4C3 # 0 +0x9745 0xB4C4 # 0 +0x9746 0xB4C5 # 0 +0x9747 0xB4C6 # 0 +0x9748 0xB4C7 # 0 +0x9749 0xB4C8 # 0 +0x974A 0xB4C9 # 0 +0x974B 0xB4CA # 0 +0x974C 0xB4CB # 0 +0x974D 0xB4CC # 0 +0x974E 0xB4CD # 0 +0x974F 0xB4CE # 0 +0x9750 0xB4CF # 0 +0x9751 0xB4D0 # 0 +0x9753 0xB4D1 # 0 +0x9754 0xB4D2 # 0 +0x9755 0xB4D3 # 0 +0x9756 0xB4D4 # 0 +0x9757 0xB4D5 # 0 +0x9758 0xB4D6 # 0 +0x9759 0xB4D7 # 0 +0x975A 0xB4D8 # 0 +0x975B 0xB4D9 # 0 +0x975C 0xB4DA # 0 +0x975D 0xB4DB # 0 +0x9761 0xB4DC # 0 +0x9762 0xB4DD # 0 +0x9763 0xB4DE # 0 +0x9764 0xB4DF # 0 +0x9765 0xB4E0 # 0 +0x9766 0xB4E1 # 0 +0x9767 0xB4E2 # 0 +0x9768 0xB4E3 # 0 +0x9769 0xB4E4 # 0 +0x976A 0xB4E5 # 0 +0x976B 0xB4E6 # 0 +0x976C 0xB4E7 # 0 +0x976D 0xB4E8 # 0 +0x976E 0xB4E9 # 0 +0x976F 0xB4EA # 0 +0x9770 0xB4EB # 0 +0x9771 0xB4EC # 0 +0x9773 0xB4ED # 0 +0x9774 0xB4EE # 0 +0x9775 0xB4EF # 0 +0x9776 0xB4F0 # 0 +0x9777 0xB4F1 # 0 +0x9778 0xB4F2 # 0 +0x9779 0xB4F3 # 0 +0x977A 0xB4F4 # 0 +0x977B 0xB4F5 # 0 +0x977C 0xB4F6 # 0 +0x977D 0xB4F7 # 0 +0x9781 0xB4F8 # 0 +0x9782 0xB4F9 # 0 +0x9783 0xB4FA # 0 +0x9784 0xB4FB # 0 +0x9785 0xB4FC # 0 +0x9786 0xB4FD # 0 +0x9787 0xB4FE # 0 +0x9788 0xB4FF # 0 +0x9789 0xB500 # 0 +0x978A 0xB501 # 0 +0x978B 0xB502 # 0 +0x978C 0xB503 # 0 +0x978D 0xB504 # 0 +0x978E 0xB505 # 0 +0x978F 0xB506 # 0 +0x9790 0xB507 # 0 +0x9791 0xB508 # 0 +0x9793 0xB509 # 0 +0x9794 0xB50A # 0 +0x9795 0xB50B # 0 +0x9796 0xB50C # 0 +0x9797 0xB50D # 0 +0x9798 0xB50E # 0 +0x9799 0xB50F # 0 +0x979A 0xB510 # 0 +0x979B 0xB511 # 0 +0x979C 0xB512 # 0 +0x979D 0xB513 # 0 +0x97A1 0xB514 # 0 +0x97A2 0xB515 # 0 +0x97A3 0xB516 # 0 +0x97A4 0xB517 # 0 +0x97A5 0xB518 # 0 +0x97A6 0xB519 # 0 +0x97A7 0xB51A # 0 +0x97A8 0xB51B # 0 +0x97A9 0xB51C # 0 +0x97AA 0xB51D # 0 +0x97AB 0xB51E # 0 +0x97AC 0xB51F # 0 +0x97AD 0xB520 # 0 +0x97AE 0xB521 # 0 +0x97AF 0xB522 # 0 +0x97B0 0xB523 # 0 +0x97B1 0xB524 # 0 +0x97B3 0xB525 # 0 +0x97B4 0xB526 # 0 +0x97B5 0xB527 # 0 +0x97B6 0xB528 # 0 +0x97B7 0xB529 # 0 +0x97B8 0xB52A # 0 +0x97B9 0xB52B # 0 +0x97BA 0xB52C # 0 +0x97BB 0xB52D # 0 +0x97BC 0xB52E # 0 +0x97BD 0xB52F # 0 +0x9841 0x1104 # 0 +0x9861 0xB530 # 0 +0x9862 0xB531 # 0 +0x9863 0xB532 # 0 +0x9864 0xB533 # 0 +0x9865 0xB534 # 0 +0x9866 0xB535 # 0 +0x9867 0xB536 # 0 +0x9868 0xB537 # 0 +0x9869 0xB538 # 0 +0x986A 0xB539 # 0 +0x986B 0xB53A # 0 +0x986C 0xB53B # 0 +0x986D 0xB53C # 0 +0x986E 0xB53D # 0 +0x986F 0xB53E # 0 +0x9870 0xB53F # 0 +0x9871 0xB540 # 0 +0x9873 0xB541 # 0 +0x9874 0xB542 # 0 +0x9875 0xB543 # 0 +0x9876 0xB544 # 0 +0x9877 0xB545 # 0 +0x9878 0xB546 # 0 +0x9879 0xB547 # 0 +0x987A 0xB548 # 0 +0x987B 0xB549 # 0 +0x987C 0xB54A # 0 +0x987D 0xB54B # 0 +0x9881 0xB54C # 0 +0x9882 0xB54D # 0 +0x9883 0xB54E # 0 +0x9884 0xB54F # 0 +0x9885 0xB550 # 0 +0x9886 0xB551 # 0 +0x9887 0xB552 # 0 +0x9888 0xB553 # 0 +0x9889 0xB554 # 0 +0x988A 0xB555 # 0 +0x988B 0xB556 # 0 +0x988C 0xB557 # 0 +0x988D 0xB558 # 0 +0x988E 0xB559 # 0 +0x988F 0xB55A # 0 +0x9890 0xB55B # 0 +0x9891 0xB55C # 0 +0x9893 0xB55D # 0 +0x9894 0xB55E # 0 +0x9895 0xB55F # 0 +0x9896 0xB560 # 0 +0x9897 0xB561 # 0 +0x9898 0xB562 # 0 +0x9899 0xB563 # 0 +0x989A 0xB564 # 0 +0x989B 0xB565 # 0 +0x989C 0xB566 # 0 +0x989D 0xB567 # 0 +0x98A1 0xB568 # 0 +0x98A2 0xB569 # 0 +0x98A3 0xB56A # 0 +0x98A4 0xB56B # 0 +0x98A5 0xB56C # 0 +0x98A6 0xB56D # 0 +0x98A7 0xB56E # 0 +0x98A8 0xB56F # 0 +0x98A9 0xB570 # 0 +0x98AA 0xB571 # 0 +0x98AB 0xB572 # 0 +0x98AC 0xB573 # 0 +0x98AD 0xB574 # 0 +0x98AE 0xB575 # 0 +0x98AF 0xB576 # 0 +0x98B0 0xB577 # 0 +0x98B1 0xB578 # 0 +0x98B3 0xB579 # 0 +0x98B4 0xB57A # 0 +0x98B5 0xB57B # 0 +0x98B6 0xB57C # 0 +0x98B7 0xB57D # 0 +0x98B8 0xB57E # 0 +0x98B9 0xB57F # 0 +0x98BA 0xB580 # 0 +0x98BB 0xB581 # 0 +0x98BC 0xB582 # 0 +0x98BD 0xB583 # 0 +0x98C1 0xB584 # 0 +0x98C2 0xB585 # 0 +0x98C3 0xB586 # 0 +0x98C4 0xB587 # 0 +0x98C5 0xB588 # 0 +0x98C6 0xB589 # 0 +0x98C7 0xB58A # 0 +0x98C8 0xB58B # 0 +0x98C9 0xB58C # 0 +0x98CA 0xB58D # 0 +0x98CB 0xB58E # 0 +0x98CC 0xB58F # 0 +0x98CD 0xB590 # 0 +0x98CE 0xB591 # 0 +0x98CF 0xB592 # 0 +0x98D0 0xB593 # 0 +0x98D1 0xB594 # 0 +0x98D3 0xB595 # 0 +0x98D4 0xB596 # 0 +0x98D5 0xB597 # 0 +0x98D6 0xB598 # 0 +0x98D7 0xB599 # 0 +0x98D8 0xB59A # 0 +0x98D9 0xB59B # 0 +0x98DA 0xB59C # 0 +0x98DB 0xB59D # 0 +0x98DC 0xB59E # 0 +0x98DD 0xB59F # 0 +0x98E1 0xB5A0 # 0 +0x98E2 0xB5A1 # 0 +0x98E3 0xB5A2 # 0 +0x98E4 0xB5A3 # 0 +0x98E5 0xB5A4 # 0 +0x98E6 0xB5A5 # 0 +0x98E7 0xB5A6 # 0 +0x98E8 0xB5A7 # 0 +0x98E9 0xB5A8 # 0 +0x98EA 0xB5A9 # 0 +0x98EB 0xB5AA # 0 +0x98EC 0xB5AB # 0 +0x98ED 0xB5AC # 0 +0x98EE 0xB5AD # 0 +0x98EF 0xB5AE # 0 +0x98F0 0xB5AF # 0 +0x98F1 0xB5B0 # 0 +0x98F3 0xB5B1 # 0 +0x98F4 0xB5B2 # 0 +0x98F5 0xB5B3 # 0 +0x98F6 0xB5B4 # 0 +0x98F7 0xB5B5 # 0 +0x98F8 0xB5B6 # 0 +0x98F9 0xB5B7 # 0 +0x98FA 0xB5B8 # 0 +0x98FB 0xB5B9 # 0 +0x98FC 0xB5BA # 0 +0x98FD 0xB5BB # 0 +0x9941 0xB5BC # 0 +0x9942 0xB5BD # 0 +0x9943 0xB5BE # 0 +0x9944 0xB5BF # 0 +0x9945 0xB5C0 # 0 +0x9946 0xB5C1 # 0 +0x9947 0xB5C2 # 0 +0x9948 0xB5C3 # 0 +0x9949 0xB5C4 # 0 +0x994A 0xB5C5 # 0 +0x994B 0xB5C6 # 0 +0x994C 0xB5C7 # 0 +0x994D 0xB5C8 # 0 +0x994E 0xB5C9 # 0 +0x994F 0xB5CA # 0 +0x9950 0xB5CB # 0 +0x9951 0xB5CC # 0 +0x9953 0xB5CD # 0 +0x9954 0xB5CE # 0 +0x9955 0xB5CF # 0 +0x9956 0xB5D0 # 0 +0x9957 0xB5D1 # 0 +0x9958 0xB5D2 # 0 +0x9959 0xB5D3 # 0 +0x995A 0xB5D4 # 0 +0x995B 0xB5D5 # 0 +0x995C 0xB5D6 # 0 +0x995D 0xB5D7 # 0 +0x9961 0xB5D8 # 0 +0x9962 0xB5D9 # 0 +0x9963 0xB5DA # 0 +0x9964 0xB5DB # 0 +0x9965 0xB5DC # 0 +0x9966 0xB5DD # 0 +0x9967 0xB5DE # 0 +0x9968 0xB5DF # 0 +0x9969 0xB5E0 # 0 +0x996A 0xB5E1 # 0 +0x996B 0xB5E2 # 0 +0x996C 0xB5E3 # 0 +0x996D 0xB5E4 # 0 +0x996E 0xB5E5 # 0 +0x996F 0xB5E6 # 0 +0x9970 0xB5E7 # 0 +0x9971 0xB5E8 # 0 +0x9973 0xB5E9 # 0 +0x9974 0xB5EA # 0 +0x9975 0xB5EB # 0 +0x9976 0xB5EC # 0 +0x9977 0xB5ED # 0 +0x9978 0xB5EE # 0 +0x9979 0xB5EF # 0 +0x997A 0xB5F0 # 0 +0x997B 0xB5F1 # 0 +0x997C 0xB5F2 # 0 +0x997D 0xB5F3 # 0 +0x9981 0xB5F4 # 0 +0x9982 0xB5F5 # 0 +0x9983 0xB5F6 # 0 +0x9984 0xB5F7 # 0 +0x9985 0xB5F8 # 0 +0x9986 0xB5F9 # 0 +0x9987 0xB5FA # 0 +0x9988 0xB5FB # 0 +0x9989 0xB5FC # 0 +0x998A 0xB5FD # 0 +0x998B 0xB5FE # 0 +0x998C 0xB5FF # 0 +0x998D 0xB600 # 0 +0x998E 0xB601 # 0 +0x998F 0xB602 # 0 +0x9990 0xB603 # 0 +0x9991 0xB604 # 0 +0x9993 0xB605 # 0 +0x9994 0xB606 # 0 +0x9995 0xB607 # 0 +0x9996 0xB608 # 0 +0x9997 0xB609 # 0 +0x9998 0xB60A # 0 +0x9999 0xB60B # 0 +0x999A 0xB60C # 0 +0x999B 0xB60D # 0 +0x999C 0xB60E # 0 +0x999D 0xB60F # 0 +0x99A1 0xB610 # 0 +0x99A2 0xB611 # 0 +0x99A3 0xB612 # 0 +0x99A4 0xB613 # 0 +0x99A5 0xB614 # 0 +0x99A6 0xB615 # 0 +0x99A7 0xB616 # 0 +0x99A8 0xB617 # 0 +0x99A9 0xB618 # 0 +0x99AA 0xB619 # 0 +0x99AB 0xB61A # 0 +0x99AC 0xB61B # 0 +0x99AD 0xB61C # 0 +0x99AE 0xB61D # 0 +0x99AF 0xB61E # 0 +0x99B0 0xB61F # 0 +0x99B1 0xB620 # 0 +0x99B3 0xB621 # 0 +0x99B4 0xB622 # 0 +0x99B5 0xB623 # 0 +0x99B6 0xB624 # 0 +0x99B7 0xB625 # 0 +0x99B8 0xB626 # 0 +0x99B9 0xB627 # 0 +0x99BA 0xB628 # 0 +0x99BB 0xB629 # 0 +0x99BC 0xB62A # 0 +0x99BD 0xB62B # 0 +0x99C1 0xB62C # 0 +0x99C2 0xB62D # 0 +0x99C3 0xB62E # 0 +0x99C4 0xB62F # 0 +0x99C5 0xB630 # 0 +0x99C6 0xB631 # 0 +0x99C7 0xB632 # 0 +0x99C8 0xB633 # 0 +0x99C9 0xB634 # 0 +0x99CA 0xB635 # 0 +0x99CB 0xB636 # 0 +0x99CC 0xB637 # 0 +0x99CD 0xB638 # 0 +0x99CE 0xB639 # 0 +0x99CF 0xB63A # 0 +0x99D0 0xB63B # 0 +0x99D1 0xB63C # 0 +0x99D3 0xB63D # 0 +0x99D4 0xB63E # 0 +0x99D5 0xB63F # 0 +0x99D6 0xB640 # 0 +0x99D7 0xB641 # 0 +0x99D8 0xB642 # 0 +0x99D9 0xB643 # 0 +0x99DA 0xB644 # 0 +0x99DB 0xB645 # 0 +0x99DC 0xB646 # 0 +0x99DD 0xB647 # 0 +0x99E1 0xB648 # 0 +0x99E2 0xB649 # 0 +0x99E3 0xB64A # 0 +0x99E4 0xB64B # 0 +0x99E5 0xB64C # 0 +0x99E6 0xB64D # 0 +0x99E7 0xB64E # 0 +0x99E8 0xB64F # 0 +0x99E9 0xB650 # 0 +0x99EA 0xB651 # 0 +0x99EB 0xB652 # 0 +0x99EC 0xB653 # 0 +0x99ED 0xB654 # 0 +0x99EE 0xB655 # 0 +0x99EF 0xB656 # 0 +0x99F0 0xB657 # 0 +0x99F1 0xB658 # 0 +0x99F3 0xB659 # 0 +0x99F4 0xB65A # 0 +0x99F5 0xB65B # 0 +0x99F6 0xB65C # 0 +0x99F7 0xB65D # 0 +0x99F8 0xB65E # 0 +0x99F9 0xB65F # 0 +0x99FA 0xB660 # 0 +0x99FB 0xB661 # 0 +0x99FC 0xB662 # 0 +0x99FD 0xB663 # 0 +0x9A41 0xB664 # 0 +0x9A42 0xB665 # 0 +0x9A43 0xB666 # 0 +0x9A44 0xB667 # 0 +0x9A45 0xB668 # 0 +0x9A46 0xB669 # 0 +0x9A47 0xB66A # 0 +0x9A48 0xB66B # 0 +0x9A49 0xB66C # 0 +0x9A4A 0xB66D # 0 +0x9A4B 0xB66E # 0 +0x9A4C 0xB66F # 0 +0x9A4D 0xB670 # 0 +0x9A4E 0xB671 # 0 +0x9A4F 0xB672 # 0 +0x9A50 0xB673 # 0 +0x9A51 0xB674 # 0 +0x9A53 0xB675 # 0 +0x9A54 0xB676 # 0 +0x9A55 0xB677 # 0 +0x9A56 0xB678 # 0 +0x9A57 0xB679 # 0 +0x9A58 0xB67A # 0 +0x9A59 0xB67B # 0 +0x9A5A 0xB67C # 0 +0x9A5B 0xB67D # 0 +0x9A5C 0xB67E # 0 +0x9A5D 0xB67F # 0 +0x9A61 0xB680 # 0 +0x9A62 0xB681 # 0 +0x9A63 0xB682 # 0 +0x9A64 0xB683 # 0 +0x9A65 0xB684 # 0 +0x9A66 0xB685 # 0 +0x9A67 0xB686 # 0 +0x9A68 0xB687 # 0 +0x9A69 0xB688 # 0 +0x9A6A 0xB689 # 0 +0x9A6B 0xB68A # 0 +0x9A6C 0xB68B # 0 +0x9A6D 0xB68C # 0 +0x9A6E 0xB68D # 0 +0x9A6F 0xB68E # 0 +0x9A70 0xB68F # 0 +0x9A71 0xB690 # 0 +0x9A73 0xB691 # 0 +0x9A74 0xB692 # 0 +0x9A75 0xB693 # 0 +0x9A76 0xB694 # 0 +0x9A77 0xB695 # 0 +0x9A78 0xB696 # 0 +0x9A79 0xB697 # 0 +0x9A7A 0xB698 # 0 +0x9A7B 0xB699 # 0 +0x9A7C 0xB69A # 0 +0x9A7D 0xB69B # 0 +0x9A81 0xB69C # 0 +0x9A82 0xB69D # 0 +0x9A83 0xB69E # 0 +0x9A84 0xB69F # 0 +0x9A85 0xB6A0 # 0 +0x9A86 0xB6A1 # 0 +0x9A87 0xB6A2 # 0 +0x9A88 0xB6A3 # 0 +0x9A89 0xB6A4 # 0 +0x9A8A 0xB6A5 # 0 +0x9A8B 0xB6A6 # 0 +0x9A8C 0xB6A7 # 0 +0x9A8D 0xB6A8 # 0 +0x9A8E 0xB6A9 # 0 +0x9A8F 0xB6AA # 0 +0x9A90 0xB6AB # 0 +0x9A91 0xB6AC # 0 +0x9A93 0xB6AD # 0 +0x9A94 0xB6AE # 0 +0x9A95 0xB6AF # 0 +0x9A96 0xB6B0 # 0 +0x9A97 0xB6B1 # 0 +0x9A98 0xB6B2 # 0 +0x9A99 0xB6B3 # 0 +0x9A9A 0xB6B4 # 0 +0x9A9B 0xB6B5 # 0 +0x9A9C 0xB6B6 # 0 +0x9A9D 0xB6B7 # 0 +0x9AA1 0xB6B8 # 0 +0x9AA2 0xB6B9 # 0 +0x9AA3 0xB6BA # 0 +0x9AA4 0xB6BB # 0 +0x9AA5 0xB6BC # 0 +0x9AA6 0xB6BD # 0 +0x9AA7 0xB6BE # 0 +0x9AA8 0xB6BF # 0 +0x9AA9 0xB6C0 # 0 +0x9AAA 0xB6C1 # 0 +0x9AAB 0xB6C2 # 0 +0x9AAC 0xB6C3 # 0 +0x9AAD 0xB6C4 # 0 +0x9AAE 0xB6C5 # 0 +0x9AAF 0xB6C6 # 0 +0x9AB0 0xB6C7 # 0 +0x9AB1 0xB6C8 # 0 +0x9AB3 0xB6C9 # 0 +0x9AB4 0xB6CA # 0 +0x9AB5 0xB6CB # 0 +0x9AB6 0xB6CC # 0 +0x9AB7 0xB6CD # 0 +0x9AB8 0xB6CE # 0 +0x9AB9 0xB6CF # 0 +0x9ABA 0xB6D0 # 0 +0x9ABB 0xB6D1 # 0 +0x9ABC 0xB6D2 # 0 +0x9ABD 0xB6D3 # 0 +0x9AC1 0xB6D4 # 0 +0x9AC2 0xB6D5 # 0 +0x9AC3 0xB6D6 # 0 +0x9AC4 0xB6D7 # 0 +0x9AC5 0xB6D8 # 0 +0x9AC6 0xB6D9 # 0 +0x9AC7 0xB6DA # 0 +0x9AC8 0xB6DB # 0 +0x9AC9 0xB6DC # 0 +0x9ACA 0xB6DD # 0 +0x9ACB 0xB6DE # 0 +0x9ACC 0xB6DF # 0 +0x9ACD 0xB6E0 # 0 +0x9ACE 0xB6E1 # 0 +0x9ACF 0xB6E2 # 0 +0x9AD0 0xB6E3 # 0 +0x9AD1 0xB6E4 # 0 +0x9AD3 0xB6E5 # 0 +0x9AD4 0xB6E6 # 0 +0x9AD5 0xB6E7 # 0 +0x9AD6 0xB6E8 # 0 +0x9AD7 0xB6E9 # 0 +0x9AD8 0xB6EA # 0 +0x9AD9 0xB6EB # 0 +0x9ADA 0xB6EC # 0 +0x9ADB 0xB6ED # 0 +0x9ADC 0xB6EE # 0 +0x9ADD 0xB6EF # 0 +0x9AE1 0xB6F0 # 0 +0x9AE2 0xB6F1 # 0 +0x9AE3 0xB6F2 # 0 +0x9AE4 0xB6F3 # 0 +0x9AE5 0xB6F4 # 0 +0x9AE6 0xB6F5 # 0 +0x9AE7 0xB6F6 # 0 +0x9AE8 0xB6F7 # 0 +0x9AE9 0xB6F8 # 0 +0x9AEA 0xB6F9 # 0 +0x9AEB 0xB6FA # 0 +0x9AEC 0xB6FB # 0 +0x9AED 0xB6FC # 0 +0x9AEE 0xB6FD # 0 +0x9AEF 0xB6FE # 0 +0x9AF0 0xB6FF # 0 +0x9AF1 0xB700 # 0 +0x9AF3 0xB701 # 0 +0x9AF4 0xB702 # 0 +0x9AF5 0xB703 # 0 +0x9AF6 0xB704 # 0 +0x9AF7 0xB705 # 0 +0x9AF8 0xB706 # 0 +0x9AF9 0xB707 # 0 +0x9AFA 0xB708 # 0 +0x9AFB 0xB709 # 0 +0x9AFC 0xB70A # 0 +0x9AFD 0xB70B # 0 +0x9B41 0xB70C # 0 +0x9B42 0xB70D # 0 +0x9B43 0xB70E # 0 +0x9B44 0xB70F # 0 +0x9B45 0xB710 # 0 +0x9B46 0xB711 # 0 +0x9B47 0xB712 # 0 +0x9B48 0xB713 # 0 +0x9B49 0xB714 # 0 +0x9B4A 0xB715 # 0 +0x9B4B 0xB716 # 0 +0x9B4C 0xB717 # 0 +0x9B4D 0xB718 # 0 +0x9B4E 0xB719 # 0 +0x9B4F 0xB71A # 0 +0x9B50 0xB71B # 0 +0x9B51 0xB71C # 0 +0x9B53 0xB71D # 0 +0x9B54 0xB71E # 0 +0x9B55 0xB71F # 0 +0x9B56 0xB720 # 0 +0x9B57 0xB721 # 0 +0x9B58 0xB722 # 0 +0x9B59 0xB723 # 0 +0x9B5A 0xB724 # 0 +0x9B5B 0xB725 # 0 +0x9B5C 0xB726 # 0 +0x9B5D 0xB727 # 0 +0x9B61 0xB728 # 0 +0x9B62 0xB729 # 0 +0x9B63 0xB72A # 0 +0x9B64 0xB72B # 0 +0x9B65 0xB72C # 0 +0x9B66 0xB72D # 0 +0x9B67 0xB72E # 0 +0x9B68 0xB72F # 0 +0x9B69 0xB730 # 0 +0x9B6A 0xB731 # 0 +0x9B6B 0xB732 # 0 +0x9B6C 0xB733 # 0 +0x9B6D 0xB734 # 0 +0x9B6E 0xB735 # 0 +0x9B6F 0xB736 # 0 +0x9B70 0xB737 # 0 +0x9B71 0xB738 # 0 +0x9B73 0xB739 # 0 +0x9B74 0xB73A # 0 +0x9B75 0xB73B # 0 +0x9B76 0xB73C # 0 +0x9B77 0xB73D # 0 +0x9B78 0xB73E # 0 +0x9B79 0xB73F # 0 +0x9B7A 0xB740 # 0 +0x9B7B 0xB741 # 0 +0x9B7C 0xB742 # 0 +0x9B7D 0xB743 # 0 +0x9B81 0xB744 # 0 +0x9B82 0xB745 # 0 +0x9B83 0xB746 # 0 +0x9B84 0xB747 # 0 +0x9B85 0xB748 # 0 +0x9B86 0xB749 # 0 +0x9B87 0xB74A # 0 +0x9B88 0xB74B # 0 +0x9B89 0xB74C # 0 +0x9B8A 0xB74D # 0 +0x9B8B 0xB74E # 0 +0x9B8C 0xB74F # 0 +0x9B8D 0xB750 # 0 +0x9B8E 0xB751 # 0 +0x9B8F 0xB752 # 0 +0x9B90 0xB753 # 0 +0x9B91 0xB754 # 0 +0x9B93 0xB755 # 0 +0x9B94 0xB756 # 0 +0x9B95 0xB757 # 0 +0x9B96 0xB758 # 0 +0x9B97 0xB759 # 0 +0x9B98 0xB75A # 0 +0x9B99 0xB75B # 0 +0x9B9A 0xB75C # 0 +0x9B9B 0xB75D # 0 +0x9B9C 0xB75E # 0 +0x9B9D 0xB75F # 0 +0x9BA1 0xB760 # 0 +0x9BA2 0xB761 # 0 +0x9BA3 0xB762 # 0 +0x9BA4 0xB763 # 0 +0x9BA5 0xB764 # 0 +0x9BA6 0xB765 # 0 +0x9BA7 0xB766 # 0 +0x9BA8 0xB767 # 0 +0x9BA9 0xB768 # 0 +0x9BAA 0xB769 # 0 +0x9BAB 0xB76A # 0 +0x9BAC 0xB76B # 0 +0x9BAD 0xB76C # 0 +0x9BAE 0xB76D # 0 +0x9BAF 0xB76E # 0 +0x9BB0 0xB76F # 0 +0x9BB1 0xB770 # 0 +0x9BB3 0xB771 # 0 +0x9BB4 0xB772 # 0 +0x9BB5 0xB773 # 0 +0x9BB6 0xB774 # 0 +0x9BB7 0xB775 # 0 +0x9BB8 0xB776 # 0 +0x9BB9 0xB777 # 0 +0x9BBA 0xB778 # 0 +0x9BBB 0xB779 # 0 +0x9BBC 0xB77A # 0 +0x9BBD 0xB77B # 0 +0x9C41 0x1105 # 0 +0x9C61 0xB77C # 0 +0x9C62 0xB77D # 0 +0x9C63 0xB77E # 0 +0x9C64 0xB77F # 0 +0x9C65 0xB780 # 0 +0x9C66 0xB781 # 0 +0x9C67 0xB782 # 0 +0x9C68 0xB783 # 0 +0x9C69 0xB784 # 0 +0x9C6A 0xB785 # 0 +0x9C6B 0xB786 # 0 +0x9C6C 0xB787 # 0 +0x9C6D 0xB788 # 0 +0x9C6E 0xB789 # 0 +0x9C6F 0xB78A # 0 +0x9C70 0xB78B # 0 +0x9C71 0xB78C # 0 +0x9C73 0xB78D # 0 +0x9C74 0xB78E # 0 +0x9C75 0xB78F # 0 +0x9C76 0xB790 # 0 +0x9C77 0xB791 # 0 +0x9C78 0xB792 # 0 +0x9C79 0xB793 # 0 +0x9C7A 0xB794 # 0 +0x9C7B 0xB795 # 0 +0x9C7C 0xB796 # 0 +0x9C7D 0xB797 # 0 +0x9C81 0xB798 # 0 +0x9C82 0xB799 # 0 +0x9C83 0xB79A # 0 +0x9C84 0xB79B # 0 +0x9C85 0xB79C # 0 +0x9C86 0xB79D # 0 +0x9C87 0xB79E # 0 +0x9C88 0xB79F # 0 +0x9C89 0xB7A0 # 0 +0x9C8A 0xB7A1 # 0 +0x9C8B 0xB7A2 # 0 +0x9C8C 0xB7A3 # 0 +0x9C8D 0xB7A4 # 0 +0x9C8E 0xB7A5 # 0 +0x9C8F 0xB7A6 # 0 +0x9C90 0xB7A7 # 0 +0x9C91 0xB7A8 # 0 +0x9C93 0xB7A9 # 0 +0x9C94 0xB7AA # 0 +0x9C95 0xB7AB # 0 +0x9C96 0xB7AC # 0 +0x9C97 0xB7AD # 0 +0x9C98 0xB7AE # 0 +0x9C99 0xB7AF # 0 +0x9C9A 0xB7B0 # 0 +0x9C9B 0xB7B1 # 0 +0x9C9C 0xB7B2 # 0 +0x9C9D 0xB7B3 # 0 +0x9CA1 0xB7B4 # 0 +0x9CA2 0xB7B5 # 0 +0x9CA3 0xB7B6 # 0 +0x9CA4 0xB7B7 # 0 +0x9CA5 0xB7B8 # 0 +0x9CA6 0xB7B9 # 0 +0x9CA7 0xB7BA # 0 +0x9CA8 0xB7BB # 0 +0x9CA9 0xB7BC # 0 +0x9CAA 0xB7BD # 0 +0x9CAB 0xB7BE # 0 +0x9CAC 0xB7BF # 0 +0x9CAD 0xB7C0 # 0 +0x9CAE 0xB7C1 # 0 +0x9CAF 0xB7C2 # 0 +0x9CB0 0xB7C3 # 0 +0x9CB1 0xB7C4 # 0 +0x9CB3 0xB7C5 # 0 +0x9CB4 0xB7C6 # 0 +0x9CB5 0xB7C7 # 0 +0x9CB6 0xB7C8 # 0 +0x9CB7 0xB7C9 # 0 +0x9CB8 0xB7CA # 0 +0x9CB9 0xB7CB # 0 +0x9CBA 0xB7CC # 0 +0x9CBB 0xB7CD # 0 +0x9CBC 0xB7CE # 0 +0x9CBD 0xB7CF # 0 +0x9CC1 0xB7D0 # 0 +0x9CC2 0xB7D1 # 0 +0x9CC3 0xB7D2 # 0 +0x9CC4 0xB7D3 # 0 +0x9CC5 0xB7D4 # 0 +0x9CC6 0xB7D5 # 0 +0x9CC7 0xB7D6 # 0 +0x9CC8 0xB7D7 # 0 +0x9CC9 0xB7D8 # 0 +0x9CCA 0xB7D9 # 0 +0x9CCB 0xB7DA # 0 +0x9CCC 0xB7DB # 0 +0x9CCD 0xB7DC # 0 +0x9CCE 0xB7DD # 0 +0x9CCF 0xB7DE # 0 +0x9CD0 0xB7DF # 0 +0x9CD1 0xB7E0 # 0 +0x9CD3 0xB7E1 # 0 +0x9CD4 0xB7E2 # 0 +0x9CD5 0xB7E3 # 0 +0x9CD6 0xB7E4 # 0 +0x9CD7 0xB7E5 # 0 +0x9CD8 0xB7E6 # 0 +0x9CD9 0xB7E7 # 0 +0x9CDA 0xB7E8 # 0 +0x9CDB 0xB7E9 # 0 +0x9CDC 0xB7EA # 0 +0x9CDD 0xB7EB # 0 +0x9CE1 0xB7EC # 0 +0x9CE2 0xB7ED # 0 +0x9CE3 0xB7EE # 0 +0x9CE4 0xB7EF # 0 +0x9CE5 0xB7F0 # 0 +0x9CE6 0xB7F1 # 0 +0x9CE7 0xB7F2 # 0 +0x9CE8 0xB7F3 # 0 +0x9CE9 0xB7F4 # 0 +0x9CEA 0xB7F5 # 0 +0x9CEB 0xB7F6 # 0 +0x9CEC 0xB7F7 # 0 +0x9CED 0xB7F8 # 0 +0x9CEE 0xB7F9 # 0 +0x9CEF 0xB7FA # 0 +0x9CF0 0xB7FB # 0 +0x9CF1 0xB7FC # 0 +0x9CF3 0xB7FD # 0 +0x9CF4 0xB7FE # 0 +0x9CF5 0xB7FF # 0 +0x9CF6 0xB800 # 0 +0x9CF7 0xB801 # 0 +0x9CF8 0xB802 # 0 +0x9CF9 0xB803 # 0 +0x9CFA 0xB804 # 0 +0x9CFB 0xB805 # 0 +0x9CFC 0xB806 # 0 +0x9CFD 0xB807 # 0 +0x9D41 0xB808 # 0 +0x9D42 0xB809 # 0 +0x9D43 0xB80A # 0 +0x9D44 0xB80B # 0 +0x9D45 0xB80C # 0 +0x9D46 0xB80D # 0 +0x9D47 0xB80E # 0 +0x9D48 0xB80F # 0 +0x9D49 0xB810 # 0 +0x9D4A 0xB811 # 0 +0x9D4B 0xB812 # 0 +0x9D4C 0xB813 # 0 +0x9D4D 0xB814 # 0 +0x9D4E 0xB815 # 0 +0x9D4F 0xB816 # 0 +0x9D50 0xB817 # 0 +0x9D51 0xB818 # 0 +0x9D53 0xB819 # 0 +0x9D54 0xB81A # 0 +0x9D55 0xB81B # 0 +0x9D56 0xB81C # 0 +0x9D57 0xB81D # 0 +0x9D58 0xB81E # 0 +0x9D59 0xB81F # 0 +0x9D5A 0xB820 # 0 +0x9D5B 0xB821 # 0 +0x9D5C 0xB822 # 0 +0x9D5D 0xB823 # 0 +0x9D61 0xB824 # 0 +0x9D62 0xB825 # 0 +0x9D63 0xB826 # 0 +0x9D64 0xB827 # 0 +0x9D65 0xB828 # 0 +0x9D66 0xB829 # 0 +0x9D67 0xB82A # 0 +0x9D68 0xB82B # 0 +0x9D69 0xB82C # 0 +0x9D6A 0xB82D # 0 +0x9D6B 0xB82E # 0 +0x9D6C 0xB82F # 0 +0x9D6D 0xB830 # 0 +0x9D6E 0xB831 # 0 +0x9D6F 0xB832 # 0 +0x9D70 0xB833 # 0 +0x9D71 0xB834 # 0 +0x9D73 0xB835 # 0 +0x9D74 0xB836 # 0 +0x9D75 0xB837 # 0 +0x9D76 0xB838 # 0 +0x9D77 0xB839 # 0 +0x9D78 0xB83A # 0 +0x9D79 0xB83B # 0 +0x9D7A 0xB83C # 0 +0x9D7B 0xB83D # 0 +0x9D7C 0xB83E # 0 +0x9D7D 0xB83F # 0 +0x9D81 0xB840 # 0 +0x9D82 0xB841 # 0 +0x9D83 0xB842 # 0 +0x9D84 0xB843 # 0 +0x9D85 0xB844 # 0 +0x9D86 0xB845 # 0 +0x9D87 0xB846 # 0 +0x9D88 0xB847 # 0 +0x9D89 0xB848 # 0 +0x9D8A 0xB849 # 0 +0x9D8B 0xB84A # 0 +0x9D8C 0xB84B # 0 +0x9D8D 0xB84C # 0 +0x9D8E 0xB84D # 0 +0x9D8F 0xB84E # 0 +0x9D90 0xB84F # 0 +0x9D91 0xB850 # 0 +0x9D93 0xB851 # 0 +0x9D94 0xB852 # 0 +0x9D95 0xB853 # 0 +0x9D96 0xB854 # 0 +0x9D97 0xB855 # 0 +0x9D98 0xB856 # 0 +0x9D99 0xB857 # 0 +0x9D9A 0xB858 # 0 +0x9D9B 0xB859 # 0 +0x9D9C 0xB85A # 0 +0x9D9D 0xB85B # 0 +0x9DA1 0xB85C # 0 +0x9DA2 0xB85D # 0 +0x9DA3 0xB85E # 0 +0x9DA4 0xB85F # 0 +0x9DA5 0xB860 # 0 +0x9DA6 0xB861 # 0 +0x9DA7 0xB862 # 0 +0x9DA8 0xB863 # 0 +0x9DA9 0xB864 # 0 +0x9DAA 0xB865 # 0 +0x9DAB 0xB866 # 0 +0x9DAC 0xB867 # 0 +0x9DAD 0xB868 # 0 +0x9DAE 0xB869 # 0 +0x9DAF 0xB86A # 0 +0x9DB0 0xB86B # 0 +0x9DB1 0xB86C # 0 +0x9DB3 0xB86D # 0 +0x9DB4 0xB86E # 0 +0x9DB5 0xB86F # 0 +0x9DB6 0xB870 # 0 +0x9DB7 0xB871 # 0 +0x9DB8 0xB872 # 0 +0x9DB9 0xB873 # 0 +0x9DBA 0xB874 # 0 +0x9DBB 0xB875 # 0 +0x9DBC 0xB876 # 0 +0x9DBD 0xB877 # 0 +0x9DC1 0xB878 # 0 +0x9DC2 0xB879 # 0 +0x9DC3 0xB87A # 0 +0x9DC4 0xB87B # 0 +0x9DC5 0xB87C # 0 +0x9DC6 0xB87D # 0 +0x9DC7 0xB87E # 0 +0x9DC8 0xB87F # 0 +0x9DC9 0xB880 # 0 +0x9DCA 0xB881 # 0 +0x9DCB 0xB882 # 0 +0x9DCC 0xB883 # 0 +0x9DCD 0xB884 # 0 +0x9DCE 0xB885 # 0 +0x9DCF 0xB886 # 0 +0x9DD0 0xB887 # 0 +0x9DD1 0xB888 # 0 +0x9DD3 0xB889 # 0 +0x9DD4 0xB88A # 0 +0x9DD5 0xB88B # 0 +0x9DD6 0xB88C # 0 +0x9DD7 0xB88D # 0 +0x9DD8 0xB88E # 0 +0x9DD9 0xB88F # 0 +0x9DDA 0xB890 # 0 +0x9DDB 0xB891 # 0 +0x9DDC 0xB892 # 0 +0x9DDD 0xB893 # 0 +0x9DE1 0xB894 # 0 +0x9DE2 0xB895 # 0 +0x9DE3 0xB896 # 0 +0x9DE4 0xB897 # 0 +0x9DE5 0xB898 # 0 +0x9DE6 0xB899 # 0 +0x9DE7 0xB89A # 0 +0x9DE8 0xB89B # 0 +0x9DE9 0xB89C # 0 +0x9DEA 0xB89D # 0 +0x9DEB 0xB89E # 0 +0x9DEC 0xB89F # 0 +0x9DED 0xB8A0 # 0 +0x9DEE 0xB8A1 # 0 +0x9DEF 0xB8A2 # 0 +0x9DF0 0xB8A3 # 0 +0x9DF1 0xB8A4 # 0 +0x9DF3 0xB8A5 # 0 +0x9DF4 0xB8A6 # 0 +0x9DF5 0xB8A7 # 0 +0x9DF6 0xB8A8 # 0 +0x9DF7 0xB8A9 # 0 +0x9DF8 0xB8AA # 0 +0x9DF9 0xB8AB # 0 +0x9DFA 0xB8AC # 0 +0x9DFB 0xB8AD # 0 +0x9DFC 0xB8AE # 0 +0x9DFD 0xB8AF # 0 +0x9E41 0xB8B0 # 0 +0x9E42 0xB8B1 # 0 +0x9E43 0xB8B2 # 0 +0x9E44 0xB8B3 # 0 +0x9E45 0xB8B4 # 0 +0x9E46 0xB8B5 # 0 +0x9E47 0xB8B6 # 0 +0x9E48 0xB8B7 # 0 +0x9E49 0xB8B8 # 0 +0x9E4A 0xB8B9 # 0 +0x9E4B 0xB8BA # 0 +0x9E4C 0xB8BB # 0 +0x9E4D 0xB8BC # 0 +0x9E4E 0xB8BD # 0 +0x9E4F 0xB8BE # 0 +0x9E50 0xB8BF # 0 +0x9E51 0xB8C0 # 0 +0x9E53 0xB8C1 # 0 +0x9E54 0xB8C2 # 0 +0x9E55 0xB8C3 # 0 +0x9E56 0xB8C4 # 0 +0x9E57 0xB8C5 # 0 +0x9E58 0xB8C6 # 0 +0x9E59 0xB8C7 # 0 +0x9E5A 0xB8C8 # 0 +0x9E5B 0xB8C9 # 0 +0x9E5C 0xB8CA # 0 +0x9E5D 0xB8CB # 0 +0x9E61 0xB8CC # 0 +0x9E62 0xB8CD # 0 +0x9E63 0xB8CE # 0 +0x9E64 0xB8CF # 0 +0x9E65 0xB8D0 # 0 +0x9E66 0xB8D1 # 0 +0x9E67 0xB8D2 # 0 +0x9E68 0xB8D3 # 0 +0x9E69 0xB8D4 # 0 +0x9E6A 0xB8D5 # 0 +0x9E6B 0xB8D6 # 0 +0x9E6C 0xB8D7 # 0 +0x9E6D 0xB8D8 # 0 +0x9E6E 0xB8D9 # 0 +0x9E6F 0xB8DA # 0 +0x9E70 0xB8DB # 0 +0x9E71 0xB8DC # 0 +0x9E73 0xB8DD # 0 +0x9E74 0xB8DE # 0 +0x9E75 0xB8DF # 0 +0x9E76 0xB8E0 # 0 +0x9E77 0xB8E1 # 0 +0x9E78 0xB8E2 # 0 +0x9E79 0xB8E3 # 0 +0x9E7A 0xB8E4 # 0 +0x9E7B 0xB8E5 # 0 +0x9E7C 0xB8E6 # 0 +0x9E7D 0xB8E7 # 0 +0x9E81 0xB8E8 # 0 +0x9E82 0xB8E9 # 0 +0x9E83 0xB8EA # 0 +0x9E84 0xB8EB # 0 +0x9E85 0xB8EC # 0 +0x9E86 0xB8ED # 0 +0x9E87 0xB8EE # 0 +0x9E88 0xB8EF # 0 +0x9E89 0xB8F0 # 0 +0x9E8A 0xB8F1 # 0 +0x9E8B 0xB8F2 # 0 +0x9E8C 0xB8F3 # 0 +0x9E8D 0xB8F4 # 0 +0x9E8E 0xB8F5 # 0 +0x9E8F 0xB8F6 # 0 +0x9E90 0xB8F7 # 0 +0x9E91 0xB8F8 # 0 +0x9E93 0xB8F9 # 0 +0x9E94 0xB8FA # 0 +0x9E95 0xB8FB # 0 +0x9E96 0xB8FC # 0 +0x9E97 0xB8FD # 0 +0x9E98 0xB8FE # 0 +0x9E99 0xB8FF # 0 +0x9E9A 0xB900 # 0 +0x9E9B 0xB901 # 0 +0x9E9C 0xB902 # 0 +0x9E9D 0xB903 # 0 +0x9EA1 0xB904 # 0 +0x9EA2 0xB905 # 0 +0x9EA3 0xB906 # 0 +0x9EA4 0xB907 # 0 +0x9EA5 0xB908 # 0 +0x9EA6 0xB909 # 0 +0x9EA7 0xB90A # 0 +0x9EA8 0xB90B # 0 +0x9EA9 0xB90C # 0 +0x9EAA 0xB90D # 0 +0x9EAB 0xB90E # 0 +0x9EAC 0xB90F # 0 +0x9EAD 0xB910 # 0 +0x9EAE 0xB911 # 0 +0x9EAF 0xB912 # 0 +0x9EB0 0xB913 # 0 +0x9EB1 0xB914 # 0 +0x9EB3 0xB915 # 0 +0x9EB4 0xB916 # 0 +0x9EB5 0xB917 # 0 +0x9EB6 0xB918 # 0 +0x9EB7 0xB919 # 0 +0x9EB8 0xB91A # 0 +0x9EB9 0xB91B # 0 +0x9EBA 0xB91C # 0 +0x9EBB 0xB91D # 0 +0x9EBC 0xB91E # 0 +0x9EBD 0xB91F # 0 +0x9EC1 0xB920 # 0 +0x9EC2 0xB921 # 0 +0x9EC3 0xB922 # 0 +0x9EC4 0xB923 # 0 +0x9EC5 0xB924 # 0 +0x9EC6 0xB925 # 0 +0x9EC7 0xB926 # 0 +0x9EC8 0xB927 # 0 +0x9EC9 0xB928 # 0 +0x9ECA 0xB929 # 0 +0x9ECB 0xB92A # 0 +0x9ECC 0xB92B # 0 +0x9ECD 0xB92C # 0 +0x9ECE 0xB92D # 0 +0x9ECF 0xB92E # 0 +0x9ED0 0xB92F # 0 +0x9ED1 0xB930 # 0 +0x9ED3 0xB931 # 0 +0x9ED4 0xB932 # 0 +0x9ED5 0xB933 # 0 +0x9ED6 0xB934 # 0 +0x9ED7 0xB935 # 0 +0x9ED8 0xB936 # 0 +0x9ED9 0xB937 # 0 +0x9EDA 0xB938 # 0 +0x9EDB 0xB939 # 0 +0x9EDC 0xB93A # 0 +0x9EDD 0xB93B # 0 +0x9EE1 0xB93C # 0 +0x9EE2 0xB93D # 0 +0x9EE3 0xB93E # 0 +0x9EE4 0xB93F # 0 +0x9EE5 0xB940 # 0 +0x9EE6 0xB941 # 0 +0x9EE7 0xB942 # 0 +0x9EE8 0xB943 # 0 +0x9EE9 0xB944 # 0 +0x9EEA 0xB945 # 0 +0x9EEB 0xB946 # 0 +0x9EEC 0xB947 # 0 +0x9EED 0xB948 # 0 +0x9EEE 0xB949 # 0 +0x9EEF 0xB94A # 0 +0x9EF0 0xB94B # 0 +0x9EF1 0xB94C # 0 +0x9EF3 0xB94D # 0 +0x9EF4 0xB94E # 0 +0x9EF5 0xB94F # 0 +0x9EF6 0xB950 # 0 +0x9EF7 0xB951 # 0 +0x9EF8 0xB952 # 0 +0x9EF9 0xB953 # 0 +0x9EFA 0xB954 # 0 +0x9EFB 0xB955 # 0 +0x9EFC 0xB956 # 0 +0x9EFD 0xB957 # 0 +0x9F41 0xB958 # 0 +0x9F42 0xB959 # 0 +0x9F43 0xB95A # 0 +0x9F44 0xB95B # 0 +0x9F45 0xB95C # 0 +0x9F46 0xB95D # 0 +0x9F47 0xB95E # 0 +0x9F48 0xB95F # 0 +0x9F49 0xB960 # 0 +0x9F4A 0xB961 # 0 +0x9F4B 0xB962 # 0 +0x9F4C 0xB963 # 0 +0x9F4D 0xB964 # 0 +0x9F4E 0xB965 # 0 +0x9F4F 0xB966 # 0 +0x9F50 0xB967 # 0 +0x9F51 0xB968 # 0 +0x9F53 0xB969 # 0 +0x9F54 0xB96A # 0 +0x9F55 0xB96B # 0 +0x9F56 0xB96C # 0 +0x9F57 0xB96D # 0 +0x9F58 0xB96E # 0 +0x9F59 0xB96F # 0 +0x9F5A 0xB970 # 0 +0x9F5B 0xB971 # 0 +0x9F5C 0xB972 # 0 +0x9F5D 0xB973 # 0 +0x9F61 0xB974 # 0 +0x9F62 0xB975 # 0 +0x9F63 0xB976 # 0 +0x9F64 0xB977 # 0 +0x9F65 0xB978 # 0 +0x9F66 0xB979 # 0 +0x9F67 0xB97A # 0 +0x9F68 0xB97B # 0 +0x9F69 0xB97C # 0 +0x9F6A 0xB97D # 0 +0x9F6B 0xB97E # 0 +0x9F6C 0xB97F # 0 +0x9F6D 0xB980 # 0 +0x9F6E 0xB981 # 0 +0x9F6F 0xB982 # 0 +0x9F70 0xB983 # 0 +0x9F71 0xB984 # 0 +0x9F73 0xB985 # 0 +0x9F74 0xB986 # 0 +0x9F75 0xB987 # 0 +0x9F76 0xB988 # 0 +0x9F77 0xB989 # 0 +0x9F78 0xB98A # 0 +0x9F79 0xB98B # 0 +0x9F7A 0xB98C # 0 +0x9F7B 0xB98D # 0 +0x9F7C 0xB98E # 0 +0x9F7D 0xB98F # 0 +0x9F81 0xB990 # 0 +0x9F82 0xB991 # 0 +0x9F83 0xB992 # 0 +0x9F84 0xB993 # 0 +0x9F85 0xB994 # 0 +0x9F86 0xB995 # 0 +0x9F87 0xB996 # 0 +0x9F88 0xB997 # 0 +0x9F89 0xB998 # 0 +0x9F8A 0xB999 # 0 +0x9F8B 0xB99A # 0 +0x9F8C 0xB99B # 0 +0x9F8D 0xB99C # 0 +0x9F8E 0xB99D # 0 +0x9F8F 0xB99E # 0 +0x9F90 0xB99F # 0 +0x9F91 0xB9A0 # 0 +0x9F93 0xB9A1 # 0 +0x9F94 0xB9A2 # 0 +0x9F95 0xB9A3 # 0 +0x9F96 0xB9A4 # 0 +0x9F97 0xB9A5 # 0 +0x9F98 0xB9A6 # 0 +0x9F99 0xB9A7 # 0 +0x9F9A 0xB9A8 # 0 +0x9F9B 0xB9A9 # 0 +0x9F9C 0xB9AA # 0 +0x9F9D 0xB9AB # 0 +0x9FA1 0xB9AC # 0 +0x9FA2 0xB9AD # 0 +0x9FA3 0xB9AE # 0 +0x9FA4 0xB9AF # 0 +0x9FA5 0xB9B0 # 0 +0x9FA6 0xB9B1 # 0 +0x9FA7 0xB9B2 # 0 +0x9FA8 0xB9B3 # 0 +0x9FA9 0xB9B4 # 0 +0x9FAA 0xB9B5 # 0 +0x9FAB 0xB9B6 # 0 +0x9FAC 0xB9B7 # 0 +0x9FAD 0xB9B8 # 0 +0x9FAE 0xB9B9 # 0 +0x9FAF 0xB9BA # 0 +0x9FB0 0xB9BB # 0 +0x9FB1 0xB9BC # 0 +0x9FB3 0xB9BD # 0 +0x9FB4 0xB9BE # 0 +0x9FB5 0xB9BF # 0 +0x9FB6 0xB9C0 # 0 +0x9FB7 0xB9C1 # 0 +0x9FB8 0xB9C2 # 0 +0x9FB9 0xB9C3 # 0 +0x9FBA 0xB9C4 # 0 +0x9FBB 0xB9C5 # 0 +0x9FBC 0xB9C6 # 0 +0x9FBD 0xB9C7 # 0 +0xA041 0x1106 # 0 +0xA061 0xB9C8 # 0 +0xA062 0xB9C9 # 0 +0xA063 0xB9CA # 0 +0xA064 0xB9CB # 0 +0xA065 0xB9CC # 0 +0xA066 0xB9CD # 0 +0xA067 0xB9CE # 0 +0xA068 0xB9CF # 0 +0xA069 0xB9D0 # 0 +0xA06A 0xB9D1 # 0 +0xA06B 0xB9D2 # 0 +0xA06C 0xB9D3 # 0 +0xA06D 0xB9D4 # 0 +0xA06E 0xB9D5 # 0 +0xA06F 0xB9D6 # 0 +0xA070 0xB9D7 # 0 +0xA071 0xB9D8 # 0 +0xA073 0xB9D9 # 0 +0xA074 0xB9DA # 0 +0xA075 0xB9DB # 0 +0xA076 0xB9DC # 0 +0xA077 0xB9DD # 0 +0xA078 0xB9DE # 0 +0xA079 0xB9DF # 0 +0xA07A 0xB9E0 # 0 +0xA07B 0xB9E1 # 0 +0xA07C 0xB9E2 # 0 +0xA07D 0xB9E3 # 0 +0xA081 0xB9E4 # 0 +0xA082 0xB9E5 # 0 +0xA083 0xB9E6 # 0 +0xA084 0xB9E7 # 0 +0xA085 0xB9E8 # 0 +0xA086 0xB9E9 # 0 +0xA087 0xB9EA # 0 +0xA088 0xB9EB # 0 +0xA089 0xB9EC # 0 +0xA08A 0xB9ED # 0 +0xA08B 0xB9EE # 0 +0xA08C 0xB9EF # 0 +0xA08D 0xB9F0 # 0 +0xA08E 0xB9F1 # 0 +0xA08F 0xB9F2 # 0 +0xA090 0xB9F3 # 0 +0xA091 0xB9F4 # 0 +0xA093 0xB9F5 # 0 +0xA094 0xB9F6 # 0 +0xA095 0xB9F7 # 0 +0xA096 0xB9F8 # 0 +0xA097 0xB9F9 # 0 +0xA098 0xB9FA # 0 +0xA099 0xB9FB # 0 +0xA09A 0xB9FC # 0 +0xA09B 0xB9FD # 0 +0xA09C 0xB9FE # 0 +0xA09D 0xB9FF # 0 +0xA0A1 0xBA00 # 0 +0xA0A2 0xBA01 # 0 +0xA0A3 0xBA02 # 0 +0xA0A4 0xBA03 # 0 +0xA0A5 0xBA04 # 0 +0xA0A6 0xBA05 # 0 +0xA0A7 0xBA06 # 0 +0xA0A8 0xBA07 # 0 +0xA0A9 0xBA08 # 0 +0xA0AA 0xBA09 # 0 +0xA0AB 0xBA0A # 0 +0xA0AC 0xBA0B # 0 +0xA0AD 0xBA0C # 0 +0xA0AE 0xBA0D # 0 +0xA0AF 0xBA0E # 0 +0xA0B0 0xBA0F # 0 +0xA0B1 0xBA10 # 0 +0xA0B3 0xBA11 # 0 +0xA0B4 0xBA12 # 0 +0xA0B5 0xBA13 # 0 +0xA0B6 0xBA14 # 0 +0xA0B7 0xBA15 # 0 +0xA0B8 0xBA16 # 0 +0xA0B9 0xBA17 # 0 +0xA0BA 0xBA18 # 0 +0xA0BB 0xBA19 # 0 +0xA0BC 0xBA1A # 0 +0xA0BD 0xBA1B # 0 +0xA0C1 0xBA1C # 0 +0xA0C2 0xBA1D # 0 +0xA0C3 0xBA1E # 0 +0xA0C4 0xBA1F # 0 +0xA0C5 0xBA20 # 0 +0xA0C6 0xBA21 # 0 +0xA0C7 0xBA22 # 0 +0xA0C8 0xBA23 # 0 +0xA0C9 0xBA24 # 0 +0xA0CA 0xBA25 # 0 +0xA0CB 0xBA26 # 0 +0xA0CC 0xBA27 # 0 +0xA0CD 0xBA28 # 0 +0xA0CE 0xBA29 # 0 +0xA0CF 0xBA2A # 0 +0xA0D0 0xBA2B # 0 +0xA0D1 0xBA2C # 0 +0xA0D3 0xBA2D # 0 +0xA0D4 0xBA2E # 0 +0xA0D5 0xBA2F # 0 +0xA0D6 0xBA30 # 0 +0xA0D7 0xBA31 # 0 +0xA0D8 0xBA32 # 0 +0xA0D9 0xBA33 # 0 +0xA0DA 0xBA34 # 0 +0xA0DB 0xBA35 # 0 +0xA0DC 0xBA36 # 0 +0xA0DD 0xBA37 # 0 +0xA0E1 0xBA38 # 0 +0xA0E2 0xBA39 # 0 +0xA0E3 0xBA3A # 0 +0xA0E4 0xBA3B # 0 +0xA0E5 0xBA3C # 0 +0xA0E6 0xBA3D # 0 +0xA0E7 0xBA3E # 0 +0xA0E8 0xBA3F # 0 +0xA0E9 0xBA40 # 0 +0xA0EA 0xBA41 # 0 +0xA0EB 0xBA42 # 0 +0xA0EC 0xBA43 # 0 +0xA0ED 0xBA44 # 0 +0xA0EE 0xBA45 # 0 +0xA0EF 0xBA46 # 0 +0xA0F0 0xBA47 # 0 +0xA0F1 0xBA48 # 0 +0xA0F3 0xBA49 # 0 +0xA0F4 0xBA4A # 0 +0xA0F5 0xBA4B # 0 +0xA0F6 0xBA4C # 0 +0xA0F7 0xBA4D # 0 +0xA0F8 0xBA4E # 0 +0xA0F9 0xBA4F # 0 +0xA0FA 0xBA50 # 0 +0xA0FB 0xBA51 # 0 +0xA0FC 0xBA52 # 0 +0xA0FD 0xBA53 # 0 +0xA141 0xBA54 # 0 +0xA142 0xBA55 # 0 +0xA143 0xBA56 # 0 +0xA144 0xBA57 # 0 +0xA145 0xBA58 # 0 +0xA146 0xBA59 # 0 +0xA147 0xBA5A # 0 +0xA148 0xBA5B # 0 +0xA149 0xBA5C # 0 +0xA14A 0xBA5D # 0 +0xA14B 0xBA5E # 0 +0xA14C 0xBA5F # 0 +0xA14D 0xBA60 # 0 +0xA14E 0xBA61 # 0 +0xA14F 0xBA62 # 0 +0xA150 0xBA63 # 0 +0xA151 0xBA64 # 0 +0xA153 0xBA65 # 0 +0xA154 0xBA66 # 0 +0xA155 0xBA67 # 0 +0xA156 0xBA68 # 0 +0xA157 0xBA69 # 0 +0xA158 0xBA6A # 0 +0xA159 0xBA6B # 0 +0xA15A 0xBA6C # 0 +0xA15B 0xBA6D # 0 +0xA15C 0xBA6E # 0 +0xA15D 0xBA6F # 0 +0xA161 0xBA70 # 0 +0xA162 0xBA71 # 0 +0xA163 0xBA72 # 0 +0xA164 0xBA73 # 0 +0xA165 0xBA74 # 0 +0xA166 0xBA75 # 0 +0xA167 0xBA76 # 0 +0xA168 0xBA77 # 0 +0xA169 0xBA78 # 0 +0xA16A 0xBA79 # 0 +0xA16B 0xBA7A # 0 +0xA16C 0xBA7B # 0 +0xA16D 0xBA7C # 0 +0xA16E 0xBA7D # 0 +0xA16F 0xBA7E # 0 +0xA170 0xBA7F # 0 +0xA171 0xBA80 # 0 +0xA173 0xBA81 # 0 +0xA174 0xBA82 # 0 +0xA175 0xBA83 # 0 +0xA176 0xBA84 # 0 +0xA177 0xBA85 # 0 +0xA178 0xBA86 # 0 +0xA179 0xBA87 # 0 +0xA17A 0xBA88 # 0 +0xA17B 0xBA89 # 0 +0xA17C 0xBA8A # 0 +0xA17D 0xBA8B # 0 +0xA181 0xBA8C # 0 +0xA182 0xBA8D # 0 +0xA183 0xBA8E # 0 +0xA184 0xBA8F # 0 +0xA185 0xBA90 # 0 +0xA186 0xBA91 # 0 +0xA187 0xBA92 # 0 +0xA188 0xBA93 # 0 +0xA189 0xBA94 # 0 +0xA18A 0xBA95 # 0 +0xA18B 0xBA96 # 0 +0xA18C 0xBA97 # 0 +0xA18D 0xBA98 # 0 +0xA18E 0xBA99 # 0 +0xA18F 0xBA9A # 0 +0xA190 0xBA9B # 0 +0xA191 0xBA9C # 0 +0xA193 0xBA9D # 0 +0xA194 0xBA9E # 0 +0xA195 0xBA9F # 0 +0xA196 0xBAA0 # 0 +0xA197 0xBAA1 # 0 +0xA198 0xBAA2 # 0 +0xA199 0xBAA3 # 0 +0xA19A 0xBAA4 # 0 +0xA19B 0xBAA5 # 0 +0xA19C 0xBAA6 # 0 +0xA19D 0xBAA7 # 0 +0xA1A1 0xBAA8 # 0 +0xA1A2 0xBAA9 # 0 +0xA1A3 0xBAAA # 0 +0xA1A4 0xBAAB # 0 +0xA1A5 0xBAAC # 0 +0xA1A6 0xBAAD # 0 +0xA1A7 0xBAAE # 0 +0xA1A8 0xBAAF # 0 +0xA1A9 0xBAB0 # 0 +0xA1AA 0xBAB1 # 0 +0xA1AB 0xBAB2 # 0 +0xA1AC 0xBAB3 # 0 +0xA1AD 0xBAB4 # 0 +0xA1AE 0xBAB5 # 0 +0xA1AF 0xBAB6 # 0 +0xA1B0 0xBAB7 # 0 +0xA1B1 0xBAB8 # 0 +0xA1B3 0xBAB9 # 0 +0xA1B4 0xBABA # 0 +0xA1B5 0xBABB # 0 +0xA1B6 0xBABC # 0 +0xA1B7 0xBABD # 0 +0xA1B8 0xBABE # 0 +0xA1B9 0xBABF # 0 +0xA1BA 0xBAC0 # 0 +0xA1BB 0xBAC1 # 0 +0xA1BC 0xBAC2 # 0 +0xA1BD 0xBAC3 # 0 +0xA1C1 0xBAC4 # 0 +0xA1C2 0xBAC5 # 0 +0xA1C3 0xBAC6 # 0 +0xA1C4 0xBAC7 # 0 +0xA1C5 0xBAC8 # 0 +0xA1C6 0xBAC9 # 0 +0xA1C7 0xBACA # 0 +0xA1C8 0xBACB # 0 +0xA1C9 0xBACC # 0 +0xA1CA 0xBACD # 0 +0xA1CB 0xBACE # 0 +0xA1CC 0xBACF # 0 +0xA1CD 0xBAD0 # 0 +0xA1CE 0xBAD1 # 0 +0xA1CF 0xBAD2 # 0 +0xA1D0 0xBAD3 # 0 +0xA1D1 0xBAD4 # 0 +0xA1D3 0xBAD5 # 0 +0xA1D4 0xBAD6 # 0 +0xA1D5 0xBAD7 # 0 +0xA1D6 0xBAD8 # 0 +0xA1D7 0xBAD9 # 0 +0xA1D8 0xBADA # 0 +0xA1D9 0xBADB # 0 +0xA1DA 0xBADC # 0 +0xA1DB 0xBADD # 0 +0xA1DC 0xBADE # 0 +0xA1DD 0xBADF # 0 +0xA1E1 0xBAE0 # 0 +0xA1E2 0xBAE1 # 0 +0xA1E3 0xBAE2 # 0 +0xA1E4 0xBAE3 # 0 +0xA1E5 0xBAE4 # 0 +0xA1E6 0xBAE5 # 0 +0xA1E7 0xBAE6 # 0 +0xA1E8 0xBAE7 # 0 +0xA1E9 0xBAE8 # 0 +0xA1EA 0xBAE9 # 0 +0xA1EB 0xBAEA # 0 +0xA1EC 0xBAEB # 0 +0xA1ED 0xBAEC # 0 +0xA1EE 0xBAED # 0 +0xA1EF 0xBAEE # 0 +0xA1F0 0xBAEF # 0 +0xA1F1 0xBAF0 # 0 +0xA1F3 0xBAF1 # 0 +0xA1F4 0xBAF2 # 0 +0xA1F5 0xBAF3 # 0 +0xA1F6 0xBAF4 # 0 +0xA1F7 0xBAF5 # 0 +0xA1F8 0xBAF6 # 0 +0xA1F9 0xBAF7 # 0 +0xA1FA 0xBAF8 # 0 +0xA1FB 0xBAF9 # 0 +0xA1FC 0xBAFA # 0 +0xA1FD 0xBAFB # 0 +0xA241 0xBAFC # 0 +0xA242 0xBAFD # 0 +0xA243 0xBAFE # 0 +0xA244 0xBAFF # 0 +0xA245 0xBB00 # 0 +0xA246 0xBB01 # 0 +0xA247 0xBB02 # 0 +0xA248 0xBB03 # 0 +0xA249 0xBB04 # 0 +0xA24A 0xBB05 # 0 +0xA24B 0xBB06 # 0 +0xA24C 0xBB07 # 0 +0xA24D 0xBB08 # 0 +0xA24E 0xBB09 # 0 +0xA24F 0xBB0A # 0 +0xA250 0xBB0B # 0 +0xA251 0xBB0C # 0 +0xA253 0xBB0D # 0 +0xA254 0xBB0E # 0 +0xA255 0xBB0F # 0 +0xA256 0xBB10 # 0 +0xA257 0xBB11 # 0 +0xA258 0xBB12 # 0 +0xA259 0xBB13 # 0 +0xA25A 0xBB14 # 0 +0xA25B 0xBB15 # 0 +0xA25C 0xBB16 # 0 +0xA25D 0xBB17 # 0 +0xA261 0xBB18 # 0 +0xA262 0xBB19 # 0 +0xA263 0xBB1A # 0 +0xA264 0xBB1B # 0 +0xA265 0xBB1C # 0 +0xA266 0xBB1D # 0 +0xA267 0xBB1E # 0 +0xA268 0xBB1F # 0 +0xA269 0xBB20 # 0 +0xA26A 0xBB21 # 0 +0xA26B 0xBB22 # 0 +0xA26C 0xBB23 # 0 +0xA26D 0xBB24 # 0 +0xA26E 0xBB25 # 0 +0xA26F 0xBB26 # 0 +0xA270 0xBB27 # 0 +0xA271 0xBB28 # 0 +0xA273 0xBB29 # 0 +0xA274 0xBB2A # 0 +0xA275 0xBB2B # 0 +0xA276 0xBB2C # 0 +0xA277 0xBB2D # 0 +0xA278 0xBB2E # 0 +0xA279 0xBB2F # 0 +0xA27A 0xBB30 # 0 +0xA27B 0xBB31 # 0 +0xA27C 0xBB32 # 0 +0xA27D 0xBB33 # 0 +0xA281 0xBB34 # 0 +0xA282 0xBB35 # 0 +0xA283 0xBB36 # 0 +0xA284 0xBB37 # 0 +0xA285 0xBB38 # 0 +0xA286 0xBB39 # 0 +0xA287 0xBB3A # 0 +0xA288 0xBB3B # 0 +0xA289 0xBB3C # 0 +0xA28A 0xBB3D # 0 +0xA28B 0xBB3E # 0 +0xA28C 0xBB3F # 0 +0xA28D 0xBB40 # 0 +0xA28E 0xBB41 # 0 +0xA28F 0xBB42 # 0 +0xA290 0xBB43 # 0 +0xA291 0xBB44 # 0 +0xA293 0xBB45 # 0 +0xA294 0xBB46 # 0 +0xA295 0xBB47 # 0 +0xA296 0xBB48 # 0 +0xA297 0xBB49 # 0 +0xA298 0xBB4A # 0 +0xA299 0xBB4B # 0 +0xA29A 0xBB4C # 0 +0xA29B 0xBB4D # 0 +0xA29C 0xBB4E # 0 +0xA29D 0xBB4F # 0 +0xA2A1 0xBB50 # 0 +0xA2A2 0xBB51 # 0 +0xA2A3 0xBB52 # 0 +0xA2A4 0xBB53 # 0 +0xA2A5 0xBB54 # 0 +0xA2A6 0xBB55 # 0 +0xA2A7 0xBB56 # 0 +0xA2A8 0xBB57 # 0 +0xA2A9 0xBB58 # 0 +0xA2AA 0xBB59 # 0 +0xA2AB 0xBB5A # 0 +0xA2AC 0xBB5B # 0 +0xA2AD 0xBB5C # 0 +0xA2AE 0xBB5D # 0 +0xA2AF 0xBB5E # 0 +0xA2B0 0xBB5F # 0 +0xA2B1 0xBB60 # 0 +0xA2B3 0xBB61 # 0 +0xA2B4 0xBB62 # 0 +0xA2B5 0xBB63 # 0 +0xA2B6 0xBB64 # 0 +0xA2B7 0xBB65 # 0 +0xA2B8 0xBB66 # 0 +0xA2B9 0xBB67 # 0 +0xA2BA 0xBB68 # 0 +0xA2BB 0xBB69 # 0 +0xA2BC 0xBB6A # 0 +0xA2BD 0xBB6B # 0 +0xA2C1 0xBB6C # 0 +0xA2C2 0xBB6D # 0 +0xA2C3 0xBB6E # 0 +0xA2C4 0xBB6F # 0 +0xA2C5 0xBB70 # 0 +0xA2C6 0xBB71 # 0 +0xA2C7 0xBB72 # 0 +0xA2C8 0xBB73 # 0 +0xA2C9 0xBB74 # 0 +0xA2CA 0xBB75 # 0 +0xA2CB 0xBB76 # 0 +0xA2CC 0xBB77 # 0 +0xA2CD 0xBB78 # 0 +0xA2CE 0xBB79 # 0 +0xA2CF 0xBB7A # 0 +0xA2D0 0xBB7B # 0 +0xA2D1 0xBB7C # 0 +0xA2D3 0xBB7D # 0 +0xA2D4 0xBB7E # 0 +0xA2D5 0xBB7F # 0 +0xA2D6 0xBB80 # 0 +0xA2D7 0xBB81 # 0 +0xA2D8 0xBB82 # 0 +0xA2D9 0xBB83 # 0 +0xA2DA 0xBB84 # 0 +0xA2DB 0xBB85 # 0 +0xA2DC 0xBB86 # 0 +0xA2DD 0xBB87 # 0 +0xA2E1 0xBB88 # 0 +0xA2E2 0xBB89 # 0 +0xA2E3 0xBB8A # 0 +0xA2E4 0xBB8B # 0 +0xA2E5 0xBB8C # 0 +0xA2E6 0xBB8D # 0 +0xA2E7 0xBB8E # 0 +0xA2E8 0xBB8F # 0 +0xA2E9 0xBB90 # 0 +0xA2EA 0xBB91 # 0 +0xA2EB 0xBB92 # 0 +0xA2EC 0xBB93 # 0 +0xA2ED 0xBB94 # 0 +0xA2EE 0xBB95 # 0 +0xA2EF 0xBB96 # 0 +0xA2F0 0xBB97 # 0 +0xA2F1 0xBB98 # 0 +0xA2F3 0xBB99 # 0 +0xA2F4 0xBB9A # 0 +0xA2F5 0xBB9B # 0 +0xA2F6 0xBB9C # 0 +0xA2F7 0xBB9D # 0 +0xA2F8 0xBB9E # 0 +0xA2F9 0xBB9F # 0 +0xA2FA 0xBBA0 # 0 +0xA2FB 0xBBA1 # 0 +0xA2FC 0xBBA2 # 0 +0xA2FD 0xBBA3 # 0 +0xA341 0xBBA4 # 0 +0xA342 0xBBA5 # 0 +0xA343 0xBBA6 # 0 +0xA344 0xBBA7 # 0 +0xA345 0xBBA8 # 0 +0xA346 0xBBA9 # 0 +0xA347 0xBBAA # 0 +0xA348 0xBBAB # 0 +0xA349 0xBBAC # 0 +0xA34A 0xBBAD # 0 +0xA34B 0xBBAE # 0 +0xA34C 0xBBAF # 0 +0xA34D 0xBBB0 # 0 +0xA34E 0xBBB1 # 0 +0xA34F 0xBBB2 # 0 +0xA350 0xBBB3 # 0 +0xA351 0xBBB4 # 0 +0xA353 0xBBB5 # 0 +0xA354 0xBBB6 # 0 +0xA355 0xBBB7 # 0 +0xA356 0xBBB8 # 0 +0xA357 0xBBB9 # 0 +0xA358 0xBBBA # 0 +0xA359 0xBBBB # 0 +0xA35A 0xBBBC # 0 +0xA35B 0xBBBD # 0 +0xA35C 0xBBBE # 0 +0xA35D 0xBBBF # 0 +0xA361 0xBBC0 # 0 +0xA362 0xBBC1 # 0 +0xA363 0xBBC2 # 0 +0xA364 0xBBC3 # 0 +0xA365 0xBBC4 # 0 +0xA366 0xBBC5 # 0 +0xA367 0xBBC6 # 0 +0xA368 0xBBC7 # 0 +0xA369 0xBBC8 # 0 +0xA36A 0xBBC9 # 0 +0xA36B 0xBBCA # 0 +0xA36C 0xBBCB # 0 +0xA36D 0xBBCC # 0 +0xA36E 0xBBCD # 0 +0xA36F 0xBBCE # 0 +0xA370 0xBBCF # 0 +0xA371 0xBBD0 # 0 +0xA373 0xBBD1 # 0 +0xA374 0xBBD2 # 0 +0xA375 0xBBD3 # 0 +0xA376 0xBBD4 # 0 +0xA377 0xBBD5 # 0 +0xA378 0xBBD6 # 0 +0xA379 0xBBD7 # 0 +0xA37A 0xBBD8 # 0 +0xA37B 0xBBD9 # 0 +0xA37C 0xBBDA # 0 +0xA37D 0xBBDB # 0 +0xA381 0xBBDC # 0 +0xA382 0xBBDD # 0 +0xA383 0xBBDE # 0 +0xA384 0xBBDF # 0 +0xA385 0xBBE0 # 0 +0xA386 0xBBE1 # 0 +0xA387 0xBBE2 # 0 +0xA388 0xBBE3 # 0 +0xA389 0xBBE4 # 0 +0xA38A 0xBBE5 # 0 +0xA38B 0xBBE6 # 0 +0xA38C 0xBBE7 # 0 +0xA38D 0xBBE8 # 0 +0xA38E 0xBBE9 # 0 +0xA38F 0xBBEA # 0 +0xA390 0xBBEB # 0 +0xA391 0xBBEC # 0 +0xA393 0xBBED # 0 +0xA394 0xBBEE # 0 +0xA395 0xBBEF # 0 +0xA396 0xBBF0 # 0 +0xA397 0xBBF1 # 0 +0xA398 0xBBF2 # 0 +0xA399 0xBBF3 # 0 +0xA39A 0xBBF4 # 0 +0xA39B 0xBBF5 # 0 +0xA39C 0xBBF6 # 0 +0xA39D 0xBBF7 # 0 +0xA3A1 0xBBF8 # 0 +0xA3A2 0xBBF9 # 0 +0xA3A3 0xBBFA # 0 +0xA3A4 0xBBFB # 0 +0xA3A5 0xBBFC # 0 +0xA3A6 0xBBFD # 0 +0xA3A7 0xBBFE # 0 +0xA3A8 0xBBFF # 0 +0xA3A9 0xBC00 # 0 +0xA3AA 0xBC01 # 0 +0xA3AB 0xBC02 # 0 +0xA3AC 0xBC03 # 0 +0xA3AD 0xBC04 # 0 +0xA3AE 0xBC05 # 0 +0xA3AF 0xBC06 # 0 +0xA3B0 0xBC07 # 0 +0xA3B1 0xBC08 # 0 +0xA3B3 0xBC09 # 0 +0xA3B4 0xBC0A # 0 +0xA3B5 0xBC0B # 0 +0xA3B6 0xBC0C # 0 +0xA3B7 0xBC0D # 0 +0xA3B8 0xBC0E # 0 +0xA3B9 0xBC0F # 0 +0xA3BA 0xBC10 # 0 +0xA3BB 0xBC11 # 0 +0xA3BC 0xBC12 # 0 +0xA3BD 0xBC13 # 0 +0xA441 0x1107 # 0 +0xA461 0xBC14 # 0 +0xA462 0xBC15 # 0 +0xA463 0xBC16 # 0 +0xA464 0xBC17 # 0 +0xA465 0xBC18 # 0 +0xA466 0xBC19 # 0 +0xA467 0xBC1A # 0 +0xA468 0xBC1B # 0 +0xA469 0xBC1C # 0 +0xA46A 0xBC1D # 0 +0xA46B 0xBC1E # 0 +0xA46C 0xBC1F # 0 +0xA46D 0xBC20 # 0 +0xA46E 0xBC21 # 0 +0xA46F 0xBC22 # 0 +0xA470 0xBC23 # 0 +0xA471 0xBC24 # 0 +0xA473 0xBC25 # 0 +0xA474 0xBC26 # 0 +0xA475 0xBC27 # 0 +0xA476 0xBC28 # 0 +0xA477 0xBC29 # 0 +0xA478 0xBC2A # 0 +0xA479 0xBC2B # 0 +0xA47A 0xBC2C # 0 +0xA47B 0xBC2D # 0 +0xA47C 0xBC2E # 0 +0xA47D 0xBC2F # 0 +0xA481 0xBC30 # 0 +0xA482 0xBC31 # 0 +0xA483 0xBC32 # 0 +0xA484 0xBC33 # 0 +0xA485 0xBC34 # 0 +0xA486 0xBC35 # 0 +0xA487 0xBC36 # 0 +0xA488 0xBC37 # 0 +0xA489 0xBC38 # 0 +0xA48A 0xBC39 # 0 +0xA48B 0xBC3A # 0 +0xA48C 0xBC3B # 0 +0xA48D 0xBC3C # 0 +0xA48E 0xBC3D # 0 +0xA48F 0xBC3E # 0 +0xA490 0xBC3F # 0 +0xA491 0xBC40 # 0 +0xA493 0xBC41 # 0 +0xA494 0xBC42 # 0 +0xA495 0xBC43 # 0 +0xA496 0xBC44 # 0 +0xA497 0xBC45 # 0 +0xA498 0xBC46 # 0 +0xA499 0xBC47 # 0 +0xA49A 0xBC48 # 0 +0xA49B 0xBC49 # 0 +0xA49C 0xBC4A # 0 +0xA49D 0xBC4B # 0 +0xA4A1 0xBC4C # 0 +0xA4A2 0xBC4D # 0 +0xA4A3 0xBC4E # 0 +0xA4A4 0xBC4F # 0 +0xA4A5 0xBC50 # 0 +0xA4A6 0xBC51 # 0 +0xA4A7 0xBC52 # 0 +0xA4A8 0xBC53 # 0 +0xA4A9 0xBC54 # 0 +0xA4AA 0xBC55 # 0 +0xA4AB 0xBC56 # 0 +0xA4AC 0xBC57 # 0 +0xA4AD 0xBC58 # 0 +0xA4AE 0xBC59 # 0 +0xA4AF 0xBC5A # 0 +0xA4B0 0xBC5B # 0 +0xA4B1 0xBC5C # 0 +0xA4B3 0xBC5D # 0 +0xA4B4 0xBC5E # 0 +0xA4B5 0xBC5F # 0 +0xA4B6 0xBC60 # 0 +0xA4B7 0xBC61 # 0 +0xA4B8 0xBC62 # 0 +0xA4B9 0xBC63 # 0 +0xA4BA 0xBC64 # 0 +0xA4BB 0xBC65 # 0 +0xA4BC 0xBC66 # 0 +0xA4BD 0xBC67 # 0 +0xA4C1 0xBC68 # 0 +0xA4C2 0xBC69 # 0 +0xA4C3 0xBC6A # 0 +0xA4C4 0xBC6B # 0 +0xA4C5 0xBC6C # 0 +0xA4C6 0xBC6D # 0 +0xA4C7 0xBC6E # 0 +0xA4C8 0xBC6F # 0 +0xA4C9 0xBC70 # 0 +0xA4CA 0xBC71 # 0 +0xA4CB 0xBC72 # 0 +0xA4CC 0xBC73 # 0 +0xA4CD 0xBC74 # 0 +0xA4CE 0xBC75 # 0 +0xA4CF 0xBC76 # 0 +0xA4D0 0xBC77 # 0 +0xA4D1 0xBC78 # 0 +0xA4D3 0xBC79 # 0 +0xA4D4 0xBC7A # 0 +0xA4D5 0xBC7B # 0 +0xA4D6 0xBC7C # 0 +0xA4D7 0xBC7D # 0 +0xA4D8 0xBC7E # 0 +0xA4D9 0xBC7F # 0 +0xA4DA 0xBC80 # 0 +0xA4DB 0xBC81 # 0 +0xA4DC 0xBC82 # 0 +0xA4DD 0xBC83 # 0 +0xA4E1 0xBC84 # 0 +0xA4E2 0xBC85 # 0 +0xA4E3 0xBC86 # 0 +0xA4E4 0xBC87 # 0 +0xA4E5 0xBC88 # 0 +0xA4E6 0xBC89 # 0 +0xA4E7 0xBC8A # 0 +0xA4E8 0xBC8B # 0 +0xA4E9 0xBC8C # 0 +0xA4EA 0xBC8D # 0 +0xA4EB 0xBC8E # 0 +0xA4EC 0xBC8F # 0 +0xA4ED 0xBC90 # 0 +0xA4EE 0xBC91 # 0 +0xA4EF 0xBC92 # 0 +0xA4F0 0xBC93 # 0 +0xA4F1 0xBC94 # 0 +0xA4F3 0xBC95 # 0 +0xA4F4 0xBC96 # 0 +0xA4F5 0xBC97 # 0 +0xA4F6 0xBC98 # 0 +0xA4F7 0xBC99 # 0 +0xA4F8 0xBC9A # 0 +0xA4F9 0xBC9B # 0 +0xA4FA 0xBC9C # 0 +0xA4FB 0xBC9D # 0 +0xA4FC 0xBC9E # 0 +0xA4FD 0xBC9F # 0 +0xA541 0xBCA0 # 0 +0xA542 0xBCA1 # 0 +0xA543 0xBCA2 # 0 +0xA544 0xBCA3 # 0 +0xA545 0xBCA4 # 0 +0xA546 0xBCA5 # 0 +0xA547 0xBCA6 # 0 +0xA548 0xBCA7 # 0 +0xA549 0xBCA8 # 0 +0xA54A 0xBCA9 # 0 +0xA54B 0xBCAA # 0 +0xA54C 0xBCAB # 0 +0xA54D 0xBCAC # 0 +0xA54E 0xBCAD # 0 +0xA54F 0xBCAE # 0 +0xA550 0xBCAF # 0 +0xA551 0xBCB0 # 0 +0xA553 0xBCB1 # 0 +0xA554 0xBCB2 # 0 +0xA555 0xBCB3 # 0 +0xA556 0xBCB4 # 0 +0xA557 0xBCB5 # 0 +0xA558 0xBCB6 # 0 +0xA559 0xBCB7 # 0 +0xA55A 0xBCB8 # 0 +0xA55B 0xBCB9 # 0 +0xA55C 0xBCBA # 0 +0xA55D 0xBCBB # 0 +0xA561 0xBCBC # 0 +0xA562 0xBCBD # 0 +0xA563 0xBCBE # 0 +0xA564 0xBCBF # 0 +0xA565 0xBCC0 # 0 +0xA566 0xBCC1 # 0 +0xA567 0xBCC2 # 0 +0xA568 0xBCC3 # 0 +0xA569 0xBCC4 # 0 +0xA56A 0xBCC5 # 0 +0xA56B 0xBCC6 # 0 +0xA56C 0xBCC7 # 0 +0xA56D 0xBCC8 # 0 +0xA56E 0xBCC9 # 0 +0xA56F 0xBCCA # 0 +0xA570 0xBCCB # 0 +0xA571 0xBCCC # 0 +0xA573 0xBCCD # 0 +0xA574 0xBCCE # 0 +0xA575 0xBCCF # 0 +0xA576 0xBCD0 # 0 +0xA577 0xBCD1 # 0 +0xA578 0xBCD2 # 0 +0xA579 0xBCD3 # 0 +0xA57A 0xBCD4 # 0 +0xA57B 0xBCD5 # 0 +0xA57C 0xBCD6 # 0 +0xA57D 0xBCD7 # 0 +0xA581 0xBCD8 # 0 +0xA582 0xBCD9 # 0 +0xA583 0xBCDA # 0 +0xA584 0xBCDB # 0 +0xA585 0xBCDC # 0 +0xA586 0xBCDD # 0 +0xA587 0xBCDE # 0 +0xA588 0xBCDF # 0 +0xA589 0xBCE0 # 0 +0xA58A 0xBCE1 # 0 +0xA58B 0xBCE2 # 0 +0xA58C 0xBCE3 # 0 +0xA58D 0xBCE4 # 0 +0xA58E 0xBCE5 # 0 +0xA58F 0xBCE6 # 0 +0xA590 0xBCE7 # 0 +0xA591 0xBCE8 # 0 +0xA593 0xBCE9 # 0 +0xA594 0xBCEA # 0 +0xA595 0xBCEB # 0 +0xA596 0xBCEC # 0 +0xA597 0xBCED # 0 +0xA598 0xBCEE # 0 +0xA599 0xBCEF # 0 +0xA59A 0xBCF0 # 0 +0xA59B 0xBCF1 # 0 +0xA59C 0xBCF2 # 0 +0xA59D 0xBCF3 # 0 +0xA5A1 0xBCF4 # 0 +0xA5A2 0xBCF5 # 0 +0xA5A3 0xBCF6 # 0 +0xA5A4 0xBCF7 # 0 +0xA5A5 0xBCF8 # 0 +0xA5A6 0xBCF9 # 0 +0xA5A7 0xBCFA # 0 +0xA5A8 0xBCFB # 0 +0xA5A9 0xBCFC # 0 +0xA5AA 0xBCFD # 0 +0xA5AB 0xBCFE # 0 +0xA5AC 0xBCFF # 0 +0xA5AD 0xBD00 # 0 +0xA5AE 0xBD01 # 0 +0xA5AF 0xBD02 # 0 +0xA5B0 0xBD03 # 0 +0xA5B1 0xBD04 # 0 +0xA5B3 0xBD05 # 0 +0xA5B4 0xBD06 # 0 +0xA5B5 0xBD07 # 0 +0xA5B6 0xBD08 # 0 +0xA5B7 0xBD09 # 0 +0xA5B8 0xBD0A # 0 +0xA5B9 0xBD0B # 0 +0xA5BA 0xBD0C # 0 +0xA5BB 0xBD0D # 0 +0xA5BC 0xBD0E # 0 +0xA5BD 0xBD0F # 0 +0xA5C1 0xBD10 # 0 +0xA5C2 0xBD11 # 0 +0xA5C3 0xBD12 # 0 +0xA5C4 0xBD13 # 0 +0xA5C5 0xBD14 # 0 +0xA5C6 0xBD15 # 0 +0xA5C7 0xBD16 # 0 +0xA5C8 0xBD17 # 0 +0xA5C9 0xBD18 # 0 +0xA5CA 0xBD19 # 0 +0xA5CB 0xBD1A # 0 +0xA5CC 0xBD1B # 0 +0xA5CD 0xBD1C # 0 +0xA5CE 0xBD1D # 0 +0xA5CF 0xBD1E # 0 +0xA5D0 0xBD1F # 0 +0xA5D1 0xBD20 # 0 +0xA5D3 0xBD21 # 0 +0xA5D4 0xBD22 # 0 +0xA5D5 0xBD23 # 0 +0xA5D6 0xBD24 # 0 +0xA5D7 0xBD25 # 0 +0xA5D8 0xBD26 # 0 +0xA5D9 0xBD27 # 0 +0xA5DA 0xBD28 # 0 +0xA5DB 0xBD29 # 0 +0xA5DC 0xBD2A # 0 +0xA5DD 0xBD2B # 0 +0xA5E1 0xBD2C # 0 +0xA5E2 0xBD2D # 0 +0xA5E3 0xBD2E # 0 +0xA5E4 0xBD2F # 0 +0xA5E5 0xBD30 # 0 +0xA5E6 0xBD31 # 0 +0xA5E7 0xBD32 # 0 +0xA5E8 0xBD33 # 0 +0xA5E9 0xBD34 # 0 +0xA5EA 0xBD35 # 0 +0xA5EB 0xBD36 # 0 +0xA5EC 0xBD37 # 0 +0xA5ED 0xBD38 # 0 +0xA5EE 0xBD39 # 0 +0xA5EF 0xBD3A # 0 +0xA5F0 0xBD3B # 0 +0xA5F1 0xBD3C # 0 +0xA5F3 0xBD3D # 0 +0xA5F4 0xBD3E # 0 +0xA5F5 0xBD3F # 0 +0xA5F6 0xBD40 # 0 +0xA5F7 0xBD41 # 0 +0xA5F8 0xBD42 # 0 +0xA5F9 0xBD43 # 0 +0xA5FA 0xBD44 # 0 +0xA5FB 0xBD45 # 0 +0xA5FC 0xBD46 # 0 +0xA5FD 0xBD47 # 0 +0xA641 0xBD48 # 0 +0xA642 0xBD49 # 0 +0xA643 0xBD4A # 0 +0xA644 0xBD4B # 0 +0xA645 0xBD4C # 0 +0xA646 0xBD4D # 0 +0xA647 0xBD4E # 0 +0xA648 0xBD4F # 0 +0xA649 0xBD50 # 0 +0xA64A 0xBD51 # 0 +0xA64B 0xBD52 # 0 +0xA64C 0xBD53 # 0 +0xA64D 0xBD54 # 0 +0xA64E 0xBD55 # 0 +0xA64F 0xBD56 # 0 +0xA650 0xBD57 # 0 +0xA651 0xBD58 # 0 +0xA653 0xBD59 # 0 +0xA654 0xBD5A # 0 +0xA655 0xBD5B # 0 +0xA656 0xBD5C # 0 +0xA657 0xBD5D # 0 +0xA658 0xBD5E # 0 +0xA659 0xBD5F # 0 +0xA65A 0xBD60 # 0 +0xA65B 0xBD61 # 0 +0xA65C 0xBD62 # 0 +0xA65D 0xBD63 # 0 +0xA661 0xBD64 # 0 +0xA662 0xBD65 # 0 +0xA663 0xBD66 # 0 +0xA664 0xBD67 # 0 +0xA665 0xBD68 # 0 +0xA666 0xBD69 # 0 +0xA667 0xBD6A # 0 +0xA668 0xBD6B # 0 +0xA669 0xBD6C # 0 +0xA66A 0xBD6D # 0 +0xA66B 0xBD6E # 0 +0xA66C 0xBD6F # 0 +0xA66D 0xBD70 # 0 +0xA66E 0xBD71 # 0 +0xA66F 0xBD72 # 0 +0xA670 0xBD73 # 0 +0xA671 0xBD74 # 0 +0xA673 0xBD75 # 0 +0xA674 0xBD76 # 0 +0xA675 0xBD77 # 0 +0xA676 0xBD78 # 0 +0xA677 0xBD79 # 0 +0xA678 0xBD7A # 0 +0xA679 0xBD7B # 0 +0xA67A 0xBD7C # 0 +0xA67B 0xBD7D # 0 +0xA67C 0xBD7E # 0 +0xA67D 0xBD7F # 0 +0xA681 0xBD80 # 0 +0xA682 0xBD81 # 0 +0xA683 0xBD82 # 0 +0xA684 0xBD83 # 0 +0xA685 0xBD84 # 0 +0xA686 0xBD85 # 0 +0xA687 0xBD86 # 0 +0xA688 0xBD87 # 0 +0xA689 0xBD88 # 0 +0xA68A 0xBD89 # 0 +0xA68B 0xBD8A # 0 +0xA68C 0xBD8B # 0 +0xA68D 0xBD8C # 0 +0xA68E 0xBD8D # 0 +0xA68F 0xBD8E # 0 +0xA690 0xBD8F # 0 +0xA691 0xBD90 # 0 +0xA693 0xBD91 # 0 +0xA694 0xBD92 # 0 +0xA695 0xBD93 # 0 +0xA696 0xBD94 # 0 +0xA697 0xBD95 # 0 +0xA698 0xBD96 # 0 +0xA699 0xBD97 # 0 +0xA69A 0xBD98 # 0 +0xA69B 0xBD99 # 0 +0xA69C 0xBD9A # 0 +0xA69D 0xBD9B # 0 +0xA6A1 0xBD9C # 0 +0xA6A2 0xBD9D # 0 +0xA6A3 0xBD9E # 0 +0xA6A4 0xBD9F # 0 +0xA6A5 0xBDA0 # 0 +0xA6A6 0xBDA1 # 0 +0xA6A7 0xBDA2 # 0 +0xA6A8 0xBDA3 # 0 +0xA6A9 0xBDA4 # 0 +0xA6AA 0xBDA5 # 0 +0xA6AB 0xBDA6 # 0 +0xA6AC 0xBDA7 # 0 +0xA6AD 0xBDA8 # 0 +0xA6AE 0xBDA9 # 0 +0xA6AF 0xBDAA # 0 +0xA6B0 0xBDAB # 0 +0xA6B1 0xBDAC # 0 +0xA6B3 0xBDAD # 0 +0xA6B4 0xBDAE # 0 +0xA6B5 0xBDAF # 0 +0xA6B6 0xBDB0 # 0 +0xA6B7 0xBDB1 # 0 +0xA6B8 0xBDB2 # 0 +0xA6B9 0xBDB3 # 0 +0xA6BA 0xBDB4 # 0 +0xA6BB 0xBDB5 # 0 +0xA6BC 0xBDB6 # 0 +0xA6BD 0xBDB7 # 0 +0xA6C1 0xBDB8 # 0 +0xA6C2 0xBDB9 # 0 +0xA6C3 0xBDBA # 0 +0xA6C4 0xBDBB # 0 +0xA6C5 0xBDBC # 0 +0xA6C6 0xBDBD # 0 +0xA6C7 0xBDBE # 0 +0xA6C8 0xBDBF # 0 +0xA6C9 0xBDC0 # 0 +0xA6CA 0xBDC1 # 0 +0xA6CB 0xBDC2 # 0 +0xA6CC 0xBDC3 # 0 +0xA6CD 0xBDC4 # 0 +0xA6CE 0xBDC5 # 0 +0xA6CF 0xBDC6 # 0 +0xA6D0 0xBDC7 # 0 +0xA6D1 0xBDC8 # 0 +0xA6D3 0xBDC9 # 0 +0xA6D4 0xBDCA # 0 +0xA6D5 0xBDCB # 0 +0xA6D6 0xBDCC # 0 +0xA6D7 0xBDCD # 0 +0xA6D8 0xBDCE # 0 +0xA6D9 0xBDCF # 0 +0xA6DA 0xBDD0 # 0 +0xA6DB 0xBDD1 # 0 +0xA6DC 0xBDD2 # 0 +0xA6DD 0xBDD3 # 0 +0xA6E1 0xBDD4 # 0 +0xA6E2 0xBDD5 # 0 +0xA6E3 0xBDD6 # 0 +0xA6E4 0xBDD7 # 0 +0xA6E5 0xBDD8 # 0 +0xA6E6 0xBDD9 # 0 +0xA6E7 0xBDDA # 0 +0xA6E8 0xBDDB # 0 +0xA6E9 0xBDDC # 0 +0xA6EA 0xBDDD # 0 +0xA6EB 0xBDDE # 0 +0xA6EC 0xBDDF # 0 +0xA6ED 0xBDE0 # 0 +0xA6EE 0xBDE1 # 0 +0xA6EF 0xBDE2 # 0 +0xA6F0 0xBDE3 # 0 +0xA6F1 0xBDE4 # 0 +0xA6F3 0xBDE5 # 0 +0xA6F4 0xBDE6 # 0 +0xA6F5 0xBDE7 # 0 +0xA6F6 0xBDE8 # 0 +0xA6F7 0xBDE9 # 0 +0xA6F8 0xBDEA # 0 +0xA6F9 0xBDEB # 0 +0xA6FA 0xBDEC # 0 +0xA6FB 0xBDED # 0 +0xA6FC 0xBDEE # 0 +0xA6FD 0xBDEF # 0 +0xA741 0xBDF0 # 0 +0xA742 0xBDF1 # 0 +0xA743 0xBDF2 # 0 +0xA744 0xBDF3 # 0 +0xA745 0xBDF4 # 0 +0xA746 0xBDF5 # 0 +0xA747 0xBDF6 # 0 +0xA748 0xBDF7 # 0 +0xA749 0xBDF8 # 0 +0xA74A 0xBDF9 # 0 +0xA74B 0xBDFA # 0 +0xA74C 0xBDFB # 0 +0xA74D 0xBDFC # 0 +0xA74E 0xBDFD # 0 +0xA74F 0xBDFE # 0 +0xA750 0xBDFF # 0 +0xA751 0xBE00 # 0 +0xA753 0xBE01 # 0 +0xA754 0xBE02 # 0 +0xA755 0xBE03 # 0 +0xA756 0xBE04 # 0 +0xA757 0xBE05 # 0 +0xA758 0xBE06 # 0 +0xA759 0xBE07 # 0 +0xA75A 0xBE08 # 0 +0xA75B 0xBE09 # 0 +0xA75C 0xBE0A # 0 +0xA75D 0xBE0B # 0 +0xA761 0xBE0C # 0 +0xA762 0xBE0D # 0 +0xA763 0xBE0E # 0 +0xA764 0xBE0F # 0 +0xA765 0xBE10 # 0 +0xA766 0xBE11 # 0 +0xA767 0xBE12 # 0 +0xA768 0xBE13 # 0 +0xA769 0xBE14 # 0 +0xA76A 0xBE15 # 0 +0xA76B 0xBE16 # 0 +0xA76C 0xBE17 # 0 +0xA76D 0xBE18 # 0 +0xA76E 0xBE19 # 0 +0xA76F 0xBE1A # 0 +0xA770 0xBE1B # 0 +0xA771 0xBE1C # 0 +0xA773 0xBE1D # 0 +0xA774 0xBE1E # 0 +0xA775 0xBE1F # 0 +0xA776 0xBE20 # 0 +0xA777 0xBE21 # 0 +0xA778 0xBE22 # 0 +0xA779 0xBE23 # 0 +0xA77A 0xBE24 # 0 +0xA77B 0xBE25 # 0 +0xA77C 0xBE26 # 0 +0xA77D 0xBE27 # 0 +0xA781 0xBE28 # 0 +0xA782 0xBE29 # 0 +0xA783 0xBE2A # 0 +0xA784 0xBE2B # 0 +0xA785 0xBE2C # 0 +0xA786 0xBE2D # 0 +0xA787 0xBE2E # 0 +0xA788 0xBE2F # 0 +0xA789 0xBE30 # 0 +0xA78A 0xBE31 # 0 +0xA78B 0xBE32 # 0 +0xA78C 0xBE33 # 0 +0xA78D 0xBE34 # 0 +0xA78E 0xBE35 # 0 +0xA78F 0xBE36 # 0 +0xA790 0xBE37 # 0 +0xA791 0xBE38 # 0 +0xA793 0xBE39 # 0 +0xA794 0xBE3A # 0 +0xA795 0xBE3B # 0 +0xA796 0xBE3C # 0 +0xA797 0xBE3D # 0 +0xA798 0xBE3E # 0 +0xA799 0xBE3F # 0 +0xA79A 0xBE40 # 0 +0xA79B 0xBE41 # 0 +0xA79C 0xBE42 # 0 +0xA79D 0xBE43 # 0 +0xA7A1 0xBE44 # 0 +0xA7A2 0xBE45 # 0 +0xA7A3 0xBE46 # 0 +0xA7A4 0xBE47 # 0 +0xA7A5 0xBE48 # 0 +0xA7A6 0xBE49 # 0 +0xA7A7 0xBE4A # 0 +0xA7A8 0xBE4B # 0 +0xA7A9 0xBE4C # 0 +0xA7AA 0xBE4D # 0 +0xA7AB 0xBE4E # 0 +0xA7AC 0xBE4F # 0 +0xA7AD 0xBE50 # 0 +0xA7AE 0xBE51 # 0 +0xA7AF 0xBE52 # 0 +0xA7B0 0xBE53 # 0 +0xA7B1 0xBE54 # 0 +0xA7B3 0xBE55 # 0 +0xA7B4 0xBE56 # 0 +0xA7B5 0xBE57 # 0 +0xA7B6 0xBE58 # 0 +0xA7B7 0xBE59 # 0 +0xA7B8 0xBE5A # 0 +0xA7B9 0xBE5B # 0 +0xA7BA 0xBE5C # 0 +0xA7BB 0xBE5D # 0 +0xA7BC 0xBE5E # 0 +0xA7BD 0xBE5F # 0 +0xA841 0x1108 # 0 +0xA861 0xBE60 # 0 +0xA862 0xBE61 # 0 +0xA863 0xBE62 # 0 +0xA864 0xBE63 # 0 +0xA865 0xBE64 # 0 +0xA866 0xBE65 # 0 +0xA867 0xBE66 # 0 +0xA868 0xBE67 # 0 +0xA869 0xBE68 # 0 +0xA86A 0xBE69 # 0 +0xA86B 0xBE6A # 0 +0xA86C 0xBE6B # 0 +0xA86D 0xBE6C # 0 +0xA86E 0xBE6D # 0 +0xA86F 0xBE6E # 0 +0xA870 0xBE6F # 0 +0xA871 0xBE70 # 0 +0xA873 0xBE71 # 0 +0xA874 0xBE72 # 0 +0xA875 0xBE73 # 0 +0xA876 0xBE74 # 0 +0xA877 0xBE75 # 0 +0xA878 0xBE76 # 0 +0xA879 0xBE77 # 0 +0xA87A 0xBE78 # 0 +0xA87B 0xBE79 # 0 +0xA87C 0xBE7A # 0 +0xA87D 0xBE7B # 0 +0xA881 0xBE7C # 0 +0xA882 0xBE7D # 0 +0xA883 0xBE7E # 0 +0xA884 0xBE7F # 0 +0xA885 0xBE80 # 0 +0xA886 0xBE81 # 0 +0xA887 0xBE82 # 0 +0xA888 0xBE83 # 0 +0xA889 0xBE84 # 0 +0xA88A 0xBE85 # 0 +0xA88B 0xBE86 # 0 +0xA88C 0xBE87 # 0 +0xA88D 0xBE88 # 0 +0xA88E 0xBE89 # 0 +0xA88F 0xBE8A # 0 +0xA890 0xBE8B # 0 +0xA891 0xBE8C # 0 +0xA893 0xBE8D # 0 +0xA894 0xBE8E # 0 +0xA895 0xBE8F # 0 +0xA896 0xBE90 # 0 +0xA897 0xBE91 # 0 +0xA898 0xBE92 # 0 +0xA899 0xBE93 # 0 +0xA89A 0xBE94 # 0 +0xA89B 0xBE95 # 0 +0xA89C 0xBE96 # 0 +0xA89D 0xBE97 # 0 +0xA8A1 0xBE98 # 0 +0xA8A2 0xBE99 # 0 +0xA8A3 0xBE9A # 0 +0xA8A4 0xBE9B # 0 +0xA8A5 0xBE9C # 0 +0xA8A6 0xBE9D # 0 +0xA8A7 0xBE9E # 0 +0xA8A8 0xBE9F # 0 +0xA8A9 0xBEA0 # 0 +0xA8AA 0xBEA1 # 0 +0xA8AB 0xBEA2 # 0 +0xA8AC 0xBEA3 # 0 +0xA8AD 0xBEA4 # 0 +0xA8AE 0xBEA5 # 0 +0xA8AF 0xBEA6 # 0 +0xA8B0 0xBEA7 # 0 +0xA8B1 0xBEA8 # 0 +0xA8B3 0xBEA9 # 0 +0xA8B4 0xBEAA # 0 +0xA8B5 0xBEAB # 0 +0xA8B6 0xBEAC # 0 +0xA8B7 0xBEAD # 0 +0xA8B8 0xBEAE # 0 +0xA8B9 0xBEAF # 0 +0xA8BA 0xBEB0 # 0 +0xA8BB 0xBEB1 # 0 +0xA8BC 0xBEB2 # 0 +0xA8BD 0xBEB3 # 0 +0xA8C1 0xBEB4 # 0 +0xA8C2 0xBEB5 # 0 +0xA8C3 0xBEB6 # 0 +0xA8C4 0xBEB7 # 0 +0xA8C5 0xBEB8 # 0 +0xA8C6 0xBEB9 # 0 +0xA8C7 0xBEBA # 0 +0xA8C8 0xBEBB # 0 +0xA8C9 0xBEBC # 0 +0xA8CA 0xBEBD # 0 +0xA8CB 0xBEBE # 0 +0xA8CC 0xBEBF # 0 +0xA8CD 0xBEC0 # 0 +0xA8CE 0xBEC1 # 0 +0xA8CF 0xBEC2 # 0 +0xA8D0 0xBEC3 # 0 +0xA8D1 0xBEC4 # 0 +0xA8D3 0xBEC5 # 0 +0xA8D4 0xBEC6 # 0 +0xA8D5 0xBEC7 # 0 +0xA8D6 0xBEC8 # 0 +0xA8D7 0xBEC9 # 0 +0xA8D8 0xBECA # 0 +0xA8D9 0xBECB # 0 +0xA8DA 0xBECC # 0 +0xA8DB 0xBECD # 0 +0xA8DC 0xBECE # 0 +0xA8DD 0xBECF # 0 +0xA8E1 0xBED0 # 0 +0xA8E2 0xBED1 # 0 +0xA8E3 0xBED2 # 0 +0xA8E4 0xBED3 # 0 +0xA8E5 0xBED4 # 0 +0xA8E6 0xBED5 # 0 +0xA8E7 0xBED6 # 0 +0xA8E8 0xBED7 # 0 +0xA8E9 0xBED8 # 0 +0xA8EA 0xBED9 # 0 +0xA8EB 0xBEDA # 0 +0xA8EC 0xBEDB # 0 +0xA8ED 0xBEDC # 0 +0xA8EE 0xBEDD # 0 +0xA8EF 0xBEDE # 0 +0xA8F0 0xBEDF # 0 +0xA8F1 0xBEE0 # 0 +0xA8F3 0xBEE1 # 0 +0xA8F4 0xBEE2 # 0 +0xA8F5 0xBEE3 # 0 +0xA8F6 0xBEE4 # 0 +0xA8F7 0xBEE5 # 0 +0xA8F8 0xBEE6 # 0 +0xA8F9 0xBEE7 # 0 +0xA8FA 0xBEE8 # 0 +0xA8FB 0xBEE9 # 0 +0xA8FC 0xBEEA # 0 +0xA8FD 0xBEEB # 0 +0xA941 0xBEEC # 0 +0xA942 0xBEED # 0 +0xA943 0xBEEE # 0 +0xA944 0xBEEF # 0 +0xA945 0xBEF0 # 0 +0xA946 0xBEF1 # 0 +0xA947 0xBEF2 # 0 +0xA948 0xBEF3 # 0 +0xA949 0xBEF4 # 0 +0xA94A 0xBEF5 # 0 +0xA94B 0xBEF6 # 0 +0xA94C 0xBEF7 # 0 +0xA94D 0xBEF8 # 0 +0xA94E 0xBEF9 # 0 +0xA94F 0xBEFA # 0 +0xA950 0xBEFB # 0 +0xA951 0xBEFC # 0 +0xA953 0xBEFD # 0 +0xA954 0xBEFE # 0 +0xA955 0xBEFF # 0 +0xA956 0xBF00 # 0 +0xA957 0xBF01 # 0 +0xA958 0xBF02 # 0 +0xA959 0xBF03 # 0 +0xA95A 0xBF04 # 0 +0xA95B 0xBF05 # 0 +0xA95C 0xBF06 # 0 +0xA95D 0xBF07 # 0 +0xA961 0xBF08 # 0 +0xA962 0xBF09 # 0 +0xA963 0xBF0A # 0 +0xA964 0xBF0B # 0 +0xA965 0xBF0C # 0 +0xA966 0xBF0D # 0 +0xA967 0xBF0E # 0 +0xA968 0xBF0F # 0 +0xA969 0xBF10 # 0 +0xA96A 0xBF11 # 0 +0xA96B 0xBF12 # 0 +0xA96C 0xBF13 # 0 +0xA96D 0xBF14 # 0 +0xA96E 0xBF15 # 0 +0xA96F 0xBF16 # 0 +0xA970 0xBF17 # 0 +0xA971 0xBF18 # 0 +0xA973 0xBF19 # 0 +0xA974 0xBF1A # 0 +0xA975 0xBF1B # 0 +0xA976 0xBF1C # 0 +0xA977 0xBF1D # 0 +0xA978 0xBF1E # 0 +0xA979 0xBF1F # 0 +0xA97A 0xBF20 # 0 +0xA97B 0xBF21 # 0 +0xA97C 0xBF22 # 0 +0xA97D 0xBF23 # 0 +0xA981 0xBF24 # 0 +0xA982 0xBF25 # 0 +0xA983 0xBF26 # 0 +0xA984 0xBF27 # 0 +0xA985 0xBF28 # 0 +0xA986 0xBF29 # 0 +0xA987 0xBF2A # 0 +0xA988 0xBF2B # 0 +0xA989 0xBF2C # 0 +0xA98A 0xBF2D # 0 +0xA98B 0xBF2E # 0 +0xA98C 0xBF2F # 0 +0xA98D 0xBF30 # 0 +0xA98E 0xBF31 # 0 +0xA98F 0xBF32 # 0 +0xA990 0xBF33 # 0 +0xA991 0xBF34 # 0 +0xA993 0xBF35 # 0 +0xA994 0xBF36 # 0 +0xA995 0xBF37 # 0 +0xA996 0xBF38 # 0 +0xA997 0xBF39 # 0 +0xA998 0xBF3A # 0 +0xA999 0xBF3B # 0 +0xA99A 0xBF3C # 0 +0xA99B 0xBF3D # 0 +0xA99C 0xBF3E # 0 +0xA99D 0xBF3F # 0 +0xA9A1 0xBF40 # 0 +0xA9A2 0xBF41 # 0 +0xA9A3 0xBF42 # 0 +0xA9A4 0xBF43 # 0 +0xA9A5 0xBF44 # 0 +0xA9A6 0xBF45 # 0 +0xA9A7 0xBF46 # 0 +0xA9A8 0xBF47 # 0 +0xA9A9 0xBF48 # 0 +0xA9AA 0xBF49 # 0 +0xA9AB 0xBF4A # 0 +0xA9AC 0xBF4B # 0 +0xA9AD 0xBF4C # 0 +0xA9AE 0xBF4D # 0 +0xA9AF 0xBF4E # 0 +0xA9B0 0xBF4F # 0 +0xA9B1 0xBF50 # 0 +0xA9B3 0xBF51 # 0 +0xA9B4 0xBF52 # 0 +0xA9B5 0xBF53 # 0 +0xA9B6 0xBF54 # 0 +0xA9B7 0xBF55 # 0 +0xA9B8 0xBF56 # 0 +0xA9B9 0xBF57 # 0 +0xA9BA 0xBF58 # 0 +0xA9BB 0xBF59 # 0 +0xA9BC 0xBF5A # 0 +0xA9BD 0xBF5B # 0 +0xA9C1 0xBF5C # 0 +0xA9C2 0xBF5D # 0 +0xA9C3 0xBF5E # 0 +0xA9C4 0xBF5F # 0 +0xA9C5 0xBF60 # 0 +0xA9C6 0xBF61 # 0 +0xA9C7 0xBF62 # 0 +0xA9C8 0xBF63 # 0 +0xA9C9 0xBF64 # 0 +0xA9CA 0xBF65 # 0 +0xA9CB 0xBF66 # 0 +0xA9CC 0xBF67 # 0 +0xA9CD 0xBF68 # 0 +0xA9CE 0xBF69 # 0 +0xA9CF 0xBF6A # 0 +0xA9D0 0xBF6B # 0 +0xA9D1 0xBF6C # 0 +0xA9D3 0xBF6D # 0 +0xA9D4 0xBF6E # 0 +0xA9D5 0xBF6F # 0 +0xA9D6 0xBF70 # 0 +0xA9D7 0xBF71 # 0 +0xA9D8 0xBF72 # 0 +0xA9D9 0xBF73 # 0 +0xA9DA 0xBF74 # 0 +0xA9DB 0xBF75 # 0 +0xA9DC 0xBF76 # 0 +0xA9DD 0xBF77 # 0 +0xA9E1 0xBF78 # 0 +0xA9E2 0xBF79 # 0 +0xA9E3 0xBF7A # 0 +0xA9E4 0xBF7B # 0 +0xA9E5 0xBF7C # 0 +0xA9E6 0xBF7D # 0 +0xA9E7 0xBF7E # 0 +0xA9E8 0xBF7F # 0 +0xA9E9 0xBF80 # 0 +0xA9EA 0xBF81 # 0 +0xA9EB 0xBF82 # 0 +0xA9EC 0xBF83 # 0 +0xA9ED 0xBF84 # 0 +0xA9EE 0xBF85 # 0 +0xA9EF 0xBF86 # 0 +0xA9F0 0xBF87 # 0 +0xA9F1 0xBF88 # 0 +0xA9F3 0xBF89 # 0 +0xA9F4 0xBF8A # 0 +0xA9F5 0xBF8B # 0 +0xA9F6 0xBF8C # 0 +0xA9F7 0xBF8D # 0 +0xA9F8 0xBF8E # 0 +0xA9F9 0xBF8F # 0 +0xA9FA 0xBF90 # 0 +0xA9FB 0xBF91 # 0 +0xA9FC 0xBF92 # 0 +0xA9FD 0xBF93 # 0 +0xAA41 0xBF94 # 0 +0xAA42 0xBF95 # 0 +0xAA43 0xBF96 # 0 +0xAA44 0xBF97 # 0 +0xAA45 0xBF98 # 0 +0xAA46 0xBF99 # 0 +0xAA47 0xBF9A # 0 +0xAA48 0xBF9B # 0 +0xAA49 0xBF9C # 0 +0xAA4A 0xBF9D # 0 +0xAA4B 0xBF9E # 0 +0xAA4C 0xBF9F # 0 +0xAA4D 0xBFA0 # 0 +0xAA4E 0xBFA1 # 0 +0xAA4F 0xBFA2 # 0 +0xAA50 0xBFA3 # 0 +0xAA51 0xBFA4 # 0 +0xAA53 0xBFA5 # 0 +0xAA54 0xBFA6 # 0 +0xAA55 0xBFA7 # 0 +0xAA56 0xBFA8 # 0 +0xAA57 0xBFA9 # 0 +0xAA58 0xBFAA # 0 +0xAA59 0xBFAB # 0 +0xAA5A 0xBFAC # 0 +0xAA5B 0xBFAD # 0 +0xAA5C 0xBFAE # 0 +0xAA5D 0xBFAF # 0 +0xAA61 0xBFB0 # 0 +0xAA62 0xBFB1 # 0 +0xAA63 0xBFB2 # 0 +0xAA64 0xBFB3 # 0 +0xAA65 0xBFB4 # 0 +0xAA66 0xBFB5 # 0 +0xAA67 0xBFB6 # 0 +0xAA68 0xBFB7 # 0 +0xAA69 0xBFB8 # 0 +0xAA6A 0xBFB9 # 0 +0xAA6B 0xBFBA # 0 +0xAA6C 0xBFBB # 0 +0xAA6D 0xBFBC # 0 +0xAA6E 0xBFBD # 0 +0xAA6F 0xBFBE # 0 +0xAA70 0xBFBF # 0 +0xAA71 0xBFC0 # 0 +0xAA73 0xBFC1 # 0 +0xAA74 0xBFC2 # 0 +0xAA75 0xBFC3 # 0 +0xAA76 0xBFC4 # 0 +0xAA77 0xBFC5 # 0 +0xAA78 0xBFC6 # 0 +0xAA79 0xBFC7 # 0 +0xAA7A 0xBFC8 # 0 +0xAA7B 0xBFC9 # 0 +0xAA7C 0xBFCA # 0 +0xAA7D 0xBFCB # 0 +0xAA81 0xBFCC # 0 +0xAA82 0xBFCD # 0 +0xAA83 0xBFCE # 0 +0xAA84 0xBFCF # 0 +0xAA85 0xBFD0 # 0 +0xAA86 0xBFD1 # 0 +0xAA87 0xBFD2 # 0 +0xAA88 0xBFD3 # 0 +0xAA89 0xBFD4 # 0 +0xAA8A 0xBFD5 # 0 +0xAA8B 0xBFD6 # 0 +0xAA8C 0xBFD7 # 0 +0xAA8D 0xBFD8 # 0 +0xAA8E 0xBFD9 # 0 +0xAA8F 0xBFDA # 0 +0xAA90 0xBFDB # 0 +0xAA91 0xBFDC # 0 +0xAA93 0xBFDD # 0 +0xAA94 0xBFDE # 0 +0xAA95 0xBFDF # 0 +0xAA96 0xBFE0 # 0 +0xAA97 0xBFE1 # 0 +0xAA98 0xBFE2 # 0 +0xAA99 0xBFE3 # 0 +0xAA9A 0xBFE4 # 0 +0xAA9B 0xBFE5 # 0 +0xAA9C 0xBFE6 # 0 +0xAA9D 0xBFE7 # 0 +0xAAA1 0xBFE8 # 0 +0xAAA2 0xBFE9 # 0 +0xAAA3 0xBFEA # 0 +0xAAA4 0xBFEB # 0 +0xAAA5 0xBFEC # 0 +0xAAA6 0xBFED # 0 +0xAAA7 0xBFEE # 0 +0xAAA8 0xBFEF # 0 +0xAAA9 0xBFF0 # 0 +0xAAAA 0xBFF1 # 0 +0xAAAB 0xBFF2 # 0 +0xAAAC 0xBFF3 # 0 +0xAAAD 0xBFF4 # 0 +0xAAAE 0xBFF5 # 0 +0xAAAF 0xBFF6 # 0 +0xAAB0 0xBFF7 # 0 +0xAAB1 0xBFF8 # 0 +0xAAB3 0xBFF9 # 0 +0xAAB4 0xBFFA # 0 +0xAAB5 0xBFFB # 0 +0xAAB6 0xBFFC # 0 +0xAAB7 0xBFFD # 0 +0xAAB8 0xBFFE # 0 +0xAAB9 0xBFFF # 0 +0xAABA 0xC000 # 0 +0xAABB 0xC001 # 0 +0xAABC 0xC002 # 0 +0xAABD 0xC003 # 0 +0xAAC1 0xC004 # 0 +0xAAC2 0xC005 # 0 +0xAAC3 0xC006 # 0 +0xAAC4 0xC007 # 0 +0xAAC5 0xC008 # 0 +0xAAC6 0xC009 # 0 +0xAAC7 0xC00A # 0 +0xAAC8 0xC00B # 0 +0xAAC9 0xC00C # 0 +0xAACA 0xC00D # 0 +0xAACB 0xC00E # 0 +0xAACC 0xC00F # 0 +0xAACD 0xC010 # 0 +0xAACE 0xC011 # 0 +0xAACF 0xC012 # 0 +0xAAD0 0xC013 # 0 +0xAAD1 0xC014 # 0 +0xAAD3 0xC015 # 0 +0xAAD4 0xC016 # 0 +0xAAD5 0xC017 # 0 +0xAAD6 0xC018 # 0 +0xAAD7 0xC019 # 0 +0xAAD8 0xC01A # 0 +0xAAD9 0xC01B # 0 +0xAADA 0xC01C # 0 +0xAADB 0xC01D # 0 +0xAADC 0xC01E # 0 +0xAADD 0xC01F # 0 +0xAAE1 0xC020 # 0 +0xAAE2 0xC021 # 0 +0xAAE3 0xC022 # 0 +0xAAE4 0xC023 # 0 +0xAAE5 0xC024 # 0 +0xAAE6 0xC025 # 0 +0xAAE7 0xC026 # 0 +0xAAE8 0xC027 # 0 +0xAAE9 0xC028 # 0 +0xAAEA 0xC029 # 0 +0xAAEB 0xC02A # 0 +0xAAEC 0xC02B # 0 +0xAAED 0xC02C # 0 +0xAAEE 0xC02D # 0 +0xAAEF 0xC02E # 0 +0xAAF0 0xC02F # 0 +0xAAF1 0xC030 # 0 +0xAAF3 0xC031 # 0 +0xAAF4 0xC032 # 0 +0xAAF5 0xC033 # 0 +0xAAF6 0xC034 # 0 +0xAAF7 0xC035 # 0 +0xAAF8 0xC036 # 0 +0xAAF9 0xC037 # 0 +0xAAFA 0xC038 # 0 +0xAAFB 0xC039 # 0 +0xAAFC 0xC03A # 0 +0xAAFD 0xC03B # 0 +0xAB41 0xC03C # 0 +0xAB42 0xC03D # 0 +0xAB43 0xC03E # 0 +0xAB44 0xC03F # 0 +0xAB45 0xC040 # 0 +0xAB46 0xC041 # 0 +0xAB47 0xC042 # 0 +0xAB48 0xC043 # 0 +0xAB49 0xC044 # 0 +0xAB4A 0xC045 # 0 +0xAB4B 0xC046 # 0 +0xAB4C 0xC047 # 0 +0xAB4D 0xC048 # 0 +0xAB4E 0xC049 # 0 +0xAB4F 0xC04A # 0 +0xAB50 0xC04B # 0 +0xAB51 0xC04C # 0 +0xAB53 0xC04D # 0 +0xAB54 0xC04E # 0 +0xAB55 0xC04F # 0 +0xAB56 0xC050 # 0 +0xAB57 0xC051 # 0 +0xAB58 0xC052 # 0 +0xAB59 0xC053 # 0 +0xAB5A 0xC054 # 0 +0xAB5B 0xC055 # 0 +0xAB5C 0xC056 # 0 +0xAB5D 0xC057 # 0 +0xAB61 0xC058 # 0 +0xAB62 0xC059 # 0 +0xAB63 0xC05A # 0 +0xAB64 0xC05B # 0 +0xAB65 0xC05C # 0 +0xAB66 0xC05D # 0 +0xAB67 0xC05E # 0 +0xAB68 0xC05F # 0 +0xAB69 0xC060 # 0 +0xAB6A 0xC061 # 0 +0xAB6B 0xC062 # 0 +0xAB6C 0xC063 # 0 +0xAB6D 0xC064 # 0 +0xAB6E 0xC065 # 0 +0xAB6F 0xC066 # 0 +0xAB70 0xC067 # 0 +0xAB71 0xC068 # 0 +0xAB73 0xC069 # 0 +0xAB74 0xC06A # 0 +0xAB75 0xC06B # 0 +0xAB76 0xC06C # 0 +0xAB77 0xC06D # 0 +0xAB78 0xC06E # 0 +0xAB79 0xC06F # 0 +0xAB7A 0xC070 # 0 +0xAB7B 0xC071 # 0 +0xAB7C 0xC072 # 0 +0xAB7D 0xC073 # 0 +0xAB81 0xC074 # 0 +0xAB82 0xC075 # 0 +0xAB83 0xC076 # 0 +0xAB84 0xC077 # 0 +0xAB85 0xC078 # 0 +0xAB86 0xC079 # 0 +0xAB87 0xC07A # 0 +0xAB88 0xC07B # 0 +0xAB89 0xC07C # 0 +0xAB8A 0xC07D # 0 +0xAB8B 0xC07E # 0 +0xAB8C 0xC07F # 0 +0xAB8D 0xC080 # 0 +0xAB8E 0xC081 # 0 +0xAB8F 0xC082 # 0 +0xAB90 0xC083 # 0 +0xAB91 0xC084 # 0 +0xAB93 0xC085 # 0 +0xAB94 0xC086 # 0 +0xAB95 0xC087 # 0 +0xAB96 0xC088 # 0 +0xAB97 0xC089 # 0 +0xAB98 0xC08A # 0 +0xAB99 0xC08B # 0 +0xAB9A 0xC08C # 0 +0xAB9B 0xC08D # 0 +0xAB9C 0xC08E # 0 +0xAB9D 0xC08F # 0 +0xABA1 0xC090 # 0 +0xABA2 0xC091 # 0 +0xABA3 0xC092 # 0 +0xABA4 0xC093 # 0 +0xABA5 0xC094 # 0 +0xABA6 0xC095 # 0 +0xABA7 0xC096 # 0 +0xABA8 0xC097 # 0 +0xABA9 0xC098 # 0 +0xABAA 0xC099 # 0 +0xABAB 0xC09A # 0 +0xABAC 0xC09B # 0 +0xABAD 0xC09C # 0 +0xABAE 0xC09D # 0 +0xABAF 0xC09E # 0 +0xABB0 0xC09F # 0 +0xABB1 0xC0A0 # 0 +0xABB3 0xC0A1 # 0 +0xABB4 0xC0A2 # 0 +0xABB5 0xC0A3 # 0 +0xABB6 0xC0A4 # 0 +0xABB7 0xC0A5 # 0 +0xABB8 0xC0A6 # 0 +0xABB9 0xC0A7 # 0 +0xABBA 0xC0A8 # 0 +0xABBB 0xC0A9 # 0 +0xABBC 0xC0AA # 0 +0xABBD 0xC0AB # 0 +0xAC41 0x1109 # 0 +0xAC61 0xC0AC # 0 +0xAC62 0xC0AD # 0 +0xAC63 0xC0AE # 0 +0xAC64 0xC0AF # 0 +0xAC65 0xC0B0 # 0 +0xAC66 0xC0B1 # 0 +0xAC67 0xC0B2 # 0 +0xAC68 0xC0B3 # 0 +0xAC69 0xC0B4 # 0 +0xAC6A 0xC0B5 # 0 +0xAC6B 0xC0B6 # 0 +0xAC6C 0xC0B7 # 0 +0xAC6D 0xC0B8 # 0 +0xAC6E 0xC0B9 # 0 +0xAC6F 0xC0BA # 0 +0xAC70 0xC0BB # 0 +0xAC71 0xC0BC # 0 +0xAC73 0xC0BD # 0 +0xAC74 0xC0BE # 0 +0xAC75 0xC0BF # 0 +0xAC76 0xC0C0 # 0 +0xAC77 0xC0C1 # 0 +0xAC78 0xC0C2 # 0 +0xAC79 0xC0C3 # 0 +0xAC7A 0xC0C4 # 0 +0xAC7B 0xC0C5 # 0 +0xAC7C 0xC0C6 # 0 +0xAC7D 0xC0C7 # 0 +0xAC81 0xC0C8 # 0 +0xAC82 0xC0C9 # 0 +0xAC83 0xC0CA # 0 +0xAC84 0xC0CB # 0 +0xAC85 0xC0CC # 0 +0xAC86 0xC0CD # 0 +0xAC87 0xC0CE # 0 +0xAC88 0xC0CF # 0 +0xAC89 0xC0D0 # 0 +0xAC8A 0xC0D1 # 0 +0xAC8B 0xC0D2 # 0 +0xAC8C 0xC0D3 # 0 +0xAC8D 0xC0D4 # 0 +0xAC8E 0xC0D5 # 0 +0xAC8F 0xC0D6 # 0 +0xAC90 0xC0D7 # 0 +0xAC91 0xC0D8 # 0 +0xAC93 0xC0D9 # 0 +0xAC94 0xC0DA # 0 +0xAC95 0xC0DB # 0 +0xAC96 0xC0DC # 0 +0xAC97 0xC0DD # 0 +0xAC98 0xC0DE # 0 +0xAC99 0xC0DF # 0 +0xAC9A 0xC0E0 # 0 +0xAC9B 0xC0E1 # 0 +0xAC9C 0xC0E2 # 0 +0xAC9D 0xC0E3 # 0 +0xACA1 0xC0E4 # 0 +0xACA2 0xC0E5 # 0 +0xACA3 0xC0E6 # 0 +0xACA4 0xC0E7 # 0 +0xACA5 0xC0E8 # 0 +0xACA6 0xC0E9 # 0 +0xACA7 0xC0EA # 0 +0xACA8 0xC0EB # 0 +0xACA9 0xC0EC # 0 +0xACAA 0xC0ED # 0 +0xACAB 0xC0EE # 0 +0xACAC 0xC0EF # 0 +0xACAD 0xC0F0 # 0 +0xACAE 0xC0F1 # 0 +0xACAF 0xC0F2 # 0 +0xACB0 0xC0F3 # 0 +0xACB1 0xC0F4 # 0 +0xACB3 0xC0F5 # 0 +0xACB4 0xC0F6 # 0 +0xACB5 0xC0F7 # 0 +0xACB6 0xC0F8 # 0 +0xACB7 0xC0F9 # 0 +0xACB8 0xC0FA # 0 +0xACB9 0xC0FB # 0 +0xACBA 0xC0FC # 0 +0xACBB 0xC0FD # 0 +0xACBC 0xC0FE # 0 +0xACBD 0xC0FF # 0 +0xACC1 0xC100 # 0 +0xACC2 0xC101 # 0 +0xACC3 0xC102 # 0 +0xACC4 0xC103 # 0 +0xACC5 0xC104 # 0 +0xACC6 0xC105 # 0 +0xACC7 0xC106 # 0 +0xACC8 0xC107 # 0 +0xACC9 0xC108 # 0 +0xACCA 0xC109 # 0 +0xACCB 0xC10A # 0 +0xACCC 0xC10B # 0 +0xACCD 0xC10C # 0 +0xACCE 0xC10D # 0 +0xACCF 0xC10E # 0 +0xACD0 0xC10F # 0 +0xACD1 0xC110 # 0 +0xACD3 0xC111 # 0 +0xACD4 0xC112 # 0 +0xACD5 0xC113 # 0 +0xACD6 0xC114 # 0 +0xACD7 0xC115 # 0 +0xACD8 0xC116 # 0 +0xACD9 0xC117 # 0 +0xACDA 0xC118 # 0 +0xACDB 0xC119 # 0 +0xACDC 0xC11A # 0 +0xACDD 0xC11B # 0 +0xACE1 0xC11C # 0 +0xACE2 0xC11D # 0 +0xACE3 0xC11E # 0 +0xACE4 0xC11F # 0 +0xACE5 0xC120 # 0 +0xACE6 0xC121 # 0 +0xACE7 0xC122 # 0 +0xACE8 0xC123 # 0 +0xACE9 0xC124 # 0 +0xACEA 0xC125 # 0 +0xACEB 0xC126 # 0 +0xACEC 0xC127 # 0 +0xACED 0xC128 # 0 +0xACEE 0xC129 # 0 +0xACEF 0xC12A # 0 +0xACF0 0xC12B # 0 +0xACF1 0xC12C # 0 +0xACF3 0xC12D # 0 +0xACF4 0xC12E # 0 +0xACF5 0xC12F # 0 +0xACF6 0xC130 # 0 +0xACF7 0xC131 # 0 +0xACF8 0xC132 # 0 +0xACF9 0xC133 # 0 +0xACFA 0xC134 # 0 +0xACFB 0xC135 # 0 +0xACFC 0xC136 # 0 +0xACFD 0xC137 # 0 +0xAD41 0xC138 # 0 +0xAD42 0xC139 # 0 +0xAD43 0xC13A # 0 +0xAD44 0xC13B # 0 +0xAD45 0xC13C # 0 +0xAD46 0xC13D # 0 +0xAD47 0xC13E # 0 +0xAD48 0xC13F # 0 +0xAD49 0xC140 # 0 +0xAD4A 0xC141 # 0 +0xAD4B 0xC142 # 0 +0xAD4C 0xC143 # 0 +0xAD4D 0xC144 # 0 +0xAD4E 0xC145 # 0 +0xAD4F 0xC146 # 0 +0xAD50 0xC147 # 0 +0xAD51 0xC148 # 0 +0xAD53 0xC149 # 0 +0xAD54 0xC14A # 0 +0xAD55 0xC14B # 0 +0xAD56 0xC14C # 0 +0xAD57 0xC14D # 0 +0xAD58 0xC14E # 0 +0xAD59 0xC14F # 0 +0xAD5A 0xC150 # 0 +0xAD5B 0xC151 # 0 +0xAD5C 0xC152 # 0 +0xAD5D 0xC153 # 0 +0xAD61 0xC154 # 0 +0xAD62 0xC155 # 0 +0xAD63 0xC156 # 0 +0xAD64 0xC157 # 0 +0xAD65 0xC158 # 0 +0xAD66 0xC159 # 0 +0xAD67 0xC15A # 0 +0xAD68 0xC15B # 0 +0xAD69 0xC15C # 0 +0xAD6A 0xC15D # 0 +0xAD6B 0xC15E # 0 +0xAD6C 0xC15F # 0 +0xAD6D 0xC160 # 0 +0xAD6E 0xC161 # 0 +0xAD6F 0xC162 # 0 +0xAD70 0xC163 # 0 +0xAD71 0xC164 # 0 +0xAD73 0xC165 # 0 +0xAD74 0xC166 # 0 +0xAD75 0xC167 # 0 +0xAD76 0xC168 # 0 +0xAD77 0xC169 # 0 +0xAD78 0xC16A # 0 +0xAD79 0xC16B # 0 +0xAD7A 0xC16C # 0 +0xAD7B 0xC16D # 0 +0xAD7C 0xC16E # 0 +0xAD7D 0xC16F # 0 +0xAD81 0xC170 # 0 +0xAD82 0xC171 # 0 +0xAD83 0xC172 # 0 +0xAD84 0xC173 # 0 +0xAD85 0xC174 # 0 +0xAD86 0xC175 # 0 +0xAD87 0xC176 # 0 +0xAD88 0xC177 # 0 +0xAD89 0xC178 # 0 +0xAD8A 0xC179 # 0 +0xAD8B 0xC17A # 0 +0xAD8C 0xC17B # 0 +0xAD8D 0xC17C # 0 +0xAD8E 0xC17D # 0 +0xAD8F 0xC17E # 0 +0xAD90 0xC17F # 0 +0xAD91 0xC180 # 0 +0xAD93 0xC181 # 0 +0xAD94 0xC182 # 0 +0xAD95 0xC183 # 0 +0xAD96 0xC184 # 0 +0xAD97 0xC185 # 0 +0xAD98 0xC186 # 0 +0xAD99 0xC187 # 0 +0xAD9A 0xC188 # 0 +0xAD9B 0xC189 # 0 +0xAD9C 0xC18A # 0 +0xAD9D 0xC18B # 0 +0xADA1 0xC18C # 0 +0xADA2 0xC18D # 0 +0xADA3 0xC18E # 0 +0xADA4 0xC18F # 0 +0xADA5 0xC190 # 0 +0xADA6 0xC191 # 0 +0xADA7 0xC192 # 0 +0xADA8 0xC193 # 0 +0xADA9 0xC194 # 0 +0xADAA 0xC195 # 0 +0xADAB 0xC196 # 0 +0xADAC 0xC197 # 0 +0xADAD 0xC198 # 0 +0xADAE 0xC199 # 0 +0xADAF 0xC19A # 0 +0xADB0 0xC19B # 0 +0xADB1 0xC19C # 0 +0xADB3 0xC19D # 0 +0xADB4 0xC19E # 0 +0xADB5 0xC19F # 0 +0xADB6 0xC1A0 # 0 +0xADB7 0xC1A1 # 0 +0xADB8 0xC1A2 # 0 +0xADB9 0xC1A3 # 0 +0xADBA 0xC1A4 # 0 +0xADBB 0xC1A5 # 0 +0xADBC 0xC1A6 # 0 +0xADBD 0xC1A7 # 0 +0xADC1 0xC1A8 # 0 +0xADC2 0xC1A9 # 0 +0xADC3 0xC1AA # 0 +0xADC4 0xC1AB # 0 +0xADC5 0xC1AC # 0 +0xADC6 0xC1AD # 0 +0xADC7 0xC1AE # 0 +0xADC8 0xC1AF # 0 +0xADC9 0xC1B0 # 0 +0xADCA 0xC1B1 # 0 +0xADCB 0xC1B2 # 0 +0xADCC 0xC1B3 # 0 +0xADCD 0xC1B4 # 0 +0xADCE 0xC1B5 # 0 +0xADCF 0xC1B6 # 0 +0xADD0 0xC1B7 # 0 +0xADD1 0xC1B8 # 0 +0xADD3 0xC1B9 # 0 +0xADD4 0xC1BA # 0 +0xADD5 0xC1BB # 0 +0xADD6 0xC1BC # 0 +0xADD7 0xC1BD # 0 +0xADD8 0xC1BE # 0 +0xADD9 0xC1BF # 0 +0xADDA 0xC1C0 # 0 +0xADDB 0xC1C1 # 0 +0xADDC 0xC1C2 # 0 +0xADDD 0xC1C3 # 0 +0xADE1 0xC1C4 # 0 +0xADE2 0xC1C5 # 0 +0xADE3 0xC1C6 # 0 +0xADE4 0xC1C7 # 0 +0xADE5 0xC1C8 # 0 +0xADE6 0xC1C9 # 0 +0xADE7 0xC1CA # 0 +0xADE8 0xC1CB # 0 +0xADE9 0xC1CC # 0 +0xADEA 0xC1CD # 0 +0xADEB 0xC1CE # 0 +0xADEC 0xC1CF # 0 +0xADED 0xC1D0 # 0 +0xADEE 0xC1D1 # 0 +0xADEF 0xC1D2 # 0 +0xADF0 0xC1D3 # 0 +0xADF1 0xC1D4 # 0 +0xADF3 0xC1D5 # 0 +0xADF4 0xC1D6 # 0 +0xADF5 0xC1D7 # 0 +0xADF6 0xC1D8 # 0 +0xADF7 0xC1D9 # 0 +0xADF8 0xC1DA # 0 +0xADF9 0xC1DB # 0 +0xADFA 0xC1DC # 0 +0xADFB 0xC1DD # 0 +0xADFC 0xC1DE # 0 +0xADFD 0xC1DF # 0 +0xAE41 0xC1E0 # 0 +0xAE42 0xC1E1 # 0 +0xAE43 0xC1E2 # 0 +0xAE44 0xC1E3 # 0 +0xAE45 0xC1E4 # 0 +0xAE46 0xC1E5 # 0 +0xAE47 0xC1E6 # 0 +0xAE48 0xC1E7 # 0 +0xAE49 0xC1E8 # 0 +0xAE4A 0xC1E9 # 0 +0xAE4B 0xC1EA # 0 +0xAE4C 0xC1EB # 0 +0xAE4D 0xC1EC # 0 +0xAE4E 0xC1ED # 0 +0xAE4F 0xC1EE # 0 +0xAE50 0xC1EF # 0 +0xAE51 0xC1F0 # 0 +0xAE53 0xC1F1 # 0 +0xAE54 0xC1F2 # 0 +0xAE55 0xC1F3 # 0 +0xAE56 0xC1F4 # 0 +0xAE57 0xC1F5 # 0 +0xAE58 0xC1F6 # 0 +0xAE59 0xC1F7 # 0 +0xAE5A 0xC1F8 # 0 +0xAE5B 0xC1F9 # 0 +0xAE5C 0xC1FA # 0 +0xAE5D 0xC1FB # 0 +0xAE61 0xC1FC # 0 +0xAE62 0xC1FD # 0 +0xAE63 0xC1FE # 0 +0xAE64 0xC1FF # 0 +0xAE65 0xC200 # 0 +0xAE66 0xC201 # 0 +0xAE67 0xC202 # 0 +0xAE68 0xC203 # 0 +0xAE69 0xC204 # 0 +0xAE6A 0xC205 # 0 +0xAE6B 0xC206 # 0 +0xAE6C 0xC207 # 0 +0xAE6D 0xC208 # 0 +0xAE6E 0xC209 # 0 +0xAE6F 0xC20A # 0 +0xAE70 0xC20B # 0 +0xAE71 0xC20C # 0 +0xAE73 0xC20D # 0 +0xAE74 0xC20E # 0 +0xAE75 0xC20F # 0 +0xAE76 0xC210 # 0 +0xAE77 0xC211 # 0 +0xAE78 0xC212 # 0 +0xAE79 0xC213 # 0 +0xAE7A 0xC214 # 0 +0xAE7B 0xC215 # 0 +0xAE7C 0xC216 # 0 +0xAE7D 0xC217 # 0 +0xAE81 0xC218 # 0 +0xAE82 0xC219 # 0 +0xAE83 0xC21A # 0 +0xAE84 0xC21B # 0 +0xAE85 0xC21C # 0 +0xAE86 0xC21D # 0 +0xAE87 0xC21E # 0 +0xAE88 0xC21F # 0 +0xAE89 0xC220 # 0 +0xAE8A 0xC221 # 0 +0xAE8B 0xC222 # 0 +0xAE8C 0xC223 # 0 +0xAE8D 0xC224 # 0 +0xAE8E 0xC225 # 0 +0xAE8F 0xC226 # 0 +0xAE90 0xC227 # 0 +0xAE91 0xC228 # 0 +0xAE93 0xC229 # 0 +0xAE94 0xC22A # 0 +0xAE95 0xC22B # 0 +0xAE96 0xC22C # 0 +0xAE97 0xC22D # 0 +0xAE98 0xC22E # 0 +0xAE99 0xC22F # 0 +0xAE9A 0xC230 # 0 +0xAE9B 0xC231 # 0 +0xAE9C 0xC232 # 0 +0xAE9D 0xC233 # 0 +0xAEA1 0xC234 # 0 +0xAEA2 0xC235 # 0 +0xAEA3 0xC236 # 0 +0xAEA4 0xC237 # 0 +0xAEA5 0xC238 # 0 +0xAEA6 0xC239 # 0 +0xAEA7 0xC23A # 0 +0xAEA8 0xC23B # 0 +0xAEA9 0xC23C # 0 +0xAEAA 0xC23D # 0 +0xAEAB 0xC23E # 0 +0xAEAC 0xC23F # 0 +0xAEAD 0xC240 # 0 +0xAEAE 0xC241 # 0 +0xAEAF 0xC242 # 0 +0xAEB0 0xC243 # 0 +0xAEB1 0xC244 # 0 +0xAEB3 0xC245 # 0 +0xAEB4 0xC246 # 0 +0xAEB5 0xC247 # 0 +0xAEB6 0xC248 # 0 +0xAEB7 0xC249 # 0 +0xAEB8 0xC24A # 0 +0xAEB9 0xC24B # 0 +0xAEBA 0xC24C # 0 +0xAEBB 0xC24D # 0 +0xAEBC 0xC24E # 0 +0xAEBD 0xC24F # 0 +0xAEC1 0xC250 # 0 +0xAEC2 0xC251 # 0 +0xAEC3 0xC252 # 0 +0xAEC4 0xC253 # 0 +0xAEC5 0xC254 # 0 +0xAEC6 0xC255 # 0 +0xAEC7 0xC256 # 0 +0xAEC8 0xC257 # 0 +0xAEC9 0xC258 # 0 +0xAECA 0xC259 # 0 +0xAECB 0xC25A # 0 +0xAECC 0xC25B # 0 +0xAECD 0xC25C # 0 +0xAECE 0xC25D # 0 +0xAECF 0xC25E # 0 +0xAED0 0xC25F # 0 +0xAED1 0xC260 # 0 +0xAED3 0xC261 # 0 +0xAED4 0xC262 # 0 +0xAED5 0xC263 # 0 +0xAED6 0xC264 # 0 +0xAED7 0xC265 # 0 +0xAED8 0xC266 # 0 +0xAED9 0xC267 # 0 +0xAEDA 0xC268 # 0 +0xAEDB 0xC269 # 0 +0xAEDC 0xC26A # 0 +0xAEDD 0xC26B # 0 +0xAEE1 0xC26C # 0 +0xAEE2 0xC26D # 0 +0xAEE3 0xC26E # 0 +0xAEE4 0xC26F # 0 +0xAEE5 0xC270 # 0 +0xAEE6 0xC271 # 0 +0xAEE7 0xC272 # 0 +0xAEE8 0xC273 # 0 +0xAEE9 0xC274 # 0 +0xAEEA 0xC275 # 0 +0xAEEB 0xC276 # 0 +0xAEEC 0xC277 # 0 +0xAEED 0xC278 # 0 +0xAEEE 0xC279 # 0 +0xAEEF 0xC27A # 0 +0xAEF0 0xC27B # 0 +0xAEF1 0xC27C # 0 +0xAEF3 0xC27D # 0 +0xAEF4 0xC27E # 0 +0xAEF5 0xC27F # 0 +0xAEF6 0xC280 # 0 +0xAEF7 0xC281 # 0 +0xAEF8 0xC282 # 0 +0xAEF9 0xC283 # 0 +0xAEFA 0xC284 # 0 +0xAEFB 0xC285 # 0 +0xAEFC 0xC286 # 0 +0xAEFD 0xC287 # 0 +0xAF41 0xC288 # 0 +0xAF42 0xC289 # 0 +0xAF43 0xC28A # 0 +0xAF44 0xC28B # 0 +0xAF45 0xC28C # 0 +0xAF46 0xC28D # 0 +0xAF47 0xC28E # 0 +0xAF48 0xC28F # 0 +0xAF49 0xC290 # 0 +0xAF4A 0xC291 # 0 +0xAF4B 0xC292 # 0 +0xAF4C 0xC293 # 0 +0xAF4D 0xC294 # 0 +0xAF4E 0xC295 # 0 +0xAF4F 0xC296 # 0 +0xAF50 0xC297 # 0 +0xAF51 0xC298 # 0 +0xAF53 0xC299 # 0 +0xAF54 0xC29A # 0 +0xAF55 0xC29B # 0 +0xAF56 0xC29C # 0 +0xAF57 0xC29D # 0 +0xAF58 0xC29E # 0 +0xAF59 0xC29F # 0 +0xAF5A 0xC2A0 # 0 +0xAF5B 0xC2A1 # 0 +0xAF5C 0xC2A2 # 0 +0xAF5D 0xC2A3 # 0 +0xAF61 0xC2A4 # 0 +0xAF62 0xC2A5 # 0 +0xAF63 0xC2A6 # 0 +0xAF64 0xC2A7 # 0 +0xAF65 0xC2A8 # 0 +0xAF66 0xC2A9 # 0 +0xAF67 0xC2AA # 0 +0xAF68 0xC2AB # 0 +0xAF69 0xC2AC # 0 +0xAF6A 0xC2AD # 0 +0xAF6B 0xC2AE # 0 +0xAF6C 0xC2AF # 0 +0xAF6D 0xC2B0 # 0 +0xAF6E 0xC2B1 # 0 +0xAF6F 0xC2B2 # 0 +0xAF70 0xC2B3 # 0 +0xAF71 0xC2B4 # 0 +0xAF73 0xC2B5 # 0 +0xAF74 0xC2B6 # 0 +0xAF75 0xC2B7 # 0 +0xAF76 0xC2B8 # 0 +0xAF77 0xC2B9 # 0 +0xAF78 0xC2BA # 0 +0xAF79 0xC2BB # 0 +0xAF7A 0xC2BC # 0 +0xAF7B 0xC2BD # 0 +0xAF7C 0xC2BE # 0 +0xAF7D 0xC2BF # 0 +0xAF81 0xC2C0 # 0 +0xAF82 0xC2C1 # 0 +0xAF83 0xC2C2 # 0 +0xAF84 0xC2C3 # 0 +0xAF85 0xC2C4 # 0 +0xAF86 0xC2C5 # 0 +0xAF87 0xC2C6 # 0 +0xAF88 0xC2C7 # 0 +0xAF89 0xC2C8 # 0 +0xAF8A 0xC2C9 # 0 +0xAF8B 0xC2CA # 0 +0xAF8C 0xC2CB # 0 +0xAF8D 0xC2CC # 0 +0xAF8E 0xC2CD # 0 +0xAF8F 0xC2CE # 0 +0xAF90 0xC2CF # 0 +0xAF91 0xC2D0 # 0 +0xAF93 0xC2D1 # 0 +0xAF94 0xC2D2 # 0 +0xAF95 0xC2D3 # 0 +0xAF96 0xC2D4 # 0 +0xAF97 0xC2D5 # 0 +0xAF98 0xC2D6 # 0 +0xAF99 0xC2D7 # 0 +0xAF9A 0xC2D8 # 0 +0xAF9B 0xC2D9 # 0 +0xAF9C 0xC2DA # 0 +0xAF9D 0xC2DB # 0 +0xAFA1 0xC2DC # 0 +0xAFA2 0xC2DD # 0 +0xAFA3 0xC2DE # 0 +0xAFA4 0xC2DF # 0 +0xAFA5 0xC2E0 # 0 +0xAFA6 0xC2E1 # 0 +0xAFA7 0xC2E2 # 0 +0xAFA8 0xC2E3 # 0 +0xAFA9 0xC2E4 # 0 +0xAFAA 0xC2E5 # 0 +0xAFAB 0xC2E6 # 0 +0xAFAC 0xC2E7 # 0 +0xAFAD 0xC2E8 # 0 +0xAFAE 0xC2E9 # 0 +0xAFAF 0xC2EA # 0 +0xAFB0 0xC2EB # 0 +0xAFB1 0xC2EC # 0 +0xAFB3 0xC2ED # 0 +0xAFB4 0xC2EE # 0 +0xAFB5 0xC2EF # 0 +0xAFB6 0xC2F0 # 0 +0xAFB7 0xC2F1 # 0 +0xAFB8 0xC2F2 # 0 +0xAFB9 0xC2F3 # 0 +0xAFBA 0xC2F4 # 0 +0xAFBB 0xC2F5 # 0 +0xAFBC 0xC2F6 # 0 +0xAFBD 0xC2F7 # 0 +0xB041 0x110A # 0 +0xB061 0xC2F8 # 0 +0xB062 0xC2F9 # 0 +0xB063 0xC2FA # 0 +0xB064 0xC2FB # 0 +0xB065 0xC2FC # 0 +0xB066 0xC2FD # 0 +0xB067 0xC2FE # 0 +0xB068 0xC2FF # 0 +0xB069 0xC300 # 0 +0xB06A 0xC301 # 0 +0xB06B 0xC302 # 0 +0xB06C 0xC303 # 0 +0xB06D 0xC304 # 0 +0xB06E 0xC305 # 0 +0xB06F 0xC306 # 0 +0xB070 0xC307 # 0 +0xB071 0xC308 # 0 +0xB073 0xC309 # 0 +0xB074 0xC30A # 0 +0xB075 0xC30B # 0 +0xB076 0xC30C # 0 +0xB077 0xC30D # 0 +0xB078 0xC30E # 0 +0xB079 0xC30F # 0 +0xB07A 0xC310 # 0 +0xB07B 0xC311 # 0 +0xB07C 0xC312 # 0 +0xB07D 0xC313 # 0 +0xB081 0xC314 # 0 +0xB082 0xC315 # 0 +0xB083 0xC316 # 0 +0xB084 0xC317 # 0 +0xB085 0xC318 # 0 +0xB086 0xC319 # 0 +0xB087 0xC31A # 0 +0xB088 0xC31B # 0 +0xB089 0xC31C # 0 +0xB08A 0xC31D # 0 +0xB08B 0xC31E # 0 +0xB08C 0xC31F # 0 +0xB08D 0xC320 # 0 +0xB08E 0xC321 # 0 +0xB08F 0xC322 # 0 +0xB090 0xC323 # 0 +0xB091 0xC324 # 0 +0xB093 0xC325 # 0 +0xB094 0xC326 # 0 +0xB095 0xC327 # 0 +0xB096 0xC328 # 0 +0xB097 0xC329 # 0 +0xB098 0xC32A # 0 +0xB099 0xC32B # 0 +0xB09A 0xC32C # 0 +0xB09B 0xC32D # 0 +0xB09C 0xC32E # 0 +0xB09D 0xC32F # 0 +0xB0A1 0xC330 # 0 +0xB0A2 0xC331 # 0 +0xB0A3 0xC332 # 0 +0xB0A4 0xC333 # 0 +0xB0A5 0xC334 # 0 +0xB0A6 0xC335 # 0 +0xB0A7 0xC336 # 0 +0xB0A8 0xC337 # 0 +0xB0A9 0xC338 # 0 +0xB0AA 0xC339 # 0 +0xB0AB 0xC33A # 0 +0xB0AC 0xC33B # 0 +0xB0AD 0xC33C # 0 +0xB0AE 0xC33D # 0 +0xB0AF 0xC33E # 0 +0xB0B0 0xC33F # 0 +0xB0B1 0xC340 # 0 +0xB0B3 0xC341 # 0 +0xB0B4 0xC342 # 0 +0xB0B5 0xC343 # 0 +0xB0B6 0xC344 # 0 +0xB0B7 0xC345 # 0 +0xB0B8 0xC346 # 0 +0xB0B9 0xC347 # 0 +0xB0BA 0xC348 # 0 +0xB0BB 0xC349 # 0 +0xB0BC 0xC34A # 0 +0xB0BD 0xC34B # 0 +0xB0C1 0xC34C # 0 +0xB0C2 0xC34D # 0 +0xB0C3 0xC34E # 0 +0xB0C4 0xC34F # 0 +0xB0C5 0xC350 # 0 +0xB0C6 0xC351 # 0 +0xB0C7 0xC352 # 0 +0xB0C8 0xC353 # 0 +0xB0C9 0xC354 # 0 +0xB0CA 0xC355 # 0 +0xB0CB 0xC356 # 0 +0xB0CC 0xC357 # 0 +0xB0CD 0xC358 # 0 +0xB0CE 0xC359 # 0 +0xB0CF 0xC35A # 0 +0xB0D0 0xC35B # 0 +0xB0D1 0xC35C # 0 +0xB0D3 0xC35D # 0 +0xB0D4 0xC35E # 0 +0xB0D5 0xC35F # 0 +0xB0D6 0xC360 # 0 +0xB0D7 0xC361 # 0 +0xB0D8 0xC362 # 0 +0xB0D9 0xC363 # 0 +0xB0DA 0xC364 # 0 +0xB0DB 0xC365 # 0 +0xB0DC 0xC366 # 0 +0xB0DD 0xC367 # 0 +0xB0E1 0xC368 # 0 +0xB0E2 0xC369 # 0 +0xB0E3 0xC36A # 0 +0xB0E4 0xC36B # 0 +0xB0E5 0xC36C # 0 +0xB0E6 0xC36D # 0 +0xB0E7 0xC36E # 0 +0xB0E8 0xC36F # 0 +0xB0E9 0xC370 # 0 +0xB0EA 0xC371 # 0 +0xB0EB 0xC372 # 0 +0xB0EC 0xC373 # 0 +0xB0ED 0xC374 # 0 +0xB0EE 0xC375 # 0 +0xB0EF 0xC376 # 0 +0xB0F0 0xC377 # 0 +0xB0F1 0xC378 # 0 +0xB0F3 0xC379 # 0 +0xB0F4 0xC37A # 0 +0xB0F5 0xC37B # 0 +0xB0F6 0xC37C # 0 +0xB0F7 0xC37D # 0 +0xB0F8 0xC37E # 0 +0xB0F9 0xC37F # 0 +0xB0FA 0xC380 # 0 +0xB0FB 0xC381 # 0 +0xB0FC 0xC382 # 0 +0xB0FD 0xC383 # 0 +0xB141 0xC384 # 0 +0xB142 0xC385 # 0 +0xB143 0xC386 # 0 +0xB144 0xC387 # 0 +0xB145 0xC388 # 0 +0xB146 0xC389 # 0 +0xB147 0xC38A # 0 +0xB148 0xC38B # 0 +0xB149 0xC38C # 0 +0xB14A 0xC38D # 0 +0xB14B 0xC38E # 0 +0xB14C 0xC38F # 0 +0xB14D 0xC390 # 0 +0xB14E 0xC391 # 0 +0xB14F 0xC392 # 0 +0xB150 0xC393 # 0 +0xB151 0xC394 # 0 +0xB153 0xC395 # 0 +0xB154 0xC396 # 0 +0xB155 0xC397 # 0 +0xB156 0xC398 # 0 +0xB157 0xC399 # 0 +0xB158 0xC39A # 0 +0xB159 0xC39B # 0 +0xB15A 0xC39C # 0 +0xB15B 0xC39D # 0 +0xB15C 0xC39E # 0 +0xB15D 0xC39F # 0 +0xB161 0xC3A0 # 0 +0xB162 0xC3A1 # 0 +0xB163 0xC3A2 # 0 +0xB164 0xC3A3 # 0 +0xB165 0xC3A4 # 0 +0xB166 0xC3A5 # 0 +0xB167 0xC3A6 # 0 +0xB168 0xC3A7 # 0 +0xB169 0xC3A8 # 0 +0xB16A 0xC3A9 # 0 +0xB16B 0xC3AA # 0 +0xB16C 0xC3AB # 0 +0xB16D 0xC3AC # 0 +0xB16E 0xC3AD # 0 +0xB16F 0xC3AE # 0 +0xB170 0xC3AF # 0 +0xB171 0xC3B0 # 0 +0xB173 0xC3B1 # 0 +0xB174 0xC3B2 # 0 +0xB175 0xC3B3 # 0 +0xB176 0xC3B4 # 0 +0xB177 0xC3B5 # 0 +0xB178 0xC3B6 # 0 +0xB179 0xC3B7 # 0 +0xB17A 0xC3B8 # 0 +0xB17B 0xC3B9 # 0 +0xB17C 0xC3BA # 0 +0xB17D 0xC3BB # 0 +0xB181 0xC3BC # 0 +0xB182 0xC3BD # 0 +0xB183 0xC3BE # 0 +0xB184 0xC3BF # 0 +0xB185 0xC3C0 # 0 +0xB186 0xC3C1 # 0 +0xB187 0xC3C2 # 0 +0xB188 0xC3C3 # 0 +0xB189 0xC3C4 # 0 +0xB18A 0xC3C5 # 0 +0xB18B 0xC3C6 # 0 +0xB18C 0xC3C7 # 0 +0xB18D 0xC3C8 # 0 +0xB18E 0xC3C9 # 0 +0xB18F 0xC3CA # 0 +0xB190 0xC3CB # 0 +0xB191 0xC3CC # 0 +0xB193 0xC3CD # 0 +0xB194 0xC3CE # 0 +0xB195 0xC3CF # 0 +0xB196 0xC3D0 # 0 +0xB197 0xC3D1 # 0 +0xB198 0xC3D2 # 0 +0xB199 0xC3D3 # 0 +0xB19A 0xC3D4 # 0 +0xB19B 0xC3D5 # 0 +0xB19C 0xC3D6 # 0 +0xB19D 0xC3D7 # 0 +0xB1A1 0xC3D8 # 0 +0xB1A2 0xC3D9 # 0 +0xB1A3 0xC3DA # 0 +0xB1A4 0xC3DB # 0 +0xB1A5 0xC3DC # 0 +0xB1A6 0xC3DD # 0 +0xB1A7 0xC3DE # 0 +0xB1A8 0xC3DF # 0 +0xB1A9 0xC3E0 # 0 +0xB1AA 0xC3E1 # 0 +0xB1AB 0xC3E2 # 0 +0xB1AC 0xC3E3 # 0 +0xB1AD 0xC3E4 # 0 +0xB1AE 0xC3E5 # 0 +0xB1AF 0xC3E6 # 0 +0xB1B0 0xC3E7 # 0 +0xB1B1 0xC3E8 # 0 +0xB1B3 0xC3E9 # 0 +0xB1B4 0xC3EA # 0 +0xB1B5 0xC3EB # 0 +0xB1B6 0xC3EC # 0 +0xB1B7 0xC3ED # 0 +0xB1B8 0xC3EE # 0 +0xB1B9 0xC3EF # 0 +0xB1BA 0xC3F0 # 0 +0xB1BB 0xC3F1 # 0 +0xB1BC 0xC3F2 # 0 +0xB1BD 0xC3F3 # 0 +0xB1C1 0xC3F4 # 0 +0xB1C2 0xC3F5 # 0 +0xB1C3 0xC3F6 # 0 +0xB1C4 0xC3F7 # 0 +0xB1C5 0xC3F8 # 0 +0xB1C6 0xC3F9 # 0 +0xB1C7 0xC3FA # 0 +0xB1C8 0xC3FB # 0 +0xB1C9 0xC3FC # 0 +0xB1CA 0xC3FD # 0 +0xB1CB 0xC3FE # 0 +0xB1CC 0xC3FF # 0 +0xB1CD 0xC400 # 0 +0xB1CE 0xC401 # 0 +0xB1CF 0xC402 # 0 +0xB1D0 0xC403 # 0 +0xB1D1 0xC404 # 0 +0xB1D3 0xC405 # 0 +0xB1D4 0xC406 # 0 +0xB1D5 0xC407 # 0 +0xB1D6 0xC408 # 0 +0xB1D7 0xC409 # 0 +0xB1D8 0xC40A # 0 +0xB1D9 0xC40B # 0 +0xB1DA 0xC40C # 0 +0xB1DB 0xC40D # 0 +0xB1DC 0xC40E # 0 +0xB1DD 0xC40F # 0 +0xB1E1 0xC410 # 0 +0xB1E2 0xC411 # 0 +0xB1E3 0xC412 # 0 +0xB1E4 0xC413 # 0 +0xB1E5 0xC414 # 0 +0xB1E6 0xC415 # 0 +0xB1E7 0xC416 # 0 +0xB1E8 0xC417 # 0 +0xB1E9 0xC418 # 0 +0xB1EA 0xC419 # 0 +0xB1EB 0xC41A # 0 +0xB1EC 0xC41B # 0 +0xB1ED 0xC41C # 0 +0xB1EE 0xC41D # 0 +0xB1EF 0xC41E # 0 +0xB1F0 0xC41F # 0 +0xB1F1 0xC420 # 0 +0xB1F3 0xC421 # 0 +0xB1F4 0xC422 # 0 +0xB1F5 0xC423 # 0 +0xB1F6 0xC424 # 0 +0xB1F7 0xC425 # 0 +0xB1F8 0xC426 # 0 +0xB1F9 0xC427 # 0 +0xB1FA 0xC428 # 0 +0xB1FB 0xC429 # 0 +0xB1FC 0xC42A # 0 +0xB1FD 0xC42B # 0 +0xB241 0xC42C # 0 +0xB242 0xC42D # 0 +0xB243 0xC42E # 0 +0xB244 0xC42F # 0 +0xB245 0xC430 # 0 +0xB246 0xC431 # 0 +0xB247 0xC432 # 0 +0xB248 0xC433 # 0 +0xB249 0xC434 # 0 +0xB24A 0xC435 # 0 +0xB24B 0xC436 # 0 +0xB24C 0xC437 # 0 +0xB24D 0xC438 # 0 +0xB24E 0xC439 # 0 +0xB24F 0xC43A # 0 +0xB250 0xC43B # 0 +0xB251 0xC43C # 0 +0xB253 0xC43D # 0 +0xB254 0xC43E # 0 +0xB255 0xC43F # 0 +0xB256 0xC440 # 0 +0xB257 0xC441 # 0 +0xB258 0xC442 # 0 +0xB259 0xC443 # 0 +0xB25A 0xC444 # 0 +0xB25B 0xC445 # 0 +0xB25C 0xC446 # 0 +0xB25D 0xC447 # 0 +0xB261 0xC448 # 0 +0xB262 0xC449 # 0 +0xB263 0xC44A # 0 +0xB264 0xC44B # 0 +0xB265 0xC44C # 0 +0xB266 0xC44D # 0 +0xB267 0xC44E # 0 +0xB268 0xC44F # 0 +0xB269 0xC450 # 0 +0xB26A 0xC451 # 0 +0xB26B 0xC452 # 0 +0xB26C 0xC453 # 0 +0xB26D 0xC454 # 0 +0xB26E 0xC455 # 0 +0xB26F 0xC456 # 0 +0xB270 0xC457 # 0 +0xB271 0xC458 # 0 +0xB273 0xC459 # 0 +0xB274 0xC45A # 0 +0xB275 0xC45B # 0 +0xB276 0xC45C # 0 +0xB277 0xC45D # 0 +0xB278 0xC45E # 0 +0xB279 0xC45F # 0 +0xB27A 0xC460 # 0 +0xB27B 0xC461 # 0 +0xB27C 0xC462 # 0 +0xB27D 0xC463 # 0 +0xB281 0xC464 # 0 +0xB282 0xC465 # 0 +0xB283 0xC466 # 0 +0xB284 0xC467 # 0 +0xB285 0xC468 # 0 +0xB286 0xC469 # 0 +0xB287 0xC46A # 0 +0xB288 0xC46B # 0 +0xB289 0xC46C # 0 +0xB28A 0xC46D # 0 +0xB28B 0xC46E # 0 +0xB28C 0xC46F # 0 +0xB28D 0xC470 # 0 +0xB28E 0xC471 # 0 +0xB28F 0xC472 # 0 +0xB290 0xC473 # 0 +0xB291 0xC474 # 0 +0xB293 0xC475 # 0 +0xB294 0xC476 # 0 +0xB295 0xC477 # 0 +0xB296 0xC478 # 0 +0xB297 0xC479 # 0 +0xB298 0xC47A # 0 +0xB299 0xC47B # 0 +0xB29A 0xC47C # 0 +0xB29B 0xC47D # 0 +0xB29C 0xC47E # 0 +0xB29D 0xC47F # 0 +0xB2A1 0xC480 # 0 +0xB2A2 0xC481 # 0 +0xB2A3 0xC482 # 0 +0xB2A4 0xC483 # 0 +0xB2A5 0xC484 # 0 +0xB2A6 0xC485 # 0 +0xB2A7 0xC486 # 0 +0xB2A8 0xC487 # 0 +0xB2A9 0xC488 # 0 +0xB2AA 0xC489 # 0 +0xB2AB 0xC48A # 0 +0xB2AC 0xC48B # 0 +0xB2AD 0xC48C # 0 +0xB2AE 0xC48D # 0 +0xB2AF 0xC48E # 0 +0xB2B0 0xC48F # 0 +0xB2B1 0xC490 # 0 +0xB2B3 0xC491 # 0 +0xB2B4 0xC492 # 0 +0xB2B5 0xC493 # 0 +0xB2B6 0xC494 # 0 +0xB2B7 0xC495 # 0 +0xB2B8 0xC496 # 0 +0xB2B9 0xC497 # 0 +0xB2BA 0xC498 # 0 +0xB2BB 0xC499 # 0 +0xB2BC 0xC49A # 0 +0xB2BD 0xC49B # 0 +0xB2C1 0xC49C # 0 +0xB2C2 0xC49D # 0 +0xB2C3 0xC49E # 0 +0xB2C4 0xC49F # 0 +0xB2C5 0xC4A0 # 0 +0xB2C6 0xC4A1 # 0 +0xB2C7 0xC4A2 # 0 +0xB2C8 0xC4A3 # 0 +0xB2C9 0xC4A4 # 0 +0xB2CA 0xC4A5 # 0 +0xB2CB 0xC4A6 # 0 +0xB2CC 0xC4A7 # 0 +0xB2CD 0xC4A8 # 0 +0xB2CE 0xC4A9 # 0 +0xB2CF 0xC4AA # 0 +0xB2D0 0xC4AB # 0 +0xB2D1 0xC4AC # 0 +0xB2D3 0xC4AD # 0 +0xB2D4 0xC4AE # 0 +0xB2D5 0xC4AF # 0 +0xB2D6 0xC4B0 # 0 +0xB2D7 0xC4B1 # 0 +0xB2D8 0xC4B2 # 0 +0xB2D9 0xC4B3 # 0 +0xB2DA 0xC4B4 # 0 +0xB2DB 0xC4B5 # 0 +0xB2DC 0xC4B6 # 0 +0xB2DD 0xC4B7 # 0 +0xB2E1 0xC4B8 # 0 +0xB2E2 0xC4B9 # 0 +0xB2E3 0xC4BA # 0 +0xB2E4 0xC4BB # 0 +0xB2E5 0xC4BC # 0 +0xB2E6 0xC4BD # 0 +0xB2E7 0xC4BE # 0 +0xB2E8 0xC4BF # 0 +0xB2E9 0xC4C0 # 0 +0xB2EA 0xC4C1 # 0 +0xB2EB 0xC4C2 # 0 +0xB2EC 0xC4C3 # 0 +0xB2ED 0xC4C4 # 0 +0xB2EE 0xC4C5 # 0 +0xB2EF 0xC4C6 # 0 +0xB2F0 0xC4C7 # 0 +0xB2F1 0xC4C8 # 0 +0xB2F3 0xC4C9 # 0 +0xB2F4 0xC4CA # 0 +0xB2F5 0xC4CB # 0 +0xB2F6 0xC4CC # 0 +0xB2F7 0xC4CD # 0 +0xB2F8 0xC4CE # 0 +0xB2F9 0xC4CF # 0 +0xB2FA 0xC4D0 # 0 +0xB2FB 0xC4D1 # 0 +0xB2FC 0xC4D2 # 0 +0xB2FD 0xC4D3 # 0 +0xB341 0xC4D4 # 0 +0xB342 0xC4D5 # 0 +0xB343 0xC4D6 # 0 +0xB344 0xC4D7 # 0 +0xB345 0xC4D8 # 0 +0xB346 0xC4D9 # 0 +0xB347 0xC4DA # 0 +0xB348 0xC4DB # 0 +0xB349 0xC4DC # 0 +0xB34A 0xC4DD # 0 +0xB34B 0xC4DE # 0 +0xB34C 0xC4DF # 0 +0xB34D 0xC4E0 # 0 +0xB34E 0xC4E1 # 0 +0xB34F 0xC4E2 # 0 +0xB350 0xC4E3 # 0 +0xB351 0xC4E4 # 0 +0xB353 0xC4E5 # 0 +0xB354 0xC4E6 # 0 +0xB355 0xC4E7 # 0 +0xB356 0xC4E8 # 0 +0xB357 0xC4E9 # 0 +0xB358 0xC4EA # 0 +0xB359 0xC4EB # 0 +0xB35A 0xC4EC # 0 +0xB35B 0xC4ED # 0 +0xB35C 0xC4EE # 0 +0xB35D 0xC4EF # 0 +0xB361 0xC4F0 # 0 +0xB362 0xC4F1 # 0 +0xB363 0xC4F2 # 0 +0xB364 0xC4F3 # 0 +0xB365 0xC4F4 # 0 +0xB366 0xC4F5 # 0 +0xB367 0xC4F6 # 0 +0xB368 0xC4F7 # 0 +0xB369 0xC4F8 # 0 +0xB36A 0xC4F9 # 0 +0xB36B 0xC4FA # 0 +0xB36C 0xC4FB # 0 +0xB36D 0xC4FC # 0 +0xB36E 0xC4FD # 0 +0xB36F 0xC4FE # 0 +0xB370 0xC4FF # 0 +0xB371 0xC500 # 0 +0xB373 0xC501 # 0 +0xB374 0xC502 # 0 +0xB375 0xC503 # 0 +0xB376 0xC504 # 0 +0xB377 0xC505 # 0 +0xB378 0xC506 # 0 +0xB379 0xC507 # 0 +0xB37A 0xC508 # 0 +0xB37B 0xC509 # 0 +0xB37C 0xC50A # 0 +0xB37D 0xC50B # 0 +0xB381 0xC50C # 0 +0xB382 0xC50D # 0 +0xB383 0xC50E # 0 +0xB384 0xC50F # 0 +0xB385 0xC510 # 0 +0xB386 0xC511 # 0 +0xB387 0xC512 # 0 +0xB388 0xC513 # 0 +0xB389 0xC514 # 0 +0xB38A 0xC515 # 0 +0xB38B 0xC516 # 0 +0xB38C 0xC517 # 0 +0xB38D 0xC518 # 0 +0xB38E 0xC519 # 0 +0xB38F 0xC51A # 0 +0xB390 0xC51B # 0 +0xB391 0xC51C # 0 +0xB393 0xC51D # 0 +0xB394 0xC51E # 0 +0xB395 0xC51F # 0 +0xB396 0xC520 # 0 +0xB397 0xC521 # 0 +0xB398 0xC522 # 0 +0xB399 0xC523 # 0 +0xB39A 0xC524 # 0 +0xB39B 0xC525 # 0 +0xB39C 0xC526 # 0 +0xB39D 0xC527 # 0 +0xB3A1 0xC528 # 0 +0xB3A2 0xC529 # 0 +0xB3A3 0xC52A # 0 +0xB3A4 0xC52B # 0 +0xB3A5 0xC52C # 0 +0xB3A6 0xC52D # 0 +0xB3A7 0xC52E # 0 +0xB3A8 0xC52F # 0 +0xB3A9 0xC530 # 0 +0xB3AA 0xC531 # 0 +0xB3AB 0xC532 # 0 +0xB3AC 0xC533 # 0 +0xB3AD 0xC534 # 0 +0xB3AE 0xC535 # 0 +0xB3AF 0xC536 # 0 +0xB3B0 0xC537 # 0 +0xB3B1 0xC538 # 0 +0xB3B3 0xC539 # 0 +0xB3B4 0xC53A # 0 +0xB3B5 0xC53B # 0 +0xB3B6 0xC53C # 0 +0xB3B7 0xC53D # 0 +0xB3B8 0xC53E # 0 +0xB3B9 0xC53F # 0 +0xB3BA 0xC540 # 0 +0xB3BB 0xC541 # 0 +0xB3BC 0xC542 # 0 +0xB3BD 0xC543 # 0 +0xB441 0x110B # 0 +0xB461 0xC544 # 0 +0xB462 0xC545 # 0 +0xB463 0xC546 # 0 +0xB464 0xC547 # 0 +0xB465 0xC548 # 0 +0xB466 0xC549 # 0 +0xB467 0xC54A # 0 +0xB468 0xC54B # 0 +0xB469 0xC54C # 0 +0xB46A 0xC54D # 0 +0xB46B 0xC54E # 0 +0xB46C 0xC54F # 0 +0xB46D 0xC550 # 0 +0xB46E 0xC551 # 0 +0xB46F 0xC552 # 0 +0xB470 0xC553 # 0 +0xB471 0xC554 # 0 +0xB473 0xC555 # 0 +0xB474 0xC556 # 0 +0xB475 0xC557 # 0 +0xB476 0xC558 # 0 +0xB477 0xC559 # 0 +0xB478 0xC55A # 0 +0xB479 0xC55B # 0 +0xB47A 0xC55C # 0 +0xB47B 0xC55D # 0 +0xB47C 0xC55E # 0 +0xB47D 0xC55F # 0 +0xB481 0xC560 # 0 +0xB482 0xC561 # 0 +0xB483 0xC562 # 0 +0xB484 0xC563 # 0 +0xB485 0xC564 # 0 +0xB486 0xC565 # 0 +0xB487 0xC566 # 0 +0xB488 0xC567 # 0 +0xB489 0xC568 # 0 +0xB48A 0xC569 # 0 +0xB48B 0xC56A # 0 +0xB48C 0xC56B # 0 +0xB48D 0xC56C # 0 +0xB48E 0xC56D # 0 +0xB48F 0xC56E # 0 +0xB490 0xC56F # 0 +0xB491 0xC570 # 0 +0xB493 0xC571 # 0 +0xB494 0xC572 # 0 +0xB495 0xC573 # 0 +0xB496 0xC574 # 0 +0xB497 0xC575 # 0 +0xB498 0xC576 # 0 +0xB499 0xC577 # 0 +0xB49A 0xC578 # 0 +0xB49B 0xC579 # 0 +0xB49C 0xC57A # 0 +0xB49D 0xC57B # 0 +0xB4A1 0xC57C # 0 +0xB4A2 0xC57D # 0 +0xB4A3 0xC57E # 0 +0xB4A4 0xC57F # 0 +0xB4A5 0xC580 # 0 +0xB4A6 0xC581 # 0 +0xB4A7 0xC582 # 0 +0xB4A8 0xC583 # 0 +0xB4A9 0xC584 # 0 +0xB4AA 0xC585 # 0 +0xB4AB 0xC586 # 0 +0xB4AC 0xC587 # 0 +0xB4AD 0xC588 # 0 +0xB4AE 0xC589 # 0 +0xB4AF 0xC58A # 0 +0xB4B0 0xC58B # 0 +0xB4B1 0xC58C # 0 +0xB4B3 0xC58D # 0 +0xB4B4 0xC58E # 0 +0xB4B5 0xC58F # 0 +0xB4B6 0xC590 # 0 +0xB4B7 0xC591 # 0 +0xB4B8 0xC592 # 0 +0xB4B9 0xC593 # 0 +0xB4BA 0xC594 # 0 +0xB4BB 0xC595 # 0 +0xB4BC 0xC596 # 0 +0xB4BD 0xC597 # 0 +0xB4C1 0xC598 # 0 +0xB4C2 0xC599 # 0 +0xB4C3 0xC59A # 0 +0xB4C4 0xC59B # 0 +0xB4C5 0xC59C # 0 +0xB4C6 0xC59D # 0 +0xB4C7 0xC59E # 0 +0xB4C8 0xC59F # 0 +0xB4C9 0xC5A0 # 0 +0xB4CA 0xC5A1 # 0 +0xB4CB 0xC5A2 # 0 +0xB4CC 0xC5A3 # 0 +0xB4CD 0xC5A4 # 0 +0xB4CE 0xC5A5 # 0 +0xB4CF 0xC5A6 # 0 +0xB4D0 0xC5A7 # 0 +0xB4D1 0xC5A8 # 0 +0xB4D3 0xC5A9 # 0 +0xB4D4 0xC5AA # 0 +0xB4D5 0xC5AB # 0 +0xB4D6 0xC5AC # 0 +0xB4D7 0xC5AD # 0 +0xB4D8 0xC5AE # 0 +0xB4D9 0xC5AF # 0 +0xB4DA 0xC5B0 # 0 +0xB4DB 0xC5B1 # 0 +0xB4DC 0xC5B2 # 0 +0xB4DD 0xC5B3 # 0 +0xB4E1 0xC5B4 # 0 +0xB4E2 0xC5B5 # 0 +0xB4E3 0xC5B6 # 0 +0xB4E4 0xC5B7 # 0 +0xB4E5 0xC5B8 # 0 +0xB4E6 0xC5B9 # 0 +0xB4E7 0xC5BA # 0 +0xB4E8 0xC5BB # 0 +0xB4E9 0xC5BC # 0 +0xB4EA 0xC5BD # 0 +0xB4EB 0xC5BE # 0 +0xB4EC 0xC5BF # 0 +0xB4ED 0xC5C0 # 0 +0xB4EE 0xC5C1 # 0 +0xB4EF 0xC5C2 # 0 +0xB4F0 0xC5C3 # 0 +0xB4F1 0xC5C4 # 0 +0xB4F3 0xC5C5 # 0 +0xB4F4 0xC5C6 # 0 +0xB4F5 0xC5C7 # 0 +0xB4F6 0xC5C8 # 0 +0xB4F7 0xC5C9 # 0 +0xB4F8 0xC5CA # 0 +0xB4F9 0xC5CB # 0 +0xB4FA 0xC5CC # 0 +0xB4FB 0xC5CD # 0 +0xB4FC 0xC5CE # 0 +0xB4FD 0xC5CF # 0 +0xB541 0xC5D0 # 0 +0xB542 0xC5D1 # 0 +0xB543 0xC5D2 # 0 +0xB544 0xC5D3 # 0 +0xB545 0xC5D4 # 0 +0xB546 0xC5D5 # 0 +0xB547 0xC5D6 # 0 +0xB548 0xC5D7 # 0 +0xB549 0xC5D8 # 0 +0xB54A 0xC5D9 # 0 +0xB54B 0xC5DA # 0 +0xB54C 0xC5DB # 0 +0xB54D 0xC5DC # 0 +0xB54E 0xC5DD # 0 +0xB54F 0xC5DE # 0 +0xB550 0xC5DF # 0 +0xB551 0xC5E0 # 0 +0xB553 0xC5E1 # 0 +0xB554 0xC5E2 # 0 +0xB555 0xC5E3 # 0 +0xB556 0xC5E4 # 0 +0xB557 0xC5E5 # 0 +0xB558 0xC5E6 # 0 +0xB559 0xC5E7 # 0 +0xB55A 0xC5E8 # 0 +0xB55B 0xC5E9 # 0 +0xB55C 0xC5EA # 0 +0xB55D 0xC5EB # 0 +0xB561 0xC5EC # 0 +0xB562 0xC5ED # 0 +0xB563 0xC5EE # 0 +0xB564 0xC5EF # 0 +0xB565 0xC5F0 # 0 +0xB566 0xC5F1 # 0 +0xB567 0xC5F2 # 0 +0xB568 0xC5F3 # 0 +0xB569 0xC5F4 # 0 +0xB56A 0xC5F5 # 0 +0xB56B 0xC5F6 # 0 +0xB56C 0xC5F7 # 0 +0xB56D 0xC5F8 # 0 +0xB56E 0xC5F9 # 0 +0xB56F 0xC5FA # 0 +0xB570 0xC5FB # 0 +0xB571 0xC5FC # 0 +0xB573 0xC5FD # 0 +0xB574 0xC5FE # 0 +0xB575 0xC5FF # 0 +0xB576 0xC600 # 0 +0xB577 0xC601 # 0 +0xB578 0xC602 # 0 +0xB579 0xC603 # 0 +0xB57A 0xC604 # 0 +0xB57B 0xC605 # 0 +0xB57C 0xC606 # 0 +0xB57D 0xC607 # 0 +0xB581 0xC608 # 0 +0xB582 0xC609 # 0 +0xB583 0xC60A # 0 +0xB584 0xC60B # 0 +0xB585 0xC60C # 0 +0xB586 0xC60D # 0 +0xB587 0xC60E # 0 +0xB588 0xC60F # 0 +0xB589 0xC610 # 0 +0xB58A 0xC611 # 0 +0xB58B 0xC612 # 0 +0xB58C 0xC613 # 0 +0xB58D 0xC614 # 0 +0xB58E 0xC615 # 0 +0xB58F 0xC616 # 0 +0xB590 0xC617 # 0 +0xB591 0xC618 # 0 +0xB593 0xC619 # 0 +0xB594 0xC61A # 0 +0xB595 0xC61B # 0 +0xB596 0xC61C # 0 +0xB597 0xC61D # 0 +0xB598 0xC61E # 0 +0xB599 0xC61F # 0 +0xB59A 0xC620 # 0 +0xB59B 0xC621 # 0 +0xB59C 0xC622 # 0 +0xB59D 0xC623 # 0 +0xB5A1 0xC624 # 0 +0xB5A2 0xC625 # 0 +0xB5A3 0xC626 # 0 +0xB5A4 0xC627 # 0 +0xB5A5 0xC628 # 0 +0xB5A6 0xC629 # 0 +0xB5A7 0xC62A # 0 +0xB5A8 0xC62B # 0 +0xB5A9 0xC62C # 0 +0xB5AA 0xC62D # 0 +0xB5AB 0xC62E # 0 +0xB5AC 0xC62F # 0 +0xB5AD 0xC630 # 0 +0xB5AE 0xC631 # 0 +0xB5AF 0xC632 # 0 +0xB5B0 0xC633 # 0 +0xB5B1 0xC634 # 0 +0xB5B3 0xC635 # 0 +0xB5B4 0xC636 # 0 +0xB5B5 0xC637 # 0 +0xB5B6 0xC638 # 0 +0xB5B7 0xC639 # 0 +0xB5B8 0xC63A # 0 +0xB5B9 0xC63B # 0 +0xB5BA 0xC63C # 0 +0xB5BB 0xC63D # 0 +0xB5BC 0xC63E # 0 +0xB5BD 0xC63F # 0 +0xB5C1 0xC640 # 0 +0xB5C2 0xC641 # 0 +0xB5C3 0xC642 # 0 +0xB5C4 0xC643 # 0 +0xB5C5 0xC644 # 0 +0xB5C6 0xC645 # 0 +0xB5C7 0xC646 # 0 +0xB5C8 0xC647 # 0 +0xB5C9 0xC648 # 0 +0xB5CA 0xC649 # 0 +0xB5CB 0xC64A # 0 +0xB5CC 0xC64B # 0 +0xB5CD 0xC64C # 0 +0xB5CE 0xC64D # 0 +0xB5CF 0xC64E # 0 +0xB5D0 0xC64F # 0 +0xB5D1 0xC650 # 0 +0xB5D3 0xC651 # 0 +0xB5D4 0xC652 # 0 +0xB5D5 0xC653 # 0 +0xB5D6 0xC654 # 0 +0xB5D7 0xC655 # 0 +0xB5D8 0xC656 # 0 +0xB5D9 0xC657 # 0 +0xB5DA 0xC658 # 0 +0xB5DB 0xC659 # 0 +0xB5DC 0xC65A # 0 +0xB5DD 0xC65B # 0 +0xB5E1 0xC65C # 0 +0xB5E2 0xC65D # 0 +0xB5E3 0xC65E # 0 +0xB5E4 0xC65F # 0 +0xB5E5 0xC660 # 0 +0xB5E6 0xC661 # 0 +0xB5E7 0xC662 # 0 +0xB5E8 0xC663 # 0 +0xB5E9 0xC664 # 0 +0xB5EA 0xC665 # 0 +0xB5EB 0xC666 # 0 +0xB5EC 0xC667 # 0 +0xB5ED 0xC668 # 0 +0xB5EE 0xC669 # 0 +0xB5EF 0xC66A # 0 +0xB5F0 0xC66B # 0 +0xB5F1 0xC66C # 0 +0xB5F3 0xC66D # 0 +0xB5F4 0xC66E # 0 +0xB5F5 0xC66F # 0 +0xB5F6 0xC670 # 0 +0xB5F7 0xC671 # 0 +0xB5F8 0xC672 # 0 +0xB5F9 0xC673 # 0 +0xB5FA 0xC674 # 0 +0xB5FB 0xC675 # 0 +0xB5FC 0xC676 # 0 +0xB5FD 0xC677 # 0 +0xB641 0xC678 # 0 +0xB642 0xC679 # 0 +0xB643 0xC67A # 0 +0xB644 0xC67B # 0 +0xB645 0xC67C # 0 +0xB646 0xC67D # 0 +0xB647 0xC67E # 0 +0xB648 0xC67F # 0 +0xB649 0xC680 # 0 +0xB64A 0xC681 # 0 +0xB64B 0xC682 # 0 +0xB64C 0xC683 # 0 +0xB64D 0xC684 # 0 +0xB64E 0xC685 # 0 +0xB64F 0xC686 # 0 +0xB650 0xC687 # 0 +0xB651 0xC688 # 0 +0xB653 0xC689 # 0 +0xB654 0xC68A # 0 +0xB655 0xC68B # 0 +0xB656 0xC68C # 0 +0xB657 0xC68D # 0 +0xB658 0xC68E # 0 +0xB659 0xC68F # 0 +0xB65A 0xC690 # 0 +0xB65B 0xC691 # 0 +0xB65C 0xC692 # 0 +0xB65D 0xC693 # 0 +0xB661 0xC694 # 0 +0xB662 0xC695 # 0 +0xB663 0xC696 # 0 +0xB664 0xC697 # 0 +0xB665 0xC698 # 0 +0xB666 0xC699 # 0 +0xB667 0xC69A # 0 +0xB668 0xC69B # 0 +0xB669 0xC69C # 0 +0xB66A 0xC69D # 0 +0xB66B 0xC69E # 0 +0xB66C 0xC69F # 0 +0xB66D 0xC6A0 # 0 +0xB66E 0xC6A1 # 0 +0xB66F 0xC6A2 # 0 +0xB670 0xC6A3 # 0 +0xB671 0xC6A4 # 0 +0xB673 0xC6A5 # 0 +0xB674 0xC6A6 # 0 +0xB675 0xC6A7 # 0 +0xB676 0xC6A8 # 0 +0xB677 0xC6A9 # 0 +0xB678 0xC6AA # 0 +0xB679 0xC6AB # 0 +0xB67A 0xC6AC # 0 +0xB67B 0xC6AD # 0 +0xB67C 0xC6AE # 0 +0xB67D 0xC6AF # 0 +0xB681 0xC6B0 # 0 +0xB682 0xC6B1 # 0 +0xB683 0xC6B2 # 0 +0xB684 0xC6B3 # 0 +0xB685 0xC6B4 # 0 +0xB686 0xC6B5 # 0 +0xB687 0xC6B6 # 0 +0xB688 0xC6B7 # 0 +0xB689 0xC6B8 # 0 +0xB68A 0xC6B9 # 0 +0xB68B 0xC6BA # 0 +0xB68C 0xC6BB # 0 +0xB68D 0xC6BC # 0 +0xB68E 0xC6BD # 0 +0xB68F 0xC6BE # 0 +0xB690 0xC6BF # 0 +0xB691 0xC6C0 # 0 +0xB693 0xC6C1 # 0 +0xB694 0xC6C2 # 0 +0xB695 0xC6C3 # 0 +0xB696 0xC6C4 # 0 +0xB697 0xC6C5 # 0 +0xB698 0xC6C6 # 0 +0xB699 0xC6C7 # 0 +0xB69A 0xC6C8 # 0 +0xB69B 0xC6C9 # 0 +0xB69C 0xC6CA # 0 +0xB69D 0xC6CB # 0 +0xB6A1 0xC6CC # 0 +0xB6A2 0xC6CD # 0 +0xB6A3 0xC6CE # 0 +0xB6A4 0xC6CF # 0 +0xB6A5 0xC6D0 # 0 +0xB6A6 0xC6D1 # 0 +0xB6A7 0xC6D2 # 0 +0xB6A8 0xC6D3 # 0 +0xB6A9 0xC6D4 # 0 +0xB6AA 0xC6D5 # 0 +0xB6AB 0xC6D6 # 0 +0xB6AC 0xC6D7 # 0 +0xB6AD 0xC6D8 # 0 +0xB6AE 0xC6D9 # 0 +0xB6AF 0xC6DA # 0 +0xB6B0 0xC6DB # 0 +0xB6B1 0xC6DC # 0 +0xB6B3 0xC6DD # 0 +0xB6B4 0xC6DE # 0 +0xB6B5 0xC6DF # 0 +0xB6B6 0xC6E0 # 0 +0xB6B7 0xC6E1 # 0 +0xB6B8 0xC6E2 # 0 +0xB6B9 0xC6E3 # 0 +0xB6BA 0xC6E4 # 0 +0xB6BB 0xC6E5 # 0 +0xB6BC 0xC6E6 # 0 +0xB6BD 0xC6E7 # 0 +0xB6C1 0xC6E8 # 0 +0xB6C2 0xC6E9 # 0 +0xB6C3 0xC6EA # 0 +0xB6C4 0xC6EB # 0 +0xB6C5 0xC6EC # 0 +0xB6C6 0xC6ED # 0 +0xB6C7 0xC6EE # 0 +0xB6C8 0xC6EF # 0 +0xB6C9 0xC6F0 # 0 +0xB6CA 0xC6F1 # 0 +0xB6CB 0xC6F2 # 0 +0xB6CC 0xC6F3 # 0 +0xB6CD 0xC6F4 # 0 +0xB6CE 0xC6F5 # 0 +0xB6CF 0xC6F6 # 0 +0xB6D0 0xC6F7 # 0 +0xB6D1 0xC6F8 # 0 +0xB6D3 0xC6F9 # 0 +0xB6D4 0xC6FA # 0 +0xB6D5 0xC6FB # 0 +0xB6D6 0xC6FC # 0 +0xB6D7 0xC6FD # 0 +0xB6D8 0xC6FE # 0 +0xB6D9 0xC6FF # 0 +0xB6DA 0xC700 # 0 +0xB6DB 0xC701 # 0 +0xB6DC 0xC702 # 0 +0xB6DD 0xC703 # 0 +0xB6E1 0xC704 # 0 +0xB6E2 0xC705 # 0 +0xB6E3 0xC706 # 0 +0xB6E4 0xC707 # 0 +0xB6E5 0xC708 # 0 +0xB6E6 0xC709 # 0 +0xB6E7 0xC70A # 0 +0xB6E8 0xC70B # 0 +0xB6E9 0xC70C # 0 +0xB6EA 0xC70D # 0 +0xB6EB 0xC70E # 0 +0xB6EC 0xC70F # 0 +0xB6ED 0xC710 # 0 +0xB6EE 0xC711 # 0 +0xB6EF 0xC712 # 0 +0xB6F0 0xC713 # 0 +0xB6F1 0xC714 # 0 +0xB6F3 0xC715 # 0 +0xB6F4 0xC716 # 0 +0xB6F5 0xC717 # 0 +0xB6F6 0xC718 # 0 +0xB6F7 0xC719 # 0 +0xB6F8 0xC71A # 0 +0xB6F9 0xC71B # 0 +0xB6FA 0xC71C # 0 +0xB6FB 0xC71D # 0 +0xB6FC 0xC71E # 0 +0xB6FD 0xC71F # 0 +0xB741 0xC720 # 0 +0xB742 0xC721 # 0 +0xB743 0xC722 # 0 +0xB744 0xC723 # 0 +0xB745 0xC724 # 0 +0xB746 0xC725 # 0 +0xB747 0xC726 # 0 +0xB748 0xC727 # 0 +0xB749 0xC728 # 0 +0xB74A 0xC729 # 0 +0xB74B 0xC72A # 0 +0xB74C 0xC72B # 0 +0xB74D 0xC72C # 0 +0xB74E 0xC72D # 0 +0xB74F 0xC72E # 0 +0xB750 0xC72F # 0 +0xB751 0xC730 # 0 +0xB753 0xC731 # 0 +0xB754 0xC732 # 0 +0xB755 0xC733 # 0 +0xB756 0xC734 # 0 +0xB757 0xC735 # 0 +0xB758 0xC736 # 0 +0xB759 0xC737 # 0 +0xB75A 0xC738 # 0 +0xB75B 0xC739 # 0 +0xB75C 0xC73A # 0 +0xB75D 0xC73B # 0 +0xB761 0xC73C # 0 +0xB762 0xC73D # 0 +0xB763 0xC73E # 0 +0xB764 0xC73F # 0 +0xB765 0xC740 # 0 +0xB766 0xC741 # 0 +0xB767 0xC742 # 0 +0xB768 0xC743 # 0 +0xB769 0xC744 # 0 +0xB76A 0xC745 # 0 +0xB76B 0xC746 # 0 +0xB76C 0xC747 # 0 +0xB76D 0xC748 # 0 +0xB76E 0xC749 # 0 +0xB76F 0xC74A # 0 +0xB770 0xC74B # 0 +0xB771 0xC74C # 0 +0xB773 0xC74D # 0 +0xB774 0xC74E # 0 +0xB775 0xC74F # 0 +0xB776 0xC750 # 0 +0xB777 0xC751 # 0 +0xB778 0xC752 # 0 +0xB779 0xC753 # 0 +0xB77A 0xC754 # 0 +0xB77B 0xC755 # 0 +0xB77C 0xC756 # 0 +0xB77D 0xC757 # 0 +0xB781 0xC758 # 0 +0xB782 0xC759 # 0 +0xB783 0xC75A # 0 +0xB784 0xC75B # 0 +0xB785 0xC75C # 0 +0xB786 0xC75D # 0 +0xB787 0xC75E # 0 +0xB788 0xC75F # 0 +0xB789 0xC760 # 0 +0xB78A 0xC761 # 0 +0xB78B 0xC762 # 0 +0xB78C 0xC763 # 0 +0xB78D 0xC764 # 0 +0xB78E 0xC765 # 0 +0xB78F 0xC766 # 0 +0xB790 0xC767 # 0 +0xB791 0xC768 # 0 +0xB793 0xC769 # 0 +0xB794 0xC76A # 0 +0xB795 0xC76B # 0 +0xB796 0xC76C # 0 +0xB797 0xC76D # 0 +0xB798 0xC76E # 0 +0xB799 0xC76F # 0 +0xB79A 0xC770 # 0 +0xB79B 0xC771 # 0 +0xB79C 0xC772 # 0 +0xB79D 0xC773 # 0 +0xB7A1 0xC774 # 0 +0xB7A2 0xC775 # 0 +0xB7A3 0xC776 # 0 +0xB7A4 0xC777 # 0 +0xB7A5 0xC778 # 0 +0xB7A6 0xC779 # 0 +0xB7A7 0xC77A # 0 +0xB7A8 0xC77B # 0 +0xB7A9 0xC77C # 0 +0xB7AA 0xC77D # 0 +0xB7AB 0xC77E # 0 +0xB7AC 0xC77F # 0 +0xB7AD 0xC780 # 0 +0xB7AE 0xC781 # 0 +0xB7AF 0xC782 # 0 +0xB7B0 0xC783 # 0 +0xB7B1 0xC784 # 0 +0xB7B3 0xC785 # 0 +0xB7B4 0xC786 # 0 +0xB7B5 0xC787 # 0 +0xB7B6 0xC788 # 0 +0xB7B7 0xC789 # 0 +0xB7B8 0xC78A # 0 +0xB7B9 0xC78B # 0 +0xB7BA 0xC78C # 0 +0xB7BB 0xC78D # 0 +0xB7BC 0xC78E # 0 +0xB7BD 0xC78F # 0 +0xB841 0x110C # 0 +0xB861 0xC790 # 0 +0xB862 0xC791 # 0 +0xB863 0xC792 # 0 +0xB864 0xC793 # 0 +0xB865 0xC794 # 0 +0xB866 0xC795 # 0 +0xB867 0xC796 # 0 +0xB868 0xC797 # 0 +0xB869 0xC798 # 0 +0xB86A 0xC799 # 0 +0xB86B 0xC79A # 0 +0xB86C 0xC79B # 0 +0xB86D 0xC79C # 0 +0xB86E 0xC79D # 0 +0xB86F 0xC79E # 0 +0xB870 0xC79F # 0 +0xB871 0xC7A0 # 0 +0xB873 0xC7A1 # 0 +0xB874 0xC7A2 # 0 +0xB875 0xC7A3 # 0 +0xB876 0xC7A4 # 0 +0xB877 0xC7A5 # 0 +0xB878 0xC7A6 # 0 +0xB879 0xC7A7 # 0 +0xB87A 0xC7A8 # 0 +0xB87B 0xC7A9 # 0 +0xB87C 0xC7AA # 0 +0xB87D 0xC7AB # 0 +0xB881 0xC7AC # 0 +0xB882 0xC7AD # 0 +0xB883 0xC7AE # 0 +0xB884 0xC7AF # 0 +0xB885 0xC7B0 # 0 +0xB886 0xC7B1 # 0 +0xB887 0xC7B2 # 0 +0xB888 0xC7B3 # 0 +0xB889 0xC7B4 # 0 +0xB88A 0xC7B5 # 0 +0xB88B 0xC7B6 # 0 +0xB88C 0xC7B7 # 0 +0xB88D 0xC7B8 # 0 +0xB88E 0xC7B9 # 0 +0xB88F 0xC7BA # 0 +0xB890 0xC7BB # 0 +0xB891 0xC7BC # 0 +0xB893 0xC7BD # 0 +0xB894 0xC7BE # 0 +0xB895 0xC7BF # 0 +0xB896 0xC7C0 # 0 +0xB897 0xC7C1 # 0 +0xB898 0xC7C2 # 0 +0xB899 0xC7C3 # 0 +0xB89A 0xC7C4 # 0 +0xB89B 0xC7C5 # 0 +0xB89C 0xC7C6 # 0 +0xB89D 0xC7C7 # 0 +0xB8A1 0xC7C8 # 0 +0xB8A2 0xC7C9 # 0 +0xB8A3 0xC7CA # 0 +0xB8A4 0xC7CB # 0 +0xB8A5 0xC7CC # 0 +0xB8A6 0xC7CD # 0 +0xB8A7 0xC7CE # 0 +0xB8A8 0xC7CF # 0 +0xB8A9 0xC7D0 # 0 +0xB8AA 0xC7D1 # 0 +0xB8AB 0xC7D2 # 0 +0xB8AC 0xC7D3 # 0 +0xB8AD 0xC7D4 # 0 +0xB8AE 0xC7D5 # 0 +0xB8AF 0xC7D6 # 0 +0xB8B0 0xC7D7 # 0 +0xB8B1 0xC7D8 # 0 +0xB8B3 0xC7D9 # 0 +0xB8B4 0xC7DA # 0 +0xB8B5 0xC7DB # 0 +0xB8B6 0xC7DC # 0 +0xB8B7 0xC7DD # 0 +0xB8B8 0xC7DE # 0 +0xB8B9 0xC7DF # 0 +0xB8BA 0xC7E0 # 0 +0xB8BB 0xC7E1 # 0 +0xB8BC 0xC7E2 # 0 +0xB8BD 0xC7E3 # 0 +0xB8C1 0xC7E4 # 0 +0xB8C2 0xC7E5 # 0 +0xB8C3 0xC7E6 # 0 +0xB8C4 0xC7E7 # 0 +0xB8C5 0xC7E8 # 0 +0xB8C6 0xC7E9 # 0 +0xB8C7 0xC7EA # 0 +0xB8C8 0xC7EB # 0 +0xB8C9 0xC7EC # 0 +0xB8CA 0xC7ED # 0 +0xB8CB 0xC7EE # 0 +0xB8CC 0xC7EF # 0 +0xB8CD 0xC7F0 # 0 +0xB8CE 0xC7F1 # 0 +0xB8CF 0xC7F2 # 0 +0xB8D0 0xC7F3 # 0 +0xB8D1 0xC7F4 # 0 +0xB8D3 0xC7F5 # 0 +0xB8D4 0xC7F6 # 0 +0xB8D5 0xC7F7 # 0 +0xB8D6 0xC7F8 # 0 +0xB8D7 0xC7F9 # 0 +0xB8D8 0xC7FA # 0 +0xB8D9 0xC7FB # 0 +0xB8DA 0xC7FC # 0 +0xB8DB 0xC7FD # 0 +0xB8DC 0xC7FE # 0 +0xB8DD 0xC7FF # 0 +0xB8E1 0xC800 # 0 +0xB8E2 0xC801 # 0 +0xB8E3 0xC802 # 0 +0xB8E4 0xC803 # 0 +0xB8E5 0xC804 # 0 +0xB8E6 0xC805 # 0 +0xB8E7 0xC806 # 0 +0xB8E8 0xC807 # 0 +0xB8E9 0xC808 # 0 +0xB8EA 0xC809 # 0 +0xB8EB 0xC80A # 0 +0xB8EC 0xC80B # 0 +0xB8ED 0xC80C # 0 +0xB8EE 0xC80D # 0 +0xB8EF 0xC80E # 0 +0xB8F0 0xC80F # 0 +0xB8F1 0xC810 # 0 +0xB8F3 0xC811 # 0 +0xB8F4 0xC812 # 0 +0xB8F5 0xC813 # 0 +0xB8F6 0xC814 # 0 +0xB8F7 0xC815 # 0 +0xB8F8 0xC816 # 0 +0xB8F9 0xC817 # 0 +0xB8FA 0xC818 # 0 +0xB8FB 0xC819 # 0 +0xB8FC 0xC81A # 0 +0xB8FD 0xC81B # 0 +0xB941 0xC81C # 0 +0xB942 0xC81D # 0 +0xB943 0xC81E # 0 +0xB944 0xC81F # 0 +0xB945 0xC820 # 0 +0xB946 0xC821 # 0 +0xB947 0xC822 # 0 +0xB948 0xC823 # 0 +0xB949 0xC824 # 0 +0xB94A 0xC825 # 0 +0xB94B 0xC826 # 0 +0xB94C 0xC827 # 0 +0xB94D 0xC828 # 0 +0xB94E 0xC829 # 0 +0xB94F 0xC82A # 0 +0xB950 0xC82B # 0 +0xB951 0xC82C # 0 +0xB953 0xC82D # 0 +0xB954 0xC82E # 0 +0xB955 0xC82F # 0 +0xB956 0xC830 # 0 +0xB957 0xC831 # 0 +0xB958 0xC832 # 0 +0xB959 0xC833 # 0 +0xB95A 0xC834 # 0 +0xB95B 0xC835 # 0 +0xB95C 0xC836 # 0 +0xB95D 0xC837 # 0 +0xB961 0xC838 # 0 +0xB962 0xC839 # 0 +0xB963 0xC83A # 0 +0xB964 0xC83B # 0 +0xB965 0xC83C # 0 +0xB966 0xC83D # 0 +0xB967 0xC83E # 0 +0xB968 0xC83F # 0 +0xB969 0xC840 # 0 +0xB96A 0xC841 # 0 +0xB96B 0xC842 # 0 +0xB96C 0xC843 # 0 +0xB96D 0xC844 # 0 +0xB96E 0xC845 # 0 +0xB96F 0xC846 # 0 +0xB970 0xC847 # 0 +0xB971 0xC848 # 0 +0xB973 0xC849 # 0 +0xB974 0xC84A # 0 +0xB975 0xC84B # 0 +0xB976 0xC84C # 0 +0xB977 0xC84D # 0 +0xB978 0xC84E # 0 +0xB979 0xC84F # 0 +0xB97A 0xC850 # 0 +0xB97B 0xC851 # 0 +0xB97C 0xC852 # 0 +0xB97D 0xC853 # 0 +0xB981 0xC854 # 0 +0xB982 0xC855 # 0 +0xB983 0xC856 # 0 +0xB984 0xC857 # 0 +0xB985 0xC858 # 0 +0xB986 0xC859 # 0 +0xB987 0xC85A # 0 +0xB988 0xC85B # 0 +0xB989 0xC85C # 0 +0xB98A 0xC85D # 0 +0xB98B 0xC85E # 0 +0xB98C 0xC85F # 0 +0xB98D 0xC860 # 0 +0xB98E 0xC861 # 0 +0xB98F 0xC862 # 0 +0xB990 0xC863 # 0 +0xB991 0xC864 # 0 +0xB993 0xC865 # 0 +0xB994 0xC866 # 0 +0xB995 0xC867 # 0 +0xB996 0xC868 # 0 +0xB997 0xC869 # 0 +0xB998 0xC86A # 0 +0xB999 0xC86B # 0 +0xB99A 0xC86C # 0 +0xB99B 0xC86D # 0 +0xB99C 0xC86E # 0 +0xB99D 0xC86F # 0 +0xB9A1 0xC870 # 0 +0xB9A2 0xC871 # 0 +0xB9A3 0xC872 # 0 +0xB9A4 0xC873 # 0 +0xB9A5 0xC874 # 0 +0xB9A6 0xC875 # 0 +0xB9A7 0xC876 # 0 +0xB9A8 0xC877 # 0 +0xB9A9 0xC878 # 0 +0xB9AA 0xC879 # 0 +0xB9AB 0xC87A # 0 +0xB9AC 0xC87B # 0 +0xB9AD 0xC87C # 0 +0xB9AE 0xC87D # 0 +0xB9AF 0xC87E # 0 +0xB9B0 0xC87F # 0 +0xB9B1 0xC880 # 0 +0xB9B3 0xC881 # 0 +0xB9B4 0xC882 # 0 +0xB9B5 0xC883 # 0 +0xB9B6 0xC884 # 0 +0xB9B7 0xC885 # 0 +0xB9B8 0xC886 # 0 +0xB9B9 0xC887 # 0 +0xB9BA 0xC888 # 0 +0xB9BB 0xC889 # 0 +0xB9BC 0xC88A # 0 +0xB9BD 0xC88B # 0 +0xB9C1 0xC88C # 0 +0xB9C2 0xC88D # 0 +0xB9C3 0xC88E # 0 +0xB9C4 0xC88F # 0 +0xB9C5 0xC890 # 0 +0xB9C6 0xC891 # 0 +0xB9C7 0xC892 # 0 +0xB9C8 0xC893 # 0 +0xB9C9 0xC894 # 0 +0xB9CA 0xC895 # 0 +0xB9CB 0xC896 # 0 +0xB9CC 0xC897 # 0 +0xB9CD 0xC898 # 0 +0xB9CE 0xC899 # 0 +0xB9CF 0xC89A # 0 +0xB9D0 0xC89B # 0 +0xB9D1 0xC89C # 0 +0xB9D3 0xC89D # 0 +0xB9D4 0xC89E # 0 +0xB9D5 0xC89F # 0 +0xB9D6 0xC8A0 # 0 +0xB9D7 0xC8A1 # 0 +0xB9D8 0xC8A2 # 0 +0xB9D9 0xC8A3 # 0 +0xB9DA 0xC8A4 # 0 +0xB9DB 0xC8A5 # 0 +0xB9DC 0xC8A6 # 0 +0xB9DD 0xC8A7 # 0 +0xB9E1 0xC8A8 # 0 +0xB9E2 0xC8A9 # 0 +0xB9E3 0xC8AA # 0 +0xB9E4 0xC8AB # 0 +0xB9E5 0xC8AC # 0 +0xB9E6 0xC8AD # 0 +0xB9E7 0xC8AE # 0 +0xB9E8 0xC8AF # 0 +0xB9E9 0xC8B0 # 0 +0xB9EA 0xC8B1 # 0 +0xB9EB 0xC8B2 # 0 +0xB9EC 0xC8B3 # 0 +0xB9ED 0xC8B4 # 0 +0xB9EE 0xC8B5 # 0 +0xB9EF 0xC8B6 # 0 +0xB9F0 0xC8B7 # 0 +0xB9F1 0xC8B8 # 0 +0xB9F3 0xC8B9 # 0 +0xB9F4 0xC8BA # 0 +0xB9F5 0xC8BB # 0 +0xB9F6 0xC8BC # 0 +0xB9F7 0xC8BD # 0 +0xB9F8 0xC8BE # 0 +0xB9F9 0xC8BF # 0 +0xB9FA 0xC8C0 # 0 +0xB9FB 0xC8C1 # 0 +0xB9FC 0xC8C2 # 0 +0xB9FD 0xC8C3 # 0 +0xBA41 0xC8C4 # 0 +0xBA42 0xC8C5 # 0 +0xBA43 0xC8C6 # 0 +0xBA44 0xC8C7 # 0 +0xBA45 0xC8C8 # 0 +0xBA46 0xC8C9 # 0 +0xBA47 0xC8CA # 0 +0xBA48 0xC8CB # 0 +0xBA49 0xC8CC # 0 +0xBA4A 0xC8CD # 0 +0xBA4B 0xC8CE # 0 +0xBA4C 0xC8CF # 0 +0xBA4D 0xC8D0 # 0 +0xBA4E 0xC8D1 # 0 +0xBA4F 0xC8D2 # 0 +0xBA50 0xC8D3 # 0 +0xBA51 0xC8D4 # 0 +0xBA53 0xC8D5 # 0 +0xBA54 0xC8D6 # 0 +0xBA55 0xC8D7 # 0 +0xBA56 0xC8D8 # 0 +0xBA57 0xC8D9 # 0 +0xBA58 0xC8DA # 0 +0xBA59 0xC8DB # 0 +0xBA5A 0xC8DC # 0 +0xBA5B 0xC8DD # 0 +0xBA5C 0xC8DE # 0 +0xBA5D 0xC8DF # 0 +0xBA61 0xC8E0 # 0 +0xBA62 0xC8E1 # 0 +0xBA63 0xC8E2 # 0 +0xBA64 0xC8E3 # 0 +0xBA65 0xC8E4 # 0 +0xBA66 0xC8E5 # 0 +0xBA67 0xC8E6 # 0 +0xBA68 0xC8E7 # 0 +0xBA69 0xC8E8 # 0 +0xBA6A 0xC8E9 # 0 +0xBA6B 0xC8EA # 0 +0xBA6C 0xC8EB # 0 +0xBA6D 0xC8EC # 0 +0xBA6E 0xC8ED # 0 +0xBA6F 0xC8EE # 0 +0xBA70 0xC8EF # 0 +0xBA71 0xC8F0 # 0 +0xBA73 0xC8F1 # 0 +0xBA74 0xC8F2 # 0 +0xBA75 0xC8F3 # 0 +0xBA76 0xC8F4 # 0 +0xBA77 0xC8F5 # 0 +0xBA78 0xC8F6 # 0 +0xBA79 0xC8F7 # 0 +0xBA7A 0xC8F8 # 0 +0xBA7B 0xC8F9 # 0 +0xBA7C 0xC8FA # 0 +0xBA7D 0xC8FB # 0 +0xBA81 0xC8FC # 0 +0xBA82 0xC8FD # 0 +0xBA83 0xC8FE # 0 +0xBA84 0xC8FF # 0 +0xBA85 0xC900 # 0 +0xBA86 0xC901 # 0 +0xBA87 0xC902 # 0 +0xBA88 0xC903 # 0 +0xBA89 0xC904 # 0 +0xBA8A 0xC905 # 0 +0xBA8B 0xC906 # 0 +0xBA8C 0xC907 # 0 +0xBA8D 0xC908 # 0 +0xBA8E 0xC909 # 0 +0xBA8F 0xC90A # 0 +0xBA90 0xC90B # 0 +0xBA91 0xC90C # 0 +0xBA93 0xC90D # 0 +0xBA94 0xC90E # 0 +0xBA95 0xC90F # 0 +0xBA96 0xC910 # 0 +0xBA97 0xC911 # 0 +0xBA98 0xC912 # 0 +0xBA99 0xC913 # 0 +0xBA9A 0xC914 # 0 +0xBA9B 0xC915 # 0 +0xBA9C 0xC916 # 0 +0xBA9D 0xC917 # 0 +0xBAA1 0xC918 # 0 +0xBAA2 0xC919 # 0 +0xBAA3 0xC91A # 0 +0xBAA4 0xC91B # 0 +0xBAA5 0xC91C # 0 +0xBAA6 0xC91D # 0 +0xBAA7 0xC91E # 0 +0xBAA8 0xC91F # 0 +0xBAA9 0xC920 # 0 +0xBAAA 0xC921 # 0 +0xBAAB 0xC922 # 0 +0xBAAC 0xC923 # 0 +0xBAAD 0xC924 # 0 +0xBAAE 0xC925 # 0 +0xBAAF 0xC926 # 0 +0xBAB0 0xC927 # 0 +0xBAB1 0xC928 # 0 +0xBAB3 0xC929 # 0 +0xBAB4 0xC92A # 0 +0xBAB5 0xC92B # 0 +0xBAB6 0xC92C # 0 +0xBAB7 0xC92D # 0 +0xBAB8 0xC92E # 0 +0xBAB9 0xC92F # 0 +0xBABA 0xC930 # 0 +0xBABB 0xC931 # 0 +0xBABC 0xC932 # 0 +0xBABD 0xC933 # 0 +0xBAC1 0xC934 # 0 +0xBAC2 0xC935 # 0 +0xBAC3 0xC936 # 0 +0xBAC4 0xC937 # 0 +0xBAC5 0xC938 # 0 +0xBAC6 0xC939 # 0 +0xBAC7 0xC93A # 0 +0xBAC8 0xC93B # 0 +0xBAC9 0xC93C # 0 +0xBACA 0xC93D # 0 +0xBACB 0xC93E # 0 +0xBACC 0xC93F # 0 +0xBACD 0xC940 # 0 +0xBACE 0xC941 # 0 +0xBACF 0xC942 # 0 +0xBAD0 0xC943 # 0 +0xBAD1 0xC944 # 0 +0xBAD3 0xC945 # 0 +0xBAD4 0xC946 # 0 +0xBAD5 0xC947 # 0 +0xBAD6 0xC948 # 0 +0xBAD7 0xC949 # 0 +0xBAD8 0xC94A # 0 +0xBAD9 0xC94B # 0 +0xBADA 0xC94C # 0 +0xBADB 0xC94D # 0 +0xBADC 0xC94E # 0 +0xBADD 0xC94F # 0 +0xBAE1 0xC950 # 0 +0xBAE2 0xC951 # 0 +0xBAE3 0xC952 # 0 +0xBAE4 0xC953 # 0 +0xBAE5 0xC954 # 0 +0xBAE6 0xC955 # 0 +0xBAE7 0xC956 # 0 +0xBAE8 0xC957 # 0 +0xBAE9 0xC958 # 0 +0xBAEA 0xC959 # 0 +0xBAEB 0xC95A # 0 +0xBAEC 0xC95B # 0 +0xBAED 0xC95C # 0 +0xBAEE 0xC95D # 0 +0xBAEF 0xC95E # 0 +0xBAF0 0xC95F # 0 +0xBAF1 0xC960 # 0 +0xBAF3 0xC961 # 0 +0xBAF4 0xC962 # 0 +0xBAF5 0xC963 # 0 +0xBAF6 0xC964 # 0 +0xBAF7 0xC965 # 0 +0xBAF8 0xC966 # 0 +0xBAF9 0xC967 # 0 +0xBAFA 0xC968 # 0 +0xBAFB 0xC969 # 0 +0xBAFC 0xC96A # 0 +0xBAFD 0xC96B # 0 +0xBB41 0xC96C # 0 +0xBB42 0xC96D # 0 +0xBB43 0xC96E # 0 +0xBB44 0xC96F # 0 +0xBB45 0xC970 # 0 +0xBB46 0xC971 # 0 +0xBB47 0xC972 # 0 +0xBB48 0xC973 # 0 +0xBB49 0xC974 # 0 +0xBB4A 0xC975 # 0 +0xBB4B 0xC976 # 0 +0xBB4C 0xC977 # 0 +0xBB4D 0xC978 # 0 +0xBB4E 0xC979 # 0 +0xBB4F 0xC97A # 0 +0xBB50 0xC97B # 0 +0xBB51 0xC97C # 0 +0xBB53 0xC97D # 0 +0xBB54 0xC97E # 0 +0xBB55 0xC97F # 0 +0xBB56 0xC980 # 0 +0xBB57 0xC981 # 0 +0xBB58 0xC982 # 0 +0xBB59 0xC983 # 0 +0xBB5A 0xC984 # 0 +0xBB5B 0xC985 # 0 +0xBB5C 0xC986 # 0 +0xBB5D 0xC987 # 0 +0xBB61 0xC988 # 0 +0xBB62 0xC989 # 0 +0xBB63 0xC98A # 0 +0xBB64 0xC98B # 0 +0xBB65 0xC98C # 0 +0xBB66 0xC98D # 0 +0xBB67 0xC98E # 0 +0xBB68 0xC98F # 0 +0xBB69 0xC990 # 0 +0xBB6A 0xC991 # 0 +0xBB6B 0xC992 # 0 +0xBB6C 0xC993 # 0 +0xBB6D 0xC994 # 0 +0xBB6E 0xC995 # 0 +0xBB6F 0xC996 # 0 +0xBB70 0xC997 # 0 +0xBB71 0xC998 # 0 +0xBB73 0xC999 # 0 +0xBB74 0xC99A # 0 +0xBB75 0xC99B # 0 +0xBB76 0xC99C # 0 +0xBB77 0xC99D # 0 +0xBB78 0xC99E # 0 +0xBB79 0xC99F # 0 +0xBB7A 0xC9A0 # 0 +0xBB7B 0xC9A1 # 0 +0xBB7C 0xC9A2 # 0 +0xBB7D 0xC9A3 # 0 +0xBB81 0xC9A4 # 0 +0xBB82 0xC9A5 # 0 +0xBB83 0xC9A6 # 0 +0xBB84 0xC9A7 # 0 +0xBB85 0xC9A8 # 0 +0xBB86 0xC9A9 # 0 +0xBB87 0xC9AA # 0 +0xBB88 0xC9AB # 0 +0xBB89 0xC9AC # 0 +0xBB8A 0xC9AD # 0 +0xBB8B 0xC9AE # 0 +0xBB8C 0xC9AF # 0 +0xBB8D 0xC9B0 # 0 +0xBB8E 0xC9B1 # 0 +0xBB8F 0xC9B2 # 0 +0xBB90 0xC9B3 # 0 +0xBB91 0xC9B4 # 0 +0xBB93 0xC9B5 # 0 +0xBB94 0xC9B6 # 0 +0xBB95 0xC9B7 # 0 +0xBB96 0xC9B8 # 0 +0xBB97 0xC9B9 # 0 +0xBB98 0xC9BA # 0 +0xBB99 0xC9BB # 0 +0xBB9A 0xC9BC # 0 +0xBB9B 0xC9BD # 0 +0xBB9C 0xC9BE # 0 +0xBB9D 0xC9BF # 0 +0xBBA1 0xC9C0 # 0 +0xBBA2 0xC9C1 # 0 +0xBBA3 0xC9C2 # 0 +0xBBA4 0xC9C3 # 0 +0xBBA5 0xC9C4 # 0 +0xBBA6 0xC9C5 # 0 +0xBBA7 0xC9C6 # 0 +0xBBA8 0xC9C7 # 0 +0xBBA9 0xC9C8 # 0 +0xBBAA 0xC9C9 # 0 +0xBBAB 0xC9CA # 0 +0xBBAC 0xC9CB # 0 +0xBBAD 0xC9CC # 0 +0xBBAE 0xC9CD # 0 +0xBBAF 0xC9CE # 0 +0xBBB0 0xC9CF # 0 +0xBBB1 0xC9D0 # 0 +0xBBB3 0xC9D1 # 0 +0xBBB4 0xC9D2 # 0 +0xBBB5 0xC9D3 # 0 +0xBBB6 0xC9D4 # 0 +0xBBB7 0xC9D5 # 0 +0xBBB8 0xC9D6 # 0 +0xBBB9 0xC9D7 # 0 +0xBBBA 0xC9D8 # 0 +0xBBBB 0xC9D9 # 0 +0xBBBC 0xC9DA # 0 +0xBBBD 0xC9DB # 0 +0xBC41 0x110D # 0 +0xBC61 0xC9DC # 0 +0xBC62 0xC9DD # 0 +0xBC63 0xC9DE # 0 +0xBC64 0xC9DF # 0 +0xBC65 0xC9E0 # 0 +0xBC66 0xC9E1 # 0 +0xBC67 0xC9E2 # 0 +0xBC68 0xC9E3 # 0 +0xBC69 0xC9E4 # 0 +0xBC6A 0xC9E5 # 0 +0xBC6B 0xC9E6 # 0 +0xBC6C 0xC9E7 # 0 +0xBC6D 0xC9E8 # 0 +0xBC6E 0xC9E9 # 0 +0xBC6F 0xC9EA # 0 +0xBC70 0xC9EB # 0 +0xBC71 0xC9EC # 0 +0xBC73 0xC9ED # 0 +0xBC74 0xC9EE # 0 +0xBC75 0xC9EF # 0 +0xBC76 0xC9F0 # 0 +0xBC77 0xC9F1 # 0 +0xBC78 0xC9F2 # 0 +0xBC79 0xC9F3 # 0 +0xBC7A 0xC9F4 # 0 +0xBC7B 0xC9F5 # 0 +0xBC7C 0xC9F6 # 0 +0xBC7D 0xC9F7 # 0 +0xBC81 0xC9F8 # 0 +0xBC82 0xC9F9 # 0 +0xBC83 0xC9FA # 0 +0xBC84 0xC9FB # 0 +0xBC85 0xC9FC # 0 +0xBC86 0xC9FD # 0 +0xBC87 0xC9FE # 0 +0xBC88 0xC9FF # 0 +0xBC89 0xCA00 # 0 +0xBC8A 0xCA01 # 0 +0xBC8B 0xCA02 # 0 +0xBC8C 0xCA03 # 0 +0xBC8D 0xCA04 # 0 +0xBC8E 0xCA05 # 0 +0xBC8F 0xCA06 # 0 +0xBC90 0xCA07 # 0 +0xBC91 0xCA08 # 0 +0xBC93 0xCA09 # 0 +0xBC94 0xCA0A # 0 +0xBC95 0xCA0B # 0 +0xBC96 0xCA0C # 0 +0xBC97 0xCA0D # 0 +0xBC98 0xCA0E # 0 +0xBC99 0xCA0F # 0 +0xBC9A 0xCA10 # 0 +0xBC9B 0xCA11 # 0 +0xBC9C 0xCA12 # 0 +0xBC9D 0xCA13 # 0 +0xBCA1 0xCA14 # 0 +0xBCA2 0xCA15 # 0 +0xBCA3 0xCA16 # 0 +0xBCA4 0xCA17 # 0 +0xBCA5 0xCA18 # 0 +0xBCA6 0xCA19 # 0 +0xBCA7 0xCA1A # 0 +0xBCA8 0xCA1B # 0 +0xBCA9 0xCA1C # 0 +0xBCAA 0xCA1D # 0 +0xBCAB 0xCA1E # 0 +0xBCAC 0xCA1F # 0 +0xBCAD 0xCA20 # 0 +0xBCAE 0xCA21 # 0 +0xBCAF 0xCA22 # 0 +0xBCB0 0xCA23 # 0 +0xBCB1 0xCA24 # 0 +0xBCB3 0xCA25 # 0 +0xBCB4 0xCA26 # 0 +0xBCB5 0xCA27 # 0 +0xBCB6 0xCA28 # 0 +0xBCB7 0xCA29 # 0 +0xBCB8 0xCA2A # 0 +0xBCB9 0xCA2B # 0 +0xBCBA 0xCA2C # 0 +0xBCBB 0xCA2D # 0 +0xBCBC 0xCA2E # 0 +0xBCBD 0xCA2F # 0 +0xBCC1 0xCA30 # 0 +0xBCC2 0xCA31 # 0 +0xBCC3 0xCA32 # 0 +0xBCC4 0xCA33 # 0 +0xBCC5 0xCA34 # 0 +0xBCC6 0xCA35 # 0 +0xBCC7 0xCA36 # 0 +0xBCC8 0xCA37 # 0 +0xBCC9 0xCA38 # 0 +0xBCCA 0xCA39 # 0 +0xBCCB 0xCA3A # 0 +0xBCCC 0xCA3B # 0 +0xBCCD 0xCA3C # 0 +0xBCCE 0xCA3D # 0 +0xBCCF 0xCA3E # 0 +0xBCD0 0xCA3F # 0 +0xBCD1 0xCA40 # 0 +0xBCD3 0xCA41 # 0 +0xBCD4 0xCA42 # 0 +0xBCD5 0xCA43 # 0 +0xBCD6 0xCA44 # 0 +0xBCD7 0xCA45 # 0 +0xBCD8 0xCA46 # 0 +0xBCD9 0xCA47 # 0 +0xBCDA 0xCA48 # 0 +0xBCDB 0xCA49 # 0 +0xBCDC 0xCA4A # 0 +0xBCDD 0xCA4B # 0 +0xBCE1 0xCA4C # 0 +0xBCE2 0xCA4D # 0 +0xBCE3 0xCA4E # 0 +0xBCE4 0xCA4F # 0 +0xBCE5 0xCA50 # 0 +0xBCE6 0xCA51 # 0 +0xBCE7 0xCA52 # 0 +0xBCE8 0xCA53 # 0 +0xBCE9 0xCA54 # 0 +0xBCEA 0xCA55 # 0 +0xBCEB 0xCA56 # 0 +0xBCEC 0xCA57 # 0 +0xBCED 0xCA58 # 0 +0xBCEE 0xCA59 # 0 +0xBCEF 0xCA5A # 0 +0xBCF0 0xCA5B # 0 +0xBCF1 0xCA5C # 0 +0xBCF3 0xCA5D # 0 +0xBCF4 0xCA5E # 0 +0xBCF5 0xCA5F # 0 +0xBCF6 0xCA60 # 0 +0xBCF7 0xCA61 # 0 +0xBCF8 0xCA62 # 0 +0xBCF9 0xCA63 # 0 +0xBCFA 0xCA64 # 0 +0xBCFB 0xCA65 # 0 +0xBCFC 0xCA66 # 0 +0xBCFD 0xCA67 # 0 +0xBD41 0xCA68 # 0 +0xBD42 0xCA69 # 0 +0xBD43 0xCA6A # 0 +0xBD44 0xCA6B # 0 +0xBD45 0xCA6C # 0 +0xBD46 0xCA6D # 0 +0xBD47 0xCA6E # 0 +0xBD48 0xCA6F # 0 +0xBD49 0xCA70 # 0 +0xBD4A 0xCA71 # 0 +0xBD4B 0xCA72 # 0 +0xBD4C 0xCA73 # 0 +0xBD4D 0xCA74 # 0 +0xBD4E 0xCA75 # 0 +0xBD4F 0xCA76 # 0 +0xBD50 0xCA77 # 0 +0xBD51 0xCA78 # 0 +0xBD53 0xCA79 # 0 +0xBD54 0xCA7A # 0 +0xBD55 0xCA7B # 0 +0xBD56 0xCA7C # 0 +0xBD57 0xCA7D # 0 +0xBD58 0xCA7E # 0 +0xBD59 0xCA7F # 0 +0xBD5A 0xCA80 # 0 +0xBD5B 0xCA81 # 0 +0xBD5C 0xCA82 # 0 +0xBD5D 0xCA83 # 0 +0xBD61 0xCA84 # 0 +0xBD62 0xCA85 # 0 +0xBD63 0xCA86 # 0 +0xBD64 0xCA87 # 0 +0xBD65 0xCA88 # 0 +0xBD66 0xCA89 # 0 +0xBD67 0xCA8A # 0 +0xBD68 0xCA8B # 0 +0xBD69 0xCA8C # 0 +0xBD6A 0xCA8D # 0 +0xBD6B 0xCA8E # 0 +0xBD6C 0xCA8F # 0 +0xBD6D 0xCA90 # 0 +0xBD6E 0xCA91 # 0 +0xBD6F 0xCA92 # 0 +0xBD70 0xCA93 # 0 +0xBD71 0xCA94 # 0 +0xBD73 0xCA95 # 0 +0xBD74 0xCA96 # 0 +0xBD75 0xCA97 # 0 +0xBD76 0xCA98 # 0 +0xBD77 0xCA99 # 0 +0xBD78 0xCA9A # 0 +0xBD79 0xCA9B # 0 +0xBD7A 0xCA9C # 0 +0xBD7B 0xCA9D # 0 +0xBD7C 0xCA9E # 0 +0xBD7D 0xCA9F # 0 +0xBD81 0xCAA0 # 0 +0xBD82 0xCAA1 # 0 +0xBD83 0xCAA2 # 0 +0xBD84 0xCAA3 # 0 +0xBD85 0xCAA4 # 0 +0xBD86 0xCAA5 # 0 +0xBD87 0xCAA6 # 0 +0xBD88 0xCAA7 # 0 +0xBD89 0xCAA8 # 0 +0xBD8A 0xCAA9 # 0 +0xBD8B 0xCAAA # 0 +0xBD8C 0xCAAB # 0 +0xBD8D 0xCAAC # 0 +0xBD8E 0xCAAD # 0 +0xBD8F 0xCAAE # 0 +0xBD90 0xCAAF # 0 +0xBD91 0xCAB0 # 0 +0xBD93 0xCAB1 # 0 +0xBD94 0xCAB2 # 0 +0xBD95 0xCAB3 # 0 +0xBD96 0xCAB4 # 0 +0xBD97 0xCAB5 # 0 +0xBD98 0xCAB6 # 0 +0xBD99 0xCAB7 # 0 +0xBD9A 0xCAB8 # 0 +0xBD9B 0xCAB9 # 0 +0xBD9C 0xCABA # 0 +0xBD9D 0xCABB # 0 +0xBDA1 0xCABC # 0 +0xBDA2 0xCABD # 0 +0xBDA3 0xCABE # 0 +0xBDA4 0xCABF # 0 +0xBDA5 0xCAC0 # 0 +0xBDA6 0xCAC1 # 0 +0xBDA7 0xCAC2 # 0 +0xBDA8 0xCAC3 # 0 +0xBDA9 0xCAC4 # 0 +0xBDAA 0xCAC5 # 0 +0xBDAB 0xCAC6 # 0 +0xBDAC 0xCAC7 # 0 +0xBDAD 0xCAC8 # 0 +0xBDAE 0xCAC9 # 0 +0xBDAF 0xCACA # 0 +0xBDB0 0xCACB # 0 +0xBDB1 0xCACC # 0 +0xBDB3 0xCACD # 0 +0xBDB4 0xCACE # 0 +0xBDB5 0xCACF # 0 +0xBDB6 0xCAD0 # 0 +0xBDB7 0xCAD1 # 0 +0xBDB8 0xCAD2 # 0 +0xBDB9 0xCAD3 # 0 +0xBDBA 0xCAD4 # 0 +0xBDBB 0xCAD5 # 0 +0xBDBC 0xCAD6 # 0 +0xBDBD 0xCAD7 # 0 +0xBDC1 0xCAD8 # 0 +0xBDC2 0xCAD9 # 0 +0xBDC3 0xCADA # 0 +0xBDC4 0xCADB # 0 +0xBDC5 0xCADC # 0 +0xBDC6 0xCADD # 0 +0xBDC7 0xCADE # 0 +0xBDC8 0xCADF # 0 +0xBDC9 0xCAE0 # 0 +0xBDCA 0xCAE1 # 0 +0xBDCB 0xCAE2 # 0 +0xBDCC 0xCAE3 # 0 +0xBDCD 0xCAE4 # 0 +0xBDCE 0xCAE5 # 0 +0xBDCF 0xCAE6 # 0 +0xBDD0 0xCAE7 # 0 +0xBDD1 0xCAE8 # 0 +0xBDD3 0xCAE9 # 0 +0xBDD4 0xCAEA # 0 +0xBDD5 0xCAEB # 0 +0xBDD6 0xCAEC # 0 +0xBDD7 0xCAED # 0 +0xBDD8 0xCAEE # 0 +0xBDD9 0xCAEF # 0 +0xBDDA 0xCAF0 # 0 +0xBDDB 0xCAF1 # 0 +0xBDDC 0xCAF2 # 0 +0xBDDD 0xCAF3 # 0 +0xBDE1 0xCAF4 # 0 +0xBDE2 0xCAF5 # 0 +0xBDE3 0xCAF6 # 0 +0xBDE4 0xCAF7 # 0 +0xBDE5 0xCAF8 # 0 +0xBDE6 0xCAF9 # 0 +0xBDE7 0xCAFA # 0 +0xBDE8 0xCAFB # 0 +0xBDE9 0xCAFC # 0 +0xBDEA 0xCAFD # 0 +0xBDEB 0xCAFE # 0 +0xBDEC 0xCAFF # 0 +0xBDED 0xCB00 # 0 +0xBDEE 0xCB01 # 0 +0xBDEF 0xCB02 # 0 +0xBDF0 0xCB03 # 0 +0xBDF1 0xCB04 # 0 +0xBDF3 0xCB05 # 0 +0xBDF4 0xCB06 # 0 +0xBDF5 0xCB07 # 0 +0xBDF6 0xCB08 # 0 +0xBDF7 0xCB09 # 0 +0xBDF8 0xCB0A # 0 +0xBDF9 0xCB0B # 0 +0xBDFA 0xCB0C # 0 +0xBDFB 0xCB0D # 0 +0xBDFC 0xCB0E # 0 +0xBDFD 0xCB0F # 0 +0xBE41 0xCB10 # 0 +0xBE42 0xCB11 # 0 +0xBE43 0xCB12 # 0 +0xBE44 0xCB13 # 0 +0xBE45 0xCB14 # 0 +0xBE46 0xCB15 # 0 +0xBE47 0xCB16 # 0 +0xBE48 0xCB17 # 0 +0xBE49 0xCB18 # 0 +0xBE4A 0xCB19 # 0 +0xBE4B 0xCB1A # 0 +0xBE4C 0xCB1B # 0 +0xBE4D 0xCB1C # 0 +0xBE4E 0xCB1D # 0 +0xBE4F 0xCB1E # 0 +0xBE50 0xCB1F # 0 +0xBE51 0xCB20 # 0 +0xBE53 0xCB21 # 0 +0xBE54 0xCB22 # 0 +0xBE55 0xCB23 # 0 +0xBE56 0xCB24 # 0 +0xBE57 0xCB25 # 0 +0xBE58 0xCB26 # 0 +0xBE59 0xCB27 # 0 +0xBE5A 0xCB28 # 0 +0xBE5B 0xCB29 # 0 +0xBE5C 0xCB2A # 0 +0xBE5D 0xCB2B # 0 +0xBE61 0xCB2C # 0 +0xBE62 0xCB2D # 0 +0xBE63 0xCB2E # 0 +0xBE64 0xCB2F # 0 +0xBE65 0xCB30 # 0 +0xBE66 0xCB31 # 0 +0xBE67 0xCB32 # 0 +0xBE68 0xCB33 # 0 +0xBE69 0xCB34 # 0 +0xBE6A 0xCB35 # 0 +0xBE6B 0xCB36 # 0 +0xBE6C 0xCB37 # 0 +0xBE6D 0xCB38 # 0 +0xBE6E 0xCB39 # 0 +0xBE6F 0xCB3A # 0 +0xBE70 0xCB3B # 0 +0xBE71 0xCB3C # 0 +0xBE73 0xCB3D # 0 +0xBE74 0xCB3E # 0 +0xBE75 0xCB3F # 0 +0xBE76 0xCB40 # 0 +0xBE77 0xCB41 # 0 +0xBE78 0xCB42 # 0 +0xBE79 0xCB43 # 0 +0xBE7A 0xCB44 # 0 +0xBE7B 0xCB45 # 0 +0xBE7C 0xCB46 # 0 +0xBE7D 0xCB47 # 0 +0xBE81 0xCB48 # 0 +0xBE82 0xCB49 # 0 +0xBE83 0xCB4A # 0 +0xBE84 0xCB4B # 0 +0xBE85 0xCB4C # 0 +0xBE86 0xCB4D # 0 +0xBE87 0xCB4E # 0 +0xBE88 0xCB4F # 0 +0xBE89 0xCB50 # 0 +0xBE8A 0xCB51 # 0 +0xBE8B 0xCB52 # 0 +0xBE8C 0xCB53 # 0 +0xBE8D 0xCB54 # 0 +0xBE8E 0xCB55 # 0 +0xBE8F 0xCB56 # 0 +0xBE90 0xCB57 # 0 +0xBE91 0xCB58 # 0 +0xBE93 0xCB59 # 0 +0xBE94 0xCB5A # 0 +0xBE95 0xCB5B # 0 +0xBE96 0xCB5C # 0 +0xBE97 0xCB5D # 0 +0xBE98 0xCB5E # 0 +0xBE99 0xCB5F # 0 +0xBE9A 0xCB60 # 0 +0xBE9B 0xCB61 # 0 +0xBE9C 0xCB62 # 0 +0xBE9D 0xCB63 # 0 +0xBEA1 0xCB64 # 0 +0xBEA2 0xCB65 # 0 +0xBEA3 0xCB66 # 0 +0xBEA4 0xCB67 # 0 +0xBEA5 0xCB68 # 0 +0xBEA6 0xCB69 # 0 +0xBEA7 0xCB6A # 0 +0xBEA8 0xCB6B # 0 +0xBEA9 0xCB6C # 0 +0xBEAA 0xCB6D # 0 +0xBEAB 0xCB6E # 0 +0xBEAC 0xCB6F # 0 +0xBEAD 0xCB70 # 0 +0xBEAE 0xCB71 # 0 +0xBEAF 0xCB72 # 0 +0xBEB0 0xCB73 # 0 +0xBEB1 0xCB74 # 0 +0xBEB3 0xCB75 # 0 +0xBEB4 0xCB76 # 0 +0xBEB5 0xCB77 # 0 +0xBEB6 0xCB78 # 0 +0xBEB7 0xCB79 # 0 +0xBEB8 0xCB7A # 0 +0xBEB9 0xCB7B # 0 +0xBEBA 0xCB7C # 0 +0xBEBB 0xCB7D # 0 +0xBEBC 0xCB7E # 0 +0xBEBD 0xCB7F # 0 +0xBEC1 0xCB80 # 0 +0xBEC2 0xCB81 # 0 +0xBEC3 0xCB82 # 0 +0xBEC4 0xCB83 # 0 +0xBEC5 0xCB84 # 0 +0xBEC6 0xCB85 # 0 +0xBEC7 0xCB86 # 0 +0xBEC8 0xCB87 # 0 +0xBEC9 0xCB88 # 0 +0xBECA 0xCB89 # 0 +0xBECB 0xCB8A # 0 +0xBECC 0xCB8B # 0 +0xBECD 0xCB8C # 0 +0xBECE 0xCB8D # 0 +0xBECF 0xCB8E # 0 +0xBED0 0xCB8F # 0 +0xBED1 0xCB90 # 0 +0xBED3 0xCB91 # 0 +0xBED4 0xCB92 # 0 +0xBED5 0xCB93 # 0 +0xBED6 0xCB94 # 0 +0xBED7 0xCB95 # 0 +0xBED8 0xCB96 # 0 +0xBED9 0xCB97 # 0 +0xBEDA 0xCB98 # 0 +0xBEDB 0xCB99 # 0 +0xBEDC 0xCB9A # 0 +0xBEDD 0xCB9B # 0 +0xBEE1 0xCB9C # 0 +0xBEE2 0xCB9D # 0 +0xBEE3 0xCB9E # 0 +0xBEE4 0xCB9F # 0 +0xBEE5 0xCBA0 # 0 +0xBEE6 0xCBA1 # 0 +0xBEE7 0xCBA2 # 0 +0xBEE8 0xCBA3 # 0 +0xBEE9 0xCBA4 # 0 +0xBEEA 0xCBA5 # 0 +0xBEEB 0xCBA6 # 0 +0xBEEC 0xCBA7 # 0 +0xBEED 0xCBA8 # 0 +0xBEEE 0xCBA9 # 0 +0xBEEF 0xCBAA # 0 +0xBEF0 0xCBAB # 0 +0xBEF1 0xCBAC # 0 +0xBEF3 0xCBAD # 0 +0xBEF4 0xCBAE # 0 +0xBEF5 0xCBAF # 0 +0xBEF6 0xCBB0 # 0 +0xBEF7 0xCBB1 # 0 +0xBEF8 0xCBB2 # 0 +0xBEF9 0xCBB3 # 0 +0xBEFA 0xCBB4 # 0 +0xBEFB 0xCBB5 # 0 +0xBEFC 0xCBB6 # 0 +0xBEFD 0xCBB7 # 0 +0xBF41 0xCBB8 # 0 +0xBF42 0xCBB9 # 0 +0xBF43 0xCBBA # 0 +0xBF44 0xCBBB # 0 +0xBF45 0xCBBC # 0 +0xBF46 0xCBBD # 0 +0xBF47 0xCBBE # 0 +0xBF48 0xCBBF # 0 +0xBF49 0xCBC0 # 0 +0xBF4A 0xCBC1 # 0 +0xBF4B 0xCBC2 # 0 +0xBF4C 0xCBC3 # 0 +0xBF4D 0xCBC4 # 0 +0xBF4E 0xCBC5 # 0 +0xBF4F 0xCBC6 # 0 +0xBF50 0xCBC7 # 0 +0xBF51 0xCBC8 # 0 +0xBF53 0xCBC9 # 0 +0xBF54 0xCBCA # 0 +0xBF55 0xCBCB # 0 +0xBF56 0xCBCC # 0 +0xBF57 0xCBCD # 0 +0xBF58 0xCBCE # 0 +0xBF59 0xCBCF # 0 +0xBF5A 0xCBD0 # 0 +0xBF5B 0xCBD1 # 0 +0xBF5C 0xCBD2 # 0 +0xBF5D 0xCBD3 # 0 +0xBF61 0xCBD4 # 0 +0xBF62 0xCBD5 # 0 +0xBF63 0xCBD6 # 0 +0xBF64 0xCBD7 # 0 +0xBF65 0xCBD8 # 0 +0xBF66 0xCBD9 # 0 +0xBF67 0xCBDA # 0 +0xBF68 0xCBDB # 0 +0xBF69 0xCBDC # 0 +0xBF6A 0xCBDD # 0 +0xBF6B 0xCBDE # 0 +0xBF6C 0xCBDF # 0 +0xBF6D 0xCBE0 # 0 +0xBF6E 0xCBE1 # 0 +0xBF6F 0xCBE2 # 0 +0xBF70 0xCBE3 # 0 +0xBF71 0xCBE4 # 0 +0xBF73 0xCBE5 # 0 +0xBF74 0xCBE6 # 0 +0xBF75 0xCBE7 # 0 +0xBF76 0xCBE8 # 0 +0xBF77 0xCBE9 # 0 +0xBF78 0xCBEA # 0 +0xBF79 0xCBEB # 0 +0xBF7A 0xCBEC # 0 +0xBF7B 0xCBED # 0 +0xBF7C 0xCBEE # 0 +0xBF7D 0xCBEF # 0 +0xBF81 0xCBF0 # 0 +0xBF82 0xCBF1 # 0 +0xBF83 0xCBF2 # 0 +0xBF84 0xCBF3 # 0 +0xBF85 0xCBF4 # 0 +0xBF86 0xCBF5 # 0 +0xBF87 0xCBF6 # 0 +0xBF88 0xCBF7 # 0 +0xBF89 0xCBF8 # 0 +0xBF8A 0xCBF9 # 0 +0xBF8B 0xCBFA # 0 +0xBF8C 0xCBFB # 0 +0xBF8D 0xCBFC # 0 +0xBF8E 0xCBFD # 0 +0xBF8F 0xCBFE # 0 +0xBF90 0xCBFF # 0 +0xBF91 0xCC00 # 0 +0xBF93 0xCC01 # 0 +0xBF94 0xCC02 # 0 +0xBF95 0xCC03 # 0 +0xBF96 0xCC04 # 0 +0xBF97 0xCC05 # 0 +0xBF98 0xCC06 # 0 +0xBF99 0xCC07 # 0 +0xBF9A 0xCC08 # 0 +0xBF9B 0xCC09 # 0 +0xBF9C 0xCC0A # 0 +0xBF9D 0xCC0B # 0 +0xBFA1 0xCC0C # 0 +0xBFA2 0xCC0D # 0 +0xBFA3 0xCC0E # 0 +0xBFA4 0xCC0F # 0 +0xBFA5 0xCC10 # 0 +0xBFA6 0xCC11 # 0 +0xBFA7 0xCC12 # 0 +0xBFA8 0xCC13 # 0 +0xBFA9 0xCC14 # 0 +0xBFAA 0xCC15 # 0 +0xBFAB 0xCC16 # 0 +0xBFAC 0xCC17 # 0 +0xBFAD 0xCC18 # 0 +0xBFAE 0xCC19 # 0 +0xBFAF 0xCC1A # 0 +0xBFB0 0xCC1B # 0 +0xBFB1 0xCC1C # 0 +0xBFB3 0xCC1D # 0 +0xBFB4 0xCC1E # 0 +0xBFB5 0xCC1F # 0 +0xBFB6 0xCC20 # 0 +0xBFB7 0xCC21 # 0 +0xBFB8 0xCC22 # 0 +0xBFB9 0xCC23 # 0 +0xBFBA 0xCC24 # 0 +0xBFBB 0xCC25 # 0 +0xBFBC 0xCC26 # 0 +0xBFBD 0xCC27 # 0 +0xC041 0x110E # 0 +0xC061 0xCC28 # 0 +0xC062 0xCC29 # 0 +0xC063 0xCC2A # 0 +0xC064 0xCC2B # 0 +0xC065 0xCC2C # 0 +0xC066 0xCC2D # 0 +0xC067 0xCC2E # 0 +0xC068 0xCC2F # 0 +0xC069 0xCC30 # 0 +0xC06A 0xCC31 # 0 +0xC06B 0xCC32 # 0 +0xC06C 0xCC33 # 0 +0xC06D 0xCC34 # 0 +0xC06E 0xCC35 # 0 +0xC06F 0xCC36 # 0 +0xC070 0xCC37 # 0 +0xC071 0xCC38 # 0 +0xC073 0xCC39 # 0 +0xC074 0xCC3A # 0 +0xC075 0xCC3B # 0 +0xC076 0xCC3C # 0 +0xC077 0xCC3D # 0 +0xC078 0xCC3E # 0 +0xC079 0xCC3F # 0 +0xC07A 0xCC40 # 0 +0xC07B 0xCC41 # 0 +0xC07C 0xCC42 # 0 +0xC07D 0xCC43 # 0 +0xC081 0xCC44 # 0 +0xC082 0xCC45 # 0 +0xC083 0xCC46 # 0 +0xC084 0xCC47 # 0 +0xC085 0xCC48 # 0 +0xC086 0xCC49 # 0 +0xC087 0xCC4A # 0 +0xC088 0xCC4B # 0 +0xC089 0xCC4C # 0 +0xC08A 0xCC4D # 0 +0xC08B 0xCC4E # 0 +0xC08C 0xCC4F # 0 +0xC08D 0xCC50 # 0 +0xC08E 0xCC51 # 0 +0xC08F 0xCC52 # 0 +0xC090 0xCC53 # 0 +0xC091 0xCC54 # 0 +0xC093 0xCC55 # 0 +0xC094 0xCC56 # 0 +0xC095 0xCC57 # 0 +0xC096 0xCC58 # 0 +0xC097 0xCC59 # 0 +0xC098 0xCC5A # 0 +0xC099 0xCC5B # 0 +0xC09A 0xCC5C # 0 +0xC09B 0xCC5D # 0 +0xC09C 0xCC5E # 0 +0xC09D 0xCC5F # 0 +0xC0A1 0xCC60 # 0 +0xC0A2 0xCC61 # 0 +0xC0A3 0xCC62 # 0 +0xC0A4 0xCC63 # 0 +0xC0A5 0xCC64 # 0 +0xC0A6 0xCC65 # 0 +0xC0A7 0xCC66 # 0 +0xC0A8 0xCC67 # 0 +0xC0A9 0xCC68 # 0 +0xC0AA 0xCC69 # 0 +0xC0AB 0xCC6A # 0 +0xC0AC 0xCC6B # 0 +0xC0AD 0xCC6C # 0 +0xC0AE 0xCC6D # 0 +0xC0AF 0xCC6E # 0 +0xC0B0 0xCC6F # 0 +0xC0B1 0xCC70 # 0 +0xC0B3 0xCC71 # 0 +0xC0B4 0xCC72 # 0 +0xC0B5 0xCC73 # 0 +0xC0B6 0xCC74 # 0 +0xC0B7 0xCC75 # 0 +0xC0B8 0xCC76 # 0 +0xC0B9 0xCC77 # 0 +0xC0BA 0xCC78 # 0 +0xC0BB 0xCC79 # 0 +0xC0BC 0xCC7A # 0 +0xC0BD 0xCC7B # 0 +0xC0C1 0xCC7C # 0 +0xC0C2 0xCC7D # 0 +0xC0C3 0xCC7E # 0 +0xC0C4 0xCC7F # 0 +0xC0C5 0xCC80 # 0 +0xC0C6 0xCC81 # 0 +0xC0C7 0xCC82 # 0 +0xC0C8 0xCC83 # 0 +0xC0C9 0xCC84 # 0 +0xC0CA 0xCC85 # 0 +0xC0CB 0xCC86 # 0 +0xC0CC 0xCC87 # 0 +0xC0CD 0xCC88 # 0 +0xC0CE 0xCC89 # 0 +0xC0CF 0xCC8A # 0 +0xC0D0 0xCC8B # 0 +0xC0D1 0xCC8C # 0 +0xC0D3 0xCC8D # 0 +0xC0D4 0xCC8E # 0 +0xC0D5 0xCC8F # 0 +0xC0D6 0xCC90 # 0 +0xC0D7 0xCC91 # 0 +0xC0D8 0xCC92 # 0 +0xC0D9 0xCC93 # 0 +0xC0DA 0xCC94 # 0 +0xC0DB 0xCC95 # 0 +0xC0DC 0xCC96 # 0 +0xC0DD 0xCC97 # 0 +0xC0E1 0xCC98 # 0 +0xC0E2 0xCC99 # 0 +0xC0E3 0xCC9A # 0 +0xC0E4 0xCC9B # 0 +0xC0E5 0xCC9C # 0 +0xC0E6 0xCC9D # 0 +0xC0E7 0xCC9E # 0 +0xC0E8 0xCC9F # 0 +0xC0E9 0xCCA0 # 0 +0xC0EA 0xCCA1 # 0 +0xC0EB 0xCCA2 # 0 +0xC0EC 0xCCA3 # 0 +0xC0ED 0xCCA4 # 0 +0xC0EE 0xCCA5 # 0 +0xC0EF 0xCCA6 # 0 +0xC0F0 0xCCA7 # 0 +0xC0F1 0xCCA8 # 0 +0xC0F3 0xCCA9 # 0 +0xC0F4 0xCCAA # 0 +0xC0F5 0xCCAB # 0 +0xC0F6 0xCCAC # 0 +0xC0F7 0xCCAD # 0 +0xC0F8 0xCCAE # 0 +0xC0F9 0xCCAF # 0 +0xC0FA 0xCCB0 # 0 +0xC0FB 0xCCB1 # 0 +0xC0FC 0xCCB2 # 0 +0xC0FD 0xCCB3 # 0 +0xC141 0xCCB4 # 0 +0xC142 0xCCB5 # 0 +0xC143 0xCCB6 # 0 +0xC144 0xCCB7 # 0 +0xC145 0xCCB8 # 0 +0xC146 0xCCB9 # 0 +0xC147 0xCCBA # 0 +0xC148 0xCCBB # 0 +0xC149 0xCCBC # 0 +0xC14A 0xCCBD # 0 +0xC14B 0xCCBE # 0 +0xC14C 0xCCBF # 0 +0xC14D 0xCCC0 # 0 +0xC14E 0xCCC1 # 0 +0xC14F 0xCCC2 # 0 +0xC150 0xCCC3 # 0 +0xC151 0xCCC4 # 0 +0xC153 0xCCC5 # 0 +0xC154 0xCCC6 # 0 +0xC155 0xCCC7 # 0 +0xC156 0xCCC8 # 0 +0xC157 0xCCC9 # 0 +0xC158 0xCCCA # 0 +0xC159 0xCCCB # 0 +0xC15A 0xCCCC # 0 +0xC15B 0xCCCD # 0 +0xC15C 0xCCCE # 0 +0xC15D 0xCCCF # 0 +0xC161 0xCCD0 # 0 +0xC162 0xCCD1 # 0 +0xC163 0xCCD2 # 0 +0xC164 0xCCD3 # 0 +0xC165 0xCCD4 # 0 +0xC166 0xCCD5 # 0 +0xC167 0xCCD6 # 0 +0xC168 0xCCD7 # 0 +0xC169 0xCCD8 # 0 +0xC16A 0xCCD9 # 0 +0xC16B 0xCCDA # 0 +0xC16C 0xCCDB # 0 +0xC16D 0xCCDC # 0 +0xC16E 0xCCDD # 0 +0xC16F 0xCCDE # 0 +0xC170 0xCCDF # 0 +0xC171 0xCCE0 # 0 +0xC173 0xCCE1 # 0 +0xC174 0xCCE2 # 0 +0xC175 0xCCE3 # 0 +0xC176 0xCCE4 # 0 +0xC177 0xCCE5 # 0 +0xC178 0xCCE6 # 0 +0xC179 0xCCE7 # 0 +0xC17A 0xCCE8 # 0 +0xC17B 0xCCE9 # 0 +0xC17C 0xCCEA # 0 +0xC17D 0xCCEB # 0 +0xC181 0xCCEC # 0 +0xC182 0xCCED # 0 +0xC183 0xCCEE # 0 +0xC184 0xCCEF # 0 +0xC185 0xCCF0 # 0 +0xC186 0xCCF1 # 0 +0xC187 0xCCF2 # 0 +0xC188 0xCCF3 # 0 +0xC189 0xCCF4 # 0 +0xC18A 0xCCF5 # 0 +0xC18B 0xCCF6 # 0 +0xC18C 0xCCF7 # 0 +0xC18D 0xCCF8 # 0 +0xC18E 0xCCF9 # 0 +0xC18F 0xCCFA # 0 +0xC190 0xCCFB # 0 +0xC191 0xCCFC # 0 +0xC193 0xCCFD # 0 +0xC194 0xCCFE # 0 +0xC195 0xCCFF # 0 +0xC196 0xCD00 # 0 +0xC197 0xCD01 # 0 +0xC198 0xCD02 # 0 +0xC199 0xCD03 # 0 +0xC19A 0xCD04 # 0 +0xC19B 0xCD05 # 0 +0xC19C 0xCD06 # 0 +0xC19D 0xCD07 # 0 +0xC1A1 0xCD08 # 0 +0xC1A2 0xCD09 # 0 +0xC1A3 0xCD0A # 0 +0xC1A4 0xCD0B # 0 +0xC1A5 0xCD0C # 0 +0xC1A6 0xCD0D # 0 +0xC1A7 0xCD0E # 0 +0xC1A8 0xCD0F # 0 +0xC1A9 0xCD10 # 0 +0xC1AA 0xCD11 # 0 +0xC1AB 0xCD12 # 0 +0xC1AC 0xCD13 # 0 +0xC1AD 0xCD14 # 0 +0xC1AE 0xCD15 # 0 +0xC1AF 0xCD16 # 0 +0xC1B0 0xCD17 # 0 +0xC1B1 0xCD18 # 0 +0xC1B3 0xCD19 # 0 +0xC1B4 0xCD1A # 0 +0xC1B5 0xCD1B # 0 +0xC1B6 0xCD1C # 0 +0xC1B7 0xCD1D # 0 +0xC1B8 0xCD1E # 0 +0xC1B9 0xCD1F # 0 +0xC1BA 0xCD20 # 0 +0xC1BB 0xCD21 # 0 +0xC1BC 0xCD22 # 0 +0xC1BD 0xCD23 # 0 +0xC1C1 0xCD24 # 0 +0xC1C2 0xCD25 # 0 +0xC1C3 0xCD26 # 0 +0xC1C4 0xCD27 # 0 +0xC1C5 0xCD28 # 0 +0xC1C6 0xCD29 # 0 +0xC1C7 0xCD2A # 0 +0xC1C8 0xCD2B # 0 +0xC1C9 0xCD2C # 0 +0xC1CA 0xCD2D # 0 +0xC1CB 0xCD2E # 0 +0xC1CC 0xCD2F # 0 +0xC1CD 0xCD30 # 0 +0xC1CE 0xCD31 # 0 +0xC1CF 0xCD32 # 0 +0xC1D0 0xCD33 # 0 +0xC1D1 0xCD34 # 0 +0xC1D3 0xCD35 # 0 +0xC1D4 0xCD36 # 0 +0xC1D5 0xCD37 # 0 +0xC1D6 0xCD38 # 0 +0xC1D7 0xCD39 # 0 +0xC1D8 0xCD3A # 0 +0xC1D9 0xCD3B # 0 +0xC1DA 0xCD3C # 0 +0xC1DB 0xCD3D # 0 +0xC1DC 0xCD3E # 0 +0xC1DD 0xCD3F # 0 +0xC1E1 0xCD40 # 0 +0xC1E2 0xCD41 # 0 +0xC1E3 0xCD42 # 0 +0xC1E4 0xCD43 # 0 +0xC1E5 0xCD44 # 0 +0xC1E6 0xCD45 # 0 +0xC1E7 0xCD46 # 0 +0xC1E8 0xCD47 # 0 +0xC1E9 0xCD48 # 0 +0xC1EA 0xCD49 # 0 +0xC1EB 0xCD4A # 0 +0xC1EC 0xCD4B # 0 +0xC1ED 0xCD4C # 0 +0xC1EE 0xCD4D # 0 +0xC1EF 0xCD4E # 0 +0xC1F0 0xCD4F # 0 +0xC1F1 0xCD50 # 0 +0xC1F3 0xCD51 # 0 +0xC1F4 0xCD52 # 0 +0xC1F5 0xCD53 # 0 +0xC1F6 0xCD54 # 0 +0xC1F7 0xCD55 # 0 +0xC1F8 0xCD56 # 0 +0xC1F9 0xCD57 # 0 +0xC1FA 0xCD58 # 0 +0xC1FB 0xCD59 # 0 +0xC1FC 0xCD5A # 0 +0xC1FD 0xCD5B # 0 +0xC241 0xCD5C # 0 +0xC242 0xCD5D # 0 +0xC243 0xCD5E # 0 +0xC244 0xCD5F # 0 +0xC245 0xCD60 # 0 +0xC246 0xCD61 # 0 +0xC247 0xCD62 # 0 +0xC248 0xCD63 # 0 +0xC249 0xCD64 # 0 +0xC24A 0xCD65 # 0 +0xC24B 0xCD66 # 0 +0xC24C 0xCD67 # 0 +0xC24D 0xCD68 # 0 +0xC24E 0xCD69 # 0 +0xC24F 0xCD6A # 0 +0xC250 0xCD6B # 0 +0xC251 0xCD6C # 0 +0xC253 0xCD6D # 0 +0xC254 0xCD6E # 0 +0xC255 0xCD6F # 0 +0xC256 0xCD70 # 0 +0xC257 0xCD71 # 0 +0xC258 0xCD72 # 0 +0xC259 0xCD73 # 0 +0xC25A 0xCD74 # 0 +0xC25B 0xCD75 # 0 +0xC25C 0xCD76 # 0 +0xC25D 0xCD77 # 0 +0xC261 0xCD78 # 0 +0xC262 0xCD79 # 0 +0xC263 0xCD7A # 0 +0xC264 0xCD7B # 0 +0xC265 0xCD7C # 0 +0xC266 0xCD7D # 0 +0xC267 0xCD7E # 0 +0xC268 0xCD7F # 0 +0xC269 0xCD80 # 0 +0xC26A 0xCD81 # 0 +0xC26B 0xCD82 # 0 +0xC26C 0xCD83 # 0 +0xC26D 0xCD84 # 0 +0xC26E 0xCD85 # 0 +0xC26F 0xCD86 # 0 +0xC270 0xCD87 # 0 +0xC271 0xCD88 # 0 +0xC273 0xCD89 # 0 +0xC274 0xCD8A # 0 +0xC275 0xCD8B # 0 +0xC276 0xCD8C # 0 +0xC277 0xCD8D # 0 +0xC278 0xCD8E # 0 +0xC279 0xCD8F # 0 +0xC27A 0xCD90 # 0 +0xC27B 0xCD91 # 0 +0xC27C 0xCD92 # 0 +0xC27D 0xCD93 # 0 +0xC281 0xCD94 # 0 +0xC282 0xCD95 # 0 +0xC283 0xCD96 # 0 +0xC284 0xCD97 # 0 +0xC285 0xCD98 # 0 +0xC286 0xCD99 # 0 +0xC287 0xCD9A # 0 +0xC288 0xCD9B # 0 +0xC289 0xCD9C # 0 +0xC28A 0xCD9D # 0 +0xC28B 0xCD9E # 0 +0xC28C 0xCD9F # 0 +0xC28D 0xCDA0 # 0 +0xC28E 0xCDA1 # 0 +0xC28F 0xCDA2 # 0 +0xC290 0xCDA3 # 0 +0xC291 0xCDA4 # 0 +0xC293 0xCDA5 # 0 +0xC294 0xCDA6 # 0 +0xC295 0xCDA7 # 0 +0xC296 0xCDA8 # 0 +0xC297 0xCDA9 # 0 +0xC298 0xCDAA # 0 +0xC299 0xCDAB # 0 +0xC29A 0xCDAC # 0 +0xC29B 0xCDAD # 0 +0xC29C 0xCDAE # 0 +0xC29D 0xCDAF # 0 +0xC2A1 0xCDB0 # 0 +0xC2A2 0xCDB1 # 0 +0xC2A3 0xCDB2 # 0 +0xC2A4 0xCDB3 # 0 +0xC2A5 0xCDB4 # 0 +0xC2A6 0xCDB5 # 0 +0xC2A7 0xCDB6 # 0 +0xC2A8 0xCDB7 # 0 +0xC2A9 0xCDB8 # 0 +0xC2AA 0xCDB9 # 0 +0xC2AB 0xCDBA # 0 +0xC2AC 0xCDBB # 0 +0xC2AD 0xCDBC # 0 +0xC2AE 0xCDBD # 0 +0xC2AF 0xCDBE # 0 +0xC2B0 0xCDBF # 0 +0xC2B1 0xCDC0 # 0 +0xC2B3 0xCDC1 # 0 +0xC2B4 0xCDC2 # 0 +0xC2B5 0xCDC3 # 0 +0xC2B6 0xCDC4 # 0 +0xC2B7 0xCDC5 # 0 +0xC2B8 0xCDC6 # 0 +0xC2B9 0xCDC7 # 0 +0xC2BA 0xCDC8 # 0 +0xC2BB 0xCDC9 # 0 +0xC2BC 0xCDCA # 0 +0xC2BD 0xCDCB # 0 +0xC2C1 0xCDCC # 0 +0xC2C2 0xCDCD # 0 +0xC2C3 0xCDCE # 0 +0xC2C4 0xCDCF # 0 +0xC2C5 0xCDD0 # 0 +0xC2C6 0xCDD1 # 0 +0xC2C7 0xCDD2 # 0 +0xC2C8 0xCDD3 # 0 +0xC2C9 0xCDD4 # 0 +0xC2CA 0xCDD5 # 0 +0xC2CB 0xCDD6 # 0 +0xC2CC 0xCDD7 # 0 +0xC2CD 0xCDD8 # 0 +0xC2CE 0xCDD9 # 0 +0xC2CF 0xCDDA # 0 +0xC2D0 0xCDDB # 0 +0xC2D1 0xCDDC # 0 +0xC2D3 0xCDDD # 0 +0xC2D4 0xCDDE # 0 +0xC2D5 0xCDDF # 0 +0xC2D6 0xCDE0 # 0 +0xC2D7 0xCDE1 # 0 +0xC2D8 0xCDE2 # 0 +0xC2D9 0xCDE3 # 0 +0xC2DA 0xCDE4 # 0 +0xC2DB 0xCDE5 # 0 +0xC2DC 0xCDE6 # 0 +0xC2DD 0xCDE7 # 0 +0xC2E1 0xCDE8 # 0 +0xC2E2 0xCDE9 # 0 +0xC2E3 0xCDEA # 0 +0xC2E4 0xCDEB # 0 +0xC2E5 0xCDEC # 0 +0xC2E6 0xCDED # 0 +0xC2E7 0xCDEE # 0 +0xC2E8 0xCDEF # 0 +0xC2E9 0xCDF0 # 0 +0xC2EA 0xCDF1 # 0 +0xC2EB 0xCDF2 # 0 +0xC2EC 0xCDF3 # 0 +0xC2ED 0xCDF4 # 0 +0xC2EE 0xCDF5 # 0 +0xC2EF 0xCDF6 # 0 +0xC2F0 0xCDF7 # 0 +0xC2F1 0xCDF8 # 0 +0xC2F3 0xCDF9 # 0 +0xC2F4 0xCDFA # 0 +0xC2F5 0xCDFB # 0 +0xC2F6 0xCDFC # 0 +0xC2F7 0xCDFD # 0 +0xC2F8 0xCDFE # 0 +0xC2F9 0xCDFF # 0 +0xC2FA 0xCE00 # 0 +0xC2FB 0xCE01 # 0 +0xC2FC 0xCE02 # 0 +0xC2FD 0xCE03 # 0 +0xC341 0xCE04 # 0 +0xC342 0xCE05 # 0 +0xC343 0xCE06 # 0 +0xC344 0xCE07 # 0 +0xC345 0xCE08 # 0 +0xC346 0xCE09 # 0 +0xC347 0xCE0A # 0 +0xC348 0xCE0B # 0 +0xC349 0xCE0C # 0 +0xC34A 0xCE0D # 0 +0xC34B 0xCE0E # 0 +0xC34C 0xCE0F # 0 +0xC34D 0xCE10 # 0 +0xC34E 0xCE11 # 0 +0xC34F 0xCE12 # 0 +0xC350 0xCE13 # 0 +0xC351 0xCE14 # 0 +0xC353 0xCE15 # 0 +0xC354 0xCE16 # 0 +0xC355 0xCE17 # 0 +0xC356 0xCE18 # 0 +0xC357 0xCE19 # 0 +0xC358 0xCE1A # 0 +0xC359 0xCE1B # 0 +0xC35A 0xCE1C # 0 +0xC35B 0xCE1D # 0 +0xC35C 0xCE1E # 0 +0xC35D 0xCE1F # 0 +0xC361 0xCE20 # 0 +0xC362 0xCE21 # 0 +0xC363 0xCE22 # 0 +0xC364 0xCE23 # 0 +0xC365 0xCE24 # 0 +0xC366 0xCE25 # 0 +0xC367 0xCE26 # 0 +0xC368 0xCE27 # 0 +0xC369 0xCE28 # 0 +0xC36A 0xCE29 # 0 +0xC36B 0xCE2A # 0 +0xC36C 0xCE2B # 0 +0xC36D 0xCE2C # 0 +0xC36E 0xCE2D # 0 +0xC36F 0xCE2E # 0 +0xC370 0xCE2F # 0 +0xC371 0xCE30 # 0 +0xC373 0xCE31 # 0 +0xC374 0xCE32 # 0 +0xC375 0xCE33 # 0 +0xC376 0xCE34 # 0 +0xC377 0xCE35 # 0 +0xC378 0xCE36 # 0 +0xC379 0xCE37 # 0 +0xC37A 0xCE38 # 0 +0xC37B 0xCE39 # 0 +0xC37C 0xCE3A # 0 +0xC37D 0xCE3B # 0 +0xC381 0xCE3C # 0 +0xC382 0xCE3D # 0 +0xC383 0xCE3E # 0 +0xC384 0xCE3F # 0 +0xC385 0xCE40 # 0 +0xC386 0xCE41 # 0 +0xC387 0xCE42 # 0 +0xC388 0xCE43 # 0 +0xC389 0xCE44 # 0 +0xC38A 0xCE45 # 0 +0xC38B 0xCE46 # 0 +0xC38C 0xCE47 # 0 +0xC38D 0xCE48 # 0 +0xC38E 0xCE49 # 0 +0xC38F 0xCE4A # 0 +0xC390 0xCE4B # 0 +0xC391 0xCE4C # 0 +0xC393 0xCE4D # 0 +0xC394 0xCE4E # 0 +0xC395 0xCE4F # 0 +0xC396 0xCE50 # 0 +0xC397 0xCE51 # 0 +0xC398 0xCE52 # 0 +0xC399 0xCE53 # 0 +0xC39A 0xCE54 # 0 +0xC39B 0xCE55 # 0 +0xC39C 0xCE56 # 0 +0xC39D 0xCE57 # 0 +0xC3A1 0xCE58 # 0 +0xC3A2 0xCE59 # 0 +0xC3A3 0xCE5A # 0 +0xC3A4 0xCE5B # 0 +0xC3A5 0xCE5C # 0 +0xC3A6 0xCE5D # 0 +0xC3A7 0xCE5E # 0 +0xC3A8 0xCE5F # 0 +0xC3A9 0xCE60 # 0 +0xC3AA 0xCE61 # 0 +0xC3AB 0xCE62 # 0 +0xC3AC 0xCE63 # 0 +0xC3AD 0xCE64 # 0 +0xC3AE 0xCE65 # 0 +0xC3AF 0xCE66 # 0 +0xC3B0 0xCE67 # 0 +0xC3B1 0xCE68 # 0 +0xC3B3 0xCE69 # 0 +0xC3B4 0xCE6A # 0 +0xC3B5 0xCE6B # 0 +0xC3B6 0xCE6C # 0 +0xC3B7 0xCE6D # 0 +0xC3B8 0xCE6E # 0 +0xC3B9 0xCE6F # 0 +0xC3BA 0xCE70 # 0 +0xC3BB 0xCE71 # 0 +0xC3BC 0xCE72 # 0 +0xC3BD 0xCE73 # 0 +0xC441 0x110F # 0 +0xC461 0xCE74 # 0 +0xC462 0xCE75 # 0 +0xC463 0xCE76 # 0 +0xC464 0xCE77 # 0 +0xC465 0xCE78 # 0 +0xC466 0xCE79 # 0 +0xC467 0xCE7A # 0 +0xC468 0xCE7B # 0 +0xC469 0xCE7C # 0 +0xC46A 0xCE7D # 0 +0xC46B 0xCE7E # 0 +0xC46C 0xCE7F # 0 +0xC46D 0xCE80 # 0 +0xC46E 0xCE81 # 0 +0xC46F 0xCE82 # 0 +0xC470 0xCE83 # 0 +0xC471 0xCE84 # 0 +0xC473 0xCE85 # 0 +0xC474 0xCE86 # 0 +0xC475 0xCE87 # 0 +0xC476 0xCE88 # 0 +0xC477 0xCE89 # 0 +0xC478 0xCE8A # 0 +0xC479 0xCE8B # 0 +0xC47A 0xCE8C # 0 +0xC47B 0xCE8D # 0 +0xC47C 0xCE8E # 0 +0xC47D 0xCE8F # 0 +0xC481 0xCE90 # 0 +0xC482 0xCE91 # 0 +0xC483 0xCE92 # 0 +0xC484 0xCE93 # 0 +0xC485 0xCE94 # 0 +0xC486 0xCE95 # 0 +0xC487 0xCE96 # 0 +0xC488 0xCE97 # 0 +0xC489 0xCE98 # 0 +0xC48A 0xCE99 # 0 +0xC48B 0xCE9A # 0 +0xC48C 0xCE9B # 0 +0xC48D 0xCE9C # 0 +0xC48E 0xCE9D # 0 +0xC48F 0xCE9E # 0 +0xC490 0xCE9F # 0 +0xC491 0xCEA0 # 0 +0xC493 0xCEA1 # 0 +0xC494 0xCEA2 # 0 +0xC495 0xCEA3 # 0 +0xC496 0xCEA4 # 0 +0xC497 0xCEA5 # 0 +0xC498 0xCEA6 # 0 +0xC499 0xCEA7 # 0 +0xC49A 0xCEA8 # 0 +0xC49B 0xCEA9 # 0 +0xC49C 0xCEAA # 0 +0xC49D 0xCEAB # 0 +0xC4A1 0xCEAC # 0 +0xC4A2 0xCEAD # 0 +0xC4A3 0xCEAE # 0 +0xC4A4 0xCEAF # 0 +0xC4A5 0xCEB0 # 0 +0xC4A6 0xCEB1 # 0 +0xC4A7 0xCEB2 # 0 +0xC4A8 0xCEB3 # 0 +0xC4A9 0xCEB4 # 0 +0xC4AA 0xCEB5 # 0 +0xC4AB 0xCEB6 # 0 +0xC4AC 0xCEB7 # 0 +0xC4AD 0xCEB8 # 0 +0xC4AE 0xCEB9 # 0 +0xC4AF 0xCEBA # 0 +0xC4B0 0xCEBB # 0 +0xC4B1 0xCEBC # 0 +0xC4B3 0xCEBD # 0 +0xC4B4 0xCEBE # 0 +0xC4B5 0xCEBF # 0 +0xC4B6 0xCEC0 # 0 +0xC4B7 0xCEC1 # 0 +0xC4B8 0xCEC2 # 0 +0xC4B9 0xCEC3 # 0 +0xC4BA 0xCEC4 # 0 +0xC4BB 0xCEC5 # 0 +0xC4BC 0xCEC6 # 0 +0xC4BD 0xCEC7 # 0 +0xC4C1 0xCEC8 # 0 +0xC4C2 0xCEC9 # 0 +0xC4C3 0xCECA # 0 +0xC4C4 0xCECB # 0 +0xC4C5 0xCECC # 0 +0xC4C6 0xCECD # 0 +0xC4C7 0xCECE # 0 +0xC4C8 0xCECF # 0 +0xC4C9 0xCED0 # 0 +0xC4CA 0xCED1 # 0 +0xC4CB 0xCED2 # 0 +0xC4CC 0xCED3 # 0 +0xC4CD 0xCED4 # 0 +0xC4CE 0xCED5 # 0 +0xC4CF 0xCED6 # 0 +0xC4D0 0xCED7 # 0 +0xC4D1 0xCED8 # 0 +0xC4D3 0xCED9 # 0 +0xC4D4 0xCEDA # 0 +0xC4D5 0xCEDB # 0 +0xC4D6 0xCEDC # 0 +0xC4D7 0xCEDD # 0 +0xC4D8 0xCEDE # 0 +0xC4D9 0xCEDF # 0 +0xC4DA 0xCEE0 # 0 +0xC4DB 0xCEE1 # 0 +0xC4DC 0xCEE2 # 0 +0xC4DD 0xCEE3 # 0 +0xC4E1 0xCEE4 # 0 +0xC4E2 0xCEE5 # 0 +0xC4E3 0xCEE6 # 0 +0xC4E4 0xCEE7 # 0 +0xC4E5 0xCEE8 # 0 +0xC4E6 0xCEE9 # 0 +0xC4E7 0xCEEA # 0 +0xC4E8 0xCEEB # 0 +0xC4E9 0xCEEC # 0 +0xC4EA 0xCEED # 0 +0xC4EB 0xCEEE # 0 +0xC4EC 0xCEEF # 0 +0xC4ED 0xCEF0 # 0 +0xC4EE 0xCEF1 # 0 +0xC4EF 0xCEF2 # 0 +0xC4F0 0xCEF3 # 0 +0xC4F1 0xCEF4 # 0 +0xC4F3 0xCEF5 # 0 +0xC4F4 0xCEF6 # 0 +0xC4F5 0xCEF7 # 0 +0xC4F6 0xCEF8 # 0 +0xC4F7 0xCEF9 # 0 +0xC4F8 0xCEFA # 0 +0xC4F9 0xCEFB # 0 +0xC4FA 0xCEFC # 0 +0xC4FB 0xCEFD # 0 +0xC4FC 0xCEFE # 0 +0xC4FD 0xCEFF # 0 +0xC541 0xCF00 # 0 +0xC542 0xCF01 # 0 +0xC543 0xCF02 # 0 +0xC544 0xCF03 # 0 +0xC545 0xCF04 # 0 +0xC546 0xCF05 # 0 +0xC547 0xCF06 # 0 +0xC548 0xCF07 # 0 +0xC549 0xCF08 # 0 +0xC54A 0xCF09 # 0 +0xC54B 0xCF0A # 0 +0xC54C 0xCF0B # 0 +0xC54D 0xCF0C # 0 +0xC54E 0xCF0D # 0 +0xC54F 0xCF0E # 0 +0xC550 0xCF0F # 0 +0xC551 0xCF10 # 0 +0xC553 0xCF11 # 0 +0xC554 0xCF12 # 0 +0xC555 0xCF13 # 0 +0xC556 0xCF14 # 0 +0xC557 0xCF15 # 0 +0xC558 0xCF16 # 0 +0xC559 0xCF17 # 0 +0xC55A 0xCF18 # 0 +0xC55B 0xCF19 # 0 +0xC55C 0xCF1A # 0 +0xC55D 0xCF1B # 0 +0xC561 0xCF1C # 0 +0xC562 0xCF1D # 0 +0xC563 0xCF1E # 0 +0xC564 0xCF1F # 0 +0xC565 0xCF20 # 0 +0xC566 0xCF21 # 0 +0xC567 0xCF22 # 0 +0xC568 0xCF23 # 0 +0xC569 0xCF24 # 0 +0xC56A 0xCF25 # 0 +0xC56B 0xCF26 # 0 +0xC56C 0xCF27 # 0 +0xC56D 0xCF28 # 0 +0xC56E 0xCF29 # 0 +0xC56F 0xCF2A # 0 +0xC570 0xCF2B # 0 +0xC571 0xCF2C # 0 +0xC573 0xCF2D # 0 +0xC574 0xCF2E # 0 +0xC575 0xCF2F # 0 +0xC576 0xCF30 # 0 +0xC577 0xCF31 # 0 +0xC578 0xCF32 # 0 +0xC579 0xCF33 # 0 +0xC57A 0xCF34 # 0 +0xC57B 0xCF35 # 0 +0xC57C 0xCF36 # 0 +0xC57D 0xCF37 # 0 +0xC581 0xCF38 # 0 +0xC582 0xCF39 # 0 +0xC583 0xCF3A # 0 +0xC584 0xCF3B # 0 +0xC585 0xCF3C # 0 +0xC586 0xCF3D # 0 +0xC587 0xCF3E # 0 +0xC588 0xCF3F # 0 +0xC589 0xCF40 # 0 +0xC58A 0xCF41 # 0 +0xC58B 0xCF42 # 0 +0xC58C 0xCF43 # 0 +0xC58D 0xCF44 # 0 +0xC58E 0xCF45 # 0 +0xC58F 0xCF46 # 0 +0xC590 0xCF47 # 0 +0xC591 0xCF48 # 0 +0xC593 0xCF49 # 0 +0xC594 0xCF4A # 0 +0xC595 0xCF4B # 0 +0xC596 0xCF4C # 0 +0xC597 0xCF4D # 0 +0xC598 0xCF4E # 0 +0xC599 0xCF4F # 0 +0xC59A 0xCF50 # 0 +0xC59B 0xCF51 # 0 +0xC59C 0xCF52 # 0 +0xC59D 0xCF53 # 0 +0xC5A1 0xCF54 # 0 +0xC5A2 0xCF55 # 0 +0xC5A3 0xCF56 # 0 +0xC5A4 0xCF57 # 0 +0xC5A5 0xCF58 # 0 +0xC5A6 0xCF59 # 0 +0xC5A7 0xCF5A # 0 +0xC5A8 0xCF5B # 0 +0xC5A9 0xCF5C # 0 +0xC5AA 0xCF5D # 0 +0xC5AB 0xCF5E # 0 +0xC5AC 0xCF5F # 0 +0xC5AD 0xCF60 # 0 +0xC5AE 0xCF61 # 0 +0xC5AF 0xCF62 # 0 +0xC5B0 0xCF63 # 0 +0xC5B1 0xCF64 # 0 +0xC5B3 0xCF65 # 0 +0xC5B4 0xCF66 # 0 +0xC5B5 0xCF67 # 0 +0xC5B6 0xCF68 # 0 +0xC5B7 0xCF69 # 0 +0xC5B8 0xCF6A # 0 +0xC5B9 0xCF6B # 0 +0xC5BA 0xCF6C # 0 +0xC5BB 0xCF6D # 0 +0xC5BC 0xCF6E # 0 +0xC5BD 0xCF6F # 0 +0xC5C1 0xCF70 # 0 +0xC5C2 0xCF71 # 0 +0xC5C3 0xCF72 # 0 +0xC5C4 0xCF73 # 0 +0xC5C5 0xCF74 # 0 +0xC5C6 0xCF75 # 0 +0xC5C7 0xCF76 # 0 +0xC5C8 0xCF77 # 0 +0xC5C9 0xCF78 # 0 +0xC5CA 0xCF79 # 0 +0xC5CB 0xCF7A # 0 +0xC5CC 0xCF7B # 0 +0xC5CD 0xCF7C # 0 +0xC5CE 0xCF7D # 0 +0xC5CF 0xCF7E # 0 +0xC5D0 0xCF7F # 0 +0xC5D1 0xCF80 # 0 +0xC5D3 0xCF81 # 0 +0xC5D4 0xCF82 # 0 +0xC5D5 0xCF83 # 0 +0xC5D6 0xCF84 # 0 +0xC5D7 0xCF85 # 0 +0xC5D8 0xCF86 # 0 +0xC5D9 0xCF87 # 0 +0xC5DA 0xCF88 # 0 +0xC5DB 0xCF89 # 0 +0xC5DC 0xCF8A # 0 +0xC5DD 0xCF8B # 0 +0xC5E1 0xCF8C # 0 +0xC5E2 0xCF8D # 0 +0xC5E3 0xCF8E # 0 +0xC5E4 0xCF8F # 0 +0xC5E5 0xCF90 # 0 +0xC5E6 0xCF91 # 0 +0xC5E7 0xCF92 # 0 +0xC5E8 0xCF93 # 0 +0xC5E9 0xCF94 # 0 +0xC5EA 0xCF95 # 0 +0xC5EB 0xCF96 # 0 +0xC5EC 0xCF97 # 0 +0xC5ED 0xCF98 # 0 +0xC5EE 0xCF99 # 0 +0xC5EF 0xCF9A # 0 +0xC5F0 0xCF9B # 0 +0xC5F1 0xCF9C # 0 +0xC5F3 0xCF9D # 0 +0xC5F4 0xCF9E # 0 +0xC5F5 0xCF9F # 0 +0xC5F6 0xCFA0 # 0 +0xC5F7 0xCFA1 # 0 +0xC5F8 0xCFA2 # 0 +0xC5F9 0xCFA3 # 0 +0xC5FA 0xCFA4 # 0 +0xC5FB 0xCFA5 # 0 +0xC5FC 0xCFA6 # 0 +0xC5FD 0xCFA7 # 0 +0xC641 0xCFA8 # 0 +0xC642 0xCFA9 # 0 +0xC643 0xCFAA # 0 +0xC644 0xCFAB # 0 +0xC645 0xCFAC # 0 +0xC646 0xCFAD # 0 +0xC647 0xCFAE # 0 +0xC648 0xCFAF # 0 +0xC649 0xCFB0 # 0 +0xC64A 0xCFB1 # 0 +0xC64B 0xCFB2 # 0 +0xC64C 0xCFB3 # 0 +0xC64D 0xCFB4 # 0 +0xC64E 0xCFB5 # 0 +0xC64F 0xCFB6 # 0 +0xC650 0xCFB7 # 0 +0xC651 0xCFB8 # 0 +0xC653 0xCFB9 # 0 +0xC654 0xCFBA # 0 +0xC655 0xCFBB # 0 +0xC656 0xCFBC # 0 +0xC657 0xCFBD # 0 +0xC658 0xCFBE # 0 +0xC659 0xCFBF # 0 +0xC65A 0xCFC0 # 0 +0xC65B 0xCFC1 # 0 +0xC65C 0xCFC2 # 0 +0xC65D 0xCFC3 # 0 +0xC661 0xCFC4 # 0 +0xC662 0xCFC5 # 0 +0xC663 0xCFC6 # 0 +0xC664 0xCFC7 # 0 +0xC665 0xCFC8 # 0 +0xC666 0xCFC9 # 0 +0xC667 0xCFCA # 0 +0xC668 0xCFCB # 0 +0xC669 0xCFCC # 0 +0xC66A 0xCFCD # 0 +0xC66B 0xCFCE # 0 +0xC66C 0xCFCF # 0 +0xC66D 0xCFD0 # 0 +0xC66E 0xCFD1 # 0 +0xC66F 0xCFD2 # 0 +0xC670 0xCFD3 # 0 +0xC671 0xCFD4 # 0 +0xC673 0xCFD5 # 0 +0xC674 0xCFD6 # 0 +0xC675 0xCFD7 # 0 +0xC676 0xCFD8 # 0 +0xC677 0xCFD9 # 0 +0xC678 0xCFDA # 0 +0xC679 0xCFDB # 0 +0xC67A 0xCFDC # 0 +0xC67B 0xCFDD # 0 +0xC67C 0xCFDE # 0 +0xC67D 0xCFDF # 0 +0xC681 0xCFE0 # 0 +0xC682 0xCFE1 # 0 +0xC683 0xCFE2 # 0 +0xC684 0xCFE3 # 0 +0xC685 0xCFE4 # 0 +0xC686 0xCFE5 # 0 +0xC687 0xCFE6 # 0 +0xC688 0xCFE7 # 0 +0xC689 0xCFE8 # 0 +0xC68A 0xCFE9 # 0 +0xC68B 0xCFEA # 0 +0xC68C 0xCFEB # 0 +0xC68D 0xCFEC # 0 +0xC68E 0xCFED # 0 +0xC68F 0xCFEE # 0 +0xC690 0xCFEF # 0 +0xC691 0xCFF0 # 0 +0xC693 0xCFF1 # 0 +0xC694 0xCFF2 # 0 +0xC695 0xCFF3 # 0 +0xC696 0xCFF4 # 0 +0xC697 0xCFF5 # 0 +0xC698 0xCFF6 # 0 +0xC699 0xCFF7 # 0 +0xC69A 0xCFF8 # 0 +0xC69B 0xCFF9 # 0 +0xC69C 0xCFFA # 0 +0xC69D 0xCFFB # 0 +0xC6A1 0xCFFC # 0 +0xC6A2 0xCFFD # 0 +0xC6A3 0xCFFE # 0 +0xC6A4 0xCFFF # 0 +0xC6A5 0xD000 # 0 +0xC6A6 0xD001 # 0 +0xC6A7 0xD002 # 0 +0xC6A8 0xD003 # 0 +0xC6A9 0xD004 # 0 +0xC6AA 0xD005 # 0 +0xC6AB 0xD006 # 0 +0xC6AC 0xD007 # 0 +0xC6AD 0xD008 # 0 +0xC6AE 0xD009 # 0 +0xC6AF 0xD00A # 0 +0xC6B0 0xD00B # 0 +0xC6B1 0xD00C # 0 +0xC6B3 0xD00D # 0 +0xC6B4 0xD00E # 0 +0xC6B5 0xD00F # 0 +0xC6B6 0xD010 # 0 +0xC6B7 0xD011 # 0 +0xC6B8 0xD012 # 0 +0xC6B9 0xD013 # 0 +0xC6BA 0xD014 # 0 +0xC6BB 0xD015 # 0 +0xC6BC 0xD016 # 0 +0xC6BD 0xD017 # 0 +0xC6C1 0xD018 # 0 +0xC6C2 0xD019 # 0 +0xC6C3 0xD01A # 0 +0xC6C4 0xD01B # 0 +0xC6C5 0xD01C # 0 +0xC6C6 0xD01D # 0 +0xC6C7 0xD01E # 0 +0xC6C8 0xD01F # 0 +0xC6C9 0xD020 # 0 +0xC6CA 0xD021 # 0 +0xC6CB 0xD022 # 0 +0xC6CC 0xD023 # 0 +0xC6CD 0xD024 # 0 +0xC6CE 0xD025 # 0 +0xC6CF 0xD026 # 0 +0xC6D0 0xD027 # 0 +0xC6D1 0xD028 # 0 +0xC6D3 0xD029 # 0 +0xC6D4 0xD02A # 0 +0xC6D5 0xD02B # 0 +0xC6D6 0xD02C # 0 +0xC6D7 0xD02D # 0 +0xC6D8 0xD02E # 0 +0xC6D9 0xD02F # 0 +0xC6DA 0xD030 # 0 +0xC6DB 0xD031 # 0 +0xC6DC 0xD032 # 0 +0xC6DD 0xD033 # 0 +0xC6E1 0xD034 # 0 +0xC6E2 0xD035 # 0 +0xC6E3 0xD036 # 0 +0xC6E4 0xD037 # 0 +0xC6E5 0xD038 # 0 +0xC6E6 0xD039 # 0 +0xC6E7 0xD03A # 0 +0xC6E8 0xD03B # 0 +0xC6E9 0xD03C # 0 +0xC6EA 0xD03D # 0 +0xC6EB 0xD03E # 0 +0xC6EC 0xD03F # 0 +0xC6ED 0xD040 # 0 +0xC6EE 0xD041 # 0 +0xC6EF 0xD042 # 0 +0xC6F0 0xD043 # 0 +0xC6F1 0xD044 # 0 +0xC6F3 0xD045 # 0 +0xC6F4 0xD046 # 0 +0xC6F5 0xD047 # 0 +0xC6F6 0xD048 # 0 +0xC6F7 0xD049 # 0 +0xC6F8 0xD04A # 0 +0xC6F9 0xD04B # 0 +0xC6FA 0xD04C # 0 +0xC6FB 0xD04D # 0 +0xC6FC 0xD04E # 0 +0xC6FD 0xD04F # 0 +0xC741 0xD050 # 0 +0xC742 0xD051 # 0 +0xC743 0xD052 # 0 +0xC744 0xD053 # 0 +0xC745 0xD054 # 0 +0xC746 0xD055 # 0 +0xC747 0xD056 # 0 +0xC748 0xD057 # 0 +0xC749 0xD058 # 0 +0xC74A 0xD059 # 0 +0xC74B 0xD05A # 0 +0xC74C 0xD05B # 0 +0xC74D 0xD05C # 0 +0xC74E 0xD05D # 0 +0xC74F 0xD05E # 0 +0xC750 0xD05F # 0 +0xC751 0xD060 # 0 +0xC753 0xD061 # 0 +0xC754 0xD062 # 0 +0xC755 0xD063 # 0 +0xC756 0xD064 # 0 +0xC757 0xD065 # 0 +0xC758 0xD066 # 0 +0xC759 0xD067 # 0 +0xC75A 0xD068 # 0 +0xC75B 0xD069 # 0 +0xC75C 0xD06A # 0 +0xC75D 0xD06B # 0 +0xC761 0xD06C # 0 +0xC762 0xD06D # 0 +0xC763 0xD06E # 0 +0xC764 0xD06F # 0 +0xC765 0xD070 # 0 +0xC766 0xD071 # 0 +0xC767 0xD072 # 0 +0xC768 0xD073 # 0 +0xC769 0xD074 # 0 +0xC76A 0xD075 # 0 +0xC76B 0xD076 # 0 +0xC76C 0xD077 # 0 +0xC76D 0xD078 # 0 +0xC76E 0xD079 # 0 +0xC76F 0xD07A # 0 +0xC770 0xD07B # 0 +0xC771 0xD07C # 0 +0xC773 0xD07D # 0 +0xC774 0xD07E # 0 +0xC775 0xD07F # 0 +0xC776 0xD080 # 0 +0xC777 0xD081 # 0 +0xC778 0xD082 # 0 +0xC779 0xD083 # 0 +0xC77A 0xD084 # 0 +0xC77B 0xD085 # 0 +0xC77C 0xD086 # 0 +0xC77D 0xD087 # 0 +0xC781 0xD088 # 0 +0xC782 0xD089 # 0 +0xC783 0xD08A # 0 +0xC784 0xD08B # 0 +0xC785 0xD08C # 0 +0xC786 0xD08D # 0 +0xC787 0xD08E # 0 +0xC788 0xD08F # 0 +0xC789 0xD090 # 0 +0xC78A 0xD091 # 0 +0xC78B 0xD092 # 0 +0xC78C 0xD093 # 0 +0xC78D 0xD094 # 0 +0xC78E 0xD095 # 0 +0xC78F 0xD096 # 0 +0xC790 0xD097 # 0 +0xC791 0xD098 # 0 +0xC793 0xD099 # 0 +0xC794 0xD09A # 0 +0xC795 0xD09B # 0 +0xC796 0xD09C # 0 +0xC797 0xD09D # 0 +0xC798 0xD09E # 0 +0xC799 0xD09F # 0 +0xC79A 0xD0A0 # 0 +0xC79B 0xD0A1 # 0 +0xC79C 0xD0A2 # 0 +0xC79D 0xD0A3 # 0 +0xC7A1 0xD0A4 # 0 +0xC7A2 0xD0A5 # 0 +0xC7A3 0xD0A6 # 0 +0xC7A4 0xD0A7 # 0 +0xC7A5 0xD0A8 # 0 +0xC7A6 0xD0A9 # 0 +0xC7A7 0xD0AA # 0 +0xC7A8 0xD0AB # 0 +0xC7A9 0xD0AC # 0 +0xC7AA 0xD0AD # 0 +0xC7AB 0xD0AE # 0 +0xC7AC 0xD0AF # 0 +0xC7AD 0xD0B0 # 0 +0xC7AE 0xD0B1 # 0 +0xC7AF 0xD0B2 # 0 +0xC7B0 0xD0B3 # 0 +0xC7B1 0xD0B4 # 0 +0xC7B3 0xD0B5 # 0 +0xC7B4 0xD0B6 # 0 +0xC7B5 0xD0B7 # 0 +0xC7B6 0xD0B8 # 0 +0xC7B7 0xD0B9 # 0 +0xC7B8 0xD0BA # 0 +0xC7B9 0xD0BB # 0 +0xC7BA 0xD0BC # 0 +0xC7BB 0xD0BD # 0 +0xC7BC 0xD0BE # 0 +0xC7BD 0xD0BF # 0 +0xC841 0x1110 # 0 +0xC861 0xD0C0 # 0 +0xC862 0xD0C1 # 0 +0xC863 0xD0C2 # 0 +0xC864 0xD0C3 # 0 +0xC865 0xD0C4 # 0 +0xC866 0xD0C5 # 0 +0xC867 0xD0C6 # 0 +0xC868 0xD0C7 # 0 +0xC869 0xD0C8 # 0 +0xC86A 0xD0C9 # 0 +0xC86B 0xD0CA # 0 +0xC86C 0xD0CB # 0 +0xC86D 0xD0CC # 0 +0xC86E 0xD0CD # 0 +0xC86F 0xD0CE # 0 +0xC870 0xD0CF # 0 +0xC871 0xD0D0 # 0 +0xC873 0xD0D1 # 0 +0xC874 0xD0D2 # 0 +0xC875 0xD0D3 # 0 +0xC876 0xD0D4 # 0 +0xC877 0xD0D5 # 0 +0xC878 0xD0D6 # 0 +0xC879 0xD0D7 # 0 +0xC87A 0xD0D8 # 0 +0xC87B 0xD0D9 # 0 +0xC87C 0xD0DA # 0 +0xC87D 0xD0DB # 0 +0xC881 0xD0DC # 0 +0xC882 0xD0DD # 0 +0xC883 0xD0DE # 0 +0xC884 0xD0DF # 0 +0xC885 0xD0E0 # 0 +0xC886 0xD0E1 # 0 +0xC887 0xD0E2 # 0 +0xC888 0xD0E3 # 0 +0xC889 0xD0E4 # 0 +0xC88A 0xD0E5 # 0 +0xC88B 0xD0E6 # 0 +0xC88C 0xD0E7 # 0 +0xC88D 0xD0E8 # 0 +0xC88E 0xD0E9 # 0 +0xC88F 0xD0EA # 0 +0xC890 0xD0EB # 0 +0xC891 0xD0EC # 0 +0xC893 0xD0ED # 0 +0xC894 0xD0EE # 0 +0xC895 0xD0EF # 0 +0xC896 0xD0F0 # 0 +0xC897 0xD0F1 # 0 +0xC898 0xD0F2 # 0 +0xC899 0xD0F3 # 0 +0xC89A 0xD0F4 # 0 +0xC89B 0xD0F5 # 0 +0xC89C 0xD0F6 # 0 +0xC89D 0xD0F7 # 0 +0xC8A1 0xD0F8 # 0 +0xC8A2 0xD0F9 # 0 +0xC8A3 0xD0FA # 0 +0xC8A4 0xD0FB # 0 +0xC8A5 0xD0FC # 0 +0xC8A6 0xD0FD # 0 +0xC8A7 0xD0FE # 0 +0xC8A8 0xD0FF # 0 +0xC8A9 0xD100 # 0 +0xC8AA 0xD101 # 0 +0xC8AB 0xD102 # 0 +0xC8AC 0xD103 # 0 +0xC8AD 0xD104 # 0 +0xC8AE 0xD105 # 0 +0xC8AF 0xD106 # 0 +0xC8B0 0xD107 # 0 +0xC8B1 0xD108 # 0 +0xC8B3 0xD109 # 0 +0xC8B4 0xD10A # 0 +0xC8B5 0xD10B # 0 +0xC8B6 0xD10C # 0 +0xC8B7 0xD10D # 0 +0xC8B8 0xD10E # 0 +0xC8B9 0xD10F # 0 +0xC8BA 0xD110 # 0 +0xC8BB 0xD111 # 0 +0xC8BC 0xD112 # 0 +0xC8BD 0xD113 # 0 +0xC8C1 0xD114 # 0 +0xC8C2 0xD115 # 0 +0xC8C3 0xD116 # 0 +0xC8C4 0xD117 # 0 +0xC8C5 0xD118 # 0 +0xC8C6 0xD119 # 0 +0xC8C7 0xD11A # 0 +0xC8C8 0xD11B # 0 +0xC8C9 0xD11C # 0 +0xC8CA 0xD11D # 0 +0xC8CB 0xD11E # 0 +0xC8CC 0xD11F # 0 +0xC8CD 0xD120 # 0 +0xC8CE 0xD121 # 0 +0xC8CF 0xD122 # 0 +0xC8D0 0xD123 # 0 +0xC8D1 0xD124 # 0 +0xC8D3 0xD125 # 0 +0xC8D4 0xD126 # 0 +0xC8D5 0xD127 # 0 +0xC8D6 0xD128 # 0 +0xC8D7 0xD129 # 0 +0xC8D8 0xD12A # 0 +0xC8D9 0xD12B # 0 +0xC8DA 0xD12C # 0 +0xC8DB 0xD12D # 0 +0xC8DC 0xD12E # 0 +0xC8DD 0xD12F # 0 +0xC8E1 0xD130 # 0 +0xC8E2 0xD131 # 0 +0xC8E3 0xD132 # 0 +0xC8E4 0xD133 # 0 +0xC8E5 0xD134 # 0 +0xC8E6 0xD135 # 0 +0xC8E7 0xD136 # 0 +0xC8E8 0xD137 # 0 +0xC8E9 0xD138 # 0 +0xC8EA 0xD139 # 0 +0xC8EB 0xD13A # 0 +0xC8EC 0xD13B # 0 +0xC8ED 0xD13C # 0 +0xC8EE 0xD13D # 0 +0xC8EF 0xD13E # 0 +0xC8F0 0xD13F # 0 +0xC8F1 0xD140 # 0 +0xC8F3 0xD141 # 0 +0xC8F4 0xD142 # 0 +0xC8F5 0xD143 # 0 +0xC8F6 0xD144 # 0 +0xC8F7 0xD145 # 0 +0xC8F8 0xD146 # 0 +0xC8F9 0xD147 # 0 +0xC8FA 0xD148 # 0 +0xC8FB 0xD149 # 0 +0xC8FC 0xD14A # 0 +0xC8FD 0xD14B # 0 +0xC941 0xD14C # 0 +0xC942 0xD14D # 0 +0xC943 0xD14E # 0 +0xC944 0xD14F # 0 +0xC945 0xD150 # 0 +0xC946 0xD151 # 0 +0xC947 0xD152 # 0 +0xC948 0xD153 # 0 +0xC949 0xD154 # 0 +0xC94A 0xD155 # 0 +0xC94B 0xD156 # 0 +0xC94C 0xD157 # 0 +0xC94D 0xD158 # 0 +0xC94E 0xD159 # 0 +0xC94F 0xD15A # 0 +0xC950 0xD15B # 0 +0xC951 0xD15C # 0 +0xC953 0xD15D # 0 +0xC954 0xD15E # 0 +0xC955 0xD15F # 0 +0xC956 0xD160 # 0 +0xC957 0xD161 # 0 +0xC958 0xD162 # 0 +0xC959 0xD163 # 0 +0xC95A 0xD164 # 0 +0xC95B 0xD165 # 0 +0xC95C 0xD166 # 0 +0xC95D 0xD167 # 0 +0xC961 0xD168 # 0 +0xC962 0xD169 # 0 +0xC963 0xD16A # 0 +0xC964 0xD16B # 0 +0xC965 0xD16C # 0 +0xC966 0xD16D # 0 +0xC967 0xD16E # 0 +0xC968 0xD16F # 0 +0xC969 0xD170 # 0 +0xC96A 0xD171 # 0 +0xC96B 0xD172 # 0 +0xC96C 0xD173 # 0 +0xC96D 0xD174 # 0 +0xC96E 0xD175 # 0 +0xC96F 0xD176 # 0 +0xC970 0xD177 # 0 +0xC971 0xD178 # 0 +0xC973 0xD179 # 0 +0xC974 0xD17A # 0 +0xC975 0xD17B # 0 +0xC976 0xD17C # 0 +0xC977 0xD17D # 0 +0xC978 0xD17E # 0 +0xC979 0xD17F # 0 +0xC97A 0xD180 # 0 +0xC97B 0xD181 # 0 +0xC97C 0xD182 # 0 +0xC97D 0xD183 # 0 +0xC981 0xD184 # 0 +0xC982 0xD185 # 0 +0xC983 0xD186 # 0 +0xC984 0xD187 # 0 +0xC985 0xD188 # 0 +0xC986 0xD189 # 0 +0xC987 0xD18A # 0 +0xC988 0xD18B # 0 +0xC989 0xD18C # 0 +0xC98A 0xD18D # 0 +0xC98B 0xD18E # 0 +0xC98C 0xD18F # 0 +0xC98D 0xD190 # 0 +0xC98E 0xD191 # 0 +0xC98F 0xD192 # 0 +0xC990 0xD193 # 0 +0xC991 0xD194 # 0 +0xC993 0xD195 # 0 +0xC994 0xD196 # 0 +0xC995 0xD197 # 0 +0xC996 0xD198 # 0 +0xC997 0xD199 # 0 +0xC998 0xD19A # 0 +0xC999 0xD19B # 0 +0xC99A 0xD19C # 0 +0xC99B 0xD19D # 0 +0xC99C 0xD19E # 0 +0xC99D 0xD19F # 0 +0xC9A1 0xD1A0 # 0 +0xC9A2 0xD1A1 # 0 +0xC9A3 0xD1A2 # 0 +0xC9A4 0xD1A3 # 0 +0xC9A5 0xD1A4 # 0 +0xC9A6 0xD1A5 # 0 +0xC9A7 0xD1A6 # 0 +0xC9A8 0xD1A7 # 0 +0xC9A9 0xD1A8 # 0 +0xC9AA 0xD1A9 # 0 +0xC9AB 0xD1AA # 0 +0xC9AC 0xD1AB # 0 +0xC9AD 0xD1AC # 0 +0xC9AE 0xD1AD # 0 +0xC9AF 0xD1AE # 0 +0xC9B0 0xD1AF # 0 +0xC9B1 0xD1B0 # 0 +0xC9B3 0xD1B1 # 0 +0xC9B4 0xD1B2 # 0 +0xC9B5 0xD1B3 # 0 +0xC9B6 0xD1B4 # 0 +0xC9B7 0xD1B5 # 0 +0xC9B8 0xD1B6 # 0 +0xC9B9 0xD1B7 # 0 +0xC9BA 0xD1B8 # 0 +0xC9BB 0xD1B9 # 0 +0xC9BC 0xD1BA # 0 +0xC9BD 0xD1BB # 0 +0xC9C1 0xD1BC # 0 +0xC9C2 0xD1BD # 0 +0xC9C3 0xD1BE # 0 +0xC9C4 0xD1BF # 0 +0xC9C5 0xD1C0 # 0 +0xC9C6 0xD1C1 # 0 +0xC9C7 0xD1C2 # 0 +0xC9C8 0xD1C3 # 0 +0xC9C9 0xD1C4 # 0 +0xC9CA 0xD1C5 # 0 +0xC9CB 0xD1C6 # 0 +0xC9CC 0xD1C7 # 0 +0xC9CD 0xD1C8 # 0 +0xC9CE 0xD1C9 # 0 +0xC9CF 0xD1CA # 0 +0xC9D0 0xD1CB # 0 +0xC9D1 0xD1CC # 0 +0xC9D3 0xD1CD # 0 +0xC9D4 0xD1CE # 0 +0xC9D5 0xD1CF # 0 +0xC9D6 0xD1D0 # 0 +0xC9D7 0xD1D1 # 0 +0xC9D8 0xD1D2 # 0 +0xC9D9 0xD1D3 # 0 +0xC9DA 0xD1D4 # 0 +0xC9DB 0xD1D5 # 0 +0xC9DC 0xD1D6 # 0 +0xC9DD 0xD1D7 # 0 +0xC9E1 0xD1D8 # 0 +0xC9E2 0xD1D9 # 0 +0xC9E3 0xD1DA # 0 +0xC9E4 0xD1DB # 0 +0xC9E5 0xD1DC # 0 +0xC9E6 0xD1DD # 0 +0xC9E7 0xD1DE # 0 +0xC9E8 0xD1DF # 0 +0xC9E9 0xD1E0 # 0 +0xC9EA 0xD1E1 # 0 +0xC9EB 0xD1E2 # 0 +0xC9EC 0xD1E3 # 0 +0xC9ED 0xD1E4 # 0 +0xC9EE 0xD1E5 # 0 +0xC9EF 0xD1E6 # 0 +0xC9F0 0xD1E7 # 0 +0xC9F1 0xD1E8 # 0 +0xC9F3 0xD1E9 # 0 +0xC9F4 0xD1EA # 0 +0xC9F5 0xD1EB # 0 +0xC9F6 0xD1EC # 0 +0xC9F7 0xD1ED # 0 +0xC9F8 0xD1EE # 0 +0xC9F9 0xD1EF # 0 +0xC9FA 0xD1F0 # 0 +0xC9FB 0xD1F1 # 0 +0xC9FC 0xD1F2 # 0 +0xC9FD 0xD1F3 # 0 +0xCA41 0xD1F4 # 0 +0xCA42 0xD1F5 # 0 +0xCA43 0xD1F6 # 0 +0xCA44 0xD1F7 # 0 +0xCA45 0xD1F8 # 0 +0xCA46 0xD1F9 # 0 +0xCA47 0xD1FA # 0 +0xCA48 0xD1FB # 0 +0xCA49 0xD1FC # 0 +0xCA4A 0xD1FD # 0 +0xCA4B 0xD1FE # 0 +0xCA4C 0xD1FF # 0 +0xCA4D 0xD200 # 0 +0xCA4E 0xD201 # 0 +0xCA4F 0xD202 # 0 +0xCA50 0xD203 # 0 +0xCA51 0xD204 # 0 +0xCA53 0xD205 # 0 +0xCA54 0xD206 # 0 +0xCA55 0xD207 # 0 +0xCA56 0xD208 # 0 +0xCA57 0xD209 # 0 +0xCA58 0xD20A # 0 +0xCA59 0xD20B # 0 +0xCA5A 0xD20C # 0 +0xCA5B 0xD20D # 0 +0xCA5C 0xD20E # 0 +0xCA5D 0xD20F # 0 +0xCA61 0xD210 # 0 +0xCA62 0xD211 # 0 +0xCA63 0xD212 # 0 +0xCA64 0xD213 # 0 +0xCA65 0xD214 # 0 +0xCA66 0xD215 # 0 +0xCA67 0xD216 # 0 +0xCA68 0xD217 # 0 +0xCA69 0xD218 # 0 +0xCA6A 0xD219 # 0 +0xCA6B 0xD21A # 0 +0xCA6C 0xD21B # 0 +0xCA6D 0xD21C # 0 +0xCA6E 0xD21D # 0 +0xCA6F 0xD21E # 0 +0xCA70 0xD21F # 0 +0xCA71 0xD220 # 0 +0xCA73 0xD221 # 0 +0xCA74 0xD222 # 0 +0xCA75 0xD223 # 0 +0xCA76 0xD224 # 0 +0xCA77 0xD225 # 0 +0xCA78 0xD226 # 0 +0xCA79 0xD227 # 0 +0xCA7A 0xD228 # 0 +0xCA7B 0xD229 # 0 +0xCA7C 0xD22A # 0 +0xCA7D 0xD22B # 0 +0xCA81 0xD22C # 0 +0xCA82 0xD22D # 0 +0xCA83 0xD22E # 0 +0xCA84 0xD22F # 0 +0xCA85 0xD230 # 0 +0xCA86 0xD231 # 0 +0xCA87 0xD232 # 0 +0xCA88 0xD233 # 0 +0xCA89 0xD234 # 0 +0xCA8A 0xD235 # 0 +0xCA8B 0xD236 # 0 +0xCA8C 0xD237 # 0 +0xCA8D 0xD238 # 0 +0xCA8E 0xD239 # 0 +0xCA8F 0xD23A # 0 +0xCA90 0xD23B # 0 +0xCA91 0xD23C # 0 +0xCA93 0xD23D # 0 +0xCA94 0xD23E # 0 +0xCA95 0xD23F # 0 +0xCA96 0xD240 # 0 +0xCA97 0xD241 # 0 +0xCA98 0xD242 # 0 +0xCA99 0xD243 # 0 +0xCA9A 0xD244 # 0 +0xCA9B 0xD245 # 0 +0xCA9C 0xD246 # 0 +0xCA9D 0xD247 # 0 +0xCAA1 0xD248 # 0 +0xCAA2 0xD249 # 0 +0xCAA3 0xD24A # 0 +0xCAA4 0xD24B # 0 +0xCAA5 0xD24C # 0 +0xCAA6 0xD24D # 0 +0xCAA7 0xD24E # 0 +0xCAA8 0xD24F # 0 +0xCAA9 0xD250 # 0 +0xCAAA 0xD251 # 0 +0xCAAB 0xD252 # 0 +0xCAAC 0xD253 # 0 +0xCAAD 0xD254 # 0 +0xCAAE 0xD255 # 0 +0xCAAF 0xD256 # 0 +0xCAB0 0xD257 # 0 +0xCAB1 0xD258 # 0 +0xCAB3 0xD259 # 0 +0xCAB4 0xD25A # 0 +0xCAB5 0xD25B # 0 +0xCAB6 0xD25C # 0 +0xCAB7 0xD25D # 0 +0xCAB8 0xD25E # 0 +0xCAB9 0xD25F # 0 +0xCABA 0xD260 # 0 +0xCABB 0xD261 # 0 +0xCABC 0xD262 # 0 +0xCABD 0xD263 # 0 +0xCAC1 0xD264 # 0 +0xCAC2 0xD265 # 0 +0xCAC3 0xD266 # 0 +0xCAC4 0xD267 # 0 +0xCAC5 0xD268 # 0 +0xCAC6 0xD269 # 0 +0xCAC7 0xD26A # 0 +0xCAC8 0xD26B # 0 +0xCAC9 0xD26C # 0 +0xCACA 0xD26D # 0 +0xCACB 0xD26E # 0 +0xCACC 0xD26F # 0 +0xCACD 0xD270 # 0 +0xCACE 0xD271 # 0 +0xCACF 0xD272 # 0 +0xCAD0 0xD273 # 0 +0xCAD1 0xD274 # 0 +0xCAD3 0xD275 # 0 +0xCAD4 0xD276 # 0 +0xCAD5 0xD277 # 0 +0xCAD6 0xD278 # 0 +0xCAD7 0xD279 # 0 +0xCAD8 0xD27A # 0 +0xCAD9 0xD27B # 0 +0xCADA 0xD27C # 0 +0xCADB 0xD27D # 0 +0xCADC 0xD27E # 0 +0xCADD 0xD27F # 0 +0xCAE1 0xD280 # 0 +0xCAE2 0xD281 # 0 +0xCAE3 0xD282 # 0 +0xCAE4 0xD283 # 0 +0xCAE5 0xD284 # 0 +0xCAE6 0xD285 # 0 +0xCAE7 0xD286 # 0 +0xCAE8 0xD287 # 0 +0xCAE9 0xD288 # 0 +0xCAEA 0xD289 # 0 +0xCAEB 0xD28A # 0 +0xCAEC 0xD28B # 0 +0xCAED 0xD28C # 0 +0xCAEE 0xD28D # 0 +0xCAEF 0xD28E # 0 +0xCAF0 0xD28F # 0 +0xCAF1 0xD290 # 0 +0xCAF3 0xD291 # 0 +0xCAF4 0xD292 # 0 +0xCAF5 0xD293 # 0 +0xCAF6 0xD294 # 0 +0xCAF7 0xD295 # 0 +0xCAF8 0xD296 # 0 +0xCAF9 0xD297 # 0 +0xCAFA 0xD298 # 0 +0xCAFB 0xD299 # 0 +0xCAFC 0xD29A # 0 +0xCAFD 0xD29B # 0 +0xCB41 0xD29C # 0 +0xCB42 0xD29D # 0 +0xCB43 0xD29E # 0 +0xCB44 0xD29F # 0 +0xCB45 0xD2A0 # 0 +0xCB46 0xD2A1 # 0 +0xCB47 0xD2A2 # 0 +0xCB48 0xD2A3 # 0 +0xCB49 0xD2A4 # 0 +0xCB4A 0xD2A5 # 0 +0xCB4B 0xD2A6 # 0 +0xCB4C 0xD2A7 # 0 +0xCB4D 0xD2A8 # 0 +0xCB4E 0xD2A9 # 0 +0xCB4F 0xD2AA # 0 +0xCB50 0xD2AB # 0 +0xCB51 0xD2AC # 0 +0xCB53 0xD2AD # 0 +0xCB54 0xD2AE # 0 +0xCB55 0xD2AF # 0 +0xCB56 0xD2B0 # 0 +0xCB57 0xD2B1 # 0 +0xCB58 0xD2B2 # 0 +0xCB59 0xD2B3 # 0 +0xCB5A 0xD2B4 # 0 +0xCB5B 0xD2B5 # 0 +0xCB5C 0xD2B6 # 0 +0xCB5D 0xD2B7 # 0 +0xCB61 0xD2B8 # 0 +0xCB62 0xD2B9 # 0 +0xCB63 0xD2BA # 0 +0xCB64 0xD2BB # 0 +0xCB65 0xD2BC # 0 +0xCB66 0xD2BD # 0 +0xCB67 0xD2BE # 0 +0xCB68 0xD2BF # 0 +0xCB69 0xD2C0 # 0 +0xCB6A 0xD2C1 # 0 +0xCB6B 0xD2C2 # 0 +0xCB6C 0xD2C3 # 0 +0xCB6D 0xD2C4 # 0 +0xCB6E 0xD2C5 # 0 +0xCB6F 0xD2C6 # 0 +0xCB70 0xD2C7 # 0 +0xCB71 0xD2C8 # 0 +0xCB73 0xD2C9 # 0 +0xCB74 0xD2CA # 0 +0xCB75 0xD2CB # 0 +0xCB76 0xD2CC # 0 +0xCB77 0xD2CD # 0 +0xCB78 0xD2CE # 0 +0xCB79 0xD2CF # 0 +0xCB7A 0xD2D0 # 0 +0xCB7B 0xD2D1 # 0 +0xCB7C 0xD2D2 # 0 +0xCB7D 0xD2D3 # 0 +0xCB81 0xD2D4 # 0 +0xCB82 0xD2D5 # 0 +0xCB83 0xD2D6 # 0 +0xCB84 0xD2D7 # 0 +0xCB85 0xD2D8 # 0 +0xCB86 0xD2D9 # 0 +0xCB87 0xD2DA # 0 +0xCB88 0xD2DB # 0 +0xCB89 0xD2DC # 0 +0xCB8A 0xD2DD # 0 +0xCB8B 0xD2DE # 0 +0xCB8C 0xD2DF # 0 +0xCB8D 0xD2E0 # 0 +0xCB8E 0xD2E1 # 0 +0xCB8F 0xD2E2 # 0 +0xCB90 0xD2E3 # 0 +0xCB91 0xD2E4 # 0 +0xCB93 0xD2E5 # 0 +0xCB94 0xD2E6 # 0 +0xCB95 0xD2E7 # 0 +0xCB96 0xD2E8 # 0 +0xCB97 0xD2E9 # 0 +0xCB98 0xD2EA # 0 +0xCB99 0xD2EB # 0 +0xCB9A 0xD2EC # 0 +0xCB9B 0xD2ED # 0 +0xCB9C 0xD2EE # 0 +0xCB9D 0xD2EF # 0 +0xCBA1 0xD2F0 # 0 +0xCBA2 0xD2F1 # 0 +0xCBA3 0xD2F2 # 0 +0xCBA4 0xD2F3 # 0 +0xCBA5 0xD2F4 # 0 +0xCBA6 0xD2F5 # 0 +0xCBA7 0xD2F6 # 0 +0xCBA8 0xD2F7 # 0 +0xCBA9 0xD2F8 # 0 +0xCBAA 0xD2F9 # 0 +0xCBAB 0xD2FA # 0 +0xCBAC 0xD2FB # 0 +0xCBAD 0xD2FC # 0 +0xCBAE 0xD2FD # 0 +0xCBAF 0xD2FE # 0 +0xCBB0 0xD2FF # 0 +0xCBB1 0xD300 # 0 +0xCBB3 0xD301 # 0 +0xCBB4 0xD302 # 0 +0xCBB5 0xD303 # 0 +0xCBB6 0xD304 # 0 +0xCBB7 0xD305 # 0 +0xCBB8 0xD306 # 0 +0xCBB9 0xD307 # 0 +0xCBBA 0xD308 # 0 +0xCBBB 0xD309 # 0 +0xCBBC 0xD30A # 0 +0xCBBD 0xD30B # 0 +0xCC41 0x1111 # 0 +0xCC61 0xD30C # 0 +0xCC62 0xD30D # 0 +0xCC63 0xD30E # 0 +0xCC64 0xD30F # 0 +0xCC65 0xD310 # 0 +0xCC66 0xD311 # 0 +0xCC67 0xD312 # 0 +0xCC68 0xD313 # 0 +0xCC69 0xD314 # 0 +0xCC6A 0xD315 # 0 +0xCC6B 0xD316 # 0 +0xCC6C 0xD317 # 0 +0xCC6D 0xD318 # 0 +0xCC6E 0xD319 # 0 +0xCC6F 0xD31A # 0 +0xCC70 0xD31B # 0 +0xCC71 0xD31C # 0 +0xCC73 0xD31D # 0 +0xCC74 0xD31E # 0 +0xCC75 0xD31F # 0 +0xCC76 0xD320 # 0 +0xCC77 0xD321 # 0 +0xCC78 0xD322 # 0 +0xCC79 0xD323 # 0 +0xCC7A 0xD324 # 0 +0xCC7B 0xD325 # 0 +0xCC7C 0xD326 # 0 +0xCC7D 0xD327 # 0 +0xCC81 0xD328 # 0 +0xCC82 0xD329 # 0 +0xCC83 0xD32A # 0 +0xCC84 0xD32B # 0 +0xCC85 0xD32C # 0 +0xCC86 0xD32D # 0 +0xCC87 0xD32E # 0 +0xCC88 0xD32F # 0 +0xCC89 0xD330 # 0 +0xCC8A 0xD331 # 0 +0xCC8B 0xD332 # 0 +0xCC8C 0xD333 # 0 +0xCC8D 0xD334 # 0 +0xCC8E 0xD335 # 0 +0xCC8F 0xD336 # 0 +0xCC90 0xD337 # 0 +0xCC91 0xD338 # 0 +0xCC93 0xD339 # 0 +0xCC94 0xD33A # 0 +0xCC95 0xD33B # 0 +0xCC96 0xD33C # 0 +0xCC97 0xD33D # 0 +0xCC98 0xD33E # 0 +0xCC99 0xD33F # 0 +0xCC9A 0xD340 # 0 +0xCC9B 0xD341 # 0 +0xCC9C 0xD342 # 0 +0xCC9D 0xD343 # 0 +0xCCA1 0xD344 # 0 +0xCCA2 0xD345 # 0 +0xCCA3 0xD346 # 0 +0xCCA4 0xD347 # 0 +0xCCA5 0xD348 # 0 +0xCCA6 0xD349 # 0 +0xCCA7 0xD34A # 0 +0xCCA8 0xD34B # 0 +0xCCA9 0xD34C # 0 +0xCCAA 0xD34D # 0 +0xCCAB 0xD34E # 0 +0xCCAC 0xD34F # 0 +0xCCAD 0xD350 # 0 +0xCCAE 0xD351 # 0 +0xCCAF 0xD352 # 0 +0xCCB0 0xD353 # 0 +0xCCB1 0xD354 # 0 +0xCCB3 0xD355 # 0 +0xCCB4 0xD356 # 0 +0xCCB5 0xD357 # 0 +0xCCB6 0xD358 # 0 +0xCCB7 0xD359 # 0 +0xCCB8 0xD35A # 0 +0xCCB9 0xD35B # 0 +0xCCBA 0xD35C # 0 +0xCCBB 0xD35D # 0 +0xCCBC 0xD35E # 0 +0xCCBD 0xD35F # 0 +0xCCC1 0xD360 # 0 +0xCCC2 0xD361 # 0 +0xCCC3 0xD362 # 0 +0xCCC4 0xD363 # 0 +0xCCC5 0xD364 # 0 +0xCCC6 0xD365 # 0 +0xCCC7 0xD366 # 0 +0xCCC8 0xD367 # 0 +0xCCC9 0xD368 # 0 +0xCCCA 0xD369 # 0 +0xCCCB 0xD36A # 0 +0xCCCC 0xD36B # 0 +0xCCCD 0xD36C # 0 +0xCCCE 0xD36D # 0 +0xCCCF 0xD36E # 0 +0xCCD0 0xD36F # 0 +0xCCD1 0xD370 # 0 +0xCCD3 0xD371 # 0 +0xCCD4 0xD372 # 0 +0xCCD5 0xD373 # 0 +0xCCD6 0xD374 # 0 +0xCCD7 0xD375 # 0 +0xCCD8 0xD376 # 0 +0xCCD9 0xD377 # 0 +0xCCDA 0xD378 # 0 +0xCCDB 0xD379 # 0 +0xCCDC 0xD37A # 0 +0xCCDD 0xD37B # 0 +0xCCE1 0xD37C # 0 +0xCCE2 0xD37D # 0 +0xCCE3 0xD37E # 0 +0xCCE4 0xD37F # 0 +0xCCE5 0xD380 # 0 +0xCCE6 0xD381 # 0 +0xCCE7 0xD382 # 0 +0xCCE8 0xD383 # 0 +0xCCE9 0xD384 # 0 +0xCCEA 0xD385 # 0 +0xCCEB 0xD386 # 0 +0xCCEC 0xD387 # 0 +0xCCED 0xD388 # 0 +0xCCEE 0xD389 # 0 +0xCCEF 0xD38A # 0 +0xCCF0 0xD38B # 0 +0xCCF1 0xD38C # 0 +0xCCF3 0xD38D # 0 +0xCCF4 0xD38E # 0 +0xCCF5 0xD38F # 0 +0xCCF6 0xD390 # 0 +0xCCF7 0xD391 # 0 +0xCCF8 0xD392 # 0 +0xCCF9 0xD393 # 0 +0xCCFA 0xD394 # 0 +0xCCFB 0xD395 # 0 +0xCCFC 0xD396 # 0 +0xCCFD 0xD397 # 0 +0xCD41 0xD398 # 0 +0xCD42 0xD399 # 0 +0xCD43 0xD39A # 0 +0xCD44 0xD39B # 0 +0xCD45 0xD39C # 0 +0xCD46 0xD39D # 0 +0xCD47 0xD39E # 0 +0xCD48 0xD39F # 0 +0xCD49 0xD3A0 # 0 +0xCD4A 0xD3A1 # 0 +0xCD4B 0xD3A2 # 0 +0xCD4C 0xD3A3 # 0 +0xCD4D 0xD3A4 # 0 +0xCD4E 0xD3A5 # 0 +0xCD4F 0xD3A6 # 0 +0xCD50 0xD3A7 # 0 +0xCD51 0xD3A8 # 0 +0xCD53 0xD3A9 # 0 +0xCD54 0xD3AA # 0 +0xCD55 0xD3AB # 0 +0xCD56 0xD3AC # 0 +0xCD57 0xD3AD # 0 +0xCD58 0xD3AE # 0 +0xCD59 0xD3AF # 0 +0xCD5A 0xD3B0 # 0 +0xCD5B 0xD3B1 # 0 +0xCD5C 0xD3B2 # 0 +0xCD5D 0xD3B3 # 0 +0xCD61 0xD3B4 # 0 +0xCD62 0xD3B5 # 0 +0xCD63 0xD3B6 # 0 +0xCD64 0xD3B7 # 0 +0xCD65 0xD3B8 # 0 +0xCD66 0xD3B9 # 0 +0xCD67 0xD3BA # 0 +0xCD68 0xD3BB # 0 +0xCD69 0xD3BC # 0 +0xCD6A 0xD3BD # 0 +0xCD6B 0xD3BE # 0 +0xCD6C 0xD3BF # 0 +0xCD6D 0xD3C0 # 0 +0xCD6E 0xD3C1 # 0 +0xCD6F 0xD3C2 # 0 +0xCD70 0xD3C3 # 0 +0xCD71 0xD3C4 # 0 +0xCD73 0xD3C5 # 0 +0xCD74 0xD3C6 # 0 +0xCD75 0xD3C7 # 0 +0xCD76 0xD3C8 # 0 +0xCD77 0xD3C9 # 0 +0xCD78 0xD3CA # 0 +0xCD79 0xD3CB # 0 +0xCD7A 0xD3CC # 0 +0xCD7B 0xD3CD # 0 +0xCD7C 0xD3CE # 0 +0xCD7D 0xD3CF # 0 +0xCD81 0xD3D0 # 0 +0xCD82 0xD3D1 # 0 +0xCD83 0xD3D2 # 0 +0xCD84 0xD3D3 # 0 +0xCD85 0xD3D4 # 0 +0xCD86 0xD3D5 # 0 +0xCD87 0xD3D6 # 0 +0xCD88 0xD3D7 # 0 +0xCD89 0xD3D8 # 0 +0xCD8A 0xD3D9 # 0 +0xCD8B 0xD3DA # 0 +0xCD8C 0xD3DB # 0 +0xCD8D 0xD3DC # 0 +0xCD8E 0xD3DD # 0 +0xCD8F 0xD3DE # 0 +0xCD90 0xD3DF # 0 +0xCD91 0xD3E0 # 0 +0xCD93 0xD3E1 # 0 +0xCD94 0xD3E2 # 0 +0xCD95 0xD3E3 # 0 +0xCD96 0xD3E4 # 0 +0xCD97 0xD3E5 # 0 +0xCD98 0xD3E6 # 0 +0xCD99 0xD3E7 # 0 +0xCD9A 0xD3E8 # 0 +0xCD9B 0xD3E9 # 0 +0xCD9C 0xD3EA # 0 +0xCD9D 0xD3EB # 0 +0xCDA1 0xD3EC # 0 +0xCDA2 0xD3ED # 0 +0xCDA3 0xD3EE # 0 +0xCDA4 0xD3EF # 0 +0xCDA5 0xD3F0 # 0 +0xCDA6 0xD3F1 # 0 +0xCDA7 0xD3F2 # 0 +0xCDA8 0xD3F3 # 0 +0xCDA9 0xD3F4 # 0 +0xCDAA 0xD3F5 # 0 +0xCDAB 0xD3F6 # 0 +0xCDAC 0xD3F7 # 0 +0xCDAD 0xD3F8 # 0 +0xCDAE 0xD3F9 # 0 +0xCDAF 0xD3FA # 0 +0xCDB0 0xD3FB # 0 +0xCDB1 0xD3FC # 0 +0xCDB3 0xD3FD # 0 +0xCDB4 0xD3FE # 0 +0xCDB5 0xD3FF # 0 +0xCDB6 0xD400 # 0 +0xCDB7 0xD401 # 0 +0xCDB8 0xD402 # 0 +0xCDB9 0xD403 # 0 +0xCDBA 0xD404 # 0 +0xCDBB 0xD405 # 0 +0xCDBC 0xD406 # 0 +0xCDBD 0xD407 # 0 +0xCDC1 0xD408 # 0 +0xCDC2 0xD409 # 0 +0xCDC3 0xD40A # 0 +0xCDC4 0xD40B # 0 +0xCDC5 0xD40C # 0 +0xCDC6 0xD40D # 0 +0xCDC7 0xD40E # 0 +0xCDC8 0xD40F # 0 +0xCDC9 0xD410 # 0 +0xCDCA 0xD411 # 0 +0xCDCB 0xD412 # 0 +0xCDCC 0xD413 # 0 +0xCDCD 0xD414 # 0 +0xCDCE 0xD415 # 0 +0xCDCF 0xD416 # 0 +0xCDD0 0xD417 # 0 +0xCDD1 0xD418 # 0 +0xCDD3 0xD419 # 0 +0xCDD4 0xD41A # 0 +0xCDD5 0xD41B # 0 +0xCDD6 0xD41C # 0 +0xCDD7 0xD41D # 0 +0xCDD8 0xD41E # 0 +0xCDD9 0xD41F # 0 +0xCDDA 0xD420 # 0 +0xCDDB 0xD421 # 0 +0xCDDC 0xD422 # 0 +0xCDDD 0xD423 # 0 +0xCDE1 0xD424 # 0 +0xCDE2 0xD425 # 0 +0xCDE3 0xD426 # 0 +0xCDE4 0xD427 # 0 +0xCDE5 0xD428 # 0 +0xCDE6 0xD429 # 0 +0xCDE7 0xD42A # 0 +0xCDE8 0xD42B # 0 +0xCDE9 0xD42C # 0 +0xCDEA 0xD42D # 0 +0xCDEB 0xD42E # 0 +0xCDEC 0xD42F # 0 +0xCDED 0xD430 # 0 +0xCDEE 0xD431 # 0 +0xCDEF 0xD432 # 0 +0xCDF0 0xD433 # 0 +0xCDF1 0xD434 # 0 +0xCDF3 0xD435 # 0 +0xCDF4 0xD436 # 0 +0xCDF5 0xD437 # 0 +0xCDF6 0xD438 # 0 +0xCDF7 0xD439 # 0 +0xCDF8 0xD43A # 0 +0xCDF9 0xD43B # 0 +0xCDFA 0xD43C # 0 +0xCDFB 0xD43D # 0 +0xCDFC 0xD43E # 0 +0xCDFD 0xD43F # 0 +0xCE41 0xD440 # 0 +0xCE42 0xD441 # 0 +0xCE43 0xD442 # 0 +0xCE44 0xD443 # 0 +0xCE45 0xD444 # 0 +0xCE46 0xD445 # 0 +0xCE47 0xD446 # 0 +0xCE48 0xD447 # 0 +0xCE49 0xD448 # 0 +0xCE4A 0xD449 # 0 +0xCE4B 0xD44A # 0 +0xCE4C 0xD44B # 0 +0xCE4D 0xD44C # 0 +0xCE4E 0xD44D # 0 +0xCE4F 0xD44E # 0 +0xCE50 0xD44F # 0 +0xCE51 0xD450 # 0 +0xCE53 0xD451 # 0 +0xCE54 0xD452 # 0 +0xCE55 0xD453 # 0 +0xCE56 0xD454 # 0 +0xCE57 0xD455 # 0 +0xCE58 0xD456 # 0 +0xCE59 0xD457 # 0 +0xCE5A 0xD458 # 0 +0xCE5B 0xD459 # 0 +0xCE5C 0xD45A # 0 +0xCE5D 0xD45B # 0 +0xCE61 0xD45C # 0 +0xCE62 0xD45D # 0 +0xCE63 0xD45E # 0 +0xCE64 0xD45F # 0 +0xCE65 0xD460 # 0 +0xCE66 0xD461 # 0 +0xCE67 0xD462 # 0 +0xCE68 0xD463 # 0 +0xCE69 0xD464 # 0 +0xCE6A 0xD465 # 0 +0xCE6B 0xD466 # 0 +0xCE6C 0xD467 # 0 +0xCE6D 0xD468 # 0 +0xCE6E 0xD469 # 0 +0xCE6F 0xD46A # 0 +0xCE70 0xD46B # 0 +0xCE71 0xD46C # 0 +0xCE73 0xD46D # 0 +0xCE74 0xD46E # 0 +0xCE75 0xD46F # 0 +0xCE76 0xD470 # 0 +0xCE77 0xD471 # 0 +0xCE78 0xD472 # 0 +0xCE79 0xD473 # 0 +0xCE7A 0xD474 # 0 +0xCE7B 0xD475 # 0 +0xCE7C 0xD476 # 0 +0xCE7D 0xD477 # 0 +0xCE81 0xD478 # 0 +0xCE82 0xD479 # 0 +0xCE83 0xD47A # 0 +0xCE84 0xD47B # 0 +0xCE85 0xD47C # 0 +0xCE86 0xD47D # 0 +0xCE87 0xD47E # 0 +0xCE88 0xD47F # 0 +0xCE89 0xD480 # 0 +0xCE8A 0xD481 # 0 +0xCE8B 0xD482 # 0 +0xCE8C 0xD483 # 0 +0xCE8D 0xD484 # 0 +0xCE8E 0xD485 # 0 +0xCE8F 0xD486 # 0 +0xCE90 0xD487 # 0 +0xCE91 0xD488 # 0 +0xCE93 0xD489 # 0 +0xCE94 0xD48A # 0 +0xCE95 0xD48B # 0 +0xCE96 0xD48C # 0 +0xCE97 0xD48D # 0 +0xCE98 0xD48E # 0 +0xCE99 0xD48F # 0 +0xCE9A 0xD490 # 0 +0xCE9B 0xD491 # 0 +0xCE9C 0xD492 # 0 +0xCE9D 0xD493 # 0 +0xCEA1 0xD494 # 0 +0xCEA2 0xD495 # 0 +0xCEA3 0xD496 # 0 +0xCEA4 0xD497 # 0 +0xCEA5 0xD498 # 0 +0xCEA6 0xD499 # 0 +0xCEA7 0xD49A # 0 +0xCEA8 0xD49B # 0 +0xCEA9 0xD49C # 0 +0xCEAA 0xD49D # 0 +0xCEAB 0xD49E # 0 +0xCEAC 0xD49F # 0 +0xCEAD 0xD4A0 # 0 +0xCEAE 0xD4A1 # 0 +0xCEAF 0xD4A2 # 0 +0xCEB0 0xD4A3 # 0 +0xCEB1 0xD4A4 # 0 +0xCEB3 0xD4A5 # 0 +0xCEB4 0xD4A6 # 0 +0xCEB5 0xD4A7 # 0 +0xCEB6 0xD4A8 # 0 +0xCEB7 0xD4A9 # 0 +0xCEB8 0xD4AA # 0 +0xCEB9 0xD4AB # 0 +0xCEBA 0xD4AC # 0 +0xCEBB 0xD4AD # 0 +0xCEBC 0xD4AE # 0 +0xCEBD 0xD4AF # 0 +0xCEC1 0xD4B0 # 0 +0xCEC2 0xD4B1 # 0 +0xCEC3 0xD4B2 # 0 +0xCEC4 0xD4B3 # 0 +0xCEC5 0xD4B4 # 0 +0xCEC6 0xD4B5 # 0 +0xCEC7 0xD4B6 # 0 +0xCEC8 0xD4B7 # 0 +0xCEC9 0xD4B8 # 0 +0xCECA 0xD4B9 # 0 +0xCECB 0xD4BA # 0 +0xCECC 0xD4BB # 0 +0xCECD 0xD4BC # 0 +0xCECE 0xD4BD # 0 +0xCECF 0xD4BE # 0 +0xCED0 0xD4BF # 0 +0xCED1 0xD4C0 # 0 +0xCED3 0xD4C1 # 0 +0xCED4 0xD4C2 # 0 +0xCED5 0xD4C3 # 0 +0xCED6 0xD4C4 # 0 +0xCED7 0xD4C5 # 0 +0xCED8 0xD4C6 # 0 +0xCED9 0xD4C7 # 0 +0xCEDA 0xD4C8 # 0 +0xCEDB 0xD4C9 # 0 +0xCEDC 0xD4CA # 0 +0xCEDD 0xD4CB # 0 +0xCEE1 0xD4CC # 0 +0xCEE2 0xD4CD # 0 +0xCEE3 0xD4CE # 0 +0xCEE4 0xD4CF # 0 +0xCEE5 0xD4D0 # 0 +0xCEE6 0xD4D1 # 0 +0xCEE7 0xD4D2 # 0 +0xCEE8 0xD4D3 # 0 +0xCEE9 0xD4D4 # 0 +0xCEEA 0xD4D5 # 0 +0xCEEB 0xD4D6 # 0 +0xCEEC 0xD4D7 # 0 +0xCEED 0xD4D8 # 0 +0xCEEE 0xD4D9 # 0 +0xCEEF 0xD4DA # 0 +0xCEF0 0xD4DB # 0 +0xCEF1 0xD4DC # 0 +0xCEF3 0xD4DD # 0 +0xCEF4 0xD4DE # 0 +0xCEF5 0xD4DF # 0 +0xCEF6 0xD4E0 # 0 +0xCEF7 0xD4E1 # 0 +0xCEF8 0xD4E2 # 0 +0xCEF9 0xD4E3 # 0 +0xCEFA 0xD4E4 # 0 +0xCEFB 0xD4E5 # 0 +0xCEFC 0xD4E6 # 0 +0xCEFD 0xD4E7 # 0 +0xCF41 0xD4E8 # 0 +0xCF42 0xD4E9 # 0 +0xCF43 0xD4EA # 0 +0xCF44 0xD4EB # 0 +0xCF45 0xD4EC # 0 +0xCF46 0xD4ED # 0 +0xCF47 0xD4EE # 0 +0xCF48 0xD4EF # 0 +0xCF49 0xD4F0 # 0 +0xCF4A 0xD4F1 # 0 +0xCF4B 0xD4F2 # 0 +0xCF4C 0xD4F3 # 0 +0xCF4D 0xD4F4 # 0 +0xCF4E 0xD4F5 # 0 +0xCF4F 0xD4F6 # 0 +0xCF50 0xD4F7 # 0 +0xCF51 0xD4F8 # 0 +0xCF53 0xD4F9 # 0 +0xCF54 0xD4FA # 0 +0xCF55 0xD4FB # 0 +0xCF56 0xD4FC # 0 +0xCF57 0xD4FD # 0 +0xCF58 0xD4FE # 0 +0xCF59 0xD4FF # 0 +0xCF5A 0xD500 # 0 +0xCF5B 0xD501 # 0 +0xCF5C 0xD502 # 0 +0xCF5D 0xD503 # 0 +0xCF61 0xD504 # 0 +0xCF62 0xD505 # 0 +0xCF63 0xD506 # 0 +0xCF64 0xD507 # 0 +0xCF65 0xD508 # 0 +0xCF66 0xD509 # 0 +0xCF67 0xD50A # 0 +0xCF68 0xD50B # 0 +0xCF69 0xD50C # 0 +0xCF6A 0xD50D # 0 +0xCF6B 0xD50E # 0 +0xCF6C 0xD50F # 0 +0xCF6D 0xD510 # 0 +0xCF6E 0xD511 # 0 +0xCF6F 0xD512 # 0 +0xCF70 0xD513 # 0 +0xCF71 0xD514 # 0 +0xCF73 0xD515 # 0 +0xCF74 0xD516 # 0 +0xCF75 0xD517 # 0 +0xCF76 0xD518 # 0 +0xCF77 0xD519 # 0 +0xCF78 0xD51A # 0 +0xCF79 0xD51B # 0 +0xCF7A 0xD51C # 0 +0xCF7B 0xD51D # 0 +0xCF7C 0xD51E # 0 +0xCF7D 0xD51F # 0 +0xCF81 0xD520 # 0 +0xCF82 0xD521 # 0 +0xCF83 0xD522 # 0 +0xCF84 0xD523 # 0 +0xCF85 0xD524 # 0 +0xCF86 0xD525 # 0 +0xCF87 0xD526 # 0 +0xCF88 0xD527 # 0 +0xCF89 0xD528 # 0 +0xCF8A 0xD529 # 0 +0xCF8B 0xD52A # 0 +0xCF8C 0xD52B # 0 +0xCF8D 0xD52C # 0 +0xCF8E 0xD52D # 0 +0xCF8F 0xD52E # 0 +0xCF90 0xD52F # 0 +0xCF91 0xD530 # 0 +0xCF93 0xD531 # 0 +0xCF94 0xD532 # 0 +0xCF95 0xD533 # 0 +0xCF96 0xD534 # 0 +0xCF97 0xD535 # 0 +0xCF98 0xD536 # 0 +0xCF99 0xD537 # 0 +0xCF9A 0xD538 # 0 +0xCF9B 0xD539 # 0 +0xCF9C 0xD53A # 0 +0xCF9D 0xD53B # 0 +0xCFA1 0xD53C # 0 +0xCFA2 0xD53D # 0 +0xCFA3 0xD53E # 0 +0xCFA4 0xD53F # 0 +0xCFA5 0xD540 # 0 +0xCFA6 0xD541 # 0 +0xCFA7 0xD542 # 0 +0xCFA8 0xD543 # 0 +0xCFA9 0xD544 # 0 +0xCFAA 0xD545 # 0 +0xCFAB 0xD546 # 0 +0xCFAC 0xD547 # 0 +0xCFAD 0xD548 # 0 +0xCFAE 0xD549 # 0 +0xCFAF 0xD54A # 0 +0xCFB0 0xD54B # 0 +0xCFB1 0xD54C # 0 +0xCFB3 0xD54D # 0 +0xCFB4 0xD54E # 0 +0xCFB5 0xD54F # 0 +0xCFB6 0xD550 # 0 +0xCFB7 0xD551 # 0 +0xCFB8 0xD552 # 0 +0xCFB9 0xD553 # 0 +0xCFBA 0xD554 # 0 +0xCFBB 0xD555 # 0 +0xCFBC 0xD556 # 0 +0xCFBD 0xD557 # 0 +0xD041 0x1112 # 0 +0xD061 0xD558 # 0 +0xD062 0xD559 # 0 +0xD063 0xD55A # 0 +0xD064 0xD55B # 0 +0xD065 0xD55C # 0 +0xD066 0xD55D # 0 +0xD067 0xD55E # 0 +0xD068 0xD55F # 0 +0xD069 0xD560 # 0 +0xD06A 0xD561 # 0 +0xD06B 0xD562 # 0 +0xD06C 0xD563 # 0 +0xD06D 0xD564 # 0 +0xD06E 0xD565 # 0 +0xD06F 0xD566 # 0 +0xD070 0xD567 # 0 +0xD071 0xD568 # 0 +0xD073 0xD569 # 0 +0xD074 0xD56A # 0 +0xD075 0xD56B # 0 +0xD076 0xD56C # 0 +0xD077 0xD56D # 0 +0xD078 0xD56E # 0 +0xD079 0xD56F # 0 +0xD07A 0xD570 # 0 +0xD07B 0xD571 # 0 +0xD07C 0xD572 # 0 +0xD07D 0xD573 # 0 +0xD081 0xD574 # 0 +0xD082 0xD575 # 0 +0xD083 0xD576 # 0 +0xD084 0xD577 # 0 +0xD085 0xD578 # 0 +0xD086 0xD579 # 0 +0xD087 0xD57A # 0 +0xD088 0xD57B # 0 +0xD089 0xD57C # 0 +0xD08A 0xD57D # 0 +0xD08B 0xD57E # 0 +0xD08C 0xD57F # 0 +0xD08D 0xD580 # 0 +0xD08E 0xD581 # 0 +0xD08F 0xD582 # 0 +0xD090 0xD583 # 0 +0xD091 0xD584 # 0 +0xD093 0xD585 # 0 +0xD094 0xD586 # 0 +0xD095 0xD587 # 0 +0xD096 0xD588 # 0 +0xD097 0xD589 # 0 +0xD098 0xD58A # 0 +0xD099 0xD58B # 0 +0xD09A 0xD58C # 0 +0xD09B 0xD58D # 0 +0xD09C 0xD58E # 0 +0xD09D 0xD58F # 0 +0xD0A1 0xD590 # 0 +0xD0A2 0xD591 # 0 +0xD0A3 0xD592 # 0 +0xD0A4 0xD593 # 0 +0xD0A5 0xD594 # 0 +0xD0A6 0xD595 # 0 +0xD0A7 0xD596 # 0 +0xD0A8 0xD597 # 0 +0xD0A9 0xD598 # 0 +0xD0AA 0xD599 # 0 +0xD0AB 0xD59A # 0 +0xD0AC 0xD59B # 0 +0xD0AD 0xD59C # 0 +0xD0AE 0xD59D # 0 +0xD0AF 0xD59E # 0 +0xD0B0 0xD59F # 0 +0xD0B1 0xD5A0 # 0 +0xD0B3 0xD5A1 # 0 +0xD0B4 0xD5A2 # 0 +0xD0B5 0xD5A3 # 0 +0xD0B6 0xD5A4 # 0 +0xD0B7 0xD5A5 # 0 +0xD0B8 0xD5A6 # 0 +0xD0B9 0xD5A7 # 0 +0xD0BA 0xD5A8 # 0 +0xD0BB 0xD5A9 # 0 +0xD0BC 0xD5AA # 0 +0xD0BD 0xD5AB # 0 +0xD0C1 0xD5AC # 0 +0xD0C2 0xD5AD # 0 +0xD0C3 0xD5AE # 0 +0xD0C4 0xD5AF # 0 +0xD0C5 0xD5B0 # 0 +0xD0C6 0xD5B1 # 0 +0xD0C7 0xD5B2 # 0 +0xD0C8 0xD5B3 # 0 +0xD0C9 0xD5B4 # 0 +0xD0CA 0xD5B5 # 0 +0xD0CB 0xD5B6 # 0 +0xD0CC 0xD5B7 # 0 +0xD0CD 0xD5B8 # 0 +0xD0CE 0xD5B9 # 0 +0xD0CF 0xD5BA # 0 +0xD0D0 0xD5BB # 0 +0xD0D1 0xD5BC # 0 +0xD0D3 0xD5BD # 0 +0xD0D4 0xD5BE # 0 +0xD0D5 0xD5BF # 0 +0xD0D6 0xD5C0 # 0 +0xD0D7 0xD5C1 # 0 +0xD0D8 0xD5C2 # 0 +0xD0D9 0xD5C3 # 0 +0xD0DA 0xD5C4 # 0 +0xD0DB 0xD5C5 # 0 +0xD0DC 0xD5C6 # 0 +0xD0DD 0xD5C7 # 0 +0xD0E1 0xD5C8 # 0 +0xD0E2 0xD5C9 # 0 +0xD0E3 0xD5CA # 0 +0xD0E4 0xD5CB # 0 +0xD0E5 0xD5CC # 0 +0xD0E6 0xD5CD # 0 +0xD0E7 0xD5CE # 0 +0xD0E8 0xD5CF # 0 +0xD0E9 0xD5D0 # 0 +0xD0EA 0xD5D1 # 0 +0xD0EB 0xD5D2 # 0 +0xD0EC 0xD5D3 # 0 +0xD0ED 0xD5D4 # 0 +0xD0EE 0xD5D5 # 0 +0xD0EF 0xD5D6 # 0 +0xD0F0 0xD5D7 # 0 +0xD0F1 0xD5D8 # 0 +0xD0F3 0xD5D9 # 0 +0xD0F4 0xD5DA # 0 +0xD0F5 0xD5DB # 0 +0xD0F6 0xD5DC # 0 +0xD0F7 0xD5DD # 0 +0xD0F8 0xD5DE # 0 +0xD0F9 0xD5DF # 0 +0xD0FA 0xD5E0 # 0 +0xD0FB 0xD5E1 # 0 +0xD0FC 0xD5E2 # 0 +0xD0FD 0xD5E3 # 0 +0xD141 0xD5E4 # 0 +0xD142 0xD5E5 # 0 +0xD143 0xD5E6 # 0 +0xD144 0xD5E7 # 0 +0xD145 0xD5E8 # 0 +0xD146 0xD5E9 # 0 +0xD147 0xD5EA # 0 +0xD148 0xD5EB # 0 +0xD149 0xD5EC # 0 +0xD14A 0xD5ED # 0 +0xD14B 0xD5EE # 0 +0xD14C 0xD5EF # 0 +0xD14D 0xD5F0 # 0 +0xD14E 0xD5F1 # 0 +0xD14F 0xD5F2 # 0 +0xD150 0xD5F3 # 0 +0xD151 0xD5F4 # 0 +0xD153 0xD5F5 # 0 +0xD154 0xD5F6 # 0 +0xD155 0xD5F7 # 0 +0xD156 0xD5F8 # 0 +0xD157 0xD5F9 # 0 +0xD158 0xD5FA # 0 +0xD159 0xD5FB # 0 +0xD15A 0xD5FC # 0 +0xD15B 0xD5FD # 0 +0xD15C 0xD5FE # 0 +0xD15D 0xD5FF # 0 +0xD161 0xD600 # 0 +0xD162 0xD601 # 0 +0xD163 0xD602 # 0 +0xD164 0xD603 # 0 +0xD165 0xD604 # 0 +0xD166 0xD605 # 0 +0xD167 0xD606 # 0 +0xD168 0xD607 # 0 +0xD169 0xD608 # 0 +0xD16A 0xD609 # 0 +0xD16B 0xD60A # 0 +0xD16C 0xD60B # 0 +0xD16D 0xD60C # 0 +0xD16E 0xD60D # 0 +0xD16F 0xD60E # 0 +0xD170 0xD60F # 0 +0xD171 0xD610 # 0 +0xD173 0xD611 # 0 +0xD174 0xD612 # 0 +0xD175 0xD613 # 0 +0xD176 0xD614 # 0 +0xD177 0xD615 # 0 +0xD178 0xD616 # 0 +0xD179 0xD617 # 0 +0xD17A 0xD618 # 0 +0xD17B 0xD619 # 0 +0xD17C 0xD61A # 0 +0xD17D 0xD61B # 0 +0xD181 0xD61C # 0 +0xD182 0xD61D # 0 +0xD183 0xD61E # 0 +0xD184 0xD61F # 0 +0xD185 0xD620 # 0 +0xD186 0xD621 # 0 +0xD187 0xD622 # 0 +0xD188 0xD623 # 0 +0xD189 0xD624 # 0 +0xD18A 0xD625 # 0 +0xD18B 0xD626 # 0 +0xD18C 0xD627 # 0 +0xD18D 0xD628 # 0 +0xD18E 0xD629 # 0 +0xD18F 0xD62A # 0 +0xD190 0xD62B # 0 +0xD191 0xD62C # 0 +0xD193 0xD62D # 0 +0xD194 0xD62E # 0 +0xD195 0xD62F # 0 +0xD196 0xD630 # 0 +0xD197 0xD631 # 0 +0xD198 0xD632 # 0 +0xD199 0xD633 # 0 +0xD19A 0xD634 # 0 +0xD19B 0xD635 # 0 +0xD19C 0xD636 # 0 +0xD19D 0xD637 # 0 +0xD1A1 0xD638 # 0 +0xD1A2 0xD639 # 0 +0xD1A3 0xD63A # 0 +0xD1A4 0xD63B # 0 +0xD1A5 0xD63C # 0 +0xD1A6 0xD63D # 0 +0xD1A7 0xD63E # 0 +0xD1A8 0xD63F # 0 +0xD1A9 0xD640 # 0 +0xD1AA 0xD641 # 0 +0xD1AB 0xD642 # 0 +0xD1AC 0xD643 # 0 +0xD1AD 0xD644 # 0 +0xD1AE 0xD645 # 0 +0xD1AF 0xD646 # 0 +0xD1B0 0xD647 # 0 +0xD1B1 0xD648 # 0 +0xD1B3 0xD649 # 0 +0xD1B4 0xD64A # 0 +0xD1B5 0xD64B # 0 +0xD1B6 0xD64C # 0 +0xD1B7 0xD64D # 0 +0xD1B8 0xD64E # 0 +0xD1B9 0xD64F # 0 +0xD1BA 0xD650 # 0 +0xD1BB 0xD651 # 0 +0xD1BC 0xD652 # 0 +0xD1BD 0xD653 # 0 +0xD1C1 0xD654 # 0 +0xD1C2 0xD655 # 0 +0xD1C3 0xD656 # 0 +0xD1C4 0xD657 # 0 +0xD1C5 0xD658 # 0 +0xD1C6 0xD659 # 0 +0xD1C7 0xD65A # 0 +0xD1C8 0xD65B # 0 +0xD1C9 0xD65C # 0 +0xD1CA 0xD65D # 0 +0xD1CB 0xD65E # 0 +0xD1CC 0xD65F # 0 +0xD1CD 0xD660 # 0 +0xD1CE 0xD661 # 0 +0xD1CF 0xD662 # 0 +0xD1D0 0xD663 # 0 +0xD1D1 0xD664 # 0 +0xD1D3 0xD665 # 0 +0xD1D4 0xD666 # 0 +0xD1D5 0xD667 # 0 +0xD1D6 0xD668 # 0 +0xD1D7 0xD669 # 0 +0xD1D8 0xD66A # 0 +0xD1D9 0xD66B # 0 +0xD1DA 0xD66C # 0 +0xD1DB 0xD66D # 0 +0xD1DC 0xD66E # 0 +0xD1DD 0xD66F # 0 +0xD1E1 0xD670 # 0 +0xD1E2 0xD671 # 0 +0xD1E3 0xD672 # 0 +0xD1E4 0xD673 # 0 +0xD1E5 0xD674 # 0 +0xD1E6 0xD675 # 0 +0xD1E7 0xD676 # 0 +0xD1E8 0xD677 # 0 +0xD1E9 0xD678 # 0 +0xD1EA 0xD679 # 0 +0xD1EB 0xD67A # 0 +0xD1EC 0xD67B # 0 +0xD1ED 0xD67C # 0 +0xD1EE 0xD67D # 0 +0xD1EF 0xD67E # 0 +0xD1F0 0xD67F # 0 +0xD1F1 0xD680 # 0 +0xD1F3 0xD681 # 0 +0xD1F4 0xD682 # 0 +0xD1F5 0xD683 # 0 +0xD1F6 0xD684 # 0 +0xD1F7 0xD685 # 0 +0xD1F8 0xD686 # 0 +0xD1F9 0xD687 # 0 +0xD1FA 0xD688 # 0 +0xD1FB 0xD689 # 0 +0xD1FC 0xD68A # 0 +0xD1FD 0xD68B # 0 +0xD241 0xD68C # 0 +0xD242 0xD68D # 0 +0xD243 0xD68E # 0 +0xD244 0xD68F # 0 +0xD245 0xD690 # 0 +0xD246 0xD691 # 0 +0xD247 0xD692 # 0 +0xD248 0xD693 # 0 +0xD249 0xD694 # 0 +0xD24A 0xD695 # 0 +0xD24B 0xD696 # 0 +0xD24C 0xD697 # 0 +0xD24D 0xD698 # 0 +0xD24E 0xD699 # 0 +0xD24F 0xD69A # 0 +0xD250 0xD69B # 0 +0xD251 0xD69C # 0 +0xD253 0xD69D # 0 +0xD254 0xD69E # 0 +0xD255 0xD69F # 0 +0xD256 0xD6A0 # 0 +0xD257 0xD6A1 # 0 +0xD258 0xD6A2 # 0 +0xD259 0xD6A3 # 0 +0xD25A 0xD6A4 # 0 +0xD25B 0xD6A5 # 0 +0xD25C 0xD6A6 # 0 +0xD25D 0xD6A7 # 0 +0xD261 0xD6A8 # 0 +0xD262 0xD6A9 # 0 +0xD263 0xD6AA # 0 +0xD264 0xD6AB # 0 +0xD265 0xD6AC # 0 +0xD266 0xD6AD # 0 +0xD267 0xD6AE # 0 +0xD268 0xD6AF # 0 +0xD269 0xD6B0 # 0 +0xD26A 0xD6B1 # 0 +0xD26B 0xD6B2 # 0 +0xD26C 0xD6B3 # 0 +0xD26D 0xD6B4 # 0 +0xD26E 0xD6B5 # 0 +0xD26F 0xD6B6 # 0 +0xD270 0xD6B7 # 0 +0xD271 0xD6B8 # 0 +0xD273 0xD6B9 # 0 +0xD274 0xD6BA # 0 +0xD275 0xD6BB # 0 +0xD276 0xD6BC # 0 +0xD277 0xD6BD # 0 +0xD278 0xD6BE # 0 +0xD279 0xD6BF # 0 +0xD27A 0xD6C0 # 0 +0xD27B 0xD6C1 # 0 +0xD27C 0xD6C2 # 0 +0xD27D 0xD6C3 # 0 +0xD281 0xD6C4 # 0 +0xD282 0xD6C5 # 0 +0xD283 0xD6C6 # 0 +0xD284 0xD6C7 # 0 +0xD285 0xD6C8 # 0 +0xD286 0xD6C9 # 0 +0xD287 0xD6CA # 0 +0xD288 0xD6CB # 0 +0xD289 0xD6CC # 0 +0xD28A 0xD6CD # 0 +0xD28B 0xD6CE # 0 +0xD28C 0xD6CF # 0 +0xD28D 0xD6D0 # 0 +0xD28E 0xD6D1 # 0 +0xD28F 0xD6D2 # 0 +0xD290 0xD6D3 # 0 +0xD291 0xD6D4 # 0 +0xD293 0xD6D5 # 0 +0xD294 0xD6D6 # 0 +0xD295 0xD6D7 # 0 +0xD296 0xD6D8 # 0 +0xD297 0xD6D9 # 0 +0xD298 0xD6DA # 0 +0xD299 0xD6DB # 0 +0xD29A 0xD6DC # 0 +0xD29B 0xD6DD # 0 +0xD29C 0xD6DE # 0 +0xD29D 0xD6DF # 0 +0xD2A1 0xD6E0 # 0 +0xD2A2 0xD6E1 # 0 +0xD2A3 0xD6E2 # 0 +0xD2A4 0xD6E3 # 0 +0xD2A5 0xD6E4 # 0 +0xD2A6 0xD6E5 # 0 +0xD2A7 0xD6E6 # 0 +0xD2A8 0xD6E7 # 0 +0xD2A9 0xD6E8 # 0 +0xD2AA 0xD6E9 # 0 +0xD2AB 0xD6EA # 0 +0xD2AC 0xD6EB # 0 +0xD2AD 0xD6EC # 0 +0xD2AE 0xD6ED # 0 +0xD2AF 0xD6EE # 0 +0xD2B0 0xD6EF # 0 +0xD2B1 0xD6F0 # 0 +0xD2B3 0xD6F1 # 0 +0xD2B4 0xD6F2 # 0 +0xD2B5 0xD6F3 # 0 +0xD2B6 0xD6F4 # 0 +0xD2B7 0xD6F5 # 0 +0xD2B8 0xD6F6 # 0 +0xD2B9 0xD6F7 # 0 +0xD2BA 0xD6F8 # 0 +0xD2BB 0xD6F9 # 0 +0xD2BC 0xD6FA # 0 +0xD2BD 0xD6FB # 0 +0xD2C1 0xD6FC # 0 +0xD2C2 0xD6FD # 0 +0xD2C3 0xD6FE # 0 +0xD2C4 0xD6FF # 0 +0xD2C5 0xD700 # 0 +0xD2C6 0xD701 # 0 +0xD2C7 0xD702 # 0 +0xD2C8 0xD703 # 0 +0xD2C9 0xD704 # 0 +0xD2CA 0xD705 # 0 +0xD2CB 0xD706 # 0 +0xD2CC 0xD707 # 0 +0xD2CD 0xD708 # 0 +0xD2CE 0xD709 # 0 +0xD2CF 0xD70A # 0 +0xD2D0 0xD70B # 0 +0xD2D1 0xD70C # 0 +0xD2D3 0xD70D # 0 +0xD2D4 0xD70E # 0 +0xD2D5 0xD70F # 0 +0xD2D6 0xD710 # 0 +0xD2D7 0xD711 # 0 +0xD2D8 0xD712 # 0 +0xD2D9 0xD713 # 0 +0xD2DA 0xD714 # 0 +0xD2DB 0xD715 # 0 +0xD2DC 0xD716 # 0 +0xD2DD 0xD717 # 0 +0xD2E1 0xD718 # 0 +0xD2E2 0xD719 # 0 +0xD2E3 0xD71A # 0 +0xD2E4 0xD71B # 0 +0xD2E5 0xD71C # 0 +0xD2E6 0xD71D # 0 +0xD2E7 0xD71E # 0 +0xD2E8 0xD71F # 0 +0xD2E9 0xD720 # 0 +0xD2EA 0xD721 # 0 +0xD2EB 0xD722 # 0 +0xD2EC 0xD723 # 0 +0xD2ED 0xD724 # 0 +0xD2EE 0xD725 # 0 +0xD2EF 0xD726 # 0 +0xD2F0 0xD727 # 0 +0xD2F1 0xD728 # 0 +0xD2F3 0xD729 # 0 +0xD2F4 0xD72A # 0 +0xD2F5 0xD72B # 0 +0xD2F6 0xD72C # 0 +0xD2F7 0xD72D # 0 +0xD2F8 0xD72E # 0 +0xD2F9 0xD72F # 0 +0xD2FA 0xD730 # 0 +0xD2FB 0xD731 # 0 +0xD2FC 0xD732 # 0 +0xD2FD 0xD733 # 0 +0xD341 0xD734 # 0 +0xD342 0xD735 # 0 +0xD343 0xD736 # 0 +0xD344 0xD737 # 0 +0xD345 0xD738 # 0 +0xD346 0xD739 # 0 +0xD347 0xD73A # 0 +0xD348 0xD73B # 0 +0xD349 0xD73C # 0 +0xD34A 0xD73D # 0 +0xD34B 0xD73E # 0 +0xD34C 0xD73F # 0 +0xD34D 0xD740 # 0 +0xD34E 0xD741 # 0 +0xD34F 0xD742 # 0 +0xD350 0xD743 # 0 +0xD351 0xD744 # 0 +0xD353 0xD745 # 0 +0xD354 0xD746 # 0 +0xD355 0xD747 # 0 +0xD356 0xD748 # 0 +0xD357 0xD749 # 0 +0xD358 0xD74A # 0 +0xD359 0xD74B # 0 +0xD35A 0xD74C # 0 +0xD35B 0xD74D # 0 +0xD35C 0xD74E # 0 +0xD35D 0xD74F # 0 +0xD361 0xD750 # 0 +0xD362 0xD751 # 0 +0xD363 0xD752 # 0 +0xD364 0xD753 # 0 +0xD365 0xD754 # 0 +0xD366 0xD755 # 0 +0xD367 0xD756 # 0 +0xD368 0xD757 # 0 +0xD369 0xD758 # 0 +0xD36A 0xD759 # 0 +0xD36B 0xD75A # 0 +0xD36C 0xD75B # 0 +0xD36D 0xD75C # 0 +0xD36E 0xD75D # 0 +0xD36F 0xD75E # 0 +0xD370 0xD75F # 0 +0xD371 0xD760 # 0 +0xD373 0xD761 # 0 +0xD374 0xD762 # 0 +0xD375 0xD763 # 0 +0xD376 0xD764 # 0 +0xD377 0xD765 # 0 +0xD378 0xD766 # 0 +0xD379 0xD767 # 0 +0xD37A 0xD768 # 0 +0xD37B 0xD769 # 0 +0xD37C 0xD76A # 0 +0xD37D 0xD76B # 0 +0xD381 0xD76C # 0 +0xD382 0xD76D # 0 +0xD383 0xD76E # 0 +0xD384 0xD76F # 0 +0xD385 0xD770 # 0 +0xD386 0xD771 # 0 +0xD387 0xD772 # 0 +0xD388 0xD773 # 0 +0xD389 0xD774 # 0 +0xD38A 0xD775 # 0 +0xD38B 0xD776 # 0 +0xD38C 0xD777 # 0 +0xD38D 0xD778 # 0 +0xD38E 0xD779 # 0 +0xD38F 0xD77A # 0 +0xD390 0xD77B # 0 +0xD391 0xD77C # 0 +0xD393 0xD77D # 0 +0xD394 0xD77E # 0 +0xD395 0xD77F # 0 +0xD396 0xD780 # 0 +0xD397 0xD781 # 0 +0xD398 0xD782 # 0 +0xD399 0xD783 # 0 +0xD39A 0xD784 # 0 +0xD39B 0xD785 # 0 +0xD39C 0xD786 # 0 +0xD39D 0xD787 # 0 +0xD3A1 0xD788 # 0 +0xD3A2 0xD789 # 0 +0xD3A3 0xD78A # 0 +0xD3A4 0xD78B # 0 +0xD3A5 0xD78C # 0 +0xD3A6 0xD78D # 0 +0xD3A7 0xD78E # 0 +0xD3A8 0xD78F # 0 +0xD3A9 0xD790 # 0 +0xD3AA 0xD791 # 0 +0xD3AB 0xD792 # 0 +0xD3AC 0xD793 # 0 +0xD3AD 0xD794 # 0 +0xD3AE 0xD795 # 0 +0xD3AF 0xD796 # 0 +0xD3B0 0xD797 # 0 +0xD3B1 0xD798 # 0 +0xD3B3 0xD799 # 0 +0xD3B4 0xD79A # 0 +0xD3B5 0xD79B # 0 +0xD3B6 0xD79C # 0 +0xD3B7 0xD79D # 0 +0xD3B8 0xD79E # 0 +0xD3B9 0xD79F # 0 +0xD3BA 0xD7A0 # 0 +0xD3BB 0xD7A1 # 0 +0xD3BC 0xD7A2 # 0 +0xD3BD 0xD7A3 # 0 +0xD831 0xE000 # 0 +0xD832 0xE001 # 0 +0xD833 0xE002 # 0 +0xD834 0xE003 # 0 +0xD835 0xE004 # 0 +0xD836 0xE005 # 0 +0xD837 0xE006 # 0 +0xD838 0xE007 # 0 +0xD839 0xE008 # 0 +0xD83A 0xE009 # 0 +0xD83B 0xE00A # 0 +0xD83C 0xE00B # 0 +0xD83D 0xE00C # 0 +0xD83E 0xE00D # 0 +0xD83F 0xE00E # 0 +0xD840 0xE00F # 0 +0xD841 0xE010 # 0 +0xD842 0xE011 # 0 +0xD843 0xE012 # 0 +0xD844 0xE013 # 0 +0xD845 0xE014 # 0 +0xD846 0xE015 # 0 +0xD847 0xE016 # 0 +0xD848 0xE017 # 0 +0xD849 0xE018 # 0 +0xD84A 0xE019 # 0 +0xD84B 0xE01A # 0 +0xD84C 0xE01B # 0 +0xD84D 0xE01C # 0 +0xD84E 0xE01D # 0 +0xD84F 0xE01E # 0 +0xD850 0xE01F # 0 +0xD851 0xE020 # 0 +0xD852 0xE021 # 0 +0xD853 0xE022 # 0 +0xD854 0xE023 # 0 +0xD855 0xE024 # 0 +0xD856 0xE025 # 0 +0xD857 0xE026 # 0 +0xD858 0xE027 # 0 +0xD859 0xE028 # 0 +0xD85A 0xE029 # 0 +0xD85B 0xE02A # 0 +0xD85C 0xE02B # 0 +0xD85D 0xE02C # 0 +0xD85E 0xE02D # 0 +0xD85F 0xE02E # 0 +0xD860 0xE02F # 0 +0xD861 0xE030 # 0 +0xD862 0xE031 # 0 +0xD863 0xE032 # 0 +0xD864 0xE033 # 0 +0xD865 0xE034 # 0 +0xD866 0xE035 # 0 +0xD867 0xE036 # 0 +0xD868 0xE037 # 0 +0xD869 0xE038 # 0 +0xD86A 0xE039 # 0 +0xD86B 0xE03A # 0 +0xD86C 0xE03B # 0 +0xD86D 0xE03C # 0 +0xD86E 0xE03D # 0 +0xD86F 0xE03E # 0 +0xD870 0xE03F # 0 +0xD871 0xE040 # 0 +0xD872 0xE041 # 0 +0xD873 0xE042 # 0 +0xD874 0xE043 # 0 +0xD875 0xE044 # 0 +0xD876 0xE045 # 0 +0xD877 0xE046 # 0 +0xD878 0xE047 # 0 +0xD879 0xE048 # 0 +0xD87A 0xE049 # 0 +0xD87B 0xE04A # 0 +0xD87C 0xE04B # 0 +0xD87D 0xE04C # 0 +0xD87E 0xE04D # 0 +0xD891 0xE04E # 0 +0xD892 0xE04F # 0 +0xD893 0xE050 # 0 +0xD894 0xE051 # 0 +0xD895 0xE052 # 0 +0xD896 0xE053 # 0 +0xD897 0xE054 # 0 +0xD898 0xE055 # 0 +0xD899 0xE056 # 0 +0xD89A 0xE057 # 0 +0xD89B 0xE058 # 0 +0xD89C 0xE059 # 0 +0xD89D 0xE05A # 0 +0xD89E 0xE05B # 0 +0xD89F 0xE05C # 0 +0xD8A0 0xE05D # 0 +0xD8A1 0xE05E # 0 +0xD8A2 0xE05F # 0 +0xD8A3 0xE060 # 0 +0xD8A4 0xE061 # 0 +0xD8A5 0xE062 # 0 +0xD8A6 0xE063 # 0 +0xD8A7 0xE064 # 0 +0xD8A8 0xE065 # 0 +0xD8A9 0xE066 # 0 +0xD8AA 0xE067 # 0 +0xD8AB 0xE068 # 0 +0xD8AC 0xE069 # 0 +0xD8AD 0xE06A # 0 +0xD8AE 0xE06B # 0 +0xD8AF 0xE06C # 0 +0xD8B0 0xE06D # 0 +0xD8B1 0xE06E # 0 +0xD8B2 0xE06F # 0 +0xD8B3 0xE070 # 0 +0xD8B4 0xE071 # 0 +0xD8B5 0xE072 # 0 +0xD8B6 0xE073 # 0 +0xD8B7 0xE074 # 0 +0xD8B8 0xE075 # 0 +0xD8B9 0xE076 # 0 +0xD8BA 0xE077 # 0 +0xD8BB 0xE078 # 0 +0xD8BC 0xE079 # 0 +0xD8BD 0xE07A # 0 +0xD8BE 0xE07B # 0 +0xD8BF 0xE07C # 0 +0xD8C0 0xE07D # 0 +0xD8C1 0xE07E # 0 +0xD8C2 0xE07F # 0 +0xD8C3 0xE080 # 0 +0xD8C4 0xE081 # 0 +0xD8C5 0xE082 # 0 +0xD8C6 0xE083 # 0 +0xD8C7 0xE084 # 0 +0xD8C8 0xE085 # 0 +0xD8C9 0xE086 # 0 +0xD8CA 0xE087 # 0 +0xD8CB 0xE088 # 0 +0xD8CC 0xE089 # 0 +0xD8CD 0xE08A # 0 +0xD8CE 0xE08B # 0 +0xD8CF 0xE08C # 0 +0xD8D0 0xE08D # 0 +0xD8D1 0xE08E # 0 +0xD8D2 0xE08F # 0 +0xD8D3 0xE090 # 0 +0xD8D4 0xE091 # 0 +0xD8D5 0xE092 # 0 +0xD8D6 0xE093 # 0 +0xD8D7 0xE094 # 0 +0xD8D8 0xE095 # 0 +0xD8D9 0xE096 # 0 +0xD8DA 0xE097 # 0 +0xD8DB 0xE098 # 0 +0xD8DC 0xE099 # 0 +0xD8DD 0xE09A # 0 +0xD8DE 0xE09B # 0 +0xD8DF 0xE09C # 0 +0xD8E0 0xE09D # 0 +0xD8E1 0xE09E # 0 +0xD8E2 0xE09F # 0 +0xD8E3 0xE0A0 # 0 +0xD8E4 0xE0A1 # 0 +0xD8E5 0xE0A2 # 0 +0xD8E6 0xE0A3 # 0 +0xD8E7 0xE0A4 # 0 +0xD8E8 0xE0A5 # 0 +0xD8E9 0xE0A6 # 0 +0xD8EA 0xE0A7 # 0 +0xD8EB 0xE0A8 # 0 +0xD8EC 0xE0A9 # 0 +0xD8ED 0xE0AA # 0 +0xD8EE 0xE0AB # 0 +0xD8EF 0xE0AC # 0 +0xD8F0 0xE0AD # 0 +0xD8F1 0xE0AE # 0 +0xD8F2 0xE0AF # 0 +0xD8F3 0xE0B0 # 0 +0xD8F4 0xE0B1 # 0 +0xD8F5 0xE0B2 # 0 +0xD8F6 0xE0B3 # 0 +0xD8F7 0xE0B4 # 0 +0xD8F8 0xE0B5 # 0 +0xD8F9 0xE0B6 # 0 +0xD8FA 0xE0B7 # 0 +0xD8FB 0xE0B8 # 0 +0xD8FC 0xE0B9 # 0 +0xD8FD 0xE0BA # 0 +0xD8FE 0xE0BB # 0 +0xD931 0x3000 # 0 +0xD932 0x3001 # 0 +0xD933 0x3002 # 0 +0xD934 0x00B7 # 0 +0xD935 0x2025 # 0 +0xD936 0x2026 # 0 +0xD937 0x00A8 # 0 +0xD938 0x3003 # 0 +0xD939 0x00AD # 0 +0xD93A 0x2015 # 0 +0xD93B 0x2225 # 0 +0xD93C 0xFF3C # 0 +0xD93D 0x223C # 0 +0xD93E 0x2018 # 0 +0xD93F 0x2019 # 0 +0xD940 0x201C # 0 +0xD941 0x201D # 0 +0xD942 0x3014 # 0 +0xD943 0x3015 # 0 +0xD944 0x3008 # 0 +0xD945 0x3009 # 0 +0xD946 0x300A # 0 +0xD947 0x300B # 0 +0xD948 0x300C # 0 +0xD949 0x300D # 0 +0xD94A 0x300E # 0 +0xD94B 0x300F # 0 +0xD94C 0x3010 # 0 +0xD94D 0x3011 # 0 +0xD94E 0x00B1 # 0 +0xD94F 0x00D7 # 0 +0xD950 0x00F7 # 0 +0xD951 0x2260 # 0 +0xD952 0x2264 # 0 +0xD953 0x2265 # 0 +0xD954 0x221E # 0 +0xD955 0x2234 # 0 +0xD956 0x00B0 # 0 +0xD957 0x2032 # 0 +0xD958 0x2033 # 0 +0xD959 0x2103 # 0 +0xD95A 0x212B # 0 +0xD95B 0xFFE0 # 0 +0xD95C 0xFFE1 # 0 +0xD95D 0xFFE5 # 0 +0xD95E 0x2642 # 0 +0xD95F 0x2640 # 0 +0xD960 0x2220 # 0 +0xD961 0x22A5 # 0 +0xD962 0x2312 # 0 +0xD963 0x2202 # 0 +0xD964 0x2207 # 0 +0xD965 0x2261 # 0 +0xD966 0x2252 # 0 +0xD967 0x00A7 # 0 +0xD968 0x203B # 0 +0xD969 0x2606 # 0 +0xD96A 0x2605 # 0 +0xD96B 0x25CB # 0 +0xD96C 0x25CF # 0 +0xD96D 0x25CE # 0 +0xD96E 0x25C7 # 0 +0xD96F 0x25C6 # 0 +0xD970 0x25A1 # 0 +0xD971 0x25A0 # 0 +0xD972 0x25B3 # 0 +0xD973 0x25B2 # 0 +0xD974 0x25BD # 0 +0xD975 0x25BC # 0 +0xD976 0x2192 # 0 +0xD977 0x2190 # 0 +0xD978 0x2191 # 0 +0xD979 0x2193 # 0 +0xD97A 0x2194 # 0 +0xD97B 0x3013 # 0 +0xD97C 0x226A # 0 +0xD97D 0x226B # 0 +0xD97E 0x221A # 0 +0xD991 0x223D # 0 +0xD992 0x221D # 0 +0xD993 0x2235 # 0 +0xD994 0x222B # 0 +0xD995 0x222C # 0 +0xD996 0x2208 # 0 +0xD997 0x220B # 0 +0xD998 0x2286 # 0 +0xD999 0x2287 # 0 +0xD99A 0x2282 # 0 +0xD99B 0x2283 # 0 +0xD99C 0x222A # 0 +0xD99D 0x2229 # 0 +0xD99E 0x2227 # 0 +0xD99F 0x2228 # 0 +0xD9A0 0xFFE2 # 0 +0xD9A1 0x21D2 # 0 +0xD9A2 0x21D4 # 0 +0xD9A3 0x2200 # 0 +0xD9A4 0x2203 # 0 +0xD9A5 0x00B4 # 0 +0xD9A6 0xFF5E # 0 +0xD9A7 0x02C7 # 0 +0xD9A8 0x02D8 # 0 +0xD9A9 0x02DD # 0 +0xD9AA 0x02DA # 0 +0xD9AB 0x02D9 # 0 +0xD9AC 0x00B8 # 0 +0xD9AD 0x02DB # 0 +0xD9AE 0x00A1 # 0 +0xD9AF 0x00BF # 0 +0xD9B0 0x02D0 # 0 +0xD9B1 0x222E # 0 +0xD9B2 0x2211 # 0 +0xD9B3 0x220F # 0 +0xD9B4 0x00A4 # 0 +0xD9B5 0x2109 # 0 +0xD9B6 0x2030 # 0 +0xD9B7 0x25C1 # 0 +0xD9B8 0x25C0 # 0 +0xD9B9 0x25B7 # 0 +0xD9BA 0x25B6 # 0 +0xD9BB 0x2664 # 0 +0xD9BC 0x2660 # 0 +0xD9BD 0x2661 # 0 +0xD9BE 0x2665 # 0 +0xD9BF 0x2667 # 0 +0xD9C0 0x2663 # 0 +0xD9C1 0x2299 # 0 +0xD9C2 0x25C8 # 0 +0xD9C3 0x25A3 # 0 +0xD9C4 0x25D0 # 0 +0xD9C5 0x25D1 # 0 +0xD9C6 0x2592 # 0 +0xD9C7 0x25A4 # 0 +0xD9C8 0x25A5 # 0 +0xD9C9 0x25A8 # 0 +0xD9CA 0x25A7 # 0 +0xD9CB 0x25A6 # 0 +0xD9CC 0x25A9 # 0 +0xD9CD 0x2668 # 0 +0xD9CE 0x260F # 0 +0xD9CF 0x260E # 0 +0xD9D0 0x261C # 0 +0xD9D1 0x261E # 0 +0xD9D2 0x00B6 # 0 +0xD9D3 0x2020 # 0 +0xD9D4 0x2021 # 0 +0xD9D5 0x2195 # 0 +0xD9D6 0x2197 # 0 +0xD9D7 0x2199 # 0 +0xD9D8 0x2196 # 0 +0xD9D9 0x2198 # 0 +0xD9DA 0x266D # 0 +0xD9DB 0x2669 # 0 +0xD9DC 0x266A # 0 +0xD9DD 0x266C # 0 +0xD9DE 0x327F # 0 +0xD9DF 0x321C # 0 +0xD9E0 0x2116 # 0 +0xD9E1 0x33C7 # 0 +0xD9E2 0x2122 # 0 +0xD9E3 0x33C2 # 0 +0xD9E4 0x33D8 # 0 +0xD9E5 0x2121 # 0 +0xD9E6 0x20AC # 0 +0xD9E7 0x00AE # 0 +0xDA31 0xFF01 # 0 +0xDA32 0xFF02 # 0 +0xDA33 0xFF03 # 0 +0xDA34 0xFF04 # 0 +0xDA35 0xFF05 # 0 +0xDA36 0xFF06 # 0 +0xDA37 0xFF07 # 0 +0xDA38 0xFF08 # 0 +0xDA39 0xFF09 # 0 +0xDA3A 0xFF0A # 0 +0xDA3B 0xFF0B # 0 +0xDA3C 0xFF0C # 0 +0xDA3D 0xFF0D # 0 +0xDA3E 0xFF0E # 0 +0xDA3F 0xFF0F # 0 +0xDA40 0xFF10 # 0 +0xDA41 0xFF11 # 0 +0xDA42 0xFF12 # 0 +0xDA43 0xFF13 # 0 +0xDA44 0xFF14 # 0 +0xDA45 0xFF15 # 0 +0xDA46 0xFF16 # 0 +0xDA47 0xFF17 # 0 +0xDA48 0xFF18 # 0 +0xDA49 0xFF19 # 0 +0xDA4A 0xFF1A # 0 +0xDA4B 0xFF1B # 0 +0xDA4C 0xFF1C # 0 +0xDA4D 0xFF1D # 0 +0xDA4E 0xFF1E # 0 +0xDA4F 0xFF1F # 0 +0xDA50 0xFF20 # 0 +0xDA51 0xFF21 # 0 +0xDA52 0xFF22 # 0 +0xDA53 0xFF23 # 0 +0xDA54 0xFF24 # 0 +0xDA55 0xFF25 # 0 +0xDA56 0xFF26 # 0 +0xDA57 0xFF27 # 0 +0xDA58 0xFF28 # 0 +0xDA59 0xFF29 # 0 +0xDA5A 0xFF2A # 0 +0xDA5B 0xFF2B # 0 +0xDA5C 0xFF2C # 0 +0xDA5D 0xFF2D # 0 +0xDA5E 0xFF2E # 0 +0xDA5F 0xFF2F # 0 +0xDA60 0xFF30 # 0 +0xDA61 0xFF31 # 0 +0xDA62 0xFF32 # 0 +0xDA63 0xFF33 # 0 +0xDA64 0xFF34 # 0 +0xDA65 0xFF35 # 0 +0xDA66 0xFF36 # 0 +0xDA67 0xFF37 # 0 +0xDA68 0xFF38 # 0 +0xDA69 0xFF39 # 0 +0xDA6A 0xFF3A # 0 +0xDA6B 0xFF3B # 0 +0xDA6C 0xFFE6 # 0 +0xDA6D 0xFF3D # 0 +0xDA6E 0xFF3E # 0 +0xDA6F 0xFF3F # 0 +0xDA70 0xFF40 # 0 +0xDA71 0xFF41 # 0 +0xDA72 0xFF42 # 0 +0xDA73 0xFF43 # 0 +0xDA74 0xFF44 # 0 +0xDA75 0xFF45 # 0 +0xDA76 0xFF46 # 0 +0xDA77 0xFF47 # 0 +0xDA78 0xFF48 # 0 +0xDA79 0xFF49 # 0 +0xDA7A 0xFF4A # 0 +0xDA7B 0xFF4B # 0 +0xDA7C 0xFF4C # 0 +0xDA7D 0xFF4D # 0 +0xDA7E 0xFF4E # 0 +0xDA91 0xFF4F # 0 +0xDA92 0xFF50 # 0 +0xDA93 0xFF51 # 0 +0xDA94 0xFF52 # 0 +0xDA95 0xFF53 # 0 +0xDA96 0xFF54 # 0 +0xDA97 0xFF55 # 0 +0xDA98 0xFF56 # 0 +0xDA99 0xFF57 # 0 +0xDA9A 0xFF58 # 0 +0xDA9B 0xFF59 # 0 +0xDA9C 0xFF5A # 0 +0xDA9D 0xFF5B # 0 +0xDA9E 0xFF5C # 0 +0xDA9F 0xFF5D # 0 +0xDAA0 0xFFE3 # 0 +0xDAD4 0x115F # 0 +0xDAD5 0x1114 # 0 +0xDAD6 0x1115 # 0 +0xDAD7 0x11C7 # 0 +0xDAD8 0x11C8 # 0 +0xDAD9 0x11CC # 0 +0xDADA 0x11CE # 0 +0xDADB 0x11D3 # 0 +0xDADC 0x11D7 # 0 +0xDADD 0x11D9 # 0 +0xDADE 0x111C # 0 +0xDADF 0x11DD # 0 +0xDAE0 0x11DF # 0 +0xDAE1 0x111D # 0 +0xDAE2 0x111E # 0 +0xDAE3 0x1120 # 0 +0xDAE4 0x1122 # 0 +0xDAE5 0x1123 # 0 +0xDAE6 0x1127 # 0 +0xDAE7 0x1128 # 0 +0xDAE8 0x112B # 0 +0xDAE9 0x112C # 0 +0xDAEA 0x112D # 0 +0xDAEB 0x112E # 0 +0xDAEC 0x112F # 0 +0xDAED 0x1132 # 0 +0xDAEE 0x1136 # 0 +0xDAEF 0x1140 # 0 +0xDAF0 0x1147 # 0 +0xDAF1 0x114C # 0 +0xDAF2 0x1145 # 0 +0xDAF3 0x1146 # 0 +0xDAF4 0x1157 # 0 +0xDAF5 0x1158 # 0 +0xDAF6 0x1159 # 0 +0xDAF7 0x1184 # 0 +0xDAF8 0x1185 # 0 +0xDAF9 0x1188 # 0 +0xDAFA 0x1191 # 0 +0xDAFB 0x1192 # 0 +0xDAFC 0x1194 # 0 +0xDAFD 0x119E # 0 +0xDAFE 0x11A1 # 0 +0xDB31 0x2170 # 0 +0xDB32 0x2171 # 0 +0xDB33 0x2172 # 0 +0xDB34 0x2173 # 0 +0xDB35 0x2174 # 0 +0xDB36 0x2175 # 0 +0xDB37 0x2176 # 0 +0xDB38 0x2177 # 0 +0xDB39 0x2178 # 0 +0xDB3A 0x2179 # 0 +0xDB40 0x2160 # 0 +0xDB41 0x2161 # 0 +0xDB42 0x2162 # 0 +0xDB43 0x2163 # 0 +0xDB44 0x2164 # 0 +0xDB45 0x2165 # 0 +0xDB46 0x2166 # 0 +0xDB47 0x2167 # 0 +0xDB48 0x2168 # 0 +0xDB49 0x2169 # 0 +0xDB51 0x0391 # 0 +0xDB52 0x0392 # 0 +0xDB53 0x0393 # 0 +0xDB54 0x0394 # 0 +0xDB55 0x0395 # 0 +0xDB56 0x0396 # 0 +0xDB57 0x0397 # 0 +0xDB58 0x0398 # 0 +0xDB59 0x0399 # 0 +0xDB5A 0x039A # 0 +0xDB5B 0x039B # 0 +0xDB5C 0x039C # 0 +0xDB5D 0x039D # 0 +0xDB5E 0x039E # 0 +0xDB5F 0x039F # 0 +0xDB60 0x03A0 # 0 +0xDB61 0x03A1 # 0 +0xDB62 0x03A3 # 0 +0xDB63 0x03A4 # 0 +0xDB64 0x03A5 # 0 +0xDB65 0x03A6 # 0 +0xDB66 0x03A7 # 0 +0xDB67 0x03A8 # 0 +0xDB68 0x03A9 # 0 +0xDB71 0x03B1 # 0 +0xDB72 0x03B2 # 0 +0xDB73 0x03B3 # 0 +0xDB74 0x03B4 # 0 +0xDB75 0x03B5 # 0 +0xDB76 0x03B6 # 0 +0xDB77 0x03B7 # 0 +0xDB78 0x03B8 # 0 +0xDB79 0x03B9 # 0 +0xDB7A 0x03BA # 0 +0xDB7B 0x03BB # 0 +0xDB7C 0x03BC # 0 +0xDB7D 0x03BD # 0 +0xDB7E 0x03BE # 0 +0xDB91 0x03BF # 0 +0xDB92 0x03C0 # 0 +0xDB93 0x03C1 # 0 +0xDB94 0x03C3 # 0 +0xDB95 0x03C4 # 0 +0xDB96 0x03C5 # 0 +0xDB97 0x03C6 # 0 +0xDB98 0x03C7 # 0 +0xDB99 0x03C8 # 0 +0xDB9A 0x03C9 # 0 +0xDBA1 0x2500 # 0 +0xDBA2 0x2502 # 0 +0xDBA3 0x250C # 0 +0xDBA4 0x2510 # 0 +0xDBA5 0x2518 # 0 +0xDBA6 0x2514 # 0 +0xDBA7 0x251C # 0 +0xDBA8 0x252C # 0 +0xDBA9 0x2524 # 0 +0xDBAA 0x2534 # 0 +0xDBAB 0x253C # 0 +0xDBAC 0x2501 # 0 +0xDBAD 0x2503 # 0 +0xDBAE 0x250F # 0 +0xDBAF 0x2513 # 0 +0xDBB0 0x251B # 0 +0xDBB1 0x2517 # 0 +0xDBB2 0x2523 # 0 +0xDBB3 0x2533 # 0 +0xDBB4 0x252B # 0 +0xDBB5 0x253B # 0 +0xDBB6 0x254B # 0 +0xDBB7 0x2520 # 0 +0xDBB8 0x252F # 0 +0xDBB9 0x2528 # 0 +0xDBBA 0x2537 # 0 +0xDBBB 0x253F # 0 +0xDBBC 0x251D # 0 +0xDBBD 0x2530 # 0 +0xDBBE 0x2525 # 0 +0xDBBF 0x2538 # 0 +0xDBC0 0x2542 # 0 +0xDBC1 0x2512 # 0 +0xDBC2 0x2511 # 0 +0xDBC3 0x251A # 0 +0xDBC4 0x2519 # 0 +0xDBC5 0x2516 # 0 +0xDBC6 0x2515 # 0 +0xDBC7 0x250E # 0 +0xDBC8 0x250D # 0 +0xDBC9 0x251E # 0 +0xDBCA 0x251F # 0 +0xDBCB 0x2521 # 0 +0xDBCC 0x2522 # 0 +0xDBCD 0x2526 # 0 +0xDBCE 0x2527 # 0 +0xDBCF 0x2529 # 0 +0xDBD0 0x252A # 0 +0xDBD1 0x252D # 0 +0xDBD2 0x252E # 0 +0xDBD3 0x2531 # 0 +0xDBD4 0x2532 # 0 +0xDBD5 0x2535 # 0 +0xDBD6 0x2536 # 0 +0xDBD7 0x2539 # 0 +0xDBD8 0x253A # 0 +0xDBD9 0x253D # 0 +0xDBDA 0x253E # 0 +0xDBDB 0x2540 # 0 +0xDBDC 0x2541 # 0 +0xDBDD 0x2543 # 0 +0xDBDE 0x2544 # 0 +0xDBDF 0x2545 # 0 +0xDBE0 0x2546 # 0 +0xDBE1 0x2547 # 0 +0xDBE2 0x2548 # 0 +0xDBE3 0x2549 # 0 +0xDBE4 0x254A # 0 +0xDC31 0x3395 # 0 +0xDC32 0x3396 # 0 +0xDC33 0x3397 # 0 +0xDC34 0x2113 # 0 +0xDC35 0x3398 # 0 +0xDC36 0x33C4 # 0 +0xDC37 0x33A3 # 0 +0xDC38 0x33A4 # 0 +0xDC39 0x33A5 # 0 +0xDC3A 0x33A6 # 0 +0xDC3B 0x3399 # 0 +0xDC3C 0x339A # 0 +0xDC3D 0x339B # 0 +0xDC3E 0x339C # 0 +0xDC3F 0x339D # 0 +0xDC40 0x339E # 0 +0xDC41 0x339F # 0 +0xDC42 0x33A0 # 0 +0xDC43 0x33A1 # 0 +0xDC44 0x33A2 # 0 +0xDC45 0x33CA # 0 +0xDC46 0x338D # 0 +0xDC47 0x338E # 0 +0xDC48 0x338F # 0 +0xDC49 0x33CF # 0 +0xDC4A 0x3388 # 0 +0xDC4B 0x3389 # 0 +0xDC4C 0x33C8 # 0 +0xDC4D 0x33A7 # 0 +0xDC4E 0x33A8 # 0 +0xDC4F 0x33B0 # 0 +0xDC50 0x33B1 # 0 +0xDC51 0x33B2 # 0 +0xDC52 0x33B3 # 0 +0xDC53 0x33B4 # 0 +0xDC54 0x33B5 # 0 +0xDC55 0x33B6 # 0 +0xDC56 0x33B7 # 0 +0xDC57 0x33B8 # 0 +0xDC58 0x33B9 # 0 +0xDC59 0x3380 # 0 +0xDC5A 0x3381 # 0 +0xDC5B 0x3382 # 0 +0xDC5C 0x3383 # 0 +0xDC5D 0x3384 # 0 +0xDC5E 0x33BA # 0 +0xDC5F 0x33BB # 0 +0xDC60 0x33BC # 0 +0xDC61 0x33BD # 0 +0xDC62 0x33BE # 0 +0xDC63 0x33BF # 0 +0xDC64 0x3390 # 0 +0xDC65 0x3391 # 0 +0xDC66 0x3392 # 0 +0xDC67 0x3393 # 0 +0xDC68 0x3394 # 0 +0xDC69 0x2126 # 0 +0xDC6A 0x33C0 # 0 +0xDC6B 0x33C1 # 0 +0xDC6C 0x338A # 0 +0xDC6D 0x338B # 0 +0xDC6E 0x338C # 0 +0xDC6F 0x33D6 # 0 +0xDC70 0x33C5 # 0 +0xDC71 0x33AD # 0 +0xDC72 0x33AE # 0 +0xDC73 0x33AF # 0 +0xDC74 0x33DB # 0 +0xDC75 0x33A9 # 0 +0xDC76 0x33AA # 0 +0xDC77 0x33AB # 0 +0xDC78 0x33AC # 0 +0xDC79 0x33DD # 0 +0xDC7A 0x33D0 # 0 +0xDC7B 0x33D3 # 0 +0xDC7C 0x33C3 # 0 +0xDC7D 0x33C9 # 0 +0xDC7E 0x33DC # 0 +0xDC91 0x33C6 # 0 +0xDCA1 0x00C6 # 0 +0xDCA2 0x00D0 # 0 +0xDCA3 0x00AA # 0 +0xDCA4 0x0126 # 0 +0xDCA6 0x0132 # 0 +0xDCA8 0x013F # 0 +0xDCA9 0x0141 # 0 +0xDCAA 0x00D8 # 0 +0xDCAB 0x0152 # 0 +0xDCAC 0x00BA # 0 +0xDCAD 0x00DE # 0 +0xDCAE 0x0166 # 0 +0xDCAF 0x014A # 0 +0xDCB1 0x3260 # 0 +0xDCB2 0x3261 # 0 +0xDCB3 0x3262 # 0 +0xDCB4 0x3263 # 0 +0xDCB5 0x3264 # 0 +0xDCB6 0x3265 # 0 +0xDCB7 0x3266 # 0 +0xDCB8 0x3267 # 0 +0xDCB9 0x3268 # 0 +0xDCBA 0x3269 # 0 +0xDCBB 0x326A # 0 +0xDCBC 0x326B # 0 +0xDCBD 0x326C # 0 +0xDCBE 0x326D # 0 +0xDCBF 0x326E # 0 +0xDCC0 0x326F # 0 +0xDCC1 0x3270 # 0 +0xDCC2 0x3271 # 0 +0xDCC3 0x3272 # 0 +0xDCC4 0x3273 # 0 +0xDCC5 0x3274 # 0 +0xDCC6 0x3275 # 0 +0xDCC7 0x3276 # 0 +0xDCC8 0x3277 # 0 +0xDCC9 0x3278 # 0 +0xDCCA 0x3279 # 0 +0xDCCB 0x327A # 0 +0xDCCC 0x327B # 0 +0xDCCD 0x24D0 # 0 +0xDCCE 0x24D1 # 0 +0xDCCF 0x24D2 # 0 +0xDCD0 0x24D3 # 0 +0xDCD1 0x24D4 # 0 +0xDCD2 0x24D5 # 0 +0xDCD3 0x24D6 # 0 +0xDCD4 0x24D7 # 0 +0xDCD5 0x24D8 # 0 +0xDCD6 0x24D9 # 0 +0xDCD7 0x24DA # 0 +0xDCD8 0x24DB # 0 +0xDCD9 0x24DC # 0 +0xDCDA 0x24DD # 0 +0xDCDB 0x24DE # 0 +0xDCDC 0x24DF # 0 +0xDCDD 0x24E0 # 0 +0xDCDE 0x24E1 # 0 +0xDCDF 0x24E2 # 0 +0xDCE0 0x24E3 # 0 +0xDCE1 0x24E4 # 0 +0xDCE2 0x24E5 # 0 +0xDCE3 0x24E6 # 0 +0xDCE4 0x24E7 # 0 +0xDCE5 0x24E8 # 0 +0xDCE6 0x24E9 # 0 +0xDCE7 0x2460 # 0 +0xDCE8 0x2461 # 0 +0xDCE9 0x2462 # 0 +0xDCEA 0x2463 # 0 +0xDCEB 0x2464 # 0 +0xDCEC 0x2465 # 0 +0xDCED 0x2466 # 0 +0xDCEE 0x2467 # 0 +0xDCEF 0x2468 # 0 +0xDCF0 0x2469 # 0 +0xDCF1 0x246A # 0 +0xDCF2 0x246B # 0 +0xDCF3 0x246C # 0 +0xDCF4 0x246D # 0 +0xDCF5 0x246E # 0 +0xDCF6 0x00BD # 0 +0xDCF7 0x2153 # 0 +0xDCF8 0x2154 # 0 +0xDCF9 0x00BC # 0 +0xDCFA 0x00BE # 0 +0xDCFB 0x215B # 0 +0xDCFC 0x215C # 0 +0xDCFD 0x215D # 0 +0xDCFE 0x215E # 0 +0xDD31 0x00E6 # 0 +0xDD32 0x0111 # 0 +0xDD33 0x00F0 # 0 +0xDD34 0x0127 # 0 +0xDD35 0x0131 # 0 +0xDD36 0x0133 # 0 +0xDD37 0x0138 # 0 +0xDD38 0x0140 # 0 +0xDD39 0x0142 # 0 +0xDD3A 0x00F8 # 0 +0xDD3B 0x0153 # 0 +0xDD3C 0x00DF # 0 +0xDD3D 0x00FE # 0 +0xDD3E 0x0167 # 0 +0xDD3F 0x014B # 0 +0xDD40 0x0149 # 0 +0xDD41 0x3200 # 0 +0xDD42 0x3201 # 0 +0xDD43 0x3202 # 0 +0xDD44 0x3203 # 0 +0xDD45 0x3204 # 0 +0xDD46 0x3205 # 0 +0xDD47 0x3206 # 0 +0xDD48 0x3207 # 0 +0xDD49 0x3208 # 0 +0xDD4A 0x3209 # 0 +0xDD4B 0x320A # 0 +0xDD4C 0x320B # 0 +0xDD4D 0x320C # 0 +0xDD4E 0x320D # 0 +0xDD4F 0x320E # 0 +0xDD50 0x320F # 0 +0xDD51 0x3210 # 0 +0xDD52 0x3211 # 0 +0xDD53 0x3212 # 0 +0xDD54 0x3213 # 0 +0xDD55 0x3214 # 0 +0xDD56 0x3215 # 0 +0xDD57 0x3216 # 0 +0xDD58 0x3217 # 0 +0xDD59 0x3218 # 0 +0xDD5A 0x3219 # 0 +0xDD5B 0x321A # 0 +0xDD5C 0x321B # 0 +0xDD5D 0x249C # 0 +0xDD5E 0x249D # 0 +0xDD5F 0x249E # 0 +0xDD60 0x249F # 0 +0xDD61 0x24A0 # 0 +0xDD62 0x24A1 # 0 +0xDD63 0x24A2 # 0 +0xDD64 0x24A3 # 0 +0xDD65 0x24A4 # 0 +0xDD66 0x24A5 # 0 +0xDD67 0x24A6 # 0 +0xDD68 0x24A7 # 0 +0xDD69 0x24A8 # 0 +0xDD6A 0x24A9 # 0 +0xDD6B 0x24AA # 0 +0xDD6C 0x24AB # 0 +0xDD6D 0x24AC # 0 +0xDD6E 0x24AD # 0 +0xDD6F 0x24AE # 0 +0xDD70 0x24AF # 0 +0xDD71 0x24B0 # 0 +0xDD72 0x24B1 # 0 +0xDD73 0x24B2 # 0 +0xDD74 0x24B3 # 0 +0xDD75 0x24B4 # 0 +0xDD76 0x24B5 # 0 +0xDD77 0x2474 # 0 +0xDD78 0x2475 # 0 +0xDD79 0x2476 # 0 +0xDD7A 0x2477 # 0 +0xDD7B 0x2478 # 0 +0xDD7C 0x2479 # 0 +0xDD7D 0x247A # 0 +0xDD7E 0x247B # 0 +0xDD91 0x247C # 0 +0xDD92 0x247D # 0 +0xDD93 0x247E # 0 +0xDD94 0x247F # 0 +0xDD95 0x2480 # 0 +0xDD96 0x2481 # 0 +0xDD97 0x2482 # 0 +0xDD98 0x00B9 # 0 +0xDD99 0x00B2 # 0 +0xDD9A 0x00B3 # 0 +0xDD9B 0x2074 # 0 +0xDD9C 0x207F # 0 +0xDD9D 0x2081 # 0 +0xDD9E 0x2082 # 0 +0xDD9F 0x2083 # 0 +0xDDA0 0x2084 # 0 +0xDDA1 0x3041 # 0 +0xDDA2 0x3042 # 0 +0xDDA3 0x3043 # 0 +0xDDA4 0x3044 # 0 +0xDDA5 0x3045 # 0 +0xDDA6 0x3046 # 0 +0xDDA7 0x3047 # 0 +0xDDA8 0x3048 # 0 +0xDDA9 0x3049 # 0 +0xDDAA 0x304A # 0 +0xDDAB 0x304B # 0 +0xDDAC 0x304C # 0 +0xDDAD 0x304D # 0 +0xDDAE 0x304E # 0 +0xDDAF 0x304F # 0 +0xDDB0 0x3050 # 0 +0xDDB1 0x3051 # 0 +0xDDB2 0x3052 # 0 +0xDDB3 0x3053 # 0 +0xDDB4 0x3054 # 0 +0xDDB5 0x3055 # 0 +0xDDB6 0x3056 # 0 +0xDDB7 0x3057 # 0 +0xDDB8 0x3058 # 0 +0xDDB9 0x3059 # 0 +0xDDBA 0x305A # 0 +0xDDBB 0x305B # 0 +0xDDBC 0x305C # 0 +0xDDBD 0x305D # 0 +0xDDBE 0x305E # 0 +0xDDBF 0x305F # 0 +0xDDC0 0x3060 # 0 +0xDDC1 0x3061 # 0 +0xDDC2 0x3062 # 0 +0xDDC3 0x3063 # 0 +0xDDC4 0x3064 # 0 +0xDDC5 0x3065 # 0 +0xDDC6 0x3066 # 0 +0xDDC7 0x3067 # 0 +0xDDC8 0x3068 # 0 +0xDDC9 0x3069 # 0 +0xDDCA 0x306A # 0 +0xDDCB 0x306B # 0 +0xDDCC 0x306C # 0 +0xDDCD 0x306D # 0 +0xDDCE 0x306E # 0 +0xDDCF 0x306F # 0 +0xDDD0 0x3070 # 0 +0xDDD1 0x3071 # 0 +0xDDD2 0x3072 # 0 +0xDDD3 0x3073 # 0 +0xDDD4 0x3074 # 0 +0xDDD5 0x3075 # 0 +0xDDD6 0x3076 # 0 +0xDDD7 0x3077 # 0 +0xDDD8 0x3078 # 0 +0xDDD9 0x3079 # 0 +0xDDDA 0x307A # 0 +0xDDDB 0x307B # 0 +0xDDDC 0x307C # 0 +0xDDDD 0x307D # 0 +0xDDDE 0x307E # 0 +0xDDDF 0x307F # 0 +0xDDE0 0x3080 # 0 +0xDDE1 0x3081 # 0 +0xDDE2 0x3082 # 0 +0xDDE3 0x3083 # 0 +0xDDE4 0x3084 # 0 +0xDDE5 0x3085 # 0 +0xDDE6 0x3086 # 0 +0xDDE7 0x3087 # 0 +0xDDE8 0x3088 # 0 +0xDDE9 0x3089 # 0 +0xDDEA 0x308A # 0 +0xDDEB 0x308B # 0 +0xDDEC 0x308C # 0 +0xDDED 0x308D # 0 +0xDDEE 0x308E # 0 +0xDDEF 0x308F # 0 +0xDDF0 0x3090 # 0 +0xDDF1 0x3091 # 0 +0xDDF2 0x3092 # 0 +0xDDF3 0x3093 # 0 +0xDE31 0x30A1 # 0 +0xDE32 0x30A2 # 0 +0xDE33 0x30A3 # 0 +0xDE34 0x30A4 # 0 +0xDE35 0x30A5 # 0 +0xDE36 0x30A6 # 0 +0xDE37 0x30A7 # 0 +0xDE38 0x30A8 # 0 +0xDE39 0x30A9 # 0 +0xDE3A 0x30AA # 0 +0xDE3B 0x30AB # 0 +0xDE3C 0x30AC # 0 +0xDE3D 0x30AD # 0 +0xDE3E 0x30AE # 0 +0xDE3F 0x30AF # 0 +0xDE40 0x30B0 # 0 +0xDE41 0x30B1 # 0 +0xDE42 0x30B2 # 0 +0xDE43 0x30B3 # 0 +0xDE44 0x30B4 # 0 +0xDE45 0x30B5 # 0 +0xDE46 0x30B6 # 0 +0xDE47 0x30B7 # 0 +0xDE48 0x30B8 # 0 +0xDE49 0x30B9 # 0 +0xDE4A 0x30BA # 0 +0xDE4B 0x30BB # 0 +0xDE4C 0x30BC # 0 +0xDE4D 0x30BD # 0 +0xDE4E 0x30BE # 0 +0xDE4F 0x30BF # 0 +0xDE50 0x30C0 # 0 +0xDE51 0x30C1 # 0 +0xDE52 0x30C2 # 0 +0xDE53 0x30C3 # 0 +0xDE54 0x30C4 # 0 +0xDE55 0x30C5 # 0 +0xDE56 0x30C6 # 0 +0xDE57 0x30C7 # 0 +0xDE58 0x30C8 # 0 +0xDE59 0x30C9 # 0 +0xDE5A 0x30CA # 0 +0xDE5B 0x30CB # 0 +0xDE5C 0x30CC # 0 +0xDE5D 0x30CD # 0 +0xDE5E 0x30CE # 0 +0xDE5F 0x30CF # 0 +0xDE60 0x30D0 # 0 +0xDE61 0x30D1 # 0 +0xDE62 0x30D2 # 0 +0xDE63 0x30D3 # 0 +0xDE64 0x30D4 # 0 +0xDE65 0x30D5 # 0 +0xDE66 0x30D6 # 0 +0xDE67 0x30D7 # 0 +0xDE68 0x30D8 # 0 +0xDE69 0x30D9 # 0 +0xDE6A 0x30DA # 0 +0xDE6B 0x30DB # 0 +0xDE6C 0x30DC # 0 +0xDE6D 0x30DD # 0 +0xDE6E 0x30DE # 0 +0xDE6F 0x30DF # 0 +0xDE70 0x30E0 # 0 +0xDE71 0x30E1 # 0 +0xDE72 0x30E2 # 0 +0xDE73 0x30E3 # 0 +0xDE74 0x30E4 # 0 +0xDE75 0x30E5 # 0 +0xDE76 0x30E6 # 0 +0xDE77 0x30E7 # 0 +0xDE78 0x30E8 # 0 +0xDE79 0x30E9 # 0 +0xDE7A 0x30EA # 0 +0xDE7B 0x30EB # 0 +0xDE7C 0x30EC # 0 +0xDE7D 0x30ED # 0 +0xDE7E 0x30EE # 0 +0xDE91 0x30EF # 0 +0xDE92 0x30F0 # 0 +0xDE93 0x30F1 # 0 +0xDE94 0x30F2 # 0 +0xDE95 0x30F3 # 0 +0xDE96 0x30F4 # 0 +0xDE97 0x30F5 # 0 +0xDE98 0x30F6 # 0 +0xDEA1 0x0410 # 0 +0xDEA2 0x0411 # 0 +0xDEA3 0x0412 # 0 +0xDEA4 0x0413 # 0 +0xDEA5 0x0414 # 0 +0xDEA6 0x0415 # 0 +0xDEA7 0x0401 # 0 +0xDEA8 0x0416 # 0 +0xDEA9 0x0417 # 0 +0xDEAA 0x0418 # 0 +0xDEAB 0x0419 # 0 +0xDEAC 0x041A # 0 +0xDEAD 0x041B # 0 +0xDEAE 0x041C # 0 +0xDEAF 0x041D # 0 +0xDEB0 0x041E # 0 +0xDEB1 0x041F # 0 +0xDEB2 0x0420 # 0 +0xDEB3 0x0421 # 0 +0xDEB4 0x0422 # 0 +0xDEB5 0x0423 # 0 +0xDEB6 0x0424 # 0 +0xDEB7 0x0425 # 0 +0xDEB8 0x0426 # 0 +0xDEB9 0x0427 # 0 +0xDEBA 0x0428 # 0 +0xDEBB 0x0429 # 0 +0xDEBC 0x042A # 0 +0xDEBD 0x042B # 0 +0xDEBE 0x042C # 0 +0xDEBF 0x042D # 0 +0xDEC0 0x042E # 0 +0xDEC1 0x042F # 0 +0xDED1 0x0430 # 0 +0xDED2 0x0431 # 0 +0xDED3 0x0432 # 0 +0xDED4 0x0433 # 0 +0xDED5 0x0434 # 0 +0xDED6 0x0435 # 0 +0xDED7 0x0451 # 0 +0xDED8 0x0436 # 0 +0xDED9 0x0437 # 0 +0xDEDA 0x0438 # 0 +0xDEDB 0x0439 # 0 +0xDEDC 0x043A # 0 +0xDEDD 0x043B # 0 +0xDEDE 0x043C # 0 +0xDEDF 0x043D # 0 +0xDEE0 0x043E # 0 +0xDEE1 0x043F # 0 +0xDEE2 0x0440 # 0 +0xDEE3 0x0441 # 0 +0xDEE4 0x0442 # 0 +0xDEE5 0x0443 # 0 +0xDEE6 0x0444 # 0 +0xDEE7 0x0445 # 0 +0xDEE8 0x0446 # 0 +0xDEE9 0x0447 # 0 +0xDEEA 0x0448 # 0 +0xDEEB 0x0449 # 0 +0xDEEC 0x044A # 0 +0xDEED 0x044B # 0 +0xDEEE 0x044C # 0 +0xDEEF 0x044D # 0 +0xDEF0 0x044E # 0 +0xDEF1 0x044F # 0 +0xE031 0x4F3D # 0 +0xE032 0x4F73 # 0 +0xE033 0x5047 # 0 +0xE034 0x50F9 # 0 +0xE035 0x52A0 # 0 +0xE036 0x53EF # 0 +0xE037 0x5475 # 0 +0xE038 0x54E5 # 0 +0xE039 0x5609 # 0 +0xE03A 0x5AC1 # 0 +0xE03B 0x5BB6 # 0 +0xE03C 0x6687 # 0 +0xE03D 0x67B6 # 0 +0xE03E 0x67B7 # 0 +0xE03F 0x67EF # 0 +0xE040 0x6B4C # 0 +0xE041 0x73C2 # 0 +0xE042 0x75C2 # 0 +0xE043 0x7A3C # 0 +0xE044 0x82DB # 0 +0xE045 0x8304 # 0 +0xE046 0x8857 # 0 +0xE047 0x8888 # 0 +0xE048 0x8A36 # 0 +0xE049 0x8CC8 # 0 +0xE04A 0x8DCF # 0 +0xE04B 0x8EFB # 0 +0xE04C 0x8FE6 # 0 +0xE04D 0x99D5 # 0 +0xE04E 0x523B # 0 +0xE04F 0x5374 # 0 +0xE050 0x5404 # 0 +0xE051 0x606A # 0 +0xE052 0x6164 # 0 +0xE053 0x6BBC # 0 +0xE054 0x73CF # 0 +0xE055 0x811A # 0 +0xE056 0x89BA # 0 +0xE057 0x89D2 # 0 +0xE058 0x95A3 # 0 +0xE059 0x4F83 # 0 +0xE05A 0x520A # 0 +0xE05B 0x58BE # 0 +0xE05C 0x5978 # 0 +0xE05D 0x59E6 # 0 +0xE05E 0x5E72 # 0 +0xE05F 0x5E79 # 0 +0xE060 0x61C7 # 0 +0xE061 0x63C0 # 0 +0xE062 0x6746 # 0 +0xE063 0x67EC # 0 +0xE064 0x687F # 0 +0xE065 0x6F97 # 0 +0xE066 0x764E # 0 +0xE067 0x770B # 0 +0xE068 0x78F5 # 0 +0xE069 0x7A08 # 0 +0xE06A 0x7AFF # 0 +0xE06B 0x7C21 # 0 +0xE06C 0x809D # 0 +0xE06D 0x826E # 0 +0xE06E 0x8271 # 0 +0xE06F 0x8AEB # 0 +0xE070 0x9593 # 0 +0xE071 0x4E6B # 0 +0xE072 0x559D # 0 +0xE073 0x66F7 # 0 +0xE074 0x6E34 # 0 +0xE075 0x78A3 # 0 +0xE076 0x7AED # 0 +0xE077 0x845B # 0 +0xE078 0x8910 # 0 +0xE079 0x874E # 0 +0xE07A 0x97A8 # 0 +0xE07B 0x52D8 # 0 +0xE07C 0x574E # 0 +0xE07D 0x582A # 0 +0xE07E 0x5D4C # 0 +0xE091 0x611F # 0 +0xE092 0x61BE # 0 +0xE093 0x6221 # 0 +0xE094 0x6562 # 0 +0xE095 0x67D1 # 0 +0xE096 0x6A44 # 0 +0xE097 0x6E1B # 0 +0xE098 0x7518 # 0 +0xE099 0x75B3 # 0 +0xE09A 0x76E3 # 0 +0xE09B 0x77B0 # 0 +0xE09C 0x7D3A # 0 +0xE09D 0x90AF # 0 +0xE09E 0x9451 # 0 +0xE09F 0x9452 # 0 +0xE0A0 0x9F95 # 0 +0xE0A1 0x5323 # 0 +0xE0A2 0x5CAC # 0 +0xE0A3 0x7532 # 0 +0xE0A4 0x80DB # 0 +0xE0A5 0x9240 # 0 +0xE0A6 0x9598 # 0 +0xE0A7 0x525B # 0 +0xE0A8 0x5808 # 0 +0xE0A9 0x59DC # 0 +0xE0AA 0x5CA1 # 0 +0xE0AB 0x5D17 # 0 +0xE0AC 0x5EB7 # 0 +0xE0AD 0x5F3A # 0 +0xE0AE 0x5F4A # 0 +0xE0AF 0x6177 # 0 +0xE0B0 0x6C5F # 0 +0xE0B1 0x757A # 0 +0xE0B2 0x7586 # 0 +0xE0B3 0x7CE0 # 0 +0xE0B4 0x7D73 # 0 +0xE0B5 0x7DB1 # 0 +0xE0B6 0x7F8C # 0 +0xE0B7 0x8154 # 0 +0xE0B8 0x8221 # 0 +0xE0B9 0x8591 # 0 +0xE0BA 0x8941 # 0 +0xE0BB 0x8B1B # 0 +0xE0BC 0x92FC # 0 +0xE0BD 0x964D # 0 +0xE0BE 0x9C47 # 0 +0xE0BF 0x4ECB # 0 +0xE0C0 0x4EF7 # 0 +0xE0C1 0x500B # 0 +0xE0C2 0x51F1 # 0 +0xE0C3 0x584F # 0 +0xE0C4 0x6137 # 0 +0xE0C5 0x613E # 0 +0xE0C6 0x6168 # 0 +0xE0C7 0x6539 # 0 +0xE0C8 0x69EA # 0 +0xE0C9 0x6F11 # 0 +0xE0CA 0x75A5 # 0 +0xE0CB 0x7686 # 0 +0xE0CC 0x76D6 # 0 +0xE0CD 0x7B87 # 0 +0xE0CE 0x82A5 # 0 +0xE0CF 0x84CB # 0 +0xE0D0 0xF900 # 0 +0xE0D1 0x93A7 # 0 +0xE0D2 0x958B # 0 +0xE0D3 0x5580 # 0 +0xE0D4 0x5BA2 # 0 +0xE0D5 0x5751 # 0 +0xE0D6 0xF901 # 0 +0xE0D7 0x7CB3 # 0 +0xE0D8 0x7FB9 # 0 +0xE0D9 0x91B5 # 0 +0xE0DA 0x5028 # 0 +0xE0DB 0x53BB # 0 +0xE0DC 0x5C45 # 0 +0xE0DD 0x5DE8 # 0 +0xE0DE 0x62D2 # 0 +0xE0DF 0x636E # 0 +0xE0E0 0x64DA # 0 +0xE0E1 0x64E7 # 0 +0xE0E2 0x6E20 # 0 +0xE0E3 0x70AC # 0 +0xE0E4 0x795B # 0 +0xE0E5 0x8DDD # 0 +0xE0E6 0x8E1E # 0 +0xE0E7 0xF902 # 0 +0xE0E8 0x907D # 0 +0xE0E9 0x9245 # 0 +0xE0EA 0x92F8 # 0 +0xE0EB 0x4E7E # 0 +0xE0EC 0x4EF6 # 0 +0xE0ED 0x5065 # 0 +0xE0EE 0x5DFE # 0 +0xE0EF 0x5EFA # 0 +0xE0F0 0x6106 # 0 +0xE0F1 0x6957 # 0 +0xE0F2 0x8171 # 0 +0xE0F3 0x8654 # 0 +0xE0F4 0x8E47 # 0 +0xE0F5 0x9375 # 0 +0xE0F6 0x9A2B # 0 +0xE0F7 0x4E5E # 0 +0xE0F8 0x5091 # 0 +0xE0F9 0x6770 # 0 +0xE0FA 0x6840 # 0 +0xE0FB 0x5109 # 0 +0xE0FC 0x528D # 0 +0xE0FD 0x5292 # 0 +0xE0FE 0x6AA2 # 0 +0xE131 0x77BC # 0 +0xE132 0x9210 # 0 +0xE133 0x9ED4 # 0 +0xE134 0x52AB # 0 +0xE135 0x602F # 0 +0xE136 0x8FF2 # 0 +0xE137 0x5048 # 0 +0xE138 0x61A9 # 0 +0xE139 0x63ED # 0 +0xE13A 0x64CA # 0 +0xE13B 0x683C # 0 +0xE13C 0x6A84 # 0 +0xE13D 0x6FC0 # 0 +0xE13E 0x8188 # 0 +0xE13F 0x89A1 # 0 +0xE140 0x9694 # 0 +0xE141 0x5805 # 0 +0xE142 0x727D # 0 +0xE143 0x72AC # 0 +0xE144 0x7504 # 0 +0xE145 0x7D79 # 0 +0xE146 0x7E6D # 0 +0xE147 0x80A9 # 0 +0xE148 0x898B # 0 +0xE149 0x8B74 # 0 +0xE14A 0x9063 # 0 +0xE14B 0x9D51 # 0 +0xE14C 0x6289 # 0 +0xE14D 0x6C7A # 0 +0xE14E 0x6F54 # 0 +0xE14F 0x7D50 # 0 +0xE150 0x7F3A # 0 +0xE151 0x8A23 # 0 +0xE152 0x517C # 0 +0xE153 0x614A # 0 +0xE154 0x7B9D # 0 +0xE155 0x8B19 # 0 +0xE156 0x9257 # 0 +0xE157 0x938C # 0 +0xE158 0x4EAC # 0 +0xE159 0x4FD3 # 0 +0xE15A 0x501E # 0 +0xE15B 0x50BE # 0 +0xE15C 0x5106 # 0 +0xE15D 0x52C1 # 0 +0xE15E 0x52CD # 0 +0xE15F 0x537F # 0 +0xE160 0x5770 # 0 +0xE161 0x5883 # 0 +0xE162 0x5E9A # 0 +0xE163 0x5F91 # 0 +0xE164 0x6176 # 0 +0xE165 0x61AC # 0 +0xE166 0x64CE # 0 +0xE167 0x656C # 0 +0xE168 0x666F # 0 +0xE169 0x66BB # 0 +0xE16A 0x66F4 # 0 +0xE16B 0x6897 # 0 +0xE16C 0x6D87 # 0 +0xE16D 0x7085 # 0 +0xE16E 0x70F1 # 0 +0xE16F 0x749F # 0 +0xE170 0x74A5 # 0 +0xE171 0x74CA # 0 +0xE172 0x75D9 # 0 +0xE173 0x786C # 0 +0xE174 0x78EC # 0 +0xE175 0x7ADF # 0 +0xE176 0x7AF6 # 0 +0xE177 0x7D45 # 0 +0xE178 0x7D93 # 0 +0xE179 0x8015 # 0 +0xE17A 0x803F # 0 +0xE17B 0x811B # 0 +0xE17C 0x8396 # 0 +0xE17D 0x8B66 # 0 +0xE17E 0x8F15 # 0 +0xE191 0x9015 # 0 +0xE192 0x93E1 # 0 +0xE193 0x9803 # 0 +0xE194 0x9838 # 0 +0xE195 0x9A5A # 0 +0xE196 0x9BE8 # 0 +0xE197 0x4FC2 # 0 +0xE198 0x5553 # 0 +0xE199 0x583A # 0 +0xE19A 0x5951 # 0 +0xE19B 0x5B63 # 0 +0xE19C 0x5C46 # 0 +0xE19D 0x60B8 # 0 +0xE19E 0x6212 # 0 +0xE19F 0x6842 # 0 +0xE1A0 0x68B0 # 0 +0xE1A1 0x68E8 # 0 +0xE1A2 0x6EAA # 0 +0xE1A3 0x754C # 0 +0xE1A4 0x7678 # 0 +0xE1A5 0x78CE # 0 +0xE1A6 0x7A3D # 0 +0xE1A7 0x7CFB # 0 +0xE1A8 0x7E6B # 0 +0xE1A9 0x7E7C # 0 +0xE1AA 0x8A08 # 0 +0xE1AB 0x8AA1 # 0 +0xE1AC 0x8C3F # 0 +0xE1AD 0x968E # 0 +0xE1AE 0x9DC4 # 0 +0xE1AF 0x53E4 # 0 +0xE1B0 0x53E9 # 0 +0xE1B1 0x544A # 0 +0xE1B2 0x5471 # 0 +0xE1B3 0x56FA # 0 +0xE1B4 0x59D1 # 0 +0xE1B5 0x5B64 # 0 +0xE1B6 0x5C3B # 0 +0xE1B7 0x5EAB # 0 +0xE1B8 0x62F7 # 0 +0xE1B9 0x6537 # 0 +0xE1BA 0x6545 # 0 +0xE1BB 0x6572 # 0 +0xE1BC 0x66A0 # 0 +0xE1BD 0x67AF # 0 +0xE1BE 0x69C1 # 0 +0xE1BF 0x6CBD # 0 +0xE1C0 0x75FC # 0 +0xE1C1 0x7690 # 0 +0xE1C2 0x777E # 0 +0xE1C3 0x7A3F # 0 +0xE1C4 0x7F94 # 0 +0xE1C5 0x8003 # 0 +0xE1C6 0x80A1 # 0 +0xE1C7 0x818F # 0 +0xE1C8 0x82E6 # 0 +0xE1C9 0x82FD # 0 +0xE1CA 0x83F0 # 0 +0xE1CB 0x85C1 # 0 +0xE1CC 0x8831 # 0 +0xE1CD 0x88B4 # 0 +0xE1CE 0x8AA5 # 0 +0xE1CF 0xF903 # 0 +0xE1D0 0x8F9C # 0 +0xE1D1 0x932E # 0 +0xE1D2 0x96C7 # 0 +0xE1D3 0x9867 # 0 +0xE1D4 0x9AD8 # 0 +0xE1D5 0x9F13 # 0 +0xE1D6 0x54ED # 0 +0xE1D7 0x659B # 0 +0xE1D8 0x66F2 # 0 +0xE1D9 0x688F # 0 +0xE1DA 0x7A40 # 0 +0xE1DB 0x8C37 # 0 +0xE1DC 0x9D60 # 0 +0xE1DD 0x56F0 # 0 +0xE1DE 0x5764 # 0 +0xE1DF 0x5D11 # 0 +0xE1E0 0x6606 # 0 +0xE1E1 0x68B1 # 0 +0xE1E2 0x68CD # 0 +0xE1E3 0x6EFE # 0 +0xE1E4 0x7428 # 0 +0xE1E5 0x889E # 0 +0xE1E6 0x9BE4 # 0 +0xE1E7 0x6C68 # 0 +0xE1E8 0xF904 # 0 +0xE1E9 0x9AA8 # 0 +0xE1EA 0x4F9B # 0 +0xE1EB 0x516C # 0 +0xE1EC 0x5171 # 0 +0xE1ED 0x529F # 0 +0xE1EE 0x5B54 # 0 +0xE1EF 0x5DE5 # 0 +0xE1F0 0x6050 # 0 +0xE1F1 0x606D # 0 +0xE1F2 0x62F1 # 0 +0xE1F3 0x63A7 # 0 +0xE1F4 0x653B # 0 +0xE1F5 0x73D9 # 0 +0xE1F6 0x7A7A # 0 +0xE1F7 0x86A3 # 0 +0xE1F8 0x8CA2 # 0 +0xE1F9 0x978F # 0 +0xE1FA 0x4E32 # 0 +0xE1FB 0x5BE1 # 0 +0xE1FC 0x6208 # 0 +0xE1FD 0x679C # 0 +0xE1FE 0x74DC # 0 +0xE231 0x79D1 # 0 +0xE232 0x83D3 # 0 +0xE233 0x8A87 # 0 +0xE234 0x8AB2 # 0 +0xE235 0x8DE8 # 0 +0xE236 0x904E # 0 +0xE237 0x934B # 0 +0xE238 0x9846 # 0 +0xE239 0x5ED3 # 0 +0xE23A 0x69E8 # 0 +0xE23B 0x85FF # 0 +0xE23C 0x90ED # 0 +0xE23D 0xF905 # 0 +0xE23E 0x51A0 # 0 +0xE23F 0x5B98 # 0 +0xE240 0x5BEC # 0 +0xE241 0x6163 # 0 +0xE242 0x68FA # 0 +0xE243 0x6B3E # 0 +0xE244 0x704C # 0 +0xE245 0x742F # 0 +0xE246 0x74D8 # 0 +0xE247 0x7BA1 # 0 +0xE248 0x7F50 # 0 +0xE249 0x83C5 # 0 +0xE24A 0x89C0 # 0 +0xE24B 0x8CAB # 0 +0xE24C 0x95DC # 0 +0xE24D 0x9928 # 0 +0xE24E 0x522E # 0 +0xE24F 0x605D # 0 +0xE250 0x62EC # 0 +0xE251 0x9002 # 0 +0xE252 0x4F8A # 0 +0xE253 0x5149 # 0 +0xE254 0x5321 # 0 +0xE255 0x58D9 # 0 +0xE256 0x5EE3 # 0 +0xE257 0x66E0 # 0 +0xE258 0x6D38 # 0 +0xE259 0x709A # 0 +0xE25A 0x72C2 # 0 +0xE25B 0x73D6 # 0 +0xE25C 0x7B50 # 0 +0xE25D 0x80F1 # 0 +0xE25E 0x945B # 0 +0xE25F 0x5366 # 0 +0xE260 0x639B # 0 +0xE261 0x7F6B # 0 +0xE262 0x4E56 # 0 +0xE263 0x5080 # 0 +0xE264 0x584A # 0 +0xE265 0x58DE # 0 +0xE266 0x602A # 0 +0xE267 0x6127 # 0 +0xE268 0x62D0 # 0 +0xE269 0x69D0 # 0 +0xE26A 0x9B41 # 0 +0xE26B 0x5B8F # 0 +0xE26C 0x7D18 # 0 +0xE26D 0x80B1 # 0 +0xE26E 0x8F5F # 0 +0xE26F 0x4EA4 # 0 +0xE270 0x50D1 # 0 +0xE271 0x54AC # 0 +0xE272 0x55AC # 0 +0xE273 0x5B0C # 0 +0xE274 0x5DA0 # 0 +0xE275 0x5DE7 # 0 +0xE276 0x652A # 0 +0xE277 0x654E # 0 +0xE278 0x6821 # 0 +0xE279 0x6A4B # 0 +0xE27A 0x72E1 # 0 +0xE27B 0x768E # 0 +0xE27C 0x77EF # 0 +0xE27D 0x7D5E # 0 +0xE27E 0x7FF9 # 0 +0xE291 0x81A0 # 0 +0xE292 0x854E # 0 +0xE293 0x86DF # 0 +0xE294 0x8F03 # 0 +0xE295 0x8F4E # 0 +0xE296 0x90CA # 0 +0xE297 0x9903 # 0 +0xE298 0x9A55 # 0 +0xE299 0x9BAB # 0 +0xE29A 0x4E18 # 0 +0xE29B 0x4E45 # 0 +0xE29C 0x4E5D # 0 +0xE29D 0x4EC7 # 0 +0xE29E 0x4FF1 # 0 +0xE29F 0x5177 # 0 +0xE2A0 0x52FE # 0 +0xE2A1 0x5340 # 0 +0xE2A2 0x53E3 # 0 +0xE2A3 0x53E5 # 0 +0xE2A4 0x548E # 0 +0xE2A5 0x5614 # 0 +0xE2A6 0x5775 # 0 +0xE2A7 0x57A2 # 0 +0xE2A8 0x5BC7 # 0 +0xE2A9 0x5D87 # 0 +0xE2AA 0x5ED0 # 0 +0xE2AB 0x61FC # 0 +0xE2AC 0x62D8 # 0 +0xE2AD 0x6551 # 0 +0xE2AE 0x67B8 # 0 +0xE2AF 0x67E9 # 0 +0xE2B0 0x69CB # 0 +0xE2B1 0x6B50 # 0 +0xE2B2 0x6BC6 # 0 +0xE2B3 0x6BEC # 0 +0xE2B4 0x6C42 # 0 +0xE2B5 0x6E9D # 0 +0xE2B6 0x7078 # 0 +0xE2B7 0x72D7 # 0 +0xE2B8 0x7396 # 0 +0xE2B9 0x7403 # 0 +0xE2BA 0x77BF # 0 +0xE2BB 0x77E9 # 0 +0xE2BC 0x7A76 # 0 +0xE2BD 0x7D7F # 0 +0xE2BE 0x8009 # 0 +0xE2BF 0x81FC # 0 +0xE2C0 0x8205 # 0 +0xE2C1 0x820A # 0 +0xE2C2 0x82DF # 0 +0xE2C3 0x8862 # 0 +0xE2C4 0x8B33 # 0 +0xE2C5 0x8CFC # 0 +0xE2C6 0x8EC0 # 0 +0xE2C7 0x9011 # 0 +0xE2C8 0x90B1 # 0 +0xE2C9 0x9264 # 0 +0xE2CA 0x92B6 # 0 +0xE2CB 0x99D2 # 0 +0xE2CC 0x9A45 # 0 +0xE2CD 0x9CE9 # 0 +0xE2CE 0x9DD7 # 0 +0xE2CF 0x9F9C # 0 +0xE2D0 0x570B # 0 +0xE2D1 0x5C40 # 0 +0xE2D2 0x83CA # 0 +0xE2D3 0x97A0 # 0 +0xE2D4 0x97AB # 0 +0xE2D5 0x9EB4 # 0 +0xE2D6 0x541B # 0 +0xE2D7 0x7A98 # 0 +0xE2D8 0x7FA4 # 0 +0xE2D9 0x88D9 # 0 +0xE2DA 0x8ECD # 0 +0xE2DB 0x90E1 # 0 +0xE2DC 0x5800 # 0 +0xE2DD 0x5C48 # 0 +0xE2DE 0x6398 # 0 +0xE2DF 0x7A9F # 0 +0xE2E0 0x5BAE # 0 +0xE2E1 0x5F13 # 0 +0xE2E2 0x7A79 # 0 +0xE2E3 0x7AAE # 0 +0xE2E4 0x828E # 0 +0xE2E5 0x8EAC # 0 +0xE2E6 0x5026 # 0 +0xE2E7 0x5238 # 0 +0xE2E8 0x52F8 # 0 +0xE2E9 0x5377 # 0 +0xE2EA 0x5708 # 0 +0xE2EB 0x62F3 # 0 +0xE2EC 0x6372 # 0 +0xE2ED 0x6B0A # 0 +0xE2EE 0x6DC3 # 0 +0xE2EF 0x7737 # 0 +0xE2F0 0x53A5 # 0 +0xE2F1 0x7357 # 0 +0xE2F2 0x8568 # 0 +0xE2F3 0x8E76 # 0 +0xE2F4 0x95D5 # 0 +0xE2F5 0x673A # 0 +0xE2F6 0x6AC3 # 0 +0xE2F7 0x6F70 # 0 +0xE2F8 0x8A6D # 0 +0xE2F9 0x8ECC # 0 +0xE2FA 0x994B # 0 +0xE2FB 0xF906 # 0 +0xE2FC 0x6677 # 0 +0xE2FD 0x6B78 # 0 +0xE2FE 0x8CB4 # 0 +0xE331 0x9B3C # 0 +0xE332 0xF907 # 0 +0xE333 0x53EB # 0 +0xE334 0x572D # 0 +0xE335 0x594E # 0 +0xE336 0x63C6 # 0 +0xE337 0x69FB # 0 +0xE338 0x73EA # 0 +0xE339 0x7845 # 0 +0xE33A 0x7ABA # 0 +0xE33B 0x7AC5 # 0 +0xE33C 0x7CFE # 0 +0xE33D 0x8475 # 0 +0xE33E 0x898F # 0 +0xE33F 0x8D73 # 0 +0xE340 0x9035 # 0 +0xE341 0x95A8 # 0 +0xE342 0x52FB # 0 +0xE343 0x5747 # 0 +0xE344 0x7547 # 0 +0xE345 0x7B60 # 0 +0xE346 0x83CC # 0 +0xE347 0x921E # 0 +0xE348 0xF908 # 0 +0xE349 0x6A58 # 0 +0xE34A 0x514B # 0 +0xE34B 0x524B # 0 +0xE34C 0x5287 # 0 +0xE34D 0x621F # 0 +0xE34E 0x68D8 # 0 +0xE34F 0x6975 # 0 +0xE350 0x9699 # 0 +0xE351 0x50C5 # 0 +0xE352 0x52A4 # 0 +0xE353 0x52E4 # 0 +0xE354 0x61C3 # 0 +0xE355 0x65A4 # 0 +0xE356 0x6839 # 0 +0xE357 0x69FF # 0 +0xE358 0x747E # 0 +0xE359 0x7B4B # 0 +0xE35A 0x82B9 # 0 +0xE35B 0x83EB # 0 +0xE35C 0x89B2 # 0 +0xE35D 0x8B39 # 0 +0xE35E 0x8FD1 # 0 +0xE35F 0x9949 # 0 +0xE360 0xF909 # 0 +0xE361 0x4ECA # 0 +0xE362 0x5997 # 0 +0xE363 0x64D2 # 0 +0xE364 0x6611 # 0 +0xE365 0x6A8E # 0 +0xE366 0x7434 # 0 +0xE367 0x7981 # 0 +0xE368 0x79BD # 0 +0xE369 0x82A9 # 0 +0xE36A 0x887E # 0 +0xE36B 0x887F # 0 +0xE36C 0x895F # 0 +0xE36D 0xF90A # 0 +0xE36E 0x9326 # 0 +0xE36F 0x4F0B # 0 +0xE370 0x53CA # 0 +0xE371 0x6025 # 0 +0xE372 0x6271 # 0 +0xE373 0x6C72 # 0 +0xE374 0x7D1A # 0 +0xE375 0x7D66 # 0 +0xE376 0x4E98 # 0 +0xE377 0x5162 # 0 +0xE378 0x77DC # 0 +0xE379 0x80AF # 0 +0xE37A 0x4F01 # 0 +0xE37B 0x4F0E # 0 +0xE37C 0x5176 # 0 +0xE37D 0x5180 # 0 +0xE37E 0x55DC # 0 +0xE391 0x5668 # 0 +0xE392 0x573B # 0 +0xE393 0x57FA # 0 +0xE394 0x57FC # 0 +0xE395 0x5914 # 0 +0xE396 0x5947 # 0 +0xE397 0x5993 # 0 +0xE398 0x5BC4 # 0 +0xE399 0x5C90 # 0 +0xE39A 0x5D0E # 0 +0xE39B 0x5DF1 # 0 +0xE39C 0x5E7E # 0 +0xE39D 0x5FCC # 0 +0xE39E 0x6280 # 0 +0xE39F 0x65D7 # 0 +0xE3A0 0x65E3 # 0 +0xE3A1 0x671E # 0 +0xE3A2 0x671F # 0 +0xE3A3 0x675E # 0 +0xE3A4 0x68CB # 0 +0xE3A5 0x68C4 # 0 +0xE3A6 0x6A5F # 0 +0xE3A7 0x6B3A # 0 +0xE3A8 0x6C23 # 0 +0xE3A9 0x6C7D # 0 +0xE3AA 0x6C82 # 0 +0xE3AB 0x6DC7 # 0 +0xE3AC 0x7398 # 0 +0xE3AD 0x7426 # 0 +0xE3AE 0x742A # 0 +0xE3AF 0x7482 # 0 +0xE3B0 0x74A3 # 0 +0xE3B1 0x7578 # 0 +0xE3B2 0x757F # 0 +0xE3B3 0x7881 # 0 +0xE3B4 0x78EF # 0 +0xE3B5 0x7941 # 0 +0xE3B6 0x7947 # 0 +0xE3B7 0x7948 # 0 +0xE3B8 0x797A # 0 +0xE3B9 0x7B95 # 0 +0xE3BA 0x7D00 # 0 +0xE3BB 0x7DBA # 0 +0xE3BC 0x7F88 # 0 +0xE3BD 0x8006 # 0 +0xE3BE 0x802D # 0 +0xE3BF 0x808C # 0 +0xE3C0 0x8A18 # 0 +0xE3C1 0x8B4F # 0 +0xE3C2 0x8C48 # 0 +0xE3C3 0x8D77 # 0 +0xE3C4 0x9321 # 0 +0xE3C5 0x9324 # 0 +0xE3C6 0x98E2 # 0 +0xE3C7 0x9951 # 0 +0xE3C8 0x9A0E # 0 +0xE3C9 0x9A0F # 0 +0xE3CA 0x9A65 # 0 +0xE3CB 0x9E92 # 0 +0xE3CC 0x7DCA # 0 +0xE3CD 0x4F76 # 0 +0xE3CE 0x5409 # 0 +0xE3CF 0x62EE # 0 +0xE3D0 0x6854 # 0 +0xE3D1 0x91D1 # 0 +0xE3D2 0x55AB # 0 +0xE3D3 0x513A # 0 +0xE3D4 0xF90B # 0 +0xE3D5 0xF90C # 0 +0xE3D6 0x5A1C # 0 +0xE3D7 0x61E6 # 0 +0xE3D8 0xF90D # 0 +0xE3D9 0x62CF # 0 +0xE3DA 0x62FF # 0 +0xE3DB 0xF90E # 0 +0xE3DC 0xF90F # 0 +0xE3DD 0xF910 # 0 +0xE3DE 0xF911 # 0 +0xE3DF 0xF912 # 0 +0xE3E0 0xF913 # 0 +0xE3E1 0x90A3 # 0 +0xE3E2 0xF914 # 0 +0xE3E3 0xF915 # 0 +0xE3E4 0xF916 # 0 +0xE3E5 0xF917 # 0 +0xE3E6 0xF918 # 0 +0xE3E7 0x8AFE # 0 +0xE3E8 0xF919 # 0 +0xE3E9 0xF91A # 0 +0xE3EA 0xF91B # 0 +0xE3EB 0xF91C # 0 +0xE3EC 0x6696 # 0 +0xE3ED 0xF91D # 0 +0xE3EE 0x7156 # 0 +0xE3EF 0xF91E # 0 +0xE3F0 0xF91F # 0 +0xE3F1 0x96E3 # 0 +0xE3F2 0xF920 # 0 +0xE3F3 0x634F # 0 +0xE3F4 0x637A # 0 +0xE3F5 0x5357 # 0 +0xE3F6 0xF921 # 0 +0xE3F7 0x678F # 0 +0xE3F8 0x6960 # 0 +0xE3F9 0x6E73 # 0 +0xE3FA 0xF922 # 0 +0xE3FB 0x7537 # 0 +0xE3FC 0xF923 # 0 +0xE3FD 0xF924 # 0 +0xE3FE 0xF925 # 0 +0xE431 0x7D0D # 0 +0xE432 0xF926 # 0 +0xE433 0xF927 # 0 +0xE434 0x8872 # 0 +0xE435 0x56CA # 0 +0xE436 0x5A18 # 0 +0xE437 0xF928 # 0 +0xE438 0xF929 # 0 +0xE439 0xF92A # 0 +0xE43A 0xF92B # 0 +0xE43B 0xF92C # 0 +0xE43C 0x4E43 # 0 +0xE43D 0xF92D # 0 +0xE43E 0x5167 # 0 +0xE43F 0x5948 # 0 +0xE440 0x67F0 # 0 +0xE441 0x8010 # 0 +0xE442 0xF92E # 0 +0xE443 0x5973 # 0 +0xE444 0x5E74 # 0 +0xE445 0x649A # 0 +0xE446 0x79CA # 0 +0xE447 0x5FF5 # 0 +0xE448 0x606C # 0 +0xE449 0x62C8 # 0 +0xE44A 0x637B # 0 +0xE44B 0x5BE7 # 0 +0xE44C 0x5BD7 # 0 +0xE44D 0x52AA # 0 +0xE44E 0xF92F # 0 +0xE44F 0x5974 # 0 +0xE450 0x5F29 # 0 +0xE451 0x6012 # 0 +0xE452 0xF930 # 0 +0xE453 0xF931 # 0 +0xE454 0xF932 # 0 +0xE455 0x7459 # 0 +0xE456 0xF933 # 0 +0xE457 0xF934 # 0 +0xE458 0xF935 # 0 +0xE459 0xF936 # 0 +0xE45A 0xF937 # 0 +0xE45B 0xF938 # 0 +0xE45C 0x99D1 # 0 +0xE45D 0xF939 # 0 +0xE45E 0xF93A # 0 +0xE45F 0xF93B # 0 +0xE460 0xF93C # 0 +0xE461 0xF93D # 0 +0xE462 0xF93E # 0 +0xE463 0xF93F # 0 +0xE464 0xF940 # 0 +0xE465 0xF941 # 0 +0xE466 0xF942 # 0 +0xE467 0xF943 # 0 +0xE468 0x6FC3 # 0 +0xE469 0xF944 # 0 +0xE46A 0xF945 # 0 +0xE46B 0x81BF # 0 +0xE46C 0x8FB2 # 0 +0xE46D 0x60F1 # 0 +0xE46E 0xF946 # 0 +0xE46F 0xF947 # 0 +0xE470 0x8166 # 0 +0xE471 0xF948 # 0 +0xE472 0xF949 # 0 +0xE473 0x5C3F # 0 +0xE474 0xF94A # 0 +0xE475 0xF94B # 0 +0xE476 0xF94C # 0 +0xE477 0xF94D # 0 +0xE478 0xF94E # 0 +0xE479 0xF94F # 0 +0xE47A 0xF950 # 0 +0xE47B 0xF951 # 0 +0xE47C 0x5AE9 # 0 +0xE47D 0x8A25 # 0 +0xE47E 0x677B # 0 +0xE491 0x7D10 # 0 +0xE492 0xF952 # 0 +0xE493 0xF953 # 0 +0xE494 0xF954 # 0 +0xE495 0xF955 # 0 +0xE496 0xF956 # 0 +0xE497 0xF957 # 0 +0xE498 0x80FD # 0 +0xE499 0xF958 # 0 +0xE49A 0xF959 # 0 +0xE49B 0x5C3C # 0 +0xE49C 0x6CE5 # 0 +0xE49D 0x533F # 0 +0xE49E 0x6EBA # 0 +0xE49F 0x591A # 0 +0xE4A0 0x8336 # 0 +0xE4A1 0x4E39 # 0 +0xE4A2 0x4EB6 # 0 +0xE4A3 0x4F46 # 0 +0xE4A4 0x55AE # 0 +0xE4A5 0x5718 # 0 +0xE4A6 0x58C7 # 0 +0xE4A7 0x5F56 # 0 +0xE4A8 0x65B7 # 0 +0xE4A9 0x65E6 # 0 +0xE4AA 0x6A80 # 0 +0xE4AB 0x6BB5 # 0 +0xE4AC 0x6E4D # 0 +0xE4AD 0x77ED # 0 +0xE4AE 0x7AEF # 0 +0xE4AF 0x7C1E # 0 +0xE4B0 0x7DDE # 0 +0xE4B1 0x86CB # 0 +0xE4B2 0x8892 # 0 +0xE4B3 0x9132 # 0 +0xE4B4 0x935B # 0 +0xE4B5 0x64BB # 0 +0xE4B6 0x6FBE # 0 +0xE4B7 0x737A # 0 +0xE4B8 0x75B8 # 0 +0xE4B9 0x9054 # 0 +0xE4BA 0x5556 # 0 +0xE4BB 0x574D # 0 +0xE4BC 0x61BA # 0 +0xE4BD 0x64D4 # 0 +0xE4BE 0x66C7 # 0 +0xE4BF 0x6DE1 # 0 +0xE4C0 0x6E5B # 0 +0xE4C1 0x6F6D # 0 +0xE4C2 0x6FB9 # 0 +0xE4C3 0x75F0 # 0 +0xE4C4 0x8043 # 0 +0xE4C5 0x81BD # 0 +0xE4C6 0x8541 # 0 +0xE4C7 0x8983 # 0 +0xE4C8 0x8AC7 # 0 +0xE4C9 0x8B5A # 0 +0xE4CA 0x931F # 0 +0xE4CB 0x6C93 # 0 +0xE4CC 0x7553 # 0 +0xE4CD 0x7B54 # 0 +0xE4CE 0x8E0F # 0 +0xE4CF 0x905D # 0 +0xE4D0 0x5510 # 0 +0xE4D1 0x5802 # 0 +0xE4D2 0x5858 # 0 +0xE4D3 0x5E62 # 0 +0xE4D4 0x6207 # 0 +0xE4D5 0x649E # 0 +0xE4D6 0x68E0 # 0 +0xE4D7 0x7576 # 0 +0xE4D8 0x7CD6 # 0 +0xE4D9 0x87B3 # 0 +0xE4DA 0x9EE8 # 0 +0xE4DB 0x4EE3 # 0 +0xE4DC 0x5788 # 0 +0xE4DD 0x576E # 0 +0xE4DE 0x5927 # 0 +0xE4DF 0x5C0D # 0 +0xE4E0 0x5CB1 # 0 +0xE4E1 0x5E36 # 0 +0xE4E2 0x5F85 # 0 +0xE4E3 0x6234 # 0 +0xE4E4 0x64E1 # 0 +0xE4E5 0x73B3 # 0 +0xE4E6 0x81FA # 0 +0xE4E7 0x888B # 0 +0xE4E8 0x8CB8 # 0 +0xE4E9 0x968A # 0 +0xE4EA 0x9EDB # 0 +0xE4EB 0x5B85 # 0 +0xE4EC 0x5FB7 # 0 +0xE4ED 0x60B3 # 0 +0xE4EE 0x5012 # 0 +0xE4EF 0x5200 # 0 +0xE4F0 0x5230 # 0 +0xE4F1 0x5716 # 0 +0xE4F2 0x5835 # 0 +0xE4F3 0x5857 # 0 +0xE4F4 0x5C0E # 0 +0xE4F5 0x5C60 # 0 +0xE4F6 0x5CF6 # 0 +0xE4F7 0x5D8B # 0 +0xE4F8 0x5EA6 # 0 +0xE4F9 0x5F92 # 0 +0xE4FA 0x60BC # 0 +0xE4FB 0x6311 # 0 +0xE4FC 0x6389 # 0 +0xE4FD 0x6417 # 0 +0xE4FE 0x6843 # 0 +0xE531 0x68F9 # 0 +0xE532 0x6AC2 # 0 +0xE533 0x6DD8 # 0 +0xE534 0x6E21 # 0 +0xE535 0x6ED4 # 0 +0xE536 0x6FE4 # 0 +0xE537 0x71FE # 0 +0xE538 0x76DC # 0 +0xE539 0x7779 # 0 +0xE53A 0x79B1 # 0 +0xE53B 0x7A3B # 0 +0xE53C 0x8404 # 0 +0xE53D 0x89A9 # 0 +0xE53E 0x8CED # 0 +0xE53F 0x8DF3 # 0 +0xE540 0x8E48 # 0 +0xE541 0x9003 # 0 +0xE542 0x9014 # 0 +0xE543 0x9053 # 0 +0xE544 0x90FD # 0 +0xE545 0x934D # 0 +0xE546 0x9676 # 0 +0xE547 0x97DC # 0 +0xE548 0x6BD2 # 0 +0xE549 0x7006 # 0 +0xE54A 0x7258 # 0 +0xE54B 0x72A2 # 0 +0xE54C 0x7368 # 0 +0xE54D 0x7763 # 0 +0xE54E 0x79BF # 0 +0xE54F 0x7BE4 # 0 +0xE550 0x7E9B # 0 +0xE551 0x8B80 # 0 +0xE552 0x58A9 # 0 +0xE553 0x60C7 # 0 +0xE554 0x6566 # 0 +0xE555 0x65FD # 0 +0xE556 0x66BE # 0 +0xE557 0x6C8C # 0 +0xE558 0x711E # 0 +0xE559 0x71C9 # 0 +0xE55A 0x8C5A # 0 +0xE55B 0x9813 # 0 +0xE55C 0x4E6D # 0 +0xE55D 0x7A81 # 0 +0xE55E 0x4EDD # 0 +0xE55F 0x51AC # 0 +0xE560 0x51CD # 0 +0xE561 0x52D5 # 0 +0xE562 0x540C # 0 +0xE563 0x61A7 # 0 +0xE564 0x6771 # 0 +0xE565 0x6850 # 0 +0xE566 0x68DF # 0 +0xE567 0x6D1E # 0 +0xE568 0x6F7C # 0 +0xE569 0x75BC # 0 +0xE56A 0x77B3 # 0 +0xE56B 0x7AE5 # 0 +0xE56C 0x80F4 # 0 +0xE56D 0x8463 # 0 +0xE56E 0x9285 # 0 +0xE56F 0x515C # 0 +0xE570 0x6597 # 0 +0xE571 0x675C # 0 +0xE572 0x6793 # 0 +0xE573 0x75D8 # 0 +0xE574 0x7AC7 # 0 +0xE575 0x8373 # 0 +0xE576 0xF95A # 0 +0xE577 0x8C46 # 0 +0xE578 0x9017 # 0 +0xE579 0x982D # 0 +0xE57A 0x5C6F # 0 +0xE57B 0x81C0 # 0 +0xE57C 0x829A # 0 +0xE57D 0x9041 # 0 +0xE57E 0x906F # 0 +0xE591 0x920D # 0 +0xE592 0x5F97 # 0 +0xE593 0x5D9D # 0 +0xE594 0x6A59 # 0 +0xE595 0x71C8 # 0 +0xE596 0x767B # 0 +0xE597 0x7B49 # 0 +0xE598 0x85E4 # 0 +0xE599 0x8B04 # 0 +0xE59A 0x9127 # 0 +0xE59B 0x9A30 # 0 +0xE59C 0x5587 # 0 +0xE59D 0x61F6 # 0 +0xE59E 0xF95B # 0 +0xE59F 0x7669 # 0 +0xE5A0 0x7F85 # 0 +0xE5A1 0x863F # 0 +0xE5A2 0x87BA # 0 +0xE5A3 0x88F8 # 0 +0xE5A4 0x908F # 0 +0xE5A5 0xF95C # 0 +0xE5A6 0x6D1B # 0 +0xE5A7 0x70D9 # 0 +0xE5A8 0x73DE # 0 +0xE5A9 0x7D61 # 0 +0xE5AA 0x843D # 0 +0xE5AB 0xF95D # 0 +0xE5AC 0x916A # 0 +0xE5AD 0x99F1 # 0 +0xE5AE 0xF95E # 0 +0xE5AF 0x4E82 # 0 +0xE5B0 0x5375 # 0 +0xE5B1 0x6B04 # 0 +0xE5B2 0x6B12 # 0 +0xE5B3 0x703E # 0 +0xE5B4 0x721B # 0 +0xE5B5 0x862D # 0 +0xE5B6 0x9E1E # 0 +0xE5B7 0x524C # 0 +0xE5B8 0x8FA3 # 0 +0xE5B9 0x5D50 # 0 +0xE5BA 0x64E5 # 0 +0xE5BB 0x652C # 0 +0xE5BC 0x6B16 # 0 +0xE5BD 0x6FEB # 0 +0xE5BE 0x7C43 # 0 +0xE5BF 0x7E9C # 0 +0xE5C0 0x85CD # 0 +0xE5C1 0x8964 # 0 +0xE5C2 0x89BD # 0 +0xE5C3 0x62C9 # 0 +0xE5C4 0x81D8 # 0 +0xE5C5 0x881F # 0 +0xE5C6 0x5ECA # 0 +0xE5C7 0x6717 # 0 +0xE5C8 0x6D6A # 0 +0xE5C9 0x72FC # 0 +0xE5CA 0x7405 # 0 +0xE5CB 0x746F # 0 +0xE5CC 0x8782 # 0 +0xE5CD 0x90DE # 0 +0xE5CE 0x4F86 # 0 +0xE5CF 0x5D0D # 0 +0xE5D0 0x5FA0 # 0 +0xE5D1 0x840A # 0 +0xE5D2 0x51B7 # 0 +0xE5D3 0x63A0 # 0 +0xE5D4 0x7565 # 0 +0xE5D5 0x4EAE # 0 +0xE5D6 0x5006 # 0 +0xE5D7 0x5169 # 0 +0xE5D8 0x51C9 # 0 +0xE5D9 0x6881 # 0 +0xE5DA 0x6A11 # 0 +0xE5DB 0x7CAE # 0 +0xE5DC 0x7CB1 # 0 +0xE5DD 0x7CE7 # 0 +0xE5DE 0x826F # 0 +0xE5DF 0x8AD2 # 0 +0xE5E0 0x8F1B # 0 +0xE5E1 0x91CF # 0 +0xE5E2 0x4FB6 # 0 +0xE5E3 0x5137 # 0 +0xE5E4 0x52F5 # 0 +0xE5E5 0x5442 # 0 +0xE5E6 0x5EEC # 0 +0xE5E7 0x616E # 0 +0xE5E8 0x623E # 0 +0xE5E9 0x65C5 # 0 +0xE5EA 0x6ADA # 0 +0xE5EB 0x6FFE # 0 +0xE5EC 0x792A # 0 +0xE5ED 0x85DC # 0 +0xE5EE 0x8823 # 0 +0xE5EF 0x95AD # 0 +0xE5F0 0x9A62 # 0 +0xE5F1 0x9A6A # 0 +0xE5F2 0x9E97 # 0 +0xE5F3 0x9ECE # 0 +0xE5F4 0x529B # 0 +0xE5F5 0x66C6 # 0 +0xE5F6 0x6B77 # 0 +0xE5F7 0x701D # 0 +0xE5F8 0x792B # 0 +0xE5F9 0x8F62 # 0 +0xE5FA 0x9742 # 0 +0xE5FB 0x6190 # 0 +0xE5FC 0x6200 # 0 +0xE5FD 0x6523 # 0 +0xE5FE 0x6F23 # 0 +0xE631 0x7149 # 0 +0xE632 0x7489 # 0 +0xE633 0x7DF4 # 0 +0xE634 0x806F # 0 +0xE635 0x84EE # 0 +0xE636 0x8F26 # 0 +0xE637 0x9023 # 0 +0xE638 0x934A # 0 +0xE639 0x51BD # 0 +0xE63A 0x5217 # 0 +0xE63B 0x52A3 # 0 +0xE63C 0x6D0C # 0 +0xE63D 0x70C8 # 0 +0xE63E 0x88C2 # 0 +0xE63F 0x5EC9 # 0 +0xE640 0x6582 # 0 +0xE641 0x6BAE # 0 +0xE642 0x6FC2 # 0 +0xE643 0x7C3E # 0 +0xE644 0x7375 # 0 +0xE645 0x4EE4 # 0 +0xE646 0x4F36 # 0 +0xE647 0x56F9 # 0 +0xE648 0xF95F # 0 +0xE649 0x5CBA # 0 +0xE64A 0x5DBA # 0 +0xE64B 0x601C # 0 +0xE64C 0x73B2 # 0 +0xE64D 0x7B2D # 0 +0xE64E 0x7F9A # 0 +0xE64F 0x7FCE # 0 +0xE650 0x8046 # 0 +0xE651 0x901E # 0 +0xE652 0x9234 # 0 +0xE653 0x96F6 # 0 +0xE654 0x9748 # 0 +0xE655 0x9818 # 0 +0xE656 0x9F61 # 0 +0xE657 0x4F8B # 0 +0xE658 0x6FA7 # 0 +0xE659 0x79AE # 0 +0xE65A 0x91B4 # 0 +0xE65B 0x96B7 # 0 +0xE65C 0x52DE # 0 +0xE65D 0xF960 # 0 +0xE65E 0x6488 # 0 +0xE65F 0x64C4 # 0 +0xE660 0x6AD3 # 0 +0xE661 0x6F5E # 0 +0xE662 0x7018 # 0 +0xE663 0x7210 # 0 +0xE664 0x76E7 # 0 +0xE665 0x8001 # 0 +0xE666 0x8606 # 0 +0xE667 0x865C # 0 +0xE668 0x8DEF # 0 +0xE669 0x8F05 # 0 +0xE66A 0x9732 # 0 +0xE66B 0x9B6F # 0 +0xE66C 0x9DFA # 0 +0xE66D 0x9E75 # 0 +0xE66E 0x788C # 0 +0xE66F 0x797F # 0 +0xE670 0x7DA0 # 0 +0xE671 0x83C9 # 0 +0xE672 0x9304 # 0 +0xE673 0x9E7F # 0 +0xE674 0x9E93 # 0 +0xE675 0x8AD6 # 0 +0xE676 0x58DF # 0 +0xE677 0x5F04 # 0 +0xE678 0x6727 # 0 +0xE679 0x7027 # 0 +0xE67A 0x74CF # 0 +0xE67B 0x7C60 # 0 +0xE67C 0x807E # 0 +0xE67D 0x5121 # 0 +0xE67E 0x7028 # 0 +0xE691 0x7262 # 0 +0xE692 0x78CA # 0 +0xE693 0x8CC2 # 0 +0xE694 0x8CDA # 0 +0xE695 0x8CF4 # 0 +0xE696 0x96F7 # 0 +0xE697 0x4E86 # 0 +0xE698 0x50DA # 0 +0xE699 0x5BEE # 0 +0xE69A 0x5ED6 # 0 +0xE69B 0x6599 # 0 +0xE69C 0x71CE # 0 +0xE69D 0x7642 # 0 +0xE69E 0x77AD # 0 +0xE69F 0x804A # 0 +0xE6A0 0x84FC # 0 +0xE6A1 0x907C # 0 +0xE6A2 0x9B27 # 0 +0xE6A3 0x9F8D # 0 +0xE6A4 0x58D8 # 0 +0xE6A5 0x5A41 # 0 +0xE6A6 0x5C62 # 0 +0xE6A7 0x6A13 # 0 +0xE6A8 0x6DDA # 0 +0xE6A9 0x6F0F # 0 +0xE6AA 0x763B # 0 +0xE6AB 0x7D2F # 0 +0xE6AC 0x7E37 # 0 +0xE6AD 0x851E # 0 +0xE6AE 0x8938 # 0 +0xE6AF 0x93E4 # 0 +0xE6B0 0x964B # 0 +0xE6B1 0x5289 # 0 +0xE6B2 0x65D2 # 0 +0xE6B3 0x67F3 # 0 +0xE6B4 0x69B4 # 0 +0xE6B5 0x6D41 # 0 +0xE6B6 0x6E9C # 0 +0xE6B7 0x700F # 0 +0xE6B8 0x7409 # 0 +0xE6B9 0x7460 # 0 +0xE6BA 0x7559 # 0 +0xE6BB 0x7624 # 0 +0xE6BC 0x786B # 0 +0xE6BD 0x8B2C # 0 +0xE6BE 0x985E # 0 +0xE6BF 0x516D # 0 +0xE6C0 0x622E # 0 +0xE6C1 0x9678 # 0 +0xE6C2 0x4F96 # 0 +0xE6C3 0x502B # 0 +0xE6C4 0x5D19 # 0 +0xE6C5 0x6DEA # 0 +0xE6C6 0x7DB8 # 0 +0xE6C7 0x8F2A # 0 +0xE6C8 0x5F8B # 0 +0xE6C9 0x6144 # 0 +0xE6CA 0x6817 # 0 +0xE6CB 0xF961 # 0 +0xE6CC 0x9686 # 0 +0xE6CD 0x52D2 # 0 +0xE6CE 0x808B # 0 +0xE6CF 0x51DC # 0 +0xE6D0 0x51CC # 0 +0xE6D1 0x695E # 0 +0xE6D2 0x7A1C # 0 +0xE6D3 0x7DBE # 0 +0xE6D4 0x83F1 # 0 +0xE6D5 0x9675 # 0 +0xE6D6 0x4FDA # 0 +0xE6D7 0x5229 # 0 +0xE6D8 0x5398 # 0 +0xE6D9 0x540F # 0 +0xE6DA 0x550E # 0 +0xE6DB 0x5C65 # 0 +0xE6DC 0x60A7 # 0 +0xE6DD 0x674E # 0 +0xE6DE 0x68A8 # 0 +0xE6DF 0x6D6C # 0 +0xE6E0 0x7281 # 0 +0xE6E1 0x72F8 # 0 +0xE6E2 0x7406 # 0 +0xE6E3 0x7483 # 0 +0xE6E4 0xF962 # 0 +0xE6E5 0x75E2 # 0 +0xE6E6 0x7C6C # 0 +0xE6E7 0x7F79 # 0 +0xE6E8 0x7FB8 # 0 +0xE6E9 0x8389 # 0 +0xE6EA 0x88CF # 0 +0xE6EB 0x88E1 # 0 +0xE6EC 0x91CC # 0 +0xE6ED 0x91D0 # 0 +0xE6EE 0x96E2 # 0 +0xE6EF 0x9BC9 # 0 +0xE6F0 0x541D # 0 +0xE6F1 0x6F7E # 0 +0xE6F2 0x71D0 # 0 +0xE6F3 0x7498 # 0 +0xE6F4 0x85FA # 0 +0xE6F5 0x8EAA # 0 +0xE6F6 0x96A3 # 0 +0xE6F7 0x9C57 # 0 +0xE6F8 0x9E9F # 0 +0xE6F9 0x6797 # 0 +0xE6FA 0x6DCB # 0 +0xE6FB 0x7433 # 0 +0xE6FC 0x81E8 # 0 +0xE6FD 0x9716 # 0 +0xE6FE 0x782C # 0 +0xE731 0x7ACB # 0 +0xE732 0x7B20 # 0 +0xE733 0x7C92 # 0 +0xE734 0x6469 # 0 +0xE735 0x746A # 0 +0xE736 0x75F2 # 0 +0xE737 0x78BC # 0 +0xE738 0x78E8 # 0 +0xE739 0x99AC # 0 +0xE73A 0x9B54 # 0 +0xE73B 0x9EBB # 0 +0xE73C 0x5BDE # 0 +0xE73D 0x5E55 # 0 +0xE73E 0x6F20 # 0 +0xE73F 0x819C # 0 +0xE740 0x83AB # 0 +0xE741 0x9088 # 0 +0xE742 0x4E07 # 0 +0xE743 0x534D # 0 +0xE744 0x5A29 # 0 +0xE745 0x5DD2 # 0 +0xE746 0x5F4E # 0 +0xE747 0x6162 # 0 +0xE748 0x633D # 0 +0xE749 0x6669 # 0 +0xE74A 0x66FC # 0 +0xE74B 0x6EFF # 0 +0xE74C 0x6F2B # 0 +0xE74D 0x7063 # 0 +0xE74E 0x779E # 0 +0xE74F 0x842C # 0 +0xE750 0x8513 # 0 +0xE751 0x883B # 0 +0xE752 0x8F13 # 0 +0xE753 0x9945 # 0 +0xE754 0x9C3B # 0 +0xE755 0x551C # 0 +0xE756 0x62B9 # 0 +0xE757 0x672B # 0 +0xE758 0x6CAB # 0 +0xE759 0x8309 # 0 +0xE75A 0x896A # 0 +0xE75B 0x977A # 0 +0xE75C 0x4EA1 # 0 +0xE75D 0x5984 # 0 +0xE75E 0x5FD8 # 0 +0xE75F 0x5FD9 # 0 +0xE760 0x671B # 0 +0xE761 0x7DB2 # 0 +0xE762 0x7F54 # 0 +0xE763 0x8292 # 0 +0xE764 0x832B # 0 +0xE765 0x83BD # 0 +0xE766 0x8F1E # 0 +0xE767 0x9099 # 0 +0xE768 0x57CB # 0 +0xE769 0x59B9 # 0 +0xE76A 0x5A92 # 0 +0xE76B 0x5BD0 # 0 +0xE76C 0x6627 # 0 +0xE76D 0x679A # 0 +0xE76E 0x6885 # 0 +0xE76F 0x6BCF # 0 +0xE770 0x7164 # 0 +0xE771 0x7F75 # 0 +0xE772 0x8CB7 # 0 +0xE773 0x8CE3 # 0 +0xE774 0x9081 # 0 +0xE775 0x9B45 # 0 +0xE776 0x8108 # 0 +0xE777 0x8C8A # 0 +0xE778 0x964C # 0 +0xE779 0x9A40 # 0 +0xE77A 0x9EA5 # 0 +0xE77B 0x5B5F # 0 +0xE77C 0x6C13 # 0 +0xE77D 0x731B # 0 +0xE77E 0x76F2 # 0 +0xE791 0x76DF # 0 +0xE792 0x840C # 0 +0xE793 0x51AA # 0 +0xE794 0x8993 # 0 +0xE795 0x514D # 0 +0xE796 0x5195 # 0 +0xE797 0x52C9 # 0 +0xE798 0x68C9 # 0 +0xE799 0x6C94 # 0 +0xE79A 0x7704 # 0 +0xE79B 0x7720 # 0 +0xE79C 0x7DBF # 0 +0xE79D 0x7DEC # 0 +0xE79E 0x9762 # 0 +0xE79F 0x9EB5 # 0 +0xE7A0 0x6EC5 # 0 +0xE7A1 0x8511 # 0 +0xE7A2 0x51A5 # 0 +0xE7A3 0x540D # 0 +0xE7A4 0x547D # 0 +0xE7A5 0x660E # 0 +0xE7A6 0x669D # 0 +0xE7A7 0x6927 # 0 +0xE7A8 0x6E9F # 0 +0xE7A9 0x76BF # 0 +0xE7AA 0x7791 # 0 +0xE7AB 0x8317 # 0 +0xE7AC 0x84C2 # 0 +0xE7AD 0x879F # 0 +0xE7AE 0x9169 # 0 +0xE7AF 0x9298 # 0 +0xE7B0 0x9CF4 # 0 +0xE7B1 0x8882 # 0 +0xE7B2 0x4FAE # 0 +0xE7B3 0x5192 # 0 +0xE7B4 0x52DF # 0 +0xE7B5 0x59C6 # 0 +0xE7B6 0x5E3D # 0 +0xE7B7 0x6155 # 0 +0xE7B8 0x6478 # 0 +0xE7B9 0x6479 # 0 +0xE7BA 0x66AE # 0 +0xE7BB 0x67D0 # 0 +0xE7BC 0x6A21 # 0 +0xE7BD 0x6BCD # 0 +0xE7BE 0x6BDB # 0 +0xE7BF 0x725F # 0 +0xE7C0 0x7261 # 0 +0xE7C1 0x7441 # 0 +0xE7C2 0x7738 # 0 +0xE7C3 0x77DB # 0 +0xE7C4 0x8017 # 0 +0xE7C5 0x82BC # 0 +0xE7C6 0x8305 # 0 +0xE7C7 0x8B00 # 0 +0xE7C8 0x8B28 # 0 +0xE7C9 0x8C8C # 0 +0xE7CA 0x6728 # 0 +0xE7CB 0x6C90 # 0 +0xE7CC 0x7267 # 0 +0xE7CD 0x76EE # 0 +0xE7CE 0x7766 # 0 +0xE7CF 0x7A46 # 0 +0xE7D0 0x9DA9 # 0 +0xE7D1 0x6B7F # 0 +0xE7D2 0x6C92 # 0 +0xE7D3 0x5922 # 0 +0xE7D4 0x6726 # 0 +0xE7D5 0x8499 # 0 +0xE7D6 0x536F # 0 +0xE7D7 0x5893 # 0 +0xE7D8 0x5999 # 0 +0xE7D9 0x5EDF # 0 +0xE7DA 0x63CF # 0 +0xE7DB 0x6634 # 0 +0xE7DC 0x6773 # 0 +0xE7DD 0x6E3A # 0 +0xE7DE 0x732B # 0 +0xE7DF 0x7AD7 # 0 +0xE7E0 0x82D7 # 0 +0xE7E1 0x9328 # 0 +0xE7E2 0x52D9 # 0 +0xE7E3 0x5DEB # 0 +0xE7E4 0x61AE # 0 +0xE7E5 0x61CB # 0 +0xE7E6 0x620A # 0 +0xE7E7 0x62C7 # 0 +0xE7E8 0x64AB # 0 +0xE7E9 0x65E0 # 0 +0xE7EA 0x6959 # 0 +0xE7EB 0x6B66 # 0 +0xE7EC 0x6BCB # 0 +0xE7ED 0x7121 # 0 +0xE7EE 0x73F7 # 0 +0xE7EF 0x755D # 0 +0xE7F0 0x7E46 # 0 +0xE7F1 0x821E # 0 +0xE7F2 0x8302 # 0 +0xE7F3 0x856A # 0 +0xE7F4 0x8AA3 # 0 +0xE7F5 0x8CBF # 0 +0xE7F6 0x9727 # 0 +0xE7F7 0x9D61 # 0 +0xE7F8 0x58A8 # 0 +0xE7F9 0x9ED8 # 0 +0xE7FA 0x5011 # 0 +0xE7FB 0x520E # 0 +0xE7FC 0x543B # 0 +0xE7FD 0x554F # 0 +0xE7FE 0x6587 # 0 +0xE831 0x6C76 # 0 +0xE832 0x7D0A # 0 +0xE833 0x7D0B # 0 +0xE834 0x805E # 0 +0xE835 0x868A # 0 +0xE836 0x9580 # 0 +0xE837 0x96EF # 0 +0xE838 0x52FF # 0 +0xE839 0x6C95 # 0 +0xE83A 0x7269 # 0 +0xE83B 0x5473 # 0 +0xE83C 0x5A9A # 0 +0xE83D 0x5C3E # 0 +0xE83E 0x5D4B # 0 +0xE83F 0x5F4C # 0 +0xE840 0x5FAE # 0 +0xE841 0x672A # 0 +0xE842 0x68B6 # 0 +0xE843 0x6963 # 0 +0xE844 0x6E3C # 0 +0xE845 0x6E44 # 0 +0xE846 0x7709 # 0 +0xE847 0x7C73 # 0 +0xE848 0x7F8E # 0 +0xE849 0x8587 # 0 +0xE84A 0x8B0E # 0 +0xE84B 0x8FF7 # 0 +0xE84C 0x9761 # 0 +0xE84D 0x9EF4 # 0 +0xE84E 0x5CB7 # 0 +0xE84F 0x60B6 # 0 +0xE850 0x610D # 0 +0xE851 0x61AB # 0 +0xE852 0x654F # 0 +0xE853 0x65FB # 0 +0xE854 0x65FC # 0 +0xE855 0x6C11 # 0 +0xE856 0x6CEF # 0 +0xE857 0x739F # 0 +0xE858 0x73C9 # 0 +0xE859 0x7DE1 # 0 +0xE85A 0x9594 # 0 +0xE85B 0x5BC6 # 0 +0xE85C 0x871C # 0 +0xE85D 0x8B10 # 0 +0xE85E 0x525D # 0 +0xE85F 0x535A # 0 +0xE860 0x62CD # 0 +0xE861 0x640F # 0 +0xE862 0x64B2 # 0 +0xE863 0x6734 # 0 +0xE864 0x6A38 # 0 +0xE865 0x6CCA # 0 +0xE866 0x73C0 # 0 +0xE867 0x749E # 0 +0xE868 0x7B94 # 0 +0xE869 0x7C95 # 0 +0xE86A 0x7E1B # 0 +0xE86B 0x818A # 0 +0xE86C 0x8236 # 0 +0xE86D 0x8584 # 0 +0xE86E 0x8FEB # 0 +0xE86F 0x96F9 # 0 +0xE870 0x99C1 # 0 +0xE871 0x4F34 # 0 +0xE872 0x534A # 0 +0xE873 0x53CD # 0 +0xE874 0x53DB # 0 +0xE875 0x62CC # 0 +0xE876 0x642C # 0 +0xE877 0x6500 # 0 +0xE878 0x6591 # 0 +0xE879 0x69C3 # 0 +0xE87A 0x6CEE # 0 +0xE87B 0x6F58 # 0 +0xE87C 0x73ED # 0 +0xE87D 0x7554 # 0 +0xE87E 0x7622 # 0 +0xE891 0x76E4 # 0 +0xE892 0x76FC # 0 +0xE893 0x78D0 # 0 +0xE894 0x78FB # 0 +0xE895 0x792C # 0 +0xE896 0x7D46 # 0 +0xE897 0x822C # 0 +0xE898 0x87E0 # 0 +0xE899 0x8FD4 # 0 +0xE89A 0x9812 # 0 +0xE89B 0x98EF # 0 +0xE89C 0x52C3 # 0 +0xE89D 0x62D4 # 0 +0xE89E 0x64A5 # 0 +0xE89F 0x6E24 # 0 +0xE8A0 0x6F51 # 0 +0xE8A1 0x767C # 0 +0xE8A2 0x8DCB # 0 +0xE8A3 0x91B1 # 0 +0xE8A4 0x9262 # 0 +0xE8A5 0x9AEE # 0 +0xE8A6 0x9B43 # 0 +0xE8A7 0x5023 # 0 +0xE8A8 0x508D # 0 +0xE8A9 0x574A # 0 +0xE8AA 0x59A8 # 0 +0xE8AB 0x5C28 # 0 +0xE8AC 0x5E47 # 0 +0xE8AD 0x5F77 # 0 +0xE8AE 0x623F # 0 +0xE8AF 0x653E # 0 +0xE8B0 0x65B9 # 0 +0xE8B1 0x65C1 # 0 +0xE8B2 0x6609 # 0 +0xE8B3 0x678B # 0 +0xE8B4 0x699C # 0 +0xE8B5 0x6EC2 # 0 +0xE8B6 0x78C5 # 0 +0xE8B7 0x7D21 # 0 +0xE8B8 0x80AA # 0 +0xE8B9 0x8180 # 0 +0xE8BA 0x822B # 0 +0xE8BB 0x82B3 # 0 +0xE8BC 0x84A1 # 0 +0xE8BD 0x868C # 0 +0xE8BE 0x8A2A # 0 +0xE8BF 0x8B17 # 0 +0xE8C0 0x90A6 # 0 +0xE8C1 0x9632 # 0 +0xE8C2 0x9F90 # 0 +0xE8C3 0x500D # 0 +0xE8C4 0x4FF3 # 0 +0xE8C5 0xF963 # 0 +0xE8C6 0x57F9 # 0 +0xE8C7 0x5F98 # 0 +0xE8C8 0x62DC # 0 +0xE8C9 0x6392 # 0 +0xE8CA 0x676F # 0 +0xE8CB 0x6E43 # 0 +0xE8CC 0x7119 # 0 +0xE8CD 0x76C3 # 0 +0xE8CE 0x80CC # 0 +0xE8CF 0x80DA # 0 +0xE8D0 0x88F4 # 0 +0xE8D1 0x88F5 # 0 +0xE8D2 0x8919 # 0 +0xE8D3 0x8CE0 # 0 +0xE8D4 0x8F29 # 0 +0xE8D5 0x914D # 0 +0xE8D6 0x966A # 0 +0xE8D7 0x4F2F # 0 +0xE8D8 0x4F70 # 0 +0xE8D9 0x5E1B # 0 +0xE8DA 0x67CF # 0 +0xE8DB 0x6822 # 0 +0xE8DC 0x767D # 0 +0xE8DD 0x767E # 0 +0xE8DE 0x9B44 # 0 +0xE8DF 0x5E61 # 0 +0xE8E0 0x6A0A # 0 +0xE8E1 0x7169 # 0 +0xE8E2 0x71D4 # 0 +0xE8E3 0x756A # 0 +0xE8E4 0xF964 # 0 +0xE8E5 0x7E41 # 0 +0xE8E6 0x8543 # 0 +0xE8E7 0x85E9 # 0 +0xE8E8 0x98DC # 0 +0xE8E9 0x4F10 # 0 +0xE8EA 0x7B4F # 0 +0xE8EB 0x7F70 # 0 +0xE8EC 0x95A5 # 0 +0xE8ED 0x51E1 # 0 +0xE8EE 0x5E06 # 0 +0xE8EF 0x68B5 # 0 +0xE8F0 0x6C3E # 0 +0xE8F1 0x6C4E # 0 +0xE8F2 0x6CDB # 0 +0xE8F3 0x72AF # 0 +0xE8F4 0x7BC4 # 0 +0xE8F5 0x8303 # 0 +0xE8F6 0x6CD5 # 0 +0xE8F7 0x743A # 0 +0xE8F8 0x50FB # 0 +0xE8F9 0x5288 # 0 +0xE8FA 0x58C1 # 0 +0xE8FB 0x64D8 # 0 +0xE8FC 0x6A97 # 0 +0xE8FD 0x74A7 # 0 +0xE8FE 0x7656 # 0 +0xE931 0x78A7 # 0 +0xE932 0x8617 # 0 +0xE933 0x95E2 # 0 +0xE934 0x9739 # 0 +0xE935 0xF965 # 0 +0xE936 0x535E # 0 +0xE937 0x5F01 # 0 +0xE938 0x8B8A # 0 +0xE939 0x8FA8 # 0 +0xE93A 0x8FAF # 0 +0xE93B 0x908A # 0 +0xE93C 0x5225 # 0 +0xE93D 0x77A5 # 0 +0xE93E 0x9C49 # 0 +0xE93F 0x9F08 # 0 +0xE940 0x4E19 # 0 +0xE941 0x5002 # 0 +0xE942 0x5175 # 0 +0xE943 0x5C5B # 0 +0xE944 0x5E77 # 0 +0xE945 0x661E # 0 +0xE946 0x663A # 0 +0xE947 0x67C4 # 0 +0xE948 0x68C5 # 0 +0xE949 0x70B3 # 0 +0xE94A 0x7501 # 0 +0xE94B 0x75C5 # 0 +0xE94C 0x79C9 # 0 +0xE94D 0x7ADD # 0 +0xE94E 0x8F27 # 0 +0xE94F 0x9920 # 0 +0xE950 0x9A08 # 0 +0xE951 0x4FDD # 0 +0xE952 0x5821 # 0 +0xE953 0x5831 # 0 +0xE954 0x5BF6 # 0 +0xE955 0x666E # 0 +0xE956 0x6B65 # 0 +0xE957 0x6D11 # 0 +0xE958 0x6E7A # 0 +0xE959 0x6F7D # 0 +0xE95A 0x73E4 # 0 +0xE95B 0x752B # 0 +0xE95C 0x83E9 # 0 +0xE95D 0x88DC # 0 +0xE95E 0x8913 # 0 +0xE95F 0x8B5C # 0 +0xE960 0x8F14 # 0 +0xE961 0x4F0F # 0 +0xE962 0x50D5 # 0 +0xE963 0x5310 # 0 +0xE964 0x535C # 0 +0xE965 0x5B93 # 0 +0xE966 0x5FA9 # 0 +0xE967 0x670D # 0 +0xE968 0x798F # 0 +0xE969 0x8179 # 0 +0xE96A 0x832F # 0 +0xE96B 0x8514 # 0 +0xE96C 0x8907 # 0 +0xE96D 0x8986 # 0 +0xE96E 0x8F39 # 0 +0xE96F 0x8F3B # 0 +0xE970 0x99A5 # 0 +0xE971 0x9C12 # 0 +0xE972 0x672C # 0 +0xE973 0x4E76 # 0 +0xE974 0x4FF8 # 0 +0xE975 0x5949 # 0 +0xE976 0x5C01 # 0 +0xE977 0x5CEF # 0 +0xE978 0x5CF0 # 0 +0xE979 0x6367 # 0 +0xE97A 0x68D2 # 0 +0xE97B 0x70FD # 0 +0xE97C 0x71A2 # 0 +0xE97D 0x742B # 0 +0xE97E 0x7E2B # 0 +0xE991 0x84EC # 0 +0xE992 0x8702 # 0 +0xE993 0x9022 # 0 +0xE994 0x92D2 # 0 +0xE995 0x9CF3 # 0 +0xE996 0x4E0D # 0 +0xE997 0x4ED8 # 0 +0xE998 0x4FEF # 0 +0xE999 0x5085 # 0 +0xE99A 0x5256 # 0 +0xE99B 0x526F # 0 +0xE99C 0x5426 # 0 +0xE99D 0x5490 # 0 +0xE99E 0x57E0 # 0 +0xE99F 0x592B # 0 +0xE9A0 0x5A66 # 0 +0xE9A1 0x5B5A # 0 +0xE9A2 0x5B75 # 0 +0xE9A3 0x5BCC # 0 +0xE9A4 0x5E9C # 0 +0xE9A5 0xF966 # 0 +0xE9A6 0x6276 # 0 +0xE9A7 0x6577 # 0 +0xE9A8 0x65A7 # 0 +0xE9A9 0x6D6E # 0 +0xE9AA 0x6EA5 # 0 +0xE9AB 0x7236 # 0 +0xE9AC 0x7B26 # 0 +0xE9AD 0x7C3F # 0 +0xE9AE 0x7F36 # 0 +0xE9AF 0x8150 # 0 +0xE9B0 0x8151 # 0 +0xE9B1 0x819A # 0 +0xE9B2 0x8240 # 0 +0xE9B3 0x8299 # 0 +0xE9B4 0x83A9 # 0 +0xE9B5 0x8A03 # 0 +0xE9B6 0x8CA0 # 0 +0xE9B7 0x8CE6 # 0 +0xE9B8 0x8CFB # 0 +0xE9B9 0x8D74 # 0 +0xE9BA 0x8DBA # 0 +0xE9BB 0x90E8 # 0 +0xE9BC 0x91DC # 0 +0xE9BD 0x961C # 0 +0xE9BE 0x9644 # 0 +0xE9BF 0x99D9 # 0 +0xE9C0 0x9CE7 # 0 +0xE9C1 0x5317 # 0 +0xE9C2 0x5206 # 0 +0xE9C3 0x5429 # 0 +0xE9C4 0x5674 # 0 +0xE9C5 0x58B3 # 0 +0xE9C6 0x5954 # 0 +0xE9C7 0x596E # 0 +0xE9C8 0x5FFF # 0 +0xE9C9 0x61A4 # 0 +0xE9CA 0x626E # 0 +0xE9CB 0x6610 # 0 +0xE9CC 0x6C7E # 0 +0xE9CD 0x711A # 0 +0xE9CE 0x76C6 # 0 +0xE9CF 0x7C89 # 0 +0xE9D0 0x7CDE # 0 +0xE9D1 0x7D1B # 0 +0xE9D2 0x82AC # 0 +0xE9D3 0x8CC1 # 0 +0xE9D4 0x96F0 # 0 +0xE9D5 0xF967 # 0 +0xE9D6 0x4F5B # 0 +0xE9D7 0x5F17 # 0 +0xE9D8 0x5F7F # 0 +0xE9D9 0x62C2 # 0 +0xE9DA 0x5D29 # 0 +0xE9DB 0x670B # 0 +0xE9DC 0x68DA # 0 +0xE9DD 0x787C # 0 +0xE9DE 0x7E43 # 0 +0xE9DF 0x9D6C # 0 +0xE9E0 0x4E15 # 0 +0xE9E1 0x5099 # 0 +0xE9E2 0x5315 # 0 +0xE9E3 0x532A # 0 +0xE9E4 0x5351 # 0 +0xE9E5 0x5983 # 0 +0xE9E6 0x5A62 # 0 +0xE9E7 0x5E87 # 0 +0xE9E8 0x60B2 # 0 +0xE9E9 0x618A # 0 +0xE9EA 0x6249 # 0 +0xE9EB 0x6279 # 0 +0xE9EC 0x6590 # 0 +0xE9ED 0x6787 # 0 +0xE9EE 0x69A7 # 0 +0xE9EF 0x6BD4 # 0 +0xE9F0 0x6BD6 # 0 +0xE9F1 0x6BD7 # 0 +0xE9F2 0x6BD8 # 0 +0xE9F3 0x6CB8 # 0 +0xE9F4 0xF968 # 0 +0xE9F5 0x7435 # 0 +0xE9F6 0x75FA # 0 +0xE9F7 0x7812 # 0 +0xE9F8 0x7891 # 0 +0xE9F9 0x79D5 # 0 +0xE9FA 0x79D8 # 0 +0xE9FB 0x7C83 # 0 +0xE9FC 0x7DCB # 0 +0xE9FD 0x7FE1 # 0 +0xE9FE 0x80A5 # 0 +0xEA31 0x813E # 0 +0xEA32 0x81C2 # 0 +0xEA33 0x83F2 # 0 +0xEA34 0x871A # 0 +0xEA35 0x88E8 # 0 +0xEA36 0x8AB9 # 0 +0xEA37 0x8B6C # 0 +0xEA38 0x8CBB # 0 +0xEA39 0x9119 # 0 +0xEA3A 0x975E # 0 +0xEA3B 0x98DB # 0 +0xEA3C 0x9F3B # 0 +0xEA3D 0x56AC # 0 +0xEA3E 0x5B2A # 0 +0xEA3F 0x5F6C # 0 +0xEA40 0x658C # 0 +0xEA41 0x6AB3 # 0 +0xEA42 0x6BAF # 0 +0xEA43 0x6D5C # 0 +0xEA44 0x6FF1 # 0 +0xEA45 0x7015 # 0 +0xEA46 0x725D # 0 +0xEA47 0x73AD # 0 +0xEA48 0x8CA7 # 0 +0xEA49 0x8CD3 # 0 +0xEA4A 0x983B # 0 +0xEA4B 0x6191 # 0 +0xEA4C 0x6C37 # 0 +0xEA4D 0x8058 # 0 +0xEA4E 0x9A01 # 0 +0xEA4F 0x4E4D # 0 +0xEA50 0x4E8B # 0 +0xEA51 0x4E9B # 0 +0xEA52 0x4ED5 # 0 +0xEA53 0x4F3A # 0 +0xEA54 0x4F3C # 0 +0xEA55 0x4F7F # 0 +0xEA56 0x4FDF # 0 +0xEA57 0x50FF # 0 +0xEA58 0x53F2 # 0 +0xEA59 0x53F8 # 0 +0xEA5A 0x5506 # 0 +0xEA5B 0x55E3 # 0 +0xEA5C 0x56DB # 0 +0xEA5D 0x58EB # 0 +0xEA5E 0x5962 # 0 +0xEA5F 0x5A11 # 0 +0xEA60 0x5BEB # 0 +0xEA61 0x5BFA # 0 +0xEA62 0x5C04 # 0 +0xEA63 0x5DF3 # 0 +0xEA64 0x5E2B # 0 +0xEA65 0x5F99 # 0 +0xEA66 0x601D # 0 +0xEA67 0x6368 # 0 +0xEA68 0x659C # 0 +0xEA69 0x65AF # 0 +0xEA6A 0x67F6 # 0 +0xEA6B 0x67FB # 0 +0xEA6C 0x68AD # 0 +0xEA6D 0x6B7B # 0 +0xEA6E 0x6C99 # 0 +0xEA6F 0x6CD7 # 0 +0xEA70 0x6E23 # 0 +0xEA71 0x7009 # 0 +0xEA72 0x7345 # 0 +0xEA73 0x7802 # 0 +0xEA74 0x793E # 0 +0xEA75 0x7940 # 0 +0xEA76 0x7960 # 0 +0xEA77 0x79C1 # 0 +0xEA78 0x7BE9 # 0 +0xEA79 0x7D17 # 0 +0xEA7A 0x7D72 # 0 +0xEA7B 0x8086 # 0 +0xEA7C 0x820D # 0 +0xEA7D 0x838E # 0 +0xEA7E 0x84D1 # 0 +0xEA91 0x86C7 # 0 +0xEA92 0x88DF # 0 +0xEA93 0x8A50 # 0 +0xEA94 0x8A5E # 0 +0xEA95 0x8B1D # 0 +0xEA96 0x8CDC # 0 +0xEA97 0x8D66 # 0 +0xEA98 0x8FAD # 0 +0xEA99 0x90AA # 0 +0xEA9A 0x98FC # 0 +0xEA9B 0x99DF # 0 +0xEA9C 0x9E9D # 0 +0xEA9D 0x524A # 0 +0xEA9E 0xF969 # 0 +0xEA9F 0x6714 # 0 +0xEAA0 0xF96A # 0 +0xEAA1 0x5098 # 0 +0xEAA2 0x522A # 0 +0xEAA3 0x5C71 # 0 +0xEAA4 0x6563 # 0 +0xEAA5 0x6C55 # 0 +0xEAA6 0x73CA # 0 +0xEAA7 0x7523 # 0 +0xEAA8 0x759D # 0 +0xEAA9 0x7B97 # 0 +0xEAAA 0x849C # 0 +0xEAAB 0x9178 # 0 +0xEAAC 0x9730 # 0 +0xEAAD 0x4E77 # 0 +0xEAAE 0x6492 # 0 +0xEAAF 0x6BBA # 0 +0xEAB0 0x715E # 0 +0xEAB1 0x85A9 # 0 +0xEAB2 0x4E09 # 0 +0xEAB3 0xF96B # 0 +0xEAB4 0x6749 # 0 +0xEAB5 0x68EE # 0 +0xEAB6 0x6E17 # 0 +0xEAB7 0x829F # 0 +0xEAB8 0x8518 # 0 +0xEAB9 0x886B # 0 +0xEABA 0x63F7 # 0 +0xEABB 0x6F81 # 0 +0xEABC 0x9212 # 0 +0xEABD 0x98AF # 0 +0xEABE 0x4E0A # 0 +0xEABF 0x50B7 # 0 +0xEAC0 0x50CF # 0 +0xEAC1 0x511F # 0 +0xEAC2 0x5546 # 0 +0xEAC3 0x55AA # 0 +0xEAC4 0x5617 # 0 +0xEAC5 0x5B40 # 0 +0xEAC6 0x5C19 # 0 +0xEAC7 0x5CE0 # 0 +0xEAC8 0x5E38 # 0 +0xEAC9 0x5E8A # 0 +0xEACA 0x5EA0 # 0 +0xEACB 0x5EC2 # 0 +0xEACC 0x60F3 # 0 +0xEACD 0x6851 # 0 +0xEACE 0x6A61 # 0 +0xEACF 0x6E58 # 0 +0xEAD0 0x723D # 0 +0xEAD1 0x7240 # 0 +0xEAD2 0x72C0 # 0 +0xEAD3 0x76F8 # 0 +0xEAD4 0x7965 # 0 +0xEAD5 0x7BB1 # 0 +0xEAD6 0x7FD4 # 0 +0xEAD7 0x88F3 # 0 +0xEAD8 0x89F4 # 0 +0xEAD9 0x8A73 # 0 +0xEADA 0x8C61 # 0 +0xEADB 0x8CDE # 0 +0xEADC 0x971C # 0 +0xEADD 0x585E # 0 +0xEADE 0x74BD # 0 +0xEADF 0x8CFD # 0 +0xEAE0 0x55C7 # 0 +0xEAE1 0xF96C # 0 +0xEAE2 0x7A61 # 0 +0xEAE3 0x7D22 # 0 +0xEAE4 0x8272 # 0 +0xEAE5 0x7272 # 0 +0xEAE6 0x751F # 0 +0xEAE7 0x7525 # 0 +0xEAE8 0xF96D # 0 +0xEAE9 0x7B19 # 0 +0xEAEA 0x5885 # 0 +0xEAEB 0x58FB # 0 +0xEAEC 0x5DBC # 0 +0xEAED 0x5E8F # 0 +0xEAEE 0x5EB6 # 0 +0xEAEF 0x5F90 # 0 +0xEAF0 0x6055 # 0 +0xEAF1 0x6292 # 0 +0xEAF2 0x637F # 0 +0xEAF3 0x654D # 0 +0xEAF4 0x6691 # 0 +0xEAF5 0x66D9 # 0 +0xEAF6 0x66F8 # 0 +0xEAF7 0x6816 # 0 +0xEAF8 0x68F2 # 0 +0xEAF9 0x7280 # 0 +0xEAFA 0x745E # 0 +0xEAFB 0x7B6E # 0 +0xEAFC 0x7D6E # 0 +0xEAFD 0x7DD6 # 0 +0xEAFE 0x7F72 # 0 +0xEB31 0x80E5 # 0 +0xEB32 0x8212 # 0 +0xEB33 0x85AF # 0 +0xEB34 0x897F # 0 +0xEB35 0x8A93 # 0 +0xEB36 0x901D # 0 +0xEB37 0x92E4 # 0 +0xEB38 0x9ECD # 0 +0xEB39 0x9F20 # 0 +0xEB3A 0x5915 # 0 +0xEB3B 0x596D # 0 +0xEB3C 0x5E2D # 0 +0xEB3D 0x60DC # 0 +0xEB3E 0x6614 # 0 +0xEB3F 0x6673 # 0 +0xEB40 0x6790 # 0 +0xEB41 0x6C50 # 0 +0xEB42 0x6DC5 # 0 +0xEB43 0x6F5F # 0 +0xEB44 0x77F3 # 0 +0xEB45 0x78A9 # 0 +0xEB46 0x84C6 # 0 +0xEB47 0x91CB # 0 +0xEB48 0x932B # 0 +0xEB49 0x4ED9 # 0 +0xEB4A 0x50CA # 0 +0xEB4B 0x5148 # 0 +0xEB4C 0x5584 # 0 +0xEB4D 0x5B0B # 0 +0xEB4E 0x5BA3 # 0 +0xEB4F 0x6247 # 0 +0xEB50 0x657E # 0 +0xEB51 0x65CB # 0 +0xEB52 0x6E32 # 0 +0xEB53 0x717D # 0 +0xEB54 0x7401 # 0 +0xEB55 0x7444 # 0 +0xEB56 0x7487 # 0 +0xEB57 0x74BF # 0 +0xEB58 0x766C # 0 +0xEB59 0x79AA # 0 +0xEB5A 0x7DDA # 0 +0xEB5B 0x7E55 # 0 +0xEB5C 0x7FA8 # 0 +0xEB5D 0x817A # 0 +0xEB5E 0x81B3 # 0 +0xEB5F 0x8239 # 0 +0xEB60 0x861A # 0 +0xEB61 0x87EC # 0 +0xEB62 0x8A75 # 0 +0xEB63 0x8DE3 # 0 +0xEB64 0x9078 # 0 +0xEB65 0x9291 # 0 +0xEB66 0x9425 # 0 +0xEB67 0x994D # 0 +0xEB68 0x9BAE # 0 +0xEB69 0x5368 # 0 +0xEB6A 0x5C51 # 0 +0xEB6B 0x6954 # 0 +0xEB6C 0x6CC4 # 0 +0xEB6D 0x6D29 # 0 +0xEB6E 0x6E2B # 0 +0xEB6F 0x820C # 0 +0xEB70 0x859B # 0 +0xEB71 0x893B # 0 +0xEB72 0x8A2D # 0 +0xEB73 0x8AAA # 0 +0xEB74 0x96EA # 0 +0xEB75 0x9F67 # 0 +0xEB76 0x5261 # 0 +0xEB77 0x66B9 # 0 +0xEB78 0x6BB2 # 0 +0xEB79 0x7E96 # 0 +0xEB7A 0x87FE # 0 +0xEB7B 0x8D0D # 0 +0xEB7C 0x9583 # 0 +0xEB7D 0x965D # 0 +0xEB7E 0x651D # 0 +0xEB91 0x6D89 # 0 +0xEB92 0x71EE # 0 +0xEB93 0xF96E # 0 +0xEB94 0x57CE # 0 +0xEB95 0x59D3 # 0 +0xEB96 0x5BAC # 0 +0xEB97 0x6027 # 0 +0xEB98 0x60FA # 0 +0xEB99 0x6210 # 0 +0xEB9A 0x661F # 0 +0xEB9B 0x665F # 0 +0xEB9C 0x7329 # 0 +0xEB9D 0x73F9 # 0 +0xEB9E 0x76DB # 0 +0xEB9F 0x7701 # 0 +0xEBA0 0x7B6C # 0 +0xEBA1 0x8056 # 0 +0xEBA2 0x8072 # 0 +0xEBA3 0x8165 # 0 +0xEBA4 0x8AA0 # 0 +0xEBA5 0x9192 # 0 +0xEBA6 0x4E16 # 0 +0xEBA7 0x52E2 # 0 +0xEBA8 0x6B72 # 0 +0xEBA9 0x6D17 # 0 +0xEBAA 0x7A05 # 0 +0xEBAB 0x7B39 # 0 +0xEBAC 0x7D30 # 0 +0xEBAD 0xF96F # 0 +0xEBAE 0x8CB0 # 0 +0xEBAF 0x53EC # 0 +0xEBB0 0x562F # 0 +0xEBB1 0x5851 # 0 +0xEBB2 0x5BB5 # 0 +0xEBB3 0x5C0F # 0 +0xEBB4 0x5C11 # 0 +0xEBB5 0x5DE2 # 0 +0xEBB6 0x6240 # 0 +0xEBB7 0x6383 # 0 +0xEBB8 0x6414 # 0 +0xEBB9 0x662D # 0 +0xEBBA 0x68B3 # 0 +0xEBBB 0x6CBC # 0 +0xEBBC 0x6D88 # 0 +0xEBBD 0x6EAF # 0 +0xEBBE 0x701F # 0 +0xEBBF 0x70A4 # 0 +0xEBC0 0x71D2 # 0 +0xEBC1 0x7526 # 0 +0xEBC2 0x758F # 0 +0xEBC3 0x758E # 0 +0xEBC4 0x7619 # 0 +0xEBC5 0x7B11 # 0 +0xEBC6 0x7BE0 # 0 +0xEBC7 0x7C2B # 0 +0xEBC8 0x7D20 # 0 +0xEBC9 0x7D39 # 0 +0xEBCA 0x852C # 0 +0xEBCB 0x856D # 0 +0xEBCC 0x8607 # 0 +0xEBCD 0x8A34 # 0 +0xEBCE 0x900D # 0 +0xEBCF 0x9061 # 0 +0xEBD0 0x90B5 # 0 +0xEBD1 0x92B7 # 0 +0xEBD2 0x97F6 # 0 +0xEBD3 0x9A37 # 0 +0xEBD4 0x4FD7 # 0 +0xEBD5 0x5C6C # 0 +0xEBD6 0x675F # 0 +0xEBD7 0x6D91 # 0 +0xEBD8 0x7C9F # 0 +0xEBD9 0x7E8C # 0 +0xEBDA 0x8B16 # 0 +0xEBDB 0x8D16 # 0 +0xEBDC 0x901F # 0 +0xEBDD 0x5B6B # 0 +0xEBDE 0x5DFD # 0 +0xEBDF 0x640D # 0 +0xEBE0 0x84C0 # 0 +0xEBE1 0x905C # 0 +0xEBE2 0x98E1 # 0 +0xEBE3 0x7387 # 0 +0xEBE4 0x5B8B # 0 +0xEBE5 0x609A # 0 +0xEBE6 0x677E # 0 +0xEBE7 0x6DDE # 0 +0xEBE8 0x8A1F # 0 +0xEBE9 0x8AA6 # 0 +0xEBEA 0x9001 # 0 +0xEBEB 0x980C # 0 +0xEBEC 0x5237 # 0 +0xEBED 0xF970 # 0 +0xEBEE 0x7051 # 0 +0xEBEF 0x788E # 0 +0xEBF0 0x9396 # 0 +0xEBF1 0x8870 # 0 +0xEBF2 0x91D7 # 0 +0xEBF3 0x4FEE # 0 +0xEBF4 0x53D7 # 0 +0xEBF5 0x55FD # 0 +0xEBF6 0x56DA # 0 +0xEBF7 0x5782 # 0 +0xEBF8 0x58FD # 0 +0xEBF9 0x5AC2 # 0 +0xEBFA 0x5B88 # 0 +0xEBFB 0x5CAB # 0 +0xEBFC 0x5CC0 # 0 +0xEBFD 0x5E25 # 0 +0xEBFE 0x6101 # 0 +0xEC31 0x620D # 0 +0xEC32 0x624B # 0 +0xEC33 0x6388 # 0 +0xEC34 0x641C # 0 +0xEC35 0x6536 # 0 +0xEC36 0x6578 # 0 +0xEC37 0x6A39 # 0 +0xEC38 0x6B8A # 0 +0xEC39 0x6C34 # 0 +0xEC3A 0x6D19 # 0 +0xEC3B 0x6F31 # 0 +0xEC3C 0x71E7 # 0 +0xEC3D 0x72E9 # 0 +0xEC3E 0x7378 # 0 +0xEC3F 0x7407 # 0 +0xEC40 0x74B2 # 0 +0xEC41 0x7626 # 0 +0xEC42 0x7761 # 0 +0xEC43 0x79C0 # 0 +0xEC44 0x7A57 # 0 +0xEC45 0x7AEA # 0 +0xEC46 0x7CB9 # 0 +0xEC47 0x7D8F # 0 +0xEC48 0x7DAC # 0 +0xEC49 0x7E61 # 0 +0xEC4A 0x7F9E # 0 +0xEC4B 0x8129 # 0 +0xEC4C 0x8331 # 0 +0xEC4D 0x8490 # 0 +0xEC4E 0x84DA # 0 +0xEC4F 0x85EA # 0 +0xEC50 0x8896 # 0 +0xEC51 0x8AB0 # 0 +0xEC52 0x8B90 # 0 +0xEC53 0x8F38 # 0 +0xEC54 0x9042 # 0 +0xEC55 0x9083 # 0 +0xEC56 0x916C # 0 +0xEC57 0x9296 # 0 +0xEC58 0x92B9 # 0 +0xEC59 0x968B # 0 +0xEC5A 0x96A7 # 0 +0xEC5B 0x96A8 # 0 +0xEC5C 0x96D6 # 0 +0xEC5D 0x9700 # 0 +0xEC5E 0x9808 # 0 +0xEC5F 0x9996 # 0 +0xEC60 0x9AD3 # 0 +0xEC61 0x9B1A # 0 +0xEC62 0x53D4 # 0 +0xEC63 0x587E # 0 +0xEC64 0x5919 # 0 +0xEC65 0x5B70 # 0 +0xEC66 0x5BBF # 0 +0xEC67 0x6DD1 # 0 +0xEC68 0x6F5A # 0 +0xEC69 0x719F # 0 +0xEC6A 0x7421 # 0 +0xEC6B 0x74B9 # 0 +0xEC6C 0x8085 # 0 +0xEC6D 0x83FD # 0 +0xEC6E 0x5DE1 # 0 +0xEC6F 0x5F87 # 0 +0xEC70 0x5FAA # 0 +0xEC71 0x6042 # 0 +0xEC72 0x65EC # 0 +0xEC73 0x6812 # 0 +0xEC74 0x696F # 0 +0xEC75 0x6A53 # 0 +0xEC76 0x6B89 # 0 +0xEC77 0x6D35 # 0 +0xEC78 0x6DF3 # 0 +0xEC79 0x73E3 # 0 +0xEC7A 0x76FE # 0 +0xEC7B 0x77AC # 0 +0xEC7C 0x7B4D # 0 +0xEC7D 0x7D14 # 0 +0xEC7E 0x8123 # 0 +0xEC91 0x821C # 0 +0xEC92 0x8340 # 0 +0xEC93 0x84F4 # 0 +0xEC94 0x8563 # 0 +0xEC95 0x8A62 # 0 +0xEC96 0x8AC4 # 0 +0xEC97 0x9187 # 0 +0xEC98 0x931E # 0 +0xEC99 0x9806 # 0 +0xEC9A 0x99B4 # 0 +0xEC9B 0x620C # 0 +0xEC9C 0x8853 # 0 +0xEC9D 0x8FF0 # 0 +0xEC9E 0x9265 # 0 +0xEC9F 0x5D07 # 0 +0xECA0 0x5D27 # 0 +0xECA1 0x5D69 # 0 +0xECA2 0x745F # 0 +0xECA3 0x819D # 0 +0xECA4 0x8768 # 0 +0xECA5 0x6FD5 # 0 +0xECA6 0x62FE # 0 +0xECA7 0x7FD2 # 0 +0xECA8 0x8936 # 0 +0xECA9 0x8972 # 0 +0xECAA 0x4E1E # 0 +0xECAB 0x4E58 # 0 +0xECAC 0x50E7 # 0 +0xECAD 0x52DD # 0 +0xECAE 0x5347 # 0 +0xECAF 0x627F # 0 +0xECB0 0x6607 # 0 +0xECB1 0x7E69 # 0 +0xECB2 0x8805 # 0 +0xECB3 0x965E # 0 +0xECB4 0x4F8D # 0 +0xECB5 0x5319 # 0 +0xECB6 0x5636 # 0 +0xECB7 0x59CB # 0 +0xECB8 0x5AA4 # 0 +0xECB9 0x5C38 # 0 +0xECBA 0x5C4E # 0 +0xECBB 0x5C4D # 0 +0xECBC 0x5E02 # 0 +0xECBD 0x5F11 # 0 +0xECBE 0x6043 # 0 +0xECBF 0x65BD # 0 +0xECC0 0x662F # 0 +0xECC1 0x6642 # 0 +0xECC2 0x67BE # 0 +0xECC3 0x67F4 # 0 +0xECC4 0x731C # 0 +0xECC5 0x77E2 # 0 +0xECC6 0x793A # 0 +0xECC7 0x7FC5 # 0 +0xECC8 0x8494 # 0 +0xECC9 0x84CD # 0 +0xECCA 0x8996 # 0 +0xECCB 0x8A66 # 0 +0xECCC 0x8A69 # 0 +0xECCD 0x8AE1 # 0 +0xECCE 0x8C55 # 0 +0xECCF 0x8C7A # 0 +0xECD0 0x57F4 # 0 +0xECD1 0x5BD4 # 0 +0xECD2 0x5F0F # 0 +0xECD3 0x606F # 0 +0xECD4 0x62ED # 0 +0xECD5 0x690D # 0 +0xECD6 0x6B96 # 0 +0xECD7 0x6E5C # 0 +0xECD8 0x7184 # 0 +0xECD9 0x7BD2 # 0 +0xECDA 0x8755 # 0 +0xECDB 0x8B58 # 0 +0xECDC 0x8EFE # 0 +0xECDD 0x98DF # 0 +0xECDE 0x98FE # 0 +0xECDF 0x4F38 # 0 +0xECE0 0x4F81 # 0 +0xECE1 0x4FE1 # 0 +0xECE2 0x547B # 0 +0xECE3 0x5A20 # 0 +0xECE4 0x5BB8 # 0 +0xECE5 0x613C # 0 +0xECE6 0x65B0 # 0 +0xECE7 0x6668 # 0 +0xECE8 0x71FC # 0 +0xECE9 0x7533 # 0 +0xECEA 0x795E # 0 +0xECEB 0x7D33 # 0 +0xECEC 0x814E # 0 +0xECED 0x81E3 # 0 +0xECEE 0x8398 # 0 +0xECEF 0x85AA # 0 +0xECF0 0x85CE # 0 +0xECF1 0x8703 # 0 +0xECF2 0x8A0A # 0 +0xECF3 0x8EAB # 0 +0xECF4 0x8F9B # 0 +0xECF5 0xF971 # 0 +0xECF6 0x8FC5 # 0 +0xECF7 0x5931 # 0 +0xECF8 0x5BA4 # 0 +0xECF9 0x5BE6 # 0 +0xECFA 0x6089 # 0 +0xECFB 0x5BE9 # 0 +0xECFC 0x5C0B # 0 +0xECFD 0x5FC3 # 0 +0xECFE 0x6C81 # 0 +0xED31 0xF972 # 0 +0xED32 0x6DF1 # 0 +0xED33 0x700B # 0 +0xED34 0x751A # 0 +0xED35 0x82AF # 0 +0xED36 0x8AF6 # 0 +0xED37 0x4EC0 # 0 +0xED38 0x5341 # 0 +0xED39 0xF973 # 0 +0xED3A 0x96D9 # 0 +0xED3B 0x6C0F # 0 +0xED3C 0x4E9E # 0 +0xED3D 0x4FC4 # 0 +0xED3E 0x5152 # 0 +0xED3F 0x555E # 0 +0xED40 0x5A25 # 0 +0xED41 0x5CE8 # 0 +0xED42 0x6211 # 0 +0xED43 0x7259 # 0 +0xED44 0x82BD # 0 +0xED45 0x83AA # 0 +0xED46 0x86FE # 0 +0xED47 0x8859 # 0 +0xED48 0x8A1D # 0 +0xED49 0x963F # 0 +0xED4A 0x96C5 # 0 +0xED4B 0x9913 # 0 +0xED4C 0x9D09 # 0 +0xED4D 0x9D5D # 0 +0xED4E 0x580A # 0 +0xED4F 0x5CB3 # 0 +0xED50 0x5DBD # 0 +0xED51 0x5E44 # 0 +0xED52 0x60E1 # 0 +0xED53 0x6115 # 0 +0xED54 0x63E1 # 0 +0xED55 0x6A02 # 0 +0xED56 0x6E25 # 0 +0xED57 0x9102 # 0 +0xED58 0x9354 # 0 +0xED59 0x984E # 0 +0xED5A 0x9C10 # 0 +0xED5B 0x9F77 # 0 +0xED5C 0x5B89 # 0 +0xED5D 0x5CB8 # 0 +0xED5E 0x6309 # 0 +0xED5F 0x664F # 0 +0xED60 0x6848 # 0 +0xED61 0x773C # 0 +0xED62 0x96C1 # 0 +0xED63 0x978D # 0 +0xED64 0x9854 # 0 +0xED65 0x9B9F # 0 +0xED66 0x65A1 # 0 +0xED67 0x8B01 # 0 +0xED68 0x8ECB # 0 +0xED69 0x95BC # 0 +0xED6A 0x5535 # 0 +0xED6B 0x5CA9 # 0 +0xED6C 0x5DD6 # 0 +0xED6D 0x5EB5 # 0 +0xED6E 0x6697 # 0 +0xED6F 0x764C # 0 +0xED70 0x83F4 # 0 +0xED71 0x95C7 # 0 +0xED72 0x58D3 # 0 +0xED73 0x62BC # 0 +0xED74 0x72CE # 0 +0xED75 0x9D28 # 0 +0xED76 0x4EF0 # 0 +0xED77 0x592E # 0 +0xED78 0x600F # 0 +0xED79 0x663B # 0 +0xED7A 0x6B83 # 0 +0xED7B 0x79E7 # 0 +0xED7C 0x9D26 # 0 +0xED7D 0x5393 # 0 +0xED7E 0x54C0 # 0 +0xED91 0x57C3 # 0 +0xED92 0x5D16 # 0 +0xED93 0x611B # 0 +0xED94 0x66D6 # 0 +0xED95 0x6DAF # 0 +0xED96 0x788D # 0 +0xED97 0x827E # 0 +0xED98 0x9698 # 0 +0xED99 0x9744 # 0 +0xED9A 0x5384 # 0 +0xED9B 0x627C # 0 +0xED9C 0x6396 # 0 +0xED9D 0x6DB2 # 0 +0xED9E 0x7E0A # 0 +0xED9F 0x814B # 0 +0xEDA0 0x984D # 0 +0xEDA1 0x6AFB # 0 +0xEDA2 0x7F4C # 0 +0xEDA3 0x9DAF # 0 +0xEDA4 0x9E1A # 0 +0xEDA5 0x4E5F # 0 +0xEDA6 0x503B # 0 +0xEDA7 0x51B6 # 0 +0xEDA8 0x591C # 0 +0xEDA9 0x60F9 # 0 +0xEDAA 0x63F6 # 0 +0xEDAB 0x6930 # 0 +0xEDAC 0x723A # 0 +0xEDAD 0x8036 # 0 +0xEDAE 0xF974 # 0 +0xEDAF 0x91CE # 0 +0xEDB0 0x5F31 # 0 +0xEDB1 0xF975 # 0 +0xEDB2 0xF976 # 0 +0xEDB3 0x7D04 # 0 +0xEDB4 0x82E5 # 0 +0xEDB5 0x846F # 0 +0xEDB6 0x84BB # 0 +0xEDB7 0x85E5 # 0 +0xEDB8 0x8E8D # 0 +0xEDB9 0xF977 # 0 +0xEDBA 0x4F6F # 0 +0xEDBB 0xF978 # 0 +0xEDBC 0xF979 # 0 +0xEDBD 0x58E4 # 0 +0xEDBE 0x5B43 # 0 +0xEDBF 0x6059 # 0 +0xEDC0 0x63DA # 0 +0xEDC1 0x6518 # 0 +0xEDC2 0x656D # 0 +0xEDC3 0x6698 # 0 +0xEDC4 0xF97A # 0 +0xEDC5 0x694A # 0 +0xEDC6 0x6A23 # 0 +0xEDC7 0x6D0B # 0 +0xEDC8 0x7001 # 0 +0xEDC9 0x716C # 0 +0xEDCA 0x75D2 # 0 +0xEDCB 0x760D # 0 +0xEDCC 0x79B3 # 0 +0xEDCD 0x7A70 # 0 +0xEDCE 0xF97B # 0 +0xEDCF 0x7F8A # 0 +0xEDD0 0xF97C # 0 +0xEDD1 0x8944 # 0 +0xEDD2 0xF97D # 0 +0xEDD3 0x8B93 # 0 +0xEDD4 0x91C0 # 0 +0xEDD5 0x967D # 0 +0xEDD6 0xF97E # 0 +0xEDD7 0x990A # 0 +0xEDD8 0x5704 # 0 +0xEDD9 0x5FA1 # 0 +0xEDDA 0x65BC # 0 +0xEDDB 0x6F01 # 0 +0xEDDC 0x7600 # 0 +0xEDDD 0x79A6 # 0 +0xEDDE 0x8A9E # 0 +0xEDDF 0x99AD # 0 +0xEDE0 0x9B5A # 0 +0xEDE1 0x9F6C # 0 +0xEDE2 0x5104 # 0 +0xEDE3 0x61B6 # 0 +0xEDE4 0x6291 # 0 +0xEDE5 0x6A8D # 0 +0xEDE6 0x81C6 # 0 +0xEDE7 0x5043 # 0 +0xEDE8 0x5830 # 0 +0xEDE9 0x5F66 # 0 +0xEDEA 0x7109 # 0 +0xEDEB 0x8A00 # 0 +0xEDEC 0x8AFA # 0 +0xEDED 0x5B7C # 0 +0xEDEE 0x8616 # 0 +0xEDEF 0x4FFA # 0 +0xEDF0 0x513C # 0 +0xEDF1 0x56B4 # 0 +0xEDF2 0x5944 # 0 +0xEDF3 0x63A9 # 0 +0xEDF4 0x6DF9 # 0 +0xEDF5 0x5DAA # 0 +0xEDF6 0x696D # 0 +0xEDF7 0x5186 # 0 +0xEDF8 0x4E88 # 0 +0xEDF9 0x4F59 # 0 +0xEDFA 0xF97F # 0 +0xEDFB 0xF980 # 0 +0xEDFC 0xF981 # 0 +0xEDFD 0x5982 # 0 +0xEDFE 0xF982 # 0 +0xEE31 0xF983 # 0 +0xEE32 0x6B5F # 0 +0xEE33 0x6C5D # 0 +0xEE34 0xF984 # 0 +0xEE35 0x74B5 # 0 +0xEE36 0x7916 # 0 +0xEE37 0xF985 # 0 +0xEE38 0x8207 # 0 +0xEE39 0x8245 # 0 +0xEE3A 0x8339 # 0 +0xEE3B 0x8F3F # 0 +0xEE3C 0x8F5D # 0 +0xEE3D 0xF986 # 0 +0xEE3E 0x9918 # 0 +0xEE3F 0xF987 # 0 +0xEE40 0xF988 # 0 +0xEE41 0xF989 # 0 +0xEE42 0x4EA6 # 0 +0xEE43 0xF98A # 0 +0xEE44 0x57DF # 0 +0xEE45 0x5F79 # 0 +0xEE46 0x6613 # 0 +0xEE47 0xF98B # 0 +0xEE48 0xF98C # 0 +0xEE49 0x75AB # 0 +0xEE4A 0x7E79 # 0 +0xEE4B 0x8B6F # 0 +0xEE4C 0xF98D # 0 +0xEE4D 0x9006 # 0 +0xEE4E 0x9A5B # 0 +0xEE4F 0x56A5 # 0 +0xEE50 0x5827 # 0 +0xEE51 0x59F8 # 0 +0xEE52 0x5A1F # 0 +0xEE53 0x5BB4 # 0 +0xEE54 0xF98E # 0 +0xEE55 0x5EF6 # 0 +0xEE56 0xF98F # 0 +0xEE57 0xF990 # 0 +0xEE58 0x6350 # 0 +0xEE59 0x633B # 0 +0xEE5A 0xF991 # 0 +0xEE5B 0x693D # 0 +0xEE5C 0x6C87 # 0 +0xEE5D 0x6CBF # 0 +0xEE5E 0x6D8E # 0 +0xEE5F 0x6D93 # 0 +0xEE60 0x6DF5 # 0 +0xEE61 0x6F14 # 0 +0xEE62 0xF992 # 0 +0xEE63 0x70DF # 0 +0xEE64 0x7136 # 0 +0xEE65 0x7159 # 0 +0xEE66 0xF993 # 0 +0xEE67 0x71C3 # 0 +0xEE68 0x71D5 # 0 +0xEE69 0xF994 # 0 +0xEE6A 0x784F # 0 +0xEE6B 0x786F # 0 +0xEE6C 0xF995 # 0 +0xEE6D 0x7B75 # 0 +0xEE6E 0x7DE3 # 0 +0xEE6F 0xF996 # 0 +0xEE70 0x7E2F # 0 +0xEE71 0xF997 # 0 +0xEE72 0x884D # 0 +0xEE73 0x8EDF # 0 +0xEE74 0xF998 # 0 +0xEE75 0xF999 # 0 +0xEE76 0xF99A # 0 +0xEE77 0x925B # 0 +0xEE78 0xF99B # 0 +0xEE79 0x9CF6 # 0 +0xEE7A 0xF99C # 0 +0xEE7B 0xF99D # 0 +0xEE7C 0xF99E # 0 +0xEE7D 0x6085 # 0 +0xEE7E 0x6D85 # 0 +0xEE91 0xF99F # 0 +0xEE92 0x71B1 # 0 +0xEE93 0xF9A0 # 0 +0xEE94 0xF9A1 # 0 +0xEE95 0x95B1 # 0 +0xEE96 0x53AD # 0 +0xEE97 0xF9A2 # 0 +0xEE98 0xF9A3 # 0 +0xEE99 0xF9A4 # 0 +0xEE9A 0x67D3 # 0 +0xEE9B 0xF9A5 # 0 +0xEE9C 0x708E # 0 +0xEE9D 0x7130 # 0 +0xEE9E 0x7430 # 0 +0xEE9F 0x8276 # 0 +0xEEA0 0x82D2 # 0 +0xEEA1 0xF9A6 # 0 +0xEEA2 0x95BB # 0 +0xEEA3 0x9AE5 # 0 +0xEEA4 0x9E7D # 0 +0xEEA5 0x66C4 # 0 +0xEEA6 0xF9A7 # 0 +0xEEA7 0x71C1 # 0 +0xEEA8 0x8449 # 0 +0xEEA9 0xF9A8 # 0 +0xEEAA 0xF9A9 # 0 +0xEEAB 0x584B # 0 +0xEEAC 0xF9AA # 0 +0xEEAD 0xF9AB # 0 +0xEEAE 0x5DB8 # 0 +0xEEAF 0x5F71 # 0 +0xEEB0 0xF9AC # 0 +0xEEB1 0x6620 # 0 +0xEEB2 0x668E # 0 +0xEEB3 0x6979 # 0 +0xEEB4 0x69AE # 0 +0xEEB5 0x6C38 # 0 +0xEEB6 0x6CF3 # 0 +0xEEB7 0x6E36 # 0 +0xEEB8 0x6F41 # 0 +0xEEB9 0x6FDA # 0 +0xEEBA 0x701B # 0 +0xEEBB 0x702F # 0 +0xEEBC 0x7150 # 0 +0xEEBD 0x71DF # 0 +0xEEBE 0x7370 # 0 +0xEEBF 0xF9AD # 0 +0xEEC0 0x745B # 0 +0xEEC1 0xF9AE # 0 +0xEEC2 0x74D4 # 0 +0xEEC3 0x76C8 # 0 +0xEEC4 0x7A4E # 0 +0xEEC5 0x7E93 # 0 +0xEEC6 0xF9AF # 0 +0xEEC7 0xF9B0 # 0 +0xEEC8 0x82F1 # 0 +0xEEC9 0x8A60 # 0 +0xEECA 0x8FCE # 0 +0xEECB 0xF9B1 # 0 +0xEECC 0x9348 # 0 +0xEECD 0xF9B2 # 0 +0xEECE 0x9719 # 0 +0xEECF 0xF9B3 # 0 +0xEED0 0xF9B4 # 0 +0xEED1 0x4E42 # 0 +0xEED2 0x502A # 0 +0xEED3 0xF9B5 # 0 +0xEED4 0x5208 # 0 +0xEED5 0x53E1 # 0 +0xEED6 0x66F3 # 0 +0xEED7 0x6C6D # 0 +0xEED8 0x6FCA # 0 +0xEED9 0x730A # 0 +0xEEDA 0x777F # 0 +0xEEDB 0x7A62 # 0 +0xEEDC 0x82AE # 0 +0xEEDD 0x85DD # 0 +0xEEDE 0x8602 # 0 +0xEEDF 0xF9B6 # 0 +0xEEE0 0x88D4 # 0 +0xEEE1 0x8A63 # 0 +0xEEE2 0x8B7D # 0 +0xEEE3 0x8C6B # 0 +0xEEE4 0xF9B7 # 0 +0xEEE5 0x92B3 # 0 +0xEEE6 0xF9B8 # 0 +0xEEE7 0x9713 # 0 +0xEEE8 0x9810 # 0 +0xEEE9 0x4E94 # 0 +0xEEEA 0x4F0D # 0 +0xEEEB 0x4FC9 # 0 +0xEEEC 0x50B2 # 0 +0xEEED 0x5348 # 0 +0xEEEE 0x543E # 0 +0xEEEF 0x5433 # 0 +0xEEF0 0x55DA # 0 +0xEEF1 0x5862 # 0 +0xEEF2 0x58BA # 0 +0xEEF3 0x5967 # 0 +0xEEF4 0x5A1B # 0 +0xEEF5 0x5BE4 # 0 +0xEEF6 0x609F # 0 +0xEEF7 0xF9B9 # 0 +0xEEF8 0x61CA # 0 +0xEEF9 0x6556 # 0 +0xEEFA 0x65FF # 0 +0xEEFB 0x6664 # 0 +0xEEFC 0x68A7 # 0 +0xEEFD 0x6C5A # 0 +0xEEFE 0x6FB3 # 0 +0xEF31 0x70CF # 0 +0xEF32 0x71AC # 0 +0xEF33 0x7352 # 0 +0xEF34 0x7B7D # 0 +0xEF35 0x8708 # 0 +0xEF36 0x8AA4 # 0 +0xEF37 0x9C32 # 0 +0xEF38 0x9F07 # 0 +0xEF39 0x5C4B # 0 +0xEF3A 0x6C83 # 0 +0xEF3B 0x7344 # 0 +0xEF3C 0x7389 # 0 +0xEF3D 0x923A # 0 +0xEF3E 0x6EAB # 0 +0xEF3F 0x7465 # 0 +0xEF40 0x761F # 0 +0xEF41 0x7A69 # 0 +0xEF42 0x7E15 # 0 +0xEF43 0x860A # 0 +0xEF44 0x5140 # 0 +0xEF45 0x58C5 # 0 +0xEF46 0x64C1 # 0 +0xEF47 0x74EE # 0 +0xEF48 0x7515 # 0 +0xEF49 0x7670 # 0 +0xEF4A 0x7FC1 # 0 +0xEF4B 0x9095 # 0 +0xEF4C 0x96CD # 0 +0xEF4D 0x9954 # 0 +0xEF4E 0x6E26 # 0 +0xEF4F 0x74E6 # 0 +0xEF50 0x7AA9 # 0 +0xEF51 0x7AAA # 0 +0xEF52 0x81E5 # 0 +0xEF53 0x86D9 # 0 +0xEF54 0x8778 # 0 +0xEF55 0x8A1B # 0 +0xEF56 0x5A49 # 0 +0xEF57 0x5B8C # 0 +0xEF58 0x5B9B # 0 +0xEF59 0x68A1 # 0 +0xEF5A 0x6900 # 0 +0xEF5B 0x6D63 # 0 +0xEF5C 0x73A9 # 0 +0xEF5D 0x7413 # 0 +0xEF5E 0x742C # 0 +0xEF5F 0x7897 # 0 +0xEF60 0x7DE9 # 0 +0xEF61 0x7FEB # 0 +0xEF62 0x8118 # 0 +0xEF63 0x8155 # 0 +0xEF64 0x839E # 0 +0xEF65 0x8C4C # 0 +0xEF66 0x962E # 0 +0xEF67 0x9811 # 0 +0xEF68 0x66F0 # 0 +0xEF69 0x5F80 # 0 +0xEF6A 0x65FA # 0 +0xEF6B 0x6789 # 0 +0xEF6C 0x6C6A # 0 +0xEF6D 0x738B # 0 +0xEF6E 0x502D # 0 +0xEF6F 0x5A03 # 0 +0xEF70 0x6B6A # 0 +0xEF71 0x77EE # 0 +0xEF72 0x5916 # 0 +0xEF73 0x5D6C # 0 +0xEF74 0x5DCD # 0 +0xEF75 0x7325 # 0 +0xEF76 0x754F # 0 +0xEF77 0xF9BA # 0 +0xEF78 0xF9BB # 0 +0xEF79 0x50E5 # 0 +0xEF7A 0x51F9 # 0 +0xEF7B 0x582F # 0 +0xEF7C 0x592D # 0 +0xEF7D 0x5996 # 0 +0xEF7E 0x59DA # 0 +0xEF91 0x5BE5 # 0 +0xEF92 0xF9BC # 0 +0xEF93 0xF9BD # 0 +0xEF94 0x5DA2 # 0 +0xEF95 0x62D7 # 0 +0xEF96 0x6416 # 0 +0xEF97 0x6493 # 0 +0xEF98 0x64FE # 0 +0xEF99 0xF9BE # 0 +0xEF9A 0x66DC # 0 +0xEF9B 0xF9BF # 0 +0xEF9C 0x6A48 # 0 +0xEF9D 0xF9C0 # 0 +0xEF9E 0x71FF # 0 +0xEF9F 0x7464 # 0 +0xEFA0 0xF9C1 # 0 +0xEFA1 0x7A88 # 0 +0xEFA2 0x7AAF # 0 +0xEFA3 0x7E47 # 0 +0xEFA4 0x7E5E # 0 +0xEFA5 0x8000 # 0 +0xEFA6 0x8170 # 0 +0xEFA7 0xF9C2 # 0 +0xEFA8 0x87EF # 0 +0xEFA9 0x8981 # 0 +0xEFAA 0x8B20 # 0 +0xEFAB 0x9059 # 0 +0xEFAC 0xF9C3 # 0 +0xEFAD 0x9080 # 0 +0xEFAE 0x9952 # 0 +0xEFAF 0x617E # 0 +0xEFB0 0x6B32 # 0 +0xEFB1 0x6D74 # 0 +0xEFB2 0x7E1F # 0 +0xEFB3 0x8925 # 0 +0xEFB4 0x8FB1 # 0 +0xEFB5 0x4FD1 # 0 +0xEFB6 0x50AD # 0 +0xEFB7 0x5197 # 0 +0xEFB8 0x52C7 # 0 +0xEFB9 0x57C7 # 0 +0xEFBA 0x5889 # 0 +0xEFBB 0x5BB9 # 0 +0xEFBC 0x5EB8 # 0 +0xEFBD 0x6142 # 0 +0xEFBE 0x6995 # 0 +0xEFBF 0x6D8C # 0 +0xEFC0 0x6E67 # 0 +0xEFC1 0x6EB6 # 0 +0xEFC2 0x7194 # 0 +0xEFC3 0x7462 # 0 +0xEFC4 0x7528 # 0 +0xEFC5 0x752C # 0 +0xEFC6 0x8073 # 0 +0xEFC7 0x8338 # 0 +0xEFC8 0x84C9 # 0 +0xEFC9 0x8E0A # 0 +0xEFCA 0x9394 # 0 +0xEFCB 0x93DE # 0 +0xEFCC 0xF9C4 # 0 +0xEFCD 0x4E8E # 0 +0xEFCE 0x4F51 # 0 +0xEFCF 0x5076 # 0 +0xEFD0 0x512A # 0 +0xEFD1 0x53C8 # 0 +0xEFD2 0x53CB # 0 +0xEFD3 0x53F3 # 0 +0xEFD4 0x5B87 # 0 +0xEFD5 0x5BD3 # 0 +0xEFD6 0x5C24 # 0 +0xEFD7 0x611A # 0 +0xEFD8 0x6182 # 0 +0xEFD9 0x65F4 # 0 +0xEFDA 0x725B # 0 +0xEFDB 0x7397 # 0 +0xEFDC 0x7440 # 0 +0xEFDD 0x76C2 # 0 +0xEFDE 0x7950 # 0 +0xEFDF 0x7991 # 0 +0xEFE0 0x79B9 # 0 +0xEFE1 0x7D06 # 0 +0xEFE2 0x7FBD # 0 +0xEFE3 0x828B # 0 +0xEFE4 0x85D5 # 0 +0xEFE5 0x865E # 0 +0xEFE6 0x8FC2 # 0 +0xEFE7 0x9047 # 0 +0xEFE8 0x90F5 # 0 +0xEFE9 0x91EA # 0 +0xEFEA 0x9685 # 0 +0xEFEB 0x96E8 # 0 +0xEFEC 0x96E9 # 0 +0xEFED 0x52D6 # 0 +0xEFEE 0x5F67 # 0 +0xEFEF 0x65ED # 0 +0xEFF0 0x6631 # 0 +0xEFF1 0x682F # 0 +0xEFF2 0x715C # 0 +0xEFF3 0x7A36 # 0 +0xEFF4 0x90C1 # 0 +0xEFF5 0x980A # 0 +0xEFF6 0x4E91 # 0 +0xEFF7 0xF9C5 # 0 +0xEFF8 0x6A52 # 0 +0xEFF9 0x6B9E # 0 +0xEFFA 0x6F90 # 0 +0xEFFB 0x7189 # 0 +0xEFFC 0x8018 # 0 +0xEFFD 0x82B8 # 0 +0xEFFE 0x8553 # 0 +0xF031 0x904B # 0 +0xF032 0x9695 # 0 +0xF033 0x96F2 # 0 +0xF034 0x97FB # 0 +0xF035 0x851A # 0 +0xF036 0x9B31 # 0 +0xF037 0x4E90 # 0 +0xF038 0x718A # 0 +0xF039 0x96C4 # 0 +0xF03A 0x5143 # 0 +0xF03B 0x539F # 0 +0xF03C 0x54E1 # 0 +0xF03D 0x5713 # 0 +0xF03E 0x5712 # 0 +0xF03F 0x57A3 # 0 +0xF040 0x5A9B # 0 +0xF041 0x5AC4 # 0 +0xF042 0x5BC3 # 0 +0xF043 0x6028 # 0 +0xF044 0x613F # 0 +0xF045 0x63F4 # 0 +0xF046 0x6C85 # 0 +0xF047 0x6D39 # 0 +0xF048 0x6E72 # 0 +0xF049 0x6E90 # 0 +0xF04A 0x7230 # 0 +0xF04B 0x733F # 0 +0xF04C 0x7457 # 0 +0xF04D 0x82D1 # 0 +0xF04E 0x8881 # 0 +0xF04F 0x8F45 # 0 +0xF050 0x9060 # 0 +0xF051 0xF9C6 # 0 +0xF052 0x9662 # 0 +0xF053 0x9858 # 0 +0xF054 0x9D1B # 0 +0xF055 0x6708 # 0 +0xF056 0x8D8A # 0 +0xF057 0x925E # 0 +0xF058 0x4F4D # 0 +0xF059 0x5049 # 0 +0xF05A 0x50DE # 0 +0xF05B 0x5371 # 0 +0xF05C 0x570D # 0 +0xF05D 0x59D4 # 0 +0xF05E 0x5A01 # 0 +0xF05F 0x5C09 # 0 +0xF060 0x6170 # 0 +0xF061 0x6690 # 0 +0xF062 0x6E2D # 0 +0xF063 0x7232 # 0 +0xF064 0x744B # 0 +0xF065 0x7DEF # 0 +0xF066 0x80C3 # 0 +0xF067 0x840E # 0 +0xF068 0x8466 # 0 +0xF069 0x853F # 0 +0xF06A 0x875F # 0 +0xF06B 0x885B # 0 +0xF06C 0x8918 # 0 +0xF06D 0x8B02 # 0 +0xF06E 0x9055 # 0 +0xF06F 0x97CB # 0 +0xF070 0x9B4F # 0 +0xF071 0x4E73 # 0 +0xF072 0x4F91 # 0 +0xF073 0x5112 # 0 +0xF074 0x516A # 0 +0xF075 0xF9C7 # 0 +0xF076 0x552F # 0 +0xF077 0x55A9 # 0 +0xF078 0x5B7A # 0 +0xF079 0x5BA5 # 0 +0xF07A 0x5E7C # 0 +0xF07B 0x5E7D # 0 +0xF07C 0x5EBE # 0 +0xF07D 0x60A0 # 0 +0xF07E 0x60DF # 0 +0xF091 0x6108 # 0 +0xF092 0x6109 # 0 +0xF093 0x63C4 # 0 +0xF094 0x6538 # 0 +0xF095 0x6709 # 0 +0xF096 0xF9C8 # 0 +0xF097 0x67D4 # 0 +0xF098 0x67DA # 0 +0xF099 0xF9C9 # 0 +0xF09A 0x6961 # 0 +0xF09B 0x6962 # 0 +0xF09C 0x6CB9 # 0 +0xF09D 0x6D27 # 0 +0xF09E 0xF9CA # 0 +0xF09F 0x6E38 # 0 +0xF0A0 0xF9CB # 0 +0xF0A1 0x6FE1 # 0 +0xF0A2 0x7336 # 0 +0xF0A3 0x7337 # 0 +0xF0A4 0xF9CC # 0 +0xF0A5 0x745C # 0 +0xF0A6 0x7531 # 0 +0xF0A7 0xF9CD # 0 +0xF0A8 0x7652 # 0 +0xF0A9 0xF9CE # 0 +0xF0AA 0xF9CF # 0 +0xF0AB 0x7DAD # 0 +0xF0AC 0x81FE # 0 +0xF0AD 0x8438 # 0 +0xF0AE 0x88D5 # 0 +0xF0AF 0x8A98 # 0 +0xF0B0 0x8ADB # 0 +0xF0B1 0x8AED # 0 +0xF0B2 0x8E30 # 0 +0xF0B3 0x8E42 # 0 +0xF0B4 0x904A # 0 +0xF0B5 0x903E # 0 +0xF0B6 0x907A # 0 +0xF0B7 0x9149 # 0 +0xF0B8 0x91C9 # 0 +0xF0B9 0x936E # 0 +0xF0BA 0xF9D0 # 0 +0xF0BB 0xF9D1 # 0 +0xF0BC 0x5809 # 0 +0xF0BD 0xF9D2 # 0 +0xF0BE 0x6BD3 # 0 +0xF0BF 0x8089 # 0 +0xF0C0 0x80B2 # 0 +0xF0C1 0xF9D3 # 0 +0xF0C2 0xF9D4 # 0 +0xF0C3 0x5141 # 0 +0xF0C4 0x596B # 0 +0xF0C5 0x5C39 # 0 +0xF0C6 0xF9D5 # 0 +0xF0C7 0xF9D6 # 0 +0xF0C8 0x6F64 # 0 +0xF0C9 0x73A7 # 0 +0xF0CA 0x80E4 # 0 +0xF0CB 0x8D07 # 0 +0xF0CC 0xF9D7 # 0 +0xF0CD 0x9217 # 0 +0xF0CE 0x958F # 0 +0xF0CF 0xF9D8 # 0 +0xF0D0 0xF9D9 # 0 +0xF0D1 0xF9DA # 0 +0xF0D2 0xF9DB # 0 +0xF0D3 0x807F # 0 +0xF0D4 0x620E # 0 +0xF0D5 0x701C # 0 +0xF0D6 0x7D68 # 0 +0xF0D7 0x878D # 0 +0xF0D8 0xF9DC # 0 +0xF0D9 0x57A0 # 0 +0xF0DA 0x6069 # 0 +0xF0DB 0x6147 # 0 +0xF0DC 0x6BB7 # 0 +0xF0DD 0x8ABE # 0 +0xF0DE 0x9280 # 0 +0xF0DF 0x96B1 # 0 +0xF0E0 0x4E59 # 0 +0xF0E1 0x541F # 0 +0xF0E2 0x6DEB # 0 +0xF0E3 0x852D # 0 +0xF0E4 0x9670 # 0 +0xF0E5 0x97F3 # 0 +0xF0E6 0x98EE # 0 +0xF0E7 0x63D6 # 0 +0xF0E8 0x6CE3 # 0 +0xF0E9 0x9091 # 0 +0xF0EA 0x51DD # 0 +0xF0EB 0x61C9 # 0 +0xF0EC 0x81BA # 0 +0xF0ED 0x9DF9 # 0 +0xF0EE 0x4F9D # 0 +0xF0EF 0x501A # 0 +0xF0F0 0x5100 # 0 +0xF0F1 0x5B9C # 0 +0xF0F2 0x610F # 0 +0xF0F3 0x61FF # 0 +0xF0F4 0x64EC # 0 +0xF0F5 0x6905 # 0 +0xF0F6 0x6BC5 # 0 +0xF0F7 0x7591 # 0 +0xF0F8 0x77E3 # 0 +0xF0F9 0x7FA9 # 0 +0xF0FA 0x8264 # 0 +0xF0FB 0x858F # 0 +0xF0FC 0x87FB # 0 +0xF0FD 0x8863 # 0 +0xF0FE 0x8ABC # 0 +0xF131 0x8B70 # 0 +0xF132 0x91AB # 0 +0xF133 0x4E8C # 0 +0xF134 0x4EE5 # 0 +0xF135 0x4F0A # 0 +0xF136 0xF9DD # 0 +0xF137 0xF9DE # 0 +0xF138 0x5937 # 0 +0xF139 0x59E8 # 0 +0xF13A 0xF9DF # 0 +0xF13B 0x5DF2 # 0 +0xF13C 0x5F1B # 0 +0xF13D 0x5F5B # 0 +0xF13E 0x6021 # 0 +0xF13F 0xF9E0 # 0 +0xF140 0xF9E1 # 0 +0xF141 0xF9E2 # 0 +0xF142 0xF9E3 # 0 +0xF143 0x723E # 0 +0xF144 0x73E5 # 0 +0xF145 0xF9E4 # 0 +0xF146 0x7570 # 0 +0xF147 0x75CD # 0 +0xF148 0xF9E5 # 0 +0xF149 0x79FB # 0 +0xF14A 0xF9E6 # 0 +0xF14B 0x800C # 0 +0xF14C 0x8033 # 0 +0xF14D 0x8084 # 0 +0xF14E 0x82E1 # 0 +0xF14F 0x8351 # 0 +0xF150 0xF9E7 # 0 +0xF151 0xF9E8 # 0 +0xF152 0x8CBD # 0 +0xF153 0x8CB3 # 0 +0xF154 0x9087 # 0 +0xF155 0xF9E9 # 0 +0xF156 0xF9EA # 0 +0xF157 0x98F4 # 0 +0xF158 0x990C # 0 +0xF159 0xF9EB # 0 +0xF15A 0xF9EC # 0 +0xF15B 0x7037 # 0 +0xF15C 0x76CA # 0 +0xF15D 0x7FCA # 0 +0xF15E 0x7FCC # 0 +0xF15F 0x7FFC # 0 +0xF160 0x8B1A # 0 +0xF161 0x4EBA # 0 +0xF162 0x4EC1 # 0 +0xF163 0x5203 # 0 +0xF164 0x5370 # 0 +0xF165 0xF9ED # 0 +0xF166 0x54BD # 0 +0xF167 0x56E0 # 0 +0xF168 0x59FB # 0 +0xF169 0x5BC5 # 0 +0xF16A 0x5F15 # 0 +0xF16B 0x5FCD # 0 +0xF16C 0x6E6E # 0 +0xF16D 0xF9EE # 0 +0xF16E 0xF9EF # 0 +0xF16F 0x7D6A # 0 +0xF170 0x8335 # 0 +0xF171 0xF9F0 # 0 +0xF172 0x8693 # 0 +0xF173 0x8A8D # 0 +0xF174 0xF9F1 # 0 +0xF175 0x976D # 0 +0xF176 0x9777 # 0 +0xF177 0xF9F2 # 0 +0xF178 0xF9F3 # 0 +0xF179 0x4E00 # 0 +0xF17A 0x4F5A # 0 +0xF17B 0x4F7E # 0 +0xF17C 0x58F9 # 0 +0xF17D 0x65E5 # 0 +0xF17E 0x6EA2 # 0 +0xF191 0x9038 # 0 +0xF192 0x93B0 # 0 +0xF193 0x99B9 # 0 +0xF194 0x4EFB # 0 +0xF195 0x58EC # 0 +0xF196 0x598A # 0 +0xF197 0x59D9 # 0 +0xF198 0x6041 # 0 +0xF199 0xF9F4 # 0 +0xF19A 0xF9F5 # 0 +0xF19B 0x7A14 # 0 +0xF19C 0xF9F6 # 0 +0xF19D 0x834F # 0 +0xF19E 0x8CC3 # 0 +0xF19F 0x5165 # 0 +0xF1A0 0x5344 # 0 +0xF1A1 0xF9F7 # 0 +0xF1A2 0xF9F8 # 0 +0xF1A3 0xF9F9 # 0 +0xF1A4 0x4ECD # 0 +0xF1A5 0x5269 # 0 +0xF1A6 0x5B55 # 0 +0xF1A7 0x82BF # 0 +0xF1A8 0x4ED4 # 0 +0xF1A9 0x523A # 0 +0xF1AA 0x54A8 # 0 +0xF1AB 0x59C9 # 0 +0xF1AC 0x59FF # 0 +0xF1AD 0x5B50 # 0 +0xF1AE 0x5B57 # 0 +0xF1AF 0x5B5C # 0 +0xF1B0 0x6063 # 0 +0xF1B1 0x6148 # 0 +0xF1B2 0x6ECB # 0 +0xF1B3 0x7099 # 0 +0xF1B4 0x716E # 0 +0xF1B5 0x7386 # 0 +0xF1B6 0x74F7 # 0 +0xF1B7 0x75B5 # 0 +0xF1B8 0x78C1 # 0 +0xF1B9 0x7D2B # 0 +0xF1BA 0x8005 # 0 +0xF1BB 0x81EA # 0 +0xF1BC 0x8328 # 0 +0xF1BD 0x8517 # 0 +0xF1BE 0x85C9 # 0 +0xF1BF 0x8AEE # 0 +0xF1C0 0x8CC7 # 0 +0xF1C1 0x96CC # 0 +0xF1C2 0x4F5C # 0 +0xF1C3 0x52FA # 0 +0xF1C4 0x56BC # 0 +0xF1C5 0x65AB # 0 +0xF1C6 0x6628 # 0 +0xF1C7 0x707C # 0 +0xF1C8 0x70B8 # 0 +0xF1C9 0x7235 # 0 +0xF1CA 0x7DBD # 0 +0xF1CB 0x828D # 0 +0xF1CC 0x914C # 0 +0xF1CD 0x96C0 # 0 +0xF1CE 0x9D72 # 0 +0xF1CF 0x5B71 # 0 +0xF1D0 0x68E7 # 0 +0xF1D1 0x6B98 # 0 +0xF1D2 0x6F7A # 0 +0xF1D3 0x76DE # 0 +0xF1D4 0x5C91 # 0 +0xF1D5 0x66AB # 0 +0xF1D6 0x6F5B # 0 +0xF1D7 0x7BB4 # 0 +0xF1D8 0x7C2A # 0 +0xF1D9 0x8836 # 0 +0xF1DA 0x96DC # 0 +0xF1DB 0x4E08 # 0 +0xF1DC 0x4ED7 # 0 +0xF1DD 0x5320 # 0 +0xF1DE 0x5834 # 0 +0xF1DF 0x58BB # 0 +0xF1E0 0x58EF # 0 +0xF1E1 0x596C # 0 +0xF1E2 0x5C07 # 0 +0xF1E3 0x5E33 # 0 +0xF1E4 0x5E84 # 0 +0xF1E5 0x5F35 # 0 +0xF1E6 0x638C # 0 +0xF1E7 0x66B2 # 0 +0xF1E8 0x6756 # 0 +0xF1E9 0x6A1F # 0 +0xF1EA 0x6AA3 # 0 +0xF1EB 0x6B0C # 0 +0xF1EC 0x6F3F # 0 +0xF1ED 0x7246 # 0 +0xF1EE 0xF9FA # 0 +0xF1EF 0x7350 # 0 +0xF1F0 0x748B # 0 +0xF1F1 0x7AE0 # 0 +0xF1F2 0x7CA7 # 0 +0xF1F3 0x8178 # 0 +0xF1F4 0x81DF # 0 +0xF1F5 0x81E7 # 0 +0xF1F6 0x838A # 0 +0xF1F7 0x846C # 0 +0xF1F8 0x8523 # 0 +0xF1F9 0x8594 # 0 +0xF1FA 0x85CF # 0 +0xF1FB 0x88DD # 0 +0xF1FC 0x8D13 # 0 +0xF1FD 0x91AC # 0 +0xF1FE 0x9577 # 0 +0xF231 0x969C # 0 +0xF232 0x518D # 0 +0xF233 0x54C9 # 0 +0xF234 0x5728 # 0 +0xF235 0x5BB0 # 0 +0xF236 0x624D # 0 +0xF237 0x6750 # 0 +0xF238 0x683D # 0 +0xF239 0x6893 # 0 +0xF23A 0x6E3D # 0 +0xF23B 0x6ED3 # 0 +0xF23C 0x707D # 0 +0xF23D 0x7E21 # 0 +0xF23E 0x88C1 # 0 +0xF23F 0x8CA1 # 0 +0xF240 0x8F09 # 0 +0xF241 0x9F4B # 0 +0xF242 0x9F4E # 0 +0xF243 0x722D # 0 +0xF244 0x7B8F # 0 +0xF245 0x8ACD # 0 +0xF246 0x931A # 0 +0xF247 0x4F47 # 0 +0xF248 0x4F4E # 0 +0xF249 0x5132 # 0 +0xF24A 0x5480 # 0 +0xF24B 0x59D0 # 0 +0xF24C 0x5E95 # 0 +0xF24D 0x62B5 # 0 +0xF24E 0x6775 # 0 +0xF24F 0x696E # 0 +0xF250 0x6A17 # 0 +0xF251 0x6CAE # 0 +0xF252 0x6E1A # 0 +0xF253 0x72D9 # 0 +0xF254 0x732A # 0 +0xF255 0x75BD # 0 +0xF256 0x7BB8 # 0 +0xF257 0x7D35 # 0 +0xF258 0x82E7 # 0 +0xF259 0x83F9 # 0 +0xF25A 0x8457 # 0 +0xF25B 0x85F7 # 0 +0xF25C 0x8A5B # 0 +0xF25D 0x8CAF # 0 +0xF25E 0x8E87 # 0 +0xF25F 0x9019 # 0 +0xF260 0x90B8 # 0 +0xF261 0x96CE # 0 +0xF262 0x9F5F # 0 +0xF263 0x52E3 # 0 +0xF264 0x540A # 0 +0xF265 0x5AE1 # 0 +0xF266 0x5BC2 # 0 +0xF267 0x6458 # 0 +0xF268 0x6575 # 0 +0xF269 0x6EF4 # 0 +0xF26A 0x72C4 # 0 +0xF26B 0xF9FB # 0 +0xF26C 0x7684 # 0 +0xF26D 0x7A4D # 0 +0xF26E 0x7B1B # 0 +0xF26F 0x7C4D # 0 +0xF270 0x7E3E # 0 +0xF271 0x7FDF # 0 +0xF272 0x837B # 0 +0xF273 0x8B2B # 0 +0xF274 0x8CCA # 0 +0xF275 0x8D64 # 0 +0xF276 0x8DE1 # 0 +0xF277 0x8E5F # 0 +0xF278 0x8FEA # 0 +0xF279 0x8FF9 # 0 +0xF27A 0x9069 # 0 +0xF27B 0x93D1 # 0 +0xF27C 0x4F43 # 0 +0xF27D 0x4F7A # 0 +0xF27E 0x50B3 # 0 +0xF291 0x5168 # 0 +0xF292 0x5178 # 0 +0xF293 0x524D # 0 +0xF294 0x526A # 0 +0xF295 0x5861 # 0 +0xF296 0x587C # 0 +0xF297 0x5960 # 0 +0xF298 0x5C08 # 0 +0xF299 0x5C55 # 0 +0xF29A 0x5EDB # 0 +0xF29B 0x609B # 0 +0xF29C 0x6230 # 0 +0xF29D 0x6813 # 0 +0xF29E 0x6BBF # 0 +0xF29F 0x6C08 # 0 +0xF2A0 0x6FB1 # 0 +0xF2A1 0x714E # 0 +0xF2A2 0x7420 # 0 +0xF2A3 0x7530 # 0 +0xF2A4 0x7538 # 0 +0xF2A5 0x7551 # 0 +0xF2A6 0x7672 # 0 +0xF2A7 0x7B4C # 0 +0xF2A8 0x7B8B # 0 +0xF2A9 0x7BAD # 0 +0xF2AA 0x7BC6 # 0 +0xF2AB 0x7E8F # 0 +0xF2AC 0x8A6E # 0 +0xF2AD 0x8F3E # 0 +0xF2AE 0x8F49 # 0 +0xF2AF 0x923F # 0 +0xF2B0 0x9293 # 0 +0xF2B1 0x9322 # 0 +0xF2B2 0x942B # 0 +0xF2B3 0x96FB # 0 +0xF2B4 0x985A # 0 +0xF2B5 0x986B # 0 +0xF2B6 0x991E # 0 +0xF2B7 0x5207 # 0 +0xF2B8 0x622A # 0 +0xF2B9 0x6298 # 0 +0xF2BA 0x6D59 # 0 +0xF2BB 0x7664 # 0 +0xF2BC 0x7ACA # 0 +0xF2BD 0x7BC0 # 0 +0xF2BE 0x7D76 # 0 +0xF2BF 0x5360 # 0 +0xF2C0 0x5CBE # 0 +0xF2C1 0x5E97 # 0 +0xF2C2 0x6F38 # 0 +0xF2C3 0x70B9 # 0 +0xF2C4 0x7C98 # 0 +0xF2C5 0x9711 # 0 +0xF2C6 0x9B8E # 0 +0xF2C7 0x9EDE # 0 +0xF2C8 0x63A5 # 0 +0xF2C9 0x647A # 0 +0xF2CA 0x8776 # 0 +0xF2CB 0x4E01 # 0 +0xF2CC 0x4E95 # 0 +0xF2CD 0x4EAD # 0 +0xF2CE 0x505C # 0 +0xF2CF 0x5075 # 0 +0xF2D0 0x5448 # 0 +0xF2D1 0x59C3 # 0 +0xF2D2 0x5B9A # 0 +0xF2D3 0x5E40 # 0 +0xF2D4 0x5EAD # 0 +0xF2D5 0x5EF7 # 0 +0xF2D6 0x5F81 # 0 +0xF2D7 0x60C5 # 0 +0xF2D8 0x633A # 0 +0xF2D9 0x653F # 0 +0xF2DA 0x6574 # 0 +0xF2DB 0x65CC # 0 +0xF2DC 0x6676 # 0 +0xF2DD 0x6678 # 0 +0xF2DE 0x67FE # 0 +0xF2DF 0x6968 # 0 +0xF2E0 0x6A89 # 0 +0xF2E1 0x6B63 # 0 +0xF2E2 0x6C40 # 0 +0xF2E3 0x6DC0 # 0 +0xF2E4 0x6DE8 # 0 +0xF2E5 0x6E1F # 0 +0xF2E6 0x6E5E # 0 +0xF2E7 0x701E # 0 +0xF2E8 0x70A1 # 0 +0xF2E9 0x738E # 0 +0xF2EA 0x73FD # 0 +0xF2EB 0x753A # 0 +0xF2EC 0x775B # 0 +0xF2ED 0x7887 # 0 +0xF2EE 0x798E # 0 +0xF2EF 0x7A0B # 0 +0xF2F0 0x7A7D # 0 +0xF2F1 0x7CBE # 0 +0xF2F2 0x7D8E # 0 +0xF2F3 0x8247 # 0 +0xF2F4 0x8A02 # 0 +0xF2F5 0x8AEA # 0 +0xF2F6 0x8C9E # 0 +0xF2F7 0x912D # 0 +0xF2F8 0x914A # 0 +0xF2F9 0x91D8 # 0 +0xF2FA 0x9266 # 0 +0xF2FB 0x92CC # 0 +0xF2FC 0x9320 # 0 +0xF2FD 0x9706 # 0 +0xF2FE 0x9756 # 0 +0xF331 0x975C # 0 +0xF332 0x9802 # 0 +0xF333 0x9F0E # 0 +0xF334 0x5236 # 0 +0xF335 0x5291 # 0 +0xF336 0x557C # 0 +0xF337 0x5824 # 0 +0xF338 0x5E1D # 0 +0xF339 0x5F1F # 0 +0xF33A 0x608C # 0 +0xF33B 0x63D0 # 0 +0xF33C 0x68AF # 0 +0xF33D 0x6FDF # 0 +0xF33E 0x796D # 0 +0xF33F 0x7B2C # 0 +0xF340 0x81CD # 0 +0xF341 0x85BA # 0 +0xF342 0x88FD # 0 +0xF343 0x8AF8 # 0 +0xF344 0x8E44 # 0 +0xF345 0x918D # 0 +0xF346 0x9664 # 0 +0xF347 0x969B # 0 +0xF348 0x973D # 0 +0xF349 0x984C # 0 +0xF34A 0x9F4A # 0 +0xF34B 0x4FCE # 0 +0xF34C 0x5146 # 0 +0xF34D 0x51CB # 0 +0xF34E 0x52A9 # 0 +0xF34F 0x5632 # 0 +0xF350 0x5F14 # 0 +0xF351 0x5F6B # 0 +0xF352 0x63AA # 0 +0xF353 0x64CD # 0 +0xF354 0x65E9 # 0 +0xF355 0x6641 # 0 +0xF356 0x66FA # 0 +0xF357 0x66F9 # 0 +0xF358 0x671D # 0 +0xF359 0x689D # 0 +0xF35A 0x68D7 # 0 +0xF35B 0x69FD # 0 +0xF35C 0x6F15 # 0 +0xF35D 0x6F6E # 0 +0xF35E 0x7167 # 0 +0xF35F 0x71E5 # 0 +0xF360 0x722A # 0 +0xF361 0x74AA # 0 +0xF362 0x773A # 0 +0xF363 0x7956 # 0 +0xF364 0x795A # 0 +0xF365 0x79DF # 0 +0xF366 0x7A20 # 0 +0xF367 0x7A95 # 0 +0xF368 0x7C97 # 0 +0xF369 0x7CDF # 0 +0xF36A 0x7D44 # 0 +0xF36B 0x7E70 # 0 +0xF36C 0x8087 # 0 +0xF36D 0x85FB # 0 +0xF36E 0x86A4 # 0 +0xF36F 0x8A54 # 0 +0xF370 0x8ABF # 0 +0xF371 0x8D99 # 0 +0xF372 0x8E81 # 0 +0xF373 0x9020 # 0 +0xF374 0x906D # 0 +0xF375 0x91E3 # 0 +0xF376 0x963B # 0 +0xF377 0x96D5 # 0 +0xF378 0x9CE5 # 0 +0xF379 0x65CF # 0 +0xF37A 0x7C07 # 0 +0xF37B 0x8DB3 # 0 +0xF37C 0x93C3 # 0 +0xF37D 0x5B58 # 0 +0xF37E 0x5C0A # 0 +0xF391 0x5352 # 0 +0xF392 0x62D9 # 0 +0xF393 0x731D # 0 +0xF394 0x5027 # 0 +0xF395 0x5B97 # 0 +0xF396 0x5F9E # 0 +0xF397 0x60B0 # 0 +0xF398 0x616B # 0 +0xF399 0x68D5 # 0 +0xF39A 0x6DD9 # 0 +0xF39B 0x742E # 0 +0xF39C 0x7A2E # 0 +0xF39D 0x7D42 # 0 +0xF39E 0x7D9C # 0 +0xF39F 0x7E31 # 0 +0xF3A0 0x816B # 0 +0xF3A1 0x8E2A # 0 +0xF3A2 0x8E35 # 0 +0xF3A3 0x937E # 0 +0xF3A4 0x9418 # 0 +0xF3A5 0x4F50 # 0 +0xF3A6 0x5750 # 0 +0xF3A7 0x5DE6 # 0 +0xF3A8 0x5EA7 # 0 +0xF3A9 0x632B # 0 +0xF3AA 0x7F6A # 0 +0xF3AB 0x4E3B # 0 +0xF3AC 0x4F4F # 0 +0xF3AD 0x4F8F # 0 +0xF3AE 0x505A # 0 +0xF3AF 0x59DD # 0 +0xF3B0 0x80C4 # 0 +0xF3B1 0x546A # 0 +0xF3B2 0x5468 # 0 +0xF3B3 0x55FE # 0 +0xF3B4 0x594F # 0 +0xF3B5 0x5B99 # 0 +0xF3B6 0x5DDE # 0 +0xF3B7 0x5EDA # 0 +0xF3B8 0x665D # 0 +0xF3B9 0x6731 # 0 +0xF3BA 0x67F1 # 0 +0xF3BB 0x682A # 0 +0xF3BC 0x6CE8 # 0 +0xF3BD 0x6D32 # 0 +0xF3BE 0x6E4A # 0 +0xF3BF 0x6F8D # 0 +0xF3C0 0x70B7 # 0 +0xF3C1 0x73E0 # 0 +0xF3C2 0x7587 # 0 +0xF3C3 0x7C4C # 0 +0xF3C4 0x7D02 # 0 +0xF3C5 0x7D2C # 0 +0xF3C6 0x7DA2 # 0 +0xF3C7 0x821F # 0 +0xF3C8 0x86DB # 0 +0xF3C9 0x8A3B # 0 +0xF3CA 0x8A85 # 0 +0xF3CB 0x8D70 # 0 +0xF3CC 0x8E8A # 0 +0xF3CD 0x8F33 # 0 +0xF3CE 0x9031 # 0 +0xF3CF 0x914E # 0 +0xF3D0 0x9152 # 0 +0xF3D1 0x9444 # 0 +0xF3D2 0x99D0 # 0 +0xF3D3 0x7AF9 # 0 +0xF3D4 0x7CA5 # 0 +0xF3D5 0x4FCA # 0 +0xF3D6 0x5101 # 0 +0xF3D7 0x51C6 # 0 +0xF3D8 0x57C8 # 0 +0xF3D9 0x5BEF # 0 +0xF3DA 0x5CFB # 0 +0xF3DB 0x6659 # 0 +0xF3DC 0x6A3D # 0 +0xF3DD 0x6D5A # 0 +0xF3DE 0x6E96 # 0 +0xF3DF 0x6FEC # 0 +0xF3E0 0x710C # 0 +0xF3E1 0x756F # 0 +0xF3E2 0x7AE3 # 0 +0xF3E3 0x8822 # 0 +0xF3E4 0x9021 # 0 +0xF3E5 0x9075 # 0 +0xF3E6 0x96CB # 0 +0xF3E7 0x99FF # 0 +0xF3E8 0x8301 # 0 +0xF3E9 0x4E2D # 0 +0xF3EA 0x4EF2 # 0 +0xF3EB 0x8846 # 0 +0xF3EC 0x91CD # 0 +0xF3ED 0x537D # 0 +0xF3EE 0x6ADB # 0 +0xF3EF 0x696B # 0 +0xF3F0 0x6C41 # 0 +0xF3F1 0x847A # 0 +0xF3F2 0x589E # 0 +0xF3F3 0x618E # 0 +0xF3F4 0x66FE # 0 +0xF3F5 0x62EF # 0 +0xF3F6 0x70DD # 0 +0xF3F7 0x7511 # 0 +0xF3F8 0x75C7 # 0 +0xF3F9 0x7E52 # 0 +0xF3FA 0x84B8 # 0 +0xF3FB 0x8B49 # 0 +0xF3FC 0x8D08 # 0 +0xF3FD 0x4E4B # 0 +0xF3FE 0x53EA # 0 +0xF431 0x54AB # 0 +0xF432 0x5730 # 0 +0xF433 0x5740 # 0 +0xF434 0x5FD7 # 0 +0xF435 0x6301 # 0 +0xF436 0x6307 # 0 +0xF437 0x646F # 0 +0xF438 0x652F # 0 +0xF439 0x65E8 # 0 +0xF43A 0x667A # 0 +0xF43B 0x679D # 0 +0xF43C 0x67B3 # 0 +0xF43D 0x6B62 # 0 +0xF43E 0x6C60 # 0 +0xF43F 0x6C9A # 0 +0xF440 0x6F2C # 0 +0xF441 0x77E5 # 0 +0xF442 0x7825 # 0 +0xF443 0x7949 # 0 +0xF444 0x7957 # 0 +0xF445 0x7D19 # 0 +0xF446 0x80A2 # 0 +0xF447 0x8102 # 0 +0xF448 0x81F3 # 0 +0xF449 0x829D # 0 +0xF44A 0x82B7 # 0 +0xF44B 0x8718 # 0 +0xF44C 0x8A8C # 0 +0xF44D 0xF9FC # 0 +0xF44E 0x8D04 # 0 +0xF44F 0x8DBE # 0 +0xF450 0x9072 # 0 +0xF451 0x76F4 # 0 +0xF452 0x7A19 # 0 +0xF453 0x7A37 # 0 +0xF454 0x7E54 # 0 +0xF455 0x8077 # 0 +0xF456 0x5507 # 0 +0xF457 0x55D4 # 0 +0xF458 0x5875 # 0 +0xF459 0x632F # 0 +0xF45A 0x6422 # 0 +0xF45B 0x6649 # 0 +0xF45C 0x664B # 0 +0xF45D 0x686D # 0 +0xF45E 0x699B # 0 +0xF45F 0x6B84 # 0 +0xF460 0x6D25 # 0 +0xF461 0x6EB1 # 0 +0xF462 0x73CD # 0 +0xF463 0x7468 # 0 +0xF464 0x74A1 # 0 +0xF465 0x755B # 0 +0xF466 0x75B9 # 0 +0xF467 0x76E1 # 0 +0xF468 0x771E # 0 +0xF469 0x778B # 0 +0xF46A 0x79E6 # 0 +0xF46B 0x7E09 # 0 +0xF46C 0x7E1D # 0 +0xF46D 0x81FB # 0 +0xF46E 0x852F # 0 +0xF46F 0x8897 # 0 +0xF470 0x8A3A # 0 +0xF471 0x8CD1 # 0 +0xF472 0x8EEB # 0 +0xF473 0x8FB0 # 0 +0xF474 0x9032 # 0 +0xF475 0x93AD # 0 +0xF476 0x9663 # 0 +0xF477 0x9673 # 0 +0xF478 0x9707 # 0 +0xF479 0x4F84 # 0 +0xF47A 0x53F1 # 0 +0xF47B 0x59EA # 0 +0xF47C 0x5AC9 # 0 +0xF47D 0x5E19 # 0 +0xF47E 0x684E # 0 +0xF491 0x74C6 # 0 +0xF492 0x75BE # 0 +0xF493 0x79E9 # 0 +0xF494 0x7A92 # 0 +0xF495 0x81A3 # 0 +0xF496 0x86ED # 0 +0xF497 0x8CEA # 0 +0xF498 0x8DCC # 0 +0xF499 0x8FED # 0 +0xF49A 0x659F # 0 +0xF49B 0x6715 # 0 +0xF49C 0xF9FD # 0 +0xF49D 0x57F7 # 0 +0xF49E 0x6F57 # 0 +0xF49F 0x7DDD # 0 +0xF4A0 0x8F2F # 0 +0xF4A1 0x93F6 # 0 +0xF4A2 0x96C6 # 0 +0xF4A3 0x5FB5 # 0 +0xF4A4 0x61F2 # 0 +0xF4A5 0x6F84 # 0 +0xF4A6 0x4E14 # 0 +0xF4A7 0x4F98 # 0 +0xF4A8 0x501F # 0 +0xF4A9 0x53C9 # 0 +0xF4AA 0x55DF # 0 +0xF4AB 0x5D6F # 0 +0xF4AC 0x5DEE # 0 +0xF4AD 0x6B21 # 0 +0xF4AE 0x6B64 # 0 +0xF4AF 0x78CB # 0 +0xF4B0 0x7B9A # 0 +0xF4B1 0xF9FE # 0 +0xF4B2 0x8E49 # 0 +0xF4B3 0x8ECA # 0 +0xF4B4 0x906E # 0 +0xF4B5 0x6349 # 0 +0xF4B6 0x643E # 0 +0xF4B7 0x7740 # 0 +0xF4B8 0x7A84 # 0 +0xF4B9 0x932F # 0 +0xF4BA 0x947F # 0 +0xF4BB 0x9F6A # 0 +0xF4BC 0x64B0 # 0 +0xF4BD 0x6FAF # 0 +0xF4BE 0x71E6 # 0 +0xF4BF 0x74A8 # 0 +0xF4C0 0x74DA # 0 +0xF4C1 0x7AC4 # 0 +0xF4C2 0x7C12 # 0 +0xF4C3 0x7E82 # 0 +0xF4C4 0x7CB2 # 0 +0xF4C5 0x7E98 # 0 +0xF4C6 0x8B9A # 0 +0xF4C7 0x8D0A # 0 +0xF4C8 0x947D # 0 +0xF4C9 0x9910 # 0 +0xF4CA 0x994C # 0 +0xF4CB 0x5239 # 0 +0xF4CC 0x5BDF # 0 +0xF4CD 0x64E6 # 0 +0xF4CE 0x672D # 0 +0xF4CF 0x7D2E # 0 +0xF4D0 0x50ED # 0 +0xF4D1 0x53C3 # 0 +0xF4D2 0x5879 # 0 +0xF4D3 0x6158 # 0 +0xF4D4 0x6159 # 0 +0xF4D5 0x61FA # 0 +0xF4D6 0x65AC # 0 +0xF4D7 0x7AD9 # 0 +0xF4D8 0x8B92 # 0 +0xF4D9 0x8B96 # 0 +0xF4DA 0x5009 # 0 +0xF4DB 0x5021 # 0 +0xF4DC 0x5275 # 0 +0xF4DD 0x5531 # 0 +0xF4DE 0x5A3C # 0 +0xF4DF 0x5EE0 # 0 +0xF4E0 0x5F70 # 0 +0xF4E1 0x6134 # 0 +0xF4E2 0x655E # 0 +0xF4E3 0x660C # 0 +0xF4E4 0x6636 # 0 +0xF4E5 0x66A2 # 0 +0xF4E6 0x69CD # 0 +0xF4E7 0x6EC4 # 0 +0xF4E8 0x6F32 # 0 +0xF4E9 0x7316 # 0 +0xF4EA 0x7621 # 0 +0xF4EB 0x7A93 # 0 +0xF4EC 0x8139 # 0 +0xF4ED 0x8259 # 0 +0xF4EE 0x83D6 # 0 +0xF4EF 0x84BC # 0 +0xF4F0 0x50B5 # 0 +0xF4F1 0x57F0 # 0 +0xF4F2 0x5BC0 # 0 +0xF4F3 0x5BE8 # 0 +0xF4F4 0x5F69 # 0 +0xF4F5 0x63A1 # 0 +0xF4F6 0x7826 # 0 +0xF4F7 0x7DB5 # 0 +0xF4F8 0x83DC # 0 +0xF4F9 0x8521 # 0 +0xF4FA 0x91C7 # 0 +0xF4FB 0x91F5 # 0 +0xF4FC 0x518A # 0 +0xF4FD 0x67F5 # 0 +0xF4FE 0x7B56 # 0 +0xF531 0x8CAC # 0 +0xF532 0x51C4 # 0 +0xF533 0x59BB # 0 +0xF534 0x60BD # 0 +0xF535 0x8655 # 0 +0xF536 0x501C # 0 +0xF537 0xF9FF # 0 +0xF538 0x5254 # 0 +0xF539 0x5C3A # 0 +0xF53A 0x617D # 0 +0xF53B 0x621A # 0 +0xF53C 0x62D3 # 0 +0xF53D 0x64F2 # 0 +0xF53E 0x65A5 # 0 +0xF53F 0x6ECC # 0 +0xF540 0x7620 # 0 +0xF541 0x810A # 0 +0xF542 0x8E60 # 0 +0xF543 0x965F # 0 +0xF544 0x96BB # 0 +0xF545 0x4EDF # 0 +0xF546 0x5343 # 0 +0xF547 0x5598 # 0 +0xF548 0x5929 # 0 +0xF549 0x5DDD # 0 +0xF54A 0x64C5 # 0 +0xF54B 0x6CC9 # 0 +0xF54C 0x6DFA # 0 +0xF54D 0x7394 # 0 +0xF54E 0x7A7F # 0 +0xF54F 0x821B # 0 +0xF550 0x85A6 # 0 +0xF551 0x8CE4 # 0 +0xF552 0x8E10 # 0 +0xF553 0x9077 # 0 +0xF554 0x91E7 # 0 +0xF555 0x95E1 # 0 +0xF556 0x9621 # 0 +0xF557 0x97C6 # 0 +0xF558 0x51F8 # 0 +0xF559 0x54F2 # 0 +0xF55A 0x5586 # 0 +0xF55B 0x5FB9 # 0 +0xF55C 0x64A4 # 0 +0xF55D 0x6F88 # 0 +0xF55E 0x7DB4 # 0 +0xF55F 0x8F1F # 0 +0xF560 0x8F4D # 0 +0xF561 0x9435 # 0 +0xF562 0x50C9 # 0 +0xF563 0x5C16 # 0 +0xF564 0x6CBE # 0 +0xF565 0x6DFB # 0 +0xF566 0x751B # 0 +0xF567 0x77BB # 0 +0xF568 0x7C3D # 0 +0xF569 0x7C64 # 0 +0xF56A 0x8A79 # 0 +0xF56B 0x8AC2 # 0 +0xF56C 0x581E # 0 +0xF56D 0x59BE # 0 +0xF56E 0x5E16 # 0 +0xF56F 0x6377 # 0 +0xF570 0x7252 # 0 +0xF571 0x758A # 0 +0xF572 0x776B # 0 +0xF573 0x8ADC # 0 +0xF574 0x8CBC # 0 +0xF575 0x8F12 # 0 +0xF576 0x5EF3 # 0 +0xF577 0x6674 # 0 +0xF578 0x6DF8 # 0 +0xF579 0x807D # 0 +0xF57A 0x83C1 # 0 +0xF57B 0x8ACB # 0 +0xF57C 0x9751 # 0 +0xF57D 0x9BD6 # 0 +0xF57E 0xFA00 # 0 +0xF591 0x5243 # 0 +0xF592 0x66FF # 0 +0xF593 0x6D95 # 0 +0xF594 0x6EEF # 0 +0xF595 0x7DE0 # 0 +0xF596 0x8AE6 # 0 +0xF597 0x902E # 0 +0xF598 0x905E # 0 +0xF599 0x9AD4 # 0 +0xF59A 0x521D # 0 +0xF59B 0x527F # 0 +0xF59C 0x54E8 # 0 +0xF59D 0x6194 # 0 +0xF59E 0x6284 # 0 +0xF59F 0x62DB # 0 +0xF5A0 0x68A2 # 0 +0xF5A1 0x6912 # 0 +0xF5A2 0x695A # 0 +0xF5A3 0x6A35 # 0 +0xF5A4 0x7092 # 0 +0xF5A5 0x7126 # 0 +0xF5A6 0x785D # 0 +0xF5A7 0x7901 # 0 +0xF5A8 0x790E # 0 +0xF5A9 0x79D2 # 0 +0xF5AA 0x7A0D # 0 +0xF5AB 0x8096 # 0 +0xF5AC 0x8278 # 0 +0xF5AD 0x82D5 # 0 +0xF5AE 0x8349 # 0 +0xF5AF 0x8549 # 0 +0xF5B0 0x8C82 # 0 +0xF5B1 0x8D85 # 0 +0xF5B2 0x9162 # 0 +0xF5B3 0x918B # 0 +0xF5B4 0x91AE # 0 +0xF5B5 0x4FC3 # 0 +0xF5B6 0x56D1 # 0 +0xF5B7 0x71ED # 0 +0xF5B8 0x77D7 # 0 +0xF5B9 0x8700 # 0 +0xF5BA 0x89F8 # 0 +0xF5BB 0x5BF8 # 0 +0xF5BC 0x5FD6 # 0 +0xF5BD 0x6751 # 0 +0xF5BE 0x90A8 # 0 +0xF5BF 0x53E2 # 0 +0xF5C0 0x585A # 0 +0xF5C1 0x5BF5 # 0 +0xF5C2 0x60A4 # 0 +0xF5C3 0x6181 # 0 +0xF5C4 0x6460 # 0 +0xF5C5 0x7E3D # 0 +0xF5C6 0x8070 # 0 +0xF5C7 0x8525 # 0 +0xF5C8 0x9283 # 0 +0xF5C9 0x64AE # 0 +0xF5CA 0x50AC # 0 +0xF5CB 0x5D14 # 0 +0xF5CC 0x6700 # 0 +0xF5CD 0x589C # 0 +0xF5CE 0x62BD # 0 +0xF5CF 0x63A8 # 0 +0xF5D0 0x690E # 0 +0xF5D1 0x6978 # 0 +0xF5D2 0x6A1E # 0 +0xF5D3 0x6E6B # 0 +0xF5D4 0x76BA # 0 +0xF5D5 0x79CB # 0 +0xF5D6 0x82BB # 0 +0xF5D7 0x8429 # 0 +0xF5D8 0x8ACF # 0 +0xF5D9 0x8DA8 # 0 +0xF5DA 0x8FFD # 0 +0xF5DB 0x9112 # 0 +0xF5DC 0x914B # 0 +0xF5DD 0x919C # 0 +0xF5DE 0x9310 # 0 +0xF5DF 0x9318 # 0 +0xF5E0 0x939A # 0 +0xF5E1 0x96DB # 0 +0xF5E2 0x9A36 # 0 +0xF5E3 0x9C0D # 0 +0xF5E4 0x4E11 # 0 +0xF5E5 0x755C # 0 +0xF5E6 0x795D # 0 +0xF5E7 0x7AFA # 0 +0xF5E8 0x7B51 # 0 +0xF5E9 0x7BC9 # 0 +0xF5EA 0x7E2E # 0 +0xF5EB 0x84C4 # 0 +0xF5EC 0x8E59 # 0 +0xF5ED 0x8E74 # 0 +0xF5EE 0x8EF8 # 0 +0xF5EF 0x9010 # 0 +0xF5F0 0x6625 # 0 +0xF5F1 0x693F # 0 +0xF5F2 0x7443 # 0 +0xF5F3 0x51FA # 0 +0xF5F4 0x672E # 0 +0xF5F5 0x9EDC # 0 +0xF5F6 0x5145 # 0 +0xF5F7 0x5FE0 # 0 +0xF5F8 0x6C96 # 0 +0xF5F9 0x87F2 # 0 +0xF5FA 0x885D # 0 +0xF5FB 0x8877 # 0 +0xF5FC 0x60B4 # 0 +0xF5FD 0x81B5 # 0 +0xF5FE 0x8403 # 0 +0xF631 0x8D05 # 0 +0xF632 0x53D6 # 0 +0xF633 0x5439 # 0 +0xF634 0x5634 # 0 +0xF635 0x5A36 # 0 +0xF636 0x5C31 # 0 +0xF637 0x708A # 0 +0xF638 0x7FE0 # 0 +0xF639 0x805A # 0 +0xF63A 0x8106 # 0 +0xF63B 0x81ED # 0 +0xF63C 0x8DA3 # 0 +0xF63D 0x9189 # 0 +0xF63E 0x9A5F # 0 +0xF63F 0x9DF2 # 0 +0xF640 0x5074 # 0 +0xF641 0x4EC4 # 0 +0xF642 0x53A0 # 0 +0xF643 0x60FB # 0 +0xF644 0x6E2C # 0 +0xF645 0x5C64 # 0 +0xF646 0x4F88 # 0 +0xF647 0x5024 # 0 +0xF648 0x55E4 # 0 +0xF649 0x5CD9 # 0 +0xF64A 0x5E5F # 0 +0xF64B 0x6065 # 0 +0xF64C 0x6894 # 0 +0xF64D 0x6CBB # 0 +0xF64E 0x6DC4 # 0 +0xF64F 0x71BE # 0 +0xF650 0x75D4 # 0 +0xF651 0x75F4 # 0 +0xF652 0x7661 # 0 +0xF653 0x7A1A # 0 +0xF654 0x7A49 # 0 +0xF655 0x7DC7 # 0 +0xF656 0x7DFB # 0 +0xF657 0x7F6E # 0 +0xF658 0x81F4 # 0 +0xF659 0x86A9 # 0 +0xF65A 0x8F1C # 0 +0xF65B 0x96C9 # 0 +0xF65C 0x99B3 # 0 +0xF65D 0x9F52 # 0 +0xF65E 0x5247 # 0 +0xF65F 0x52C5 # 0 +0xF660 0x98ED # 0 +0xF661 0x89AA # 0 +0xF662 0x4E03 # 0 +0xF663 0x67D2 # 0 +0xF664 0x6F06 # 0 +0xF665 0x4FB5 # 0 +0xF666 0x5BE2 # 0 +0xF667 0x6795 # 0 +0xF668 0x6C88 # 0 +0xF669 0x6D78 # 0 +0xF66A 0x741B # 0 +0xF66B 0x7827 # 0 +0xF66C 0x91DD # 0 +0xF66D 0x937C # 0 +0xF66E 0x87C4 # 0 +0xF66F 0x79E4 # 0 +0xF670 0x7A31 # 0 +0xF671 0x5FEB # 0 +0xF672 0x4ED6 # 0 +0xF673 0x54A4 # 0 +0xF674 0x553E # 0 +0xF675 0x58AE # 0 +0xF676 0x59A5 # 0 +0xF677 0x60F0 # 0 +0xF678 0x6253 # 0 +0xF679 0x62D6 # 0 +0xF67A 0x6736 # 0 +0xF67B 0x6955 # 0 +0xF67C 0x8235 # 0 +0xF67D 0x9640 # 0 +0xF67E 0x99B1 # 0 +0xF691 0x99DD # 0 +0xF692 0x502C # 0 +0xF693 0x5353 # 0 +0xF694 0x5544 # 0 +0xF695 0x577C # 0 +0xF696 0xFA01 # 0 +0xF697 0x6258 # 0 +0xF698 0xFA02 # 0 +0xF699 0x64E2 # 0 +0xF69A 0x666B # 0 +0xF69B 0x67DD # 0 +0xF69C 0x6FC1 # 0 +0xF69D 0x6FEF # 0 +0xF69E 0x7422 # 0 +0xF69F 0x7438 # 0 +0xF6A0 0x8A17 # 0 +0xF6A1 0x9438 # 0 +0xF6A2 0x5451 # 0 +0xF6A3 0x5606 # 0 +0xF6A4 0x5766 # 0 +0xF6A5 0x5F48 # 0 +0xF6A6 0x619A # 0 +0xF6A7 0x6B4E # 0 +0xF6A8 0x7058 # 0 +0xF6A9 0x70AD # 0 +0xF6AA 0x7DBB # 0 +0xF6AB 0x8A95 # 0 +0xF6AC 0x596A # 0 +0xF6AD 0x812B # 0 +0xF6AE 0x63A2 # 0 +0xF6AF 0x7708 # 0 +0xF6B0 0x803D # 0 +0xF6B1 0x8CAA # 0 +0xF6B2 0x5854 # 0 +0xF6B3 0x642D # 0 +0xF6B4 0x69BB # 0 +0xF6B5 0x5B95 # 0 +0xF6B6 0x5E11 # 0 +0xF6B7 0x6E6F # 0 +0xF6B8 0xFA03 # 0 +0xF6B9 0x8569 # 0 +0xF6BA 0x514C # 0 +0xF6BB 0x53F0 # 0 +0xF6BC 0x592A # 0 +0xF6BD 0x6020 # 0 +0xF6BE 0x614B # 0 +0xF6BF 0x6B86 # 0 +0xF6C0 0x6C70 # 0 +0xF6C1 0x6CF0 # 0 +0xF6C2 0x7B1E # 0 +0xF6C3 0x80CE # 0 +0xF6C4 0x82D4 # 0 +0xF6C5 0x8DC6 # 0 +0xF6C6 0x90B0 # 0 +0xF6C7 0x98B1 # 0 +0xF6C8 0xFA04 # 0 +0xF6C9 0x64C7 # 0 +0xF6CA 0x6FA4 # 0 +0xF6CB 0x6491 # 0 +0xF6CC 0x6504 # 0 +0xF6CD 0x514E # 0 +0xF6CE 0x5410 # 0 +0xF6CF 0x571F # 0 +0xF6D0 0x8A0E # 0 +0xF6D1 0x615F # 0 +0xF6D2 0x6876 # 0 +0xF6D3 0xFA05 # 0 +0xF6D4 0x75DB # 0 +0xF6D5 0x7B52 # 0 +0xF6D6 0x7D71 # 0 +0xF6D7 0x901A # 0 +0xF6D8 0x5806 # 0 +0xF6D9 0x69CC # 0 +0xF6DA 0x817F # 0 +0xF6DB 0x892A # 0 +0xF6DC 0x9000 # 0 +0xF6DD 0x9839 # 0 +0xF6DE 0x5078 # 0 +0xF6DF 0x5957 # 0 +0xF6E0 0x59AC # 0 +0xF6E1 0x6295 # 0 +0xF6E2 0x900F # 0 +0xF6E3 0x9B2A # 0 +0xF6E4 0x615D # 0 +0xF6E5 0x7279 # 0 +0xF6E6 0x95D6 # 0 +0xF6E7 0x5761 # 0 +0xF6E8 0x5A46 # 0 +0xF6E9 0x5DF4 # 0 +0xF6EA 0x628A # 0 +0xF6EB 0x64AD # 0 +0xF6EC 0x64FA # 0 +0xF6ED 0x6777 # 0 +0xF6EE 0x6CE2 # 0 +0xF6EF 0x6D3E # 0 +0xF6F0 0x722C # 0 +0xF6F1 0x7436 # 0 +0xF6F2 0x7834 # 0 +0xF6F3 0x7F77 # 0 +0xF6F4 0x82AD # 0 +0xF6F5 0x8DDB # 0 +0xF6F6 0x9817 # 0 +0xF6F7 0x5224 # 0 +0xF6F8 0x5742 # 0 +0xF6F9 0x677F # 0 +0xF6FA 0x7248 # 0 +0xF6FB 0x74E3 # 0 +0xF6FC 0x8CA9 # 0 +0xF6FD 0x8FA6 # 0 +0xF6FE 0x9211 # 0 +0xF731 0x962A # 0 +0xF732 0x516B # 0 +0xF733 0x53ED # 0 +0xF734 0x634C # 0 +0xF735 0x4F69 # 0 +0xF736 0x5504 # 0 +0xF737 0x6096 # 0 +0xF738 0x6557 # 0 +0xF739 0x6C9B # 0 +0xF73A 0x6D7F # 0 +0xF73B 0x724C # 0 +0xF73C 0x72FD # 0 +0xF73D 0x7A17 # 0 +0xF73E 0x8987 # 0 +0xF73F 0x8C9D # 0 +0xF740 0x5F6D # 0 +0xF741 0x6F8E # 0 +0xF742 0x70F9 # 0 +0xF743 0x81A8 # 0 +0xF744 0x610E # 0 +0xF745 0x4FBF # 0 +0xF746 0x504F # 0 +0xF747 0x6241 # 0 +0xF748 0x7247 # 0 +0xF749 0x7BC7 # 0 +0xF74A 0x7DE8 # 0 +0xF74B 0x7FE9 # 0 +0xF74C 0x904D # 0 +0xF74D 0x97AD # 0 +0xF74E 0x9A19 # 0 +0xF74F 0x8CB6 # 0 +0xF750 0x576A # 0 +0xF751 0x5E73 # 0 +0xF752 0x67B0 # 0 +0xF753 0x840D # 0 +0xF754 0x8A55 # 0 +0xF755 0x5420 # 0 +0xF756 0x5B16 # 0 +0xF757 0x5E63 # 0 +0xF758 0x5EE2 # 0 +0xF759 0x5F0A # 0 +0xF75A 0x6583 # 0 +0xF75B 0x80BA # 0 +0xF75C 0x853D # 0 +0xF75D 0x9589 # 0 +0xF75E 0x965B # 0 +0xF75F 0x4F48 # 0 +0xF760 0x5305 # 0 +0xF761 0x530D # 0 +0xF762 0x530F # 0 +0xF763 0x5486 # 0 +0xF764 0x54FA # 0 +0xF765 0x5703 # 0 +0xF766 0x5E03 # 0 +0xF767 0x6016 # 0 +0xF768 0x629B # 0 +0xF769 0x62B1 # 0 +0xF76A 0x6355 # 0 +0xF76B 0xFA06 # 0 +0xF76C 0x6CE1 # 0 +0xF76D 0x6D66 # 0 +0xF76E 0x75B1 # 0 +0xF76F 0x7832 # 0 +0xF770 0x80DE # 0 +0xF771 0x812F # 0 +0xF772 0x82DE # 0 +0xF773 0x8461 # 0 +0xF774 0x84B2 # 0 +0xF775 0x888D # 0 +0xF776 0x8912 # 0 +0xF777 0x900B # 0 +0xF778 0x92EA # 0 +0xF779 0x98FD # 0 +0xF77A 0x9B91 # 0 +0xF77B 0x5E45 # 0 +0xF77C 0x66B4 # 0 +0xF77D 0x66DD # 0 +0xF77E 0x7011 # 0 +0xF791 0x7206 # 0 +0xF792 0xFA07 # 0 +0xF793 0x4FF5 # 0 +0xF794 0x527D # 0 +0xF795 0x5F6A # 0 +0xF796 0x6153 # 0 +0xF797 0x6753 # 0 +0xF798 0x6A19 # 0 +0xF799 0x6F02 # 0 +0xF79A 0x74E2 # 0 +0xF79B 0x7968 # 0 +0xF79C 0x8868 # 0 +0xF79D 0x8C79 # 0 +0xF79E 0x98C7 # 0 +0xF79F 0x98C4 # 0 +0xF7A0 0x9A43 # 0 +0xF7A1 0x54C1 # 0 +0xF7A2 0x7A1F # 0 +0xF7A3 0x6953 # 0 +0xF7A4 0x8AF7 # 0 +0xF7A5 0x8C4A # 0 +0xF7A6 0x98A8 # 0 +0xF7A7 0x99AE # 0 +0xF7A8 0x5F7C # 0 +0xF7A9 0x62AB # 0 +0xF7AA 0x75B2 # 0 +0xF7AB 0x76AE # 0 +0xF7AC 0x88AB # 0 +0xF7AD 0x907F # 0 +0xF7AE 0x9642 # 0 +0xF7AF 0x5339 # 0 +0xF7B0 0x5F3C # 0 +0xF7B1 0x5FC5 # 0 +0xF7B2 0x6CCC # 0 +0xF7B3 0x73CC # 0 +0xF7B4 0x7562 # 0 +0xF7B5 0x758B # 0 +0xF7B6 0x7B46 # 0 +0xF7B7 0x82FE # 0 +0xF7B8 0x999D # 0 +0xF7B9 0x4E4F # 0 +0xF7BA 0x903C # 0 +0xF7BB 0x4E0B # 0 +0xF7BC 0x4F55 # 0 +0xF7BD 0x53A6 # 0 +0xF7BE 0x590F # 0 +0xF7BF 0x5EC8 # 0 +0xF7C0 0x6630 # 0 +0xF7C1 0x6CB3 # 0 +0xF7C2 0x7455 # 0 +0xF7C3 0x8377 # 0 +0xF7C4 0x8766 # 0 +0xF7C5 0x8CC0 # 0 +0xF7C6 0x9050 # 0 +0xF7C7 0x971E # 0 +0xF7C8 0x9C15 # 0 +0xF7C9 0x58D1 # 0 +0xF7CA 0x5B78 # 0 +0xF7CB 0x8650 # 0 +0xF7CC 0x8B14 # 0 +0xF7CD 0x9DB4 # 0 +0xF7CE 0x5BD2 # 0 +0xF7CF 0x6068 # 0 +0xF7D0 0x608D # 0 +0xF7D1 0x65F1 # 0 +0xF7D2 0x6C57 # 0 +0xF7D3 0x6F22 # 0 +0xF7D4 0x6FA3 # 0 +0xF7D5 0x701A # 0 +0xF7D6 0x7F55 # 0 +0xF7D7 0x7FF0 # 0 +0xF7D8 0x9591 # 0 +0xF7D9 0x9592 # 0 +0xF7DA 0x9650 # 0 +0xF7DB 0x97D3 # 0 +0xF7DC 0x5272 # 0 +0xF7DD 0x8F44 # 0 +0xF7DE 0x51FD # 0 +0xF7DF 0x542B # 0 +0xF7E0 0x54B8 # 0 +0xF7E1 0x5563 # 0 +0xF7E2 0x558A # 0 +0xF7E3 0x6ABB # 0 +0xF7E4 0x6DB5 # 0 +0xF7E5 0x7DD8 # 0 +0xF7E6 0x8266 # 0 +0xF7E7 0x929C # 0 +0xF7E8 0x9677 # 0 +0xF7E9 0x9E79 # 0 +0xF7EA 0x5408 # 0 +0xF7EB 0x54C8 # 0 +0xF7EC 0x76D2 # 0 +0xF7ED 0x86E4 # 0 +0xF7EE 0x95A4 # 0 +0xF7EF 0x95D4 # 0 +0xF7F0 0x965C # 0 +0xF7F1 0x4EA2 # 0 +0xF7F2 0x4F09 # 0 +0xF7F3 0x59EE # 0 +0xF7F4 0x5AE6 # 0 +0xF7F5 0x5DF7 # 0 +0xF7F6 0x6052 # 0 +0xF7F7 0x6297 # 0 +0xF7F8 0x676D # 0 +0xF7F9 0x6841 # 0 +0xF7FA 0x6C86 # 0 +0xF7FB 0x6E2F # 0 +0xF7FC 0x7F38 # 0 +0xF7FD 0x809B # 0 +0xF7FE 0x822A # 0 +0xF831 0xFA08 # 0 +0xF832 0xFA09 # 0 +0xF833 0x9805 # 0 +0xF834 0x4EA5 # 0 +0xF835 0x5055 # 0 +0xF836 0x54B3 # 0 +0xF837 0x5793 # 0 +0xF838 0x595A # 0 +0xF839 0x5B69 # 0 +0xF83A 0x5BB3 # 0 +0xF83B 0x61C8 # 0 +0xF83C 0x6977 # 0 +0xF83D 0x6D77 # 0 +0xF83E 0x7023 # 0 +0xF83F 0x87F9 # 0 +0xF840 0x89E3 # 0 +0xF841 0x8A72 # 0 +0xF842 0x8AE7 # 0 +0xF843 0x9082 # 0 +0xF844 0x99ED # 0 +0xF845 0x9AB8 # 0 +0xF846 0x52BE # 0 +0xF847 0x6838 # 0 +0xF848 0x5016 # 0 +0xF849 0x5E78 # 0 +0xF84A 0x674F # 0 +0xF84B 0x8347 # 0 +0xF84C 0x884C # 0 +0xF84D 0x4EAB # 0 +0xF84E 0x5411 # 0 +0xF84F 0x56AE # 0 +0xF850 0x73E6 # 0 +0xF851 0x9115 # 0 +0xF852 0x97FF # 0 +0xF853 0x9909 # 0 +0xF854 0x9957 # 0 +0xF855 0x9999 # 0 +0xF856 0x5653 # 0 +0xF857 0x589F # 0 +0xF858 0x865B # 0 +0xF859 0x8A31 # 0 +0xF85A 0x61B2 # 0 +0xF85B 0x6AF6 # 0 +0xF85C 0x737B # 0 +0xF85D 0x8ED2 # 0 +0xF85E 0x6B47 # 0 +0xF85F 0x96AA # 0 +0xF860 0x9A57 # 0 +0xF861 0x5955 # 0 +0xF862 0x7200 # 0 +0xF863 0x8D6B # 0 +0xF864 0x9769 # 0 +0xF865 0x4FD4 # 0 +0xF866 0x5CF4 # 0 +0xF867 0x5F26 # 0 +0xF868 0x61F8 # 0 +0xF869 0x665B # 0 +0xF86A 0x6CEB # 0 +0xF86B 0x70AB # 0 +0xF86C 0x7384 # 0 +0xF86D 0x73B9 # 0 +0xF86E 0x73FE # 0 +0xF86F 0x7729 # 0 +0xF870 0x774D # 0 +0xF871 0x7D43 # 0 +0xF872 0x7D62 # 0 +0xF873 0x7E23 # 0 +0xF874 0x8237 # 0 +0xF875 0x8852 # 0 +0xF876 0xFA0A # 0 +0xF877 0x8CE2 # 0 +0xF878 0x9249 # 0 +0xF879 0x986F # 0 +0xF87A 0x5B51 # 0 +0xF87B 0x7A74 # 0 +0xF87C 0x8840 # 0 +0xF87D 0x9801 # 0 +0xF87E 0x5ACC # 0 +0xF891 0x4FE0 # 0 +0xF892 0x5354 # 0 +0xF893 0x593E # 0 +0xF894 0x5CFD # 0 +0xF895 0x633E # 0 +0xF896 0x6D79 # 0 +0xF897 0x72F9 # 0 +0xF898 0x8105 # 0 +0xF899 0x8107 # 0 +0xF89A 0x83A2 # 0 +0xF89B 0x92CF # 0 +0xF89C 0x9830 # 0 +0xF89D 0x4EA8 # 0 +0xF89E 0x5144 # 0 +0xF89F 0x5211 # 0 +0xF8A0 0x578B # 0 +0xF8A1 0x5F62 # 0 +0xF8A2 0x6CC2 # 0 +0xF8A3 0x6ECE # 0 +0xF8A4 0x7005 # 0 +0xF8A5 0x7050 # 0 +0xF8A6 0x70AF # 0 +0xF8A7 0x7192 # 0 +0xF8A8 0x73E9 # 0 +0xF8A9 0x7469 # 0 +0xF8AA 0x834A # 0 +0xF8AB 0x87A2 # 0 +0xF8AC 0x8861 # 0 +0xF8AD 0x9008 # 0 +0xF8AE 0x90A2 # 0 +0xF8AF 0x93A3 # 0 +0xF8B0 0x99A8 # 0 +0xF8B1 0x516E # 0 +0xF8B2 0x5F57 # 0 +0xF8B3 0x60E0 # 0 +0xF8B4 0x6167 # 0 +0xF8B5 0x66B3 # 0 +0xF8B6 0x8559 # 0 +0xF8B7 0x8E4A # 0 +0xF8B8 0x91AF # 0 +0xF8B9 0x978B # 0 +0xF8BA 0x4E4E # 0 +0xF8BB 0x4E92 # 0 +0xF8BC 0x547C # 0 +0xF8BD 0x58D5 # 0 +0xF8BE 0x58FA # 0 +0xF8BF 0x597D # 0 +0xF8C0 0x5CB5 # 0 +0xF8C1 0x5F27 # 0 +0xF8C2 0x6236 # 0 +0xF8C3 0x6248 # 0 +0xF8C4 0x660A # 0 +0xF8C5 0x6667 # 0 +0xF8C6 0x6BEB # 0 +0xF8C7 0x6D69 # 0 +0xF8C8 0x6DCF # 0 +0xF8C9 0x6E56 # 0 +0xF8CA 0x6EF8 # 0 +0xF8CB 0x6F94 # 0 +0xF8CC 0x6FE0 # 0 +0xF8CD 0x6FE9 # 0 +0xF8CE 0x705D # 0 +0xF8CF 0x72D0 # 0 +0xF8D0 0x7425 # 0 +0xF8D1 0x745A # 0 +0xF8D2 0x74E0 # 0 +0xF8D3 0x7693 # 0 +0xF8D4 0x795C # 0 +0xF8D5 0x7CCA # 0 +0xF8D6 0x7E1E # 0 +0xF8D7 0x80E1 # 0 +0xF8D8 0x82A6 # 0 +0xF8D9 0x846B # 0 +0xF8DA 0x84BF # 0 +0xF8DB 0x864E # 0 +0xF8DC 0x865F # 0 +0xF8DD 0x8774 # 0 +0xF8DE 0x8B77 # 0 +0xF8DF 0x8C6A # 0 +0xF8E0 0x93AC # 0 +0xF8E1 0x9800 # 0 +0xF8E2 0x9865 # 0 +0xF8E3 0x60D1 # 0 +0xF8E4 0x6216 # 0 +0xF8E5 0x9177 # 0 +0xF8E6 0x5A5A # 0 +0xF8E7 0x660F # 0 +0xF8E8 0x6DF7 # 0 +0xF8E9 0x6E3E # 0 +0xF8EA 0x743F # 0 +0xF8EB 0x9B42 # 0 +0xF8EC 0x5FFD # 0 +0xF8ED 0x60DA # 0 +0xF8EE 0x7B0F # 0 +0xF8EF 0x54C4 # 0 +0xF8F0 0x5F18 # 0 +0xF8F1 0x6C5E # 0 +0xF8F2 0x6CD3 # 0 +0xF8F3 0x6D2A # 0 +0xF8F4 0x70D8 # 0 +0xF8F5 0x7D05 # 0 +0xF8F6 0x8679 # 0 +0xF8F7 0x8A0C # 0 +0xF8F8 0x9D3B # 0 +0xF8F9 0x5316 # 0 +0xF8FA 0x548C # 0 +0xF8FB 0x5B05 # 0 +0xF8FC 0x6A3A # 0 +0xF8FD 0x706B # 0 +0xF8FE 0x7575 # 0 +0xF931 0x798D # 0 +0xF932 0x79BE # 0 +0xF933 0x82B1 # 0 +0xF934 0x83EF # 0 +0xF935 0x8A71 # 0 +0xF936 0x8B41 # 0 +0xF937 0x8CA8 # 0 +0xF938 0x9774 # 0 +0xF939 0xFA0B # 0 +0xF93A 0x64F4 # 0 +0xF93B 0x652B # 0 +0xF93C 0x78BA # 0 +0xF93D 0x78BB # 0 +0xF93E 0x7A6B # 0 +0xF93F 0x4E38 # 0 +0xF940 0x559A # 0 +0xF941 0x5950 # 0 +0xF942 0x5BA6 # 0 +0xF943 0x5E7B # 0 +0xF944 0x60A3 # 0 +0xF945 0x63DB # 0 +0xF946 0x6B61 # 0 +0xF947 0x6665 # 0 +0xF948 0x6853 # 0 +0xF949 0x6E19 # 0 +0xF94A 0x7165 # 0 +0xF94B 0x74B0 # 0 +0xF94C 0x7D08 # 0 +0xF94D 0x9084 # 0 +0xF94E 0x9A69 # 0 +0xF94F 0x9C25 # 0 +0xF950 0x6D3B # 0 +0xF951 0x6ED1 # 0 +0xF952 0x733E # 0 +0xF953 0x8C41 # 0 +0xF954 0x95CA # 0 +0xF955 0x51F0 # 0 +0xF956 0x5E4C # 0 +0xF957 0x5FA8 # 0 +0xF958 0x604D # 0 +0xF959 0x60F6 # 0 +0xF95A 0x6130 # 0 +0xF95B 0x614C # 0 +0xF95C 0x6643 # 0 +0xF95D 0x6644 # 0 +0xF95E 0x69A5 # 0 +0xF95F 0x6CC1 # 0 +0xF960 0x6E5F # 0 +0xF961 0x6EC9 # 0 +0xF962 0x6F62 # 0 +0xF963 0x714C # 0 +0xF964 0x749C # 0 +0xF965 0x7687 # 0 +0xF966 0x7BC1 # 0 +0xF967 0x7C27 # 0 +0xF968 0x8352 # 0 +0xF969 0x8757 # 0 +0xF96A 0x9051 # 0 +0xF96B 0x968D # 0 +0xF96C 0x9EC3 # 0 +0xF96D 0x532F # 0 +0xF96E 0x56DE # 0 +0xF96F 0x5EFB # 0 +0xF970 0x5F8A # 0 +0xF971 0x6062 # 0 +0xF972 0x6094 # 0 +0xF973 0x61F7 # 0 +0xF974 0x6666 # 0 +0xF975 0x6703 # 0 +0xF976 0x6A9C # 0 +0xF977 0x6DEE # 0 +0xF978 0x6FAE # 0 +0xF979 0x7070 # 0 +0xF97A 0x736A # 0 +0xF97B 0x7E6A # 0 +0xF97C 0x81BE # 0 +0xF97D 0x8334 # 0 +0xF97E 0x86D4 # 0 +0xF991 0x8AA8 # 0 +0xF992 0x8CC4 # 0 +0xF993 0x5283 # 0 +0xF994 0x7372 # 0 +0xF995 0x5B96 # 0 +0xF996 0x6A6B # 0 +0xF997 0x9404 # 0 +0xF998 0x54EE # 0 +0xF999 0x5686 # 0 +0xF99A 0x5B5D # 0 +0xF99B 0x6548 # 0 +0xF99C 0x6585 # 0 +0xF99D 0x66C9 # 0 +0xF99E 0x689F # 0 +0xF99F 0x6D8D # 0 +0xF9A0 0x6DC6 # 0 +0xF9A1 0x723B # 0 +0xF9A2 0x80B4 # 0 +0xF9A3 0x9175 # 0 +0xF9A4 0x9A4D # 0 +0xF9A5 0x4FAF # 0 +0xF9A6 0x5019 # 0 +0xF9A7 0x539A # 0 +0xF9A8 0x540E # 0 +0xF9A9 0x543C # 0 +0xF9AA 0x5589 # 0 +0xF9AB 0x55C5 # 0 +0xF9AC 0x5E3F # 0 +0xF9AD 0x5F8C # 0 +0xF9AE 0x673D # 0 +0xF9AF 0x7166 # 0 +0xF9B0 0x73DD # 0 +0xF9B1 0x9005 # 0 +0xF9B2 0x52DB # 0 +0xF9B3 0x52F3 # 0 +0xF9B4 0x5864 # 0 +0xF9B5 0x58CE # 0 +0xF9B6 0x7104 # 0 +0xF9B7 0x718F # 0 +0xF9B8 0x71FB # 0 +0xF9B9 0x85B0 # 0 +0xF9BA 0x8A13 # 0 +0xF9BB 0x6688 # 0 +0xF9BC 0x85A8 # 0 +0xF9BD 0x55A7 # 0 +0xF9BE 0x6684 # 0 +0xF9BF 0x714A # 0 +0xF9C0 0x8431 # 0 +0xF9C1 0x5349 # 0 +0xF9C2 0x5599 # 0 +0xF9C3 0x6BC1 # 0 +0xF9C4 0x5F59 # 0 +0xF9C5 0x5FBD # 0 +0xF9C6 0x63EE # 0 +0xF9C7 0x6689 # 0 +0xF9C8 0x7147 # 0 +0xF9C9 0x8AF1 # 0 +0xF9CA 0x8F1D # 0 +0xF9CB 0x9EBE # 0 +0xF9CC 0x4F11 # 0 +0xF9CD 0x643A # 0 +0xF9CE 0x70CB # 0 +0xF9CF 0x7566 # 0 +0xF9D0 0x8667 # 0 +0xF9D1 0x6064 # 0 +0xF9D2 0x8B4E # 0 +0xF9D3 0x9DF8 # 0 +0xF9D4 0x5147 # 0 +0xF9D5 0x51F6 # 0 +0xF9D6 0x5308 # 0 +0xF9D7 0x6D36 # 0 +0xF9D8 0x80F8 # 0 +0xF9D9 0x9ED1 # 0 +0xF9DA 0x6615 # 0 +0xF9DB 0x6B23 # 0 +0xF9DC 0x7098 # 0 +0xF9DD 0x75D5 # 0 +0xF9DE 0x5403 # 0 +0xF9DF 0x5C79 # 0 +0xF9E0 0x7D07 # 0 +0xF9E1 0x8A16 # 0 +0xF9E2 0x6B20 # 0 +0xF9E3 0x6B3D # 0 +0xF9E4 0x6B46 # 0 +0xF9E5 0x5438 # 0 +0xF9E6 0x6070 # 0 +0xF9E7 0x6D3D # 0 +0xF9E8 0x7FD5 # 0 +0xF9E9 0x8208 # 0 +0xF9EA 0x50D6 # 0 +0xF9EB 0x51DE # 0 +0xF9EC 0x559C # 0 +0xF9ED 0x566B # 0 +0xF9EE 0x56CD # 0 +0xF9EF 0x59EC # 0 +0xF9F0 0x5B09 # 0 +0xF9F1 0x5E0C # 0 +0xF9F2 0x6199 # 0 +0xF9F3 0x6198 # 0 +0xF9F4 0x6231 # 0 +0xF9F5 0x665E # 0 +0xF9F6 0x66E6 # 0 +0xF9F7 0x7199 # 0 +0xF9F8 0x71B9 # 0 +0xF9F9 0x71BA # 0 +0xF9FA 0x72A7 # 0 +0xF9FB 0x79A7 # 0 +0xF9FC 0x7A00 # 0 +0xF9FD 0x7FB2 # 0 +0xF9FE 0x8A70 # 0 diff --git a/data/windows-874.txt b/data/windows-874.txt new file mode 100644 index 0000000000..1eb71dfe1b --- /dev/null +++ b/data/windows-874.txt @@ -0,0 +1,274 @@ +# +# Name: cp874 to Unicode table +# Unicode version: 2.0 +# Table version: 2.01 +# Table format: Format A +# Date: 02/28/98 +# +# Contact: cpxlate@microsoft.com +# +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp874 code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp874 order +# +0x00 0x0000 #NULL +0x01 0x0001 #START OF HEADING +0x02 0x0002 #START OF TEXT +0x03 0x0003 #END OF TEXT +0x04 0x0004 #END OF TRANSMISSION +0x05 0x0005 #ENQUIRY +0x06 0x0006 #ACKNOWLEDGE +0x07 0x0007 #BELL +0x08 0x0008 #BACKSPACE +0x09 0x0009 #HORIZONTAL TABULATION +0x0A 0x000A #LINE FEED +0x0B 0x000B #VERTICAL TABULATION +0x0C 0x000C #FORM FEED +0x0D 0x000D #CARRIAGE RETURN +0x0E 0x000E #SHIFT OUT +0x0F 0x000F #SHIFT IN +0x10 0x0010 #DATA LINK ESCAPE +0x11 0x0011 #DEVICE CONTROL ONE +0x12 0x0012 #DEVICE CONTROL TWO +0x13 0x0013 #DEVICE CONTROL THREE +0x14 0x0014 #DEVICE CONTROL FOUR +0x15 0x0015 #NEGATIVE ACKNOWLEDGE +0x16 0x0016 #SYNCHRONOUS IDLE +0x17 0x0017 #END OF TRANSMISSION BLOCK +0x18 0x0018 #CANCEL +0x19 0x0019 #END OF MEDIUM +0x1A 0x001A #SUBSTITUTE +0x1B 0x001B #ESCAPE +0x1C 0x001C #FILE SEPARATOR +0x1D 0x001D #GROUP SEPARATOR +0x1E 0x001E #RECORD SEPARATOR +0x1F 0x001F #UNIT SEPARATOR +0x20 0x0020 #SPACE +0x21 0x0021 #EXCLAMATION MARK +0x22 0x0022 #QUOTATION MARK +0x23 0x0023 #NUMBER SIGN +0x24 0x0024 #DOLLAR SIGN +0x25 0x0025 #PERCENT SIGN +0x26 0x0026 #AMPERSAND +0x27 0x0027 #APOSTROPHE +0x28 0x0028 #LEFT PARENTHESIS +0x29 0x0029 #RIGHT PARENTHESIS +0x2A 0x002A #ASTERISK +0x2B 0x002B #PLUS SIGN +0x2C 0x002C #COMMA +0x2D 0x002D #HYPHEN-MINUS +0x2E 0x002E #FULL STOP +0x2F 0x002F #SOLIDUS +0x30 0x0030 #DIGIT ZERO +0x31 0x0031 #DIGIT ONE +0x32 0x0032 #DIGIT TWO +0x33 0x0033 #DIGIT THREE +0x34 0x0034 #DIGIT FOUR +0x35 0x0035 #DIGIT FIVE +0x36 0x0036 #DIGIT SIX +0x37 0x0037 #DIGIT SEVEN +0x38 0x0038 #DIGIT EIGHT +0x39 0x0039 #DIGIT NINE +0x3A 0x003A #COLON +0x3B 0x003B #SEMICOLON +0x3C 0x003C #LESS-THAN SIGN +0x3D 0x003D #EQUALS SIGN +0x3E 0x003E #GREATER-THAN SIGN +0x3F 0x003F #QUESTION MARK +0x40 0x0040 #COMMERCIAL AT +0x41 0x0041 #LATIN CAPITAL LETTER A +0x42 0x0042 #LATIN CAPITAL LETTER B +0x43 0x0043 #LATIN CAPITAL LETTER C +0x44 0x0044 #LATIN CAPITAL LETTER D +0x45 0x0045 #LATIN CAPITAL LETTER E +0x46 0x0046 #LATIN CAPITAL LETTER F +0x47 0x0047 #LATIN CAPITAL LETTER G +0x48 0x0048 #LATIN CAPITAL LETTER H +0x49 0x0049 #LATIN CAPITAL LETTER I +0x4A 0x004A #LATIN CAPITAL LETTER J +0x4B 0x004B #LATIN CAPITAL LETTER K +0x4C 0x004C #LATIN CAPITAL LETTER L +0x4D 0x004D #LATIN CAPITAL LETTER M +0x4E 0x004E #LATIN CAPITAL LETTER N +0x4F 0x004F #LATIN CAPITAL LETTER O +0x50 0x0050 #LATIN CAPITAL LETTER P +0x51 0x0051 #LATIN CAPITAL LETTER Q +0x52 0x0052 #LATIN CAPITAL LETTER R +0x53 0x0053 #LATIN CAPITAL LETTER S +0x54 0x0054 #LATIN CAPITAL LETTER T +0x55 0x0055 #LATIN CAPITAL LETTER U +0x56 0x0056 #LATIN CAPITAL LETTER V +0x57 0x0057 #LATIN CAPITAL LETTER W +0x58 0x0058 #LATIN CAPITAL LETTER X +0x59 0x0059 #LATIN CAPITAL LETTER Y +0x5A 0x005A #LATIN CAPITAL LETTER Z +0x5B 0x005B #LEFT SQUARE BRACKET +0x5C 0x005C #REVERSE SOLIDUS +0x5D 0x005D #RIGHT SQUARE BRACKET +0x5E 0x005E #CIRCUMFLEX ACCENT +0x5F 0x005F #LOW LINE +0x60 0x0060 #GRAVE ACCENT +0x61 0x0061 #LATIN SMALL LETTER A +0x62 0x0062 #LATIN SMALL LETTER B +0x63 0x0063 #LATIN SMALL LETTER C +0x64 0x0064 #LATIN SMALL LETTER D +0x65 0x0065 #LATIN SMALL LETTER E +0x66 0x0066 #LATIN SMALL LETTER F +0x67 0x0067 #LATIN SMALL LETTER G +0x68 0x0068 #LATIN SMALL LETTER H +0x69 0x0069 #LATIN SMALL LETTER I +0x6A 0x006A #LATIN SMALL LETTER J +0x6B 0x006B #LATIN SMALL LETTER K +0x6C 0x006C #LATIN SMALL LETTER L +0x6D 0x006D #LATIN SMALL LETTER M +0x6E 0x006E #LATIN SMALL LETTER N +0x6F 0x006F #LATIN SMALL LETTER O +0x70 0x0070 #LATIN SMALL LETTER P +0x71 0x0071 #LATIN SMALL LETTER Q +0x72 0x0072 #LATIN SMALL LETTER R +0x73 0x0073 #LATIN SMALL LETTER S +0x74 0x0074 #LATIN SMALL LETTER T +0x75 0x0075 #LATIN SMALL LETTER U +0x76 0x0076 #LATIN SMALL LETTER V +0x77 0x0077 #LATIN SMALL LETTER W +0x78 0x0078 #LATIN SMALL LETTER X +0x79 0x0079 #LATIN SMALL LETTER Y +0x7A 0x007A #LATIN SMALL LETTER Z +0x7B 0x007B #LEFT CURLY BRACKET +0x7C 0x007C #VERTICAL LINE +0x7D 0x007D #RIGHT CURLY BRACKET +0x7E 0x007E #TILDE +0x7F 0x007F #DELETE +0x80 0x20AC #EURO SIGN +0x81 #UNDEFINED +0x82 #UNDEFINED +0x83 #UNDEFINED +0x84 #UNDEFINED +0x85 0x2026 #HORIZONTAL ELLIPSIS +0x86 #UNDEFINED +0x87 #UNDEFINED +0x88 #UNDEFINED +0x89 #UNDEFINED +0x8A #UNDEFINED +0x8B #UNDEFINED +0x8C #UNDEFINED +0x8D #UNDEFINED +0x8E #UNDEFINED +0x8F #UNDEFINED +0x90 #UNDEFINED +0x91 0x2018 #LEFT SINGLE QUOTATION MARK +0x92 0x2019 #RIGHT SINGLE QUOTATION MARK +0x93 0x201C #LEFT DOUBLE QUOTATION MARK +0x94 0x201D #RIGHT DOUBLE QUOTATION MARK +0x95 0x2022 #BULLET +0x96 0x2013 #EN DASH +0x97 0x2014 #EM DASH +0x98 #UNDEFINED +0x99 #UNDEFINED +0x9A #UNDEFINED +0x9B #UNDEFINED +0x9C #UNDEFINED +0x9D #UNDEFINED +0x9E #UNDEFINED +0x9F #UNDEFINED +0xA0 0x00A0 #NO-BREAK SPACE +0xA1 0x0E01 #THAI CHARACTER KO KAI +0xA2 0x0E02 #THAI CHARACTER KHO KHAI +0xA3 0x0E03 #THAI CHARACTER KHO KHUAT +0xA4 0x0E04 #THAI CHARACTER KHO KHWAI +0xA5 0x0E05 #THAI CHARACTER KHO KHON +0xA6 0x0E06 #THAI CHARACTER KHO RAKHANG +0xA7 0x0E07 #THAI CHARACTER NGO NGU +0xA8 0x0E08 #THAI CHARACTER CHO CHAN +0xA9 0x0E09 #THAI CHARACTER CHO CHING +0xAA 0x0E0A #THAI CHARACTER CHO CHANG +0xAB 0x0E0B #THAI CHARACTER SO SO +0xAC 0x0E0C #THAI CHARACTER CHO CHOE +0xAD 0x0E0D #THAI CHARACTER YO YING +0xAE 0x0E0E #THAI CHARACTER DO CHADA +0xAF 0x0E0F #THAI CHARACTER TO PATAK +0xB0 0x0E10 #THAI CHARACTER THO THAN +0xB1 0x0E11 #THAI CHARACTER THO NANGMONTHO +0xB2 0x0E12 #THAI CHARACTER THO PHUTHAO +0xB3 0x0E13 #THAI CHARACTER NO NEN +0xB4 0x0E14 #THAI CHARACTER DO DEK +0xB5 0x0E15 #THAI CHARACTER TO TAO +0xB6 0x0E16 #THAI CHARACTER THO THUNG +0xB7 0x0E17 #THAI CHARACTER THO THAHAN +0xB8 0x0E18 #THAI CHARACTER THO THONG +0xB9 0x0E19 #THAI CHARACTER NO NU +0xBA 0x0E1A #THAI CHARACTER BO BAIMAI +0xBB 0x0E1B #THAI CHARACTER PO PLA +0xBC 0x0E1C #THAI CHARACTER PHO PHUNG +0xBD 0x0E1D #THAI CHARACTER FO FA +0xBE 0x0E1E #THAI CHARACTER PHO PHAN +0xBF 0x0E1F #THAI CHARACTER FO FAN +0xC0 0x0E20 #THAI CHARACTER PHO SAMPHAO +0xC1 0x0E21 #THAI CHARACTER MO MA +0xC2 0x0E22 #THAI CHARACTER YO YAK +0xC3 0x0E23 #THAI CHARACTER RO RUA +0xC4 0x0E24 #THAI CHARACTER RU +0xC5 0x0E25 #THAI CHARACTER LO LING +0xC6 0x0E26 #THAI CHARACTER LU +0xC7 0x0E27 #THAI CHARACTER WO WAEN +0xC8 0x0E28 #THAI CHARACTER SO SALA +0xC9 0x0E29 #THAI CHARACTER SO RUSI +0xCA 0x0E2A #THAI CHARACTER SO SUA +0xCB 0x0E2B #THAI CHARACTER HO HIP +0xCC 0x0E2C #THAI CHARACTER LO CHULA +0xCD 0x0E2D #THAI CHARACTER O ANG +0xCE 0x0E2E #THAI CHARACTER HO NOKHUK +0xCF 0x0E2F #THAI CHARACTER PAIYANNOI +0xD0 0x0E30 #THAI CHARACTER SARA A +0xD1 0x0E31 #THAI CHARACTER MAI HAN-AKAT +0xD2 0x0E32 #THAI CHARACTER SARA AA +0xD3 0x0E33 #THAI CHARACTER SARA AM +0xD4 0x0E34 #THAI CHARACTER SARA I +0xD5 0x0E35 #THAI CHARACTER SARA II +0xD6 0x0E36 #THAI CHARACTER SARA UE +0xD7 0x0E37 #THAI CHARACTER SARA UEE +0xD8 0x0E38 #THAI CHARACTER SARA U +0xD9 0x0E39 #THAI CHARACTER SARA UU +0xDA 0x0E3A #THAI CHARACTER PHINTHU +0xDB #UNDEFINED +0xDC #UNDEFINED +0xDD #UNDEFINED +0xDE #UNDEFINED +0xDF 0x0E3F #THAI CURRENCY SYMBOL BAHT +0xE0 0x0E40 #THAI CHARACTER SARA E +0xE1 0x0E41 #THAI CHARACTER SARA AE +0xE2 0x0E42 #THAI CHARACTER SARA O +0xE3 0x0E43 #THAI CHARACTER SARA AI MAIMUAN +0xE4 0x0E44 #THAI CHARACTER SARA AI MAIMALAI +0xE5 0x0E45 #THAI CHARACTER LAKKHANGYAO +0xE6 0x0E46 #THAI CHARACTER MAIYAMOK +0xE7 0x0E47 #THAI CHARACTER MAITAIKHU +0xE8 0x0E48 #THAI CHARACTER MAI EK +0xE9 0x0E49 #THAI CHARACTER MAI THO +0xEA 0x0E4A #THAI CHARACTER MAI TRI +0xEB 0x0E4B #THAI CHARACTER MAI CHATTAWA +0xEC 0x0E4C #THAI CHARACTER THANTHAKHAT +0xED 0x0E4D #THAI CHARACTER NIKHAHIT +0xEE 0x0E4E #THAI CHARACTER YAMAKKAN +0xEF 0x0E4F #THAI CHARACTER FONGMAN +0xF0 0x0E50 #THAI DIGIT ZERO +0xF1 0x0E51 #THAI DIGIT ONE +0xF2 0x0E52 #THAI DIGIT TWO +0xF3 0x0E53 #THAI DIGIT THREE +0xF4 0x0E54 #THAI DIGIT FOUR +0xF5 0x0E55 #THAI DIGIT FIVE +0xF6 0x0E56 #THAI DIGIT SIX +0xF7 0x0E57 #THAI DIGIT SEVEN +0xF8 0x0E58 #THAI DIGIT EIGHT +0xF9 0x0E59 #THAI DIGIT NINE +0xFA 0x0E5A #THAI CHARACTER ANGKHANKHU +0xFB 0x0E5B #THAI CHARACTER KHOMUT +0xFC #UNDEFINED +0xFD #UNDEFINED +0xFE #UNDEFINED +0xFF #UNDEFINED diff --git a/data/windows-932.txt b/data/windows-932.txt new file mode 100644 index 0000000000..b754215d9d --- /dev/null +++ b/data/windows-932.txt @@ -0,0 +1,9403 @@ +# cp932.txt - Legacy to Unicode charmap +0x0000 0x0000 # 0 +0x0001 0x0001 # 0 +0x0002 0x0002 # 0 +0x0003 0x0003 # 0 +0x0004 0x0004 # 0 +0x0005 0x0005 # 0 +0x0006 0x0006 # 0 +0x0007 0x0007 # 0 +0x0008 0x0008 # 0 +0x0009 0x0009 # 0 +0x000A 0x000A # 0 +0x000B 0x000B # 0 +0x000C 0x000C # 0 +0x000D 0x000D # 0 +0x000E 0x000E # 0 +0x000F 0x000F # 0 +0x0010 0x0010 # 0 +0x0011 0x0011 # 0 +0x0012 0x0012 # 0 +0x0013 0x0013 # 0 +0x0014 0x0014 # 0 +0x0015 0x0015 # 0 +0x0016 0x0016 # 0 +0x0017 0x0017 # 0 +0x0018 0x0018 # 0 +0x0019 0x0019 # 0 +0x001A 0x001A # 0 +0x001B 0x001B # 0 +0x001C 0x001C # 0 +0x001D 0x001D # 0 +0x001E 0x001E # 0 +0x001F 0x001F # 0 +0x0020 0x0020 # 0 +0x0021 0x0021 # 0 +0x0022 0x0022 # 0 +0x0023 0x0023 # 0 +0x0024 0x0024 # 0 +0x0025 0x0025 # 0 +0x0026 0x0026 # 0 +0x0027 0x0027 # 0 +0x0028 0x0028 # 0 +0x0029 0x0029 # 0 +0x002A 0x002A # 0 +0x002B 0x002B # 0 +0x002C 0x002C # 0 +0x002D 0x002D # 0 +0x002E 0x002E # 0 +0x002F 0x002F # 0 +0x0030 0x0030 # 0 +0x0031 0x0031 # 0 +0x0032 0x0032 # 0 +0x0033 0x0033 # 0 +0x0034 0x0034 # 0 +0x0035 0x0035 # 0 +0x0036 0x0036 # 0 +0x0037 0x0037 # 0 +0x0038 0x0038 # 0 +0x0039 0x0039 # 0 +0x003A 0x003A # 0 +0x003B 0x003B # 0 +0x003C 0x003C # 0 +0x003D 0x003D # 0 +0x003E 0x003E # 0 +0x003F 0x003F # 0 +0x0040 0x0040 # 0 +0x0041 0x0041 # 0 +0x0042 0x0042 # 0 +0x0043 0x0043 # 0 +0x0044 0x0044 # 0 +0x0045 0x0045 # 0 +0x0046 0x0046 # 0 +0x0047 0x0047 # 0 +0x0048 0x0048 # 0 +0x0049 0x0049 # 0 +0x004A 0x004A # 0 +0x004B 0x004B # 0 +0x004C 0x004C # 0 +0x004D 0x004D # 0 +0x004E 0x004E # 0 +0x004F 0x004F # 0 +0x0050 0x0050 # 0 +0x0051 0x0051 # 0 +0x0052 0x0052 # 0 +0x0053 0x0053 # 0 +0x0054 0x0054 # 0 +0x0055 0x0055 # 0 +0x0056 0x0056 # 0 +0x0057 0x0057 # 0 +0x0058 0x0058 # 0 +0x0059 0x0059 # 0 +0x005A 0x005A # 0 +0x005B 0x005B # 0 +0x005C 0x005C # 0 +0x005D 0x005D # 0 +0x005E 0x005E # 0 +0x005F 0x005F # 0 +0x0060 0x0060 # 0 +0x0061 0x0061 # 0 +0x0062 0x0062 # 0 +0x0063 0x0063 # 0 +0x0064 0x0064 # 0 +0x0065 0x0065 # 0 +0x0066 0x0066 # 0 +0x0067 0x0067 # 0 +0x0068 0x0068 # 0 +0x0069 0x0069 # 0 +0x006A 0x006A # 0 +0x006B 0x006B # 0 +0x006C 0x006C # 0 +0x006D 0x006D # 0 +0x006E 0x006E # 0 +0x006F 0x006F # 0 +0x0070 0x0070 # 0 +0x0071 0x0071 # 0 +0x0072 0x0072 # 0 +0x0073 0x0073 # 0 +0x0074 0x0074 # 0 +0x0075 0x0075 # 0 +0x0076 0x0076 # 0 +0x0077 0x0077 # 0 +0x0078 0x0078 # 0 +0x0079 0x0079 # 0 +0x007A 0x007A # 0 +0x007B 0x007B # 0 +0x007C 0x007C # 0 +0x007D 0x007D # 0 +0x007E 0x007E # 0 +0x007F 0x007F # 0 +0x0080 0x0080 # 0 +0x00A0 0xF8F0 # 0 +0x00A1 0xFF61 # 0 +0x00A2 0xFF62 # 0 +0x00A3 0xFF63 # 0 +0x00A4 0xFF64 # 0 +0x00A5 0xFF65 # 0 +0x00A6 0xFF66 # 0 +0x00A7 0xFF67 # 0 +0x00A8 0xFF68 # 0 +0x00A9 0xFF69 # 0 +0x00AA 0xFF6A # 0 +0x00AB 0xFF6B # 0 +0x00AC 0xFF6C # 0 +0x00AD 0xFF6D # 0 +0x00AE 0xFF6E # 0 +0x00AF 0xFF6F # 0 +0x00B0 0xFF70 # 0 +0x00B1 0xFF71 # 0 +0x00B2 0xFF72 # 0 +0x00B3 0xFF73 # 0 +0x00B4 0xFF74 # 0 +0x00B5 0xFF75 # 0 +0x00B6 0xFF76 # 0 +0x00B7 0xFF77 # 0 +0x00B8 0xFF78 # 0 +0x00B9 0xFF79 # 0 +0x00BA 0xFF7A # 0 +0x00BB 0xFF7B # 0 +0x00BC 0xFF7C # 0 +0x00BD 0xFF7D # 0 +0x00BE 0xFF7E # 0 +0x00BF 0xFF7F # 0 +0x00C0 0xFF80 # 0 +0x00C1 0xFF81 # 0 +0x00C2 0xFF82 # 0 +0x00C3 0xFF83 # 0 +0x00C4 0xFF84 # 0 +0x00C5 0xFF85 # 0 +0x00C6 0xFF86 # 0 +0x00C7 0xFF87 # 0 +0x00C8 0xFF88 # 0 +0x00C9 0xFF89 # 0 +0x00CA 0xFF8A # 0 +0x00CB 0xFF8B # 0 +0x00CC 0xFF8C # 0 +0x00CD 0xFF8D # 0 +0x00CE 0xFF8E # 0 +0x00CF 0xFF8F # 0 +0x00D0 0xFF90 # 0 +0x00D1 0xFF91 # 0 +0x00D2 0xFF92 # 0 +0x00D3 0xFF93 # 0 +0x00D4 0xFF94 # 0 +0x00D5 0xFF95 # 0 +0x00D6 0xFF96 # 0 +0x00D7 0xFF97 # 0 +0x00D8 0xFF98 # 0 +0x00D9 0xFF99 # 0 +0x00DA 0xFF9A # 0 +0x00DB 0xFF9B # 0 +0x00DC 0xFF9C # 0 +0x00DD 0xFF9D # 0 +0x00DE 0xFF9E # 0 +0x00DF 0xFF9F # 0 +0x00FD 0xF8F1 # 0 +0x00FE 0xF8F2 # 0 +0x00FF 0xF8F3 # 0 +0x8140 0x3000 # 0 +0x8141 0x3001 # 0 +0x8142 0x3002 # 0 +0x8143 0xFF0C # 0 +0x8144 0xFF0E # 0 +0x8145 0x30FB # 0 +0x8146 0xFF1A # 0 +0x8147 0xFF1B # 0 +0x8148 0xFF1F # 0 +0x8149 0xFF01 # 0 +0x814A 0x309B # 0 +0x814B 0x309C # 0 +0x814C 0x00B4 # 0 +0x814D 0xFF40 # 0 +0x814E 0x00A8 # 0 +0x814F 0xFF3E # 0 +0x8150 0xFFE3 # 0 +0x8151 0xFF3F # 0 +0x8152 0x30FD # 0 +0x8153 0x30FE # 0 +0x8154 0x309D # 0 +0x8155 0x309E # 0 +0x8156 0x3003 # 0 +0x8157 0x4EDD # 0 +0x8158 0x3005 # 0 +0x8159 0x3006 # 0 +0x815A 0x3007 # 0 +0x815B 0x30FC # 0 +0x815C 0x2015 # 0 +0x815D 0x2010 # 0 +0x815E 0xFF0F # 0 +0x815F 0xFF3C # 0 +0x8160 0xFF5E # 0 +0x8161 0x2225 # 0 +0x8162 0xFF5C # 0 +0x8163 0x2026 # 0 +0x8164 0x2025 # 0 +0x8165 0x2018 # 0 +0x8166 0x2019 # 0 +0x8167 0x201C # 0 +0x8168 0x201D # 0 +0x8169 0xFF08 # 0 +0x816A 0xFF09 # 0 +0x816B 0x3014 # 0 +0x816C 0x3015 # 0 +0x816D 0xFF3B # 0 +0x816E 0xFF3D # 0 +0x816F 0xFF5B # 0 +0x8170 0xFF5D # 0 +0x8171 0x3008 # 0 +0x8172 0x3009 # 0 +0x8173 0x300A # 0 +0x8174 0x300B # 0 +0x8175 0x300C # 0 +0x8176 0x300D # 0 +0x8177 0x300E # 0 +0x8178 0x300F # 0 +0x8179 0x3010 # 0 +0x817A 0x3011 # 0 +0x817B 0xFF0B # 0 +0x817C 0xFF0D # 0 +0x817D 0x00B1 # 0 +0x817E 0x00D7 # 0 +0x8180 0x00F7 # 0 +0x8181 0xFF1D # 0 +0x8182 0x2260 # 0 +0x8183 0xFF1C # 0 +0x8184 0xFF1E # 0 +0x8185 0x2266 # 0 +0x8186 0x2267 # 0 +0x8187 0x221E # 0 +0x8188 0x2234 # 0 +0x8189 0x2642 # 0 +0x818A 0x2640 # 0 +0x818B 0x00B0 # 0 +0x818C 0x2032 # 0 +0x818D 0x2033 # 0 +0x818E 0x2103 # 0 +0x818F 0xFFE5 # 0 +0x8190 0xFF04 # 0 +0x8191 0xFFE0 # 0 +0x8192 0xFFE1 # 0 +0x8193 0xFF05 # 0 +0x8194 0xFF03 # 0 +0x8195 0xFF06 # 0 +0x8196 0xFF0A # 0 +0x8197 0xFF20 # 0 +0x8198 0x00A7 # 0 +0x8199 0x2606 # 0 +0x819A 0x2605 # 0 +0x819B 0x25CB # 0 +0x819C 0x25CF # 0 +0x819D 0x25CE # 0 +0x819E 0x25C7 # 0 +0x819F 0x25C6 # 0 +0x81A0 0x25A1 # 0 +0x81A1 0x25A0 # 0 +0x81A2 0x25B3 # 0 +0x81A3 0x25B2 # 0 +0x81A4 0x25BD # 0 +0x81A5 0x25BC # 0 +0x81A6 0x203B # 0 +0x81A7 0x3012 # 0 +0x81A8 0x2192 # 0 +0x81A9 0x2190 # 0 +0x81AA 0x2191 # 0 +0x81AB 0x2193 # 0 +0x81AC 0x3013 # 0 +0x81B8 0x2208 # 0 +0x81B9 0x220B # 0 +0x81BA 0x2286 # 0 +0x81BB 0x2287 # 0 +0x81BC 0x2282 # 0 +0x81BD 0x2283 # 0 +0x81BE 0x222A # 0 +0x81BF 0x2229 # 0 +0x81C8 0x2227 # 0 +0x81C9 0x2228 # 0 +0x81CA 0xFFE2 # 0 +0x81CB 0x21D2 # 0 +0x81CC 0x21D4 # 0 +0x81CD 0x2200 # 0 +0x81CE 0x2203 # 0 +0x81DA 0x2220 # 0 +0x81DB 0x22A5 # 0 +0x81DC 0x2312 # 0 +0x81DD 0x2202 # 0 +0x81DE 0x2207 # 0 +0x81DF 0x2261 # 0 +0x81E0 0x2252 # 0 +0x81E1 0x226A # 0 +0x81E2 0x226B # 0 +0x81E3 0x221A # 0 +0x81E4 0x223D # 0 +0x81E5 0x221D # 0 +0x81E6 0x2235 # 0 +0x81E7 0x222B # 0 +0x81E8 0x222C # 0 +0x81F0 0x212B # 0 +0x81F1 0x2030 # 0 +0x81F2 0x266F # 0 +0x81F3 0x266D # 0 +0x81F4 0x266A # 0 +0x81F5 0x2020 # 0 +0x81F6 0x2021 # 0 +0x81F7 0x00B6 # 0 +0x81FC 0x25EF # 0 +0x824F 0xFF10 # 0 +0x8250 0xFF11 # 0 +0x8251 0xFF12 # 0 +0x8252 0xFF13 # 0 +0x8253 0xFF14 # 0 +0x8254 0xFF15 # 0 +0x8255 0xFF16 # 0 +0x8256 0xFF17 # 0 +0x8257 0xFF18 # 0 +0x8258 0xFF19 # 0 +0x8260 0xFF21 # 0 +0x8261 0xFF22 # 0 +0x8262 0xFF23 # 0 +0x8263 0xFF24 # 0 +0x8264 0xFF25 # 0 +0x8265 0xFF26 # 0 +0x8266 0xFF27 # 0 +0x8267 0xFF28 # 0 +0x8268 0xFF29 # 0 +0x8269 0xFF2A # 0 +0x826A 0xFF2B # 0 +0x826B 0xFF2C # 0 +0x826C 0xFF2D # 0 +0x826D 0xFF2E # 0 +0x826E 0xFF2F # 0 +0x826F 0xFF30 # 0 +0x8270 0xFF31 # 0 +0x8271 0xFF32 # 0 +0x8272 0xFF33 # 0 +0x8273 0xFF34 # 0 +0x8274 0xFF35 # 0 +0x8275 0xFF36 # 0 +0x8276 0xFF37 # 0 +0x8277 0xFF38 # 0 +0x8278 0xFF39 # 0 +0x8279 0xFF3A # 0 +0x8281 0xFF41 # 0 +0x8282 0xFF42 # 0 +0x8283 0xFF43 # 0 +0x8284 0xFF44 # 0 +0x8285 0xFF45 # 0 +0x8286 0xFF46 # 0 +0x8287 0xFF47 # 0 +0x8288 0xFF48 # 0 +0x8289 0xFF49 # 0 +0x828A 0xFF4A # 0 +0x828B 0xFF4B # 0 +0x828C 0xFF4C # 0 +0x828D 0xFF4D # 0 +0x828E 0xFF4E # 0 +0x828F 0xFF4F # 0 +0x8290 0xFF50 # 0 +0x8291 0xFF51 # 0 +0x8292 0xFF52 # 0 +0x8293 0xFF53 # 0 +0x8294 0xFF54 # 0 +0x8295 0xFF55 # 0 +0x8296 0xFF56 # 0 +0x8297 0xFF57 # 0 +0x8298 0xFF58 # 0 +0x8299 0xFF59 # 0 +0x829A 0xFF5A # 0 +0x829F 0x3041 # 0 +0x82A0 0x3042 # 0 +0x82A1 0x3043 # 0 +0x82A2 0x3044 # 0 +0x82A3 0x3045 # 0 +0x82A4 0x3046 # 0 +0x82A5 0x3047 # 0 +0x82A6 0x3048 # 0 +0x82A7 0x3049 # 0 +0x82A8 0x304A # 0 +0x82A9 0x304B # 0 +0x82AA 0x304C # 0 +0x82AB 0x304D # 0 +0x82AC 0x304E # 0 +0x82AD 0x304F # 0 +0x82AE 0x3050 # 0 +0x82AF 0x3051 # 0 +0x82B0 0x3052 # 0 +0x82B1 0x3053 # 0 +0x82B2 0x3054 # 0 +0x82B3 0x3055 # 0 +0x82B4 0x3056 # 0 +0x82B5 0x3057 # 0 +0x82B6 0x3058 # 0 +0x82B7 0x3059 # 0 +0x82B8 0x305A # 0 +0x82B9 0x305B # 0 +0x82BA 0x305C # 0 +0x82BB 0x305D # 0 +0x82BC 0x305E # 0 +0x82BD 0x305F # 0 +0x82BE 0x3060 # 0 +0x82BF 0x3061 # 0 +0x82C0 0x3062 # 0 +0x82C1 0x3063 # 0 +0x82C2 0x3064 # 0 +0x82C3 0x3065 # 0 +0x82C4 0x3066 # 0 +0x82C5 0x3067 # 0 +0x82C6 0x3068 # 0 +0x82C7 0x3069 # 0 +0x82C8 0x306A # 0 +0x82C9 0x306B # 0 +0x82CA 0x306C # 0 +0x82CB 0x306D # 0 +0x82CC 0x306E # 0 +0x82CD 0x306F # 0 +0x82CE 0x3070 # 0 +0x82CF 0x3071 # 0 +0x82D0 0x3072 # 0 +0x82D1 0x3073 # 0 +0x82D2 0x3074 # 0 +0x82D3 0x3075 # 0 +0x82D4 0x3076 # 0 +0x82D5 0x3077 # 0 +0x82D6 0x3078 # 0 +0x82D7 0x3079 # 0 +0x82D8 0x307A # 0 +0x82D9 0x307B # 0 +0x82DA 0x307C # 0 +0x82DB 0x307D # 0 +0x82DC 0x307E # 0 +0x82DD 0x307F # 0 +0x82DE 0x3080 # 0 +0x82DF 0x3081 # 0 +0x82E0 0x3082 # 0 +0x82E1 0x3083 # 0 +0x82E2 0x3084 # 0 +0x82E3 0x3085 # 0 +0x82E4 0x3086 # 0 +0x82E5 0x3087 # 0 +0x82E6 0x3088 # 0 +0x82E7 0x3089 # 0 +0x82E8 0x308A # 0 +0x82E9 0x308B # 0 +0x82EA 0x308C # 0 +0x82EB 0x308D # 0 +0x82EC 0x308E # 0 +0x82ED 0x308F # 0 +0x82EE 0x3090 # 0 +0x82EF 0x3091 # 0 +0x82F0 0x3092 # 0 +0x82F1 0x3093 # 0 +0x8340 0x30A1 # 0 +0x8341 0x30A2 # 0 +0x8342 0x30A3 # 0 +0x8343 0x30A4 # 0 +0x8344 0x30A5 # 0 +0x8345 0x30A6 # 0 +0x8346 0x30A7 # 0 +0x8347 0x30A8 # 0 +0x8348 0x30A9 # 0 +0x8349 0x30AA # 0 +0x834A 0x30AB # 0 +0x834B 0x30AC # 0 +0x834C 0x30AD # 0 +0x834D 0x30AE # 0 +0x834E 0x30AF # 0 +0x834F 0x30B0 # 0 +0x8350 0x30B1 # 0 +0x8351 0x30B2 # 0 +0x8352 0x30B3 # 0 +0x8353 0x30B4 # 0 +0x8354 0x30B5 # 0 +0x8355 0x30B6 # 0 +0x8356 0x30B7 # 0 +0x8357 0x30B8 # 0 +0x8358 0x30B9 # 0 +0x8359 0x30BA # 0 +0x835A 0x30BB # 0 +0x835B 0x30BC # 0 +0x835C 0x30BD # 0 +0x835D 0x30BE # 0 +0x835E 0x30BF # 0 +0x835F 0x30C0 # 0 +0x8360 0x30C1 # 0 +0x8361 0x30C2 # 0 +0x8362 0x30C3 # 0 +0x8363 0x30C4 # 0 +0x8364 0x30C5 # 0 +0x8365 0x30C6 # 0 +0x8366 0x30C7 # 0 +0x8367 0x30C8 # 0 +0x8368 0x30C9 # 0 +0x8369 0x30CA # 0 +0x836A 0x30CB # 0 +0x836B 0x30CC # 0 +0x836C 0x30CD # 0 +0x836D 0x30CE # 0 +0x836E 0x30CF # 0 +0x836F 0x30D0 # 0 +0x8370 0x30D1 # 0 +0x8371 0x30D2 # 0 +0x8372 0x30D3 # 0 +0x8373 0x30D4 # 0 +0x8374 0x30D5 # 0 +0x8375 0x30D6 # 0 +0x8376 0x30D7 # 0 +0x8377 0x30D8 # 0 +0x8378 0x30D9 # 0 +0x8379 0x30DA # 0 +0x837A 0x30DB # 0 +0x837B 0x30DC # 0 +0x837C 0x30DD # 0 +0x837D 0x30DE # 0 +0x837E 0x30DF # 0 +0x8380 0x30E0 # 0 +0x8381 0x30E1 # 0 +0x8382 0x30E2 # 0 +0x8383 0x30E3 # 0 +0x8384 0x30E4 # 0 +0x8385 0x30E5 # 0 +0x8386 0x30E6 # 0 +0x8387 0x30E7 # 0 +0x8388 0x30E8 # 0 +0x8389 0x30E9 # 0 +0x838A 0x30EA # 0 +0x838B 0x30EB # 0 +0x838C 0x30EC # 0 +0x838D 0x30ED # 0 +0x838E 0x30EE # 0 +0x838F 0x30EF # 0 +0x8390 0x30F0 # 0 +0x8391 0x30F1 # 0 +0x8392 0x30F2 # 0 +0x8393 0x30F3 # 0 +0x8394 0x30F4 # 0 +0x8395 0x30F5 # 0 +0x8396 0x30F6 # 0 +0x839F 0x0391 # 0 +0x83A0 0x0392 # 0 +0x83A1 0x0393 # 0 +0x83A2 0x0394 # 0 +0x83A3 0x0395 # 0 +0x83A4 0x0396 # 0 +0x83A5 0x0397 # 0 +0x83A6 0x0398 # 0 +0x83A7 0x0399 # 0 +0x83A8 0x039A # 0 +0x83A9 0x039B # 0 +0x83AA 0x039C # 0 +0x83AB 0x039D # 0 +0x83AC 0x039E # 0 +0x83AD 0x039F # 0 +0x83AE 0x03A0 # 0 +0x83AF 0x03A1 # 0 +0x83B0 0x03A3 # 0 +0x83B1 0x03A4 # 0 +0x83B2 0x03A5 # 0 +0x83B3 0x03A6 # 0 +0x83B4 0x03A7 # 0 +0x83B5 0x03A8 # 0 +0x83B6 0x03A9 # 0 +0x83BF 0x03B1 # 0 +0x83C0 0x03B2 # 0 +0x83C1 0x03B3 # 0 +0x83C2 0x03B4 # 0 +0x83C3 0x03B5 # 0 +0x83C4 0x03B6 # 0 +0x83C5 0x03B7 # 0 +0x83C6 0x03B8 # 0 +0x83C7 0x03B9 # 0 +0x83C8 0x03BA # 0 +0x83C9 0x03BB # 0 +0x83CA 0x03BC # 0 +0x83CB 0x03BD # 0 +0x83CC 0x03BE # 0 +0x83CD 0x03BF # 0 +0x83CE 0x03C0 # 0 +0x83CF 0x03C1 # 0 +0x83D0 0x03C3 # 0 +0x83D1 0x03C4 # 0 +0x83D2 0x03C5 # 0 +0x83D3 0x03C6 # 0 +0x83D4 0x03C7 # 0 +0x83D5 0x03C8 # 0 +0x83D6 0x03C9 # 0 +0x8440 0x0410 # 0 +0x8441 0x0411 # 0 +0x8442 0x0412 # 0 +0x8443 0x0413 # 0 +0x8444 0x0414 # 0 +0x8445 0x0415 # 0 +0x8446 0x0401 # 0 +0x8447 0x0416 # 0 +0x8448 0x0417 # 0 +0x8449 0x0418 # 0 +0x844A 0x0419 # 0 +0x844B 0x041A # 0 +0x844C 0x041B # 0 +0x844D 0x041C # 0 +0x844E 0x041D # 0 +0x844F 0x041E # 0 +0x8450 0x041F # 0 +0x8451 0x0420 # 0 +0x8452 0x0421 # 0 +0x8453 0x0422 # 0 +0x8454 0x0423 # 0 +0x8455 0x0424 # 0 +0x8456 0x0425 # 0 +0x8457 0x0426 # 0 +0x8458 0x0427 # 0 +0x8459 0x0428 # 0 +0x845A 0x0429 # 0 +0x845B 0x042A # 0 +0x845C 0x042B # 0 +0x845D 0x042C # 0 +0x845E 0x042D # 0 +0x845F 0x042E # 0 +0x8460 0x042F # 0 +0x8470 0x0430 # 0 +0x8471 0x0431 # 0 +0x8472 0x0432 # 0 +0x8473 0x0433 # 0 +0x8474 0x0434 # 0 +0x8475 0x0435 # 0 +0x8476 0x0451 # 0 +0x8477 0x0436 # 0 +0x8478 0x0437 # 0 +0x8479 0x0438 # 0 +0x847A 0x0439 # 0 +0x847B 0x043A # 0 +0x847C 0x043B # 0 +0x847D 0x043C # 0 +0x847E 0x043D # 0 +0x8480 0x043E # 0 +0x8481 0x043F # 0 +0x8482 0x0440 # 0 +0x8483 0x0441 # 0 +0x8484 0x0442 # 0 +0x8485 0x0443 # 0 +0x8486 0x0444 # 0 +0x8487 0x0445 # 0 +0x8488 0x0446 # 0 +0x8489 0x0447 # 0 +0x848A 0x0448 # 0 +0x848B 0x0449 # 0 +0x848C 0x044A # 0 +0x848D 0x044B # 0 +0x848E 0x044C # 0 +0x848F 0x044D # 0 +0x8490 0x044E # 0 +0x8491 0x044F # 0 +0x849F 0x2500 # 0 +0x84A0 0x2502 # 0 +0x84A1 0x250C # 0 +0x84A2 0x2510 # 0 +0x84A3 0x2518 # 0 +0x84A4 0x2514 # 0 +0x84A5 0x251C # 0 +0x84A6 0x252C # 0 +0x84A7 0x2524 # 0 +0x84A8 0x2534 # 0 +0x84A9 0x253C # 0 +0x84AA 0x2501 # 0 +0x84AB 0x2503 # 0 +0x84AC 0x250F # 0 +0x84AD 0x2513 # 0 +0x84AE 0x251B # 0 +0x84AF 0x2517 # 0 +0x84B0 0x2523 # 0 +0x84B1 0x2533 # 0 +0x84B2 0x252B # 0 +0x84B3 0x253B # 0 +0x84B4 0x254B # 0 +0x84B5 0x2520 # 0 +0x84B6 0x252F # 0 +0x84B7 0x2528 # 0 +0x84B8 0x2537 # 0 +0x84B9 0x253F # 0 +0x84BA 0x251D # 0 +0x84BB 0x2530 # 0 +0x84BC 0x2525 # 0 +0x84BD 0x2538 # 0 +0x84BE 0x2542 # 0 +0x8740 0x2460 # 0 +0x8741 0x2461 # 0 +0x8742 0x2462 # 0 +0x8743 0x2463 # 0 +0x8744 0x2464 # 0 +0x8745 0x2465 # 0 +0x8746 0x2466 # 0 +0x8747 0x2467 # 0 +0x8748 0x2468 # 0 +0x8749 0x2469 # 0 +0x874A 0x246A # 0 +0x874B 0x246B # 0 +0x874C 0x246C # 0 +0x874D 0x246D # 0 +0x874E 0x246E # 0 +0x874F 0x246F # 0 +0x8750 0x2470 # 0 +0x8751 0x2471 # 0 +0x8752 0x2472 # 0 +0x8753 0x2473 # 0 +0x8754 0x2160 # 0 +0x8755 0x2161 # 0 +0x8756 0x2162 # 0 +0x8757 0x2163 # 0 +0x8758 0x2164 # 0 +0x8759 0x2165 # 0 +0x875A 0x2166 # 0 +0x875B 0x2167 # 0 +0x875C 0x2168 # 0 +0x875D 0x2169 # 0 +0x875F 0x3349 # 0 +0x8760 0x3314 # 0 +0x8761 0x3322 # 0 +0x8762 0x334D # 0 +0x8763 0x3318 # 0 +0x8764 0x3327 # 0 +0x8765 0x3303 # 0 +0x8766 0x3336 # 0 +0x8767 0x3351 # 0 +0x8768 0x3357 # 0 +0x8769 0x330D # 0 +0x876A 0x3326 # 0 +0x876B 0x3323 # 0 +0x876C 0x332B # 0 +0x876D 0x334A # 0 +0x876E 0x333B # 0 +0x876F 0x339C # 0 +0x8770 0x339D # 0 +0x8771 0x339E # 0 +0x8772 0x338E # 0 +0x8773 0x338F # 0 +0x8774 0x33C4 # 0 +0x8775 0x33A1 # 0 +0x877E 0x337B # 0 +0x8780 0x301D # 0 +0x8781 0x301F # 0 +0x8782 0x2116 # 0 +0x8783 0x33CD # 0 +0x8784 0x2121 # 0 +0x8785 0x32A4 # 0 +0x8786 0x32A5 # 0 +0x8787 0x32A6 # 0 +0x8788 0x32A7 # 0 +0x8789 0x32A8 # 0 +0x878A 0x3231 # 0 +0x878B 0x3232 # 0 +0x878C 0x3239 # 0 +0x878D 0x337E # 0 +0x878E 0x337D # 0 +0x878F 0x337C # 0 +0x8793 0x222E # 0 +0x8794 0x2211 # 0 +0x8798 0x221F # 0 +0x8799 0x22BF # 0 +0x889F 0x4E9C # 0 +0x88A0 0x5516 # 0 +0x88A1 0x5A03 # 0 +0x88A2 0x963F # 0 +0x88A3 0x54C0 # 0 +0x88A4 0x611B # 0 +0x88A5 0x6328 # 0 +0x88A6 0x59F6 # 0 +0x88A7 0x9022 # 0 +0x88A8 0x8475 # 0 +0x88A9 0x831C # 0 +0x88AA 0x7A50 # 0 +0x88AB 0x60AA # 0 +0x88AC 0x63E1 # 0 +0x88AD 0x6E25 # 0 +0x88AE 0x65ED # 0 +0x88AF 0x8466 # 0 +0x88B0 0x82A6 # 0 +0x88B1 0x9BF5 # 0 +0x88B2 0x6893 # 0 +0x88B3 0x5727 # 0 +0x88B4 0x65A1 # 0 +0x88B5 0x6271 # 0 +0x88B6 0x5B9B # 0 +0x88B7 0x59D0 # 0 +0x88B8 0x867B # 0 +0x88B9 0x98F4 # 0 +0x88BA 0x7D62 # 0 +0x88BB 0x7DBE # 0 +0x88BC 0x9B8E # 0 +0x88BD 0x6216 # 0 +0x88BE 0x7C9F # 0 +0x88BF 0x88B7 # 0 +0x88C0 0x5B89 # 0 +0x88C1 0x5EB5 # 0 +0x88C2 0x6309 # 0 +0x88C3 0x6697 # 0 +0x88C4 0x6848 # 0 +0x88C5 0x95C7 # 0 +0x88C6 0x978D # 0 +0x88C7 0x674F # 0 +0x88C8 0x4EE5 # 0 +0x88C9 0x4F0A # 0 +0x88CA 0x4F4D # 0 +0x88CB 0x4F9D # 0 +0x88CC 0x5049 # 0 +0x88CD 0x56F2 # 0 +0x88CE 0x5937 # 0 +0x88CF 0x59D4 # 0 +0x88D0 0x5A01 # 0 +0x88D1 0x5C09 # 0 +0x88D2 0x60DF # 0 +0x88D3 0x610F # 0 +0x88D4 0x6170 # 0 +0x88D5 0x6613 # 0 +0x88D6 0x6905 # 0 +0x88D7 0x70BA # 0 +0x88D8 0x754F # 0 +0x88D9 0x7570 # 0 +0x88DA 0x79FB # 0 +0x88DB 0x7DAD # 0 +0x88DC 0x7DEF # 0 +0x88DD 0x80C3 # 0 +0x88DE 0x840E # 0 +0x88DF 0x8863 # 0 +0x88E0 0x8B02 # 0 +0x88E1 0x9055 # 0 +0x88E2 0x907A # 0 +0x88E3 0x533B # 0 +0x88E4 0x4E95 # 0 +0x88E5 0x4EA5 # 0 +0x88E6 0x57DF # 0 +0x88E7 0x80B2 # 0 +0x88E8 0x90C1 # 0 +0x88E9 0x78EF # 0 +0x88EA 0x4E00 # 0 +0x88EB 0x58F1 # 0 +0x88EC 0x6EA2 # 0 +0x88ED 0x9038 # 0 +0x88EE 0x7A32 # 0 +0x88EF 0x8328 # 0 +0x88F0 0x828B # 0 +0x88F1 0x9C2F # 0 +0x88F2 0x5141 # 0 +0x88F3 0x5370 # 0 +0x88F4 0x54BD # 0 +0x88F5 0x54E1 # 0 +0x88F6 0x56E0 # 0 +0x88F7 0x59FB # 0 +0x88F8 0x5F15 # 0 +0x88F9 0x98F2 # 0 +0x88FA 0x6DEB # 0 +0x88FB 0x80E4 # 0 +0x88FC 0x852D # 0 +0x8940 0x9662 # 0 +0x8941 0x9670 # 0 +0x8942 0x96A0 # 0 +0x8943 0x97FB # 0 +0x8944 0x540B # 0 +0x8945 0x53F3 # 0 +0x8946 0x5B87 # 0 +0x8947 0x70CF # 0 +0x8948 0x7FBD # 0 +0x8949 0x8FC2 # 0 +0x894A 0x96E8 # 0 +0x894B 0x536F # 0 +0x894C 0x9D5C # 0 +0x894D 0x7ABA # 0 +0x894E 0x4E11 # 0 +0x894F 0x7893 # 0 +0x8950 0x81FC # 0 +0x8951 0x6E26 # 0 +0x8952 0x5618 # 0 +0x8953 0x5504 # 0 +0x8954 0x6B1D # 0 +0x8955 0x851A # 0 +0x8956 0x9C3B # 0 +0x8957 0x59E5 # 0 +0x8958 0x53A9 # 0 +0x8959 0x6D66 # 0 +0x895A 0x74DC # 0 +0x895B 0x958F # 0 +0x895C 0x5642 # 0 +0x895D 0x4E91 # 0 +0x895E 0x904B # 0 +0x895F 0x96F2 # 0 +0x8960 0x834F # 0 +0x8961 0x990C # 0 +0x8962 0x53E1 # 0 +0x8963 0x55B6 # 0 +0x8964 0x5B30 # 0 +0x8965 0x5F71 # 0 +0x8966 0x6620 # 0 +0x8967 0x66F3 # 0 +0x8968 0x6804 # 0 +0x8969 0x6C38 # 0 +0x896A 0x6CF3 # 0 +0x896B 0x6D29 # 0 +0x896C 0x745B # 0 +0x896D 0x76C8 # 0 +0x896E 0x7A4E # 0 +0x896F 0x9834 # 0 +0x8970 0x82F1 # 0 +0x8971 0x885B # 0 +0x8972 0x8A60 # 0 +0x8973 0x92ED # 0 +0x8974 0x6DB2 # 0 +0x8975 0x75AB # 0 +0x8976 0x76CA # 0 +0x8977 0x99C5 # 0 +0x8978 0x60A6 # 0 +0x8979 0x8B01 # 0 +0x897A 0x8D8A # 0 +0x897B 0x95B2 # 0 +0x897C 0x698E # 0 +0x897D 0x53AD # 0 +0x897E 0x5186 # 0 +0x8980 0x5712 # 0 +0x8981 0x5830 # 0 +0x8982 0x5944 # 0 +0x8983 0x5BB4 # 0 +0x8984 0x5EF6 # 0 +0x8985 0x6028 # 0 +0x8986 0x63A9 # 0 +0x8987 0x63F4 # 0 +0x8988 0x6CBF # 0 +0x8989 0x6F14 # 0 +0x898A 0x708E # 0 +0x898B 0x7114 # 0 +0x898C 0x7159 # 0 +0x898D 0x71D5 # 0 +0x898E 0x733F # 0 +0x898F 0x7E01 # 0 +0x8990 0x8276 # 0 +0x8991 0x82D1 # 0 +0x8992 0x8597 # 0 +0x8993 0x9060 # 0 +0x8994 0x925B # 0 +0x8995 0x9D1B # 0 +0x8996 0x5869 # 0 +0x8997 0x65BC # 0 +0x8998 0x6C5A # 0 +0x8999 0x7525 # 0 +0x899A 0x51F9 # 0 +0x899B 0x592E # 0 +0x899C 0x5965 # 0 +0x899D 0x5F80 # 0 +0x899E 0x5FDC # 0 +0x899F 0x62BC # 0 +0x89A0 0x65FA # 0 +0x89A1 0x6A2A # 0 +0x89A2 0x6B27 # 0 +0x89A3 0x6BB4 # 0 +0x89A4 0x738B # 0 +0x89A5 0x7FC1 # 0 +0x89A6 0x8956 # 0 +0x89A7 0x9D2C # 0 +0x89A8 0x9D0E # 0 +0x89A9 0x9EC4 # 0 +0x89AA 0x5CA1 # 0 +0x89AB 0x6C96 # 0 +0x89AC 0x837B # 0 +0x89AD 0x5104 # 0 +0x89AE 0x5C4B # 0 +0x89AF 0x61B6 # 0 +0x89B0 0x81C6 # 0 +0x89B1 0x6876 # 0 +0x89B2 0x7261 # 0 +0x89B3 0x4E59 # 0 +0x89B4 0x4FFA # 0 +0x89B5 0x5378 # 0 +0x89B6 0x6069 # 0 +0x89B7 0x6E29 # 0 +0x89B8 0x7A4F # 0 +0x89B9 0x97F3 # 0 +0x89BA 0x4E0B # 0 +0x89BB 0x5316 # 0 +0x89BC 0x4EEE # 0 +0x89BD 0x4F55 # 0 +0x89BE 0x4F3D # 0 +0x89BF 0x4FA1 # 0 +0x89C0 0x4F73 # 0 +0x89C1 0x52A0 # 0 +0x89C2 0x53EF # 0 +0x89C3 0x5609 # 0 +0x89C4 0x590F # 0 +0x89C5 0x5AC1 # 0 +0x89C6 0x5BB6 # 0 +0x89C7 0x5BE1 # 0 +0x89C8 0x79D1 # 0 +0x89C9 0x6687 # 0 +0x89CA 0x679C # 0 +0x89CB 0x67B6 # 0 +0x89CC 0x6B4C # 0 +0x89CD 0x6CB3 # 0 +0x89CE 0x706B # 0 +0x89CF 0x73C2 # 0 +0x89D0 0x798D # 0 +0x89D1 0x79BE # 0 +0x89D2 0x7A3C # 0 +0x89D3 0x7B87 # 0 +0x89D4 0x82B1 # 0 +0x89D5 0x82DB # 0 +0x89D6 0x8304 # 0 +0x89D7 0x8377 # 0 +0x89D8 0x83EF # 0 +0x89D9 0x83D3 # 0 +0x89DA 0x8766 # 0 +0x89DB 0x8AB2 # 0 +0x89DC 0x5629 # 0 +0x89DD 0x8CA8 # 0 +0x89DE 0x8FE6 # 0 +0x89DF 0x904E # 0 +0x89E0 0x971E # 0 +0x89E1 0x868A # 0 +0x89E2 0x4FC4 # 0 +0x89E3 0x5CE8 # 0 +0x89E4 0x6211 # 0 +0x89E5 0x7259 # 0 +0x89E6 0x753B # 0 +0x89E7 0x81E5 # 0 +0x89E8 0x82BD # 0 +0x89E9 0x86FE # 0 +0x89EA 0x8CC0 # 0 +0x89EB 0x96C5 # 0 +0x89EC 0x9913 # 0 +0x89ED 0x99D5 # 0 +0x89EE 0x4ECB # 0 +0x89EF 0x4F1A # 0 +0x89F0 0x89E3 # 0 +0x89F1 0x56DE # 0 +0x89F2 0x584A # 0 +0x89F3 0x58CA # 0 +0x89F4 0x5EFB # 0 +0x89F5 0x5FEB # 0 +0x89F6 0x602A # 0 +0x89F7 0x6094 # 0 +0x89F8 0x6062 # 0 +0x89F9 0x61D0 # 0 +0x89FA 0x6212 # 0 +0x89FB 0x62D0 # 0 +0x89FC 0x6539 # 0 +0x8A40 0x9B41 # 0 +0x8A41 0x6666 # 0 +0x8A42 0x68B0 # 0 +0x8A43 0x6D77 # 0 +0x8A44 0x7070 # 0 +0x8A45 0x754C # 0 +0x8A46 0x7686 # 0 +0x8A47 0x7D75 # 0 +0x8A48 0x82A5 # 0 +0x8A49 0x87F9 # 0 +0x8A4A 0x958B # 0 +0x8A4B 0x968E # 0 +0x8A4C 0x8C9D # 0 +0x8A4D 0x51F1 # 0 +0x8A4E 0x52BE # 0 +0x8A4F 0x5916 # 0 +0x8A50 0x54B3 # 0 +0x8A51 0x5BB3 # 0 +0x8A52 0x5D16 # 0 +0x8A53 0x6168 # 0 +0x8A54 0x6982 # 0 +0x8A55 0x6DAF # 0 +0x8A56 0x788D # 0 +0x8A57 0x84CB # 0 +0x8A58 0x8857 # 0 +0x8A59 0x8A72 # 0 +0x8A5A 0x93A7 # 0 +0x8A5B 0x9AB8 # 0 +0x8A5C 0x6D6C # 0 +0x8A5D 0x99A8 # 0 +0x8A5E 0x86D9 # 0 +0x8A5F 0x57A3 # 0 +0x8A60 0x67FF # 0 +0x8A61 0x86CE # 0 +0x8A62 0x920E # 0 +0x8A63 0x5283 # 0 +0x8A64 0x5687 # 0 +0x8A65 0x5404 # 0 +0x8A66 0x5ED3 # 0 +0x8A67 0x62E1 # 0 +0x8A68 0x64B9 # 0 +0x8A69 0x683C # 0 +0x8A6A 0x6838 # 0 +0x8A6B 0x6BBB # 0 +0x8A6C 0x7372 # 0 +0x8A6D 0x78BA # 0 +0x8A6E 0x7A6B # 0 +0x8A6F 0x899A # 0 +0x8A70 0x89D2 # 0 +0x8A71 0x8D6B # 0 +0x8A72 0x8F03 # 0 +0x8A73 0x90ED # 0 +0x8A74 0x95A3 # 0 +0x8A75 0x9694 # 0 +0x8A76 0x9769 # 0 +0x8A77 0x5B66 # 0 +0x8A78 0x5CB3 # 0 +0x8A79 0x697D # 0 +0x8A7A 0x984D # 0 +0x8A7B 0x984E # 0 +0x8A7C 0x639B # 0 +0x8A7D 0x7B20 # 0 +0x8A7E 0x6A2B # 0 +0x8A80 0x6A7F # 0 +0x8A81 0x68B6 # 0 +0x8A82 0x9C0D # 0 +0x8A83 0x6F5F # 0 +0x8A84 0x5272 # 0 +0x8A85 0x559D # 0 +0x8A86 0x6070 # 0 +0x8A87 0x62EC # 0 +0x8A88 0x6D3B # 0 +0x8A89 0x6E07 # 0 +0x8A8A 0x6ED1 # 0 +0x8A8B 0x845B # 0 +0x8A8C 0x8910 # 0 +0x8A8D 0x8F44 # 0 +0x8A8E 0x4E14 # 0 +0x8A8F 0x9C39 # 0 +0x8A90 0x53F6 # 0 +0x8A91 0x691B # 0 +0x8A92 0x6A3A # 0 +0x8A93 0x9784 # 0 +0x8A94 0x682A # 0 +0x8A95 0x515C # 0 +0x8A96 0x7AC3 # 0 +0x8A97 0x84B2 # 0 +0x8A98 0x91DC # 0 +0x8A99 0x938C # 0 +0x8A9A 0x565B # 0 +0x8A9B 0x9D28 # 0 +0x8A9C 0x6822 # 0 +0x8A9D 0x8305 # 0 +0x8A9E 0x8431 # 0 +0x8A9F 0x7CA5 # 0 +0x8AA0 0x5208 # 0 +0x8AA1 0x82C5 # 0 +0x8AA2 0x74E6 # 0 +0x8AA3 0x4E7E # 0 +0x8AA4 0x4F83 # 0 +0x8AA5 0x51A0 # 0 +0x8AA6 0x5BD2 # 0 +0x8AA7 0x520A # 0 +0x8AA8 0x52D8 # 0 +0x8AA9 0x52E7 # 0 +0x8AAA 0x5DFB # 0 +0x8AAB 0x559A # 0 +0x8AAC 0x582A # 0 +0x8AAD 0x59E6 # 0 +0x8AAE 0x5B8C # 0 +0x8AAF 0x5B98 # 0 +0x8AB0 0x5BDB # 0 +0x8AB1 0x5E72 # 0 +0x8AB2 0x5E79 # 0 +0x8AB3 0x60A3 # 0 +0x8AB4 0x611F # 0 +0x8AB5 0x6163 # 0 +0x8AB6 0x61BE # 0 +0x8AB7 0x63DB # 0 +0x8AB8 0x6562 # 0 +0x8AB9 0x67D1 # 0 +0x8ABA 0x6853 # 0 +0x8ABB 0x68FA # 0 +0x8ABC 0x6B3E # 0 +0x8ABD 0x6B53 # 0 +0x8ABE 0x6C57 # 0 +0x8ABF 0x6F22 # 0 +0x8AC0 0x6F97 # 0 +0x8AC1 0x6F45 # 0 +0x8AC2 0x74B0 # 0 +0x8AC3 0x7518 # 0 +0x8AC4 0x76E3 # 0 +0x8AC5 0x770B # 0 +0x8AC6 0x7AFF # 0 +0x8AC7 0x7BA1 # 0 +0x8AC8 0x7C21 # 0 +0x8AC9 0x7DE9 # 0 +0x8ACA 0x7F36 # 0 +0x8ACB 0x7FF0 # 0 +0x8ACC 0x809D # 0 +0x8ACD 0x8266 # 0 +0x8ACE 0x839E # 0 +0x8ACF 0x89B3 # 0 +0x8AD0 0x8ACC # 0 +0x8AD1 0x8CAB # 0 +0x8AD2 0x9084 # 0 +0x8AD3 0x9451 # 0 +0x8AD4 0x9593 # 0 +0x8AD5 0x9591 # 0 +0x8AD6 0x95A2 # 0 +0x8AD7 0x9665 # 0 +0x8AD8 0x97D3 # 0 +0x8AD9 0x9928 # 0 +0x8ADA 0x8218 # 0 +0x8ADB 0x4E38 # 0 +0x8ADC 0x542B # 0 +0x8ADD 0x5CB8 # 0 +0x8ADE 0x5DCC # 0 +0x8ADF 0x73A9 # 0 +0x8AE0 0x764C # 0 +0x8AE1 0x773C # 0 +0x8AE2 0x5CA9 # 0 +0x8AE3 0x7FEB # 0 +0x8AE4 0x8D0B # 0 +0x8AE5 0x96C1 # 0 +0x8AE6 0x9811 # 0 +0x8AE7 0x9854 # 0 +0x8AE8 0x9858 # 0 +0x8AE9 0x4F01 # 0 +0x8AEA 0x4F0E # 0 +0x8AEB 0x5371 # 0 +0x8AEC 0x559C # 0 +0x8AED 0x5668 # 0 +0x8AEE 0x57FA # 0 +0x8AEF 0x5947 # 0 +0x8AF0 0x5B09 # 0 +0x8AF1 0x5BC4 # 0 +0x8AF2 0x5C90 # 0 +0x8AF3 0x5E0C # 0 +0x8AF4 0x5E7E # 0 +0x8AF5 0x5FCC # 0 +0x8AF6 0x63EE # 0 +0x8AF7 0x673A # 0 +0x8AF8 0x65D7 # 0 +0x8AF9 0x65E2 # 0 +0x8AFA 0x671F # 0 +0x8AFB 0x68CB # 0 +0x8AFC 0x68C4 # 0 +0x8B40 0x6A5F # 0 +0x8B41 0x5E30 # 0 +0x8B42 0x6BC5 # 0 +0x8B43 0x6C17 # 0 +0x8B44 0x6C7D # 0 +0x8B45 0x757F # 0 +0x8B46 0x7948 # 0 +0x8B47 0x5B63 # 0 +0x8B48 0x7A00 # 0 +0x8B49 0x7D00 # 0 +0x8B4A 0x5FBD # 0 +0x8B4B 0x898F # 0 +0x8B4C 0x8A18 # 0 +0x8B4D 0x8CB4 # 0 +0x8B4E 0x8D77 # 0 +0x8B4F 0x8ECC # 0 +0x8B50 0x8F1D # 0 +0x8B51 0x98E2 # 0 +0x8B52 0x9A0E # 0 +0x8B53 0x9B3C # 0 +0x8B54 0x4E80 # 0 +0x8B55 0x507D # 0 +0x8B56 0x5100 # 0 +0x8B57 0x5993 # 0 +0x8B58 0x5B9C # 0 +0x8B59 0x622F # 0 +0x8B5A 0x6280 # 0 +0x8B5B 0x64EC # 0 +0x8B5C 0x6B3A # 0 +0x8B5D 0x72A0 # 0 +0x8B5E 0x7591 # 0 +0x8B5F 0x7947 # 0 +0x8B60 0x7FA9 # 0 +0x8B61 0x87FB # 0 +0x8B62 0x8ABC # 0 +0x8B63 0x8B70 # 0 +0x8B64 0x63AC # 0 +0x8B65 0x83CA # 0 +0x8B66 0x97A0 # 0 +0x8B67 0x5409 # 0 +0x8B68 0x5403 # 0 +0x8B69 0x55AB # 0 +0x8B6A 0x6854 # 0 +0x8B6B 0x6A58 # 0 +0x8B6C 0x8A70 # 0 +0x8B6D 0x7827 # 0 +0x8B6E 0x6775 # 0 +0x8B6F 0x9ECD # 0 +0x8B70 0x5374 # 0 +0x8B71 0x5BA2 # 0 +0x8B72 0x811A # 0 +0x8B73 0x8650 # 0 +0x8B74 0x9006 # 0 +0x8B75 0x4E18 # 0 +0x8B76 0x4E45 # 0 +0x8B77 0x4EC7 # 0 +0x8B78 0x4F11 # 0 +0x8B79 0x53CA # 0 +0x8B7A 0x5438 # 0 +0x8B7B 0x5BAE # 0 +0x8B7C 0x5F13 # 0 +0x8B7D 0x6025 # 0 +0x8B7E 0x6551 # 0 +0x8B80 0x673D # 0 +0x8B81 0x6C42 # 0 +0x8B82 0x6C72 # 0 +0x8B83 0x6CE3 # 0 +0x8B84 0x7078 # 0 +0x8B85 0x7403 # 0 +0x8B86 0x7A76 # 0 +0x8B87 0x7AAE # 0 +0x8B88 0x7B08 # 0 +0x8B89 0x7D1A # 0 +0x8B8A 0x7CFE # 0 +0x8B8B 0x7D66 # 0 +0x8B8C 0x65E7 # 0 +0x8B8D 0x725B # 0 +0x8B8E 0x53BB # 0 +0x8B8F 0x5C45 # 0 +0x8B90 0x5DE8 # 0 +0x8B91 0x62D2 # 0 +0x8B92 0x62E0 # 0 +0x8B93 0x6319 # 0 +0x8B94 0x6E20 # 0 +0x8B95 0x865A # 0 +0x8B96 0x8A31 # 0 +0x8B97 0x8DDD # 0 +0x8B98 0x92F8 # 0 +0x8B99 0x6F01 # 0 +0x8B9A 0x79A6 # 0 +0x8B9B 0x9B5A # 0 +0x8B9C 0x4EA8 # 0 +0x8B9D 0x4EAB # 0 +0x8B9E 0x4EAC # 0 +0x8B9F 0x4F9B # 0 +0x8BA0 0x4FA0 # 0 +0x8BA1 0x50D1 # 0 +0x8BA2 0x5147 # 0 +0x8BA3 0x7AF6 # 0 +0x8BA4 0x5171 # 0 +0x8BA5 0x51F6 # 0 +0x8BA6 0x5354 # 0 +0x8BA7 0x5321 # 0 +0x8BA8 0x537F # 0 +0x8BA9 0x53EB # 0 +0x8BAA 0x55AC # 0 +0x8BAB 0x5883 # 0 +0x8BAC 0x5CE1 # 0 +0x8BAD 0x5F37 # 0 +0x8BAE 0x5F4A # 0 +0x8BAF 0x602F # 0 +0x8BB0 0x6050 # 0 +0x8BB1 0x606D # 0 +0x8BB2 0x631F # 0 +0x8BB3 0x6559 # 0 +0x8BB4 0x6A4B # 0 +0x8BB5 0x6CC1 # 0 +0x8BB6 0x72C2 # 0 +0x8BB7 0x72ED # 0 +0x8BB8 0x77EF # 0 +0x8BB9 0x80F8 # 0 +0x8BBA 0x8105 # 0 +0x8BBB 0x8208 # 0 +0x8BBC 0x854E # 0 +0x8BBD 0x90F7 # 0 +0x8BBE 0x93E1 # 0 +0x8BBF 0x97FF # 0 +0x8BC0 0x9957 # 0 +0x8BC1 0x9A5A # 0 +0x8BC2 0x4EF0 # 0 +0x8BC3 0x51DD # 0 +0x8BC4 0x5C2D # 0 +0x8BC5 0x6681 # 0 +0x8BC6 0x696D # 0 +0x8BC7 0x5C40 # 0 +0x8BC8 0x66F2 # 0 +0x8BC9 0x6975 # 0 +0x8BCA 0x7389 # 0 +0x8BCB 0x6850 # 0 +0x8BCC 0x7C81 # 0 +0x8BCD 0x50C5 # 0 +0x8BCE 0x52E4 # 0 +0x8BCF 0x5747 # 0 +0x8BD0 0x5DFE # 0 +0x8BD1 0x9326 # 0 +0x8BD2 0x65A4 # 0 +0x8BD3 0x6B23 # 0 +0x8BD4 0x6B3D # 0 +0x8BD5 0x7434 # 0 +0x8BD6 0x7981 # 0 +0x8BD7 0x79BD # 0 +0x8BD8 0x7B4B # 0 +0x8BD9 0x7DCA # 0 +0x8BDA 0x82B9 # 0 +0x8BDB 0x83CC # 0 +0x8BDC 0x887F # 0 +0x8BDD 0x895F # 0 +0x8BDE 0x8B39 # 0 +0x8BDF 0x8FD1 # 0 +0x8BE0 0x91D1 # 0 +0x8BE1 0x541F # 0 +0x8BE2 0x9280 # 0 +0x8BE3 0x4E5D # 0 +0x8BE4 0x5036 # 0 +0x8BE5 0x53E5 # 0 +0x8BE6 0x533A # 0 +0x8BE7 0x72D7 # 0 +0x8BE8 0x7396 # 0 +0x8BE9 0x77E9 # 0 +0x8BEA 0x82E6 # 0 +0x8BEB 0x8EAF # 0 +0x8BEC 0x99C6 # 0 +0x8BED 0x99C8 # 0 +0x8BEE 0x99D2 # 0 +0x8BEF 0x5177 # 0 +0x8BF0 0x611A # 0 +0x8BF1 0x865E # 0 +0x8BF2 0x55B0 # 0 +0x8BF3 0x7A7A # 0 +0x8BF4 0x5076 # 0 +0x8BF5 0x5BD3 # 0 +0x8BF6 0x9047 # 0 +0x8BF7 0x9685 # 0 +0x8BF8 0x4E32 # 0 +0x8BF9 0x6ADB # 0 +0x8BFA 0x91E7 # 0 +0x8BFB 0x5C51 # 0 +0x8BFC 0x5C48 # 0 +0x8C40 0x6398 # 0 +0x8C41 0x7A9F # 0 +0x8C42 0x6C93 # 0 +0x8C43 0x9774 # 0 +0x8C44 0x8F61 # 0 +0x8C45 0x7AAA # 0 +0x8C46 0x718A # 0 +0x8C47 0x9688 # 0 +0x8C48 0x7C82 # 0 +0x8C49 0x6817 # 0 +0x8C4A 0x7E70 # 0 +0x8C4B 0x6851 # 0 +0x8C4C 0x936C # 0 +0x8C4D 0x52F2 # 0 +0x8C4E 0x541B # 0 +0x8C4F 0x85AB # 0 +0x8C50 0x8A13 # 0 +0x8C51 0x7FA4 # 0 +0x8C52 0x8ECD # 0 +0x8C53 0x90E1 # 0 +0x8C54 0x5366 # 0 +0x8C55 0x8888 # 0 +0x8C56 0x7941 # 0 +0x8C57 0x4FC2 # 0 +0x8C58 0x50BE # 0 +0x8C59 0x5211 # 0 +0x8C5A 0x5144 # 0 +0x8C5B 0x5553 # 0 +0x8C5C 0x572D # 0 +0x8C5D 0x73EA # 0 +0x8C5E 0x578B # 0 +0x8C5F 0x5951 # 0 +0x8C60 0x5F62 # 0 +0x8C61 0x5F84 # 0 +0x8C62 0x6075 # 0 +0x8C63 0x6176 # 0 +0x8C64 0x6167 # 0 +0x8C65 0x61A9 # 0 +0x8C66 0x63B2 # 0 +0x8C67 0x643A # 0 +0x8C68 0x656C # 0 +0x8C69 0x666F # 0 +0x8C6A 0x6842 # 0 +0x8C6B 0x6E13 # 0 +0x8C6C 0x7566 # 0 +0x8C6D 0x7A3D # 0 +0x8C6E 0x7CFB # 0 +0x8C6F 0x7D4C # 0 +0x8C70 0x7D99 # 0 +0x8C71 0x7E4B # 0 +0x8C72 0x7F6B # 0 +0x8C73 0x830E # 0 +0x8C74 0x834A # 0 +0x8C75 0x86CD # 0 +0x8C76 0x8A08 # 0 +0x8C77 0x8A63 # 0 +0x8C78 0x8B66 # 0 +0x8C79 0x8EFD # 0 +0x8C7A 0x981A # 0 +0x8C7B 0x9D8F # 0 +0x8C7C 0x82B8 # 0 +0x8C7D 0x8FCE # 0 +0x8C7E 0x9BE8 # 0 +0x8C80 0x5287 # 0 +0x8C81 0x621F # 0 +0x8C82 0x6483 # 0 +0x8C83 0x6FC0 # 0 +0x8C84 0x9699 # 0 +0x8C85 0x6841 # 0 +0x8C86 0x5091 # 0 +0x8C87 0x6B20 # 0 +0x8C88 0x6C7A # 0 +0x8C89 0x6F54 # 0 +0x8C8A 0x7A74 # 0 +0x8C8B 0x7D50 # 0 +0x8C8C 0x8840 # 0 +0x8C8D 0x8A23 # 0 +0x8C8E 0x6708 # 0 +0x8C8F 0x4EF6 # 0 +0x8C90 0x5039 # 0 +0x8C91 0x5026 # 0 +0x8C92 0x5065 # 0 +0x8C93 0x517C # 0 +0x8C94 0x5238 # 0 +0x8C95 0x5263 # 0 +0x8C96 0x55A7 # 0 +0x8C97 0x570F # 0 +0x8C98 0x5805 # 0 +0x8C99 0x5ACC # 0 +0x8C9A 0x5EFA # 0 +0x8C9B 0x61B2 # 0 +0x8C9C 0x61F8 # 0 +0x8C9D 0x62F3 # 0 +0x8C9E 0x6372 # 0 +0x8C9F 0x691C # 0 +0x8CA0 0x6A29 # 0 +0x8CA1 0x727D # 0 +0x8CA2 0x72AC # 0 +0x8CA3 0x732E # 0 +0x8CA4 0x7814 # 0 +0x8CA5 0x786F # 0 +0x8CA6 0x7D79 # 0 +0x8CA7 0x770C # 0 +0x8CA8 0x80A9 # 0 +0x8CA9 0x898B # 0 +0x8CAA 0x8B19 # 0 +0x8CAB 0x8CE2 # 0 +0x8CAC 0x8ED2 # 0 +0x8CAD 0x9063 # 0 +0x8CAE 0x9375 # 0 +0x8CAF 0x967A # 0 +0x8CB0 0x9855 # 0 +0x8CB1 0x9A13 # 0 +0x8CB2 0x9E78 # 0 +0x8CB3 0x5143 # 0 +0x8CB4 0x539F # 0 +0x8CB5 0x53B3 # 0 +0x8CB6 0x5E7B # 0 +0x8CB7 0x5F26 # 0 +0x8CB8 0x6E1B # 0 +0x8CB9 0x6E90 # 0 +0x8CBA 0x7384 # 0 +0x8CBB 0x73FE # 0 +0x8CBC 0x7D43 # 0 +0x8CBD 0x8237 # 0 +0x8CBE 0x8A00 # 0 +0x8CBF 0x8AFA # 0 +0x8CC0 0x9650 # 0 +0x8CC1 0x4E4E # 0 +0x8CC2 0x500B # 0 +0x8CC3 0x53E4 # 0 +0x8CC4 0x547C # 0 +0x8CC5 0x56FA # 0 +0x8CC6 0x59D1 # 0 +0x8CC7 0x5B64 # 0 +0x8CC8 0x5DF1 # 0 +0x8CC9 0x5EAB # 0 +0x8CCA 0x5F27 # 0 +0x8CCB 0x6238 # 0 +0x8CCC 0x6545 # 0 +0x8CCD 0x67AF # 0 +0x8CCE 0x6E56 # 0 +0x8CCF 0x72D0 # 0 +0x8CD0 0x7CCA # 0 +0x8CD1 0x88B4 # 0 +0x8CD2 0x80A1 # 0 +0x8CD3 0x80E1 # 0 +0x8CD4 0x83F0 # 0 +0x8CD5 0x864E # 0 +0x8CD6 0x8A87 # 0 +0x8CD7 0x8DE8 # 0 +0x8CD8 0x9237 # 0 +0x8CD9 0x96C7 # 0 +0x8CDA 0x9867 # 0 +0x8CDB 0x9F13 # 0 +0x8CDC 0x4E94 # 0 +0x8CDD 0x4E92 # 0 +0x8CDE 0x4F0D # 0 +0x8CDF 0x5348 # 0 +0x8CE0 0x5449 # 0 +0x8CE1 0x543E # 0 +0x8CE2 0x5A2F # 0 +0x8CE3 0x5F8C # 0 +0x8CE4 0x5FA1 # 0 +0x8CE5 0x609F # 0 +0x8CE6 0x68A7 # 0 +0x8CE7 0x6A8E # 0 +0x8CE8 0x745A # 0 +0x8CE9 0x7881 # 0 +0x8CEA 0x8A9E # 0 +0x8CEB 0x8AA4 # 0 +0x8CEC 0x8B77 # 0 +0x8CED 0x9190 # 0 +0x8CEE 0x4E5E # 0 +0x8CEF 0x9BC9 # 0 +0x8CF0 0x4EA4 # 0 +0x8CF1 0x4F7C # 0 +0x8CF2 0x4FAF # 0 +0x8CF3 0x5019 # 0 +0x8CF4 0x5016 # 0 +0x8CF5 0x5149 # 0 +0x8CF6 0x516C # 0 +0x8CF7 0x529F # 0 +0x8CF8 0x52B9 # 0 +0x8CF9 0x52FE # 0 +0x8CFA 0x539A # 0 +0x8CFB 0x53E3 # 0 +0x8CFC 0x5411 # 0 +0x8D40 0x540E # 0 +0x8D41 0x5589 # 0 +0x8D42 0x5751 # 0 +0x8D43 0x57A2 # 0 +0x8D44 0x597D # 0 +0x8D45 0x5B54 # 0 +0x8D46 0x5B5D # 0 +0x8D47 0x5B8F # 0 +0x8D48 0x5DE5 # 0 +0x8D49 0x5DE7 # 0 +0x8D4A 0x5DF7 # 0 +0x8D4B 0x5E78 # 0 +0x8D4C 0x5E83 # 0 +0x8D4D 0x5E9A # 0 +0x8D4E 0x5EB7 # 0 +0x8D4F 0x5F18 # 0 +0x8D50 0x6052 # 0 +0x8D51 0x614C # 0 +0x8D52 0x6297 # 0 +0x8D53 0x62D8 # 0 +0x8D54 0x63A7 # 0 +0x8D55 0x653B # 0 +0x8D56 0x6602 # 0 +0x8D57 0x6643 # 0 +0x8D58 0x66F4 # 0 +0x8D59 0x676D # 0 +0x8D5A 0x6821 # 0 +0x8D5B 0x6897 # 0 +0x8D5C 0x69CB # 0 +0x8D5D 0x6C5F # 0 +0x8D5E 0x6D2A # 0 +0x8D5F 0x6D69 # 0 +0x8D60 0x6E2F # 0 +0x8D61 0x6E9D # 0 +0x8D62 0x7532 # 0 +0x8D63 0x7687 # 0 +0x8D64 0x786C # 0 +0x8D65 0x7A3F # 0 +0x8D66 0x7CE0 # 0 +0x8D67 0x7D05 # 0 +0x8D68 0x7D18 # 0 +0x8D69 0x7D5E # 0 +0x8D6A 0x7DB1 # 0 +0x8D6B 0x8015 # 0 +0x8D6C 0x8003 # 0 +0x8D6D 0x80AF # 0 +0x8D6E 0x80B1 # 0 +0x8D6F 0x8154 # 0 +0x8D70 0x818F # 0 +0x8D71 0x822A # 0 +0x8D72 0x8352 # 0 +0x8D73 0x884C # 0 +0x8D74 0x8861 # 0 +0x8D75 0x8B1B # 0 +0x8D76 0x8CA2 # 0 +0x8D77 0x8CFC # 0 +0x8D78 0x90CA # 0 +0x8D79 0x9175 # 0 +0x8D7A 0x9271 # 0 +0x8D7B 0x783F # 0 +0x8D7C 0x92FC # 0 +0x8D7D 0x95A4 # 0 +0x8D7E 0x964D # 0 +0x8D80 0x9805 # 0 +0x8D81 0x9999 # 0 +0x8D82 0x9AD8 # 0 +0x8D83 0x9D3B # 0 +0x8D84 0x525B # 0 +0x8D85 0x52AB # 0 +0x8D86 0x53F7 # 0 +0x8D87 0x5408 # 0 +0x8D88 0x58D5 # 0 +0x8D89 0x62F7 # 0 +0x8D8A 0x6FE0 # 0 +0x8D8B 0x8C6A # 0 +0x8D8C 0x8F5F # 0 +0x8D8D 0x9EB9 # 0 +0x8D8E 0x514B # 0 +0x8D8F 0x523B # 0 +0x8D90 0x544A # 0 +0x8D91 0x56FD # 0 +0x8D92 0x7A40 # 0 +0x8D93 0x9177 # 0 +0x8D94 0x9D60 # 0 +0x8D95 0x9ED2 # 0 +0x8D96 0x7344 # 0 +0x8D97 0x6F09 # 0 +0x8D98 0x8170 # 0 +0x8D99 0x7511 # 0 +0x8D9A 0x5FFD # 0 +0x8D9B 0x60DA # 0 +0x8D9C 0x9AA8 # 0 +0x8D9D 0x72DB # 0 +0x8D9E 0x8FBC # 0 +0x8D9F 0x6B64 # 0 +0x8DA0 0x9803 # 0 +0x8DA1 0x4ECA # 0 +0x8DA2 0x56F0 # 0 +0x8DA3 0x5764 # 0 +0x8DA4 0x58BE # 0 +0x8DA5 0x5A5A # 0 +0x8DA6 0x6068 # 0 +0x8DA7 0x61C7 # 0 +0x8DA8 0x660F # 0 +0x8DA9 0x6606 # 0 +0x8DAA 0x6839 # 0 +0x8DAB 0x68B1 # 0 +0x8DAC 0x6DF7 # 0 +0x8DAD 0x75D5 # 0 +0x8DAE 0x7D3A # 0 +0x8DAF 0x826E # 0 +0x8DB0 0x9B42 # 0 +0x8DB1 0x4E9B # 0 +0x8DB2 0x4F50 # 0 +0x8DB3 0x53C9 # 0 +0x8DB4 0x5506 # 0 +0x8DB5 0x5D6F # 0 +0x8DB6 0x5DE6 # 0 +0x8DB7 0x5DEE # 0 +0x8DB8 0x67FB # 0 +0x8DB9 0x6C99 # 0 +0x8DBA 0x7473 # 0 +0x8DBB 0x7802 # 0 +0x8DBC 0x8A50 # 0 +0x8DBD 0x9396 # 0 +0x8DBE 0x88DF # 0 +0x8DBF 0x5750 # 0 +0x8DC0 0x5EA7 # 0 +0x8DC1 0x632B # 0 +0x8DC2 0x50B5 # 0 +0x8DC3 0x50AC # 0 +0x8DC4 0x518D # 0 +0x8DC5 0x6700 # 0 +0x8DC6 0x54C9 # 0 +0x8DC7 0x585E # 0 +0x8DC8 0x59BB # 0 +0x8DC9 0x5BB0 # 0 +0x8DCA 0x5F69 # 0 +0x8DCB 0x624D # 0 +0x8DCC 0x63A1 # 0 +0x8DCD 0x683D # 0 +0x8DCE 0x6B73 # 0 +0x8DCF 0x6E08 # 0 +0x8DD0 0x707D # 0 +0x8DD1 0x91C7 # 0 +0x8DD2 0x7280 # 0 +0x8DD3 0x7815 # 0 +0x8DD4 0x7826 # 0 +0x8DD5 0x796D # 0 +0x8DD6 0x658E # 0 +0x8DD7 0x7D30 # 0 +0x8DD8 0x83DC # 0 +0x8DD9 0x88C1 # 0 +0x8DDA 0x8F09 # 0 +0x8DDB 0x969B # 0 +0x8DDC 0x5264 # 0 +0x8DDD 0x5728 # 0 +0x8DDE 0x6750 # 0 +0x8DDF 0x7F6A # 0 +0x8DE0 0x8CA1 # 0 +0x8DE1 0x51B4 # 0 +0x8DE2 0x5742 # 0 +0x8DE3 0x962A # 0 +0x8DE4 0x583A # 0 +0x8DE5 0x698A # 0 +0x8DE6 0x80B4 # 0 +0x8DE7 0x54B2 # 0 +0x8DE8 0x5D0E # 0 +0x8DE9 0x57FC # 0 +0x8DEA 0x7895 # 0 +0x8DEB 0x9DFA # 0 +0x8DEC 0x4F5C # 0 +0x8DED 0x524A # 0 +0x8DEE 0x548B # 0 +0x8DEF 0x643E # 0 +0x8DF0 0x6628 # 0 +0x8DF1 0x6714 # 0 +0x8DF2 0x67F5 # 0 +0x8DF3 0x7A84 # 0 +0x8DF4 0x7B56 # 0 +0x8DF5 0x7D22 # 0 +0x8DF6 0x932F # 0 +0x8DF7 0x685C # 0 +0x8DF8 0x9BAD # 0 +0x8DF9 0x7B39 # 0 +0x8DFA 0x5319 # 0 +0x8DFB 0x518A # 0 +0x8DFC 0x5237 # 0 +0x8E40 0x5BDF # 0 +0x8E41 0x62F6 # 0 +0x8E42 0x64AE # 0 +0x8E43 0x64E6 # 0 +0x8E44 0x672D # 0 +0x8E45 0x6BBA # 0 +0x8E46 0x85A9 # 0 +0x8E47 0x96D1 # 0 +0x8E48 0x7690 # 0 +0x8E49 0x9BD6 # 0 +0x8E4A 0x634C # 0 +0x8E4B 0x9306 # 0 +0x8E4C 0x9BAB # 0 +0x8E4D 0x76BF # 0 +0x8E4E 0x6652 # 0 +0x8E4F 0x4E09 # 0 +0x8E50 0x5098 # 0 +0x8E51 0x53C2 # 0 +0x8E52 0x5C71 # 0 +0x8E53 0x60E8 # 0 +0x8E54 0x6492 # 0 +0x8E55 0x6563 # 0 +0x8E56 0x685F # 0 +0x8E57 0x71E6 # 0 +0x8E58 0x73CA # 0 +0x8E59 0x7523 # 0 +0x8E5A 0x7B97 # 0 +0x8E5B 0x7E82 # 0 +0x8E5C 0x8695 # 0 +0x8E5D 0x8B83 # 0 +0x8E5E 0x8CDB # 0 +0x8E5F 0x9178 # 0 +0x8E60 0x9910 # 0 +0x8E61 0x65AC # 0 +0x8E62 0x66AB # 0 +0x8E63 0x6B8B # 0 +0x8E64 0x4ED5 # 0 +0x8E65 0x4ED4 # 0 +0x8E66 0x4F3A # 0 +0x8E67 0x4F7F # 0 +0x8E68 0x523A # 0 +0x8E69 0x53F8 # 0 +0x8E6A 0x53F2 # 0 +0x8E6B 0x55E3 # 0 +0x8E6C 0x56DB # 0 +0x8E6D 0x58EB # 0 +0x8E6E 0x59CB # 0 +0x8E6F 0x59C9 # 0 +0x8E70 0x59FF # 0 +0x8E71 0x5B50 # 0 +0x8E72 0x5C4D # 0 +0x8E73 0x5E02 # 0 +0x8E74 0x5E2B # 0 +0x8E75 0x5FD7 # 0 +0x8E76 0x601D # 0 +0x8E77 0x6307 # 0 +0x8E78 0x652F # 0 +0x8E79 0x5B5C # 0 +0x8E7A 0x65AF # 0 +0x8E7B 0x65BD # 0 +0x8E7C 0x65E8 # 0 +0x8E7D 0x679D # 0 +0x8E7E 0x6B62 # 0 +0x8E80 0x6B7B # 0 +0x8E81 0x6C0F # 0 +0x8E82 0x7345 # 0 +0x8E83 0x7949 # 0 +0x8E84 0x79C1 # 0 +0x8E85 0x7CF8 # 0 +0x8E86 0x7D19 # 0 +0x8E87 0x7D2B # 0 +0x8E88 0x80A2 # 0 +0x8E89 0x8102 # 0 +0x8E8A 0x81F3 # 0 +0x8E8B 0x8996 # 0 +0x8E8C 0x8A5E # 0 +0x8E8D 0x8A69 # 0 +0x8E8E 0x8A66 # 0 +0x8E8F 0x8A8C # 0 +0x8E90 0x8AEE # 0 +0x8E91 0x8CC7 # 0 +0x8E92 0x8CDC # 0 +0x8E93 0x96CC # 0 +0x8E94 0x98FC # 0 +0x8E95 0x6B6F # 0 +0x8E96 0x4E8B # 0 +0x8E97 0x4F3C # 0 +0x8E98 0x4F8D # 0 +0x8E99 0x5150 # 0 +0x8E9A 0x5B57 # 0 +0x8E9B 0x5BFA # 0 +0x8E9C 0x6148 # 0 +0x8E9D 0x6301 # 0 +0x8E9E 0x6642 # 0 +0x8E9F 0x6B21 # 0 +0x8EA0 0x6ECB # 0 +0x8EA1 0x6CBB # 0 +0x8EA2 0x723E # 0 +0x8EA3 0x74BD # 0 +0x8EA4 0x75D4 # 0 +0x8EA5 0x78C1 # 0 +0x8EA6 0x793A # 0 +0x8EA7 0x800C # 0 +0x8EA8 0x8033 # 0 +0x8EA9 0x81EA # 0 +0x8EAA 0x8494 # 0 +0x8EAB 0x8F9E # 0 +0x8EAC 0x6C50 # 0 +0x8EAD 0x9E7F # 0 +0x8EAE 0x5F0F # 0 +0x8EAF 0x8B58 # 0 +0x8EB0 0x9D2B # 0 +0x8EB1 0x7AFA # 0 +0x8EB2 0x8EF8 # 0 +0x8EB3 0x5B8D # 0 +0x8EB4 0x96EB # 0 +0x8EB5 0x4E03 # 0 +0x8EB6 0x53F1 # 0 +0x8EB7 0x57F7 # 0 +0x8EB8 0x5931 # 0 +0x8EB9 0x5AC9 # 0 +0x8EBA 0x5BA4 # 0 +0x8EBB 0x6089 # 0 +0x8EBC 0x6E7F # 0 +0x8EBD 0x6F06 # 0 +0x8EBE 0x75BE # 0 +0x8EBF 0x8CEA # 0 +0x8EC0 0x5B9F # 0 +0x8EC1 0x8500 # 0 +0x8EC2 0x7BE0 # 0 +0x8EC3 0x5072 # 0 +0x8EC4 0x67F4 # 0 +0x8EC5 0x829D # 0 +0x8EC6 0x5C61 # 0 +0x8EC7 0x854A # 0 +0x8EC8 0x7E1E # 0 +0x8EC9 0x820E # 0 +0x8ECA 0x5199 # 0 +0x8ECB 0x5C04 # 0 +0x8ECC 0x6368 # 0 +0x8ECD 0x8D66 # 0 +0x8ECE 0x659C # 0 +0x8ECF 0x716E # 0 +0x8ED0 0x793E # 0 +0x8ED1 0x7D17 # 0 +0x8ED2 0x8005 # 0 +0x8ED3 0x8B1D # 0 +0x8ED4 0x8ECA # 0 +0x8ED5 0x906E # 0 +0x8ED6 0x86C7 # 0 +0x8ED7 0x90AA # 0 +0x8ED8 0x501F # 0 +0x8ED9 0x52FA # 0 +0x8EDA 0x5C3A # 0 +0x8EDB 0x6753 # 0 +0x8EDC 0x707C # 0 +0x8EDD 0x7235 # 0 +0x8EDE 0x914C # 0 +0x8EDF 0x91C8 # 0 +0x8EE0 0x932B # 0 +0x8EE1 0x82E5 # 0 +0x8EE2 0x5BC2 # 0 +0x8EE3 0x5F31 # 0 +0x8EE4 0x60F9 # 0 +0x8EE5 0x4E3B # 0 +0x8EE6 0x53D6 # 0 +0x8EE7 0x5B88 # 0 +0x8EE8 0x624B # 0 +0x8EE9 0x6731 # 0 +0x8EEA 0x6B8A # 0 +0x8EEB 0x72E9 # 0 +0x8EEC 0x73E0 # 0 +0x8EED 0x7A2E # 0 +0x8EEE 0x816B # 0 +0x8EEF 0x8DA3 # 0 +0x8EF0 0x9152 # 0 +0x8EF1 0x9996 # 0 +0x8EF2 0x5112 # 0 +0x8EF3 0x53D7 # 0 +0x8EF4 0x546A # 0 +0x8EF5 0x5BFF # 0 +0x8EF6 0x6388 # 0 +0x8EF7 0x6A39 # 0 +0x8EF8 0x7DAC # 0 +0x8EF9 0x9700 # 0 +0x8EFA 0x56DA # 0 +0x8EFB 0x53CE # 0 +0x8EFC 0x5468 # 0 +0x8F40 0x5B97 # 0 +0x8F41 0x5C31 # 0 +0x8F42 0x5DDE # 0 +0x8F43 0x4FEE # 0 +0x8F44 0x6101 # 0 +0x8F45 0x62FE # 0 +0x8F46 0x6D32 # 0 +0x8F47 0x79C0 # 0 +0x8F48 0x79CB # 0 +0x8F49 0x7D42 # 0 +0x8F4A 0x7E4D # 0 +0x8F4B 0x7FD2 # 0 +0x8F4C 0x81ED # 0 +0x8F4D 0x821F # 0 +0x8F4E 0x8490 # 0 +0x8F4F 0x8846 # 0 +0x8F50 0x8972 # 0 +0x8F51 0x8B90 # 0 +0x8F52 0x8E74 # 0 +0x8F53 0x8F2F # 0 +0x8F54 0x9031 # 0 +0x8F55 0x914B # 0 +0x8F56 0x916C # 0 +0x8F57 0x96C6 # 0 +0x8F58 0x919C # 0 +0x8F59 0x4EC0 # 0 +0x8F5A 0x4F4F # 0 +0x8F5B 0x5145 # 0 +0x8F5C 0x5341 # 0 +0x8F5D 0x5F93 # 0 +0x8F5E 0x620E # 0 +0x8F5F 0x67D4 # 0 +0x8F60 0x6C41 # 0 +0x8F61 0x6E0B # 0 +0x8F62 0x7363 # 0 +0x8F63 0x7E26 # 0 +0x8F64 0x91CD # 0 +0x8F65 0x9283 # 0 +0x8F66 0x53D4 # 0 +0x8F67 0x5919 # 0 +0x8F68 0x5BBF # 0 +0x8F69 0x6DD1 # 0 +0x8F6A 0x795D # 0 +0x8F6B 0x7E2E # 0 +0x8F6C 0x7C9B # 0 +0x8F6D 0x587E # 0 +0x8F6E 0x719F # 0 +0x8F6F 0x51FA # 0 +0x8F70 0x8853 # 0 +0x8F71 0x8FF0 # 0 +0x8F72 0x4FCA # 0 +0x8F73 0x5CFB # 0 +0x8F74 0x6625 # 0 +0x8F75 0x77AC # 0 +0x8F76 0x7AE3 # 0 +0x8F77 0x821C # 0 +0x8F78 0x99FF # 0 +0x8F79 0x51C6 # 0 +0x8F7A 0x5FAA # 0 +0x8F7B 0x65EC # 0 +0x8F7C 0x696F # 0 +0x8F7D 0x6B89 # 0 +0x8F7E 0x6DF3 # 0 +0x8F80 0x6E96 # 0 +0x8F81 0x6F64 # 0 +0x8F82 0x76FE # 0 +0x8F83 0x7D14 # 0 +0x8F84 0x5DE1 # 0 +0x8F85 0x9075 # 0 +0x8F86 0x9187 # 0 +0x8F87 0x9806 # 0 +0x8F88 0x51E6 # 0 +0x8F89 0x521D # 0 +0x8F8A 0x6240 # 0 +0x8F8B 0x6691 # 0 +0x8F8C 0x66D9 # 0 +0x8F8D 0x6E1A # 0 +0x8F8E 0x5EB6 # 0 +0x8F8F 0x7DD2 # 0 +0x8F90 0x7F72 # 0 +0x8F91 0x66F8 # 0 +0x8F92 0x85AF # 0 +0x8F93 0x85F7 # 0 +0x8F94 0x8AF8 # 0 +0x8F95 0x52A9 # 0 +0x8F96 0x53D9 # 0 +0x8F97 0x5973 # 0 +0x8F98 0x5E8F # 0 +0x8F99 0x5F90 # 0 +0x8F9A 0x6055 # 0 +0x8F9B 0x92E4 # 0 +0x8F9C 0x9664 # 0 +0x8F9D 0x50B7 # 0 +0x8F9E 0x511F # 0 +0x8F9F 0x52DD # 0 +0x8FA0 0x5320 # 0 +0x8FA1 0x5347 # 0 +0x8FA2 0x53EC # 0 +0x8FA3 0x54E8 # 0 +0x8FA4 0x5546 # 0 +0x8FA5 0x5531 # 0 +0x8FA6 0x5617 # 0 +0x8FA7 0x5968 # 0 +0x8FA8 0x59BE # 0 +0x8FA9 0x5A3C # 0 +0x8FAA 0x5BB5 # 0 +0x8FAB 0x5C06 # 0 +0x8FAC 0x5C0F # 0 +0x8FAD 0x5C11 # 0 +0x8FAE 0x5C1A # 0 +0x8FAF 0x5E84 # 0 +0x8FB0 0x5E8A # 0 +0x8FB1 0x5EE0 # 0 +0x8FB2 0x5F70 # 0 +0x8FB3 0x627F # 0 +0x8FB4 0x6284 # 0 +0x8FB5 0x62DB # 0 +0x8FB6 0x638C # 0 +0x8FB7 0x6377 # 0 +0x8FB8 0x6607 # 0 +0x8FB9 0x660C # 0 +0x8FBA 0x662D # 0 +0x8FBB 0x6676 # 0 +0x8FBC 0x677E # 0 +0x8FBD 0x68A2 # 0 +0x8FBE 0x6A1F # 0 +0x8FBF 0x6A35 # 0 +0x8FC0 0x6CBC # 0 +0x8FC1 0x6D88 # 0 +0x8FC2 0x6E09 # 0 +0x8FC3 0x6E58 # 0 +0x8FC4 0x713C # 0 +0x8FC5 0x7126 # 0 +0x8FC6 0x7167 # 0 +0x8FC7 0x75C7 # 0 +0x8FC8 0x7701 # 0 +0x8FC9 0x785D # 0 +0x8FCA 0x7901 # 0 +0x8FCB 0x7965 # 0 +0x8FCC 0x79F0 # 0 +0x8FCD 0x7AE0 # 0 +0x8FCE 0x7B11 # 0 +0x8FCF 0x7CA7 # 0 +0x8FD0 0x7D39 # 0 +0x8FD1 0x8096 # 0 +0x8FD2 0x83D6 # 0 +0x8FD3 0x848B # 0 +0x8FD4 0x8549 # 0 +0x8FD5 0x885D # 0 +0x8FD6 0x88F3 # 0 +0x8FD7 0x8A1F # 0 +0x8FD8 0x8A3C # 0 +0x8FD9 0x8A54 # 0 +0x8FDA 0x8A73 # 0 +0x8FDB 0x8C61 # 0 +0x8FDC 0x8CDE # 0 +0x8FDD 0x91A4 # 0 +0x8FDE 0x9266 # 0 +0x8FDF 0x937E # 0 +0x8FE0 0x9418 # 0 +0x8FE1 0x969C # 0 +0x8FE2 0x9798 # 0 +0x8FE3 0x4E0A # 0 +0x8FE4 0x4E08 # 0 +0x8FE5 0x4E1E # 0 +0x8FE6 0x4E57 # 0 +0x8FE7 0x5197 # 0 +0x8FE8 0x5270 # 0 +0x8FE9 0x57CE # 0 +0x8FEA 0x5834 # 0 +0x8FEB 0x58CC # 0 +0x8FEC 0x5B22 # 0 +0x8FED 0x5E38 # 0 +0x8FEE 0x60C5 # 0 +0x8FEF 0x64FE # 0 +0x8FF0 0x6761 # 0 +0x8FF1 0x6756 # 0 +0x8FF2 0x6D44 # 0 +0x8FF3 0x72B6 # 0 +0x8FF4 0x7573 # 0 +0x8FF5 0x7A63 # 0 +0x8FF6 0x84B8 # 0 +0x8FF7 0x8B72 # 0 +0x8FF8 0x91B8 # 0 +0x8FF9 0x9320 # 0 +0x8FFA 0x5631 # 0 +0x8FFB 0x57F4 # 0 +0x8FFC 0x98FE # 0 +0x9040 0x62ED # 0 +0x9041 0x690D # 0 +0x9042 0x6B96 # 0 +0x9043 0x71ED # 0 +0x9044 0x7E54 # 0 +0x9045 0x8077 # 0 +0x9046 0x8272 # 0 +0x9047 0x89E6 # 0 +0x9048 0x98DF # 0 +0x9049 0x8755 # 0 +0x904A 0x8FB1 # 0 +0x904B 0x5C3B # 0 +0x904C 0x4F38 # 0 +0x904D 0x4FE1 # 0 +0x904E 0x4FB5 # 0 +0x904F 0x5507 # 0 +0x9050 0x5A20 # 0 +0x9051 0x5BDD # 0 +0x9052 0x5BE9 # 0 +0x9053 0x5FC3 # 0 +0x9054 0x614E # 0 +0x9055 0x632F # 0 +0x9056 0x65B0 # 0 +0x9057 0x664B # 0 +0x9058 0x68EE # 0 +0x9059 0x699B # 0 +0x905A 0x6D78 # 0 +0x905B 0x6DF1 # 0 +0x905C 0x7533 # 0 +0x905D 0x75B9 # 0 +0x905E 0x771F # 0 +0x905F 0x795E # 0 +0x9060 0x79E6 # 0 +0x9061 0x7D33 # 0 +0x9062 0x81E3 # 0 +0x9063 0x82AF # 0 +0x9064 0x85AA # 0 +0x9065 0x89AA # 0 +0x9066 0x8A3A # 0 +0x9067 0x8EAB # 0 +0x9068 0x8F9B # 0 +0x9069 0x9032 # 0 +0x906A 0x91DD # 0 +0x906B 0x9707 # 0 +0x906C 0x4EBA # 0 +0x906D 0x4EC1 # 0 +0x906E 0x5203 # 0 +0x906F 0x5875 # 0 +0x9070 0x58EC # 0 +0x9071 0x5C0B # 0 +0x9072 0x751A # 0 +0x9073 0x5C3D # 0 +0x9074 0x814E # 0 +0x9075 0x8A0A # 0 +0x9076 0x8FC5 # 0 +0x9077 0x9663 # 0 +0x9078 0x976D # 0 +0x9079 0x7B25 # 0 +0x907A 0x8ACF # 0 +0x907B 0x9808 # 0 +0x907C 0x9162 # 0 +0x907D 0x56F3 # 0 +0x907E 0x53A8 # 0 +0x9080 0x9017 # 0 +0x9081 0x5439 # 0 +0x9082 0x5782 # 0 +0x9083 0x5E25 # 0 +0x9084 0x63A8 # 0 +0x9085 0x6C34 # 0 +0x9086 0x708A # 0 +0x9087 0x7761 # 0 +0x9088 0x7C8B # 0 +0x9089 0x7FE0 # 0 +0x908A 0x8870 # 0 +0x908B 0x9042 # 0 +0x908C 0x9154 # 0 +0x908D 0x9310 # 0 +0x908E 0x9318 # 0 +0x908F 0x968F # 0 +0x9090 0x745E # 0 +0x9091 0x9AC4 # 0 +0x9092 0x5D07 # 0 +0x9093 0x5D69 # 0 +0x9094 0x6570 # 0 +0x9095 0x67A2 # 0 +0x9096 0x8DA8 # 0 +0x9097 0x96DB # 0 +0x9098 0x636E # 0 +0x9099 0x6749 # 0 +0x909A 0x6919 # 0 +0x909B 0x83C5 # 0 +0x909C 0x9817 # 0 +0x909D 0x96C0 # 0 +0x909E 0x88FE # 0 +0x909F 0x6F84 # 0 +0x90A0 0x647A # 0 +0x90A1 0x5BF8 # 0 +0x90A2 0x4E16 # 0 +0x90A3 0x702C # 0 +0x90A4 0x755D # 0 +0x90A5 0x662F # 0 +0x90A6 0x51C4 # 0 +0x90A7 0x5236 # 0 +0x90A8 0x52E2 # 0 +0x90A9 0x59D3 # 0 +0x90AA 0x5F81 # 0 +0x90AB 0x6027 # 0 +0x90AC 0x6210 # 0 +0x90AD 0x653F # 0 +0x90AE 0x6574 # 0 +0x90AF 0x661F # 0 +0x90B0 0x6674 # 0 +0x90B1 0x68F2 # 0 +0x90B2 0x6816 # 0 +0x90B3 0x6B63 # 0 +0x90B4 0x6E05 # 0 +0x90B5 0x7272 # 0 +0x90B6 0x751F # 0 +0x90B7 0x76DB # 0 +0x90B8 0x7CBE # 0 +0x90B9 0x8056 # 0 +0x90BA 0x58F0 # 0 +0x90BB 0x88FD # 0 +0x90BC 0x897F # 0 +0x90BD 0x8AA0 # 0 +0x90BE 0x8A93 # 0 +0x90BF 0x8ACB # 0 +0x90C0 0x901D # 0 +0x90C1 0x9192 # 0 +0x90C2 0x9752 # 0 +0x90C3 0x9759 # 0 +0x90C4 0x6589 # 0 +0x90C5 0x7A0E # 0 +0x90C6 0x8106 # 0 +0x90C7 0x96BB # 0 +0x90C8 0x5E2D # 0 +0x90C9 0x60DC # 0 +0x90CA 0x621A # 0 +0x90CB 0x65A5 # 0 +0x90CC 0x6614 # 0 +0x90CD 0x6790 # 0 +0x90CE 0x77F3 # 0 +0x90CF 0x7A4D # 0 +0x90D0 0x7C4D # 0 +0x90D1 0x7E3E # 0 +0x90D2 0x810A # 0 +0x90D3 0x8CAC # 0 +0x90D4 0x8D64 # 0 +0x90D5 0x8DE1 # 0 +0x90D6 0x8E5F # 0 +0x90D7 0x78A9 # 0 +0x90D8 0x5207 # 0 +0x90D9 0x62D9 # 0 +0x90DA 0x63A5 # 0 +0x90DB 0x6442 # 0 +0x90DC 0x6298 # 0 +0x90DD 0x8A2D # 0 +0x90DE 0x7A83 # 0 +0x90DF 0x7BC0 # 0 +0x90E0 0x8AAC # 0 +0x90E1 0x96EA # 0 +0x90E2 0x7D76 # 0 +0x90E3 0x820C # 0 +0x90E4 0x8749 # 0 +0x90E5 0x4ED9 # 0 +0x90E6 0x5148 # 0 +0x90E7 0x5343 # 0 +0x90E8 0x5360 # 0 +0x90E9 0x5BA3 # 0 +0x90EA 0x5C02 # 0 +0x90EB 0x5C16 # 0 +0x90EC 0x5DDD # 0 +0x90ED 0x6226 # 0 +0x90EE 0x6247 # 0 +0x90EF 0x64B0 # 0 +0x90F0 0x6813 # 0 +0x90F1 0x6834 # 0 +0x90F2 0x6CC9 # 0 +0x90F3 0x6D45 # 0 +0x90F4 0x6D17 # 0 +0x90F5 0x67D3 # 0 +0x90F6 0x6F5C # 0 +0x90F7 0x714E # 0 +0x90F8 0x717D # 0 +0x90F9 0x65CB # 0 +0x90FA 0x7A7F # 0 +0x90FB 0x7BAD # 0 +0x90FC 0x7DDA # 0 +0x9140 0x7E4A # 0 +0x9141 0x7FA8 # 0 +0x9142 0x817A # 0 +0x9143 0x821B # 0 +0x9144 0x8239 # 0 +0x9145 0x85A6 # 0 +0x9146 0x8A6E # 0 +0x9147 0x8CCE # 0 +0x9148 0x8DF5 # 0 +0x9149 0x9078 # 0 +0x914A 0x9077 # 0 +0x914B 0x92AD # 0 +0x914C 0x9291 # 0 +0x914D 0x9583 # 0 +0x914E 0x9BAE # 0 +0x914F 0x524D # 0 +0x9150 0x5584 # 0 +0x9151 0x6F38 # 0 +0x9152 0x7136 # 0 +0x9153 0x5168 # 0 +0x9154 0x7985 # 0 +0x9155 0x7E55 # 0 +0x9156 0x81B3 # 0 +0x9157 0x7CCE # 0 +0x9158 0x564C # 0 +0x9159 0x5851 # 0 +0x915A 0x5CA8 # 0 +0x915B 0x63AA # 0 +0x915C 0x66FE # 0 +0x915D 0x66FD # 0 +0x915E 0x695A # 0 +0x915F 0x72D9 # 0 +0x9160 0x758F # 0 +0x9161 0x758E # 0 +0x9162 0x790E # 0 +0x9163 0x7956 # 0 +0x9164 0x79DF # 0 +0x9165 0x7C97 # 0 +0x9166 0x7D20 # 0 +0x9167 0x7D44 # 0 +0x9168 0x8607 # 0 +0x9169 0x8A34 # 0 +0x916A 0x963B # 0 +0x916B 0x9061 # 0 +0x916C 0x9F20 # 0 +0x916D 0x50E7 # 0 +0x916E 0x5275 # 0 +0x916F 0x53CC # 0 +0x9170 0x53E2 # 0 +0x9171 0x5009 # 0 +0x9172 0x55AA # 0 +0x9173 0x58EE # 0 +0x9174 0x594F # 0 +0x9175 0x723D # 0 +0x9176 0x5B8B # 0 +0x9177 0x5C64 # 0 +0x9178 0x531D # 0 +0x9179 0x60E3 # 0 +0x917A 0x60F3 # 0 +0x917B 0x635C # 0 +0x917C 0x6383 # 0 +0x917D 0x633F # 0 +0x917E 0x63BB # 0 +0x9180 0x64CD # 0 +0x9181 0x65E9 # 0 +0x9182 0x66F9 # 0 +0x9183 0x5DE3 # 0 +0x9184 0x69CD # 0 +0x9185 0x69FD # 0 +0x9186 0x6F15 # 0 +0x9187 0x71E5 # 0 +0x9188 0x4E89 # 0 +0x9189 0x75E9 # 0 +0x918A 0x76F8 # 0 +0x918B 0x7A93 # 0 +0x918C 0x7CDF # 0 +0x918D 0x7DCF # 0 +0x918E 0x7D9C # 0 +0x918F 0x8061 # 0 +0x9190 0x8349 # 0 +0x9191 0x8358 # 0 +0x9192 0x846C # 0 +0x9193 0x84BC # 0 +0x9194 0x85FB # 0 +0x9195 0x88C5 # 0 +0x9196 0x8D70 # 0 +0x9197 0x9001 # 0 +0x9198 0x906D # 0 +0x9199 0x9397 # 0 +0x919A 0x971C # 0 +0x919B 0x9A12 # 0 +0x919C 0x50CF # 0 +0x919D 0x5897 # 0 +0x919E 0x618E # 0 +0x919F 0x81D3 # 0 +0x91A0 0x8535 # 0 +0x91A1 0x8D08 # 0 +0x91A2 0x9020 # 0 +0x91A3 0x4FC3 # 0 +0x91A4 0x5074 # 0 +0x91A5 0x5247 # 0 +0x91A6 0x5373 # 0 +0x91A7 0x606F # 0 +0x91A8 0x6349 # 0 +0x91A9 0x675F # 0 +0x91AA 0x6E2C # 0 +0x91AB 0x8DB3 # 0 +0x91AC 0x901F # 0 +0x91AD 0x4FD7 # 0 +0x91AE 0x5C5E # 0 +0x91AF 0x8CCA # 0 +0x91B0 0x65CF # 0 +0x91B1 0x7D9A # 0 +0x91B2 0x5352 # 0 +0x91B3 0x8896 # 0 +0x91B4 0x5176 # 0 +0x91B5 0x63C3 # 0 +0x91B6 0x5B58 # 0 +0x91B7 0x5B6B # 0 +0x91B8 0x5C0A # 0 +0x91B9 0x640D # 0 +0x91BA 0x6751 # 0 +0x91BB 0x905C # 0 +0x91BC 0x4ED6 # 0 +0x91BD 0x591A # 0 +0x91BE 0x592A # 0 +0x91BF 0x6C70 # 0 +0x91C0 0x8A51 # 0 +0x91C1 0x553E # 0 +0x91C2 0x5815 # 0 +0x91C3 0x59A5 # 0 +0x91C4 0x60F0 # 0 +0x91C5 0x6253 # 0 +0x91C6 0x67C1 # 0 +0x91C7 0x8235 # 0 +0x91C8 0x6955 # 0 +0x91C9 0x9640 # 0 +0x91CA 0x99C4 # 0 +0x91CB 0x9A28 # 0 +0x91CC 0x4F53 # 0 +0x91CD 0x5806 # 0 +0x91CE 0x5BFE # 0 +0x91CF 0x8010 # 0 +0x91D0 0x5CB1 # 0 +0x91D1 0x5E2F # 0 +0x91D2 0x5F85 # 0 +0x91D3 0x6020 # 0 +0x91D4 0x614B # 0 +0x91D5 0x6234 # 0 +0x91D6 0x66FF # 0 +0x91D7 0x6CF0 # 0 +0x91D8 0x6EDE # 0 +0x91D9 0x80CE # 0 +0x91DA 0x817F # 0 +0x91DB 0x82D4 # 0 +0x91DC 0x888B # 0 +0x91DD 0x8CB8 # 0 +0x91DE 0x9000 # 0 +0x91DF 0x902E # 0 +0x91E0 0x968A # 0 +0x91E1 0x9EDB # 0 +0x91E2 0x9BDB # 0 +0x91E3 0x4EE3 # 0 +0x91E4 0x53F0 # 0 +0x91E5 0x5927 # 0 +0x91E6 0x7B2C # 0 +0x91E7 0x918D # 0 +0x91E8 0x984C # 0 +0x91E9 0x9DF9 # 0 +0x91EA 0x6EDD # 0 +0x91EB 0x7027 # 0 +0x91EC 0x5353 # 0 +0x91ED 0x5544 # 0 +0x91EE 0x5B85 # 0 +0x91EF 0x6258 # 0 +0x91F0 0x629E # 0 +0x91F1 0x62D3 # 0 +0x91F2 0x6CA2 # 0 +0x91F3 0x6FEF # 0 +0x91F4 0x7422 # 0 +0x91F5 0x8A17 # 0 +0x91F6 0x9438 # 0 +0x91F7 0x6FC1 # 0 +0x91F8 0x8AFE # 0 +0x91F9 0x8338 # 0 +0x91FA 0x51E7 # 0 +0x91FB 0x86F8 # 0 +0x91FC 0x53EA # 0 +0x9240 0x53E9 # 0 +0x9241 0x4F46 # 0 +0x9242 0x9054 # 0 +0x9243 0x8FB0 # 0 +0x9244 0x596A # 0 +0x9245 0x8131 # 0 +0x9246 0x5DFD # 0 +0x9247 0x7AEA # 0 +0x9248 0x8FBF # 0 +0x9249 0x68DA # 0 +0x924A 0x8C37 # 0 +0x924B 0x72F8 # 0 +0x924C 0x9C48 # 0 +0x924D 0x6A3D # 0 +0x924E 0x8AB0 # 0 +0x924F 0x4E39 # 0 +0x9250 0x5358 # 0 +0x9251 0x5606 # 0 +0x9252 0x5766 # 0 +0x9253 0x62C5 # 0 +0x9254 0x63A2 # 0 +0x9255 0x65E6 # 0 +0x9256 0x6B4E # 0 +0x9257 0x6DE1 # 0 +0x9258 0x6E5B # 0 +0x9259 0x70AD # 0 +0x925A 0x77ED # 0 +0x925B 0x7AEF # 0 +0x925C 0x7BAA # 0 +0x925D 0x7DBB # 0 +0x925E 0x803D # 0 +0x925F 0x80C6 # 0 +0x9260 0x86CB # 0 +0x9261 0x8A95 # 0 +0x9262 0x935B # 0 +0x9263 0x56E3 # 0 +0x9264 0x58C7 # 0 +0x9265 0x5F3E # 0 +0x9266 0x65AD # 0 +0x9267 0x6696 # 0 +0x9268 0x6A80 # 0 +0x9269 0x6BB5 # 0 +0x926A 0x7537 # 0 +0x926B 0x8AC7 # 0 +0x926C 0x5024 # 0 +0x926D 0x77E5 # 0 +0x926E 0x5730 # 0 +0x926F 0x5F1B # 0 +0x9270 0x6065 # 0 +0x9271 0x667A # 0 +0x9272 0x6C60 # 0 +0x9273 0x75F4 # 0 +0x9274 0x7A1A # 0 +0x9275 0x7F6E # 0 +0x9276 0x81F4 # 0 +0x9277 0x8718 # 0 +0x9278 0x9045 # 0 +0x9279 0x99B3 # 0 +0x927A 0x7BC9 # 0 +0x927B 0x755C # 0 +0x927C 0x7AF9 # 0 +0x927D 0x7B51 # 0 +0x927E 0x84C4 # 0 +0x9280 0x9010 # 0 +0x9281 0x79E9 # 0 +0x9282 0x7A92 # 0 +0x9283 0x8336 # 0 +0x9284 0x5AE1 # 0 +0x9285 0x7740 # 0 +0x9286 0x4E2D # 0 +0x9287 0x4EF2 # 0 +0x9288 0x5B99 # 0 +0x9289 0x5FE0 # 0 +0x928A 0x62BD # 0 +0x928B 0x663C # 0 +0x928C 0x67F1 # 0 +0x928D 0x6CE8 # 0 +0x928E 0x866B # 0 +0x928F 0x8877 # 0 +0x9290 0x8A3B # 0 +0x9291 0x914E # 0 +0x9292 0x92F3 # 0 +0x9293 0x99D0 # 0 +0x9294 0x6A17 # 0 +0x9295 0x7026 # 0 +0x9296 0x732A # 0 +0x9297 0x82E7 # 0 +0x9298 0x8457 # 0 +0x9299 0x8CAF # 0 +0x929A 0x4E01 # 0 +0x929B 0x5146 # 0 +0x929C 0x51CB # 0 +0x929D 0x558B # 0 +0x929E 0x5BF5 # 0 +0x929F 0x5E16 # 0 +0x92A0 0x5E33 # 0 +0x92A1 0x5E81 # 0 +0x92A2 0x5F14 # 0 +0x92A3 0x5F35 # 0 +0x92A4 0x5F6B # 0 +0x92A5 0x5FB4 # 0 +0x92A6 0x61F2 # 0 +0x92A7 0x6311 # 0 +0x92A8 0x66A2 # 0 +0x92A9 0x671D # 0 +0x92AA 0x6F6E # 0 +0x92AB 0x7252 # 0 +0x92AC 0x753A # 0 +0x92AD 0x773A # 0 +0x92AE 0x8074 # 0 +0x92AF 0x8139 # 0 +0x92B0 0x8178 # 0 +0x92B1 0x8776 # 0 +0x92B2 0x8ABF # 0 +0x92B3 0x8ADC # 0 +0x92B4 0x8D85 # 0 +0x92B5 0x8DF3 # 0 +0x92B6 0x929A # 0 +0x92B7 0x9577 # 0 +0x92B8 0x9802 # 0 +0x92B9 0x9CE5 # 0 +0x92BA 0x52C5 # 0 +0x92BB 0x6357 # 0 +0x92BC 0x76F4 # 0 +0x92BD 0x6715 # 0 +0x92BE 0x6C88 # 0 +0x92BF 0x73CD # 0 +0x92C0 0x8CC3 # 0 +0x92C1 0x93AE # 0 +0x92C2 0x9673 # 0 +0x92C3 0x6D25 # 0 +0x92C4 0x589C # 0 +0x92C5 0x690E # 0 +0x92C6 0x69CC # 0 +0x92C7 0x8FFD # 0 +0x92C8 0x939A # 0 +0x92C9 0x75DB # 0 +0x92CA 0x901A # 0 +0x92CB 0x585A # 0 +0x92CC 0x6802 # 0 +0x92CD 0x63B4 # 0 +0x92CE 0x69FB # 0 +0x92CF 0x4F43 # 0 +0x92D0 0x6F2C # 0 +0x92D1 0x67D8 # 0 +0x92D2 0x8FBB # 0 +0x92D3 0x8526 # 0 +0x92D4 0x7DB4 # 0 +0x92D5 0x9354 # 0 +0x92D6 0x693F # 0 +0x92D7 0x6F70 # 0 +0x92D8 0x576A # 0 +0x92D9 0x58F7 # 0 +0x92DA 0x5B2C # 0 +0x92DB 0x7D2C # 0 +0x92DC 0x722A # 0 +0x92DD 0x540A # 0 +0x92DE 0x91E3 # 0 +0x92DF 0x9DB4 # 0 +0x92E0 0x4EAD # 0 +0x92E1 0x4F4E # 0 +0x92E2 0x505C # 0 +0x92E3 0x5075 # 0 +0x92E4 0x5243 # 0 +0x92E5 0x8C9E # 0 +0x92E6 0x5448 # 0 +0x92E7 0x5824 # 0 +0x92E8 0x5B9A # 0 +0x92E9 0x5E1D # 0 +0x92EA 0x5E95 # 0 +0x92EB 0x5EAD # 0 +0x92EC 0x5EF7 # 0 +0x92ED 0x5F1F # 0 +0x92EE 0x608C # 0 +0x92EF 0x62B5 # 0 +0x92F0 0x633A # 0 +0x92F1 0x63D0 # 0 +0x92F2 0x68AF # 0 +0x92F3 0x6C40 # 0 +0x92F4 0x7887 # 0 +0x92F5 0x798E # 0 +0x92F6 0x7A0B # 0 +0x92F7 0x7DE0 # 0 +0x92F8 0x8247 # 0 +0x92F9 0x8A02 # 0 +0x92FA 0x8AE6 # 0 +0x92FB 0x8E44 # 0 +0x92FC 0x9013 # 0 +0x9340 0x90B8 # 0 +0x9341 0x912D # 0 +0x9342 0x91D8 # 0 +0x9343 0x9F0E # 0 +0x9344 0x6CE5 # 0 +0x9345 0x6458 # 0 +0x9346 0x64E2 # 0 +0x9347 0x6575 # 0 +0x9348 0x6EF4 # 0 +0x9349 0x7684 # 0 +0x934A 0x7B1B # 0 +0x934B 0x9069 # 0 +0x934C 0x93D1 # 0 +0x934D 0x6EBA # 0 +0x934E 0x54F2 # 0 +0x934F 0x5FB9 # 0 +0x9350 0x64A4 # 0 +0x9351 0x8F4D # 0 +0x9352 0x8FED # 0 +0x9353 0x9244 # 0 +0x9354 0x5178 # 0 +0x9355 0x586B # 0 +0x9356 0x5929 # 0 +0x9357 0x5C55 # 0 +0x9358 0x5E97 # 0 +0x9359 0x6DFB # 0 +0x935A 0x7E8F # 0 +0x935B 0x751C # 0 +0x935C 0x8CBC # 0 +0x935D 0x8EE2 # 0 +0x935E 0x985B # 0 +0x935F 0x70B9 # 0 +0x9360 0x4F1D # 0 +0x9361 0x6BBF # 0 +0x9362 0x6FB1 # 0 +0x9363 0x7530 # 0 +0x9364 0x96FB # 0 +0x9365 0x514E # 0 +0x9366 0x5410 # 0 +0x9367 0x5835 # 0 +0x9368 0x5857 # 0 +0x9369 0x59AC # 0 +0x936A 0x5C60 # 0 +0x936B 0x5F92 # 0 +0x936C 0x6597 # 0 +0x936D 0x675C # 0 +0x936E 0x6E21 # 0 +0x936F 0x767B # 0 +0x9370 0x83DF # 0 +0x9371 0x8CED # 0 +0x9372 0x9014 # 0 +0x9373 0x90FD # 0 +0x9374 0x934D # 0 +0x9375 0x7825 # 0 +0x9376 0x783A # 0 +0x9377 0x52AA # 0 +0x9378 0x5EA6 # 0 +0x9379 0x571F # 0 +0x937A 0x5974 # 0 +0x937B 0x6012 # 0 +0x937C 0x5012 # 0 +0x937D 0x515A # 0 +0x937E 0x51AC # 0 +0x9380 0x51CD # 0 +0x9381 0x5200 # 0 +0x9382 0x5510 # 0 +0x9383 0x5854 # 0 +0x9384 0x5858 # 0 +0x9385 0x5957 # 0 +0x9386 0x5B95 # 0 +0x9387 0x5CF6 # 0 +0x9388 0x5D8B # 0 +0x9389 0x60BC # 0 +0x938A 0x6295 # 0 +0x938B 0x642D # 0 +0x938C 0x6771 # 0 +0x938D 0x6843 # 0 +0x938E 0x68BC # 0 +0x938F 0x68DF # 0 +0x9390 0x76D7 # 0 +0x9391 0x6DD8 # 0 +0x9392 0x6E6F # 0 +0x9393 0x6D9B # 0 +0x9394 0x706F # 0 +0x9395 0x71C8 # 0 +0x9396 0x5F53 # 0 +0x9397 0x75D8 # 0 +0x9398 0x7977 # 0 +0x9399 0x7B49 # 0 +0x939A 0x7B54 # 0 +0x939B 0x7B52 # 0 +0x939C 0x7CD6 # 0 +0x939D 0x7D71 # 0 +0x939E 0x5230 # 0 +0x939F 0x8463 # 0 +0x93A0 0x8569 # 0 +0x93A1 0x85E4 # 0 +0x93A2 0x8A0E # 0 +0x93A3 0x8B04 # 0 +0x93A4 0x8C46 # 0 +0x93A5 0x8E0F # 0 +0x93A6 0x9003 # 0 +0x93A7 0x900F # 0 +0x93A8 0x9419 # 0 +0x93A9 0x9676 # 0 +0x93AA 0x982D # 0 +0x93AB 0x9A30 # 0 +0x93AC 0x95D8 # 0 +0x93AD 0x50CD # 0 +0x93AE 0x52D5 # 0 +0x93AF 0x540C # 0 +0x93B0 0x5802 # 0 +0x93B1 0x5C0E # 0 +0x93B2 0x61A7 # 0 +0x93B3 0x649E # 0 +0x93B4 0x6D1E # 0 +0x93B5 0x77B3 # 0 +0x93B6 0x7AE5 # 0 +0x93B7 0x80F4 # 0 +0x93B8 0x8404 # 0 +0x93B9 0x9053 # 0 +0x93BA 0x9285 # 0 +0x93BB 0x5CE0 # 0 +0x93BC 0x9D07 # 0 +0x93BD 0x533F # 0 +0x93BE 0x5F97 # 0 +0x93BF 0x5FB3 # 0 +0x93C0 0x6D9C # 0 +0x93C1 0x7279 # 0 +0x93C2 0x7763 # 0 +0x93C3 0x79BF # 0 +0x93C4 0x7BE4 # 0 +0x93C5 0x6BD2 # 0 +0x93C6 0x72EC # 0 +0x93C7 0x8AAD # 0 +0x93C8 0x6803 # 0 +0x93C9 0x6A61 # 0 +0x93CA 0x51F8 # 0 +0x93CB 0x7A81 # 0 +0x93CC 0x6934 # 0 +0x93CD 0x5C4A # 0 +0x93CE 0x9CF6 # 0 +0x93CF 0x82EB # 0 +0x93D0 0x5BC5 # 0 +0x93D1 0x9149 # 0 +0x93D2 0x701E # 0 +0x93D3 0x5678 # 0 +0x93D4 0x5C6F # 0 +0x93D5 0x60C7 # 0 +0x93D6 0x6566 # 0 +0x93D7 0x6C8C # 0 +0x93D8 0x8C5A # 0 +0x93D9 0x9041 # 0 +0x93DA 0x9813 # 0 +0x93DB 0x5451 # 0 +0x93DC 0x66C7 # 0 +0x93DD 0x920D # 0 +0x93DE 0x5948 # 0 +0x93DF 0x90A3 # 0 +0x93E0 0x5185 # 0 +0x93E1 0x4E4D # 0 +0x93E2 0x51EA # 0 +0x93E3 0x8599 # 0 +0x93E4 0x8B0E # 0 +0x93E5 0x7058 # 0 +0x93E6 0x637A # 0 +0x93E7 0x934B # 0 +0x93E8 0x6962 # 0 +0x93E9 0x99B4 # 0 +0x93EA 0x7E04 # 0 +0x93EB 0x7577 # 0 +0x93EC 0x5357 # 0 +0x93ED 0x6960 # 0 +0x93EE 0x8EDF # 0 +0x93EF 0x96E3 # 0 +0x93F0 0x6C5D # 0 +0x93F1 0x4E8C # 0 +0x93F2 0x5C3C # 0 +0x93F3 0x5F10 # 0 +0x93F4 0x8FE9 # 0 +0x93F5 0x5302 # 0 +0x93F6 0x8CD1 # 0 +0x93F7 0x8089 # 0 +0x93F8 0x8679 # 0 +0x93F9 0x5EFF # 0 +0x93FA 0x65E5 # 0 +0x93FB 0x4E73 # 0 +0x93FC 0x5165 # 0 +0x9440 0x5982 # 0 +0x9441 0x5C3F # 0 +0x9442 0x97EE # 0 +0x9443 0x4EFB # 0 +0x9444 0x598A # 0 +0x9445 0x5FCD # 0 +0x9446 0x8A8D # 0 +0x9447 0x6FE1 # 0 +0x9448 0x79B0 # 0 +0x9449 0x7962 # 0 +0x944A 0x5BE7 # 0 +0x944B 0x8471 # 0 +0x944C 0x732B # 0 +0x944D 0x71B1 # 0 +0x944E 0x5E74 # 0 +0x944F 0x5FF5 # 0 +0x9450 0x637B # 0 +0x9451 0x649A # 0 +0x9452 0x71C3 # 0 +0x9453 0x7C98 # 0 +0x9454 0x4E43 # 0 +0x9455 0x5EFC # 0 +0x9456 0x4E4B # 0 +0x9457 0x57DC # 0 +0x9458 0x56A2 # 0 +0x9459 0x60A9 # 0 +0x945A 0x6FC3 # 0 +0x945B 0x7D0D # 0 +0x945C 0x80FD # 0 +0x945D 0x8133 # 0 +0x945E 0x81BF # 0 +0x945F 0x8FB2 # 0 +0x9460 0x8997 # 0 +0x9461 0x86A4 # 0 +0x9462 0x5DF4 # 0 +0x9463 0x628A # 0 +0x9464 0x64AD # 0 +0x9465 0x8987 # 0 +0x9466 0x6777 # 0 +0x9467 0x6CE2 # 0 +0x9468 0x6D3E # 0 +0x9469 0x7436 # 0 +0x946A 0x7834 # 0 +0x946B 0x5A46 # 0 +0x946C 0x7F75 # 0 +0x946D 0x82AD # 0 +0x946E 0x99AC # 0 +0x946F 0x4FF3 # 0 +0x9470 0x5EC3 # 0 +0x9471 0x62DD # 0 +0x9472 0x6392 # 0 +0x9473 0x6557 # 0 +0x9474 0x676F # 0 +0x9475 0x76C3 # 0 +0x9476 0x724C # 0 +0x9477 0x80CC # 0 +0x9478 0x80BA # 0 +0x9479 0x8F29 # 0 +0x947A 0x914D # 0 +0x947B 0x500D # 0 +0x947C 0x57F9 # 0 +0x947D 0x5A92 # 0 +0x947E 0x6885 # 0 +0x9480 0x6973 # 0 +0x9481 0x7164 # 0 +0x9482 0x72FD # 0 +0x9483 0x8CB7 # 0 +0x9484 0x58F2 # 0 +0x9485 0x8CE0 # 0 +0x9486 0x966A # 0 +0x9487 0x9019 # 0 +0x9488 0x877F # 0 +0x9489 0x79E4 # 0 +0x948A 0x77E7 # 0 +0x948B 0x8429 # 0 +0x948C 0x4F2F # 0 +0x948D 0x5265 # 0 +0x948E 0x535A # 0 +0x948F 0x62CD # 0 +0x9490 0x67CF # 0 +0x9491 0x6CCA # 0 +0x9492 0x767D # 0 +0x9493 0x7B94 # 0 +0x9494 0x7C95 # 0 +0x9495 0x8236 # 0 +0x9496 0x8584 # 0 +0x9497 0x8FEB # 0 +0x9498 0x66DD # 0 +0x9499 0x6F20 # 0 +0x949A 0x7206 # 0 +0x949B 0x7E1B # 0 +0x949C 0x83AB # 0 +0x949D 0x99C1 # 0 +0x949E 0x9EA6 # 0 +0x949F 0x51FD # 0 +0x94A0 0x7BB1 # 0 +0x94A1 0x7872 # 0 +0x94A2 0x7BB8 # 0 +0x94A3 0x8087 # 0 +0x94A4 0x7B48 # 0 +0x94A5 0x6AE8 # 0 +0x94A6 0x5E61 # 0 +0x94A7 0x808C # 0 +0x94A8 0x7551 # 0 +0x94A9 0x7560 # 0 +0x94AA 0x516B # 0 +0x94AB 0x9262 # 0 +0x94AC 0x6E8C # 0 +0x94AD 0x767A # 0 +0x94AE 0x9197 # 0 +0x94AF 0x9AEA # 0 +0x94B0 0x4F10 # 0 +0x94B1 0x7F70 # 0 +0x94B2 0x629C # 0 +0x94B3 0x7B4F # 0 +0x94B4 0x95A5 # 0 +0x94B5 0x9CE9 # 0 +0x94B6 0x567A # 0 +0x94B7 0x5859 # 0 +0x94B8 0x86E4 # 0 +0x94B9 0x96BC # 0 +0x94BA 0x4F34 # 0 +0x94BB 0x5224 # 0 +0x94BC 0x534A # 0 +0x94BD 0x53CD # 0 +0x94BE 0x53DB # 0 +0x94BF 0x5E06 # 0 +0x94C0 0x642C # 0 +0x94C1 0x6591 # 0 +0x94C2 0x677F # 0 +0x94C3 0x6C3E # 0 +0x94C4 0x6C4E # 0 +0x94C5 0x7248 # 0 +0x94C6 0x72AF # 0 +0x94C7 0x73ED # 0 +0x94C8 0x7554 # 0 +0x94C9 0x7E41 # 0 +0x94CA 0x822C # 0 +0x94CB 0x85E9 # 0 +0x94CC 0x8CA9 # 0 +0x94CD 0x7BC4 # 0 +0x94CE 0x91C6 # 0 +0x94CF 0x7169 # 0 +0x94D0 0x9812 # 0 +0x94D1 0x98EF # 0 +0x94D2 0x633D # 0 +0x94D3 0x6669 # 0 +0x94D4 0x756A # 0 +0x94D5 0x76E4 # 0 +0x94D6 0x78D0 # 0 +0x94D7 0x8543 # 0 +0x94D8 0x86EE # 0 +0x94D9 0x532A # 0 +0x94DA 0x5351 # 0 +0x94DB 0x5426 # 0 +0x94DC 0x5983 # 0 +0x94DD 0x5E87 # 0 +0x94DE 0x5F7C # 0 +0x94DF 0x60B2 # 0 +0x94E0 0x6249 # 0 +0x94E1 0x6279 # 0 +0x94E2 0x62AB # 0 +0x94E3 0x6590 # 0 +0x94E4 0x6BD4 # 0 +0x94E5 0x6CCC # 0 +0x94E6 0x75B2 # 0 +0x94E7 0x76AE # 0 +0x94E8 0x7891 # 0 +0x94E9 0x79D8 # 0 +0x94EA 0x7DCB # 0 +0x94EB 0x7F77 # 0 +0x94EC 0x80A5 # 0 +0x94ED 0x88AB # 0 +0x94EE 0x8AB9 # 0 +0x94EF 0x8CBB # 0 +0x94F0 0x907F # 0 +0x94F1 0x975E # 0 +0x94F2 0x98DB # 0 +0x94F3 0x6A0B # 0 +0x94F4 0x7C38 # 0 +0x94F5 0x5099 # 0 +0x94F6 0x5C3E # 0 +0x94F7 0x5FAE # 0 +0x94F8 0x6787 # 0 +0x94F9 0x6BD8 # 0 +0x94FA 0x7435 # 0 +0x94FB 0x7709 # 0 +0x94FC 0x7F8E # 0 +0x9540 0x9F3B # 0 +0x9541 0x67CA # 0 +0x9542 0x7A17 # 0 +0x9543 0x5339 # 0 +0x9544 0x758B # 0 +0x9545 0x9AED # 0 +0x9546 0x5F66 # 0 +0x9547 0x819D # 0 +0x9548 0x83F1 # 0 +0x9549 0x8098 # 0 +0x954A 0x5F3C # 0 +0x954B 0x5FC5 # 0 +0x954C 0x7562 # 0 +0x954D 0x7B46 # 0 +0x954E 0x903C # 0 +0x954F 0x6867 # 0 +0x9550 0x59EB # 0 +0x9551 0x5A9B # 0 +0x9552 0x7D10 # 0 +0x9553 0x767E # 0 +0x9554 0x8B2C # 0 +0x9555 0x4FF5 # 0 +0x9556 0x5F6A # 0 +0x9557 0x6A19 # 0 +0x9558 0x6C37 # 0 +0x9559 0x6F02 # 0 +0x955A 0x74E2 # 0 +0x955B 0x7968 # 0 +0x955C 0x8868 # 0 +0x955D 0x8A55 # 0 +0x955E 0x8C79 # 0 +0x955F 0x5EDF # 0 +0x9560 0x63CF # 0 +0x9561 0x75C5 # 0 +0x9562 0x79D2 # 0 +0x9563 0x82D7 # 0 +0x9564 0x9328 # 0 +0x9565 0x92F2 # 0 +0x9566 0x849C # 0 +0x9567 0x86ED # 0 +0x9568 0x9C2D # 0 +0x9569 0x54C1 # 0 +0x956A 0x5F6C # 0 +0x956B 0x658C # 0 +0x956C 0x6D5C # 0 +0x956D 0x7015 # 0 +0x956E 0x8CA7 # 0 +0x956F 0x8CD3 # 0 +0x9570 0x983B # 0 +0x9571 0x654F # 0 +0x9572 0x74F6 # 0 +0x9573 0x4E0D # 0 +0x9574 0x4ED8 # 0 +0x9575 0x57E0 # 0 +0x9576 0x592B # 0 +0x9577 0x5A66 # 0 +0x9578 0x5BCC # 0 +0x9579 0x51A8 # 0 +0x957A 0x5E03 # 0 +0x957B 0x5E9C # 0 +0x957C 0x6016 # 0 +0x957D 0x6276 # 0 +0x957E 0x6577 # 0 +0x9580 0x65A7 # 0 +0x9581 0x666E # 0 +0x9582 0x6D6E # 0 +0x9583 0x7236 # 0 +0x9584 0x7B26 # 0 +0x9585 0x8150 # 0 +0x9586 0x819A # 0 +0x9587 0x8299 # 0 +0x9588 0x8B5C # 0 +0x9589 0x8CA0 # 0 +0x958A 0x8CE6 # 0 +0x958B 0x8D74 # 0 +0x958C 0x961C # 0 +0x958D 0x9644 # 0 +0x958E 0x4FAE # 0 +0x958F 0x64AB # 0 +0x9590 0x6B66 # 0 +0x9591 0x821E # 0 +0x9592 0x8461 # 0 +0x9593 0x856A # 0 +0x9594 0x90E8 # 0 +0x9595 0x5C01 # 0 +0x9596 0x6953 # 0 +0x9597 0x98A8 # 0 +0x9598 0x847A # 0 +0x9599 0x8557 # 0 +0x959A 0x4F0F # 0 +0x959B 0x526F # 0 +0x959C 0x5FA9 # 0 +0x959D 0x5E45 # 0 +0x959E 0x670D # 0 +0x959F 0x798F # 0 +0x95A0 0x8179 # 0 +0x95A1 0x8907 # 0 +0x95A2 0x8986 # 0 +0x95A3 0x6DF5 # 0 +0x95A4 0x5F17 # 0 +0x95A5 0x6255 # 0 +0x95A6 0x6CB8 # 0 +0x95A7 0x4ECF # 0 +0x95A8 0x7269 # 0 +0x95A9 0x9B92 # 0 +0x95AA 0x5206 # 0 +0x95AB 0x543B # 0 +0x95AC 0x5674 # 0 +0x95AD 0x58B3 # 0 +0x95AE 0x61A4 # 0 +0x95AF 0x626E # 0 +0x95B0 0x711A # 0 +0x95B1 0x596E # 0 +0x95B2 0x7C89 # 0 +0x95B3 0x7CDE # 0 +0x95B4 0x7D1B # 0 +0x95B5 0x96F0 # 0 +0x95B6 0x6587 # 0 +0x95B7 0x805E # 0 +0x95B8 0x4E19 # 0 +0x95B9 0x4F75 # 0 +0x95BA 0x5175 # 0 +0x95BB 0x5840 # 0 +0x95BC 0x5E63 # 0 +0x95BD 0x5E73 # 0 +0x95BE 0x5F0A # 0 +0x95BF 0x67C4 # 0 +0x95C0 0x4E26 # 0 +0x95C1 0x853D # 0 +0x95C2 0x9589 # 0 +0x95C3 0x965B # 0 +0x95C4 0x7C73 # 0 +0x95C5 0x9801 # 0 +0x95C6 0x50FB # 0 +0x95C7 0x58C1 # 0 +0x95C8 0x7656 # 0 +0x95C9 0x78A7 # 0 +0x95CA 0x5225 # 0 +0x95CB 0x77A5 # 0 +0x95CC 0x8511 # 0 +0x95CD 0x7B86 # 0 +0x95CE 0x504F # 0 +0x95CF 0x5909 # 0 +0x95D0 0x7247 # 0 +0x95D1 0x7BC7 # 0 +0x95D2 0x7DE8 # 0 +0x95D3 0x8FBA # 0 +0x95D4 0x8FD4 # 0 +0x95D5 0x904D # 0 +0x95D6 0x4FBF # 0 +0x95D7 0x52C9 # 0 +0x95D8 0x5A29 # 0 +0x95D9 0x5F01 # 0 +0x95DA 0x97AD # 0 +0x95DB 0x4FDD # 0 +0x95DC 0x8217 # 0 +0x95DD 0x92EA # 0 +0x95DE 0x5703 # 0 +0x95DF 0x6355 # 0 +0x95E0 0x6B69 # 0 +0x95E1 0x752B # 0 +0x95E2 0x88DC # 0 +0x95E3 0x8F14 # 0 +0x95E4 0x7A42 # 0 +0x95E5 0x52DF # 0 +0x95E6 0x5893 # 0 +0x95E7 0x6155 # 0 +0x95E8 0x620A # 0 +0x95E9 0x66AE # 0 +0x95EA 0x6BCD # 0 +0x95EB 0x7C3F # 0 +0x95EC 0x83E9 # 0 +0x95ED 0x5023 # 0 +0x95EE 0x4FF8 # 0 +0x95EF 0x5305 # 0 +0x95F0 0x5446 # 0 +0x95F1 0x5831 # 0 +0x95F2 0x5949 # 0 +0x95F3 0x5B9D # 0 +0x95F4 0x5CF0 # 0 +0x95F5 0x5CEF # 0 +0x95F6 0x5D29 # 0 +0x95F7 0x5E96 # 0 +0x95F8 0x62B1 # 0 +0x95F9 0x6367 # 0 +0x95FA 0x653E # 0 +0x95FB 0x65B9 # 0 +0x95FC 0x670B # 0 +0x9640 0x6CD5 # 0 +0x9641 0x6CE1 # 0 +0x9642 0x70F9 # 0 +0x9643 0x7832 # 0 +0x9644 0x7E2B # 0 +0x9645 0x80DE # 0 +0x9646 0x82B3 # 0 +0x9647 0x840C # 0 +0x9648 0x84EC # 0 +0x9649 0x8702 # 0 +0x964A 0x8912 # 0 +0x964B 0x8A2A # 0 +0x964C 0x8C4A # 0 +0x964D 0x90A6 # 0 +0x964E 0x92D2 # 0 +0x964F 0x98FD # 0 +0x9650 0x9CF3 # 0 +0x9651 0x9D6C # 0 +0x9652 0x4E4F # 0 +0x9653 0x4EA1 # 0 +0x9654 0x508D # 0 +0x9655 0x5256 # 0 +0x9656 0x574A # 0 +0x9657 0x59A8 # 0 +0x9658 0x5E3D # 0 +0x9659 0x5FD8 # 0 +0x965A 0x5FD9 # 0 +0x965B 0x623F # 0 +0x965C 0x66B4 # 0 +0x965D 0x671B # 0 +0x965E 0x67D0 # 0 +0x965F 0x68D2 # 0 +0x9660 0x5192 # 0 +0x9661 0x7D21 # 0 +0x9662 0x80AA # 0 +0x9663 0x81A8 # 0 +0x9664 0x8B00 # 0 +0x9665 0x8C8C # 0 +0x9666 0x8CBF # 0 +0x9667 0x927E # 0 +0x9668 0x9632 # 0 +0x9669 0x5420 # 0 +0x966A 0x982C # 0 +0x966B 0x5317 # 0 +0x966C 0x50D5 # 0 +0x966D 0x535C # 0 +0x966E 0x58A8 # 0 +0x966F 0x64B2 # 0 +0x9670 0x6734 # 0 +0x9671 0x7267 # 0 +0x9672 0x7766 # 0 +0x9673 0x7A46 # 0 +0x9674 0x91E6 # 0 +0x9675 0x52C3 # 0 +0x9676 0x6CA1 # 0 +0x9677 0x6B86 # 0 +0x9678 0x5800 # 0 +0x9679 0x5E4C # 0 +0x967A 0x5954 # 0 +0x967B 0x672C # 0 +0x967C 0x7FFB # 0 +0x967D 0x51E1 # 0 +0x967E 0x76C6 # 0 +0x9680 0x6469 # 0 +0x9681 0x78E8 # 0 +0x9682 0x9B54 # 0 +0x9683 0x9EBB # 0 +0x9684 0x57CB # 0 +0x9685 0x59B9 # 0 +0x9686 0x6627 # 0 +0x9687 0x679A # 0 +0x9688 0x6BCE # 0 +0x9689 0x54E9 # 0 +0x968A 0x69D9 # 0 +0x968B 0x5E55 # 0 +0x968C 0x819C # 0 +0x968D 0x6795 # 0 +0x968E 0x9BAA # 0 +0x968F 0x67FE # 0 +0x9690 0x9C52 # 0 +0x9691 0x685D # 0 +0x9692 0x4EA6 # 0 +0x9693 0x4FE3 # 0 +0x9694 0x53C8 # 0 +0x9695 0x62B9 # 0 +0x9696 0x672B # 0 +0x9697 0x6CAB # 0 +0x9698 0x8FC4 # 0 +0x9699 0x4FAD # 0 +0x969A 0x7E6D # 0 +0x969B 0x9EBF # 0 +0x969C 0x4E07 # 0 +0x969D 0x6162 # 0 +0x969E 0x6E80 # 0 +0x969F 0x6F2B # 0 +0x96A0 0x8513 # 0 +0x96A1 0x5473 # 0 +0x96A2 0x672A # 0 +0x96A3 0x9B45 # 0 +0x96A4 0x5DF3 # 0 +0x96A5 0x7B95 # 0 +0x96A6 0x5CAC # 0 +0x96A7 0x5BC6 # 0 +0x96A8 0x871C # 0 +0x96A9 0x6E4A # 0 +0x96AA 0x84D1 # 0 +0x96AB 0x7A14 # 0 +0x96AC 0x8108 # 0 +0x96AD 0x5999 # 0 +0x96AE 0x7C8D # 0 +0x96AF 0x6C11 # 0 +0x96B0 0x7720 # 0 +0x96B1 0x52D9 # 0 +0x96B2 0x5922 # 0 +0x96B3 0x7121 # 0 +0x96B4 0x725F # 0 +0x96B5 0x77DB # 0 +0x96B6 0x9727 # 0 +0x96B7 0x9D61 # 0 +0x96B8 0x690B # 0 +0x96B9 0x5A7F # 0 +0x96BA 0x5A18 # 0 +0x96BB 0x51A5 # 0 +0x96BC 0x540D # 0 +0x96BD 0x547D # 0 +0x96BE 0x660E # 0 +0x96BF 0x76DF # 0 +0x96C0 0x8FF7 # 0 +0x96C1 0x9298 # 0 +0x96C2 0x9CF4 # 0 +0x96C3 0x59EA # 0 +0x96C4 0x725D # 0 +0x96C5 0x6EC5 # 0 +0x96C6 0x514D # 0 +0x96C7 0x68C9 # 0 +0x96C8 0x7DBF # 0 +0x96C9 0x7DEC # 0 +0x96CA 0x9762 # 0 +0x96CB 0x9EBA # 0 +0x96CC 0x6478 # 0 +0x96CD 0x6A21 # 0 +0x96CE 0x8302 # 0 +0x96CF 0x5984 # 0 +0x96D0 0x5B5F # 0 +0x96D1 0x6BDB # 0 +0x96D2 0x731B # 0 +0x96D3 0x76F2 # 0 +0x96D4 0x7DB2 # 0 +0x96D5 0x8017 # 0 +0x96D6 0x8499 # 0 +0x96D7 0x5132 # 0 +0x96D8 0x6728 # 0 +0x96D9 0x9ED9 # 0 +0x96DA 0x76EE # 0 +0x96DB 0x6762 # 0 +0x96DC 0x52FF # 0 +0x96DD 0x9905 # 0 +0x96DE 0x5C24 # 0 +0x96DF 0x623B # 0 +0x96E0 0x7C7E # 0 +0x96E1 0x8CB0 # 0 +0x96E2 0x554F # 0 +0x96E3 0x60B6 # 0 +0x96E4 0x7D0B # 0 +0x96E5 0x9580 # 0 +0x96E6 0x5301 # 0 +0x96E7 0x4E5F # 0 +0x96E8 0x51B6 # 0 +0x96E9 0x591C # 0 +0x96EA 0x723A # 0 +0x96EB 0x8036 # 0 +0x96EC 0x91CE # 0 +0x96ED 0x5F25 # 0 +0x96EE 0x77E2 # 0 +0x96EF 0x5384 # 0 +0x96F0 0x5F79 # 0 +0x96F1 0x7D04 # 0 +0x96F2 0x85AC # 0 +0x96F3 0x8A33 # 0 +0x96F4 0x8E8D # 0 +0x96F5 0x9756 # 0 +0x96F6 0x67F3 # 0 +0x96F7 0x85AE # 0 +0x96F8 0x9453 # 0 +0x96F9 0x6109 # 0 +0x96FA 0x6108 # 0 +0x96FB 0x6CB9 # 0 +0x96FC 0x7652 # 0 +0x9740 0x8AED # 0 +0x9741 0x8F38 # 0 +0x9742 0x552F # 0 +0x9743 0x4F51 # 0 +0x9744 0x512A # 0 +0x9745 0x52C7 # 0 +0x9746 0x53CB # 0 +0x9747 0x5BA5 # 0 +0x9748 0x5E7D # 0 +0x9749 0x60A0 # 0 +0x974A 0x6182 # 0 +0x974B 0x63D6 # 0 +0x974C 0x6709 # 0 +0x974D 0x67DA # 0 +0x974E 0x6E67 # 0 +0x974F 0x6D8C # 0 +0x9750 0x7336 # 0 +0x9751 0x7337 # 0 +0x9752 0x7531 # 0 +0x9753 0x7950 # 0 +0x9754 0x88D5 # 0 +0x9755 0x8A98 # 0 +0x9756 0x904A # 0 +0x9757 0x9091 # 0 +0x9758 0x90F5 # 0 +0x9759 0x96C4 # 0 +0x975A 0x878D # 0 +0x975B 0x5915 # 0 +0x975C 0x4E88 # 0 +0x975D 0x4F59 # 0 +0x975E 0x4E0E # 0 +0x975F 0x8A89 # 0 +0x9760 0x8F3F # 0 +0x9761 0x9810 # 0 +0x9762 0x50AD # 0 +0x9763 0x5E7C # 0 +0x9764 0x5996 # 0 +0x9765 0x5BB9 # 0 +0x9766 0x5EB8 # 0 +0x9767 0x63DA # 0 +0x9768 0x63FA # 0 +0x9769 0x64C1 # 0 +0x976A 0x66DC # 0 +0x976B 0x694A # 0 +0x976C 0x69D8 # 0 +0x976D 0x6D0B # 0 +0x976E 0x6EB6 # 0 +0x976F 0x7194 # 0 +0x9770 0x7528 # 0 +0x9771 0x7AAF # 0 +0x9772 0x7F8A # 0 +0x9773 0x8000 # 0 +0x9774 0x8449 # 0 +0x9775 0x84C9 # 0 +0x9776 0x8981 # 0 +0x9777 0x8B21 # 0 +0x9778 0x8E0A # 0 +0x9779 0x9065 # 0 +0x977A 0x967D # 0 +0x977B 0x990A # 0 +0x977C 0x617E # 0 +0x977D 0x6291 # 0 +0x977E 0x6B32 # 0 +0x9780 0x6C83 # 0 +0x9781 0x6D74 # 0 +0x9782 0x7FCC # 0 +0x9783 0x7FFC # 0 +0x9784 0x6DC0 # 0 +0x9785 0x7F85 # 0 +0x9786 0x87BA # 0 +0x9787 0x88F8 # 0 +0x9788 0x6765 # 0 +0x9789 0x83B1 # 0 +0x978A 0x983C # 0 +0x978B 0x96F7 # 0 +0x978C 0x6D1B # 0 +0x978D 0x7D61 # 0 +0x978E 0x843D # 0 +0x978F 0x916A # 0 +0x9790 0x4E71 # 0 +0x9791 0x5375 # 0 +0x9792 0x5D50 # 0 +0x9793 0x6B04 # 0 +0x9794 0x6FEB # 0 +0x9795 0x85CD # 0 +0x9796 0x862D # 0 +0x9797 0x89A7 # 0 +0x9798 0x5229 # 0 +0x9799 0x540F # 0 +0x979A 0x5C65 # 0 +0x979B 0x674E # 0 +0x979C 0x68A8 # 0 +0x979D 0x7406 # 0 +0x979E 0x7483 # 0 +0x979F 0x75E2 # 0 +0x97A0 0x88CF # 0 +0x97A1 0x88E1 # 0 +0x97A2 0x91CC # 0 +0x97A3 0x96E2 # 0 +0x97A4 0x9678 # 0 +0x97A5 0x5F8B # 0 +0x97A6 0x7387 # 0 +0x97A7 0x7ACB # 0 +0x97A8 0x844E # 0 +0x97A9 0x63A0 # 0 +0x97AA 0x7565 # 0 +0x97AB 0x5289 # 0 +0x97AC 0x6D41 # 0 +0x97AD 0x6E9C # 0 +0x97AE 0x7409 # 0 +0x97AF 0x7559 # 0 +0x97B0 0x786B # 0 +0x97B1 0x7C92 # 0 +0x97B2 0x9686 # 0 +0x97B3 0x7ADC # 0 +0x97B4 0x9F8D # 0 +0x97B5 0x4FB6 # 0 +0x97B6 0x616E # 0 +0x97B7 0x65C5 # 0 +0x97B8 0x865C # 0 +0x97B9 0x4E86 # 0 +0x97BA 0x4EAE # 0 +0x97BB 0x50DA # 0 +0x97BC 0x4E21 # 0 +0x97BD 0x51CC # 0 +0x97BE 0x5BEE # 0 +0x97BF 0x6599 # 0 +0x97C0 0x6881 # 0 +0x97C1 0x6DBC # 0 +0x97C2 0x731F # 0 +0x97C3 0x7642 # 0 +0x97C4 0x77AD # 0 +0x97C5 0x7A1C # 0 +0x97C6 0x7CE7 # 0 +0x97C7 0x826F # 0 +0x97C8 0x8AD2 # 0 +0x97C9 0x907C # 0 +0x97CA 0x91CF # 0 +0x97CB 0x9675 # 0 +0x97CC 0x9818 # 0 +0x97CD 0x529B # 0 +0x97CE 0x7DD1 # 0 +0x97CF 0x502B # 0 +0x97D0 0x5398 # 0 +0x97D1 0x6797 # 0 +0x97D2 0x6DCB # 0 +0x97D3 0x71D0 # 0 +0x97D4 0x7433 # 0 +0x97D5 0x81E8 # 0 +0x97D6 0x8F2A # 0 +0x97D7 0x96A3 # 0 +0x97D8 0x9C57 # 0 +0x97D9 0x9E9F # 0 +0x97DA 0x7460 # 0 +0x97DB 0x5841 # 0 +0x97DC 0x6D99 # 0 +0x97DD 0x7D2F # 0 +0x97DE 0x985E # 0 +0x97DF 0x4EE4 # 0 +0x97E0 0x4F36 # 0 +0x97E1 0x4F8B # 0 +0x97E2 0x51B7 # 0 +0x97E3 0x52B1 # 0 +0x97E4 0x5DBA # 0 +0x97E5 0x601C # 0 +0x97E6 0x73B2 # 0 +0x97E7 0x793C # 0 +0x97E8 0x82D3 # 0 +0x97E9 0x9234 # 0 +0x97EA 0x96B7 # 0 +0x97EB 0x96F6 # 0 +0x97EC 0x970A # 0 +0x97ED 0x9E97 # 0 +0x97EE 0x9F62 # 0 +0x97EF 0x66A6 # 0 +0x97F0 0x6B74 # 0 +0x97F1 0x5217 # 0 +0x97F2 0x52A3 # 0 +0x97F3 0x70C8 # 0 +0x97F4 0x88C2 # 0 +0x97F5 0x5EC9 # 0 +0x97F6 0x604B # 0 +0x97F7 0x6190 # 0 +0x97F8 0x6F23 # 0 +0x97F9 0x7149 # 0 +0x97FA 0x7C3E # 0 +0x97FB 0x7DF4 # 0 +0x97FC 0x806F # 0 +0x9840 0x84EE # 0 +0x9841 0x9023 # 0 +0x9842 0x932C # 0 +0x9843 0x5442 # 0 +0x9844 0x9B6F # 0 +0x9845 0x6AD3 # 0 +0x9846 0x7089 # 0 +0x9847 0x8CC2 # 0 +0x9848 0x8DEF # 0 +0x9849 0x9732 # 0 +0x984A 0x52B4 # 0 +0x984B 0x5A41 # 0 +0x984C 0x5ECA # 0 +0x984D 0x5F04 # 0 +0x984E 0x6717 # 0 +0x984F 0x697C # 0 +0x9850 0x6994 # 0 +0x9851 0x6D6A # 0 +0x9852 0x6F0F # 0 +0x9853 0x7262 # 0 +0x9854 0x72FC # 0 +0x9855 0x7BED # 0 +0x9856 0x8001 # 0 +0x9857 0x807E # 0 +0x9858 0x874B # 0 +0x9859 0x90CE # 0 +0x985A 0x516D # 0 +0x985B 0x9E93 # 0 +0x985C 0x7984 # 0 +0x985D 0x808B # 0 +0x985E 0x9332 # 0 +0x985F 0x8AD6 # 0 +0x9860 0x502D # 0 +0x9861 0x548C # 0 +0x9862 0x8A71 # 0 +0x9863 0x6B6A # 0 +0x9864 0x8CC4 # 0 +0x9865 0x8107 # 0 +0x9866 0x60D1 # 0 +0x9867 0x67A0 # 0 +0x9868 0x9DF2 # 0 +0x9869 0x4E99 # 0 +0x986A 0x4E98 # 0 +0x986B 0x9C10 # 0 +0x986C 0x8A6B # 0 +0x986D 0x85C1 # 0 +0x986E 0x8568 # 0 +0x986F 0x6900 # 0 +0x9870 0x6E7E # 0 +0x9871 0x7897 # 0 +0x9872 0x8155 # 0 +0x989F 0x5F0C # 0 +0x98A0 0x4E10 # 0 +0x98A1 0x4E15 # 0 +0x98A2 0x4E2A # 0 +0x98A3 0x4E31 # 0 +0x98A4 0x4E36 # 0 +0x98A5 0x4E3C # 0 +0x98A6 0x4E3F # 0 +0x98A7 0x4E42 # 0 +0x98A8 0x4E56 # 0 +0x98A9 0x4E58 # 0 +0x98AA 0x4E82 # 0 +0x98AB 0x4E85 # 0 +0x98AC 0x8C6B # 0 +0x98AD 0x4E8A # 0 +0x98AE 0x8212 # 0 +0x98AF 0x5F0D # 0 +0x98B0 0x4E8E # 0 +0x98B1 0x4E9E # 0 +0x98B2 0x4E9F # 0 +0x98B3 0x4EA0 # 0 +0x98B4 0x4EA2 # 0 +0x98B5 0x4EB0 # 0 +0x98B6 0x4EB3 # 0 +0x98B7 0x4EB6 # 0 +0x98B8 0x4ECE # 0 +0x98B9 0x4ECD # 0 +0x98BA 0x4EC4 # 0 +0x98BB 0x4EC6 # 0 +0x98BC 0x4EC2 # 0 +0x98BD 0x4ED7 # 0 +0x98BE 0x4EDE # 0 +0x98BF 0x4EED # 0 +0x98C0 0x4EDF # 0 +0x98C1 0x4EF7 # 0 +0x98C2 0x4F09 # 0 +0x98C3 0x4F5A # 0 +0x98C4 0x4F30 # 0 +0x98C5 0x4F5B # 0 +0x98C6 0x4F5D # 0 +0x98C7 0x4F57 # 0 +0x98C8 0x4F47 # 0 +0x98C9 0x4F76 # 0 +0x98CA 0x4F88 # 0 +0x98CB 0x4F8F # 0 +0x98CC 0x4F98 # 0 +0x98CD 0x4F7B # 0 +0x98CE 0x4F69 # 0 +0x98CF 0x4F70 # 0 +0x98D0 0x4F91 # 0 +0x98D1 0x4F6F # 0 +0x98D2 0x4F86 # 0 +0x98D3 0x4F96 # 0 +0x98D4 0x5118 # 0 +0x98D5 0x4FD4 # 0 +0x98D6 0x4FDF # 0 +0x98D7 0x4FCE # 0 +0x98D8 0x4FD8 # 0 +0x98D9 0x4FDB # 0 +0x98DA 0x4FD1 # 0 +0x98DB 0x4FDA # 0 +0x98DC 0x4FD0 # 0 +0x98DD 0x4FE4 # 0 +0x98DE 0x4FE5 # 0 +0x98DF 0x501A # 0 +0x98E0 0x5028 # 0 +0x98E1 0x5014 # 0 +0x98E2 0x502A # 0 +0x98E3 0x5025 # 0 +0x98E4 0x5005 # 0 +0x98E5 0x4F1C # 0 +0x98E6 0x4FF6 # 0 +0x98E7 0x5021 # 0 +0x98E8 0x5029 # 0 +0x98E9 0x502C # 0 +0x98EA 0x4FFE # 0 +0x98EB 0x4FEF # 0 +0x98EC 0x5011 # 0 +0x98ED 0x5006 # 0 +0x98EE 0x5043 # 0 +0x98EF 0x5047 # 0 +0x98F0 0x6703 # 0 +0x98F1 0x5055 # 0 +0x98F2 0x5050 # 0 +0x98F3 0x5048 # 0 +0x98F4 0x505A # 0 +0x98F5 0x5056 # 0 +0x98F6 0x506C # 0 +0x98F7 0x5078 # 0 +0x98F8 0x5080 # 0 +0x98F9 0x509A # 0 +0x98FA 0x5085 # 0 +0x98FB 0x50B4 # 0 +0x98FC 0x50B2 # 0 +0x9940 0x50C9 # 0 +0x9941 0x50CA # 0 +0x9942 0x50B3 # 0 +0x9943 0x50C2 # 0 +0x9944 0x50D6 # 0 +0x9945 0x50DE # 0 +0x9946 0x50E5 # 0 +0x9947 0x50ED # 0 +0x9948 0x50E3 # 0 +0x9949 0x50EE # 0 +0x994A 0x50F9 # 0 +0x994B 0x50F5 # 0 +0x994C 0x5109 # 0 +0x994D 0x5101 # 0 +0x994E 0x5102 # 0 +0x994F 0x5116 # 0 +0x9950 0x5115 # 0 +0x9951 0x5114 # 0 +0x9952 0x511A # 0 +0x9953 0x5121 # 0 +0x9954 0x513A # 0 +0x9955 0x5137 # 0 +0x9956 0x513C # 0 +0x9957 0x513B # 0 +0x9958 0x513F # 0 +0x9959 0x5140 # 0 +0x995A 0x5152 # 0 +0x995B 0x514C # 0 +0x995C 0x5154 # 0 +0x995D 0x5162 # 0 +0x995E 0x7AF8 # 0 +0x995F 0x5169 # 0 +0x9960 0x516A # 0 +0x9961 0x516E # 0 +0x9962 0x5180 # 0 +0x9963 0x5182 # 0 +0x9964 0x56D8 # 0 +0x9965 0x518C # 0 +0x9966 0x5189 # 0 +0x9967 0x518F # 0 +0x9968 0x5191 # 0 +0x9969 0x5193 # 0 +0x996A 0x5195 # 0 +0x996B 0x5196 # 0 +0x996C 0x51A4 # 0 +0x996D 0x51A6 # 0 +0x996E 0x51A2 # 0 +0x996F 0x51A9 # 0 +0x9970 0x51AA # 0 +0x9971 0x51AB # 0 +0x9972 0x51B3 # 0 +0x9973 0x51B1 # 0 +0x9974 0x51B2 # 0 +0x9975 0x51B0 # 0 +0x9976 0x51B5 # 0 +0x9977 0x51BD # 0 +0x9978 0x51C5 # 0 +0x9979 0x51C9 # 0 +0x997A 0x51DB # 0 +0x997B 0x51E0 # 0 +0x997C 0x8655 # 0 +0x997D 0x51E9 # 0 +0x997E 0x51ED # 0 +0x9980 0x51F0 # 0 +0x9981 0x51F5 # 0 +0x9982 0x51FE # 0 +0x9983 0x5204 # 0 +0x9984 0x520B # 0 +0x9985 0x5214 # 0 +0x9986 0x520E # 0 +0x9987 0x5227 # 0 +0x9988 0x522A # 0 +0x9989 0x522E # 0 +0x998A 0x5233 # 0 +0x998B 0x5239 # 0 +0x998C 0x524F # 0 +0x998D 0x5244 # 0 +0x998E 0x524B # 0 +0x998F 0x524C # 0 +0x9990 0x525E # 0 +0x9991 0x5254 # 0 +0x9992 0x526A # 0 +0x9993 0x5274 # 0 +0x9994 0x5269 # 0 +0x9995 0x5273 # 0 +0x9996 0x527F # 0 +0x9997 0x527D # 0 +0x9998 0x528D # 0 +0x9999 0x5294 # 0 +0x999A 0x5292 # 0 +0x999B 0x5271 # 0 +0x999C 0x5288 # 0 +0x999D 0x5291 # 0 +0x999E 0x8FA8 # 0 +0x999F 0x8FA7 # 0 +0x99A0 0x52AC # 0 +0x99A1 0x52AD # 0 +0x99A2 0x52BC # 0 +0x99A3 0x52B5 # 0 +0x99A4 0x52C1 # 0 +0x99A5 0x52CD # 0 +0x99A6 0x52D7 # 0 +0x99A7 0x52DE # 0 +0x99A8 0x52E3 # 0 +0x99A9 0x52E6 # 0 +0x99AA 0x98ED # 0 +0x99AB 0x52E0 # 0 +0x99AC 0x52F3 # 0 +0x99AD 0x52F5 # 0 +0x99AE 0x52F8 # 0 +0x99AF 0x52F9 # 0 +0x99B0 0x5306 # 0 +0x99B1 0x5308 # 0 +0x99B2 0x7538 # 0 +0x99B3 0x530D # 0 +0x99B4 0x5310 # 0 +0x99B5 0x530F # 0 +0x99B6 0x5315 # 0 +0x99B7 0x531A # 0 +0x99B8 0x5323 # 0 +0x99B9 0x532F # 0 +0x99BA 0x5331 # 0 +0x99BB 0x5333 # 0 +0x99BC 0x5338 # 0 +0x99BD 0x5340 # 0 +0x99BE 0x5346 # 0 +0x99BF 0x5345 # 0 +0x99C0 0x4E17 # 0 +0x99C1 0x5349 # 0 +0x99C2 0x534D # 0 +0x99C3 0x51D6 # 0 +0x99C4 0x535E # 0 +0x99C5 0x5369 # 0 +0x99C6 0x536E # 0 +0x99C7 0x5918 # 0 +0x99C8 0x537B # 0 +0x99C9 0x5377 # 0 +0x99CA 0x5382 # 0 +0x99CB 0x5396 # 0 +0x99CC 0x53A0 # 0 +0x99CD 0x53A6 # 0 +0x99CE 0x53A5 # 0 +0x99CF 0x53AE # 0 +0x99D0 0x53B0 # 0 +0x99D1 0x53B6 # 0 +0x99D2 0x53C3 # 0 +0x99D3 0x7C12 # 0 +0x99D4 0x96D9 # 0 +0x99D5 0x53DF # 0 +0x99D6 0x66FC # 0 +0x99D7 0x71EE # 0 +0x99D8 0x53EE # 0 +0x99D9 0x53E8 # 0 +0x99DA 0x53ED # 0 +0x99DB 0x53FA # 0 +0x99DC 0x5401 # 0 +0x99DD 0x543D # 0 +0x99DE 0x5440 # 0 +0x99DF 0x542C # 0 +0x99E0 0x542D # 0 +0x99E1 0x543C # 0 +0x99E2 0x542E # 0 +0x99E3 0x5436 # 0 +0x99E4 0x5429 # 0 +0x99E5 0x541D # 0 +0x99E6 0x544E # 0 +0x99E7 0x548F # 0 +0x99E8 0x5475 # 0 +0x99E9 0x548E # 0 +0x99EA 0x545F # 0 +0x99EB 0x5471 # 0 +0x99EC 0x5477 # 0 +0x99ED 0x5470 # 0 +0x99EE 0x5492 # 0 +0x99EF 0x547B # 0 +0x99F0 0x5480 # 0 +0x99F1 0x5476 # 0 +0x99F2 0x5484 # 0 +0x99F3 0x5490 # 0 +0x99F4 0x5486 # 0 +0x99F5 0x54C7 # 0 +0x99F6 0x54A2 # 0 +0x99F7 0x54B8 # 0 +0x99F8 0x54A5 # 0 +0x99F9 0x54AC # 0 +0x99FA 0x54C4 # 0 +0x99FB 0x54C8 # 0 +0x99FC 0x54A8 # 0 +0x9A40 0x54AB # 0 +0x9A41 0x54C2 # 0 +0x9A42 0x54A4 # 0 +0x9A43 0x54BE # 0 +0x9A44 0x54BC # 0 +0x9A45 0x54D8 # 0 +0x9A46 0x54E5 # 0 +0x9A47 0x54E6 # 0 +0x9A48 0x550F # 0 +0x9A49 0x5514 # 0 +0x9A4A 0x54FD # 0 +0x9A4B 0x54EE # 0 +0x9A4C 0x54ED # 0 +0x9A4D 0x54FA # 0 +0x9A4E 0x54E2 # 0 +0x9A4F 0x5539 # 0 +0x9A50 0x5540 # 0 +0x9A51 0x5563 # 0 +0x9A52 0x554C # 0 +0x9A53 0x552E # 0 +0x9A54 0x555C # 0 +0x9A55 0x5545 # 0 +0x9A56 0x5556 # 0 +0x9A57 0x5557 # 0 +0x9A58 0x5538 # 0 +0x9A59 0x5533 # 0 +0x9A5A 0x555D # 0 +0x9A5B 0x5599 # 0 +0x9A5C 0x5580 # 0 +0x9A5D 0x54AF # 0 +0x9A5E 0x558A # 0 +0x9A5F 0x559F # 0 +0x9A60 0x557B # 0 +0x9A61 0x557E # 0 +0x9A62 0x5598 # 0 +0x9A63 0x559E # 0 +0x9A64 0x55AE # 0 +0x9A65 0x557C # 0 +0x9A66 0x5583 # 0 +0x9A67 0x55A9 # 0 +0x9A68 0x5587 # 0 +0x9A69 0x55A8 # 0 +0x9A6A 0x55DA # 0 +0x9A6B 0x55C5 # 0 +0x9A6C 0x55DF # 0 +0x9A6D 0x55C4 # 0 +0x9A6E 0x55DC # 0 +0x9A6F 0x55E4 # 0 +0x9A70 0x55D4 # 0 +0x9A71 0x5614 # 0 +0x9A72 0x55F7 # 0 +0x9A73 0x5616 # 0 +0x9A74 0x55FE # 0 +0x9A75 0x55FD # 0 +0x9A76 0x561B # 0 +0x9A77 0x55F9 # 0 +0x9A78 0x564E # 0 +0x9A79 0x5650 # 0 +0x9A7A 0x71DF # 0 +0x9A7B 0x5634 # 0 +0x9A7C 0x5636 # 0 +0x9A7D 0x5632 # 0 +0x9A7E 0x5638 # 0 +0x9A80 0x566B # 0 +0x9A81 0x5664 # 0 +0x9A82 0x562F # 0 +0x9A83 0x566C # 0 +0x9A84 0x566A # 0 +0x9A85 0x5686 # 0 +0x9A86 0x5680 # 0 +0x9A87 0x568A # 0 +0x9A88 0x56A0 # 0 +0x9A89 0x5694 # 0 +0x9A8A 0x568F # 0 +0x9A8B 0x56A5 # 0 +0x9A8C 0x56AE # 0 +0x9A8D 0x56B6 # 0 +0x9A8E 0x56B4 # 0 +0x9A8F 0x56C2 # 0 +0x9A90 0x56BC # 0 +0x9A91 0x56C1 # 0 +0x9A92 0x56C3 # 0 +0x9A93 0x56C0 # 0 +0x9A94 0x56C8 # 0 +0x9A95 0x56CE # 0 +0x9A96 0x56D1 # 0 +0x9A97 0x56D3 # 0 +0x9A98 0x56D7 # 0 +0x9A99 0x56EE # 0 +0x9A9A 0x56F9 # 0 +0x9A9B 0x5700 # 0 +0x9A9C 0x56FF # 0 +0x9A9D 0x5704 # 0 +0x9A9E 0x5709 # 0 +0x9A9F 0x5708 # 0 +0x9AA0 0x570B # 0 +0x9AA1 0x570D # 0 +0x9AA2 0x5713 # 0 +0x9AA3 0x5718 # 0 +0x9AA4 0x5716 # 0 +0x9AA5 0x55C7 # 0 +0x9AA6 0x571C # 0 +0x9AA7 0x5726 # 0 +0x9AA8 0x5737 # 0 +0x9AA9 0x5738 # 0 +0x9AAA 0x574E # 0 +0x9AAB 0x573B # 0 +0x9AAC 0x5740 # 0 +0x9AAD 0x574F # 0 +0x9AAE 0x5769 # 0 +0x9AAF 0x57C0 # 0 +0x9AB0 0x5788 # 0 +0x9AB1 0x5761 # 0 +0x9AB2 0x577F # 0 +0x9AB3 0x5789 # 0 +0x9AB4 0x5793 # 0 +0x9AB5 0x57A0 # 0 +0x9AB6 0x57B3 # 0 +0x9AB7 0x57A4 # 0 +0x9AB8 0x57AA # 0 +0x9AB9 0x57B0 # 0 +0x9ABA 0x57C3 # 0 +0x9ABB 0x57C6 # 0 +0x9ABC 0x57D4 # 0 +0x9ABD 0x57D2 # 0 +0x9ABE 0x57D3 # 0 +0x9ABF 0x580A # 0 +0x9AC0 0x57D6 # 0 +0x9AC1 0x57E3 # 0 +0x9AC2 0x580B # 0 +0x9AC3 0x5819 # 0 +0x9AC4 0x581D # 0 +0x9AC5 0x5872 # 0 +0x9AC6 0x5821 # 0 +0x9AC7 0x5862 # 0 +0x9AC8 0x584B # 0 +0x9AC9 0x5870 # 0 +0x9ACA 0x6BC0 # 0 +0x9ACB 0x5852 # 0 +0x9ACC 0x583D # 0 +0x9ACD 0x5879 # 0 +0x9ACE 0x5885 # 0 +0x9ACF 0x58B9 # 0 +0x9AD0 0x589F # 0 +0x9AD1 0x58AB # 0 +0x9AD2 0x58BA # 0 +0x9AD3 0x58DE # 0 +0x9AD4 0x58BB # 0 +0x9AD5 0x58B8 # 0 +0x9AD6 0x58AE # 0 +0x9AD7 0x58C5 # 0 +0x9AD8 0x58D3 # 0 +0x9AD9 0x58D1 # 0 +0x9ADA 0x58D7 # 0 +0x9ADB 0x58D9 # 0 +0x9ADC 0x58D8 # 0 +0x9ADD 0x58E5 # 0 +0x9ADE 0x58DC # 0 +0x9ADF 0x58E4 # 0 +0x9AE0 0x58DF # 0 +0x9AE1 0x58EF # 0 +0x9AE2 0x58FA # 0 +0x9AE3 0x58F9 # 0 +0x9AE4 0x58FB # 0 +0x9AE5 0x58FC # 0 +0x9AE6 0x58FD # 0 +0x9AE7 0x5902 # 0 +0x9AE8 0x590A # 0 +0x9AE9 0x5910 # 0 +0x9AEA 0x591B # 0 +0x9AEB 0x68A6 # 0 +0x9AEC 0x5925 # 0 +0x9AED 0x592C # 0 +0x9AEE 0x592D # 0 +0x9AEF 0x5932 # 0 +0x9AF0 0x5938 # 0 +0x9AF1 0x593E # 0 +0x9AF2 0x7AD2 # 0 +0x9AF3 0x5955 # 0 +0x9AF4 0x5950 # 0 +0x9AF5 0x594E # 0 +0x9AF6 0x595A # 0 +0x9AF7 0x5958 # 0 +0x9AF8 0x5962 # 0 +0x9AF9 0x5960 # 0 +0x9AFA 0x5967 # 0 +0x9AFB 0x596C # 0 +0x9AFC 0x5969 # 0 +0x9B40 0x5978 # 0 +0x9B41 0x5981 # 0 +0x9B42 0x599D # 0 +0x9B43 0x4F5E # 0 +0x9B44 0x4FAB # 0 +0x9B45 0x59A3 # 0 +0x9B46 0x59B2 # 0 +0x9B47 0x59C6 # 0 +0x9B48 0x59E8 # 0 +0x9B49 0x59DC # 0 +0x9B4A 0x598D # 0 +0x9B4B 0x59D9 # 0 +0x9B4C 0x59DA # 0 +0x9B4D 0x5A25 # 0 +0x9B4E 0x5A1F # 0 +0x9B4F 0x5A11 # 0 +0x9B50 0x5A1C # 0 +0x9B51 0x5A09 # 0 +0x9B52 0x5A1A # 0 +0x9B53 0x5A40 # 0 +0x9B54 0x5A6C # 0 +0x9B55 0x5A49 # 0 +0x9B56 0x5A35 # 0 +0x9B57 0x5A36 # 0 +0x9B58 0x5A62 # 0 +0x9B59 0x5A6A # 0 +0x9B5A 0x5A9A # 0 +0x9B5B 0x5ABC # 0 +0x9B5C 0x5ABE # 0 +0x9B5D 0x5ACB # 0 +0x9B5E 0x5AC2 # 0 +0x9B5F 0x5ABD # 0 +0x9B60 0x5AE3 # 0 +0x9B61 0x5AD7 # 0 +0x9B62 0x5AE6 # 0 +0x9B63 0x5AE9 # 0 +0x9B64 0x5AD6 # 0 +0x9B65 0x5AFA # 0 +0x9B66 0x5AFB # 0 +0x9B67 0x5B0C # 0 +0x9B68 0x5B0B # 0 +0x9B69 0x5B16 # 0 +0x9B6A 0x5B32 # 0 +0x9B6B 0x5AD0 # 0 +0x9B6C 0x5B2A # 0 +0x9B6D 0x5B36 # 0 +0x9B6E 0x5B3E # 0 +0x9B6F 0x5B43 # 0 +0x9B70 0x5B45 # 0 +0x9B71 0x5B40 # 0 +0x9B72 0x5B51 # 0 +0x9B73 0x5B55 # 0 +0x9B74 0x5B5A # 0 +0x9B75 0x5B5B # 0 +0x9B76 0x5B65 # 0 +0x9B77 0x5B69 # 0 +0x9B78 0x5B70 # 0 +0x9B79 0x5B73 # 0 +0x9B7A 0x5B75 # 0 +0x9B7B 0x5B78 # 0 +0x9B7C 0x6588 # 0 +0x9B7D 0x5B7A # 0 +0x9B7E 0x5B80 # 0 +0x9B80 0x5B83 # 0 +0x9B81 0x5BA6 # 0 +0x9B82 0x5BB8 # 0 +0x9B83 0x5BC3 # 0 +0x9B84 0x5BC7 # 0 +0x9B85 0x5BC9 # 0 +0x9B86 0x5BD4 # 0 +0x9B87 0x5BD0 # 0 +0x9B88 0x5BE4 # 0 +0x9B89 0x5BE6 # 0 +0x9B8A 0x5BE2 # 0 +0x9B8B 0x5BDE # 0 +0x9B8C 0x5BE5 # 0 +0x9B8D 0x5BEB # 0 +0x9B8E 0x5BF0 # 0 +0x9B8F 0x5BF6 # 0 +0x9B90 0x5BF3 # 0 +0x9B91 0x5C05 # 0 +0x9B92 0x5C07 # 0 +0x9B93 0x5C08 # 0 +0x9B94 0x5C0D # 0 +0x9B95 0x5C13 # 0 +0x9B96 0x5C20 # 0 +0x9B97 0x5C22 # 0 +0x9B98 0x5C28 # 0 +0x9B99 0x5C38 # 0 +0x9B9A 0x5C39 # 0 +0x9B9B 0x5C41 # 0 +0x9B9C 0x5C46 # 0 +0x9B9D 0x5C4E # 0 +0x9B9E 0x5C53 # 0 +0x9B9F 0x5C50 # 0 +0x9BA0 0x5C4F # 0 +0x9BA1 0x5B71 # 0 +0x9BA2 0x5C6C # 0 +0x9BA3 0x5C6E # 0 +0x9BA4 0x4E62 # 0 +0x9BA5 0x5C76 # 0 +0x9BA6 0x5C79 # 0 +0x9BA7 0x5C8C # 0 +0x9BA8 0x5C91 # 0 +0x9BA9 0x5C94 # 0 +0x9BAA 0x599B # 0 +0x9BAB 0x5CAB # 0 +0x9BAC 0x5CBB # 0 +0x9BAD 0x5CB6 # 0 +0x9BAE 0x5CBC # 0 +0x9BAF 0x5CB7 # 0 +0x9BB0 0x5CC5 # 0 +0x9BB1 0x5CBE # 0 +0x9BB2 0x5CC7 # 0 +0x9BB3 0x5CD9 # 0 +0x9BB4 0x5CE9 # 0 +0x9BB5 0x5CFD # 0 +0x9BB6 0x5CFA # 0 +0x9BB7 0x5CED # 0 +0x9BB8 0x5D8C # 0 +0x9BB9 0x5CEA # 0 +0x9BBA 0x5D0B # 0 +0x9BBB 0x5D15 # 0 +0x9BBC 0x5D17 # 0 +0x9BBD 0x5D5C # 0 +0x9BBE 0x5D1F # 0 +0x9BBF 0x5D1B # 0 +0x9BC0 0x5D11 # 0 +0x9BC1 0x5D14 # 0 +0x9BC2 0x5D22 # 0 +0x9BC3 0x5D1A # 0 +0x9BC4 0x5D19 # 0 +0x9BC5 0x5D18 # 0 +0x9BC6 0x5D4C # 0 +0x9BC7 0x5D52 # 0 +0x9BC8 0x5D4E # 0 +0x9BC9 0x5D4B # 0 +0x9BCA 0x5D6C # 0 +0x9BCB 0x5D73 # 0 +0x9BCC 0x5D76 # 0 +0x9BCD 0x5D87 # 0 +0x9BCE 0x5D84 # 0 +0x9BCF 0x5D82 # 0 +0x9BD0 0x5DA2 # 0 +0x9BD1 0x5D9D # 0 +0x9BD2 0x5DAC # 0 +0x9BD3 0x5DAE # 0 +0x9BD4 0x5DBD # 0 +0x9BD5 0x5D90 # 0 +0x9BD6 0x5DB7 # 0 +0x9BD7 0x5DBC # 0 +0x9BD8 0x5DC9 # 0 +0x9BD9 0x5DCD # 0 +0x9BDA 0x5DD3 # 0 +0x9BDB 0x5DD2 # 0 +0x9BDC 0x5DD6 # 0 +0x9BDD 0x5DDB # 0 +0x9BDE 0x5DEB # 0 +0x9BDF 0x5DF2 # 0 +0x9BE0 0x5DF5 # 0 +0x9BE1 0x5E0B # 0 +0x9BE2 0x5E1A # 0 +0x9BE3 0x5E19 # 0 +0x9BE4 0x5E11 # 0 +0x9BE5 0x5E1B # 0 +0x9BE6 0x5E36 # 0 +0x9BE7 0x5E37 # 0 +0x9BE8 0x5E44 # 0 +0x9BE9 0x5E43 # 0 +0x9BEA 0x5E40 # 0 +0x9BEB 0x5E4E # 0 +0x9BEC 0x5E57 # 0 +0x9BED 0x5E54 # 0 +0x9BEE 0x5E5F # 0 +0x9BEF 0x5E62 # 0 +0x9BF0 0x5E64 # 0 +0x9BF1 0x5E47 # 0 +0x9BF2 0x5E75 # 0 +0x9BF3 0x5E76 # 0 +0x9BF4 0x5E7A # 0 +0x9BF5 0x9EBC # 0 +0x9BF6 0x5E7F # 0 +0x9BF7 0x5EA0 # 0 +0x9BF8 0x5EC1 # 0 +0x9BF9 0x5EC2 # 0 +0x9BFA 0x5EC8 # 0 +0x9BFB 0x5ED0 # 0 +0x9BFC 0x5ECF # 0 +0x9C40 0x5ED6 # 0 +0x9C41 0x5EE3 # 0 +0x9C42 0x5EDD # 0 +0x9C43 0x5EDA # 0 +0x9C44 0x5EDB # 0 +0x9C45 0x5EE2 # 0 +0x9C46 0x5EE1 # 0 +0x9C47 0x5EE8 # 0 +0x9C48 0x5EE9 # 0 +0x9C49 0x5EEC # 0 +0x9C4A 0x5EF1 # 0 +0x9C4B 0x5EF3 # 0 +0x9C4C 0x5EF0 # 0 +0x9C4D 0x5EF4 # 0 +0x9C4E 0x5EF8 # 0 +0x9C4F 0x5EFE # 0 +0x9C50 0x5F03 # 0 +0x9C51 0x5F09 # 0 +0x9C52 0x5F5D # 0 +0x9C53 0x5F5C # 0 +0x9C54 0x5F0B # 0 +0x9C55 0x5F11 # 0 +0x9C56 0x5F16 # 0 +0x9C57 0x5F29 # 0 +0x9C58 0x5F2D # 0 +0x9C59 0x5F38 # 0 +0x9C5A 0x5F41 # 0 +0x9C5B 0x5F48 # 0 +0x9C5C 0x5F4C # 0 +0x9C5D 0x5F4E # 0 +0x9C5E 0x5F2F # 0 +0x9C5F 0x5F51 # 0 +0x9C60 0x5F56 # 0 +0x9C61 0x5F57 # 0 +0x9C62 0x5F59 # 0 +0x9C63 0x5F61 # 0 +0x9C64 0x5F6D # 0 +0x9C65 0x5F73 # 0 +0x9C66 0x5F77 # 0 +0x9C67 0x5F83 # 0 +0x9C68 0x5F82 # 0 +0x9C69 0x5F7F # 0 +0x9C6A 0x5F8A # 0 +0x9C6B 0x5F88 # 0 +0x9C6C 0x5F91 # 0 +0x9C6D 0x5F87 # 0 +0x9C6E 0x5F9E # 0 +0x9C6F 0x5F99 # 0 +0x9C70 0x5F98 # 0 +0x9C71 0x5FA0 # 0 +0x9C72 0x5FA8 # 0 +0x9C73 0x5FAD # 0 +0x9C74 0x5FBC # 0 +0x9C75 0x5FD6 # 0 +0x9C76 0x5FFB # 0 +0x9C77 0x5FE4 # 0 +0x9C78 0x5FF8 # 0 +0x9C79 0x5FF1 # 0 +0x9C7A 0x5FDD # 0 +0x9C7B 0x60B3 # 0 +0x9C7C 0x5FFF # 0 +0x9C7D 0x6021 # 0 +0x9C7E 0x6060 # 0 +0x9C80 0x6019 # 0 +0x9C81 0x6010 # 0 +0x9C82 0x6029 # 0 +0x9C83 0x600E # 0 +0x9C84 0x6031 # 0 +0x9C85 0x601B # 0 +0x9C86 0x6015 # 0 +0x9C87 0x602B # 0 +0x9C88 0x6026 # 0 +0x9C89 0x600F # 0 +0x9C8A 0x603A # 0 +0x9C8B 0x605A # 0 +0x9C8C 0x6041 # 0 +0x9C8D 0x606A # 0 +0x9C8E 0x6077 # 0 +0x9C8F 0x605F # 0 +0x9C90 0x604A # 0 +0x9C91 0x6046 # 0 +0x9C92 0x604D # 0 +0x9C93 0x6063 # 0 +0x9C94 0x6043 # 0 +0x9C95 0x6064 # 0 +0x9C96 0x6042 # 0 +0x9C97 0x606C # 0 +0x9C98 0x606B # 0 +0x9C99 0x6059 # 0 +0x9C9A 0x6081 # 0 +0x9C9B 0x608D # 0 +0x9C9C 0x60E7 # 0 +0x9C9D 0x6083 # 0 +0x9C9E 0x609A # 0 +0x9C9F 0x6084 # 0 +0x9CA0 0x609B # 0 +0x9CA1 0x6096 # 0 +0x9CA2 0x6097 # 0 +0x9CA3 0x6092 # 0 +0x9CA4 0x60A7 # 0 +0x9CA5 0x608B # 0 +0x9CA6 0x60E1 # 0 +0x9CA7 0x60B8 # 0 +0x9CA8 0x60E0 # 0 +0x9CA9 0x60D3 # 0 +0x9CAA 0x60B4 # 0 +0x9CAB 0x5FF0 # 0 +0x9CAC 0x60BD # 0 +0x9CAD 0x60C6 # 0 +0x9CAE 0x60B5 # 0 +0x9CAF 0x60D8 # 0 +0x9CB0 0x614D # 0 +0x9CB1 0x6115 # 0 +0x9CB2 0x6106 # 0 +0x9CB3 0x60F6 # 0 +0x9CB4 0x60F7 # 0 +0x9CB5 0x6100 # 0 +0x9CB6 0x60F4 # 0 +0x9CB7 0x60FA # 0 +0x9CB8 0x6103 # 0 +0x9CB9 0x6121 # 0 +0x9CBA 0x60FB # 0 +0x9CBB 0x60F1 # 0 +0x9CBC 0x610D # 0 +0x9CBD 0x610E # 0 +0x9CBE 0x6147 # 0 +0x9CBF 0x613E # 0 +0x9CC0 0x6128 # 0 +0x9CC1 0x6127 # 0 +0x9CC2 0x614A # 0 +0x9CC3 0x613F # 0 +0x9CC4 0x613C # 0 +0x9CC5 0x612C # 0 +0x9CC6 0x6134 # 0 +0x9CC7 0x613D # 0 +0x9CC8 0x6142 # 0 +0x9CC9 0x6144 # 0 +0x9CCA 0x6173 # 0 +0x9CCB 0x6177 # 0 +0x9CCC 0x6158 # 0 +0x9CCD 0x6159 # 0 +0x9CCE 0x615A # 0 +0x9CCF 0x616B # 0 +0x9CD0 0x6174 # 0 +0x9CD1 0x616F # 0 +0x9CD2 0x6165 # 0 +0x9CD3 0x6171 # 0 +0x9CD4 0x615F # 0 +0x9CD5 0x615D # 0 +0x9CD6 0x6153 # 0 +0x9CD7 0x6175 # 0 +0x9CD8 0x6199 # 0 +0x9CD9 0x6196 # 0 +0x9CDA 0x6187 # 0 +0x9CDB 0x61AC # 0 +0x9CDC 0x6194 # 0 +0x9CDD 0x619A # 0 +0x9CDE 0x618A # 0 +0x9CDF 0x6191 # 0 +0x9CE0 0x61AB # 0 +0x9CE1 0x61AE # 0 +0x9CE2 0x61CC # 0 +0x9CE3 0x61CA # 0 +0x9CE4 0x61C9 # 0 +0x9CE5 0x61F7 # 0 +0x9CE6 0x61C8 # 0 +0x9CE7 0x61C3 # 0 +0x9CE8 0x61C6 # 0 +0x9CE9 0x61BA # 0 +0x9CEA 0x61CB # 0 +0x9CEB 0x7F79 # 0 +0x9CEC 0x61CD # 0 +0x9CED 0x61E6 # 0 +0x9CEE 0x61E3 # 0 +0x9CEF 0x61F6 # 0 +0x9CF0 0x61FA # 0 +0x9CF1 0x61F4 # 0 +0x9CF2 0x61FF # 0 +0x9CF3 0x61FD # 0 +0x9CF4 0x61FC # 0 +0x9CF5 0x61FE # 0 +0x9CF6 0x6200 # 0 +0x9CF7 0x6208 # 0 +0x9CF8 0x6209 # 0 +0x9CF9 0x620D # 0 +0x9CFA 0x620C # 0 +0x9CFB 0x6214 # 0 +0x9CFC 0x621B # 0 +0x9D40 0x621E # 0 +0x9D41 0x6221 # 0 +0x9D42 0x622A # 0 +0x9D43 0x622E # 0 +0x9D44 0x6230 # 0 +0x9D45 0x6232 # 0 +0x9D46 0x6233 # 0 +0x9D47 0x6241 # 0 +0x9D48 0x624E # 0 +0x9D49 0x625E # 0 +0x9D4A 0x6263 # 0 +0x9D4B 0x625B # 0 +0x9D4C 0x6260 # 0 +0x9D4D 0x6268 # 0 +0x9D4E 0x627C # 0 +0x9D4F 0x6282 # 0 +0x9D50 0x6289 # 0 +0x9D51 0x627E # 0 +0x9D52 0x6292 # 0 +0x9D53 0x6293 # 0 +0x9D54 0x6296 # 0 +0x9D55 0x62D4 # 0 +0x9D56 0x6283 # 0 +0x9D57 0x6294 # 0 +0x9D58 0x62D7 # 0 +0x9D59 0x62D1 # 0 +0x9D5A 0x62BB # 0 +0x9D5B 0x62CF # 0 +0x9D5C 0x62FF # 0 +0x9D5D 0x62C6 # 0 +0x9D5E 0x64D4 # 0 +0x9D5F 0x62C8 # 0 +0x9D60 0x62DC # 0 +0x9D61 0x62CC # 0 +0x9D62 0x62CA # 0 +0x9D63 0x62C2 # 0 +0x9D64 0x62C7 # 0 +0x9D65 0x629B # 0 +0x9D66 0x62C9 # 0 +0x9D67 0x630C # 0 +0x9D68 0x62EE # 0 +0x9D69 0x62F1 # 0 +0x9D6A 0x6327 # 0 +0x9D6B 0x6302 # 0 +0x9D6C 0x6308 # 0 +0x9D6D 0x62EF # 0 +0x9D6E 0x62F5 # 0 +0x9D6F 0x6350 # 0 +0x9D70 0x633E # 0 +0x9D71 0x634D # 0 +0x9D72 0x641C # 0 +0x9D73 0x634F # 0 +0x9D74 0x6396 # 0 +0x9D75 0x638E # 0 +0x9D76 0x6380 # 0 +0x9D77 0x63AB # 0 +0x9D78 0x6376 # 0 +0x9D79 0x63A3 # 0 +0x9D7A 0x638F # 0 +0x9D7B 0x6389 # 0 +0x9D7C 0x639F # 0 +0x9D7D 0x63B5 # 0 +0x9D7E 0x636B # 0 +0x9D80 0x6369 # 0 +0x9D81 0x63BE # 0 +0x9D82 0x63E9 # 0 +0x9D83 0x63C0 # 0 +0x9D84 0x63C6 # 0 +0x9D85 0x63E3 # 0 +0x9D86 0x63C9 # 0 +0x9D87 0x63D2 # 0 +0x9D88 0x63F6 # 0 +0x9D89 0x63C4 # 0 +0x9D8A 0x6416 # 0 +0x9D8B 0x6434 # 0 +0x9D8C 0x6406 # 0 +0x9D8D 0x6413 # 0 +0x9D8E 0x6426 # 0 +0x9D8F 0x6436 # 0 +0x9D90 0x651D # 0 +0x9D91 0x6417 # 0 +0x9D92 0x6428 # 0 +0x9D93 0x640F # 0 +0x9D94 0x6467 # 0 +0x9D95 0x646F # 0 +0x9D96 0x6476 # 0 +0x9D97 0x644E # 0 +0x9D98 0x652A # 0 +0x9D99 0x6495 # 0 +0x9D9A 0x6493 # 0 +0x9D9B 0x64A5 # 0 +0x9D9C 0x64A9 # 0 +0x9D9D 0x6488 # 0 +0x9D9E 0x64BC # 0 +0x9D9F 0x64DA # 0 +0x9DA0 0x64D2 # 0 +0x9DA1 0x64C5 # 0 +0x9DA2 0x64C7 # 0 +0x9DA3 0x64BB # 0 +0x9DA4 0x64D8 # 0 +0x9DA5 0x64C2 # 0 +0x9DA6 0x64F1 # 0 +0x9DA7 0x64E7 # 0 +0x9DA8 0x8209 # 0 +0x9DA9 0x64E0 # 0 +0x9DAA 0x64E1 # 0 +0x9DAB 0x62AC # 0 +0x9DAC 0x64E3 # 0 +0x9DAD 0x64EF # 0 +0x9DAE 0x652C # 0 +0x9DAF 0x64F6 # 0 +0x9DB0 0x64F4 # 0 +0x9DB1 0x64F2 # 0 +0x9DB2 0x64FA # 0 +0x9DB3 0x6500 # 0 +0x9DB4 0x64FD # 0 +0x9DB5 0x6518 # 0 +0x9DB6 0x651C # 0 +0x9DB7 0x6505 # 0 +0x9DB8 0x6524 # 0 +0x9DB9 0x6523 # 0 +0x9DBA 0x652B # 0 +0x9DBB 0x6534 # 0 +0x9DBC 0x6535 # 0 +0x9DBD 0x6537 # 0 +0x9DBE 0x6536 # 0 +0x9DBF 0x6538 # 0 +0x9DC0 0x754B # 0 +0x9DC1 0x6548 # 0 +0x9DC2 0x6556 # 0 +0x9DC3 0x6555 # 0 +0x9DC4 0x654D # 0 +0x9DC5 0x6558 # 0 +0x9DC6 0x655E # 0 +0x9DC7 0x655D # 0 +0x9DC8 0x6572 # 0 +0x9DC9 0x6578 # 0 +0x9DCA 0x6582 # 0 +0x9DCB 0x6583 # 0 +0x9DCC 0x8B8A # 0 +0x9DCD 0x659B # 0 +0x9DCE 0x659F # 0 +0x9DCF 0x65AB # 0 +0x9DD0 0x65B7 # 0 +0x9DD1 0x65C3 # 0 +0x9DD2 0x65C6 # 0 +0x9DD3 0x65C1 # 0 +0x9DD4 0x65C4 # 0 +0x9DD5 0x65CC # 0 +0x9DD6 0x65D2 # 0 +0x9DD7 0x65DB # 0 +0x9DD8 0x65D9 # 0 +0x9DD9 0x65E0 # 0 +0x9DDA 0x65E1 # 0 +0x9DDB 0x65F1 # 0 +0x9DDC 0x6772 # 0 +0x9DDD 0x660A # 0 +0x9DDE 0x6603 # 0 +0x9DDF 0x65FB # 0 +0x9DE0 0x6773 # 0 +0x9DE1 0x6635 # 0 +0x9DE2 0x6636 # 0 +0x9DE3 0x6634 # 0 +0x9DE4 0x661C # 0 +0x9DE5 0x664F # 0 +0x9DE6 0x6644 # 0 +0x9DE7 0x6649 # 0 +0x9DE8 0x6641 # 0 +0x9DE9 0x665E # 0 +0x9DEA 0x665D # 0 +0x9DEB 0x6664 # 0 +0x9DEC 0x6667 # 0 +0x9DED 0x6668 # 0 +0x9DEE 0x665F # 0 +0x9DEF 0x6662 # 0 +0x9DF0 0x6670 # 0 +0x9DF1 0x6683 # 0 +0x9DF2 0x6688 # 0 +0x9DF3 0x668E # 0 +0x9DF4 0x6689 # 0 +0x9DF5 0x6684 # 0 +0x9DF6 0x6698 # 0 +0x9DF7 0x669D # 0 +0x9DF8 0x66C1 # 0 +0x9DF9 0x66B9 # 0 +0x9DFA 0x66C9 # 0 +0x9DFB 0x66BE # 0 +0x9DFC 0x66BC # 0 +0x9E40 0x66C4 # 0 +0x9E41 0x66B8 # 0 +0x9E42 0x66D6 # 0 +0x9E43 0x66DA # 0 +0x9E44 0x66E0 # 0 +0x9E45 0x663F # 0 +0x9E46 0x66E6 # 0 +0x9E47 0x66E9 # 0 +0x9E48 0x66F0 # 0 +0x9E49 0x66F5 # 0 +0x9E4A 0x66F7 # 0 +0x9E4B 0x670F # 0 +0x9E4C 0x6716 # 0 +0x9E4D 0x671E # 0 +0x9E4E 0x6726 # 0 +0x9E4F 0x6727 # 0 +0x9E50 0x9738 # 0 +0x9E51 0x672E # 0 +0x9E52 0x673F # 0 +0x9E53 0x6736 # 0 +0x9E54 0x6741 # 0 +0x9E55 0x6738 # 0 +0x9E56 0x6737 # 0 +0x9E57 0x6746 # 0 +0x9E58 0x675E # 0 +0x9E59 0x6760 # 0 +0x9E5A 0x6759 # 0 +0x9E5B 0x6763 # 0 +0x9E5C 0x6764 # 0 +0x9E5D 0x6789 # 0 +0x9E5E 0x6770 # 0 +0x9E5F 0x67A9 # 0 +0x9E60 0x677C # 0 +0x9E61 0x676A # 0 +0x9E62 0x678C # 0 +0x9E63 0x678B # 0 +0x9E64 0x67A6 # 0 +0x9E65 0x67A1 # 0 +0x9E66 0x6785 # 0 +0x9E67 0x67B7 # 0 +0x9E68 0x67EF # 0 +0x9E69 0x67B4 # 0 +0x9E6A 0x67EC # 0 +0x9E6B 0x67B3 # 0 +0x9E6C 0x67E9 # 0 +0x9E6D 0x67B8 # 0 +0x9E6E 0x67E4 # 0 +0x9E6F 0x67DE # 0 +0x9E70 0x67DD # 0 +0x9E71 0x67E2 # 0 +0x9E72 0x67EE # 0 +0x9E73 0x67B9 # 0 +0x9E74 0x67CE # 0 +0x9E75 0x67C6 # 0 +0x9E76 0x67E7 # 0 +0x9E77 0x6A9C # 0 +0x9E78 0x681E # 0 +0x9E79 0x6846 # 0 +0x9E7A 0x6829 # 0 +0x9E7B 0x6840 # 0 +0x9E7C 0x684D # 0 +0x9E7D 0x6832 # 0 +0x9E7E 0x684E # 0 +0x9E80 0x68B3 # 0 +0x9E81 0x682B # 0 +0x9E82 0x6859 # 0 +0x9E83 0x6863 # 0 +0x9E84 0x6877 # 0 +0x9E85 0x687F # 0 +0x9E86 0x689F # 0 +0x9E87 0x688F # 0 +0x9E88 0x68AD # 0 +0x9E89 0x6894 # 0 +0x9E8A 0x689D # 0 +0x9E8B 0x689B # 0 +0x9E8C 0x6883 # 0 +0x9E8D 0x6AAE # 0 +0x9E8E 0x68B9 # 0 +0x9E8F 0x6874 # 0 +0x9E90 0x68B5 # 0 +0x9E91 0x68A0 # 0 +0x9E92 0x68BA # 0 +0x9E93 0x690F # 0 +0x9E94 0x688D # 0 +0x9E95 0x687E # 0 +0x9E96 0x6901 # 0 +0x9E97 0x68CA # 0 +0x9E98 0x6908 # 0 +0x9E99 0x68D8 # 0 +0x9E9A 0x6922 # 0 +0x9E9B 0x6926 # 0 +0x9E9C 0x68E1 # 0 +0x9E9D 0x690C # 0 +0x9E9E 0x68CD # 0 +0x9E9F 0x68D4 # 0 +0x9EA0 0x68E7 # 0 +0x9EA1 0x68D5 # 0 +0x9EA2 0x6936 # 0 +0x9EA3 0x6912 # 0 +0x9EA4 0x6904 # 0 +0x9EA5 0x68D7 # 0 +0x9EA6 0x68E3 # 0 +0x9EA7 0x6925 # 0 +0x9EA8 0x68F9 # 0 +0x9EA9 0x68E0 # 0 +0x9EAA 0x68EF # 0 +0x9EAB 0x6928 # 0 +0x9EAC 0x692A # 0 +0x9EAD 0x691A # 0 +0x9EAE 0x6923 # 0 +0x9EAF 0x6921 # 0 +0x9EB0 0x68C6 # 0 +0x9EB1 0x6979 # 0 +0x9EB2 0x6977 # 0 +0x9EB3 0x695C # 0 +0x9EB4 0x6978 # 0 +0x9EB5 0x696B # 0 +0x9EB6 0x6954 # 0 +0x9EB7 0x697E # 0 +0x9EB8 0x696E # 0 +0x9EB9 0x6939 # 0 +0x9EBA 0x6974 # 0 +0x9EBB 0x693D # 0 +0x9EBC 0x6959 # 0 +0x9EBD 0x6930 # 0 +0x9EBE 0x6961 # 0 +0x9EBF 0x695E # 0 +0x9EC0 0x695D # 0 +0x9EC1 0x6981 # 0 +0x9EC2 0x696A # 0 +0x9EC3 0x69B2 # 0 +0x9EC4 0x69AE # 0 +0x9EC5 0x69D0 # 0 +0x9EC6 0x69BF # 0 +0x9EC7 0x69C1 # 0 +0x9EC8 0x69D3 # 0 +0x9EC9 0x69BE # 0 +0x9ECA 0x69CE # 0 +0x9ECB 0x5BE8 # 0 +0x9ECC 0x69CA # 0 +0x9ECD 0x69DD # 0 +0x9ECE 0x69BB # 0 +0x9ECF 0x69C3 # 0 +0x9ED0 0x69A7 # 0 +0x9ED1 0x6A2E # 0 +0x9ED2 0x6991 # 0 +0x9ED3 0x69A0 # 0 +0x9ED4 0x699C # 0 +0x9ED5 0x6995 # 0 +0x9ED6 0x69B4 # 0 +0x9ED7 0x69DE # 0 +0x9ED8 0x69E8 # 0 +0x9ED9 0x6A02 # 0 +0x9EDA 0x6A1B # 0 +0x9EDB 0x69FF # 0 +0x9EDC 0x6B0A # 0 +0x9EDD 0x69F9 # 0 +0x9EDE 0x69F2 # 0 +0x9EDF 0x69E7 # 0 +0x9EE0 0x6A05 # 0 +0x9EE1 0x69B1 # 0 +0x9EE2 0x6A1E # 0 +0x9EE3 0x69ED # 0 +0x9EE4 0x6A14 # 0 +0x9EE5 0x69EB # 0 +0x9EE6 0x6A0A # 0 +0x9EE7 0x6A12 # 0 +0x9EE8 0x6AC1 # 0 +0x9EE9 0x6A23 # 0 +0x9EEA 0x6A13 # 0 +0x9EEB 0x6A44 # 0 +0x9EEC 0x6A0C # 0 +0x9EED 0x6A72 # 0 +0x9EEE 0x6A36 # 0 +0x9EEF 0x6A78 # 0 +0x9EF0 0x6A47 # 0 +0x9EF1 0x6A62 # 0 +0x9EF2 0x6A59 # 0 +0x9EF3 0x6A66 # 0 +0x9EF4 0x6A48 # 0 +0x9EF5 0x6A38 # 0 +0x9EF6 0x6A22 # 0 +0x9EF7 0x6A90 # 0 +0x9EF8 0x6A8D # 0 +0x9EF9 0x6AA0 # 0 +0x9EFA 0x6A84 # 0 +0x9EFB 0x6AA2 # 0 +0x9EFC 0x6AA3 # 0 +0x9F40 0x6A97 # 0 +0x9F41 0x8617 # 0 +0x9F42 0x6ABB # 0 +0x9F43 0x6AC3 # 0 +0x9F44 0x6AC2 # 0 +0x9F45 0x6AB8 # 0 +0x9F46 0x6AB3 # 0 +0x9F47 0x6AAC # 0 +0x9F48 0x6ADE # 0 +0x9F49 0x6AD1 # 0 +0x9F4A 0x6ADF # 0 +0x9F4B 0x6AAA # 0 +0x9F4C 0x6ADA # 0 +0x9F4D 0x6AEA # 0 +0x9F4E 0x6AFB # 0 +0x9F4F 0x6B05 # 0 +0x9F50 0x8616 # 0 +0x9F51 0x6AFA # 0 +0x9F52 0x6B12 # 0 +0x9F53 0x6B16 # 0 +0x9F54 0x9B31 # 0 +0x9F55 0x6B1F # 0 +0x9F56 0x6B38 # 0 +0x9F57 0x6B37 # 0 +0x9F58 0x76DC # 0 +0x9F59 0x6B39 # 0 +0x9F5A 0x98EE # 0 +0x9F5B 0x6B47 # 0 +0x9F5C 0x6B43 # 0 +0x9F5D 0x6B49 # 0 +0x9F5E 0x6B50 # 0 +0x9F5F 0x6B59 # 0 +0x9F60 0x6B54 # 0 +0x9F61 0x6B5B # 0 +0x9F62 0x6B5F # 0 +0x9F63 0x6B61 # 0 +0x9F64 0x6B78 # 0 +0x9F65 0x6B79 # 0 +0x9F66 0x6B7F # 0 +0x9F67 0x6B80 # 0 +0x9F68 0x6B84 # 0 +0x9F69 0x6B83 # 0 +0x9F6A 0x6B8D # 0 +0x9F6B 0x6B98 # 0 +0x9F6C 0x6B95 # 0 +0x9F6D 0x6B9E # 0 +0x9F6E 0x6BA4 # 0 +0x9F6F 0x6BAA # 0 +0x9F70 0x6BAB # 0 +0x9F71 0x6BAF # 0 +0x9F72 0x6BB2 # 0 +0x9F73 0x6BB1 # 0 +0x9F74 0x6BB3 # 0 +0x9F75 0x6BB7 # 0 +0x9F76 0x6BBC # 0 +0x9F77 0x6BC6 # 0 +0x9F78 0x6BCB # 0 +0x9F79 0x6BD3 # 0 +0x9F7A 0x6BDF # 0 +0x9F7B 0x6BEC # 0 +0x9F7C 0x6BEB # 0 +0x9F7D 0x6BF3 # 0 +0x9F7E 0x6BEF # 0 +0x9F80 0x9EBE # 0 +0x9F81 0x6C08 # 0 +0x9F82 0x6C13 # 0 +0x9F83 0x6C14 # 0 +0x9F84 0x6C1B # 0 +0x9F85 0x6C24 # 0 +0x9F86 0x6C23 # 0 +0x9F87 0x6C5E # 0 +0x9F88 0x6C55 # 0 +0x9F89 0x6C62 # 0 +0x9F8A 0x6C6A # 0 +0x9F8B 0x6C82 # 0 +0x9F8C 0x6C8D # 0 +0x9F8D 0x6C9A # 0 +0x9F8E 0x6C81 # 0 +0x9F8F 0x6C9B # 0 +0x9F90 0x6C7E # 0 +0x9F91 0x6C68 # 0 +0x9F92 0x6C73 # 0 +0x9F93 0x6C92 # 0 +0x9F94 0x6C90 # 0 +0x9F95 0x6CC4 # 0 +0x9F96 0x6CF1 # 0 +0x9F97 0x6CD3 # 0 +0x9F98 0x6CBD # 0 +0x9F99 0x6CD7 # 0 +0x9F9A 0x6CC5 # 0 +0x9F9B 0x6CDD # 0 +0x9F9C 0x6CAE # 0 +0x9F9D 0x6CB1 # 0 +0x9F9E 0x6CBE # 0 +0x9F9F 0x6CBA # 0 +0x9FA0 0x6CDB # 0 +0x9FA1 0x6CEF # 0 +0x9FA2 0x6CD9 # 0 +0x9FA3 0x6CEA # 0 +0x9FA4 0x6D1F # 0 +0x9FA5 0x884D # 0 +0x9FA6 0x6D36 # 0 +0x9FA7 0x6D2B # 0 +0x9FA8 0x6D3D # 0 +0x9FA9 0x6D38 # 0 +0x9FAA 0x6D19 # 0 +0x9FAB 0x6D35 # 0 +0x9FAC 0x6D33 # 0 +0x9FAD 0x6D12 # 0 +0x9FAE 0x6D0C # 0 +0x9FAF 0x6D63 # 0 +0x9FB0 0x6D93 # 0 +0x9FB1 0x6D64 # 0 +0x9FB2 0x6D5A # 0 +0x9FB3 0x6D79 # 0 +0x9FB4 0x6D59 # 0 +0x9FB5 0x6D8E # 0 +0x9FB6 0x6D95 # 0 +0x9FB7 0x6FE4 # 0 +0x9FB8 0x6D85 # 0 +0x9FB9 0x6DF9 # 0 +0x9FBA 0x6E15 # 0 +0x9FBB 0x6E0A # 0 +0x9FBC 0x6DB5 # 0 +0x9FBD 0x6DC7 # 0 +0x9FBE 0x6DE6 # 0 +0x9FBF 0x6DB8 # 0 +0x9FC0 0x6DC6 # 0 +0x9FC1 0x6DEC # 0 +0x9FC2 0x6DDE # 0 +0x9FC3 0x6DCC # 0 +0x9FC4 0x6DE8 # 0 +0x9FC5 0x6DD2 # 0 +0x9FC6 0x6DC5 # 0 +0x9FC7 0x6DFA # 0 +0x9FC8 0x6DD9 # 0 +0x9FC9 0x6DE4 # 0 +0x9FCA 0x6DD5 # 0 +0x9FCB 0x6DEA # 0 +0x9FCC 0x6DEE # 0 +0x9FCD 0x6E2D # 0 +0x9FCE 0x6E6E # 0 +0x9FCF 0x6E2E # 0 +0x9FD0 0x6E19 # 0 +0x9FD1 0x6E72 # 0 +0x9FD2 0x6E5F # 0 +0x9FD3 0x6E3E # 0 +0x9FD4 0x6E23 # 0 +0x9FD5 0x6E6B # 0 +0x9FD6 0x6E2B # 0 +0x9FD7 0x6E76 # 0 +0x9FD8 0x6E4D # 0 +0x9FD9 0x6E1F # 0 +0x9FDA 0x6E43 # 0 +0x9FDB 0x6E3A # 0 +0x9FDC 0x6E4E # 0 +0x9FDD 0x6E24 # 0 +0x9FDE 0x6EFF # 0 +0x9FDF 0x6E1D # 0 +0x9FE0 0x6E38 # 0 +0x9FE1 0x6E82 # 0 +0x9FE2 0x6EAA # 0 +0x9FE3 0x6E98 # 0 +0x9FE4 0x6EC9 # 0 +0x9FE5 0x6EB7 # 0 +0x9FE6 0x6ED3 # 0 +0x9FE7 0x6EBD # 0 +0x9FE8 0x6EAF # 0 +0x9FE9 0x6EC4 # 0 +0x9FEA 0x6EB2 # 0 +0x9FEB 0x6ED4 # 0 +0x9FEC 0x6ED5 # 0 +0x9FED 0x6E8F # 0 +0x9FEE 0x6EA5 # 0 +0x9FEF 0x6EC2 # 0 +0x9FF0 0x6E9F # 0 +0x9FF1 0x6F41 # 0 +0x9FF2 0x6F11 # 0 +0x9FF3 0x704C # 0 +0x9FF4 0x6EEC # 0 +0x9FF5 0x6EF8 # 0 +0x9FF6 0x6EFE # 0 +0x9FF7 0x6F3F # 0 +0x9FF8 0x6EF2 # 0 +0x9FF9 0x6F31 # 0 +0x9FFA 0x6EEF # 0 +0x9FFB 0x6F32 # 0 +0x9FFC 0x6ECC # 0 +0xE040 0x6F3E # 0 +0xE041 0x6F13 # 0 +0xE042 0x6EF7 # 0 +0xE043 0x6F86 # 0 +0xE044 0x6F7A # 0 +0xE045 0x6F78 # 0 +0xE046 0x6F81 # 0 +0xE047 0x6F80 # 0 +0xE048 0x6F6F # 0 +0xE049 0x6F5B # 0 +0xE04A 0x6FF3 # 0 +0xE04B 0x6F6D # 0 +0xE04C 0x6F82 # 0 +0xE04D 0x6F7C # 0 +0xE04E 0x6F58 # 0 +0xE04F 0x6F8E # 0 +0xE050 0x6F91 # 0 +0xE051 0x6FC2 # 0 +0xE052 0x6F66 # 0 +0xE053 0x6FB3 # 0 +0xE054 0x6FA3 # 0 +0xE055 0x6FA1 # 0 +0xE056 0x6FA4 # 0 +0xE057 0x6FB9 # 0 +0xE058 0x6FC6 # 0 +0xE059 0x6FAA # 0 +0xE05A 0x6FDF # 0 +0xE05B 0x6FD5 # 0 +0xE05C 0x6FEC # 0 +0xE05D 0x6FD4 # 0 +0xE05E 0x6FD8 # 0 +0xE05F 0x6FF1 # 0 +0xE060 0x6FEE # 0 +0xE061 0x6FDB # 0 +0xE062 0x7009 # 0 +0xE063 0x700B # 0 +0xE064 0x6FFA # 0 +0xE065 0x7011 # 0 +0xE066 0x7001 # 0 +0xE067 0x700F # 0 +0xE068 0x6FFE # 0 +0xE069 0x701B # 0 +0xE06A 0x701A # 0 +0xE06B 0x6F74 # 0 +0xE06C 0x701D # 0 +0xE06D 0x7018 # 0 +0xE06E 0x701F # 0 +0xE06F 0x7030 # 0 +0xE070 0x703E # 0 +0xE071 0x7032 # 0 +0xE072 0x7051 # 0 +0xE073 0x7063 # 0 +0xE074 0x7099 # 0 +0xE075 0x7092 # 0 +0xE076 0x70AF # 0 +0xE077 0x70F1 # 0 +0xE078 0x70AC # 0 +0xE079 0x70B8 # 0 +0xE07A 0x70B3 # 0 +0xE07B 0x70AE # 0 +0xE07C 0x70DF # 0 +0xE07D 0x70CB # 0 +0xE07E 0x70DD # 0 +0xE080 0x70D9 # 0 +0xE081 0x7109 # 0 +0xE082 0x70FD # 0 +0xE083 0x711C # 0 +0xE084 0x7119 # 0 +0xE085 0x7165 # 0 +0xE086 0x7155 # 0 +0xE087 0x7188 # 0 +0xE088 0x7166 # 0 +0xE089 0x7162 # 0 +0xE08A 0x714C # 0 +0xE08B 0x7156 # 0 +0xE08C 0x716C # 0 +0xE08D 0x718F # 0 +0xE08E 0x71FB # 0 +0xE08F 0x7184 # 0 +0xE090 0x7195 # 0 +0xE091 0x71A8 # 0 +0xE092 0x71AC # 0 +0xE093 0x71D7 # 0 +0xE094 0x71B9 # 0 +0xE095 0x71BE # 0 +0xE096 0x71D2 # 0 +0xE097 0x71C9 # 0 +0xE098 0x71D4 # 0 +0xE099 0x71CE # 0 +0xE09A 0x71E0 # 0 +0xE09B 0x71EC # 0 +0xE09C 0x71E7 # 0 +0xE09D 0x71F5 # 0 +0xE09E 0x71FC # 0 +0xE09F 0x71F9 # 0 +0xE0A0 0x71FF # 0 +0xE0A1 0x720D # 0 +0xE0A2 0x7210 # 0 +0xE0A3 0x721B # 0 +0xE0A4 0x7228 # 0 +0xE0A5 0x722D # 0 +0xE0A6 0x722C # 0 +0xE0A7 0x7230 # 0 +0xE0A8 0x7232 # 0 +0xE0A9 0x723B # 0 +0xE0AA 0x723C # 0 +0xE0AB 0x723F # 0 +0xE0AC 0x7240 # 0 +0xE0AD 0x7246 # 0 +0xE0AE 0x724B # 0 +0xE0AF 0x7258 # 0 +0xE0B0 0x7274 # 0 +0xE0B1 0x727E # 0 +0xE0B2 0x7282 # 0 +0xE0B3 0x7281 # 0 +0xE0B4 0x7287 # 0 +0xE0B5 0x7292 # 0 +0xE0B6 0x7296 # 0 +0xE0B7 0x72A2 # 0 +0xE0B8 0x72A7 # 0 +0xE0B9 0x72B9 # 0 +0xE0BA 0x72B2 # 0 +0xE0BB 0x72C3 # 0 +0xE0BC 0x72C6 # 0 +0xE0BD 0x72C4 # 0 +0xE0BE 0x72CE # 0 +0xE0BF 0x72D2 # 0 +0xE0C0 0x72E2 # 0 +0xE0C1 0x72E0 # 0 +0xE0C2 0x72E1 # 0 +0xE0C3 0x72F9 # 0 +0xE0C4 0x72F7 # 0 +0xE0C5 0x500F # 0 +0xE0C6 0x7317 # 0 +0xE0C7 0x730A # 0 +0xE0C8 0x731C # 0 +0xE0C9 0x7316 # 0 +0xE0CA 0x731D # 0 +0xE0CB 0x7334 # 0 +0xE0CC 0x732F # 0 +0xE0CD 0x7329 # 0 +0xE0CE 0x7325 # 0 +0xE0CF 0x733E # 0 +0xE0D0 0x734E # 0 +0xE0D1 0x734F # 0 +0xE0D2 0x9ED8 # 0 +0xE0D3 0x7357 # 0 +0xE0D4 0x736A # 0 +0xE0D5 0x7368 # 0 +0xE0D6 0x7370 # 0 +0xE0D7 0x7378 # 0 +0xE0D8 0x7375 # 0 +0xE0D9 0x737B # 0 +0xE0DA 0x737A # 0 +0xE0DB 0x73C8 # 0 +0xE0DC 0x73B3 # 0 +0xE0DD 0x73CE # 0 +0xE0DE 0x73BB # 0 +0xE0DF 0x73C0 # 0 +0xE0E0 0x73E5 # 0 +0xE0E1 0x73EE # 0 +0xE0E2 0x73DE # 0 +0xE0E3 0x74A2 # 0 +0xE0E4 0x7405 # 0 +0xE0E5 0x746F # 0 +0xE0E6 0x7425 # 0 +0xE0E7 0x73F8 # 0 +0xE0E8 0x7432 # 0 +0xE0E9 0x743A # 0 +0xE0EA 0x7455 # 0 +0xE0EB 0x743F # 0 +0xE0EC 0x745F # 0 +0xE0ED 0x7459 # 0 +0xE0EE 0x7441 # 0 +0xE0EF 0x745C # 0 +0xE0F0 0x7469 # 0 +0xE0F1 0x7470 # 0 +0xE0F2 0x7463 # 0 +0xE0F3 0x746A # 0 +0xE0F4 0x7476 # 0 +0xE0F5 0x747E # 0 +0xE0F6 0x748B # 0 +0xE0F7 0x749E # 0 +0xE0F8 0x74A7 # 0 +0xE0F9 0x74CA # 0 +0xE0FA 0x74CF # 0 +0xE0FB 0x74D4 # 0 +0xE0FC 0x73F1 # 0 +0xE140 0x74E0 # 0 +0xE141 0x74E3 # 0 +0xE142 0x74E7 # 0 +0xE143 0x74E9 # 0 +0xE144 0x74EE # 0 +0xE145 0x74F2 # 0 +0xE146 0x74F0 # 0 +0xE147 0x74F1 # 0 +0xE148 0x74F8 # 0 +0xE149 0x74F7 # 0 +0xE14A 0x7504 # 0 +0xE14B 0x7503 # 0 +0xE14C 0x7505 # 0 +0xE14D 0x750C # 0 +0xE14E 0x750E # 0 +0xE14F 0x750D # 0 +0xE150 0x7515 # 0 +0xE151 0x7513 # 0 +0xE152 0x751E # 0 +0xE153 0x7526 # 0 +0xE154 0x752C # 0 +0xE155 0x753C # 0 +0xE156 0x7544 # 0 +0xE157 0x754D # 0 +0xE158 0x754A # 0 +0xE159 0x7549 # 0 +0xE15A 0x755B # 0 +0xE15B 0x7546 # 0 +0xE15C 0x755A # 0 +0xE15D 0x7569 # 0 +0xE15E 0x7564 # 0 +0xE15F 0x7567 # 0 +0xE160 0x756B # 0 +0xE161 0x756D # 0 +0xE162 0x7578 # 0 +0xE163 0x7576 # 0 +0xE164 0x7586 # 0 +0xE165 0x7587 # 0 +0xE166 0x7574 # 0 +0xE167 0x758A # 0 +0xE168 0x7589 # 0 +0xE169 0x7582 # 0 +0xE16A 0x7594 # 0 +0xE16B 0x759A # 0 +0xE16C 0x759D # 0 +0xE16D 0x75A5 # 0 +0xE16E 0x75A3 # 0 +0xE16F 0x75C2 # 0 +0xE170 0x75B3 # 0 +0xE171 0x75C3 # 0 +0xE172 0x75B5 # 0 +0xE173 0x75BD # 0 +0xE174 0x75B8 # 0 +0xE175 0x75BC # 0 +0xE176 0x75B1 # 0 +0xE177 0x75CD # 0 +0xE178 0x75CA # 0 +0xE179 0x75D2 # 0 +0xE17A 0x75D9 # 0 +0xE17B 0x75E3 # 0 +0xE17C 0x75DE # 0 +0xE17D 0x75FE # 0 +0xE17E 0x75FF # 0 +0xE180 0x75FC # 0 +0xE181 0x7601 # 0 +0xE182 0x75F0 # 0 +0xE183 0x75FA # 0 +0xE184 0x75F2 # 0 +0xE185 0x75F3 # 0 +0xE186 0x760B # 0 +0xE187 0x760D # 0 +0xE188 0x7609 # 0 +0xE189 0x761F # 0 +0xE18A 0x7627 # 0 +0xE18B 0x7620 # 0 +0xE18C 0x7621 # 0 +0xE18D 0x7622 # 0 +0xE18E 0x7624 # 0 +0xE18F 0x7634 # 0 +0xE190 0x7630 # 0 +0xE191 0x763B # 0 +0xE192 0x7647 # 0 +0xE193 0x7648 # 0 +0xE194 0x7646 # 0 +0xE195 0x765C # 0 +0xE196 0x7658 # 0 +0xE197 0x7661 # 0 +0xE198 0x7662 # 0 +0xE199 0x7668 # 0 +0xE19A 0x7669 # 0 +0xE19B 0x766A # 0 +0xE19C 0x7667 # 0 +0xE19D 0x766C # 0 +0xE19E 0x7670 # 0 +0xE19F 0x7672 # 0 +0xE1A0 0x7676 # 0 +0xE1A1 0x7678 # 0 +0xE1A2 0x767C # 0 +0xE1A3 0x7680 # 0 +0xE1A4 0x7683 # 0 +0xE1A5 0x7688 # 0 +0xE1A6 0x768B # 0 +0xE1A7 0x768E # 0 +0xE1A8 0x7696 # 0 +0xE1A9 0x7693 # 0 +0xE1AA 0x7699 # 0 +0xE1AB 0x769A # 0 +0xE1AC 0x76B0 # 0 +0xE1AD 0x76B4 # 0 +0xE1AE 0x76B8 # 0 +0xE1AF 0x76B9 # 0 +0xE1B0 0x76BA # 0 +0xE1B1 0x76C2 # 0 +0xE1B2 0x76CD # 0 +0xE1B3 0x76D6 # 0 +0xE1B4 0x76D2 # 0 +0xE1B5 0x76DE # 0 +0xE1B6 0x76E1 # 0 +0xE1B7 0x76E5 # 0 +0xE1B8 0x76E7 # 0 +0xE1B9 0x76EA # 0 +0xE1BA 0x862F # 0 +0xE1BB 0x76FB # 0 +0xE1BC 0x7708 # 0 +0xE1BD 0x7707 # 0 +0xE1BE 0x7704 # 0 +0xE1BF 0x7729 # 0 +0xE1C0 0x7724 # 0 +0xE1C1 0x771E # 0 +0xE1C2 0x7725 # 0 +0xE1C3 0x7726 # 0 +0xE1C4 0x771B # 0 +0xE1C5 0x7737 # 0 +0xE1C6 0x7738 # 0 +0xE1C7 0x7747 # 0 +0xE1C8 0x775A # 0 +0xE1C9 0x7768 # 0 +0xE1CA 0x776B # 0 +0xE1CB 0x775B # 0 +0xE1CC 0x7765 # 0 +0xE1CD 0x777F # 0 +0xE1CE 0x777E # 0 +0xE1CF 0x7779 # 0 +0xE1D0 0x778E # 0 +0xE1D1 0x778B # 0 +0xE1D2 0x7791 # 0 +0xE1D3 0x77A0 # 0 +0xE1D4 0x779E # 0 +0xE1D5 0x77B0 # 0 +0xE1D6 0x77B6 # 0 +0xE1D7 0x77B9 # 0 +0xE1D8 0x77BF # 0 +0xE1D9 0x77BC # 0 +0xE1DA 0x77BD # 0 +0xE1DB 0x77BB # 0 +0xE1DC 0x77C7 # 0 +0xE1DD 0x77CD # 0 +0xE1DE 0x77D7 # 0 +0xE1DF 0x77DA # 0 +0xE1E0 0x77DC # 0 +0xE1E1 0x77E3 # 0 +0xE1E2 0x77EE # 0 +0xE1E3 0x77FC # 0 +0xE1E4 0x780C # 0 +0xE1E5 0x7812 # 0 +0xE1E6 0x7926 # 0 +0xE1E7 0x7820 # 0 +0xE1E8 0x792A # 0 +0xE1E9 0x7845 # 0 +0xE1EA 0x788E # 0 +0xE1EB 0x7874 # 0 +0xE1EC 0x7886 # 0 +0xE1ED 0x787C # 0 +0xE1EE 0x789A # 0 +0xE1EF 0x788C # 0 +0xE1F0 0x78A3 # 0 +0xE1F1 0x78B5 # 0 +0xE1F2 0x78AA # 0 +0xE1F3 0x78AF # 0 +0xE1F4 0x78D1 # 0 +0xE1F5 0x78C6 # 0 +0xE1F6 0x78CB # 0 +0xE1F7 0x78D4 # 0 +0xE1F8 0x78BE # 0 +0xE1F9 0x78BC # 0 +0xE1FA 0x78C5 # 0 +0xE1FB 0x78CA # 0 +0xE1FC 0x78EC # 0 +0xE240 0x78E7 # 0 +0xE241 0x78DA # 0 +0xE242 0x78FD # 0 +0xE243 0x78F4 # 0 +0xE244 0x7907 # 0 +0xE245 0x7912 # 0 +0xE246 0x7911 # 0 +0xE247 0x7919 # 0 +0xE248 0x792C # 0 +0xE249 0x792B # 0 +0xE24A 0x7940 # 0 +0xE24B 0x7960 # 0 +0xE24C 0x7957 # 0 +0xE24D 0x795F # 0 +0xE24E 0x795A # 0 +0xE24F 0x7955 # 0 +0xE250 0x7953 # 0 +0xE251 0x797A # 0 +0xE252 0x797F # 0 +0xE253 0x798A # 0 +0xE254 0x799D # 0 +0xE255 0x79A7 # 0 +0xE256 0x9F4B # 0 +0xE257 0x79AA # 0 +0xE258 0x79AE # 0 +0xE259 0x79B3 # 0 +0xE25A 0x79B9 # 0 +0xE25B 0x79BA # 0 +0xE25C 0x79C9 # 0 +0xE25D 0x79D5 # 0 +0xE25E 0x79E7 # 0 +0xE25F 0x79EC # 0 +0xE260 0x79E1 # 0 +0xE261 0x79E3 # 0 +0xE262 0x7A08 # 0 +0xE263 0x7A0D # 0 +0xE264 0x7A18 # 0 +0xE265 0x7A19 # 0 +0xE266 0x7A20 # 0 +0xE267 0x7A1F # 0 +0xE268 0x7980 # 0 +0xE269 0x7A31 # 0 +0xE26A 0x7A3B # 0 +0xE26B 0x7A3E # 0 +0xE26C 0x7A37 # 0 +0xE26D 0x7A43 # 0 +0xE26E 0x7A57 # 0 +0xE26F 0x7A49 # 0 +0xE270 0x7A61 # 0 +0xE271 0x7A62 # 0 +0xE272 0x7A69 # 0 +0xE273 0x9F9D # 0 +0xE274 0x7A70 # 0 +0xE275 0x7A79 # 0 +0xE276 0x7A7D # 0 +0xE277 0x7A88 # 0 +0xE278 0x7A97 # 0 +0xE279 0x7A95 # 0 +0xE27A 0x7A98 # 0 +0xE27B 0x7A96 # 0 +0xE27C 0x7AA9 # 0 +0xE27D 0x7AC8 # 0 +0xE27E 0x7AB0 # 0 +0xE280 0x7AB6 # 0 +0xE281 0x7AC5 # 0 +0xE282 0x7AC4 # 0 +0xE283 0x7ABF # 0 +0xE284 0x9083 # 0 +0xE285 0x7AC7 # 0 +0xE286 0x7ACA # 0 +0xE287 0x7ACD # 0 +0xE288 0x7ACF # 0 +0xE289 0x7AD5 # 0 +0xE28A 0x7AD3 # 0 +0xE28B 0x7AD9 # 0 +0xE28C 0x7ADA # 0 +0xE28D 0x7ADD # 0 +0xE28E 0x7AE1 # 0 +0xE28F 0x7AE2 # 0 +0xE290 0x7AE6 # 0 +0xE291 0x7AED # 0 +0xE292 0x7AF0 # 0 +0xE293 0x7B02 # 0 +0xE294 0x7B0F # 0 +0xE295 0x7B0A # 0 +0xE296 0x7B06 # 0 +0xE297 0x7B33 # 0 +0xE298 0x7B18 # 0 +0xE299 0x7B19 # 0 +0xE29A 0x7B1E # 0 +0xE29B 0x7B35 # 0 +0xE29C 0x7B28 # 0 +0xE29D 0x7B36 # 0 +0xE29E 0x7B50 # 0 +0xE29F 0x7B7A # 0 +0xE2A0 0x7B04 # 0 +0xE2A1 0x7B4D # 0 +0xE2A2 0x7B0B # 0 +0xE2A3 0x7B4C # 0 +0xE2A4 0x7B45 # 0 +0xE2A5 0x7B75 # 0 +0xE2A6 0x7B65 # 0 +0xE2A7 0x7B74 # 0 +0xE2A8 0x7B67 # 0 +0xE2A9 0x7B70 # 0 +0xE2AA 0x7B71 # 0 +0xE2AB 0x7B6C # 0 +0xE2AC 0x7B6E # 0 +0xE2AD 0x7B9D # 0 +0xE2AE 0x7B98 # 0 +0xE2AF 0x7B9F # 0 +0xE2B0 0x7B8D # 0 +0xE2B1 0x7B9C # 0 +0xE2B2 0x7B9A # 0 +0xE2B3 0x7B8B # 0 +0xE2B4 0x7B92 # 0 +0xE2B5 0x7B8F # 0 +0xE2B6 0x7B5D # 0 +0xE2B7 0x7B99 # 0 +0xE2B8 0x7BCB # 0 +0xE2B9 0x7BC1 # 0 +0xE2BA 0x7BCC # 0 +0xE2BB 0x7BCF # 0 +0xE2BC 0x7BB4 # 0 +0xE2BD 0x7BC6 # 0 +0xE2BE 0x7BDD # 0 +0xE2BF 0x7BE9 # 0 +0xE2C0 0x7C11 # 0 +0xE2C1 0x7C14 # 0 +0xE2C2 0x7BE6 # 0 +0xE2C3 0x7BE5 # 0 +0xE2C4 0x7C60 # 0 +0xE2C5 0x7C00 # 0 +0xE2C6 0x7C07 # 0 +0xE2C7 0x7C13 # 0 +0xE2C8 0x7BF3 # 0 +0xE2C9 0x7BF7 # 0 +0xE2CA 0x7C17 # 0 +0xE2CB 0x7C0D # 0 +0xE2CC 0x7BF6 # 0 +0xE2CD 0x7C23 # 0 +0xE2CE 0x7C27 # 0 +0xE2CF 0x7C2A # 0 +0xE2D0 0x7C1F # 0 +0xE2D1 0x7C37 # 0 +0xE2D2 0x7C2B # 0 +0xE2D3 0x7C3D # 0 +0xE2D4 0x7C4C # 0 +0xE2D5 0x7C43 # 0 +0xE2D6 0x7C54 # 0 +0xE2D7 0x7C4F # 0 +0xE2D8 0x7C40 # 0 +0xE2D9 0x7C50 # 0 +0xE2DA 0x7C58 # 0 +0xE2DB 0x7C5F # 0 +0xE2DC 0x7C64 # 0 +0xE2DD 0x7C56 # 0 +0xE2DE 0x7C65 # 0 +0xE2DF 0x7C6C # 0 +0xE2E0 0x7C75 # 0 +0xE2E1 0x7C83 # 0 +0xE2E2 0x7C90 # 0 +0xE2E3 0x7CA4 # 0 +0xE2E4 0x7CAD # 0 +0xE2E5 0x7CA2 # 0 +0xE2E6 0x7CAB # 0 +0xE2E7 0x7CA1 # 0 +0xE2E8 0x7CA8 # 0 +0xE2E9 0x7CB3 # 0 +0xE2EA 0x7CB2 # 0 +0xE2EB 0x7CB1 # 0 +0xE2EC 0x7CAE # 0 +0xE2ED 0x7CB9 # 0 +0xE2EE 0x7CBD # 0 +0xE2EF 0x7CC0 # 0 +0xE2F0 0x7CC5 # 0 +0xE2F1 0x7CC2 # 0 +0xE2F2 0x7CD8 # 0 +0xE2F3 0x7CD2 # 0 +0xE2F4 0x7CDC # 0 +0xE2F5 0x7CE2 # 0 +0xE2F6 0x9B3B # 0 +0xE2F7 0x7CEF # 0 +0xE2F8 0x7CF2 # 0 +0xE2F9 0x7CF4 # 0 +0xE2FA 0x7CF6 # 0 +0xE2FB 0x7CFA # 0 +0xE2FC 0x7D06 # 0 +0xE340 0x7D02 # 0 +0xE341 0x7D1C # 0 +0xE342 0x7D15 # 0 +0xE343 0x7D0A # 0 +0xE344 0x7D45 # 0 +0xE345 0x7D4B # 0 +0xE346 0x7D2E # 0 +0xE347 0x7D32 # 0 +0xE348 0x7D3F # 0 +0xE349 0x7D35 # 0 +0xE34A 0x7D46 # 0 +0xE34B 0x7D73 # 0 +0xE34C 0x7D56 # 0 +0xE34D 0x7D4E # 0 +0xE34E 0x7D72 # 0 +0xE34F 0x7D68 # 0 +0xE350 0x7D6E # 0 +0xE351 0x7D4F # 0 +0xE352 0x7D63 # 0 +0xE353 0x7D93 # 0 +0xE354 0x7D89 # 0 +0xE355 0x7D5B # 0 +0xE356 0x7D8F # 0 +0xE357 0x7D7D # 0 +0xE358 0x7D9B # 0 +0xE359 0x7DBA # 0 +0xE35A 0x7DAE # 0 +0xE35B 0x7DA3 # 0 +0xE35C 0x7DB5 # 0 +0xE35D 0x7DC7 # 0 +0xE35E 0x7DBD # 0 +0xE35F 0x7DAB # 0 +0xE360 0x7E3D # 0 +0xE361 0x7DA2 # 0 +0xE362 0x7DAF # 0 +0xE363 0x7DDC # 0 +0xE364 0x7DB8 # 0 +0xE365 0x7D9F # 0 +0xE366 0x7DB0 # 0 +0xE367 0x7DD8 # 0 +0xE368 0x7DDD # 0 +0xE369 0x7DE4 # 0 +0xE36A 0x7DDE # 0 +0xE36B 0x7DFB # 0 +0xE36C 0x7DF2 # 0 +0xE36D 0x7DE1 # 0 +0xE36E 0x7E05 # 0 +0xE36F 0x7E0A # 0 +0xE370 0x7E23 # 0 +0xE371 0x7E21 # 0 +0xE372 0x7E12 # 0 +0xE373 0x7E31 # 0 +0xE374 0x7E1F # 0 +0xE375 0x7E09 # 0 +0xE376 0x7E0B # 0 +0xE377 0x7E22 # 0 +0xE378 0x7E46 # 0 +0xE379 0x7E66 # 0 +0xE37A 0x7E3B # 0 +0xE37B 0x7E35 # 0 +0xE37C 0x7E39 # 0 +0xE37D 0x7E43 # 0 +0xE37E 0x7E37 # 0 +0xE380 0x7E32 # 0 +0xE381 0x7E3A # 0 +0xE382 0x7E67 # 0 +0xE383 0x7E5D # 0 +0xE384 0x7E56 # 0 +0xE385 0x7E5E # 0 +0xE386 0x7E59 # 0 +0xE387 0x7E5A # 0 +0xE388 0x7E79 # 0 +0xE389 0x7E6A # 0 +0xE38A 0x7E69 # 0 +0xE38B 0x7E7C # 0 +0xE38C 0x7E7B # 0 +0xE38D 0x7E83 # 0 +0xE38E 0x7DD5 # 0 +0xE38F 0x7E7D # 0 +0xE390 0x8FAE # 0 +0xE391 0x7E7F # 0 +0xE392 0x7E88 # 0 +0xE393 0x7E89 # 0 +0xE394 0x7E8C # 0 +0xE395 0x7E92 # 0 +0xE396 0x7E90 # 0 +0xE397 0x7E93 # 0 +0xE398 0x7E94 # 0 +0xE399 0x7E96 # 0 +0xE39A 0x7E8E # 0 +0xE39B 0x7E9B # 0 +0xE39C 0x7E9C # 0 +0xE39D 0x7F38 # 0 +0xE39E 0x7F3A # 0 +0xE39F 0x7F45 # 0 +0xE3A0 0x7F4C # 0 +0xE3A1 0x7F4D # 0 +0xE3A2 0x7F4E # 0 +0xE3A3 0x7F50 # 0 +0xE3A4 0x7F51 # 0 +0xE3A5 0x7F55 # 0 +0xE3A6 0x7F54 # 0 +0xE3A7 0x7F58 # 0 +0xE3A8 0x7F5F # 0 +0xE3A9 0x7F60 # 0 +0xE3AA 0x7F68 # 0 +0xE3AB 0x7F69 # 0 +0xE3AC 0x7F67 # 0 +0xE3AD 0x7F78 # 0 +0xE3AE 0x7F82 # 0 +0xE3AF 0x7F86 # 0 +0xE3B0 0x7F83 # 0 +0xE3B1 0x7F88 # 0 +0xE3B2 0x7F87 # 0 +0xE3B3 0x7F8C # 0 +0xE3B4 0x7F94 # 0 +0xE3B5 0x7F9E # 0 +0xE3B6 0x7F9D # 0 +0xE3B7 0x7F9A # 0 +0xE3B8 0x7FA3 # 0 +0xE3B9 0x7FAF # 0 +0xE3BA 0x7FB2 # 0 +0xE3BB 0x7FB9 # 0 +0xE3BC 0x7FAE # 0 +0xE3BD 0x7FB6 # 0 +0xE3BE 0x7FB8 # 0 +0xE3BF 0x8B71 # 0 +0xE3C0 0x7FC5 # 0 +0xE3C1 0x7FC6 # 0 +0xE3C2 0x7FCA # 0 +0xE3C3 0x7FD5 # 0 +0xE3C4 0x7FD4 # 0 +0xE3C5 0x7FE1 # 0 +0xE3C6 0x7FE6 # 0 +0xE3C7 0x7FE9 # 0 +0xE3C8 0x7FF3 # 0 +0xE3C9 0x7FF9 # 0 +0xE3CA 0x98DC # 0 +0xE3CB 0x8006 # 0 +0xE3CC 0x8004 # 0 +0xE3CD 0x800B # 0 +0xE3CE 0x8012 # 0 +0xE3CF 0x8018 # 0 +0xE3D0 0x8019 # 0 +0xE3D1 0x801C # 0 +0xE3D2 0x8021 # 0 +0xE3D3 0x8028 # 0 +0xE3D4 0x803F # 0 +0xE3D5 0x803B # 0 +0xE3D6 0x804A # 0 +0xE3D7 0x8046 # 0 +0xE3D8 0x8052 # 0 +0xE3D9 0x8058 # 0 +0xE3DA 0x805A # 0 +0xE3DB 0x805F # 0 +0xE3DC 0x8062 # 0 +0xE3DD 0x8068 # 0 +0xE3DE 0x8073 # 0 +0xE3DF 0x8072 # 0 +0xE3E0 0x8070 # 0 +0xE3E1 0x8076 # 0 +0xE3E2 0x8079 # 0 +0xE3E3 0x807D # 0 +0xE3E4 0x807F # 0 +0xE3E5 0x8084 # 0 +0xE3E6 0x8086 # 0 +0xE3E7 0x8085 # 0 +0xE3E8 0x809B # 0 +0xE3E9 0x8093 # 0 +0xE3EA 0x809A # 0 +0xE3EB 0x80AD # 0 +0xE3EC 0x5190 # 0 +0xE3ED 0x80AC # 0 +0xE3EE 0x80DB # 0 +0xE3EF 0x80E5 # 0 +0xE3F0 0x80D9 # 0 +0xE3F1 0x80DD # 0 +0xE3F2 0x80C4 # 0 +0xE3F3 0x80DA # 0 +0xE3F4 0x80D6 # 0 +0xE3F5 0x8109 # 0 +0xE3F6 0x80EF # 0 +0xE3F7 0x80F1 # 0 +0xE3F8 0x811B # 0 +0xE3F9 0x8129 # 0 +0xE3FA 0x8123 # 0 +0xE3FB 0x812F # 0 +0xE3FC 0x814B # 0 +0xE440 0x968B # 0 +0xE441 0x8146 # 0 +0xE442 0x813E # 0 +0xE443 0x8153 # 0 +0xE444 0x8151 # 0 +0xE445 0x80FC # 0 +0xE446 0x8171 # 0 +0xE447 0x816E # 0 +0xE448 0x8165 # 0 +0xE449 0x8166 # 0 +0xE44A 0x8174 # 0 +0xE44B 0x8183 # 0 +0xE44C 0x8188 # 0 +0xE44D 0x818A # 0 +0xE44E 0x8180 # 0 +0xE44F 0x8182 # 0 +0xE450 0x81A0 # 0 +0xE451 0x8195 # 0 +0xE452 0x81A4 # 0 +0xE453 0x81A3 # 0 +0xE454 0x815F # 0 +0xE455 0x8193 # 0 +0xE456 0x81A9 # 0 +0xE457 0x81B0 # 0 +0xE458 0x81B5 # 0 +0xE459 0x81BE # 0 +0xE45A 0x81B8 # 0 +0xE45B 0x81BD # 0 +0xE45C 0x81C0 # 0 +0xE45D 0x81C2 # 0 +0xE45E 0x81BA # 0 +0xE45F 0x81C9 # 0 +0xE460 0x81CD # 0 +0xE461 0x81D1 # 0 +0xE462 0x81D9 # 0 +0xE463 0x81D8 # 0 +0xE464 0x81C8 # 0 +0xE465 0x81DA # 0 +0xE466 0x81DF # 0 +0xE467 0x81E0 # 0 +0xE468 0x81E7 # 0 +0xE469 0x81FA # 0 +0xE46A 0x81FB # 0 +0xE46B 0x81FE # 0 +0xE46C 0x8201 # 0 +0xE46D 0x8202 # 0 +0xE46E 0x8205 # 0 +0xE46F 0x8207 # 0 +0xE470 0x820A # 0 +0xE471 0x820D # 0 +0xE472 0x8210 # 0 +0xE473 0x8216 # 0 +0xE474 0x8229 # 0 +0xE475 0x822B # 0 +0xE476 0x8238 # 0 +0xE477 0x8233 # 0 +0xE478 0x8240 # 0 +0xE479 0x8259 # 0 +0xE47A 0x8258 # 0 +0xE47B 0x825D # 0 +0xE47C 0x825A # 0 +0xE47D 0x825F # 0 +0xE47E 0x8264 # 0 +0xE480 0x8262 # 0 +0xE481 0x8268 # 0 +0xE482 0x826A # 0 +0xE483 0x826B # 0 +0xE484 0x822E # 0 +0xE485 0x8271 # 0 +0xE486 0x8277 # 0 +0xE487 0x8278 # 0 +0xE488 0x827E # 0 +0xE489 0x828D # 0 +0xE48A 0x8292 # 0 +0xE48B 0x82AB # 0 +0xE48C 0x829F # 0 +0xE48D 0x82BB # 0 +0xE48E 0x82AC # 0 +0xE48F 0x82E1 # 0 +0xE490 0x82E3 # 0 +0xE491 0x82DF # 0 +0xE492 0x82D2 # 0 +0xE493 0x82F4 # 0 +0xE494 0x82F3 # 0 +0xE495 0x82FA # 0 +0xE496 0x8393 # 0 +0xE497 0x8303 # 0 +0xE498 0x82FB # 0 +0xE499 0x82F9 # 0 +0xE49A 0x82DE # 0 +0xE49B 0x8306 # 0 +0xE49C 0x82DC # 0 +0xE49D 0x8309 # 0 +0xE49E 0x82D9 # 0 +0xE49F 0x8335 # 0 +0xE4A0 0x8334 # 0 +0xE4A1 0x8316 # 0 +0xE4A2 0x8332 # 0 +0xE4A3 0x8331 # 0 +0xE4A4 0x8340 # 0 +0xE4A5 0x8339 # 0 +0xE4A6 0x8350 # 0 +0xE4A7 0x8345 # 0 +0xE4A8 0x832F # 0 +0xE4A9 0x832B # 0 +0xE4AA 0x8317 # 0 +0xE4AB 0x8318 # 0 +0xE4AC 0x8385 # 0 +0xE4AD 0x839A # 0 +0xE4AE 0x83AA # 0 +0xE4AF 0x839F # 0 +0xE4B0 0x83A2 # 0 +0xE4B1 0x8396 # 0 +0xE4B2 0x8323 # 0 +0xE4B3 0x838E # 0 +0xE4B4 0x8387 # 0 +0xE4B5 0x838A # 0 +0xE4B6 0x837C # 0 +0xE4B7 0x83B5 # 0 +0xE4B8 0x8373 # 0 +0xE4B9 0x8375 # 0 +0xE4BA 0x83A0 # 0 +0xE4BB 0x8389 # 0 +0xE4BC 0x83A8 # 0 +0xE4BD 0x83F4 # 0 +0xE4BE 0x8413 # 0 +0xE4BF 0x83EB # 0 +0xE4C0 0x83CE # 0 +0xE4C1 0x83FD # 0 +0xE4C2 0x8403 # 0 +0xE4C3 0x83D8 # 0 +0xE4C4 0x840B # 0 +0xE4C5 0x83C1 # 0 +0xE4C6 0x83F7 # 0 +0xE4C7 0x8407 # 0 +0xE4C8 0x83E0 # 0 +0xE4C9 0x83F2 # 0 +0xE4CA 0x840D # 0 +0xE4CB 0x8422 # 0 +0xE4CC 0x8420 # 0 +0xE4CD 0x83BD # 0 +0xE4CE 0x8438 # 0 +0xE4CF 0x8506 # 0 +0xE4D0 0x83FB # 0 +0xE4D1 0x846D # 0 +0xE4D2 0x842A # 0 +0xE4D3 0x843C # 0 +0xE4D4 0x855A # 0 +0xE4D5 0x8484 # 0 +0xE4D6 0x8477 # 0 +0xE4D7 0x846B # 0 +0xE4D8 0x84AD # 0 +0xE4D9 0x846E # 0 +0xE4DA 0x8482 # 0 +0xE4DB 0x8469 # 0 +0xE4DC 0x8446 # 0 +0xE4DD 0x842C # 0 +0xE4DE 0x846F # 0 +0xE4DF 0x8479 # 0 +0xE4E0 0x8435 # 0 +0xE4E1 0x84CA # 0 +0xE4E2 0x8462 # 0 +0xE4E3 0x84B9 # 0 +0xE4E4 0x84BF # 0 +0xE4E5 0x849F # 0 +0xE4E6 0x84D9 # 0 +0xE4E7 0x84CD # 0 +0xE4E8 0x84BB # 0 +0xE4E9 0x84DA # 0 +0xE4EA 0x84D0 # 0 +0xE4EB 0x84C1 # 0 +0xE4EC 0x84C6 # 0 +0xE4ED 0x84D6 # 0 +0xE4EE 0x84A1 # 0 +0xE4EF 0x8521 # 0 +0xE4F0 0x84FF # 0 +0xE4F1 0x84F4 # 0 +0xE4F2 0x8517 # 0 +0xE4F3 0x8518 # 0 +0xE4F4 0x852C # 0 +0xE4F5 0x851F # 0 +0xE4F6 0x8515 # 0 +0xE4F7 0x8514 # 0 +0xE4F8 0x84FC # 0 +0xE4F9 0x8540 # 0 +0xE4FA 0x8563 # 0 +0xE4FB 0x8558 # 0 +0xE4FC 0x8548 # 0 +0xE540 0x8541 # 0 +0xE541 0x8602 # 0 +0xE542 0x854B # 0 +0xE543 0x8555 # 0 +0xE544 0x8580 # 0 +0xE545 0x85A4 # 0 +0xE546 0x8588 # 0 +0xE547 0x8591 # 0 +0xE548 0x858A # 0 +0xE549 0x85A8 # 0 +0xE54A 0x856D # 0 +0xE54B 0x8594 # 0 +0xE54C 0x859B # 0 +0xE54D 0x85EA # 0 +0xE54E 0x8587 # 0 +0xE54F 0x859C # 0 +0xE550 0x8577 # 0 +0xE551 0x857E # 0 +0xE552 0x8590 # 0 +0xE553 0x85C9 # 0 +0xE554 0x85BA # 0 +0xE555 0x85CF # 0 +0xE556 0x85B9 # 0 +0xE557 0x85D0 # 0 +0xE558 0x85D5 # 0 +0xE559 0x85DD # 0 +0xE55A 0x85E5 # 0 +0xE55B 0x85DC # 0 +0xE55C 0x85F9 # 0 +0xE55D 0x860A # 0 +0xE55E 0x8613 # 0 +0xE55F 0x860B # 0 +0xE560 0x85FE # 0 +0xE561 0x85FA # 0 +0xE562 0x8606 # 0 +0xE563 0x8622 # 0 +0xE564 0x861A # 0 +0xE565 0x8630 # 0 +0xE566 0x863F # 0 +0xE567 0x864D # 0 +0xE568 0x4E55 # 0 +0xE569 0x8654 # 0 +0xE56A 0x865F # 0 +0xE56B 0x8667 # 0 +0xE56C 0x8671 # 0 +0xE56D 0x8693 # 0 +0xE56E 0x86A3 # 0 +0xE56F 0x86A9 # 0 +0xE570 0x86AA # 0 +0xE571 0x868B # 0 +0xE572 0x868C # 0 +0xE573 0x86B6 # 0 +0xE574 0x86AF # 0 +0xE575 0x86C4 # 0 +0xE576 0x86C6 # 0 +0xE577 0x86B0 # 0 +0xE578 0x86C9 # 0 +0xE579 0x8823 # 0 +0xE57A 0x86AB # 0 +0xE57B 0x86D4 # 0 +0xE57C 0x86DE # 0 +0xE57D 0x86E9 # 0 +0xE57E 0x86EC # 0 +0xE580 0x86DF # 0 +0xE581 0x86DB # 0 +0xE582 0x86EF # 0 +0xE583 0x8712 # 0 +0xE584 0x8706 # 0 +0xE585 0x8708 # 0 +0xE586 0x8700 # 0 +0xE587 0x8703 # 0 +0xE588 0x86FB # 0 +0xE589 0x8711 # 0 +0xE58A 0x8709 # 0 +0xE58B 0x870D # 0 +0xE58C 0x86F9 # 0 +0xE58D 0x870A # 0 +0xE58E 0x8734 # 0 +0xE58F 0x873F # 0 +0xE590 0x8737 # 0 +0xE591 0x873B # 0 +0xE592 0x8725 # 0 +0xE593 0x8729 # 0 +0xE594 0x871A # 0 +0xE595 0x8760 # 0 +0xE596 0x875F # 0 +0xE597 0x8778 # 0 +0xE598 0x874C # 0 +0xE599 0x874E # 0 +0xE59A 0x8774 # 0 +0xE59B 0x8757 # 0 +0xE59C 0x8768 # 0 +0xE59D 0x876E # 0 +0xE59E 0x8759 # 0 +0xE59F 0x8753 # 0 +0xE5A0 0x8763 # 0 +0xE5A1 0x876A # 0 +0xE5A2 0x8805 # 0 +0xE5A3 0x87A2 # 0 +0xE5A4 0x879F # 0 +0xE5A5 0x8782 # 0 +0xE5A6 0x87AF # 0 +0xE5A7 0x87CB # 0 +0xE5A8 0x87BD # 0 +0xE5A9 0x87C0 # 0 +0xE5AA 0x87D0 # 0 +0xE5AB 0x96D6 # 0 +0xE5AC 0x87AB # 0 +0xE5AD 0x87C4 # 0 +0xE5AE 0x87B3 # 0 +0xE5AF 0x87C7 # 0 +0xE5B0 0x87C6 # 0 +0xE5B1 0x87BB # 0 +0xE5B2 0x87EF # 0 +0xE5B3 0x87F2 # 0 +0xE5B4 0x87E0 # 0 +0xE5B5 0x880F # 0 +0xE5B6 0x880D # 0 +0xE5B7 0x87FE # 0 +0xE5B8 0x87F6 # 0 +0xE5B9 0x87F7 # 0 +0xE5BA 0x880E # 0 +0xE5BB 0x87D2 # 0 +0xE5BC 0x8811 # 0 +0xE5BD 0x8816 # 0 +0xE5BE 0x8815 # 0 +0xE5BF 0x8822 # 0 +0xE5C0 0x8821 # 0 +0xE5C1 0x8831 # 0 +0xE5C2 0x8836 # 0 +0xE5C3 0x8839 # 0 +0xE5C4 0x8827 # 0 +0xE5C5 0x883B # 0 +0xE5C6 0x8844 # 0 +0xE5C7 0x8842 # 0 +0xE5C8 0x8852 # 0 +0xE5C9 0x8859 # 0 +0xE5CA 0x885E # 0 +0xE5CB 0x8862 # 0 +0xE5CC 0x886B # 0 +0xE5CD 0x8881 # 0 +0xE5CE 0x887E # 0 +0xE5CF 0x889E # 0 +0xE5D0 0x8875 # 0 +0xE5D1 0x887D # 0 +0xE5D2 0x88B5 # 0 +0xE5D3 0x8872 # 0 +0xE5D4 0x8882 # 0 +0xE5D5 0x8897 # 0 +0xE5D6 0x8892 # 0 +0xE5D7 0x88AE # 0 +0xE5D8 0x8899 # 0 +0xE5D9 0x88A2 # 0 +0xE5DA 0x888D # 0 +0xE5DB 0x88A4 # 0 +0xE5DC 0x88B0 # 0 +0xE5DD 0x88BF # 0 +0xE5DE 0x88B1 # 0 +0xE5DF 0x88C3 # 0 +0xE5E0 0x88C4 # 0 +0xE5E1 0x88D4 # 0 +0xE5E2 0x88D8 # 0 +0xE5E3 0x88D9 # 0 +0xE5E4 0x88DD # 0 +0xE5E5 0x88F9 # 0 +0xE5E6 0x8902 # 0 +0xE5E7 0x88FC # 0 +0xE5E8 0x88F4 # 0 +0xE5E9 0x88E8 # 0 +0xE5EA 0x88F2 # 0 +0xE5EB 0x8904 # 0 +0xE5EC 0x890C # 0 +0xE5ED 0x890A # 0 +0xE5EE 0x8913 # 0 +0xE5EF 0x8943 # 0 +0xE5F0 0x891E # 0 +0xE5F1 0x8925 # 0 +0xE5F2 0x892A # 0 +0xE5F3 0x892B # 0 +0xE5F4 0x8941 # 0 +0xE5F5 0x8944 # 0 +0xE5F6 0x893B # 0 +0xE5F7 0x8936 # 0 +0xE5F8 0x8938 # 0 +0xE5F9 0x894C # 0 +0xE5FA 0x891D # 0 +0xE5FB 0x8960 # 0 +0xE5FC 0x895E # 0 +0xE640 0x8966 # 0 +0xE641 0x8964 # 0 +0xE642 0x896D # 0 +0xE643 0x896A # 0 +0xE644 0x896F # 0 +0xE645 0x8974 # 0 +0xE646 0x8977 # 0 +0xE647 0x897E # 0 +0xE648 0x8983 # 0 +0xE649 0x8988 # 0 +0xE64A 0x898A # 0 +0xE64B 0x8993 # 0 +0xE64C 0x8998 # 0 +0xE64D 0x89A1 # 0 +0xE64E 0x89A9 # 0 +0xE64F 0x89A6 # 0 +0xE650 0x89AC # 0 +0xE651 0x89AF # 0 +0xE652 0x89B2 # 0 +0xE653 0x89BA # 0 +0xE654 0x89BD # 0 +0xE655 0x89BF # 0 +0xE656 0x89C0 # 0 +0xE657 0x89DA # 0 +0xE658 0x89DC # 0 +0xE659 0x89DD # 0 +0xE65A 0x89E7 # 0 +0xE65B 0x89F4 # 0 +0xE65C 0x89F8 # 0 +0xE65D 0x8A03 # 0 +0xE65E 0x8A16 # 0 +0xE65F 0x8A10 # 0 +0xE660 0x8A0C # 0 +0xE661 0x8A1B # 0 +0xE662 0x8A1D # 0 +0xE663 0x8A25 # 0 +0xE664 0x8A36 # 0 +0xE665 0x8A41 # 0 +0xE666 0x8A5B # 0 +0xE667 0x8A52 # 0 +0xE668 0x8A46 # 0 +0xE669 0x8A48 # 0 +0xE66A 0x8A7C # 0 +0xE66B 0x8A6D # 0 +0xE66C 0x8A6C # 0 +0xE66D 0x8A62 # 0 +0xE66E 0x8A85 # 0 +0xE66F 0x8A82 # 0 +0xE670 0x8A84 # 0 +0xE671 0x8AA8 # 0 +0xE672 0x8AA1 # 0 +0xE673 0x8A91 # 0 +0xE674 0x8AA5 # 0 +0xE675 0x8AA6 # 0 +0xE676 0x8A9A # 0 +0xE677 0x8AA3 # 0 +0xE678 0x8AC4 # 0 +0xE679 0x8ACD # 0 +0xE67A 0x8AC2 # 0 +0xE67B 0x8ADA # 0 +0xE67C 0x8AEB # 0 +0xE67D 0x8AF3 # 0 +0xE67E 0x8AE7 # 0 +0xE680 0x8AE4 # 0 +0xE681 0x8AF1 # 0 +0xE682 0x8B14 # 0 +0xE683 0x8AE0 # 0 +0xE684 0x8AE2 # 0 +0xE685 0x8AF7 # 0 +0xE686 0x8ADE # 0 +0xE687 0x8ADB # 0 +0xE688 0x8B0C # 0 +0xE689 0x8B07 # 0 +0xE68A 0x8B1A # 0 +0xE68B 0x8AE1 # 0 +0xE68C 0x8B16 # 0 +0xE68D 0x8B10 # 0 +0xE68E 0x8B17 # 0 +0xE68F 0x8B20 # 0 +0xE690 0x8B33 # 0 +0xE691 0x97AB # 0 +0xE692 0x8B26 # 0 +0xE693 0x8B2B # 0 +0xE694 0x8B3E # 0 +0xE695 0x8B28 # 0 +0xE696 0x8B41 # 0 +0xE697 0x8B4C # 0 +0xE698 0x8B4F # 0 +0xE699 0x8B4E # 0 +0xE69A 0x8B49 # 0 +0xE69B 0x8B56 # 0 +0xE69C 0x8B5B # 0 +0xE69D 0x8B5A # 0 +0xE69E 0x8B6B # 0 +0xE69F 0x8B5F # 0 +0xE6A0 0x8B6C # 0 +0xE6A1 0x8B6F # 0 +0xE6A2 0x8B74 # 0 +0xE6A3 0x8B7D # 0 +0xE6A4 0x8B80 # 0 +0xE6A5 0x8B8C # 0 +0xE6A6 0x8B8E # 0 +0xE6A7 0x8B92 # 0 +0xE6A8 0x8B93 # 0 +0xE6A9 0x8B96 # 0 +0xE6AA 0x8B99 # 0 +0xE6AB 0x8B9A # 0 +0xE6AC 0x8C3A # 0 +0xE6AD 0x8C41 # 0 +0xE6AE 0x8C3F # 0 +0xE6AF 0x8C48 # 0 +0xE6B0 0x8C4C # 0 +0xE6B1 0x8C4E # 0 +0xE6B2 0x8C50 # 0 +0xE6B3 0x8C55 # 0 +0xE6B4 0x8C62 # 0 +0xE6B5 0x8C6C # 0 +0xE6B6 0x8C78 # 0 +0xE6B7 0x8C7A # 0 +0xE6B8 0x8C82 # 0 +0xE6B9 0x8C89 # 0 +0xE6BA 0x8C85 # 0 +0xE6BB 0x8C8A # 0 +0xE6BC 0x8C8D # 0 +0xE6BD 0x8C8E # 0 +0xE6BE 0x8C94 # 0 +0xE6BF 0x8C7C # 0 +0xE6C0 0x8C98 # 0 +0xE6C1 0x621D # 0 +0xE6C2 0x8CAD # 0 +0xE6C3 0x8CAA # 0 +0xE6C4 0x8CBD # 0 +0xE6C5 0x8CB2 # 0 +0xE6C6 0x8CB3 # 0 +0xE6C7 0x8CAE # 0 +0xE6C8 0x8CB6 # 0 +0xE6C9 0x8CC8 # 0 +0xE6CA 0x8CC1 # 0 +0xE6CB 0x8CE4 # 0 +0xE6CC 0x8CE3 # 0 +0xE6CD 0x8CDA # 0 +0xE6CE 0x8CFD # 0 +0xE6CF 0x8CFA # 0 +0xE6D0 0x8CFB # 0 +0xE6D1 0x8D04 # 0 +0xE6D2 0x8D05 # 0 +0xE6D3 0x8D0A # 0 +0xE6D4 0x8D07 # 0 +0xE6D5 0x8D0F # 0 +0xE6D6 0x8D0D # 0 +0xE6D7 0x8D10 # 0 +0xE6D8 0x9F4E # 0 +0xE6D9 0x8D13 # 0 +0xE6DA 0x8CCD # 0 +0xE6DB 0x8D14 # 0 +0xE6DC 0x8D16 # 0 +0xE6DD 0x8D67 # 0 +0xE6DE 0x8D6D # 0 +0xE6DF 0x8D71 # 0 +0xE6E0 0x8D73 # 0 +0xE6E1 0x8D81 # 0 +0xE6E2 0x8D99 # 0 +0xE6E3 0x8DC2 # 0 +0xE6E4 0x8DBE # 0 +0xE6E5 0x8DBA # 0 +0xE6E6 0x8DCF # 0 +0xE6E7 0x8DDA # 0 +0xE6E8 0x8DD6 # 0 +0xE6E9 0x8DCC # 0 +0xE6EA 0x8DDB # 0 +0xE6EB 0x8DCB # 0 +0xE6EC 0x8DEA # 0 +0xE6ED 0x8DEB # 0 +0xE6EE 0x8DDF # 0 +0xE6EF 0x8DE3 # 0 +0xE6F0 0x8DFC # 0 +0xE6F1 0x8E08 # 0 +0xE6F2 0x8E09 # 0 +0xE6F3 0x8DFF # 0 +0xE6F4 0x8E1D # 0 +0xE6F5 0x8E1E # 0 +0xE6F6 0x8E10 # 0 +0xE6F7 0x8E1F # 0 +0xE6F8 0x8E42 # 0 +0xE6F9 0x8E35 # 0 +0xE6FA 0x8E30 # 0 +0xE6FB 0x8E34 # 0 +0xE6FC 0x8E4A # 0 +0xE740 0x8E47 # 0 +0xE741 0x8E49 # 0 +0xE742 0x8E4C # 0 +0xE743 0x8E50 # 0 +0xE744 0x8E48 # 0 +0xE745 0x8E59 # 0 +0xE746 0x8E64 # 0 +0xE747 0x8E60 # 0 +0xE748 0x8E2A # 0 +0xE749 0x8E63 # 0 +0xE74A 0x8E55 # 0 +0xE74B 0x8E76 # 0 +0xE74C 0x8E72 # 0 +0xE74D 0x8E7C # 0 +0xE74E 0x8E81 # 0 +0xE74F 0x8E87 # 0 +0xE750 0x8E85 # 0 +0xE751 0x8E84 # 0 +0xE752 0x8E8B # 0 +0xE753 0x8E8A # 0 +0xE754 0x8E93 # 0 +0xE755 0x8E91 # 0 +0xE756 0x8E94 # 0 +0xE757 0x8E99 # 0 +0xE758 0x8EAA # 0 +0xE759 0x8EA1 # 0 +0xE75A 0x8EAC # 0 +0xE75B 0x8EB0 # 0 +0xE75C 0x8EC6 # 0 +0xE75D 0x8EB1 # 0 +0xE75E 0x8EBE # 0 +0xE75F 0x8EC5 # 0 +0xE760 0x8EC8 # 0 +0xE761 0x8ECB # 0 +0xE762 0x8EDB # 0 +0xE763 0x8EE3 # 0 +0xE764 0x8EFC # 0 +0xE765 0x8EFB # 0 +0xE766 0x8EEB # 0 +0xE767 0x8EFE # 0 +0xE768 0x8F0A # 0 +0xE769 0x8F05 # 0 +0xE76A 0x8F15 # 0 +0xE76B 0x8F12 # 0 +0xE76C 0x8F19 # 0 +0xE76D 0x8F13 # 0 +0xE76E 0x8F1C # 0 +0xE76F 0x8F1F # 0 +0xE770 0x8F1B # 0 +0xE771 0x8F0C # 0 +0xE772 0x8F26 # 0 +0xE773 0x8F33 # 0 +0xE774 0x8F3B # 0 +0xE775 0x8F39 # 0 +0xE776 0x8F45 # 0 +0xE777 0x8F42 # 0 +0xE778 0x8F3E # 0 +0xE779 0x8F4C # 0 +0xE77A 0x8F49 # 0 +0xE77B 0x8F46 # 0 +0xE77C 0x8F4E # 0 +0xE77D 0x8F57 # 0 +0xE77E 0x8F5C # 0 +0xE780 0x8F62 # 0 +0xE781 0x8F63 # 0 +0xE782 0x8F64 # 0 +0xE783 0x8F9C # 0 +0xE784 0x8F9F # 0 +0xE785 0x8FA3 # 0 +0xE786 0x8FAD # 0 +0xE787 0x8FAF # 0 +0xE788 0x8FB7 # 0 +0xE789 0x8FDA # 0 +0xE78A 0x8FE5 # 0 +0xE78B 0x8FE2 # 0 +0xE78C 0x8FEA # 0 +0xE78D 0x8FEF # 0 +0xE78E 0x9087 # 0 +0xE78F 0x8FF4 # 0 +0xE790 0x9005 # 0 +0xE791 0x8FF9 # 0 +0xE792 0x8FFA # 0 +0xE793 0x9011 # 0 +0xE794 0x9015 # 0 +0xE795 0x9021 # 0 +0xE796 0x900D # 0 +0xE797 0x901E # 0 +0xE798 0x9016 # 0 +0xE799 0x900B # 0 +0xE79A 0x9027 # 0 +0xE79B 0x9036 # 0 +0xE79C 0x9035 # 0 +0xE79D 0x9039 # 0 +0xE79E 0x8FF8 # 0 +0xE79F 0x904F # 0 +0xE7A0 0x9050 # 0 +0xE7A1 0x9051 # 0 +0xE7A2 0x9052 # 0 +0xE7A3 0x900E # 0 +0xE7A4 0x9049 # 0 +0xE7A5 0x903E # 0 +0xE7A6 0x9056 # 0 +0xE7A7 0x9058 # 0 +0xE7A8 0x905E # 0 +0xE7A9 0x9068 # 0 +0xE7AA 0x906F # 0 +0xE7AB 0x9076 # 0 +0xE7AC 0x96A8 # 0 +0xE7AD 0x9072 # 0 +0xE7AE 0x9082 # 0 +0xE7AF 0x907D # 0 +0xE7B0 0x9081 # 0 +0xE7B1 0x9080 # 0 +0xE7B2 0x908A # 0 +0xE7B3 0x9089 # 0 +0xE7B4 0x908F # 0 +0xE7B5 0x90A8 # 0 +0xE7B6 0x90AF # 0 +0xE7B7 0x90B1 # 0 +0xE7B8 0x90B5 # 0 +0xE7B9 0x90E2 # 0 +0xE7BA 0x90E4 # 0 +0xE7BB 0x6248 # 0 +0xE7BC 0x90DB # 0 +0xE7BD 0x9102 # 0 +0xE7BE 0x9112 # 0 +0xE7BF 0x9119 # 0 +0xE7C0 0x9132 # 0 +0xE7C1 0x9130 # 0 +0xE7C2 0x914A # 0 +0xE7C3 0x9156 # 0 +0xE7C4 0x9158 # 0 +0xE7C5 0x9163 # 0 +0xE7C6 0x9165 # 0 +0xE7C7 0x9169 # 0 +0xE7C8 0x9173 # 0 +0xE7C9 0x9172 # 0 +0xE7CA 0x918B # 0 +0xE7CB 0x9189 # 0 +0xE7CC 0x9182 # 0 +0xE7CD 0x91A2 # 0 +0xE7CE 0x91AB # 0 +0xE7CF 0x91AF # 0 +0xE7D0 0x91AA # 0 +0xE7D1 0x91B5 # 0 +0xE7D2 0x91B4 # 0 +0xE7D3 0x91BA # 0 +0xE7D4 0x91C0 # 0 +0xE7D5 0x91C1 # 0 +0xE7D6 0x91C9 # 0 +0xE7D7 0x91CB # 0 +0xE7D8 0x91D0 # 0 +0xE7D9 0x91D6 # 0 +0xE7DA 0x91DF # 0 +0xE7DB 0x91E1 # 0 +0xE7DC 0x91DB # 0 +0xE7DD 0x91FC # 0 +0xE7DE 0x91F5 # 0 +0xE7DF 0x91F6 # 0 +0xE7E0 0x921E # 0 +0xE7E1 0x91FF # 0 +0xE7E2 0x9214 # 0 +0xE7E3 0x922C # 0 +0xE7E4 0x9215 # 0 +0xE7E5 0x9211 # 0 +0xE7E6 0x925E # 0 +0xE7E7 0x9257 # 0 +0xE7E8 0x9245 # 0 +0xE7E9 0x9249 # 0 +0xE7EA 0x9264 # 0 +0xE7EB 0x9248 # 0 +0xE7EC 0x9295 # 0 +0xE7ED 0x923F # 0 +0xE7EE 0x924B # 0 +0xE7EF 0x9250 # 0 +0xE7F0 0x929C # 0 +0xE7F1 0x9296 # 0 +0xE7F2 0x9293 # 0 +0xE7F3 0x929B # 0 +0xE7F4 0x925A # 0 +0xE7F5 0x92CF # 0 +0xE7F6 0x92B9 # 0 +0xE7F7 0x92B7 # 0 +0xE7F8 0x92E9 # 0 +0xE7F9 0x930F # 0 +0xE7FA 0x92FA # 0 +0xE7FB 0x9344 # 0 +0xE7FC 0x932E # 0 +0xE840 0x9319 # 0 +0xE841 0x9322 # 0 +0xE842 0x931A # 0 +0xE843 0x9323 # 0 +0xE844 0x933A # 0 +0xE845 0x9335 # 0 +0xE846 0x933B # 0 +0xE847 0x935C # 0 +0xE848 0x9360 # 0 +0xE849 0x937C # 0 +0xE84A 0x936E # 0 +0xE84B 0x9356 # 0 +0xE84C 0x93B0 # 0 +0xE84D 0x93AC # 0 +0xE84E 0x93AD # 0 +0xE84F 0x9394 # 0 +0xE850 0x93B9 # 0 +0xE851 0x93D6 # 0 +0xE852 0x93D7 # 0 +0xE853 0x93E8 # 0 +0xE854 0x93E5 # 0 +0xE855 0x93D8 # 0 +0xE856 0x93C3 # 0 +0xE857 0x93DD # 0 +0xE858 0x93D0 # 0 +0xE859 0x93C8 # 0 +0xE85A 0x93E4 # 0 +0xE85B 0x941A # 0 +0xE85C 0x9414 # 0 +0xE85D 0x9413 # 0 +0xE85E 0x9403 # 0 +0xE85F 0x9407 # 0 +0xE860 0x9410 # 0 +0xE861 0x9436 # 0 +0xE862 0x942B # 0 +0xE863 0x9435 # 0 +0xE864 0x9421 # 0 +0xE865 0x943A # 0 +0xE866 0x9441 # 0 +0xE867 0x9452 # 0 +0xE868 0x9444 # 0 +0xE869 0x945B # 0 +0xE86A 0x9460 # 0 +0xE86B 0x9462 # 0 +0xE86C 0x945E # 0 +0xE86D 0x946A # 0 +0xE86E 0x9229 # 0 +0xE86F 0x9470 # 0 +0xE870 0x9475 # 0 +0xE871 0x9477 # 0 +0xE872 0x947D # 0 +0xE873 0x945A # 0 +0xE874 0x947C # 0 +0xE875 0x947E # 0 +0xE876 0x9481 # 0 +0xE877 0x947F # 0 +0xE878 0x9582 # 0 +0xE879 0x9587 # 0 +0xE87A 0x958A # 0 +0xE87B 0x9594 # 0 +0xE87C 0x9596 # 0 +0xE87D 0x9598 # 0 +0xE87E 0x9599 # 0 +0xE880 0x95A0 # 0 +0xE881 0x95A8 # 0 +0xE882 0x95A7 # 0 +0xE883 0x95AD # 0 +0xE884 0x95BC # 0 +0xE885 0x95BB # 0 +0xE886 0x95B9 # 0 +0xE887 0x95BE # 0 +0xE888 0x95CA # 0 +0xE889 0x6FF6 # 0 +0xE88A 0x95C3 # 0 +0xE88B 0x95CD # 0 +0xE88C 0x95CC # 0 +0xE88D 0x95D5 # 0 +0xE88E 0x95D4 # 0 +0xE88F 0x95D6 # 0 +0xE890 0x95DC # 0 +0xE891 0x95E1 # 0 +0xE892 0x95E5 # 0 +0xE893 0x95E2 # 0 +0xE894 0x9621 # 0 +0xE895 0x9628 # 0 +0xE896 0x962E # 0 +0xE897 0x962F # 0 +0xE898 0x9642 # 0 +0xE899 0x964C # 0 +0xE89A 0x964F # 0 +0xE89B 0x964B # 0 +0xE89C 0x9677 # 0 +0xE89D 0x965C # 0 +0xE89E 0x965E # 0 +0xE89F 0x965D # 0 +0xE8A0 0x965F # 0 +0xE8A1 0x9666 # 0 +0xE8A2 0x9672 # 0 +0xE8A3 0x966C # 0 +0xE8A4 0x968D # 0 +0xE8A5 0x9698 # 0 +0xE8A6 0x9695 # 0 +0xE8A7 0x9697 # 0 +0xE8A8 0x96AA # 0 +0xE8A9 0x96A7 # 0 +0xE8AA 0x96B1 # 0 +0xE8AB 0x96B2 # 0 +0xE8AC 0x96B0 # 0 +0xE8AD 0x96B4 # 0 +0xE8AE 0x96B6 # 0 +0xE8AF 0x96B8 # 0 +0xE8B0 0x96B9 # 0 +0xE8B1 0x96CE # 0 +0xE8B2 0x96CB # 0 +0xE8B3 0x96C9 # 0 +0xE8B4 0x96CD # 0 +0xE8B5 0x894D # 0 +0xE8B6 0x96DC # 0 +0xE8B7 0x970D # 0 +0xE8B8 0x96D5 # 0 +0xE8B9 0x96F9 # 0 +0xE8BA 0x9704 # 0 +0xE8BB 0x9706 # 0 +0xE8BC 0x9708 # 0 +0xE8BD 0x9713 # 0 +0xE8BE 0x970E # 0 +0xE8BF 0x9711 # 0 +0xE8C0 0x970F # 0 +0xE8C1 0x9716 # 0 +0xE8C2 0x9719 # 0 +0xE8C3 0x9724 # 0 +0xE8C4 0x972A # 0 +0xE8C5 0x9730 # 0 +0xE8C6 0x9739 # 0 +0xE8C7 0x973D # 0 +0xE8C8 0x973E # 0 +0xE8C9 0x9744 # 0 +0xE8CA 0x9746 # 0 +0xE8CB 0x9748 # 0 +0xE8CC 0x9742 # 0 +0xE8CD 0x9749 # 0 +0xE8CE 0x975C # 0 +0xE8CF 0x9760 # 0 +0xE8D0 0x9764 # 0 +0xE8D1 0x9766 # 0 +0xE8D2 0x9768 # 0 +0xE8D3 0x52D2 # 0 +0xE8D4 0x976B # 0 +0xE8D5 0x9771 # 0 +0xE8D6 0x9779 # 0 +0xE8D7 0x9785 # 0 +0xE8D8 0x977C # 0 +0xE8D9 0x9781 # 0 +0xE8DA 0x977A # 0 +0xE8DB 0x9786 # 0 +0xE8DC 0x978B # 0 +0xE8DD 0x978F # 0 +0xE8DE 0x9790 # 0 +0xE8DF 0x979C # 0 +0xE8E0 0x97A8 # 0 +0xE8E1 0x97A6 # 0 +0xE8E2 0x97A3 # 0 +0xE8E3 0x97B3 # 0 +0xE8E4 0x97B4 # 0 +0xE8E5 0x97C3 # 0 +0xE8E6 0x97C6 # 0 +0xE8E7 0x97C8 # 0 +0xE8E8 0x97CB # 0 +0xE8E9 0x97DC # 0 +0xE8EA 0x97ED # 0 +0xE8EB 0x9F4F # 0 +0xE8EC 0x97F2 # 0 +0xE8ED 0x7ADF # 0 +0xE8EE 0x97F6 # 0 +0xE8EF 0x97F5 # 0 +0xE8F0 0x980F # 0 +0xE8F1 0x980C # 0 +0xE8F2 0x9838 # 0 +0xE8F3 0x9824 # 0 +0xE8F4 0x9821 # 0 +0xE8F5 0x9837 # 0 +0xE8F6 0x983D # 0 +0xE8F7 0x9846 # 0 +0xE8F8 0x984F # 0 +0xE8F9 0x984B # 0 +0xE8FA 0x986B # 0 +0xE8FB 0x986F # 0 +0xE8FC 0x9870 # 0 +0xE940 0x9871 # 0 +0xE941 0x9874 # 0 +0xE942 0x9873 # 0 +0xE943 0x98AA # 0 +0xE944 0x98AF # 0 +0xE945 0x98B1 # 0 +0xE946 0x98B6 # 0 +0xE947 0x98C4 # 0 +0xE948 0x98C3 # 0 +0xE949 0x98C6 # 0 +0xE94A 0x98E9 # 0 +0xE94B 0x98EB # 0 +0xE94C 0x9903 # 0 +0xE94D 0x9909 # 0 +0xE94E 0x9912 # 0 +0xE94F 0x9914 # 0 +0xE950 0x9918 # 0 +0xE951 0x9921 # 0 +0xE952 0x991D # 0 +0xE953 0x991E # 0 +0xE954 0x9924 # 0 +0xE955 0x9920 # 0 +0xE956 0x992C # 0 +0xE957 0x992E # 0 +0xE958 0x993D # 0 +0xE959 0x993E # 0 +0xE95A 0x9942 # 0 +0xE95B 0x9949 # 0 +0xE95C 0x9945 # 0 +0xE95D 0x9950 # 0 +0xE95E 0x994B # 0 +0xE95F 0x9951 # 0 +0xE960 0x9952 # 0 +0xE961 0x994C # 0 +0xE962 0x9955 # 0 +0xE963 0x9997 # 0 +0xE964 0x9998 # 0 +0xE965 0x99A5 # 0 +0xE966 0x99AD # 0 +0xE967 0x99AE # 0 +0xE968 0x99BC # 0 +0xE969 0x99DF # 0 +0xE96A 0x99DB # 0 +0xE96B 0x99DD # 0 +0xE96C 0x99D8 # 0 +0xE96D 0x99D1 # 0 +0xE96E 0x99ED # 0 +0xE96F 0x99EE # 0 +0xE970 0x99F1 # 0 +0xE971 0x99F2 # 0 +0xE972 0x99FB # 0 +0xE973 0x99F8 # 0 +0xE974 0x9A01 # 0 +0xE975 0x9A0F # 0 +0xE976 0x9A05 # 0 +0xE977 0x99E2 # 0 +0xE978 0x9A19 # 0 +0xE979 0x9A2B # 0 +0xE97A 0x9A37 # 0 +0xE97B 0x9A45 # 0 +0xE97C 0x9A42 # 0 +0xE97D 0x9A40 # 0 +0xE97E 0x9A43 # 0 +0xE980 0x9A3E # 0 +0xE981 0x9A55 # 0 +0xE982 0x9A4D # 0 +0xE983 0x9A5B # 0 +0xE984 0x9A57 # 0 +0xE985 0x9A5F # 0 +0xE986 0x9A62 # 0 +0xE987 0x9A65 # 0 +0xE988 0x9A64 # 0 +0xE989 0x9A69 # 0 +0xE98A 0x9A6B # 0 +0xE98B 0x9A6A # 0 +0xE98C 0x9AAD # 0 +0xE98D 0x9AB0 # 0 +0xE98E 0x9ABC # 0 +0xE98F 0x9AC0 # 0 +0xE990 0x9ACF # 0 +0xE991 0x9AD1 # 0 +0xE992 0x9AD3 # 0 +0xE993 0x9AD4 # 0 +0xE994 0x9ADE # 0 +0xE995 0x9ADF # 0 +0xE996 0x9AE2 # 0 +0xE997 0x9AE3 # 0 +0xE998 0x9AE6 # 0 +0xE999 0x9AEF # 0 +0xE99A 0x9AEB # 0 +0xE99B 0x9AEE # 0 +0xE99C 0x9AF4 # 0 +0xE99D 0x9AF1 # 0 +0xE99E 0x9AF7 # 0 +0xE99F 0x9AFB # 0 +0xE9A0 0x9B06 # 0 +0xE9A1 0x9B18 # 0 +0xE9A2 0x9B1A # 0 +0xE9A3 0x9B1F # 0 +0xE9A4 0x9B22 # 0 +0xE9A5 0x9B23 # 0 +0xE9A6 0x9B25 # 0 +0xE9A7 0x9B27 # 0 +0xE9A8 0x9B28 # 0 +0xE9A9 0x9B29 # 0 +0xE9AA 0x9B2A # 0 +0xE9AB 0x9B2E # 0 +0xE9AC 0x9B2F # 0 +0xE9AD 0x9B32 # 0 +0xE9AE 0x9B44 # 0 +0xE9AF 0x9B43 # 0 +0xE9B0 0x9B4F # 0 +0xE9B1 0x9B4D # 0 +0xE9B2 0x9B4E # 0 +0xE9B3 0x9B51 # 0 +0xE9B4 0x9B58 # 0 +0xE9B5 0x9B74 # 0 +0xE9B6 0x9B93 # 0 +0xE9B7 0x9B83 # 0 +0xE9B8 0x9B91 # 0 +0xE9B9 0x9B96 # 0 +0xE9BA 0x9B97 # 0 +0xE9BB 0x9B9F # 0 +0xE9BC 0x9BA0 # 0 +0xE9BD 0x9BA8 # 0 +0xE9BE 0x9BB4 # 0 +0xE9BF 0x9BC0 # 0 +0xE9C0 0x9BCA # 0 +0xE9C1 0x9BB9 # 0 +0xE9C2 0x9BC6 # 0 +0xE9C3 0x9BCF # 0 +0xE9C4 0x9BD1 # 0 +0xE9C5 0x9BD2 # 0 +0xE9C6 0x9BE3 # 0 +0xE9C7 0x9BE2 # 0 +0xE9C8 0x9BE4 # 0 +0xE9C9 0x9BD4 # 0 +0xE9CA 0x9BE1 # 0 +0xE9CB 0x9C3A # 0 +0xE9CC 0x9BF2 # 0 +0xE9CD 0x9BF1 # 0 +0xE9CE 0x9BF0 # 0 +0xE9CF 0x9C15 # 0 +0xE9D0 0x9C14 # 0 +0xE9D1 0x9C09 # 0 +0xE9D2 0x9C13 # 0 +0xE9D3 0x9C0C # 0 +0xE9D4 0x9C06 # 0 +0xE9D5 0x9C08 # 0 +0xE9D6 0x9C12 # 0 +0xE9D7 0x9C0A # 0 +0xE9D8 0x9C04 # 0 +0xE9D9 0x9C2E # 0 +0xE9DA 0x9C1B # 0 +0xE9DB 0x9C25 # 0 +0xE9DC 0x9C24 # 0 +0xE9DD 0x9C21 # 0 +0xE9DE 0x9C30 # 0 +0xE9DF 0x9C47 # 0 +0xE9E0 0x9C32 # 0 +0xE9E1 0x9C46 # 0 +0xE9E2 0x9C3E # 0 +0xE9E3 0x9C5A # 0 +0xE9E4 0x9C60 # 0 +0xE9E5 0x9C67 # 0 +0xE9E6 0x9C76 # 0 +0xE9E7 0x9C78 # 0 +0xE9E8 0x9CE7 # 0 +0xE9E9 0x9CEC # 0 +0xE9EA 0x9CF0 # 0 +0xE9EB 0x9D09 # 0 +0xE9EC 0x9D08 # 0 +0xE9ED 0x9CEB # 0 +0xE9EE 0x9D03 # 0 +0xE9EF 0x9D06 # 0 +0xE9F0 0x9D2A # 0 +0xE9F1 0x9D26 # 0 +0xE9F2 0x9DAF # 0 +0xE9F3 0x9D23 # 0 +0xE9F4 0x9D1F # 0 +0xE9F5 0x9D44 # 0 +0xE9F6 0x9D15 # 0 +0xE9F7 0x9D12 # 0 +0xE9F8 0x9D41 # 0 +0xE9F9 0x9D3F # 0 +0xE9FA 0x9D3E # 0 +0xE9FB 0x9D46 # 0 +0xE9FC 0x9D48 # 0 +0xEA40 0x9D5D # 0 +0xEA41 0x9D5E # 0 +0xEA42 0x9D64 # 0 +0xEA43 0x9D51 # 0 +0xEA44 0x9D50 # 0 +0xEA45 0x9D59 # 0 +0xEA46 0x9D72 # 0 +0xEA47 0x9D89 # 0 +0xEA48 0x9D87 # 0 +0xEA49 0x9DAB # 0 +0xEA4A 0x9D6F # 0 +0xEA4B 0x9D7A # 0 +0xEA4C 0x9D9A # 0 +0xEA4D 0x9DA4 # 0 +0xEA4E 0x9DA9 # 0 +0xEA4F 0x9DB2 # 0 +0xEA50 0x9DC4 # 0 +0xEA51 0x9DC1 # 0 +0xEA52 0x9DBB # 0 +0xEA53 0x9DB8 # 0 +0xEA54 0x9DBA # 0 +0xEA55 0x9DC6 # 0 +0xEA56 0x9DCF # 0 +0xEA57 0x9DC2 # 0 +0xEA58 0x9DD9 # 0 +0xEA59 0x9DD3 # 0 +0xEA5A 0x9DF8 # 0 +0xEA5B 0x9DE6 # 0 +0xEA5C 0x9DED # 0 +0xEA5D 0x9DEF # 0 +0xEA5E 0x9DFD # 0 +0xEA5F 0x9E1A # 0 +0xEA60 0x9E1B # 0 +0xEA61 0x9E1E # 0 +0xEA62 0x9E75 # 0 +0xEA63 0x9E79 # 0 +0xEA64 0x9E7D # 0 +0xEA65 0x9E81 # 0 +0xEA66 0x9E88 # 0 +0xEA67 0x9E8B # 0 +0xEA68 0x9E8C # 0 +0xEA69 0x9E92 # 0 +0xEA6A 0x9E95 # 0 +0xEA6B 0x9E91 # 0 +0xEA6C 0x9E9D # 0 +0xEA6D 0x9EA5 # 0 +0xEA6E 0x9EA9 # 0 +0xEA6F 0x9EB8 # 0 +0xEA70 0x9EAA # 0 +0xEA71 0x9EAD # 0 +0xEA72 0x9761 # 0 +0xEA73 0x9ECC # 0 +0xEA74 0x9ECE # 0 +0xEA75 0x9ECF # 0 +0xEA76 0x9ED0 # 0 +0xEA77 0x9ED4 # 0 +0xEA78 0x9EDC # 0 +0xEA79 0x9EDE # 0 +0xEA7A 0x9EDD # 0 +0xEA7B 0x9EE0 # 0 +0xEA7C 0x9EE5 # 0 +0xEA7D 0x9EE8 # 0 +0xEA7E 0x9EEF # 0 +0xEA80 0x9EF4 # 0 +0xEA81 0x9EF6 # 0 +0xEA82 0x9EF7 # 0 +0xEA83 0x9EF9 # 0 +0xEA84 0x9EFB # 0 +0xEA85 0x9EFC # 0 +0xEA86 0x9EFD # 0 +0xEA87 0x9F07 # 0 +0xEA88 0x9F08 # 0 +0xEA89 0x76B7 # 0 +0xEA8A 0x9F15 # 0 +0xEA8B 0x9F21 # 0 +0xEA8C 0x9F2C # 0 +0xEA8D 0x9F3E # 0 +0xEA8E 0x9F4A # 0 +0xEA8F 0x9F52 # 0 +0xEA90 0x9F54 # 0 +0xEA91 0x9F63 # 0 +0xEA92 0x9F5F # 0 +0xEA93 0x9F60 # 0 +0xEA94 0x9F61 # 0 +0xEA95 0x9F66 # 0 +0xEA96 0x9F67 # 0 +0xEA97 0x9F6C # 0 +0xEA98 0x9F6A # 0 +0xEA99 0x9F77 # 0 +0xEA9A 0x9F72 # 0 +0xEA9B 0x9F76 # 0 +0xEA9C 0x9F95 # 0 +0xEA9D 0x9F9C # 0 +0xEA9E 0x9FA0 # 0 +0xEA9F 0x582F # 0 +0xEAA0 0x69C7 # 0 +0xEAA1 0x9059 # 0 +0xEAA2 0x7464 # 0 +0xEAA3 0x51DC # 0 +0xEAA4 0x7199 # 0 +0xF040 0xE000 # 0 +0xF041 0xE001 # 0 +0xF042 0xE002 # 0 +0xF043 0xE003 # 0 +0xF044 0xE004 # 0 +0xF045 0xE005 # 0 +0xF046 0xE006 # 0 +0xF047 0xE007 # 0 +0xF048 0xE008 # 0 +0xF049 0xE009 # 0 +0xF04A 0xE00A # 0 +0xF04B 0xE00B # 0 +0xF04C 0xE00C # 0 +0xF04D 0xE00D # 0 +0xF04E 0xE00E # 0 +0xF04F 0xE00F # 0 +0xF050 0xE010 # 0 +0xF051 0xE011 # 0 +0xF052 0xE012 # 0 +0xF053 0xE013 # 0 +0xF054 0xE014 # 0 +0xF055 0xE015 # 0 +0xF056 0xE016 # 0 +0xF057 0xE017 # 0 +0xF058 0xE018 # 0 +0xF059 0xE019 # 0 +0xF05A 0xE01A # 0 +0xF05B 0xE01B # 0 +0xF05C 0xE01C # 0 +0xF05D 0xE01D # 0 +0xF05E 0xE01E # 0 +0xF05F 0xE01F # 0 +0xF060 0xE020 # 0 +0xF061 0xE021 # 0 +0xF062 0xE022 # 0 +0xF063 0xE023 # 0 +0xF064 0xE024 # 0 +0xF065 0xE025 # 0 +0xF066 0xE026 # 0 +0xF067 0xE027 # 0 +0xF068 0xE028 # 0 +0xF069 0xE029 # 0 +0xF06A 0xE02A # 0 +0xF06B 0xE02B # 0 +0xF06C 0xE02C # 0 +0xF06D 0xE02D # 0 +0xF06E 0xE02E # 0 +0xF06F 0xE02F # 0 +0xF070 0xE030 # 0 +0xF071 0xE031 # 0 +0xF072 0xE032 # 0 +0xF073 0xE033 # 0 +0xF074 0xE034 # 0 +0xF075 0xE035 # 0 +0xF076 0xE036 # 0 +0xF077 0xE037 # 0 +0xF078 0xE038 # 0 +0xF079 0xE039 # 0 +0xF07A 0xE03A # 0 +0xF07B 0xE03B # 0 +0xF07C 0xE03C # 0 +0xF07D 0xE03D # 0 +0xF07E 0xE03E # 0 +0xF080 0xE03F # 0 +0xF081 0xE040 # 0 +0xF082 0xE041 # 0 +0xF083 0xE042 # 0 +0xF084 0xE043 # 0 +0xF085 0xE044 # 0 +0xF086 0xE045 # 0 +0xF087 0xE046 # 0 +0xF088 0xE047 # 0 +0xF089 0xE048 # 0 +0xF08A 0xE049 # 0 +0xF08B 0xE04A # 0 +0xF08C 0xE04B # 0 +0xF08D 0xE04C # 0 +0xF08E 0xE04D # 0 +0xF08F 0xE04E # 0 +0xF090 0xE04F # 0 +0xF091 0xE050 # 0 +0xF092 0xE051 # 0 +0xF093 0xE052 # 0 +0xF094 0xE053 # 0 +0xF095 0xE054 # 0 +0xF096 0xE055 # 0 +0xF097 0xE056 # 0 +0xF098 0xE057 # 0 +0xF099 0xE058 # 0 +0xF09A 0xE059 # 0 +0xF09B 0xE05A # 0 +0xF09C 0xE05B # 0 +0xF09D 0xE05C # 0 +0xF09E 0xE05D # 0 +0xF09F 0xE05E # 0 +0xF0A0 0xE05F # 0 +0xF0A1 0xE060 # 0 +0xF0A2 0xE061 # 0 +0xF0A3 0xE062 # 0 +0xF0A4 0xE063 # 0 +0xF0A5 0xE064 # 0 +0xF0A6 0xE065 # 0 +0xF0A7 0xE066 # 0 +0xF0A8 0xE067 # 0 +0xF0A9 0xE068 # 0 +0xF0AA 0xE069 # 0 +0xF0AB 0xE06A # 0 +0xF0AC 0xE06B # 0 +0xF0AD 0xE06C # 0 +0xF0AE 0xE06D # 0 +0xF0AF 0xE06E # 0 +0xF0B0 0xE06F # 0 +0xF0B1 0xE070 # 0 +0xF0B2 0xE071 # 0 +0xF0B3 0xE072 # 0 +0xF0B4 0xE073 # 0 +0xF0B5 0xE074 # 0 +0xF0B6 0xE075 # 0 +0xF0B7 0xE076 # 0 +0xF0B8 0xE077 # 0 +0xF0B9 0xE078 # 0 +0xF0BA 0xE079 # 0 +0xF0BB 0xE07A # 0 +0xF0BC 0xE07B # 0 +0xF0BD 0xE07C # 0 +0xF0BE 0xE07D # 0 +0xF0BF 0xE07E # 0 +0xF0C0 0xE07F # 0 +0xF0C1 0xE080 # 0 +0xF0C2 0xE081 # 0 +0xF0C3 0xE082 # 0 +0xF0C4 0xE083 # 0 +0xF0C5 0xE084 # 0 +0xF0C6 0xE085 # 0 +0xF0C7 0xE086 # 0 +0xF0C8 0xE087 # 0 +0xF0C9 0xE088 # 0 +0xF0CA 0xE089 # 0 +0xF0CB 0xE08A # 0 +0xF0CC 0xE08B # 0 +0xF0CD 0xE08C # 0 +0xF0CE 0xE08D # 0 +0xF0CF 0xE08E # 0 +0xF0D0 0xE08F # 0 +0xF0D1 0xE090 # 0 +0xF0D2 0xE091 # 0 +0xF0D3 0xE092 # 0 +0xF0D4 0xE093 # 0 +0xF0D5 0xE094 # 0 +0xF0D6 0xE095 # 0 +0xF0D7 0xE096 # 0 +0xF0D8 0xE097 # 0 +0xF0D9 0xE098 # 0 +0xF0DA 0xE099 # 0 +0xF0DB 0xE09A # 0 +0xF0DC 0xE09B # 0 +0xF0DD 0xE09C # 0 +0xF0DE 0xE09D # 0 +0xF0DF 0xE09E # 0 +0xF0E0 0xE09F # 0 +0xF0E1 0xE0A0 # 0 +0xF0E2 0xE0A1 # 0 +0xF0E3 0xE0A2 # 0 +0xF0E4 0xE0A3 # 0 +0xF0E5 0xE0A4 # 0 +0xF0E6 0xE0A5 # 0 +0xF0E7 0xE0A6 # 0 +0xF0E8 0xE0A7 # 0 +0xF0E9 0xE0A8 # 0 +0xF0EA 0xE0A9 # 0 +0xF0EB 0xE0AA # 0 +0xF0EC 0xE0AB # 0 +0xF0ED 0xE0AC # 0 +0xF0EE 0xE0AD # 0 +0xF0EF 0xE0AE # 0 +0xF0F0 0xE0AF # 0 +0xF0F1 0xE0B0 # 0 +0xF0F2 0xE0B1 # 0 +0xF0F3 0xE0B2 # 0 +0xF0F4 0xE0B3 # 0 +0xF0F5 0xE0B4 # 0 +0xF0F6 0xE0B5 # 0 +0xF0F7 0xE0B6 # 0 +0xF0F8 0xE0B7 # 0 +0xF0F9 0xE0B8 # 0 +0xF0FA 0xE0B9 # 0 +0xF0FB 0xE0BA # 0 +0xF0FC 0xE0BB # 0 +0xF140 0xE0BC # 0 +0xF141 0xE0BD # 0 +0xF142 0xE0BE # 0 +0xF143 0xE0BF # 0 +0xF144 0xE0C0 # 0 +0xF145 0xE0C1 # 0 +0xF146 0xE0C2 # 0 +0xF147 0xE0C3 # 0 +0xF148 0xE0C4 # 0 +0xF149 0xE0C5 # 0 +0xF14A 0xE0C6 # 0 +0xF14B 0xE0C7 # 0 +0xF14C 0xE0C8 # 0 +0xF14D 0xE0C9 # 0 +0xF14E 0xE0CA # 0 +0xF14F 0xE0CB # 0 +0xF150 0xE0CC # 0 +0xF151 0xE0CD # 0 +0xF152 0xE0CE # 0 +0xF153 0xE0CF # 0 +0xF154 0xE0D0 # 0 +0xF155 0xE0D1 # 0 +0xF156 0xE0D2 # 0 +0xF157 0xE0D3 # 0 +0xF158 0xE0D4 # 0 +0xF159 0xE0D5 # 0 +0xF15A 0xE0D6 # 0 +0xF15B 0xE0D7 # 0 +0xF15C 0xE0D8 # 0 +0xF15D 0xE0D9 # 0 +0xF15E 0xE0DA # 0 +0xF15F 0xE0DB # 0 +0xF160 0xE0DC # 0 +0xF161 0xE0DD # 0 +0xF162 0xE0DE # 0 +0xF163 0xE0DF # 0 +0xF164 0xE0E0 # 0 +0xF165 0xE0E1 # 0 +0xF166 0xE0E2 # 0 +0xF167 0xE0E3 # 0 +0xF168 0xE0E4 # 0 +0xF169 0xE0E5 # 0 +0xF16A 0xE0E6 # 0 +0xF16B 0xE0E7 # 0 +0xF16C 0xE0E8 # 0 +0xF16D 0xE0E9 # 0 +0xF16E 0xE0EA # 0 +0xF16F 0xE0EB # 0 +0xF170 0xE0EC # 0 +0xF171 0xE0ED # 0 +0xF172 0xE0EE # 0 +0xF173 0xE0EF # 0 +0xF174 0xE0F0 # 0 +0xF175 0xE0F1 # 0 +0xF176 0xE0F2 # 0 +0xF177 0xE0F3 # 0 +0xF178 0xE0F4 # 0 +0xF179 0xE0F5 # 0 +0xF17A 0xE0F6 # 0 +0xF17B 0xE0F7 # 0 +0xF17C 0xE0F8 # 0 +0xF17D 0xE0F9 # 0 +0xF17E 0xE0FA # 0 +0xF180 0xE0FB # 0 +0xF181 0xE0FC # 0 +0xF182 0xE0FD # 0 +0xF183 0xE0FE # 0 +0xF184 0xE0FF # 0 +0xF185 0xE100 # 0 +0xF186 0xE101 # 0 +0xF187 0xE102 # 0 +0xF188 0xE103 # 0 +0xF189 0xE104 # 0 +0xF18A 0xE105 # 0 +0xF18B 0xE106 # 0 +0xF18C 0xE107 # 0 +0xF18D 0xE108 # 0 +0xF18E 0xE109 # 0 +0xF18F 0xE10A # 0 +0xF190 0xE10B # 0 +0xF191 0xE10C # 0 +0xF192 0xE10D # 0 +0xF193 0xE10E # 0 +0xF194 0xE10F # 0 +0xF195 0xE110 # 0 +0xF196 0xE111 # 0 +0xF197 0xE112 # 0 +0xF198 0xE113 # 0 +0xF199 0xE114 # 0 +0xF19A 0xE115 # 0 +0xF19B 0xE116 # 0 +0xF19C 0xE117 # 0 +0xF19D 0xE118 # 0 +0xF19E 0xE119 # 0 +0xF19F 0xE11A # 0 +0xF1A0 0xE11B # 0 +0xF1A1 0xE11C # 0 +0xF1A2 0xE11D # 0 +0xF1A3 0xE11E # 0 +0xF1A4 0xE11F # 0 +0xF1A5 0xE120 # 0 +0xF1A6 0xE121 # 0 +0xF1A7 0xE122 # 0 +0xF1A8 0xE123 # 0 +0xF1A9 0xE124 # 0 +0xF1AA 0xE125 # 0 +0xF1AB 0xE126 # 0 +0xF1AC 0xE127 # 0 +0xF1AD 0xE128 # 0 +0xF1AE 0xE129 # 0 +0xF1AF 0xE12A # 0 +0xF1B0 0xE12B # 0 +0xF1B1 0xE12C # 0 +0xF1B2 0xE12D # 0 +0xF1B3 0xE12E # 0 +0xF1B4 0xE12F # 0 +0xF1B5 0xE130 # 0 +0xF1B6 0xE131 # 0 +0xF1B7 0xE132 # 0 +0xF1B8 0xE133 # 0 +0xF1B9 0xE134 # 0 +0xF1BA 0xE135 # 0 +0xF1BB 0xE136 # 0 +0xF1BC 0xE137 # 0 +0xF1BD 0xE138 # 0 +0xF1BE 0xE139 # 0 +0xF1BF 0xE13A # 0 +0xF1C0 0xE13B # 0 +0xF1C1 0xE13C # 0 +0xF1C2 0xE13D # 0 +0xF1C3 0xE13E # 0 +0xF1C4 0xE13F # 0 +0xF1C5 0xE140 # 0 +0xF1C6 0xE141 # 0 +0xF1C7 0xE142 # 0 +0xF1C8 0xE143 # 0 +0xF1C9 0xE144 # 0 +0xF1CA 0xE145 # 0 +0xF1CB 0xE146 # 0 +0xF1CC 0xE147 # 0 +0xF1CD 0xE148 # 0 +0xF1CE 0xE149 # 0 +0xF1CF 0xE14A # 0 +0xF1D0 0xE14B # 0 +0xF1D1 0xE14C # 0 +0xF1D2 0xE14D # 0 +0xF1D3 0xE14E # 0 +0xF1D4 0xE14F # 0 +0xF1D5 0xE150 # 0 +0xF1D6 0xE151 # 0 +0xF1D7 0xE152 # 0 +0xF1D8 0xE153 # 0 +0xF1D9 0xE154 # 0 +0xF1DA 0xE155 # 0 +0xF1DB 0xE156 # 0 +0xF1DC 0xE157 # 0 +0xF1DD 0xE158 # 0 +0xF1DE 0xE159 # 0 +0xF1DF 0xE15A # 0 +0xF1E0 0xE15B # 0 +0xF1E1 0xE15C # 0 +0xF1E2 0xE15D # 0 +0xF1E3 0xE15E # 0 +0xF1E4 0xE15F # 0 +0xF1E5 0xE160 # 0 +0xF1E6 0xE161 # 0 +0xF1E7 0xE162 # 0 +0xF1E8 0xE163 # 0 +0xF1E9 0xE164 # 0 +0xF1EA 0xE165 # 0 +0xF1EB 0xE166 # 0 +0xF1EC 0xE167 # 0 +0xF1ED 0xE168 # 0 +0xF1EE 0xE169 # 0 +0xF1EF 0xE16A # 0 +0xF1F0 0xE16B # 0 +0xF1F1 0xE16C # 0 +0xF1F2 0xE16D # 0 +0xF1F3 0xE16E # 0 +0xF1F4 0xE16F # 0 +0xF1F5 0xE170 # 0 +0xF1F6 0xE171 # 0 +0xF1F7 0xE172 # 0 +0xF1F8 0xE173 # 0 +0xF1F9 0xE174 # 0 +0xF1FA 0xE175 # 0 +0xF1FB 0xE176 # 0 +0xF1FC 0xE177 # 0 +0xF240 0xE178 # 0 +0xF241 0xE179 # 0 +0xF242 0xE17A # 0 +0xF243 0xE17B # 0 +0xF244 0xE17C # 0 +0xF245 0xE17D # 0 +0xF246 0xE17E # 0 +0xF247 0xE17F # 0 +0xF248 0xE180 # 0 +0xF249 0xE181 # 0 +0xF24A 0xE182 # 0 +0xF24B 0xE183 # 0 +0xF24C 0xE184 # 0 +0xF24D 0xE185 # 0 +0xF24E 0xE186 # 0 +0xF24F 0xE187 # 0 +0xF250 0xE188 # 0 +0xF251 0xE189 # 0 +0xF252 0xE18A # 0 +0xF253 0xE18B # 0 +0xF254 0xE18C # 0 +0xF255 0xE18D # 0 +0xF256 0xE18E # 0 +0xF257 0xE18F # 0 +0xF258 0xE190 # 0 +0xF259 0xE191 # 0 +0xF25A 0xE192 # 0 +0xF25B 0xE193 # 0 +0xF25C 0xE194 # 0 +0xF25D 0xE195 # 0 +0xF25E 0xE196 # 0 +0xF25F 0xE197 # 0 +0xF260 0xE198 # 0 +0xF261 0xE199 # 0 +0xF262 0xE19A # 0 +0xF263 0xE19B # 0 +0xF264 0xE19C # 0 +0xF265 0xE19D # 0 +0xF266 0xE19E # 0 +0xF267 0xE19F # 0 +0xF268 0xE1A0 # 0 +0xF269 0xE1A1 # 0 +0xF26A 0xE1A2 # 0 +0xF26B 0xE1A3 # 0 +0xF26C 0xE1A4 # 0 +0xF26D 0xE1A5 # 0 +0xF26E 0xE1A6 # 0 +0xF26F 0xE1A7 # 0 +0xF270 0xE1A8 # 0 +0xF271 0xE1A9 # 0 +0xF272 0xE1AA # 0 +0xF273 0xE1AB # 0 +0xF274 0xE1AC # 0 +0xF275 0xE1AD # 0 +0xF276 0xE1AE # 0 +0xF277 0xE1AF # 0 +0xF278 0xE1B0 # 0 +0xF279 0xE1B1 # 0 +0xF27A 0xE1B2 # 0 +0xF27B 0xE1B3 # 0 +0xF27C 0xE1B4 # 0 +0xF27D 0xE1B5 # 0 +0xF27E 0xE1B6 # 0 +0xF280 0xE1B7 # 0 +0xF281 0xE1B8 # 0 +0xF282 0xE1B9 # 0 +0xF283 0xE1BA # 0 +0xF284 0xE1BB # 0 +0xF285 0xE1BC # 0 +0xF286 0xE1BD # 0 +0xF287 0xE1BE # 0 +0xF288 0xE1BF # 0 +0xF289 0xE1C0 # 0 +0xF28A 0xE1C1 # 0 +0xF28B 0xE1C2 # 0 +0xF28C 0xE1C3 # 0 +0xF28D 0xE1C4 # 0 +0xF28E 0xE1C5 # 0 +0xF28F 0xE1C6 # 0 +0xF290 0xE1C7 # 0 +0xF291 0xE1C8 # 0 +0xF292 0xE1C9 # 0 +0xF293 0xE1CA # 0 +0xF294 0xE1CB # 0 +0xF295 0xE1CC # 0 +0xF296 0xE1CD # 0 +0xF297 0xE1CE # 0 +0xF298 0xE1CF # 0 +0xF299 0xE1D0 # 0 +0xF29A 0xE1D1 # 0 +0xF29B 0xE1D2 # 0 +0xF29C 0xE1D3 # 0 +0xF29D 0xE1D4 # 0 +0xF29E 0xE1D5 # 0 +0xF29F 0xE1D6 # 0 +0xF2A0 0xE1D7 # 0 +0xF2A1 0xE1D8 # 0 +0xF2A2 0xE1D9 # 0 +0xF2A3 0xE1DA # 0 +0xF2A4 0xE1DB # 0 +0xF2A5 0xE1DC # 0 +0xF2A6 0xE1DD # 0 +0xF2A7 0xE1DE # 0 +0xF2A8 0xE1DF # 0 +0xF2A9 0xE1E0 # 0 +0xF2AA 0xE1E1 # 0 +0xF2AB 0xE1E2 # 0 +0xF2AC 0xE1E3 # 0 +0xF2AD 0xE1E4 # 0 +0xF2AE 0xE1E5 # 0 +0xF2AF 0xE1E6 # 0 +0xF2B0 0xE1E7 # 0 +0xF2B1 0xE1E8 # 0 +0xF2B2 0xE1E9 # 0 +0xF2B3 0xE1EA # 0 +0xF2B4 0xE1EB # 0 +0xF2B5 0xE1EC # 0 +0xF2B6 0xE1ED # 0 +0xF2B7 0xE1EE # 0 +0xF2B8 0xE1EF # 0 +0xF2B9 0xE1F0 # 0 +0xF2BA 0xE1F1 # 0 +0xF2BB 0xE1F2 # 0 +0xF2BC 0xE1F3 # 0 +0xF2BD 0xE1F4 # 0 +0xF2BE 0xE1F5 # 0 +0xF2BF 0xE1F6 # 0 +0xF2C0 0xE1F7 # 0 +0xF2C1 0xE1F8 # 0 +0xF2C2 0xE1F9 # 0 +0xF2C3 0xE1FA # 0 +0xF2C4 0xE1FB # 0 +0xF2C5 0xE1FC # 0 +0xF2C6 0xE1FD # 0 +0xF2C7 0xE1FE # 0 +0xF2C8 0xE1FF # 0 +0xF2C9 0xE200 # 0 +0xF2CA 0xE201 # 0 +0xF2CB 0xE202 # 0 +0xF2CC 0xE203 # 0 +0xF2CD 0xE204 # 0 +0xF2CE 0xE205 # 0 +0xF2CF 0xE206 # 0 +0xF2D0 0xE207 # 0 +0xF2D1 0xE208 # 0 +0xF2D2 0xE209 # 0 +0xF2D3 0xE20A # 0 +0xF2D4 0xE20B # 0 +0xF2D5 0xE20C # 0 +0xF2D6 0xE20D # 0 +0xF2D7 0xE20E # 0 +0xF2D8 0xE20F # 0 +0xF2D9 0xE210 # 0 +0xF2DA 0xE211 # 0 +0xF2DB 0xE212 # 0 +0xF2DC 0xE213 # 0 +0xF2DD 0xE214 # 0 +0xF2DE 0xE215 # 0 +0xF2DF 0xE216 # 0 +0xF2E0 0xE217 # 0 +0xF2E1 0xE218 # 0 +0xF2E2 0xE219 # 0 +0xF2E3 0xE21A # 0 +0xF2E4 0xE21B # 0 +0xF2E5 0xE21C # 0 +0xF2E6 0xE21D # 0 +0xF2E7 0xE21E # 0 +0xF2E8 0xE21F # 0 +0xF2E9 0xE220 # 0 +0xF2EA 0xE221 # 0 +0xF2EB 0xE222 # 0 +0xF2EC 0xE223 # 0 +0xF2ED 0xE224 # 0 +0xF2EE 0xE225 # 0 +0xF2EF 0xE226 # 0 +0xF2F0 0xE227 # 0 +0xF2F1 0xE228 # 0 +0xF2F2 0xE229 # 0 +0xF2F3 0xE22A # 0 +0xF2F4 0xE22B # 0 +0xF2F5 0xE22C # 0 +0xF2F6 0xE22D # 0 +0xF2F7 0xE22E # 0 +0xF2F8 0xE22F # 0 +0xF2F9 0xE230 # 0 +0xF2FA 0xE231 # 0 +0xF2FB 0xE232 # 0 +0xF2FC 0xE233 # 0 +0xF340 0xE234 # 0 +0xF341 0xE235 # 0 +0xF342 0xE236 # 0 +0xF343 0xE237 # 0 +0xF344 0xE238 # 0 +0xF345 0xE239 # 0 +0xF346 0xE23A # 0 +0xF347 0xE23B # 0 +0xF348 0xE23C # 0 +0xF349 0xE23D # 0 +0xF34A 0xE23E # 0 +0xF34B 0xE23F # 0 +0xF34C 0xE240 # 0 +0xF34D 0xE241 # 0 +0xF34E 0xE242 # 0 +0xF34F 0xE243 # 0 +0xF350 0xE244 # 0 +0xF351 0xE245 # 0 +0xF352 0xE246 # 0 +0xF353 0xE247 # 0 +0xF354 0xE248 # 0 +0xF355 0xE249 # 0 +0xF356 0xE24A # 0 +0xF357 0xE24B # 0 +0xF358 0xE24C # 0 +0xF359 0xE24D # 0 +0xF35A 0xE24E # 0 +0xF35B 0xE24F # 0 +0xF35C 0xE250 # 0 +0xF35D 0xE251 # 0 +0xF35E 0xE252 # 0 +0xF35F 0xE253 # 0 +0xF360 0xE254 # 0 +0xF361 0xE255 # 0 +0xF362 0xE256 # 0 +0xF363 0xE257 # 0 +0xF364 0xE258 # 0 +0xF365 0xE259 # 0 +0xF366 0xE25A # 0 +0xF367 0xE25B # 0 +0xF368 0xE25C # 0 +0xF369 0xE25D # 0 +0xF36A 0xE25E # 0 +0xF36B 0xE25F # 0 +0xF36C 0xE260 # 0 +0xF36D 0xE261 # 0 +0xF36E 0xE262 # 0 +0xF36F 0xE263 # 0 +0xF370 0xE264 # 0 +0xF371 0xE265 # 0 +0xF372 0xE266 # 0 +0xF373 0xE267 # 0 +0xF374 0xE268 # 0 +0xF375 0xE269 # 0 +0xF376 0xE26A # 0 +0xF377 0xE26B # 0 +0xF378 0xE26C # 0 +0xF379 0xE26D # 0 +0xF37A 0xE26E # 0 +0xF37B 0xE26F # 0 +0xF37C 0xE270 # 0 +0xF37D 0xE271 # 0 +0xF37E 0xE272 # 0 +0xF380 0xE273 # 0 +0xF381 0xE274 # 0 +0xF382 0xE275 # 0 +0xF383 0xE276 # 0 +0xF384 0xE277 # 0 +0xF385 0xE278 # 0 +0xF386 0xE279 # 0 +0xF387 0xE27A # 0 +0xF388 0xE27B # 0 +0xF389 0xE27C # 0 +0xF38A 0xE27D # 0 +0xF38B 0xE27E # 0 +0xF38C 0xE27F # 0 +0xF38D 0xE280 # 0 +0xF38E 0xE281 # 0 +0xF38F 0xE282 # 0 +0xF390 0xE283 # 0 +0xF391 0xE284 # 0 +0xF392 0xE285 # 0 +0xF393 0xE286 # 0 +0xF394 0xE287 # 0 +0xF395 0xE288 # 0 +0xF396 0xE289 # 0 +0xF397 0xE28A # 0 +0xF398 0xE28B # 0 +0xF399 0xE28C # 0 +0xF39A 0xE28D # 0 +0xF39B 0xE28E # 0 +0xF39C 0xE28F # 0 +0xF39D 0xE290 # 0 +0xF39E 0xE291 # 0 +0xF39F 0xE292 # 0 +0xF3A0 0xE293 # 0 +0xF3A1 0xE294 # 0 +0xF3A2 0xE295 # 0 +0xF3A3 0xE296 # 0 +0xF3A4 0xE297 # 0 +0xF3A5 0xE298 # 0 +0xF3A6 0xE299 # 0 +0xF3A7 0xE29A # 0 +0xF3A8 0xE29B # 0 +0xF3A9 0xE29C # 0 +0xF3AA 0xE29D # 0 +0xF3AB 0xE29E # 0 +0xF3AC 0xE29F # 0 +0xF3AD 0xE2A0 # 0 +0xF3AE 0xE2A1 # 0 +0xF3AF 0xE2A2 # 0 +0xF3B0 0xE2A3 # 0 +0xF3B1 0xE2A4 # 0 +0xF3B2 0xE2A5 # 0 +0xF3B3 0xE2A6 # 0 +0xF3B4 0xE2A7 # 0 +0xF3B5 0xE2A8 # 0 +0xF3B6 0xE2A9 # 0 +0xF3B7 0xE2AA # 0 +0xF3B8 0xE2AB # 0 +0xF3B9 0xE2AC # 0 +0xF3BA 0xE2AD # 0 +0xF3BB 0xE2AE # 0 +0xF3BC 0xE2AF # 0 +0xF3BD 0xE2B0 # 0 +0xF3BE 0xE2B1 # 0 +0xF3BF 0xE2B2 # 0 +0xF3C0 0xE2B3 # 0 +0xF3C1 0xE2B4 # 0 +0xF3C2 0xE2B5 # 0 +0xF3C3 0xE2B6 # 0 +0xF3C4 0xE2B7 # 0 +0xF3C5 0xE2B8 # 0 +0xF3C6 0xE2B9 # 0 +0xF3C7 0xE2BA # 0 +0xF3C8 0xE2BB # 0 +0xF3C9 0xE2BC # 0 +0xF3CA 0xE2BD # 0 +0xF3CB 0xE2BE # 0 +0xF3CC 0xE2BF # 0 +0xF3CD 0xE2C0 # 0 +0xF3CE 0xE2C1 # 0 +0xF3CF 0xE2C2 # 0 +0xF3D0 0xE2C3 # 0 +0xF3D1 0xE2C4 # 0 +0xF3D2 0xE2C5 # 0 +0xF3D3 0xE2C6 # 0 +0xF3D4 0xE2C7 # 0 +0xF3D5 0xE2C8 # 0 +0xF3D6 0xE2C9 # 0 +0xF3D7 0xE2CA # 0 +0xF3D8 0xE2CB # 0 +0xF3D9 0xE2CC # 0 +0xF3DA 0xE2CD # 0 +0xF3DB 0xE2CE # 0 +0xF3DC 0xE2CF # 0 +0xF3DD 0xE2D0 # 0 +0xF3DE 0xE2D1 # 0 +0xF3DF 0xE2D2 # 0 +0xF3E0 0xE2D3 # 0 +0xF3E1 0xE2D4 # 0 +0xF3E2 0xE2D5 # 0 +0xF3E3 0xE2D6 # 0 +0xF3E4 0xE2D7 # 0 +0xF3E5 0xE2D8 # 0 +0xF3E6 0xE2D9 # 0 +0xF3E7 0xE2DA # 0 +0xF3E8 0xE2DB # 0 +0xF3E9 0xE2DC # 0 +0xF3EA 0xE2DD # 0 +0xF3EB 0xE2DE # 0 +0xF3EC 0xE2DF # 0 +0xF3ED 0xE2E0 # 0 +0xF3EE 0xE2E1 # 0 +0xF3EF 0xE2E2 # 0 +0xF3F0 0xE2E3 # 0 +0xF3F1 0xE2E4 # 0 +0xF3F2 0xE2E5 # 0 +0xF3F3 0xE2E6 # 0 +0xF3F4 0xE2E7 # 0 +0xF3F5 0xE2E8 # 0 +0xF3F6 0xE2E9 # 0 +0xF3F7 0xE2EA # 0 +0xF3F8 0xE2EB # 0 +0xF3F9 0xE2EC # 0 +0xF3FA 0xE2ED # 0 +0xF3FB 0xE2EE # 0 +0xF3FC 0xE2EF # 0 +0xF440 0xE2F0 # 0 +0xF441 0xE2F1 # 0 +0xF442 0xE2F2 # 0 +0xF443 0xE2F3 # 0 +0xF444 0xE2F4 # 0 +0xF445 0xE2F5 # 0 +0xF446 0xE2F6 # 0 +0xF447 0xE2F7 # 0 +0xF448 0xE2F8 # 0 +0xF449 0xE2F9 # 0 +0xF44A 0xE2FA # 0 +0xF44B 0xE2FB # 0 +0xF44C 0xE2FC # 0 +0xF44D 0xE2FD # 0 +0xF44E 0xE2FE # 0 +0xF44F 0xE2FF # 0 +0xF450 0xE300 # 0 +0xF451 0xE301 # 0 +0xF452 0xE302 # 0 +0xF453 0xE303 # 0 +0xF454 0xE304 # 0 +0xF455 0xE305 # 0 +0xF456 0xE306 # 0 +0xF457 0xE307 # 0 +0xF458 0xE308 # 0 +0xF459 0xE309 # 0 +0xF45A 0xE30A # 0 +0xF45B 0xE30B # 0 +0xF45C 0xE30C # 0 +0xF45D 0xE30D # 0 +0xF45E 0xE30E # 0 +0xF45F 0xE30F # 0 +0xF460 0xE310 # 0 +0xF461 0xE311 # 0 +0xF462 0xE312 # 0 +0xF463 0xE313 # 0 +0xF464 0xE314 # 0 +0xF465 0xE315 # 0 +0xF466 0xE316 # 0 +0xF467 0xE317 # 0 +0xF468 0xE318 # 0 +0xF469 0xE319 # 0 +0xF46A 0xE31A # 0 +0xF46B 0xE31B # 0 +0xF46C 0xE31C # 0 +0xF46D 0xE31D # 0 +0xF46E 0xE31E # 0 +0xF46F 0xE31F # 0 +0xF470 0xE320 # 0 +0xF471 0xE321 # 0 +0xF472 0xE322 # 0 +0xF473 0xE323 # 0 +0xF474 0xE324 # 0 +0xF475 0xE325 # 0 +0xF476 0xE326 # 0 +0xF477 0xE327 # 0 +0xF478 0xE328 # 0 +0xF479 0xE329 # 0 +0xF47A 0xE32A # 0 +0xF47B 0xE32B # 0 +0xF47C 0xE32C # 0 +0xF47D 0xE32D # 0 +0xF47E 0xE32E # 0 +0xF480 0xE32F # 0 +0xF481 0xE330 # 0 +0xF482 0xE331 # 0 +0xF483 0xE332 # 0 +0xF484 0xE333 # 0 +0xF485 0xE334 # 0 +0xF486 0xE335 # 0 +0xF487 0xE336 # 0 +0xF488 0xE337 # 0 +0xF489 0xE338 # 0 +0xF48A 0xE339 # 0 +0xF48B 0xE33A # 0 +0xF48C 0xE33B # 0 +0xF48D 0xE33C # 0 +0xF48E 0xE33D # 0 +0xF48F 0xE33E # 0 +0xF490 0xE33F # 0 +0xF491 0xE340 # 0 +0xF492 0xE341 # 0 +0xF493 0xE342 # 0 +0xF494 0xE343 # 0 +0xF495 0xE344 # 0 +0xF496 0xE345 # 0 +0xF497 0xE346 # 0 +0xF498 0xE347 # 0 +0xF499 0xE348 # 0 +0xF49A 0xE349 # 0 +0xF49B 0xE34A # 0 +0xF49C 0xE34B # 0 +0xF49D 0xE34C # 0 +0xF49E 0xE34D # 0 +0xF49F 0xE34E # 0 +0xF4A0 0xE34F # 0 +0xF4A1 0xE350 # 0 +0xF4A2 0xE351 # 0 +0xF4A3 0xE352 # 0 +0xF4A4 0xE353 # 0 +0xF4A5 0xE354 # 0 +0xF4A6 0xE355 # 0 +0xF4A7 0xE356 # 0 +0xF4A8 0xE357 # 0 +0xF4A9 0xE358 # 0 +0xF4AA 0xE359 # 0 +0xF4AB 0xE35A # 0 +0xF4AC 0xE35B # 0 +0xF4AD 0xE35C # 0 +0xF4AE 0xE35D # 0 +0xF4AF 0xE35E # 0 +0xF4B0 0xE35F # 0 +0xF4B1 0xE360 # 0 +0xF4B2 0xE361 # 0 +0xF4B3 0xE362 # 0 +0xF4B4 0xE363 # 0 +0xF4B5 0xE364 # 0 +0xF4B6 0xE365 # 0 +0xF4B7 0xE366 # 0 +0xF4B8 0xE367 # 0 +0xF4B9 0xE368 # 0 +0xF4BA 0xE369 # 0 +0xF4BB 0xE36A # 0 +0xF4BC 0xE36B # 0 +0xF4BD 0xE36C # 0 +0xF4BE 0xE36D # 0 +0xF4BF 0xE36E # 0 +0xF4C0 0xE36F # 0 +0xF4C1 0xE370 # 0 +0xF4C2 0xE371 # 0 +0xF4C3 0xE372 # 0 +0xF4C4 0xE373 # 0 +0xF4C5 0xE374 # 0 +0xF4C6 0xE375 # 0 +0xF4C7 0xE376 # 0 +0xF4C8 0xE377 # 0 +0xF4C9 0xE378 # 0 +0xF4CA 0xE379 # 0 +0xF4CB 0xE37A # 0 +0xF4CC 0xE37B # 0 +0xF4CD 0xE37C # 0 +0xF4CE 0xE37D # 0 +0xF4CF 0xE37E # 0 +0xF4D0 0xE37F # 0 +0xF4D1 0xE380 # 0 +0xF4D2 0xE381 # 0 +0xF4D3 0xE382 # 0 +0xF4D4 0xE383 # 0 +0xF4D5 0xE384 # 0 +0xF4D6 0xE385 # 0 +0xF4D7 0xE386 # 0 +0xF4D8 0xE387 # 0 +0xF4D9 0xE388 # 0 +0xF4DA 0xE389 # 0 +0xF4DB 0xE38A # 0 +0xF4DC 0xE38B # 0 +0xF4DD 0xE38C # 0 +0xF4DE 0xE38D # 0 +0xF4DF 0xE38E # 0 +0xF4E0 0xE38F # 0 +0xF4E1 0xE390 # 0 +0xF4E2 0xE391 # 0 +0xF4E3 0xE392 # 0 +0xF4E4 0xE393 # 0 +0xF4E5 0xE394 # 0 +0xF4E6 0xE395 # 0 +0xF4E7 0xE396 # 0 +0xF4E8 0xE397 # 0 +0xF4E9 0xE398 # 0 +0xF4EA 0xE399 # 0 +0xF4EB 0xE39A # 0 +0xF4EC 0xE39B # 0 +0xF4ED 0xE39C # 0 +0xF4EE 0xE39D # 0 +0xF4EF 0xE39E # 0 +0xF4F0 0xE39F # 0 +0xF4F1 0xE3A0 # 0 +0xF4F2 0xE3A1 # 0 +0xF4F3 0xE3A2 # 0 +0xF4F4 0xE3A3 # 0 +0xF4F5 0xE3A4 # 0 +0xF4F6 0xE3A5 # 0 +0xF4F7 0xE3A6 # 0 +0xF4F8 0xE3A7 # 0 +0xF4F9 0xE3A8 # 0 +0xF4FA 0xE3A9 # 0 +0xF4FB 0xE3AA # 0 +0xF4FC 0xE3AB # 0 +0xF540 0xE3AC # 0 +0xF541 0xE3AD # 0 +0xF542 0xE3AE # 0 +0xF543 0xE3AF # 0 +0xF544 0xE3B0 # 0 +0xF545 0xE3B1 # 0 +0xF546 0xE3B2 # 0 +0xF547 0xE3B3 # 0 +0xF548 0xE3B4 # 0 +0xF549 0xE3B5 # 0 +0xF54A 0xE3B6 # 0 +0xF54B 0xE3B7 # 0 +0xF54C 0xE3B8 # 0 +0xF54D 0xE3B9 # 0 +0xF54E 0xE3BA # 0 +0xF54F 0xE3BB # 0 +0xF550 0xE3BC # 0 +0xF551 0xE3BD # 0 +0xF552 0xE3BE # 0 +0xF553 0xE3BF # 0 +0xF554 0xE3C0 # 0 +0xF555 0xE3C1 # 0 +0xF556 0xE3C2 # 0 +0xF557 0xE3C3 # 0 +0xF558 0xE3C4 # 0 +0xF559 0xE3C5 # 0 +0xF55A 0xE3C6 # 0 +0xF55B 0xE3C7 # 0 +0xF55C 0xE3C8 # 0 +0xF55D 0xE3C9 # 0 +0xF55E 0xE3CA # 0 +0xF55F 0xE3CB # 0 +0xF560 0xE3CC # 0 +0xF561 0xE3CD # 0 +0xF562 0xE3CE # 0 +0xF563 0xE3CF # 0 +0xF564 0xE3D0 # 0 +0xF565 0xE3D1 # 0 +0xF566 0xE3D2 # 0 +0xF567 0xE3D3 # 0 +0xF568 0xE3D4 # 0 +0xF569 0xE3D5 # 0 +0xF56A 0xE3D6 # 0 +0xF56B 0xE3D7 # 0 +0xF56C 0xE3D8 # 0 +0xF56D 0xE3D9 # 0 +0xF56E 0xE3DA # 0 +0xF56F 0xE3DB # 0 +0xF570 0xE3DC # 0 +0xF571 0xE3DD # 0 +0xF572 0xE3DE # 0 +0xF573 0xE3DF # 0 +0xF574 0xE3E0 # 0 +0xF575 0xE3E1 # 0 +0xF576 0xE3E2 # 0 +0xF577 0xE3E3 # 0 +0xF578 0xE3E4 # 0 +0xF579 0xE3E5 # 0 +0xF57A 0xE3E6 # 0 +0xF57B 0xE3E7 # 0 +0xF57C 0xE3E8 # 0 +0xF57D 0xE3E9 # 0 +0xF57E 0xE3EA # 0 +0xF580 0xE3EB # 0 +0xF581 0xE3EC # 0 +0xF582 0xE3ED # 0 +0xF583 0xE3EE # 0 +0xF584 0xE3EF # 0 +0xF585 0xE3F0 # 0 +0xF586 0xE3F1 # 0 +0xF587 0xE3F2 # 0 +0xF588 0xE3F3 # 0 +0xF589 0xE3F4 # 0 +0xF58A 0xE3F5 # 0 +0xF58B 0xE3F6 # 0 +0xF58C 0xE3F7 # 0 +0xF58D 0xE3F8 # 0 +0xF58E 0xE3F9 # 0 +0xF58F 0xE3FA # 0 +0xF590 0xE3FB # 0 +0xF591 0xE3FC # 0 +0xF592 0xE3FD # 0 +0xF593 0xE3FE # 0 +0xF594 0xE3FF # 0 +0xF595 0xE400 # 0 +0xF596 0xE401 # 0 +0xF597 0xE402 # 0 +0xF598 0xE403 # 0 +0xF599 0xE404 # 0 +0xF59A 0xE405 # 0 +0xF59B 0xE406 # 0 +0xF59C 0xE407 # 0 +0xF59D 0xE408 # 0 +0xF59E 0xE409 # 0 +0xF59F 0xE40A # 0 +0xF5A0 0xE40B # 0 +0xF5A1 0xE40C # 0 +0xF5A2 0xE40D # 0 +0xF5A3 0xE40E # 0 +0xF5A4 0xE40F # 0 +0xF5A5 0xE410 # 0 +0xF5A6 0xE411 # 0 +0xF5A7 0xE412 # 0 +0xF5A8 0xE413 # 0 +0xF5A9 0xE414 # 0 +0xF5AA 0xE415 # 0 +0xF5AB 0xE416 # 0 +0xF5AC 0xE417 # 0 +0xF5AD 0xE418 # 0 +0xF5AE 0xE419 # 0 +0xF5AF 0xE41A # 0 +0xF5B0 0xE41B # 0 +0xF5B1 0xE41C # 0 +0xF5B2 0xE41D # 0 +0xF5B3 0xE41E # 0 +0xF5B4 0xE41F # 0 +0xF5B5 0xE420 # 0 +0xF5B6 0xE421 # 0 +0xF5B7 0xE422 # 0 +0xF5B8 0xE423 # 0 +0xF5B9 0xE424 # 0 +0xF5BA 0xE425 # 0 +0xF5BB 0xE426 # 0 +0xF5BC 0xE427 # 0 +0xF5BD 0xE428 # 0 +0xF5BE 0xE429 # 0 +0xF5BF 0xE42A # 0 +0xF5C0 0xE42B # 0 +0xF5C1 0xE42C # 0 +0xF5C2 0xE42D # 0 +0xF5C3 0xE42E # 0 +0xF5C4 0xE42F # 0 +0xF5C5 0xE430 # 0 +0xF5C6 0xE431 # 0 +0xF5C7 0xE432 # 0 +0xF5C8 0xE433 # 0 +0xF5C9 0xE434 # 0 +0xF5CA 0xE435 # 0 +0xF5CB 0xE436 # 0 +0xF5CC 0xE437 # 0 +0xF5CD 0xE438 # 0 +0xF5CE 0xE439 # 0 +0xF5CF 0xE43A # 0 +0xF5D0 0xE43B # 0 +0xF5D1 0xE43C # 0 +0xF5D2 0xE43D # 0 +0xF5D3 0xE43E # 0 +0xF5D4 0xE43F # 0 +0xF5D5 0xE440 # 0 +0xF5D6 0xE441 # 0 +0xF5D7 0xE442 # 0 +0xF5D8 0xE443 # 0 +0xF5D9 0xE444 # 0 +0xF5DA 0xE445 # 0 +0xF5DB 0xE446 # 0 +0xF5DC 0xE447 # 0 +0xF5DD 0xE448 # 0 +0xF5DE 0xE449 # 0 +0xF5DF 0xE44A # 0 +0xF5E0 0xE44B # 0 +0xF5E1 0xE44C # 0 +0xF5E2 0xE44D # 0 +0xF5E3 0xE44E # 0 +0xF5E4 0xE44F # 0 +0xF5E5 0xE450 # 0 +0xF5E6 0xE451 # 0 +0xF5E7 0xE452 # 0 +0xF5E8 0xE453 # 0 +0xF5E9 0xE454 # 0 +0xF5EA 0xE455 # 0 +0xF5EB 0xE456 # 0 +0xF5EC 0xE457 # 0 +0xF5ED 0xE458 # 0 +0xF5EE 0xE459 # 0 +0xF5EF 0xE45A # 0 +0xF5F0 0xE45B # 0 +0xF5F1 0xE45C # 0 +0xF5F2 0xE45D # 0 +0xF5F3 0xE45E # 0 +0xF5F4 0xE45F # 0 +0xF5F5 0xE460 # 0 +0xF5F6 0xE461 # 0 +0xF5F7 0xE462 # 0 +0xF5F8 0xE463 # 0 +0xF5F9 0xE464 # 0 +0xF5FA 0xE465 # 0 +0xF5FB 0xE466 # 0 +0xF5FC 0xE467 # 0 +0xF640 0xE468 # 0 +0xF641 0xE469 # 0 +0xF642 0xE46A # 0 +0xF643 0xE46B # 0 +0xF644 0xE46C # 0 +0xF645 0xE46D # 0 +0xF646 0xE46E # 0 +0xF647 0xE46F # 0 +0xF648 0xE470 # 0 +0xF649 0xE471 # 0 +0xF64A 0xE472 # 0 +0xF64B 0xE473 # 0 +0xF64C 0xE474 # 0 +0xF64D 0xE475 # 0 +0xF64E 0xE476 # 0 +0xF64F 0xE477 # 0 +0xF650 0xE478 # 0 +0xF651 0xE479 # 0 +0xF652 0xE47A # 0 +0xF653 0xE47B # 0 +0xF654 0xE47C # 0 +0xF655 0xE47D # 0 +0xF656 0xE47E # 0 +0xF657 0xE47F # 0 +0xF658 0xE480 # 0 +0xF659 0xE481 # 0 +0xF65A 0xE482 # 0 +0xF65B 0xE483 # 0 +0xF65C 0xE484 # 0 +0xF65D 0xE485 # 0 +0xF65E 0xE486 # 0 +0xF65F 0xE487 # 0 +0xF660 0xE488 # 0 +0xF661 0xE489 # 0 +0xF662 0xE48A # 0 +0xF663 0xE48B # 0 +0xF664 0xE48C # 0 +0xF665 0xE48D # 0 +0xF666 0xE48E # 0 +0xF667 0xE48F # 0 +0xF668 0xE490 # 0 +0xF669 0xE491 # 0 +0xF66A 0xE492 # 0 +0xF66B 0xE493 # 0 +0xF66C 0xE494 # 0 +0xF66D 0xE495 # 0 +0xF66E 0xE496 # 0 +0xF66F 0xE497 # 0 +0xF670 0xE498 # 0 +0xF671 0xE499 # 0 +0xF672 0xE49A # 0 +0xF673 0xE49B # 0 +0xF674 0xE49C # 0 +0xF675 0xE49D # 0 +0xF676 0xE49E # 0 +0xF677 0xE49F # 0 +0xF678 0xE4A0 # 0 +0xF679 0xE4A1 # 0 +0xF67A 0xE4A2 # 0 +0xF67B 0xE4A3 # 0 +0xF67C 0xE4A4 # 0 +0xF67D 0xE4A5 # 0 +0xF67E 0xE4A6 # 0 +0xF680 0xE4A7 # 0 +0xF681 0xE4A8 # 0 +0xF682 0xE4A9 # 0 +0xF683 0xE4AA # 0 +0xF684 0xE4AB # 0 +0xF685 0xE4AC # 0 +0xF686 0xE4AD # 0 +0xF687 0xE4AE # 0 +0xF688 0xE4AF # 0 +0xF689 0xE4B0 # 0 +0xF68A 0xE4B1 # 0 +0xF68B 0xE4B2 # 0 +0xF68C 0xE4B3 # 0 +0xF68D 0xE4B4 # 0 +0xF68E 0xE4B5 # 0 +0xF68F 0xE4B6 # 0 +0xF690 0xE4B7 # 0 +0xF691 0xE4B8 # 0 +0xF692 0xE4B9 # 0 +0xF693 0xE4BA # 0 +0xF694 0xE4BB # 0 +0xF695 0xE4BC # 0 +0xF696 0xE4BD # 0 +0xF697 0xE4BE # 0 +0xF698 0xE4BF # 0 +0xF699 0xE4C0 # 0 +0xF69A 0xE4C1 # 0 +0xF69B 0xE4C2 # 0 +0xF69C 0xE4C3 # 0 +0xF69D 0xE4C4 # 0 +0xF69E 0xE4C5 # 0 +0xF69F 0xE4C6 # 0 +0xF6A0 0xE4C7 # 0 +0xF6A1 0xE4C8 # 0 +0xF6A2 0xE4C9 # 0 +0xF6A3 0xE4CA # 0 +0xF6A4 0xE4CB # 0 +0xF6A5 0xE4CC # 0 +0xF6A6 0xE4CD # 0 +0xF6A7 0xE4CE # 0 +0xF6A8 0xE4CF # 0 +0xF6A9 0xE4D0 # 0 +0xF6AA 0xE4D1 # 0 +0xF6AB 0xE4D2 # 0 +0xF6AC 0xE4D3 # 0 +0xF6AD 0xE4D4 # 0 +0xF6AE 0xE4D5 # 0 +0xF6AF 0xE4D6 # 0 +0xF6B0 0xE4D7 # 0 +0xF6B1 0xE4D8 # 0 +0xF6B2 0xE4D9 # 0 +0xF6B3 0xE4DA # 0 +0xF6B4 0xE4DB # 0 +0xF6B5 0xE4DC # 0 +0xF6B6 0xE4DD # 0 +0xF6B7 0xE4DE # 0 +0xF6B8 0xE4DF # 0 +0xF6B9 0xE4E0 # 0 +0xF6BA 0xE4E1 # 0 +0xF6BB 0xE4E2 # 0 +0xF6BC 0xE4E3 # 0 +0xF6BD 0xE4E4 # 0 +0xF6BE 0xE4E5 # 0 +0xF6BF 0xE4E6 # 0 +0xF6C0 0xE4E7 # 0 +0xF6C1 0xE4E8 # 0 +0xF6C2 0xE4E9 # 0 +0xF6C3 0xE4EA # 0 +0xF6C4 0xE4EB # 0 +0xF6C5 0xE4EC # 0 +0xF6C6 0xE4ED # 0 +0xF6C7 0xE4EE # 0 +0xF6C8 0xE4EF # 0 +0xF6C9 0xE4F0 # 0 +0xF6CA 0xE4F1 # 0 +0xF6CB 0xE4F2 # 0 +0xF6CC 0xE4F3 # 0 +0xF6CD 0xE4F4 # 0 +0xF6CE 0xE4F5 # 0 +0xF6CF 0xE4F6 # 0 +0xF6D0 0xE4F7 # 0 +0xF6D1 0xE4F8 # 0 +0xF6D2 0xE4F9 # 0 +0xF6D3 0xE4FA # 0 +0xF6D4 0xE4FB # 0 +0xF6D5 0xE4FC # 0 +0xF6D6 0xE4FD # 0 +0xF6D7 0xE4FE # 0 +0xF6D8 0xE4FF # 0 +0xF6D9 0xE500 # 0 +0xF6DA 0xE501 # 0 +0xF6DB 0xE502 # 0 +0xF6DC 0xE503 # 0 +0xF6DD 0xE504 # 0 +0xF6DE 0xE505 # 0 +0xF6DF 0xE506 # 0 +0xF6E0 0xE507 # 0 +0xF6E1 0xE508 # 0 +0xF6E2 0xE509 # 0 +0xF6E3 0xE50A # 0 +0xF6E4 0xE50B # 0 +0xF6E5 0xE50C # 0 +0xF6E6 0xE50D # 0 +0xF6E7 0xE50E # 0 +0xF6E8 0xE50F # 0 +0xF6E9 0xE510 # 0 +0xF6EA 0xE511 # 0 +0xF6EB 0xE512 # 0 +0xF6EC 0xE513 # 0 +0xF6ED 0xE514 # 0 +0xF6EE 0xE515 # 0 +0xF6EF 0xE516 # 0 +0xF6F0 0xE517 # 0 +0xF6F1 0xE518 # 0 +0xF6F2 0xE519 # 0 +0xF6F3 0xE51A # 0 +0xF6F4 0xE51B # 0 +0xF6F5 0xE51C # 0 +0xF6F6 0xE51D # 0 +0xF6F7 0xE51E # 0 +0xF6F8 0xE51F # 0 +0xF6F9 0xE520 # 0 +0xF6FA 0xE521 # 0 +0xF6FB 0xE522 # 0 +0xF6FC 0xE523 # 0 +0xF740 0xE524 # 0 +0xF741 0xE525 # 0 +0xF742 0xE526 # 0 +0xF743 0xE527 # 0 +0xF744 0xE528 # 0 +0xF745 0xE529 # 0 +0xF746 0xE52A # 0 +0xF747 0xE52B # 0 +0xF748 0xE52C # 0 +0xF749 0xE52D # 0 +0xF74A 0xE52E # 0 +0xF74B 0xE52F # 0 +0xF74C 0xE530 # 0 +0xF74D 0xE531 # 0 +0xF74E 0xE532 # 0 +0xF74F 0xE533 # 0 +0xF750 0xE534 # 0 +0xF751 0xE535 # 0 +0xF752 0xE536 # 0 +0xF753 0xE537 # 0 +0xF754 0xE538 # 0 +0xF755 0xE539 # 0 +0xF756 0xE53A # 0 +0xF757 0xE53B # 0 +0xF758 0xE53C # 0 +0xF759 0xE53D # 0 +0xF75A 0xE53E # 0 +0xF75B 0xE53F # 0 +0xF75C 0xE540 # 0 +0xF75D 0xE541 # 0 +0xF75E 0xE542 # 0 +0xF75F 0xE543 # 0 +0xF760 0xE544 # 0 +0xF761 0xE545 # 0 +0xF762 0xE546 # 0 +0xF763 0xE547 # 0 +0xF764 0xE548 # 0 +0xF765 0xE549 # 0 +0xF766 0xE54A # 0 +0xF767 0xE54B # 0 +0xF768 0xE54C # 0 +0xF769 0xE54D # 0 +0xF76A 0xE54E # 0 +0xF76B 0xE54F # 0 +0xF76C 0xE550 # 0 +0xF76D 0xE551 # 0 +0xF76E 0xE552 # 0 +0xF76F 0xE553 # 0 +0xF770 0xE554 # 0 +0xF771 0xE555 # 0 +0xF772 0xE556 # 0 +0xF773 0xE557 # 0 +0xF774 0xE558 # 0 +0xF775 0xE559 # 0 +0xF776 0xE55A # 0 +0xF777 0xE55B # 0 +0xF778 0xE55C # 0 +0xF779 0xE55D # 0 +0xF77A 0xE55E # 0 +0xF77B 0xE55F # 0 +0xF77C 0xE560 # 0 +0xF77D 0xE561 # 0 +0xF77E 0xE562 # 0 +0xF780 0xE563 # 0 +0xF781 0xE564 # 0 +0xF782 0xE565 # 0 +0xF783 0xE566 # 0 +0xF784 0xE567 # 0 +0xF785 0xE568 # 0 +0xF786 0xE569 # 0 +0xF787 0xE56A # 0 +0xF788 0xE56B # 0 +0xF789 0xE56C # 0 +0xF78A 0xE56D # 0 +0xF78B 0xE56E # 0 +0xF78C 0xE56F # 0 +0xF78D 0xE570 # 0 +0xF78E 0xE571 # 0 +0xF78F 0xE572 # 0 +0xF790 0xE573 # 0 +0xF791 0xE574 # 0 +0xF792 0xE575 # 0 +0xF793 0xE576 # 0 +0xF794 0xE577 # 0 +0xF795 0xE578 # 0 +0xF796 0xE579 # 0 +0xF797 0xE57A # 0 +0xF798 0xE57B # 0 +0xF799 0xE57C # 0 +0xF79A 0xE57D # 0 +0xF79B 0xE57E # 0 +0xF79C 0xE57F # 0 +0xF79D 0xE580 # 0 +0xF79E 0xE581 # 0 +0xF79F 0xE582 # 0 +0xF7A0 0xE583 # 0 +0xF7A1 0xE584 # 0 +0xF7A2 0xE585 # 0 +0xF7A3 0xE586 # 0 +0xF7A4 0xE587 # 0 +0xF7A5 0xE588 # 0 +0xF7A6 0xE589 # 0 +0xF7A7 0xE58A # 0 +0xF7A8 0xE58B # 0 +0xF7A9 0xE58C # 0 +0xF7AA 0xE58D # 0 +0xF7AB 0xE58E # 0 +0xF7AC 0xE58F # 0 +0xF7AD 0xE590 # 0 +0xF7AE 0xE591 # 0 +0xF7AF 0xE592 # 0 +0xF7B0 0xE593 # 0 +0xF7B1 0xE594 # 0 +0xF7B2 0xE595 # 0 +0xF7B3 0xE596 # 0 +0xF7B4 0xE597 # 0 +0xF7B5 0xE598 # 0 +0xF7B6 0xE599 # 0 +0xF7B7 0xE59A # 0 +0xF7B8 0xE59B # 0 +0xF7B9 0xE59C # 0 +0xF7BA 0xE59D # 0 +0xF7BB 0xE59E # 0 +0xF7BC 0xE59F # 0 +0xF7BD 0xE5A0 # 0 +0xF7BE 0xE5A1 # 0 +0xF7BF 0xE5A2 # 0 +0xF7C0 0xE5A3 # 0 +0xF7C1 0xE5A4 # 0 +0xF7C2 0xE5A5 # 0 +0xF7C3 0xE5A6 # 0 +0xF7C4 0xE5A7 # 0 +0xF7C5 0xE5A8 # 0 +0xF7C6 0xE5A9 # 0 +0xF7C7 0xE5AA # 0 +0xF7C8 0xE5AB # 0 +0xF7C9 0xE5AC # 0 +0xF7CA 0xE5AD # 0 +0xF7CB 0xE5AE # 0 +0xF7CC 0xE5AF # 0 +0xF7CD 0xE5B0 # 0 +0xF7CE 0xE5B1 # 0 +0xF7CF 0xE5B2 # 0 +0xF7D0 0xE5B3 # 0 +0xF7D1 0xE5B4 # 0 +0xF7D2 0xE5B5 # 0 +0xF7D3 0xE5B6 # 0 +0xF7D4 0xE5B7 # 0 +0xF7D5 0xE5B8 # 0 +0xF7D6 0xE5B9 # 0 +0xF7D7 0xE5BA # 0 +0xF7D8 0xE5BB # 0 +0xF7D9 0xE5BC # 0 +0xF7DA 0xE5BD # 0 +0xF7DB 0xE5BE # 0 +0xF7DC 0xE5BF # 0 +0xF7DD 0xE5C0 # 0 +0xF7DE 0xE5C1 # 0 +0xF7DF 0xE5C2 # 0 +0xF7E0 0xE5C3 # 0 +0xF7E1 0xE5C4 # 0 +0xF7E2 0xE5C5 # 0 +0xF7E3 0xE5C6 # 0 +0xF7E4 0xE5C7 # 0 +0xF7E5 0xE5C8 # 0 +0xF7E6 0xE5C9 # 0 +0xF7E7 0xE5CA # 0 +0xF7E8 0xE5CB # 0 +0xF7E9 0xE5CC # 0 +0xF7EA 0xE5CD # 0 +0xF7EB 0xE5CE # 0 +0xF7EC 0xE5CF # 0 +0xF7ED 0xE5D0 # 0 +0xF7EE 0xE5D1 # 0 +0xF7EF 0xE5D2 # 0 +0xF7F0 0xE5D3 # 0 +0xF7F1 0xE5D4 # 0 +0xF7F2 0xE5D5 # 0 +0xF7F3 0xE5D6 # 0 +0xF7F4 0xE5D7 # 0 +0xF7F5 0xE5D8 # 0 +0xF7F6 0xE5D9 # 0 +0xF7F7 0xE5DA # 0 +0xF7F8 0xE5DB # 0 +0xF7F9 0xE5DC # 0 +0xF7FA 0xE5DD # 0 +0xF7FB 0xE5DE # 0 +0xF7FC 0xE5DF # 0 +0xF840 0xE5E0 # 0 +0xF841 0xE5E1 # 0 +0xF842 0xE5E2 # 0 +0xF843 0xE5E3 # 0 +0xF844 0xE5E4 # 0 +0xF845 0xE5E5 # 0 +0xF846 0xE5E6 # 0 +0xF847 0xE5E7 # 0 +0xF848 0xE5E8 # 0 +0xF849 0xE5E9 # 0 +0xF84A 0xE5EA # 0 +0xF84B 0xE5EB # 0 +0xF84C 0xE5EC # 0 +0xF84D 0xE5ED # 0 +0xF84E 0xE5EE # 0 +0xF84F 0xE5EF # 0 +0xF850 0xE5F0 # 0 +0xF851 0xE5F1 # 0 +0xF852 0xE5F2 # 0 +0xF853 0xE5F3 # 0 +0xF854 0xE5F4 # 0 +0xF855 0xE5F5 # 0 +0xF856 0xE5F6 # 0 +0xF857 0xE5F7 # 0 +0xF858 0xE5F8 # 0 +0xF859 0xE5F9 # 0 +0xF85A 0xE5FA # 0 +0xF85B 0xE5FB # 0 +0xF85C 0xE5FC # 0 +0xF85D 0xE5FD # 0 +0xF85E 0xE5FE # 0 +0xF85F 0xE5FF # 0 +0xF860 0xE600 # 0 +0xF861 0xE601 # 0 +0xF862 0xE602 # 0 +0xF863 0xE603 # 0 +0xF864 0xE604 # 0 +0xF865 0xE605 # 0 +0xF866 0xE606 # 0 +0xF867 0xE607 # 0 +0xF868 0xE608 # 0 +0xF869 0xE609 # 0 +0xF86A 0xE60A # 0 +0xF86B 0xE60B # 0 +0xF86C 0xE60C # 0 +0xF86D 0xE60D # 0 +0xF86E 0xE60E # 0 +0xF86F 0xE60F # 0 +0xF870 0xE610 # 0 +0xF871 0xE611 # 0 +0xF872 0xE612 # 0 +0xF873 0xE613 # 0 +0xF874 0xE614 # 0 +0xF875 0xE615 # 0 +0xF876 0xE616 # 0 +0xF877 0xE617 # 0 +0xF878 0xE618 # 0 +0xF879 0xE619 # 0 +0xF87A 0xE61A # 0 +0xF87B 0xE61B # 0 +0xF87C 0xE61C # 0 +0xF87D 0xE61D # 0 +0xF87E 0xE61E # 0 +0xF880 0xE61F # 0 +0xF881 0xE620 # 0 +0xF882 0xE621 # 0 +0xF883 0xE622 # 0 +0xF884 0xE623 # 0 +0xF885 0xE624 # 0 +0xF886 0xE625 # 0 +0xF887 0xE626 # 0 +0xF888 0xE627 # 0 +0xF889 0xE628 # 0 +0xF88A 0xE629 # 0 +0xF88B 0xE62A # 0 +0xF88C 0xE62B # 0 +0xF88D 0xE62C # 0 +0xF88E 0xE62D # 0 +0xF88F 0xE62E # 0 +0xF890 0xE62F # 0 +0xF891 0xE630 # 0 +0xF892 0xE631 # 0 +0xF893 0xE632 # 0 +0xF894 0xE633 # 0 +0xF895 0xE634 # 0 +0xF896 0xE635 # 0 +0xF897 0xE636 # 0 +0xF898 0xE637 # 0 +0xF899 0xE638 # 0 +0xF89A 0xE639 # 0 +0xF89B 0xE63A # 0 +0xF89C 0xE63B # 0 +0xF89D 0xE63C # 0 +0xF89E 0xE63D # 0 +0xF89F 0xE63E # 0 +0xF8A0 0xE63F # 0 +0xF8A1 0xE640 # 0 +0xF8A2 0xE641 # 0 +0xF8A3 0xE642 # 0 +0xF8A4 0xE643 # 0 +0xF8A5 0xE644 # 0 +0xF8A6 0xE645 # 0 +0xF8A7 0xE646 # 0 +0xF8A8 0xE647 # 0 +0xF8A9 0xE648 # 0 +0xF8AA 0xE649 # 0 +0xF8AB 0xE64A # 0 +0xF8AC 0xE64B # 0 +0xF8AD 0xE64C # 0 +0xF8AE 0xE64D # 0 +0xF8AF 0xE64E # 0 +0xF8B0 0xE64F # 0 +0xF8B1 0xE650 # 0 +0xF8B2 0xE651 # 0 +0xF8B3 0xE652 # 0 +0xF8B4 0xE653 # 0 +0xF8B5 0xE654 # 0 +0xF8B6 0xE655 # 0 +0xF8B7 0xE656 # 0 +0xF8B8 0xE657 # 0 +0xF8B9 0xE658 # 0 +0xF8BA 0xE659 # 0 +0xF8BB 0xE65A # 0 +0xF8BC 0xE65B # 0 +0xF8BD 0xE65C # 0 +0xF8BE 0xE65D # 0 +0xF8BF 0xE65E # 0 +0xF8C0 0xE65F # 0 +0xF8C1 0xE660 # 0 +0xF8C2 0xE661 # 0 +0xF8C3 0xE662 # 0 +0xF8C4 0xE663 # 0 +0xF8C5 0xE664 # 0 +0xF8C6 0xE665 # 0 +0xF8C7 0xE666 # 0 +0xF8C8 0xE667 # 0 +0xF8C9 0xE668 # 0 +0xF8CA 0xE669 # 0 +0xF8CB 0xE66A # 0 +0xF8CC 0xE66B # 0 +0xF8CD 0xE66C # 0 +0xF8CE 0xE66D # 0 +0xF8CF 0xE66E # 0 +0xF8D0 0xE66F # 0 +0xF8D1 0xE670 # 0 +0xF8D2 0xE671 # 0 +0xF8D3 0xE672 # 0 +0xF8D4 0xE673 # 0 +0xF8D5 0xE674 # 0 +0xF8D6 0xE675 # 0 +0xF8D7 0xE676 # 0 +0xF8D8 0xE677 # 0 +0xF8D9 0xE678 # 0 +0xF8DA 0xE679 # 0 +0xF8DB 0xE67A # 0 +0xF8DC 0xE67B # 0 +0xF8DD 0xE67C # 0 +0xF8DE 0xE67D # 0 +0xF8DF 0xE67E # 0 +0xF8E0 0xE67F # 0 +0xF8E1 0xE680 # 0 +0xF8E2 0xE681 # 0 +0xF8E3 0xE682 # 0 +0xF8E4 0xE683 # 0 +0xF8E5 0xE684 # 0 +0xF8E6 0xE685 # 0 +0xF8E7 0xE686 # 0 +0xF8E8 0xE687 # 0 +0xF8E9 0xE688 # 0 +0xF8EA 0xE689 # 0 +0xF8EB 0xE68A # 0 +0xF8EC 0xE68B # 0 +0xF8ED 0xE68C # 0 +0xF8EE 0xE68D # 0 +0xF8EF 0xE68E # 0 +0xF8F0 0xE68F # 0 +0xF8F1 0xE690 # 0 +0xF8F2 0xE691 # 0 +0xF8F3 0xE692 # 0 +0xF8F4 0xE693 # 0 +0xF8F5 0xE694 # 0 +0xF8F6 0xE695 # 0 +0xF8F7 0xE696 # 0 +0xF8F8 0xE697 # 0 +0xF8F9 0xE698 # 0 +0xF8FA 0xE699 # 0 +0xF8FB 0xE69A # 0 +0xF8FC 0xE69B # 0 +0xF940 0xE69C # 0 +0xF941 0xE69D # 0 +0xF942 0xE69E # 0 +0xF943 0xE69F # 0 +0xF944 0xE6A0 # 0 +0xF945 0xE6A1 # 0 +0xF946 0xE6A2 # 0 +0xF947 0xE6A3 # 0 +0xF948 0xE6A4 # 0 +0xF949 0xE6A5 # 0 +0xF94A 0xE6A6 # 0 +0xF94B 0xE6A7 # 0 +0xF94C 0xE6A8 # 0 +0xF94D 0xE6A9 # 0 +0xF94E 0xE6AA # 0 +0xF94F 0xE6AB # 0 +0xF950 0xE6AC # 0 +0xF951 0xE6AD # 0 +0xF952 0xE6AE # 0 +0xF953 0xE6AF # 0 +0xF954 0xE6B0 # 0 +0xF955 0xE6B1 # 0 +0xF956 0xE6B2 # 0 +0xF957 0xE6B3 # 0 +0xF958 0xE6B4 # 0 +0xF959 0xE6B5 # 0 +0xF95A 0xE6B6 # 0 +0xF95B 0xE6B7 # 0 +0xF95C 0xE6B8 # 0 +0xF95D 0xE6B9 # 0 +0xF95E 0xE6BA # 0 +0xF95F 0xE6BB # 0 +0xF960 0xE6BC # 0 +0xF961 0xE6BD # 0 +0xF962 0xE6BE # 0 +0xF963 0xE6BF # 0 +0xF964 0xE6C0 # 0 +0xF965 0xE6C1 # 0 +0xF966 0xE6C2 # 0 +0xF967 0xE6C3 # 0 +0xF968 0xE6C4 # 0 +0xF969 0xE6C5 # 0 +0xF96A 0xE6C6 # 0 +0xF96B 0xE6C7 # 0 +0xF96C 0xE6C8 # 0 +0xF96D 0xE6C9 # 0 +0xF96E 0xE6CA # 0 +0xF96F 0xE6CB # 0 +0xF970 0xE6CC # 0 +0xF971 0xE6CD # 0 +0xF972 0xE6CE # 0 +0xF973 0xE6CF # 0 +0xF974 0xE6D0 # 0 +0xF975 0xE6D1 # 0 +0xF976 0xE6D2 # 0 +0xF977 0xE6D3 # 0 +0xF978 0xE6D4 # 0 +0xF979 0xE6D5 # 0 +0xF97A 0xE6D6 # 0 +0xF97B 0xE6D7 # 0 +0xF97C 0xE6D8 # 0 +0xF97D 0xE6D9 # 0 +0xF97E 0xE6DA # 0 +0xF980 0xE6DB # 0 +0xF981 0xE6DC # 0 +0xF982 0xE6DD # 0 +0xF983 0xE6DE # 0 +0xF984 0xE6DF # 0 +0xF985 0xE6E0 # 0 +0xF986 0xE6E1 # 0 +0xF987 0xE6E2 # 0 +0xF988 0xE6E3 # 0 +0xF989 0xE6E4 # 0 +0xF98A 0xE6E5 # 0 +0xF98B 0xE6E6 # 0 +0xF98C 0xE6E7 # 0 +0xF98D 0xE6E8 # 0 +0xF98E 0xE6E9 # 0 +0xF98F 0xE6EA # 0 +0xF990 0xE6EB # 0 +0xF991 0xE6EC # 0 +0xF992 0xE6ED # 0 +0xF993 0xE6EE # 0 +0xF994 0xE6EF # 0 +0xF995 0xE6F0 # 0 +0xF996 0xE6F1 # 0 +0xF997 0xE6F2 # 0 +0xF998 0xE6F3 # 0 +0xF999 0xE6F4 # 0 +0xF99A 0xE6F5 # 0 +0xF99B 0xE6F6 # 0 +0xF99C 0xE6F7 # 0 +0xF99D 0xE6F8 # 0 +0xF99E 0xE6F9 # 0 +0xF99F 0xE6FA # 0 +0xF9A0 0xE6FB # 0 +0xF9A1 0xE6FC # 0 +0xF9A2 0xE6FD # 0 +0xF9A3 0xE6FE # 0 +0xF9A4 0xE6FF # 0 +0xF9A5 0xE700 # 0 +0xF9A6 0xE701 # 0 +0xF9A7 0xE702 # 0 +0xF9A8 0xE703 # 0 +0xF9A9 0xE704 # 0 +0xF9AA 0xE705 # 0 +0xF9AB 0xE706 # 0 +0xF9AC 0xE707 # 0 +0xF9AD 0xE708 # 0 +0xF9AE 0xE709 # 0 +0xF9AF 0xE70A # 0 +0xF9B0 0xE70B # 0 +0xF9B1 0xE70C # 0 +0xF9B2 0xE70D # 0 +0xF9B3 0xE70E # 0 +0xF9B4 0xE70F # 0 +0xF9B5 0xE710 # 0 +0xF9B6 0xE711 # 0 +0xF9B7 0xE712 # 0 +0xF9B8 0xE713 # 0 +0xF9B9 0xE714 # 0 +0xF9BA 0xE715 # 0 +0xF9BB 0xE716 # 0 +0xF9BC 0xE717 # 0 +0xF9BD 0xE718 # 0 +0xF9BE 0xE719 # 0 +0xF9BF 0xE71A # 0 +0xF9C0 0xE71B # 0 +0xF9C1 0xE71C # 0 +0xF9C2 0xE71D # 0 +0xF9C3 0xE71E # 0 +0xF9C4 0xE71F # 0 +0xF9C5 0xE720 # 0 +0xF9C6 0xE721 # 0 +0xF9C7 0xE722 # 0 +0xF9C8 0xE723 # 0 +0xF9C9 0xE724 # 0 +0xF9CA 0xE725 # 0 +0xF9CB 0xE726 # 0 +0xF9CC 0xE727 # 0 +0xF9CD 0xE728 # 0 +0xF9CE 0xE729 # 0 +0xF9CF 0xE72A # 0 +0xF9D0 0xE72B # 0 +0xF9D1 0xE72C # 0 +0xF9D2 0xE72D # 0 +0xF9D3 0xE72E # 0 +0xF9D4 0xE72F # 0 +0xF9D5 0xE730 # 0 +0xF9D6 0xE731 # 0 +0xF9D7 0xE732 # 0 +0xF9D8 0xE733 # 0 +0xF9D9 0xE734 # 0 +0xF9DA 0xE735 # 0 +0xF9DB 0xE736 # 0 +0xF9DC 0xE737 # 0 +0xF9DD 0xE738 # 0 +0xF9DE 0xE739 # 0 +0xF9DF 0xE73A # 0 +0xF9E0 0xE73B # 0 +0xF9E1 0xE73C # 0 +0xF9E2 0xE73D # 0 +0xF9E3 0xE73E # 0 +0xF9E4 0xE73F # 0 +0xF9E5 0xE740 # 0 +0xF9E6 0xE741 # 0 +0xF9E7 0xE742 # 0 +0xF9E8 0xE743 # 0 +0xF9E9 0xE744 # 0 +0xF9EA 0xE745 # 0 +0xF9EB 0xE746 # 0 +0xF9EC 0xE747 # 0 +0xF9ED 0xE748 # 0 +0xF9EE 0xE749 # 0 +0xF9EF 0xE74A # 0 +0xF9F0 0xE74B # 0 +0xF9F1 0xE74C # 0 +0xF9F2 0xE74D # 0 +0xF9F3 0xE74E # 0 +0xF9F4 0xE74F # 0 +0xF9F5 0xE750 # 0 +0xF9F6 0xE751 # 0 +0xF9F7 0xE752 # 0 +0xF9F8 0xE753 # 0 +0xF9F9 0xE754 # 0 +0xF9FA 0xE755 # 0 +0xF9FB 0xE756 # 0 +0xF9FC 0xE757 # 0 +0xFA40 0x2170 # 0 +0xFA41 0x2171 # 0 +0xFA42 0x2172 # 0 +0xFA43 0x2173 # 0 +0xFA44 0x2174 # 0 +0xFA45 0x2175 # 0 +0xFA46 0x2176 # 0 +0xFA47 0x2177 # 0 +0xFA48 0x2178 # 0 +0xFA49 0x2179 # 0 +0xFA55 0xFFE4 # 0 +0xFA56 0xFF07 # 0 +0xFA57 0xFF02 # 0 +0xFA5C 0x7E8A # 0 +0xFA5D 0x891C # 0 +0xFA5E 0x9348 # 0 +0xFA5F 0x9288 # 0 +0xFA60 0x84DC # 0 +0xFA61 0x4FC9 # 0 +0xFA62 0x70BB # 0 +0xFA63 0x6631 # 0 +0xFA64 0x68C8 # 0 +0xFA65 0x92F9 # 0 +0xFA66 0x66FB # 0 +0xFA67 0x5F45 # 0 +0xFA68 0x4E28 # 0 +0xFA69 0x4EE1 # 0 +0xFA6A 0x4EFC # 0 +0xFA6B 0x4F00 # 0 +0xFA6C 0x4F03 # 0 +0xFA6D 0x4F39 # 0 +0xFA6E 0x4F56 # 0 +0xFA6F 0x4F92 # 0 +0xFA70 0x4F8A # 0 +0xFA71 0x4F9A # 0 +0xFA72 0x4F94 # 0 +0xFA73 0x4FCD # 0 +0xFA74 0x5040 # 0 +0xFA75 0x5022 # 0 +0xFA76 0x4FFF # 0 +0xFA77 0x501E # 0 +0xFA78 0x5046 # 0 +0xFA79 0x5070 # 0 +0xFA7A 0x5042 # 0 +0xFA7B 0x5094 # 0 +0xFA7C 0x50F4 # 0 +0xFA7D 0x50D8 # 0 +0xFA7E 0x514A # 0 +0xFA80 0x5164 # 0 +0xFA81 0x519D # 0 +0xFA82 0x51BE # 0 +0xFA83 0x51EC # 0 +0xFA84 0x5215 # 0 +0xFA85 0x529C # 0 +0xFA86 0x52A6 # 0 +0xFA87 0x52C0 # 0 +0xFA88 0x52DB # 0 +0xFA89 0x5300 # 0 +0xFA8A 0x5307 # 0 +0xFA8B 0x5324 # 0 +0xFA8C 0x5372 # 0 +0xFA8D 0x5393 # 0 +0xFA8E 0x53B2 # 0 +0xFA8F 0x53DD # 0 +0xFA90 0xFA0E # 0 +0xFA91 0x549C # 0 +0xFA92 0x548A # 0 +0xFA93 0x54A9 # 0 +0xFA94 0x54FF # 0 +0xFA95 0x5586 # 0 +0xFA96 0x5759 # 0 +0xFA97 0x5765 # 0 +0xFA98 0x57AC # 0 +0xFA99 0x57C8 # 0 +0xFA9A 0x57C7 # 0 +0xFA9B 0xFA0F # 0 +0xFA9C 0xFA10 # 0 +0xFA9D 0x589E # 0 +0xFA9E 0x58B2 # 0 +0xFA9F 0x590B # 0 +0xFAA0 0x5953 # 0 +0xFAA1 0x595B # 0 +0xFAA2 0x595D # 0 +0xFAA3 0x5963 # 0 +0xFAA4 0x59A4 # 0 +0xFAA5 0x59BA # 0 +0xFAA6 0x5B56 # 0 +0xFAA7 0x5BC0 # 0 +0xFAA8 0x752F # 0 +0xFAA9 0x5BD8 # 0 +0xFAAA 0x5BEC # 0 +0xFAAB 0x5C1E # 0 +0xFAAC 0x5CA6 # 0 +0xFAAD 0x5CBA # 0 +0xFAAE 0x5CF5 # 0 +0xFAAF 0x5D27 # 0 +0xFAB0 0x5D53 # 0 +0xFAB1 0xFA11 # 0 +0xFAB2 0x5D42 # 0 +0xFAB3 0x5D6D # 0 +0xFAB4 0x5DB8 # 0 +0xFAB5 0x5DB9 # 0 +0xFAB6 0x5DD0 # 0 +0xFAB7 0x5F21 # 0 +0xFAB8 0x5F34 # 0 +0xFAB9 0x5F67 # 0 +0xFABA 0x5FB7 # 0 +0xFABB 0x5FDE # 0 +0xFABC 0x605D # 0 +0xFABD 0x6085 # 0 +0xFABE 0x608A # 0 +0xFABF 0x60DE # 0 +0xFAC0 0x60D5 # 0 +0xFAC1 0x6120 # 0 +0xFAC2 0x60F2 # 0 +0xFAC3 0x6111 # 0 +0xFAC4 0x6137 # 0 +0xFAC5 0x6130 # 0 +0xFAC6 0x6198 # 0 +0xFAC7 0x6213 # 0 +0xFAC8 0x62A6 # 0 +0xFAC9 0x63F5 # 0 +0xFACA 0x6460 # 0 +0xFACB 0x649D # 0 +0xFACC 0x64CE # 0 +0xFACD 0x654E # 0 +0xFACE 0x6600 # 0 +0xFACF 0x6615 # 0 +0xFAD0 0x663B # 0 +0xFAD1 0x6609 # 0 +0xFAD2 0x662E # 0 +0xFAD3 0x661E # 0 +0xFAD4 0x6624 # 0 +0xFAD5 0x6665 # 0 +0xFAD6 0x6657 # 0 +0xFAD7 0x6659 # 0 +0xFAD8 0xFA12 # 0 +0xFAD9 0x6673 # 0 +0xFADA 0x6699 # 0 +0xFADB 0x66A0 # 0 +0xFADC 0x66B2 # 0 +0xFADD 0x66BF # 0 +0xFADE 0x66FA # 0 +0xFADF 0x670E # 0 +0xFAE0 0xF929 # 0 +0xFAE1 0x6766 # 0 +0xFAE2 0x67BB # 0 +0xFAE3 0x6852 # 0 +0xFAE4 0x67C0 # 0 +0xFAE5 0x6801 # 0 +0xFAE6 0x6844 # 0 +0xFAE7 0x68CF # 0 +0xFAE8 0xFA13 # 0 +0xFAE9 0x6968 # 0 +0xFAEA 0xFA14 # 0 +0xFAEB 0x6998 # 0 +0xFAEC 0x69E2 # 0 +0xFAED 0x6A30 # 0 +0xFAEE 0x6A6B # 0 +0xFAEF 0x6A46 # 0 +0xFAF0 0x6A73 # 0 +0xFAF1 0x6A7E # 0 +0xFAF2 0x6AE2 # 0 +0xFAF3 0x6AE4 # 0 +0xFAF4 0x6BD6 # 0 +0xFAF5 0x6C3F # 0 +0xFAF6 0x6C5C # 0 +0xFAF7 0x6C86 # 0 +0xFAF8 0x6C6F # 0 +0xFAF9 0x6CDA # 0 +0xFAFA 0x6D04 # 0 +0xFAFB 0x6D87 # 0 +0xFAFC 0x6D6F # 0 +0xFB40 0x6D96 # 0 +0xFB41 0x6DAC # 0 +0xFB42 0x6DCF # 0 +0xFB43 0x6DF8 # 0 +0xFB44 0x6DF2 # 0 +0xFB45 0x6DFC # 0 +0xFB46 0x6E39 # 0 +0xFB47 0x6E5C # 0 +0xFB48 0x6E27 # 0 +0xFB49 0x6E3C # 0 +0xFB4A 0x6EBF # 0 +0xFB4B 0x6F88 # 0 +0xFB4C 0x6FB5 # 0 +0xFB4D 0x6FF5 # 0 +0xFB4E 0x7005 # 0 +0xFB4F 0x7007 # 0 +0xFB50 0x7028 # 0 +0xFB51 0x7085 # 0 +0xFB52 0x70AB # 0 +0xFB53 0x710F # 0 +0xFB54 0x7104 # 0 +0xFB55 0x715C # 0 +0xFB56 0x7146 # 0 +0xFB57 0x7147 # 0 +0xFB58 0xFA15 # 0 +0xFB59 0x71C1 # 0 +0xFB5A 0x71FE # 0 +0xFB5B 0x72B1 # 0 +0xFB5C 0x72BE # 0 +0xFB5D 0x7324 # 0 +0xFB5E 0xFA16 # 0 +0xFB5F 0x7377 # 0 +0xFB60 0x73BD # 0 +0xFB61 0x73C9 # 0 +0xFB62 0x73D6 # 0 +0xFB63 0x73E3 # 0 +0xFB64 0x73D2 # 0 +0xFB65 0x7407 # 0 +0xFB66 0x73F5 # 0 +0xFB67 0x7426 # 0 +0xFB68 0x742A # 0 +0xFB69 0x7429 # 0 +0xFB6A 0x742E # 0 +0xFB6B 0x7462 # 0 +0xFB6C 0x7489 # 0 +0xFB6D 0x749F # 0 +0xFB6E 0x7501 # 0 +0xFB6F 0x756F # 0 +0xFB70 0x7682 # 0 +0xFB71 0x769C # 0 +0xFB72 0x769E # 0 +0xFB73 0x769B # 0 +0xFB74 0x76A6 # 0 +0xFB75 0xFA17 # 0 +0xFB76 0x7746 # 0 +0xFB77 0x52AF # 0 +0xFB78 0x7821 # 0 +0xFB79 0x784E # 0 +0xFB7A 0x7864 # 0 +0xFB7B 0x787A # 0 +0xFB7C 0x7930 # 0 +0xFB7D 0xFA18 # 0 +0xFB7E 0xFA19 # 0 +0xFB80 0xFA1A # 0 +0xFB81 0x7994 # 0 +0xFB82 0xFA1B # 0 +0xFB83 0x799B # 0 +0xFB84 0x7AD1 # 0 +0xFB85 0x7AE7 # 0 +0xFB86 0xFA1C # 0 +0xFB87 0x7AEB # 0 +0xFB88 0x7B9E # 0 +0xFB89 0xFA1D # 0 +0xFB8A 0x7D48 # 0 +0xFB8B 0x7D5C # 0 +0xFB8C 0x7DB7 # 0 +0xFB8D 0x7DA0 # 0 +0xFB8E 0x7DD6 # 0 +0xFB8F 0x7E52 # 0 +0xFB90 0x7F47 # 0 +0xFB91 0x7FA1 # 0 +0xFB92 0xFA1E # 0 +0xFB93 0x8301 # 0 +0xFB94 0x8362 # 0 +0xFB95 0x837F # 0 +0xFB96 0x83C7 # 0 +0xFB97 0x83F6 # 0 +0xFB98 0x8448 # 0 +0xFB99 0x84B4 # 0 +0xFB9A 0x8553 # 0 +0xFB9B 0x8559 # 0 +0xFB9C 0x856B # 0 +0xFB9D 0xFA1F # 0 +0xFB9E 0x85B0 # 0 +0xFB9F 0xFA20 # 0 +0xFBA0 0xFA21 # 0 +0xFBA1 0x8807 # 0 +0xFBA2 0x88F5 # 0 +0xFBA3 0x8A12 # 0 +0xFBA4 0x8A37 # 0 +0xFBA5 0x8A79 # 0 +0xFBA6 0x8AA7 # 0 +0xFBA7 0x8ABE # 0 +0xFBA8 0x8ADF # 0 +0xFBA9 0xFA22 # 0 +0xFBAA 0x8AF6 # 0 +0xFBAB 0x8B53 # 0 +0xFBAC 0x8B7F # 0 +0xFBAD 0x8CF0 # 0 +0xFBAE 0x8CF4 # 0 +0xFBAF 0x8D12 # 0 +0xFBB0 0x8D76 # 0 +0xFBB1 0xFA23 # 0 +0xFBB2 0x8ECF # 0 +0xFBB3 0xFA24 # 0 +0xFBB4 0xFA25 # 0 +0xFBB5 0x9067 # 0 +0xFBB6 0x90DE # 0 +0xFBB7 0xFA26 # 0 +0xFBB8 0x9115 # 0 +0xFBB9 0x9127 # 0 +0xFBBA 0x91DA # 0 +0xFBBB 0x91D7 # 0 +0xFBBC 0x91DE # 0 +0xFBBD 0x91ED # 0 +0xFBBE 0x91EE # 0 +0xFBBF 0x91E4 # 0 +0xFBC0 0x91E5 # 0 +0xFBC1 0x9206 # 0 +0xFBC2 0x9210 # 0 +0xFBC3 0x920A # 0 +0xFBC4 0x923A # 0 +0xFBC5 0x9240 # 0 +0xFBC6 0x923C # 0 +0xFBC7 0x924E # 0 +0xFBC8 0x9259 # 0 +0xFBC9 0x9251 # 0 +0xFBCA 0x9239 # 0 +0xFBCB 0x9267 # 0 +0xFBCC 0x92A7 # 0 +0xFBCD 0x9277 # 0 +0xFBCE 0x9278 # 0 +0xFBCF 0x92E7 # 0 +0xFBD0 0x92D7 # 0 +0xFBD1 0x92D9 # 0 +0xFBD2 0x92D0 # 0 +0xFBD3 0xFA27 # 0 +0xFBD4 0x92D5 # 0 +0xFBD5 0x92E0 # 0 +0xFBD6 0x92D3 # 0 +0xFBD7 0x9325 # 0 +0xFBD8 0x9321 # 0 +0xFBD9 0x92FB # 0 +0xFBDA 0xFA28 # 0 +0xFBDB 0x931E # 0 +0xFBDC 0x92FF # 0 +0xFBDD 0x931D # 0 +0xFBDE 0x9302 # 0 +0xFBDF 0x9370 # 0 +0xFBE0 0x9357 # 0 +0xFBE1 0x93A4 # 0 +0xFBE2 0x93C6 # 0 +0xFBE3 0x93DE # 0 +0xFBE4 0x93F8 # 0 +0xFBE5 0x9431 # 0 +0xFBE6 0x9445 # 0 +0xFBE7 0x9448 # 0 +0xFBE8 0x9592 # 0 +0xFBE9 0xF9DC # 0 +0xFBEA 0xFA29 # 0 +0xFBEB 0x969D # 0 +0xFBEC 0x96AF # 0 +0xFBED 0x9733 # 0 +0xFBEE 0x973B # 0 +0xFBEF 0x9743 # 0 +0xFBF0 0x974D # 0 +0xFBF1 0x974F # 0 +0xFBF2 0x9751 # 0 +0xFBF3 0x9755 # 0 +0xFBF4 0x9857 # 0 +0xFBF5 0x9865 # 0 +0xFBF6 0xFA2A # 0 +0xFBF7 0xFA2B # 0 +0xFBF8 0x9927 # 0 +0xFBF9 0xFA2C # 0 +0xFBFA 0x999E # 0 +0xFBFB 0x9A4E # 0 +0xFBFC 0x9AD9 # 0 +0xFC40 0x9ADC # 0 +0xFC41 0x9B75 # 0 +0xFC42 0x9B72 # 0 +0xFC43 0x9B8F # 0 +0xFC44 0x9BB1 # 0 +0xFC45 0x9BBB # 0 +0xFC46 0x9C00 # 0 +0xFC47 0x9D70 # 0 +0xFC48 0x9D6B # 0 +0xFC49 0xFA2D # 0 +0xFC4A 0x9E19 # 0 +0xFC4B 0x9ED1 # 0 diff --git a/data/windows-936.txt b/data/windows-936.txt new file mode 100644 index 0000000000..2a15482004 --- /dev/null +++ b/data/windows-936.txt @@ -0,0 +1,24071 @@ +# cp936.txt - Legacy to Unicode charmap +0x0000 0x0000 # 0 +0x0001 0x0001 # 0 +0x0002 0x0002 # 0 +0x0003 0x0003 # 0 +0x0004 0x0004 # 0 +0x0005 0x0005 # 0 +0x0006 0x0006 # 0 +0x0007 0x0007 # 0 +0x0008 0x0008 # 0 +0x0009 0x0009 # 0 +0x000A 0x000A # 0 +0x000B 0x000B # 0 +0x000C 0x000C # 0 +0x000D 0x000D # 0 +0x000E 0x000E # 0 +0x000F 0x000F # 0 +0x0010 0x0010 # 0 +0x0011 0x0011 # 0 +0x0012 0x0012 # 0 +0x0013 0x0013 # 0 +0x0014 0x0014 # 0 +0x0015 0x0015 # 0 +0x0016 0x0016 # 0 +0x0017 0x0017 # 0 +0x0018 0x0018 # 0 +0x0019 0x0019 # 0 +0x001A 0x001A # 0 +0x001B 0x001B # 0 +0x001C 0x001C # 0 +0x001D 0x001D # 0 +0x001E 0x001E # 0 +0x001F 0x001F # 0 +0x0020 0x0020 # 0 +0x0021 0x0021 # 0 +0x0022 0x0022 # 0 +0x0023 0x0023 # 0 +0x0024 0x0024 # 0 +0x0025 0x0025 # 0 +0x0026 0x0026 # 0 +0x0027 0x0027 # 0 +0x0028 0x0028 # 0 +0x0029 0x0029 # 0 +0x002A 0x002A # 0 +0x002B 0x002B # 0 +0x002C 0x002C # 0 +0x002D 0x002D # 0 +0x002E 0x002E # 0 +0x002F 0x002F # 0 +0x0030 0x0030 # 0 +0x0031 0x0031 # 0 +0x0032 0x0032 # 0 +0x0033 0x0033 # 0 +0x0034 0x0034 # 0 +0x0035 0x0035 # 0 +0x0036 0x0036 # 0 +0x0037 0x0037 # 0 +0x0038 0x0038 # 0 +0x0039 0x0039 # 0 +0x003A 0x003A # 0 +0x003B 0x003B # 0 +0x003C 0x003C # 0 +0x003D 0x003D # 0 +0x003E 0x003E # 0 +0x003F 0x003F # 0 +0x0040 0x0040 # 0 +0x0041 0x0041 # 0 +0x0042 0x0042 # 0 +0x0043 0x0043 # 0 +0x0044 0x0044 # 0 +0x0045 0x0045 # 0 +0x0046 0x0046 # 0 +0x0047 0x0047 # 0 +0x0048 0x0048 # 0 +0x0049 0x0049 # 0 +0x004A 0x004A # 0 +0x004B 0x004B # 0 +0x004C 0x004C # 0 +0x004D 0x004D # 0 +0x004E 0x004E # 0 +0x004F 0x004F # 0 +0x0050 0x0050 # 0 +0x0051 0x0051 # 0 +0x0052 0x0052 # 0 +0x0053 0x0053 # 0 +0x0054 0x0054 # 0 +0x0055 0x0055 # 0 +0x0056 0x0056 # 0 +0x0057 0x0057 # 0 +0x0058 0x0058 # 0 +0x0059 0x0059 # 0 +0x005A 0x005A # 0 +0x005B 0x005B # 0 +0x005C 0x005C # 0 +0x005D 0x005D # 0 +0x005E 0x005E # 0 +0x005F 0x005F # 0 +0x0060 0x0060 # 0 +0x0061 0x0061 # 0 +0x0062 0x0062 # 0 +0x0063 0x0063 # 0 +0x0064 0x0064 # 0 +0x0065 0x0065 # 0 +0x0066 0x0066 # 0 +0x0067 0x0067 # 0 +0x0068 0x0068 # 0 +0x0069 0x0069 # 0 +0x006A 0x006A # 0 +0x006B 0x006B # 0 +0x006C 0x006C # 0 +0x006D 0x006D # 0 +0x006E 0x006E # 0 +0x006F 0x006F # 0 +0x0070 0x0070 # 0 +0x0071 0x0071 # 0 +0x0072 0x0072 # 0 +0x0073 0x0073 # 0 +0x0074 0x0074 # 0 +0x0075 0x0075 # 0 +0x0076 0x0076 # 0 +0x0077 0x0077 # 0 +0x0078 0x0078 # 0 +0x0079 0x0079 # 0 +0x007A 0x007A # 0 +0x007B 0x007B # 0 +0x007C 0x007C # 0 +0x007D 0x007D # 0 +0x007E 0x007E # 0 +0x007F 0x007F # 0 +0x0080 0x20AC # 0 +0x00FF 0xF8F5 # 0 +0x8140 0x4E02 # 0 +0x8141 0x4E04 # 0 +0x8142 0x4E05 # 0 +0x8143 0x4E06 # 0 +0x8144 0x4E0F # 0 +0x8145 0x4E12 # 0 +0x8146 0x4E17 # 0 +0x8147 0x4E1F # 0 +0x8148 0x4E20 # 0 +0x8149 0x4E21 # 0 +0x814A 0x4E23 # 0 +0x814B 0x4E26 # 0 +0x814C 0x4E29 # 0 +0x814D 0x4E2E # 0 +0x814E 0x4E2F # 0 +0x814F 0x4E31 # 0 +0x8150 0x4E33 # 0 +0x8151 0x4E35 # 0 +0x8152 0x4E37 # 0 +0x8153 0x4E3C # 0 +0x8154 0x4E40 # 0 +0x8155 0x4E41 # 0 +0x8156 0x4E42 # 0 +0x8157 0x4E44 # 0 +0x8158 0x4E46 # 0 +0x8159 0x4E4A # 0 +0x815A 0x4E51 # 0 +0x815B 0x4E55 # 0 +0x815C 0x4E57 # 0 +0x815D 0x4E5A # 0 +0x815E 0x4E5B # 0 +0x815F 0x4E62 # 0 +0x8160 0x4E63 # 0 +0x8161 0x4E64 # 0 +0x8162 0x4E65 # 0 +0x8163 0x4E67 # 0 +0x8164 0x4E68 # 0 +0x8165 0x4E6A # 0 +0x8166 0x4E6B # 0 +0x8167 0x4E6C # 0 +0x8168 0x4E6D # 0 +0x8169 0x4E6E # 0 +0x816A 0x4E6F # 0 +0x816B 0x4E72 # 0 +0x816C 0x4E74 # 0 +0x816D 0x4E75 # 0 +0x816E 0x4E76 # 0 +0x816F 0x4E77 # 0 +0x8170 0x4E78 # 0 +0x8171 0x4E79 # 0 +0x8172 0x4E7A # 0 +0x8173 0x4E7B # 0 +0x8174 0x4E7C # 0 +0x8175 0x4E7D # 0 +0x8176 0x4E7F # 0 +0x8177 0x4E80 # 0 +0x8178 0x4E81 # 0 +0x8179 0x4E82 # 0 +0x817A 0x4E83 # 0 +0x817B 0x4E84 # 0 +0x817C 0x4E85 # 0 +0x817D 0x4E87 # 0 +0x817E 0x4E8A # 0 +0x8180 0x4E90 # 0 +0x8181 0x4E96 # 0 +0x8182 0x4E97 # 0 +0x8183 0x4E99 # 0 +0x8184 0x4E9C # 0 +0x8185 0x4E9D # 0 +0x8186 0x4E9E # 0 +0x8187 0x4EA3 # 0 +0x8188 0x4EAA # 0 +0x8189 0x4EAF # 0 +0x818A 0x4EB0 # 0 +0x818B 0x4EB1 # 0 +0x818C 0x4EB4 # 0 +0x818D 0x4EB6 # 0 +0x818E 0x4EB7 # 0 +0x818F 0x4EB8 # 0 +0x8190 0x4EB9 # 0 +0x8191 0x4EBC # 0 +0x8192 0x4EBD # 0 +0x8193 0x4EBE # 0 +0x8194 0x4EC8 # 0 +0x8195 0x4ECC # 0 +0x8196 0x4ECF # 0 +0x8197 0x4ED0 # 0 +0x8198 0x4ED2 # 0 +0x8199 0x4EDA # 0 +0x819A 0x4EDB # 0 +0x819B 0x4EDC # 0 +0x819C 0x4EE0 # 0 +0x819D 0x4EE2 # 0 +0x819E 0x4EE6 # 0 +0x819F 0x4EE7 # 0 +0x81A0 0x4EE9 # 0 +0x81A1 0x4EED # 0 +0x81A2 0x4EEE # 0 +0x81A3 0x4EEF # 0 +0x81A4 0x4EF1 # 0 +0x81A5 0x4EF4 # 0 +0x81A6 0x4EF8 # 0 +0x81A7 0x4EF9 # 0 +0x81A8 0x4EFA # 0 +0x81A9 0x4EFC # 0 +0x81AA 0x4EFE # 0 +0x81AB 0x4F00 # 0 +0x81AC 0x4F02 # 0 +0x81AD 0x4F03 # 0 +0x81AE 0x4F04 # 0 +0x81AF 0x4F05 # 0 +0x81B0 0x4F06 # 0 +0x81B1 0x4F07 # 0 +0x81B2 0x4F08 # 0 +0x81B3 0x4F0B # 0 +0x81B4 0x4F0C # 0 +0x81B5 0x4F12 # 0 +0x81B6 0x4F13 # 0 +0x81B7 0x4F14 # 0 +0x81B8 0x4F15 # 0 +0x81B9 0x4F16 # 0 +0x81BA 0x4F1C # 0 +0x81BB 0x4F1D # 0 +0x81BC 0x4F21 # 0 +0x81BD 0x4F23 # 0 +0x81BE 0x4F28 # 0 +0x81BF 0x4F29 # 0 +0x81C0 0x4F2C # 0 +0x81C1 0x4F2D # 0 +0x81C2 0x4F2E # 0 +0x81C3 0x4F31 # 0 +0x81C4 0x4F33 # 0 +0x81C5 0x4F35 # 0 +0x81C6 0x4F37 # 0 +0x81C7 0x4F39 # 0 +0x81C8 0x4F3B # 0 +0x81C9 0x4F3E # 0 +0x81CA 0x4F3F # 0 +0x81CB 0x4F40 # 0 +0x81CC 0x4F41 # 0 +0x81CD 0x4F42 # 0 +0x81CE 0x4F44 # 0 +0x81CF 0x4F45 # 0 +0x81D0 0x4F47 # 0 +0x81D1 0x4F48 # 0 +0x81D2 0x4F49 # 0 +0x81D3 0x4F4A # 0 +0x81D4 0x4F4B # 0 +0x81D5 0x4F4C # 0 +0x81D6 0x4F52 # 0 +0x81D7 0x4F54 # 0 +0x81D8 0x4F56 # 0 +0x81D9 0x4F61 # 0 +0x81DA 0x4F62 # 0 +0x81DB 0x4F66 # 0 +0x81DC 0x4F68 # 0 +0x81DD 0x4F6A # 0 +0x81DE 0x4F6B # 0 +0x81DF 0x4F6D # 0 +0x81E0 0x4F6E # 0 +0x81E1 0x4F71 # 0 +0x81E2 0x4F72 # 0 +0x81E3 0x4F75 # 0 +0x81E4 0x4F77 # 0 +0x81E5 0x4F78 # 0 +0x81E6 0x4F79 # 0 +0x81E7 0x4F7A # 0 +0x81E8 0x4F7D # 0 +0x81E9 0x4F80 # 0 +0x81EA 0x4F81 # 0 +0x81EB 0x4F82 # 0 +0x81EC 0x4F85 # 0 +0x81ED 0x4F86 # 0 +0x81EE 0x4F87 # 0 +0x81EF 0x4F8A # 0 +0x81F0 0x4F8C # 0 +0x81F1 0x4F8E # 0 +0x81F2 0x4F90 # 0 +0x81F3 0x4F92 # 0 +0x81F4 0x4F93 # 0 +0x81F5 0x4F95 # 0 +0x81F6 0x4F96 # 0 +0x81F7 0x4F98 # 0 +0x81F8 0x4F99 # 0 +0x81F9 0x4F9A # 0 +0x81FA 0x4F9C # 0 +0x81FB 0x4F9E # 0 +0x81FC 0x4F9F # 0 +0x81FD 0x4FA1 # 0 +0x81FE 0x4FA2 # 0 +0x8240 0x4FA4 # 0 +0x8241 0x4FAB # 0 +0x8242 0x4FAD # 0 +0x8243 0x4FB0 # 0 +0x8244 0x4FB1 # 0 +0x8245 0x4FB2 # 0 +0x8246 0x4FB3 # 0 +0x8247 0x4FB4 # 0 +0x8248 0x4FB6 # 0 +0x8249 0x4FB7 # 0 +0x824A 0x4FB8 # 0 +0x824B 0x4FB9 # 0 +0x824C 0x4FBA # 0 +0x824D 0x4FBB # 0 +0x824E 0x4FBC # 0 +0x824F 0x4FBD # 0 +0x8250 0x4FBE # 0 +0x8251 0x4FC0 # 0 +0x8252 0x4FC1 # 0 +0x8253 0x4FC2 # 0 +0x8254 0x4FC6 # 0 +0x8255 0x4FC7 # 0 +0x8256 0x4FC8 # 0 +0x8257 0x4FC9 # 0 +0x8258 0x4FCB # 0 +0x8259 0x4FCC # 0 +0x825A 0x4FCD # 0 +0x825B 0x4FD2 # 0 +0x825C 0x4FD3 # 0 +0x825D 0x4FD4 # 0 +0x825E 0x4FD5 # 0 +0x825F 0x4FD6 # 0 +0x8260 0x4FD9 # 0 +0x8261 0x4FDB # 0 +0x8262 0x4FE0 # 0 +0x8263 0x4FE2 # 0 +0x8264 0x4FE4 # 0 +0x8265 0x4FE5 # 0 +0x8266 0x4FE7 # 0 +0x8267 0x4FEB # 0 +0x8268 0x4FEC # 0 +0x8269 0x4FF0 # 0 +0x826A 0x4FF2 # 0 +0x826B 0x4FF4 # 0 +0x826C 0x4FF5 # 0 +0x826D 0x4FF6 # 0 +0x826E 0x4FF7 # 0 +0x826F 0x4FF9 # 0 +0x8270 0x4FFB # 0 +0x8271 0x4FFC # 0 +0x8272 0x4FFD # 0 +0x8273 0x4FFF # 0 +0x8274 0x5000 # 0 +0x8275 0x5001 # 0 +0x8276 0x5002 # 0 +0x8277 0x5003 # 0 +0x8278 0x5004 # 0 +0x8279 0x5005 # 0 +0x827A 0x5006 # 0 +0x827B 0x5007 # 0 +0x827C 0x5008 # 0 +0x827D 0x5009 # 0 +0x827E 0x500A # 0 +0x8280 0x500B # 0 +0x8281 0x500E # 0 +0x8282 0x5010 # 0 +0x8283 0x5011 # 0 +0x8284 0x5013 # 0 +0x8285 0x5015 # 0 +0x8286 0x5016 # 0 +0x8287 0x5017 # 0 +0x8288 0x501B # 0 +0x8289 0x501D # 0 +0x828A 0x501E # 0 +0x828B 0x5020 # 0 +0x828C 0x5022 # 0 +0x828D 0x5023 # 0 +0x828E 0x5024 # 0 +0x828F 0x5027 # 0 +0x8290 0x502B # 0 +0x8291 0x502F # 0 +0x8292 0x5030 # 0 +0x8293 0x5031 # 0 +0x8294 0x5032 # 0 +0x8295 0x5033 # 0 +0x8296 0x5034 # 0 +0x8297 0x5035 # 0 +0x8298 0x5036 # 0 +0x8299 0x5037 # 0 +0x829A 0x5038 # 0 +0x829B 0x5039 # 0 +0x829C 0x503B # 0 +0x829D 0x503D # 0 +0x829E 0x503F # 0 +0x829F 0x5040 # 0 +0x82A0 0x5041 # 0 +0x82A1 0x5042 # 0 +0x82A2 0x5044 # 0 +0x82A3 0x5045 # 0 +0x82A4 0x5046 # 0 +0x82A5 0x5049 # 0 +0x82A6 0x504A # 0 +0x82A7 0x504B # 0 +0x82A8 0x504D # 0 +0x82A9 0x5050 # 0 +0x82AA 0x5051 # 0 +0x82AB 0x5052 # 0 +0x82AC 0x5053 # 0 +0x82AD 0x5054 # 0 +0x82AE 0x5056 # 0 +0x82AF 0x5057 # 0 +0x82B0 0x5058 # 0 +0x82B1 0x5059 # 0 +0x82B2 0x505B # 0 +0x82B3 0x505D # 0 +0x82B4 0x505E # 0 +0x82B5 0x505F # 0 +0x82B6 0x5060 # 0 +0x82B7 0x5061 # 0 +0x82B8 0x5062 # 0 +0x82B9 0x5063 # 0 +0x82BA 0x5064 # 0 +0x82BB 0x5066 # 0 +0x82BC 0x5067 # 0 +0x82BD 0x5068 # 0 +0x82BE 0x5069 # 0 +0x82BF 0x506A # 0 +0x82C0 0x506B # 0 +0x82C1 0x506D # 0 +0x82C2 0x506E # 0 +0x82C3 0x506F # 0 +0x82C4 0x5070 # 0 +0x82C5 0x5071 # 0 +0x82C6 0x5072 # 0 +0x82C7 0x5073 # 0 +0x82C8 0x5074 # 0 +0x82C9 0x5075 # 0 +0x82CA 0x5078 # 0 +0x82CB 0x5079 # 0 +0x82CC 0x507A # 0 +0x82CD 0x507C # 0 +0x82CE 0x507D # 0 +0x82CF 0x5081 # 0 +0x82D0 0x5082 # 0 +0x82D1 0x5083 # 0 +0x82D2 0x5084 # 0 +0x82D3 0x5086 # 0 +0x82D4 0x5087 # 0 +0x82D5 0x5089 # 0 +0x82D6 0x508A # 0 +0x82D7 0x508B # 0 +0x82D8 0x508C # 0 +0x82D9 0x508E # 0 +0x82DA 0x508F # 0 +0x82DB 0x5090 # 0 +0x82DC 0x5091 # 0 +0x82DD 0x5092 # 0 +0x82DE 0x5093 # 0 +0x82DF 0x5094 # 0 +0x82E0 0x5095 # 0 +0x82E1 0x5096 # 0 +0x82E2 0x5097 # 0 +0x82E3 0x5098 # 0 +0x82E4 0x5099 # 0 +0x82E5 0x509A # 0 +0x82E6 0x509B # 0 +0x82E7 0x509C # 0 +0x82E8 0x509D # 0 +0x82E9 0x509E # 0 +0x82EA 0x509F # 0 +0x82EB 0x50A0 # 0 +0x82EC 0x50A1 # 0 +0x82ED 0x50A2 # 0 +0x82EE 0x50A4 # 0 +0x82EF 0x50A6 # 0 +0x82F0 0x50AA # 0 +0x82F1 0x50AB # 0 +0x82F2 0x50AD # 0 +0x82F3 0x50AE # 0 +0x82F4 0x50AF # 0 +0x82F5 0x50B0 # 0 +0x82F6 0x50B1 # 0 +0x82F7 0x50B3 # 0 +0x82F8 0x50B4 # 0 +0x82F9 0x50B5 # 0 +0x82FA 0x50B6 # 0 +0x82FB 0x50B7 # 0 +0x82FC 0x50B8 # 0 +0x82FD 0x50B9 # 0 +0x82FE 0x50BC # 0 +0x8340 0x50BD # 0 +0x8341 0x50BE # 0 +0x8342 0x50BF # 0 +0x8343 0x50C0 # 0 +0x8344 0x50C1 # 0 +0x8345 0x50C2 # 0 +0x8346 0x50C3 # 0 +0x8347 0x50C4 # 0 +0x8348 0x50C5 # 0 +0x8349 0x50C6 # 0 +0x834A 0x50C7 # 0 +0x834B 0x50C8 # 0 +0x834C 0x50C9 # 0 +0x834D 0x50CA # 0 +0x834E 0x50CB # 0 +0x834F 0x50CC # 0 +0x8350 0x50CD # 0 +0x8351 0x50CE # 0 +0x8352 0x50D0 # 0 +0x8353 0x50D1 # 0 +0x8354 0x50D2 # 0 +0x8355 0x50D3 # 0 +0x8356 0x50D4 # 0 +0x8357 0x50D5 # 0 +0x8358 0x50D7 # 0 +0x8359 0x50D8 # 0 +0x835A 0x50D9 # 0 +0x835B 0x50DB # 0 +0x835C 0x50DC # 0 +0x835D 0x50DD # 0 +0x835E 0x50DE # 0 +0x835F 0x50DF # 0 +0x8360 0x50E0 # 0 +0x8361 0x50E1 # 0 +0x8362 0x50E2 # 0 +0x8363 0x50E3 # 0 +0x8364 0x50E4 # 0 +0x8365 0x50E5 # 0 +0x8366 0x50E8 # 0 +0x8367 0x50E9 # 0 +0x8368 0x50EA # 0 +0x8369 0x50EB # 0 +0x836A 0x50EF # 0 +0x836B 0x50F0 # 0 +0x836C 0x50F1 # 0 +0x836D 0x50F2 # 0 +0x836E 0x50F4 # 0 +0x836F 0x50F6 # 0 +0x8370 0x50F7 # 0 +0x8371 0x50F8 # 0 +0x8372 0x50F9 # 0 +0x8373 0x50FA # 0 +0x8374 0x50FC # 0 +0x8375 0x50FD # 0 +0x8376 0x50FE # 0 +0x8377 0x50FF # 0 +0x8378 0x5100 # 0 +0x8379 0x5101 # 0 +0x837A 0x5102 # 0 +0x837B 0x5103 # 0 +0x837C 0x5104 # 0 +0x837D 0x5105 # 0 +0x837E 0x5108 # 0 +0x8380 0x5109 # 0 +0x8381 0x510A # 0 +0x8382 0x510C # 0 +0x8383 0x510D # 0 +0x8384 0x510E # 0 +0x8385 0x510F # 0 +0x8386 0x5110 # 0 +0x8387 0x5111 # 0 +0x8388 0x5113 # 0 +0x8389 0x5114 # 0 +0x838A 0x5115 # 0 +0x838B 0x5116 # 0 +0x838C 0x5117 # 0 +0x838D 0x5118 # 0 +0x838E 0x5119 # 0 +0x838F 0x511A # 0 +0x8390 0x511B # 0 +0x8391 0x511C # 0 +0x8392 0x511D # 0 +0x8393 0x511E # 0 +0x8394 0x511F # 0 +0x8395 0x5120 # 0 +0x8396 0x5122 # 0 +0x8397 0x5123 # 0 +0x8398 0x5124 # 0 +0x8399 0x5125 # 0 +0x839A 0x5126 # 0 +0x839B 0x5127 # 0 +0x839C 0x5128 # 0 +0x839D 0x5129 # 0 +0x839E 0x512A # 0 +0x839F 0x512B # 0 +0x83A0 0x512C # 0 +0x83A1 0x512D # 0 +0x83A2 0x512E # 0 +0x83A3 0x512F # 0 +0x83A4 0x5130 # 0 +0x83A5 0x5131 # 0 +0x83A6 0x5132 # 0 +0x83A7 0x5133 # 0 +0x83A8 0x5134 # 0 +0x83A9 0x5135 # 0 +0x83AA 0x5136 # 0 +0x83AB 0x5137 # 0 +0x83AC 0x5138 # 0 +0x83AD 0x5139 # 0 +0x83AE 0x513A # 0 +0x83AF 0x513B # 0 +0x83B0 0x513C # 0 +0x83B1 0x513D # 0 +0x83B2 0x513E # 0 +0x83B3 0x5142 # 0 +0x83B4 0x5147 # 0 +0x83B5 0x514A # 0 +0x83B6 0x514C # 0 +0x83B7 0x514E # 0 +0x83B8 0x514F # 0 +0x83B9 0x5150 # 0 +0x83BA 0x5152 # 0 +0x83BB 0x5153 # 0 +0x83BC 0x5157 # 0 +0x83BD 0x5158 # 0 +0x83BE 0x5159 # 0 +0x83BF 0x515B # 0 +0x83C0 0x515D # 0 +0x83C1 0x515E # 0 +0x83C2 0x515F # 0 +0x83C3 0x5160 # 0 +0x83C4 0x5161 # 0 +0x83C5 0x5163 # 0 +0x83C6 0x5164 # 0 +0x83C7 0x5166 # 0 +0x83C8 0x5167 # 0 +0x83C9 0x5169 # 0 +0x83CA 0x516A # 0 +0x83CB 0x516F # 0 +0x83CC 0x5172 # 0 +0x83CD 0x517A # 0 +0x83CE 0x517E # 0 +0x83CF 0x517F # 0 +0x83D0 0x5183 # 0 +0x83D1 0x5184 # 0 +0x83D2 0x5186 # 0 +0x83D3 0x5187 # 0 +0x83D4 0x518A # 0 +0x83D5 0x518B # 0 +0x83D6 0x518E # 0 +0x83D7 0x518F # 0 +0x83D8 0x5190 # 0 +0x83D9 0x5191 # 0 +0x83DA 0x5193 # 0 +0x83DB 0x5194 # 0 +0x83DC 0x5198 # 0 +0x83DD 0x519A # 0 +0x83DE 0x519D # 0 +0x83DF 0x519E # 0 +0x83E0 0x519F # 0 +0x83E1 0x51A1 # 0 +0x83E2 0x51A3 # 0 +0x83E3 0x51A6 # 0 +0x83E4 0x51A7 # 0 +0x83E5 0x51A8 # 0 +0x83E6 0x51A9 # 0 +0x83E7 0x51AA # 0 +0x83E8 0x51AD # 0 +0x83E9 0x51AE # 0 +0x83EA 0x51B4 # 0 +0x83EB 0x51B8 # 0 +0x83EC 0x51B9 # 0 +0x83ED 0x51BA # 0 +0x83EE 0x51BE # 0 +0x83EF 0x51BF # 0 +0x83F0 0x51C1 # 0 +0x83F1 0x51C2 # 0 +0x83F2 0x51C3 # 0 +0x83F3 0x51C5 # 0 +0x83F4 0x51C8 # 0 +0x83F5 0x51CA # 0 +0x83F6 0x51CD # 0 +0x83F7 0x51CE # 0 +0x83F8 0x51D0 # 0 +0x83F9 0x51D2 # 0 +0x83FA 0x51D3 # 0 +0x83FB 0x51D4 # 0 +0x83FC 0x51D5 # 0 +0x83FD 0x51D6 # 0 +0x83FE 0x51D7 # 0 +0x8440 0x51D8 # 0 +0x8441 0x51D9 # 0 +0x8442 0x51DA # 0 +0x8443 0x51DC # 0 +0x8444 0x51DE # 0 +0x8445 0x51DF # 0 +0x8446 0x51E2 # 0 +0x8447 0x51E3 # 0 +0x8448 0x51E5 # 0 +0x8449 0x51E6 # 0 +0x844A 0x51E7 # 0 +0x844B 0x51E8 # 0 +0x844C 0x51E9 # 0 +0x844D 0x51EA # 0 +0x844E 0x51EC # 0 +0x844F 0x51EE # 0 +0x8450 0x51F1 # 0 +0x8451 0x51F2 # 0 +0x8452 0x51F4 # 0 +0x8453 0x51F7 # 0 +0x8454 0x51FE # 0 +0x8455 0x5204 # 0 +0x8456 0x5205 # 0 +0x8457 0x5209 # 0 +0x8458 0x520B # 0 +0x8459 0x520C # 0 +0x845A 0x520F # 0 +0x845B 0x5210 # 0 +0x845C 0x5213 # 0 +0x845D 0x5214 # 0 +0x845E 0x5215 # 0 +0x845F 0x521C # 0 +0x8460 0x521E # 0 +0x8461 0x521F # 0 +0x8462 0x5221 # 0 +0x8463 0x5222 # 0 +0x8464 0x5223 # 0 +0x8465 0x5225 # 0 +0x8466 0x5226 # 0 +0x8467 0x5227 # 0 +0x8468 0x522A # 0 +0x8469 0x522C # 0 +0x846A 0x522F # 0 +0x846B 0x5231 # 0 +0x846C 0x5232 # 0 +0x846D 0x5234 # 0 +0x846E 0x5235 # 0 +0x846F 0x523C # 0 +0x8470 0x523E # 0 +0x8471 0x5244 # 0 +0x8472 0x5245 # 0 +0x8473 0x5246 # 0 +0x8474 0x5247 # 0 +0x8475 0x5248 # 0 +0x8476 0x5249 # 0 +0x8477 0x524B # 0 +0x8478 0x524E # 0 +0x8479 0x524F # 0 +0x847A 0x5252 # 0 +0x847B 0x5253 # 0 +0x847C 0x5255 # 0 +0x847D 0x5257 # 0 +0x847E 0x5258 # 0 +0x8480 0x5259 # 0 +0x8481 0x525A # 0 +0x8482 0x525B # 0 +0x8483 0x525D # 0 +0x8484 0x525F # 0 +0x8485 0x5260 # 0 +0x8486 0x5262 # 0 +0x8487 0x5263 # 0 +0x8488 0x5264 # 0 +0x8489 0x5266 # 0 +0x848A 0x5268 # 0 +0x848B 0x526B # 0 +0x848C 0x526C # 0 +0x848D 0x526D # 0 +0x848E 0x526E # 0 +0x848F 0x5270 # 0 +0x8490 0x5271 # 0 +0x8491 0x5273 # 0 +0x8492 0x5274 # 0 +0x8493 0x5275 # 0 +0x8494 0x5276 # 0 +0x8495 0x5277 # 0 +0x8496 0x5278 # 0 +0x8497 0x5279 # 0 +0x8498 0x527A # 0 +0x8499 0x527B # 0 +0x849A 0x527C # 0 +0x849B 0x527E # 0 +0x849C 0x5280 # 0 +0x849D 0x5283 # 0 +0x849E 0x5284 # 0 +0x849F 0x5285 # 0 +0x84A0 0x5286 # 0 +0x84A1 0x5287 # 0 +0x84A2 0x5289 # 0 +0x84A3 0x528A # 0 +0x84A4 0x528B # 0 +0x84A5 0x528C # 0 +0x84A6 0x528D # 0 +0x84A7 0x528E # 0 +0x84A8 0x528F # 0 +0x84A9 0x5291 # 0 +0x84AA 0x5292 # 0 +0x84AB 0x5294 # 0 +0x84AC 0x5295 # 0 +0x84AD 0x5296 # 0 +0x84AE 0x5297 # 0 +0x84AF 0x5298 # 0 +0x84B0 0x5299 # 0 +0x84B1 0x529A # 0 +0x84B2 0x529C # 0 +0x84B3 0x52A4 # 0 +0x84B4 0x52A5 # 0 +0x84B5 0x52A6 # 0 +0x84B6 0x52A7 # 0 +0x84B7 0x52AE # 0 +0x84B8 0x52AF # 0 +0x84B9 0x52B0 # 0 +0x84BA 0x52B4 # 0 +0x84BB 0x52B5 # 0 +0x84BC 0x52B6 # 0 +0x84BD 0x52B7 # 0 +0x84BE 0x52B8 # 0 +0x84BF 0x52B9 # 0 +0x84C0 0x52BA # 0 +0x84C1 0x52BB # 0 +0x84C2 0x52BC # 0 +0x84C3 0x52BD # 0 +0x84C4 0x52C0 # 0 +0x84C5 0x52C1 # 0 +0x84C6 0x52C2 # 0 +0x84C7 0x52C4 # 0 +0x84C8 0x52C5 # 0 +0x84C9 0x52C6 # 0 +0x84CA 0x52C8 # 0 +0x84CB 0x52CA # 0 +0x84CC 0x52CC # 0 +0x84CD 0x52CD # 0 +0x84CE 0x52CE # 0 +0x84CF 0x52CF # 0 +0x84D0 0x52D1 # 0 +0x84D1 0x52D3 # 0 +0x84D2 0x52D4 # 0 +0x84D3 0x52D5 # 0 +0x84D4 0x52D7 # 0 +0x84D5 0x52D9 # 0 +0x84D6 0x52DA # 0 +0x84D7 0x52DB # 0 +0x84D8 0x52DC # 0 +0x84D9 0x52DD # 0 +0x84DA 0x52DE # 0 +0x84DB 0x52E0 # 0 +0x84DC 0x52E1 # 0 +0x84DD 0x52E2 # 0 +0x84DE 0x52E3 # 0 +0x84DF 0x52E5 # 0 +0x84E0 0x52E6 # 0 +0x84E1 0x52E7 # 0 +0x84E2 0x52E8 # 0 +0x84E3 0x52E9 # 0 +0x84E4 0x52EA # 0 +0x84E5 0x52EB # 0 +0x84E6 0x52EC # 0 +0x84E7 0x52ED # 0 +0x84E8 0x52EE # 0 +0x84E9 0x52EF # 0 +0x84EA 0x52F1 # 0 +0x84EB 0x52F2 # 0 +0x84EC 0x52F3 # 0 +0x84ED 0x52F4 # 0 +0x84EE 0x52F5 # 0 +0x84EF 0x52F6 # 0 +0x84F0 0x52F7 # 0 +0x84F1 0x52F8 # 0 +0x84F2 0x52FB # 0 +0x84F3 0x52FC # 0 +0x84F4 0x52FD # 0 +0x84F5 0x5301 # 0 +0x84F6 0x5302 # 0 +0x84F7 0x5303 # 0 +0x84F8 0x5304 # 0 +0x84F9 0x5307 # 0 +0x84FA 0x5309 # 0 +0x84FB 0x530A # 0 +0x84FC 0x530B # 0 +0x84FD 0x530C # 0 +0x84FE 0x530E # 0 +0x8540 0x5311 # 0 +0x8541 0x5312 # 0 +0x8542 0x5313 # 0 +0x8543 0x5314 # 0 +0x8544 0x5318 # 0 +0x8545 0x531B # 0 +0x8546 0x531C # 0 +0x8547 0x531E # 0 +0x8548 0x531F # 0 +0x8549 0x5322 # 0 +0x854A 0x5324 # 0 +0x854B 0x5325 # 0 +0x854C 0x5327 # 0 +0x854D 0x5328 # 0 +0x854E 0x5329 # 0 +0x854F 0x532B # 0 +0x8550 0x532C # 0 +0x8551 0x532D # 0 +0x8552 0x532F # 0 +0x8553 0x5330 # 0 +0x8554 0x5331 # 0 +0x8555 0x5332 # 0 +0x8556 0x5333 # 0 +0x8557 0x5334 # 0 +0x8558 0x5335 # 0 +0x8559 0x5336 # 0 +0x855A 0x5337 # 0 +0x855B 0x5338 # 0 +0x855C 0x533C # 0 +0x855D 0x533D # 0 +0x855E 0x5340 # 0 +0x855F 0x5342 # 0 +0x8560 0x5344 # 0 +0x8561 0x5346 # 0 +0x8562 0x534B # 0 +0x8563 0x534C # 0 +0x8564 0x534D # 0 +0x8565 0x5350 # 0 +0x8566 0x5354 # 0 +0x8567 0x5358 # 0 +0x8568 0x5359 # 0 +0x8569 0x535B # 0 +0x856A 0x535D # 0 +0x856B 0x5365 # 0 +0x856C 0x5368 # 0 +0x856D 0x536A # 0 +0x856E 0x536C # 0 +0x856F 0x536D # 0 +0x8570 0x5372 # 0 +0x8571 0x5376 # 0 +0x8572 0x5379 # 0 +0x8573 0x537B # 0 +0x8574 0x537C # 0 +0x8575 0x537D # 0 +0x8576 0x537E # 0 +0x8577 0x5380 # 0 +0x8578 0x5381 # 0 +0x8579 0x5383 # 0 +0x857A 0x5387 # 0 +0x857B 0x5388 # 0 +0x857C 0x538A # 0 +0x857D 0x538E # 0 +0x857E 0x538F # 0 +0x8580 0x5390 # 0 +0x8581 0x5391 # 0 +0x8582 0x5392 # 0 +0x8583 0x5393 # 0 +0x8584 0x5394 # 0 +0x8585 0x5396 # 0 +0x8586 0x5397 # 0 +0x8587 0x5399 # 0 +0x8588 0x539B # 0 +0x8589 0x539C # 0 +0x858A 0x539E # 0 +0x858B 0x53A0 # 0 +0x858C 0x53A1 # 0 +0x858D 0x53A4 # 0 +0x858E 0x53A7 # 0 +0x858F 0x53AA # 0 +0x8590 0x53AB # 0 +0x8591 0x53AC # 0 +0x8592 0x53AD # 0 +0x8593 0x53AF # 0 +0x8594 0x53B0 # 0 +0x8595 0x53B1 # 0 +0x8596 0x53B2 # 0 +0x8597 0x53B3 # 0 +0x8598 0x53B4 # 0 +0x8599 0x53B5 # 0 +0x859A 0x53B7 # 0 +0x859B 0x53B8 # 0 +0x859C 0x53B9 # 0 +0x859D 0x53BA # 0 +0x859E 0x53BC # 0 +0x859F 0x53BD # 0 +0x85A0 0x53BE # 0 +0x85A1 0x53C0 # 0 +0x85A2 0x53C3 # 0 +0x85A3 0x53C4 # 0 +0x85A4 0x53C5 # 0 +0x85A5 0x53C6 # 0 +0x85A6 0x53C7 # 0 +0x85A7 0x53CE # 0 +0x85A8 0x53CF # 0 +0x85A9 0x53D0 # 0 +0x85AA 0x53D2 # 0 +0x85AB 0x53D3 # 0 +0x85AC 0x53D5 # 0 +0x85AD 0x53DA # 0 +0x85AE 0x53DC # 0 +0x85AF 0x53DD # 0 +0x85B0 0x53DE # 0 +0x85B1 0x53E1 # 0 +0x85B2 0x53E2 # 0 +0x85B3 0x53E7 # 0 +0x85B4 0x53F4 # 0 +0x85B5 0x53FA # 0 +0x85B6 0x53FE # 0 +0x85B7 0x53FF # 0 +0x85B8 0x5400 # 0 +0x85B9 0x5402 # 0 +0x85BA 0x5405 # 0 +0x85BB 0x5407 # 0 +0x85BC 0x540B # 0 +0x85BD 0x5414 # 0 +0x85BE 0x5418 # 0 +0x85BF 0x5419 # 0 +0x85C0 0x541A # 0 +0x85C1 0x541C # 0 +0x85C2 0x5422 # 0 +0x85C3 0x5424 # 0 +0x85C4 0x5425 # 0 +0x85C5 0x542A # 0 +0x85C6 0x5430 # 0 +0x85C7 0x5433 # 0 +0x85C8 0x5436 # 0 +0x85C9 0x5437 # 0 +0x85CA 0x543A # 0 +0x85CB 0x543D # 0 +0x85CC 0x543F # 0 +0x85CD 0x5441 # 0 +0x85CE 0x5442 # 0 +0x85CF 0x5444 # 0 +0x85D0 0x5445 # 0 +0x85D1 0x5447 # 0 +0x85D2 0x5449 # 0 +0x85D3 0x544C # 0 +0x85D4 0x544D # 0 +0x85D5 0x544E # 0 +0x85D6 0x544F # 0 +0x85D7 0x5451 # 0 +0x85D8 0x545A # 0 +0x85D9 0x545D # 0 +0x85DA 0x545E # 0 +0x85DB 0x545F # 0 +0x85DC 0x5460 # 0 +0x85DD 0x5461 # 0 +0x85DE 0x5463 # 0 +0x85DF 0x5465 # 0 +0x85E0 0x5467 # 0 +0x85E1 0x5469 # 0 +0x85E2 0x546A # 0 +0x85E3 0x546B # 0 +0x85E4 0x546C # 0 +0x85E5 0x546D # 0 +0x85E6 0x546E # 0 +0x85E7 0x546F # 0 +0x85E8 0x5470 # 0 +0x85E9 0x5474 # 0 +0x85EA 0x5479 # 0 +0x85EB 0x547A # 0 +0x85EC 0x547E # 0 +0x85ED 0x547F # 0 +0x85EE 0x5481 # 0 +0x85EF 0x5483 # 0 +0x85F0 0x5485 # 0 +0x85F1 0x5487 # 0 +0x85F2 0x5488 # 0 +0x85F3 0x5489 # 0 +0x85F4 0x548A # 0 +0x85F5 0x548D # 0 +0x85F6 0x5491 # 0 +0x85F7 0x5493 # 0 +0x85F8 0x5497 # 0 +0x85F9 0x5498 # 0 +0x85FA 0x549C # 0 +0x85FB 0x549E # 0 +0x85FC 0x549F # 0 +0x85FD 0x54A0 # 0 +0x85FE 0x54A1 # 0 +0x8640 0x54A2 # 0 +0x8641 0x54A5 # 0 +0x8642 0x54AE # 0 +0x8643 0x54B0 # 0 +0x8644 0x54B2 # 0 +0x8645 0x54B5 # 0 +0x8646 0x54B6 # 0 +0x8647 0x54B7 # 0 +0x8648 0x54B9 # 0 +0x8649 0x54BA # 0 +0x864A 0x54BC # 0 +0x864B 0x54BE # 0 +0x864C 0x54C3 # 0 +0x864D 0x54C5 # 0 +0x864E 0x54CA # 0 +0x864F 0x54CB # 0 +0x8650 0x54D6 # 0 +0x8651 0x54D8 # 0 +0x8652 0x54DB # 0 +0x8653 0x54E0 # 0 +0x8654 0x54E1 # 0 +0x8655 0x54E2 # 0 +0x8656 0x54E3 # 0 +0x8657 0x54E4 # 0 +0x8658 0x54EB # 0 +0x8659 0x54EC # 0 +0x865A 0x54EF # 0 +0x865B 0x54F0 # 0 +0x865C 0x54F1 # 0 +0x865D 0x54F4 # 0 +0x865E 0x54F5 # 0 +0x865F 0x54F6 # 0 +0x8660 0x54F7 # 0 +0x8661 0x54F8 # 0 +0x8662 0x54F9 # 0 +0x8663 0x54FB # 0 +0x8664 0x54FE # 0 +0x8665 0x5500 # 0 +0x8666 0x5502 # 0 +0x8667 0x5503 # 0 +0x8668 0x5504 # 0 +0x8669 0x5505 # 0 +0x866A 0x5508 # 0 +0x866B 0x550A # 0 +0x866C 0x550B # 0 +0x866D 0x550C # 0 +0x866E 0x550D # 0 +0x866F 0x550E # 0 +0x8670 0x5512 # 0 +0x8671 0x5513 # 0 +0x8672 0x5515 # 0 +0x8673 0x5516 # 0 +0x8674 0x5517 # 0 +0x8675 0x5518 # 0 +0x8676 0x5519 # 0 +0x8677 0x551A # 0 +0x8678 0x551C # 0 +0x8679 0x551D # 0 +0x867A 0x551E # 0 +0x867B 0x551F # 0 +0x867C 0x5521 # 0 +0x867D 0x5525 # 0 +0x867E 0x5526 # 0 +0x8680 0x5528 # 0 +0x8681 0x5529 # 0 +0x8682 0x552B # 0 +0x8683 0x552D # 0 +0x8684 0x5532 # 0 +0x8685 0x5534 # 0 +0x8686 0x5535 # 0 +0x8687 0x5536 # 0 +0x8688 0x5538 # 0 +0x8689 0x5539 # 0 +0x868A 0x553A # 0 +0x868B 0x553B # 0 +0x868C 0x553D # 0 +0x868D 0x5540 # 0 +0x868E 0x5542 # 0 +0x868F 0x5545 # 0 +0x8690 0x5547 # 0 +0x8691 0x5548 # 0 +0x8692 0x554B # 0 +0x8693 0x554C # 0 +0x8694 0x554D # 0 +0x8695 0x554E # 0 +0x8696 0x554F # 0 +0x8697 0x5551 # 0 +0x8698 0x5552 # 0 +0x8699 0x5553 # 0 +0x869A 0x5554 # 0 +0x869B 0x5557 # 0 +0x869C 0x5558 # 0 +0x869D 0x5559 # 0 +0x869E 0x555A # 0 +0x869F 0x555B # 0 +0x86A0 0x555D # 0 +0x86A1 0x555E # 0 +0x86A2 0x555F # 0 +0x86A3 0x5560 # 0 +0x86A4 0x5562 # 0 +0x86A5 0x5563 # 0 +0x86A6 0x5568 # 0 +0x86A7 0x5569 # 0 +0x86A8 0x556B # 0 +0x86A9 0x556F # 0 +0x86AA 0x5570 # 0 +0x86AB 0x5571 # 0 +0x86AC 0x5572 # 0 +0x86AD 0x5573 # 0 +0x86AE 0x5574 # 0 +0x86AF 0x5579 # 0 +0x86B0 0x557A # 0 +0x86B1 0x557D # 0 +0x86B2 0x557F # 0 +0x86B3 0x5585 # 0 +0x86B4 0x5586 # 0 +0x86B5 0x558C # 0 +0x86B6 0x558D # 0 +0x86B7 0x558E # 0 +0x86B8 0x5590 # 0 +0x86B9 0x5592 # 0 +0x86BA 0x5593 # 0 +0x86BB 0x5595 # 0 +0x86BC 0x5596 # 0 +0x86BD 0x5597 # 0 +0x86BE 0x559A # 0 +0x86BF 0x559B # 0 +0x86C0 0x559E # 0 +0x86C1 0x55A0 # 0 +0x86C2 0x55A1 # 0 +0x86C3 0x55A2 # 0 +0x86C4 0x55A3 # 0 +0x86C5 0x55A4 # 0 +0x86C6 0x55A5 # 0 +0x86C7 0x55A6 # 0 +0x86C8 0x55A8 # 0 +0x86C9 0x55A9 # 0 +0x86CA 0x55AA # 0 +0x86CB 0x55AB # 0 +0x86CC 0x55AC # 0 +0x86CD 0x55AD # 0 +0x86CE 0x55AE # 0 +0x86CF 0x55AF # 0 +0x86D0 0x55B0 # 0 +0x86D1 0x55B2 # 0 +0x86D2 0x55B4 # 0 +0x86D3 0x55B6 # 0 +0x86D4 0x55B8 # 0 +0x86D5 0x55BA # 0 +0x86D6 0x55BC # 0 +0x86D7 0x55BF # 0 +0x86D8 0x55C0 # 0 +0x86D9 0x55C1 # 0 +0x86DA 0x55C2 # 0 +0x86DB 0x55C3 # 0 +0x86DC 0x55C6 # 0 +0x86DD 0x55C7 # 0 +0x86DE 0x55C8 # 0 +0x86DF 0x55CA # 0 +0x86E0 0x55CB # 0 +0x86E1 0x55CE # 0 +0x86E2 0x55CF # 0 +0x86E3 0x55D0 # 0 +0x86E4 0x55D5 # 0 +0x86E5 0x55D7 # 0 +0x86E6 0x55D8 # 0 +0x86E7 0x55D9 # 0 +0x86E8 0x55DA # 0 +0x86E9 0x55DB # 0 +0x86EA 0x55DE # 0 +0x86EB 0x55E0 # 0 +0x86EC 0x55E2 # 0 +0x86ED 0x55E7 # 0 +0x86EE 0x55E9 # 0 +0x86EF 0x55ED # 0 +0x86F0 0x55EE # 0 +0x86F1 0x55F0 # 0 +0x86F2 0x55F1 # 0 +0x86F3 0x55F4 # 0 +0x86F4 0x55F6 # 0 +0x86F5 0x55F8 # 0 +0x86F6 0x55F9 # 0 +0x86F7 0x55FA # 0 +0x86F8 0x55FB # 0 +0x86F9 0x55FC # 0 +0x86FA 0x55FF # 0 +0x86FB 0x5602 # 0 +0x86FC 0x5603 # 0 +0x86FD 0x5604 # 0 +0x86FE 0x5605 # 0 +0x8740 0x5606 # 0 +0x8741 0x5607 # 0 +0x8742 0x560A # 0 +0x8743 0x560B # 0 +0x8744 0x560D # 0 +0x8745 0x5610 # 0 +0x8746 0x5611 # 0 +0x8747 0x5612 # 0 +0x8748 0x5613 # 0 +0x8749 0x5614 # 0 +0x874A 0x5615 # 0 +0x874B 0x5616 # 0 +0x874C 0x5617 # 0 +0x874D 0x5619 # 0 +0x874E 0x561A # 0 +0x874F 0x561C # 0 +0x8750 0x561D # 0 +0x8751 0x5620 # 0 +0x8752 0x5621 # 0 +0x8753 0x5622 # 0 +0x8754 0x5625 # 0 +0x8755 0x5626 # 0 +0x8756 0x5628 # 0 +0x8757 0x5629 # 0 +0x8758 0x562A # 0 +0x8759 0x562B # 0 +0x875A 0x562E # 0 +0x875B 0x562F # 0 +0x875C 0x5630 # 0 +0x875D 0x5633 # 0 +0x875E 0x5635 # 0 +0x875F 0x5637 # 0 +0x8760 0x5638 # 0 +0x8761 0x563A # 0 +0x8762 0x563C # 0 +0x8763 0x563D # 0 +0x8764 0x563E # 0 +0x8765 0x5640 # 0 +0x8766 0x5641 # 0 +0x8767 0x5642 # 0 +0x8768 0x5643 # 0 +0x8769 0x5644 # 0 +0x876A 0x5645 # 0 +0x876B 0x5646 # 0 +0x876C 0x5647 # 0 +0x876D 0x5648 # 0 +0x876E 0x5649 # 0 +0x876F 0x564A # 0 +0x8770 0x564B # 0 +0x8771 0x564F # 0 +0x8772 0x5650 # 0 +0x8773 0x5651 # 0 +0x8774 0x5652 # 0 +0x8775 0x5653 # 0 +0x8776 0x5655 # 0 +0x8777 0x5656 # 0 +0x8778 0x565A # 0 +0x8779 0x565B # 0 +0x877A 0x565D # 0 +0x877B 0x565E # 0 +0x877C 0x565F # 0 +0x877D 0x5660 # 0 +0x877E 0x5661 # 0 +0x8780 0x5663 # 0 +0x8781 0x5665 # 0 +0x8782 0x5666 # 0 +0x8783 0x5667 # 0 +0x8784 0x566D # 0 +0x8785 0x566E # 0 +0x8786 0x566F # 0 +0x8787 0x5670 # 0 +0x8788 0x5672 # 0 +0x8789 0x5673 # 0 +0x878A 0x5674 # 0 +0x878B 0x5675 # 0 +0x878C 0x5677 # 0 +0x878D 0x5678 # 0 +0x878E 0x5679 # 0 +0x878F 0x567A # 0 +0x8790 0x567D # 0 +0x8791 0x567E # 0 +0x8792 0x567F # 0 +0x8793 0x5680 # 0 +0x8794 0x5681 # 0 +0x8795 0x5682 # 0 +0x8796 0x5683 # 0 +0x8797 0x5684 # 0 +0x8798 0x5687 # 0 +0x8799 0x5688 # 0 +0x879A 0x5689 # 0 +0x879B 0x568A # 0 +0x879C 0x568B # 0 +0x879D 0x568C # 0 +0x879E 0x568D # 0 +0x879F 0x5690 # 0 +0x87A0 0x5691 # 0 +0x87A1 0x5692 # 0 +0x87A2 0x5694 # 0 +0x87A3 0x5695 # 0 +0x87A4 0x5696 # 0 +0x87A5 0x5697 # 0 +0x87A6 0x5698 # 0 +0x87A7 0x5699 # 0 +0x87A8 0x569A # 0 +0x87A9 0x569B # 0 +0x87AA 0x569C # 0 +0x87AB 0x569D # 0 +0x87AC 0x569E # 0 +0x87AD 0x569F # 0 +0x87AE 0x56A0 # 0 +0x87AF 0x56A1 # 0 +0x87B0 0x56A2 # 0 +0x87B1 0x56A4 # 0 +0x87B2 0x56A5 # 0 +0x87B3 0x56A6 # 0 +0x87B4 0x56A7 # 0 +0x87B5 0x56A8 # 0 +0x87B6 0x56A9 # 0 +0x87B7 0x56AA # 0 +0x87B8 0x56AB # 0 +0x87B9 0x56AC # 0 +0x87BA 0x56AD # 0 +0x87BB 0x56AE # 0 +0x87BC 0x56B0 # 0 +0x87BD 0x56B1 # 0 +0x87BE 0x56B2 # 0 +0x87BF 0x56B3 # 0 +0x87C0 0x56B4 # 0 +0x87C1 0x56B5 # 0 +0x87C2 0x56B6 # 0 +0x87C3 0x56B8 # 0 +0x87C4 0x56B9 # 0 +0x87C5 0x56BA # 0 +0x87C6 0x56BB # 0 +0x87C7 0x56BD # 0 +0x87C8 0x56BE # 0 +0x87C9 0x56BF # 0 +0x87CA 0x56C0 # 0 +0x87CB 0x56C1 # 0 +0x87CC 0x56C2 # 0 +0x87CD 0x56C3 # 0 +0x87CE 0x56C4 # 0 +0x87CF 0x56C5 # 0 +0x87D0 0x56C6 # 0 +0x87D1 0x56C7 # 0 +0x87D2 0x56C8 # 0 +0x87D3 0x56C9 # 0 +0x87D4 0x56CB # 0 +0x87D5 0x56CC # 0 +0x87D6 0x56CD # 0 +0x87D7 0x56CE # 0 +0x87D8 0x56CF # 0 +0x87D9 0x56D0 # 0 +0x87DA 0x56D1 # 0 +0x87DB 0x56D2 # 0 +0x87DC 0x56D3 # 0 +0x87DD 0x56D5 # 0 +0x87DE 0x56D6 # 0 +0x87DF 0x56D8 # 0 +0x87E0 0x56D9 # 0 +0x87E1 0x56DC # 0 +0x87E2 0x56E3 # 0 +0x87E3 0x56E5 # 0 +0x87E4 0x56E6 # 0 +0x87E5 0x56E7 # 0 +0x87E6 0x56E8 # 0 +0x87E7 0x56E9 # 0 +0x87E8 0x56EA # 0 +0x87E9 0x56EC # 0 +0x87EA 0x56EE # 0 +0x87EB 0x56EF # 0 +0x87EC 0x56F2 # 0 +0x87ED 0x56F3 # 0 +0x87EE 0x56F6 # 0 +0x87EF 0x56F7 # 0 +0x87F0 0x56F8 # 0 +0x87F1 0x56FB # 0 +0x87F2 0x56FC # 0 +0x87F3 0x5700 # 0 +0x87F4 0x5701 # 0 +0x87F5 0x5702 # 0 +0x87F6 0x5705 # 0 +0x87F7 0x5707 # 0 +0x87F8 0x570B # 0 +0x87F9 0x570C # 0 +0x87FA 0x570D # 0 +0x87FB 0x570E # 0 +0x87FC 0x570F # 0 +0x87FD 0x5710 # 0 +0x87FE 0x5711 # 0 +0x8840 0x5712 # 0 +0x8841 0x5713 # 0 +0x8842 0x5714 # 0 +0x8843 0x5715 # 0 +0x8844 0x5716 # 0 +0x8845 0x5717 # 0 +0x8846 0x5718 # 0 +0x8847 0x5719 # 0 +0x8848 0x571A # 0 +0x8849 0x571B # 0 +0x884A 0x571D # 0 +0x884B 0x571E # 0 +0x884C 0x5720 # 0 +0x884D 0x5721 # 0 +0x884E 0x5722 # 0 +0x884F 0x5724 # 0 +0x8850 0x5725 # 0 +0x8851 0x5726 # 0 +0x8852 0x5727 # 0 +0x8853 0x572B # 0 +0x8854 0x5731 # 0 +0x8855 0x5732 # 0 +0x8856 0x5734 # 0 +0x8857 0x5735 # 0 +0x8858 0x5736 # 0 +0x8859 0x5737 # 0 +0x885A 0x5738 # 0 +0x885B 0x573C # 0 +0x885C 0x573D # 0 +0x885D 0x573F # 0 +0x885E 0x5741 # 0 +0x885F 0x5743 # 0 +0x8860 0x5744 # 0 +0x8861 0x5745 # 0 +0x8862 0x5746 # 0 +0x8863 0x5748 # 0 +0x8864 0x5749 # 0 +0x8865 0x574B # 0 +0x8866 0x5752 # 0 +0x8867 0x5753 # 0 +0x8868 0x5754 # 0 +0x8869 0x5755 # 0 +0x886A 0x5756 # 0 +0x886B 0x5758 # 0 +0x886C 0x5759 # 0 +0x886D 0x5762 # 0 +0x886E 0x5763 # 0 +0x886F 0x5765 # 0 +0x8870 0x5767 # 0 +0x8871 0x576C # 0 +0x8872 0x576E # 0 +0x8873 0x5770 # 0 +0x8874 0x5771 # 0 +0x8875 0x5772 # 0 +0x8876 0x5774 # 0 +0x8877 0x5775 # 0 +0x8878 0x5778 # 0 +0x8879 0x5779 # 0 +0x887A 0x577A # 0 +0x887B 0x577D # 0 +0x887C 0x577E # 0 +0x887D 0x577F # 0 +0x887E 0x5780 # 0 +0x8880 0x5781 # 0 +0x8881 0x5787 # 0 +0x8882 0x5788 # 0 +0x8883 0x5789 # 0 +0x8884 0x578A # 0 +0x8885 0x578D # 0 +0x8886 0x578E # 0 +0x8887 0x578F # 0 +0x8888 0x5790 # 0 +0x8889 0x5791 # 0 +0x888A 0x5794 # 0 +0x888B 0x5795 # 0 +0x888C 0x5796 # 0 +0x888D 0x5797 # 0 +0x888E 0x5798 # 0 +0x888F 0x5799 # 0 +0x8890 0x579A # 0 +0x8891 0x579C # 0 +0x8892 0x579D # 0 +0x8893 0x579E # 0 +0x8894 0x579F # 0 +0x8895 0x57A5 # 0 +0x8896 0x57A8 # 0 +0x8897 0x57AA # 0 +0x8898 0x57AC # 0 +0x8899 0x57AF # 0 +0x889A 0x57B0 # 0 +0x889B 0x57B1 # 0 +0x889C 0x57B3 # 0 +0x889D 0x57B5 # 0 +0x889E 0x57B6 # 0 +0x889F 0x57B7 # 0 +0x88A0 0x57B9 # 0 +0x88A1 0x57BA # 0 +0x88A2 0x57BB # 0 +0x88A3 0x57BC # 0 +0x88A4 0x57BD # 0 +0x88A5 0x57BE # 0 +0x88A6 0x57BF # 0 +0x88A7 0x57C0 # 0 +0x88A8 0x57C1 # 0 +0x88A9 0x57C4 # 0 +0x88AA 0x57C5 # 0 +0x88AB 0x57C6 # 0 +0x88AC 0x57C7 # 0 +0x88AD 0x57C8 # 0 +0x88AE 0x57C9 # 0 +0x88AF 0x57CA # 0 +0x88B0 0x57CC # 0 +0x88B1 0x57CD # 0 +0x88B2 0x57D0 # 0 +0x88B3 0x57D1 # 0 +0x88B4 0x57D3 # 0 +0x88B5 0x57D6 # 0 +0x88B6 0x57D7 # 0 +0x88B7 0x57DB # 0 +0x88B8 0x57DC # 0 +0x88B9 0x57DE # 0 +0x88BA 0x57E1 # 0 +0x88BB 0x57E2 # 0 +0x88BC 0x57E3 # 0 +0x88BD 0x57E5 # 0 +0x88BE 0x57E6 # 0 +0x88BF 0x57E7 # 0 +0x88C0 0x57E8 # 0 +0x88C1 0x57E9 # 0 +0x88C2 0x57EA # 0 +0x88C3 0x57EB # 0 +0x88C4 0x57EC # 0 +0x88C5 0x57EE # 0 +0x88C6 0x57F0 # 0 +0x88C7 0x57F1 # 0 +0x88C8 0x57F2 # 0 +0x88C9 0x57F3 # 0 +0x88CA 0x57F5 # 0 +0x88CB 0x57F6 # 0 +0x88CC 0x57F7 # 0 +0x88CD 0x57FB # 0 +0x88CE 0x57FC # 0 +0x88CF 0x57FE # 0 +0x88D0 0x57FF # 0 +0x88D1 0x5801 # 0 +0x88D2 0x5803 # 0 +0x88D3 0x5804 # 0 +0x88D4 0x5805 # 0 +0x88D5 0x5808 # 0 +0x88D6 0x5809 # 0 +0x88D7 0x580A # 0 +0x88D8 0x580C # 0 +0x88D9 0x580E # 0 +0x88DA 0x580F # 0 +0x88DB 0x5810 # 0 +0x88DC 0x5812 # 0 +0x88DD 0x5813 # 0 +0x88DE 0x5814 # 0 +0x88DF 0x5816 # 0 +0x88E0 0x5817 # 0 +0x88E1 0x5818 # 0 +0x88E2 0x581A # 0 +0x88E3 0x581B # 0 +0x88E4 0x581C # 0 +0x88E5 0x581D # 0 +0x88E6 0x581F # 0 +0x88E7 0x5822 # 0 +0x88E8 0x5823 # 0 +0x88E9 0x5825 # 0 +0x88EA 0x5826 # 0 +0x88EB 0x5827 # 0 +0x88EC 0x5828 # 0 +0x88ED 0x5829 # 0 +0x88EE 0x582B # 0 +0x88EF 0x582C # 0 +0x88F0 0x582D # 0 +0x88F1 0x582E # 0 +0x88F2 0x582F # 0 +0x88F3 0x5831 # 0 +0x88F4 0x5832 # 0 +0x88F5 0x5833 # 0 +0x88F6 0x5834 # 0 +0x88F7 0x5836 # 0 +0x88F8 0x5837 # 0 +0x88F9 0x5838 # 0 +0x88FA 0x5839 # 0 +0x88FB 0x583A # 0 +0x88FC 0x583B # 0 +0x88FD 0x583C # 0 +0x88FE 0x583D # 0 +0x8940 0x583E # 0 +0x8941 0x583F # 0 +0x8942 0x5840 # 0 +0x8943 0x5841 # 0 +0x8944 0x5842 # 0 +0x8945 0x5843 # 0 +0x8946 0x5845 # 0 +0x8947 0x5846 # 0 +0x8948 0x5847 # 0 +0x8949 0x5848 # 0 +0x894A 0x5849 # 0 +0x894B 0x584A # 0 +0x894C 0x584B # 0 +0x894D 0x584E # 0 +0x894E 0x584F # 0 +0x894F 0x5850 # 0 +0x8950 0x5852 # 0 +0x8951 0x5853 # 0 +0x8952 0x5855 # 0 +0x8953 0x5856 # 0 +0x8954 0x5857 # 0 +0x8955 0x5859 # 0 +0x8956 0x585A # 0 +0x8957 0x585B # 0 +0x8958 0x585C # 0 +0x8959 0x585D # 0 +0x895A 0x585F # 0 +0x895B 0x5860 # 0 +0x895C 0x5861 # 0 +0x895D 0x5862 # 0 +0x895E 0x5863 # 0 +0x895F 0x5864 # 0 +0x8960 0x5866 # 0 +0x8961 0x5867 # 0 +0x8962 0x5868 # 0 +0x8963 0x5869 # 0 +0x8964 0x586A # 0 +0x8965 0x586D # 0 +0x8966 0x586E # 0 +0x8967 0x586F # 0 +0x8968 0x5870 # 0 +0x8969 0x5871 # 0 +0x896A 0x5872 # 0 +0x896B 0x5873 # 0 +0x896C 0x5874 # 0 +0x896D 0x5875 # 0 +0x896E 0x5876 # 0 +0x896F 0x5877 # 0 +0x8970 0x5878 # 0 +0x8971 0x5879 # 0 +0x8972 0x587A # 0 +0x8973 0x587B # 0 +0x8974 0x587C # 0 +0x8975 0x587D # 0 +0x8976 0x587F # 0 +0x8977 0x5882 # 0 +0x8978 0x5884 # 0 +0x8979 0x5886 # 0 +0x897A 0x5887 # 0 +0x897B 0x5888 # 0 +0x897C 0x588A # 0 +0x897D 0x588B # 0 +0x897E 0x588C # 0 +0x8980 0x588D # 0 +0x8981 0x588E # 0 +0x8982 0x588F # 0 +0x8983 0x5890 # 0 +0x8984 0x5891 # 0 +0x8985 0x5894 # 0 +0x8986 0x5895 # 0 +0x8987 0x5896 # 0 +0x8988 0x5897 # 0 +0x8989 0x5898 # 0 +0x898A 0x589B # 0 +0x898B 0x589C # 0 +0x898C 0x589D # 0 +0x898D 0x58A0 # 0 +0x898E 0x58A1 # 0 +0x898F 0x58A2 # 0 +0x8990 0x58A3 # 0 +0x8991 0x58A4 # 0 +0x8992 0x58A5 # 0 +0x8993 0x58A6 # 0 +0x8994 0x58A7 # 0 +0x8995 0x58AA # 0 +0x8996 0x58AB # 0 +0x8997 0x58AC # 0 +0x8998 0x58AD # 0 +0x8999 0x58AE # 0 +0x899A 0x58AF # 0 +0x899B 0x58B0 # 0 +0x899C 0x58B1 # 0 +0x899D 0x58B2 # 0 +0x899E 0x58B3 # 0 +0x899F 0x58B4 # 0 +0x89A0 0x58B5 # 0 +0x89A1 0x58B6 # 0 +0x89A2 0x58B7 # 0 +0x89A3 0x58B8 # 0 +0x89A4 0x58B9 # 0 +0x89A5 0x58BA # 0 +0x89A6 0x58BB # 0 +0x89A7 0x58BD # 0 +0x89A8 0x58BE # 0 +0x89A9 0x58BF # 0 +0x89AA 0x58C0 # 0 +0x89AB 0x58C2 # 0 +0x89AC 0x58C3 # 0 +0x89AD 0x58C4 # 0 +0x89AE 0x58C6 # 0 +0x89AF 0x58C7 # 0 +0x89B0 0x58C8 # 0 +0x89B1 0x58C9 # 0 +0x89B2 0x58CA # 0 +0x89B3 0x58CB # 0 +0x89B4 0x58CC # 0 +0x89B5 0x58CD # 0 +0x89B6 0x58CE # 0 +0x89B7 0x58CF # 0 +0x89B8 0x58D0 # 0 +0x89B9 0x58D2 # 0 +0x89BA 0x58D3 # 0 +0x89BB 0x58D4 # 0 +0x89BC 0x58D6 # 0 +0x89BD 0x58D7 # 0 +0x89BE 0x58D8 # 0 +0x89BF 0x58D9 # 0 +0x89C0 0x58DA # 0 +0x89C1 0x58DB # 0 +0x89C2 0x58DC # 0 +0x89C3 0x58DD # 0 +0x89C4 0x58DE # 0 +0x89C5 0x58DF # 0 +0x89C6 0x58E0 # 0 +0x89C7 0x58E1 # 0 +0x89C8 0x58E2 # 0 +0x89C9 0x58E3 # 0 +0x89CA 0x58E5 # 0 +0x89CB 0x58E6 # 0 +0x89CC 0x58E7 # 0 +0x89CD 0x58E8 # 0 +0x89CE 0x58E9 # 0 +0x89CF 0x58EA # 0 +0x89D0 0x58ED # 0 +0x89D1 0x58EF # 0 +0x89D2 0x58F1 # 0 +0x89D3 0x58F2 # 0 +0x89D4 0x58F4 # 0 +0x89D5 0x58F5 # 0 +0x89D6 0x58F7 # 0 +0x89D7 0x58F8 # 0 +0x89D8 0x58FA # 0 +0x89D9 0x58FB # 0 +0x89DA 0x58FC # 0 +0x89DB 0x58FD # 0 +0x89DC 0x58FE # 0 +0x89DD 0x58FF # 0 +0x89DE 0x5900 # 0 +0x89DF 0x5901 # 0 +0x89E0 0x5903 # 0 +0x89E1 0x5905 # 0 +0x89E2 0x5906 # 0 +0x89E3 0x5908 # 0 +0x89E4 0x5909 # 0 +0x89E5 0x590A # 0 +0x89E6 0x590B # 0 +0x89E7 0x590C # 0 +0x89E8 0x590E # 0 +0x89E9 0x5910 # 0 +0x89EA 0x5911 # 0 +0x89EB 0x5912 # 0 +0x89EC 0x5913 # 0 +0x89ED 0x5917 # 0 +0x89EE 0x5918 # 0 +0x89EF 0x591B # 0 +0x89F0 0x591D # 0 +0x89F1 0x591E # 0 +0x89F2 0x5920 # 0 +0x89F3 0x5921 # 0 +0x89F4 0x5922 # 0 +0x89F5 0x5923 # 0 +0x89F6 0x5926 # 0 +0x89F7 0x5928 # 0 +0x89F8 0x592C # 0 +0x89F9 0x5930 # 0 +0x89FA 0x5932 # 0 +0x89FB 0x5933 # 0 +0x89FC 0x5935 # 0 +0x89FD 0x5936 # 0 +0x89FE 0x593B # 0 +0x8A40 0x593D # 0 +0x8A41 0x593E # 0 +0x8A42 0x593F # 0 +0x8A43 0x5940 # 0 +0x8A44 0x5943 # 0 +0x8A45 0x5945 # 0 +0x8A46 0x5946 # 0 +0x8A47 0x594A # 0 +0x8A48 0x594C # 0 +0x8A49 0x594D # 0 +0x8A4A 0x5950 # 0 +0x8A4B 0x5952 # 0 +0x8A4C 0x5953 # 0 +0x8A4D 0x5959 # 0 +0x8A4E 0x595B # 0 +0x8A4F 0x595C # 0 +0x8A50 0x595D # 0 +0x8A51 0x595E # 0 +0x8A52 0x595F # 0 +0x8A53 0x5961 # 0 +0x8A54 0x5963 # 0 +0x8A55 0x5964 # 0 +0x8A56 0x5966 # 0 +0x8A57 0x5967 # 0 +0x8A58 0x5968 # 0 +0x8A59 0x5969 # 0 +0x8A5A 0x596A # 0 +0x8A5B 0x596B # 0 +0x8A5C 0x596C # 0 +0x8A5D 0x596D # 0 +0x8A5E 0x596E # 0 +0x8A5F 0x596F # 0 +0x8A60 0x5970 # 0 +0x8A61 0x5971 # 0 +0x8A62 0x5972 # 0 +0x8A63 0x5975 # 0 +0x8A64 0x5977 # 0 +0x8A65 0x597A # 0 +0x8A66 0x597B # 0 +0x8A67 0x597C # 0 +0x8A68 0x597E # 0 +0x8A69 0x597F # 0 +0x8A6A 0x5980 # 0 +0x8A6B 0x5985 # 0 +0x8A6C 0x5989 # 0 +0x8A6D 0x598B # 0 +0x8A6E 0x598C # 0 +0x8A6F 0x598E # 0 +0x8A70 0x598F # 0 +0x8A71 0x5990 # 0 +0x8A72 0x5991 # 0 +0x8A73 0x5994 # 0 +0x8A74 0x5995 # 0 +0x8A75 0x5998 # 0 +0x8A76 0x599A # 0 +0x8A77 0x599B # 0 +0x8A78 0x599C # 0 +0x8A79 0x599D # 0 +0x8A7A 0x599F # 0 +0x8A7B 0x59A0 # 0 +0x8A7C 0x59A1 # 0 +0x8A7D 0x59A2 # 0 +0x8A7E 0x59A6 # 0 +0x8A80 0x59A7 # 0 +0x8A81 0x59AC # 0 +0x8A82 0x59AD # 0 +0x8A83 0x59B0 # 0 +0x8A84 0x59B1 # 0 +0x8A85 0x59B3 # 0 +0x8A86 0x59B4 # 0 +0x8A87 0x59B5 # 0 +0x8A88 0x59B6 # 0 +0x8A89 0x59B7 # 0 +0x8A8A 0x59B8 # 0 +0x8A8B 0x59BA # 0 +0x8A8C 0x59BC # 0 +0x8A8D 0x59BD # 0 +0x8A8E 0x59BF # 0 +0x8A8F 0x59C0 # 0 +0x8A90 0x59C1 # 0 +0x8A91 0x59C2 # 0 +0x8A92 0x59C3 # 0 +0x8A93 0x59C4 # 0 +0x8A94 0x59C5 # 0 +0x8A95 0x59C7 # 0 +0x8A96 0x59C8 # 0 +0x8A97 0x59C9 # 0 +0x8A98 0x59CC # 0 +0x8A99 0x59CD # 0 +0x8A9A 0x59CE # 0 +0x8A9B 0x59CF # 0 +0x8A9C 0x59D5 # 0 +0x8A9D 0x59D6 # 0 +0x8A9E 0x59D9 # 0 +0x8A9F 0x59DB # 0 +0x8AA0 0x59DE # 0 +0x8AA1 0x59DF # 0 +0x8AA2 0x59E0 # 0 +0x8AA3 0x59E1 # 0 +0x8AA4 0x59E2 # 0 +0x8AA5 0x59E4 # 0 +0x8AA6 0x59E6 # 0 +0x8AA7 0x59E7 # 0 +0x8AA8 0x59E9 # 0 +0x8AA9 0x59EA # 0 +0x8AAA 0x59EB # 0 +0x8AAB 0x59ED # 0 +0x8AAC 0x59EE # 0 +0x8AAD 0x59EF # 0 +0x8AAE 0x59F0 # 0 +0x8AAF 0x59F1 # 0 +0x8AB0 0x59F2 # 0 +0x8AB1 0x59F3 # 0 +0x8AB2 0x59F4 # 0 +0x8AB3 0x59F5 # 0 +0x8AB4 0x59F6 # 0 +0x8AB5 0x59F7 # 0 +0x8AB6 0x59F8 # 0 +0x8AB7 0x59FA # 0 +0x8AB8 0x59FC # 0 +0x8AB9 0x59FD # 0 +0x8ABA 0x59FE # 0 +0x8ABB 0x5A00 # 0 +0x8ABC 0x5A02 # 0 +0x8ABD 0x5A0A # 0 +0x8ABE 0x5A0B # 0 +0x8ABF 0x5A0D # 0 +0x8AC0 0x5A0E # 0 +0x8AC1 0x5A0F # 0 +0x8AC2 0x5A10 # 0 +0x8AC3 0x5A12 # 0 +0x8AC4 0x5A14 # 0 +0x8AC5 0x5A15 # 0 +0x8AC6 0x5A16 # 0 +0x8AC7 0x5A17 # 0 +0x8AC8 0x5A19 # 0 +0x8AC9 0x5A1A # 0 +0x8ACA 0x5A1B # 0 +0x8ACB 0x5A1D # 0 +0x8ACC 0x5A1E # 0 +0x8ACD 0x5A21 # 0 +0x8ACE 0x5A22 # 0 +0x8ACF 0x5A24 # 0 +0x8AD0 0x5A26 # 0 +0x8AD1 0x5A27 # 0 +0x8AD2 0x5A28 # 0 +0x8AD3 0x5A2A # 0 +0x8AD4 0x5A2B # 0 +0x8AD5 0x5A2C # 0 +0x8AD6 0x5A2D # 0 +0x8AD7 0x5A2E # 0 +0x8AD8 0x5A2F # 0 +0x8AD9 0x5A30 # 0 +0x8ADA 0x5A33 # 0 +0x8ADB 0x5A35 # 0 +0x8ADC 0x5A37 # 0 +0x8ADD 0x5A38 # 0 +0x8ADE 0x5A39 # 0 +0x8ADF 0x5A3A # 0 +0x8AE0 0x5A3B # 0 +0x8AE1 0x5A3D # 0 +0x8AE2 0x5A3E # 0 +0x8AE3 0x5A3F # 0 +0x8AE4 0x5A41 # 0 +0x8AE5 0x5A42 # 0 +0x8AE6 0x5A43 # 0 +0x8AE7 0x5A44 # 0 +0x8AE8 0x5A45 # 0 +0x8AE9 0x5A47 # 0 +0x8AEA 0x5A48 # 0 +0x8AEB 0x5A4B # 0 +0x8AEC 0x5A4C # 0 +0x8AED 0x5A4D # 0 +0x8AEE 0x5A4E # 0 +0x8AEF 0x5A4F # 0 +0x8AF0 0x5A50 # 0 +0x8AF1 0x5A51 # 0 +0x8AF2 0x5A52 # 0 +0x8AF3 0x5A53 # 0 +0x8AF4 0x5A54 # 0 +0x8AF5 0x5A56 # 0 +0x8AF6 0x5A57 # 0 +0x8AF7 0x5A58 # 0 +0x8AF8 0x5A59 # 0 +0x8AF9 0x5A5B # 0 +0x8AFA 0x5A5C # 0 +0x8AFB 0x5A5D # 0 +0x8AFC 0x5A5E # 0 +0x8AFD 0x5A5F # 0 +0x8AFE 0x5A60 # 0 +0x8B40 0x5A61 # 0 +0x8B41 0x5A63 # 0 +0x8B42 0x5A64 # 0 +0x8B43 0x5A65 # 0 +0x8B44 0x5A66 # 0 +0x8B45 0x5A68 # 0 +0x8B46 0x5A69 # 0 +0x8B47 0x5A6B # 0 +0x8B48 0x5A6C # 0 +0x8B49 0x5A6D # 0 +0x8B4A 0x5A6E # 0 +0x8B4B 0x5A6F # 0 +0x8B4C 0x5A70 # 0 +0x8B4D 0x5A71 # 0 +0x8B4E 0x5A72 # 0 +0x8B4F 0x5A73 # 0 +0x8B50 0x5A78 # 0 +0x8B51 0x5A79 # 0 +0x8B52 0x5A7B # 0 +0x8B53 0x5A7C # 0 +0x8B54 0x5A7D # 0 +0x8B55 0x5A7E # 0 +0x8B56 0x5A80 # 0 +0x8B57 0x5A81 # 0 +0x8B58 0x5A82 # 0 +0x8B59 0x5A83 # 0 +0x8B5A 0x5A84 # 0 +0x8B5B 0x5A85 # 0 +0x8B5C 0x5A86 # 0 +0x8B5D 0x5A87 # 0 +0x8B5E 0x5A88 # 0 +0x8B5F 0x5A89 # 0 +0x8B60 0x5A8A # 0 +0x8B61 0x5A8B # 0 +0x8B62 0x5A8C # 0 +0x8B63 0x5A8D # 0 +0x8B64 0x5A8E # 0 +0x8B65 0x5A8F # 0 +0x8B66 0x5A90 # 0 +0x8B67 0x5A91 # 0 +0x8B68 0x5A93 # 0 +0x8B69 0x5A94 # 0 +0x8B6A 0x5A95 # 0 +0x8B6B 0x5A96 # 0 +0x8B6C 0x5A97 # 0 +0x8B6D 0x5A98 # 0 +0x8B6E 0x5A99 # 0 +0x8B6F 0x5A9C # 0 +0x8B70 0x5A9D # 0 +0x8B71 0x5A9E # 0 +0x8B72 0x5A9F # 0 +0x8B73 0x5AA0 # 0 +0x8B74 0x5AA1 # 0 +0x8B75 0x5AA2 # 0 +0x8B76 0x5AA3 # 0 +0x8B77 0x5AA4 # 0 +0x8B78 0x5AA5 # 0 +0x8B79 0x5AA6 # 0 +0x8B7A 0x5AA7 # 0 +0x8B7B 0x5AA8 # 0 +0x8B7C 0x5AA9 # 0 +0x8B7D 0x5AAB # 0 +0x8B7E 0x5AAC # 0 +0x8B80 0x5AAD # 0 +0x8B81 0x5AAE # 0 +0x8B82 0x5AAF # 0 +0x8B83 0x5AB0 # 0 +0x8B84 0x5AB1 # 0 +0x8B85 0x5AB4 # 0 +0x8B86 0x5AB6 # 0 +0x8B87 0x5AB7 # 0 +0x8B88 0x5AB9 # 0 +0x8B89 0x5ABA # 0 +0x8B8A 0x5ABB # 0 +0x8B8B 0x5ABC # 0 +0x8B8C 0x5ABD # 0 +0x8B8D 0x5ABF # 0 +0x8B8E 0x5AC0 # 0 +0x8B8F 0x5AC3 # 0 +0x8B90 0x5AC4 # 0 +0x8B91 0x5AC5 # 0 +0x8B92 0x5AC6 # 0 +0x8B93 0x5AC7 # 0 +0x8B94 0x5AC8 # 0 +0x8B95 0x5ACA # 0 +0x8B96 0x5ACB # 0 +0x8B97 0x5ACD # 0 +0x8B98 0x5ACE # 0 +0x8B99 0x5ACF # 0 +0x8B9A 0x5AD0 # 0 +0x8B9B 0x5AD1 # 0 +0x8B9C 0x5AD3 # 0 +0x8B9D 0x5AD5 # 0 +0x8B9E 0x5AD7 # 0 +0x8B9F 0x5AD9 # 0 +0x8BA0 0x5ADA # 0 +0x8BA1 0x5ADB # 0 +0x8BA2 0x5ADD # 0 +0x8BA3 0x5ADE # 0 +0x8BA4 0x5ADF # 0 +0x8BA5 0x5AE2 # 0 +0x8BA6 0x5AE4 # 0 +0x8BA7 0x5AE5 # 0 +0x8BA8 0x5AE7 # 0 +0x8BA9 0x5AE8 # 0 +0x8BAA 0x5AEA # 0 +0x8BAB 0x5AEC # 0 +0x8BAC 0x5AED # 0 +0x8BAD 0x5AEE # 0 +0x8BAE 0x5AEF # 0 +0x8BAF 0x5AF0 # 0 +0x8BB0 0x5AF2 # 0 +0x8BB1 0x5AF3 # 0 +0x8BB2 0x5AF4 # 0 +0x8BB3 0x5AF5 # 0 +0x8BB4 0x5AF6 # 0 +0x8BB5 0x5AF7 # 0 +0x8BB6 0x5AF8 # 0 +0x8BB7 0x5AF9 # 0 +0x8BB8 0x5AFA # 0 +0x8BB9 0x5AFB # 0 +0x8BBA 0x5AFC # 0 +0x8BBB 0x5AFD # 0 +0x8BBC 0x5AFE # 0 +0x8BBD 0x5AFF # 0 +0x8BBE 0x5B00 # 0 +0x8BBF 0x5B01 # 0 +0x8BC0 0x5B02 # 0 +0x8BC1 0x5B03 # 0 +0x8BC2 0x5B04 # 0 +0x8BC3 0x5B05 # 0 +0x8BC4 0x5B06 # 0 +0x8BC5 0x5B07 # 0 +0x8BC6 0x5B08 # 0 +0x8BC7 0x5B0A # 0 +0x8BC8 0x5B0B # 0 +0x8BC9 0x5B0C # 0 +0x8BCA 0x5B0D # 0 +0x8BCB 0x5B0E # 0 +0x8BCC 0x5B0F # 0 +0x8BCD 0x5B10 # 0 +0x8BCE 0x5B11 # 0 +0x8BCF 0x5B12 # 0 +0x8BD0 0x5B13 # 0 +0x8BD1 0x5B14 # 0 +0x8BD2 0x5B15 # 0 +0x8BD3 0x5B18 # 0 +0x8BD4 0x5B19 # 0 +0x8BD5 0x5B1A # 0 +0x8BD6 0x5B1B # 0 +0x8BD7 0x5B1C # 0 +0x8BD8 0x5B1D # 0 +0x8BD9 0x5B1E # 0 +0x8BDA 0x5B1F # 0 +0x8BDB 0x5B20 # 0 +0x8BDC 0x5B21 # 0 +0x8BDD 0x5B22 # 0 +0x8BDE 0x5B23 # 0 +0x8BDF 0x5B24 # 0 +0x8BE0 0x5B25 # 0 +0x8BE1 0x5B26 # 0 +0x8BE2 0x5B27 # 0 +0x8BE3 0x5B28 # 0 +0x8BE4 0x5B29 # 0 +0x8BE5 0x5B2A # 0 +0x8BE6 0x5B2B # 0 +0x8BE7 0x5B2C # 0 +0x8BE8 0x5B2D # 0 +0x8BE9 0x5B2E # 0 +0x8BEA 0x5B2F # 0 +0x8BEB 0x5B30 # 0 +0x8BEC 0x5B31 # 0 +0x8BED 0x5B33 # 0 +0x8BEE 0x5B35 # 0 +0x8BEF 0x5B36 # 0 +0x8BF0 0x5B38 # 0 +0x8BF1 0x5B39 # 0 +0x8BF2 0x5B3A # 0 +0x8BF3 0x5B3B # 0 +0x8BF4 0x5B3C # 0 +0x8BF5 0x5B3D # 0 +0x8BF6 0x5B3E # 0 +0x8BF7 0x5B3F # 0 +0x8BF8 0x5B41 # 0 +0x8BF9 0x5B42 # 0 +0x8BFA 0x5B43 # 0 +0x8BFB 0x5B44 # 0 +0x8BFC 0x5B45 # 0 +0x8BFD 0x5B46 # 0 +0x8BFE 0x5B47 # 0 +0x8C40 0x5B48 # 0 +0x8C41 0x5B49 # 0 +0x8C42 0x5B4A # 0 +0x8C43 0x5B4B # 0 +0x8C44 0x5B4C # 0 +0x8C45 0x5B4D # 0 +0x8C46 0x5B4E # 0 +0x8C47 0x5B4F # 0 +0x8C48 0x5B52 # 0 +0x8C49 0x5B56 # 0 +0x8C4A 0x5B5E # 0 +0x8C4B 0x5B60 # 0 +0x8C4C 0x5B61 # 0 +0x8C4D 0x5B67 # 0 +0x8C4E 0x5B68 # 0 +0x8C4F 0x5B6B # 0 +0x8C50 0x5B6D # 0 +0x8C51 0x5B6E # 0 +0x8C52 0x5B6F # 0 +0x8C53 0x5B72 # 0 +0x8C54 0x5B74 # 0 +0x8C55 0x5B76 # 0 +0x8C56 0x5B77 # 0 +0x8C57 0x5B78 # 0 +0x8C58 0x5B79 # 0 +0x8C59 0x5B7B # 0 +0x8C5A 0x5B7C # 0 +0x8C5B 0x5B7E # 0 +0x8C5C 0x5B7F # 0 +0x8C5D 0x5B82 # 0 +0x8C5E 0x5B86 # 0 +0x8C5F 0x5B8A # 0 +0x8C60 0x5B8D # 0 +0x8C61 0x5B8E # 0 +0x8C62 0x5B90 # 0 +0x8C63 0x5B91 # 0 +0x8C64 0x5B92 # 0 +0x8C65 0x5B94 # 0 +0x8C66 0x5B96 # 0 +0x8C67 0x5B9F # 0 +0x8C68 0x5BA7 # 0 +0x8C69 0x5BA8 # 0 +0x8C6A 0x5BA9 # 0 +0x8C6B 0x5BAC # 0 +0x8C6C 0x5BAD # 0 +0x8C6D 0x5BAE # 0 +0x8C6E 0x5BAF # 0 +0x8C6F 0x5BB1 # 0 +0x8C70 0x5BB2 # 0 +0x8C71 0x5BB7 # 0 +0x8C72 0x5BBA # 0 +0x8C73 0x5BBB # 0 +0x8C74 0x5BBC # 0 +0x8C75 0x5BC0 # 0 +0x8C76 0x5BC1 # 0 +0x8C77 0x5BC3 # 0 +0x8C78 0x5BC8 # 0 +0x8C79 0x5BC9 # 0 +0x8C7A 0x5BCA # 0 +0x8C7B 0x5BCB # 0 +0x8C7C 0x5BCD # 0 +0x8C7D 0x5BCE # 0 +0x8C7E 0x5BCF # 0 +0x8C80 0x5BD1 # 0 +0x8C81 0x5BD4 # 0 +0x8C82 0x5BD5 # 0 +0x8C83 0x5BD6 # 0 +0x8C84 0x5BD7 # 0 +0x8C85 0x5BD8 # 0 +0x8C86 0x5BD9 # 0 +0x8C87 0x5BDA # 0 +0x8C88 0x5BDB # 0 +0x8C89 0x5BDC # 0 +0x8C8A 0x5BE0 # 0 +0x8C8B 0x5BE2 # 0 +0x8C8C 0x5BE3 # 0 +0x8C8D 0x5BE6 # 0 +0x8C8E 0x5BE7 # 0 +0x8C8F 0x5BE9 # 0 +0x8C90 0x5BEA # 0 +0x8C91 0x5BEB # 0 +0x8C92 0x5BEC # 0 +0x8C93 0x5BED # 0 +0x8C94 0x5BEF # 0 +0x8C95 0x5BF1 # 0 +0x8C96 0x5BF2 # 0 +0x8C97 0x5BF3 # 0 +0x8C98 0x5BF4 # 0 +0x8C99 0x5BF5 # 0 +0x8C9A 0x5BF6 # 0 +0x8C9B 0x5BF7 # 0 +0x8C9C 0x5BFD # 0 +0x8C9D 0x5BFE # 0 +0x8C9E 0x5C00 # 0 +0x8C9F 0x5C02 # 0 +0x8CA0 0x5C03 # 0 +0x8CA1 0x5C05 # 0 +0x8CA2 0x5C07 # 0 +0x8CA3 0x5C08 # 0 +0x8CA4 0x5C0B # 0 +0x8CA5 0x5C0C # 0 +0x8CA6 0x5C0D # 0 +0x8CA7 0x5C0E # 0 +0x8CA8 0x5C10 # 0 +0x8CA9 0x5C12 # 0 +0x8CAA 0x5C13 # 0 +0x8CAB 0x5C17 # 0 +0x8CAC 0x5C19 # 0 +0x8CAD 0x5C1B # 0 +0x8CAE 0x5C1E # 0 +0x8CAF 0x5C1F # 0 +0x8CB0 0x5C20 # 0 +0x8CB1 0x5C21 # 0 +0x8CB2 0x5C23 # 0 +0x8CB3 0x5C26 # 0 +0x8CB4 0x5C28 # 0 +0x8CB5 0x5C29 # 0 +0x8CB6 0x5C2A # 0 +0x8CB7 0x5C2B # 0 +0x8CB8 0x5C2D # 0 +0x8CB9 0x5C2E # 0 +0x8CBA 0x5C2F # 0 +0x8CBB 0x5C30 # 0 +0x8CBC 0x5C32 # 0 +0x8CBD 0x5C33 # 0 +0x8CBE 0x5C35 # 0 +0x8CBF 0x5C36 # 0 +0x8CC0 0x5C37 # 0 +0x8CC1 0x5C43 # 0 +0x8CC2 0x5C44 # 0 +0x8CC3 0x5C46 # 0 +0x8CC4 0x5C47 # 0 +0x8CC5 0x5C4C # 0 +0x8CC6 0x5C4D # 0 +0x8CC7 0x5C52 # 0 +0x8CC8 0x5C53 # 0 +0x8CC9 0x5C54 # 0 +0x8CCA 0x5C56 # 0 +0x8CCB 0x5C57 # 0 +0x8CCC 0x5C58 # 0 +0x8CCD 0x5C5A # 0 +0x8CCE 0x5C5B # 0 +0x8CCF 0x5C5C # 0 +0x8CD0 0x5C5D # 0 +0x8CD1 0x5C5F # 0 +0x8CD2 0x5C62 # 0 +0x8CD3 0x5C64 # 0 +0x8CD4 0x5C67 # 0 +0x8CD5 0x5C68 # 0 +0x8CD6 0x5C69 # 0 +0x8CD7 0x5C6A # 0 +0x8CD8 0x5C6B # 0 +0x8CD9 0x5C6C # 0 +0x8CDA 0x5C6D # 0 +0x8CDB 0x5C70 # 0 +0x8CDC 0x5C72 # 0 +0x8CDD 0x5C73 # 0 +0x8CDE 0x5C74 # 0 +0x8CDF 0x5C75 # 0 +0x8CE0 0x5C76 # 0 +0x8CE1 0x5C77 # 0 +0x8CE2 0x5C78 # 0 +0x8CE3 0x5C7B # 0 +0x8CE4 0x5C7C # 0 +0x8CE5 0x5C7D # 0 +0x8CE6 0x5C7E # 0 +0x8CE7 0x5C80 # 0 +0x8CE8 0x5C83 # 0 +0x8CE9 0x5C84 # 0 +0x8CEA 0x5C85 # 0 +0x8CEB 0x5C86 # 0 +0x8CEC 0x5C87 # 0 +0x8CED 0x5C89 # 0 +0x8CEE 0x5C8A # 0 +0x8CEF 0x5C8B # 0 +0x8CF0 0x5C8E # 0 +0x8CF1 0x5C8F # 0 +0x8CF2 0x5C92 # 0 +0x8CF3 0x5C93 # 0 +0x8CF4 0x5C95 # 0 +0x8CF5 0x5C9D # 0 +0x8CF6 0x5C9E # 0 +0x8CF7 0x5C9F # 0 +0x8CF8 0x5CA0 # 0 +0x8CF9 0x5CA1 # 0 +0x8CFA 0x5CA4 # 0 +0x8CFB 0x5CA5 # 0 +0x8CFC 0x5CA6 # 0 +0x8CFD 0x5CA7 # 0 +0x8CFE 0x5CA8 # 0 +0x8D40 0x5CAA # 0 +0x8D41 0x5CAE # 0 +0x8D42 0x5CAF # 0 +0x8D43 0x5CB0 # 0 +0x8D44 0x5CB2 # 0 +0x8D45 0x5CB4 # 0 +0x8D46 0x5CB6 # 0 +0x8D47 0x5CB9 # 0 +0x8D48 0x5CBA # 0 +0x8D49 0x5CBB # 0 +0x8D4A 0x5CBC # 0 +0x8D4B 0x5CBE # 0 +0x8D4C 0x5CC0 # 0 +0x8D4D 0x5CC2 # 0 +0x8D4E 0x5CC3 # 0 +0x8D4F 0x5CC5 # 0 +0x8D50 0x5CC6 # 0 +0x8D51 0x5CC7 # 0 +0x8D52 0x5CC8 # 0 +0x8D53 0x5CC9 # 0 +0x8D54 0x5CCA # 0 +0x8D55 0x5CCC # 0 +0x8D56 0x5CCD # 0 +0x8D57 0x5CCE # 0 +0x8D58 0x5CCF # 0 +0x8D59 0x5CD0 # 0 +0x8D5A 0x5CD1 # 0 +0x8D5B 0x5CD3 # 0 +0x8D5C 0x5CD4 # 0 +0x8D5D 0x5CD5 # 0 +0x8D5E 0x5CD6 # 0 +0x8D5F 0x5CD7 # 0 +0x8D60 0x5CD8 # 0 +0x8D61 0x5CDA # 0 +0x8D62 0x5CDB # 0 +0x8D63 0x5CDC # 0 +0x8D64 0x5CDD # 0 +0x8D65 0x5CDE # 0 +0x8D66 0x5CDF # 0 +0x8D67 0x5CE0 # 0 +0x8D68 0x5CE2 # 0 +0x8D69 0x5CE3 # 0 +0x8D6A 0x5CE7 # 0 +0x8D6B 0x5CE9 # 0 +0x8D6C 0x5CEB # 0 +0x8D6D 0x5CEC # 0 +0x8D6E 0x5CEE # 0 +0x8D6F 0x5CEF # 0 +0x8D70 0x5CF1 # 0 +0x8D71 0x5CF2 # 0 +0x8D72 0x5CF3 # 0 +0x8D73 0x5CF4 # 0 +0x8D74 0x5CF5 # 0 +0x8D75 0x5CF6 # 0 +0x8D76 0x5CF7 # 0 +0x8D77 0x5CF8 # 0 +0x8D78 0x5CF9 # 0 +0x8D79 0x5CFA # 0 +0x8D7A 0x5CFC # 0 +0x8D7B 0x5CFD # 0 +0x8D7C 0x5CFE # 0 +0x8D7D 0x5CFF # 0 +0x8D7E 0x5D00 # 0 +0x8D80 0x5D01 # 0 +0x8D81 0x5D04 # 0 +0x8D82 0x5D05 # 0 +0x8D83 0x5D08 # 0 +0x8D84 0x5D09 # 0 +0x8D85 0x5D0A # 0 +0x8D86 0x5D0B # 0 +0x8D87 0x5D0C # 0 +0x8D88 0x5D0D # 0 +0x8D89 0x5D0F # 0 +0x8D8A 0x5D10 # 0 +0x8D8B 0x5D11 # 0 +0x8D8C 0x5D12 # 0 +0x8D8D 0x5D13 # 0 +0x8D8E 0x5D15 # 0 +0x8D8F 0x5D17 # 0 +0x8D90 0x5D18 # 0 +0x8D91 0x5D19 # 0 +0x8D92 0x5D1A # 0 +0x8D93 0x5D1C # 0 +0x8D94 0x5D1D # 0 +0x8D95 0x5D1F # 0 +0x8D96 0x5D20 # 0 +0x8D97 0x5D21 # 0 +0x8D98 0x5D22 # 0 +0x8D99 0x5D23 # 0 +0x8D9A 0x5D25 # 0 +0x8D9B 0x5D28 # 0 +0x8D9C 0x5D2A # 0 +0x8D9D 0x5D2B # 0 +0x8D9E 0x5D2C # 0 +0x8D9F 0x5D2F # 0 +0x8DA0 0x5D30 # 0 +0x8DA1 0x5D31 # 0 +0x8DA2 0x5D32 # 0 +0x8DA3 0x5D33 # 0 +0x8DA4 0x5D35 # 0 +0x8DA5 0x5D36 # 0 +0x8DA6 0x5D37 # 0 +0x8DA7 0x5D38 # 0 +0x8DA8 0x5D39 # 0 +0x8DA9 0x5D3A # 0 +0x8DAA 0x5D3B # 0 +0x8DAB 0x5D3C # 0 +0x8DAC 0x5D3F # 0 +0x8DAD 0x5D40 # 0 +0x8DAE 0x5D41 # 0 +0x8DAF 0x5D42 # 0 +0x8DB0 0x5D43 # 0 +0x8DB1 0x5D44 # 0 +0x8DB2 0x5D45 # 0 +0x8DB3 0x5D46 # 0 +0x8DB4 0x5D48 # 0 +0x8DB5 0x5D49 # 0 +0x8DB6 0x5D4D # 0 +0x8DB7 0x5D4E # 0 +0x8DB8 0x5D4F # 0 +0x8DB9 0x5D50 # 0 +0x8DBA 0x5D51 # 0 +0x8DBB 0x5D52 # 0 +0x8DBC 0x5D53 # 0 +0x8DBD 0x5D54 # 0 +0x8DBE 0x5D55 # 0 +0x8DBF 0x5D56 # 0 +0x8DC0 0x5D57 # 0 +0x8DC1 0x5D59 # 0 +0x8DC2 0x5D5A # 0 +0x8DC3 0x5D5C # 0 +0x8DC4 0x5D5E # 0 +0x8DC5 0x5D5F # 0 +0x8DC6 0x5D60 # 0 +0x8DC7 0x5D61 # 0 +0x8DC8 0x5D62 # 0 +0x8DC9 0x5D63 # 0 +0x8DCA 0x5D64 # 0 +0x8DCB 0x5D65 # 0 +0x8DCC 0x5D66 # 0 +0x8DCD 0x5D67 # 0 +0x8DCE 0x5D68 # 0 +0x8DCF 0x5D6A # 0 +0x8DD0 0x5D6D # 0 +0x8DD1 0x5D6E # 0 +0x8DD2 0x5D70 # 0 +0x8DD3 0x5D71 # 0 +0x8DD4 0x5D72 # 0 +0x8DD5 0x5D73 # 0 +0x8DD6 0x5D75 # 0 +0x8DD7 0x5D76 # 0 +0x8DD8 0x5D77 # 0 +0x8DD9 0x5D78 # 0 +0x8DDA 0x5D79 # 0 +0x8DDB 0x5D7A # 0 +0x8DDC 0x5D7B # 0 +0x8DDD 0x5D7C # 0 +0x8DDE 0x5D7D # 0 +0x8DDF 0x5D7E # 0 +0x8DE0 0x5D7F # 0 +0x8DE1 0x5D80 # 0 +0x8DE2 0x5D81 # 0 +0x8DE3 0x5D83 # 0 +0x8DE4 0x5D84 # 0 +0x8DE5 0x5D85 # 0 +0x8DE6 0x5D86 # 0 +0x8DE7 0x5D87 # 0 +0x8DE8 0x5D88 # 0 +0x8DE9 0x5D89 # 0 +0x8DEA 0x5D8A # 0 +0x8DEB 0x5D8B # 0 +0x8DEC 0x5D8C # 0 +0x8DED 0x5D8D # 0 +0x8DEE 0x5D8E # 0 +0x8DEF 0x5D8F # 0 +0x8DF0 0x5D90 # 0 +0x8DF1 0x5D91 # 0 +0x8DF2 0x5D92 # 0 +0x8DF3 0x5D93 # 0 +0x8DF4 0x5D94 # 0 +0x8DF5 0x5D95 # 0 +0x8DF6 0x5D96 # 0 +0x8DF7 0x5D97 # 0 +0x8DF8 0x5D98 # 0 +0x8DF9 0x5D9A # 0 +0x8DFA 0x5D9B # 0 +0x8DFB 0x5D9C # 0 +0x8DFC 0x5D9E # 0 +0x8DFD 0x5D9F # 0 +0x8DFE 0x5DA0 # 0 +0x8E40 0x5DA1 # 0 +0x8E41 0x5DA2 # 0 +0x8E42 0x5DA3 # 0 +0x8E43 0x5DA4 # 0 +0x8E44 0x5DA5 # 0 +0x8E45 0x5DA6 # 0 +0x8E46 0x5DA7 # 0 +0x8E47 0x5DA8 # 0 +0x8E48 0x5DA9 # 0 +0x8E49 0x5DAA # 0 +0x8E4A 0x5DAB # 0 +0x8E4B 0x5DAC # 0 +0x8E4C 0x5DAD # 0 +0x8E4D 0x5DAE # 0 +0x8E4E 0x5DAF # 0 +0x8E4F 0x5DB0 # 0 +0x8E50 0x5DB1 # 0 +0x8E51 0x5DB2 # 0 +0x8E52 0x5DB3 # 0 +0x8E53 0x5DB4 # 0 +0x8E54 0x5DB5 # 0 +0x8E55 0x5DB6 # 0 +0x8E56 0x5DB8 # 0 +0x8E57 0x5DB9 # 0 +0x8E58 0x5DBA # 0 +0x8E59 0x5DBB # 0 +0x8E5A 0x5DBC # 0 +0x8E5B 0x5DBD # 0 +0x8E5C 0x5DBE # 0 +0x8E5D 0x5DBF # 0 +0x8E5E 0x5DC0 # 0 +0x8E5F 0x5DC1 # 0 +0x8E60 0x5DC2 # 0 +0x8E61 0x5DC3 # 0 +0x8E62 0x5DC4 # 0 +0x8E63 0x5DC6 # 0 +0x8E64 0x5DC7 # 0 +0x8E65 0x5DC8 # 0 +0x8E66 0x5DC9 # 0 +0x8E67 0x5DCA # 0 +0x8E68 0x5DCB # 0 +0x8E69 0x5DCC # 0 +0x8E6A 0x5DCE # 0 +0x8E6B 0x5DCF # 0 +0x8E6C 0x5DD0 # 0 +0x8E6D 0x5DD1 # 0 +0x8E6E 0x5DD2 # 0 +0x8E6F 0x5DD3 # 0 +0x8E70 0x5DD4 # 0 +0x8E71 0x5DD5 # 0 +0x8E72 0x5DD6 # 0 +0x8E73 0x5DD7 # 0 +0x8E74 0x5DD8 # 0 +0x8E75 0x5DD9 # 0 +0x8E76 0x5DDA # 0 +0x8E77 0x5DDC # 0 +0x8E78 0x5DDF # 0 +0x8E79 0x5DE0 # 0 +0x8E7A 0x5DE3 # 0 +0x8E7B 0x5DE4 # 0 +0x8E7C 0x5DEA # 0 +0x8E7D 0x5DEC # 0 +0x8E7E 0x5DED # 0 +0x8E80 0x5DF0 # 0 +0x8E81 0x5DF5 # 0 +0x8E82 0x5DF6 # 0 +0x8E83 0x5DF8 # 0 +0x8E84 0x5DF9 # 0 +0x8E85 0x5DFA # 0 +0x8E86 0x5DFB # 0 +0x8E87 0x5DFC # 0 +0x8E88 0x5DFF # 0 +0x8E89 0x5E00 # 0 +0x8E8A 0x5E04 # 0 +0x8E8B 0x5E07 # 0 +0x8E8C 0x5E09 # 0 +0x8E8D 0x5E0A # 0 +0x8E8E 0x5E0B # 0 +0x8E8F 0x5E0D # 0 +0x8E90 0x5E0E # 0 +0x8E91 0x5E12 # 0 +0x8E92 0x5E13 # 0 +0x8E93 0x5E17 # 0 +0x8E94 0x5E1E # 0 +0x8E95 0x5E1F # 0 +0x8E96 0x5E20 # 0 +0x8E97 0x5E21 # 0 +0x8E98 0x5E22 # 0 +0x8E99 0x5E23 # 0 +0x8E9A 0x5E24 # 0 +0x8E9B 0x5E25 # 0 +0x8E9C 0x5E28 # 0 +0x8E9D 0x5E29 # 0 +0x8E9E 0x5E2A # 0 +0x8E9F 0x5E2B # 0 +0x8EA0 0x5E2C # 0 +0x8EA1 0x5E2F # 0 +0x8EA2 0x5E30 # 0 +0x8EA3 0x5E32 # 0 +0x8EA4 0x5E33 # 0 +0x8EA5 0x5E34 # 0 +0x8EA6 0x5E35 # 0 +0x8EA7 0x5E36 # 0 +0x8EA8 0x5E39 # 0 +0x8EA9 0x5E3A # 0 +0x8EAA 0x5E3E # 0 +0x8EAB 0x5E3F # 0 +0x8EAC 0x5E40 # 0 +0x8EAD 0x5E41 # 0 +0x8EAE 0x5E43 # 0 +0x8EAF 0x5E46 # 0 +0x8EB0 0x5E47 # 0 +0x8EB1 0x5E48 # 0 +0x8EB2 0x5E49 # 0 +0x8EB3 0x5E4A # 0 +0x8EB4 0x5E4B # 0 +0x8EB5 0x5E4D # 0 +0x8EB6 0x5E4E # 0 +0x8EB7 0x5E4F # 0 +0x8EB8 0x5E50 # 0 +0x8EB9 0x5E51 # 0 +0x8EBA 0x5E52 # 0 +0x8EBB 0x5E53 # 0 +0x8EBC 0x5E56 # 0 +0x8EBD 0x5E57 # 0 +0x8EBE 0x5E58 # 0 +0x8EBF 0x5E59 # 0 +0x8EC0 0x5E5A # 0 +0x8EC1 0x5E5C # 0 +0x8EC2 0x5E5D # 0 +0x8EC3 0x5E5F # 0 +0x8EC4 0x5E60 # 0 +0x8EC5 0x5E63 # 0 +0x8EC6 0x5E64 # 0 +0x8EC7 0x5E65 # 0 +0x8EC8 0x5E66 # 0 +0x8EC9 0x5E67 # 0 +0x8ECA 0x5E68 # 0 +0x8ECB 0x5E69 # 0 +0x8ECC 0x5E6A # 0 +0x8ECD 0x5E6B # 0 +0x8ECE 0x5E6C # 0 +0x8ECF 0x5E6D # 0 +0x8ED0 0x5E6E # 0 +0x8ED1 0x5E6F # 0 +0x8ED2 0x5E70 # 0 +0x8ED3 0x5E71 # 0 +0x8ED4 0x5E75 # 0 +0x8ED5 0x5E77 # 0 +0x8ED6 0x5E79 # 0 +0x8ED7 0x5E7E # 0 +0x8ED8 0x5E81 # 0 +0x8ED9 0x5E82 # 0 +0x8EDA 0x5E83 # 0 +0x8EDB 0x5E85 # 0 +0x8EDC 0x5E88 # 0 +0x8EDD 0x5E89 # 0 +0x8EDE 0x5E8C # 0 +0x8EDF 0x5E8D # 0 +0x8EE0 0x5E8E # 0 +0x8EE1 0x5E92 # 0 +0x8EE2 0x5E98 # 0 +0x8EE3 0x5E9B # 0 +0x8EE4 0x5E9D # 0 +0x8EE5 0x5EA1 # 0 +0x8EE6 0x5EA2 # 0 +0x8EE7 0x5EA3 # 0 +0x8EE8 0x5EA4 # 0 +0x8EE9 0x5EA8 # 0 +0x8EEA 0x5EA9 # 0 +0x8EEB 0x5EAA # 0 +0x8EEC 0x5EAB # 0 +0x8EED 0x5EAC # 0 +0x8EEE 0x5EAE # 0 +0x8EEF 0x5EAF # 0 +0x8EF0 0x5EB0 # 0 +0x8EF1 0x5EB1 # 0 +0x8EF2 0x5EB2 # 0 +0x8EF3 0x5EB4 # 0 +0x8EF4 0x5EBA # 0 +0x8EF5 0x5EBB # 0 +0x8EF6 0x5EBC # 0 +0x8EF7 0x5EBD # 0 +0x8EF8 0x5EBF # 0 +0x8EF9 0x5EC0 # 0 +0x8EFA 0x5EC1 # 0 +0x8EFB 0x5EC2 # 0 +0x8EFC 0x5EC3 # 0 +0x8EFD 0x5EC4 # 0 +0x8EFE 0x5EC5 # 0 +0x8F40 0x5EC6 # 0 +0x8F41 0x5EC7 # 0 +0x8F42 0x5EC8 # 0 +0x8F43 0x5ECB # 0 +0x8F44 0x5ECC # 0 +0x8F45 0x5ECD # 0 +0x8F46 0x5ECE # 0 +0x8F47 0x5ECF # 0 +0x8F48 0x5ED0 # 0 +0x8F49 0x5ED4 # 0 +0x8F4A 0x5ED5 # 0 +0x8F4B 0x5ED7 # 0 +0x8F4C 0x5ED8 # 0 +0x8F4D 0x5ED9 # 0 +0x8F4E 0x5EDA # 0 +0x8F4F 0x5EDC # 0 +0x8F50 0x5EDD # 0 +0x8F51 0x5EDE # 0 +0x8F52 0x5EDF # 0 +0x8F53 0x5EE0 # 0 +0x8F54 0x5EE1 # 0 +0x8F55 0x5EE2 # 0 +0x8F56 0x5EE3 # 0 +0x8F57 0x5EE4 # 0 +0x8F58 0x5EE5 # 0 +0x8F59 0x5EE6 # 0 +0x8F5A 0x5EE7 # 0 +0x8F5B 0x5EE9 # 0 +0x8F5C 0x5EEB # 0 +0x8F5D 0x5EEC # 0 +0x8F5E 0x5EED # 0 +0x8F5F 0x5EEE # 0 +0x8F60 0x5EEF # 0 +0x8F61 0x5EF0 # 0 +0x8F62 0x5EF1 # 0 +0x8F63 0x5EF2 # 0 +0x8F64 0x5EF3 # 0 +0x8F65 0x5EF5 # 0 +0x8F66 0x5EF8 # 0 +0x8F67 0x5EF9 # 0 +0x8F68 0x5EFB # 0 +0x8F69 0x5EFC # 0 +0x8F6A 0x5EFD # 0 +0x8F6B 0x5F05 # 0 +0x8F6C 0x5F06 # 0 +0x8F6D 0x5F07 # 0 +0x8F6E 0x5F09 # 0 +0x8F6F 0x5F0C # 0 +0x8F70 0x5F0D # 0 +0x8F71 0x5F0E # 0 +0x8F72 0x5F10 # 0 +0x8F73 0x5F12 # 0 +0x8F74 0x5F14 # 0 +0x8F75 0x5F16 # 0 +0x8F76 0x5F19 # 0 +0x8F77 0x5F1A # 0 +0x8F78 0x5F1C # 0 +0x8F79 0x5F1D # 0 +0x8F7A 0x5F1E # 0 +0x8F7B 0x5F21 # 0 +0x8F7C 0x5F22 # 0 +0x8F7D 0x5F23 # 0 +0x8F7E 0x5F24 # 0 +0x8F80 0x5F28 # 0 +0x8F81 0x5F2B # 0 +0x8F82 0x5F2C # 0 +0x8F83 0x5F2E # 0 +0x8F84 0x5F30 # 0 +0x8F85 0x5F32 # 0 +0x8F86 0x5F33 # 0 +0x8F87 0x5F34 # 0 +0x8F88 0x5F35 # 0 +0x8F89 0x5F36 # 0 +0x8F8A 0x5F37 # 0 +0x8F8B 0x5F38 # 0 +0x8F8C 0x5F3B # 0 +0x8F8D 0x5F3D # 0 +0x8F8E 0x5F3E # 0 +0x8F8F 0x5F3F # 0 +0x8F90 0x5F41 # 0 +0x8F91 0x5F42 # 0 +0x8F92 0x5F43 # 0 +0x8F93 0x5F44 # 0 +0x8F94 0x5F45 # 0 +0x8F95 0x5F46 # 0 +0x8F96 0x5F47 # 0 +0x8F97 0x5F48 # 0 +0x8F98 0x5F49 # 0 +0x8F99 0x5F4A # 0 +0x8F9A 0x5F4B # 0 +0x8F9B 0x5F4C # 0 +0x8F9C 0x5F4D # 0 +0x8F9D 0x5F4E # 0 +0x8F9E 0x5F4F # 0 +0x8F9F 0x5F51 # 0 +0x8FA0 0x5F54 # 0 +0x8FA1 0x5F59 # 0 +0x8FA2 0x5F5A # 0 +0x8FA3 0x5F5B # 0 +0x8FA4 0x5F5C # 0 +0x8FA5 0x5F5E # 0 +0x8FA6 0x5F5F # 0 +0x8FA7 0x5F60 # 0 +0x8FA8 0x5F63 # 0 +0x8FA9 0x5F65 # 0 +0x8FAA 0x5F67 # 0 +0x8FAB 0x5F68 # 0 +0x8FAC 0x5F6B # 0 +0x8FAD 0x5F6E # 0 +0x8FAE 0x5F6F # 0 +0x8FAF 0x5F72 # 0 +0x8FB0 0x5F74 # 0 +0x8FB1 0x5F75 # 0 +0x8FB2 0x5F76 # 0 +0x8FB3 0x5F78 # 0 +0x8FB4 0x5F7A # 0 +0x8FB5 0x5F7D # 0 +0x8FB6 0x5F7E # 0 +0x8FB7 0x5F7F # 0 +0x8FB8 0x5F83 # 0 +0x8FB9 0x5F86 # 0 +0x8FBA 0x5F8D # 0 +0x8FBB 0x5F8E # 0 +0x8FBC 0x5F8F # 0 +0x8FBD 0x5F91 # 0 +0x8FBE 0x5F93 # 0 +0x8FBF 0x5F94 # 0 +0x8FC0 0x5F96 # 0 +0x8FC1 0x5F9A # 0 +0x8FC2 0x5F9B # 0 +0x8FC3 0x5F9D # 0 +0x8FC4 0x5F9E # 0 +0x8FC5 0x5F9F # 0 +0x8FC6 0x5FA0 # 0 +0x8FC7 0x5FA2 # 0 +0x8FC8 0x5FA3 # 0 +0x8FC9 0x5FA4 # 0 +0x8FCA 0x5FA5 # 0 +0x8FCB 0x5FA6 # 0 +0x8FCC 0x5FA7 # 0 +0x8FCD 0x5FA9 # 0 +0x8FCE 0x5FAB # 0 +0x8FCF 0x5FAC # 0 +0x8FD0 0x5FAF # 0 +0x8FD1 0x5FB0 # 0 +0x8FD2 0x5FB1 # 0 +0x8FD3 0x5FB2 # 0 +0x8FD4 0x5FB3 # 0 +0x8FD5 0x5FB4 # 0 +0x8FD6 0x5FB6 # 0 +0x8FD7 0x5FB8 # 0 +0x8FD8 0x5FB9 # 0 +0x8FD9 0x5FBA # 0 +0x8FDA 0x5FBB # 0 +0x8FDB 0x5FBE # 0 +0x8FDC 0x5FBF # 0 +0x8FDD 0x5FC0 # 0 +0x8FDE 0x5FC1 # 0 +0x8FDF 0x5FC2 # 0 +0x8FE0 0x5FC7 # 0 +0x8FE1 0x5FC8 # 0 +0x8FE2 0x5FCA # 0 +0x8FE3 0x5FCB # 0 +0x8FE4 0x5FCE # 0 +0x8FE5 0x5FD3 # 0 +0x8FE6 0x5FD4 # 0 +0x8FE7 0x5FD5 # 0 +0x8FE8 0x5FDA # 0 +0x8FE9 0x5FDB # 0 +0x8FEA 0x5FDC # 0 +0x8FEB 0x5FDE # 0 +0x8FEC 0x5FDF # 0 +0x8FED 0x5FE2 # 0 +0x8FEE 0x5FE3 # 0 +0x8FEF 0x5FE5 # 0 +0x8FF0 0x5FE6 # 0 +0x8FF1 0x5FE8 # 0 +0x8FF2 0x5FE9 # 0 +0x8FF3 0x5FEC # 0 +0x8FF4 0x5FEF # 0 +0x8FF5 0x5FF0 # 0 +0x8FF6 0x5FF2 # 0 +0x8FF7 0x5FF3 # 0 +0x8FF8 0x5FF4 # 0 +0x8FF9 0x5FF6 # 0 +0x8FFA 0x5FF7 # 0 +0x8FFB 0x5FF9 # 0 +0x8FFC 0x5FFA # 0 +0x8FFD 0x5FFC # 0 +0x8FFE 0x6007 # 0 +0x9040 0x6008 # 0 +0x9041 0x6009 # 0 +0x9042 0x600B # 0 +0x9043 0x600C # 0 +0x9044 0x6010 # 0 +0x9045 0x6011 # 0 +0x9046 0x6013 # 0 +0x9047 0x6017 # 0 +0x9048 0x6018 # 0 +0x9049 0x601A # 0 +0x904A 0x601E # 0 +0x904B 0x601F # 0 +0x904C 0x6022 # 0 +0x904D 0x6023 # 0 +0x904E 0x6024 # 0 +0x904F 0x602C # 0 +0x9050 0x602D # 0 +0x9051 0x602E # 0 +0x9052 0x6030 # 0 +0x9053 0x6031 # 0 +0x9054 0x6032 # 0 +0x9055 0x6033 # 0 +0x9056 0x6034 # 0 +0x9057 0x6036 # 0 +0x9058 0x6037 # 0 +0x9059 0x6038 # 0 +0x905A 0x6039 # 0 +0x905B 0x603A # 0 +0x905C 0x603D # 0 +0x905D 0x603E # 0 +0x905E 0x6040 # 0 +0x905F 0x6044 # 0 +0x9060 0x6045 # 0 +0x9061 0x6046 # 0 +0x9062 0x6047 # 0 +0x9063 0x6048 # 0 +0x9064 0x6049 # 0 +0x9065 0x604A # 0 +0x9066 0x604C # 0 +0x9067 0x604E # 0 +0x9068 0x604F # 0 +0x9069 0x6051 # 0 +0x906A 0x6053 # 0 +0x906B 0x6054 # 0 +0x906C 0x6056 # 0 +0x906D 0x6057 # 0 +0x906E 0x6058 # 0 +0x906F 0x605B # 0 +0x9070 0x605C # 0 +0x9071 0x605E # 0 +0x9072 0x605F # 0 +0x9073 0x6060 # 0 +0x9074 0x6061 # 0 +0x9075 0x6065 # 0 +0x9076 0x6066 # 0 +0x9077 0x606E # 0 +0x9078 0x6071 # 0 +0x9079 0x6072 # 0 +0x907A 0x6074 # 0 +0x907B 0x6075 # 0 +0x907C 0x6077 # 0 +0x907D 0x607E # 0 +0x907E 0x6080 # 0 +0x9080 0x6081 # 0 +0x9081 0x6082 # 0 +0x9082 0x6085 # 0 +0x9083 0x6086 # 0 +0x9084 0x6087 # 0 +0x9085 0x6088 # 0 +0x9086 0x608A # 0 +0x9087 0x608B # 0 +0x9088 0x608E # 0 +0x9089 0x608F # 0 +0x908A 0x6090 # 0 +0x908B 0x6091 # 0 +0x908C 0x6093 # 0 +0x908D 0x6095 # 0 +0x908E 0x6097 # 0 +0x908F 0x6098 # 0 +0x9090 0x6099 # 0 +0x9091 0x609C # 0 +0x9092 0x609E # 0 +0x9093 0x60A1 # 0 +0x9094 0x60A2 # 0 +0x9095 0x60A4 # 0 +0x9096 0x60A5 # 0 +0x9097 0x60A7 # 0 +0x9098 0x60A9 # 0 +0x9099 0x60AA # 0 +0x909A 0x60AE # 0 +0x909B 0x60B0 # 0 +0x909C 0x60B3 # 0 +0x909D 0x60B5 # 0 +0x909E 0x60B6 # 0 +0x909F 0x60B7 # 0 +0x90A0 0x60B9 # 0 +0x90A1 0x60BA # 0 +0x90A2 0x60BD # 0 +0x90A3 0x60BE # 0 +0x90A4 0x60BF # 0 +0x90A5 0x60C0 # 0 +0x90A6 0x60C1 # 0 +0x90A7 0x60C2 # 0 +0x90A8 0x60C3 # 0 +0x90A9 0x60C4 # 0 +0x90AA 0x60C7 # 0 +0x90AB 0x60C8 # 0 +0x90AC 0x60C9 # 0 +0x90AD 0x60CC # 0 +0x90AE 0x60CD # 0 +0x90AF 0x60CE # 0 +0x90B0 0x60CF # 0 +0x90B1 0x60D0 # 0 +0x90B2 0x60D2 # 0 +0x90B3 0x60D3 # 0 +0x90B4 0x60D4 # 0 +0x90B5 0x60D6 # 0 +0x90B6 0x60D7 # 0 +0x90B7 0x60D9 # 0 +0x90B8 0x60DB # 0 +0x90B9 0x60DE # 0 +0x90BA 0x60E1 # 0 +0x90BB 0x60E2 # 0 +0x90BC 0x60E3 # 0 +0x90BD 0x60E4 # 0 +0x90BE 0x60E5 # 0 +0x90BF 0x60EA # 0 +0x90C0 0x60F1 # 0 +0x90C1 0x60F2 # 0 +0x90C2 0x60F5 # 0 +0x90C3 0x60F7 # 0 +0x90C4 0x60F8 # 0 +0x90C5 0x60FB # 0 +0x90C6 0x60FC # 0 +0x90C7 0x60FD # 0 +0x90C8 0x60FE # 0 +0x90C9 0x60FF # 0 +0x90CA 0x6102 # 0 +0x90CB 0x6103 # 0 +0x90CC 0x6104 # 0 +0x90CD 0x6105 # 0 +0x90CE 0x6107 # 0 +0x90CF 0x610A # 0 +0x90D0 0x610B # 0 +0x90D1 0x610C # 0 +0x90D2 0x6110 # 0 +0x90D3 0x6111 # 0 +0x90D4 0x6112 # 0 +0x90D5 0x6113 # 0 +0x90D6 0x6114 # 0 +0x90D7 0x6116 # 0 +0x90D8 0x6117 # 0 +0x90D9 0x6118 # 0 +0x90DA 0x6119 # 0 +0x90DB 0x611B # 0 +0x90DC 0x611C # 0 +0x90DD 0x611D # 0 +0x90DE 0x611E # 0 +0x90DF 0x6121 # 0 +0x90E0 0x6122 # 0 +0x90E1 0x6125 # 0 +0x90E2 0x6128 # 0 +0x90E3 0x6129 # 0 +0x90E4 0x612A # 0 +0x90E5 0x612C # 0 +0x90E6 0x612D # 0 +0x90E7 0x612E # 0 +0x90E8 0x612F # 0 +0x90E9 0x6130 # 0 +0x90EA 0x6131 # 0 +0x90EB 0x6132 # 0 +0x90EC 0x6133 # 0 +0x90ED 0x6134 # 0 +0x90EE 0x6135 # 0 +0x90EF 0x6136 # 0 +0x90F0 0x6137 # 0 +0x90F1 0x6138 # 0 +0x90F2 0x6139 # 0 +0x90F3 0x613A # 0 +0x90F4 0x613B # 0 +0x90F5 0x613C # 0 +0x90F6 0x613D # 0 +0x90F7 0x613E # 0 +0x90F8 0x6140 # 0 +0x90F9 0x6141 # 0 +0x90FA 0x6142 # 0 +0x90FB 0x6143 # 0 +0x90FC 0x6144 # 0 +0x90FD 0x6145 # 0 +0x90FE 0x6146 # 0 +0x9140 0x6147 # 0 +0x9141 0x6149 # 0 +0x9142 0x614B # 0 +0x9143 0x614D # 0 +0x9144 0x614F # 0 +0x9145 0x6150 # 0 +0x9146 0x6152 # 0 +0x9147 0x6153 # 0 +0x9148 0x6154 # 0 +0x9149 0x6156 # 0 +0x914A 0x6157 # 0 +0x914B 0x6158 # 0 +0x914C 0x6159 # 0 +0x914D 0x615A # 0 +0x914E 0x615B # 0 +0x914F 0x615C # 0 +0x9150 0x615E # 0 +0x9151 0x615F # 0 +0x9152 0x6160 # 0 +0x9153 0x6161 # 0 +0x9154 0x6163 # 0 +0x9155 0x6164 # 0 +0x9156 0x6165 # 0 +0x9157 0x6166 # 0 +0x9158 0x6169 # 0 +0x9159 0x616A # 0 +0x915A 0x616B # 0 +0x915B 0x616C # 0 +0x915C 0x616D # 0 +0x915D 0x616E # 0 +0x915E 0x616F # 0 +0x915F 0x6171 # 0 +0x9160 0x6172 # 0 +0x9161 0x6173 # 0 +0x9162 0x6174 # 0 +0x9163 0x6176 # 0 +0x9164 0x6178 # 0 +0x9165 0x6179 # 0 +0x9166 0x617A # 0 +0x9167 0x617B # 0 +0x9168 0x617C # 0 +0x9169 0x617D # 0 +0x916A 0x617E # 0 +0x916B 0x617F # 0 +0x916C 0x6180 # 0 +0x916D 0x6181 # 0 +0x916E 0x6182 # 0 +0x916F 0x6183 # 0 +0x9170 0x6184 # 0 +0x9171 0x6185 # 0 +0x9172 0x6186 # 0 +0x9173 0x6187 # 0 +0x9174 0x6188 # 0 +0x9175 0x6189 # 0 +0x9176 0x618A # 0 +0x9177 0x618C # 0 +0x9178 0x618D # 0 +0x9179 0x618F # 0 +0x917A 0x6190 # 0 +0x917B 0x6191 # 0 +0x917C 0x6192 # 0 +0x917D 0x6193 # 0 +0x917E 0x6195 # 0 +0x9180 0x6196 # 0 +0x9181 0x6197 # 0 +0x9182 0x6198 # 0 +0x9183 0x6199 # 0 +0x9184 0x619A # 0 +0x9185 0x619B # 0 +0x9186 0x619C # 0 +0x9187 0x619E # 0 +0x9188 0x619F # 0 +0x9189 0x61A0 # 0 +0x918A 0x61A1 # 0 +0x918B 0x61A2 # 0 +0x918C 0x61A3 # 0 +0x918D 0x61A4 # 0 +0x918E 0x61A5 # 0 +0x918F 0x61A6 # 0 +0x9190 0x61AA # 0 +0x9191 0x61AB # 0 +0x9192 0x61AD # 0 +0x9193 0x61AE # 0 +0x9194 0x61AF # 0 +0x9195 0x61B0 # 0 +0x9196 0x61B1 # 0 +0x9197 0x61B2 # 0 +0x9198 0x61B3 # 0 +0x9199 0x61B4 # 0 +0x919A 0x61B5 # 0 +0x919B 0x61B6 # 0 +0x919C 0x61B8 # 0 +0x919D 0x61B9 # 0 +0x919E 0x61BA # 0 +0x919F 0x61BB # 0 +0x91A0 0x61BC # 0 +0x91A1 0x61BD # 0 +0x91A2 0x61BF # 0 +0x91A3 0x61C0 # 0 +0x91A4 0x61C1 # 0 +0x91A5 0x61C3 # 0 +0x91A6 0x61C4 # 0 +0x91A7 0x61C5 # 0 +0x91A8 0x61C6 # 0 +0x91A9 0x61C7 # 0 +0x91AA 0x61C9 # 0 +0x91AB 0x61CC # 0 +0x91AC 0x61CD # 0 +0x91AD 0x61CE # 0 +0x91AE 0x61CF # 0 +0x91AF 0x61D0 # 0 +0x91B0 0x61D3 # 0 +0x91B1 0x61D5 # 0 +0x91B2 0x61D6 # 0 +0x91B3 0x61D7 # 0 +0x91B4 0x61D8 # 0 +0x91B5 0x61D9 # 0 +0x91B6 0x61DA # 0 +0x91B7 0x61DB # 0 +0x91B8 0x61DC # 0 +0x91B9 0x61DD # 0 +0x91BA 0x61DE # 0 +0x91BB 0x61DF # 0 +0x91BC 0x61E0 # 0 +0x91BD 0x61E1 # 0 +0x91BE 0x61E2 # 0 +0x91BF 0x61E3 # 0 +0x91C0 0x61E4 # 0 +0x91C1 0x61E5 # 0 +0x91C2 0x61E7 # 0 +0x91C3 0x61E8 # 0 +0x91C4 0x61E9 # 0 +0x91C5 0x61EA # 0 +0x91C6 0x61EB # 0 +0x91C7 0x61EC # 0 +0x91C8 0x61ED # 0 +0x91C9 0x61EE # 0 +0x91CA 0x61EF # 0 +0x91CB 0x61F0 # 0 +0x91CC 0x61F1 # 0 +0x91CD 0x61F2 # 0 +0x91CE 0x61F3 # 0 +0x91CF 0x61F4 # 0 +0x91D0 0x61F6 # 0 +0x91D1 0x61F7 # 0 +0x91D2 0x61F8 # 0 +0x91D3 0x61F9 # 0 +0x91D4 0x61FA # 0 +0x91D5 0x61FB # 0 +0x91D6 0x61FC # 0 +0x91D7 0x61FD # 0 +0x91D8 0x61FE # 0 +0x91D9 0x6200 # 0 +0x91DA 0x6201 # 0 +0x91DB 0x6202 # 0 +0x91DC 0x6203 # 0 +0x91DD 0x6204 # 0 +0x91DE 0x6205 # 0 +0x91DF 0x6207 # 0 +0x91E0 0x6209 # 0 +0x91E1 0x6213 # 0 +0x91E2 0x6214 # 0 +0x91E3 0x6219 # 0 +0x91E4 0x621C # 0 +0x91E5 0x621D # 0 +0x91E6 0x621E # 0 +0x91E7 0x6220 # 0 +0x91E8 0x6223 # 0 +0x91E9 0x6226 # 0 +0x91EA 0x6227 # 0 +0x91EB 0x6228 # 0 +0x91EC 0x6229 # 0 +0x91ED 0x622B # 0 +0x91EE 0x622D # 0 +0x91EF 0x622F # 0 +0x91F0 0x6230 # 0 +0x91F1 0x6231 # 0 +0x91F2 0x6232 # 0 +0x91F3 0x6235 # 0 +0x91F4 0x6236 # 0 +0x91F5 0x6238 # 0 +0x91F6 0x6239 # 0 +0x91F7 0x623A # 0 +0x91F8 0x623B # 0 +0x91F9 0x623C # 0 +0x91FA 0x6242 # 0 +0x91FB 0x6244 # 0 +0x91FC 0x6245 # 0 +0x91FD 0x6246 # 0 +0x91FE 0x624A # 0 +0x9240 0x624F # 0 +0x9241 0x6250 # 0 +0x9242 0x6255 # 0 +0x9243 0x6256 # 0 +0x9244 0x6257 # 0 +0x9245 0x6259 # 0 +0x9246 0x625A # 0 +0x9247 0x625C # 0 +0x9248 0x625D # 0 +0x9249 0x625E # 0 +0x924A 0x625F # 0 +0x924B 0x6260 # 0 +0x924C 0x6261 # 0 +0x924D 0x6262 # 0 +0x924E 0x6264 # 0 +0x924F 0x6265 # 0 +0x9250 0x6268 # 0 +0x9251 0x6271 # 0 +0x9252 0x6272 # 0 +0x9253 0x6274 # 0 +0x9254 0x6275 # 0 +0x9255 0x6277 # 0 +0x9256 0x6278 # 0 +0x9257 0x627A # 0 +0x9258 0x627B # 0 +0x9259 0x627D # 0 +0x925A 0x6281 # 0 +0x925B 0x6282 # 0 +0x925C 0x6283 # 0 +0x925D 0x6285 # 0 +0x925E 0x6286 # 0 +0x925F 0x6287 # 0 +0x9260 0x6288 # 0 +0x9261 0x628B # 0 +0x9262 0x628C # 0 +0x9263 0x628D # 0 +0x9264 0x628E # 0 +0x9265 0x628F # 0 +0x9266 0x6290 # 0 +0x9267 0x6294 # 0 +0x9268 0x6299 # 0 +0x9269 0x629C # 0 +0x926A 0x629D # 0 +0x926B 0x629E # 0 +0x926C 0x62A3 # 0 +0x926D 0x62A6 # 0 +0x926E 0x62A7 # 0 +0x926F 0x62A9 # 0 +0x9270 0x62AA # 0 +0x9271 0x62AD # 0 +0x9272 0x62AE # 0 +0x9273 0x62AF # 0 +0x9274 0x62B0 # 0 +0x9275 0x62B2 # 0 +0x9276 0x62B3 # 0 +0x9277 0x62B4 # 0 +0x9278 0x62B6 # 0 +0x9279 0x62B7 # 0 +0x927A 0x62B8 # 0 +0x927B 0x62BA # 0 +0x927C 0x62BE # 0 +0x927D 0x62C0 # 0 +0x927E 0x62C1 # 0 +0x9280 0x62C3 # 0 +0x9281 0x62CB # 0 +0x9282 0x62CF # 0 +0x9283 0x62D1 # 0 +0x9284 0x62D5 # 0 +0x9285 0x62DD # 0 +0x9286 0x62DE # 0 +0x9287 0x62E0 # 0 +0x9288 0x62E1 # 0 +0x9289 0x62E4 # 0 +0x928A 0x62EA # 0 +0x928B 0x62EB # 0 +0x928C 0x62F0 # 0 +0x928D 0x62F2 # 0 +0x928E 0x62F5 # 0 +0x928F 0x62F8 # 0 +0x9290 0x62F9 # 0 +0x9291 0x62FA # 0 +0x9292 0x62FB # 0 +0x9293 0x6300 # 0 +0x9294 0x6303 # 0 +0x9295 0x6304 # 0 +0x9296 0x6305 # 0 +0x9297 0x6306 # 0 +0x9298 0x630A # 0 +0x9299 0x630B # 0 +0x929A 0x630C # 0 +0x929B 0x630D # 0 +0x929C 0x630F # 0 +0x929D 0x6310 # 0 +0x929E 0x6312 # 0 +0x929F 0x6313 # 0 +0x92A0 0x6314 # 0 +0x92A1 0x6315 # 0 +0x92A2 0x6317 # 0 +0x92A3 0x6318 # 0 +0x92A4 0x6319 # 0 +0x92A5 0x631C # 0 +0x92A6 0x6326 # 0 +0x92A7 0x6327 # 0 +0x92A8 0x6329 # 0 +0x92A9 0x632C # 0 +0x92AA 0x632D # 0 +0x92AB 0x632E # 0 +0x92AC 0x6330 # 0 +0x92AD 0x6331 # 0 +0x92AE 0x6333 # 0 +0x92AF 0x6334 # 0 +0x92B0 0x6335 # 0 +0x92B1 0x6336 # 0 +0x92B2 0x6337 # 0 +0x92B3 0x6338 # 0 +0x92B4 0x633B # 0 +0x92B5 0x633C # 0 +0x92B6 0x633E # 0 +0x92B7 0x633F # 0 +0x92B8 0x6340 # 0 +0x92B9 0x6341 # 0 +0x92BA 0x6344 # 0 +0x92BB 0x6347 # 0 +0x92BC 0x6348 # 0 +0x92BD 0x634A # 0 +0x92BE 0x6351 # 0 +0x92BF 0x6352 # 0 +0x92C0 0x6353 # 0 +0x92C1 0x6354 # 0 +0x92C2 0x6356 # 0 +0x92C3 0x6357 # 0 +0x92C4 0x6358 # 0 +0x92C5 0x6359 # 0 +0x92C6 0x635A # 0 +0x92C7 0x635B # 0 +0x92C8 0x635C # 0 +0x92C9 0x635D # 0 +0x92CA 0x6360 # 0 +0x92CB 0x6364 # 0 +0x92CC 0x6365 # 0 +0x92CD 0x6366 # 0 +0x92CE 0x6368 # 0 +0x92CF 0x636A # 0 +0x92D0 0x636B # 0 +0x92D1 0x636C # 0 +0x92D2 0x636F # 0 +0x92D3 0x6370 # 0 +0x92D4 0x6372 # 0 +0x92D5 0x6373 # 0 +0x92D6 0x6374 # 0 +0x92D7 0x6375 # 0 +0x92D8 0x6378 # 0 +0x92D9 0x6379 # 0 +0x92DA 0x637C # 0 +0x92DB 0x637D # 0 +0x92DC 0x637E # 0 +0x92DD 0x637F # 0 +0x92DE 0x6381 # 0 +0x92DF 0x6383 # 0 +0x92E0 0x6384 # 0 +0x92E1 0x6385 # 0 +0x92E2 0x6386 # 0 +0x92E3 0x638B # 0 +0x92E4 0x638D # 0 +0x92E5 0x6391 # 0 +0x92E6 0x6393 # 0 +0x92E7 0x6394 # 0 +0x92E8 0x6395 # 0 +0x92E9 0x6397 # 0 +0x92EA 0x6399 # 0 +0x92EB 0x639A # 0 +0x92EC 0x639B # 0 +0x92ED 0x639C # 0 +0x92EE 0x639D # 0 +0x92EF 0x639E # 0 +0x92F0 0x639F # 0 +0x92F1 0x63A1 # 0 +0x92F2 0x63A4 # 0 +0x92F3 0x63A6 # 0 +0x92F4 0x63AB # 0 +0x92F5 0x63AF # 0 +0x92F6 0x63B1 # 0 +0x92F7 0x63B2 # 0 +0x92F8 0x63B5 # 0 +0x92F9 0x63B6 # 0 +0x92FA 0x63B9 # 0 +0x92FB 0x63BB # 0 +0x92FC 0x63BD # 0 +0x92FD 0x63BF # 0 +0x92FE 0x63C0 # 0 +0x9340 0x63C1 # 0 +0x9341 0x63C2 # 0 +0x9342 0x63C3 # 0 +0x9343 0x63C5 # 0 +0x9344 0x63C7 # 0 +0x9345 0x63C8 # 0 +0x9346 0x63CA # 0 +0x9347 0x63CB # 0 +0x9348 0x63CC # 0 +0x9349 0x63D1 # 0 +0x934A 0x63D3 # 0 +0x934B 0x63D4 # 0 +0x934C 0x63D5 # 0 +0x934D 0x63D7 # 0 +0x934E 0x63D8 # 0 +0x934F 0x63D9 # 0 +0x9350 0x63DA # 0 +0x9351 0x63DB # 0 +0x9352 0x63DC # 0 +0x9353 0x63DD # 0 +0x9354 0x63DF # 0 +0x9355 0x63E2 # 0 +0x9356 0x63E4 # 0 +0x9357 0x63E5 # 0 +0x9358 0x63E6 # 0 +0x9359 0x63E7 # 0 +0x935A 0x63E8 # 0 +0x935B 0x63EB # 0 +0x935C 0x63EC # 0 +0x935D 0x63EE # 0 +0x935E 0x63EF # 0 +0x935F 0x63F0 # 0 +0x9360 0x63F1 # 0 +0x9361 0x63F3 # 0 +0x9362 0x63F5 # 0 +0x9363 0x63F7 # 0 +0x9364 0x63F9 # 0 +0x9365 0x63FA # 0 +0x9366 0x63FB # 0 +0x9367 0x63FC # 0 +0x9368 0x63FE # 0 +0x9369 0x6403 # 0 +0x936A 0x6404 # 0 +0x936B 0x6406 # 0 +0x936C 0x6407 # 0 +0x936D 0x6408 # 0 +0x936E 0x6409 # 0 +0x936F 0x640A # 0 +0x9370 0x640D # 0 +0x9371 0x640E # 0 +0x9372 0x6411 # 0 +0x9373 0x6412 # 0 +0x9374 0x6415 # 0 +0x9375 0x6416 # 0 +0x9376 0x6417 # 0 +0x9377 0x6418 # 0 +0x9378 0x6419 # 0 +0x9379 0x641A # 0 +0x937A 0x641D # 0 +0x937B 0x641F # 0 +0x937C 0x6422 # 0 +0x937D 0x6423 # 0 +0x937E 0x6424 # 0 +0x9380 0x6425 # 0 +0x9381 0x6427 # 0 +0x9382 0x6428 # 0 +0x9383 0x6429 # 0 +0x9384 0x642B # 0 +0x9385 0x642E # 0 +0x9386 0x642F # 0 +0x9387 0x6430 # 0 +0x9388 0x6431 # 0 +0x9389 0x6432 # 0 +0x938A 0x6433 # 0 +0x938B 0x6435 # 0 +0x938C 0x6436 # 0 +0x938D 0x6437 # 0 +0x938E 0x6438 # 0 +0x938F 0x6439 # 0 +0x9390 0x643B # 0 +0x9391 0x643C # 0 +0x9392 0x643E # 0 +0x9393 0x6440 # 0 +0x9394 0x6442 # 0 +0x9395 0x6443 # 0 +0x9396 0x6449 # 0 +0x9397 0x644B # 0 +0x9398 0x644C # 0 +0x9399 0x644D # 0 +0x939A 0x644E # 0 +0x939B 0x644F # 0 +0x939C 0x6450 # 0 +0x939D 0x6451 # 0 +0x939E 0x6453 # 0 +0x939F 0x6455 # 0 +0x93A0 0x6456 # 0 +0x93A1 0x6457 # 0 +0x93A2 0x6459 # 0 +0x93A3 0x645A # 0 +0x93A4 0x645B # 0 +0x93A5 0x645C # 0 +0x93A6 0x645D # 0 +0x93A7 0x645F # 0 +0x93A8 0x6460 # 0 +0x93A9 0x6461 # 0 +0x93AA 0x6462 # 0 +0x93AB 0x6463 # 0 +0x93AC 0x6464 # 0 +0x93AD 0x6465 # 0 +0x93AE 0x6466 # 0 +0x93AF 0x6468 # 0 +0x93B0 0x646A # 0 +0x93B1 0x646B # 0 +0x93B2 0x646C # 0 +0x93B3 0x646E # 0 +0x93B4 0x646F # 0 +0x93B5 0x6470 # 0 +0x93B6 0x6471 # 0 +0x93B7 0x6472 # 0 +0x93B8 0x6473 # 0 +0x93B9 0x6474 # 0 +0x93BA 0x6475 # 0 +0x93BB 0x6476 # 0 +0x93BC 0x6477 # 0 +0x93BD 0x647B # 0 +0x93BE 0x647C # 0 +0x93BF 0x647D # 0 +0x93C0 0x647E # 0 +0x93C1 0x647F # 0 +0x93C2 0x6480 # 0 +0x93C3 0x6481 # 0 +0x93C4 0x6483 # 0 +0x93C5 0x6486 # 0 +0x93C6 0x6488 # 0 +0x93C7 0x6489 # 0 +0x93C8 0x648A # 0 +0x93C9 0x648B # 0 +0x93CA 0x648C # 0 +0x93CB 0x648D # 0 +0x93CC 0x648E # 0 +0x93CD 0x648F # 0 +0x93CE 0x6490 # 0 +0x93CF 0x6493 # 0 +0x93D0 0x6494 # 0 +0x93D1 0x6497 # 0 +0x93D2 0x6498 # 0 +0x93D3 0x649A # 0 +0x93D4 0x649B # 0 +0x93D5 0x649C # 0 +0x93D6 0x649D # 0 +0x93D7 0x649F # 0 +0x93D8 0x64A0 # 0 +0x93D9 0x64A1 # 0 +0x93DA 0x64A2 # 0 +0x93DB 0x64A3 # 0 +0x93DC 0x64A5 # 0 +0x93DD 0x64A6 # 0 +0x93DE 0x64A7 # 0 +0x93DF 0x64A8 # 0 +0x93E0 0x64AA # 0 +0x93E1 0x64AB # 0 +0x93E2 0x64AF # 0 +0x93E3 0x64B1 # 0 +0x93E4 0x64B2 # 0 +0x93E5 0x64B3 # 0 +0x93E6 0x64B4 # 0 +0x93E7 0x64B6 # 0 +0x93E8 0x64B9 # 0 +0x93E9 0x64BB # 0 +0x93EA 0x64BD # 0 +0x93EB 0x64BE # 0 +0x93EC 0x64BF # 0 +0x93ED 0x64C1 # 0 +0x93EE 0x64C3 # 0 +0x93EF 0x64C4 # 0 +0x93F0 0x64C6 # 0 +0x93F1 0x64C7 # 0 +0x93F2 0x64C8 # 0 +0x93F3 0x64C9 # 0 +0x93F4 0x64CA # 0 +0x93F5 0x64CB # 0 +0x93F6 0x64CC # 0 +0x93F7 0x64CF # 0 +0x93F8 0x64D1 # 0 +0x93F9 0x64D3 # 0 +0x93FA 0x64D4 # 0 +0x93FB 0x64D5 # 0 +0x93FC 0x64D6 # 0 +0x93FD 0x64D9 # 0 +0x93FE 0x64DA # 0 +0x9440 0x64DB # 0 +0x9441 0x64DC # 0 +0x9442 0x64DD # 0 +0x9443 0x64DF # 0 +0x9444 0x64E0 # 0 +0x9445 0x64E1 # 0 +0x9446 0x64E3 # 0 +0x9447 0x64E5 # 0 +0x9448 0x64E7 # 0 +0x9449 0x64E8 # 0 +0x944A 0x64E9 # 0 +0x944B 0x64EA # 0 +0x944C 0x64EB # 0 +0x944D 0x64EC # 0 +0x944E 0x64ED # 0 +0x944F 0x64EE # 0 +0x9450 0x64EF # 0 +0x9451 0x64F0 # 0 +0x9452 0x64F1 # 0 +0x9453 0x64F2 # 0 +0x9454 0x64F3 # 0 +0x9455 0x64F4 # 0 +0x9456 0x64F5 # 0 +0x9457 0x64F6 # 0 +0x9458 0x64F7 # 0 +0x9459 0x64F8 # 0 +0x945A 0x64F9 # 0 +0x945B 0x64FA # 0 +0x945C 0x64FB # 0 +0x945D 0x64FC # 0 +0x945E 0x64FD # 0 +0x945F 0x64FE # 0 +0x9460 0x64FF # 0 +0x9461 0x6501 # 0 +0x9462 0x6502 # 0 +0x9463 0x6503 # 0 +0x9464 0x6504 # 0 +0x9465 0x6505 # 0 +0x9466 0x6506 # 0 +0x9467 0x6507 # 0 +0x9468 0x6508 # 0 +0x9469 0x650A # 0 +0x946A 0x650B # 0 +0x946B 0x650C # 0 +0x946C 0x650D # 0 +0x946D 0x650E # 0 +0x946E 0x650F # 0 +0x946F 0x6510 # 0 +0x9470 0x6511 # 0 +0x9471 0x6513 # 0 +0x9472 0x6514 # 0 +0x9473 0x6515 # 0 +0x9474 0x6516 # 0 +0x9475 0x6517 # 0 +0x9476 0x6519 # 0 +0x9477 0x651A # 0 +0x9478 0x651B # 0 +0x9479 0x651C # 0 +0x947A 0x651D # 0 +0x947B 0x651E # 0 +0x947C 0x651F # 0 +0x947D 0x6520 # 0 +0x947E 0x6521 # 0 +0x9480 0x6522 # 0 +0x9481 0x6523 # 0 +0x9482 0x6524 # 0 +0x9483 0x6526 # 0 +0x9484 0x6527 # 0 +0x9485 0x6528 # 0 +0x9486 0x6529 # 0 +0x9487 0x652A # 0 +0x9488 0x652C # 0 +0x9489 0x652D # 0 +0x948A 0x6530 # 0 +0x948B 0x6531 # 0 +0x948C 0x6532 # 0 +0x948D 0x6533 # 0 +0x948E 0x6537 # 0 +0x948F 0x653A # 0 +0x9490 0x653C # 0 +0x9491 0x653D # 0 +0x9492 0x6540 # 0 +0x9493 0x6541 # 0 +0x9494 0x6542 # 0 +0x9495 0x6543 # 0 +0x9496 0x6544 # 0 +0x9497 0x6546 # 0 +0x9498 0x6547 # 0 +0x9499 0x654A # 0 +0x949A 0x654B # 0 +0x949B 0x654D # 0 +0x949C 0x654E # 0 +0x949D 0x6550 # 0 +0x949E 0x6552 # 0 +0x949F 0x6553 # 0 +0x94A0 0x6554 # 0 +0x94A1 0x6557 # 0 +0x94A2 0x6558 # 0 +0x94A3 0x655A # 0 +0x94A4 0x655C # 0 +0x94A5 0x655F # 0 +0x94A6 0x6560 # 0 +0x94A7 0x6561 # 0 +0x94A8 0x6564 # 0 +0x94A9 0x6565 # 0 +0x94AA 0x6567 # 0 +0x94AB 0x6568 # 0 +0x94AC 0x6569 # 0 +0x94AD 0x656A # 0 +0x94AE 0x656D # 0 +0x94AF 0x656E # 0 +0x94B0 0x656F # 0 +0x94B1 0x6571 # 0 +0x94B2 0x6573 # 0 +0x94B3 0x6575 # 0 +0x94B4 0x6576 # 0 +0x94B5 0x6578 # 0 +0x94B6 0x6579 # 0 +0x94B7 0x657A # 0 +0x94B8 0x657B # 0 +0x94B9 0x657C # 0 +0x94BA 0x657D # 0 +0x94BB 0x657E # 0 +0x94BC 0x657F # 0 +0x94BD 0x6580 # 0 +0x94BE 0x6581 # 0 +0x94BF 0x6582 # 0 +0x94C0 0x6583 # 0 +0x94C1 0x6584 # 0 +0x94C2 0x6585 # 0 +0x94C3 0x6586 # 0 +0x94C4 0x6588 # 0 +0x94C5 0x6589 # 0 +0x94C6 0x658A # 0 +0x94C7 0x658D # 0 +0x94C8 0x658E # 0 +0x94C9 0x658F # 0 +0x94CA 0x6592 # 0 +0x94CB 0x6594 # 0 +0x94CC 0x6595 # 0 +0x94CD 0x6596 # 0 +0x94CE 0x6598 # 0 +0x94CF 0x659A # 0 +0x94D0 0x659D # 0 +0x94D1 0x659E # 0 +0x94D2 0x65A0 # 0 +0x94D3 0x65A2 # 0 +0x94D4 0x65A3 # 0 +0x94D5 0x65A6 # 0 +0x94D6 0x65A8 # 0 +0x94D7 0x65AA # 0 +0x94D8 0x65AC # 0 +0x94D9 0x65AE # 0 +0x94DA 0x65B1 # 0 +0x94DB 0x65B2 # 0 +0x94DC 0x65B3 # 0 +0x94DD 0x65B4 # 0 +0x94DE 0x65B5 # 0 +0x94DF 0x65B6 # 0 +0x94E0 0x65B7 # 0 +0x94E1 0x65B8 # 0 +0x94E2 0x65BA # 0 +0x94E3 0x65BB # 0 +0x94E4 0x65BE # 0 +0x94E5 0x65BF # 0 +0x94E6 0x65C0 # 0 +0x94E7 0x65C2 # 0 +0x94E8 0x65C7 # 0 +0x94E9 0x65C8 # 0 +0x94EA 0x65C9 # 0 +0x94EB 0x65CA # 0 +0x94EC 0x65CD # 0 +0x94ED 0x65D0 # 0 +0x94EE 0x65D1 # 0 +0x94EF 0x65D3 # 0 +0x94F0 0x65D4 # 0 +0x94F1 0x65D5 # 0 +0x94F2 0x65D8 # 0 +0x94F3 0x65D9 # 0 +0x94F4 0x65DA # 0 +0x94F5 0x65DB # 0 +0x94F6 0x65DC # 0 +0x94F7 0x65DD # 0 +0x94F8 0x65DE # 0 +0x94F9 0x65DF # 0 +0x94FA 0x65E1 # 0 +0x94FB 0x65E3 # 0 +0x94FC 0x65E4 # 0 +0x94FD 0x65EA # 0 +0x94FE 0x65EB # 0 +0x9540 0x65F2 # 0 +0x9541 0x65F3 # 0 +0x9542 0x65F4 # 0 +0x9543 0x65F5 # 0 +0x9544 0x65F8 # 0 +0x9545 0x65F9 # 0 +0x9546 0x65FB # 0 +0x9547 0x65FC # 0 +0x9548 0x65FD # 0 +0x9549 0x65FE # 0 +0x954A 0x65FF # 0 +0x954B 0x6601 # 0 +0x954C 0x6604 # 0 +0x954D 0x6605 # 0 +0x954E 0x6607 # 0 +0x954F 0x6608 # 0 +0x9550 0x6609 # 0 +0x9551 0x660B # 0 +0x9552 0x660D # 0 +0x9553 0x6610 # 0 +0x9554 0x6611 # 0 +0x9555 0x6612 # 0 +0x9556 0x6616 # 0 +0x9557 0x6617 # 0 +0x9558 0x6618 # 0 +0x9559 0x661A # 0 +0x955A 0x661B # 0 +0x955B 0x661C # 0 +0x955C 0x661E # 0 +0x955D 0x6621 # 0 +0x955E 0x6622 # 0 +0x955F 0x6623 # 0 +0x9560 0x6624 # 0 +0x9561 0x6626 # 0 +0x9562 0x6629 # 0 +0x9563 0x662A # 0 +0x9564 0x662B # 0 +0x9565 0x662C # 0 +0x9566 0x662E # 0 +0x9567 0x6630 # 0 +0x9568 0x6632 # 0 +0x9569 0x6633 # 0 +0x956A 0x6637 # 0 +0x956B 0x6638 # 0 +0x956C 0x6639 # 0 +0x956D 0x663A # 0 +0x956E 0x663B # 0 +0x956F 0x663D # 0 +0x9570 0x663F # 0 +0x9571 0x6640 # 0 +0x9572 0x6642 # 0 +0x9573 0x6644 # 0 +0x9574 0x6645 # 0 +0x9575 0x6646 # 0 +0x9576 0x6647 # 0 +0x9577 0x6648 # 0 +0x9578 0x6649 # 0 +0x9579 0x664A # 0 +0x957A 0x664D # 0 +0x957B 0x664E # 0 +0x957C 0x6650 # 0 +0x957D 0x6651 # 0 +0x957E 0x6658 # 0 +0x9580 0x6659 # 0 +0x9581 0x665B # 0 +0x9582 0x665C # 0 +0x9583 0x665D # 0 +0x9584 0x665E # 0 +0x9585 0x6660 # 0 +0x9586 0x6662 # 0 +0x9587 0x6663 # 0 +0x9588 0x6665 # 0 +0x9589 0x6667 # 0 +0x958A 0x6669 # 0 +0x958B 0x666A # 0 +0x958C 0x666B # 0 +0x958D 0x666C # 0 +0x958E 0x666D # 0 +0x958F 0x6671 # 0 +0x9590 0x6672 # 0 +0x9591 0x6673 # 0 +0x9592 0x6675 # 0 +0x9593 0x6678 # 0 +0x9594 0x6679 # 0 +0x9595 0x667B # 0 +0x9596 0x667C # 0 +0x9597 0x667D # 0 +0x9598 0x667F # 0 +0x9599 0x6680 # 0 +0x959A 0x6681 # 0 +0x959B 0x6683 # 0 +0x959C 0x6685 # 0 +0x959D 0x6686 # 0 +0x959E 0x6688 # 0 +0x959F 0x6689 # 0 +0x95A0 0x668A # 0 +0x95A1 0x668B # 0 +0x95A2 0x668D # 0 +0x95A3 0x668E # 0 +0x95A4 0x668F # 0 +0x95A5 0x6690 # 0 +0x95A6 0x6692 # 0 +0x95A7 0x6693 # 0 +0x95A8 0x6694 # 0 +0x95A9 0x6695 # 0 +0x95AA 0x6698 # 0 +0x95AB 0x6699 # 0 +0x95AC 0x669A # 0 +0x95AD 0x669B # 0 +0x95AE 0x669C # 0 +0x95AF 0x669E # 0 +0x95B0 0x669F # 0 +0x95B1 0x66A0 # 0 +0x95B2 0x66A1 # 0 +0x95B3 0x66A2 # 0 +0x95B4 0x66A3 # 0 +0x95B5 0x66A4 # 0 +0x95B6 0x66A5 # 0 +0x95B7 0x66A6 # 0 +0x95B8 0x66A9 # 0 +0x95B9 0x66AA # 0 +0x95BA 0x66AB # 0 +0x95BB 0x66AC # 0 +0x95BC 0x66AD # 0 +0x95BD 0x66AF # 0 +0x95BE 0x66B0 # 0 +0x95BF 0x66B1 # 0 +0x95C0 0x66B2 # 0 +0x95C1 0x66B3 # 0 +0x95C2 0x66B5 # 0 +0x95C3 0x66B6 # 0 +0x95C4 0x66B7 # 0 +0x95C5 0x66B8 # 0 +0x95C6 0x66BA # 0 +0x95C7 0x66BB # 0 +0x95C8 0x66BC # 0 +0x95C9 0x66BD # 0 +0x95CA 0x66BF # 0 +0x95CB 0x66C0 # 0 +0x95CC 0x66C1 # 0 +0x95CD 0x66C2 # 0 +0x95CE 0x66C3 # 0 +0x95CF 0x66C4 # 0 +0x95D0 0x66C5 # 0 +0x95D1 0x66C6 # 0 +0x95D2 0x66C7 # 0 +0x95D3 0x66C8 # 0 +0x95D4 0x66C9 # 0 +0x95D5 0x66CA # 0 +0x95D6 0x66CB # 0 +0x95D7 0x66CC # 0 +0x95D8 0x66CD # 0 +0x95D9 0x66CE # 0 +0x95DA 0x66CF # 0 +0x95DB 0x66D0 # 0 +0x95DC 0x66D1 # 0 +0x95DD 0x66D2 # 0 +0x95DE 0x66D3 # 0 +0x95DF 0x66D4 # 0 +0x95E0 0x66D5 # 0 +0x95E1 0x66D6 # 0 +0x95E2 0x66D7 # 0 +0x95E3 0x66D8 # 0 +0x95E4 0x66DA # 0 +0x95E5 0x66DE # 0 +0x95E6 0x66DF # 0 +0x95E7 0x66E0 # 0 +0x95E8 0x66E1 # 0 +0x95E9 0x66E2 # 0 +0x95EA 0x66E3 # 0 +0x95EB 0x66E4 # 0 +0x95EC 0x66E5 # 0 +0x95ED 0x66E7 # 0 +0x95EE 0x66E8 # 0 +0x95EF 0x66EA # 0 +0x95F0 0x66EB # 0 +0x95F1 0x66EC # 0 +0x95F2 0x66ED # 0 +0x95F3 0x66EE # 0 +0x95F4 0x66EF # 0 +0x95F5 0x66F1 # 0 +0x95F6 0x66F5 # 0 +0x95F7 0x66F6 # 0 +0x95F8 0x66F8 # 0 +0x95F9 0x66FA # 0 +0x95FA 0x66FB # 0 +0x95FB 0x66FD # 0 +0x95FC 0x6701 # 0 +0x95FD 0x6702 # 0 +0x95FE 0x6703 # 0 +0x9640 0x6704 # 0 +0x9641 0x6705 # 0 +0x9642 0x6706 # 0 +0x9643 0x6707 # 0 +0x9644 0x670C # 0 +0x9645 0x670E # 0 +0x9646 0x670F # 0 +0x9647 0x6711 # 0 +0x9648 0x6712 # 0 +0x9649 0x6713 # 0 +0x964A 0x6716 # 0 +0x964B 0x6718 # 0 +0x964C 0x6719 # 0 +0x964D 0x671A # 0 +0x964E 0x671C # 0 +0x964F 0x671E # 0 +0x9650 0x6720 # 0 +0x9651 0x6721 # 0 +0x9652 0x6722 # 0 +0x9653 0x6723 # 0 +0x9654 0x6724 # 0 +0x9655 0x6725 # 0 +0x9656 0x6727 # 0 +0x9657 0x6729 # 0 +0x9658 0x672E # 0 +0x9659 0x6730 # 0 +0x965A 0x6732 # 0 +0x965B 0x6733 # 0 +0x965C 0x6736 # 0 +0x965D 0x6737 # 0 +0x965E 0x6738 # 0 +0x965F 0x6739 # 0 +0x9660 0x673B # 0 +0x9661 0x673C # 0 +0x9662 0x673E # 0 +0x9663 0x673F # 0 +0x9664 0x6741 # 0 +0x9665 0x6744 # 0 +0x9666 0x6745 # 0 +0x9667 0x6747 # 0 +0x9668 0x674A # 0 +0x9669 0x674B # 0 +0x966A 0x674D # 0 +0x966B 0x6752 # 0 +0x966C 0x6754 # 0 +0x966D 0x6755 # 0 +0x966E 0x6757 # 0 +0x966F 0x6758 # 0 +0x9670 0x6759 # 0 +0x9671 0x675A # 0 +0x9672 0x675B # 0 +0x9673 0x675D # 0 +0x9674 0x6762 # 0 +0x9675 0x6763 # 0 +0x9676 0x6764 # 0 +0x9677 0x6766 # 0 +0x9678 0x6767 # 0 +0x9679 0x676B # 0 +0x967A 0x676C # 0 +0x967B 0x676E # 0 +0x967C 0x6771 # 0 +0x967D 0x6774 # 0 +0x967E 0x6776 # 0 +0x9680 0x6778 # 0 +0x9681 0x6779 # 0 +0x9682 0x677A # 0 +0x9683 0x677B # 0 +0x9684 0x677D # 0 +0x9685 0x6780 # 0 +0x9686 0x6782 # 0 +0x9687 0x6783 # 0 +0x9688 0x6785 # 0 +0x9689 0x6786 # 0 +0x968A 0x6788 # 0 +0x968B 0x678A # 0 +0x968C 0x678C # 0 +0x968D 0x678D # 0 +0x968E 0x678E # 0 +0x968F 0x678F # 0 +0x9690 0x6791 # 0 +0x9691 0x6792 # 0 +0x9692 0x6793 # 0 +0x9693 0x6794 # 0 +0x9694 0x6796 # 0 +0x9695 0x6799 # 0 +0x9696 0x679B # 0 +0x9697 0x679F # 0 +0x9698 0x67A0 # 0 +0x9699 0x67A1 # 0 +0x969A 0x67A4 # 0 +0x969B 0x67A6 # 0 +0x969C 0x67A9 # 0 +0x969D 0x67AC # 0 +0x969E 0x67AE # 0 +0x969F 0x67B1 # 0 +0x96A0 0x67B2 # 0 +0x96A1 0x67B4 # 0 +0x96A2 0x67B9 # 0 +0x96A3 0x67BA # 0 +0x96A4 0x67BB # 0 +0x96A5 0x67BC # 0 +0x96A6 0x67BD # 0 +0x96A7 0x67BE # 0 +0x96A8 0x67BF # 0 +0x96A9 0x67C0 # 0 +0x96AA 0x67C2 # 0 +0x96AB 0x67C5 # 0 +0x96AC 0x67C6 # 0 +0x96AD 0x67C7 # 0 +0x96AE 0x67C8 # 0 +0x96AF 0x67C9 # 0 +0x96B0 0x67CA # 0 +0x96B1 0x67CB # 0 +0x96B2 0x67CC # 0 +0x96B3 0x67CD # 0 +0x96B4 0x67CE # 0 +0x96B5 0x67D5 # 0 +0x96B6 0x67D6 # 0 +0x96B7 0x67D7 # 0 +0x96B8 0x67DB # 0 +0x96B9 0x67DF # 0 +0x96BA 0x67E1 # 0 +0x96BB 0x67E3 # 0 +0x96BC 0x67E4 # 0 +0x96BD 0x67E6 # 0 +0x96BE 0x67E7 # 0 +0x96BF 0x67E8 # 0 +0x96C0 0x67EA # 0 +0x96C1 0x67EB # 0 +0x96C2 0x67ED # 0 +0x96C3 0x67EE # 0 +0x96C4 0x67F2 # 0 +0x96C5 0x67F5 # 0 +0x96C6 0x67F6 # 0 +0x96C7 0x67F7 # 0 +0x96C8 0x67F8 # 0 +0x96C9 0x67F9 # 0 +0x96CA 0x67FA # 0 +0x96CB 0x67FB # 0 +0x96CC 0x67FC # 0 +0x96CD 0x67FE # 0 +0x96CE 0x6801 # 0 +0x96CF 0x6802 # 0 +0x96D0 0x6803 # 0 +0x96D1 0x6804 # 0 +0x96D2 0x6806 # 0 +0x96D3 0x680D # 0 +0x96D4 0x6810 # 0 +0x96D5 0x6812 # 0 +0x96D6 0x6814 # 0 +0x96D7 0x6815 # 0 +0x96D8 0x6818 # 0 +0x96D9 0x6819 # 0 +0x96DA 0x681A # 0 +0x96DB 0x681B # 0 +0x96DC 0x681C # 0 +0x96DD 0x681E # 0 +0x96DE 0x681F # 0 +0x96DF 0x6820 # 0 +0x96E0 0x6822 # 0 +0x96E1 0x6823 # 0 +0x96E2 0x6824 # 0 +0x96E3 0x6825 # 0 +0x96E4 0x6826 # 0 +0x96E5 0x6827 # 0 +0x96E6 0x6828 # 0 +0x96E7 0x682B # 0 +0x96E8 0x682C # 0 +0x96E9 0x682D # 0 +0x96EA 0x682E # 0 +0x96EB 0x682F # 0 +0x96EC 0x6830 # 0 +0x96ED 0x6831 # 0 +0x96EE 0x6834 # 0 +0x96EF 0x6835 # 0 +0x96F0 0x6836 # 0 +0x96F1 0x683A # 0 +0x96F2 0x683B # 0 +0x96F3 0x683F # 0 +0x96F4 0x6847 # 0 +0x96F5 0x684B # 0 +0x96F6 0x684D # 0 +0x96F7 0x684F # 0 +0x96F8 0x6852 # 0 +0x96F9 0x6856 # 0 +0x96FA 0x6857 # 0 +0x96FB 0x6858 # 0 +0x96FC 0x6859 # 0 +0x96FD 0x685A # 0 +0x96FE 0x685B # 0 +0x9740 0x685C # 0 +0x9741 0x685D # 0 +0x9742 0x685E # 0 +0x9743 0x685F # 0 +0x9744 0x686A # 0 +0x9745 0x686C # 0 +0x9746 0x686D # 0 +0x9747 0x686E # 0 +0x9748 0x686F # 0 +0x9749 0x6870 # 0 +0x974A 0x6871 # 0 +0x974B 0x6872 # 0 +0x974C 0x6873 # 0 +0x974D 0x6875 # 0 +0x974E 0x6878 # 0 +0x974F 0x6879 # 0 +0x9750 0x687A # 0 +0x9751 0x687B # 0 +0x9752 0x687C # 0 +0x9753 0x687D # 0 +0x9754 0x687E # 0 +0x9755 0x687F # 0 +0x9756 0x6880 # 0 +0x9757 0x6882 # 0 +0x9758 0x6884 # 0 +0x9759 0x6887 # 0 +0x975A 0x6888 # 0 +0x975B 0x6889 # 0 +0x975C 0x688A # 0 +0x975D 0x688B # 0 +0x975E 0x688C # 0 +0x975F 0x688D # 0 +0x9760 0x688E # 0 +0x9761 0x6890 # 0 +0x9762 0x6891 # 0 +0x9763 0x6892 # 0 +0x9764 0x6894 # 0 +0x9765 0x6895 # 0 +0x9766 0x6896 # 0 +0x9767 0x6898 # 0 +0x9768 0x6899 # 0 +0x9769 0x689A # 0 +0x976A 0x689B # 0 +0x976B 0x689C # 0 +0x976C 0x689D # 0 +0x976D 0x689E # 0 +0x976E 0x689F # 0 +0x976F 0x68A0 # 0 +0x9770 0x68A1 # 0 +0x9771 0x68A3 # 0 +0x9772 0x68A4 # 0 +0x9773 0x68A5 # 0 +0x9774 0x68A9 # 0 +0x9775 0x68AA # 0 +0x9776 0x68AB # 0 +0x9777 0x68AC # 0 +0x9778 0x68AE # 0 +0x9779 0x68B1 # 0 +0x977A 0x68B2 # 0 +0x977B 0x68B4 # 0 +0x977C 0x68B6 # 0 +0x977D 0x68B7 # 0 +0x977E 0x68B8 # 0 +0x9780 0x68B9 # 0 +0x9781 0x68BA # 0 +0x9782 0x68BB # 0 +0x9783 0x68BC # 0 +0x9784 0x68BD # 0 +0x9785 0x68BE # 0 +0x9786 0x68BF # 0 +0x9787 0x68C1 # 0 +0x9788 0x68C3 # 0 +0x9789 0x68C4 # 0 +0x978A 0x68C5 # 0 +0x978B 0x68C6 # 0 +0x978C 0x68C7 # 0 +0x978D 0x68C8 # 0 +0x978E 0x68CA # 0 +0x978F 0x68CC # 0 +0x9790 0x68CE # 0 +0x9791 0x68CF # 0 +0x9792 0x68D0 # 0 +0x9793 0x68D1 # 0 +0x9794 0x68D3 # 0 +0x9795 0x68D4 # 0 +0x9796 0x68D6 # 0 +0x9797 0x68D7 # 0 +0x9798 0x68D9 # 0 +0x9799 0x68DB # 0 +0x979A 0x68DC # 0 +0x979B 0x68DD # 0 +0x979C 0x68DE # 0 +0x979D 0x68DF # 0 +0x979E 0x68E1 # 0 +0x979F 0x68E2 # 0 +0x97A0 0x68E4 # 0 +0x97A1 0x68E5 # 0 +0x97A2 0x68E6 # 0 +0x97A3 0x68E7 # 0 +0x97A4 0x68E8 # 0 +0x97A5 0x68E9 # 0 +0x97A6 0x68EA # 0 +0x97A7 0x68EB # 0 +0x97A8 0x68EC # 0 +0x97A9 0x68ED # 0 +0x97AA 0x68EF # 0 +0x97AB 0x68F2 # 0 +0x97AC 0x68F3 # 0 +0x97AD 0x68F4 # 0 +0x97AE 0x68F6 # 0 +0x97AF 0x68F7 # 0 +0x97B0 0x68F8 # 0 +0x97B1 0x68FB # 0 +0x97B2 0x68FD # 0 +0x97B3 0x68FE # 0 +0x97B4 0x68FF # 0 +0x97B5 0x6900 # 0 +0x97B6 0x6902 # 0 +0x97B7 0x6903 # 0 +0x97B8 0x6904 # 0 +0x97B9 0x6906 # 0 +0x97BA 0x6907 # 0 +0x97BB 0x6908 # 0 +0x97BC 0x6909 # 0 +0x97BD 0x690A # 0 +0x97BE 0x690C # 0 +0x97BF 0x690F # 0 +0x97C0 0x6911 # 0 +0x97C1 0x6913 # 0 +0x97C2 0x6914 # 0 +0x97C3 0x6915 # 0 +0x97C4 0x6916 # 0 +0x97C5 0x6917 # 0 +0x97C6 0x6918 # 0 +0x97C7 0x6919 # 0 +0x97C8 0x691A # 0 +0x97C9 0x691B # 0 +0x97CA 0x691C # 0 +0x97CB 0x691D # 0 +0x97CC 0x691E # 0 +0x97CD 0x6921 # 0 +0x97CE 0x6922 # 0 +0x97CF 0x6923 # 0 +0x97D0 0x6925 # 0 +0x97D1 0x6926 # 0 +0x97D2 0x6927 # 0 +0x97D3 0x6928 # 0 +0x97D4 0x6929 # 0 +0x97D5 0x692A # 0 +0x97D6 0x692B # 0 +0x97D7 0x692C # 0 +0x97D8 0x692E # 0 +0x97D9 0x692F # 0 +0x97DA 0x6931 # 0 +0x97DB 0x6932 # 0 +0x97DC 0x6933 # 0 +0x97DD 0x6935 # 0 +0x97DE 0x6936 # 0 +0x97DF 0x6937 # 0 +0x97E0 0x6938 # 0 +0x97E1 0x693A # 0 +0x97E2 0x693B # 0 +0x97E3 0x693C # 0 +0x97E4 0x693E # 0 +0x97E5 0x6940 # 0 +0x97E6 0x6941 # 0 +0x97E7 0x6943 # 0 +0x97E8 0x6944 # 0 +0x97E9 0x6945 # 0 +0x97EA 0x6946 # 0 +0x97EB 0x6947 # 0 +0x97EC 0x6948 # 0 +0x97ED 0x6949 # 0 +0x97EE 0x694A # 0 +0x97EF 0x694B # 0 +0x97F0 0x694C # 0 +0x97F1 0x694D # 0 +0x97F2 0x694E # 0 +0x97F3 0x694F # 0 +0x97F4 0x6950 # 0 +0x97F5 0x6951 # 0 +0x97F6 0x6952 # 0 +0x97F7 0x6953 # 0 +0x97F8 0x6955 # 0 +0x97F9 0x6956 # 0 +0x97FA 0x6958 # 0 +0x97FB 0x6959 # 0 +0x97FC 0x695B # 0 +0x97FD 0x695C # 0 +0x97FE 0x695F # 0 +0x9840 0x6961 # 0 +0x9841 0x6962 # 0 +0x9842 0x6964 # 0 +0x9843 0x6965 # 0 +0x9844 0x6967 # 0 +0x9845 0x6968 # 0 +0x9846 0x6969 # 0 +0x9847 0x696A # 0 +0x9848 0x696C # 0 +0x9849 0x696D # 0 +0x984A 0x696F # 0 +0x984B 0x6970 # 0 +0x984C 0x6972 # 0 +0x984D 0x6973 # 0 +0x984E 0x6974 # 0 +0x984F 0x6975 # 0 +0x9850 0x6976 # 0 +0x9851 0x697A # 0 +0x9852 0x697B # 0 +0x9853 0x697D # 0 +0x9854 0x697E # 0 +0x9855 0x697F # 0 +0x9856 0x6981 # 0 +0x9857 0x6983 # 0 +0x9858 0x6985 # 0 +0x9859 0x698A # 0 +0x985A 0x698B # 0 +0x985B 0x698C # 0 +0x985C 0x698E # 0 +0x985D 0x698F # 0 +0x985E 0x6990 # 0 +0x985F 0x6991 # 0 +0x9860 0x6992 # 0 +0x9861 0x6993 # 0 +0x9862 0x6996 # 0 +0x9863 0x6997 # 0 +0x9864 0x6999 # 0 +0x9865 0x699A # 0 +0x9866 0x699D # 0 +0x9867 0x699E # 0 +0x9868 0x699F # 0 +0x9869 0x69A0 # 0 +0x986A 0x69A1 # 0 +0x986B 0x69A2 # 0 +0x986C 0x69A3 # 0 +0x986D 0x69A4 # 0 +0x986E 0x69A5 # 0 +0x986F 0x69A6 # 0 +0x9870 0x69A9 # 0 +0x9871 0x69AA # 0 +0x9872 0x69AC # 0 +0x9873 0x69AE # 0 +0x9874 0x69AF # 0 +0x9875 0x69B0 # 0 +0x9876 0x69B2 # 0 +0x9877 0x69B3 # 0 +0x9878 0x69B5 # 0 +0x9879 0x69B6 # 0 +0x987A 0x69B8 # 0 +0x987B 0x69B9 # 0 +0x987C 0x69BA # 0 +0x987D 0x69BC # 0 +0x987E 0x69BD # 0 +0x9880 0x69BE # 0 +0x9881 0x69BF # 0 +0x9882 0x69C0 # 0 +0x9883 0x69C2 # 0 +0x9884 0x69C3 # 0 +0x9885 0x69C4 # 0 +0x9886 0x69C5 # 0 +0x9887 0x69C6 # 0 +0x9888 0x69C7 # 0 +0x9889 0x69C8 # 0 +0x988A 0x69C9 # 0 +0x988B 0x69CB # 0 +0x988C 0x69CD # 0 +0x988D 0x69CF # 0 +0x988E 0x69D1 # 0 +0x988F 0x69D2 # 0 +0x9890 0x69D3 # 0 +0x9891 0x69D5 # 0 +0x9892 0x69D6 # 0 +0x9893 0x69D7 # 0 +0x9894 0x69D8 # 0 +0x9895 0x69D9 # 0 +0x9896 0x69DA # 0 +0x9897 0x69DC # 0 +0x9898 0x69DD # 0 +0x9899 0x69DE # 0 +0x989A 0x69E1 # 0 +0x989B 0x69E2 # 0 +0x989C 0x69E3 # 0 +0x989D 0x69E4 # 0 +0x989E 0x69E5 # 0 +0x989F 0x69E6 # 0 +0x98A0 0x69E7 # 0 +0x98A1 0x69E8 # 0 +0x98A2 0x69E9 # 0 +0x98A3 0x69EA # 0 +0x98A4 0x69EB # 0 +0x98A5 0x69EC # 0 +0x98A6 0x69EE # 0 +0x98A7 0x69EF # 0 +0x98A8 0x69F0 # 0 +0x98A9 0x69F1 # 0 +0x98AA 0x69F3 # 0 +0x98AB 0x69F4 # 0 +0x98AC 0x69F5 # 0 +0x98AD 0x69F6 # 0 +0x98AE 0x69F7 # 0 +0x98AF 0x69F8 # 0 +0x98B0 0x69F9 # 0 +0x98B1 0x69FA # 0 +0x98B2 0x69FB # 0 +0x98B3 0x69FC # 0 +0x98B4 0x69FE # 0 +0x98B5 0x6A00 # 0 +0x98B6 0x6A01 # 0 +0x98B7 0x6A02 # 0 +0x98B8 0x6A03 # 0 +0x98B9 0x6A04 # 0 +0x98BA 0x6A05 # 0 +0x98BB 0x6A06 # 0 +0x98BC 0x6A07 # 0 +0x98BD 0x6A08 # 0 +0x98BE 0x6A09 # 0 +0x98BF 0x6A0B # 0 +0x98C0 0x6A0C # 0 +0x98C1 0x6A0D # 0 +0x98C2 0x6A0E # 0 +0x98C3 0x6A0F # 0 +0x98C4 0x6A10 # 0 +0x98C5 0x6A11 # 0 +0x98C6 0x6A12 # 0 +0x98C7 0x6A13 # 0 +0x98C8 0x6A14 # 0 +0x98C9 0x6A15 # 0 +0x98CA 0x6A16 # 0 +0x98CB 0x6A19 # 0 +0x98CC 0x6A1A # 0 +0x98CD 0x6A1B # 0 +0x98CE 0x6A1C # 0 +0x98CF 0x6A1D # 0 +0x98D0 0x6A1E # 0 +0x98D1 0x6A20 # 0 +0x98D2 0x6A22 # 0 +0x98D3 0x6A23 # 0 +0x98D4 0x6A24 # 0 +0x98D5 0x6A25 # 0 +0x98D6 0x6A26 # 0 +0x98D7 0x6A27 # 0 +0x98D8 0x6A29 # 0 +0x98D9 0x6A2B # 0 +0x98DA 0x6A2C # 0 +0x98DB 0x6A2D # 0 +0x98DC 0x6A2E # 0 +0x98DD 0x6A30 # 0 +0x98DE 0x6A32 # 0 +0x98DF 0x6A33 # 0 +0x98E0 0x6A34 # 0 +0x98E1 0x6A36 # 0 +0x98E2 0x6A37 # 0 +0x98E3 0x6A38 # 0 +0x98E4 0x6A39 # 0 +0x98E5 0x6A3A # 0 +0x98E6 0x6A3B # 0 +0x98E7 0x6A3C # 0 +0x98E8 0x6A3F # 0 +0x98E9 0x6A40 # 0 +0x98EA 0x6A41 # 0 +0x98EB 0x6A42 # 0 +0x98EC 0x6A43 # 0 +0x98ED 0x6A45 # 0 +0x98EE 0x6A46 # 0 +0x98EF 0x6A48 # 0 +0x98F0 0x6A49 # 0 +0x98F1 0x6A4A # 0 +0x98F2 0x6A4B # 0 +0x98F3 0x6A4C # 0 +0x98F4 0x6A4D # 0 +0x98F5 0x6A4E # 0 +0x98F6 0x6A4F # 0 +0x98F7 0x6A51 # 0 +0x98F8 0x6A52 # 0 +0x98F9 0x6A53 # 0 +0x98FA 0x6A54 # 0 +0x98FB 0x6A55 # 0 +0x98FC 0x6A56 # 0 +0x98FD 0x6A57 # 0 +0x98FE 0x6A5A # 0 +0x9940 0x6A5C # 0 +0x9941 0x6A5D # 0 +0x9942 0x6A5E # 0 +0x9943 0x6A5F # 0 +0x9944 0x6A60 # 0 +0x9945 0x6A62 # 0 +0x9946 0x6A63 # 0 +0x9947 0x6A64 # 0 +0x9948 0x6A66 # 0 +0x9949 0x6A67 # 0 +0x994A 0x6A68 # 0 +0x994B 0x6A69 # 0 +0x994C 0x6A6A # 0 +0x994D 0x6A6B # 0 +0x994E 0x6A6C # 0 +0x994F 0x6A6D # 0 +0x9950 0x6A6E # 0 +0x9951 0x6A6F # 0 +0x9952 0x6A70 # 0 +0x9953 0x6A72 # 0 +0x9954 0x6A73 # 0 +0x9955 0x6A74 # 0 +0x9956 0x6A75 # 0 +0x9957 0x6A76 # 0 +0x9958 0x6A77 # 0 +0x9959 0x6A78 # 0 +0x995A 0x6A7A # 0 +0x995B 0x6A7B # 0 +0x995C 0x6A7D # 0 +0x995D 0x6A7E # 0 +0x995E 0x6A7F # 0 +0x995F 0x6A81 # 0 +0x9960 0x6A82 # 0 +0x9961 0x6A83 # 0 +0x9962 0x6A85 # 0 +0x9963 0x6A86 # 0 +0x9964 0x6A87 # 0 +0x9965 0x6A88 # 0 +0x9966 0x6A89 # 0 +0x9967 0x6A8A # 0 +0x9968 0x6A8B # 0 +0x9969 0x6A8C # 0 +0x996A 0x6A8D # 0 +0x996B 0x6A8F # 0 +0x996C 0x6A92 # 0 +0x996D 0x6A93 # 0 +0x996E 0x6A94 # 0 +0x996F 0x6A95 # 0 +0x9970 0x6A96 # 0 +0x9971 0x6A98 # 0 +0x9972 0x6A99 # 0 +0x9973 0x6A9A # 0 +0x9974 0x6A9B # 0 +0x9975 0x6A9C # 0 +0x9976 0x6A9D # 0 +0x9977 0x6A9E # 0 +0x9978 0x6A9F # 0 +0x9979 0x6AA1 # 0 +0x997A 0x6AA2 # 0 +0x997B 0x6AA3 # 0 +0x997C 0x6AA4 # 0 +0x997D 0x6AA5 # 0 +0x997E 0x6AA6 # 0 +0x9980 0x6AA7 # 0 +0x9981 0x6AA8 # 0 +0x9982 0x6AAA # 0 +0x9983 0x6AAD # 0 +0x9984 0x6AAE # 0 +0x9985 0x6AAF # 0 +0x9986 0x6AB0 # 0 +0x9987 0x6AB1 # 0 +0x9988 0x6AB2 # 0 +0x9989 0x6AB3 # 0 +0x998A 0x6AB4 # 0 +0x998B 0x6AB5 # 0 +0x998C 0x6AB6 # 0 +0x998D 0x6AB7 # 0 +0x998E 0x6AB8 # 0 +0x998F 0x6AB9 # 0 +0x9990 0x6ABA # 0 +0x9991 0x6ABB # 0 +0x9992 0x6ABC # 0 +0x9993 0x6ABD # 0 +0x9994 0x6ABE # 0 +0x9995 0x6ABF # 0 +0x9996 0x6AC0 # 0 +0x9997 0x6AC1 # 0 +0x9998 0x6AC2 # 0 +0x9999 0x6AC3 # 0 +0x999A 0x6AC4 # 0 +0x999B 0x6AC5 # 0 +0x999C 0x6AC6 # 0 +0x999D 0x6AC7 # 0 +0x999E 0x6AC8 # 0 +0x999F 0x6AC9 # 0 +0x99A0 0x6ACA # 0 +0x99A1 0x6ACB # 0 +0x99A2 0x6ACC # 0 +0x99A3 0x6ACD # 0 +0x99A4 0x6ACE # 0 +0x99A5 0x6ACF # 0 +0x99A6 0x6AD0 # 0 +0x99A7 0x6AD1 # 0 +0x99A8 0x6AD2 # 0 +0x99A9 0x6AD3 # 0 +0x99AA 0x6AD4 # 0 +0x99AB 0x6AD5 # 0 +0x99AC 0x6AD6 # 0 +0x99AD 0x6AD7 # 0 +0x99AE 0x6AD8 # 0 +0x99AF 0x6AD9 # 0 +0x99B0 0x6ADA # 0 +0x99B1 0x6ADB # 0 +0x99B2 0x6ADC # 0 +0x99B3 0x6ADD # 0 +0x99B4 0x6ADE # 0 +0x99B5 0x6ADF # 0 +0x99B6 0x6AE0 # 0 +0x99B7 0x6AE1 # 0 +0x99B8 0x6AE2 # 0 +0x99B9 0x6AE3 # 0 +0x99BA 0x6AE4 # 0 +0x99BB 0x6AE5 # 0 +0x99BC 0x6AE6 # 0 +0x99BD 0x6AE7 # 0 +0x99BE 0x6AE8 # 0 +0x99BF 0x6AE9 # 0 +0x99C0 0x6AEA # 0 +0x99C1 0x6AEB # 0 +0x99C2 0x6AEC # 0 +0x99C3 0x6AED # 0 +0x99C4 0x6AEE # 0 +0x99C5 0x6AEF # 0 +0x99C6 0x6AF0 # 0 +0x99C7 0x6AF1 # 0 +0x99C8 0x6AF2 # 0 +0x99C9 0x6AF3 # 0 +0x99CA 0x6AF4 # 0 +0x99CB 0x6AF5 # 0 +0x99CC 0x6AF6 # 0 +0x99CD 0x6AF7 # 0 +0x99CE 0x6AF8 # 0 +0x99CF 0x6AF9 # 0 +0x99D0 0x6AFA # 0 +0x99D1 0x6AFB # 0 +0x99D2 0x6AFC # 0 +0x99D3 0x6AFD # 0 +0x99D4 0x6AFE # 0 +0x99D5 0x6AFF # 0 +0x99D6 0x6B00 # 0 +0x99D7 0x6B01 # 0 +0x99D8 0x6B02 # 0 +0x99D9 0x6B03 # 0 +0x99DA 0x6B04 # 0 +0x99DB 0x6B05 # 0 +0x99DC 0x6B06 # 0 +0x99DD 0x6B07 # 0 +0x99DE 0x6B08 # 0 +0x99DF 0x6B09 # 0 +0x99E0 0x6B0A # 0 +0x99E1 0x6B0B # 0 +0x99E2 0x6B0C # 0 +0x99E3 0x6B0D # 0 +0x99E4 0x6B0E # 0 +0x99E5 0x6B0F # 0 +0x99E6 0x6B10 # 0 +0x99E7 0x6B11 # 0 +0x99E8 0x6B12 # 0 +0x99E9 0x6B13 # 0 +0x99EA 0x6B14 # 0 +0x99EB 0x6B15 # 0 +0x99EC 0x6B16 # 0 +0x99ED 0x6B17 # 0 +0x99EE 0x6B18 # 0 +0x99EF 0x6B19 # 0 +0x99F0 0x6B1A # 0 +0x99F1 0x6B1B # 0 +0x99F2 0x6B1C # 0 +0x99F3 0x6B1D # 0 +0x99F4 0x6B1E # 0 +0x99F5 0x6B1F # 0 +0x99F6 0x6B25 # 0 +0x99F7 0x6B26 # 0 +0x99F8 0x6B28 # 0 +0x99F9 0x6B29 # 0 +0x99FA 0x6B2A # 0 +0x99FB 0x6B2B # 0 +0x99FC 0x6B2C # 0 +0x99FD 0x6B2D # 0 +0x99FE 0x6B2E # 0 +0x9A40 0x6B2F # 0 +0x9A41 0x6B30 # 0 +0x9A42 0x6B31 # 0 +0x9A43 0x6B33 # 0 +0x9A44 0x6B34 # 0 +0x9A45 0x6B35 # 0 +0x9A46 0x6B36 # 0 +0x9A47 0x6B38 # 0 +0x9A48 0x6B3B # 0 +0x9A49 0x6B3C # 0 +0x9A4A 0x6B3D # 0 +0x9A4B 0x6B3F # 0 +0x9A4C 0x6B40 # 0 +0x9A4D 0x6B41 # 0 +0x9A4E 0x6B42 # 0 +0x9A4F 0x6B44 # 0 +0x9A50 0x6B45 # 0 +0x9A51 0x6B48 # 0 +0x9A52 0x6B4A # 0 +0x9A53 0x6B4B # 0 +0x9A54 0x6B4D # 0 +0x9A55 0x6B4E # 0 +0x9A56 0x6B4F # 0 +0x9A57 0x6B50 # 0 +0x9A58 0x6B51 # 0 +0x9A59 0x6B52 # 0 +0x9A5A 0x6B53 # 0 +0x9A5B 0x6B54 # 0 +0x9A5C 0x6B55 # 0 +0x9A5D 0x6B56 # 0 +0x9A5E 0x6B57 # 0 +0x9A5F 0x6B58 # 0 +0x9A60 0x6B5A # 0 +0x9A61 0x6B5B # 0 +0x9A62 0x6B5C # 0 +0x9A63 0x6B5D # 0 +0x9A64 0x6B5E # 0 +0x9A65 0x6B5F # 0 +0x9A66 0x6B60 # 0 +0x9A67 0x6B61 # 0 +0x9A68 0x6B68 # 0 +0x9A69 0x6B69 # 0 +0x9A6A 0x6B6B # 0 +0x9A6B 0x6B6C # 0 +0x9A6C 0x6B6D # 0 +0x9A6D 0x6B6E # 0 +0x9A6E 0x6B6F # 0 +0x9A6F 0x6B70 # 0 +0x9A70 0x6B71 # 0 +0x9A71 0x6B72 # 0 +0x9A72 0x6B73 # 0 +0x9A73 0x6B74 # 0 +0x9A74 0x6B75 # 0 +0x9A75 0x6B76 # 0 +0x9A76 0x6B77 # 0 +0x9A77 0x6B78 # 0 +0x9A78 0x6B7A # 0 +0x9A79 0x6B7D # 0 +0x9A7A 0x6B7E # 0 +0x9A7B 0x6B7F # 0 +0x9A7C 0x6B80 # 0 +0x9A7D 0x6B85 # 0 +0x9A7E 0x6B88 # 0 +0x9A80 0x6B8C # 0 +0x9A81 0x6B8E # 0 +0x9A82 0x6B8F # 0 +0x9A83 0x6B90 # 0 +0x9A84 0x6B91 # 0 +0x9A85 0x6B94 # 0 +0x9A86 0x6B95 # 0 +0x9A87 0x6B97 # 0 +0x9A88 0x6B98 # 0 +0x9A89 0x6B99 # 0 +0x9A8A 0x6B9C # 0 +0x9A8B 0x6B9D # 0 +0x9A8C 0x6B9E # 0 +0x9A8D 0x6B9F # 0 +0x9A8E 0x6BA0 # 0 +0x9A8F 0x6BA2 # 0 +0x9A90 0x6BA3 # 0 +0x9A91 0x6BA4 # 0 +0x9A92 0x6BA5 # 0 +0x9A93 0x6BA6 # 0 +0x9A94 0x6BA7 # 0 +0x9A95 0x6BA8 # 0 +0x9A96 0x6BA9 # 0 +0x9A97 0x6BAB # 0 +0x9A98 0x6BAC # 0 +0x9A99 0x6BAD # 0 +0x9A9A 0x6BAE # 0 +0x9A9B 0x6BAF # 0 +0x9A9C 0x6BB0 # 0 +0x9A9D 0x6BB1 # 0 +0x9A9E 0x6BB2 # 0 +0x9A9F 0x6BB6 # 0 +0x9AA0 0x6BB8 # 0 +0x9AA1 0x6BB9 # 0 +0x9AA2 0x6BBA # 0 +0x9AA3 0x6BBB # 0 +0x9AA4 0x6BBC # 0 +0x9AA5 0x6BBD # 0 +0x9AA6 0x6BBE # 0 +0x9AA7 0x6BC0 # 0 +0x9AA8 0x6BC3 # 0 +0x9AA9 0x6BC4 # 0 +0x9AAA 0x6BC6 # 0 +0x9AAB 0x6BC7 # 0 +0x9AAC 0x6BC8 # 0 +0x9AAD 0x6BC9 # 0 +0x9AAE 0x6BCA # 0 +0x9AAF 0x6BCC # 0 +0x9AB0 0x6BCE # 0 +0x9AB1 0x6BD0 # 0 +0x9AB2 0x6BD1 # 0 +0x9AB3 0x6BD8 # 0 +0x9AB4 0x6BDA # 0 +0x9AB5 0x6BDC # 0 +0x9AB6 0x6BDD # 0 +0x9AB7 0x6BDE # 0 +0x9AB8 0x6BDF # 0 +0x9AB9 0x6BE0 # 0 +0x9ABA 0x6BE2 # 0 +0x9ABB 0x6BE3 # 0 +0x9ABC 0x6BE4 # 0 +0x9ABD 0x6BE5 # 0 +0x9ABE 0x6BE6 # 0 +0x9ABF 0x6BE7 # 0 +0x9AC0 0x6BE8 # 0 +0x9AC1 0x6BE9 # 0 +0x9AC2 0x6BEC # 0 +0x9AC3 0x6BED # 0 +0x9AC4 0x6BEE # 0 +0x9AC5 0x6BF0 # 0 +0x9AC6 0x6BF1 # 0 +0x9AC7 0x6BF2 # 0 +0x9AC8 0x6BF4 # 0 +0x9AC9 0x6BF6 # 0 +0x9ACA 0x6BF7 # 0 +0x9ACB 0x6BF8 # 0 +0x9ACC 0x6BFA # 0 +0x9ACD 0x6BFB # 0 +0x9ACE 0x6BFC # 0 +0x9ACF 0x6BFE # 0 +0x9AD0 0x6BFF # 0 +0x9AD1 0x6C00 # 0 +0x9AD2 0x6C01 # 0 +0x9AD3 0x6C02 # 0 +0x9AD4 0x6C03 # 0 +0x9AD5 0x6C04 # 0 +0x9AD6 0x6C08 # 0 +0x9AD7 0x6C09 # 0 +0x9AD8 0x6C0A # 0 +0x9AD9 0x6C0B # 0 +0x9ADA 0x6C0C # 0 +0x9ADB 0x6C0E # 0 +0x9ADC 0x6C12 # 0 +0x9ADD 0x6C17 # 0 +0x9ADE 0x6C1C # 0 +0x9ADF 0x6C1D # 0 +0x9AE0 0x6C1E # 0 +0x9AE1 0x6C20 # 0 +0x9AE2 0x6C23 # 0 +0x9AE3 0x6C25 # 0 +0x9AE4 0x6C2B # 0 +0x9AE5 0x6C2C # 0 +0x9AE6 0x6C2D # 0 +0x9AE7 0x6C31 # 0 +0x9AE8 0x6C33 # 0 +0x9AE9 0x6C36 # 0 +0x9AEA 0x6C37 # 0 +0x9AEB 0x6C39 # 0 +0x9AEC 0x6C3A # 0 +0x9AED 0x6C3B # 0 +0x9AEE 0x6C3C # 0 +0x9AEF 0x6C3E # 0 +0x9AF0 0x6C3F # 0 +0x9AF1 0x6C43 # 0 +0x9AF2 0x6C44 # 0 +0x9AF3 0x6C45 # 0 +0x9AF4 0x6C48 # 0 +0x9AF5 0x6C4B # 0 +0x9AF6 0x6C4C # 0 +0x9AF7 0x6C4D # 0 +0x9AF8 0x6C4E # 0 +0x9AF9 0x6C4F # 0 +0x9AFA 0x6C51 # 0 +0x9AFB 0x6C52 # 0 +0x9AFC 0x6C53 # 0 +0x9AFD 0x6C56 # 0 +0x9AFE 0x6C58 # 0 +0x9B40 0x6C59 # 0 +0x9B41 0x6C5A # 0 +0x9B42 0x6C62 # 0 +0x9B43 0x6C63 # 0 +0x9B44 0x6C65 # 0 +0x9B45 0x6C66 # 0 +0x9B46 0x6C67 # 0 +0x9B47 0x6C6B # 0 +0x9B48 0x6C6C # 0 +0x9B49 0x6C6D # 0 +0x9B4A 0x6C6E # 0 +0x9B4B 0x6C6F # 0 +0x9B4C 0x6C71 # 0 +0x9B4D 0x6C73 # 0 +0x9B4E 0x6C75 # 0 +0x9B4F 0x6C77 # 0 +0x9B50 0x6C78 # 0 +0x9B51 0x6C7A # 0 +0x9B52 0x6C7B # 0 +0x9B53 0x6C7C # 0 +0x9B54 0x6C7F # 0 +0x9B55 0x6C80 # 0 +0x9B56 0x6C84 # 0 +0x9B57 0x6C87 # 0 +0x9B58 0x6C8A # 0 +0x9B59 0x6C8B # 0 +0x9B5A 0x6C8D # 0 +0x9B5B 0x6C8E # 0 +0x9B5C 0x6C91 # 0 +0x9B5D 0x6C92 # 0 +0x9B5E 0x6C95 # 0 +0x9B5F 0x6C96 # 0 +0x9B60 0x6C97 # 0 +0x9B61 0x6C98 # 0 +0x9B62 0x6C9A # 0 +0x9B63 0x6C9C # 0 +0x9B64 0x6C9D # 0 +0x9B65 0x6C9E # 0 +0x9B66 0x6CA0 # 0 +0x9B67 0x6CA2 # 0 +0x9B68 0x6CA8 # 0 +0x9B69 0x6CAC # 0 +0x9B6A 0x6CAF # 0 +0x9B6B 0x6CB0 # 0 +0x9B6C 0x6CB4 # 0 +0x9B6D 0x6CB5 # 0 +0x9B6E 0x6CB6 # 0 +0x9B6F 0x6CB7 # 0 +0x9B70 0x6CBA # 0 +0x9B71 0x6CC0 # 0 +0x9B72 0x6CC1 # 0 +0x9B73 0x6CC2 # 0 +0x9B74 0x6CC3 # 0 +0x9B75 0x6CC6 # 0 +0x9B76 0x6CC7 # 0 +0x9B77 0x6CC8 # 0 +0x9B78 0x6CCB # 0 +0x9B79 0x6CCD # 0 +0x9B7A 0x6CCE # 0 +0x9B7B 0x6CCF # 0 +0x9B7C 0x6CD1 # 0 +0x9B7D 0x6CD2 # 0 +0x9B7E 0x6CD8 # 0 +0x9B80 0x6CD9 # 0 +0x9B81 0x6CDA # 0 +0x9B82 0x6CDC # 0 +0x9B83 0x6CDD # 0 +0x9B84 0x6CDF # 0 +0x9B85 0x6CE4 # 0 +0x9B86 0x6CE6 # 0 +0x9B87 0x6CE7 # 0 +0x9B88 0x6CE9 # 0 +0x9B89 0x6CEC # 0 +0x9B8A 0x6CED # 0 +0x9B8B 0x6CF2 # 0 +0x9B8C 0x6CF4 # 0 +0x9B8D 0x6CF9 # 0 +0x9B8E 0x6CFF # 0 +0x9B8F 0x6D00 # 0 +0x9B90 0x6D02 # 0 +0x9B91 0x6D03 # 0 +0x9B92 0x6D05 # 0 +0x9B93 0x6D06 # 0 +0x9B94 0x6D08 # 0 +0x9B95 0x6D09 # 0 +0x9B96 0x6D0A # 0 +0x9B97 0x6D0D # 0 +0x9B98 0x6D0F # 0 +0x9B99 0x6D10 # 0 +0x9B9A 0x6D11 # 0 +0x9B9B 0x6D13 # 0 +0x9B9C 0x6D14 # 0 +0x9B9D 0x6D15 # 0 +0x9B9E 0x6D16 # 0 +0x9B9F 0x6D18 # 0 +0x9BA0 0x6D1C # 0 +0x9BA1 0x6D1D # 0 +0x9BA2 0x6D1F # 0 +0x9BA3 0x6D20 # 0 +0x9BA4 0x6D21 # 0 +0x9BA5 0x6D22 # 0 +0x9BA6 0x6D23 # 0 +0x9BA7 0x6D24 # 0 +0x9BA8 0x6D26 # 0 +0x9BA9 0x6D28 # 0 +0x9BAA 0x6D29 # 0 +0x9BAB 0x6D2C # 0 +0x9BAC 0x6D2D # 0 +0x9BAD 0x6D2F # 0 +0x9BAE 0x6D30 # 0 +0x9BAF 0x6D34 # 0 +0x9BB0 0x6D36 # 0 +0x9BB1 0x6D37 # 0 +0x9BB2 0x6D38 # 0 +0x9BB3 0x6D3A # 0 +0x9BB4 0x6D3F # 0 +0x9BB5 0x6D40 # 0 +0x9BB6 0x6D42 # 0 +0x9BB7 0x6D44 # 0 +0x9BB8 0x6D49 # 0 +0x9BB9 0x6D4C # 0 +0x9BBA 0x6D50 # 0 +0x9BBB 0x6D55 # 0 +0x9BBC 0x6D56 # 0 +0x9BBD 0x6D57 # 0 +0x9BBE 0x6D58 # 0 +0x9BBF 0x6D5B # 0 +0x9BC0 0x6D5D # 0 +0x9BC1 0x6D5F # 0 +0x9BC2 0x6D61 # 0 +0x9BC3 0x6D62 # 0 +0x9BC4 0x6D64 # 0 +0x9BC5 0x6D65 # 0 +0x9BC6 0x6D67 # 0 +0x9BC7 0x6D68 # 0 +0x9BC8 0x6D6B # 0 +0x9BC9 0x6D6C # 0 +0x9BCA 0x6D6D # 0 +0x9BCB 0x6D70 # 0 +0x9BCC 0x6D71 # 0 +0x9BCD 0x6D72 # 0 +0x9BCE 0x6D73 # 0 +0x9BCF 0x6D75 # 0 +0x9BD0 0x6D76 # 0 +0x9BD1 0x6D79 # 0 +0x9BD2 0x6D7A # 0 +0x9BD3 0x6D7B # 0 +0x9BD4 0x6D7D # 0 +0x9BD5 0x6D7E # 0 +0x9BD6 0x6D7F # 0 +0x9BD7 0x6D80 # 0 +0x9BD8 0x6D81 # 0 +0x9BD9 0x6D83 # 0 +0x9BDA 0x6D84 # 0 +0x9BDB 0x6D86 # 0 +0x9BDC 0x6D87 # 0 +0x9BDD 0x6D8A # 0 +0x9BDE 0x6D8B # 0 +0x9BDF 0x6D8D # 0 +0x9BE0 0x6D8F # 0 +0x9BE1 0x6D90 # 0 +0x9BE2 0x6D92 # 0 +0x9BE3 0x6D96 # 0 +0x9BE4 0x6D97 # 0 +0x9BE5 0x6D98 # 0 +0x9BE6 0x6D99 # 0 +0x9BE7 0x6D9A # 0 +0x9BE8 0x6D9C # 0 +0x9BE9 0x6DA2 # 0 +0x9BEA 0x6DA5 # 0 +0x9BEB 0x6DAC # 0 +0x9BEC 0x6DAD # 0 +0x9BED 0x6DB0 # 0 +0x9BEE 0x6DB1 # 0 +0x9BEF 0x6DB3 # 0 +0x9BF0 0x6DB4 # 0 +0x9BF1 0x6DB6 # 0 +0x9BF2 0x6DB7 # 0 +0x9BF3 0x6DB9 # 0 +0x9BF4 0x6DBA # 0 +0x9BF5 0x6DBB # 0 +0x9BF6 0x6DBC # 0 +0x9BF7 0x6DBD # 0 +0x9BF8 0x6DBE # 0 +0x9BF9 0x6DC1 # 0 +0x9BFA 0x6DC2 # 0 +0x9BFB 0x6DC3 # 0 +0x9BFC 0x6DC8 # 0 +0x9BFD 0x6DC9 # 0 +0x9BFE 0x6DCA # 0 +0x9C40 0x6DCD # 0 +0x9C41 0x6DCE # 0 +0x9C42 0x6DCF # 0 +0x9C43 0x6DD0 # 0 +0x9C44 0x6DD2 # 0 +0x9C45 0x6DD3 # 0 +0x9C46 0x6DD4 # 0 +0x9C47 0x6DD5 # 0 +0x9C48 0x6DD7 # 0 +0x9C49 0x6DDA # 0 +0x9C4A 0x6DDB # 0 +0x9C4B 0x6DDC # 0 +0x9C4C 0x6DDF # 0 +0x9C4D 0x6DE2 # 0 +0x9C4E 0x6DE3 # 0 +0x9C4F 0x6DE5 # 0 +0x9C50 0x6DE7 # 0 +0x9C51 0x6DE8 # 0 +0x9C52 0x6DE9 # 0 +0x9C53 0x6DEA # 0 +0x9C54 0x6DED # 0 +0x9C55 0x6DEF # 0 +0x9C56 0x6DF0 # 0 +0x9C57 0x6DF2 # 0 +0x9C58 0x6DF4 # 0 +0x9C59 0x6DF5 # 0 +0x9C5A 0x6DF6 # 0 +0x9C5B 0x6DF8 # 0 +0x9C5C 0x6DFA # 0 +0x9C5D 0x6DFD # 0 +0x9C5E 0x6DFE # 0 +0x9C5F 0x6DFF # 0 +0x9C60 0x6E00 # 0 +0x9C61 0x6E01 # 0 +0x9C62 0x6E02 # 0 +0x9C63 0x6E03 # 0 +0x9C64 0x6E04 # 0 +0x9C65 0x6E06 # 0 +0x9C66 0x6E07 # 0 +0x9C67 0x6E08 # 0 +0x9C68 0x6E09 # 0 +0x9C69 0x6E0B # 0 +0x9C6A 0x6E0F # 0 +0x9C6B 0x6E12 # 0 +0x9C6C 0x6E13 # 0 +0x9C6D 0x6E15 # 0 +0x9C6E 0x6E18 # 0 +0x9C6F 0x6E19 # 0 +0x9C70 0x6E1B # 0 +0x9C71 0x6E1C # 0 +0x9C72 0x6E1E # 0 +0x9C73 0x6E1F # 0 +0x9C74 0x6E22 # 0 +0x9C75 0x6E26 # 0 +0x9C76 0x6E27 # 0 +0x9C77 0x6E28 # 0 +0x9C78 0x6E2A # 0 +0x9C79 0x6E2C # 0 +0x9C7A 0x6E2E # 0 +0x9C7B 0x6E30 # 0 +0x9C7C 0x6E31 # 0 +0x9C7D 0x6E33 # 0 +0x9C7E 0x6E35 # 0 +0x9C80 0x6E36 # 0 +0x9C81 0x6E37 # 0 +0x9C82 0x6E39 # 0 +0x9C83 0x6E3B # 0 +0x9C84 0x6E3C # 0 +0x9C85 0x6E3D # 0 +0x9C86 0x6E3E # 0 +0x9C87 0x6E3F # 0 +0x9C88 0x6E40 # 0 +0x9C89 0x6E41 # 0 +0x9C8A 0x6E42 # 0 +0x9C8B 0x6E45 # 0 +0x9C8C 0x6E46 # 0 +0x9C8D 0x6E47 # 0 +0x9C8E 0x6E48 # 0 +0x9C8F 0x6E49 # 0 +0x9C90 0x6E4A # 0 +0x9C91 0x6E4B # 0 +0x9C92 0x6E4C # 0 +0x9C93 0x6E4F # 0 +0x9C94 0x6E50 # 0 +0x9C95 0x6E51 # 0 +0x9C96 0x6E52 # 0 +0x9C97 0x6E55 # 0 +0x9C98 0x6E57 # 0 +0x9C99 0x6E59 # 0 +0x9C9A 0x6E5A # 0 +0x9C9B 0x6E5C # 0 +0x9C9C 0x6E5D # 0 +0x9C9D 0x6E5E # 0 +0x9C9E 0x6E60 # 0 +0x9C9F 0x6E61 # 0 +0x9CA0 0x6E62 # 0 +0x9CA1 0x6E63 # 0 +0x9CA2 0x6E64 # 0 +0x9CA3 0x6E65 # 0 +0x9CA4 0x6E66 # 0 +0x9CA5 0x6E67 # 0 +0x9CA6 0x6E68 # 0 +0x9CA7 0x6E69 # 0 +0x9CA8 0x6E6A # 0 +0x9CA9 0x6E6C # 0 +0x9CAA 0x6E6D # 0 +0x9CAB 0x6E6F # 0 +0x9CAC 0x6E70 # 0 +0x9CAD 0x6E71 # 0 +0x9CAE 0x6E72 # 0 +0x9CAF 0x6E73 # 0 +0x9CB0 0x6E74 # 0 +0x9CB1 0x6E75 # 0 +0x9CB2 0x6E76 # 0 +0x9CB3 0x6E77 # 0 +0x9CB4 0x6E78 # 0 +0x9CB5 0x6E79 # 0 +0x9CB6 0x6E7A # 0 +0x9CB7 0x6E7B # 0 +0x9CB8 0x6E7C # 0 +0x9CB9 0x6E7D # 0 +0x9CBA 0x6E80 # 0 +0x9CBB 0x6E81 # 0 +0x9CBC 0x6E82 # 0 +0x9CBD 0x6E84 # 0 +0x9CBE 0x6E87 # 0 +0x9CBF 0x6E88 # 0 +0x9CC0 0x6E8A # 0 +0x9CC1 0x6E8B # 0 +0x9CC2 0x6E8C # 0 +0x9CC3 0x6E8D # 0 +0x9CC4 0x6E8E # 0 +0x9CC5 0x6E91 # 0 +0x9CC6 0x6E92 # 0 +0x9CC7 0x6E93 # 0 +0x9CC8 0x6E94 # 0 +0x9CC9 0x6E95 # 0 +0x9CCA 0x6E96 # 0 +0x9CCB 0x6E97 # 0 +0x9CCC 0x6E99 # 0 +0x9CCD 0x6E9A # 0 +0x9CCE 0x6E9B # 0 +0x9CCF 0x6E9D # 0 +0x9CD0 0x6E9E # 0 +0x9CD1 0x6EA0 # 0 +0x9CD2 0x6EA1 # 0 +0x9CD3 0x6EA3 # 0 +0x9CD4 0x6EA4 # 0 +0x9CD5 0x6EA6 # 0 +0x9CD6 0x6EA8 # 0 +0x9CD7 0x6EA9 # 0 +0x9CD8 0x6EAB # 0 +0x9CD9 0x6EAC # 0 +0x9CDA 0x6EAD # 0 +0x9CDB 0x6EAE # 0 +0x9CDC 0x6EB0 # 0 +0x9CDD 0x6EB3 # 0 +0x9CDE 0x6EB5 # 0 +0x9CDF 0x6EB8 # 0 +0x9CE0 0x6EB9 # 0 +0x9CE1 0x6EBC # 0 +0x9CE2 0x6EBE # 0 +0x9CE3 0x6EBF # 0 +0x9CE4 0x6EC0 # 0 +0x9CE5 0x6EC3 # 0 +0x9CE6 0x6EC4 # 0 +0x9CE7 0x6EC5 # 0 +0x9CE8 0x6EC6 # 0 +0x9CE9 0x6EC8 # 0 +0x9CEA 0x6EC9 # 0 +0x9CEB 0x6ECA # 0 +0x9CEC 0x6ECC # 0 +0x9CED 0x6ECD # 0 +0x9CEE 0x6ECE # 0 +0x9CEF 0x6ED0 # 0 +0x9CF0 0x6ED2 # 0 +0x9CF1 0x6ED6 # 0 +0x9CF2 0x6ED8 # 0 +0x9CF3 0x6ED9 # 0 +0x9CF4 0x6EDB # 0 +0x9CF5 0x6EDC # 0 +0x9CF6 0x6EDD # 0 +0x9CF7 0x6EE3 # 0 +0x9CF8 0x6EE7 # 0 +0x9CF9 0x6EEA # 0 +0x9CFA 0x6EEB # 0 +0x9CFB 0x6EEC # 0 +0x9CFC 0x6EED # 0 +0x9CFD 0x6EEE # 0 +0x9CFE 0x6EEF # 0 +0x9D40 0x6EF0 # 0 +0x9D41 0x6EF1 # 0 +0x9D42 0x6EF2 # 0 +0x9D43 0x6EF3 # 0 +0x9D44 0x6EF5 # 0 +0x9D45 0x6EF6 # 0 +0x9D46 0x6EF7 # 0 +0x9D47 0x6EF8 # 0 +0x9D48 0x6EFA # 0 +0x9D49 0x6EFB # 0 +0x9D4A 0x6EFC # 0 +0x9D4B 0x6EFD # 0 +0x9D4C 0x6EFE # 0 +0x9D4D 0x6EFF # 0 +0x9D4E 0x6F00 # 0 +0x9D4F 0x6F01 # 0 +0x9D50 0x6F03 # 0 +0x9D51 0x6F04 # 0 +0x9D52 0x6F05 # 0 +0x9D53 0x6F07 # 0 +0x9D54 0x6F08 # 0 +0x9D55 0x6F0A # 0 +0x9D56 0x6F0B # 0 +0x9D57 0x6F0C # 0 +0x9D58 0x6F0D # 0 +0x9D59 0x6F0E # 0 +0x9D5A 0x6F10 # 0 +0x9D5B 0x6F11 # 0 +0x9D5C 0x6F12 # 0 +0x9D5D 0x6F16 # 0 +0x9D5E 0x6F17 # 0 +0x9D5F 0x6F18 # 0 +0x9D60 0x6F19 # 0 +0x9D61 0x6F1A # 0 +0x9D62 0x6F1B # 0 +0x9D63 0x6F1C # 0 +0x9D64 0x6F1D # 0 +0x9D65 0x6F1E # 0 +0x9D66 0x6F1F # 0 +0x9D67 0x6F21 # 0 +0x9D68 0x6F22 # 0 +0x9D69 0x6F23 # 0 +0x9D6A 0x6F25 # 0 +0x9D6B 0x6F26 # 0 +0x9D6C 0x6F27 # 0 +0x9D6D 0x6F28 # 0 +0x9D6E 0x6F2C # 0 +0x9D6F 0x6F2E # 0 +0x9D70 0x6F30 # 0 +0x9D71 0x6F32 # 0 +0x9D72 0x6F34 # 0 +0x9D73 0x6F35 # 0 +0x9D74 0x6F37 # 0 +0x9D75 0x6F38 # 0 +0x9D76 0x6F39 # 0 +0x9D77 0x6F3A # 0 +0x9D78 0x6F3B # 0 +0x9D79 0x6F3C # 0 +0x9D7A 0x6F3D # 0 +0x9D7B 0x6F3F # 0 +0x9D7C 0x6F40 # 0 +0x9D7D 0x6F41 # 0 +0x9D7E 0x6F42 # 0 +0x9D80 0x6F43 # 0 +0x9D81 0x6F44 # 0 +0x9D82 0x6F45 # 0 +0x9D83 0x6F48 # 0 +0x9D84 0x6F49 # 0 +0x9D85 0x6F4A # 0 +0x9D86 0x6F4C # 0 +0x9D87 0x6F4E # 0 +0x9D88 0x6F4F # 0 +0x9D89 0x6F50 # 0 +0x9D8A 0x6F51 # 0 +0x9D8B 0x6F52 # 0 +0x9D8C 0x6F53 # 0 +0x9D8D 0x6F54 # 0 +0x9D8E 0x6F55 # 0 +0x9D8F 0x6F56 # 0 +0x9D90 0x6F57 # 0 +0x9D91 0x6F59 # 0 +0x9D92 0x6F5A # 0 +0x9D93 0x6F5B # 0 +0x9D94 0x6F5D # 0 +0x9D95 0x6F5F # 0 +0x9D96 0x6F60 # 0 +0x9D97 0x6F61 # 0 +0x9D98 0x6F63 # 0 +0x9D99 0x6F64 # 0 +0x9D9A 0x6F65 # 0 +0x9D9B 0x6F67 # 0 +0x9D9C 0x6F68 # 0 +0x9D9D 0x6F69 # 0 +0x9D9E 0x6F6A # 0 +0x9D9F 0x6F6B # 0 +0x9DA0 0x6F6C # 0 +0x9DA1 0x6F6F # 0 +0x9DA2 0x6F70 # 0 +0x9DA3 0x6F71 # 0 +0x9DA4 0x6F73 # 0 +0x9DA5 0x6F75 # 0 +0x9DA6 0x6F76 # 0 +0x9DA7 0x6F77 # 0 +0x9DA8 0x6F79 # 0 +0x9DA9 0x6F7B # 0 +0x9DAA 0x6F7D # 0 +0x9DAB 0x6F7E # 0 +0x9DAC 0x6F7F # 0 +0x9DAD 0x6F80 # 0 +0x9DAE 0x6F81 # 0 +0x9DAF 0x6F82 # 0 +0x9DB0 0x6F83 # 0 +0x9DB1 0x6F85 # 0 +0x9DB2 0x6F86 # 0 +0x9DB3 0x6F87 # 0 +0x9DB4 0x6F8A # 0 +0x9DB5 0x6F8B # 0 +0x9DB6 0x6F8F # 0 +0x9DB7 0x6F90 # 0 +0x9DB8 0x6F91 # 0 +0x9DB9 0x6F92 # 0 +0x9DBA 0x6F93 # 0 +0x9DBB 0x6F94 # 0 +0x9DBC 0x6F95 # 0 +0x9DBD 0x6F96 # 0 +0x9DBE 0x6F97 # 0 +0x9DBF 0x6F98 # 0 +0x9DC0 0x6F99 # 0 +0x9DC1 0x6F9A # 0 +0x9DC2 0x6F9B # 0 +0x9DC3 0x6F9D # 0 +0x9DC4 0x6F9E # 0 +0x9DC5 0x6F9F # 0 +0x9DC6 0x6FA0 # 0 +0x9DC7 0x6FA2 # 0 +0x9DC8 0x6FA3 # 0 +0x9DC9 0x6FA4 # 0 +0x9DCA 0x6FA5 # 0 +0x9DCB 0x6FA6 # 0 +0x9DCC 0x6FA8 # 0 +0x9DCD 0x6FA9 # 0 +0x9DCE 0x6FAA # 0 +0x9DCF 0x6FAB # 0 +0x9DD0 0x6FAC # 0 +0x9DD1 0x6FAD # 0 +0x9DD2 0x6FAE # 0 +0x9DD3 0x6FAF # 0 +0x9DD4 0x6FB0 # 0 +0x9DD5 0x6FB1 # 0 +0x9DD6 0x6FB2 # 0 +0x9DD7 0x6FB4 # 0 +0x9DD8 0x6FB5 # 0 +0x9DD9 0x6FB7 # 0 +0x9DDA 0x6FB8 # 0 +0x9DDB 0x6FBA # 0 +0x9DDC 0x6FBB # 0 +0x9DDD 0x6FBC # 0 +0x9DDE 0x6FBD # 0 +0x9DDF 0x6FBE # 0 +0x9DE0 0x6FBF # 0 +0x9DE1 0x6FC1 # 0 +0x9DE2 0x6FC3 # 0 +0x9DE3 0x6FC4 # 0 +0x9DE4 0x6FC5 # 0 +0x9DE5 0x6FC6 # 0 +0x9DE6 0x6FC7 # 0 +0x9DE7 0x6FC8 # 0 +0x9DE8 0x6FCA # 0 +0x9DE9 0x6FCB # 0 +0x9DEA 0x6FCC # 0 +0x9DEB 0x6FCD # 0 +0x9DEC 0x6FCE # 0 +0x9DED 0x6FCF # 0 +0x9DEE 0x6FD0 # 0 +0x9DEF 0x6FD3 # 0 +0x9DF0 0x6FD4 # 0 +0x9DF1 0x6FD5 # 0 +0x9DF2 0x6FD6 # 0 +0x9DF3 0x6FD7 # 0 +0x9DF4 0x6FD8 # 0 +0x9DF5 0x6FD9 # 0 +0x9DF6 0x6FDA # 0 +0x9DF7 0x6FDB # 0 +0x9DF8 0x6FDC # 0 +0x9DF9 0x6FDD # 0 +0x9DFA 0x6FDF # 0 +0x9DFB 0x6FE2 # 0 +0x9DFC 0x6FE3 # 0 +0x9DFD 0x6FE4 # 0 +0x9DFE 0x6FE5 # 0 +0x9E40 0x6FE6 # 0 +0x9E41 0x6FE7 # 0 +0x9E42 0x6FE8 # 0 +0x9E43 0x6FE9 # 0 +0x9E44 0x6FEA # 0 +0x9E45 0x6FEB # 0 +0x9E46 0x6FEC # 0 +0x9E47 0x6FED # 0 +0x9E48 0x6FF0 # 0 +0x9E49 0x6FF1 # 0 +0x9E4A 0x6FF2 # 0 +0x9E4B 0x6FF3 # 0 +0x9E4C 0x6FF4 # 0 +0x9E4D 0x6FF5 # 0 +0x9E4E 0x6FF6 # 0 +0x9E4F 0x6FF7 # 0 +0x9E50 0x6FF8 # 0 +0x9E51 0x6FF9 # 0 +0x9E52 0x6FFA # 0 +0x9E53 0x6FFB # 0 +0x9E54 0x6FFC # 0 +0x9E55 0x6FFD # 0 +0x9E56 0x6FFE # 0 +0x9E57 0x6FFF # 0 +0x9E58 0x7000 # 0 +0x9E59 0x7001 # 0 +0x9E5A 0x7002 # 0 +0x9E5B 0x7003 # 0 +0x9E5C 0x7004 # 0 +0x9E5D 0x7005 # 0 +0x9E5E 0x7006 # 0 +0x9E5F 0x7007 # 0 +0x9E60 0x7008 # 0 +0x9E61 0x7009 # 0 +0x9E62 0x700A # 0 +0x9E63 0x700B # 0 +0x9E64 0x700C # 0 +0x9E65 0x700D # 0 +0x9E66 0x700E # 0 +0x9E67 0x700F # 0 +0x9E68 0x7010 # 0 +0x9E69 0x7012 # 0 +0x9E6A 0x7013 # 0 +0x9E6B 0x7014 # 0 +0x9E6C 0x7015 # 0 +0x9E6D 0x7016 # 0 +0x9E6E 0x7017 # 0 +0x9E6F 0x7018 # 0 +0x9E70 0x7019 # 0 +0x9E71 0x701C # 0 +0x9E72 0x701D # 0 +0x9E73 0x701E # 0 +0x9E74 0x701F # 0 +0x9E75 0x7020 # 0 +0x9E76 0x7021 # 0 +0x9E77 0x7022 # 0 +0x9E78 0x7024 # 0 +0x9E79 0x7025 # 0 +0x9E7A 0x7026 # 0 +0x9E7B 0x7027 # 0 +0x9E7C 0x7028 # 0 +0x9E7D 0x7029 # 0 +0x9E7E 0x702A # 0 +0x9E80 0x702B # 0 +0x9E81 0x702C # 0 +0x9E82 0x702D # 0 +0x9E83 0x702E # 0 +0x9E84 0x702F # 0 +0x9E85 0x7030 # 0 +0x9E86 0x7031 # 0 +0x9E87 0x7032 # 0 +0x9E88 0x7033 # 0 +0x9E89 0x7034 # 0 +0x9E8A 0x7036 # 0 +0x9E8B 0x7037 # 0 +0x9E8C 0x7038 # 0 +0x9E8D 0x703A # 0 +0x9E8E 0x703B # 0 +0x9E8F 0x703C # 0 +0x9E90 0x703D # 0 +0x9E91 0x703E # 0 +0x9E92 0x703F # 0 +0x9E93 0x7040 # 0 +0x9E94 0x7041 # 0 +0x9E95 0x7042 # 0 +0x9E96 0x7043 # 0 +0x9E97 0x7044 # 0 +0x9E98 0x7045 # 0 +0x9E99 0x7046 # 0 +0x9E9A 0x7047 # 0 +0x9E9B 0x7048 # 0 +0x9E9C 0x7049 # 0 +0x9E9D 0x704A # 0 +0x9E9E 0x704B # 0 +0x9E9F 0x704D # 0 +0x9EA0 0x704E # 0 +0x9EA1 0x7050 # 0 +0x9EA2 0x7051 # 0 +0x9EA3 0x7052 # 0 +0x9EA4 0x7053 # 0 +0x9EA5 0x7054 # 0 +0x9EA6 0x7055 # 0 +0x9EA7 0x7056 # 0 +0x9EA8 0x7057 # 0 +0x9EA9 0x7058 # 0 +0x9EAA 0x7059 # 0 +0x9EAB 0x705A # 0 +0x9EAC 0x705B # 0 +0x9EAD 0x705C # 0 +0x9EAE 0x705D # 0 +0x9EAF 0x705F # 0 +0x9EB0 0x7060 # 0 +0x9EB1 0x7061 # 0 +0x9EB2 0x7062 # 0 +0x9EB3 0x7063 # 0 +0x9EB4 0x7064 # 0 +0x9EB5 0x7065 # 0 +0x9EB6 0x7066 # 0 +0x9EB7 0x7067 # 0 +0x9EB8 0x7068 # 0 +0x9EB9 0x7069 # 0 +0x9EBA 0x706A # 0 +0x9EBB 0x706E # 0 +0x9EBC 0x7071 # 0 +0x9EBD 0x7072 # 0 +0x9EBE 0x7073 # 0 +0x9EBF 0x7074 # 0 +0x9EC0 0x7077 # 0 +0x9EC1 0x7079 # 0 +0x9EC2 0x707A # 0 +0x9EC3 0x707B # 0 +0x9EC4 0x707D # 0 +0x9EC5 0x7081 # 0 +0x9EC6 0x7082 # 0 +0x9EC7 0x7083 # 0 +0x9EC8 0x7084 # 0 +0x9EC9 0x7086 # 0 +0x9ECA 0x7087 # 0 +0x9ECB 0x7088 # 0 +0x9ECC 0x708B # 0 +0x9ECD 0x708C # 0 +0x9ECE 0x708D # 0 +0x9ECF 0x708F # 0 +0x9ED0 0x7090 # 0 +0x9ED1 0x7091 # 0 +0x9ED2 0x7093 # 0 +0x9ED3 0x7097 # 0 +0x9ED4 0x7098 # 0 +0x9ED5 0x709A # 0 +0x9ED6 0x709B # 0 +0x9ED7 0x709E # 0 +0x9ED8 0x709F # 0 +0x9ED9 0x70A0 # 0 +0x9EDA 0x70A1 # 0 +0x9EDB 0x70A2 # 0 +0x9EDC 0x70A3 # 0 +0x9EDD 0x70A4 # 0 +0x9EDE 0x70A5 # 0 +0x9EDF 0x70A6 # 0 +0x9EE0 0x70A7 # 0 +0x9EE1 0x70A8 # 0 +0x9EE2 0x70A9 # 0 +0x9EE3 0x70AA # 0 +0x9EE4 0x70B0 # 0 +0x9EE5 0x70B2 # 0 +0x9EE6 0x70B4 # 0 +0x9EE7 0x70B5 # 0 +0x9EE8 0x70B6 # 0 +0x9EE9 0x70BA # 0 +0x9EEA 0x70BE # 0 +0x9EEB 0x70BF # 0 +0x9EEC 0x70C4 # 0 +0x9EED 0x70C5 # 0 +0x9EEE 0x70C6 # 0 +0x9EEF 0x70C7 # 0 +0x9EF0 0x70C9 # 0 +0x9EF1 0x70CB # 0 +0x9EF2 0x70CC # 0 +0x9EF3 0x70CD # 0 +0x9EF4 0x70CE # 0 +0x9EF5 0x70CF # 0 +0x9EF6 0x70D0 # 0 +0x9EF7 0x70D1 # 0 +0x9EF8 0x70D2 # 0 +0x9EF9 0x70D3 # 0 +0x9EFA 0x70D4 # 0 +0x9EFB 0x70D5 # 0 +0x9EFC 0x70D6 # 0 +0x9EFD 0x70D7 # 0 +0x9EFE 0x70DA # 0 +0x9F40 0x70DC # 0 +0x9F41 0x70DD # 0 +0x9F42 0x70DE # 0 +0x9F43 0x70E0 # 0 +0x9F44 0x70E1 # 0 +0x9F45 0x70E2 # 0 +0x9F46 0x70E3 # 0 +0x9F47 0x70E5 # 0 +0x9F48 0x70EA # 0 +0x9F49 0x70EE # 0 +0x9F4A 0x70F0 # 0 +0x9F4B 0x70F1 # 0 +0x9F4C 0x70F2 # 0 +0x9F4D 0x70F3 # 0 +0x9F4E 0x70F4 # 0 +0x9F4F 0x70F5 # 0 +0x9F50 0x70F6 # 0 +0x9F51 0x70F8 # 0 +0x9F52 0x70FA # 0 +0x9F53 0x70FB # 0 +0x9F54 0x70FC # 0 +0x9F55 0x70FE # 0 +0x9F56 0x70FF # 0 +0x9F57 0x7100 # 0 +0x9F58 0x7101 # 0 +0x9F59 0x7102 # 0 +0x9F5A 0x7103 # 0 +0x9F5B 0x7104 # 0 +0x9F5C 0x7105 # 0 +0x9F5D 0x7106 # 0 +0x9F5E 0x7107 # 0 +0x9F5F 0x7108 # 0 +0x9F60 0x710B # 0 +0x9F61 0x710C # 0 +0x9F62 0x710D # 0 +0x9F63 0x710E # 0 +0x9F64 0x710F # 0 +0x9F65 0x7111 # 0 +0x9F66 0x7112 # 0 +0x9F67 0x7114 # 0 +0x9F68 0x7117 # 0 +0x9F69 0x711B # 0 +0x9F6A 0x711C # 0 +0x9F6B 0x711D # 0 +0x9F6C 0x711E # 0 +0x9F6D 0x711F # 0 +0x9F6E 0x7120 # 0 +0x9F6F 0x7121 # 0 +0x9F70 0x7122 # 0 +0x9F71 0x7123 # 0 +0x9F72 0x7124 # 0 +0x9F73 0x7125 # 0 +0x9F74 0x7127 # 0 +0x9F75 0x7128 # 0 +0x9F76 0x7129 # 0 +0x9F77 0x712A # 0 +0x9F78 0x712B # 0 +0x9F79 0x712C # 0 +0x9F7A 0x712D # 0 +0x9F7B 0x712E # 0 +0x9F7C 0x7132 # 0 +0x9F7D 0x7133 # 0 +0x9F7E 0x7134 # 0 +0x9F80 0x7135 # 0 +0x9F81 0x7137 # 0 +0x9F82 0x7138 # 0 +0x9F83 0x7139 # 0 +0x9F84 0x713A # 0 +0x9F85 0x713B # 0 +0x9F86 0x713C # 0 +0x9F87 0x713D # 0 +0x9F88 0x713E # 0 +0x9F89 0x713F # 0 +0x9F8A 0x7140 # 0 +0x9F8B 0x7141 # 0 +0x9F8C 0x7142 # 0 +0x9F8D 0x7143 # 0 +0x9F8E 0x7144 # 0 +0x9F8F 0x7146 # 0 +0x9F90 0x7147 # 0 +0x9F91 0x7148 # 0 +0x9F92 0x7149 # 0 +0x9F93 0x714B # 0 +0x9F94 0x714D # 0 +0x9F95 0x714F # 0 +0x9F96 0x7150 # 0 +0x9F97 0x7151 # 0 +0x9F98 0x7152 # 0 +0x9F99 0x7153 # 0 +0x9F9A 0x7154 # 0 +0x9F9B 0x7155 # 0 +0x9F9C 0x7156 # 0 +0x9F9D 0x7157 # 0 +0x9F9E 0x7158 # 0 +0x9F9F 0x7159 # 0 +0x9FA0 0x715A # 0 +0x9FA1 0x715B # 0 +0x9FA2 0x715D # 0 +0x9FA3 0x715F # 0 +0x9FA4 0x7160 # 0 +0x9FA5 0x7161 # 0 +0x9FA6 0x7162 # 0 +0x9FA7 0x7163 # 0 +0x9FA8 0x7165 # 0 +0x9FA9 0x7169 # 0 +0x9FAA 0x716A # 0 +0x9FAB 0x716B # 0 +0x9FAC 0x716C # 0 +0x9FAD 0x716D # 0 +0x9FAE 0x716F # 0 +0x9FAF 0x7170 # 0 +0x9FB0 0x7171 # 0 +0x9FB1 0x7174 # 0 +0x9FB2 0x7175 # 0 +0x9FB3 0x7176 # 0 +0x9FB4 0x7177 # 0 +0x9FB5 0x7179 # 0 +0x9FB6 0x717B # 0 +0x9FB7 0x717C # 0 +0x9FB8 0x717E # 0 +0x9FB9 0x717F # 0 +0x9FBA 0x7180 # 0 +0x9FBB 0x7181 # 0 +0x9FBC 0x7182 # 0 +0x9FBD 0x7183 # 0 +0x9FBE 0x7185 # 0 +0x9FBF 0x7186 # 0 +0x9FC0 0x7187 # 0 +0x9FC1 0x7188 # 0 +0x9FC2 0x7189 # 0 +0x9FC3 0x718B # 0 +0x9FC4 0x718C # 0 +0x9FC5 0x718D # 0 +0x9FC6 0x718E # 0 +0x9FC7 0x7190 # 0 +0x9FC8 0x7191 # 0 +0x9FC9 0x7192 # 0 +0x9FCA 0x7193 # 0 +0x9FCB 0x7195 # 0 +0x9FCC 0x7196 # 0 +0x9FCD 0x7197 # 0 +0x9FCE 0x719A # 0 +0x9FCF 0x719B # 0 +0x9FD0 0x719C # 0 +0x9FD1 0x719D # 0 +0x9FD2 0x719E # 0 +0x9FD3 0x71A1 # 0 +0x9FD4 0x71A2 # 0 +0x9FD5 0x71A3 # 0 +0x9FD6 0x71A4 # 0 +0x9FD7 0x71A5 # 0 +0x9FD8 0x71A6 # 0 +0x9FD9 0x71A7 # 0 +0x9FDA 0x71A9 # 0 +0x9FDB 0x71AA # 0 +0x9FDC 0x71AB # 0 +0x9FDD 0x71AD # 0 +0x9FDE 0x71AE # 0 +0x9FDF 0x71AF # 0 +0x9FE0 0x71B0 # 0 +0x9FE1 0x71B1 # 0 +0x9FE2 0x71B2 # 0 +0x9FE3 0x71B4 # 0 +0x9FE4 0x71B6 # 0 +0x9FE5 0x71B7 # 0 +0x9FE6 0x71B8 # 0 +0x9FE7 0x71BA # 0 +0x9FE8 0x71BB # 0 +0x9FE9 0x71BC # 0 +0x9FEA 0x71BD # 0 +0x9FEB 0x71BE # 0 +0x9FEC 0x71BF # 0 +0x9FED 0x71C0 # 0 +0x9FEE 0x71C1 # 0 +0x9FEF 0x71C2 # 0 +0x9FF0 0x71C4 # 0 +0x9FF1 0x71C5 # 0 +0x9FF2 0x71C6 # 0 +0x9FF3 0x71C7 # 0 +0x9FF4 0x71C8 # 0 +0x9FF5 0x71C9 # 0 +0x9FF6 0x71CA # 0 +0x9FF7 0x71CB # 0 +0x9FF8 0x71CC # 0 +0x9FF9 0x71CD # 0 +0x9FFA 0x71CF # 0 +0x9FFB 0x71D0 # 0 +0x9FFC 0x71D1 # 0 +0x9FFD 0x71D2 # 0 +0x9FFE 0x71D3 # 0 +0xA040 0x71D6 # 0 +0xA041 0x71D7 # 0 +0xA042 0x71D8 # 0 +0xA043 0x71D9 # 0 +0xA044 0x71DA # 0 +0xA045 0x71DB # 0 +0xA046 0x71DC # 0 +0xA047 0x71DD # 0 +0xA048 0x71DE # 0 +0xA049 0x71DF # 0 +0xA04A 0x71E1 # 0 +0xA04B 0x71E2 # 0 +0xA04C 0x71E3 # 0 +0xA04D 0x71E4 # 0 +0xA04E 0x71E6 # 0 +0xA04F 0x71E8 # 0 +0xA050 0x71E9 # 0 +0xA051 0x71EA # 0 +0xA052 0x71EB # 0 +0xA053 0x71EC # 0 +0xA054 0x71ED # 0 +0xA055 0x71EF # 0 +0xA056 0x71F0 # 0 +0xA057 0x71F1 # 0 +0xA058 0x71F2 # 0 +0xA059 0x71F3 # 0 +0xA05A 0x71F4 # 0 +0xA05B 0x71F5 # 0 +0xA05C 0x71F6 # 0 +0xA05D 0x71F7 # 0 +0xA05E 0x71F8 # 0 +0xA05F 0x71FA # 0 +0xA060 0x71FB # 0 +0xA061 0x71FC # 0 +0xA062 0x71FD # 0 +0xA063 0x71FE # 0 +0xA064 0x71FF # 0 +0xA065 0x7200 # 0 +0xA066 0x7201 # 0 +0xA067 0x7202 # 0 +0xA068 0x7203 # 0 +0xA069 0x7204 # 0 +0xA06A 0x7205 # 0 +0xA06B 0x7207 # 0 +0xA06C 0x7208 # 0 +0xA06D 0x7209 # 0 +0xA06E 0x720A # 0 +0xA06F 0x720B # 0 +0xA070 0x720C # 0 +0xA071 0x720D # 0 +0xA072 0x720E # 0 +0xA073 0x720F # 0 +0xA074 0x7210 # 0 +0xA075 0x7211 # 0 +0xA076 0x7212 # 0 +0xA077 0x7213 # 0 +0xA078 0x7214 # 0 +0xA079 0x7215 # 0 +0xA07A 0x7216 # 0 +0xA07B 0x7217 # 0 +0xA07C 0x7218 # 0 +0xA07D 0x7219 # 0 +0xA07E 0x721A # 0 +0xA080 0x721B # 0 +0xA081 0x721C # 0 +0xA082 0x721E # 0 +0xA083 0x721F # 0 +0xA084 0x7220 # 0 +0xA085 0x7221 # 0 +0xA086 0x7222 # 0 +0xA087 0x7223 # 0 +0xA088 0x7224 # 0 +0xA089 0x7225 # 0 +0xA08A 0x7226 # 0 +0xA08B 0x7227 # 0 +0xA08C 0x7229 # 0 +0xA08D 0x722B # 0 +0xA08E 0x722D # 0 +0xA08F 0x722E # 0 +0xA090 0x722F # 0 +0xA091 0x7232 # 0 +0xA092 0x7233 # 0 +0xA093 0x7234 # 0 +0xA094 0x723A # 0 +0xA095 0x723C # 0 +0xA096 0x723E # 0 +0xA097 0x7240 # 0 +0xA098 0x7241 # 0 +0xA099 0x7242 # 0 +0xA09A 0x7243 # 0 +0xA09B 0x7244 # 0 +0xA09C 0x7245 # 0 +0xA09D 0x7246 # 0 +0xA09E 0x7249 # 0 +0xA09F 0x724A # 0 +0xA0A0 0x724B # 0 +0xA0A1 0x724E # 0 +0xA0A2 0x724F # 0 +0xA0A3 0x7250 # 0 +0xA0A4 0x7251 # 0 +0xA0A5 0x7253 # 0 +0xA0A6 0x7254 # 0 +0xA0A7 0x7255 # 0 +0xA0A8 0x7257 # 0 +0xA0A9 0x7258 # 0 +0xA0AA 0x725A # 0 +0xA0AB 0x725C # 0 +0xA0AC 0x725E # 0 +0xA0AD 0x7260 # 0 +0xA0AE 0x7263 # 0 +0xA0AF 0x7264 # 0 +0xA0B0 0x7265 # 0 +0xA0B1 0x7268 # 0 +0xA0B2 0x726A # 0 +0xA0B3 0x726B # 0 +0xA0B4 0x726C # 0 +0xA0B5 0x726D # 0 +0xA0B6 0x7270 # 0 +0xA0B7 0x7271 # 0 +0xA0B8 0x7273 # 0 +0xA0B9 0x7274 # 0 +0xA0BA 0x7276 # 0 +0xA0BB 0x7277 # 0 +0xA0BC 0x7278 # 0 +0xA0BD 0x727B # 0 +0xA0BE 0x727C # 0 +0xA0BF 0x727D # 0 +0xA0C0 0x7282 # 0 +0xA0C1 0x7283 # 0 +0xA0C2 0x7285 # 0 +0xA0C3 0x7286 # 0 +0xA0C4 0x7287 # 0 +0xA0C5 0x7288 # 0 +0xA0C6 0x7289 # 0 +0xA0C7 0x728C # 0 +0xA0C8 0x728E # 0 +0xA0C9 0x7290 # 0 +0xA0CA 0x7291 # 0 +0xA0CB 0x7293 # 0 +0xA0CC 0x7294 # 0 +0xA0CD 0x7295 # 0 +0xA0CE 0x7296 # 0 +0xA0CF 0x7297 # 0 +0xA0D0 0x7298 # 0 +0xA0D1 0x7299 # 0 +0xA0D2 0x729A # 0 +0xA0D3 0x729B # 0 +0xA0D4 0x729C # 0 +0xA0D5 0x729D # 0 +0xA0D6 0x729E # 0 +0xA0D7 0x72A0 # 0 +0xA0D8 0x72A1 # 0 +0xA0D9 0x72A2 # 0 +0xA0DA 0x72A3 # 0 +0xA0DB 0x72A4 # 0 +0xA0DC 0x72A5 # 0 +0xA0DD 0x72A6 # 0 +0xA0DE 0x72A7 # 0 +0xA0DF 0x72A8 # 0 +0xA0E0 0x72A9 # 0 +0xA0E1 0x72AA # 0 +0xA0E2 0x72AB # 0 +0xA0E3 0x72AE # 0 +0xA0E4 0x72B1 # 0 +0xA0E5 0x72B2 # 0 +0xA0E6 0x72B3 # 0 +0xA0E7 0x72B5 # 0 +0xA0E8 0x72BA # 0 +0xA0E9 0x72BB # 0 +0xA0EA 0x72BC # 0 +0xA0EB 0x72BD # 0 +0xA0EC 0x72BE # 0 +0xA0ED 0x72BF # 0 +0xA0EE 0x72C0 # 0 +0xA0EF 0x72C5 # 0 +0xA0F0 0x72C6 # 0 +0xA0F1 0x72C7 # 0 +0xA0F2 0x72C9 # 0 +0xA0F3 0x72CA # 0 +0xA0F4 0x72CB # 0 +0xA0F5 0x72CC # 0 +0xA0F6 0x72CF # 0 +0xA0F7 0x72D1 # 0 +0xA0F8 0x72D3 # 0 +0xA0F9 0x72D4 # 0 +0xA0FA 0x72D5 # 0 +0xA0FB 0x72D6 # 0 +0xA0FC 0x72D8 # 0 +0xA0FD 0x72DA # 0 +0xA0FE 0x72DB # 0 +0xA140 0xE4C6 # 0 +0xA141 0xE4C7 # 0 +0xA142 0xE4C8 # 0 +0xA143 0xE4C9 # 0 +0xA144 0xE4CA # 0 +0xA145 0xE4CB # 0 +0xA146 0xE4CC # 0 +0xA147 0xE4CD # 0 +0xA148 0xE4CE # 0 +0xA149 0xE4CF # 0 +0xA14A 0xE4D0 # 0 +0xA14B 0xE4D1 # 0 +0xA14C 0xE4D2 # 0 +0xA14D 0xE4D3 # 0 +0xA14E 0xE4D4 # 0 +0xA14F 0xE4D5 # 0 +0xA150 0xE4D6 # 0 +0xA151 0xE4D7 # 0 +0xA152 0xE4D8 # 0 +0xA153 0xE4D9 # 0 +0xA154 0xE4DA # 0 +0xA155 0xE4DB # 0 +0xA156 0xE4DC # 0 +0xA157 0xE4DD # 0 +0xA158 0xE4DE # 0 +0xA159 0xE4DF # 0 +0xA15A 0xE4E0 # 0 +0xA15B 0xE4E1 # 0 +0xA15C 0xE4E2 # 0 +0xA15D 0xE4E3 # 0 +0xA15E 0xE4E4 # 0 +0xA15F 0xE4E5 # 0 +0xA160 0xE4E6 # 0 +0xA161 0xE4E7 # 0 +0xA162 0xE4E8 # 0 +0xA163 0xE4E9 # 0 +0xA164 0xE4EA # 0 +0xA165 0xE4EB # 0 +0xA166 0xE4EC # 0 +0xA167 0xE4ED # 0 +0xA168 0xE4EE # 0 +0xA169 0xE4EF # 0 +0xA16A 0xE4F0 # 0 +0xA16B 0xE4F1 # 0 +0xA16C 0xE4F2 # 0 +0xA16D 0xE4F3 # 0 +0xA16E 0xE4F4 # 0 +0xA16F 0xE4F5 # 0 +0xA170 0xE4F6 # 0 +0xA171 0xE4F7 # 0 +0xA172 0xE4F8 # 0 +0xA173 0xE4F9 # 0 +0xA174 0xE4FA # 0 +0xA175 0xE4FB # 0 +0xA176 0xE4FC # 0 +0xA177 0xE4FD # 0 +0xA178 0xE4FE # 0 +0xA179 0xE4FF # 0 +0xA17A 0xE500 # 0 +0xA17B 0xE501 # 0 +0xA17C 0xE502 # 0 +0xA17D 0xE503 # 0 +0xA17E 0xE504 # 0 +0xA180 0xE505 # 0 +0xA181 0xE506 # 0 +0xA182 0xE507 # 0 +0xA183 0xE508 # 0 +0xA184 0xE509 # 0 +0xA185 0xE50A # 0 +0xA186 0xE50B # 0 +0xA187 0xE50C # 0 +0xA188 0xE50D # 0 +0xA189 0xE50E # 0 +0xA18A 0xE50F # 0 +0xA18B 0xE510 # 0 +0xA18C 0xE511 # 0 +0xA18D 0xE512 # 0 +0xA18E 0xE513 # 0 +0xA18F 0xE514 # 0 +0xA190 0xE515 # 0 +0xA191 0xE516 # 0 +0xA192 0xE517 # 0 +0xA193 0xE518 # 0 +0xA194 0xE519 # 0 +0xA195 0xE51A # 0 +0xA196 0xE51B # 0 +0xA197 0xE51C # 0 +0xA198 0xE51D # 0 +0xA199 0xE51E # 0 +0xA19A 0xE51F # 0 +0xA19B 0xE520 # 0 +0xA19C 0xE521 # 0 +0xA19D 0xE522 # 0 +0xA19E 0xE523 # 0 +0xA19F 0xE524 # 0 +0xA1A0 0xE525 # 0 +0xA1A1 0x3000 # 0 +0xA1A2 0x3001 # 0 +0xA1A3 0x3002 # 0 +0xA1A4 0x00B7 # 0 +0xA1A5 0x02C9 # 0 +0xA1A6 0x02C7 # 0 +0xA1A7 0x00A8 # 0 +0xA1A8 0x3003 # 0 +0xA1A9 0x3005 # 0 +0xA1AA 0x2014 # 0 +0xA1AB 0xFF5E # 0 +0xA1AC 0x2016 # 0 +0xA1AD 0x2026 # 0 +0xA1AE 0x2018 # 0 +0xA1AF 0x2019 # 0 +0xA1B0 0x201C # 0 +0xA1B1 0x201D # 0 +0xA1B2 0x3014 # 0 +0xA1B3 0x3015 # 0 +0xA1B4 0x3008 # 0 +0xA1B5 0x3009 # 0 +0xA1B6 0x300A # 0 +0xA1B7 0x300B # 0 +0xA1B8 0x300C # 0 +0xA1B9 0x300D # 0 +0xA1BA 0x300E # 0 +0xA1BB 0x300F # 0 +0xA1BC 0x3016 # 0 +0xA1BD 0x3017 # 0 +0xA1BE 0x3010 # 0 +0xA1BF 0x3011 # 0 +0xA1C0 0x00B1 # 0 +0xA1C1 0x00D7 # 0 +0xA1C2 0x00F7 # 0 +0xA1C3 0x2236 # 0 +0xA1C4 0x2227 # 0 +0xA1C5 0x2228 # 0 +0xA1C6 0x2211 # 0 +0xA1C7 0x220F # 0 +0xA1C8 0x222A # 0 +0xA1C9 0x2229 # 0 +0xA1CA 0x2208 # 0 +0xA1CB 0x2237 # 0 +0xA1CC 0x221A # 0 +0xA1CD 0x22A5 # 0 +0xA1CE 0x2225 # 0 +0xA1CF 0x2220 # 0 +0xA1D0 0x2312 # 0 +0xA1D1 0x2299 # 0 +0xA1D2 0x222B # 0 +0xA1D3 0x222E # 0 +0xA1D4 0x2261 # 0 +0xA1D5 0x224C # 0 +0xA1D6 0x2248 # 0 +0xA1D7 0x223D # 0 +0xA1D8 0x221D # 0 +0xA1D9 0x2260 # 0 +0xA1DA 0x226E # 0 +0xA1DB 0x226F # 0 +0xA1DC 0x2264 # 0 +0xA1DD 0x2265 # 0 +0xA1DE 0x221E # 0 +0xA1DF 0x2235 # 0 +0xA1E0 0x2234 # 0 +0xA1E1 0x2642 # 0 +0xA1E2 0x2640 # 0 +0xA1E3 0x00B0 # 0 +0xA1E4 0x2032 # 0 +0xA1E5 0x2033 # 0 +0xA1E6 0x2103 # 0 +0xA1E7 0xFF04 # 0 +0xA1E8 0x00A4 # 0 +0xA1E9 0xFFE0 # 0 +0xA1EA 0xFFE1 # 0 +0xA1EB 0x2030 # 0 +0xA1EC 0x00A7 # 0 +0xA1ED 0x2116 # 0 +0xA1EE 0x2606 # 0 +0xA1EF 0x2605 # 0 +0xA1F0 0x25CB # 0 +0xA1F1 0x25CF # 0 +0xA1F2 0x25CE # 0 +0xA1F3 0x25C7 # 0 +0xA1F4 0x25C6 # 0 +0xA1F5 0x25A1 # 0 +0xA1F6 0x25A0 # 0 +0xA1F7 0x25B3 # 0 +0xA1F8 0x25B2 # 0 +0xA1F9 0x203B # 0 +0xA1FA 0x2192 # 0 +0xA1FB 0x2190 # 0 +0xA1FC 0x2191 # 0 +0xA1FD 0x2193 # 0 +0xA1FE 0x3013 # 0 +0xA240 0xE526 # 0 +0xA241 0xE527 # 0 +0xA242 0xE528 # 0 +0xA243 0xE529 # 0 +0xA244 0xE52A # 0 +0xA245 0xE52B # 0 +0xA246 0xE52C # 0 +0xA247 0xE52D # 0 +0xA248 0xE52E # 0 +0xA249 0xE52F # 0 +0xA24A 0xE530 # 0 +0xA24B 0xE531 # 0 +0xA24C 0xE532 # 0 +0xA24D 0xE533 # 0 +0xA24E 0xE534 # 0 +0xA24F 0xE535 # 0 +0xA250 0xE536 # 0 +0xA251 0xE537 # 0 +0xA252 0xE538 # 0 +0xA253 0xE539 # 0 +0xA254 0xE53A # 0 +0xA255 0xE53B # 0 +0xA256 0xE53C # 0 +0xA257 0xE53D # 0 +0xA258 0xE53E # 0 +0xA259 0xE53F # 0 +0xA25A 0xE540 # 0 +0xA25B 0xE541 # 0 +0xA25C 0xE542 # 0 +0xA25D 0xE543 # 0 +0xA25E 0xE544 # 0 +0xA25F 0xE545 # 0 +0xA260 0xE546 # 0 +0xA261 0xE547 # 0 +0xA262 0xE548 # 0 +0xA263 0xE549 # 0 +0xA264 0xE54A # 0 +0xA265 0xE54B # 0 +0xA266 0xE54C # 0 +0xA267 0xE54D # 0 +0xA268 0xE54E # 0 +0xA269 0xE54F # 0 +0xA26A 0xE550 # 0 +0xA26B 0xE551 # 0 +0xA26C 0xE552 # 0 +0xA26D 0xE553 # 0 +0xA26E 0xE554 # 0 +0xA26F 0xE555 # 0 +0xA270 0xE556 # 0 +0xA271 0xE557 # 0 +0xA272 0xE558 # 0 +0xA273 0xE559 # 0 +0xA274 0xE55A # 0 +0xA275 0xE55B # 0 +0xA276 0xE55C # 0 +0xA277 0xE55D # 0 +0xA278 0xE55E # 0 +0xA279 0xE55F # 0 +0xA27A 0xE560 # 0 +0xA27B 0xE561 # 0 +0xA27C 0xE562 # 0 +0xA27D 0xE563 # 0 +0xA27E 0xE564 # 0 +0xA280 0xE565 # 0 +0xA281 0xE566 # 0 +0xA282 0xE567 # 0 +0xA283 0xE568 # 0 +0xA284 0xE569 # 0 +0xA285 0xE56A # 0 +0xA286 0xE56B # 0 +0xA287 0xE56C # 0 +0xA288 0xE56D # 0 +0xA289 0xE56E # 0 +0xA28A 0xE56F # 0 +0xA28B 0xE570 # 0 +0xA28C 0xE571 # 0 +0xA28D 0xE572 # 0 +0xA28E 0xE573 # 0 +0xA28F 0xE574 # 0 +0xA290 0xE575 # 0 +0xA291 0xE576 # 0 +0xA292 0xE577 # 0 +0xA293 0xE578 # 0 +0xA294 0xE579 # 0 +0xA295 0xE57A # 0 +0xA296 0xE57B # 0 +0xA297 0xE57C # 0 +0xA298 0xE57D # 0 +0xA299 0xE57E # 0 +0xA29A 0xE57F # 0 +0xA29B 0xE580 # 0 +0xA29C 0xE581 # 0 +0xA29D 0xE582 # 0 +0xA29E 0xE583 # 0 +0xA29F 0xE584 # 0 +0xA2A0 0xE585 # 0 +0xA2A1 0x2170 # 0 +0xA2A2 0x2171 # 0 +0xA2A3 0x2172 # 0 +0xA2A4 0x2173 # 0 +0xA2A5 0x2174 # 0 +0xA2A6 0x2175 # 0 +0xA2A7 0x2176 # 0 +0xA2A8 0x2177 # 0 +0xA2A9 0x2178 # 0 +0xA2AA 0x2179 # 0 +0xA2AB 0xE766 # 0 +0xA2AC 0xE767 # 0 +0xA2AD 0xE768 # 0 +0xA2AE 0xE769 # 0 +0xA2AF 0xE76A # 0 +0xA2B0 0xE76B # 0 +0xA2B1 0x2488 # 0 +0xA2B2 0x2489 # 0 +0xA2B3 0x248A # 0 +0xA2B4 0x248B # 0 +0xA2B5 0x248C # 0 +0xA2B6 0x248D # 0 +0xA2B7 0x248E # 0 +0xA2B8 0x248F # 0 +0xA2B9 0x2490 # 0 +0xA2BA 0x2491 # 0 +0xA2BB 0x2492 # 0 +0xA2BC 0x2493 # 0 +0xA2BD 0x2494 # 0 +0xA2BE 0x2495 # 0 +0xA2BF 0x2496 # 0 +0xA2C0 0x2497 # 0 +0xA2C1 0x2498 # 0 +0xA2C2 0x2499 # 0 +0xA2C3 0x249A # 0 +0xA2C4 0x249B # 0 +0xA2C5 0x2474 # 0 +0xA2C6 0x2475 # 0 +0xA2C7 0x2476 # 0 +0xA2C8 0x2477 # 0 +0xA2C9 0x2478 # 0 +0xA2CA 0x2479 # 0 +0xA2CB 0x247A # 0 +0xA2CC 0x247B # 0 +0xA2CD 0x247C # 0 +0xA2CE 0x247D # 0 +0xA2CF 0x247E # 0 +0xA2D0 0x247F # 0 +0xA2D1 0x2480 # 0 +0xA2D2 0x2481 # 0 +0xA2D3 0x2482 # 0 +0xA2D4 0x2483 # 0 +0xA2D5 0x2484 # 0 +0xA2D6 0x2485 # 0 +0xA2D7 0x2486 # 0 +0xA2D8 0x2487 # 0 +0xA2D9 0x2460 # 0 +0xA2DA 0x2461 # 0 +0xA2DB 0x2462 # 0 +0xA2DC 0x2463 # 0 +0xA2DD 0x2464 # 0 +0xA2DE 0x2465 # 0 +0xA2DF 0x2466 # 0 +0xA2E0 0x2467 # 0 +0xA2E1 0x2468 # 0 +0xA2E2 0x2469 # 0 +0xA2E3 0xE76C # 0 +0xA2E4 0xE76D # 0 +0xA2E5 0x3220 # 0 +0xA2E6 0x3221 # 0 +0xA2E7 0x3222 # 0 +0xA2E8 0x3223 # 0 +0xA2E9 0x3224 # 0 +0xA2EA 0x3225 # 0 +0xA2EB 0x3226 # 0 +0xA2EC 0x3227 # 0 +0xA2ED 0x3228 # 0 +0xA2EE 0x3229 # 0 +0xA2EF 0xE76E # 0 +0xA2F0 0xE76F # 0 +0xA2F1 0x2160 # 0 +0xA2F2 0x2161 # 0 +0xA2F3 0x2162 # 0 +0xA2F4 0x2163 # 0 +0xA2F5 0x2164 # 0 +0xA2F6 0x2165 # 0 +0xA2F7 0x2166 # 0 +0xA2F8 0x2167 # 0 +0xA2F9 0x2168 # 0 +0xA2FA 0x2169 # 0 +0xA2FB 0x216A # 0 +0xA2FC 0x216B # 0 +0xA2FD 0xE770 # 0 +0xA2FE 0xE771 # 0 +0xA340 0xE586 # 0 +0xA341 0xE587 # 0 +0xA342 0xE588 # 0 +0xA343 0xE589 # 0 +0xA344 0xE58A # 0 +0xA345 0xE58B # 0 +0xA346 0xE58C # 0 +0xA347 0xE58D # 0 +0xA348 0xE58E # 0 +0xA349 0xE58F # 0 +0xA34A 0xE590 # 0 +0xA34B 0xE591 # 0 +0xA34C 0xE592 # 0 +0xA34D 0xE593 # 0 +0xA34E 0xE594 # 0 +0xA34F 0xE595 # 0 +0xA350 0xE596 # 0 +0xA351 0xE597 # 0 +0xA352 0xE598 # 0 +0xA353 0xE599 # 0 +0xA354 0xE59A # 0 +0xA355 0xE59B # 0 +0xA356 0xE59C # 0 +0xA357 0xE59D # 0 +0xA358 0xE59E # 0 +0xA359 0xE59F # 0 +0xA35A 0xE5A0 # 0 +0xA35B 0xE5A1 # 0 +0xA35C 0xE5A2 # 0 +0xA35D 0xE5A3 # 0 +0xA35E 0xE5A4 # 0 +0xA35F 0xE5A5 # 0 +0xA360 0xE5A6 # 0 +0xA361 0xE5A7 # 0 +0xA362 0xE5A8 # 0 +0xA363 0xE5A9 # 0 +0xA364 0xE5AA # 0 +0xA365 0xE5AB # 0 +0xA366 0xE5AC # 0 +0xA367 0xE5AD # 0 +0xA368 0xE5AE # 0 +0xA369 0xE5AF # 0 +0xA36A 0xE5B0 # 0 +0xA36B 0xE5B1 # 0 +0xA36C 0xE5B2 # 0 +0xA36D 0xE5B3 # 0 +0xA36E 0xE5B4 # 0 +0xA36F 0xE5B5 # 0 +0xA370 0xE5B6 # 0 +0xA371 0xE5B7 # 0 +0xA372 0xE5B8 # 0 +0xA373 0xE5B9 # 0 +0xA374 0xE5BA # 0 +0xA375 0xE5BB # 0 +0xA376 0xE5BC # 0 +0xA377 0xE5BD # 0 +0xA378 0xE5BE # 0 +0xA379 0xE5BF # 0 +0xA37A 0xE5C0 # 0 +0xA37B 0xE5C1 # 0 +0xA37C 0xE5C2 # 0 +0xA37D 0xE5C3 # 0 +0xA37E 0xE5C4 # 0 +0xA380 0xE5C5 # 0 +0xA381 0xE5C6 # 0 +0xA382 0xE5C7 # 0 +0xA383 0xE5C8 # 0 +0xA384 0xE5C9 # 0 +0xA385 0xE5CA # 0 +0xA386 0xE5CB # 0 +0xA387 0xE5CC # 0 +0xA388 0xE5CD # 0 +0xA389 0xE5CE # 0 +0xA38A 0xE5CF # 0 +0xA38B 0xE5D0 # 0 +0xA38C 0xE5D1 # 0 +0xA38D 0xE5D2 # 0 +0xA38E 0xE5D3 # 0 +0xA38F 0xE5D4 # 0 +0xA390 0xE5D5 # 0 +0xA391 0xE5D6 # 0 +0xA392 0xE5D7 # 0 +0xA393 0xE5D8 # 0 +0xA394 0xE5D9 # 0 +0xA395 0xE5DA # 0 +0xA396 0xE5DB # 0 +0xA397 0xE5DC # 0 +0xA398 0xE5DD # 0 +0xA399 0xE5DE # 0 +0xA39A 0xE5DF # 0 +0xA39B 0xE5E0 # 0 +0xA39C 0xE5E1 # 0 +0xA39D 0xE5E2 # 0 +0xA39E 0xE5E3 # 0 +0xA39F 0xE5E4 # 0 +0xA3A0 0xE5E5 # 0 +0xA3A1 0xFF01 # 0 +0xA3A2 0xFF02 # 0 +0xA3A3 0xFF03 # 0 +0xA3A4 0xFFE5 # 0 +0xA3A5 0xFF05 # 0 +0xA3A6 0xFF06 # 0 +0xA3A7 0xFF07 # 0 +0xA3A8 0xFF08 # 0 +0xA3A9 0xFF09 # 0 +0xA3AA 0xFF0A # 0 +0xA3AB 0xFF0B # 0 +0xA3AC 0xFF0C # 0 +0xA3AD 0xFF0D # 0 +0xA3AE 0xFF0E # 0 +0xA3AF 0xFF0F # 0 +0xA3B0 0xFF10 # 0 +0xA3B1 0xFF11 # 0 +0xA3B2 0xFF12 # 0 +0xA3B3 0xFF13 # 0 +0xA3B4 0xFF14 # 0 +0xA3B5 0xFF15 # 0 +0xA3B6 0xFF16 # 0 +0xA3B7 0xFF17 # 0 +0xA3B8 0xFF18 # 0 +0xA3B9 0xFF19 # 0 +0xA3BA 0xFF1A # 0 +0xA3BB 0xFF1B # 0 +0xA3BC 0xFF1C # 0 +0xA3BD 0xFF1D # 0 +0xA3BE 0xFF1E # 0 +0xA3BF 0xFF1F # 0 +0xA3C0 0xFF20 # 0 +0xA3C1 0xFF21 # 0 +0xA3C2 0xFF22 # 0 +0xA3C3 0xFF23 # 0 +0xA3C4 0xFF24 # 0 +0xA3C5 0xFF25 # 0 +0xA3C6 0xFF26 # 0 +0xA3C7 0xFF27 # 0 +0xA3C8 0xFF28 # 0 +0xA3C9 0xFF29 # 0 +0xA3CA 0xFF2A # 0 +0xA3CB 0xFF2B # 0 +0xA3CC 0xFF2C # 0 +0xA3CD 0xFF2D # 0 +0xA3CE 0xFF2E # 0 +0xA3CF 0xFF2F # 0 +0xA3D0 0xFF30 # 0 +0xA3D1 0xFF31 # 0 +0xA3D2 0xFF32 # 0 +0xA3D3 0xFF33 # 0 +0xA3D4 0xFF34 # 0 +0xA3D5 0xFF35 # 0 +0xA3D6 0xFF36 # 0 +0xA3D7 0xFF37 # 0 +0xA3D8 0xFF38 # 0 +0xA3D9 0xFF39 # 0 +0xA3DA 0xFF3A # 0 +0xA3DB 0xFF3B # 0 +0xA3DC 0xFF3C # 0 +0xA3DD 0xFF3D # 0 +0xA3DE 0xFF3E # 0 +0xA3DF 0xFF3F # 0 +0xA3E0 0xFF40 # 0 +0xA3E1 0xFF41 # 0 +0xA3E2 0xFF42 # 0 +0xA3E3 0xFF43 # 0 +0xA3E4 0xFF44 # 0 +0xA3E5 0xFF45 # 0 +0xA3E6 0xFF46 # 0 +0xA3E7 0xFF47 # 0 +0xA3E8 0xFF48 # 0 +0xA3E9 0xFF49 # 0 +0xA3EA 0xFF4A # 0 +0xA3EB 0xFF4B # 0 +0xA3EC 0xFF4C # 0 +0xA3ED 0xFF4D # 0 +0xA3EE 0xFF4E # 0 +0xA3EF 0xFF4F # 0 +0xA3F0 0xFF50 # 0 +0xA3F1 0xFF51 # 0 +0xA3F2 0xFF52 # 0 +0xA3F3 0xFF53 # 0 +0xA3F4 0xFF54 # 0 +0xA3F5 0xFF55 # 0 +0xA3F6 0xFF56 # 0 +0xA3F7 0xFF57 # 0 +0xA3F8 0xFF58 # 0 +0xA3F9 0xFF59 # 0 +0xA3FA 0xFF5A # 0 +0xA3FB 0xFF5B # 0 +0xA3FC 0xFF5C # 0 +0xA3FD 0xFF5D # 0 +0xA3FE 0xFFE3 # 0 +0xA440 0xE5E6 # 0 +0xA441 0xE5E7 # 0 +0xA442 0xE5E8 # 0 +0xA443 0xE5E9 # 0 +0xA444 0xE5EA # 0 +0xA445 0xE5EB # 0 +0xA446 0xE5EC # 0 +0xA447 0xE5ED # 0 +0xA448 0xE5EE # 0 +0xA449 0xE5EF # 0 +0xA44A 0xE5F0 # 0 +0xA44B 0xE5F1 # 0 +0xA44C 0xE5F2 # 0 +0xA44D 0xE5F3 # 0 +0xA44E 0xE5F4 # 0 +0xA44F 0xE5F5 # 0 +0xA450 0xE5F6 # 0 +0xA451 0xE5F7 # 0 +0xA452 0xE5F8 # 0 +0xA453 0xE5F9 # 0 +0xA454 0xE5FA # 0 +0xA455 0xE5FB # 0 +0xA456 0xE5FC # 0 +0xA457 0xE5FD # 0 +0xA458 0xE5FE # 0 +0xA459 0xE5FF # 0 +0xA45A 0xE600 # 0 +0xA45B 0xE601 # 0 +0xA45C 0xE602 # 0 +0xA45D 0xE603 # 0 +0xA45E 0xE604 # 0 +0xA45F 0xE605 # 0 +0xA460 0xE606 # 0 +0xA461 0xE607 # 0 +0xA462 0xE608 # 0 +0xA463 0xE609 # 0 +0xA464 0xE60A # 0 +0xA465 0xE60B # 0 +0xA466 0xE60C # 0 +0xA467 0xE60D # 0 +0xA468 0xE60E # 0 +0xA469 0xE60F # 0 +0xA46A 0xE610 # 0 +0xA46B 0xE611 # 0 +0xA46C 0xE612 # 0 +0xA46D 0xE613 # 0 +0xA46E 0xE614 # 0 +0xA46F 0xE615 # 0 +0xA470 0xE616 # 0 +0xA471 0xE617 # 0 +0xA472 0xE618 # 0 +0xA473 0xE619 # 0 +0xA474 0xE61A # 0 +0xA475 0xE61B # 0 +0xA476 0xE61C # 0 +0xA477 0xE61D # 0 +0xA478 0xE61E # 0 +0xA479 0xE61F # 0 +0xA47A 0xE620 # 0 +0xA47B 0xE621 # 0 +0xA47C 0xE622 # 0 +0xA47D 0xE623 # 0 +0xA47E 0xE624 # 0 +0xA480 0xE625 # 0 +0xA481 0xE626 # 0 +0xA482 0xE627 # 0 +0xA483 0xE628 # 0 +0xA484 0xE629 # 0 +0xA485 0xE62A # 0 +0xA486 0xE62B # 0 +0xA487 0xE62C # 0 +0xA488 0xE62D # 0 +0xA489 0xE62E # 0 +0xA48A 0xE62F # 0 +0xA48B 0xE630 # 0 +0xA48C 0xE631 # 0 +0xA48D 0xE632 # 0 +0xA48E 0xE633 # 0 +0xA48F 0xE634 # 0 +0xA490 0xE635 # 0 +0xA491 0xE636 # 0 +0xA492 0xE637 # 0 +0xA493 0xE638 # 0 +0xA494 0xE639 # 0 +0xA495 0xE63A # 0 +0xA496 0xE63B # 0 +0xA497 0xE63C # 0 +0xA498 0xE63D # 0 +0xA499 0xE63E # 0 +0xA49A 0xE63F # 0 +0xA49B 0xE640 # 0 +0xA49C 0xE641 # 0 +0xA49D 0xE642 # 0 +0xA49E 0xE643 # 0 +0xA49F 0xE644 # 0 +0xA4A0 0xE645 # 0 +0xA4A1 0x3041 # 0 +0xA4A2 0x3042 # 0 +0xA4A3 0x3043 # 0 +0xA4A4 0x3044 # 0 +0xA4A5 0x3045 # 0 +0xA4A6 0x3046 # 0 +0xA4A7 0x3047 # 0 +0xA4A8 0x3048 # 0 +0xA4A9 0x3049 # 0 +0xA4AA 0x304A # 0 +0xA4AB 0x304B # 0 +0xA4AC 0x304C # 0 +0xA4AD 0x304D # 0 +0xA4AE 0x304E # 0 +0xA4AF 0x304F # 0 +0xA4B0 0x3050 # 0 +0xA4B1 0x3051 # 0 +0xA4B2 0x3052 # 0 +0xA4B3 0x3053 # 0 +0xA4B4 0x3054 # 0 +0xA4B5 0x3055 # 0 +0xA4B6 0x3056 # 0 +0xA4B7 0x3057 # 0 +0xA4B8 0x3058 # 0 +0xA4B9 0x3059 # 0 +0xA4BA 0x305A # 0 +0xA4BB 0x305B # 0 +0xA4BC 0x305C # 0 +0xA4BD 0x305D # 0 +0xA4BE 0x305E # 0 +0xA4BF 0x305F # 0 +0xA4C0 0x3060 # 0 +0xA4C1 0x3061 # 0 +0xA4C2 0x3062 # 0 +0xA4C3 0x3063 # 0 +0xA4C4 0x3064 # 0 +0xA4C5 0x3065 # 0 +0xA4C6 0x3066 # 0 +0xA4C7 0x3067 # 0 +0xA4C8 0x3068 # 0 +0xA4C9 0x3069 # 0 +0xA4CA 0x306A # 0 +0xA4CB 0x306B # 0 +0xA4CC 0x306C # 0 +0xA4CD 0x306D # 0 +0xA4CE 0x306E # 0 +0xA4CF 0x306F # 0 +0xA4D0 0x3070 # 0 +0xA4D1 0x3071 # 0 +0xA4D2 0x3072 # 0 +0xA4D3 0x3073 # 0 +0xA4D4 0x3074 # 0 +0xA4D5 0x3075 # 0 +0xA4D6 0x3076 # 0 +0xA4D7 0x3077 # 0 +0xA4D8 0x3078 # 0 +0xA4D9 0x3079 # 0 +0xA4DA 0x307A # 0 +0xA4DB 0x307B # 0 +0xA4DC 0x307C # 0 +0xA4DD 0x307D # 0 +0xA4DE 0x307E # 0 +0xA4DF 0x307F # 0 +0xA4E0 0x3080 # 0 +0xA4E1 0x3081 # 0 +0xA4E2 0x3082 # 0 +0xA4E3 0x3083 # 0 +0xA4E4 0x3084 # 0 +0xA4E5 0x3085 # 0 +0xA4E6 0x3086 # 0 +0xA4E7 0x3087 # 0 +0xA4E8 0x3088 # 0 +0xA4E9 0x3089 # 0 +0xA4EA 0x308A # 0 +0xA4EB 0x308B # 0 +0xA4EC 0x308C # 0 +0xA4ED 0x308D # 0 +0xA4EE 0x308E # 0 +0xA4EF 0x308F # 0 +0xA4F0 0x3090 # 0 +0xA4F1 0x3091 # 0 +0xA4F2 0x3092 # 0 +0xA4F3 0x3093 # 0 +0xA4F4 0xE772 # 0 +0xA4F5 0xE773 # 0 +0xA4F6 0xE774 # 0 +0xA4F7 0xE775 # 0 +0xA4F8 0xE776 # 0 +0xA4F9 0xE777 # 0 +0xA4FA 0xE778 # 0 +0xA4FB 0xE779 # 0 +0xA4FC 0xE77A # 0 +0xA4FD 0xE77B # 0 +0xA4FE 0xE77C # 0 +0xA540 0xE646 # 0 +0xA541 0xE647 # 0 +0xA542 0xE648 # 0 +0xA543 0xE649 # 0 +0xA544 0xE64A # 0 +0xA545 0xE64B # 0 +0xA546 0xE64C # 0 +0xA547 0xE64D # 0 +0xA548 0xE64E # 0 +0xA549 0xE64F # 0 +0xA54A 0xE650 # 0 +0xA54B 0xE651 # 0 +0xA54C 0xE652 # 0 +0xA54D 0xE653 # 0 +0xA54E 0xE654 # 0 +0xA54F 0xE655 # 0 +0xA550 0xE656 # 0 +0xA551 0xE657 # 0 +0xA552 0xE658 # 0 +0xA553 0xE659 # 0 +0xA554 0xE65A # 0 +0xA555 0xE65B # 0 +0xA556 0xE65C # 0 +0xA557 0xE65D # 0 +0xA558 0xE65E # 0 +0xA559 0xE65F # 0 +0xA55A 0xE660 # 0 +0xA55B 0xE661 # 0 +0xA55C 0xE662 # 0 +0xA55D 0xE663 # 0 +0xA55E 0xE664 # 0 +0xA55F 0xE665 # 0 +0xA560 0xE666 # 0 +0xA561 0xE667 # 0 +0xA562 0xE668 # 0 +0xA563 0xE669 # 0 +0xA564 0xE66A # 0 +0xA565 0xE66B # 0 +0xA566 0xE66C # 0 +0xA567 0xE66D # 0 +0xA568 0xE66E # 0 +0xA569 0xE66F # 0 +0xA56A 0xE670 # 0 +0xA56B 0xE671 # 0 +0xA56C 0xE672 # 0 +0xA56D 0xE673 # 0 +0xA56E 0xE674 # 0 +0xA56F 0xE675 # 0 +0xA570 0xE676 # 0 +0xA571 0xE677 # 0 +0xA572 0xE678 # 0 +0xA573 0xE679 # 0 +0xA574 0xE67A # 0 +0xA575 0xE67B # 0 +0xA576 0xE67C # 0 +0xA577 0xE67D # 0 +0xA578 0xE67E # 0 +0xA579 0xE67F # 0 +0xA57A 0xE680 # 0 +0xA57B 0xE681 # 0 +0xA57C 0xE682 # 0 +0xA57D 0xE683 # 0 +0xA57E 0xE684 # 0 +0xA580 0xE685 # 0 +0xA581 0xE686 # 0 +0xA582 0xE687 # 0 +0xA583 0xE688 # 0 +0xA584 0xE689 # 0 +0xA585 0xE68A # 0 +0xA586 0xE68B # 0 +0xA587 0xE68C # 0 +0xA588 0xE68D # 0 +0xA589 0xE68E # 0 +0xA58A 0xE68F # 0 +0xA58B 0xE690 # 0 +0xA58C 0xE691 # 0 +0xA58D 0xE692 # 0 +0xA58E 0xE693 # 0 +0xA58F 0xE694 # 0 +0xA590 0xE695 # 0 +0xA591 0xE696 # 0 +0xA592 0xE697 # 0 +0xA593 0xE698 # 0 +0xA594 0xE699 # 0 +0xA595 0xE69A # 0 +0xA596 0xE69B # 0 +0xA597 0xE69C # 0 +0xA598 0xE69D # 0 +0xA599 0xE69E # 0 +0xA59A 0xE69F # 0 +0xA59B 0xE6A0 # 0 +0xA59C 0xE6A1 # 0 +0xA59D 0xE6A2 # 0 +0xA59E 0xE6A3 # 0 +0xA59F 0xE6A4 # 0 +0xA5A0 0xE6A5 # 0 +0xA5A1 0x30A1 # 0 +0xA5A2 0x30A2 # 0 +0xA5A3 0x30A3 # 0 +0xA5A4 0x30A4 # 0 +0xA5A5 0x30A5 # 0 +0xA5A6 0x30A6 # 0 +0xA5A7 0x30A7 # 0 +0xA5A8 0x30A8 # 0 +0xA5A9 0x30A9 # 0 +0xA5AA 0x30AA # 0 +0xA5AB 0x30AB # 0 +0xA5AC 0x30AC # 0 +0xA5AD 0x30AD # 0 +0xA5AE 0x30AE # 0 +0xA5AF 0x30AF # 0 +0xA5B0 0x30B0 # 0 +0xA5B1 0x30B1 # 0 +0xA5B2 0x30B2 # 0 +0xA5B3 0x30B3 # 0 +0xA5B4 0x30B4 # 0 +0xA5B5 0x30B5 # 0 +0xA5B6 0x30B6 # 0 +0xA5B7 0x30B7 # 0 +0xA5B8 0x30B8 # 0 +0xA5B9 0x30B9 # 0 +0xA5BA 0x30BA # 0 +0xA5BB 0x30BB # 0 +0xA5BC 0x30BC # 0 +0xA5BD 0x30BD # 0 +0xA5BE 0x30BE # 0 +0xA5BF 0x30BF # 0 +0xA5C0 0x30C0 # 0 +0xA5C1 0x30C1 # 0 +0xA5C2 0x30C2 # 0 +0xA5C3 0x30C3 # 0 +0xA5C4 0x30C4 # 0 +0xA5C5 0x30C5 # 0 +0xA5C6 0x30C6 # 0 +0xA5C7 0x30C7 # 0 +0xA5C8 0x30C8 # 0 +0xA5C9 0x30C9 # 0 +0xA5CA 0x30CA # 0 +0xA5CB 0x30CB # 0 +0xA5CC 0x30CC # 0 +0xA5CD 0x30CD # 0 +0xA5CE 0x30CE # 0 +0xA5CF 0x30CF # 0 +0xA5D0 0x30D0 # 0 +0xA5D1 0x30D1 # 0 +0xA5D2 0x30D2 # 0 +0xA5D3 0x30D3 # 0 +0xA5D4 0x30D4 # 0 +0xA5D5 0x30D5 # 0 +0xA5D6 0x30D6 # 0 +0xA5D7 0x30D7 # 0 +0xA5D8 0x30D8 # 0 +0xA5D9 0x30D9 # 0 +0xA5DA 0x30DA # 0 +0xA5DB 0x30DB # 0 +0xA5DC 0x30DC # 0 +0xA5DD 0x30DD # 0 +0xA5DE 0x30DE # 0 +0xA5DF 0x30DF # 0 +0xA5E0 0x30E0 # 0 +0xA5E1 0x30E1 # 0 +0xA5E2 0x30E2 # 0 +0xA5E3 0x30E3 # 0 +0xA5E4 0x30E4 # 0 +0xA5E5 0x30E5 # 0 +0xA5E6 0x30E6 # 0 +0xA5E7 0x30E7 # 0 +0xA5E8 0x30E8 # 0 +0xA5E9 0x30E9 # 0 +0xA5EA 0x30EA # 0 +0xA5EB 0x30EB # 0 +0xA5EC 0x30EC # 0 +0xA5ED 0x30ED # 0 +0xA5EE 0x30EE # 0 +0xA5EF 0x30EF # 0 +0xA5F0 0x30F0 # 0 +0xA5F1 0x30F1 # 0 +0xA5F2 0x30F2 # 0 +0xA5F3 0x30F3 # 0 +0xA5F4 0x30F4 # 0 +0xA5F5 0x30F5 # 0 +0xA5F6 0x30F6 # 0 +0xA5F7 0xE77D # 0 +0xA5F8 0xE77E # 0 +0xA5F9 0xE77F # 0 +0xA5FA 0xE780 # 0 +0xA5FB 0xE781 # 0 +0xA5FC 0xE782 # 0 +0xA5FD 0xE783 # 0 +0xA5FE 0xE784 # 0 +0xA640 0xE6A6 # 0 +0xA641 0xE6A7 # 0 +0xA642 0xE6A8 # 0 +0xA643 0xE6A9 # 0 +0xA644 0xE6AA # 0 +0xA645 0xE6AB # 0 +0xA646 0xE6AC # 0 +0xA647 0xE6AD # 0 +0xA648 0xE6AE # 0 +0xA649 0xE6AF # 0 +0xA64A 0xE6B0 # 0 +0xA64B 0xE6B1 # 0 +0xA64C 0xE6B2 # 0 +0xA64D 0xE6B3 # 0 +0xA64E 0xE6B4 # 0 +0xA64F 0xE6B5 # 0 +0xA650 0xE6B6 # 0 +0xA651 0xE6B7 # 0 +0xA652 0xE6B8 # 0 +0xA653 0xE6B9 # 0 +0xA654 0xE6BA # 0 +0xA655 0xE6BB # 0 +0xA656 0xE6BC # 0 +0xA657 0xE6BD # 0 +0xA658 0xE6BE # 0 +0xA659 0xE6BF # 0 +0xA65A 0xE6C0 # 0 +0xA65B 0xE6C1 # 0 +0xA65C 0xE6C2 # 0 +0xA65D 0xE6C3 # 0 +0xA65E 0xE6C4 # 0 +0xA65F 0xE6C5 # 0 +0xA660 0xE6C6 # 0 +0xA661 0xE6C7 # 0 +0xA662 0xE6C8 # 0 +0xA663 0xE6C9 # 0 +0xA664 0xE6CA # 0 +0xA665 0xE6CB # 0 +0xA666 0xE6CC # 0 +0xA667 0xE6CD # 0 +0xA668 0xE6CE # 0 +0xA669 0xE6CF # 0 +0xA66A 0xE6D0 # 0 +0xA66B 0xE6D1 # 0 +0xA66C 0xE6D2 # 0 +0xA66D 0xE6D3 # 0 +0xA66E 0xE6D4 # 0 +0xA66F 0xE6D5 # 0 +0xA670 0xE6D6 # 0 +0xA671 0xE6D7 # 0 +0xA672 0xE6D8 # 0 +0xA673 0xE6D9 # 0 +0xA674 0xE6DA # 0 +0xA675 0xE6DB # 0 +0xA676 0xE6DC # 0 +0xA677 0xE6DD # 0 +0xA678 0xE6DE # 0 +0xA679 0xE6DF # 0 +0xA67A 0xE6E0 # 0 +0xA67B 0xE6E1 # 0 +0xA67C 0xE6E2 # 0 +0xA67D 0xE6E3 # 0 +0xA67E 0xE6E4 # 0 +0xA680 0xE6E5 # 0 +0xA681 0xE6E6 # 0 +0xA682 0xE6E7 # 0 +0xA683 0xE6E8 # 0 +0xA684 0xE6E9 # 0 +0xA685 0xE6EA # 0 +0xA686 0xE6EB # 0 +0xA687 0xE6EC # 0 +0xA688 0xE6ED # 0 +0xA689 0xE6EE # 0 +0xA68A 0xE6EF # 0 +0xA68B 0xE6F0 # 0 +0xA68C 0xE6F1 # 0 +0xA68D 0xE6F2 # 0 +0xA68E 0xE6F3 # 0 +0xA68F 0xE6F4 # 0 +0xA690 0xE6F5 # 0 +0xA691 0xE6F6 # 0 +0xA692 0xE6F7 # 0 +0xA693 0xE6F8 # 0 +0xA694 0xE6F9 # 0 +0xA695 0xE6FA # 0 +0xA696 0xE6FB # 0 +0xA697 0xE6FC # 0 +0xA698 0xE6FD # 0 +0xA699 0xE6FE # 0 +0xA69A 0xE6FF # 0 +0xA69B 0xE700 # 0 +0xA69C 0xE701 # 0 +0xA69D 0xE702 # 0 +0xA69E 0xE703 # 0 +0xA69F 0xE704 # 0 +0xA6A0 0xE705 # 0 +0xA6A1 0x0391 # 0 +0xA6A2 0x0392 # 0 +0xA6A3 0x0393 # 0 +0xA6A4 0x0394 # 0 +0xA6A5 0x0395 # 0 +0xA6A6 0x0396 # 0 +0xA6A7 0x0397 # 0 +0xA6A8 0x0398 # 0 +0xA6A9 0x0399 # 0 +0xA6AA 0x039A # 0 +0xA6AB 0x039B # 0 +0xA6AC 0x039C # 0 +0xA6AD 0x039D # 0 +0xA6AE 0x039E # 0 +0xA6AF 0x039F # 0 +0xA6B0 0x03A0 # 0 +0xA6B1 0x03A1 # 0 +0xA6B2 0x03A3 # 0 +0xA6B3 0x03A4 # 0 +0xA6B4 0x03A5 # 0 +0xA6B5 0x03A6 # 0 +0xA6B6 0x03A7 # 0 +0xA6B7 0x03A8 # 0 +0xA6B8 0x03A9 # 0 +0xA6B9 0xE785 # 0 +0xA6BA 0xE786 # 0 +0xA6BB 0xE787 # 0 +0xA6BC 0xE788 # 0 +0xA6BD 0xE789 # 0 +0xA6BE 0xE78A # 0 +0xA6BF 0xE78B # 0 +0xA6C0 0xE78C # 0 +0xA6C1 0x03B1 # 0 +0xA6C2 0x03B2 # 0 +0xA6C3 0x03B3 # 0 +0xA6C4 0x03B4 # 0 +0xA6C5 0x03B5 # 0 +0xA6C6 0x03B6 # 0 +0xA6C7 0x03B7 # 0 +0xA6C8 0x03B8 # 0 +0xA6C9 0x03B9 # 0 +0xA6CA 0x03BA # 0 +0xA6CB 0x03BB # 0 +0xA6CC 0x03BC # 0 +0xA6CD 0x03BD # 0 +0xA6CE 0x03BE # 0 +0xA6CF 0x03BF # 0 +0xA6D0 0x03C0 # 0 +0xA6D1 0x03C1 # 0 +0xA6D2 0x03C3 # 0 +0xA6D3 0x03C4 # 0 +0xA6D4 0x03C5 # 0 +0xA6D5 0x03C6 # 0 +0xA6D6 0x03C7 # 0 +0xA6D7 0x03C8 # 0 +0xA6D8 0x03C9 # 0 +0xA6D9 0xE78D # 0 +0xA6DA 0xE78E # 0 +0xA6DB 0xE78F # 0 +0xA6DC 0xE790 # 0 +0xA6DD 0xE791 # 0 +0xA6DE 0xE792 # 0 +0xA6DF 0xE793 # 0 +0xA6E0 0xFE35 # 0 +0xA6E1 0xFE36 # 0 +0xA6E2 0xFE39 # 0 +0xA6E3 0xFE3A # 0 +0xA6E4 0xFE3F # 0 +0xA6E5 0xFE40 # 0 +0xA6E6 0xFE3D # 0 +0xA6E7 0xFE3E # 0 +0xA6E8 0xFE41 # 0 +0xA6E9 0xFE42 # 0 +0xA6EA 0xFE43 # 0 +0xA6EB 0xFE44 # 0 +0xA6EC 0xE794 # 0 +0xA6ED 0xE795 # 0 +0xA6EE 0xFE3B # 0 +0xA6EF 0xFE3C # 0 +0xA6F0 0xFE37 # 0 +0xA6F1 0xFE38 # 0 +0xA6F2 0xFE31 # 0 +0xA6F3 0xE796 # 0 +0xA6F4 0xFE33 # 0 +0xA6F5 0xFE34 # 0 +0xA6F6 0xE797 # 0 +0xA6F7 0xE798 # 0 +0xA6F8 0xE799 # 0 +0xA6F9 0xE79A # 0 +0xA6FA 0xE79B # 0 +0xA6FB 0xE79C # 0 +0xA6FC 0xE79D # 0 +0xA6FD 0xE79E # 0 +0xA6FE 0xE79F # 0 +0xA740 0xE706 # 0 +0xA741 0xE707 # 0 +0xA742 0xE708 # 0 +0xA743 0xE709 # 0 +0xA744 0xE70A # 0 +0xA745 0xE70B # 0 +0xA746 0xE70C # 0 +0xA747 0xE70D # 0 +0xA748 0xE70E # 0 +0xA749 0xE70F # 0 +0xA74A 0xE710 # 0 +0xA74B 0xE711 # 0 +0xA74C 0xE712 # 0 +0xA74D 0xE713 # 0 +0xA74E 0xE714 # 0 +0xA74F 0xE715 # 0 +0xA750 0xE716 # 0 +0xA751 0xE717 # 0 +0xA752 0xE718 # 0 +0xA753 0xE719 # 0 +0xA754 0xE71A # 0 +0xA755 0xE71B # 0 +0xA756 0xE71C # 0 +0xA757 0xE71D # 0 +0xA758 0xE71E # 0 +0xA759 0xE71F # 0 +0xA75A 0xE720 # 0 +0xA75B 0xE721 # 0 +0xA75C 0xE722 # 0 +0xA75D 0xE723 # 0 +0xA75E 0xE724 # 0 +0xA75F 0xE725 # 0 +0xA760 0xE726 # 0 +0xA761 0xE727 # 0 +0xA762 0xE728 # 0 +0xA763 0xE729 # 0 +0xA764 0xE72A # 0 +0xA765 0xE72B # 0 +0xA766 0xE72C # 0 +0xA767 0xE72D # 0 +0xA768 0xE72E # 0 +0xA769 0xE72F # 0 +0xA76A 0xE730 # 0 +0xA76B 0xE731 # 0 +0xA76C 0xE732 # 0 +0xA76D 0xE733 # 0 +0xA76E 0xE734 # 0 +0xA76F 0xE735 # 0 +0xA770 0xE736 # 0 +0xA771 0xE737 # 0 +0xA772 0xE738 # 0 +0xA773 0xE739 # 0 +0xA774 0xE73A # 0 +0xA775 0xE73B # 0 +0xA776 0xE73C # 0 +0xA777 0xE73D # 0 +0xA778 0xE73E # 0 +0xA779 0xE73F # 0 +0xA77A 0xE740 # 0 +0xA77B 0xE741 # 0 +0xA77C 0xE742 # 0 +0xA77D 0xE743 # 0 +0xA77E 0xE744 # 0 +0xA780 0xE745 # 0 +0xA781 0xE746 # 0 +0xA782 0xE747 # 0 +0xA783 0xE748 # 0 +0xA784 0xE749 # 0 +0xA785 0xE74A # 0 +0xA786 0xE74B # 0 +0xA787 0xE74C # 0 +0xA788 0xE74D # 0 +0xA789 0xE74E # 0 +0xA78A 0xE74F # 0 +0xA78B 0xE750 # 0 +0xA78C 0xE751 # 0 +0xA78D 0xE752 # 0 +0xA78E 0xE753 # 0 +0xA78F 0xE754 # 0 +0xA790 0xE755 # 0 +0xA791 0xE756 # 0 +0xA792 0xE757 # 0 +0xA793 0xE758 # 0 +0xA794 0xE759 # 0 +0xA795 0xE75A # 0 +0xA796 0xE75B # 0 +0xA797 0xE75C # 0 +0xA798 0xE75D # 0 +0xA799 0xE75E # 0 +0xA79A 0xE75F # 0 +0xA79B 0xE760 # 0 +0xA79C 0xE761 # 0 +0xA79D 0xE762 # 0 +0xA79E 0xE763 # 0 +0xA79F 0xE764 # 0 +0xA7A0 0xE765 # 0 +0xA7A1 0x0410 # 0 +0xA7A2 0x0411 # 0 +0xA7A3 0x0412 # 0 +0xA7A4 0x0413 # 0 +0xA7A5 0x0414 # 0 +0xA7A6 0x0415 # 0 +0xA7A7 0x0401 # 0 +0xA7A8 0x0416 # 0 +0xA7A9 0x0417 # 0 +0xA7AA 0x0418 # 0 +0xA7AB 0x0419 # 0 +0xA7AC 0x041A # 0 +0xA7AD 0x041B # 0 +0xA7AE 0x041C # 0 +0xA7AF 0x041D # 0 +0xA7B0 0x041E # 0 +0xA7B1 0x041F # 0 +0xA7B2 0x0420 # 0 +0xA7B3 0x0421 # 0 +0xA7B4 0x0422 # 0 +0xA7B5 0x0423 # 0 +0xA7B6 0x0424 # 0 +0xA7B7 0x0425 # 0 +0xA7B8 0x0426 # 0 +0xA7B9 0x0427 # 0 +0xA7BA 0x0428 # 0 +0xA7BB 0x0429 # 0 +0xA7BC 0x042A # 0 +0xA7BD 0x042B # 0 +0xA7BE 0x042C # 0 +0xA7BF 0x042D # 0 +0xA7C0 0x042E # 0 +0xA7C1 0x042F # 0 +0xA7C2 0xE7A0 # 0 +0xA7C3 0xE7A1 # 0 +0xA7C4 0xE7A2 # 0 +0xA7C5 0xE7A3 # 0 +0xA7C6 0xE7A4 # 0 +0xA7C7 0xE7A5 # 0 +0xA7C8 0xE7A6 # 0 +0xA7C9 0xE7A7 # 0 +0xA7CA 0xE7A8 # 0 +0xA7CB 0xE7A9 # 0 +0xA7CC 0xE7AA # 0 +0xA7CD 0xE7AB # 0 +0xA7CE 0xE7AC # 0 +0xA7CF 0xE7AD # 0 +0xA7D0 0xE7AE # 0 +0xA7D1 0x0430 # 0 +0xA7D2 0x0431 # 0 +0xA7D3 0x0432 # 0 +0xA7D4 0x0433 # 0 +0xA7D5 0x0434 # 0 +0xA7D6 0x0435 # 0 +0xA7D7 0x0451 # 0 +0xA7D8 0x0436 # 0 +0xA7D9 0x0437 # 0 +0xA7DA 0x0438 # 0 +0xA7DB 0x0439 # 0 +0xA7DC 0x043A # 0 +0xA7DD 0x043B # 0 +0xA7DE 0x043C # 0 +0xA7DF 0x043D # 0 +0xA7E0 0x043E # 0 +0xA7E1 0x043F # 0 +0xA7E2 0x0440 # 0 +0xA7E3 0x0441 # 0 +0xA7E4 0x0442 # 0 +0xA7E5 0x0443 # 0 +0xA7E6 0x0444 # 0 +0xA7E7 0x0445 # 0 +0xA7E8 0x0446 # 0 +0xA7E9 0x0447 # 0 +0xA7EA 0x0448 # 0 +0xA7EB 0x0449 # 0 +0xA7EC 0x044A # 0 +0xA7ED 0x044B # 0 +0xA7EE 0x044C # 0 +0xA7EF 0x044D # 0 +0xA7F0 0x044E # 0 +0xA7F1 0x044F # 0 +0xA7F2 0xE7AF # 0 +0xA7F3 0xE7B0 # 0 +0xA7F4 0xE7B1 # 0 +0xA7F5 0xE7B2 # 0 +0xA7F6 0xE7B3 # 0 +0xA7F7 0xE7B4 # 0 +0xA7F8 0xE7B5 # 0 +0xA7F9 0xE7B6 # 0 +0xA7FA 0xE7B7 # 0 +0xA7FB 0xE7B8 # 0 +0xA7FC 0xE7B9 # 0 +0xA7FD 0xE7BA # 0 +0xA7FE 0xE7BB # 0 +0xA840 0x02CA # 0 +0xA841 0x02CB # 0 +0xA842 0x02D9 # 0 +0xA843 0x2013 # 0 +0xA844 0x2015 # 0 +0xA845 0x2025 # 0 +0xA846 0x2035 # 0 +0xA847 0x2105 # 0 +0xA848 0x2109 # 0 +0xA849 0x2196 # 0 +0xA84A 0x2197 # 0 +0xA84B 0x2198 # 0 +0xA84C 0x2199 # 0 +0xA84D 0x2215 # 0 +0xA84E 0x221F # 0 +0xA84F 0x2223 # 0 +0xA850 0x2252 # 0 +0xA851 0x2266 # 0 +0xA852 0x2267 # 0 +0xA853 0x22BF # 0 +0xA854 0x2550 # 0 +0xA855 0x2551 # 0 +0xA856 0x2552 # 0 +0xA857 0x2553 # 0 +0xA858 0x2554 # 0 +0xA859 0x2555 # 0 +0xA85A 0x2556 # 0 +0xA85B 0x2557 # 0 +0xA85C 0x2558 # 0 +0xA85D 0x2559 # 0 +0xA85E 0x255A # 0 +0xA85F 0x255B # 0 +0xA860 0x255C # 0 +0xA861 0x255D # 0 +0xA862 0x255E # 0 +0xA863 0x255F # 0 +0xA864 0x2560 # 0 +0xA865 0x2561 # 0 +0xA866 0x2562 # 0 +0xA867 0x2563 # 0 +0xA868 0x2564 # 0 +0xA869 0x2565 # 0 +0xA86A 0x2566 # 0 +0xA86B 0x2567 # 0 +0xA86C 0x2568 # 0 +0xA86D 0x2569 # 0 +0xA86E 0x256A # 0 +0xA86F 0x256B # 0 +0xA870 0x256C # 0 +0xA871 0x256D # 0 +0xA872 0x256E # 0 +0xA873 0x256F # 0 +0xA874 0x2570 # 0 +0xA875 0x2571 # 0 +0xA876 0x2572 # 0 +0xA877 0x2573 # 0 +0xA878 0x2581 # 0 +0xA879 0x2582 # 0 +0xA87A 0x2583 # 0 +0xA87B 0x2584 # 0 +0xA87C 0x2585 # 0 +0xA87D 0x2586 # 0 +0xA87E 0x2587 # 0 +0xA880 0x2588 # 0 +0xA881 0x2589 # 0 +0xA882 0x258A # 0 +0xA883 0x258B # 0 +0xA884 0x258C # 0 +0xA885 0x258D # 0 +0xA886 0x258E # 0 +0xA887 0x258F # 0 +0xA888 0x2593 # 0 +0xA889 0x2594 # 0 +0xA88A 0x2595 # 0 +0xA88B 0x25BC # 0 +0xA88C 0x25BD # 0 +0xA88D 0x25E2 # 0 +0xA88E 0x25E3 # 0 +0xA88F 0x25E4 # 0 +0xA890 0x25E5 # 0 +0xA891 0x2609 # 0 +0xA892 0x2295 # 0 +0xA893 0x3012 # 0 +0xA894 0x301D # 0 +0xA895 0x301E # 0 +0xA896 0xE7BC # 0 +0xA897 0xE7BD # 0 +0xA898 0xE7BE # 0 +0xA899 0xE7BF # 0 +0xA89A 0xE7C0 # 0 +0xA89B 0xE7C1 # 0 +0xA89C 0xE7C2 # 0 +0xA89D 0xE7C3 # 0 +0xA89E 0xE7C4 # 0 +0xA89F 0xE7C5 # 0 +0xA8A0 0xE7C6 # 0 +0xA8A1 0x0101 # 0 +0xA8A2 0x00E1 # 0 +0xA8A3 0x01CE # 0 +0xA8A4 0x00E0 # 0 +0xA8A5 0x0113 # 0 +0xA8A6 0x00E9 # 0 +0xA8A7 0x011B # 0 +0xA8A8 0x00E8 # 0 +0xA8A9 0x012B # 0 +0xA8AA 0x00ED # 0 +0xA8AB 0x01D0 # 0 +0xA8AC 0x00EC # 0 +0xA8AD 0x014D # 0 +0xA8AE 0x00F3 # 0 +0xA8AF 0x01D2 # 0 +0xA8B0 0x00F2 # 0 +0xA8B1 0x016B # 0 +0xA8B2 0x00FA # 0 +0xA8B3 0x01D4 # 0 +0xA8B4 0x00F9 # 0 +0xA8B5 0x01D6 # 0 +0xA8B6 0x01D8 # 0 +0xA8B7 0x01DA # 0 +0xA8B8 0x01DC # 0 +0xA8B9 0x00FC # 0 +0xA8BA 0x00EA # 0 +0xA8BB 0x0251 # 0 +0xA8BC 0xE7C7 # 0 +0xA8BD 0x0144 # 0 +0xA8BE 0x0148 # 0 +0xA8BF 0xE7C8 # 0 +0xA8C0 0x0261 # 0 +0xA8C1 0xE7C9 # 0 +0xA8C2 0xE7CA # 0 +0xA8C3 0xE7CB # 0 +0xA8C4 0xE7CC # 0 +0xA8C5 0x3105 # 0 +0xA8C6 0x3106 # 0 +0xA8C7 0x3107 # 0 +0xA8C8 0x3108 # 0 +0xA8C9 0x3109 # 0 +0xA8CA 0x310A # 0 +0xA8CB 0x310B # 0 +0xA8CC 0x310C # 0 +0xA8CD 0x310D # 0 +0xA8CE 0x310E # 0 +0xA8CF 0x310F # 0 +0xA8D0 0x3110 # 0 +0xA8D1 0x3111 # 0 +0xA8D2 0x3112 # 0 +0xA8D3 0x3113 # 0 +0xA8D4 0x3114 # 0 +0xA8D5 0x3115 # 0 +0xA8D6 0x3116 # 0 +0xA8D7 0x3117 # 0 +0xA8D8 0x3118 # 0 +0xA8D9 0x3119 # 0 +0xA8DA 0x311A # 0 +0xA8DB 0x311B # 0 +0xA8DC 0x311C # 0 +0xA8DD 0x311D # 0 +0xA8DE 0x311E # 0 +0xA8DF 0x311F # 0 +0xA8E0 0x3120 # 0 +0xA8E1 0x3121 # 0 +0xA8E2 0x3122 # 0 +0xA8E3 0x3123 # 0 +0xA8E4 0x3124 # 0 +0xA8E5 0x3125 # 0 +0xA8E6 0x3126 # 0 +0xA8E7 0x3127 # 0 +0xA8E8 0x3128 # 0 +0xA8E9 0x3129 # 0 +0xA8EA 0xE7CD # 0 +0xA8EB 0xE7CE # 0 +0xA8EC 0xE7CF # 0 +0xA8ED 0xE7D0 # 0 +0xA8EE 0xE7D1 # 0 +0xA8EF 0xE7D2 # 0 +0xA8F0 0xE7D3 # 0 +0xA8F1 0xE7D4 # 0 +0xA8F2 0xE7D5 # 0 +0xA8F3 0xE7D6 # 0 +0xA8F4 0xE7D7 # 0 +0xA8F5 0xE7D8 # 0 +0xA8F6 0xE7D9 # 0 +0xA8F7 0xE7DA # 0 +0xA8F8 0xE7DB # 0 +0xA8F9 0xE7DC # 0 +0xA8FA 0xE7DD # 0 +0xA8FB 0xE7DE # 0 +0xA8FC 0xE7DF # 0 +0xA8FD 0xE7E0 # 0 +0xA8FE 0xE7E1 # 0 +0xA940 0x3021 # 0 +0xA941 0x3022 # 0 +0xA942 0x3023 # 0 +0xA943 0x3024 # 0 +0xA944 0x3025 # 0 +0xA945 0x3026 # 0 +0xA946 0x3027 # 0 +0xA947 0x3028 # 0 +0xA948 0x3029 # 0 +0xA949 0x32A3 # 0 +0xA94A 0x338E # 0 +0xA94B 0x338F # 0 +0xA94C 0x339C # 0 +0xA94D 0x339D # 0 +0xA94E 0x339E # 0 +0xA94F 0x33A1 # 0 +0xA950 0x33C4 # 0 +0xA951 0x33CE # 0 +0xA952 0x33D1 # 0 +0xA953 0x33D2 # 0 +0xA954 0x33D5 # 0 +0xA955 0xFE30 # 0 +0xA956 0xFFE2 # 0 +0xA957 0xFFE4 # 0 +0xA958 0xE7E2 # 0 +0xA959 0x2121 # 0 +0xA95A 0x3231 # 0 +0xA95B 0xE7E3 # 0 +0xA95C 0x2010 # 0 +0xA95D 0xE7E4 # 0 +0xA95E 0xE7E5 # 0 +0xA95F 0xE7E6 # 0 +0xA960 0x30FC # 0 +0xA961 0x309B # 0 +0xA962 0x309C # 0 +0xA963 0x30FD # 0 +0xA964 0x30FE # 0 +0xA965 0x3006 # 0 +0xA966 0x309D # 0 +0xA967 0x309E # 0 +0xA968 0xFE49 # 0 +0xA969 0xFE4A # 0 +0xA96A 0xFE4B # 0 +0xA96B 0xFE4C # 0 +0xA96C 0xFE4D # 0 +0xA96D 0xFE4E # 0 +0xA96E 0xFE4F # 0 +0xA96F 0xFE50 # 0 +0xA970 0xFE51 # 0 +0xA971 0xFE52 # 0 +0xA972 0xFE54 # 0 +0xA973 0xFE55 # 0 +0xA974 0xFE56 # 0 +0xA975 0xFE57 # 0 +0xA976 0xFE59 # 0 +0xA977 0xFE5A # 0 +0xA978 0xFE5B # 0 +0xA979 0xFE5C # 0 +0xA97A 0xFE5D # 0 +0xA97B 0xFE5E # 0 +0xA97C 0xFE5F # 0 +0xA97D 0xFE60 # 0 +0xA97E 0xFE61 # 0 +0xA980 0xFE62 # 0 +0xA981 0xFE63 # 0 +0xA982 0xFE64 # 0 +0xA983 0xFE65 # 0 +0xA984 0xFE66 # 0 +0xA985 0xFE68 # 0 +0xA986 0xFE69 # 0 +0xA987 0xFE6A # 0 +0xA988 0xFE6B # 0 +0xA989 0xE7E7 # 0 +0xA98A 0xE7E8 # 0 +0xA98B 0xE7E9 # 0 +0xA98C 0xE7EA # 0 +0xA98D 0xE7EB # 0 +0xA98E 0xE7EC # 0 +0xA98F 0xE7ED # 0 +0xA990 0xE7EE # 0 +0xA991 0xE7EF # 0 +0xA992 0xE7F0 # 0 +0xA993 0xE7F1 # 0 +0xA994 0xE7F2 # 0 +0xA995 0xE7F3 # 0 +0xA996 0x3007 # 0 +0xA997 0xE7F4 # 0 +0xA998 0xE7F5 # 0 +0xA999 0xE7F6 # 0 +0xA99A 0xE7F7 # 0 +0xA99B 0xE7F8 # 0 +0xA99C 0xE7F9 # 0 +0xA99D 0xE7FA # 0 +0xA99E 0xE7FB # 0 +0xA99F 0xE7FC # 0 +0xA9A0 0xE7FD # 0 +0xA9A1 0xE7FE # 0 +0xA9A2 0xE7FF # 0 +0xA9A3 0xE800 # 0 +0xA9A4 0x2500 # 0 +0xA9A5 0x2501 # 0 +0xA9A6 0x2502 # 0 +0xA9A7 0x2503 # 0 +0xA9A8 0x2504 # 0 +0xA9A9 0x2505 # 0 +0xA9AA 0x2506 # 0 +0xA9AB 0x2507 # 0 +0xA9AC 0x2508 # 0 +0xA9AD 0x2509 # 0 +0xA9AE 0x250A # 0 +0xA9AF 0x250B # 0 +0xA9B0 0x250C # 0 +0xA9B1 0x250D # 0 +0xA9B2 0x250E # 0 +0xA9B3 0x250F # 0 +0xA9B4 0x2510 # 0 +0xA9B5 0x2511 # 0 +0xA9B6 0x2512 # 0 +0xA9B7 0x2513 # 0 +0xA9B8 0x2514 # 0 +0xA9B9 0x2515 # 0 +0xA9BA 0x2516 # 0 +0xA9BB 0x2517 # 0 +0xA9BC 0x2518 # 0 +0xA9BD 0x2519 # 0 +0xA9BE 0x251A # 0 +0xA9BF 0x251B # 0 +0xA9C0 0x251C # 0 +0xA9C1 0x251D # 0 +0xA9C2 0x251E # 0 +0xA9C3 0x251F # 0 +0xA9C4 0x2520 # 0 +0xA9C5 0x2521 # 0 +0xA9C6 0x2522 # 0 +0xA9C7 0x2523 # 0 +0xA9C8 0x2524 # 0 +0xA9C9 0x2525 # 0 +0xA9CA 0x2526 # 0 +0xA9CB 0x2527 # 0 +0xA9CC 0x2528 # 0 +0xA9CD 0x2529 # 0 +0xA9CE 0x252A # 0 +0xA9CF 0x252B # 0 +0xA9D0 0x252C # 0 +0xA9D1 0x252D # 0 +0xA9D2 0x252E # 0 +0xA9D3 0x252F # 0 +0xA9D4 0x2530 # 0 +0xA9D5 0x2531 # 0 +0xA9D6 0x2532 # 0 +0xA9D7 0x2533 # 0 +0xA9D8 0x2534 # 0 +0xA9D9 0x2535 # 0 +0xA9DA 0x2536 # 0 +0xA9DB 0x2537 # 0 +0xA9DC 0x2538 # 0 +0xA9DD 0x2539 # 0 +0xA9DE 0x253A # 0 +0xA9DF 0x253B # 0 +0xA9E0 0x253C # 0 +0xA9E1 0x253D # 0 +0xA9E2 0x253E # 0 +0xA9E3 0x253F # 0 +0xA9E4 0x2540 # 0 +0xA9E5 0x2541 # 0 +0xA9E6 0x2542 # 0 +0xA9E7 0x2543 # 0 +0xA9E8 0x2544 # 0 +0xA9E9 0x2545 # 0 +0xA9EA 0x2546 # 0 +0xA9EB 0x2547 # 0 +0xA9EC 0x2548 # 0 +0xA9ED 0x2549 # 0 +0xA9EE 0x254A # 0 +0xA9EF 0x254B # 0 +0xA9F0 0xE801 # 0 +0xA9F1 0xE802 # 0 +0xA9F2 0xE803 # 0 +0xA9F3 0xE804 # 0 +0xA9F4 0xE805 # 0 +0xA9F5 0xE806 # 0 +0xA9F6 0xE807 # 0 +0xA9F7 0xE808 # 0 +0xA9F8 0xE809 # 0 +0xA9F9 0xE80A # 0 +0xA9FA 0xE80B # 0 +0xA9FB 0xE80C # 0 +0xA9FC 0xE80D # 0 +0xA9FD 0xE80E # 0 +0xA9FE 0xE80F # 0 +0xAA40 0x72DC # 0 +0xAA41 0x72DD # 0 +0xAA42 0x72DF # 0 +0xAA43 0x72E2 # 0 +0xAA44 0x72E3 # 0 +0xAA45 0x72E4 # 0 +0xAA46 0x72E5 # 0 +0xAA47 0x72E6 # 0 +0xAA48 0x72E7 # 0 +0xAA49 0x72EA # 0 +0xAA4A 0x72EB # 0 +0xAA4B 0x72F5 # 0 +0xAA4C 0x72F6 # 0 +0xAA4D 0x72F9 # 0 +0xAA4E 0x72FD # 0 +0xAA4F 0x72FE # 0 +0xAA50 0x72FF # 0 +0xAA51 0x7300 # 0 +0xAA52 0x7302 # 0 +0xAA53 0x7304 # 0 +0xAA54 0x7305 # 0 +0xAA55 0x7306 # 0 +0xAA56 0x7307 # 0 +0xAA57 0x7308 # 0 +0xAA58 0x7309 # 0 +0xAA59 0x730B # 0 +0xAA5A 0x730C # 0 +0xAA5B 0x730D # 0 +0xAA5C 0x730F # 0 +0xAA5D 0x7310 # 0 +0xAA5E 0x7311 # 0 +0xAA5F 0x7312 # 0 +0xAA60 0x7314 # 0 +0xAA61 0x7318 # 0 +0xAA62 0x7319 # 0 +0xAA63 0x731A # 0 +0xAA64 0x731F # 0 +0xAA65 0x7320 # 0 +0xAA66 0x7323 # 0 +0xAA67 0x7324 # 0 +0xAA68 0x7326 # 0 +0xAA69 0x7327 # 0 +0xAA6A 0x7328 # 0 +0xAA6B 0x732D # 0 +0xAA6C 0x732F # 0 +0xAA6D 0x7330 # 0 +0xAA6E 0x7332 # 0 +0xAA6F 0x7333 # 0 +0xAA70 0x7335 # 0 +0xAA71 0x7336 # 0 +0xAA72 0x733A # 0 +0xAA73 0x733B # 0 +0xAA74 0x733C # 0 +0xAA75 0x733D # 0 +0xAA76 0x7340 # 0 +0xAA77 0x7341 # 0 +0xAA78 0x7342 # 0 +0xAA79 0x7343 # 0 +0xAA7A 0x7344 # 0 +0xAA7B 0x7345 # 0 +0xAA7C 0x7346 # 0 +0xAA7D 0x7347 # 0 +0xAA7E 0x7348 # 0 +0xAA80 0x7349 # 0 +0xAA81 0x734A # 0 +0xAA82 0x734B # 0 +0xAA83 0x734C # 0 +0xAA84 0x734E # 0 +0xAA85 0x734F # 0 +0xAA86 0x7351 # 0 +0xAA87 0x7353 # 0 +0xAA88 0x7354 # 0 +0xAA89 0x7355 # 0 +0xAA8A 0x7356 # 0 +0xAA8B 0x7358 # 0 +0xAA8C 0x7359 # 0 +0xAA8D 0x735A # 0 +0xAA8E 0x735B # 0 +0xAA8F 0x735C # 0 +0xAA90 0x735D # 0 +0xAA91 0x735E # 0 +0xAA92 0x735F # 0 +0xAA93 0x7361 # 0 +0xAA94 0x7362 # 0 +0xAA95 0x7363 # 0 +0xAA96 0x7364 # 0 +0xAA97 0x7365 # 0 +0xAA98 0x7366 # 0 +0xAA99 0x7367 # 0 +0xAA9A 0x7368 # 0 +0xAA9B 0x7369 # 0 +0xAA9C 0x736A # 0 +0xAA9D 0x736B # 0 +0xAA9E 0x736E # 0 +0xAA9F 0x7370 # 0 +0xAAA0 0x7371 # 0 +0xAAA1 0xE000 # 0 +0xAAA2 0xE001 # 0 +0xAAA3 0xE002 # 0 +0xAAA4 0xE003 # 0 +0xAAA5 0xE004 # 0 +0xAAA6 0xE005 # 0 +0xAAA7 0xE006 # 0 +0xAAA8 0xE007 # 0 +0xAAA9 0xE008 # 0 +0xAAAA 0xE009 # 0 +0xAAAB 0xE00A # 0 +0xAAAC 0xE00B # 0 +0xAAAD 0xE00C # 0 +0xAAAE 0xE00D # 0 +0xAAAF 0xE00E # 0 +0xAAB0 0xE00F # 0 +0xAAB1 0xE010 # 0 +0xAAB2 0xE011 # 0 +0xAAB3 0xE012 # 0 +0xAAB4 0xE013 # 0 +0xAAB5 0xE014 # 0 +0xAAB6 0xE015 # 0 +0xAAB7 0xE016 # 0 +0xAAB8 0xE017 # 0 +0xAAB9 0xE018 # 0 +0xAABA 0xE019 # 0 +0xAABB 0xE01A # 0 +0xAABC 0xE01B # 0 +0xAABD 0xE01C # 0 +0xAABE 0xE01D # 0 +0xAABF 0xE01E # 0 +0xAAC0 0xE01F # 0 +0xAAC1 0xE020 # 0 +0xAAC2 0xE021 # 0 +0xAAC3 0xE022 # 0 +0xAAC4 0xE023 # 0 +0xAAC5 0xE024 # 0 +0xAAC6 0xE025 # 0 +0xAAC7 0xE026 # 0 +0xAAC8 0xE027 # 0 +0xAAC9 0xE028 # 0 +0xAACA 0xE029 # 0 +0xAACB 0xE02A # 0 +0xAACC 0xE02B # 0 +0xAACD 0xE02C # 0 +0xAACE 0xE02D # 0 +0xAACF 0xE02E # 0 +0xAAD0 0xE02F # 0 +0xAAD1 0xE030 # 0 +0xAAD2 0xE031 # 0 +0xAAD3 0xE032 # 0 +0xAAD4 0xE033 # 0 +0xAAD5 0xE034 # 0 +0xAAD6 0xE035 # 0 +0xAAD7 0xE036 # 0 +0xAAD8 0xE037 # 0 +0xAAD9 0xE038 # 0 +0xAADA 0xE039 # 0 +0xAADB 0xE03A # 0 +0xAADC 0xE03B # 0 +0xAADD 0xE03C # 0 +0xAADE 0xE03D # 0 +0xAADF 0xE03E # 0 +0xAAE0 0xE03F # 0 +0xAAE1 0xE040 # 0 +0xAAE2 0xE041 # 0 +0xAAE3 0xE042 # 0 +0xAAE4 0xE043 # 0 +0xAAE5 0xE044 # 0 +0xAAE6 0xE045 # 0 +0xAAE7 0xE046 # 0 +0xAAE8 0xE047 # 0 +0xAAE9 0xE048 # 0 +0xAAEA 0xE049 # 0 +0xAAEB 0xE04A # 0 +0xAAEC 0xE04B # 0 +0xAAED 0xE04C # 0 +0xAAEE 0xE04D # 0 +0xAAEF 0xE04E # 0 +0xAAF0 0xE04F # 0 +0xAAF1 0xE050 # 0 +0xAAF2 0xE051 # 0 +0xAAF3 0xE052 # 0 +0xAAF4 0xE053 # 0 +0xAAF5 0xE054 # 0 +0xAAF6 0xE055 # 0 +0xAAF7 0xE056 # 0 +0xAAF8 0xE057 # 0 +0xAAF9 0xE058 # 0 +0xAAFA 0xE059 # 0 +0xAAFB 0xE05A # 0 +0xAAFC 0xE05B # 0 +0xAAFD 0xE05C # 0 +0xAAFE 0xE05D # 0 +0xAB40 0x7372 # 0 +0xAB41 0x7373 # 0 +0xAB42 0x7374 # 0 +0xAB43 0x7375 # 0 +0xAB44 0x7376 # 0 +0xAB45 0x7377 # 0 +0xAB46 0x7378 # 0 +0xAB47 0x7379 # 0 +0xAB48 0x737A # 0 +0xAB49 0x737B # 0 +0xAB4A 0x737C # 0 +0xAB4B 0x737D # 0 +0xAB4C 0x737F # 0 +0xAB4D 0x7380 # 0 +0xAB4E 0x7381 # 0 +0xAB4F 0x7382 # 0 +0xAB50 0x7383 # 0 +0xAB51 0x7385 # 0 +0xAB52 0x7386 # 0 +0xAB53 0x7388 # 0 +0xAB54 0x738A # 0 +0xAB55 0x738C # 0 +0xAB56 0x738D # 0 +0xAB57 0x738F # 0 +0xAB58 0x7390 # 0 +0xAB59 0x7392 # 0 +0xAB5A 0x7393 # 0 +0xAB5B 0x7394 # 0 +0xAB5C 0x7395 # 0 +0xAB5D 0x7397 # 0 +0xAB5E 0x7398 # 0 +0xAB5F 0x7399 # 0 +0xAB60 0x739A # 0 +0xAB61 0x739C # 0 +0xAB62 0x739D # 0 +0xAB63 0x739E # 0 +0xAB64 0x73A0 # 0 +0xAB65 0x73A1 # 0 +0xAB66 0x73A3 # 0 +0xAB67 0x73A4 # 0 +0xAB68 0x73A5 # 0 +0xAB69 0x73A6 # 0 +0xAB6A 0x73A7 # 0 +0xAB6B 0x73A8 # 0 +0xAB6C 0x73AA # 0 +0xAB6D 0x73AC # 0 +0xAB6E 0x73AD # 0 +0xAB6F 0x73B1 # 0 +0xAB70 0x73B4 # 0 +0xAB71 0x73B5 # 0 +0xAB72 0x73B6 # 0 +0xAB73 0x73B8 # 0 +0xAB74 0x73B9 # 0 +0xAB75 0x73BC # 0 +0xAB76 0x73BD # 0 +0xAB77 0x73BE # 0 +0xAB78 0x73BF # 0 +0xAB79 0x73C1 # 0 +0xAB7A 0x73C3 # 0 +0xAB7B 0x73C4 # 0 +0xAB7C 0x73C5 # 0 +0xAB7D 0x73C6 # 0 +0xAB7E 0x73C7 # 0 +0xAB80 0x73CB # 0 +0xAB81 0x73CC # 0 +0xAB82 0x73CE # 0 +0xAB83 0x73D2 # 0 +0xAB84 0x73D3 # 0 +0xAB85 0x73D4 # 0 +0xAB86 0x73D5 # 0 +0xAB87 0x73D6 # 0 +0xAB88 0x73D7 # 0 +0xAB89 0x73D8 # 0 +0xAB8A 0x73DA # 0 +0xAB8B 0x73DB # 0 +0xAB8C 0x73DC # 0 +0xAB8D 0x73DD # 0 +0xAB8E 0x73DF # 0 +0xAB8F 0x73E1 # 0 +0xAB90 0x73E2 # 0 +0xAB91 0x73E3 # 0 +0xAB92 0x73E4 # 0 +0xAB93 0x73E6 # 0 +0xAB94 0x73E8 # 0 +0xAB95 0x73EA # 0 +0xAB96 0x73EB # 0 +0xAB97 0x73EC # 0 +0xAB98 0x73EE # 0 +0xAB99 0x73EF # 0 +0xAB9A 0x73F0 # 0 +0xAB9B 0x73F1 # 0 +0xAB9C 0x73F3 # 0 +0xAB9D 0x73F4 # 0 +0xAB9E 0x73F5 # 0 +0xAB9F 0x73F6 # 0 +0xABA0 0x73F7 # 0 +0xABA1 0xE05E # 0 +0xABA2 0xE05F # 0 +0xABA3 0xE060 # 0 +0xABA4 0xE061 # 0 +0xABA5 0xE062 # 0 +0xABA6 0xE063 # 0 +0xABA7 0xE064 # 0 +0xABA8 0xE065 # 0 +0xABA9 0xE066 # 0 +0xABAA 0xE067 # 0 +0xABAB 0xE068 # 0 +0xABAC 0xE069 # 0 +0xABAD 0xE06A # 0 +0xABAE 0xE06B # 0 +0xABAF 0xE06C # 0 +0xABB0 0xE06D # 0 +0xABB1 0xE06E # 0 +0xABB2 0xE06F # 0 +0xABB3 0xE070 # 0 +0xABB4 0xE071 # 0 +0xABB5 0xE072 # 0 +0xABB6 0xE073 # 0 +0xABB7 0xE074 # 0 +0xABB8 0xE075 # 0 +0xABB9 0xE076 # 0 +0xABBA 0xE077 # 0 +0xABBB 0xE078 # 0 +0xABBC 0xE079 # 0 +0xABBD 0xE07A # 0 +0xABBE 0xE07B # 0 +0xABBF 0xE07C # 0 +0xABC0 0xE07D # 0 +0xABC1 0xE07E # 0 +0xABC2 0xE07F # 0 +0xABC3 0xE080 # 0 +0xABC4 0xE081 # 0 +0xABC5 0xE082 # 0 +0xABC6 0xE083 # 0 +0xABC7 0xE084 # 0 +0xABC8 0xE085 # 0 +0xABC9 0xE086 # 0 +0xABCA 0xE087 # 0 +0xABCB 0xE088 # 0 +0xABCC 0xE089 # 0 +0xABCD 0xE08A # 0 +0xABCE 0xE08B # 0 +0xABCF 0xE08C # 0 +0xABD0 0xE08D # 0 +0xABD1 0xE08E # 0 +0xABD2 0xE08F # 0 +0xABD3 0xE090 # 0 +0xABD4 0xE091 # 0 +0xABD5 0xE092 # 0 +0xABD6 0xE093 # 0 +0xABD7 0xE094 # 0 +0xABD8 0xE095 # 0 +0xABD9 0xE096 # 0 +0xABDA 0xE097 # 0 +0xABDB 0xE098 # 0 +0xABDC 0xE099 # 0 +0xABDD 0xE09A # 0 +0xABDE 0xE09B # 0 +0xABDF 0xE09C # 0 +0xABE0 0xE09D # 0 +0xABE1 0xE09E # 0 +0xABE2 0xE09F # 0 +0xABE3 0xE0A0 # 0 +0xABE4 0xE0A1 # 0 +0xABE5 0xE0A2 # 0 +0xABE6 0xE0A3 # 0 +0xABE7 0xE0A4 # 0 +0xABE8 0xE0A5 # 0 +0xABE9 0xE0A6 # 0 +0xABEA 0xE0A7 # 0 +0xABEB 0xE0A8 # 0 +0xABEC 0xE0A9 # 0 +0xABED 0xE0AA # 0 +0xABEE 0xE0AB # 0 +0xABEF 0xE0AC # 0 +0xABF0 0xE0AD # 0 +0xABF1 0xE0AE # 0 +0xABF2 0xE0AF # 0 +0xABF3 0xE0B0 # 0 +0xABF4 0xE0B1 # 0 +0xABF5 0xE0B2 # 0 +0xABF6 0xE0B3 # 0 +0xABF7 0xE0B4 # 0 +0xABF8 0xE0B5 # 0 +0xABF9 0xE0B6 # 0 +0xABFA 0xE0B7 # 0 +0xABFB 0xE0B8 # 0 +0xABFC 0xE0B9 # 0 +0xABFD 0xE0BA # 0 +0xABFE 0xE0BB # 0 +0xAC40 0x73F8 # 0 +0xAC41 0x73F9 # 0 +0xAC42 0x73FA # 0 +0xAC43 0x73FB # 0 +0xAC44 0x73FC # 0 +0xAC45 0x73FD # 0 +0xAC46 0x73FE # 0 +0xAC47 0x73FF # 0 +0xAC48 0x7400 # 0 +0xAC49 0x7401 # 0 +0xAC4A 0x7402 # 0 +0xAC4B 0x7404 # 0 +0xAC4C 0x7407 # 0 +0xAC4D 0x7408 # 0 +0xAC4E 0x740B # 0 +0xAC4F 0x740C # 0 +0xAC50 0x740D # 0 +0xAC51 0x740E # 0 +0xAC52 0x7411 # 0 +0xAC53 0x7412 # 0 +0xAC54 0x7413 # 0 +0xAC55 0x7414 # 0 +0xAC56 0x7415 # 0 +0xAC57 0x7416 # 0 +0xAC58 0x7417 # 0 +0xAC59 0x7418 # 0 +0xAC5A 0x7419 # 0 +0xAC5B 0x741C # 0 +0xAC5C 0x741D # 0 +0xAC5D 0x741E # 0 +0xAC5E 0x741F # 0 +0xAC5F 0x7420 # 0 +0xAC60 0x7421 # 0 +0xAC61 0x7423 # 0 +0xAC62 0x7424 # 0 +0xAC63 0x7427 # 0 +0xAC64 0x7429 # 0 +0xAC65 0x742B # 0 +0xAC66 0x742D # 0 +0xAC67 0x742F # 0 +0xAC68 0x7431 # 0 +0xAC69 0x7432 # 0 +0xAC6A 0x7437 # 0 +0xAC6B 0x7438 # 0 +0xAC6C 0x7439 # 0 +0xAC6D 0x743A # 0 +0xAC6E 0x743B # 0 +0xAC6F 0x743D # 0 +0xAC70 0x743E # 0 +0xAC71 0x743F # 0 +0xAC72 0x7440 # 0 +0xAC73 0x7442 # 0 +0xAC74 0x7443 # 0 +0xAC75 0x7444 # 0 +0xAC76 0x7445 # 0 +0xAC77 0x7446 # 0 +0xAC78 0x7447 # 0 +0xAC79 0x7448 # 0 +0xAC7A 0x7449 # 0 +0xAC7B 0x744A # 0 +0xAC7C 0x744B # 0 +0xAC7D 0x744C # 0 +0xAC7E 0x744D # 0 +0xAC80 0x744E # 0 +0xAC81 0x744F # 0 +0xAC82 0x7450 # 0 +0xAC83 0x7451 # 0 +0xAC84 0x7452 # 0 +0xAC85 0x7453 # 0 +0xAC86 0x7454 # 0 +0xAC87 0x7456 # 0 +0xAC88 0x7458 # 0 +0xAC89 0x745D # 0 +0xAC8A 0x7460 # 0 +0xAC8B 0x7461 # 0 +0xAC8C 0x7462 # 0 +0xAC8D 0x7463 # 0 +0xAC8E 0x7464 # 0 +0xAC8F 0x7465 # 0 +0xAC90 0x7466 # 0 +0xAC91 0x7467 # 0 +0xAC92 0x7468 # 0 +0xAC93 0x7469 # 0 +0xAC94 0x746A # 0 +0xAC95 0x746B # 0 +0xAC96 0x746C # 0 +0xAC97 0x746E # 0 +0xAC98 0x746F # 0 +0xAC99 0x7471 # 0 +0xAC9A 0x7472 # 0 +0xAC9B 0x7473 # 0 +0xAC9C 0x7474 # 0 +0xAC9D 0x7475 # 0 +0xAC9E 0x7478 # 0 +0xAC9F 0x7479 # 0 +0xACA0 0x747A # 0 +0xACA1 0xE0BC # 0 +0xACA2 0xE0BD # 0 +0xACA3 0xE0BE # 0 +0xACA4 0xE0BF # 0 +0xACA5 0xE0C0 # 0 +0xACA6 0xE0C1 # 0 +0xACA7 0xE0C2 # 0 +0xACA8 0xE0C3 # 0 +0xACA9 0xE0C4 # 0 +0xACAA 0xE0C5 # 0 +0xACAB 0xE0C6 # 0 +0xACAC 0xE0C7 # 0 +0xACAD 0xE0C8 # 0 +0xACAE 0xE0C9 # 0 +0xACAF 0xE0CA # 0 +0xACB0 0xE0CB # 0 +0xACB1 0xE0CC # 0 +0xACB2 0xE0CD # 0 +0xACB3 0xE0CE # 0 +0xACB4 0xE0CF # 0 +0xACB5 0xE0D0 # 0 +0xACB6 0xE0D1 # 0 +0xACB7 0xE0D2 # 0 +0xACB8 0xE0D3 # 0 +0xACB9 0xE0D4 # 0 +0xACBA 0xE0D5 # 0 +0xACBB 0xE0D6 # 0 +0xACBC 0xE0D7 # 0 +0xACBD 0xE0D8 # 0 +0xACBE 0xE0D9 # 0 +0xACBF 0xE0DA # 0 +0xACC0 0xE0DB # 0 +0xACC1 0xE0DC # 0 +0xACC2 0xE0DD # 0 +0xACC3 0xE0DE # 0 +0xACC4 0xE0DF # 0 +0xACC5 0xE0E0 # 0 +0xACC6 0xE0E1 # 0 +0xACC7 0xE0E2 # 0 +0xACC8 0xE0E3 # 0 +0xACC9 0xE0E4 # 0 +0xACCA 0xE0E5 # 0 +0xACCB 0xE0E6 # 0 +0xACCC 0xE0E7 # 0 +0xACCD 0xE0E8 # 0 +0xACCE 0xE0E9 # 0 +0xACCF 0xE0EA # 0 +0xACD0 0xE0EB # 0 +0xACD1 0xE0EC # 0 +0xACD2 0xE0ED # 0 +0xACD3 0xE0EE # 0 +0xACD4 0xE0EF # 0 +0xACD5 0xE0F0 # 0 +0xACD6 0xE0F1 # 0 +0xACD7 0xE0F2 # 0 +0xACD8 0xE0F3 # 0 +0xACD9 0xE0F4 # 0 +0xACDA 0xE0F5 # 0 +0xACDB 0xE0F6 # 0 +0xACDC 0xE0F7 # 0 +0xACDD 0xE0F8 # 0 +0xACDE 0xE0F9 # 0 +0xACDF 0xE0FA # 0 +0xACE0 0xE0FB # 0 +0xACE1 0xE0FC # 0 +0xACE2 0xE0FD # 0 +0xACE3 0xE0FE # 0 +0xACE4 0xE0FF # 0 +0xACE5 0xE100 # 0 +0xACE6 0xE101 # 0 +0xACE7 0xE102 # 0 +0xACE8 0xE103 # 0 +0xACE9 0xE104 # 0 +0xACEA 0xE105 # 0 +0xACEB 0xE106 # 0 +0xACEC 0xE107 # 0 +0xACED 0xE108 # 0 +0xACEE 0xE109 # 0 +0xACEF 0xE10A # 0 +0xACF0 0xE10B # 0 +0xACF1 0xE10C # 0 +0xACF2 0xE10D # 0 +0xACF3 0xE10E # 0 +0xACF4 0xE10F # 0 +0xACF5 0xE110 # 0 +0xACF6 0xE111 # 0 +0xACF7 0xE112 # 0 +0xACF8 0xE113 # 0 +0xACF9 0xE114 # 0 +0xACFA 0xE115 # 0 +0xACFB 0xE116 # 0 +0xACFC 0xE117 # 0 +0xACFD 0xE118 # 0 +0xACFE 0xE119 # 0 +0xAD40 0x747B # 0 +0xAD41 0x747C # 0 +0xAD42 0x747D # 0 +0xAD43 0x747F # 0 +0xAD44 0x7482 # 0 +0xAD45 0x7484 # 0 +0xAD46 0x7485 # 0 +0xAD47 0x7486 # 0 +0xAD48 0x7488 # 0 +0xAD49 0x7489 # 0 +0xAD4A 0x748A # 0 +0xAD4B 0x748C # 0 +0xAD4C 0x748D # 0 +0xAD4D 0x748F # 0 +0xAD4E 0x7491 # 0 +0xAD4F 0x7492 # 0 +0xAD50 0x7493 # 0 +0xAD51 0x7494 # 0 +0xAD52 0x7495 # 0 +0xAD53 0x7496 # 0 +0xAD54 0x7497 # 0 +0xAD55 0x7498 # 0 +0xAD56 0x7499 # 0 +0xAD57 0x749A # 0 +0xAD58 0x749B # 0 +0xAD59 0x749D # 0 +0xAD5A 0x749F # 0 +0xAD5B 0x74A0 # 0 +0xAD5C 0x74A1 # 0 +0xAD5D 0x74A2 # 0 +0xAD5E 0x74A3 # 0 +0xAD5F 0x74A4 # 0 +0xAD60 0x74A5 # 0 +0xAD61 0x74A6 # 0 +0xAD62 0x74AA # 0 +0xAD63 0x74AB # 0 +0xAD64 0x74AC # 0 +0xAD65 0x74AD # 0 +0xAD66 0x74AE # 0 +0xAD67 0x74AF # 0 +0xAD68 0x74B0 # 0 +0xAD69 0x74B1 # 0 +0xAD6A 0x74B2 # 0 +0xAD6B 0x74B3 # 0 +0xAD6C 0x74B4 # 0 +0xAD6D 0x74B5 # 0 +0xAD6E 0x74B6 # 0 +0xAD6F 0x74B7 # 0 +0xAD70 0x74B8 # 0 +0xAD71 0x74B9 # 0 +0xAD72 0x74BB # 0 +0xAD73 0x74BC # 0 +0xAD74 0x74BD # 0 +0xAD75 0x74BE # 0 +0xAD76 0x74BF # 0 +0xAD77 0x74C0 # 0 +0xAD78 0x74C1 # 0 +0xAD79 0x74C2 # 0 +0xAD7A 0x74C3 # 0 +0xAD7B 0x74C4 # 0 +0xAD7C 0x74C5 # 0 +0xAD7D 0x74C6 # 0 +0xAD7E 0x74C7 # 0 +0xAD80 0x74C8 # 0 +0xAD81 0x74C9 # 0 +0xAD82 0x74CA # 0 +0xAD83 0x74CB # 0 +0xAD84 0x74CC # 0 +0xAD85 0x74CD # 0 +0xAD86 0x74CE # 0 +0xAD87 0x74CF # 0 +0xAD88 0x74D0 # 0 +0xAD89 0x74D1 # 0 +0xAD8A 0x74D3 # 0 +0xAD8B 0x74D4 # 0 +0xAD8C 0x74D5 # 0 +0xAD8D 0x74D6 # 0 +0xAD8E 0x74D7 # 0 +0xAD8F 0x74D8 # 0 +0xAD90 0x74D9 # 0 +0xAD91 0x74DA # 0 +0xAD92 0x74DB # 0 +0xAD93 0x74DD # 0 +0xAD94 0x74DF # 0 +0xAD95 0x74E1 # 0 +0xAD96 0x74E5 # 0 +0xAD97 0x74E7 # 0 +0xAD98 0x74E8 # 0 +0xAD99 0x74E9 # 0 +0xAD9A 0x74EA # 0 +0xAD9B 0x74EB # 0 +0xAD9C 0x74EC # 0 +0xAD9D 0x74ED # 0 +0xAD9E 0x74F0 # 0 +0xAD9F 0x74F1 # 0 +0xADA0 0x74F2 # 0 +0xADA1 0xE11A # 0 +0xADA2 0xE11B # 0 +0xADA3 0xE11C # 0 +0xADA4 0xE11D # 0 +0xADA5 0xE11E # 0 +0xADA6 0xE11F # 0 +0xADA7 0xE120 # 0 +0xADA8 0xE121 # 0 +0xADA9 0xE122 # 0 +0xADAA 0xE123 # 0 +0xADAB 0xE124 # 0 +0xADAC 0xE125 # 0 +0xADAD 0xE126 # 0 +0xADAE 0xE127 # 0 +0xADAF 0xE128 # 0 +0xADB0 0xE129 # 0 +0xADB1 0xE12A # 0 +0xADB2 0xE12B # 0 +0xADB3 0xE12C # 0 +0xADB4 0xE12D # 0 +0xADB5 0xE12E # 0 +0xADB6 0xE12F # 0 +0xADB7 0xE130 # 0 +0xADB8 0xE131 # 0 +0xADB9 0xE132 # 0 +0xADBA 0xE133 # 0 +0xADBB 0xE134 # 0 +0xADBC 0xE135 # 0 +0xADBD 0xE136 # 0 +0xADBE 0xE137 # 0 +0xADBF 0xE138 # 0 +0xADC0 0xE139 # 0 +0xADC1 0xE13A # 0 +0xADC2 0xE13B # 0 +0xADC3 0xE13C # 0 +0xADC4 0xE13D # 0 +0xADC5 0xE13E # 0 +0xADC6 0xE13F # 0 +0xADC7 0xE140 # 0 +0xADC8 0xE141 # 0 +0xADC9 0xE142 # 0 +0xADCA 0xE143 # 0 +0xADCB 0xE144 # 0 +0xADCC 0xE145 # 0 +0xADCD 0xE146 # 0 +0xADCE 0xE147 # 0 +0xADCF 0xE148 # 0 +0xADD0 0xE149 # 0 +0xADD1 0xE14A # 0 +0xADD2 0xE14B # 0 +0xADD3 0xE14C # 0 +0xADD4 0xE14D # 0 +0xADD5 0xE14E # 0 +0xADD6 0xE14F # 0 +0xADD7 0xE150 # 0 +0xADD8 0xE151 # 0 +0xADD9 0xE152 # 0 +0xADDA 0xE153 # 0 +0xADDB 0xE154 # 0 +0xADDC 0xE155 # 0 +0xADDD 0xE156 # 0 +0xADDE 0xE157 # 0 +0xADDF 0xE158 # 0 +0xADE0 0xE159 # 0 +0xADE1 0xE15A # 0 +0xADE2 0xE15B # 0 +0xADE3 0xE15C # 0 +0xADE4 0xE15D # 0 +0xADE5 0xE15E # 0 +0xADE6 0xE15F # 0 +0xADE7 0xE160 # 0 +0xADE8 0xE161 # 0 +0xADE9 0xE162 # 0 +0xADEA 0xE163 # 0 +0xADEB 0xE164 # 0 +0xADEC 0xE165 # 0 +0xADED 0xE166 # 0 +0xADEE 0xE167 # 0 +0xADEF 0xE168 # 0 +0xADF0 0xE169 # 0 +0xADF1 0xE16A # 0 +0xADF2 0xE16B # 0 +0xADF3 0xE16C # 0 +0xADF4 0xE16D # 0 +0xADF5 0xE16E # 0 +0xADF6 0xE16F # 0 +0xADF7 0xE170 # 0 +0xADF8 0xE171 # 0 +0xADF9 0xE172 # 0 +0xADFA 0xE173 # 0 +0xADFB 0xE174 # 0 +0xADFC 0xE175 # 0 +0xADFD 0xE176 # 0 +0xADFE 0xE177 # 0 +0xAE40 0x74F3 # 0 +0xAE41 0x74F5 # 0 +0xAE42 0x74F8 # 0 +0xAE43 0x74F9 # 0 +0xAE44 0x74FA # 0 +0xAE45 0x74FB # 0 +0xAE46 0x74FC # 0 +0xAE47 0x74FD # 0 +0xAE48 0x74FE # 0 +0xAE49 0x7500 # 0 +0xAE4A 0x7501 # 0 +0xAE4B 0x7502 # 0 +0xAE4C 0x7503 # 0 +0xAE4D 0x7505 # 0 +0xAE4E 0x7506 # 0 +0xAE4F 0x7507 # 0 +0xAE50 0x7508 # 0 +0xAE51 0x7509 # 0 +0xAE52 0x750A # 0 +0xAE53 0x750B # 0 +0xAE54 0x750C # 0 +0xAE55 0x750E # 0 +0xAE56 0x7510 # 0 +0xAE57 0x7512 # 0 +0xAE58 0x7514 # 0 +0xAE59 0x7515 # 0 +0xAE5A 0x7516 # 0 +0xAE5B 0x7517 # 0 +0xAE5C 0x751B # 0 +0xAE5D 0x751D # 0 +0xAE5E 0x751E # 0 +0xAE5F 0x7520 # 0 +0xAE60 0x7521 # 0 +0xAE61 0x7522 # 0 +0xAE62 0x7523 # 0 +0xAE63 0x7524 # 0 +0xAE64 0x7526 # 0 +0xAE65 0x7527 # 0 +0xAE66 0x752A # 0 +0xAE67 0x752E # 0 +0xAE68 0x7534 # 0 +0xAE69 0x7536 # 0 +0xAE6A 0x7539 # 0 +0xAE6B 0x753C # 0 +0xAE6C 0x753D # 0 +0xAE6D 0x753F # 0 +0xAE6E 0x7541 # 0 +0xAE6F 0x7542 # 0 +0xAE70 0x7543 # 0 +0xAE71 0x7544 # 0 +0xAE72 0x7546 # 0 +0xAE73 0x7547 # 0 +0xAE74 0x7549 # 0 +0xAE75 0x754A # 0 +0xAE76 0x754D # 0 +0xAE77 0x7550 # 0 +0xAE78 0x7551 # 0 +0xAE79 0x7552 # 0 +0xAE7A 0x7553 # 0 +0xAE7B 0x7555 # 0 +0xAE7C 0x7556 # 0 +0xAE7D 0x7557 # 0 +0xAE7E 0x7558 # 0 +0xAE80 0x755D # 0 +0xAE81 0x755E # 0 +0xAE82 0x755F # 0 +0xAE83 0x7560 # 0 +0xAE84 0x7561 # 0 +0xAE85 0x7562 # 0 +0xAE86 0x7563 # 0 +0xAE87 0x7564 # 0 +0xAE88 0x7567 # 0 +0xAE89 0x7568 # 0 +0xAE8A 0x7569 # 0 +0xAE8B 0x756B # 0 +0xAE8C 0x756C # 0 +0xAE8D 0x756D # 0 +0xAE8E 0x756E # 0 +0xAE8F 0x756F # 0 +0xAE90 0x7570 # 0 +0xAE91 0x7571 # 0 +0xAE92 0x7573 # 0 +0xAE93 0x7575 # 0 +0xAE94 0x7576 # 0 +0xAE95 0x7577 # 0 +0xAE96 0x757A # 0 +0xAE97 0x757B # 0 +0xAE98 0x757C # 0 +0xAE99 0x757D # 0 +0xAE9A 0x757E # 0 +0xAE9B 0x7580 # 0 +0xAE9C 0x7581 # 0 +0xAE9D 0x7582 # 0 +0xAE9E 0x7584 # 0 +0xAE9F 0x7585 # 0 +0xAEA0 0x7587 # 0 +0xAEA1 0xE178 # 0 +0xAEA2 0xE179 # 0 +0xAEA3 0xE17A # 0 +0xAEA4 0xE17B # 0 +0xAEA5 0xE17C # 0 +0xAEA6 0xE17D # 0 +0xAEA7 0xE17E # 0 +0xAEA8 0xE17F # 0 +0xAEA9 0xE180 # 0 +0xAEAA 0xE181 # 0 +0xAEAB 0xE182 # 0 +0xAEAC 0xE183 # 0 +0xAEAD 0xE184 # 0 +0xAEAE 0xE185 # 0 +0xAEAF 0xE186 # 0 +0xAEB0 0xE187 # 0 +0xAEB1 0xE188 # 0 +0xAEB2 0xE189 # 0 +0xAEB3 0xE18A # 0 +0xAEB4 0xE18B # 0 +0xAEB5 0xE18C # 0 +0xAEB6 0xE18D # 0 +0xAEB7 0xE18E # 0 +0xAEB8 0xE18F # 0 +0xAEB9 0xE190 # 0 +0xAEBA 0xE191 # 0 +0xAEBB 0xE192 # 0 +0xAEBC 0xE193 # 0 +0xAEBD 0xE194 # 0 +0xAEBE 0xE195 # 0 +0xAEBF 0xE196 # 0 +0xAEC0 0xE197 # 0 +0xAEC1 0xE198 # 0 +0xAEC2 0xE199 # 0 +0xAEC3 0xE19A # 0 +0xAEC4 0xE19B # 0 +0xAEC5 0xE19C # 0 +0xAEC6 0xE19D # 0 +0xAEC7 0xE19E # 0 +0xAEC8 0xE19F # 0 +0xAEC9 0xE1A0 # 0 +0xAECA 0xE1A1 # 0 +0xAECB 0xE1A2 # 0 +0xAECC 0xE1A3 # 0 +0xAECD 0xE1A4 # 0 +0xAECE 0xE1A5 # 0 +0xAECF 0xE1A6 # 0 +0xAED0 0xE1A7 # 0 +0xAED1 0xE1A8 # 0 +0xAED2 0xE1A9 # 0 +0xAED3 0xE1AA # 0 +0xAED4 0xE1AB # 0 +0xAED5 0xE1AC # 0 +0xAED6 0xE1AD # 0 +0xAED7 0xE1AE # 0 +0xAED8 0xE1AF # 0 +0xAED9 0xE1B0 # 0 +0xAEDA 0xE1B1 # 0 +0xAEDB 0xE1B2 # 0 +0xAEDC 0xE1B3 # 0 +0xAEDD 0xE1B4 # 0 +0xAEDE 0xE1B5 # 0 +0xAEDF 0xE1B6 # 0 +0xAEE0 0xE1B7 # 0 +0xAEE1 0xE1B8 # 0 +0xAEE2 0xE1B9 # 0 +0xAEE3 0xE1BA # 0 +0xAEE4 0xE1BB # 0 +0xAEE5 0xE1BC # 0 +0xAEE6 0xE1BD # 0 +0xAEE7 0xE1BE # 0 +0xAEE8 0xE1BF # 0 +0xAEE9 0xE1C0 # 0 +0xAEEA 0xE1C1 # 0 +0xAEEB 0xE1C2 # 0 +0xAEEC 0xE1C3 # 0 +0xAEED 0xE1C4 # 0 +0xAEEE 0xE1C5 # 0 +0xAEEF 0xE1C6 # 0 +0xAEF0 0xE1C7 # 0 +0xAEF1 0xE1C8 # 0 +0xAEF2 0xE1C9 # 0 +0xAEF3 0xE1CA # 0 +0xAEF4 0xE1CB # 0 +0xAEF5 0xE1CC # 0 +0xAEF6 0xE1CD # 0 +0xAEF7 0xE1CE # 0 +0xAEF8 0xE1CF # 0 +0xAEF9 0xE1D0 # 0 +0xAEFA 0xE1D1 # 0 +0xAEFB 0xE1D2 # 0 +0xAEFC 0xE1D3 # 0 +0xAEFD 0xE1D4 # 0 +0xAEFE 0xE1D5 # 0 +0xAF40 0x7588 # 0 +0xAF41 0x7589 # 0 +0xAF42 0x758A # 0 +0xAF43 0x758C # 0 +0xAF44 0x758D # 0 +0xAF45 0x758E # 0 +0xAF46 0x7590 # 0 +0xAF47 0x7593 # 0 +0xAF48 0x7595 # 0 +0xAF49 0x7598 # 0 +0xAF4A 0x759B # 0 +0xAF4B 0x759C # 0 +0xAF4C 0x759E # 0 +0xAF4D 0x75A2 # 0 +0xAF4E 0x75A6 # 0 +0xAF4F 0x75A7 # 0 +0xAF50 0x75A8 # 0 +0xAF51 0x75A9 # 0 +0xAF52 0x75AA # 0 +0xAF53 0x75AD # 0 +0xAF54 0x75B6 # 0 +0xAF55 0x75B7 # 0 +0xAF56 0x75BA # 0 +0xAF57 0x75BB # 0 +0xAF58 0x75BF # 0 +0xAF59 0x75C0 # 0 +0xAF5A 0x75C1 # 0 +0xAF5B 0x75C6 # 0 +0xAF5C 0x75CB # 0 +0xAF5D 0x75CC # 0 +0xAF5E 0x75CE # 0 +0xAF5F 0x75CF # 0 +0xAF60 0x75D0 # 0 +0xAF61 0x75D1 # 0 +0xAF62 0x75D3 # 0 +0xAF63 0x75D7 # 0 +0xAF64 0x75D9 # 0 +0xAF65 0x75DA # 0 +0xAF66 0x75DC # 0 +0xAF67 0x75DD # 0 +0xAF68 0x75DF # 0 +0xAF69 0x75E0 # 0 +0xAF6A 0x75E1 # 0 +0xAF6B 0x75E5 # 0 +0xAF6C 0x75E9 # 0 +0xAF6D 0x75EC # 0 +0xAF6E 0x75ED # 0 +0xAF6F 0x75EE # 0 +0xAF70 0x75EF # 0 +0xAF71 0x75F2 # 0 +0xAF72 0x75F3 # 0 +0xAF73 0x75F5 # 0 +0xAF74 0x75F6 # 0 +0xAF75 0x75F7 # 0 +0xAF76 0x75F8 # 0 +0xAF77 0x75FA # 0 +0xAF78 0x75FB # 0 +0xAF79 0x75FD # 0 +0xAF7A 0x75FE # 0 +0xAF7B 0x7602 # 0 +0xAF7C 0x7604 # 0 +0xAF7D 0x7606 # 0 +0xAF7E 0x7607 # 0 +0xAF80 0x7608 # 0 +0xAF81 0x7609 # 0 +0xAF82 0x760B # 0 +0xAF83 0x760D # 0 +0xAF84 0x760E # 0 +0xAF85 0x760F # 0 +0xAF86 0x7611 # 0 +0xAF87 0x7612 # 0 +0xAF88 0x7613 # 0 +0xAF89 0x7614 # 0 +0xAF8A 0x7616 # 0 +0xAF8B 0x761A # 0 +0xAF8C 0x761C # 0 +0xAF8D 0x761D # 0 +0xAF8E 0x761E # 0 +0xAF8F 0x7621 # 0 +0xAF90 0x7623 # 0 +0xAF91 0x7627 # 0 +0xAF92 0x7628 # 0 +0xAF93 0x762C # 0 +0xAF94 0x762E # 0 +0xAF95 0x762F # 0 +0xAF96 0x7631 # 0 +0xAF97 0x7632 # 0 +0xAF98 0x7636 # 0 +0xAF99 0x7637 # 0 +0xAF9A 0x7639 # 0 +0xAF9B 0x763A # 0 +0xAF9C 0x763B # 0 +0xAF9D 0x763D # 0 +0xAF9E 0x7641 # 0 +0xAF9F 0x7642 # 0 +0xAFA0 0x7644 # 0 +0xAFA1 0xE1D6 # 0 +0xAFA2 0xE1D7 # 0 +0xAFA3 0xE1D8 # 0 +0xAFA4 0xE1D9 # 0 +0xAFA5 0xE1DA # 0 +0xAFA6 0xE1DB # 0 +0xAFA7 0xE1DC # 0 +0xAFA8 0xE1DD # 0 +0xAFA9 0xE1DE # 0 +0xAFAA 0xE1DF # 0 +0xAFAB 0xE1E0 # 0 +0xAFAC 0xE1E1 # 0 +0xAFAD 0xE1E2 # 0 +0xAFAE 0xE1E3 # 0 +0xAFAF 0xE1E4 # 0 +0xAFB0 0xE1E5 # 0 +0xAFB1 0xE1E6 # 0 +0xAFB2 0xE1E7 # 0 +0xAFB3 0xE1E8 # 0 +0xAFB4 0xE1E9 # 0 +0xAFB5 0xE1EA # 0 +0xAFB6 0xE1EB # 0 +0xAFB7 0xE1EC # 0 +0xAFB8 0xE1ED # 0 +0xAFB9 0xE1EE # 0 +0xAFBA 0xE1EF # 0 +0xAFBB 0xE1F0 # 0 +0xAFBC 0xE1F1 # 0 +0xAFBD 0xE1F2 # 0 +0xAFBE 0xE1F3 # 0 +0xAFBF 0xE1F4 # 0 +0xAFC0 0xE1F5 # 0 +0xAFC1 0xE1F6 # 0 +0xAFC2 0xE1F7 # 0 +0xAFC3 0xE1F8 # 0 +0xAFC4 0xE1F9 # 0 +0xAFC5 0xE1FA # 0 +0xAFC6 0xE1FB # 0 +0xAFC7 0xE1FC # 0 +0xAFC8 0xE1FD # 0 +0xAFC9 0xE1FE # 0 +0xAFCA 0xE1FF # 0 +0xAFCB 0xE200 # 0 +0xAFCC 0xE201 # 0 +0xAFCD 0xE202 # 0 +0xAFCE 0xE203 # 0 +0xAFCF 0xE204 # 0 +0xAFD0 0xE205 # 0 +0xAFD1 0xE206 # 0 +0xAFD2 0xE207 # 0 +0xAFD3 0xE208 # 0 +0xAFD4 0xE209 # 0 +0xAFD5 0xE20A # 0 +0xAFD6 0xE20B # 0 +0xAFD7 0xE20C # 0 +0xAFD8 0xE20D # 0 +0xAFD9 0xE20E # 0 +0xAFDA 0xE20F # 0 +0xAFDB 0xE210 # 0 +0xAFDC 0xE211 # 0 +0xAFDD 0xE212 # 0 +0xAFDE 0xE213 # 0 +0xAFDF 0xE214 # 0 +0xAFE0 0xE215 # 0 +0xAFE1 0xE216 # 0 +0xAFE2 0xE217 # 0 +0xAFE3 0xE218 # 0 +0xAFE4 0xE219 # 0 +0xAFE5 0xE21A # 0 +0xAFE6 0xE21B # 0 +0xAFE7 0xE21C # 0 +0xAFE8 0xE21D # 0 +0xAFE9 0xE21E # 0 +0xAFEA 0xE21F # 0 +0xAFEB 0xE220 # 0 +0xAFEC 0xE221 # 0 +0xAFED 0xE222 # 0 +0xAFEE 0xE223 # 0 +0xAFEF 0xE224 # 0 +0xAFF0 0xE225 # 0 +0xAFF1 0xE226 # 0 +0xAFF2 0xE227 # 0 +0xAFF3 0xE228 # 0 +0xAFF4 0xE229 # 0 +0xAFF5 0xE22A # 0 +0xAFF6 0xE22B # 0 +0xAFF7 0xE22C # 0 +0xAFF8 0xE22D # 0 +0xAFF9 0xE22E # 0 +0xAFFA 0xE22F # 0 +0xAFFB 0xE230 # 0 +0xAFFC 0xE231 # 0 +0xAFFD 0xE232 # 0 +0xAFFE 0xE233 # 0 +0xB040 0x7645 # 0 +0xB041 0x7646 # 0 +0xB042 0x7647 # 0 +0xB043 0x7648 # 0 +0xB044 0x7649 # 0 +0xB045 0x764A # 0 +0xB046 0x764B # 0 +0xB047 0x764E # 0 +0xB048 0x764F # 0 +0xB049 0x7650 # 0 +0xB04A 0x7651 # 0 +0xB04B 0x7652 # 0 +0xB04C 0x7653 # 0 +0xB04D 0x7655 # 0 +0xB04E 0x7657 # 0 +0xB04F 0x7658 # 0 +0xB050 0x7659 # 0 +0xB051 0x765A # 0 +0xB052 0x765B # 0 +0xB053 0x765D # 0 +0xB054 0x765F # 0 +0xB055 0x7660 # 0 +0xB056 0x7661 # 0 +0xB057 0x7662 # 0 +0xB058 0x7664 # 0 +0xB059 0x7665 # 0 +0xB05A 0x7666 # 0 +0xB05B 0x7667 # 0 +0xB05C 0x7668 # 0 +0xB05D 0x7669 # 0 +0xB05E 0x766A # 0 +0xB05F 0x766C # 0 +0xB060 0x766D # 0 +0xB061 0x766E # 0 +0xB062 0x7670 # 0 +0xB063 0x7671 # 0 +0xB064 0x7672 # 0 +0xB065 0x7673 # 0 +0xB066 0x7674 # 0 +0xB067 0x7675 # 0 +0xB068 0x7676 # 0 +0xB069 0x7677 # 0 +0xB06A 0x7679 # 0 +0xB06B 0x767A # 0 +0xB06C 0x767C # 0 +0xB06D 0x767F # 0 +0xB06E 0x7680 # 0 +0xB06F 0x7681 # 0 +0xB070 0x7683 # 0 +0xB071 0x7685 # 0 +0xB072 0x7689 # 0 +0xB073 0x768A # 0 +0xB074 0x768C # 0 +0xB075 0x768D # 0 +0xB076 0x768F # 0 +0xB077 0x7690 # 0 +0xB078 0x7692 # 0 +0xB079 0x7694 # 0 +0xB07A 0x7695 # 0 +0xB07B 0x7697 # 0 +0xB07C 0x7698 # 0 +0xB07D 0x769A # 0 +0xB07E 0x769B # 0 +0xB080 0x769C # 0 +0xB081 0x769D # 0 +0xB082 0x769E # 0 +0xB083 0x769F # 0 +0xB084 0x76A0 # 0 +0xB085 0x76A1 # 0 +0xB086 0x76A2 # 0 +0xB087 0x76A3 # 0 +0xB088 0x76A5 # 0 +0xB089 0x76A6 # 0 +0xB08A 0x76A7 # 0 +0xB08B 0x76A8 # 0 +0xB08C 0x76A9 # 0 +0xB08D 0x76AA # 0 +0xB08E 0x76AB # 0 +0xB08F 0x76AC # 0 +0xB090 0x76AD # 0 +0xB091 0x76AF # 0 +0xB092 0x76B0 # 0 +0xB093 0x76B3 # 0 +0xB094 0x76B5 # 0 +0xB095 0x76B6 # 0 +0xB096 0x76B7 # 0 +0xB097 0x76B8 # 0 +0xB098 0x76B9 # 0 +0xB099 0x76BA # 0 +0xB09A 0x76BB # 0 +0xB09B 0x76BC # 0 +0xB09C 0x76BD # 0 +0xB09D 0x76BE # 0 +0xB09E 0x76C0 # 0 +0xB09F 0x76C1 # 0 +0xB0A0 0x76C3 # 0 +0xB0A1 0x554A # 0 +0xB0A2 0x963F # 0 +0xB0A3 0x57C3 # 0 +0xB0A4 0x6328 # 0 +0xB0A5 0x54CE # 0 +0xB0A6 0x5509 # 0 +0xB0A7 0x54C0 # 0 +0xB0A8 0x7691 # 0 +0xB0A9 0x764C # 0 +0xB0AA 0x853C # 0 +0xB0AB 0x77EE # 0 +0xB0AC 0x827E # 0 +0xB0AD 0x788D # 0 +0xB0AE 0x7231 # 0 +0xB0AF 0x9698 # 0 +0xB0B0 0x978D # 0 +0xB0B1 0x6C28 # 0 +0xB0B2 0x5B89 # 0 +0xB0B3 0x4FFA # 0 +0xB0B4 0x6309 # 0 +0xB0B5 0x6697 # 0 +0xB0B6 0x5CB8 # 0 +0xB0B7 0x80FA # 0 +0xB0B8 0x6848 # 0 +0xB0B9 0x80AE # 0 +0xB0BA 0x6602 # 0 +0xB0BB 0x76CE # 0 +0xB0BC 0x51F9 # 0 +0xB0BD 0x6556 # 0 +0xB0BE 0x71AC # 0 +0xB0BF 0x7FF1 # 0 +0xB0C0 0x8884 # 0 +0xB0C1 0x50B2 # 0 +0xB0C2 0x5965 # 0 +0xB0C3 0x61CA # 0 +0xB0C4 0x6FB3 # 0 +0xB0C5 0x82AD # 0 +0xB0C6 0x634C # 0 +0xB0C7 0x6252 # 0 +0xB0C8 0x53ED # 0 +0xB0C9 0x5427 # 0 +0xB0CA 0x7B06 # 0 +0xB0CB 0x516B # 0 +0xB0CC 0x75A4 # 0 +0xB0CD 0x5DF4 # 0 +0xB0CE 0x62D4 # 0 +0xB0CF 0x8DCB # 0 +0xB0D0 0x9776 # 0 +0xB0D1 0x628A # 0 +0xB0D2 0x8019 # 0 +0xB0D3 0x575D # 0 +0xB0D4 0x9738 # 0 +0xB0D5 0x7F62 # 0 +0xB0D6 0x7238 # 0 +0xB0D7 0x767D # 0 +0xB0D8 0x67CF # 0 +0xB0D9 0x767E # 0 +0xB0DA 0x6446 # 0 +0xB0DB 0x4F70 # 0 +0xB0DC 0x8D25 # 0 +0xB0DD 0x62DC # 0 +0xB0DE 0x7A17 # 0 +0xB0DF 0x6591 # 0 +0xB0E0 0x73ED # 0 +0xB0E1 0x642C # 0 +0xB0E2 0x6273 # 0 +0xB0E3 0x822C # 0 +0xB0E4 0x9881 # 0 +0xB0E5 0x677F # 0 +0xB0E6 0x7248 # 0 +0xB0E7 0x626E # 0 +0xB0E8 0x62CC # 0 +0xB0E9 0x4F34 # 0 +0xB0EA 0x74E3 # 0 +0xB0EB 0x534A # 0 +0xB0EC 0x529E # 0 +0xB0ED 0x7ECA # 0 +0xB0EE 0x90A6 # 0 +0xB0EF 0x5E2E # 0 +0xB0F0 0x6886 # 0 +0xB0F1 0x699C # 0 +0xB0F2 0x8180 # 0 +0xB0F3 0x7ED1 # 0 +0xB0F4 0x68D2 # 0 +0xB0F5 0x78C5 # 0 +0xB0F6 0x868C # 0 +0xB0F7 0x9551 # 0 +0xB0F8 0x508D # 0 +0xB0F9 0x8C24 # 0 +0xB0FA 0x82DE # 0 +0xB0FB 0x80DE # 0 +0xB0FC 0x5305 # 0 +0xB0FD 0x8912 # 0 +0xB0FE 0x5265 # 0 +0xB140 0x76C4 # 0 +0xB141 0x76C7 # 0 +0xB142 0x76C9 # 0 +0xB143 0x76CB # 0 +0xB144 0x76CC # 0 +0xB145 0x76D3 # 0 +0xB146 0x76D5 # 0 +0xB147 0x76D9 # 0 +0xB148 0x76DA # 0 +0xB149 0x76DC # 0 +0xB14A 0x76DD # 0 +0xB14B 0x76DE # 0 +0xB14C 0x76E0 # 0 +0xB14D 0x76E1 # 0 +0xB14E 0x76E2 # 0 +0xB14F 0x76E3 # 0 +0xB150 0x76E4 # 0 +0xB151 0x76E6 # 0 +0xB152 0x76E7 # 0 +0xB153 0x76E8 # 0 +0xB154 0x76E9 # 0 +0xB155 0x76EA # 0 +0xB156 0x76EB # 0 +0xB157 0x76EC # 0 +0xB158 0x76ED # 0 +0xB159 0x76F0 # 0 +0xB15A 0x76F3 # 0 +0xB15B 0x76F5 # 0 +0xB15C 0x76F6 # 0 +0xB15D 0x76F7 # 0 +0xB15E 0x76FA # 0 +0xB15F 0x76FB # 0 +0xB160 0x76FD # 0 +0xB161 0x76FF # 0 +0xB162 0x7700 # 0 +0xB163 0x7702 # 0 +0xB164 0x7703 # 0 +0xB165 0x7705 # 0 +0xB166 0x7706 # 0 +0xB167 0x770A # 0 +0xB168 0x770C # 0 +0xB169 0x770E # 0 +0xB16A 0x770F # 0 +0xB16B 0x7710 # 0 +0xB16C 0x7711 # 0 +0xB16D 0x7712 # 0 +0xB16E 0x7713 # 0 +0xB16F 0x7714 # 0 +0xB170 0x7715 # 0 +0xB171 0x7716 # 0 +0xB172 0x7717 # 0 +0xB173 0x7718 # 0 +0xB174 0x771B # 0 +0xB175 0x771C # 0 +0xB176 0x771D # 0 +0xB177 0x771E # 0 +0xB178 0x7721 # 0 +0xB179 0x7723 # 0 +0xB17A 0x7724 # 0 +0xB17B 0x7725 # 0 +0xB17C 0x7727 # 0 +0xB17D 0x772A # 0 +0xB17E 0x772B # 0 +0xB180 0x772C # 0 +0xB181 0x772E # 0 +0xB182 0x7730 # 0 +0xB183 0x7731 # 0 +0xB184 0x7732 # 0 +0xB185 0x7733 # 0 +0xB186 0x7734 # 0 +0xB187 0x7739 # 0 +0xB188 0x773B # 0 +0xB189 0x773D # 0 +0xB18A 0x773E # 0 +0xB18B 0x773F # 0 +0xB18C 0x7742 # 0 +0xB18D 0x7744 # 0 +0xB18E 0x7745 # 0 +0xB18F 0x7746 # 0 +0xB190 0x7748 # 0 +0xB191 0x7749 # 0 +0xB192 0x774A # 0 +0xB193 0x774B # 0 +0xB194 0x774C # 0 +0xB195 0x774D # 0 +0xB196 0x774E # 0 +0xB197 0x774F # 0 +0xB198 0x7752 # 0 +0xB199 0x7753 # 0 +0xB19A 0x7754 # 0 +0xB19B 0x7755 # 0 +0xB19C 0x7756 # 0 +0xB19D 0x7757 # 0 +0xB19E 0x7758 # 0 +0xB19F 0x7759 # 0 +0xB1A0 0x775C # 0 +0xB1A1 0x8584 # 0 +0xB1A2 0x96F9 # 0 +0xB1A3 0x4FDD # 0 +0xB1A4 0x5821 # 0 +0xB1A5 0x9971 # 0 +0xB1A6 0x5B9D # 0 +0xB1A7 0x62B1 # 0 +0xB1A8 0x62A5 # 0 +0xB1A9 0x66B4 # 0 +0xB1AA 0x8C79 # 0 +0xB1AB 0x9C8D # 0 +0xB1AC 0x7206 # 0 +0xB1AD 0x676F # 0 +0xB1AE 0x7891 # 0 +0xB1AF 0x60B2 # 0 +0xB1B0 0x5351 # 0 +0xB1B1 0x5317 # 0 +0xB1B2 0x8F88 # 0 +0xB1B3 0x80CC # 0 +0xB1B4 0x8D1D # 0 +0xB1B5 0x94A1 # 0 +0xB1B6 0x500D # 0 +0xB1B7 0x72C8 # 0 +0xB1B8 0x5907 # 0 +0xB1B9 0x60EB # 0 +0xB1BA 0x7119 # 0 +0xB1BB 0x88AB # 0 +0xB1BC 0x5954 # 0 +0xB1BD 0x82EF # 0 +0xB1BE 0x672C # 0 +0xB1BF 0x7B28 # 0 +0xB1C0 0x5D29 # 0 +0xB1C1 0x7EF7 # 0 +0xB1C2 0x752D # 0 +0xB1C3 0x6CF5 # 0 +0xB1C4 0x8E66 # 0 +0xB1C5 0x8FF8 # 0 +0xB1C6 0x903C # 0 +0xB1C7 0x9F3B # 0 +0xB1C8 0x6BD4 # 0 +0xB1C9 0x9119 # 0 +0xB1CA 0x7B14 # 0 +0xB1CB 0x5F7C # 0 +0xB1CC 0x78A7 # 0 +0xB1CD 0x84D6 # 0 +0xB1CE 0x853D # 0 +0xB1CF 0x6BD5 # 0 +0xB1D0 0x6BD9 # 0 +0xB1D1 0x6BD6 # 0 +0xB1D2 0x5E01 # 0 +0xB1D3 0x5E87 # 0 +0xB1D4 0x75F9 # 0 +0xB1D5 0x95ED # 0 +0xB1D6 0x655D # 0 +0xB1D7 0x5F0A # 0 +0xB1D8 0x5FC5 # 0 +0xB1D9 0x8F9F # 0 +0xB1DA 0x58C1 # 0 +0xB1DB 0x81C2 # 0 +0xB1DC 0x907F # 0 +0xB1DD 0x965B # 0 +0xB1DE 0x97AD # 0 +0xB1DF 0x8FB9 # 0 +0xB1E0 0x7F16 # 0 +0xB1E1 0x8D2C # 0 +0xB1E2 0x6241 # 0 +0xB1E3 0x4FBF # 0 +0xB1E4 0x53D8 # 0 +0xB1E5 0x535E # 0 +0xB1E6 0x8FA8 # 0 +0xB1E7 0x8FA9 # 0 +0xB1E8 0x8FAB # 0 +0xB1E9 0x904D # 0 +0xB1EA 0x6807 # 0 +0xB1EB 0x5F6A # 0 +0xB1EC 0x8198 # 0 +0xB1ED 0x8868 # 0 +0xB1EE 0x9CD6 # 0 +0xB1EF 0x618B # 0 +0xB1F0 0x522B # 0 +0xB1F1 0x762A # 0 +0xB1F2 0x5F6C # 0 +0xB1F3 0x658C # 0 +0xB1F4 0x6FD2 # 0 +0xB1F5 0x6EE8 # 0 +0xB1F6 0x5BBE # 0 +0xB1F7 0x6448 # 0 +0xB1F8 0x5175 # 0 +0xB1F9 0x51B0 # 0 +0xB1FA 0x67C4 # 0 +0xB1FB 0x4E19 # 0 +0xB1FC 0x79C9 # 0 +0xB1FD 0x997C # 0 +0xB1FE 0x70B3 # 0 +0xB240 0x775D # 0 +0xB241 0x775E # 0 +0xB242 0x775F # 0 +0xB243 0x7760 # 0 +0xB244 0x7764 # 0 +0xB245 0x7767 # 0 +0xB246 0x7769 # 0 +0xB247 0x776A # 0 +0xB248 0x776D # 0 +0xB249 0x776E # 0 +0xB24A 0x776F # 0 +0xB24B 0x7770 # 0 +0xB24C 0x7771 # 0 +0xB24D 0x7772 # 0 +0xB24E 0x7773 # 0 +0xB24F 0x7774 # 0 +0xB250 0x7775 # 0 +0xB251 0x7776 # 0 +0xB252 0x7777 # 0 +0xB253 0x7778 # 0 +0xB254 0x777A # 0 +0xB255 0x777B # 0 +0xB256 0x777C # 0 +0xB257 0x7781 # 0 +0xB258 0x7782 # 0 +0xB259 0x7783 # 0 +0xB25A 0x7786 # 0 +0xB25B 0x7787 # 0 +0xB25C 0x7788 # 0 +0xB25D 0x7789 # 0 +0xB25E 0x778A # 0 +0xB25F 0x778B # 0 +0xB260 0x778F # 0 +0xB261 0x7790 # 0 +0xB262 0x7793 # 0 +0xB263 0x7794 # 0 +0xB264 0x7795 # 0 +0xB265 0x7796 # 0 +0xB266 0x7797 # 0 +0xB267 0x7798 # 0 +0xB268 0x7799 # 0 +0xB269 0x779A # 0 +0xB26A 0x779B # 0 +0xB26B 0x779C # 0 +0xB26C 0x779D # 0 +0xB26D 0x779E # 0 +0xB26E 0x77A1 # 0 +0xB26F 0x77A3 # 0 +0xB270 0x77A4 # 0 +0xB271 0x77A6 # 0 +0xB272 0x77A8 # 0 +0xB273 0x77AB # 0 +0xB274 0x77AD # 0 +0xB275 0x77AE # 0 +0xB276 0x77AF # 0 +0xB277 0x77B1 # 0 +0xB278 0x77B2 # 0 +0xB279 0x77B4 # 0 +0xB27A 0x77B6 # 0 +0xB27B 0x77B7 # 0 +0xB27C 0x77B8 # 0 +0xB27D 0x77B9 # 0 +0xB27E 0x77BA # 0 +0xB280 0x77BC # 0 +0xB281 0x77BE # 0 +0xB282 0x77C0 # 0 +0xB283 0x77C1 # 0 +0xB284 0x77C2 # 0 +0xB285 0x77C3 # 0 +0xB286 0x77C4 # 0 +0xB287 0x77C5 # 0 +0xB288 0x77C6 # 0 +0xB289 0x77C7 # 0 +0xB28A 0x77C8 # 0 +0xB28B 0x77C9 # 0 +0xB28C 0x77CA # 0 +0xB28D 0x77CB # 0 +0xB28E 0x77CC # 0 +0xB28F 0x77CE # 0 +0xB290 0x77CF # 0 +0xB291 0x77D0 # 0 +0xB292 0x77D1 # 0 +0xB293 0x77D2 # 0 +0xB294 0x77D3 # 0 +0xB295 0x77D4 # 0 +0xB296 0x77D5 # 0 +0xB297 0x77D6 # 0 +0xB298 0x77D8 # 0 +0xB299 0x77D9 # 0 +0xB29A 0x77DA # 0 +0xB29B 0x77DD # 0 +0xB29C 0x77DE # 0 +0xB29D 0x77DF # 0 +0xB29E 0x77E0 # 0 +0xB29F 0x77E1 # 0 +0xB2A0 0x77E4 # 0 +0xB2A1 0x75C5 # 0 +0xB2A2 0x5E76 # 0 +0xB2A3 0x73BB # 0 +0xB2A4 0x83E0 # 0 +0xB2A5 0x64AD # 0 +0xB2A6 0x62E8 # 0 +0xB2A7 0x94B5 # 0 +0xB2A8 0x6CE2 # 0 +0xB2A9 0x535A # 0 +0xB2AA 0x52C3 # 0 +0xB2AB 0x640F # 0 +0xB2AC 0x94C2 # 0 +0xB2AD 0x7B94 # 0 +0xB2AE 0x4F2F # 0 +0xB2AF 0x5E1B # 0 +0xB2B0 0x8236 # 0 +0xB2B1 0x8116 # 0 +0xB2B2 0x818A # 0 +0xB2B3 0x6E24 # 0 +0xB2B4 0x6CCA # 0 +0xB2B5 0x9A73 # 0 +0xB2B6 0x6355 # 0 +0xB2B7 0x535C # 0 +0xB2B8 0x54FA # 0 +0xB2B9 0x8865 # 0 +0xB2BA 0x57E0 # 0 +0xB2BB 0x4E0D # 0 +0xB2BC 0x5E03 # 0 +0xB2BD 0x6B65 # 0 +0xB2BE 0x7C3F # 0 +0xB2BF 0x90E8 # 0 +0xB2C0 0x6016 # 0 +0xB2C1 0x64E6 # 0 +0xB2C2 0x731C # 0 +0xB2C3 0x88C1 # 0 +0xB2C4 0x6750 # 0 +0xB2C5 0x624D # 0 +0xB2C6 0x8D22 # 0 +0xB2C7 0x776C # 0 +0xB2C8 0x8E29 # 0 +0xB2C9 0x91C7 # 0 +0xB2CA 0x5F69 # 0 +0xB2CB 0x83DC # 0 +0xB2CC 0x8521 # 0 +0xB2CD 0x9910 # 0 +0xB2CE 0x53C2 # 0 +0xB2CF 0x8695 # 0 +0xB2D0 0x6B8B # 0 +0xB2D1 0x60ED # 0 +0xB2D2 0x60E8 # 0 +0xB2D3 0x707F # 0 +0xB2D4 0x82CD # 0 +0xB2D5 0x8231 # 0 +0xB2D6 0x4ED3 # 0 +0xB2D7 0x6CA7 # 0 +0xB2D8 0x85CF # 0 +0xB2D9 0x64CD # 0 +0xB2DA 0x7CD9 # 0 +0xB2DB 0x69FD # 0 +0xB2DC 0x66F9 # 0 +0xB2DD 0x8349 # 0 +0xB2DE 0x5395 # 0 +0xB2DF 0x7B56 # 0 +0xB2E0 0x4FA7 # 0 +0xB2E1 0x518C # 0 +0xB2E2 0x6D4B # 0 +0xB2E3 0x5C42 # 0 +0xB2E4 0x8E6D # 0 +0xB2E5 0x63D2 # 0 +0xB2E6 0x53C9 # 0 +0xB2E7 0x832C # 0 +0xB2E8 0x8336 # 0 +0xB2E9 0x67E5 # 0 +0xB2EA 0x78B4 # 0 +0xB2EB 0x643D # 0 +0xB2EC 0x5BDF # 0 +0xB2ED 0x5C94 # 0 +0xB2EE 0x5DEE # 0 +0xB2EF 0x8BE7 # 0 +0xB2F0 0x62C6 # 0 +0xB2F1 0x67F4 # 0 +0xB2F2 0x8C7A # 0 +0xB2F3 0x6400 # 0 +0xB2F4 0x63BA # 0 +0xB2F5 0x8749 # 0 +0xB2F6 0x998B # 0 +0xB2F7 0x8C17 # 0 +0xB2F8 0x7F20 # 0 +0xB2F9 0x94F2 # 0 +0xB2FA 0x4EA7 # 0 +0xB2FB 0x9610 # 0 +0xB2FC 0x98A4 # 0 +0xB2FD 0x660C # 0 +0xB2FE 0x7316 # 0 +0xB340 0x77E6 # 0 +0xB341 0x77E8 # 0 +0xB342 0x77EA # 0 +0xB343 0x77EF # 0 +0xB344 0x77F0 # 0 +0xB345 0x77F1 # 0 +0xB346 0x77F2 # 0 +0xB347 0x77F4 # 0 +0xB348 0x77F5 # 0 +0xB349 0x77F7 # 0 +0xB34A 0x77F9 # 0 +0xB34B 0x77FA # 0 +0xB34C 0x77FB # 0 +0xB34D 0x77FC # 0 +0xB34E 0x7803 # 0 +0xB34F 0x7804 # 0 +0xB350 0x7805 # 0 +0xB351 0x7806 # 0 +0xB352 0x7807 # 0 +0xB353 0x7808 # 0 +0xB354 0x780A # 0 +0xB355 0x780B # 0 +0xB356 0x780E # 0 +0xB357 0x780F # 0 +0xB358 0x7810 # 0 +0xB359 0x7813 # 0 +0xB35A 0x7815 # 0 +0xB35B 0x7819 # 0 +0xB35C 0x781B # 0 +0xB35D 0x781E # 0 +0xB35E 0x7820 # 0 +0xB35F 0x7821 # 0 +0xB360 0x7822 # 0 +0xB361 0x7824 # 0 +0xB362 0x7828 # 0 +0xB363 0x782A # 0 +0xB364 0x782B # 0 +0xB365 0x782E # 0 +0xB366 0x782F # 0 +0xB367 0x7831 # 0 +0xB368 0x7832 # 0 +0xB369 0x7833 # 0 +0xB36A 0x7835 # 0 +0xB36B 0x7836 # 0 +0xB36C 0x783D # 0 +0xB36D 0x783F # 0 +0xB36E 0x7841 # 0 +0xB36F 0x7842 # 0 +0xB370 0x7843 # 0 +0xB371 0x7844 # 0 +0xB372 0x7846 # 0 +0xB373 0x7848 # 0 +0xB374 0x7849 # 0 +0xB375 0x784A # 0 +0xB376 0x784B # 0 +0xB377 0x784D # 0 +0xB378 0x784F # 0 +0xB379 0x7851 # 0 +0xB37A 0x7853 # 0 +0xB37B 0x7854 # 0 +0xB37C 0x7858 # 0 +0xB37D 0x7859 # 0 +0xB37E 0x785A # 0 +0xB380 0x785B # 0 +0xB381 0x785C # 0 +0xB382 0x785E # 0 +0xB383 0x785F # 0 +0xB384 0x7860 # 0 +0xB385 0x7861 # 0 +0xB386 0x7862 # 0 +0xB387 0x7863 # 0 +0xB388 0x7864 # 0 +0xB389 0x7865 # 0 +0xB38A 0x7866 # 0 +0xB38B 0x7867 # 0 +0xB38C 0x7868 # 0 +0xB38D 0x7869 # 0 +0xB38E 0x786F # 0 +0xB38F 0x7870 # 0 +0xB390 0x7871 # 0 +0xB391 0x7872 # 0 +0xB392 0x7873 # 0 +0xB393 0x7874 # 0 +0xB394 0x7875 # 0 +0xB395 0x7876 # 0 +0xB396 0x7878 # 0 +0xB397 0x7879 # 0 +0xB398 0x787A # 0 +0xB399 0x787B # 0 +0xB39A 0x787D # 0 +0xB39B 0x787E # 0 +0xB39C 0x787F # 0 +0xB39D 0x7880 # 0 +0xB39E 0x7881 # 0 +0xB39F 0x7882 # 0 +0xB3A0 0x7883 # 0 +0xB3A1 0x573A # 0 +0xB3A2 0x5C1D # 0 +0xB3A3 0x5E38 # 0 +0xB3A4 0x957F # 0 +0xB3A5 0x507F # 0 +0xB3A6 0x80A0 # 0 +0xB3A7 0x5382 # 0 +0xB3A8 0x655E # 0 +0xB3A9 0x7545 # 0 +0xB3AA 0x5531 # 0 +0xB3AB 0x5021 # 0 +0xB3AC 0x8D85 # 0 +0xB3AD 0x6284 # 0 +0xB3AE 0x949E # 0 +0xB3AF 0x671D # 0 +0xB3B0 0x5632 # 0 +0xB3B1 0x6F6E # 0 +0xB3B2 0x5DE2 # 0 +0xB3B3 0x5435 # 0 +0xB3B4 0x7092 # 0 +0xB3B5 0x8F66 # 0 +0xB3B6 0x626F # 0 +0xB3B7 0x64A4 # 0 +0xB3B8 0x63A3 # 0 +0xB3B9 0x5F7B # 0 +0xB3BA 0x6F88 # 0 +0xB3BB 0x90F4 # 0 +0xB3BC 0x81E3 # 0 +0xB3BD 0x8FB0 # 0 +0xB3BE 0x5C18 # 0 +0xB3BF 0x6668 # 0 +0xB3C0 0x5FF1 # 0 +0xB3C1 0x6C89 # 0 +0xB3C2 0x9648 # 0 +0xB3C3 0x8D81 # 0 +0xB3C4 0x886C # 0 +0xB3C5 0x6491 # 0 +0xB3C6 0x79F0 # 0 +0xB3C7 0x57CE # 0 +0xB3C8 0x6A59 # 0 +0xB3C9 0x6210 # 0 +0xB3CA 0x5448 # 0 +0xB3CB 0x4E58 # 0 +0xB3CC 0x7A0B # 0 +0xB3CD 0x60E9 # 0 +0xB3CE 0x6F84 # 0 +0xB3CF 0x8BDA # 0 +0xB3D0 0x627F # 0 +0xB3D1 0x901E # 0 +0xB3D2 0x9A8B # 0 +0xB3D3 0x79E4 # 0 +0xB3D4 0x5403 # 0 +0xB3D5 0x75F4 # 0 +0xB3D6 0x6301 # 0 +0xB3D7 0x5319 # 0 +0xB3D8 0x6C60 # 0 +0xB3D9 0x8FDF # 0 +0xB3DA 0x5F1B # 0 +0xB3DB 0x9A70 # 0 +0xB3DC 0x803B # 0 +0xB3DD 0x9F7F # 0 +0xB3DE 0x4F88 # 0 +0xB3DF 0x5C3A # 0 +0xB3E0 0x8D64 # 0 +0xB3E1 0x7FC5 # 0 +0xB3E2 0x65A5 # 0 +0xB3E3 0x70BD # 0 +0xB3E4 0x5145 # 0 +0xB3E5 0x51B2 # 0 +0xB3E6 0x866B # 0 +0xB3E7 0x5D07 # 0 +0xB3E8 0x5BA0 # 0 +0xB3E9 0x62BD # 0 +0xB3EA 0x916C # 0 +0xB3EB 0x7574 # 0 +0xB3EC 0x8E0C # 0 +0xB3ED 0x7A20 # 0 +0xB3EE 0x6101 # 0 +0xB3EF 0x7B79 # 0 +0xB3F0 0x4EC7 # 0 +0xB3F1 0x7EF8 # 0 +0xB3F2 0x7785 # 0 +0xB3F3 0x4E11 # 0 +0xB3F4 0x81ED # 0 +0xB3F5 0x521D # 0 +0xB3F6 0x51FA # 0 +0xB3F7 0x6A71 # 0 +0xB3F8 0x53A8 # 0 +0xB3F9 0x8E87 # 0 +0xB3FA 0x9504 # 0 +0xB3FB 0x96CF # 0 +0xB3FC 0x6EC1 # 0 +0xB3FD 0x9664 # 0 +0xB3FE 0x695A # 0 +0xB440 0x7884 # 0 +0xB441 0x7885 # 0 +0xB442 0x7886 # 0 +0xB443 0x7888 # 0 +0xB444 0x788A # 0 +0xB445 0x788B # 0 +0xB446 0x788F # 0 +0xB447 0x7890 # 0 +0xB448 0x7892 # 0 +0xB449 0x7894 # 0 +0xB44A 0x7895 # 0 +0xB44B 0x7896 # 0 +0xB44C 0x7899 # 0 +0xB44D 0x789D # 0 +0xB44E 0x789E # 0 +0xB44F 0x78A0 # 0 +0xB450 0x78A2 # 0 +0xB451 0x78A4 # 0 +0xB452 0x78A6 # 0 +0xB453 0x78A8 # 0 +0xB454 0x78A9 # 0 +0xB455 0x78AA # 0 +0xB456 0x78AB # 0 +0xB457 0x78AC # 0 +0xB458 0x78AD # 0 +0xB459 0x78AE # 0 +0xB45A 0x78AF # 0 +0xB45B 0x78B5 # 0 +0xB45C 0x78B6 # 0 +0xB45D 0x78B7 # 0 +0xB45E 0x78B8 # 0 +0xB45F 0x78BA # 0 +0xB460 0x78BB # 0 +0xB461 0x78BC # 0 +0xB462 0x78BD # 0 +0xB463 0x78BF # 0 +0xB464 0x78C0 # 0 +0xB465 0x78C2 # 0 +0xB466 0x78C3 # 0 +0xB467 0x78C4 # 0 +0xB468 0x78C6 # 0 +0xB469 0x78C7 # 0 +0xB46A 0x78C8 # 0 +0xB46B 0x78CC # 0 +0xB46C 0x78CD # 0 +0xB46D 0x78CE # 0 +0xB46E 0x78CF # 0 +0xB46F 0x78D1 # 0 +0xB470 0x78D2 # 0 +0xB471 0x78D3 # 0 +0xB472 0x78D6 # 0 +0xB473 0x78D7 # 0 +0xB474 0x78D8 # 0 +0xB475 0x78DA # 0 +0xB476 0x78DB # 0 +0xB477 0x78DC # 0 +0xB478 0x78DD # 0 +0xB479 0x78DE # 0 +0xB47A 0x78DF # 0 +0xB47B 0x78E0 # 0 +0xB47C 0x78E1 # 0 +0xB47D 0x78E2 # 0 +0xB47E 0x78E3 # 0 +0xB480 0x78E4 # 0 +0xB481 0x78E5 # 0 +0xB482 0x78E6 # 0 +0xB483 0x78E7 # 0 +0xB484 0x78E9 # 0 +0xB485 0x78EA # 0 +0xB486 0x78EB # 0 +0xB487 0x78ED # 0 +0xB488 0x78EE # 0 +0xB489 0x78EF # 0 +0xB48A 0x78F0 # 0 +0xB48B 0x78F1 # 0 +0xB48C 0x78F3 # 0 +0xB48D 0x78F5 # 0 +0xB48E 0x78F6 # 0 +0xB48F 0x78F8 # 0 +0xB490 0x78F9 # 0 +0xB491 0x78FB # 0 +0xB492 0x78FC # 0 +0xB493 0x78FD # 0 +0xB494 0x78FE # 0 +0xB495 0x78FF # 0 +0xB496 0x7900 # 0 +0xB497 0x7902 # 0 +0xB498 0x7903 # 0 +0xB499 0x7904 # 0 +0xB49A 0x7906 # 0 +0xB49B 0x7907 # 0 +0xB49C 0x7908 # 0 +0xB49D 0x7909 # 0 +0xB49E 0x790A # 0 +0xB49F 0x790B # 0 +0xB4A0 0x790C # 0 +0xB4A1 0x7840 # 0 +0xB4A2 0x50A8 # 0 +0xB4A3 0x77D7 # 0 +0xB4A4 0x6410 # 0 +0xB4A5 0x89E6 # 0 +0xB4A6 0x5904 # 0 +0xB4A7 0x63E3 # 0 +0xB4A8 0x5DDD # 0 +0xB4A9 0x7A7F # 0 +0xB4AA 0x693D # 0 +0xB4AB 0x4F20 # 0 +0xB4AC 0x8239 # 0 +0xB4AD 0x5598 # 0 +0xB4AE 0x4E32 # 0 +0xB4AF 0x75AE # 0 +0xB4B0 0x7A97 # 0 +0xB4B1 0x5E62 # 0 +0xB4B2 0x5E8A # 0 +0xB4B3 0x95EF # 0 +0xB4B4 0x521B # 0 +0xB4B5 0x5439 # 0 +0xB4B6 0x708A # 0 +0xB4B7 0x6376 # 0 +0xB4B8 0x9524 # 0 +0xB4B9 0x5782 # 0 +0xB4BA 0x6625 # 0 +0xB4BB 0x693F # 0 +0xB4BC 0x9187 # 0 +0xB4BD 0x5507 # 0 +0xB4BE 0x6DF3 # 0 +0xB4BF 0x7EAF # 0 +0xB4C0 0x8822 # 0 +0xB4C1 0x6233 # 0 +0xB4C2 0x7EF0 # 0 +0xB4C3 0x75B5 # 0 +0xB4C4 0x8328 # 0 +0xB4C5 0x78C1 # 0 +0xB4C6 0x96CC # 0 +0xB4C7 0x8F9E # 0 +0xB4C8 0x6148 # 0 +0xB4C9 0x74F7 # 0 +0xB4CA 0x8BCD # 0 +0xB4CB 0x6B64 # 0 +0xB4CC 0x523A # 0 +0xB4CD 0x8D50 # 0 +0xB4CE 0x6B21 # 0 +0xB4CF 0x806A # 0 +0xB4D0 0x8471 # 0 +0xB4D1 0x56F1 # 0 +0xB4D2 0x5306 # 0 +0xB4D3 0x4ECE # 0 +0xB4D4 0x4E1B # 0 +0xB4D5 0x51D1 # 0 +0xB4D6 0x7C97 # 0 +0xB4D7 0x918B # 0 +0xB4D8 0x7C07 # 0 +0xB4D9 0x4FC3 # 0 +0xB4DA 0x8E7F # 0 +0xB4DB 0x7BE1 # 0 +0xB4DC 0x7A9C # 0 +0xB4DD 0x6467 # 0 +0xB4DE 0x5D14 # 0 +0xB4DF 0x50AC # 0 +0xB4E0 0x8106 # 0 +0xB4E1 0x7601 # 0 +0xB4E2 0x7CB9 # 0 +0xB4E3 0x6DEC # 0 +0xB4E4 0x7FE0 # 0 +0xB4E5 0x6751 # 0 +0xB4E6 0x5B58 # 0 +0xB4E7 0x5BF8 # 0 +0xB4E8 0x78CB # 0 +0xB4E9 0x64AE # 0 +0xB4EA 0x6413 # 0 +0xB4EB 0x63AA # 0 +0xB4EC 0x632B # 0 +0xB4ED 0x9519 # 0 +0xB4EE 0x642D # 0 +0xB4EF 0x8FBE # 0 +0xB4F0 0x7B54 # 0 +0xB4F1 0x7629 # 0 +0xB4F2 0x6253 # 0 +0xB4F3 0x5927 # 0 +0xB4F4 0x5446 # 0 +0xB4F5 0x6B79 # 0 +0xB4F6 0x50A3 # 0 +0xB4F7 0x6234 # 0 +0xB4F8 0x5E26 # 0 +0xB4F9 0x6B86 # 0 +0xB4FA 0x4EE3 # 0 +0xB4FB 0x8D37 # 0 +0xB4FC 0x888B # 0 +0xB4FD 0x5F85 # 0 +0xB4FE 0x902E # 0 +0xB540 0x790D # 0 +0xB541 0x790E # 0 +0xB542 0x790F # 0 +0xB543 0x7910 # 0 +0xB544 0x7911 # 0 +0xB545 0x7912 # 0 +0xB546 0x7914 # 0 +0xB547 0x7915 # 0 +0xB548 0x7916 # 0 +0xB549 0x7917 # 0 +0xB54A 0x7918 # 0 +0xB54B 0x7919 # 0 +0xB54C 0x791A # 0 +0xB54D 0x791B # 0 +0xB54E 0x791C # 0 +0xB54F 0x791D # 0 +0xB550 0x791F # 0 +0xB551 0x7920 # 0 +0xB552 0x7921 # 0 +0xB553 0x7922 # 0 +0xB554 0x7923 # 0 +0xB555 0x7925 # 0 +0xB556 0x7926 # 0 +0xB557 0x7927 # 0 +0xB558 0x7928 # 0 +0xB559 0x7929 # 0 +0xB55A 0x792A # 0 +0xB55B 0x792B # 0 +0xB55C 0x792C # 0 +0xB55D 0x792D # 0 +0xB55E 0x792E # 0 +0xB55F 0x792F # 0 +0xB560 0x7930 # 0 +0xB561 0x7931 # 0 +0xB562 0x7932 # 0 +0xB563 0x7933 # 0 +0xB564 0x7935 # 0 +0xB565 0x7936 # 0 +0xB566 0x7937 # 0 +0xB567 0x7938 # 0 +0xB568 0x7939 # 0 +0xB569 0x793D # 0 +0xB56A 0x793F # 0 +0xB56B 0x7942 # 0 +0xB56C 0x7943 # 0 +0xB56D 0x7944 # 0 +0xB56E 0x7945 # 0 +0xB56F 0x7947 # 0 +0xB570 0x794A # 0 +0xB571 0x794B # 0 +0xB572 0x794C # 0 +0xB573 0x794D # 0 +0xB574 0x794E # 0 +0xB575 0x794F # 0 +0xB576 0x7950 # 0 +0xB577 0x7951 # 0 +0xB578 0x7952 # 0 +0xB579 0x7954 # 0 +0xB57A 0x7955 # 0 +0xB57B 0x7958 # 0 +0xB57C 0x7959 # 0 +0xB57D 0x7961 # 0 +0xB57E 0x7963 # 0 +0xB580 0x7964 # 0 +0xB581 0x7966 # 0 +0xB582 0x7969 # 0 +0xB583 0x796A # 0 +0xB584 0x796B # 0 +0xB585 0x796C # 0 +0xB586 0x796E # 0 +0xB587 0x7970 # 0 +0xB588 0x7971 # 0 +0xB589 0x7972 # 0 +0xB58A 0x7973 # 0 +0xB58B 0x7974 # 0 +0xB58C 0x7975 # 0 +0xB58D 0x7976 # 0 +0xB58E 0x7979 # 0 +0xB58F 0x797B # 0 +0xB590 0x797C # 0 +0xB591 0x797D # 0 +0xB592 0x797E # 0 +0xB593 0x797F # 0 +0xB594 0x7982 # 0 +0xB595 0x7983 # 0 +0xB596 0x7986 # 0 +0xB597 0x7987 # 0 +0xB598 0x7988 # 0 +0xB599 0x7989 # 0 +0xB59A 0x798B # 0 +0xB59B 0x798C # 0 +0xB59C 0x798D # 0 +0xB59D 0x798E # 0 +0xB59E 0x7990 # 0 +0xB59F 0x7991 # 0 +0xB5A0 0x7992 # 0 +0xB5A1 0x6020 # 0 +0xB5A2 0x803D # 0 +0xB5A3 0x62C5 # 0 +0xB5A4 0x4E39 # 0 +0xB5A5 0x5355 # 0 +0xB5A6 0x90F8 # 0 +0xB5A7 0x63B8 # 0 +0xB5A8 0x80C6 # 0 +0xB5A9 0x65E6 # 0 +0xB5AA 0x6C2E # 0 +0xB5AB 0x4F46 # 0 +0xB5AC 0x60EE # 0 +0xB5AD 0x6DE1 # 0 +0xB5AE 0x8BDE # 0 +0xB5AF 0x5F39 # 0 +0xB5B0 0x86CB # 0 +0xB5B1 0x5F53 # 0 +0xB5B2 0x6321 # 0 +0xB5B3 0x515A # 0 +0xB5B4 0x8361 # 0 +0xB5B5 0x6863 # 0 +0xB5B6 0x5200 # 0 +0xB5B7 0x6363 # 0 +0xB5B8 0x8E48 # 0 +0xB5B9 0x5012 # 0 +0xB5BA 0x5C9B # 0 +0xB5BB 0x7977 # 0 +0xB5BC 0x5BFC # 0 +0xB5BD 0x5230 # 0 +0xB5BE 0x7A3B # 0 +0xB5BF 0x60BC # 0 +0xB5C0 0x9053 # 0 +0xB5C1 0x76D7 # 0 +0xB5C2 0x5FB7 # 0 +0xB5C3 0x5F97 # 0 +0xB5C4 0x7684 # 0 +0xB5C5 0x8E6C # 0 +0xB5C6 0x706F # 0 +0xB5C7 0x767B # 0 +0xB5C8 0x7B49 # 0 +0xB5C9 0x77AA # 0 +0xB5CA 0x51F3 # 0 +0xB5CB 0x9093 # 0 +0xB5CC 0x5824 # 0 +0xB5CD 0x4F4E # 0 +0xB5CE 0x6EF4 # 0 +0xB5CF 0x8FEA # 0 +0xB5D0 0x654C # 0 +0xB5D1 0x7B1B # 0 +0xB5D2 0x72C4 # 0 +0xB5D3 0x6DA4 # 0 +0xB5D4 0x7FDF # 0 +0xB5D5 0x5AE1 # 0 +0xB5D6 0x62B5 # 0 +0xB5D7 0x5E95 # 0 +0xB5D8 0x5730 # 0 +0xB5D9 0x8482 # 0 +0xB5DA 0x7B2C # 0 +0xB5DB 0x5E1D # 0 +0xB5DC 0x5F1F # 0 +0xB5DD 0x9012 # 0 +0xB5DE 0x7F14 # 0 +0xB5DF 0x98A0 # 0 +0xB5E0 0x6382 # 0 +0xB5E1 0x6EC7 # 0 +0xB5E2 0x7898 # 0 +0xB5E3 0x70B9 # 0 +0xB5E4 0x5178 # 0 +0xB5E5 0x975B # 0 +0xB5E6 0x57AB # 0 +0xB5E7 0x7535 # 0 +0xB5E8 0x4F43 # 0 +0xB5E9 0x7538 # 0 +0xB5EA 0x5E97 # 0 +0xB5EB 0x60E6 # 0 +0xB5EC 0x5960 # 0 +0xB5ED 0x6DC0 # 0 +0xB5EE 0x6BBF # 0 +0xB5EF 0x7889 # 0 +0xB5F0 0x53FC # 0 +0xB5F1 0x96D5 # 0 +0xB5F2 0x51CB # 0 +0xB5F3 0x5201 # 0 +0xB5F4 0x6389 # 0 +0xB5F5 0x540A # 0 +0xB5F6 0x9493 # 0 +0xB5F7 0x8C03 # 0 +0xB5F8 0x8DCC # 0 +0xB5F9 0x7239 # 0 +0xB5FA 0x789F # 0 +0xB5FB 0x8776 # 0 +0xB5FC 0x8FED # 0 +0xB5FD 0x8C0D # 0 +0xB5FE 0x53E0 # 0 +0xB640 0x7993 # 0 +0xB641 0x7994 # 0 +0xB642 0x7995 # 0 +0xB643 0x7996 # 0 +0xB644 0x7997 # 0 +0xB645 0x7998 # 0 +0xB646 0x7999 # 0 +0xB647 0x799B # 0 +0xB648 0x799C # 0 +0xB649 0x799D # 0 +0xB64A 0x799E # 0 +0xB64B 0x799F # 0 +0xB64C 0x79A0 # 0 +0xB64D 0x79A1 # 0 +0xB64E 0x79A2 # 0 +0xB64F 0x79A3 # 0 +0xB650 0x79A4 # 0 +0xB651 0x79A5 # 0 +0xB652 0x79A6 # 0 +0xB653 0x79A8 # 0 +0xB654 0x79A9 # 0 +0xB655 0x79AA # 0 +0xB656 0x79AB # 0 +0xB657 0x79AC # 0 +0xB658 0x79AD # 0 +0xB659 0x79AE # 0 +0xB65A 0x79AF # 0 +0xB65B 0x79B0 # 0 +0xB65C 0x79B1 # 0 +0xB65D 0x79B2 # 0 +0xB65E 0x79B4 # 0 +0xB65F 0x79B5 # 0 +0xB660 0x79B6 # 0 +0xB661 0x79B7 # 0 +0xB662 0x79B8 # 0 +0xB663 0x79BC # 0 +0xB664 0x79BF # 0 +0xB665 0x79C2 # 0 +0xB666 0x79C4 # 0 +0xB667 0x79C5 # 0 +0xB668 0x79C7 # 0 +0xB669 0x79C8 # 0 +0xB66A 0x79CA # 0 +0xB66B 0x79CC # 0 +0xB66C 0x79CE # 0 +0xB66D 0x79CF # 0 +0xB66E 0x79D0 # 0 +0xB66F 0x79D3 # 0 +0xB670 0x79D4 # 0 +0xB671 0x79D6 # 0 +0xB672 0x79D7 # 0 +0xB673 0x79D9 # 0 +0xB674 0x79DA # 0 +0xB675 0x79DB # 0 +0xB676 0x79DC # 0 +0xB677 0x79DD # 0 +0xB678 0x79DE # 0 +0xB679 0x79E0 # 0 +0xB67A 0x79E1 # 0 +0xB67B 0x79E2 # 0 +0xB67C 0x79E5 # 0 +0xB67D 0x79E8 # 0 +0xB67E 0x79EA # 0 +0xB680 0x79EC # 0 +0xB681 0x79EE # 0 +0xB682 0x79F1 # 0 +0xB683 0x79F2 # 0 +0xB684 0x79F3 # 0 +0xB685 0x79F4 # 0 +0xB686 0x79F5 # 0 +0xB687 0x79F6 # 0 +0xB688 0x79F7 # 0 +0xB689 0x79F9 # 0 +0xB68A 0x79FA # 0 +0xB68B 0x79FC # 0 +0xB68C 0x79FE # 0 +0xB68D 0x79FF # 0 +0xB68E 0x7A01 # 0 +0xB68F 0x7A04 # 0 +0xB690 0x7A05 # 0 +0xB691 0x7A07 # 0 +0xB692 0x7A08 # 0 +0xB693 0x7A09 # 0 +0xB694 0x7A0A # 0 +0xB695 0x7A0C # 0 +0xB696 0x7A0F # 0 +0xB697 0x7A10 # 0 +0xB698 0x7A11 # 0 +0xB699 0x7A12 # 0 +0xB69A 0x7A13 # 0 +0xB69B 0x7A15 # 0 +0xB69C 0x7A16 # 0 +0xB69D 0x7A18 # 0 +0xB69E 0x7A19 # 0 +0xB69F 0x7A1B # 0 +0xB6A0 0x7A1C # 0 +0xB6A1 0x4E01 # 0 +0xB6A2 0x76EF # 0 +0xB6A3 0x53EE # 0 +0xB6A4 0x9489 # 0 +0xB6A5 0x9876 # 0 +0xB6A6 0x9F0E # 0 +0xB6A7 0x952D # 0 +0xB6A8 0x5B9A # 0 +0xB6A9 0x8BA2 # 0 +0xB6AA 0x4E22 # 0 +0xB6AB 0x4E1C # 0 +0xB6AC 0x51AC # 0 +0xB6AD 0x8463 # 0 +0xB6AE 0x61C2 # 0 +0xB6AF 0x52A8 # 0 +0xB6B0 0x680B # 0 +0xB6B1 0x4F97 # 0 +0xB6B2 0x606B # 0 +0xB6B3 0x51BB # 0 +0xB6B4 0x6D1E # 0 +0xB6B5 0x515C # 0 +0xB6B6 0x6296 # 0 +0xB6B7 0x6597 # 0 +0xB6B8 0x9661 # 0 +0xB6B9 0x8C46 # 0 +0xB6BA 0x9017 # 0 +0xB6BB 0x75D8 # 0 +0xB6BC 0x90FD # 0 +0xB6BD 0x7763 # 0 +0xB6BE 0x6BD2 # 0 +0xB6BF 0x728A # 0 +0xB6C0 0x72EC # 0 +0xB6C1 0x8BFB # 0 +0xB6C2 0x5835 # 0 +0xB6C3 0x7779 # 0 +0xB6C4 0x8D4C # 0 +0xB6C5 0x675C # 0 +0xB6C6 0x9540 # 0 +0xB6C7 0x809A # 0 +0xB6C8 0x5EA6 # 0 +0xB6C9 0x6E21 # 0 +0xB6CA 0x5992 # 0 +0xB6CB 0x7AEF # 0 +0xB6CC 0x77ED # 0 +0xB6CD 0x953B # 0 +0xB6CE 0x6BB5 # 0 +0xB6CF 0x65AD # 0 +0xB6D0 0x7F0E # 0 +0xB6D1 0x5806 # 0 +0xB6D2 0x5151 # 0 +0xB6D3 0x961F # 0 +0xB6D4 0x5BF9 # 0 +0xB6D5 0x58A9 # 0 +0xB6D6 0x5428 # 0 +0xB6D7 0x8E72 # 0 +0xB6D8 0x6566 # 0 +0xB6D9 0x987F # 0 +0xB6DA 0x56E4 # 0 +0xB6DB 0x949D # 0 +0xB6DC 0x76FE # 0 +0xB6DD 0x9041 # 0 +0xB6DE 0x6387 # 0 +0xB6DF 0x54C6 # 0 +0xB6E0 0x591A # 0 +0xB6E1 0x593A # 0 +0xB6E2 0x579B # 0 +0xB6E3 0x8EB2 # 0 +0xB6E4 0x6735 # 0 +0xB6E5 0x8DFA # 0 +0xB6E6 0x8235 # 0 +0xB6E7 0x5241 # 0 +0xB6E8 0x60F0 # 0 +0xB6E9 0x5815 # 0 +0xB6EA 0x86FE # 0 +0xB6EB 0x5CE8 # 0 +0xB6EC 0x9E45 # 0 +0xB6ED 0x4FC4 # 0 +0xB6EE 0x989D # 0 +0xB6EF 0x8BB9 # 0 +0xB6F0 0x5A25 # 0 +0xB6F1 0x6076 # 0 +0xB6F2 0x5384 # 0 +0xB6F3 0x627C # 0 +0xB6F4 0x904F # 0 +0xB6F5 0x9102 # 0 +0xB6F6 0x997F # 0 +0xB6F7 0x6069 # 0 +0xB6F8 0x800C # 0 +0xB6F9 0x513F # 0 +0xB6FA 0x8033 # 0 +0xB6FB 0x5C14 # 0 +0xB6FC 0x9975 # 0 +0xB6FD 0x6D31 # 0 +0xB6FE 0x4E8C # 0 +0xB740 0x7A1D # 0 +0xB741 0x7A1F # 0 +0xB742 0x7A21 # 0 +0xB743 0x7A22 # 0 +0xB744 0x7A24 # 0 +0xB745 0x7A25 # 0 +0xB746 0x7A26 # 0 +0xB747 0x7A27 # 0 +0xB748 0x7A28 # 0 +0xB749 0x7A29 # 0 +0xB74A 0x7A2A # 0 +0xB74B 0x7A2B # 0 +0xB74C 0x7A2C # 0 +0xB74D 0x7A2D # 0 +0xB74E 0x7A2E # 0 +0xB74F 0x7A2F # 0 +0xB750 0x7A30 # 0 +0xB751 0x7A31 # 0 +0xB752 0x7A32 # 0 +0xB753 0x7A34 # 0 +0xB754 0x7A35 # 0 +0xB755 0x7A36 # 0 +0xB756 0x7A38 # 0 +0xB757 0x7A3A # 0 +0xB758 0x7A3E # 0 +0xB759 0x7A40 # 0 +0xB75A 0x7A41 # 0 +0xB75B 0x7A42 # 0 +0xB75C 0x7A43 # 0 +0xB75D 0x7A44 # 0 +0xB75E 0x7A45 # 0 +0xB75F 0x7A47 # 0 +0xB760 0x7A48 # 0 +0xB761 0x7A49 # 0 +0xB762 0x7A4A # 0 +0xB763 0x7A4B # 0 +0xB764 0x7A4C # 0 +0xB765 0x7A4D # 0 +0xB766 0x7A4E # 0 +0xB767 0x7A4F # 0 +0xB768 0x7A50 # 0 +0xB769 0x7A52 # 0 +0xB76A 0x7A53 # 0 +0xB76B 0x7A54 # 0 +0xB76C 0x7A55 # 0 +0xB76D 0x7A56 # 0 +0xB76E 0x7A58 # 0 +0xB76F 0x7A59 # 0 +0xB770 0x7A5A # 0 +0xB771 0x7A5B # 0 +0xB772 0x7A5C # 0 +0xB773 0x7A5D # 0 +0xB774 0x7A5E # 0 +0xB775 0x7A5F # 0 +0xB776 0x7A60 # 0 +0xB777 0x7A61 # 0 +0xB778 0x7A62 # 0 +0xB779 0x7A63 # 0 +0xB77A 0x7A64 # 0 +0xB77B 0x7A65 # 0 +0xB77C 0x7A66 # 0 +0xB77D 0x7A67 # 0 +0xB77E 0x7A68 # 0 +0xB780 0x7A69 # 0 +0xB781 0x7A6A # 0 +0xB782 0x7A6B # 0 +0xB783 0x7A6C # 0 +0xB784 0x7A6D # 0 +0xB785 0x7A6E # 0 +0xB786 0x7A6F # 0 +0xB787 0x7A71 # 0 +0xB788 0x7A72 # 0 +0xB789 0x7A73 # 0 +0xB78A 0x7A75 # 0 +0xB78B 0x7A7B # 0 +0xB78C 0x7A7C # 0 +0xB78D 0x7A7D # 0 +0xB78E 0x7A7E # 0 +0xB78F 0x7A82 # 0 +0xB790 0x7A85 # 0 +0xB791 0x7A87 # 0 +0xB792 0x7A89 # 0 +0xB793 0x7A8A # 0 +0xB794 0x7A8B # 0 +0xB795 0x7A8C # 0 +0xB796 0x7A8E # 0 +0xB797 0x7A8F # 0 +0xB798 0x7A90 # 0 +0xB799 0x7A93 # 0 +0xB79A 0x7A94 # 0 +0xB79B 0x7A99 # 0 +0xB79C 0x7A9A # 0 +0xB79D 0x7A9B # 0 +0xB79E 0x7A9E # 0 +0xB79F 0x7AA1 # 0 +0xB7A0 0x7AA2 # 0 +0xB7A1 0x8D30 # 0 +0xB7A2 0x53D1 # 0 +0xB7A3 0x7F5A # 0 +0xB7A4 0x7B4F # 0 +0xB7A5 0x4F10 # 0 +0xB7A6 0x4E4F # 0 +0xB7A7 0x9600 # 0 +0xB7A8 0x6CD5 # 0 +0xB7A9 0x73D0 # 0 +0xB7AA 0x85E9 # 0 +0xB7AB 0x5E06 # 0 +0xB7AC 0x756A # 0 +0xB7AD 0x7FFB # 0 +0xB7AE 0x6A0A # 0 +0xB7AF 0x77FE # 0 +0xB7B0 0x9492 # 0 +0xB7B1 0x7E41 # 0 +0xB7B2 0x51E1 # 0 +0xB7B3 0x70E6 # 0 +0xB7B4 0x53CD # 0 +0xB7B5 0x8FD4 # 0 +0xB7B6 0x8303 # 0 +0xB7B7 0x8D29 # 0 +0xB7B8 0x72AF # 0 +0xB7B9 0x996D # 0 +0xB7BA 0x6CDB # 0 +0xB7BB 0x574A # 0 +0xB7BC 0x82B3 # 0 +0xB7BD 0x65B9 # 0 +0xB7BE 0x80AA # 0 +0xB7BF 0x623F # 0 +0xB7C0 0x9632 # 0 +0xB7C1 0x59A8 # 0 +0xB7C2 0x4EFF # 0 +0xB7C3 0x8BBF # 0 +0xB7C4 0x7EBA # 0 +0xB7C5 0x653E # 0 +0xB7C6 0x83F2 # 0 +0xB7C7 0x975E # 0 +0xB7C8 0x5561 # 0 +0xB7C9 0x98DE # 0 +0xB7CA 0x80A5 # 0 +0xB7CB 0x532A # 0 +0xB7CC 0x8BFD # 0 +0xB7CD 0x5420 # 0 +0xB7CE 0x80BA # 0 +0xB7CF 0x5E9F # 0 +0xB7D0 0x6CB8 # 0 +0xB7D1 0x8D39 # 0 +0xB7D2 0x82AC # 0 +0xB7D3 0x915A # 0 +0xB7D4 0x5429 # 0 +0xB7D5 0x6C1B # 0 +0xB7D6 0x5206 # 0 +0xB7D7 0x7EB7 # 0 +0xB7D8 0x575F # 0 +0xB7D9 0x711A # 0 +0xB7DA 0x6C7E # 0 +0xB7DB 0x7C89 # 0 +0xB7DC 0x594B # 0 +0xB7DD 0x4EFD # 0 +0xB7DE 0x5FFF # 0 +0xB7DF 0x6124 # 0 +0xB7E0 0x7CAA # 0 +0xB7E1 0x4E30 # 0 +0xB7E2 0x5C01 # 0 +0xB7E3 0x67AB # 0 +0xB7E4 0x8702 # 0 +0xB7E5 0x5CF0 # 0 +0xB7E6 0x950B # 0 +0xB7E7 0x98CE # 0 +0xB7E8 0x75AF # 0 +0xB7E9 0x70FD # 0 +0xB7EA 0x9022 # 0 +0xB7EB 0x51AF # 0 +0xB7EC 0x7F1D # 0 +0xB7ED 0x8BBD # 0 +0xB7EE 0x5949 # 0 +0xB7EF 0x51E4 # 0 +0xB7F0 0x4F5B # 0 +0xB7F1 0x5426 # 0 +0xB7F2 0x592B # 0 +0xB7F3 0x6577 # 0 +0xB7F4 0x80A4 # 0 +0xB7F5 0x5B75 # 0 +0xB7F6 0x6276 # 0 +0xB7F7 0x62C2 # 0 +0xB7F8 0x8F90 # 0 +0xB7F9 0x5E45 # 0 +0xB7FA 0x6C1F # 0 +0xB7FB 0x7B26 # 0 +0xB7FC 0x4F0F # 0 +0xB7FD 0x4FD8 # 0 +0xB7FE 0x670D # 0 +0xB840 0x7AA3 # 0 +0xB841 0x7AA4 # 0 +0xB842 0x7AA7 # 0 +0xB843 0x7AA9 # 0 +0xB844 0x7AAA # 0 +0xB845 0x7AAB # 0 +0xB846 0x7AAE # 0 +0xB847 0x7AAF # 0 +0xB848 0x7AB0 # 0 +0xB849 0x7AB1 # 0 +0xB84A 0x7AB2 # 0 +0xB84B 0x7AB4 # 0 +0xB84C 0x7AB5 # 0 +0xB84D 0x7AB6 # 0 +0xB84E 0x7AB7 # 0 +0xB84F 0x7AB8 # 0 +0xB850 0x7AB9 # 0 +0xB851 0x7ABA # 0 +0xB852 0x7ABB # 0 +0xB853 0x7ABC # 0 +0xB854 0x7ABD # 0 +0xB855 0x7ABE # 0 +0xB856 0x7AC0 # 0 +0xB857 0x7AC1 # 0 +0xB858 0x7AC2 # 0 +0xB859 0x7AC3 # 0 +0xB85A 0x7AC4 # 0 +0xB85B 0x7AC5 # 0 +0xB85C 0x7AC6 # 0 +0xB85D 0x7AC7 # 0 +0xB85E 0x7AC8 # 0 +0xB85F 0x7AC9 # 0 +0xB860 0x7ACA # 0 +0xB861 0x7ACC # 0 +0xB862 0x7ACD # 0 +0xB863 0x7ACE # 0 +0xB864 0x7ACF # 0 +0xB865 0x7AD0 # 0 +0xB866 0x7AD1 # 0 +0xB867 0x7AD2 # 0 +0xB868 0x7AD3 # 0 +0xB869 0x7AD4 # 0 +0xB86A 0x7AD5 # 0 +0xB86B 0x7AD7 # 0 +0xB86C 0x7AD8 # 0 +0xB86D 0x7ADA # 0 +0xB86E 0x7ADB # 0 +0xB86F 0x7ADC # 0 +0xB870 0x7ADD # 0 +0xB871 0x7AE1 # 0 +0xB872 0x7AE2 # 0 +0xB873 0x7AE4 # 0 +0xB874 0x7AE7 # 0 +0xB875 0x7AE8 # 0 +0xB876 0x7AE9 # 0 +0xB877 0x7AEA # 0 +0xB878 0x7AEB # 0 +0xB879 0x7AEC # 0 +0xB87A 0x7AEE # 0 +0xB87B 0x7AF0 # 0 +0xB87C 0x7AF1 # 0 +0xB87D 0x7AF2 # 0 +0xB87E 0x7AF3 # 0 +0xB880 0x7AF4 # 0 +0xB881 0x7AF5 # 0 +0xB882 0x7AF6 # 0 +0xB883 0x7AF7 # 0 +0xB884 0x7AF8 # 0 +0xB885 0x7AFB # 0 +0xB886 0x7AFC # 0 +0xB887 0x7AFE # 0 +0xB888 0x7B00 # 0 +0xB889 0x7B01 # 0 +0xB88A 0x7B02 # 0 +0xB88B 0x7B05 # 0 +0xB88C 0x7B07 # 0 +0xB88D 0x7B09 # 0 +0xB88E 0x7B0C # 0 +0xB88F 0x7B0D # 0 +0xB890 0x7B0E # 0 +0xB891 0x7B10 # 0 +0xB892 0x7B12 # 0 +0xB893 0x7B13 # 0 +0xB894 0x7B16 # 0 +0xB895 0x7B17 # 0 +0xB896 0x7B18 # 0 +0xB897 0x7B1A # 0 +0xB898 0x7B1C # 0 +0xB899 0x7B1D # 0 +0xB89A 0x7B1F # 0 +0xB89B 0x7B21 # 0 +0xB89C 0x7B22 # 0 +0xB89D 0x7B23 # 0 +0xB89E 0x7B27 # 0 +0xB89F 0x7B29 # 0 +0xB8A0 0x7B2D # 0 +0xB8A1 0x6D6E # 0 +0xB8A2 0x6DAA # 0 +0xB8A3 0x798F # 0 +0xB8A4 0x88B1 # 0 +0xB8A5 0x5F17 # 0 +0xB8A6 0x752B # 0 +0xB8A7 0x629A # 0 +0xB8A8 0x8F85 # 0 +0xB8A9 0x4FEF # 0 +0xB8AA 0x91DC # 0 +0xB8AB 0x65A7 # 0 +0xB8AC 0x812F # 0 +0xB8AD 0x8151 # 0 +0xB8AE 0x5E9C # 0 +0xB8AF 0x8150 # 0 +0xB8B0 0x8D74 # 0 +0xB8B1 0x526F # 0 +0xB8B2 0x8986 # 0 +0xB8B3 0x8D4B # 0 +0xB8B4 0x590D # 0 +0xB8B5 0x5085 # 0 +0xB8B6 0x4ED8 # 0 +0xB8B7 0x961C # 0 +0xB8B8 0x7236 # 0 +0xB8B9 0x8179 # 0 +0xB8BA 0x8D1F # 0 +0xB8BB 0x5BCC # 0 +0xB8BC 0x8BA3 # 0 +0xB8BD 0x9644 # 0 +0xB8BE 0x5987 # 0 +0xB8BF 0x7F1A # 0 +0xB8C0 0x5490 # 0 +0xB8C1 0x5676 # 0 +0xB8C2 0x560E # 0 +0xB8C3 0x8BE5 # 0 +0xB8C4 0x6539 # 0 +0xB8C5 0x6982 # 0 +0xB8C6 0x9499 # 0 +0xB8C7 0x76D6 # 0 +0xB8C8 0x6E89 # 0 +0xB8C9 0x5E72 # 0 +0xB8CA 0x7518 # 0 +0xB8CB 0x6746 # 0 +0xB8CC 0x67D1 # 0 +0xB8CD 0x7AFF # 0 +0xB8CE 0x809D # 0 +0xB8CF 0x8D76 # 0 +0xB8D0 0x611F # 0 +0xB8D1 0x79C6 # 0 +0xB8D2 0x6562 # 0 +0xB8D3 0x8D63 # 0 +0xB8D4 0x5188 # 0 +0xB8D5 0x521A # 0 +0xB8D6 0x94A2 # 0 +0xB8D7 0x7F38 # 0 +0xB8D8 0x809B # 0 +0xB8D9 0x7EB2 # 0 +0xB8DA 0x5C97 # 0 +0xB8DB 0x6E2F # 0 +0xB8DC 0x6760 # 0 +0xB8DD 0x7BD9 # 0 +0xB8DE 0x768B # 0 +0xB8DF 0x9AD8 # 0 +0xB8E0 0x818F # 0 +0xB8E1 0x7F94 # 0 +0xB8E2 0x7CD5 # 0 +0xB8E3 0x641E # 0 +0xB8E4 0x9550 # 0 +0xB8E5 0x7A3F # 0 +0xB8E6 0x544A # 0 +0xB8E7 0x54E5 # 0 +0xB8E8 0x6B4C # 0 +0xB8E9 0x6401 # 0 +0xB8EA 0x6208 # 0 +0xB8EB 0x9E3D # 0 +0xB8EC 0x80F3 # 0 +0xB8ED 0x7599 # 0 +0xB8EE 0x5272 # 0 +0xB8EF 0x9769 # 0 +0xB8F0 0x845B # 0 +0xB8F1 0x683C # 0 +0xB8F2 0x86E4 # 0 +0xB8F3 0x9601 # 0 +0xB8F4 0x9694 # 0 +0xB8F5 0x94EC # 0 +0xB8F6 0x4E2A # 0 +0xB8F7 0x5404 # 0 +0xB8F8 0x7ED9 # 0 +0xB8F9 0x6839 # 0 +0xB8FA 0x8DDF # 0 +0xB8FB 0x8015 # 0 +0xB8FC 0x66F4 # 0 +0xB8FD 0x5E9A # 0 +0xB8FE 0x7FB9 # 0 +0xB940 0x7B2F # 0 +0xB941 0x7B30 # 0 +0xB942 0x7B32 # 0 +0xB943 0x7B34 # 0 +0xB944 0x7B35 # 0 +0xB945 0x7B36 # 0 +0xB946 0x7B37 # 0 +0xB947 0x7B39 # 0 +0xB948 0x7B3B # 0 +0xB949 0x7B3D # 0 +0xB94A 0x7B3F # 0 +0xB94B 0x7B40 # 0 +0xB94C 0x7B41 # 0 +0xB94D 0x7B42 # 0 +0xB94E 0x7B43 # 0 +0xB94F 0x7B44 # 0 +0xB950 0x7B46 # 0 +0xB951 0x7B48 # 0 +0xB952 0x7B4A # 0 +0xB953 0x7B4D # 0 +0xB954 0x7B4E # 0 +0xB955 0x7B53 # 0 +0xB956 0x7B55 # 0 +0xB957 0x7B57 # 0 +0xB958 0x7B59 # 0 +0xB959 0x7B5C # 0 +0xB95A 0x7B5E # 0 +0xB95B 0x7B5F # 0 +0xB95C 0x7B61 # 0 +0xB95D 0x7B63 # 0 +0xB95E 0x7B64 # 0 +0xB95F 0x7B65 # 0 +0xB960 0x7B66 # 0 +0xB961 0x7B67 # 0 +0xB962 0x7B68 # 0 +0xB963 0x7B69 # 0 +0xB964 0x7B6A # 0 +0xB965 0x7B6B # 0 +0xB966 0x7B6C # 0 +0xB967 0x7B6D # 0 +0xB968 0x7B6F # 0 +0xB969 0x7B70 # 0 +0xB96A 0x7B73 # 0 +0xB96B 0x7B74 # 0 +0xB96C 0x7B76 # 0 +0xB96D 0x7B78 # 0 +0xB96E 0x7B7A # 0 +0xB96F 0x7B7C # 0 +0xB970 0x7B7D # 0 +0xB971 0x7B7F # 0 +0xB972 0x7B81 # 0 +0xB973 0x7B82 # 0 +0xB974 0x7B83 # 0 +0xB975 0x7B84 # 0 +0xB976 0x7B86 # 0 +0xB977 0x7B87 # 0 +0xB978 0x7B88 # 0 +0xB979 0x7B89 # 0 +0xB97A 0x7B8A # 0 +0xB97B 0x7B8B # 0 +0xB97C 0x7B8C # 0 +0xB97D 0x7B8E # 0 +0xB97E 0x7B8F # 0 +0xB980 0x7B91 # 0 +0xB981 0x7B92 # 0 +0xB982 0x7B93 # 0 +0xB983 0x7B96 # 0 +0xB984 0x7B98 # 0 +0xB985 0x7B99 # 0 +0xB986 0x7B9A # 0 +0xB987 0x7B9B # 0 +0xB988 0x7B9E # 0 +0xB989 0x7B9F # 0 +0xB98A 0x7BA0 # 0 +0xB98B 0x7BA3 # 0 +0xB98C 0x7BA4 # 0 +0xB98D 0x7BA5 # 0 +0xB98E 0x7BAE # 0 +0xB98F 0x7BAF # 0 +0xB990 0x7BB0 # 0 +0xB991 0x7BB2 # 0 +0xB992 0x7BB3 # 0 +0xB993 0x7BB5 # 0 +0xB994 0x7BB6 # 0 +0xB995 0x7BB7 # 0 +0xB996 0x7BB9 # 0 +0xB997 0x7BBA # 0 +0xB998 0x7BBB # 0 +0xB999 0x7BBC # 0 +0xB99A 0x7BBD # 0 +0xB99B 0x7BBE # 0 +0xB99C 0x7BBF # 0 +0xB99D 0x7BC0 # 0 +0xB99E 0x7BC2 # 0 +0xB99F 0x7BC3 # 0 +0xB9A0 0x7BC4 # 0 +0xB9A1 0x57C2 # 0 +0xB9A2 0x803F # 0 +0xB9A3 0x6897 # 0 +0xB9A4 0x5DE5 # 0 +0xB9A5 0x653B # 0 +0xB9A6 0x529F # 0 +0xB9A7 0x606D # 0 +0xB9A8 0x9F9A # 0 +0xB9A9 0x4F9B # 0 +0xB9AA 0x8EAC # 0 +0xB9AB 0x516C # 0 +0xB9AC 0x5BAB # 0 +0xB9AD 0x5F13 # 0 +0xB9AE 0x5DE9 # 0 +0xB9AF 0x6C5E # 0 +0xB9B0 0x62F1 # 0 +0xB9B1 0x8D21 # 0 +0xB9B2 0x5171 # 0 +0xB9B3 0x94A9 # 0 +0xB9B4 0x52FE # 0 +0xB9B5 0x6C9F # 0 +0xB9B6 0x82DF # 0 +0xB9B7 0x72D7 # 0 +0xB9B8 0x57A2 # 0 +0xB9B9 0x6784 # 0 +0xB9BA 0x8D2D # 0 +0xB9BB 0x591F # 0 +0xB9BC 0x8F9C # 0 +0xB9BD 0x83C7 # 0 +0xB9BE 0x5495 # 0 +0xB9BF 0x7B8D # 0 +0xB9C0 0x4F30 # 0 +0xB9C1 0x6CBD # 0 +0xB9C2 0x5B64 # 0 +0xB9C3 0x59D1 # 0 +0xB9C4 0x9F13 # 0 +0xB9C5 0x53E4 # 0 +0xB9C6 0x86CA # 0 +0xB9C7 0x9AA8 # 0 +0xB9C8 0x8C37 # 0 +0xB9C9 0x80A1 # 0 +0xB9CA 0x6545 # 0 +0xB9CB 0x987E # 0 +0xB9CC 0x56FA # 0 +0xB9CD 0x96C7 # 0 +0xB9CE 0x522E # 0 +0xB9CF 0x74DC # 0 +0xB9D0 0x5250 # 0 +0xB9D1 0x5BE1 # 0 +0xB9D2 0x6302 # 0 +0xB9D3 0x8902 # 0 +0xB9D4 0x4E56 # 0 +0xB9D5 0x62D0 # 0 +0xB9D6 0x602A # 0 +0xB9D7 0x68FA # 0 +0xB9D8 0x5173 # 0 +0xB9D9 0x5B98 # 0 +0xB9DA 0x51A0 # 0 +0xB9DB 0x89C2 # 0 +0xB9DC 0x7BA1 # 0 +0xB9DD 0x9986 # 0 +0xB9DE 0x7F50 # 0 +0xB9DF 0x60EF # 0 +0xB9E0 0x704C # 0 +0xB9E1 0x8D2F # 0 +0xB9E2 0x5149 # 0 +0xB9E3 0x5E7F # 0 +0xB9E4 0x901B # 0 +0xB9E5 0x7470 # 0 +0xB9E6 0x89C4 # 0 +0xB9E7 0x572D # 0 +0xB9E8 0x7845 # 0 +0xB9E9 0x5F52 # 0 +0xB9EA 0x9F9F # 0 +0xB9EB 0x95FA # 0 +0xB9EC 0x8F68 # 0 +0xB9ED 0x9B3C # 0 +0xB9EE 0x8BE1 # 0 +0xB9EF 0x7678 # 0 +0xB9F0 0x6842 # 0 +0xB9F1 0x67DC # 0 +0xB9F2 0x8DEA # 0 +0xB9F3 0x8D35 # 0 +0xB9F4 0x523D # 0 +0xB9F5 0x8F8A # 0 +0xB9F6 0x6EDA # 0 +0xB9F7 0x68CD # 0 +0xB9F8 0x9505 # 0 +0xB9F9 0x90ED # 0 +0xB9FA 0x56FD # 0 +0xB9FB 0x679C # 0 +0xB9FC 0x88F9 # 0 +0xB9FD 0x8FC7 # 0 +0xB9FE 0x54C8 # 0 +0xBA40 0x7BC5 # 0 +0xBA41 0x7BC8 # 0 +0xBA42 0x7BC9 # 0 +0xBA43 0x7BCA # 0 +0xBA44 0x7BCB # 0 +0xBA45 0x7BCD # 0 +0xBA46 0x7BCE # 0 +0xBA47 0x7BCF # 0 +0xBA48 0x7BD0 # 0 +0xBA49 0x7BD2 # 0 +0xBA4A 0x7BD4 # 0 +0xBA4B 0x7BD5 # 0 +0xBA4C 0x7BD6 # 0 +0xBA4D 0x7BD7 # 0 +0xBA4E 0x7BD8 # 0 +0xBA4F 0x7BDB # 0 +0xBA50 0x7BDC # 0 +0xBA51 0x7BDE # 0 +0xBA52 0x7BDF # 0 +0xBA53 0x7BE0 # 0 +0xBA54 0x7BE2 # 0 +0xBA55 0x7BE3 # 0 +0xBA56 0x7BE4 # 0 +0xBA57 0x7BE7 # 0 +0xBA58 0x7BE8 # 0 +0xBA59 0x7BE9 # 0 +0xBA5A 0x7BEB # 0 +0xBA5B 0x7BEC # 0 +0xBA5C 0x7BED # 0 +0xBA5D 0x7BEF # 0 +0xBA5E 0x7BF0 # 0 +0xBA5F 0x7BF2 # 0 +0xBA60 0x7BF3 # 0 +0xBA61 0x7BF4 # 0 +0xBA62 0x7BF5 # 0 +0xBA63 0x7BF6 # 0 +0xBA64 0x7BF8 # 0 +0xBA65 0x7BF9 # 0 +0xBA66 0x7BFA # 0 +0xBA67 0x7BFB # 0 +0xBA68 0x7BFD # 0 +0xBA69 0x7BFF # 0 +0xBA6A 0x7C00 # 0 +0xBA6B 0x7C01 # 0 +0xBA6C 0x7C02 # 0 +0xBA6D 0x7C03 # 0 +0xBA6E 0x7C04 # 0 +0xBA6F 0x7C05 # 0 +0xBA70 0x7C06 # 0 +0xBA71 0x7C08 # 0 +0xBA72 0x7C09 # 0 +0xBA73 0x7C0A # 0 +0xBA74 0x7C0D # 0 +0xBA75 0x7C0E # 0 +0xBA76 0x7C10 # 0 +0xBA77 0x7C11 # 0 +0xBA78 0x7C12 # 0 +0xBA79 0x7C13 # 0 +0xBA7A 0x7C14 # 0 +0xBA7B 0x7C15 # 0 +0xBA7C 0x7C17 # 0 +0xBA7D 0x7C18 # 0 +0xBA7E 0x7C19 # 0 +0xBA80 0x7C1A # 0 +0xBA81 0x7C1B # 0 +0xBA82 0x7C1C # 0 +0xBA83 0x7C1D # 0 +0xBA84 0x7C1E # 0 +0xBA85 0x7C20 # 0 +0xBA86 0x7C21 # 0 +0xBA87 0x7C22 # 0 +0xBA88 0x7C23 # 0 +0xBA89 0x7C24 # 0 +0xBA8A 0x7C25 # 0 +0xBA8B 0x7C28 # 0 +0xBA8C 0x7C29 # 0 +0xBA8D 0x7C2B # 0 +0xBA8E 0x7C2C # 0 +0xBA8F 0x7C2D # 0 +0xBA90 0x7C2E # 0 +0xBA91 0x7C2F # 0 +0xBA92 0x7C30 # 0 +0xBA93 0x7C31 # 0 +0xBA94 0x7C32 # 0 +0xBA95 0x7C33 # 0 +0xBA96 0x7C34 # 0 +0xBA97 0x7C35 # 0 +0xBA98 0x7C36 # 0 +0xBA99 0x7C37 # 0 +0xBA9A 0x7C39 # 0 +0xBA9B 0x7C3A # 0 +0xBA9C 0x7C3B # 0 +0xBA9D 0x7C3C # 0 +0xBA9E 0x7C3D # 0 +0xBA9F 0x7C3E # 0 +0xBAA0 0x7C42 # 0 +0xBAA1 0x9AB8 # 0 +0xBAA2 0x5B69 # 0 +0xBAA3 0x6D77 # 0 +0xBAA4 0x6C26 # 0 +0xBAA5 0x4EA5 # 0 +0xBAA6 0x5BB3 # 0 +0xBAA7 0x9A87 # 0 +0xBAA8 0x9163 # 0 +0xBAA9 0x61A8 # 0 +0xBAAA 0x90AF # 0 +0xBAAB 0x97E9 # 0 +0xBAAC 0x542B # 0 +0xBAAD 0x6DB5 # 0 +0xBAAE 0x5BD2 # 0 +0xBAAF 0x51FD # 0 +0xBAB0 0x558A # 0 +0xBAB1 0x7F55 # 0 +0xBAB2 0x7FF0 # 0 +0xBAB3 0x64BC # 0 +0xBAB4 0x634D # 0 +0xBAB5 0x65F1 # 0 +0xBAB6 0x61BE # 0 +0xBAB7 0x608D # 0 +0xBAB8 0x710A # 0 +0xBAB9 0x6C57 # 0 +0xBABA 0x6C49 # 0 +0xBABB 0x592F # 0 +0xBABC 0x676D # 0 +0xBABD 0x822A # 0 +0xBABE 0x58D5 # 0 +0xBABF 0x568E # 0 +0xBAC0 0x8C6A # 0 +0xBAC1 0x6BEB # 0 +0xBAC2 0x90DD # 0 +0xBAC3 0x597D # 0 +0xBAC4 0x8017 # 0 +0xBAC5 0x53F7 # 0 +0xBAC6 0x6D69 # 0 +0xBAC7 0x5475 # 0 +0xBAC8 0x559D # 0 +0xBAC9 0x8377 # 0 +0xBACA 0x83CF # 0 +0xBACB 0x6838 # 0 +0xBACC 0x79BE # 0 +0xBACD 0x548C # 0 +0xBACE 0x4F55 # 0 +0xBACF 0x5408 # 0 +0xBAD0 0x76D2 # 0 +0xBAD1 0x8C89 # 0 +0xBAD2 0x9602 # 0 +0xBAD3 0x6CB3 # 0 +0xBAD4 0x6DB8 # 0 +0xBAD5 0x8D6B # 0 +0xBAD6 0x8910 # 0 +0xBAD7 0x9E64 # 0 +0xBAD8 0x8D3A # 0 +0xBAD9 0x563F # 0 +0xBADA 0x9ED1 # 0 +0xBADB 0x75D5 # 0 +0xBADC 0x5F88 # 0 +0xBADD 0x72E0 # 0 +0xBADE 0x6068 # 0 +0xBADF 0x54FC # 0 +0xBAE0 0x4EA8 # 0 +0xBAE1 0x6A2A # 0 +0xBAE2 0x8861 # 0 +0xBAE3 0x6052 # 0 +0xBAE4 0x8F70 # 0 +0xBAE5 0x54C4 # 0 +0xBAE6 0x70D8 # 0 +0xBAE7 0x8679 # 0 +0xBAE8 0x9E3F # 0 +0xBAE9 0x6D2A # 0 +0xBAEA 0x5B8F # 0 +0xBAEB 0x5F18 # 0 +0xBAEC 0x7EA2 # 0 +0xBAED 0x5589 # 0 +0xBAEE 0x4FAF # 0 +0xBAEF 0x7334 # 0 +0xBAF0 0x543C # 0 +0xBAF1 0x539A # 0 +0xBAF2 0x5019 # 0 +0xBAF3 0x540E # 0 +0xBAF4 0x547C # 0 +0xBAF5 0x4E4E # 0 +0xBAF6 0x5FFD # 0 +0xBAF7 0x745A # 0 +0xBAF8 0x58F6 # 0 +0xBAF9 0x846B # 0 +0xBAFA 0x80E1 # 0 +0xBAFB 0x8774 # 0 +0xBAFC 0x72D0 # 0 +0xBAFD 0x7CCA # 0 +0xBAFE 0x6E56 # 0 +0xBB40 0x7C43 # 0 +0xBB41 0x7C44 # 0 +0xBB42 0x7C45 # 0 +0xBB43 0x7C46 # 0 +0xBB44 0x7C47 # 0 +0xBB45 0x7C48 # 0 +0xBB46 0x7C49 # 0 +0xBB47 0x7C4A # 0 +0xBB48 0x7C4B # 0 +0xBB49 0x7C4C # 0 +0xBB4A 0x7C4E # 0 +0xBB4B 0x7C4F # 0 +0xBB4C 0x7C50 # 0 +0xBB4D 0x7C51 # 0 +0xBB4E 0x7C52 # 0 +0xBB4F 0x7C53 # 0 +0xBB50 0x7C54 # 0 +0xBB51 0x7C55 # 0 +0xBB52 0x7C56 # 0 +0xBB53 0x7C57 # 0 +0xBB54 0x7C58 # 0 +0xBB55 0x7C59 # 0 +0xBB56 0x7C5A # 0 +0xBB57 0x7C5B # 0 +0xBB58 0x7C5C # 0 +0xBB59 0x7C5D # 0 +0xBB5A 0x7C5E # 0 +0xBB5B 0x7C5F # 0 +0xBB5C 0x7C60 # 0 +0xBB5D 0x7C61 # 0 +0xBB5E 0x7C62 # 0 +0xBB5F 0x7C63 # 0 +0xBB60 0x7C64 # 0 +0xBB61 0x7C65 # 0 +0xBB62 0x7C66 # 0 +0xBB63 0x7C67 # 0 +0xBB64 0x7C68 # 0 +0xBB65 0x7C69 # 0 +0xBB66 0x7C6A # 0 +0xBB67 0x7C6B # 0 +0xBB68 0x7C6C # 0 +0xBB69 0x7C6D # 0 +0xBB6A 0x7C6E # 0 +0xBB6B 0x7C6F # 0 +0xBB6C 0x7C70 # 0 +0xBB6D 0x7C71 # 0 +0xBB6E 0x7C72 # 0 +0xBB6F 0x7C75 # 0 +0xBB70 0x7C76 # 0 +0xBB71 0x7C77 # 0 +0xBB72 0x7C78 # 0 +0xBB73 0x7C79 # 0 +0xBB74 0x7C7A # 0 +0xBB75 0x7C7E # 0 +0xBB76 0x7C7F # 0 +0xBB77 0x7C80 # 0 +0xBB78 0x7C81 # 0 +0xBB79 0x7C82 # 0 +0xBB7A 0x7C83 # 0 +0xBB7B 0x7C84 # 0 +0xBB7C 0x7C85 # 0 +0xBB7D 0x7C86 # 0 +0xBB7E 0x7C87 # 0 +0xBB80 0x7C88 # 0 +0xBB81 0x7C8A # 0 +0xBB82 0x7C8B # 0 +0xBB83 0x7C8C # 0 +0xBB84 0x7C8D # 0 +0xBB85 0x7C8E # 0 +0xBB86 0x7C8F # 0 +0xBB87 0x7C90 # 0 +0xBB88 0x7C93 # 0 +0xBB89 0x7C94 # 0 +0xBB8A 0x7C96 # 0 +0xBB8B 0x7C99 # 0 +0xBB8C 0x7C9A # 0 +0xBB8D 0x7C9B # 0 +0xBB8E 0x7CA0 # 0 +0xBB8F 0x7CA1 # 0 +0xBB90 0x7CA3 # 0 +0xBB91 0x7CA6 # 0 +0xBB92 0x7CA7 # 0 +0xBB93 0x7CA8 # 0 +0xBB94 0x7CA9 # 0 +0xBB95 0x7CAB # 0 +0xBB96 0x7CAC # 0 +0xBB97 0x7CAD # 0 +0xBB98 0x7CAF # 0 +0xBB99 0x7CB0 # 0 +0xBB9A 0x7CB4 # 0 +0xBB9B 0x7CB5 # 0 +0xBB9C 0x7CB6 # 0 +0xBB9D 0x7CB7 # 0 +0xBB9E 0x7CB8 # 0 +0xBB9F 0x7CBA # 0 +0xBBA0 0x7CBB # 0 +0xBBA1 0x5F27 # 0 +0xBBA2 0x864E # 0 +0xBBA3 0x552C # 0 +0xBBA4 0x62A4 # 0 +0xBBA5 0x4E92 # 0 +0xBBA6 0x6CAA # 0 +0xBBA7 0x6237 # 0 +0xBBA8 0x82B1 # 0 +0xBBA9 0x54D7 # 0 +0xBBAA 0x534E # 0 +0xBBAB 0x733E # 0 +0xBBAC 0x6ED1 # 0 +0xBBAD 0x753B # 0 +0xBBAE 0x5212 # 0 +0xBBAF 0x5316 # 0 +0xBBB0 0x8BDD # 0 +0xBBB1 0x69D0 # 0 +0xBBB2 0x5F8A # 0 +0xBBB3 0x6000 # 0 +0xBBB4 0x6DEE # 0 +0xBBB5 0x574F # 0 +0xBBB6 0x6B22 # 0 +0xBBB7 0x73AF # 0 +0xBBB8 0x6853 # 0 +0xBBB9 0x8FD8 # 0 +0xBBBA 0x7F13 # 0 +0xBBBB 0x6362 # 0 +0xBBBC 0x60A3 # 0 +0xBBBD 0x5524 # 0 +0xBBBE 0x75EA # 0 +0xBBBF 0x8C62 # 0 +0xBBC0 0x7115 # 0 +0xBBC1 0x6DA3 # 0 +0xBBC2 0x5BA6 # 0 +0xBBC3 0x5E7B # 0 +0xBBC4 0x8352 # 0 +0xBBC5 0x614C # 0 +0xBBC6 0x9EC4 # 0 +0xBBC7 0x78FA # 0 +0xBBC8 0x8757 # 0 +0xBBC9 0x7C27 # 0 +0xBBCA 0x7687 # 0 +0xBBCB 0x51F0 # 0 +0xBBCC 0x60F6 # 0 +0xBBCD 0x714C # 0 +0xBBCE 0x6643 # 0 +0xBBCF 0x5E4C # 0 +0xBBD0 0x604D # 0 +0xBBD1 0x8C0E # 0 +0xBBD2 0x7070 # 0 +0xBBD3 0x6325 # 0 +0xBBD4 0x8F89 # 0 +0xBBD5 0x5FBD # 0 +0xBBD6 0x6062 # 0 +0xBBD7 0x86D4 # 0 +0xBBD8 0x56DE # 0 +0xBBD9 0x6BC1 # 0 +0xBBDA 0x6094 # 0 +0xBBDB 0x6167 # 0 +0xBBDC 0x5349 # 0 +0xBBDD 0x60E0 # 0 +0xBBDE 0x6666 # 0 +0xBBDF 0x8D3F # 0 +0xBBE0 0x79FD # 0 +0xBBE1 0x4F1A # 0 +0xBBE2 0x70E9 # 0 +0xBBE3 0x6C47 # 0 +0xBBE4 0x8BB3 # 0 +0xBBE5 0x8BF2 # 0 +0xBBE6 0x7ED8 # 0 +0xBBE7 0x8364 # 0 +0xBBE8 0x660F # 0 +0xBBE9 0x5A5A # 0 +0xBBEA 0x9B42 # 0 +0xBBEB 0x6D51 # 0 +0xBBEC 0x6DF7 # 0 +0xBBED 0x8C41 # 0 +0xBBEE 0x6D3B # 0 +0xBBEF 0x4F19 # 0 +0xBBF0 0x706B # 0 +0xBBF1 0x83B7 # 0 +0xBBF2 0x6216 # 0 +0xBBF3 0x60D1 # 0 +0xBBF4 0x970D # 0 +0xBBF5 0x8D27 # 0 +0xBBF6 0x7978 # 0 +0xBBF7 0x51FB # 0 +0xBBF8 0x573E # 0 +0xBBF9 0x57FA # 0 +0xBBFA 0x673A # 0 +0xBBFB 0x7578 # 0 +0xBBFC 0x7A3D # 0 +0xBBFD 0x79EF # 0 +0xBBFE 0x7B95 # 0 +0xBC40 0x7CBF # 0 +0xBC41 0x7CC0 # 0 +0xBC42 0x7CC2 # 0 +0xBC43 0x7CC3 # 0 +0xBC44 0x7CC4 # 0 +0xBC45 0x7CC6 # 0 +0xBC46 0x7CC9 # 0 +0xBC47 0x7CCB # 0 +0xBC48 0x7CCE # 0 +0xBC49 0x7CCF # 0 +0xBC4A 0x7CD0 # 0 +0xBC4B 0x7CD1 # 0 +0xBC4C 0x7CD2 # 0 +0xBC4D 0x7CD3 # 0 +0xBC4E 0x7CD4 # 0 +0xBC4F 0x7CD8 # 0 +0xBC50 0x7CDA # 0 +0xBC51 0x7CDB # 0 +0xBC52 0x7CDD # 0 +0xBC53 0x7CDE # 0 +0xBC54 0x7CE1 # 0 +0xBC55 0x7CE2 # 0 +0xBC56 0x7CE3 # 0 +0xBC57 0x7CE4 # 0 +0xBC58 0x7CE5 # 0 +0xBC59 0x7CE6 # 0 +0xBC5A 0x7CE7 # 0 +0xBC5B 0x7CE9 # 0 +0xBC5C 0x7CEA # 0 +0xBC5D 0x7CEB # 0 +0xBC5E 0x7CEC # 0 +0xBC5F 0x7CED # 0 +0xBC60 0x7CEE # 0 +0xBC61 0x7CF0 # 0 +0xBC62 0x7CF1 # 0 +0xBC63 0x7CF2 # 0 +0xBC64 0x7CF3 # 0 +0xBC65 0x7CF4 # 0 +0xBC66 0x7CF5 # 0 +0xBC67 0x7CF6 # 0 +0xBC68 0x7CF7 # 0 +0xBC69 0x7CF9 # 0 +0xBC6A 0x7CFA # 0 +0xBC6B 0x7CFC # 0 +0xBC6C 0x7CFD # 0 +0xBC6D 0x7CFE # 0 +0xBC6E 0x7CFF # 0 +0xBC6F 0x7D00 # 0 +0xBC70 0x7D01 # 0 +0xBC71 0x7D02 # 0 +0xBC72 0x7D03 # 0 +0xBC73 0x7D04 # 0 +0xBC74 0x7D05 # 0 +0xBC75 0x7D06 # 0 +0xBC76 0x7D07 # 0 +0xBC77 0x7D08 # 0 +0xBC78 0x7D09 # 0 +0xBC79 0x7D0B # 0 +0xBC7A 0x7D0C # 0 +0xBC7B 0x7D0D # 0 +0xBC7C 0x7D0E # 0 +0xBC7D 0x7D0F # 0 +0xBC7E 0x7D10 # 0 +0xBC80 0x7D11 # 0 +0xBC81 0x7D12 # 0 +0xBC82 0x7D13 # 0 +0xBC83 0x7D14 # 0 +0xBC84 0x7D15 # 0 +0xBC85 0x7D16 # 0 +0xBC86 0x7D17 # 0 +0xBC87 0x7D18 # 0 +0xBC88 0x7D19 # 0 +0xBC89 0x7D1A # 0 +0xBC8A 0x7D1B # 0 +0xBC8B 0x7D1C # 0 +0xBC8C 0x7D1D # 0 +0xBC8D 0x7D1E # 0 +0xBC8E 0x7D1F # 0 +0xBC8F 0x7D21 # 0 +0xBC90 0x7D23 # 0 +0xBC91 0x7D24 # 0 +0xBC92 0x7D25 # 0 +0xBC93 0x7D26 # 0 +0xBC94 0x7D28 # 0 +0xBC95 0x7D29 # 0 +0xBC96 0x7D2A # 0 +0xBC97 0x7D2C # 0 +0xBC98 0x7D2D # 0 +0xBC99 0x7D2E # 0 +0xBC9A 0x7D30 # 0 +0xBC9B 0x7D31 # 0 +0xBC9C 0x7D32 # 0 +0xBC9D 0x7D33 # 0 +0xBC9E 0x7D34 # 0 +0xBC9F 0x7D35 # 0 +0xBCA0 0x7D36 # 0 +0xBCA1 0x808C # 0 +0xBCA2 0x9965 # 0 +0xBCA3 0x8FF9 # 0 +0xBCA4 0x6FC0 # 0 +0xBCA5 0x8BA5 # 0 +0xBCA6 0x9E21 # 0 +0xBCA7 0x59EC # 0 +0xBCA8 0x7EE9 # 0 +0xBCA9 0x7F09 # 0 +0xBCAA 0x5409 # 0 +0xBCAB 0x6781 # 0 +0xBCAC 0x68D8 # 0 +0xBCAD 0x8F91 # 0 +0xBCAE 0x7C4D # 0 +0xBCAF 0x96C6 # 0 +0xBCB0 0x53CA # 0 +0xBCB1 0x6025 # 0 +0xBCB2 0x75BE # 0 +0xBCB3 0x6C72 # 0 +0xBCB4 0x5373 # 0 +0xBCB5 0x5AC9 # 0 +0xBCB6 0x7EA7 # 0 +0xBCB7 0x6324 # 0 +0xBCB8 0x51E0 # 0 +0xBCB9 0x810A # 0 +0xBCBA 0x5DF1 # 0 +0xBCBB 0x84DF # 0 +0xBCBC 0x6280 # 0 +0xBCBD 0x5180 # 0 +0xBCBE 0x5B63 # 0 +0xBCBF 0x4F0E # 0 +0xBCC0 0x796D # 0 +0xBCC1 0x5242 # 0 +0xBCC2 0x60B8 # 0 +0xBCC3 0x6D4E # 0 +0xBCC4 0x5BC4 # 0 +0xBCC5 0x5BC2 # 0 +0xBCC6 0x8BA1 # 0 +0xBCC7 0x8BB0 # 0 +0xBCC8 0x65E2 # 0 +0xBCC9 0x5FCC # 0 +0xBCCA 0x9645 # 0 +0xBCCB 0x5993 # 0 +0xBCCC 0x7EE7 # 0 +0xBCCD 0x7EAA # 0 +0xBCCE 0x5609 # 0 +0xBCCF 0x67B7 # 0 +0xBCD0 0x5939 # 0 +0xBCD1 0x4F73 # 0 +0xBCD2 0x5BB6 # 0 +0xBCD3 0x52A0 # 0 +0xBCD4 0x835A # 0 +0xBCD5 0x988A # 0 +0xBCD6 0x8D3E # 0 +0xBCD7 0x7532 # 0 +0xBCD8 0x94BE # 0 +0xBCD9 0x5047 # 0 +0xBCDA 0x7A3C # 0 +0xBCDB 0x4EF7 # 0 +0xBCDC 0x67B6 # 0 +0xBCDD 0x9A7E # 0 +0xBCDE 0x5AC1 # 0 +0xBCDF 0x6B7C # 0 +0xBCE0 0x76D1 # 0 +0xBCE1 0x575A # 0 +0xBCE2 0x5C16 # 0 +0xBCE3 0x7B3A # 0 +0xBCE4 0x95F4 # 0 +0xBCE5 0x714E # 0 +0xBCE6 0x517C # 0 +0xBCE7 0x80A9 # 0 +0xBCE8 0x8270 # 0 +0xBCE9 0x5978 # 0 +0xBCEA 0x7F04 # 0 +0xBCEB 0x8327 # 0 +0xBCEC 0x68C0 # 0 +0xBCED 0x67EC # 0 +0xBCEE 0x78B1 # 0 +0xBCEF 0x7877 # 0 +0xBCF0 0x62E3 # 0 +0xBCF1 0x6361 # 0 +0xBCF2 0x7B80 # 0 +0xBCF3 0x4FED # 0 +0xBCF4 0x526A # 0 +0xBCF5 0x51CF # 0 +0xBCF6 0x8350 # 0 +0xBCF7 0x69DB # 0 +0xBCF8 0x9274 # 0 +0xBCF9 0x8DF5 # 0 +0xBCFA 0x8D31 # 0 +0xBCFB 0x89C1 # 0 +0xBCFC 0x952E # 0 +0xBCFD 0x7BAD # 0 +0xBCFE 0x4EF6 # 0 +0xBD40 0x7D37 # 0 +0xBD41 0x7D38 # 0 +0xBD42 0x7D39 # 0 +0xBD43 0x7D3A # 0 +0xBD44 0x7D3B # 0 +0xBD45 0x7D3C # 0 +0xBD46 0x7D3D # 0 +0xBD47 0x7D3E # 0 +0xBD48 0x7D3F # 0 +0xBD49 0x7D40 # 0 +0xBD4A 0x7D41 # 0 +0xBD4B 0x7D42 # 0 +0xBD4C 0x7D43 # 0 +0xBD4D 0x7D44 # 0 +0xBD4E 0x7D45 # 0 +0xBD4F 0x7D46 # 0 +0xBD50 0x7D47 # 0 +0xBD51 0x7D48 # 0 +0xBD52 0x7D49 # 0 +0xBD53 0x7D4A # 0 +0xBD54 0x7D4B # 0 +0xBD55 0x7D4C # 0 +0xBD56 0x7D4D # 0 +0xBD57 0x7D4E # 0 +0xBD58 0x7D4F # 0 +0xBD59 0x7D50 # 0 +0xBD5A 0x7D51 # 0 +0xBD5B 0x7D52 # 0 +0xBD5C 0x7D53 # 0 +0xBD5D 0x7D54 # 0 +0xBD5E 0x7D55 # 0 +0xBD5F 0x7D56 # 0 +0xBD60 0x7D57 # 0 +0xBD61 0x7D58 # 0 +0xBD62 0x7D59 # 0 +0xBD63 0x7D5A # 0 +0xBD64 0x7D5B # 0 +0xBD65 0x7D5C # 0 +0xBD66 0x7D5D # 0 +0xBD67 0x7D5E # 0 +0xBD68 0x7D5F # 0 +0xBD69 0x7D60 # 0 +0xBD6A 0x7D61 # 0 +0xBD6B 0x7D62 # 0 +0xBD6C 0x7D63 # 0 +0xBD6D 0x7D64 # 0 +0xBD6E 0x7D65 # 0 +0xBD6F 0x7D66 # 0 +0xBD70 0x7D67 # 0 +0xBD71 0x7D68 # 0 +0xBD72 0x7D69 # 0 +0xBD73 0x7D6A # 0 +0xBD74 0x7D6B # 0 +0xBD75 0x7D6C # 0 +0xBD76 0x7D6D # 0 +0xBD77 0x7D6F # 0 +0xBD78 0x7D70 # 0 +0xBD79 0x7D71 # 0 +0xBD7A 0x7D72 # 0 +0xBD7B 0x7D73 # 0 +0xBD7C 0x7D74 # 0 +0xBD7D 0x7D75 # 0 +0xBD7E 0x7D76 # 0 +0xBD80 0x7D78 # 0 +0xBD81 0x7D79 # 0 +0xBD82 0x7D7A # 0 +0xBD83 0x7D7B # 0 +0xBD84 0x7D7C # 0 +0xBD85 0x7D7D # 0 +0xBD86 0x7D7E # 0 +0xBD87 0x7D7F # 0 +0xBD88 0x7D80 # 0 +0xBD89 0x7D81 # 0 +0xBD8A 0x7D82 # 0 +0xBD8B 0x7D83 # 0 +0xBD8C 0x7D84 # 0 +0xBD8D 0x7D85 # 0 +0xBD8E 0x7D86 # 0 +0xBD8F 0x7D87 # 0 +0xBD90 0x7D88 # 0 +0xBD91 0x7D89 # 0 +0xBD92 0x7D8A # 0 +0xBD93 0x7D8B # 0 +0xBD94 0x7D8C # 0 +0xBD95 0x7D8D # 0 +0xBD96 0x7D8E # 0 +0xBD97 0x7D8F # 0 +0xBD98 0x7D90 # 0 +0xBD99 0x7D91 # 0 +0xBD9A 0x7D92 # 0 +0xBD9B 0x7D93 # 0 +0xBD9C 0x7D94 # 0 +0xBD9D 0x7D95 # 0 +0xBD9E 0x7D96 # 0 +0xBD9F 0x7D97 # 0 +0xBDA0 0x7D98 # 0 +0xBDA1 0x5065 # 0 +0xBDA2 0x8230 # 0 +0xBDA3 0x5251 # 0 +0xBDA4 0x996F # 0 +0xBDA5 0x6E10 # 0 +0xBDA6 0x6E85 # 0 +0xBDA7 0x6DA7 # 0 +0xBDA8 0x5EFA # 0 +0xBDA9 0x50F5 # 0 +0xBDAA 0x59DC # 0 +0xBDAB 0x5C06 # 0 +0xBDAC 0x6D46 # 0 +0xBDAD 0x6C5F # 0 +0xBDAE 0x7586 # 0 +0xBDAF 0x848B # 0 +0xBDB0 0x6868 # 0 +0xBDB1 0x5956 # 0 +0xBDB2 0x8BB2 # 0 +0xBDB3 0x5320 # 0 +0xBDB4 0x9171 # 0 +0xBDB5 0x964D # 0 +0xBDB6 0x8549 # 0 +0xBDB7 0x6912 # 0 +0xBDB8 0x7901 # 0 +0xBDB9 0x7126 # 0 +0xBDBA 0x80F6 # 0 +0xBDBB 0x4EA4 # 0 +0xBDBC 0x90CA # 0 +0xBDBD 0x6D47 # 0 +0xBDBE 0x9A84 # 0 +0xBDBF 0x5A07 # 0 +0xBDC0 0x56BC # 0 +0xBDC1 0x6405 # 0 +0xBDC2 0x94F0 # 0 +0xBDC3 0x77EB # 0 +0xBDC4 0x4FA5 # 0 +0xBDC5 0x811A # 0 +0xBDC6 0x72E1 # 0 +0xBDC7 0x89D2 # 0 +0xBDC8 0x997A # 0 +0xBDC9 0x7F34 # 0 +0xBDCA 0x7EDE # 0 +0xBDCB 0x527F # 0 +0xBDCC 0x6559 # 0 +0xBDCD 0x9175 # 0 +0xBDCE 0x8F7F # 0 +0xBDCF 0x8F83 # 0 +0xBDD0 0x53EB # 0 +0xBDD1 0x7A96 # 0 +0xBDD2 0x63ED # 0 +0xBDD3 0x63A5 # 0 +0xBDD4 0x7686 # 0 +0xBDD5 0x79F8 # 0 +0xBDD6 0x8857 # 0 +0xBDD7 0x9636 # 0 +0xBDD8 0x622A # 0 +0xBDD9 0x52AB # 0 +0xBDDA 0x8282 # 0 +0xBDDB 0x6854 # 0 +0xBDDC 0x6770 # 0 +0xBDDD 0x6377 # 0 +0xBDDE 0x776B # 0 +0xBDDF 0x7AED # 0 +0xBDE0 0x6D01 # 0 +0xBDE1 0x7ED3 # 0 +0xBDE2 0x89E3 # 0 +0xBDE3 0x59D0 # 0 +0xBDE4 0x6212 # 0 +0xBDE5 0x85C9 # 0 +0xBDE6 0x82A5 # 0 +0xBDE7 0x754C # 0 +0xBDE8 0x501F # 0 +0xBDE9 0x4ECB # 0 +0xBDEA 0x75A5 # 0 +0xBDEB 0x8BEB # 0 +0xBDEC 0x5C4A # 0 +0xBDED 0x5DFE # 0 +0xBDEE 0x7B4B # 0 +0xBDEF 0x65A4 # 0 +0xBDF0 0x91D1 # 0 +0xBDF1 0x4ECA # 0 +0xBDF2 0x6D25 # 0 +0xBDF3 0x895F # 0 +0xBDF4 0x7D27 # 0 +0xBDF5 0x9526 # 0 +0xBDF6 0x4EC5 # 0 +0xBDF7 0x8C28 # 0 +0xBDF8 0x8FDB # 0 +0xBDF9 0x9773 # 0 +0xBDFA 0x664B # 0 +0xBDFB 0x7981 # 0 +0xBDFC 0x8FD1 # 0 +0xBDFD 0x70EC # 0 +0xBDFE 0x6D78 # 0 +0xBE40 0x7D99 # 0 +0xBE41 0x7D9A # 0 +0xBE42 0x7D9B # 0 +0xBE43 0x7D9C # 0 +0xBE44 0x7D9D # 0 +0xBE45 0x7D9E # 0 +0xBE46 0x7D9F # 0 +0xBE47 0x7DA0 # 0 +0xBE48 0x7DA1 # 0 +0xBE49 0x7DA2 # 0 +0xBE4A 0x7DA3 # 0 +0xBE4B 0x7DA4 # 0 +0xBE4C 0x7DA5 # 0 +0xBE4D 0x7DA7 # 0 +0xBE4E 0x7DA8 # 0 +0xBE4F 0x7DA9 # 0 +0xBE50 0x7DAA # 0 +0xBE51 0x7DAB # 0 +0xBE52 0x7DAC # 0 +0xBE53 0x7DAD # 0 +0xBE54 0x7DAF # 0 +0xBE55 0x7DB0 # 0 +0xBE56 0x7DB1 # 0 +0xBE57 0x7DB2 # 0 +0xBE58 0x7DB3 # 0 +0xBE59 0x7DB4 # 0 +0xBE5A 0x7DB5 # 0 +0xBE5B 0x7DB6 # 0 +0xBE5C 0x7DB7 # 0 +0xBE5D 0x7DB8 # 0 +0xBE5E 0x7DB9 # 0 +0xBE5F 0x7DBA # 0 +0xBE60 0x7DBB # 0 +0xBE61 0x7DBC # 0 +0xBE62 0x7DBD # 0 +0xBE63 0x7DBE # 0 +0xBE64 0x7DBF # 0 +0xBE65 0x7DC0 # 0 +0xBE66 0x7DC1 # 0 +0xBE67 0x7DC2 # 0 +0xBE68 0x7DC3 # 0 +0xBE69 0x7DC4 # 0 +0xBE6A 0x7DC5 # 0 +0xBE6B 0x7DC6 # 0 +0xBE6C 0x7DC7 # 0 +0xBE6D 0x7DC8 # 0 +0xBE6E 0x7DC9 # 0 +0xBE6F 0x7DCA # 0 +0xBE70 0x7DCB # 0 +0xBE71 0x7DCC # 0 +0xBE72 0x7DCD # 0 +0xBE73 0x7DCE # 0 +0xBE74 0x7DCF # 0 +0xBE75 0x7DD0 # 0 +0xBE76 0x7DD1 # 0 +0xBE77 0x7DD2 # 0 +0xBE78 0x7DD3 # 0 +0xBE79 0x7DD4 # 0 +0xBE7A 0x7DD5 # 0 +0xBE7B 0x7DD6 # 0 +0xBE7C 0x7DD7 # 0 +0xBE7D 0x7DD8 # 0 +0xBE7E 0x7DD9 # 0 +0xBE80 0x7DDA # 0 +0xBE81 0x7DDB # 0 +0xBE82 0x7DDC # 0 +0xBE83 0x7DDD # 0 +0xBE84 0x7DDE # 0 +0xBE85 0x7DDF # 0 +0xBE86 0x7DE0 # 0 +0xBE87 0x7DE1 # 0 +0xBE88 0x7DE2 # 0 +0xBE89 0x7DE3 # 0 +0xBE8A 0x7DE4 # 0 +0xBE8B 0x7DE5 # 0 +0xBE8C 0x7DE6 # 0 +0xBE8D 0x7DE7 # 0 +0xBE8E 0x7DE8 # 0 +0xBE8F 0x7DE9 # 0 +0xBE90 0x7DEA # 0 +0xBE91 0x7DEB # 0 +0xBE92 0x7DEC # 0 +0xBE93 0x7DED # 0 +0xBE94 0x7DEE # 0 +0xBE95 0x7DEF # 0 +0xBE96 0x7DF0 # 0 +0xBE97 0x7DF1 # 0 +0xBE98 0x7DF2 # 0 +0xBE99 0x7DF3 # 0 +0xBE9A 0x7DF4 # 0 +0xBE9B 0x7DF5 # 0 +0xBE9C 0x7DF6 # 0 +0xBE9D 0x7DF7 # 0 +0xBE9E 0x7DF8 # 0 +0xBE9F 0x7DF9 # 0 +0xBEA0 0x7DFA # 0 +0xBEA1 0x5C3D # 0 +0xBEA2 0x52B2 # 0 +0xBEA3 0x8346 # 0 +0xBEA4 0x5162 # 0 +0xBEA5 0x830E # 0 +0xBEA6 0x775B # 0 +0xBEA7 0x6676 # 0 +0xBEA8 0x9CB8 # 0 +0xBEA9 0x4EAC # 0 +0xBEAA 0x60CA # 0 +0xBEAB 0x7CBE # 0 +0xBEAC 0x7CB3 # 0 +0xBEAD 0x7ECF # 0 +0xBEAE 0x4E95 # 0 +0xBEAF 0x8B66 # 0 +0xBEB0 0x666F # 0 +0xBEB1 0x9888 # 0 +0xBEB2 0x9759 # 0 +0xBEB3 0x5883 # 0 +0xBEB4 0x656C # 0 +0xBEB5 0x955C # 0 +0xBEB6 0x5F84 # 0 +0xBEB7 0x75C9 # 0 +0xBEB8 0x9756 # 0 +0xBEB9 0x7ADF # 0 +0xBEBA 0x7ADE # 0 +0xBEBB 0x51C0 # 0 +0xBEBC 0x70AF # 0 +0xBEBD 0x7A98 # 0 +0xBEBE 0x63EA # 0 +0xBEBF 0x7A76 # 0 +0xBEC0 0x7EA0 # 0 +0xBEC1 0x7396 # 0 +0xBEC2 0x97ED # 0 +0xBEC3 0x4E45 # 0 +0xBEC4 0x7078 # 0 +0xBEC5 0x4E5D # 0 +0xBEC6 0x9152 # 0 +0xBEC7 0x53A9 # 0 +0xBEC8 0x6551 # 0 +0xBEC9 0x65E7 # 0 +0xBECA 0x81FC # 0 +0xBECB 0x8205 # 0 +0xBECC 0x548E # 0 +0xBECD 0x5C31 # 0 +0xBECE 0x759A # 0 +0xBECF 0x97A0 # 0 +0xBED0 0x62D8 # 0 +0xBED1 0x72D9 # 0 +0xBED2 0x75BD # 0 +0xBED3 0x5C45 # 0 +0xBED4 0x9A79 # 0 +0xBED5 0x83CA # 0 +0xBED6 0x5C40 # 0 +0xBED7 0x5480 # 0 +0xBED8 0x77E9 # 0 +0xBED9 0x4E3E # 0 +0xBEDA 0x6CAE # 0 +0xBEDB 0x805A # 0 +0xBEDC 0x62D2 # 0 +0xBEDD 0x636E # 0 +0xBEDE 0x5DE8 # 0 +0xBEDF 0x5177 # 0 +0xBEE0 0x8DDD # 0 +0xBEE1 0x8E1E # 0 +0xBEE2 0x952F # 0 +0xBEE3 0x4FF1 # 0 +0xBEE4 0x53E5 # 0 +0xBEE5 0x60E7 # 0 +0xBEE6 0x70AC # 0 +0xBEE7 0x5267 # 0 +0xBEE8 0x6350 # 0 +0xBEE9 0x9E43 # 0 +0xBEEA 0x5A1F # 0 +0xBEEB 0x5026 # 0 +0xBEEC 0x7737 # 0 +0xBEED 0x5377 # 0 +0xBEEE 0x7EE2 # 0 +0xBEEF 0x6485 # 0 +0xBEF0 0x652B # 0 +0xBEF1 0x6289 # 0 +0xBEF2 0x6398 # 0 +0xBEF3 0x5014 # 0 +0xBEF4 0x7235 # 0 +0xBEF5 0x89C9 # 0 +0xBEF6 0x51B3 # 0 +0xBEF7 0x8BC0 # 0 +0xBEF8 0x7EDD # 0 +0xBEF9 0x5747 # 0 +0xBEFA 0x83CC # 0 +0xBEFB 0x94A7 # 0 +0xBEFC 0x519B # 0 +0xBEFD 0x541B # 0 +0xBEFE 0x5CFB # 0 +0xBF40 0x7DFB # 0 +0xBF41 0x7DFC # 0 +0xBF42 0x7DFD # 0 +0xBF43 0x7DFE # 0 +0xBF44 0x7DFF # 0 +0xBF45 0x7E00 # 0 +0xBF46 0x7E01 # 0 +0xBF47 0x7E02 # 0 +0xBF48 0x7E03 # 0 +0xBF49 0x7E04 # 0 +0xBF4A 0x7E05 # 0 +0xBF4B 0x7E06 # 0 +0xBF4C 0x7E07 # 0 +0xBF4D 0x7E08 # 0 +0xBF4E 0x7E09 # 0 +0xBF4F 0x7E0A # 0 +0xBF50 0x7E0B # 0 +0xBF51 0x7E0C # 0 +0xBF52 0x7E0D # 0 +0xBF53 0x7E0E # 0 +0xBF54 0x7E0F # 0 +0xBF55 0x7E10 # 0 +0xBF56 0x7E11 # 0 +0xBF57 0x7E12 # 0 +0xBF58 0x7E13 # 0 +0xBF59 0x7E14 # 0 +0xBF5A 0x7E15 # 0 +0xBF5B 0x7E16 # 0 +0xBF5C 0x7E17 # 0 +0xBF5D 0x7E18 # 0 +0xBF5E 0x7E19 # 0 +0xBF5F 0x7E1A # 0 +0xBF60 0x7E1B # 0 +0xBF61 0x7E1C # 0 +0xBF62 0x7E1D # 0 +0xBF63 0x7E1E # 0 +0xBF64 0x7E1F # 0 +0xBF65 0x7E20 # 0 +0xBF66 0x7E21 # 0 +0xBF67 0x7E22 # 0 +0xBF68 0x7E23 # 0 +0xBF69 0x7E24 # 0 +0xBF6A 0x7E25 # 0 +0xBF6B 0x7E26 # 0 +0xBF6C 0x7E27 # 0 +0xBF6D 0x7E28 # 0 +0xBF6E 0x7E29 # 0 +0xBF6F 0x7E2A # 0 +0xBF70 0x7E2B # 0 +0xBF71 0x7E2C # 0 +0xBF72 0x7E2D # 0 +0xBF73 0x7E2E # 0 +0xBF74 0x7E2F # 0 +0xBF75 0x7E30 # 0 +0xBF76 0x7E31 # 0 +0xBF77 0x7E32 # 0 +0xBF78 0x7E33 # 0 +0xBF79 0x7E34 # 0 +0xBF7A 0x7E35 # 0 +0xBF7B 0x7E36 # 0 +0xBF7C 0x7E37 # 0 +0xBF7D 0x7E38 # 0 +0xBF7E 0x7E39 # 0 +0xBF80 0x7E3A # 0 +0xBF81 0x7E3C # 0 +0xBF82 0x7E3D # 0 +0xBF83 0x7E3E # 0 +0xBF84 0x7E3F # 0 +0xBF85 0x7E40 # 0 +0xBF86 0x7E42 # 0 +0xBF87 0x7E43 # 0 +0xBF88 0x7E44 # 0 +0xBF89 0x7E45 # 0 +0xBF8A 0x7E46 # 0 +0xBF8B 0x7E48 # 0 +0xBF8C 0x7E49 # 0 +0xBF8D 0x7E4A # 0 +0xBF8E 0x7E4B # 0 +0xBF8F 0x7E4C # 0 +0xBF90 0x7E4D # 0 +0xBF91 0x7E4E # 0 +0xBF92 0x7E4F # 0 +0xBF93 0x7E50 # 0 +0xBF94 0x7E51 # 0 +0xBF95 0x7E52 # 0 +0xBF96 0x7E53 # 0 +0xBF97 0x7E54 # 0 +0xBF98 0x7E55 # 0 +0xBF99 0x7E56 # 0 +0xBF9A 0x7E57 # 0 +0xBF9B 0x7E58 # 0 +0xBF9C 0x7E59 # 0 +0xBF9D 0x7E5A # 0 +0xBF9E 0x7E5B # 0 +0xBF9F 0x7E5C # 0 +0xBFA0 0x7E5D # 0 +0xBFA1 0x4FCA # 0 +0xBFA2 0x7AE3 # 0 +0xBFA3 0x6D5A # 0 +0xBFA4 0x90E1 # 0 +0xBFA5 0x9A8F # 0 +0xBFA6 0x5580 # 0 +0xBFA7 0x5496 # 0 +0xBFA8 0x5361 # 0 +0xBFA9 0x54AF # 0 +0xBFAA 0x5F00 # 0 +0xBFAB 0x63E9 # 0 +0xBFAC 0x6977 # 0 +0xBFAD 0x51EF # 0 +0xBFAE 0x6168 # 0 +0xBFAF 0x520A # 0 +0xBFB0 0x582A # 0 +0xBFB1 0x52D8 # 0 +0xBFB2 0x574E # 0 +0xBFB3 0x780D # 0 +0xBFB4 0x770B # 0 +0xBFB5 0x5EB7 # 0 +0xBFB6 0x6177 # 0 +0xBFB7 0x7CE0 # 0 +0xBFB8 0x625B # 0 +0xBFB9 0x6297 # 0 +0xBFBA 0x4EA2 # 0 +0xBFBB 0x7095 # 0 +0xBFBC 0x8003 # 0 +0xBFBD 0x62F7 # 0 +0xBFBE 0x70E4 # 0 +0xBFBF 0x9760 # 0 +0xBFC0 0x5777 # 0 +0xBFC1 0x82DB # 0 +0xBFC2 0x67EF # 0 +0xBFC3 0x68F5 # 0 +0xBFC4 0x78D5 # 0 +0xBFC5 0x9897 # 0 +0xBFC6 0x79D1 # 0 +0xBFC7 0x58F3 # 0 +0xBFC8 0x54B3 # 0 +0xBFC9 0x53EF # 0 +0xBFCA 0x6E34 # 0 +0xBFCB 0x514B # 0 +0xBFCC 0x523B # 0 +0xBFCD 0x5BA2 # 0 +0xBFCE 0x8BFE # 0 +0xBFCF 0x80AF # 0 +0xBFD0 0x5543 # 0 +0xBFD1 0x57A6 # 0 +0xBFD2 0x6073 # 0 +0xBFD3 0x5751 # 0 +0xBFD4 0x542D # 0 +0xBFD5 0x7A7A # 0 +0xBFD6 0x6050 # 0 +0xBFD7 0x5B54 # 0 +0xBFD8 0x63A7 # 0 +0xBFD9 0x62A0 # 0 +0xBFDA 0x53E3 # 0 +0xBFDB 0x6263 # 0 +0xBFDC 0x5BC7 # 0 +0xBFDD 0x67AF # 0 +0xBFDE 0x54ED # 0 +0xBFDF 0x7A9F # 0 +0xBFE0 0x82E6 # 0 +0xBFE1 0x9177 # 0 +0xBFE2 0x5E93 # 0 +0xBFE3 0x88E4 # 0 +0xBFE4 0x5938 # 0 +0xBFE5 0x57AE # 0 +0xBFE6 0x630E # 0 +0xBFE7 0x8DE8 # 0 +0xBFE8 0x80EF # 0 +0xBFE9 0x5757 # 0 +0xBFEA 0x7B77 # 0 +0xBFEB 0x4FA9 # 0 +0xBFEC 0x5FEB # 0 +0xBFED 0x5BBD # 0 +0xBFEE 0x6B3E # 0 +0xBFEF 0x5321 # 0 +0xBFF0 0x7B50 # 0 +0xBFF1 0x72C2 # 0 +0xBFF2 0x6846 # 0 +0xBFF3 0x77FF # 0 +0xBFF4 0x7736 # 0 +0xBFF5 0x65F7 # 0 +0xBFF6 0x51B5 # 0 +0xBFF7 0x4E8F # 0 +0xBFF8 0x76D4 # 0 +0xBFF9 0x5CBF # 0 +0xBFFA 0x7AA5 # 0 +0xBFFB 0x8475 # 0 +0xBFFC 0x594E # 0 +0xBFFD 0x9B41 # 0 +0xBFFE 0x5080 # 0 +0xC040 0x7E5E # 0 +0xC041 0x7E5F # 0 +0xC042 0x7E60 # 0 +0xC043 0x7E61 # 0 +0xC044 0x7E62 # 0 +0xC045 0x7E63 # 0 +0xC046 0x7E64 # 0 +0xC047 0x7E65 # 0 +0xC048 0x7E66 # 0 +0xC049 0x7E67 # 0 +0xC04A 0x7E68 # 0 +0xC04B 0x7E69 # 0 +0xC04C 0x7E6A # 0 +0xC04D 0x7E6B # 0 +0xC04E 0x7E6C # 0 +0xC04F 0x7E6D # 0 +0xC050 0x7E6E # 0 +0xC051 0x7E6F # 0 +0xC052 0x7E70 # 0 +0xC053 0x7E71 # 0 +0xC054 0x7E72 # 0 +0xC055 0x7E73 # 0 +0xC056 0x7E74 # 0 +0xC057 0x7E75 # 0 +0xC058 0x7E76 # 0 +0xC059 0x7E77 # 0 +0xC05A 0x7E78 # 0 +0xC05B 0x7E79 # 0 +0xC05C 0x7E7A # 0 +0xC05D 0x7E7B # 0 +0xC05E 0x7E7C # 0 +0xC05F 0x7E7D # 0 +0xC060 0x7E7E # 0 +0xC061 0x7E7F # 0 +0xC062 0x7E80 # 0 +0xC063 0x7E81 # 0 +0xC064 0x7E83 # 0 +0xC065 0x7E84 # 0 +0xC066 0x7E85 # 0 +0xC067 0x7E86 # 0 +0xC068 0x7E87 # 0 +0xC069 0x7E88 # 0 +0xC06A 0x7E89 # 0 +0xC06B 0x7E8A # 0 +0xC06C 0x7E8B # 0 +0xC06D 0x7E8C # 0 +0xC06E 0x7E8D # 0 +0xC06F 0x7E8E # 0 +0xC070 0x7E8F # 0 +0xC071 0x7E90 # 0 +0xC072 0x7E91 # 0 +0xC073 0x7E92 # 0 +0xC074 0x7E93 # 0 +0xC075 0x7E94 # 0 +0xC076 0x7E95 # 0 +0xC077 0x7E96 # 0 +0xC078 0x7E97 # 0 +0xC079 0x7E98 # 0 +0xC07A 0x7E99 # 0 +0xC07B 0x7E9A # 0 +0xC07C 0x7E9C # 0 +0xC07D 0x7E9D # 0 +0xC07E 0x7E9E # 0 +0xC080 0x7EAE # 0 +0xC081 0x7EB4 # 0 +0xC082 0x7EBB # 0 +0xC083 0x7EBC # 0 +0xC084 0x7ED6 # 0 +0xC085 0x7EE4 # 0 +0xC086 0x7EEC # 0 +0xC087 0x7EF9 # 0 +0xC088 0x7F0A # 0 +0xC089 0x7F10 # 0 +0xC08A 0x7F1E # 0 +0xC08B 0x7F37 # 0 +0xC08C 0x7F39 # 0 +0xC08D 0x7F3B # 0 +0xC08E 0x7F3C # 0 +0xC08F 0x7F3D # 0 +0xC090 0x7F3E # 0 +0xC091 0x7F3F # 0 +0xC092 0x7F40 # 0 +0xC093 0x7F41 # 0 +0xC094 0x7F43 # 0 +0xC095 0x7F46 # 0 +0xC096 0x7F47 # 0 +0xC097 0x7F48 # 0 +0xC098 0x7F49 # 0 +0xC099 0x7F4A # 0 +0xC09A 0x7F4B # 0 +0xC09B 0x7F4C # 0 +0xC09C 0x7F4D # 0 +0xC09D 0x7F4E # 0 +0xC09E 0x7F4F # 0 +0xC09F 0x7F52 # 0 +0xC0A0 0x7F53 # 0 +0xC0A1 0x9988 # 0 +0xC0A2 0x6127 # 0 +0xC0A3 0x6E83 # 0 +0xC0A4 0x5764 # 0 +0xC0A5 0x6606 # 0 +0xC0A6 0x6346 # 0 +0xC0A7 0x56F0 # 0 +0xC0A8 0x62EC # 0 +0xC0A9 0x6269 # 0 +0xC0AA 0x5ED3 # 0 +0xC0AB 0x9614 # 0 +0xC0AC 0x5783 # 0 +0xC0AD 0x62C9 # 0 +0xC0AE 0x5587 # 0 +0xC0AF 0x8721 # 0 +0xC0B0 0x814A # 0 +0xC0B1 0x8FA3 # 0 +0xC0B2 0x5566 # 0 +0xC0B3 0x83B1 # 0 +0xC0B4 0x6765 # 0 +0xC0B5 0x8D56 # 0 +0xC0B6 0x84DD # 0 +0xC0B7 0x5A6A # 0 +0xC0B8 0x680F # 0 +0xC0B9 0x62E6 # 0 +0xC0BA 0x7BEE # 0 +0xC0BB 0x9611 # 0 +0xC0BC 0x5170 # 0 +0xC0BD 0x6F9C # 0 +0xC0BE 0x8C30 # 0 +0xC0BF 0x63FD # 0 +0xC0C0 0x89C8 # 0 +0xC0C1 0x61D2 # 0 +0xC0C2 0x7F06 # 0 +0xC0C3 0x70C2 # 0 +0xC0C4 0x6EE5 # 0 +0xC0C5 0x7405 # 0 +0xC0C6 0x6994 # 0 +0xC0C7 0x72FC # 0 +0xC0C8 0x5ECA # 0 +0xC0C9 0x90CE # 0 +0xC0CA 0x6717 # 0 +0xC0CB 0x6D6A # 0 +0xC0CC 0x635E # 0 +0xC0CD 0x52B3 # 0 +0xC0CE 0x7262 # 0 +0xC0CF 0x8001 # 0 +0xC0D0 0x4F6C # 0 +0xC0D1 0x59E5 # 0 +0xC0D2 0x916A # 0 +0xC0D3 0x70D9 # 0 +0xC0D4 0x6D9D # 0 +0xC0D5 0x52D2 # 0 +0xC0D6 0x4E50 # 0 +0xC0D7 0x96F7 # 0 +0xC0D8 0x956D # 0 +0xC0D9 0x857E # 0 +0xC0DA 0x78CA # 0 +0xC0DB 0x7D2F # 0 +0xC0DC 0x5121 # 0 +0xC0DD 0x5792 # 0 +0xC0DE 0x64C2 # 0 +0xC0DF 0x808B # 0 +0xC0E0 0x7C7B # 0 +0xC0E1 0x6CEA # 0 +0xC0E2 0x68F1 # 0 +0xC0E3 0x695E # 0 +0xC0E4 0x51B7 # 0 +0xC0E5 0x5398 # 0 +0xC0E6 0x68A8 # 0 +0xC0E7 0x7281 # 0 +0xC0E8 0x9ECE # 0 +0xC0E9 0x7BF1 # 0 +0xC0EA 0x72F8 # 0 +0xC0EB 0x79BB # 0 +0xC0EC 0x6F13 # 0 +0xC0ED 0x7406 # 0 +0xC0EE 0x674E # 0 +0xC0EF 0x91CC # 0 +0xC0F0 0x9CA4 # 0 +0xC0F1 0x793C # 0 +0xC0F2 0x8389 # 0 +0xC0F3 0x8354 # 0 +0xC0F4 0x540F # 0 +0xC0F5 0x6817 # 0 +0xC0F6 0x4E3D # 0 +0xC0F7 0x5389 # 0 +0xC0F8 0x52B1 # 0 +0xC0F9 0x783E # 0 +0xC0FA 0x5386 # 0 +0xC0FB 0x5229 # 0 +0xC0FC 0x5088 # 0 +0xC0FD 0x4F8B # 0 +0xC0FE 0x4FD0 # 0 +0xC140 0x7F56 # 0 +0xC141 0x7F59 # 0 +0xC142 0x7F5B # 0 +0xC143 0x7F5C # 0 +0xC144 0x7F5D # 0 +0xC145 0x7F5E # 0 +0xC146 0x7F60 # 0 +0xC147 0x7F63 # 0 +0xC148 0x7F64 # 0 +0xC149 0x7F65 # 0 +0xC14A 0x7F66 # 0 +0xC14B 0x7F67 # 0 +0xC14C 0x7F6B # 0 +0xC14D 0x7F6C # 0 +0xC14E 0x7F6D # 0 +0xC14F 0x7F6F # 0 +0xC150 0x7F70 # 0 +0xC151 0x7F73 # 0 +0xC152 0x7F75 # 0 +0xC153 0x7F76 # 0 +0xC154 0x7F77 # 0 +0xC155 0x7F78 # 0 +0xC156 0x7F7A # 0 +0xC157 0x7F7B # 0 +0xC158 0x7F7C # 0 +0xC159 0x7F7D # 0 +0xC15A 0x7F7F # 0 +0xC15B 0x7F80 # 0 +0xC15C 0x7F82 # 0 +0xC15D 0x7F83 # 0 +0xC15E 0x7F84 # 0 +0xC15F 0x7F85 # 0 +0xC160 0x7F86 # 0 +0xC161 0x7F87 # 0 +0xC162 0x7F88 # 0 +0xC163 0x7F89 # 0 +0xC164 0x7F8B # 0 +0xC165 0x7F8D # 0 +0xC166 0x7F8F # 0 +0xC167 0x7F90 # 0 +0xC168 0x7F91 # 0 +0xC169 0x7F92 # 0 +0xC16A 0x7F93 # 0 +0xC16B 0x7F95 # 0 +0xC16C 0x7F96 # 0 +0xC16D 0x7F97 # 0 +0xC16E 0x7F98 # 0 +0xC16F 0x7F99 # 0 +0xC170 0x7F9B # 0 +0xC171 0x7F9C # 0 +0xC172 0x7FA0 # 0 +0xC173 0x7FA2 # 0 +0xC174 0x7FA3 # 0 +0xC175 0x7FA5 # 0 +0xC176 0x7FA6 # 0 +0xC177 0x7FA8 # 0 +0xC178 0x7FA9 # 0 +0xC179 0x7FAA # 0 +0xC17A 0x7FAB # 0 +0xC17B 0x7FAC # 0 +0xC17C 0x7FAD # 0 +0xC17D 0x7FAE # 0 +0xC17E 0x7FB1 # 0 +0xC180 0x7FB3 # 0 +0xC181 0x7FB4 # 0 +0xC182 0x7FB5 # 0 +0xC183 0x7FB6 # 0 +0xC184 0x7FB7 # 0 +0xC185 0x7FBA # 0 +0xC186 0x7FBB # 0 +0xC187 0x7FBE # 0 +0xC188 0x7FC0 # 0 +0xC189 0x7FC2 # 0 +0xC18A 0x7FC3 # 0 +0xC18B 0x7FC4 # 0 +0xC18C 0x7FC6 # 0 +0xC18D 0x7FC7 # 0 +0xC18E 0x7FC8 # 0 +0xC18F 0x7FC9 # 0 +0xC190 0x7FCB # 0 +0xC191 0x7FCD # 0 +0xC192 0x7FCF # 0 +0xC193 0x7FD0 # 0 +0xC194 0x7FD1 # 0 +0xC195 0x7FD2 # 0 +0xC196 0x7FD3 # 0 +0xC197 0x7FD6 # 0 +0xC198 0x7FD7 # 0 +0xC199 0x7FD9 # 0 +0xC19A 0x7FDA # 0 +0xC19B 0x7FDB # 0 +0xC19C 0x7FDC # 0 +0xC19D 0x7FDD # 0 +0xC19E 0x7FDE # 0 +0xC19F 0x7FE2 # 0 +0xC1A0 0x7FE3 # 0 +0xC1A1 0x75E2 # 0 +0xC1A2 0x7ACB # 0 +0xC1A3 0x7C92 # 0 +0xC1A4 0x6CA5 # 0 +0xC1A5 0x96B6 # 0 +0xC1A6 0x529B # 0 +0xC1A7 0x7483 # 0 +0xC1A8 0x54E9 # 0 +0xC1A9 0x4FE9 # 0 +0xC1AA 0x8054 # 0 +0xC1AB 0x83B2 # 0 +0xC1AC 0x8FDE # 0 +0xC1AD 0x9570 # 0 +0xC1AE 0x5EC9 # 0 +0xC1AF 0x601C # 0 +0xC1B0 0x6D9F # 0 +0xC1B1 0x5E18 # 0 +0xC1B2 0x655B # 0 +0xC1B3 0x8138 # 0 +0xC1B4 0x94FE # 0 +0xC1B5 0x604B # 0 +0xC1B6 0x70BC # 0 +0xC1B7 0x7EC3 # 0 +0xC1B8 0x7CAE # 0 +0xC1B9 0x51C9 # 0 +0xC1BA 0x6881 # 0 +0xC1BB 0x7CB1 # 0 +0xC1BC 0x826F # 0 +0xC1BD 0x4E24 # 0 +0xC1BE 0x8F86 # 0 +0xC1BF 0x91CF # 0 +0xC1C0 0x667E # 0 +0xC1C1 0x4EAE # 0 +0xC1C2 0x8C05 # 0 +0xC1C3 0x64A9 # 0 +0xC1C4 0x804A # 0 +0xC1C5 0x50DA # 0 +0xC1C6 0x7597 # 0 +0xC1C7 0x71CE # 0 +0xC1C8 0x5BE5 # 0 +0xC1C9 0x8FBD # 0 +0xC1CA 0x6F66 # 0 +0xC1CB 0x4E86 # 0 +0xC1CC 0x6482 # 0 +0xC1CD 0x9563 # 0 +0xC1CE 0x5ED6 # 0 +0xC1CF 0x6599 # 0 +0xC1D0 0x5217 # 0 +0xC1D1 0x88C2 # 0 +0xC1D2 0x70C8 # 0 +0xC1D3 0x52A3 # 0 +0xC1D4 0x730E # 0 +0xC1D5 0x7433 # 0 +0xC1D6 0x6797 # 0 +0xC1D7 0x78F7 # 0 +0xC1D8 0x9716 # 0 +0xC1D9 0x4E34 # 0 +0xC1DA 0x90BB # 0 +0xC1DB 0x9CDE # 0 +0xC1DC 0x6DCB # 0 +0xC1DD 0x51DB # 0 +0xC1DE 0x8D41 # 0 +0xC1DF 0x541D # 0 +0xC1E0 0x62CE # 0 +0xC1E1 0x73B2 # 0 +0xC1E2 0x83F1 # 0 +0xC1E3 0x96F6 # 0 +0xC1E4 0x9F84 # 0 +0xC1E5 0x94C3 # 0 +0xC1E6 0x4F36 # 0 +0xC1E7 0x7F9A # 0 +0xC1E8 0x51CC # 0 +0xC1E9 0x7075 # 0 +0xC1EA 0x9675 # 0 +0xC1EB 0x5CAD # 0 +0xC1EC 0x9886 # 0 +0xC1ED 0x53E6 # 0 +0xC1EE 0x4EE4 # 0 +0xC1EF 0x6E9C # 0 +0xC1F0 0x7409 # 0 +0xC1F1 0x69B4 # 0 +0xC1F2 0x786B # 0 +0xC1F3 0x998F # 0 +0xC1F4 0x7559 # 0 +0xC1F5 0x5218 # 0 +0xC1F6 0x7624 # 0 +0xC1F7 0x6D41 # 0 +0xC1F8 0x67F3 # 0 +0xC1F9 0x516D # 0 +0xC1FA 0x9F99 # 0 +0xC1FB 0x804B # 0 +0xC1FC 0x5499 # 0 +0xC1FD 0x7B3C # 0 +0xC1FE 0x7ABF # 0 +0xC240 0x7FE4 # 0 +0xC241 0x7FE7 # 0 +0xC242 0x7FE8 # 0 +0xC243 0x7FEA # 0 +0xC244 0x7FEB # 0 +0xC245 0x7FEC # 0 +0xC246 0x7FED # 0 +0xC247 0x7FEF # 0 +0xC248 0x7FF2 # 0 +0xC249 0x7FF4 # 0 +0xC24A 0x7FF5 # 0 +0xC24B 0x7FF6 # 0 +0xC24C 0x7FF7 # 0 +0xC24D 0x7FF8 # 0 +0xC24E 0x7FF9 # 0 +0xC24F 0x7FFA # 0 +0xC250 0x7FFD # 0 +0xC251 0x7FFE # 0 +0xC252 0x7FFF # 0 +0xC253 0x8002 # 0 +0xC254 0x8007 # 0 +0xC255 0x8008 # 0 +0xC256 0x8009 # 0 +0xC257 0x800A # 0 +0xC258 0x800E # 0 +0xC259 0x800F # 0 +0xC25A 0x8011 # 0 +0xC25B 0x8013 # 0 +0xC25C 0x801A # 0 +0xC25D 0x801B # 0 +0xC25E 0x801D # 0 +0xC25F 0x801E # 0 +0xC260 0x801F # 0 +0xC261 0x8021 # 0 +0xC262 0x8023 # 0 +0xC263 0x8024 # 0 +0xC264 0x802B # 0 +0xC265 0x802C # 0 +0xC266 0x802D # 0 +0xC267 0x802E # 0 +0xC268 0x802F # 0 +0xC269 0x8030 # 0 +0xC26A 0x8032 # 0 +0xC26B 0x8034 # 0 +0xC26C 0x8039 # 0 +0xC26D 0x803A # 0 +0xC26E 0x803C # 0 +0xC26F 0x803E # 0 +0xC270 0x8040 # 0 +0xC271 0x8041 # 0 +0xC272 0x8044 # 0 +0xC273 0x8045 # 0 +0xC274 0x8047 # 0 +0xC275 0x8048 # 0 +0xC276 0x8049 # 0 +0xC277 0x804E # 0 +0xC278 0x804F # 0 +0xC279 0x8050 # 0 +0xC27A 0x8051 # 0 +0xC27B 0x8053 # 0 +0xC27C 0x8055 # 0 +0xC27D 0x8056 # 0 +0xC27E 0x8057 # 0 +0xC280 0x8059 # 0 +0xC281 0x805B # 0 +0xC282 0x805C # 0 +0xC283 0x805D # 0 +0xC284 0x805E # 0 +0xC285 0x805F # 0 +0xC286 0x8060 # 0 +0xC287 0x8061 # 0 +0xC288 0x8062 # 0 +0xC289 0x8063 # 0 +0xC28A 0x8064 # 0 +0xC28B 0x8065 # 0 +0xC28C 0x8066 # 0 +0xC28D 0x8067 # 0 +0xC28E 0x8068 # 0 +0xC28F 0x806B # 0 +0xC290 0x806C # 0 +0xC291 0x806D # 0 +0xC292 0x806E # 0 +0xC293 0x806F # 0 +0xC294 0x8070 # 0 +0xC295 0x8072 # 0 +0xC296 0x8073 # 0 +0xC297 0x8074 # 0 +0xC298 0x8075 # 0 +0xC299 0x8076 # 0 +0xC29A 0x8077 # 0 +0xC29B 0x8078 # 0 +0xC29C 0x8079 # 0 +0xC29D 0x807A # 0 +0xC29E 0x807B # 0 +0xC29F 0x807C # 0 +0xC2A0 0x807D # 0 +0xC2A1 0x9686 # 0 +0xC2A2 0x5784 # 0 +0xC2A3 0x62E2 # 0 +0xC2A4 0x9647 # 0 +0xC2A5 0x697C # 0 +0xC2A6 0x5A04 # 0 +0xC2A7 0x6402 # 0 +0xC2A8 0x7BD3 # 0 +0xC2A9 0x6F0F # 0 +0xC2AA 0x964B # 0 +0xC2AB 0x82A6 # 0 +0xC2AC 0x5362 # 0 +0xC2AD 0x9885 # 0 +0xC2AE 0x5E90 # 0 +0xC2AF 0x7089 # 0 +0xC2B0 0x63B3 # 0 +0xC2B1 0x5364 # 0 +0xC2B2 0x864F # 0 +0xC2B3 0x9C81 # 0 +0xC2B4 0x9E93 # 0 +0xC2B5 0x788C # 0 +0xC2B6 0x9732 # 0 +0xC2B7 0x8DEF # 0 +0xC2B8 0x8D42 # 0 +0xC2B9 0x9E7F # 0 +0xC2BA 0x6F5E # 0 +0xC2BB 0x7984 # 0 +0xC2BC 0x5F55 # 0 +0xC2BD 0x9646 # 0 +0xC2BE 0x622E # 0 +0xC2BF 0x9A74 # 0 +0xC2C0 0x5415 # 0 +0xC2C1 0x94DD # 0 +0xC2C2 0x4FA3 # 0 +0xC2C3 0x65C5 # 0 +0xC2C4 0x5C65 # 0 +0xC2C5 0x5C61 # 0 +0xC2C6 0x7F15 # 0 +0xC2C7 0x8651 # 0 +0xC2C8 0x6C2F # 0 +0xC2C9 0x5F8B # 0 +0xC2CA 0x7387 # 0 +0xC2CB 0x6EE4 # 0 +0xC2CC 0x7EFF # 0 +0xC2CD 0x5CE6 # 0 +0xC2CE 0x631B # 0 +0xC2CF 0x5B6A # 0 +0xC2D0 0x6EE6 # 0 +0xC2D1 0x5375 # 0 +0xC2D2 0x4E71 # 0 +0xC2D3 0x63A0 # 0 +0xC2D4 0x7565 # 0 +0xC2D5 0x62A1 # 0 +0xC2D6 0x8F6E # 0 +0xC2D7 0x4F26 # 0 +0xC2D8 0x4ED1 # 0 +0xC2D9 0x6CA6 # 0 +0xC2DA 0x7EB6 # 0 +0xC2DB 0x8BBA # 0 +0xC2DC 0x841D # 0 +0xC2DD 0x87BA # 0 +0xC2DE 0x7F57 # 0 +0xC2DF 0x903B # 0 +0xC2E0 0x9523 # 0 +0xC2E1 0x7BA9 # 0 +0xC2E2 0x9AA1 # 0 +0xC2E3 0x88F8 # 0 +0xC2E4 0x843D # 0 +0xC2E5 0x6D1B # 0 +0xC2E6 0x9A86 # 0 +0xC2E7 0x7EDC # 0 +0xC2E8 0x5988 # 0 +0xC2E9 0x9EBB # 0 +0xC2EA 0x739B # 0 +0xC2EB 0x7801 # 0 +0xC2EC 0x8682 # 0 +0xC2ED 0x9A6C # 0 +0xC2EE 0x9A82 # 0 +0xC2EF 0x561B # 0 +0xC2F0 0x5417 # 0 +0xC2F1 0x57CB # 0 +0xC2F2 0x4E70 # 0 +0xC2F3 0x9EA6 # 0 +0xC2F4 0x5356 # 0 +0xC2F5 0x8FC8 # 0 +0xC2F6 0x8109 # 0 +0xC2F7 0x7792 # 0 +0xC2F8 0x9992 # 0 +0xC2F9 0x86EE # 0 +0xC2FA 0x6EE1 # 0 +0xC2FB 0x8513 # 0 +0xC2FC 0x66FC # 0 +0xC2FD 0x6162 # 0 +0xC2FE 0x6F2B # 0 +0xC340 0x807E # 0 +0xC341 0x8081 # 0 +0xC342 0x8082 # 0 +0xC343 0x8085 # 0 +0xC344 0x8088 # 0 +0xC345 0x808A # 0 +0xC346 0x808D # 0 +0xC347 0x808E # 0 +0xC348 0x808F # 0 +0xC349 0x8090 # 0 +0xC34A 0x8091 # 0 +0xC34B 0x8092 # 0 +0xC34C 0x8094 # 0 +0xC34D 0x8095 # 0 +0xC34E 0x8097 # 0 +0xC34F 0x8099 # 0 +0xC350 0x809E # 0 +0xC351 0x80A3 # 0 +0xC352 0x80A6 # 0 +0xC353 0x80A7 # 0 +0xC354 0x80A8 # 0 +0xC355 0x80AC # 0 +0xC356 0x80B0 # 0 +0xC357 0x80B3 # 0 +0xC358 0x80B5 # 0 +0xC359 0x80B6 # 0 +0xC35A 0x80B8 # 0 +0xC35B 0x80B9 # 0 +0xC35C 0x80BB # 0 +0xC35D 0x80C5 # 0 +0xC35E 0x80C7 # 0 +0xC35F 0x80C8 # 0 +0xC360 0x80C9 # 0 +0xC361 0x80CA # 0 +0xC362 0x80CB # 0 +0xC363 0x80CF # 0 +0xC364 0x80D0 # 0 +0xC365 0x80D1 # 0 +0xC366 0x80D2 # 0 +0xC367 0x80D3 # 0 +0xC368 0x80D4 # 0 +0xC369 0x80D5 # 0 +0xC36A 0x80D8 # 0 +0xC36B 0x80DF # 0 +0xC36C 0x80E0 # 0 +0xC36D 0x80E2 # 0 +0xC36E 0x80E3 # 0 +0xC36F 0x80E6 # 0 +0xC370 0x80EE # 0 +0xC371 0x80F5 # 0 +0xC372 0x80F7 # 0 +0xC373 0x80F9 # 0 +0xC374 0x80FB # 0 +0xC375 0x80FE # 0 +0xC376 0x80FF # 0 +0xC377 0x8100 # 0 +0xC378 0x8101 # 0 +0xC379 0x8103 # 0 +0xC37A 0x8104 # 0 +0xC37B 0x8105 # 0 +0xC37C 0x8107 # 0 +0xC37D 0x8108 # 0 +0xC37E 0x810B # 0 +0xC380 0x810C # 0 +0xC381 0x8115 # 0 +0xC382 0x8117 # 0 +0xC383 0x8119 # 0 +0xC384 0x811B # 0 +0xC385 0x811C # 0 +0xC386 0x811D # 0 +0xC387 0x811F # 0 +0xC388 0x8120 # 0 +0xC389 0x8121 # 0 +0xC38A 0x8122 # 0 +0xC38B 0x8123 # 0 +0xC38C 0x8124 # 0 +0xC38D 0x8125 # 0 +0xC38E 0x8126 # 0 +0xC38F 0x8127 # 0 +0xC390 0x8128 # 0 +0xC391 0x8129 # 0 +0xC392 0x812A # 0 +0xC393 0x812B # 0 +0xC394 0x812D # 0 +0xC395 0x812E # 0 +0xC396 0x8130 # 0 +0xC397 0x8133 # 0 +0xC398 0x8134 # 0 +0xC399 0x8135 # 0 +0xC39A 0x8137 # 0 +0xC39B 0x8139 # 0 +0xC39C 0x813A # 0 +0xC39D 0x813B # 0 +0xC39E 0x813C # 0 +0xC39F 0x813D # 0 +0xC3A0 0x813F # 0 +0xC3A1 0x8C29 # 0 +0xC3A2 0x8292 # 0 +0xC3A3 0x832B # 0 +0xC3A4 0x76F2 # 0 +0xC3A5 0x6C13 # 0 +0xC3A6 0x5FD9 # 0 +0xC3A7 0x83BD # 0 +0xC3A8 0x732B # 0 +0xC3A9 0x8305 # 0 +0xC3AA 0x951A # 0 +0xC3AB 0x6BDB # 0 +0xC3AC 0x77DB # 0 +0xC3AD 0x94C6 # 0 +0xC3AE 0x536F # 0 +0xC3AF 0x8302 # 0 +0xC3B0 0x5192 # 0 +0xC3B1 0x5E3D # 0 +0xC3B2 0x8C8C # 0 +0xC3B3 0x8D38 # 0 +0xC3B4 0x4E48 # 0 +0xC3B5 0x73AB # 0 +0xC3B6 0x679A # 0 +0xC3B7 0x6885 # 0 +0xC3B8 0x9176 # 0 +0xC3B9 0x9709 # 0 +0xC3BA 0x7164 # 0 +0xC3BB 0x6CA1 # 0 +0xC3BC 0x7709 # 0 +0xC3BD 0x5A92 # 0 +0xC3BE 0x9541 # 0 +0xC3BF 0x6BCF # 0 +0xC3C0 0x7F8E # 0 +0xC3C1 0x6627 # 0 +0xC3C2 0x5BD0 # 0 +0xC3C3 0x59B9 # 0 +0xC3C4 0x5A9A # 0 +0xC3C5 0x95E8 # 0 +0xC3C6 0x95F7 # 0 +0xC3C7 0x4EEC # 0 +0xC3C8 0x840C # 0 +0xC3C9 0x8499 # 0 +0xC3CA 0x6AAC # 0 +0xC3CB 0x76DF # 0 +0xC3CC 0x9530 # 0 +0xC3CD 0x731B # 0 +0xC3CE 0x68A6 # 0 +0xC3CF 0x5B5F # 0 +0xC3D0 0x772F # 0 +0xC3D1 0x919A # 0 +0xC3D2 0x9761 # 0 +0xC3D3 0x7CDC # 0 +0xC3D4 0x8FF7 # 0 +0xC3D5 0x8C1C # 0 +0xC3D6 0x5F25 # 0 +0xC3D7 0x7C73 # 0 +0xC3D8 0x79D8 # 0 +0xC3D9 0x89C5 # 0 +0xC3DA 0x6CCC # 0 +0xC3DB 0x871C # 0 +0xC3DC 0x5BC6 # 0 +0xC3DD 0x5E42 # 0 +0xC3DE 0x68C9 # 0 +0xC3DF 0x7720 # 0 +0xC3E0 0x7EF5 # 0 +0xC3E1 0x5195 # 0 +0xC3E2 0x514D # 0 +0xC3E3 0x52C9 # 0 +0xC3E4 0x5A29 # 0 +0xC3E5 0x7F05 # 0 +0xC3E6 0x9762 # 0 +0xC3E7 0x82D7 # 0 +0xC3E8 0x63CF # 0 +0xC3E9 0x7784 # 0 +0xC3EA 0x85D0 # 0 +0xC3EB 0x79D2 # 0 +0xC3EC 0x6E3A # 0 +0xC3ED 0x5E99 # 0 +0xC3EE 0x5999 # 0 +0xC3EF 0x8511 # 0 +0xC3F0 0x706D # 0 +0xC3F1 0x6C11 # 0 +0xC3F2 0x62BF # 0 +0xC3F3 0x76BF # 0 +0xC3F4 0x654F # 0 +0xC3F5 0x60AF # 0 +0xC3F6 0x95FD # 0 +0xC3F7 0x660E # 0 +0xC3F8 0x879F # 0 +0xC3F9 0x9E23 # 0 +0xC3FA 0x94ED # 0 +0xC3FB 0x540D # 0 +0xC3FC 0x547D # 0 +0xC3FD 0x8C2C # 0 +0xC3FE 0x6478 # 0 +0xC440 0x8140 # 0 +0xC441 0x8141 # 0 +0xC442 0x8142 # 0 +0xC443 0x8143 # 0 +0xC444 0x8144 # 0 +0xC445 0x8145 # 0 +0xC446 0x8147 # 0 +0xC447 0x8149 # 0 +0xC448 0x814D # 0 +0xC449 0x814E # 0 +0xC44A 0x814F # 0 +0xC44B 0x8152 # 0 +0xC44C 0x8156 # 0 +0xC44D 0x8157 # 0 +0xC44E 0x8158 # 0 +0xC44F 0x815B # 0 +0xC450 0x815C # 0 +0xC451 0x815D # 0 +0xC452 0x815E # 0 +0xC453 0x815F # 0 +0xC454 0x8161 # 0 +0xC455 0x8162 # 0 +0xC456 0x8163 # 0 +0xC457 0x8164 # 0 +0xC458 0x8166 # 0 +0xC459 0x8168 # 0 +0xC45A 0x816A # 0 +0xC45B 0x816B # 0 +0xC45C 0x816C # 0 +0xC45D 0x816F # 0 +0xC45E 0x8172 # 0 +0xC45F 0x8173 # 0 +0xC460 0x8175 # 0 +0xC461 0x8176 # 0 +0xC462 0x8177 # 0 +0xC463 0x8178 # 0 +0xC464 0x8181 # 0 +0xC465 0x8183 # 0 +0xC466 0x8184 # 0 +0xC467 0x8185 # 0 +0xC468 0x8186 # 0 +0xC469 0x8187 # 0 +0xC46A 0x8189 # 0 +0xC46B 0x818B # 0 +0xC46C 0x818C # 0 +0xC46D 0x818D # 0 +0xC46E 0x818E # 0 +0xC46F 0x8190 # 0 +0xC470 0x8192 # 0 +0xC471 0x8193 # 0 +0xC472 0x8194 # 0 +0xC473 0x8195 # 0 +0xC474 0x8196 # 0 +0xC475 0x8197 # 0 +0xC476 0x8199 # 0 +0xC477 0x819A # 0 +0xC478 0x819E # 0 +0xC479 0x819F # 0 +0xC47A 0x81A0 # 0 +0xC47B 0x81A1 # 0 +0xC47C 0x81A2 # 0 +0xC47D 0x81A4 # 0 +0xC47E 0x81A5 # 0 +0xC480 0x81A7 # 0 +0xC481 0x81A9 # 0 +0xC482 0x81AB # 0 +0xC483 0x81AC # 0 +0xC484 0x81AD # 0 +0xC485 0x81AE # 0 +0xC486 0x81AF # 0 +0xC487 0x81B0 # 0 +0xC488 0x81B1 # 0 +0xC489 0x81B2 # 0 +0xC48A 0x81B4 # 0 +0xC48B 0x81B5 # 0 +0xC48C 0x81B6 # 0 +0xC48D 0x81B7 # 0 +0xC48E 0x81B8 # 0 +0xC48F 0x81B9 # 0 +0xC490 0x81BC # 0 +0xC491 0x81BD # 0 +0xC492 0x81BE # 0 +0xC493 0x81BF # 0 +0xC494 0x81C4 # 0 +0xC495 0x81C5 # 0 +0xC496 0x81C7 # 0 +0xC497 0x81C8 # 0 +0xC498 0x81C9 # 0 +0xC499 0x81CB # 0 +0xC49A 0x81CD # 0 +0xC49B 0x81CE # 0 +0xC49C 0x81CF # 0 +0xC49D 0x81D0 # 0 +0xC49E 0x81D1 # 0 +0xC49F 0x81D2 # 0 +0xC4A0 0x81D3 # 0 +0xC4A1 0x6479 # 0 +0xC4A2 0x8611 # 0 +0xC4A3 0x6A21 # 0 +0xC4A4 0x819C # 0 +0xC4A5 0x78E8 # 0 +0xC4A6 0x6469 # 0 +0xC4A7 0x9B54 # 0 +0xC4A8 0x62B9 # 0 +0xC4A9 0x672B # 0 +0xC4AA 0x83AB # 0 +0xC4AB 0x58A8 # 0 +0xC4AC 0x9ED8 # 0 +0xC4AD 0x6CAB # 0 +0xC4AE 0x6F20 # 0 +0xC4AF 0x5BDE # 0 +0xC4B0 0x964C # 0 +0xC4B1 0x8C0B # 0 +0xC4B2 0x725F # 0 +0xC4B3 0x67D0 # 0 +0xC4B4 0x62C7 # 0 +0xC4B5 0x7261 # 0 +0xC4B6 0x4EA9 # 0 +0xC4B7 0x59C6 # 0 +0xC4B8 0x6BCD # 0 +0xC4B9 0x5893 # 0 +0xC4BA 0x66AE # 0 +0xC4BB 0x5E55 # 0 +0xC4BC 0x52DF # 0 +0xC4BD 0x6155 # 0 +0xC4BE 0x6728 # 0 +0xC4BF 0x76EE # 0 +0xC4C0 0x7766 # 0 +0xC4C1 0x7267 # 0 +0xC4C2 0x7A46 # 0 +0xC4C3 0x62FF # 0 +0xC4C4 0x54EA # 0 +0xC4C5 0x5450 # 0 +0xC4C6 0x94A0 # 0 +0xC4C7 0x90A3 # 0 +0xC4C8 0x5A1C # 0 +0xC4C9 0x7EB3 # 0 +0xC4CA 0x6C16 # 0 +0xC4CB 0x4E43 # 0 +0xC4CC 0x5976 # 0 +0xC4CD 0x8010 # 0 +0xC4CE 0x5948 # 0 +0xC4CF 0x5357 # 0 +0xC4D0 0x7537 # 0 +0xC4D1 0x96BE # 0 +0xC4D2 0x56CA # 0 +0xC4D3 0x6320 # 0 +0xC4D4 0x8111 # 0 +0xC4D5 0x607C # 0 +0xC4D6 0x95F9 # 0 +0xC4D7 0x6DD6 # 0 +0xC4D8 0x5462 # 0 +0xC4D9 0x9981 # 0 +0xC4DA 0x5185 # 0 +0xC4DB 0x5AE9 # 0 +0xC4DC 0x80FD # 0 +0xC4DD 0x59AE # 0 +0xC4DE 0x9713 # 0 +0xC4DF 0x502A # 0 +0xC4E0 0x6CE5 # 0 +0xC4E1 0x5C3C # 0 +0xC4E2 0x62DF # 0 +0xC4E3 0x4F60 # 0 +0xC4E4 0x533F # 0 +0xC4E5 0x817B # 0 +0xC4E6 0x9006 # 0 +0xC4E7 0x6EBA # 0 +0xC4E8 0x852B # 0 +0xC4E9 0x62C8 # 0 +0xC4EA 0x5E74 # 0 +0xC4EB 0x78BE # 0 +0xC4EC 0x64B5 # 0 +0xC4ED 0x637B # 0 +0xC4EE 0x5FF5 # 0 +0xC4EF 0x5A18 # 0 +0xC4F0 0x917F # 0 +0xC4F1 0x9E1F # 0 +0xC4F2 0x5C3F # 0 +0xC4F3 0x634F # 0 +0xC4F4 0x8042 # 0 +0xC4F5 0x5B7D # 0 +0xC4F6 0x556E # 0 +0xC4F7 0x954A # 0 +0xC4F8 0x954D # 0 +0xC4F9 0x6D85 # 0 +0xC4FA 0x60A8 # 0 +0xC4FB 0x67E0 # 0 +0xC4FC 0x72DE # 0 +0xC4FD 0x51DD # 0 +0xC4FE 0x5B81 # 0 +0xC540 0x81D4 # 0 +0xC541 0x81D5 # 0 +0xC542 0x81D6 # 0 +0xC543 0x81D7 # 0 +0xC544 0x81D8 # 0 +0xC545 0x81D9 # 0 +0xC546 0x81DA # 0 +0xC547 0x81DB # 0 +0xC548 0x81DC # 0 +0xC549 0x81DD # 0 +0xC54A 0x81DE # 0 +0xC54B 0x81DF # 0 +0xC54C 0x81E0 # 0 +0xC54D 0x81E1 # 0 +0xC54E 0x81E2 # 0 +0xC54F 0x81E4 # 0 +0xC550 0x81E5 # 0 +0xC551 0x81E6 # 0 +0xC552 0x81E8 # 0 +0xC553 0x81E9 # 0 +0xC554 0x81EB # 0 +0xC555 0x81EE # 0 +0xC556 0x81EF # 0 +0xC557 0x81F0 # 0 +0xC558 0x81F1 # 0 +0xC559 0x81F2 # 0 +0xC55A 0x81F5 # 0 +0xC55B 0x81F6 # 0 +0xC55C 0x81F7 # 0 +0xC55D 0x81F8 # 0 +0xC55E 0x81F9 # 0 +0xC55F 0x81FA # 0 +0xC560 0x81FD # 0 +0xC561 0x81FF # 0 +0xC562 0x8203 # 0 +0xC563 0x8207 # 0 +0xC564 0x8208 # 0 +0xC565 0x8209 # 0 +0xC566 0x820A # 0 +0xC567 0x820B # 0 +0xC568 0x820E # 0 +0xC569 0x820F # 0 +0xC56A 0x8211 # 0 +0xC56B 0x8213 # 0 +0xC56C 0x8215 # 0 +0xC56D 0x8216 # 0 +0xC56E 0x8217 # 0 +0xC56F 0x8218 # 0 +0xC570 0x8219 # 0 +0xC571 0x821A # 0 +0xC572 0x821D # 0 +0xC573 0x8220 # 0 +0xC574 0x8224 # 0 +0xC575 0x8225 # 0 +0xC576 0x8226 # 0 +0xC577 0x8227 # 0 +0xC578 0x8229 # 0 +0xC579 0x822E # 0 +0xC57A 0x8232 # 0 +0xC57B 0x823A # 0 +0xC57C 0x823C # 0 +0xC57D 0x823D # 0 +0xC57E 0x823F # 0 +0xC580 0x8240 # 0 +0xC581 0x8241 # 0 +0xC582 0x8242 # 0 +0xC583 0x8243 # 0 +0xC584 0x8245 # 0 +0xC585 0x8246 # 0 +0xC586 0x8248 # 0 +0xC587 0x824A # 0 +0xC588 0x824C # 0 +0xC589 0x824D # 0 +0xC58A 0x824E # 0 +0xC58B 0x8250 # 0 +0xC58C 0x8251 # 0 +0xC58D 0x8252 # 0 +0xC58E 0x8253 # 0 +0xC58F 0x8254 # 0 +0xC590 0x8255 # 0 +0xC591 0x8256 # 0 +0xC592 0x8257 # 0 +0xC593 0x8259 # 0 +0xC594 0x825B # 0 +0xC595 0x825C # 0 +0xC596 0x825D # 0 +0xC597 0x825E # 0 +0xC598 0x8260 # 0 +0xC599 0x8261 # 0 +0xC59A 0x8262 # 0 +0xC59B 0x8263 # 0 +0xC59C 0x8264 # 0 +0xC59D 0x8265 # 0 +0xC59E 0x8266 # 0 +0xC59F 0x8267 # 0 +0xC5A0 0x8269 # 0 +0xC5A1 0x62E7 # 0 +0xC5A2 0x6CDE # 0 +0xC5A3 0x725B # 0 +0xC5A4 0x626D # 0 +0xC5A5 0x94AE # 0 +0xC5A6 0x7EBD # 0 +0xC5A7 0x8113 # 0 +0xC5A8 0x6D53 # 0 +0xC5A9 0x519C # 0 +0xC5AA 0x5F04 # 0 +0xC5AB 0x5974 # 0 +0xC5AC 0x52AA # 0 +0xC5AD 0x6012 # 0 +0xC5AE 0x5973 # 0 +0xC5AF 0x6696 # 0 +0xC5B0 0x8650 # 0 +0xC5B1 0x759F # 0 +0xC5B2 0x632A # 0 +0xC5B3 0x61E6 # 0 +0xC5B4 0x7CEF # 0 +0xC5B5 0x8BFA # 0 +0xC5B6 0x54E6 # 0 +0xC5B7 0x6B27 # 0 +0xC5B8 0x9E25 # 0 +0xC5B9 0x6BB4 # 0 +0xC5BA 0x85D5 # 0 +0xC5BB 0x5455 # 0 +0xC5BC 0x5076 # 0 +0xC5BD 0x6CA4 # 0 +0xC5BE 0x556A # 0 +0xC5BF 0x8DB4 # 0 +0xC5C0 0x722C # 0 +0xC5C1 0x5E15 # 0 +0xC5C2 0x6015 # 0 +0xC5C3 0x7436 # 0 +0xC5C4 0x62CD # 0 +0xC5C5 0x6392 # 0 +0xC5C6 0x724C # 0 +0xC5C7 0x5F98 # 0 +0xC5C8 0x6E43 # 0 +0xC5C9 0x6D3E # 0 +0xC5CA 0x6500 # 0 +0xC5CB 0x6F58 # 0 +0xC5CC 0x76D8 # 0 +0xC5CD 0x78D0 # 0 +0xC5CE 0x76FC # 0 +0xC5CF 0x7554 # 0 +0xC5D0 0x5224 # 0 +0xC5D1 0x53DB # 0 +0xC5D2 0x4E53 # 0 +0xC5D3 0x5E9E # 0 +0xC5D4 0x65C1 # 0 +0xC5D5 0x802A # 0 +0xC5D6 0x80D6 # 0 +0xC5D7 0x629B # 0 +0xC5D8 0x5486 # 0 +0xC5D9 0x5228 # 0 +0xC5DA 0x70AE # 0 +0xC5DB 0x888D # 0 +0xC5DC 0x8DD1 # 0 +0xC5DD 0x6CE1 # 0 +0xC5DE 0x5478 # 0 +0xC5DF 0x80DA # 0 +0xC5E0 0x57F9 # 0 +0xC5E1 0x88F4 # 0 +0xC5E2 0x8D54 # 0 +0xC5E3 0x966A # 0 +0xC5E4 0x914D # 0 +0xC5E5 0x4F69 # 0 +0xC5E6 0x6C9B # 0 +0xC5E7 0x55B7 # 0 +0xC5E8 0x76C6 # 0 +0xC5E9 0x7830 # 0 +0xC5EA 0x62A8 # 0 +0xC5EB 0x70F9 # 0 +0xC5EC 0x6F8E # 0 +0xC5ED 0x5F6D # 0 +0xC5EE 0x84EC # 0 +0xC5EF 0x68DA # 0 +0xC5F0 0x787C # 0 +0xC5F1 0x7BF7 # 0 +0xC5F2 0x81A8 # 0 +0xC5F3 0x670B # 0 +0xC5F4 0x9E4F # 0 +0xC5F5 0x6367 # 0 +0xC5F6 0x78B0 # 0 +0xC5F7 0x576F # 0 +0xC5F8 0x7812 # 0 +0xC5F9 0x9739 # 0 +0xC5FA 0x6279 # 0 +0xC5FB 0x62AB # 0 +0xC5FC 0x5288 # 0 +0xC5FD 0x7435 # 0 +0xC5FE 0x6BD7 # 0 +0xC640 0x826A # 0 +0xC641 0x826B # 0 +0xC642 0x826C # 0 +0xC643 0x826D # 0 +0xC644 0x8271 # 0 +0xC645 0x8275 # 0 +0xC646 0x8276 # 0 +0xC647 0x8277 # 0 +0xC648 0x8278 # 0 +0xC649 0x827B # 0 +0xC64A 0x827C # 0 +0xC64B 0x8280 # 0 +0xC64C 0x8281 # 0 +0xC64D 0x8283 # 0 +0xC64E 0x8285 # 0 +0xC64F 0x8286 # 0 +0xC650 0x8287 # 0 +0xC651 0x8289 # 0 +0xC652 0x828C # 0 +0xC653 0x8290 # 0 +0xC654 0x8293 # 0 +0xC655 0x8294 # 0 +0xC656 0x8295 # 0 +0xC657 0x8296 # 0 +0xC658 0x829A # 0 +0xC659 0x829B # 0 +0xC65A 0x829E # 0 +0xC65B 0x82A0 # 0 +0xC65C 0x82A2 # 0 +0xC65D 0x82A3 # 0 +0xC65E 0x82A7 # 0 +0xC65F 0x82B2 # 0 +0xC660 0x82B5 # 0 +0xC661 0x82B6 # 0 +0xC662 0x82BA # 0 +0xC663 0x82BB # 0 +0xC664 0x82BC # 0 +0xC665 0x82BF # 0 +0xC666 0x82C0 # 0 +0xC667 0x82C2 # 0 +0xC668 0x82C3 # 0 +0xC669 0x82C5 # 0 +0xC66A 0x82C6 # 0 +0xC66B 0x82C9 # 0 +0xC66C 0x82D0 # 0 +0xC66D 0x82D6 # 0 +0xC66E 0x82D9 # 0 +0xC66F 0x82DA # 0 +0xC670 0x82DD # 0 +0xC671 0x82E2 # 0 +0xC672 0x82E7 # 0 +0xC673 0x82E8 # 0 +0xC674 0x82E9 # 0 +0xC675 0x82EA # 0 +0xC676 0x82EC # 0 +0xC677 0x82ED # 0 +0xC678 0x82EE # 0 +0xC679 0x82F0 # 0 +0xC67A 0x82F2 # 0 +0xC67B 0x82F3 # 0 +0xC67C 0x82F5 # 0 +0xC67D 0x82F6 # 0 +0xC67E 0x82F8 # 0 +0xC680 0x82FA # 0 +0xC681 0x82FC # 0 +0xC682 0x82FD # 0 +0xC683 0x82FE # 0 +0xC684 0x82FF # 0 +0xC685 0x8300 # 0 +0xC686 0x830A # 0 +0xC687 0x830B # 0 +0xC688 0x830D # 0 +0xC689 0x8310 # 0 +0xC68A 0x8312 # 0 +0xC68B 0x8313 # 0 +0xC68C 0x8316 # 0 +0xC68D 0x8318 # 0 +0xC68E 0x8319 # 0 +0xC68F 0x831D # 0 +0xC690 0x831E # 0 +0xC691 0x831F # 0 +0xC692 0x8320 # 0 +0xC693 0x8321 # 0 +0xC694 0x8322 # 0 +0xC695 0x8323 # 0 +0xC696 0x8324 # 0 +0xC697 0x8325 # 0 +0xC698 0x8326 # 0 +0xC699 0x8329 # 0 +0xC69A 0x832A # 0 +0xC69B 0x832E # 0 +0xC69C 0x8330 # 0 +0xC69D 0x8332 # 0 +0xC69E 0x8337 # 0 +0xC69F 0x833B # 0 +0xC6A0 0x833D # 0 +0xC6A1 0x5564 # 0 +0xC6A2 0x813E # 0 +0xC6A3 0x75B2 # 0 +0xC6A4 0x76AE # 0 +0xC6A5 0x5339 # 0 +0xC6A6 0x75DE # 0 +0xC6A7 0x50FB # 0 +0xC6A8 0x5C41 # 0 +0xC6A9 0x8B6C # 0 +0xC6AA 0x7BC7 # 0 +0xC6AB 0x504F # 0 +0xC6AC 0x7247 # 0 +0xC6AD 0x9A97 # 0 +0xC6AE 0x98D8 # 0 +0xC6AF 0x6F02 # 0 +0xC6B0 0x74E2 # 0 +0xC6B1 0x7968 # 0 +0xC6B2 0x6487 # 0 +0xC6B3 0x77A5 # 0 +0xC6B4 0x62FC # 0 +0xC6B5 0x9891 # 0 +0xC6B6 0x8D2B # 0 +0xC6B7 0x54C1 # 0 +0xC6B8 0x8058 # 0 +0xC6B9 0x4E52 # 0 +0xC6BA 0x576A # 0 +0xC6BB 0x82F9 # 0 +0xC6BC 0x840D # 0 +0xC6BD 0x5E73 # 0 +0xC6BE 0x51ED # 0 +0xC6BF 0x74F6 # 0 +0xC6C0 0x8BC4 # 0 +0xC6C1 0x5C4F # 0 +0xC6C2 0x5761 # 0 +0xC6C3 0x6CFC # 0 +0xC6C4 0x9887 # 0 +0xC6C5 0x5A46 # 0 +0xC6C6 0x7834 # 0 +0xC6C7 0x9B44 # 0 +0xC6C8 0x8FEB # 0 +0xC6C9 0x7C95 # 0 +0xC6CA 0x5256 # 0 +0xC6CB 0x6251 # 0 +0xC6CC 0x94FA # 0 +0xC6CD 0x4EC6 # 0 +0xC6CE 0x8386 # 0 +0xC6CF 0x8461 # 0 +0xC6D0 0x83E9 # 0 +0xC6D1 0x84B2 # 0 +0xC6D2 0x57D4 # 0 +0xC6D3 0x6734 # 0 +0xC6D4 0x5703 # 0 +0xC6D5 0x666E # 0 +0xC6D6 0x6D66 # 0 +0xC6D7 0x8C31 # 0 +0xC6D8 0x66DD # 0 +0xC6D9 0x7011 # 0 +0xC6DA 0x671F # 0 +0xC6DB 0x6B3A # 0 +0xC6DC 0x6816 # 0 +0xC6DD 0x621A # 0 +0xC6DE 0x59BB # 0 +0xC6DF 0x4E03 # 0 +0xC6E0 0x51C4 # 0 +0xC6E1 0x6F06 # 0 +0xC6E2 0x67D2 # 0 +0xC6E3 0x6C8F # 0 +0xC6E4 0x5176 # 0 +0xC6E5 0x68CB # 0 +0xC6E6 0x5947 # 0 +0xC6E7 0x6B67 # 0 +0xC6E8 0x7566 # 0 +0xC6E9 0x5D0E # 0 +0xC6EA 0x8110 # 0 +0xC6EB 0x9F50 # 0 +0xC6EC 0x65D7 # 0 +0xC6ED 0x7948 # 0 +0xC6EE 0x7941 # 0 +0xC6EF 0x9A91 # 0 +0xC6F0 0x8D77 # 0 +0xC6F1 0x5C82 # 0 +0xC6F2 0x4E5E # 0 +0xC6F3 0x4F01 # 0 +0xC6F4 0x542F # 0 +0xC6F5 0x5951 # 0 +0xC6F6 0x780C # 0 +0xC6F7 0x5668 # 0 +0xC6F8 0x6C14 # 0 +0xC6F9 0x8FC4 # 0 +0xC6FA 0x5F03 # 0 +0xC6FB 0x6C7D # 0 +0xC6FC 0x6CE3 # 0 +0xC6FD 0x8BAB # 0 +0xC6FE 0x6390 # 0 +0xC740 0x833E # 0 +0xC741 0x833F # 0 +0xC742 0x8341 # 0 +0xC743 0x8342 # 0 +0xC744 0x8344 # 0 +0xC745 0x8345 # 0 +0xC746 0x8348 # 0 +0xC747 0x834A # 0 +0xC748 0x834B # 0 +0xC749 0x834C # 0 +0xC74A 0x834D # 0 +0xC74B 0x834E # 0 +0xC74C 0x8353 # 0 +0xC74D 0x8355 # 0 +0xC74E 0x8356 # 0 +0xC74F 0x8357 # 0 +0xC750 0x8358 # 0 +0xC751 0x8359 # 0 +0xC752 0x835D # 0 +0xC753 0x8362 # 0 +0xC754 0x8370 # 0 +0xC755 0x8371 # 0 +0xC756 0x8372 # 0 +0xC757 0x8373 # 0 +0xC758 0x8374 # 0 +0xC759 0x8375 # 0 +0xC75A 0x8376 # 0 +0xC75B 0x8379 # 0 +0xC75C 0x837A # 0 +0xC75D 0x837E # 0 +0xC75E 0x837F # 0 +0xC75F 0x8380 # 0 +0xC760 0x8381 # 0 +0xC761 0x8382 # 0 +0xC762 0x8383 # 0 +0xC763 0x8384 # 0 +0xC764 0x8387 # 0 +0xC765 0x8388 # 0 +0xC766 0x838A # 0 +0xC767 0x838B # 0 +0xC768 0x838C # 0 +0xC769 0x838D # 0 +0xC76A 0x838F # 0 +0xC76B 0x8390 # 0 +0xC76C 0x8391 # 0 +0xC76D 0x8394 # 0 +0xC76E 0x8395 # 0 +0xC76F 0x8396 # 0 +0xC770 0x8397 # 0 +0xC771 0x8399 # 0 +0xC772 0x839A # 0 +0xC773 0x839D # 0 +0xC774 0x839F # 0 +0xC775 0x83A1 # 0 +0xC776 0x83A2 # 0 +0xC777 0x83A3 # 0 +0xC778 0x83A4 # 0 +0xC779 0x83A5 # 0 +0xC77A 0x83A6 # 0 +0xC77B 0x83A7 # 0 +0xC77C 0x83AC # 0 +0xC77D 0x83AD # 0 +0xC77E 0x83AE # 0 +0xC780 0x83AF # 0 +0xC781 0x83B5 # 0 +0xC782 0x83BB # 0 +0xC783 0x83BE # 0 +0xC784 0x83BF # 0 +0xC785 0x83C2 # 0 +0xC786 0x83C3 # 0 +0xC787 0x83C4 # 0 +0xC788 0x83C6 # 0 +0xC789 0x83C8 # 0 +0xC78A 0x83C9 # 0 +0xC78B 0x83CB # 0 +0xC78C 0x83CD # 0 +0xC78D 0x83CE # 0 +0xC78E 0x83D0 # 0 +0xC78F 0x83D1 # 0 +0xC790 0x83D2 # 0 +0xC791 0x83D3 # 0 +0xC792 0x83D5 # 0 +0xC793 0x83D7 # 0 +0xC794 0x83D9 # 0 +0xC795 0x83DA # 0 +0xC796 0x83DB # 0 +0xC797 0x83DE # 0 +0xC798 0x83E2 # 0 +0xC799 0x83E3 # 0 +0xC79A 0x83E4 # 0 +0xC79B 0x83E6 # 0 +0xC79C 0x83E7 # 0 +0xC79D 0x83E8 # 0 +0xC79E 0x83EB # 0 +0xC79F 0x83EC # 0 +0xC7A0 0x83ED # 0 +0xC7A1 0x6070 # 0 +0xC7A2 0x6D3D # 0 +0xC7A3 0x7275 # 0 +0xC7A4 0x6266 # 0 +0xC7A5 0x948E # 0 +0xC7A6 0x94C5 # 0 +0xC7A7 0x5343 # 0 +0xC7A8 0x8FC1 # 0 +0xC7A9 0x7B7E # 0 +0xC7AA 0x4EDF # 0 +0xC7AB 0x8C26 # 0 +0xC7AC 0x4E7E # 0 +0xC7AD 0x9ED4 # 0 +0xC7AE 0x94B1 # 0 +0xC7AF 0x94B3 # 0 +0xC7B0 0x524D # 0 +0xC7B1 0x6F5C # 0 +0xC7B2 0x9063 # 0 +0xC7B3 0x6D45 # 0 +0xC7B4 0x8C34 # 0 +0xC7B5 0x5811 # 0 +0xC7B6 0x5D4C # 0 +0xC7B7 0x6B20 # 0 +0xC7B8 0x6B49 # 0 +0xC7B9 0x67AA # 0 +0xC7BA 0x545B # 0 +0xC7BB 0x8154 # 0 +0xC7BC 0x7F8C # 0 +0xC7BD 0x5899 # 0 +0xC7BE 0x8537 # 0 +0xC7BF 0x5F3A # 0 +0xC7C0 0x62A2 # 0 +0xC7C1 0x6A47 # 0 +0xC7C2 0x9539 # 0 +0xC7C3 0x6572 # 0 +0xC7C4 0x6084 # 0 +0xC7C5 0x6865 # 0 +0xC7C6 0x77A7 # 0 +0xC7C7 0x4E54 # 0 +0xC7C8 0x4FA8 # 0 +0xC7C9 0x5DE7 # 0 +0xC7CA 0x9798 # 0 +0xC7CB 0x64AC # 0 +0xC7CC 0x7FD8 # 0 +0xC7CD 0x5CED # 0 +0xC7CE 0x4FCF # 0 +0xC7CF 0x7A8D # 0 +0xC7D0 0x5207 # 0 +0xC7D1 0x8304 # 0 +0xC7D2 0x4E14 # 0 +0xC7D3 0x602F # 0 +0xC7D4 0x7A83 # 0 +0xC7D5 0x94A6 # 0 +0xC7D6 0x4FB5 # 0 +0xC7D7 0x4EB2 # 0 +0xC7D8 0x79E6 # 0 +0xC7D9 0x7434 # 0 +0xC7DA 0x52E4 # 0 +0xC7DB 0x82B9 # 0 +0xC7DC 0x64D2 # 0 +0xC7DD 0x79BD # 0 +0xC7DE 0x5BDD # 0 +0xC7DF 0x6C81 # 0 +0xC7E0 0x9752 # 0 +0xC7E1 0x8F7B # 0 +0xC7E2 0x6C22 # 0 +0xC7E3 0x503E # 0 +0xC7E4 0x537F # 0 +0xC7E5 0x6E05 # 0 +0xC7E6 0x64CE # 0 +0xC7E7 0x6674 # 0 +0xC7E8 0x6C30 # 0 +0xC7E9 0x60C5 # 0 +0xC7EA 0x9877 # 0 +0xC7EB 0x8BF7 # 0 +0xC7EC 0x5E86 # 0 +0xC7ED 0x743C # 0 +0xC7EE 0x7A77 # 0 +0xC7EF 0x79CB # 0 +0xC7F0 0x4E18 # 0 +0xC7F1 0x90B1 # 0 +0xC7F2 0x7403 # 0 +0xC7F3 0x6C42 # 0 +0xC7F4 0x56DA # 0 +0xC7F5 0x914B # 0 +0xC7F6 0x6CC5 # 0 +0xC7F7 0x8D8B # 0 +0xC7F8 0x533A # 0 +0xC7F9 0x86C6 # 0 +0xC7FA 0x66F2 # 0 +0xC7FB 0x8EAF # 0 +0xC7FC 0x5C48 # 0 +0xC7FD 0x9A71 # 0 +0xC7FE 0x6E20 # 0 +0xC840 0x83EE # 0 +0xC841 0x83EF # 0 +0xC842 0x83F3 # 0 +0xC843 0x83F4 # 0 +0xC844 0x83F5 # 0 +0xC845 0x83F6 # 0 +0xC846 0x83F7 # 0 +0xC847 0x83FA # 0 +0xC848 0x83FB # 0 +0xC849 0x83FC # 0 +0xC84A 0x83FE # 0 +0xC84B 0x83FF # 0 +0xC84C 0x8400 # 0 +0xC84D 0x8402 # 0 +0xC84E 0x8405 # 0 +0xC84F 0x8407 # 0 +0xC850 0x8408 # 0 +0xC851 0x8409 # 0 +0xC852 0x840A # 0 +0xC853 0x8410 # 0 +0xC854 0x8412 # 0 +0xC855 0x8413 # 0 +0xC856 0x8414 # 0 +0xC857 0x8415 # 0 +0xC858 0x8416 # 0 +0xC859 0x8417 # 0 +0xC85A 0x8419 # 0 +0xC85B 0x841A # 0 +0xC85C 0x841B # 0 +0xC85D 0x841E # 0 +0xC85E 0x841F # 0 +0xC85F 0x8420 # 0 +0xC860 0x8421 # 0 +0xC861 0x8422 # 0 +0xC862 0x8423 # 0 +0xC863 0x8429 # 0 +0xC864 0x842A # 0 +0xC865 0x842B # 0 +0xC866 0x842C # 0 +0xC867 0x842D # 0 +0xC868 0x842E # 0 +0xC869 0x842F # 0 +0xC86A 0x8430 # 0 +0xC86B 0x8432 # 0 +0xC86C 0x8433 # 0 +0xC86D 0x8434 # 0 +0xC86E 0x8435 # 0 +0xC86F 0x8436 # 0 +0xC870 0x8437 # 0 +0xC871 0x8439 # 0 +0xC872 0x843A # 0 +0xC873 0x843B # 0 +0xC874 0x843E # 0 +0xC875 0x843F # 0 +0xC876 0x8440 # 0 +0xC877 0x8441 # 0 +0xC878 0x8442 # 0 +0xC879 0x8443 # 0 +0xC87A 0x8444 # 0 +0xC87B 0x8445 # 0 +0xC87C 0x8447 # 0 +0xC87D 0x8448 # 0 +0xC87E 0x8449 # 0 +0xC880 0x844A # 0 +0xC881 0x844B # 0 +0xC882 0x844C # 0 +0xC883 0x844D # 0 +0xC884 0x844E # 0 +0xC885 0x844F # 0 +0xC886 0x8450 # 0 +0xC887 0x8452 # 0 +0xC888 0x8453 # 0 +0xC889 0x8454 # 0 +0xC88A 0x8455 # 0 +0xC88B 0x8456 # 0 +0xC88C 0x8458 # 0 +0xC88D 0x845D # 0 +0xC88E 0x845E # 0 +0xC88F 0x845F # 0 +0xC890 0x8460 # 0 +0xC891 0x8462 # 0 +0xC892 0x8464 # 0 +0xC893 0x8465 # 0 +0xC894 0x8466 # 0 +0xC895 0x8467 # 0 +0xC896 0x8468 # 0 +0xC897 0x846A # 0 +0xC898 0x846E # 0 +0xC899 0x846F # 0 +0xC89A 0x8470 # 0 +0xC89B 0x8472 # 0 +0xC89C 0x8474 # 0 +0xC89D 0x8477 # 0 +0xC89E 0x8479 # 0 +0xC89F 0x847B # 0 +0xC8A0 0x847C # 0 +0xC8A1 0x53D6 # 0 +0xC8A2 0x5A36 # 0 +0xC8A3 0x9F8B # 0 +0xC8A4 0x8DA3 # 0 +0xC8A5 0x53BB # 0 +0xC8A6 0x5708 # 0 +0xC8A7 0x98A7 # 0 +0xC8A8 0x6743 # 0 +0xC8A9 0x919B # 0 +0xC8AA 0x6CC9 # 0 +0xC8AB 0x5168 # 0 +0xC8AC 0x75CA # 0 +0xC8AD 0x62F3 # 0 +0xC8AE 0x72AC # 0 +0xC8AF 0x5238 # 0 +0xC8B0 0x529D # 0 +0xC8B1 0x7F3A # 0 +0xC8B2 0x7094 # 0 +0xC8B3 0x7638 # 0 +0xC8B4 0x5374 # 0 +0xC8B5 0x9E4A # 0 +0xC8B6 0x69B7 # 0 +0xC8B7 0x786E # 0 +0xC8B8 0x96C0 # 0 +0xC8B9 0x88D9 # 0 +0xC8BA 0x7FA4 # 0 +0xC8BB 0x7136 # 0 +0xC8BC 0x71C3 # 0 +0xC8BD 0x5189 # 0 +0xC8BE 0x67D3 # 0 +0xC8BF 0x74E4 # 0 +0xC8C0 0x58E4 # 0 +0xC8C1 0x6518 # 0 +0xC8C2 0x56B7 # 0 +0xC8C3 0x8BA9 # 0 +0xC8C4 0x9976 # 0 +0xC8C5 0x6270 # 0 +0xC8C6 0x7ED5 # 0 +0xC8C7 0x60F9 # 0 +0xC8C8 0x70ED # 0 +0xC8C9 0x58EC # 0 +0xC8CA 0x4EC1 # 0 +0xC8CB 0x4EBA # 0 +0xC8CC 0x5FCD # 0 +0xC8CD 0x97E7 # 0 +0xC8CE 0x4EFB # 0 +0xC8CF 0x8BA4 # 0 +0xC8D0 0x5203 # 0 +0xC8D1 0x598A # 0 +0xC8D2 0x7EAB # 0 +0xC8D3 0x6254 # 0 +0xC8D4 0x4ECD # 0 +0xC8D5 0x65E5 # 0 +0xC8D6 0x620E # 0 +0xC8D7 0x8338 # 0 +0xC8D8 0x84C9 # 0 +0xC8D9 0x8363 # 0 +0xC8DA 0x878D # 0 +0xC8DB 0x7194 # 0 +0xC8DC 0x6EB6 # 0 +0xC8DD 0x5BB9 # 0 +0xC8DE 0x7ED2 # 0 +0xC8DF 0x5197 # 0 +0xC8E0 0x63C9 # 0 +0xC8E1 0x67D4 # 0 +0xC8E2 0x8089 # 0 +0xC8E3 0x8339 # 0 +0xC8E4 0x8815 # 0 +0xC8E5 0x5112 # 0 +0xC8E6 0x5B7A # 0 +0xC8E7 0x5982 # 0 +0xC8E8 0x8FB1 # 0 +0xC8E9 0x4E73 # 0 +0xC8EA 0x6C5D # 0 +0xC8EB 0x5165 # 0 +0xC8EC 0x8925 # 0 +0xC8ED 0x8F6F # 0 +0xC8EE 0x962E # 0 +0xC8EF 0x854A # 0 +0xC8F0 0x745E # 0 +0xC8F1 0x9510 # 0 +0xC8F2 0x95F0 # 0 +0xC8F3 0x6DA6 # 0 +0xC8F4 0x82E5 # 0 +0xC8F5 0x5F31 # 0 +0xC8F6 0x6492 # 0 +0xC8F7 0x6D12 # 0 +0xC8F8 0x8428 # 0 +0xC8F9 0x816E # 0 +0xC8FA 0x9CC3 # 0 +0xC8FB 0x585E # 0 +0xC8FC 0x8D5B # 0 +0xC8FD 0x4E09 # 0 +0xC8FE 0x53C1 # 0 +0xC940 0x847D # 0 +0xC941 0x847E # 0 +0xC942 0x847F # 0 +0xC943 0x8480 # 0 +0xC944 0x8481 # 0 +0xC945 0x8483 # 0 +0xC946 0x8484 # 0 +0xC947 0x8485 # 0 +0xC948 0x8486 # 0 +0xC949 0x848A # 0 +0xC94A 0x848D # 0 +0xC94B 0x848F # 0 +0xC94C 0x8490 # 0 +0xC94D 0x8491 # 0 +0xC94E 0x8492 # 0 +0xC94F 0x8493 # 0 +0xC950 0x8494 # 0 +0xC951 0x8495 # 0 +0xC952 0x8496 # 0 +0xC953 0x8498 # 0 +0xC954 0x849A # 0 +0xC955 0x849B # 0 +0xC956 0x849D # 0 +0xC957 0x849E # 0 +0xC958 0x849F # 0 +0xC959 0x84A0 # 0 +0xC95A 0x84A2 # 0 +0xC95B 0x84A3 # 0 +0xC95C 0x84A4 # 0 +0xC95D 0x84A5 # 0 +0xC95E 0x84A6 # 0 +0xC95F 0x84A7 # 0 +0xC960 0x84A8 # 0 +0xC961 0x84A9 # 0 +0xC962 0x84AA # 0 +0xC963 0x84AB # 0 +0xC964 0x84AC # 0 +0xC965 0x84AD # 0 +0xC966 0x84AE # 0 +0xC967 0x84B0 # 0 +0xC968 0x84B1 # 0 +0xC969 0x84B3 # 0 +0xC96A 0x84B5 # 0 +0xC96B 0x84B6 # 0 +0xC96C 0x84B7 # 0 +0xC96D 0x84BB # 0 +0xC96E 0x84BC # 0 +0xC96F 0x84BE # 0 +0xC970 0x84C0 # 0 +0xC971 0x84C2 # 0 +0xC972 0x84C3 # 0 +0xC973 0x84C5 # 0 +0xC974 0x84C6 # 0 +0xC975 0x84C7 # 0 +0xC976 0x84C8 # 0 +0xC977 0x84CB # 0 +0xC978 0x84CC # 0 +0xC979 0x84CE # 0 +0xC97A 0x84CF # 0 +0xC97B 0x84D2 # 0 +0xC97C 0x84D4 # 0 +0xC97D 0x84D5 # 0 +0xC97E 0x84D7 # 0 +0xC980 0x84D8 # 0 +0xC981 0x84D9 # 0 +0xC982 0x84DA # 0 +0xC983 0x84DB # 0 +0xC984 0x84DC # 0 +0xC985 0x84DE # 0 +0xC986 0x84E1 # 0 +0xC987 0x84E2 # 0 +0xC988 0x84E4 # 0 +0xC989 0x84E7 # 0 +0xC98A 0x84E8 # 0 +0xC98B 0x84E9 # 0 +0xC98C 0x84EA # 0 +0xC98D 0x84EB # 0 +0xC98E 0x84ED # 0 +0xC98F 0x84EE # 0 +0xC990 0x84EF # 0 +0xC991 0x84F1 # 0 +0xC992 0x84F2 # 0 +0xC993 0x84F3 # 0 +0xC994 0x84F4 # 0 +0xC995 0x84F5 # 0 +0xC996 0x84F6 # 0 +0xC997 0x84F7 # 0 +0xC998 0x84F8 # 0 +0xC999 0x84F9 # 0 +0xC99A 0x84FA # 0 +0xC99B 0x84FB # 0 +0xC99C 0x84FD # 0 +0xC99D 0x84FE # 0 +0xC99E 0x8500 # 0 +0xC99F 0x8501 # 0 +0xC9A0 0x8502 # 0 +0xC9A1 0x4F1E # 0 +0xC9A2 0x6563 # 0 +0xC9A3 0x6851 # 0 +0xC9A4 0x55D3 # 0 +0xC9A5 0x4E27 # 0 +0xC9A6 0x6414 # 0 +0xC9A7 0x9A9A # 0 +0xC9A8 0x626B # 0 +0xC9A9 0x5AC2 # 0 +0xC9AA 0x745F # 0 +0xC9AB 0x8272 # 0 +0xC9AC 0x6DA9 # 0 +0xC9AD 0x68EE # 0 +0xC9AE 0x50E7 # 0 +0xC9AF 0x838E # 0 +0xC9B0 0x7802 # 0 +0xC9B1 0x6740 # 0 +0xC9B2 0x5239 # 0 +0xC9B3 0x6C99 # 0 +0xC9B4 0x7EB1 # 0 +0xC9B5 0x50BB # 0 +0xC9B6 0x5565 # 0 +0xC9B7 0x715E # 0 +0xC9B8 0x7B5B # 0 +0xC9B9 0x6652 # 0 +0xC9BA 0x73CA # 0 +0xC9BB 0x82EB # 0 +0xC9BC 0x6749 # 0 +0xC9BD 0x5C71 # 0 +0xC9BE 0x5220 # 0 +0xC9BF 0x717D # 0 +0xC9C0 0x886B # 0 +0xC9C1 0x95EA # 0 +0xC9C2 0x9655 # 0 +0xC9C3 0x64C5 # 0 +0xC9C4 0x8D61 # 0 +0xC9C5 0x81B3 # 0 +0xC9C6 0x5584 # 0 +0xC9C7 0x6C55 # 0 +0xC9C8 0x6247 # 0 +0xC9C9 0x7F2E # 0 +0xC9CA 0x5892 # 0 +0xC9CB 0x4F24 # 0 +0xC9CC 0x5546 # 0 +0xC9CD 0x8D4F # 0 +0xC9CE 0x664C # 0 +0xC9CF 0x4E0A # 0 +0xC9D0 0x5C1A # 0 +0xC9D1 0x88F3 # 0 +0xC9D2 0x68A2 # 0 +0xC9D3 0x634E # 0 +0xC9D4 0x7A0D # 0 +0xC9D5 0x70E7 # 0 +0xC9D6 0x828D # 0 +0xC9D7 0x52FA # 0 +0xC9D8 0x97F6 # 0 +0xC9D9 0x5C11 # 0 +0xC9DA 0x54E8 # 0 +0xC9DB 0x90B5 # 0 +0xC9DC 0x7ECD # 0 +0xC9DD 0x5962 # 0 +0xC9DE 0x8D4A # 0 +0xC9DF 0x86C7 # 0 +0xC9E0 0x820C # 0 +0xC9E1 0x820D # 0 +0xC9E2 0x8D66 # 0 +0xC9E3 0x6444 # 0 +0xC9E4 0x5C04 # 0 +0xC9E5 0x6151 # 0 +0xC9E6 0x6D89 # 0 +0xC9E7 0x793E # 0 +0xC9E8 0x8BBE # 0 +0xC9E9 0x7837 # 0 +0xC9EA 0x7533 # 0 +0xC9EB 0x547B # 0 +0xC9EC 0x4F38 # 0 +0xC9ED 0x8EAB # 0 +0xC9EE 0x6DF1 # 0 +0xC9EF 0x5A20 # 0 +0xC9F0 0x7EC5 # 0 +0xC9F1 0x795E # 0 +0xC9F2 0x6C88 # 0 +0xC9F3 0x5BA1 # 0 +0xC9F4 0x5A76 # 0 +0xC9F5 0x751A # 0 +0xC9F6 0x80BE # 0 +0xC9F7 0x614E # 0 +0xC9F8 0x6E17 # 0 +0xC9F9 0x58F0 # 0 +0xC9FA 0x751F # 0 +0xC9FB 0x7525 # 0 +0xC9FC 0x7272 # 0 +0xC9FD 0x5347 # 0 +0xC9FE 0x7EF3 # 0 +0xCA40 0x8503 # 0 +0xCA41 0x8504 # 0 +0xCA42 0x8505 # 0 +0xCA43 0x8506 # 0 +0xCA44 0x8507 # 0 +0xCA45 0x8508 # 0 +0xCA46 0x8509 # 0 +0xCA47 0x850A # 0 +0xCA48 0x850B # 0 +0xCA49 0x850D # 0 +0xCA4A 0x850E # 0 +0xCA4B 0x850F # 0 +0xCA4C 0x8510 # 0 +0xCA4D 0x8512 # 0 +0xCA4E 0x8514 # 0 +0xCA4F 0x8515 # 0 +0xCA50 0x8516 # 0 +0xCA51 0x8518 # 0 +0xCA52 0x8519 # 0 +0xCA53 0x851B # 0 +0xCA54 0x851C # 0 +0xCA55 0x851D # 0 +0xCA56 0x851E # 0 +0xCA57 0x8520 # 0 +0xCA58 0x8522 # 0 +0xCA59 0x8523 # 0 +0xCA5A 0x8524 # 0 +0xCA5B 0x8525 # 0 +0xCA5C 0x8526 # 0 +0xCA5D 0x8527 # 0 +0xCA5E 0x8528 # 0 +0xCA5F 0x8529 # 0 +0xCA60 0x852A # 0 +0xCA61 0x852D # 0 +0xCA62 0x852E # 0 +0xCA63 0x852F # 0 +0xCA64 0x8530 # 0 +0xCA65 0x8531 # 0 +0xCA66 0x8532 # 0 +0xCA67 0x8533 # 0 +0xCA68 0x8534 # 0 +0xCA69 0x8535 # 0 +0xCA6A 0x8536 # 0 +0xCA6B 0x853E # 0 +0xCA6C 0x853F # 0 +0xCA6D 0x8540 # 0 +0xCA6E 0x8541 # 0 +0xCA6F 0x8542 # 0 +0xCA70 0x8544 # 0 +0xCA71 0x8545 # 0 +0xCA72 0x8546 # 0 +0xCA73 0x8547 # 0 +0xCA74 0x854B # 0 +0xCA75 0x854C # 0 +0xCA76 0x854D # 0 +0xCA77 0x854E # 0 +0xCA78 0x854F # 0 +0xCA79 0x8550 # 0 +0xCA7A 0x8551 # 0 +0xCA7B 0x8552 # 0 +0xCA7C 0x8553 # 0 +0xCA7D 0x8554 # 0 +0xCA7E 0x8555 # 0 +0xCA80 0x8557 # 0 +0xCA81 0x8558 # 0 +0xCA82 0x855A # 0 +0xCA83 0x855B # 0 +0xCA84 0x855C # 0 +0xCA85 0x855D # 0 +0xCA86 0x855F # 0 +0xCA87 0x8560 # 0 +0xCA88 0x8561 # 0 +0xCA89 0x8562 # 0 +0xCA8A 0x8563 # 0 +0xCA8B 0x8565 # 0 +0xCA8C 0x8566 # 0 +0xCA8D 0x8567 # 0 +0xCA8E 0x8569 # 0 +0xCA8F 0x856A # 0 +0xCA90 0x856B # 0 +0xCA91 0x856C # 0 +0xCA92 0x856D # 0 +0xCA93 0x856E # 0 +0xCA94 0x856F # 0 +0xCA95 0x8570 # 0 +0xCA96 0x8571 # 0 +0xCA97 0x8573 # 0 +0xCA98 0x8575 # 0 +0xCA99 0x8576 # 0 +0xCA9A 0x8577 # 0 +0xCA9B 0x8578 # 0 +0xCA9C 0x857C # 0 +0xCA9D 0x857D # 0 +0xCA9E 0x857F # 0 +0xCA9F 0x8580 # 0 +0xCAA0 0x8581 # 0 +0xCAA1 0x7701 # 0 +0xCAA2 0x76DB # 0 +0xCAA3 0x5269 # 0 +0xCAA4 0x80DC # 0 +0xCAA5 0x5723 # 0 +0xCAA6 0x5E08 # 0 +0xCAA7 0x5931 # 0 +0xCAA8 0x72EE # 0 +0xCAA9 0x65BD # 0 +0xCAAA 0x6E7F # 0 +0xCAAB 0x8BD7 # 0 +0xCAAC 0x5C38 # 0 +0xCAAD 0x8671 # 0 +0xCAAE 0x5341 # 0 +0xCAAF 0x77F3 # 0 +0xCAB0 0x62FE # 0 +0xCAB1 0x65F6 # 0 +0xCAB2 0x4EC0 # 0 +0xCAB3 0x98DF # 0 +0xCAB4 0x8680 # 0 +0xCAB5 0x5B9E # 0 +0xCAB6 0x8BC6 # 0 +0xCAB7 0x53F2 # 0 +0xCAB8 0x77E2 # 0 +0xCAB9 0x4F7F # 0 +0xCABA 0x5C4E # 0 +0xCABB 0x9A76 # 0 +0xCABC 0x59CB # 0 +0xCABD 0x5F0F # 0 +0xCABE 0x793A # 0 +0xCABF 0x58EB # 0 +0xCAC0 0x4E16 # 0 +0xCAC1 0x67FF # 0 +0xCAC2 0x4E8B # 0 +0xCAC3 0x62ED # 0 +0xCAC4 0x8A93 # 0 +0xCAC5 0x901D # 0 +0xCAC6 0x52BF # 0 +0xCAC7 0x662F # 0 +0xCAC8 0x55DC # 0 +0xCAC9 0x566C # 0 +0xCACA 0x9002 # 0 +0xCACB 0x4ED5 # 0 +0xCACC 0x4F8D # 0 +0xCACD 0x91CA # 0 +0xCACE 0x9970 # 0 +0xCACF 0x6C0F # 0 +0xCAD0 0x5E02 # 0 +0xCAD1 0x6043 # 0 +0xCAD2 0x5BA4 # 0 +0xCAD3 0x89C6 # 0 +0xCAD4 0x8BD5 # 0 +0xCAD5 0x6536 # 0 +0xCAD6 0x624B # 0 +0xCAD7 0x9996 # 0 +0xCAD8 0x5B88 # 0 +0xCAD9 0x5BFF # 0 +0xCADA 0x6388 # 0 +0xCADB 0x552E # 0 +0xCADC 0x53D7 # 0 +0xCADD 0x7626 # 0 +0xCADE 0x517D # 0 +0xCADF 0x852C # 0 +0xCAE0 0x67A2 # 0 +0xCAE1 0x68B3 # 0 +0xCAE2 0x6B8A # 0 +0xCAE3 0x6292 # 0 +0xCAE4 0x8F93 # 0 +0xCAE5 0x53D4 # 0 +0xCAE6 0x8212 # 0 +0xCAE7 0x6DD1 # 0 +0xCAE8 0x758F # 0 +0xCAE9 0x4E66 # 0 +0xCAEA 0x8D4E # 0 +0xCAEB 0x5B70 # 0 +0xCAEC 0x719F # 0 +0xCAED 0x85AF # 0 +0xCAEE 0x6691 # 0 +0xCAEF 0x66D9 # 0 +0xCAF0 0x7F72 # 0 +0xCAF1 0x8700 # 0 +0xCAF2 0x9ECD # 0 +0xCAF3 0x9F20 # 0 +0xCAF4 0x5C5E # 0 +0xCAF5 0x672F # 0 +0xCAF6 0x8FF0 # 0 +0xCAF7 0x6811 # 0 +0xCAF8 0x675F # 0 +0xCAF9 0x620D # 0 +0xCAFA 0x7AD6 # 0 +0xCAFB 0x5885 # 0 +0xCAFC 0x5EB6 # 0 +0xCAFD 0x6570 # 0 +0xCAFE 0x6F31 # 0 +0xCB40 0x8582 # 0 +0xCB41 0x8583 # 0 +0xCB42 0x8586 # 0 +0xCB43 0x8588 # 0 +0xCB44 0x8589 # 0 +0xCB45 0x858A # 0 +0xCB46 0x858B # 0 +0xCB47 0x858C # 0 +0xCB48 0x858D # 0 +0xCB49 0x858E # 0 +0xCB4A 0x8590 # 0 +0xCB4B 0x8591 # 0 +0xCB4C 0x8592 # 0 +0xCB4D 0x8593 # 0 +0xCB4E 0x8594 # 0 +0xCB4F 0x8595 # 0 +0xCB50 0x8596 # 0 +0xCB51 0x8597 # 0 +0xCB52 0x8598 # 0 +0xCB53 0x8599 # 0 +0xCB54 0x859A # 0 +0xCB55 0x859D # 0 +0xCB56 0x859E # 0 +0xCB57 0x859F # 0 +0xCB58 0x85A0 # 0 +0xCB59 0x85A1 # 0 +0xCB5A 0x85A2 # 0 +0xCB5B 0x85A3 # 0 +0xCB5C 0x85A5 # 0 +0xCB5D 0x85A6 # 0 +0xCB5E 0x85A7 # 0 +0xCB5F 0x85A9 # 0 +0xCB60 0x85AB # 0 +0xCB61 0x85AC # 0 +0xCB62 0x85AD # 0 +0xCB63 0x85B1 # 0 +0xCB64 0x85B2 # 0 +0xCB65 0x85B3 # 0 +0xCB66 0x85B4 # 0 +0xCB67 0x85B5 # 0 +0xCB68 0x85B6 # 0 +0xCB69 0x85B8 # 0 +0xCB6A 0x85BA # 0 +0xCB6B 0x85BB # 0 +0xCB6C 0x85BC # 0 +0xCB6D 0x85BD # 0 +0xCB6E 0x85BE # 0 +0xCB6F 0x85BF # 0 +0xCB70 0x85C0 # 0 +0xCB71 0x85C2 # 0 +0xCB72 0x85C3 # 0 +0xCB73 0x85C4 # 0 +0xCB74 0x85C5 # 0 +0xCB75 0x85C6 # 0 +0xCB76 0x85C7 # 0 +0xCB77 0x85C8 # 0 +0xCB78 0x85CA # 0 +0xCB79 0x85CB # 0 +0xCB7A 0x85CC # 0 +0xCB7B 0x85CD # 0 +0xCB7C 0x85CE # 0 +0xCB7D 0x85D1 # 0 +0xCB7E 0x85D2 # 0 +0xCB80 0x85D4 # 0 +0xCB81 0x85D6 # 0 +0xCB82 0x85D7 # 0 +0xCB83 0x85D8 # 0 +0xCB84 0x85D9 # 0 +0xCB85 0x85DA # 0 +0xCB86 0x85DB # 0 +0xCB87 0x85DD # 0 +0xCB88 0x85DE # 0 +0xCB89 0x85DF # 0 +0xCB8A 0x85E0 # 0 +0xCB8B 0x85E1 # 0 +0xCB8C 0x85E2 # 0 +0xCB8D 0x85E3 # 0 +0xCB8E 0x85E5 # 0 +0xCB8F 0x85E6 # 0 +0xCB90 0x85E7 # 0 +0xCB91 0x85E8 # 0 +0xCB92 0x85EA # 0 +0xCB93 0x85EB # 0 +0xCB94 0x85EC # 0 +0xCB95 0x85ED # 0 +0xCB96 0x85EE # 0 +0xCB97 0x85EF # 0 +0xCB98 0x85F0 # 0 +0xCB99 0x85F1 # 0 +0xCB9A 0x85F2 # 0 +0xCB9B 0x85F3 # 0 +0xCB9C 0x85F4 # 0 +0xCB9D 0x85F5 # 0 +0xCB9E 0x85F6 # 0 +0xCB9F 0x85F7 # 0 +0xCBA0 0x85F8 # 0 +0xCBA1 0x6055 # 0 +0xCBA2 0x5237 # 0 +0xCBA3 0x800D # 0 +0xCBA4 0x6454 # 0 +0xCBA5 0x8870 # 0 +0xCBA6 0x7529 # 0 +0xCBA7 0x5E05 # 0 +0xCBA8 0x6813 # 0 +0xCBA9 0x62F4 # 0 +0xCBAA 0x971C # 0 +0xCBAB 0x53CC # 0 +0xCBAC 0x723D # 0 +0xCBAD 0x8C01 # 0 +0xCBAE 0x6C34 # 0 +0xCBAF 0x7761 # 0 +0xCBB0 0x7A0E # 0 +0xCBB1 0x542E # 0 +0xCBB2 0x77AC # 0 +0xCBB3 0x987A # 0 +0xCBB4 0x821C # 0 +0xCBB5 0x8BF4 # 0 +0xCBB6 0x7855 # 0 +0xCBB7 0x6714 # 0 +0xCBB8 0x70C1 # 0 +0xCBB9 0x65AF # 0 +0xCBBA 0x6495 # 0 +0xCBBB 0x5636 # 0 +0xCBBC 0x601D # 0 +0xCBBD 0x79C1 # 0 +0xCBBE 0x53F8 # 0 +0xCBBF 0x4E1D # 0 +0xCBC0 0x6B7B # 0 +0xCBC1 0x8086 # 0 +0xCBC2 0x5BFA # 0 +0xCBC3 0x55E3 # 0 +0xCBC4 0x56DB # 0 +0xCBC5 0x4F3A # 0 +0xCBC6 0x4F3C # 0 +0xCBC7 0x9972 # 0 +0xCBC8 0x5DF3 # 0 +0xCBC9 0x677E # 0 +0xCBCA 0x8038 # 0 +0xCBCB 0x6002 # 0 +0xCBCC 0x9882 # 0 +0xCBCD 0x9001 # 0 +0xCBCE 0x5B8B # 0 +0xCBCF 0x8BBC # 0 +0xCBD0 0x8BF5 # 0 +0xCBD1 0x641C # 0 +0xCBD2 0x8258 # 0 +0xCBD3 0x64DE # 0 +0xCBD4 0x55FD # 0 +0xCBD5 0x82CF # 0 +0xCBD6 0x9165 # 0 +0xCBD7 0x4FD7 # 0 +0xCBD8 0x7D20 # 0 +0xCBD9 0x901F # 0 +0xCBDA 0x7C9F # 0 +0xCBDB 0x50F3 # 0 +0xCBDC 0x5851 # 0 +0xCBDD 0x6EAF # 0 +0xCBDE 0x5BBF # 0 +0xCBDF 0x8BC9 # 0 +0xCBE0 0x8083 # 0 +0xCBE1 0x9178 # 0 +0xCBE2 0x849C # 0 +0xCBE3 0x7B97 # 0 +0xCBE4 0x867D # 0 +0xCBE5 0x968B # 0 +0xCBE6 0x968F # 0 +0xCBE7 0x7EE5 # 0 +0xCBE8 0x9AD3 # 0 +0xCBE9 0x788E # 0 +0xCBEA 0x5C81 # 0 +0xCBEB 0x7A57 # 0 +0xCBEC 0x9042 # 0 +0xCBED 0x96A7 # 0 +0xCBEE 0x795F # 0 +0xCBEF 0x5B59 # 0 +0xCBF0 0x635F # 0 +0xCBF1 0x7B0B # 0 +0xCBF2 0x84D1 # 0 +0xCBF3 0x68AD # 0 +0xCBF4 0x5506 # 0 +0xCBF5 0x7F29 # 0 +0xCBF6 0x7410 # 0 +0xCBF7 0x7D22 # 0 +0xCBF8 0x9501 # 0 +0xCBF9 0x6240 # 0 +0xCBFA 0x584C # 0 +0xCBFB 0x4ED6 # 0 +0xCBFC 0x5B83 # 0 +0xCBFD 0x5979 # 0 +0xCBFE 0x5854 # 0 +0xCC40 0x85F9 # 0 +0xCC41 0x85FA # 0 +0xCC42 0x85FC # 0 +0xCC43 0x85FD # 0 +0xCC44 0x85FE # 0 +0xCC45 0x8600 # 0 +0xCC46 0x8601 # 0 +0xCC47 0x8602 # 0 +0xCC48 0x8603 # 0 +0xCC49 0x8604 # 0 +0xCC4A 0x8606 # 0 +0xCC4B 0x8607 # 0 +0xCC4C 0x8608 # 0 +0xCC4D 0x8609 # 0 +0xCC4E 0x860A # 0 +0xCC4F 0x860B # 0 +0xCC50 0x860C # 0 +0xCC51 0x860D # 0 +0xCC52 0x860E # 0 +0xCC53 0x860F # 0 +0xCC54 0x8610 # 0 +0xCC55 0x8612 # 0 +0xCC56 0x8613 # 0 +0xCC57 0x8614 # 0 +0xCC58 0x8615 # 0 +0xCC59 0x8617 # 0 +0xCC5A 0x8618 # 0 +0xCC5B 0x8619 # 0 +0xCC5C 0x861A # 0 +0xCC5D 0x861B # 0 +0xCC5E 0x861C # 0 +0xCC5F 0x861D # 0 +0xCC60 0x861E # 0 +0xCC61 0x861F # 0 +0xCC62 0x8620 # 0 +0xCC63 0x8621 # 0 +0xCC64 0x8622 # 0 +0xCC65 0x8623 # 0 +0xCC66 0x8624 # 0 +0xCC67 0x8625 # 0 +0xCC68 0x8626 # 0 +0xCC69 0x8628 # 0 +0xCC6A 0x862A # 0 +0xCC6B 0x862B # 0 +0xCC6C 0x862C # 0 +0xCC6D 0x862D # 0 +0xCC6E 0x862E # 0 +0xCC6F 0x862F # 0 +0xCC70 0x8630 # 0 +0xCC71 0x8631 # 0 +0xCC72 0x8632 # 0 +0xCC73 0x8633 # 0 +0xCC74 0x8634 # 0 +0xCC75 0x8635 # 0 +0xCC76 0x8636 # 0 +0xCC77 0x8637 # 0 +0xCC78 0x8639 # 0 +0xCC79 0x863A # 0 +0xCC7A 0x863B # 0 +0xCC7B 0x863D # 0 +0xCC7C 0x863E # 0 +0xCC7D 0x863F # 0 +0xCC7E 0x8640 # 0 +0xCC80 0x8641 # 0 +0xCC81 0x8642 # 0 +0xCC82 0x8643 # 0 +0xCC83 0x8644 # 0 +0xCC84 0x8645 # 0 +0xCC85 0x8646 # 0 +0xCC86 0x8647 # 0 +0xCC87 0x8648 # 0 +0xCC88 0x8649 # 0 +0xCC89 0x864A # 0 +0xCC8A 0x864B # 0 +0xCC8B 0x864C # 0 +0xCC8C 0x8652 # 0 +0xCC8D 0x8653 # 0 +0xCC8E 0x8655 # 0 +0xCC8F 0x8656 # 0 +0xCC90 0x8657 # 0 +0xCC91 0x8658 # 0 +0xCC92 0x8659 # 0 +0xCC93 0x865B # 0 +0xCC94 0x865C # 0 +0xCC95 0x865D # 0 +0xCC96 0x865F # 0 +0xCC97 0x8660 # 0 +0xCC98 0x8661 # 0 +0xCC99 0x8663 # 0 +0xCC9A 0x8664 # 0 +0xCC9B 0x8665 # 0 +0xCC9C 0x8666 # 0 +0xCC9D 0x8667 # 0 +0xCC9E 0x8668 # 0 +0xCC9F 0x8669 # 0 +0xCCA0 0x866A # 0 +0xCCA1 0x736D # 0 +0xCCA2 0x631E # 0 +0xCCA3 0x8E4B # 0 +0xCCA4 0x8E0F # 0 +0xCCA5 0x80CE # 0 +0xCCA6 0x82D4 # 0 +0xCCA7 0x62AC # 0 +0xCCA8 0x53F0 # 0 +0xCCA9 0x6CF0 # 0 +0xCCAA 0x915E # 0 +0xCCAB 0x592A # 0 +0xCCAC 0x6001 # 0 +0xCCAD 0x6C70 # 0 +0xCCAE 0x574D # 0 +0xCCAF 0x644A # 0 +0xCCB0 0x8D2A # 0 +0xCCB1 0x762B # 0 +0xCCB2 0x6EE9 # 0 +0xCCB3 0x575B # 0 +0xCCB4 0x6A80 # 0 +0xCCB5 0x75F0 # 0 +0xCCB6 0x6F6D # 0 +0xCCB7 0x8C2D # 0 +0xCCB8 0x8C08 # 0 +0xCCB9 0x5766 # 0 +0xCCBA 0x6BEF # 0 +0xCCBB 0x8892 # 0 +0xCCBC 0x78B3 # 0 +0xCCBD 0x63A2 # 0 +0xCCBE 0x53F9 # 0 +0xCCBF 0x70AD # 0 +0xCCC0 0x6C64 # 0 +0xCCC1 0x5858 # 0 +0xCCC2 0x642A # 0 +0xCCC3 0x5802 # 0 +0xCCC4 0x68E0 # 0 +0xCCC5 0x819B # 0 +0xCCC6 0x5510 # 0 +0xCCC7 0x7CD6 # 0 +0xCCC8 0x5018 # 0 +0xCCC9 0x8EBA # 0 +0xCCCA 0x6DCC # 0 +0xCCCB 0x8D9F # 0 +0xCCCC 0x70EB # 0 +0xCCCD 0x638F # 0 +0xCCCE 0x6D9B # 0 +0xCCCF 0x6ED4 # 0 +0xCCD0 0x7EE6 # 0 +0xCCD1 0x8404 # 0 +0xCCD2 0x6843 # 0 +0xCCD3 0x9003 # 0 +0xCCD4 0x6DD8 # 0 +0xCCD5 0x9676 # 0 +0xCCD6 0x8BA8 # 0 +0xCCD7 0x5957 # 0 +0xCCD8 0x7279 # 0 +0xCCD9 0x85E4 # 0 +0xCCDA 0x817E # 0 +0xCCDB 0x75BC # 0 +0xCCDC 0x8A8A # 0 +0xCCDD 0x68AF # 0 +0xCCDE 0x5254 # 0 +0xCCDF 0x8E22 # 0 +0xCCE0 0x9511 # 0 +0xCCE1 0x63D0 # 0 +0xCCE2 0x9898 # 0 +0xCCE3 0x8E44 # 0 +0xCCE4 0x557C # 0 +0xCCE5 0x4F53 # 0 +0xCCE6 0x66FF # 0 +0xCCE7 0x568F # 0 +0xCCE8 0x60D5 # 0 +0xCCE9 0x6D95 # 0 +0xCCEA 0x5243 # 0 +0xCCEB 0x5C49 # 0 +0xCCEC 0x5929 # 0 +0xCCED 0x6DFB # 0 +0xCCEE 0x586B # 0 +0xCCEF 0x7530 # 0 +0xCCF0 0x751C # 0 +0xCCF1 0x606C # 0 +0xCCF2 0x8214 # 0 +0xCCF3 0x8146 # 0 +0xCCF4 0x6311 # 0 +0xCCF5 0x6761 # 0 +0xCCF6 0x8FE2 # 0 +0xCCF7 0x773A # 0 +0xCCF8 0x8DF3 # 0 +0xCCF9 0x8D34 # 0 +0xCCFA 0x94C1 # 0 +0xCCFB 0x5E16 # 0 +0xCCFC 0x5385 # 0 +0xCCFD 0x542C # 0 +0xCCFE 0x70C3 # 0 +0xCD40 0x866D # 0 +0xCD41 0x866F # 0 +0xCD42 0x8670 # 0 +0xCD43 0x8672 # 0 +0xCD44 0x8673 # 0 +0xCD45 0x8674 # 0 +0xCD46 0x8675 # 0 +0xCD47 0x8676 # 0 +0xCD48 0x8677 # 0 +0xCD49 0x8678 # 0 +0xCD4A 0x8683 # 0 +0xCD4B 0x8684 # 0 +0xCD4C 0x8685 # 0 +0xCD4D 0x8686 # 0 +0xCD4E 0x8687 # 0 +0xCD4F 0x8688 # 0 +0xCD50 0x8689 # 0 +0xCD51 0x868E # 0 +0xCD52 0x868F # 0 +0xCD53 0x8690 # 0 +0xCD54 0x8691 # 0 +0xCD55 0x8692 # 0 +0xCD56 0x8694 # 0 +0xCD57 0x8696 # 0 +0xCD58 0x8697 # 0 +0xCD59 0x8698 # 0 +0xCD5A 0x8699 # 0 +0xCD5B 0x869A # 0 +0xCD5C 0x869B # 0 +0xCD5D 0x869E # 0 +0xCD5E 0x869F # 0 +0xCD5F 0x86A0 # 0 +0xCD60 0x86A1 # 0 +0xCD61 0x86A2 # 0 +0xCD62 0x86A5 # 0 +0xCD63 0x86A6 # 0 +0xCD64 0x86AB # 0 +0xCD65 0x86AD # 0 +0xCD66 0x86AE # 0 +0xCD67 0x86B2 # 0 +0xCD68 0x86B3 # 0 +0xCD69 0x86B7 # 0 +0xCD6A 0x86B8 # 0 +0xCD6B 0x86B9 # 0 +0xCD6C 0x86BB # 0 +0xCD6D 0x86BC # 0 +0xCD6E 0x86BD # 0 +0xCD6F 0x86BE # 0 +0xCD70 0x86BF # 0 +0xCD71 0x86C1 # 0 +0xCD72 0x86C2 # 0 +0xCD73 0x86C3 # 0 +0xCD74 0x86C5 # 0 +0xCD75 0x86C8 # 0 +0xCD76 0x86CC # 0 +0xCD77 0x86CD # 0 +0xCD78 0x86D2 # 0 +0xCD79 0x86D3 # 0 +0xCD7A 0x86D5 # 0 +0xCD7B 0x86D6 # 0 +0xCD7C 0x86D7 # 0 +0xCD7D 0x86DA # 0 +0xCD7E 0x86DC # 0 +0xCD80 0x86DD # 0 +0xCD81 0x86E0 # 0 +0xCD82 0x86E1 # 0 +0xCD83 0x86E2 # 0 +0xCD84 0x86E3 # 0 +0xCD85 0x86E5 # 0 +0xCD86 0x86E6 # 0 +0xCD87 0x86E7 # 0 +0xCD88 0x86E8 # 0 +0xCD89 0x86EA # 0 +0xCD8A 0x86EB # 0 +0xCD8B 0x86EC # 0 +0xCD8C 0x86EF # 0 +0xCD8D 0x86F5 # 0 +0xCD8E 0x86F6 # 0 +0xCD8F 0x86F7 # 0 +0xCD90 0x86FA # 0 +0xCD91 0x86FB # 0 +0xCD92 0x86FC # 0 +0xCD93 0x86FD # 0 +0xCD94 0x86FF # 0 +0xCD95 0x8701 # 0 +0xCD96 0x8704 # 0 +0xCD97 0x8705 # 0 +0xCD98 0x8706 # 0 +0xCD99 0x870B # 0 +0xCD9A 0x870C # 0 +0xCD9B 0x870E # 0 +0xCD9C 0x870F # 0 +0xCD9D 0x8710 # 0 +0xCD9E 0x8711 # 0 +0xCD9F 0x8714 # 0 +0xCDA0 0x8716 # 0 +0xCDA1 0x6C40 # 0 +0xCDA2 0x5EF7 # 0 +0xCDA3 0x505C # 0 +0xCDA4 0x4EAD # 0 +0xCDA5 0x5EAD # 0 +0xCDA6 0x633A # 0 +0xCDA7 0x8247 # 0 +0xCDA8 0x901A # 0 +0xCDA9 0x6850 # 0 +0xCDAA 0x916E # 0 +0xCDAB 0x77B3 # 0 +0xCDAC 0x540C # 0 +0xCDAD 0x94DC # 0 +0xCDAE 0x5F64 # 0 +0xCDAF 0x7AE5 # 0 +0xCDB0 0x6876 # 0 +0xCDB1 0x6345 # 0 +0xCDB2 0x7B52 # 0 +0xCDB3 0x7EDF # 0 +0xCDB4 0x75DB # 0 +0xCDB5 0x5077 # 0 +0xCDB6 0x6295 # 0 +0xCDB7 0x5934 # 0 +0xCDB8 0x900F # 0 +0xCDB9 0x51F8 # 0 +0xCDBA 0x79C3 # 0 +0xCDBB 0x7A81 # 0 +0xCDBC 0x56FE # 0 +0xCDBD 0x5F92 # 0 +0xCDBE 0x9014 # 0 +0xCDBF 0x6D82 # 0 +0xCDC0 0x5C60 # 0 +0xCDC1 0x571F # 0 +0xCDC2 0x5410 # 0 +0xCDC3 0x5154 # 0 +0xCDC4 0x6E4D # 0 +0xCDC5 0x56E2 # 0 +0xCDC6 0x63A8 # 0 +0xCDC7 0x9893 # 0 +0xCDC8 0x817F # 0 +0xCDC9 0x8715 # 0 +0xCDCA 0x892A # 0 +0xCDCB 0x9000 # 0 +0xCDCC 0x541E # 0 +0xCDCD 0x5C6F # 0 +0xCDCE 0x81C0 # 0 +0xCDCF 0x62D6 # 0 +0xCDD0 0x6258 # 0 +0xCDD1 0x8131 # 0 +0xCDD2 0x9E35 # 0 +0xCDD3 0x9640 # 0 +0xCDD4 0x9A6E # 0 +0xCDD5 0x9A7C # 0 +0xCDD6 0x692D # 0 +0xCDD7 0x59A5 # 0 +0xCDD8 0x62D3 # 0 +0xCDD9 0x553E # 0 +0xCDDA 0x6316 # 0 +0xCDDB 0x54C7 # 0 +0xCDDC 0x86D9 # 0 +0xCDDD 0x6D3C # 0 +0xCDDE 0x5A03 # 0 +0xCDDF 0x74E6 # 0 +0xCDE0 0x889C # 0 +0xCDE1 0x6B6A # 0 +0xCDE2 0x5916 # 0 +0xCDE3 0x8C4C # 0 +0xCDE4 0x5F2F # 0 +0xCDE5 0x6E7E # 0 +0xCDE6 0x73A9 # 0 +0xCDE7 0x987D # 0 +0xCDE8 0x4E38 # 0 +0xCDE9 0x70F7 # 0 +0xCDEA 0x5B8C # 0 +0xCDEB 0x7897 # 0 +0xCDEC 0x633D # 0 +0xCDED 0x665A # 0 +0xCDEE 0x7696 # 0 +0xCDEF 0x60CB # 0 +0xCDF0 0x5B9B # 0 +0xCDF1 0x5A49 # 0 +0xCDF2 0x4E07 # 0 +0xCDF3 0x8155 # 0 +0xCDF4 0x6C6A # 0 +0xCDF5 0x738B # 0 +0xCDF6 0x4EA1 # 0 +0xCDF7 0x6789 # 0 +0xCDF8 0x7F51 # 0 +0xCDF9 0x5F80 # 0 +0xCDFA 0x65FA # 0 +0xCDFB 0x671B # 0 +0xCDFC 0x5FD8 # 0 +0xCDFD 0x5984 # 0 +0xCDFE 0x5A01 # 0 +0xCE40 0x8719 # 0 +0xCE41 0x871B # 0 +0xCE42 0x871D # 0 +0xCE43 0x871F # 0 +0xCE44 0x8720 # 0 +0xCE45 0x8724 # 0 +0xCE46 0x8726 # 0 +0xCE47 0x8727 # 0 +0xCE48 0x8728 # 0 +0xCE49 0x872A # 0 +0xCE4A 0x872B # 0 +0xCE4B 0x872C # 0 +0xCE4C 0x872D # 0 +0xCE4D 0x872F # 0 +0xCE4E 0x8730 # 0 +0xCE4F 0x8732 # 0 +0xCE50 0x8733 # 0 +0xCE51 0x8735 # 0 +0xCE52 0x8736 # 0 +0xCE53 0x8738 # 0 +0xCE54 0x8739 # 0 +0xCE55 0x873A # 0 +0xCE56 0x873C # 0 +0xCE57 0x873D # 0 +0xCE58 0x8740 # 0 +0xCE59 0x8741 # 0 +0xCE5A 0x8742 # 0 +0xCE5B 0x8743 # 0 +0xCE5C 0x8744 # 0 +0xCE5D 0x8745 # 0 +0xCE5E 0x8746 # 0 +0xCE5F 0x874A # 0 +0xCE60 0x874B # 0 +0xCE61 0x874D # 0 +0xCE62 0x874F # 0 +0xCE63 0x8750 # 0 +0xCE64 0x8751 # 0 +0xCE65 0x8752 # 0 +0xCE66 0x8754 # 0 +0xCE67 0x8755 # 0 +0xCE68 0x8756 # 0 +0xCE69 0x8758 # 0 +0xCE6A 0x875A # 0 +0xCE6B 0x875B # 0 +0xCE6C 0x875C # 0 +0xCE6D 0x875D # 0 +0xCE6E 0x875E # 0 +0xCE6F 0x875F # 0 +0xCE70 0x8761 # 0 +0xCE71 0x8762 # 0 +0xCE72 0x8766 # 0 +0xCE73 0x8767 # 0 +0xCE74 0x8768 # 0 +0xCE75 0x8769 # 0 +0xCE76 0x876A # 0 +0xCE77 0x876B # 0 +0xCE78 0x876C # 0 +0xCE79 0x876D # 0 +0xCE7A 0x876F # 0 +0xCE7B 0x8771 # 0 +0xCE7C 0x8772 # 0 +0xCE7D 0x8773 # 0 +0xCE7E 0x8775 # 0 +0xCE80 0x8777 # 0 +0xCE81 0x8778 # 0 +0xCE82 0x8779 # 0 +0xCE83 0x877A # 0 +0xCE84 0x877F # 0 +0xCE85 0x8780 # 0 +0xCE86 0x8781 # 0 +0xCE87 0x8784 # 0 +0xCE88 0x8786 # 0 +0xCE89 0x8787 # 0 +0xCE8A 0x8789 # 0 +0xCE8B 0x878A # 0 +0xCE8C 0x878C # 0 +0xCE8D 0x878E # 0 +0xCE8E 0x878F # 0 +0xCE8F 0x8790 # 0 +0xCE90 0x8791 # 0 +0xCE91 0x8792 # 0 +0xCE92 0x8794 # 0 +0xCE93 0x8795 # 0 +0xCE94 0x8796 # 0 +0xCE95 0x8798 # 0 +0xCE96 0x8799 # 0 +0xCE97 0x879A # 0 +0xCE98 0x879B # 0 +0xCE99 0x879C # 0 +0xCE9A 0x879D # 0 +0xCE9B 0x879E # 0 +0xCE9C 0x87A0 # 0 +0xCE9D 0x87A1 # 0 +0xCE9E 0x87A2 # 0 +0xCE9F 0x87A3 # 0 +0xCEA0 0x87A4 # 0 +0xCEA1 0x5DCD # 0 +0xCEA2 0x5FAE # 0 +0xCEA3 0x5371 # 0 +0xCEA4 0x97E6 # 0 +0xCEA5 0x8FDD # 0 +0xCEA6 0x6845 # 0 +0xCEA7 0x56F4 # 0 +0xCEA8 0x552F # 0 +0xCEA9 0x60DF # 0 +0xCEAA 0x4E3A # 0 +0xCEAB 0x6F4D # 0 +0xCEAC 0x7EF4 # 0 +0xCEAD 0x82C7 # 0 +0xCEAE 0x840E # 0 +0xCEAF 0x59D4 # 0 +0xCEB0 0x4F1F # 0 +0xCEB1 0x4F2A # 0 +0xCEB2 0x5C3E # 0 +0xCEB3 0x7EAC # 0 +0xCEB4 0x672A # 0 +0xCEB5 0x851A # 0 +0xCEB6 0x5473 # 0 +0xCEB7 0x754F # 0 +0xCEB8 0x80C3 # 0 +0xCEB9 0x5582 # 0 +0xCEBA 0x9B4F # 0 +0xCEBB 0x4F4D # 0 +0xCEBC 0x6E2D # 0 +0xCEBD 0x8C13 # 0 +0xCEBE 0x5C09 # 0 +0xCEBF 0x6170 # 0 +0xCEC0 0x536B # 0 +0xCEC1 0x761F # 0 +0xCEC2 0x6E29 # 0 +0xCEC3 0x868A # 0 +0xCEC4 0x6587 # 0 +0xCEC5 0x95FB # 0 +0xCEC6 0x7EB9 # 0 +0xCEC7 0x543B # 0 +0xCEC8 0x7A33 # 0 +0xCEC9 0x7D0A # 0 +0xCECA 0x95EE # 0 +0xCECB 0x55E1 # 0 +0xCECC 0x7FC1 # 0 +0xCECD 0x74EE # 0 +0xCECE 0x631D # 0 +0xCECF 0x8717 # 0 +0xCED0 0x6DA1 # 0 +0xCED1 0x7A9D # 0 +0xCED2 0x6211 # 0 +0xCED3 0x65A1 # 0 +0xCED4 0x5367 # 0 +0xCED5 0x63E1 # 0 +0xCED6 0x6C83 # 0 +0xCED7 0x5DEB # 0 +0xCED8 0x545C # 0 +0xCED9 0x94A8 # 0 +0xCEDA 0x4E4C # 0 +0xCEDB 0x6C61 # 0 +0xCEDC 0x8BEC # 0 +0xCEDD 0x5C4B # 0 +0xCEDE 0x65E0 # 0 +0xCEDF 0x829C # 0 +0xCEE0 0x68A7 # 0 +0xCEE1 0x543E # 0 +0xCEE2 0x5434 # 0 +0xCEE3 0x6BCB # 0 +0xCEE4 0x6B66 # 0 +0xCEE5 0x4E94 # 0 +0xCEE6 0x6342 # 0 +0xCEE7 0x5348 # 0 +0xCEE8 0x821E # 0 +0xCEE9 0x4F0D # 0 +0xCEEA 0x4FAE # 0 +0xCEEB 0x575E # 0 +0xCEEC 0x620A # 0 +0xCEED 0x96FE # 0 +0xCEEE 0x6664 # 0 +0xCEEF 0x7269 # 0 +0xCEF0 0x52FF # 0 +0xCEF1 0x52A1 # 0 +0xCEF2 0x609F # 0 +0xCEF3 0x8BEF # 0 +0xCEF4 0x6614 # 0 +0xCEF5 0x7199 # 0 +0xCEF6 0x6790 # 0 +0xCEF7 0x897F # 0 +0xCEF8 0x7852 # 0 +0xCEF9 0x77FD # 0 +0xCEFA 0x6670 # 0 +0xCEFB 0x563B # 0 +0xCEFC 0x5438 # 0 +0xCEFD 0x9521 # 0 +0xCEFE 0x727A # 0 +0xCF40 0x87A5 # 0 +0xCF41 0x87A6 # 0 +0xCF42 0x87A7 # 0 +0xCF43 0x87A9 # 0 +0xCF44 0x87AA # 0 +0xCF45 0x87AE # 0 +0xCF46 0x87B0 # 0 +0xCF47 0x87B1 # 0 +0xCF48 0x87B2 # 0 +0xCF49 0x87B4 # 0 +0xCF4A 0x87B6 # 0 +0xCF4B 0x87B7 # 0 +0xCF4C 0x87B8 # 0 +0xCF4D 0x87B9 # 0 +0xCF4E 0x87BB # 0 +0xCF4F 0x87BC # 0 +0xCF50 0x87BE # 0 +0xCF51 0x87BF # 0 +0xCF52 0x87C1 # 0 +0xCF53 0x87C2 # 0 +0xCF54 0x87C3 # 0 +0xCF55 0x87C4 # 0 +0xCF56 0x87C5 # 0 +0xCF57 0x87C7 # 0 +0xCF58 0x87C8 # 0 +0xCF59 0x87C9 # 0 +0xCF5A 0x87CC # 0 +0xCF5B 0x87CD # 0 +0xCF5C 0x87CE # 0 +0xCF5D 0x87CF # 0 +0xCF5E 0x87D0 # 0 +0xCF5F 0x87D4 # 0 +0xCF60 0x87D5 # 0 +0xCF61 0x87D6 # 0 +0xCF62 0x87D7 # 0 +0xCF63 0x87D8 # 0 +0xCF64 0x87D9 # 0 +0xCF65 0x87DA # 0 +0xCF66 0x87DC # 0 +0xCF67 0x87DD # 0 +0xCF68 0x87DE # 0 +0xCF69 0x87DF # 0 +0xCF6A 0x87E1 # 0 +0xCF6B 0x87E2 # 0 +0xCF6C 0x87E3 # 0 +0xCF6D 0x87E4 # 0 +0xCF6E 0x87E6 # 0 +0xCF6F 0x87E7 # 0 +0xCF70 0x87E8 # 0 +0xCF71 0x87E9 # 0 +0xCF72 0x87EB # 0 +0xCF73 0x87EC # 0 +0xCF74 0x87ED # 0 +0xCF75 0x87EF # 0 +0xCF76 0x87F0 # 0 +0xCF77 0x87F1 # 0 +0xCF78 0x87F2 # 0 +0xCF79 0x87F3 # 0 +0xCF7A 0x87F4 # 0 +0xCF7B 0x87F5 # 0 +0xCF7C 0x87F6 # 0 +0xCF7D 0x87F7 # 0 +0xCF7E 0x87F8 # 0 +0xCF80 0x87FA # 0 +0xCF81 0x87FB # 0 +0xCF82 0x87FC # 0 +0xCF83 0x87FD # 0 +0xCF84 0x87FF # 0 +0xCF85 0x8800 # 0 +0xCF86 0x8801 # 0 +0xCF87 0x8802 # 0 +0xCF88 0x8804 # 0 +0xCF89 0x8805 # 0 +0xCF8A 0x8806 # 0 +0xCF8B 0x8807 # 0 +0xCF8C 0x8808 # 0 +0xCF8D 0x8809 # 0 +0xCF8E 0x880B # 0 +0xCF8F 0x880C # 0 +0xCF90 0x880D # 0 +0xCF91 0x880E # 0 +0xCF92 0x880F # 0 +0xCF93 0x8810 # 0 +0xCF94 0x8811 # 0 +0xCF95 0x8812 # 0 +0xCF96 0x8814 # 0 +0xCF97 0x8817 # 0 +0xCF98 0x8818 # 0 +0xCF99 0x8819 # 0 +0xCF9A 0x881A # 0 +0xCF9B 0x881C # 0 +0xCF9C 0x881D # 0 +0xCF9D 0x881E # 0 +0xCF9E 0x881F # 0 +0xCF9F 0x8820 # 0 +0xCFA0 0x8823 # 0 +0xCFA1 0x7A00 # 0 +0xCFA2 0x606F # 0 +0xCFA3 0x5E0C # 0 +0xCFA4 0x6089 # 0 +0xCFA5 0x819D # 0 +0xCFA6 0x5915 # 0 +0xCFA7 0x60DC # 0 +0xCFA8 0x7184 # 0 +0xCFA9 0x70EF # 0 +0xCFAA 0x6EAA # 0 +0xCFAB 0x6C50 # 0 +0xCFAC 0x7280 # 0 +0xCFAD 0x6A84 # 0 +0xCFAE 0x88AD # 0 +0xCFAF 0x5E2D # 0 +0xCFB0 0x4E60 # 0 +0xCFB1 0x5AB3 # 0 +0xCFB2 0x559C # 0 +0xCFB3 0x94E3 # 0 +0xCFB4 0x6D17 # 0 +0xCFB5 0x7CFB # 0 +0xCFB6 0x9699 # 0 +0xCFB7 0x620F # 0 +0xCFB8 0x7EC6 # 0 +0xCFB9 0x778E # 0 +0xCFBA 0x867E # 0 +0xCFBB 0x5323 # 0 +0xCFBC 0x971E # 0 +0xCFBD 0x8F96 # 0 +0xCFBE 0x6687 # 0 +0xCFBF 0x5CE1 # 0 +0xCFC0 0x4FA0 # 0 +0xCFC1 0x72ED # 0 +0xCFC2 0x4E0B # 0 +0xCFC3 0x53A6 # 0 +0xCFC4 0x590F # 0 +0xCFC5 0x5413 # 0 +0xCFC6 0x6380 # 0 +0xCFC7 0x9528 # 0 +0xCFC8 0x5148 # 0 +0xCFC9 0x4ED9 # 0 +0xCFCA 0x9C9C # 0 +0xCFCB 0x7EA4 # 0 +0xCFCC 0x54B8 # 0 +0xCFCD 0x8D24 # 0 +0xCFCE 0x8854 # 0 +0xCFCF 0x8237 # 0 +0xCFD0 0x95F2 # 0 +0xCFD1 0x6D8E # 0 +0xCFD2 0x5F26 # 0 +0xCFD3 0x5ACC # 0 +0xCFD4 0x663E # 0 +0xCFD5 0x9669 # 0 +0xCFD6 0x73B0 # 0 +0xCFD7 0x732E # 0 +0xCFD8 0x53BF # 0 +0xCFD9 0x817A # 0 +0xCFDA 0x9985 # 0 +0xCFDB 0x7FA1 # 0 +0xCFDC 0x5BAA # 0 +0xCFDD 0x9677 # 0 +0xCFDE 0x9650 # 0 +0xCFDF 0x7EBF # 0 +0xCFE0 0x76F8 # 0 +0xCFE1 0x53A2 # 0 +0xCFE2 0x9576 # 0 +0xCFE3 0x9999 # 0 +0xCFE4 0x7BB1 # 0 +0xCFE5 0x8944 # 0 +0xCFE6 0x6E58 # 0 +0xCFE7 0x4E61 # 0 +0xCFE8 0x7FD4 # 0 +0xCFE9 0x7965 # 0 +0xCFEA 0x8BE6 # 0 +0xCFEB 0x60F3 # 0 +0xCFEC 0x54CD # 0 +0xCFED 0x4EAB # 0 +0xCFEE 0x9879 # 0 +0xCFEF 0x5DF7 # 0 +0xCFF0 0x6A61 # 0 +0xCFF1 0x50CF # 0 +0xCFF2 0x5411 # 0 +0xCFF3 0x8C61 # 0 +0xCFF4 0x8427 # 0 +0xCFF5 0x785D # 0 +0xCFF6 0x9704 # 0 +0xCFF7 0x524A # 0 +0xCFF8 0x54EE # 0 +0xCFF9 0x56A3 # 0 +0xCFFA 0x9500 # 0 +0xCFFB 0x6D88 # 0 +0xCFFC 0x5BB5 # 0 +0xCFFD 0x6DC6 # 0 +0xCFFE 0x6653 # 0 +0xD040 0x8824 # 0 +0xD041 0x8825 # 0 +0xD042 0x8826 # 0 +0xD043 0x8827 # 0 +0xD044 0x8828 # 0 +0xD045 0x8829 # 0 +0xD046 0x882A # 0 +0xD047 0x882B # 0 +0xD048 0x882C # 0 +0xD049 0x882D # 0 +0xD04A 0x882E # 0 +0xD04B 0x882F # 0 +0xD04C 0x8830 # 0 +0xD04D 0x8831 # 0 +0xD04E 0x8833 # 0 +0xD04F 0x8834 # 0 +0xD050 0x8835 # 0 +0xD051 0x8836 # 0 +0xD052 0x8837 # 0 +0xD053 0x8838 # 0 +0xD054 0x883A # 0 +0xD055 0x883B # 0 +0xD056 0x883D # 0 +0xD057 0x883E # 0 +0xD058 0x883F # 0 +0xD059 0x8841 # 0 +0xD05A 0x8842 # 0 +0xD05B 0x8843 # 0 +0xD05C 0x8846 # 0 +0xD05D 0x8847 # 0 +0xD05E 0x8848 # 0 +0xD05F 0x8849 # 0 +0xD060 0x884A # 0 +0xD061 0x884B # 0 +0xD062 0x884E # 0 +0xD063 0x884F # 0 +0xD064 0x8850 # 0 +0xD065 0x8851 # 0 +0xD066 0x8852 # 0 +0xD067 0x8853 # 0 +0xD068 0x8855 # 0 +0xD069 0x8856 # 0 +0xD06A 0x8858 # 0 +0xD06B 0x885A # 0 +0xD06C 0x885B # 0 +0xD06D 0x885C # 0 +0xD06E 0x885D # 0 +0xD06F 0x885E # 0 +0xD070 0x885F # 0 +0xD071 0x8860 # 0 +0xD072 0x8866 # 0 +0xD073 0x8867 # 0 +0xD074 0x886A # 0 +0xD075 0x886D # 0 +0xD076 0x886F # 0 +0xD077 0x8871 # 0 +0xD078 0x8873 # 0 +0xD079 0x8874 # 0 +0xD07A 0x8875 # 0 +0xD07B 0x8876 # 0 +0xD07C 0x8878 # 0 +0xD07D 0x8879 # 0 +0xD07E 0x887A # 0 +0xD080 0x887B # 0 +0xD081 0x887C # 0 +0xD082 0x8880 # 0 +0xD083 0x8883 # 0 +0xD084 0x8886 # 0 +0xD085 0x8887 # 0 +0xD086 0x8889 # 0 +0xD087 0x888A # 0 +0xD088 0x888C # 0 +0xD089 0x888E # 0 +0xD08A 0x888F # 0 +0xD08B 0x8890 # 0 +0xD08C 0x8891 # 0 +0xD08D 0x8893 # 0 +0xD08E 0x8894 # 0 +0xD08F 0x8895 # 0 +0xD090 0x8897 # 0 +0xD091 0x8898 # 0 +0xD092 0x8899 # 0 +0xD093 0x889A # 0 +0xD094 0x889B # 0 +0xD095 0x889D # 0 +0xD096 0x889E # 0 +0xD097 0x889F # 0 +0xD098 0x88A0 # 0 +0xD099 0x88A1 # 0 +0xD09A 0x88A3 # 0 +0xD09B 0x88A5 # 0 +0xD09C 0x88A6 # 0 +0xD09D 0x88A7 # 0 +0xD09E 0x88A8 # 0 +0xD09F 0x88A9 # 0 +0xD0A0 0x88AA # 0 +0xD0A1 0x5C0F # 0 +0xD0A2 0x5B5D # 0 +0xD0A3 0x6821 # 0 +0xD0A4 0x8096 # 0 +0xD0A5 0x5578 # 0 +0xD0A6 0x7B11 # 0 +0xD0A7 0x6548 # 0 +0xD0A8 0x6954 # 0 +0xD0A9 0x4E9B # 0 +0xD0AA 0x6B47 # 0 +0xD0AB 0x874E # 0 +0xD0AC 0x978B # 0 +0xD0AD 0x534F # 0 +0xD0AE 0x631F # 0 +0xD0AF 0x643A # 0 +0xD0B0 0x90AA # 0 +0xD0B1 0x659C # 0 +0xD0B2 0x80C1 # 0 +0xD0B3 0x8C10 # 0 +0xD0B4 0x5199 # 0 +0xD0B5 0x68B0 # 0 +0xD0B6 0x5378 # 0 +0xD0B7 0x87F9 # 0 +0xD0B8 0x61C8 # 0 +0xD0B9 0x6CC4 # 0 +0xD0BA 0x6CFB # 0 +0xD0BB 0x8C22 # 0 +0xD0BC 0x5C51 # 0 +0xD0BD 0x85AA # 0 +0xD0BE 0x82AF # 0 +0xD0BF 0x950C # 0 +0xD0C0 0x6B23 # 0 +0xD0C1 0x8F9B # 0 +0xD0C2 0x65B0 # 0 +0xD0C3 0x5FFB # 0 +0xD0C4 0x5FC3 # 0 +0xD0C5 0x4FE1 # 0 +0xD0C6 0x8845 # 0 +0xD0C7 0x661F # 0 +0xD0C8 0x8165 # 0 +0xD0C9 0x7329 # 0 +0xD0CA 0x60FA # 0 +0xD0CB 0x5174 # 0 +0xD0CC 0x5211 # 0 +0xD0CD 0x578B # 0 +0xD0CE 0x5F62 # 0 +0xD0CF 0x90A2 # 0 +0xD0D0 0x884C # 0 +0xD0D1 0x9192 # 0 +0xD0D2 0x5E78 # 0 +0xD0D3 0x674F # 0 +0xD0D4 0x6027 # 0 +0xD0D5 0x59D3 # 0 +0xD0D6 0x5144 # 0 +0xD0D7 0x51F6 # 0 +0xD0D8 0x80F8 # 0 +0xD0D9 0x5308 # 0 +0xD0DA 0x6C79 # 0 +0xD0DB 0x96C4 # 0 +0xD0DC 0x718A # 0 +0xD0DD 0x4F11 # 0 +0xD0DE 0x4FEE # 0 +0xD0DF 0x7F9E # 0 +0xD0E0 0x673D # 0 +0xD0E1 0x55C5 # 0 +0xD0E2 0x9508 # 0 +0xD0E3 0x79C0 # 0 +0xD0E4 0x8896 # 0 +0xD0E5 0x7EE3 # 0 +0xD0E6 0x589F # 0 +0xD0E7 0x620C # 0 +0xD0E8 0x9700 # 0 +0xD0E9 0x865A # 0 +0xD0EA 0x5618 # 0 +0xD0EB 0x987B # 0 +0xD0EC 0x5F90 # 0 +0xD0ED 0x8BB8 # 0 +0xD0EE 0x84C4 # 0 +0xD0EF 0x9157 # 0 +0xD0F0 0x53D9 # 0 +0xD0F1 0x65ED # 0 +0xD0F2 0x5E8F # 0 +0xD0F3 0x755C # 0 +0xD0F4 0x6064 # 0 +0xD0F5 0x7D6E # 0 +0xD0F6 0x5A7F # 0 +0xD0F7 0x7EEA # 0 +0xD0F8 0x7EED # 0 +0xD0F9 0x8F69 # 0 +0xD0FA 0x55A7 # 0 +0xD0FB 0x5BA3 # 0 +0xD0FC 0x60AC # 0 +0xD0FD 0x65CB # 0 +0xD0FE 0x7384 # 0 +0xD140 0x88AC # 0 +0xD141 0x88AE # 0 +0xD142 0x88AF # 0 +0xD143 0x88B0 # 0 +0xD144 0x88B2 # 0 +0xD145 0x88B3 # 0 +0xD146 0x88B4 # 0 +0xD147 0x88B5 # 0 +0xD148 0x88B6 # 0 +0xD149 0x88B8 # 0 +0xD14A 0x88B9 # 0 +0xD14B 0x88BA # 0 +0xD14C 0x88BB # 0 +0xD14D 0x88BD # 0 +0xD14E 0x88BE # 0 +0xD14F 0x88BF # 0 +0xD150 0x88C0 # 0 +0xD151 0x88C3 # 0 +0xD152 0x88C4 # 0 +0xD153 0x88C7 # 0 +0xD154 0x88C8 # 0 +0xD155 0x88CA # 0 +0xD156 0x88CB # 0 +0xD157 0x88CC # 0 +0xD158 0x88CD # 0 +0xD159 0x88CF # 0 +0xD15A 0x88D0 # 0 +0xD15B 0x88D1 # 0 +0xD15C 0x88D3 # 0 +0xD15D 0x88D6 # 0 +0xD15E 0x88D7 # 0 +0xD15F 0x88DA # 0 +0xD160 0x88DB # 0 +0xD161 0x88DC # 0 +0xD162 0x88DD # 0 +0xD163 0x88DE # 0 +0xD164 0x88E0 # 0 +0xD165 0x88E1 # 0 +0xD166 0x88E6 # 0 +0xD167 0x88E7 # 0 +0xD168 0x88E9 # 0 +0xD169 0x88EA # 0 +0xD16A 0x88EB # 0 +0xD16B 0x88EC # 0 +0xD16C 0x88ED # 0 +0xD16D 0x88EE # 0 +0xD16E 0x88EF # 0 +0xD16F 0x88F2 # 0 +0xD170 0x88F5 # 0 +0xD171 0x88F6 # 0 +0xD172 0x88F7 # 0 +0xD173 0x88FA # 0 +0xD174 0x88FB # 0 +0xD175 0x88FD # 0 +0xD176 0x88FF # 0 +0xD177 0x8900 # 0 +0xD178 0x8901 # 0 +0xD179 0x8903 # 0 +0xD17A 0x8904 # 0 +0xD17B 0x8905 # 0 +0xD17C 0x8906 # 0 +0xD17D 0x8907 # 0 +0xD17E 0x8908 # 0 +0xD180 0x8909 # 0 +0xD181 0x890B # 0 +0xD182 0x890C # 0 +0xD183 0x890D # 0 +0xD184 0x890E # 0 +0xD185 0x890F # 0 +0xD186 0x8911 # 0 +0xD187 0x8914 # 0 +0xD188 0x8915 # 0 +0xD189 0x8916 # 0 +0xD18A 0x8917 # 0 +0xD18B 0x8918 # 0 +0xD18C 0x891C # 0 +0xD18D 0x891D # 0 +0xD18E 0x891E # 0 +0xD18F 0x891F # 0 +0xD190 0x8920 # 0 +0xD191 0x8922 # 0 +0xD192 0x8923 # 0 +0xD193 0x8924 # 0 +0xD194 0x8926 # 0 +0xD195 0x8927 # 0 +0xD196 0x8928 # 0 +0xD197 0x8929 # 0 +0xD198 0x892C # 0 +0xD199 0x892D # 0 +0xD19A 0x892E # 0 +0xD19B 0x892F # 0 +0xD19C 0x8931 # 0 +0xD19D 0x8932 # 0 +0xD19E 0x8933 # 0 +0xD19F 0x8935 # 0 +0xD1A0 0x8937 # 0 +0xD1A1 0x9009 # 0 +0xD1A2 0x7663 # 0 +0xD1A3 0x7729 # 0 +0xD1A4 0x7EDA # 0 +0xD1A5 0x9774 # 0 +0xD1A6 0x859B # 0 +0xD1A7 0x5B66 # 0 +0xD1A8 0x7A74 # 0 +0xD1A9 0x96EA # 0 +0xD1AA 0x8840 # 0 +0xD1AB 0x52CB # 0 +0xD1AC 0x718F # 0 +0xD1AD 0x5FAA # 0 +0xD1AE 0x65EC # 0 +0xD1AF 0x8BE2 # 0 +0xD1B0 0x5BFB # 0 +0xD1B1 0x9A6F # 0 +0xD1B2 0x5DE1 # 0 +0xD1B3 0x6B89 # 0 +0xD1B4 0x6C5B # 0 +0xD1B5 0x8BAD # 0 +0xD1B6 0x8BAF # 0 +0xD1B7 0x900A # 0 +0xD1B8 0x8FC5 # 0 +0xD1B9 0x538B # 0 +0xD1BA 0x62BC # 0 +0xD1BB 0x9E26 # 0 +0xD1BC 0x9E2D # 0 +0xD1BD 0x5440 # 0 +0xD1BE 0x4E2B # 0 +0xD1BF 0x82BD # 0 +0xD1C0 0x7259 # 0 +0xD1C1 0x869C # 0 +0xD1C2 0x5D16 # 0 +0xD1C3 0x8859 # 0 +0xD1C4 0x6DAF # 0 +0xD1C5 0x96C5 # 0 +0xD1C6 0x54D1 # 0 +0xD1C7 0x4E9A # 0 +0xD1C8 0x8BB6 # 0 +0xD1C9 0x7109 # 0 +0xD1CA 0x54BD # 0 +0xD1CB 0x9609 # 0 +0xD1CC 0x70DF # 0 +0xD1CD 0x6DF9 # 0 +0xD1CE 0x76D0 # 0 +0xD1CF 0x4E25 # 0 +0xD1D0 0x7814 # 0 +0xD1D1 0x8712 # 0 +0xD1D2 0x5CA9 # 0 +0xD1D3 0x5EF6 # 0 +0xD1D4 0x8A00 # 0 +0xD1D5 0x989C # 0 +0xD1D6 0x960E # 0 +0xD1D7 0x708E # 0 +0xD1D8 0x6CBF # 0 +0xD1D9 0x5944 # 0 +0xD1DA 0x63A9 # 0 +0xD1DB 0x773C # 0 +0xD1DC 0x884D # 0 +0xD1DD 0x6F14 # 0 +0xD1DE 0x8273 # 0 +0xD1DF 0x5830 # 0 +0xD1E0 0x71D5 # 0 +0xD1E1 0x538C # 0 +0xD1E2 0x781A # 0 +0xD1E3 0x96C1 # 0 +0xD1E4 0x5501 # 0 +0xD1E5 0x5F66 # 0 +0xD1E6 0x7130 # 0 +0xD1E7 0x5BB4 # 0 +0xD1E8 0x8C1A # 0 +0xD1E9 0x9A8C # 0 +0xD1EA 0x6B83 # 0 +0xD1EB 0x592E # 0 +0xD1EC 0x9E2F # 0 +0xD1ED 0x79E7 # 0 +0xD1EE 0x6768 # 0 +0xD1EF 0x626C # 0 +0xD1F0 0x4F6F # 0 +0xD1F1 0x75A1 # 0 +0xD1F2 0x7F8A # 0 +0xD1F3 0x6D0B # 0 +0xD1F4 0x9633 # 0 +0xD1F5 0x6C27 # 0 +0xD1F6 0x4EF0 # 0 +0xD1F7 0x75D2 # 0 +0xD1F8 0x517B # 0 +0xD1F9 0x6837 # 0 +0xD1FA 0x6F3E # 0 +0xD1FB 0x9080 # 0 +0xD1FC 0x8170 # 0 +0xD1FD 0x5996 # 0 +0xD1FE 0x7476 # 0 +0xD240 0x8938 # 0 +0xD241 0x8939 # 0 +0xD242 0x893A # 0 +0xD243 0x893B # 0 +0xD244 0x893C # 0 +0xD245 0x893D # 0 +0xD246 0x893E # 0 +0xD247 0x893F # 0 +0xD248 0x8940 # 0 +0xD249 0x8942 # 0 +0xD24A 0x8943 # 0 +0xD24B 0x8945 # 0 +0xD24C 0x8946 # 0 +0xD24D 0x8947 # 0 +0xD24E 0x8948 # 0 +0xD24F 0x8949 # 0 +0xD250 0x894A # 0 +0xD251 0x894B # 0 +0xD252 0x894C # 0 +0xD253 0x894D # 0 +0xD254 0x894E # 0 +0xD255 0x894F # 0 +0xD256 0x8950 # 0 +0xD257 0x8951 # 0 +0xD258 0x8952 # 0 +0xD259 0x8953 # 0 +0xD25A 0x8954 # 0 +0xD25B 0x8955 # 0 +0xD25C 0x8956 # 0 +0xD25D 0x8957 # 0 +0xD25E 0x8958 # 0 +0xD25F 0x8959 # 0 +0xD260 0x895A # 0 +0xD261 0x895B # 0 +0xD262 0x895C # 0 +0xD263 0x895D # 0 +0xD264 0x8960 # 0 +0xD265 0x8961 # 0 +0xD266 0x8962 # 0 +0xD267 0x8963 # 0 +0xD268 0x8964 # 0 +0xD269 0x8965 # 0 +0xD26A 0x8967 # 0 +0xD26B 0x8968 # 0 +0xD26C 0x8969 # 0 +0xD26D 0x896A # 0 +0xD26E 0x896B # 0 +0xD26F 0x896C # 0 +0xD270 0x896D # 0 +0xD271 0x896E # 0 +0xD272 0x896F # 0 +0xD273 0x8970 # 0 +0xD274 0x8971 # 0 +0xD275 0x8972 # 0 +0xD276 0x8973 # 0 +0xD277 0x8974 # 0 +0xD278 0x8975 # 0 +0xD279 0x8976 # 0 +0xD27A 0x8977 # 0 +0xD27B 0x8978 # 0 +0xD27C 0x8979 # 0 +0xD27D 0x897A # 0 +0xD27E 0x897C # 0 +0xD280 0x897D # 0 +0xD281 0x897E # 0 +0xD282 0x8980 # 0 +0xD283 0x8982 # 0 +0xD284 0x8984 # 0 +0xD285 0x8985 # 0 +0xD286 0x8987 # 0 +0xD287 0x8988 # 0 +0xD288 0x8989 # 0 +0xD289 0x898A # 0 +0xD28A 0x898B # 0 +0xD28B 0x898C # 0 +0xD28C 0x898D # 0 +0xD28D 0x898E # 0 +0xD28E 0x898F # 0 +0xD28F 0x8990 # 0 +0xD290 0x8991 # 0 +0xD291 0x8992 # 0 +0xD292 0x8993 # 0 +0xD293 0x8994 # 0 +0xD294 0x8995 # 0 +0xD295 0x8996 # 0 +0xD296 0x8997 # 0 +0xD297 0x8998 # 0 +0xD298 0x8999 # 0 +0xD299 0x899A # 0 +0xD29A 0x899B # 0 +0xD29B 0x899C # 0 +0xD29C 0x899D # 0 +0xD29D 0x899E # 0 +0xD29E 0x899F # 0 +0xD29F 0x89A0 # 0 +0xD2A0 0x89A1 # 0 +0xD2A1 0x6447 # 0 +0xD2A2 0x5C27 # 0 +0xD2A3 0x9065 # 0 +0xD2A4 0x7A91 # 0 +0xD2A5 0x8C23 # 0 +0xD2A6 0x59DA # 0 +0xD2A7 0x54AC # 0 +0xD2A8 0x8200 # 0 +0xD2A9 0x836F # 0 +0xD2AA 0x8981 # 0 +0xD2AB 0x8000 # 0 +0xD2AC 0x6930 # 0 +0xD2AD 0x564E # 0 +0xD2AE 0x8036 # 0 +0xD2AF 0x7237 # 0 +0xD2B0 0x91CE # 0 +0xD2B1 0x51B6 # 0 +0xD2B2 0x4E5F # 0 +0xD2B3 0x9875 # 0 +0xD2B4 0x6396 # 0 +0xD2B5 0x4E1A # 0 +0xD2B6 0x53F6 # 0 +0xD2B7 0x66F3 # 0 +0xD2B8 0x814B # 0 +0xD2B9 0x591C # 0 +0xD2BA 0x6DB2 # 0 +0xD2BB 0x4E00 # 0 +0xD2BC 0x58F9 # 0 +0xD2BD 0x533B # 0 +0xD2BE 0x63D6 # 0 +0xD2BF 0x94F1 # 0 +0xD2C0 0x4F9D # 0 +0xD2C1 0x4F0A # 0 +0xD2C2 0x8863 # 0 +0xD2C3 0x9890 # 0 +0xD2C4 0x5937 # 0 +0xD2C5 0x9057 # 0 +0xD2C6 0x79FB # 0 +0xD2C7 0x4EEA # 0 +0xD2C8 0x80F0 # 0 +0xD2C9 0x7591 # 0 +0xD2CA 0x6C82 # 0 +0xD2CB 0x5B9C # 0 +0xD2CC 0x59E8 # 0 +0xD2CD 0x5F5D # 0 +0xD2CE 0x6905 # 0 +0xD2CF 0x8681 # 0 +0xD2D0 0x501A # 0 +0xD2D1 0x5DF2 # 0 +0xD2D2 0x4E59 # 0 +0xD2D3 0x77E3 # 0 +0xD2D4 0x4EE5 # 0 +0xD2D5 0x827A # 0 +0xD2D6 0x6291 # 0 +0xD2D7 0x6613 # 0 +0xD2D8 0x9091 # 0 +0xD2D9 0x5C79 # 0 +0xD2DA 0x4EBF # 0 +0xD2DB 0x5F79 # 0 +0xD2DC 0x81C6 # 0 +0xD2DD 0x9038 # 0 +0xD2DE 0x8084 # 0 +0xD2DF 0x75AB # 0 +0xD2E0 0x4EA6 # 0 +0xD2E1 0x88D4 # 0 +0xD2E2 0x610F # 0 +0xD2E3 0x6BC5 # 0 +0xD2E4 0x5FC6 # 0 +0xD2E5 0x4E49 # 0 +0xD2E6 0x76CA # 0 +0xD2E7 0x6EA2 # 0 +0xD2E8 0x8BE3 # 0 +0xD2E9 0x8BAE # 0 +0xD2EA 0x8C0A # 0 +0xD2EB 0x8BD1 # 0 +0xD2EC 0x5F02 # 0 +0xD2ED 0x7FFC # 0 +0xD2EE 0x7FCC # 0 +0xD2EF 0x7ECE # 0 +0xD2F0 0x8335 # 0 +0xD2F1 0x836B # 0 +0xD2F2 0x56E0 # 0 +0xD2F3 0x6BB7 # 0 +0xD2F4 0x97F3 # 0 +0xD2F5 0x9634 # 0 +0xD2F6 0x59FB # 0 +0xD2F7 0x541F # 0 +0xD2F8 0x94F6 # 0 +0xD2F9 0x6DEB # 0 +0xD2FA 0x5BC5 # 0 +0xD2FB 0x996E # 0 +0xD2FC 0x5C39 # 0 +0xD2FD 0x5F15 # 0 +0xD2FE 0x9690 # 0 +0xD340 0x89A2 # 0 +0xD341 0x89A3 # 0 +0xD342 0x89A4 # 0 +0xD343 0x89A5 # 0 +0xD344 0x89A6 # 0 +0xD345 0x89A7 # 0 +0xD346 0x89A8 # 0 +0xD347 0x89A9 # 0 +0xD348 0x89AA # 0 +0xD349 0x89AB # 0 +0xD34A 0x89AC # 0 +0xD34B 0x89AD # 0 +0xD34C 0x89AE # 0 +0xD34D 0x89AF # 0 +0xD34E 0x89B0 # 0 +0xD34F 0x89B1 # 0 +0xD350 0x89B2 # 0 +0xD351 0x89B3 # 0 +0xD352 0x89B4 # 0 +0xD353 0x89B5 # 0 +0xD354 0x89B6 # 0 +0xD355 0x89B7 # 0 +0xD356 0x89B8 # 0 +0xD357 0x89B9 # 0 +0xD358 0x89BA # 0 +0xD359 0x89BB # 0 +0xD35A 0x89BC # 0 +0xD35B 0x89BD # 0 +0xD35C 0x89BE # 0 +0xD35D 0x89BF # 0 +0xD35E 0x89C0 # 0 +0xD35F 0x89C3 # 0 +0xD360 0x89CD # 0 +0xD361 0x89D3 # 0 +0xD362 0x89D4 # 0 +0xD363 0x89D5 # 0 +0xD364 0x89D7 # 0 +0xD365 0x89D8 # 0 +0xD366 0x89D9 # 0 +0xD367 0x89DB # 0 +0xD368 0x89DD # 0 +0xD369 0x89DF # 0 +0xD36A 0x89E0 # 0 +0xD36B 0x89E1 # 0 +0xD36C 0x89E2 # 0 +0xD36D 0x89E4 # 0 +0xD36E 0x89E7 # 0 +0xD36F 0x89E8 # 0 +0xD370 0x89E9 # 0 +0xD371 0x89EA # 0 +0xD372 0x89EC # 0 +0xD373 0x89ED # 0 +0xD374 0x89EE # 0 +0xD375 0x89F0 # 0 +0xD376 0x89F1 # 0 +0xD377 0x89F2 # 0 +0xD378 0x89F4 # 0 +0xD379 0x89F5 # 0 +0xD37A 0x89F6 # 0 +0xD37B 0x89F7 # 0 +0xD37C 0x89F8 # 0 +0xD37D 0x89F9 # 0 +0xD37E 0x89FA # 0 +0xD380 0x89FB # 0 +0xD381 0x89FC # 0 +0xD382 0x89FD # 0 +0xD383 0x89FE # 0 +0xD384 0x89FF # 0 +0xD385 0x8A01 # 0 +0xD386 0x8A02 # 0 +0xD387 0x8A03 # 0 +0xD388 0x8A04 # 0 +0xD389 0x8A05 # 0 +0xD38A 0x8A06 # 0 +0xD38B 0x8A08 # 0 +0xD38C 0x8A09 # 0 +0xD38D 0x8A0A # 0 +0xD38E 0x8A0B # 0 +0xD38F 0x8A0C # 0 +0xD390 0x8A0D # 0 +0xD391 0x8A0E # 0 +0xD392 0x8A0F # 0 +0xD393 0x8A10 # 0 +0xD394 0x8A11 # 0 +0xD395 0x8A12 # 0 +0xD396 0x8A13 # 0 +0xD397 0x8A14 # 0 +0xD398 0x8A15 # 0 +0xD399 0x8A16 # 0 +0xD39A 0x8A17 # 0 +0xD39B 0x8A18 # 0 +0xD39C 0x8A19 # 0 +0xD39D 0x8A1A # 0 +0xD39E 0x8A1B # 0 +0xD39F 0x8A1C # 0 +0xD3A0 0x8A1D # 0 +0xD3A1 0x5370 # 0 +0xD3A2 0x82F1 # 0 +0xD3A3 0x6A31 # 0 +0xD3A4 0x5A74 # 0 +0xD3A5 0x9E70 # 0 +0xD3A6 0x5E94 # 0 +0xD3A7 0x7F28 # 0 +0xD3A8 0x83B9 # 0 +0xD3A9 0x8424 # 0 +0xD3AA 0x8425 # 0 +0xD3AB 0x8367 # 0 +0xD3AC 0x8747 # 0 +0xD3AD 0x8FCE # 0 +0xD3AE 0x8D62 # 0 +0xD3AF 0x76C8 # 0 +0xD3B0 0x5F71 # 0 +0xD3B1 0x9896 # 0 +0xD3B2 0x786C # 0 +0xD3B3 0x6620 # 0 +0xD3B4 0x54DF # 0 +0xD3B5 0x62E5 # 0 +0xD3B6 0x4F63 # 0 +0xD3B7 0x81C3 # 0 +0xD3B8 0x75C8 # 0 +0xD3B9 0x5EB8 # 0 +0xD3BA 0x96CD # 0 +0xD3BB 0x8E0A # 0 +0xD3BC 0x86F9 # 0 +0xD3BD 0x548F # 0 +0xD3BE 0x6CF3 # 0 +0xD3BF 0x6D8C # 0 +0xD3C0 0x6C38 # 0 +0xD3C1 0x607F # 0 +0xD3C2 0x52C7 # 0 +0xD3C3 0x7528 # 0 +0xD3C4 0x5E7D # 0 +0xD3C5 0x4F18 # 0 +0xD3C6 0x60A0 # 0 +0xD3C7 0x5FE7 # 0 +0xD3C8 0x5C24 # 0 +0xD3C9 0x7531 # 0 +0xD3CA 0x90AE # 0 +0xD3CB 0x94C0 # 0 +0xD3CC 0x72B9 # 0 +0xD3CD 0x6CB9 # 0 +0xD3CE 0x6E38 # 0 +0xD3CF 0x9149 # 0 +0xD3D0 0x6709 # 0 +0xD3D1 0x53CB # 0 +0xD3D2 0x53F3 # 0 +0xD3D3 0x4F51 # 0 +0xD3D4 0x91C9 # 0 +0xD3D5 0x8BF1 # 0 +0xD3D6 0x53C8 # 0 +0xD3D7 0x5E7C # 0 +0xD3D8 0x8FC2 # 0 +0xD3D9 0x6DE4 # 0 +0xD3DA 0x4E8E # 0 +0xD3DB 0x76C2 # 0 +0xD3DC 0x6986 # 0 +0xD3DD 0x865E # 0 +0xD3DE 0x611A # 0 +0xD3DF 0x8206 # 0 +0xD3E0 0x4F59 # 0 +0xD3E1 0x4FDE # 0 +0xD3E2 0x903E # 0 +0xD3E3 0x9C7C # 0 +0xD3E4 0x6109 # 0 +0xD3E5 0x6E1D # 0 +0xD3E6 0x6E14 # 0 +0xD3E7 0x9685 # 0 +0xD3E8 0x4E88 # 0 +0xD3E9 0x5A31 # 0 +0xD3EA 0x96E8 # 0 +0xD3EB 0x4E0E # 0 +0xD3EC 0x5C7F # 0 +0xD3ED 0x79B9 # 0 +0xD3EE 0x5B87 # 0 +0xD3EF 0x8BED # 0 +0xD3F0 0x7FBD # 0 +0xD3F1 0x7389 # 0 +0xD3F2 0x57DF # 0 +0xD3F3 0x828B # 0 +0xD3F4 0x90C1 # 0 +0xD3F5 0x5401 # 0 +0xD3F6 0x9047 # 0 +0xD3F7 0x55BB # 0 +0xD3F8 0x5CEA # 0 +0xD3F9 0x5FA1 # 0 +0xD3FA 0x6108 # 0 +0xD3FB 0x6B32 # 0 +0xD3FC 0x72F1 # 0 +0xD3FD 0x80B2 # 0 +0xD3FE 0x8A89 # 0 +0xD440 0x8A1E # 0 +0xD441 0x8A1F # 0 +0xD442 0x8A20 # 0 +0xD443 0x8A21 # 0 +0xD444 0x8A22 # 0 +0xD445 0x8A23 # 0 +0xD446 0x8A24 # 0 +0xD447 0x8A25 # 0 +0xD448 0x8A26 # 0 +0xD449 0x8A27 # 0 +0xD44A 0x8A28 # 0 +0xD44B 0x8A29 # 0 +0xD44C 0x8A2A # 0 +0xD44D 0x8A2B # 0 +0xD44E 0x8A2C # 0 +0xD44F 0x8A2D # 0 +0xD450 0x8A2E # 0 +0xD451 0x8A2F # 0 +0xD452 0x8A30 # 0 +0xD453 0x8A31 # 0 +0xD454 0x8A32 # 0 +0xD455 0x8A33 # 0 +0xD456 0x8A34 # 0 +0xD457 0x8A35 # 0 +0xD458 0x8A36 # 0 +0xD459 0x8A37 # 0 +0xD45A 0x8A38 # 0 +0xD45B 0x8A39 # 0 +0xD45C 0x8A3A # 0 +0xD45D 0x8A3B # 0 +0xD45E 0x8A3C # 0 +0xD45F 0x8A3D # 0 +0xD460 0x8A3F # 0 +0xD461 0x8A40 # 0 +0xD462 0x8A41 # 0 +0xD463 0x8A42 # 0 +0xD464 0x8A43 # 0 +0xD465 0x8A44 # 0 +0xD466 0x8A45 # 0 +0xD467 0x8A46 # 0 +0xD468 0x8A47 # 0 +0xD469 0x8A49 # 0 +0xD46A 0x8A4A # 0 +0xD46B 0x8A4B # 0 +0xD46C 0x8A4C # 0 +0xD46D 0x8A4D # 0 +0xD46E 0x8A4E # 0 +0xD46F 0x8A4F # 0 +0xD470 0x8A50 # 0 +0xD471 0x8A51 # 0 +0xD472 0x8A52 # 0 +0xD473 0x8A53 # 0 +0xD474 0x8A54 # 0 +0xD475 0x8A55 # 0 +0xD476 0x8A56 # 0 +0xD477 0x8A57 # 0 +0xD478 0x8A58 # 0 +0xD479 0x8A59 # 0 +0xD47A 0x8A5A # 0 +0xD47B 0x8A5B # 0 +0xD47C 0x8A5C # 0 +0xD47D 0x8A5D # 0 +0xD47E 0x8A5E # 0 +0xD480 0x8A5F # 0 +0xD481 0x8A60 # 0 +0xD482 0x8A61 # 0 +0xD483 0x8A62 # 0 +0xD484 0x8A63 # 0 +0xD485 0x8A64 # 0 +0xD486 0x8A65 # 0 +0xD487 0x8A66 # 0 +0xD488 0x8A67 # 0 +0xD489 0x8A68 # 0 +0xD48A 0x8A69 # 0 +0xD48B 0x8A6A # 0 +0xD48C 0x8A6B # 0 +0xD48D 0x8A6C # 0 +0xD48E 0x8A6D # 0 +0xD48F 0x8A6E # 0 +0xD490 0x8A6F # 0 +0xD491 0x8A70 # 0 +0xD492 0x8A71 # 0 +0xD493 0x8A72 # 0 +0xD494 0x8A73 # 0 +0xD495 0x8A74 # 0 +0xD496 0x8A75 # 0 +0xD497 0x8A76 # 0 +0xD498 0x8A77 # 0 +0xD499 0x8A78 # 0 +0xD49A 0x8A7A # 0 +0xD49B 0x8A7B # 0 +0xD49C 0x8A7C # 0 +0xD49D 0x8A7D # 0 +0xD49E 0x8A7E # 0 +0xD49F 0x8A7F # 0 +0xD4A0 0x8A80 # 0 +0xD4A1 0x6D74 # 0 +0xD4A2 0x5BD3 # 0 +0xD4A3 0x88D5 # 0 +0xD4A4 0x9884 # 0 +0xD4A5 0x8C6B # 0 +0xD4A6 0x9A6D # 0 +0xD4A7 0x9E33 # 0 +0xD4A8 0x6E0A # 0 +0xD4A9 0x51A4 # 0 +0xD4AA 0x5143 # 0 +0xD4AB 0x57A3 # 0 +0xD4AC 0x8881 # 0 +0xD4AD 0x539F # 0 +0xD4AE 0x63F4 # 0 +0xD4AF 0x8F95 # 0 +0xD4B0 0x56ED # 0 +0xD4B1 0x5458 # 0 +0xD4B2 0x5706 # 0 +0xD4B3 0x733F # 0 +0xD4B4 0x6E90 # 0 +0xD4B5 0x7F18 # 0 +0xD4B6 0x8FDC # 0 +0xD4B7 0x82D1 # 0 +0xD4B8 0x613F # 0 +0xD4B9 0x6028 # 0 +0xD4BA 0x9662 # 0 +0xD4BB 0x66F0 # 0 +0xD4BC 0x7EA6 # 0 +0xD4BD 0x8D8A # 0 +0xD4BE 0x8DC3 # 0 +0xD4BF 0x94A5 # 0 +0xD4C0 0x5CB3 # 0 +0xD4C1 0x7CA4 # 0 +0xD4C2 0x6708 # 0 +0xD4C3 0x60A6 # 0 +0xD4C4 0x9605 # 0 +0xD4C5 0x8018 # 0 +0xD4C6 0x4E91 # 0 +0xD4C7 0x90E7 # 0 +0xD4C8 0x5300 # 0 +0xD4C9 0x9668 # 0 +0xD4CA 0x5141 # 0 +0xD4CB 0x8FD0 # 0 +0xD4CC 0x8574 # 0 +0xD4CD 0x915D # 0 +0xD4CE 0x6655 # 0 +0xD4CF 0x97F5 # 0 +0xD4D0 0x5B55 # 0 +0xD4D1 0x531D # 0 +0xD4D2 0x7838 # 0 +0xD4D3 0x6742 # 0 +0xD4D4 0x683D # 0 +0xD4D5 0x54C9 # 0 +0xD4D6 0x707E # 0 +0xD4D7 0x5BB0 # 0 +0xD4D8 0x8F7D # 0 +0xD4D9 0x518D # 0 +0xD4DA 0x5728 # 0 +0xD4DB 0x54B1 # 0 +0xD4DC 0x6512 # 0 +0xD4DD 0x6682 # 0 +0xD4DE 0x8D5E # 0 +0xD4DF 0x8D43 # 0 +0xD4E0 0x810F # 0 +0xD4E1 0x846C # 0 +0xD4E2 0x906D # 0 +0xD4E3 0x7CDF # 0 +0xD4E4 0x51FF # 0 +0xD4E5 0x85FB # 0 +0xD4E6 0x67A3 # 0 +0xD4E7 0x65E9 # 0 +0xD4E8 0x6FA1 # 0 +0xD4E9 0x86A4 # 0 +0xD4EA 0x8E81 # 0 +0xD4EB 0x566A # 0 +0xD4EC 0x9020 # 0 +0xD4ED 0x7682 # 0 +0xD4EE 0x7076 # 0 +0xD4EF 0x71E5 # 0 +0xD4F0 0x8D23 # 0 +0xD4F1 0x62E9 # 0 +0xD4F2 0x5219 # 0 +0xD4F3 0x6CFD # 0 +0xD4F4 0x8D3C # 0 +0xD4F5 0x600E # 0 +0xD4F6 0x589E # 0 +0xD4F7 0x618E # 0 +0xD4F8 0x66FE # 0 +0xD4F9 0x8D60 # 0 +0xD4FA 0x624E # 0 +0xD4FB 0x55B3 # 0 +0xD4FC 0x6E23 # 0 +0xD4FD 0x672D # 0 +0xD4FE 0x8F67 # 0 +0xD540 0x8A81 # 0 +0xD541 0x8A82 # 0 +0xD542 0x8A83 # 0 +0xD543 0x8A84 # 0 +0xD544 0x8A85 # 0 +0xD545 0x8A86 # 0 +0xD546 0x8A87 # 0 +0xD547 0x8A88 # 0 +0xD548 0x8A8B # 0 +0xD549 0x8A8C # 0 +0xD54A 0x8A8D # 0 +0xD54B 0x8A8E # 0 +0xD54C 0x8A8F # 0 +0xD54D 0x8A90 # 0 +0xD54E 0x8A91 # 0 +0xD54F 0x8A92 # 0 +0xD550 0x8A94 # 0 +0xD551 0x8A95 # 0 +0xD552 0x8A96 # 0 +0xD553 0x8A97 # 0 +0xD554 0x8A98 # 0 +0xD555 0x8A99 # 0 +0xD556 0x8A9A # 0 +0xD557 0x8A9B # 0 +0xD558 0x8A9C # 0 +0xD559 0x8A9D # 0 +0xD55A 0x8A9E # 0 +0xD55B 0x8A9F # 0 +0xD55C 0x8AA0 # 0 +0xD55D 0x8AA1 # 0 +0xD55E 0x8AA2 # 0 +0xD55F 0x8AA3 # 0 +0xD560 0x8AA4 # 0 +0xD561 0x8AA5 # 0 +0xD562 0x8AA6 # 0 +0xD563 0x8AA7 # 0 +0xD564 0x8AA8 # 0 +0xD565 0x8AA9 # 0 +0xD566 0x8AAA # 0 +0xD567 0x8AAB # 0 +0xD568 0x8AAC # 0 +0xD569 0x8AAD # 0 +0xD56A 0x8AAE # 0 +0xD56B 0x8AAF # 0 +0xD56C 0x8AB0 # 0 +0xD56D 0x8AB1 # 0 +0xD56E 0x8AB2 # 0 +0xD56F 0x8AB3 # 0 +0xD570 0x8AB4 # 0 +0xD571 0x8AB5 # 0 +0xD572 0x8AB6 # 0 +0xD573 0x8AB7 # 0 +0xD574 0x8AB8 # 0 +0xD575 0x8AB9 # 0 +0xD576 0x8ABA # 0 +0xD577 0x8ABB # 0 +0xD578 0x8ABC # 0 +0xD579 0x8ABD # 0 +0xD57A 0x8ABE # 0 +0xD57B 0x8ABF # 0 +0xD57C 0x8AC0 # 0 +0xD57D 0x8AC1 # 0 +0xD57E 0x8AC2 # 0 +0xD580 0x8AC3 # 0 +0xD581 0x8AC4 # 0 +0xD582 0x8AC5 # 0 +0xD583 0x8AC6 # 0 +0xD584 0x8AC7 # 0 +0xD585 0x8AC8 # 0 +0xD586 0x8AC9 # 0 +0xD587 0x8ACA # 0 +0xD588 0x8ACB # 0 +0xD589 0x8ACC # 0 +0xD58A 0x8ACD # 0 +0xD58B 0x8ACE # 0 +0xD58C 0x8ACF # 0 +0xD58D 0x8AD0 # 0 +0xD58E 0x8AD1 # 0 +0xD58F 0x8AD2 # 0 +0xD590 0x8AD3 # 0 +0xD591 0x8AD4 # 0 +0xD592 0x8AD5 # 0 +0xD593 0x8AD6 # 0 +0xD594 0x8AD7 # 0 +0xD595 0x8AD8 # 0 +0xD596 0x8AD9 # 0 +0xD597 0x8ADA # 0 +0xD598 0x8ADB # 0 +0xD599 0x8ADC # 0 +0xD59A 0x8ADD # 0 +0xD59B 0x8ADE # 0 +0xD59C 0x8ADF # 0 +0xD59D 0x8AE0 # 0 +0xD59E 0x8AE1 # 0 +0xD59F 0x8AE2 # 0 +0xD5A0 0x8AE3 # 0 +0xD5A1 0x94E1 # 0 +0xD5A2 0x95F8 # 0 +0xD5A3 0x7728 # 0 +0xD5A4 0x6805 # 0 +0xD5A5 0x69A8 # 0 +0xD5A6 0x548B # 0 +0xD5A7 0x4E4D # 0 +0xD5A8 0x70B8 # 0 +0xD5A9 0x8BC8 # 0 +0xD5AA 0x6458 # 0 +0xD5AB 0x658B # 0 +0xD5AC 0x5B85 # 0 +0xD5AD 0x7A84 # 0 +0xD5AE 0x503A # 0 +0xD5AF 0x5BE8 # 0 +0xD5B0 0x77BB # 0 +0xD5B1 0x6BE1 # 0 +0xD5B2 0x8A79 # 0 +0xD5B3 0x7C98 # 0 +0xD5B4 0x6CBE # 0 +0xD5B5 0x76CF # 0 +0xD5B6 0x65A9 # 0 +0xD5B7 0x8F97 # 0 +0xD5B8 0x5D2D # 0 +0xD5B9 0x5C55 # 0 +0xD5BA 0x8638 # 0 +0xD5BB 0x6808 # 0 +0xD5BC 0x5360 # 0 +0xD5BD 0x6218 # 0 +0xD5BE 0x7AD9 # 0 +0xD5BF 0x6E5B # 0 +0xD5C0 0x7EFD # 0 +0xD5C1 0x6A1F # 0 +0xD5C2 0x7AE0 # 0 +0xD5C3 0x5F70 # 0 +0xD5C4 0x6F33 # 0 +0xD5C5 0x5F20 # 0 +0xD5C6 0x638C # 0 +0xD5C7 0x6DA8 # 0 +0xD5C8 0x6756 # 0 +0xD5C9 0x4E08 # 0 +0xD5CA 0x5E10 # 0 +0xD5CB 0x8D26 # 0 +0xD5CC 0x4ED7 # 0 +0xD5CD 0x80C0 # 0 +0xD5CE 0x7634 # 0 +0xD5CF 0x969C # 0 +0xD5D0 0x62DB # 0 +0xD5D1 0x662D # 0 +0xD5D2 0x627E # 0 +0xD5D3 0x6CBC # 0 +0xD5D4 0x8D75 # 0 +0xD5D5 0x7167 # 0 +0xD5D6 0x7F69 # 0 +0xD5D7 0x5146 # 0 +0xD5D8 0x8087 # 0 +0xD5D9 0x53EC # 0 +0xD5DA 0x906E # 0 +0xD5DB 0x6298 # 0 +0xD5DC 0x54F2 # 0 +0xD5DD 0x86F0 # 0 +0xD5DE 0x8F99 # 0 +0xD5DF 0x8005 # 0 +0xD5E0 0x9517 # 0 +0xD5E1 0x8517 # 0 +0xD5E2 0x8FD9 # 0 +0xD5E3 0x6D59 # 0 +0xD5E4 0x73CD # 0 +0xD5E5 0x659F # 0 +0xD5E6 0x771F # 0 +0xD5E7 0x7504 # 0 +0xD5E8 0x7827 # 0 +0xD5E9 0x81FB # 0 +0xD5EA 0x8D1E # 0 +0xD5EB 0x9488 # 0 +0xD5EC 0x4FA6 # 0 +0xD5ED 0x6795 # 0 +0xD5EE 0x75B9 # 0 +0xD5EF 0x8BCA # 0 +0xD5F0 0x9707 # 0 +0xD5F1 0x632F # 0 +0xD5F2 0x9547 # 0 +0xD5F3 0x9635 # 0 +0xD5F4 0x84B8 # 0 +0xD5F5 0x6323 # 0 +0xD5F6 0x7741 # 0 +0xD5F7 0x5F81 # 0 +0xD5F8 0x72F0 # 0 +0xD5F9 0x4E89 # 0 +0xD5FA 0x6014 # 0 +0xD5FB 0x6574 # 0 +0xD5FC 0x62EF # 0 +0xD5FD 0x6B63 # 0 +0xD5FE 0x653F # 0 +0xD640 0x8AE4 # 0 +0xD641 0x8AE5 # 0 +0xD642 0x8AE6 # 0 +0xD643 0x8AE7 # 0 +0xD644 0x8AE8 # 0 +0xD645 0x8AE9 # 0 +0xD646 0x8AEA # 0 +0xD647 0x8AEB # 0 +0xD648 0x8AEC # 0 +0xD649 0x8AED # 0 +0xD64A 0x8AEE # 0 +0xD64B 0x8AEF # 0 +0xD64C 0x8AF0 # 0 +0xD64D 0x8AF1 # 0 +0xD64E 0x8AF2 # 0 +0xD64F 0x8AF3 # 0 +0xD650 0x8AF4 # 0 +0xD651 0x8AF5 # 0 +0xD652 0x8AF6 # 0 +0xD653 0x8AF7 # 0 +0xD654 0x8AF8 # 0 +0xD655 0x8AF9 # 0 +0xD656 0x8AFA # 0 +0xD657 0x8AFB # 0 +0xD658 0x8AFC # 0 +0xD659 0x8AFD # 0 +0xD65A 0x8AFE # 0 +0xD65B 0x8AFF # 0 +0xD65C 0x8B00 # 0 +0xD65D 0x8B01 # 0 +0xD65E 0x8B02 # 0 +0xD65F 0x8B03 # 0 +0xD660 0x8B04 # 0 +0xD661 0x8B05 # 0 +0xD662 0x8B06 # 0 +0xD663 0x8B08 # 0 +0xD664 0x8B09 # 0 +0xD665 0x8B0A # 0 +0xD666 0x8B0B # 0 +0xD667 0x8B0C # 0 +0xD668 0x8B0D # 0 +0xD669 0x8B0E # 0 +0xD66A 0x8B0F # 0 +0xD66B 0x8B10 # 0 +0xD66C 0x8B11 # 0 +0xD66D 0x8B12 # 0 +0xD66E 0x8B13 # 0 +0xD66F 0x8B14 # 0 +0xD670 0x8B15 # 0 +0xD671 0x8B16 # 0 +0xD672 0x8B17 # 0 +0xD673 0x8B18 # 0 +0xD674 0x8B19 # 0 +0xD675 0x8B1A # 0 +0xD676 0x8B1B # 0 +0xD677 0x8B1C # 0 +0xD678 0x8B1D # 0 +0xD679 0x8B1E # 0 +0xD67A 0x8B1F # 0 +0xD67B 0x8B20 # 0 +0xD67C 0x8B21 # 0 +0xD67D 0x8B22 # 0 +0xD67E 0x8B23 # 0 +0xD680 0x8B24 # 0 +0xD681 0x8B25 # 0 +0xD682 0x8B27 # 0 +0xD683 0x8B28 # 0 +0xD684 0x8B29 # 0 +0xD685 0x8B2A # 0 +0xD686 0x8B2B # 0 +0xD687 0x8B2C # 0 +0xD688 0x8B2D # 0 +0xD689 0x8B2E # 0 +0xD68A 0x8B2F # 0 +0xD68B 0x8B30 # 0 +0xD68C 0x8B31 # 0 +0xD68D 0x8B32 # 0 +0xD68E 0x8B33 # 0 +0xD68F 0x8B34 # 0 +0xD690 0x8B35 # 0 +0xD691 0x8B36 # 0 +0xD692 0x8B37 # 0 +0xD693 0x8B38 # 0 +0xD694 0x8B39 # 0 +0xD695 0x8B3A # 0 +0xD696 0x8B3B # 0 +0xD697 0x8B3C # 0 +0xD698 0x8B3D # 0 +0xD699 0x8B3E # 0 +0xD69A 0x8B3F # 0 +0xD69B 0x8B40 # 0 +0xD69C 0x8B41 # 0 +0xD69D 0x8B42 # 0 +0xD69E 0x8B43 # 0 +0xD69F 0x8B44 # 0 +0xD6A0 0x8B45 # 0 +0xD6A1 0x5E27 # 0 +0xD6A2 0x75C7 # 0 +0xD6A3 0x90D1 # 0 +0xD6A4 0x8BC1 # 0 +0xD6A5 0x829D # 0 +0xD6A6 0x679D # 0 +0xD6A7 0x652F # 0 +0xD6A8 0x5431 # 0 +0xD6A9 0x8718 # 0 +0xD6AA 0x77E5 # 0 +0xD6AB 0x80A2 # 0 +0xD6AC 0x8102 # 0 +0xD6AD 0x6C41 # 0 +0xD6AE 0x4E4B # 0 +0xD6AF 0x7EC7 # 0 +0xD6B0 0x804C # 0 +0xD6B1 0x76F4 # 0 +0xD6B2 0x690D # 0 +0xD6B3 0x6B96 # 0 +0xD6B4 0x6267 # 0 +0xD6B5 0x503C # 0 +0xD6B6 0x4F84 # 0 +0xD6B7 0x5740 # 0 +0xD6B8 0x6307 # 0 +0xD6B9 0x6B62 # 0 +0xD6BA 0x8DBE # 0 +0xD6BB 0x53EA # 0 +0xD6BC 0x65E8 # 0 +0xD6BD 0x7EB8 # 0 +0xD6BE 0x5FD7 # 0 +0xD6BF 0x631A # 0 +0xD6C0 0x63B7 # 0 +0xD6C1 0x81F3 # 0 +0xD6C2 0x81F4 # 0 +0xD6C3 0x7F6E # 0 +0xD6C4 0x5E1C # 0 +0xD6C5 0x5CD9 # 0 +0xD6C6 0x5236 # 0 +0xD6C7 0x667A # 0 +0xD6C8 0x79E9 # 0 +0xD6C9 0x7A1A # 0 +0xD6CA 0x8D28 # 0 +0xD6CB 0x7099 # 0 +0xD6CC 0x75D4 # 0 +0xD6CD 0x6EDE # 0 +0xD6CE 0x6CBB # 0 +0xD6CF 0x7A92 # 0 +0xD6D0 0x4E2D # 0 +0xD6D1 0x76C5 # 0 +0xD6D2 0x5FE0 # 0 +0xD6D3 0x949F # 0 +0xD6D4 0x8877 # 0 +0xD6D5 0x7EC8 # 0 +0xD6D6 0x79CD # 0 +0xD6D7 0x80BF # 0 +0xD6D8 0x91CD # 0 +0xD6D9 0x4EF2 # 0 +0xD6DA 0x4F17 # 0 +0xD6DB 0x821F # 0 +0xD6DC 0x5468 # 0 +0xD6DD 0x5DDE # 0 +0xD6DE 0x6D32 # 0 +0xD6DF 0x8BCC # 0 +0xD6E0 0x7CA5 # 0 +0xD6E1 0x8F74 # 0 +0xD6E2 0x8098 # 0 +0xD6E3 0x5E1A # 0 +0xD6E4 0x5492 # 0 +0xD6E5 0x76B1 # 0 +0xD6E6 0x5B99 # 0 +0xD6E7 0x663C # 0 +0xD6E8 0x9AA4 # 0 +0xD6E9 0x73E0 # 0 +0xD6EA 0x682A # 0 +0xD6EB 0x86DB # 0 +0xD6EC 0x6731 # 0 +0xD6ED 0x732A # 0 +0xD6EE 0x8BF8 # 0 +0xD6EF 0x8BDB # 0 +0xD6F0 0x9010 # 0 +0xD6F1 0x7AF9 # 0 +0xD6F2 0x70DB # 0 +0xD6F3 0x716E # 0 +0xD6F4 0x62C4 # 0 +0xD6F5 0x77A9 # 0 +0xD6F6 0x5631 # 0 +0xD6F7 0x4E3B # 0 +0xD6F8 0x8457 # 0 +0xD6F9 0x67F1 # 0 +0xD6FA 0x52A9 # 0 +0xD6FB 0x86C0 # 0 +0xD6FC 0x8D2E # 0 +0xD6FD 0x94F8 # 0 +0xD6FE 0x7B51 # 0 +0xD740 0x8B46 # 0 +0xD741 0x8B47 # 0 +0xD742 0x8B48 # 0 +0xD743 0x8B49 # 0 +0xD744 0x8B4A # 0 +0xD745 0x8B4B # 0 +0xD746 0x8B4C # 0 +0xD747 0x8B4D # 0 +0xD748 0x8B4E # 0 +0xD749 0x8B4F # 0 +0xD74A 0x8B50 # 0 +0xD74B 0x8B51 # 0 +0xD74C 0x8B52 # 0 +0xD74D 0x8B53 # 0 +0xD74E 0x8B54 # 0 +0xD74F 0x8B55 # 0 +0xD750 0x8B56 # 0 +0xD751 0x8B57 # 0 +0xD752 0x8B58 # 0 +0xD753 0x8B59 # 0 +0xD754 0x8B5A # 0 +0xD755 0x8B5B # 0 +0xD756 0x8B5C # 0 +0xD757 0x8B5D # 0 +0xD758 0x8B5E # 0 +0xD759 0x8B5F # 0 +0xD75A 0x8B60 # 0 +0xD75B 0x8B61 # 0 +0xD75C 0x8B62 # 0 +0xD75D 0x8B63 # 0 +0xD75E 0x8B64 # 0 +0xD75F 0x8B65 # 0 +0xD760 0x8B67 # 0 +0xD761 0x8B68 # 0 +0xD762 0x8B69 # 0 +0xD763 0x8B6A # 0 +0xD764 0x8B6B # 0 +0xD765 0x8B6D # 0 +0xD766 0x8B6E # 0 +0xD767 0x8B6F # 0 +0xD768 0x8B70 # 0 +0xD769 0x8B71 # 0 +0xD76A 0x8B72 # 0 +0xD76B 0x8B73 # 0 +0xD76C 0x8B74 # 0 +0xD76D 0x8B75 # 0 +0xD76E 0x8B76 # 0 +0xD76F 0x8B77 # 0 +0xD770 0x8B78 # 0 +0xD771 0x8B79 # 0 +0xD772 0x8B7A # 0 +0xD773 0x8B7B # 0 +0xD774 0x8B7C # 0 +0xD775 0x8B7D # 0 +0xD776 0x8B7E # 0 +0xD777 0x8B7F # 0 +0xD778 0x8B80 # 0 +0xD779 0x8B81 # 0 +0xD77A 0x8B82 # 0 +0xD77B 0x8B83 # 0 +0xD77C 0x8B84 # 0 +0xD77D 0x8B85 # 0 +0xD77E 0x8B86 # 0 +0xD780 0x8B87 # 0 +0xD781 0x8B88 # 0 +0xD782 0x8B89 # 0 +0xD783 0x8B8A # 0 +0xD784 0x8B8B # 0 +0xD785 0x8B8C # 0 +0xD786 0x8B8D # 0 +0xD787 0x8B8E # 0 +0xD788 0x8B8F # 0 +0xD789 0x8B90 # 0 +0xD78A 0x8B91 # 0 +0xD78B 0x8B92 # 0 +0xD78C 0x8B93 # 0 +0xD78D 0x8B94 # 0 +0xD78E 0x8B95 # 0 +0xD78F 0x8B96 # 0 +0xD790 0x8B97 # 0 +0xD791 0x8B98 # 0 +0xD792 0x8B99 # 0 +0xD793 0x8B9A # 0 +0xD794 0x8B9B # 0 +0xD795 0x8B9C # 0 +0xD796 0x8B9D # 0 +0xD797 0x8B9E # 0 +0xD798 0x8B9F # 0 +0xD799 0x8BAC # 0 +0xD79A 0x8BB1 # 0 +0xD79B 0x8BBB # 0 +0xD79C 0x8BC7 # 0 +0xD79D 0x8BD0 # 0 +0xD79E 0x8BEA # 0 +0xD79F 0x8C09 # 0 +0xD7A0 0x8C1E # 0 +0xD7A1 0x4F4F # 0 +0xD7A2 0x6CE8 # 0 +0xD7A3 0x795D # 0 +0xD7A4 0x9A7B # 0 +0xD7A5 0x6293 # 0 +0xD7A6 0x722A # 0 +0xD7A7 0x62FD # 0 +0xD7A8 0x4E13 # 0 +0xD7A9 0x7816 # 0 +0xD7AA 0x8F6C # 0 +0xD7AB 0x64B0 # 0 +0xD7AC 0x8D5A # 0 +0xD7AD 0x7BC6 # 0 +0xD7AE 0x6869 # 0 +0xD7AF 0x5E84 # 0 +0xD7B0 0x88C5 # 0 +0xD7B1 0x5986 # 0 +0xD7B2 0x649E # 0 +0xD7B3 0x58EE # 0 +0xD7B4 0x72B6 # 0 +0xD7B5 0x690E # 0 +0xD7B6 0x9525 # 0 +0xD7B7 0x8FFD # 0 +0xD7B8 0x8D58 # 0 +0xD7B9 0x5760 # 0 +0xD7BA 0x7F00 # 0 +0xD7BB 0x8C06 # 0 +0xD7BC 0x51C6 # 0 +0xD7BD 0x6349 # 0 +0xD7BE 0x62D9 # 0 +0xD7BF 0x5353 # 0 +0xD7C0 0x684C # 0 +0xD7C1 0x7422 # 0 +0xD7C2 0x8301 # 0 +0xD7C3 0x914C # 0 +0xD7C4 0x5544 # 0 +0xD7C5 0x7740 # 0 +0xD7C6 0x707C # 0 +0xD7C7 0x6D4A # 0 +0xD7C8 0x5179 # 0 +0xD7C9 0x54A8 # 0 +0xD7CA 0x8D44 # 0 +0xD7CB 0x59FF # 0 +0xD7CC 0x6ECB # 0 +0xD7CD 0x6DC4 # 0 +0xD7CE 0x5B5C # 0 +0xD7CF 0x7D2B # 0 +0xD7D0 0x4ED4 # 0 +0xD7D1 0x7C7D # 0 +0xD7D2 0x6ED3 # 0 +0xD7D3 0x5B50 # 0 +0xD7D4 0x81EA # 0 +0xD7D5 0x6E0D # 0 +0xD7D6 0x5B57 # 0 +0xD7D7 0x9B03 # 0 +0xD7D8 0x68D5 # 0 +0xD7D9 0x8E2A # 0 +0xD7DA 0x5B97 # 0 +0xD7DB 0x7EFC # 0 +0xD7DC 0x603B # 0 +0xD7DD 0x7EB5 # 0 +0xD7DE 0x90B9 # 0 +0xD7DF 0x8D70 # 0 +0xD7E0 0x594F # 0 +0xD7E1 0x63CD # 0 +0xD7E2 0x79DF # 0 +0xD7E3 0x8DB3 # 0 +0xD7E4 0x5352 # 0 +0xD7E5 0x65CF # 0 +0xD7E6 0x7956 # 0 +0xD7E7 0x8BC5 # 0 +0xD7E8 0x963B # 0 +0xD7E9 0x7EC4 # 0 +0xD7EA 0x94BB # 0 +0xD7EB 0x7E82 # 0 +0xD7EC 0x5634 # 0 +0xD7ED 0x9189 # 0 +0xD7EE 0x6700 # 0 +0xD7EF 0x7F6A # 0 +0xD7F0 0x5C0A # 0 +0xD7F1 0x9075 # 0 +0xD7F2 0x6628 # 0 +0xD7F3 0x5DE6 # 0 +0xD7F4 0x4F50 # 0 +0xD7F5 0x67DE # 0 +0xD7F6 0x505A # 0 +0xD7F7 0x4F5C # 0 +0xD7F8 0x5750 # 0 +0xD7F9 0x5EA7 # 0 +0xD7FA 0xE810 # 0 +0xD7FB 0xE811 # 0 +0xD7FC 0xE812 # 0 +0xD7FD 0xE813 # 0 +0xD7FE 0xE814 # 0 +0xD840 0x8C38 # 0 +0xD841 0x8C39 # 0 +0xD842 0x8C3A # 0 +0xD843 0x8C3B # 0 +0xD844 0x8C3C # 0 +0xD845 0x8C3D # 0 +0xD846 0x8C3E # 0 +0xD847 0x8C3F # 0 +0xD848 0x8C40 # 0 +0xD849 0x8C42 # 0 +0xD84A 0x8C43 # 0 +0xD84B 0x8C44 # 0 +0xD84C 0x8C45 # 0 +0xD84D 0x8C48 # 0 +0xD84E 0x8C4A # 0 +0xD84F 0x8C4B # 0 +0xD850 0x8C4D # 0 +0xD851 0x8C4E # 0 +0xD852 0x8C4F # 0 +0xD853 0x8C50 # 0 +0xD854 0x8C51 # 0 +0xD855 0x8C52 # 0 +0xD856 0x8C53 # 0 +0xD857 0x8C54 # 0 +0xD858 0x8C56 # 0 +0xD859 0x8C57 # 0 +0xD85A 0x8C58 # 0 +0xD85B 0x8C59 # 0 +0xD85C 0x8C5B # 0 +0xD85D 0x8C5C # 0 +0xD85E 0x8C5D # 0 +0xD85F 0x8C5E # 0 +0xD860 0x8C5F # 0 +0xD861 0x8C60 # 0 +0xD862 0x8C63 # 0 +0xD863 0x8C64 # 0 +0xD864 0x8C65 # 0 +0xD865 0x8C66 # 0 +0xD866 0x8C67 # 0 +0xD867 0x8C68 # 0 +0xD868 0x8C69 # 0 +0xD869 0x8C6C # 0 +0xD86A 0x8C6D # 0 +0xD86B 0x8C6E # 0 +0xD86C 0x8C6F # 0 +0xD86D 0x8C70 # 0 +0xD86E 0x8C71 # 0 +0xD86F 0x8C72 # 0 +0xD870 0x8C74 # 0 +0xD871 0x8C75 # 0 +0xD872 0x8C76 # 0 +0xD873 0x8C77 # 0 +0xD874 0x8C7B # 0 +0xD875 0x8C7C # 0 +0xD876 0x8C7D # 0 +0xD877 0x8C7E # 0 +0xD878 0x8C7F # 0 +0xD879 0x8C80 # 0 +0xD87A 0x8C81 # 0 +0xD87B 0x8C83 # 0 +0xD87C 0x8C84 # 0 +0xD87D 0x8C86 # 0 +0xD87E 0x8C87 # 0 +0xD880 0x8C88 # 0 +0xD881 0x8C8B # 0 +0xD882 0x8C8D # 0 +0xD883 0x8C8E # 0 +0xD884 0x8C8F # 0 +0xD885 0x8C90 # 0 +0xD886 0x8C91 # 0 +0xD887 0x8C92 # 0 +0xD888 0x8C93 # 0 +0xD889 0x8C95 # 0 +0xD88A 0x8C96 # 0 +0xD88B 0x8C97 # 0 +0xD88C 0x8C99 # 0 +0xD88D 0x8C9A # 0 +0xD88E 0x8C9B # 0 +0xD88F 0x8C9C # 0 +0xD890 0x8C9D # 0 +0xD891 0x8C9E # 0 +0xD892 0x8C9F # 0 +0xD893 0x8CA0 # 0 +0xD894 0x8CA1 # 0 +0xD895 0x8CA2 # 0 +0xD896 0x8CA3 # 0 +0xD897 0x8CA4 # 0 +0xD898 0x8CA5 # 0 +0xD899 0x8CA6 # 0 +0xD89A 0x8CA7 # 0 +0xD89B 0x8CA8 # 0 +0xD89C 0x8CA9 # 0 +0xD89D 0x8CAA # 0 +0xD89E 0x8CAB # 0 +0xD89F 0x8CAC # 0 +0xD8A0 0x8CAD # 0 +0xD8A1 0x4E8D # 0 +0xD8A2 0x4E0C # 0 +0xD8A3 0x5140 # 0 +0xD8A4 0x4E10 # 0 +0xD8A5 0x5EFF # 0 +0xD8A6 0x5345 # 0 +0xD8A7 0x4E15 # 0 +0xD8A8 0x4E98 # 0 +0xD8A9 0x4E1E # 0 +0xD8AA 0x9B32 # 0 +0xD8AB 0x5B6C # 0 +0xD8AC 0x5669 # 0 +0xD8AD 0x4E28 # 0 +0xD8AE 0x79BA # 0 +0xD8AF 0x4E3F # 0 +0xD8B0 0x5315 # 0 +0xD8B1 0x4E47 # 0 +0xD8B2 0x592D # 0 +0xD8B3 0x723B # 0 +0xD8B4 0x536E # 0 +0xD8B5 0x6C10 # 0 +0xD8B6 0x56DF # 0 +0xD8B7 0x80E4 # 0 +0xD8B8 0x9997 # 0 +0xD8B9 0x6BD3 # 0 +0xD8BA 0x777E # 0 +0xD8BB 0x9F17 # 0 +0xD8BC 0x4E36 # 0 +0xD8BD 0x4E9F # 0 +0xD8BE 0x9F10 # 0 +0xD8BF 0x4E5C # 0 +0xD8C0 0x4E69 # 0 +0xD8C1 0x4E93 # 0 +0xD8C2 0x8288 # 0 +0xD8C3 0x5B5B # 0 +0xD8C4 0x556C # 0 +0xD8C5 0x560F # 0 +0xD8C6 0x4EC4 # 0 +0xD8C7 0x538D # 0 +0xD8C8 0x539D # 0 +0xD8C9 0x53A3 # 0 +0xD8CA 0x53A5 # 0 +0xD8CB 0x53AE # 0 +0xD8CC 0x9765 # 0 +0xD8CD 0x8D5D # 0 +0xD8CE 0x531A # 0 +0xD8CF 0x53F5 # 0 +0xD8D0 0x5326 # 0 +0xD8D1 0x532E # 0 +0xD8D2 0x533E # 0 +0xD8D3 0x8D5C # 0 +0xD8D4 0x5366 # 0 +0xD8D5 0x5363 # 0 +0xD8D6 0x5202 # 0 +0xD8D7 0x5208 # 0 +0xD8D8 0x520E # 0 +0xD8D9 0x522D # 0 +0xD8DA 0x5233 # 0 +0xD8DB 0x523F # 0 +0xD8DC 0x5240 # 0 +0xD8DD 0x524C # 0 +0xD8DE 0x525E # 0 +0xD8DF 0x5261 # 0 +0xD8E0 0x525C # 0 +0xD8E1 0x84AF # 0 +0xD8E2 0x527D # 0 +0xD8E3 0x5282 # 0 +0xD8E4 0x5281 # 0 +0xD8E5 0x5290 # 0 +0xD8E6 0x5293 # 0 +0xD8E7 0x5182 # 0 +0xD8E8 0x7F54 # 0 +0xD8E9 0x4EBB # 0 +0xD8EA 0x4EC3 # 0 +0xD8EB 0x4EC9 # 0 +0xD8EC 0x4EC2 # 0 +0xD8ED 0x4EE8 # 0 +0xD8EE 0x4EE1 # 0 +0xD8EF 0x4EEB # 0 +0xD8F0 0x4EDE # 0 +0xD8F1 0x4F1B # 0 +0xD8F2 0x4EF3 # 0 +0xD8F3 0x4F22 # 0 +0xD8F4 0x4F64 # 0 +0xD8F5 0x4EF5 # 0 +0xD8F6 0x4F25 # 0 +0xD8F7 0x4F27 # 0 +0xD8F8 0x4F09 # 0 +0xD8F9 0x4F2B # 0 +0xD8FA 0x4F5E # 0 +0xD8FB 0x4F67 # 0 +0xD8FC 0x6538 # 0 +0xD8FD 0x4F5A # 0 +0xD8FE 0x4F5D # 0 +0xD940 0x8CAE # 0 +0xD941 0x8CAF # 0 +0xD942 0x8CB0 # 0 +0xD943 0x8CB1 # 0 +0xD944 0x8CB2 # 0 +0xD945 0x8CB3 # 0 +0xD946 0x8CB4 # 0 +0xD947 0x8CB5 # 0 +0xD948 0x8CB6 # 0 +0xD949 0x8CB7 # 0 +0xD94A 0x8CB8 # 0 +0xD94B 0x8CB9 # 0 +0xD94C 0x8CBA # 0 +0xD94D 0x8CBB # 0 +0xD94E 0x8CBC # 0 +0xD94F 0x8CBD # 0 +0xD950 0x8CBE # 0 +0xD951 0x8CBF # 0 +0xD952 0x8CC0 # 0 +0xD953 0x8CC1 # 0 +0xD954 0x8CC2 # 0 +0xD955 0x8CC3 # 0 +0xD956 0x8CC4 # 0 +0xD957 0x8CC5 # 0 +0xD958 0x8CC6 # 0 +0xD959 0x8CC7 # 0 +0xD95A 0x8CC8 # 0 +0xD95B 0x8CC9 # 0 +0xD95C 0x8CCA # 0 +0xD95D 0x8CCB # 0 +0xD95E 0x8CCC # 0 +0xD95F 0x8CCD # 0 +0xD960 0x8CCE # 0 +0xD961 0x8CCF # 0 +0xD962 0x8CD0 # 0 +0xD963 0x8CD1 # 0 +0xD964 0x8CD2 # 0 +0xD965 0x8CD3 # 0 +0xD966 0x8CD4 # 0 +0xD967 0x8CD5 # 0 +0xD968 0x8CD6 # 0 +0xD969 0x8CD7 # 0 +0xD96A 0x8CD8 # 0 +0xD96B 0x8CD9 # 0 +0xD96C 0x8CDA # 0 +0xD96D 0x8CDB # 0 +0xD96E 0x8CDC # 0 +0xD96F 0x8CDD # 0 +0xD970 0x8CDE # 0 +0xD971 0x8CDF # 0 +0xD972 0x8CE0 # 0 +0xD973 0x8CE1 # 0 +0xD974 0x8CE2 # 0 +0xD975 0x8CE3 # 0 +0xD976 0x8CE4 # 0 +0xD977 0x8CE5 # 0 +0xD978 0x8CE6 # 0 +0xD979 0x8CE7 # 0 +0xD97A 0x8CE8 # 0 +0xD97B 0x8CE9 # 0 +0xD97C 0x8CEA # 0 +0xD97D 0x8CEB # 0 +0xD97E 0x8CEC # 0 +0xD980 0x8CED # 0 +0xD981 0x8CEE # 0 +0xD982 0x8CEF # 0 +0xD983 0x8CF0 # 0 +0xD984 0x8CF1 # 0 +0xD985 0x8CF2 # 0 +0xD986 0x8CF3 # 0 +0xD987 0x8CF4 # 0 +0xD988 0x8CF5 # 0 +0xD989 0x8CF6 # 0 +0xD98A 0x8CF7 # 0 +0xD98B 0x8CF8 # 0 +0xD98C 0x8CF9 # 0 +0xD98D 0x8CFA # 0 +0xD98E 0x8CFB # 0 +0xD98F 0x8CFC # 0 +0xD990 0x8CFD # 0 +0xD991 0x8CFE # 0 +0xD992 0x8CFF # 0 +0xD993 0x8D00 # 0 +0xD994 0x8D01 # 0 +0xD995 0x8D02 # 0 +0xD996 0x8D03 # 0 +0xD997 0x8D04 # 0 +0xD998 0x8D05 # 0 +0xD999 0x8D06 # 0 +0xD99A 0x8D07 # 0 +0xD99B 0x8D08 # 0 +0xD99C 0x8D09 # 0 +0xD99D 0x8D0A # 0 +0xD99E 0x8D0B # 0 +0xD99F 0x8D0C # 0 +0xD9A0 0x8D0D # 0 +0xD9A1 0x4F5F # 0 +0xD9A2 0x4F57 # 0 +0xD9A3 0x4F32 # 0 +0xD9A4 0x4F3D # 0 +0xD9A5 0x4F76 # 0 +0xD9A6 0x4F74 # 0 +0xD9A7 0x4F91 # 0 +0xD9A8 0x4F89 # 0 +0xD9A9 0x4F83 # 0 +0xD9AA 0x4F8F # 0 +0xD9AB 0x4F7E # 0 +0xD9AC 0x4F7B # 0 +0xD9AD 0x4FAA # 0 +0xD9AE 0x4F7C # 0 +0xD9AF 0x4FAC # 0 +0xD9B0 0x4F94 # 0 +0xD9B1 0x4FE6 # 0 +0xD9B2 0x4FE8 # 0 +0xD9B3 0x4FEA # 0 +0xD9B4 0x4FC5 # 0 +0xD9B5 0x4FDA # 0 +0xD9B6 0x4FE3 # 0 +0xD9B7 0x4FDC # 0 +0xD9B8 0x4FD1 # 0 +0xD9B9 0x4FDF # 0 +0xD9BA 0x4FF8 # 0 +0xD9BB 0x5029 # 0 +0xD9BC 0x504C # 0 +0xD9BD 0x4FF3 # 0 +0xD9BE 0x502C # 0 +0xD9BF 0x500F # 0 +0xD9C0 0x502E # 0 +0xD9C1 0x502D # 0 +0xD9C2 0x4FFE # 0 +0xD9C3 0x501C # 0 +0xD9C4 0x500C # 0 +0xD9C5 0x5025 # 0 +0xD9C6 0x5028 # 0 +0xD9C7 0x507E # 0 +0xD9C8 0x5043 # 0 +0xD9C9 0x5055 # 0 +0xD9CA 0x5048 # 0 +0xD9CB 0x504E # 0 +0xD9CC 0x506C # 0 +0xD9CD 0x507B # 0 +0xD9CE 0x50A5 # 0 +0xD9CF 0x50A7 # 0 +0xD9D0 0x50A9 # 0 +0xD9D1 0x50BA # 0 +0xD9D2 0x50D6 # 0 +0xD9D3 0x5106 # 0 +0xD9D4 0x50ED # 0 +0xD9D5 0x50EC # 0 +0xD9D6 0x50E6 # 0 +0xD9D7 0x50EE # 0 +0xD9D8 0x5107 # 0 +0xD9D9 0x510B # 0 +0xD9DA 0x4EDD # 0 +0xD9DB 0x6C3D # 0 +0xD9DC 0x4F58 # 0 +0xD9DD 0x4F65 # 0 +0xD9DE 0x4FCE # 0 +0xD9DF 0x9FA0 # 0 +0xD9E0 0x6C46 # 0 +0xD9E1 0x7C74 # 0 +0xD9E2 0x516E # 0 +0xD9E3 0x5DFD # 0 +0xD9E4 0x9EC9 # 0 +0xD9E5 0x9998 # 0 +0xD9E6 0x5181 # 0 +0xD9E7 0x5914 # 0 +0xD9E8 0x52F9 # 0 +0xD9E9 0x530D # 0 +0xD9EA 0x8A07 # 0 +0xD9EB 0x5310 # 0 +0xD9EC 0x51EB # 0 +0xD9ED 0x5919 # 0 +0xD9EE 0x5155 # 0 +0xD9EF 0x4EA0 # 0 +0xD9F0 0x5156 # 0 +0xD9F1 0x4EB3 # 0 +0xD9F2 0x886E # 0 +0xD9F3 0x88A4 # 0 +0xD9F4 0x4EB5 # 0 +0xD9F5 0x8114 # 0 +0xD9F6 0x88D2 # 0 +0xD9F7 0x7980 # 0 +0xD9F8 0x5B34 # 0 +0xD9F9 0x8803 # 0 +0xD9FA 0x7FB8 # 0 +0xD9FB 0x51AB # 0 +0xD9FC 0x51B1 # 0 +0xD9FD 0x51BD # 0 +0xD9FE 0x51BC # 0 +0xDA40 0x8D0E # 0 +0xDA41 0x8D0F # 0 +0xDA42 0x8D10 # 0 +0xDA43 0x8D11 # 0 +0xDA44 0x8D12 # 0 +0xDA45 0x8D13 # 0 +0xDA46 0x8D14 # 0 +0xDA47 0x8D15 # 0 +0xDA48 0x8D16 # 0 +0xDA49 0x8D17 # 0 +0xDA4A 0x8D18 # 0 +0xDA4B 0x8D19 # 0 +0xDA4C 0x8D1A # 0 +0xDA4D 0x8D1B # 0 +0xDA4E 0x8D1C # 0 +0xDA4F 0x8D20 # 0 +0xDA50 0x8D51 # 0 +0xDA51 0x8D52 # 0 +0xDA52 0x8D57 # 0 +0xDA53 0x8D5F # 0 +0xDA54 0x8D65 # 0 +0xDA55 0x8D68 # 0 +0xDA56 0x8D69 # 0 +0xDA57 0x8D6A # 0 +0xDA58 0x8D6C # 0 +0xDA59 0x8D6E # 0 +0xDA5A 0x8D6F # 0 +0xDA5B 0x8D71 # 0 +0xDA5C 0x8D72 # 0 +0xDA5D 0x8D78 # 0 +0xDA5E 0x8D79 # 0 +0xDA5F 0x8D7A # 0 +0xDA60 0x8D7B # 0 +0xDA61 0x8D7C # 0 +0xDA62 0x8D7D # 0 +0xDA63 0x8D7E # 0 +0xDA64 0x8D7F # 0 +0xDA65 0x8D80 # 0 +0xDA66 0x8D82 # 0 +0xDA67 0x8D83 # 0 +0xDA68 0x8D86 # 0 +0xDA69 0x8D87 # 0 +0xDA6A 0x8D88 # 0 +0xDA6B 0x8D89 # 0 +0xDA6C 0x8D8C # 0 +0xDA6D 0x8D8D # 0 +0xDA6E 0x8D8E # 0 +0xDA6F 0x8D8F # 0 +0xDA70 0x8D90 # 0 +0xDA71 0x8D92 # 0 +0xDA72 0x8D93 # 0 +0xDA73 0x8D95 # 0 +0xDA74 0x8D96 # 0 +0xDA75 0x8D97 # 0 +0xDA76 0x8D98 # 0 +0xDA77 0x8D99 # 0 +0xDA78 0x8D9A # 0 +0xDA79 0x8D9B # 0 +0xDA7A 0x8D9C # 0 +0xDA7B 0x8D9D # 0 +0xDA7C 0x8D9E # 0 +0xDA7D 0x8DA0 # 0 +0xDA7E 0x8DA1 # 0 +0xDA80 0x8DA2 # 0 +0xDA81 0x8DA4 # 0 +0xDA82 0x8DA5 # 0 +0xDA83 0x8DA6 # 0 +0xDA84 0x8DA7 # 0 +0xDA85 0x8DA8 # 0 +0xDA86 0x8DA9 # 0 +0xDA87 0x8DAA # 0 +0xDA88 0x8DAB # 0 +0xDA89 0x8DAC # 0 +0xDA8A 0x8DAD # 0 +0xDA8B 0x8DAE # 0 +0xDA8C 0x8DAF # 0 +0xDA8D 0x8DB0 # 0 +0xDA8E 0x8DB2 # 0 +0xDA8F 0x8DB6 # 0 +0xDA90 0x8DB7 # 0 +0xDA91 0x8DB9 # 0 +0xDA92 0x8DBB # 0 +0xDA93 0x8DBD # 0 +0xDA94 0x8DC0 # 0 +0xDA95 0x8DC1 # 0 +0xDA96 0x8DC2 # 0 +0xDA97 0x8DC5 # 0 +0xDA98 0x8DC7 # 0 +0xDA99 0x8DC8 # 0 +0xDA9A 0x8DC9 # 0 +0xDA9B 0x8DCA # 0 +0xDA9C 0x8DCD # 0 +0xDA9D 0x8DD0 # 0 +0xDA9E 0x8DD2 # 0 +0xDA9F 0x8DD3 # 0 +0xDAA0 0x8DD4 # 0 +0xDAA1 0x51C7 # 0 +0xDAA2 0x5196 # 0 +0xDAA3 0x51A2 # 0 +0xDAA4 0x51A5 # 0 +0xDAA5 0x8BA0 # 0 +0xDAA6 0x8BA6 # 0 +0xDAA7 0x8BA7 # 0 +0xDAA8 0x8BAA # 0 +0xDAA9 0x8BB4 # 0 +0xDAAA 0x8BB5 # 0 +0xDAAB 0x8BB7 # 0 +0xDAAC 0x8BC2 # 0 +0xDAAD 0x8BC3 # 0 +0xDAAE 0x8BCB # 0 +0xDAAF 0x8BCF # 0 +0xDAB0 0x8BCE # 0 +0xDAB1 0x8BD2 # 0 +0xDAB2 0x8BD3 # 0 +0xDAB3 0x8BD4 # 0 +0xDAB4 0x8BD6 # 0 +0xDAB5 0x8BD8 # 0 +0xDAB6 0x8BD9 # 0 +0xDAB7 0x8BDC # 0 +0xDAB8 0x8BDF # 0 +0xDAB9 0x8BE0 # 0 +0xDABA 0x8BE4 # 0 +0xDABB 0x8BE8 # 0 +0xDABC 0x8BE9 # 0 +0xDABD 0x8BEE # 0 +0xDABE 0x8BF0 # 0 +0xDABF 0x8BF3 # 0 +0xDAC0 0x8BF6 # 0 +0xDAC1 0x8BF9 # 0 +0xDAC2 0x8BFC # 0 +0xDAC3 0x8BFF # 0 +0xDAC4 0x8C00 # 0 +0xDAC5 0x8C02 # 0 +0xDAC6 0x8C04 # 0 +0xDAC7 0x8C07 # 0 +0xDAC8 0x8C0C # 0 +0xDAC9 0x8C0F # 0 +0xDACA 0x8C11 # 0 +0xDACB 0x8C12 # 0 +0xDACC 0x8C14 # 0 +0xDACD 0x8C15 # 0 +0xDACE 0x8C16 # 0 +0xDACF 0x8C19 # 0 +0xDAD0 0x8C1B # 0 +0xDAD1 0x8C18 # 0 +0xDAD2 0x8C1D # 0 +0xDAD3 0x8C1F # 0 +0xDAD4 0x8C20 # 0 +0xDAD5 0x8C21 # 0 +0xDAD6 0x8C25 # 0 +0xDAD7 0x8C27 # 0 +0xDAD8 0x8C2A # 0 +0xDAD9 0x8C2B # 0 +0xDADA 0x8C2E # 0 +0xDADB 0x8C2F # 0 +0xDADC 0x8C32 # 0 +0xDADD 0x8C33 # 0 +0xDADE 0x8C35 # 0 +0xDADF 0x8C36 # 0 +0xDAE0 0x5369 # 0 +0xDAE1 0x537A # 0 +0xDAE2 0x961D # 0 +0xDAE3 0x9622 # 0 +0xDAE4 0x9621 # 0 +0xDAE5 0x9631 # 0 +0xDAE6 0x962A # 0 +0xDAE7 0x963D # 0 +0xDAE8 0x963C # 0 +0xDAE9 0x9642 # 0 +0xDAEA 0x9649 # 0 +0xDAEB 0x9654 # 0 +0xDAEC 0x965F # 0 +0xDAED 0x9667 # 0 +0xDAEE 0x966C # 0 +0xDAEF 0x9672 # 0 +0xDAF0 0x9674 # 0 +0xDAF1 0x9688 # 0 +0xDAF2 0x968D # 0 +0xDAF3 0x9697 # 0 +0xDAF4 0x96B0 # 0 +0xDAF5 0x9097 # 0 +0xDAF6 0x909B # 0 +0xDAF7 0x909D # 0 +0xDAF8 0x9099 # 0 +0xDAF9 0x90AC # 0 +0xDAFA 0x90A1 # 0 +0xDAFB 0x90B4 # 0 +0xDAFC 0x90B3 # 0 +0xDAFD 0x90B6 # 0 +0xDAFE 0x90BA # 0 +0xDB40 0x8DD5 # 0 +0xDB41 0x8DD8 # 0 +0xDB42 0x8DD9 # 0 +0xDB43 0x8DDC # 0 +0xDB44 0x8DE0 # 0 +0xDB45 0x8DE1 # 0 +0xDB46 0x8DE2 # 0 +0xDB47 0x8DE5 # 0 +0xDB48 0x8DE6 # 0 +0xDB49 0x8DE7 # 0 +0xDB4A 0x8DE9 # 0 +0xDB4B 0x8DED # 0 +0xDB4C 0x8DEE # 0 +0xDB4D 0x8DF0 # 0 +0xDB4E 0x8DF1 # 0 +0xDB4F 0x8DF2 # 0 +0xDB50 0x8DF4 # 0 +0xDB51 0x8DF6 # 0 +0xDB52 0x8DFC # 0 +0xDB53 0x8DFE # 0 +0xDB54 0x8DFF # 0 +0xDB55 0x8E00 # 0 +0xDB56 0x8E01 # 0 +0xDB57 0x8E02 # 0 +0xDB58 0x8E03 # 0 +0xDB59 0x8E04 # 0 +0xDB5A 0x8E06 # 0 +0xDB5B 0x8E07 # 0 +0xDB5C 0x8E08 # 0 +0xDB5D 0x8E0B # 0 +0xDB5E 0x8E0D # 0 +0xDB5F 0x8E0E # 0 +0xDB60 0x8E10 # 0 +0xDB61 0x8E11 # 0 +0xDB62 0x8E12 # 0 +0xDB63 0x8E13 # 0 +0xDB64 0x8E15 # 0 +0xDB65 0x8E16 # 0 +0xDB66 0x8E17 # 0 +0xDB67 0x8E18 # 0 +0xDB68 0x8E19 # 0 +0xDB69 0x8E1A # 0 +0xDB6A 0x8E1B # 0 +0xDB6B 0x8E1C # 0 +0xDB6C 0x8E20 # 0 +0xDB6D 0x8E21 # 0 +0xDB6E 0x8E24 # 0 +0xDB6F 0x8E25 # 0 +0xDB70 0x8E26 # 0 +0xDB71 0x8E27 # 0 +0xDB72 0x8E28 # 0 +0xDB73 0x8E2B # 0 +0xDB74 0x8E2D # 0 +0xDB75 0x8E30 # 0 +0xDB76 0x8E32 # 0 +0xDB77 0x8E33 # 0 +0xDB78 0x8E34 # 0 +0xDB79 0x8E36 # 0 +0xDB7A 0x8E37 # 0 +0xDB7B 0x8E38 # 0 +0xDB7C 0x8E3B # 0 +0xDB7D 0x8E3C # 0 +0xDB7E 0x8E3E # 0 +0xDB80 0x8E3F # 0 +0xDB81 0x8E43 # 0 +0xDB82 0x8E45 # 0 +0xDB83 0x8E46 # 0 +0xDB84 0x8E4C # 0 +0xDB85 0x8E4D # 0 +0xDB86 0x8E4E # 0 +0xDB87 0x8E4F # 0 +0xDB88 0x8E50 # 0 +0xDB89 0x8E53 # 0 +0xDB8A 0x8E54 # 0 +0xDB8B 0x8E55 # 0 +0xDB8C 0x8E56 # 0 +0xDB8D 0x8E57 # 0 +0xDB8E 0x8E58 # 0 +0xDB8F 0x8E5A # 0 +0xDB90 0x8E5B # 0 +0xDB91 0x8E5C # 0 +0xDB92 0x8E5D # 0 +0xDB93 0x8E5E # 0 +0xDB94 0x8E5F # 0 +0xDB95 0x8E60 # 0 +0xDB96 0x8E61 # 0 +0xDB97 0x8E62 # 0 +0xDB98 0x8E63 # 0 +0xDB99 0x8E64 # 0 +0xDB9A 0x8E65 # 0 +0xDB9B 0x8E67 # 0 +0xDB9C 0x8E68 # 0 +0xDB9D 0x8E6A # 0 +0xDB9E 0x8E6B # 0 +0xDB9F 0x8E6E # 0 +0xDBA0 0x8E71 # 0 +0xDBA1 0x90B8 # 0 +0xDBA2 0x90B0 # 0 +0xDBA3 0x90CF # 0 +0xDBA4 0x90C5 # 0 +0xDBA5 0x90BE # 0 +0xDBA6 0x90D0 # 0 +0xDBA7 0x90C4 # 0 +0xDBA8 0x90C7 # 0 +0xDBA9 0x90D3 # 0 +0xDBAA 0x90E6 # 0 +0xDBAB 0x90E2 # 0 +0xDBAC 0x90DC # 0 +0xDBAD 0x90D7 # 0 +0xDBAE 0x90DB # 0 +0xDBAF 0x90EB # 0 +0xDBB0 0x90EF # 0 +0xDBB1 0x90FE # 0 +0xDBB2 0x9104 # 0 +0xDBB3 0x9122 # 0 +0xDBB4 0x911E # 0 +0xDBB5 0x9123 # 0 +0xDBB6 0x9131 # 0 +0xDBB7 0x912F # 0 +0xDBB8 0x9139 # 0 +0xDBB9 0x9143 # 0 +0xDBBA 0x9146 # 0 +0xDBBB 0x520D # 0 +0xDBBC 0x5942 # 0 +0xDBBD 0x52A2 # 0 +0xDBBE 0x52AC # 0 +0xDBBF 0x52AD # 0 +0xDBC0 0x52BE # 0 +0xDBC1 0x54FF # 0 +0xDBC2 0x52D0 # 0 +0xDBC3 0x52D6 # 0 +0xDBC4 0x52F0 # 0 +0xDBC5 0x53DF # 0 +0xDBC6 0x71EE # 0 +0xDBC7 0x77CD # 0 +0xDBC8 0x5EF4 # 0 +0xDBC9 0x51F5 # 0 +0xDBCA 0x51FC # 0 +0xDBCB 0x9B2F # 0 +0xDBCC 0x53B6 # 0 +0xDBCD 0x5F01 # 0 +0xDBCE 0x755A # 0 +0xDBCF 0x5DEF # 0 +0xDBD0 0x574C # 0 +0xDBD1 0x57A9 # 0 +0xDBD2 0x57A1 # 0 +0xDBD3 0x587E # 0 +0xDBD4 0x58BC # 0 +0xDBD5 0x58C5 # 0 +0xDBD6 0x58D1 # 0 +0xDBD7 0x5729 # 0 +0xDBD8 0x572C # 0 +0xDBD9 0x572A # 0 +0xDBDA 0x5733 # 0 +0xDBDB 0x5739 # 0 +0xDBDC 0x572E # 0 +0xDBDD 0x572F # 0 +0xDBDE 0x575C # 0 +0xDBDF 0x573B # 0 +0xDBE0 0x5742 # 0 +0xDBE1 0x5769 # 0 +0xDBE2 0x5785 # 0 +0xDBE3 0x576B # 0 +0xDBE4 0x5786 # 0 +0xDBE5 0x577C # 0 +0xDBE6 0x577B # 0 +0xDBE7 0x5768 # 0 +0xDBE8 0x576D # 0 +0xDBE9 0x5776 # 0 +0xDBEA 0x5773 # 0 +0xDBEB 0x57AD # 0 +0xDBEC 0x57A4 # 0 +0xDBED 0x578C # 0 +0xDBEE 0x57B2 # 0 +0xDBEF 0x57CF # 0 +0xDBF0 0x57A7 # 0 +0xDBF1 0x57B4 # 0 +0xDBF2 0x5793 # 0 +0xDBF3 0x57A0 # 0 +0xDBF4 0x57D5 # 0 +0xDBF5 0x57D8 # 0 +0xDBF6 0x57DA # 0 +0xDBF7 0x57D9 # 0 +0xDBF8 0x57D2 # 0 +0xDBF9 0x57B8 # 0 +0xDBFA 0x57F4 # 0 +0xDBFB 0x57EF # 0 +0xDBFC 0x57F8 # 0 +0xDBFD 0x57E4 # 0 +0xDBFE 0x57DD # 0 +0xDC40 0x8E73 # 0 +0xDC41 0x8E75 # 0 +0xDC42 0x8E77 # 0 +0xDC43 0x8E78 # 0 +0xDC44 0x8E79 # 0 +0xDC45 0x8E7A # 0 +0xDC46 0x8E7B # 0 +0xDC47 0x8E7D # 0 +0xDC48 0x8E7E # 0 +0xDC49 0x8E80 # 0 +0xDC4A 0x8E82 # 0 +0xDC4B 0x8E83 # 0 +0xDC4C 0x8E84 # 0 +0xDC4D 0x8E86 # 0 +0xDC4E 0x8E88 # 0 +0xDC4F 0x8E89 # 0 +0xDC50 0x8E8A # 0 +0xDC51 0x8E8B # 0 +0xDC52 0x8E8C # 0 +0xDC53 0x8E8D # 0 +0xDC54 0x8E8E # 0 +0xDC55 0x8E91 # 0 +0xDC56 0x8E92 # 0 +0xDC57 0x8E93 # 0 +0xDC58 0x8E95 # 0 +0xDC59 0x8E96 # 0 +0xDC5A 0x8E97 # 0 +0xDC5B 0x8E98 # 0 +0xDC5C 0x8E99 # 0 +0xDC5D 0x8E9A # 0 +0xDC5E 0x8E9B # 0 +0xDC5F 0x8E9D # 0 +0xDC60 0x8E9F # 0 +0xDC61 0x8EA0 # 0 +0xDC62 0x8EA1 # 0 +0xDC63 0x8EA2 # 0 +0xDC64 0x8EA3 # 0 +0xDC65 0x8EA4 # 0 +0xDC66 0x8EA5 # 0 +0xDC67 0x8EA6 # 0 +0xDC68 0x8EA7 # 0 +0xDC69 0x8EA8 # 0 +0xDC6A 0x8EA9 # 0 +0xDC6B 0x8EAA # 0 +0xDC6C 0x8EAD # 0 +0xDC6D 0x8EAE # 0 +0xDC6E 0x8EB0 # 0 +0xDC6F 0x8EB1 # 0 +0xDC70 0x8EB3 # 0 +0xDC71 0x8EB4 # 0 +0xDC72 0x8EB5 # 0 +0xDC73 0x8EB6 # 0 +0xDC74 0x8EB7 # 0 +0xDC75 0x8EB8 # 0 +0xDC76 0x8EB9 # 0 +0xDC77 0x8EBB # 0 +0xDC78 0x8EBC # 0 +0xDC79 0x8EBD # 0 +0xDC7A 0x8EBE # 0 +0xDC7B 0x8EBF # 0 +0xDC7C 0x8EC0 # 0 +0xDC7D 0x8EC1 # 0 +0xDC7E 0x8EC2 # 0 +0xDC80 0x8EC3 # 0 +0xDC81 0x8EC4 # 0 +0xDC82 0x8EC5 # 0 +0xDC83 0x8EC6 # 0 +0xDC84 0x8EC7 # 0 +0xDC85 0x8EC8 # 0 +0xDC86 0x8EC9 # 0 +0xDC87 0x8ECA # 0 +0xDC88 0x8ECB # 0 +0xDC89 0x8ECC # 0 +0xDC8A 0x8ECD # 0 +0xDC8B 0x8ECF # 0 +0xDC8C 0x8ED0 # 0 +0xDC8D 0x8ED1 # 0 +0xDC8E 0x8ED2 # 0 +0xDC8F 0x8ED3 # 0 +0xDC90 0x8ED4 # 0 +0xDC91 0x8ED5 # 0 +0xDC92 0x8ED6 # 0 +0xDC93 0x8ED7 # 0 +0xDC94 0x8ED8 # 0 +0xDC95 0x8ED9 # 0 +0xDC96 0x8EDA # 0 +0xDC97 0x8EDB # 0 +0xDC98 0x8EDC # 0 +0xDC99 0x8EDD # 0 +0xDC9A 0x8EDE # 0 +0xDC9B 0x8EDF # 0 +0xDC9C 0x8EE0 # 0 +0xDC9D 0x8EE1 # 0 +0xDC9E 0x8EE2 # 0 +0xDC9F 0x8EE3 # 0 +0xDCA0 0x8EE4 # 0 +0xDCA1 0x580B # 0 +0xDCA2 0x580D # 0 +0xDCA3 0x57FD # 0 +0xDCA4 0x57ED # 0 +0xDCA5 0x5800 # 0 +0xDCA6 0x581E # 0 +0xDCA7 0x5819 # 0 +0xDCA8 0x5844 # 0 +0xDCA9 0x5820 # 0 +0xDCAA 0x5865 # 0 +0xDCAB 0x586C # 0 +0xDCAC 0x5881 # 0 +0xDCAD 0x5889 # 0 +0xDCAE 0x589A # 0 +0xDCAF 0x5880 # 0 +0xDCB0 0x99A8 # 0 +0xDCB1 0x9F19 # 0 +0xDCB2 0x61FF # 0 +0xDCB3 0x8279 # 0 +0xDCB4 0x827D # 0 +0xDCB5 0x827F # 0 +0xDCB6 0x828F # 0 +0xDCB7 0x828A # 0 +0xDCB8 0x82A8 # 0 +0xDCB9 0x8284 # 0 +0xDCBA 0x828E # 0 +0xDCBB 0x8291 # 0 +0xDCBC 0x8297 # 0 +0xDCBD 0x8299 # 0 +0xDCBE 0x82AB # 0 +0xDCBF 0x82B8 # 0 +0xDCC0 0x82BE # 0 +0xDCC1 0x82B0 # 0 +0xDCC2 0x82C8 # 0 +0xDCC3 0x82CA # 0 +0xDCC4 0x82E3 # 0 +0xDCC5 0x8298 # 0 +0xDCC6 0x82B7 # 0 +0xDCC7 0x82AE # 0 +0xDCC8 0x82CB # 0 +0xDCC9 0x82CC # 0 +0xDCCA 0x82C1 # 0 +0xDCCB 0x82A9 # 0 +0xDCCC 0x82B4 # 0 +0xDCCD 0x82A1 # 0 +0xDCCE 0x82AA # 0 +0xDCCF 0x829F # 0 +0xDCD0 0x82C4 # 0 +0xDCD1 0x82CE # 0 +0xDCD2 0x82A4 # 0 +0xDCD3 0x82E1 # 0 +0xDCD4 0x8309 # 0 +0xDCD5 0x82F7 # 0 +0xDCD6 0x82E4 # 0 +0xDCD7 0x830F # 0 +0xDCD8 0x8307 # 0 +0xDCD9 0x82DC # 0 +0xDCDA 0x82F4 # 0 +0xDCDB 0x82D2 # 0 +0xDCDC 0x82D8 # 0 +0xDCDD 0x830C # 0 +0xDCDE 0x82FB # 0 +0xDCDF 0x82D3 # 0 +0xDCE0 0x8311 # 0 +0xDCE1 0x831A # 0 +0xDCE2 0x8306 # 0 +0xDCE3 0x8314 # 0 +0xDCE4 0x8315 # 0 +0xDCE5 0x82E0 # 0 +0xDCE6 0x82D5 # 0 +0xDCE7 0x831C # 0 +0xDCE8 0x8351 # 0 +0xDCE9 0x835B # 0 +0xDCEA 0x835C # 0 +0xDCEB 0x8308 # 0 +0xDCEC 0x8392 # 0 +0xDCED 0x833C # 0 +0xDCEE 0x8334 # 0 +0xDCEF 0x8331 # 0 +0xDCF0 0x839B # 0 +0xDCF1 0x835E # 0 +0xDCF2 0x832F # 0 +0xDCF3 0x834F # 0 +0xDCF4 0x8347 # 0 +0xDCF5 0x8343 # 0 +0xDCF6 0x835F # 0 +0xDCF7 0x8340 # 0 +0xDCF8 0x8317 # 0 +0xDCF9 0x8360 # 0 +0xDCFA 0x832D # 0 +0xDCFB 0x833A # 0 +0xDCFC 0x8333 # 0 +0xDCFD 0x8366 # 0 +0xDCFE 0x8365 # 0 +0xDD40 0x8EE5 # 0 +0xDD41 0x8EE6 # 0 +0xDD42 0x8EE7 # 0 +0xDD43 0x8EE8 # 0 +0xDD44 0x8EE9 # 0 +0xDD45 0x8EEA # 0 +0xDD46 0x8EEB # 0 +0xDD47 0x8EEC # 0 +0xDD48 0x8EED # 0 +0xDD49 0x8EEE # 0 +0xDD4A 0x8EEF # 0 +0xDD4B 0x8EF0 # 0 +0xDD4C 0x8EF1 # 0 +0xDD4D 0x8EF2 # 0 +0xDD4E 0x8EF3 # 0 +0xDD4F 0x8EF4 # 0 +0xDD50 0x8EF5 # 0 +0xDD51 0x8EF6 # 0 +0xDD52 0x8EF7 # 0 +0xDD53 0x8EF8 # 0 +0xDD54 0x8EF9 # 0 +0xDD55 0x8EFA # 0 +0xDD56 0x8EFB # 0 +0xDD57 0x8EFC # 0 +0xDD58 0x8EFD # 0 +0xDD59 0x8EFE # 0 +0xDD5A 0x8EFF # 0 +0xDD5B 0x8F00 # 0 +0xDD5C 0x8F01 # 0 +0xDD5D 0x8F02 # 0 +0xDD5E 0x8F03 # 0 +0xDD5F 0x8F04 # 0 +0xDD60 0x8F05 # 0 +0xDD61 0x8F06 # 0 +0xDD62 0x8F07 # 0 +0xDD63 0x8F08 # 0 +0xDD64 0x8F09 # 0 +0xDD65 0x8F0A # 0 +0xDD66 0x8F0B # 0 +0xDD67 0x8F0C # 0 +0xDD68 0x8F0D # 0 +0xDD69 0x8F0E # 0 +0xDD6A 0x8F0F # 0 +0xDD6B 0x8F10 # 0 +0xDD6C 0x8F11 # 0 +0xDD6D 0x8F12 # 0 +0xDD6E 0x8F13 # 0 +0xDD6F 0x8F14 # 0 +0xDD70 0x8F15 # 0 +0xDD71 0x8F16 # 0 +0xDD72 0x8F17 # 0 +0xDD73 0x8F18 # 0 +0xDD74 0x8F19 # 0 +0xDD75 0x8F1A # 0 +0xDD76 0x8F1B # 0 +0xDD77 0x8F1C # 0 +0xDD78 0x8F1D # 0 +0xDD79 0x8F1E # 0 +0xDD7A 0x8F1F # 0 +0xDD7B 0x8F20 # 0 +0xDD7C 0x8F21 # 0 +0xDD7D 0x8F22 # 0 +0xDD7E 0x8F23 # 0 +0xDD80 0x8F24 # 0 +0xDD81 0x8F25 # 0 +0xDD82 0x8F26 # 0 +0xDD83 0x8F27 # 0 +0xDD84 0x8F28 # 0 +0xDD85 0x8F29 # 0 +0xDD86 0x8F2A # 0 +0xDD87 0x8F2B # 0 +0xDD88 0x8F2C # 0 +0xDD89 0x8F2D # 0 +0xDD8A 0x8F2E # 0 +0xDD8B 0x8F2F # 0 +0xDD8C 0x8F30 # 0 +0xDD8D 0x8F31 # 0 +0xDD8E 0x8F32 # 0 +0xDD8F 0x8F33 # 0 +0xDD90 0x8F34 # 0 +0xDD91 0x8F35 # 0 +0xDD92 0x8F36 # 0 +0xDD93 0x8F37 # 0 +0xDD94 0x8F38 # 0 +0xDD95 0x8F39 # 0 +0xDD96 0x8F3A # 0 +0xDD97 0x8F3B # 0 +0xDD98 0x8F3C # 0 +0xDD99 0x8F3D # 0 +0xDD9A 0x8F3E # 0 +0xDD9B 0x8F3F # 0 +0xDD9C 0x8F40 # 0 +0xDD9D 0x8F41 # 0 +0xDD9E 0x8F42 # 0 +0xDD9F 0x8F43 # 0 +0xDDA0 0x8F44 # 0 +0xDDA1 0x8368 # 0 +0xDDA2 0x831B # 0 +0xDDA3 0x8369 # 0 +0xDDA4 0x836C # 0 +0xDDA5 0x836A # 0 +0xDDA6 0x836D # 0 +0xDDA7 0x836E # 0 +0xDDA8 0x83B0 # 0 +0xDDA9 0x8378 # 0 +0xDDAA 0x83B3 # 0 +0xDDAB 0x83B4 # 0 +0xDDAC 0x83A0 # 0 +0xDDAD 0x83AA # 0 +0xDDAE 0x8393 # 0 +0xDDAF 0x839C # 0 +0xDDB0 0x8385 # 0 +0xDDB1 0x837C # 0 +0xDDB2 0x83B6 # 0 +0xDDB3 0x83A9 # 0 +0xDDB4 0x837D # 0 +0xDDB5 0x83B8 # 0 +0xDDB6 0x837B # 0 +0xDDB7 0x8398 # 0 +0xDDB8 0x839E # 0 +0xDDB9 0x83A8 # 0 +0xDDBA 0x83BA # 0 +0xDDBB 0x83BC # 0 +0xDDBC 0x83C1 # 0 +0xDDBD 0x8401 # 0 +0xDDBE 0x83E5 # 0 +0xDDBF 0x83D8 # 0 +0xDDC0 0x5807 # 0 +0xDDC1 0x8418 # 0 +0xDDC2 0x840B # 0 +0xDDC3 0x83DD # 0 +0xDDC4 0x83FD # 0 +0xDDC5 0x83D6 # 0 +0xDDC6 0x841C # 0 +0xDDC7 0x8438 # 0 +0xDDC8 0x8411 # 0 +0xDDC9 0x8406 # 0 +0xDDCA 0x83D4 # 0 +0xDDCB 0x83DF # 0 +0xDDCC 0x840F # 0 +0xDDCD 0x8403 # 0 +0xDDCE 0x83F8 # 0 +0xDDCF 0x83F9 # 0 +0xDDD0 0x83EA # 0 +0xDDD1 0x83C5 # 0 +0xDDD2 0x83C0 # 0 +0xDDD3 0x8426 # 0 +0xDDD4 0x83F0 # 0 +0xDDD5 0x83E1 # 0 +0xDDD6 0x845C # 0 +0xDDD7 0x8451 # 0 +0xDDD8 0x845A # 0 +0xDDD9 0x8459 # 0 +0xDDDA 0x8473 # 0 +0xDDDB 0x8487 # 0 +0xDDDC 0x8488 # 0 +0xDDDD 0x847A # 0 +0xDDDE 0x8489 # 0 +0xDDDF 0x8478 # 0 +0xDDE0 0x843C # 0 +0xDDE1 0x8446 # 0 +0xDDE2 0x8469 # 0 +0xDDE3 0x8476 # 0 +0xDDE4 0x848C # 0 +0xDDE5 0x848E # 0 +0xDDE6 0x8431 # 0 +0xDDE7 0x846D # 0 +0xDDE8 0x84C1 # 0 +0xDDE9 0x84CD # 0 +0xDDEA 0x84D0 # 0 +0xDDEB 0x84E6 # 0 +0xDDEC 0x84BD # 0 +0xDDED 0x84D3 # 0 +0xDDEE 0x84CA # 0 +0xDDEF 0x84BF # 0 +0xDDF0 0x84BA # 0 +0xDDF1 0x84E0 # 0 +0xDDF2 0x84A1 # 0 +0xDDF3 0x84B9 # 0 +0xDDF4 0x84B4 # 0 +0xDDF5 0x8497 # 0 +0xDDF6 0x84E5 # 0 +0xDDF7 0x84E3 # 0 +0xDDF8 0x850C # 0 +0xDDF9 0x750D # 0 +0xDDFA 0x8538 # 0 +0xDDFB 0x84F0 # 0 +0xDDFC 0x8539 # 0 +0xDDFD 0x851F # 0 +0xDDFE 0x853A # 0 +0xDE40 0x8F45 # 0 +0xDE41 0x8F46 # 0 +0xDE42 0x8F47 # 0 +0xDE43 0x8F48 # 0 +0xDE44 0x8F49 # 0 +0xDE45 0x8F4A # 0 +0xDE46 0x8F4B # 0 +0xDE47 0x8F4C # 0 +0xDE48 0x8F4D # 0 +0xDE49 0x8F4E # 0 +0xDE4A 0x8F4F # 0 +0xDE4B 0x8F50 # 0 +0xDE4C 0x8F51 # 0 +0xDE4D 0x8F52 # 0 +0xDE4E 0x8F53 # 0 +0xDE4F 0x8F54 # 0 +0xDE50 0x8F55 # 0 +0xDE51 0x8F56 # 0 +0xDE52 0x8F57 # 0 +0xDE53 0x8F58 # 0 +0xDE54 0x8F59 # 0 +0xDE55 0x8F5A # 0 +0xDE56 0x8F5B # 0 +0xDE57 0x8F5C # 0 +0xDE58 0x8F5D # 0 +0xDE59 0x8F5E # 0 +0xDE5A 0x8F5F # 0 +0xDE5B 0x8F60 # 0 +0xDE5C 0x8F61 # 0 +0xDE5D 0x8F62 # 0 +0xDE5E 0x8F63 # 0 +0xDE5F 0x8F64 # 0 +0xDE60 0x8F65 # 0 +0xDE61 0x8F6A # 0 +0xDE62 0x8F80 # 0 +0xDE63 0x8F8C # 0 +0xDE64 0x8F92 # 0 +0xDE65 0x8F9D # 0 +0xDE66 0x8FA0 # 0 +0xDE67 0x8FA1 # 0 +0xDE68 0x8FA2 # 0 +0xDE69 0x8FA4 # 0 +0xDE6A 0x8FA5 # 0 +0xDE6B 0x8FA6 # 0 +0xDE6C 0x8FA7 # 0 +0xDE6D 0x8FAA # 0 +0xDE6E 0x8FAC # 0 +0xDE6F 0x8FAD # 0 +0xDE70 0x8FAE # 0 +0xDE71 0x8FAF # 0 +0xDE72 0x8FB2 # 0 +0xDE73 0x8FB3 # 0 +0xDE74 0x8FB4 # 0 +0xDE75 0x8FB5 # 0 +0xDE76 0x8FB7 # 0 +0xDE77 0x8FB8 # 0 +0xDE78 0x8FBA # 0 +0xDE79 0x8FBB # 0 +0xDE7A 0x8FBC # 0 +0xDE7B 0x8FBF # 0 +0xDE7C 0x8FC0 # 0 +0xDE7D 0x8FC3 # 0 +0xDE7E 0x8FC6 # 0 +0xDE80 0x8FC9 # 0 +0xDE81 0x8FCA # 0 +0xDE82 0x8FCB # 0 +0xDE83 0x8FCC # 0 +0xDE84 0x8FCD # 0 +0xDE85 0x8FCF # 0 +0xDE86 0x8FD2 # 0 +0xDE87 0x8FD6 # 0 +0xDE88 0x8FD7 # 0 +0xDE89 0x8FDA # 0 +0xDE8A 0x8FE0 # 0 +0xDE8B 0x8FE1 # 0 +0xDE8C 0x8FE3 # 0 +0xDE8D 0x8FE7 # 0 +0xDE8E 0x8FEC # 0 +0xDE8F 0x8FEF # 0 +0xDE90 0x8FF1 # 0 +0xDE91 0x8FF2 # 0 +0xDE92 0x8FF4 # 0 +0xDE93 0x8FF5 # 0 +0xDE94 0x8FF6 # 0 +0xDE95 0x8FFA # 0 +0xDE96 0x8FFB # 0 +0xDE97 0x8FFC # 0 +0xDE98 0x8FFE # 0 +0xDE99 0x8FFF # 0 +0xDE9A 0x9007 # 0 +0xDE9B 0x9008 # 0 +0xDE9C 0x900C # 0 +0xDE9D 0x900E # 0 +0xDE9E 0x9013 # 0 +0xDE9F 0x9015 # 0 +0xDEA0 0x9018 # 0 +0xDEA1 0x8556 # 0 +0xDEA2 0x853B # 0 +0xDEA3 0x84FF # 0 +0xDEA4 0x84FC # 0 +0xDEA5 0x8559 # 0 +0xDEA6 0x8548 # 0 +0xDEA7 0x8568 # 0 +0xDEA8 0x8564 # 0 +0xDEA9 0x855E # 0 +0xDEAA 0x857A # 0 +0xDEAB 0x77A2 # 0 +0xDEAC 0x8543 # 0 +0xDEAD 0x8572 # 0 +0xDEAE 0x857B # 0 +0xDEAF 0x85A4 # 0 +0xDEB0 0x85A8 # 0 +0xDEB1 0x8587 # 0 +0xDEB2 0x858F # 0 +0xDEB3 0x8579 # 0 +0xDEB4 0x85AE # 0 +0xDEB5 0x859C # 0 +0xDEB6 0x8585 # 0 +0xDEB7 0x85B9 # 0 +0xDEB8 0x85B7 # 0 +0xDEB9 0x85B0 # 0 +0xDEBA 0x85D3 # 0 +0xDEBB 0x85C1 # 0 +0xDEBC 0x85DC # 0 +0xDEBD 0x85FF # 0 +0xDEBE 0x8627 # 0 +0xDEBF 0x8605 # 0 +0xDEC0 0x8629 # 0 +0xDEC1 0x8616 # 0 +0xDEC2 0x863C # 0 +0xDEC3 0x5EFE # 0 +0xDEC4 0x5F08 # 0 +0xDEC5 0x593C # 0 +0xDEC6 0x5941 # 0 +0xDEC7 0x8037 # 0 +0xDEC8 0x5955 # 0 +0xDEC9 0x595A # 0 +0xDECA 0x5958 # 0 +0xDECB 0x530F # 0 +0xDECC 0x5C22 # 0 +0xDECD 0x5C25 # 0 +0xDECE 0x5C2C # 0 +0xDECF 0x5C34 # 0 +0xDED0 0x624C # 0 +0xDED1 0x626A # 0 +0xDED2 0x629F # 0 +0xDED3 0x62BB # 0 +0xDED4 0x62CA # 0 +0xDED5 0x62DA # 0 +0xDED6 0x62D7 # 0 +0xDED7 0x62EE # 0 +0xDED8 0x6322 # 0 +0xDED9 0x62F6 # 0 +0xDEDA 0x6339 # 0 +0xDEDB 0x634B # 0 +0xDEDC 0x6343 # 0 +0xDEDD 0x63AD # 0 +0xDEDE 0x63F6 # 0 +0xDEDF 0x6371 # 0 +0xDEE0 0x637A # 0 +0xDEE1 0x638E # 0 +0xDEE2 0x63B4 # 0 +0xDEE3 0x636D # 0 +0xDEE4 0x63AC # 0 +0xDEE5 0x638A # 0 +0xDEE6 0x6369 # 0 +0xDEE7 0x63AE # 0 +0xDEE8 0x63BC # 0 +0xDEE9 0x63F2 # 0 +0xDEEA 0x63F8 # 0 +0xDEEB 0x63E0 # 0 +0xDEEC 0x63FF # 0 +0xDEED 0x63C4 # 0 +0xDEEE 0x63DE # 0 +0xDEEF 0x63CE # 0 +0xDEF0 0x6452 # 0 +0xDEF1 0x63C6 # 0 +0xDEF2 0x63BE # 0 +0xDEF3 0x6445 # 0 +0xDEF4 0x6441 # 0 +0xDEF5 0x640B # 0 +0xDEF6 0x641B # 0 +0xDEF7 0x6420 # 0 +0xDEF8 0x640C # 0 +0xDEF9 0x6426 # 0 +0xDEFA 0x6421 # 0 +0xDEFB 0x645E # 0 +0xDEFC 0x6484 # 0 +0xDEFD 0x646D # 0 +0xDEFE 0x6496 # 0 +0xDF40 0x9019 # 0 +0xDF41 0x901C # 0 +0xDF42 0x9023 # 0 +0xDF43 0x9024 # 0 +0xDF44 0x9025 # 0 +0xDF45 0x9027 # 0 +0xDF46 0x9028 # 0 +0xDF47 0x9029 # 0 +0xDF48 0x902A # 0 +0xDF49 0x902B # 0 +0xDF4A 0x902C # 0 +0xDF4B 0x9030 # 0 +0xDF4C 0x9031 # 0 +0xDF4D 0x9032 # 0 +0xDF4E 0x9033 # 0 +0xDF4F 0x9034 # 0 +0xDF50 0x9037 # 0 +0xDF51 0x9039 # 0 +0xDF52 0x903A # 0 +0xDF53 0x903D # 0 +0xDF54 0x903F # 0 +0xDF55 0x9040 # 0 +0xDF56 0x9043 # 0 +0xDF57 0x9045 # 0 +0xDF58 0x9046 # 0 +0xDF59 0x9048 # 0 +0xDF5A 0x9049 # 0 +0xDF5B 0x904A # 0 +0xDF5C 0x904B # 0 +0xDF5D 0x904C # 0 +0xDF5E 0x904E # 0 +0xDF5F 0x9054 # 0 +0xDF60 0x9055 # 0 +0xDF61 0x9056 # 0 +0xDF62 0x9059 # 0 +0xDF63 0x905A # 0 +0xDF64 0x905C # 0 +0xDF65 0x905D # 0 +0xDF66 0x905E # 0 +0xDF67 0x905F # 0 +0xDF68 0x9060 # 0 +0xDF69 0x9061 # 0 +0xDF6A 0x9064 # 0 +0xDF6B 0x9066 # 0 +0xDF6C 0x9067 # 0 +0xDF6D 0x9069 # 0 +0xDF6E 0x906A # 0 +0xDF6F 0x906B # 0 +0xDF70 0x906C # 0 +0xDF71 0x906F # 0 +0xDF72 0x9070 # 0 +0xDF73 0x9071 # 0 +0xDF74 0x9072 # 0 +0xDF75 0x9073 # 0 +0xDF76 0x9076 # 0 +0xDF77 0x9077 # 0 +0xDF78 0x9078 # 0 +0xDF79 0x9079 # 0 +0xDF7A 0x907A # 0 +0xDF7B 0x907B # 0 +0xDF7C 0x907C # 0 +0xDF7D 0x907E # 0 +0xDF7E 0x9081 # 0 +0xDF80 0x9084 # 0 +0xDF81 0x9085 # 0 +0xDF82 0x9086 # 0 +0xDF83 0x9087 # 0 +0xDF84 0x9089 # 0 +0xDF85 0x908A # 0 +0xDF86 0x908C # 0 +0xDF87 0x908D # 0 +0xDF88 0x908E # 0 +0xDF89 0x908F # 0 +0xDF8A 0x9090 # 0 +0xDF8B 0x9092 # 0 +0xDF8C 0x9094 # 0 +0xDF8D 0x9096 # 0 +0xDF8E 0x9098 # 0 +0xDF8F 0x909A # 0 +0xDF90 0x909C # 0 +0xDF91 0x909E # 0 +0xDF92 0x909F # 0 +0xDF93 0x90A0 # 0 +0xDF94 0x90A4 # 0 +0xDF95 0x90A5 # 0 +0xDF96 0x90A7 # 0 +0xDF97 0x90A8 # 0 +0xDF98 0x90A9 # 0 +0xDF99 0x90AB # 0 +0xDF9A 0x90AD # 0 +0xDF9B 0x90B2 # 0 +0xDF9C 0x90B7 # 0 +0xDF9D 0x90BC # 0 +0xDF9E 0x90BD # 0 +0xDF9F 0x90BF # 0 +0xDFA0 0x90C0 # 0 +0xDFA1 0x647A # 0 +0xDFA2 0x64B7 # 0 +0xDFA3 0x64B8 # 0 +0xDFA4 0x6499 # 0 +0xDFA5 0x64BA # 0 +0xDFA6 0x64C0 # 0 +0xDFA7 0x64D0 # 0 +0xDFA8 0x64D7 # 0 +0xDFA9 0x64E4 # 0 +0xDFAA 0x64E2 # 0 +0xDFAB 0x6509 # 0 +0xDFAC 0x6525 # 0 +0xDFAD 0x652E # 0 +0xDFAE 0x5F0B # 0 +0xDFAF 0x5FD2 # 0 +0xDFB0 0x7519 # 0 +0xDFB1 0x5F11 # 0 +0xDFB2 0x535F # 0 +0xDFB3 0x53F1 # 0 +0xDFB4 0x53FD # 0 +0xDFB5 0x53E9 # 0 +0xDFB6 0x53E8 # 0 +0xDFB7 0x53FB # 0 +0xDFB8 0x5412 # 0 +0xDFB9 0x5416 # 0 +0xDFBA 0x5406 # 0 +0xDFBB 0x544B # 0 +0xDFBC 0x5452 # 0 +0xDFBD 0x5453 # 0 +0xDFBE 0x5454 # 0 +0xDFBF 0x5456 # 0 +0xDFC0 0x5443 # 0 +0xDFC1 0x5421 # 0 +0xDFC2 0x5457 # 0 +0xDFC3 0x5459 # 0 +0xDFC4 0x5423 # 0 +0xDFC5 0x5432 # 0 +0xDFC6 0x5482 # 0 +0xDFC7 0x5494 # 0 +0xDFC8 0x5477 # 0 +0xDFC9 0x5471 # 0 +0xDFCA 0x5464 # 0 +0xDFCB 0x549A # 0 +0xDFCC 0x549B # 0 +0xDFCD 0x5484 # 0 +0xDFCE 0x5476 # 0 +0xDFCF 0x5466 # 0 +0xDFD0 0x549D # 0 +0xDFD1 0x54D0 # 0 +0xDFD2 0x54AD # 0 +0xDFD3 0x54C2 # 0 +0xDFD4 0x54B4 # 0 +0xDFD5 0x54D2 # 0 +0xDFD6 0x54A7 # 0 +0xDFD7 0x54A6 # 0 +0xDFD8 0x54D3 # 0 +0xDFD9 0x54D4 # 0 +0xDFDA 0x5472 # 0 +0xDFDB 0x54A3 # 0 +0xDFDC 0x54D5 # 0 +0xDFDD 0x54BB # 0 +0xDFDE 0x54BF # 0 +0xDFDF 0x54CC # 0 +0xDFE0 0x54D9 # 0 +0xDFE1 0x54DA # 0 +0xDFE2 0x54DC # 0 +0xDFE3 0x54A9 # 0 +0xDFE4 0x54AA # 0 +0xDFE5 0x54A4 # 0 +0xDFE6 0x54DD # 0 +0xDFE7 0x54CF # 0 +0xDFE8 0x54DE # 0 +0xDFE9 0x551B # 0 +0xDFEA 0x54E7 # 0 +0xDFEB 0x5520 # 0 +0xDFEC 0x54FD # 0 +0xDFED 0x5514 # 0 +0xDFEE 0x54F3 # 0 +0xDFEF 0x5522 # 0 +0xDFF0 0x5523 # 0 +0xDFF1 0x550F # 0 +0xDFF2 0x5511 # 0 +0xDFF3 0x5527 # 0 +0xDFF4 0x552A # 0 +0xDFF5 0x5567 # 0 +0xDFF6 0x558F # 0 +0xDFF7 0x55B5 # 0 +0xDFF8 0x5549 # 0 +0xDFF9 0x556D # 0 +0xDFFA 0x5541 # 0 +0xDFFB 0x5555 # 0 +0xDFFC 0x553F # 0 +0xDFFD 0x5550 # 0 +0xDFFE 0x553C # 0 +0xE040 0x90C2 # 0 +0xE041 0x90C3 # 0 +0xE042 0x90C6 # 0 +0xE043 0x90C8 # 0 +0xE044 0x90C9 # 0 +0xE045 0x90CB # 0 +0xE046 0x90CC # 0 +0xE047 0x90CD # 0 +0xE048 0x90D2 # 0 +0xE049 0x90D4 # 0 +0xE04A 0x90D5 # 0 +0xE04B 0x90D6 # 0 +0xE04C 0x90D8 # 0 +0xE04D 0x90D9 # 0 +0xE04E 0x90DA # 0 +0xE04F 0x90DE # 0 +0xE050 0x90DF # 0 +0xE051 0x90E0 # 0 +0xE052 0x90E3 # 0 +0xE053 0x90E4 # 0 +0xE054 0x90E5 # 0 +0xE055 0x90E9 # 0 +0xE056 0x90EA # 0 +0xE057 0x90EC # 0 +0xE058 0x90EE # 0 +0xE059 0x90F0 # 0 +0xE05A 0x90F1 # 0 +0xE05B 0x90F2 # 0 +0xE05C 0x90F3 # 0 +0xE05D 0x90F5 # 0 +0xE05E 0x90F6 # 0 +0xE05F 0x90F7 # 0 +0xE060 0x90F9 # 0 +0xE061 0x90FA # 0 +0xE062 0x90FB # 0 +0xE063 0x90FC # 0 +0xE064 0x90FF # 0 +0xE065 0x9100 # 0 +0xE066 0x9101 # 0 +0xE067 0x9103 # 0 +0xE068 0x9105 # 0 +0xE069 0x9106 # 0 +0xE06A 0x9107 # 0 +0xE06B 0x9108 # 0 +0xE06C 0x9109 # 0 +0xE06D 0x910A # 0 +0xE06E 0x910B # 0 +0xE06F 0x910C # 0 +0xE070 0x910D # 0 +0xE071 0x910E # 0 +0xE072 0x910F # 0 +0xE073 0x9110 # 0 +0xE074 0x9111 # 0 +0xE075 0x9112 # 0 +0xE076 0x9113 # 0 +0xE077 0x9114 # 0 +0xE078 0x9115 # 0 +0xE079 0x9116 # 0 +0xE07A 0x9117 # 0 +0xE07B 0x9118 # 0 +0xE07C 0x911A # 0 +0xE07D 0x911B # 0 +0xE07E 0x911C # 0 +0xE080 0x911D # 0 +0xE081 0x911F # 0 +0xE082 0x9120 # 0 +0xE083 0x9121 # 0 +0xE084 0x9124 # 0 +0xE085 0x9125 # 0 +0xE086 0x9126 # 0 +0xE087 0x9127 # 0 +0xE088 0x9128 # 0 +0xE089 0x9129 # 0 +0xE08A 0x912A # 0 +0xE08B 0x912B # 0 +0xE08C 0x912C # 0 +0xE08D 0x912D # 0 +0xE08E 0x912E # 0 +0xE08F 0x9130 # 0 +0xE090 0x9132 # 0 +0xE091 0x9133 # 0 +0xE092 0x9134 # 0 +0xE093 0x9135 # 0 +0xE094 0x9136 # 0 +0xE095 0x9137 # 0 +0xE096 0x9138 # 0 +0xE097 0x913A # 0 +0xE098 0x913B # 0 +0xE099 0x913C # 0 +0xE09A 0x913D # 0 +0xE09B 0x913E # 0 +0xE09C 0x913F # 0 +0xE09D 0x9140 # 0 +0xE09E 0x9141 # 0 +0xE09F 0x9142 # 0 +0xE0A0 0x9144 # 0 +0xE0A1 0x5537 # 0 +0xE0A2 0x5556 # 0 +0xE0A3 0x5575 # 0 +0xE0A4 0x5576 # 0 +0xE0A5 0x5577 # 0 +0xE0A6 0x5533 # 0 +0xE0A7 0x5530 # 0 +0xE0A8 0x555C # 0 +0xE0A9 0x558B # 0 +0xE0AA 0x55D2 # 0 +0xE0AB 0x5583 # 0 +0xE0AC 0x55B1 # 0 +0xE0AD 0x55B9 # 0 +0xE0AE 0x5588 # 0 +0xE0AF 0x5581 # 0 +0xE0B0 0x559F # 0 +0xE0B1 0x557E # 0 +0xE0B2 0x55D6 # 0 +0xE0B3 0x5591 # 0 +0xE0B4 0x557B # 0 +0xE0B5 0x55DF # 0 +0xE0B6 0x55BD # 0 +0xE0B7 0x55BE # 0 +0xE0B8 0x5594 # 0 +0xE0B9 0x5599 # 0 +0xE0BA 0x55EA # 0 +0xE0BB 0x55F7 # 0 +0xE0BC 0x55C9 # 0 +0xE0BD 0x561F # 0 +0xE0BE 0x55D1 # 0 +0xE0BF 0x55EB # 0 +0xE0C0 0x55EC # 0 +0xE0C1 0x55D4 # 0 +0xE0C2 0x55E6 # 0 +0xE0C3 0x55DD # 0 +0xE0C4 0x55C4 # 0 +0xE0C5 0x55EF # 0 +0xE0C6 0x55E5 # 0 +0xE0C7 0x55F2 # 0 +0xE0C8 0x55F3 # 0 +0xE0C9 0x55CC # 0 +0xE0CA 0x55CD # 0 +0xE0CB 0x55E8 # 0 +0xE0CC 0x55F5 # 0 +0xE0CD 0x55E4 # 0 +0xE0CE 0x8F94 # 0 +0xE0CF 0x561E # 0 +0xE0D0 0x5608 # 0 +0xE0D1 0x560C # 0 +0xE0D2 0x5601 # 0 +0xE0D3 0x5624 # 0 +0xE0D4 0x5623 # 0 +0xE0D5 0x55FE # 0 +0xE0D6 0x5600 # 0 +0xE0D7 0x5627 # 0 +0xE0D8 0x562D # 0 +0xE0D9 0x5658 # 0 +0xE0DA 0x5639 # 0 +0xE0DB 0x5657 # 0 +0xE0DC 0x562C # 0 +0xE0DD 0x564D # 0 +0xE0DE 0x5662 # 0 +0xE0DF 0x5659 # 0 +0xE0E0 0x565C # 0 +0xE0E1 0x564C # 0 +0xE0E2 0x5654 # 0 +0xE0E3 0x5686 # 0 +0xE0E4 0x5664 # 0 +0xE0E5 0x5671 # 0 +0xE0E6 0x566B # 0 +0xE0E7 0x567B # 0 +0xE0E8 0x567C # 0 +0xE0E9 0x5685 # 0 +0xE0EA 0x5693 # 0 +0xE0EB 0x56AF # 0 +0xE0EC 0x56D4 # 0 +0xE0ED 0x56D7 # 0 +0xE0EE 0x56DD # 0 +0xE0EF 0x56E1 # 0 +0xE0F0 0x56F5 # 0 +0xE0F1 0x56EB # 0 +0xE0F2 0x56F9 # 0 +0xE0F3 0x56FF # 0 +0xE0F4 0x5704 # 0 +0xE0F5 0x570A # 0 +0xE0F6 0x5709 # 0 +0xE0F7 0x571C # 0 +0xE0F8 0x5E0F # 0 +0xE0F9 0x5E19 # 0 +0xE0FA 0x5E14 # 0 +0xE0FB 0x5E11 # 0 +0xE0FC 0x5E31 # 0 +0xE0FD 0x5E3B # 0 +0xE0FE 0x5E3C # 0 +0xE140 0x9145 # 0 +0xE141 0x9147 # 0 +0xE142 0x9148 # 0 +0xE143 0x9151 # 0 +0xE144 0x9153 # 0 +0xE145 0x9154 # 0 +0xE146 0x9155 # 0 +0xE147 0x9156 # 0 +0xE148 0x9158 # 0 +0xE149 0x9159 # 0 +0xE14A 0x915B # 0 +0xE14B 0x915C # 0 +0xE14C 0x915F # 0 +0xE14D 0x9160 # 0 +0xE14E 0x9166 # 0 +0xE14F 0x9167 # 0 +0xE150 0x9168 # 0 +0xE151 0x916B # 0 +0xE152 0x916D # 0 +0xE153 0x9173 # 0 +0xE154 0x917A # 0 +0xE155 0x917B # 0 +0xE156 0x917C # 0 +0xE157 0x9180 # 0 +0xE158 0x9181 # 0 +0xE159 0x9182 # 0 +0xE15A 0x9183 # 0 +0xE15B 0x9184 # 0 +0xE15C 0x9186 # 0 +0xE15D 0x9188 # 0 +0xE15E 0x918A # 0 +0xE15F 0x918E # 0 +0xE160 0x918F # 0 +0xE161 0x9193 # 0 +0xE162 0x9194 # 0 +0xE163 0x9195 # 0 +0xE164 0x9196 # 0 +0xE165 0x9197 # 0 +0xE166 0x9198 # 0 +0xE167 0x9199 # 0 +0xE168 0x919C # 0 +0xE169 0x919D # 0 +0xE16A 0x919E # 0 +0xE16B 0x919F # 0 +0xE16C 0x91A0 # 0 +0xE16D 0x91A1 # 0 +0xE16E 0x91A4 # 0 +0xE16F 0x91A5 # 0 +0xE170 0x91A6 # 0 +0xE171 0x91A7 # 0 +0xE172 0x91A8 # 0 +0xE173 0x91A9 # 0 +0xE174 0x91AB # 0 +0xE175 0x91AC # 0 +0xE176 0x91B0 # 0 +0xE177 0x91B1 # 0 +0xE178 0x91B2 # 0 +0xE179 0x91B3 # 0 +0xE17A 0x91B6 # 0 +0xE17B 0x91B7 # 0 +0xE17C 0x91B8 # 0 +0xE17D 0x91B9 # 0 +0xE17E 0x91BB # 0 +0xE180 0x91BC # 0 +0xE181 0x91BD # 0 +0xE182 0x91BE # 0 +0xE183 0x91BF # 0 +0xE184 0x91C0 # 0 +0xE185 0x91C1 # 0 +0xE186 0x91C2 # 0 +0xE187 0x91C3 # 0 +0xE188 0x91C4 # 0 +0xE189 0x91C5 # 0 +0xE18A 0x91C6 # 0 +0xE18B 0x91C8 # 0 +0xE18C 0x91CB # 0 +0xE18D 0x91D0 # 0 +0xE18E 0x91D2 # 0 +0xE18F 0x91D3 # 0 +0xE190 0x91D4 # 0 +0xE191 0x91D5 # 0 +0xE192 0x91D6 # 0 +0xE193 0x91D7 # 0 +0xE194 0x91D8 # 0 +0xE195 0x91D9 # 0 +0xE196 0x91DA # 0 +0xE197 0x91DB # 0 +0xE198 0x91DD # 0 +0xE199 0x91DE # 0 +0xE19A 0x91DF # 0 +0xE19B 0x91E0 # 0 +0xE19C 0x91E1 # 0 +0xE19D 0x91E2 # 0 +0xE19E 0x91E3 # 0 +0xE19F 0x91E4 # 0 +0xE1A0 0x91E5 # 0 +0xE1A1 0x5E37 # 0 +0xE1A2 0x5E44 # 0 +0xE1A3 0x5E54 # 0 +0xE1A4 0x5E5B # 0 +0xE1A5 0x5E5E # 0 +0xE1A6 0x5E61 # 0 +0xE1A7 0x5C8C # 0 +0xE1A8 0x5C7A # 0 +0xE1A9 0x5C8D # 0 +0xE1AA 0x5C90 # 0 +0xE1AB 0x5C96 # 0 +0xE1AC 0x5C88 # 0 +0xE1AD 0x5C98 # 0 +0xE1AE 0x5C99 # 0 +0xE1AF 0x5C91 # 0 +0xE1B0 0x5C9A # 0 +0xE1B1 0x5C9C # 0 +0xE1B2 0x5CB5 # 0 +0xE1B3 0x5CA2 # 0 +0xE1B4 0x5CBD # 0 +0xE1B5 0x5CAC # 0 +0xE1B6 0x5CAB # 0 +0xE1B7 0x5CB1 # 0 +0xE1B8 0x5CA3 # 0 +0xE1B9 0x5CC1 # 0 +0xE1BA 0x5CB7 # 0 +0xE1BB 0x5CC4 # 0 +0xE1BC 0x5CD2 # 0 +0xE1BD 0x5CE4 # 0 +0xE1BE 0x5CCB # 0 +0xE1BF 0x5CE5 # 0 +0xE1C0 0x5D02 # 0 +0xE1C1 0x5D03 # 0 +0xE1C2 0x5D27 # 0 +0xE1C3 0x5D26 # 0 +0xE1C4 0x5D2E # 0 +0xE1C5 0x5D24 # 0 +0xE1C6 0x5D1E # 0 +0xE1C7 0x5D06 # 0 +0xE1C8 0x5D1B # 0 +0xE1C9 0x5D58 # 0 +0xE1CA 0x5D3E # 0 +0xE1CB 0x5D34 # 0 +0xE1CC 0x5D3D # 0 +0xE1CD 0x5D6C # 0 +0xE1CE 0x5D5B # 0 +0xE1CF 0x5D6F # 0 +0xE1D0 0x5D5D # 0 +0xE1D1 0x5D6B # 0 +0xE1D2 0x5D4B # 0 +0xE1D3 0x5D4A # 0 +0xE1D4 0x5D69 # 0 +0xE1D5 0x5D74 # 0 +0xE1D6 0x5D82 # 0 +0xE1D7 0x5D99 # 0 +0xE1D8 0x5D9D # 0 +0xE1D9 0x8C73 # 0 +0xE1DA 0x5DB7 # 0 +0xE1DB 0x5DC5 # 0 +0xE1DC 0x5F73 # 0 +0xE1DD 0x5F77 # 0 +0xE1DE 0x5F82 # 0 +0xE1DF 0x5F87 # 0 +0xE1E0 0x5F89 # 0 +0xE1E1 0x5F8C # 0 +0xE1E2 0x5F95 # 0 +0xE1E3 0x5F99 # 0 +0xE1E4 0x5F9C # 0 +0xE1E5 0x5FA8 # 0 +0xE1E6 0x5FAD # 0 +0xE1E7 0x5FB5 # 0 +0xE1E8 0x5FBC # 0 +0xE1E9 0x8862 # 0 +0xE1EA 0x5F61 # 0 +0xE1EB 0x72AD # 0 +0xE1EC 0x72B0 # 0 +0xE1ED 0x72B4 # 0 +0xE1EE 0x72B7 # 0 +0xE1EF 0x72B8 # 0 +0xE1F0 0x72C3 # 0 +0xE1F1 0x72C1 # 0 +0xE1F2 0x72CE # 0 +0xE1F3 0x72CD # 0 +0xE1F4 0x72D2 # 0 +0xE1F5 0x72E8 # 0 +0xE1F6 0x72EF # 0 +0xE1F7 0x72E9 # 0 +0xE1F8 0x72F2 # 0 +0xE1F9 0x72F4 # 0 +0xE1FA 0x72F7 # 0 +0xE1FB 0x7301 # 0 +0xE1FC 0x72F3 # 0 +0xE1FD 0x7303 # 0 +0xE1FE 0x72FA # 0 +0xE240 0x91E6 # 0 +0xE241 0x91E7 # 0 +0xE242 0x91E8 # 0 +0xE243 0x91E9 # 0 +0xE244 0x91EA # 0 +0xE245 0x91EB # 0 +0xE246 0x91EC # 0 +0xE247 0x91ED # 0 +0xE248 0x91EE # 0 +0xE249 0x91EF # 0 +0xE24A 0x91F0 # 0 +0xE24B 0x91F1 # 0 +0xE24C 0x91F2 # 0 +0xE24D 0x91F3 # 0 +0xE24E 0x91F4 # 0 +0xE24F 0x91F5 # 0 +0xE250 0x91F6 # 0 +0xE251 0x91F7 # 0 +0xE252 0x91F8 # 0 +0xE253 0x91F9 # 0 +0xE254 0x91FA # 0 +0xE255 0x91FB # 0 +0xE256 0x91FC # 0 +0xE257 0x91FD # 0 +0xE258 0x91FE # 0 +0xE259 0x91FF # 0 +0xE25A 0x9200 # 0 +0xE25B 0x9201 # 0 +0xE25C 0x9202 # 0 +0xE25D 0x9203 # 0 +0xE25E 0x9204 # 0 +0xE25F 0x9205 # 0 +0xE260 0x9206 # 0 +0xE261 0x9207 # 0 +0xE262 0x9208 # 0 +0xE263 0x9209 # 0 +0xE264 0x920A # 0 +0xE265 0x920B # 0 +0xE266 0x920C # 0 +0xE267 0x920D # 0 +0xE268 0x920E # 0 +0xE269 0x920F # 0 +0xE26A 0x9210 # 0 +0xE26B 0x9211 # 0 +0xE26C 0x9212 # 0 +0xE26D 0x9213 # 0 +0xE26E 0x9214 # 0 +0xE26F 0x9215 # 0 +0xE270 0x9216 # 0 +0xE271 0x9217 # 0 +0xE272 0x9218 # 0 +0xE273 0x9219 # 0 +0xE274 0x921A # 0 +0xE275 0x921B # 0 +0xE276 0x921C # 0 +0xE277 0x921D # 0 +0xE278 0x921E # 0 +0xE279 0x921F # 0 +0xE27A 0x9220 # 0 +0xE27B 0x9221 # 0 +0xE27C 0x9222 # 0 +0xE27D 0x9223 # 0 +0xE27E 0x9224 # 0 +0xE280 0x9225 # 0 +0xE281 0x9226 # 0 +0xE282 0x9227 # 0 +0xE283 0x9228 # 0 +0xE284 0x9229 # 0 +0xE285 0x922A # 0 +0xE286 0x922B # 0 +0xE287 0x922C # 0 +0xE288 0x922D # 0 +0xE289 0x922E # 0 +0xE28A 0x922F # 0 +0xE28B 0x9230 # 0 +0xE28C 0x9231 # 0 +0xE28D 0x9232 # 0 +0xE28E 0x9233 # 0 +0xE28F 0x9234 # 0 +0xE290 0x9235 # 0 +0xE291 0x9236 # 0 +0xE292 0x9237 # 0 +0xE293 0x9238 # 0 +0xE294 0x9239 # 0 +0xE295 0x923A # 0 +0xE296 0x923B # 0 +0xE297 0x923C # 0 +0xE298 0x923D # 0 +0xE299 0x923E # 0 +0xE29A 0x923F # 0 +0xE29B 0x9240 # 0 +0xE29C 0x9241 # 0 +0xE29D 0x9242 # 0 +0xE29E 0x9243 # 0 +0xE29F 0x9244 # 0 +0xE2A0 0x9245 # 0 +0xE2A1 0x72FB # 0 +0xE2A2 0x7317 # 0 +0xE2A3 0x7313 # 0 +0xE2A4 0x7321 # 0 +0xE2A5 0x730A # 0 +0xE2A6 0x731E # 0 +0xE2A7 0x731D # 0 +0xE2A8 0x7315 # 0 +0xE2A9 0x7322 # 0 +0xE2AA 0x7339 # 0 +0xE2AB 0x7325 # 0 +0xE2AC 0x732C # 0 +0xE2AD 0x7338 # 0 +0xE2AE 0x7331 # 0 +0xE2AF 0x7350 # 0 +0xE2B0 0x734D # 0 +0xE2B1 0x7357 # 0 +0xE2B2 0x7360 # 0 +0xE2B3 0x736C # 0 +0xE2B4 0x736F # 0 +0xE2B5 0x737E # 0 +0xE2B6 0x821B # 0 +0xE2B7 0x5925 # 0 +0xE2B8 0x98E7 # 0 +0xE2B9 0x5924 # 0 +0xE2BA 0x5902 # 0 +0xE2BB 0x9963 # 0 +0xE2BC 0x9967 # 0 +0xE2BD 0x9968 # 0 +0xE2BE 0x9969 # 0 +0xE2BF 0x996A # 0 +0xE2C0 0x996B # 0 +0xE2C1 0x996C # 0 +0xE2C2 0x9974 # 0 +0xE2C3 0x9977 # 0 +0xE2C4 0x997D # 0 +0xE2C5 0x9980 # 0 +0xE2C6 0x9984 # 0 +0xE2C7 0x9987 # 0 +0xE2C8 0x998A # 0 +0xE2C9 0x998D # 0 +0xE2CA 0x9990 # 0 +0xE2CB 0x9991 # 0 +0xE2CC 0x9993 # 0 +0xE2CD 0x9994 # 0 +0xE2CE 0x9995 # 0 +0xE2CF 0x5E80 # 0 +0xE2D0 0x5E91 # 0 +0xE2D1 0x5E8B # 0 +0xE2D2 0x5E96 # 0 +0xE2D3 0x5EA5 # 0 +0xE2D4 0x5EA0 # 0 +0xE2D5 0x5EB9 # 0 +0xE2D6 0x5EB5 # 0 +0xE2D7 0x5EBE # 0 +0xE2D8 0x5EB3 # 0 +0xE2D9 0x8D53 # 0 +0xE2DA 0x5ED2 # 0 +0xE2DB 0x5ED1 # 0 +0xE2DC 0x5EDB # 0 +0xE2DD 0x5EE8 # 0 +0xE2DE 0x5EEA # 0 +0xE2DF 0x81BA # 0 +0xE2E0 0x5FC4 # 0 +0xE2E1 0x5FC9 # 0 +0xE2E2 0x5FD6 # 0 +0xE2E3 0x5FCF # 0 +0xE2E4 0x6003 # 0 +0xE2E5 0x5FEE # 0 +0xE2E6 0x6004 # 0 +0xE2E7 0x5FE1 # 0 +0xE2E8 0x5FE4 # 0 +0xE2E9 0x5FFE # 0 +0xE2EA 0x6005 # 0 +0xE2EB 0x6006 # 0 +0xE2EC 0x5FEA # 0 +0xE2ED 0x5FED # 0 +0xE2EE 0x5FF8 # 0 +0xE2EF 0x6019 # 0 +0xE2F0 0x6035 # 0 +0xE2F1 0x6026 # 0 +0xE2F2 0x601B # 0 +0xE2F3 0x600F # 0 +0xE2F4 0x600D # 0 +0xE2F5 0x6029 # 0 +0xE2F6 0x602B # 0 +0xE2F7 0x600A # 0 +0xE2F8 0x603F # 0 +0xE2F9 0x6021 # 0 +0xE2FA 0x6078 # 0 +0xE2FB 0x6079 # 0 +0xE2FC 0x607B # 0 +0xE2FD 0x607A # 0 +0xE2FE 0x6042 # 0 +0xE340 0x9246 # 0 +0xE341 0x9247 # 0 +0xE342 0x9248 # 0 +0xE343 0x9249 # 0 +0xE344 0x924A # 0 +0xE345 0x924B # 0 +0xE346 0x924C # 0 +0xE347 0x924D # 0 +0xE348 0x924E # 0 +0xE349 0x924F # 0 +0xE34A 0x9250 # 0 +0xE34B 0x9251 # 0 +0xE34C 0x9252 # 0 +0xE34D 0x9253 # 0 +0xE34E 0x9254 # 0 +0xE34F 0x9255 # 0 +0xE350 0x9256 # 0 +0xE351 0x9257 # 0 +0xE352 0x9258 # 0 +0xE353 0x9259 # 0 +0xE354 0x925A # 0 +0xE355 0x925B # 0 +0xE356 0x925C # 0 +0xE357 0x925D # 0 +0xE358 0x925E # 0 +0xE359 0x925F # 0 +0xE35A 0x9260 # 0 +0xE35B 0x9261 # 0 +0xE35C 0x9262 # 0 +0xE35D 0x9263 # 0 +0xE35E 0x9264 # 0 +0xE35F 0x9265 # 0 +0xE360 0x9266 # 0 +0xE361 0x9267 # 0 +0xE362 0x9268 # 0 +0xE363 0x9269 # 0 +0xE364 0x926A # 0 +0xE365 0x926B # 0 +0xE366 0x926C # 0 +0xE367 0x926D # 0 +0xE368 0x926E # 0 +0xE369 0x926F # 0 +0xE36A 0x9270 # 0 +0xE36B 0x9271 # 0 +0xE36C 0x9272 # 0 +0xE36D 0x9273 # 0 +0xE36E 0x9275 # 0 +0xE36F 0x9276 # 0 +0xE370 0x9277 # 0 +0xE371 0x9278 # 0 +0xE372 0x9279 # 0 +0xE373 0x927A # 0 +0xE374 0x927B # 0 +0xE375 0x927C # 0 +0xE376 0x927D # 0 +0xE377 0x927E # 0 +0xE378 0x927F # 0 +0xE379 0x9280 # 0 +0xE37A 0x9281 # 0 +0xE37B 0x9282 # 0 +0xE37C 0x9283 # 0 +0xE37D 0x9284 # 0 +0xE37E 0x9285 # 0 +0xE380 0x9286 # 0 +0xE381 0x9287 # 0 +0xE382 0x9288 # 0 +0xE383 0x9289 # 0 +0xE384 0x928A # 0 +0xE385 0x928B # 0 +0xE386 0x928C # 0 +0xE387 0x928D # 0 +0xE388 0x928F # 0 +0xE389 0x9290 # 0 +0xE38A 0x9291 # 0 +0xE38B 0x9292 # 0 +0xE38C 0x9293 # 0 +0xE38D 0x9294 # 0 +0xE38E 0x9295 # 0 +0xE38F 0x9296 # 0 +0xE390 0x9297 # 0 +0xE391 0x9298 # 0 +0xE392 0x9299 # 0 +0xE393 0x929A # 0 +0xE394 0x929B # 0 +0xE395 0x929C # 0 +0xE396 0x929D # 0 +0xE397 0x929E # 0 +0xE398 0x929F # 0 +0xE399 0x92A0 # 0 +0xE39A 0x92A1 # 0 +0xE39B 0x92A2 # 0 +0xE39C 0x92A3 # 0 +0xE39D 0x92A4 # 0 +0xE39E 0x92A5 # 0 +0xE39F 0x92A6 # 0 +0xE3A0 0x92A7 # 0 +0xE3A1 0x606A # 0 +0xE3A2 0x607D # 0 +0xE3A3 0x6096 # 0 +0xE3A4 0x609A # 0 +0xE3A5 0x60AD # 0 +0xE3A6 0x609D # 0 +0xE3A7 0x6083 # 0 +0xE3A8 0x6092 # 0 +0xE3A9 0x608C # 0 +0xE3AA 0x609B # 0 +0xE3AB 0x60EC # 0 +0xE3AC 0x60BB # 0 +0xE3AD 0x60B1 # 0 +0xE3AE 0x60DD # 0 +0xE3AF 0x60D8 # 0 +0xE3B0 0x60C6 # 0 +0xE3B1 0x60DA # 0 +0xE3B2 0x60B4 # 0 +0xE3B3 0x6120 # 0 +0xE3B4 0x6126 # 0 +0xE3B5 0x6115 # 0 +0xE3B6 0x6123 # 0 +0xE3B7 0x60F4 # 0 +0xE3B8 0x6100 # 0 +0xE3B9 0x610E # 0 +0xE3BA 0x612B # 0 +0xE3BB 0x614A # 0 +0xE3BC 0x6175 # 0 +0xE3BD 0x61AC # 0 +0xE3BE 0x6194 # 0 +0xE3BF 0x61A7 # 0 +0xE3C0 0x61B7 # 0 +0xE3C1 0x61D4 # 0 +0xE3C2 0x61F5 # 0 +0xE3C3 0x5FDD # 0 +0xE3C4 0x96B3 # 0 +0xE3C5 0x95E9 # 0 +0xE3C6 0x95EB # 0 +0xE3C7 0x95F1 # 0 +0xE3C8 0x95F3 # 0 +0xE3C9 0x95F5 # 0 +0xE3CA 0x95F6 # 0 +0xE3CB 0x95FC # 0 +0xE3CC 0x95FE # 0 +0xE3CD 0x9603 # 0 +0xE3CE 0x9604 # 0 +0xE3CF 0x9606 # 0 +0xE3D0 0x9608 # 0 +0xE3D1 0x960A # 0 +0xE3D2 0x960B # 0 +0xE3D3 0x960C # 0 +0xE3D4 0x960D # 0 +0xE3D5 0x960F # 0 +0xE3D6 0x9612 # 0 +0xE3D7 0x9615 # 0 +0xE3D8 0x9616 # 0 +0xE3D9 0x9617 # 0 +0xE3DA 0x9619 # 0 +0xE3DB 0x961A # 0 +0xE3DC 0x4E2C # 0 +0xE3DD 0x723F # 0 +0xE3DE 0x6215 # 0 +0xE3DF 0x6C35 # 0 +0xE3E0 0x6C54 # 0 +0xE3E1 0x6C5C # 0 +0xE3E2 0x6C4A # 0 +0xE3E3 0x6CA3 # 0 +0xE3E4 0x6C85 # 0 +0xE3E5 0x6C90 # 0 +0xE3E6 0x6C94 # 0 +0xE3E7 0x6C8C # 0 +0xE3E8 0x6C68 # 0 +0xE3E9 0x6C69 # 0 +0xE3EA 0x6C74 # 0 +0xE3EB 0x6C76 # 0 +0xE3EC 0x6C86 # 0 +0xE3ED 0x6CA9 # 0 +0xE3EE 0x6CD0 # 0 +0xE3EF 0x6CD4 # 0 +0xE3F0 0x6CAD # 0 +0xE3F1 0x6CF7 # 0 +0xE3F2 0x6CF8 # 0 +0xE3F3 0x6CF1 # 0 +0xE3F4 0x6CD7 # 0 +0xE3F5 0x6CB2 # 0 +0xE3F6 0x6CE0 # 0 +0xE3F7 0x6CD6 # 0 +0xE3F8 0x6CFA # 0 +0xE3F9 0x6CEB # 0 +0xE3FA 0x6CEE # 0 +0xE3FB 0x6CB1 # 0 +0xE3FC 0x6CD3 # 0 +0xE3FD 0x6CEF # 0 +0xE3FE 0x6CFE # 0 +0xE440 0x92A8 # 0 +0xE441 0x92A9 # 0 +0xE442 0x92AA # 0 +0xE443 0x92AB # 0 +0xE444 0x92AC # 0 +0xE445 0x92AD # 0 +0xE446 0x92AF # 0 +0xE447 0x92B0 # 0 +0xE448 0x92B1 # 0 +0xE449 0x92B2 # 0 +0xE44A 0x92B3 # 0 +0xE44B 0x92B4 # 0 +0xE44C 0x92B5 # 0 +0xE44D 0x92B6 # 0 +0xE44E 0x92B7 # 0 +0xE44F 0x92B8 # 0 +0xE450 0x92B9 # 0 +0xE451 0x92BA # 0 +0xE452 0x92BB # 0 +0xE453 0x92BC # 0 +0xE454 0x92BD # 0 +0xE455 0x92BE # 0 +0xE456 0x92BF # 0 +0xE457 0x92C0 # 0 +0xE458 0x92C1 # 0 +0xE459 0x92C2 # 0 +0xE45A 0x92C3 # 0 +0xE45B 0x92C4 # 0 +0xE45C 0x92C5 # 0 +0xE45D 0x92C6 # 0 +0xE45E 0x92C7 # 0 +0xE45F 0x92C9 # 0 +0xE460 0x92CA # 0 +0xE461 0x92CB # 0 +0xE462 0x92CC # 0 +0xE463 0x92CD # 0 +0xE464 0x92CE # 0 +0xE465 0x92CF # 0 +0xE466 0x92D0 # 0 +0xE467 0x92D1 # 0 +0xE468 0x92D2 # 0 +0xE469 0x92D3 # 0 +0xE46A 0x92D4 # 0 +0xE46B 0x92D5 # 0 +0xE46C 0x92D6 # 0 +0xE46D 0x92D7 # 0 +0xE46E 0x92D8 # 0 +0xE46F 0x92D9 # 0 +0xE470 0x92DA # 0 +0xE471 0x92DB # 0 +0xE472 0x92DC # 0 +0xE473 0x92DD # 0 +0xE474 0x92DE # 0 +0xE475 0x92DF # 0 +0xE476 0x92E0 # 0 +0xE477 0x92E1 # 0 +0xE478 0x92E2 # 0 +0xE479 0x92E3 # 0 +0xE47A 0x92E4 # 0 +0xE47B 0x92E5 # 0 +0xE47C 0x92E6 # 0 +0xE47D 0x92E7 # 0 +0xE47E 0x92E8 # 0 +0xE480 0x92E9 # 0 +0xE481 0x92EA # 0 +0xE482 0x92EB # 0 +0xE483 0x92EC # 0 +0xE484 0x92ED # 0 +0xE485 0x92EE # 0 +0xE486 0x92EF # 0 +0xE487 0x92F0 # 0 +0xE488 0x92F1 # 0 +0xE489 0x92F2 # 0 +0xE48A 0x92F3 # 0 +0xE48B 0x92F4 # 0 +0xE48C 0x92F5 # 0 +0xE48D 0x92F6 # 0 +0xE48E 0x92F7 # 0 +0xE48F 0x92F8 # 0 +0xE490 0x92F9 # 0 +0xE491 0x92FA # 0 +0xE492 0x92FB # 0 +0xE493 0x92FC # 0 +0xE494 0x92FD # 0 +0xE495 0x92FE # 0 +0xE496 0x92FF # 0 +0xE497 0x9300 # 0 +0xE498 0x9301 # 0 +0xE499 0x9302 # 0 +0xE49A 0x9303 # 0 +0xE49B 0x9304 # 0 +0xE49C 0x9305 # 0 +0xE49D 0x9306 # 0 +0xE49E 0x9307 # 0 +0xE49F 0x9308 # 0 +0xE4A0 0x9309 # 0 +0xE4A1 0x6D39 # 0 +0xE4A2 0x6D27 # 0 +0xE4A3 0x6D0C # 0 +0xE4A4 0x6D43 # 0 +0xE4A5 0x6D48 # 0 +0xE4A6 0x6D07 # 0 +0xE4A7 0x6D04 # 0 +0xE4A8 0x6D19 # 0 +0xE4A9 0x6D0E # 0 +0xE4AA 0x6D2B # 0 +0xE4AB 0x6D4D # 0 +0xE4AC 0x6D2E # 0 +0xE4AD 0x6D35 # 0 +0xE4AE 0x6D1A # 0 +0xE4AF 0x6D4F # 0 +0xE4B0 0x6D52 # 0 +0xE4B1 0x6D54 # 0 +0xE4B2 0x6D33 # 0 +0xE4B3 0x6D91 # 0 +0xE4B4 0x6D6F # 0 +0xE4B5 0x6D9E # 0 +0xE4B6 0x6DA0 # 0 +0xE4B7 0x6D5E # 0 +0xE4B8 0x6D93 # 0 +0xE4B9 0x6D94 # 0 +0xE4BA 0x6D5C # 0 +0xE4BB 0x6D60 # 0 +0xE4BC 0x6D7C # 0 +0xE4BD 0x6D63 # 0 +0xE4BE 0x6E1A # 0 +0xE4BF 0x6DC7 # 0 +0xE4C0 0x6DC5 # 0 +0xE4C1 0x6DDE # 0 +0xE4C2 0x6E0E # 0 +0xE4C3 0x6DBF # 0 +0xE4C4 0x6DE0 # 0 +0xE4C5 0x6E11 # 0 +0xE4C6 0x6DE6 # 0 +0xE4C7 0x6DDD # 0 +0xE4C8 0x6DD9 # 0 +0xE4C9 0x6E16 # 0 +0xE4CA 0x6DAB # 0 +0xE4CB 0x6E0C # 0 +0xE4CC 0x6DAE # 0 +0xE4CD 0x6E2B # 0 +0xE4CE 0x6E6E # 0 +0xE4CF 0x6E4E # 0 +0xE4D0 0x6E6B # 0 +0xE4D1 0x6EB2 # 0 +0xE4D2 0x6E5F # 0 +0xE4D3 0x6E86 # 0 +0xE4D4 0x6E53 # 0 +0xE4D5 0x6E54 # 0 +0xE4D6 0x6E32 # 0 +0xE4D7 0x6E25 # 0 +0xE4D8 0x6E44 # 0 +0xE4D9 0x6EDF # 0 +0xE4DA 0x6EB1 # 0 +0xE4DB 0x6E98 # 0 +0xE4DC 0x6EE0 # 0 +0xE4DD 0x6F2D # 0 +0xE4DE 0x6EE2 # 0 +0xE4DF 0x6EA5 # 0 +0xE4E0 0x6EA7 # 0 +0xE4E1 0x6EBD # 0 +0xE4E2 0x6EBB # 0 +0xE4E3 0x6EB7 # 0 +0xE4E4 0x6ED7 # 0 +0xE4E5 0x6EB4 # 0 +0xE4E6 0x6ECF # 0 +0xE4E7 0x6E8F # 0 +0xE4E8 0x6EC2 # 0 +0xE4E9 0x6E9F # 0 +0xE4EA 0x6F62 # 0 +0xE4EB 0x6F46 # 0 +0xE4EC 0x6F47 # 0 +0xE4ED 0x6F24 # 0 +0xE4EE 0x6F15 # 0 +0xE4EF 0x6EF9 # 0 +0xE4F0 0x6F2F # 0 +0xE4F1 0x6F36 # 0 +0xE4F2 0x6F4B # 0 +0xE4F3 0x6F74 # 0 +0xE4F4 0x6F2A # 0 +0xE4F5 0x6F09 # 0 +0xE4F6 0x6F29 # 0 +0xE4F7 0x6F89 # 0 +0xE4F8 0x6F8D # 0 +0xE4F9 0x6F8C # 0 +0xE4FA 0x6F78 # 0 +0xE4FB 0x6F72 # 0 +0xE4FC 0x6F7C # 0 +0xE4FD 0x6F7A # 0 +0xE4FE 0x6FD1 # 0 +0xE540 0x930A # 0 +0xE541 0x930B # 0 +0xE542 0x930C # 0 +0xE543 0x930D # 0 +0xE544 0x930E # 0 +0xE545 0x930F # 0 +0xE546 0x9310 # 0 +0xE547 0x9311 # 0 +0xE548 0x9312 # 0 +0xE549 0x9313 # 0 +0xE54A 0x9314 # 0 +0xE54B 0x9315 # 0 +0xE54C 0x9316 # 0 +0xE54D 0x9317 # 0 +0xE54E 0x9318 # 0 +0xE54F 0x9319 # 0 +0xE550 0x931A # 0 +0xE551 0x931B # 0 +0xE552 0x931C # 0 +0xE553 0x931D # 0 +0xE554 0x931E # 0 +0xE555 0x931F # 0 +0xE556 0x9320 # 0 +0xE557 0x9321 # 0 +0xE558 0x9322 # 0 +0xE559 0x9323 # 0 +0xE55A 0x9324 # 0 +0xE55B 0x9325 # 0 +0xE55C 0x9326 # 0 +0xE55D 0x9327 # 0 +0xE55E 0x9328 # 0 +0xE55F 0x9329 # 0 +0xE560 0x932A # 0 +0xE561 0x932B # 0 +0xE562 0x932C # 0 +0xE563 0x932D # 0 +0xE564 0x932E # 0 +0xE565 0x932F # 0 +0xE566 0x9330 # 0 +0xE567 0x9331 # 0 +0xE568 0x9332 # 0 +0xE569 0x9333 # 0 +0xE56A 0x9334 # 0 +0xE56B 0x9335 # 0 +0xE56C 0x9336 # 0 +0xE56D 0x9337 # 0 +0xE56E 0x9338 # 0 +0xE56F 0x9339 # 0 +0xE570 0x933A # 0 +0xE571 0x933B # 0 +0xE572 0x933C # 0 +0xE573 0x933D # 0 +0xE574 0x933F # 0 +0xE575 0x9340 # 0 +0xE576 0x9341 # 0 +0xE577 0x9342 # 0 +0xE578 0x9343 # 0 +0xE579 0x9344 # 0 +0xE57A 0x9345 # 0 +0xE57B 0x9346 # 0 +0xE57C 0x9347 # 0 +0xE57D 0x9348 # 0 +0xE57E 0x9349 # 0 +0xE580 0x934A # 0 +0xE581 0x934B # 0 +0xE582 0x934C # 0 +0xE583 0x934D # 0 +0xE584 0x934E # 0 +0xE585 0x934F # 0 +0xE586 0x9350 # 0 +0xE587 0x9351 # 0 +0xE588 0x9352 # 0 +0xE589 0x9353 # 0 +0xE58A 0x9354 # 0 +0xE58B 0x9355 # 0 +0xE58C 0x9356 # 0 +0xE58D 0x9357 # 0 +0xE58E 0x9358 # 0 +0xE58F 0x9359 # 0 +0xE590 0x935A # 0 +0xE591 0x935B # 0 +0xE592 0x935C # 0 +0xE593 0x935D # 0 +0xE594 0x935E # 0 +0xE595 0x935F # 0 +0xE596 0x9360 # 0 +0xE597 0x9361 # 0 +0xE598 0x9362 # 0 +0xE599 0x9363 # 0 +0xE59A 0x9364 # 0 +0xE59B 0x9365 # 0 +0xE59C 0x9366 # 0 +0xE59D 0x9367 # 0 +0xE59E 0x9368 # 0 +0xE59F 0x9369 # 0 +0xE5A0 0x936B # 0 +0xE5A1 0x6FC9 # 0 +0xE5A2 0x6FA7 # 0 +0xE5A3 0x6FB9 # 0 +0xE5A4 0x6FB6 # 0 +0xE5A5 0x6FC2 # 0 +0xE5A6 0x6FE1 # 0 +0xE5A7 0x6FEE # 0 +0xE5A8 0x6FDE # 0 +0xE5A9 0x6FE0 # 0 +0xE5AA 0x6FEF # 0 +0xE5AB 0x701A # 0 +0xE5AC 0x7023 # 0 +0xE5AD 0x701B # 0 +0xE5AE 0x7039 # 0 +0xE5AF 0x7035 # 0 +0xE5B0 0x704F # 0 +0xE5B1 0x705E # 0 +0xE5B2 0x5B80 # 0 +0xE5B3 0x5B84 # 0 +0xE5B4 0x5B95 # 0 +0xE5B5 0x5B93 # 0 +0xE5B6 0x5BA5 # 0 +0xE5B7 0x5BB8 # 0 +0xE5B8 0x752F # 0 +0xE5B9 0x9A9E # 0 +0xE5BA 0x6434 # 0 +0xE5BB 0x5BE4 # 0 +0xE5BC 0x5BEE # 0 +0xE5BD 0x8930 # 0 +0xE5BE 0x5BF0 # 0 +0xE5BF 0x8E47 # 0 +0xE5C0 0x8B07 # 0 +0xE5C1 0x8FB6 # 0 +0xE5C2 0x8FD3 # 0 +0xE5C3 0x8FD5 # 0 +0xE5C4 0x8FE5 # 0 +0xE5C5 0x8FEE # 0 +0xE5C6 0x8FE4 # 0 +0xE5C7 0x8FE9 # 0 +0xE5C8 0x8FE6 # 0 +0xE5C9 0x8FF3 # 0 +0xE5CA 0x8FE8 # 0 +0xE5CB 0x9005 # 0 +0xE5CC 0x9004 # 0 +0xE5CD 0x900B # 0 +0xE5CE 0x9026 # 0 +0xE5CF 0x9011 # 0 +0xE5D0 0x900D # 0 +0xE5D1 0x9016 # 0 +0xE5D2 0x9021 # 0 +0xE5D3 0x9035 # 0 +0xE5D4 0x9036 # 0 +0xE5D5 0x902D # 0 +0xE5D6 0x902F # 0 +0xE5D7 0x9044 # 0 +0xE5D8 0x9051 # 0 +0xE5D9 0x9052 # 0 +0xE5DA 0x9050 # 0 +0xE5DB 0x9068 # 0 +0xE5DC 0x9058 # 0 +0xE5DD 0x9062 # 0 +0xE5DE 0x905B # 0 +0xE5DF 0x66B9 # 0 +0xE5E0 0x9074 # 0 +0xE5E1 0x907D # 0 +0xE5E2 0x9082 # 0 +0xE5E3 0x9088 # 0 +0xE5E4 0x9083 # 0 +0xE5E5 0x908B # 0 +0xE5E6 0x5F50 # 0 +0xE5E7 0x5F57 # 0 +0xE5E8 0x5F56 # 0 +0xE5E9 0x5F58 # 0 +0xE5EA 0x5C3B # 0 +0xE5EB 0x54AB # 0 +0xE5EC 0x5C50 # 0 +0xE5ED 0x5C59 # 0 +0xE5EE 0x5B71 # 0 +0xE5EF 0x5C63 # 0 +0xE5F0 0x5C66 # 0 +0xE5F1 0x7FBC # 0 +0xE5F2 0x5F2A # 0 +0xE5F3 0x5F29 # 0 +0xE5F4 0x5F2D # 0 +0xE5F5 0x8274 # 0 +0xE5F6 0x5F3C # 0 +0xE5F7 0x9B3B # 0 +0xE5F8 0x5C6E # 0 +0xE5F9 0x5981 # 0 +0xE5FA 0x5983 # 0 +0xE5FB 0x598D # 0 +0xE5FC 0x59A9 # 0 +0xE5FD 0x59AA # 0 +0xE5FE 0x59A3 # 0 +0xE640 0x936C # 0 +0xE641 0x936D # 0 +0xE642 0x936E # 0 +0xE643 0x936F # 0 +0xE644 0x9370 # 0 +0xE645 0x9371 # 0 +0xE646 0x9372 # 0 +0xE647 0x9373 # 0 +0xE648 0x9374 # 0 +0xE649 0x9375 # 0 +0xE64A 0x9376 # 0 +0xE64B 0x9377 # 0 +0xE64C 0x9378 # 0 +0xE64D 0x9379 # 0 +0xE64E 0x937A # 0 +0xE64F 0x937B # 0 +0xE650 0x937C # 0 +0xE651 0x937D # 0 +0xE652 0x937E # 0 +0xE653 0x937F # 0 +0xE654 0x9380 # 0 +0xE655 0x9381 # 0 +0xE656 0x9382 # 0 +0xE657 0x9383 # 0 +0xE658 0x9384 # 0 +0xE659 0x9385 # 0 +0xE65A 0x9386 # 0 +0xE65B 0x9387 # 0 +0xE65C 0x9388 # 0 +0xE65D 0x9389 # 0 +0xE65E 0x938A # 0 +0xE65F 0x938B # 0 +0xE660 0x938C # 0 +0xE661 0x938D # 0 +0xE662 0x938E # 0 +0xE663 0x9390 # 0 +0xE664 0x9391 # 0 +0xE665 0x9392 # 0 +0xE666 0x9393 # 0 +0xE667 0x9394 # 0 +0xE668 0x9395 # 0 +0xE669 0x9396 # 0 +0xE66A 0x9397 # 0 +0xE66B 0x9398 # 0 +0xE66C 0x9399 # 0 +0xE66D 0x939A # 0 +0xE66E 0x939B # 0 +0xE66F 0x939C # 0 +0xE670 0x939D # 0 +0xE671 0x939E # 0 +0xE672 0x939F # 0 +0xE673 0x93A0 # 0 +0xE674 0x93A1 # 0 +0xE675 0x93A2 # 0 +0xE676 0x93A3 # 0 +0xE677 0x93A4 # 0 +0xE678 0x93A5 # 0 +0xE679 0x93A6 # 0 +0xE67A 0x93A7 # 0 +0xE67B 0x93A8 # 0 +0xE67C 0x93A9 # 0 +0xE67D 0x93AA # 0 +0xE67E 0x93AB # 0 +0xE680 0x93AC # 0 +0xE681 0x93AD # 0 +0xE682 0x93AE # 0 +0xE683 0x93AF # 0 +0xE684 0x93B0 # 0 +0xE685 0x93B1 # 0 +0xE686 0x93B2 # 0 +0xE687 0x93B3 # 0 +0xE688 0x93B4 # 0 +0xE689 0x93B5 # 0 +0xE68A 0x93B6 # 0 +0xE68B 0x93B7 # 0 +0xE68C 0x93B8 # 0 +0xE68D 0x93B9 # 0 +0xE68E 0x93BA # 0 +0xE68F 0x93BB # 0 +0xE690 0x93BC # 0 +0xE691 0x93BD # 0 +0xE692 0x93BE # 0 +0xE693 0x93BF # 0 +0xE694 0x93C0 # 0 +0xE695 0x93C1 # 0 +0xE696 0x93C2 # 0 +0xE697 0x93C3 # 0 +0xE698 0x93C4 # 0 +0xE699 0x93C5 # 0 +0xE69A 0x93C6 # 0 +0xE69B 0x93C7 # 0 +0xE69C 0x93C8 # 0 +0xE69D 0x93C9 # 0 +0xE69E 0x93CB # 0 +0xE69F 0x93CC # 0 +0xE6A0 0x93CD # 0 +0xE6A1 0x5997 # 0 +0xE6A2 0x59CA # 0 +0xE6A3 0x59AB # 0 +0xE6A4 0x599E # 0 +0xE6A5 0x59A4 # 0 +0xE6A6 0x59D2 # 0 +0xE6A7 0x59B2 # 0 +0xE6A8 0x59AF # 0 +0xE6A9 0x59D7 # 0 +0xE6AA 0x59BE # 0 +0xE6AB 0x5A05 # 0 +0xE6AC 0x5A06 # 0 +0xE6AD 0x59DD # 0 +0xE6AE 0x5A08 # 0 +0xE6AF 0x59E3 # 0 +0xE6B0 0x59D8 # 0 +0xE6B1 0x59F9 # 0 +0xE6B2 0x5A0C # 0 +0xE6B3 0x5A09 # 0 +0xE6B4 0x5A32 # 0 +0xE6B5 0x5A34 # 0 +0xE6B6 0x5A11 # 0 +0xE6B7 0x5A23 # 0 +0xE6B8 0x5A13 # 0 +0xE6B9 0x5A40 # 0 +0xE6BA 0x5A67 # 0 +0xE6BB 0x5A4A # 0 +0xE6BC 0x5A55 # 0 +0xE6BD 0x5A3C # 0 +0xE6BE 0x5A62 # 0 +0xE6BF 0x5A75 # 0 +0xE6C0 0x80EC # 0 +0xE6C1 0x5AAA # 0 +0xE6C2 0x5A9B # 0 +0xE6C3 0x5A77 # 0 +0xE6C4 0x5A7A # 0 +0xE6C5 0x5ABE # 0 +0xE6C6 0x5AEB # 0 +0xE6C7 0x5AB2 # 0 +0xE6C8 0x5AD2 # 0 +0xE6C9 0x5AD4 # 0 +0xE6CA 0x5AB8 # 0 +0xE6CB 0x5AE0 # 0 +0xE6CC 0x5AE3 # 0 +0xE6CD 0x5AF1 # 0 +0xE6CE 0x5AD6 # 0 +0xE6CF 0x5AE6 # 0 +0xE6D0 0x5AD8 # 0 +0xE6D1 0x5ADC # 0 +0xE6D2 0x5B09 # 0 +0xE6D3 0x5B17 # 0 +0xE6D4 0x5B16 # 0 +0xE6D5 0x5B32 # 0 +0xE6D6 0x5B37 # 0 +0xE6D7 0x5B40 # 0 +0xE6D8 0x5C15 # 0 +0xE6D9 0x5C1C # 0 +0xE6DA 0x5B5A # 0 +0xE6DB 0x5B65 # 0 +0xE6DC 0x5B73 # 0 +0xE6DD 0x5B51 # 0 +0xE6DE 0x5B53 # 0 +0xE6DF 0x5B62 # 0 +0xE6E0 0x9A75 # 0 +0xE6E1 0x9A77 # 0 +0xE6E2 0x9A78 # 0 +0xE6E3 0x9A7A # 0 +0xE6E4 0x9A7F # 0 +0xE6E5 0x9A7D # 0 +0xE6E6 0x9A80 # 0 +0xE6E7 0x9A81 # 0 +0xE6E8 0x9A85 # 0 +0xE6E9 0x9A88 # 0 +0xE6EA 0x9A8A # 0 +0xE6EB 0x9A90 # 0 +0xE6EC 0x9A92 # 0 +0xE6ED 0x9A93 # 0 +0xE6EE 0x9A96 # 0 +0xE6EF 0x9A98 # 0 +0xE6F0 0x9A9B # 0 +0xE6F1 0x9A9C # 0 +0xE6F2 0x9A9D # 0 +0xE6F3 0x9A9F # 0 +0xE6F4 0x9AA0 # 0 +0xE6F5 0x9AA2 # 0 +0xE6F6 0x9AA3 # 0 +0xE6F7 0x9AA5 # 0 +0xE6F8 0x9AA7 # 0 +0xE6F9 0x7E9F # 0 +0xE6FA 0x7EA1 # 0 +0xE6FB 0x7EA3 # 0 +0xE6FC 0x7EA5 # 0 +0xE6FD 0x7EA8 # 0 +0xE6FE 0x7EA9 # 0 +0xE740 0x93CE # 0 +0xE741 0x93CF # 0 +0xE742 0x93D0 # 0 +0xE743 0x93D1 # 0 +0xE744 0x93D2 # 0 +0xE745 0x93D3 # 0 +0xE746 0x93D4 # 0 +0xE747 0x93D5 # 0 +0xE748 0x93D7 # 0 +0xE749 0x93D8 # 0 +0xE74A 0x93D9 # 0 +0xE74B 0x93DA # 0 +0xE74C 0x93DB # 0 +0xE74D 0x93DC # 0 +0xE74E 0x93DD # 0 +0xE74F 0x93DE # 0 +0xE750 0x93DF # 0 +0xE751 0x93E0 # 0 +0xE752 0x93E1 # 0 +0xE753 0x93E2 # 0 +0xE754 0x93E3 # 0 +0xE755 0x93E4 # 0 +0xE756 0x93E5 # 0 +0xE757 0x93E6 # 0 +0xE758 0x93E7 # 0 +0xE759 0x93E8 # 0 +0xE75A 0x93E9 # 0 +0xE75B 0x93EA # 0 +0xE75C 0x93EB # 0 +0xE75D 0x93EC # 0 +0xE75E 0x93ED # 0 +0xE75F 0x93EE # 0 +0xE760 0x93EF # 0 +0xE761 0x93F0 # 0 +0xE762 0x93F1 # 0 +0xE763 0x93F2 # 0 +0xE764 0x93F3 # 0 +0xE765 0x93F4 # 0 +0xE766 0x93F5 # 0 +0xE767 0x93F6 # 0 +0xE768 0x93F7 # 0 +0xE769 0x93F8 # 0 +0xE76A 0x93F9 # 0 +0xE76B 0x93FA # 0 +0xE76C 0x93FB # 0 +0xE76D 0x93FC # 0 +0xE76E 0x93FD # 0 +0xE76F 0x93FE # 0 +0xE770 0x93FF # 0 +0xE771 0x9400 # 0 +0xE772 0x9401 # 0 +0xE773 0x9402 # 0 +0xE774 0x9403 # 0 +0xE775 0x9404 # 0 +0xE776 0x9405 # 0 +0xE777 0x9406 # 0 +0xE778 0x9407 # 0 +0xE779 0x9408 # 0 +0xE77A 0x9409 # 0 +0xE77B 0x940A # 0 +0xE77C 0x940B # 0 +0xE77D 0x940C # 0 +0xE77E 0x940D # 0 +0xE780 0x940E # 0 +0xE781 0x940F # 0 +0xE782 0x9410 # 0 +0xE783 0x9411 # 0 +0xE784 0x9412 # 0 +0xE785 0x9413 # 0 +0xE786 0x9414 # 0 +0xE787 0x9415 # 0 +0xE788 0x9416 # 0 +0xE789 0x9417 # 0 +0xE78A 0x9418 # 0 +0xE78B 0x9419 # 0 +0xE78C 0x941A # 0 +0xE78D 0x941B # 0 +0xE78E 0x941C # 0 +0xE78F 0x941D # 0 +0xE790 0x941E # 0 +0xE791 0x941F # 0 +0xE792 0x9420 # 0 +0xE793 0x9421 # 0 +0xE794 0x9422 # 0 +0xE795 0x9423 # 0 +0xE796 0x9424 # 0 +0xE797 0x9425 # 0 +0xE798 0x9426 # 0 +0xE799 0x9427 # 0 +0xE79A 0x9428 # 0 +0xE79B 0x9429 # 0 +0xE79C 0x942A # 0 +0xE79D 0x942B # 0 +0xE79E 0x942C # 0 +0xE79F 0x942D # 0 +0xE7A0 0x942E # 0 +0xE7A1 0x7EAD # 0 +0xE7A2 0x7EB0 # 0 +0xE7A3 0x7EBE # 0 +0xE7A4 0x7EC0 # 0 +0xE7A5 0x7EC1 # 0 +0xE7A6 0x7EC2 # 0 +0xE7A7 0x7EC9 # 0 +0xE7A8 0x7ECB # 0 +0xE7A9 0x7ECC # 0 +0xE7AA 0x7ED0 # 0 +0xE7AB 0x7ED4 # 0 +0xE7AC 0x7ED7 # 0 +0xE7AD 0x7EDB # 0 +0xE7AE 0x7EE0 # 0 +0xE7AF 0x7EE1 # 0 +0xE7B0 0x7EE8 # 0 +0xE7B1 0x7EEB # 0 +0xE7B2 0x7EEE # 0 +0xE7B3 0x7EEF # 0 +0xE7B4 0x7EF1 # 0 +0xE7B5 0x7EF2 # 0 +0xE7B6 0x7F0D # 0 +0xE7B7 0x7EF6 # 0 +0xE7B8 0x7EFA # 0 +0xE7B9 0x7EFB # 0 +0xE7BA 0x7EFE # 0 +0xE7BB 0x7F01 # 0 +0xE7BC 0x7F02 # 0 +0xE7BD 0x7F03 # 0 +0xE7BE 0x7F07 # 0 +0xE7BF 0x7F08 # 0 +0xE7C0 0x7F0B # 0 +0xE7C1 0x7F0C # 0 +0xE7C2 0x7F0F # 0 +0xE7C3 0x7F11 # 0 +0xE7C4 0x7F12 # 0 +0xE7C5 0x7F17 # 0 +0xE7C6 0x7F19 # 0 +0xE7C7 0x7F1C # 0 +0xE7C8 0x7F1B # 0 +0xE7C9 0x7F1F # 0 +0xE7CA 0x7F21 # 0 +0xE7CB 0x7F22 # 0 +0xE7CC 0x7F23 # 0 +0xE7CD 0x7F24 # 0 +0xE7CE 0x7F25 # 0 +0xE7CF 0x7F26 # 0 +0xE7D0 0x7F27 # 0 +0xE7D1 0x7F2A # 0 +0xE7D2 0x7F2B # 0 +0xE7D3 0x7F2C # 0 +0xE7D4 0x7F2D # 0 +0xE7D5 0x7F2F # 0 +0xE7D6 0x7F30 # 0 +0xE7D7 0x7F31 # 0 +0xE7D8 0x7F32 # 0 +0xE7D9 0x7F33 # 0 +0xE7DA 0x7F35 # 0 +0xE7DB 0x5E7A # 0 +0xE7DC 0x757F # 0 +0xE7DD 0x5DDB # 0 +0xE7DE 0x753E # 0 +0xE7DF 0x9095 # 0 +0xE7E0 0x738E # 0 +0xE7E1 0x7391 # 0 +0xE7E2 0x73AE # 0 +0xE7E3 0x73A2 # 0 +0xE7E4 0x739F # 0 +0xE7E5 0x73CF # 0 +0xE7E6 0x73C2 # 0 +0xE7E7 0x73D1 # 0 +0xE7E8 0x73B7 # 0 +0xE7E9 0x73B3 # 0 +0xE7EA 0x73C0 # 0 +0xE7EB 0x73C9 # 0 +0xE7EC 0x73C8 # 0 +0xE7ED 0x73E5 # 0 +0xE7EE 0x73D9 # 0 +0xE7EF 0x987C # 0 +0xE7F0 0x740A # 0 +0xE7F1 0x73E9 # 0 +0xE7F2 0x73E7 # 0 +0xE7F3 0x73DE # 0 +0xE7F4 0x73BA # 0 +0xE7F5 0x73F2 # 0 +0xE7F6 0x740F # 0 +0xE7F7 0x742A # 0 +0xE7F8 0x745B # 0 +0xE7F9 0x7426 # 0 +0xE7FA 0x7425 # 0 +0xE7FB 0x7428 # 0 +0xE7FC 0x7430 # 0 +0xE7FD 0x742E # 0 +0xE7FE 0x742C # 0 +0xE840 0x942F # 0 +0xE841 0x9430 # 0 +0xE842 0x9431 # 0 +0xE843 0x9432 # 0 +0xE844 0x9433 # 0 +0xE845 0x9434 # 0 +0xE846 0x9435 # 0 +0xE847 0x9436 # 0 +0xE848 0x9437 # 0 +0xE849 0x9438 # 0 +0xE84A 0x9439 # 0 +0xE84B 0x943A # 0 +0xE84C 0x943B # 0 +0xE84D 0x943C # 0 +0xE84E 0x943D # 0 +0xE84F 0x943F # 0 +0xE850 0x9440 # 0 +0xE851 0x9441 # 0 +0xE852 0x9442 # 0 +0xE853 0x9443 # 0 +0xE854 0x9444 # 0 +0xE855 0x9445 # 0 +0xE856 0x9446 # 0 +0xE857 0x9447 # 0 +0xE858 0x9448 # 0 +0xE859 0x9449 # 0 +0xE85A 0x944A # 0 +0xE85B 0x944B # 0 +0xE85C 0x944C # 0 +0xE85D 0x944D # 0 +0xE85E 0x944E # 0 +0xE85F 0x944F # 0 +0xE860 0x9450 # 0 +0xE861 0x9451 # 0 +0xE862 0x9452 # 0 +0xE863 0x9453 # 0 +0xE864 0x9454 # 0 +0xE865 0x9455 # 0 +0xE866 0x9456 # 0 +0xE867 0x9457 # 0 +0xE868 0x9458 # 0 +0xE869 0x9459 # 0 +0xE86A 0x945A # 0 +0xE86B 0x945B # 0 +0xE86C 0x945C # 0 +0xE86D 0x945D # 0 +0xE86E 0x945E # 0 +0xE86F 0x945F # 0 +0xE870 0x9460 # 0 +0xE871 0x9461 # 0 +0xE872 0x9462 # 0 +0xE873 0x9463 # 0 +0xE874 0x9464 # 0 +0xE875 0x9465 # 0 +0xE876 0x9466 # 0 +0xE877 0x9467 # 0 +0xE878 0x9468 # 0 +0xE879 0x9469 # 0 +0xE87A 0x946A # 0 +0xE87B 0x946C # 0 +0xE87C 0x946D # 0 +0xE87D 0x946E # 0 +0xE87E 0x946F # 0 +0xE880 0x9470 # 0 +0xE881 0x9471 # 0 +0xE882 0x9472 # 0 +0xE883 0x9473 # 0 +0xE884 0x9474 # 0 +0xE885 0x9475 # 0 +0xE886 0x9476 # 0 +0xE887 0x9477 # 0 +0xE888 0x9478 # 0 +0xE889 0x9479 # 0 +0xE88A 0x947A # 0 +0xE88B 0x947B # 0 +0xE88C 0x947C # 0 +0xE88D 0x947D # 0 +0xE88E 0x947E # 0 +0xE88F 0x947F # 0 +0xE890 0x9480 # 0 +0xE891 0x9481 # 0 +0xE892 0x9482 # 0 +0xE893 0x9483 # 0 +0xE894 0x9484 # 0 +0xE895 0x9491 # 0 +0xE896 0x9496 # 0 +0xE897 0x9498 # 0 +0xE898 0x94C7 # 0 +0xE899 0x94CF # 0 +0xE89A 0x94D3 # 0 +0xE89B 0x94D4 # 0 +0xE89C 0x94DA # 0 +0xE89D 0x94E6 # 0 +0xE89E 0x94FB # 0 +0xE89F 0x951C # 0 +0xE8A0 0x9520 # 0 +0xE8A1 0x741B # 0 +0xE8A2 0x741A # 0 +0xE8A3 0x7441 # 0 +0xE8A4 0x745C # 0 +0xE8A5 0x7457 # 0 +0xE8A6 0x7455 # 0 +0xE8A7 0x7459 # 0 +0xE8A8 0x7477 # 0 +0xE8A9 0x746D # 0 +0xE8AA 0x747E # 0 +0xE8AB 0x749C # 0 +0xE8AC 0x748E # 0 +0xE8AD 0x7480 # 0 +0xE8AE 0x7481 # 0 +0xE8AF 0x7487 # 0 +0xE8B0 0x748B # 0 +0xE8B1 0x749E # 0 +0xE8B2 0x74A8 # 0 +0xE8B3 0x74A9 # 0 +0xE8B4 0x7490 # 0 +0xE8B5 0x74A7 # 0 +0xE8B6 0x74D2 # 0 +0xE8B7 0x74BA # 0 +0xE8B8 0x97EA # 0 +0xE8B9 0x97EB # 0 +0xE8BA 0x97EC # 0 +0xE8BB 0x674C # 0 +0xE8BC 0x6753 # 0 +0xE8BD 0x675E # 0 +0xE8BE 0x6748 # 0 +0xE8BF 0x6769 # 0 +0xE8C0 0x67A5 # 0 +0xE8C1 0x6787 # 0 +0xE8C2 0x676A # 0 +0xE8C3 0x6773 # 0 +0xE8C4 0x6798 # 0 +0xE8C5 0x67A7 # 0 +0xE8C6 0x6775 # 0 +0xE8C7 0x67A8 # 0 +0xE8C8 0x679E # 0 +0xE8C9 0x67AD # 0 +0xE8CA 0x678B # 0 +0xE8CB 0x6777 # 0 +0xE8CC 0x677C # 0 +0xE8CD 0x67F0 # 0 +0xE8CE 0x6809 # 0 +0xE8CF 0x67D8 # 0 +0xE8D0 0x680A # 0 +0xE8D1 0x67E9 # 0 +0xE8D2 0x67B0 # 0 +0xE8D3 0x680C # 0 +0xE8D4 0x67D9 # 0 +0xE8D5 0x67B5 # 0 +0xE8D6 0x67DA # 0 +0xE8D7 0x67B3 # 0 +0xE8D8 0x67DD # 0 +0xE8D9 0x6800 # 0 +0xE8DA 0x67C3 # 0 +0xE8DB 0x67B8 # 0 +0xE8DC 0x67E2 # 0 +0xE8DD 0x680E # 0 +0xE8DE 0x67C1 # 0 +0xE8DF 0x67FD # 0 +0xE8E0 0x6832 # 0 +0xE8E1 0x6833 # 0 +0xE8E2 0x6860 # 0 +0xE8E3 0x6861 # 0 +0xE8E4 0x684E # 0 +0xE8E5 0x6862 # 0 +0xE8E6 0x6844 # 0 +0xE8E7 0x6864 # 0 +0xE8E8 0x6883 # 0 +0xE8E9 0x681D # 0 +0xE8EA 0x6855 # 0 +0xE8EB 0x6866 # 0 +0xE8EC 0x6841 # 0 +0xE8ED 0x6867 # 0 +0xE8EE 0x6840 # 0 +0xE8EF 0x683E # 0 +0xE8F0 0x684A # 0 +0xE8F1 0x6849 # 0 +0xE8F2 0x6829 # 0 +0xE8F3 0x68B5 # 0 +0xE8F4 0x688F # 0 +0xE8F5 0x6874 # 0 +0xE8F6 0x6877 # 0 +0xE8F7 0x6893 # 0 +0xE8F8 0x686B # 0 +0xE8F9 0x68C2 # 0 +0xE8FA 0x696E # 0 +0xE8FB 0x68FC # 0 +0xE8FC 0x691F # 0 +0xE8FD 0x6920 # 0 +0xE8FE 0x68F9 # 0 +0xE940 0x9527 # 0 +0xE941 0x9533 # 0 +0xE942 0x953D # 0 +0xE943 0x9543 # 0 +0xE944 0x9548 # 0 +0xE945 0x954B # 0 +0xE946 0x9555 # 0 +0xE947 0x955A # 0 +0xE948 0x9560 # 0 +0xE949 0x956E # 0 +0xE94A 0x9574 # 0 +0xE94B 0x9575 # 0 +0xE94C 0x9577 # 0 +0xE94D 0x9578 # 0 +0xE94E 0x9579 # 0 +0xE94F 0x957A # 0 +0xE950 0x957B # 0 +0xE951 0x957C # 0 +0xE952 0x957D # 0 +0xE953 0x957E # 0 +0xE954 0x9580 # 0 +0xE955 0x9581 # 0 +0xE956 0x9582 # 0 +0xE957 0x9583 # 0 +0xE958 0x9584 # 0 +0xE959 0x9585 # 0 +0xE95A 0x9586 # 0 +0xE95B 0x9587 # 0 +0xE95C 0x9588 # 0 +0xE95D 0x9589 # 0 +0xE95E 0x958A # 0 +0xE95F 0x958B # 0 +0xE960 0x958C # 0 +0xE961 0x958D # 0 +0xE962 0x958E # 0 +0xE963 0x958F # 0 +0xE964 0x9590 # 0 +0xE965 0x9591 # 0 +0xE966 0x9592 # 0 +0xE967 0x9593 # 0 +0xE968 0x9594 # 0 +0xE969 0x9595 # 0 +0xE96A 0x9596 # 0 +0xE96B 0x9597 # 0 +0xE96C 0x9598 # 0 +0xE96D 0x9599 # 0 +0xE96E 0x959A # 0 +0xE96F 0x959B # 0 +0xE970 0x959C # 0 +0xE971 0x959D # 0 +0xE972 0x959E # 0 +0xE973 0x959F # 0 +0xE974 0x95A0 # 0 +0xE975 0x95A1 # 0 +0xE976 0x95A2 # 0 +0xE977 0x95A3 # 0 +0xE978 0x95A4 # 0 +0xE979 0x95A5 # 0 +0xE97A 0x95A6 # 0 +0xE97B 0x95A7 # 0 +0xE97C 0x95A8 # 0 +0xE97D 0x95A9 # 0 +0xE97E 0x95AA # 0 +0xE980 0x95AB # 0 +0xE981 0x95AC # 0 +0xE982 0x95AD # 0 +0xE983 0x95AE # 0 +0xE984 0x95AF # 0 +0xE985 0x95B0 # 0 +0xE986 0x95B1 # 0 +0xE987 0x95B2 # 0 +0xE988 0x95B3 # 0 +0xE989 0x95B4 # 0 +0xE98A 0x95B5 # 0 +0xE98B 0x95B6 # 0 +0xE98C 0x95B7 # 0 +0xE98D 0x95B8 # 0 +0xE98E 0x95B9 # 0 +0xE98F 0x95BA # 0 +0xE990 0x95BB # 0 +0xE991 0x95BC # 0 +0xE992 0x95BD # 0 +0xE993 0x95BE # 0 +0xE994 0x95BF # 0 +0xE995 0x95C0 # 0 +0xE996 0x95C1 # 0 +0xE997 0x95C2 # 0 +0xE998 0x95C3 # 0 +0xE999 0x95C4 # 0 +0xE99A 0x95C5 # 0 +0xE99B 0x95C6 # 0 +0xE99C 0x95C7 # 0 +0xE99D 0x95C8 # 0 +0xE99E 0x95C9 # 0 +0xE99F 0x95CA # 0 +0xE9A0 0x95CB # 0 +0xE9A1 0x6924 # 0 +0xE9A2 0x68F0 # 0 +0xE9A3 0x690B # 0 +0xE9A4 0x6901 # 0 +0xE9A5 0x6957 # 0 +0xE9A6 0x68E3 # 0 +0xE9A7 0x6910 # 0 +0xE9A8 0x6971 # 0 +0xE9A9 0x6939 # 0 +0xE9AA 0x6960 # 0 +0xE9AB 0x6942 # 0 +0xE9AC 0x695D # 0 +0xE9AD 0x6984 # 0 +0xE9AE 0x696B # 0 +0xE9AF 0x6980 # 0 +0xE9B0 0x6998 # 0 +0xE9B1 0x6978 # 0 +0xE9B2 0x6934 # 0 +0xE9B3 0x69CC # 0 +0xE9B4 0x6987 # 0 +0xE9B5 0x6988 # 0 +0xE9B6 0x69CE # 0 +0xE9B7 0x6989 # 0 +0xE9B8 0x6966 # 0 +0xE9B9 0x6963 # 0 +0xE9BA 0x6979 # 0 +0xE9BB 0x699B # 0 +0xE9BC 0x69A7 # 0 +0xE9BD 0x69BB # 0 +0xE9BE 0x69AB # 0 +0xE9BF 0x69AD # 0 +0xE9C0 0x69D4 # 0 +0xE9C1 0x69B1 # 0 +0xE9C2 0x69C1 # 0 +0xE9C3 0x69CA # 0 +0xE9C4 0x69DF # 0 +0xE9C5 0x6995 # 0 +0xE9C6 0x69E0 # 0 +0xE9C7 0x698D # 0 +0xE9C8 0x69FF # 0 +0xE9C9 0x6A2F # 0 +0xE9CA 0x69ED # 0 +0xE9CB 0x6A17 # 0 +0xE9CC 0x6A18 # 0 +0xE9CD 0x6A65 # 0 +0xE9CE 0x69F2 # 0 +0xE9CF 0x6A44 # 0 +0xE9D0 0x6A3E # 0 +0xE9D1 0x6AA0 # 0 +0xE9D2 0x6A50 # 0 +0xE9D3 0x6A5B # 0 +0xE9D4 0x6A35 # 0 +0xE9D5 0x6A8E # 0 +0xE9D6 0x6A79 # 0 +0xE9D7 0x6A3D # 0 +0xE9D8 0x6A28 # 0 +0xE9D9 0x6A58 # 0 +0xE9DA 0x6A7C # 0 +0xE9DB 0x6A91 # 0 +0xE9DC 0x6A90 # 0 +0xE9DD 0x6AA9 # 0 +0xE9DE 0x6A97 # 0 +0xE9DF 0x6AAB # 0 +0xE9E0 0x7337 # 0 +0xE9E1 0x7352 # 0 +0xE9E2 0x6B81 # 0 +0xE9E3 0x6B82 # 0 +0xE9E4 0x6B87 # 0 +0xE9E5 0x6B84 # 0 +0xE9E6 0x6B92 # 0 +0xE9E7 0x6B93 # 0 +0xE9E8 0x6B8D # 0 +0xE9E9 0x6B9A # 0 +0xE9EA 0x6B9B # 0 +0xE9EB 0x6BA1 # 0 +0xE9EC 0x6BAA # 0 +0xE9ED 0x8F6B # 0 +0xE9EE 0x8F6D # 0 +0xE9EF 0x8F71 # 0 +0xE9F0 0x8F72 # 0 +0xE9F1 0x8F73 # 0 +0xE9F2 0x8F75 # 0 +0xE9F3 0x8F76 # 0 +0xE9F4 0x8F78 # 0 +0xE9F5 0x8F77 # 0 +0xE9F6 0x8F79 # 0 +0xE9F7 0x8F7A # 0 +0xE9F8 0x8F7C # 0 +0xE9F9 0x8F7E # 0 +0xE9FA 0x8F81 # 0 +0xE9FB 0x8F82 # 0 +0xE9FC 0x8F84 # 0 +0xE9FD 0x8F87 # 0 +0xE9FE 0x8F8B # 0 +0xEA40 0x95CC # 0 +0xEA41 0x95CD # 0 +0xEA42 0x95CE # 0 +0xEA43 0x95CF # 0 +0xEA44 0x95D0 # 0 +0xEA45 0x95D1 # 0 +0xEA46 0x95D2 # 0 +0xEA47 0x95D3 # 0 +0xEA48 0x95D4 # 0 +0xEA49 0x95D5 # 0 +0xEA4A 0x95D6 # 0 +0xEA4B 0x95D7 # 0 +0xEA4C 0x95D8 # 0 +0xEA4D 0x95D9 # 0 +0xEA4E 0x95DA # 0 +0xEA4F 0x95DB # 0 +0xEA50 0x95DC # 0 +0xEA51 0x95DD # 0 +0xEA52 0x95DE # 0 +0xEA53 0x95DF # 0 +0xEA54 0x95E0 # 0 +0xEA55 0x95E1 # 0 +0xEA56 0x95E2 # 0 +0xEA57 0x95E3 # 0 +0xEA58 0x95E4 # 0 +0xEA59 0x95E5 # 0 +0xEA5A 0x95E6 # 0 +0xEA5B 0x95E7 # 0 +0xEA5C 0x95EC # 0 +0xEA5D 0x95FF # 0 +0xEA5E 0x9607 # 0 +0xEA5F 0x9613 # 0 +0xEA60 0x9618 # 0 +0xEA61 0x961B # 0 +0xEA62 0x961E # 0 +0xEA63 0x9620 # 0 +0xEA64 0x9623 # 0 +0xEA65 0x9624 # 0 +0xEA66 0x9625 # 0 +0xEA67 0x9626 # 0 +0xEA68 0x9627 # 0 +0xEA69 0x9628 # 0 +0xEA6A 0x9629 # 0 +0xEA6B 0x962B # 0 +0xEA6C 0x962C # 0 +0xEA6D 0x962D # 0 +0xEA6E 0x962F # 0 +0xEA6F 0x9630 # 0 +0xEA70 0x9637 # 0 +0xEA71 0x9638 # 0 +0xEA72 0x9639 # 0 +0xEA73 0x963A # 0 +0xEA74 0x963E # 0 +0xEA75 0x9641 # 0 +0xEA76 0x9643 # 0 +0xEA77 0x964A # 0 +0xEA78 0x964E # 0 +0xEA79 0x964F # 0 +0xEA7A 0x9651 # 0 +0xEA7B 0x9652 # 0 +0xEA7C 0x9653 # 0 +0xEA7D 0x9656 # 0 +0xEA7E 0x9657 # 0 +0xEA80 0x9658 # 0 +0xEA81 0x9659 # 0 +0xEA82 0x965A # 0 +0xEA83 0x965C # 0 +0xEA84 0x965D # 0 +0xEA85 0x965E # 0 +0xEA86 0x9660 # 0 +0xEA87 0x9663 # 0 +0xEA88 0x9665 # 0 +0xEA89 0x9666 # 0 +0xEA8A 0x966B # 0 +0xEA8B 0x966D # 0 +0xEA8C 0x966E # 0 +0xEA8D 0x966F # 0 +0xEA8E 0x9670 # 0 +0xEA8F 0x9671 # 0 +0xEA90 0x9673 # 0 +0xEA91 0x9678 # 0 +0xEA92 0x9679 # 0 +0xEA93 0x967A # 0 +0xEA94 0x967B # 0 +0xEA95 0x967C # 0 +0xEA96 0x967D # 0 +0xEA97 0x967E # 0 +0xEA98 0x967F # 0 +0xEA99 0x9680 # 0 +0xEA9A 0x9681 # 0 +0xEA9B 0x9682 # 0 +0xEA9C 0x9683 # 0 +0xEA9D 0x9684 # 0 +0xEA9E 0x9687 # 0 +0xEA9F 0x9689 # 0 +0xEAA0 0x968A # 0 +0xEAA1 0x8F8D # 0 +0xEAA2 0x8F8E # 0 +0xEAA3 0x8F8F # 0 +0xEAA4 0x8F98 # 0 +0xEAA5 0x8F9A # 0 +0xEAA6 0x8ECE # 0 +0xEAA7 0x620B # 0 +0xEAA8 0x6217 # 0 +0xEAA9 0x621B # 0 +0xEAAA 0x621F # 0 +0xEAAB 0x6222 # 0 +0xEAAC 0x6221 # 0 +0xEAAD 0x6225 # 0 +0xEAAE 0x6224 # 0 +0xEAAF 0x622C # 0 +0xEAB0 0x81E7 # 0 +0xEAB1 0x74EF # 0 +0xEAB2 0x74F4 # 0 +0xEAB3 0x74FF # 0 +0xEAB4 0x750F # 0 +0xEAB5 0x7511 # 0 +0xEAB6 0x7513 # 0 +0xEAB7 0x6534 # 0 +0xEAB8 0x65EE # 0 +0xEAB9 0x65EF # 0 +0xEABA 0x65F0 # 0 +0xEABB 0x660A # 0 +0xEABC 0x6619 # 0 +0xEABD 0x6772 # 0 +0xEABE 0x6603 # 0 +0xEABF 0x6615 # 0 +0xEAC0 0x6600 # 0 +0xEAC1 0x7085 # 0 +0xEAC2 0x66F7 # 0 +0xEAC3 0x661D # 0 +0xEAC4 0x6634 # 0 +0xEAC5 0x6631 # 0 +0xEAC6 0x6636 # 0 +0xEAC7 0x6635 # 0 +0xEAC8 0x8006 # 0 +0xEAC9 0x665F # 0 +0xEACA 0x6654 # 0 +0xEACB 0x6641 # 0 +0xEACC 0x664F # 0 +0xEACD 0x6656 # 0 +0xEACE 0x6661 # 0 +0xEACF 0x6657 # 0 +0xEAD0 0x6677 # 0 +0xEAD1 0x6684 # 0 +0xEAD2 0x668C # 0 +0xEAD3 0x66A7 # 0 +0xEAD4 0x669D # 0 +0xEAD5 0x66BE # 0 +0xEAD6 0x66DB # 0 +0xEAD7 0x66DC # 0 +0xEAD8 0x66E6 # 0 +0xEAD9 0x66E9 # 0 +0xEADA 0x8D32 # 0 +0xEADB 0x8D33 # 0 +0xEADC 0x8D36 # 0 +0xEADD 0x8D3B # 0 +0xEADE 0x8D3D # 0 +0xEADF 0x8D40 # 0 +0xEAE0 0x8D45 # 0 +0xEAE1 0x8D46 # 0 +0xEAE2 0x8D48 # 0 +0xEAE3 0x8D49 # 0 +0xEAE4 0x8D47 # 0 +0xEAE5 0x8D4D # 0 +0xEAE6 0x8D55 # 0 +0xEAE7 0x8D59 # 0 +0xEAE8 0x89C7 # 0 +0xEAE9 0x89CA # 0 +0xEAEA 0x89CB # 0 +0xEAEB 0x89CC # 0 +0xEAEC 0x89CE # 0 +0xEAED 0x89CF # 0 +0xEAEE 0x89D0 # 0 +0xEAEF 0x89D1 # 0 +0xEAF0 0x726E # 0 +0xEAF1 0x729F # 0 +0xEAF2 0x725D # 0 +0xEAF3 0x7266 # 0 +0xEAF4 0x726F # 0 +0xEAF5 0x727E # 0 +0xEAF6 0x727F # 0 +0xEAF7 0x7284 # 0 +0xEAF8 0x728B # 0 +0xEAF9 0x728D # 0 +0xEAFA 0x728F # 0 +0xEAFB 0x7292 # 0 +0xEAFC 0x6308 # 0 +0xEAFD 0x6332 # 0 +0xEAFE 0x63B0 # 0 +0xEB40 0x968C # 0 +0xEB41 0x968E # 0 +0xEB42 0x9691 # 0 +0xEB43 0x9692 # 0 +0xEB44 0x9693 # 0 +0xEB45 0x9695 # 0 +0xEB46 0x9696 # 0 +0xEB47 0x969A # 0 +0xEB48 0x969B # 0 +0xEB49 0x969D # 0 +0xEB4A 0x969E # 0 +0xEB4B 0x969F # 0 +0xEB4C 0x96A0 # 0 +0xEB4D 0x96A1 # 0 +0xEB4E 0x96A2 # 0 +0xEB4F 0x96A3 # 0 +0xEB50 0x96A4 # 0 +0xEB51 0x96A5 # 0 +0xEB52 0x96A6 # 0 +0xEB53 0x96A8 # 0 +0xEB54 0x96A9 # 0 +0xEB55 0x96AA # 0 +0xEB56 0x96AB # 0 +0xEB57 0x96AC # 0 +0xEB58 0x96AD # 0 +0xEB59 0x96AE # 0 +0xEB5A 0x96AF # 0 +0xEB5B 0x96B1 # 0 +0xEB5C 0x96B2 # 0 +0xEB5D 0x96B4 # 0 +0xEB5E 0x96B5 # 0 +0xEB5F 0x96B7 # 0 +0xEB60 0x96B8 # 0 +0xEB61 0x96BA # 0 +0xEB62 0x96BB # 0 +0xEB63 0x96BF # 0 +0xEB64 0x96C2 # 0 +0xEB65 0x96C3 # 0 +0xEB66 0x96C8 # 0 +0xEB67 0x96CA # 0 +0xEB68 0x96CB # 0 +0xEB69 0x96D0 # 0 +0xEB6A 0x96D1 # 0 +0xEB6B 0x96D3 # 0 +0xEB6C 0x96D4 # 0 +0xEB6D 0x96D6 # 0 +0xEB6E 0x96D7 # 0 +0xEB6F 0x96D8 # 0 +0xEB70 0x96D9 # 0 +0xEB71 0x96DA # 0 +0xEB72 0x96DB # 0 +0xEB73 0x96DC # 0 +0xEB74 0x96DD # 0 +0xEB75 0x96DE # 0 +0xEB76 0x96DF # 0 +0xEB77 0x96E1 # 0 +0xEB78 0x96E2 # 0 +0xEB79 0x96E3 # 0 +0xEB7A 0x96E4 # 0 +0xEB7B 0x96E5 # 0 +0xEB7C 0x96E6 # 0 +0xEB7D 0x96E7 # 0 +0xEB7E 0x96EB # 0 +0xEB80 0x96EC # 0 +0xEB81 0x96ED # 0 +0xEB82 0x96EE # 0 +0xEB83 0x96F0 # 0 +0xEB84 0x96F1 # 0 +0xEB85 0x96F2 # 0 +0xEB86 0x96F4 # 0 +0xEB87 0x96F5 # 0 +0xEB88 0x96F8 # 0 +0xEB89 0x96FA # 0 +0xEB8A 0x96FB # 0 +0xEB8B 0x96FC # 0 +0xEB8C 0x96FD # 0 +0xEB8D 0x96FF # 0 +0xEB8E 0x9702 # 0 +0xEB8F 0x9703 # 0 +0xEB90 0x9705 # 0 +0xEB91 0x970A # 0 +0xEB92 0x970B # 0 +0xEB93 0x970C # 0 +0xEB94 0x9710 # 0 +0xEB95 0x9711 # 0 +0xEB96 0x9712 # 0 +0xEB97 0x9714 # 0 +0xEB98 0x9715 # 0 +0xEB99 0x9717 # 0 +0xEB9A 0x9718 # 0 +0xEB9B 0x9719 # 0 +0xEB9C 0x971A # 0 +0xEB9D 0x971B # 0 +0xEB9E 0x971D # 0 +0xEB9F 0x971F # 0 +0xEBA0 0x9720 # 0 +0xEBA1 0x643F # 0 +0xEBA2 0x64D8 # 0 +0xEBA3 0x8004 # 0 +0xEBA4 0x6BEA # 0 +0xEBA5 0x6BF3 # 0 +0xEBA6 0x6BFD # 0 +0xEBA7 0x6BF5 # 0 +0xEBA8 0x6BF9 # 0 +0xEBA9 0x6C05 # 0 +0xEBAA 0x6C07 # 0 +0xEBAB 0x6C06 # 0 +0xEBAC 0x6C0D # 0 +0xEBAD 0x6C15 # 0 +0xEBAE 0x6C18 # 0 +0xEBAF 0x6C19 # 0 +0xEBB0 0x6C1A # 0 +0xEBB1 0x6C21 # 0 +0xEBB2 0x6C29 # 0 +0xEBB3 0x6C24 # 0 +0xEBB4 0x6C2A # 0 +0xEBB5 0x6C32 # 0 +0xEBB6 0x6535 # 0 +0xEBB7 0x6555 # 0 +0xEBB8 0x656B # 0 +0xEBB9 0x724D # 0 +0xEBBA 0x7252 # 0 +0xEBBB 0x7256 # 0 +0xEBBC 0x7230 # 0 +0xEBBD 0x8662 # 0 +0xEBBE 0x5216 # 0 +0xEBBF 0x809F # 0 +0xEBC0 0x809C # 0 +0xEBC1 0x8093 # 0 +0xEBC2 0x80BC # 0 +0xEBC3 0x670A # 0 +0xEBC4 0x80BD # 0 +0xEBC5 0x80B1 # 0 +0xEBC6 0x80AB # 0 +0xEBC7 0x80AD # 0 +0xEBC8 0x80B4 # 0 +0xEBC9 0x80B7 # 0 +0xEBCA 0x80E7 # 0 +0xEBCB 0x80E8 # 0 +0xEBCC 0x80E9 # 0 +0xEBCD 0x80EA # 0 +0xEBCE 0x80DB # 0 +0xEBCF 0x80C2 # 0 +0xEBD0 0x80C4 # 0 +0xEBD1 0x80D9 # 0 +0xEBD2 0x80CD # 0 +0xEBD3 0x80D7 # 0 +0xEBD4 0x6710 # 0 +0xEBD5 0x80DD # 0 +0xEBD6 0x80EB # 0 +0xEBD7 0x80F1 # 0 +0xEBD8 0x80F4 # 0 +0xEBD9 0x80ED # 0 +0xEBDA 0x810D # 0 +0xEBDB 0x810E # 0 +0xEBDC 0x80F2 # 0 +0xEBDD 0x80FC # 0 +0xEBDE 0x6715 # 0 +0xEBDF 0x8112 # 0 +0xEBE0 0x8C5A # 0 +0xEBE1 0x8136 # 0 +0xEBE2 0x811E # 0 +0xEBE3 0x812C # 0 +0xEBE4 0x8118 # 0 +0xEBE5 0x8132 # 0 +0xEBE6 0x8148 # 0 +0xEBE7 0x814C # 0 +0xEBE8 0x8153 # 0 +0xEBE9 0x8174 # 0 +0xEBEA 0x8159 # 0 +0xEBEB 0x815A # 0 +0xEBEC 0x8171 # 0 +0xEBED 0x8160 # 0 +0xEBEE 0x8169 # 0 +0xEBEF 0x817C # 0 +0xEBF0 0x817D # 0 +0xEBF1 0x816D # 0 +0xEBF2 0x8167 # 0 +0xEBF3 0x584D # 0 +0xEBF4 0x5AB5 # 0 +0xEBF5 0x8188 # 0 +0xEBF6 0x8182 # 0 +0xEBF7 0x8191 # 0 +0xEBF8 0x6ED5 # 0 +0xEBF9 0x81A3 # 0 +0xEBFA 0x81AA # 0 +0xEBFB 0x81CC # 0 +0xEBFC 0x6726 # 0 +0xEBFD 0x81CA # 0 +0xEBFE 0x81BB # 0 +0xEC40 0x9721 # 0 +0xEC41 0x9722 # 0 +0xEC42 0x9723 # 0 +0xEC43 0x9724 # 0 +0xEC44 0x9725 # 0 +0xEC45 0x9726 # 0 +0xEC46 0x9727 # 0 +0xEC47 0x9728 # 0 +0xEC48 0x9729 # 0 +0xEC49 0x972B # 0 +0xEC4A 0x972C # 0 +0xEC4B 0x972E # 0 +0xEC4C 0x972F # 0 +0xEC4D 0x9731 # 0 +0xEC4E 0x9733 # 0 +0xEC4F 0x9734 # 0 +0xEC50 0x9735 # 0 +0xEC51 0x9736 # 0 +0xEC52 0x9737 # 0 +0xEC53 0x973A # 0 +0xEC54 0x973B # 0 +0xEC55 0x973C # 0 +0xEC56 0x973D # 0 +0xEC57 0x973F # 0 +0xEC58 0x9740 # 0 +0xEC59 0x9741 # 0 +0xEC5A 0x9742 # 0 +0xEC5B 0x9743 # 0 +0xEC5C 0x9744 # 0 +0xEC5D 0x9745 # 0 +0xEC5E 0x9746 # 0 +0xEC5F 0x9747 # 0 +0xEC60 0x9748 # 0 +0xEC61 0x9749 # 0 +0xEC62 0x974A # 0 +0xEC63 0x974B # 0 +0xEC64 0x974C # 0 +0xEC65 0x974D # 0 +0xEC66 0x974E # 0 +0xEC67 0x974F # 0 +0xEC68 0x9750 # 0 +0xEC69 0x9751 # 0 +0xEC6A 0x9754 # 0 +0xEC6B 0x9755 # 0 +0xEC6C 0x9757 # 0 +0xEC6D 0x9758 # 0 +0xEC6E 0x975A # 0 +0xEC6F 0x975C # 0 +0xEC70 0x975D # 0 +0xEC71 0x975F # 0 +0xEC72 0x9763 # 0 +0xEC73 0x9764 # 0 +0xEC74 0x9766 # 0 +0xEC75 0x9767 # 0 +0xEC76 0x9768 # 0 +0xEC77 0x976A # 0 +0xEC78 0x976B # 0 +0xEC79 0x976C # 0 +0xEC7A 0x976D # 0 +0xEC7B 0x976E # 0 +0xEC7C 0x976F # 0 +0xEC7D 0x9770 # 0 +0xEC7E 0x9771 # 0 +0xEC80 0x9772 # 0 +0xEC81 0x9775 # 0 +0xEC82 0x9777 # 0 +0xEC83 0x9778 # 0 +0xEC84 0x9779 # 0 +0xEC85 0x977A # 0 +0xEC86 0x977B # 0 +0xEC87 0x977D # 0 +0xEC88 0x977E # 0 +0xEC89 0x977F # 0 +0xEC8A 0x9780 # 0 +0xEC8B 0x9781 # 0 +0xEC8C 0x9782 # 0 +0xEC8D 0x9783 # 0 +0xEC8E 0x9784 # 0 +0xEC8F 0x9786 # 0 +0xEC90 0x9787 # 0 +0xEC91 0x9788 # 0 +0xEC92 0x9789 # 0 +0xEC93 0x978A # 0 +0xEC94 0x978C # 0 +0xEC95 0x978E # 0 +0xEC96 0x978F # 0 +0xEC97 0x9790 # 0 +0xEC98 0x9793 # 0 +0xEC99 0x9795 # 0 +0xEC9A 0x9796 # 0 +0xEC9B 0x9797 # 0 +0xEC9C 0x9799 # 0 +0xEC9D 0x979A # 0 +0xEC9E 0x979B # 0 +0xEC9F 0x979C # 0 +0xECA0 0x979D # 0 +0xECA1 0x81C1 # 0 +0xECA2 0x81A6 # 0 +0xECA3 0x6B24 # 0 +0xECA4 0x6B37 # 0 +0xECA5 0x6B39 # 0 +0xECA6 0x6B43 # 0 +0xECA7 0x6B46 # 0 +0xECA8 0x6B59 # 0 +0xECA9 0x98D1 # 0 +0xECAA 0x98D2 # 0 +0xECAB 0x98D3 # 0 +0xECAC 0x98D5 # 0 +0xECAD 0x98D9 # 0 +0xECAE 0x98DA # 0 +0xECAF 0x6BB3 # 0 +0xECB0 0x5F40 # 0 +0xECB1 0x6BC2 # 0 +0xECB2 0x89F3 # 0 +0xECB3 0x6590 # 0 +0xECB4 0x9F51 # 0 +0xECB5 0x6593 # 0 +0xECB6 0x65BC # 0 +0xECB7 0x65C6 # 0 +0xECB8 0x65C4 # 0 +0xECB9 0x65C3 # 0 +0xECBA 0x65CC # 0 +0xECBB 0x65CE # 0 +0xECBC 0x65D2 # 0 +0xECBD 0x65D6 # 0 +0xECBE 0x7080 # 0 +0xECBF 0x709C # 0 +0xECC0 0x7096 # 0 +0xECC1 0x709D # 0 +0xECC2 0x70BB # 0 +0xECC3 0x70C0 # 0 +0xECC4 0x70B7 # 0 +0xECC5 0x70AB # 0 +0xECC6 0x70B1 # 0 +0xECC7 0x70E8 # 0 +0xECC8 0x70CA # 0 +0xECC9 0x7110 # 0 +0xECCA 0x7113 # 0 +0xECCB 0x7116 # 0 +0xECCC 0x712F # 0 +0xECCD 0x7131 # 0 +0xECCE 0x7173 # 0 +0xECCF 0x715C # 0 +0xECD0 0x7168 # 0 +0xECD1 0x7145 # 0 +0xECD2 0x7172 # 0 +0xECD3 0x714A # 0 +0xECD4 0x7178 # 0 +0xECD5 0x717A # 0 +0xECD6 0x7198 # 0 +0xECD7 0x71B3 # 0 +0xECD8 0x71B5 # 0 +0xECD9 0x71A8 # 0 +0xECDA 0x71A0 # 0 +0xECDB 0x71E0 # 0 +0xECDC 0x71D4 # 0 +0xECDD 0x71E7 # 0 +0xECDE 0x71F9 # 0 +0xECDF 0x721D # 0 +0xECE0 0x7228 # 0 +0xECE1 0x706C # 0 +0xECE2 0x7118 # 0 +0xECE3 0x7166 # 0 +0xECE4 0x71B9 # 0 +0xECE5 0x623E # 0 +0xECE6 0x623D # 0 +0xECE7 0x6243 # 0 +0xECE8 0x6248 # 0 +0xECE9 0x6249 # 0 +0xECEA 0x793B # 0 +0xECEB 0x7940 # 0 +0xECEC 0x7946 # 0 +0xECED 0x7949 # 0 +0xECEE 0x795B # 0 +0xECEF 0x795C # 0 +0xECF0 0x7953 # 0 +0xECF1 0x795A # 0 +0xECF2 0x7962 # 0 +0xECF3 0x7957 # 0 +0xECF4 0x7960 # 0 +0xECF5 0x796F # 0 +0xECF6 0x7967 # 0 +0xECF7 0x797A # 0 +0xECF8 0x7985 # 0 +0xECF9 0x798A # 0 +0xECFA 0x799A # 0 +0xECFB 0x79A7 # 0 +0xECFC 0x79B3 # 0 +0xECFD 0x5FD1 # 0 +0xECFE 0x5FD0 # 0 +0xED40 0x979E # 0 +0xED41 0x979F # 0 +0xED42 0x97A1 # 0 +0xED43 0x97A2 # 0 +0xED44 0x97A4 # 0 +0xED45 0x97A5 # 0 +0xED46 0x97A6 # 0 +0xED47 0x97A7 # 0 +0xED48 0x97A8 # 0 +0xED49 0x97A9 # 0 +0xED4A 0x97AA # 0 +0xED4B 0x97AC # 0 +0xED4C 0x97AE # 0 +0xED4D 0x97B0 # 0 +0xED4E 0x97B1 # 0 +0xED4F 0x97B3 # 0 +0xED50 0x97B5 # 0 +0xED51 0x97B6 # 0 +0xED52 0x97B7 # 0 +0xED53 0x97B8 # 0 +0xED54 0x97B9 # 0 +0xED55 0x97BA # 0 +0xED56 0x97BB # 0 +0xED57 0x97BC # 0 +0xED58 0x97BD # 0 +0xED59 0x97BE # 0 +0xED5A 0x97BF # 0 +0xED5B 0x97C0 # 0 +0xED5C 0x97C1 # 0 +0xED5D 0x97C2 # 0 +0xED5E 0x97C3 # 0 +0xED5F 0x97C4 # 0 +0xED60 0x97C5 # 0 +0xED61 0x97C6 # 0 +0xED62 0x97C7 # 0 +0xED63 0x97C8 # 0 +0xED64 0x97C9 # 0 +0xED65 0x97CA # 0 +0xED66 0x97CB # 0 +0xED67 0x97CC # 0 +0xED68 0x97CD # 0 +0xED69 0x97CE # 0 +0xED6A 0x97CF # 0 +0xED6B 0x97D0 # 0 +0xED6C 0x97D1 # 0 +0xED6D 0x97D2 # 0 +0xED6E 0x97D3 # 0 +0xED6F 0x97D4 # 0 +0xED70 0x97D5 # 0 +0xED71 0x97D6 # 0 +0xED72 0x97D7 # 0 +0xED73 0x97D8 # 0 +0xED74 0x97D9 # 0 +0xED75 0x97DA # 0 +0xED76 0x97DB # 0 +0xED77 0x97DC # 0 +0xED78 0x97DD # 0 +0xED79 0x97DE # 0 +0xED7A 0x97DF # 0 +0xED7B 0x97E0 # 0 +0xED7C 0x97E1 # 0 +0xED7D 0x97E2 # 0 +0xED7E 0x97E3 # 0 +0xED80 0x97E4 # 0 +0xED81 0x97E5 # 0 +0xED82 0x97E8 # 0 +0xED83 0x97EE # 0 +0xED84 0x97EF # 0 +0xED85 0x97F0 # 0 +0xED86 0x97F1 # 0 +0xED87 0x97F2 # 0 +0xED88 0x97F4 # 0 +0xED89 0x97F7 # 0 +0xED8A 0x97F8 # 0 +0xED8B 0x97F9 # 0 +0xED8C 0x97FA # 0 +0xED8D 0x97FB # 0 +0xED8E 0x97FC # 0 +0xED8F 0x97FD # 0 +0xED90 0x97FE # 0 +0xED91 0x97FF # 0 +0xED92 0x9800 # 0 +0xED93 0x9801 # 0 +0xED94 0x9802 # 0 +0xED95 0x9803 # 0 +0xED96 0x9804 # 0 +0xED97 0x9805 # 0 +0xED98 0x9806 # 0 +0xED99 0x9807 # 0 +0xED9A 0x9808 # 0 +0xED9B 0x9809 # 0 +0xED9C 0x980A # 0 +0xED9D 0x980B # 0 +0xED9E 0x980C # 0 +0xED9F 0x980D # 0 +0xEDA0 0x980E # 0 +0xEDA1 0x603C # 0 +0xEDA2 0x605D # 0 +0xEDA3 0x605A # 0 +0xEDA4 0x6067 # 0 +0xEDA5 0x6041 # 0 +0xEDA6 0x6059 # 0 +0xEDA7 0x6063 # 0 +0xEDA8 0x60AB # 0 +0xEDA9 0x6106 # 0 +0xEDAA 0x610D # 0 +0xEDAB 0x615D # 0 +0xEDAC 0x61A9 # 0 +0xEDAD 0x619D # 0 +0xEDAE 0x61CB # 0 +0xEDAF 0x61D1 # 0 +0xEDB0 0x6206 # 0 +0xEDB1 0x8080 # 0 +0xEDB2 0x807F # 0 +0xEDB3 0x6C93 # 0 +0xEDB4 0x6CF6 # 0 +0xEDB5 0x6DFC # 0 +0xEDB6 0x77F6 # 0 +0xEDB7 0x77F8 # 0 +0xEDB8 0x7800 # 0 +0xEDB9 0x7809 # 0 +0xEDBA 0x7817 # 0 +0xEDBB 0x7818 # 0 +0xEDBC 0x7811 # 0 +0xEDBD 0x65AB # 0 +0xEDBE 0x782D # 0 +0xEDBF 0x781C # 0 +0xEDC0 0x781D # 0 +0xEDC1 0x7839 # 0 +0xEDC2 0x783A # 0 +0xEDC3 0x783B # 0 +0xEDC4 0x781F # 0 +0xEDC5 0x783C # 0 +0xEDC6 0x7825 # 0 +0xEDC7 0x782C # 0 +0xEDC8 0x7823 # 0 +0xEDC9 0x7829 # 0 +0xEDCA 0x784E # 0 +0xEDCB 0x786D # 0 +0xEDCC 0x7856 # 0 +0xEDCD 0x7857 # 0 +0xEDCE 0x7826 # 0 +0xEDCF 0x7850 # 0 +0xEDD0 0x7847 # 0 +0xEDD1 0x784C # 0 +0xEDD2 0x786A # 0 +0xEDD3 0x789B # 0 +0xEDD4 0x7893 # 0 +0xEDD5 0x789A # 0 +0xEDD6 0x7887 # 0 +0xEDD7 0x789C # 0 +0xEDD8 0x78A1 # 0 +0xEDD9 0x78A3 # 0 +0xEDDA 0x78B2 # 0 +0xEDDB 0x78B9 # 0 +0xEDDC 0x78A5 # 0 +0xEDDD 0x78D4 # 0 +0xEDDE 0x78D9 # 0 +0xEDDF 0x78C9 # 0 +0xEDE0 0x78EC # 0 +0xEDE1 0x78F2 # 0 +0xEDE2 0x7905 # 0 +0xEDE3 0x78F4 # 0 +0xEDE4 0x7913 # 0 +0xEDE5 0x7924 # 0 +0xEDE6 0x791E # 0 +0xEDE7 0x7934 # 0 +0xEDE8 0x9F9B # 0 +0xEDE9 0x9EF9 # 0 +0xEDEA 0x9EFB # 0 +0xEDEB 0x9EFC # 0 +0xEDEC 0x76F1 # 0 +0xEDED 0x7704 # 0 +0xEDEE 0x770D # 0 +0xEDEF 0x76F9 # 0 +0xEDF0 0x7707 # 0 +0xEDF1 0x7708 # 0 +0xEDF2 0x771A # 0 +0xEDF3 0x7722 # 0 +0xEDF4 0x7719 # 0 +0xEDF5 0x772D # 0 +0xEDF6 0x7726 # 0 +0xEDF7 0x7735 # 0 +0xEDF8 0x7738 # 0 +0xEDF9 0x7750 # 0 +0xEDFA 0x7751 # 0 +0xEDFB 0x7747 # 0 +0xEDFC 0x7743 # 0 +0xEDFD 0x775A # 0 +0xEDFE 0x7768 # 0 +0xEE40 0x980F # 0 +0xEE41 0x9810 # 0 +0xEE42 0x9811 # 0 +0xEE43 0x9812 # 0 +0xEE44 0x9813 # 0 +0xEE45 0x9814 # 0 +0xEE46 0x9815 # 0 +0xEE47 0x9816 # 0 +0xEE48 0x9817 # 0 +0xEE49 0x9818 # 0 +0xEE4A 0x9819 # 0 +0xEE4B 0x981A # 0 +0xEE4C 0x981B # 0 +0xEE4D 0x981C # 0 +0xEE4E 0x981D # 0 +0xEE4F 0x981E # 0 +0xEE50 0x981F # 0 +0xEE51 0x9820 # 0 +0xEE52 0x9821 # 0 +0xEE53 0x9822 # 0 +0xEE54 0x9823 # 0 +0xEE55 0x9824 # 0 +0xEE56 0x9825 # 0 +0xEE57 0x9826 # 0 +0xEE58 0x9827 # 0 +0xEE59 0x9828 # 0 +0xEE5A 0x9829 # 0 +0xEE5B 0x982A # 0 +0xEE5C 0x982B # 0 +0xEE5D 0x982C # 0 +0xEE5E 0x982D # 0 +0xEE5F 0x982E # 0 +0xEE60 0x982F # 0 +0xEE61 0x9830 # 0 +0xEE62 0x9831 # 0 +0xEE63 0x9832 # 0 +0xEE64 0x9833 # 0 +0xEE65 0x9834 # 0 +0xEE66 0x9835 # 0 +0xEE67 0x9836 # 0 +0xEE68 0x9837 # 0 +0xEE69 0x9838 # 0 +0xEE6A 0x9839 # 0 +0xEE6B 0x983A # 0 +0xEE6C 0x983B # 0 +0xEE6D 0x983C # 0 +0xEE6E 0x983D # 0 +0xEE6F 0x983E # 0 +0xEE70 0x983F # 0 +0xEE71 0x9840 # 0 +0xEE72 0x9841 # 0 +0xEE73 0x9842 # 0 +0xEE74 0x9843 # 0 +0xEE75 0x9844 # 0 +0xEE76 0x9845 # 0 +0xEE77 0x9846 # 0 +0xEE78 0x9847 # 0 +0xEE79 0x9848 # 0 +0xEE7A 0x9849 # 0 +0xEE7B 0x984A # 0 +0xEE7C 0x984B # 0 +0xEE7D 0x984C # 0 +0xEE7E 0x984D # 0 +0xEE80 0x984E # 0 +0xEE81 0x984F # 0 +0xEE82 0x9850 # 0 +0xEE83 0x9851 # 0 +0xEE84 0x9852 # 0 +0xEE85 0x9853 # 0 +0xEE86 0x9854 # 0 +0xEE87 0x9855 # 0 +0xEE88 0x9856 # 0 +0xEE89 0x9857 # 0 +0xEE8A 0x9858 # 0 +0xEE8B 0x9859 # 0 +0xEE8C 0x985A # 0 +0xEE8D 0x985B # 0 +0xEE8E 0x985C # 0 +0xEE8F 0x985D # 0 +0xEE90 0x985E # 0 +0xEE91 0x985F # 0 +0xEE92 0x9860 # 0 +0xEE93 0x9861 # 0 +0xEE94 0x9862 # 0 +0xEE95 0x9863 # 0 +0xEE96 0x9864 # 0 +0xEE97 0x9865 # 0 +0xEE98 0x9866 # 0 +0xEE99 0x9867 # 0 +0xEE9A 0x9868 # 0 +0xEE9B 0x9869 # 0 +0xEE9C 0x986A # 0 +0xEE9D 0x986B # 0 +0xEE9E 0x986C # 0 +0xEE9F 0x986D # 0 +0xEEA0 0x986E # 0 +0xEEA1 0x7762 # 0 +0xEEA2 0x7765 # 0 +0xEEA3 0x777F # 0 +0xEEA4 0x778D # 0 +0xEEA5 0x777D # 0 +0xEEA6 0x7780 # 0 +0xEEA7 0x778C # 0 +0xEEA8 0x7791 # 0 +0xEEA9 0x779F # 0 +0xEEAA 0x77A0 # 0 +0xEEAB 0x77B0 # 0 +0xEEAC 0x77B5 # 0 +0xEEAD 0x77BD # 0 +0xEEAE 0x753A # 0 +0xEEAF 0x7540 # 0 +0xEEB0 0x754E # 0 +0xEEB1 0x754B # 0 +0xEEB2 0x7548 # 0 +0xEEB3 0x755B # 0 +0xEEB4 0x7572 # 0 +0xEEB5 0x7579 # 0 +0xEEB6 0x7583 # 0 +0xEEB7 0x7F58 # 0 +0xEEB8 0x7F61 # 0 +0xEEB9 0x7F5F # 0 +0xEEBA 0x8A48 # 0 +0xEEBB 0x7F68 # 0 +0xEEBC 0x7F74 # 0 +0xEEBD 0x7F71 # 0 +0xEEBE 0x7F79 # 0 +0xEEBF 0x7F81 # 0 +0xEEC0 0x7F7E # 0 +0xEEC1 0x76CD # 0 +0xEEC2 0x76E5 # 0 +0xEEC3 0x8832 # 0 +0xEEC4 0x9485 # 0 +0xEEC5 0x9486 # 0 +0xEEC6 0x9487 # 0 +0xEEC7 0x948B # 0 +0xEEC8 0x948A # 0 +0xEEC9 0x948C # 0 +0xEECA 0x948D # 0 +0xEECB 0x948F # 0 +0xEECC 0x9490 # 0 +0xEECD 0x9494 # 0 +0xEECE 0x9497 # 0 +0xEECF 0x9495 # 0 +0xEED0 0x949A # 0 +0xEED1 0x949B # 0 +0xEED2 0x949C # 0 +0xEED3 0x94A3 # 0 +0xEED4 0x94A4 # 0 +0xEED5 0x94AB # 0 +0xEED6 0x94AA # 0 +0xEED7 0x94AD # 0 +0xEED8 0x94AC # 0 +0xEED9 0x94AF # 0 +0xEEDA 0x94B0 # 0 +0xEEDB 0x94B2 # 0 +0xEEDC 0x94B4 # 0 +0xEEDD 0x94B6 # 0 +0xEEDE 0x94B7 # 0 +0xEEDF 0x94B8 # 0 +0xEEE0 0x94B9 # 0 +0xEEE1 0x94BA # 0 +0xEEE2 0x94BC # 0 +0xEEE3 0x94BD # 0 +0xEEE4 0x94BF # 0 +0xEEE5 0x94C4 # 0 +0xEEE6 0x94C8 # 0 +0xEEE7 0x94C9 # 0 +0xEEE8 0x94CA # 0 +0xEEE9 0x94CB # 0 +0xEEEA 0x94CC # 0 +0xEEEB 0x94CD # 0 +0xEEEC 0x94CE # 0 +0xEEED 0x94D0 # 0 +0xEEEE 0x94D1 # 0 +0xEEEF 0x94D2 # 0 +0xEEF0 0x94D5 # 0 +0xEEF1 0x94D6 # 0 +0xEEF2 0x94D7 # 0 +0xEEF3 0x94D9 # 0 +0xEEF4 0x94D8 # 0 +0xEEF5 0x94DB # 0 +0xEEF6 0x94DE # 0 +0xEEF7 0x94DF # 0 +0xEEF8 0x94E0 # 0 +0xEEF9 0x94E2 # 0 +0xEEFA 0x94E4 # 0 +0xEEFB 0x94E5 # 0 +0xEEFC 0x94E7 # 0 +0xEEFD 0x94E8 # 0 +0xEEFE 0x94EA # 0 +0xEF40 0x986F # 0 +0xEF41 0x9870 # 0 +0xEF42 0x9871 # 0 +0xEF43 0x9872 # 0 +0xEF44 0x9873 # 0 +0xEF45 0x9874 # 0 +0xEF46 0x988B # 0 +0xEF47 0x988E # 0 +0xEF48 0x9892 # 0 +0xEF49 0x9895 # 0 +0xEF4A 0x9899 # 0 +0xEF4B 0x98A3 # 0 +0xEF4C 0x98A8 # 0 +0xEF4D 0x98A9 # 0 +0xEF4E 0x98AA # 0 +0xEF4F 0x98AB # 0 +0xEF50 0x98AC # 0 +0xEF51 0x98AD # 0 +0xEF52 0x98AE # 0 +0xEF53 0x98AF # 0 +0xEF54 0x98B0 # 0 +0xEF55 0x98B1 # 0 +0xEF56 0x98B2 # 0 +0xEF57 0x98B3 # 0 +0xEF58 0x98B4 # 0 +0xEF59 0x98B5 # 0 +0xEF5A 0x98B6 # 0 +0xEF5B 0x98B7 # 0 +0xEF5C 0x98B8 # 0 +0xEF5D 0x98B9 # 0 +0xEF5E 0x98BA # 0 +0xEF5F 0x98BB # 0 +0xEF60 0x98BC # 0 +0xEF61 0x98BD # 0 +0xEF62 0x98BE # 0 +0xEF63 0x98BF # 0 +0xEF64 0x98C0 # 0 +0xEF65 0x98C1 # 0 +0xEF66 0x98C2 # 0 +0xEF67 0x98C3 # 0 +0xEF68 0x98C4 # 0 +0xEF69 0x98C5 # 0 +0xEF6A 0x98C6 # 0 +0xEF6B 0x98C7 # 0 +0xEF6C 0x98C8 # 0 +0xEF6D 0x98C9 # 0 +0xEF6E 0x98CA # 0 +0xEF6F 0x98CB # 0 +0xEF70 0x98CC # 0 +0xEF71 0x98CD # 0 +0xEF72 0x98CF # 0 +0xEF73 0x98D0 # 0 +0xEF74 0x98D4 # 0 +0xEF75 0x98D6 # 0 +0xEF76 0x98D7 # 0 +0xEF77 0x98DB # 0 +0xEF78 0x98DC # 0 +0xEF79 0x98DD # 0 +0xEF7A 0x98E0 # 0 +0xEF7B 0x98E1 # 0 +0xEF7C 0x98E2 # 0 +0xEF7D 0x98E3 # 0 +0xEF7E 0x98E4 # 0 +0xEF80 0x98E5 # 0 +0xEF81 0x98E6 # 0 +0xEF82 0x98E9 # 0 +0xEF83 0x98EA # 0 +0xEF84 0x98EB # 0 +0xEF85 0x98EC # 0 +0xEF86 0x98ED # 0 +0xEF87 0x98EE # 0 +0xEF88 0x98EF # 0 +0xEF89 0x98F0 # 0 +0xEF8A 0x98F1 # 0 +0xEF8B 0x98F2 # 0 +0xEF8C 0x98F3 # 0 +0xEF8D 0x98F4 # 0 +0xEF8E 0x98F5 # 0 +0xEF8F 0x98F6 # 0 +0xEF90 0x98F7 # 0 +0xEF91 0x98F8 # 0 +0xEF92 0x98F9 # 0 +0xEF93 0x98FA # 0 +0xEF94 0x98FB # 0 +0xEF95 0x98FC # 0 +0xEF96 0x98FD # 0 +0xEF97 0x98FE # 0 +0xEF98 0x98FF # 0 +0xEF99 0x9900 # 0 +0xEF9A 0x9901 # 0 +0xEF9B 0x9902 # 0 +0xEF9C 0x9903 # 0 +0xEF9D 0x9904 # 0 +0xEF9E 0x9905 # 0 +0xEF9F 0x9906 # 0 +0xEFA0 0x9907 # 0 +0xEFA1 0x94E9 # 0 +0xEFA2 0x94EB # 0 +0xEFA3 0x94EE # 0 +0xEFA4 0x94EF # 0 +0xEFA5 0x94F3 # 0 +0xEFA6 0x94F4 # 0 +0xEFA7 0x94F5 # 0 +0xEFA8 0x94F7 # 0 +0xEFA9 0x94F9 # 0 +0xEFAA 0x94FC # 0 +0xEFAB 0x94FD # 0 +0xEFAC 0x94FF # 0 +0xEFAD 0x9503 # 0 +0xEFAE 0x9502 # 0 +0xEFAF 0x9506 # 0 +0xEFB0 0x9507 # 0 +0xEFB1 0x9509 # 0 +0xEFB2 0x950A # 0 +0xEFB3 0x950D # 0 +0xEFB4 0x950E # 0 +0xEFB5 0x950F # 0 +0xEFB6 0x9512 # 0 +0xEFB7 0x9513 # 0 +0xEFB8 0x9514 # 0 +0xEFB9 0x9515 # 0 +0xEFBA 0x9516 # 0 +0xEFBB 0x9518 # 0 +0xEFBC 0x951B # 0 +0xEFBD 0x951D # 0 +0xEFBE 0x951E # 0 +0xEFBF 0x951F # 0 +0xEFC0 0x9522 # 0 +0xEFC1 0x952A # 0 +0xEFC2 0x952B # 0 +0xEFC3 0x9529 # 0 +0xEFC4 0x952C # 0 +0xEFC5 0x9531 # 0 +0xEFC6 0x9532 # 0 +0xEFC7 0x9534 # 0 +0xEFC8 0x9536 # 0 +0xEFC9 0x9537 # 0 +0xEFCA 0x9538 # 0 +0xEFCB 0x953C # 0 +0xEFCC 0x953E # 0 +0xEFCD 0x953F # 0 +0xEFCE 0x9542 # 0 +0xEFCF 0x9535 # 0 +0xEFD0 0x9544 # 0 +0xEFD1 0x9545 # 0 +0xEFD2 0x9546 # 0 +0xEFD3 0x9549 # 0 +0xEFD4 0x954C # 0 +0xEFD5 0x954E # 0 +0xEFD6 0x954F # 0 +0xEFD7 0x9552 # 0 +0xEFD8 0x9553 # 0 +0xEFD9 0x9554 # 0 +0xEFDA 0x9556 # 0 +0xEFDB 0x9557 # 0 +0xEFDC 0x9558 # 0 +0xEFDD 0x9559 # 0 +0xEFDE 0x955B # 0 +0xEFDF 0x955E # 0 +0xEFE0 0x955F # 0 +0xEFE1 0x955D # 0 +0xEFE2 0x9561 # 0 +0xEFE3 0x9562 # 0 +0xEFE4 0x9564 # 0 +0xEFE5 0x9565 # 0 +0xEFE6 0x9566 # 0 +0xEFE7 0x9567 # 0 +0xEFE8 0x9568 # 0 +0xEFE9 0x9569 # 0 +0xEFEA 0x956A # 0 +0xEFEB 0x956B # 0 +0xEFEC 0x956C # 0 +0xEFED 0x956F # 0 +0xEFEE 0x9571 # 0 +0xEFEF 0x9572 # 0 +0xEFF0 0x9573 # 0 +0xEFF1 0x953A # 0 +0xEFF2 0x77E7 # 0 +0xEFF3 0x77EC # 0 +0xEFF4 0x96C9 # 0 +0xEFF5 0x79D5 # 0 +0xEFF6 0x79ED # 0 +0xEFF7 0x79E3 # 0 +0xEFF8 0x79EB # 0 +0xEFF9 0x7A06 # 0 +0xEFFA 0x5D47 # 0 +0xEFFB 0x7A03 # 0 +0xEFFC 0x7A02 # 0 +0xEFFD 0x7A1E # 0 +0xEFFE 0x7A14 # 0 +0xF040 0x9908 # 0 +0xF041 0x9909 # 0 +0xF042 0x990A # 0 +0xF043 0x990B # 0 +0xF044 0x990C # 0 +0xF045 0x990E # 0 +0xF046 0x990F # 0 +0xF047 0x9911 # 0 +0xF048 0x9912 # 0 +0xF049 0x9913 # 0 +0xF04A 0x9914 # 0 +0xF04B 0x9915 # 0 +0xF04C 0x9916 # 0 +0xF04D 0x9917 # 0 +0xF04E 0x9918 # 0 +0xF04F 0x9919 # 0 +0xF050 0x991A # 0 +0xF051 0x991B # 0 +0xF052 0x991C # 0 +0xF053 0x991D # 0 +0xF054 0x991E # 0 +0xF055 0x991F # 0 +0xF056 0x9920 # 0 +0xF057 0x9921 # 0 +0xF058 0x9922 # 0 +0xF059 0x9923 # 0 +0xF05A 0x9924 # 0 +0xF05B 0x9925 # 0 +0xF05C 0x9926 # 0 +0xF05D 0x9927 # 0 +0xF05E 0x9928 # 0 +0xF05F 0x9929 # 0 +0xF060 0x992A # 0 +0xF061 0x992B # 0 +0xF062 0x992C # 0 +0xF063 0x992D # 0 +0xF064 0x992F # 0 +0xF065 0x9930 # 0 +0xF066 0x9931 # 0 +0xF067 0x9932 # 0 +0xF068 0x9933 # 0 +0xF069 0x9934 # 0 +0xF06A 0x9935 # 0 +0xF06B 0x9936 # 0 +0xF06C 0x9937 # 0 +0xF06D 0x9938 # 0 +0xF06E 0x9939 # 0 +0xF06F 0x993A # 0 +0xF070 0x993B # 0 +0xF071 0x993C # 0 +0xF072 0x993D # 0 +0xF073 0x993E # 0 +0xF074 0x993F # 0 +0xF075 0x9940 # 0 +0xF076 0x9941 # 0 +0xF077 0x9942 # 0 +0xF078 0x9943 # 0 +0xF079 0x9944 # 0 +0xF07A 0x9945 # 0 +0xF07B 0x9946 # 0 +0xF07C 0x9947 # 0 +0xF07D 0x9948 # 0 +0xF07E 0x9949 # 0 +0xF080 0x994A # 0 +0xF081 0x994B # 0 +0xF082 0x994C # 0 +0xF083 0x994D # 0 +0xF084 0x994E # 0 +0xF085 0x994F # 0 +0xF086 0x9950 # 0 +0xF087 0x9951 # 0 +0xF088 0x9952 # 0 +0xF089 0x9953 # 0 +0xF08A 0x9956 # 0 +0xF08B 0x9957 # 0 +0xF08C 0x9958 # 0 +0xF08D 0x9959 # 0 +0xF08E 0x995A # 0 +0xF08F 0x995B # 0 +0xF090 0x995C # 0 +0xF091 0x995D # 0 +0xF092 0x995E # 0 +0xF093 0x995F # 0 +0xF094 0x9960 # 0 +0xF095 0x9961 # 0 +0xF096 0x9962 # 0 +0xF097 0x9964 # 0 +0xF098 0x9966 # 0 +0xF099 0x9973 # 0 +0xF09A 0x9978 # 0 +0xF09B 0x9979 # 0 +0xF09C 0x997B # 0 +0xF09D 0x997E # 0 +0xF09E 0x9982 # 0 +0xF09F 0x9983 # 0 +0xF0A0 0x9989 # 0 +0xF0A1 0x7A39 # 0 +0xF0A2 0x7A37 # 0 +0xF0A3 0x7A51 # 0 +0xF0A4 0x9ECF # 0 +0xF0A5 0x99A5 # 0 +0xF0A6 0x7A70 # 0 +0xF0A7 0x7688 # 0 +0xF0A8 0x768E # 0 +0xF0A9 0x7693 # 0 +0xF0AA 0x7699 # 0 +0xF0AB 0x76A4 # 0 +0xF0AC 0x74DE # 0 +0xF0AD 0x74E0 # 0 +0xF0AE 0x752C # 0 +0xF0AF 0x9E20 # 0 +0xF0B0 0x9E22 # 0 +0xF0B1 0x9E28 # 0 +0xF0B2 0x9E29 # 0 +0xF0B3 0x9E2A # 0 +0xF0B4 0x9E2B # 0 +0xF0B5 0x9E2C # 0 +0xF0B6 0x9E32 # 0 +0xF0B7 0x9E31 # 0 +0xF0B8 0x9E36 # 0 +0xF0B9 0x9E38 # 0 +0xF0BA 0x9E37 # 0 +0xF0BB 0x9E39 # 0 +0xF0BC 0x9E3A # 0 +0xF0BD 0x9E3E # 0 +0xF0BE 0x9E41 # 0 +0xF0BF 0x9E42 # 0 +0xF0C0 0x9E44 # 0 +0xF0C1 0x9E46 # 0 +0xF0C2 0x9E47 # 0 +0xF0C3 0x9E48 # 0 +0xF0C4 0x9E49 # 0 +0xF0C5 0x9E4B # 0 +0xF0C6 0x9E4C # 0 +0xF0C7 0x9E4E # 0 +0xF0C8 0x9E51 # 0 +0xF0C9 0x9E55 # 0 +0xF0CA 0x9E57 # 0 +0xF0CB 0x9E5A # 0 +0xF0CC 0x9E5B # 0 +0xF0CD 0x9E5C # 0 +0xF0CE 0x9E5E # 0 +0xF0CF 0x9E63 # 0 +0xF0D0 0x9E66 # 0 +0xF0D1 0x9E67 # 0 +0xF0D2 0x9E68 # 0 +0xF0D3 0x9E69 # 0 +0xF0D4 0x9E6A # 0 +0xF0D5 0x9E6B # 0 +0xF0D6 0x9E6C # 0 +0xF0D7 0x9E71 # 0 +0xF0D8 0x9E6D # 0 +0xF0D9 0x9E73 # 0 +0xF0DA 0x7592 # 0 +0xF0DB 0x7594 # 0 +0xF0DC 0x7596 # 0 +0xF0DD 0x75A0 # 0 +0xF0DE 0x759D # 0 +0xF0DF 0x75AC # 0 +0xF0E0 0x75A3 # 0 +0xF0E1 0x75B3 # 0 +0xF0E2 0x75B4 # 0 +0xF0E3 0x75B8 # 0 +0xF0E4 0x75C4 # 0 +0xF0E5 0x75B1 # 0 +0xF0E6 0x75B0 # 0 +0xF0E7 0x75C3 # 0 +0xF0E8 0x75C2 # 0 +0xF0E9 0x75D6 # 0 +0xF0EA 0x75CD # 0 +0xF0EB 0x75E3 # 0 +0xF0EC 0x75E8 # 0 +0xF0ED 0x75E6 # 0 +0xF0EE 0x75E4 # 0 +0xF0EF 0x75EB # 0 +0xF0F0 0x75E7 # 0 +0xF0F1 0x7603 # 0 +0xF0F2 0x75F1 # 0 +0xF0F3 0x75FC # 0 +0xF0F4 0x75FF # 0 +0xF0F5 0x7610 # 0 +0xF0F6 0x7600 # 0 +0xF0F7 0x7605 # 0 +0xF0F8 0x760C # 0 +0xF0F9 0x7617 # 0 +0xF0FA 0x760A # 0 +0xF0FB 0x7625 # 0 +0xF0FC 0x7618 # 0 +0xF0FD 0x7615 # 0 +0xF0FE 0x7619 # 0 +0xF140 0x998C # 0 +0xF141 0x998E # 0 +0xF142 0x999A # 0 +0xF143 0x999B # 0 +0xF144 0x999C # 0 +0xF145 0x999D # 0 +0xF146 0x999E # 0 +0xF147 0x999F # 0 +0xF148 0x99A0 # 0 +0xF149 0x99A1 # 0 +0xF14A 0x99A2 # 0 +0xF14B 0x99A3 # 0 +0xF14C 0x99A4 # 0 +0xF14D 0x99A6 # 0 +0xF14E 0x99A7 # 0 +0xF14F 0x99A9 # 0 +0xF150 0x99AA # 0 +0xF151 0x99AB # 0 +0xF152 0x99AC # 0 +0xF153 0x99AD # 0 +0xF154 0x99AE # 0 +0xF155 0x99AF # 0 +0xF156 0x99B0 # 0 +0xF157 0x99B1 # 0 +0xF158 0x99B2 # 0 +0xF159 0x99B3 # 0 +0xF15A 0x99B4 # 0 +0xF15B 0x99B5 # 0 +0xF15C 0x99B6 # 0 +0xF15D 0x99B7 # 0 +0xF15E 0x99B8 # 0 +0xF15F 0x99B9 # 0 +0xF160 0x99BA # 0 +0xF161 0x99BB # 0 +0xF162 0x99BC # 0 +0xF163 0x99BD # 0 +0xF164 0x99BE # 0 +0xF165 0x99BF # 0 +0xF166 0x99C0 # 0 +0xF167 0x99C1 # 0 +0xF168 0x99C2 # 0 +0xF169 0x99C3 # 0 +0xF16A 0x99C4 # 0 +0xF16B 0x99C5 # 0 +0xF16C 0x99C6 # 0 +0xF16D 0x99C7 # 0 +0xF16E 0x99C8 # 0 +0xF16F 0x99C9 # 0 +0xF170 0x99CA # 0 +0xF171 0x99CB # 0 +0xF172 0x99CC # 0 +0xF173 0x99CD # 0 +0xF174 0x99CE # 0 +0xF175 0x99CF # 0 +0xF176 0x99D0 # 0 +0xF177 0x99D1 # 0 +0xF178 0x99D2 # 0 +0xF179 0x99D3 # 0 +0xF17A 0x99D4 # 0 +0xF17B 0x99D5 # 0 +0xF17C 0x99D6 # 0 +0xF17D 0x99D7 # 0 +0xF17E 0x99D8 # 0 +0xF180 0x99D9 # 0 +0xF181 0x99DA # 0 +0xF182 0x99DB # 0 +0xF183 0x99DC # 0 +0xF184 0x99DD # 0 +0xF185 0x99DE # 0 +0xF186 0x99DF # 0 +0xF187 0x99E0 # 0 +0xF188 0x99E1 # 0 +0xF189 0x99E2 # 0 +0xF18A 0x99E3 # 0 +0xF18B 0x99E4 # 0 +0xF18C 0x99E5 # 0 +0xF18D 0x99E6 # 0 +0xF18E 0x99E7 # 0 +0xF18F 0x99E8 # 0 +0xF190 0x99E9 # 0 +0xF191 0x99EA # 0 +0xF192 0x99EB # 0 +0xF193 0x99EC # 0 +0xF194 0x99ED # 0 +0xF195 0x99EE # 0 +0xF196 0x99EF # 0 +0xF197 0x99F0 # 0 +0xF198 0x99F1 # 0 +0xF199 0x99F2 # 0 +0xF19A 0x99F3 # 0 +0xF19B 0x99F4 # 0 +0xF19C 0x99F5 # 0 +0xF19D 0x99F6 # 0 +0xF19E 0x99F7 # 0 +0xF19F 0x99F8 # 0 +0xF1A0 0x99F9 # 0 +0xF1A1 0x761B # 0 +0xF1A2 0x763C # 0 +0xF1A3 0x7622 # 0 +0xF1A4 0x7620 # 0 +0xF1A5 0x7640 # 0 +0xF1A6 0x762D # 0 +0xF1A7 0x7630 # 0 +0xF1A8 0x763F # 0 +0xF1A9 0x7635 # 0 +0xF1AA 0x7643 # 0 +0xF1AB 0x763E # 0 +0xF1AC 0x7633 # 0 +0xF1AD 0x764D # 0 +0xF1AE 0x765E # 0 +0xF1AF 0x7654 # 0 +0xF1B0 0x765C # 0 +0xF1B1 0x7656 # 0 +0xF1B2 0x766B # 0 +0xF1B3 0x766F # 0 +0xF1B4 0x7FCA # 0 +0xF1B5 0x7AE6 # 0 +0xF1B6 0x7A78 # 0 +0xF1B7 0x7A79 # 0 +0xF1B8 0x7A80 # 0 +0xF1B9 0x7A86 # 0 +0xF1BA 0x7A88 # 0 +0xF1BB 0x7A95 # 0 +0xF1BC 0x7AA6 # 0 +0xF1BD 0x7AA0 # 0 +0xF1BE 0x7AAC # 0 +0xF1BF 0x7AA8 # 0 +0xF1C0 0x7AAD # 0 +0xF1C1 0x7AB3 # 0 +0xF1C2 0x8864 # 0 +0xF1C3 0x8869 # 0 +0xF1C4 0x8872 # 0 +0xF1C5 0x887D # 0 +0xF1C6 0x887F # 0 +0xF1C7 0x8882 # 0 +0xF1C8 0x88A2 # 0 +0xF1C9 0x88C6 # 0 +0xF1CA 0x88B7 # 0 +0xF1CB 0x88BC # 0 +0xF1CC 0x88C9 # 0 +0xF1CD 0x88E2 # 0 +0xF1CE 0x88CE # 0 +0xF1CF 0x88E3 # 0 +0xF1D0 0x88E5 # 0 +0xF1D1 0x88F1 # 0 +0xF1D2 0x891A # 0 +0xF1D3 0x88FC # 0 +0xF1D4 0x88E8 # 0 +0xF1D5 0x88FE # 0 +0xF1D6 0x88F0 # 0 +0xF1D7 0x8921 # 0 +0xF1D8 0x8919 # 0 +0xF1D9 0x8913 # 0 +0xF1DA 0x891B # 0 +0xF1DB 0x890A # 0 +0xF1DC 0x8934 # 0 +0xF1DD 0x892B # 0 +0xF1DE 0x8936 # 0 +0xF1DF 0x8941 # 0 +0xF1E0 0x8966 # 0 +0xF1E1 0x897B # 0 +0xF1E2 0x758B # 0 +0xF1E3 0x80E5 # 0 +0xF1E4 0x76B2 # 0 +0xF1E5 0x76B4 # 0 +0xF1E6 0x77DC # 0 +0xF1E7 0x8012 # 0 +0xF1E8 0x8014 # 0 +0xF1E9 0x8016 # 0 +0xF1EA 0x801C # 0 +0xF1EB 0x8020 # 0 +0xF1EC 0x8022 # 0 +0xF1ED 0x8025 # 0 +0xF1EE 0x8026 # 0 +0xF1EF 0x8027 # 0 +0xF1F0 0x8029 # 0 +0xF1F1 0x8028 # 0 +0xF1F2 0x8031 # 0 +0xF1F3 0x800B # 0 +0xF1F4 0x8035 # 0 +0xF1F5 0x8043 # 0 +0xF1F6 0x8046 # 0 +0xF1F7 0x804D # 0 +0xF1F8 0x8052 # 0 +0xF1F9 0x8069 # 0 +0xF1FA 0x8071 # 0 +0xF1FB 0x8983 # 0 +0xF1FC 0x9878 # 0 +0xF1FD 0x9880 # 0 +0xF1FE 0x9883 # 0 +0xF240 0x99FA # 0 +0xF241 0x99FB # 0 +0xF242 0x99FC # 0 +0xF243 0x99FD # 0 +0xF244 0x99FE # 0 +0xF245 0x99FF # 0 +0xF246 0x9A00 # 0 +0xF247 0x9A01 # 0 +0xF248 0x9A02 # 0 +0xF249 0x9A03 # 0 +0xF24A 0x9A04 # 0 +0xF24B 0x9A05 # 0 +0xF24C 0x9A06 # 0 +0xF24D 0x9A07 # 0 +0xF24E 0x9A08 # 0 +0xF24F 0x9A09 # 0 +0xF250 0x9A0A # 0 +0xF251 0x9A0B # 0 +0xF252 0x9A0C # 0 +0xF253 0x9A0D # 0 +0xF254 0x9A0E # 0 +0xF255 0x9A0F # 0 +0xF256 0x9A10 # 0 +0xF257 0x9A11 # 0 +0xF258 0x9A12 # 0 +0xF259 0x9A13 # 0 +0xF25A 0x9A14 # 0 +0xF25B 0x9A15 # 0 +0xF25C 0x9A16 # 0 +0xF25D 0x9A17 # 0 +0xF25E 0x9A18 # 0 +0xF25F 0x9A19 # 0 +0xF260 0x9A1A # 0 +0xF261 0x9A1B # 0 +0xF262 0x9A1C # 0 +0xF263 0x9A1D # 0 +0xF264 0x9A1E # 0 +0xF265 0x9A1F # 0 +0xF266 0x9A20 # 0 +0xF267 0x9A21 # 0 +0xF268 0x9A22 # 0 +0xF269 0x9A23 # 0 +0xF26A 0x9A24 # 0 +0xF26B 0x9A25 # 0 +0xF26C 0x9A26 # 0 +0xF26D 0x9A27 # 0 +0xF26E 0x9A28 # 0 +0xF26F 0x9A29 # 0 +0xF270 0x9A2A # 0 +0xF271 0x9A2B # 0 +0xF272 0x9A2C # 0 +0xF273 0x9A2D # 0 +0xF274 0x9A2E # 0 +0xF275 0x9A2F # 0 +0xF276 0x9A30 # 0 +0xF277 0x9A31 # 0 +0xF278 0x9A32 # 0 +0xF279 0x9A33 # 0 +0xF27A 0x9A34 # 0 +0xF27B 0x9A35 # 0 +0xF27C 0x9A36 # 0 +0xF27D 0x9A37 # 0 +0xF27E 0x9A38 # 0 +0xF280 0x9A39 # 0 +0xF281 0x9A3A # 0 +0xF282 0x9A3B # 0 +0xF283 0x9A3C # 0 +0xF284 0x9A3D # 0 +0xF285 0x9A3E # 0 +0xF286 0x9A3F # 0 +0xF287 0x9A40 # 0 +0xF288 0x9A41 # 0 +0xF289 0x9A42 # 0 +0xF28A 0x9A43 # 0 +0xF28B 0x9A44 # 0 +0xF28C 0x9A45 # 0 +0xF28D 0x9A46 # 0 +0xF28E 0x9A47 # 0 +0xF28F 0x9A48 # 0 +0xF290 0x9A49 # 0 +0xF291 0x9A4A # 0 +0xF292 0x9A4B # 0 +0xF293 0x9A4C # 0 +0xF294 0x9A4D # 0 +0xF295 0x9A4E # 0 +0xF296 0x9A4F # 0 +0xF297 0x9A50 # 0 +0xF298 0x9A51 # 0 +0xF299 0x9A52 # 0 +0xF29A 0x9A53 # 0 +0xF29B 0x9A54 # 0 +0xF29C 0x9A55 # 0 +0xF29D 0x9A56 # 0 +0xF29E 0x9A57 # 0 +0xF29F 0x9A58 # 0 +0xF2A0 0x9A59 # 0 +0xF2A1 0x9889 # 0 +0xF2A2 0x988C # 0 +0xF2A3 0x988D # 0 +0xF2A4 0x988F # 0 +0xF2A5 0x9894 # 0 +0xF2A6 0x989A # 0 +0xF2A7 0x989B # 0 +0xF2A8 0x989E # 0 +0xF2A9 0x989F # 0 +0xF2AA 0x98A1 # 0 +0xF2AB 0x98A2 # 0 +0xF2AC 0x98A5 # 0 +0xF2AD 0x98A6 # 0 +0xF2AE 0x864D # 0 +0xF2AF 0x8654 # 0 +0xF2B0 0x866C # 0 +0xF2B1 0x866E # 0 +0xF2B2 0x867F # 0 +0xF2B3 0x867A # 0 +0xF2B4 0x867C # 0 +0xF2B5 0x867B # 0 +0xF2B6 0x86A8 # 0 +0xF2B7 0x868D # 0 +0xF2B8 0x868B # 0 +0xF2B9 0x86AC # 0 +0xF2BA 0x869D # 0 +0xF2BB 0x86A7 # 0 +0xF2BC 0x86A3 # 0 +0xF2BD 0x86AA # 0 +0xF2BE 0x8693 # 0 +0xF2BF 0x86A9 # 0 +0xF2C0 0x86B6 # 0 +0xF2C1 0x86C4 # 0 +0xF2C2 0x86B5 # 0 +0xF2C3 0x86CE # 0 +0xF2C4 0x86B0 # 0 +0xF2C5 0x86BA # 0 +0xF2C6 0x86B1 # 0 +0xF2C7 0x86AF # 0 +0xF2C8 0x86C9 # 0 +0xF2C9 0x86CF # 0 +0xF2CA 0x86B4 # 0 +0xF2CB 0x86E9 # 0 +0xF2CC 0x86F1 # 0 +0xF2CD 0x86F2 # 0 +0xF2CE 0x86ED # 0 +0xF2CF 0x86F3 # 0 +0xF2D0 0x86D0 # 0 +0xF2D1 0x8713 # 0 +0xF2D2 0x86DE # 0 +0xF2D3 0x86F4 # 0 +0xF2D4 0x86DF # 0 +0xF2D5 0x86D8 # 0 +0xF2D6 0x86D1 # 0 +0xF2D7 0x8703 # 0 +0xF2D8 0x8707 # 0 +0xF2D9 0x86F8 # 0 +0xF2DA 0x8708 # 0 +0xF2DB 0x870A # 0 +0xF2DC 0x870D # 0 +0xF2DD 0x8709 # 0 +0xF2DE 0x8723 # 0 +0xF2DF 0x873B # 0 +0xF2E0 0x871E # 0 +0xF2E1 0x8725 # 0 +0xF2E2 0x872E # 0 +0xF2E3 0x871A # 0 +0xF2E4 0x873E # 0 +0xF2E5 0x8748 # 0 +0xF2E6 0x8734 # 0 +0xF2E7 0x8731 # 0 +0xF2E8 0x8729 # 0 +0xF2E9 0x8737 # 0 +0xF2EA 0x873F # 0 +0xF2EB 0x8782 # 0 +0xF2EC 0x8722 # 0 +0xF2ED 0x877D # 0 +0xF2EE 0x877E # 0 +0xF2EF 0x877B # 0 +0xF2F0 0x8760 # 0 +0xF2F1 0x8770 # 0 +0xF2F2 0x874C # 0 +0xF2F3 0x876E # 0 +0xF2F4 0x878B # 0 +0xF2F5 0x8753 # 0 +0xF2F6 0x8763 # 0 +0xF2F7 0x877C # 0 +0xF2F8 0x8764 # 0 +0xF2F9 0x8759 # 0 +0xF2FA 0x8765 # 0 +0xF2FB 0x8793 # 0 +0xF2FC 0x87AF # 0 +0xF2FD 0x87A8 # 0 +0xF2FE 0x87D2 # 0 +0xF340 0x9A5A # 0 +0xF341 0x9A5B # 0 +0xF342 0x9A5C # 0 +0xF343 0x9A5D # 0 +0xF344 0x9A5E # 0 +0xF345 0x9A5F # 0 +0xF346 0x9A60 # 0 +0xF347 0x9A61 # 0 +0xF348 0x9A62 # 0 +0xF349 0x9A63 # 0 +0xF34A 0x9A64 # 0 +0xF34B 0x9A65 # 0 +0xF34C 0x9A66 # 0 +0xF34D 0x9A67 # 0 +0xF34E 0x9A68 # 0 +0xF34F 0x9A69 # 0 +0xF350 0x9A6A # 0 +0xF351 0x9A6B # 0 +0xF352 0x9A72 # 0 +0xF353 0x9A83 # 0 +0xF354 0x9A89 # 0 +0xF355 0x9A8D # 0 +0xF356 0x9A8E # 0 +0xF357 0x9A94 # 0 +0xF358 0x9A95 # 0 +0xF359 0x9A99 # 0 +0xF35A 0x9AA6 # 0 +0xF35B 0x9AA9 # 0 +0xF35C 0x9AAA # 0 +0xF35D 0x9AAB # 0 +0xF35E 0x9AAC # 0 +0xF35F 0x9AAD # 0 +0xF360 0x9AAE # 0 +0xF361 0x9AAF # 0 +0xF362 0x9AB2 # 0 +0xF363 0x9AB3 # 0 +0xF364 0x9AB4 # 0 +0xF365 0x9AB5 # 0 +0xF366 0x9AB9 # 0 +0xF367 0x9ABB # 0 +0xF368 0x9ABD # 0 +0xF369 0x9ABE # 0 +0xF36A 0x9ABF # 0 +0xF36B 0x9AC3 # 0 +0xF36C 0x9AC4 # 0 +0xF36D 0x9AC6 # 0 +0xF36E 0x9AC7 # 0 +0xF36F 0x9AC8 # 0 +0xF370 0x9AC9 # 0 +0xF371 0x9ACA # 0 +0xF372 0x9ACD # 0 +0xF373 0x9ACE # 0 +0xF374 0x9ACF # 0 +0xF375 0x9AD0 # 0 +0xF376 0x9AD2 # 0 +0xF377 0x9AD4 # 0 +0xF378 0x9AD5 # 0 +0xF379 0x9AD6 # 0 +0xF37A 0x9AD7 # 0 +0xF37B 0x9AD9 # 0 +0xF37C 0x9ADA # 0 +0xF37D 0x9ADB # 0 +0xF37E 0x9ADC # 0 +0xF380 0x9ADD # 0 +0xF381 0x9ADE # 0 +0xF382 0x9AE0 # 0 +0xF383 0x9AE2 # 0 +0xF384 0x9AE3 # 0 +0xF385 0x9AE4 # 0 +0xF386 0x9AE5 # 0 +0xF387 0x9AE7 # 0 +0xF388 0x9AE8 # 0 +0xF389 0x9AE9 # 0 +0xF38A 0x9AEA # 0 +0xF38B 0x9AEC # 0 +0xF38C 0x9AEE # 0 +0xF38D 0x9AF0 # 0 +0xF38E 0x9AF1 # 0 +0xF38F 0x9AF2 # 0 +0xF390 0x9AF3 # 0 +0xF391 0x9AF4 # 0 +0xF392 0x9AF5 # 0 +0xF393 0x9AF6 # 0 +0xF394 0x9AF7 # 0 +0xF395 0x9AF8 # 0 +0xF396 0x9AFA # 0 +0xF397 0x9AFC # 0 +0xF398 0x9AFD # 0 +0xF399 0x9AFE # 0 +0xF39A 0x9AFF # 0 +0xF39B 0x9B00 # 0 +0xF39C 0x9B01 # 0 +0xF39D 0x9B02 # 0 +0xF39E 0x9B04 # 0 +0xF39F 0x9B05 # 0 +0xF3A0 0x9B06 # 0 +0xF3A1 0x87C6 # 0 +0xF3A2 0x8788 # 0 +0xF3A3 0x8785 # 0 +0xF3A4 0x87AD # 0 +0xF3A5 0x8797 # 0 +0xF3A6 0x8783 # 0 +0xF3A7 0x87AB # 0 +0xF3A8 0x87E5 # 0 +0xF3A9 0x87AC # 0 +0xF3AA 0x87B5 # 0 +0xF3AB 0x87B3 # 0 +0xF3AC 0x87CB # 0 +0xF3AD 0x87D3 # 0 +0xF3AE 0x87BD # 0 +0xF3AF 0x87D1 # 0 +0xF3B0 0x87C0 # 0 +0xF3B1 0x87CA # 0 +0xF3B2 0x87DB # 0 +0xF3B3 0x87EA # 0 +0xF3B4 0x87E0 # 0 +0xF3B5 0x87EE # 0 +0xF3B6 0x8816 # 0 +0xF3B7 0x8813 # 0 +0xF3B8 0x87FE # 0 +0xF3B9 0x880A # 0 +0xF3BA 0x881B # 0 +0xF3BB 0x8821 # 0 +0xF3BC 0x8839 # 0 +0xF3BD 0x883C # 0 +0xF3BE 0x7F36 # 0 +0xF3BF 0x7F42 # 0 +0xF3C0 0x7F44 # 0 +0xF3C1 0x7F45 # 0 +0xF3C2 0x8210 # 0 +0xF3C3 0x7AFA # 0 +0xF3C4 0x7AFD # 0 +0xF3C5 0x7B08 # 0 +0xF3C6 0x7B03 # 0 +0xF3C7 0x7B04 # 0 +0xF3C8 0x7B15 # 0 +0xF3C9 0x7B0A # 0 +0xF3CA 0x7B2B # 0 +0xF3CB 0x7B0F # 0 +0xF3CC 0x7B47 # 0 +0xF3CD 0x7B38 # 0 +0xF3CE 0x7B2A # 0 +0xF3CF 0x7B19 # 0 +0xF3D0 0x7B2E # 0 +0xF3D1 0x7B31 # 0 +0xF3D2 0x7B20 # 0 +0xF3D3 0x7B25 # 0 +0xF3D4 0x7B24 # 0 +0xF3D5 0x7B33 # 0 +0xF3D6 0x7B3E # 0 +0xF3D7 0x7B1E # 0 +0xF3D8 0x7B58 # 0 +0xF3D9 0x7B5A # 0 +0xF3DA 0x7B45 # 0 +0xF3DB 0x7B75 # 0 +0xF3DC 0x7B4C # 0 +0xF3DD 0x7B5D # 0 +0xF3DE 0x7B60 # 0 +0xF3DF 0x7B6E # 0 +0xF3E0 0x7B7B # 0 +0xF3E1 0x7B62 # 0 +0xF3E2 0x7B72 # 0 +0xF3E3 0x7B71 # 0 +0xF3E4 0x7B90 # 0 +0xF3E5 0x7BA6 # 0 +0xF3E6 0x7BA7 # 0 +0xF3E7 0x7BB8 # 0 +0xF3E8 0x7BAC # 0 +0xF3E9 0x7B9D # 0 +0xF3EA 0x7BA8 # 0 +0xF3EB 0x7B85 # 0 +0xF3EC 0x7BAA # 0 +0xF3ED 0x7B9C # 0 +0xF3EE 0x7BA2 # 0 +0xF3EF 0x7BAB # 0 +0xF3F0 0x7BB4 # 0 +0xF3F1 0x7BD1 # 0 +0xF3F2 0x7BC1 # 0 +0xF3F3 0x7BCC # 0 +0xF3F4 0x7BDD # 0 +0xF3F5 0x7BDA # 0 +0xF3F6 0x7BE5 # 0 +0xF3F7 0x7BE6 # 0 +0xF3F8 0x7BEA # 0 +0xF3F9 0x7C0C # 0 +0xF3FA 0x7BFE # 0 +0xF3FB 0x7BFC # 0 +0xF3FC 0x7C0F # 0 +0xF3FD 0x7C16 # 0 +0xF3FE 0x7C0B # 0 +0xF440 0x9B07 # 0 +0xF441 0x9B09 # 0 +0xF442 0x9B0A # 0 +0xF443 0x9B0B # 0 +0xF444 0x9B0C # 0 +0xF445 0x9B0D # 0 +0xF446 0x9B0E # 0 +0xF447 0x9B10 # 0 +0xF448 0x9B11 # 0 +0xF449 0x9B12 # 0 +0xF44A 0x9B14 # 0 +0xF44B 0x9B15 # 0 +0xF44C 0x9B16 # 0 +0xF44D 0x9B17 # 0 +0xF44E 0x9B18 # 0 +0xF44F 0x9B19 # 0 +0xF450 0x9B1A # 0 +0xF451 0x9B1B # 0 +0xF452 0x9B1C # 0 +0xF453 0x9B1D # 0 +0xF454 0x9B1E # 0 +0xF455 0x9B20 # 0 +0xF456 0x9B21 # 0 +0xF457 0x9B22 # 0 +0xF458 0x9B24 # 0 +0xF459 0x9B25 # 0 +0xF45A 0x9B26 # 0 +0xF45B 0x9B27 # 0 +0xF45C 0x9B28 # 0 +0xF45D 0x9B29 # 0 +0xF45E 0x9B2A # 0 +0xF45F 0x9B2B # 0 +0xF460 0x9B2C # 0 +0xF461 0x9B2D # 0 +0xF462 0x9B2E # 0 +0xF463 0x9B30 # 0 +0xF464 0x9B31 # 0 +0xF465 0x9B33 # 0 +0xF466 0x9B34 # 0 +0xF467 0x9B35 # 0 +0xF468 0x9B36 # 0 +0xF469 0x9B37 # 0 +0xF46A 0x9B38 # 0 +0xF46B 0x9B39 # 0 +0xF46C 0x9B3A # 0 +0xF46D 0x9B3D # 0 +0xF46E 0x9B3E # 0 +0xF46F 0x9B3F # 0 +0xF470 0x9B40 # 0 +0xF471 0x9B46 # 0 +0xF472 0x9B4A # 0 +0xF473 0x9B4B # 0 +0xF474 0x9B4C # 0 +0xF475 0x9B4E # 0 +0xF476 0x9B50 # 0 +0xF477 0x9B52 # 0 +0xF478 0x9B53 # 0 +0xF479 0x9B55 # 0 +0xF47A 0x9B56 # 0 +0xF47B 0x9B57 # 0 +0xF47C 0x9B58 # 0 +0xF47D 0x9B59 # 0 +0xF47E 0x9B5A # 0 +0xF480 0x9B5B # 0 +0xF481 0x9B5C # 0 +0xF482 0x9B5D # 0 +0xF483 0x9B5E # 0 +0xF484 0x9B5F # 0 +0xF485 0x9B60 # 0 +0xF486 0x9B61 # 0 +0xF487 0x9B62 # 0 +0xF488 0x9B63 # 0 +0xF489 0x9B64 # 0 +0xF48A 0x9B65 # 0 +0xF48B 0x9B66 # 0 +0xF48C 0x9B67 # 0 +0xF48D 0x9B68 # 0 +0xF48E 0x9B69 # 0 +0xF48F 0x9B6A # 0 +0xF490 0x9B6B # 0 +0xF491 0x9B6C # 0 +0xF492 0x9B6D # 0 +0xF493 0x9B6E # 0 +0xF494 0x9B6F # 0 +0xF495 0x9B70 # 0 +0xF496 0x9B71 # 0 +0xF497 0x9B72 # 0 +0xF498 0x9B73 # 0 +0xF499 0x9B74 # 0 +0xF49A 0x9B75 # 0 +0xF49B 0x9B76 # 0 +0xF49C 0x9B77 # 0 +0xF49D 0x9B78 # 0 +0xF49E 0x9B79 # 0 +0xF49F 0x9B7A # 0 +0xF4A0 0x9B7B # 0 +0xF4A1 0x7C1F # 0 +0xF4A2 0x7C2A # 0 +0xF4A3 0x7C26 # 0 +0xF4A4 0x7C38 # 0 +0xF4A5 0x7C41 # 0 +0xF4A6 0x7C40 # 0 +0xF4A7 0x81FE # 0 +0xF4A8 0x8201 # 0 +0xF4A9 0x8202 # 0 +0xF4AA 0x8204 # 0 +0xF4AB 0x81EC # 0 +0xF4AC 0x8844 # 0 +0xF4AD 0x8221 # 0 +0xF4AE 0x8222 # 0 +0xF4AF 0x8223 # 0 +0xF4B0 0x822D # 0 +0xF4B1 0x822F # 0 +0xF4B2 0x8228 # 0 +0xF4B3 0x822B # 0 +0xF4B4 0x8238 # 0 +0xF4B5 0x823B # 0 +0xF4B6 0x8233 # 0 +0xF4B7 0x8234 # 0 +0xF4B8 0x823E # 0 +0xF4B9 0x8244 # 0 +0xF4BA 0x8249 # 0 +0xF4BB 0x824B # 0 +0xF4BC 0x824F # 0 +0xF4BD 0x825A # 0 +0xF4BE 0x825F # 0 +0xF4BF 0x8268 # 0 +0xF4C0 0x887E # 0 +0xF4C1 0x8885 # 0 +0xF4C2 0x8888 # 0 +0xF4C3 0x88D8 # 0 +0xF4C4 0x88DF # 0 +0xF4C5 0x895E # 0 +0xF4C6 0x7F9D # 0 +0xF4C7 0x7F9F # 0 +0xF4C8 0x7FA7 # 0 +0xF4C9 0x7FAF # 0 +0xF4CA 0x7FB0 # 0 +0xF4CB 0x7FB2 # 0 +0xF4CC 0x7C7C # 0 +0xF4CD 0x6549 # 0 +0xF4CE 0x7C91 # 0 +0xF4CF 0x7C9D # 0 +0xF4D0 0x7C9C # 0 +0xF4D1 0x7C9E # 0 +0xF4D2 0x7CA2 # 0 +0xF4D3 0x7CB2 # 0 +0xF4D4 0x7CBC # 0 +0xF4D5 0x7CBD # 0 +0xF4D6 0x7CC1 # 0 +0xF4D7 0x7CC7 # 0 +0xF4D8 0x7CCC # 0 +0xF4D9 0x7CCD # 0 +0xF4DA 0x7CC8 # 0 +0xF4DB 0x7CC5 # 0 +0xF4DC 0x7CD7 # 0 +0xF4DD 0x7CE8 # 0 +0xF4DE 0x826E # 0 +0xF4DF 0x66A8 # 0 +0xF4E0 0x7FBF # 0 +0xF4E1 0x7FCE # 0 +0xF4E2 0x7FD5 # 0 +0xF4E3 0x7FE5 # 0 +0xF4E4 0x7FE1 # 0 +0xF4E5 0x7FE6 # 0 +0xF4E6 0x7FE9 # 0 +0xF4E7 0x7FEE # 0 +0xF4E8 0x7FF3 # 0 +0xF4E9 0x7CF8 # 0 +0xF4EA 0x7D77 # 0 +0xF4EB 0x7DA6 # 0 +0xF4EC 0x7DAE # 0 +0xF4ED 0x7E47 # 0 +0xF4EE 0x7E9B # 0 +0xF4EF 0x9EB8 # 0 +0xF4F0 0x9EB4 # 0 +0xF4F1 0x8D73 # 0 +0xF4F2 0x8D84 # 0 +0xF4F3 0x8D94 # 0 +0xF4F4 0x8D91 # 0 +0xF4F5 0x8DB1 # 0 +0xF4F6 0x8D67 # 0 +0xF4F7 0x8D6D # 0 +0xF4F8 0x8C47 # 0 +0xF4F9 0x8C49 # 0 +0xF4FA 0x914A # 0 +0xF4FB 0x9150 # 0 +0xF4FC 0x914E # 0 +0xF4FD 0x914F # 0 +0xF4FE 0x9164 # 0 +0xF540 0x9B7C # 0 +0xF541 0x9B7D # 0 +0xF542 0x9B7E # 0 +0xF543 0x9B7F # 0 +0xF544 0x9B80 # 0 +0xF545 0x9B81 # 0 +0xF546 0x9B82 # 0 +0xF547 0x9B83 # 0 +0xF548 0x9B84 # 0 +0xF549 0x9B85 # 0 +0xF54A 0x9B86 # 0 +0xF54B 0x9B87 # 0 +0xF54C 0x9B88 # 0 +0xF54D 0x9B89 # 0 +0xF54E 0x9B8A # 0 +0xF54F 0x9B8B # 0 +0xF550 0x9B8C # 0 +0xF551 0x9B8D # 0 +0xF552 0x9B8E # 0 +0xF553 0x9B8F # 0 +0xF554 0x9B90 # 0 +0xF555 0x9B91 # 0 +0xF556 0x9B92 # 0 +0xF557 0x9B93 # 0 +0xF558 0x9B94 # 0 +0xF559 0x9B95 # 0 +0xF55A 0x9B96 # 0 +0xF55B 0x9B97 # 0 +0xF55C 0x9B98 # 0 +0xF55D 0x9B99 # 0 +0xF55E 0x9B9A # 0 +0xF55F 0x9B9B # 0 +0xF560 0x9B9C # 0 +0xF561 0x9B9D # 0 +0xF562 0x9B9E # 0 +0xF563 0x9B9F # 0 +0xF564 0x9BA0 # 0 +0xF565 0x9BA1 # 0 +0xF566 0x9BA2 # 0 +0xF567 0x9BA3 # 0 +0xF568 0x9BA4 # 0 +0xF569 0x9BA5 # 0 +0xF56A 0x9BA6 # 0 +0xF56B 0x9BA7 # 0 +0xF56C 0x9BA8 # 0 +0xF56D 0x9BA9 # 0 +0xF56E 0x9BAA # 0 +0xF56F 0x9BAB # 0 +0xF570 0x9BAC # 0 +0xF571 0x9BAD # 0 +0xF572 0x9BAE # 0 +0xF573 0x9BAF # 0 +0xF574 0x9BB0 # 0 +0xF575 0x9BB1 # 0 +0xF576 0x9BB2 # 0 +0xF577 0x9BB3 # 0 +0xF578 0x9BB4 # 0 +0xF579 0x9BB5 # 0 +0xF57A 0x9BB6 # 0 +0xF57B 0x9BB7 # 0 +0xF57C 0x9BB8 # 0 +0xF57D 0x9BB9 # 0 +0xF57E 0x9BBA # 0 +0xF580 0x9BBB # 0 +0xF581 0x9BBC # 0 +0xF582 0x9BBD # 0 +0xF583 0x9BBE # 0 +0xF584 0x9BBF # 0 +0xF585 0x9BC0 # 0 +0xF586 0x9BC1 # 0 +0xF587 0x9BC2 # 0 +0xF588 0x9BC3 # 0 +0xF589 0x9BC4 # 0 +0xF58A 0x9BC5 # 0 +0xF58B 0x9BC6 # 0 +0xF58C 0x9BC7 # 0 +0xF58D 0x9BC8 # 0 +0xF58E 0x9BC9 # 0 +0xF58F 0x9BCA # 0 +0xF590 0x9BCB # 0 +0xF591 0x9BCC # 0 +0xF592 0x9BCD # 0 +0xF593 0x9BCE # 0 +0xF594 0x9BCF # 0 +0xF595 0x9BD0 # 0 +0xF596 0x9BD1 # 0 +0xF597 0x9BD2 # 0 +0xF598 0x9BD3 # 0 +0xF599 0x9BD4 # 0 +0xF59A 0x9BD5 # 0 +0xF59B 0x9BD6 # 0 +0xF59C 0x9BD7 # 0 +0xF59D 0x9BD8 # 0 +0xF59E 0x9BD9 # 0 +0xF59F 0x9BDA # 0 +0xF5A0 0x9BDB # 0 +0xF5A1 0x9162 # 0 +0xF5A2 0x9161 # 0 +0xF5A3 0x9170 # 0 +0xF5A4 0x9169 # 0 +0xF5A5 0x916F # 0 +0xF5A6 0x917D # 0 +0xF5A7 0x917E # 0 +0xF5A8 0x9172 # 0 +0xF5A9 0x9174 # 0 +0xF5AA 0x9179 # 0 +0xF5AB 0x918C # 0 +0xF5AC 0x9185 # 0 +0xF5AD 0x9190 # 0 +0xF5AE 0x918D # 0 +0xF5AF 0x9191 # 0 +0xF5B0 0x91A2 # 0 +0xF5B1 0x91A3 # 0 +0xF5B2 0x91AA # 0 +0xF5B3 0x91AD # 0 +0xF5B4 0x91AE # 0 +0xF5B5 0x91AF # 0 +0xF5B6 0x91B5 # 0 +0xF5B7 0x91B4 # 0 +0xF5B8 0x91BA # 0 +0xF5B9 0x8C55 # 0 +0xF5BA 0x9E7E # 0 +0xF5BB 0x8DB8 # 0 +0xF5BC 0x8DEB # 0 +0xF5BD 0x8E05 # 0 +0xF5BE 0x8E59 # 0 +0xF5BF 0x8E69 # 0 +0xF5C0 0x8DB5 # 0 +0xF5C1 0x8DBF # 0 +0xF5C2 0x8DBC # 0 +0xF5C3 0x8DBA # 0 +0xF5C4 0x8DC4 # 0 +0xF5C5 0x8DD6 # 0 +0xF5C6 0x8DD7 # 0 +0xF5C7 0x8DDA # 0 +0xF5C8 0x8DDE # 0 +0xF5C9 0x8DCE # 0 +0xF5CA 0x8DCF # 0 +0xF5CB 0x8DDB # 0 +0xF5CC 0x8DC6 # 0 +0xF5CD 0x8DEC # 0 +0xF5CE 0x8DF7 # 0 +0xF5CF 0x8DF8 # 0 +0xF5D0 0x8DE3 # 0 +0xF5D1 0x8DF9 # 0 +0xF5D2 0x8DFB # 0 +0xF5D3 0x8DE4 # 0 +0xF5D4 0x8E09 # 0 +0xF5D5 0x8DFD # 0 +0xF5D6 0x8E14 # 0 +0xF5D7 0x8E1D # 0 +0xF5D8 0x8E1F # 0 +0xF5D9 0x8E2C # 0 +0xF5DA 0x8E2E # 0 +0xF5DB 0x8E23 # 0 +0xF5DC 0x8E2F # 0 +0xF5DD 0x8E3A # 0 +0xF5DE 0x8E40 # 0 +0xF5DF 0x8E39 # 0 +0xF5E0 0x8E35 # 0 +0xF5E1 0x8E3D # 0 +0xF5E2 0x8E31 # 0 +0xF5E3 0x8E49 # 0 +0xF5E4 0x8E41 # 0 +0xF5E5 0x8E42 # 0 +0xF5E6 0x8E51 # 0 +0xF5E7 0x8E52 # 0 +0xF5E8 0x8E4A # 0 +0xF5E9 0x8E70 # 0 +0xF5EA 0x8E76 # 0 +0xF5EB 0x8E7C # 0 +0xF5EC 0x8E6F # 0 +0xF5ED 0x8E74 # 0 +0xF5EE 0x8E85 # 0 +0xF5EF 0x8E8F # 0 +0xF5F0 0x8E94 # 0 +0xF5F1 0x8E90 # 0 +0xF5F2 0x8E9C # 0 +0xF5F3 0x8E9E # 0 +0xF5F4 0x8C78 # 0 +0xF5F5 0x8C82 # 0 +0xF5F6 0x8C8A # 0 +0xF5F7 0x8C85 # 0 +0xF5F8 0x8C98 # 0 +0xF5F9 0x8C94 # 0 +0xF5FA 0x659B # 0 +0xF5FB 0x89D6 # 0 +0xF5FC 0x89DE # 0 +0xF5FD 0x89DA # 0 +0xF5FE 0x89DC # 0 +0xF640 0x9BDC # 0 +0xF641 0x9BDD # 0 +0xF642 0x9BDE # 0 +0xF643 0x9BDF # 0 +0xF644 0x9BE0 # 0 +0xF645 0x9BE1 # 0 +0xF646 0x9BE2 # 0 +0xF647 0x9BE3 # 0 +0xF648 0x9BE4 # 0 +0xF649 0x9BE5 # 0 +0xF64A 0x9BE6 # 0 +0xF64B 0x9BE7 # 0 +0xF64C 0x9BE8 # 0 +0xF64D 0x9BE9 # 0 +0xF64E 0x9BEA # 0 +0xF64F 0x9BEB # 0 +0xF650 0x9BEC # 0 +0xF651 0x9BED # 0 +0xF652 0x9BEE # 0 +0xF653 0x9BEF # 0 +0xF654 0x9BF0 # 0 +0xF655 0x9BF1 # 0 +0xF656 0x9BF2 # 0 +0xF657 0x9BF3 # 0 +0xF658 0x9BF4 # 0 +0xF659 0x9BF5 # 0 +0xF65A 0x9BF6 # 0 +0xF65B 0x9BF7 # 0 +0xF65C 0x9BF8 # 0 +0xF65D 0x9BF9 # 0 +0xF65E 0x9BFA # 0 +0xF65F 0x9BFB # 0 +0xF660 0x9BFC # 0 +0xF661 0x9BFD # 0 +0xF662 0x9BFE # 0 +0xF663 0x9BFF # 0 +0xF664 0x9C00 # 0 +0xF665 0x9C01 # 0 +0xF666 0x9C02 # 0 +0xF667 0x9C03 # 0 +0xF668 0x9C04 # 0 +0xF669 0x9C05 # 0 +0xF66A 0x9C06 # 0 +0xF66B 0x9C07 # 0 +0xF66C 0x9C08 # 0 +0xF66D 0x9C09 # 0 +0xF66E 0x9C0A # 0 +0xF66F 0x9C0B # 0 +0xF670 0x9C0C # 0 +0xF671 0x9C0D # 0 +0xF672 0x9C0E # 0 +0xF673 0x9C0F # 0 +0xF674 0x9C10 # 0 +0xF675 0x9C11 # 0 +0xF676 0x9C12 # 0 +0xF677 0x9C13 # 0 +0xF678 0x9C14 # 0 +0xF679 0x9C15 # 0 +0xF67A 0x9C16 # 0 +0xF67B 0x9C17 # 0 +0xF67C 0x9C18 # 0 +0xF67D 0x9C19 # 0 +0xF67E 0x9C1A # 0 +0xF680 0x9C1B # 0 +0xF681 0x9C1C # 0 +0xF682 0x9C1D # 0 +0xF683 0x9C1E # 0 +0xF684 0x9C1F # 0 +0xF685 0x9C20 # 0 +0xF686 0x9C21 # 0 +0xF687 0x9C22 # 0 +0xF688 0x9C23 # 0 +0xF689 0x9C24 # 0 +0xF68A 0x9C25 # 0 +0xF68B 0x9C26 # 0 +0xF68C 0x9C27 # 0 +0xF68D 0x9C28 # 0 +0xF68E 0x9C29 # 0 +0xF68F 0x9C2A # 0 +0xF690 0x9C2B # 0 +0xF691 0x9C2C # 0 +0xF692 0x9C2D # 0 +0xF693 0x9C2E # 0 +0xF694 0x9C2F # 0 +0xF695 0x9C30 # 0 +0xF696 0x9C31 # 0 +0xF697 0x9C32 # 0 +0xF698 0x9C33 # 0 +0xF699 0x9C34 # 0 +0xF69A 0x9C35 # 0 +0xF69B 0x9C36 # 0 +0xF69C 0x9C37 # 0 +0xF69D 0x9C38 # 0 +0xF69E 0x9C39 # 0 +0xF69F 0x9C3A # 0 +0xF6A0 0x9C3B # 0 +0xF6A1 0x89E5 # 0 +0xF6A2 0x89EB # 0 +0xF6A3 0x89EF # 0 +0xF6A4 0x8A3E # 0 +0xF6A5 0x8B26 # 0 +0xF6A6 0x9753 # 0 +0xF6A7 0x96E9 # 0 +0xF6A8 0x96F3 # 0 +0xF6A9 0x96EF # 0 +0xF6AA 0x9706 # 0 +0xF6AB 0x9701 # 0 +0xF6AC 0x9708 # 0 +0xF6AD 0x970F # 0 +0xF6AE 0x970E # 0 +0xF6AF 0x972A # 0 +0xF6B0 0x972D # 0 +0xF6B1 0x9730 # 0 +0xF6B2 0x973E # 0 +0xF6B3 0x9F80 # 0 +0xF6B4 0x9F83 # 0 +0xF6B5 0x9F85 # 0 +0xF6B6 0x9F86 # 0 +0xF6B7 0x9F87 # 0 +0xF6B8 0x9F88 # 0 +0xF6B9 0x9F89 # 0 +0xF6BA 0x9F8A # 0 +0xF6BB 0x9F8C # 0 +0xF6BC 0x9EFE # 0 +0xF6BD 0x9F0B # 0 +0xF6BE 0x9F0D # 0 +0xF6BF 0x96B9 # 0 +0xF6C0 0x96BC # 0 +0xF6C1 0x96BD # 0 +0xF6C2 0x96CE # 0 +0xF6C3 0x96D2 # 0 +0xF6C4 0x77BF # 0 +0xF6C5 0x96E0 # 0 +0xF6C6 0x928E # 0 +0xF6C7 0x92AE # 0 +0xF6C8 0x92C8 # 0 +0xF6C9 0x933E # 0 +0xF6CA 0x936A # 0 +0xF6CB 0x93CA # 0 +0xF6CC 0x938F # 0 +0xF6CD 0x943E # 0 +0xF6CE 0x946B # 0 +0xF6CF 0x9C7F # 0 +0xF6D0 0x9C82 # 0 +0xF6D1 0x9C85 # 0 +0xF6D2 0x9C86 # 0 +0xF6D3 0x9C87 # 0 +0xF6D4 0x9C88 # 0 +0xF6D5 0x7A23 # 0 +0xF6D6 0x9C8B # 0 +0xF6D7 0x9C8E # 0 +0xF6D8 0x9C90 # 0 +0xF6D9 0x9C91 # 0 +0xF6DA 0x9C92 # 0 +0xF6DB 0x9C94 # 0 +0xF6DC 0x9C95 # 0 +0xF6DD 0x9C9A # 0 +0xF6DE 0x9C9B # 0 +0xF6DF 0x9C9E # 0 +0xF6E0 0x9C9F # 0 +0xF6E1 0x9CA0 # 0 +0xF6E2 0x9CA1 # 0 +0xF6E3 0x9CA2 # 0 +0xF6E4 0x9CA3 # 0 +0xF6E5 0x9CA5 # 0 +0xF6E6 0x9CA6 # 0 +0xF6E7 0x9CA7 # 0 +0xF6E8 0x9CA8 # 0 +0xF6E9 0x9CA9 # 0 +0xF6EA 0x9CAB # 0 +0xF6EB 0x9CAD # 0 +0xF6EC 0x9CAE # 0 +0xF6ED 0x9CB0 # 0 +0xF6EE 0x9CB1 # 0 +0xF6EF 0x9CB2 # 0 +0xF6F0 0x9CB3 # 0 +0xF6F1 0x9CB4 # 0 +0xF6F2 0x9CB5 # 0 +0xF6F3 0x9CB6 # 0 +0xF6F4 0x9CB7 # 0 +0xF6F5 0x9CBA # 0 +0xF6F6 0x9CBB # 0 +0xF6F7 0x9CBC # 0 +0xF6F8 0x9CBD # 0 +0xF6F9 0x9CC4 # 0 +0xF6FA 0x9CC5 # 0 +0xF6FB 0x9CC6 # 0 +0xF6FC 0x9CC7 # 0 +0xF6FD 0x9CCA # 0 +0xF6FE 0x9CCB # 0 +0xF740 0x9C3C # 0 +0xF741 0x9C3D # 0 +0xF742 0x9C3E # 0 +0xF743 0x9C3F # 0 +0xF744 0x9C40 # 0 +0xF745 0x9C41 # 0 +0xF746 0x9C42 # 0 +0xF747 0x9C43 # 0 +0xF748 0x9C44 # 0 +0xF749 0x9C45 # 0 +0xF74A 0x9C46 # 0 +0xF74B 0x9C47 # 0 +0xF74C 0x9C48 # 0 +0xF74D 0x9C49 # 0 +0xF74E 0x9C4A # 0 +0xF74F 0x9C4B # 0 +0xF750 0x9C4C # 0 +0xF751 0x9C4D # 0 +0xF752 0x9C4E # 0 +0xF753 0x9C4F # 0 +0xF754 0x9C50 # 0 +0xF755 0x9C51 # 0 +0xF756 0x9C52 # 0 +0xF757 0x9C53 # 0 +0xF758 0x9C54 # 0 +0xF759 0x9C55 # 0 +0xF75A 0x9C56 # 0 +0xF75B 0x9C57 # 0 +0xF75C 0x9C58 # 0 +0xF75D 0x9C59 # 0 +0xF75E 0x9C5A # 0 +0xF75F 0x9C5B # 0 +0xF760 0x9C5C # 0 +0xF761 0x9C5D # 0 +0xF762 0x9C5E # 0 +0xF763 0x9C5F # 0 +0xF764 0x9C60 # 0 +0xF765 0x9C61 # 0 +0xF766 0x9C62 # 0 +0xF767 0x9C63 # 0 +0xF768 0x9C64 # 0 +0xF769 0x9C65 # 0 +0xF76A 0x9C66 # 0 +0xF76B 0x9C67 # 0 +0xF76C 0x9C68 # 0 +0xF76D 0x9C69 # 0 +0xF76E 0x9C6A # 0 +0xF76F 0x9C6B # 0 +0xF770 0x9C6C # 0 +0xF771 0x9C6D # 0 +0xF772 0x9C6E # 0 +0xF773 0x9C6F # 0 +0xF774 0x9C70 # 0 +0xF775 0x9C71 # 0 +0xF776 0x9C72 # 0 +0xF777 0x9C73 # 0 +0xF778 0x9C74 # 0 +0xF779 0x9C75 # 0 +0xF77A 0x9C76 # 0 +0xF77B 0x9C77 # 0 +0xF77C 0x9C78 # 0 +0xF77D 0x9C79 # 0 +0xF77E 0x9C7A # 0 +0xF780 0x9C7B # 0 +0xF781 0x9C7D # 0 +0xF782 0x9C7E # 0 +0xF783 0x9C80 # 0 +0xF784 0x9C83 # 0 +0xF785 0x9C84 # 0 +0xF786 0x9C89 # 0 +0xF787 0x9C8A # 0 +0xF788 0x9C8C # 0 +0xF789 0x9C8F # 0 +0xF78A 0x9C93 # 0 +0xF78B 0x9C96 # 0 +0xF78C 0x9C97 # 0 +0xF78D 0x9C98 # 0 +0xF78E 0x9C99 # 0 +0xF78F 0x9C9D # 0 +0xF790 0x9CAA # 0 +0xF791 0x9CAC # 0 +0xF792 0x9CAF # 0 +0xF793 0x9CB9 # 0 +0xF794 0x9CBE # 0 +0xF795 0x9CBF # 0 +0xF796 0x9CC0 # 0 +0xF797 0x9CC1 # 0 +0xF798 0x9CC2 # 0 +0xF799 0x9CC8 # 0 +0xF79A 0x9CC9 # 0 +0xF79B 0x9CD1 # 0 +0xF79C 0x9CD2 # 0 +0xF79D 0x9CDA # 0 +0xF79E 0x9CDB # 0 +0xF79F 0x9CE0 # 0 +0xF7A0 0x9CE1 # 0 +0xF7A1 0x9CCC # 0 +0xF7A2 0x9CCD # 0 +0xF7A3 0x9CCE # 0 +0xF7A4 0x9CCF # 0 +0xF7A5 0x9CD0 # 0 +0xF7A6 0x9CD3 # 0 +0xF7A7 0x9CD4 # 0 +0xF7A8 0x9CD5 # 0 +0xF7A9 0x9CD7 # 0 +0xF7AA 0x9CD8 # 0 +0xF7AB 0x9CD9 # 0 +0xF7AC 0x9CDC # 0 +0xF7AD 0x9CDD # 0 +0xF7AE 0x9CDF # 0 +0xF7AF 0x9CE2 # 0 +0xF7B0 0x977C # 0 +0xF7B1 0x9785 # 0 +0xF7B2 0x9791 # 0 +0xF7B3 0x9792 # 0 +0xF7B4 0x9794 # 0 +0xF7B5 0x97AF # 0 +0xF7B6 0x97AB # 0 +0xF7B7 0x97A3 # 0 +0xF7B8 0x97B2 # 0 +0xF7B9 0x97B4 # 0 +0xF7BA 0x9AB1 # 0 +0xF7BB 0x9AB0 # 0 +0xF7BC 0x9AB7 # 0 +0xF7BD 0x9E58 # 0 +0xF7BE 0x9AB6 # 0 +0xF7BF 0x9ABA # 0 +0xF7C0 0x9ABC # 0 +0xF7C1 0x9AC1 # 0 +0xF7C2 0x9AC0 # 0 +0xF7C3 0x9AC5 # 0 +0xF7C4 0x9AC2 # 0 +0xF7C5 0x9ACB # 0 +0xF7C6 0x9ACC # 0 +0xF7C7 0x9AD1 # 0 +0xF7C8 0x9B45 # 0 +0xF7C9 0x9B43 # 0 +0xF7CA 0x9B47 # 0 +0xF7CB 0x9B49 # 0 +0xF7CC 0x9B48 # 0 +0xF7CD 0x9B4D # 0 +0xF7CE 0x9B51 # 0 +0xF7CF 0x98E8 # 0 +0xF7D0 0x990D # 0 +0xF7D1 0x992E # 0 +0xF7D2 0x9955 # 0 +0xF7D3 0x9954 # 0 +0xF7D4 0x9ADF # 0 +0xF7D5 0x9AE1 # 0 +0xF7D6 0x9AE6 # 0 +0xF7D7 0x9AEF # 0 +0xF7D8 0x9AEB # 0 +0xF7D9 0x9AFB # 0 +0xF7DA 0x9AED # 0 +0xF7DB 0x9AF9 # 0 +0xF7DC 0x9B08 # 0 +0xF7DD 0x9B0F # 0 +0xF7DE 0x9B13 # 0 +0xF7DF 0x9B1F # 0 +0xF7E0 0x9B23 # 0 +0xF7E1 0x9EBD # 0 +0xF7E2 0x9EBE # 0 +0xF7E3 0x7E3B # 0 +0xF7E4 0x9E82 # 0 +0xF7E5 0x9E87 # 0 +0xF7E6 0x9E88 # 0 +0xF7E7 0x9E8B # 0 +0xF7E8 0x9E92 # 0 +0xF7E9 0x93D6 # 0 +0xF7EA 0x9E9D # 0 +0xF7EB 0x9E9F # 0 +0xF7EC 0x9EDB # 0 +0xF7ED 0x9EDC # 0 +0xF7EE 0x9EDD # 0 +0xF7EF 0x9EE0 # 0 +0xF7F0 0x9EDF # 0 +0xF7F1 0x9EE2 # 0 +0xF7F2 0x9EE9 # 0 +0xF7F3 0x9EE7 # 0 +0xF7F4 0x9EE5 # 0 +0xF7F5 0x9EEA # 0 +0xF7F6 0x9EEF # 0 +0xF7F7 0x9F22 # 0 +0xF7F8 0x9F2C # 0 +0xF7F9 0x9F2F # 0 +0xF7FA 0x9F39 # 0 +0xF7FB 0x9F37 # 0 +0xF7FC 0x9F3D # 0 +0xF7FD 0x9F3E # 0 +0xF7FE 0x9F44 # 0 +0xF840 0x9CE3 # 0 +0xF841 0x9CE4 # 0 +0xF842 0x9CE5 # 0 +0xF843 0x9CE6 # 0 +0xF844 0x9CE7 # 0 +0xF845 0x9CE8 # 0 +0xF846 0x9CE9 # 0 +0xF847 0x9CEA # 0 +0xF848 0x9CEB # 0 +0xF849 0x9CEC # 0 +0xF84A 0x9CED # 0 +0xF84B 0x9CEE # 0 +0xF84C 0x9CEF # 0 +0xF84D 0x9CF0 # 0 +0xF84E 0x9CF1 # 0 +0xF84F 0x9CF2 # 0 +0xF850 0x9CF3 # 0 +0xF851 0x9CF4 # 0 +0xF852 0x9CF5 # 0 +0xF853 0x9CF6 # 0 +0xF854 0x9CF7 # 0 +0xF855 0x9CF8 # 0 +0xF856 0x9CF9 # 0 +0xF857 0x9CFA # 0 +0xF858 0x9CFB # 0 +0xF859 0x9CFC # 0 +0xF85A 0x9CFD # 0 +0xF85B 0x9CFE # 0 +0xF85C 0x9CFF # 0 +0xF85D 0x9D00 # 0 +0xF85E 0x9D01 # 0 +0xF85F 0x9D02 # 0 +0xF860 0x9D03 # 0 +0xF861 0x9D04 # 0 +0xF862 0x9D05 # 0 +0xF863 0x9D06 # 0 +0xF864 0x9D07 # 0 +0xF865 0x9D08 # 0 +0xF866 0x9D09 # 0 +0xF867 0x9D0A # 0 +0xF868 0x9D0B # 0 +0xF869 0x9D0C # 0 +0xF86A 0x9D0D # 0 +0xF86B 0x9D0E # 0 +0xF86C 0x9D0F # 0 +0xF86D 0x9D10 # 0 +0xF86E 0x9D11 # 0 +0xF86F 0x9D12 # 0 +0xF870 0x9D13 # 0 +0xF871 0x9D14 # 0 +0xF872 0x9D15 # 0 +0xF873 0x9D16 # 0 +0xF874 0x9D17 # 0 +0xF875 0x9D18 # 0 +0xF876 0x9D19 # 0 +0xF877 0x9D1A # 0 +0xF878 0x9D1B # 0 +0xF879 0x9D1C # 0 +0xF87A 0x9D1D # 0 +0xF87B 0x9D1E # 0 +0xF87C 0x9D1F # 0 +0xF87D 0x9D20 # 0 +0xF87E 0x9D21 # 0 +0xF880 0x9D22 # 0 +0xF881 0x9D23 # 0 +0xF882 0x9D24 # 0 +0xF883 0x9D25 # 0 +0xF884 0x9D26 # 0 +0xF885 0x9D27 # 0 +0xF886 0x9D28 # 0 +0xF887 0x9D29 # 0 +0xF888 0x9D2A # 0 +0xF889 0x9D2B # 0 +0xF88A 0x9D2C # 0 +0xF88B 0x9D2D # 0 +0xF88C 0x9D2E # 0 +0xF88D 0x9D2F # 0 +0xF88E 0x9D30 # 0 +0xF88F 0x9D31 # 0 +0xF890 0x9D32 # 0 +0xF891 0x9D33 # 0 +0xF892 0x9D34 # 0 +0xF893 0x9D35 # 0 +0xF894 0x9D36 # 0 +0xF895 0x9D37 # 0 +0xF896 0x9D38 # 0 +0xF897 0x9D39 # 0 +0xF898 0x9D3A # 0 +0xF899 0x9D3B # 0 +0xF89A 0x9D3C # 0 +0xF89B 0x9D3D # 0 +0xF89C 0x9D3E # 0 +0xF89D 0x9D3F # 0 +0xF89E 0x9D40 # 0 +0xF89F 0x9D41 # 0 +0xF8A0 0x9D42 # 0 +0xF8A1 0xE234 # 0 +0xF8A2 0xE235 # 0 +0xF8A3 0xE236 # 0 +0xF8A4 0xE237 # 0 +0xF8A5 0xE238 # 0 +0xF8A6 0xE239 # 0 +0xF8A7 0xE23A # 0 +0xF8A8 0xE23B # 0 +0xF8A9 0xE23C # 0 +0xF8AA 0xE23D # 0 +0xF8AB 0xE23E # 0 +0xF8AC 0xE23F # 0 +0xF8AD 0xE240 # 0 +0xF8AE 0xE241 # 0 +0xF8AF 0xE242 # 0 +0xF8B0 0xE243 # 0 +0xF8B1 0xE244 # 0 +0xF8B2 0xE245 # 0 +0xF8B3 0xE246 # 0 +0xF8B4 0xE247 # 0 +0xF8B5 0xE248 # 0 +0xF8B6 0xE249 # 0 +0xF8B7 0xE24A # 0 +0xF8B8 0xE24B # 0 +0xF8B9 0xE24C # 0 +0xF8BA 0xE24D # 0 +0xF8BB 0xE24E # 0 +0xF8BC 0xE24F # 0 +0xF8BD 0xE250 # 0 +0xF8BE 0xE251 # 0 +0xF8BF 0xE252 # 0 +0xF8C0 0xE253 # 0 +0xF8C1 0xE254 # 0 +0xF8C2 0xE255 # 0 +0xF8C3 0xE256 # 0 +0xF8C4 0xE257 # 0 +0xF8C5 0xE258 # 0 +0xF8C6 0xE259 # 0 +0xF8C7 0xE25A # 0 +0xF8C8 0xE25B # 0 +0xF8C9 0xE25C # 0 +0xF8CA 0xE25D # 0 +0xF8CB 0xE25E # 0 +0xF8CC 0xE25F # 0 +0xF8CD 0xE260 # 0 +0xF8CE 0xE261 # 0 +0xF8CF 0xE262 # 0 +0xF8D0 0xE263 # 0 +0xF8D1 0xE264 # 0 +0xF8D2 0xE265 # 0 +0xF8D3 0xE266 # 0 +0xF8D4 0xE267 # 0 +0xF8D5 0xE268 # 0 +0xF8D6 0xE269 # 0 +0xF8D7 0xE26A # 0 +0xF8D8 0xE26B # 0 +0xF8D9 0xE26C # 0 +0xF8DA 0xE26D # 0 +0xF8DB 0xE26E # 0 +0xF8DC 0xE26F # 0 +0xF8DD 0xE270 # 0 +0xF8DE 0xE271 # 0 +0xF8DF 0xE272 # 0 +0xF8E0 0xE273 # 0 +0xF8E1 0xE274 # 0 +0xF8E2 0xE275 # 0 +0xF8E3 0xE276 # 0 +0xF8E4 0xE277 # 0 +0xF8E5 0xE278 # 0 +0xF8E6 0xE279 # 0 +0xF8E7 0xE27A # 0 +0xF8E8 0xE27B # 0 +0xF8E9 0xE27C # 0 +0xF8EA 0xE27D # 0 +0xF8EB 0xE27E # 0 +0xF8EC 0xE27F # 0 +0xF8ED 0xE280 # 0 +0xF8EE 0xE281 # 0 +0xF8EF 0xE282 # 0 +0xF8F0 0xE283 # 0 +0xF8F1 0xE284 # 0 +0xF8F2 0xE285 # 0 +0xF8F3 0xE286 # 0 +0xF8F4 0xE287 # 0 +0xF8F5 0xE288 # 0 +0xF8F6 0xE289 # 0 +0xF8F7 0xE28A # 0 +0xF8F8 0xE28B # 0 +0xF8F9 0xE28C # 0 +0xF8FA 0xE28D # 0 +0xF8FB 0xE28E # 0 +0xF8FC 0xE28F # 0 +0xF8FD 0xE290 # 0 +0xF8FE 0xE291 # 0 +0xF940 0x9D43 # 0 +0xF941 0x9D44 # 0 +0xF942 0x9D45 # 0 +0xF943 0x9D46 # 0 +0xF944 0x9D47 # 0 +0xF945 0x9D48 # 0 +0xF946 0x9D49 # 0 +0xF947 0x9D4A # 0 +0xF948 0x9D4B # 0 +0xF949 0x9D4C # 0 +0xF94A 0x9D4D # 0 +0xF94B 0x9D4E # 0 +0xF94C 0x9D4F # 0 +0xF94D 0x9D50 # 0 +0xF94E 0x9D51 # 0 +0xF94F 0x9D52 # 0 +0xF950 0x9D53 # 0 +0xF951 0x9D54 # 0 +0xF952 0x9D55 # 0 +0xF953 0x9D56 # 0 +0xF954 0x9D57 # 0 +0xF955 0x9D58 # 0 +0xF956 0x9D59 # 0 +0xF957 0x9D5A # 0 +0xF958 0x9D5B # 0 +0xF959 0x9D5C # 0 +0xF95A 0x9D5D # 0 +0xF95B 0x9D5E # 0 +0xF95C 0x9D5F # 0 +0xF95D 0x9D60 # 0 +0xF95E 0x9D61 # 0 +0xF95F 0x9D62 # 0 +0xF960 0x9D63 # 0 +0xF961 0x9D64 # 0 +0xF962 0x9D65 # 0 +0xF963 0x9D66 # 0 +0xF964 0x9D67 # 0 +0xF965 0x9D68 # 0 +0xF966 0x9D69 # 0 +0xF967 0x9D6A # 0 +0xF968 0x9D6B # 0 +0xF969 0x9D6C # 0 +0xF96A 0x9D6D # 0 +0xF96B 0x9D6E # 0 +0xF96C 0x9D6F # 0 +0xF96D 0x9D70 # 0 +0xF96E 0x9D71 # 0 +0xF96F 0x9D72 # 0 +0xF970 0x9D73 # 0 +0xF971 0x9D74 # 0 +0xF972 0x9D75 # 0 +0xF973 0x9D76 # 0 +0xF974 0x9D77 # 0 +0xF975 0x9D78 # 0 +0xF976 0x9D79 # 0 +0xF977 0x9D7A # 0 +0xF978 0x9D7B # 0 +0xF979 0x9D7C # 0 +0xF97A 0x9D7D # 0 +0xF97B 0x9D7E # 0 +0xF97C 0x9D7F # 0 +0xF97D 0x9D80 # 0 +0xF97E 0x9D81 # 0 +0xF980 0x9D82 # 0 +0xF981 0x9D83 # 0 +0xF982 0x9D84 # 0 +0xF983 0x9D85 # 0 +0xF984 0x9D86 # 0 +0xF985 0x9D87 # 0 +0xF986 0x9D88 # 0 +0xF987 0x9D89 # 0 +0xF988 0x9D8A # 0 +0xF989 0x9D8B # 0 +0xF98A 0x9D8C # 0 +0xF98B 0x9D8D # 0 +0xF98C 0x9D8E # 0 +0xF98D 0x9D8F # 0 +0xF98E 0x9D90 # 0 +0xF98F 0x9D91 # 0 +0xF990 0x9D92 # 0 +0xF991 0x9D93 # 0 +0xF992 0x9D94 # 0 +0xF993 0x9D95 # 0 +0xF994 0x9D96 # 0 +0xF995 0x9D97 # 0 +0xF996 0x9D98 # 0 +0xF997 0x9D99 # 0 +0xF998 0x9D9A # 0 +0xF999 0x9D9B # 0 +0xF99A 0x9D9C # 0 +0xF99B 0x9D9D # 0 +0xF99C 0x9D9E # 0 +0xF99D 0x9D9F # 0 +0xF99E 0x9DA0 # 0 +0xF99F 0x9DA1 # 0 +0xF9A0 0x9DA2 # 0 +0xF9A1 0xE292 # 0 +0xF9A2 0xE293 # 0 +0xF9A3 0xE294 # 0 +0xF9A4 0xE295 # 0 +0xF9A5 0xE296 # 0 +0xF9A6 0xE297 # 0 +0xF9A7 0xE298 # 0 +0xF9A8 0xE299 # 0 +0xF9A9 0xE29A # 0 +0xF9AA 0xE29B # 0 +0xF9AB 0xE29C # 0 +0xF9AC 0xE29D # 0 +0xF9AD 0xE29E # 0 +0xF9AE 0xE29F # 0 +0xF9AF 0xE2A0 # 0 +0xF9B0 0xE2A1 # 0 +0xF9B1 0xE2A2 # 0 +0xF9B2 0xE2A3 # 0 +0xF9B3 0xE2A4 # 0 +0xF9B4 0xE2A5 # 0 +0xF9B5 0xE2A6 # 0 +0xF9B6 0xE2A7 # 0 +0xF9B7 0xE2A8 # 0 +0xF9B8 0xE2A9 # 0 +0xF9B9 0xE2AA # 0 +0xF9BA 0xE2AB # 0 +0xF9BB 0xE2AC # 0 +0xF9BC 0xE2AD # 0 +0xF9BD 0xE2AE # 0 +0xF9BE 0xE2AF # 0 +0xF9BF 0xE2B0 # 0 +0xF9C0 0xE2B1 # 0 +0xF9C1 0xE2B2 # 0 +0xF9C2 0xE2B3 # 0 +0xF9C3 0xE2B4 # 0 +0xF9C4 0xE2B5 # 0 +0xF9C5 0xE2B6 # 0 +0xF9C6 0xE2B7 # 0 +0xF9C7 0xE2B8 # 0 +0xF9C8 0xE2B9 # 0 +0xF9C9 0xE2BA # 0 +0xF9CA 0xE2BB # 0 +0xF9CB 0xE2BC # 0 +0xF9CC 0xE2BD # 0 +0xF9CD 0xE2BE # 0 +0xF9CE 0xE2BF # 0 +0xF9CF 0xE2C0 # 0 +0xF9D0 0xE2C1 # 0 +0xF9D1 0xE2C2 # 0 +0xF9D2 0xE2C3 # 0 +0xF9D3 0xE2C4 # 0 +0xF9D4 0xE2C5 # 0 +0xF9D5 0xE2C6 # 0 +0xF9D6 0xE2C7 # 0 +0xF9D7 0xE2C8 # 0 +0xF9D8 0xE2C9 # 0 +0xF9D9 0xE2CA # 0 +0xF9DA 0xE2CB # 0 +0xF9DB 0xE2CC # 0 +0xF9DC 0xE2CD # 0 +0xF9DD 0xE2CE # 0 +0xF9DE 0xE2CF # 0 +0xF9DF 0xE2D0 # 0 +0xF9E0 0xE2D1 # 0 +0xF9E1 0xE2D2 # 0 +0xF9E2 0xE2D3 # 0 +0xF9E3 0xE2D4 # 0 +0xF9E4 0xE2D5 # 0 +0xF9E5 0xE2D6 # 0 +0xF9E6 0xE2D7 # 0 +0xF9E7 0xE2D8 # 0 +0xF9E8 0xE2D9 # 0 +0xF9E9 0xE2DA # 0 +0xF9EA 0xE2DB # 0 +0xF9EB 0xE2DC # 0 +0xF9EC 0xE2DD # 0 +0xF9ED 0xE2DE # 0 +0xF9EE 0xE2DF # 0 +0xF9EF 0xE2E0 # 0 +0xF9F0 0xE2E1 # 0 +0xF9F1 0xE2E2 # 0 +0xF9F2 0xE2E3 # 0 +0xF9F3 0xE2E4 # 0 +0xF9F4 0xE2E5 # 0 +0xF9F5 0xE2E6 # 0 +0xF9F6 0xE2E7 # 0 +0xF9F7 0xE2E8 # 0 +0xF9F8 0xE2E9 # 0 +0xF9F9 0xE2EA # 0 +0xF9FA 0xE2EB # 0 +0xF9FB 0xE2EC # 0 +0xF9FC 0xE2ED # 0 +0xF9FD 0xE2EE # 0 +0xF9FE 0xE2EF # 0 +0xFA40 0x9DA3 # 0 +0xFA41 0x9DA4 # 0 +0xFA42 0x9DA5 # 0 +0xFA43 0x9DA6 # 0 +0xFA44 0x9DA7 # 0 +0xFA45 0x9DA8 # 0 +0xFA46 0x9DA9 # 0 +0xFA47 0x9DAA # 0 +0xFA48 0x9DAB # 0 +0xFA49 0x9DAC # 0 +0xFA4A 0x9DAD # 0 +0xFA4B 0x9DAE # 0 +0xFA4C 0x9DAF # 0 +0xFA4D 0x9DB0 # 0 +0xFA4E 0x9DB1 # 0 +0xFA4F 0x9DB2 # 0 +0xFA50 0x9DB3 # 0 +0xFA51 0x9DB4 # 0 +0xFA52 0x9DB5 # 0 +0xFA53 0x9DB6 # 0 +0xFA54 0x9DB7 # 0 +0xFA55 0x9DB8 # 0 +0xFA56 0x9DB9 # 0 +0xFA57 0x9DBA # 0 +0xFA58 0x9DBB # 0 +0xFA59 0x9DBC # 0 +0xFA5A 0x9DBD # 0 +0xFA5B 0x9DBE # 0 +0xFA5C 0x9DBF # 0 +0xFA5D 0x9DC0 # 0 +0xFA5E 0x9DC1 # 0 +0xFA5F 0x9DC2 # 0 +0xFA60 0x9DC3 # 0 +0xFA61 0x9DC4 # 0 +0xFA62 0x9DC5 # 0 +0xFA63 0x9DC6 # 0 +0xFA64 0x9DC7 # 0 +0xFA65 0x9DC8 # 0 +0xFA66 0x9DC9 # 0 +0xFA67 0x9DCA # 0 +0xFA68 0x9DCB # 0 +0xFA69 0x9DCC # 0 +0xFA6A 0x9DCD # 0 +0xFA6B 0x9DCE # 0 +0xFA6C 0x9DCF # 0 +0xFA6D 0x9DD0 # 0 +0xFA6E 0x9DD1 # 0 +0xFA6F 0x9DD2 # 0 +0xFA70 0x9DD3 # 0 +0xFA71 0x9DD4 # 0 +0xFA72 0x9DD5 # 0 +0xFA73 0x9DD6 # 0 +0xFA74 0x9DD7 # 0 +0xFA75 0x9DD8 # 0 +0xFA76 0x9DD9 # 0 +0xFA77 0x9DDA # 0 +0xFA78 0x9DDB # 0 +0xFA79 0x9DDC # 0 +0xFA7A 0x9DDD # 0 +0xFA7B 0x9DDE # 0 +0xFA7C 0x9DDF # 0 +0xFA7D 0x9DE0 # 0 +0xFA7E 0x9DE1 # 0 +0xFA80 0x9DE2 # 0 +0xFA81 0x9DE3 # 0 +0xFA82 0x9DE4 # 0 +0xFA83 0x9DE5 # 0 +0xFA84 0x9DE6 # 0 +0xFA85 0x9DE7 # 0 +0xFA86 0x9DE8 # 0 +0xFA87 0x9DE9 # 0 +0xFA88 0x9DEA # 0 +0xFA89 0x9DEB # 0 +0xFA8A 0x9DEC # 0 +0xFA8B 0x9DED # 0 +0xFA8C 0x9DEE # 0 +0xFA8D 0x9DEF # 0 +0xFA8E 0x9DF0 # 0 +0xFA8F 0x9DF1 # 0 +0xFA90 0x9DF2 # 0 +0xFA91 0x9DF3 # 0 +0xFA92 0x9DF4 # 0 +0xFA93 0x9DF5 # 0 +0xFA94 0x9DF6 # 0 +0xFA95 0x9DF7 # 0 +0xFA96 0x9DF8 # 0 +0xFA97 0x9DF9 # 0 +0xFA98 0x9DFA # 0 +0xFA99 0x9DFB # 0 +0xFA9A 0x9DFC # 0 +0xFA9B 0x9DFD # 0 +0xFA9C 0x9DFE # 0 +0xFA9D 0x9DFF # 0 +0xFA9E 0x9E00 # 0 +0xFA9F 0x9E01 # 0 +0xFAA0 0x9E02 # 0 +0xFAA1 0xE2F0 # 0 +0xFAA2 0xE2F1 # 0 +0xFAA3 0xE2F2 # 0 +0xFAA4 0xE2F3 # 0 +0xFAA5 0xE2F4 # 0 +0xFAA6 0xE2F5 # 0 +0xFAA7 0xE2F6 # 0 +0xFAA8 0xE2F7 # 0 +0xFAA9 0xE2F8 # 0 +0xFAAA 0xE2F9 # 0 +0xFAAB 0xE2FA # 0 +0xFAAC 0xE2FB # 0 +0xFAAD 0xE2FC # 0 +0xFAAE 0xE2FD # 0 +0xFAAF 0xE2FE # 0 +0xFAB0 0xE2FF # 0 +0xFAB1 0xE300 # 0 +0xFAB2 0xE301 # 0 +0xFAB3 0xE302 # 0 +0xFAB4 0xE303 # 0 +0xFAB5 0xE304 # 0 +0xFAB6 0xE305 # 0 +0xFAB7 0xE306 # 0 +0xFAB8 0xE307 # 0 +0xFAB9 0xE308 # 0 +0xFABA 0xE309 # 0 +0xFABB 0xE30A # 0 +0xFABC 0xE30B # 0 +0xFABD 0xE30C # 0 +0xFABE 0xE30D # 0 +0xFABF 0xE30E # 0 +0xFAC0 0xE30F # 0 +0xFAC1 0xE310 # 0 +0xFAC2 0xE311 # 0 +0xFAC3 0xE312 # 0 +0xFAC4 0xE313 # 0 +0xFAC5 0xE314 # 0 +0xFAC6 0xE315 # 0 +0xFAC7 0xE316 # 0 +0xFAC8 0xE317 # 0 +0xFAC9 0xE318 # 0 +0xFACA 0xE319 # 0 +0xFACB 0xE31A # 0 +0xFACC 0xE31B # 0 +0xFACD 0xE31C # 0 +0xFACE 0xE31D # 0 +0xFACF 0xE31E # 0 +0xFAD0 0xE31F # 0 +0xFAD1 0xE320 # 0 +0xFAD2 0xE321 # 0 +0xFAD3 0xE322 # 0 +0xFAD4 0xE323 # 0 +0xFAD5 0xE324 # 0 +0xFAD6 0xE325 # 0 +0xFAD7 0xE326 # 0 +0xFAD8 0xE327 # 0 +0xFAD9 0xE328 # 0 +0xFADA 0xE329 # 0 +0xFADB 0xE32A # 0 +0xFADC 0xE32B # 0 +0xFADD 0xE32C # 0 +0xFADE 0xE32D # 0 +0xFADF 0xE32E # 0 +0xFAE0 0xE32F # 0 +0xFAE1 0xE330 # 0 +0xFAE2 0xE331 # 0 +0xFAE3 0xE332 # 0 +0xFAE4 0xE333 # 0 +0xFAE5 0xE334 # 0 +0xFAE6 0xE335 # 0 +0xFAE7 0xE336 # 0 +0xFAE8 0xE337 # 0 +0xFAE9 0xE338 # 0 +0xFAEA 0xE339 # 0 +0xFAEB 0xE33A # 0 +0xFAEC 0xE33B # 0 +0xFAED 0xE33C # 0 +0xFAEE 0xE33D # 0 +0xFAEF 0xE33E # 0 +0xFAF0 0xE33F # 0 +0xFAF1 0xE340 # 0 +0xFAF2 0xE341 # 0 +0xFAF3 0xE342 # 0 +0xFAF4 0xE343 # 0 +0xFAF5 0xE344 # 0 +0xFAF6 0xE345 # 0 +0xFAF7 0xE346 # 0 +0xFAF8 0xE347 # 0 +0xFAF9 0xE348 # 0 +0xFAFA 0xE349 # 0 +0xFAFB 0xE34A # 0 +0xFAFC 0xE34B # 0 +0xFAFD 0xE34C # 0 +0xFAFE 0xE34D # 0 +0xFB40 0x9E03 # 0 +0xFB41 0x9E04 # 0 +0xFB42 0x9E05 # 0 +0xFB43 0x9E06 # 0 +0xFB44 0x9E07 # 0 +0xFB45 0x9E08 # 0 +0xFB46 0x9E09 # 0 +0xFB47 0x9E0A # 0 +0xFB48 0x9E0B # 0 +0xFB49 0x9E0C # 0 +0xFB4A 0x9E0D # 0 +0xFB4B 0x9E0E # 0 +0xFB4C 0x9E0F # 0 +0xFB4D 0x9E10 # 0 +0xFB4E 0x9E11 # 0 +0xFB4F 0x9E12 # 0 +0xFB50 0x9E13 # 0 +0xFB51 0x9E14 # 0 +0xFB52 0x9E15 # 0 +0xFB53 0x9E16 # 0 +0xFB54 0x9E17 # 0 +0xFB55 0x9E18 # 0 +0xFB56 0x9E19 # 0 +0xFB57 0x9E1A # 0 +0xFB58 0x9E1B # 0 +0xFB59 0x9E1C # 0 +0xFB5A 0x9E1D # 0 +0xFB5B 0x9E1E # 0 +0xFB5C 0x9E24 # 0 +0xFB5D 0x9E27 # 0 +0xFB5E 0x9E2E # 0 +0xFB5F 0x9E30 # 0 +0xFB60 0x9E34 # 0 +0xFB61 0x9E3B # 0 +0xFB62 0x9E3C # 0 +0xFB63 0x9E40 # 0 +0xFB64 0x9E4D # 0 +0xFB65 0x9E50 # 0 +0xFB66 0x9E52 # 0 +0xFB67 0x9E53 # 0 +0xFB68 0x9E54 # 0 +0xFB69 0x9E56 # 0 +0xFB6A 0x9E59 # 0 +0xFB6B 0x9E5D # 0 +0xFB6C 0x9E5F # 0 +0xFB6D 0x9E60 # 0 +0xFB6E 0x9E61 # 0 +0xFB6F 0x9E62 # 0 +0xFB70 0x9E65 # 0 +0xFB71 0x9E6E # 0 +0xFB72 0x9E6F # 0 +0xFB73 0x9E72 # 0 +0xFB74 0x9E74 # 0 +0xFB75 0x9E75 # 0 +0xFB76 0x9E76 # 0 +0xFB77 0x9E77 # 0 +0xFB78 0x9E78 # 0 +0xFB79 0x9E79 # 0 +0xFB7A 0x9E7A # 0 +0xFB7B 0x9E7B # 0 +0xFB7C 0x9E7C # 0 +0xFB7D 0x9E7D # 0 +0xFB7E 0x9E80 # 0 +0xFB80 0x9E81 # 0 +0xFB81 0x9E83 # 0 +0xFB82 0x9E84 # 0 +0xFB83 0x9E85 # 0 +0xFB84 0x9E86 # 0 +0xFB85 0x9E89 # 0 +0xFB86 0x9E8A # 0 +0xFB87 0x9E8C # 0 +0xFB88 0x9E8D # 0 +0xFB89 0x9E8E # 0 +0xFB8A 0x9E8F # 0 +0xFB8B 0x9E90 # 0 +0xFB8C 0x9E91 # 0 +0xFB8D 0x9E94 # 0 +0xFB8E 0x9E95 # 0 +0xFB8F 0x9E96 # 0 +0xFB90 0x9E97 # 0 +0xFB91 0x9E98 # 0 +0xFB92 0x9E99 # 0 +0xFB93 0x9E9A # 0 +0xFB94 0x9E9B # 0 +0xFB95 0x9E9C # 0 +0xFB96 0x9E9E # 0 +0xFB97 0x9EA0 # 0 +0xFB98 0x9EA1 # 0 +0xFB99 0x9EA2 # 0 +0xFB9A 0x9EA3 # 0 +0xFB9B 0x9EA4 # 0 +0xFB9C 0x9EA5 # 0 +0xFB9D 0x9EA7 # 0 +0xFB9E 0x9EA8 # 0 +0xFB9F 0x9EA9 # 0 +0xFBA0 0x9EAA # 0 +0xFBA1 0xE34E # 0 +0xFBA2 0xE34F # 0 +0xFBA3 0xE350 # 0 +0xFBA4 0xE351 # 0 +0xFBA5 0xE352 # 0 +0xFBA6 0xE353 # 0 +0xFBA7 0xE354 # 0 +0xFBA8 0xE355 # 0 +0xFBA9 0xE356 # 0 +0xFBAA 0xE357 # 0 +0xFBAB 0xE358 # 0 +0xFBAC 0xE359 # 0 +0xFBAD 0xE35A # 0 +0xFBAE 0xE35B # 0 +0xFBAF 0xE35C # 0 +0xFBB0 0xE35D # 0 +0xFBB1 0xE35E # 0 +0xFBB2 0xE35F # 0 +0xFBB3 0xE360 # 0 +0xFBB4 0xE361 # 0 +0xFBB5 0xE362 # 0 +0xFBB6 0xE363 # 0 +0xFBB7 0xE364 # 0 +0xFBB8 0xE365 # 0 +0xFBB9 0xE366 # 0 +0xFBBA 0xE367 # 0 +0xFBBB 0xE368 # 0 +0xFBBC 0xE369 # 0 +0xFBBD 0xE36A # 0 +0xFBBE 0xE36B # 0 +0xFBBF 0xE36C # 0 +0xFBC0 0xE36D # 0 +0xFBC1 0xE36E # 0 +0xFBC2 0xE36F # 0 +0xFBC3 0xE370 # 0 +0xFBC4 0xE371 # 0 +0xFBC5 0xE372 # 0 +0xFBC6 0xE373 # 0 +0xFBC7 0xE374 # 0 +0xFBC8 0xE375 # 0 +0xFBC9 0xE376 # 0 +0xFBCA 0xE377 # 0 +0xFBCB 0xE378 # 0 +0xFBCC 0xE379 # 0 +0xFBCD 0xE37A # 0 +0xFBCE 0xE37B # 0 +0xFBCF 0xE37C # 0 +0xFBD0 0xE37D # 0 +0xFBD1 0xE37E # 0 +0xFBD2 0xE37F # 0 +0xFBD3 0xE380 # 0 +0xFBD4 0xE381 # 0 +0xFBD5 0xE382 # 0 +0xFBD6 0xE383 # 0 +0xFBD7 0xE384 # 0 +0xFBD8 0xE385 # 0 +0xFBD9 0xE386 # 0 +0xFBDA 0xE387 # 0 +0xFBDB 0xE388 # 0 +0xFBDC 0xE389 # 0 +0xFBDD 0xE38A # 0 +0xFBDE 0xE38B # 0 +0xFBDF 0xE38C # 0 +0xFBE0 0xE38D # 0 +0xFBE1 0xE38E # 0 +0xFBE2 0xE38F # 0 +0xFBE3 0xE390 # 0 +0xFBE4 0xE391 # 0 +0xFBE5 0xE392 # 0 +0xFBE6 0xE393 # 0 +0xFBE7 0xE394 # 0 +0xFBE8 0xE395 # 0 +0xFBE9 0xE396 # 0 +0xFBEA 0xE397 # 0 +0xFBEB 0xE398 # 0 +0xFBEC 0xE399 # 0 +0xFBED 0xE39A # 0 +0xFBEE 0xE39B # 0 +0xFBEF 0xE39C # 0 +0xFBF0 0xE39D # 0 +0xFBF1 0xE39E # 0 +0xFBF2 0xE39F # 0 +0xFBF3 0xE3A0 # 0 +0xFBF4 0xE3A1 # 0 +0xFBF5 0xE3A2 # 0 +0xFBF6 0xE3A3 # 0 +0xFBF7 0xE3A4 # 0 +0xFBF8 0xE3A5 # 0 +0xFBF9 0xE3A6 # 0 +0xFBFA 0xE3A7 # 0 +0xFBFB 0xE3A8 # 0 +0xFBFC 0xE3A9 # 0 +0xFBFD 0xE3AA # 0 +0xFBFE 0xE3AB # 0 +0xFC40 0x9EAB # 0 +0xFC41 0x9EAC # 0 +0xFC42 0x9EAD # 0 +0xFC43 0x9EAE # 0 +0xFC44 0x9EAF # 0 +0xFC45 0x9EB0 # 0 +0xFC46 0x9EB1 # 0 +0xFC47 0x9EB2 # 0 +0xFC48 0x9EB3 # 0 +0xFC49 0x9EB5 # 0 +0xFC4A 0x9EB6 # 0 +0xFC4B 0x9EB7 # 0 +0xFC4C 0x9EB9 # 0 +0xFC4D 0x9EBA # 0 +0xFC4E 0x9EBC # 0 +0xFC4F 0x9EBF # 0 +0xFC50 0x9EC0 # 0 +0xFC51 0x9EC1 # 0 +0xFC52 0x9EC2 # 0 +0xFC53 0x9EC3 # 0 +0xFC54 0x9EC5 # 0 +0xFC55 0x9EC6 # 0 +0xFC56 0x9EC7 # 0 +0xFC57 0x9EC8 # 0 +0xFC58 0x9ECA # 0 +0xFC59 0x9ECB # 0 +0xFC5A 0x9ECC # 0 +0xFC5B 0x9ED0 # 0 +0xFC5C 0x9ED2 # 0 +0xFC5D 0x9ED3 # 0 +0xFC5E 0x9ED5 # 0 +0xFC5F 0x9ED6 # 0 +0xFC60 0x9ED7 # 0 +0xFC61 0x9ED9 # 0 +0xFC62 0x9EDA # 0 +0xFC63 0x9EDE # 0 +0xFC64 0x9EE1 # 0 +0xFC65 0x9EE3 # 0 +0xFC66 0x9EE4 # 0 +0xFC67 0x9EE6 # 0 +0xFC68 0x9EE8 # 0 +0xFC69 0x9EEB # 0 +0xFC6A 0x9EEC # 0 +0xFC6B 0x9EED # 0 +0xFC6C 0x9EEE # 0 +0xFC6D 0x9EF0 # 0 +0xFC6E 0x9EF1 # 0 +0xFC6F 0x9EF2 # 0 +0xFC70 0x9EF3 # 0 +0xFC71 0x9EF4 # 0 +0xFC72 0x9EF5 # 0 +0xFC73 0x9EF6 # 0 +0xFC74 0x9EF7 # 0 +0xFC75 0x9EF8 # 0 +0xFC76 0x9EFA # 0 +0xFC77 0x9EFD # 0 +0xFC78 0x9EFF # 0 +0xFC79 0x9F00 # 0 +0xFC7A 0x9F01 # 0 +0xFC7B 0x9F02 # 0 +0xFC7C 0x9F03 # 0 +0xFC7D 0x9F04 # 0 +0xFC7E 0x9F05 # 0 +0xFC80 0x9F06 # 0 +0xFC81 0x9F07 # 0 +0xFC82 0x9F08 # 0 +0xFC83 0x9F09 # 0 +0xFC84 0x9F0A # 0 +0xFC85 0x9F0C # 0 +0xFC86 0x9F0F # 0 +0xFC87 0x9F11 # 0 +0xFC88 0x9F12 # 0 +0xFC89 0x9F14 # 0 +0xFC8A 0x9F15 # 0 +0xFC8B 0x9F16 # 0 +0xFC8C 0x9F18 # 0 +0xFC8D 0x9F1A # 0 +0xFC8E 0x9F1B # 0 +0xFC8F 0x9F1C # 0 +0xFC90 0x9F1D # 0 +0xFC91 0x9F1E # 0 +0xFC92 0x9F1F # 0 +0xFC93 0x9F21 # 0 +0xFC94 0x9F23 # 0 +0xFC95 0x9F24 # 0 +0xFC96 0x9F25 # 0 +0xFC97 0x9F26 # 0 +0xFC98 0x9F27 # 0 +0xFC99 0x9F28 # 0 +0xFC9A 0x9F29 # 0 +0xFC9B 0x9F2A # 0 +0xFC9C 0x9F2B # 0 +0xFC9D 0x9F2D # 0 +0xFC9E 0x9F2E # 0 +0xFC9F 0x9F30 # 0 +0xFCA0 0x9F31 # 0 +0xFCA1 0xE3AC # 0 +0xFCA2 0xE3AD # 0 +0xFCA3 0xE3AE # 0 +0xFCA4 0xE3AF # 0 +0xFCA5 0xE3B0 # 0 +0xFCA6 0xE3B1 # 0 +0xFCA7 0xE3B2 # 0 +0xFCA8 0xE3B3 # 0 +0xFCA9 0xE3B4 # 0 +0xFCAA 0xE3B5 # 0 +0xFCAB 0xE3B6 # 0 +0xFCAC 0xE3B7 # 0 +0xFCAD 0xE3B8 # 0 +0xFCAE 0xE3B9 # 0 +0xFCAF 0xE3BA # 0 +0xFCB0 0xE3BB # 0 +0xFCB1 0xE3BC # 0 +0xFCB2 0xE3BD # 0 +0xFCB3 0xE3BE # 0 +0xFCB4 0xE3BF # 0 +0xFCB5 0xE3C0 # 0 +0xFCB6 0xE3C1 # 0 +0xFCB7 0xE3C2 # 0 +0xFCB8 0xE3C3 # 0 +0xFCB9 0xE3C4 # 0 +0xFCBA 0xE3C5 # 0 +0xFCBB 0xE3C6 # 0 +0xFCBC 0xE3C7 # 0 +0xFCBD 0xE3C8 # 0 +0xFCBE 0xE3C9 # 0 +0xFCBF 0xE3CA # 0 +0xFCC0 0xE3CB # 0 +0xFCC1 0xE3CC # 0 +0xFCC2 0xE3CD # 0 +0xFCC3 0xE3CE # 0 +0xFCC4 0xE3CF # 0 +0xFCC5 0xE3D0 # 0 +0xFCC6 0xE3D1 # 0 +0xFCC7 0xE3D2 # 0 +0xFCC8 0xE3D3 # 0 +0xFCC9 0xE3D4 # 0 +0xFCCA 0xE3D5 # 0 +0xFCCB 0xE3D6 # 0 +0xFCCC 0xE3D7 # 0 +0xFCCD 0xE3D8 # 0 +0xFCCE 0xE3D9 # 0 +0xFCCF 0xE3DA # 0 +0xFCD0 0xE3DB # 0 +0xFCD1 0xE3DC # 0 +0xFCD2 0xE3DD # 0 +0xFCD3 0xE3DE # 0 +0xFCD4 0xE3DF # 0 +0xFCD5 0xE3E0 # 0 +0xFCD6 0xE3E1 # 0 +0xFCD7 0xE3E2 # 0 +0xFCD8 0xE3E3 # 0 +0xFCD9 0xE3E4 # 0 +0xFCDA 0xE3E5 # 0 +0xFCDB 0xE3E6 # 0 +0xFCDC 0xE3E7 # 0 +0xFCDD 0xE3E8 # 0 +0xFCDE 0xE3E9 # 0 +0xFCDF 0xE3EA # 0 +0xFCE0 0xE3EB # 0 +0xFCE1 0xE3EC # 0 +0xFCE2 0xE3ED # 0 +0xFCE3 0xE3EE # 0 +0xFCE4 0xE3EF # 0 +0xFCE5 0xE3F0 # 0 +0xFCE6 0xE3F1 # 0 +0xFCE7 0xE3F2 # 0 +0xFCE8 0xE3F3 # 0 +0xFCE9 0xE3F4 # 0 +0xFCEA 0xE3F5 # 0 +0xFCEB 0xE3F6 # 0 +0xFCEC 0xE3F7 # 0 +0xFCED 0xE3F8 # 0 +0xFCEE 0xE3F9 # 0 +0xFCEF 0xE3FA # 0 +0xFCF0 0xE3FB # 0 +0xFCF1 0xE3FC # 0 +0xFCF2 0xE3FD # 0 +0xFCF3 0xE3FE # 0 +0xFCF4 0xE3FF # 0 +0xFCF5 0xE400 # 0 +0xFCF6 0xE401 # 0 +0xFCF7 0xE402 # 0 +0xFCF8 0xE403 # 0 +0xFCF9 0xE404 # 0 +0xFCFA 0xE405 # 0 +0xFCFB 0xE406 # 0 +0xFCFC 0xE407 # 0 +0xFCFD 0xE408 # 0 +0xFCFE 0xE409 # 0 +0xFD40 0x9F32 # 0 +0xFD41 0x9F33 # 0 +0xFD42 0x9F34 # 0 +0xFD43 0x9F35 # 0 +0xFD44 0x9F36 # 0 +0xFD45 0x9F38 # 0 +0xFD46 0x9F3A # 0 +0xFD47 0x9F3C # 0 +0xFD48 0x9F3F # 0 +0xFD49 0x9F40 # 0 +0xFD4A 0x9F41 # 0 +0xFD4B 0x9F42 # 0 +0xFD4C 0x9F43 # 0 +0xFD4D 0x9F45 # 0 +0xFD4E 0x9F46 # 0 +0xFD4F 0x9F47 # 0 +0xFD50 0x9F48 # 0 +0xFD51 0x9F49 # 0 +0xFD52 0x9F4A # 0 +0xFD53 0x9F4B # 0 +0xFD54 0x9F4C # 0 +0xFD55 0x9F4D # 0 +0xFD56 0x9F4E # 0 +0xFD57 0x9F4F # 0 +0xFD58 0x9F52 # 0 +0xFD59 0x9F53 # 0 +0xFD5A 0x9F54 # 0 +0xFD5B 0x9F55 # 0 +0xFD5C 0x9F56 # 0 +0xFD5D 0x9F57 # 0 +0xFD5E 0x9F58 # 0 +0xFD5F 0x9F59 # 0 +0xFD60 0x9F5A # 0 +0xFD61 0x9F5B # 0 +0xFD62 0x9F5C # 0 +0xFD63 0x9F5D # 0 +0xFD64 0x9F5E # 0 +0xFD65 0x9F5F # 0 +0xFD66 0x9F60 # 0 +0xFD67 0x9F61 # 0 +0xFD68 0x9F62 # 0 +0xFD69 0x9F63 # 0 +0xFD6A 0x9F64 # 0 +0xFD6B 0x9F65 # 0 +0xFD6C 0x9F66 # 0 +0xFD6D 0x9F67 # 0 +0xFD6E 0x9F68 # 0 +0xFD6F 0x9F69 # 0 +0xFD70 0x9F6A # 0 +0xFD71 0x9F6B # 0 +0xFD72 0x9F6C # 0 +0xFD73 0x9F6D # 0 +0xFD74 0x9F6E # 0 +0xFD75 0x9F6F # 0 +0xFD76 0x9F70 # 0 +0xFD77 0x9F71 # 0 +0xFD78 0x9F72 # 0 +0xFD79 0x9F73 # 0 +0xFD7A 0x9F74 # 0 +0xFD7B 0x9F75 # 0 +0xFD7C 0x9F76 # 0 +0xFD7D 0x9F77 # 0 +0xFD7E 0x9F78 # 0 +0xFD80 0x9F79 # 0 +0xFD81 0x9F7A # 0 +0xFD82 0x9F7B # 0 +0xFD83 0x9F7C # 0 +0xFD84 0x9F7D # 0 +0xFD85 0x9F7E # 0 +0xFD86 0x9F81 # 0 +0xFD87 0x9F82 # 0 +0xFD88 0x9F8D # 0 +0xFD89 0x9F8E # 0 +0xFD8A 0x9F8F # 0 +0xFD8B 0x9F90 # 0 +0xFD8C 0x9F91 # 0 +0xFD8D 0x9F92 # 0 +0xFD8E 0x9F93 # 0 +0xFD8F 0x9F94 # 0 +0xFD90 0x9F95 # 0 +0xFD91 0x9F96 # 0 +0xFD92 0x9F97 # 0 +0xFD93 0x9F98 # 0 +0xFD94 0x9F9C # 0 +0xFD95 0x9F9D # 0 +0xFD96 0x9F9E # 0 +0xFD97 0x9FA1 # 0 +0xFD98 0x9FA2 # 0 +0xFD99 0x9FA3 # 0 +0xFD9A 0x9FA4 # 0 +0xFD9B 0x9FA5 # 0 +0xFD9C 0xF92C # 0 +0xFD9D 0xF979 # 0 +0xFD9E 0xF995 # 0 +0xFD9F 0xF9E7 # 0 +0xFDA0 0xF9F1 # 0 +0xFDA1 0xE40A # 0 +0xFDA2 0xE40B # 0 +0xFDA3 0xE40C # 0 +0xFDA4 0xE40D # 0 +0xFDA5 0xE40E # 0 +0xFDA6 0xE40F # 0 +0xFDA7 0xE410 # 0 +0xFDA8 0xE411 # 0 +0xFDA9 0xE412 # 0 +0xFDAA 0xE413 # 0 +0xFDAB 0xE414 # 0 +0xFDAC 0xE415 # 0 +0xFDAD 0xE416 # 0 +0xFDAE 0xE417 # 0 +0xFDAF 0xE418 # 0 +0xFDB0 0xE419 # 0 +0xFDB1 0xE41A # 0 +0xFDB2 0xE41B # 0 +0xFDB3 0xE41C # 0 +0xFDB4 0xE41D # 0 +0xFDB5 0xE41E # 0 +0xFDB6 0xE41F # 0 +0xFDB7 0xE420 # 0 +0xFDB8 0xE421 # 0 +0xFDB9 0xE422 # 0 +0xFDBA 0xE423 # 0 +0xFDBB 0xE424 # 0 +0xFDBC 0xE425 # 0 +0xFDBD 0xE426 # 0 +0xFDBE 0xE427 # 0 +0xFDBF 0xE428 # 0 +0xFDC0 0xE429 # 0 +0xFDC1 0xE42A # 0 +0xFDC2 0xE42B # 0 +0xFDC3 0xE42C # 0 +0xFDC4 0xE42D # 0 +0xFDC5 0xE42E # 0 +0xFDC6 0xE42F # 0 +0xFDC7 0xE430 # 0 +0xFDC8 0xE431 # 0 +0xFDC9 0xE432 # 0 +0xFDCA 0xE433 # 0 +0xFDCB 0xE434 # 0 +0xFDCC 0xE435 # 0 +0xFDCD 0xE436 # 0 +0xFDCE 0xE437 # 0 +0xFDCF 0xE438 # 0 +0xFDD0 0xE439 # 0 +0xFDD1 0xE43A # 0 +0xFDD2 0xE43B # 0 +0xFDD3 0xE43C # 0 +0xFDD4 0xE43D # 0 +0xFDD5 0xE43E # 0 +0xFDD6 0xE43F # 0 +0xFDD7 0xE440 # 0 +0xFDD8 0xE441 # 0 +0xFDD9 0xE442 # 0 +0xFDDA 0xE443 # 0 +0xFDDB 0xE444 # 0 +0xFDDC 0xE445 # 0 +0xFDDD 0xE446 # 0 +0xFDDE 0xE447 # 0 +0xFDDF 0xE448 # 0 +0xFDE0 0xE449 # 0 +0xFDE1 0xE44A # 0 +0xFDE2 0xE44B # 0 +0xFDE3 0xE44C # 0 +0xFDE4 0xE44D # 0 +0xFDE5 0xE44E # 0 +0xFDE6 0xE44F # 0 +0xFDE7 0xE450 # 0 +0xFDE8 0xE451 # 0 +0xFDE9 0xE452 # 0 +0xFDEA 0xE453 # 0 +0xFDEB 0xE454 # 0 +0xFDEC 0xE455 # 0 +0xFDED 0xE456 # 0 +0xFDEE 0xE457 # 0 +0xFDEF 0xE458 # 0 +0xFDF0 0xE459 # 0 +0xFDF1 0xE45A # 0 +0xFDF2 0xE45B # 0 +0xFDF3 0xE45C # 0 +0xFDF4 0xE45D # 0 +0xFDF5 0xE45E # 0 +0xFDF6 0xE45F # 0 +0xFDF7 0xE460 # 0 +0xFDF8 0xE461 # 0 +0xFDF9 0xE462 # 0 +0xFDFA 0xE463 # 0 +0xFDFB 0xE464 # 0 +0xFDFC 0xE465 # 0 +0xFDFD 0xE466 # 0 +0xFDFE 0xE467 # 0 +0xFE40 0xFA0C # 0 +0xFE41 0xFA0D # 0 +0xFE42 0xFA0E # 0 +0xFE43 0xFA0F # 0 +0xFE44 0xFA11 # 0 +0xFE45 0xFA13 # 0 +0xFE46 0xFA14 # 0 +0xFE47 0xFA18 # 0 +0xFE48 0xFA1F # 0 +0xFE49 0xFA20 # 0 +0xFE4A 0xFA21 # 0 +0xFE4B 0xFA23 # 0 +0xFE4C 0xFA24 # 0 +0xFE4D 0xFA27 # 0 +0xFE4E 0xFA28 # 0 +0xFE4F 0xFA29 # 0 +0xFE50 0xE815 # 0 +0xFE51 0xE816 # 0 +0xFE52 0xE817 # 0 +0xFE53 0xE818 # 0 +0xFE54 0xE819 # 0 +0xFE55 0xE81A # 0 +0xFE56 0xE81B # 0 +0xFE57 0xE81C # 0 +0xFE58 0xE81D # 0 +0xFE59 0xE81E # 0 +0xFE5A 0xE81F # 0 +0xFE5B 0xE820 # 0 +0xFE5C 0xE821 # 0 +0xFE5D 0xE822 # 0 +0xFE5E 0xE823 # 0 +0xFE5F 0xE824 # 0 +0xFE60 0xE825 # 0 +0xFE61 0xE826 # 0 +0xFE62 0xE827 # 0 +0xFE63 0xE828 # 0 +0xFE64 0xE829 # 0 +0xFE65 0xE82A # 0 +0xFE66 0xE82B # 0 +0xFE67 0xE82C # 0 +0xFE68 0xE82D # 0 +0xFE69 0xE82E # 0 +0xFE6A 0xE82F # 0 +0xFE6B 0xE830 # 0 +0xFE6C 0xE831 # 0 +0xFE6D 0xE832 # 0 +0xFE6E 0xE833 # 0 +0xFE6F 0xE834 # 0 +0xFE70 0xE835 # 0 +0xFE71 0xE836 # 0 +0xFE72 0xE837 # 0 +0xFE73 0xE838 # 0 +0xFE74 0xE839 # 0 +0xFE75 0xE83A # 0 +0xFE76 0xE83B # 0 +0xFE77 0xE83C # 0 +0xFE78 0xE83D # 0 +0xFE79 0xE83E # 0 +0xFE7A 0xE83F # 0 +0xFE7B 0xE840 # 0 +0xFE7C 0xE841 # 0 +0xFE7D 0xE842 # 0 +0xFE7E 0xE843 # 0 +0xFE80 0xE844 # 0 +0xFE81 0xE845 # 0 +0xFE82 0xE846 # 0 +0xFE83 0xE847 # 0 +0xFE84 0xE848 # 0 +0xFE85 0xE849 # 0 +0xFE86 0xE84A # 0 +0xFE87 0xE84B # 0 +0xFE88 0xE84C # 0 +0xFE89 0xE84D # 0 +0xFE8A 0xE84E # 0 +0xFE8B 0xE84F # 0 +0xFE8C 0xE850 # 0 +0xFE8D 0xE851 # 0 +0xFE8E 0xE852 # 0 +0xFE8F 0xE853 # 0 +0xFE90 0xE854 # 0 +0xFE91 0xE855 # 0 +0xFE92 0xE856 # 0 +0xFE93 0xE857 # 0 +0xFE94 0xE858 # 0 +0xFE95 0xE859 # 0 +0xFE96 0xE85A # 0 +0xFE97 0xE85B # 0 +0xFE98 0xE85C # 0 +0xFE99 0xE85D # 0 +0xFE9A 0xE85E # 0 +0xFE9B 0xE85F # 0 +0xFE9C 0xE860 # 0 +0xFE9D 0xE861 # 0 +0xFE9E 0xE862 # 0 +0xFE9F 0xE863 # 0 +0xFEA0 0xE864 # 0 +0xFEA1 0xE468 # 0 +0xFEA2 0xE469 # 0 +0xFEA3 0xE46A # 0 +0xFEA4 0xE46B # 0 +0xFEA5 0xE46C # 0 +0xFEA6 0xE46D # 0 +0xFEA7 0xE46E # 0 +0xFEA8 0xE46F # 0 +0xFEA9 0xE470 # 0 +0xFEAA 0xE471 # 0 +0xFEAB 0xE472 # 0 +0xFEAC 0xE473 # 0 +0xFEAD 0xE474 # 0 +0xFEAE 0xE475 # 0 +0xFEAF 0xE476 # 0 +0xFEB0 0xE477 # 0 +0xFEB1 0xE478 # 0 +0xFEB2 0xE479 # 0 +0xFEB3 0xE47A # 0 +0xFEB4 0xE47B # 0 +0xFEB5 0xE47C # 0 +0xFEB6 0xE47D # 0 +0xFEB7 0xE47E # 0 +0xFEB8 0xE47F # 0 +0xFEB9 0xE480 # 0 +0xFEBA 0xE481 # 0 +0xFEBB 0xE482 # 0 +0xFEBC 0xE483 # 0 +0xFEBD 0xE484 # 0 +0xFEBE 0xE485 # 0 +0xFEBF 0xE486 # 0 +0xFEC0 0xE487 # 0 +0xFEC1 0xE488 # 0 +0xFEC2 0xE489 # 0 +0xFEC3 0xE48A # 0 +0xFEC4 0xE48B # 0 +0xFEC5 0xE48C # 0 +0xFEC6 0xE48D # 0 +0xFEC7 0xE48E # 0 +0xFEC8 0xE48F # 0 +0xFEC9 0xE490 # 0 +0xFECA 0xE491 # 0 +0xFECB 0xE492 # 0 +0xFECC 0xE493 # 0 +0xFECD 0xE494 # 0 +0xFECE 0xE495 # 0 +0xFECF 0xE496 # 0 +0xFED0 0xE497 # 0 +0xFED1 0xE498 # 0 +0xFED2 0xE499 # 0 +0xFED3 0xE49A # 0 +0xFED4 0xE49B # 0 +0xFED5 0xE49C # 0 +0xFED6 0xE49D # 0 +0xFED7 0xE49E # 0 +0xFED8 0xE49F # 0 +0xFED9 0xE4A0 # 0 +0xFEDA 0xE4A1 # 0 +0xFEDB 0xE4A2 # 0 +0xFEDC 0xE4A3 # 0 +0xFEDD 0xE4A4 # 0 +0xFEDE 0xE4A5 # 0 +0xFEDF 0xE4A6 # 0 +0xFEE0 0xE4A7 # 0 +0xFEE1 0xE4A8 # 0 +0xFEE2 0xE4A9 # 0 +0xFEE3 0xE4AA # 0 +0xFEE4 0xE4AB # 0 +0xFEE5 0xE4AC # 0 +0xFEE6 0xE4AD # 0 +0xFEE7 0xE4AE # 0 +0xFEE8 0xE4AF # 0 +0xFEE9 0xE4B0 # 0 +0xFEEA 0xE4B1 # 0 +0xFEEB 0xE4B2 # 0 +0xFEEC 0xE4B3 # 0 +0xFEED 0xE4B4 # 0 +0xFEEE 0xE4B5 # 0 +0xFEEF 0xE4B6 # 0 +0xFEF0 0xE4B7 # 0 +0xFEF1 0xE4B8 # 0 +0xFEF2 0xE4B9 # 0 +0xFEF3 0xE4BA # 0 +0xFEF4 0xE4BB # 0 +0xFEF5 0xE4BC # 0 +0xFEF6 0xE4BD # 0 +0xFEF7 0xE4BE # 0 +0xFEF8 0xE4BF # 0 +0xFEF9 0xE4C0 # 0 +0xFEFA 0xE4C1 # 0 +0xFEFB 0xE4C2 # 0 +0xFEFC 0xE4C3 # 0 +0xFEFD 0xE4C4 # 0 +0xFEFE 0xE4C5 # 0 diff --git a/data/windows-949.txt b/data/windows-949.txt new file mode 100644 index 0000000000..68cf9fa7fc --- /dev/null +++ b/data/windows-949.txt @@ -0,0 +1,17367 @@ +# cp949.txt - Legacy to Unicode charmap +0x0000 0x0000 # 0 +0x0001 0x0001 # 0 +0x0002 0x0002 # 0 +0x0003 0x0003 # 0 +0x0004 0x0004 # 0 +0x0005 0x0005 # 0 +0x0006 0x0006 # 0 +0x0007 0x0007 # 0 +0x0008 0x0008 # 0 +0x0009 0x0009 # 0 +0x000A 0x000A # 0 +0x000B 0x000B # 0 +0x000C 0x000C # 0 +0x000D 0x000D # 0 +0x000E 0x000E # 0 +0x000F 0x000F # 0 +0x0010 0x0010 # 0 +0x0011 0x0011 # 0 +0x0012 0x0012 # 0 +0x0013 0x0013 # 0 +0x0014 0x0014 # 0 +0x0015 0x0015 # 0 +0x0016 0x0016 # 0 +0x0017 0x0017 # 0 +0x0018 0x0018 # 0 +0x0019 0x0019 # 0 +0x001A 0x001A # 0 +0x001B 0x001B # 0 +0x001C 0x001C # 0 +0x001D 0x001D # 0 +0x001E 0x001E # 0 +0x001F 0x001F # 0 +0x0020 0x0020 # 0 +0x0021 0x0021 # 0 +0x0022 0x0022 # 0 +0x0023 0x0023 # 0 +0x0024 0x0024 # 0 +0x0025 0x0025 # 0 +0x0026 0x0026 # 0 +0x0027 0x0027 # 0 +0x0028 0x0028 # 0 +0x0029 0x0029 # 0 +0x002A 0x002A # 0 +0x002B 0x002B # 0 +0x002C 0x002C # 0 +0x002D 0x002D # 0 +0x002E 0x002E # 0 +0x002F 0x002F # 0 +0x0030 0x0030 # 0 +0x0031 0x0031 # 0 +0x0032 0x0032 # 0 +0x0033 0x0033 # 0 +0x0034 0x0034 # 0 +0x0035 0x0035 # 0 +0x0036 0x0036 # 0 +0x0037 0x0037 # 0 +0x0038 0x0038 # 0 +0x0039 0x0039 # 0 +0x003A 0x003A # 0 +0x003B 0x003B # 0 +0x003C 0x003C # 0 +0x003D 0x003D # 0 +0x003E 0x003E # 0 +0x003F 0x003F # 0 +0x0040 0x0040 # 0 +0x0041 0x0041 # 0 +0x0042 0x0042 # 0 +0x0043 0x0043 # 0 +0x0044 0x0044 # 0 +0x0045 0x0045 # 0 +0x0046 0x0046 # 0 +0x0047 0x0047 # 0 +0x0048 0x0048 # 0 +0x0049 0x0049 # 0 +0x004A 0x004A # 0 +0x004B 0x004B # 0 +0x004C 0x004C # 0 +0x004D 0x004D # 0 +0x004E 0x004E # 0 +0x004F 0x004F # 0 +0x0050 0x0050 # 0 +0x0051 0x0051 # 0 +0x0052 0x0052 # 0 +0x0053 0x0053 # 0 +0x0054 0x0054 # 0 +0x0055 0x0055 # 0 +0x0056 0x0056 # 0 +0x0057 0x0057 # 0 +0x0058 0x0058 # 0 +0x0059 0x0059 # 0 +0x005A 0x005A # 0 +0x005B 0x005B # 0 +0x005C 0x005C # 0 +0x005D 0x005D # 0 +0x005E 0x005E # 0 +0x005F 0x005F # 0 +0x0060 0x0060 # 0 +0x0061 0x0061 # 0 +0x0062 0x0062 # 0 +0x0063 0x0063 # 0 +0x0064 0x0064 # 0 +0x0065 0x0065 # 0 +0x0066 0x0066 # 0 +0x0067 0x0067 # 0 +0x0068 0x0068 # 0 +0x0069 0x0069 # 0 +0x006A 0x006A # 0 +0x006B 0x006B # 0 +0x006C 0x006C # 0 +0x006D 0x006D # 0 +0x006E 0x006E # 0 +0x006F 0x006F # 0 +0x0070 0x0070 # 0 +0x0071 0x0071 # 0 +0x0072 0x0072 # 0 +0x0073 0x0073 # 0 +0x0074 0x0074 # 0 +0x0075 0x0075 # 0 +0x0076 0x0076 # 0 +0x0077 0x0077 # 0 +0x0078 0x0078 # 0 +0x0079 0x0079 # 0 +0x007A 0x007A # 0 +0x007B 0x007B # 0 +0x007C 0x007C # 0 +0x007D 0x007D # 0 +0x007E 0x007E # 0 +0x007F 0x007F # 0 +0x0080 0x0080 # 0 +0x00FF 0xF8F7 # 0 +0x8141 0xAC02 # 0 +0x8142 0xAC03 # 0 +0x8143 0xAC05 # 0 +0x8144 0xAC06 # 0 +0x8145 0xAC0B # 0 +0x8146 0xAC0C # 0 +0x8147 0xAC0D # 0 +0x8148 0xAC0E # 0 +0x8149 0xAC0F # 0 +0x814A 0xAC18 # 0 +0x814B 0xAC1E # 0 +0x814C 0xAC1F # 0 +0x814D 0xAC21 # 0 +0x814E 0xAC22 # 0 +0x814F 0xAC23 # 0 +0x8150 0xAC25 # 0 +0x8151 0xAC26 # 0 +0x8152 0xAC27 # 0 +0x8153 0xAC28 # 0 +0x8154 0xAC29 # 0 +0x8155 0xAC2A # 0 +0x8156 0xAC2B # 0 +0x8157 0xAC2E # 0 +0x8158 0xAC32 # 0 +0x8159 0xAC33 # 0 +0x815A 0xAC34 # 0 +0x8161 0xAC35 # 0 +0x8162 0xAC36 # 0 +0x8163 0xAC37 # 0 +0x8164 0xAC3A # 0 +0x8165 0xAC3B # 0 +0x8166 0xAC3D # 0 +0x8167 0xAC3E # 0 +0x8168 0xAC3F # 0 +0x8169 0xAC41 # 0 +0x816A 0xAC42 # 0 +0x816B 0xAC43 # 0 +0x816C 0xAC44 # 0 +0x816D 0xAC45 # 0 +0x816E 0xAC46 # 0 +0x816F 0xAC47 # 0 +0x8170 0xAC48 # 0 +0x8171 0xAC49 # 0 +0x8172 0xAC4A # 0 +0x8173 0xAC4C # 0 +0x8174 0xAC4E # 0 +0x8175 0xAC4F # 0 +0x8176 0xAC50 # 0 +0x8177 0xAC51 # 0 +0x8178 0xAC52 # 0 +0x8179 0xAC53 # 0 +0x817A 0xAC55 # 0 +0x8181 0xAC56 # 0 +0x8182 0xAC57 # 0 +0x8183 0xAC59 # 0 +0x8184 0xAC5A # 0 +0x8185 0xAC5B # 0 +0x8186 0xAC5D # 0 +0x8187 0xAC5E # 0 +0x8188 0xAC5F # 0 +0x8189 0xAC60 # 0 +0x818A 0xAC61 # 0 +0x818B 0xAC62 # 0 +0x818C 0xAC63 # 0 +0x818D 0xAC64 # 0 +0x818E 0xAC65 # 0 +0x818F 0xAC66 # 0 +0x8190 0xAC67 # 0 +0x8191 0xAC68 # 0 +0x8192 0xAC69 # 0 +0x8193 0xAC6A # 0 +0x8194 0xAC6B # 0 +0x8195 0xAC6C # 0 +0x8196 0xAC6D # 0 +0x8197 0xAC6E # 0 +0x8198 0xAC6F # 0 +0x8199 0xAC72 # 0 +0x819A 0xAC73 # 0 +0x819B 0xAC75 # 0 +0x819C 0xAC76 # 0 +0x819D 0xAC79 # 0 +0x819E 0xAC7B # 0 +0x819F 0xAC7C # 0 +0x81A0 0xAC7D # 0 +0x81A1 0xAC7E # 0 +0x81A2 0xAC7F # 0 +0x81A3 0xAC82 # 0 +0x81A4 0xAC87 # 0 +0x81A5 0xAC88 # 0 +0x81A6 0xAC8D # 0 +0x81A7 0xAC8E # 0 +0x81A8 0xAC8F # 0 +0x81A9 0xAC91 # 0 +0x81AA 0xAC92 # 0 +0x81AB 0xAC93 # 0 +0x81AC 0xAC95 # 0 +0x81AD 0xAC96 # 0 +0x81AE 0xAC97 # 0 +0x81AF 0xAC98 # 0 +0x81B0 0xAC99 # 0 +0x81B1 0xAC9A # 0 +0x81B2 0xAC9B # 0 +0x81B3 0xAC9E # 0 +0x81B4 0xACA2 # 0 +0x81B5 0xACA3 # 0 +0x81B6 0xACA4 # 0 +0x81B7 0xACA5 # 0 +0x81B8 0xACA6 # 0 +0x81B9 0xACA7 # 0 +0x81BA 0xACAB # 0 +0x81BB 0xACAD # 0 +0x81BC 0xACAE # 0 +0x81BD 0xACB1 # 0 +0x81BE 0xACB2 # 0 +0x81BF 0xACB3 # 0 +0x81C0 0xACB4 # 0 +0x81C1 0xACB5 # 0 +0x81C2 0xACB6 # 0 +0x81C3 0xACB7 # 0 +0x81C4 0xACBA # 0 +0x81C5 0xACBE # 0 +0x81C6 0xACBF # 0 +0x81C7 0xACC0 # 0 +0x81C8 0xACC2 # 0 +0x81C9 0xACC3 # 0 +0x81CA 0xACC5 # 0 +0x81CB 0xACC6 # 0 +0x81CC 0xACC7 # 0 +0x81CD 0xACC9 # 0 +0x81CE 0xACCA # 0 +0x81CF 0xACCB # 0 +0x81D0 0xACCD # 0 +0x81D1 0xACCE # 0 +0x81D2 0xACCF # 0 +0x81D3 0xACD0 # 0 +0x81D4 0xACD1 # 0 +0x81D5 0xACD2 # 0 +0x81D6 0xACD3 # 0 +0x81D7 0xACD4 # 0 +0x81D8 0xACD6 # 0 +0x81D9 0xACD8 # 0 +0x81DA 0xACD9 # 0 +0x81DB 0xACDA # 0 +0x81DC 0xACDB # 0 +0x81DD 0xACDC # 0 +0x81DE 0xACDD # 0 +0x81DF 0xACDE # 0 +0x81E0 0xACDF # 0 +0x81E1 0xACE2 # 0 +0x81E2 0xACE3 # 0 +0x81E3 0xACE5 # 0 +0x81E4 0xACE6 # 0 +0x81E5 0xACE9 # 0 +0x81E6 0xACEB # 0 +0x81E7 0xACED # 0 +0x81E8 0xACEE # 0 +0x81E9 0xACF2 # 0 +0x81EA 0xACF4 # 0 +0x81EB 0xACF7 # 0 +0x81EC 0xACF8 # 0 +0x81ED 0xACF9 # 0 +0x81EE 0xACFA # 0 +0x81EF 0xACFB # 0 +0x81F0 0xACFE # 0 +0x81F1 0xACFF # 0 +0x81F2 0xAD01 # 0 +0x81F3 0xAD02 # 0 +0x81F4 0xAD03 # 0 +0x81F5 0xAD05 # 0 +0x81F6 0xAD07 # 0 +0x81F7 0xAD08 # 0 +0x81F8 0xAD09 # 0 +0x81F9 0xAD0A # 0 +0x81FA 0xAD0B # 0 +0x81FB 0xAD0E # 0 +0x81FC 0xAD10 # 0 +0x81FD 0xAD12 # 0 +0x81FE 0xAD13 # 0 +0x8241 0xAD14 # 0 +0x8242 0xAD15 # 0 +0x8243 0xAD16 # 0 +0x8244 0xAD17 # 0 +0x8245 0xAD19 # 0 +0x8246 0xAD1A # 0 +0x8247 0xAD1B # 0 +0x8248 0xAD1D # 0 +0x8249 0xAD1E # 0 +0x824A 0xAD1F # 0 +0x824B 0xAD21 # 0 +0x824C 0xAD22 # 0 +0x824D 0xAD23 # 0 +0x824E 0xAD24 # 0 +0x824F 0xAD25 # 0 +0x8250 0xAD26 # 0 +0x8251 0xAD27 # 0 +0x8252 0xAD28 # 0 +0x8253 0xAD2A # 0 +0x8254 0xAD2B # 0 +0x8255 0xAD2E # 0 +0x8256 0xAD2F # 0 +0x8257 0xAD30 # 0 +0x8258 0xAD31 # 0 +0x8259 0xAD32 # 0 +0x825A 0xAD33 # 0 +0x8261 0xAD36 # 0 +0x8262 0xAD37 # 0 +0x8263 0xAD39 # 0 +0x8264 0xAD3A # 0 +0x8265 0xAD3B # 0 +0x8266 0xAD3D # 0 +0x8267 0xAD3E # 0 +0x8268 0xAD3F # 0 +0x8269 0xAD40 # 0 +0x826A 0xAD41 # 0 +0x826B 0xAD42 # 0 +0x826C 0xAD43 # 0 +0x826D 0xAD46 # 0 +0x826E 0xAD48 # 0 +0x826F 0xAD4A # 0 +0x8270 0xAD4B # 0 +0x8271 0xAD4C # 0 +0x8272 0xAD4D # 0 +0x8273 0xAD4E # 0 +0x8274 0xAD4F # 0 +0x8275 0xAD51 # 0 +0x8276 0xAD52 # 0 +0x8277 0xAD53 # 0 +0x8278 0xAD55 # 0 +0x8279 0xAD56 # 0 +0x827A 0xAD57 # 0 +0x8281 0xAD59 # 0 +0x8282 0xAD5A # 0 +0x8283 0xAD5B # 0 +0x8284 0xAD5C # 0 +0x8285 0xAD5D # 0 +0x8286 0xAD5E # 0 +0x8287 0xAD5F # 0 +0x8288 0xAD60 # 0 +0x8289 0xAD62 # 0 +0x828A 0xAD64 # 0 +0x828B 0xAD65 # 0 +0x828C 0xAD66 # 0 +0x828D 0xAD67 # 0 +0x828E 0xAD68 # 0 +0x828F 0xAD69 # 0 +0x8290 0xAD6A # 0 +0x8291 0xAD6B # 0 +0x8292 0xAD6E # 0 +0x8293 0xAD6F # 0 +0x8294 0xAD71 # 0 +0x8295 0xAD72 # 0 +0x8296 0xAD77 # 0 +0x8297 0xAD78 # 0 +0x8298 0xAD79 # 0 +0x8299 0xAD7A # 0 +0x829A 0xAD7E # 0 +0x829B 0xAD80 # 0 +0x829C 0xAD83 # 0 +0x829D 0xAD84 # 0 +0x829E 0xAD85 # 0 +0x829F 0xAD86 # 0 +0x82A0 0xAD87 # 0 +0x82A1 0xAD8A # 0 +0x82A2 0xAD8B # 0 +0x82A3 0xAD8D # 0 +0x82A4 0xAD8E # 0 +0x82A5 0xAD8F # 0 +0x82A6 0xAD91 # 0 +0x82A7 0xAD92 # 0 +0x82A8 0xAD93 # 0 +0x82A9 0xAD94 # 0 +0x82AA 0xAD95 # 0 +0x82AB 0xAD96 # 0 +0x82AC 0xAD97 # 0 +0x82AD 0xAD98 # 0 +0x82AE 0xAD99 # 0 +0x82AF 0xAD9A # 0 +0x82B0 0xAD9B # 0 +0x82B1 0xAD9E # 0 +0x82B2 0xAD9F # 0 +0x82B3 0xADA0 # 0 +0x82B4 0xADA1 # 0 +0x82B5 0xADA2 # 0 +0x82B6 0xADA3 # 0 +0x82B7 0xADA5 # 0 +0x82B8 0xADA6 # 0 +0x82B9 0xADA7 # 0 +0x82BA 0xADA8 # 0 +0x82BB 0xADA9 # 0 +0x82BC 0xADAA # 0 +0x82BD 0xADAB # 0 +0x82BE 0xADAC # 0 +0x82BF 0xADAD # 0 +0x82C0 0xADAE # 0 +0x82C1 0xADAF # 0 +0x82C2 0xADB0 # 0 +0x82C3 0xADB1 # 0 +0x82C4 0xADB2 # 0 +0x82C5 0xADB3 # 0 +0x82C6 0xADB4 # 0 +0x82C7 0xADB5 # 0 +0x82C8 0xADB6 # 0 +0x82C9 0xADB8 # 0 +0x82CA 0xADB9 # 0 +0x82CB 0xADBA # 0 +0x82CC 0xADBB # 0 +0x82CD 0xADBC # 0 +0x82CE 0xADBD # 0 +0x82CF 0xADBE # 0 +0x82D0 0xADBF # 0 +0x82D1 0xADC2 # 0 +0x82D2 0xADC3 # 0 +0x82D3 0xADC5 # 0 +0x82D4 0xADC6 # 0 +0x82D5 0xADC7 # 0 +0x82D6 0xADC9 # 0 +0x82D7 0xADCA # 0 +0x82D8 0xADCB # 0 +0x82D9 0xADCC # 0 +0x82DA 0xADCD # 0 +0x82DB 0xADCE # 0 +0x82DC 0xADCF # 0 +0x82DD 0xADD2 # 0 +0x82DE 0xADD4 # 0 +0x82DF 0xADD5 # 0 +0x82E0 0xADD6 # 0 +0x82E1 0xADD7 # 0 +0x82E2 0xADD8 # 0 +0x82E3 0xADD9 # 0 +0x82E4 0xADDA # 0 +0x82E5 0xADDB # 0 +0x82E6 0xADDD # 0 +0x82E7 0xADDE # 0 +0x82E8 0xADDF # 0 +0x82E9 0xADE1 # 0 +0x82EA 0xADE2 # 0 +0x82EB 0xADE3 # 0 +0x82EC 0xADE5 # 0 +0x82ED 0xADE6 # 0 +0x82EE 0xADE7 # 0 +0x82EF 0xADE8 # 0 +0x82F0 0xADE9 # 0 +0x82F1 0xADEA # 0 +0x82F2 0xADEB # 0 +0x82F3 0xADEC # 0 +0x82F4 0xADED # 0 +0x82F5 0xADEE # 0 +0x82F6 0xADEF # 0 +0x82F7 0xADF0 # 0 +0x82F8 0xADF1 # 0 +0x82F9 0xADF2 # 0 +0x82FA 0xADF3 # 0 +0x82FB 0xADF4 # 0 +0x82FC 0xADF5 # 0 +0x82FD 0xADF6 # 0 +0x82FE 0xADF7 # 0 +0x8341 0xADFA # 0 +0x8342 0xADFB # 0 +0x8343 0xADFD # 0 +0x8344 0xADFE # 0 +0x8345 0xAE02 # 0 +0x8346 0xAE03 # 0 +0x8347 0xAE04 # 0 +0x8348 0xAE05 # 0 +0x8349 0xAE06 # 0 +0x834A 0xAE07 # 0 +0x834B 0xAE0A # 0 +0x834C 0xAE0C # 0 +0x834D 0xAE0E # 0 +0x834E 0xAE0F # 0 +0x834F 0xAE10 # 0 +0x8350 0xAE11 # 0 +0x8351 0xAE12 # 0 +0x8352 0xAE13 # 0 +0x8353 0xAE15 # 0 +0x8354 0xAE16 # 0 +0x8355 0xAE17 # 0 +0x8356 0xAE18 # 0 +0x8357 0xAE19 # 0 +0x8358 0xAE1A # 0 +0x8359 0xAE1B # 0 +0x835A 0xAE1C # 0 +0x8361 0xAE1D # 0 +0x8362 0xAE1E # 0 +0x8363 0xAE1F # 0 +0x8364 0xAE20 # 0 +0x8365 0xAE21 # 0 +0x8366 0xAE22 # 0 +0x8367 0xAE23 # 0 +0x8368 0xAE24 # 0 +0x8369 0xAE25 # 0 +0x836A 0xAE26 # 0 +0x836B 0xAE27 # 0 +0x836C 0xAE28 # 0 +0x836D 0xAE29 # 0 +0x836E 0xAE2A # 0 +0x836F 0xAE2B # 0 +0x8370 0xAE2C # 0 +0x8371 0xAE2D # 0 +0x8372 0xAE2E # 0 +0x8373 0xAE2F # 0 +0x8374 0xAE32 # 0 +0x8375 0xAE33 # 0 +0x8376 0xAE35 # 0 +0x8377 0xAE36 # 0 +0x8378 0xAE39 # 0 +0x8379 0xAE3B # 0 +0x837A 0xAE3C # 0 +0x8381 0xAE3D # 0 +0x8382 0xAE3E # 0 +0x8383 0xAE3F # 0 +0x8384 0xAE42 # 0 +0x8385 0xAE44 # 0 +0x8386 0xAE47 # 0 +0x8387 0xAE48 # 0 +0x8388 0xAE49 # 0 +0x8389 0xAE4B # 0 +0x838A 0xAE4F # 0 +0x838B 0xAE51 # 0 +0x838C 0xAE52 # 0 +0x838D 0xAE53 # 0 +0x838E 0xAE55 # 0 +0x838F 0xAE57 # 0 +0x8390 0xAE58 # 0 +0x8391 0xAE59 # 0 +0x8392 0xAE5A # 0 +0x8393 0xAE5B # 0 +0x8394 0xAE5E # 0 +0x8395 0xAE62 # 0 +0x8396 0xAE63 # 0 +0x8397 0xAE64 # 0 +0x8398 0xAE66 # 0 +0x8399 0xAE67 # 0 +0x839A 0xAE6A # 0 +0x839B 0xAE6B # 0 +0x839C 0xAE6D # 0 +0x839D 0xAE6E # 0 +0x839E 0xAE6F # 0 +0x839F 0xAE71 # 0 +0x83A0 0xAE72 # 0 +0x83A1 0xAE73 # 0 +0x83A2 0xAE74 # 0 +0x83A3 0xAE75 # 0 +0x83A4 0xAE76 # 0 +0x83A5 0xAE77 # 0 +0x83A6 0xAE7A # 0 +0x83A7 0xAE7E # 0 +0x83A8 0xAE7F # 0 +0x83A9 0xAE80 # 0 +0x83AA 0xAE81 # 0 +0x83AB 0xAE82 # 0 +0x83AC 0xAE83 # 0 +0x83AD 0xAE86 # 0 +0x83AE 0xAE87 # 0 +0x83AF 0xAE88 # 0 +0x83B0 0xAE89 # 0 +0x83B1 0xAE8A # 0 +0x83B2 0xAE8B # 0 +0x83B3 0xAE8D # 0 +0x83B4 0xAE8E # 0 +0x83B5 0xAE8F # 0 +0x83B6 0xAE90 # 0 +0x83B7 0xAE91 # 0 +0x83B8 0xAE92 # 0 +0x83B9 0xAE93 # 0 +0x83BA 0xAE94 # 0 +0x83BB 0xAE95 # 0 +0x83BC 0xAE96 # 0 +0x83BD 0xAE97 # 0 +0x83BE 0xAE98 # 0 +0x83BF 0xAE99 # 0 +0x83C0 0xAE9A # 0 +0x83C1 0xAE9B # 0 +0x83C2 0xAE9C # 0 +0x83C3 0xAE9D # 0 +0x83C4 0xAE9E # 0 +0x83C5 0xAE9F # 0 +0x83C6 0xAEA0 # 0 +0x83C7 0xAEA1 # 0 +0x83C8 0xAEA2 # 0 +0x83C9 0xAEA3 # 0 +0x83CA 0xAEA4 # 0 +0x83CB 0xAEA5 # 0 +0x83CC 0xAEA6 # 0 +0x83CD 0xAEA7 # 0 +0x83CE 0xAEA8 # 0 +0x83CF 0xAEA9 # 0 +0x83D0 0xAEAA # 0 +0x83D1 0xAEAB # 0 +0x83D2 0xAEAC # 0 +0x83D3 0xAEAD # 0 +0x83D4 0xAEAE # 0 +0x83D5 0xAEAF # 0 +0x83D6 0xAEB0 # 0 +0x83D7 0xAEB1 # 0 +0x83D8 0xAEB2 # 0 +0x83D9 0xAEB3 # 0 +0x83DA 0xAEB4 # 0 +0x83DB 0xAEB5 # 0 +0x83DC 0xAEB6 # 0 +0x83DD 0xAEB7 # 0 +0x83DE 0xAEB8 # 0 +0x83DF 0xAEB9 # 0 +0x83E0 0xAEBA # 0 +0x83E1 0xAEBB # 0 +0x83E2 0xAEBF # 0 +0x83E3 0xAEC1 # 0 +0x83E4 0xAEC2 # 0 +0x83E5 0xAEC3 # 0 +0x83E6 0xAEC5 # 0 +0x83E7 0xAEC6 # 0 +0x83E8 0xAEC7 # 0 +0x83E9 0xAEC8 # 0 +0x83EA 0xAEC9 # 0 +0x83EB 0xAECA # 0 +0x83EC 0xAECB # 0 +0x83ED 0xAECE # 0 +0x83EE 0xAED2 # 0 +0x83EF 0xAED3 # 0 +0x83F0 0xAED4 # 0 +0x83F1 0xAED5 # 0 +0x83F2 0xAED6 # 0 +0x83F3 0xAED7 # 0 +0x83F4 0xAEDA # 0 +0x83F5 0xAEDB # 0 +0x83F6 0xAEDD # 0 +0x83F7 0xAEDE # 0 +0x83F8 0xAEDF # 0 +0x83F9 0xAEE0 # 0 +0x83FA 0xAEE1 # 0 +0x83FB 0xAEE2 # 0 +0x83FC 0xAEE3 # 0 +0x83FD 0xAEE4 # 0 +0x83FE 0xAEE5 # 0 +0x8441 0xAEE6 # 0 +0x8442 0xAEE7 # 0 +0x8443 0xAEE9 # 0 +0x8444 0xAEEA # 0 +0x8445 0xAEEC # 0 +0x8446 0xAEEE # 0 +0x8447 0xAEEF # 0 +0x8448 0xAEF0 # 0 +0x8449 0xAEF1 # 0 +0x844A 0xAEF2 # 0 +0x844B 0xAEF3 # 0 +0x844C 0xAEF5 # 0 +0x844D 0xAEF6 # 0 +0x844E 0xAEF7 # 0 +0x844F 0xAEF9 # 0 +0x8450 0xAEFA # 0 +0x8451 0xAEFB # 0 +0x8452 0xAEFD # 0 +0x8453 0xAEFE # 0 +0x8454 0xAEFF # 0 +0x8455 0xAF00 # 0 +0x8456 0xAF01 # 0 +0x8457 0xAF02 # 0 +0x8458 0xAF03 # 0 +0x8459 0xAF04 # 0 +0x845A 0xAF05 # 0 +0x8461 0xAF06 # 0 +0x8462 0xAF09 # 0 +0x8463 0xAF0A # 0 +0x8464 0xAF0B # 0 +0x8465 0xAF0C # 0 +0x8466 0xAF0E # 0 +0x8467 0xAF0F # 0 +0x8468 0xAF11 # 0 +0x8469 0xAF12 # 0 +0x846A 0xAF13 # 0 +0x846B 0xAF14 # 0 +0x846C 0xAF15 # 0 +0x846D 0xAF16 # 0 +0x846E 0xAF17 # 0 +0x846F 0xAF18 # 0 +0x8470 0xAF19 # 0 +0x8471 0xAF1A # 0 +0x8472 0xAF1B # 0 +0x8473 0xAF1C # 0 +0x8474 0xAF1D # 0 +0x8475 0xAF1E # 0 +0x8476 0xAF1F # 0 +0x8477 0xAF20 # 0 +0x8478 0xAF21 # 0 +0x8479 0xAF22 # 0 +0x847A 0xAF23 # 0 +0x8481 0xAF24 # 0 +0x8482 0xAF25 # 0 +0x8483 0xAF26 # 0 +0x8484 0xAF27 # 0 +0x8485 0xAF28 # 0 +0x8486 0xAF29 # 0 +0x8487 0xAF2A # 0 +0x8488 0xAF2B # 0 +0x8489 0xAF2E # 0 +0x848A 0xAF2F # 0 +0x848B 0xAF31 # 0 +0x848C 0xAF33 # 0 +0x848D 0xAF35 # 0 +0x848E 0xAF36 # 0 +0x848F 0xAF37 # 0 +0x8490 0xAF38 # 0 +0x8491 0xAF39 # 0 +0x8492 0xAF3A # 0 +0x8493 0xAF3B # 0 +0x8494 0xAF3E # 0 +0x8495 0xAF40 # 0 +0x8496 0xAF44 # 0 +0x8497 0xAF45 # 0 +0x8498 0xAF46 # 0 +0x8499 0xAF47 # 0 +0x849A 0xAF4A # 0 +0x849B 0xAF4B # 0 +0x849C 0xAF4C # 0 +0x849D 0xAF4D # 0 +0x849E 0xAF4E # 0 +0x849F 0xAF4F # 0 +0x84A0 0xAF51 # 0 +0x84A1 0xAF52 # 0 +0x84A2 0xAF53 # 0 +0x84A3 0xAF54 # 0 +0x84A4 0xAF55 # 0 +0x84A5 0xAF56 # 0 +0x84A6 0xAF57 # 0 +0x84A7 0xAF58 # 0 +0x84A8 0xAF59 # 0 +0x84A9 0xAF5A # 0 +0x84AA 0xAF5B # 0 +0x84AB 0xAF5E # 0 +0x84AC 0xAF5F # 0 +0x84AD 0xAF60 # 0 +0x84AE 0xAF61 # 0 +0x84AF 0xAF62 # 0 +0x84B0 0xAF63 # 0 +0x84B1 0xAF66 # 0 +0x84B2 0xAF67 # 0 +0x84B3 0xAF68 # 0 +0x84B4 0xAF69 # 0 +0x84B5 0xAF6A # 0 +0x84B6 0xAF6B # 0 +0x84B7 0xAF6C # 0 +0x84B8 0xAF6D # 0 +0x84B9 0xAF6E # 0 +0x84BA 0xAF6F # 0 +0x84BB 0xAF70 # 0 +0x84BC 0xAF71 # 0 +0x84BD 0xAF72 # 0 +0x84BE 0xAF73 # 0 +0x84BF 0xAF74 # 0 +0x84C0 0xAF75 # 0 +0x84C1 0xAF76 # 0 +0x84C2 0xAF77 # 0 +0x84C3 0xAF78 # 0 +0x84C4 0xAF7A # 0 +0x84C5 0xAF7B # 0 +0x84C6 0xAF7C # 0 +0x84C7 0xAF7D # 0 +0x84C8 0xAF7E # 0 +0x84C9 0xAF7F # 0 +0x84CA 0xAF81 # 0 +0x84CB 0xAF82 # 0 +0x84CC 0xAF83 # 0 +0x84CD 0xAF85 # 0 +0x84CE 0xAF86 # 0 +0x84CF 0xAF87 # 0 +0x84D0 0xAF89 # 0 +0x84D1 0xAF8A # 0 +0x84D2 0xAF8B # 0 +0x84D3 0xAF8C # 0 +0x84D4 0xAF8D # 0 +0x84D5 0xAF8E # 0 +0x84D6 0xAF8F # 0 +0x84D7 0xAF92 # 0 +0x84D8 0xAF93 # 0 +0x84D9 0xAF94 # 0 +0x84DA 0xAF96 # 0 +0x84DB 0xAF97 # 0 +0x84DC 0xAF98 # 0 +0x84DD 0xAF99 # 0 +0x84DE 0xAF9A # 0 +0x84DF 0xAF9B # 0 +0x84E0 0xAF9D # 0 +0x84E1 0xAF9E # 0 +0x84E2 0xAF9F # 0 +0x84E3 0xAFA0 # 0 +0x84E4 0xAFA1 # 0 +0x84E5 0xAFA2 # 0 +0x84E6 0xAFA3 # 0 +0x84E7 0xAFA4 # 0 +0x84E8 0xAFA5 # 0 +0x84E9 0xAFA6 # 0 +0x84EA 0xAFA7 # 0 +0x84EB 0xAFA8 # 0 +0x84EC 0xAFA9 # 0 +0x84ED 0xAFAA # 0 +0x84EE 0xAFAB # 0 +0x84EF 0xAFAC # 0 +0x84F0 0xAFAD # 0 +0x84F1 0xAFAE # 0 +0x84F2 0xAFAF # 0 +0x84F3 0xAFB0 # 0 +0x84F4 0xAFB1 # 0 +0x84F5 0xAFB2 # 0 +0x84F6 0xAFB3 # 0 +0x84F7 0xAFB4 # 0 +0x84F8 0xAFB5 # 0 +0x84F9 0xAFB6 # 0 +0x84FA 0xAFB7 # 0 +0x84FB 0xAFBA # 0 +0x84FC 0xAFBB # 0 +0x84FD 0xAFBD # 0 +0x84FE 0xAFBE # 0 +0x8541 0xAFBF # 0 +0x8542 0xAFC1 # 0 +0x8543 0xAFC2 # 0 +0x8544 0xAFC3 # 0 +0x8545 0xAFC4 # 0 +0x8546 0xAFC5 # 0 +0x8547 0xAFC6 # 0 +0x8548 0xAFCA # 0 +0x8549 0xAFCC # 0 +0x854A 0xAFCF # 0 +0x854B 0xAFD0 # 0 +0x854C 0xAFD1 # 0 +0x854D 0xAFD2 # 0 +0x854E 0xAFD3 # 0 +0x854F 0xAFD5 # 0 +0x8550 0xAFD6 # 0 +0x8551 0xAFD7 # 0 +0x8552 0xAFD8 # 0 +0x8553 0xAFD9 # 0 +0x8554 0xAFDA # 0 +0x8555 0xAFDB # 0 +0x8556 0xAFDD # 0 +0x8557 0xAFDE # 0 +0x8558 0xAFDF # 0 +0x8559 0xAFE0 # 0 +0x855A 0xAFE1 # 0 +0x8561 0xAFE2 # 0 +0x8562 0xAFE3 # 0 +0x8563 0xAFE4 # 0 +0x8564 0xAFE5 # 0 +0x8565 0xAFE6 # 0 +0x8566 0xAFE7 # 0 +0x8567 0xAFEA # 0 +0x8568 0xAFEB # 0 +0x8569 0xAFEC # 0 +0x856A 0xAFED # 0 +0x856B 0xAFEE # 0 +0x856C 0xAFEF # 0 +0x856D 0xAFF2 # 0 +0x856E 0xAFF3 # 0 +0x856F 0xAFF5 # 0 +0x8570 0xAFF6 # 0 +0x8571 0xAFF7 # 0 +0x8572 0xAFF9 # 0 +0x8573 0xAFFA # 0 +0x8574 0xAFFB # 0 +0x8575 0xAFFC # 0 +0x8576 0xAFFD # 0 +0x8577 0xAFFE # 0 +0x8578 0xAFFF # 0 +0x8579 0xB002 # 0 +0x857A 0xB003 # 0 +0x8581 0xB005 # 0 +0x8582 0xB006 # 0 +0x8583 0xB007 # 0 +0x8584 0xB008 # 0 +0x8585 0xB009 # 0 +0x8586 0xB00A # 0 +0x8587 0xB00B # 0 +0x8588 0xB00D # 0 +0x8589 0xB00E # 0 +0x858A 0xB00F # 0 +0x858B 0xB011 # 0 +0x858C 0xB012 # 0 +0x858D 0xB013 # 0 +0x858E 0xB015 # 0 +0x858F 0xB016 # 0 +0x8590 0xB017 # 0 +0x8591 0xB018 # 0 +0x8592 0xB019 # 0 +0x8593 0xB01A # 0 +0x8594 0xB01B # 0 +0x8595 0xB01E # 0 +0x8596 0xB01F # 0 +0x8597 0xB020 # 0 +0x8598 0xB021 # 0 +0x8599 0xB022 # 0 +0x859A 0xB023 # 0 +0x859B 0xB024 # 0 +0x859C 0xB025 # 0 +0x859D 0xB026 # 0 +0x859E 0xB027 # 0 +0x859F 0xB029 # 0 +0x85A0 0xB02A # 0 +0x85A1 0xB02B # 0 +0x85A2 0xB02C # 0 +0x85A3 0xB02D # 0 +0x85A4 0xB02E # 0 +0x85A5 0xB02F # 0 +0x85A6 0xB030 # 0 +0x85A7 0xB031 # 0 +0x85A8 0xB032 # 0 +0x85A9 0xB033 # 0 +0x85AA 0xB034 # 0 +0x85AB 0xB035 # 0 +0x85AC 0xB036 # 0 +0x85AD 0xB037 # 0 +0x85AE 0xB038 # 0 +0x85AF 0xB039 # 0 +0x85B0 0xB03A # 0 +0x85B1 0xB03B # 0 +0x85B2 0xB03C # 0 +0x85B3 0xB03D # 0 +0x85B4 0xB03E # 0 +0x85B5 0xB03F # 0 +0x85B6 0xB040 # 0 +0x85B7 0xB041 # 0 +0x85B8 0xB042 # 0 +0x85B9 0xB043 # 0 +0x85BA 0xB046 # 0 +0x85BB 0xB047 # 0 +0x85BC 0xB049 # 0 +0x85BD 0xB04B # 0 +0x85BE 0xB04D # 0 +0x85BF 0xB04F # 0 +0x85C0 0xB050 # 0 +0x85C1 0xB051 # 0 +0x85C2 0xB052 # 0 +0x85C3 0xB056 # 0 +0x85C4 0xB058 # 0 +0x85C5 0xB05A # 0 +0x85C6 0xB05B # 0 +0x85C7 0xB05C # 0 +0x85C8 0xB05E # 0 +0x85C9 0xB05F # 0 +0x85CA 0xB060 # 0 +0x85CB 0xB061 # 0 +0x85CC 0xB062 # 0 +0x85CD 0xB063 # 0 +0x85CE 0xB064 # 0 +0x85CF 0xB065 # 0 +0x85D0 0xB066 # 0 +0x85D1 0xB067 # 0 +0x85D2 0xB068 # 0 +0x85D3 0xB069 # 0 +0x85D4 0xB06A # 0 +0x85D5 0xB06B # 0 +0x85D6 0xB06C # 0 +0x85D7 0xB06D # 0 +0x85D8 0xB06E # 0 +0x85D9 0xB06F # 0 +0x85DA 0xB070 # 0 +0x85DB 0xB071 # 0 +0x85DC 0xB072 # 0 +0x85DD 0xB073 # 0 +0x85DE 0xB074 # 0 +0x85DF 0xB075 # 0 +0x85E0 0xB076 # 0 +0x85E1 0xB077 # 0 +0x85E2 0xB078 # 0 +0x85E3 0xB079 # 0 +0x85E4 0xB07A # 0 +0x85E5 0xB07B # 0 +0x85E6 0xB07E # 0 +0x85E7 0xB07F # 0 +0x85E8 0xB081 # 0 +0x85E9 0xB082 # 0 +0x85EA 0xB083 # 0 +0x85EB 0xB085 # 0 +0x85EC 0xB086 # 0 +0x85ED 0xB087 # 0 +0x85EE 0xB088 # 0 +0x85EF 0xB089 # 0 +0x85F0 0xB08A # 0 +0x85F1 0xB08B # 0 +0x85F2 0xB08E # 0 +0x85F3 0xB090 # 0 +0x85F4 0xB092 # 0 +0x85F5 0xB093 # 0 +0x85F6 0xB094 # 0 +0x85F7 0xB095 # 0 +0x85F8 0xB096 # 0 +0x85F9 0xB097 # 0 +0x85FA 0xB09B # 0 +0x85FB 0xB09D # 0 +0x85FC 0xB09E # 0 +0x85FD 0xB0A3 # 0 +0x85FE 0xB0A4 # 0 +0x8641 0xB0A5 # 0 +0x8642 0xB0A6 # 0 +0x8643 0xB0A7 # 0 +0x8644 0xB0AA # 0 +0x8645 0xB0B0 # 0 +0x8646 0xB0B2 # 0 +0x8647 0xB0B6 # 0 +0x8648 0xB0B7 # 0 +0x8649 0xB0B9 # 0 +0x864A 0xB0BA # 0 +0x864B 0xB0BB # 0 +0x864C 0xB0BD # 0 +0x864D 0xB0BE # 0 +0x864E 0xB0BF # 0 +0x864F 0xB0C0 # 0 +0x8650 0xB0C1 # 0 +0x8651 0xB0C2 # 0 +0x8652 0xB0C3 # 0 +0x8653 0xB0C6 # 0 +0x8654 0xB0CA # 0 +0x8655 0xB0CB # 0 +0x8656 0xB0CC # 0 +0x8657 0xB0CD # 0 +0x8658 0xB0CE # 0 +0x8659 0xB0CF # 0 +0x865A 0xB0D2 # 0 +0x8661 0xB0D3 # 0 +0x8662 0xB0D5 # 0 +0x8663 0xB0D6 # 0 +0x8664 0xB0D7 # 0 +0x8665 0xB0D9 # 0 +0x8666 0xB0DA # 0 +0x8667 0xB0DB # 0 +0x8668 0xB0DC # 0 +0x8669 0xB0DD # 0 +0x866A 0xB0DE # 0 +0x866B 0xB0DF # 0 +0x866C 0xB0E1 # 0 +0x866D 0xB0E2 # 0 +0x866E 0xB0E3 # 0 +0x866F 0xB0E4 # 0 +0x8670 0xB0E6 # 0 +0x8671 0xB0E7 # 0 +0x8672 0xB0E8 # 0 +0x8673 0xB0E9 # 0 +0x8674 0xB0EA # 0 +0x8675 0xB0EB # 0 +0x8676 0xB0EC # 0 +0x8677 0xB0ED # 0 +0x8678 0xB0EE # 0 +0x8679 0xB0EF # 0 +0x867A 0xB0F0 # 0 +0x8681 0xB0F1 # 0 +0x8682 0xB0F2 # 0 +0x8683 0xB0F3 # 0 +0x8684 0xB0F4 # 0 +0x8685 0xB0F5 # 0 +0x8686 0xB0F6 # 0 +0x8687 0xB0F7 # 0 +0x8688 0xB0F8 # 0 +0x8689 0xB0F9 # 0 +0x868A 0xB0FA # 0 +0x868B 0xB0FB # 0 +0x868C 0xB0FC # 0 +0x868D 0xB0FD # 0 +0x868E 0xB0FE # 0 +0x868F 0xB0FF # 0 +0x8690 0xB100 # 0 +0x8691 0xB101 # 0 +0x8692 0xB102 # 0 +0x8693 0xB103 # 0 +0x8694 0xB104 # 0 +0x8695 0xB105 # 0 +0x8696 0xB106 # 0 +0x8697 0xB107 # 0 +0x8698 0xB10A # 0 +0x8699 0xB10D # 0 +0x869A 0xB10E # 0 +0x869B 0xB10F # 0 +0x869C 0xB111 # 0 +0x869D 0xB114 # 0 +0x869E 0xB115 # 0 +0x869F 0xB116 # 0 +0x86A0 0xB117 # 0 +0x86A1 0xB11A # 0 +0x86A2 0xB11E # 0 +0x86A3 0xB11F # 0 +0x86A4 0xB120 # 0 +0x86A5 0xB121 # 0 +0x86A6 0xB122 # 0 +0x86A7 0xB126 # 0 +0x86A8 0xB127 # 0 +0x86A9 0xB129 # 0 +0x86AA 0xB12A # 0 +0x86AB 0xB12B # 0 +0x86AC 0xB12D # 0 +0x86AD 0xB12E # 0 +0x86AE 0xB12F # 0 +0x86AF 0xB130 # 0 +0x86B0 0xB131 # 0 +0x86B1 0xB132 # 0 +0x86B2 0xB133 # 0 +0x86B3 0xB136 # 0 +0x86B4 0xB13A # 0 +0x86B5 0xB13B # 0 +0x86B6 0xB13C # 0 +0x86B7 0xB13D # 0 +0x86B8 0xB13E # 0 +0x86B9 0xB13F # 0 +0x86BA 0xB142 # 0 +0x86BB 0xB143 # 0 +0x86BC 0xB145 # 0 +0x86BD 0xB146 # 0 +0x86BE 0xB147 # 0 +0x86BF 0xB149 # 0 +0x86C0 0xB14A # 0 +0x86C1 0xB14B # 0 +0x86C2 0xB14C # 0 +0x86C3 0xB14D # 0 +0x86C4 0xB14E # 0 +0x86C5 0xB14F # 0 +0x86C6 0xB152 # 0 +0x86C7 0xB153 # 0 +0x86C8 0xB156 # 0 +0x86C9 0xB157 # 0 +0x86CA 0xB159 # 0 +0x86CB 0xB15A # 0 +0x86CC 0xB15B # 0 +0x86CD 0xB15D # 0 +0x86CE 0xB15E # 0 +0x86CF 0xB15F # 0 +0x86D0 0xB161 # 0 +0x86D1 0xB162 # 0 +0x86D2 0xB163 # 0 +0x86D3 0xB164 # 0 +0x86D4 0xB165 # 0 +0x86D5 0xB166 # 0 +0x86D6 0xB167 # 0 +0x86D7 0xB168 # 0 +0x86D8 0xB169 # 0 +0x86D9 0xB16A # 0 +0x86DA 0xB16B # 0 +0x86DB 0xB16C # 0 +0x86DC 0xB16D # 0 +0x86DD 0xB16E # 0 +0x86DE 0xB16F # 0 +0x86DF 0xB170 # 0 +0x86E0 0xB171 # 0 +0x86E1 0xB172 # 0 +0x86E2 0xB173 # 0 +0x86E3 0xB174 # 0 +0x86E4 0xB175 # 0 +0x86E5 0xB176 # 0 +0x86E6 0xB177 # 0 +0x86E7 0xB17A # 0 +0x86E8 0xB17B # 0 +0x86E9 0xB17D # 0 +0x86EA 0xB17E # 0 +0x86EB 0xB17F # 0 +0x86EC 0xB181 # 0 +0x86ED 0xB183 # 0 +0x86EE 0xB184 # 0 +0x86EF 0xB185 # 0 +0x86F0 0xB186 # 0 +0x86F1 0xB187 # 0 +0x86F2 0xB18A # 0 +0x86F3 0xB18C # 0 +0x86F4 0xB18E # 0 +0x86F5 0xB18F # 0 +0x86F6 0xB190 # 0 +0x86F7 0xB191 # 0 +0x86F8 0xB195 # 0 +0x86F9 0xB196 # 0 +0x86FA 0xB197 # 0 +0x86FB 0xB199 # 0 +0x86FC 0xB19A # 0 +0x86FD 0xB19B # 0 +0x86FE 0xB19D # 0 +0x8741 0xB19E # 0 +0x8742 0xB19F # 0 +0x8743 0xB1A0 # 0 +0x8744 0xB1A1 # 0 +0x8745 0xB1A2 # 0 +0x8746 0xB1A3 # 0 +0x8747 0xB1A4 # 0 +0x8748 0xB1A5 # 0 +0x8749 0xB1A6 # 0 +0x874A 0xB1A7 # 0 +0x874B 0xB1A9 # 0 +0x874C 0xB1AA # 0 +0x874D 0xB1AB # 0 +0x874E 0xB1AC # 0 +0x874F 0xB1AD # 0 +0x8750 0xB1AE # 0 +0x8751 0xB1AF # 0 +0x8752 0xB1B0 # 0 +0x8753 0xB1B1 # 0 +0x8754 0xB1B2 # 0 +0x8755 0xB1B3 # 0 +0x8756 0xB1B4 # 0 +0x8757 0xB1B5 # 0 +0x8758 0xB1B6 # 0 +0x8759 0xB1B7 # 0 +0x875A 0xB1B8 # 0 +0x8761 0xB1B9 # 0 +0x8762 0xB1BA # 0 +0x8763 0xB1BB # 0 +0x8764 0xB1BC # 0 +0x8765 0xB1BD # 0 +0x8766 0xB1BE # 0 +0x8767 0xB1BF # 0 +0x8768 0xB1C0 # 0 +0x8769 0xB1C1 # 0 +0x876A 0xB1C2 # 0 +0x876B 0xB1C3 # 0 +0x876C 0xB1C4 # 0 +0x876D 0xB1C5 # 0 +0x876E 0xB1C6 # 0 +0x876F 0xB1C7 # 0 +0x8770 0xB1C8 # 0 +0x8771 0xB1C9 # 0 +0x8772 0xB1CA # 0 +0x8773 0xB1CB # 0 +0x8774 0xB1CD # 0 +0x8775 0xB1CE # 0 +0x8776 0xB1CF # 0 +0x8777 0xB1D1 # 0 +0x8778 0xB1D2 # 0 +0x8779 0xB1D3 # 0 +0x877A 0xB1D5 # 0 +0x8781 0xB1D6 # 0 +0x8782 0xB1D7 # 0 +0x8783 0xB1D8 # 0 +0x8784 0xB1D9 # 0 +0x8785 0xB1DA # 0 +0x8786 0xB1DB # 0 +0x8787 0xB1DE # 0 +0x8788 0xB1E0 # 0 +0x8789 0xB1E1 # 0 +0x878A 0xB1E2 # 0 +0x878B 0xB1E3 # 0 +0x878C 0xB1E4 # 0 +0x878D 0xB1E5 # 0 +0x878E 0xB1E6 # 0 +0x878F 0xB1E7 # 0 +0x8790 0xB1EA # 0 +0x8791 0xB1EB # 0 +0x8792 0xB1ED # 0 +0x8793 0xB1EE # 0 +0x8794 0xB1EF # 0 +0x8795 0xB1F1 # 0 +0x8796 0xB1F2 # 0 +0x8797 0xB1F3 # 0 +0x8798 0xB1F4 # 0 +0x8799 0xB1F5 # 0 +0x879A 0xB1F6 # 0 +0x879B 0xB1F7 # 0 +0x879C 0xB1F8 # 0 +0x879D 0xB1FA # 0 +0x879E 0xB1FC # 0 +0x879F 0xB1FE # 0 +0x87A0 0xB1FF # 0 +0x87A1 0xB200 # 0 +0x87A2 0xB201 # 0 +0x87A3 0xB202 # 0 +0x87A4 0xB203 # 0 +0x87A5 0xB206 # 0 +0x87A6 0xB207 # 0 +0x87A7 0xB209 # 0 +0x87A8 0xB20A # 0 +0x87A9 0xB20D # 0 +0x87AA 0xB20E # 0 +0x87AB 0xB20F # 0 +0x87AC 0xB210 # 0 +0x87AD 0xB211 # 0 +0x87AE 0xB212 # 0 +0x87AF 0xB213 # 0 +0x87B0 0xB216 # 0 +0x87B1 0xB218 # 0 +0x87B2 0xB21A # 0 +0x87B3 0xB21B # 0 +0x87B4 0xB21C # 0 +0x87B5 0xB21D # 0 +0x87B6 0xB21E # 0 +0x87B7 0xB21F # 0 +0x87B8 0xB221 # 0 +0x87B9 0xB222 # 0 +0x87BA 0xB223 # 0 +0x87BB 0xB224 # 0 +0x87BC 0xB225 # 0 +0x87BD 0xB226 # 0 +0x87BE 0xB227 # 0 +0x87BF 0xB228 # 0 +0x87C0 0xB229 # 0 +0x87C1 0xB22A # 0 +0x87C2 0xB22B # 0 +0x87C3 0xB22C # 0 +0x87C4 0xB22D # 0 +0x87C5 0xB22E # 0 +0x87C6 0xB22F # 0 +0x87C7 0xB230 # 0 +0x87C8 0xB231 # 0 +0x87C9 0xB232 # 0 +0x87CA 0xB233 # 0 +0x87CB 0xB235 # 0 +0x87CC 0xB236 # 0 +0x87CD 0xB237 # 0 +0x87CE 0xB238 # 0 +0x87CF 0xB239 # 0 +0x87D0 0xB23A # 0 +0x87D1 0xB23B # 0 +0x87D2 0xB23D # 0 +0x87D3 0xB23E # 0 +0x87D4 0xB23F # 0 +0x87D5 0xB240 # 0 +0x87D6 0xB241 # 0 +0x87D7 0xB242 # 0 +0x87D8 0xB243 # 0 +0x87D9 0xB244 # 0 +0x87DA 0xB245 # 0 +0x87DB 0xB246 # 0 +0x87DC 0xB247 # 0 +0x87DD 0xB248 # 0 +0x87DE 0xB249 # 0 +0x87DF 0xB24A # 0 +0x87E0 0xB24B # 0 +0x87E1 0xB24C # 0 +0x87E2 0xB24D # 0 +0x87E3 0xB24E # 0 +0x87E4 0xB24F # 0 +0x87E5 0xB250 # 0 +0x87E6 0xB251 # 0 +0x87E7 0xB252 # 0 +0x87E8 0xB253 # 0 +0x87E9 0xB254 # 0 +0x87EA 0xB255 # 0 +0x87EB 0xB256 # 0 +0x87EC 0xB257 # 0 +0x87ED 0xB259 # 0 +0x87EE 0xB25A # 0 +0x87EF 0xB25B # 0 +0x87F0 0xB25D # 0 +0x87F1 0xB25E # 0 +0x87F2 0xB25F # 0 +0x87F3 0xB261 # 0 +0x87F4 0xB262 # 0 +0x87F5 0xB263 # 0 +0x87F6 0xB264 # 0 +0x87F7 0xB265 # 0 +0x87F8 0xB266 # 0 +0x87F9 0xB267 # 0 +0x87FA 0xB26A # 0 +0x87FB 0xB26B # 0 +0x87FC 0xB26C # 0 +0x87FD 0xB26D # 0 +0x87FE 0xB26E # 0 +0x8841 0xB26F # 0 +0x8842 0xB270 # 0 +0x8843 0xB271 # 0 +0x8844 0xB272 # 0 +0x8845 0xB273 # 0 +0x8846 0xB276 # 0 +0x8847 0xB277 # 0 +0x8848 0xB278 # 0 +0x8849 0xB279 # 0 +0x884A 0xB27A # 0 +0x884B 0xB27B # 0 +0x884C 0xB27D # 0 +0x884D 0xB27E # 0 +0x884E 0xB27F # 0 +0x884F 0xB280 # 0 +0x8850 0xB281 # 0 +0x8851 0xB282 # 0 +0x8852 0xB283 # 0 +0x8853 0xB286 # 0 +0x8854 0xB287 # 0 +0x8855 0xB288 # 0 +0x8856 0xB28A # 0 +0x8857 0xB28B # 0 +0x8858 0xB28C # 0 +0x8859 0xB28D # 0 +0x885A 0xB28E # 0 +0x8861 0xB28F # 0 +0x8862 0xB292 # 0 +0x8863 0xB293 # 0 +0x8864 0xB295 # 0 +0x8865 0xB296 # 0 +0x8866 0xB297 # 0 +0x8867 0xB29B # 0 +0x8868 0xB29C # 0 +0x8869 0xB29D # 0 +0x886A 0xB29E # 0 +0x886B 0xB29F # 0 +0x886C 0xB2A2 # 0 +0x886D 0xB2A4 # 0 +0x886E 0xB2A7 # 0 +0x886F 0xB2A8 # 0 +0x8870 0xB2A9 # 0 +0x8871 0xB2AB # 0 +0x8872 0xB2AD # 0 +0x8873 0xB2AE # 0 +0x8874 0xB2AF # 0 +0x8875 0xB2B1 # 0 +0x8876 0xB2B2 # 0 +0x8877 0xB2B3 # 0 +0x8878 0xB2B5 # 0 +0x8879 0xB2B6 # 0 +0x887A 0xB2B7 # 0 +0x8881 0xB2B8 # 0 +0x8882 0xB2B9 # 0 +0x8883 0xB2BA # 0 +0x8884 0xB2BB # 0 +0x8885 0xB2BC # 0 +0x8886 0xB2BD # 0 +0x8887 0xB2BE # 0 +0x8888 0xB2BF # 0 +0x8889 0xB2C0 # 0 +0x888A 0xB2C1 # 0 +0x888B 0xB2C2 # 0 +0x888C 0xB2C3 # 0 +0x888D 0xB2C4 # 0 +0x888E 0xB2C5 # 0 +0x888F 0xB2C6 # 0 +0x8890 0xB2C7 # 0 +0x8891 0xB2CA # 0 +0x8892 0xB2CB # 0 +0x8893 0xB2CD # 0 +0x8894 0xB2CE # 0 +0x8895 0xB2CF # 0 +0x8896 0xB2D1 # 0 +0x8897 0xB2D3 # 0 +0x8898 0xB2D4 # 0 +0x8899 0xB2D5 # 0 +0x889A 0xB2D6 # 0 +0x889B 0xB2D7 # 0 +0x889C 0xB2DA # 0 +0x889D 0xB2DC # 0 +0x889E 0xB2DE # 0 +0x889F 0xB2DF # 0 +0x88A0 0xB2E0 # 0 +0x88A1 0xB2E1 # 0 +0x88A2 0xB2E3 # 0 +0x88A3 0xB2E7 # 0 +0x88A4 0xB2E9 # 0 +0x88A5 0xB2EA # 0 +0x88A6 0xB2F0 # 0 +0x88A7 0xB2F1 # 0 +0x88A8 0xB2F2 # 0 +0x88A9 0xB2F6 # 0 +0x88AA 0xB2FC # 0 +0x88AB 0xB2FD # 0 +0x88AC 0xB2FE # 0 +0x88AD 0xB302 # 0 +0x88AE 0xB303 # 0 +0x88AF 0xB305 # 0 +0x88B0 0xB306 # 0 +0x88B1 0xB307 # 0 +0x88B2 0xB309 # 0 +0x88B3 0xB30A # 0 +0x88B4 0xB30B # 0 +0x88B5 0xB30C # 0 +0x88B6 0xB30D # 0 +0x88B7 0xB30E # 0 +0x88B8 0xB30F # 0 +0x88B9 0xB312 # 0 +0x88BA 0xB316 # 0 +0x88BB 0xB317 # 0 +0x88BC 0xB318 # 0 +0x88BD 0xB319 # 0 +0x88BE 0xB31A # 0 +0x88BF 0xB31B # 0 +0x88C0 0xB31D # 0 +0x88C1 0xB31E # 0 +0x88C2 0xB31F # 0 +0x88C3 0xB320 # 0 +0x88C4 0xB321 # 0 +0x88C5 0xB322 # 0 +0x88C6 0xB323 # 0 +0x88C7 0xB324 # 0 +0x88C8 0xB325 # 0 +0x88C9 0xB326 # 0 +0x88CA 0xB327 # 0 +0x88CB 0xB328 # 0 +0x88CC 0xB329 # 0 +0x88CD 0xB32A # 0 +0x88CE 0xB32B # 0 +0x88CF 0xB32C # 0 +0x88D0 0xB32D # 0 +0x88D1 0xB32E # 0 +0x88D2 0xB32F # 0 +0x88D3 0xB330 # 0 +0x88D4 0xB331 # 0 +0x88D5 0xB332 # 0 +0x88D6 0xB333 # 0 +0x88D7 0xB334 # 0 +0x88D8 0xB335 # 0 +0x88D9 0xB336 # 0 +0x88DA 0xB337 # 0 +0x88DB 0xB338 # 0 +0x88DC 0xB339 # 0 +0x88DD 0xB33A # 0 +0x88DE 0xB33B # 0 +0x88DF 0xB33C # 0 +0x88E0 0xB33D # 0 +0x88E1 0xB33E # 0 +0x88E2 0xB33F # 0 +0x88E3 0xB340 # 0 +0x88E4 0xB341 # 0 +0x88E5 0xB342 # 0 +0x88E6 0xB343 # 0 +0x88E7 0xB344 # 0 +0x88E8 0xB345 # 0 +0x88E9 0xB346 # 0 +0x88EA 0xB347 # 0 +0x88EB 0xB348 # 0 +0x88EC 0xB349 # 0 +0x88ED 0xB34A # 0 +0x88EE 0xB34B # 0 +0x88EF 0xB34C # 0 +0x88F0 0xB34D # 0 +0x88F1 0xB34E # 0 +0x88F2 0xB34F # 0 +0x88F3 0xB350 # 0 +0x88F4 0xB351 # 0 +0x88F5 0xB352 # 0 +0x88F6 0xB353 # 0 +0x88F7 0xB357 # 0 +0x88F8 0xB359 # 0 +0x88F9 0xB35A # 0 +0x88FA 0xB35D # 0 +0x88FB 0xB360 # 0 +0x88FC 0xB361 # 0 +0x88FD 0xB362 # 0 +0x88FE 0xB363 # 0 +0x8941 0xB366 # 0 +0x8942 0xB368 # 0 +0x8943 0xB36A # 0 +0x8944 0xB36C # 0 +0x8945 0xB36D # 0 +0x8946 0xB36F # 0 +0x8947 0xB372 # 0 +0x8948 0xB373 # 0 +0x8949 0xB375 # 0 +0x894A 0xB376 # 0 +0x894B 0xB377 # 0 +0x894C 0xB379 # 0 +0x894D 0xB37A # 0 +0x894E 0xB37B # 0 +0x894F 0xB37C # 0 +0x8950 0xB37D # 0 +0x8951 0xB37E # 0 +0x8952 0xB37F # 0 +0x8953 0xB382 # 0 +0x8954 0xB386 # 0 +0x8955 0xB387 # 0 +0x8956 0xB388 # 0 +0x8957 0xB389 # 0 +0x8958 0xB38A # 0 +0x8959 0xB38B # 0 +0x895A 0xB38D # 0 +0x8961 0xB38E # 0 +0x8962 0xB38F # 0 +0x8963 0xB391 # 0 +0x8964 0xB392 # 0 +0x8965 0xB393 # 0 +0x8966 0xB395 # 0 +0x8967 0xB396 # 0 +0x8968 0xB397 # 0 +0x8969 0xB398 # 0 +0x896A 0xB399 # 0 +0x896B 0xB39A # 0 +0x896C 0xB39B # 0 +0x896D 0xB39C # 0 +0x896E 0xB39D # 0 +0x896F 0xB39E # 0 +0x8970 0xB39F # 0 +0x8971 0xB3A2 # 0 +0x8972 0xB3A3 # 0 +0x8973 0xB3A4 # 0 +0x8974 0xB3A5 # 0 +0x8975 0xB3A6 # 0 +0x8976 0xB3A7 # 0 +0x8977 0xB3A9 # 0 +0x8978 0xB3AA # 0 +0x8979 0xB3AB # 0 +0x897A 0xB3AD # 0 +0x8981 0xB3AE # 0 +0x8982 0xB3AF # 0 +0x8983 0xB3B0 # 0 +0x8984 0xB3B1 # 0 +0x8985 0xB3B2 # 0 +0x8986 0xB3B3 # 0 +0x8987 0xB3B4 # 0 +0x8988 0xB3B5 # 0 +0x8989 0xB3B6 # 0 +0x898A 0xB3B7 # 0 +0x898B 0xB3B8 # 0 +0x898C 0xB3B9 # 0 +0x898D 0xB3BA # 0 +0x898E 0xB3BB # 0 +0x898F 0xB3BC # 0 +0x8990 0xB3BD # 0 +0x8991 0xB3BE # 0 +0x8992 0xB3BF # 0 +0x8993 0xB3C0 # 0 +0x8994 0xB3C1 # 0 +0x8995 0xB3C2 # 0 +0x8996 0xB3C3 # 0 +0x8997 0xB3C6 # 0 +0x8998 0xB3C7 # 0 +0x8999 0xB3C9 # 0 +0x899A 0xB3CA # 0 +0x899B 0xB3CD # 0 +0x899C 0xB3CF # 0 +0x899D 0xB3D1 # 0 +0x899E 0xB3D2 # 0 +0x899F 0xB3D3 # 0 +0x89A0 0xB3D6 # 0 +0x89A1 0xB3D8 # 0 +0x89A2 0xB3DA # 0 +0x89A3 0xB3DC # 0 +0x89A4 0xB3DE # 0 +0x89A5 0xB3DF # 0 +0x89A6 0xB3E1 # 0 +0x89A7 0xB3E2 # 0 +0x89A8 0xB3E3 # 0 +0x89A9 0xB3E5 # 0 +0x89AA 0xB3E6 # 0 +0x89AB 0xB3E7 # 0 +0x89AC 0xB3E9 # 0 +0x89AD 0xB3EA # 0 +0x89AE 0xB3EB # 0 +0x89AF 0xB3EC # 0 +0x89B0 0xB3ED # 0 +0x89B1 0xB3EE # 0 +0x89B2 0xB3EF # 0 +0x89B3 0xB3F0 # 0 +0x89B4 0xB3F1 # 0 +0x89B5 0xB3F2 # 0 +0x89B6 0xB3F3 # 0 +0x89B7 0xB3F4 # 0 +0x89B8 0xB3F5 # 0 +0x89B9 0xB3F6 # 0 +0x89BA 0xB3F7 # 0 +0x89BB 0xB3F8 # 0 +0x89BC 0xB3F9 # 0 +0x89BD 0xB3FA # 0 +0x89BE 0xB3FB # 0 +0x89BF 0xB3FD # 0 +0x89C0 0xB3FE # 0 +0x89C1 0xB3FF # 0 +0x89C2 0xB400 # 0 +0x89C3 0xB401 # 0 +0x89C4 0xB402 # 0 +0x89C5 0xB403 # 0 +0x89C6 0xB404 # 0 +0x89C7 0xB405 # 0 +0x89C8 0xB406 # 0 +0x89C9 0xB407 # 0 +0x89CA 0xB408 # 0 +0x89CB 0xB409 # 0 +0x89CC 0xB40A # 0 +0x89CD 0xB40B # 0 +0x89CE 0xB40C # 0 +0x89CF 0xB40D # 0 +0x89D0 0xB40E # 0 +0x89D1 0xB40F # 0 +0x89D2 0xB411 # 0 +0x89D3 0xB412 # 0 +0x89D4 0xB413 # 0 +0x89D5 0xB414 # 0 +0x89D6 0xB415 # 0 +0x89D7 0xB416 # 0 +0x89D8 0xB417 # 0 +0x89D9 0xB419 # 0 +0x89DA 0xB41A # 0 +0x89DB 0xB41B # 0 +0x89DC 0xB41D # 0 +0x89DD 0xB41E # 0 +0x89DE 0xB41F # 0 +0x89DF 0xB421 # 0 +0x89E0 0xB422 # 0 +0x89E1 0xB423 # 0 +0x89E2 0xB424 # 0 +0x89E3 0xB425 # 0 +0x89E4 0xB426 # 0 +0x89E5 0xB427 # 0 +0x89E6 0xB42A # 0 +0x89E7 0xB42C # 0 +0x89E8 0xB42D # 0 +0x89E9 0xB42E # 0 +0x89EA 0xB42F # 0 +0x89EB 0xB430 # 0 +0x89EC 0xB431 # 0 +0x89ED 0xB432 # 0 +0x89EE 0xB433 # 0 +0x89EF 0xB435 # 0 +0x89F0 0xB436 # 0 +0x89F1 0xB437 # 0 +0x89F2 0xB438 # 0 +0x89F3 0xB439 # 0 +0x89F4 0xB43A # 0 +0x89F5 0xB43B # 0 +0x89F6 0xB43C # 0 +0x89F7 0xB43D # 0 +0x89F8 0xB43E # 0 +0x89F9 0xB43F # 0 +0x89FA 0xB440 # 0 +0x89FB 0xB441 # 0 +0x89FC 0xB442 # 0 +0x89FD 0xB443 # 0 +0x89FE 0xB444 # 0 +0x8A41 0xB445 # 0 +0x8A42 0xB446 # 0 +0x8A43 0xB447 # 0 +0x8A44 0xB448 # 0 +0x8A45 0xB449 # 0 +0x8A46 0xB44A # 0 +0x8A47 0xB44B # 0 +0x8A48 0xB44C # 0 +0x8A49 0xB44D # 0 +0x8A4A 0xB44E # 0 +0x8A4B 0xB44F # 0 +0x8A4C 0xB452 # 0 +0x8A4D 0xB453 # 0 +0x8A4E 0xB455 # 0 +0x8A4F 0xB456 # 0 +0x8A50 0xB457 # 0 +0x8A51 0xB459 # 0 +0x8A52 0xB45A # 0 +0x8A53 0xB45B # 0 +0x8A54 0xB45C # 0 +0x8A55 0xB45D # 0 +0x8A56 0xB45E # 0 +0x8A57 0xB45F # 0 +0x8A58 0xB462 # 0 +0x8A59 0xB464 # 0 +0x8A5A 0xB466 # 0 +0x8A61 0xB467 # 0 +0x8A62 0xB468 # 0 +0x8A63 0xB469 # 0 +0x8A64 0xB46A # 0 +0x8A65 0xB46B # 0 +0x8A66 0xB46D # 0 +0x8A67 0xB46E # 0 +0x8A68 0xB46F # 0 +0x8A69 0xB470 # 0 +0x8A6A 0xB471 # 0 +0x8A6B 0xB472 # 0 +0x8A6C 0xB473 # 0 +0x8A6D 0xB474 # 0 +0x8A6E 0xB475 # 0 +0x8A6F 0xB476 # 0 +0x8A70 0xB477 # 0 +0x8A71 0xB478 # 0 +0x8A72 0xB479 # 0 +0x8A73 0xB47A # 0 +0x8A74 0xB47B # 0 +0x8A75 0xB47C # 0 +0x8A76 0xB47D # 0 +0x8A77 0xB47E # 0 +0x8A78 0xB47F # 0 +0x8A79 0xB481 # 0 +0x8A7A 0xB482 # 0 +0x8A81 0xB483 # 0 +0x8A82 0xB484 # 0 +0x8A83 0xB485 # 0 +0x8A84 0xB486 # 0 +0x8A85 0xB487 # 0 +0x8A86 0xB489 # 0 +0x8A87 0xB48A # 0 +0x8A88 0xB48B # 0 +0x8A89 0xB48C # 0 +0x8A8A 0xB48D # 0 +0x8A8B 0xB48E # 0 +0x8A8C 0xB48F # 0 +0x8A8D 0xB490 # 0 +0x8A8E 0xB491 # 0 +0x8A8F 0xB492 # 0 +0x8A90 0xB493 # 0 +0x8A91 0xB494 # 0 +0x8A92 0xB495 # 0 +0x8A93 0xB496 # 0 +0x8A94 0xB497 # 0 +0x8A95 0xB498 # 0 +0x8A96 0xB499 # 0 +0x8A97 0xB49A # 0 +0x8A98 0xB49B # 0 +0x8A99 0xB49C # 0 +0x8A9A 0xB49E # 0 +0x8A9B 0xB49F # 0 +0x8A9C 0xB4A0 # 0 +0x8A9D 0xB4A1 # 0 +0x8A9E 0xB4A2 # 0 +0x8A9F 0xB4A3 # 0 +0x8AA0 0xB4A5 # 0 +0x8AA1 0xB4A6 # 0 +0x8AA2 0xB4A7 # 0 +0x8AA3 0xB4A9 # 0 +0x8AA4 0xB4AA # 0 +0x8AA5 0xB4AB # 0 +0x8AA6 0xB4AD # 0 +0x8AA7 0xB4AE # 0 +0x8AA8 0xB4AF # 0 +0x8AA9 0xB4B0 # 0 +0x8AAA 0xB4B1 # 0 +0x8AAB 0xB4B2 # 0 +0x8AAC 0xB4B3 # 0 +0x8AAD 0xB4B4 # 0 +0x8AAE 0xB4B6 # 0 +0x8AAF 0xB4B8 # 0 +0x8AB0 0xB4BA # 0 +0x8AB1 0xB4BB # 0 +0x8AB2 0xB4BC # 0 +0x8AB3 0xB4BD # 0 +0x8AB4 0xB4BE # 0 +0x8AB5 0xB4BF # 0 +0x8AB6 0xB4C1 # 0 +0x8AB7 0xB4C2 # 0 +0x8AB8 0xB4C3 # 0 +0x8AB9 0xB4C5 # 0 +0x8ABA 0xB4C6 # 0 +0x8ABB 0xB4C7 # 0 +0x8ABC 0xB4C9 # 0 +0x8ABD 0xB4CA # 0 +0x8ABE 0xB4CB # 0 +0x8ABF 0xB4CC # 0 +0x8AC0 0xB4CD # 0 +0x8AC1 0xB4CE # 0 +0x8AC2 0xB4CF # 0 +0x8AC3 0xB4D1 # 0 +0x8AC4 0xB4D2 # 0 +0x8AC5 0xB4D3 # 0 +0x8AC6 0xB4D4 # 0 +0x8AC7 0xB4D6 # 0 +0x8AC8 0xB4D7 # 0 +0x8AC9 0xB4D8 # 0 +0x8ACA 0xB4D9 # 0 +0x8ACB 0xB4DA # 0 +0x8ACC 0xB4DB # 0 +0x8ACD 0xB4DE # 0 +0x8ACE 0xB4DF # 0 +0x8ACF 0xB4E1 # 0 +0x8AD0 0xB4E2 # 0 +0x8AD1 0xB4E5 # 0 +0x8AD2 0xB4E7 # 0 +0x8AD3 0xB4E8 # 0 +0x8AD4 0xB4E9 # 0 +0x8AD5 0xB4EA # 0 +0x8AD6 0xB4EB # 0 +0x8AD7 0xB4EE # 0 +0x8AD8 0xB4F0 # 0 +0x8AD9 0xB4F2 # 0 +0x8ADA 0xB4F3 # 0 +0x8ADB 0xB4F4 # 0 +0x8ADC 0xB4F5 # 0 +0x8ADD 0xB4F6 # 0 +0x8ADE 0xB4F7 # 0 +0x8ADF 0xB4F9 # 0 +0x8AE0 0xB4FA # 0 +0x8AE1 0xB4FB # 0 +0x8AE2 0xB4FC # 0 +0x8AE3 0xB4FD # 0 +0x8AE4 0xB4FE # 0 +0x8AE5 0xB4FF # 0 +0x8AE6 0xB500 # 0 +0x8AE7 0xB501 # 0 +0x8AE8 0xB502 # 0 +0x8AE9 0xB503 # 0 +0x8AEA 0xB504 # 0 +0x8AEB 0xB505 # 0 +0x8AEC 0xB506 # 0 +0x8AED 0xB507 # 0 +0x8AEE 0xB508 # 0 +0x8AEF 0xB509 # 0 +0x8AF0 0xB50A # 0 +0x8AF1 0xB50B # 0 +0x8AF2 0xB50C # 0 +0x8AF3 0xB50D # 0 +0x8AF4 0xB50E # 0 +0x8AF5 0xB50F # 0 +0x8AF6 0xB510 # 0 +0x8AF7 0xB511 # 0 +0x8AF8 0xB512 # 0 +0x8AF9 0xB513 # 0 +0x8AFA 0xB516 # 0 +0x8AFB 0xB517 # 0 +0x8AFC 0xB519 # 0 +0x8AFD 0xB51A # 0 +0x8AFE 0xB51D # 0 +0x8B41 0xB51E # 0 +0x8B42 0xB51F # 0 +0x8B43 0xB520 # 0 +0x8B44 0xB521 # 0 +0x8B45 0xB522 # 0 +0x8B46 0xB523 # 0 +0x8B47 0xB526 # 0 +0x8B48 0xB52B # 0 +0x8B49 0xB52C # 0 +0x8B4A 0xB52D # 0 +0x8B4B 0xB52E # 0 +0x8B4C 0xB52F # 0 +0x8B4D 0xB532 # 0 +0x8B4E 0xB533 # 0 +0x8B4F 0xB535 # 0 +0x8B50 0xB536 # 0 +0x8B51 0xB537 # 0 +0x8B52 0xB539 # 0 +0x8B53 0xB53A # 0 +0x8B54 0xB53B # 0 +0x8B55 0xB53C # 0 +0x8B56 0xB53D # 0 +0x8B57 0xB53E # 0 +0x8B58 0xB53F # 0 +0x8B59 0xB542 # 0 +0x8B5A 0xB546 # 0 +0x8B61 0xB547 # 0 +0x8B62 0xB548 # 0 +0x8B63 0xB549 # 0 +0x8B64 0xB54A # 0 +0x8B65 0xB54E # 0 +0x8B66 0xB54F # 0 +0x8B67 0xB551 # 0 +0x8B68 0xB552 # 0 +0x8B69 0xB553 # 0 +0x8B6A 0xB555 # 0 +0x8B6B 0xB556 # 0 +0x8B6C 0xB557 # 0 +0x8B6D 0xB558 # 0 +0x8B6E 0xB559 # 0 +0x8B6F 0xB55A # 0 +0x8B70 0xB55B # 0 +0x8B71 0xB55E # 0 +0x8B72 0xB562 # 0 +0x8B73 0xB563 # 0 +0x8B74 0xB564 # 0 +0x8B75 0xB565 # 0 +0x8B76 0xB566 # 0 +0x8B77 0xB567 # 0 +0x8B78 0xB568 # 0 +0x8B79 0xB569 # 0 +0x8B7A 0xB56A # 0 +0x8B81 0xB56B # 0 +0x8B82 0xB56C # 0 +0x8B83 0xB56D # 0 +0x8B84 0xB56E # 0 +0x8B85 0xB56F # 0 +0x8B86 0xB570 # 0 +0x8B87 0xB571 # 0 +0x8B88 0xB572 # 0 +0x8B89 0xB573 # 0 +0x8B8A 0xB574 # 0 +0x8B8B 0xB575 # 0 +0x8B8C 0xB576 # 0 +0x8B8D 0xB577 # 0 +0x8B8E 0xB578 # 0 +0x8B8F 0xB579 # 0 +0x8B90 0xB57A # 0 +0x8B91 0xB57B # 0 +0x8B92 0xB57C # 0 +0x8B93 0xB57D # 0 +0x8B94 0xB57E # 0 +0x8B95 0xB57F # 0 +0x8B96 0xB580 # 0 +0x8B97 0xB581 # 0 +0x8B98 0xB582 # 0 +0x8B99 0xB583 # 0 +0x8B9A 0xB584 # 0 +0x8B9B 0xB585 # 0 +0x8B9C 0xB586 # 0 +0x8B9D 0xB587 # 0 +0x8B9E 0xB588 # 0 +0x8B9F 0xB589 # 0 +0x8BA0 0xB58A # 0 +0x8BA1 0xB58B # 0 +0x8BA2 0xB58C # 0 +0x8BA3 0xB58D # 0 +0x8BA4 0xB58E # 0 +0x8BA5 0xB58F # 0 +0x8BA6 0xB590 # 0 +0x8BA7 0xB591 # 0 +0x8BA8 0xB592 # 0 +0x8BA9 0xB593 # 0 +0x8BAA 0xB594 # 0 +0x8BAB 0xB595 # 0 +0x8BAC 0xB596 # 0 +0x8BAD 0xB597 # 0 +0x8BAE 0xB598 # 0 +0x8BAF 0xB599 # 0 +0x8BB0 0xB59A # 0 +0x8BB1 0xB59B # 0 +0x8BB2 0xB59C # 0 +0x8BB3 0xB59D # 0 +0x8BB4 0xB59E # 0 +0x8BB5 0xB59F # 0 +0x8BB6 0xB5A2 # 0 +0x8BB7 0xB5A3 # 0 +0x8BB8 0xB5A5 # 0 +0x8BB9 0xB5A6 # 0 +0x8BBA 0xB5A7 # 0 +0x8BBB 0xB5A9 # 0 +0x8BBC 0xB5AC # 0 +0x8BBD 0xB5AD # 0 +0x8BBE 0xB5AE # 0 +0x8BBF 0xB5AF # 0 +0x8BC0 0xB5B2 # 0 +0x8BC1 0xB5B6 # 0 +0x8BC2 0xB5B7 # 0 +0x8BC3 0xB5B8 # 0 +0x8BC4 0xB5B9 # 0 +0x8BC5 0xB5BA # 0 +0x8BC6 0xB5BE # 0 +0x8BC7 0xB5BF # 0 +0x8BC8 0xB5C1 # 0 +0x8BC9 0xB5C2 # 0 +0x8BCA 0xB5C3 # 0 +0x8BCB 0xB5C5 # 0 +0x8BCC 0xB5C6 # 0 +0x8BCD 0xB5C7 # 0 +0x8BCE 0xB5C8 # 0 +0x8BCF 0xB5C9 # 0 +0x8BD0 0xB5CA # 0 +0x8BD1 0xB5CB # 0 +0x8BD2 0xB5CE # 0 +0x8BD3 0xB5D2 # 0 +0x8BD4 0xB5D3 # 0 +0x8BD5 0xB5D4 # 0 +0x8BD6 0xB5D5 # 0 +0x8BD7 0xB5D6 # 0 +0x8BD8 0xB5D7 # 0 +0x8BD9 0xB5D9 # 0 +0x8BDA 0xB5DA # 0 +0x8BDB 0xB5DB # 0 +0x8BDC 0xB5DC # 0 +0x8BDD 0xB5DD # 0 +0x8BDE 0xB5DE # 0 +0x8BDF 0xB5DF # 0 +0x8BE0 0xB5E0 # 0 +0x8BE1 0xB5E1 # 0 +0x8BE2 0xB5E2 # 0 +0x8BE3 0xB5E3 # 0 +0x8BE4 0xB5E4 # 0 +0x8BE5 0xB5E5 # 0 +0x8BE6 0xB5E6 # 0 +0x8BE7 0xB5E7 # 0 +0x8BE8 0xB5E8 # 0 +0x8BE9 0xB5E9 # 0 +0x8BEA 0xB5EA # 0 +0x8BEB 0xB5EB # 0 +0x8BEC 0xB5ED # 0 +0x8BED 0xB5EE # 0 +0x8BEE 0xB5EF # 0 +0x8BEF 0xB5F0 # 0 +0x8BF0 0xB5F1 # 0 +0x8BF1 0xB5F2 # 0 +0x8BF2 0xB5F3 # 0 +0x8BF3 0xB5F4 # 0 +0x8BF4 0xB5F5 # 0 +0x8BF5 0xB5F6 # 0 +0x8BF6 0xB5F7 # 0 +0x8BF7 0xB5F8 # 0 +0x8BF8 0xB5F9 # 0 +0x8BF9 0xB5FA # 0 +0x8BFA 0xB5FB # 0 +0x8BFB 0xB5FC # 0 +0x8BFC 0xB5FD # 0 +0x8BFD 0xB5FE # 0 +0x8BFE 0xB5FF # 0 +0x8C41 0xB600 # 0 +0x8C42 0xB601 # 0 +0x8C43 0xB602 # 0 +0x8C44 0xB603 # 0 +0x8C45 0xB604 # 0 +0x8C46 0xB605 # 0 +0x8C47 0xB606 # 0 +0x8C48 0xB607 # 0 +0x8C49 0xB608 # 0 +0x8C4A 0xB609 # 0 +0x8C4B 0xB60A # 0 +0x8C4C 0xB60B # 0 +0x8C4D 0xB60C # 0 +0x8C4E 0xB60D # 0 +0x8C4F 0xB60E # 0 +0x8C50 0xB60F # 0 +0x8C51 0xB612 # 0 +0x8C52 0xB613 # 0 +0x8C53 0xB615 # 0 +0x8C54 0xB616 # 0 +0x8C55 0xB617 # 0 +0x8C56 0xB619 # 0 +0x8C57 0xB61A # 0 +0x8C58 0xB61B # 0 +0x8C59 0xB61C # 0 +0x8C5A 0xB61D # 0 +0x8C61 0xB61E # 0 +0x8C62 0xB61F # 0 +0x8C63 0xB620 # 0 +0x8C64 0xB621 # 0 +0x8C65 0xB622 # 0 +0x8C66 0xB623 # 0 +0x8C67 0xB624 # 0 +0x8C68 0xB626 # 0 +0x8C69 0xB627 # 0 +0x8C6A 0xB628 # 0 +0x8C6B 0xB629 # 0 +0x8C6C 0xB62A # 0 +0x8C6D 0xB62B # 0 +0x8C6E 0xB62D # 0 +0x8C6F 0xB62E # 0 +0x8C70 0xB62F # 0 +0x8C71 0xB630 # 0 +0x8C72 0xB631 # 0 +0x8C73 0xB632 # 0 +0x8C74 0xB633 # 0 +0x8C75 0xB635 # 0 +0x8C76 0xB636 # 0 +0x8C77 0xB637 # 0 +0x8C78 0xB638 # 0 +0x8C79 0xB639 # 0 +0x8C7A 0xB63A # 0 +0x8C81 0xB63B # 0 +0x8C82 0xB63C # 0 +0x8C83 0xB63D # 0 +0x8C84 0xB63E # 0 +0x8C85 0xB63F # 0 +0x8C86 0xB640 # 0 +0x8C87 0xB641 # 0 +0x8C88 0xB642 # 0 +0x8C89 0xB643 # 0 +0x8C8A 0xB644 # 0 +0x8C8B 0xB645 # 0 +0x8C8C 0xB646 # 0 +0x8C8D 0xB647 # 0 +0x8C8E 0xB649 # 0 +0x8C8F 0xB64A # 0 +0x8C90 0xB64B # 0 +0x8C91 0xB64C # 0 +0x8C92 0xB64D # 0 +0x8C93 0xB64E # 0 +0x8C94 0xB64F # 0 +0x8C95 0xB650 # 0 +0x8C96 0xB651 # 0 +0x8C97 0xB652 # 0 +0x8C98 0xB653 # 0 +0x8C99 0xB654 # 0 +0x8C9A 0xB655 # 0 +0x8C9B 0xB656 # 0 +0x8C9C 0xB657 # 0 +0x8C9D 0xB658 # 0 +0x8C9E 0xB659 # 0 +0x8C9F 0xB65A # 0 +0x8CA0 0xB65B # 0 +0x8CA1 0xB65C # 0 +0x8CA2 0xB65D # 0 +0x8CA3 0xB65E # 0 +0x8CA4 0xB65F # 0 +0x8CA5 0xB660 # 0 +0x8CA6 0xB661 # 0 +0x8CA7 0xB662 # 0 +0x8CA8 0xB663 # 0 +0x8CA9 0xB665 # 0 +0x8CAA 0xB666 # 0 +0x8CAB 0xB667 # 0 +0x8CAC 0xB669 # 0 +0x8CAD 0xB66A # 0 +0x8CAE 0xB66B # 0 +0x8CAF 0xB66C # 0 +0x8CB0 0xB66D # 0 +0x8CB1 0xB66E # 0 +0x8CB2 0xB66F # 0 +0x8CB3 0xB670 # 0 +0x8CB4 0xB671 # 0 +0x8CB5 0xB672 # 0 +0x8CB6 0xB673 # 0 +0x8CB7 0xB674 # 0 +0x8CB8 0xB675 # 0 +0x8CB9 0xB676 # 0 +0x8CBA 0xB677 # 0 +0x8CBB 0xB678 # 0 +0x8CBC 0xB679 # 0 +0x8CBD 0xB67A # 0 +0x8CBE 0xB67B # 0 +0x8CBF 0xB67C # 0 +0x8CC0 0xB67D # 0 +0x8CC1 0xB67E # 0 +0x8CC2 0xB67F # 0 +0x8CC3 0xB680 # 0 +0x8CC4 0xB681 # 0 +0x8CC5 0xB682 # 0 +0x8CC6 0xB683 # 0 +0x8CC7 0xB684 # 0 +0x8CC8 0xB685 # 0 +0x8CC9 0xB686 # 0 +0x8CCA 0xB687 # 0 +0x8CCB 0xB688 # 0 +0x8CCC 0xB689 # 0 +0x8CCD 0xB68A # 0 +0x8CCE 0xB68B # 0 +0x8CCF 0xB68C # 0 +0x8CD0 0xB68D # 0 +0x8CD1 0xB68E # 0 +0x8CD2 0xB68F # 0 +0x8CD3 0xB690 # 0 +0x8CD4 0xB691 # 0 +0x8CD5 0xB692 # 0 +0x8CD6 0xB693 # 0 +0x8CD7 0xB694 # 0 +0x8CD8 0xB695 # 0 +0x8CD9 0xB696 # 0 +0x8CDA 0xB697 # 0 +0x8CDB 0xB698 # 0 +0x8CDC 0xB699 # 0 +0x8CDD 0xB69A # 0 +0x8CDE 0xB69B # 0 +0x8CDF 0xB69E # 0 +0x8CE0 0xB69F # 0 +0x8CE1 0xB6A1 # 0 +0x8CE2 0xB6A2 # 0 +0x8CE3 0xB6A3 # 0 +0x8CE4 0xB6A5 # 0 +0x8CE5 0xB6A6 # 0 +0x8CE6 0xB6A7 # 0 +0x8CE7 0xB6A8 # 0 +0x8CE8 0xB6A9 # 0 +0x8CE9 0xB6AA # 0 +0x8CEA 0xB6AD # 0 +0x8CEB 0xB6AE # 0 +0x8CEC 0xB6AF # 0 +0x8CED 0xB6B0 # 0 +0x8CEE 0xB6B2 # 0 +0x8CEF 0xB6B3 # 0 +0x8CF0 0xB6B4 # 0 +0x8CF1 0xB6B5 # 0 +0x8CF2 0xB6B6 # 0 +0x8CF3 0xB6B7 # 0 +0x8CF4 0xB6B8 # 0 +0x8CF5 0xB6B9 # 0 +0x8CF6 0xB6BA # 0 +0x8CF7 0xB6BB # 0 +0x8CF8 0xB6BC # 0 +0x8CF9 0xB6BD # 0 +0x8CFA 0xB6BE # 0 +0x8CFB 0xB6BF # 0 +0x8CFC 0xB6C0 # 0 +0x8CFD 0xB6C1 # 0 +0x8CFE 0xB6C2 # 0 +0x8D41 0xB6C3 # 0 +0x8D42 0xB6C4 # 0 +0x8D43 0xB6C5 # 0 +0x8D44 0xB6C6 # 0 +0x8D45 0xB6C7 # 0 +0x8D46 0xB6C8 # 0 +0x8D47 0xB6C9 # 0 +0x8D48 0xB6CA # 0 +0x8D49 0xB6CB # 0 +0x8D4A 0xB6CC # 0 +0x8D4B 0xB6CD # 0 +0x8D4C 0xB6CE # 0 +0x8D4D 0xB6CF # 0 +0x8D4E 0xB6D0 # 0 +0x8D4F 0xB6D1 # 0 +0x8D50 0xB6D2 # 0 +0x8D51 0xB6D3 # 0 +0x8D52 0xB6D5 # 0 +0x8D53 0xB6D6 # 0 +0x8D54 0xB6D7 # 0 +0x8D55 0xB6D8 # 0 +0x8D56 0xB6D9 # 0 +0x8D57 0xB6DA # 0 +0x8D58 0xB6DB # 0 +0x8D59 0xB6DC # 0 +0x8D5A 0xB6DD # 0 +0x8D61 0xB6DE # 0 +0x8D62 0xB6DF # 0 +0x8D63 0xB6E0 # 0 +0x8D64 0xB6E1 # 0 +0x8D65 0xB6E2 # 0 +0x8D66 0xB6E3 # 0 +0x8D67 0xB6E4 # 0 +0x8D68 0xB6E5 # 0 +0x8D69 0xB6E6 # 0 +0x8D6A 0xB6E7 # 0 +0x8D6B 0xB6E8 # 0 +0x8D6C 0xB6E9 # 0 +0x8D6D 0xB6EA # 0 +0x8D6E 0xB6EB # 0 +0x8D6F 0xB6EC # 0 +0x8D70 0xB6ED # 0 +0x8D71 0xB6EE # 0 +0x8D72 0xB6EF # 0 +0x8D73 0xB6F1 # 0 +0x8D74 0xB6F2 # 0 +0x8D75 0xB6F3 # 0 +0x8D76 0xB6F5 # 0 +0x8D77 0xB6F6 # 0 +0x8D78 0xB6F7 # 0 +0x8D79 0xB6F9 # 0 +0x8D7A 0xB6FA # 0 +0x8D81 0xB6FB # 0 +0x8D82 0xB6FC # 0 +0x8D83 0xB6FD # 0 +0x8D84 0xB6FE # 0 +0x8D85 0xB6FF # 0 +0x8D86 0xB702 # 0 +0x8D87 0xB703 # 0 +0x8D88 0xB704 # 0 +0x8D89 0xB706 # 0 +0x8D8A 0xB707 # 0 +0x8D8B 0xB708 # 0 +0x8D8C 0xB709 # 0 +0x8D8D 0xB70A # 0 +0x8D8E 0xB70B # 0 +0x8D8F 0xB70C # 0 +0x8D90 0xB70D # 0 +0x8D91 0xB70E # 0 +0x8D92 0xB70F # 0 +0x8D93 0xB710 # 0 +0x8D94 0xB711 # 0 +0x8D95 0xB712 # 0 +0x8D96 0xB713 # 0 +0x8D97 0xB714 # 0 +0x8D98 0xB715 # 0 +0x8D99 0xB716 # 0 +0x8D9A 0xB717 # 0 +0x8D9B 0xB718 # 0 +0x8D9C 0xB719 # 0 +0x8D9D 0xB71A # 0 +0x8D9E 0xB71B # 0 +0x8D9F 0xB71C # 0 +0x8DA0 0xB71D # 0 +0x8DA1 0xB71E # 0 +0x8DA2 0xB71F # 0 +0x8DA3 0xB720 # 0 +0x8DA4 0xB721 # 0 +0x8DA5 0xB722 # 0 +0x8DA6 0xB723 # 0 +0x8DA7 0xB724 # 0 +0x8DA8 0xB725 # 0 +0x8DA9 0xB726 # 0 +0x8DAA 0xB727 # 0 +0x8DAB 0xB72A # 0 +0x8DAC 0xB72B # 0 +0x8DAD 0xB72D # 0 +0x8DAE 0xB72E # 0 +0x8DAF 0xB731 # 0 +0x8DB0 0xB732 # 0 +0x8DB1 0xB733 # 0 +0x8DB2 0xB734 # 0 +0x8DB3 0xB735 # 0 +0x8DB4 0xB736 # 0 +0x8DB5 0xB737 # 0 +0x8DB6 0xB73A # 0 +0x8DB7 0xB73C # 0 +0x8DB8 0xB73D # 0 +0x8DB9 0xB73E # 0 +0x8DBA 0xB73F # 0 +0x8DBB 0xB740 # 0 +0x8DBC 0xB741 # 0 +0x8DBD 0xB742 # 0 +0x8DBE 0xB743 # 0 +0x8DBF 0xB745 # 0 +0x8DC0 0xB746 # 0 +0x8DC1 0xB747 # 0 +0x8DC2 0xB749 # 0 +0x8DC3 0xB74A # 0 +0x8DC4 0xB74B # 0 +0x8DC5 0xB74D # 0 +0x8DC6 0xB74E # 0 +0x8DC7 0xB74F # 0 +0x8DC8 0xB750 # 0 +0x8DC9 0xB751 # 0 +0x8DCA 0xB752 # 0 +0x8DCB 0xB753 # 0 +0x8DCC 0xB756 # 0 +0x8DCD 0xB757 # 0 +0x8DCE 0xB758 # 0 +0x8DCF 0xB759 # 0 +0x8DD0 0xB75A # 0 +0x8DD1 0xB75B # 0 +0x8DD2 0xB75C # 0 +0x8DD3 0xB75D # 0 +0x8DD4 0xB75E # 0 +0x8DD5 0xB75F # 0 +0x8DD6 0xB761 # 0 +0x8DD7 0xB762 # 0 +0x8DD8 0xB763 # 0 +0x8DD9 0xB765 # 0 +0x8DDA 0xB766 # 0 +0x8DDB 0xB767 # 0 +0x8DDC 0xB769 # 0 +0x8DDD 0xB76A # 0 +0x8DDE 0xB76B # 0 +0x8DDF 0xB76C # 0 +0x8DE0 0xB76D # 0 +0x8DE1 0xB76E # 0 +0x8DE2 0xB76F # 0 +0x8DE3 0xB772 # 0 +0x8DE4 0xB774 # 0 +0x8DE5 0xB776 # 0 +0x8DE6 0xB777 # 0 +0x8DE7 0xB778 # 0 +0x8DE8 0xB779 # 0 +0x8DE9 0xB77A # 0 +0x8DEA 0xB77B # 0 +0x8DEB 0xB77E # 0 +0x8DEC 0xB77F # 0 +0x8DED 0xB781 # 0 +0x8DEE 0xB782 # 0 +0x8DEF 0xB783 # 0 +0x8DF0 0xB785 # 0 +0x8DF1 0xB786 # 0 +0x8DF2 0xB787 # 0 +0x8DF3 0xB788 # 0 +0x8DF4 0xB789 # 0 +0x8DF5 0xB78A # 0 +0x8DF6 0xB78B # 0 +0x8DF7 0xB78E # 0 +0x8DF8 0xB793 # 0 +0x8DF9 0xB794 # 0 +0x8DFA 0xB795 # 0 +0x8DFB 0xB79A # 0 +0x8DFC 0xB79B # 0 +0x8DFD 0xB79D # 0 +0x8DFE 0xB79E # 0 +0x8E41 0xB79F # 0 +0x8E42 0xB7A1 # 0 +0x8E43 0xB7A2 # 0 +0x8E44 0xB7A3 # 0 +0x8E45 0xB7A4 # 0 +0x8E46 0xB7A5 # 0 +0x8E47 0xB7A6 # 0 +0x8E48 0xB7A7 # 0 +0x8E49 0xB7AA # 0 +0x8E4A 0xB7AE # 0 +0x8E4B 0xB7AF # 0 +0x8E4C 0xB7B0 # 0 +0x8E4D 0xB7B1 # 0 +0x8E4E 0xB7B2 # 0 +0x8E4F 0xB7B3 # 0 +0x8E50 0xB7B6 # 0 +0x8E51 0xB7B7 # 0 +0x8E52 0xB7B9 # 0 +0x8E53 0xB7BA # 0 +0x8E54 0xB7BB # 0 +0x8E55 0xB7BC # 0 +0x8E56 0xB7BD # 0 +0x8E57 0xB7BE # 0 +0x8E58 0xB7BF # 0 +0x8E59 0xB7C0 # 0 +0x8E5A 0xB7C1 # 0 +0x8E61 0xB7C2 # 0 +0x8E62 0xB7C3 # 0 +0x8E63 0xB7C4 # 0 +0x8E64 0xB7C5 # 0 +0x8E65 0xB7C6 # 0 +0x8E66 0xB7C8 # 0 +0x8E67 0xB7CA # 0 +0x8E68 0xB7CB # 0 +0x8E69 0xB7CC # 0 +0x8E6A 0xB7CD # 0 +0x8E6B 0xB7CE # 0 +0x8E6C 0xB7CF # 0 +0x8E6D 0xB7D0 # 0 +0x8E6E 0xB7D1 # 0 +0x8E6F 0xB7D2 # 0 +0x8E70 0xB7D3 # 0 +0x8E71 0xB7D4 # 0 +0x8E72 0xB7D5 # 0 +0x8E73 0xB7D6 # 0 +0x8E74 0xB7D7 # 0 +0x8E75 0xB7D8 # 0 +0x8E76 0xB7D9 # 0 +0x8E77 0xB7DA # 0 +0x8E78 0xB7DB # 0 +0x8E79 0xB7DC # 0 +0x8E7A 0xB7DD # 0 +0x8E81 0xB7DE # 0 +0x8E82 0xB7DF # 0 +0x8E83 0xB7E0 # 0 +0x8E84 0xB7E1 # 0 +0x8E85 0xB7E2 # 0 +0x8E86 0xB7E3 # 0 +0x8E87 0xB7E4 # 0 +0x8E88 0xB7E5 # 0 +0x8E89 0xB7E6 # 0 +0x8E8A 0xB7E7 # 0 +0x8E8B 0xB7E8 # 0 +0x8E8C 0xB7E9 # 0 +0x8E8D 0xB7EA # 0 +0x8E8E 0xB7EB # 0 +0x8E8F 0xB7EE # 0 +0x8E90 0xB7EF # 0 +0x8E91 0xB7F1 # 0 +0x8E92 0xB7F2 # 0 +0x8E93 0xB7F3 # 0 +0x8E94 0xB7F5 # 0 +0x8E95 0xB7F6 # 0 +0x8E96 0xB7F7 # 0 +0x8E97 0xB7F8 # 0 +0x8E98 0xB7F9 # 0 +0x8E99 0xB7FA # 0 +0x8E9A 0xB7FB # 0 +0x8E9B 0xB7FE # 0 +0x8E9C 0xB802 # 0 +0x8E9D 0xB803 # 0 +0x8E9E 0xB804 # 0 +0x8E9F 0xB805 # 0 +0x8EA0 0xB806 # 0 +0x8EA1 0xB80A # 0 +0x8EA2 0xB80B # 0 +0x8EA3 0xB80D # 0 +0x8EA4 0xB80E # 0 +0x8EA5 0xB80F # 0 +0x8EA6 0xB811 # 0 +0x8EA7 0xB812 # 0 +0x8EA8 0xB813 # 0 +0x8EA9 0xB814 # 0 +0x8EAA 0xB815 # 0 +0x8EAB 0xB816 # 0 +0x8EAC 0xB817 # 0 +0x8EAD 0xB81A # 0 +0x8EAE 0xB81C # 0 +0x8EAF 0xB81E # 0 +0x8EB0 0xB81F # 0 +0x8EB1 0xB820 # 0 +0x8EB2 0xB821 # 0 +0x8EB3 0xB822 # 0 +0x8EB4 0xB823 # 0 +0x8EB5 0xB826 # 0 +0x8EB6 0xB827 # 0 +0x8EB7 0xB829 # 0 +0x8EB8 0xB82A # 0 +0x8EB9 0xB82B # 0 +0x8EBA 0xB82D # 0 +0x8EBB 0xB82E # 0 +0x8EBC 0xB82F # 0 +0x8EBD 0xB830 # 0 +0x8EBE 0xB831 # 0 +0x8EBF 0xB832 # 0 +0x8EC0 0xB833 # 0 +0x8EC1 0xB836 # 0 +0x8EC2 0xB83A # 0 +0x8EC3 0xB83B # 0 +0x8EC4 0xB83C # 0 +0x8EC5 0xB83D # 0 +0x8EC6 0xB83E # 0 +0x8EC7 0xB83F # 0 +0x8EC8 0xB841 # 0 +0x8EC9 0xB842 # 0 +0x8ECA 0xB843 # 0 +0x8ECB 0xB845 # 0 +0x8ECC 0xB846 # 0 +0x8ECD 0xB847 # 0 +0x8ECE 0xB848 # 0 +0x8ECF 0xB849 # 0 +0x8ED0 0xB84A # 0 +0x8ED1 0xB84B # 0 +0x8ED2 0xB84C # 0 +0x8ED3 0xB84D # 0 +0x8ED4 0xB84E # 0 +0x8ED5 0xB84F # 0 +0x8ED6 0xB850 # 0 +0x8ED7 0xB852 # 0 +0x8ED8 0xB854 # 0 +0x8ED9 0xB855 # 0 +0x8EDA 0xB856 # 0 +0x8EDB 0xB857 # 0 +0x8EDC 0xB858 # 0 +0x8EDD 0xB859 # 0 +0x8EDE 0xB85A # 0 +0x8EDF 0xB85B # 0 +0x8EE0 0xB85E # 0 +0x8EE1 0xB85F # 0 +0x8EE2 0xB861 # 0 +0x8EE3 0xB862 # 0 +0x8EE4 0xB863 # 0 +0x8EE5 0xB865 # 0 +0x8EE6 0xB866 # 0 +0x8EE7 0xB867 # 0 +0x8EE8 0xB868 # 0 +0x8EE9 0xB869 # 0 +0x8EEA 0xB86A # 0 +0x8EEB 0xB86B # 0 +0x8EEC 0xB86E # 0 +0x8EED 0xB870 # 0 +0x8EEE 0xB872 # 0 +0x8EEF 0xB873 # 0 +0x8EF0 0xB874 # 0 +0x8EF1 0xB875 # 0 +0x8EF2 0xB876 # 0 +0x8EF3 0xB877 # 0 +0x8EF4 0xB879 # 0 +0x8EF5 0xB87A # 0 +0x8EF6 0xB87B # 0 +0x8EF7 0xB87D # 0 +0x8EF8 0xB87E # 0 +0x8EF9 0xB87F # 0 +0x8EFA 0xB880 # 0 +0x8EFB 0xB881 # 0 +0x8EFC 0xB882 # 0 +0x8EFD 0xB883 # 0 +0x8EFE 0xB884 # 0 +0x8F41 0xB885 # 0 +0x8F42 0xB886 # 0 +0x8F43 0xB887 # 0 +0x8F44 0xB888 # 0 +0x8F45 0xB889 # 0 +0x8F46 0xB88A # 0 +0x8F47 0xB88B # 0 +0x8F48 0xB88C # 0 +0x8F49 0xB88E # 0 +0x8F4A 0xB88F # 0 +0x8F4B 0xB890 # 0 +0x8F4C 0xB891 # 0 +0x8F4D 0xB892 # 0 +0x8F4E 0xB893 # 0 +0x8F4F 0xB894 # 0 +0x8F50 0xB895 # 0 +0x8F51 0xB896 # 0 +0x8F52 0xB897 # 0 +0x8F53 0xB898 # 0 +0x8F54 0xB899 # 0 +0x8F55 0xB89A # 0 +0x8F56 0xB89B # 0 +0x8F57 0xB89C # 0 +0x8F58 0xB89D # 0 +0x8F59 0xB89E # 0 +0x8F5A 0xB89F # 0 +0x8F61 0xB8A0 # 0 +0x8F62 0xB8A1 # 0 +0x8F63 0xB8A2 # 0 +0x8F64 0xB8A3 # 0 +0x8F65 0xB8A4 # 0 +0x8F66 0xB8A5 # 0 +0x8F67 0xB8A6 # 0 +0x8F68 0xB8A7 # 0 +0x8F69 0xB8A9 # 0 +0x8F6A 0xB8AA # 0 +0x8F6B 0xB8AB # 0 +0x8F6C 0xB8AC # 0 +0x8F6D 0xB8AD # 0 +0x8F6E 0xB8AE # 0 +0x8F6F 0xB8AF # 0 +0x8F70 0xB8B1 # 0 +0x8F71 0xB8B2 # 0 +0x8F72 0xB8B3 # 0 +0x8F73 0xB8B5 # 0 +0x8F74 0xB8B6 # 0 +0x8F75 0xB8B7 # 0 +0x8F76 0xB8B9 # 0 +0x8F77 0xB8BA # 0 +0x8F78 0xB8BB # 0 +0x8F79 0xB8BC # 0 +0x8F7A 0xB8BD # 0 +0x8F81 0xB8BE # 0 +0x8F82 0xB8BF # 0 +0x8F83 0xB8C2 # 0 +0x8F84 0xB8C4 # 0 +0x8F85 0xB8C6 # 0 +0x8F86 0xB8C7 # 0 +0x8F87 0xB8C8 # 0 +0x8F88 0xB8C9 # 0 +0x8F89 0xB8CA # 0 +0x8F8A 0xB8CB # 0 +0x8F8B 0xB8CD # 0 +0x8F8C 0xB8CE # 0 +0x8F8D 0xB8CF # 0 +0x8F8E 0xB8D1 # 0 +0x8F8F 0xB8D2 # 0 +0x8F90 0xB8D3 # 0 +0x8F91 0xB8D5 # 0 +0x8F92 0xB8D6 # 0 +0x8F93 0xB8D7 # 0 +0x8F94 0xB8D8 # 0 +0x8F95 0xB8D9 # 0 +0x8F96 0xB8DA # 0 +0x8F97 0xB8DB # 0 +0x8F98 0xB8DC # 0 +0x8F99 0xB8DE # 0 +0x8F9A 0xB8E0 # 0 +0x8F9B 0xB8E2 # 0 +0x8F9C 0xB8E3 # 0 +0x8F9D 0xB8E4 # 0 +0x8F9E 0xB8E5 # 0 +0x8F9F 0xB8E6 # 0 +0x8FA0 0xB8E7 # 0 +0x8FA1 0xB8EA # 0 +0x8FA2 0xB8EB # 0 +0x8FA3 0xB8ED # 0 +0x8FA4 0xB8EE # 0 +0x8FA5 0xB8EF # 0 +0x8FA6 0xB8F1 # 0 +0x8FA7 0xB8F2 # 0 +0x8FA8 0xB8F3 # 0 +0x8FA9 0xB8F4 # 0 +0x8FAA 0xB8F5 # 0 +0x8FAB 0xB8F6 # 0 +0x8FAC 0xB8F7 # 0 +0x8FAD 0xB8FA # 0 +0x8FAE 0xB8FC # 0 +0x8FAF 0xB8FE # 0 +0x8FB0 0xB8FF # 0 +0x8FB1 0xB900 # 0 +0x8FB2 0xB901 # 0 +0x8FB3 0xB902 # 0 +0x8FB4 0xB903 # 0 +0x8FB5 0xB905 # 0 +0x8FB6 0xB906 # 0 +0x8FB7 0xB907 # 0 +0x8FB8 0xB908 # 0 +0x8FB9 0xB909 # 0 +0x8FBA 0xB90A # 0 +0x8FBB 0xB90B # 0 +0x8FBC 0xB90C # 0 +0x8FBD 0xB90D # 0 +0x8FBE 0xB90E # 0 +0x8FBF 0xB90F # 0 +0x8FC0 0xB910 # 0 +0x8FC1 0xB911 # 0 +0x8FC2 0xB912 # 0 +0x8FC3 0xB913 # 0 +0x8FC4 0xB914 # 0 +0x8FC5 0xB915 # 0 +0x8FC6 0xB916 # 0 +0x8FC7 0xB917 # 0 +0x8FC8 0xB919 # 0 +0x8FC9 0xB91A # 0 +0x8FCA 0xB91B # 0 +0x8FCB 0xB91C # 0 +0x8FCC 0xB91D # 0 +0x8FCD 0xB91E # 0 +0x8FCE 0xB91F # 0 +0x8FCF 0xB921 # 0 +0x8FD0 0xB922 # 0 +0x8FD1 0xB923 # 0 +0x8FD2 0xB924 # 0 +0x8FD3 0xB925 # 0 +0x8FD4 0xB926 # 0 +0x8FD5 0xB927 # 0 +0x8FD6 0xB928 # 0 +0x8FD7 0xB929 # 0 +0x8FD8 0xB92A # 0 +0x8FD9 0xB92B # 0 +0x8FDA 0xB92C # 0 +0x8FDB 0xB92D # 0 +0x8FDC 0xB92E # 0 +0x8FDD 0xB92F # 0 +0x8FDE 0xB930 # 0 +0x8FDF 0xB931 # 0 +0x8FE0 0xB932 # 0 +0x8FE1 0xB933 # 0 +0x8FE2 0xB934 # 0 +0x8FE3 0xB935 # 0 +0x8FE4 0xB936 # 0 +0x8FE5 0xB937 # 0 +0x8FE6 0xB938 # 0 +0x8FE7 0xB939 # 0 +0x8FE8 0xB93A # 0 +0x8FE9 0xB93B # 0 +0x8FEA 0xB93E # 0 +0x8FEB 0xB93F # 0 +0x8FEC 0xB941 # 0 +0x8FED 0xB942 # 0 +0x8FEE 0xB943 # 0 +0x8FEF 0xB945 # 0 +0x8FF0 0xB946 # 0 +0x8FF1 0xB947 # 0 +0x8FF2 0xB948 # 0 +0x8FF3 0xB949 # 0 +0x8FF4 0xB94A # 0 +0x8FF5 0xB94B # 0 +0x8FF6 0xB94D # 0 +0x8FF7 0xB94E # 0 +0x8FF8 0xB950 # 0 +0x8FF9 0xB952 # 0 +0x8FFA 0xB953 # 0 +0x8FFB 0xB954 # 0 +0x8FFC 0xB955 # 0 +0x8FFD 0xB956 # 0 +0x8FFE 0xB957 # 0 +0x9041 0xB95A # 0 +0x9042 0xB95B # 0 +0x9043 0xB95D # 0 +0x9044 0xB95E # 0 +0x9045 0xB95F # 0 +0x9046 0xB961 # 0 +0x9047 0xB962 # 0 +0x9048 0xB963 # 0 +0x9049 0xB964 # 0 +0x904A 0xB965 # 0 +0x904B 0xB966 # 0 +0x904C 0xB967 # 0 +0x904D 0xB96A # 0 +0x904E 0xB96C # 0 +0x904F 0xB96E # 0 +0x9050 0xB96F # 0 +0x9051 0xB970 # 0 +0x9052 0xB971 # 0 +0x9053 0xB972 # 0 +0x9054 0xB973 # 0 +0x9055 0xB976 # 0 +0x9056 0xB977 # 0 +0x9057 0xB979 # 0 +0x9058 0xB97A # 0 +0x9059 0xB97B # 0 +0x905A 0xB97D # 0 +0x9061 0xB97E # 0 +0x9062 0xB97F # 0 +0x9063 0xB980 # 0 +0x9064 0xB981 # 0 +0x9065 0xB982 # 0 +0x9066 0xB983 # 0 +0x9067 0xB986 # 0 +0x9068 0xB988 # 0 +0x9069 0xB98B # 0 +0x906A 0xB98C # 0 +0x906B 0xB98F # 0 +0x906C 0xB990 # 0 +0x906D 0xB991 # 0 +0x906E 0xB992 # 0 +0x906F 0xB993 # 0 +0x9070 0xB994 # 0 +0x9071 0xB995 # 0 +0x9072 0xB996 # 0 +0x9073 0xB997 # 0 +0x9074 0xB998 # 0 +0x9075 0xB999 # 0 +0x9076 0xB99A # 0 +0x9077 0xB99B # 0 +0x9078 0xB99C # 0 +0x9079 0xB99D # 0 +0x907A 0xB99E # 0 +0x9081 0xB99F # 0 +0x9082 0xB9A0 # 0 +0x9083 0xB9A1 # 0 +0x9084 0xB9A2 # 0 +0x9085 0xB9A3 # 0 +0x9086 0xB9A4 # 0 +0x9087 0xB9A5 # 0 +0x9088 0xB9A6 # 0 +0x9089 0xB9A7 # 0 +0x908A 0xB9A8 # 0 +0x908B 0xB9A9 # 0 +0x908C 0xB9AA # 0 +0x908D 0xB9AB # 0 +0x908E 0xB9AE # 0 +0x908F 0xB9AF # 0 +0x9090 0xB9B1 # 0 +0x9091 0xB9B2 # 0 +0x9092 0xB9B3 # 0 +0x9093 0xB9B5 # 0 +0x9094 0xB9B6 # 0 +0x9095 0xB9B7 # 0 +0x9096 0xB9B8 # 0 +0x9097 0xB9B9 # 0 +0x9098 0xB9BA # 0 +0x9099 0xB9BB # 0 +0x909A 0xB9BE # 0 +0x909B 0xB9C0 # 0 +0x909C 0xB9C2 # 0 +0x909D 0xB9C3 # 0 +0x909E 0xB9C4 # 0 +0x909F 0xB9C5 # 0 +0x90A0 0xB9C6 # 0 +0x90A1 0xB9C7 # 0 +0x90A2 0xB9CA # 0 +0x90A3 0xB9CB # 0 +0x90A4 0xB9CD # 0 +0x90A5 0xB9D3 # 0 +0x90A6 0xB9D4 # 0 +0x90A7 0xB9D5 # 0 +0x90A8 0xB9D6 # 0 +0x90A9 0xB9D7 # 0 +0x90AA 0xB9DA # 0 +0x90AB 0xB9DC # 0 +0x90AC 0xB9DF # 0 +0x90AD 0xB9E0 # 0 +0x90AE 0xB9E2 # 0 +0x90AF 0xB9E6 # 0 +0x90B0 0xB9E7 # 0 +0x90B1 0xB9E9 # 0 +0x90B2 0xB9EA # 0 +0x90B3 0xB9EB # 0 +0x90B4 0xB9ED # 0 +0x90B5 0xB9EE # 0 +0x90B6 0xB9EF # 0 +0x90B7 0xB9F0 # 0 +0x90B8 0xB9F1 # 0 +0x90B9 0xB9F2 # 0 +0x90BA 0xB9F3 # 0 +0x90BB 0xB9F6 # 0 +0x90BC 0xB9FB # 0 +0x90BD 0xB9FC # 0 +0x90BE 0xB9FD # 0 +0x90BF 0xB9FE # 0 +0x90C0 0xB9FF # 0 +0x90C1 0xBA02 # 0 +0x90C2 0xBA03 # 0 +0x90C3 0xBA04 # 0 +0x90C4 0xBA05 # 0 +0x90C5 0xBA06 # 0 +0x90C6 0xBA07 # 0 +0x90C7 0xBA09 # 0 +0x90C8 0xBA0A # 0 +0x90C9 0xBA0B # 0 +0x90CA 0xBA0C # 0 +0x90CB 0xBA0D # 0 +0x90CC 0xBA0E # 0 +0x90CD 0xBA0F # 0 +0x90CE 0xBA10 # 0 +0x90CF 0xBA11 # 0 +0x90D0 0xBA12 # 0 +0x90D1 0xBA13 # 0 +0x90D2 0xBA14 # 0 +0x90D3 0xBA16 # 0 +0x90D4 0xBA17 # 0 +0x90D5 0xBA18 # 0 +0x90D6 0xBA19 # 0 +0x90D7 0xBA1A # 0 +0x90D8 0xBA1B # 0 +0x90D9 0xBA1C # 0 +0x90DA 0xBA1D # 0 +0x90DB 0xBA1E # 0 +0x90DC 0xBA1F # 0 +0x90DD 0xBA20 # 0 +0x90DE 0xBA21 # 0 +0x90DF 0xBA22 # 0 +0x90E0 0xBA23 # 0 +0x90E1 0xBA24 # 0 +0x90E2 0xBA25 # 0 +0x90E3 0xBA26 # 0 +0x90E4 0xBA27 # 0 +0x90E5 0xBA28 # 0 +0x90E6 0xBA29 # 0 +0x90E7 0xBA2A # 0 +0x90E8 0xBA2B # 0 +0x90E9 0xBA2C # 0 +0x90EA 0xBA2D # 0 +0x90EB 0xBA2E # 0 +0x90EC 0xBA2F # 0 +0x90ED 0xBA30 # 0 +0x90EE 0xBA31 # 0 +0x90EF 0xBA32 # 0 +0x90F0 0xBA33 # 0 +0x90F1 0xBA34 # 0 +0x90F2 0xBA35 # 0 +0x90F3 0xBA36 # 0 +0x90F4 0xBA37 # 0 +0x90F5 0xBA3A # 0 +0x90F6 0xBA3B # 0 +0x90F7 0xBA3D # 0 +0x90F8 0xBA3E # 0 +0x90F9 0xBA3F # 0 +0x90FA 0xBA41 # 0 +0x90FB 0xBA43 # 0 +0x90FC 0xBA44 # 0 +0x90FD 0xBA45 # 0 +0x90FE 0xBA46 # 0 +0x9141 0xBA47 # 0 +0x9142 0xBA4A # 0 +0x9143 0xBA4C # 0 +0x9144 0xBA4F # 0 +0x9145 0xBA50 # 0 +0x9146 0xBA51 # 0 +0x9147 0xBA52 # 0 +0x9148 0xBA56 # 0 +0x9149 0xBA57 # 0 +0x914A 0xBA59 # 0 +0x914B 0xBA5A # 0 +0x914C 0xBA5B # 0 +0x914D 0xBA5D # 0 +0x914E 0xBA5E # 0 +0x914F 0xBA5F # 0 +0x9150 0xBA60 # 0 +0x9151 0xBA61 # 0 +0x9152 0xBA62 # 0 +0x9153 0xBA63 # 0 +0x9154 0xBA66 # 0 +0x9155 0xBA6A # 0 +0x9156 0xBA6B # 0 +0x9157 0xBA6C # 0 +0x9158 0xBA6D # 0 +0x9159 0xBA6E # 0 +0x915A 0xBA6F # 0 +0x9161 0xBA72 # 0 +0x9162 0xBA73 # 0 +0x9163 0xBA75 # 0 +0x9164 0xBA76 # 0 +0x9165 0xBA77 # 0 +0x9166 0xBA79 # 0 +0x9167 0xBA7A # 0 +0x9168 0xBA7B # 0 +0x9169 0xBA7C # 0 +0x916A 0xBA7D # 0 +0x916B 0xBA7E # 0 +0x916C 0xBA7F # 0 +0x916D 0xBA80 # 0 +0x916E 0xBA81 # 0 +0x916F 0xBA82 # 0 +0x9170 0xBA86 # 0 +0x9171 0xBA88 # 0 +0x9172 0xBA89 # 0 +0x9173 0xBA8A # 0 +0x9174 0xBA8B # 0 +0x9175 0xBA8D # 0 +0x9176 0xBA8E # 0 +0x9177 0xBA8F # 0 +0x9178 0xBA90 # 0 +0x9179 0xBA91 # 0 +0x917A 0xBA92 # 0 +0x9181 0xBA93 # 0 +0x9182 0xBA94 # 0 +0x9183 0xBA95 # 0 +0x9184 0xBA96 # 0 +0x9185 0xBA97 # 0 +0x9186 0xBA98 # 0 +0x9187 0xBA99 # 0 +0x9188 0xBA9A # 0 +0x9189 0xBA9B # 0 +0x918A 0xBA9C # 0 +0x918B 0xBA9D # 0 +0x918C 0xBA9E # 0 +0x918D 0xBA9F # 0 +0x918E 0xBAA0 # 0 +0x918F 0xBAA1 # 0 +0x9190 0xBAA2 # 0 +0x9191 0xBAA3 # 0 +0x9192 0xBAA4 # 0 +0x9193 0xBAA5 # 0 +0x9194 0xBAA6 # 0 +0x9195 0xBAA7 # 0 +0x9196 0xBAAA # 0 +0x9197 0xBAAD # 0 +0x9198 0xBAAE # 0 +0x9199 0xBAAF # 0 +0x919A 0xBAB1 # 0 +0x919B 0xBAB3 # 0 +0x919C 0xBAB4 # 0 +0x919D 0xBAB5 # 0 +0x919E 0xBAB6 # 0 +0x919F 0xBAB7 # 0 +0x91A0 0xBABA # 0 +0x91A1 0xBABC # 0 +0x91A2 0xBABE # 0 +0x91A3 0xBABF # 0 +0x91A4 0xBAC0 # 0 +0x91A5 0xBAC1 # 0 +0x91A6 0xBAC2 # 0 +0x91A7 0xBAC3 # 0 +0x91A8 0xBAC5 # 0 +0x91A9 0xBAC6 # 0 +0x91AA 0xBAC7 # 0 +0x91AB 0xBAC9 # 0 +0x91AC 0xBACA # 0 +0x91AD 0xBACB # 0 +0x91AE 0xBACC # 0 +0x91AF 0xBACD # 0 +0x91B0 0xBACE # 0 +0x91B1 0xBACF # 0 +0x91B2 0xBAD0 # 0 +0x91B3 0xBAD1 # 0 +0x91B4 0xBAD2 # 0 +0x91B5 0xBAD3 # 0 +0x91B6 0xBAD4 # 0 +0x91B7 0xBAD5 # 0 +0x91B8 0xBAD6 # 0 +0x91B9 0xBAD7 # 0 +0x91BA 0xBADA # 0 +0x91BB 0xBADB # 0 +0x91BC 0xBADC # 0 +0x91BD 0xBADD # 0 +0x91BE 0xBADE # 0 +0x91BF 0xBADF # 0 +0x91C0 0xBAE0 # 0 +0x91C1 0xBAE1 # 0 +0x91C2 0xBAE2 # 0 +0x91C3 0xBAE3 # 0 +0x91C4 0xBAE4 # 0 +0x91C5 0xBAE5 # 0 +0x91C6 0xBAE6 # 0 +0x91C7 0xBAE7 # 0 +0x91C8 0xBAE8 # 0 +0x91C9 0xBAE9 # 0 +0x91CA 0xBAEA # 0 +0x91CB 0xBAEB # 0 +0x91CC 0xBAEC # 0 +0x91CD 0xBAED # 0 +0x91CE 0xBAEE # 0 +0x91CF 0xBAEF # 0 +0x91D0 0xBAF0 # 0 +0x91D1 0xBAF1 # 0 +0x91D2 0xBAF2 # 0 +0x91D3 0xBAF3 # 0 +0x91D4 0xBAF4 # 0 +0x91D5 0xBAF5 # 0 +0x91D6 0xBAF6 # 0 +0x91D7 0xBAF7 # 0 +0x91D8 0xBAF8 # 0 +0x91D9 0xBAF9 # 0 +0x91DA 0xBAFA # 0 +0x91DB 0xBAFB # 0 +0x91DC 0xBAFD # 0 +0x91DD 0xBAFE # 0 +0x91DE 0xBAFF # 0 +0x91DF 0xBB01 # 0 +0x91E0 0xBB02 # 0 +0x91E1 0xBB03 # 0 +0x91E2 0xBB05 # 0 +0x91E3 0xBB06 # 0 +0x91E4 0xBB07 # 0 +0x91E5 0xBB08 # 0 +0x91E6 0xBB09 # 0 +0x91E7 0xBB0A # 0 +0x91E8 0xBB0B # 0 +0x91E9 0xBB0C # 0 +0x91EA 0xBB0E # 0 +0x91EB 0xBB10 # 0 +0x91EC 0xBB12 # 0 +0x91ED 0xBB13 # 0 +0x91EE 0xBB14 # 0 +0x91EF 0xBB15 # 0 +0x91F0 0xBB16 # 0 +0x91F1 0xBB17 # 0 +0x91F2 0xBB19 # 0 +0x91F3 0xBB1A # 0 +0x91F4 0xBB1B # 0 +0x91F5 0xBB1D # 0 +0x91F6 0xBB1E # 0 +0x91F7 0xBB1F # 0 +0x91F8 0xBB21 # 0 +0x91F9 0xBB22 # 0 +0x91FA 0xBB23 # 0 +0x91FB 0xBB24 # 0 +0x91FC 0xBB25 # 0 +0x91FD 0xBB26 # 0 +0x91FE 0xBB27 # 0 +0x9241 0xBB28 # 0 +0x9242 0xBB2A # 0 +0x9243 0xBB2C # 0 +0x9244 0xBB2D # 0 +0x9245 0xBB2E # 0 +0x9246 0xBB2F # 0 +0x9247 0xBB30 # 0 +0x9248 0xBB31 # 0 +0x9249 0xBB32 # 0 +0x924A 0xBB33 # 0 +0x924B 0xBB37 # 0 +0x924C 0xBB39 # 0 +0x924D 0xBB3A # 0 +0x924E 0xBB3F # 0 +0x924F 0xBB40 # 0 +0x9250 0xBB41 # 0 +0x9251 0xBB42 # 0 +0x9252 0xBB43 # 0 +0x9253 0xBB46 # 0 +0x9254 0xBB48 # 0 +0x9255 0xBB4A # 0 +0x9256 0xBB4B # 0 +0x9257 0xBB4C # 0 +0x9258 0xBB4E # 0 +0x9259 0xBB51 # 0 +0x925A 0xBB52 # 0 +0x9261 0xBB53 # 0 +0x9262 0xBB55 # 0 +0x9263 0xBB56 # 0 +0x9264 0xBB57 # 0 +0x9265 0xBB59 # 0 +0x9266 0xBB5A # 0 +0x9267 0xBB5B # 0 +0x9268 0xBB5C # 0 +0x9269 0xBB5D # 0 +0x926A 0xBB5E # 0 +0x926B 0xBB5F # 0 +0x926C 0xBB60 # 0 +0x926D 0xBB62 # 0 +0x926E 0xBB64 # 0 +0x926F 0xBB65 # 0 +0x9270 0xBB66 # 0 +0x9271 0xBB67 # 0 +0x9272 0xBB68 # 0 +0x9273 0xBB69 # 0 +0x9274 0xBB6A # 0 +0x9275 0xBB6B # 0 +0x9276 0xBB6D # 0 +0x9277 0xBB6E # 0 +0x9278 0xBB6F # 0 +0x9279 0xBB70 # 0 +0x927A 0xBB71 # 0 +0x9281 0xBB72 # 0 +0x9282 0xBB73 # 0 +0x9283 0xBB74 # 0 +0x9284 0xBB75 # 0 +0x9285 0xBB76 # 0 +0x9286 0xBB77 # 0 +0x9287 0xBB78 # 0 +0x9288 0xBB79 # 0 +0x9289 0xBB7A # 0 +0x928A 0xBB7B # 0 +0x928B 0xBB7C # 0 +0x928C 0xBB7D # 0 +0x928D 0xBB7E # 0 +0x928E 0xBB7F # 0 +0x928F 0xBB80 # 0 +0x9290 0xBB81 # 0 +0x9291 0xBB82 # 0 +0x9292 0xBB83 # 0 +0x9293 0xBB84 # 0 +0x9294 0xBB85 # 0 +0x9295 0xBB86 # 0 +0x9296 0xBB87 # 0 +0x9297 0xBB89 # 0 +0x9298 0xBB8A # 0 +0x9299 0xBB8B # 0 +0x929A 0xBB8D # 0 +0x929B 0xBB8E # 0 +0x929C 0xBB8F # 0 +0x929D 0xBB91 # 0 +0x929E 0xBB92 # 0 +0x929F 0xBB93 # 0 +0x92A0 0xBB94 # 0 +0x92A1 0xBB95 # 0 +0x92A2 0xBB96 # 0 +0x92A3 0xBB97 # 0 +0x92A4 0xBB98 # 0 +0x92A5 0xBB99 # 0 +0x92A6 0xBB9A # 0 +0x92A7 0xBB9B # 0 +0x92A8 0xBB9C # 0 +0x92A9 0xBB9D # 0 +0x92AA 0xBB9E # 0 +0x92AB 0xBB9F # 0 +0x92AC 0xBBA0 # 0 +0x92AD 0xBBA1 # 0 +0x92AE 0xBBA2 # 0 +0x92AF 0xBBA3 # 0 +0x92B0 0xBBA5 # 0 +0x92B1 0xBBA6 # 0 +0x92B2 0xBBA7 # 0 +0x92B3 0xBBA9 # 0 +0x92B4 0xBBAA # 0 +0x92B5 0xBBAB # 0 +0x92B6 0xBBAD # 0 +0x92B7 0xBBAE # 0 +0x92B8 0xBBAF # 0 +0x92B9 0xBBB0 # 0 +0x92BA 0xBBB1 # 0 +0x92BB 0xBBB2 # 0 +0x92BC 0xBBB3 # 0 +0x92BD 0xBBB5 # 0 +0x92BE 0xBBB6 # 0 +0x92BF 0xBBB8 # 0 +0x92C0 0xBBB9 # 0 +0x92C1 0xBBBA # 0 +0x92C2 0xBBBB # 0 +0x92C3 0xBBBC # 0 +0x92C4 0xBBBD # 0 +0x92C5 0xBBBE # 0 +0x92C6 0xBBBF # 0 +0x92C7 0xBBC1 # 0 +0x92C8 0xBBC2 # 0 +0x92C9 0xBBC3 # 0 +0x92CA 0xBBC5 # 0 +0x92CB 0xBBC6 # 0 +0x92CC 0xBBC7 # 0 +0x92CD 0xBBC9 # 0 +0x92CE 0xBBCA # 0 +0x92CF 0xBBCB # 0 +0x92D0 0xBBCC # 0 +0x92D1 0xBBCD # 0 +0x92D2 0xBBCE # 0 +0x92D3 0xBBCF # 0 +0x92D4 0xBBD1 # 0 +0x92D5 0xBBD2 # 0 +0x92D6 0xBBD4 # 0 +0x92D7 0xBBD5 # 0 +0x92D8 0xBBD6 # 0 +0x92D9 0xBBD7 # 0 +0x92DA 0xBBD8 # 0 +0x92DB 0xBBD9 # 0 +0x92DC 0xBBDA # 0 +0x92DD 0xBBDB # 0 +0x92DE 0xBBDC # 0 +0x92DF 0xBBDD # 0 +0x92E0 0xBBDE # 0 +0x92E1 0xBBDF # 0 +0x92E2 0xBBE0 # 0 +0x92E3 0xBBE1 # 0 +0x92E4 0xBBE2 # 0 +0x92E5 0xBBE3 # 0 +0x92E6 0xBBE4 # 0 +0x92E7 0xBBE5 # 0 +0x92E8 0xBBE6 # 0 +0x92E9 0xBBE7 # 0 +0x92EA 0xBBE8 # 0 +0x92EB 0xBBE9 # 0 +0x92EC 0xBBEA # 0 +0x92ED 0xBBEB # 0 +0x92EE 0xBBEC # 0 +0x92EF 0xBBED # 0 +0x92F0 0xBBEE # 0 +0x92F1 0xBBEF # 0 +0x92F2 0xBBF0 # 0 +0x92F3 0xBBF1 # 0 +0x92F4 0xBBF2 # 0 +0x92F5 0xBBF3 # 0 +0x92F6 0xBBF4 # 0 +0x92F7 0xBBF5 # 0 +0x92F8 0xBBF6 # 0 +0x92F9 0xBBF7 # 0 +0x92FA 0xBBFA # 0 +0x92FB 0xBBFB # 0 +0x92FC 0xBBFD # 0 +0x92FD 0xBBFE # 0 +0x92FE 0xBC01 # 0 +0x9341 0xBC03 # 0 +0x9342 0xBC04 # 0 +0x9343 0xBC05 # 0 +0x9344 0xBC06 # 0 +0x9345 0xBC07 # 0 +0x9346 0xBC0A # 0 +0x9347 0xBC0E # 0 +0x9348 0xBC10 # 0 +0x9349 0xBC12 # 0 +0x934A 0xBC13 # 0 +0x934B 0xBC19 # 0 +0x934C 0xBC1A # 0 +0x934D 0xBC20 # 0 +0x934E 0xBC21 # 0 +0x934F 0xBC22 # 0 +0x9350 0xBC23 # 0 +0x9351 0xBC26 # 0 +0x9352 0xBC28 # 0 +0x9353 0xBC2A # 0 +0x9354 0xBC2B # 0 +0x9355 0xBC2C # 0 +0x9356 0xBC2E # 0 +0x9357 0xBC2F # 0 +0x9358 0xBC32 # 0 +0x9359 0xBC33 # 0 +0x935A 0xBC35 # 0 +0x9361 0xBC36 # 0 +0x9362 0xBC37 # 0 +0x9363 0xBC39 # 0 +0x9364 0xBC3A # 0 +0x9365 0xBC3B # 0 +0x9366 0xBC3C # 0 +0x9367 0xBC3D # 0 +0x9368 0xBC3E # 0 +0x9369 0xBC3F # 0 +0x936A 0xBC42 # 0 +0x936B 0xBC46 # 0 +0x936C 0xBC47 # 0 +0x936D 0xBC48 # 0 +0x936E 0xBC4A # 0 +0x936F 0xBC4B # 0 +0x9370 0xBC4E # 0 +0x9371 0xBC4F # 0 +0x9372 0xBC51 # 0 +0x9373 0xBC52 # 0 +0x9374 0xBC53 # 0 +0x9375 0xBC54 # 0 +0x9376 0xBC55 # 0 +0x9377 0xBC56 # 0 +0x9378 0xBC57 # 0 +0x9379 0xBC58 # 0 +0x937A 0xBC59 # 0 +0x9381 0xBC5A # 0 +0x9382 0xBC5B # 0 +0x9383 0xBC5C # 0 +0x9384 0xBC5E # 0 +0x9385 0xBC5F # 0 +0x9386 0xBC60 # 0 +0x9387 0xBC61 # 0 +0x9388 0xBC62 # 0 +0x9389 0xBC63 # 0 +0x938A 0xBC64 # 0 +0x938B 0xBC65 # 0 +0x938C 0xBC66 # 0 +0x938D 0xBC67 # 0 +0x938E 0xBC68 # 0 +0x938F 0xBC69 # 0 +0x9390 0xBC6A # 0 +0x9391 0xBC6B # 0 +0x9392 0xBC6C # 0 +0x9393 0xBC6D # 0 +0x9394 0xBC6E # 0 +0x9395 0xBC6F # 0 +0x9396 0xBC70 # 0 +0x9397 0xBC71 # 0 +0x9398 0xBC72 # 0 +0x9399 0xBC73 # 0 +0x939A 0xBC74 # 0 +0x939B 0xBC75 # 0 +0x939C 0xBC76 # 0 +0x939D 0xBC77 # 0 +0x939E 0xBC78 # 0 +0x939F 0xBC79 # 0 +0x93A0 0xBC7A # 0 +0x93A1 0xBC7B # 0 +0x93A2 0xBC7C # 0 +0x93A3 0xBC7D # 0 +0x93A4 0xBC7E # 0 +0x93A5 0xBC7F # 0 +0x93A6 0xBC80 # 0 +0x93A7 0xBC81 # 0 +0x93A8 0xBC82 # 0 +0x93A9 0xBC83 # 0 +0x93AA 0xBC86 # 0 +0x93AB 0xBC87 # 0 +0x93AC 0xBC89 # 0 +0x93AD 0xBC8A # 0 +0x93AE 0xBC8D # 0 +0x93AF 0xBC8F # 0 +0x93B0 0xBC90 # 0 +0x93B1 0xBC91 # 0 +0x93B2 0xBC92 # 0 +0x93B3 0xBC93 # 0 +0x93B4 0xBC96 # 0 +0x93B5 0xBC98 # 0 +0x93B6 0xBC9B # 0 +0x93B7 0xBC9C # 0 +0x93B8 0xBC9D # 0 +0x93B9 0xBC9E # 0 +0x93BA 0xBC9F # 0 +0x93BB 0xBCA2 # 0 +0x93BC 0xBCA3 # 0 +0x93BD 0xBCA5 # 0 +0x93BE 0xBCA6 # 0 +0x93BF 0xBCA9 # 0 +0x93C0 0xBCAA # 0 +0x93C1 0xBCAB # 0 +0x93C2 0xBCAC # 0 +0x93C3 0xBCAD # 0 +0x93C4 0xBCAE # 0 +0x93C5 0xBCAF # 0 +0x93C6 0xBCB2 # 0 +0x93C7 0xBCB6 # 0 +0x93C8 0xBCB7 # 0 +0x93C9 0xBCB8 # 0 +0x93CA 0xBCB9 # 0 +0x93CB 0xBCBA # 0 +0x93CC 0xBCBB # 0 +0x93CD 0xBCBE # 0 +0x93CE 0xBCBF # 0 +0x93CF 0xBCC1 # 0 +0x93D0 0xBCC2 # 0 +0x93D1 0xBCC3 # 0 +0x93D2 0xBCC5 # 0 +0x93D3 0xBCC6 # 0 +0x93D4 0xBCC7 # 0 +0x93D5 0xBCC8 # 0 +0x93D6 0xBCC9 # 0 +0x93D7 0xBCCA # 0 +0x93D8 0xBCCB # 0 +0x93D9 0xBCCC # 0 +0x93DA 0xBCCE # 0 +0x93DB 0xBCD2 # 0 +0x93DC 0xBCD3 # 0 +0x93DD 0xBCD4 # 0 +0x93DE 0xBCD6 # 0 +0x93DF 0xBCD7 # 0 +0x93E0 0xBCD9 # 0 +0x93E1 0xBCDA # 0 +0x93E2 0xBCDB # 0 +0x93E3 0xBCDD # 0 +0x93E4 0xBCDE # 0 +0x93E5 0xBCDF # 0 +0x93E6 0xBCE0 # 0 +0x93E7 0xBCE1 # 0 +0x93E8 0xBCE2 # 0 +0x93E9 0xBCE3 # 0 +0x93EA 0xBCE4 # 0 +0x93EB 0xBCE5 # 0 +0x93EC 0xBCE6 # 0 +0x93ED 0xBCE7 # 0 +0x93EE 0xBCE8 # 0 +0x93EF 0xBCE9 # 0 +0x93F0 0xBCEA # 0 +0x93F1 0xBCEB # 0 +0x93F2 0xBCEC # 0 +0x93F3 0xBCED # 0 +0x93F4 0xBCEE # 0 +0x93F5 0xBCEF # 0 +0x93F6 0xBCF0 # 0 +0x93F7 0xBCF1 # 0 +0x93F8 0xBCF2 # 0 +0x93F9 0xBCF3 # 0 +0x93FA 0xBCF7 # 0 +0x93FB 0xBCF9 # 0 +0x93FC 0xBCFA # 0 +0x93FD 0xBCFB # 0 +0x93FE 0xBCFD # 0 +0x9441 0xBCFE # 0 +0x9442 0xBCFF # 0 +0x9443 0xBD00 # 0 +0x9444 0xBD01 # 0 +0x9445 0xBD02 # 0 +0x9446 0xBD03 # 0 +0x9447 0xBD06 # 0 +0x9448 0xBD08 # 0 +0x9449 0xBD0A # 0 +0x944A 0xBD0B # 0 +0x944B 0xBD0C # 0 +0x944C 0xBD0D # 0 +0x944D 0xBD0E # 0 +0x944E 0xBD0F # 0 +0x944F 0xBD11 # 0 +0x9450 0xBD12 # 0 +0x9451 0xBD13 # 0 +0x9452 0xBD15 # 0 +0x9453 0xBD16 # 0 +0x9454 0xBD17 # 0 +0x9455 0xBD18 # 0 +0x9456 0xBD19 # 0 +0x9457 0xBD1A # 0 +0x9458 0xBD1B # 0 +0x9459 0xBD1C # 0 +0x945A 0xBD1D # 0 +0x9461 0xBD1E # 0 +0x9462 0xBD1F # 0 +0x9463 0xBD20 # 0 +0x9464 0xBD21 # 0 +0x9465 0xBD22 # 0 +0x9466 0xBD23 # 0 +0x9467 0xBD25 # 0 +0x9468 0xBD26 # 0 +0x9469 0xBD27 # 0 +0x946A 0xBD28 # 0 +0x946B 0xBD29 # 0 +0x946C 0xBD2A # 0 +0x946D 0xBD2B # 0 +0x946E 0xBD2D # 0 +0x946F 0xBD2E # 0 +0x9470 0xBD2F # 0 +0x9471 0xBD30 # 0 +0x9472 0xBD31 # 0 +0x9473 0xBD32 # 0 +0x9474 0xBD33 # 0 +0x9475 0xBD34 # 0 +0x9476 0xBD35 # 0 +0x9477 0xBD36 # 0 +0x9478 0xBD37 # 0 +0x9479 0xBD38 # 0 +0x947A 0xBD39 # 0 +0x9481 0xBD3A # 0 +0x9482 0xBD3B # 0 +0x9483 0xBD3C # 0 +0x9484 0xBD3D # 0 +0x9485 0xBD3E # 0 +0x9486 0xBD3F # 0 +0x9487 0xBD41 # 0 +0x9488 0xBD42 # 0 +0x9489 0xBD43 # 0 +0x948A 0xBD44 # 0 +0x948B 0xBD45 # 0 +0x948C 0xBD46 # 0 +0x948D 0xBD47 # 0 +0x948E 0xBD4A # 0 +0x948F 0xBD4B # 0 +0x9490 0xBD4D # 0 +0x9491 0xBD4E # 0 +0x9492 0xBD4F # 0 +0x9493 0xBD51 # 0 +0x9494 0xBD52 # 0 +0x9495 0xBD53 # 0 +0x9496 0xBD54 # 0 +0x9497 0xBD55 # 0 +0x9498 0xBD56 # 0 +0x9499 0xBD57 # 0 +0x949A 0xBD5A # 0 +0x949B 0xBD5B # 0 +0x949C 0xBD5C # 0 +0x949D 0xBD5D # 0 +0x949E 0xBD5E # 0 +0x949F 0xBD5F # 0 +0x94A0 0xBD60 # 0 +0x94A1 0xBD61 # 0 +0x94A2 0xBD62 # 0 +0x94A3 0xBD63 # 0 +0x94A4 0xBD65 # 0 +0x94A5 0xBD66 # 0 +0x94A6 0xBD67 # 0 +0x94A7 0xBD69 # 0 +0x94A8 0xBD6A # 0 +0x94A9 0xBD6B # 0 +0x94AA 0xBD6C # 0 +0x94AB 0xBD6D # 0 +0x94AC 0xBD6E # 0 +0x94AD 0xBD6F # 0 +0x94AE 0xBD70 # 0 +0x94AF 0xBD71 # 0 +0x94B0 0xBD72 # 0 +0x94B1 0xBD73 # 0 +0x94B2 0xBD74 # 0 +0x94B3 0xBD75 # 0 +0x94B4 0xBD76 # 0 +0x94B5 0xBD77 # 0 +0x94B6 0xBD78 # 0 +0x94B7 0xBD79 # 0 +0x94B8 0xBD7A # 0 +0x94B9 0xBD7B # 0 +0x94BA 0xBD7C # 0 +0x94BB 0xBD7D # 0 +0x94BC 0xBD7E # 0 +0x94BD 0xBD7F # 0 +0x94BE 0xBD82 # 0 +0x94BF 0xBD83 # 0 +0x94C0 0xBD85 # 0 +0x94C1 0xBD86 # 0 +0x94C2 0xBD8B # 0 +0x94C3 0xBD8C # 0 +0x94C4 0xBD8D # 0 +0x94C5 0xBD8E # 0 +0x94C6 0xBD8F # 0 +0x94C7 0xBD92 # 0 +0x94C8 0xBD94 # 0 +0x94C9 0xBD96 # 0 +0x94CA 0xBD97 # 0 +0x94CB 0xBD98 # 0 +0x94CC 0xBD9B # 0 +0x94CD 0xBD9D # 0 +0x94CE 0xBD9E # 0 +0x94CF 0xBD9F # 0 +0x94D0 0xBDA0 # 0 +0x94D1 0xBDA1 # 0 +0x94D2 0xBDA2 # 0 +0x94D3 0xBDA3 # 0 +0x94D4 0xBDA5 # 0 +0x94D5 0xBDA6 # 0 +0x94D6 0xBDA7 # 0 +0x94D7 0xBDA8 # 0 +0x94D8 0xBDA9 # 0 +0x94D9 0xBDAA # 0 +0x94DA 0xBDAB # 0 +0x94DB 0xBDAC # 0 +0x94DC 0xBDAD # 0 +0x94DD 0xBDAE # 0 +0x94DE 0xBDAF # 0 +0x94DF 0xBDB1 # 0 +0x94E0 0xBDB2 # 0 +0x94E1 0xBDB3 # 0 +0x94E2 0xBDB4 # 0 +0x94E3 0xBDB5 # 0 +0x94E4 0xBDB6 # 0 +0x94E5 0xBDB7 # 0 +0x94E6 0xBDB9 # 0 +0x94E7 0xBDBA # 0 +0x94E8 0xBDBB # 0 +0x94E9 0xBDBC # 0 +0x94EA 0xBDBD # 0 +0x94EB 0xBDBE # 0 +0x94EC 0xBDBF # 0 +0x94ED 0xBDC0 # 0 +0x94EE 0xBDC1 # 0 +0x94EF 0xBDC2 # 0 +0x94F0 0xBDC3 # 0 +0x94F1 0xBDC4 # 0 +0x94F2 0xBDC5 # 0 +0x94F3 0xBDC6 # 0 +0x94F4 0xBDC7 # 0 +0x94F5 0xBDC8 # 0 +0x94F6 0xBDC9 # 0 +0x94F7 0xBDCA # 0 +0x94F8 0xBDCB # 0 +0x94F9 0xBDCC # 0 +0x94FA 0xBDCD # 0 +0x94FB 0xBDCE # 0 +0x94FC 0xBDCF # 0 +0x94FD 0xBDD0 # 0 +0x94FE 0xBDD1 # 0 +0x9541 0xBDD2 # 0 +0x9542 0xBDD3 # 0 +0x9543 0xBDD6 # 0 +0x9544 0xBDD7 # 0 +0x9545 0xBDD9 # 0 +0x9546 0xBDDA # 0 +0x9547 0xBDDB # 0 +0x9548 0xBDDD # 0 +0x9549 0xBDDE # 0 +0x954A 0xBDDF # 0 +0x954B 0xBDE0 # 0 +0x954C 0xBDE1 # 0 +0x954D 0xBDE2 # 0 +0x954E 0xBDE3 # 0 +0x954F 0xBDE4 # 0 +0x9550 0xBDE5 # 0 +0x9551 0xBDE6 # 0 +0x9552 0xBDE7 # 0 +0x9553 0xBDE8 # 0 +0x9554 0xBDEA # 0 +0x9555 0xBDEB # 0 +0x9556 0xBDEC # 0 +0x9557 0xBDED # 0 +0x9558 0xBDEE # 0 +0x9559 0xBDEF # 0 +0x955A 0xBDF1 # 0 +0x9561 0xBDF2 # 0 +0x9562 0xBDF3 # 0 +0x9563 0xBDF5 # 0 +0x9564 0xBDF6 # 0 +0x9565 0xBDF7 # 0 +0x9566 0xBDF9 # 0 +0x9567 0xBDFA # 0 +0x9568 0xBDFB # 0 +0x9569 0xBDFC # 0 +0x956A 0xBDFD # 0 +0x956B 0xBDFE # 0 +0x956C 0xBDFF # 0 +0x956D 0xBE01 # 0 +0x956E 0xBE02 # 0 +0x956F 0xBE04 # 0 +0x9570 0xBE06 # 0 +0x9571 0xBE07 # 0 +0x9572 0xBE08 # 0 +0x9573 0xBE09 # 0 +0x9574 0xBE0A # 0 +0x9575 0xBE0B # 0 +0x9576 0xBE0E # 0 +0x9577 0xBE0F # 0 +0x9578 0xBE11 # 0 +0x9579 0xBE12 # 0 +0x957A 0xBE13 # 0 +0x9581 0xBE15 # 0 +0x9582 0xBE16 # 0 +0x9583 0xBE17 # 0 +0x9584 0xBE18 # 0 +0x9585 0xBE19 # 0 +0x9586 0xBE1A # 0 +0x9587 0xBE1B # 0 +0x9588 0xBE1E # 0 +0x9589 0xBE20 # 0 +0x958A 0xBE21 # 0 +0x958B 0xBE22 # 0 +0x958C 0xBE23 # 0 +0x958D 0xBE24 # 0 +0x958E 0xBE25 # 0 +0x958F 0xBE26 # 0 +0x9590 0xBE27 # 0 +0x9591 0xBE28 # 0 +0x9592 0xBE29 # 0 +0x9593 0xBE2A # 0 +0x9594 0xBE2B # 0 +0x9595 0xBE2C # 0 +0x9596 0xBE2D # 0 +0x9597 0xBE2E # 0 +0x9598 0xBE2F # 0 +0x9599 0xBE30 # 0 +0x959A 0xBE31 # 0 +0x959B 0xBE32 # 0 +0x959C 0xBE33 # 0 +0x959D 0xBE34 # 0 +0x959E 0xBE35 # 0 +0x959F 0xBE36 # 0 +0x95A0 0xBE37 # 0 +0x95A1 0xBE38 # 0 +0x95A2 0xBE39 # 0 +0x95A3 0xBE3A # 0 +0x95A4 0xBE3B # 0 +0x95A5 0xBE3C # 0 +0x95A6 0xBE3D # 0 +0x95A7 0xBE3E # 0 +0x95A8 0xBE3F # 0 +0x95A9 0xBE40 # 0 +0x95AA 0xBE41 # 0 +0x95AB 0xBE42 # 0 +0x95AC 0xBE43 # 0 +0x95AD 0xBE46 # 0 +0x95AE 0xBE47 # 0 +0x95AF 0xBE49 # 0 +0x95B0 0xBE4A # 0 +0x95B1 0xBE4B # 0 +0x95B2 0xBE4D # 0 +0x95B3 0xBE4F # 0 +0x95B4 0xBE50 # 0 +0x95B5 0xBE51 # 0 +0x95B6 0xBE52 # 0 +0x95B7 0xBE53 # 0 +0x95B8 0xBE56 # 0 +0x95B9 0xBE58 # 0 +0x95BA 0xBE5C # 0 +0x95BB 0xBE5D # 0 +0x95BC 0xBE5E # 0 +0x95BD 0xBE5F # 0 +0x95BE 0xBE62 # 0 +0x95BF 0xBE63 # 0 +0x95C0 0xBE65 # 0 +0x95C1 0xBE66 # 0 +0x95C2 0xBE67 # 0 +0x95C3 0xBE69 # 0 +0x95C4 0xBE6B # 0 +0x95C5 0xBE6C # 0 +0x95C6 0xBE6D # 0 +0x95C7 0xBE6E # 0 +0x95C8 0xBE6F # 0 +0x95C9 0xBE72 # 0 +0x95CA 0xBE76 # 0 +0x95CB 0xBE77 # 0 +0x95CC 0xBE78 # 0 +0x95CD 0xBE79 # 0 +0x95CE 0xBE7A # 0 +0x95CF 0xBE7E # 0 +0x95D0 0xBE7F # 0 +0x95D1 0xBE81 # 0 +0x95D2 0xBE82 # 0 +0x95D3 0xBE83 # 0 +0x95D4 0xBE85 # 0 +0x95D5 0xBE86 # 0 +0x95D6 0xBE87 # 0 +0x95D7 0xBE88 # 0 +0x95D8 0xBE89 # 0 +0x95D9 0xBE8A # 0 +0x95DA 0xBE8B # 0 +0x95DB 0xBE8E # 0 +0x95DC 0xBE92 # 0 +0x95DD 0xBE93 # 0 +0x95DE 0xBE94 # 0 +0x95DF 0xBE95 # 0 +0x95E0 0xBE96 # 0 +0x95E1 0xBE97 # 0 +0x95E2 0xBE9A # 0 +0x95E3 0xBE9B # 0 +0x95E4 0xBE9C # 0 +0x95E5 0xBE9D # 0 +0x95E6 0xBE9E # 0 +0x95E7 0xBE9F # 0 +0x95E8 0xBEA0 # 0 +0x95E9 0xBEA1 # 0 +0x95EA 0xBEA2 # 0 +0x95EB 0xBEA3 # 0 +0x95EC 0xBEA4 # 0 +0x95ED 0xBEA5 # 0 +0x95EE 0xBEA6 # 0 +0x95EF 0xBEA7 # 0 +0x95F0 0xBEA9 # 0 +0x95F1 0xBEAA # 0 +0x95F2 0xBEAB # 0 +0x95F3 0xBEAC # 0 +0x95F4 0xBEAD # 0 +0x95F5 0xBEAE # 0 +0x95F6 0xBEAF # 0 +0x95F7 0xBEB0 # 0 +0x95F8 0xBEB1 # 0 +0x95F9 0xBEB2 # 0 +0x95FA 0xBEB3 # 0 +0x95FB 0xBEB4 # 0 +0x95FC 0xBEB5 # 0 +0x95FD 0xBEB6 # 0 +0x95FE 0xBEB7 # 0 +0x9641 0xBEB8 # 0 +0x9642 0xBEB9 # 0 +0x9643 0xBEBA # 0 +0x9644 0xBEBB # 0 +0x9645 0xBEBC # 0 +0x9646 0xBEBD # 0 +0x9647 0xBEBE # 0 +0x9648 0xBEBF # 0 +0x9649 0xBEC0 # 0 +0x964A 0xBEC1 # 0 +0x964B 0xBEC2 # 0 +0x964C 0xBEC3 # 0 +0x964D 0xBEC4 # 0 +0x964E 0xBEC5 # 0 +0x964F 0xBEC6 # 0 +0x9650 0xBEC7 # 0 +0x9651 0xBEC8 # 0 +0x9652 0xBEC9 # 0 +0x9653 0xBECA # 0 +0x9654 0xBECB # 0 +0x9655 0xBECC # 0 +0x9656 0xBECD # 0 +0x9657 0xBECE # 0 +0x9658 0xBECF # 0 +0x9659 0xBED2 # 0 +0x965A 0xBED3 # 0 +0x9661 0xBED5 # 0 +0x9662 0xBED6 # 0 +0x9663 0xBED9 # 0 +0x9664 0xBEDA # 0 +0x9665 0xBEDB # 0 +0x9666 0xBEDC # 0 +0x9667 0xBEDD # 0 +0x9668 0xBEDE # 0 +0x9669 0xBEDF # 0 +0x966A 0xBEE1 # 0 +0x966B 0xBEE2 # 0 +0x966C 0xBEE6 # 0 +0x966D 0xBEE7 # 0 +0x966E 0xBEE8 # 0 +0x966F 0xBEE9 # 0 +0x9670 0xBEEA # 0 +0x9671 0xBEEB # 0 +0x9672 0xBEED # 0 +0x9673 0xBEEE # 0 +0x9674 0xBEEF # 0 +0x9675 0xBEF0 # 0 +0x9676 0xBEF1 # 0 +0x9677 0xBEF2 # 0 +0x9678 0xBEF3 # 0 +0x9679 0xBEF4 # 0 +0x967A 0xBEF5 # 0 +0x9681 0xBEF6 # 0 +0x9682 0xBEF7 # 0 +0x9683 0xBEF8 # 0 +0x9684 0xBEF9 # 0 +0x9685 0xBEFA # 0 +0x9686 0xBEFB # 0 +0x9687 0xBEFC # 0 +0x9688 0xBEFD # 0 +0x9689 0xBEFE # 0 +0x968A 0xBEFF # 0 +0x968B 0xBF00 # 0 +0x968C 0xBF02 # 0 +0x968D 0xBF03 # 0 +0x968E 0xBF04 # 0 +0x968F 0xBF05 # 0 +0x9690 0xBF06 # 0 +0x9691 0xBF07 # 0 +0x9692 0xBF0A # 0 +0x9693 0xBF0B # 0 +0x9694 0xBF0C # 0 +0x9695 0xBF0D # 0 +0x9696 0xBF0E # 0 +0x9697 0xBF0F # 0 +0x9698 0xBF10 # 0 +0x9699 0xBF11 # 0 +0x969A 0xBF12 # 0 +0x969B 0xBF13 # 0 +0x969C 0xBF14 # 0 +0x969D 0xBF15 # 0 +0x969E 0xBF16 # 0 +0x969F 0xBF17 # 0 +0x96A0 0xBF1A # 0 +0x96A1 0xBF1E # 0 +0x96A2 0xBF1F # 0 +0x96A3 0xBF20 # 0 +0x96A4 0xBF21 # 0 +0x96A5 0xBF22 # 0 +0x96A6 0xBF23 # 0 +0x96A7 0xBF24 # 0 +0x96A8 0xBF25 # 0 +0x96A9 0xBF26 # 0 +0x96AA 0xBF27 # 0 +0x96AB 0xBF28 # 0 +0x96AC 0xBF29 # 0 +0x96AD 0xBF2A # 0 +0x96AE 0xBF2B # 0 +0x96AF 0xBF2C # 0 +0x96B0 0xBF2D # 0 +0x96B1 0xBF2E # 0 +0x96B2 0xBF2F # 0 +0x96B3 0xBF30 # 0 +0x96B4 0xBF31 # 0 +0x96B5 0xBF32 # 0 +0x96B6 0xBF33 # 0 +0x96B7 0xBF34 # 0 +0x96B8 0xBF35 # 0 +0x96B9 0xBF36 # 0 +0x96BA 0xBF37 # 0 +0x96BB 0xBF38 # 0 +0x96BC 0xBF39 # 0 +0x96BD 0xBF3A # 0 +0x96BE 0xBF3B # 0 +0x96BF 0xBF3C # 0 +0x96C0 0xBF3D # 0 +0x96C1 0xBF3E # 0 +0x96C2 0xBF3F # 0 +0x96C3 0xBF42 # 0 +0x96C4 0xBF43 # 0 +0x96C5 0xBF45 # 0 +0x96C6 0xBF46 # 0 +0x96C7 0xBF47 # 0 +0x96C8 0xBF49 # 0 +0x96C9 0xBF4A # 0 +0x96CA 0xBF4B # 0 +0x96CB 0xBF4C # 0 +0x96CC 0xBF4D # 0 +0x96CD 0xBF4E # 0 +0x96CE 0xBF4F # 0 +0x96CF 0xBF52 # 0 +0x96D0 0xBF53 # 0 +0x96D1 0xBF54 # 0 +0x96D2 0xBF56 # 0 +0x96D3 0xBF57 # 0 +0x96D4 0xBF58 # 0 +0x96D5 0xBF59 # 0 +0x96D6 0xBF5A # 0 +0x96D7 0xBF5B # 0 +0x96D8 0xBF5C # 0 +0x96D9 0xBF5D # 0 +0x96DA 0xBF5E # 0 +0x96DB 0xBF5F # 0 +0x96DC 0xBF60 # 0 +0x96DD 0xBF61 # 0 +0x96DE 0xBF62 # 0 +0x96DF 0xBF63 # 0 +0x96E0 0xBF64 # 0 +0x96E1 0xBF65 # 0 +0x96E2 0xBF66 # 0 +0x96E3 0xBF67 # 0 +0x96E4 0xBF68 # 0 +0x96E5 0xBF69 # 0 +0x96E6 0xBF6A # 0 +0x96E7 0xBF6B # 0 +0x96E8 0xBF6C # 0 +0x96E9 0xBF6D # 0 +0x96EA 0xBF6E # 0 +0x96EB 0xBF6F # 0 +0x96EC 0xBF70 # 0 +0x96ED 0xBF71 # 0 +0x96EE 0xBF72 # 0 +0x96EF 0xBF73 # 0 +0x96F0 0xBF74 # 0 +0x96F1 0xBF75 # 0 +0x96F2 0xBF76 # 0 +0x96F3 0xBF77 # 0 +0x96F4 0xBF78 # 0 +0x96F5 0xBF79 # 0 +0x96F6 0xBF7A # 0 +0x96F7 0xBF7B # 0 +0x96F8 0xBF7C # 0 +0x96F9 0xBF7D # 0 +0x96FA 0xBF7E # 0 +0x96FB 0xBF7F # 0 +0x96FC 0xBF80 # 0 +0x96FD 0xBF81 # 0 +0x96FE 0xBF82 # 0 +0x9741 0xBF83 # 0 +0x9742 0xBF84 # 0 +0x9743 0xBF85 # 0 +0x9744 0xBF86 # 0 +0x9745 0xBF87 # 0 +0x9746 0xBF88 # 0 +0x9747 0xBF89 # 0 +0x9748 0xBF8A # 0 +0x9749 0xBF8B # 0 +0x974A 0xBF8C # 0 +0x974B 0xBF8D # 0 +0x974C 0xBF8E # 0 +0x974D 0xBF8F # 0 +0x974E 0xBF90 # 0 +0x974F 0xBF91 # 0 +0x9750 0xBF92 # 0 +0x9751 0xBF93 # 0 +0x9752 0xBF95 # 0 +0x9753 0xBF96 # 0 +0x9754 0xBF97 # 0 +0x9755 0xBF98 # 0 +0x9756 0xBF99 # 0 +0x9757 0xBF9A # 0 +0x9758 0xBF9B # 0 +0x9759 0xBF9C # 0 +0x975A 0xBF9D # 0 +0x9761 0xBF9E # 0 +0x9762 0xBF9F # 0 +0x9763 0xBFA0 # 0 +0x9764 0xBFA1 # 0 +0x9765 0xBFA2 # 0 +0x9766 0xBFA3 # 0 +0x9767 0xBFA4 # 0 +0x9768 0xBFA5 # 0 +0x9769 0xBFA6 # 0 +0x976A 0xBFA7 # 0 +0x976B 0xBFA8 # 0 +0x976C 0xBFA9 # 0 +0x976D 0xBFAA # 0 +0x976E 0xBFAB # 0 +0x976F 0xBFAC # 0 +0x9770 0xBFAD # 0 +0x9771 0xBFAE # 0 +0x9772 0xBFAF # 0 +0x9773 0xBFB1 # 0 +0x9774 0xBFB2 # 0 +0x9775 0xBFB3 # 0 +0x9776 0xBFB4 # 0 +0x9777 0xBFB5 # 0 +0x9778 0xBFB6 # 0 +0x9779 0xBFB7 # 0 +0x977A 0xBFB8 # 0 +0x9781 0xBFB9 # 0 +0x9782 0xBFBA # 0 +0x9783 0xBFBB # 0 +0x9784 0xBFBC # 0 +0x9785 0xBFBD # 0 +0x9786 0xBFBE # 0 +0x9787 0xBFBF # 0 +0x9788 0xBFC0 # 0 +0x9789 0xBFC1 # 0 +0x978A 0xBFC2 # 0 +0x978B 0xBFC3 # 0 +0x978C 0xBFC4 # 0 +0x978D 0xBFC6 # 0 +0x978E 0xBFC7 # 0 +0x978F 0xBFC8 # 0 +0x9790 0xBFC9 # 0 +0x9791 0xBFCA # 0 +0x9792 0xBFCB # 0 +0x9793 0xBFCE # 0 +0x9794 0xBFCF # 0 +0x9795 0xBFD1 # 0 +0x9796 0xBFD2 # 0 +0x9797 0xBFD3 # 0 +0x9798 0xBFD5 # 0 +0x9799 0xBFD6 # 0 +0x979A 0xBFD7 # 0 +0x979B 0xBFD8 # 0 +0x979C 0xBFD9 # 0 +0x979D 0xBFDA # 0 +0x979E 0xBFDB # 0 +0x979F 0xBFDD # 0 +0x97A0 0xBFDE # 0 +0x97A1 0xBFE0 # 0 +0x97A2 0xBFE2 # 0 +0x97A3 0xBFE3 # 0 +0x97A4 0xBFE4 # 0 +0x97A5 0xBFE5 # 0 +0x97A6 0xBFE6 # 0 +0x97A7 0xBFE7 # 0 +0x97A8 0xBFE8 # 0 +0x97A9 0xBFE9 # 0 +0x97AA 0xBFEA # 0 +0x97AB 0xBFEB # 0 +0x97AC 0xBFEC # 0 +0x97AD 0xBFED # 0 +0x97AE 0xBFEE # 0 +0x97AF 0xBFEF # 0 +0x97B0 0xBFF0 # 0 +0x97B1 0xBFF1 # 0 +0x97B2 0xBFF2 # 0 +0x97B3 0xBFF3 # 0 +0x97B4 0xBFF4 # 0 +0x97B5 0xBFF5 # 0 +0x97B6 0xBFF6 # 0 +0x97B7 0xBFF7 # 0 +0x97B8 0xBFF8 # 0 +0x97B9 0xBFF9 # 0 +0x97BA 0xBFFA # 0 +0x97BB 0xBFFB # 0 +0x97BC 0xBFFC # 0 +0x97BD 0xBFFD # 0 +0x97BE 0xBFFE # 0 +0x97BF 0xBFFF # 0 +0x97C0 0xC000 # 0 +0x97C1 0xC001 # 0 +0x97C2 0xC002 # 0 +0x97C3 0xC003 # 0 +0x97C4 0xC004 # 0 +0x97C5 0xC005 # 0 +0x97C6 0xC006 # 0 +0x97C7 0xC007 # 0 +0x97C8 0xC008 # 0 +0x97C9 0xC009 # 0 +0x97CA 0xC00A # 0 +0x97CB 0xC00B # 0 +0x97CC 0xC00C # 0 +0x97CD 0xC00D # 0 +0x97CE 0xC00E # 0 +0x97CF 0xC00F # 0 +0x97D0 0xC010 # 0 +0x97D1 0xC011 # 0 +0x97D2 0xC012 # 0 +0x97D3 0xC013 # 0 +0x97D4 0xC014 # 0 +0x97D5 0xC015 # 0 +0x97D6 0xC016 # 0 +0x97D7 0xC017 # 0 +0x97D8 0xC018 # 0 +0x97D9 0xC019 # 0 +0x97DA 0xC01A # 0 +0x97DB 0xC01B # 0 +0x97DC 0xC01C # 0 +0x97DD 0xC01D # 0 +0x97DE 0xC01E # 0 +0x97DF 0xC01F # 0 +0x97E0 0xC020 # 0 +0x97E1 0xC021 # 0 +0x97E2 0xC022 # 0 +0x97E3 0xC023 # 0 +0x97E4 0xC024 # 0 +0x97E5 0xC025 # 0 +0x97E6 0xC026 # 0 +0x97E7 0xC027 # 0 +0x97E8 0xC028 # 0 +0x97E9 0xC029 # 0 +0x97EA 0xC02A # 0 +0x97EB 0xC02B # 0 +0x97EC 0xC02C # 0 +0x97ED 0xC02D # 0 +0x97EE 0xC02E # 0 +0x97EF 0xC02F # 0 +0x97F0 0xC030 # 0 +0x97F1 0xC031 # 0 +0x97F2 0xC032 # 0 +0x97F3 0xC033 # 0 +0x97F4 0xC034 # 0 +0x97F5 0xC035 # 0 +0x97F6 0xC036 # 0 +0x97F7 0xC037 # 0 +0x97F8 0xC038 # 0 +0x97F9 0xC039 # 0 +0x97FA 0xC03A # 0 +0x97FB 0xC03B # 0 +0x97FC 0xC03D # 0 +0x97FD 0xC03E # 0 +0x97FE 0xC03F # 0 +0x9841 0xC040 # 0 +0x9842 0xC041 # 0 +0x9843 0xC042 # 0 +0x9844 0xC043 # 0 +0x9845 0xC044 # 0 +0x9846 0xC045 # 0 +0x9847 0xC046 # 0 +0x9848 0xC047 # 0 +0x9849 0xC048 # 0 +0x984A 0xC049 # 0 +0x984B 0xC04A # 0 +0x984C 0xC04B # 0 +0x984D 0xC04C # 0 +0x984E 0xC04D # 0 +0x984F 0xC04E # 0 +0x9850 0xC04F # 0 +0x9851 0xC050 # 0 +0x9852 0xC052 # 0 +0x9853 0xC053 # 0 +0x9854 0xC054 # 0 +0x9855 0xC055 # 0 +0x9856 0xC056 # 0 +0x9857 0xC057 # 0 +0x9858 0xC059 # 0 +0x9859 0xC05A # 0 +0x985A 0xC05B # 0 +0x9861 0xC05D # 0 +0x9862 0xC05E # 0 +0x9863 0xC05F # 0 +0x9864 0xC061 # 0 +0x9865 0xC062 # 0 +0x9866 0xC063 # 0 +0x9867 0xC064 # 0 +0x9868 0xC065 # 0 +0x9869 0xC066 # 0 +0x986A 0xC067 # 0 +0x986B 0xC06A # 0 +0x986C 0xC06B # 0 +0x986D 0xC06C # 0 +0x986E 0xC06D # 0 +0x986F 0xC06E # 0 +0x9870 0xC06F # 0 +0x9871 0xC070 # 0 +0x9872 0xC071 # 0 +0x9873 0xC072 # 0 +0x9874 0xC073 # 0 +0x9875 0xC074 # 0 +0x9876 0xC075 # 0 +0x9877 0xC076 # 0 +0x9878 0xC077 # 0 +0x9879 0xC078 # 0 +0x987A 0xC079 # 0 +0x9881 0xC07A # 0 +0x9882 0xC07B # 0 +0x9883 0xC07C # 0 +0x9884 0xC07D # 0 +0x9885 0xC07E # 0 +0x9886 0xC07F # 0 +0x9887 0xC080 # 0 +0x9888 0xC081 # 0 +0x9889 0xC082 # 0 +0x988A 0xC083 # 0 +0x988B 0xC084 # 0 +0x988C 0xC085 # 0 +0x988D 0xC086 # 0 +0x988E 0xC087 # 0 +0x988F 0xC088 # 0 +0x9890 0xC089 # 0 +0x9891 0xC08A # 0 +0x9892 0xC08B # 0 +0x9893 0xC08C # 0 +0x9894 0xC08D # 0 +0x9895 0xC08E # 0 +0x9896 0xC08F # 0 +0x9897 0xC092 # 0 +0x9898 0xC093 # 0 +0x9899 0xC095 # 0 +0x989A 0xC096 # 0 +0x989B 0xC097 # 0 +0x989C 0xC099 # 0 +0x989D 0xC09A # 0 +0x989E 0xC09B # 0 +0x989F 0xC09C # 0 +0x98A0 0xC09D # 0 +0x98A1 0xC09E # 0 +0x98A2 0xC09F # 0 +0x98A3 0xC0A2 # 0 +0x98A4 0xC0A4 # 0 +0x98A5 0xC0A6 # 0 +0x98A6 0xC0A7 # 0 +0x98A7 0xC0A8 # 0 +0x98A8 0xC0A9 # 0 +0x98A9 0xC0AA # 0 +0x98AA 0xC0AB # 0 +0x98AB 0xC0AE # 0 +0x98AC 0xC0B1 # 0 +0x98AD 0xC0B2 # 0 +0x98AE 0xC0B7 # 0 +0x98AF 0xC0B8 # 0 +0x98B0 0xC0B9 # 0 +0x98B1 0xC0BA # 0 +0x98B2 0xC0BB # 0 +0x98B3 0xC0BE # 0 +0x98B4 0xC0C2 # 0 +0x98B5 0xC0C3 # 0 +0x98B6 0xC0C4 # 0 +0x98B7 0xC0C6 # 0 +0x98B8 0xC0C7 # 0 +0x98B9 0xC0CA # 0 +0x98BA 0xC0CB # 0 +0x98BB 0xC0CD # 0 +0x98BC 0xC0CE # 0 +0x98BD 0xC0CF # 0 +0x98BE 0xC0D1 # 0 +0x98BF 0xC0D2 # 0 +0x98C0 0xC0D3 # 0 +0x98C1 0xC0D4 # 0 +0x98C2 0xC0D5 # 0 +0x98C3 0xC0D6 # 0 +0x98C4 0xC0D7 # 0 +0x98C5 0xC0DA # 0 +0x98C6 0xC0DE # 0 +0x98C7 0xC0DF # 0 +0x98C8 0xC0E0 # 0 +0x98C9 0xC0E1 # 0 +0x98CA 0xC0E2 # 0 +0x98CB 0xC0E3 # 0 +0x98CC 0xC0E6 # 0 +0x98CD 0xC0E7 # 0 +0x98CE 0xC0E9 # 0 +0x98CF 0xC0EA # 0 +0x98D0 0xC0EB # 0 +0x98D1 0xC0ED # 0 +0x98D2 0xC0EE # 0 +0x98D3 0xC0EF # 0 +0x98D4 0xC0F0 # 0 +0x98D5 0xC0F1 # 0 +0x98D6 0xC0F2 # 0 +0x98D7 0xC0F3 # 0 +0x98D8 0xC0F6 # 0 +0x98D9 0xC0F8 # 0 +0x98DA 0xC0FA # 0 +0x98DB 0xC0FB # 0 +0x98DC 0xC0FC # 0 +0x98DD 0xC0FD # 0 +0x98DE 0xC0FE # 0 +0x98DF 0xC0FF # 0 +0x98E0 0xC101 # 0 +0x98E1 0xC102 # 0 +0x98E2 0xC103 # 0 +0x98E3 0xC105 # 0 +0x98E4 0xC106 # 0 +0x98E5 0xC107 # 0 +0x98E6 0xC109 # 0 +0x98E7 0xC10A # 0 +0x98E8 0xC10B # 0 +0x98E9 0xC10C # 0 +0x98EA 0xC10D # 0 +0x98EB 0xC10E # 0 +0x98EC 0xC10F # 0 +0x98ED 0xC111 # 0 +0x98EE 0xC112 # 0 +0x98EF 0xC113 # 0 +0x98F0 0xC114 # 0 +0x98F1 0xC116 # 0 +0x98F2 0xC117 # 0 +0x98F3 0xC118 # 0 +0x98F4 0xC119 # 0 +0x98F5 0xC11A # 0 +0x98F6 0xC11B # 0 +0x98F7 0xC121 # 0 +0x98F8 0xC122 # 0 +0x98F9 0xC125 # 0 +0x98FA 0xC128 # 0 +0x98FB 0xC129 # 0 +0x98FC 0xC12A # 0 +0x98FD 0xC12B # 0 +0x98FE 0xC12E # 0 +0x9941 0xC132 # 0 +0x9942 0xC133 # 0 +0x9943 0xC134 # 0 +0x9944 0xC135 # 0 +0x9945 0xC137 # 0 +0x9946 0xC13A # 0 +0x9947 0xC13B # 0 +0x9948 0xC13D # 0 +0x9949 0xC13E # 0 +0x994A 0xC13F # 0 +0x994B 0xC141 # 0 +0x994C 0xC142 # 0 +0x994D 0xC143 # 0 +0x994E 0xC144 # 0 +0x994F 0xC145 # 0 +0x9950 0xC146 # 0 +0x9951 0xC147 # 0 +0x9952 0xC14A # 0 +0x9953 0xC14E # 0 +0x9954 0xC14F # 0 +0x9955 0xC150 # 0 +0x9956 0xC151 # 0 +0x9957 0xC152 # 0 +0x9958 0xC153 # 0 +0x9959 0xC156 # 0 +0x995A 0xC157 # 0 +0x9961 0xC159 # 0 +0x9962 0xC15A # 0 +0x9963 0xC15B # 0 +0x9964 0xC15D # 0 +0x9965 0xC15E # 0 +0x9966 0xC15F # 0 +0x9967 0xC160 # 0 +0x9968 0xC161 # 0 +0x9969 0xC162 # 0 +0x996A 0xC163 # 0 +0x996B 0xC166 # 0 +0x996C 0xC16A # 0 +0x996D 0xC16B # 0 +0x996E 0xC16C # 0 +0x996F 0xC16D # 0 +0x9970 0xC16E # 0 +0x9971 0xC16F # 0 +0x9972 0xC171 # 0 +0x9973 0xC172 # 0 +0x9974 0xC173 # 0 +0x9975 0xC175 # 0 +0x9976 0xC176 # 0 +0x9977 0xC177 # 0 +0x9978 0xC179 # 0 +0x9979 0xC17A # 0 +0x997A 0xC17B # 0 +0x9981 0xC17C # 0 +0x9982 0xC17D # 0 +0x9983 0xC17E # 0 +0x9984 0xC17F # 0 +0x9985 0xC180 # 0 +0x9986 0xC181 # 0 +0x9987 0xC182 # 0 +0x9988 0xC183 # 0 +0x9989 0xC184 # 0 +0x998A 0xC186 # 0 +0x998B 0xC187 # 0 +0x998C 0xC188 # 0 +0x998D 0xC189 # 0 +0x998E 0xC18A # 0 +0x998F 0xC18B # 0 +0x9990 0xC18F # 0 +0x9991 0xC191 # 0 +0x9992 0xC192 # 0 +0x9993 0xC193 # 0 +0x9994 0xC195 # 0 +0x9995 0xC197 # 0 +0x9996 0xC198 # 0 +0x9997 0xC199 # 0 +0x9998 0xC19A # 0 +0x9999 0xC19B # 0 +0x999A 0xC19E # 0 +0x999B 0xC1A0 # 0 +0x999C 0xC1A2 # 0 +0x999D 0xC1A3 # 0 +0x999E 0xC1A4 # 0 +0x999F 0xC1A6 # 0 +0x99A0 0xC1A7 # 0 +0x99A1 0xC1AA # 0 +0x99A2 0xC1AB # 0 +0x99A3 0xC1AD # 0 +0x99A4 0xC1AE # 0 +0x99A5 0xC1AF # 0 +0x99A6 0xC1B1 # 0 +0x99A7 0xC1B2 # 0 +0x99A8 0xC1B3 # 0 +0x99A9 0xC1B4 # 0 +0x99AA 0xC1B5 # 0 +0x99AB 0xC1B6 # 0 +0x99AC 0xC1B7 # 0 +0x99AD 0xC1B8 # 0 +0x99AE 0xC1B9 # 0 +0x99AF 0xC1BA # 0 +0x99B0 0xC1BB # 0 +0x99B1 0xC1BC # 0 +0x99B2 0xC1BE # 0 +0x99B3 0xC1BF # 0 +0x99B4 0xC1C0 # 0 +0x99B5 0xC1C1 # 0 +0x99B6 0xC1C2 # 0 +0x99B7 0xC1C3 # 0 +0x99B8 0xC1C5 # 0 +0x99B9 0xC1C6 # 0 +0x99BA 0xC1C7 # 0 +0x99BB 0xC1C9 # 0 +0x99BC 0xC1CA # 0 +0x99BD 0xC1CB # 0 +0x99BE 0xC1CD # 0 +0x99BF 0xC1CE # 0 +0x99C0 0xC1CF # 0 +0x99C1 0xC1D0 # 0 +0x99C2 0xC1D1 # 0 +0x99C3 0xC1D2 # 0 +0x99C4 0xC1D3 # 0 +0x99C5 0xC1D5 # 0 +0x99C6 0xC1D6 # 0 +0x99C7 0xC1D9 # 0 +0x99C8 0xC1DA # 0 +0x99C9 0xC1DB # 0 +0x99CA 0xC1DC # 0 +0x99CB 0xC1DD # 0 +0x99CC 0xC1DE # 0 +0x99CD 0xC1DF # 0 +0x99CE 0xC1E1 # 0 +0x99CF 0xC1E2 # 0 +0x99D0 0xC1E3 # 0 +0x99D1 0xC1E5 # 0 +0x99D2 0xC1E6 # 0 +0x99D3 0xC1E7 # 0 +0x99D4 0xC1E9 # 0 +0x99D5 0xC1EA # 0 +0x99D6 0xC1EB # 0 +0x99D7 0xC1EC # 0 +0x99D8 0xC1ED # 0 +0x99D9 0xC1EE # 0 +0x99DA 0xC1EF # 0 +0x99DB 0xC1F2 # 0 +0x99DC 0xC1F4 # 0 +0x99DD 0xC1F5 # 0 +0x99DE 0xC1F6 # 0 +0x99DF 0xC1F7 # 0 +0x99E0 0xC1F8 # 0 +0x99E1 0xC1F9 # 0 +0x99E2 0xC1FA # 0 +0x99E3 0xC1FB # 0 +0x99E4 0xC1FE # 0 +0x99E5 0xC1FF # 0 +0x99E6 0xC201 # 0 +0x99E7 0xC202 # 0 +0x99E8 0xC203 # 0 +0x99E9 0xC205 # 0 +0x99EA 0xC206 # 0 +0x99EB 0xC207 # 0 +0x99EC 0xC208 # 0 +0x99ED 0xC209 # 0 +0x99EE 0xC20A # 0 +0x99EF 0xC20B # 0 +0x99F0 0xC20E # 0 +0x99F1 0xC210 # 0 +0x99F2 0xC212 # 0 +0x99F3 0xC213 # 0 +0x99F4 0xC214 # 0 +0x99F5 0xC215 # 0 +0x99F6 0xC216 # 0 +0x99F7 0xC217 # 0 +0x99F8 0xC21A # 0 +0x99F9 0xC21B # 0 +0x99FA 0xC21D # 0 +0x99FB 0xC21E # 0 +0x99FC 0xC221 # 0 +0x99FD 0xC222 # 0 +0x99FE 0xC223 # 0 +0x9A41 0xC224 # 0 +0x9A42 0xC225 # 0 +0x9A43 0xC226 # 0 +0x9A44 0xC227 # 0 +0x9A45 0xC22A # 0 +0x9A46 0xC22C # 0 +0x9A47 0xC22E # 0 +0x9A48 0xC230 # 0 +0x9A49 0xC233 # 0 +0x9A4A 0xC235 # 0 +0x9A4B 0xC236 # 0 +0x9A4C 0xC237 # 0 +0x9A4D 0xC238 # 0 +0x9A4E 0xC239 # 0 +0x9A4F 0xC23A # 0 +0x9A50 0xC23B # 0 +0x9A51 0xC23C # 0 +0x9A52 0xC23D # 0 +0x9A53 0xC23E # 0 +0x9A54 0xC23F # 0 +0x9A55 0xC240 # 0 +0x9A56 0xC241 # 0 +0x9A57 0xC242 # 0 +0x9A58 0xC243 # 0 +0x9A59 0xC244 # 0 +0x9A5A 0xC245 # 0 +0x9A61 0xC246 # 0 +0x9A62 0xC247 # 0 +0x9A63 0xC249 # 0 +0x9A64 0xC24A # 0 +0x9A65 0xC24B # 0 +0x9A66 0xC24C # 0 +0x9A67 0xC24D # 0 +0x9A68 0xC24E # 0 +0x9A69 0xC24F # 0 +0x9A6A 0xC252 # 0 +0x9A6B 0xC253 # 0 +0x9A6C 0xC255 # 0 +0x9A6D 0xC256 # 0 +0x9A6E 0xC257 # 0 +0x9A6F 0xC259 # 0 +0x9A70 0xC25A # 0 +0x9A71 0xC25B # 0 +0x9A72 0xC25C # 0 +0x9A73 0xC25D # 0 +0x9A74 0xC25E # 0 +0x9A75 0xC25F # 0 +0x9A76 0xC261 # 0 +0x9A77 0xC262 # 0 +0x9A78 0xC263 # 0 +0x9A79 0xC264 # 0 +0x9A7A 0xC266 # 0 +0x9A81 0xC267 # 0 +0x9A82 0xC268 # 0 +0x9A83 0xC269 # 0 +0x9A84 0xC26A # 0 +0x9A85 0xC26B # 0 +0x9A86 0xC26E # 0 +0x9A87 0xC26F # 0 +0x9A88 0xC271 # 0 +0x9A89 0xC272 # 0 +0x9A8A 0xC273 # 0 +0x9A8B 0xC275 # 0 +0x9A8C 0xC276 # 0 +0x9A8D 0xC277 # 0 +0x9A8E 0xC278 # 0 +0x9A8F 0xC279 # 0 +0x9A90 0xC27A # 0 +0x9A91 0xC27B # 0 +0x9A92 0xC27E # 0 +0x9A93 0xC280 # 0 +0x9A94 0xC282 # 0 +0x9A95 0xC283 # 0 +0x9A96 0xC284 # 0 +0x9A97 0xC285 # 0 +0x9A98 0xC286 # 0 +0x9A99 0xC287 # 0 +0x9A9A 0xC28A # 0 +0x9A9B 0xC28B # 0 +0x9A9C 0xC28C # 0 +0x9A9D 0xC28D # 0 +0x9A9E 0xC28E # 0 +0x9A9F 0xC28F # 0 +0x9AA0 0xC291 # 0 +0x9AA1 0xC292 # 0 +0x9AA2 0xC293 # 0 +0x9AA3 0xC294 # 0 +0x9AA4 0xC295 # 0 +0x9AA5 0xC296 # 0 +0x9AA6 0xC297 # 0 +0x9AA7 0xC299 # 0 +0x9AA8 0xC29A # 0 +0x9AA9 0xC29C # 0 +0x9AAA 0xC29E # 0 +0x9AAB 0xC29F # 0 +0x9AAC 0xC2A0 # 0 +0x9AAD 0xC2A1 # 0 +0x9AAE 0xC2A2 # 0 +0x9AAF 0xC2A3 # 0 +0x9AB0 0xC2A6 # 0 +0x9AB1 0xC2A7 # 0 +0x9AB2 0xC2A9 # 0 +0x9AB3 0xC2AA # 0 +0x9AB4 0xC2AB # 0 +0x9AB5 0xC2AE # 0 +0x9AB6 0xC2AF # 0 +0x9AB7 0xC2B0 # 0 +0x9AB8 0xC2B1 # 0 +0x9AB9 0xC2B2 # 0 +0x9ABA 0xC2B3 # 0 +0x9ABB 0xC2B6 # 0 +0x9ABC 0xC2B8 # 0 +0x9ABD 0xC2BA # 0 +0x9ABE 0xC2BB # 0 +0x9ABF 0xC2BC # 0 +0x9AC0 0xC2BD # 0 +0x9AC1 0xC2BE # 0 +0x9AC2 0xC2BF # 0 +0x9AC3 0xC2C0 # 0 +0x9AC4 0xC2C1 # 0 +0x9AC5 0xC2C2 # 0 +0x9AC6 0xC2C3 # 0 +0x9AC7 0xC2C4 # 0 +0x9AC8 0xC2C5 # 0 +0x9AC9 0xC2C6 # 0 +0x9ACA 0xC2C7 # 0 +0x9ACB 0xC2C8 # 0 +0x9ACC 0xC2C9 # 0 +0x9ACD 0xC2CA # 0 +0x9ACE 0xC2CB # 0 +0x9ACF 0xC2CC # 0 +0x9AD0 0xC2CD # 0 +0x9AD1 0xC2CE # 0 +0x9AD2 0xC2CF # 0 +0x9AD3 0xC2D0 # 0 +0x9AD4 0xC2D1 # 0 +0x9AD5 0xC2D2 # 0 +0x9AD6 0xC2D3 # 0 +0x9AD7 0xC2D4 # 0 +0x9AD8 0xC2D5 # 0 +0x9AD9 0xC2D6 # 0 +0x9ADA 0xC2D7 # 0 +0x9ADB 0xC2D8 # 0 +0x9ADC 0xC2D9 # 0 +0x9ADD 0xC2DA # 0 +0x9ADE 0xC2DB # 0 +0x9ADF 0xC2DE # 0 +0x9AE0 0xC2DF # 0 +0x9AE1 0xC2E1 # 0 +0x9AE2 0xC2E2 # 0 +0x9AE3 0xC2E5 # 0 +0x9AE4 0xC2E6 # 0 +0x9AE5 0xC2E7 # 0 +0x9AE6 0xC2E8 # 0 +0x9AE7 0xC2E9 # 0 +0x9AE8 0xC2EA # 0 +0x9AE9 0xC2EE # 0 +0x9AEA 0xC2F0 # 0 +0x9AEB 0xC2F2 # 0 +0x9AEC 0xC2F3 # 0 +0x9AED 0xC2F4 # 0 +0x9AEE 0xC2F5 # 0 +0x9AEF 0xC2F7 # 0 +0x9AF0 0xC2FA # 0 +0x9AF1 0xC2FD # 0 +0x9AF2 0xC2FE # 0 +0x9AF3 0xC2FF # 0 +0x9AF4 0xC301 # 0 +0x9AF5 0xC302 # 0 +0x9AF6 0xC303 # 0 +0x9AF7 0xC304 # 0 +0x9AF8 0xC305 # 0 +0x9AF9 0xC306 # 0 +0x9AFA 0xC307 # 0 +0x9AFB 0xC30A # 0 +0x9AFC 0xC30B # 0 +0x9AFD 0xC30E # 0 +0x9AFE 0xC30F # 0 +0x9B41 0xC310 # 0 +0x9B42 0xC311 # 0 +0x9B43 0xC312 # 0 +0x9B44 0xC316 # 0 +0x9B45 0xC317 # 0 +0x9B46 0xC319 # 0 +0x9B47 0xC31A # 0 +0x9B48 0xC31B # 0 +0x9B49 0xC31D # 0 +0x9B4A 0xC31E # 0 +0x9B4B 0xC31F # 0 +0x9B4C 0xC320 # 0 +0x9B4D 0xC321 # 0 +0x9B4E 0xC322 # 0 +0x9B4F 0xC323 # 0 +0x9B50 0xC326 # 0 +0x9B51 0xC327 # 0 +0x9B52 0xC32A # 0 +0x9B53 0xC32B # 0 +0x9B54 0xC32C # 0 +0x9B55 0xC32D # 0 +0x9B56 0xC32E # 0 +0x9B57 0xC32F # 0 +0x9B58 0xC330 # 0 +0x9B59 0xC331 # 0 +0x9B5A 0xC332 # 0 +0x9B61 0xC333 # 0 +0x9B62 0xC334 # 0 +0x9B63 0xC335 # 0 +0x9B64 0xC336 # 0 +0x9B65 0xC337 # 0 +0x9B66 0xC338 # 0 +0x9B67 0xC339 # 0 +0x9B68 0xC33A # 0 +0x9B69 0xC33B # 0 +0x9B6A 0xC33C # 0 +0x9B6B 0xC33D # 0 +0x9B6C 0xC33E # 0 +0x9B6D 0xC33F # 0 +0x9B6E 0xC340 # 0 +0x9B6F 0xC341 # 0 +0x9B70 0xC342 # 0 +0x9B71 0xC343 # 0 +0x9B72 0xC344 # 0 +0x9B73 0xC346 # 0 +0x9B74 0xC347 # 0 +0x9B75 0xC348 # 0 +0x9B76 0xC349 # 0 +0x9B77 0xC34A # 0 +0x9B78 0xC34B # 0 +0x9B79 0xC34C # 0 +0x9B7A 0xC34D # 0 +0x9B81 0xC34E # 0 +0x9B82 0xC34F # 0 +0x9B83 0xC350 # 0 +0x9B84 0xC351 # 0 +0x9B85 0xC352 # 0 +0x9B86 0xC353 # 0 +0x9B87 0xC354 # 0 +0x9B88 0xC355 # 0 +0x9B89 0xC356 # 0 +0x9B8A 0xC357 # 0 +0x9B8B 0xC358 # 0 +0x9B8C 0xC359 # 0 +0x9B8D 0xC35A # 0 +0x9B8E 0xC35B # 0 +0x9B8F 0xC35C # 0 +0x9B90 0xC35D # 0 +0x9B91 0xC35E # 0 +0x9B92 0xC35F # 0 +0x9B93 0xC360 # 0 +0x9B94 0xC361 # 0 +0x9B95 0xC362 # 0 +0x9B96 0xC363 # 0 +0x9B97 0xC364 # 0 +0x9B98 0xC365 # 0 +0x9B99 0xC366 # 0 +0x9B9A 0xC367 # 0 +0x9B9B 0xC36A # 0 +0x9B9C 0xC36B # 0 +0x9B9D 0xC36D # 0 +0x9B9E 0xC36E # 0 +0x9B9F 0xC36F # 0 +0x9BA0 0xC371 # 0 +0x9BA1 0xC373 # 0 +0x9BA2 0xC374 # 0 +0x9BA3 0xC375 # 0 +0x9BA4 0xC376 # 0 +0x9BA5 0xC377 # 0 +0x9BA6 0xC37A # 0 +0x9BA7 0xC37B # 0 +0x9BA8 0xC37E # 0 +0x9BA9 0xC37F # 0 +0x9BAA 0xC380 # 0 +0x9BAB 0xC381 # 0 +0x9BAC 0xC382 # 0 +0x9BAD 0xC383 # 0 +0x9BAE 0xC385 # 0 +0x9BAF 0xC386 # 0 +0x9BB0 0xC387 # 0 +0x9BB1 0xC389 # 0 +0x9BB2 0xC38A # 0 +0x9BB3 0xC38B # 0 +0x9BB4 0xC38D # 0 +0x9BB5 0xC38E # 0 +0x9BB6 0xC38F # 0 +0x9BB7 0xC390 # 0 +0x9BB8 0xC391 # 0 +0x9BB9 0xC392 # 0 +0x9BBA 0xC393 # 0 +0x9BBB 0xC394 # 0 +0x9BBC 0xC395 # 0 +0x9BBD 0xC396 # 0 +0x9BBE 0xC397 # 0 +0x9BBF 0xC398 # 0 +0x9BC0 0xC399 # 0 +0x9BC1 0xC39A # 0 +0x9BC2 0xC39B # 0 +0x9BC3 0xC39C # 0 +0x9BC4 0xC39D # 0 +0x9BC5 0xC39E # 0 +0x9BC6 0xC39F # 0 +0x9BC7 0xC3A0 # 0 +0x9BC8 0xC3A1 # 0 +0x9BC9 0xC3A2 # 0 +0x9BCA 0xC3A3 # 0 +0x9BCB 0xC3A4 # 0 +0x9BCC 0xC3A5 # 0 +0x9BCD 0xC3A6 # 0 +0x9BCE 0xC3A7 # 0 +0x9BCF 0xC3A8 # 0 +0x9BD0 0xC3A9 # 0 +0x9BD1 0xC3AA # 0 +0x9BD2 0xC3AB # 0 +0x9BD3 0xC3AC # 0 +0x9BD4 0xC3AD # 0 +0x9BD5 0xC3AE # 0 +0x9BD6 0xC3AF # 0 +0x9BD7 0xC3B0 # 0 +0x9BD8 0xC3B1 # 0 +0x9BD9 0xC3B2 # 0 +0x9BDA 0xC3B3 # 0 +0x9BDB 0xC3B4 # 0 +0x9BDC 0xC3B5 # 0 +0x9BDD 0xC3B6 # 0 +0x9BDE 0xC3B7 # 0 +0x9BDF 0xC3B8 # 0 +0x9BE0 0xC3B9 # 0 +0x9BE1 0xC3BA # 0 +0x9BE2 0xC3BB # 0 +0x9BE3 0xC3BC # 0 +0x9BE4 0xC3BD # 0 +0x9BE5 0xC3BE # 0 +0x9BE6 0xC3BF # 0 +0x9BE7 0xC3C1 # 0 +0x9BE8 0xC3C2 # 0 +0x9BE9 0xC3C3 # 0 +0x9BEA 0xC3C4 # 0 +0x9BEB 0xC3C5 # 0 +0x9BEC 0xC3C6 # 0 +0x9BED 0xC3C7 # 0 +0x9BEE 0xC3C8 # 0 +0x9BEF 0xC3C9 # 0 +0x9BF0 0xC3CA # 0 +0x9BF1 0xC3CB # 0 +0x9BF2 0xC3CC # 0 +0x9BF3 0xC3CD # 0 +0x9BF4 0xC3CE # 0 +0x9BF5 0xC3CF # 0 +0x9BF6 0xC3D0 # 0 +0x9BF7 0xC3D1 # 0 +0x9BF8 0xC3D2 # 0 +0x9BF9 0xC3D3 # 0 +0x9BFA 0xC3D4 # 0 +0x9BFB 0xC3D5 # 0 +0x9BFC 0xC3D6 # 0 +0x9BFD 0xC3D7 # 0 +0x9BFE 0xC3DA # 0 +0x9C41 0xC3DB # 0 +0x9C42 0xC3DD # 0 +0x9C43 0xC3DE # 0 +0x9C44 0xC3E1 # 0 +0x9C45 0xC3E3 # 0 +0x9C46 0xC3E4 # 0 +0x9C47 0xC3E5 # 0 +0x9C48 0xC3E6 # 0 +0x9C49 0xC3E7 # 0 +0x9C4A 0xC3EA # 0 +0x9C4B 0xC3EB # 0 +0x9C4C 0xC3EC # 0 +0x9C4D 0xC3EE # 0 +0x9C4E 0xC3EF # 0 +0x9C4F 0xC3F0 # 0 +0x9C50 0xC3F1 # 0 +0x9C51 0xC3F2 # 0 +0x9C52 0xC3F3 # 0 +0x9C53 0xC3F6 # 0 +0x9C54 0xC3F7 # 0 +0x9C55 0xC3F9 # 0 +0x9C56 0xC3FA # 0 +0x9C57 0xC3FB # 0 +0x9C58 0xC3FC # 0 +0x9C59 0xC3FD # 0 +0x9C5A 0xC3FE # 0 +0x9C61 0xC3FF # 0 +0x9C62 0xC400 # 0 +0x9C63 0xC401 # 0 +0x9C64 0xC402 # 0 +0x9C65 0xC403 # 0 +0x9C66 0xC404 # 0 +0x9C67 0xC405 # 0 +0x9C68 0xC406 # 0 +0x9C69 0xC407 # 0 +0x9C6A 0xC409 # 0 +0x9C6B 0xC40A # 0 +0x9C6C 0xC40B # 0 +0x9C6D 0xC40C # 0 +0x9C6E 0xC40D # 0 +0x9C6F 0xC40E # 0 +0x9C70 0xC40F # 0 +0x9C71 0xC411 # 0 +0x9C72 0xC412 # 0 +0x9C73 0xC413 # 0 +0x9C74 0xC414 # 0 +0x9C75 0xC415 # 0 +0x9C76 0xC416 # 0 +0x9C77 0xC417 # 0 +0x9C78 0xC418 # 0 +0x9C79 0xC419 # 0 +0x9C7A 0xC41A # 0 +0x9C81 0xC41B # 0 +0x9C82 0xC41C # 0 +0x9C83 0xC41D # 0 +0x9C84 0xC41E # 0 +0x9C85 0xC41F # 0 +0x9C86 0xC420 # 0 +0x9C87 0xC421 # 0 +0x9C88 0xC422 # 0 +0x9C89 0xC423 # 0 +0x9C8A 0xC425 # 0 +0x9C8B 0xC426 # 0 +0x9C8C 0xC427 # 0 +0x9C8D 0xC428 # 0 +0x9C8E 0xC429 # 0 +0x9C8F 0xC42A # 0 +0x9C90 0xC42B # 0 +0x9C91 0xC42D # 0 +0x9C92 0xC42E # 0 +0x9C93 0xC42F # 0 +0x9C94 0xC431 # 0 +0x9C95 0xC432 # 0 +0x9C96 0xC433 # 0 +0x9C97 0xC435 # 0 +0x9C98 0xC436 # 0 +0x9C99 0xC437 # 0 +0x9C9A 0xC438 # 0 +0x9C9B 0xC439 # 0 +0x9C9C 0xC43A # 0 +0x9C9D 0xC43B # 0 +0x9C9E 0xC43E # 0 +0x9C9F 0xC43F # 0 +0x9CA0 0xC440 # 0 +0x9CA1 0xC441 # 0 +0x9CA2 0xC442 # 0 +0x9CA3 0xC443 # 0 +0x9CA4 0xC444 # 0 +0x9CA5 0xC445 # 0 +0x9CA6 0xC446 # 0 +0x9CA7 0xC447 # 0 +0x9CA8 0xC449 # 0 +0x9CA9 0xC44A # 0 +0x9CAA 0xC44B # 0 +0x9CAB 0xC44C # 0 +0x9CAC 0xC44D # 0 +0x9CAD 0xC44E # 0 +0x9CAE 0xC44F # 0 +0x9CAF 0xC450 # 0 +0x9CB0 0xC451 # 0 +0x9CB1 0xC452 # 0 +0x9CB2 0xC453 # 0 +0x9CB3 0xC454 # 0 +0x9CB4 0xC455 # 0 +0x9CB5 0xC456 # 0 +0x9CB6 0xC457 # 0 +0x9CB7 0xC458 # 0 +0x9CB8 0xC459 # 0 +0x9CB9 0xC45A # 0 +0x9CBA 0xC45B # 0 +0x9CBB 0xC45C # 0 +0x9CBC 0xC45D # 0 +0x9CBD 0xC45E # 0 +0x9CBE 0xC45F # 0 +0x9CBF 0xC460 # 0 +0x9CC0 0xC461 # 0 +0x9CC1 0xC462 # 0 +0x9CC2 0xC463 # 0 +0x9CC3 0xC466 # 0 +0x9CC4 0xC467 # 0 +0x9CC5 0xC469 # 0 +0x9CC6 0xC46A # 0 +0x9CC7 0xC46B # 0 +0x9CC8 0xC46D # 0 +0x9CC9 0xC46E # 0 +0x9CCA 0xC46F # 0 +0x9CCB 0xC470 # 0 +0x9CCC 0xC471 # 0 +0x9CCD 0xC472 # 0 +0x9CCE 0xC473 # 0 +0x9CCF 0xC476 # 0 +0x9CD0 0xC477 # 0 +0x9CD1 0xC478 # 0 +0x9CD2 0xC47A # 0 +0x9CD3 0xC47B # 0 +0x9CD4 0xC47C # 0 +0x9CD5 0xC47D # 0 +0x9CD6 0xC47E # 0 +0x9CD7 0xC47F # 0 +0x9CD8 0xC481 # 0 +0x9CD9 0xC482 # 0 +0x9CDA 0xC483 # 0 +0x9CDB 0xC484 # 0 +0x9CDC 0xC485 # 0 +0x9CDD 0xC486 # 0 +0x9CDE 0xC487 # 0 +0x9CDF 0xC488 # 0 +0x9CE0 0xC489 # 0 +0x9CE1 0xC48A # 0 +0x9CE2 0xC48B # 0 +0x9CE3 0xC48C # 0 +0x9CE4 0xC48D # 0 +0x9CE5 0xC48E # 0 +0x9CE6 0xC48F # 0 +0x9CE7 0xC490 # 0 +0x9CE8 0xC491 # 0 +0x9CE9 0xC492 # 0 +0x9CEA 0xC493 # 0 +0x9CEB 0xC495 # 0 +0x9CEC 0xC496 # 0 +0x9CED 0xC497 # 0 +0x9CEE 0xC498 # 0 +0x9CEF 0xC499 # 0 +0x9CF0 0xC49A # 0 +0x9CF1 0xC49B # 0 +0x9CF2 0xC49D # 0 +0x9CF3 0xC49E # 0 +0x9CF4 0xC49F # 0 +0x9CF5 0xC4A0 # 0 +0x9CF6 0xC4A1 # 0 +0x9CF7 0xC4A2 # 0 +0x9CF8 0xC4A3 # 0 +0x9CF9 0xC4A4 # 0 +0x9CFA 0xC4A5 # 0 +0x9CFB 0xC4A6 # 0 +0x9CFC 0xC4A7 # 0 +0x9CFD 0xC4A8 # 0 +0x9CFE 0xC4A9 # 0 +0x9D41 0xC4AA # 0 +0x9D42 0xC4AB # 0 +0x9D43 0xC4AC # 0 +0x9D44 0xC4AD # 0 +0x9D45 0xC4AE # 0 +0x9D46 0xC4AF # 0 +0x9D47 0xC4B0 # 0 +0x9D48 0xC4B1 # 0 +0x9D49 0xC4B2 # 0 +0x9D4A 0xC4B3 # 0 +0x9D4B 0xC4B4 # 0 +0x9D4C 0xC4B5 # 0 +0x9D4D 0xC4B6 # 0 +0x9D4E 0xC4B7 # 0 +0x9D4F 0xC4B9 # 0 +0x9D50 0xC4BA # 0 +0x9D51 0xC4BB # 0 +0x9D52 0xC4BD # 0 +0x9D53 0xC4BE # 0 +0x9D54 0xC4BF # 0 +0x9D55 0xC4C0 # 0 +0x9D56 0xC4C1 # 0 +0x9D57 0xC4C2 # 0 +0x9D58 0xC4C3 # 0 +0x9D59 0xC4C4 # 0 +0x9D5A 0xC4C5 # 0 +0x9D61 0xC4C6 # 0 +0x9D62 0xC4C7 # 0 +0x9D63 0xC4C8 # 0 +0x9D64 0xC4C9 # 0 +0x9D65 0xC4CA # 0 +0x9D66 0xC4CB # 0 +0x9D67 0xC4CC # 0 +0x9D68 0xC4CD # 0 +0x9D69 0xC4CE # 0 +0x9D6A 0xC4CF # 0 +0x9D6B 0xC4D0 # 0 +0x9D6C 0xC4D1 # 0 +0x9D6D 0xC4D2 # 0 +0x9D6E 0xC4D3 # 0 +0x9D6F 0xC4D4 # 0 +0x9D70 0xC4D5 # 0 +0x9D71 0xC4D6 # 0 +0x9D72 0xC4D7 # 0 +0x9D73 0xC4D8 # 0 +0x9D74 0xC4D9 # 0 +0x9D75 0xC4DA # 0 +0x9D76 0xC4DB # 0 +0x9D77 0xC4DC # 0 +0x9D78 0xC4DD # 0 +0x9D79 0xC4DE # 0 +0x9D7A 0xC4DF # 0 +0x9D81 0xC4E0 # 0 +0x9D82 0xC4E1 # 0 +0x9D83 0xC4E2 # 0 +0x9D84 0xC4E3 # 0 +0x9D85 0xC4E4 # 0 +0x9D86 0xC4E5 # 0 +0x9D87 0xC4E6 # 0 +0x9D88 0xC4E7 # 0 +0x9D89 0xC4E8 # 0 +0x9D8A 0xC4EA # 0 +0x9D8B 0xC4EB # 0 +0x9D8C 0xC4EC # 0 +0x9D8D 0xC4ED # 0 +0x9D8E 0xC4EE # 0 +0x9D8F 0xC4EF # 0 +0x9D90 0xC4F2 # 0 +0x9D91 0xC4F3 # 0 +0x9D92 0xC4F5 # 0 +0x9D93 0xC4F6 # 0 +0x9D94 0xC4F7 # 0 +0x9D95 0xC4F9 # 0 +0x9D96 0xC4FB # 0 +0x9D97 0xC4FC # 0 +0x9D98 0xC4FD # 0 +0x9D99 0xC4FE # 0 +0x9D9A 0xC502 # 0 +0x9D9B 0xC503 # 0 +0x9D9C 0xC504 # 0 +0x9D9D 0xC505 # 0 +0x9D9E 0xC506 # 0 +0x9D9F 0xC507 # 0 +0x9DA0 0xC508 # 0 +0x9DA1 0xC509 # 0 +0x9DA2 0xC50A # 0 +0x9DA3 0xC50B # 0 +0x9DA4 0xC50D # 0 +0x9DA5 0xC50E # 0 +0x9DA6 0xC50F # 0 +0x9DA7 0xC511 # 0 +0x9DA8 0xC512 # 0 +0x9DA9 0xC513 # 0 +0x9DAA 0xC515 # 0 +0x9DAB 0xC516 # 0 +0x9DAC 0xC517 # 0 +0x9DAD 0xC518 # 0 +0x9DAE 0xC519 # 0 +0x9DAF 0xC51A # 0 +0x9DB0 0xC51B # 0 +0x9DB1 0xC51D # 0 +0x9DB2 0xC51E # 0 +0x9DB3 0xC51F # 0 +0x9DB4 0xC520 # 0 +0x9DB5 0xC521 # 0 +0x9DB6 0xC522 # 0 +0x9DB7 0xC523 # 0 +0x9DB8 0xC524 # 0 +0x9DB9 0xC525 # 0 +0x9DBA 0xC526 # 0 +0x9DBB 0xC527 # 0 +0x9DBC 0xC52A # 0 +0x9DBD 0xC52B # 0 +0x9DBE 0xC52D # 0 +0x9DBF 0xC52E # 0 +0x9DC0 0xC52F # 0 +0x9DC1 0xC531 # 0 +0x9DC2 0xC532 # 0 +0x9DC3 0xC533 # 0 +0x9DC4 0xC534 # 0 +0x9DC5 0xC535 # 0 +0x9DC6 0xC536 # 0 +0x9DC7 0xC537 # 0 +0x9DC8 0xC53A # 0 +0x9DC9 0xC53C # 0 +0x9DCA 0xC53E # 0 +0x9DCB 0xC53F # 0 +0x9DCC 0xC540 # 0 +0x9DCD 0xC541 # 0 +0x9DCE 0xC542 # 0 +0x9DCF 0xC543 # 0 +0x9DD0 0xC546 # 0 +0x9DD1 0xC547 # 0 +0x9DD2 0xC54B # 0 +0x9DD3 0xC54F # 0 +0x9DD4 0xC550 # 0 +0x9DD5 0xC551 # 0 +0x9DD6 0xC552 # 0 +0x9DD7 0xC556 # 0 +0x9DD8 0xC55A # 0 +0x9DD9 0xC55B # 0 +0x9DDA 0xC55C # 0 +0x9DDB 0xC55F # 0 +0x9DDC 0xC562 # 0 +0x9DDD 0xC563 # 0 +0x9DDE 0xC565 # 0 +0x9DDF 0xC566 # 0 +0x9DE0 0xC567 # 0 +0x9DE1 0xC569 # 0 +0x9DE2 0xC56A # 0 +0x9DE3 0xC56B # 0 +0x9DE4 0xC56C # 0 +0x9DE5 0xC56D # 0 +0x9DE6 0xC56E # 0 +0x9DE7 0xC56F # 0 +0x9DE8 0xC572 # 0 +0x9DE9 0xC576 # 0 +0x9DEA 0xC577 # 0 +0x9DEB 0xC578 # 0 +0x9DEC 0xC579 # 0 +0x9DED 0xC57A # 0 +0x9DEE 0xC57B # 0 +0x9DEF 0xC57E # 0 +0x9DF0 0xC57F # 0 +0x9DF1 0xC581 # 0 +0x9DF2 0xC582 # 0 +0x9DF3 0xC583 # 0 +0x9DF4 0xC585 # 0 +0x9DF5 0xC586 # 0 +0x9DF6 0xC588 # 0 +0x9DF7 0xC589 # 0 +0x9DF8 0xC58A # 0 +0x9DF9 0xC58B # 0 +0x9DFA 0xC58E # 0 +0x9DFB 0xC590 # 0 +0x9DFC 0xC592 # 0 +0x9DFD 0xC593 # 0 +0x9DFE 0xC594 # 0 +0x9E41 0xC596 # 0 +0x9E42 0xC599 # 0 +0x9E43 0xC59A # 0 +0x9E44 0xC59B # 0 +0x9E45 0xC59D # 0 +0x9E46 0xC59E # 0 +0x9E47 0xC59F # 0 +0x9E48 0xC5A1 # 0 +0x9E49 0xC5A2 # 0 +0x9E4A 0xC5A3 # 0 +0x9E4B 0xC5A4 # 0 +0x9E4C 0xC5A5 # 0 +0x9E4D 0xC5A6 # 0 +0x9E4E 0xC5A7 # 0 +0x9E4F 0xC5A8 # 0 +0x9E50 0xC5AA # 0 +0x9E51 0xC5AB # 0 +0x9E52 0xC5AC # 0 +0x9E53 0xC5AD # 0 +0x9E54 0xC5AE # 0 +0x9E55 0xC5AF # 0 +0x9E56 0xC5B0 # 0 +0x9E57 0xC5B1 # 0 +0x9E58 0xC5B2 # 0 +0x9E59 0xC5B3 # 0 +0x9E5A 0xC5B6 # 0 +0x9E61 0xC5B7 # 0 +0x9E62 0xC5BA # 0 +0x9E63 0xC5BF # 0 +0x9E64 0xC5C0 # 0 +0x9E65 0xC5C1 # 0 +0x9E66 0xC5C2 # 0 +0x9E67 0xC5C3 # 0 +0x9E68 0xC5CB # 0 +0x9E69 0xC5CD # 0 +0x9E6A 0xC5CF # 0 +0x9E6B 0xC5D2 # 0 +0x9E6C 0xC5D3 # 0 +0x9E6D 0xC5D5 # 0 +0x9E6E 0xC5D6 # 0 +0x9E6F 0xC5D7 # 0 +0x9E70 0xC5D9 # 0 +0x9E71 0xC5DA # 0 +0x9E72 0xC5DB # 0 +0x9E73 0xC5DC # 0 +0x9E74 0xC5DD # 0 +0x9E75 0xC5DE # 0 +0x9E76 0xC5DF # 0 +0x9E77 0xC5E2 # 0 +0x9E78 0xC5E4 # 0 +0x9E79 0xC5E6 # 0 +0x9E7A 0xC5E7 # 0 +0x9E81 0xC5E8 # 0 +0x9E82 0xC5E9 # 0 +0x9E83 0xC5EA # 0 +0x9E84 0xC5EB # 0 +0x9E85 0xC5EF # 0 +0x9E86 0xC5F1 # 0 +0x9E87 0xC5F2 # 0 +0x9E88 0xC5F3 # 0 +0x9E89 0xC5F5 # 0 +0x9E8A 0xC5F8 # 0 +0x9E8B 0xC5F9 # 0 +0x9E8C 0xC5FA # 0 +0x9E8D 0xC5FB # 0 +0x9E8E 0xC602 # 0 +0x9E8F 0xC603 # 0 +0x9E90 0xC604 # 0 +0x9E91 0xC609 # 0 +0x9E92 0xC60A # 0 +0x9E93 0xC60B # 0 +0x9E94 0xC60D # 0 +0x9E95 0xC60E # 0 +0x9E96 0xC60F # 0 +0x9E97 0xC611 # 0 +0x9E98 0xC612 # 0 +0x9E99 0xC613 # 0 +0x9E9A 0xC614 # 0 +0x9E9B 0xC615 # 0 +0x9E9C 0xC616 # 0 +0x9E9D 0xC617 # 0 +0x9E9E 0xC61A # 0 +0x9E9F 0xC61D # 0 +0x9EA0 0xC61E # 0 +0x9EA1 0xC61F # 0 +0x9EA2 0xC620 # 0 +0x9EA3 0xC621 # 0 +0x9EA4 0xC622 # 0 +0x9EA5 0xC623 # 0 +0x9EA6 0xC626 # 0 +0x9EA7 0xC627 # 0 +0x9EA8 0xC629 # 0 +0x9EA9 0xC62A # 0 +0x9EAA 0xC62B # 0 +0x9EAB 0xC62F # 0 +0x9EAC 0xC631 # 0 +0x9EAD 0xC632 # 0 +0x9EAE 0xC636 # 0 +0x9EAF 0xC638 # 0 +0x9EB0 0xC63A # 0 +0x9EB1 0xC63C # 0 +0x9EB2 0xC63D # 0 +0x9EB3 0xC63E # 0 +0x9EB4 0xC63F # 0 +0x9EB5 0xC642 # 0 +0x9EB6 0xC643 # 0 +0x9EB7 0xC645 # 0 +0x9EB8 0xC646 # 0 +0x9EB9 0xC647 # 0 +0x9EBA 0xC649 # 0 +0x9EBB 0xC64A # 0 +0x9EBC 0xC64B # 0 +0x9EBD 0xC64C # 0 +0x9EBE 0xC64D # 0 +0x9EBF 0xC64E # 0 +0x9EC0 0xC64F # 0 +0x9EC1 0xC652 # 0 +0x9EC2 0xC656 # 0 +0x9EC3 0xC657 # 0 +0x9EC4 0xC658 # 0 +0x9EC5 0xC659 # 0 +0x9EC6 0xC65A # 0 +0x9EC7 0xC65B # 0 +0x9EC8 0xC65E # 0 +0x9EC9 0xC65F # 0 +0x9ECA 0xC661 # 0 +0x9ECB 0xC662 # 0 +0x9ECC 0xC663 # 0 +0x9ECD 0xC664 # 0 +0x9ECE 0xC665 # 0 +0x9ECF 0xC666 # 0 +0x9ED0 0xC667 # 0 +0x9ED1 0xC668 # 0 +0x9ED2 0xC669 # 0 +0x9ED3 0xC66A # 0 +0x9ED4 0xC66B # 0 +0x9ED5 0xC66D # 0 +0x9ED6 0xC66E # 0 +0x9ED7 0xC670 # 0 +0x9ED8 0xC672 # 0 +0x9ED9 0xC673 # 0 +0x9EDA 0xC674 # 0 +0x9EDB 0xC675 # 0 +0x9EDC 0xC676 # 0 +0x9EDD 0xC677 # 0 +0x9EDE 0xC67A # 0 +0x9EDF 0xC67B # 0 +0x9EE0 0xC67D # 0 +0x9EE1 0xC67E # 0 +0x9EE2 0xC67F # 0 +0x9EE3 0xC681 # 0 +0x9EE4 0xC682 # 0 +0x9EE5 0xC683 # 0 +0x9EE6 0xC684 # 0 +0x9EE7 0xC685 # 0 +0x9EE8 0xC686 # 0 +0x9EE9 0xC687 # 0 +0x9EEA 0xC68A # 0 +0x9EEB 0xC68C # 0 +0x9EEC 0xC68E # 0 +0x9EED 0xC68F # 0 +0x9EEE 0xC690 # 0 +0x9EEF 0xC691 # 0 +0x9EF0 0xC692 # 0 +0x9EF1 0xC693 # 0 +0x9EF2 0xC696 # 0 +0x9EF3 0xC697 # 0 +0x9EF4 0xC699 # 0 +0x9EF5 0xC69A # 0 +0x9EF6 0xC69B # 0 +0x9EF7 0xC69D # 0 +0x9EF8 0xC69E # 0 +0x9EF9 0xC69F # 0 +0x9EFA 0xC6A0 # 0 +0x9EFB 0xC6A1 # 0 +0x9EFC 0xC6A2 # 0 +0x9EFD 0xC6A3 # 0 +0x9EFE 0xC6A6 # 0 +0x9F41 0xC6A8 # 0 +0x9F42 0xC6AA # 0 +0x9F43 0xC6AB # 0 +0x9F44 0xC6AC # 0 +0x9F45 0xC6AD # 0 +0x9F46 0xC6AE # 0 +0x9F47 0xC6AF # 0 +0x9F48 0xC6B2 # 0 +0x9F49 0xC6B3 # 0 +0x9F4A 0xC6B5 # 0 +0x9F4B 0xC6B6 # 0 +0x9F4C 0xC6B7 # 0 +0x9F4D 0xC6BB # 0 +0x9F4E 0xC6BC # 0 +0x9F4F 0xC6BD # 0 +0x9F50 0xC6BE # 0 +0x9F51 0xC6BF # 0 +0x9F52 0xC6C2 # 0 +0x9F53 0xC6C4 # 0 +0x9F54 0xC6C6 # 0 +0x9F55 0xC6C7 # 0 +0x9F56 0xC6C8 # 0 +0x9F57 0xC6C9 # 0 +0x9F58 0xC6CA # 0 +0x9F59 0xC6CB # 0 +0x9F5A 0xC6CE # 0 +0x9F61 0xC6CF # 0 +0x9F62 0xC6D1 # 0 +0x9F63 0xC6D2 # 0 +0x9F64 0xC6D3 # 0 +0x9F65 0xC6D5 # 0 +0x9F66 0xC6D6 # 0 +0x9F67 0xC6D7 # 0 +0x9F68 0xC6D8 # 0 +0x9F69 0xC6D9 # 0 +0x9F6A 0xC6DA # 0 +0x9F6B 0xC6DB # 0 +0x9F6C 0xC6DE # 0 +0x9F6D 0xC6DF # 0 +0x9F6E 0xC6E2 # 0 +0x9F6F 0xC6E3 # 0 +0x9F70 0xC6E4 # 0 +0x9F71 0xC6E5 # 0 +0x9F72 0xC6E6 # 0 +0x9F73 0xC6E7 # 0 +0x9F74 0xC6EA # 0 +0x9F75 0xC6EB # 0 +0x9F76 0xC6ED # 0 +0x9F77 0xC6EE # 0 +0x9F78 0xC6EF # 0 +0x9F79 0xC6F1 # 0 +0x9F7A 0xC6F2 # 0 +0x9F81 0xC6F3 # 0 +0x9F82 0xC6F4 # 0 +0x9F83 0xC6F5 # 0 +0x9F84 0xC6F6 # 0 +0x9F85 0xC6F7 # 0 +0x9F86 0xC6FA # 0 +0x9F87 0xC6FB # 0 +0x9F88 0xC6FC # 0 +0x9F89 0xC6FE # 0 +0x9F8A 0xC6FF # 0 +0x9F8B 0xC700 # 0 +0x9F8C 0xC701 # 0 +0x9F8D 0xC702 # 0 +0x9F8E 0xC703 # 0 +0x9F8F 0xC706 # 0 +0x9F90 0xC707 # 0 +0x9F91 0xC709 # 0 +0x9F92 0xC70A # 0 +0x9F93 0xC70B # 0 +0x9F94 0xC70D # 0 +0x9F95 0xC70E # 0 +0x9F96 0xC70F # 0 +0x9F97 0xC710 # 0 +0x9F98 0xC711 # 0 +0x9F99 0xC712 # 0 +0x9F9A 0xC713 # 0 +0x9F9B 0xC716 # 0 +0x9F9C 0xC718 # 0 +0x9F9D 0xC71A # 0 +0x9F9E 0xC71B # 0 +0x9F9F 0xC71C # 0 +0x9FA0 0xC71D # 0 +0x9FA1 0xC71E # 0 +0x9FA2 0xC71F # 0 +0x9FA3 0xC722 # 0 +0x9FA4 0xC723 # 0 +0x9FA5 0xC725 # 0 +0x9FA6 0xC726 # 0 +0x9FA7 0xC727 # 0 +0x9FA8 0xC729 # 0 +0x9FA9 0xC72A # 0 +0x9FAA 0xC72B # 0 +0x9FAB 0xC72C # 0 +0x9FAC 0xC72D # 0 +0x9FAD 0xC72E # 0 +0x9FAE 0xC72F # 0 +0x9FAF 0xC732 # 0 +0x9FB0 0xC734 # 0 +0x9FB1 0xC736 # 0 +0x9FB2 0xC738 # 0 +0x9FB3 0xC739 # 0 +0x9FB4 0xC73A # 0 +0x9FB5 0xC73B # 0 +0x9FB6 0xC73E # 0 +0x9FB7 0xC73F # 0 +0x9FB8 0xC741 # 0 +0x9FB9 0xC742 # 0 +0x9FBA 0xC743 # 0 +0x9FBB 0xC745 # 0 +0x9FBC 0xC746 # 0 +0x9FBD 0xC747 # 0 +0x9FBE 0xC748 # 0 +0x9FBF 0xC749 # 0 +0x9FC0 0xC74B # 0 +0x9FC1 0xC74E # 0 +0x9FC2 0xC750 # 0 +0x9FC3 0xC759 # 0 +0x9FC4 0xC75A # 0 +0x9FC5 0xC75B # 0 +0x9FC6 0xC75D # 0 +0x9FC7 0xC75E # 0 +0x9FC8 0xC75F # 0 +0x9FC9 0xC761 # 0 +0x9FCA 0xC762 # 0 +0x9FCB 0xC763 # 0 +0x9FCC 0xC764 # 0 +0x9FCD 0xC765 # 0 +0x9FCE 0xC766 # 0 +0x9FCF 0xC767 # 0 +0x9FD0 0xC769 # 0 +0x9FD1 0xC76A # 0 +0x9FD2 0xC76C # 0 +0x9FD3 0xC76D # 0 +0x9FD4 0xC76E # 0 +0x9FD5 0xC76F # 0 +0x9FD6 0xC770 # 0 +0x9FD7 0xC771 # 0 +0x9FD8 0xC772 # 0 +0x9FD9 0xC773 # 0 +0x9FDA 0xC776 # 0 +0x9FDB 0xC777 # 0 +0x9FDC 0xC779 # 0 +0x9FDD 0xC77A # 0 +0x9FDE 0xC77B # 0 +0x9FDF 0xC77F # 0 +0x9FE0 0xC780 # 0 +0x9FE1 0xC781 # 0 +0x9FE2 0xC782 # 0 +0x9FE3 0xC786 # 0 +0x9FE4 0xC78B # 0 +0x9FE5 0xC78C # 0 +0x9FE6 0xC78D # 0 +0x9FE7 0xC78F # 0 +0x9FE8 0xC792 # 0 +0x9FE9 0xC793 # 0 +0x9FEA 0xC795 # 0 +0x9FEB 0xC799 # 0 +0x9FEC 0xC79B # 0 +0x9FED 0xC79C # 0 +0x9FEE 0xC79D # 0 +0x9FEF 0xC79E # 0 +0x9FF0 0xC79F # 0 +0x9FF1 0xC7A2 # 0 +0x9FF2 0xC7A7 # 0 +0x9FF3 0xC7A8 # 0 +0x9FF4 0xC7A9 # 0 +0x9FF5 0xC7AA # 0 +0x9FF6 0xC7AB # 0 +0x9FF7 0xC7AE # 0 +0x9FF8 0xC7AF # 0 +0x9FF9 0xC7B1 # 0 +0x9FFA 0xC7B2 # 0 +0x9FFB 0xC7B3 # 0 +0x9FFC 0xC7B5 # 0 +0x9FFD 0xC7B6 # 0 +0x9FFE 0xC7B7 # 0 +0xA041 0xC7B8 # 0 +0xA042 0xC7B9 # 0 +0xA043 0xC7BA # 0 +0xA044 0xC7BB # 0 +0xA045 0xC7BE # 0 +0xA046 0xC7C2 # 0 +0xA047 0xC7C3 # 0 +0xA048 0xC7C4 # 0 +0xA049 0xC7C5 # 0 +0xA04A 0xC7C6 # 0 +0xA04B 0xC7C7 # 0 +0xA04C 0xC7CA # 0 +0xA04D 0xC7CB # 0 +0xA04E 0xC7CD # 0 +0xA04F 0xC7CF # 0 +0xA050 0xC7D1 # 0 +0xA051 0xC7D2 # 0 +0xA052 0xC7D3 # 0 +0xA053 0xC7D4 # 0 +0xA054 0xC7D5 # 0 +0xA055 0xC7D6 # 0 +0xA056 0xC7D7 # 0 +0xA057 0xC7D9 # 0 +0xA058 0xC7DA # 0 +0xA059 0xC7DB # 0 +0xA05A 0xC7DC # 0 +0xA061 0xC7DE # 0 +0xA062 0xC7DF # 0 +0xA063 0xC7E0 # 0 +0xA064 0xC7E1 # 0 +0xA065 0xC7E2 # 0 +0xA066 0xC7E3 # 0 +0xA067 0xC7E5 # 0 +0xA068 0xC7E6 # 0 +0xA069 0xC7E7 # 0 +0xA06A 0xC7E9 # 0 +0xA06B 0xC7EA # 0 +0xA06C 0xC7EB # 0 +0xA06D 0xC7ED # 0 +0xA06E 0xC7EE # 0 +0xA06F 0xC7EF # 0 +0xA070 0xC7F0 # 0 +0xA071 0xC7F1 # 0 +0xA072 0xC7F2 # 0 +0xA073 0xC7F3 # 0 +0xA074 0xC7F4 # 0 +0xA075 0xC7F5 # 0 +0xA076 0xC7F6 # 0 +0xA077 0xC7F7 # 0 +0xA078 0xC7F8 # 0 +0xA079 0xC7F9 # 0 +0xA07A 0xC7FA # 0 +0xA081 0xC7FB # 0 +0xA082 0xC7FC # 0 +0xA083 0xC7FD # 0 +0xA084 0xC7FE # 0 +0xA085 0xC7FF # 0 +0xA086 0xC802 # 0 +0xA087 0xC803 # 0 +0xA088 0xC805 # 0 +0xA089 0xC806 # 0 +0xA08A 0xC807 # 0 +0xA08B 0xC809 # 0 +0xA08C 0xC80B # 0 +0xA08D 0xC80C # 0 +0xA08E 0xC80D # 0 +0xA08F 0xC80E # 0 +0xA090 0xC80F # 0 +0xA091 0xC812 # 0 +0xA092 0xC814 # 0 +0xA093 0xC817 # 0 +0xA094 0xC818 # 0 +0xA095 0xC819 # 0 +0xA096 0xC81A # 0 +0xA097 0xC81B # 0 +0xA098 0xC81E # 0 +0xA099 0xC81F # 0 +0xA09A 0xC821 # 0 +0xA09B 0xC822 # 0 +0xA09C 0xC823 # 0 +0xA09D 0xC825 # 0 +0xA09E 0xC826 # 0 +0xA09F 0xC827 # 0 +0xA0A0 0xC828 # 0 +0xA0A1 0xC829 # 0 +0xA0A2 0xC82A # 0 +0xA0A3 0xC82B # 0 +0xA0A4 0xC82E # 0 +0xA0A5 0xC830 # 0 +0xA0A6 0xC832 # 0 +0xA0A7 0xC833 # 0 +0xA0A8 0xC834 # 0 +0xA0A9 0xC835 # 0 +0xA0AA 0xC836 # 0 +0xA0AB 0xC837 # 0 +0xA0AC 0xC839 # 0 +0xA0AD 0xC83A # 0 +0xA0AE 0xC83B # 0 +0xA0AF 0xC83D # 0 +0xA0B0 0xC83E # 0 +0xA0B1 0xC83F # 0 +0xA0B2 0xC841 # 0 +0xA0B3 0xC842 # 0 +0xA0B4 0xC843 # 0 +0xA0B5 0xC844 # 0 +0xA0B6 0xC845 # 0 +0xA0B7 0xC846 # 0 +0xA0B8 0xC847 # 0 +0xA0B9 0xC84A # 0 +0xA0BA 0xC84B # 0 +0xA0BB 0xC84E # 0 +0xA0BC 0xC84F # 0 +0xA0BD 0xC850 # 0 +0xA0BE 0xC851 # 0 +0xA0BF 0xC852 # 0 +0xA0C0 0xC853 # 0 +0xA0C1 0xC855 # 0 +0xA0C2 0xC856 # 0 +0xA0C3 0xC857 # 0 +0xA0C4 0xC858 # 0 +0xA0C5 0xC859 # 0 +0xA0C6 0xC85A # 0 +0xA0C7 0xC85B # 0 +0xA0C8 0xC85C # 0 +0xA0C9 0xC85D # 0 +0xA0CA 0xC85E # 0 +0xA0CB 0xC85F # 0 +0xA0CC 0xC860 # 0 +0xA0CD 0xC861 # 0 +0xA0CE 0xC862 # 0 +0xA0CF 0xC863 # 0 +0xA0D0 0xC864 # 0 +0xA0D1 0xC865 # 0 +0xA0D2 0xC866 # 0 +0xA0D3 0xC867 # 0 +0xA0D4 0xC868 # 0 +0xA0D5 0xC869 # 0 +0xA0D6 0xC86A # 0 +0xA0D7 0xC86B # 0 +0xA0D8 0xC86C # 0 +0xA0D9 0xC86D # 0 +0xA0DA 0xC86E # 0 +0xA0DB 0xC86F # 0 +0xA0DC 0xC872 # 0 +0xA0DD 0xC873 # 0 +0xA0DE 0xC875 # 0 +0xA0DF 0xC876 # 0 +0xA0E0 0xC877 # 0 +0xA0E1 0xC879 # 0 +0xA0E2 0xC87B # 0 +0xA0E3 0xC87C # 0 +0xA0E4 0xC87D # 0 +0xA0E5 0xC87E # 0 +0xA0E6 0xC87F # 0 +0xA0E7 0xC882 # 0 +0xA0E8 0xC884 # 0 +0xA0E9 0xC888 # 0 +0xA0EA 0xC889 # 0 +0xA0EB 0xC88A # 0 +0xA0EC 0xC88E # 0 +0xA0ED 0xC88F # 0 +0xA0EE 0xC890 # 0 +0xA0EF 0xC891 # 0 +0xA0F0 0xC892 # 0 +0xA0F1 0xC893 # 0 +0xA0F2 0xC895 # 0 +0xA0F3 0xC896 # 0 +0xA0F4 0xC897 # 0 +0xA0F5 0xC898 # 0 +0xA0F6 0xC899 # 0 +0xA0F7 0xC89A # 0 +0xA0F8 0xC89B # 0 +0xA0F9 0xC89C # 0 +0xA0FA 0xC89E # 0 +0xA0FB 0xC8A0 # 0 +0xA0FC 0xC8A2 # 0 +0xA0FD 0xC8A3 # 0 +0xA0FE 0xC8A4 # 0 +0xA141 0xC8A5 # 0 +0xA142 0xC8A6 # 0 +0xA143 0xC8A7 # 0 +0xA144 0xC8A9 # 0 +0xA145 0xC8AA # 0 +0xA146 0xC8AB # 0 +0xA147 0xC8AC # 0 +0xA148 0xC8AD # 0 +0xA149 0xC8AE # 0 +0xA14A 0xC8AF # 0 +0xA14B 0xC8B0 # 0 +0xA14C 0xC8B1 # 0 +0xA14D 0xC8B2 # 0 +0xA14E 0xC8B3 # 0 +0xA14F 0xC8B4 # 0 +0xA150 0xC8B5 # 0 +0xA151 0xC8B6 # 0 +0xA152 0xC8B7 # 0 +0xA153 0xC8B8 # 0 +0xA154 0xC8B9 # 0 +0xA155 0xC8BA # 0 +0xA156 0xC8BB # 0 +0xA157 0xC8BE # 0 +0xA158 0xC8BF # 0 +0xA159 0xC8C0 # 0 +0xA15A 0xC8C1 # 0 +0xA161 0xC8C2 # 0 +0xA162 0xC8C3 # 0 +0xA163 0xC8C5 # 0 +0xA164 0xC8C6 # 0 +0xA165 0xC8C7 # 0 +0xA166 0xC8C9 # 0 +0xA167 0xC8CA # 0 +0xA168 0xC8CB # 0 +0xA169 0xC8CD # 0 +0xA16A 0xC8CE # 0 +0xA16B 0xC8CF # 0 +0xA16C 0xC8D0 # 0 +0xA16D 0xC8D1 # 0 +0xA16E 0xC8D2 # 0 +0xA16F 0xC8D3 # 0 +0xA170 0xC8D6 # 0 +0xA171 0xC8D8 # 0 +0xA172 0xC8DA # 0 +0xA173 0xC8DB # 0 +0xA174 0xC8DC # 0 +0xA175 0xC8DD # 0 +0xA176 0xC8DE # 0 +0xA177 0xC8DF # 0 +0xA178 0xC8E2 # 0 +0xA179 0xC8E3 # 0 +0xA17A 0xC8E5 # 0 +0xA181 0xC8E6 # 0 +0xA182 0xC8E7 # 0 +0xA183 0xC8E8 # 0 +0xA184 0xC8E9 # 0 +0xA185 0xC8EA # 0 +0xA186 0xC8EB # 0 +0xA187 0xC8EC # 0 +0xA188 0xC8ED # 0 +0xA189 0xC8EE # 0 +0xA18A 0xC8EF # 0 +0xA18B 0xC8F0 # 0 +0xA18C 0xC8F1 # 0 +0xA18D 0xC8F2 # 0 +0xA18E 0xC8F3 # 0 +0xA18F 0xC8F4 # 0 +0xA190 0xC8F6 # 0 +0xA191 0xC8F7 # 0 +0xA192 0xC8F8 # 0 +0xA193 0xC8F9 # 0 +0xA194 0xC8FA # 0 +0xA195 0xC8FB # 0 +0xA196 0xC8FE # 0 +0xA197 0xC8FF # 0 +0xA198 0xC901 # 0 +0xA199 0xC902 # 0 +0xA19A 0xC903 # 0 +0xA19B 0xC907 # 0 +0xA19C 0xC908 # 0 +0xA19D 0xC909 # 0 +0xA19E 0xC90A # 0 +0xA19F 0xC90B # 0 +0xA1A0 0xC90E # 0 +0xA1A1 0x3000 # 0 +0xA1A2 0x3001 # 0 +0xA1A3 0x3002 # 0 +0xA1A4 0x00B7 # 0 +0xA1A5 0x2025 # 0 +0xA1A6 0x2026 # 0 +0xA1A7 0x00A8 # 0 +0xA1A8 0x3003 # 0 +0xA1A9 0x00AD # 0 +0xA1AA 0x2015 # 0 +0xA1AB 0x2225 # 0 +0xA1AC 0xFF3C # 0 +0xA1AD 0x223C # 0 +0xA1AE 0x2018 # 0 +0xA1AF 0x2019 # 0 +0xA1B0 0x201C # 0 +0xA1B1 0x201D # 0 +0xA1B2 0x3014 # 0 +0xA1B3 0x3015 # 0 +0xA1B4 0x3008 # 0 +0xA1B5 0x3009 # 0 +0xA1B6 0x300A # 0 +0xA1B7 0x300B # 0 +0xA1B8 0x300C # 0 +0xA1B9 0x300D # 0 +0xA1BA 0x300E # 0 +0xA1BB 0x300F # 0 +0xA1BC 0x3010 # 0 +0xA1BD 0x3011 # 0 +0xA1BE 0x00B1 # 0 +0xA1BF 0x00D7 # 0 +0xA1C0 0x00F7 # 0 +0xA1C1 0x2260 # 0 +0xA1C2 0x2264 # 0 +0xA1C3 0x2265 # 0 +0xA1C4 0x221E # 0 +0xA1C5 0x2234 # 0 +0xA1C6 0x00B0 # 0 +0xA1C7 0x2032 # 0 +0xA1C8 0x2033 # 0 +0xA1C9 0x2103 # 0 +0xA1CA 0x212B # 0 +0xA1CB 0xFFE0 # 0 +0xA1CC 0xFFE1 # 0 +0xA1CD 0xFFE5 # 0 +0xA1CE 0x2642 # 0 +0xA1CF 0x2640 # 0 +0xA1D0 0x2220 # 0 +0xA1D1 0x22A5 # 0 +0xA1D2 0x2312 # 0 +0xA1D3 0x2202 # 0 +0xA1D4 0x2207 # 0 +0xA1D5 0x2261 # 0 +0xA1D6 0x2252 # 0 +0xA1D7 0x00A7 # 0 +0xA1D8 0x203B # 0 +0xA1D9 0x2606 # 0 +0xA1DA 0x2605 # 0 +0xA1DB 0x25CB # 0 +0xA1DC 0x25CF # 0 +0xA1DD 0x25CE # 0 +0xA1DE 0x25C7 # 0 +0xA1DF 0x25C6 # 0 +0xA1E0 0x25A1 # 0 +0xA1E1 0x25A0 # 0 +0xA1E2 0x25B3 # 0 +0xA1E3 0x25B2 # 0 +0xA1E4 0x25BD # 0 +0xA1E5 0x25BC # 0 +0xA1E6 0x2192 # 0 +0xA1E7 0x2190 # 0 +0xA1E8 0x2191 # 0 +0xA1E9 0x2193 # 0 +0xA1EA 0x2194 # 0 +0xA1EB 0x3013 # 0 +0xA1EC 0x226A # 0 +0xA1ED 0x226B # 0 +0xA1EE 0x221A # 0 +0xA1EF 0x223D # 0 +0xA1F0 0x221D # 0 +0xA1F1 0x2235 # 0 +0xA1F2 0x222B # 0 +0xA1F3 0x222C # 0 +0xA1F4 0x2208 # 0 +0xA1F5 0x220B # 0 +0xA1F6 0x2286 # 0 +0xA1F7 0x2287 # 0 +0xA1F8 0x2282 # 0 +0xA1F9 0x2283 # 0 +0xA1FA 0x222A # 0 +0xA1FB 0x2229 # 0 +0xA1FC 0x2227 # 0 +0xA1FD 0x2228 # 0 +0xA1FE 0xFFE2 # 0 +0xA241 0xC910 # 0 +0xA242 0xC912 # 0 +0xA243 0xC913 # 0 +0xA244 0xC914 # 0 +0xA245 0xC915 # 0 +0xA246 0xC916 # 0 +0xA247 0xC917 # 0 +0xA248 0xC919 # 0 +0xA249 0xC91A # 0 +0xA24A 0xC91B # 0 +0xA24B 0xC91C # 0 +0xA24C 0xC91D # 0 +0xA24D 0xC91E # 0 +0xA24E 0xC91F # 0 +0xA24F 0xC920 # 0 +0xA250 0xC921 # 0 +0xA251 0xC922 # 0 +0xA252 0xC923 # 0 +0xA253 0xC924 # 0 +0xA254 0xC925 # 0 +0xA255 0xC926 # 0 +0xA256 0xC927 # 0 +0xA257 0xC928 # 0 +0xA258 0xC929 # 0 +0xA259 0xC92A # 0 +0xA25A 0xC92B # 0 +0xA261 0xC92D # 0 +0xA262 0xC92E # 0 +0xA263 0xC92F # 0 +0xA264 0xC930 # 0 +0xA265 0xC931 # 0 +0xA266 0xC932 # 0 +0xA267 0xC933 # 0 +0xA268 0xC935 # 0 +0xA269 0xC936 # 0 +0xA26A 0xC937 # 0 +0xA26B 0xC938 # 0 +0xA26C 0xC939 # 0 +0xA26D 0xC93A # 0 +0xA26E 0xC93B # 0 +0xA26F 0xC93C # 0 +0xA270 0xC93D # 0 +0xA271 0xC93E # 0 +0xA272 0xC93F # 0 +0xA273 0xC940 # 0 +0xA274 0xC941 # 0 +0xA275 0xC942 # 0 +0xA276 0xC943 # 0 +0xA277 0xC944 # 0 +0xA278 0xC945 # 0 +0xA279 0xC946 # 0 +0xA27A 0xC947 # 0 +0xA281 0xC948 # 0 +0xA282 0xC949 # 0 +0xA283 0xC94A # 0 +0xA284 0xC94B # 0 +0xA285 0xC94C # 0 +0xA286 0xC94D # 0 +0xA287 0xC94E # 0 +0xA288 0xC94F # 0 +0xA289 0xC952 # 0 +0xA28A 0xC953 # 0 +0xA28B 0xC955 # 0 +0xA28C 0xC956 # 0 +0xA28D 0xC957 # 0 +0xA28E 0xC959 # 0 +0xA28F 0xC95A # 0 +0xA290 0xC95B # 0 +0xA291 0xC95C # 0 +0xA292 0xC95D # 0 +0xA293 0xC95E # 0 +0xA294 0xC95F # 0 +0xA295 0xC962 # 0 +0xA296 0xC964 # 0 +0xA297 0xC965 # 0 +0xA298 0xC966 # 0 +0xA299 0xC967 # 0 +0xA29A 0xC968 # 0 +0xA29B 0xC969 # 0 +0xA29C 0xC96A # 0 +0xA29D 0xC96B # 0 +0xA29E 0xC96D # 0 +0xA29F 0xC96E # 0 +0xA2A0 0xC96F # 0 +0xA2A1 0x21D2 # 0 +0xA2A2 0x21D4 # 0 +0xA2A3 0x2200 # 0 +0xA2A4 0x2203 # 0 +0xA2A5 0x00B4 # 0 +0xA2A6 0xFF5E # 0 +0xA2A7 0x02C7 # 0 +0xA2A8 0x02D8 # 0 +0xA2A9 0x02DD # 0 +0xA2AA 0x02DA # 0 +0xA2AB 0x02D9 # 0 +0xA2AC 0x00B8 # 0 +0xA2AD 0x02DB # 0 +0xA2AE 0x00A1 # 0 +0xA2AF 0x00BF # 0 +0xA2B0 0x02D0 # 0 +0xA2B1 0x222E # 0 +0xA2B2 0x2211 # 0 +0xA2B3 0x220F # 0 +0xA2B4 0x00A4 # 0 +0xA2B5 0x2109 # 0 +0xA2B6 0x2030 # 0 +0xA2B7 0x25C1 # 0 +0xA2B8 0x25C0 # 0 +0xA2B9 0x25B7 # 0 +0xA2BA 0x25B6 # 0 +0xA2BB 0x2664 # 0 +0xA2BC 0x2660 # 0 +0xA2BD 0x2661 # 0 +0xA2BE 0x2665 # 0 +0xA2BF 0x2667 # 0 +0xA2C0 0x2663 # 0 +0xA2C1 0x2299 # 0 +0xA2C2 0x25C8 # 0 +0xA2C3 0x25A3 # 0 +0xA2C4 0x25D0 # 0 +0xA2C5 0x25D1 # 0 +0xA2C6 0x2592 # 0 +0xA2C7 0x25A4 # 0 +0xA2C8 0x25A5 # 0 +0xA2C9 0x25A8 # 0 +0xA2CA 0x25A7 # 0 +0xA2CB 0x25A6 # 0 +0xA2CC 0x25A9 # 0 +0xA2CD 0x2668 # 0 +0xA2CE 0x260F # 0 +0xA2CF 0x260E # 0 +0xA2D0 0x261C # 0 +0xA2D1 0x261E # 0 +0xA2D2 0x00B6 # 0 +0xA2D3 0x2020 # 0 +0xA2D4 0x2021 # 0 +0xA2D5 0x2195 # 0 +0xA2D6 0x2197 # 0 +0xA2D7 0x2199 # 0 +0xA2D8 0x2196 # 0 +0xA2D9 0x2198 # 0 +0xA2DA 0x266D # 0 +0xA2DB 0x2669 # 0 +0xA2DC 0x266A # 0 +0xA2DD 0x266C # 0 +0xA2DE 0x327F # 0 +0xA2DF 0x321C # 0 +0xA2E0 0x2116 # 0 +0xA2E1 0x33C7 # 0 +0xA2E2 0x2122 # 0 +0xA2E3 0x33C2 # 0 +0xA2E4 0x33D8 # 0 +0xA2E5 0x2121 # 0 +0xA2E6 0x20AC # 0 +0xA2E7 0x00AE # 0 +0xA341 0xC971 # 0 +0xA342 0xC972 # 0 +0xA343 0xC973 # 0 +0xA344 0xC975 # 0 +0xA345 0xC976 # 0 +0xA346 0xC977 # 0 +0xA347 0xC978 # 0 +0xA348 0xC979 # 0 +0xA349 0xC97A # 0 +0xA34A 0xC97B # 0 +0xA34B 0xC97D # 0 +0xA34C 0xC97E # 0 +0xA34D 0xC97F # 0 +0xA34E 0xC980 # 0 +0xA34F 0xC981 # 0 +0xA350 0xC982 # 0 +0xA351 0xC983 # 0 +0xA352 0xC984 # 0 +0xA353 0xC985 # 0 +0xA354 0xC986 # 0 +0xA355 0xC987 # 0 +0xA356 0xC98A # 0 +0xA357 0xC98B # 0 +0xA358 0xC98D # 0 +0xA359 0xC98E # 0 +0xA35A 0xC98F # 0 +0xA361 0xC991 # 0 +0xA362 0xC992 # 0 +0xA363 0xC993 # 0 +0xA364 0xC994 # 0 +0xA365 0xC995 # 0 +0xA366 0xC996 # 0 +0xA367 0xC997 # 0 +0xA368 0xC99A # 0 +0xA369 0xC99C # 0 +0xA36A 0xC99E # 0 +0xA36B 0xC99F # 0 +0xA36C 0xC9A0 # 0 +0xA36D 0xC9A1 # 0 +0xA36E 0xC9A2 # 0 +0xA36F 0xC9A3 # 0 +0xA370 0xC9A4 # 0 +0xA371 0xC9A5 # 0 +0xA372 0xC9A6 # 0 +0xA373 0xC9A7 # 0 +0xA374 0xC9A8 # 0 +0xA375 0xC9A9 # 0 +0xA376 0xC9AA # 0 +0xA377 0xC9AB # 0 +0xA378 0xC9AC # 0 +0xA379 0xC9AD # 0 +0xA37A 0xC9AE # 0 +0xA381 0xC9AF # 0 +0xA382 0xC9B0 # 0 +0xA383 0xC9B1 # 0 +0xA384 0xC9B2 # 0 +0xA385 0xC9B3 # 0 +0xA386 0xC9B4 # 0 +0xA387 0xC9B5 # 0 +0xA388 0xC9B6 # 0 +0xA389 0xC9B7 # 0 +0xA38A 0xC9B8 # 0 +0xA38B 0xC9B9 # 0 +0xA38C 0xC9BA # 0 +0xA38D 0xC9BB # 0 +0xA38E 0xC9BC # 0 +0xA38F 0xC9BD # 0 +0xA390 0xC9BE # 0 +0xA391 0xC9BF # 0 +0xA392 0xC9C2 # 0 +0xA393 0xC9C3 # 0 +0xA394 0xC9C5 # 0 +0xA395 0xC9C6 # 0 +0xA396 0xC9C9 # 0 +0xA397 0xC9CB # 0 +0xA398 0xC9CC # 0 +0xA399 0xC9CD # 0 +0xA39A 0xC9CE # 0 +0xA39B 0xC9CF # 0 +0xA39C 0xC9D2 # 0 +0xA39D 0xC9D4 # 0 +0xA39E 0xC9D7 # 0 +0xA39F 0xC9D8 # 0 +0xA3A0 0xC9DB # 0 +0xA3A1 0xFF01 # 0 +0xA3A2 0xFF02 # 0 +0xA3A3 0xFF03 # 0 +0xA3A4 0xFF04 # 0 +0xA3A5 0xFF05 # 0 +0xA3A6 0xFF06 # 0 +0xA3A7 0xFF07 # 0 +0xA3A8 0xFF08 # 0 +0xA3A9 0xFF09 # 0 +0xA3AA 0xFF0A # 0 +0xA3AB 0xFF0B # 0 +0xA3AC 0xFF0C # 0 +0xA3AD 0xFF0D # 0 +0xA3AE 0xFF0E # 0 +0xA3AF 0xFF0F # 0 +0xA3B0 0xFF10 # 0 +0xA3B1 0xFF11 # 0 +0xA3B2 0xFF12 # 0 +0xA3B3 0xFF13 # 0 +0xA3B4 0xFF14 # 0 +0xA3B5 0xFF15 # 0 +0xA3B6 0xFF16 # 0 +0xA3B7 0xFF17 # 0 +0xA3B8 0xFF18 # 0 +0xA3B9 0xFF19 # 0 +0xA3BA 0xFF1A # 0 +0xA3BB 0xFF1B # 0 +0xA3BC 0xFF1C # 0 +0xA3BD 0xFF1D # 0 +0xA3BE 0xFF1E # 0 +0xA3BF 0xFF1F # 0 +0xA3C0 0xFF20 # 0 +0xA3C1 0xFF21 # 0 +0xA3C2 0xFF22 # 0 +0xA3C3 0xFF23 # 0 +0xA3C4 0xFF24 # 0 +0xA3C5 0xFF25 # 0 +0xA3C6 0xFF26 # 0 +0xA3C7 0xFF27 # 0 +0xA3C8 0xFF28 # 0 +0xA3C9 0xFF29 # 0 +0xA3CA 0xFF2A # 0 +0xA3CB 0xFF2B # 0 +0xA3CC 0xFF2C # 0 +0xA3CD 0xFF2D # 0 +0xA3CE 0xFF2E # 0 +0xA3CF 0xFF2F # 0 +0xA3D0 0xFF30 # 0 +0xA3D1 0xFF31 # 0 +0xA3D2 0xFF32 # 0 +0xA3D3 0xFF33 # 0 +0xA3D4 0xFF34 # 0 +0xA3D5 0xFF35 # 0 +0xA3D6 0xFF36 # 0 +0xA3D7 0xFF37 # 0 +0xA3D8 0xFF38 # 0 +0xA3D9 0xFF39 # 0 +0xA3DA 0xFF3A # 0 +0xA3DB 0xFF3B # 0 +0xA3DC 0xFFE6 # 0 +0xA3DD 0xFF3D # 0 +0xA3DE 0xFF3E # 0 +0xA3DF 0xFF3F # 0 +0xA3E0 0xFF40 # 0 +0xA3E1 0xFF41 # 0 +0xA3E2 0xFF42 # 0 +0xA3E3 0xFF43 # 0 +0xA3E4 0xFF44 # 0 +0xA3E5 0xFF45 # 0 +0xA3E6 0xFF46 # 0 +0xA3E7 0xFF47 # 0 +0xA3E8 0xFF48 # 0 +0xA3E9 0xFF49 # 0 +0xA3EA 0xFF4A # 0 +0xA3EB 0xFF4B # 0 +0xA3EC 0xFF4C # 0 +0xA3ED 0xFF4D # 0 +0xA3EE 0xFF4E # 0 +0xA3EF 0xFF4F # 0 +0xA3F0 0xFF50 # 0 +0xA3F1 0xFF51 # 0 +0xA3F2 0xFF52 # 0 +0xA3F3 0xFF53 # 0 +0xA3F4 0xFF54 # 0 +0xA3F5 0xFF55 # 0 +0xA3F6 0xFF56 # 0 +0xA3F7 0xFF57 # 0 +0xA3F8 0xFF58 # 0 +0xA3F9 0xFF59 # 0 +0xA3FA 0xFF5A # 0 +0xA3FB 0xFF5B # 0 +0xA3FC 0xFF5C # 0 +0xA3FD 0xFF5D # 0 +0xA3FE 0xFFE3 # 0 +0xA441 0xC9DE # 0 +0xA442 0xC9DF # 0 +0xA443 0xC9E1 # 0 +0xA444 0xC9E3 # 0 +0xA445 0xC9E5 # 0 +0xA446 0xC9E6 # 0 +0xA447 0xC9E8 # 0 +0xA448 0xC9E9 # 0 +0xA449 0xC9EA # 0 +0xA44A 0xC9EB # 0 +0xA44B 0xC9EE # 0 +0xA44C 0xC9F2 # 0 +0xA44D 0xC9F3 # 0 +0xA44E 0xC9F4 # 0 +0xA44F 0xC9F5 # 0 +0xA450 0xC9F6 # 0 +0xA451 0xC9F7 # 0 +0xA452 0xC9FA # 0 +0xA453 0xC9FB # 0 +0xA454 0xC9FD # 0 +0xA455 0xC9FE # 0 +0xA456 0xC9FF # 0 +0xA457 0xCA01 # 0 +0xA458 0xCA02 # 0 +0xA459 0xCA03 # 0 +0xA45A 0xCA04 # 0 +0xA461 0xCA05 # 0 +0xA462 0xCA06 # 0 +0xA463 0xCA07 # 0 +0xA464 0xCA0A # 0 +0xA465 0xCA0E # 0 +0xA466 0xCA0F # 0 +0xA467 0xCA10 # 0 +0xA468 0xCA11 # 0 +0xA469 0xCA12 # 0 +0xA46A 0xCA13 # 0 +0xA46B 0xCA15 # 0 +0xA46C 0xCA16 # 0 +0xA46D 0xCA17 # 0 +0xA46E 0xCA19 # 0 +0xA46F 0xCA1A # 0 +0xA470 0xCA1B # 0 +0xA471 0xCA1C # 0 +0xA472 0xCA1D # 0 +0xA473 0xCA1E # 0 +0xA474 0xCA1F # 0 +0xA475 0xCA20 # 0 +0xA476 0xCA21 # 0 +0xA477 0xCA22 # 0 +0xA478 0xCA23 # 0 +0xA479 0xCA24 # 0 +0xA47A 0xCA25 # 0 +0xA481 0xCA26 # 0 +0xA482 0xCA27 # 0 +0xA483 0xCA28 # 0 +0xA484 0xCA2A # 0 +0xA485 0xCA2B # 0 +0xA486 0xCA2C # 0 +0xA487 0xCA2D # 0 +0xA488 0xCA2E # 0 +0xA489 0xCA2F # 0 +0xA48A 0xCA30 # 0 +0xA48B 0xCA31 # 0 +0xA48C 0xCA32 # 0 +0xA48D 0xCA33 # 0 +0xA48E 0xCA34 # 0 +0xA48F 0xCA35 # 0 +0xA490 0xCA36 # 0 +0xA491 0xCA37 # 0 +0xA492 0xCA38 # 0 +0xA493 0xCA39 # 0 +0xA494 0xCA3A # 0 +0xA495 0xCA3B # 0 +0xA496 0xCA3C # 0 +0xA497 0xCA3D # 0 +0xA498 0xCA3E # 0 +0xA499 0xCA3F # 0 +0xA49A 0xCA40 # 0 +0xA49B 0xCA41 # 0 +0xA49C 0xCA42 # 0 +0xA49D 0xCA43 # 0 +0xA49E 0xCA44 # 0 +0xA49F 0xCA45 # 0 +0xA4A0 0xCA46 # 0 +0xA4A1 0x3131 # 0 +0xA4A2 0x3132 # 0 +0xA4A3 0x3133 # 0 +0xA4A4 0x3134 # 0 +0xA4A5 0x3135 # 0 +0xA4A6 0x3136 # 0 +0xA4A7 0x3137 # 0 +0xA4A8 0x3138 # 0 +0xA4A9 0x3139 # 0 +0xA4AA 0x313A # 0 +0xA4AB 0x313B # 0 +0xA4AC 0x313C # 0 +0xA4AD 0x313D # 0 +0xA4AE 0x313E # 0 +0xA4AF 0x313F # 0 +0xA4B0 0x3140 # 0 +0xA4B1 0x3141 # 0 +0xA4B2 0x3142 # 0 +0xA4B3 0x3143 # 0 +0xA4B4 0x3144 # 0 +0xA4B5 0x3145 # 0 +0xA4B6 0x3146 # 0 +0xA4B7 0x3147 # 0 +0xA4B8 0x3148 # 0 +0xA4B9 0x3149 # 0 +0xA4BA 0x314A # 0 +0xA4BB 0x314B # 0 +0xA4BC 0x314C # 0 +0xA4BD 0x314D # 0 +0xA4BE 0x314E # 0 +0xA4BF 0x314F # 0 +0xA4C0 0x3150 # 0 +0xA4C1 0x3151 # 0 +0xA4C2 0x3152 # 0 +0xA4C3 0x3153 # 0 +0xA4C4 0x3154 # 0 +0xA4C5 0x3155 # 0 +0xA4C6 0x3156 # 0 +0xA4C7 0x3157 # 0 +0xA4C8 0x3158 # 0 +0xA4C9 0x3159 # 0 +0xA4CA 0x315A # 0 +0xA4CB 0x315B # 0 +0xA4CC 0x315C # 0 +0xA4CD 0x315D # 0 +0xA4CE 0x315E # 0 +0xA4CF 0x315F # 0 +0xA4D0 0x3160 # 0 +0xA4D1 0x3161 # 0 +0xA4D2 0x3162 # 0 +0xA4D3 0x3163 # 0 +0xA4D4 0x3164 # 0 +0xA4D5 0x3165 # 0 +0xA4D6 0x3166 # 0 +0xA4D7 0x3167 # 0 +0xA4D8 0x3168 # 0 +0xA4D9 0x3169 # 0 +0xA4DA 0x316A # 0 +0xA4DB 0x316B # 0 +0xA4DC 0x316C # 0 +0xA4DD 0x316D # 0 +0xA4DE 0x316E # 0 +0xA4DF 0x316F # 0 +0xA4E0 0x3170 # 0 +0xA4E1 0x3171 # 0 +0xA4E2 0x3172 # 0 +0xA4E3 0x3173 # 0 +0xA4E4 0x3174 # 0 +0xA4E5 0x3175 # 0 +0xA4E6 0x3176 # 0 +0xA4E7 0x3177 # 0 +0xA4E8 0x3178 # 0 +0xA4E9 0x3179 # 0 +0xA4EA 0x317A # 0 +0xA4EB 0x317B # 0 +0xA4EC 0x317C # 0 +0xA4ED 0x317D # 0 +0xA4EE 0x317E # 0 +0xA4EF 0x317F # 0 +0xA4F0 0x3180 # 0 +0xA4F1 0x3181 # 0 +0xA4F2 0x3182 # 0 +0xA4F3 0x3183 # 0 +0xA4F4 0x3184 # 0 +0xA4F5 0x3185 # 0 +0xA4F6 0x3186 # 0 +0xA4F7 0x3187 # 0 +0xA4F8 0x3188 # 0 +0xA4F9 0x3189 # 0 +0xA4FA 0x318A # 0 +0xA4FB 0x318B # 0 +0xA4FC 0x318C # 0 +0xA4FD 0x318D # 0 +0xA4FE 0x318E # 0 +0xA541 0xCA47 # 0 +0xA542 0xCA48 # 0 +0xA543 0xCA49 # 0 +0xA544 0xCA4A # 0 +0xA545 0xCA4B # 0 +0xA546 0xCA4E # 0 +0xA547 0xCA4F # 0 +0xA548 0xCA51 # 0 +0xA549 0xCA52 # 0 +0xA54A 0xCA53 # 0 +0xA54B 0xCA55 # 0 +0xA54C 0xCA56 # 0 +0xA54D 0xCA57 # 0 +0xA54E 0xCA58 # 0 +0xA54F 0xCA59 # 0 +0xA550 0xCA5A # 0 +0xA551 0xCA5B # 0 +0xA552 0xCA5E # 0 +0xA553 0xCA62 # 0 +0xA554 0xCA63 # 0 +0xA555 0xCA64 # 0 +0xA556 0xCA65 # 0 +0xA557 0xCA66 # 0 +0xA558 0xCA67 # 0 +0xA559 0xCA69 # 0 +0xA55A 0xCA6A # 0 +0xA561 0xCA6B # 0 +0xA562 0xCA6C # 0 +0xA563 0xCA6D # 0 +0xA564 0xCA6E # 0 +0xA565 0xCA6F # 0 +0xA566 0xCA70 # 0 +0xA567 0xCA71 # 0 +0xA568 0xCA72 # 0 +0xA569 0xCA73 # 0 +0xA56A 0xCA74 # 0 +0xA56B 0xCA75 # 0 +0xA56C 0xCA76 # 0 +0xA56D 0xCA77 # 0 +0xA56E 0xCA78 # 0 +0xA56F 0xCA79 # 0 +0xA570 0xCA7A # 0 +0xA571 0xCA7B # 0 +0xA572 0xCA7C # 0 +0xA573 0xCA7E # 0 +0xA574 0xCA7F # 0 +0xA575 0xCA80 # 0 +0xA576 0xCA81 # 0 +0xA577 0xCA82 # 0 +0xA578 0xCA83 # 0 +0xA579 0xCA85 # 0 +0xA57A 0xCA86 # 0 +0xA581 0xCA87 # 0 +0xA582 0xCA88 # 0 +0xA583 0xCA89 # 0 +0xA584 0xCA8A # 0 +0xA585 0xCA8B # 0 +0xA586 0xCA8C # 0 +0xA587 0xCA8D # 0 +0xA588 0xCA8E # 0 +0xA589 0xCA8F # 0 +0xA58A 0xCA90 # 0 +0xA58B 0xCA91 # 0 +0xA58C 0xCA92 # 0 +0xA58D 0xCA93 # 0 +0xA58E 0xCA94 # 0 +0xA58F 0xCA95 # 0 +0xA590 0xCA96 # 0 +0xA591 0xCA97 # 0 +0xA592 0xCA99 # 0 +0xA593 0xCA9A # 0 +0xA594 0xCA9B # 0 +0xA595 0xCA9C # 0 +0xA596 0xCA9D # 0 +0xA597 0xCA9E # 0 +0xA598 0xCA9F # 0 +0xA599 0xCAA0 # 0 +0xA59A 0xCAA1 # 0 +0xA59B 0xCAA2 # 0 +0xA59C 0xCAA3 # 0 +0xA59D 0xCAA4 # 0 +0xA59E 0xCAA5 # 0 +0xA59F 0xCAA6 # 0 +0xA5A0 0xCAA7 # 0 +0xA5A1 0x2170 # 0 +0xA5A2 0x2171 # 0 +0xA5A3 0x2172 # 0 +0xA5A4 0x2173 # 0 +0xA5A5 0x2174 # 0 +0xA5A6 0x2175 # 0 +0xA5A7 0x2176 # 0 +0xA5A8 0x2177 # 0 +0xA5A9 0x2178 # 0 +0xA5AA 0x2179 # 0 +0xA5B0 0x2160 # 0 +0xA5B1 0x2161 # 0 +0xA5B2 0x2162 # 0 +0xA5B3 0x2163 # 0 +0xA5B4 0x2164 # 0 +0xA5B5 0x2165 # 0 +0xA5B6 0x2166 # 0 +0xA5B7 0x2167 # 0 +0xA5B8 0x2168 # 0 +0xA5B9 0x2169 # 0 +0xA5C1 0x0391 # 0 +0xA5C2 0x0392 # 0 +0xA5C3 0x0393 # 0 +0xA5C4 0x0394 # 0 +0xA5C5 0x0395 # 0 +0xA5C6 0x0396 # 0 +0xA5C7 0x0397 # 0 +0xA5C8 0x0398 # 0 +0xA5C9 0x0399 # 0 +0xA5CA 0x039A # 0 +0xA5CB 0x039B # 0 +0xA5CC 0x039C # 0 +0xA5CD 0x039D # 0 +0xA5CE 0x039E # 0 +0xA5CF 0x039F # 0 +0xA5D0 0x03A0 # 0 +0xA5D1 0x03A1 # 0 +0xA5D2 0x03A3 # 0 +0xA5D3 0x03A4 # 0 +0xA5D4 0x03A5 # 0 +0xA5D5 0x03A6 # 0 +0xA5D6 0x03A7 # 0 +0xA5D7 0x03A8 # 0 +0xA5D8 0x03A9 # 0 +0xA5E1 0x03B1 # 0 +0xA5E2 0x03B2 # 0 +0xA5E3 0x03B3 # 0 +0xA5E4 0x03B4 # 0 +0xA5E5 0x03B5 # 0 +0xA5E6 0x03B6 # 0 +0xA5E7 0x03B7 # 0 +0xA5E8 0x03B8 # 0 +0xA5E9 0x03B9 # 0 +0xA5EA 0x03BA # 0 +0xA5EB 0x03BB # 0 +0xA5EC 0x03BC # 0 +0xA5ED 0x03BD # 0 +0xA5EE 0x03BE # 0 +0xA5EF 0x03BF # 0 +0xA5F0 0x03C0 # 0 +0xA5F1 0x03C1 # 0 +0xA5F2 0x03C3 # 0 +0xA5F3 0x03C4 # 0 +0xA5F4 0x03C5 # 0 +0xA5F5 0x03C6 # 0 +0xA5F6 0x03C7 # 0 +0xA5F7 0x03C8 # 0 +0xA5F8 0x03C9 # 0 +0xA641 0xCAA8 # 0 +0xA642 0xCAA9 # 0 +0xA643 0xCAAA # 0 +0xA644 0xCAAB # 0 +0xA645 0xCAAC # 0 +0xA646 0xCAAD # 0 +0xA647 0xCAAE # 0 +0xA648 0xCAAF # 0 +0xA649 0xCAB0 # 0 +0xA64A 0xCAB1 # 0 +0xA64B 0xCAB2 # 0 +0xA64C 0xCAB3 # 0 +0xA64D 0xCAB4 # 0 +0xA64E 0xCAB5 # 0 +0xA64F 0xCAB6 # 0 +0xA650 0xCAB7 # 0 +0xA651 0xCAB8 # 0 +0xA652 0xCAB9 # 0 +0xA653 0xCABA # 0 +0xA654 0xCABB # 0 +0xA655 0xCABE # 0 +0xA656 0xCABF # 0 +0xA657 0xCAC1 # 0 +0xA658 0xCAC2 # 0 +0xA659 0xCAC3 # 0 +0xA65A 0xCAC5 # 0 +0xA661 0xCAC6 # 0 +0xA662 0xCAC7 # 0 +0xA663 0xCAC8 # 0 +0xA664 0xCAC9 # 0 +0xA665 0xCACA # 0 +0xA666 0xCACB # 0 +0xA667 0xCACE # 0 +0xA668 0xCAD0 # 0 +0xA669 0xCAD2 # 0 +0xA66A 0xCAD4 # 0 +0xA66B 0xCAD5 # 0 +0xA66C 0xCAD6 # 0 +0xA66D 0xCAD7 # 0 +0xA66E 0xCADA # 0 +0xA66F 0xCADB # 0 +0xA670 0xCADC # 0 +0xA671 0xCADD # 0 +0xA672 0xCADE # 0 +0xA673 0xCADF # 0 +0xA674 0xCAE1 # 0 +0xA675 0xCAE2 # 0 +0xA676 0xCAE3 # 0 +0xA677 0xCAE4 # 0 +0xA678 0xCAE5 # 0 +0xA679 0xCAE6 # 0 +0xA67A 0xCAE7 # 0 +0xA681 0xCAE8 # 0 +0xA682 0xCAE9 # 0 +0xA683 0xCAEA # 0 +0xA684 0xCAEB # 0 +0xA685 0xCAED # 0 +0xA686 0xCAEE # 0 +0xA687 0xCAEF # 0 +0xA688 0xCAF0 # 0 +0xA689 0xCAF1 # 0 +0xA68A 0xCAF2 # 0 +0xA68B 0xCAF3 # 0 +0xA68C 0xCAF5 # 0 +0xA68D 0xCAF6 # 0 +0xA68E 0xCAF7 # 0 +0xA68F 0xCAF8 # 0 +0xA690 0xCAF9 # 0 +0xA691 0xCAFA # 0 +0xA692 0xCAFB # 0 +0xA693 0xCAFC # 0 +0xA694 0xCAFD # 0 +0xA695 0xCAFE # 0 +0xA696 0xCAFF # 0 +0xA697 0xCB00 # 0 +0xA698 0xCB01 # 0 +0xA699 0xCB02 # 0 +0xA69A 0xCB03 # 0 +0xA69B 0xCB04 # 0 +0xA69C 0xCB05 # 0 +0xA69D 0xCB06 # 0 +0xA69E 0xCB07 # 0 +0xA69F 0xCB09 # 0 +0xA6A0 0xCB0A # 0 +0xA6A1 0x2500 # 0 +0xA6A2 0x2502 # 0 +0xA6A3 0x250C # 0 +0xA6A4 0x2510 # 0 +0xA6A5 0x2518 # 0 +0xA6A6 0x2514 # 0 +0xA6A7 0x251C # 0 +0xA6A8 0x252C # 0 +0xA6A9 0x2524 # 0 +0xA6AA 0x2534 # 0 +0xA6AB 0x253C # 0 +0xA6AC 0x2501 # 0 +0xA6AD 0x2503 # 0 +0xA6AE 0x250F # 0 +0xA6AF 0x2513 # 0 +0xA6B0 0x251B # 0 +0xA6B1 0x2517 # 0 +0xA6B2 0x2523 # 0 +0xA6B3 0x2533 # 0 +0xA6B4 0x252B # 0 +0xA6B5 0x253B # 0 +0xA6B6 0x254B # 0 +0xA6B7 0x2520 # 0 +0xA6B8 0x252F # 0 +0xA6B9 0x2528 # 0 +0xA6BA 0x2537 # 0 +0xA6BB 0x253F # 0 +0xA6BC 0x251D # 0 +0xA6BD 0x2530 # 0 +0xA6BE 0x2525 # 0 +0xA6BF 0x2538 # 0 +0xA6C0 0x2542 # 0 +0xA6C1 0x2512 # 0 +0xA6C2 0x2511 # 0 +0xA6C3 0x251A # 0 +0xA6C4 0x2519 # 0 +0xA6C5 0x2516 # 0 +0xA6C6 0x2515 # 0 +0xA6C7 0x250E # 0 +0xA6C8 0x250D # 0 +0xA6C9 0x251E # 0 +0xA6CA 0x251F # 0 +0xA6CB 0x2521 # 0 +0xA6CC 0x2522 # 0 +0xA6CD 0x2526 # 0 +0xA6CE 0x2527 # 0 +0xA6CF 0x2529 # 0 +0xA6D0 0x252A # 0 +0xA6D1 0x252D # 0 +0xA6D2 0x252E # 0 +0xA6D3 0x2531 # 0 +0xA6D4 0x2532 # 0 +0xA6D5 0x2535 # 0 +0xA6D6 0x2536 # 0 +0xA6D7 0x2539 # 0 +0xA6D8 0x253A # 0 +0xA6D9 0x253D # 0 +0xA6DA 0x253E # 0 +0xA6DB 0x2540 # 0 +0xA6DC 0x2541 # 0 +0xA6DD 0x2543 # 0 +0xA6DE 0x2544 # 0 +0xA6DF 0x2545 # 0 +0xA6E0 0x2546 # 0 +0xA6E1 0x2547 # 0 +0xA6E2 0x2548 # 0 +0xA6E3 0x2549 # 0 +0xA6E4 0x254A # 0 +0xA741 0xCB0B # 0 +0xA742 0xCB0C # 0 +0xA743 0xCB0D # 0 +0xA744 0xCB0E # 0 +0xA745 0xCB0F # 0 +0xA746 0xCB11 # 0 +0xA747 0xCB12 # 0 +0xA748 0xCB13 # 0 +0xA749 0xCB15 # 0 +0xA74A 0xCB16 # 0 +0xA74B 0xCB17 # 0 +0xA74C 0xCB19 # 0 +0xA74D 0xCB1A # 0 +0xA74E 0xCB1B # 0 +0xA74F 0xCB1C # 0 +0xA750 0xCB1D # 0 +0xA751 0xCB1E # 0 +0xA752 0xCB1F # 0 +0xA753 0xCB22 # 0 +0xA754 0xCB23 # 0 +0xA755 0xCB24 # 0 +0xA756 0xCB25 # 0 +0xA757 0xCB26 # 0 +0xA758 0xCB27 # 0 +0xA759 0xCB28 # 0 +0xA75A 0xCB29 # 0 +0xA761 0xCB2A # 0 +0xA762 0xCB2B # 0 +0xA763 0xCB2C # 0 +0xA764 0xCB2D # 0 +0xA765 0xCB2E # 0 +0xA766 0xCB2F # 0 +0xA767 0xCB30 # 0 +0xA768 0xCB31 # 0 +0xA769 0xCB32 # 0 +0xA76A 0xCB33 # 0 +0xA76B 0xCB34 # 0 +0xA76C 0xCB35 # 0 +0xA76D 0xCB36 # 0 +0xA76E 0xCB37 # 0 +0xA76F 0xCB38 # 0 +0xA770 0xCB39 # 0 +0xA771 0xCB3A # 0 +0xA772 0xCB3B # 0 +0xA773 0xCB3C # 0 +0xA774 0xCB3D # 0 +0xA775 0xCB3E # 0 +0xA776 0xCB3F # 0 +0xA777 0xCB40 # 0 +0xA778 0xCB42 # 0 +0xA779 0xCB43 # 0 +0xA77A 0xCB44 # 0 +0xA781 0xCB45 # 0 +0xA782 0xCB46 # 0 +0xA783 0xCB47 # 0 +0xA784 0xCB4A # 0 +0xA785 0xCB4B # 0 +0xA786 0xCB4D # 0 +0xA787 0xCB4E # 0 +0xA788 0xCB4F # 0 +0xA789 0xCB51 # 0 +0xA78A 0xCB52 # 0 +0xA78B 0xCB53 # 0 +0xA78C 0xCB54 # 0 +0xA78D 0xCB55 # 0 +0xA78E 0xCB56 # 0 +0xA78F 0xCB57 # 0 +0xA790 0xCB5A # 0 +0xA791 0xCB5B # 0 +0xA792 0xCB5C # 0 +0xA793 0xCB5E # 0 +0xA794 0xCB5F # 0 +0xA795 0xCB60 # 0 +0xA796 0xCB61 # 0 +0xA797 0xCB62 # 0 +0xA798 0xCB63 # 0 +0xA799 0xCB65 # 0 +0xA79A 0xCB66 # 0 +0xA79B 0xCB67 # 0 +0xA79C 0xCB68 # 0 +0xA79D 0xCB69 # 0 +0xA79E 0xCB6A # 0 +0xA79F 0xCB6B # 0 +0xA7A0 0xCB6C # 0 +0xA7A1 0x3395 # 0 +0xA7A2 0x3396 # 0 +0xA7A3 0x3397 # 0 +0xA7A4 0x2113 # 0 +0xA7A5 0x3398 # 0 +0xA7A6 0x33C4 # 0 +0xA7A7 0x33A3 # 0 +0xA7A8 0x33A4 # 0 +0xA7A9 0x33A5 # 0 +0xA7AA 0x33A6 # 0 +0xA7AB 0x3399 # 0 +0xA7AC 0x339A # 0 +0xA7AD 0x339B # 0 +0xA7AE 0x339C # 0 +0xA7AF 0x339D # 0 +0xA7B0 0x339E # 0 +0xA7B1 0x339F # 0 +0xA7B2 0x33A0 # 0 +0xA7B3 0x33A1 # 0 +0xA7B4 0x33A2 # 0 +0xA7B5 0x33CA # 0 +0xA7B6 0x338D # 0 +0xA7B7 0x338E # 0 +0xA7B8 0x338F # 0 +0xA7B9 0x33CF # 0 +0xA7BA 0x3388 # 0 +0xA7BB 0x3389 # 0 +0xA7BC 0x33C8 # 0 +0xA7BD 0x33A7 # 0 +0xA7BE 0x33A8 # 0 +0xA7BF 0x33B0 # 0 +0xA7C0 0x33B1 # 0 +0xA7C1 0x33B2 # 0 +0xA7C2 0x33B3 # 0 +0xA7C3 0x33B4 # 0 +0xA7C4 0x33B5 # 0 +0xA7C5 0x33B6 # 0 +0xA7C6 0x33B7 # 0 +0xA7C7 0x33B8 # 0 +0xA7C8 0x33B9 # 0 +0xA7C9 0x3380 # 0 +0xA7CA 0x3381 # 0 +0xA7CB 0x3382 # 0 +0xA7CC 0x3383 # 0 +0xA7CD 0x3384 # 0 +0xA7CE 0x33BA # 0 +0xA7CF 0x33BB # 0 +0xA7D0 0x33BC # 0 +0xA7D1 0x33BD # 0 +0xA7D2 0x33BE # 0 +0xA7D3 0x33BF # 0 +0xA7D4 0x3390 # 0 +0xA7D5 0x3391 # 0 +0xA7D6 0x3392 # 0 +0xA7D7 0x3393 # 0 +0xA7D8 0x3394 # 0 +0xA7D9 0x2126 # 0 +0xA7DA 0x33C0 # 0 +0xA7DB 0x33C1 # 0 +0xA7DC 0x338A # 0 +0xA7DD 0x338B # 0 +0xA7DE 0x338C # 0 +0xA7DF 0x33D6 # 0 +0xA7E0 0x33C5 # 0 +0xA7E1 0x33AD # 0 +0xA7E2 0x33AE # 0 +0xA7E3 0x33AF # 0 +0xA7E4 0x33DB # 0 +0xA7E5 0x33A9 # 0 +0xA7E6 0x33AA # 0 +0xA7E7 0x33AB # 0 +0xA7E8 0x33AC # 0 +0xA7E9 0x33DD # 0 +0xA7EA 0x33D0 # 0 +0xA7EB 0x33D3 # 0 +0xA7EC 0x33C3 # 0 +0xA7ED 0x33C9 # 0 +0xA7EE 0x33DC # 0 +0xA7EF 0x33C6 # 0 +0xA841 0xCB6D # 0 +0xA842 0xCB6E # 0 +0xA843 0xCB6F # 0 +0xA844 0xCB70 # 0 +0xA845 0xCB71 # 0 +0xA846 0xCB72 # 0 +0xA847 0xCB73 # 0 +0xA848 0xCB74 # 0 +0xA849 0xCB75 # 0 +0xA84A 0xCB76 # 0 +0xA84B 0xCB77 # 0 +0xA84C 0xCB7A # 0 +0xA84D 0xCB7B # 0 +0xA84E 0xCB7C # 0 +0xA84F 0xCB7D # 0 +0xA850 0xCB7E # 0 +0xA851 0xCB7F # 0 +0xA852 0xCB80 # 0 +0xA853 0xCB81 # 0 +0xA854 0xCB82 # 0 +0xA855 0xCB83 # 0 +0xA856 0xCB84 # 0 +0xA857 0xCB85 # 0 +0xA858 0xCB86 # 0 +0xA859 0xCB87 # 0 +0xA85A 0xCB88 # 0 +0xA861 0xCB89 # 0 +0xA862 0xCB8A # 0 +0xA863 0xCB8B # 0 +0xA864 0xCB8C # 0 +0xA865 0xCB8D # 0 +0xA866 0xCB8E # 0 +0xA867 0xCB8F # 0 +0xA868 0xCB90 # 0 +0xA869 0xCB91 # 0 +0xA86A 0xCB92 # 0 +0xA86B 0xCB93 # 0 +0xA86C 0xCB94 # 0 +0xA86D 0xCB95 # 0 +0xA86E 0xCB96 # 0 +0xA86F 0xCB97 # 0 +0xA870 0xCB98 # 0 +0xA871 0xCB99 # 0 +0xA872 0xCB9A # 0 +0xA873 0xCB9B # 0 +0xA874 0xCB9D # 0 +0xA875 0xCB9E # 0 +0xA876 0xCB9F # 0 +0xA877 0xCBA0 # 0 +0xA878 0xCBA1 # 0 +0xA879 0xCBA2 # 0 +0xA87A 0xCBA3 # 0 +0xA881 0xCBA4 # 0 +0xA882 0xCBA5 # 0 +0xA883 0xCBA6 # 0 +0xA884 0xCBA7 # 0 +0xA885 0xCBA8 # 0 +0xA886 0xCBA9 # 0 +0xA887 0xCBAA # 0 +0xA888 0xCBAB # 0 +0xA889 0xCBAC # 0 +0xA88A 0xCBAD # 0 +0xA88B 0xCBAE # 0 +0xA88C 0xCBAF # 0 +0xA88D 0xCBB0 # 0 +0xA88E 0xCBB1 # 0 +0xA88F 0xCBB2 # 0 +0xA890 0xCBB3 # 0 +0xA891 0xCBB4 # 0 +0xA892 0xCBB5 # 0 +0xA893 0xCBB6 # 0 +0xA894 0xCBB7 # 0 +0xA895 0xCBB9 # 0 +0xA896 0xCBBA # 0 +0xA897 0xCBBB # 0 +0xA898 0xCBBC # 0 +0xA899 0xCBBD # 0 +0xA89A 0xCBBE # 0 +0xA89B 0xCBBF # 0 +0xA89C 0xCBC0 # 0 +0xA89D 0xCBC1 # 0 +0xA89E 0xCBC2 # 0 +0xA89F 0xCBC3 # 0 +0xA8A0 0xCBC4 # 0 +0xA8A1 0x00C6 # 0 +0xA8A2 0x00D0 # 0 +0xA8A3 0x00AA # 0 +0xA8A4 0x0126 # 0 +0xA8A6 0x0132 # 0 +0xA8A8 0x013F # 0 +0xA8A9 0x0141 # 0 +0xA8AA 0x00D8 # 0 +0xA8AB 0x0152 # 0 +0xA8AC 0x00BA # 0 +0xA8AD 0x00DE # 0 +0xA8AE 0x0166 # 0 +0xA8AF 0x014A # 0 +0xA8B1 0x3260 # 0 +0xA8B2 0x3261 # 0 +0xA8B3 0x3262 # 0 +0xA8B4 0x3263 # 0 +0xA8B5 0x3264 # 0 +0xA8B6 0x3265 # 0 +0xA8B7 0x3266 # 0 +0xA8B8 0x3267 # 0 +0xA8B9 0x3268 # 0 +0xA8BA 0x3269 # 0 +0xA8BB 0x326A # 0 +0xA8BC 0x326B # 0 +0xA8BD 0x326C # 0 +0xA8BE 0x326D # 0 +0xA8BF 0x326E # 0 +0xA8C0 0x326F # 0 +0xA8C1 0x3270 # 0 +0xA8C2 0x3271 # 0 +0xA8C3 0x3272 # 0 +0xA8C4 0x3273 # 0 +0xA8C5 0x3274 # 0 +0xA8C6 0x3275 # 0 +0xA8C7 0x3276 # 0 +0xA8C8 0x3277 # 0 +0xA8C9 0x3278 # 0 +0xA8CA 0x3279 # 0 +0xA8CB 0x327A # 0 +0xA8CC 0x327B # 0 +0xA8CD 0x24D0 # 0 +0xA8CE 0x24D1 # 0 +0xA8CF 0x24D2 # 0 +0xA8D0 0x24D3 # 0 +0xA8D1 0x24D4 # 0 +0xA8D2 0x24D5 # 0 +0xA8D3 0x24D6 # 0 +0xA8D4 0x24D7 # 0 +0xA8D5 0x24D8 # 0 +0xA8D6 0x24D9 # 0 +0xA8D7 0x24DA # 0 +0xA8D8 0x24DB # 0 +0xA8D9 0x24DC # 0 +0xA8DA 0x24DD # 0 +0xA8DB 0x24DE # 0 +0xA8DC 0x24DF # 0 +0xA8DD 0x24E0 # 0 +0xA8DE 0x24E1 # 0 +0xA8DF 0x24E2 # 0 +0xA8E0 0x24E3 # 0 +0xA8E1 0x24E4 # 0 +0xA8E2 0x24E5 # 0 +0xA8E3 0x24E6 # 0 +0xA8E4 0x24E7 # 0 +0xA8E5 0x24E8 # 0 +0xA8E6 0x24E9 # 0 +0xA8E7 0x2460 # 0 +0xA8E8 0x2461 # 0 +0xA8E9 0x2462 # 0 +0xA8EA 0x2463 # 0 +0xA8EB 0x2464 # 0 +0xA8EC 0x2465 # 0 +0xA8ED 0x2466 # 0 +0xA8EE 0x2467 # 0 +0xA8EF 0x2468 # 0 +0xA8F0 0x2469 # 0 +0xA8F1 0x246A # 0 +0xA8F2 0x246B # 0 +0xA8F3 0x246C # 0 +0xA8F4 0x246D # 0 +0xA8F5 0x246E # 0 +0xA8F6 0x00BD # 0 +0xA8F7 0x2153 # 0 +0xA8F8 0x2154 # 0 +0xA8F9 0x00BC # 0 +0xA8FA 0x00BE # 0 +0xA8FB 0x215B # 0 +0xA8FC 0x215C # 0 +0xA8FD 0x215D # 0 +0xA8FE 0x215E # 0 +0xA941 0xCBC5 # 0 +0xA942 0xCBC6 # 0 +0xA943 0xCBC7 # 0 +0xA944 0xCBC8 # 0 +0xA945 0xCBC9 # 0 +0xA946 0xCBCA # 0 +0xA947 0xCBCB # 0 +0xA948 0xCBCC # 0 +0xA949 0xCBCD # 0 +0xA94A 0xCBCE # 0 +0xA94B 0xCBCF # 0 +0xA94C 0xCBD0 # 0 +0xA94D 0xCBD1 # 0 +0xA94E 0xCBD2 # 0 +0xA94F 0xCBD3 # 0 +0xA950 0xCBD5 # 0 +0xA951 0xCBD6 # 0 +0xA952 0xCBD7 # 0 +0xA953 0xCBD8 # 0 +0xA954 0xCBD9 # 0 +0xA955 0xCBDA # 0 +0xA956 0xCBDB # 0 +0xA957 0xCBDC # 0 +0xA958 0xCBDD # 0 +0xA959 0xCBDE # 0 +0xA95A 0xCBDF # 0 +0xA961 0xCBE0 # 0 +0xA962 0xCBE1 # 0 +0xA963 0xCBE2 # 0 +0xA964 0xCBE3 # 0 +0xA965 0xCBE5 # 0 +0xA966 0xCBE6 # 0 +0xA967 0xCBE8 # 0 +0xA968 0xCBEA # 0 +0xA969 0xCBEB # 0 +0xA96A 0xCBEC # 0 +0xA96B 0xCBED # 0 +0xA96C 0xCBEE # 0 +0xA96D 0xCBEF # 0 +0xA96E 0xCBF0 # 0 +0xA96F 0xCBF1 # 0 +0xA970 0xCBF2 # 0 +0xA971 0xCBF3 # 0 +0xA972 0xCBF4 # 0 +0xA973 0xCBF5 # 0 +0xA974 0xCBF6 # 0 +0xA975 0xCBF7 # 0 +0xA976 0xCBF8 # 0 +0xA977 0xCBF9 # 0 +0xA978 0xCBFA # 0 +0xA979 0xCBFB # 0 +0xA97A 0xCBFC # 0 +0xA981 0xCBFD # 0 +0xA982 0xCBFE # 0 +0xA983 0xCBFF # 0 +0xA984 0xCC00 # 0 +0xA985 0xCC01 # 0 +0xA986 0xCC02 # 0 +0xA987 0xCC03 # 0 +0xA988 0xCC04 # 0 +0xA989 0xCC05 # 0 +0xA98A 0xCC06 # 0 +0xA98B 0xCC07 # 0 +0xA98C 0xCC08 # 0 +0xA98D 0xCC09 # 0 +0xA98E 0xCC0A # 0 +0xA98F 0xCC0B # 0 +0xA990 0xCC0E # 0 +0xA991 0xCC0F # 0 +0xA992 0xCC11 # 0 +0xA993 0xCC12 # 0 +0xA994 0xCC13 # 0 +0xA995 0xCC15 # 0 +0xA996 0xCC16 # 0 +0xA997 0xCC17 # 0 +0xA998 0xCC18 # 0 +0xA999 0xCC19 # 0 +0xA99A 0xCC1A # 0 +0xA99B 0xCC1B # 0 +0xA99C 0xCC1E # 0 +0xA99D 0xCC1F # 0 +0xA99E 0xCC20 # 0 +0xA99F 0xCC23 # 0 +0xA9A0 0xCC24 # 0 +0xA9A1 0x00E6 # 0 +0xA9A2 0x0111 # 0 +0xA9A3 0x00F0 # 0 +0xA9A4 0x0127 # 0 +0xA9A5 0x0131 # 0 +0xA9A6 0x0133 # 0 +0xA9A7 0x0138 # 0 +0xA9A8 0x0140 # 0 +0xA9A9 0x0142 # 0 +0xA9AA 0x00F8 # 0 +0xA9AB 0x0153 # 0 +0xA9AC 0x00DF # 0 +0xA9AD 0x00FE # 0 +0xA9AE 0x0167 # 0 +0xA9AF 0x014B # 0 +0xA9B0 0x0149 # 0 +0xA9B1 0x3200 # 0 +0xA9B2 0x3201 # 0 +0xA9B3 0x3202 # 0 +0xA9B4 0x3203 # 0 +0xA9B5 0x3204 # 0 +0xA9B6 0x3205 # 0 +0xA9B7 0x3206 # 0 +0xA9B8 0x3207 # 0 +0xA9B9 0x3208 # 0 +0xA9BA 0x3209 # 0 +0xA9BB 0x320A # 0 +0xA9BC 0x320B # 0 +0xA9BD 0x320C # 0 +0xA9BE 0x320D # 0 +0xA9BF 0x320E # 0 +0xA9C0 0x320F # 0 +0xA9C1 0x3210 # 0 +0xA9C2 0x3211 # 0 +0xA9C3 0x3212 # 0 +0xA9C4 0x3213 # 0 +0xA9C5 0x3214 # 0 +0xA9C6 0x3215 # 0 +0xA9C7 0x3216 # 0 +0xA9C8 0x3217 # 0 +0xA9C9 0x3218 # 0 +0xA9CA 0x3219 # 0 +0xA9CB 0x321A # 0 +0xA9CC 0x321B # 0 +0xA9CD 0x249C # 0 +0xA9CE 0x249D # 0 +0xA9CF 0x249E # 0 +0xA9D0 0x249F # 0 +0xA9D1 0x24A0 # 0 +0xA9D2 0x24A1 # 0 +0xA9D3 0x24A2 # 0 +0xA9D4 0x24A3 # 0 +0xA9D5 0x24A4 # 0 +0xA9D6 0x24A5 # 0 +0xA9D7 0x24A6 # 0 +0xA9D8 0x24A7 # 0 +0xA9D9 0x24A8 # 0 +0xA9DA 0x24A9 # 0 +0xA9DB 0x24AA # 0 +0xA9DC 0x24AB # 0 +0xA9DD 0x24AC # 0 +0xA9DE 0x24AD # 0 +0xA9DF 0x24AE # 0 +0xA9E0 0x24AF # 0 +0xA9E1 0x24B0 # 0 +0xA9E2 0x24B1 # 0 +0xA9E3 0x24B2 # 0 +0xA9E4 0x24B3 # 0 +0xA9E5 0x24B4 # 0 +0xA9E6 0x24B5 # 0 +0xA9E7 0x2474 # 0 +0xA9E8 0x2475 # 0 +0xA9E9 0x2476 # 0 +0xA9EA 0x2477 # 0 +0xA9EB 0x2478 # 0 +0xA9EC 0x2479 # 0 +0xA9ED 0x247A # 0 +0xA9EE 0x247B # 0 +0xA9EF 0x247C # 0 +0xA9F0 0x247D # 0 +0xA9F1 0x247E # 0 +0xA9F2 0x247F # 0 +0xA9F3 0x2480 # 0 +0xA9F4 0x2481 # 0 +0xA9F5 0x2482 # 0 +0xA9F6 0x00B9 # 0 +0xA9F7 0x00B2 # 0 +0xA9F8 0x00B3 # 0 +0xA9F9 0x2074 # 0 +0xA9FA 0x207F # 0 +0xA9FB 0x2081 # 0 +0xA9FC 0x2082 # 0 +0xA9FD 0x2083 # 0 +0xA9FE 0x2084 # 0 +0xAA41 0xCC25 # 0 +0xAA42 0xCC26 # 0 +0xAA43 0xCC2A # 0 +0xAA44 0xCC2B # 0 +0xAA45 0xCC2D # 0 +0xAA46 0xCC2F # 0 +0xAA47 0xCC31 # 0 +0xAA48 0xCC32 # 0 +0xAA49 0xCC33 # 0 +0xAA4A 0xCC34 # 0 +0xAA4B 0xCC35 # 0 +0xAA4C 0xCC36 # 0 +0xAA4D 0xCC37 # 0 +0xAA4E 0xCC3A # 0 +0xAA4F 0xCC3F # 0 +0xAA50 0xCC40 # 0 +0xAA51 0xCC41 # 0 +0xAA52 0xCC42 # 0 +0xAA53 0xCC43 # 0 +0xAA54 0xCC46 # 0 +0xAA55 0xCC47 # 0 +0xAA56 0xCC49 # 0 +0xAA57 0xCC4A # 0 +0xAA58 0xCC4B # 0 +0xAA59 0xCC4D # 0 +0xAA5A 0xCC4E # 0 +0xAA61 0xCC4F # 0 +0xAA62 0xCC50 # 0 +0xAA63 0xCC51 # 0 +0xAA64 0xCC52 # 0 +0xAA65 0xCC53 # 0 +0xAA66 0xCC56 # 0 +0xAA67 0xCC5A # 0 +0xAA68 0xCC5B # 0 +0xAA69 0xCC5C # 0 +0xAA6A 0xCC5D # 0 +0xAA6B 0xCC5E # 0 +0xAA6C 0xCC5F # 0 +0xAA6D 0xCC61 # 0 +0xAA6E 0xCC62 # 0 +0xAA6F 0xCC63 # 0 +0xAA70 0xCC65 # 0 +0xAA71 0xCC67 # 0 +0xAA72 0xCC69 # 0 +0xAA73 0xCC6A # 0 +0xAA74 0xCC6B # 0 +0xAA75 0xCC6C # 0 +0xAA76 0xCC6D # 0 +0xAA77 0xCC6E # 0 +0xAA78 0xCC6F # 0 +0xAA79 0xCC71 # 0 +0xAA7A 0xCC72 # 0 +0xAA81 0xCC73 # 0 +0xAA82 0xCC74 # 0 +0xAA83 0xCC76 # 0 +0xAA84 0xCC77 # 0 +0xAA85 0xCC78 # 0 +0xAA86 0xCC79 # 0 +0xAA87 0xCC7A # 0 +0xAA88 0xCC7B # 0 +0xAA89 0xCC7C # 0 +0xAA8A 0xCC7D # 0 +0xAA8B 0xCC7E # 0 +0xAA8C 0xCC7F # 0 +0xAA8D 0xCC80 # 0 +0xAA8E 0xCC81 # 0 +0xAA8F 0xCC82 # 0 +0xAA90 0xCC83 # 0 +0xAA91 0xCC84 # 0 +0xAA92 0xCC85 # 0 +0xAA93 0xCC86 # 0 +0xAA94 0xCC87 # 0 +0xAA95 0xCC88 # 0 +0xAA96 0xCC89 # 0 +0xAA97 0xCC8A # 0 +0xAA98 0xCC8B # 0 +0xAA99 0xCC8C # 0 +0xAA9A 0xCC8D # 0 +0xAA9B 0xCC8E # 0 +0xAA9C 0xCC8F # 0 +0xAA9D 0xCC90 # 0 +0xAA9E 0xCC91 # 0 +0xAA9F 0xCC92 # 0 +0xAAA0 0xCC93 # 0 +0xAAA1 0x3041 # 0 +0xAAA2 0x3042 # 0 +0xAAA3 0x3043 # 0 +0xAAA4 0x3044 # 0 +0xAAA5 0x3045 # 0 +0xAAA6 0x3046 # 0 +0xAAA7 0x3047 # 0 +0xAAA8 0x3048 # 0 +0xAAA9 0x3049 # 0 +0xAAAA 0x304A # 0 +0xAAAB 0x304B # 0 +0xAAAC 0x304C # 0 +0xAAAD 0x304D # 0 +0xAAAE 0x304E # 0 +0xAAAF 0x304F # 0 +0xAAB0 0x3050 # 0 +0xAAB1 0x3051 # 0 +0xAAB2 0x3052 # 0 +0xAAB3 0x3053 # 0 +0xAAB4 0x3054 # 0 +0xAAB5 0x3055 # 0 +0xAAB6 0x3056 # 0 +0xAAB7 0x3057 # 0 +0xAAB8 0x3058 # 0 +0xAAB9 0x3059 # 0 +0xAABA 0x305A # 0 +0xAABB 0x305B # 0 +0xAABC 0x305C # 0 +0xAABD 0x305D # 0 +0xAABE 0x305E # 0 +0xAABF 0x305F # 0 +0xAAC0 0x3060 # 0 +0xAAC1 0x3061 # 0 +0xAAC2 0x3062 # 0 +0xAAC3 0x3063 # 0 +0xAAC4 0x3064 # 0 +0xAAC5 0x3065 # 0 +0xAAC6 0x3066 # 0 +0xAAC7 0x3067 # 0 +0xAAC8 0x3068 # 0 +0xAAC9 0x3069 # 0 +0xAACA 0x306A # 0 +0xAACB 0x306B # 0 +0xAACC 0x306C # 0 +0xAACD 0x306D # 0 +0xAACE 0x306E # 0 +0xAACF 0x306F # 0 +0xAAD0 0x3070 # 0 +0xAAD1 0x3071 # 0 +0xAAD2 0x3072 # 0 +0xAAD3 0x3073 # 0 +0xAAD4 0x3074 # 0 +0xAAD5 0x3075 # 0 +0xAAD6 0x3076 # 0 +0xAAD7 0x3077 # 0 +0xAAD8 0x3078 # 0 +0xAAD9 0x3079 # 0 +0xAADA 0x307A # 0 +0xAADB 0x307B # 0 +0xAADC 0x307C # 0 +0xAADD 0x307D # 0 +0xAADE 0x307E # 0 +0xAADF 0x307F # 0 +0xAAE0 0x3080 # 0 +0xAAE1 0x3081 # 0 +0xAAE2 0x3082 # 0 +0xAAE3 0x3083 # 0 +0xAAE4 0x3084 # 0 +0xAAE5 0x3085 # 0 +0xAAE6 0x3086 # 0 +0xAAE7 0x3087 # 0 +0xAAE8 0x3088 # 0 +0xAAE9 0x3089 # 0 +0xAAEA 0x308A # 0 +0xAAEB 0x308B # 0 +0xAAEC 0x308C # 0 +0xAAED 0x308D # 0 +0xAAEE 0x308E # 0 +0xAAEF 0x308F # 0 +0xAAF0 0x3090 # 0 +0xAAF1 0x3091 # 0 +0xAAF2 0x3092 # 0 +0xAAF3 0x3093 # 0 +0xAB41 0xCC94 # 0 +0xAB42 0xCC95 # 0 +0xAB43 0xCC96 # 0 +0xAB44 0xCC97 # 0 +0xAB45 0xCC9A # 0 +0xAB46 0xCC9B # 0 +0xAB47 0xCC9D # 0 +0xAB48 0xCC9E # 0 +0xAB49 0xCC9F # 0 +0xAB4A 0xCCA1 # 0 +0xAB4B 0xCCA2 # 0 +0xAB4C 0xCCA3 # 0 +0xAB4D 0xCCA4 # 0 +0xAB4E 0xCCA5 # 0 +0xAB4F 0xCCA6 # 0 +0xAB50 0xCCA7 # 0 +0xAB51 0xCCAA # 0 +0xAB52 0xCCAE # 0 +0xAB53 0xCCAF # 0 +0xAB54 0xCCB0 # 0 +0xAB55 0xCCB1 # 0 +0xAB56 0xCCB2 # 0 +0xAB57 0xCCB3 # 0 +0xAB58 0xCCB6 # 0 +0xAB59 0xCCB7 # 0 +0xAB5A 0xCCB9 # 0 +0xAB61 0xCCBA # 0 +0xAB62 0xCCBB # 0 +0xAB63 0xCCBD # 0 +0xAB64 0xCCBE # 0 +0xAB65 0xCCBF # 0 +0xAB66 0xCCC0 # 0 +0xAB67 0xCCC1 # 0 +0xAB68 0xCCC2 # 0 +0xAB69 0xCCC3 # 0 +0xAB6A 0xCCC6 # 0 +0xAB6B 0xCCC8 # 0 +0xAB6C 0xCCCA # 0 +0xAB6D 0xCCCB # 0 +0xAB6E 0xCCCC # 0 +0xAB6F 0xCCCD # 0 +0xAB70 0xCCCE # 0 +0xAB71 0xCCCF # 0 +0xAB72 0xCCD1 # 0 +0xAB73 0xCCD2 # 0 +0xAB74 0xCCD3 # 0 +0xAB75 0xCCD5 # 0 +0xAB76 0xCCD6 # 0 +0xAB77 0xCCD7 # 0 +0xAB78 0xCCD8 # 0 +0xAB79 0xCCD9 # 0 +0xAB7A 0xCCDA # 0 +0xAB81 0xCCDB # 0 +0xAB82 0xCCDC # 0 +0xAB83 0xCCDD # 0 +0xAB84 0xCCDE # 0 +0xAB85 0xCCDF # 0 +0xAB86 0xCCE0 # 0 +0xAB87 0xCCE1 # 0 +0xAB88 0xCCE2 # 0 +0xAB89 0xCCE3 # 0 +0xAB8A 0xCCE5 # 0 +0xAB8B 0xCCE6 # 0 +0xAB8C 0xCCE7 # 0 +0xAB8D 0xCCE8 # 0 +0xAB8E 0xCCE9 # 0 +0xAB8F 0xCCEA # 0 +0xAB90 0xCCEB # 0 +0xAB91 0xCCED # 0 +0xAB92 0xCCEE # 0 +0xAB93 0xCCEF # 0 +0xAB94 0xCCF1 # 0 +0xAB95 0xCCF2 # 0 +0xAB96 0xCCF3 # 0 +0xAB97 0xCCF4 # 0 +0xAB98 0xCCF5 # 0 +0xAB99 0xCCF6 # 0 +0xAB9A 0xCCF7 # 0 +0xAB9B 0xCCF8 # 0 +0xAB9C 0xCCF9 # 0 +0xAB9D 0xCCFA # 0 +0xAB9E 0xCCFB # 0 +0xAB9F 0xCCFC # 0 +0xABA0 0xCCFD # 0 +0xABA1 0x30A1 # 0 +0xABA2 0x30A2 # 0 +0xABA3 0x30A3 # 0 +0xABA4 0x30A4 # 0 +0xABA5 0x30A5 # 0 +0xABA6 0x30A6 # 0 +0xABA7 0x30A7 # 0 +0xABA8 0x30A8 # 0 +0xABA9 0x30A9 # 0 +0xABAA 0x30AA # 0 +0xABAB 0x30AB # 0 +0xABAC 0x30AC # 0 +0xABAD 0x30AD # 0 +0xABAE 0x30AE # 0 +0xABAF 0x30AF # 0 +0xABB0 0x30B0 # 0 +0xABB1 0x30B1 # 0 +0xABB2 0x30B2 # 0 +0xABB3 0x30B3 # 0 +0xABB4 0x30B4 # 0 +0xABB5 0x30B5 # 0 +0xABB6 0x30B6 # 0 +0xABB7 0x30B7 # 0 +0xABB8 0x30B8 # 0 +0xABB9 0x30B9 # 0 +0xABBA 0x30BA # 0 +0xABBB 0x30BB # 0 +0xABBC 0x30BC # 0 +0xABBD 0x30BD # 0 +0xABBE 0x30BE # 0 +0xABBF 0x30BF # 0 +0xABC0 0x30C0 # 0 +0xABC1 0x30C1 # 0 +0xABC2 0x30C2 # 0 +0xABC3 0x30C3 # 0 +0xABC4 0x30C4 # 0 +0xABC5 0x30C5 # 0 +0xABC6 0x30C6 # 0 +0xABC7 0x30C7 # 0 +0xABC8 0x30C8 # 0 +0xABC9 0x30C9 # 0 +0xABCA 0x30CA # 0 +0xABCB 0x30CB # 0 +0xABCC 0x30CC # 0 +0xABCD 0x30CD # 0 +0xABCE 0x30CE # 0 +0xABCF 0x30CF # 0 +0xABD0 0x30D0 # 0 +0xABD1 0x30D1 # 0 +0xABD2 0x30D2 # 0 +0xABD3 0x30D3 # 0 +0xABD4 0x30D4 # 0 +0xABD5 0x30D5 # 0 +0xABD6 0x30D6 # 0 +0xABD7 0x30D7 # 0 +0xABD8 0x30D8 # 0 +0xABD9 0x30D9 # 0 +0xABDA 0x30DA # 0 +0xABDB 0x30DB # 0 +0xABDC 0x30DC # 0 +0xABDD 0x30DD # 0 +0xABDE 0x30DE # 0 +0xABDF 0x30DF # 0 +0xABE0 0x30E0 # 0 +0xABE1 0x30E1 # 0 +0xABE2 0x30E2 # 0 +0xABE3 0x30E3 # 0 +0xABE4 0x30E4 # 0 +0xABE5 0x30E5 # 0 +0xABE6 0x30E6 # 0 +0xABE7 0x30E7 # 0 +0xABE8 0x30E8 # 0 +0xABE9 0x30E9 # 0 +0xABEA 0x30EA # 0 +0xABEB 0x30EB # 0 +0xABEC 0x30EC # 0 +0xABED 0x30ED # 0 +0xABEE 0x30EE # 0 +0xABEF 0x30EF # 0 +0xABF0 0x30F0 # 0 +0xABF1 0x30F1 # 0 +0xABF2 0x30F2 # 0 +0xABF3 0x30F3 # 0 +0xABF4 0x30F4 # 0 +0xABF5 0x30F5 # 0 +0xABF6 0x30F6 # 0 +0xAC41 0xCCFE # 0 +0xAC42 0xCCFF # 0 +0xAC43 0xCD00 # 0 +0xAC44 0xCD02 # 0 +0xAC45 0xCD03 # 0 +0xAC46 0xCD04 # 0 +0xAC47 0xCD05 # 0 +0xAC48 0xCD06 # 0 +0xAC49 0xCD07 # 0 +0xAC4A 0xCD0A # 0 +0xAC4B 0xCD0B # 0 +0xAC4C 0xCD0D # 0 +0xAC4D 0xCD0E # 0 +0xAC4E 0xCD0F # 0 +0xAC4F 0xCD11 # 0 +0xAC50 0xCD12 # 0 +0xAC51 0xCD13 # 0 +0xAC52 0xCD14 # 0 +0xAC53 0xCD15 # 0 +0xAC54 0xCD16 # 0 +0xAC55 0xCD17 # 0 +0xAC56 0xCD1A # 0 +0xAC57 0xCD1C # 0 +0xAC58 0xCD1E # 0 +0xAC59 0xCD1F # 0 +0xAC5A 0xCD20 # 0 +0xAC61 0xCD21 # 0 +0xAC62 0xCD22 # 0 +0xAC63 0xCD23 # 0 +0xAC64 0xCD25 # 0 +0xAC65 0xCD26 # 0 +0xAC66 0xCD27 # 0 +0xAC67 0xCD29 # 0 +0xAC68 0xCD2A # 0 +0xAC69 0xCD2B # 0 +0xAC6A 0xCD2D # 0 +0xAC6B 0xCD2E # 0 +0xAC6C 0xCD2F # 0 +0xAC6D 0xCD30 # 0 +0xAC6E 0xCD31 # 0 +0xAC6F 0xCD32 # 0 +0xAC70 0xCD33 # 0 +0xAC71 0xCD34 # 0 +0xAC72 0xCD35 # 0 +0xAC73 0xCD36 # 0 +0xAC74 0xCD37 # 0 +0xAC75 0xCD38 # 0 +0xAC76 0xCD3A # 0 +0xAC77 0xCD3B # 0 +0xAC78 0xCD3C # 0 +0xAC79 0xCD3D # 0 +0xAC7A 0xCD3E # 0 +0xAC81 0xCD3F # 0 +0xAC82 0xCD40 # 0 +0xAC83 0xCD41 # 0 +0xAC84 0xCD42 # 0 +0xAC85 0xCD43 # 0 +0xAC86 0xCD44 # 0 +0xAC87 0xCD45 # 0 +0xAC88 0xCD46 # 0 +0xAC89 0xCD47 # 0 +0xAC8A 0xCD48 # 0 +0xAC8B 0xCD49 # 0 +0xAC8C 0xCD4A # 0 +0xAC8D 0xCD4B # 0 +0xAC8E 0xCD4C # 0 +0xAC8F 0xCD4D # 0 +0xAC90 0xCD4E # 0 +0xAC91 0xCD4F # 0 +0xAC92 0xCD50 # 0 +0xAC93 0xCD51 # 0 +0xAC94 0xCD52 # 0 +0xAC95 0xCD53 # 0 +0xAC96 0xCD54 # 0 +0xAC97 0xCD55 # 0 +0xAC98 0xCD56 # 0 +0xAC99 0xCD57 # 0 +0xAC9A 0xCD58 # 0 +0xAC9B 0xCD59 # 0 +0xAC9C 0xCD5A # 0 +0xAC9D 0xCD5B # 0 +0xAC9E 0xCD5D # 0 +0xAC9F 0xCD5E # 0 +0xACA0 0xCD5F # 0 +0xACA1 0x0410 # 0 +0xACA2 0x0411 # 0 +0xACA3 0x0412 # 0 +0xACA4 0x0413 # 0 +0xACA5 0x0414 # 0 +0xACA6 0x0415 # 0 +0xACA7 0x0401 # 0 +0xACA8 0x0416 # 0 +0xACA9 0x0417 # 0 +0xACAA 0x0418 # 0 +0xACAB 0x0419 # 0 +0xACAC 0x041A # 0 +0xACAD 0x041B # 0 +0xACAE 0x041C # 0 +0xACAF 0x041D # 0 +0xACB0 0x041E # 0 +0xACB1 0x041F # 0 +0xACB2 0x0420 # 0 +0xACB3 0x0421 # 0 +0xACB4 0x0422 # 0 +0xACB5 0x0423 # 0 +0xACB6 0x0424 # 0 +0xACB7 0x0425 # 0 +0xACB8 0x0426 # 0 +0xACB9 0x0427 # 0 +0xACBA 0x0428 # 0 +0xACBB 0x0429 # 0 +0xACBC 0x042A # 0 +0xACBD 0x042B # 0 +0xACBE 0x042C # 0 +0xACBF 0x042D # 0 +0xACC0 0x042E # 0 +0xACC1 0x042F # 0 +0xACD1 0x0430 # 0 +0xACD2 0x0431 # 0 +0xACD3 0x0432 # 0 +0xACD4 0x0433 # 0 +0xACD5 0x0434 # 0 +0xACD6 0x0435 # 0 +0xACD7 0x0451 # 0 +0xACD8 0x0436 # 0 +0xACD9 0x0437 # 0 +0xACDA 0x0438 # 0 +0xACDB 0x0439 # 0 +0xACDC 0x043A # 0 +0xACDD 0x043B # 0 +0xACDE 0x043C # 0 +0xACDF 0x043D # 0 +0xACE0 0x043E # 0 +0xACE1 0x043F # 0 +0xACE2 0x0440 # 0 +0xACE3 0x0441 # 0 +0xACE4 0x0442 # 0 +0xACE5 0x0443 # 0 +0xACE6 0x0444 # 0 +0xACE7 0x0445 # 0 +0xACE8 0x0446 # 0 +0xACE9 0x0447 # 0 +0xACEA 0x0448 # 0 +0xACEB 0x0449 # 0 +0xACEC 0x044A # 0 +0xACED 0x044B # 0 +0xACEE 0x044C # 0 +0xACEF 0x044D # 0 +0xACF0 0x044E # 0 +0xACF1 0x044F # 0 +0xAD41 0xCD61 # 0 +0xAD42 0xCD62 # 0 +0xAD43 0xCD63 # 0 +0xAD44 0xCD65 # 0 +0xAD45 0xCD66 # 0 +0xAD46 0xCD67 # 0 +0xAD47 0xCD68 # 0 +0xAD48 0xCD69 # 0 +0xAD49 0xCD6A # 0 +0xAD4A 0xCD6B # 0 +0xAD4B 0xCD6E # 0 +0xAD4C 0xCD70 # 0 +0xAD4D 0xCD72 # 0 +0xAD4E 0xCD73 # 0 +0xAD4F 0xCD74 # 0 +0xAD50 0xCD75 # 0 +0xAD51 0xCD76 # 0 +0xAD52 0xCD77 # 0 +0xAD53 0xCD79 # 0 +0xAD54 0xCD7A # 0 +0xAD55 0xCD7B # 0 +0xAD56 0xCD7C # 0 +0xAD57 0xCD7D # 0 +0xAD58 0xCD7E # 0 +0xAD59 0xCD7F # 0 +0xAD5A 0xCD80 # 0 +0xAD61 0xCD81 # 0 +0xAD62 0xCD82 # 0 +0xAD63 0xCD83 # 0 +0xAD64 0xCD84 # 0 +0xAD65 0xCD85 # 0 +0xAD66 0xCD86 # 0 +0xAD67 0xCD87 # 0 +0xAD68 0xCD89 # 0 +0xAD69 0xCD8A # 0 +0xAD6A 0xCD8B # 0 +0xAD6B 0xCD8C # 0 +0xAD6C 0xCD8D # 0 +0xAD6D 0xCD8E # 0 +0xAD6E 0xCD8F # 0 +0xAD6F 0xCD90 # 0 +0xAD70 0xCD91 # 0 +0xAD71 0xCD92 # 0 +0xAD72 0xCD93 # 0 +0xAD73 0xCD96 # 0 +0xAD74 0xCD97 # 0 +0xAD75 0xCD99 # 0 +0xAD76 0xCD9A # 0 +0xAD77 0xCD9B # 0 +0xAD78 0xCD9D # 0 +0xAD79 0xCD9E # 0 +0xAD7A 0xCD9F # 0 +0xAD81 0xCDA0 # 0 +0xAD82 0xCDA1 # 0 +0xAD83 0xCDA2 # 0 +0xAD84 0xCDA3 # 0 +0xAD85 0xCDA6 # 0 +0xAD86 0xCDA8 # 0 +0xAD87 0xCDAA # 0 +0xAD88 0xCDAB # 0 +0xAD89 0xCDAC # 0 +0xAD8A 0xCDAD # 0 +0xAD8B 0xCDAE # 0 +0xAD8C 0xCDAF # 0 +0xAD8D 0xCDB1 # 0 +0xAD8E 0xCDB2 # 0 +0xAD8F 0xCDB3 # 0 +0xAD90 0xCDB4 # 0 +0xAD91 0xCDB5 # 0 +0xAD92 0xCDB6 # 0 +0xAD93 0xCDB7 # 0 +0xAD94 0xCDB8 # 0 +0xAD95 0xCDB9 # 0 +0xAD96 0xCDBA # 0 +0xAD97 0xCDBB # 0 +0xAD98 0xCDBC # 0 +0xAD99 0xCDBD # 0 +0xAD9A 0xCDBE # 0 +0xAD9B 0xCDBF # 0 +0xAD9C 0xCDC0 # 0 +0xAD9D 0xCDC1 # 0 +0xAD9E 0xCDC2 # 0 +0xAD9F 0xCDC3 # 0 +0xADA0 0xCDC5 # 0 +0xAE41 0xCDC6 # 0 +0xAE42 0xCDC7 # 0 +0xAE43 0xCDC8 # 0 +0xAE44 0xCDC9 # 0 +0xAE45 0xCDCA # 0 +0xAE46 0xCDCB # 0 +0xAE47 0xCDCD # 0 +0xAE48 0xCDCE # 0 +0xAE49 0xCDCF # 0 +0xAE4A 0xCDD1 # 0 +0xAE4B 0xCDD2 # 0 +0xAE4C 0xCDD3 # 0 +0xAE4D 0xCDD4 # 0 +0xAE4E 0xCDD5 # 0 +0xAE4F 0xCDD6 # 0 +0xAE50 0xCDD7 # 0 +0xAE51 0xCDD8 # 0 +0xAE52 0xCDD9 # 0 +0xAE53 0xCDDA # 0 +0xAE54 0xCDDB # 0 +0xAE55 0xCDDC # 0 +0xAE56 0xCDDD # 0 +0xAE57 0xCDDE # 0 +0xAE58 0xCDDF # 0 +0xAE59 0xCDE0 # 0 +0xAE5A 0xCDE1 # 0 +0xAE61 0xCDE2 # 0 +0xAE62 0xCDE3 # 0 +0xAE63 0xCDE4 # 0 +0xAE64 0xCDE5 # 0 +0xAE65 0xCDE6 # 0 +0xAE66 0xCDE7 # 0 +0xAE67 0xCDE9 # 0 +0xAE68 0xCDEA # 0 +0xAE69 0xCDEB # 0 +0xAE6A 0xCDED # 0 +0xAE6B 0xCDEE # 0 +0xAE6C 0xCDEF # 0 +0xAE6D 0xCDF1 # 0 +0xAE6E 0xCDF2 # 0 +0xAE6F 0xCDF3 # 0 +0xAE70 0xCDF4 # 0 +0xAE71 0xCDF5 # 0 +0xAE72 0xCDF6 # 0 +0xAE73 0xCDF7 # 0 +0xAE74 0xCDFA # 0 +0xAE75 0xCDFC # 0 +0xAE76 0xCDFE # 0 +0xAE77 0xCDFF # 0 +0xAE78 0xCE00 # 0 +0xAE79 0xCE01 # 0 +0xAE7A 0xCE02 # 0 +0xAE81 0xCE03 # 0 +0xAE82 0xCE05 # 0 +0xAE83 0xCE06 # 0 +0xAE84 0xCE07 # 0 +0xAE85 0xCE09 # 0 +0xAE86 0xCE0A # 0 +0xAE87 0xCE0B # 0 +0xAE88 0xCE0D # 0 +0xAE89 0xCE0E # 0 +0xAE8A 0xCE0F # 0 +0xAE8B 0xCE10 # 0 +0xAE8C 0xCE11 # 0 +0xAE8D 0xCE12 # 0 +0xAE8E 0xCE13 # 0 +0xAE8F 0xCE15 # 0 +0xAE90 0xCE16 # 0 +0xAE91 0xCE17 # 0 +0xAE92 0xCE18 # 0 +0xAE93 0xCE1A # 0 +0xAE94 0xCE1B # 0 +0xAE95 0xCE1C # 0 +0xAE96 0xCE1D # 0 +0xAE97 0xCE1E # 0 +0xAE98 0xCE1F # 0 +0xAE99 0xCE22 # 0 +0xAE9A 0xCE23 # 0 +0xAE9B 0xCE25 # 0 +0xAE9C 0xCE26 # 0 +0xAE9D 0xCE27 # 0 +0xAE9E 0xCE29 # 0 +0xAE9F 0xCE2A # 0 +0xAEA0 0xCE2B # 0 +0xAF41 0xCE2C # 0 +0xAF42 0xCE2D # 0 +0xAF43 0xCE2E # 0 +0xAF44 0xCE2F # 0 +0xAF45 0xCE32 # 0 +0xAF46 0xCE34 # 0 +0xAF47 0xCE36 # 0 +0xAF48 0xCE37 # 0 +0xAF49 0xCE38 # 0 +0xAF4A 0xCE39 # 0 +0xAF4B 0xCE3A # 0 +0xAF4C 0xCE3B # 0 +0xAF4D 0xCE3C # 0 +0xAF4E 0xCE3D # 0 +0xAF4F 0xCE3E # 0 +0xAF50 0xCE3F # 0 +0xAF51 0xCE40 # 0 +0xAF52 0xCE41 # 0 +0xAF53 0xCE42 # 0 +0xAF54 0xCE43 # 0 +0xAF55 0xCE44 # 0 +0xAF56 0xCE45 # 0 +0xAF57 0xCE46 # 0 +0xAF58 0xCE47 # 0 +0xAF59 0xCE48 # 0 +0xAF5A 0xCE49 # 0 +0xAF61 0xCE4A # 0 +0xAF62 0xCE4B # 0 +0xAF63 0xCE4C # 0 +0xAF64 0xCE4D # 0 +0xAF65 0xCE4E # 0 +0xAF66 0xCE4F # 0 +0xAF67 0xCE50 # 0 +0xAF68 0xCE51 # 0 +0xAF69 0xCE52 # 0 +0xAF6A 0xCE53 # 0 +0xAF6B 0xCE54 # 0 +0xAF6C 0xCE55 # 0 +0xAF6D 0xCE56 # 0 +0xAF6E 0xCE57 # 0 +0xAF6F 0xCE5A # 0 +0xAF70 0xCE5B # 0 +0xAF71 0xCE5D # 0 +0xAF72 0xCE5E # 0 +0xAF73 0xCE62 # 0 +0xAF74 0xCE63 # 0 +0xAF75 0xCE64 # 0 +0xAF76 0xCE65 # 0 +0xAF77 0xCE66 # 0 +0xAF78 0xCE67 # 0 +0xAF79 0xCE6A # 0 +0xAF7A 0xCE6C # 0 +0xAF81 0xCE6E # 0 +0xAF82 0xCE6F # 0 +0xAF83 0xCE70 # 0 +0xAF84 0xCE71 # 0 +0xAF85 0xCE72 # 0 +0xAF86 0xCE73 # 0 +0xAF87 0xCE76 # 0 +0xAF88 0xCE77 # 0 +0xAF89 0xCE79 # 0 +0xAF8A 0xCE7A # 0 +0xAF8B 0xCE7B # 0 +0xAF8C 0xCE7D # 0 +0xAF8D 0xCE7E # 0 +0xAF8E 0xCE7F # 0 +0xAF8F 0xCE80 # 0 +0xAF90 0xCE81 # 0 +0xAF91 0xCE82 # 0 +0xAF92 0xCE83 # 0 +0xAF93 0xCE86 # 0 +0xAF94 0xCE88 # 0 +0xAF95 0xCE8A # 0 +0xAF96 0xCE8B # 0 +0xAF97 0xCE8C # 0 +0xAF98 0xCE8D # 0 +0xAF99 0xCE8E # 0 +0xAF9A 0xCE8F # 0 +0xAF9B 0xCE92 # 0 +0xAF9C 0xCE93 # 0 +0xAF9D 0xCE95 # 0 +0xAF9E 0xCE96 # 0 +0xAF9F 0xCE97 # 0 +0xAFA0 0xCE99 # 0 +0xB041 0xCE9A # 0 +0xB042 0xCE9B # 0 +0xB043 0xCE9C # 0 +0xB044 0xCE9D # 0 +0xB045 0xCE9E # 0 +0xB046 0xCE9F # 0 +0xB047 0xCEA2 # 0 +0xB048 0xCEA6 # 0 +0xB049 0xCEA7 # 0 +0xB04A 0xCEA8 # 0 +0xB04B 0xCEA9 # 0 +0xB04C 0xCEAA # 0 +0xB04D 0xCEAB # 0 +0xB04E 0xCEAE # 0 +0xB04F 0xCEAF # 0 +0xB050 0xCEB0 # 0 +0xB051 0xCEB1 # 0 +0xB052 0xCEB2 # 0 +0xB053 0xCEB3 # 0 +0xB054 0xCEB4 # 0 +0xB055 0xCEB5 # 0 +0xB056 0xCEB6 # 0 +0xB057 0xCEB7 # 0 +0xB058 0xCEB8 # 0 +0xB059 0xCEB9 # 0 +0xB05A 0xCEBA # 0 +0xB061 0xCEBB # 0 +0xB062 0xCEBC # 0 +0xB063 0xCEBD # 0 +0xB064 0xCEBE # 0 +0xB065 0xCEBF # 0 +0xB066 0xCEC0 # 0 +0xB067 0xCEC2 # 0 +0xB068 0xCEC3 # 0 +0xB069 0xCEC4 # 0 +0xB06A 0xCEC5 # 0 +0xB06B 0xCEC6 # 0 +0xB06C 0xCEC7 # 0 +0xB06D 0xCEC8 # 0 +0xB06E 0xCEC9 # 0 +0xB06F 0xCECA # 0 +0xB070 0xCECB # 0 +0xB071 0xCECC # 0 +0xB072 0xCECD # 0 +0xB073 0xCECE # 0 +0xB074 0xCECF # 0 +0xB075 0xCED0 # 0 +0xB076 0xCED1 # 0 +0xB077 0xCED2 # 0 +0xB078 0xCED3 # 0 +0xB079 0xCED4 # 0 +0xB07A 0xCED5 # 0 +0xB081 0xCED6 # 0 +0xB082 0xCED7 # 0 +0xB083 0xCED8 # 0 +0xB084 0xCED9 # 0 +0xB085 0xCEDA # 0 +0xB086 0xCEDB # 0 +0xB087 0xCEDC # 0 +0xB088 0xCEDD # 0 +0xB089 0xCEDE # 0 +0xB08A 0xCEDF # 0 +0xB08B 0xCEE0 # 0 +0xB08C 0xCEE1 # 0 +0xB08D 0xCEE2 # 0 +0xB08E 0xCEE3 # 0 +0xB08F 0xCEE6 # 0 +0xB090 0xCEE7 # 0 +0xB091 0xCEE9 # 0 +0xB092 0xCEEA # 0 +0xB093 0xCEED # 0 +0xB094 0xCEEE # 0 +0xB095 0xCEEF # 0 +0xB096 0xCEF0 # 0 +0xB097 0xCEF1 # 0 +0xB098 0xCEF2 # 0 +0xB099 0xCEF3 # 0 +0xB09A 0xCEF6 # 0 +0xB09B 0xCEFA # 0 +0xB09C 0xCEFB # 0 +0xB09D 0xCEFC # 0 +0xB09E 0xCEFD # 0 +0xB09F 0xCEFE # 0 +0xB0A0 0xCEFF # 0 +0xB0A1 0xAC00 # 0 +0xB0A2 0xAC01 # 0 +0xB0A3 0xAC04 # 0 +0xB0A4 0xAC07 # 0 +0xB0A5 0xAC08 # 0 +0xB0A6 0xAC09 # 0 +0xB0A7 0xAC0A # 0 +0xB0A8 0xAC10 # 0 +0xB0A9 0xAC11 # 0 +0xB0AA 0xAC12 # 0 +0xB0AB 0xAC13 # 0 +0xB0AC 0xAC14 # 0 +0xB0AD 0xAC15 # 0 +0xB0AE 0xAC16 # 0 +0xB0AF 0xAC17 # 0 +0xB0B0 0xAC19 # 0 +0xB0B1 0xAC1A # 0 +0xB0B2 0xAC1B # 0 +0xB0B3 0xAC1C # 0 +0xB0B4 0xAC1D # 0 +0xB0B5 0xAC20 # 0 +0xB0B6 0xAC24 # 0 +0xB0B7 0xAC2C # 0 +0xB0B8 0xAC2D # 0 +0xB0B9 0xAC2F # 0 +0xB0BA 0xAC30 # 0 +0xB0BB 0xAC31 # 0 +0xB0BC 0xAC38 # 0 +0xB0BD 0xAC39 # 0 +0xB0BE 0xAC3C # 0 +0xB0BF 0xAC40 # 0 +0xB0C0 0xAC4B # 0 +0xB0C1 0xAC4D # 0 +0xB0C2 0xAC54 # 0 +0xB0C3 0xAC58 # 0 +0xB0C4 0xAC5C # 0 +0xB0C5 0xAC70 # 0 +0xB0C6 0xAC71 # 0 +0xB0C7 0xAC74 # 0 +0xB0C8 0xAC77 # 0 +0xB0C9 0xAC78 # 0 +0xB0CA 0xAC7A # 0 +0xB0CB 0xAC80 # 0 +0xB0CC 0xAC81 # 0 +0xB0CD 0xAC83 # 0 +0xB0CE 0xAC84 # 0 +0xB0CF 0xAC85 # 0 +0xB0D0 0xAC86 # 0 +0xB0D1 0xAC89 # 0 +0xB0D2 0xAC8A # 0 +0xB0D3 0xAC8B # 0 +0xB0D4 0xAC8C # 0 +0xB0D5 0xAC90 # 0 +0xB0D6 0xAC94 # 0 +0xB0D7 0xAC9C # 0 +0xB0D8 0xAC9D # 0 +0xB0D9 0xAC9F # 0 +0xB0DA 0xACA0 # 0 +0xB0DB 0xACA1 # 0 +0xB0DC 0xACA8 # 0 +0xB0DD 0xACA9 # 0 +0xB0DE 0xACAA # 0 +0xB0DF 0xACAC # 0 +0xB0E0 0xACAF # 0 +0xB0E1 0xACB0 # 0 +0xB0E2 0xACB8 # 0 +0xB0E3 0xACB9 # 0 +0xB0E4 0xACBB # 0 +0xB0E5 0xACBC # 0 +0xB0E6 0xACBD # 0 +0xB0E7 0xACC1 # 0 +0xB0E8 0xACC4 # 0 +0xB0E9 0xACC8 # 0 +0xB0EA 0xACCC # 0 +0xB0EB 0xACD5 # 0 +0xB0EC 0xACD7 # 0 +0xB0ED 0xACE0 # 0 +0xB0EE 0xACE1 # 0 +0xB0EF 0xACE4 # 0 +0xB0F0 0xACE7 # 0 +0xB0F1 0xACE8 # 0 +0xB0F2 0xACEA # 0 +0xB0F3 0xACEC # 0 +0xB0F4 0xACEF # 0 +0xB0F5 0xACF0 # 0 +0xB0F6 0xACF1 # 0 +0xB0F7 0xACF3 # 0 +0xB0F8 0xACF5 # 0 +0xB0F9 0xACF6 # 0 +0xB0FA 0xACFC # 0 +0xB0FB 0xACFD # 0 +0xB0FC 0xAD00 # 0 +0xB0FD 0xAD04 # 0 +0xB0FE 0xAD06 # 0 +0xB141 0xCF02 # 0 +0xB142 0xCF03 # 0 +0xB143 0xCF05 # 0 +0xB144 0xCF06 # 0 +0xB145 0xCF07 # 0 +0xB146 0xCF09 # 0 +0xB147 0xCF0A # 0 +0xB148 0xCF0B # 0 +0xB149 0xCF0C # 0 +0xB14A 0xCF0D # 0 +0xB14B 0xCF0E # 0 +0xB14C 0xCF0F # 0 +0xB14D 0xCF12 # 0 +0xB14E 0xCF14 # 0 +0xB14F 0xCF16 # 0 +0xB150 0xCF17 # 0 +0xB151 0xCF18 # 0 +0xB152 0xCF19 # 0 +0xB153 0xCF1A # 0 +0xB154 0xCF1B # 0 +0xB155 0xCF1D # 0 +0xB156 0xCF1E # 0 +0xB157 0xCF1F # 0 +0xB158 0xCF21 # 0 +0xB159 0xCF22 # 0 +0xB15A 0xCF23 # 0 +0xB161 0xCF25 # 0 +0xB162 0xCF26 # 0 +0xB163 0xCF27 # 0 +0xB164 0xCF28 # 0 +0xB165 0xCF29 # 0 +0xB166 0xCF2A # 0 +0xB167 0xCF2B # 0 +0xB168 0xCF2E # 0 +0xB169 0xCF32 # 0 +0xB16A 0xCF33 # 0 +0xB16B 0xCF34 # 0 +0xB16C 0xCF35 # 0 +0xB16D 0xCF36 # 0 +0xB16E 0xCF37 # 0 +0xB16F 0xCF39 # 0 +0xB170 0xCF3A # 0 +0xB171 0xCF3B # 0 +0xB172 0xCF3C # 0 +0xB173 0xCF3D # 0 +0xB174 0xCF3E # 0 +0xB175 0xCF3F # 0 +0xB176 0xCF40 # 0 +0xB177 0xCF41 # 0 +0xB178 0xCF42 # 0 +0xB179 0xCF43 # 0 +0xB17A 0xCF44 # 0 +0xB181 0xCF45 # 0 +0xB182 0xCF46 # 0 +0xB183 0xCF47 # 0 +0xB184 0xCF48 # 0 +0xB185 0xCF49 # 0 +0xB186 0xCF4A # 0 +0xB187 0xCF4B # 0 +0xB188 0xCF4C # 0 +0xB189 0xCF4D # 0 +0xB18A 0xCF4E # 0 +0xB18B 0xCF4F # 0 +0xB18C 0xCF50 # 0 +0xB18D 0xCF51 # 0 +0xB18E 0xCF52 # 0 +0xB18F 0xCF53 # 0 +0xB190 0xCF56 # 0 +0xB191 0xCF57 # 0 +0xB192 0xCF59 # 0 +0xB193 0xCF5A # 0 +0xB194 0xCF5B # 0 +0xB195 0xCF5D # 0 +0xB196 0xCF5E # 0 +0xB197 0xCF5F # 0 +0xB198 0xCF60 # 0 +0xB199 0xCF61 # 0 +0xB19A 0xCF62 # 0 +0xB19B 0xCF63 # 0 +0xB19C 0xCF66 # 0 +0xB19D 0xCF68 # 0 +0xB19E 0xCF6A # 0 +0xB19F 0xCF6B # 0 +0xB1A0 0xCF6C # 0 +0xB1A1 0xAD0C # 0 +0xB1A2 0xAD0D # 0 +0xB1A3 0xAD0F # 0 +0xB1A4 0xAD11 # 0 +0xB1A5 0xAD18 # 0 +0xB1A6 0xAD1C # 0 +0xB1A7 0xAD20 # 0 +0xB1A8 0xAD29 # 0 +0xB1A9 0xAD2C # 0 +0xB1AA 0xAD2D # 0 +0xB1AB 0xAD34 # 0 +0xB1AC 0xAD35 # 0 +0xB1AD 0xAD38 # 0 +0xB1AE 0xAD3C # 0 +0xB1AF 0xAD44 # 0 +0xB1B0 0xAD45 # 0 +0xB1B1 0xAD47 # 0 +0xB1B2 0xAD49 # 0 +0xB1B3 0xAD50 # 0 +0xB1B4 0xAD54 # 0 +0xB1B5 0xAD58 # 0 +0xB1B6 0xAD61 # 0 +0xB1B7 0xAD63 # 0 +0xB1B8 0xAD6C # 0 +0xB1B9 0xAD6D # 0 +0xB1BA 0xAD70 # 0 +0xB1BB 0xAD73 # 0 +0xB1BC 0xAD74 # 0 +0xB1BD 0xAD75 # 0 +0xB1BE 0xAD76 # 0 +0xB1BF 0xAD7B # 0 +0xB1C0 0xAD7C # 0 +0xB1C1 0xAD7D # 0 +0xB1C2 0xAD7F # 0 +0xB1C3 0xAD81 # 0 +0xB1C4 0xAD82 # 0 +0xB1C5 0xAD88 # 0 +0xB1C6 0xAD89 # 0 +0xB1C7 0xAD8C # 0 +0xB1C8 0xAD90 # 0 +0xB1C9 0xAD9C # 0 +0xB1CA 0xAD9D # 0 +0xB1CB 0xADA4 # 0 +0xB1CC 0xADB7 # 0 +0xB1CD 0xADC0 # 0 +0xB1CE 0xADC1 # 0 +0xB1CF 0xADC4 # 0 +0xB1D0 0xADC8 # 0 +0xB1D1 0xADD0 # 0 +0xB1D2 0xADD1 # 0 +0xB1D3 0xADD3 # 0 +0xB1D4 0xADDC # 0 +0xB1D5 0xADE0 # 0 +0xB1D6 0xADE4 # 0 +0xB1D7 0xADF8 # 0 +0xB1D8 0xADF9 # 0 +0xB1D9 0xADFC # 0 +0xB1DA 0xADFF # 0 +0xB1DB 0xAE00 # 0 +0xB1DC 0xAE01 # 0 +0xB1DD 0xAE08 # 0 +0xB1DE 0xAE09 # 0 +0xB1DF 0xAE0B # 0 +0xB1E0 0xAE0D # 0 +0xB1E1 0xAE14 # 0 +0xB1E2 0xAE30 # 0 +0xB1E3 0xAE31 # 0 +0xB1E4 0xAE34 # 0 +0xB1E5 0xAE37 # 0 +0xB1E6 0xAE38 # 0 +0xB1E7 0xAE3A # 0 +0xB1E8 0xAE40 # 0 +0xB1E9 0xAE41 # 0 +0xB1EA 0xAE43 # 0 +0xB1EB 0xAE45 # 0 +0xB1EC 0xAE46 # 0 +0xB1ED 0xAE4A # 0 +0xB1EE 0xAE4C # 0 +0xB1EF 0xAE4D # 0 +0xB1F0 0xAE4E # 0 +0xB1F1 0xAE50 # 0 +0xB1F2 0xAE54 # 0 +0xB1F3 0xAE56 # 0 +0xB1F4 0xAE5C # 0 +0xB1F5 0xAE5D # 0 +0xB1F6 0xAE5F # 0 +0xB1F7 0xAE60 # 0 +0xB1F8 0xAE61 # 0 +0xB1F9 0xAE65 # 0 +0xB1FA 0xAE68 # 0 +0xB1FB 0xAE69 # 0 +0xB1FC 0xAE6C # 0 +0xB1FD 0xAE70 # 0 +0xB1FE 0xAE78 # 0 +0xB241 0xCF6D # 0 +0xB242 0xCF6E # 0 +0xB243 0xCF6F # 0 +0xB244 0xCF72 # 0 +0xB245 0xCF73 # 0 +0xB246 0xCF75 # 0 +0xB247 0xCF76 # 0 +0xB248 0xCF77 # 0 +0xB249 0xCF79 # 0 +0xB24A 0xCF7A # 0 +0xB24B 0xCF7B # 0 +0xB24C 0xCF7C # 0 +0xB24D 0xCF7D # 0 +0xB24E 0xCF7E # 0 +0xB24F 0xCF7F # 0 +0xB250 0xCF81 # 0 +0xB251 0xCF82 # 0 +0xB252 0xCF83 # 0 +0xB253 0xCF84 # 0 +0xB254 0xCF86 # 0 +0xB255 0xCF87 # 0 +0xB256 0xCF88 # 0 +0xB257 0xCF89 # 0 +0xB258 0xCF8A # 0 +0xB259 0xCF8B # 0 +0xB25A 0xCF8D # 0 +0xB261 0xCF8E # 0 +0xB262 0xCF8F # 0 +0xB263 0xCF90 # 0 +0xB264 0xCF91 # 0 +0xB265 0xCF92 # 0 +0xB266 0xCF93 # 0 +0xB267 0xCF94 # 0 +0xB268 0xCF95 # 0 +0xB269 0xCF96 # 0 +0xB26A 0xCF97 # 0 +0xB26B 0xCF98 # 0 +0xB26C 0xCF99 # 0 +0xB26D 0xCF9A # 0 +0xB26E 0xCF9B # 0 +0xB26F 0xCF9C # 0 +0xB270 0xCF9D # 0 +0xB271 0xCF9E # 0 +0xB272 0xCF9F # 0 +0xB273 0xCFA0 # 0 +0xB274 0xCFA2 # 0 +0xB275 0xCFA3 # 0 +0xB276 0xCFA4 # 0 +0xB277 0xCFA5 # 0 +0xB278 0xCFA6 # 0 +0xB279 0xCFA7 # 0 +0xB27A 0xCFA9 # 0 +0xB281 0xCFAA # 0 +0xB282 0xCFAB # 0 +0xB283 0xCFAC # 0 +0xB284 0xCFAD # 0 +0xB285 0xCFAE # 0 +0xB286 0xCFAF # 0 +0xB287 0xCFB1 # 0 +0xB288 0xCFB2 # 0 +0xB289 0xCFB3 # 0 +0xB28A 0xCFB4 # 0 +0xB28B 0xCFB5 # 0 +0xB28C 0xCFB6 # 0 +0xB28D 0xCFB7 # 0 +0xB28E 0xCFB8 # 0 +0xB28F 0xCFB9 # 0 +0xB290 0xCFBA # 0 +0xB291 0xCFBB # 0 +0xB292 0xCFBC # 0 +0xB293 0xCFBD # 0 +0xB294 0xCFBE # 0 +0xB295 0xCFBF # 0 +0xB296 0xCFC0 # 0 +0xB297 0xCFC1 # 0 +0xB298 0xCFC2 # 0 +0xB299 0xCFC3 # 0 +0xB29A 0xCFC5 # 0 +0xB29B 0xCFC6 # 0 +0xB29C 0xCFC7 # 0 +0xB29D 0xCFC8 # 0 +0xB29E 0xCFC9 # 0 +0xB29F 0xCFCA # 0 +0xB2A0 0xCFCB # 0 +0xB2A1 0xAE79 # 0 +0xB2A2 0xAE7B # 0 +0xB2A3 0xAE7C # 0 +0xB2A4 0xAE7D # 0 +0xB2A5 0xAE84 # 0 +0xB2A6 0xAE85 # 0 +0xB2A7 0xAE8C # 0 +0xB2A8 0xAEBC # 0 +0xB2A9 0xAEBD # 0 +0xB2AA 0xAEBE # 0 +0xB2AB 0xAEC0 # 0 +0xB2AC 0xAEC4 # 0 +0xB2AD 0xAECC # 0 +0xB2AE 0xAECD # 0 +0xB2AF 0xAECF # 0 +0xB2B0 0xAED0 # 0 +0xB2B1 0xAED1 # 0 +0xB2B2 0xAED8 # 0 +0xB2B3 0xAED9 # 0 +0xB2B4 0xAEDC # 0 +0xB2B5 0xAEE8 # 0 +0xB2B6 0xAEEB # 0 +0xB2B7 0xAEED # 0 +0xB2B8 0xAEF4 # 0 +0xB2B9 0xAEF8 # 0 +0xB2BA 0xAEFC # 0 +0xB2BB 0xAF07 # 0 +0xB2BC 0xAF08 # 0 +0xB2BD 0xAF0D # 0 +0xB2BE 0xAF10 # 0 +0xB2BF 0xAF2C # 0 +0xB2C0 0xAF2D # 0 +0xB2C1 0xAF30 # 0 +0xB2C2 0xAF32 # 0 +0xB2C3 0xAF34 # 0 +0xB2C4 0xAF3C # 0 +0xB2C5 0xAF3D # 0 +0xB2C6 0xAF3F # 0 +0xB2C7 0xAF41 # 0 +0xB2C8 0xAF42 # 0 +0xB2C9 0xAF43 # 0 +0xB2CA 0xAF48 # 0 +0xB2CB 0xAF49 # 0 +0xB2CC 0xAF50 # 0 +0xB2CD 0xAF5C # 0 +0xB2CE 0xAF5D # 0 +0xB2CF 0xAF64 # 0 +0xB2D0 0xAF65 # 0 +0xB2D1 0xAF79 # 0 +0xB2D2 0xAF80 # 0 +0xB2D3 0xAF84 # 0 +0xB2D4 0xAF88 # 0 +0xB2D5 0xAF90 # 0 +0xB2D6 0xAF91 # 0 +0xB2D7 0xAF95 # 0 +0xB2D8 0xAF9C # 0 +0xB2D9 0xAFB8 # 0 +0xB2DA 0xAFB9 # 0 +0xB2DB 0xAFBC # 0 +0xB2DC 0xAFC0 # 0 +0xB2DD 0xAFC7 # 0 +0xB2DE 0xAFC8 # 0 +0xB2DF 0xAFC9 # 0 +0xB2E0 0xAFCB # 0 +0xB2E1 0xAFCD # 0 +0xB2E2 0xAFCE # 0 +0xB2E3 0xAFD4 # 0 +0xB2E4 0xAFDC # 0 +0xB2E5 0xAFE8 # 0 +0xB2E6 0xAFE9 # 0 +0xB2E7 0xAFF0 # 0 +0xB2E8 0xAFF1 # 0 +0xB2E9 0xAFF4 # 0 +0xB2EA 0xAFF8 # 0 +0xB2EB 0xB000 # 0 +0xB2EC 0xB001 # 0 +0xB2ED 0xB004 # 0 +0xB2EE 0xB00C # 0 +0xB2EF 0xB010 # 0 +0xB2F0 0xB014 # 0 +0xB2F1 0xB01C # 0 +0xB2F2 0xB01D # 0 +0xB2F3 0xB028 # 0 +0xB2F4 0xB044 # 0 +0xB2F5 0xB045 # 0 +0xB2F6 0xB048 # 0 +0xB2F7 0xB04A # 0 +0xB2F8 0xB04C # 0 +0xB2F9 0xB04E # 0 +0xB2FA 0xB053 # 0 +0xB2FB 0xB054 # 0 +0xB2FC 0xB055 # 0 +0xB2FD 0xB057 # 0 +0xB2FE 0xB059 # 0 +0xB341 0xCFCC # 0 +0xB342 0xCFCD # 0 +0xB343 0xCFCE # 0 +0xB344 0xCFCF # 0 +0xB345 0xCFD0 # 0 +0xB346 0xCFD1 # 0 +0xB347 0xCFD2 # 0 +0xB348 0xCFD3 # 0 +0xB349 0xCFD4 # 0 +0xB34A 0xCFD5 # 0 +0xB34B 0xCFD6 # 0 +0xB34C 0xCFD7 # 0 +0xB34D 0xCFD8 # 0 +0xB34E 0xCFD9 # 0 +0xB34F 0xCFDA # 0 +0xB350 0xCFDB # 0 +0xB351 0xCFDC # 0 +0xB352 0xCFDD # 0 +0xB353 0xCFDE # 0 +0xB354 0xCFDF # 0 +0xB355 0xCFE2 # 0 +0xB356 0xCFE3 # 0 +0xB357 0xCFE5 # 0 +0xB358 0xCFE6 # 0 +0xB359 0xCFE7 # 0 +0xB35A 0xCFE9 # 0 +0xB361 0xCFEA # 0 +0xB362 0xCFEB # 0 +0xB363 0xCFEC # 0 +0xB364 0xCFED # 0 +0xB365 0xCFEE # 0 +0xB366 0xCFEF # 0 +0xB367 0xCFF2 # 0 +0xB368 0xCFF4 # 0 +0xB369 0xCFF6 # 0 +0xB36A 0xCFF7 # 0 +0xB36B 0xCFF8 # 0 +0xB36C 0xCFF9 # 0 +0xB36D 0xCFFA # 0 +0xB36E 0xCFFB # 0 +0xB36F 0xCFFD # 0 +0xB370 0xCFFE # 0 +0xB371 0xCFFF # 0 +0xB372 0xD001 # 0 +0xB373 0xD002 # 0 +0xB374 0xD003 # 0 +0xB375 0xD005 # 0 +0xB376 0xD006 # 0 +0xB377 0xD007 # 0 +0xB378 0xD008 # 0 +0xB379 0xD009 # 0 +0xB37A 0xD00A # 0 +0xB381 0xD00B # 0 +0xB382 0xD00C # 0 +0xB383 0xD00D # 0 +0xB384 0xD00E # 0 +0xB385 0xD00F # 0 +0xB386 0xD010 # 0 +0xB387 0xD012 # 0 +0xB388 0xD013 # 0 +0xB389 0xD014 # 0 +0xB38A 0xD015 # 0 +0xB38B 0xD016 # 0 +0xB38C 0xD017 # 0 +0xB38D 0xD019 # 0 +0xB38E 0xD01A # 0 +0xB38F 0xD01B # 0 +0xB390 0xD01C # 0 +0xB391 0xD01D # 0 +0xB392 0xD01E # 0 +0xB393 0xD01F # 0 +0xB394 0xD020 # 0 +0xB395 0xD021 # 0 +0xB396 0xD022 # 0 +0xB397 0xD023 # 0 +0xB398 0xD024 # 0 +0xB399 0xD025 # 0 +0xB39A 0xD026 # 0 +0xB39B 0xD027 # 0 +0xB39C 0xD028 # 0 +0xB39D 0xD029 # 0 +0xB39E 0xD02A # 0 +0xB39F 0xD02B # 0 +0xB3A0 0xD02C # 0 +0xB3A1 0xB05D # 0 +0xB3A2 0xB07C # 0 +0xB3A3 0xB07D # 0 +0xB3A4 0xB080 # 0 +0xB3A5 0xB084 # 0 +0xB3A6 0xB08C # 0 +0xB3A7 0xB08D # 0 +0xB3A8 0xB08F # 0 +0xB3A9 0xB091 # 0 +0xB3AA 0xB098 # 0 +0xB3AB 0xB099 # 0 +0xB3AC 0xB09A # 0 +0xB3AD 0xB09C # 0 +0xB3AE 0xB09F # 0 +0xB3AF 0xB0A0 # 0 +0xB3B0 0xB0A1 # 0 +0xB3B1 0xB0A2 # 0 +0xB3B2 0xB0A8 # 0 +0xB3B3 0xB0A9 # 0 +0xB3B4 0xB0AB # 0 +0xB3B5 0xB0AC # 0 +0xB3B6 0xB0AD # 0 +0xB3B7 0xB0AE # 0 +0xB3B8 0xB0AF # 0 +0xB3B9 0xB0B1 # 0 +0xB3BA 0xB0B3 # 0 +0xB3BB 0xB0B4 # 0 +0xB3BC 0xB0B5 # 0 +0xB3BD 0xB0B8 # 0 +0xB3BE 0xB0BC # 0 +0xB3BF 0xB0C4 # 0 +0xB3C0 0xB0C5 # 0 +0xB3C1 0xB0C7 # 0 +0xB3C2 0xB0C8 # 0 +0xB3C3 0xB0C9 # 0 +0xB3C4 0xB0D0 # 0 +0xB3C5 0xB0D1 # 0 +0xB3C6 0xB0D4 # 0 +0xB3C7 0xB0D8 # 0 +0xB3C8 0xB0E0 # 0 +0xB3C9 0xB0E5 # 0 +0xB3CA 0xB108 # 0 +0xB3CB 0xB109 # 0 +0xB3CC 0xB10B # 0 +0xB3CD 0xB10C # 0 +0xB3CE 0xB110 # 0 +0xB3CF 0xB112 # 0 +0xB3D0 0xB113 # 0 +0xB3D1 0xB118 # 0 +0xB3D2 0xB119 # 0 +0xB3D3 0xB11B # 0 +0xB3D4 0xB11C # 0 +0xB3D5 0xB11D # 0 +0xB3D6 0xB123 # 0 +0xB3D7 0xB124 # 0 +0xB3D8 0xB125 # 0 +0xB3D9 0xB128 # 0 +0xB3DA 0xB12C # 0 +0xB3DB 0xB134 # 0 +0xB3DC 0xB135 # 0 +0xB3DD 0xB137 # 0 +0xB3DE 0xB138 # 0 +0xB3DF 0xB139 # 0 +0xB3E0 0xB140 # 0 +0xB3E1 0xB141 # 0 +0xB3E2 0xB144 # 0 +0xB3E3 0xB148 # 0 +0xB3E4 0xB150 # 0 +0xB3E5 0xB151 # 0 +0xB3E6 0xB154 # 0 +0xB3E7 0xB155 # 0 +0xB3E8 0xB158 # 0 +0xB3E9 0xB15C # 0 +0xB3EA 0xB160 # 0 +0xB3EB 0xB178 # 0 +0xB3EC 0xB179 # 0 +0xB3ED 0xB17C # 0 +0xB3EE 0xB180 # 0 +0xB3EF 0xB182 # 0 +0xB3F0 0xB188 # 0 +0xB3F1 0xB189 # 0 +0xB3F2 0xB18B # 0 +0xB3F3 0xB18D # 0 +0xB3F4 0xB192 # 0 +0xB3F5 0xB193 # 0 +0xB3F6 0xB194 # 0 +0xB3F7 0xB198 # 0 +0xB3F8 0xB19C # 0 +0xB3F9 0xB1A8 # 0 +0xB3FA 0xB1CC # 0 +0xB3FB 0xB1D0 # 0 +0xB3FC 0xB1D4 # 0 +0xB3FD 0xB1DC # 0 +0xB3FE 0xB1DD # 0 +0xB441 0xD02E # 0 +0xB442 0xD02F # 0 +0xB443 0xD030 # 0 +0xB444 0xD031 # 0 +0xB445 0xD032 # 0 +0xB446 0xD033 # 0 +0xB447 0xD036 # 0 +0xB448 0xD037 # 0 +0xB449 0xD039 # 0 +0xB44A 0xD03A # 0 +0xB44B 0xD03B # 0 +0xB44C 0xD03D # 0 +0xB44D 0xD03E # 0 +0xB44E 0xD03F # 0 +0xB44F 0xD040 # 0 +0xB450 0xD041 # 0 +0xB451 0xD042 # 0 +0xB452 0xD043 # 0 +0xB453 0xD046 # 0 +0xB454 0xD048 # 0 +0xB455 0xD04A # 0 +0xB456 0xD04B # 0 +0xB457 0xD04C # 0 +0xB458 0xD04D # 0 +0xB459 0xD04E # 0 +0xB45A 0xD04F # 0 +0xB461 0xD051 # 0 +0xB462 0xD052 # 0 +0xB463 0xD053 # 0 +0xB464 0xD055 # 0 +0xB465 0xD056 # 0 +0xB466 0xD057 # 0 +0xB467 0xD059 # 0 +0xB468 0xD05A # 0 +0xB469 0xD05B # 0 +0xB46A 0xD05C # 0 +0xB46B 0xD05D # 0 +0xB46C 0xD05E # 0 +0xB46D 0xD05F # 0 +0xB46E 0xD061 # 0 +0xB46F 0xD062 # 0 +0xB470 0xD063 # 0 +0xB471 0xD064 # 0 +0xB472 0xD065 # 0 +0xB473 0xD066 # 0 +0xB474 0xD067 # 0 +0xB475 0xD068 # 0 +0xB476 0xD069 # 0 +0xB477 0xD06A # 0 +0xB478 0xD06B # 0 +0xB479 0xD06E # 0 +0xB47A 0xD06F # 0 +0xB481 0xD071 # 0 +0xB482 0xD072 # 0 +0xB483 0xD073 # 0 +0xB484 0xD075 # 0 +0xB485 0xD076 # 0 +0xB486 0xD077 # 0 +0xB487 0xD078 # 0 +0xB488 0xD079 # 0 +0xB489 0xD07A # 0 +0xB48A 0xD07B # 0 +0xB48B 0xD07E # 0 +0xB48C 0xD07F # 0 +0xB48D 0xD080 # 0 +0xB48E 0xD082 # 0 +0xB48F 0xD083 # 0 +0xB490 0xD084 # 0 +0xB491 0xD085 # 0 +0xB492 0xD086 # 0 +0xB493 0xD087 # 0 +0xB494 0xD088 # 0 +0xB495 0xD089 # 0 +0xB496 0xD08A # 0 +0xB497 0xD08B # 0 +0xB498 0xD08C # 0 +0xB499 0xD08D # 0 +0xB49A 0xD08E # 0 +0xB49B 0xD08F # 0 +0xB49C 0xD090 # 0 +0xB49D 0xD091 # 0 +0xB49E 0xD092 # 0 +0xB49F 0xD093 # 0 +0xB4A0 0xD094 # 0 +0xB4A1 0xB1DF # 0 +0xB4A2 0xB1E8 # 0 +0xB4A3 0xB1E9 # 0 +0xB4A4 0xB1EC # 0 +0xB4A5 0xB1F0 # 0 +0xB4A6 0xB1F9 # 0 +0xB4A7 0xB1FB # 0 +0xB4A8 0xB1FD # 0 +0xB4A9 0xB204 # 0 +0xB4AA 0xB205 # 0 +0xB4AB 0xB208 # 0 +0xB4AC 0xB20B # 0 +0xB4AD 0xB20C # 0 +0xB4AE 0xB214 # 0 +0xB4AF 0xB215 # 0 +0xB4B0 0xB217 # 0 +0xB4B1 0xB219 # 0 +0xB4B2 0xB220 # 0 +0xB4B3 0xB234 # 0 +0xB4B4 0xB23C # 0 +0xB4B5 0xB258 # 0 +0xB4B6 0xB25C # 0 +0xB4B7 0xB260 # 0 +0xB4B8 0xB268 # 0 +0xB4B9 0xB269 # 0 +0xB4BA 0xB274 # 0 +0xB4BB 0xB275 # 0 +0xB4BC 0xB27C # 0 +0xB4BD 0xB284 # 0 +0xB4BE 0xB285 # 0 +0xB4BF 0xB289 # 0 +0xB4C0 0xB290 # 0 +0xB4C1 0xB291 # 0 +0xB4C2 0xB294 # 0 +0xB4C3 0xB298 # 0 +0xB4C4 0xB299 # 0 +0xB4C5 0xB29A # 0 +0xB4C6 0xB2A0 # 0 +0xB4C7 0xB2A1 # 0 +0xB4C8 0xB2A3 # 0 +0xB4C9 0xB2A5 # 0 +0xB4CA 0xB2A6 # 0 +0xB4CB 0xB2AA # 0 +0xB4CC 0xB2AC # 0 +0xB4CD 0xB2B0 # 0 +0xB4CE 0xB2B4 # 0 +0xB4CF 0xB2C8 # 0 +0xB4D0 0xB2C9 # 0 +0xB4D1 0xB2CC # 0 +0xB4D2 0xB2D0 # 0 +0xB4D3 0xB2D2 # 0 +0xB4D4 0xB2D8 # 0 +0xB4D5 0xB2D9 # 0 +0xB4D6 0xB2DB # 0 +0xB4D7 0xB2DD # 0 +0xB4D8 0xB2E2 # 0 +0xB4D9 0xB2E4 # 0 +0xB4DA 0xB2E5 # 0 +0xB4DB 0xB2E6 # 0 +0xB4DC 0xB2E8 # 0 +0xB4DD 0xB2EB # 0 +0xB4DE 0xB2EC # 0 +0xB4DF 0xB2ED # 0 +0xB4E0 0xB2EE # 0 +0xB4E1 0xB2EF # 0 +0xB4E2 0xB2F3 # 0 +0xB4E3 0xB2F4 # 0 +0xB4E4 0xB2F5 # 0 +0xB4E5 0xB2F7 # 0 +0xB4E6 0xB2F8 # 0 +0xB4E7 0xB2F9 # 0 +0xB4E8 0xB2FA # 0 +0xB4E9 0xB2FB # 0 +0xB4EA 0xB2FF # 0 +0xB4EB 0xB300 # 0 +0xB4EC 0xB301 # 0 +0xB4ED 0xB304 # 0 +0xB4EE 0xB308 # 0 +0xB4EF 0xB310 # 0 +0xB4F0 0xB311 # 0 +0xB4F1 0xB313 # 0 +0xB4F2 0xB314 # 0 +0xB4F3 0xB315 # 0 +0xB4F4 0xB31C # 0 +0xB4F5 0xB354 # 0 +0xB4F6 0xB355 # 0 +0xB4F7 0xB356 # 0 +0xB4F8 0xB358 # 0 +0xB4F9 0xB35B # 0 +0xB4FA 0xB35C # 0 +0xB4FB 0xB35E # 0 +0xB4FC 0xB35F # 0 +0xB4FD 0xB364 # 0 +0xB4FE 0xB365 # 0 +0xB541 0xD095 # 0 +0xB542 0xD096 # 0 +0xB543 0xD097 # 0 +0xB544 0xD098 # 0 +0xB545 0xD099 # 0 +0xB546 0xD09A # 0 +0xB547 0xD09B # 0 +0xB548 0xD09C # 0 +0xB549 0xD09D # 0 +0xB54A 0xD09E # 0 +0xB54B 0xD09F # 0 +0xB54C 0xD0A0 # 0 +0xB54D 0xD0A1 # 0 +0xB54E 0xD0A2 # 0 +0xB54F 0xD0A3 # 0 +0xB550 0xD0A6 # 0 +0xB551 0xD0A7 # 0 +0xB552 0xD0A9 # 0 +0xB553 0xD0AA # 0 +0xB554 0xD0AB # 0 +0xB555 0xD0AD # 0 +0xB556 0xD0AE # 0 +0xB557 0xD0AF # 0 +0xB558 0xD0B0 # 0 +0xB559 0xD0B1 # 0 +0xB55A 0xD0B2 # 0 +0xB561 0xD0B3 # 0 +0xB562 0xD0B6 # 0 +0xB563 0xD0B8 # 0 +0xB564 0xD0BA # 0 +0xB565 0xD0BB # 0 +0xB566 0xD0BC # 0 +0xB567 0xD0BD # 0 +0xB568 0xD0BE # 0 +0xB569 0xD0BF # 0 +0xB56A 0xD0C2 # 0 +0xB56B 0xD0C3 # 0 +0xB56C 0xD0C5 # 0 +0xB56D 0xD0C6 # 0 +0xB56E 0xD0C7 # 0 +0xB56F 0xD0CA # 0 +0xB570 0xD0CB # 0 +0xB571 0xD0CC # 0 +0xB572 0xD0CD # 0 +0xB573 0xD0CE # 0 +0xB574 0xD0CF # 0 +0xB575 0xD0D2 # 0 +0xB576 0xD0D6 # 0 +0xB577 0xD0D7 # 0 +0xB578 0xD0D8 # 0 +0xB579 0xD0D9 # 0 +0xB57A 0xD0DA # 0 +0xB581 0xD0DB # 0 +0xB582 0xD0DE # 0 +0xB583 0xD0DF # 0 +0xB584 0xD0E1 # 0 +0xB585 0xD0E2 # 0 +0xB586 0xD0E3 # 0 +0xB587 0xD0E5 # 0 +0xB588 0xD0E6 # 0 +0xB589 0xD0E7 # 0 +0xB58A 0xD0E8 # 0 +0xB58B 0xD0E9 # 0 +0xB58C 0xD0EA # 0 +0xB58D 0xD0EB # 0 +0xB58E 0xD0EE # 0 +0xB58F 0xD0F2 # 0 +0xB590 0xD0F3 # 0 +0xB591 0xD0F4 # 0 +0xB592 0xD0F5 # 0 +0xB593 0xD0F6 # 0 +0xB594 0xD0F7 # 0 +0xB595 0xD0F9 # 0 +0xB596 0xD0FA # 0 +0xB597 0xD0FB # 0 +0xB598 0xD0FC # 0 +0xB599 0xD0FD # 0 +0xB59A 0xD0FE # 0 +0xB59B 0xD0FF # 0 +0xB59C 0xD100 # 0 +0xB59D 0xD101 # 0 +0xB59E 0xD102 # 0 +0xB59F 0xD103 # 0 +0xB5A0 0xD104 # 0 +0xB5A1 0xB367 # 0 +0xB5A2 0xB369 # 0 +0xB5A3 0xB36B # 0 +0xB5A4 0xB36E # 0 +0xB5A5 0xB370 # 0 +0xB5A6 0xB371 # 0 +0xB5A7 0xB374 # 0 +0xB5A8 0xB378 # 0 +0xB5A9 0xB380 # 0 +0xB5AA 0xB381 # 0 +0xB5AB 0xB383 # 0 +0xB5AC 0xB384 # 0 +0xB5AD 0xB385 # 0 +0xB5AE 0xB38C # 0 +0xB5AF 0xB390 # 0 +0xB5B0 0xB394 # 0 +0xB5B1 0xB3A0 # 0 +0xB5B2 0xB3A1 # 0 +0xB5B3 0xB3A8 # 0 +0xB5B4 0xB3AC # 0 +0xB5B5 0xB3C4 # 0 +0xB5B6 0xB3C5 # 0 +0xB5B7 0xB3C8 # 0 +0xB5B8 0xB3CB # 0 +0xB5B9 0xB3CC # 0 +0xB5BA 0xB3CE # 0 +0xB5BB 0xB3D0 # 0 +0xB5BC 0xB3D4 # 0 +0xB5BD 0xB3D5 # 0 +0xB5BE 0xB3D7 # 0 +0xB5BF 0xB3D9 # 0 +0xB5C0 0xB3DB # 0 +0xB5C1 0xB3DD # 0 +0xB5C2 0xB3E0 # 0 +0xB5C3 0xB3E4 # 0 +0xB5C4 0xB3E8 # 0 +0xB5C5 0xB3FC # 0 +0xB5C6 0xB410 # 0 +0xB5C7 0xB418 # 0 +0xB5C8 0xB41C # 0 +0xB5C9 0xB420 # 0 +0xB5CA 0xB428 # 0 +0xB5CB 0xB429 # 0 +0xB5CC 0xB42B # 0 +0xB5CD 0xB434 # 0 +0xB5CE 0xB450 # 0 +0xB5CF 0xB451 # 0 +0xB5D0 0xB454 # 0 +0xB5D1 0xB458 # 0 +0xB5D2 0xB460 # 0 +0xB5D3 0xB461 # 0 +0xB5D4 0xB463 # 0 +0xB5D5 0xB465 # 0 +0xB5D6 0xB46C # 0 +0xB5D7 0xB480 # 0 +0xB5D8 0xB488 # 0 +0xB5D9 0xB49D # 0 +0xB5DA 0xB4A4 # 0 +0xB5DB 0xB4A8 # 0 +0xB5DC 0xB4AC # 0 +0xB5DD 0xB4B5 # 0 +0xB5DE 0xB4B7 # 0 +0xB5DF 0xB4B9 # 0 +0xB5E0 0xB4C0 # 0 +0xB5E1 0xB4C4 # 0 +0xB5E2 0xB4C8 # 0 +0xB5E3 0xB4D0 # 0 +0xB5E4 0xB4D5 # 0 +0xB5E5 0xB4DC # 0 +0xB5E6 0xB4DD # 0 +0xB5E7 0xB4E0 # 0 +0xB5E8 0xB4E3 # 0 +0xB5E9 0xB4E4 # 0 +0xB5EA 0xB4E6 # 0 +0xB5EB 0xB4EC # 0 +0xB5EC 0xB4ED # 0 +0xB5ED 0xB4EF # 0 +0xB5EE 0xB4F1 # 0 +0xB5EF 0xB4F8 # 0 +0xB5F0 0xB514 # 0 +0xB5F1 0xB515 # 0 +0xB5F2 0xB518 # 0 +0xB5F3 0xB51B # 0 +0xB5F4 0xB51C # 0 +0xB5F5 0xB524 # 0 +0xB5F6 0xB525 # 0 +0xB5F7 0xB527 # 0 +0xB5F8 0xB528 # 0 +0xB5F9 0xB529 # 0 +0xB5FA 0xB52A # 0 +0xB5FB 0xB530 # 0 +0xB5FC 0xB531 # 0 +0xB5FD 0xB534 # 0 +0xB5FE 0xB538 # 0 +0xB641 0xD105 # 0 +0xB642 0xD106 # 0 +0xB643 0xD107 # 0 +0xB644 0xD108 # 0 +0xB645 0xD109 # 0 +0xB646 0xD10A # 0 +0xB647 0xD10B # 0 +0xB648 0xD10C # 0 +0xB649 0xD10E # 0 +0xB64A 0xD10F # 0 +0xB64B 0xD110 # 0 +0xB64C 0xD111 # 0 +0xB64D 0xD112 # 0 +0xB64E 0xD113 # 0 +0xB64F 0xD114 # 0 +0xB650 0xD115 # 0 +0xB651 0xD116 # 0 +0xB652 0xD117 # 0 +0xB653 0xD118 # 0 +0xB654 0xD119 # 0 +0xB655 0xD11A # 0 +0xB656 0xD11B # 0 +0xB657 0xD11C # 0 +0xB658 0xD11D # 0 +0xB659 0xD11E # 0 +0xB65A 0xD11F # 0 +0xB661 0xD120 # 0 +0xB662 0xD121 # 0 +0xB663 0xD122 # 0 +0xB664 0xD123 # 0 +0xB665 0xD124 # 0 +0xB666 0xD125 # 0 +0xB667 0xD126 # 0 +0xB668 0xD127 # 0 +0xB669 0xD128 # 0 +0xB66A 0xD129 # 0 +0xB66B 0xD12A # 0 +0xB66C 0xD12B # 0 +0xB66D 0xD12C # 0 +0xB66E 0xD12D # 0 +0xB66F 0xD12E # 0 +0xB670 0xD12F # 0 +0xB671 0xD132 # 0 +0xB672 0xD133 # 0 +0xB673 0xD135 # 0 +0xB674 0xD136 # 0 +0xB675 0xD137 # 0 +0xB676 0xD139 # 0 +0xB677 0xD13B # 0 +0xB678 0xD13C # 0 +0xB679 0xD13D # 0 +0xB67A 0xD13E # 0 +0xB681 0xD13F # 0 +0xB682 0xD142 # 0 +0xB683 0xD146 # 0 +0xB684 0xD147 # 0 +0xB685 0xD148 # 0 +0xB686 0xD149 # 0 +0xB687 0xD14A # 0 +0xB688 0xD14B # 0 +0xB689 0xD14E # 0 +0xB68A 0xD14F # 0 +0xB68B 0xD151 # 0 +0xB68C 0xD152 # 0 +0xB68D 0xD153 # 0 +0xB68E 0xD155 # 0 +0xB68F 0xD156 # 0 +0xB690 0xD157 # 0 +0xB691 0xD158 # 0 +0xB692 0xD159 # 0 +0xB693 0xD15A # 0 +0xB694 0xD15B # 0 +0xB695 0xD15E # 0 +0xB696 0xD160 # 0 +0xB697 0xD162 # 0 +0xB698 0xD163 # 0 +0xB699 0xD164 # 0 +0xB69A 0xD165 # 0 +0xB69B 0xD166 # 0 +0xB69C 0xD167 # 0 +0xB69D 0xD169 # 0 +0xB69E 0xD16A # 0 +0xB69F 0xD16B # 0 +0xB6A0 0xD16D # 0 +0xB6A1 0xB540 # 0 +0xB6A2 0xB541 # 0 +0xB6A3 0xB543 # 0 +0xB6A4 0xB544 # 0 +0xB6A5 0xB545 # 0 +0xB6A6 0xB54B # 0 +0xB6A7 0xB54C # 0 +0xB6A8 0xB54D # 0 +0xB6A9 0xB550 # 0 +0xB6AA 0xB554 # 0 +0xB6AB 0xB55C # 0 +0xB6AC 0xB55D # 0 +0xB6AD 0xB55F # 0 +0xB6AE 0xB560 # 0 +0xB6AF 0xB561 # 0 +0xB6B0 0xB5A0 # 0 +0xB6B1 0xB5A1 # 0 +0xB6B2 0xB5A4 # 0 +0xB6B3 0xB5A8 # 0 +0xB6B4 0xB5AA # 0 +0xB6B5 0xB5AB # 0 +0xB6B6 0xB5B0 # 0 +0xB6B7 0xB5B1 # 0 +0xB6B8 0xB5B3 # 0 +0xB6B9 0xB5B4 # 0 +0xB6BA 0xB5B5 # 0 +0xB6BB 0xB5BB # 0 +0xB6BC 0xB5BC # 0 +0xB6BD 0xB5BD # 0 +0xB6BE 0xB5C0 # 0 +0xB6BF 0xB5C4 # 0 +0xB6C0 0xB5CC # 0 +0xB6C1 0xB5CD # 0 +0xB6C2 0xB5CF # 0 +0xB6C3 0xB5D0 # 0 +0xB6C4 0xB5D1 # 0 +0xB6C5 0xB5D8 # 0 +0xB6C6 0xB5EC # 0 +0xB6C7 0xB610 # 0 +0xB6C8 0xB611 # 0 +0xB6C9 0xB614 # 0 +0xB6CA 0xB618 # 0 +0xB6CB 0xB625 # 0 +0xB6CC 0xB62C # 0 +0xB6CD 0xB634 # 0 +0xB6CE 0xB648 # 0 +0xB6CF 0xB664 # 0 +0xB6D0 0xB668 # 0 +0xB6D1 0xB69C # 0 +0xB6D2 0xB69D # 0 +0xB6D3 0xB6A0 # 0 +0xB6D4 0xB6A4 # 0 +0xB6D5 0xB6AB # 0 +0xB6D6 0xB6AC # 0 +0xB6D7 0xB6B1 # 0 +0xB6D8 0xB6D4 # 0 +0xB6D9 0xB6F0 # 0 +0xB6DA 0xB6F4 # 0 +0xB6DB 0xB6F8 # 0 +0xB6DC 0xB700 # 0 +0xB6DD 0xB701 # 0 +0xB6DE 0xB705 # 0 +0xB6DF 0xB728 # 0 +0xB6E0 0xB729 # 0 +0xB6E1 0xB72C # 0 +0xB6E2 0xB72F # 0 +0xB6E3 0xB730 # 0 +0xB6E4 0xB738 # 0 +0xB6E5 0xB739 # 0 +0xB6E6 0xB73B # 0 +0xB6E7 0xB744 # 0 +0xB6E8 0xB748 # 0 +0xB6E9 0xB74C # 0 +0xB6EA 0xB754 # 0 +0xB6EB 0xB755 # 0 +0xB6EC 0xB760 # 0 +0xB6ED 0xB764 # 0 +0xB6EE 0xB768 # 0 +0xB6EF 0xB770 # 0 +0xB6F0 0xB771 # 0 +0xB6F1 0xB773 # 0 +0xB6F2 0xB775 # 0 +0xB6F3 0xB77C # 0 +0xB6F4 0xB77D # 0 +0xB6F5 0xB780 # 0 +0xB6F6 0xB784 # 0 +0xB6F7 0xB78C # 0 +0xB6F8 0xB78D # 0 +0xB6F9 0xB78F # 0 +0xB6FA 0xB790 # 0 +0xB6FB 0xB791 # 0 +0xB6FC 0xB792 # 0 +0xB6FD 0xB796 # 0 +0xB6FE 0xB797 # 0 +0xB741 0xD16E # 0 +0xB742 0xD16F # 0 +0xB743 0xD170 # 0 +0xB744 0xD171 # 0 +0xB745 0xD172 # 0 +0xB746 0xD173 # 0 +0xB747 0xD174 # 0 +0xB748 0xD175 # 0 +0xB749 0xD176 # 0 +0xB74A 0xD177 # 0 +0xB74B 0xD178 # 0 +0xB74C 0xD179 # 0 +0xB74D 0xD17A # 0 +0xB74E 0xD17B # 0 +0xB74F 0xD17D # 0 +0xB750 0xD17E # 0 +0xB751 0xD17F # 0 +0xB752 0xD180 # 0 +0xB753 0xD181 # 0 +0xB754 0xD182 # 0 +0xB755 0xD183 # 0 +0xB756 0xD185 # 0 +0xB757 0xD186 # 0 +0xB758 0xD187 # 0 +0xB759 0xD189 # 0 +0xB75A 0xD18A # 0 +0xB761 0xD18B # 0 +0xB762 0xD18C # 0 +0xB763 0xD18D # 0 +0xB764 0xD18E # 0 +0xB765 0xD18F # 0 +0xB766 0xD190 # 0 +0xB767 0xD191 # 0 +0xB768 0xD192 # 0 +0xB769 0xD193 # 0 +0xB76A 0xD194 # 0 +0xB76B 0xD195 # 0 +0xB76C 0xD196 # 0 +0xB76D 0xD197 # 0 +0xB76E 0xD198 # 0 +0xB76F 0xD199 # 0 +0xB770 0xD19A # 0 +0xB771 0xD19B # 0 +0xB772 0xD19C # 0 +0xB773 0xD19D # 0 +0xB774 0xD19E # 0 +0xB775 0xD19F # 0 +0xB776 0xD1A2 # 0 +0xB777 0xD1A3 # 0 +0xB778 0xD1A5 # 0 +0xB779 0xD1A6 # 0 +0xB77A 0xD1A7 # 0 +0xB781 0xD1A9 # 0 +0xB782 0xD1AA # 0 +0xB783 0xD1AB # 0 +0xB784 0xD1AC # 0 +0xB785 0xD1AD # 0 +0xB786 0xD1AE # 0 +0xB787 0xD1AF # 0 +0xB788 0xD1B2 # 0 +0xB789 0xD1B4 # 0 +0xB78A 0xD1B6 # 0 +0xB78B 0xD1B7 # 0 +0xB78C 0xD1B8 # 0 +0xB78D 0xD1B9 # 0 +0xB78E 0xD1BB # 0 +0xB78F 0xD1BD # 0 +0xB790 0xD1BE # 0 +0xB791 0xD1BF # 0 +0xB792 0xD1C1 # 0 +0xB793 0xD1C2 # 0 +0xB794 0xD1C3 # 0 +0xB795 0xD1C4 # 0 +0xB796 0xD1C5 # 0 +0xB797 0xD1C6 # 0 +0xB798 0xD1C7 # 0 +0xB799 0xD1C8 # 0 +0xB79A 0xD1C9 # 0 +0xB79B 0xD1CA # 0 +0xB79C 0xD1CB # 0 +0xB79D 0xD1CC # 0 +0xB79E 0xD1CD # 0 +0xB79F 0xD1CE # 0 +0xB7A0 0xD1CF # 0 +0xB7A1 0xB798 # 0 +0xB7A2 0xB799 # 0 +0xB7A3 0xB79C # 0 +0xB7A4 0xB7A0 # 0 +0xB7A5 0xB7A8 # 0 +0xB7A6 0xB7A9 # 0 +0xB7A7 0xB7AB # 0 +0xB7A8 0xB7AC # 0 +0xB7A9 0xB7AD # 0 +0xB7AA 0xB7B4 # 0 +0xB7AB 0xB7B5 # 0 +0xB7AC 0xB7B8 # 0 +0xB7AD 0xB7C7 # 0 +0xB7AE 0xB7C9 # 0 +0xB7AF 0xB7EC # 0 +0xB7B0 0xB7ED # 0 +0xB7B1 0xB7F0 # 0 +0xB7B2 0xB7F4 # 0 +0xB7B3 0xB7FC # 0 +0xB7B4 0xB7FD # 0 +0xB7B5 0xB7FF # 0 +0xB7B6 0xB800 # 0 +0xB7B7 0xB801 # 0 +0xB7B8 0xB807 # 0 +0xB7B9 0xB808 # 0 +0xB7BA 0xB809 # 0 +0xB7BB 0xB80C # 0 +0xB7BC 0xB810 # 0 +0xB7BD 0xB818 # 0 +0xB7BE 0xB819 # 0 +0xB7BF 0xB81B # 0 +0xB7C0 0xB81D # 0 +0xB7C1 0xB824 # 0 +0xB7C2 0xB825 # 0 +0xB7C3 0xB828 # 0 +0xB7C4 0xB82C # 0 +0xB7C5 0xB834 # 0 +0xB7C6 0xB835 # 0 +0xB7C7 0xB837 # 0 +0xB7C8 0xB838 # 0 +0xB7C9 0xB839 # 0 +0xB7CA 0xB840 # 0 +0xB7CB 0xB844 # 0 +0xB7CC 0xB851 # 0 +0xB7CD 0xB853 # 0 +0xB7CE 0xB85C # 0 +0xB7CF 0xB85D # 0 +0xB7D0 0xB860 # 0 +0xB7D1 0xB864 # 0 +0xB7D2 0xB86C # 0 +0xB7D3 0xB86D # 0 +0xB7D4 0xB86F # 0 +0xB7D5 0xB871 # 0 +0xB7D6 0xB878 # 0 +0xB7D7 0xB87C # 0 +0xB7D8 0xB88D # 0 +0xB7D9 0xB8A8 # 0 +0xB7DA 0xB8B0 # 0 +0xB7DB 0xB8B4 # 0 +0xB7DC 0xB8B8 # 0 +0xB7DD 0xB8C0 # 0 +0xB7DE 0xB8C1 # 0 +0xB7DF 0xB8C3 # 0 +0xB7E0 0xB8C5 # 0 +0xB7E1 0xB8CC # 0 +0xB7E2 0xB8D0 # 0 +0xB7E3 0xB8D4 # 0 +0xB7E4 0xB8DD # 0 +0xB7E5 0xB8DF # 0 +0xB7E6 0xB8E1 # 0 +0xB7E7 0xB8E8 # 0 +0xB7E8 0xB8E9 # 0 +0xB7E9 0xB8EC # 0 +0xB7EA 0xB8F0 # 0 +0xB7EB 0xB8F8 # 0 +0xB7EC 0xB8F9 # 0 +0xB7ED 0xB8FB # 0 +0xB7EE 0xB8FD # 0 +0xB7EF 0xB904 # 0 +0xB7F0 0xB918 # 0 +0xB7F1 0xB920 # 0 +0xB7F2 0xB93C # 0 +0xB7F3 0xB93D # 0 +0xB7F4 0xB940 # 0 +0xB7F5 0xB944 # 0 +0xB7F6 0xB94C # 0 +0xB7F7 0xB94F # 0 +0xB7F8 0xB951 # 0 +0xB7F9 0xB958 # 0 +0xB7FA 0xB959 # 0 +0xB7FB 0xB95C # 0 +0xB7FC 0xB960 # 0 +0xB7FD 0xB968 # 0 +0xB7FE 0xB969 # 0 +0xB841 0xD1D0 # 0 +0xB842 0xD1D1 # 0 +0xB843 0xD1D2 # 0 +0xB844 0xD1D3 # 0 +0xB845 0xD1D4 # 0 +0xB846 0xD1D5 # 0 +0xB847 0xD1D6 # 0 +0xB848 0xD1D7 # 0 +0xB849 0xD1D9 # 0 +0xB84A 0xD1DA # 0 +0xB84B 0xD1DB # 0 +0xB84C 0xD1DC # 0 +0xB84D 0xD1DD # 0 +0xB84E 0xD1DE # 0 +0xB84F 0xD1DF # 0 +0xB850 0xD1E0 # 0 +0xB851 0xD1E1 # 0 +0xB852 0xD1E2 # 0 +0xB853 0xD1E3 # 0 +0xB854 0xD1E4 # 0 +0xB855 0xD1E5 # 0 +0xB856 0xD1E6 # 0 +0xB857 0xD1E7 # 0 +0xB858 0xD1E8 # 0 +0xB859 0xD1E9 # 0 +0xB85A 0xD1EA # 0 +0xB861 0xD1EB # 0 +0xB862 0xD1EC # 0 +0xB863 0xD1ED # 0 +0xB864 0xD1EE # 0 +0xB865 0xD1EF # 0 +0xB866 0xD1F0 # 0 +0xB867 0xD1F1 # 0 +0xB868 0xD1F2 # 0 +0xB869 0xD1F3 # 0 +0xB86A 0xD1F5 # 0 +0xB86B 0xD1F6 # 0 +0xB86C 0xD1F7 # 0 +0xB86D 0xD1F9 # 0 +0xB86E 0xD1FA # 0 +0xB86F 0xD1FB # 0 +0xB870 0xD1FC # 0 +0xB871 0xD1FD # 0 +0xB872 0xD1FE # 0 +0xB873 0xD1FF # 0 +0xB874 0xD200 # 0 +0xB875 0xD201 # 0 +0xB876 0xD202 # 0 +0xB877 0xD203 # 0 +0xB878 0xD204 # 0 +0xB879 0xD205 # 0 +0xB87A 0xD206 # 0 +0xB881 0xD208 # 0 +0xB882 0xD20A # 0 +0xB883 0xD20B # 0 +0xB884 0xD20C # 0 +0xB885 0xD20D # 0 +0xB886 0xD20E # 0 +0xB887 0xD20F # 0 +0xB888 0xD211 # 0 +0xB889 0xD212 # 0 +0xB88A 0xD213 # 0 +0xB88B 0xD214 # 0 +0xB88C 0xD215 # 0 +0xB88D 0xD216 # 0 +0xB88E 0xD217 # 0 +0xB88F 0xD218 # 0 +0xB890 0xD219 # 0 +0xB891 0xD21A # 0 +0xB892 0xD21B # 0 +0xB893 0xD21C # 0 +0xB894 0xD21D # 0 +0xB895 0xD21E # 0 +0xB896 0xD21F # 0 +0xB897 0xD220 # 0 +0xB898 0xD221 # 0 +0xB899 0xD222 # 0 +0xB89A 0xD223 # 0 +0xB89B 0xD224 # 0 +0xB89C 0xD225 # 0 +0xB89D 0xD226 # 0 +0xB89E 0xD227 # 0 +0xB89F 0xD228 # 0 +0xB8A0 0xD229 # 0 +0xB8A1 0xB96B # 0 +0xB8A2 0xB96D # 0 +0xB8A3 0xB974 # 0 +0xB8A4 0xB975 # 0 +0xB8A5 0xB978 # 0 +0xB8A6 0xB97C # 0 +0xB8A7 0xB984 # 0 +0xB8A8 0xB985 # 0 +0xB8A9 0xB987 # 0 +0xB8AA 0xB989 # 0 +0xB8AB 0xB98A # 0 +0xB8AC 0xB98D # 0 +0xB8AD 0xB98E # 0 +0xB8AE 0xB9AC # 0 +0xB8AF 0xB9AD # 0 +0xB8B0 0xB9B0 # 0 +0xB8B1 0xB9B4 # 0 +0xB8B2 0xB9BC # 0 +0xB8B3 0xB9BD # 0 +0xB8B4 0xB9BF # 0 +0xB8B5 0xB9C1 # 0 +0xB8B6 0xB9C8 # 0 +0xB8B7 0xB9C9 # 0 +0xB8B8 0xB9CC # 0 +0xB8B9 0xB9CE # 0 +0xB8BA 0xB9CF # 0 +0xB8BB 0xB9D0 # 0 +0xB8BC 0xB9D1 # 0 +0xB8BD 0xB9D2 # 0 +0xB8BE 0xB9D8 # 0 +0xB8BF 0xB9D9 # 0 +0xB8C0 0xB9DB # 0 +0xB8C1 0xB9DD # 0 +0xB8C2 0xB9DE # 0 +0xB8C3 0xB9E1 # 0 +0xB8C4 0xB9E3 # 0 +0xB8C5 0xB9E4 # 0 +0xB8C6 0xB9E5 # 0 +0xB8C7 0xB9E8 # 0 +0xB8C8 0xB9EC # 0 +0xB8C9 0xB9F4 # 0 +0xB8CA 0xB9F5 # 0 +0xB8CB 0xB9F7 # 0 +0xB8CC 0xB9F8 # 0 +0xB8CD 0xB9F9 # 0 +0xB8CE 0xB9FA # 0 +0xB8CF 0xBA00 # 0 +0xB8D0 0xBA01 # 0 +0xB8D1 0xBA08 # 0 +0xB8D2 0xBA15 # 0 +0xB8D3 0xBA38 # 0 +0xB8D4 0xBA39 # 0 +0xB8D5 0xBA3C # 0 +0xB8D6 0xBA40 # 0 +0xB8D7 0xBA42 # 0 +0xB8D8 0xBA48 # 0 +0xB8D9 0xBA49 # 0 +0xB8DA 0xBA4B # 0 +0xB8DB 0xBA4D # 0 +0xB8DC 0xBA4E # 0 +0xB8DD 0xBA53 # 0 +0xB8DE 0xBA54 # 0 +0xB8DF 0xBA55 # 0 +0xB8E0 0xBA58 # 0 +0xB8E1 0xBA5C # 0 +0xB8E2 0xBA64 # 0 +0xB8E3 0xBA65 # 0 +0xB8E4 0xBA67 # 0 +0xB8E5 0xBA68 # 0 +0xB8E6 0xBA69 # 0 +0xB8E7 0xBA70 # 0 +0xB8E8 0xBA71 # 0 +0xB8E9 0xBA74 # 0 +0xB8EA 0xBA78 # 0 +0xB8EB 0xBA83 # 0 +0xB8EC 0xBA84 # 0 +0xB8ED 0xBA85 # 0 +0xB8EE 0xBA87 # 0 +0xB8EF 0xBA8C # 0 +0xB8F0 0xBAA8 # 0 +0xB8F1 0xBAA9 # 0 +0xB8F2 0xBAAB # 0 +0xB8F3 0xBAAC # 0 +0xB8F4 0xBAB0 # 0 +0xB8F5 0xBAB2 # 0 +0xB8F6 0xBAB8 # 0 +0xB8F7 0xBAB9 # 0 +0xB8F8 0xBABB # 0 +0xB8F9 0xBABD # 0 +0xB8FA 0xBAC4 # 0 +0xB8FB 0xBAC8 # 0 +0xB8FC 0xBAD8 # 0 +0xB8FD 0xBAD9 # 0 +0xB8FE 0xBAFC # 0 +0xB941 0xD22A # 0 +0xB942 0xD22B # 0 +0xB943 0xD22E # 0 +0xB944 0xD22F # 0 +0xB945 0xD231 # 0 +0xB946 0xD232 # 0 +0xB947 0xD233 # 0 +0xB948 0xD235 # 0 +0xB949 0xD236 # 0 +0xB94A 0xD237 # 0 +0xB94B 0xD238 # 0 +0xB94C 0xD239 # 0 +0xB94D 0xD23A # 0 +0xB94E 0xD23B # 0 +0xB94F 0xD23E # 0 +0xB950 0xD240 # 0 +0xB951 0xD242 # 0 +0xB952 0xD243 # 0 +0xB953 0xD244 # 0 +0xB954 0xD245 # 0 +0xB955 0xD246 # 0 +0xB956 0xD247 # 0 +0xB957 0xD249 # 0 +0xB958 0xD24A # 0 +0xB959 0xD24B # 0 +0xB95A 0xD24C # 0 +0xB961 0xD24D # 0 +0xB962 0xD24E # 0 +0xB963 0xD24F # 0 +0xB964 0xD250 # 0 +0xB965 0xD251 # 0 +0xB966 0xD252 # 0 +0xB967 0xD253 # 0 +0xB968 0xD254 # 0 +0xB969 0xD255 # 0 +0xB96A 0xD256 # 0 +0xB96B 0xD257 # 0 +0xB96C 0xD258 # 0 +0xB96D 0xD259 # 0 +0xB96E 0xD25A # 0 +0xB96F 0xD25B # 0 +0xB970 0xD25D # 0 +0xB971 0xD25E # 0 +0xB972 0xD25F # 0 +0xB973 0xD260 # 0 +0xB974 0xD261 # 0 +0xB975 0xD262 # 0 +0xB976 0xD263 # 0 +0xB977 0xD265 # 0 +0xB978 0xD266 # 0 +0xB979 0xD267 # 0 +0xB97A 0xD268 # 0 +0xB981 0xD269 # 0 +0xB982 0xD26A # 0 +0xB983 0xD26B # 0 +0xB984 0xD26C # 0 +0xB985 0xD26D # 0 +0xB986 0xD26E # 0 +0xB987 0xD26F # 0 +0xB988 0xD270 # 0 +0xB989 0xD271 # 0 +0xB98A 0xD272 # 0 +0xB98B 0xD273 # 0 +0xB98C 0xD274 # 0 +0xB98D 0xD275 # 0 +0xB98E 0xD276 # 0 +0xB98F 0xD277 # 0 +0xB990 0xD278 # 0 +0xB991 0xD279 # 0 +0xB992 0xD27A # 0 +0xB993 0xD27B # 0 +0xB994 0xD27C # 0 +0xB995 0xD27D # 0 +0xB996 0xD27E # 0 +0xB997 0xD27F # 0 +0xB998 0xD282 # 0 +0xB999 0xD283 # 0 +0xB99A 0xD285 # 0 +0xB99B 0xD286 # 0 +0xB99C 0xD287 # 0 +0xB99D 0xD289 # 0 +0xB99E 0xD28A # 0 +0xB99F 0xD28B # 0 +0xB9A0 0xD28C # 0 +0xB9A1 0xBB00 # 0 +0xB9A2 0xBB04 # 0 +0xB9A3 0xBB0D # 0 +0xB9A4 0xBB0F # 0 +0xB9A5 0xBB11 # 0 +0xB9A6 0xBB18 # 0 +0xB9A7 0xBB1C # 0 +0xB9A8 0xBB20 # 0 +0xB9A9 0xBB29 # 0 +0xB9AA 0xBB2B # 0 +0xB9AB 0xBB34 # 0 +0xB9AC 0xBB35 # 0 +0xB9AD 0xBB36 # 0 +0xB9AE 0xBB38 # 0 +0xB9AF 0xBB3B # 0 +0xB9B0 0xBB3C # 0 +0xB9B1 0xBB3D # 0 +0xB9B2 0xBB3E # 0 +0xB9B3 0xBB44 # 0 +0xB9B4 0xBB45 # 0 +0xB9B5 0xBB47 # 0 +0xB9B6 0xBB49 # 0 +0xB9B7 0xBB4D # 0 +0xB9B8 0xBB4F # 0 +0xB9B9 0xBB50 # 0 +0xB9BA 0xBB54 # 0 +0xB9BB 0xBB58 # 0 +0xB9BC 0xBB61 # 0 +0xB9BD 0xBB63 # 0 +0xB9BE 0xBB6C # 0 +0xB9BF 0xBB88 # 0 +0xB9C0 0xBB8C # 0 +0xB9C1 0xBB90 # 0 +0xB9C2 0xBBA4 # 0 +0xB9C3 0xBBA8 # 0 +0xB9C4 0xBBAC # 0 +0xB9C5 0xBBB4 # 0 +0xB9C6 0xBBB7 # 0 +0xB9C7 0xBBC0 # 0 +0xB9C8 0xBBC4 # 0 +0xB9C9 0xBBC8 # 0 +0xB9CA 0xBBD0 # 0 +0xB9CB 0xBBD3 # 0 +0xB9CC 0xBBF8 # 0 +0xB9CD 0xBBF9 # 0 +0xB9CE 0xBBFC # 0 +0xB9CF 0xBBFF # 0 +0xB9D0 0xBC00 # 0 +0xB9D1 0xBC02 # 0 +0xB9D2 0xBC08 # 0 +0xB9D3 0xBC09 # 0 +0xB9D4 0xBC0B # 0 +0xB9D5 0xBC0C # 0 +0xB9D6 0xBC0D # 0 +0xB9D7 0xBC0F # 0 +0xB9D8 0xBC11 # 0 +0xB9D9 0xBC14 # 0 +0xB9DA 0xBC15 # 0 +0xB9DB 0xBC16 # 0 +0xB9DC 0xBC17 # 0 +0xB9DD 0xBC18 # 0 +0xB9DE 0xBC1B # 0 +0xB9DF 0xBC1C # 0 +0xB9E0 0xBC1D # 0 +0xB9E1 0xBC1E # 0 +0xB9E2 0xBC1F # 0 +0xB9E3 0xBC24 # 0 +0xB9E4 0xBC25 # 0 +0xB9E5 0xBC27 # 0 +0xB9E6 0xBC29 # 0 +0xB9E7 0xBC2D # 0 +0xB9E8 0xBC30 # 0 +0xB9E9 0xBC31 # 0 +0xB9EA 0xBC34 # 0 +0xB9EB 0xBC38 # 0 +0xB9EC 0xBC40 # 0 +0xB9ED 0xBC41 # 0 +0xB9EE 0xBC43 # 0 +0xB9EF 0xBC44 # 0 +0xB9F0 0xBC45 # 0 +0xB9F1 0xBC49 # 0 +0xB9F2 0xBC4C # 0 +0xB9F3 0xBC4D # 0 +0xB9F4 0xBC50 # 0 +0xB9F5 0xBC5D # 0 +0xB9F6 0xBC84 # 0 +0xB9F7 0xBC85 # 0 +0xB9F8 0xBC88 # 0 +0xB9F9 0xBC8B # 0 +0xB9FA 0xBC8C # 0 +0xB9FB 0xBC8E # 0 +0xB9FC 0xBC94 # 0 +0xB9FD 0xBC95 # 0 +0xB9FE 0xBC97 # 0 +0xBA41 0xD28D # 0 +0xBA42 0xD28E # 0 +0xBA43 0xD28F # 0 +0xBA44 0xD292 # 0 +0xBA45 0xD293 # 0 +0xBA46 0xD294 # 0 +0xBA47 0xD296 # 0 +0xBA48 0xD297 # 0 +0xBA49 0xD298 # 0 +0xBA4A 0xD299 # 0 +0xBA4B 0xD29A # 0 +0xBA4C 0xD29B # 0 +0xBA4D 0xD29D # 0 +0xBA4E 0xD29E # 0 +0xBA4F 0xD29F # 0 +0xBA50 0xD2A1 # 0 +0xBA51 0xD2A2 # 0 +0xBA52 0xD2A3 # 0 +0xBA53 0xD2A5 # 0 +0xBA54 0xD2A6 # 0 +0xBA55 0xD2A7 # 0 +0xBA56 0xD2A8 # 0 +0xBA57 0xD2A9 # 0 +0xBA58 0xD2AA # 0 +0xBA59 0xD2AB # 0 +0xBA5A 0xD2AD # 0 +0xBA61 0xD2AE # 0 +0xBA62 0xD2AF # 0 +0xBA63 0xD2B0 # 0 +0xBA64 0xD2B2 # 0 +0xBA65 0xD2B3 # 0 +0xBA66 0xD2B4 # 0 +0xBA67 0xD2B5 # 0 +0xBA68 0xD2B6 # 0 +0xBA69 0xD2B7 # 0 +0xBA6A 0xD2BA # 0 +0xBA6B 0xD2BB # 0 +0xBA6C 0xD2BD # 0 +0xBA6D 0xD2BE # 0 +0xBA6E 0xD2C1 # 0 +0xBA6F 0xD2C3 # 0 +0xBA70 0xD2C4 # 0 +0xBA71 0xD2C5 # 0 +0xBA72 0xD2C6 # 0 +0xBA73 0xD2C7 # 0 +0xBA74 0xD2CA # 0 +0xBA75 0xD2CC # 0 +0xBA76 0xD2CD # 0 +0xBA77 0xD2CE # 0 +0xBA78 0xD2CF # 0 +0xBA79 0xD2D0 # 0 +0xBA7A 0xD2D1 # 0 +0xBA81 0xD2D2 # 0 +0xBA82 0xD2D3 # 0 +0xBA83 0xD2D5 # 0 +0xBA84 0xD2D6 # 0 +0xBA85 0xD2D7 # 0 +0xBA86 0xD2D9 # 0 +0xBA87 0xD2DA # 0 +0xBA88 0xD2DB # 0 +0xBA89 0xD2DD # 0 +0xBA8A 0xD2DE # 0 +0xBA8B 0xD2DF # 0 +0xBA8C 0xD2E0 # 0 +0xBA8D 0xD2E1 # 0 +0xBA8E 0xD2E2 # 0 +0xBA8F 0xD2E3 # 0 +0xBA90 0xD2E6 # 0 +0xBA91 0xD2E7 # 0 +0xBA92 0xD2E8 # 0 +0xBA93 0xD2E9 # 0 +0xBA94 0xD2EA # 0 +0xBA95 0xD2EB # 0 +0xBA96 0xD2EC # 0 +0xBA97 0xD2ED # 0 +0xBA98 0xD2EE # 0 +0xBA99 0xD2EF # 0 +0xBA9A 0xD2F2 # 0 +0xBA9B 0xD2F3 # 0 +0xBA9C 0xD2F5 # 0 +0xBA9D 0xD2F6 # 0 +0xBA9E 0xD2F7 # 0 +0xBA9F 0xD2F9 # 0 +0xBAA0 0xD2FA # 0 +0xBAA1 0xBC99 # 0 +0xBAA2 0xBC9A # 0 +0xBAA3 0xBCA0 # 0 +0xBAA4 0xBCA1 # 0 +0xBAA5 0xBCA4 # 0 +0xBAA6 0xBCA7 # 0 +0xBAA7 0xBCA8 # 0 +0xBAA8 0xBCB0 # 0 +0xBAA9 0xBCB1 # 0 +0xBAAA 0xBCB3 # 0 +0xBAAB 0xBCB4 # 0 +0xBAAC 0xBCB5 # 0 +0xBAAD 0xBCBC # 0 +0xBAAE 0xBCBD # 0 +0xBAAF 0xBCC0 # 0 +0xBAB0 0xBCC4 # 0 +0xBAB1 0xBCCD # 0 +0xBAB2 0xBCCF # 0 +0xBAB3 0xBCD0 # 0 +0xBAB4 0xBCD1 # 0 +0xBAB5 0xBCD5 # 0 +0xBAB6 0xBCD8 # 0 +0xBAB7 0xBCDC # 0 +0xBAB8 0xBCF4 # 0 +0xBAB9 0xBCF5 # 0 +0xBABA 0xBCF6 # 0 +0xBABB 0xBCF8 # 0 +0xBABC 0xBCFC # 0 +0xBABD 0xBD04 # 0 +0xBABE 0xBD05 # 0 +0xBABF 0xBD07 # 0 +0xBAC0 0xBD09 # 0 +0xBAC1 0xBD10 # 0 +0xBAC2 0xBD14 # 0 +0xBAC3 0xBD24 # 0 +0xBAC4 0xBD2C # 0 +0xBAC5 0xBD40 # 0 +0xBAC6 0xBD48 # 0 +0xBAC7 0xBD49 # 0 +0xBAC8 0xBD4C # 0 +0xBAC9 0xBD50 # 0 +0xBACA 0xBD58 # 0 +0xBACB 0xBD59 # 0 +0xBACC 0xBD64 # 0 +0xBACD 0xBD68 # 0 +0xBACE 0xBD80 # 0 +0xBACF 0xBD81 # 0 +0xBAD0 0xBD84 # 0 +0xBAD1 0xBD87 # 0 +0xBAD2 0xBD88 # 0 +0xBAD3 0xBD89 # 0 +0xBAD4 0xBD8A # 0 +0xBAD5 0xBD90 # 0 +0xBAD6 0xBD91 # 0 +0xBAD7 0xBD93 # 0 +0xBAD8 0xBD95 # 0 +0xBAD9 0xBD99 # 0 +0xBADA 0xBD9A # 0 +0xBADB 0xBD9C # 0 +0xBADC 0xBDA4 # 0 +0xBADD 0xBDB0 # 0 +0xBADE 0xBDB8 # 0 +0xBADF 0xBDD4 # 0 +0xBAE0 0xBDD5 # 0 +0xBAE1 0xBDD8 # 0 +0xBAE2 0xBDDC # 0 +0xBAE3 0xBDE9 # 0 +0xBAE4 0xBDF0 # 0 +0xBAE5 0xBDF4 # 0 +0xBAE6 0xBDF8 # 0 +0xBAE7 0xBE00 # 0 +0xBAE8 0xBE03 # 0 +0xBAE9 0xBE05 # 0 +0xBAEA 0xBE0C # 0 +0xBAEB 0xBE0D # 0 +0xBAEC 0xBE10 # 0 +0xBAED 0xBE14 # 0 +0xBAEE 0xBE1C # 0 +0xBAEF 0xBE1D # 0 +0xBAF0 0xBE1F # 0 +0xBAF1 0xBE44 # 0 +0xBAF2 0xBE45 # 0 +0xBAF3 0xBE48 # 0 +0xBAF4 0xBE4C # 0 +0xBAF5 0xBE4E # 0 +0xBAF6 0xBE54 # 0 +0xBAF7 0xBE55 # 0 +0xBAF8 0xBE57 # 0 +0xBAF9 0xBE59 # 0 +0xBAFA 0xBE5A # 0 +0xBAFB 0xBE5B # 0 +0xBAFC 0xBE60 # 0 +0xBAFD 0xBE61 # 0 +0xBAFE 0xBE64 # 0 +0xBB41 0xD2FB # 0 +0xBB42 0xD2FC # 0 +0xBB43 0xD2FD # 0 +0xBB44 0xD2FE # 0 +0xBB45 0xD2FF # 0 +0xBB46 0xD302 # 0 +0xBB47 0xD304 # 0 +0xBB48 0xD306 # 0 +0xBB49 0xD307 # 0 +0xBB4A 0xD308 # 0 +0xBB4B 0xD309 # 0 +0xBB4C 0xD30A # 0 +0xBB4D 0xD30B # 0 +0xBB4E 0xD30F # 0 +0xBB4F 0xD311 # 0 +0xBB50 0xD312 # 0 +0xBB51 0xD313 # 0 +0xBB52 0xD315 # 0 +0xBB53 0xD317 # 0 +0xBB54 0xD318 # 0 +0xBB55 0xD319 # 0 +0xBB56 0xD31A # 0 +0xBB57 0xD31B # 0 +0xBB58 0xD31E # 0 +0xBB59 0xD322 # 0 +0xBB5A 0xD323 # 0 +0xBB61 0xD324 # 0 +0xBB62 0xD326 # 0 +0xBB63 0xD327 # 0 +0xBB64 0xD32A # 0 +0xBB65 0xD32B # 0 +0xBB66 0xD32D # 0 +0xBB67 0xD32E # 0 +0xBB68 0xD32F # 0 +0xBB69 0xD331 # 0 +0xBB6A 0xD332 # 0 +0xBB6B 0xD333 # 0 +0xBB6C 0xD334 # 0 +0xBB6D 0xD335 # 0 +0xBB6E 0xD336 # 0 +0xBB6F 0xD337 # 0 +0xBB70 0xD33A # 0 +0xBB71 0xD33E # 0 +0xBB72 0xD33F # 0 +0xBB73 0xD340 # 0 +0xBB74 0xD341 # 0 +0xBB75 0xD342 # 0 +0xBB76 0xD343 # 0 +0xBB77 0xD346 # 0 +0xBB78 0xD347 # 0 +0xBB79 0xD348 # 0 +0xBB7A 0xD349 # 0 +0xBB81 0xD34A # 0 +0xBB82 0xD34B # 0 +0xBB83 0xD34C # 0 +0xBB84 0xD34D # 0 +0xBB85 0xD34E # 0 +0xBB86 0xD34F # 0 +0xBB87 0xD350 # 0 +0xBB88 0xD351 # 0 +0xBB89 0xD352 # 0 +0xBB8A 0xD353 # 0 +0xBB8B 0xD354 # 0 +0xBB8C 0xD355 # 0 +0xBB8D 0xD356 # 0 +0xBB8E 0xD357 # 0 +0xBB8F 0xD358 # 0 +0xBB90 0xD359 # 0 +0xBB91 0xD35A # 0 +0xBB92 0xD35B # 0 +0xBB93 0xD35C # 0 +0xBB94 0xD35D # 0 +0xBB95 0xD35E # 0 +0xBB96 0xD35F # 0 +0xBB97 0xD360 # 0 +0xBB98 0xD361 # 0 +0xBB99 0xD362 # 0 +0xBB9A 0xD363 # 0 +0xBB9B 0xD364 # 0 +0xBB9C 0xD365 # 0 +0xBB9D 0xD366 # 0 +0xBB9E 0xD367 # 0 +0xBB9F 0xD368 # 0 +0xBBA0 0xD369 # 0 +0xBBA1 0xBE68 # 0 +0xBBA2 0xBE6A # 0 +0xBBA3 0xBE70 # 0 +0xBBA4 0xBE71 # 0 +0xBBA5 0xBE73 # 0 +0xBBA6 0xBE74 # 0 +0xBBA7 0xBE75 # 0 +0xBBA8 0xBE7B # 0 +0xBBA9 0xBE7C # 0 +0xBBAA 0xBE7D # 0 +0xBBAB 0xBE80 # 0 +0xBBAC 0xBE84 # 0 +0xBBAD 0xBE8C # 0 +0xBBAE 0xBE8D # 0 +0xBBAF 0xBE8F # 0 +0xBBB0 0xBE90 # 0 +0xBBB1 0xBE91 # 0 +0xBBB2 0xBE98 # 0 +0xBBB3 0xBE99 # 0 +0xBBB4 0xBEA8 # 0 +0xBBB5 0xBED0 # 0 +0xBBB6 0xBED1 # 0 +0xBBB7 0xBED4 # 0 +0xBBB8 0xBED7 # 0 +0xBBB9 0xBED8 # 0 +0xBBBA 0xBEE0 # 0 +0xBBBB 0xBEE3 # 0 +0xBBBC 0xBEE4 # 0 +0xBBBD 0xBEE5 # 0 +0xBBBE 0xBEEC # 0 +0xBBBF 0xBF01 # 0 +0xBBC0 0xBF08 # 0 +0xBBC1 0xBF09 # 0 +0xBBC2 0xBF18 # 0 +0xBBC3 0xBF19 # 0 +0xBBC4 0xBF1B # 0 +0xBBC5 0xBF1C # 0 +0xBBC6 0xBF1D # 0 +0xBBC7 0xBF40 # 0 +0xBBC8 0xBF41 # 0 +0xBBC9 0xBF44 # 0 +0xBBCA 0xBF48 # 0 +0xBBCB 0xBF50 # 0 +0xBBCC 0xBF51 # 0 +0xBBCD 0xBF55 # 0 +0xBBCE 0xBF94 # 0 +0xBBCF 0xBFB0 # 0 +0xBBD0 0xBFC5 # 0 +0xBBD1 0xBFCC # 0 +0xBBD2 0xBFCD # 0 +0xBBD3 0xBFD0 # 0 +0xBBD4 0xBFD4 # 0 +0xBBD5 0xBFDC # 0 +0xBBD6 0xBFDF # 0 +0xBBD7 0xBFE1 # 0 +0xBBD8 0xC03C # 0 +0xBBD9 0xC051 # 0 +0xBBDA 0xC058 # 0 +0xBBDB 0xC05C # 0 +0xBBDC 0xC060 # 0 +0xBBDD 0xC068 # 0 +0xBBDE 0xC069 # 0 +0xBBDF 0xC090 # 0 +0xBBE0 0xC091 # 0 +0xBBE1 0xC094 # 0 +0xBBE2 0xC098 # 0 +0xBBE3 0xC0A0 # 0 +0xBBE4 0xC0A1 # 0 +0xBBE5 0xC0A3 # 0 +0xBBE6 0xC0A5 # 0 +0xBBE7 0xC0AC # 0 +0xBBE8 0xC0AD # 0 +0xBBE9 0xC0AF # 0 +0xBBEA 0xC0B0 # 0 +0xBBEB 0xC0B3 # 0 +0xBBEC 0xC0B4 # 0 +0xBBED 0xC0B5 # 0 +0xBBEE 0xC0B6 # 0 +0xBBEF 0xC0BC # 0 +0xBBF0 0xC0BD # 0 +0xBBF1 0xC0BF # 0 +0xBBF2 0xC0C0 # 0 +0xBBF3 0xC0C1 # 0 +0xBBF4 0xC0C5 # 0 +0xBBF5 0xC0C8 # 0 +0xBBF6 0xC0C9 # 0 +0xBBF7 0xC0CC # 0 +0xBBF8 0xC0D0 # 0 +0xBBF9 0xC0D8 # 0 +0xBBFA 0xC0D9 # 0 +0xBBFB 0xC0DB # 0 +0xBBFC 0xC0DC # 0 +0xBBFD 0xC0DD # 0 +0xBBFE 0xC0E4 # 0 +0xBC41 0xD36A # 0 +0xBC42 0xD36B # 0 +0xBC43 0xD36C # 0 +0xBC44 0xD36D # 0 +0xBC45 0xD36E # 0 +0xBC46 0xD36F # 0 +0xBC47 0xD370 # 0 +0xBC48 0xD371 # 0 +0xBC49 0xD372 # 0 +0xBC4A 0xD373 # 0 +0xBC4B 0xD374 # 0 +0xBC4C 0xD375 # 0 +0xBC4D 0xD376 # 0 +0xBC4E 0xD377 # 0 +0xBC4F 0xD378 # 0 +0xBC50 0xD379 # 0 +0xBC51 0xD37A # 0 +0xBC52 0xD37B # 0 +0xBC53 0xD37E # 0 +0xBC54 0xD37F # 0 +0xBC55 0xD381 # 0 +0xBC56 0xD382 # 0 +0xBC57 0xD383 # 0 +0xBC58 0xD385 # 0 +0xBC59 0xD386 # 0 +0xBC5A 0xD387 # 0 +0xBC61 0xD388 # 0 +0xBC62 0xD389 # 0 +0xBC63 0xD38A # 0 +0xBC64 0xD38B # 0 +0xBC65 0xD38E # 0 +0xBC66 0xD392 # 0 +0xBC67 0xD393 # 0 +0xBC68 0xD394 # 0 +0xBC69 0xD395 # 0 +0xBC6A 0xD396 # 0 +0xBC6B 0xD397 # 0 +0xBC6C 0xD39A # 0 +0xBC6D 0xD39B # 0 +0xBC6E 0xD39D # 0 +0xBC6F 0xD39E # 0 +0xBC70 0xD39F # 0 +0xBC71 0xD3A1 # 0 +0xBC72 0xD3A2 # 0 +0xBC73 0xD3A3 # 0 +0xBC74 0xD3A4 # 0 +0xBC75 0xD3A5 # 0 +0xBC76 0xD3A6 # 0 +0xBC77 0xD3A7 # 0 +0xBC78 0xD3AA # 0 +0xBC79 0xD3AC # 0 +0xBC7A 0xD3AE # 0 +0xBC81 0xD3AF # 0 +0xBC82 0xD3B0 # 0 +0xBC83 0xD3B1 # 0 +0xBC84 0xD3B2 # 0 +0xBC85 0xD3B3 # 0 +0xBC86 0xD3B5 # 0 +0xBC87 0xD3B6 # 0 +0xBC88 0xD3B7 # 0 +0xBC89 0xD3B9 # 0 +0xBC8A 0xD3BA # 0 +0xBC8B 0xD3BB # 0 +0xBC8C 0xD3BD # 0 +0xBC8D 0xD3BE # 0 +0xBC8E 0xD3BF # 0 +0xBC8F 0xD3C0 # 0 +0xBC90 0xD3C1 # 0 +0xBC91 0xD3C2 # 0 +0xBC92 0xD3C3 # 0 +0xBC93 0xD3C6 # 0 +0xBC94 0xD3C7 # 0 +0xBC95 0xD3CA # 0 +0xBC96 0xD3CB # 0 +0xBC97 0xD3CC # 0 +0xBC98 0xD3CD # 0 +0xBC99 0xD3CE # 0 +0xBC9A 0xD3CF # 0 +0xBC9B 0xD3D1 # 0 +0xBC9C 0xD3D2 # 0 +0xBC9D 0xD3D3 # 0 +0xBC9E 0xD3D4 # 0 +0xBC9F 0xD3D5 # 0 +0xBCA0 0xD3D6 # 0 +0xBCA1 0xC0E5 # 0 +0xBCA2 0xC0E8 # 0 +0xBCA3 0xC0EC # 0 +0xBCA4 0xC0F4 # 0 +0xBCA5 0xC0F5 # 0 +0xBCA6 0xC0F7 # 0 +0xBCA7 0xC0F9 # 0 +0xBCA8 0xC100 # 0 +0xBCA9 0xC104 # 0 +0xBCAA 0xC108 # 0 +0xBCAB 0xC110 # 0 +0xBCAC 0xC115 # 0 +0xBCAD 0xC11C # 0 +0xBCAE 0xC11D # 0 +0xBCAF 0xC11E # 0 +0xBCB0 0xC11F # 0 +0xBCB1 0xC120 # 0 +0xBCB2 0xC123 # 0 +0xBCB3 0xC124 # 0 +0xBCB4 0xC126 # 0 +0xBCB5 0xC127 # 0 +0xBCB6 0xC12C # 0 +0xBCB7 0xC12D # 0 +0xBCB8 0xC12F # 0 +0xBCB9 0xC130 # 0 +0xBCBA 0xC131 # 0 +0xBCBB 0xC136 # 0 +0xBCBC 0xC138 # 0 +0xBCBD 0xC139 # 0 +0xBCBE 0xC13C # 0 +0xBCBF 0xC140 # 0 +0xBCC0 0xC148 # 0 +0xBCC1 0xC149 # 0 +0xBCC2 0xC14B # 0 +0xBCC3 0xC14C # 0 +0xBCC4 0xC14D # 0 +0xBCC5 0xC154 # 0 +0xBCC6 0xC155 # 0 +0xBCC7 0xC158 # 0 +0xBCC8 0xC15C # 0 +0xBCC9 0xC164 # 0 +0xBCCA 0xC165 # 0 +0xBCCB 0xC167 # 0 +0xBCCC 0xC168 # 0 +0xBCCD 0xC169 # 0 +0xBCCE 0xC170 # 0 +0xBCCF 0xC174 # 0 +0xBCD0 0xC178 # 0 +0xBCD1 0xC185 # 0 +0xBCD2 0xC18C # 0 +0xBCD3 0xC18D # 0 +0xBCD4 0xC18E # 0 +0xBCD5 0xC190 # 0 +0xBCD6 0xC194 # 0 +0xBCD7 0xC196 # 0 +0xBCD8 0xC19C # 0 +0xBCD9 0xC19D # 0 +0xBCDA 0xC19F # 0 +0xBCDB 0xC1A1 # 0 +0xBCDC 0xC1A5 # 0 +0xBCDD 0xC1A8 # 0 +0xBCDE 0xC1A9 # 0 +0xBCDF 0xC1AC # 0 +0xBCE0 0xC1B0 # 0 +0xBCE1 0xC1BD # 0 +0xBCE2 0xC1C4 # 0 +0xBCE3 0xC1C8 # 0 +0xBCE4 0xC1CC # 0 +0xBCE5 0xC1D4 # 0 +0xBCE6 0xC1D7 # 0 +0xBCE7 0xC1D8 # 0 +0xBCE8 0xC1E0 # 0 +0xBCE9 0xC1E4 # 0 +0xBCEA 0xC1E8 # 0 +0xBCEB 0xC1F0 # 0 +0xBCEC 0xC1F1 # 0 +0xBCED 0xC1F3 # 0 +0xBCEE 0xC1FC # 0 +0xBCEF 0xC1FD # 0 +0xBCF0 0xC200 # 0 +0xBCF1 0xC204 # 0 +0xBCF2 0xC20C # 0 +0xBCF3 0xC20D # 0 +0xBCF4 0xC20F # 0 +0xBCF5 0xC211 # 0 +0xBCF6 0xC218 # 0 +0xBCF7 0xC219 # 0 +0xBCF8 0xC21C # 0 +0xBCF9 0xC21F # 0 +0xBCFA 0xC220 # 0 +0xBCFB 0xC228 # 0 +0xBCFC 0xC229 # 0 +0xBCFD 0xC22B # 0 +0xBCFE 0xC22D # 0 +0xBD41 0xD3D7 # 0 +0xBD42 0xD3D9 # 0 +0xBD43 0xD3DA # 0 +0xBD44 0xD3DB # 0 +0xBD45 0xD3DC # 0 +0xBD46 0xD3DD # 0 +0xBD47 0xD3DE # 0 +0xBD48 0xD3DF # 0 +0xBD49 0xD3E0 # 0 +0xBD4A 0xD3E2 # 0 +0xBD4B 0xD3E4 # 0 +0xBD4C 0xD3E5 # 0 +0xBD4D 0xD3E6 # 0 +0xBD4E 0xD3E7 # 0 +0xBD4F 0xD3E8 # 0 +0xBD50 0xD3E9 # 0 +0xBD51 0xD3EA # 0 +0xBD52 0xD3EB # 0 +0xBD53 0xD3EE # 0 +0xBD54 0xD3EF # 0 +0xBD55 0xD3F1 # 0 +0xBD56 0xD3F2 # 0 +0xBD57 0xD3F3 # 0 +0xBD58 0xD3F5 # 0 +0xBD59 0xD3F6 # 0 +0xBD5A 0xD3F7 # 0 +0xBD61 0xD3F8 # 0 +0xBD62 0xD3F9 # 0 +0xBD63 0xD3FA # 0 +0xBD64 0xD3FB # 0 +0xBD65 0xD3FE # 0 +0xBD66 0xD400 # 0 +0xBD67 0xD402 # 0 +0xBD68 0xD403 # 0 +0xBD69 0xD404 # 0 +0xBD6A 0xD405 # 0 +0xBD6B 0xD406 # 0 +0xBD6C 0xD407 # 0 +0xBD6D 0xD409 # 0 +0xBD6E 0xD40A # 0 +0xBD6F 0xD40B # 0 +0xBD70 0xD40C # 0 +0xBD71 0xD40D # 0 +0xBD72 0xD40E # 0 +0xBD73 0xD40F # 0 +0xBD74 0xD410 # 0 +0xBD75 0xD411 # 0 +0xBD76 0xD412 # 0 +0xBD77 0xD413 # 0 +0xBD78 0xD414 # 0 +0xBD79 0xD415 # 0 +0xBD7A 0xD416 # 0 +0xBD81 0xD417 # 0 +0xBD82 0xD418 # 0 +0xBD83 0xD419 # 0 +0xBD84 0xD41A # 0 +0xBD85 0xD41B # 0 +0xBD86 0xD41C # 0 +0xBD87 0xD41E # 0 +0xBD88 0xD41F # 0 +0xBD89 0xD420 # 0 +0xBD8A 0xD421 # 0 +0xBD8B 0xD422 # 0 +0xBD8C 0xD423 # 0 +0xBD8D 0xD424 # 0 +0xBD8E 0xD425 # 0 +0xBD8F 0xD426 # 0 +0xBD90 0xD427 # 0 +0xBD91 0xD428 # 0 +0xBD92 0xD429 # 0 +0xBD93 0xD42A # 0 +0xBD94 0xD42B # 0 +0xBD95 0xD42C # 0 +0xBD96 0xD42D # 0 +0xBD97 0xD42E # 0 +0xBD98 0xD42F # 0 +0xBD99 0xD430 # 0 +0xBD9A 0xD431 # 0 +0xBD9B 0xD432 # 0 +0xBD9C 0xD433 # 0 +0xBD9D 0xD434 # 0 +0xBD9E 0xD435 # 0 +0xBD9F 0xD436 # 0 +0xBDA0 0xD437 # 0 +0xBDA1 0xC22F # 0 +0xBDA2 0xC231 # 0 +0xBDA3 0xC232 # 0 +0xBDA4 0xC234 # 0 +0xBDA5 0xC248 # 0 +0xBDA6 0xC250 # 0 +0xBDA7 0xC251 # 0 +0xBDA8 0xC254 # 0 +0xBDA9 0xC258 # 0 +0xBDAA 0xC260 # 0 +0xBDAB 0xC265 # 0 +0xBDAC 0xC26C # 0 +0xBDAD 0xC26D # 0 +0xBDAE 0xC270 # 0 +0xBDAF 0xC274 # 0 +0xBDB0 0xC27C # 0 +0xBDB1 0xC27D # 0 +0xBDB2 0xC27F # 0 +0xBDB3 0xC281 # 0 +0xBDB4 0xC288 # 0 +0xBDB5 0xC289 # 0 +0xBDB6 0xC290 # 0 +0xBDB7 0xC298 # 0 +0xBDB8 0xC29B # 0 +0xBDB9 0xC29D # 0 +0xBDBA 0xC2A4 # 0 +0xBDBB 0xC2A5 # 0 +0xBDBC 0xC2A8 # 0 +0xBDBD 0xC2AC # 0 +0xBDBE 0xC2AD # 0 +0xBDBF 0xC2B4 # 0 +0xBDC0 0xC2B5 # 0 +0xBDC1 0xC2B7 # 0 +0xBDC2 0xC2B9 # 0 +0xBDC3 0xC2DC # 0 +0xBDC4 0xC2DD # 0 +0xBDC5 0xC2E0 # 0 +0xBDC6 0xC2E3 # 0 +0xBDC7 0xC2E4 # 0 +0xBDC8 0xC2EB # 0 +0xBDC9 0xC2EC # 0 +0xBDCA 0xC2ED # 0 +0xBDCB 0xC2EF # 0 +0xBDCC 0xC2F1 # 0 +0xBDCD 0xC2F6 # 0 +0xBDCE 0xC2F8 # 0 +0xBDCF 0xC2F9 # 0 +0xBDD0 0xC2FB # 0 +0xBDD1 0xC2FC # 0 +0xBDD2 0xC300 # 0 +0xBDD3 0xC308 # 0 +0xBDD4 0xC309 # 0 +0xBDD5 0xC30C # 0 +0xBDD6 0xC30D # 0 +0xBDD7 0xC313 # 0 +0xBDD8 0xC314 # 0 +0xBDD9 0xC315 # 0 +0xBDDA 0xC318 # 0 +0xBDDB 0xC31C # 0 +0xBDDC 0xC324 # 0 +0xBDDD 0xC325 # 0 +0xBDDE 0xC328 # 0 +0xBDDF 0xC329 # 0 +0xBDE0 0xC345 # 0 +0xBDE1 0xC368 # 0 +0xBDE2 0xC369 # 0 +0xBDE3 0xC36C # 0 +0xBDE4 0xC370 # 0 +0xBDE5 0xC372 # 0 +0xBDE6 0xC378 # 0 +0xBDE7 0xC379 # 0 +0xBDE8 0xC37C # 0 +0xBDE9 0xC37D # 0 +0xBDEA 0xC384 # 0 +0xBDEB 0xC388 # 0 +0xBDEC 0xC38C # 0 +0xBDED 0xC3C0 # 0 +0xBDEE 0xC3D8 # 0 +0xBDEF 0xC3D9 # 0 +0xBDF0 0xC3DC # 0 +0xBDF1 0xC3DF # 0 +0xBDF2 0xC3E0 # 0 +0xBDF3 0xC3E2 # 0 +0xBDF4 0xC3E8 # 0 +0xBDF5 0xC3E9 # 0 +0xBDF6 0xC3ED # 0 +0xBDF7 0xC3F4 # 0 +0xBDF8 0xC3F5 # 0 +0xBDF9 0xC3F8 # 0 +0xBDFA 0xC408 # 0 +0xBDFB 0xC410 # 0 +0xBDFC 0xC424 # 0 +0xBDFD 0xC42C # 0 +0xBDFE 0xC430 # 0 +0xBE41 0xD438 # 0 +0xBE42 0xD439 # 0 +0xBE43 0xD43A # 0 +0xBE44 0xD43B # 0 +0xBE45 0xD43C # 0 +0xBE46 0xD43D # 0 +0xBE47 0xD43E # 0 +0xBE48 0xD43F # 0 +0xBE49 0xD441 # 0 +0xBE4A 0xD442 # 0 +0xBE4B 0xD443 # 0 +0xBE4C 0xD445 # 0 +0xBE4D 0xD446 # 0 +0xBE4E 0xD447 # 0 +0xBE4F 0xD448 # 0 +0xBE50 0xD449 # 0 +0xBE51 0xD44A # 0 +0xBE52 0xD44B # 0 +0xBE53 0xD44C # 0 +0xBE54 0xD44D # 0 +0xBE55 0xD44E # 0 +0xBE56 0xD44F # 0 +0xBE57 0xD450 # 0 +0xBE58 0xD451 # 0 +0xBE59 0xD452 # 0 +0xBE5A 0xD453 # 0 +0xBE61 0xD454 # 0 +0xBE62 0xD455 # 0 +0xBE63 0xD456 # 0 +0xBE64 0xD457 # 0 +0xBE65 0xD458 # 0 +0xBE66 0xD459 # 0 +0xBE67 0xD45A # 0 +0xBE68 0xD45B # 0 +0xBE69 0xD45D # 0 +0xBE6A 0xD45E # 0 +0xBE6B 0xD45F # 0 +0xBE6C 0xD461 # 0 +0xBE6D 0xD462 # 0 +0xBE6E 0xD463 # 0 +0xBE6F 0xD465 # 0 +0xBE70 0xD466 # 0 +0xBE71 0xD467 # 0 +0xBE72 0xD468 # 0 +0xBE73 0xD469 # 0 +0xBE74 0xD46A # 0 +0xBE75 0xD46B # 0 +0xBE76 0xD46C # 0 +0xBE77 0xD46E # 0 +0xBE78 0xD470 # 0 +0xBE79 0xD471 # 0 +0xBE7A 0xD472 # 0 +0xBE81 0xD473 # 0 +0xBE82 0xD474 # 0 +0xBE83 0xD475 # 0 +0xBE84 0xD476 # 0 +0xBE85 0xD477 # 0 +0xBE86 0xD47A # 0 +0xBE87 0xD47B # 0 +0xBE88 0xD47D # 0 +0xBE89 0xD47E # 0 +0xBE8A 0xD481 # 0 +0xBE8B 0xD483 # 0 +0xBE8C 0xD484 # 0 +0xBE8D 0xD485 # 0 +0xBE8E 0xD486 # 0 +0xBE8F 0xD487 # 0 +0xBE90 0xD48A # 0 +0xBE91 0xD48C # 0 +0xBE92 0xD48E # 0 +0xBE93 0xD48F # 0 +0xBE94 0xD490 # 0 +0xBE95 0xD491 # 0 +0xBE96 0xD492 # 0 +0xBE97 0xD493 # 0 +0xBE98 0xD495 # 0 +0xBE99 0xD496 # 0 +0xBE9A 0xD497 # 0 +0xBE9B 0xD498 # 0 +0xBE9C 0xD499 # 0 +0xBE9D 0xD49A # 0 +0xBE9E 0xD49B # 0 +0xBE9F 0xD49C # 0 +0xBEA0 0xD49D # 0 +0xBEA1 0xC434 # 0 +0xBEA2 0xC43C # 0 +0xBEA3 0xC43D # 0 +0xBEA4 0xC448 # 0 +0xBEA5 0xC464 # 0 +0xBEA6 0xC465 # 0 +0xBEA7 0xC468 # 0 +0xBEA8 0xC46C # 0 +0xBEA9 0xC474 # 0 +0xBEAA 0xC475 # 0 +0xBEAB 0xC479 # 0 +0xBEAC 0xC480 # 0 +0xBEAD 0xC494 # 0 +0xBEAE 0xC49C # 0 +0xBEAF 0xC4B8 # 0 +0xBEB0 0xC4BC # 0 +0xBEB1 0xC4E9 # 0 +0xBEB2 0xC4F0 # 0 +0xBEB3 0xC4F1 # 0 +0xBEB4 0xC4F4 # 0 +0xBEB5 0xC4F8 # 0 +0xBEB6 0xC4FA # 0 +0xBEB7 0xC4FF # 0 +0xBEB8 0xC500 # 0 +0xBEB9 0xC501 # 0 +0xBEBA 0xC50C # 0 +0xBEBB 0xC510 # 0 +0xBEBC 0xC514 # 0 +0xBEBD 0xC51C # 0 +0xBEBE 0xC528 # 0 +0xBEBF 0xC529 # 0 +0xBEC0 0xC52C # 0 +0xBEC1 0xC530 # 0 +0xBEC2 0xC538 # 0 +0xBEC3 0xC539 # 0 +0xBEC4 0xC53B # 0 +0xBEC5 0xC53D # 0 +0xBEC6 0xC544 # 0 +0xBEC7 0xC545 # 0 +0xBEC8 0xC548 # 0 +0xBEC9 0xC549 # 0 +0xBECA 0xC54A # 0 +0xBECB 0xC54C # 0 +0xBECC 0xC54D # 0 +0xBECD 0xC54E # 0 +0xBECE 0xC553 # 0 +0xBECF 0xC554 # 0 +0xBED0 0xC555 # 0 +0xBED1 0xC557 # 0 +0xBED2 0xC558 # 0 +0xBED3 0xC559 # 0 +0xBED4 0xC55D # 0 +0xBED5 0xC55E # 0 +0xBED6 0xC560 # 0 +0xBED7 0xC561 # 0 +0xBED8 0xC564 # 0 +0xBED9 0xC568 # 0 +0xBEDA 0xC570 # 0 +0xBEDB 0xC571 # 0 +0xBEDC 0xC573 # 0 +0xBEDD 0xC574 # 0 +0xBEDE 0xC575 # 0 +0xBEDF 0xC57C # 0 +0xBEE0 0xC57D # 0 +0xBEE1 0xC580 # 0 +0xBEE2 0xC584 # 0 +0xBEE3 0xC587 # 0 +0xBEE4 0xC58C # 0 +0xBEE5 0xC58D # 0 +0xBEE6 0xC58F # 0 +0xBEE7 0xC591 # 0 +0xBEE8 0xC595 # 0 +0xBEE9 0xC597 # 0 +0xBEEA 0xC598 # 0 +0xBEEB 0xC59C # 0 +0xBEEC 0xC5A0 # 0 +0xBEED 0xC5A9 # 0 +0xBEEE 0xC5B4 # 0 +0xBEEF 0xC5B5 # 0 +0xBEF0 0xC5B8 # 0 +0xBEF1 0xC5B9 # 0 +0xBEF2 0xC5BB # 0 +0xBEF3 0xC5BC # 0 +0xBEF4 0xC5BD # 0 +0xBEF5 0xC5BE # 0 +0xBEF6 0xC5C4 # 0 +0xBEF7 0xC5C5 # 0 +0xBEF8 0xC5C6 # 0 +0xBEF9 0xC5C7 # 0 +0xBEFA 0xC5C8 # 0 +0xBEFB 0xC5C9 # 0 +0xBEFC 0xC5CA # 0 +0xBEFD 0xC5CC # 0 +0xBEFE 0xC5CE # 0 +0xBF41 0xD49E # 0 +0xBF42 0xD49F # 0 +0xBF43 0xD4A0 # 0 +0xBF44 0xD4A1 # 0 +0xBF45 0xD4A2 # 0 +0xBF46 0xD4A3 # 0 +0xBF47 0xD4A4 # 0 +0xBF48 0xD4A5 # 0 +0xBF49 0xD4A6 # 0 +0xBF4A 0xD4A7 # 0 +0xBF4B 0xD4A8 # 0 +0xBF4C 0xD4AA # 0 +0xBF4D 0xD4AB # 0 +0xBF4E 0xD4AC # 0 +0xBF4F 0xD4AD # 0 +0xBF50 0xD4AE # 0 +0xBF51 0xD4AF # 0 +0xBF52 0xD4B0 # 0 +0xBF53 0xD4B1 # 0 +0xBF54 0xD4B2 # 0 +0xBF55 0xD4B3 # 0 +0xBF56 0xD4B4 # 0 +0xBF57 0xD4B5 # 0 +0xBF58 0xD4B6 # 0 +0xBF59 0xD4B7 # 0 +0xBF5A 0xD4B8 # 0 +0xBF61 0xD4B9 # 0 +0xBF62 0xD4BA # 0 +0xBF63 0xD4BB # 0 +0xBF64 0xD4BC # 0 +0xBF65 0xD4BD # 0 +0xBF66 0xD4BE # 0 +0xBF67 0xD4BF # 0 +0xBF68 0xD4C0 # 0 +0xBF69 0xD4C1 # 0 +0xBF6A 0xD4C2 # 0 +0xBF6B 0xD4C3 # 0 +0xBF6C 0xD4C4 # 0 +0xBF6D 0xD4C5 # 0 +0xBF6E 0xD4C6 # 0 +0xBF6F 0xD4C7 # 0 +0xBF70 0xD4C8 # 0 +0xBF71 0xD4C9 # 0 +0xBF72 0xD4CA # 0 +0xBF73 0xD4CB # 0 +0xBF74 0xD4CD # 0 +0xBF75 0xD4CE # 0 +0xBF76 0xD4CF # 0 +0xBF77 0xD4D1 # 0 +0xBF78 0xD4D2 # 0 +0xBF79 0xD4D3 # 0 +0xBF7A 0xD4D5 # 0 +0xBF81 0xD4D6 # 0 +0xBF82 0xD4D7 # 0 +0xBF83 0xD4D8 # 0 +0xBF84 0xD4D9 # 0 +0xBF85 0xD4DA # 0 +0xBF86 0xD4DB # 0 +0xBF87 0xD4DD # 0 +0xBF88 0xD4DE # 0 +0xBF89 0xD4E0 # 0 +0xBF8A 0xD4E1 # 0 +0xBF8B 0xD4E2 # 0 +0xBF8C 0xD4E3 # 0 +0xBF8D 0xD4E4 # 0 +0xBF8E 0xD4E5 # 0 +0xBF8F 0xD4E6 # 0 +0xBF90 0xD4E7 # 0 +0xBF91 0xD4E9 # 0 +0xBF92 0xD4EA # 0 +0xBF93 0xD4EB # 0 +0xBF94 0xD4ED # 0 +0xBF95 0xD4EE # 0 +0xBF96 0xD4EF # 0 +0xBF97 0xD4F1 # 0 +0xBF98 0xD4F2 # 0 +0xBF99 0xD4F3 # 0 +0xBF9A 0xD4F4 # 0 +0xBF9B 0xD4F5 # 0 +0xBF9C 0xD4F6 # 0 +0xBF9D 0xD4F7 # 0 +0xBF9E 0xD4F9 # 0 +0xBF9F 0xD4FA # 0 +0xBFA0 0xD4FC # 0 +0xBFA1 0xC5D0 # 0 +0xBFA2 0xC5D1 # 0 +0xBFA3 0xC5D4 # 0 +0xBFA4 0xC5D8 # 0 +0xBFA5 0xC5E0 # 0 +0xBFA6 0xC5E1 # 0 +0xBFA7 0xC5E3 # 0 +0xBFA8 0xC5E5 # 0 +0xBFA9 0xC5EC # 0 +0xBFAA 0xC5ED # 0 +0xBFAB 0xC5EE # 0 +0xBFAC 0xC5F0 # 0 +0xBFAD 0xC5F4 # 0 +0xBFAE 0xC5F6 # 0 +0xBFAF 0xC5F7 # 0 +0xBFB0 0xC5FC # 0 +0xBFB1 0xC5FD # 0 +0xBFB2 0xC5FE # 0 +0xBFB3 0xC5FF # 0 +0xBFB4 0xC600 # 0 +0xBFB5 0xC601 # 0 +0xBFB6 0xC605 # 0 +0xBFB7 0xC606 # 0 +0xBFB8 0xC607 # 0 +0xBFB9 0xC608 # 0 +0xBFBA 0xC60C # 0 +0xBFBB 0xC610 # 0 +0xBFBC 0xC618 # 0 +0xBFBD 0xC619 # 0 +0xBFBE 0xC61B # 0 +0xBFBF 0xC61C # 0 +0xBFC0 0xC624 # 0 +0xBFC1 0xC625 # 0 +0xBFC2 0xC628 # 0 +0xBFC3 0xC62C # 0 +0xBFC4 0xC62D # 0 +0xBFC5 0xC62E # 0 +0xBFC6 0xC630 # 0 +0xBFC7 0xC633 # 0 +0xBFC8 0xC634 # 0 +0xBFC9 0xC635 # 0 +0xBFCA 0xC637 # 0 +0xBFCB 0xC639 # 0 +0xBFCC 0xC63B # 0 +0xBFCD 0xC640 # 0 +0xBFCE 0xC641 # 0 +0xBFCF 0xC644 # 0 +0xBFD0 0xC648 # 0 +0xBFD1 0xC650 # 0 +0xBFD2 0xC651 # 0 +0xBFD3 0xC653 # 0 +0xBFD4 0xC654 # 0 +0xBFD5 0xC655 # 0 +0xBFD6 0xC65C # 0 +0xBFD7 0xC65D # 0 +0xBFD8 0xC660 # 0 +0xBFD9 0xC66C # 0 +0xBFDA 0xC66F # 0 +0xBFDB 0xC671 # 0 +0xBFDC 0xC678 # 0 +0xBFDD 0xC679 # 0 +0xBFDE 0xC67C # 0 +0xBFDF 0xC680 # 0 +0xBFE0 0xC688 # 0 +0xBFE1 0xC689 # 0 +0xBFE2 0xC68B # 0 +0xBFE3 0xC68D # 0 +0xBFE4 0xC694 # 0 +0xBFE5 0xC695 # 0 +0xBFE6 0xC698 # 0 +0xBFE7 0xC69C # 0 +0xBFE8 0xC6A4 # 0 +0xBFE9 0xC6A5 # 0 +0xBFEA 0xC6A7 # 0 +0xBFEB 0xC6A9 # 0 +0xBFEC 0xC6B0 # 0 +0xBFED 0xC6B1 # 0 +0xBFEE 0xC6B4 # 0 +0xBFEF 0xC6B8 # 0 +0xBFF0 0xC6B9 # 0 +0xBFF1 0xC6BA # 0 +0xBFF2 0xC6C0 # 0 +0xBFF3 0xC6C1 # 0 +0xBFF4 0xC6C3 # 0 +0xBFF5 0xC6C5 # 0 +0xBFF6 0xC6CC # 0 +0xBFF7 0xC6CD # 0 +0xBFF8 0xC6D0 # 0 +0xBFF9 0xC6D4 # 0 +0xBFFA 0xC6DC # 0 +0xBFFB 0xC6DD # 0 +0xBFFC 0xC6E0 # 0 +0xBFFD 0xC6E1 # 0 +0xBFFE 0xC6E8 # 0 +0xC041 0xD4FE # 0 +0xC042 0xD4FF # 0 +0xC043 0xD500 # 0 +0xC044 0xD501 # 0 +0xC045 0xD502 # 0 +0xC046 0xD503 # 0 +0xC047 0xD505 # 0 +0xC048 0xD506 # 0 +0xC049 0xD507 # 0 +0xC04A 0xD509 # 0 +0xC04B 0xD50A # 0 +0xC04C 0xD50B # 0 +0xC04D 0xD50D # 0 +0xC04E 0xD50E # 0 +0xC04F 0xD50F # 0 +0xC050 0xD510 # 0 +0xC051 0xD511 # 0 +0xC052 0xD512 # 0 +0xC053 0xD513 # 0 +0xC054 0xD516 # 0 +0xC055 0xD518 # 0 +0xC056 0xD519 # 0 +0xC057 0xD51A # 0 +0xC058 0xD51B # 0 +0xC059 0xD51C # 0 +0xC05A 0xD51D # 0 +0xC061 0xD51E # 0 +0xC062 0xD51F # 0 +0xC063 0xD520 # 0 +0xC064 0xD521 # 0 +0xC065 0xD522 # 0 +0xC066 0xD523 # 0 +0xC067 0xD524 # 0 +0xC068 0xD525 # 0 +0xC069 0xD526 # 0 +0xC06A 0xD527 # 0 +0xC06B 0xD528 # 0 +0xC06C 0xD529 # 0 +0xC06D 0xD52A # 0 +0xC06E 0xD52B # 0 +0xC06F 0xD52C # 0 +0xC070 0xD52D # 0 +0xC071 0xD52E # 0 +0xC072 0xD52F # 0 +0xC073 0xD530 # 0 +0xC074 0xD531 # 0 +0xC075 0xD532 # 0 +0xC076 0xD533 # 0 +0xC077 0xD534 # 0 +0xC078 0xD535 # 0 +0xC079 0xD536 # 0 +0xC07A 0xD537 # 0 +0xC081 0xD538 # 0 +0xC082 0xD539 # 0 +0xC083 0xD53A # 0 +0xC084 0xD53B # 0 +0xC085 0xD53E # 0 +0xC086 0xD53F # 0 +0xC087 0xD541 # 0 +0xC088 0xD542 # 0 +0xC089 0xD543 # 0 +0xC08A 0xD545 # 0 +0xC08B 0xD546 # 0 +0xC08C 0xD547 # 0 +0xC08D 0xD548 # 0 +0xC08E 0xD549 # 0 +0xC08F 0xD54A # 0 +0xC090 0xD54B # 0 +0xC091 0xD54E # 0 +0xC092 0xD550 # 0 +0xC093 0xD552 # 0 +0xC094 0xD553 # 0 +0xC095 0xD554 # 0 +0xC096 0xD555 # 0 +0xC097 0xD556 # 0 +0xC098 0xD557 # 0 +0xC099 0xD55A # 0 +0xC09A 0xD55B # 0 +0xC09B 0xD55D # 0 +0xC09C 0xD55E # 0 +0xC09D 0xD55F # 0 +0xC09E 0xD561 # 0 +0xC09F 0xD562 # 0 +0xC0A0 0xD563 # 0 +0xC0A1 0xC6E9 # 0 +0xC0A2 0xC6EC # 0 +0xC0A3 0xC6F0 # 0 +0xC0A4 0xC6F8 # 0 +0xC0A5 0xC6F9 # 0 +0xC0A6 0xC6FD # 0 +0xC0A7 0xC704 # 0 +0xC0A8 0xC705 # 0 +0xC0A9 0xC708 # 0 +0xC0AA 0xC70C # 0 +0xC0AB 0xC714 # 0 +0xC0AC 0xC715 # 0 +0xC0AD 0xC717 # 0 +0xC0AE 0xC719 # 0 +0xC0AF 0xC720 # 0 +0xC0B0 0xC721 # 0 +0xC0B1 0xC724 # 0 +0xC0B2 0xC728 # 0 +0xC0B3 0xC730 # 0 +0xC0B4 0xC731 # 0 +0xC0B5 0xC733 # 0 +0xC0B6 0xC735 # 0 +0xC0B7 0xC737 # 0 +0xC0B8 0xC73C # 0 +0xC0B9 0xC73D # 0 +0xC0BA 0xC740 # 0 +0xC0BB 0xC744 # 0 +0xC0BC 0xC74A # 0 +0xC0BD 0xC74C # 0 +0xC0BE 0xC74D # 0 +0xC0BF 0xC74F # 0 +0xC0C0 0xC751 # 0 +0xC0C1 0xC752 # 0 +0xC0C2 0xC753 # 0 +0xC0C3 0xC754 # 0 +0xC0C4 0xC755 # 0 +0xC0C5 0xC756 # 0 +0xC0C6 0xC757 # 0 +0xC0C7 0xC758 # 0 +0xC0C8 0xC75C # 0 +0xC0C9 0xC760 # 0 +0xC0CA 0xC768 # 0 +0xC0CB 0xC76B # 0 +0xC0CC 0xC774 # 0 +0xC0CD 0xC775 # 0 +0xC0CE 0xC778 # 0 +0xC0CF 0xC77C # 0 +0xC0D0 0xC77D # 0 +0xC0D1 0xC77E # 0 +0xC0D2 0xC783 # 0 +0xC0D3 0xC784 # 0 +0xC0D4 0xC785 # 0 +0xC0D5 0xC787 # 0 +0xC0D6 0xC788 # 0 +0xC0D7 0xC789 # 0 +0xC0D8 0xC78A # 0 +0xC0D9 0xC78E # 0 +0xC0DA 0xC790 # 0 +0xC0DB 0xC791 # 0 +0xC0DC 0xC794 # 0 +0xC0DD 0xC796 # 0 +0xC0DE 0xC797 # 0 +0xC0DF 0xC798 # 0 +0xC0E0 0xC79A # 0 +0xC0E1 0xC7A0 # 0 +0xC0E2 0xC7A1 # 0 +0xC0E3 0xC7A3 # 0 +0xC0E4 0xC7A4 # 0 +0xC0E5 0xC7A5 # 0 +0xC0E6 0xC7A6 # 0 +0xC0E7 0xC7AC # 0 +0xC0E8 0xC7AD # 0 +0xC0E9 0xC7B0 # 0 +0xC0EA 0xC7B4 # 0 +0xC0EB 0xC7BC # 0 +0xC0EC 0xC7BD # 0 +0xC0ED 0xC7BF # 0 +0xC0EE 0xC7C0 # 0 +0xC0EF 0xC7C1 # 0 +0xC0F0 0xC7C8 # 0 +0xC0F1 0xC7C9 # 0 +0xC0F2 0xC7CC # 0 +0xC0F3 0xC7CE # 0 +0xC0F4 0xC7D0 # 0 +0xC0F5 0xC7D8 # 0 +0xC0F6 0xC7DD # 0 +0xC0F7 0xC7E4 # 0 +0xC0F8 0xC7E8 # 0 +0xC0F9 0xC7EC # 0 +0xC0FA 0xC800 # 0 +0xC0FB 0xC801 # 0 +0xC0FC 0xC804 # 0 +0xC0FD 0xC808 # 0 +0xC0FE 0xC80A # 0 +0xC141 0xD564 # 0 +0xC142 0xD566 # 0 +0xC143 0xD567 # 0 +0xC144 0xD56A # 0 +0xC145 0xD56C # 0 +0xC146 0xD56E # 0 +0xC147 0xD56F # 0 +0xC148 0xD570 # 0 +0xC149 0xD571 # 0 +0xC14A 0xD572 # 0 +0xC14B 0xD573 # 0 +0xC14C 0xD576 # 0 +0xC14D 0xD577 # 0 +0xC14E 0xD579 # 0 +0xC14F 0xD57A # 0 +0xC150 0xD57B # 0 +0xC151 0xD57D # 0 +0xC152 0xD57E # 0 +0xC153 0xD57F # 0 +0xC154 0xD580 # 0 +0xC155 0xD581 # 0 +0xC156 0xD582 # 0 +0xC157 0xD583 # 0 +0xC158 0xD586 # 0 +0xC159 0xD58A # 0 +0xC15A 0xD58B # 0 +0xC161 0xD58C # 0 +0xC162 0xD58D # 0 +0xC163 0xD58E # 0 +0xC164 0xD58F # 0 +0xC165 0xD591 # 0 +0xC166 0xD592 # 0 +0xC167 0xD593 # 0 +0xC168 0xD594 # 0 +0xC169 0xD595 # 0 +0xC16A 0xD596 # 0 +0xC16B 0xD597 # 0 +0xC16C 0xD598 # 0 +0xC16D 0xD599 # 0 +0xC16E 0xD59A # 0 +0xC16F 0xD59B # 0 +0xC170 0xD59C # 0 +0xC171 0xD59D # 0 +0xC172 0xD59E # 0 +0xC173 0xD59F # 0 +0xC174 0xD5A0 # 0 +0xC175 0xD5A1 # 0 +0xC176 0xD5A2 # 0 +0xC177 0xD5A3 # 0 +0xC178 0xD5A4 # 0 +0xC179 0xD5A6 # 0 +0xC17A 0xD5A7 # 0 +0xC181 0xD5A8 # 0 +0xC182 0xD5A9 # 0 +0xC183 0xD5AA # 0 +0xC184 0xD5AB # 0 +0xC185 0xD5AC # 0 +0xC186 0xD5AD # 0 +0xC187 0xD5AE # 0 +0xC188 0xD5AF # 0 +0xC189 0xD5B0 # 0 +0xC18A 0xD5B1 # 0 +0xC18B 0xD5B2 # 0 +0xC18C 0xD5B3 # 0 +0xC18D 0xD5B4 # 0 +0xC18E 0xD5B5 # 0 +0xC18F 0xD5B6 # 0 +0xC190 0xD5B7 # 0 +0xC191 0xD5B8 # 0 +0xC192 0xD5B9 # 0 +0xC193 0xD5BA # 0 +0xC194 0xD5BB # 0 +0xC195 0xD5BC # 0 +0xC196 0xD5BD # 0 +0xC197 0xD5BE # 0 +0xC198 0xD5BF # 0 +0xC199 0xD5C0 # 0 +0xC19A 0xD5C1 # 0 +0xC19B 0xD5C2 # 0 +0xC19C 0xD5C3 # 0 +0xC19D 0xD5C4 # 0 +0xC19E 0xD5C5 # 0 +0xC19F 0xD5C6 # 0 +0xC1A0 0xD5C7 # 0 +0xC1A1 0xC810 # 0 +0xC1A2 0xC811 # 0 +0xC1A3 0xC813 # 0 +0xC1A4 0xC815 # 0 +0xC1A5 0xC816 # 0 +0xC1A6 0xC81C # 0 +0xC1A7 0xC81D # 0 +0xC1A8 0xC820 # 0 +0xC1A9 0xC824 # 0 +0xC1AA 0xC82C # 0 +0xC1AB 0xC82D # 0 +0xC1AC 0xC82F # 0 +0xC1AD 0xC831 # 0 +0xC1AE 0xC838 # 0 +0xC1AF 0xC83C # 0 +0xC1B0 0xC840 # 0 +0xC1B1 0xC848 # 0 +0xC1B2 0xC849 # 0 +0xC1B3 0xC84C # 0 +0xC1B4 0xC84D # 0 +0xC1B5 0xC854 # 0 +0xC1B6 0xC870 # 0 +0xC1B7 0xC871 # 0 +0xC1B8 0xC874 # 0 +0xC1B9 0xC878 # 0 +0xC1BA 0xC87A # 0 +0xC1BB 0xC880 # 0 +0xC1BC 0xC881 # 0 +0xC1BD 0xC883 # 0 +0xC1BE 0xC885 # 0 +0xC1BF 0xC886 # 0 +0xC1C0 0xC887 # 0 +0xC1C1 0xC88B # 0 +0xC1C2 0xC88C # 0 +0xC1C3 0xC88D # 0 +0xC1C4 0xC894 # 0 +0xC1C5 0xC89D # 0 +0xC1C6 0xC89F # 0 +0xC1C7 0xC8A1 # 0 +0xC1C8 0xC8A8 # 0 +0xC1C9 0xC8BC # 0 +0xC1CA 0xC8BD # 0 +0xC1CB 0xC8C4 # 0 +0xC1CC 0xC8C8 # 0 +0xC1CD 0xC8CC # 0 +0xC1CE 0xC8D4 # 0 +0xC1CF 0xC8D5 # 0 +0xC1D0 0xC8D7 # 0 +0xC1D1 0xC8D9 # 0 +0xC1D2 0xC8E0 # 0 +0xC1D3 0xC8E1 # 0 +0xC1D4 0xC8E4 # 0 +0xC1D5 0xC8F5 # 0 +0xC1D6 0xC8FC # 0 +0xC1D7 0xC8FD # 0 +0xC1D8 0xC900 # 0 +0xC1D9 0xC904 # 0 +0xC1DA 0xC905 # 0 +0xC1DB 0xC906 # 0 +0xC1DC 0xC90C # 0 +0xC1DD 0xC90D # 0 +0xC1DE 0xC90F # 0 +0xC1DF 0xC911 # 0 +0xC1E0 0xC918 # 0 +0xC1E1 0xC92C # 0 +0xC1E2 0xC934 # 0 +0xC1E3 0xC950 # 0 +0xC1E4 0xC951 # 0 +0xC1E5 0xC954 # 0 +0xC1E6 0xC958 # 0 +0xC1E7 0xC960 # 0 +0xC1E8 0xC961 # 0 +0xC1E9 0xC963 # 0 +0xC1EA 0xC96C # 0 +0xC1EB 0xC970 # 0 +0xC1EC 0xC974 # 0 +0xC1ED 0xC97C # 0 +0xC1EE 0xC988 # 0 +0xC1EF 0xC989 # 0 +0xC1F0 0xC98C # 0 +0xC1F1 0xC990 # 0 +0xC1F2 0xC998 # 0 +0xC1F3 0xC999 # 0 +0xC1F4 0xC99B # 0 +0xC1F5 0xC99D # 0 +0xC1F6 0xC9C0 # 0 +0xC1F7 0xC9C1 # 0 +0xC1F8 0xC9C4 # 0 +0xC1F9 0xC9C7 # 0 +0xC1FA 0xC9C8 # 0 +0xC1FB 0xC9CA # 0 +0xC1FC 0xC9D0 # 0 +0xC1FD 0xC9D1 # 0 +0xC1FE 0xC9D3 # 0 +0xC241 0xD5CA # 0 +0xC242 0xD5CB # 0 +0xC243 0xD5CD # 0 +0xC244 0xD5CE # 0 +0xC245 0xD5CF # 0 +0xC246 0xD5D1 # 0 +0xC247 0xD5D3 # 0 +0xC248 0xD5D4 # 0 +0xC249 0xD5D5 # 0 +0xC24A 0xD5D6 # 0 +0xC24B 0xD5D7 # 0 +0xC24C 0xD5DA # 0 +0xC24D 0xD5DC # 0 +0xC24E 0xD5DE # 0 +0xC24F 0xD5DF # 0 +0xC250 0xD5E0 # 0 +0xC251 0xD5E1 # 0 +0xC252 0xD5E2 # 0 +0xC253 0xD5E3 # 0 +0xC254 0xD5E6 # 0 +0xC255 0xD5E7 # 0 +0xC256 0xD5E9 # 0 +0xC257 0xD5EA # 0 +0xC258 0xD5EB # 0 +0xC259 0xD5ED # 0 +0xC25A 0xD5EE # 0 +0xC261 0xD5EF # 0 +0xC262 0xD5F0 # 0 +0xC263 0xD5F1 # 0 +0xC264 0xD5F2 # 0 +0xC265 0xD5F3 # 0 +0xC266 0xD5F6 # 0 +0xC267 0xD5F8 # 0 +0xC268 0xD5FA # 0 +0xC269 0xD5FB # 0 +0xC26A 0xD5FC # 0 +0xC26B 0xD5FD # 0 +0xC26C 0xD5FE # 0 +0xC26D 0xD5FF # 0 +0xC26E 0xD602 # 0 +0xC26F 0xD603 # 0 +0xC270 0xD605 # 0 +0xC271 0xD606 # 0 +0xC272 0xD607 # 0 +0xC273 0xD609 # 0 +0xC274 0xD60A # 0 +0xC275 0xD60B # 0 +0xC276 0xD60C # 0 +0xC277 0xD60D # 0 +0xC278 0xD60E # 0 +0xC279 0xD60F # 0 +0xC27A 0xD612 # 0 +0xC281 0xD616 # 0 +0xC282 0xD617 # 0 +0xC283 0xD618 # 0 +0xC284 0xD619 # 0 +0xC285 0xD61A # 0 +0xC286 0xD61B # 0 +0xC287 0xD61D # 0 +0xC288 0xD61E # 0 +0xC289 0xD61F # 0 +0xC28A 0xD621 # 0 +0xC28B 0xD622 # 0 +0xC28C 0xD623 # 0 +0xC28D 0xD625 # 0 +0xC28E 0xD626 # 0 +0xC28F 0xD627 # 0 +0xC290 0xD628 # 0 +0xC291 0xD629 # 0 +0xC292 0xD62A # 0 +0xC293 0xD62B # 0 +0xC294 0xD62C # 0 +0xC295 0xD62E # 0 +0xC296 0xD62F # 0 +0xC297 0xD630 # 0 +0xC298 0xD631 # 0 +0xC299 0xD632 # 0 +0xC29A 0xD633 # 0 +0xC29B 0xD634 # 0 +0xC29C 0xD635 # 0 +0xC29D 0xD636 # 0 +0xC29E 0xD637 # 0 +0xC29F 0xD63A # 0 +0xC2A0 0xD63B # 0 +0xC2A1 0xC9D5 # 0 +0xC2A2 0xC9D6 # 0 +0xC2A3 0xC9D9 # 0 +0xC2A4 0xC9DA # 0 +0xC2A5 0xC9DC # 0 +0xC2A6 0xC9DD # 0 +0xC2A7 0xC9E0 # 0 +0xC2A8 0xC9E2 # 0 +0xC2A9 0xC9E4 # 0 +0xC2AA 0xC9E7 # 0 +0xC2AB 0xC9EC # 0 +0xC2AC 0xC9ED # 0 +0xC2AD 0xC9EF # 0 +0xC2AE 0xC9F0 # 0 +0xC2AF 0xC9F1 # 0 +0xC2B0 0xC9F8 # 0 +0xC2B1 0xC9F9 # 0 +0xC2B2 0xC9FC # 0 +0xC2B3 0xCA00 # 0 +0xC2B4 0xCA08 # 0 +0xC2B5 0xCA09 # 0 +0xC2B6 0xCA0B # 0 +0xC2B7 0xCA0C # 0 +0xC2B8 0xCA0D # 0 +0xC2B9 0xCA14 # 0 +0xC2BA 0xCA18 # 0 +0xC2BB 0xCA29 # 0 +0xC2BC 0xCA4C # 0 +0xC2BD 0xCA4D # 0 +0xC2BE 0xCA50 # 0 +0xC2BF 0xCA54 # 0 +0xC2C0 0xCA5C # 0 +0xC2C1 0xCA5D # 0 +0xC2C2 0xCA5F # 0 +0xC2C3 0xCA60 # 0 +0xC2C4 0xCA61 # 0 +0xC2C5 0xCA68 # 0 +0xC2C6 0xCA7D # 0 +0xC2C7 0xCA84 # 0 +0xC2C8 0xCA98 # 0 +0xC2C9 0xCABC # 0 +0xC2CA 0xCABD # 0 +0xC2CB 0xCAC0 # 0 +0xC2CC 0xCAC4 # 0 +0xC2CD 0xCACC # 0 +0xC2CE 0xCACD # 0 +0xC2CF 0xCACF # 0 +0xC2D0 0xCAD1 # 0 +0xC2D1 0xCAD3 # 0 +0xC2D2 0xCAD8 # 0 +0xC2D3 0xCAD9 # 0 +0xC2D4 0xCAE0 # 0 +0xC2D5 0xCAEC # 0 +0xC2D6 0xCAF4 # 0 +0xC2D7 0xCB08 # 0 +0xC2D8 0xCB10 # 0 +0xC2D9 0xCB14 # 0 +0xC2DA 0xCB18 # 0 +0xC2DB 0xCB20 # 0 +0xC2DC 0xCB21 # 0 +0xC2DD 0xCB41 # 0 +0xC2DE 0xCB48 # 0 +0xC2DF 0xCB49 # 0 +0xC2E0 0xCB4C # 0 +0xC2E1 0xCB50 # 0 +0xC2E2 0xCB58 # 0 +0xC2E3 0xCB59 # 0 +0xC2E4 0xCB5D # 0 +0xC2E5 0xCB64 # 0 +0xC2E6 0xCB78 # 0 +0xC2E7 0xCB79 # 0 +0xC2E8 0xCB9C # 0 +0xC2E9 0xCBB8 # 0 +0xC2EA 0xCBD4 # 0 +0xC2EB 0xCBE4 # 0 +0xC2EC 0xCBE7 # 0 +0xC2ED 0xCBE9 # 0 +0xC2EE 0xCC0C # 0 +0xC2EF 0xCC0D # 0 +0xC2F0 0xCC10 # 0 +0xC2F1 0xCC14 # 0 +0xC2F2 0xCC1C # 0 +0xC2F3 0xCC1D # 0 +0xC2F4 0xCC21 # 0 +0xC2F5 0xCC22 # 0 +0xC2F6 0xCC27 # 0 +0xC2F7 0xCC28 # 0 +0xC2F8 0xCC29 # 0 +0xC2F9 0xCC2C # 0 +0xC2FA 0xCC2E # 0 +0xC2FB 0xCC30 # 0 +0xC2FC 0xCC38 # 0 +0xC2FD 0xCC39 # 0 +0xC2FE 0xCC3B # 0 +0xC341 0xD63D # 0 +0xC342 0xD63E # 0 +0xC343 0xD63F # 0 +0xC344 0xD641 # 0 +0xC345 0xD642 # 0 +0xC346 0xD643 # 0 +0xC347 0xD644 # 0 +0xC348 0xD646 # 0 +0xC349 0xD647 # 0 +0xC34A 0xD64A # 0 +0xC34B 0xD64C # 0 +0xC34C 0xD64E # 0 +0xC34D 0xD64F # 0 +0xC34E 0xD650 # 0 +0xC34F 0xD652 # 0 +0xC350 0xD653 # 0 +0xC351 0xD656 # 0 +0xC352 0xD657 # 0 +0xC353 0xD659 # 0 +0xC354 0xD65A # 0 +0xC355 0xD65B # 0 +0xC356 0xD65D # 0 +0xC357 0xD65E # 0 +0xC358 0xD65F # 0 +0xC359 0xD660 # 0 +0xC35A 0xD661 # 0 +0xC361 0xD662 # 0 +0xC362 0xD663 # 0 +0xC363 0xD664 # 0 +0xC364 0xD665 # 0 +0xC365 0xD666 # 0 +0xC366 0xD668 # 0 +0xC367 0xD66A # 0 +0xC368 0xD66B # 0 +0xC369 0xD66C # 0 +0xC36A 0xD66D # 0 +0xC36B 0xD66E # 0 +0xC36C 0xD66F # 0 +0xC36D 0xD672 # 0 +0xC36E 0xD673 # 0 +0xC36F 0xD675 # 0 +0xC370 0xD676 # 0 +0xC371 0xD677 # 0 +0xC372 0xD678 # 0 +0xC373 0xD679 # 0 +0xC374 0xD67A # 0 +0xC375 0xD67B # 0 +0xC376 0xD67C # 0 +0xC377 0xD67D # 0 +0xC378 0xD67E # 0 +0xC379 0xD67F # 0 +0xC37A 0xD680 # 0 +0xC381 0xD681 # 0 +0xC382 0xD682 # 0 +0xC383 0xD684 # 0 +0xC384 0xD686 # 0 +0xC385 0xD687 # 0 +0xC386 0xD688 # 0 +0xC387 0xD689 # 0 +0xC388 0xD68A # 0 +0xC389 0xD68B # 0 +0xC38A 0xD68E # 0 +0xC38B 0xD68F # 0 +0xC38C 0xD691 # 0 +0xC38D 0xD692 # 0 +0xC38E 0xD693 # 0 +0xC38F 0xD695 # 0 +0xC390 0xD696 # 0 +0xC391 0xD697 # 0 +0xC392 0xD698 # 0 +0xC393 0xD699 # 0 +0xC394 0xD69A # 0 +0xC395 0xD69B # 0 +0xC396 0xD69C # 0 +0xC397 0xD69E # 0 +0xC398 0xD6A0 # 0 +0xC399 0xD6A2 # 0 +0xC39A 0xD6A3 # 0 +0xC39B 0xD6A4 # 0 +0xC39C 0xD6A5 # 0 +0xC39D 0xD6A6 # 0 +0xC39E 0xD6A7 # 0 +0xC39F 0xD6A9 # 0 +0xC3A0 0xD6AA # 0 +0xC3A1 0xCC3C # 0 +0xC3A2 0xCC3D # 0 +0xC3A3 0xCC3E # 0 +0xC3A4 0xCC44 # 0 +0xC3A5 0xCC45 # 0 +0xC3A6 0xCC48 # 0 +0xC3A7 0xCC4C # 0 +0xC3A8 0xCC54 # 0 +0xC3A9 0xCC55 # 0 +0xC3AA 0xCC57 # 0 +0xC3AB 0xCC58 # 0 +0xC3AC 0xCC59 # 0 +0xC3AD 0xCC60 # 0 +0xC3AE 0xCC64 # 0 +0xC3AF 0xCC66 # 0 +0xC3B0 0xCC68 # 0 +0xC3B1 0xCC70 # 0 +0xC3B2 0xCC75 # 0 +0xC3B3 0xCC98 # 0 +0xC3B4 0xCC99 # 0 +0xC3B5 0xCC9C # 0 +0xC3B6 0xCCA0 # 0 +0xC3B7 0xCCA8 # 0 +0xC3B8 0xCCA9 # 0 +0xC3B9 0xCCAB # 0 +0xC3BA 0xCCAC # 0 +0xC3BB 0xCCAD # 0 +0xC3BC 0xCCB4 # 0 +0xC3BD 0xCCB5 # 0 +0xC3BE 0xCCB8 # 0 +0xC3BF 0xCCBC # 0 +0xC3C0 0xCCC4 # 0 +0xC3C1 0xCCC5 # 0 +0xC3C2 0xCCC7 # 0 +0xC3C3 0xCCC9 # 0 +0xC3C4 0xCCD0 # 0 +0xC3C5 0xCCD4 # 0 +0xC3C6 0xCCE4 # 0 +0xC3C7 0xCCEC # 0 +0xC3C8 0xCCF0 # 0 +0xC3C9 0xCD01 # 0 +0xC3CA 0xCD08 # 0 +0xC3CB 0xCD09 # 0 +0xC3CC 0xCD0C # 0 +0xC3CD 0xCD10 # 0 +0xC3CE 0xCD18 # 0 +0xC3CF 0xCD19 # 0 +0xC3D0 0xCD1B # 0 +0xC3D1 0xCD1D # 0 +0xC3D2 0xCD24 # 0 +0xC3D3 0xCD28 # 0 +0xC3D4 0xCD2C # 0 +0xC3D5 0xCD39 # 0 +0xC3D6 0xCD5C # 0 +0xC3D7 0xCD60 # 0 +0xC3D8 0xCD64 # 0 +0xC3D9 0xCD6C # 0 +0xC3DA 0xCD6D # 0 +0xC3DB 0xCD6F # 0 +0xC3DC 0xCD71 # 0 +0xC3DD 0xCD78 # 0 +0xC3DE 0xCD88 # 0 +0xC3DF 0xCD94 # 0 +0xC3E0 0xCD95 # 0 +0xC3E1 0xCD98 # 0 +0xC3E2 0xCD9C # 0 +0xC3E3 0xCDA4 # 0 +0xC3E4 0xCDA5 # 0 +0xC3E5 0xCDA7 # 0 +0xC3E6 0xCDA9 # 0 +0xC3E7 0xCDB0 # 0 +0xC3E8 0xCDC4 # 0 +0xC3E9 0xCDCC # 0 +0xC3EA 0xCDD0 # 0 +0xC3EB 0xCDE8 # 0 +0xC3EC 0xCDEC # 0 +0xC3ED 0xCDF0 # 0 +0xC3EE 0xCDF8 # 0 +0xC3EF 0xCDF9 # 0 +0xC3F0 0xCDFB # 0 +0xC3F1 0xCDFD # 0 +0xC3F2 0xCE04 # 0 +0xC3F3 0xCE08 # 0 +0xC3F4 0xCE0C # 0 +0xC3F5 0xCE14 # 0 +0xC3F6 0xCE19 # 0 +0xC3F7 0xCE20 # 0 +0xC3F8 0xCE21 # 0 +0xC3F9 0xCE24 # 0 +0xC3FA 0xCE28 # 0 +0xC3FB 0xCE30 # 0 +0xC3FC 0xCE31 # 0 +0xC3FD 0xCE33 # 0 +0xC3FE 0xCE35 # 0 +0xC441 0xD6AB # 0 +0xC442 0xD6AD # 0 +0xC443 0xD6AE # 0 +0xC444 0xD6AF # 0 +0xC445 0xD6B1 # 0 +0xC446 0xD6B2 # 0 +0xC447 0xD6B3 # 0 +0xC448 0xD6B4 # 0 +0xC449 0xD6B5 # 0 +0xC44A 0xD6B6 # 0 +0xC44B 0xD6B7 # 0 +0xC44C 0xD6B8 # 0 +0xC44D 0xD6BA # 0 +0xC44E 0xD6BC # 0 +0xC44F 0xD6BD # 0 +0xC450 0xD6BE # 0 +0xC451 0xD6BF # 0 +0xC452 0xD6C0 # 0 +0xC453 0xD6C1 # 0 +0xC454 0xD6C2 # 0 +0xC455 0xD6C3 # 0 +0xC456 0xD6C6 # 0 +0xC457 0xD6C7 # 0 +0xC458 0xD6C9 # 0 +0xC459 0xD6CA # 0 +0xC45A 0xD6CB # 0 +0xC461 0xD6CD # 0 +0xC462 0xD6CE # 0 +0xC463 0xD6CF # 0 +0xC464 0xD6D0 # 0 +0xC465 0xD6D2 # 0 +0xC466 0xD6D3 # 0 +0xC467 0xD6D5 # 0 +0xC468 0xD6D6 # 0 +0xC469 0xD6D8 # 0 +0xC46A 0xD6DA # 0 +0xC46B 0xD6DB # 0 +0xC46C 0xD6DC # 0 +0xC46D 0xD6DD # 0 +0xC46E 0xD6DE # 0 +0xC46F 0xD6DF # 0 +0xC470 0xD6E1 # 0 +0xC471 0xD6E2 # 0 +0xC472 0xD6E3 # 0 +0xC473 0xD6E5 # 0 +0xC474 0xD6E6 # 0 +0xC475 0xD6E7 # 0 +0xC476 0xD6E9 # 0 +0xC477 0xD6EA # 0 +0xC478 0xD6EB # 0 +0xC479 0xD6EC # 0 +0xC47A 0xD6ED # 0 +0xC481 0xD6EE # 0 +0xC482 0xD6EF # 0 +0xC483 0xD6F1 # 0 +0xC484 0xD6F2 # 0 +0xC485 0xD6F3 # 0 +0xC486 0xD6F4 # 0 +0xC487 0xD6F6 # 0 +0xC488 0xD6F7 # 0 +0xC489 0xD6F8 # 0 +0xC48A 0xD6F9 # 0 +0xC48B 0xD6FA # 0 +0xC48C 0xD6FB # 0 +0xC48D 0xD6FE # 0 +0xC48E 0xD6FF # 0 +0xC48F 0xD701 # 0 +0xC490 0xD702 # 0 +0xC491 0xD703 # 0 +0xC492 0xD705 # 0 +0xC493 0xD706 # 0 +0xC494 0xD707 # 0 +0xC495 0xD708 # 0 +0xC496 0xD709 # 0 +0xC497 0xD70A # 0 +0xC498 0xD70B # 0 +0xC499 0xD70C # 0 +0xC49A 0xD70D # 0 +0xC49B 0xD70E # 0 +0xC49C 0xD70F # 0 +0xC49D 0xD710 # 0 +0xC49E 0xD712 # 0 +0xC49F 0xD713 # 0 +0xC4A0 0xD714 # 0 +0xC4A1 0xCE58 # 0 +0xC4A2 0xCE59 # 0 +0xC4A3 0xCE5C # 0 +0xC4A4 0xCE5F # 0 +0xC4A5 0xCE60 # 0 +0xC4A6 0xCE61 # 0 +0xC4A7 0xCE68 # 0 +0xC4A8 0xCE69 # 0 +0xC4A9 0xCE6B # 0 +0xC4AA 0xCE6D # 0 +0xC4AB 0xCE74 # 0 +0xC4AC 0xCE75 # 0 +0xC4AD 0xCE78 # 0 +0xC4AE 0xCE7C # 0 +0xC4AF 0xCE84 # 0 +0xC4B0 0xCE85 # 0 +0xC4B1 0xCE87 # 0 +0xC4B2 0xCE89 # 0 +0xC4B3 0xCE90 # 0 +0xC4B4 0xCE91 # 0 +0xC4B5 0xCE94 # 0 +0xC4B6 0xCE98 # 0 +0xC4B7 0xCEA0 # 0 +0xC4B8 0xCEA1 # 0 +0xC4B9 0xCEA3 # 0 +0xC4BA 0xCEA4 # 0 +0xC4BB 0xCEA5 # 0 +0xC4BC 0xCEAC # 0 +0xC4BD 0xCEAD # 0 +0xC4BE 0xCEC1 # 0 +0xC4BF 0xCEE4 # 0 +0xC4C0 0xCEE5 # 0 +0xC4C1 0xCEE8 # 0 +0xC4C2 0xCEEB # 0 +0xC4C3 0xCEEC # 0 +0xC4C4 0xCEF4 # 0 +0xC4C5 0xCEF5 # 0 +0xC4C6 0xCEF7 # 0 +0xC4C7 0xCEF8 # 0 +0xC4C8 0xCEF9 # 0 +0xC4C9 0xCF00 # 0 +0xC4CA 0xCF01 # 0 +0xC4CB 0xCF04 # 0 +0xC4CC 0xCF08 # 0 +0xC4CD 0xCF10 # 0 +0xC4CE 0xCF11 # 0 +0xC4CF 0xCF13 # 0 +0xC4D0 0xCF15 # 0 +0xC4D1 0xCF1C # 0 +0xC4D2 0xCF20 # 0 +0xC4D3 0xCF24 # 0 +0xC4D4 0xCF2C # 0 +0xC4D5 0xCF2D # 0 +0xC4D6 0xCF2F # 0 +0xC4D7 0xCF30 # 0 +0xC4D8 0xCF31 # 0 +0xC4D9 0xCF38 # 0 +0xC4DA 0xCF54 # 0 +0xC4DB 0xCF55 # 0 +0xC4DC 0xCF58 # 0 +0xC4DD 0xCF5C # 0 +0xC4DE 0xCF64 # 0 +0xC4DF 0xCF65 # 0 +0xC4E0 0xCF67 # 0 +0xC4E1 0xCF69 # 0 +0xC4E2 0xCF70 # 0 +0xC4E3 0xCF71 # 0 +0xC4E4 0xCF74 # 0 +0xC4E5 0xCF78 # 0 +0xC4E6 0xCF80 # 0 +0xC4E7 0xCF85 # 0 +0xC4E8 0xCF8C # 0 +0xC4E9 0xCFA1 # 0 +0xC4EA 0xCFA8 # 0 +0xC4EB 0xCFB0 # 0 +0xC4EC 0xCFC4 # 0 +0xC4ED 0xCFE0 # 0 +0xC4EE 0xCFE1 # 0 +0xC4EF 0xCFE4 # 0 +0xC4F0 0xCFE8 # 0 +0xC4F1 0xCFF0 # 0 +0xC4F2 0xCFF1 # 0 +0xC4F3 0xCFF3 # 0 +0xC4F4 0xCFF5 # 0 +0xC4F5 0xCFFC # 0 +0xC4F6 0xD000 # 0 +0xC4F7 0xD004 # 0 +0xC4F8 0xD011 # 0 +0xC4F9 0xD018 # 0 +0xC4FA 0xD02D # 0 +0xC4FB 0xD034 # 0 +0xC4FC 0xD035 # 0 +0xC4FD 0xD038 # 0 +0xC4FE 0xD03C # 0 +0xC541 0xD715 # 0 +0xC542 0xD716 # 0 +0xC543 0xD717 # 0 +0xC544 0xD71A # 0 +0xC545 0xD71B # 0 +0xC546 0xD71D # 0 +0xC547 0xD71E # 0 +0xC548 0xD71F # 0 +0xC549 0xD721 # 0 +0xC54A 0xD722 # 0 +0xC54B 0xD723 # 0 +0xC54C 0xD724 # 0 +0xC54D 0xD725 # 0 +0xC54E 0xD726 # 0 +0xC54F 0xD727 # 0 +0xC550 0xD72A # 0 +0xC551 0xD72C # 0 +0xC552 0xD72E # 0 +0xC553 0xD72F # 0 +0xC554 0xD730 # 0 +0xC555 0xD731 # 0 +0xC556 0xD732 # 0 +0xC557 0xD733 # 0 +0xC558 0xD736 # 0 +0xC559 0xD737 # 0 +0xC55A 0xD739 # 0 +0xC561 0xD73A # 0 +0xC562 0xD73B # 0 +0xC563 0xD73D # 0 +0xC564 0xD73E # 0 +0xC565 0xD73F # 0 +0xC566 0xD740 # 0 +0xC567 0xD741 # 0 +0xC568 0xD742 # 0 +0xC569 0xD743 # 0 +0xC56A 0xD745 # 0 +0xC56B 0xD746 # 0 +0xC56C 0xD748 # 0 +0xC56D 0xD74A # 0 +0xC56E 0xD74B # 0 +0xC56F 0xD74C # 0 +0xC570 0xD74D # 0 +0xC571 0xD74E # 0 +0xC572 0xD74F # 0 +0xC573 0xD752 # 0 +0xC574 0xD753 # 0 +0xC575 0xD755 # 0 +0xC576 0xD75A # 0 +0xC577 0xD75B # 0 +0xC578 0xD75C # 0 +0xC579 0xD75D # 0 +0xC57A 0xD75E # 0 +0xC581 0xD75F # 0 +0xC582 0xD762 # 0 +0xC583 0xD764 # 0 +0xC584 0xD766 # 0 +0xC585 0xD767 # 0 +0xC586 0xD768 # 0 +0xC587 0xD76A # 0 +0xC588 0xD76B # 0 +0xC589 0xD76D # 0 +0xC58A 0xD76E # 0 +0xC58B 0xD76F # 0 +0xC58C 0xD771 # 0 +0xC58D 0xD772 # 0 +0xC58E 0xD773 # 0 +0xC58F 0xD775 # 0 +0xC590 0xD776 # 0 +0xC591 0xD777 # 0 +0xC592 0xD778 # 0 +0xC593 0xD779 # 0 +0xC594 0xD77A # 0 +0xC595 0xD77B # 0 +0xC596 0xD77E # 0 +0xC597 0xD77F # 0 +0xC598 0xD780 # 0 +0xC599 0xD782 # 0 +0xC59A 0xD783 # 0 +0xC59B 0xD784 # 0 +0xC59C 0xD785 # 0 +0xC59D 0xD786 # 0 +0xC59E 0xD787 # 0 +0xC59F 0xD78A # 0 +0xC5A0 0xD78B # 0 +0xC5A1 0xD044 # 0 +0xC5A2 0xD045 # 0 +0xC5A3 0xD047 # 0 +0xC5A4 0xD049 # 0 +0xC5A5 0xD050 # 0 +0xC5A6 0xD054 # 0 +0xC5A7 0xD058 # 0 +0xC5A8 0xD060 # 0 +0xC5A9 0xD06C # 0 +0xC5AA 0xD06D # 0 +0xC5AB 0xD070 # 0 +0xC5AC 0xD074 # 0 +0xC5AD 0xD07C # 0 +0xC5AE 0xD07D # 0 +0xC5AF 0xD081 # 0 +0xC5B0 0xD0A4 # 0 +0xC5B1 0xD0A5 # 0 +0xC5B2 0xD0A8 # 0 +0xC5B3 0xD0AC # 0 +0xC5B4 0xD0B4 # 0 +0xC5B5 0xD0B5 # 0 +0xC5B6 0xD0B7 # 0 +0xC5B7 0xD0B9 # 0 +0xC5B8 0xD0C0 # 0 +0xC5B9 0xD0C1 # 0 +0xC5BA 0xD0C4 # 0 +0xC5BB 0xD0C8 # 0 +0xC5BC 0xD0C9 # 0 +0xC5BD 0xD0D0 # 0 +0xC5BE 0xD0D1 # 0 +0xC5BF 0xD0D3 # 0 +0xC5C0 0xD0D4 # 0 +0xC5C1 0xD0D5 # 0 +0xC5C2 0xD0DC # 0 +0xC5C3 0xD0DD # 0 +0xC5C4 0xD0E0 # 0 +0xC5C5 0xD0E4 # 0 +0xC5C6 0xD0EC # 0 +0xC5C7 0xD0ED # 0 +0xC5C8 0xD0EF # 0 +0xC5C9 0xD0F0 # 0 +0xC5CA 0xD0F1 # 0 +0xC5CB 0xD0F8 # 0 +0xC5CC 0xD10D # 0 +0xC5CD 0xD130 # 0 +0xC5CE 0xD131 # 0 +0xC5CF 0xD134 # 0 +0xC5D0 0xD138 # 0 +0xC5D1 0xD13A # 0 +0xC5D2 0xD140 # 0 +0xC5D3 0xD141 # 0 +0xC5D4 0xD143 # 0 +0xC5D5 0xD144 # 0 +0xC5D6 0xD145 # 0 +0xC5D7 0xD14C # 0 +0xC5D8 0xD14D # 0 +0xC5D9 0xD150 # 0 +0xC5DA 0xD154 # 0 +0xC5DB 0xD15C # 0 +0xC5DC 0xD15D # 0 +0xC5DD 0xD15F # 0 +0xC5DE 0xD161 # 0 +0xC5DF 0xD168 # 0 +0xC5E0 0xD16C # 0 +0xC5E1 0xD17C # 0 +0xC5E2 0xD184 # 0 +0xC5E3 0xD188 # 0 +0xC5E4 0xD1A0 # 0 +0xC5E5 0xD1A1 # 0 +0xC5E6 0xD1A4 # 0 +0xC5E7 0xD1A8 # 0 +0xC5E8 0xD1B0 # 0 +0xC5E9 0xD1B1 # 0 +0xC5EA 0xD1B3 # 0 +0xC5EB 0xD1B5 # 0 +0xC5EC 0xD1BA # 0 +0xC5ED 0xD1BC # 0 +0xC5EE 0xD1C0 # 0 +0xC5EF 0xD1D8 # 0 +0xC5F0 0xD1F4 # 0 +0xC5F1 0xD1F8 # 0 +0xC5F2 0xD207 # 0 +0xC5F3 0xD209 # 0 +0xC5F4 0xD210 # 0 +0xC5F5 0xD22C # 0 +0xC5F6 0xD22D # 0 +0xC5F7 0xD230 # 0 +0xC5F8 0xD234 # 0 +0xC5F9 0xD23C # 0 +0xC5FA 0xD23D # 0 +0xC5FB 0xD23F # 0 +0xC5FC 0xD241 # 0 +0xC5FD 0xD248 # 0 +0xC5FE 0xD25C # 0 +0xC641 0xD78D # 0 +0xC642 0xD78E # 0 +0xC643 0xD78F # 0 +0xC644 0xD791 # 0 +0xC645 0xD792 # 0 +0xC646 0xD793 # 0 +0xC647 0xD794 # 0 +0xC648 0xD795 # 0 +0xC649 0xD796 # 0 +0xC64A 0xD797 # 0 +0xC64B 0xD79A # 0 +0xC64C 0xD79C # 0 +0xC64D 0xD79E # 0 +0xC64E 0xD79F # 0 +0xC64F 0xD7A0 # 0 +0xC650 0xD7A1 # 0 +0xC651 0xD7A2 # 0 +0xC652 0xD7A3 # 0 +0xC6A1 0xD264 # 0 +0xC6A2 0xD280 # 0 +0xC6A3 0xD281 # 0 +0xC6A4 0xD284 # 0 +0xC6A5 0xD288 # 0 +0xC6A6 0xD290 # 0 +0xC6A7 0xD291 # 0 +0xC6A8 0xD295 # 0 +0xC6A9 0xD29C # 0 +0xC6AA 0xD2A0 # 0 +0xC6AB 0xD2A4 # 0 +0xC6AC 0xD2AC # 0 +0xC6AD 0xD2B1 # 0 +0xC6AE 0xD2B8 # 0 +0xC6AF 0xD2B9 # 0 +0xC6B0 0xD2BC # 0 +0xC6B1 0xD2BF # 0 +0xC6B2 0xD2C0 # 0 +0xC6B3 0xD2C2 # 0 +0xC6B4 0xD2C8 # 0 +0xC6B5 0xD2C9 # 0 +0xC6B6 0xD2CB # 0 +0xC6B7 0xD2D4 # 0 +0xC6B8 0xD2D8 # 0 +0xC6B9 0xD2DC # 0 +0xC6BA 0xD2E4 # 0 +0xC6BB 0xD2E5 # 0 +0xC6BC 0xD2F0 # 0 +0xC6BD 0xD2F1 # 0 +0xC6BE 0xD2F4 # 0 +0xC6BF 0xD2F8 # 0 +0xC6C0 0xD300 # 0 +0xC6C1 0xD301 # 0 +0xC6C2 0xD303 # 0 +0xC6C3 0xD305 # 0 +0xC6C4 0xD30C # 0 +0xC6C5 0xD30D # 0 +0xC6C6 0xD30E # 0 +0xC6C7 0xD310 # 0 +0xC6C8 0xD314 # 0 +0xC6C9 0xD316 # 0 +0xC6CA 0xD31C # 0 +0xC6CB 0xD31D # 0 +0xC6CC 0xD31F # 0 +0xC6CD 0xD320 # 0 +0xC6CE 0xD321 # 0 +0xC6CF 0xD325 # 0 +0xC6D0 0xD328 # 0 +0xC6D1 0xD329 # 0 +0xC6D2 0xD32C # 0 +0xC6D3 0xD330 # 0 +0xC6D4 0xD338 # 0 +0xC6D5 0xD339 # 0 +0xC6D6 0xD33B # 0 +0xC6D7 0xD33C # 0 +0xC6D8 0xD33D # 0 +0xC6D9 0xD344 # 0 +0xC6DA 0xD345 # 0 +0xC6DB 0xD37C # 0 +0xC6DC 0xD37D # 0 +0xC6DD 0xD380 # 0 +0xC6DE 0xD384 # 0 +0xC6DF 0xD38C # 0 +0xC6E0 0xD38D # 0 +0xC6E1 0xD38F # 0 +0xC6E2 0xD390 # 0 +0xC6E3 0xD391 # 0 +0xC6E4 0xD398 # 0 +0xC6E5 0xD399 # 0 +0xC6E6 0xD39C # 0 +0xC6E7 0xD3A0 # 0 +0xC6E8 0xD3A8 # 0 +0xC6E9 0xD3A9 # 0 +0xC6EA 0xD3AB # 0 +0xC6EB 0xD3AD # 0 +0xC6EC 0xD3B4 # 0 +0xC6ED 0xD3B8 # 0 +0xC6EE 0xD3BC # 0 +0xC6EF 0xD3C4 # 0 +0xC6F0 0xD3C5 # 0 +0xC6F1 0xD3C8 # 0 +0xC6F2 0xD3C9 # 0 +0xC6F3 0xD3D0 # 0 +0xC6F4 0xD3D8 # 0 +0xC6F5 0xD3E1 # 0 +0xC6F6 0xD3E3 # 0 +0xC6F7 0xD3EC # 0 +0xC6F8 0xD3ED # 0 +0xC6F9 0xD3F0 # 0 +0xC6FA 0xD3F4 # 0 +0xC6FB 0xD3FC # 0 +0xC6FC 0xD3FD # 0 +0xC6FD 0xD3FF # 0 +0xC6FE 0xD401 # 0 +0xC7A1 0xD408 # 0 +0xC7A2 0xD41D # 0 +0xC7A3 0xD440 # 0 +0xC7A4 0xD444 # 0 +0xC7A5 0xD45C # 0 +0xC7A6 0xD460 # 0 +0xC7A7 0xD464 # 0 +0xC7A8 0xD46D # 0 +0xC7A9 0xD46F # 0 +0xC7AA 0xD478 # 0 +0xC7AB 0xD479 # 0 +0xC7AC 0xD47C # 0 +0xC7AD 0xD47F # 0 +0xC7AE 0xD480 # 0 +0xC7AF 0xD482 # 0 +0xC7B0 0xD488 # 0 +0xC7B1 0xD489 # 0 +0xC7B2 0xD48B # 0 +0xC7B3 0xD48D # 0 +0xC7B4 0xD494 # 0 +0xC7B5 0xD4A9 # 0 +0xC7B6 0xD4CC # 0 +0xC7B7 0xD4D0 # 0 +0xC7B8 0xD4D4 # 0 +0xC7B9 0xD4DC # 0 +0xC7BA 0xD4DF # 0 +0xC7BB 0xD4E8 # 0 +0xC7BC 0xD4EC # 0 +0xC7BD 0xD4F0 # 0 +0xC7BE 0xD4F8 # 0 +0xC7BF 0xD4FB # 0 +0xC7C0 0xD4FD # 0 +0xC7C1 0xD504 # 0 +0xC7C2 0xD508 # 0 +0xC7C3 0xD50C # 0 +0xC7C4 0xD514 # 0 +0xC7C5 0xD515 # 0 +0xC7C6 0xD517 # 0 +0xC7C7 0xD53C # 0 +0xC7C8 0xD53D # 0 +0xC7C9 0xD540 # 0 +0xC7CA 0xD544 # 0 +0xC7CB 0xD54C # 0 +0xC7CC 0xD54D # 0 +0xC7CD 0xD54F # 0 +0xC7CE 0xD551 # 0 +0xC7CF 0xD558 # 0 +0xC7D0 0xD559 # 0 +0xC7D1 0xD55C # 0 +0xC7D2 0xD560 # 0 +0xC7D3 0xD565 # 0 +0xC7D4 0xD568 # 0 +0xC7D5 0xD569 # 0 +0xC7D6 0xD56B # 0 +0xC7D7 0xD56D # 0 +0xC7D8 0xD574 # 0 +0xC7D9 0xD575 # 0 +0xC7DA 0xD578 # 0 +0xC7DB 0xD57C # 0 +0xC7DC 0xD584 # 0 +0xC7DD 0xD585 # 0 +0xC7DE 0xD587 # 0 +0xC7DF 0xD588 # 0 +0xC7E0 0xD589 # 0 +0xC7E1 0xD590 # 0 +0xC7E2 0xD5A5 # 0 +0xC7E3 0xD5C8 # 0 +0xC7E4 0xD5C9 # 0 +0xC7E5 0xD5CC # 0 +0xC7E6 0xD5D0 # 0 +0xC7E7 0xD5D2 # 0 +0xC7E8 0xD5D8 # 0 +0xC7E9 0xD5D9 # 0 +0xC7EA 0xD5DB # 0 +0xC7EB 0xD5DD # 0 +0xC7EC 0xD5E4 # 0 +0xC7ED 0xD5E5 # 0 +0xC7EE 0xD5E8 # 0 +0xC7EF 0xD5EC # 0 +0xC7F0 0xD5F4 # 0 +0xC7F1 0xD5F5 # 0 +0xC7F2 0xD5F7 # 0 +0xC7F3 0xD5F9 # 0 +0xC7F4 0xD600 # 0 +0xC7F5 0xD601 # 0 +0xC7F6 0xD604 # 0 +0xC7F7 0xD608 # 0 +0xC7F8 0xD610 # 0 +0xC7F9 0xD611 # 0 +0xC7FA 0xD613 # 0 +0xC7FB 0xD614 # 0 +0xC7FC 0xD615 # 0 +0xC7FD 0xD61C # 0 +0xC7FE 0xD620 # 0 +0xC8A1 0xD624 # 0 +0xC8A2 0xD62D # 0 +0xC8A3 0xD638 # 0 +0xC8A4 0xD639 # 0 +0xC8A5 0xD63C # 0 +0xC8A6 0xD640 # 0 +0xC8A7 0xD645 # 0 +0xC8A8 0xD648 # 0 +0xC8A9 0xD649 # 0 +0xC8AA 0xD64B # 0 +0xC8AB 0xD64D # 0 +0xC8AC 0xD651 # 0 +0xC8AD 0xD654 # 0 +0xC8AE 0xD655 # 0 +0xC8AF 0xD658 # 0 +0xC8B0 0xD65C # 0 +0xC8B1 0xD667 # 0 +0xC8B2 0xD669 # 0 +0xC8B3 0xD670 # 0 +0xC8B4 0xD671 # 0 +0xC8B5 0xD674 # 0 +0xC8B6 0xD683 # 0 +0xC8B7 0xD685 # 0 +0xC8B8 0xD68C # 0 +0xC8B9 0xD68D # 0 +0xC8BA 0xD690 # 0 +0xC8BB 0xD694 # 0 +0xC8BC 0xD69D # 0 +0xC8BD 0xD69F # 0 +0xC8BE 0xD6A1 # 0 +0xC8BF 0xD6A8 # 0 +0xC8C0 0xD6AC # 0 +0xC8C1 0xD6B0 # 0 +0xC8C2 0xD6B9 # 0 +0xC8C3 0xD6BB # 0 +0xC8C4 0xD6C4 # 0 +0xC8C5 0xD6C5 # 0 +0xC8C6 0xD6C8 # 0 +0xC8C7 0xD6CC # 0 +0xC8C8 0xD6D1 # 0 +0xC8C9 0xD6D4 # 0 +0xC8CA 0xD6D7 # 0 +0xC8CB 0xD6D9 # 0 +0xC8CC 0xD6E0 # 0 +0xC8CD 0xD6E4 # 0 +0xC8CE 0xD6E8 # 0 +0xC8CF 0xD6F0 # 0 +0xC8D0 0xD6F5 # 0 +0xC8D1 0xD6FC # 0 +0xC8D2 0xD6FD # 0 +0xC8D3 0xD700 # 0 +0xC8D4 0xD704 # 0 +0xC8D5 0xD711 # 0 +0xC8D6 0xD718 # 0 +0xC8D7 0xD719 # 0 +0xC8D8 0xD71C # 0 +0xC8D9 0xD720 # 0 +0xC8DA 0xD728 # 0 +0xC8DB 0xD729 # 0 +0xC8DC 0xD72B # 0 +0xC8DD 0xD72D # 0 +0xC8DE 0xD734 # 0 +0xC8DF 0xD735 # 0 +0xC8E0 0xD738 # 0 +0xC8E1 0xD73C # 0 +0xC8E2 0xD744 # 0 +0xC8E3 0xD747 # 0 +0xC8E4 0xD749 # 0 +0xC8E5 0xD750 # 0 +0xC8E6 0xD751 # 0 +0xC8E7 0xD754 # 0 +0xC8E8 0xD756 # 0 +0xC8E9 0xD757 # 0 +0xC8EA 0xD758 # 0 +0xC8EB 0xD759 # 0 +0xC8EC 0xD760 # 0 +0xC8ED 0xD761 # 0 +0xC8EE 0xD763 # 0 +0xC8EF 0xD765 # 0 +0xC8F0 0xD769 # 0 +0xC8F1 0xD76C # 0 +0xC8F2 0xD770 # 0 +0xC8F3 0xD774 # 0 +0xC8F4 0xD77C # 0 +0xC8F5 0xD77D # 0 +0xC8F6 0xD781 # 0 +0xC8F7 0xD788 # 0 +0xC8F8 0xD789 # 0 +0xC8F9 0xD78C # 0 +0xC8FA 0xD790 # 0 +0xC8FB 0xD798 # 0 +0xC8FC 0xD799 # 0 +0xC8FD 0xD79B # 0 +0xC8FE 0xD79D # 0 +0xC9A1 0xE000 # 0 +0xC9A2 0xE001 # 0 +0xC9A3 0xE002 # 0 +0xC9A4 0xE003 # 0 +0xC9A5 0xE004 # 0 +0xC9A6 0xE005 # 0 +0xC9A7 0xE006 # 0 +0xC9A8 0xE007 # 0 +0xC9A9 0xE008 # 0 +0xC9AA 0xE009 # 0 +0xC9AB 0xE00A # 0 +0xC9AC 0xE00B # 0 +0xC9AD 0xE00C # 0 +0xC9AE 0xE00D # 0 +0xC9AF 0xE00E # 0 +0xC9B0 0xE00F # 0 +0xC9B1 0xE010 # 0 +0xC9B2 0xE011 # 0 +0xC9B3 0xE012 # 0 +0xC9B4 0xE013 # 0 +0xC9B5 0xE014 # 0 +0xC9B6 0xE015 # 0 +0xC9B7 0xE016 # 0 +0xC9B8 0xE017 # 0 +0xC9B9 0xE018 # 0 +0xC9BA 0xE019 # 0 +0xC9BB 0xE01A # 0 +0xC9BC 0xE01B # 0 +0xC9BD 0xE01C # 0 +0xC9BE 0xE01D # 0 +0xC9BF 0xE01E # 0 +0xC9C0 0xE01F # 0 +0xC9C1 0xE020 # 0 +0xC9C2 0xE021 # 0 +0xC9C3 0xE022 # 0 +0xC9C4 0xE023 # 0 +0xC9C5 0xE024 # 0 +0xC9C6 0xE025 # 0 +0xC9C7 0xE026 # 0 +0xC9C8 0xE027 # 0 +0xC9C9 0xE028 # 0 +0xC9CA 0xE029 # 0 +0xC9CB 0xE02A # 0 +0xC9CC 0xE02B # 0 +0xC9CD 0xE02C # 0 +0xC9CE 0xE02D # 0 +0xC9CF 0xE02E # 0 +0xC9D0 0xE02F # 0 +0xC9D1 0xE030 # 0 +0xC9D2 0xE031 # 0 +0xC9D3 0xE032 # 0 +0xC9D4 0xE033 # 0 +0xC9D5 0xE034 # 0 +0xC9D6 0xE035 # 0 +0xC9D7 0xE036 # 0 +0xC9D8 0xE037 # 0 +0xC9D9 0xE038 # 0 +0xC9DA 0xE039 # 0 +0xC9DB 0xE03A # 0 +0xC9DC 0xE03B # 0 +0xC9DD 0xE03C # 0 +0xC9DE 0xE03D # 0 +0xC9DF 0xE03E # 0 +0xC9E0 0xE03F # 0 +0xC9E1 0xE040 # 0 +0xC9E2 0xE041 # 0 +0xC9E3 0xE042 # 0 +0xC9E4 0xE043 # 0 +0xC9E5 0xE044 # 0 +0xC9E6 0xE045 # 0 +0xC9E7 0xE046 # 0 +0xC9E8 0xE047 # 0 +0xC9E9 0xE048 # 0 +0xC9EA 0xE049 # 0 +0xC9EB 0xE04A # 0 +0xC9EC 0xE04B # 0 +0xC9ED 0xE04C # 0 +0xC9EE 0xE04D # 0 +0xC9EF 0xE04E # 0 +0xC9F0 0xE04F # 0 +0xC9F1 0xE050 # 0 +0xC9F2 0xE051 # 0 +0xC9F3 0xE052 # 0 +0xC9F4 0xE053 # 0 +0xC9F5 0xE054 # 0 +0xC9F6 0xE055 # 0 +0xC9F7 0xE056 # 0 +0xC9F8 0xE057 # 0 +0xC9F9 0xE058 # 0 +0xC9FA 0xE059 # 0 +0xC9FB 0xE05A # 0 +0xC9FC 0xE05B # 0 +0xC9FD 0xE05C # 0 +0xC9FE 0xE05D # 0 +0xCAA1 0x4F3D # 0 +0xCAA2 0x4F73 # 0 +0xCAA3 0x5047 # 0 +0xCAA4 0x50F9 # 0 +0xCAA5 0x52A0 # 0 +0xCAA6 0x53EF # 0 +0xCAA7 0x5475 # 0 +0xCAA8 0x54E5 # 0 +0xCAA9 0x5609 # 0 +0xCAAA 0x5AC1 # 0 +0xCAAB 0x5BB6 # 0 +0xCAAC 0x6687 # 0 +0xCAAD 0x67B6 # 0 +0xCAAE 0x67B7 # 0 +0xCAAF 0x67EF # 0 +0xCAB0 0x6B4C # 0 +0xCAB1 0x73C2 # 0 +0xCAB2 0x75C2 # 0 +0xCAB3 0x7A3C # 0 +0xCAB4 0x82DB # 0 +0xCAB5 0x8304 # 0 +0xCAB6 0x8857 # 0 +0xCAB7 0x8888 # 0 +0xCAB8 0x8A36 # 0 +0xCAB9 0x8CC8 # 0 +0xCABA 0x8DCF # 0 +0xCABB 0x8EFB # 0 +0xCABC 0x8FE6 # 0 +0xCABD 0x99D5 # 0 +0xCABE 0x523B # 0 +0xCABF 0x5374 # 0 +0xCAC0 0x5404 # 0 +0xCAC1 0x606A # 0 +0xCAC2 0x6164 # 0 +0xCAC3 0x6BBC # 0 +0xCAC4 0x73CF # 0 +0xCAC5 0x811A # 0 +0xCAC6 0x89BA # 0 +0xCAC7 0x89D2 # 0 +0xCAC8 0x95A3 # 0 +0xCAC9 0x4F83 # 0 +0xCACA 0x520A # 0 +0xCACB 0x58BE # 0 +0xCACC 0x5978 # 0 +0xCACD 0x59E6 # 0 +0xCACE 0x5E72 # 0 +0xCACF 0x5E79 # 0 +0xCAD0 0x61C7 # 0 +0xCAD1 0x63C0 # 0 +0xCAD2 0x6746 # 0 +0xCAD3 0x67EC # 0 +0xCAD4 0x687F # 0 +0xCAD5 0x6F97 # 0 +0xCAD6 0x764E # 0 +0xCAD7 0x770B # 0 +0xCAD8 0x78F5 # 0 +0xCAD9 0x7A08 # 0 +0xCADA 0x7AFF # 0 +0xCADB 0x7C21 # 0 +0xCADC 0x809D # 0 +0xCADD 0x826E # 0 +0xCADE 0x8271 # 0 +0xCADF 0x8AEB # 0 +0xCAE0 0x9593 # 0 +0xCAE1 0x4E6B # 0 +0xCAE2 0x559D # 0 +0xCAE3 0x66F7 # 0 +0xCAE4 0x6E34 # 0 +0xCAE5 0x78A3 # 0 +0xCAE6 0x7AED # 0 +0xCAE7 0x845B # 0 +0xCAE8 0x8910 # 0 +0xCAE9 0x874E # 0 +0xCAEA 0x97A8 # 0 +0xCAEB 0x52D8 # 0 +0xCAEC 0x574E # 0 +0xCAED 0x582A # 0 +0xCAEE 0x5D4C # 0 +0xCAEF 0x611F # 0 +0xCAF0 0x61BE # 0 +0xCAF1 0x6221 # 0 +0xCAF2 0x6562 # 0 +0xCAF3 0x67D1 # 0 +0xCAF4 0x6A44 # 0 +0xCAF5 0x6E1B # 0 +0xCAF6 0x7518 # 0 +0xCAF7 0x75B3 # 0 +0xCAF8 0x76E3 # 0 +0xCAF9 0x77B0 # 0 +0xCAFA 0x7D3A # 0 +0xCAFB 0x90AF # 0 +0xCAFC 0x9451 # 0 +0xCAFD 0x9452 # 0 +0xCAFE 0x9F95 # 0 +0xCBA1 0x5323 # 0 +0xCBA2 0x5CAC # 0 +0xCBA3 0x7532 # 0 +0xCBA4 0x80DB # 0 +0xCBA5 0x9240 # 0 +0xCBA6 0x9598 # 0 +0xCBA7 0x525B # 0 +0xCBA8 0x5808 # 0 +0xCBA9 0x59DC # 0 +0xCBAA 0x5CA1 # 0 +0xCBAB 0x5D17 # 0 +0xCBAC 0x5EB7 # 0 +0xCBAD 0x5F3A # 0 +0xCBAE 0x5F4A # 0 +0xCBAF 0x6177 # 0 +0xCBB0 0x6C5F # 0 +0xCBB1 0x757A # 0 +0xCBB2 0x7586 # 0 +0xCBB3 0x7CE0 # 0 +0xCBB4 0x7D73 # 0 +0xCBB5 0x7DB1 # 0 +0xCBB6 0x7F8C # 0 +0xCBB7 0x8154 # 0 +0xCBB8 0x8221 # 0 +0xCBB9 0x8591 # 0 +0xCBBA 0x8941 # 0 +0xCBBB 0x8B1B # 0 +0xCBBC 0x92FC # 0 +0xCBBD 0x964D # 0 +0xCBBE 0x9C47 # 0 +0xCBBF 0x4ECB # 0 +0xCBC0 0x4EF7 # 0 +0xCBC1 0x500B # 0 +0xCBC2 0x51F1 # 0 +0xCBC3 0x584F # 0 +0xCBC4 0x6137 # 0 +0xCBC5 0x613E # 0 +0xCBC6 0x6168 # 0 +0xCBC7 0x6539 # 0 +0xCBC8 0x69EA # 0 +0xCBC9 0x6F11 # 0 +0xCBCA 0x75A5 # 0 +0xCBCB 0x7686 # 0 +0xCBCC 0x76D6 # 0 +0xCBCD 0x7B87 # 0 +0xCBCE 0x82A5 # 0 +0xCBCF 0x84CB # 0 +0xCBD0 0xF900 # 0 +0xCBD1 0x93A7 # 0 +0xCBD2 0x958B # 0 +0xCBD3 0x5580 # 0 +0xCBD4 0x5BA2 # 0 +0xCBD5 0x5751 # 0 +0xCBD6 0xF901 # 0 +0xCBD7 0x7CB3 # 0 +0xCBD8 0x7FB9 # 0 +0xCBD9 0x91B5 # 0 +0xCBDA 0x5028 # 0 +0xCBDB 0x53BB # 0 +0xCBDC 0x5C45 # 0 +0xCBDD 0x5DE8 # 0 +0xCBDE 0x62D2 # 0 +0xCBDF 0x636E # 0 +0xCBE0 0x64DA # 0 +0xCBE1 0x64E7 # 0 +0xCBE2 0x6E20 # 0 +0xCBE3 0x70AC # 0 +0xCBE4 0x795B # 0 +0xCBE5 0x8DDD # 0 +0xCBE6 0x8E1E # 0 +0xCBE7 0xF902 # 0 +0xCBE8 0x907D # 0 +0xCBE9 0x9245 # 0 +0xCBEA 0x92F8 # 0 +0xCBEB 0x4E7E # 0 +0xCBEC 0x4EF6 # 0 +0xCBED 0x5065 # 0 +0xCBEE 0x5DFE # 0 +0xCBEF 0x5EFA # 0 +0xCBF0 0x6106 # 0 +0xCBF1 0x6957 # 0 +0xCBF2 0x8171 # 0 +0xCBF3 0x8654 # 0 +0xCBF4 0x8E47 # 0 +0xCBF5 0x9375 # 0 +0xCBF6 0x9A2B # 0 +0xCBF7 0x4E5E # 0 +0xCBF8 0x5091 # 0 +0xCBF9 0x6770 # 0 +0xCBFA 0x6840 # 0 +0xCBFB 0x5109 # 0 +0xCBFC 0x528D # 0 +0xCBFD 0x5292 # 0 +0xCBFE 0x6AA2 # 0 +0xCCA1 0x77BC # 0 +0xCCA2 0x9210 # 0 +0xCCA3 0x9ED4 # 0 +0xCCA4 0x52AB # 0 +0xCCA5 0x602F # 0 +0xCCA6 0x8FF2 # 0 +0xCCA7 0x5048 # 0 +0xCCA8 0x61A9 # 0 +0xCCA9 0x63ED # 0 +0xCCAA 0x64CA # 0 +0xCCAB 0x683C # 0 +0xCCAC 0x6A84 # 0 +0xCCAD 0x6FC0 # 0 +0xCCAE 0x8188 # 0 +0xCCAF 0x89A1 # 0 +0xCCB0 0x9694 # 0 +0xCCB1 0x5805 # 0 +0xCCB2 0x727D # 0 +0xCCB3 0x72AC # 0 +0xCCB4 0x7504 # 0 +0xCCB5 0x7D79 # 0 +0xCCB6 0x7E6D # 0 +0xCCB7 0x80A9 # 0 +0xCCB8 0x898B # 0 +0xCCB9 0x8B74 # 0 +0xCCBA 0x9063 # 0 +0xCCBB 0x9D51 # 0 +0xCCBC 0x6289 # 0 +0xCCBD 0x6C7A # 0 +0xCCBE 0x6F54 # 0 +0xCCBF 0x7D50 # 0 +0xCCC0 0x7F3A # 0 +0xCCC1 0x8A23 # 0 +0xCCC2 0x517C # 0 +0xCCC3 0x614A # 0 +0xCCC4 0x7B9D # 0 +0xCCC5 0x8B19 # 0 +0xCCC6 0x9257 # 0 +0xCCC7 0x938C # 0 +0xCCC8 0x4EAC # 0 +0xCCC9 0x4FD3 # 0 +0xCCCA 0x501E # 0 +0xCCCB 0x50BE # 0 +0xCCCC 0x5106 # 0 +0xCCCD 0x52C1 # 0 +0xCCCE 0x52CD # 0 +0xCCCF 0x537F # 0 +0xCCD0 0x5770 # 0 +0xCCD1 0x5883 # 0 +0xCCD2 0x5E9A # 0 +0xCCD3 0x5F91 # 0 +0xCCD4 0x6176 # 0 +0xCCD5 0x61AC # 0 +0xCCD6 0x64CE # 0 +0xCCD7 0x656C # 0 +0xCCD8 0x666F # 0 +0xCCD9 0x66BB # 0 +0xCCDA 0x66F4 # 0 +0xCCDB 0x6897 # 0 +0xCCDC 0x6D87 # 0 +0xCCDD 0x7085 # 0 +0xCCDE 0x70F1 # 0 +0xCCDF 0x749F # 0 +0xCCE0 0x74A5 # 0 +0xCCE1 0x74CA # 0 +0xCCE2 0x75D9 # 0 +0xCCE3 0x786C # 0 +0xCCE4 0x78EC # 0 +0xCCE5 0x7ADF # 0 +0xCCE6 0x7AF6 # 0 +0xCCE7 0x7D45 # 0 +0xCCE8 0x7D93 # 0 +0xCCE9 0x8015 # 0 +0xCCEA 0x803F # 0 +0xCCEB 0x811B # 0 +0xCCEC 0x8396 # 0 +0xCCED 0x8B66 # 0 +0xCCEE 0x8F15 # 0 +0xCCEF 0x9015 # 0 +0xCCF0 0x93E1 # 0 +0xCCF1 0x9803 # 0 +0xCCF2 0x9838 # 0 +0xCCF3 0x9A5A # 0 +0xCCF4 0x9BE8 # 0 +0xCCF5 0x4FC2 # 0 +0xCCF6 0x5553 # 0 +0xCCF7 0x583A # 0 +0xCCF8 0x5951 # 0 +0xCCF9 0x5B63 # 0 +0xCCFA 0x5C46 # 0 +0xCCFB 0x60B8 # 0 +0xCCFC 0x6212 # 0 +0xCCFD 0x6842 # 0 +0xCCFE 0x68B0 # 0 +0xCDA1 0x68E8 # 0 +0xCDA2 0x6EAA # 0 +0xCDA3 0x754C # 0 +0xCDA4 0x7678 # 0 +0xCDA5 0x78CE # 0 +0xCDA6 0x7A3D # 0 +0xCDA7 0x7CFB # 0 +0xCDA8 0x7E6B # 0 +0xCDA9 0x7E7C # 0 +0xCDAA 0x8A08 # 0 +0xCDAB 0x8AA1 # 0 +0xCDAC 0x8C3F # 0 +0xCDAD 0x968E # 0 +0xCDAE 0x9DC4 # 0 +0xCDAF 0x53E4 # 0 +0xCDB0 0x53E9 # 0 +0xCDB1 0x544A # 0 +0xCDB2 0x5471 # 0 +0xCDB3 0x56FA # 0 +0xCDB4 0x59D1 # 0 +0xCDB5 0x5B64 # 0 +0xCDB6 0x5C3B # 0 +0xCDB7 0x5EAB # 0 +0xCDB8 0x62F7 # 0 +0xCDB9 0x6537 # 0 +0xCDBA 0x6545 # 0 +0xCDBB 0x6572 # 0 +0xCDBC 0x66A0 # 0 +0xCDBD 0x67AF # 0 +0xCDBE 0x69C1 # 0 +0xCDBF 0x6CBD # 0 +0xCDC0 0x75FC # 0 +0xCDC1 0x7690 # 0 +0xCDC2 0x777E # 0 +0xCDC3 0x7A3F # 0 +0xCDC4 0x7F94 # 0 +0xCDC5 0x8003 # 0 +0xCDC6 0x80A1 # 0 +0xCDC7 0x818F # 0 +0xCDC8 0x82E6 # 0 +0xCDC9 0x82FD # 0 +0xCDCA 0x83F0 # 0 +0xCDCB 0x85C1 # 0 +0xCDCC 0x8831 # 0 +0xCDCD 0x88B4 # 0 +0xCDCE 0x8AA5 # 0 +0xCDCF 0xF903 # 0 +0xCDD0 0x8F9C # 0 +0xCDD1 0x932E # 0 +0xCDD2 0x96C7 # 0 +0xCDD3 0x9867 # 0 +0xCDD4 0x9AD8 # 0 +0xCDD5 0x9F13 # 0 +0xCDD6 0x54ED # 0 +0xCDD7 0x659B # 0 +0xCDD8 0x66F2 # 0 +0xCDD9 0x688F # 0 +0xCDDA 0x7A40 # 0 +0xCDDB 0x8C37 # 0 +0xCDDC 0x9D60 # 0 +0xCDDD 0x56F0 # 0 +0xCDDE 0x5764 # 0 +0xCDDF 0x5D11 # 0 +0xCDE0 0x6606 # 0 +0xCDE1 0x68B1 # 0 +0xCDE2 0x68CD # 0 +0xCDE3 0x6EFE # 0 +0xCDE4 0x7428 # 0 +0xCDE5 0x889E # 0 +0xCDE6 0x9BE4 # 0 +0xCDE7 0x6C68 # 0 +0xCDE8 0xF904 # 0 +0xCDE9 0x9AA8 # 0 +0xCDEA 0x4F9B # 0 +0xCDEB 0x516C # 0 +0xCDEC 0x5171 # 0 +0xCDED 0x529F # 0 +0xCDEE 0x5B54 # 0 +0xCDEF 0x5DE5 # 0 +0xCDF0 0x6050 # 0 +0xCDF1 0x606D # 0 +0xCDF2 0x62F1 # 0 +0xCDF3 0x63A7 # 0 +0xCDF4 0x653B # 0 +0xCDF5 0x73D9 # 0 +0xCDF6 0x7A7A # 0 +0xCDF7 0x86A3 # 0 +0xCDF8 0x8CA2 # 0 +0xCDF9 0x978F # 0 +0xCDFA 0x4E32 # 0 +0xCDFB 0x5BE1 # 0 +0xCDFC 0x6208 # 0 +0xCDFD 0x679C # 0 +0xCDFE 0x74DC # 0 +0xCEA1 0x79D1 # 0 +0xCEA2 0x83D3 # 0 +0xCEA3 0x8A87 # 0 +0xCEA4 0x8AB2 # 0 +0xCEA5 0x8DE8 # 0 +0xCEA6 0x904E # 0 +0xCEA7 0x934B # 0 +0xCEA8 0x9846 # 0 +0xCEA9 0x5ED3 # 0 +0xCEAA 0x69E8 # 0 +0xCEAB 0x85FF # 0 +0xCEAC 0x90ED # 0 +0xCEAD 0xF905 # 0 +0xCEAE 0x51A0 # 0 +0xCEAF 0x5B98 # 0 +0xCEB0 0x5BEC # 0 +0xCEB1 0x6163 # 0 +0xCEB2 0x68FA # 0 +0xCEB3 0x6B3E # 0 +0xCEB4 0x704C # 0 +0xCEB5 0x742F # 0 +0xCEB6 0x74D8 # 0 +0xCEB7 0x7BA1 # 0 +0xCEB8 0x7F50 # 0 +0xCEB9 0x83C5 # 0 +0xCEBA 0x89C0 # 0 +0xCEBB 0x8CAB # 0 +0xCEBC 0x95DC # 0 +0xCEBD 0x9928 # 0 +0xCEBE 0x522E # 0 +0xCEBF 0x605D # 0 +0xCEC0 0x62EC # 0 +0xCEC1 0x9002 # 0 +0xCEC2 0x4F8A # 0 +0xCEC3 0x5149 # 0 +0xCEC4 0x5321 # 0 +0xCEC5 0x58D9 # 0 +0xCEC6 0x5EE3 # 0 +0xCEC7 0x66E0 # 0 +0xCEC8 0x6D38 # 0 +0xCEC9 0x709A # 0 +0xCECA 0x72C2 # 0 +0xCECB 0x73D6 # 0 +0xCECC 0x7B50 # 0 +0xCECD 0x80F1 # 0 +0xCECE 0x945B # 0 +0xCECF 0x5366 # 0 +0xCED0 0x639B # 0 +0xCED1 0x7F6B # 0 +0xCED2 0x4E56 # 0 +0xCED3 0x5080 # 0 +0xCED4 0x584A # 0 +0xCED5 0x58DE # 0 +0xCED6 0x602A # 0 +0xCED7 0x6127 # 0 +0xCED8 0x62D0 # 0 +0xCED9 0x69D0 # 0 +0xCEDA 0x9B41 # 0 +0xCEDB 0x5B8F # 0 +0xCEDC 0x7D18 # 0 +0xCEDD 0x80B1 # 0 +0xCEDE 0x8F5F # 0 +0xCEDF 0x4EA4 # 0 +0xCEE0 0x50D1 # 0 +0xCEE1 0x54AC # 0 +0xCEE2 0x55AC # 0 +0xCEE3 0x5B0C # 0 +0xCEE4 0x5DA0 # 0 +0xCEE5 0x5DE7 # 0 +0xCEE6 0x652A # 0 +0xCEE7 0x654E # 0 +0xCEE8 0x6821 # 0 +0xCEE9 0x6A4B # 0 +0xCEEA 0x72E1 # 0 +0xCEEB 0x768E # 0 +0xCEEC 0x77EF # 0 +0xCEED 0x7D5E # 0 +0xCEEE 0x7FF9 # 0 +0xCEEF 0x81A0 # 0 +0xCEF0 0x854E # 0 +0xCEF1 0x86DF # 0 +0xCEF2 0x8F03 # 0 +0xCEF3 0x8F4E # 0 +0xCEF4 0x90CA # 0 +0xCEF5 0x9903 # 0 +0xCEF6 0x9A55 # 0 +0xCEF7 0x9BAB # 0 +0xCEF8 0x4E18 # 0 +0xCEF9 0x4E45 # 0 +0xCEFA 0x4E5D # 0 +0xCEFB 0x4EC7 # 0 +0xCEFC 0x4FF1 # 0 +0xCEFD 0x5177 # 0 +0xCEFE 0x52FE # 0 +0xCFA1 0x5340 # 0 +0xCFA2 0x53E3 # 0 +0xCFA3 0x53E5 # 0 +0xCFA4 0x548E # 0 +0xCFA5 0x5614 # 0 +0xCFA6 0x5775 # 0 +0xCFA7 0x57A2 # 0 +0xCFA8 0x5BC7 # 0 +0xCFA9 0x5D87 # 0 +0xCFAA 0x5ED0 # 0 +0xCFAB 0x61FC # 0 +0xCFAC 0x62D8 # 0 +0xCFAD 0x6551 # 0 +0xCFAE 0x67B8 # 0 +0xCFAF 0x67E9 # 0 +0xCFB0 0x69CB # 0 +0xCFB1 0x6B50 # 0 +0xCFB2 0x6BC6 # 0 +0xCFB3 0x6BEC # 0 +0xCFB4 0x6C42 # 0 +0xCFB5 0x6E9D # 0 +0xCFB6 0x7078 # 0 +0xCFB7 0x72D7 # 0 +0xCFB8 0x7396 # 0 +0xCFB9 0x7403 # 0 +0xCFBA 0x77BF # 0 +0xCFBB 0x77E9 # 0 +0xCFBC 0x7A76 # 0 +0xCFBD 0x7D7F # 0 +0xCFBE 0x8009 # 0 +0xCFBF 0x81FC # 0 +0xCFC0 0x8205 # 0 +0xCFC1 0x820A # 0 +0xCFC2 0x82DF # 0 +0xCFC3 0x8862 # 0 +0xCFC4 0x8B33 # 0 +0xCFC5 0x8CFC # 0 +0xCFC6 0x8EC0 # 0 +0xCFC7 0x9011 # 0 +0xCFC8 0x90B1 # 0 +0xCFC9 0x9264 # 0 +0xCFCA 0x92B6 # 0 +0xCFCB 0x99D2 # 0 +0xCFCC 0x9A45 # 0 +0xCFCD 0x9CE9 # 0 +0xCFCE 0x9DD7 # 0 +0xCFCF 0x9F9C # 0 +0xCFD0 0x570B # 0 +0xCFD1 0x5C40 # 0 +0xCFD2 0x83CA # 0 +0xCFD3 0x97A0 # 0 +0xCFD4 0x97AB # 0 +0xCFD5 0x9EB4 # 0 +0xCFD6 0x541B # 0 +0xCFD7 0x7A98 # 0 +0xCFD8 0x7FA4 # 0 +0xCFD9 0x88D9 # 0 +0xCFDA 0x8ECD # 0 +0xCFDB 0x90E1 # 0 +0xCFDC 0x5800 # 0 +0xCFDD 0x5C48 # 0 +0xCFDE 0x6398 # 0 +0xCFDF 0x7A9F # 0 +0xCFE0 0x5BAE # 0 +0xCFE1 0x5F13 # 0 +0xCFE2 0x7A79 # 0 +0xCFE3 0x7AAE # 0 +0xCFE4 0x828E # 0 +0xCFE5 0x8EAC # 0 +0xCFE6 0x5026 # 0 +0xCFE7 0x5238 # 0 +0xCFE8 0x52F8 # 0 +0xCFE9 0x5377 # 0 +0xCFEA 0x5708 # 0 +0xCFEB 0x62F3 # 0 +0xCFEC 0x6372 # 0 +0xCFED 0x6B0A # 0 +0xCFEE 0x6DC3 # 0 +0xCFEF 0x7737 # 0 +0xCFF0 0x53A5 # 0 +0xCFF1 0x7357 # 0 +0xCFF2 0x8568 # 0 +0xCFF3 0x8E76 # 0 +0xCFF4 0x95D5 # 0 +0xCFF5 0x673A # 0 +0xCFF6 0x6AC3 # 0 +0xCFF7 0x6F70 # 0 +0xCFF8 0x8A6D # 0 +0xCFF9 0x8ECC # 0 +0xCFFA 0x994B # 0 +0xCFFB 0xF906 # 0 +0xCFFC 0x6677 # 0 +0xCFFD 0x6B78 # 0 +0xCFFE 0x8CB4 # 0 +0xD0A1 0x9B3C # 0 +0xD0A2 0xF907 # 0 +0xD0A3 0x53EB # 0 +0xD0A4 0x572D # 0 +0xD0A5 0x594E # 0 +0xD0A6 0x63C6 # 0 +0xD0A7 0x69FB # 0 +0xD0A8 0x73EA # 0 +0xD0A9 0x7845 # 0 +0xD0AA 0x7ABA # 0 +0xD0AB 0x7AC5 # 0 +0xD0AC 0x7CFE # 0 +0xD0AD 0x8475 # 0 +0xD0AE 0x898F # 0 +0xD0AF 0x8D73 # 0 +0xD0B0 0x9035 # 0 +0xD0B1 0x95A8 # 0 +0xD0B2 0x52FB # 0 +0xD0B3 0x5747 # 0 +0xD0B4 0x7547 # 0 +0xD0B5 0x7B60 # 0 +0xD0B6 0x83CC # 0 +0xD0B7 0x921E # 0 +0xD0B8 0xF908 # 0 +0xD0B9 0x6A58 # 0 +0xD0BA 0x514B # 0 +0xD0BB 0x524B # 0 +0xD0BC 0x5287 # 0 +0xD0BD 0x621F # 0 +0xD0BE 0x68D8 # 0 +0xD0BF 0x6975 # 0 +0xD0C0 0x9699 # 0 +0xD0C1 0x50C5 # 0 +0xD0C2 0x52A4 # 0 +0xD0C3 0x52E4 # 0 +0xD0C4 0x61C3 # 0 +0xD0C5 0x65A4 # 0 +0xD0C6 0x6839 # 0 +0xD0C7 0x69FF # 0 +0xD0C8 0x747E # 0 +0xD0C9 0x7B4B # 0 +0xD0CA 0x82B9 # 0 +0xD0CB 0x83EB # 0 +0xD0CC 0x89B2 # 0 +0xD0CD 0x8B39 # 0 +0xD0CE 0x8FD1 # 0 +0xD0CF 0x9949 # 0 +0xD0D0 0xF909 # 0 +0xD0D1 0x4ECA # 0 +0xD0D2 0x5997 # 0 +0xD0D3 0x64D2 # 0 +0xD0D4 0x6611 # 0 +0xD0D5 0x6A8E # 0 +0xD0D6 0x7434 # 0 +0xD0D7 0x7981 # 0 +0xD0D8 0x79BD # 0 +0xD0D9 0x82A9 # 0 +0xD0DA 0x887E # 0 +0xD0DB 0x887F # 0 +0xD0DC 0x895F # 0 +0xD0DD 0xF90A # 0 +0xD0DE 0x9326 # 0 +0xD0DF 0x4F0B # 0 +0xD0E0 0x53CA # 0 +0xD0E1 0x6025 # 0 +0xD0E2 0x6271 # 0 +0xD0E3 0x6C72 # 0 +0xD0E4 0x7D1A # 0 +0xD0E5 0x7D66 # 0 +0xD0E6 0x4E98 # 0 +0xD0E7 0x5162 # 0 +0xD0E8 0x77DC # 0 +0xD0E9 0x80AF # 0 +0xD0EA 0x4F01 # 0 +0xD0EB 0x4F0E # 0 +0xD0EC 0x5176 # 0 +0xD0ED 0x5180 # 0 +0xD0EE 0x55DC # 0 +0xD0EF 0x5668 # 0 +0xD0F0 0x573B # 0 +0xD0F1 0x57FA # 0 +0xD0F2 0x57FC # 0 +0xD0F3 0x5914 # 0 +0xD0F4 0x5947 # 0 +0xD0F5 0x5993 # 0 +0xD0F6 0x5BC4 # 0 +0xD0F7 0x5C90 # 0 +0xD0F8 0x5D0E # 0 +0xD0F9 0x5DF1 # 0 +0xD0FA 0x5E7E # 0 +0xD0FB 0x5FCC # 0 +0xD0FC 0x6280 # 0 +0xD0FD 0x65D7 # 0 +0xD0FE 0x65E3 # 0 +0xD1A1 0x671E # 0 +0xD1A2 0x671F # 0 +0xD1A3 0x675E # 0 +0xD1A4 0x68CB # 0 +0xD1A5 0x68C4 # 0 +0xD1A6 0x6A5F # 0 +0xD1A7 0x6B3A # 0 +0xD1A8 0x6C23 # 0 +0xD1A9 0x6C7D # 0 +0xD1AA 0x6C82 # 0 +0xD1AB 0x6DC7 # 0 +0xD1AC 0x7398 # 0 +0xD1AD 0x7426 # 0 +0xD1AE 0x742A # 0 +0xD1AF 0x7482 # 0 +0xD1B0 0x74A3 # 0 +0xD1B1 0x7578 # 0 +0xD1B2 0x757F # 0 +0xD1B3 0x7881 # 0 +0xD1B4 0x78EF # 0 +0xD1B5 0x7941 # 0 +0xD1B6 0x7947 # 0 +0xD1B7 0x7948 # 0 +0xD1B8 0x797A # 0 +0xD1B9 0x7B95 # 0 +0xD1BA 0x7D00 # 0 +0xD1BB 0x7DBA # 0 +0xD1BC 0x7F88 # 0 +0xD1BD 0x8006 # 0 +0xD1BE 0x802D # 0 +0xD1BF 0x808C # 0 +0xD1C0 0x8A18 # 0 +0xD1C1 0x8B4F # 0 +0xD1C2 0x8C48 # 0 +0xD1C3 0x8D77 # 0 +0xD1C4 0x9321 # 0 +0xD1C5 0x9324 # 0 +0xD1C6 0x98E2 # 0 +0xD1C7 0x9951 # 0 +0xD1C8 0x9A0E # 0 +0xD1C9 0x9A0F # 0 +0xD1CA 0x9A65 # 0 +0xD1CB 0x9E92 # 0 +0xD1CC 0x7DCA # 0 +0xD1CD 0x4F76 # 0 +0xD1CE 0x5409 # 0 +0xD1CF 0x62EE # 0 +0xD1D0 0x6854 # 0 +0xD1D1 0x91D1 # 0 +0xD1D2 0x55AB # 0 +0xD1D3 0x513A # 0 +0xD1D4 0xF90B # 0 +0xD1D5 0xF90C # 0 +0xD1D6 0x5A1C # 0 +0xD1D7 0x61E6 # 0 +0xD1D8 0xF90D # 0 +0xD1D9 0x62CF # 0 +0xD1DA 0x62FF # 0 +0xD1DB 0xF90E # 0 +0xD1DC 0xF90F # 0 +0xD1DD 0xF910 # 0 +0xD1DE 0xF911 # 0 +0xD1DF 0xF912 # 0 +0xD1E0 0xF913 # 0 +0xD1E1 0x90A3 # 0 +0xD1E2 0xF914 # 0 +0xD1E3 0xF915 # 0 +0xD1E4 0xF916 # 0 +0xD1E5 0xF917 # 0 +0xD1E6 0xF918 # 0 +0xD1E7 0x8AFE # 0 +0xD1E8 0xF919 # 0 +0xD1E9 0xF91A # 0 +0xD1EA 0xF91B # 0 +0xD1EB 0xF91C # 0 +0xD1EC 0x6696 # 0 +0xD1ED 0xF91D # 0 +0xD1EE 0x7156 # 0 +0xD1EF 0xF91E # 0 +0xD1F0 0xF91F # 0 +0xD1F1 0x96E3 # 0 +0xD1F2 0xF920 # 0 +0xD1F3 0x634F # 0 +0xD1F4 0x637A # 0 +0xD1F5 0x5357 # 0 +0xD1F6 0xF921 # 0 +0xD1F7 0x678F # 0 +0xD1F8 0x6960 # 0 +0xD1F9 0x6E73 # 0 +0xD1FA 0xF922 # 0 +0xD1FB 0x7537 # 0 +0xD1FC 0xF923 # 0 +0xD1FD 0xF924 # 0 +0xD1FE 0xF925 # 0 +0xD2A1 0x7D0D # 0 +0xD2A2 0xF926 # 0 +0xD2A3 0xF927 # 0 +0xD2A4 0x8872 # 0 +0xD2A5 0x56CA # 0 +0xD2A6 0x5A18 # 0 +0xD2A7 0xF928 # 0 +0xD2A8 0xF929 # 0 +0xD2A9 0xF92A # 0 +0xD2AA 0xF92B # 0 +0xD2AB 0xF92C # 0 +0xD2AC 0x4E43 # 0 +0xD2AD 0xF92D # 0 +0xD2AE 0x5167 # 0 +0xD2AF 0x5948 # 0 +0xD2B0 0x67F0 # 0 +0xD2B1 0x8010 # 0 +0xD2B2 0xF92E # 0 +0xD2B3 0x5973 # 0 +0xD2B4 0x5E74 # 0 +0xD2B5 0x649A # 0 +0xD2B6 0x79CA # 0 +0xD2B7 0x5FF5 # 0 +0xD2B8 0x606C # 0 +0xD2B9 0x62C8 # 0 +0xD2BA 0x637B # 0 +0xD2BB 0x5BE7 # 0 +0xD2BC 0x5BD7 # 0 +0xD2BD 0x52AA # 0 +0xD2BE 0xF92F # 0 +0xD2BF 0x5974 # 0 +0xD2C0 0x5F29 # 0 +0xD2C1 0x6012 # 0 +0xD2C2 0xF930 # 0 +0xD2C3 0xF931 # 0 +0xD2C4 0xF932 # 0 +0xD2C5 0x7459 # 0 +0xD2C6 0xF933 # 0 +0xD2C7 0xF934 # 0 +0xD2C8 0xF935 # 0 +0xD2C9 0xF936 # 0 +0xD2CA 0xF937 # 0 +0xD2CB 0xF938 # 0 +0xD2CC 0x99D1 # 0 +0xD2CD 0xF939 # 0 +0xD2CE 0xF93A # 0 +0xD2CF 0xF93B # 0 +0xD2D0 0xF93C # 0 +0xD2D1 0xF93D # 0 +0xD2D2 0xF93E # 0 +0xD2D3 0xF93F # 0 +0xD2D4 0xF940 # 0 +0xD2D5 0xF941 # 0 +0xD2D6 0xF942 # 0 +0xD2D7 0xF943 # 0 +0xD2D8 0x6FC3 # 0 +0xD2D9 0xF944 # 0 +0xD2DA 0xF945 # 0 +0xD2DB 0x81BF # 0 +0xD2DC 0x8FB2 # 0 +0xD2DD 0x60F1 # 0 +0xD2DE 0xF946 # 0 +0xD2DF 0xF947 # 0 +0xD2E0 0x8166 # 0 +0xD2E1 0xF948 # 0 +0xD2E2 0xF949 # 0 +0xD2E3 0x5C3F # 0 +0xD2E4 0xF94A # 0 +0xD2E5 0xF94B # 0 +0xD2E6 0xF94C # 0 +0xD2E7 0xF94D # 0 +0xD2E8 0xF94E # 0 +0xD2E9 0xF94F # 0 +0xD2EA 0xF950 # 0 +0xD2EB 0xF951 # 0 +0xD2EC 0x5AE9 # 0 +0xD2ED 0x8A25 # 0 +0xD2EE 0x677B # 0 +0xD2EF 0x7D10 # 0 +0xD2F0 0xF952 # 0 +0xD2F1 0xF953 # 0 +0xD2F2 0xF954 # 0 +0xD2F3 0xF955 # 0 +0xD2F4 0xF956 # 0 +0xD2F5 0xF957 # 0 +0xD2F6 0x80FD # 0 +0xD2F7 0xF958 # 0 +0xD2F8 0xF959 # 0 +0xD2F9 0x5C3C # 0 +0xD2FA 0x6CE5 # 0 +0xD2FB 0x533F # 0 +0xD2FC 0x6EBA # 0 +0xD2FD 0x591A # 0 +0xD2FE 0x8336 # 0 +0xD3A1 0x4E39 # 0 +0xD3A2 0x4EB6 # 0 +0xD3A3 0x4F46 # 0 +0xD3A4 0x55AE # 0 +0xD3A5 0x5718 # 0 +0xD3A6 0x58C7 # 0 +0xD3A7 0x5F56 # 0 +0xD3A8 0x65B7 # 0 +0xD3A9 0x65E6 # 0 +0xD3AA 0x6A80 # 0 +0xD3AB 0x6BB5 # 0 +0xD3AC 0x6E4D # 0 +0xD3AD 0x77ED # 0 +0xD3AE 0x7AEF # 0 +0xD3AF 0x7C1E # 0 +0xD3B0 0x7DDE # 0 +0xD3B1 0x86CB # 0 +0xD3B2 0x8892 # 0 +0xD3B3 0x9132 # 0 +0xD3B4 0x935B # 0 +0xD3B5 0x64BB # 0 +0xD3B6 0x6FBE # 0 +0xD3B7 0x737A # 0 +0xD3B8 0x75B8 # 0 +0xD3B9 0x9054 # 0 +0xD3BA 0x5556 # 0 +0xD3BB 0x574D # 0 +0xD3BC 0x61BA # 0 +0xD3BD 0x64D4 # 0 +0xD3BE 0x66C7 # 0 +0xD3BF 0x6DE1 # 0 +0xD3C0 0x6E5B # 0 +0xD3C1 0x6F6D # 0 +0xD3C2 0x6FB9 # 0 +0xD3C3 0x75F0 # 0 +0xD3C4 0x8043 # 0 +0xD3C5 0x81BD # 0 +0xD3C6 0x8541 # 0 +0xD3C7 0x8983 # 0 +0xD3C8 0x8AC7 # 0 +0xD3C9 0x8B5A # 0 +0xD3CA 0x931F # 0 +0xD3CB 0x6C93 # 0 +0xD3CC 0x7553 # 0 +0xD3CD 0x7B54 # 0 +0xD3CE 0x8E0F # 0 +0xD3CF 0x905D # 0 +0xD3D0 0x5510 # 0 +0xD3D1 0x5802 # 0 +0xD3D2 0x5858 # 0 +0xD3D3 0x5E62 # 0 +0xD3D4 0x6207 # 0 +0xD3D5 0x649E # 0 +0xD3D6 0x68E0 # 0 +0xD3D7 0x7576 # 0 +0xD3D8 0x7CD6 # 0 +0xD3D9 0x87B3 # 0 +0xD3DA 0x9EE8 # 0 +0xD3DB 0x4EE3 # 0 +0xD3DC 0x5788 # 0 +0xD3DD 0x576E # 0 +0xD3DE 0x5927 # 0 +0xD3DF 0x5C0D # 0 +0xD3E0 0x5CB1 # 0 +0xD3E1 0x5E36 # 0 +0xD3E2 0x5F85 # 0 +0xD3E3 0x6234 # 0 +0xD3E4 0x64E1 # 0 +0xD3E5 0x73B3 # 0 +0xD3E6 0x81FA # 0 +0xD3E7 0x888B # 0 +0xD3E8 0x8CB8 # 0 +0xD3E9 0x968A # 0 +0xD3EA 0x9EDB # 0 +0xD3EB 0x5B85 # 0 +0xD3EC 0x5FB7 # 0 +0xD3ED 0x60B3 # 0 +0xD3EE 0x5012 # 0 +0xD3EF 0x5200 # 0 +0xD3F0 0x5230 # 0 +0xD3F1 0x5716 # 0 +0xD3F2 0x5835 # 0 +0xD3F3 0x5857 # 0 +0xD3F4 0x5C0E # 0 +0xD3F5 0x5C60 # 0 +0xD3F6 0x5CF6 # 0 +0xD3F7 0x5D8B # 0 +0xD3F8 0x5EA6 # 0 +0xD3F9 0x5F92 # 0 +0xD3FA 0x60BC # 0 +0xD3FB 0x6311 # 0 +0xD3FC 0x6389 # 0 +0xD3FD 0x6417 # 0 +0xD3FE 0x6843 # 0 +0xD4A1 0x68F9 # 0 +0xD4A2 0x6AC2 # 0 +0xD4A3 0x6DD8 # 0 +0xD4A4 0x6E21 # 0 +0xD4A5 0x6ED4 # 0 +0xD4A6 0x6FE4 # 0 +0xD4A7 0x71FE # 0 +0xD4A8 0x76DC # 0 +0xD4A9 0x7779 # 0 +0xD4AA 0x79B1 # 0 +0xD4AB 0x7A3B # 0 +0xD4AC 0x8404 # 0 +0xD4AD 0x89A9 # 0 +0xD4AE 0x8CED # 0 +0xD4AF 0x8DF3 # 0 +0xD4B0 0x8E48 # 0 +0xD4B1 0x9003 # 0 +0xD4B2 0x9014 # 0 +0xD4B3 0x9053 # 0 +0xD4B4 0x90FD # 0 +0xD4B5 0x934D # 0 +0xD4B6 0x9676 # 0 +0xD4B7 0x97DC # 0 +0xD4B8 0x6BD2 # 0 +0xD4B9 0x7006 # 0 +0xD4BA 0x7258 # 0 +0xD4BB 0x72A2 # 0 +0xD4BC 0x7368 # 0 +0xD4BD 0x7763 # 0 +0xD4BE 0x79BF # 0 +0xD4BF 0x7BE4 # 0 +0xD4C0 0x7E9B # 0 +0xD4C1 0x8B80 # 0 +0xD4C2 0x58A9 # 0 +0xD4C3 0x60C7 # 0 +0xD4C4 0x6566 # 0 +0xD4C5 0x65FD # 0 +0xD4C6 0x66BE # 0 +0xD4C7 0x6C8C # 0 +0xD4C8 0x711E # 0 +0xD4C9 0x71C9 # 0 +0xD4CA 0x8C5A # 0 +0xD4CB 0x9813 # 0 +0xD4CC 0x4E6D # 0 +0xD4CD 0x7A81 # 0 +0xD4CE 0x4EDD # 0 +0xD4CF 0x51AC # 0 +0xD4D0 0x51CD # 0 +0xD4D1 0x52D5 # 0 +0xD4D2 0x540C # 0 +0xD4D3 0x61A7 # 0 +0xD4D4 0x6771 # 0 +0xD4D5 0x6850 # 0 +0xD4D6 0x68DF # 0 +0xD4D7 0x6D1E # 0 +0xD4D8 0x6F7C # 0 +0xD4D9 0x75BC # 0 +0xD4DA 0x77B3 # 0 +0xD4DB 0x7AE5 # 0 +0xD4DC 0x80F4 # 0 +0xD4DD 0x8463 # 0 +0xD4DE 0x9285 # 0 +0xD4DF 0x515C # 0 +0xD4E0 0x6597 # 0 +0xD4E1 0x675C # 0 +0xD4E2 0x6793 # 0 +0xD4E3 0x75D8 # 0 +0xD4E4 0x7AC7 # 0 +0xD4E5 0x8373 # 0 +0xD4E6 0xF95A # 0 +0xD4E7 0x8C46 # 0 +0xD4E8 0x9017 # 0 +0xD4E9 0x982D # 0 +0xD4EA 0x5C6F # 0 +0xD4EB 0x81C0 # 0 +0xD4EC 0x829A # 0 +0xD4ED 0x9041 # 0 +0xD4EE 0x906F # 0 +0xD4EF 0x920D # 0 +0xD4F0 0x5F97 # 0 +0xD4F1 0x5D9D # 0 +0xD4F2 0x6A59 # 0 +0xD4F3 0x71C8 # 0 +0xD4F4 0x767B # 0 +0xD4F5 0x7B49 # 0 +0xD4F6 0x85E4 # 0 +0xD4F7 0x8B04 # 0 +0xD4F8 0x9127 # 0 +0xD4F9 0x9A30 # 0 +0xD4FA 0x5587 # 0 +0xD4FB 0x61F6 # 0 +0xD4FC 0xF95B # 0 +0xD4FD 0x7669 # 0 +0xD4FE 0x7F85 # 0 +0xD5A1 0x863F # 0 +0xD5A2 0x87BA # 0 +0xD5A3 0x88F8 # 0 +0xD5A4 0x908F # 0 +0xD5A5 0xF95C # 0 +0xD5A6 0x6D1B # 0 +0xD5A7 0x70D9 # 0 +0xD5A8 0x73DE # 0 +0xD5A9 0x7D61 # 0 +0xD5AA 0x843D # 0 +0xD5AB 0xF95D # 0 +0xD5AC 0x916A # 0 +0xD5AD 0x99F1 # 0 +0xD5AE 0xF95E # 0 +0xD5AF 0x4E82 # 0 +0xD5B0 0x5375 # 0 +0xD5B1 0x6B04 # 0 +0xD5B2 0x6B12 # 0 +0xD5B3 0x703E # 0 +0xD5B4 0x721B # 0 +0xD5B5 0x862D # 0 +0xD5B6 0x9E1E # 0 +0xD5B7 0x524C # 0 +0xD5B8 0x8FA3 # 0 +0xD5B9 0x5D50 # 0 +0xD5BA 0x64E5 # 0 +0xD5BB 0x652C # 0 +0xD5BC 0x6B16 # 0 +0xD5BD 0x6FEB # 0 +0xD5BE 0x7C43 # 0 +0xD5BF 0x7E9C # 0 +0xD5C0 0x85CD # 0 +0xD5C1 0x8964 # 0 +0xD5C2 0x89BD # 0 +0xD5C3 0x62C9 # 0 +0xD5C4 0x81D8 # 0 +0xD5C5 0x881F # 0 +0xD5C6 0x5ECA # 0 +0xD5C7 0x6717 # 0 +0xD5C8 0x6D6A # 0 +0xD5C9 0x72FC # 0 +0xD5CA 0x7405 # 0 +0xD5CB 0x746F # 0 +0xD5CC 0x8782 # 0 +0xD5CD 0x90DE # 0 +0xD5CE 0x4F86 # 0 +0xD5CF 0x5D0D # 0 +0xD5D0 0x5FA0 # 0 +0xD5D1 0x840A # 0 +0xD5D2 0x51B7 # 0 +0xD5D3 0x63A0 # 0 +0xD5D4 0x7565 # 0 +0xD5D5 0x4EAE # 0 +0xD5D6 0x5006 # 0 +0xD5D7 0x5169 # 0 +0xD5D8 0x51C9 # 0 +0xD5D9 0x6881 # 0 +0xD5DA 0x6A11 # 0 +0xD5DB 0x7CAE # 0 +0xD5DC 0x7CB1 # 0 +0xD5DD 0x7CE7 # 0 +0xD5DE 0x826F # 0 +0xD5DF 0x8AD2 # 0 +0xD5E0 0x8F1B # 0 +0xD5E1 0x91CF # 0 +0xD5E2 0x4FB6 # 0 +0xD5E3 0x5137 # 0 +0xD5E4 0x52F5 # 0 +0xD5E5 0x5442 # 0 +0xD5E6 0x5EEC # 0 +0xD5E7 0x616E # 0 +0xD5E8 0x623E # 0 +0xD5E9 0x65C5 # 0 +0xD5EA 0x6ADA # 0 +0xD5EB 0x6FFE # 0 +0xD5EC 0x792A # 0 +0xD5ED 0x85DC # 0 +0xD5EE 0x8823 # 0 +0xD5EF 0x95AD # 0 +0xD5F0 0x9A62 # 0 +0xD5F1 0x9A6A # 0 +0xD5F2 0x9E97 # 0 +0xD5F3 0x9ECE # 0 +0xD5F4 0x529B # 0 +0xD5F5 0x66C6 # 0 +0xD5F6 0x6B77 # 0 +0xD5F7 0x701D # 0 +0xD5F8 0x792B # 0 +0xD5F9 0x8F62 # 0 +0xD5FA 0x9742 # 0 +0xD5FB 0x6190 # 0 +0xD5FC 0x6200 # 0 +0xD5FD 0x6523 # 0 +0xD5FE 0x6F23 # 0 +0xD6A1 0x7149 # 0 +0xD6A2 0x7489 # 0 +0xD6A3 0x7DF4 # 0 +0xD6A4 0x806F # 0 +0xD6A5 0x84EE # 0 +0xD6A6 0x8F26 # 0 +0xD6A7 0x9023 # 0 +0xD6A8 0x934A # 0 +0xD6A9 0x51BD # 0 +0xD6AA 0x5217 # 0 +0xD6AB 0x52A3 # 0 +0xD6AC 0x6D0C # 0 +0xD6AD 0x70C8 # 0 +0xD6AE 0x88C2 # 0 +0xD6AF 0x5EC9 # 0 +0xD6B0 0x6582 # 0 +0xD6B1 0x6BAE # 0 +0xD6B2 0x6FC2 # 0 +0xD6B3 0x7C3E # 0 +0xD6B4 0x7375 # 0 +0xD6B5 0x4EE4 # 0 +0xD6B6 0x4F36 # 0 +0xD6B7 0x56F9 # 0 +0xD6B8 0xF95F # 0 +0xD6B9 0x5CBA # 0 +0xD6BA 0x5DBA # 0 +0xD6BB 0x601C # 0 +0xD6BC 0x73B2 # 0 +0xD6BD 0x7B2D # 0 +0xD6BE 0x7F9A # 0 +0xD6BF 0x7FCE # 0 +0xD6C0 0x8046 # 0 +0xD6C1 0x901E # 0 +0xD6C2 0x9234 # 0 +0xD6C3 0x96F6 # 0 +0xD6C4 0x9748 # 0 +0xD6C5 0x9818 # 0 +0xD6C6 0x9F61 # 0 +0xD6C7 0x4F8B # 0 +0xD6C8 0x6FA7 # 0 +0xD6C9 0x79AE # 0 +0xD6CA 0x91B4 # 0 +0xD6CB 0x96B7 # 0 +0xD6CC 0x52DE # 0 +0xD6CD 0xF960 # 0 +0xD6CE 0x6488 # 0 +0xD6CF 0x64C4 # 0 +0xD6D0 0x6AD3 # 0 +0xD6D1 0x6F5E # 0 +0xD6D2 0x7018 # 0 +0xD6D3 0x7210 # 0 +0xD6D4 0x76E7 # 0 +0xD6D5 0x8001 # 0 +0xD6D6 0x8606 # 0 +0xD6D7 0x865C # 0 +0xD6D8 0x8DEF # 0 +0xD6D9 0x8F05 # 0 +0xD6DA 0x9732 # 0 +0xD6DB 0x9B6F # 0 +0xD6DC 0x9DFA # 0 +0xD6DD 0x9E75 # 0 +0xD6DE 0x788C # 0 +0xD6DF 0x797F # 0 +0xD6E0 0x7DA0 # 0 +0xD6E1 0x83C9 # 0 +0xD6E2 0x9304 # 0 +0xD6E3 0x9E7F # 0 +0xD6E4 0x9E93 # 0 +0xD6E5 0x8AD6 # 0 +0xD6E6 0x58DF # 0 +0xD6E7 0x5F04 # 0 +0xD6E8 0x6727 # 0 +0xD6E9 0x7027 # 0 +0xD6EA 0x74CF # 0 +0xD6EB 0x7C60 # 0 +0xD6EC 0x807E # 0 +0xD6ED 0x5121 # 0 +0xD6EE 0x7028 # 0 +0xD6EF 0x7262 # 0 +0xD6F0 0x78CA # 0 +0xD6F1 0x8CC2 # 0 +0xD6F2 0x8CDA # 0 +0xD6F3 0x8CF4 # 0 +0xD6F4 0x96F7 # 0 +0xD6F5 0x4E86 # 0 +0xD6F6 0x50DA # 0 +0xD6F7 0x5BEE # 0 +0xD6F8 0x5ED6 # 0 +0xD6F9 0x6599 # 0 +0xD6FA 0x71CE # 0 +0xD6FB 0x7642 # 0 +0xD6FC 0x77AD # 0 +0xD6FD 0x804A # 0 +0xD6FE 0x84FC # 0 +0xD7A1 0x907C # 0 +0xD7A2 0x9B27 # 0 +0xD7A3 0x9F8D # 0 +0xD7A4 0x58D8 # 0 +0xD7A5 0x5A41 # 0 +0xD7A6 0x5C62 # 0 +0xD7A7 0x6A13 # 0 +0xD7A8 0x6DDA # 0 +0xD7A9 0x6F0F # 0 +0xD7AA 0x763B # 0 +0xD7AB 0x7D2F # 0 +0xD7AC 0x7E37 # 0 +0xD7AD 0x851E # 0 +0xD7AE 0x8938 # 0 +0xD7AF 0x93E4 # 0 +0xD7B0 0x964B # 0 +0xD7B1 0x5289 # 0 +0xD7B2 0x65D2 # 0 +0xD7B3 0x67F3 # 0 +0xD7B4 0x69B4 # 0 +0xD7B5 0x6D41 # 0 +0xD7B6 0x6E9C # 0 +0xD7B7 0x700F # 0 +0xD7B8 0x7409 # 0 +0xD7B9 0x7460 # 0 +0xD7BA 0x7559 # 0 +0xD7BB 0x7624 # 0 +0xD7BC 0x786B # 0 +0xD7BD 0x8B2C # 0 +0xD7BE 0x985E # 0 +0xD7BF 0x516D # 0 +0xD7C0 0x622E # 0 +0xD7C1 0x9678 # 0 +0xD7C2 0x4F96 # 0 +0xD7C3 0x502B # 0 +0xD7C4 0x5D19 # 0 +0xD7C5 0x6DEA # 0 +0xD7C6 0x7DB8 # 0 +0xD7C7 0x8F2A # 0 +0xD7C8 0x5F8B # 0 +0xD7C9 0x6144 # 0 +0xD7CA 0x6817 # 0 +0xD7CB 0xF961 # 0 +0xD7CC 0x9686 # 0 +0xD7CD 0x52D2 # 0 +0xD7CE 0x808B # 0 +0xD7CF 0x51DC # 0 +0xD7D0 0x51CC # 0 +0xD7D1 0x695E # 0 +0xD7D2 0x7A1C # 0 +0xD7D3 0x7DBE # 0 +0xD7D4 0x83F1 # 0 +0xD7D5 0x9675 # 0 +0xD7D6 0x4FDA # 0 +0xD7D7 0x5229 # 0 +0xD7D8 0x5398 # 0 +0xD7D9 0x540F # 0 +0xD7DA 0x550E # 0 +0xD7DB 0x5C65 # 0 +0xD7DC 0x60A7 # 0 +0xD7DD 0x674E # 0 +0xD7DE 0x68A8 # 0 +0xD7DF 0x6D6C # 0 +0xD7E0 0x7281 # 0 +0xD7E1 0x72F8 # 0 +0xD7E2 0x7406 # 0 +0xD7E3 0x7483 # 0 +0xD7E4 0xF962 # 0 +0xD7E5 0x75E2 # 0 +0xD7E6 0x7C6C # 0 +0xD7E7 0x7F79 # 0 +0xD7E8 0x7FB8 # 0 +0xD7E9 0x8389 # 0 +0xD7EA 0x88CF # 0 +0xD7EB 0x88E1 # 0 +0xD7EC 0x91CC # 0 +0xD7ED 0x91D0 # 0 +0xD7EE 0x96E2 # 0 +0xD7EF 0x9BC9 # 0 +0xD7F0 0x541D # 0 +0xD7F1 0x6F7E # 0 +0xD7F2 0x71D0 # 0 +0xD7F3 0x7498 # 0 +0xD7F4 0x85FA # 0 +0xD7F5 0x8EAA # 0 +0xD7F6 0x96A3 # 0 +0xD7F7 0x9C57 # 0 +0xD7F8 0x9E9F # 0 +0xD7F9 0x6797 # 0 +0xD7FA 0x6DCB # 0 +0xD7FB 0x7433 # 0 +0xD7FC 0x81E8 # 0 +0xD7FD 0x9716 # 0 +0xD7FE 0x782C # 0 +0xD8A1 0x7ACB # 0 +0xD8A2 0x7B20 # 0 +0xD8A3 0x7C92 # 0 +0xD8A4 0x6469 # 0 +0xD8A5 0x746A # 0 +0xD8A6 0x75F2 # 0 +0xD8A7 0x78BC # 0 +0xD8A8 0x78E8 # 0 +0xD8A9 0x99AC # 0 +0xD8AA 0x9B54 # 0 +0xD8AB 0x9EBB # 0 +0xD8AC 0x5BDE # 0 +0xD8AD 0x5E55 # 0 +0xD8AE 0x6F20 # 0 +0xD8AF 0x819C # 0 +0xD8B0 0x83AB # 0 +0xD8B1 0x9088 # 0 +0xD8B2 0x4E07 # 0 +0xD8B3 0x534D # 0 +0xD8B4 0x5A29 # 0 +0xD8B5 0x5DD2 # 0 +0xD8B6 0x5F4E # 0 +0xD8B7 0x6162 # 0 +0xD8B8 0x633D # 0 +0xD8B9 0x6669 # 0 +0xD8BA 0x66FC # 0 +0xD8BB 0x6EFF # 0 +0xD8BC 0x6F2B # 0 +0xD8BD 0x7063 # 0 +0xD8BE 0x779E # 0 +0xD8BF 0x842C # 0 +0xD8C0 0x8513 # 0 +0xD8C1 0x883B # 0 +0xD8C2 0x8F13 # 0 +0xD8C3 0x9945 # 0 +0xD8C4 0x9C3B # 0 +0xD8C5 0x551C # 0 +0xD8C6 0x62B9 # 0 +0xD8C7 0x672B # 0 +0xD8C8 0x6CAB # 0 +0xD8C9 0x8309 # 0 +0xD8CA 0x896A # 0 +0xD8CB 0x977A # 0 +0xD8CC 0x4EA1 # 0 +0xD8CD 0x5984 # 0 +0xD8CE 0x5FD8 # 0 +0xD8CF 0x5FD9 # 0 +0xD8D0 0x671B # 0 +0xD8D1 0x7DB2 # 0 +0xD8D2 0x7F54 # 0 +0xD8D3 0x8292 # 0 +0xD8D4 0x832B # 0 +0xD8D5 0x83BD # 0 +0xD8D6 0x8F1E # 0 +0xD8D7 0x9099 # 0 +0xD8D8 0x57CB # 0 +0xD8D9 0x59B9 # 0 +0xD8DA 0x5A92 # 0 +0xD8DB 0x5BD0 # 0 +0xD8DC 0x6627 # 0 +0xD8DD 0x679A # 0 +0xD8DE 0x6885 # 0 +0xD8DF 0x6BCF # 0 +0xD8E0 0x7164 # 0 +0xD8E1 0x7F75 # 0 +0xD8E2 0x8CB7 # 0 +0xD8E3 0x8CE3 # 0 +0xD8E4 0x9081 # 0 +0xD8E5 0x9B45 # 0 +0xD8E6 0x8108 # 0 +0xD8E7 0x8C8A # 0 +0xD8E8 0x964C # 0 +0xD8E9 0x9A40 # 0 +0xD8EA 0x9EA5 # 0 +0xD8EB 0x5B5F # 0 +0xD8EC 0x6C13 # 0 +0xD8ED 0x731B # 0 +0xD8EE 0x76F2 # 0 +0xD8EF 0x76DF # 0 +0xD8F0 0x840C # 0 +0xD8F1 0x51AA # 0 +0xD8F2 0x8993 # 0 +0xD8F3 0x514D # 0 +0xD8F4 0x5195 # 0 +0xD8F5 0x52C9 # 0 +0xD8F6 0x68C9 # 0 +0xD8F7 0x6C94 # 0 +0xD8F8 0x7704 # 0 +0xD8F9 0x7720 # 0 +0xD8FA 0x7DBF # 0 +0xD8FB 0x7DEC # 0 +0xD8FC 0x9762 # 0 +0xD8FD 0x9EB5 # 0 +0xD8FE 0x6EC5 # 0 +0xD9A1 0x8511 # 0 +0xD9A2 0x51A5 # 0 +0xD9A3 0x540D # 0 +0xD9A4 0x547D # 0 +0xD9A5 0x660E # 0 +0xD9A6 0x669D # 0 +0xD9A7 0x6927 # 0 +0xD9A8 0x6E9F # 0 +0xD9A9 0x76BF # 0 +0xD9AA 0x7791 # 0 +0xD9AB 0x8317 # 0 +0xD9AC 0x84C2 # 0 +0xD9AD 0x879F # 0 +0xD9AE 0x9169 # 0 +0xD9AF 0x9298 # 0 +0xD9B0 0x9CF4 # 0 +0xD9B1 0x8882 # 0 +0xD9B2 0x4FAE # 0 +0xD9B3 0x5192 # 0 +0xD9B4 0x52DF # 0 +0xD9B5 0x59C6 # 0 +0xD9B6 0x5E3D # 0 +0xD9B7 0x6155 # 0 +0xD9B8 0x6478 # 0 +0xD9B9 0x6479 # 0 +0xD9BA 0x66AE # 0 +0xD9BB 0x67D0 # 0 +0xD9BC 0x6A21 # 0 +0xD9BD 0x6BCD # 0 +0xD9BE 0x6BDB # 0 +0xD9BF 0x725F # 0 +0xD9C0 0x7261 # 0 +0xD9C1 0x7441 # 0 +0xD9C2 0x7738 # 0 +0xD9C3 0x77DB # 0 +0xD9C4 0x8017 # 0 +0xD9C5 0x82BC # 0 +0xD9C6 0x8305 # 0 +0xD9C7 0x8B00 # 0 +0xD9C8 0x8B28 # 0 +0xD9C9 0x8C8C # 0 +0xD9CA 0x6728 # 0 +0xD9CB 0x6C90 # 0 +0xD9CC 0x7267 # 0 +0xD9CD 0x76EE # 0 +0xD9CE 0x7766 # 0 +0xD9CF 0x7A46 # 0 +0xD9D0 0x9DA9 # 0 +0xD9D1 0x6B7F # 0 +0xD9D2 0x6C92 # 0 +0xD9D3 0x5922 # 0 +0xD9D4 0x6726 # 0 +0xD9D5 0x8499 # 0 +0xD9D6 0x536F # 0 +0xD9D7 0x5893 # 0 +0xD9D8 0x5999 # 0 +0xD9D9 0x5EDF # 0 +0xD9DA 0x63CF # 0 +0xD9DB 0x6634 # 0 +0xD9DC 0x6773 # 0 +0xD9DD 0x6E3A # 0 +0xD9DE 0x732B # 0 +0xD9DF 0x7AD7 # 0 +0xD9E0 0x82D7 # 0 +0xD9E1 0x9328 # 0 +0xD9E2 0x52D9 # 0 +0xD9E3 0x5DEB # 0 +0xD9E4 0x61AE # 0 +0xD9E5 0x61CB # 0 +0xD9E6 0x620A # 0 +0xD9E7 0x62C7 # 0 +0xD9E8 0x64AB # 0 +0xD9E9 0x65E0 # 0 +0xD9EA 0x6959 # 0 +0xD9EB 0x6B66 # 0 +0xD9EC 0x6BCB # 0 +0xD9ED 0x7121 # 0 +0xD9EE 0x73F7 # 0 +0xD9EF 0x755D # 0 +0xD9F0 0x7E46 # 0 +0xD9F1 0x821E # 0 +0xD9F2 0x8302 # 0 +0xD9F3 0x856A # 0 +0xD9F4 0x8AA3 # 0 +0xD9F5 0x8CBF # 0 +0xD9F6 0x9727 # 0 +0xD9F7 0x9D61 # 0 +0xD9F8 0x58A8 # 0 +0xD9F9 0x9ED8 # 0 +0xD9FA 0x5011 # 0 +0xD9FB 0x520E # 0 +0xD9FC 0x543B # 0 +0xD9FD 0x554F # 0 +0xD9FE 0x6587 # 0 +0xDAA1 0x6C76 # 0 +0xDAA2 0x7D0A # 0 +0xDAA3 0x7D0B # 0 +0xDAA4 0x805E # 0 +0xDAA5 0x868A # 0 +0xDAA6 0x9580 # 0 +0xDAA7 0x96EF # 0 +0xDAA8 0x52FF # 0 +0xDAA9 0x6C95 # 0 +0xDAAA 0x7269 # 0 +0xDAAB 0x5473 # 0 +0xDAAC 0x5A9A # 0 +0xDAAD 0x5C3E # 0 +0xDAAE 0x5D4B # 0 +0xDAAF 0x5F4C # 0 +0xDAB0 0x5FAE # 0 +0xDAB1 0x672A # 0 +0xDAB2 0x68B6 # 0 +0xDAB3 0x6963 # 0 +0xDAB4 0x6E3C # 0 +0xDAB5 0x6E44 # 0 +0xDAB6 0x7709 # 0 +0xDAB7 0x7C73 # 0 +0xDAB8 0x7F8E # 0 +0xDAB9 0x8587 # 0 +0xDABA 0x8B0E # 0 +0xDABB 0x8FF7 # 0 +0xDABC 0x9761 # 0 +0xDABD 0x9EF4 # 0 +0xDABE 0x5CB7 # 0 +0xDABF 0x60B6 # 0 +0xDAC0 0x610D # 0 +0xDAC1 0x61AB # 0 +0xDAC2 0x654F # 0 +0xDAC3 0x65FB # 0 +0xDAC4 0x65FC # 0 +0xDAC5 0x6C11 # 0 +0xDAC6 0x6CEF # 0 +0xDAC7 0x739F # 0 +0xDAC8 0x73C9 # 0 +0xDAC9 0x7DE1 # 0 +0xDACA 0x9594 # 0 +0xDACB 0x5BC6 # 0 +0xDACC 0x871C # 0 +0xDACD 0x8B10 # 0 +0xDACE 0x525D # 0 +0xDACF 0x535A # 0 +0xDAD0 0x62CD # 0 +0xDAD1 0x640F # 0 +0xDAD2 0x64B2 # 0 +0xDAD3 0x6734 # 0 +0xDAD4 0x6A38 # 0 +0xDAD5 0x6CCA # 0 +0xDAD6 0x73C0 # 0 +0xDAD7 0x749E # 0 +0xDAD8 0x7B94 # 0 +0xDAD9 0x7C95 # 0 +0xDADA 0x7E1B # 0 +0xDADB 0x818A # 0 +0xDADC 0x8236 # 0 +0xDADD 0x8584 # 0 +0xDADE 0x8FEB # 0 +0xDADF 0x96F9 # 0 +0xDAE0 0x99C1 # 0 +0xDAE1 0x4F34 # 0 +0xDAE2 0x534A # 0 +0xDAE3 0x53CD # 0 +0xDAE4 0x53DB # 0 +0xDAE5 0x62CC # 0 +0xDAE6 0x642C # 0 +0xDAE7 0x6500 # 0 +0xDAE8 0x6591 # 0 +0xDAE9 0x69C3 # 0 +0xDAEA 0x6CEE # 0 +0xDAEB 0x6F58 # 0 +0xDAEC 0x73ED # 0 +0xDAED 0x7554 # 0 +0xDAEE 0x7622 # 0 +0xDAEF 0x76E4 # 0 +0xDAF0 0x76FC # 0 +0xDAF1 0x78D0 # 0 +0xDAF2 0x78FB # 0 +0xDAF3 0x792C # 0 +0xDAF4 0x7D46 # 0 +0xDAF5 0x822C # 0 +0xDAF6 0x87E0 # 0 +0xDAF7 0x8FD4 # 0 +0xDAF8 0x9812 # 0 +0xDAF9 0x98EF # 0 +0xDAFA 0x52C3 # 0 +0xDAFB 0x62D4 # 0 +0xDAFC 0x64A5 # 0 +0xDAFD 0x6E24 # 0 +0xDAFE 0x6F51 # 0 +0xDBA1 0x767C # 0 +0xDBA2 0x8DCB # 0 +0xDBA3 0x91B1 # 0 +0xDBA4 0x9262 # 0 +0xDBA5 0x9AEE # 0 +0xDBA6 0x9B43 # 0 +0xDBA7 0x5023 # 0 +0xDBA8 0x508D # 0 +0xDBA9 0x574A # 0 +0xDBAA 0x59A8 # 0 +0xDBAB 0x5C28 # 0 +0xDBAC 0x5E47 # 0 +0xDBAD 0x5F77 # 0 +0xDBAE 0x623F # 0 +0xDBAF 0x653E # 0 +0xDBB0 0x65B9 # 0 +0xDBB1 0x65C1 # 0 +0xDBB2 0x6609 # 0 +0xDBB3 0x678B # 0 +0xDBB4 0x699C # 0 +0xDBB5 0x6EC2 # 0 +0xDBB6 0x78C5 # 0 +0xDBB7 0x7D21 # 0 +0xDBB8 0x80AA # 0 +0xDBB9 0x8180 # 0 +0xDBBA 0x822B # 0 +0xDBBB 0x82B3 # 0 +0xDBBC 0x84A1 # 0 +0xDBBD 0x868C # 0 +0xDBBE 0x8A2A # 0 +0xDBBF 0x8B17 # 0 +0xDBC0 0x90A6 # 0 +0xDBC1 0x9632 # 0 +0xDBC2 0x9F90 # 0 +0xDBC3 0x500D # 0 +0xDBC4 0x4FF3 # 0 +0xDBC5 0xF963 # 0 +0xDBC6 0x57F9 # 0 +0xDBC7 0x5F98 # 0 +0xDBC8 0x62DC # 0 +0xDBC9 0x6392 # 0 +0xDBCA 0x676F # 0 +0xDBCB 0x6E43 # 0 +0xDBCC 0x7119 # 0 +0xDBCD 0x76C3 # 0 +0xDBCE 0x80CC # 0 +0xDBCF 0x80DA # 0 +0xDBD0 0x88F4 # 0 +0xDBD1 0x88F5 # 0 +0xDBD2 0x8919 # 0 +0xDBD3 0x8CE0 # 0 +0xDBD4 0x8F29 # 0 +0xDBD5 0x914D # 0 +0xDBD6 0x966A # 0 +0xDBD7 0x4F2F # 0 +0xDBD8 0x4F70 # 0 +0xDBD9 0x5E1B # 0 +0xDBDA 0x67CF # 0 +0xDBDB 0x6822 # 0 +0xDBDC 0x767D # 0 +0xDBDD 0x767E # 0 +0xDBDE 0x9B44 # 0 +0xDBDF 0x5E61 # 0 +0xDBE0 0x6A0A # 0 +0xDBE1 0x7169 # 0 +0xDBE2 0x71D4 # 0 +0xDBE3 0x756A # 0 +0xDBE4 0xF964 # 0 +0xDBE5 0x7E41 # 0 +0xDBE6 0x8543 # 0 +0xDBE7 0x85E9 # 0 +0xDBE8 0x98DC # 0 +0xDBE9 0x4F10 # 0 +0xDBEA 0x7B4F # 0 +0xDBEB 0x7F70 # 0 +0xDBEC 0x95A5 # 0 +0xDBED 0x51E1 # 0 +0xDBEE 0x5E06 # 0 +0xDBEF 0x68B5 # 0 +0xDBF0 0x6C3E # 0 +0xDBF1 0x6C4E # 0 +0xDBF2 0x6CDB # 0 +0xDBF3 0x72AF # 0 +0xDBF4 0x7BC4 # 0 +0xDBF5 0x8303 # 0 +0xDBF6 0x6CD5 # 0 +0xDBF7 0x743A # 0 +0xDBF8 0x50FB # 0 +0xDBF9 0x5288 # 0 +0xDBFA 0x58C1 # 0 +0xDBFB 0x64D8 # 0 +0xDBFC 0x6A97 # 0 +0xDBFD 0x74A7 # 0 +0xDBFE 0x7656 # 0 +0xDCA1 0x78A7 # 0 +0xDCA2 0x8617 # 0 +0xDCA3 0x95E2 # 0 +0xDCA4 0x9739 # 0 +0xDCA5 0xF965 # 0 +0xDCA6 0x535E # 0 +0xDCA7 0x5F01 # 0 +0xDCA8 0x8B8A # 0 +0xDCA9 0x8FA8 # 0 +0xDCAA 0x8FAF # 0 +0xDCAB 0x908A # 0 +0xDCAC 0x5225 # 0 +0xDCAD 0x77A5 # 0 +0xDCAE 0x9C49 # 0 +0xDCAF 0x9F08 # 0 +0xDCB0 0x4E19 # 0 +0xDCB1 0x5002 # 0 +0xDCB2 0x5175 # 0 +0xDCB3 0x5C5B # 0 +0xDCB4 0x5E77 # 0 +0xDCB5 0x661E # 0 +0xDCB6 0x663A # 0 +0xDCB7 0x67C4 # 0 +0xDCB8 0x68C5 # 0 +0xDCB9 0x70B3 # 0 +0xDCBA 0x7501 # 0 +0xDCBB 0x75C5 # 0 +0xDCBC 0x79C9 # 0 +0xDCBD 0x7ADD # 0 +0xDCBE 0x8F27 # 0 +0xDCBF 0x9920 # 0 +0xDCC0 0x9A08 # 0 +0xDCC1 0x4FDD # 0 +0xDCC2 0x5821 # 0 +0xDCC3 0x5831 # 0 +0xDCC4 0x5BF6 # 0 +0xDCC5 0x666E # 0 +0xDCC6 0x6B65 # 0 +0xDCC7 0x6D11 # 0 +0xDCC8 0x6E7A # 0 +0xDCC9 0x6F7D # 0 +0xDCCA 0x73E4 # 0 +0xDCCB 0x752B # 0 +0xDCCC 0x83E9 # 0 +0xDCCD 0x88DC # 0 +0xDCCE 0x8913 # 0 +0xDCCF 0x8B5C # 0 +0xDCD0 0x8F14 # 0 +0xDCD1 0x4F0F # 0 +0xDCD2 0x50D5 # 0 +0xDCD3 0x5310 # 0 +0xDCD4 0x535C # 0 +0xDCD5 0x5B93 # 0 +0xDCD6 0x5FA9 # 0 +0xDCD7 0x670D # 0 +0xDCD8 0x798F # 0 +0xDCD9 0x8179 # 0 +0xDCDA 0x832F # 0 +0xDCDB 0x8514 # 0 +0xDCDC 0x8907 # 0 +0xDCDD 0x8986 # 0 +0xDCDE 0x8F39 # 0 +0xDCDF 0x8F3B # 0 +0xDCE0 0x99A5 # 0 +0xDCE1 0x9C12 # 0 +0xDCE2 0x672C # 0 +0xDCE3 0x4E76 # 0 +0xDCE4 0x4FF8 # 0 +0xDCE5 0x5949 # 0 +0xDCE6 0x5C01 # 0 +0xDCE7 0x5CEF # 0 +0xDCE8 0x5CF0 # 0 +0xDCE9 0x6367 # 0 +0xDCEA 0x68D2 # 0 +0xDCEB 0x70FD # 0 +0xDCEC 0x71A2 # 0 +0xDCED 0x742B # 0 +0xDCEE 0x7E2B # 0 +0xDCEF 0x84EC # 0 +0xDCF0 0x8702 # 0 +0xDCF1 0x9022 # 0 +0xDCF2 0x92D2 # 0 +0xDCF3 0x9CF3 # 0 +0xDCF4 0x4E0D # 0 +0xDCF5 0x4ED8 # 0 +0xDCF6 0x4FEF # 0 +0xDCF7 0x5085 # 0 +0xDCF8 0x5256 # 0 +0xDCF9 0x526F # 0 +0xDCFA 0x5426 # 0 +0xDCFB 0x5490 # 0 +0xDCFC 0x57E0 # 0 +0xDCFD 0x592B # 0 +0xDCFE 0x5A66 # 0 +0xDDA1 0x5B5A # 0 +0xDDA2 0x5B75 # 0 +0xDDA3 0x5BCC # 0 +0xDDA4 0x5E9C # 0 +0xDDA5 0xF966 # 0 +0xDDA6 0x6276 # 0 +0xDDA7 0x6577 # 0 +0xDDA8 0x65A7 # 0 +0xDDA9 0x6D6E # 0 +0xDDAA 0x6EA5 # 0 +0xDDAB 0x7236 # 0 +0xDDAC 0x7B26 # 0 +0xDDAD 0x7C3F # 0 +0xDDAE 0x7F36 # 0 +0xDDAF 0x8150 # 0 +0xDDB0 0x8151 # 0 +0xDDB1 0x819A # 0 +0xDDB2 0x8240 # 0 +0xDDB3 0x8299 # 0 +0xDDB4 0x83A9 # 0 +0xDDB5 0x8A03 # 0 +0xDDB6 0x8CA0 # 0 +0xDDB7 0x8CE6 # 0 +0xDDB8 0x8CFB # 0 +0xDDB9 0x8D74 # 0 +0xDDBA 0x8DBA # 0 +0xDDBB 0x90E8 # 0 +0xDDBC 0x91DC # 0 +0xDDBD 0x961C # 0 +0xDDBE 0x9644 # 0 +0xDDBF 0x99D9 # 0 +0xDDC0 0x9CE7 # 0 +0xDDC1 0x5317 # 0 +0xDDC2 0x5206 # 0 +0xDDC3 0x5429 # 0 +0xDDC4 0x5674 # 0 +0xDDC5 0x58B3 # 0 +0xDDC6 0x5954 # 0 +0xDDC7 0x596E # 0 +0xDDC8 0x5FFF # 0 +0xDDC9 0x61A4 # 0 +0xDDCA 0x626E # 0 +0xDDCB 0x6610 # 0 +0xDDCC 0x6C7E # 0 +0xDDCD 0x711A # 0 +0xDDCE 0x76C6 # 0 +0xDDCF 0x7C89 # 0 +0xDDD0 0x7CDE # 0 +0xDDD1 0x7D1B # 0 +0xDDD2 0x82AC # 0 +0xDDD3 0x8CC1 # 0 +0xDDD4 0x96F0 # 0 +0xDDD5 0xF967 # 0 +0xDDD6 0x4F5B # 0 +0xDDD7 0x5F17 # 0 +0xDDD8 0x5F7F # 0 +0xDDD9 0x62C2 # 0 +0xDDDA 0x5D29 # 0 +0xDDDB 0x670B # 0 +0xDDDC 0x68DA # 0 +0xDDDD 0x787C # 0 +0xDDDE 0x7E43 # 0 +0xDDDF 0x9D6C # 0 +0xDDE0 0x4E15 # 0 +0xDDE1 0x5099 # 0 +0xDDE2 0x5315 # 0 +0xDDE3 0x532A # 0 +0xDDE4 0x5351 # 0 +0xDDE5 0x5983 # 0 +0xDDE6 0x5A62 # 0 +0xDDE7 0x5E87 # 0 +0xDDE8 0x60B2 # 0 +0xDDE9 0x618A # 0 +0xDDEA 0x6249 # 0 +0xDDEB 0x6279 # 0 +0xDDEC 0x6590 # 0 +0xDDED 0x6787 # 0 +0xDDEE 0x69A7 # 0 +0xDDEF 0x6BD4 # 0 +0xDDF0 0x6BD6 # 0 +0xDDF1 0x6BD7 # 0 +0xDDF2 0x6BD8 # 0 +0xDDF3 0x6CB8 # 0 +0xDDF4 0xF968 # 0 +0xDDF5 0x7435 # 0 +0xDDF6 0x75FA # 0 +0xDDF7 0x7812 # 0 +0xDDF8 0x7891 # 0 +0xDDF9 0x79D5 # 0 +0xDDFA 0x79D8 # 0 +0xDDFB 0x7C83 # 0 +0xDDFC 0x7DCB # 0 +0xDDFD 0x7FE1 # 0 +0xDDFE 0x80A5 # 0 +0xDEA1 0x813E # 0 +0xDEA2 0x81C2 # 0 +0xDEA3 0x83F2 # 0 +0xDEA4 0x871A # 0 +0xDEA5 0x88E8 # 0 +0xDEA6 0x8AB9 # 0 +0xDEA7 0x8B6C # 0 +0xDEA8 0x8CBB # 0 +0xDEA9 0x9119 # 0 +0xDEAA 0x975E # 0 +0xDEAB 0x98DB # 0 +0xDEAC 0x9F3B # 0 +0xDEAD 0x56AC # 0 +0xDEAE 0x5B2A # 0 +0xDEAF 0x5F6C # 0 +0xDEB0 0x658C # 0 +0xDEB1 0x6AB3 # 0 +0xDEB2 0x6BAF # 0 +0xDEB3 0x6D5C # 0 +0xDEB4 0x6FF1 # 0 +0xDEB5 0x7015 # 0 +0xDEB6 0x725D # 0 +0xDEB7 0x73AD # 0 +0xDEB8 0x8CA7 # 0 +0xDEB9 0x8CD3 # 0 +0xDEBA 0x983B # 0 +0xDEBB 0x6191 # 0 +0xDEBC 0x6C37 # 0 +0xDEBD 0x8058 # 0 +0xDEBE 0x9A01 # 0 +0xDEBF 0x4E4D # 0 +0xDEC0 0x4E8B # 0 +0xDEC1 0x4E9B # 0 +0xDEC2 0x4ED5 # 0 +0xDEC3 0x4F3A # 0 +0xDEC4 0x4F3C # 0 +0xDEC5 0x4F7F # 0 +0xDEC6 0x4FDF # 0 +0xDEC7 0x50FF # 0 +0xDEC8 0x53F2 # 0 +0xDEC9 0x53F8 # 0 +0xDECA 0x5506 # 0 +0xDECB 0x55E3 # 0 +0xDECC 0x56DB # 0 +0xDECD 0x58EB # 0 +0xDECE 0x5962 # 0 +0xDECF 0x5A11 # 0 +0xDED0 0x5BEB # 0 +0xDED1 0x5BFA # 0 +0xDED2 0x5C04 # 0 +0xDED3 0x5DF3 # 0 +0xDED4 0x5E2B # 0 +0xDED5 0x5F99 # 0 +0xDED6 0x601D # 0 +0xDED7 0x6368 # 0 +0xDED8 0x659C # 0 +0xDED9 0x65AF # 0 +0xDEDA 0x67F6 # 0 +0xDEDB 0x67FB # 0 +0xDEDC 0x68AD # 0 +0xDEDD 0x6B7B # 0 +0xDEDE 0x6C99 # 0 +0xDEDF 0x6CD7 # 0 +0xDEE0 0x6E23 # 0 +0xDEE1 0x7009 # 0 +0xDEE2 0x7345 # 0 +0xDEE3 0x7802 # 0 +0xDEE4 0x793E # 0 +0xDEE5 0x7940 # 0 +0xDEE6 0x7960 # 0 +0xDEE7 0x79C1 # 0 +0xDEE8 0x7BE9 # 0 +0xDEE9 0x7D17 # 0 +0xDEEA 0x7D72 # 0 +0xDEEB 0x8086 # 0 +0xDEEC 0x820D # 0 +0xDEED 0x838E # 0 +0xDEEE 0x84D1 # 0 +0xDEEF 0x86C7 # 0 +0xDEF0 0x88DF # 0 +0xDEF1 0x8A50 # 0 +0xDEF2 0x8A5E # 0 +0xDEF3 0x8B1D # 0 +0xDEF4 0x8CDC # 0 +0xDEF5 0x8D66 # 0 +0xDEF6 0x8FAD # 0 +0xDEF7 0x90AA # 0 +0xDEF8 0x98FC # 0 +0xDEF9 0x99DF # 0 +0xDEFA 0x9E9D # 0 +0xDEFB 0x524A # 0 +0xDEFC 0xF969 # 0 +0xDEFD 0x6714 # 0 +0xDEFE 0xF96A # 0 +0xDFA1 0x5098 # 0 +0xDFA2 0x522A # 0 +0xDFA3 0x5C71 # 0 +0xDFA4 0x6563 # 0 +0xDFA5 0x6C55 # 0 +0xDFA6 0x73CA # 0 +0xDFA7 0x7523 # 0 +0xDFA8 0x759D # 0 +0xDFA9 0x7B97 # 0 +0xDFAA 0x849C # 0 +0xDFAB 0x9178 # 0 +0xDFAC 0x9730 # 0 +0xDFAD 0x4E77 # 0 +0xDFAE 0x6492 # 0 +0xDFAF 0x6BBA # 0 +0xDFB0 0x715E # 0 +0xDFB1 0x85A9 # 0 +0xDFB2 0x4E09 # 0 +0xDFB3 0xF96B # 0 +0xDFB4 0x6749 # 0 +0xDFB5 0x68EE # 0 +0xDFB6 0x6E17 # 0 +0xDFB7 0x829F # 0 +0xDFB8 0x8518 # 0 +0xDFB9 0x886B # 0 +0xDFBA 0x63F7 # 0 +0xDFBB 0x6F81 # 0 +0xDFBC 0x9212 # 0 +0xDFBD 0x98AF # 0 +0xDFBE 0x4E0A # 0 +0xDFBF 0x50B7 # 0 +0xDFC0 0x50CF # 0 +0xDFC1 0x511F # 0 +0xDFC2 0x5546 # 0 +0xDFC3 0x55AA # 0 +0xDFC4 0x5617 # 0 +0xDFC5 0x5B40 # 0 +0xDFC6 0x5C19 # 0 +0xDFC7 0x5CE0 # 0 +0xDFC8 0x5E38 # 0 +0xDFC9 0x5E8A # 0 +0xDFCA 0x5EA0 # 0 +0xDFCB 0x5EC2 # 0 +0xDFCC 0x60F3 # 0 +0xDFCD 0x6851 # 0 +0xDFCE 0x6A61 # 0 +0xDFCF 0x6E58 # 0 +0xDFD0 0x723D # 0 +0xDFD1 0x7240 # 0 +0xDFD2 0x72C0 # 0 +0xDFD3 0x76F8 # 0 +0xDFD4 0x7965 # 0 +0xDFD5 0x7BB1 # 0 +0xDFD6 0x7FD4 # 0 +0xDFD7 0x88F3 # 0 +0xDFD8 0x89F4 # 0 +0xDFD9 0x8A73 # 0 +0xDFDA 0x8C61 # 0 +0xDFDB 0x8CDE # 0 +0xDFDC 0x971C # 0 +0xDFDD 0x585E # 0 +0xDFDE 0x74BD # 0 +0xDFDF 0x8CFD # 0 +0xDFE0 0x55C7 # 0 +0xDFE1 0xF96C # 0 +0xDFE2 0x7A61 # 0 +0xDFE3 0x7D22 # 0 +0xDFE4 0x8272 # 0 +0xDFE5 0x7272 # 0 +0xDFE6 0x751F # 0 +0xDFE7 0x7525 # 0 +0xDFE8 0xF96D # 0 +0xDFE9 0x7B19 # 0 +0xDFEA 0x5885 # 0 +0xDFEB 0x58FB # 0 +0xDFEC 0x5DBC # 0 +0xDFED 0x5E8F # 0 +0xDFEE 0x5EB6 # 0 +0xDFEF 0x5F90 # 0 +0xDFF0 0x6055 # 0 +0xDFF1 0x6292 # 0 +0xDFF2 0x637F # 0 +0xDFF3 0x654D # 0 +0xDFF4 0x6691 # 0 +0xDFF5 0x66D9 # 0 +0xDFF6 0x66F8 # 0 +0xDFF7 0x6816 # 0 +0xDFF8 0x68F2 # 0 +0xDFF9 0x7280 # 0 +0xDFFA 0x745E # 0 +0xDFFB 0x7B6E # 0 +0xDFFC 0x7D6E # 0 +0xDFFD 0x7DD6 # 0 +0xDFFE 0x7F72 # 0 +0xE0A1 0x80E5 # 0 +0xE0A2 0x8212 # 0 +0xE0A3 0x85AF # 0 +0xE0A4 0x897F # 0 +0xE0A5 0x8A93 # 0 +0xE0A6 0x901D # 0 +0xE0A7 0x92E4 # 0 +0xE0A8 0x9ECD # 0 +0xE0A9 0x9F20 # 0 +0xE0AA 0x5915 # 0 +0xE0AB 0x596D # 0 +0xE0AC 0x5E2D # 0 +0xE0AD 0x60DC # 0 +0xE0AE 0x6614 # 0 +0xE0AF 0x6673 # 0 +0xE0B0 0x6790 # 0 +0xE0B1 0x6C50 # 0 +0xE0B2 0x6DC5 # 0 +0xE0B3 0x6F5F # 0 +0xE0B4 0x77F3 # 0 +0xE0B5 0x78A9 # 0 +0xE0B6 0x84C6 # 0 +0xE0B7 0x91CB # 0 +0xE0B8 0x932B # 0 +0xE0B9 0x4ED9 # 0 +0xE0BA 0x50CA # 0 +0xE0BB 0x5148 # 0 +0xE0BC 0x5584 # 0 +0xE0BD 0x5B0B # 0 +0xE0BE 0x5BA3 # 0 +0xE0BF 0x6247 # 0 +0xE0C0 0x657E # 0 +0xE0C1 0x65CB # 0 +0xE0C2 0x6E32 # 0 +0xE0C3 0x717D # 0 +0xE0C4 0x7401 # 0 +0xE0C5 0x7444 # 0 +0xE0C6 0x7487 # 0 +0xE0C7 0x74BF # 0 +0xE0C8 0x766C # 0 +0xE0C9 0x79AA # 0 +0xE0CA 0x7DDA # 0 +0xE0CB 0x7E55 # 0 +0xE0CC 0x7FA8 # 0 +0xE0CD 0x817A # 0 +0xE0CE 0x81B3 # 0 +0xE0CF 0x8239 # 0 +0xE0D0 0x861A # 0 +0xE0D1 0x87EC # 0 +0xE0D2 0x8A75 # 0 +0xE0D3 0x8DE3 # 0 +0xE0D4 0x9078 # 0 +0xE0D5 0x9291 # 0 +0xE0D6 0x9425 # 0 +0xE0D7 0x994D # 0 +0xE0D8 0x9BAE # 0 +0xE0D9 0x5368 # 0 +0xE0DA 0x5C51 # 0 +0xE0DB 0x6954 # 0 +0xE0DC 0x6CC4 # 0 +0xE0DD 0x6D29 # 0 +0xE0DE 0x6E2B # 0 +0xE0DF 0x820C # 0 +0xE0E0 0x859B # 0 +0xE0E1 0x893B # 0 +0xE0E2 0x8A2D # 0 +0xE0E3 0x8AAA # 0 +0xE0E4 0x96EA # 0 +0xE0E5 0x9F67 # 0 +0xE0E6 0x5261 # 0 +0xE0E7 0x66B9 # 0 +0xE0E8 0x6BB2 # 0 +0xE0E9 0x7E96 # 0 +0xE0EA 0x87FE # 0 +0xE0EB 0x8D0D # 0 +0xE0EC 0x9583 # 0 +0xE0ED 0x965D # 0 +0xE0EE 0x651D # 0 +0xE0EF 0x6D89 # 0 +0xE0F0 0x71EE # 0 +0xE0F1 0xF96E # 0 +0xE0F2 0x57CE # 0 +0xE0F3 0x59D3 # 0 +0xE0F4 0x5BAC # 0 +0xE0F5 0x6027 # 0 +0xE0F6 0x60FA # 0 +0xE0F7 0x6210 # 0 +0xE0F8 0x661F # 0 +0xE0F9 0x665F # 0 +0xE0FA 0x7329 # 0 +0xE0FB 0x73F9 # 0 +0xE0FC 0x76DB # 0 +0xE0FD 0x7701 # 0 +0xE0FE 0x7B6C # 0 +0xE1A1 0x8056 # 0 +0xE1A2 0x8072 # 0 +0xE1A3 0x8165 # 0 +0xE1A4 0x8AA0 # 0 +0xE1A5 0x9192 # 0 +0xE1A6 0x4E16 # 0 +0xE1A7 0x52E2 # 0 +0xE1A8 0x6B72 # 0 +0xE1A9 0x6D17 # 0 +0xE1AA 0x7A05 # 0 +0xE1AB 0x7B39 # 0 +0xE1AC 0x7D30 # 0 +0xE1AD 0xF96F # 0 +0xE1AE 0x8CB0 # 0 +0xE1AF 0x53EC # 0 +0xE1B0 0x562F # 0 +0xE1B1 0x5851 # 0 +0xE1B2 0x5BB5 # 0 +0xE1B3 0x5C0F # 0 +0xE1B4 0x5C11 # 0 +0xE1B5 0x5DE2 # 0 +0xE1B6 0x6240 # 0 +0xE1B7 0x6383 # 0 +0xE1B8 0x6414 # 0 +0xE1B9 0x662D # 0 +0xE1BA 0x68B3 # 0 +0xE1BB 0x6CBC # 0 +0xE1BC 0x6D88 # 0 +0xE1BD 0x6EAF # 0 +0xE1BE 0x701F # 0 +0xE1BF 0x70A4 # 0 +0xE1C0 0x71D2 # 0 +0xE1C1 0x7526 # 0 +0xE1C2 0x758F # 0 +0xE1C3 0x758E # 0 +0xE1C4 0x7619 # 0 +0xE1C5 0x7B11 # 0 +0xE1C6 0x7BE0 # 0 +0xE1C7 0x7C2B # 0 +0xE1C8 0x7D20 # 0 +0xE1C9 0x7D39 # 0 +0xE1CA 0x852C # 0 +0xE1CB 0x856D # 0 +0xE1CC 0x8607 # 0 +0xE1CD 0x8A34 # 0 +0xE1CE 0x900D # 0 +0xE1CF 0x9061 # 0 +0xE1D0 0x90B5 # 0 +0xE1D1 0x92B7 # 0 +0xE1D2 0x97F6 # 0 +0xE1D3 0x9A37 # 0 +0xE1D4 0x4FD7 # 0 +0xE1D5 0x5C6C # 0 +0xE1D6 0x675F # 0 +0xE1D7 0x6D91 # 0 +0xE1D8 0x7C9F # 0 +0xE1D9 0x7E8C # 0 +0xE1DA 0x8B16 # 0 +0xE1DB 0x8D16 # 0 +0xE1DC 0x901F # 0 +0xE1DD 0x5B6B # 0 +0xE1DE 0x5DFD # 0 +0xE1DF 0x640D # 0 +0xE1E0 0x84C0 # 0 +0xE1E1 0x905C # 0 +0xE1E2 0x98E1 # 0 +0xE1E3 0x7387 # 0 +0xE1E4 0x5B8B # 0 +0xE1E5 0x609A # 0 +0xE1E6 0x677E # 0 +0xE1E7 0x6DDE # 0 +0xE1E8 0x8A1F # 0 +0xE1E9 0x8AA6 # 0 +0xE1EA 0x9001 # 0 +0xE1EB 0x980C # 0 +0xE1EC 0x5237 # 0 +0xE1ED 0xF970 # 0 +0xE1EE 0x7051 # 0 +0xE1EF 0x788E # 0 +0xE1F0 0x9396 # 0 +0xE1F1 0x8870 # 0 +0xE1F2 0x91D7 # 0 +0xE1F3 0x4FEE # 0 +0xE1F4 0x53D7 # 0 +0xE1F5 0x55FD # 0 +0xE1F6 0x56DA # 0 +0xE1F7 0x5782 # 0 +0xE1F8 0x58FD # 0 +0xE1F9 0x5AC2 # 0 +0xE1FA 0x5B88 # 0 +0xE1FB 0x5CAB # 0 +0xE1FC 0x5CC0 # 0 +0xE1FD 0x5E25 # 0 +0xE1FE 0x6101 # 0 +0xE2A1 0x620D # 0 +0xE2A2 0x624B # 0 +0xE2A3 0x6388 # 0 +0xE2A4 0x641C # 0 +0xE2A5 0x6536 # 0 +0xE2A6 0x6578 # 0 +0xE2A7 0x6A39 # 0 +0xE2A8 0x6B8A # 0 +0xE2A9 0x6C34 # 0 +0xE2AA 0x6D19 # 0 +0xE2AB 0x6F31 # 0 +0xE2AC 0x71E7 # 0 +0xE2AD 0x72E9 # 0 +0xE2AE 0x7378 # 0 +0xE2AF 0x7407 # 0 +0xE2B0 0x74B2 # 0 +0xE2B1 0x7626 # 0 +0xE2B2 0x7761 # 0 +0xE2B3 0x79C0 # 0 +0xE2B4 0x7A57 # 0 +0xE2B5 0x7AEA # 0 +0xE2B6 0x7CB9 # 0 +0xE2B7 0x7D8F # 0 +0xE2B8 0x7DAC # 0 +0xE2B9 0x7E61 # 0 +0xE2BA 0x7F9E # 0 +0xE2BB 0x8129 # 0 +0xE2BC 0x8331 # 0 +0xE2BD 0x8490 # 0 +0xE2BE 0x84DA # 0 +0xE2BF 0x85EA # 0 +0xE2C0 0x8896 # 0 +0xE2C1 0x8AB0 # 0 +0xE2C2 0x8B90 # 0 +0xE2C3 0x8F38 # 0 +0xE2C4 0x9042 # 0 +0xE2C5 0x9083 # 0 +0xE2C6 0x916C # 0 +0xE2C7 0x9296 # 0 +0xE2C8 0x92B9 # 0 +0xE2C9 0x968B # 0 +0xE2CA 0x96A7 # 0 +0xE2CB 0x96A8 # 0 +0xE2CC 0x96D6 # 0 +0xE2CD 0x9700 # 0 +0xE2CE 0x9808 # 0 +0xE2CF 0x9996 # 0 +0xE2D0 0x9AD3 # 0 +0xE2D1 0x9B1A # 0 +0xE2D2 0x53D4 # 0 +0xE2D3 0x587E # 0 +0xE2D4 0x5919 # 0 +0xE2D5 0x5B70 # 0 +0xE2D6 0x5BBF # 0 +0xE2D7 0x6DD1 # 0 +0xE2D8 0x6F5A # 0 +0xE2D9 0x719F # 0 +0xE2DA 0x7421 # 0 +0xE2DB 0x74B9 # 0 +0xE2DC 0x8085 # 0 +0xE2DD 0x83FD # 0 +0xE2DE 0x5DE1 # 0 +0xE2DF 0x5F87 # 0 +0xE2E0 0x5FAA # 0 +0xE2E1 0x6042 # 0 +0xE2E2 0x65EC # 0 +0xE2E3 0x6812 # 0 +0xE2E4 0x696F # 0 +0xE2E5 0x6A53 # 0 +0xE2E6 0x6B89 # 0 +0xE2E7 0x6D35 # 0 +0xE2E8 0x6DF3 # 0 +0xE2E9 0x73E3 # 0 +0xE2EA 0x76FE # 0 +0xE2EB 0x77AC # 0 +0xE2EC 0x7B4D # 0 +0xE2ED 0x7D14 # 0 +0xE2EE 0x8123 # 0 +0xE2EF 0x821C # 0 +0xE2F0 0x8340 # 0 +0xE2F1 0x84F4 # 0 +0xE2F2 0x8563 # 0 +0xE2F3 0x8A62 # 0 +0xE2F4 0x8AC4 # 0 +0xE2F5 0x9187 # 0 +0xE2F6 0x931E # 0 +0xE2F7 0x9806 # 0 +0xE2F8 0x99B4 # 0 +0xE2F9 0x620C # 0 +0xE2FA 0x8853 # 0 +0xE2FB 0x8FF0 # 0 +0xE2FC 0x9265 # 0 +0xE2FD 0x5D07 # 0 +0xE2FE 0x5D27 # 0 +0xE3A1 0x5D69 # 0 +0xE3A2 0x745F # 0 +0xE3A3 0x819D # 0 +0xE3A4 0x8768 # 0 +0xE3A5 0x6FD5 # 0 +0xE3A6 0x62FE # 0 +0xE3A7 0x7FD2 # 0 +0xE3A8 0x8936 # 0 +0xE3A9 0x8972 # 0 +0xE3AA 0x4E1E # 0 +0xE3AB 0x4E58 # 0 +0xE3AC 0x50E7 # 0 +0xE3AD 0x52DD # 0 +0xE3AE 0x5347 # 0 +0xE3AF 0x627F # 0 +0xE3B0 0x6607 # 0 +0xE3B1 0x7E69 # 0 +0xE3B2 0x8805 # 0 +0xE3B3 0x965E # 0 +0xE3B4 0x4F8D # 0 +0xE3B5 0x5319 # 0 +0xE3B6 0x5636 # 0 +0xE3B7 0x59CB # 0 +0xE3B8 0x5AA4 # 0 +0xE3B9 0x5C38 # 0 +0xE3BA 0x5C4E # 0 +0xE3BB 0x5C4D # 0 +0xE3BC 0x5E02 # 0 +0xE3BD 0x5F11 # 0 +0xE3BE 0x6043 # 0 +0xE3BF 0x65BD # 0 +0xE3C0 0x662F # 0 +0xE3C1 0x6642 # 0 +0xE3C2 0x67BE # 0 +0xE3C3 0x67F4 # 0 +0xE3C4 0x731C # 0 +0xE3C5 0x77E2 # 0 +0xE3C6 0x793A # 0 +0xE3C7 0x7FC5 # 0 +0xE3C8 0x8494 # 0 +0xE3C9 0x84CD # 0 +0xE3CA 0x8996 # 0 +0xE3CB 0x8A66 # 0 +0xE3CC 0x8A69 # 0 +0xE3CD 0x8AE1 # 0 +0xE3CE 0x8C55 # 0 +0xE3CF 0x8C7A # 0 +0xE3D0 0x57F4 # 0 +0xE3D1 0x5BD4 # 0 +0xE3D2 0x5F0F # 0 +0xE3D3 0x606F # 0 +0xE3D4 0x62ED # 0 +0xE3D5 0x690D # 0 +0xE3D6 0x6B96 # 0 +0xE3D7 0x6E5C # 0 +0xE3D8 0x7184 # 0 +0xE3D9 0x7BD2 # 0 +0xE3DA 0x8755 # 0 +0xE3DB 0x8B58 # 0 +0xE3DC 0x8EFE # 0 +0xE3DD 0x98DF # 0 +0xE3DE 0x98FE # 0 +0xE3DF 0x4F38 # 0 +0xE3E0 0x4F81 # 0 +0xE3E1 0x4FE1 # 0 +0xE3E2 0x547B # 0 +0xE3E3 0x5A20 # 0 +0xE3E4 0x5BB8 # 0 +0xE3E5 0x613C # 0 +0xE3E6 0x65B0 # 0 +0xE3E7 0x6668 # 0 +0xE3E8 0x71FC # 0 +0xE3E9 0x7533 # 0 +0xE3EA 0x795E # 0 +0xE3EB 0x7D33 # 0 +0xE3EC 0x814E # 0 +0xE3ED 0x81E3 # 0 +0xE3EE 0x8398 # 0 +0xE3EF 0x85AA # 0 +0xE3F0 0x85CE # 0 +0xE3F1 0x8703 # 0 +0xE3F2 0x8A0A # 0 +0xE3F3 0x8EAB # 0 +0xE3F4 0x8F9B # 0 +0xE3F5 0xF971 # 0 +0xE3F6 0x8FC5 # 0 +0xE3F7 0x5931 # 0 +0xE3F8 0x5BA4 # 0 +0xE3F9 0x5BE6 # 0 +0xE3FA 0x6089 # 0 +0xE3FB 0x5BE9 # 0 +0xE3FC 0x5C0B # 0 +0xE3FD 0x5FC3 # 0 +0xE3FE 0x6C81 # 0 +0xE4A1 0xF972 # 0 +0xE4A2 0x6DF1 # 0 +0xE4A3 0x700B # 0 +0xE4A4 0x751A # 0 +0xE4A5 0x82AF # 0 +0xE4A6 0x8AF6 # 0 +0xE4A7 0x4EC0 # 0 +0xE4A8 0x5341 # 0 +0xE4A9 0xF973 # 0 +0xE4AA 0x96D9 # 0 +0xE4AB 0x6C0F # 0 +0xE4AC 0x4E9E # 0 +0xE4AD 0x4FC4 # 0 +0xE4AE 0x5152 # 0 +0xE4AF 0x555E # 0 +0xE4B0 0x5A25 # 0 +0xE4B1 0x5CE8 # 0 +0xE4B2 0x6211 # 0 +0xE4B3 0x7259 # 0 +0xE4B4 0x82BD # 0 +0xE4B5 0x83AA # 0 +0xE4B6 0x86FE # 0 +0xE4B7 0x8859 # 0 +0xE4B8 0x8A1D # 0 +0xE4B9 0x963F # 0 +0xE4BA 0x96C5 # 0 +0xE4BB 0x9913 # 0 +0xE4BC 0x9D09 # 0 +0xE4BD 0x9D5D # 0 +0xE4BE 0x580A # 0 +0xE4BF 0x5CB3 # 0 +0xE4C0 0x5DBD # 0 +0xE4C1 0x5E44 # 0 +0xE4C2 0x60E1 # 0 +0xE4C3 0x6115 # 0 +0xE4C4 0x63E1 # 0 +0xE4C5 0x6A02 # 0 +0xE4C6 0x6E25 # 0 +0xE4C7 0x9102 # 0 +0xE4C8 0x9354 # 0 +0xE4C9 0x984E # 0 +0xE4CA 0x9C10 # 0 +0xE4CB 0x9F77 # 0 +0xE4CC 0x5B89 # 0 +0xE4CD 0x5CB8 # 0 +0xE4CE 0x6309 # 0 +0xE4CF 0x664F # 0 +0xE4D0 0x6848 # 0 +0xE4D1 0x773C # 0 +0xE4D2 0x96C1 # 0 +0xE4D3 0x978D # 0 +0xE4D4 0x9854 # 0 +0xE4D5 0x9B9F # 0 +0xE4D6 0x65A1 # 0 +0xE4D7 0x8B01 # 0 +0xE4D8 0x8ECB # 0 +0xE4D9 0x95BC # 0 +0xE4DA 0x5535 # 0 +0xE4DB 0x5CA9 # 0 +0xE4DC 0x5DD6 # 0 +0xE4DD 0x5EB5 # 0 +0xE4DE 0x6697 # 0 +0xE4DF 0x764C # 0 +0xE4E0 0x83F4 # 0 +0xE4E1 0x95C7 # 0 +0xE4E2 0x58D3 # 0 +0xE4E3 0x62BC # 0 +0xE4E4 0x72CE # 0 +0xE4E5 0x9D28 # 0 +0xE4E6 0x4EF0 # 0 +0xE4E7 0x592E # 0 +0xE4E8 0x600F # 0 +0xE4E9 0x663B # 0 +0xE4EA 0x6B83 # 0 +0xE4EB 0x79E7 # 0 +0xE4EC 0x9D26 # 0 +0xE4ED 0x5393 # 0 +0xE4EE 0x54C0 # 0 +0xE4EF 0x57C3 # 0 +0xE4F0 0x5D16 # 0 +0xE4F1 0x611B # 0 +0xE4F2 0x66D6 # 0 +0xE4F3 0x6DAF # 0 +0xE4F4 0x788D # 0 +0xE4F5 0x827E # 0 +0xE4F6 0x9698 # 0 +0xE4F7 0x9744 # 0 +0xE4F8 0x5384 # 0 +0xE4F9 0x627C # 0 +0xE4FA 0x6396 # 0 +0xE4FB 0x6DB2 # 0 +0xE4FC 0x7E0A # 0 +0xE4FD 0x814B # 0 +0xE4FE 0x984D # 0 +0xE5A1 0x6AFB # 0 +0xE5A2 0x7F4C # 0 +0xE5A3 0x9DAF # 0 +0xE5A4 0x9E1A # 0 +0xE5A5 0x4E5F # 0 +0xE5A6 0x503B # 0 +0xE5A7 0x51B6 # 0 +0xE5A8 0x591C # 0 +0xE5A9 0x60F9 # 0 +0xE5AA 0x63F6 # 0 +0xE5AB 0x6930 # 0 +0xE5AC 0x723A # 0 +0xE5AD 0x8036 # 0 +0xE5AE 0xF974 # 0 +0xE5AF 0x91CE # 0 +0xE5B0 0x5F31 # 0 +0xE5B1 0xF975 # 0 +0xE5B2 0xF976 # 0 +0xE5B3 0x7D04 # 0 +0xE5B4 0x82E5 # 0 +0xE5B5 0x846F # 0 +0xE5B6 0x84BB # 0 +0xE5B7 0x85E5 # 0 +0xE5B8 0x8E8D # 0 +0xE5B9 0xF977 # 0 +0xE5BA 0x4F6F # 0 +0xE5BB 0xF978 # 0 +0xE5BC 0xF979 # 0 +0xE5BD 0x58E4 # 0 +0xE5BE 0x5B43 # 0 +0xE5BF 0x6059 # 0 +0xE5C0 0x63DA # 0 +0xE5C1 0x6518 # 0 +0xE5C2 0x656D # 0 +0xE5C3 0x6698 # 0 +0xE5C4 0xF97A # 0 +0xE5C5 0x694A # 0 +0xE5C6 0x6A23 # 0 +0xE5C7 0x6D0B # 0 +0xE5C8 0x7001 # 0 +0xE5C9 0x716C # 0 +0xE5CA 0x75D2 # 0 +0xE5CB 0x760D # 0 +0xE5CC 0x79B3 # 0 +0xE5CD 0x7A70 # 0 +0xE5CE 0xF97B # 0 +0xE5CF 0x7F8A # 0 +0xE5D0 0xF97C # 0 +0xE5D1 0x8944 # 0 +0xE5D2 0xF97D # 0 +0xE5D3 0x8B93 # 0 +0xE5D4 0x91C0 # 0 +0xE5D5 0x967D # 0 +0xE5D6 0xF97E # 0 +0xE5D7 0x990A # 0 +0xE5D8 0x5704 # 0 +0xE5D9 0x5FA1 # 0 +0xE5DA 0x65BC # 0 +0xE5DB 0x6F01 # 0 +0xE5DC 0x7600 # 0 +0xE5DD 0x79A6 # 0 +0xE5DE 0x8A9E # 0 +0xE5DF 0x99AD # 0 +0xE5E0 0x9B5A # 0 +0xE5E1 0x9F6C # 0 +0xE5E2 0x5104 # 0 +0xE5E3 0x61B6 # 0 +0xE5E4 0x6291 # 0 +0xE5E5 0x6A8D # 0 +0xE5E6 0x81C6 # 0 +0xE5E7 0x5043 # 0 +0xE5E8 0x5830 # 0 +0xE5E9 0x5F66 # 0 +0xE5EA 0x7109 # 0 +0xE5EB 0x8A00 # 0 +0xE5EC 0x8AFA # 0 +0xE5ED 0x5B7C # 0 +0xE5EE 0x8616 # 0 +0xE5EF 0x4FFA # 0 +0xE5F0 0x513C # 0 +0xE5F1 0x56B4 # 0 +0xE5F2 0x5944 # 0 +0xE5F3 0x63A9 # 0 +0xE5F4 0x6DF9 # 0 +0xE5F5 0x5DAA # 0 +0xE5F6 0x696D # 0 +0xE5F7 0x5186 # 0 +0xE5F8 0x4E88 # 0 +0xE5F9 0x4F59 # 0 +0xE5FA 0xF97F # 0 +0xE5FB 0xF980 # 0 +0xE5FC 0xF981 # 0 +0xE5FD 0x5982 # 0 +0xE5FE 0xF982 # 0 +0xE6A1 0xF983 # 0 +0xE6A2 0x6B5F # 0 +0xE6A3 0x6C5D # 0 +0xE6A4 0xF984 # 0 +0xE6A5 0x74B5 # 0 +0xE6A6 0x7916 # 0 +0xE6A7 0xF985 # 0 +0xE6A8 0x8207 # 0 +0xE6A9 0x8245 # 0 +0xE6AA 0x8339 # 0 +0xE6AB 0x8F3F # 0 +0xE6AC 0x8F5D # 0 +0xE6AD 0xF986 # 0 +0xE6AE 0x9918 # 0 +0xE6AF 0xF987 # 0 +0xE6B0 0xF988 # 0 +0xE6B1 0xF989 # 0 +0xE6B2 0x4EA6 # 0 +0xE6B3 0xF98A # 0 +0xE6B4 0x57DF # 0 +0xE6B5 0x5F79 # 0 +0xE6B6 0x6613 # 0 +0xE6B7 0xF98B # 0 +0xE6B8 0xF98C # 0 +0xE6B9 0x75AB # 0 +0xE6BA 0x7E79 # 0 +0xE6BB 0x8B6F # 0 +0xE6BC 0xF98D # 0 +0xE6BD 0x9006 # 0 +0xE6BE 0x9A5B # 0 +0xE6BF 0x56A5 # 0 +0xE6C0 0x5827 # 0 +0xE6C1 0x59F8 # 0 +0xE6C2 0x5A1F # 0 +0xE6C3 0x5BB4 # 0 +0xE6C4 0xF98E # 0 +0xE6C5 0x5EF6 # 0 +0xE6C6 0xF98F # 0 +0xE6C7 0xF990 # 0 +0xE6C8 0x6350 # 0 +0xE6C9 0x633B # 0 +0xE6CA 0xF991 # 0 +0xE6CB 0x693D # 0 +0xE6CC 0x6C87 # 0 +0xE6CD 0x6CBF # 0 +0xE6CE 0x6D8E # 0 +0xE6CF 0x6D93 # 0 +0xE6D0 0x6DF5 # 0 +0xE6D1 0x6F14 # 0 +0xE6D2 0xF992 # 0 +0xE6D3 0x70DF # 0 +0xE6D4 0x7136 # 0 +0xE6D5 0x7159 # 0 +0xE6D6 0xF993 # 0 +0xE6D7 0x71C3 # 0 +0xE6D8 0x71D5 # 0 +0xE6D9 0xF994 # 0 +0xE6DA 0x784F # 0 +0xE6DB 0x786F # 0 +0xE6DC 0xF995 # 0 +0xE6DD 0x7B75 # 0 +0xE6DE 0x7DE3 # 0 +0xE6DF 0xF996 # 0 +0xE6E0 0x7E2F # 0 +0xE6E1 0xF997 # 0 +0xE6E2 0x884D # 0 +0xE6E3 0x8EDF # 0 +0xE6E4 0xF998 # 0 +0xE6E5 0xF999 # 0 +0xE6E6 0xF99A # 0 +0xE6E7 0x925B # 0 +0xE6E8 0xF99B # 0 +0xE6E9 0x9CF6 # 0 +0xE6EA 0xF99C # 0 +0xE6EB 0xF99D # 0 +0xE6EC 0xF99E # 0 +0xE6ED 0x6085 # 0 +0xE6EE 0x6D85 # 0 +0xE6EF 0xF99F # 0 +0xE6F0 0x71B1 # 0 +0xE6F1 0xF9A0 # 0 +0xE6F2 0xF9A1 # 0 +0xE6F3 0x95B1 # 0 +0xE6F4 0x53AD # 0 +0xE6F5 0xF9A2 # 0 +0xE6F6 0xF9A3 # 0 +0xE6F7 0xF9A4 # 0 +0xE6F8 0x67D3 # 0 +0xE6F9 0xF9A5 # 0 +0xE6FA 0x708E # 0 +0xE6FB 0x7130 # 0 +0xE6FC 0x7430 # 0 +0xE6FD 0x8276 # 0 +0xE6FE 0x82D2 # 0 +0xE7A1 0xF9A6 # 0 +0xE7A2 0x95BB # 0 +0xE7A3 0x9AE5 # 0 +0xE7A4 0x9E7D # 0 +0xE7A5 0x66C4 # 0 +0xE7A6 0xF9A7 # 0 +0xE7A7 0x71C1 # 0 +0xE7A8 0x8449 # 0 +0xE7A9 0xF9A8 # 0 +0xE7AA 0xF9A9 # 0 +0xE7AB 0x584B # 0 +0xE7AC 0xF9AA # 0 +0xE7AD 0xF9AB # 0 +0xE7AE 0x5DB8 # 0 +0xE7AF 0x5F71 # 0 +0xE7B0 0xF9AC # 0 +0xE7B1 0x6620 # 0 +0xE7B2 0x668E # 0 +0xE7B3 0x6979 # 0 +0xE7B4 0x69AE # 0 +0xE7B5 0x6C38 # 0 +0xE7B6 0x6CF3 # 0 +0xE7B7 0x6E36 # 0 +0xE7B8 0x6F41 # 0 +0xE7B9 0x6FDA # 0 +0xE7BA 0x701B # 0 +0xE7BB 0x702F # 0 +0xE7BC 0x7150 # 0 +0xE7BD 0x71DF # 0 +0xE7BE 0x7370 # 0 +0xE7BF 0xF9AD # 0 +0xE7C0 0x745B # 0 +0xE7C1 0xF9AE # 0 +0xE7C2 0x74D4 # 0 +0xE7C3 0x76C8 # 0 +0xE7C4 0x7A4E # 0 +0xE7C5 0x7E93 # 0 +0xE7C6 0xF9AF # 0 +0xE7C7 0xF9B0 # 0 +0xE7C8 0x82F1 # 0 +0xE7C9 0x8A60 # 0 +0xE7CA 0x8FCE # 0 +0xE7CB 0xF9B1 # 0 +0xE7CC 0x9348 # 0 +0xE7CD 0xF9B2 # 0 +0xE7CE 0x9719 # 0 +0xE7CF 0xF9B3 # 0 +0xE7D0 0xF9B4 # 0 +0xE7D1 0x4E42 # 0 +0xE7D2 0x502A # 0 +0xE7D3 0xF9B5 # 0 +0xE7D4 0x5208 # 0 +0xE7D5 0x53E1 # 0 +0xE7D6 0x66F3 # 0 +0xE7D7 0x6C6D # 0 +0xE7D8 0x6FCA # 0 +0xE7D9 0x730A # 0 +0xE7DA 0x777F # 0 +0xE7DB 0x7A62 # 0 +0xE7DC 0x82AE # 0 +0xE7DD 0x85DD # 0 +0xE7DE 0x8602 # 0 +0xE7DF 0xF9B6 # 0 +0xE7E0 0x88D4 # 0 +0xE7E1 0x8A63 # 0 +0xE7E2 0x8B7D # 0 +0xE7E3 0x8C6B # 0 +0xE7E4 0xF9B7 # 0 +0xE7E5 0x92B3 # 0 +0xE7E6 0xF9B8 # 0 +0xE7E7 0x9713 # 0 +0xE7E8 0x9810 # 0 +0xE7E9 0x4E94 # 0 +0xE7EA 0x4F0D # 0 +0xE7EB 0x4FC9 # 0 +0xE7EC 0x50B2 # 0 +0xE7ED 0x5348 # 0 +0xE7EE 0x543E # 0 +0xE7EF 0x5433 # 0 +0xE7F0 0x55DA # 0 +0xE7F1 0x5862 # 0 +0xE7F2 0x58BA # 0 +0xE7F3 0x5967 # 0 +0xE7F4 0x5A1B # 0 +0xE7F5 0x5BE4 # 0 +0xE7F6 0x609F # 0 +0xE7F7 0xF9B9 # 0 +0xE7F8 0x61CA # 0 +0xE7F9 0x6556 # 0 +0xE7FA 0x65FF # 0 +0xE7FB 0x6664 # 0 +0xE7FC 0x68A7 # 0 +0xE7FD 0x6C5A # 0 +0xE7FE 0x6FB3 # 0 +0xE8A1 0x70CF # 0 +0xE8A2 0x71AC # 0 +0xE8A3 0x7352 # 0 +0xE8A4 0x7B7D # 0 +0xE8A5 0x8708 # 0 +0xE8A6 0x8AA4 # 0 +0xE8A7 0x9C32 # 0 +0xE8A8 0x9F07 # 0 +0xE8A9 0x5C4B # 0 +0xE8AA 0x6C83 # 0 +0xE8AB 0x7344 # 0 +0xE8AC 0x7389 # 0 +0xE8AD 0x923A # 0 +0xE8AE 0x6EAB # 0 +0xE8AF 0x7465 # 0 +0xE8B0 0x761F # 0 +0xE8B1 0x7A69 # 0 +0xE8B2 0x7E15 # 0 +0xE8B3 0x860A # 0 +0xE8B4 0x5140 # 0 +0xE8B5 0x58C5 # 0 +0xE8B6 0x64C1 # 0 +0xE8B7 0x74EE # 0 +0xE8B8 0x7515 # 0 +0xE8B9 0x7670 # 0 +0xE8BA 0x7FC1 # 0 +0xE8BB 0x9095 # 0 +0xE8BC 0x96CD # 0 +0xE8BD 0x9954 # 0 +0xE8BE 0x6E26 # 0 +0xE8BF 0x74E6 # 0 +0xE8C0 0x7AA9 # 0 +0xE8C1 0x7AAA # 0 +0xE8C2 0x81E5 # 0 +0xE8C3 0x86D9 # 0 +0xE8C4 0x8778 # 0 +0xE8C5 0x8A1B # 0 +0xE8C6 0x5A49 # 0 +0xE8C7 0x5B8C # 0 +0xE8C8 0x5B9B # 0 +0xE8C9 0x68A1 # 0 +0xE8CA 0x6900 # 0 +0xE8CB 0x6D63 # 0 +0xE8CC 0x73A9 # 0 +0xE8CD 0x7413 # 0 +0xE8CE 0x742C # 0 +0xE8CF 0x7897 # 0 +0xE8D0 0x7DE9 # 0 +0xE8D1 0x7FEB # 0 +0xE8D2 0x8118 # 0 +0xE8D3 0x8155 # 0 +0xE8D4 0x839E # 0 +0xE8D5 0x8C4C # 0 +0xE8D6 0x962E # 0 +0xE8D7 0x9811 # 0 +0xE8D8 0x66F0 # 0 +0xE8D9 0x5F80 # 0 +0xE8DA 0x65FA # 0 +0xE8DB 0x6789 # 0 +0xE8DC 0x6C6A # 0 +0xE8DD 0x738B # 0 +0xE8DE 0x502D # 0 +0xE8DF 0x5A03 # 0 +0xE8E0 0x6B6A # 0 +0xE8E1 0x77EE # 0 +0xE8E2 0x5916 # 0 +0xE8E3 0x5D6C # 0 +0xE8E4 0x5DCD # 0 +0xE8E5 0x7325 # 0 +0xE8E6 0x754F # 0 +0xE8E7 0xF9BA # 0 +0xE8E8 0xF9BB # 0 +0xE8E9 0x50E5 # 0 +0xE8EA 0x51F9 # 0 +0xE8EB 0x582F # 0 +0xE8EC 0x592D # 0 +0xE8ED 0x5996 # 0 +0xE8EE 0x59DA # 0 +0xE8EF 0x5BE5 # 0 +0xE8F0 0xF9BC # 0 +0xE8F1 0xF9BD # 0 +0xE8F2 0x5DA2 # 0 +0xE8F3 0x62D7 # 0 +0xE8F4 0x6416 # 0 +0xE8F5 0x6493 # 0 +0xE8F6 0x64FE # 0 +0xE8F7 0xF9BE # 0 +0xE8F8 0x66DC # 0 +0xE8F9 0xF9BF # 0 +0xE8FA 0x6A48 # 0 +0xE8FB 0xF9C0 # 0 +0xE8FC 0x71FF # 0 +0xE8FD 0x7464 # 0 +0xE8FE 0xF9C1 # 0 +0xE9A1 0x7A88 # 0 +0xE9A2 0x7AAF # 0 +0xE9A3 0x7E47 # 0 +0xE9A4 0x7E5E # 0 +0xE9A5 0x8000 # 0 +0xE9A6 0x8170 # 0 +0xE9A7 0xF9C2 # 0 +0xE9A8 0x87EF # 0 +0xE9A9 0x8981 # 0 +0xE9AA 0x8B20 # 0 +0xE9AB 0x9059 # 0 +0xE9AC 0xF9C3 # 0 +0xE9AD 0x9080 # 0 +0xE9AE 0x9952 # 0 +0xE9AF 0x617E # 0 +0xE9B0 0x6B32 # 0 +0xE9B1 0x6D74 # 0 +0xE9B2 0x7E1F # 0 +0xE9B3 0x8925 # 0 +0xE9B4 0x8FB1 # 0 +0xE9B5 0x4FD1 # 0 +0xE9B6 0x50AD # 0 +0xE9B7 0x5197 # 0 +0xE9B8 0x52C7 # 0 +0xE9B9 0x57C7 # 0 +0xE9BA 0x5889 # 0 +0xE9BB 0x5BB9 # 0 +0xE9BC 0x5EB8 # 0 +0xE9BD 0x6142 # 0 +0xE9BE 0x6995 # 0 +0xE9BF 0x6D8C # 0 +0xE9C0 0x6E67 # 0 +0xE9C1 0x6EB6 # 0 +0xE9C2 0x7194 # 0 +0xE9C3 0x7462 # 0 +0xE9C4 0x7528 # 0 +0xE9C5 0x752C # 0 +0xE9C6 0x8073 # 0 +0xE9C7 0x8338 # 0 +0xE9C8 0x84C9 # 0 +0xE9C9 0x8E0A # 0 +0xE9CA 0x9394 # 0 +0xE9CB 0x93DE # 0 +0xE9CC 0xF9C4 # 0 +0xE9CD 0x4E8E # 0 +0xE9CE 0x4F51 # 0 +0xE9CF 0x5076 # 0 +0xE9D0 0x512A # 0 +0xE9D1 0x53C8 # 0 +0xE9D2 0x53CB # 0 +0xE9D3 0x53F3 # 0 +0xE9D4 0x5B87 # 0 +0xE9D5 0x5BD3 # 0 +0xE9D6 0x5C24 # 0 +0xE9D7 0x611A # 0 +0xE9D8 0x6182 # 0 +0xE9D9 0x65F4 # 0 +0xE9DA 0x725B # 0 +0xE9DB 0x7397 # 0 +0xE9DC 0x7440 # 0 +0xE9DD 0x76C2 # 0 +0xE9DE 0x7950 # 0 +0xE9DF 0x7991 # 0 +0xE9E0 0x79B9 # 0 +0xE9E1 0x7D06 # 0 +0xE9E2 0x7FBD # 0 +0xE9E3 0x828B # 0 +0xE9E4 0x85D5 # 0 +0xE9E5 0x865E # 0 +0xE9E6 0x8FC2 # 0 +0xE9E7 0x9047 # 0 +0xE9E8 0x90F5 # 0 +0xE9E9 0x91EA # 0 +0xE9EA 0x9685 # 0 +0xE9EB 0x96E8 # 0 +0xE9EC 0x96E9 # 0 +0xE9ED 0x52D6 # 0 +0xE9EE 0x5F67 # 0 +0xE9EF 0x65ED # 0 +0xE9F0 0x6631 # 0 +0xE9F1 0x682F # 0 +0xE9F2 0x715C # 0 +0xE9F3 0x7A36 # 0 +0xE9F4 0x90C1 # 0 +0xE9F5 0x980A # 0 +0xE9F6 0x4E91 # 0 +0xE9F7 0xF9C5 # 0 +0xE9F8 0x6A52 # 0 +0xE9F9 0x6B9E # 0 +0xE9FA 0x6F90 # 0 +0xE9FB 0x7189 # 0 +0xE9FC 0x8018 # 0 +0xE9FD 0x82B8 # 0 +0xE9FE 0x8553 # 0 +0xEAA1 0x904B # 0 +0xEAA2 0x9695 # 0 +0xEAA3 0x96F2 # 0 +0xEAA4 0x97FB # 0 +0xEAA5 0x851A # 0 +0xEAA6 0x9B31 # 0 +0xEAA7 0x4E90 # 0 +0xEAA8 0x718A # 0 +0xEAA9 0x96C4 # 0 +0xEAAA 0x5143 # 0 +0xEAAB 0x539F # 0 +0xEAAC 0x54E1 # 0 +0xEAAD 0x5713 # 0 +0xEAAE 0x5712 # 0 +0xEAAF 0x57A3 # 0 +0xEAB0 0x5A9B # 0 +0xEAB1 0x5AC4 # 0 +0xEAB2 0x5BC3 # 0 +0xEAB3 0x6028 # 0 +0xEAB4 0x613F # 0 +0xEAB5 0x63F4 # 0 +0xEAB6 0x6C85 # 0 +0xEAB7 0x6D39 # 0 +0xEAB8 0x6E72 # 0 +0xEAB9 0x6E90 # 0 +0xEABA 0x7230 # 0 +0xEABB 0x733F # 0 +0xEABC 0x7457 # 0 +0xEABD 0x82D1 # 0 +0xEABE 0x8881 # 0 +0xEABF 0x8F45 # 0 +0xEAC0 0x9060 # 0 +0xEAC1 0xF9C6 # 0 +0xEAC2 0x9662 # 0 +0xEAC3 0x9858 # 0 +0xEAC4 0x9D1B # 0 +0xEAC5 0x6708 # 0 +0xEAC6 0x8D8A # 0 +0xEAC7 0x925E # 0 +0xEAC8 0x4F4D # 0 +0xEAC9 0x5049 # 0 +0xEACA 0x50DE # 0 +0xEACB 0x5371 # 0 +0xEACC 0x570D # 0 +0xEACD 0x59D4 # 0 +0xEACE 0x5A01 # 0 +0xEACF 0x5C09 # 0 +0xEAD0 0x6170 # 0 +0xEAD1 0x6690 # 0 +0xEAD2 0x6E2D # 0 +0xEAD3 0x7232 # 0 +0xEAD4 0x744B # 0 +0xEAD5 0x7DEF # 0 +0xEAD6 0x80C3 # 0 +0xEAD7 0x840E # 0 +0xEAD8 0x8466 # 0 +0xEAD9 0x853F # 0 +0xEADA 0x875F # 0 +0xEADB 0x885B # 0 +0xEADC 0x8918 # 0 +0xEADD 0x8B02 # 0 +0xEADE 0x9055 # 0 +0xEADF 0x97CB # 0 +0xEAE0 0x9B4F # 0 +0xEAE1 0x4E73 # 0 +0xEAE2 0x4F91 # 0 +0xEAE3 0x5112 # 0 +0xEAE4 0x516A # 0 +0xEAE5 0xF9C7 # 0 +0xEAE6 0x552F # 0 +0xEAE7 0x55A9 # 0 +0xEAE8 0x5B7A # 0 +0xEAE9 0x5BA5 # 0 +0xEAEA 0x5E7C # 0 +0xEAEB 0x5E7D # 0 +0xEAEC 0x5EBE # 0 +0xEAED 0x60A0 # 0 +0xEAEE 0x60DF # 0 +0xEAEF 0x6108 # 0 +0xEAF0 0x6109 # 0 +0xEAF1 0x63C4 # 0 +0xEAF2 0x6538 # 0 +0xEAF3 0x6709 # 0 +0xEAF4 0xF9C8 # 0 +0xEAF5 0x67D4 # 0 +0xEAF6 0x67DA # 0 +0xEAF7 0xF9C9 # 0 +0xEAF8 0x6961 # 0 +0xEAF9 0x6962 # 0 +0xEAFA 0x6CB9 # 0 +0xEAFB 0x6D27 # 0 +0xEAFC 0xF9CA # 0 +0xEAFD 0x6E38 # 0 +0xEAFE 0xF9CB # 0 +0xEBA1 0x6FE1 # 0 +0xEBA2 0x7336 # 0 +0xEBA3 0x7337 # 0 +0xEBA4 0xF9CC # 0 +0xEBA5 0x745C # 0 +0xEBA6 0x7531 # 0 +0xEBA7 0xF9CD # 0 +0xEBA8 0x7652 # 0 +0xEBA9 0xF9CE # 0 +0xEBAA 0xF9CF # 0 +0xEBAB 0x7DAD # 0 +0xEBAC 0x81FE # 0 +0xEBAD 0x8438 # 0 +0xEBAE 0x88D5 # 0 +0xEBAF 0x8A98 # 0 +0xEBB0 0x8ADB # 0 +0xEBB1 0x8AED # 0 +0xEBB2 0x8E30 # 0 +0xEBB3 0x8E42 # 0 +0xEBB4 0x904A # 0 +0xEBB5 0x903E # 0 +0xEBB6 0x907A # 0 +0xEBB7 0x9149 # 0 +0xEBB8 0x91C9 # 0 +0xEBB9 0x936E # 0 +0xEBBA 0xF9D0 # 0 +0xEBBB 0xF9D1 # 0 +0xEBBC 0x5809 # 0 +0xEBBD 0xF9D2 # 0 +0xEBBE 0x6BD3 # 0 +0xEBBF 0x8089 # 0 +0xEBC0 0x80B2 # 0 +0xEBC1 0xF9D3 # 0 +0xEBC2 0xF9D4 # 0 +0xEBC3 0x5141 # 0 +0xEBC4 0x596B # 0 +0xEBC5 0x5C39 # 0 +0xEBC6 0xF9D5 # 0 +0xEBC7 0xF9D6 # 0 +0xEBC8 0x6F64 # 0 +0xEBC9 0x73A7 # 0 +0xEBCA 0x80E4 # 0 +0xEBCB 0x8D07 # 0 +0xEBCC 0xF9D7 # 0 +0xEBCD 0x9217 # 0 +0xEBCE 0x958F # 0 +0xEBCF 0xF9D8 # 0 +0xEBD0 0xF9D9 # 0 +0xEBD1 0xF9DA # 0 +0xEBD2 0xF9DB # 0 +0xEBD3 0x807F # 0 +0xEBD4 0x620E # 0 +0xEBD5 0x701C # 0 +0xEBD6 0x7D68 # 0 +0xEBD7 0x878D # 0 +0xEBD8 0xF9DC # 0 +0xEBD9 0x57A0 # 0 +0xEBDA 0x6069 # 0 +0xEBDB 0x6147 # 0 +0xEBDC 0x6BB7 # 0 +0xEBDD 0x8ABE # 0 +0xEBDE 0x9280 # 0 +0xEBDF 0x96B1 # 0 +0xEBE0 0x4E59 # 0 +0xEBE1 0x541F # 0 +0xEBE2 0x6DEB # 0 +0xEBE3 0x852D # 0 +0xEBE4 0x9670 # 0 +0xEBE5 0x97F3 # 0 +0xEBE6 0x98EE # 0 +0xEBE7 0x63D6 # 0 +0xEBE8 0x6CE3 # 0 +0xEBE9 0x9091 # 0 +0xEBEA 0x51DD # 0 +0xEBEB 0x61C9 # 0 +0xEBEC 0x81BA # 0 +0xEBED 0x9DF9 # 0 +0xEBEE 0x4F9D # 0 +0xEBEF 0x501A # 0 +0xEBF0 0x5100 # 0 +0xEBF1 0x5B9C # 0 +0xEBF2 0x610F # 0 +0xEBF3 0x61FF # 0 +0xEBF4 0x64EC # 0 +0xEBF5 0x6905 # 0 +0xEBF6 0x6BC5 # 0 +0xEBF7 0x7591 # 0 +0xEBF8 0x77E3 # 0 +0xEBF9 0x7FA9 # 0 +0xEBFA 0x8264 # 0 +0xEBFB 0x858F # 0 +0xEBFC 0x87FB # 0 +0xEBFD 0x8863 # 0 +0xEBFE 0x8ABC # 0 +0xECA1 0x8B70 # 0 +0xECA2 0x91AB # 0 +0xECA3 0x4E8C # 0 +0xECA4 0x4EE5 # 0 +0xECA5 0x4F0A # 0 +0xECA6 0xF9DD # 0 +0xECA7 0xF9DE # 0 +0xECA8 0x5937 # 0 +0xECA9 0x59E8 # 0 +0xECAA 0xF9DF # 0 +0xECAB 0x5DF2 # 0 +0xECAC 0x5F1B # 0 +0xECAD 0x5F5B # 0 +0xECAE 0x6021 # 0 +0xECAF 0xF9E0 # 0 +0xECB0 0xF9E1 # 0 +0xECB1 0xF9E2 # 0 +0xECB2 0xF9E3 # 0 +0xECB3 0x723E # 0 +0xECB4 0x73E5 # 0 +0xECB5 0xF9E4 # 0 +0xECB6 0x7570 # 0 +0xECB7 0x75CD # 0 +0xECB8 0xF9E5 # 0 +0xECB9 0x79FB # 0 +0xECBA 0xF9E6 # 0 +0xECBB 0x800C # 0 +0xECBC 0x8033 # 0 +0xECBD 0x8084 # 0 +0xECBE 0x82E1 # 0 +0xECBF 0x8351 # 0 +0xECC0 0xF9E7 # 0 +0xECC1 0xF9E8 # 0 +0xECC2 0x8CBD # 0 +0xECC3 0x8CB3 # 0 +0xECC4 0x9087 # 0 +0xECC5 0xF9E9 # 0 +0xECC6 0xF9EA # 0 +0xECC7 0x98F4 # 0 +0xECC8 0x990C # 0 +0xECC9 0xF9EB # 0 +0xECCA 0xF9EC # 0 +0xECCB 0x7037 # 0 +0xECCC 0x76CA # 0 +0xECCD 0x7FCA # 0 +0xECCE 0x7FCC # 0 +0xECCF 0x7FFC # 0 +0xECD0 0x8B1A # 0 +0xECD1 0x4EBA # 0 +0xECD2 0x4EC1 # 0 +0xECD3 0x5203 # 0 +0xECD4 0x5370 # 0 +0xECD5 0xF9ED # 0 +0xECD6 0x54BD # 0 +0xECD7 0x56E0 # 0 +0xECD8 0x59FB # 0 +0xECD9 0x5BC5 # 0 +0xECDA 0x5F15 # 0 +0xECDB 0x5FCD # 0 +0xECDC 0x6E6E # 0 +0xECDD 0xF9EE # 0 +0xECDE 0xF9EF # 0 +0xECDF 0x7D6A # 0 +0xECE0 0x8335 # 0 +0xECE1 0xF9F0 # 0 +0xECE2 0x8693 # 0 +0xECE3 0x8A8D # 0 +0xECE4 0xF9F1 # 0 +0xECE5 0x976D # 0 +0xECE6 0x9777 # 0 +0xECE7 0xF9F2 # 0 +0xECE8 0xF9F3 # 0 +0xECE9 0x4E00 # 0 +0xECEA 0x4F5A # 0 +0xECEB 0x4F7E # 0 +0xECEC 0x58F9 # 0 +0xECED 0x65E5 # 0 +0xECEE 0x6EA2 # 0 +0xECEF 0x9038 # 0 +0xECF0 0x93B0 # 0 +0xECF1 0x99B9 # 0 +0xECF2 0x4EFB # 0 +0xECF3 0x58EC # 0 +0xECF4 0x598A # 0 +0xECF5 0x59D9 # 0 +0xECF6 0x6041 # 0 +0xECF7 0xF9F4 # 0 +0xECF8 0xF9F5 # 0 +0xECF9 0x7A14 # 0 +0xECFA 0xF9F6 # 0 +0xECFB 0x834F # 0 +0xECFC 0x8CC3 # 0 +0xECFD 0x5165 # 0 +0xECFE 0x5344 # 0 +0xEDA1 0xF9F7 # 0 +0xEDA2 0xF9F8 # 0 +0xEDA3 0xF9F9 # 0 +0xEDA4 0x4ECD # 0 +0xEDA5 0x5269 # 0 +0xEDA6 0x5B55 # 0 +0xEDA7 0x82BF # 0 +0xEDA8 0x4ED4 # 0 +0xEDA9 0x523A # 0 +0xEDAA 0x54A8 # 0 +0xEDAB 0x59C9 # 0 +0xEDAC 0x59FF # 0 +0xEDAD 0x5B50 # 0 +0xEDAE 0x5B57 # 0 +0xEDAF 0x5B5C # 0 +0xEDB0 0x6063 # 0 +0xEDB1 0x6148 # 0 +0xEDB2 0x6ECB # 0 +0xEDB3 0x7099 # 0 +0xEDB4 0x716E # 0 +0xEDB5 0x7386 # 0 +0xEDB6 0x74F7 # 0 +0xEDB7 0x75B5 # 0 +0xEDB8 0x78C1 # 0 +0xEDB9 0x7D2B # 0 +0xEDBA 0x8005 # 0 +0xEDBB 0x81EA # 0 +0xEDBC 0x8328 # 0 +0xEDBD 0x8517 # 0 +0xEDBE 0x85C9 # 0 +0xEDBF 0x8AEE # 0 +0xEDC0 0x8CC7 # 0 +0xEDC1 0x96CC # 0 +0xEDC2 0x4F5C # 0 +0xEDC3 0x52FA # 0 +0xEDC4 0x56BC # 0 +0xEDC5 0x65AB # 0 +0xEDC6 0x6628 # 0 +0xEDC7 0x707C # 0 +0xEDC8 0x70B8 # 0 +0xEDC9 0x7235 # 0 +0xEDCA 0x7DBD # 0 +0xEDCB 0x828D # 0 +0xEDCC 0x914C # 0 +0xEDCD 0x96C0 # 0 +0xEDCE 0x9D72 # 0 +0xEDCF 0x5B71 # 0 +0xEDD0 0x68E7 # 0 +0xEDD1 0x6B98 # 0 +0xEDD2 0x6F7A # 0 +0xEDD3 0x76DE # 0 +0xEDD4 0x5C91 # 0 +0xEDD5 0x66AB # 0 +0xEDD6 0x6F5B # 0 +0xEDD7 0x7BB4 # 0 +0xEDD8 0x7C2A # 0 +0xEDD9 0x8836 # 0 +0xEDDA 0x96DC # 0 +0xEDDB 0x4E08 # 0 +0xEDDC 0x4ED7 # 0 +0xEDDD 0x5320 # 0 +0xEDDE 0x5834 # 0 +0xEDDF 0x58BB # 0 +0xEDE0 0x58EF # 0 +0xEDE1 0x596C # 0 +0xEDE2 0x5C07 # 0 +0xEDE3 0x5E33 # 0 +0xEDE4 0x5E84 # 0 +0xEDE5 0x5F35 # 0 +0xEDE6 0x638C # 0 +0xEDE7 0x66B2 # 0 +0xEDE8 0x6756 # 0 +0xEDE9 0x6A1F # 0 +0xEDEA 0x6AA3 # 0 +0xEDEB 0x6B0C # 0 +0xEDEC 0x6F3F # 0 +0xEDED 0x7246 # 0 +0xEDEE 0xF9FA # 0 +0xEDEF 0x7350 # 0 +0xEDF0 0x748B # 0 +0xEDF1 0x7AE0 # 0 +0xEDF2 0x7CA7 # 0 +0xEDF3 0x8178 # 0 +0xEDF4 0x81DF # 0 +0xEDF5 0x81E7 # 0 +0xEDF6 0x838A # 0 +0xEDF7 0x846C # 0 +0xEDF8 0x8523 # 0 +0xEDF9 0x8594 # 0 +0xEDFA 0x85CF # 0 +0xEDFB 0x88DD # 0 +0xEDFC 0x8D13 # 0 +0xEDFD 0x91AC # 0 +0xEDFE 0x9577 # 0 +0xEEA1 0x969C # 0 +0xEEA2 0x518D # 0 +0xEEA3 0x54C9 # 0 +0xEEA4 0x5728 # 0 +0xEEA5 0x5BB0 # 0 +0xEEA6 0x624D # 0 +0xEEA7 0x6750 # 0 +0xEEA8 0x683D # 0 +0xEEA9 0x6893 # 0 +0xEEAA 0x6E3D # 0 +0xEEAB 0x6ED3 # 0 +0xEEAC 0x707D # 0 +0xEEAD 0x7E21 # 0 +0xEEAE 0x88C1 # 0 +0xEEAF 0x8CA1 # 0 +0xEEB0 0x8F09 # 0 +0xEEB1 0x9F4B # 0 +0xEEB2 0x9F4E # 0 +0xEEB3 0x722D # 0 +0xEEB4 0x7B8F # 0 +0xEEB5 0x8ACD # 0 +0xEEB6 0x931A # 0 +0xEEB7 0x4F47 # 0 +0xEEB8 0x4F4E # 0 +0xEEB9 0x5132 # 0 +0xEEBA 0x5480 # 0 +0xEEBB 0x59D0 # 0 +0xEEBC 0x5E95 # 0 +0xEEBD 0x62B5 # 0 +0xEEBE 0x6775 # 0 +0xEEBF 0x696E # 0 +0xEEC0 0x6A17 # 0 +0xEEC1 0x6CAE # 0 +0xEEC2 0x6E1A # 0 +0xEEC3 0x72D9 # 0 +0xEEC4 0x732A # 0 +0xEEC5 0x75BD # 0 +0xEEC6 0x7BB8 # 0 +0xEEC7 0x7D35 # 0 +0xEEC8 0x82E7 # 0 +0xEEC9 0x83F9 # 0 +0xEECA 0x8457 # 0 +0xEECB 0x85F7 # 0 +0xEECC 0x8A5B # 0 +0xEECD 0x8CAF # 0 +0xEECE 0x8E87 # 0 +0xEECF 0x9019 # 0 +0xEED0 0x90B8 # 0 +0xEED1 0x96CE # 0 +0xEED2 0x9F5F # 0 +0xEED3 0x52E3 # 0 +0xEED4 0x540A # 0 +0xEED5 0x5AE1 # 0 +0xEED6 0x5BC2 # 0 +0xEED7 0x6458 # 0 +0xEED8 0x6575 # 0 +0xEED9 0x6EF4 # 0 +0xEEDA 0x72C4 # 0 +0xEEDB 0xF9FB # 0 +0xEEDC 0x7684 # 0 +0xEEDD 0x7A4D # 0 +0xEEDE 0x7B1B # 0 +0xEEDF 0x7C4D # 0 +0xEEE0 0x7E3E # 0 +0xEEE1 0x7FDF # 0 +0xEEE2 0x837B # 0 +0xEEE3 0x8B2B # 0 +0xEEE4 0x8CCA # 0 +0xEEE5 0x8D64 # 0 +0xEEE6 0x8DE1 # 0 +0xEEE7 0x8E5F # 0 +0xEEE8 0x8FEA # 0 +0xEEE9 0x8FF9 # 0 +0xEEEA 0x9069 # 0 +0xEEEB 0x93D1 # 0 +0xEEEC 0x4F43 # 0 +0xEEED 0x4F7A # 0 +0xEEEE 0x50B3 # 0 +0xEEEF 0x5168 # 0 +0xEEF0 0x5178 # 0 +0xEEF1 0x524D # 0 +0xEEF2 0x526A # 0 +0xEEF3 0x5861 # 0 +0xEEF4 0x587C # 0 +0xEEF5 0x5960 # 0 +0xEEF6 0x5C08 # 0 +0xEEF7 0x5C55 # 0 +0xEEF8 0x5EDB # 0 +0xEEF9 0x609B # 0 +0xEEFA 0x6230 # 0 +0xEEFB 0x6813 # 0 +0xEEFC 0x6BBF # 0 +0xEEFD 0x6C08 # 0 +0xEEFE 0x6FB1 # 0 +0xEFA1 0x714E # 0 +0xEFA2 0x7420 # 0 +0xEFA3 0x7530 # 0 +0xEFA4 0x7538 # 0 +0xEFA5 0x7551 # 0 +0xEFA6 0x7672 # 0 +0xEFA7 0x7B4C # 0 +0xEFA8 0x7B8B # 0 +0xEFA9 0x7BAD # 0 +0xEFAA 0x7BC6 # 0 +0xEFAB 0x7E8F # 0 +0xEFAC 0x8A6E # 0 +0xEFAD 0x8F3E # 0 +0xEFAE 0x8F49 # 0 +0xEFAF 0x923F # 0 +0xEFB0 0x9293 # 0 +0xEFB1 0x9322 # 0 +0xEFB2 0x942B # 0 +0xEFB3 0x96FB # 0 +0xEFB4 0x985A # 0 +0xEFB5 0x986B # 0 +0xEFB6 0x991E # 0 +0xEFB7 0x5207 # 0 +0xEFB8 0x622A # 0 +0xEFB9 0x6298 # 0 +0xEFBA 0x6D59 # 0 +0xEFBB 0x7664 # 0 +0xEFBC 0x7ACA # 0 +0xEFBD 0x7BC0 # 0 +0xEFBE 0x7D76 # 0 +0xEFBF 0x5360 # 0 +0xEFC0 0x5CBE # 0 +0xEFC1 0x5E97 # 0 +0xEFC2 0x6F38 # 0 +0xEFC3 0x70B9 # 0 +0xEFC4 0x7C98 # 0 +0xEFC5 0x9711 # 0 +0xEFC6 0x9B8E # 0 +0xEFC7 0x9EDE # 0 +0xEFC8 0x63A5 # 0 +0xEFC9 0x647A # 0 +0xEFCA 0x8776 # 0 +0xEFCB 0x4E01 # 0 +0xEFCC 0x4E95 # 0 +0xEFCD 0x4EAD # 0 +0xEFCE 0x505C # 0 +0xEFCF 0x5075 # 0 +0xEFD0 0x5448 # 0 +0xEFD1 0x59C3 # 0 +0xEFD2 0x5B9A # 0 +0xEFD3 0x5E40 # 0 +0xEFD4 0x5EAD # 0 +0xEFD5 0x5EF7 # 0 +0xEFD6 0x5F81 # 0 +0xEFD7 0x60C5 # 0 +0xEFD8 0x633A # 0 +0xEFD9 0x653F # 0 +0xEFDA 0x6574 # 0 +0xEFDB 0x65CC # 0 +0xEFDC 0x6676 # 0 +0xEFDD 0x6678 # 0 +0xEFDE 0x67FE # 0 +0xEFDF 0x6968 # 0 +0xEFE0 0x6A89 # 0 +0xEFE1 0x6B63 # 0 +0xEFE2 0x6C40 # 0 +0xEFE3 0x6DC0 # 0 +0xEFE4 0x6DE8 # 0 +0xEFE5 0x6E1F # 0 +0xEFE6 0x6E5E # 0 +0xEFE7 0x701E # 0 +0xEFE8 0x70A1 # 0 +0xEFE9 0x738E # 0 +0xEFEA 0x73FD # 0 +0xEFEB 0x753A # 0 +0xEFEC 0x775B # 0 +0xEFED 0x7887 # 0 +0xEFEE 0x798E # 0 +0xEFEF 0x7A0B # 0 +0xEFF0 0x7A7D # 0 +0xEFF1 0x7CBE # 0 +0xEFF2 0x7D8E # 0 +0xEFF3 0x8247 # 0 +0xEFF4 0x8A02 # 0 +0xEFF5 0x8AEA # 0 +0xEFF6 0x8C9E # 0 +0xEFF7 0x912D # 0 +0xEFF8 0x914A # 0 +0xEFF9 0x91D8 # 0 +0xEFFA 0x9266 # 0 +0xEFFB 0x92CC # 0 +0xEFFC 0x9320 # 0 +0xEFFD 0x9706 # 0 +0xEFFE 0x9756 # 0 +0xF0A1 0x975C # 0 +0xF0A2 0x9802 # 0 +0xF0A3 0x9F0E # 0 +0xF0A4 0x5236 # 0 +0xF0A5 0x5291 # 0 +0xF0A6 0x557C # 0 +0xF0A7 0x5824 # 0 +0xF0A8 0x5E1D # 0 +0xF0A9 0x5F1F # 0 +0xF0AA 0x608C # 0 +0xF0AB 0x63D0 # 0 +0xF0AC 0x68AF # 0 +0xF0AD 0x6FDF # 0 +0xF0AE 0x796D # 0 +0xF0AF 0x7B2C # 0 +0xF0B0 0x81CD # 0 +0xF0B1 0x85BA # 0 +0xF0B2 0x88FD # 0 +0xF0B3 0x8AF8 # 0 +0xF0B4 0x8E44 # 0 +0xF0B5 0x918D # 0 +0xF0B6 0x9664 # 0 +0xF0B7 0x969B # 0 +0xF0B8 0x973D # 0 +0xF0B9 0x984C # 0 +0xF0BA 0x9F4A # 0 +0xF0BB 0x4FCE # 0 +0xF0BC 0x5146 # 0 +0xF0BD 0x51CB # 0 +0xF0BE 0x52A9 # 0 +0xF0BF 0x5632 # 0 +0xF0C0 0x5F14 # 0 +0xF0C1 0x5F6B # 0 +0xF0C2 0x63AA # 0 +0xF0C3 0x64CD # 0 +0xF0C4 0x65E9 # 0 +0xF0C5 0x6641 # 0 +0xF0C6 0x66FA # 0 +0xF0C7 0x66F9 # 0 +0xF0C8 0x671D # 0 +0xF0C9 0x689D # 0 +0xF0CA 0x68D7 # 0 +0xF0CB 0x69FD # 0 +0xF0CC 0x6F15 # 0 +0xF0CD 0x6F6E # 0 +0xF0CE 0x7167 # 0 +0xF0CF 0x71E5 # 0 +0xF0D0 0x722A # 0 +0xF0D1 0x74AA # 0 +0xF0D2 0x773A # 0 +0xF0D3 0x7956 # 0 +0xF0D4 0x795A # 0 +0xF0D5 0x79DF # 0 +0xF0D6 0x7A20 # 0 +0xF0D7 0x7A95 # 0 +0xF0D8 0x7C97 # 0 +0xF0D9 0x7CDF # 0 +0xF0DA 0x7D44 # 0 +0xF0DB 0x7E70 # 0 +0xF0DC 0x8087 # 0 +0xF0DD 0x85FB # 0 +0xF0DE 0x86A4 # 0 +0xF0DF 0x8A54 # 0 +0xF0E0 0x8ABF # 0 +0xF0E1 0x8D99 # 0 +0xF0E2 0x8E81 # 0 +0xF0E3 0x9020 # 0 +0xF0E4 0x906D # 0 +0xF0E5 0x91E3 # 0 +0xF0E6 0x963B # 0 +0xF0E7 0x96D5 # 0 +0xF0E8 0x9CE5 # 0 +0xF0E9 0x65CF # 0 +0xF0EA 0x7C07 # 0 +0xF0EB 0x8DB3 # 0 +0xF0EC 0x93C3 # 0 +0xF0ED 0x5B58 # 0 +0xF0EE 0x5C0A # 0 +0xF0EF 0x5352 # 0 +0xF0F0 0x62D9 # 0 +0xF0F1 0x731D # 0 +0xF0F2 0x5027 # 0 +0xF0F3 0x5B97 # 0 +0xF0F4 0x5F9E # 0 +0xF0F5 0x60B0 # 0 +0xF0F6 0x616B # 0 +0xF0F7 0x68D5 # 0 +0xF0F8 0x6DD9 # 0 +0xF0F9 0x742E # 0 +0xF0FA 0x7A2E # 0 +0xF0FB 0x7D42 # 0 +0xF0FC 0x7D9C # 0 +0xF0FD 0x7E31 # 0 +0xF0FE 0x816B # 0 +0xF1A1 0x8E2A # 0 +0xF1A2 0x8E35 # 0 +0xF1A3 0x937E # 0 +0xF1A4 0x9418 # 0 +0xF1A5 0x4F50 # 0 +0xF1A6 0x5750 # 0 +0xF1A7 0x5DE6 # 0 +0xF1A8 0x5EA7 # 0 +0xF1A9 0x632B # 0 +0xF1AA 0x7F6A # 0 +0xF1AB 0x4E3B # 0 +0xF1AC 0x4F4F # 0 +0xF1AD 0x4F8F # 0 +0xF1AE 0x505A # 0 +0xF1AF 0x59DD # 0 +0xF1B0 0x80C4 # 0 +0xF1B1 0x546A # 0 +0xF1B2 0x5468 # 0 +0xF1B3 0x55FE # 0 +0xF1B4 0x594F # 0 +0xF1B5 0x5B99 # 0 +0xF1B6 0x5DDE # 0 +0xF1B7 0x5EDA # 0 +0xF1B8 0x665D # 0 +0xF1B9 0x6731 # 0 +0xF1BA 0x67F1 # 0 +0xF1BB 0x682A # 0 +0xF1BC 0x6CE8 # 0 +0xF1BD 0x6D32 # 0 +0xF1BE 0x6E4A # 0 +0xF1BF 0x6F8D # 0 +0xF1C0 0x70B7 # 0 +0xF1C1 0x73E0 # 0 +0xF1C2 0x7587 # 0 +0xF1C3 0x7C4C # 0 +0xF1C4 0x7D02 # 0 +0xF1C5 0x7D2C # 0 +0xF1C6 0x7DA2 # 0 +0xF1C7 0x821F # 0 +0xF1C8 0x86DB # 0 +0xF1C9 0x8A3B # 0 +0xF1CA 0x8A85 # 0 +0xF1CB 0x8D70 # 0 +0xF1CC 0x8E8A # 0 +0xF1CD 0x8F33 # 0 +0xF1CE 0x9031 # 0 +0xF1CF 0x914E # 0 +0xF1D0 0x9152 # 0 +0xF1D1 0x9444 # 0 +0xF1D2 0x99D0 # 0 +0xF1D3 0x7AF9 # 0 +0xF1D4 0x7CA5 # 0 +0xF1D5 0x4FCA # 0 +0xF1D6 0x5101 # 0 +0xF1D7 0x51C6 # 0 +0xF1D8 0x57C8 # 0 +0xF1D9 0x5BEF # 0 +0xF1DA 0x5CFB # 0 +0xF1DB 0x6659 # 0 +0xF1DC 0x6A3D # 0 +0xF1DD 0x6D5A # 0 +0xF1DE 0x6E96 # 0 +0xF1DF 0x6FEC # 0 +0xF1E0 0x710C # 0 +0xF1E1 0x756F # 0 +0xF1E2 0x7AE3 # 0 +0xF1E3 0x8822 # 0 +0xF1E4 0x9021 # 0 +0xF1E5 0x9075 # 0 +0xF1E6 0x96CB # 0 +0xF1E7 0x99FF # 0 +0xF1E8 0x8301 # 0 +0xF1E9 0x4E2D # 0 +0xF1EA 0x4EF2 # 0 +0xF1EB 0x8846 # 0 +0xF1EC 0x91CD # 0 +0xF1ED 0x537D # 0 +0xF1EE 0x6ADB # 0 +0xF1EF 0x696B # 0 +0xF1F0 0x6C41 # 0 +0xF1F1 0x847A # 0 +0xF1F2 0x589E # 0 +0xF1F3 0x618E # 0 +0xF1F4 0x66FE # 0 +0xF1F5 0x62EF # 0 +0xF1F6 0x70DD # 0 +0xF1F7 0x7511 # 0 +0xF1F8 0x75C7 # 0 +0xF1F9 0x7E52 # 0 +0xF1FA 0x84B8 # 0 +0xF1FB 0x8B49 # 0 +0xF1FC 0x8D08 # 0 +0xF1FD 0x4E4B # 0 +0xF1FE 0x53EA # 0 +0xF2A1 0x54AB # 0 +0xF2A2 0x5730 # 0 +0xF2A3 0x5740 # 0 +0xF2A4 0x5FD7 # 0 +0xF2A5 0x6301 # 0 +0xF2A6 0x6307 # 0 +0xF2A7 0x646F # 0 +0xF2A8 0x652F # 0 +0xF2A9 0x65E8 # 0 +0xF2AA 0x667A # 0 +0xF2AB 0x679D # 0 +0xF2AC 0x67B3 # 0 +0xF2AD 0x6B62 # 0 +0xF2AE 0x6C60 # 0 +0xF2AF 0x6C9A # 0 +0xF2B0 0x6F2C # 0 +0xF2B1 0x77E5 # 0 +0xF2B2 0x7825 # 0 +0xF2B3 0x7949 # 0 +0xF2B4 0x7957 # 0 +0xF2B5 0x7D19 # 0 +0xF2B6 0x80A2 # 0 +0xF2B7 0x8102 # 0 +0xF2B8 0x81F3 # 0 +0xF2B9 0x829D # 0 +0xF2BA 0x82B7 # 0 +0xF2BB 0x8718 # 0 +0xF2BC 0x8A8C # 0 +0xF2BD 0xF9FC # 0 +0xF2BE 0x8D04 # 0 +0xF2BF 0x8DBE # 0 +0xF2C0 0x9072 # 0 +0xF2C1 0x76F4 # 0 +0xF2C2 0x7A19 # 0 +0xF2C3 0x7A37 # 0 +0xF2C4 0x7E54 # 0 +0xF2C5 0x8077 # 0 +0xF2C6 0x5507 # 0 +0xF2C7 0x55D4 # 0 +0xF2C8 0x5875 # 0 +0xF2C9 0x632F # 0 +0xF2CA 0x6422 # 0 +0xF2CB 0x6649 # 0 +0xF2CC 0x664B # 0 +0xF2CD 0x686D # 0 +0xF2CE 0x699B # 0 +0xF2CF 0x6B84 # 0 +0xF2D0 0x6D25 # 0 +0xF2D1 0x6EB1 # 0 +0xF2D2 0x73CD # 0 +0xF2D3 0x7468 # 0 +0xF2D4 0x74A1 # 0 +0xF2D5 0x755B # 0 +0xF2D6 0x75B9 # 0 +0xF2D7 0x76E1 # 0 +0xF2D8 0x771E # 0 +0xF2D9 0x778B # 0 +0xF2DA 0x79E6 # 0 +0xF2DB 0x7E09 # 0 +0xF2DC 0x7E1D # 0 +0xF2DD 0x81FB # 0 +0xF2DE 0x852F # 0 +0xF2DF 0x8897 # 0 +0xF2E0 0x8A3A # 0 +0xF2E1 0x8CD1 # 0 +0xF2E2 0x8EEB # 0 +0xF2E3 0x8FB0 # 0 +0xF2E4 0x9032 # 0 +0xF2E5 0x93AD # 0 +0xF2E6 0x9663 # 0 +0xF2E7 0x9673 # 0 +0xF2E8 0x9707 # 0 +0xF2E9 0x4F84 # 0 +0xF2EA 0x53F1 # 0 +0xF2EB 0x59EA # 0 +0xF2EC 0x5AC9 # 0 +0xF2ED 0x5E19 # 0 +0xF2EE 0x684E # 0 +0xF2EF 0x74C6 # 0 +0xF2F0 0x75BE # 0 +0xF2F1 0x79E9 # 0 +0xF2F2 0x7A92 # 0 +0xF2F3 0x81A3 # 0 +0xF2F4 0x86ED # 0 +0xF2F5 0x8CEA # 0 +0xF2F6 0x8DCC # 0 +0xF2F7 0x8FED # 0 +0xF2F8 0x659F # 0 +0xF2F9 0x6715 # 0 +0xF2FA 0xF9FD # 0 +0xF2FB 0x57F7 # 0 +0xF2FC 0x6F57 # 0 +0xF2FD 0x7DDD # 0 +0xF2FE 0x8F2F # 0 +0xF3A1 0x93F6 # 0 +0xF3A2 0x96C6 # 0 +0xF3A3 0x5FB5 # 0 +0xF3A4 0x61F2 # 0 +0xF3A5 0x6F84 # 0 +0xF3A6 0x4E14 # 0 +0xF3A7 0x4F98 # 0 +0xF3A8 0x501F # 0 +0xF3A9 0x53C9 # 0 +0xF3AA 0x55DF # 0 +0xF3AB 0x5D6F # 0 +0xF3AC 0x5DEE # 0 +0xF3AD 0x6B21 # 0 +0xF3AE 0x6B64 # 0 +0xF3AF 0x78CB # 0 +0xF3B0 0x7B9A # 0 +0xF3B1 0xF9FE # 0 +0xF3B2 0x8E49 # 0 +0xF3B3 0x8ECA # 0 +0xF3B4 0x906E # 0 +0xF3B5 0x6349 # 0 +0xF3B6 0x643E # 0 +0xF3B7 0x7740 # 0 +0xF3B8 0x7A84 # 0 +0xF3B9 0x932F # 0 +0xF3BA 0x947F # 0 +0xF3BB 0x9F6A # 0 +0xF3BC 0x64B0 # 0 +0xF3BD 0x6FAF # 0 +0xF3BE 0x71E6 # 0 +0xF3BF 0x74A8 # 0 +0xF3C0 0x74DA # 0 +0xF3C1 0x7AC4 # 0 +0xF3C2 0x7C12 # 0 +0xF3C3 0x7E82 # 0 +0xF3C4 0x7CB2 # 0 +0xF3C5 0x7E98 # 0 +0xF3C6 0x8B9A # 0 +0xF3C7 0x8D0A # 0 +0xF3C8 0x947D # 0 +0xF3C9 0x9910 # 0 +0xF3CA 0x994C # 0 +0xF3CB 0x5239 # 0 +0xF3CC 0x5BDF # 0 +0xF3CD 0x64E6 # 0 +0xF3CE 0x672D # 0 +0xF3CF 0x7D2E # 0 +0xF3D0 0x50ED # 0 +0xF3D1 0x53C3 # 0 +0xF3D2 0x5879 # 0 +0xF3D3 0x6158 # 0 +0xF3D4 0x6159 # 0 +0xF3D5 0x61FA # 0 +0xF3D6 0x65AC # 0 +0xF3D7 0x7AD9 # 0 +0xF3D8 0x8B92 # 0 +0xF3D9 0x8B96 # 0 +0xF3DA 0x5009 # 0 +0xF3DB 0x5021 # 0 +0xF3DC 0x5275 # 0 +0xF3DD 0x5531 # 0 +0xF3DE 0x5A3C # 0 +0xF3DF 0x5EE0 # 0 +0xF3E0 0x5F70 # 0 +0xF3E1 0x6134 # 0 +0xF3E2 0x655E # 0 +0xF3E3 0x660C # 0 +0xF3E4 0x6636 # 0 +0xF3E5 0x66A2 # 0 +0xF3E6 0x69CD # 0 +0xF3E7 0x6EC4 # 0 +0xF3E8 0x6F32 # 0 +0xF3E9 0x7316 # 0 +0xF3EA 0x7621 # 0 +0xF3EB 0x7A93 # 0 +0xF3EC 0x8139 # 0 +0xF3ED 0x8259 # 0 +0xF3EE 0x83D6 # 0 +0xF3EF 0x84BC # 0 +0xF3F0 0x50B5 # 0 +0xF3F1 0x57F0 # 0 +0xF3F2 0x5BC0 # 0 +0xF3F3 0x5BE8 # 0 +0xF3F4 0x5F69 # 0 +0xF3F5 0x63A1 # 0 +0xF3F6 0x7826 # 0 +0xF3F7 0x7DB5 # 0 +0xF3F8 0x83DC # 0 +0xF3F9 0x8521 # 0 +0xF3FA 0x91C7 # 0 +0xF3FB 0x91F5 # 0 +0xF3FC 0x518A # 0 +0xF3FD 0x67F5 # 0 +0xF3FE 0x7B56 # 0 +0xF4A1 0x8CAC # 0 +0xF4A2 0x51C4 # 0 +0xF4A3 0x59BB # 0 +0xF4A4 0x60BD # 0 +0xF4A5 0x8655 # 0 +0xF4A6 0x501C # 0 +0xF4A7 0xF9FF # 0 +0xF4A8 0x5254 # 0 +0xF4A9 0x5C3A # 0 +0xF4AA 0x617D # 0 +0xF4AB 0x621A # 0 +0xF4AC 0x62D3 # 0 +0xF4AD 0x64F2 # 0 +0xF4AE 0x65A5 # 0 +0xF4AF 0x6ECC # 0 +0xF4B0 0x7620 # 0 +0xF4B1 0x810A # 0 +0xF4B2 0x8E60 # 0 +0xF4B3 0x965F # 0 +0xF4B4 0x96BB # 0 +0xF4B5 0x4EDF # 0 +0xF4B6 0x5343 # 0 +0xF4B7 0x5598 # 0 +0xF4B8 0x5929 # 0 +0xF4B9 0x5DDD # 0 +0xF4BA 0x64C5 # 0 +0xF4BB 0x6CC9 # 0 +0xF4BC 0x6DFA # 0 +0xF4BD 0x7394 # 0 +0xF4BE 0x7A7F # 0 +0xF4BF 0x821B # 0 +0xF4C0 0x85A6 # 0 +0xF4C1 0x8CE4 # 0 +0xF4C2 0x8E10 # 0 +0xF4C3 0x9077 # 0 +0xF4C4 0x91E7 # 0 +0xF4C5 0x95E1 # 0 +0xF4C6 0x9621 # 0 +0xF4C7 0x97C6 # 0 +0xF4C8 0x51F8 # 0 +0xF4C9 0x54F2 # 0 +0xF4CA 0x5586 # 0 +0xF4CB 0x5FB9 # 0 +0xF4CC 0x64A4 # 0 +0xF4CD 0x6F88 # 0 +0xF4CE 0x7DB4 # 0 +0xF4CF 0x8F1F # 0 +0xF4D0 0x8F4D # 0 +0xF4D1 0x9435 # 0 +0xF4D2 0x50C9 # 0 +0xF4D3 0x5C16 # 0 +0xF4D4 0x6CBE # 0 +0xF4D5 0x6DFB # 0 +0xF4D6 0x751B # 0 +0xF4D7 0x77BB # 0 +0xF4D8 0x7C3D # 0 +0xF4D9 0x7C64 # 0 +0xF4DA 0x8A79 # 0 +0xF4DB 0x8AC2 # 0 +0xF4DC 0x581E # 0 +0xF4DD 0x59BE # 0 +0xF4DE 0x5E16 # 0 +0xF4DF 0x6377 # 0 +0xF4E0 0x7252 # 0 +0xF4E1 0x758A # 0 +0xF4E2 0x776B # 0 +0xF4E3 0x8ADC # 0 +0xF4E4 0x8CBC # 0 +0xF4E5 0x8F12 # 0 +0xF4E6 0x5EF3 # 0 +0xF4E7 0x6674 # 0 +0xF4E8 0x6DF8 # 0 +0xF4E9 0x807D # 0 +0xF4EA 0x83C1 # 0 +0xF4EB 0x8ACB # 0 +0xF4EC 0x9751 # 0 +0xF4ED 0x9BD6 # 0 +0xF4EE 0xFA00 # 0 +0xF4EF 0x5243 # 0 +0xF4F0 0x66FF # 0 +0xF4F1 0x6D95 # 0 +0xF4F2 0x6EEF # 0 +0xF4F3 0x7DE0 # 0 +0xF4F4 0x8AE6 # 0 +0xF4F5 0x902E # 0 +0xF4F6 0x905E # 0 +0xF4F7 0x9AD4 # 0 +0xF4F8 0x521D # 0 +0xF4F9 0x527F # 0 +0xF4FA 0x54E8 # 0 +0xF4FB 0x6194 # 0 +0xF4FC 0x6284 # 0 +0xF4FD 0x62DB # 0 +0xF4FE 0x68A2 # 0 +0xF5A1 0x6912 # 0 +0xF5A2 0x695A # 0 +0xF5A3 0x6A35 # 0 +0xF5A4 0x7092 # 0 +0xF5A5 0x7126 # 0 +0xF5A6 0x785D # 0 +0xF5A7 0x7901 # 0 +0xF5A8 0x790E # 0 +0xF5A9 0x79D2 # 0 +0xF5AA 0x7A0D # 0 +0xF5AB 0x8096 # 0 +0xF5AC 0x8278 # 0 +0xF5AD 0x82D5 # 0 +0xF5AE 0x8349 # 0 +0xF5AF 0x8549 # 0 +0xF5B0 0x8C82 # 0 +0xF5B1 0x8D85 # 0 +0xF5B2 0x9162 # 0 +0xF5B3 0x918B # 0 +0xF5B4 0x91AE # 0 +0xF5B5 0x4FC3 # 0 +0xF5B6 0x56D1 # 0 +0xF5B7 0x71ED # 0 +0xF5B8 0x77D7 # 0 +0xF5B9 0x8700 # 0 +0xF5BA 0x89F8 # 0 +0xF5BB 0x5BF8 # 0 +0xF5BC 0x5FD6 # 0 +0xF5BD 0x6751 # 0 +0xF5BE 0x90A8 # 0 +0xF5BF 0x53E2 # 0 +0xF5C0 0x585A # 0 +0xF5C1 0x5BF5 # 0 +0xF5C2 0x60A4 # 0 +0xF5C3 0x6181 # 0 +0xF5C4 0x6460 # 0 +0xF5C5 0x7E3D # 0 +0xF5C6 0x8070 # 0 +0xF5C7 0x8525 # 0 +0xF5C8 0x9283 # 0 +0xF5C9 0x64AE # 0 +0xF5CA 0x50AC # 0 +0xF5CB 0x5D14 # 0 +0xF5CC 0x6700 # 0 +0xF5CD 0x589C # 0 +0xF5CE 0x62BD # 0 +0xF5CF 0x63A8 # 0 +0xF5D0 0x690E # 0 +0xF5D1 0x6978 # 0 +0xF5D2 0x6A1E # 0 +0xF5D3 0x6E6B # 0 +0xF5D4 0x76BA # 0 +0xF5D5 0x79CB # 0 +0xF5D6 0x82BB # 0 +0xF5D7 0x8429 # 0 +0xF5D8 0x8ACF # 0 +0xF5D9 0x8DA8 # 0 +0xF5DA 0x8FFD # 0 +0xF5DB 0x9112 # 0 +0xF5DC 0x914B # 0 +0xF5DD 0x919C # 0 +0xF5DE 0x9310 # 0 +0xF5DF 0x9318 # 0 +0xF5E0 0x939A # 0 +0xF5E1 0x96DB # 0 +0xF5E2 0x9A36 # 0 +0xF5E3 0x9C0D # 0 +0xF5E4 0x4E11 # 0 +0xF5E5 0x755C # 0 +0xF5E6 0x795D # 0 +0xF5E7 0x7AFA # 0 +0xF5E8 0x7B51 # 0 +0xF5E9 0x7BC9 # 0 +0xF5EA 0x7E2E # 0 +0xF5EB 0x84C4 # 0 +0xF5EC 0x8E59 # 0 +0xF5ED 0x8E74 # 0 +0xF5EE 0x8EF8 # 0 +0xF5EF 0x9010 # 0 +0xF5F0 0x6625 # 0 +0xF5F1 0x693F # 0 +0xF5F2 0x7443 # 0 +0xF5F3 0x51FA # 0 +0xF5F4 0x672E # 0 +0xF5F5 0x9EDC # 0 +0xF5F6 0x5145 # 0 +0xF5F7 0x5FE0 # 0 +0xF5F8 0x6C96 # 0 +0xF5F9 0x87F2 # 0 +0xF5FA 0x885D # 0 +0xF5FB 0x8877 # 0 +0xF5FC 0x60B4 # 0 +0xF5FD 0x81B5 # 0 +0xF5FE 0x8403 # 0 +0xF6A1 0x8D05 # 0 +0xF6A2 0x53D6 # 0 +0xF6A3 0x5439 # 0 +0xF6A4 0x5634 # 0 +0xF6A5 0x5A36 # 0 +0xF6A6 0x5C31 # 0 +0xF6A7 0x708A # 0 +0xF6A8 0x7FE0 # 0 +0xF6A9 0x805A # 0 +0xF6AA 0x8106 # 0 +0xF6AB 0x81ED # 0 +0xF6AC 0x8DA3 # 0 +0xF6AD 0x9189 # 0 +0xF6AE 0x9A5F # 0 +0xF6AF 0x9DF2 # 0 +0xF6B0 0x5074 # 0 +0xF6B1 0x4EC4 # 0 +0xF6B2 0x53A0 # 0 +0xF6B3 0x60FB # 0 +0xF6B4 0x6E2C # 0 +0xF6B5 0x5C64 # 0 +0xF6B6 0x4F88 # 0 +0xF6B7 0x5024 # 0 +0xF6B8 0x55E4 # 0 +0xF6B9 0x5CD9 # 0 +0xF6BA 0x5E5F # 0 +0xF6BB 0x6065 # 0 +0xF6BC 0x6894 # 0 +0xF6BD 0x6CBB # 0 +0xF6BE 0x6DC4 # 0 +0xF6BF 0x71BE # 0 +0xF6C0 0x75D4 # 0 +0xF6C1 0x75F4 # 0 +0xF6C2 0x7661 # 0 +0xF6C3 0x7A1A # 0 +0xF6C4 0x7A49 # 0 +0xF6C5 0x7DC7 # 0 +0xF6C6 0x7DFB # 0 +0xF6C7 0x7F6E # 0 +0xF6C8 0x81F4 # 0 +0xF6C9 0x86A9 # 0 +0xF6CA 0x8F1C # 0 +0xF6CB 0x96C9 # 0 +0xF6CC 0x99B3 # 0 +0xF6CD 0x9F52 # 0 +0xF6CE 0x5247 # 0 +0xF6CF 0x52C5 # 0 +0xF6D0 0x98ED # 0 +0xF6D1 0x89AA # 0 +0xF6D2 0x4E03 # 0 +0xF6D3 0x67D2 # 0 +0xF6D4 0x6F06 # 0 +0xF6D5 0x4FB5 # 0 +0xF6D6 0x5BE2 # 0 +0xF6D7 0x6795 # 0 +0xF6D8 0x6C88 # 0 +0xF6D9 0x6D78 # 0 +0xF6DA 0x741B # 0 +0xF6DB 0x7827 # 0 +0xF6DC 0x91DD # 0 +0xF6DD 0x937C # 0 +0xF6DE 0x87C4 # 0 +0xF6DF 0x79E4 # 0 +0xF6E0 0x7A31 # 0 +0xF6E1 0x5FEB # 0 +0xF6E2 0x4ED6 # 0 +0xF6E3 0x54A4 # 0 +0xF6E4 0x553E # 0 +0xF6E5 0x58AE # 0 +0xF6E6 0x59A5 # 0 +0xF6E7 0x60F0 # 0 +0xF6E8 0x6253 # 0 +0xF6E9 0x62D6 # 0 +0xF6EA 0x6736 # 0 +0xF6EB 0x6955 # 0 +0xF6EC 0x8235 # 0 +0xF6ED 0x9640 # 0 +0xF6EE 0x99B1 # 0 +0xF6EF 0x99DD # 0 +0xF6F0 0x502C # 0 +0xF6F1 0x5353 # 0 +0xF6F2 0x5544 # 0 +0xF6F3 0x577C # 0 +0xF6F4 0xFA01 # 0 +0xF6F5 0x6258 # 0 +0xF6F6 0xFA02 # 0 +0xF6F7 0x64E2 # 0 +0xF6F8 0x666B # 0 +0xF6F9 0x67DD # 0 +0xF6FA 0x6FC1 # 0 +0xF6FB 0x6FEF # 0 +0xF6FC 0x7422 # 0 +0xF6FD 0x7438 # 0 +0xF6FE 0x8A17 # 0 +0xF7A1 0x9438 # 0 +0xF7A2 0x5451 # 0 +0xF7A3 0x5606 # 0 +0xF7A4 0x5766 # 0 +0xF7A5 0x5F48 # 0 +0xF7A6 0x619A # 0 +0xF7A7 0x6B4E # 0 +0xF7A8 0x7058 # 0 +0xF7A9 0x70AD # 0 +0xF7AA 0x7DBB # 0 +0xF7AB 0x8A95 # 0 +0xF7AC 0x596A # 0 +0xF7AD 0x812B # 0 +0xF7AE 0x63A2 # 0 +0xF7AF 0x7708 # 0 +0xF7B0 0x803D # 0 +0xF7B1 0x8CAA # 0 +0xF7B2 0x5854 # 0 +0xF7B3 0x642D # 0 +0xF7B4 0x69BB # 0 +0xF7B5 0x5B95 # 0 +0xF7B6 0x5E11 # 0 +0xF7B7 0x6E6F # 0 +0xF7B8 0xFA03 # 0 +0xF7B9 0x8569 # 0 +0xF7BA 0x514C # 0 +0xF7BB 0x53F0 # 0 +0xF7BC 0x592A # 0 +0xF7BD 0x6020 # 0 +0xF7BE 0x614B # 0 +0xF7BF 0x6B86 # 0 +0xF7C0 0x6C70 # 0 +0xF7C1 0x6CF0 # 0 +0xF7C2 0x7B1E # 0 +0xF7C3 0x80CE # 0 +0xF7C4 0x82D4 # 0 +0xF7C5 0x8DC6 # 0 +0xF7C6 0x90B0 # 0 +0xF7C7 0x98B1 # 0 +0xF7C8 0xFA04 # 0 +0xF7C9 0x64C7 # 0 +0xF7CA 0x6FA4 # 0 +0xF7CB 0x6491 # 0 +0xF7CC 0x6504 # 0 +0xF7CD 0x514E # 0 +0xF7CE 0x5410 # 0 +0xF7CF 0x571F # 0 +0xF7D0 0x8A0E # 0 +0xF7D1 0x615F # 0 +0xF7D2 0x6876 # 0 +0xF7D3 0xFA05 # 0 +0xF7D4 0x75DB # 0 +0xF7D5 0x7B52 # 0 +0xF7D6 0x7D71 # 0 +0xF7D7 0x901A # 0 +0xF7D8 0x5806 # 0 +0xF7D9 0x69CC # 0 +0xF7DA 0x817F # 0 +0xF7DB 0x892A # 0 +0xF7DC 0x9000 # 0 +0xF7DD 0x9839 # 0 +0xF7DE 0x5078 # 0 +0xF7DF 0x5957 # 0 +0xF7E0 0x59AC # 0 +0xF7E1 0x6295 # 0 +0xF7E2 0x900F # 0 +0xF7E3 0x9B2A # 0 +0xF7E4 0x615D # 0 +0xF7E5 0x7279 # 0 +0xF7E6 0x95D6 # 0 +0xF7E7 0x5761 # 0 +0xF7E8 0x5A46 # 0 +0xF7E9 0x5DF4 # 0 +0xF7EA 0x628A # 0 +0xF7EB 0x64AD # 0 +0xF7EC 0x64FA # 0 +0xF7ED 0x6777 # 0 +0xF7EE 0x6CE2 # 0 +0xF7EF 0x6D3E # 0 +0xF7F0 0x722C # 0 +0xF7F1 0x7436 # 0 +0xF7F2 0x7834 # 0 +0xF7F3 0x7F77 # 0 +0xF7F4 0x82AD # 0 +0xF7F5 0x8DDB # 0 +0xF7F6 0x9817 # 0 +0xF7F7 0x5224 # 0 +0xF7F8 0x5742 # 0 +0xF7F9 0x677F # 0 +0xF7FA 0x7248 # 0 +0xF7FB 0x74E3 # 0 +0xF7FC 0x8CA9 # 0 +0xF7FD 0x8FA6 # 0 +0xF7FE 0x9211 # 0 +0xF8A1 0x962A # 0 +0xF8A2 0x516B # 0 +0xF8A3 0x53ED # 0 +0xF8A4 0x634C # 0 +0xF8A5 0x4F69 # 0 +0xF8A6 0x5504 # 0 +0xF8A7 0x6096 # 0 +0xF8A8 0x6557 # 0 +0xF8A9 0x6C9B # 0 +0xF8AA 0x6D7F # 0 +0xF8AB 0x724C # 0 +0xF8AC 0x72FD # 0 +0xF8AD 0x7A17 # 0 +0xF8AE 0x8987 # 0 +0xF8AF 0x8C9D # 0 +0xF8B0 0x5F6D # 0 +0xF8B1 0x6F8E # 0 +0xF8B2 0x70F9 # 0 +0xF8B3 0x81A8 # 0 +0xF8B4 0x610E # 0 +0xF8B5 0x4FBF # 0 +0xF8B6 0x504F # 0 +0xF8B7 0x6241 # 0 +0xF8B8 0x7247 # 0 +0xF8B9 0x7BC7 # 0 +0xF8BA 0x7DE8 # 0 +0xF8BB 0x7FE9 # 0 +0xF8BC 0x904D # 0 +0xF8BD 0x97AD # 0 +0xF8BE 0x9A19 # 0 +0xF8BF 0x8CB6 # 0 +0xF8C0 0x576A # 0 +0xF8C1 0x5E73 # 0 +0xF8C2 0x67B0 # 0 +0xF8C3 0x840D # 0 +0xF8C4 0x8A55 # 0 +0xF8C5 0x5420 # 0 +0xF8C6 0x5B16 # 0 +0xF8C7 0x5E63 # 0 +0xF8C8 0x5EE2 # 0 +0xF8C9 0x5F0A # 0 +0xF8CA 0x6583 # 0 +0xF8CB 0x80BA # 0 +0xF8CC 0x853D # 0 +0xF8CD 0x9589 # 0 +0xF8CE 0x965B # 0 +0xF8CF 0x4F48 # 0 +0xF8D0 0x5305 # 0 +0xF8D1 0x530D # 0 +0xF8D2 0x530F # 0 +0xF8D3 0x5486 # 0 +0xF8D4 0x54FA # 0 +0xF8D5 0x5703 # 0 +0xF8D6 0x5E03 # 0 +0xF8D7 0x6016 # 0 +0xF8D8 0x629B # 0 +0xF8D9 0x62B1 # 0 +0xF8DA 0x6355 # 0 +0xF8DB 0xFA06 # 0 +0xF8DC 0x6CE1 # 0 +0xF8DD 0x6D66 # 0 +0xF8DE 0x75B1 # 0 +0xF8DF 0x7832 # 0 +0xF8E0 0x80DE # 0 +0xF8E1 0x812F # 0 +0xF8E2 0x82DE # 0 +0xF8E3 0x8461 # 0 +0xF8E4 0x84B2 # 0 +0xF8E5 0x888D # 0 +0xF8E6 0x8912 # 0 +0xF8E7 0x900B # 0 +0xF8E8 0x92EA # 0 +0xF8E9 0x98FD # 0 +0xF8EA 0x9B91 # 0 +0xF8EB 0x5E45 # 0 +0xF8EC 0x66B4 # 0 +0xF8ED 0x66DD # 0 +0xF8EE 0x7011 # 0 +0xF8EF 0x7206 # 0 +0xF8F0 0xFA07 # 0 +0xF8F1 0x4FF5 # 0 +0xF8F2 0x527D # 0 +0xF8F3 0x5F6A # 0 +0xF8F4 0x6153 # 0 +0xF8F5 0x6753 # 0 +0xF8F6 0x6A19 # 0 +0xF8F7 0x6F02 # 0 +0xF8F8 0x74E2 # 0 +0xF8F9 0x7968 # 0 +0xF8FA 0x8868 # 0 +0xF8FB 0x8C79 # 0 +0xF8FC 0x98C7 # 0 +0xF8FD 0x98C4 # 0 +0xF8FE 0x9A43 # 0 +0xF9A1 0x54C1 # 0 +0xF9A2 0x7A1F # 0 +0xF9A3 0x6953 # 0 +0xF9A4 0x8AF7 # 0 +0xF9A5 0x8C4A # 0 +0xF9A6 0x98A8 # 0 +0xF9A7 0x99AE # 0 +0xF9A8 0x5F7C # 0 +0xF9A9 0x62AB # 0 +0xF9AA 0x75B2 # 0 +0xF9AB 0x76AE # 0 +0xF9AC 0x88AB # 0 +0xF9AD 0x907F # 0 +0xF9AE 0x9642 # 0 +0xF9AF 0x5339 # 0 +0xF9B0 0x5F3C # 0 +0xF9B1 0x5FC5 # 0 +0xF9B2 0x6CCC # 0 +0xF9B3 0x73CC # 0 +0xF9B4 0x7562 # 0 +0xF9B5 0x758B # 0 +0xF9B6 0x7B46 # 0 +0xF9B7 0x82FE # 0 +0xF9B8 0x999D # 0 +0xF9B9 0x4E4F # 0 +0xF9BA 0x903C # 0 +0xF9BB 0x4E0B # 0 +0xF9BC 0x4F55 # 0 +0xF9BD 0x53A6 # 0 +0xF9BE 0x590F # 0 +0xF9BF 0x5EC8 # 0 +0xF9C0 0x6630 # 0 +0xF9C1 0x6CB3 # 0 +0xF9C2 0x7455 # 0 +0xF9C3 0x8377 # 0 +0xF9C4 0x8766 # 0 +0xF9C5 0x8CC0 # 0 +0xF9C6 0x9050 # 0 +0xF9C7 0x971E # 0 +0xF9C8 0x9C15 # 0 +0xF9C9 0x58D1 # 0 +0xF9CA 0x5B78 # 0 +0xF9CB 0x8650 # 0 +0xF9CC 0x8B14 # 0 +0xF9CD 0x9DB4 # 0 +0xF9CE 0x5BD2 # 0 +0xF9CF 0x6068 # 0 +0xF9D0 0x608D # 0 +0xF9D1 0x65F1 # 0 +0xF9D2 0x6C57 # 0 +0xF9D3 0x6F22 # 0 +0xF9D4 0x6FA3 # 0 +0xF9D5 0x701A # 0 +0xF9D6 0x7F55 # 0 +0xF9D7 0x7FF0 # 0 +0xF9D8 0x9591 # 0 +0xF9D9 0x9592 # 0 +0xF9DA 0x9650 # 0 +0xF9DB 0x97D3 # 0 +0xF9DC 0x5272 # 0 +0xF9DD 0x8F44 # 0 +0xF9DE 0x51FD # 0 +0xF9DF 0x542B # 0 +0xF9E0 0x54B8 # 0 +0xF9E1 0x5563 # 0 +0xF9E2 0x558A # 0 +0xF9E3 0x6ABB # 0 +0xF9E4 0x6DB5 # 0 +0xF9E5 0x7DD8 # 0 +0xF9E6 0x8266 # 0 +0xF9E7 0x929C # 0 +0xF9E8 0x9677 # 0 +0xF9E9 0x9E79 # 0 +0xF9EA 0x5408 # 0 +0xF9EB 0x54C8 # 0 +0xF9EC 0x76D2 # 0 +0xF9ED 0x86E4 # 0 +0xF9EE 0x95A4 # 0 +0xF9EF 0x95D4 # 0 +0xF9F0 0x965C # 0 +0xF9F1 0x4EA2 # 0 +0xF9F2 0x4F09 # 0 +0xF9F3 0x59EE # 0 +0xF9F4 0x5AE6 # 0 +0xF9F5 0x5DF7 # 0 +0xF9F6 0x6052 # 0 +0xF9F7 0x6297 # 0 +0xF9F8 0x676D # 0 +0xF9F9 0x6841 # 0 +0xF9FA 0x6C86 # 0 +0xF9FB 0x6E2F # 0 +0xF9FC 0x7F38 # 0 +0xF9FD 0x809B # 0 +0xF9FE 0x822A # 0 +0xFAA1 0xFA08 # 0 +0xFAA2 0xFA09 # 0 +0xFAA3 0x9805 # 0 +0xFAA4 0x4EA5 # 0 +0xFAA5 0x5055 # 0 +0xFAA6 0x54B3 # 0 +0xFAA7 0x5793 # 0 +0xFAA8 0x595A # 0 +0xFAA9 0x5B69 # 0 +0xFAAA 0x5BB3 # 0 +0xFAAB 0x61C8 # 0 +0xFAAC 0x6977 # 0 +0xFAAD 0x6D77 # 0 +0xFAAE 0x7023 # 0 +0xFAAF 0x87F9 # 0 +0xFAB0 0x89E3 # 0 +0xFAB1 0x8A72 # 0 +0xFAB2 0x8AE7 # 0 +0xFAB3 0x9082 # 0 +0xFAB4 0x99ED # 0 +0xFAB5 0x9AB8 # 0 +0xFAB6 0x52BE # 0 +0xFAB7 0x6838 # 0 +0xFAB8 0x5016 # 0 +0xFAB9 0x5E78 # 0 +0xFABA 0x674F # 0 +0xFABB 0x8347 # 0 +0xFABC 0x884C # 0 +0xFABD 0x4EAB # 0 +0xFABE 0x5411 # 0 +0xFABF 0x56AE # 0 +0xFAC0 0x73E6 # 0 +0xFAC1 0x9115 # 0 +0xFAC2 0x97FF # 0 +0xFAC3 0x9909 # 0 +0xFAC4 0x9957 # 0 +0xFAC5 0x9999 # 0 +0xFAC6 0x5653 # 0 +0xFAC7 0x589F # 0 +0xFAC8 0x865B # 0 +0xFAC9 0x8A31 # 0 +0xFACA 0x61B2 # 0 +0xFACB 0x6AF6 # 0 +0xFACC 0x737B # 0 +0xFACD 0x8ED2 # 0 +0xFACE 0x6B47 # 0 +0xFACF 0x96AA # 0 +0xFAD0 0x9A57 # 0 +0xFAD1 0x5955 # 0 +0xFAD2 0x7200 # 0 +0xFAD3 0x8D6B # 0 +0xFAD4 0x9769 # 0 +0xFAD5 0x4FD4 # 0 +0xFAD6 0x5CF4 # 0 +0xFAD7 0x5F26 # 0 +0xFAD8 0x61F8 # 0 +0xFAD9 0x665B # 0 +0xFADA 0x6CEB # 0 +0xFADB 0x70AB # 0 +0xFADC 0x7384 # 0 +0xFADD 0x73B9 # 0 +0xFADE 0x73FE # 0 +0xFADF 0x7729 # 0 +0xFAE0 0x774D # 0 +0xFAE1 0x7D43 # 0 +0xFAE2 0x7D62 # 0 +0xFAE3 0x7E23 # 0 +0xFAE4 0x8237 # 0 +0xFAE5 0x8852 # 0 +0xFAE6 0xFA0A # 0 +0xFAE7 0x8CE2 # 0 +0xFAE8 0x9249 # 0 +0xFAE9 0x986F # 0 +0xFAEA 0x5B51 # 0 +0xFAEB 0x7A74 # 0 +0xFAEC 0x8840 # 0 +0xFAED 0x9801 # 0 +0xFAEE 0x5ACC # 0 +0xFAEF 0x4FE0 # 0 +0xFAF0 0x5354 # 0 +0xFAF1 0x593E # 0 +0xFAF2 0x5CFD # 0 +0xFAF3 0x633E # 0 +0xFAF4 0x6D79 # 0 +0xFAF5 0x72F9 # 0 +0xFAF6 0x8105 # 0 +0xFAF7 0x8107 # 0 +0xFAF8 0x83A2 # 0 +0xFAF9 0x92CF # 0 +0xFAFA 0x9830 # 0 +0xFAFB 0x4EA8 # 0 +0xFAFC 0x5144 # 0 +0xFAFD 0x5211 # 0 +0xFAFE 0x578B # 0 +0xFBA1 0x5F62 # 0 +0xFBA2 0x6CC2 # 0 +0xFBA3 0x6ECE # 0 +0xFBA4 0x7005 # 0 +0xFBA5 0x7050 # 0 +0xFBA6 0x70AF # 0 +0xFBA7 0x7192 # 0 +0xFBA8 0x73E9 # 0 +0xFBA9 0x7469 # 0 +0xFBAA 0x834A # 0 +0xFBAB 0x87A2 # 0 +0xFBAC 0x8861 # 0 +0xFBAD 0x9008 # 0 +0xFBAE 0x90A2 # 0 +0xFBAF 0x93A3 # 0 +0xFBB0 0x99A8 # 0 +0xFBB1 0x516E # 0 +0xFBB2 0x5F57 # 0 +0xFBB3 0x60E0 # 0 +0xFBB4 0x6167 # 0 +0xFBB5 0x66B3 # 0 +0xFBB6 0x8559 # 0 +0xFBB7 0x8E4A # 0 +0xFBB8 0x91AF # 0 +0xFBB9 0x978B # 0 +0xFBBA 0x4E4E # 0 +0xFBBB 0x4E92 # 0 +0xFBBC 0x547C # 0 +0xFBBD 0x58D5 # 0 +0xFBBE 0x58FA # 0 +0xFBBF 0x597D # 0 +0xFBC0 0x5CB5 # 0 +0xFBC1 0x5F27 # 0 +0xFBC2 0x6236 # 0 +0xFBC3 0x6248 # 0 +0xFBC4 0x660A # 0 +0xFBC5 0x6667 # 0 +0xFBC6 0x6BEB # 0 +0xFBC7 0x6D69 # 0 +0xFBC8 0x6DCF # 0 +0xFBC9 0x6E56 # 0 +0xFBCA 0x6EF8 # 0 +0xFBCB 0x6F94 # 0 +0xFBCC 0x6FE0 # 0 +0xFBCD 0x6FE9 # 0 +0xFBCE 0x705D # 0 +0xFBCF 0x72D0 # 0 +0xFBD0 0x7425 # 0 +0xFBD1 0x745A # 0 +0xFBD2 0x74E0 # 0 +0xFBD3 0x7693 # 0 +0xFBD4 0x795C # 0 +0xFBD5 0x7CCA # 0 +0xFBD6 0x7E1E # 0 +0xFBD7 0x80E1 # 0 +0xFBD8 0x82A6 # 0 +0xFBD9 0x846B # 0 +0xFBDA 0x84BF # 0 +0xFBDB 0x864E # 0 +0xFBDC 0x865F # 0 +0xFBDD 0x8774 # 0 +0xFBDE 0x8B77 # 0 +0xFBDF 0x8C6A # 0 +0xFBE0 0x93AC # 0 +0xFBE1 0x9800 # 0 +0xFBE2 0x9865 # 0 +0xFBE3 0x60D1 # 0 +0xFBE4 0x6216 # 0 +0xFBE5 0x9177 # 0 +0xFBE6 0x5A5A # 0 +0xFBE7 0x660F # 0 +0xFBE8 0x6DF7 # 0 +0xFBE9 0x6E3E # 0 +0xFBEA 0x743F # 0 +0xFBEB 0x9B42 # 0 +0xFBEC 0x5FFD # 0 +0xFBED 0x60DA # 0 +0xFBEE 0x7B0F # 0 +0xFBEF 0x54C4 # 0 +0xFBF0 0x5F18 # 0 +0xFBF1 0x6C5E # 0 +0xFBF2 0x6CD3 # 0 +0xFBF3 0x6D2A # 0 +0xFBF4 0x70D8 # 0 +0xFBF5 0x7D05 # 0 +0xFBF6 0x8679 # 0 +0xFBF7 0x8A0C # 0 +0xFBF8 0x9D3B # 0 +0xFBF9 0x5316 # 0 +0xFBFA 0x548C # 0 +0xFBFB 0x5B05 # 0 +0xFBFC 0x6A3A # 0 +0xFBFD 0x706B # 0 +0xFBFE 0x7575 # 0 +0xFCA1 0x798D # 0 +0xFCA2 0x79BE # 0 +0xFCA3 0x82B1 # 0 +0xFCA4 0x83EF # 0 +0xFCA5 0x8A71 # 0 +0xFCA6 0x8B41 # 0 +0xFCA7 0x8CA8 # 0 +0xFCA8 0x9774 # 0 +0xFCA9 0xFA0B # 0 +0xFCAA 0x64F4 # 0 +0xFCAB 0x652B # 0 +0xFCAC 0x78BA # 0 +0xFCAD 0x78BB # 0 +0xFCAE 0x7A6B # 0 +0xFCAF 0x4E38 # 0 +0xFCB0 0x559A # 0 +0xFCB1 0x5950 # 0 +0xFCB2 0x5BA6 # 0 +0xFCB3 0x5E7B # 0 +0xFCB4 0x60A3 # 0 +0xFCB5 0x63DB # 0 +0xFCB6 0x6B61 # 0 +0xFCB7 0x6665 # 0 +0xFCB8 0x6853 # 0 +0xFCB9 0x6E19 # 0 +0xFCBA 0x7165 # 0 +0xFCBB 0x74B0 # 0 +0xFCBC 0x7D08 # 0 +0xFCBD 0x9084 # 0 +0xFCBE 0x9A69 # 0 +0xFCBF 0x9C25 # 0 +0xFCC0 0x6D3B # 0 +0xFCC1 0x6ED1 # 0 +0xFCC2 0x733E # 0 +0xFCC3 0x8C41 # 0 +0xFCC4 0x95CA # 0 +0xFCC5 0x51F0 # 0 +0xFCC6 0x5E4C # 0 +0xFCC7 0x5FA8 # 0 +0xFCC8 0x604D # 0 +0xFCC9 0x60F6 # 0 +0xFCCA 0x6130 # 0 +0xFCCB 0x614C # 0 +0xFCCC 0x6643 # 0 +0xFCCD 0x6644 # 0 +0xFCCE 0x69A5 # 0 +0xFCCF 0x6CC1 # 0 +0xFCD0 0x6E5F # 0 +0xFCD1 0x6EC9 # 0 +0xFCD2 0x6F62 # 0 +0xFCD3 0x714C # 0 +0xFCD4 0x749C # 0 +0xFCD5 0x7687 # 0 +0xFCD6 0x7BC1 # 0 +0xFCD7 0x7C27 # 0 +0xFCD8 0x8352 # 0 +0xFCD9 0x8757 # 0 +0xFCDA 0x9051 # 0 +0xFCDB 0x968D # 0 +0xFCDC 0x9EC3 # 0 +0xFCDD 0x532F # 0 +0xFCDE 0x56DE # 0 +0xFCDF 0x5EFB # 0 +0xFCE0 0x5F8A # 0 +0xFCE1 0x6062 # 0 +0xFCE2 0x6094 # 0 +0xFCE3 0x61F7 # 0 +0xFCE4 0x6666 # 0 +0xFCE5 0x6703 # 0 +0xFCE6 0x6A9C # 0 +0xFCE7 0x6DEE # 0 +0xFCE8 0x6FAE # 0 +0xFCE9 0x7070 # 0 +0xFCEA 0x736A # 0 +0xFCEB 0x7E6A # 0 +0xFCEC 0x81BE # 0 +0xFCED 0x8334 # 0 +0xFCEE 0x86D4 # 0 +0xFCEF 0x8AA8 # 0 +0xFCF0 0x8CC4 # 0 +0xFCF1 0x5283 # 0 +0xFCF2 0x7372 # 0 +0xFCF3 0x5B96 # 0 +0xFCF4 0x6A6B # 0 +0xFCF5 0x9404 # 0 +0xFCF6 0x54EE # 0 +0xFCF7 0x5686 # 0 +0xFCF8 0x5B5D # 0 +0xFCF9 0x6548 # 0 +0xFCFA 0x6585 # 0 +0xFCFB 0x66C9 # 0 +0xFCFC 0x689F # 0 +0xFCFD 0x6D8D # 0 +0xFCFE 0x6DC6 # 0 +0xFDA1 0x723B # 0 +0xFDA2 0x80B4 # 0 +0xFDA3 0x9175 # 0 +0xFDA4 0x9A4D # 0 +0xFDA5 0x4FAF # 0 +0xFDA6 0x5019 # 0 +0xFDA7 0x539A # 0 +0xFDA8 0x540E # 0 +0xFDA9 0x543C # 0 +0xFDAA 0x5589 # 0 +0xFDAB 0x55C5 # 0 +0xFDAC 0x5E3F # 0 +0xFDAD 0x5F8C # 0 +0xFDAE 0x673D # 0 +0xFDAF 0x7166 # 0 +0xFDB0 0x73DD # 0 +0xFDB1 0x9005 # 0 +0xFDB2 0x52DB # 0 +0xFDB3 0x52F3 # 0 +0xFDB4 0x5864 # 0 +0xFDB5 0x58CE # 0 +0xFDB6 0x7104 # 0 +0xFDB7 0x718F # 0 +0xFDB8 0x71FB # 0 +0xFDB9 0x85B0 # 0 +0xFDBA 0x8A13 # 0 +0xFDBB 0x6688 # 0 +0xFDBC 0x85A8 # 0 +0xFDBD 0x55A7 # 0 +0xFDBE 0x6684 # 0 +0xFDBF 0x714A # 0 +0xFDC0 0x8431 # 0 +0xFDC1 0x5349 # 0 +0xFDC2 0x5599 # 0 +0xFDC3 0x6BC1 # 0 +0xFDC4 0x5F59 # 0 +0xFDC5 0x5FBD # 0 +0xFDC6 0x63EE # 0 +0xFDC7 0x6689 # 0 +0xFDC8 0x7147 # 0 +0xFDC9 0x8AF1 # 0 +0xFDCA 0x8F1D # 0 +0xFDCB 0x9EBE # 0 +0xFDCC 0x4F11 # 0 +0xFDCD 0x643A # 0 +0xFDCE 0x70CB # 0 +0xFDCF 0x7566 # 0 +0xFDD0 0x8667 # 0 +0xFDD1 0x6064 # 0 +0xFDD2 0x8B4E # 0 +0xFDD3 0x9DF8 # 0 +0xFDD4 0x5147 # 0 +0xFDD5 0x51F6 # 0 +0xFDD6 0x5308 # 0 +0xFDD7 0x6D36 # 0 +0xFDD8 0x80F8 # 0 +0xFDD9 0x9ED1 # 0 +0xFDDA 0x6615 # 0 +0xFDDB 0x6B23 # 0 +0xFDDC 0x7098 # 0 +0xFDDD 0x75D5 # 0 +0xFDDE 0x5403 # 0 +0xFDDF 0x5C79 # 0 +0xFDE0 0x7D07 # 0 +0xFDE1 0x8A16 # 0 +0xFDE2 0x6B20 # 0 +0xFDE3 0x6B3D # 0 +0xFDE4 0x6B46 # 0 +0xFDE5 0x5438 # 0 +0xFDE6 0x6070 # 0 +0xFDE7 0x6D3D # 0 +0xFDE8 0x7FD5 # 0 +0xFDE9 0x8208 # 0 +0xFDEA 0x50D6 # 0 +0xFDEB 0x51DE # 0 +0xFDEC 0x559C # 0 +0xFDED 0x566B # 0 +0xFDEE 0x56CD # 0 +0xFDEF 0x59EC # 0 +0xFDF0 0x5B09 # 0 +0xFDF1 0x5E0C # 0 +0xFDF2 0x6199 # 0 +0xFDF3 0x6198 # 0 +0xFDF4 0x6231 # 0 +0xFDF5 0x665E # 0 +0xFDF6 0x66E6 # 0 +0xFDF7 0x7199 # 0 +0xFDF8 0x71B9 # 0 +0xFDF9 0x71BA # 0 +0xFDFA 0x72A7 # 0 +0xFDFB 0x79A7 # 0 +0xFDFC 0x7A00 # 0 +0xFDFD 0x7FB2 # 0 +0xFDFE 0x8A70 # 0 +0xFEA1 0xE05E # 0 +0xFEA2 0xE05F # 0 +0xFEA3 0xE060 # 0 +0xFEA4 0xE061 # 0 +0xFEA5 0xE062 # 0 +0xFEA6 0xE063 # 0 +0xFEA7 0xE064 # 0 +0xFEA8 0xE065 # 0 +0xFEA9 0xE066 # 0 +0xFEAA 0xE067 # 0 +0xFEAB 0xE068 # 0 +0xFEAC 0xE069 # 0 +0xFEAD 0xE06A # 0 +0xFEAE 0xE06B # 0 +0xFEAF 0xE06C # 0 +0xFEB0 0xE06D # 0 +0xFEB1 0xE06E # 0 +0xFEB2 0xE06F # 0 +0xFEB3 0xE070 # 0 +0xFEB4 0xE071 # 0 +0xFEB5 0xE072 # 0 +0xFEB6 0xE073 # 0 +0xFEB7 0xE074 # 0 +0xFEB8 0xE075 # 0 +0xFEB9 0xE076 # 0 +0xFEBA 0xE077 # 0 +0xFEBB 0xE078 # 0 +0xFEBC 0xE079 # 0 +0xFEBD 0xE07A # 0 +0xFEBE 0xE07B # 0 +0xFEBF 0xE07C # 0 +0xFEC0 0xE07D # 0 +0xFEC1 0xE07E # 0 +0xFEC2 0xE07F # 0 +0xFEC3 0xE080 # 0 +0xFEC4 0xE081 # 0 +0xFEC5 0xE082 # 0 +0xFEC6 0xE083 # 0 +0xFEC7 0xE084 # 0 +0xFEC8 0xE085 # 0 +0xFEC9 0xE086 # 0 +0xFECA 0xE087 # 0 +0xFECB 0xE088 # 0 +0xFECC 0xE089 # 0 +0xFECD 0xE08A # 0 +0xFECE 0xE08B # 0 +0xFECF 0xE08C # 0 +0xFED0 0xE08D # 0 +0xFED1 0xE08E # 0 +0xFED2 0xE08F # 0 +0xFED3 0xE090 # 0 +0xFED4 0xE091 # 0 +0xFED5 0xE092 # 0 +0xFED6 0xE093 # 0 +0xFED7 0xE094 # 0 +0xFED8 0xE095 # 0 +0xFED9 0xE096 # 0 +0xFEDA 0xE097 # 0 +0xFEDB 0xE098 # 0 +0xFEDC 0xE099 # 0 +0xFEDD 0xE09A # 0 +0xFEDE 0xE09B # 0 +0xFEDF 0xE09C # 0 +0xFEE0 0xE09D # 0 +0xFEE1 0xE09E # 0 +0xFEE2 0xE09F # 0 +0xFEE3 0xE0A0 # 0 +0xFEE4 0xE0A1 # 0 +0xFEE5 0xE0A2 # 0 +0xFEE6 0xE0A3 # 0 +0xFEE7 0xE0A4 # 0 +0xFEE8 0xE0A5 # 0 +0xFEE9 0xE0A6 # 0 +0xFEEA 0xE0A7 # 0 +0xFEEB 0xE0A8 # 0 +0xFEEC 0xE0A9 # 0 +0xFEED 0xE0AA # 0 +0xFEEE 0xE0AB # 0 +0xFEEF 0xE0AC # 0 +0xFEF0 0xE0AD # 0 +0xFEF1 0xE0AE # 0 +0xFEF2 0xE0AF # 0 +0xFEF3 0xE0B0 # 0 +0xFEF4 0xE0B1 # 0 +0xFEF5 0xE0B2 # 0 +0xFEF6 0xE0B3 # 0 +0xFEF7 0xE0B4 # 0 +0xFEF8 0xE0B5 # 0 +0xFEF9 0xE0B6 # 0 +0xFEFA 0xE0B7 # 0 +0xFEFB 0xE0B8 # 0 +0xFEFC 0xE0B9 # 0 +0xFEFD 0xE0BA # 0 +0xFEFE 0xE0BB # 0 diff --git a/data/windows-950.txt b/data/windows-950.txt new file mode 100644 index 0000000000..2ac92bf35c --- /dev/null +++ b/data/windows-950.txt @@ -0,0 +1,19841 @@ +# cp950.txt - Legacy to Unicode charmap +0x0000 0x0000 # 0 +0x0001 0x0001 # 0 +0x0002 0x0002 # 0 +0x0003 0x0003 # 0 +0x0004 0x0004 # 0 +0x0005 0x0005 # 0 +0x0006 0x0006 # 0 +0x0007 0x0007 # 0 +0x0008 0x0008 # 0 +0x0009 0x0009 # 0 +0x000A 0x000A # 0 +0x000B 0x000B # 0 +0x000C 0x000C # 0 +0x000D 0x000D # 0 +0x000E 0x000E # 0 +0x000F 0x000F # 0 +0x0010 0x0010 # 0 +0x0011 0x0011 # 0 +0x0012 0x0012 # 0 +0x0013 0x0013 # 0 +0x0014 0x0014 # 0 +0x0015 0x0015 # 0 +0x0016 0x0016 # 0 +0x0017 0x0017 # 0 +0x0018 0x0018 # 0 +0x0019 0x0019 # 0 +0x001A 0x001A # 0 +0x001B 0x001B # 0 +0x001C 0x001C # 0 +0x001D 0x001D # 0 +0x001E 0x001E # 0 +0x001F 0x001F # 0 +0x0020 0x0020 # 0 +0x0021 0x0021 # 0 +0x0022 0x0022 # 0 +0x0023 0x0023 # 0 +0x0024 0x0024 # 0 +0x0025 0x0025 # 0 +0x0026 0x0026 # 0 +0x0027 0x0027 # 0 +0x0028 0x0028 # 0 +0x0029 0x0029 # 0 +0x002A 0x002A # 0 +0x002B 0x002B # 0 +0x002C 0x002C # 0 +0x002D 0x002D # 0 +0x002E 0x002E # 0 +0x002F 0x002F # 0 +0x0030 0x0030 # 0 +0x0031 0x0031 # 0 +0x0032 0x0032 # 0 +0x0033 0x0033 # 0 +0x0034 0x0034 # 0 +0x0035 0x0035 # 0 +0x0036 0x0036 # 0 +0x0037 0x0037 # 0 +0x0038 0x0038 # 0 +0x0039 0x0039 # 0 +0x003A 0x003A # 0 +0x003B 0x003B # 0 +0x003C 0x003C # 0 +0x003D 0x003D # 0 +0x003E 0x003E # 0 +0x003F 0x003F # 0 +0x0040 0x0040 # 0 +0x0041 0x0041 # 0 +0x0042 0x0042 # 0 +0x0043 0x0043 # 0 +0x0044 0x0044 # 0 +0x0045 0x0045 # 0 +0x0046 0x0046 # 0 +0x0047 0x0047 # 0 +0x0048 0x0048 # 0 +0x0049 0x0049 # 0 +0x004A 0x004A # 0 +0x004B 0x004B # 0 +0x004C 0x004C # 0 +0x004D 0x004D # 0 +0x004E 0x004E # 0 +0x004F 0x004F # 0 +0x0050 0x0050 # 0 +0x0051 0x0051 # 0 +0x0052 0x0052 # 0 +0x0053 0x0053 # 0 +0x0054 0x0054 # 0 +0x0055 0x0055 # 0 +0x0056 0x0056 # 0 +0x0057 0x0057 # 0 +0x0058 0x0058 # 0 +0x0059 0x0059 # 0 +0x005A 0x005A # 0 +0x005B 0x005B # 0 +0x005C 0x005C # 0 +0x005D 0x005D # 0 +0x005E 0x005E # 0 +0x005F 0x005F # 0 +0x0060 0x0060 # 0 +0x0061 0x0061 # 0 +0x0062 0x0062 # 0 +0x0063 0x0063 # 0 +0x0064 0x0064 # 0 +0x0065 0x0065 # 0 +0x0066 0x0066 # 0 +0x0067 0x0067 # 0 +0x0068 0x0068 # 0 +0x0069 0x0069 # 0 +0x006A 0x006A # 0 +0x006B 0x006B # 0 +0x006C 0x006C # 0 +0x006D 0x006D # 0 +0x006E 0x006E # 0 +0x006F 0x006F # 0 +0x0070 0x0070 # 0 +0x0071 0x0071 # 0 +0x0072 0x0072 # 0 +0x0073 0x0073 # 0 +0x0074 0x0074 # 0 +0x0075 0x0075 # 0 +0x0076 0x0076 # 0 +0x0077 0x0077 # 0 +0x0078 0x0078 # 0 +0x0079 0x0079 # 0 +0x007A 0x007A # 0 +0x007B 0x007B # 0 +0x007C 0x007C # 0 +0x007D 0x007D # 0 +0x007E 0x007E # 0 +0x007F 0x007F # 0 +0x0080 0x0080 # 0 +0x00FF 0xF8F8 # 0 +0x8140 0xEEB8 # 0 +0x8141 0xEEB9 # 0 +0x8142 0xEEBA # 0 +0x8143 0xEEBB # 0 +0x8144 0xEEBC # 0 +0x8145 0xEEBD # 0 +0x8146 0xEEBE # 0 +0x8147 0xEEBF # 0 +0x8148 0xEEC0 # 0 +0x8149 0xEEC1 # 0 +0x814A 0xEEC2 # 0 +0x814B 0xEEC3 # 0 +0x814C 0xEEC4 # 0 +0x814D 0xEEC5 # 0 +0x814E 0xEEC6 # 0 +0x814F 0xEEC7 # 0 +0x8150 0xEEC8 # 0 +0x8151 0xEEC9 # 0 +0x8152 0xEECA # 0 +0x8153 0xEECB # 0 +0x8154 0xEECC # 0 +0x8155 0xEECD # 0 +0x8156 0xEECE # 0 +0x8157 0xEECF # 0 +0x8158 0xEED0 # 0 +0x8159 0xEED1 # 0 +0x815A 0xEED2 # 0 +0x815B 0xEED3 # 0 +0x815C 0xEED4 # 0 +0x815D 0xEED5 # 0 +0x815E 0xEED6 # 0 +0x815F 0xEED7 # 0 +0x8160 0xEED8 # 0 +0x8161 0xEED9 # 0 +0x8162 0xEEDA # 0 +0x8163 0xEEDB # 0 +0x8164 0xEEDC # 0 +0x8165 0xEEDD # 0 +0x8166 0xEEDE # 0 +0x8167 0xEEDF # 0 +0x8168 0xEEE0 # 0 +0x8169 0xEEE1 # 0 +0x816A 0xEEE2 # 0 +0x816B 0xEEE3 # 0 +0x816C 0xEEE4 # 0 +0x816D 0xEEE5 # 0 +0x816E 0xEEE6 # 0 +0x816F 0xEEE7 # 0 +0x8170 0xEEE8 # 0 +0x8171 0xEEE9 # 0 +0x8172 0xEEEA # 0 +0x8173 0xEEEB # 0 +0x8174 0xEEEC # 0 +0x8175 0xEEED # 0 +0x8176 0xEEEE # 0 +0x8177 0xEEEF # 0 +0x8178 0xEEF0 # 0 +0x8179 0xEEF1 # 0 +0x817A 0xEEF2 # 0 +0x817B 0xEEF3 # 0 +0x817C 0xEEF4 # 0 +0x817D 0xEEF5 # 0 +0x817E 0xEEF6 # 0 +0x81A1 0xEEF7 # 0 +0x81A2 0xEEF8 # 0 +0x81A3 0xEEF9 # 0 +0x81A4 0xEEFA # 0 +0x81A5 0xEEFB # 0 +0x81A6 0xEEFC # 0 +0x81A7 0xEEFD # 0 +0x81A8 0xEEFE # 0 +0x81A9 0xEEFF # 0 +0x81AA 0xEF00 # 0 +0x81AB 0xEF01 # 0 +0x81AC 0xEF02 # 0 +0x81AD 0xEF03 # 0 +0x81AE 0xEF04 # 0 +0x81AF 0xEF05 # 0 +0x81B0 0xEF06 # 0 +0x81B1 0xEF07 # 0 +0x81B2 0xEF08 # 0 +0x81B3 0xEF09 # 0 +0x81B4 0xEF0A # 0 +0x81B5 0xEF0B # 0 +0x81B6 0xEF0C # 0 +0x81B7 0xEF0D # 0 +0x81B8 0xEF0E # 0 +0x81B9 0xEF0F # 0 +0x81BA 0xEF10 # 0 +0x81BB 0xEF11 # 0 +0x81BC 0xEF12 # 0 +0x81BD 0xEF13 # 0 +0x81BE 0xEF14 # 0 +0x81BF 0xEF15 # 0 +0x81C0 0xEF16 # 0 +0x81C1 0xEF17 # 0 +0x81C2 0xEF18 # 0 +0x81C3 0xEF19 # 0 +0x81C4 0xEF1A # 0 +0x81C5 0xEF1B # 0 +0x81C6 0xEF1C # 0 +0x81C7 0xEF1D # 0 +0x81C8 0xEF1E # 0 +0x81C9 0xEF1F # 0 +0x81CA 0xEF20 # 0 +0x81CB 0xEF21 # 0 +0x81CC 0xEF22 # 0 +0x81CD 0xEF23 # 0 +0x81CE 0xEF24 # 0 +0x81CF 0xEF25 # 0 +0x81D0 0xEF26 # 0 +0x81D1 0xEF27 # 0 +0x81D2 0xEF28 # 0 +0x81D3 0xEF29 # 0 +0x81D4 0xEF2A # 0 +0x81D5 0xEF2B # 0 +0x81D6 0xEF2C # 0 +0x81D7 0xEF2D # 0 +0x81D8 0xEF2E # 0 +0x81D9 0xEF2F # 0 +0x81DA 0xEF30 # 0 +0x81DB 0xEF31 # 0 +0x81DC 0xEF32 # 0 +0x81DD 0xEF33 # 0 +0x81DE 0xEF34 # 0 +0x81DF 0xEF35 # 0 +0x81E0 0xEF36 # 0 +0x81E1 0xEF37 # 0 +0x81E2 0xEF38 # 0 +0x81E3 0xEF39 # 0 +0x81E4 0xEF3A # 0 +0x81E5 0xEF3B # 0 +0x81E6 0xEF3C # 0 +0x81E7 0xEF3D # 0 +0x81E8 0xEF3E # 0 +0x81E9 0xEF3F # 0 +0x81EA 0xEF40 # 0 +0x81EB 0xEF41 # 0 +0x81EC 0xEF42 # 0 +0x81ED 0xEF43 # 0 +0x81EE 0xEF44 # 0 +0x81EF 0xEF45 # 0 +0x81F0 0xEF46 # 0 +0x81F1 0xEF47 # 0 +0x81F2 0xEF48 # 0 +0x81F3 0xEF49 # 0 +0x81F4 0xEF4A # 0 +0x81F5 0xEF4B # 0 +0x81F6 0xEF4C # 0 +0x81F7 0xEF4D # 0 +0x81F8 0xEF4E # 0 +0x81F9 0xEF4F # 0 +0x81FA 0xEF50 # 0 +0x81FB 0xEF51 # 0 +0x81FC 0xEF52 # 0 +0x81FD 0xEF53 # 0 +0x81FE 0xEF54 # 0 +0x8240 0xEF55 # 0 +0x8241 0xEF56 # 0 +0x8242 0xEF57 # 0 +0x8243 0xEF58 # 0 +0x8244 0xEF59 # 0 +0x8245 0xEF5A # 0 +0x8246 0xEF5B # 0 +0x8247 0xEF5C # 0 +0x8248 0xEF5D # 0 +0x8249 0xEF5E # 0 +0x824A 0xEF5F # 0 +0x824B 0xEF60 # 0 +0x824C 0xEF61 # 0 +0x824D 0xEF62 # 0 +0x824E 0xEF63 # 0 +0x824F 0xEF64 # 0 +0x8250 0xEF65 # 0 +0x8251 0xEF66 # 0 +0x8252 0xEF67 # 0 +0x8253 0xEF68 # 0 +0x8254 0xEF69 # 0 +0x8255 0xEF6A # 0 +0x8256 0xEF6B # 0 +0x8257 0xEF6C # 0 +0x8258 0xEF6D # 0 +0x8259 0xEF6E # 0 +0x825A 0xEF6F # 0 +0x825B 0xEF70 # 0 +0x825C 0xEF71 # 0 +0x825D 0xEF72 # 0 +0x825E 0xEF73 # 0 +0x825F 0xEF74 # 0 +0x8260 0xEF75 # 0 +0x8261 0xEF76 # 0 +0x8262 0xEF77 # 0 +0x8263 0xEF78 # 0 +0x8264 0xEF79 # 0 +0x8265 0xEF7A # 0 +0x8266 0xEF7B # 0 +0x8267 0xEF7C # 0 +0x8268 0xEF7D # 0 +0x8269 0xEF7E # 0 +0x826A 0xEF7F # 0 +0x826B 0xEF80 # 0 +0x826C 0xEF81 # 0 +0x826D 0xEF82 # 0 +0x826E 0xEF83 # 0 +0x826F 0xEF84 # 0 +0x8270 0xEF85 # 0 +0x8271 0xEF86 # 0 +0x8272 0xEF87 # 0 +0x8273 0xEF88 # 0 +0x8274 0xEF89 # 0 +0x8275 0xEF8A # 0 +0x8276 0xEF8B # 0 +0x8277 0xEF8C # 0 +0x8278 0xEF8D # 0 +0x8279 0xEF8E # 0 +0x827A 0xEF8F # 0 +0x827B 0xEF90 # 0 +0x827C 0xEF91 # 0 +0x827D 0xEF92 # 0 +0x827E 0xEF93 # 0 +0x82A1 0xEF94 # 0 +0x82A2 0xEF95 # 0 +0x82A3 0xEF96 # 0 +0x82A4 0xEF97 # 0 +0x82A5 0xEF98 # 0 +0x82A6 0xEF99 # 0 +0x82A7 0xEF9A # 0 +0x82A8 0xEF9B # 0 +0x82A9 0xEF9C # 0 +0x82AA 0xEF9D # 0 +0x82AB 0xEF9E # 0 +0x82AC 0xEF9F # 0 +0x82AD 0xEFA0 # 0 +0x82AE 0xEFA1 # 0 +0x82AF 0xEFA2 # 0 +0x82B0 0xEFA3 # 0 +0x82B1 0xEFA4 # 0 +0x82B2 0xEFA5 # 0 +0x82B3 0xEFA6 # 0 +0x82B4 0xEFA7 # 0 +0x82B5 0xEFA8 # 0 +0x82B6 0xEFA9 # 0 +0x82B7 0xEFAA # 0 +0x82B8 0xEFAB # 0 +0x82B9 0xEFAC # 0 +0x82BA 0xEFAD # 0 +0x82BB 0xEFAE # 0 +0x82BC 0xEFAF # 0 +0x82BD 0xEFB0 # 0 +0x82BE 0xEFB1 # 0 +0x82BF 0xEFB2 # 0 +0x82C0 0xEFB3 # 0 +0x82C1 0xEFB4 # 0 +0x82C2 0xEFB5 # 0 +0x82C3 0xEFB6 # 0 +0x82C4 0xEFB7 # 0 +0x82C5 0xEFB8 # 0 +0x82C6 0xEFB9 # 0 +0x82C7 0xEFBA # 0 +0x82C8 0xEFBB # 0 +0x82C9 0xEFBC # 0 +0x82CA 0xEFBD # 0 +0x82CB 0xEFBE # 0 +0x82CC 0xEFBF # 0 +0x82CD 0xEFC0 # 0 +0x82CE 0xEFC1 # 0 +0x82CF 0xEFC2 # 0 +0x82D0 0xEFC3 # 0 +0x82D1 0xEFC4 # 0 +0x82D2 0xEFC5 # 0 +0x82D3 0xEFC6 # 0 +0x82D4 0xEFC7 # 0 +0x82D5 0xEFC8 # 0 +0x82D6 0xEFC9 # 0 +0x82D7 0xEFCA # 0 +0x82D8 0xEFCB # 0 +0x82D9 0xEFCC # 0 +0x82DA 0xEFCD # 0 +0x82DB 0xEFCE # 0 +0x82DC 0xEFCF # 0 +0x82DD 0xEFD0 # 0 +0x82DE 0xEFD1 # 0 +0x82DF 0xEFD2 # 0 +0x82E0 0xEFD3 # 0 +0x82E1 0xEFD4 # 0 +0x82E2 0xEFD5 # 0 +0x82E3 0xEFD6 # 0 +0x82E4 0xEFD7 # 0 +0x82E5 0xEFD8 # 0 +0x82E6 0xEFD9 # 0 +0x82E7 0xEFDA # 0 +0x82E8 0xEFDB # 0 +0x82E9 0xEFDC # 0 +0x82EA 0xEFDD # 0 +0x82EB 0xEFDE # 0 +0x82EC 0xEFDF # 0 +0x82ED 0xEFE0 # 0 +0x82EE 0xEFE1 # 0 +0x82EF 0xEFE2 # 0 +0x82F0 0xEFE3 # 0 +0x82F1 0xEFE4 # 0 +0x82F2 0xEFE5 # 0 +0x82F3 0xEFE6 # 0 +0x82F4 0xEFE7 # 0 +0x82F5 0xEFE8 # 0 +0x82F6 0xEFE9 # 0 +0x82F7 0xEFEA # 0 +0x82F8 0xEFEB # 0 +0x82F9 0xEFEC # 0 +0x82FA 0xEFED # 0 +0x82FB 0xEFEE # 0 +0x82FC 0xEFEF # 0 +0x82FD 0xEFF0 # 0 +0x82FE 0xEFF1 # 0 +0x8340 0xEFF2 # 0 +0x8341 0xEFF3 # 0 +0x8342 0xEFF4 # 0 +0x8343 0xEFF5 # 0 +0x8344 0xEFF6 # 0 +0x8345 0xEFF7 # 0 +0x8346 0xEFF8 # 0 +0x8347 0xEFF9 # 0 +0x8348 0xEFFA # 0 +0x8349 0xEFFB # 0 +0x834A 0xEFFC # 0 +0x834B 0xEFFD # 0 +0x834C 0xEFFE # 0 +0x834D 0xEFFF # 0 +0x834E 0xF000 # 0 +0x834F 0xF001 # 0 +0x8350 0xF002 # 0 +0x8351 0xF003 # 0 +0x8352 0xF004 # 0 +0x8353 0xF005 # 0 +0x8354 0xF006 # 0 +0x8355 0xF007 # 0 +0x8356 0xF008 # 0 +0x8357 0xF009 # 0 +0x8358 0xF00A # 0 +0x8359 0xF00B # 0 +0x835A 0xF00C # 0 +0x835B 0xF00D # 0 +0x835C 0xF00E # 0 +0x835D 0xF00F # 0 +0x835E 0xF010 # 0 +0x835F 0xF011 # 0 +0x8360 0xF012 # 0 +0x8361 0xF013 # 0 +0x8362 0xF014 # 0 +0x8363 0xF015 # 0 +0x8364 0xF016 # 0 +0x8365 0xF017 # 0 +0x8366 0xF018 # 0 +0x8367 0xF019 # 0 +0x8368 0xF01A # 0 +0x8369 0xF01B # 0 +0x836A 0xF01C # 0 +0x836B 0xF01D # 0 +0x836C 0xF01E # 0 +0x836D 0xF01F # 0 +0x836E 0xF020 # 0 +0x836F 0xF021 # 0 +0x8370 0xF022 # 0 +0x8371 0xF023 # 0 +0x8372 0xF024 # 0 +0x8373 0xF025 # 0 +0x8374 0xF026 # 0 +0x8375 0xF027 # 0 +0x8376 0xF028 # 0 +0x8377 0xF029 # 0 +0x8378 0xF02A # 0 +0x8379 0xF02B # 0 +0x837A 0xF02C # 0 +0x837B 0xF02D # 0 +0x837C 0xF02E # 0 +0x837D 0xF02F # 0 +0x837E 0xF030 # 0 +0x83A1 0xF031 # 0 +0x83A2 0xF032 # 0 +0x83A3 0xF033 # 0 +0x83A4 0xF034 # 0 +0x83A5 0xF035 # 0 +0x83A6 0xF036 # 0 +0x83A7 0xF037 # 0 +0x83A8 0xF038 # 0 +0x83A9 0xF039 # 0 +0x83AA 0xF03A # 0 +0x83AB 0xF03B # 0 +0x83AC 0xF03C # 0 +0x83AD 0xF03D # 0 +0x83AE 0xF03E # 0 +0x83AF 0xF03F # 0 +0x83B0 0xF040 # 0 +0x83B1 0xF041 # 0 +0x83B2 0xF042 # 0 +0x83B3 0xF043 # 0 +0x83B4 0xF044 # 0 +0x83B5 0xF045 # 0 +0x83B6 0xF046 # 0 +0x83B7 0xF047 # 0 +0x83B8 0xF048 # 0 +0x83B9 0xF049 # 0 +0x83BA 0xF04A # 0 +0x83BB 0xF04B # 0 +0x83BC 0xF04C # 0 +0x83BD 0xF04D # 0 +0x83BE 0xF04E # 0 +0x83BF 0xF04F # 0 +0x83C0 0xF050 # 0 +0x83C1 0xF051 # 0 +0x83C2 0xF052 # 0 +0x83C3 0xF053 # 0 +0x83C4 0xF054 # 0 +0x83C5 0xF055 # 0 +0x83C6 0xF056 # 0 +0x83C7 0xF057 # 0 +0x83C8 0xF058 # 0 +0x83C9 0xF059 # 0 +0x83CA 0xF05A # 0 +0x83CB 0xF05B # 0 +0x83CC 0xF05C # 0 +0x83CD 0xF05D # 0 +0x83CE 0xF05E # 0 +0x83CF 0xF05F # 0 +0x83D0 0xF060 # 0 +0x83D1 0xF061 # 0 +0x83D2 0xF062 # 0 +0x83D3 0xF063 # 0 +0x83D4 0xF064 # 0 +0x83D5 0xF065 # 0 +0x83D6 0xF066 # 0 +0x83D7 0xF067 # 0 +0x83D8 0xF068 # 0 +0x83D9 0xF069 # 0 +0x83DA 0xF06A # 0 +0x83DB 0xF06B # 0 +0x83DC 0xF06C # 0 +0x83DD 0xF06D # 0 +0x83DE 0xF06E # 0 +0x83DF 0xF06F # 0 +0x83E0 0xF070 # 0 +0x83E1 0xF071 # 0 +0x83E2 0xF072 # 0 +0x83E3 0xF073 # 0 +0x83E4 0xF074 # 0 +0x83E5 0xF075 # 0 +0x83E6 0xF076 # 0 +0x83E7 0xF077 # 0 +0x83E8 0xF078 # 0 +0x83E9 0xF079 # 0 +0x83EA 0xF07A # 0 +0x83EB 0xF07B # 0 +0x83EC 0xF07C # 0 +0x83ED 0xF07D # 0 +0x83EE 0xF07E # 0 +0x83EF 0xF07F # 0 +0x83F0 0xF080 # 0 +0x83F1 0xF081 # 0 +0x83F2 0xF082 # 0 +0x83F3 0xF083 # 0 +0x83F4 0xF084 # 0 +0x83F5 0xF085 # 0 +0x83F6 0xF086 # 0 +0x83F7 0xF087 # 0 +0x83F8 0xF088 # 0 +0x83F9 0xF089 # 0 +0x83FA 0xF08A # 0 +0x83FB 0xF08B # 0 +0x83FC 0xF08C # 0 +0x83FD 0xF08D # 0 +0x83FE 0xF08E # 0 +0x8440 0xF08F # 0 +0x8441 0xF090 # 0 +0x8442 0xF091 # 0 +0x8443 0xF092 # 0 +0x8444 0xF093 # 0 +0x8445 0xF094 # 0 +0x8446 0xF095 # 0 +0x8447 0xF096 # 0 +0x8448 0xF097 # 0 +0x8449 0xF098 # 0 +0x844A 0xF099 # 0 +0x844B 0xF09A # 0 +0x844C 0xF09B # 0 +0x844D 0xF09C # 0 +0x844E 0xF09D # 0 +0x844F 0xF09E # 0 +0x8450 0xF09F # 0 +0x8451 0xF0A0 # 0 +0x8452 0xF0A1 # 0 +0x8453 0xF0A2 # 0 +0x8454 0xF0A3 # 0 +0x8455 0xF0A4 # 0 +0x8456 0xF0A5 # 0 +0x8457 0xF0A6 # 0 +0x8458 0xF0A7 # 0 +0x8459 0xF0A8 # 0 +0x845A 0xF0A9 # 0 +0x845B 0xF0AA # 0 +0x845C 0xF0AB # 0 +0x845D 0xF0AC # 0 +0x845E 0xF0AD # 0 +0x845F 0xF0AE # 0 +0x8460 0xF0AF # 0 +0x8461 0xF0B0 # 0 +0x8462 0xF0B1 # 0 +0x8463 0xF0B2 # 0 +0x8464 0xF0B3 # 0 +0x8465 0xF0B4 # 0 +0x8466 0xF0B5 # 0 +0x8467 0xF0B6 # 0 +0x8468 0xF0B7 # 0 +0x8469 0xF0B8 # 0 +0x846A 0xF0B9 # 0 +0x846B 0xF0BA # 0 +0x846C 0xF0BB # 0 +0x846D 0xF0BC # 0 +0x846E 0xF0BD # 0 +0x846F 0xF0BE # 0 +0x8470 0xF0BF # 0 +0x8471 0xF0C0 # 0 +0x8472 0xF0C1 # 0 +0x8473 0xF0C2 # 0 +0x8474 0xF0C3 # 0 +0x8475 0xF0C4 # 0 +0x8476 0xF0C5 # 0 +0x8477 0xF0C6 # 0 +0x8478 0xF0C7 # 0 +0x8479 0xF0C8 # 0 +0x847A 0xF0C9 # 0 +0x847B 0xF0CA # 0 +0x847C 0xF0CB # 0 +0x847D 0xF0CC # 0 +0x847E 0xF0CD # 0 +0x84A1 0xF0CE # 0 +0x84A2 0xF0CF # 0 +0x84A3 0xF0D0 # 0 +0x84A4 0xF0D1 # 0 +0x84A5 0xF0D2 # 0 +0x84A6 0xF0D3 # 0 +0x84A7 0xF0D4 # 0 +0x84A8 0xF0D5 # 0 +0x84A9 0xF0D6 # 0 +0x84AA 0xF0D7 # 0 +0x84AB 0xF0D8 # 0 +0x84AC 0xF0D9 # 0 +0x84AD 0xF0DA # 0 +0x84AE 0xF0DB # 0 +0x84AF 0xF0DC # 0 +0x84B0 0xF0DD # 0 +0x84B1 0xF0DE # 0 +0x84B2 0xF0DF # 0 +0x84B3 0xF0E0 # 0 +0x84B4 0xF0E1 # 0 +0x84B5 0xF0E2 # 0 +0x84B6 0xF0E3 # 0 +0x84B7 0xF0E4 # 0 +0x84B8 0xF0E5 # 0 +0x84B9 0xF0E6 # 0 +0x84BA 0xF0E7 # 0 +0x84BB 0xF0E8 # 0 +0x84BC 0xF0E9 # 0 +0x84BD 0xF0EA # 0 +0x84BE 0xF0EB # 0 +0x84BF 0xF0EC # 0 +0x84C0 0xF0ED # 0 +0x84C1 0xF0EE # 0 +0x84C2 0xF0EF # 0 +0x84C3 0xF0F0 # 0 +0x84C4 0xF0F1 # 0 +0x84C5 0xF0F2 # 0 +0x84C6 0xF0F3 # 0 +0x84C7 0xF0F4 # 0 +0x84C8 0xF0F5 # 0 +0x84C9 0xF0F6 # 0 +0x84CA 0xF0F7 # 0 +0x84CB 0xF0F8 # 0 +0x84CC 0xF0F9 # 0 +0x84CD 0xF0FA # 0 +0x84CE 0xF0FB # 0 +0x84CF 0xF0FC # 0 +0x84D0 0xF0FD # 0 +0x84D1 0xF0FE # 0 +0x84D2 0xF0FF # 0 +0x84D3 0xF100 # 0 +0x84D4 0xF101 # 0 +0x84D5 0xF102 # 0 +0x84D6 0xF103 # 0 +0x84D7 0xF104 # 0 +0x84D8 0xF105 # 0 +0x84D9 0xF106 # 0 +0x84DA 0xF107 # 0 +0x84DB 0xF108 # 0 +0x84DC 0xF109 # 0 +0x84DD 0xF10A # 0 +0x84DE 0xF10B # 0 +0x84DF 0xF10C # 0 +0x84E0 0xF10D # 0 +0x84E1 0xF10E # 0 +0x84E2 0xF10F # 0 +0x84E3 0xF110 # 0 +0x84E4 0xF111 # 0 +0x84E5 0xF112 # 0 +0x84E6 0xF113 # 0 +0x84E7 0xF114 # 0 +0x84E8 0xF115 # 0 +0x84E9 0xF116 # 0 +0x84EA 0xF117 # 0 +0x84EB 0xF118 # 0 +0x84EC 0xF119 # 0 +0x84ED 0xF11A # 0 +0x84EE 0xF11B # 0 +0x84EF 0xF11C # 0 +0x84F0 0xF11D # 0 +0x84F1 0xF11E # 0 +0x84F2 0xF11F # 0 +0x84F3 0xF120 # 0 +0x84F4 0xF121 # 0 +0x84F5 0xF122 # 0 +0x84F6 0xF123 # 0 +0x84F7 0xF124 # 0 +0x84F8 0xF125 # 0 +0x84F9 0xF126 # 0 +0x84FA 0xF127 # 0 +0x84FB 0xF128 # 0 +0x84FC 0xF129 # 0 +0x84FD 0xF12A # 0 +0x84FE 0xF12B # 0 +0x8540 0xF12C # 0 +0x8541 0xF12D # 0 +0x8542 0xF12E # 0 +0x8543 0xF12F # 0 +0x8544 0xF130 # 0 +0x8545 0xF131 # 0 +0x8546 0xF132 # 0 +0x8547 0xF133 # 0 +0x8548 0xF134 # 0 +0x8549 0xF135 # 0 +0x854A 0xF136 # 0 +0x854B 0xF137 # 0 +0x854C 0xF138 # 0 +0x854D 0xF139 # 0 +0x854E 0xF13A # 0 +0x854F 0xF13B # 0 +0x8550 0xF13C # 0 +0x8551 0xF13D # 0 +0x8552 0xF13E # 0 +0x8553 0xF13F # 0 +0x8554 0xF140 # 0 +0x8555 0xF141 # 0 +0x8556 0xF142 # 0 +0x8557 0xF143 # 0 +0x8558 0xF144 # 0 +0x8559 0xF145 # 0 +0x855A 0xF146 # 0 +0x855B 0xF147 # 0 +0x855C 0xF148 # 0 +0x855D 0xF149 # 0 +0x855E 0xF14A # 0 +0x855F 0xF14B # 0 +0x8560 0xF14C # 0 +0x8561 0xF14D # 0 +0x8562 0xF14E # 0 +0x8563 0xF14F # 0 +0x8564 0xF150 # 0 +0x8565 0xF151 # 0 +0x8566 0xF152 # 0 +0x8567 0xF153 # 0 +0x8568 0xF154 # 0 +0x8569 0xF155 # 0 +0x856A 0xF156 # 0 +0x856B 0xF157 # 0 +0x856C 0xF158 # 0 +0x856D 0xF159 # 0 +0x856E 0xF15A # 0 +0x856F 0xF15B # 0 +0x8570 0xF15C # 0 +0x8571 0xF15D # 0 +0x8572 0xF15E # 0 +0x8573 0xF15F # 0 +0x8574 0xF160 # 0 +0x8575 0xF161 # 0 +0x8576 0xF162 # 0 +0x8577 0xF163 # 0 +0x8578 0xF164 # 0 +0x8579 0xF165 # 0 +0x857A 0xF166 # 0 +0x857B 0xF167 # 0 +0x857C 0xF168 # 0 +0x857D 0xF169 # 0 +0x857E 0xF16A # 0 +0x85A1 0xF16B # 0 +0x85A2 0xF16C # 0 +0x85A3 0xF16D # 0 +0x85A4 0xF16E # 0 +0x85A5 0xF16F # 0 +0x85A6 0xF170 # 0 +0x85A7 0xF171 # 0 +0x85A8 0xF172 # 0 +0x85A9 0xF173 # 0 +0x85AA 0xF174 # 0 +0x85AB 0xF175 # 0 +0x85AC 0xF176 # 0 +0x85AD 0xF177 # 0 +0x85AE 0xF178 # 0 +0x85AF 0xF179 # 0 +0x85B0 0xF17A # 0 +0x85B1 0xF17B # 0 +0x85B2 0xF17C # 0 +0x85B3 0xF17D # 0 +0x85B4 0xF17E # 0 +0x85B5 0xF17F # 0 +0x85B6 0xF180 # 0 +0x85B7 0xF181 # 0 +0x85B8 0xF182 # 0 +0x85B9 0xF183 # 0 +0x85BA 0xF184 # 0 +0x85BB 0xF185 # 0 +0x85BC 0xF186 # 0 +0x85BD 0xF187 # 0 +0x85BE 0xF188 # 0 +0x85BF 0xF189 # 0 +0x85C0 0xF18A # 0 +0x85C1 0xF18B # 0 +0x85C2 0xF18C # 0 +0x85C3 0xF18D # 0 +0x85C4 0xF18E # 0 +0x85C5 0xF18F # 0 +0x85C6 0xF190 # 0 +0x85C7 0xF191 # 0 +0x85C8 0xF192 # 0 +0x85C9 0xF193 # 0 +0x85CA 0xF194 # 0 +0x85CB 0xF195 # 0 +0x85CC 0xF196 # 0 +0x85CD 0xF197 # 0 +0x85CE 0xF198 # 0 +0x85CF 0xF199 # 0 +0x85D0 0xF19A # 0 +0x85D1 0xF19B # 0 +0x85D2 0xF19C # 0 +0x85D3 0xF19D # 0 +0x85D4 0xF19E # 0 +0x85D5 0xF19F # 0 +0x85D6 0xF1A0 # 0 +0x85D7 0xF1A1 # 0 +0x85D8 0xF1A2 # 0 +0x85D9 0xF1A3 # 0 +0x85DA 0xF1A4 # 0 +0x85DB 0xF1A5 # 0 +0x85DC 0xF1A6 # 0 +0x85DD 0xF1A7 # 0 +0x85DE 0xF1A8 # 0 +0x85DF 0xF1A9 # 0 +0x85E0 0xF1AA # 0 +0x85E1 0xF1AB # 0 +0x85E2 0xF1AC # 0 +0x85E3 0xF1AD # 0 +0x85E4 0xF1AE # 0 +0x85E5 0xF1AF # 0 +0x85E6 0xF1B0 # 0 +0x85E7 0xF1B1 # 0 +0x85E8 0xF1B2 # 0 +0x85E9 0xF1B3 # 0 +0x85EA 0xF1B4 # 0 +0x85EB 0xF1B5 # 0 +0x85EC 0xF1B6 # 0 +0x85ED 0xF1B7 # 0 +0x85EE 0xF1B8 # 0 +0x85EF 0xF1B9 # 0 +0x85F0 0xF1BA # 0 +0x85F1 0xF1BB # 0 +0x85F2 0xF1BC # 0 +0x85F3 0xF1BD # 0 +0x85F4 0xF1BE # 0 +0x85F5 0xF1BF # 0 +0x85F6 0xF1C0 # 0 +0x85F7 0xF1C1 # 0 +0x85F8 0xF1C2 # 0 +0x85F9 0xF1C3 # 0 +0x85FA 0xF1C4 # 0 +0x85FB 0xF1C5 # 0 +0x85FC 0xF1C6 # 0 +0x85FD 0xF1C7 # 0 +0x85FE 0xF1C8 # 0 +0x8640 0xF1C9 # 0 +0x8641 0xF1CA # 0 +0x8642 0xF1CB # 0 +0x8643 0xF1CC # 0 +0x8644 0xF1CD # 0 +0x8645 0xF1CE # 0 +0x8646 0xF1CF # 0 +0x8647 0xF1D0 # 0 +0x8648 0xF1D1 # 0 +0x8649 0xF1D2 # 0 +0x864A 0xF1D3 # 0 +0x864B 0xF1D4 # 0 +0x864C 0xF1D5 # 0 +0x864D 0xF1D6 # 0 +0x864E 0xF1D7 # 0 +0x864F 0xF1D8 # 0 +0x8650 0xF1D9 # 0 +0x8651 0xF1DA # 0 +0x8652 0xF1DB # 0 +0x8653 0xF1DC # 0 +0x8654 0xF1DD # 0 +0x8655 0xF1DE # 0 +0x8656 0xF1DF # 0 +0x8657 0xF1E0 # 0 +0x8658 0xF1E1 # 0 +0x8659 0xF1E2 # 0 +0x865A 0xF1E3 # 0 +0x865B 0xF1E4 # 0 +0x865C 0xF1E5 # 0 +0x865D 0xF1E6 # 0 +0x865E 0xF1E7 # 0 +0x865F 0xF1E8 # 0 +0x8660 0xF1E9 # 0 +0x8661 0xF1EA # 0 +0x8662 0xF1EB # 0 +0x8663 0xF1EC # 0 +0x8664 0xF1ED # 0 +0x8665 0xF1EE # 0 +0x8666 0xF1EF # 0 +0x8667 0xF1F0 # 0 +0x8668 0xF1F1 # 0 +0x8669 0xF1F2 # 0 +0x866A 0xF1F3 # 0 +0x866B 0xF1F4 # 0 +0x866C 0xF1F5 # 0 +0x866D 0xF1F6 # 0 +0x866E 0xF1F7 # 0 +0x866F 0xF1F8 # 0 +0x8670 0xF1F9 # 0 +0x8671 0xF1FA # 0 +0x8672 0xF1FB # 0 +0x8673 0xF1FC # 0 +0x8674 0xF1FD # 0 +0x8675 0xF1FE # 0 +0x8676 0xF1FF # 0 +0x8677 0xF200 # 0 +0x8678 0xF201 # 0 +0x8679 0xF202 # 0 +0x867A 0xF203 # 0 +0x867B 0xF204 # 0 +0x867C 0xF205 # 0 +0x867D 0xF206 # 0 +0x867E 0xF207 # 0 +0x86A1 0xF208 # 0 +0x86A2 0xF209 # 0 +0x86A3 0xF20A # 0 +0x86A4 0xF20B # 0 +0x86A5 0xF20C # 0 +0x86A6 0xF20D # 0 +0x86A7 0xF20E # 0 +0x86A8 0xF20F # 0 +0x86A9 0xF210 # 0 +0x86AA 0xF211 # 0 +0x86AB 0xF212 # 0 +0x86AC 0xF213 # 0 +0x86AD 0xF214 # 0 +0x86AE 0xF215 # 0 +0x86AF 0xF216 # 0 +0x86B0 0xF217 # 0 +0x86B1 0xF218 # 0 +0x86B2 0xF219 # 0 +0x86B3 0xF21A # 0 +0x86B4 0xF21B # 0 +0x86B5 0xF21C # 0 +0x86B6 0xF21D # 0 +0x86B7 0xF21E # 0 +0x86B8 0xF21F # 0 +0x86B9 0xF220 # 0 +0x86BA 0xF221 # 0 +0x86BB 0xF222 # 0 +0x86BC 0xF223 # 0 +0x86BD 0xF224 # 0 +0x86BE 0xF225 # 0 +0x86BF 0xF226 # 0 +0x86C0 0xF227 # 0 +0x86C1 0xF228 # 0 +0x86C2 0xF229 # 0 +0x86C3 0xF22A # 0 +0x86C4 0xF22B # 0 +0x86C5 0xF22C # 0 +0x86C6 0xF22D # 0 +0x86C7 0xF22E # 0 +0x86C8 0xF22F # 0 +0x86C9 0xF230 # 0 +0x86CA 0xF231 # 0 +0x86CB 0xF232 # 0 +0x86CC 0xF233 # 0 +0x86CD 0xF234 # 0 +0x86CE 0xF235 # 0 +0x86CF 0xF236 # 0 +0x86D0 0xF237 # 0 +0x86D1 0xF238 # 0 +0x86D2 0xF239 # 0 +0x86D3 0xF23A # 0 +0x86D4 0xF23B # 0 +0x86D5 0xF23C # 0 +0x86D6 0xF23D # 0 +0x86D7 0xF23E # 0 +0x86D8 0xF23F # 0 +0x86D9 0xF240 # 0 +0x86DA 0xF241 # 0 +0x86DB 0xF242 # 0 +0x86DC 0xF243 # 0 +0x86DD 0xF244 # 0 +0x86DE 0xF245 # 0 +0x86DF 0xF246 # 0 +0x86E0 0xF247 # 0 +0x86E1 0xF248 # 0 +0x86E2 0xF249 # 0 +0x86E3 0xF24A # 0 +0x86E4 0xF24B # 0 +0x86E5 0xF24C # 0 +0x86E6 0xF24D # 0 +0x86E7 0xF24E # 0 +0x86E8 0xF24F # 0 +0x86E9 0xF250 # 0 +0x86EA 0xF251 # 0 +0x86EB 0xF252 # 0 +0x86EC 0xF253 # 0 +0x86ED 0xF254 # 0 +0x86EE 0xF255 # 0 +0x86EF 0xF256 # 0 +0x86F0 0xF257 # 0 +0x86F1 0xF258 # 0 +0x86F2 0xF259 # 0 +0x86F3 0xF25A # 0 +0x86F4 0xF25B # 0 +0x86F5 0xF25C # 0 +0x86F6 0xF25D # 0 +0x86F7 0xF25E # 0 +0x86F8 0xF25F # 0 +0x86F9 0xF260 # 0 +0x86FA 0xF261 # 0 +0x86FB 0xF262 # 0 +0x86FC 0xF263 # 0 +0x86FD 0xF264 # 0 +0x86FE 0xF265 # 0 +0x8740 0xF266 # 0 +0x8741 0xF267 # 0 +0x8742 0xF268 # 0 +0x8743 0xF269 # 0 +0x8744 0xF26A # 0 +0x8745 0xF26B # 0 +0x8746 0xF26C # 0 +0x8747 0xF26D # 0 +0x8748 0xF26E # 0 +0x8749 0xF26F # 0 +0x874A 0xF270 # 0 +0x874B 0xF271 # 0 +0x874C 0xF272 # 0 +0x874D 0xF273 # 0 +0x874E 0xF274 # 0 +0x874F 0xF275 # 0 +0x8750 0xF276 # 0 +0x8751 0xF277 # 0 +0x8752 0xF278 # 0 +0x8753 0xF279 # 0 +0x8754 0xF27A # 0 +0x8755 0xF27B # 0 +0x8756 0xF27C # 0 +0x8757 0xF27D # 0 +0x8758 0xF27E # 0 +0x8759 0xF27F # 0 +0x875A 0xF280 # 0 +0x875B 0xF281 # 0 +0x875C 0xF282 # 0 +0x875D 0xF283 # 0 +0x875E 0xF284 # 0 +0x875F 0xF285 # 0 +0x8760 0xF286 # 0 +0x8761 0xF287 # 0 +0x8762 0xF288 # 0 +0x8763 0xF289 # 0 +0x8764 0xF28A # 0 +0x8765 0xF28B # 0 +0x8766 0xF28C # 0 +0x8767 0xF28D # 0 +0x8768 0xF28E # 0 +0x8769 0xF28F # 0 +0x876A 0xF290 # 0 +0x876B 0xF291 # 0 +0x876C 0xF292 # 0 +0x876D 0xF293 # 0 +0x876E 0xF294 # 0 +0x876F 0xF295 # 0 +0x8770 0xF296 # 0 +0x8771 0xF297 # 0 +0x8772 0xF298 # 0 +0x8773 0xF299 # 0 +0x8774 0xF29A # 0 +0x8775 0xF29B # 0 +0x8776 0xF29C # 0 +0x8777 0xF29D # 0 +0x8778 0xF29E # 0 +0x8779 0xF29F # 0 +0x877A 0xF2A0 # 0 +0x877B 0xF2A1 # 0 +0x877C 0xF2A2 # 0 +0x877D 0xF2A3 # 0 +0x877E 0xF2A4 # 0 +0x87A1 0xF2A5 # 0 +0x87A2 0xF2A6 # 0 +0x87A3 0xF2A7 # 0 +0x87A4 0xF2A8 # 0 +0x87A5 0xF2A9 # 0 +0x87A6 0xF2AA # 0 +0x87A7 0xF2AB # 0 +0x87A8 0xF2AC # 0 +0x87A9 0xF2AD # 0 +0x87AA 0xF2AE # 0 +0x87AB 0xF2AF # 0 +0x87AC 0xF2B0 # 0 +0x87AD 0xF2B1 # 0 +0x87AE 0xF2B2 # 0 +0x87AF 0xF2B3 # 0 +0x87B0 0xF2B4 # 0 +0x87B1 0xF2B5 # 0 +0x87B2 0xF2B6 # 0 +0x87B3 0xF2B7 # 0 +0x87B4 0xF2B8 # 0 +0x87B5 0xF2B9 # 0 +0x87B6 0xF2BA # 0 +0x87B7 0xF2BB # 0 +0x87B8 0xF2BC # 0 +0x87B9 0xF2BD # 0 +0x87BA 0xF2BE # 0 +0x87BB 0xF2BF # 0 +0x87BC 0xF2C0 # 0 +0x87BD 0xF2C1 # 0 +0x87BE 0xF2C2 # 0 +0x87BF 0xF2C3 # 0 +0x87C0 0xF2C4 # 0 +0x87C1 0xF2C5 # 0 +0x87C2 0xF2C6 # 0 +0x87C3 0xF2C7 # 0 +0x87C4 0xF2C8 # 0 +0x87C5 0xF2C9 # 0 +0x87C6 0xF2CA # 0 +0x87C7 0xF2CB # 0 +0x87C8 0xF2CC # 0 +0x87C9 0xF2CD # 0 +0x87CA 0xF2CE # 0 +0x87CB 0xF2CF # 0 +0x87CC 0xF2D0 # 0 +0x87CD 0xF2D1 # 0 +0x87CE 0xF2D2 # 0 +0x87CF 0xF2D3 # 0 +0x87D0 0xF2D4 # 0 +0x87D1 0xF2D5 # 0 +0x87D2 0xF2D6 # 0 +0x87D3 0xF2D7 # 0 +0x87D4 0xF2D8 # 0 +0x87D5 0xF2D9 # 0 +0x87D6 0xF2DA # 0 +0x87D7 0xF2DB # 0 +0x87D8 0xF2DC # 0 +0x87D9 0xF2DD # 0 +0x87DA 0xF2DE # 0 +0x87DB 0xF2DF # 0 +0x87DC 0xF2E0 # 0 +0x87DD 0xF2E1 # 0 +0x87DE 0xF2E2 # 0 +0x87DF 0xF2E3 # 0 +0x87E0 0xF2E4 # 0 +0x87E1 0xF2E5 # 0 +0x87E2 0xF2E6 # 0 +0x87E3 0xF2E7 # 0 +0x87E4 0xF2E8 # 0 +0x87E5 0xF2E9 # 0 +0x87E6 0xF2EA # 0 +0x87E7 0xF2EB # 0 +0x87E8 0xF2EC # 0 +0x87E9 0xF2ED # 0 +0x87EA 0xF2EE # 0 +0x87EB 0xF2EF # 0 +0x87EC 0xF2F0 # 0 +0x87ED 0xF2F1 # 0 +0x87EE 0xF2F2 # 0 +0x87EF 0xF2F3 # 0 +0x87F0 0xF2F4 # 0 +0x87F1 0xF2F5 # 0 +0x87F2 0xF2F6 # 0 +0x87F3 0xF2F7 # 0 +0x87F4 0xF2F8 # 0 +0x87F5 0xF2F9 # 0 +0x87F6 0xF2FA # 0 +0x87F7 0xF2FB # 0 +0x87F8 0xF2FC # 0 +0x87F9 0xF2FD # 0 +0x87FA 0xF2FE # 0 +0x87FB 0xF2FF # 0 +0x87FC 0xF300 # 0 +0x87FD 0xF301 # 0 +0x87FE 0xF302 # 0 +0x8840 0xF303 # 0 +0x8841 0xF304 # 0 +0x8842 0xF305 # 0 +0x8843 0xF306 # 0 +0x8844 0xF307 # 0 +0x8845 0xF308 # 0 +0x8846 0xF309 # 0 +0x8847 0xF30A # 0 +0x8848 0xF30B # 0 +0x8849 0xF30C # 0 +0x884A 0xF30D # 0 +0x884B 0xF30E # 0 +0x884C 0xF30F # 0 +0x884D 0xF310 # 0 +0x884E 0xF311 # 0 +0x884F 0xF312 # 0 +0x8850 0xF313 # 0 +0x8851 0xF314 # 0 +0x8852 0xF315 # 0 +0x8853 0xF316 # 0 +0x8854 0xF317 # 0 +0x8855 0xF318 # 0 +0x8856 0xF319 # 0 +0x8857 0xF31A # 0 +0x8858 0xF31B # 0 +0x8859 0xF31C # 0 +0x885A 0xF31D # 0 +0x885B 0xF31E # 0 +0x885C 0xF31F # 0 +0x885D 0xF320 # 0 +0x885E 0xF321 # 0 +0x885F 0xF322 # 0 +0x8860 0xF323 # 0 +0x8861 0xF324 # 0 +0x8862 0xF325 # 0 +0x8863 0xF326 # 0 +0x8864 0xF327 # 0 +0x8865 0xF328 # 0 +0x8866 0xF329 # 0 +0x8867 0xF32A # 0 +0x8868 0xF32B # 0 +0x8869 0xF32C # 0 +0x886A 0xF32D # 0 +0x886B 0xF32E # 0 +0x886C 0xF32F # 0 +0x886D 0xF330 # 0 +0x886E 0xF331 # 0 +0x886F 0xF332 # 0 +0x8870 0xF333 # 0 +0x8871 0xF334 # 0 +0x8872 0xF335 # 0 +0x8873 0xF336 # 0 +0x8874 0xF337 # 0 +0x8875 0xF338 # 0 +0x8876 0xF339 # 0 +0x8877 0xF33A # 0 +0x8878 0xF33B # 0 +0x8879 0xF33C # 0 +0x887A 0xF33D # 0 +0x887B 0xF33E # 0 +0x887C 0xF33F # 0 +0x887D 0xF340 # 0 +0x887E 0xF341 # 0 +0x88A1 0xF342 # 0 +0x88A2 0xF343 # 0 +0x88A3 0xF344 # 0 +0x88A4 0xF345 # 0 +0x88A5 0xF346 # 0 +0x88A6 0xF347 # 0 +0x88A7 0xF348 # 0 +0x88A8 0xF349 # 0 +0x88A9 0xF34A # 0 +0x88AA 0xF34B # 0 +0x88AB 0xF34C # 0 +0x88AC 0xF34D # 0 +0x88AD 0xF34E # 0 +0x88AE 0xF34F # 0 +0x88AF 0xF350 # 0 +0x88B0 0xF351 # 0 +0x88B1 0xF352 # 0 +0x88B2 0xF353 # 0 +0x88B3 0xF354 # 0 +0x88B4 0xF355 # 0 +0x88B5 0xF356 # 0 +0x88B6 0xF357 # 0 +0x88B7 0xF358 # 0 +0x88B8 0xF359 # 0 +0x88B9 0xF35A # 0 +0x88BA 0xF35B # 0 +0x88BB 0xF35C # 0 +0x88BC 0xF35D # 0 +0x88BD 0xF35E # 0 +0x88BE 0xF35F # 0 +0x88BF 0xF360 # 0 +0x88C0 0xF361 # 0 +0x88C1 0xF362 # 0 +0x88C2 0xF363 # 0 +0x88C3 0xF364 # 0 +0x88C4 0xF365 # 0 +0x88C5 0xF366 # 0 +0x88C6 0xF367 # 0 +0x88C7 0xF368 # 0 +0x88C8 0xF369 # 0 +0x88C9 0xF36A # 0 +0x88CA 0xF36B # 0 +0x88CB 0xF36C # 0 +0x88CC 0xF36D # 0 +0x88CD 0xF36E # 0 +0x88CE 0xF36F # 0 +0x88CF 0xF370 # 0 +0x88D0 0xF371 # 0 +0x88D1 0xF372 # 0 +0x88D2 0xF373 # 0 +0x88D3 0xF374 # 0 +0x88D4 0xF375 # 0 +0x88D5 0xF376 # 0 +0x88D6 0xF377 # 0 +0x88D7 0xF378 # 0 +0x88D8 0xF379 # 0 +0x88D9 0xF37A # 0 +0x88DA 0xF37B # 0 +0x88DB 0xF37C # 0 +0x88DC 0xF37D # 0 +0x88DD 0xF37E # 0 +0x88DE 0xF37F # 0 +0x88DF 0xF380 # 0 +0x88E0 0xF381 # 0 +0x88E1 0xF382 # 0 +0x88E2 0xF383 # 0 +0x88E3 0xF384 # 0 +0x88E4 0xF385 # 0 +0x88E5 0xF386 # 0 +0x88E6 0xF387 # 0 +0x88E7 0xF388 # 0 +0x88E8 0xF389 # 0 +0x88E9 0xF38A # 0 +0x88EA 0xF38B # 0 +0x88EB 0xF38C # 0 +0x88EC 0xF38D # 0 +0x88ED 0xF38E # 0 +0x88EE 0xF38F # 0 +0x88EF 0xF390 # 0 +0x88F0 0xF391 # 0 +0x88F1 0xF392 # 0 +0x88F2 0xF393 # 0 +0x88F3 0xF394 # 0 +0x88F4 0xF395 # 0 +0x88F5 0xF396 # 0 +0x88F6 0xF397 # 0 +0x88F7 0xF398 # 0 +0x88F8 0xF399 # 0 +0x88F9 0xF39A # 0 +0x88FA 0xF39B # 0 +0x88FB 0xF39C # 0 +0x88FC 0xF39D # 0 +0x88FD 0xF39E # 0 +0x88FE 0xF39F # 0 +0x8940 0xF3A0 # 0 +0x8941 0xF3A1 # 0 +0x8942 0xF3A2 # 0 +0x8943 0xF3A3 # 0 +0x8944 0xF3A4 # 0 +0x8945 0xF3A5 # 0 +0x8946 0xF3A6 # 0 +0x8947 0xF3A7 # 0 +0x8948 0xF3A8 # 0 +0x8949 0xF3A9 # 0 +0x894A 0xF3AA # 0 +0x894B 0xF3AB # 0 +0x894C 0xF3AC # 0 +0x894D 0xF3AD # 0 +0x894E 0xF3AE # 0 +0x894F 0xF3AF # 0 +0x8950 0xF3B0 # 0 +0x8951 0xF3B1 # 0 +0x8952 0xF3B2 # 0 +0x8953 0xF3B3 # 0 +0x8954 0xF3B4 # 0 +0x8955 0xF3B5 # 0 +0x8956 0xF3B6 # 0 +0x8957 0xF3B7 # 0 +0x8958 0xF3B8 # 0 +0x8959 0xF3B9 # 0 +0x895A 0xF3BA # 0 +0x895B 0xF3BB # 0 +0x895C 0xF3BC # 0 +0x895D 0xF3BD # 0 +0x895E 0xF3BE # 0 +0x895F 0xF3BF # 0 +0x8960 0xF3C0 # 0 +0x8961 0xF3C1 # 0 +0x8962 0xF3C2 # 0 +0x8963 0xF3C3 # 0 +0x8964 0xF3C4 # 0 +0x8965 0xF3C5 # 0 +0x8966 0xF3C6 # 0 +0x8967 0xF3C7 # 0 +0x8968 0xF3C8 # 0 +0x8969 0xF3C9 # 0 +0x896A 0xF3CA # 0 +0x896B 0xF3CB # 0 +0x896C 0xF3CC # 0 +0x896D 0xF3CD # 0 +0x896E 0xF3CE # 0 +0x896F 0xF3CF # 0 +0x8970 0xF3D0 # 0 +0x8971 0xF3D1 # 0 +0x8972 0xF3D2 # 0 +0x8973 0xF3D3 # 0 +0x8974 0xF3D4 # 0 +0x8975 0xF3D5 # 0 +0x8976 0xF3D6 # 0 +0x8977 0xF3D7 # 0 +0x8978 0xF3D8 # 0 +0x8979 0xF3D9 # 0 +0x897A 0xF3DA # 0 +0x897B 0xF3DB # 0 +0x897C 0xF3DC # 0 +0x897D 0xF3DD # 0 +0x897E 0xF3DE # 0 +0x89A1 0xF3DF # 0 +0x89A2 0xF3E0 # 0 +0x89A3 0xF3E1 # 0 +0x89A4 0xF3E2 # 0 +0x89A5 0xF3E3 # 0 +0x89A6 0xF3E4 # 0 +0x89A7 0xF3E5 # 0 +0x89A8 0xF3E6 # 0 +0x89A9 0xF3E7 # 0 +0x89AA 0xF3E8 # 0 +0x89AB 0xF3E9 # 0 +0x89AC 0xF3EA # 0 +0x89AD 0xF3EB # 0 +0x89AE 0xF3EC # 0 +0x89AF 0xF3ED # 0 +0x89B0 0xF3EE # 0 +0x89B1 0xF3EF # 0 +0x89B2 0xF3F0 # 0 +0x89B3 0xF3F1 # 0 +0x89B4 0xF3F2 # 0 +0x89B5 0xF3F3 # 0 +0x89B6 0xF3F4 # 0 +0x89B7 0xF3F5 # 0 +0x89B8 0xF3F6 # 0 +0x89B9 0xF3F7 # 0 +0x89BA 0xF3F8 # 0 +0x89BB 0xF3F9 # 0 +0x89BC 0xF3FA # 0 +0x89BD 0xF3FB # 0 +0x89BE 0xF3FC # 0 +0x89BF 0xF3FD # 0 +0x89C0 0xF3FE # 0 +0x89C1 0xF3FF # 0 +0x89C2 0xF400 # 0 +0x89C3 0xF401 # 0 +0x89C4 0xF402 # 0 +0x89C5 0xF403 # 0 +0x89C6 0xF404 # 0 +0x89C7 0xF405 # 0 +0x89C8 0xF406 # 0 +0x89C9 0xF407 # 0 +0x89CA 0xF408 # 0 +0x89CB 0xF409 # 0 +0x89CC 0xF40A # 0 +0x89CD 0xF40B # 0 +0x89CE 0xF40C # 0 +0x89CF 0xF40D # 0 +0x89D0 0xF40E # 0 +0x89D1 0xF40F # 0 +0x89D2 0xF410 # 0 +0x89D3 0xF411 # 0 +0x89D4 0xF412 # 0 +0x89D5 0xF413 # 0 +0x89D6 0xF414 # 0 +0x89D7 0xF415 # 0 +0x89D8 0xF416 # 0 +0x89D9 0xF417 # 0 +0x89DA 0xF418 # 0 +0x89DB 0xF419 # 0 +0x89DC 0xF41A # 0 +0x89DD 0xF41B # 0 +0x89DE 0xF41C # 0 +0x89DF 0xF41D # 0 +0x89E0 0xF41E # 0 +0x89E1 0xF41F # 0 +0x89E2 0xF420 # 0 +0x89E3 0xF421 # 0 +0x89E4 0xF422 # 0 +0x89E5 0xF423 # 0 +0x89E6 0xF424 # 0 +0x89E7 0xF425 # 0 +0x89E8 0xF426 # 0 +0x89E9 0xF427 # 0 +0x89EA 0xF428 # 0 +0x89EB 0xF429 # 0 +0x89EC 0xF42A # 0 +0x89ED 0xF42B # 0 +0x89EE 0xF42C # 0 +0x89EF 0xF42D # 0 +0x89F0 0xF42E # 0 +0x89F1 0xF42F # 0 +0x89F2 0xF430 # 0 +0x89F3 0xF431 # 0 +0x89F4 0xF432 # 0 +0x89F5 0xF433 # 0 +0x89F6 0xF434 # 0 +0x89F7 0xF435 # 0 +0x89F8 0xF436 # 0 +0x89F9 0xF437 # 0 +0x89FA 0xF438 # 0 +0x89FB 0xF439 # 0 +0x89FC 0xF43A # 0 +0x89FD 0xF43B # 0 +0x89FE 0xF43C # 0 +0x8A40 0xF43D # 0 +0x8A41 0xF43E # 0 +0x8A42 0xF43F # 0 +0x8A43 0xF440 # 0 +0x8A44 0xF441 # 0 +0x8A45 0xF442 # 0 +0x8A46 0xF443 # 0 +0x8A47 0xF444 # 0 +0x8A48 0xF445 # 0 +0x8A49 0xF446 # 0 +0x8A4A 0xF447 # 0 +0x8A4B 0xF448 # 0 +0x8A4C 0xF449 # 0 +0x8A4D 0xF44A # 0 +0x8A4E 0xF44B # 0 +0x8A4F 0xF44C # 0 +0x8A50 0xF44D # 0 +0x8A51 0xF44E # 0 +0x8A52 0xF44F # 0 +0x8A53 0xF450 # 0 +0x8A54 0xF451 # 0 +0x8A55 0xF452 # 0 +0x8A56 0xF453 # 0 +0x8A57 0xF454 # 0 +0x8A58 0xF455 # 0 +0x8A59 0xF456 # 0 +0x8A5A 0xF457 # 0 +0x8A5B 0xF458 # 0 +0x8A5C 0xF459 # 0 +0x8A5D 0xF45A # 0 +0x8A5E 0xF45B # 0 +0x8A5F 0xF45C # 0 +0x8A60 0xF45D # 0 +0x8A61 0xF45E # 0 +0x8A62 0xF45F # 0 +0x8A63 0xF460 # 0 +0x8A64 0xF461 # 0 +0x8A65 0xF462 # 0 +0x8A66 0xF463 # 0 +0x8A67 0xF464 # 0 +0x8A68 0xF465 # 0 +0x8A69 0xF466 # 0 +0x8A6A 0xF467 # 0 +0x8A6B 0xF468 # 0 +0x8A6C 0xF469 # 0 +0x8A6D 0xF46A # 0 +0x8A6E 0xF46B # 0 +0x8A6F 0xF46C # 0 +0x8A70 0xF46D # 0 +0x8A71 0xF46E # 0 +0x8A72 0xF46F # 0 +0x8A73 0xF470 # 0 +0x8A74 0xF471 # 0 +0x8A75 0xF472 # 0 +0x8A76 0xF473 # 0 +0x8A77 0xF474 # 0 +0x8A78 0xF475 # 0 +0x8A79 0xF476 # 0 +0x8A7A 0xF477 # 0 +0x8A7B 0xF478 # 0 +0x8A7C 0xF479 # 0 +0x8A7D 0xF47A # 0 +0x8A7E 0xF47B # 0 +0x8AA1 0xF47C # 0 +0x8AA2 0xF47D # 0 +0x8AA3 0xF47E # 0 +0x8AA4 0xF47F # 0 +0x8AA5 0xF480 # 0 +0x8AA6 0xF481 # 0 +0x8AA7 0xF482 # 0 +0x8AA8 0xF483 # 0 +0x8AA9 0xF484 # 0 +0x8AAA 0xF485 # 0 +0x8AAB 0xF486 # 0 +0x8AAC 0xF487 # 0 +0x8AAD 0xF488 # 0 +0x8AAE 0xF489 # 0 +0x8AAF 0xF48A # 0 +0x8AB0 0xF48B # 0 +0x8AB1 0xF48C # 0 +0x8AB2 0xF48D # 0 +0x8AB3 0xF48E # 0 +0x8AB4 0xF48F # 0 +0x8AB5 0xF490 # 0 +0x8AB6 0xF491 # 0 +0x8AB7 0xF492 # 0 +0x8AB8 0xF493 # 0 +0x8AB9 0xF494 # 0 +0x8ABA 0xF495 # 0 +0x8ABB 0xF496 # 0 +0x8ABC 0xF497 # 0 +0x8ABD 0xF498 # 0 +0x8ABE 0xF499 # 0 +0x8ABF 0xF49A # 0 +0x8AC0 0xF49B # 0 +0x8AC1 0xF49C # 0 +0x8AC2 0xF49D # 0 +0x8AC3 0xF49E # 0 +0x8AC4 0xF49F # 0 +0x8AC5 0xF4A0 # 0 +0x8AC6 0xF4A1 # 0 +0x8AC7 0xF4A2 # 0 +0x8AC8 0xF4A3 # 0 +0x8AC9 0xF4A4 # 0 +0x8ACA 0xF4A5 # 0 +0x8ACB 0xF4A6 # 0 +0x8ACC 0xF4A7 # 0 +0x8ACD 0xF4A8 # 0 +0x8ACE 0xF4A9 # 0 +0x8ACF 0xF4AA # 0 +0x8AD0 0xF4AB # 0 +0x8AD1 0xF4AC # 0 +0x8AD2 0xF4AD # 0 +0x8AD3 0xF4AE # 0 +0x8AD4 0xF4AF # 0 +0x8AD5 0xF4B0 # 0 +0x8AD6 0xF4B1 # 0 +0x8AD7 0xF4B2 # 0 +0x8AD8 0xF4B3 # 0 +0x8AD9 0xF4B4 # 0 +0x8ADA 0xF4B5 # 0 +0x8ADB 0xF4B6 # 0 +0x8ADC 0xF4B7 # 0 +0x8ADD 0xF4B8 # 0 +0x8ADE 0xF4B9 # 0 +0x8ADF 0xF4BA # 0 +0x8AE0 0xF4BB # 0 +0x8AE1 0xF4BC # 0 +0x8AE2 0xF4BD # 0 +0x8AE3 0xF4BE # 0 +0x8AE4 0xF4BF # 0 +0x8AE5 0xF4C0 # 0 +0x8AE6 0xF4C1 # 0 +0x8AE7 0xF4C2 # 0 +0x8AE8 0xF4C3 # 0 +0x8AE9 0xF4C4 # 0 +0x8AEA 0xF4C5 # 0 +0x8AEB 0xF4C6 # 0 +0x8AEC 0xF4C7 # 0 +0x8AED 0xF4C8 # 0 +0x8AEE 0xF4C9 # 0 +0x8AEF 0xF4CA # 0 +0x8AF0 0xF4CB # 0 +0x8AF1 0xF4CC # 0 +0x8AF2 0xF4CD # 0 +0x8AF3 0xF4CE # 0 +0x8AF4 0xF4CF # 0 +0x8AF5 0xF4D0 # 0 +0x8AF6 0xF4D1 # 0 +0x8AF7 0xF4D2 # 0 +0x8AF8 0xF4D3 # 0 +0x8AF9 0xF4D4 # 0 +0x8AFA 0xF4D5 # 0 +0x8AFB 0xF4D6 # 0 +0x8AFC 0xF4D7 # 0 +0x8AFD 0xF4D8 # 0 +0x8AFE 0xF4D9 # 0 +0x8B40 0xF4DA # 0 +0x8B41 0xF4DB # 0 +0x8B42 0xF4DC # 0 +0x8B43 0xF4DD # 0 +0x8B44 0xF4DE # 0 +0x8B45 0xF4DF # 0 +0x8B46 0xF4E0 # 0 +0x8B47 0xF4E1 # 0 +0x8B48 0xF4E2 # 0 +0x8B49 0xF4E3 # 0 +0x8B4A 0xF4E4 # 0 +0x8B4B 0xF4E5 # 0 +0x8B4C 0xF4E6 # 0 +0x8B4D 0xF4E7 # 0 +0x8B4E 0xF4E8 # 0 +0x8B4F 0xF4E9 # 0 +0x8B50 0xF4EA # 0 +0x8B51 0xF4EB # 0 +0x8B52 0xF4EC # 0 +0x8B53 0xF4ED # 0 +0x8B54 0xF4EE # 0 +0x8B55 0xF4EF # 0 +0x8B56 0xF4F0 # 0 +0x8B57 0xF4F1 # 0 +0x8B58 0xF4F2 # 0 +0x8B59 0xF4F3 # 0 +0x8B5A 0xF4F4 # 0 +0x8B5B 0xF4F5 # 0 +0x8B5C 0xF4F6 # 0 +0x8B5D 0xF4F7 # 0 +0x8B5E 0xF4F8 # 0 +0x8B5F 0xF4F9 # 0 +0x8B60 0xF4FA # 0 +0x8B61 0xF4FB # 0 +0x8B62 0xF4FC # 0 +0x8B63 0xF4FD # 0 +0x8B64 0xF4FE # 0 +0x8B65 0xF4FF # 0 +0x8B66 0xF500 # 0 +0x8B67 0xF501 # 0 +0x8B68 0xF502 # 0 +0x8B69 0xF503 # 0 +0x8B6A 0xF504 # 0 +0x8B6B 0xF505 # 0 +0x8B6C 0xF506 # 0 +0x8B6D 0xF507 # 0 +0x8B6E 0xF508 # 0 +0x8B6F 0xF509 # 0 +0x8B70 0xF50A # 0 +0x8B71 0xF50B # 0 +0x8B72 0xF50C # 0 +0x8B73 0xF50D # 0 +0x8B74 0xF50E # 0 +0x8B75 0xF50F # 0 +0x8B76 0xF510 # 0 +0x8B77 0xF511 # 0 +0x8B78 0xF512 # 0 +0x8B79 0xF513 # 0 +0x8B7A 0xF514 # 0 +0x8B7B 0xF515 # 0 +0x8B7C 0xF516 # 0 +0x8B7D 0xF517 # 0 +0x8B7E 0xF518 # 0 +0x8BA1 0xF519 # 0 +0x8BA2 0xF51A # 0 +0x8BA3 0xF51B # 0 +0x8BA4 0xF51C # 0 +0x8BA5 0xF51D # 0 +0x8BA6 0xF51E # 0 +0x8BA7 0xF51F # 0 +0x8BA8 0xF520 # 0 +0x8BA9 0xF521 # 0 +0x8BAA 0xF522 # 0 +0x8BAB 0xF523 # 0 +0x8BAC 0xF524 # 0 +0x8BAD 0xF525 # 0 +0x8BAE 0xF526 # 0 +0x8BAF 0xF527 # 0 +0x8BB0 0xF528 # 0 +0x8BB1 0xF529 # 0 +0x8BB2 0xF52A # 0 +0x8BB3 0xF52B # 0 +0x8BB4 0xF52C # 0 +0x8BB5 0xF52D # 0 +0x8BB6 0xF52E # 0 +0x8BB7 0xF52F # 0 +0x8BB8 0xF530 # 0 +0x8BB9 0xF531 # 0 +0x8BBA 0xF532 # 0 +0x8BBB 0xF533 # 0 +0x8BBC 0xF534 # 0 +0x8BBD 0xF535 # 0 +0x8BBE 0xF536 # 0 +0x8BBF 0xF537 # 0 +0x8BC0 0xF538 # 0 +0x8BC1 0xF539 # 0 +0x8BC2 0xF53A # 0 +0x8BC3 0xF53B # 0 +0x8BC4 0xF53C # 0 +0x8BC5 0xF53D # 0 +0x8BC6 0xF53E # 0 +0x8BC7 0xF53F # 0 +0x8BC8 0xF540 # 0 +0x8BC9 0xF541 # 0 +0x8BCA 0xF542 # 0 +0x8BCB 0xF543 # 0 +0x8BCC 0xF544 # 0 +0x8BCD 0xF545 # 0 +0x8BCE 0xF546 # 0 +0x8BCF 0xF547 # 0 +0x8BD0 0xF548 # 0 +0x8BD1 0xF549 # 0 +0x8BD2 0xF54A # 0 +0x8BD3 0xF54B # 0 +0x8BD4 0xF54C # 0 +0x8BD5 0xF54D # 0 +0x8BD6 0xF54E # 0 +0x8BD7 0xF54F # 0 +0x8BD8 0xF550 # 0 +0x8BD9 0xF551 # 0 +0x8BDA 0xF552 # 0 +0x8BDB 0xF553 # 0 +0x8BDC 0xF554 # 0 +0x8BDD 0xF555 # 0 +0x8BDE 0xF556 # 0 +0x8BDF 0xF557 # 0 +0x8BE0 0xF558 # 0 +0x8BE1 0xF559 # 0 +0x8BE2 0xF55A # 0 +0x8BE3 0xF55B # 0 +0x8BE4 0xF55C # 0 +0x8BE5 0xF55D # 0 +0x8BE6 0xF55E # 0 +0x8BE7 0xF55F # 0 +0x8BE8 0xF560 # 0 +0x8BE9 0xF561 # 0 +0x8BEA 0xF562 # 0 +0x8BEB 0xF563 # 0 +0x8BEC 0xF564 # 0 +0x8BED 0xF565 # 0 +0x8BEE 0xF566 # 0 +0x8BEF 0xF567 # 0 +0x8BF0 0xF568 # 0 +0x8BF1 0xF569 # 0 +0x8BF2 0xF56A # 0 +0x8BF3 0xF56B # 0 +0x8BF4 0xF56C # 0 +0x8BF5 0xF56D # 0 +0x8BF6 0xF56E # 0 +0x8BF7 0xF56F # 0 +0x8BF8 0xF570 # 0 +0x8BF9 0xF571 # 0 +0x8BFA 0xF572 # 0 +0x8BFB 0xF573 # 0 +0x8BFC 0xF574 # 0 +0x8BFD 0xF575 # 0 +0x8BFE 0xF576 # 0 +0x8C40 0xF577 # 0 +0x8C41 0xF578 # 0 +0x8C42 0xF579 # 0 +0x8C43 0xF57A # 0 +0x8C44 0xF57B # 0 +0x8C45 0xF57C # 0 +0x8C46 0xF57D # 0 +0x8C47 0xF57E # 0 +0x8C48 0xF57F # 0 +0x8C49 0xF580 # 0 +0x8C4A 0xF581 # 0 +0x8C4B 0xF582 # 0 +0x8C4C 0xF583 # 0 +0x8C4D 0xF584 # 0 +0x8C4E 0xF585 # 0 +0x8C4F 0xF586 # 0 +0x8C50 0xF587 # 0 +0x8C51 0xF588 # 0 +0x8C52 0xF589 # 0 +0x8C53 0xF58A # 0 +0x8C54 0xF58B # 0 +0x8C55 0xF58C # 0 +0x8C56 0xF58D # 0 +0x8C57 0xF58E # 0 +0x8C58 0xF58F # 0 +0x8C59 0xF590 # 0 +0x8C5A 0xF591 # 0 +0x8C5B 0xF592 # 0 +0x8C5C 0xF593 # 0 +0x8C5D 0xF594 # 0 +0x8C5E 0xF595 # 0 +0x8C5F 0xF596 # 0 +0x8C60 0xF597 # 0 +0x8C61 0xF598 # 0 +0x8C62 0xF599 # 0 +0x8C63 0xF59A # 0 +0x8C64 0xF59B # 0 +0x8C65 0xF59C # 0 +0x8C66 0xF59D # 0 +0x8C67 0xF59E # 0 +0x8C68 0xF59F # 0 +0x8C69 0xF5A0 # 0 +0x8C6A 0xF5A1 # 0 +0x8C6B 0xF5A2 # 0 +0x8C6C 0xF5A3 # 0 +0x8C6D 0xF5A4 # 0 +0x8C6E 0xF5A5 # 0 +0x8C6F 0xF5A6 # 0 +0x8C70 0xF5A7 # 0 +0x8C71 0xF5A8 # 0 +0x8C72 0xF5A9 # 0 +0x8C73 0xF5AA # 0 +0x8C74 0xF5AB # 0 +0x8C75 0xF5AC # 0 +0x8C76 0xF5AD # 0 +0x8C77 0xF5AE # 0 +0x8C78 0xF5AF # 0 +0x8C79 0xF5B0 # 0 +0x8C7A 0xF5B1 # 0 +0x8C7B 0xF5B2 # 0 +0x8C7C 0xF5B3 # 0 +0x8C7D 0xF5B4 # 0 +0x8C7E 0xF5B5 # 0 +0x8CA1 0xF5B6 # 0 +0x8CA2 0xF5B7 # 0 +0x8CA3 0xF5B8 # 0 +0x8CA4 0xF5B9 # 0 +0x8CA5 0xF5BA # 0 +0x8CA6 0xF5BB # 0 +0x8CA7 0xF5BC # 0 +0x8CA8 0xF5BD # 0 +0x8CA9 0xF5BE # 0 +0x8CAA 0xF5BF # 0 +0x8CAB 0xF5C0 # 0 +0x8CAC 0xF5C1 # 0 +0x8CAD 0xF5C2 # 0 +0x8CAE 0xF5C3 # 0 +0x8CAF 0xF5C4 # 0 +0x8CB0 0xF5C5 # 0 +0x8CB1 0xF5C6 # 0 +0x8CB2 0xF5C7 # 0 +0x8CB3 0xF5C8 # 0 +0x8CB4 0xF5C9 # 0 +0x8CB5 0xF5CA # 0 +0x8CB6 0xF5CB # 0 +0x8CB7 0xF5CC # 0 +0x8CB8 0xF5CD # 0 +0x8CB9 0xF5CE # 0 +0x8CBA 0xF5CF # 0 +0x8CBB 0xF5D0 # 0 +0x8CBC 0xF5D1 # 0 +0x8CBD 0xF5D2 # 0 +0x8CBE 0xF5D3 # 0 +0x8CBF 0xF5D4 # 0 +0x8CC0 0xF5D5 # 0 +0x8CC1 0xF5D6 # 0 +0x8CC2 0xF5D7 # 0 +0x8CC3 0xF5D8 # 0 +0x8CC4 0xF5D9 # 0 +0x8CC5 0xF5DA # 0 +0x8CC6 0xF5DB # 0 +0x8CC7 0xF5DC # 0 +0x8CC8 0xF5DD # 0 +0x8CC9 0xF5DE # 0 +0x8CCA 0xF5DF # 0 +0x8CCB 0xF5E0 # 0 +0x8CCC 0xF5E1 # 0 +0x8CCD 0xF5E2 # 0 +0x8CCE 0xF5E3 # 0 +0x8CCF 0xF5E4 # 0 +0x8CD0 0xF5E5 # 0 +0x8CD1 0xF5E6 # 0 +0x8CD2 0xF5E7 # 0 +0x8CD3 0xF5E8 # 0 +0x8CD4 0xF5E9 # 0 +0x8CD5 0xF5EA # 0 +0x8CD6 0xF5EB # 0 +0x8CD7 0xF5EC # 0 +0x8CD8 0xF5ED # 0 +0x8CD9 0xF5EE # 0 +0x8CDA 0xF5EF # 0 +0x8CDB 0xF5F0 # 0 +0x8CDC 0xF5F1 # 0 +0x8CDD 0xF5F2 # 0 +0x8CDE 0xF5F3 # 0 +0x8CDF 0xF5F4 # 0 +0x8CE0 0xF5F5 # 0 +0x8CE1 0xF5F6 # 0 +0x8CE2 0xF5F7 # 0 +0x8CE3 0xF5F8 # 0 +0x8CE4 0xF5F9 # 0 +0x8CE5 0xF5FA # 0 +0x8CE6 0xF5FB # 0 +0x8CE7 0xF5FC # 0 +0x8CE8 0xF5FD # 0 +0x8CE9 0xF5FE # 0 +0x8CEA 0xF5FF # 0 +0x8CEB 0xF600 # 0 +0x8CEC 0xF601 # 0 +0x8CED 0xF602 # 0 +0x8CEE 0xF603 # 0 +0x8CEF 0xF604 # 0 +0x8CF0 0xF605 # 0 +0x8CF1 0xF606 # 0 +0x8CF2 0xF607 # 0 +0x8CF3 0xF608 # 0 +0x8CF4 0xF609 # 0 +0x8CF5 0xF60A # 0 +0x8CF6 0xF60B # 0 +0x8CF7 0xF60C # 0 +0x8CF8 0xF60D # 0 +0x8CF9 0xF60E # 0 +0x8CFA 0xF60F # 0 +0x8CFB 0xF610 # 0 +0x8CFC 0xF611 # 0 +0x8CFD 0xF612 # 0 +0x8CFE 0xF613 # 0 +0x8D40 0xF614 # 0 +0x8D41 0xF615 # 0 +0x8D42 0xF616 # 0 +0x8D43 0xF617 # 0 +0x8D44 0xF618 # 0 +0x8D45 0xF619 # 0 +0x8D46 0xF61A # 0 +0x8D47 0xF61B # 0 +0x8D48 0xF61C # 0 +0x8D49 0xF61D # 0 +0x8D4A 0xF61E # 0 +0x8D4B 0xF61F # 0 +0x8D4C 0xF620 # 0 +0x8D4D 0xF621 # 0 +0x8D4E 0xF622 # 0 +0x8D4F 0xF623 # 0 +0x8D50 0xF624 # 0 +0x8D51 0xF625 # 0 +0x8D52 0xF626 # 0 +0x8D53 0xF627 # 0 +0x8D54 0xF628 # 0 +0x8D55 0xF629 # 0 +0x8D56 0xF62A # 0 +0x8D57 0xF62B # 0 +0x8D58 0xF62C # 0 +0x8D59 0xF62D # 0 +0x8D5A 0xF62E # 0 +0x8D5B 0xF62F # 0 +0x8D5C 0xF630 # 0 +0x8D5D 0xF631 # 0 +0x8D5E 0xF632 # 0 +0x8D5F 0xF633 # 0 +0x8D60 0xF634 # 0 +0x8D61 0xF635 # 0 +0x8D62 0xF636 # 0 +0x8D63 0xF637 # 0 +0x8D64 0xF638 # 0 +0x8D65 0xF639 # 0 +0x8D66 0xF63A # 0 +0x8D67 0xF63B # 0 +0x8D68 0xF63C # 0 +0x8D69 0xF63D # 0 +0x8D6A 0xF63E # 0 +0x8D6B 0xF63F # 0 +0x8D6C 0xF640 # 0 +0x8D6D 0xF641 # 0 +0x8D6E 0xF642 # 0 +0x8D6F 0xF643 # 0 +0x8D70 0xF644 # 0 +0x8D71 0xF645 # 0 +0x8D72 0xF646 # 0 +0x8D73 0xF647 # 0 +0x8D74 0xF648 # 0 +0x8D75 0xF649 # 0 +0x8D76 0xF64A # 0 +0x8D77 0xF64B # 0 +0x8D78 0xF64C # 0 +0x8D79 0xF64D # 0 +0x8D7A 0xF64E # 0 +0x8D7B 0xF64F # 0 +0x8D7C 0xF650 # 0 +0x8D7D 0xF651 # 0 +0x8D7E 0xF652 # 0 +0x8DA1 0xF653 # 0 +0x8DA2 0xF654 # 0 +0x8DA3 0xF655 # 0 +0x8DA4 0xF656 # 0 +0x8DA5 0xF657 # 0 +0x8DA6 0xF658 # 0 +0x8DA7 0xF659 # 0 +0x8DA8 0xF65A # 0 +0x8DA9 0xF65B # 0 +0x8DAA 0xF65C # 0 +0x8DAB 0xF65D # 0 +0x8DAC 0xF65E # 0 +0x8DAD 0xF65F # 0 +0x8DAE 0xF660 # 0 +0x8DAF 0xF661 # 0 +0x8DB0 0xF662 # 0 +0x8DB1 0xF663 # 0 +0x8DB2 0xF664 # 0 +0x8DB3 0xF665 # 0 +0x8DB4 0xF666 # 0 +0x8DB5 0xF667 # 0 +0x8DB6 0xF668 # 0 +0x8DB7 0xF669 # 0 +0x8DB8 0xF66A # 0 +0x8DB9 0xF66B # 0 +0x8DBA 0xF66C # 0 +0x8DBB 0xF66D # 0 +0x8DBC 0xF66E # 0 +0x8DBD 0xF66F # 0 +0x8DBE 0xF670 # 0 +0x8DBF 0xF671 # 0 +0x8DC0 0xF672 # 0 +0x8DC1 0xF673 # 0 +0x8DC2 0xF674 # 0 +0x8DC3 0xF675 # 0 +0x8DC4 0xF676 # 0 +0x8DC5 0xF677 # 0 +0x8DC6 0xF678 # 0 +0x8DC7 0xF679 # 0 +0x8DC8 0xF67A # 0 +0x8DC9 0xF67B # 0 +0x8DCA 0xF67C # 0 +0x8DCB 0xF67D # 0 +0x8DCC 0xF67E # 0 +0x8DCD 0xF67F # 0 +0x8DCE 0xF680 # 0 +0x8DCF 0xF681 # 0 +0x8DD0 0xF682 # 0 +0x8DD1 0xF683 # 0 +0x8DD2 0xF684 # 0 +0x8DD3 0xF685 # 0 +0x8DD4 0xF686 # 0 +0x8DD5 0xF687 # 0 +0x8DD6 0xF688 # 0 +0x8DD7 0xF689 # 0 +0x8DD8 0xF68A # 0 +0x8DD9 0xF68B # 0 +0x8DDA 0xF68C # 0 +0x8DDB 0xF68D # 0 +0x8DDC 0xF68E # 0 +0x8DDD 0xF68F # 0 +0x8DDE 0xF690 # 0 +0x8DDF 0xF691 # 0 +0x8DE0 0xF692 # 0 +0x8DE1 0xF693 # 0 +0x8DE2 0xF694 # 0 +0x8DE3 0xF695 # 0 +0x8DE4 0xF696 # 0 +0x8DE5 0xF697 # 0 +0x8DE6 0xF698 # 0 +0x8DE7 0xF699 # 0 +0x8DE8 0xF69A # 0 +0x8DE9 0xF69B # 0 +0x8DEA 0xF69C # 0 +0x8DEB 0xF69D # 0 +0x8DEC 0xF69E # 0 +0x8DED 0xF69F # 0 +0x8DEE 0xF6A0 # 0 +0x8DEF 0xF6A1 # 0 +0x8DF0 0xF6A2 # 0 +0x8DF1 0xF6A3 # 0 +0x8DF2 0xF6A4 # 0 +0x8DF3 0xF6A5 # 0 +0x8DF4 0xF6A6 # 0 +0x8DF5 0xF6A7 # 0 +0x8DF6 0xF6A8 # 0 +0x8DF7 0xF6A9 # 0 +0x8DF8 0xF6AA # 0 +0x8DF9 0xF6AB # 0 +0x8DFA 0xF6AC # 0 +0x8DFB 0xF6AD # 0 +0x8DFC 0xF6AE # 0 +0x8DFD 0xF6AF # 0 +0x8DFE 0xF6B0 # 0 +0x8E40 0xE311 # 0 +0x8E41 0xE312 # 0 +0x8E42 0xE313 # 0 +0x8E43 0xE314 # 0 +0x8E44 0xE315 # 0 +0x8E45 0xE316 # 0 +0x8E46 0xE317 # 0 +0x8E47 0xE318 # 0 +0x8E48 0xE319 # 0 +0x8E49 0xE31A # 0 +0x8E4A 0xE31B # 0 +0x8E4B 0xE31C # 0 +0x8E4C 0xE31D # 0 +0x8E4D 0xE31E # 0 +0x8E4E 0xE31F # 0 +0x8E4F 0xE320 # 0 +0x8E50 0xE321 # 0 +0x8E51 0xE322 # 0 +0x8E52 0xE323 # 0 +0x8E53 0xE324 # 0 +0x8E54 0xE325 # 0 +0x8E55 0xE326 # 0 +0x8E56 0xE327 # 0 +0x8E57 0xE328 # 0 +0x8E58 0xE329 # 0 +0x8E59 0xE32A # 0 +0x8E5A 0xE32B # 0 +0x8E5B 0xE32C # 0 +0x8E5C 0xE32D # 0 +0x8E5D 0xE32E # 0 +0x8E5E 0xE32F # 0 +0x8E5F 0xE330 # 0 +0x8E60 0xE331 # 0 +0x8E61 0xE332 # 0 +0x8E62 0xE333 # 0 +0x8E63 0xE334 # 0 +0x8E64 0xE335 # 0 +0x8E65 0xE336 # 0 +0x8E66 0xE337 # 0 +0x8E67 0xE338 # 0 +0x8E68 0xE339 # 0 +0x8E69 0xE33A # 0 +0x8E6A 0xE33B # 0 +0x8E6B 0xE33C # 0 +0x8E6C 0xE33D # 0 +0x8E6D 0xE33E # 0 +0x8E6E 0xE33F # 0 +0x8E6F 0xE340 # 0 +0x8E70 0xE341 # 0 +0x8E71 0xE342 # 0 +0x8E72 0xE343 # 0 +0x8E73 0xE344 # 0 +0x8E74 0xE345 # 0 +0x8E75 0xE346 # 0 +0x8E76 0xE347 # 0 +0x8E77 0xE348 # 0 +0x8E78 0xE349 # 0 +0x8E79 0xE34A # 0 +0x8E7A 0xE34B # 0 +0x8E7B 0xE34C # 0 +0x8E7C 0xE34D # 0 +0x8E7D 0xE34E # 0 +0x8E7E 0xE34F # 0 +0x8EA1 0xE350 # 0 +0x8EA2 0xE351 # 0 +0x8EA3 0xE352 # 0 +0x8EA4 0xE353 # 0 +0x8EA5 0xE354 # 0 +0x8EA6 0xE355 # 0 +0x8EA7 0xE356 # 0 +0x8EA8 0xE357 # 0 +0x8EA9 0xE358 # 0 +0x8EAA 0xE359 # 0 +0x8EAB 0xE35A # 0 +0x8EAC 0xE35B # 0 +0x8EAD 0xE35C # 0 +0x8EAE 0xE35D # 0 +0x8EAF 0xE35E # 0 +0x8EB0 0xE35F # 0 +0x8EB1 0xE360 # 0 +0x8EB2 0xE361 # 0 +0x8EB3 0xE362 # 0 +0x8EB4 0xE363 # 0 +0x8EB5 0xE364 # 0 +0x8EB6 0xE365 # 0 +0x8EB7 0xE366 # 0 +0x8EB8 0xE367 # 0 +0x8EB9 0xE368 # 0 +0x8EBA 0xE369 # 0 +0x8EBB 0xE36A # 0 +0x8EBC 0xE36B # 0 +0x8EBD 0xE36C # 0 +0x8EBE 0xE36D # 0 +0x8EBF 0xE36E # 0 +0x8EC0 0xE36F # 0 +0x8EC1 0xE370 # 0 +0x8EC2 0xE371 # 0 +0x8EC3 0xE372 # 0 +0x8EC4 0xE373 # 0 +0x8EC5 0xE374 # 0 +0x8EC6 0xE375 # 0 +0x8EC7 0xE376 # 0 +0x8EC8 0xE377 # 0 +0x8EC9 0xE378 # 0 +0x8ECA 0xE379 # 0 +0x8ECB 0xE37A # 0 +0x8ECC 0xE37B # 0 +0x8ECD 0xE37C # 0 +0x8ECE 0xE37D # 0 +0x8ECF 0xE37E # 0 +0x8ED0 0xE37F # 0 +0x8ED1 0xE380 # 0 +0x8ED2 0xE381 # 0 +0x8ED3 0xE382 # 0 +0x8ED4 0xE383 # 0 +0x8ED5 0xE384 # 0 +0x8ED6 0xE385 # 0 +0x8ED7 0xE386 # 0 +0x8ED8 0xE387 # 0 +0x8ED9 0xE388 # 0 +0x8EDA 0xE389 # 0 +0x8EDB 0xE38A # 0 +0x8EDC 0xE38B # 0 +0x8EDD 0xE38C # 0 +0x8EDE 0xE38D # 0 +0x8EDF 0xE38E # 0 +0x8EE0 0xE38F # 0 +0x8EE1 0xE390 # 0 +0x8EE2 0xE391 # 0 +0x8EE3 0xE392 # 0 +0x8EE4 0xE393 # 0 +0x8EE5 0xE394 # 0 +0x8EE6 0xE395 # 0 +0x8EE7 0xE396 # 0 +0x8EE8 0xE397 # 0 +0x8EE9 0xE398 # 0 +0x8EEA 0xE399 # 0 +0x8EEB 0xE39A # 0 +0x8EEC 0xE39B # 0 +0x8EED 0xE39C # 0 +0x8EEE 0xE39D # 0 +0x8EEF 0xE39E # 0 +0x8EF0 0xE39F # 0 +0x8EF1 0xE3A0 # 0 +0x8EF2 0xE3A1 # 0 +0x8EF3 0xE3A2 # 0 +0x8EF4 0xE3A3 # 0 +0x8EF5 0xE3A4 # 0 +0x8EF6 0xE3A5 # 0 +0x8EF7 0xE3A6 # 0 +0x8EF8 0xE3A7 # 0 +0x8EF9 0xE3A8 # 0 +0x8EFA 0xE3A9 # 0 +0x8EFB 0xE3AA # 0 +0x8EFC 0xE3AB # 0 +0x8EFD 0xE3AC # 0 +0x8EFE 0xE3AD # 0 +0x8F40 0xE3AE # 0 +0x8F41 0xE3AF # 0 +0x8F42 0xE3B0 # 0 +0x8F43 0xE3B1 # 0 +0x8F44 0xE3B2 # 0 +0x8F45 0xE3B3 # 0 +0x8F46 0xE3B4 # 0 +0x8F47 0xE3B5 # 0 +0x8F48 0xE3B6 # 0 +0x8F49 0xE3B7 # 0 +0x8F4A 0xE3B8 # 0 +0x8F4B 0xE3B9 # 0 +0x8F4C 0xE3BA # 0 +0x8F4D 0xE3BB # 0 +0x8F4E 0xE3BC # 0 +0x8F4F 0xE3BD # 0 +0x8F50 0xE3BE # 0 +0x8F51 0xE3BF # 0 +0x8F52 0xE3C0 # 0 +0x8F53 0xE3C1 # 0 +0x8F54 0xE3C2 # 0 +0x8F55 0xE3C3 # 0 +0x8F56 0xE3C4 # 0 +0x8F57 0xE3C5 # 0 +0x8F58 0xE3C6 # 0 +0x8F59 0xE3C7 # 0 +0x8F5A 0xE3C8 # 0 +0x8F5B 0xE3C9 # 0 +0x8F5C 0xE3CA # 0 +0x8F5D 0xE3CB # 0 +0x8F5E 0xE3CC # 0 +0x8F5F 0xE3CD # 0 +0x8F60 0xE3CE # 0 +0x8F61 0xE3CF # 0 +0x8F62 0xE3D0 # 0 +0x8F63 0xE3D1 # 0 +0x8F64 0xE3D2 # 0 +0x8F65 0xE3D3 # 0 +0x8F66 0xE3D4 # 0 +0x8F67 0xE3D5 # 0 +0x8F68 0xE3D6 # 0 +0x8F69 0xE3D7 # 0 +0x8F6A 0xE3D8 # 0 +0x8F6B 0xE3D9 # 0 +0x8F6C 0xE3DA # 0 +0x8F6D 0xE3DB # 0 +0x8F6E 0xE3DC # 0 +0x8F6F 0xE3DD # 0 +0x8F70 0xE3DE # 0 +0x8F71 0xE3DF # 0 +0x8F72 0xE3E0 # 0 +0x8F73 0xE3E1 # 0 +0x8F74 0xE3E2 # 0 +0x8F75 0xE3E3 # 0 +0x8F76 0xE3E4 # 0 +0x8F77 0xE3E5 # 0 +0x8F78 0xE3E6 # 0 +0x8F79 0xE3E7 # 0 +0x8F7A 0xE3E8 # 0 +0x8F7B 0xE3E9 # 0 +0x8F7C 0xE3EA # 0 +0x8F7D 0xE3EB # 0 +0x8F7E 0xE3EC # 0 +0x8FA1 0xE3ED # 0 +0x8FA2 0xE3EE # 0 +0x8FA3 0xE3EF # 0 +0x8FA4 0xE3F0 # 0 +0x8FA5 0xE3F1 # 0 +0x8FA6 0xE3F2 # 0 +0x8FA7 0xE3F3 # 0 +0x8FA8 0xE3F4 # 0 +0x8FA9 0xE3F5 # 0 +0x8FAA 0xE3F6 # 0 +0x8FAB 0xE3F7 # 0 +0x8FAC 0xE3F8 # 0 +0x8FAD 0xE3F9 # 0 +0x8FAE 0xE3FA # 0 +0x8FAF 0xE3FB # 0 +0x8FB0 0xE3FC # 0 +0x8FB1 0xE3FD # 0 +0x8FB2 0xE3FE # 0 +0x8FB3 0xE3FF # 0 +0x8FB4 0xE400 # 0 +0x8FB5 0xE401 # 0 +0x8FB6 0xE402 # 0 +0x8FB7 0xE403 # 0 +0x8FB8 0xE404 # 0 +0x8FB9 0xE405 # 0 +0x8FBA 0xE406 # 0 +0x8FBB 0xE407 # 0 +0x8FBC 0xE408 # 0 +0x8FBD 0xE409 # 0 +0x8FBE 0xE40A # 0 +0x8FBF 0xE40B # 0 +0x8FC0 0xE40C # 0 +0x8FC1 0xE40D # 0 +0x8FC2 0xE40E # 0 +0x8FC3 0xE40F # 0 +0x8FC4 0xE410 # 0 +0x8FC5 0xE411 # 0 +0x8FC6 0xE412 # 0 +0x8FC7 0xE413 # 0 +0x8FC8 0xE414 # 0 +0x8FC9 0xE415 # 0 +0x8FCA 0xE416 # 0 +0x8FCB 0xE417 # 0 +0x8FCC 0xE418 # 0 +0x8FCD 0xE419 # 0 +0x8FCE 0xE41A # 0 +0x8FCF 0xE41B # 0 +0x8FD0 0xE41C # 0 +0x8FD1 0xE41D # 0 +0x8FD2 0xE41E # 0 +0x8FD3 0xE41F # 0 +0x8FD4 0xE420 # 0 +0x8FD5 0xE421 # 0 +0x8FD6 0xE422 # 0 +0x8FD7 0xE423 # 0 +0x8FD8 0xE424 # 0 +0x8FD9 0xE425 # 0 +0x8FDA 0xE426 # 0 +0x8FDB 0xE427 # 0 +0x8FDC 0xE428 # 0 +0x8FDD 0xE429 # 0 +0x8FDE 0xE42A # 0 +0x8FDF 0xE42B # 0 +0x8FE0 0xE42C # 0 +0x8FE1 0xE42D # 0 +0x8FE2 0xE42E # 0 +0x8FE3 0xE42F # 0 +0x8FE4 0xE430 # 0 +0x8FE5 0xE431 # 0 +0x8FE6 0xE432 # 0 +0x8FE7 0xE433 # 0 +0x8FE8 0xE434 # 0 +0x8FE9 0xE435 # 0 +0x8FEA 0xE436 # 0 +0x8FEB 0xE437 # 0 +0x8FEC 0xE438 # 0 +0x8FED 0xE439 # 0 +0x8FEE 0xE43A # 0 +0x8FEF 0xE43B # 0 +0x8FF0 0xE43C # 0 +0x8FF1 0xE43D # 0 +0x8FF2 0xE43E # 0 +0x8FF3 0xE43F # 0 +0x8FF4 0xE440 # 0 +0x8FF5 0xE441 # 0 +0x8FF6 0xE442 # 0 +0x8FF7 0xE443 # 0 +0x8FF8 0xE444 # 0 +0x8FF9 0xE445 # 0 +0x8FFA 0xE446 # 0 +0x8FFB 0xE447 # 0 +0x8FFC 0xE448 # 0 +0x8FFD 0xE449 # 0 +0x8FFE 0xE44A # 0 +0x9040 0xE44B # 0 +0x9041 0xE44C # 0 +0x9042 0xE44D # 0 +0x9043 0xE44E # 0 +0x9044 0xE44F # 0 +0x9045 0xE450 # 0 +0x9046 0xE451 # 0 +0x9047 0xE452 # 0 +0x9048 0xE453 # 0 +0x9049 0xE454 # 0 +0x904A 0xE455 # 0 +0x904B 0xE456 # 0 +0x904C 0xE457 # 0 +0x904D 0xE458 # 0 +0x904E 0xE459 # 0 +0x904F 0xE45A # 0 +0x9050 0xE45B # 0 +0x9051 0xE45C # 0 +0x9052 0xE45D # 0 +0x9053 0xE45E # 0 +0x9054 0xE45F # 0 +0x9055 0xE460 # 0 +0x9056 0xE461 # 0 +0x9057 0xE462 # 0 +0x9058 0xE463 # 0 +0x9059 0xE464 # 0 +0x905A 0xE465 # 0 +0x905B 0xE466 # 0 +0x905C 0xE467 # 0 +0x905D 0xE468 # 0 +0x905E 0xE469 # 0 +0x905F 0xE46A # 0 +0x9060 0xE46B # 0 +0x9061 0xE46C # 0 +0x9062 0xE46D # 0 +0x9063 0xE46E # 0 +0x9064 0xE46F # 0 +0x9065 0xE470 # 0 +0x9066 0xE471 # 0 +0x9067 0xE472 # 0 +0x9068 0xE473 # 0 +0x9069 0xE474 # 0 +0x906A 0xE475 # 0 +0x906B 0xE476 # 0 +0x906C 0xE477 # 0 +0x906D 0xE478 # 0 +0x906E 0xE479 # 0 +0x906F 0xE47A # 0 +0x9070 0xE47B # 0 +0x9071 0xE47C # 0 +0x9072 0xE47D # 0 +0x9073 0xE47E # 0 +0x9074 0xE47F # 0 +0x9075 0xE480 # 0 +0x9076 0xE481 # 0 +0x9077 0xE482 # 0 +0x9078 0xE483 # 0 +0x9079 0xE484 # 0 +0x907A 0xE485 # 0 +0x907B 0xE486 # 0 +0x907C 0xE487 # 0 +0x907D 0xE488 # 0 +0x907E 0xE489 # 0 +0x90A1 0xE48A # 0 +0x90A2 0xE48B # 0 +0x90A3 0xE48C # 0 +0x90A4 0xE48D # 0 +0x90A5 0xE48E # 0 +0x90A6 0xE48F # 0 +0x90A7 0xE490 # 0 +0x90A8 0xE491 # 0 +0x90A9 0xE492 # 0 +0x90AA 0xE493 # 0 +0x90AB 0xE494 # 0 +0x90AC 0xE495 # 0 +0x90AD 0xE496 # 0 +0x90AE 0xE497 # 0 +0x90AF 0xE498 # 0 +0x90B0 0xE499 # 0 +0x90B1 0xE49A # 0 +0x90B2 0xE49B # 0 +0x90B3 0xE49C # 0 +0x90B4 0xE49D # 0 +0x90B5 0xE49E # 0 +0x90B6 0xE49F # 0 +0x90B7 0xE4A0 # 0 +0x90B8 0xE4A1 # 0 +0x90B9 0xE4A2 # 0 +0x90BA 0xE4A3 # 0 +0x90BB 0xE4A4 # 0 +0x90BC 0xE4A5 # 0 +0x90BD 0xE4A6 # 0 +0x90BE 0xE4A7 # 0 +0x90BF 0xE4A8 # 0 +0x90C0 0xE4A9 # 0 +0x90C1 0xE4AA # 0 +0x90C2 0xE4AB # 0 +0x90C3 0xE4AC # 0 +0x90C4 0xE4AD # 0 +0x90C5 0xE4AE # 0 +0x90C6 0xE4AF # 0 +0x90C7 0xE4B0 # 0 +0x90C8 0xE4B1 # 0 +0x90C9 0xE4B2 # 0 +0x90CA 0xE4B3 # 0 +0x90CB 0xE4B4 # 0 +0x90CC 0xE4B5 # 0 +0x90CD 0xE4B6 # 0 +0x90CE 0xE4B7 # 0 +0x90CF 0xE4B8 # 0 +0x90D0 0xE4B9 # 0 +0x90D1 0xE4BA # 0 +0x90D2 0xE4BB # 0 +0x90D3 0xE4BC # 0 +0x90D4 0xE4BD # 0 +0x90D5 0xE4BE # 0 +0x90D6 0xE4BF # 0 +0x90D7 0xE4C0 # 0 +0x90D8 0xE4C1 # 0 +0x90D9 0xE4C2 # 0 +0x90DA 0xE4C3 # 0 +0x90DB 0xE4C4 # 0 +0x90DC 0xE4C5 # 0 +0x90DD 0xE4C6 # 0 +0x90DE 0xE4C7 # 0 +0x90DF 0xE4C8 # 0 +0x90E0 0xE4C9 # 0 +0x90E1 0xE4CA # 0 +0x90E2 0xE4CB # 0 +0x90E3 0xE4CC # 0 +0x90E4 0xE4CD # 0 +0x90E5 0xE4CE # 0 +0x90E6 0xE4CF # 0 +0x90E7 0xE4D0 # 0 +0x90E8 0xE4D1 # 0 +0x90E9 0xE4D2 # 0 +0x90EA 0xE4D3 # 0 +0x90EB 0xE4D4 # 0 +0x90EC 0xE4D5 # 0 +0x90ED 0xE4D6 # 0 +0x90EE 0xE4D7 # 0 +0x90EF 0xE4D8 # 0 +0x90F0 0xE4D9 # 0 +0x90F1 0xE4DA # 0 +0x90F2 0xE4DB # 0 +0x90F3 0xE4DC # 0 +0x90F4 0xE4DD # 0 +0x90F5 0xE4DE # 0 +0x90F6 0xE4DF # 0 +0x90F7 0xE4E0 # 0 +0x90F8 0xE4E1 # 0 +0x90F9 0xE4E2 # 0 +0x90FA 0xE4E3 # 0 +0x90FB 0xE4E4 # 0 +0x90FC 0xE4E5 # 0 +0x90FD 0xE4E6 # 0 +0x90FE 0xE4E7 # 0 +0x9140 0xE4E8 # 0 +0x9141 0xE4E9 # 0 +0x9142 0xE4EA # 0 +0x9143 0xE4EB # 0 +0x9144 0xE4EC # 0 +0x9145 0xE4ED # 0 +0x9146 0xE4EE # 0 +0x9147 0xE4EF # 0 +0x9148 0xE4F0 # 0 +0x9149 0xE4F1 # 0 +0x914A 0xE4F2 # 0 +0x914B 0xE4F3 # 0 +0x914C 0xE4F4 # 0 +0x914D 0xE4F5 # 0 +0x914E 0xE4F6 # 0 +0x914F 0xE4F7 # 0 +0x9150 0xE4F8 # 0 +0x9151 0xE4F9 # 0 +0x9152 0xE4FA # 0 +0x9153 0xE4FB # 0 +0x9154 0xE4FC # 0 +0x9155 0xE4FD # 0 +0x9156 0xE4FE # 0 +0x9157 0xE4FF # 0 +0x9158 0xE500 # 0 +0x9159 0xE501 # 0 +0x915A 0xE502 # 0 +0x915B 0xE503 # 0 +0x915C 0xE504 # 0 +0x915D 0xE505 # 0 +0x915E 0xE506 # 0 +0x915F 0xE507 # 0 +0x9160 0xE508 # 0 +0x9161 0xE509 # 0 +0x9162 0xE50A # 0 +0x9163 0xE50B # 0 +0x9164 0xE50C # 0 +0x9165 0xE50D # 0 +0x9166 0xE50E # 0 +0x9167 0xE50F # 0 +0x9168 0xE510 # 0 +0x9169 0xE511 # 0 +0x916A 0xE512 # 0 +0x916B 0xE513 # 0 +0x916C 0xE514 # 0 +0x916D 0xE515 # 0 +0x916E 0xE516 # 0 +0x916F 0xE517 # 0 +0x9170 0xE518 # 0 +0x9171 0xE519 # 0 +0x9172 0xE51A # 0 +0x9173 0xE51B # 0 +0x9174 0xE51C # 0 +0x9175 0xE51D # 0 +0x9176 0xE51E # 0 +0x9177 0xE51F # 0 +0x9178 0xE520 # 0 +0x9179 0xE521 # 0 +0x917A 0xE522 # 0 +0x917B 0xE523 # 0 +0x917C 0xE524 # 0 +0x917D 0xE525 # 0 +0x917E 0xE526 # 0 +0x91A1 0xE527 # 0 +0x91A2 0xE528 # 0 +0x91A3 0xE529 # 0 +0x91A4 0xE52A # 0 +0x91A5 0xE52B # 0 +0x91A6 0xE52C # 0 +0x91A7 0xE52D # 0 +0x91A8 0xE52E # 0 +0x91A9 0xE52F # 0 +0x91AA 0xE530 # 0 +0x91AB 0xE531 # 0 +0x91AC 0xE532 # 0 +0x91AD 0xE533 # 0 +0x91AE 0xE534 # 0 +0x91AF 0xE535 # 0 +0x91B0 0xE536 # 0 +0x91B1 0xE537 # 0 +0x91B2 0xE538 # 0 +0x91B3 0xE539 # 0 +0x91B4 0xE53A # 0 +0x91B5 0xE53B # 0 +0x91B6 0xE53C # 0 +0x91B7 0xE53D # 0 +0x91B8 0xE53E # 0 +0x91B9 0xE53F # 0 +0x91BA 0xE540 # 0 +0x91BB 0xE541 # 0 +0x91BC 0xE542 # 0 +0x91BD 0xE543 # 0 +0x91BE 0xE544 # 0 +0x91BF 0xE545 # 0 +0x91C0 0xE546 # 0 +0x91C1 0xE547 # 0 +0x91C2 0xE548 # 0 +0x91C3 0xE549 # 0 +0x91C4 0xE54A # 0 +0x91C5 0xE54B # 0 +0x91C6 0xE54C # 0 +0x91C7 0xE54D # 0 +0x91C8 0xE54E # 0 +0x91C9 0xE54F # 0 +0x91CA 0xE550 # 0 +0x91CB 0xE551 # 0 +0x91CC 0xE552 # 0 +0x91CD 0xE553 # 0 +0x91CE 0xE554 # 0 +0x91CF 0xE555 # 0 +0x91D0 0xE556 # 0 +0x91D1 0xE557 # 0 +0x91D2 0xE558 # 0 +0x91D3 0xE559 # 0 +0x91D4 0xE55A # 0 +0x91D5 0xE55B # 0 +0x91D6 0xE55C # 0 +0x91D7 0xE55D # 0 +0x91D8 0xE55E # 0 +0x91D9 0xE55F # 0 +0x91DA 0xE560 # 0 +0x91DB 0xE561 # 0 +0x91DC 0xE562 # 0 +0x91DD 0xE563 # 0 +0x91DE 0xE564 # 0 +0x91DF 0xE565 # 0 +0x91E0 0xE566 # 0 +0x91E1 0xE567 # 0 +0x91E2 0xE568 # 0 +0x91E3 0xE569 # 0 +0x91E4 0xE56A # 0 +0x91E5 0xE56B # 0 +0x91E6 0xE56C # 0 +0x91E7 0xE56D # 0 +0x91E8 0xE56E # 0 +0x91E9 0xE56F # 0 +0x91EA 0xE570 # 0 +0x91EB 0xE571 # 0 +0x91EC 0xE572 # 0 +0x91ED 0xE573 # 0 +0x91EE 0xE574 # 0 +0x91EF 0xE575 # 0 +0x91F0 0xE576 # 0 +0x91F1 0xE577 # 0 +0x91F2 0xE578 # 0 +0x91F3 0xE579 # 0 +0x91F4 0xE57A # 0 +0x91F5 0xE57B # 0 +0x91F6 0xE57C # 0 +0x91F7 0xE57D # 0 +0x91F8 0xE57E # 0 +0x91F9 0xE57F # 0 +0x91FA 0xE580 # 0 +0x91FB 0xE581 # 0 +0x91FC 0xE582 # 0 +0x91FD 0xE583 # 0 +0x91FE 0xE584 # 0 +0x9240 0xE585 # 0 +0x9241 0xE586 # 0 +0x9242 0xE587 # 0 +0x9243 0xE588 # 0 +0x9244 0xE589 # 0 +0x9245 0xE58A # 0 +0x9246 0xE58B # 0 +0x9247 0xE58C # 0 +0x9248 0xE58D # 0 +0x9249 0xE58E # 0 +0x924A 0xE58F # 0 +0x924B 0xE590 # 0 +0x924C 0xE591 # 0 +0x924D 0xE592 # 0 +0x924E 0xE593 # 0 +0x924F 0xE594 # 0 +0x9250 0xE595 # 0 +0x9251 0xE596 # 0 +0x9252 0xE597 # 0 +0x9253 0xE598 # 0 +0x9254 0xE599 # 0 +0x9255 0xE59A # 0 +0x9256 0xE59B # 0 +0x9257 0xE59C # 0 +0x9258 0xE59D # 0 +0x9259 0xE59E # 0 +0x925A 0xE59F # 0 +0x925B 0xE5A0 # 0 +0x925C 0xE5A1 # 0 +0x925D 0xE5A2 # 0 +0x925E 0xE5A3 # 0 +0x925F 0xE5A4 # 0 +0x9260 0xE5A5 # 0 +0x9261 0xE5A6 # 0 +0x9262 0xE5A7 # 0 +0x9263 0xE5A8 # 0 +0x9264 0xE5A9 # 0 +0x9265 0xE5AA # 0 +0x9266 0xE5AB # 0 +0x9267 0xE5AC # 0 +0x9268 0xE5AD # 0 +0x9269 0xE5AE # 0 +0x926A 0xE5AF # 0 +0x926B 0xE5B0 # 0 +0x926C 0xE5B1 # 0 +0x926D 0xE5B2 # 0 +0x926E 0xE5B3 # 0 +0x926F 0xE5B4 # 0 +0x9270 0xE5B5 # 0 +0x9271 0xE5B6 # 0 +0x9272 0xE5B7 # 0 +0x9273 0xE5B8 # 0 +0x9274 0xE5B9 # 0 +0x9275 0xE5BA # 0 +0x9276 0xE5BB # 0 +0x9277 0xE5BC # 0 +0x9278 0xE5BD # 0 +0x9279 0xE5BE # 0 +0x927A 0xE5BF # 0 +0x927B 0xE5C0 # 0 +0x927C 0xE5C1 # 0 +0x927D 0xE5C2 # 0 +0x927E 0xE5C3 # 0 +0x92A1 0xE5C4 # 0 +0x92A2 0xE5C5 # 0 +0x92A3 0xE5C6 # 0 +0x92A4 0xE5C7 # 0 +0x92A5 0xE5C8 # 0 +0x92A6 0xE5C9 # 0 +0x92A7 0xE5CA # 0 +0x92A8 0xE5CB # 0 +0x92A9 0xE5CC # 0 +0x92AA 0xE5CD # 0 +0x92AB 0xE5CE # 0 +0x92AC 0xE5CF # 0 +0x92AD 0xE5D0 # 0 +0x92AE 0xE5D1 # 0 +0x92AF 0xE5D2 # 0 +0x92B0 0xE5D3 # 0 +0x92B1 0xE5D4 # 0 +0x92B2 0xE5D5 # 0 +0x92B3 0xE5D6 # 0 +0x92B4 0xE5D7 # 0 +0x92B5 0xE5D8 # 0 +0x92B6 0xE5D9 # 0 +0x92B7 0xE5DA # 0 +0x92B8 0xE5DB # 0 +0x92B9 0xE5DC # 0 +0x92BA 0xE5DD # 0 +0x92BB 0xE5DE # 0 +0x92BC 0xE5DF # 0 +0x92BD 0xE5E0 # 0 +0x92BE 0xE5E1 # 0 +0x92BF 0xE5E2 # 0 +0x92C0 0xE5E3 # 0 +0x92C1 0xE5E4 # 0 +0x92C2 0xE5E5 # 0 +0x92C3 0xE5E6 # 0 +0x92C4 0xE5E7 # 0 +0x92C5 0xE5E8 # 0 +0x92C6 0xE5E9 # 0 +0x92C7 0xE5EA # 0 +0x92C8 0xE5EB # 0 +0x92C9 0xE5EC # 0 +0x92CA 0xE5ED # 0 +0x92CB 0xE5EE # 0 +0x92CC 0xE5EF # 0 +0x92CD 0xE5F0 # 0 +0x92CE 0xE5F1 # 0 +0x92CF 0xE5F2 # 0 +0x92D0 0xE5F3 # 0 +0x92D1 0xE5F4 # 0 +0x92D2 0xE5F5 # 0 +0x92D3 0xE5F6 # 0 +0x92D4 0xE5F7 # 0 +0x92D5 0xE5F8 # 0 +0x92D6 0xE5F9 # 0 +0x92D7 0xE5FA # 0 +0x92D8 0xE5FB # 0 +0x92D9 0xE5FC # 0 +0x92DA 0xE5FD # 0 +0x92DB 0xE5FE # 0 +0x92DC 0xE5FF # 0 +0x92DD 0xE600 # 0 +0x92DE 0xE601 # 0 +0x92DF 0xE602 # 0 +0x92E0 0xE603 # 0 +0x92E1 0xE604 # 0 +0x92E2 0xE605 # 0 +0x92E3 0xE606 # 0 +0x92E4 0xE607 # 0 +0x92E5 0xE608 # 0 +0x92E6 0xE609 # 0 +0x92E7 0xE60A # 0 +0x92E8 0xE60B # 0 +0x92E9 0xE60C # 0 +0x92EA 0xE60D # 0 +0x92EB 0xE60E # 0 +0x92EC 0xE60F # 0 +0x92ED 0xE610 # 0 +0x92EE 0xE611 # 0 +0x92EF 0xE612 # 0 +0x92F0 0xE613 # 0 +0x92F1 0xE614 # 0 +0x92F2 0xE615 # 0 +0x92F3 0xE616 # 0 +0x92F4 0xE617 # 0 +0x92F5 0xE618 # 0 +0x92F6 0xE619 # 0 +0x92F7 0xE61A # 0 +0x92F8 0xE61B # 0 +0x92F9 0xE61C # 0 +0x92FA 0xE61D # 0 +0x92FB 0xE61E # 0 +0x92FC 0xE61F # 0 +0x92FD 0xE620 # 0 +0x92FE 0xE621 # 0 +0x9340 0xE622 # 0 +0x9341 0xE623 # 0 +0x9342 0xE624 # 0 +0x9343 0xE625 # 0 +0x9344 0xE626 # 0 +0x9345 0xE627 # 0 +0x9346 0xE628 # 0 +0x9347 0xE629 # 0 +0x9348 0xE62A # 0 +0x9349 0xE62B # 0 +0x934A 0xE62C # 0 +0x934B 0xE62D # 0 +0x934C 0xE62E # 0 +0x934D 0xE62F # 0 +0x934E 0xE630 # 0 +0x934F 0xE631 # 0 +0x9350 0xE632 # 0 +0x9351 0xE633 # 0 +0x9352 0xE634 # 0 +0x9353 0xE635 # 0 +0x9354 0xE636 # 0 +0x9355 0xE637 # 0 +0x9356 0xE638 # 0 +0x9357 0xE639 # 0 +0x9358 0xE63A # 0 +0x9359 0xE63B # 0 +0x935A 0xE63C # 0 +0x935B 0xE63D # 0 +0x935C 0xE63E # 0 +0x935D 0xE63F # 0 +0x935E 0xE640 # 0 +0x935F 0xE641 # 0 +0x9360 0xE642 # 0 +0x9361 0xE643 # 0 +0x9362 0xE644 # 0 +0x9363 0xE645 # 0 +0x9364 0xE646 # 0 +0x9365 0xE647 # 0 +0x9366 0xE648 # 0 +0x9367 0xE649 # 0 +0x9368 0xE64A # 0 +0x9369 0xE64B # 0 +0x936A 0xE64C # 0 +0x936B 0xE64D # 0 +0x936C 0xE64E # 0 +0x936D 0xE64F # 0 +0x936E 0xE650 # 0 +0x936F 0xE651 # 0 +0x9370 0xE652 # 0 +0x9371 0xE653 # 0 +0x9372 0xE654 # 0 +0x9373 0xE655 # 0 +0x9374 0xE656 # 0 +0x9375 0xE657 # 0 +0x9376 0xE658 # 0 +0x9377 0xE659 # 0 +0x9378 0xE65A # 0 +0x9379 0xE65B # 0 +0x937A 0xE65C # 0 +0x937B 0xE65D # 0 +0x937C 0xE65E # 0 +0x937D 0xE65F # 0 +0x937E 0xE660 # 0 +0x93A1 0xE661 # 0 +0x93A2 0xE662 # 0 +0x93A3 0xE663 # 0 +0x93A4 0xE664 # 0 +0x93A5 0xE665 # 0 +0x93A6 0xE666 # 0 +0x93A7 0xE667 # 0 +0x93A8 0xE668 # 0 +0x93A9 0xE669 # 0 +0x93AA 0xE66A # 0 +0x93AB 0xE66B # 0 +0x93AC 0xE66C # 0 +0x93AD 0xE66D # 0 +0x93AE 0xE66E # 0 +0x93AF 0xE66F # 0 +0x93B0 0xE670 # 0 +0x93B1 0xE671 # 0 +0x93B2 0xE672 # 0 +0x93B3 0xE673 # 0 +0x93B4 0xE674 # 0 +0x93B5 0xE675 # 0 +0x93B6 0xE676 # 0 +0x93B7 0xE677 # 0 +0x93B8 0xE678 # 0 +0x93B9 0xE679 # 0 +0x93BA 0xE67A # 0 +0x93BB 0xE67B # 0 +0x93BC 0xE67C # 0 +0x93BD 0xE67D # 0 +0x93BE 0xE67E # 0 +0x93BF 0xE67F # 0 +0x93C0 0xE680 # 0 +0x93C1 0xE681 # 0 +0x93C2 0xE682 # 0 +0x93C3 0xE683 # 0 +0x93C4 0xE684 # 0 +0x93C5 0xE685 # 0 +0x93C6 0xE686 # 0 +0x93C7 0xE687 # 0 +0x93C8 0xE688 # 0 +0x93C9 0xE689 # 0 +0x93CA 0xE68A # 0 +0x93CB 0xE68B # 0 +0x93CC 0xE68C # 0 +0x93CD 0xE68D # 0 +0x93CE 0xE68E # 0 +0x93CF 0xE68F # 0 +0x93D0 0xE690 # 0 +0x93D1 0xE691 # 0 +0x93D2 0xE692 # 0 +0x93D3 0xE693 # 0 +0x93D4 0xE694 # 0 +0x93D5 0xE695 # 0 +0x93D6 0xE696 # 0 +0x93D7 0xE697 # 0 +0x93D8 0xE698 # 0 +0x93D9 0xE699 # 0 +0x93DA 0xE69A # 0 +0x93DB 0xE69B # 0 +0x93DC 0xE69C # 0 +0x93DD 0xE69D # 0 +0x93DE 0xE69E # 0 +0x93DF 0xE69F # 0 +0x93E0 0xE6A0 # 0 +0x93E1 0xE6A1 # 0 +0x93E2 0xE6A2 # 0 +0x93E3 0xE6A3 # 0 +0x93E4 0xE6A4 # 0 +0x93E5 0xE6A5 # 0 +0x93E6 0xE6A6 # 0 +0x93E7 0xE6A7 # 0 +0x93E8 0xE6A8 # 0 +0x93E9 0xE6A9 # 0 +0x93EA 0xE6AA # 0 +0x93EB 0xE6AB # 0 +0x93EC 0xE6AC # 0 +0x93ED 0xE6AD # 0 +0x93EE 0xE6AE # 0 +0x93EF 0xE6AF # 0 +0x93F0 0xE6B0 # 0 +0x93F1 0xE6B1 # 0 +0x93F2 0xE6B2 # 0 +0x93F3 0xE6B3 # 0 +0x93F4 0xE6B4 # 0 +0x93F5 0xE6B5 # 0 +0x93F6 0xE6B6 # 0 +0x93F7 0xE6B7 # 0 +0x93F8 0xE6B8 # 0 +0x93F9 0xE6B9 # 0 +0x93FA 0xE6BA # 0 +0x93FB 0xE6BB # 0 +0x93FC 0xE6BC # 0 +0x93FD 0xE6BD # 0 +0x93FE 0xE6BE # 0 +0x9440 0xE6BF # 0 +0x9441 0xE6C0 # 0 +0x9442 0xE6C1 # 0 +0x9443 0xE6C2 # 0 +0x9444 0xE6C3 # 0 +0x9445 0xE6C4 # 0 +0x9446 0xE6C5 # 0 +0x9447 0xE6C6 # 0 +0x9448 0xE6C7 # 0 +0x9449 0xE6C8 # 0 +0x944A 0xE6C9 # 0 +0x944B 0xE6CA # 0 +0x944C 0xE6CB # 0 +0x944D 0xE6CC # 0 +0x944E 0xE6CD # 0 +0x944F 0xE6CE # 0 +0x9450 0xE6CF # 0 +0x9451 0xE6D0 # 0 +0x9452 0xE6D1 # 0 +0x9453 0xE6D2 # 0 +0x9454 0xE6D3 # 0 +0x9455 0xE6D4 # 0 +0x9456 0xE6D5 # 0 +0x9457 0xE6D6 # 0 +0x9458 0xE6D7 # 0 +0x9459 0xE6D8 # 0 +0x945A 0xE6D9 # 0 +0x945B 0xE6DA # 0 +0x945C 0xE6DB # 0 +0x945D 0xE6DC # 0 +0x945E 0xE6DD # 0 +0x945F 0xE6DE # 0 +0x9460 0xE6DF # 0 +0x9461 0xE6E0 # 0 +0x9462 0xE6E1 # 0 +0x9463 0xE6E2 # 0 +0x9464 0xE6E3 # 0 +0x9465 0xE6E4 # 0 +0x9466 0xE6E5 # 0 +0x9467 0xE6E6 # 0 +0x9468 0xE6E7 # 0 +0x9469 0xE6E8 # 0 +0x946A 0xE6E9 # 0 +0x946B 0xE6EA # 0 +0x946C 0xE6EB # 0 +0x946D 0xE6EC # 0 +0x946E 0xE6ED # 0 +0x946F 0xE6EE # 0 +0x9470 0xE6EF # 0 +0x9471 0xE6F0 # 0 +0x9472 0xE6F1 # 0 +0x9473 0xE6F2 # 0 +0x9474 0xE6F3 # 0 +0x9475 0xE6F4 # 0 +0x9476 0xE6F5 # 0 +0x9477 0xE6F6 # 0 +0x9478 0xE6F7 # 0 +0x9479 0xE6F8 # 0 +0x947A 0xE6F9 # 0 +0x947B 0xE6FA # 0 +0x947C 0xE6FB # 0 +0x947D 0xE6FC # 0 +0x947E 0xE6FD # 0 +0x94A1 0xE6FE # 0 +0x94A2 0xE6FF # 0 +0x94A3 0xE700 # 0 +0x94A4 0xE701 # 0 +0x94A5 0xE702 # 0 +0x94A6 0xE703 # 0 +0x94A7 0xE704 # 0 +0x94A8 0xE705 # 0 +0x94A9 0xE706 # 0 +0x94AA 0xE707 # 0 +0x94AB 0xE708 # 0 +0x94AC 0xE709 # 0 +0x94AD 0xE70A # 0 +0x94AE 0xE70B # 0 +0x94AF 0xE70C # 0 +0x94B0 0xE70D # 0 +0x94B1 0xE70E # 0 +0x94B2 0xE70F # 0 +0x94B3 0xE710 # 0 +0x94B4 0xE711 # 0 +0x94B5 0xE712 # 0 +0x94B6 0xE713 # 0 +0x94B7 0xE714 # 0 +0x94B8 0xE715 # 0 +0x94B9 0xE716 # 0 +0x94BA 0xE717 # 0 +0x94BB 0xE718 # 0 +0x94BC 0xE719 # 0 +0x94BD 0xE71A # 0 +0x94BE 0xE71B # 0 +0x94BF 0xE71C # 0 +0x94C0 0xE71D # 0 +0x94C1 0xE71E # 0 +0x94C2 0xE71F # 0 +0x94C3 0xE720 # 0 +0x94C4 0xE721 # 0 +0x94C5 0xE722 # 0 +0x94C6 0xE723 # 0 +0x94C7 0xE724 # 0 +0x94C8 0xE725 # 0 +0x94C9 0xE726 # 0 +0x94CA 0xE727 # 0 +0x94CB 0xE728 # 0 +0x94CC 0xE729 # 0 +0x94CD 0xE72A # 0 +0x94CE 0xE72B # 0 +0x94CF 0xE72C # 0 +0x94D0 0xE72D # 0 +0x94D1 0xE72E # 0 +0x94D2 0xE72F # 0 +0x94D3 0xE730 # 0 +0x94D4 0xE731 # 0 +0x94D5 0xE732 # 0 +0x94D6 0xE733 # 0 +0x94D7 0xE734 # 0 +0x94D8 0xE735 # 0 +0x94D9 0xE736 # 0 +0x94DA 0xE737 # 0 +0x94DB 0xE738 # 0 +0x94DC 0xE739 # 0 +0x94DD 0xE73A # 0 +0x94DE 0xE73B # 0 +0x94DF 0xE73C # 0 +0x94E0 0xE73D # 0 +0x94E1 0xE73E # 0 +0x94E2 0xE73F # 0 +0x94E3 0xE740 # 0 +0x94E4 0xE741 # 0 +0x94E5 0xE742 # 0 +0x94E6 0xE743 # 0 +0x94E7 0xE744 # 0 +0x94E8 0xE745 # 0 +0x94E9 0xE746 # 0 +0x94EA 0xE747 # 0 +0x94EB 0xE748 # 0 +0x94EC 0xE749 # 0 +0x94ED 0xE74A # 0 +0x94EE 0xE74B # 0 +0x94EF 0xE74C # 0 +0x94F0 0xE74D # 0 +0x94F1 0xE74E # 0 +0x94F2 0xE74F # 0 +0x94F3 0xE750 # 0 +0x94F4 0xE751 # 0 +0x94F5 0xE752 # 0 +0x94F6 0xE753 # 0 +0x94F7 0xE754 # 0 +0x94F8 0xE755 # 0 +0x94F9 0xE756 # 0 +0x94FA 0xE757 # 0 +0x94FB 0xE758 # 0 +0x94FC 0xE759 # 0 +0x94FD 0xE75A # 0 +0x94FE 0xE75B # 0 +0x9540 0xE75C # 0 +0x9541 0xE75D # 0 +0x9542 0xE75E # 0 +0x9543 0xE75F # 0 +0x9544 0xE760 # 0 +0x9545 0xE761 # 0 +0x9546 0xE762 # 0 +0x9547 0xE763 # 0 +0x9548 0xE764 # 0 +0x9549 0xE765 # 0 +0x954A 0xE766 # 0 +0x954B 0xE767 # 0 +0x954C 0xE768 # 0 +0x954D 0xE769 # 0 +0x954E 0xE76A # 0 +0x954F 0xE76B # 0 +0x9550 0xE76C # 0 +0x9551 0xE76D # 0 +0x9552 0xE76E # 0 +0x9553 0xE76F # 0 +0x9554 0xE770 # 0 +0x9555 0xE771 # 0 +0x9556 0xE772 # 0 +0x9557 0xE773 # 0 +0x9558 0xE774 # 0 +0x9559 0xE775 # 0 +0x955A 0xE776 # 0 +0x955B 0xE777 # 0 +0x955C 0xE778 # 0 +0x955D 0xE779 # 0 +0x955E 0xE77A # 0 +0x955F 0xE77B # 0 +0x9560 0xE77C # 0 +0x9561 0xE77D # 0 +0x9562 0xE77E # 0 +0x9563 0xE77F # 0 +0x9564 0xE780 # 0 +0x9565 0xE781 # 0 +0x9566 0xE782 # 0 +0x9567 0xE783 # 0 +0x9568 0xE784 # 0 +0x9569 0xE785 # 0 +0x956A 0xE786 # 0 +0x956B 0xE787 # 0 +0x956C 0xE788 # 0 +0x956D 0xE789 # 0 +0x956E 0xE78A # 0 +0x956F 0xE78B # 0 +0x9570 0xE78C # 0 +0x9571 0xE78D # 0 +0x9572 0xE78E # 0 +0x9573 0xE78F # 0 +0x9574 0xE790 # 0 +0x9575 0xE791 # 0 +0x9576 0xE792 # 0 +0x9577 0xE793 # 0 +0x9578 0xE794 # 0 +0x9579 0xE795 # 0 +0x957A 0xE796 # 0 +0x957B 0xE797 # 0 +0x957C 0xE798 # 0 +0x957D 0xE799 # 0 +0x957E 0xE79A # 0 +0x95A1 0xE79B # 0 +0x95A2 0xE79C # 0 +0x95A3 0xE79D # 0 +0x95A4 0xE79E # 0 +0x95A5 0xE79F # 0 +0x95A6 0xE7A0 # 0 +0x95A7 0xE7A1 # 0 +0x95A8 0xE7A2 # 0 +0x95A9 0xE7A3 # 0 +0x95AA 0xE7A4 # 0 +0x95AB 0xE7A5 # 0 +0x95AC 0xE7A6 # 0 +0x95AD 0xE7A7 # 0 +0x95AE 0xE7A8 # 0 +0x95AF 0xE7A9 # 0 +0x95B0 0xE7AA # 0 +0x95B1 0xE7AB # 0 +0x95B2 0xE7AC # 0 +0x95B3 0xE7AD # 0 +0x95B4 0xE7AE # 0 +0x95B5 0xE7AF # 0 +0x95B6 0xE7B0 # 0 +0x95B7 0xE7B1 # 0 +0x95B8 0xE7B2 # 0 +0x95B9 0xE7B3 # 0 +0x95BA 0xE7B4 # 0 +0x95BB 0xE7B5 # 0 +0x95BC 0xE7B6 # 0 +0x95BD 0xE7B7 # 0 +0x95BE 0xE7B8 # 0 +0x95BF 0xE7B9 # 0 +0x95C0 0xE7BA # 0 +0x95C1 0xE7BB # 0 +0x95C2 0xE7BC # 0 +0x95C3 0xE7BD # 0 +0x95C4 0xE7BE # 0 +0x95C5 0xE7BF # 0 +0x95C6 0xE7C0 # 0 +0x95C7 0xE7C1 # 0 +0x95C8 0xE7C2 # 0 +0x95C9 0xE7C3 # 0 +0x95CA 0xE7C4 # 0 +0x95CB 0xE7C5 # 0 +0x95CC 0xE7C6 # 0 +0x95CD 0xE7C7 # 0 +0x95CE 0xE7C8 # 0 +0x95CF 0xE7C9 # 0 +0x95D0 0xE7CA # 0 +0x95D1 0xE7CB # 0 +0x95D2 0xE7CC # 0 +0x95D3 0xE7CD # 0 +0x95D4 0xE7CE # 0 +0x95D5 0xE7CF # 0 +0x95D6 0xE7D0 # 0 +0x95D7 0xE7D1 # 0 +0x95D8 0xE7D2 # 0 +0x95D9 0xE7D3 # 0 +0x95DA 0xE7D4 # 0 +0x95DB 0xE7D5 # 0 +0x95DC 0xE7D6 # 0 +0x95DD 0xE7D7 # 0 +0x95DE 0xE7D8 # 0 +0x95DF 0xE7D9 # 0 +0x95E0 0xE7DA # 0 +0x95E1 0xE7DB # 0 +0x95E2 0xE7DC # 0 +0x95E3 0xE7DD # 0 +0x95E4 0xE7DE # 0 +0x95E5 0xE7DF # 0 +0x95E6 0xE7E0 # 0 +0x95E7 0xE7E1 # 0 +0x95E8 0xE7E2 # 0 +0x95E9 0xE7E3 # 0 +0x95EA 0xE7E4 # 0 +0x95EB 0xE7E5 # 0 +0x95EC 0xE7E6 # 0 +0x95ED 0xE7E7 # 0 +0x95EE 0xE7E8 # 0 +0x95EF 0xE7E9 # 0 +0x95F0 0xE7EA # 0 +0x95F1 0xE7EB # 0 +0x95F2 0xE7EC # 0 +0x95F3 0xE7ED # 0 +0x95F4 0xE7EE # 0 +0x95F5 0xE7EF # 0 +0x95F6 0xE7F0 # 0 +0x95F7 0xE7F1 # 0 +0x95F8 0xE7F2 # 0 +0x95F9 0xE7F3 # 0 +0x95FA 0xE7F4 # 0 +0x95FB 0xE7F5 # 0 +0x95FC 0xE7F6 # 0 +0x95FD 0xE7F7 # 0 +0x95FE 0xE7F8 # 0 +0x9640 0xE7F9 # 0 +0x9641 0xE7FA # 0 +0x9642 0xE7FB # 0 +0x9643 0xE7FC # 0 +0x9644 0xE7FD # 0 +0x9645 0xE7FE # 0 +0x9646 0xE7FF # 0 +0x9647 0xE800 # 0 +0x9648 0xE801 # 0 +0x9649 0xE802 # 0 +0x964A 0xE803 # 0 +0x964B 0xE804 # 0 +0x964C 0xE805 # 0 +0x964D 0xE806 # 0 +0x964E 0xE807 # 0 +0x964F 0xE808 # 0 +0x9650 0xE809 # 0 +0x9651 0xE80A # 0 +0x9652 0xE80B # 0 +0x9653 0xE80C # 0 +0x9654 0xE80D # 0 +0x9655 0xE80E # 0 +0x9656 0xE80F # 0 +0x9657 0xE810 # 0 +0x9658 0xE811 # 0 +0x9659 0xE812 # 0 +0x965A 0xE813 # 0 +0x965B 0xE814 # 0 +0x965C 0xE815 # 0 +0x965D 0xE816 # 0 +0x965E 0xE817 # 0 +0x965F 0xE818 # 0 +0x9660 0xE819 # 0 +0x9661 0xE81A # 0 +0x9662 0xE81B # 0 +0x9663 0xE81C # 0 +0x9664 0xE81D # 0 +0x9665 0xE81E # 0 +0x9666 0xE81F # 0 +0x9667 0xE820 # 0 +0x9668 0xE821 # 0 +0x9669 0xE822 # 0 +0x966A 0xE823 # 0 +0x966B 0xE824 # 0 +0x966C 0xE825 # 0 +0x966D 0xE826 # 0 +0x966E 0xE827 # 0 +0x966F 0xE828 # 0 +0x9670 0xE829 # 0 +0x9671 0xE82A # 0 +0x9672 0xE82B # 0 +0x9673 0xE82C # 0 +0x9674 0xE82D # 0 +0x9675 0xE82E # 0 +0x9676 0xE82F # 0 +0x9677 0xE830 # 0 +0x9678 0xE831 # 0 +0x9679 0xE832 # 0 +0x967A 0xE833 # 0 +0x967B 0xE834 # 0 +0x967C 0xE835 # 0 +0x967D 0xE836 # 0 +0x967E 0xE837 # 0 +0x96A1 0xE838 # 0 +0x96A2 0xE839 # 0 +0x96A3 0xE83A # 0 +0x96A4 0xE83B # 0 +0x96A5 0xE83C # 0 +0x96A6 0xE83D # 0 +0x96A7 0xE83E # 0 +0x96A8 0xE83F # 0 +0x96A9 0xE840 # 0 +0x96AA 0xE841 # 0 +0x96AB 0xE842 # 0 +0x96AC 0xE843 # 0 +0x96AD 0xE844 # 0 +0x96AE 0xE845 # 0 +0x96AF 0xE846 # 0 +0x96B0 0xE847 # 0 +0x96B1 0xE848 # 0 +0x96B2 0xE849 # 0 +0x96B3 0xE84A # 0 +0x96B4 0xE84B # 0 +0x96B5 0xE84C # 0 +0x96B6 0xE84D # 0 +0x96B7 0xE84E # 0 +0x96B8 0xE84F # 0 +0x96B9 0xE850 # 0 +0x96BA 0xE851 # 0 +0x96BB 0xE852 # 0 +0x96BC 0xE853 # 0 +0x96BD 0xE854 # 0 +0x96BE 0xE855 # 0 +0x96BF 0xE856 # 0 +0x96C0 0xE857 # 0 +0x96C1 0xE858 # 0 +0x96C2 0xE859 # 0 +0x96C3 0xE85A # 0 +0x96C4 0xE85B # 0 +0x96C5 0xE85C # 0 +0x96C6 0xE85D # 0 +0x96C7 0xE85E # 0 +0x96C8 0xE85F # 0 +0x96C9 0xE860 # 0 +0x96CA 0xE861 # 0 +0x96CB 0xE862 # 0 +0x96CC 0xE863 # 0 +0x96CD 0xE864 # 0 +0x96CE 0xE865 # 0 +0x96CF 0xE866 # 0 +0x96D0 0xE867 # 0 +0x96D1 0xE868 # 0 +0x96D2 0xE869 # 0 +0x96D3 0xE86A # 0 +0x96D4 0xE86B # 0 +0x96D5 0xE86C # 0 +0x96D6 0xE86D # 0 +0x96D7 0xE86E # 0 +0x96D8 0xE86F # 0 +0x96D9 0xE870 # 0 +0x96DA 0xE871 # 0 +0x96DB 0xE872 # 0 +0x96DC 0xE873 # 0 +0x96DD 0xE874 # 0 +0x96DE 0xE875 # 0 +0x96DF 0xE876 # 0 +0x96E0 0xE877 # 0 +0x96E1 0xE878 # 0 +0x96E2 0xE879 # 0 +0x96E3 0xE87A # 0 +0x96E4 0xE87B # 0 +0x96E5 0xE87C # 0 +0x96E6 0xE87D # 0 +0x96E7 0xE87E # 0 +0x96E8 0xE87F # 0 +0x96E9 0xE880 # 0 +0x96EA 0xE881 # 0 +0x96EB 0xE882 # 0 +0x96EC 0xE883 # 0 +0x96ED 0xE884 # 0 +0x96EE 0xE885 # 0 +0x96EF 0xE886 # 0 +0x96F0 0xE887 # 0 +0x96F1 0xE888 # 0 +0x96F2 0xE889 # 0 +0x96F3 0xE88A # 0 +0x96F4 0xE88B # 0 +0x96F5 0xE88C # 0 +0x96F6 0xE88D # 0 +0x96F7 0xE88E # 0 +0x96F8 0xE88F # 0 +0x96F9 0xE890 # 0 +0x96FA 0xE891 # 0 +0x96FB 0xE892 # 0 +0x96FC 0xE893 # 0 +0x96FD 0xE894 # 0 +0x96FE 0xE895 # 0 +0x9740 0xE896 # 0 +0x9741 0xE897 # 0 +0x9742 0xE898 # 0 +0x9743 0xE899 # 0 +0x9744 0xE89A # 0 +0x9745 0xE89B # 0 +0x9746 0xE89C # 0 +0x9747 0xE89D # 0 +0x9748 0xE89E # 0 +0x9749 0xE89F # 0 +0x974A 0xE8A0 # 0 +0x974B 0xE8A1 # 0 +0x974C 0xE8A2 # 0 +0x974D 0xE8A3 # 0 +0x974E 0xE8A4 # 0 +0x974F 0xE8A5 # 0 +0x9750 0xE8A6 # 0 +0x9751 0xE8A7 # 0 +0x9752 0xE8A8 # 0 +0x9753 0xE8A9 # 0 +0x9754 0xE8AA # 0 +0x9755 0xE8AB # 0 +0x9756 0xE8AC # 0 +0x9757 0xE8AD # 0 +0x9758 0xE8AE # 0 +0x9759 0xE8AF # 0 +0x975A 0xE8B0 # 0 +0x975B 0xE8B1 # 0 +0x975C 0xE8B2 # 0 +0x975D 0xE8B3 # 0 +0x975E 0xE8B4 # 0 +0x975F 0xE8B5 # 0 +0x9760 0xE8B6 # 0 +0x9761 0xE8B7 # 0 +0x9762 0xE8B8 # 0 +0x9763 0xE8B9 # 0 +0x9764 0xE8BA # 0 +0x9765 0xE8BB # 0 +0x9766 0xE8BC # 0 +0x9767 0xE8BD # 0 +0x9768 0xE8BE # 0 +0x9769 0xE8BF # 0 +0x976A 0xE8C0 # 0 +0x976B 0xE8C1 # 0 +0x976C 0xE8C2 # 0 +0x976D 0xE8C3 # 0 +0x976E 0xE8C4 # 0 +0x976F 0xE8C5 # 0 +0x9770 0xE8C6 # 0 +0x9771 0xE8C7 # 0 +0x9772 0xE8C8 # 0 +0x9773 0xE8C9 # 0 +0x9774 0xE8CA # 0 +0x9775 0xE8CB # 0 +0x9776 0xE8CC # 0 +0x9777 0xE8CD # 0 +0x9778 0xE8CE # 0 +0x9779 0xE8CF # 0 +0x977A 0xE8D0 # 0 +0x977B 0xE8D1 # 0 +0x977C 0xE8D2 # 0 +0x977D 0xE8D3 # 0 +0x977E 0xE8D4 # 0 +0x97A1 0xE8D5 # 0 +0x97A2 0xE8D6 # 0 +0x97A3 0xE8D7 # 0 +0x97A4 0xE8D8 # 0 +0x97A5 0xE8D9 # 0 +0x97A6 0xE8DA # 0 +0x97A7 0xE8DB # 0 +0x97A8 0xE8DC # 0 +0x97A9 0xE8DD # 0 +0x97AA 0xE8DE # 0 +0x97AB 0xE8DF # 0 +0x97AC 0xE8E0 # 0 +0x97AD 0xE8E1 # 0 +0x97AE 0xE8E2 # 0 +0x97AF 0xE8E3 # 0 +0x97B0 0xE8E4 # 0 +0x97B1 0xE8E5 # 0 +0x97B2 0xE8E6 # 0 +0x97B3 0xE8E7 # 0 +0x97B4 0xE8E8 # 0 +0x97B5 0xE8E9 # 0 +0x97B6 0xE8EA # 0 +0x97B7 0xE8EB # 0 +0x97B8 0xE8EC # 0 +0x97B9 0xE8ED # 0 +0x97BA 0xE8EE # 0 +0x97BB 0xE8EF # 0 +0x97BC 0xE8F0 # 0 +0x97BD 0xE8F1 # 0 +0x97BE 0xE8F2 # 0 +0x97BF 0xE8F3 # 0 +0x97C0 0xE8F4 # 0 +0x97C1 0xE8F5 # 0 +0x97C2 0xE8F6 # 0 +0x97C3 0xE8F7 # 0 +0x97C4 0xE8F8 # 0 +0x97C5 0xE8F9 # 0 +0x97C6 0xE8FA # 0 +0x97C7 0xE8FB # 0 +0x97C8 0xE8FC # 0 +0x97C9 0xE8FD # 0 +0x97CA 0xE8FE # 0 +0x97CB 0xE8FF # 0 +0x97CC 0xE900 # 0 +0x97CD 0xE901 # 0 +0x97CE 0xE902 # 0 +0x97CF 0xE903 # 0 +0x97D0 0xE904 # 0 +0x97D1 0xE905 # 0 +0x97D2 0xE906 # 0 +0x97D3 0xE907 # 0 +0x97D4 0xE908 # 0 +0x97D5 0xE909 # 0 +0x97D6 0xE90A # 0 +0x97D7 0xE90B # 0 +0x97D8 0xE90C # 0 +0x97D9 0xE90D # 0 +0x97DA 0xE90E # 0 +0x97DB 0xE90F # 0 +0x97DC 0xE910 # 0 +0x97DD 0xE911 # 0 +0x97DE 0xE912 # 0 +0x97DF 0xE913 # 0 +0x97E0 0xE914 # 0 +0x97E1 0xE915 # 0 +0x97E2 0xE916 # 0 +0x97E3 0xE917 # 0 +0x97E4 0xE918 # 0 +0x97E5 0xE919 # 0 +0x97E6 0xE91A # 0 +0x97E7 0xE91B # 0 +0x97E8 0xE91C # 0 +0x97E9 0xE91D # 0 +0x97EA 0xE91E # 0 +0x97EB 0xE91F # 0 +0x97EC 0xE920 # 0 +0x97ED 0xE921 # 0 +0x97EE 0xE922 # 0 +0x97EF 0xE923 # 0 +0x97F0 0xE924 # 0 +0x97F1 0xE925 # 0 +0x97F2 0xE926 # 0 +0x97F3 0xE927 # 0 +0x97F4 0xE928 # 0 +0x97F5 0xE929 # 0 +0x97F6 0xE92A # 0 +0x97F7 0xE92B # 0 +0x97F8 0xE92C # 0 +0x97F9 0xE92D # 0 +0x97FA 0xE92E # 0 +0x97FB 0xE92F # 0 +0x97FC 0xE930 # 0 +0x97FD 0xE931 # 0 +0x97FE 0xE932 # 0 +0x9840 0xE933 # 0 +0x9841 0xE934 # 0 +0x9842 0xE935 # 0 +0x9843 0xE936 # 0 +0x9844 0xE937 # 0 +0x9845 0xE938 # 0 +0x9846 0xE939 # 0 +0x9847 0xE93A # 0 +0x9848 0xE93B # 0 +0x9849 0xE93C # 0 +0x984A 0xE93D # 0 +0x984B 0xE93E # 0 +0x984C 0xE93F # 0 +0x984D 0xE940 # 0 +0x984E 0xE941 # 0 +0x984F 0xE942 # 0 +0x9850 0xE943 # 0 +0x9851 0xE944 # 0 +0x9852 0xE945 # 0 +0x9853 0xE946 # 0 +0x9854 0xE947 # 0 +0x9855 0xE948 # 0 +0x9856 0xE949 # 0 +0x9857 0xE94A # 0 +0x9858 0xE94B # 0 +0x9859 0xE94C # 0 +0x985A 0xE94D # 0 +0x985B 0xE94E # 0 +0x985C 0xE94F # 0 +0x985D 0xE950 # 0 +0x985E 0xE951 # 0 +0x985F 0xE952 # 0 +0x9860 0xE953 # 0 +0x9861 0xE954 # 0 +0x9862 0xE955 # 0 +0x9863 0xE956 # 0 +0x9864 0xE957 # 0 +0x9865 0xE958 # 0 +0x9866 0xE959 # 0 +0x9867 0xE95A # 0 +0x9868 0xE95B # 0 +0x9869 0xE95C # 0 +0x986A 0xE95D # 0 +0x986B 0xE95E # 0 +0x986C 0xE95F # 0 +0x986D 0xE960 # 0 +0x986E 0xE961 # 0 +0x986F 0xE962 # 0 +0x9870 0xE963 # 0 +0x9871 0xE964 # 0 +0x9872 0xE965 # 0 +0x9873 0xE966 # 0 +0x9874 0xE967 # 0 +0x9875 0xE968 # 0 +0x9876 0xE969 # 0 +0x9877 0xE96A # 0 +0x9878 0xE96B # 0 +0x9879 0xE96C # 0 +0x987A 0xE96D # 0 +0x987B 0xE96E # 0 +0x987C 0xE96F # 0 +0x987D 0xE970 # 0 +0x987E 0xE971 # 0 +0x98A1 0xE972 # 0 +0x98A2 0xE973 # 0 +0x98A3 0xE974 # 0 +0x98A4 0xE975 # 0 +0x98A5 0xE976 # 0 +0x98A6 0xE977 # 0 +0x98A7 0xE978 # 0 +0x98A8 0xE979 # 0 +0x98A9 0xE97A # 0 +0x98AA 0xE97B # 0 +0x98AB 0xE97C # 0 +0x98AC 0xE97D # 0 +0x98AD 0xE97E # 0 +0x98AE 0xE97F # 0 +0x98AF 0xE980 # 0 +0x98B0 0xE981 # 0 +0x98B1 0xE982 # 0 +0x98B2 0xE983 # 0 +0x98B3 0xE984 # 0 +0x98B4 0xE985 # 0 +0x98B5 0xE986 # 0 +0x98B6 0xE987 # 0 +0x98B7 0xE988 # 0 +0x98B8 0xE989 # 0 +0x98B9 0xE98A # 0 +0x98BA 0xE98B # 0 +0x98BB 0xE98C # 0 +0x98BC 0xE98D # 0 +0x98BD 0xE98E # 0 +0x98BE 0xE98F # 0 +0x98BF 0xE990 # 0 +0x98C0 0xE991 # 0 +0x98C1 0xE992 # 0 +0x98C2 0xE993 # 0 +0x98C3 0xE994 # 0 +0x98C4 0xE995 # 0 +0x98C5 0xE996 # 0 +0x98C6 0xE997 # 0 +0x98C7 0xE998 # 0 +0x98C8 0xE999 # 0 +0x98C9 0xE99A # 0 +0x98CA 0xE99B # 0 +0x98CB 0xE99C # 0 +0x98CC 0xE99D # 0 +0x98CD 0xE99E # 0 +0x98CE 0xE99F # 0 +0x98CF 0xE9A0 # 0 +0x98D0 0xE9A1 # 0 +0x98D1 0xE9A2 # 0 +0x98D2 0xE9A3 # 0 +0x98D3 0xE9A4 # 0 +0x98D4 0xE9A5 # 0 +0x98D5 0xE9A6 # 0 +0x98D6 0xE9A7 # 0 +0x98D7 0xE9A8 # 0 +0x98D8 0xE9A9 # 0 +0x98D9 0xE9AA # 0 +0x98DA 0xE9AB # 0 +0x98DB 0xE9AC # 0 +0x98DC 0xE9AD # 0 +0x98DD 0xE9AE # 0 +0x98DE 0xE9AF # 0 +0x98DF 0xE9B0 # 0 +0x98E0 0xE9B1 # 0 +0x98E1 0xE9B2 # 0 +0x98E2 0xE9B3 # 0 +0x98E3 0xE9B4 # 0 +0x98E4 0xE9B5 # 0 +0x98E5 0xE9B6 # 0 +0x98E6 0xE9B7 # 0 +0x98E7 0xE9B8 # 0 +0x98E8 0xE9B9 # 0 +0x98E9 0xE9BA # 0 +0x98EA 0xE9BB # 0 +0x98EB 0xE9BC # 0 +0x98EC 0xE9BD # 0 +0x98ED 0xE9BE # 0 +0x98EE 0xE9BF # 0 +0x98EF 0xE9C0 # 0 +0x98F0 0xE9C1 # 0 +0x98F1 0xE9C2 # 0 +0x98F2 0xE9C3 # 0 +0x98F3 0xE9C4 # 0 +0x98F4 0xE9C5 # 0 +0x98F5 0xE9C6 # 0 +0x98F6 0xE9C7 # 0 +0x98F7 0xE9C8 # 0 +0x98F8 0xE9C9 # 0 +0x98F9 0xE9CA # 0 +0x98FA 0xE9CB # 0 +0x98FB 0xE9CC # 0 +0x98FC 0xE9CD # 0 +0x98FD 0xE9CE # 0 +0x98FE 0xE9CF # 0 +0x9940 0xE9D0 # 0 +0x9941 0xE9D1 # 0 +0x9942 0xE9D2 # 0 +0x9943 0xE9D3 # 0 +0x9944 0xE9D4 # 0 +0x9945 0xE9D5 # 0 +0x9946 0xE9D6 # 0 +0x9947 0xE9D7 # 0 +0x9948 0xE9D8 # 0 +0x9949 0xE9D9 # 0 +0x994A 0xE9DA # 0 +0x994B 0xE9DB # 0 +0x994C 0xE9DC # 0 +0x994D 0xE9DD # 0 +0x994E 0xE9DE # 0 +0x994F 0xE9DF # 0 +0x9950 0xE9E0 # 0 +0x9951 0xE9E1 # 0 +0x9952 0xE9E2 # 0 +0x9953 0xE9E3 # 0 +0x9954 0xE9E4 # 0 +0x9955 0xE9E5 # 0 +0x9956 0xE9E6 # 0 +0x9957 0xE9E7 # 0 +0x9958 0xE9E8 # 0 +0x9959 0xE9E9 # 0 +0x995A 0xE9EA # 0 +0x995B 0xE9EB # 0 +0x995C 0xE9EC # 0 +0x995D 0xE9ED # 0 +0x995E 0xE9EE # 0 +0x995F 0xE9EF # 0 +0x9960 0xE9F0 # 0 +0x9961 0xE9F1 # 0 +0x9962 0xE9F2 # 0 +0x9963 0xE9F3 # 0 +0x9964 0xE9F4 # 0 +0x9965 0xE9F5 # 0 +0x9966 0xE9F6 # 0 +0x9967 0xE9F7 # 0 +0x9968 0xE9F8 # 0 +0x9969 0xE9F9 # 0 +0x996A 0xE9FA # 0 +0x996B 0xE9FB # 0 +0x996C 0xE9FC # 0 +0x996D 0xE9FD # 0 +0x996E 0xE9FE # 0 +0x996F 0xE9FF # 0 +0x9970 0xEA00 # 0 +0x9971 0xEA01 # 0 +0x9972 0xEA02 # 0 +0x9973 0xEA03 # 0 +0x9974 0xEA04 # 0 +0x9975 0xEA05 # 0 +0x9976 0xEA06 # 0 +0x9977 0xEA07 # 0 +0x9978 0xEA08 # 0 +0x9979 0xEA09 # 0 +0x997A 0xEA0A # 0 +0x997B 0xEA0B # 0 +0x997C 0xEA0C # 0 +0x997D 0xEA0D # 0 +0x997E 0xEA0E # 0 +0x99A1 0xEA0F # 0 +0x99A2 0xEA10 # 0 +0x99A3 0xEA11 # 0 +0x99A4 0xEA12 # 0 +0x99A5 0xEA13 # 0 +0x99A6 0xEA14 # 0 +0x99A7 0xEA15 # 0 +0x99A8 0xEA16 # 0 +0x99A9 0xEA17 # 0 +0x99AA 0xEA18 # 0 +0x99AB 0xEA19 # 0 +0x99AC 0xEA1A # 0 +0x99AD 0xEA1B # 0 +0x99AE 0xEA1C # 0 +0x99AF 0xEA1D # 0 +0x99B0 0xEA1E # 0 +0x99B1 0xEA1F # 0 +0x99B2 0xEA20 # 0 +0x99B3 0xEA21 # 0 +0x99B4 0xEA22 # 0 +0x99B5 0xEA23 # 0 +0x99B6 0xEA24 # 0 +0x99B7 0xEA25 # 0 +0x99B8 0xEA26 # 0 +0x99B9 0xEA27 # 0 +0x99BA 0xEA28 # 0 +0x99BB 0xEA29 # 0 +0x99BC 0xEA2A # 0 +0x99BD 0xEA2B # 0 +0x99BE 0xEA2C # 0 +0x99BF 0xEA2D # 0 +0x99C0 0xEA2E # 0 +0x99C1 0xEA2F # 0 +0x99C2 0xEA30 # 0 +0x99C3 0xEA31 # 0 +0x99C4 0xEA32 # 0 +0x99C5 0xEA33 # 0 +0x99C6 0xEA34 # 0 +0x99C7 0xEA35 # 0 +0x99C8 0xEA36 # 0 +0x99C9 0xEA37 # 0 +0x99CA 0xEA38 # 0 +0x99CB 0xEA39 # 0 +0x99CC 0xEA3A # 0 +0x99CD 0xEA3B # 0 +0x99CE 0xEA3C # 0 +0x99CF 0xEA3D # 0 +0x99D0 0xEA3E # 0 +0x99D1 0xEA3F # 0 +0x99D2 0xEA40 # 0 +0x99D3 0xEA41 # 0 +0x99D4 0xEA42 # 0 +0x99D5 0xEA43 # 0 +0x99D6 0xEA44 # 0 +0x99D7 0xEA45 # 0 +0x99D8 0xEA46 # 0 +0x99D9 0xEA47 # 0 +0x99DA 0xEA48 # 0 +0x99DB 0xEA49 # 0 +0x99DC 0xEA4A # 0 +0x99DD 0xEA4B # 0 +0x99DE 0xEA4C # 0 +0x99DF 0xEA4D # 0 +0x99E0 0xEA4E # 0 +0x99E1 0xEA4F # 0 +0x99E2 0xEA50 # 0 +0x99E3 0xEA51 # 0 +0x99E4 0xEA52 # 0 +0x99E5 0xEA53 # 0 +0x99E6 0xEA54 # 0 +0x99E7 0xEA55 # 0 +0x99E8 0xEA56 # 0 +0x99E9 0xEA57 # 0 +0x99EA 0xEA58 # 0 +0x99EB 0xEA59 # 0 +0x99EC 0xEA5A # 0 +0x99ED 0xEA5B # 0 +0x99EE 0xEA5C # 0 +0x99EF 0xEA5D # 0 +0x99F0 0xEA5E # 0 +0x99F1 0xEA5F # 0 +0x99F2 0xEA60 # 0 +0x99F3 0xEA61 # 0 +0x99F4 0xEA62 # 0 +0x99F5 0xEA63 # 0 +0x99F6 0xEA64 # 0 +0x99F7 0xEA65 # 0 +0x99F8 0xEA66 # 0 +0x99F9 0xEA67 # 0 +0x99FA 0xEA68 # 0 +0x99FB 0xEA69 # 0 +0x99FC 0xEA6A # 0 +0x99FD 0xEA6B # 0 +0x99FE 0xEA6C # 0 +0x9A40 0xEA6D # 0 +0x9A41 0xEA6E # 0 +0x9A42 0xEA6F # 0 +0x9A43 0xEA70 # 0 +0x9A44 0xEA71 # 0 +0x9A45 0xEA72 # 0 +0x9A46 0xEA73 # 0 +0x9A47 0xEA74 # 0 +0x9A48 0xEA75 # 0 +0x9A49 0xEA76 # 0 +0x9A4A 0xEA77 # 0 +0x9A4B 0xEA78 # 0 +0x9A4C 0xEA79 # 0 +0x9A4D 0xEA7A # 0 +0x9A4E 0xEA7B # 0 +0x9A4F 0xEA7C # 0 +0x9A50 0xEA7D # 0 +0x9A51 0xEA7E # 0 +0x9A52 0xEA7F # 0 +0x9A53 0xEA80 # 0 +0x9A54 0xEA81 # 0 +0x9A55 0xEA82 # 0 +0x9A56 0xEA83 # 0 +0x9A57 0xEA84 # 0 +0x9A58 0xEA85 # 0 +0x9A59 0xEA86 # 0 +0x9A5A 0xEA87 # 0 +0x9A5B 0xEA88 # 0 +0x9A5C 0xEA89 # 0 +0x9A5D 0xEA8A # 0 +0x9A5E 0xEA8B # 0 +0x9A5F 0xEA8C # 0 +0x9A60 0xEA8D # 0 +0x9A61 0xEA8E # 0 +0x9A62 0xEA8F # 0 +0x9A63 0xEA90 # 0 +0x9A64 0xEA91 # 0 +0x9A65 0xEA92 # 0 +0x9A66 0xEA93 # 0 +0x9A67 0xEA94 # 0 +0x9A68 0xEA95 # 0 +0x9A69 0xEA96 # 0 +0x9A6A 0xEA97 # 0 +0x9A6B 0xEA98 # 0 +0x9A6C 0xEA99 # 0 +0x9A6D 0xEA9A # 0 +0x9A6E 0xEA9B # 0 +0x9A6F 0xEA9C # 0 +0x9A70 0xEA9D # 0 +0x9A71 0xEA9E # 0 +0x9A72 0xEA9F # 0 +0x9A73 0xEAA0 # 0 +0x9A74 0xEAA1 # 0 +0x9A75 0xEAA2 # 0 +0x9A76 0xEAA3 # 0 +0x9A77 0xEAA4 # 0 +0x9A78 0xEAA5 # 0 +0x9A79 0xEAA6 # 0 +0x9A7A 0xEAA7 # 0 +0x9A7B 0xEAA8 # 0 +0x9A7C 0xEAA9 # 0 +0x9A7D 0xEAAA # 0 +0x9A7E 0xEAAB # 0 +0x9AA1 0xEAAC # 0 +0x9AA2 0xEAAD # 0 +0x9AA3 0xEAAE # 0 +0x9AA4 0xEAAF # 0 +0x9AA5 0xEAB0 # 0 +0x9AA6 0xEAB1 # 0 +0x9AA7 0xEAB2 # 0 +0x9AA8 0xEAB3 # 0 +0x9AA9 0xEAB4 # 0 +0x9AAA 0xEAB5 # 0 +0x9AAB 0xEAB6 # 0 +0x9AAC 0xEAB7 # 0 +0x9AAD 0xEAB8 # 0 +0x9AAE 0xEAB9 # 0 +0x9AAF 0xEABA # 0 +0x9AB0 0xEABB # 0 +0x9AB1 0xEABC # 0 +0x9AB2 0xEABD # 0 +0x9AB3 0xEABE # 0 +0x9AB4 0xEABF # 0 +0x9AB5 0xEAC0 # 0 +0x9AB6 0xEAC1 # 0 +0x9AB7 0xEAC2 # 0 +0x9AB8 0xEAC3 # 0 +0x9AB9 0xEAC4 # 0 +0x9ABA 0xEAC5 # 0 +0x9ABB 0xEAC6 # 0 +0x9ABC 0xEAC7 # 0 +0x9ABD 0xEAC8 # 0 +0x9ABE 0xEAC9 # 0 +0x9ABF 0xEACA # 0 +0x9AC0 0xEACB # 0 +0x9AC1 0xEACC # 0 +0x9AC2 0xEACD # 0 +0x9AC3 0xEACE # 0 +0x9AC4 0xEACF # 0 +0x9AC5 0xEAD0 # 0 +0x9AC6 0xEAD1 # 0 +0x9AC7 0xEAD2 # 0 +0x9AC8 0xEAD3 # 0 +0x9AC9 0xEAD4 # 0 +0x9ACA 0xEAD5 # 0 +0x9ACB 0xEAD6 # 0 +0x9ACC 0xEAD7 # 0 +0x9ACD 0xEAD8 # 0 +0x9ACE 0xEAD9 # 0 +0x9ACF 0xEADA # 0 +0x9AD0 0xEADB # 0 +0x9AD1 0xEADC # 0 +0x9AD2 0xEADD # 0 +0x9AD3 0xEADE # 0 +0x9AD4 0xEADF # 0 +0x9AD5 0xEAE0 # 0 +0x9AD6 0xEAE1 # 0 +0x9AD7 0xEAE2 # 0 +0x9AD8 0xEAE3 # 0 +0x9AD9 0xEAE4 # 0 +0x9ADA 0xEAE5 # 0 +0x9ADB 0xEAE6 # 0 +0x9ADC 0xEAE7 # 0 +0x9ADD 0xEAE8 # 0 +0x9ADE 0xEAE9 # 0 +0x9ADF 0xEAEA # 0 +0x9AE0 0xEAEB # 0 +0x9AE1 0xEAEC # 0 +0x9AE2 0xEAED # 0 +0x9AE3 0xEAEE # 0 +0x9AE4 0xEAEF # 0 +0x9AE5 0xEAF0 # 0 +0x9AE6 0xEAF1 # 0 +0x9AE7 0xEAF2 # 0 +0x9AE8 0xEAF3 # 0 +0x9AE9 0xEAF4 # 0 +0x9AEA 0xEAF5 # 0 +0x9AEB 0xEAF6 # 0 +0x9AEC 0xEAF7 # 0 +0x9AED 0xEAF8 # 0 +0x9AEE 0xEAF9 # 0 +0x9AEF 0xEAFA # 0 +0x9AF0 0xEAFB # 0 +0x9AF1 0xEAFC # 0 +0x9AF2 0xEAFD # 0 +0x9AF3 0xEAFE # 0 +0x9AF4 0xEAFF # 0 +0x9AF5 0xEB00 # 0 +0x9AF6 0xEB01 # 0 +0x9AF7 0xEB02 # 0 +0x9AF8 0xEB03 # 0 +0x9AF9 0xEB04 # 0 +0x9AFA 0xEB05 # 0 +0x9AFB 0xEB06 # 0 +0x9AFC 0xEB07 # 0 +0x9AFD 0xEB08 # 0 +0x9AFE 0xEB09 # 0 +0x9B40 0xEB0A # 0 +0x9B41 0xEB0B # 0 +0x9B42 0xEB0C # 0 +0x9B43 0xEB0D # 0 +0x9B44 0xEB0E # 0 +0x9B45 0xEB0F # 0 +0x9B46 0xEB10 # 0 +0x9B47 0xEB11 # 0 +0x9B48 0xEB12 # 0 +0x9B49 0xEB13 # 0 +0x9B4A 0xEB14 # 0 +0x9B4B 0xEB15 # 0 +0x9B4C 0xEB16 # 0 +0x9B4D 0xEB17 # 0 +0x9B4E 0xEB18 # 0 +0x9B4F 0xEB19 # 0 +0x9B50 0xEB1A # 0 +0x9B51 0xEB1B # 0 +0x9B52 0xEB1C # 0 +0x9B53 0xEB1D # 0 +0x9B54 0xEB1E # 0 +0x9B55 0xEB1F # 0 +0x9B56 0xEB20 # 0 +0x9B57 0xEB21 # 0 +0x9B58 0xEB22 # 0 +0x9B59 0xEB23 # 0 +0x9B5A 0xEB24 # 0 +0x9B5B 0xEB25 # 0 +0x9B5C 0xEB26 # 0 +0x9B5D 0xEB27 # 0 +0x9B5E 0xEB28 # 0 +0x9B5F 0xEB29 # 0 +0x9B60 0xEB2A # 0 +0x9B61 0xEB2B # 0 +0x9B62 0xEB2C # 0 +0x9B63 0xEB2D # 0 +0x9B64 0xEB2E # 0 +0x9B65 0xEB2F # 0 +0x9B66 0xEB30 # 0 +0x9B67 0xEB31 # 0 +0x9B68 0xEB32 # 0 +0x9B69 0xEB33 # 0 +0x9B6A 0xEB34 # 0 +0x9B6B 0xEB35 # 0 +0x9B6C 0xEB36 # 0 +0x9B6D 0xEB37 # 0 +0x9B6E 0xEB38 # 0 +0x9B6F 0xEB39 # 0 +0x9B70 0xEB3A # 0 +0x9B71 0xEB3B # 0 +0x9B72 0xEB3C # 0 +0x9B73 0xEB3D # 0 +0x9B74 0xEB3E # 0 +0x9B75 0xEB3F # 0 +0x9B76 0xEB40 # 0 +0x9B77 0xEB41 # 0 +0x9B78 0xEB42 # 0 +0x9B79 0xEB43 # 0 +0x9B7A 0xEB44 # 0 +0x9B7B 0xEB45 # 0 +0x9B7C 0xEB46 # 0 +0x9B7D 0xEB47 # 0 +0x9B7E 0xEB48 # 0 +0x9BA1 0xEB49 # 0 +0x9BA2 0xEB4A # 0 +0x9BA3 0xEB4B # 0 +0x9BA4 0xEB4C # 0 +0x9BA5 0xEB4D # 0 +0x9BA6 0xEB4E # 0 +0x9BA7 0xEB4F # 0 +0x9BA8 0xEB50 # 0 +0x9BA9 0xEB51 # 0 +0x9BAA 0xEB52 # 0 +0x9BAB 0xEB53 # 0 +0x9BAC 0xEB54 # 0 +0x9BAD 0xEB55 # 0 +0x9BAE 0xEB56 # 0 +0x9BAF 0xEB57 # 0 +0x9BB0 0xEB58 # 0 +0x9BB1 0xEB59 # 0 +0x9BB2 0xEB5A # 0 +0x9BB3 0xEB5B # 0 +0x9BB4 0xEB5C # 0 +0x9BB5 0xEB5D # 0 +0x9BB6 0xEB5E # 0 +0x9BB7 0xEB5F # 0 +0x9BB8 0xEB60 # 0 +0x9BB9 0xEB61 # 0 +0x9BBA 0xEB62 # 0 +0x9BBB 0xEB63 # 0 +0x9BBC 0xEB64 # 0 +0x9BBD 0xEB65 # 0 +0x9BBE 0xEB66 # 0 +0x9BBF 0xEB67 # 0 +0x9BC0 0xEB68 # 0 +0x9BC1 0xEB69 # 0 +0x9BC2 0xEB6A # 0 +0x9BC3 0xEB6B # 0 +0x9BC4 0xEB6C # 0 +0x9BC5 0xEB6D # 0 +0x9BC6 0xEB6E # 0 +0x9BC7 0xEB6F # 0 +0x9BC8 0xEB70 # 0 +0x9BC9 0xEB71 # 0 +0x9BCA 0xEB72 # 0 +0x9BCB 0xEB73 # 0 +0x9BCC 0xEB74 # 0 +0x9BCD 0xEB75 # 0 +0x9BCE 0xEB76 # 0 +0x9BCF 0xEB77 # 0 +0x9BD0 0xEB78 # 0 +0x9BD1 0xEB79 # 0 +0x9BD2 0xEB7A # 0 +0x9BD3 0xEB7B # 0 +0x9BD4 0xEB7C # 0 +0x9BD5 0xEB7D # 0 +0x9BD6 0xEB7E # 0 +0x9BD7 0xEB7F # 0 +0x9BD8 0xEB80 # 0 +0x9BD9 0xEB81 # 0 +0x9BDA 0xEB82 # 0 +0x9BDB 0xEB83 # 0 +0x9BDC 0xEB84 # 0 +0x9BDD 0xEB85 # 0 +0x9BDE 0xEB86 # 0 +0x9BDF 0xEB87 # 0 +0x9BE0 0xEB88 # 0 +0x9BE1 0xEB89 # 0 +0x9BE2 0xEB8A # 0 +0x9BE3 0xEB8B # 0 +0x9BE4 0xEB8C # 0 +0x9BE5 0xEB8D # 0 +0x9BE6 0xEB8E # 0 +0x9BE7 0xEB8F # 0 +0x9BE8 0xEB90 # 0 +0x9BE9 0xEB91 # 0 +0x9BEA 0xEB92 # 0 +0x9BEB 0xEB93 # 0 +0x9BEC 0xEB94 # 0 +0x9BED 0xEB95 # 0 +0x9BEE 0xEB96 # 0 +0x9BEF 0xEB97 # 0 +0x9BF0 0xEB98 # 0 +0x9BF1 0xEB99 # 0 +0x9BF2 0xEB9A # 0 +0x9BF3 0xEB9B # 0 +0x9BF4 0xEB9C # 0 +0x9BF5 0xEB9D # 0 +0x9BF6 0xEB9E # 0 +0x9BF7 0xEB9F # 0 +0x9BF8 0xEBA0 # 0 +0x9BF9 0xEBA1 # 0 +0x9BFA 0xEBA2 # 0 +0x9BFB 0xEBA3 # 0 +0x9BFC 0xEBA4 # 0 +0x9BFD 0xEBA5 # 0 +0x9BFE 0xEBA6 # 0 +0x9C40 0xEBA7 # 0 +0x9C41 0xEBA8 # 0 +0x9C42 0xEBA9 # 0 +0x9C43 0xEBAA # 0 +0x9C44 0xEBAB # 0 +0x9C45 0xEBAC # 0 +0x9C46 0xEBAD # 0 +0x9C47 0xEBAE # 0 +0x9C48 0xEBAF # 0 +0x9C49 0xEBB0 # 0 +0x9C4A 0xEBB1 # 0 +0x9C4B 0xEBB2 # 0 +0x9C4C 0xEBB3 # 0 +0x9C4D 0xEBB4 # 0 +0x9C4E 0xEBB5 # 0 +0x9C4F 0xEBB6 # 0 +0x9C50 0xEBB7 # 0 +0x9C51 0xEBB8 # 0 +0x9C52 0xEBB9 # 0 +0x9C53 0xEBBA # 0 +0x9C54 0xEBBB # 0 +0x9C55 0xEBBC # 0 +0x9C56 0xEBBD # 0 +0x9C57 0xEBBE # 0 +0x9C58 0xEBBF # 0 +0x9C59 0xEBC0 # 0 +0x9C5A 0xEBC1 # 0 +0x9C5B 0xEBC2 # 0 +0x9C5C 0xEBC3 # 0 +0x9C5D 0xEBC4 # 0 +0x9C5E 0xEBC5 # 0 +0x9C5F 0xEBC6 # 0 +0x9C60 0xEBC7 # 0 +0x9C61 0xEBC8 # 0 +0x9C62 0xEBC9 # 0 +0x9C63 0xEBCA # 0 +0x9C64 0xEBCB # 0 +0x9C65 0xEBCC # 0 +0x9C66 0xEBCD # 0 +0x9C67 0xEBCE # 0 +0x9C68 0xEBCF # 0 +0x9C69 0xEBD0 # 0 +0x9C6A 0xEBD1 # 0 +0x9C6B 0xEBD2 # 0 +0x9C6C 0xEBD3 # 0 +0x9C6D 0xEBD4 # 0 +0x9C6E 0xEBD5 # 0 +0x9C6F 0xEBD6 # 0 +0x9C70 0xEBD7 # 0 +0x9C71 0xEBD8 # 0 +0x9C72 0xEBD9 # 0 +0x9C73 0xEBDA # 0 +0x9C74 0xEBDB # 0 +0x9C75 0xEBDC # 0 +0x9C76 0xEBDD # 0 +0x9C77 0xEBDE # 0 +0x9C78 0xEBDF # 0 +0x9C79 0xEBE0 # 0 +0x9C7A 0xEBE1 # 0 +0x9C7B 0xEBE2 # 0 +0x9C7C 0xEBE3 # 0 +0x9C7D 0xEBE4 # 0 +0x9C7E 0xEBE5 # 0 +0x9CA1 0xEBE6 # 0 +0x9CA2 0xEBE7 # 0 +0x9CA3 0xEBE8 # 0 +0x9CA4 0xEBE9 # 0 +0x9CA5 0xEBEA # 0 +0x9CA6 0xEBEB # 0 +0x9CA7 0xEBEC # 0 +0x9CA8 0xEBED # 0 +0x9CA9 0xEBEE # 0 +0x9CAA 0xEBEF # 0 +0x9CAB 0xEBF0 # 0 +0x9CAC 0xEBF1 # 0 +0x9CAD 0xEBF2 # 0 +0x9CAE 0xEBF3 # 0 +0x9CAF 0xEBF4 # 0 +0x9CB0 0xEBF5 # 0 +0x9CB1 0xEBF6 # 0 +0x9CB2 0xEBF7 # 0 +0x9CB3 0xEBF8 # 0 +0x9CB4 0xEBF9 # 0 +0x9CB5 0xEBFA # 0 +0x9CB6 0xEBFB # 0 +0x9CB7 0xEBFC # 0 +0x9CB8 0xEBFD # 0 +0x9CB9 0xEBFE # 0 +0x9CBA 0xEBFF # 0 +0x9CBB 0xEC00 # 0 +0x9CBC 0xEC01 # 0 +0x9CBD 0xEC02 # 0 +0x9CBE 0xEC03 # 0 +0x9CBF 0xEC04 # 0 +0x9CC0 0xEC05 # 0 +0x9CC1 0xEC06 # 0 +0x9CC2 0xEC07 # 0 +0x9CC3 0xEC08 # 0 +0x9CC4 0xEC09 # 0 +0x9CC5 0xEC0A # 0 +0x9CC6 0xEC0B # 0 +0x9CC7 0xEC0C # 0 +0x9CC8 0xEC0D # 0 +0x9CC9 0xEC0E # 0 +0x9CCA 0xEC0F # 0 +0x9CCB 0xEC10 # 0 +0x9CCC 0xEC11 # 0 +0x9CCD 0xEC12 # 0 +0x9CCE 0xEC13 # 0 +0x9CCF 0xEC14 # 0 +0x9CD0 0xEC15 # 0 +0x9CD1 0xEC16 # 0 +0x9CD2 0xEC17 # 0 +0x9CD3 0xEC18 # 0 +0x9CD4 0xEC19 # 0 +0x9CD5 0xEC1A # 0 +0x9CD6 0xEC1B # 0 +0x9CD7 0xEC1C # 0 +0x9CD8 0xEC1D # 0 +0x9CD9 0xEC1E # 0 +0x9CDA 0xEC1F # 0 +0x9CDB 0xEC20 # 0 +0x9CDC 0xEC21 # 0 +0x9CDD 0xEC22 # 0 +0x9CDE 0xEC23 # 0 +0x9CDF 0xEC24 # 0 +0x9CE0 0xEC25 # 0 +0x9CE1 0xEC26 # 0 +0x9CE2 0xEC27 # 0 +0x9CE3 0xEC28 # 0 +0x9CE4 0xEC29 # 0 +0x9CE5 0xEC2A # 0 +0x9CE6 0xEC2B # 0 +0x9CE7 0xEC2C # 0 +0x9CE8 0xEC2D # 0 +0x9CE9 0xEC2E # 0 +0x9CEA 0xEC2F # 0 +0x9CEB 0xEC30 # 0 +0x9CEC 0xEC31 # 0 +0x9CED 0xEC32 # 0 +0x9CEE 0xEC33 # 0 +0x9CEF 0xEC34 # 0 +0x9CF0 0xEC35 # 0 +0x9CF1 0xEC36 # 0 +0x9CF2 0xEC37 # 0 +0x9CF3 0xEC38 # 0 +0x9CF4 0xEC39 # 0 +0x9CF5 0xEC3A # 0 +0x9CF6 0xEC3B # 0 +0x9CF7 0xEC3C # 0 +0x9CF8 0xEC3D # 0 +0x9CF9 0xEC3E # 0 +0x9CFA 0xEC3F # 0 +0x9CFB 0xEC40 # 0 +0x9CFC 0xEC41 # 0 +0x9CFD 0xEC42 # 0 +0x9CFE 0xEC43 # 0 +0x9D40 0xEC44 # 0 +0x9D41 0xEC45 # 0 +0x9D42 0xEC46 # 0 +0x9D43 0xEC47 # 0 +0x9D44 0xEC48 # 0 +0x9D45 0xEC49 # 0 +0x9D46 0xEC4A # 0 +0x9D47 0xEC4B # 0 +0x9D48 0xEC4C # 0 +0x9D49 0xEC4D # 0 +0x9D4A 0xEC4E # 0 +0x9D4B 0xEC4F # 0 +0x9D4C 0xEC50 # 0 +0x9D4D 0xEC51 # 0 +0x9D4E 0xEC52 # 0 +0x9D4F 0xEC53 # 0 +0x9D50 0xEC54 # 0 +0x9D51 0xEC55 # 0 +0x9D52 0xEC56 # 0 +0x9D53 0xEC57 # 0 +0x9D54 0xEC58 # 0 +0x9D55 0xEC59 # 0 +0x9D56 0xEC5A # 0 +0x9D57 0xEC5B # 0 +0x9D58 0xEC5C # 0 +0x9D59 0xEC5D # 0 +0x9D5A 0xEC5E # 0 +0x9D5B 0xEC5F # 0 +0x9D5C 0xEC60 # 0 +0x9D5D 0xEC61 # 0 +0x9D5E 0xEC62 # 0 +0x9D5F 0xEC63 # 0 +0x9D60 0xEC64 # 0 +0x9D61 0xEC65 # 0 +0x9D62 0xEC66 # 0 +0x9D63 0xEC67 # 0 +0x9D64 0xEC68 # 0 +0x9D65 0xEC69 # 0 +0x9D66 0xEC6A # 0 +0x9D67 0xEC6B # 0 +0x9D68 0xEC6C # 0 +0x9D69 0xEC6D # 0 +0x9D6A 0xEC6E # 0 +0x9D6B 0xEC6F # 0 +0x9D6C 0xEC70 # 0 +0x9D6D 0xEC71 # 0 +0x9D6E 0xEC72 # 0 +0x9D6F 0xEC73 # 0 +0x9D70 0xEC74 # 0 +0x9D71 0xEC75 # 0 +0x9D72 0xEC76 # 0 +0x9D73 0xEC77 # 0 +0x9D74 0xEC78 # 0 +0x9D75 0xEC79 # 0 +0x9D76 0xEC7A # 0 +0x9D77 0xEC7B # 0 +0x9D78 0xEC7C # 0 +0x9D79 0xEC7D # 0 +0x9D7A 0xEC7E # 0 +0x9D7B 0xEC7F # 0 +0x9D7C 0xEC80 # 0 +0x9D7D 0xEC81 # 0 +0x9D7E 0xEC82 # 0 +0x9DA1 0xEC83 # 0 +0x9DA2 0xEC84 # 0 +0x9DA3 0xEC85 # 0 +0x9DA4 0xEC86 # 0 +0x9DA5 0xEC87 # 0 +0x9DA6 0xEC88 # 0 +0x9DA7 0xEC89 # 0 +0x9DA8 0xEC8A # 0 +0x9DA9 0xEC8B # 0 +0x9DAA 0xEC8C # 0 +0x9DAB 0xEC8D # 0 +0x9DAC 0xEC8E # 0 +0x9DAD 0xEC8F # 0 +0x9DAE 0xEC90 # 0 +0x9DAF 0xEC91 # 0 +0x9DB0 0xEC92 # 0 +0x9DB1 0xEC93 # 0 +0x9DB2 0xEC94 # 0 +0x9DB3 0xEC95 # 0 +0x9DB4 0xEC96 # 0 +0x9DB5 0xEC97 # 0 +0x9DB6 0xEC98 # 0 +0x9DB7 0xEC99 # 0 +0x9DB8 0xEC9A # 0 +0x9DB9 0xEC9B # 0 +0x9DBA 0xEC9C # 0 +0x9DBB 0xEC9D # 0 +0x9DBC 0xEC9E # 0 +0x9DBD 0xEC9F # 0 +0x9DBE 0xECA0 # 0 +0x9DBF 0xECA1 # 0 +0x9DC0 0xECA2 # 0 +0x9DC1 0xECA3 # 0 +0x9DC2 0xECA4 # 0 +0x9DC3 0xECA5 # 0 +0x9DC4 0xECA6 # 0 +0x9DC5 0xECA7 # 0 +0x9DC6 0xECA8 # 0 +0x9DC7 0xECA9 # 0 +0x9DC8 0xECAA # 0 +0x9DC9 0xECAB # 0 +0x9DCA 0xECAC # 0 +0x9DCB 0xECAD # 0 +0x9DCC 0xECAE # 0 +0x9DCD 0xECAF # 0 +0x9DCE 0xECB0 # 0 +0x9DCF 0xECB1 # 0 +0x9DD0 0xECB2 # 0 +0x9DD1 0xECB3 # 0 +0x9DD2 0xECB4 # 0 +0x9DD3 0xECB5 # 0 +0x9DD4 0xECB6 # 0 +0x9DD5 0xECB7 # 0 +0x9DD6 0xECB8 # 0 +0x9DD7 0xECB9 # 0 +0x9DD8 0xECBA # 0 +0x9DD9 0xECBB # 0 +0x9DDA 0xECBC # 0 +0x9DDB 0xECBD # 0 +0x9DDC 0xECBE # 0 +0x9DDD 0xECBF # 0 +0x9DDE 0xECC0 # 0 +0x9DDF 0xECC1 # 0 +0x9DE0 0xECC2 # 0 +0x9DE1 0xECC3 # 0 +0x9DE2 0xECC4 # 0 +0x9DE3 0xECC5 # 0 +0x9DE4 0xECC6 # 0 +0x9DE5 0xECC7 # 0 +0x9DE6 0xECC8 # 0 +0x9DE7 0xECC9 # 0 +0x9DE8 0xECCA # 0 +0x9DE9 0xECCB # 0 +0x9DEA 0xECCC # 0 +0x9DEB 0xECCD # 0 +0x9DEC 0xECCE # 0 +0x9DED 0xECCF # 0 +0x9DEE 0xECD0 # 0 +0x9DEF 0xECD1 # 0 +0x9DF0 0xECD2 # 0 +0x9DF1 0xECD3 # 0 +0x9DF2 0xECD4 # 0 +0x9DF3 0xECD5 # 0 +0x9DF4 0xECD6 # 0 +0x9DF5 0xECD7 # 0 +0x9DF6 0xECD8 # 0 +0x9DF7 0xECD9 # 0 +0x9DF8 0xECDA # 0 +0x9DF9 0xECDB # 0 +0x9DFA 0xECDC # 0 +0x9DFB 0xECDD # 0 +0x9DFC 0xECDE # 0 +0x9DFD 0xECDF # 0 +0x9DFE 0xECE0 # 0 +0x9E40 0xECE1 # 0 +0x9E41 0xECE2 # 0 +0x9E42 0xECE3 # 0 +0x9E43 0xECE4 # 0 +0x9E44 0xECE5 # 0 +0x9E45 0xECE6 # 0 +0x9E46 0xECE7 # 0 +0x9E47 0xECE8 # 0 +0x9E48 0xECE9 # 0 +0x9E49 0xECEA # 0 +0x9E4A 0xECEB # 0 +0x9E4B 0xECEC # 0 +0x9E4C 0xECED # 0 +0x9E4D 0xECEE # 0 +0x9E4E 0xECEF # 0 +0x9E4F 0xECF0 # 0 +0x9E50 0xECF1 # 0 +0x9E51 0xECF2 # 0 +0x9E52 0xECF3 # 0 +0x9E53 0xECF4 # 0 +0x9E54 0xECF5 # 0 +0x9E55 0xECF6 # 0 +0x9E56 0xECF7 # 0 +0x9E57 0xECF8 # 0 +0x9E58 0xECF9 # 0 +0x9E59 0xECFA # 0 +0x9E5A 0xECFB # 0 +0x9E5B 0xECFC # 0 +0x9E5C 0xECFD # 0 +0x9E5D 0xECFE # 0 +0x9E5E 0xECFF # 0 +0x9E5F 0xED00 # 0 +0x9E60 0xED01 # 0 +0x9E61 0xED02 # 0 +0x9E62 0xED03 # 0 +0x9E63 0xED04 # 0 +0x9E64 0xED05 # 0 +0x9E65 0xED06 # 0 +0x9E66 0xED07 # 0 +0x9E67 0xED08 # 0 +0x9E68 0xED09 # 0 +0x9E69 0xED0A # 0 +0x9E6A 0xED0B # 0 +0x9E6B 0xED0C # 0 +0x9E6C 0xED0D # 0 +0x9E6D 0xED0E # 0 +0x9E6E 0xED0F # 0 +0x9E6F 0xED10 # 0 +0x9E70 0xED11 # 0 +0x9E71 0xED12 # 0 +0x9E72 0xED13 # 0 +0x9E73 0xED14 # 0 +0x9E74 0xED15 # 0 +0x9E75 0xED16 # 0 +0x9E76 0xED17 # 0 +0x9E77 0xED18 # 0 +0x9E78 0xED19 # 0 +0x9E79 0xED1A # 0 +0x9E7A 0xED1B # 0 +0x9E7B 0xED1C # 0 +0x9E7C 0xED1D # 0 +0x9E7D 0xED1E # 0 +0x9E7E 0xED1F # 0 +0x9EA1 0xED20 # 0 +0x9EA2 0xED21 # 0 +0x9EA3 0xED22 # 0 +0x9EA4 0xED23 # 0 +0x9EA5 0xED24 # 0 +0x9EA6 0xED25 # 0 +0x9EA7 0xED26 # 0 +0x9EA8 0xED27 # 0 +0x9EA9 0xED28 # 0 +0x9EAA 0xED29 # 0 +0x9EAB 0xED2A # 0 +0x9EAC 0xED2B # 0 +0x9EAD 0xED2C # 0 +0x9EAE 0xED2D # 0 +0x9EAF 0xED2E # 0 +0x9EB0 0xED2F # 0 +0x9EB1 0xED30 # 0 +0x9EB2 0xED31 # 0 +0x9EB3 0xED32 # 0 +0x9EB4 0xED33 # 0 +0x9EB5 0xED34 # 0 +0x9EB6 0xED35 # 0 +0x9EB7 0xED36 # 0 +0x9EB8 0xED37 # 0 +0x9EB9 0xED38 # 0 +0x9EBA 0xED39 # 0 +0x9EBB 0xED3A # 0 +0x9EBC 0xED3B # 0 +0x9EBD 0xED3C # 0 +0x9EBE 0xED3D # 0 +0x9EBF 0xED3E # 0 +0x9EC0 0xED3F # 0 +0x9EC1 0xED40 # 0 +0x9EC2 0xED41 # 0 +0x9EC3 0xED42 # 0 +0x9EC4 0xED43 # 0 +0x9EC5 0xED44 # 0 +0x9EC6 0xED45 # 0 +0x9EC7 0xED46 # 0 +0x9EC8 0xED47 # 0 +0x9EC9 0xED48 # 0 +0x9ECA 0xED49 # 0 +0x9ECB 0xED4A # 0 +0x9ECC 0xED4B # 0 +0x9ECD 0xED4C # 0 +0x9ECE 0xED4D # 0 +0x9ECF 0xED4E # 0 +0x9ED0 0xED4F # 0 +0x9ED1 0xED50 # 0 +0x9ED2 0xED51 # 0 +0x9ED3 0xED52 # 0 +0x9ED4 0xED53 # 0 +0x9ED5 0xED54 # 0 +0x9ED6 0xED55 # 0 +0x9ED7 0xED56 # 0 +0x9ED8 0xED57 # 0 +0x9ED9 0xED58 # 0 +0x9EDA 0xED59 # 0 +0x9EDB 0xED5A # 0 +0x9EDC 0xED5B # 0 +0x9EDD 0xED5C # 0 +0x9EDE 0xED5D # 0 +0x9EDF 0xED5E # 0 +0x9EE0 0xED5F # 0 +0x9EE1 0xED60 # 0 +0x9EE2 0xED61 # 0 +0x9EE3 0xED62 # 0 +0x9EE4 0xED63 # 0 +0x9EE5 0xED64 # 0 +0x9EE6 0xED65 # 0 +0x9EE7 0xED66 # 0 +0x9EE8 0xED67 # 0 +0x9EE9 0xED68 # 0 +0x9EEA 0xED69 # 0 +0x9EEB 0xED6A # 0 +0x9EEC 0xED6B # 0 +0x9EED 0xED6C # 0 +0x9EEE 0xED6D # 0 +0x9EEF 0xED6E # 0 +0x9EF0 0xED6F # 0 +0x9EF1 0xED70 # 0 +0x9EF2 0xED71 # 0 +0x9EF3 0xED72 # 0 +0x9EF4 0xED73 # 0 +0x9EF5 0xED74 # 0 +0x9EF6 0xED75 # 0 +0x9EF7 0xED76 # 0 +0x9EF8 0xED77 # 0 +0x9EF9 0xED78 # 0 +0x9EFA 0xED79 # 0 +0x9EFB 0xED7A # 0 +0x9EFC 0xED7B # 0 +0x9EFD 0xED7C # 0 +0x9EFE 0xED7D # 0 +0x9F40 0xED7E # 0 +0x9F41 0xED7F # 0 +0x9F42 0xED80 # 0 +0x9F43 0xED81 # 0 +0x9F44 0xED82 # 0 +0x9F45 0xED83 # 0 +0x9F46 0xED84 # 0 +0x9F47 0xED85 # 0 +0x9F48 0xED86 # 0 +0x9F49 0xED87 # 0 +0x9F4A 0xED88 # 0 +0x9F4B 0xED89 # 0 +0x9F4C 0xED8A # 0 +0x9F4D 0xED8B # 0 +0x9F4E 0xED8C # 0 +0x9F4F 0xED8D # 0 +0x9F50 0xED8E # 0 +0x9F51 0xED8F # 0 +0x9F52 0xED90 # 0 +0x9F53 0xED91 # 0 +0x9F54 0xED92 # 0 +0x9F55 0xED93 # 0 +0x9F56 0xED94 # 0 +0x9F57 0xED95 # 0 +0x9F58 0xED96 # 0 +0x9F59 0xED97 # 0 +0x9F5A 0xED98 # 0 +0x9F5B 0xED99 # 0 +0x9F5C 0xED9A # 0 +0x9F5D 0xED9B # 0 +0x9F5E 0xED9C # 0 +0x9F5F 0xED9D # 0 +0x9F60 0xED9E # 0 +0x9F61 0xED9F # 0 +0x9F62 0xEDA0 # 0 +0x9F63 0xEDA1 # 0 +0x9F64 0xEDA2 # 0 +0x9F65 0xEDA3 # 0 +0x9F66 0xEDA4 # 0 +0x9F67 0xEDA5 # 0 +0x9F68 0xEDA6 # 0 +0x9F69 0xEDA7 # 0 +0x9F6A 0xEDA8 # 0 +0x9F6B 0xEDA9 # 0 +0x9F6C 0xEDAA # 0 +0x9F6D 0xEDAB # 0 +0x9F6E 0xEDAC # 0 +0x9F6F 0xEDAD # 0 +0x9F70 0xEDAE # 0 +0x9F71 0xEDAF # 0 +0x9F72 0xEDB0 # 0 +0x9F73 0xEDB1 # 0 +0x9F74 0xEDB2 # 0 +0x9F75 0xEDB3 # 0 +0x9F76 0xEDB4 # 0 +0x9F77 0xEDB5 # 0 +0x9F78 0xEDB6 # 0 +0x9F79 0xEDB7 # 0 +0x9F7A 0xEDB8 # 0 +0x9F7B 0xEDB9 # 0 +0x9F7C 0xEDBA # 0 +0x9F7D 0xEDBB # 0 +0x9F7E 0xEDBC # 0 +0x9FA1 0xEDBD # 0 +0x9FA2 0xEDBE # 0 +0x9FA3 0xEDBF # 0 +0x9FA4 0xEDC0 # 0 +0x9FA5 0xEDC1 # 0 +0x9FA6 0xEDC2 # 0 +0x9FA7 0xEDC3 # 0 +0x9FA8 0xEDC4 # 0 +0x9FA9 0xEDC5 # 0 +0x9FAA 0xEDC6 # 0 +0x9FAB 0xEDC7 # 0 +0x9FAC 0xEDC8 # 0 +0x9FAD 0xEDC9 # 0 +0x9FAE 0xEDCA # 0 +0x9FAF 0xEDCB # 0 +0x9FB0 0xEDCC # 0 +0x9FB1 0xEDCD # 0 +0x9FB2 0xEDCE # 0 +0x9FB3 0xEDCF # 0 +0x9FB4 0xEDD0 # 0 +0x9FB5 0xEDD1 # 0 +0x9FB6 0xEDD2 # 0 +0x9FB7 0xEDD3 # 0 +0x9FB8 0xEDD4 # 0 +0x9FB9 0xEDD5 # 0 +0x9FBA 0xEDD6 # 0 +0x9FBB 0xEDD7 # 0 +0x9FBC 0xEDD8 # 0 +0x9FBD 0xEDD9 # 0 +0x9FBE 0xEDDA # 0 +0x9FBF 0xEDDB # 0 +0x9FC0 0xEDDC # 0 +0x9FC1 0xEDDD # 0 +0x9FC2 0xEDDE # 0 +0x9FC3 0xEDDF # 0 +0x9FC4 0xEDE0 # 0 +0x9FC5 0xEDE1 # 0 +0x9FC6 0xEDE2 # 0 +0x9FC7 0xEDE3 # 0 +0x9FC8 0xEDE4 # 0 +0x9FC9 0xEDE5 # 0 +0x9FCA 0xEDE6 # 0 +0x9FCB 0xEDE7 # 0 +0x9FCC 0xEDE8 # 0 +0x9FCD 0xEDE9 # 0 +0x9FCE 0xEDEA # 0 +0x9FCF 0xEDEB # 0 +0x9FD0 0xEDEC # 0 +0x9FD1 0xEDED # 0 +0x9FD2 0xEDEE # 0 +0x9FD3 0xEDEF # 0 +0x9FD4 0xEDF0 # 0 +0x9FD5 0xEDF1 # 0 +0x9FD6 0xEDF2 # 0 +0x9FD7 0xEDF3 # 0 +0x9FD8 0xEDF4 # 0 +0x9FD9 0xEDF5 # 0 +0x9FDA 0xEDF6 # 0 +0x9FDB 0xEDF7 # 0 +0x9FDC 0xEDF8 # 0 +0x9FDD 0xEDF9 # 0 +0x9FDE 0xEDFA # 0 +0x9FDF 0xEDFB # 0 +0x9FE0 0xEDFC # 0 +0x9FE1 0xEDFD # 0 +0x9FE2 0xEDFE # 0 +0x9FE3 0xEDFF # 0 +0x9FE4 0xEE00 # 0 +0x9FE5 0xEE01 # 0 +0x9FE6 0xEE02 # 0 +0x9FE7 0xEE03 # 0 +0x9FE8 0xEE04 # 0 +0x9FE9 0xEE05 # 0 +0x9FEA 0xEE06 # 0 +0x9FEB 0xEE07 # 0 +0x9FEC 0xEE08 # 0 +0x9FED 0xEE09 # 0 +0x9FEE 0xEE0A # 0 +0x9FEF 0xEE0B # 0 +0x9FF0 0xEE0C # 0 +0x9FF1 0xEE0D # 0 +0x9FF2 0xEE0E # 0 +0x9FF3 0xEE0F # 0 +0x9FF4 0xEE10 # 0 +0x9FF5 0xEE11 # 0 +0x9FF6 0xEE12 # 0 +0x9FF7 0xEE13 # 0 +0x9FF8 0xEE14 # 0 +0x9FF9 0xEE15 # 0 +0x9FFA 0xEE16 # 0 +0x9FFB 0xEE17 # 0 +0x9FFC 0xEE18 # 0 +0x9FFD 0xEE19 # 0 +0x9FFE 0xEE1A # 0 +0xA040 0xEE1B # 0 +0xA041 0xEE1C # 0 +0xA042 0xEE1D # 0 +0xA043 0xEE1E # 0 +0xA044 0xEE1F # 0 +0xA045 0xEE20 # 0 +0xA046 0xEE21 # 0 +0xA047 0xEE22 # 0 +0xA048 0xEE23 # 0 +0xA049 0xEE24 # 0 +0xA04A 0xEE25 # 0 +0xA04B 0xEE26 # 0 +0xA04C 0xEE27 # 0 +0xA04D 0xEE28 # 0 +0xA04E 0xEE29 # 0 +0xA04F 0xEE2A # 0 +0xA050 0xEE2B # 0 +0xA051 0xEE2C # 0 +0xA052 0xEE2D # 0 +0xA053 0xEE2E # 0 +0xA054 0xEE2F # 0 +0xA055 0xEE30 # 0 +0xA056 0xEE31 # 0 +0xA057 0xEE32 # 0 +0xA058 0xEE33 # 0 +0xA059 0xEE34 # 0 +0xA05A 0xEE35 # 0 +0xA05B 0xEE36 # 0 +0xA05C 0xEE37 # 0 +0xA05D 0xEE38 # 0 +0xA05E 0xEE39 # 0 +0xA05F 0xEE3A # 0 +0xA060 0xEE3B # 0 +0xA061 0xEE3C # 0 +0xA062 0xEE3D # 0 +0xA063 0xEE3E # 0 +0xA064 0xEE3F # 0 +0xA065 0xEE40 # 0 +0xA066 0xEE41 # 0 +0xA067 0xEE42 # 0 +0xA068 0xEE43 # 0 +0xA069 0xEE44 # 0 +0xA06A 0xEE45 # 0 +0xA06B 0xEE46 # 0 +0xA06C 0xEE47 # 0 +0xA06D 0xEE48 # 0 +0xA06E 0xEE49 # 0 +0xA06F 0xEE4A # 0 +0xA070 0xEE4B # 0 +0xA071 0xEE4C # 0 +0xA072 0xEE4D # 0 +0xA073 0xEE4E # 0 +0xA074 0xEE4F # 0 +0xA075 0xEE50 # 0 +0xA076 0xEE51 # 0 +0xA077 0xEE52 # 0 +0xA078 0xEE53 # 0 +0xA079 0xEE54 # 0 +0xA07A 0xEE55 # 0 +0xA07B 0xEE56 # 0 +0xA07C 0xEE57 # 0 +0xA07D 0xEE58 # 0 +0xA07E 0xEE59 # 0 +0xA0A1 0xEE5A # 0 +0xA0A2 0xEE5B # 0 +0xA0A3 0xEE5C # 0 +0xA0A4 0xEE5D # 0 +0xA0A5 0xEE5E # 0 +0xA0A6 0xEE5F # 0 +0xA0A7 0xEE60 # 0 +0xA0A8 0xEE61 # 0 +0xA0A9 0xEE62 # 0 +0xA0AA 0xEE63 # 0 +0xA0AB 0xEE64 # 0 +0xA0AC 0xEE65 # 0 +0xA0AD 0xEE66 # 0 +0xA0AE 0xEE67 # 0 +0xA0AF 0xEE68 # 0 +0xA0B0 0xEE69 # 0 +0xA0B1 0xEE6A # 0 +0xA0B2 0xEE6B # 0 +0xA0B3 0xEE6C # 0 +0xA0B4 0xEE6D # 0 +0xA0B5 0xEE6E # 0 +0xA0B6 0xEE6F # 0 +0xA0B7 0xEE70 # 0 +0xA0B8 0xEE71 # 0 +0xA0B9 0xEE72 # 0 +0xA0BA 0xEE73 # 0 +0xA0BB 0xEE74 # 0 +0xA0BC 0xEE75 # 0 +0xA0BD 0xEE76 # 0 +0xA0BE 0xEE77 # 0 +0xA0BF 0xEE78 # 0 +0xA0C0 0xEE79 # 0 +0xA0C1 0xEE7A # 0 +0xA0C2 0xEE7B # 0 +0xA0C3 0xEE7C # 0 +0xA0C4 0xEE7D # 0 +0xA0C5 0xEE7E # 0 +0xA0C6 0xEE7F # 0 +0xA0C7 0xEE80 # 0 +0xA0C8 0xEE81 # 0 +0xA0C9 0xEE82 # 0 +0xA0CA 0xEE83 # 0 +0xA0CB 0xEE84 # 0 +0xA0CC 0xEE85 # 0 +0xA0CD 0xEE86 # 0 +0xA0CE 0xEE87 # 0 +0xA0CF 0xEE88 # 0 +0xA0D0 0xEE89 # 0 +0xA0D1 0xEE8A # 0 +0xA0D2 0xEE8B # 0 +0xA0D3 0xEE8C # 0 +0xA0D4 0xEE8D # 0 +0xA0D5 0xEE8E # 0 +0xA0D6 0xEE8F # 0 +0xA0D7 0xEE90 # 0 +0xA0D8 0xEE91 # 0 +0xA0D9 0xEE92 # 0 +0xA0DA 0xEE93 # 0 +0xA0DB 0xEE94 # 0 +0xA0DC 0xEE95 # 0 +0xA0DD 0xEE96 # 0 +0xA0DE 0xEE97 # 0 +0xA0DF 0xEE98 # 0 +0xA0E0 0xEE99 # 0 +0xA0E1 0xEE9A # 0 +0xA0E2 0xEE9B # 0 +0xA0E3 0xEE9C # 0 +0xA0E4 0xEE9D # 0 +0xA0E5 0xEE9E # 0 +0xA0E6 0xEE9F # 0 +0xA0E7 0xEEA0 # 0 +0xA0E8 0xEEA1 # 0 +0xA0E9 0xEEA2 # 0 +0xA0EA 0xEEA3 # 0 +0xA0EB 0xEEA4 # 0 +0xA0EC 0xEEA5 # 0 +0xA0ED 0xEEA6 # 0 +0xA0EE 0xEEA7 # 0 +0xA0EF 0xEEA8 # 0 +0xA0F0 0xEEA9 # 0 +0xA0F1 0xEEAA # 0 +0xA0F2 0xEEAB # 0 +0xA0F3 0xEEAC # 0 +0xA0F4 0xEEAD # 0 +0xA0F5 0xEEAE # 0 +0xA0F6 0xEEAF # 0 +0xA0F7 0xEEB0 # 0 +0xA0F8 0xEEB1 # 0 +0xA0F9 0xEEB2 # 0 +0xA0FA 0xEEB3 # 0 +0xA0FB 0xEEB4 # 0 +0xA0FC 0xEEB5 # 0 +0xA0FD 0xEEB6 # 0 +0xA0FE 0xEEB7 # 0 +0xA140 0x3000 # 0 +0xA141 0xFF0C # 0 +0xA142 0x3001 # 0 +0xA143 0x3002 # 0 +0xA144 0xFF0E # 0 +0xA145 0x2027 # 0 +0xA146 0xFF1B # 0 +0xA147 0xFF1A # 0 +0xA148 0xFF1F # 0 +0xA149 0xFF01 # 0 +0xA14A 0xFE30 # 0 +0xA14B 0x2026 # 0 +0xA14C 0x2025 # 0 +0xA14D 0xFE50 # 0 +0xA14E 0xFE51 # 0 +0xA14F 0xFE52 # 0 +0xA150 0x00B7 # 0 +0xA151 0xFE54 # 0 +0xA152 0xFE55 # 0 +0xA153 0xFE56 # 0 +0xA154 0xFE57 # 0 +0xA155 0xFF5C # 0 +0xA156 0x2013 # 0 +0xA157 0xFE31 # 0 +0xA158 0x2014 # 0 +0xA159 0xFE33 # 0 +0xA15A 0x2574 # 0 +0xA15B 0xFE34 # 0 +0xA15C 0xFE4F # 0 +0xA15D 0xFF08 # 0 +0xA15E 0xFF09 # 0 +0xA15F 0xFE35 # 0 +0xA160 0xFE36 # 0 +0xA161 0xFF5B # 0 +0xA162 0xFF5D # 0 +0xA163 0xFE37 # 0 +0xA164 0xFE38 # 0 +0xA165 0x3014 # 0 +0xA166 0x3015 # 0 +0xA167 0xFE39 # 0 +0xA168 0xFE3A # 0 +0xA169 0x3010 # 0 +0xA16A 0x3011 # 0 +0xA16B 0xFE3B # 0 +0xA16C 0xFE3C # 0 +0xA16D 0x300A # 0 +0xA16E 0x300B # 0 +0xA16F 0xFE3D # 0 +0xA170 0xFE3E # 0 +0xA171 0x3008 # 0 +0xA172 0x3009 # 0 +0xA173 0xFE3F # 0 +0xA174 0xFE40 # 0 +0xA175 0x300C # 0 +0xA176 0x300D # 0 +0xA177 0xFE41 # 0 +0xA178 0xFE42 # 0 +0xA179 0x300E # 0 +0xA17A 0x300F # 0 +0xA17B 0xFE43 # 0 +0xA17C 0xFE44 # 0 +0xA17D 0xFE59 # 0 +0xA17E 0xFE5A # 0 +0xA1A1 0xFE5B # 0 +0xA1A2 0xFE5C # 0 +0xA1A3 0xFE5D # 0 +0xA1A4 0xFE5E # 0 +0xA1A5 0x2018 # 0 +0xA1A6 0x2019 # 0 +0xA1A7 0x201C # 0 +0xA1A8 0x201D # 0 +0xA1A9 0x301D # 0 +0xA1AA 0x301E # 0 +0xA1AB 0x2035 # 0 +0xA1AC 0x2032 # 0 +0xA1AD 0xFF03 # 0 +0xA1AE 0xFF06 # 0 +0xA1AF 0xFF0A # 0 +0xA1B0 0x203B # 0 +0xA1B1 0x00A7 # 0 +0xA1B2 0x3003 # 0 +0xA1B3 0x25CB # 0 +0xA1B4 0x25CF # 0 +0xA1B5 0x25B3 # 0 +0xA1B6 0x25B2 # 0 +0xA1B7 0x25CE # 0 +0xA1B8 0x2606 # 0 +0xA1B9 0x2605 # 0 +0xA1BA 0x25C7 # 0 +0xA1BB 0x25C6 # 0 +0xA1BC 0x25A1 # 0 +0xA1BD 0x25A0 # 0 +0xA1BE 0x25BD # 0 +0xA1BF 0x25BC # 0 +0xA1C0 0x32A3 # 0 +0xA1C1 0x2105 # 0 +0xA1C2 0x00AF # 0 +0xA1C3 0xFFE3 # 0 +0xA1C4 0xFF3F # 0 +0xA1C5 0x02CD # 0 +0xA1C6 0xFE49 # 0 +0xA1C7 0xFE4A # 0 +0xA1C8 0xFE4D # 0 +0xA1C9 0xFE4E # 0 +0xA1CA 0xFE4B # 0 +0xA1CB 0xFE4C # 0 +0xA1CC 0xFE5F # 0 +0xA1CD 0xFE60 # 0 +0xA1CE 0xFE61 # 0 +0xA1CF 0xFF0B # 0 +0xA1D0 0xFF0D # 0 +0xA1D1 0x00D7 # 0 +0xA1D2 0x00F7 # 0 +0xA1D3 0x00B1 # 0 +0xA1D4 0x221A # 0 +0xA1D5 0xFF1C # 0 +0xA1D6 0xFF1E # 0 +0xA1D7 0xFF1D # 0 +0xA1D8 0x2266 # 0 +0xA1D9 0x2267 # 0 +0xA1DA 0x2260 # 0 +0xA1DB 0x221E # 0 +0xA1DC 0x2252 # 0 +0xA1DD 0x2261 # 0 +0xA1DE 0xFE62 # 0 +0xA1DF 0xFE63 # 0 +0xA1E0 0xFE64 # 0 +0xA1E1 0xFE65 # 0 +0xA1E2 0xFE66 # 0 +0xA1E3 0xFF5E # 0 +0xA1E4 0x2229 # 0 +0xA1E5 0x222A # 0 +0xA1E6 0x22A5 # 0 +0xA1E7 0x2220 # 0 +0xA1E8 0x221F # 0 +0xA1E9 0x22BF # 0 +0xA1EA 0x33D2 # 0 +0xA1EB 0x33D1 # 0 +0xA1EC 0x222B # 0 +0xA1ED 0x222E # 0 +0xA1EE 0x2235 # 0 +0xA1EF 0x2234 # 0 +0xA1F0 0x2640 # 0 +0xA1F1 0x2642 # 0 +0xA1F2 0x2295 # 0 +0xA1F3 0x2299 # 0 +0xA1F4 0x2191 # 0 +0xA1F5 0x2193 # 0 +0xA1F6 0x2190 # 0 +0xA1F7 0x2192 # 0 +0xA1F8 0x2196 # 0 +0xA1F9 0x2197 # 0 +0xA1FA 0x2199 # 0 +0xA1FB 0x2198 # 0 +0xA1FC 0x2225 # 0 +0xA1FD 0x2223 # 0 +0xA1FE 0xFF0F # 0 +0xA240 0xFF3C # 0 +0xA241 0x2215 # 0 +0xA242 0xFE68 # 0 +0xA243 0xFF04 # 0 +0xA244 0xFFE5 # 0 +0xA245 0x3012 # 0 +0xA246 0xFFE0 # 0 +0xA247 0xFFE1 # 0 +0xA248 0xFF05 # 0 +0xA249 0xFF20 # 0 +0xA24A 0x2103 # 0 +0xA24B 0x2109 # 0 +0xA24C 0xFE69 # 0 +0xA24D 0xFE6A # 0 +0xA24E 0xFE6B # 0 +0xA24F 0x33D5 # 0 +0xA250 0x339C # 0 +0xA251 0x339D # 0 +0xA252 0x339E # 0 +0xA253 0x33CE # 0 +0xA254 0x33A1 # 0 +0xA255 0x338E # 0 +0xA256 0x338F # 0 +0xA257 0x33C4 # 0 +0xA258 0x00B0 # 0 +0xA259 0x5159 # 0 +0xA25A 0x515B # 0 +0xA25B 0x515E # 0 +0xA25C 0x515D # 0 +0xA25D 0x5161 # 0 +0xA25E 0x5163 # 0 +0xA25F 0x55E7 # 0 +0xA260 0x74E9 # 0 +0xA261 0x7CCE # 0 +0xA262 0x2581 # 0 +0xA263 0x2582 # 0 +0xA264 0x2583 # 0 +0xA265 0x2584 # 0 +0xA266 0x2585 # 0 +0xA267 0x2586 # 0 +0xA268 0x2587 # 0 +0xA269 0x2588 # 0 +0xA26A 0x258F # 0 +0xA26B 0x258E # 0 +0xA26C 0x258D # 0 +0xA26D 0x258C # 0 +0xA26E 0x258B # 0 +0xA26F 0x258A # 0 +0xA270 0x2589 # 0 +0xA271 0x253C # 0 +0xA272 0x2534 # 0 +0xA273 0x252C # 0 +0xA274 0x2524 # 0 +0xA275 0x251C # 0 +0xA276 0x2594 # 0 +0xA277 0x2500 # 0 +0xA278 0x2502 # 0 +0xA279 0x2595 # 0 +0xA27A 0x250C # 0 +0xA27B 0x2510 # 0 +0xA27C 0x2514 # 0 +0xA27D 0x2518 # 0 +0xA27E 0x256D # 0 +0xA2A1 0x256E # 0 +0xA2A2 0x2570 # 0 +0xA2A3 0x256F # 0 +0xA2A8 0x25E2 # 0 +0xA2A9 0x25E3 # 0 +0xA2AA 0x25E5 # 0 +0xA2AB 0x25E4 # 0 +0xA2AC 0x2571 # 0 +0xA2AD 0x2572 # 0 +0xA2AE 0x2573 # 0 +0xA2AF 0xFF10 # 0 +0xA2B0 0xFF11 # 0 +0xA2B1 0xFF12 # 0 +0xA2B2 0xFF13 # 0 +0xA2B3 0xFF14 # 0 +0xA2B4 0xFF15 # 0 +0xA2B5 0xFF16 # 0 +0xA2B6 0xFF17 # 0 +0xA2B7 0xFF18 # 0 +0xA2B8 0xFF19 # 0 +0xA2B9 0x2160 # 0 +0xA2BA 0x2161 # 0 +0xA2BB 0x2162 # 0 +0xA2BC 0x2163 # 0 +0xA2BD 0x2164 # 0 +0xA2BE 0x2165 # 0 +0xA2BF 0x2166 # 0 +0xA2C0 0x2167 # 0 +0xA2C1 0x2168 # 0 +0xA2C2 0x2169 # 0 +0xA2C3 0x3021 # 0 +0xA2C4 0x3022 # 0 +0xA2C5 0x3023 # 0 +0xA2C6 0x3024 # 0 +0xA2C7 0x3025 # 0 +0xA2C8 0x3026 # 0 +0xA2C9 0x3027 # 0 +0xA2CA 0x3028 # 0 +0xA2CB 0x3029 # 0 +0xA2CD 0x5344 # 0 +0xA2CF 0xFF21 # 0 +0xA2D0 0xFF22 # 0 +0xA2D1 0xFF23 # 0 +0xA2D2 0xFF24 # 0 +0xA2D3 0xFF25 # 0 +0xA2D4 0xFF26 # 0 +0xA2D5 0xFF27 # 0 +0xA2D6 0xFF28 # 0 +0xA2D7 0xFF29 # 0 +0xA2D8 0xFF2A # 0 +0xA2D9 0xFF2B # 0 +0xA2DA 0xFF2C # 0 +0xA2DB 0xFF2D # 0 +0xA2DC 0xFF2E # 0 +0xA2DD 0xFF2F # 0 +0xA2DE 0xFF30 # 0 +0xA2DF 0xFF31 # 0 +0xA2E0 0xFF32 # 0 +0xA2E1 0xFF33 # 0 +0xA2E2 0xFF34 # 0 +0xA2E3 0xFF35 # 0 +0xA2E4 0xFF36 # 0 +0xA2E5 0xFF37 # 0 +0xA2E6 0xFF38 # 0 +0xA2E7 0xFF39 # 0 +0xA2E8 0xFF3A # 0 +0xA2E9 0xFF41 # 0 +0xA2EA 0xFF42 # 0 +0xA2EB 0xFF43 # 0 +0xA2EC 0xFF44 # 0 +0xA2ED 0xFF45 # 0 +0xA2EE 0xFF46 # 0 +0xA2EF 0xFF47 # 0 +0xA2F0 0xFF48 # 0 +0xA2F1 0xFF49 # 0 +0xA2F2 0xFF4A # 0 +0xA2F3 0xFF4B # 0 +0xA2F4 0xFF4C # 0 +0xA2F5 0xFF4D # 0 +0xA2F6 0xFF4E # 0 +0xA2F7 0xFF4F # 0 +0xA2F8 0xFF50 # 0 +0xA2F9 0xFF51 # 0 +0xA2FA 0xFF52 # 0 +0xA2FB 0xFF53 # 0 +0xA2FC 0xFF54 # 0 +0xA2FD 0xFF55 # 0 +0xA2FE 0xFF56 # 0 +0xA340 0xFF57 # 0 +0xA341 0xFF58 # 0 +0xA342 0xFF59 # 0 +0xA343 0xFF5A # 0 +0xA344 0x0391 # 0 +0xA345 0x0392 # 0 +0xA346 0x0393 # 0 +0xA347 0x0394 # 0 +0xA348 0x0395 # 0 +0xA349 0x0396 # 0 +0xA34A 0x0397 # 0 +0xA34B 0x0398 # 0 +0xA34C 0x0399 # 0 +0xA34D 0x039A # 0 +0xA34E 0x039B # 0 +0xA34F 0x039C # 0 +0xA350 0x039D # 0 +0xA351 0x039E # 0 +0xA352 0x039F # 0 +0xA353 0x03A0 # 0 +0xA354 0x03A1 # 0 +0xA355 0x03A3 # 0 +0xA356 0x03A4 # 0 +0xA357 0x03A5 # 0 +0xA358 0x03A6 # 0 +0xA359 0x03A7 # 0 +0xA35A 0x03A8 # 0 +0xA35B 0x03A9 # 0 +0xA35C 0x03B1 # 0 +0xA35D 0x03B2 # 0 +0xA35E 0x03B3 # 0 +0xA35F 0x03B4 # 0 +0xA360 0x03B5 # 0 +0xA361 0x03B6 # 0 +0xA362 0x03B7 # 0 +0xA363 0x03B8 # 0 +0xA364 0x03B9 # 0 +0xA365 0x03BA # 0 +0xA366 0x03BB # 0 +0xA367 0x03BC # 0 +0xA368 0x03BD # 0 +0xA369 0x03BE # 0 +0xA36A 0x03BF # 0 +0xA36B 0x03C0 # 0 +0xA36C 0x03C1 # 0 +0xA36D 0x03C3 # 0 +0xA36E 0x03C4 # 0 +0xA36F 0x03C5 # 0 +0xA370 0x03C6 # 0 +0xA371 0x03C7 # 0 +0xA372 0x03C8 # 0 +0xA373 0x03C9 # 0 +0xA374 0x3105 # 0 +0xA375 0x3106 # 0 +0xA376 0x3107 # 0 +0xA377 0x3108 # 0 +0xA378 0x3109 # 0 +0xA379 0x310A # 0 +0xA37A 0x310B # 0 +0xA37B 0x310C # 0 +0xA37C 0x310D # 0 +0xA37D 0x310E # 0 +0xA37E 0x310F # 0 +0xA3A1 0x3110 # 0 +0xA3A2 0x3111 # 0 +0xA3A3 0x3112 # 0 +0xA3A4 0x3113 # 0 +0xA3A5 0x3114 # 0 +0xA3A6 0x3115 # 0 +0xA3A7 0x3116 # 0 +0xA3A8 0x3117 # 0 +0xA3A9 0x3118 # 0 +0xA3AA 0x3119 # 0 +0xA3AB 0x311A # 0 +0xA3AC 0x311B # 0 +0xA3AD 0x311C # 0 +0xA3AE 0x311D # 0 +0xA3AF 0x311E # 0 +0xA3B0 0x311F # 0 +0xA3B1 0x3120 # 0 +0xA3B2 0x3121 # 0 +0xA3B3 0x3122 # 0 +0xA3B4 0x3123 # 0 +0xA3B5 0x3124 # 0 +0xA3B6 0x3125 # 0 +0xA3B7 0x3126 # 0 +0xA3B8 0x3127 # 0 +0xA3B9 0x3128 # 0 +0xA3BA 0x3129 # 0 +0xA3BB 0x02D9 # 0 +0xA3BC 0x02C9 # 0 +0xA3BD 0x02CA # 0 +0xA3BE 0x02C7 # 0 +0xA3BF 0x02CB # 0 +0xA3E1 0x20AC # 0 +0xA440 0x4E00 # 0 +0xA441 0x4E59 # 0 +0xA442 0x4E01 # 0 +0xA443 0x4E03 # 0 +0xA444 0x4E43 # 0 +0xA445 0x4E5D # 0 +0xA446 0x4E86 # 0 +0xA447 0x4E8C # 0 +0xA448 0x4EBA # 0 +0xA449 0x513F # 0 +0xA44A 0x5165 # 0 +0xA44B 0x516B # 0 +0xA44C 0x51E0 # 0 +0xA44D 0x5200 # 0 +0xA44E 0x5201 # 0 +0xA44F 0x529B # 0 +0xA450 0x5315 # 0 +0xA451 0x5341 # 0 +0xA452 0x535C # 0 +0xA453 0x53C8 # 0 +0xA454 0x4E09 # 0 +0xA455 0x4E0B # 0 +0xA456 0x4E08 # 0 +0xA457 0x4E0A # 0 +0xA458 0x4E2B # 0 +0xA459 0x4E38 # 0 +0xA45A 0x51E1 # 0 +0xA45B 0x4E45 # 0 +0xA45C 0x4E48 # 0 +0xA45D 0x4E5F # 0 +0xA45E 0x4E5E # 0 +0xA45F 0x4E8E # 0 +0xA460 0x4EA1 # 0 +0xA461 0x5140 # 0 +0xA462 0x5203 # 0 +0xA463 0x52FA # 0 +0xA464 0x5343 # 0 +0xA465 0x53C9 # 0 +0xA466 0x53E3 # 0 +0xA467 0x571F # 0 +0xA468 0x58EB # 0 +0xA469 0x5915 # 0 +0xA46A 0x5927 # 0 +0xA46B 0x5973 # 0 +0xA46C 0x5B50 # 0 +0xA46D 0x5B51 # 0 +0xA46E 0x5B53 # 0 +0xA46F 0x5BF8 # 0 +0xA470 0x5C0F # 0 +0xA471 0x5C22 # 0 +0xA472 0x5C38 # 0 +0xA473 0x5C71 # 0 +0xA474 0x5DDD # 0 +0xA475 0x5DE5 # 0 +0xA476 0x5DF1 # 0 +0xA477 0x5DF2 # 0 +0xA478 0x5DF3 # 0 +0xA479 0x5DFE # 0 +0xA47A 0x5E72 # 0 +0xA47B 0x5EFE # 0 +0xA47C 0x5F0B # 0 +0xA47D 0x5F13 # 0 +0xA47E 0x624D # 0 +0xA4A1 0x4E11 # 0 +0xA4A2 0x4E10 # 0 +0xA4A3 0x4E0D # 0 +0xA4A4 0x4E2D # 0 +0xA4A5 0x4E30 # 0 +0xA4A6 0x4E39 # 0 +0xA4A7 0x4E4B # 0 +0xA4A8 0x5C39 # 0 +0xA4A9 0x4E88 # 0 +0xA4AA 0x4E91 # 0 +0xA4AB 0x4E95 # 0 +0xA4AC 0x4E92 # 0 +0xA4AD 0x4E94 # 0 +0xA4AE 0x4EA2 # 0 +0xA4AF 0x4EC1 # 0 +0xA4B0 0x4EC0 # 0 +0xA4B1 0x4EC3 # 0 +0xA4B2 0x4EC6 # 0 +0xA4B3 0x4EC7 # 0 +0xA4B4 0x4ECD # 0 +0xA4B5 0x4ECA # 0 +0xA4B6 0x4ECB # 0 +0xA4B7 0x4EC4 # 0 +0xA4B8 0x5143 # 0 +0xA4B9 0x5141 # 0 +0xA4BA 0x5167 # 0 +0xA4BB 0x516D # 0 +0xA4BC 0x516E # 0 +0xA4BD 0x516C # 0 +0xA4BE 0x5197 # 0 +0xA4BF 0x51F6 # 0 +0xA4C0 0x5206 # 0 +0xA4C1 0x5207 # 0 +0xA4C2 0x5208 # 0 +0xA4C3 0x52FB # 0 +0xA4C4 0x52FE # 0 +0xA4C5 0x52FF # 0 +0xA4C6 0x5316 # 0 +0xA4C7 0x5339 # 0 +0xA4C8 0x5348 # 0 +0xA4C9 0x5347 # 0 +0xA4CA 0x5345 # 0 +0xA4CB 0x535E # 0 +0xA4CC 0x5384 # 0 +0xA4CD 0x53CB # 0 +0xA4CE 0x53CA # 0 +0xA4CF 0x53CD # 0 +0xA4D0 0x58EC # 0 +0xA4D1 0x5929 # 0 +0xA4D2 0x592B # 0 +0xA4D3 0x592A # 0 +0xA4D4 0x592D # 0 +0xA4D5 0x5B54 # 0 +0xA4D6 0x5C11 # 0 +0xA4D7 0x5C24 # 0 +0xA4D8 0x5C3A # 0 +0xA4D9 0x5C6F # 0 +0xA4DA 0x5DF4 # 0 +0xA4DB 0x5E7B # 0 +0xA4DC 0x5EFF # 0 +0xA4DD 0x5F14 # 0 +0xA4DE 0x5F15 # 0 +0xA4DF 0x5FC3 # 0 +0xA4E0 0x6208 # 0 +0xA4E1 0x6236 # 0 +0xA4E2 0x624B # 0 +0xA4E3 0x624E # 0 +0xA4E4 0x652F # 0 +0xA4E5 0x6587 # 0 +0xA4E6 0x6597 # 0 +0xA4E7 0x65A4 # 0 +0xA4E8 0x65B9 # 0 +0xA4E9 0x65E5 # 0 +0xA4EA 0x66F0 # 0 +0xA4EB 0x6708 # 0 +0xA4EC 0x6728 # 0 +0xA4ED 0x6B20 # 0 +0xA4EE 0x6B62 # 0 +0xA4EF 0x6B79 # 0 +0xA4F0 0x6BCB # 0 +0xA4F1 0x6BD4 # 0 +0xA4F2 0x6BDB # 0 +0xA4F3 0x6C0F # 0 +0xA4F4 0x6C34 # 0 +0xA4F5 0x706B # 0 +0xA4F6 0x722A # 0 +0xA4F7 0x7236 # 0 +0xA4F8 0x723B # 0 +0xA4F9 0x7247 # 0 +0xA4FA 0x7259 # 0 +0xA4FB 0x725B # 0 +0xA4FC 0x72AC # 0 +0xA4FD 0x738B # 0 +0xA4FE 0x4E19 # 0 +0xA540 0x4E16 # 0 +0xA541 0x4E15 # 0 +0xA542 0x4E14 # 0 +0xA543 0x4E18 # 0 +0xA544 0x4E3B # 0 +0xA545 0x4E4D # 0 +0xA546 0x4E4F # 0 +0xA547 0x4E4E # 0 +0xA548 0x4EE5 # 0 +0xA549 0x4ED8 # 0 +0xA54A 0x4ED4 # 0 +0xA54B 0x4ED5 # 0 +0xA54C 0x4ED6 # 0 +0xA54D 0x4ED7 # 0 +0xA54E 0x4EE3 # 0 +0xA54F 0x4EE4 # 0 +0xA550 0x4ED9 # 0 +0xA551 0x4EDE # 0 +0xA552 0x5145 # 0 +0xA553 0x5144 # 0 +0xA554 0x5189 # 0 +0xA555 0x518A # 0 +0xA556 0x51AC # 0 +0xA557 0x51F9 # 0 +0xA558 0x51FA # 0 +0xA559 0x51F8 # 0 +0xA55A 0x520A # 0 +0xA55B 0x52A0 # 0 +0xA55C 0x529F # 0 +0xA55D 0x5305 # 0 +0xA55E 0x5306 # 0 +0xA55F 0x5317 # 0 +0xA560 0x531D # 0 +0xA561 0x4EDF # 0 +0xA562 0x534A # 0 +0xA563 0x5349 # 0 +0xA564 0x5361 # 0 +0xA565 0x5360 # 0 +0xA566 0x536F # 0 +0xA567 0x536E # 0 +0xA568 0x53BB # 0 +0xA569 0x53EF # 0 +0xA56A 0x53E4 # 0 +0xA56B 0x53F3 # 0 +0xA56C 0x53EC # 0 +0xA56D 0x53EE # 0 +0xA56E 0x53E9 # 0 +0xA56F 0x53E8 # 0 +0xA570 0x53FC # 0 +0xA571 0x53F8 # 0 +0xA572 0x53F5 # 0 +0xA573 0x53EB # 0 +0xA574 0x53E6 # 0 +0xA575 0x53EA # 0 +0xA576 0x53F2 # 0 +0xA577 0x53F1 # 0 +0xA578 0x53F0 # 0 +0xA579 0x53E5 # 0 +0xA57A 0x53ED # 0 +0xA57B 0x53FB # 0 +0xA57C 0x56DB # 0 +0xA57D 0x56DA # 0 +0xA57E 0x5916 # 0 +0xA5A1 0x592E # 0 +0xA5A2 0x5931 # 0 +0xA5A3 0x5974 # 0 +0xA5A4 0x5976 # 0 +0xA5A5 0x5B55 # 0 +0xA5A6 0x5B83 # 0 +0xA5A7 0x5C3C # 0 +0xA5A8 0x5DE8 # 0 +0xA5A9 0x5DE7 # 0 +0xA5AA 0x5DE6 # 0 +0xA5AB 0x5E02 # 0 +0xA5AC 0x5E03 # 0 +0xA5AD 0x5E73 # 0 +0xA5AE 0x5E7C # 0 +0xA5AF 0x5F01 # 0 +0xA5B0 0x5F18 # 0 +0xA5B1 0x5F17 # 0 +0xA5B2 0x5FC5 # 0 +0xA5B3 0x620A # 0 +0xA5B4 0x6253 # 0 +0xA5B5 0x6254 # 0 +0xA5B6 0x6252 # 0 +0xA5B7 0x6251 # 0 +0xA5B8 0x65A5 # 0 +0xA5B9 0x65E6 # 0 +0xA5BA 0x672E # 0 +0xA5BB 0x672C # 0 +0xA5BC 0x672A # 0 +0xA5BD 0x672B # 0 +0xA5BE 0x672D # 0 +0xA5BF 0x6B63 # 0 +0xA5C0 0x6BCD # 0 +0xA5C1 0x6C11 # 0 +0xA5C2 0x6C10 # 0 +0xA5C3 0x6C38 # 0 +0xA5C4 0x6C41 # 0 +0xA5C5 0x6C40 # 0 +0xA5C6 0x6C3E # 0 +0xA5C7 0x72AF # 0 +0xA5C8 0x7384 # 0 +0xA5C9 0x7389 # 0 +0xA5CA 0x74DC # 0 +0xA5CB 0x74E6 # 0 +0xA5CC 0x7518 # 0 +0xA5CD 0x751F # 0 +0xA5CE 0x7528 # 0 +0xA5CF 0x7529 # 0 +0xA5D0 0x7530 # 0 +0xA5D1 0x7531 # 0 +0xA5D2 0x7532 # 0 +0xA5D3 0x7533 # 0 +0xA5D4 0x758B # 0 +0xA5D5 0x767D # 0 +0xA5D6 0x76AE # 0 +0xA5D7 0x76BF # 0 +0xA5D8 0x76EE # 0 +0xA5D9 0x77DB # 0 +0xA5DA 0x77E2 # 0 +0xA5DB 0x77F3 # 0 +0xA5DC 0x793A # 0 +0xA5DD 0x79BE # 0 +0xA5DE 0x7A74 # 0 +0xA5DF 0x7ACB # 0 +0xA5E0 0x4E1E # 0 +0xA5E1 0x4E1F # 0 +0xA5E2 0x4E52 # 0 +0xA5E3 0x4E53 # 0 +0xA5E4 0x4E69 # 0 +0xA5E5 0x4E99 # 0 +0xA5E6 0x4EA4 # 0 +0xA5E7 0x4EA6 # 0 +0xA5E8 0x4EA5 # 0 +0xA5E9 0x4EFF # 0 +0xA5EA 0x4F09 # 0 +0xA5EB 0x4F19 # 0 +0xA5EC 0x4F0A # 0 +0xA5ED 0x4F15 # 0 +0xA5EE 0x4F0D # 0 +0xA5EF 0x4F10 # 0 +0xA5F0 0x4F11 # 0 +0xA5F1 0x4F0F # 0 +0xA5F2 0x4EF2 # 0 +0xA5F3 0x4EF6 # 0 +0xA5F4 0x4EFB # 0 +0xA5F5 0x4EF0 # 0 +0xA5F6 0x4EF3 # 0 +0xA5F7 0x4EFD # 0 +0xA5F8 0x4F01 # 0 +0xA5F9 0x4F0B # 0 +0xA5FA 0x5149 # 0 +0xA5FB 0x5147 # 0 +0xA5FC 0x5146 # 0 +0xA5FD 0x5148 # 0 +0xA5FE 0x5168 # 0 +0xA640 0x5171 # 0 +0xA641 0x518D # 0 +0xA642 0x51B0 # 0 +0xA643 0x5217 # 0 +0xA644 0x5211 # 0 +0xA645 0x5212 # 0 +0xA646 0x520E # 0 +0xA647 0x5216 # 0 +0xA648 0x52A3 # 0 +0xA649 0x5308 # 0 +0xA64A 0x5321 # 0 +0xA64B 0x5320 # 0 +0xA64C 0x5370 # 0 +0xA64D 0x5371 # 0 +0xA64E 0x5409 # 0 +0xA64F 0x540F # 0 +0xA650 0x540C # 0 +0xA651 0x540A # 0 +0xA652 0x5410 # 0 +0xA653 0x5401 # 0 +0xA654 0x540B # 0 +0xA655 0x5404 # 0 +0xA656 0x5411 # 0 +0xA657 0x540D # 0 +0xA658 0x5408 # 0 +0xA659 0x5403 # 0 +0xA65A 0x540E # 0 +0xA65B 0x5406 # 0 +0xA65C 0x5412 # 0 +0xA65D 0x56E0 # 0 +0xA65E 0x56DE # 0 +0xA65F 0x56DD # 0 +0xA660 0x5733 # 0 +0xA661 0x5730 # 0 +0xA662 0x5728 # 0 +0xA663 0x572D # 0 +0xA664 0x572C # 0 +0xA665 0x572F # 0 +0xA666 0x5729 # 0 +0xA667 0x5919 # 0 +0xA668 0x591A # 0 +0xA669 0x5937 # 0 +0xA66A 0x5938 # 0 +0xA66B 0x5984 # 0 +0xA66C 0x5978 # 0 +0xA66D 0x5983 # 0 +0xA66E 0x597D # 0 +0xA66F 0x5979 # 0 +0xA670 0x5982 # 0 +0xA671 0x5981 # 0 +0xA672 0x5B57 # 0 +0xA673 0x5B58 # 0 +0xA674 0x5B87 # 0 +0xA675 0x5B88 # 0 +0xA676 0x5B85 # 0 +0xA677 0x5B89 # 0 +0xA678 0x5BFA # 0 +0xA679 0x5C16 # 0 +0xA67A 0x5C79 # 0 +0xA67B 0x5DDE # 0 +0xA67C 0x5E06 # 0 +0xA67D 0x5E76 # 0 +0xA67E 0x5E74 # 0 +0xA6A1 0x5F0F # 0 +0xA6A2 0x5F1B # 0 +0xA6A3 0x5FD9 # 0 +0xA6A4 0x5FD6 # 0 +0xA6A5 0x620E # 0 +0xA6A6 0x620C # 0 +0xA6A7 0x620D # 0 +0xA6A8 0x6210 # 0 +0xA6A9 0x6263 # 0 +0xA6AA 0x625B # 0 +0xA6AB 0x6258 # 0 +0xA6AC 0x6536 # 0 +0xA6AD 0x65E9 # 0 +0xA6AE 0x65E8 # 0 +0xA6AF 0x65EC # 0 +0xA6B0 0x65ED # 0 +0xA6B1 0x66F2 # 0 +0xA6B2 0x66F3 # 0 +0xA6B3 0x6709 # 0 +0xA6B4 0x673D # 0 +0xA6B5 0x6734 # 0 +0xA6B6 0x6731 # 0 +0xA6B7 0x6735 # 0 +0xA6B8 0x6B21 # 0 +0xA6B9 0x6B64 # 0 +0xA6BA 0x6B7B # 0 +0xA6BB 0x6C16 # 0 +0xA6BC 0x6C5D # 0 +0xA6BD 0x6C57 # 0 +0xA6BE 0x6C59 # 0 +0xA6BF 0x6C5F # 0 +0xA6C0 0x6C60 # 0 +0xA6C1 0x6C50 # 0 +0xA6C2 0x6C55 # 0 +0xA6C3 0x6C61 # 0 +0xA6C4 0x6C5B # 0 +0xA6C5 0x6C4D # 0 +0xA6C6 0x6C4E # 0 +0xA6C7 0x7070 # 0 +0xA6C8 0x725F # 0 +0xA6C9 0x725D # 0 +0xA6CA 0x767E # 0 +0xA6CB 0x7AF9 # 0 +0xA6CC 0x7C73 # 0 +0xA6CD 0x7CF8 # 0 +0xA6CE 0x7F36 # 0 +0xA6CF 0x7F8A # 0 +0xA6D0 0x7FBD # 0 +0xA6D1 0x8001 # 0 +0xA6D2 0x8003 # 0 +0xA6D3 0x800C # 0 +0xA6D4 0x8012 # 0 +0xA6D5 0x8033 # 0 +0xA6D6 0x807F # 0 +0xA6D7 0x8089 # 0 +0xA6D8 0x808B # 0 +0xA6D9 0x808C # 0 +0xA6DA 0x81E3 # 0 +0xA6DB 0x81EA # 0 +0xA6DC 0x81F3 # 0 +0xA6DD 0x81FC # 0 +0xA6DE 0x820C # 0 +0xA6DF 0x821B # 0 +0xA6E0 0x821F # 0 +0xA6E1 0x826E # 0 +0xA6E2 0x8272 # 0 +0xA6E3 0x827E # 0 +0xA6E4 0x866B # 0 +0xA6E5 0x8840 # 0 +0xA6E6 0x884C # 0 +0xA6E7 0x8863 # 0 +0xA6E8 0x897F # 0 +0xA6E9 0x9621 # 0 +0xA6EA 0x4E32 # 0 +0xA6EB 0x4EA8 # 0 +0xA6EC 0x4F4D # 0 +0xA6ED 0x4F4F # 0 +0xA6EE 0x4F47 # 0 +0xA6EF 0x4F57 # 0 +0xA6F0 0x4F5E # 0 +0xA6F1 0x4F34 # 0 +0xA6F2 0x4F5B # 0 +0xA6F3 0x4F55 # 0 +0xA6F4 0x4F30 # 0 +0xA6F5 0x4F50 # 0 +0xA6F6 0x4F51 # 0 +0xA6F7 0x4F3D # 0 +0xA6F8 0x4F3A # 0 +0xA6F9 0x4F38 # 0 +0xA6FA 0x4F43 # 0 +0xA6FB 0x4F54 # 0 +0xA6FC 0x4F3C # 0 +0xA6FD 0x4F46 # 0 +0xA6FE 0x4F63 # 0 +0xA740 0x4F5C # 0 +0xA741 0x4F60 # 0 +0xA742 0x4F2F # 0 +0xA743 0x4F4E # 0 +0xA744 0x4F36 # 0 +0xA745 0x4F59 # 0 +0xA746 0x4F5D # 0 +0xA747 0x4F48 # 0 +0xA748 0x4F5A # 0 +0xA749 0x514C # 0 +0xA74A 0x514B # 0 +0xA74B 0x514D # 0 +0xA74C 0x5175 # 0 +0xA74D 0x51B6 # 0 +0xA74E 0x51B7 # 0 +0xA74F 0x5225 # 0 +0xA750 0x5224 # 0 +0xA751 0x5229 # 0 +0xA752 0x522A # 0 +0xA753 0x5228 # 0 +0xA754 0x52AB # 0 +0xA755 0x52A9 # 0 +0xA756 0x52AA # 0 +0xA757 0x52AC # 0 +0xA758 0x5323 # 0 +0xA759 0x5373 # 0 +0xA75A 0x5375 # 0 +0xA75B 0x541D # 0 +0xA75C 0x542D # 0 +0xA75D 0x541E # 0 +0xA75E 0x543E # 0 +0xA75F 0x5426 # 0 +0xA760 0x544E # 0 +0xA761 0x5427 # 0 +0xA762 0x5446 # 0 +0xA763 0x5443 # 0 +0xA764 0x5433 # 0 +0xA765 0x5448 # 0 +0xA766 0x5442 # 0 +0xA767 0x541B # 0 +0xA768 0x5429 # 0 +0xA769 0x544A # 0 +0xA76A 0x5439 # 0 +0xA76B 0x543B # 0 +0xA76C 0x5438 # 0 +0xA76D 0x542E # 0 +0xA76E 0x5435 # 0 +0xA76F 0x5436 # 0 +0xA770 0x5420 # 0 +0xA771 0x543C # 0 +0xA772 0x5440 # 0 +0xA773 0x5431 # 0 +0xA774 0x542B # 0 +0xA775 0x541F # 0 +0xA776 0x542C # 0 +0xA777 0x56EA # 0 +0xA778 0x56F0 # 0 +0xA779 0x56E4 # 0 +0xA77A 0x56EB # 0 +0xA77B 0x574A # 0 +0xA77C 0x5751 # 0 +0xA77D 0x5740 # 0 +0xA77E 0x574D # 0 +0xA7A1 0x5747 # 0 +0xA7A2 0x574E # 0 +0xA7A3 0x573E # 0 +0xA7A4 0x5750 # 0 +0xA7A5 0x574F # 0 +0xA7A6 0x573B # 0 +0xA7A7 0x58EF # 0 +0xA7A8 0x593E # 0 +0xA7A9 0x599D # 0 +0xA7AA 0x5992 # 0 +0xA7AB 0x59A8 # 0 +0xA7AC 0x599E # 0 +0xA7AD 0x59A3 # 0 +0xA7AE 0x5999 # 0 +0xA7AF 0x5996 # 0 +0xA7B0 0x598D # 0 +0xA7B1 0x59A4 # 0 +0xA7B2 0x5993 # 0 +0xA7B3 0x598A # 0 +0xA7B4 0x59A5 # 0 +0xA7B5 0x5B5D # 0 +0xA7B6 0x5B5C # 0 +0xA7B7 0x5B5A # 0 +0xA7B8 0x5B5B # 0 +0xA7B9 0x5B8C # 0 +0xA7BA 0x5B8B # 0 +0xA7BB 0x5B8F # 0 +0xA7BC 0x5C2C # 0 +0xA7BD 0x5C40 # 0 +0xA7BE 0x5C41 # 0 +0xA7BF 0x5C3F # 0 +0xA7C0 0x5C3E # 0 +0xA7C1 0x5C90 # 0 +0xA7C2 0x5C91 # 0 +0xA7C3 0x5C94 # 0 +0xA7C4 0x5C8C # 0 +0xA7C5 0x5DEB # 0 +0xA7C6 0x5E0C # 0 +0xA7C7 0x5E8F # 0 +0xA7C8 0x5E87 # 0 +0xA7C9 0x5E8A # 0 +0xA7CA 0x5EF7 # 0 +0xA7CB 0x5F04 # 0 +0xA7CC 0x5F1F # 0 +0xA7CD 0x5F64 # 0 +0xA7CE 0x5F62 # 0 +0xA7CF 0x5F77 # 0 +0xA7D0 0x5F79 # 0 +0xA7D1 0x5FD8 # 0 +0xA7D2 0x5FCC # 0 +0xA7D3 0x5FD7 # 0 +0xA7D4 0x5FCD # 0 +0xA7D5 0x5FF1 # 0 +0xA7D6 0x5FEB # 0 +0xA7D7 0x5FF8 # 0 +0xA7D8 0x5FEA # 0 +0xA7D9 0x6212 # 0 +0xA7DA 0x6211 # 0 +0xA7DB 0x6284 # 0 +0xA7DC 0x6297 # 0 +0xA7DD 0x6296 # 0 +0xA7DE 0x6280 # 0 +0xA7DF 0x6276 # 0 +0xA7E0 0x6289 # 0 +0xA7E1 0x626D # 0 +0xA7E2 0x628A # 0 +0xA7E3 0x627C # 0 +0xA7E4 0x627E # 0 +0xA7E5 0x6279 # 0 +0xA7E6 0x6273 # 0 +0xA7E7 0x6292 # 0 +0xA7E8 0x626F # 0 +0xA7E9 0x6298 # 0 +0xA7EA 0x626E # 0 +0xA7EB 0x6295 # 0 +0xA7EC 0x6293 # 0 +0xA7ED 0x6291 # 0 +0xA7EE 0x6286 # 0 +0xA7EF 0x6539 # 0 +0xA7F0 0x653B # 0 +0xA7F1 0x6538 # 0 +0xA7F2 0x65F1 # 0 +0xA7F3 0x66F4 # 0 +0xA7F4 0x675F # 0 +0xA7F5 0x674E # 0 +0xA7F6 0x674F # 0 +0xA7F7 0x6750 # 0 +0xA7F8 0x6751 # 0 +0xA7F9 0x675C # 0 +0xA7FA 0x6756 # 0 +0xA7FB 0x675E # 0 +0xA7FC 0x6749 # 0 +0xA7FD 0x6746 # 0 +0xA7FE 0x6760 # 0 +0xA840 0x6753 # 0 +0xA841 0x6757 # 0 +0xA842 0x6B65 # 0 +0xA843 0x6BCF # 0 +0xA844 0x6C42 # 0 +0xA845 0x6C5E # 0 +0xA846 0x6C99 # 0 +0xA847 0x6C81 # 0 +0xA848 0x6C88 # 0 +0xA849 0x6C89 # 0 +0xA84A 0x6C85 # 0 +0xA84B 0x6C9B # 0 +0xA84C 0x6C6A # 0 +0xA84D 0x6C7A # 0 +0xA84E 0x6C90 # 0 +0xA84F 0x6C70 # 0 +0xA850 0x6C8C # 0 +0xA851 0x6C68 # 0 +0xA852 0x6C96 # 0 +0xA853 0x6C92 # 0 +0xA854 0x6C7D # 0 +0xA855 0x6C83 # 0 +0xA856 0x6C72 # 0 +0xA857 0x6C7E # 0 +0xA858 0x6C74 # 0 +0xA859 0x6C86 # 0 +0xA85A 0x6C76 # 0 +0xA85B 0x6C8D # 0 +0xA85C 0x6C94 # 0 +0xA85D 0x6C98 # 0 +0xA85E 0x6C82 # 0 +0xA85F 0x7076 # 0 +0xA860 0x707C # 0 +0xA861 0x707D # 0 +0xA862 0x7078 # 0 +0xA863 0x7262 # 0 +0xA864 0x7261 # 0 +0xA865 0x7260 # 0 +0xA866 0x72C4 # 0 +0xA867 0x72C2 # 0 +0xA868 0x7396 # 0 +0xA869 0x752C # 0 +0xA86A 0x752B # 0 +0xA86B 0x7537 # 0 +0xA86C 0x7538 # 0 +0xA86D 0x7682 # 0 +0xA86E 0x76EF # 0 +0xA86F 0x77E3 # 0 +0xA870 0x79C1 # 0 +0xA871 0x79C0 # 0 +0xA872 0x79BF # 0 +0xA873 0x7A76 # 0 +0xA874 0x7CFB # 0 +0xA875 0x7F55 # 0 +0xA876 0x8096 # 0 +0xA877 0x8093 # 0 +0xA878 0x809D # 0 +0xA879 0x8098 # 0 +0xA87A 0x809B # 0 +0xA87B 0x809A # 0 +0xA87C 0x80B2 # 0 +0xA87D 0x826F # 0 +0xA87E 0x8292 # 0 +0xA8A1 0x828B # 0 +0xA8A2 0x828D # 0 +0xA8A3 0x898B # 0 +0xA8A4 0x89D2 # 0 +0xA8A5 0x8A00 # 0 +0xA8A6 0x8C37 # 0 +0xA8A7 0x8C46 # 0 +0xA8A8 0x8C55 # 0 +0xA8A9 0x8C9D # 0 +0xA8AA 0x8D64 # 0 +0xA8AB 0x8D70 # 0 +0xA8AC 0x8DB3 # 0 +0xA8AD 0x8EAB # 0 +0xA8AE 0x8ECA # 0 +0xA8AF 0x8F9B # 0 +0xA8B0 0x8FB0 # 0 +0xA8B1 0x8FC2 # 0 +0xA8B2 0x8FC6 # 0 +0xA8B3 0x8FC5 # 0 +0xA8B4 0x8FC4 # 0 +0xA8B5 0x5DE1 # 0 +0xA8B6 0x9091 # 0 +0xA8B7 0x90A2 # 0 +0xA8B8 0x90AA # 0 +0xA8B9 0x90A6 # 0 +0xA8BA 0x90A3 # 0 +0xA8BB 0x9149 # 0 +0xA8BC 0x91C6 # 0 +0xA8BD 0x91CC # 0 +0xA8BE 0x9632 # 0 +0xA8BF 0x962E # 0 +0xA8C0 0x9631 # 0 +0xA8C1 0x962A # 0 +0xA8C2 0x962C # 0 +0xA8C3 0x4E26 # 0 +0xA8C4 0x4E56 # 0 +0xA8C5 0x4E73 # 0 +0xA8C6 0x4E8B # 0 +0xA8C7 0x4E9B # 0 +0xA8C8 0x4E9E # 0 +0xA8C9 0x4EAB # 0 +0xA8CA 0x4EAC # 0 +0xA8CB 0x4F6F # 0 +0xA8CC 0x4F9D # 0 +0xA8CD 0x4F8D # 0 +0xA8CE 0x4F73 # 0 +0xA8CF 0x4F7F # 0 +0xA8D0 0x4F6C # 0 +0xA8D1 0x4F9B # 0 +0xA8D2 0x4F8B # 0 +0xA8D3 0x4F86 # 0 +0xA8D4 0x4F83 # 0 +0xA8D5 0x4F70 # 0 +0xA8D6 0x4F75 # 0 +0xA8D7 0x4F88 # 0 +0xA8D8 0x4F69 # 0 +0xA8D9 0x4F7B # 0 +0xA8DA 0x4F96 # 0 +0xA8DB 0x4F7E # 0 +0xA8DC 0x4F8F # 0 +0xA8DD 0x4F91 # 0 +0xA8DE 0x4F7A # 0 +0xA8DF 0x5154 # 0 +0xA8E0 0x5152 # 0 +0xA8E1 0x5155 # 0 +0xA8E2 0x5169 # 0 +0xA8E3 0x5177 # 0 +0xA8E4 0x5176 # 0 +0xA8E5 0x5178 # 0 +0xA8E6 0x51BD # 0 +0xA8E7 0x51FD # 0 +0xA8E8 0x523B # 0 +0xA8E9 0x5238 # 0 +0xA8EA 0x5237 # 0 +0xA8EB 0x523A # 0 +0xA8EC 0x5230 # 0 +0xA8ED 0x522E # 0 +0xA8EE 0x5236 # 0 +0xA8EF 0x5241 # 0 +0xA8F0 0x52BE # 0 +0xA8F1 0x52BB # 0 +0xA8F2 0x5352 # 0 +0xA8F3 0x5354 # 0 +0xA8F4 0x5353 # 0 +0xA8F5 0x5351 # 0 +0xA8F6 0x5366 # 0 +0xA8F7 0x5377 # 0 +0xA8F8 0x5378 # 0 +0xA8F9 0x5379 # 0 +0xA8FA 0x53D6 # 0 +0xA8FB 0x53D4 # 0 +0xA8FC 0x53D7 # 0 +0xA8FD 0x5473 # 0 +0xA8FE 0x5475 # 0 +0xA940 0x5496 # 0 +0xA941 0x5478 # 0 +0xA942 0x5495 # 0 +0xA943 0x5480 # 0 +0xA944 0x547B # 0 +0xA945 0x5477 # 0 +0xA946 0x5484 # 0 +0xA947 0x5492 # 0 +0xA948 0x5486 # 0 +0xA949 0x547C # 0 +0xA94A 0x5490 # 0 +0xA94B 0x5471 # 0 +0xA94C 0x5476 # 0 +0xA94D 0x548C # 0 +0xA94E 0x549A # 0 +0xA94F 0x5462 # 0 +0xA950 0x5468 # 0 +0xA951 0x548B # 0 +0xA952 0x547D # 0 +0xA953 0x548E # 0 +0xA954 0x56FA # 0 +0xA955 0x5783 # 0 +0xA956 0x5777 # 0 +0xA957 0x576A # 0 +0xA958 0x5769 # 0 +0xA959 0x5761 # 0 +0xA95A 0x5766 # 0 +0xA95B 0x5764 # 0 +0xA95C 0x577C # 0 +0xA95D 0x591C # 0 +0xA95E 0x5949 # 0 +0xA95F 0x5947 # 0 +0xA960 0x5948 # 0 +0xA961 0x5944 # 0 +0xA962 0x5954 # 0 +0xA963 0x59BE # 0 +0xA964 0x59BB # 0 +0xA965 0x59D4 # 0 +0xA966 0x59B9 # 0 +0xA967 0x59AE # 0 +0xA968 0x59D1 # 0 +0xA969 0x59C6 # 0 +0xA96A 0x59D0 # 0 +0xA96B 0x59CD # 0 +0xA96C 0x59CB # 0 +0xA96D 0x59D3 # 0 +0xA96E 0x59CA # 0 +0xA96F 0x59AF # 0 +0xA970 0x59B3 # 0 +0xA971 0x59D2 # 0 +0xA972 0x59C5 # 0 +0xA973 0x5B5F # 0 +0xA974 0x5B64 # 0 +0xA975 0x5B63 # 0 +0xA976 0x5B97 # 0 +0xA977 0x5B9A # 0 +0xA978 0x5B98 # 0 +0xA979 0x5B9C # 0 +0xA97A 0x5B99 # 0 +0xA97B 0x5B9B # 0 +0xA97C 0x5C1A # 0 +0xA97D 0x5C48 # 0 +0xA97E 0x5C45 # 0 +0xA9A1 0x5C46 # 0 +0xA9A2 0x5CB7 # 0 +0xA9A3 0x5CA1 # 0 +0xA9A4 0x5CB8 # 0 +0xA9A5 0x5CA9 # 0 +0xA9A6 0x5CAB # 0 +0xA9A7 0x5CB1 # 0 +0xA9A8 0x5CB3 # 0 +0xA9A9 0x5E18 # 0 +0xA9AA 0x5E1A # 0 +0xA9AB 0x5E16 # 0 +0xA9AC 0x5E15 # 0 +0xA9AD 0x5E1B # 0 +0xA9AE 0x5E11 # 0 +0xA9AF 0x5E78 # 0 +0xA9B0 0x5E9A # 0 +0xA9B1 0x5E97 # 0 +0xA9B2 0x5E9C # 0 +0xA9B3 0x5E95 # 0 +0xA9B4 0x5E96 # 0 +0xA9B5 0x5EF6 # 0 +0xA9B6 0x5F26 # 0 +0xA9B7 0x5F27 # 0 +0xA9B8 0x5F29 # 0 +0xA9B9 0x5F80 # 0 +0xA9BA 0x5F81 # 0 +0xA9BB 0x5F7F # 0 +0xA9BC 0x5F7C # 0 +0xA9BD 0x5FDD # 0 +0xA9BE 0x5FE0 # 0 +0xA9BF 0x5FFD # 0 +0xA9C0 0x5FF5 # 0 +0xA9C1 0x5FFF # 0 +0xA9C2 0x600F # 0 +0xA9C3 0x6014 # 0 +0xA9C4 0x602F # 0 +0xA9C5 0x6035 # 0 +0xA9C6 0x6016 # 0 +0xA9C7 0x602A # 0 +0xA9C8 0x6015 # 0 +0xA9C9 0x6021 # 0 +0xA9CA 0x6027 # 0 +0xA9CB 0x6029 # 0 +0xA9CC 0x602B # 0 +0xA9CD 0x601B # 0 +0xA9CE 0x6216 # 0 +0xA9CF 0x6215 # 0 +0xA9D0 0x623F # 0 +0xA9D1 0x623E # 0 +0xA9D2 0x6240 # 0 +0xA9D3 0x627F # 0 +0xA9D4 0x62C9 # 0 +0xA9D5 0x62CC # 0 +0xA9D6 0x62C4 # 0 +0xA9D7 0x62BF # 0 +0xA9D8 0x62C2 # 0 +0xA9D9 0x62B9 # 0 +0xA9DA 0x62D2 # 0 +0xA9DB 0x62DB # 0 +0xA9DC 0x62AB # 0 +0xA9DD 0x62D3 # 0 +0xA9DE 0x62D4 # 0 +0xA9DF 0x62CB # 0 +0xA9E0 0x62C8 # 0 +0xA9E1 0x62A8 # 0 +0xA9E2 0x62BD # 0 +0xA9E3 0x62BC # 0 +0xA9E4 0x62D0 # 0 +0xA9E5 0x62D9 # 0 +0xA9E6 0x62C7 # 0 +0xA9E7 0x62CD # 0 +0xA9E8 0x62B5 # 0 +0xA9E9 0x62DA # 0 +0xA9EA 0x62B1 # 0 +0xA9EB 0x62D8 # 0 +0xA9EC 0x62D6 # 0 +0xA9ED 0x62D7 # 0 +0xA9EE 0x62C6 # 0 +0xA9EF 0x62AC # 0 +0xA9F0 0x62CE # 0 +0xA9F1 0x653E # 0 +0xA9F2 0x65A7 # 0 +0xA9F3 0x65BC # 0 +0xA9F4 0x65FA # 0 +0xA9F5 0x6614 # 0 +0xA9F6 0x6613 # 0 +0xA9F7 0x660C # 0 +0xA9F8 0x6606 # 0 +0xA9F9 0x6602 # 0 +0xA9FA 0x660E # 0 +0xA9FB 0x6600 # 0 +0xA9FC 0x660F # 0 +0xA9FD 0x6615 # 0 +0xA9FE 0x660A # 0 +0xAA40 0x6607 # 0 +0xAA41 0x670D # 0 +0xAA42 0x670B # 0 +0xAA43 0x676D # 0 +0xAA44 0x678B # 0 +0xAA45 0x6795 # 0 +0xAA46 0x6771 # 0 +0xAA47 0x679C # 0 +0xAA48 0x6773 # 0 +0xAA49 0x6777 # 0 +0xAA4A 0x6787 # 0 +0xAA4B 0x679D # 0 +0xAA4C 0x6797 # 0 +0xAA4D 0x676F # 0 +0xAA4E 0x6770 # 0 +0xAA4F 0x677F # 0 +0xAA50 0x6789 # 0 +0xAA51 0x677E # 0 +0xAA52 0x6790 # 0 +0xAA53 0x6775 # 0 +0xAA54 0x679A # 0 +0xAA55 0x6793 # 0 +0xAA56 0x677C # 0 +0xAA57 0x676A # 0 +0xAA58 0x6772 # 0 +0xAA59 0x6B23 # 0 +0xAA5A 0x6B66 # 0 +0xAA5B 0x6B67 # 0 +0xAA5C 0x6B7F # 0 +0xAA5D 0x6C13 # 0 +0xAA5E 0x6C1B # 0 +0xAA5F 0x6CE3 # 0 +0xAA60 0x6CE8 # 0 +0xAA61 0x6CF3 # 0 +0xAA62 0x6CB1 # 0 +0xAA63 0x6CCC # 0 +0xAA64 0x6CE5 # 0 +0xAA65 0x6CB3 # 0 +0xAA66 0x6CBD # 0 +0xAA67 0x6CBE # 0 +0xAA68 0x6CBC # 0 +0xAA69 0x6CE2 # 0 +0xAA6A 0x6CAB # 0 +0xAA6B 0x6CD5 # 0 +0xAA6C 0x6CD3 # 0 +0xAA6D 0x6CB8 # 0 +0xAA6E 0x6CC4 # 0 +0xAA6F 0x6CB9 # 0 +0xAA70 0x6CC1 # 0 +0xAA71 0x6CAE # 0 +0xAA72 0x6CD7 # 0 +0xAA73 0x6CC5 # 0 +0xAA74 0x6CF1 # 0 +0xAA75 0x6CBF # 0 +0xAA76 0x6CBB # 0 +0xAA77 0x6CE1 # 0 +0xAA78 0x6CDB # 0 +0xAA79 0x6CCA # 0 +0xAA7A 0x6CAC # 0 +0xAA7B 0x6CEF # 0 +0xAA7C 0x6CDC # 0 +0xAA7D 0x6CD6 # 0 +0xAA7E 0x6CE0 # 0 +0xAAA1 0x7095 # 0 +0xAAA2 0x708E # 0 +0xAAA3 0x7092 # 0 +0xAAA4 0x708A # 0 +0xAAA5 0x7099 # 0 +0xAAA6 0x722C # 0 +0xAAA7 0x722D # 0 +0xAAA8 0x7238 # 0 +0xAAA9 0x7248 # 0 +0xAAAA 0x7267 # 0 +0xAAAB 0x7269 # 0 +0xAAAC 0x72C0 # 0 +0xAAAD 0x72CE # 0 +0xAAAE 0x72D9 # 0 +0xAAAF 0x72D7 # 0 +0xAAB0 0x72D0 # 0 +0xAAB1 0x73A9 # 0 +0xAAB2 0x73A8 # 0 +0xAAB3 0x739F # 0 +0xAAB4 0x73AB # 0 +0xAAB5 0x73A5 # 0 +0xAAB6 0x753D # 0 +0xAAB7 0x759D # 0 +0xAAB8 0x7599 # 0 +0xAAB9 0x759A # 0 +0xAABA 0x7684 # 0 +0xAABB 0x76C2 # 0 +0xAABC 0x76F2 # 0 +0xAABD 0x76F4 # 0 +0xAABE 0x77E5 # 0 +0xAABF 0x77FD # 0 +0xAAC0 0x793E # 0 +0xAAC1 0x7940 # 0 +0xAAC2 0x7941 # 0 +0xAAC3 0x79C9 # 0 +0xAAC4 0x79C8 # 0 +0xAAC5 0x7A7A # 0 +0xAAC6 0x7A79 # 0 +0xAAC7 0x7AFA # 0 +0xAAC8 0x7CFE # 0 +0xAAC9 0x7F54 # 0 +0xAACA 0x7F8C # 0 +0xAACB 0x7F8B # 0 +0xAACC 0x8005 # 0 +0xAACD 0x80BA # 0 +0xAACE 0x80A5 # 0 +0xAACF 0x80A2 # 0 +0xAAD0 0x80B1 # 0 +0xAAD1 0x80A1 # 0 +0xAAD2 0x80AB # 0 +0xAAD3 0x80A9 # 0 +0xAAD4 0x80B4 # 0 +0xAAD5 0x80AA # 0 +0xAAD6 0x80AF # 0 +0xAAD7 0x81E5 # 0 +0xAAD8 0x81FE # 0 +0xAAD9 0x820D # 0 +0xAADA 0x82B3 # 0 +0xAADB 0x829D # 0 +0xAADC 0x8299 # 0 +0xAADD 0x82AD # 0 +0xAADE 0x82BD # 0 +0xAADF 0x829F # 0 +0xAAE0 0x82B9 # 0 +0xAAE1 0x82B1 # 0 +0xAAE2 0x82AC # 0 +0xAAE3 0x82A5 # 0 +0xAAE4 0x82AF # 0 +0xAAE5 0x82B8 # 0 +0xAAE6 0x82A3 # 0 +0xAAE7 0x82B0 # 0 +0xAAE8 0x82BE # 0 +0xAAE9 0x82B7 # 0 +0xAAEA 0x864E # 0 +0xAAEB 0x8671 # 0 +0xAAEC 0x521D # 0 +0xAAED 0x8868 # 0 +0xAAEE 0x8ECB # 0 +0xAAEF 0x8FCE # 0 +0xAAF0 0x8FD4 # 0 +0xAAF1 0x8FD1 # 0 +0xAAF2 0x90B5 # 0 +0xAAF3 0x90B8 # 0 +0xAAF4 0x90B1 # 0 +0xAAF5 0x90B6 # 0 +0xAAF6 0x91C7 # 0 +0xAAF7 0x91D1 # 0 +0xAAF8 0x9577 # 0 +0xAAF9 0x9580 # 0 +0xAAFA 0x961C # 0 +0xAAFB 0x9640 # 0 +0xAAFC 0x963F # 0 +0xAAFD 0x963B # 0 +0xAAFE 0x9644 # 0 +0xAB40 0x9642 # 0 +0xAB41 0x96B9 # 0 +0xAB42 0x96E8 # 0 +0xAB43 0x9752 # 0 +0xAB44 0x975E # 0 +0xAB45 0x4E9F # 0 +0xAB46 0x4EAD # 0 +0xAB47 0x4EAE # 0 +0xAB48 0x4FE1 # 0 +0xAB49 0x4FB5 # 0 +0xAB4A 0x4FAF # 0 +0xAB4B 0x4FBF # 0 +0xAB4C 0x4FE0 # 0 +0xAB4D 0x4FD1 # 0 +0xAB4E 0x4FCF # 0 +0xAB4F 0x4FDD # 0 +0xAB50 0x4FC3 # 0 +0xAB51 0x4FB6 # 0 +0xAB52 0x4FD8 # 0 +0xAB53 0x4FDF # 0 +0xAB54 0x4FCA # 0 +0xAB55 0x4FD7 # 0 +0xAB56 0x4FAE # 0 +0xAB57 0x4FD0 # 0 +0xAB58 0x4FC4 # 0 +0xAB59 0x4FC2 # 0 +0xAB5A 0x4FDA # 0 +0xAB5B 0x4FCE # 0 +0xAB5C 0x4FDE # 0 +0xAB5D 0x4FB7 # 0 +0xAB5E 0x5157 # 0 +0xAB5F 0x5192 # 0 +0xAB60 0x5191 # 0 +0xAB61 0x51A0 # 0 +0xAB62 0x524E # 0 +0xAB63 0x5243 # 0 +0xAB64 0x524A # 0 +0xAB65 0x524D # 0 +0xAB66 0x524C # 0 +0xAB67 0x524B # 0 +0xAB68 0x5247 # 0 +0xAB69 0x52C7 # 0 +0xAB6A 0x52C9 # 0 +0xAB6B 0x52C3 # 0 +0xAB6C 0x52C1 # 0 +0xAB6D 0x530D # 0 +0xAB6E 0x5357 # 0 +0xAB6F 0x537B # 0 +0xAB70 0x539A # 0 +0xAB71 0x53DB # 0 +0xAB72 0x54AC # 0 +0xAB73 0x54C0 # 0 +0xAB74 0x54A8 # 0 +0xAB75 0x54CE # 0 +0xAB76 0x54C9 # 0 +0xAB77 0x54B8 # 0 +0xAB78 0x54A6 # 0 +0xAB79 0x54B3 # 0 +0xAB7A 0x54C7 # 0 +0xAB7B 0x54C2 # 0 +0xAB7C 0x54BD # 0 +0xAB7D 0x54AA # 0 +0xAB7E 0x54C1 # 0 +0xABA1 0x54C4 # 0 +0xABA2 0x54C8 # 0 +0xABA3 0x54AF # 0 +0xABA4 0x54AB # 0 +0xABA5 0x54B1 # 0 +0xABA6 0x54BB # 0 +0xABA7 0x54A9 # 0 +0xABA8 0x54A7 # 0 +0xABA9 0x54BF # 0 +0xABAA 0x56FF # 0 +0xABAB 0x5782 # 0 +0xABAC 0x578B # 0 +0xABAD 0x57A0 # 0 +0xABAE 0x57A3 # 0 +0xABAF 0x57A2 # 0 +0xABB0 0x57CE # 0 +0xABB1 0x57AE # 0 +0xABB2 0x5793 # 0 +0xABB3 0x5955 # 0 +0xABB4 0x5951 # 0 +0xABB5 0x594F # 0 +0xABB6 0x594E # 0 +0xABB7 0x5950 # 0 +0xABB8 0x59DC # 0 +0xABB9 0x59D8 # 0 +0xABBA 0x59FF # 0 +0xABBB 0x59E3 # 0 +0xABBC 0x59E8 # 0 +0xABBD 0x5A03 # 0 +0xABBE 0x59E5 # 0 +0xABBF 0x59EA # 0 +0xABC0 0x59DA # 0 +0xABC1 0x59E6 # 0 +0xABC2 0x5A01 # 0 +0xABC3 0x59FB # 0 +0xABC4 0x5B69 # 0 +0xABC5 0x5BA3 # 0 +0xABC6 0x5BA6 # 0 +0xABC7 0x5BA4 # 0 +0xABC8 0x5BA2 # 0 +0xABC9 0x5BA5 # 0 +0xABCA 0x5C01 # 0 +0xABCB 0x5C4E # 0 +0xABCC 0x5C4F # 0 +0xABCD 0x5C4D # 0 +0xABCE 0x5C4B # 0 +0xABCF 0x5CD9 # 0 +0xABD0 0x5CD2 # 0 +0xABD1 0x5DF7 # 0 +0xABD2 0x5E1D # 0 +0xABD3 0x5E25 # 0 +0xABD4 0x5E1F # 0 +0xABD5 0x5E7D # 0 +0xABD6 0x5EA0 # 0 +0xABD7 0x5EA6 # 0 +0xABD8 0x5EFA # 0 +0xABD9 0x5F08 # 0 +0xABDA 0x5F2D # 0 +0xABDB 0x5F65 # 0 +0xABDC 0x5F88 # 0 +0xABDD 0x5F85 # 0 +0xABDE 0x5F8A # 0 +0xABDF 0x5F8B # 0 +0xABE0 0x5F87 # 0 +0xABE1 0x5F8C # 0 +0xABE2 0x5F89 # 0 +0xABE3 0x6012 # 0 +0xABE4 0x601D # 0 +0xABE5 0x6020 # 0 +0xABE6 0x6025 # 0 +0xABE7 0x600E # 0 +0xABE8 0x6028 # 0 +0xABE9 0x604D # 0 +0xABEA 0x6070 # 0 +0xABEB 0x6068 # 0 +0xABEC 0x6062 # 0 +0xABED 0x6046 # 0 +0xABEE 0x6043 # 0 +0xABEF 0x606C # 0 +0xABF0 0x606B # 0 +0xABF1 0x606A # 0 +0xABF2 0x6064 # 0 +0xABF3 0x6241 # 0 +0xABF4 0x62DC # 0 +0xABF5 0x6316 # 0 +0xABF6 0x6309 # 0 +0xABF7 0x62FC # 0 +0xABF8 0x62ED # 0 +0xABF9 0x6301 # 0 +0xABFA 0x62EE # 0 +0xABFB 0x62FD # 0 +0xABFC 0x6307 # 0 +0xABFD 0x62F1 # 0 +0xABFE 0x62F7 # 0 +0xAC40 0x62EF # 0 +0xAC41 0x62EC # 0 +0xAC42 0x62FE # 0 +0xAC43 0x62F4 # 0 +0xAC44 0x6311 # 0 +0xAC45 0x6302 # 0 +0xAC46 0x653F # 0 +0xAC47 0x6545 # 0 +0xAC48 0x65AB # 0 +0xAC49 0x65BD # 0 +0xAC4A 0x65E2 # 0 +0xAC4B 0x6625 # 0 +0xAC4C 0x662D # 0 +0xAC4D 0x6620 # 0 +0xAC4E 0x6627 # 0 +0xAC4F 0x662F # 0 +0xAC50 0x661F # 0 +0xAC51 0x6628 # 0 +0xAC52 0x6631 # 0 +0xAC53 0x6624 # 0 +0xAC54 0x66F7 # 0 +0xAC55 0x67FF # 0 +0xAC56 0x67D3 # 0 +0xAC57 0x67F1 # 0 +0xAC58 0x67D4 # 0 +0xAC59 0x67D0 # 0 +0xAC5A 0x67EC # 0 +0xAC5B 0x67B6 # 0 +0xAC5C 0x67AF # 0 +0xAC5D 0x67F5 # 0 +0xAC5E 0x67E9 # 0 +0xAC5F 0x67EF # 0 +0xAC60 0x67C4 # 0 +0xAC61 0x67D1 # 0 +0xAC62 0x67B4 # 0 +0xAC63 0x67DA # 0 +0xAC64 0x67E5 # 0 +0xAC65 0x67B8 # 0 +0xAC66 0x67CF # 0 +0xAC67 0x67DE # 0 +0xAC68 0x67F3 # 0 +0xAC69 0x67B0 # 0 +0xAC6A 0x67D9 # 0 +0xAC6B 0x67E2 # 0 +0xAC6C 0x67DD # 0 +0xAC6D 0x67D2 # 0 +0xAC6E 0x6B6A # 0 +0xAC6F 0x6B83 # 0 +0xAC70 0x6B86 # 0 +0xAC71 0x6BB5 # 0 +0xAC72 0x6BD2 # 0 +0xAC73 0x6BD7 # 0 +0xAC74 0x6C1F # 0 +0xAC75 0x6CC9 # 0 +0xAC76 0x6D0B # 0 +0xAC77 0x6D32 # 0 +0xAC78 0x6D2A # 0 +0xAC79 0x6D41 # 0 +0xAC7A 0x6D25 # 0 +0xAC7B 0x6D0C # 0 +0xAC7C 0x6D31 # 0 +0xAC7D 0x6D1E # 0 +0xAC7E 0x6D17 # 0 +0xACA1 0x6D3B # 0 +0xACA2 0x6D3D # 0 +0xACA3 0x6D3E # 0 +0xACA4 0x6D36 # 0 +0xACA5 0x6D1B # 0 +0xACA6 0x6CF5 # 0 +0xACA7 0x6D39 # 0 +0xACA8 0x6D27 # 0 +0xACA9 0x6D38 # 0 +0xACAA 0x6D29 # 0 +0xACAB 0x6D2E # 0 +0xACAC 0x6D35 # 0 +0xACAD 0x6D0E # 0 +0xACAE 0x6D2B # 0 +0xACAF 0x70AB # 0 +0xACB0 0x70BA # 0 +0xACB1 0x70B3 # 0 +0xACB2 0x70AC # 0 +0xACB3 0x70AF # 0 +0xACB4 0x70AD # 0 +0xACB5 0x70B8 # 0 +0xACB6 0x70AE # 0 +0xACB7 0x70A4 # 0 +0xACB8 0x7230 # 0 +0xACB9 0x7272 # 0 +0xACBA 0x726F # 0 +0xACBB 0x7274 # 0 +0xACBC 0x72E9 # 0 +0xACBD 0x72E0 # 0 +0xACBE 0x72E1 # 0 +0xACBF 0x73B7 # 0 +0xACC0 0x73CA # 0 +0xACC1 0x73BB # 0 +0xACC2 0x73B2 # 0 +0xACC3 0x73CD # 0 +0xACC4 0x73C0 # 0 +0xACC5 0x73B3 # 0 +0xACC6 0x751A # 0 +0xACC7 0x752D # 0 +0xACC8 0x754F # 0 +0xACC9 0x754C # 0 +0xACCA 0x754E # 0 +0xACCB 0x754B # 0 +0xACCC 0x75AB # 0 +0xACCD 0x75A4 # 0 +0xACCE 0x75A5 # 0 +0xACCF 0x75A2 # 0 +0xACD0 0x75A3 # 0 +0xACD1 0x7678 # 0 +0xACD2 0x7686 # 0 +0xACD3 0x7687 # 0 +0xACD4 0x7688 # 0 +0xACD5 0x76C8 # 0 +0xACD6 0x76C6 # 0 +0xACD7 0x76C3 # 0 +0xACD8 0x76C5 # 0 +0xACD9 0x7701 # 0 +0xACDA 0x76F9 # 0 +0xACDB 0x76F8 # 0 +0xACDC 0x7709 # 0 +0xACDD 0x770B # 0 +0xACDE 0x76FE # 0 +0xACDF 0x76FC # 0 +0xACE0 0x7707 # 0 +0xACE1 0x77DC # 0 +0xACE2 0x7802 # 0 +0xACE3 0x7814 # 0 +0xACE4 0x780C # 0 +0xACE5 0x780D # 0 +0xACE6 0x7946 # 0 +0xACE7 0x7949 # 0 +0xACE8 0x7948 # 0 +0xACE9 0x7947 # 0 +0xACEA 0x79B9 # 0 +0xACEB 0x79BA # 0 +0xACEC 0x79D1 # 0 +0xACED 0x79D2 # 0 +0xACEE 0x79CB # 0 +0xACEF 0x7A7F # 0 +0xACF0 0x7A81 # 0 +0xACF1 0x7AFF # 0 +0xACF2 0x7AFD # 0 +0xACF3 0x7C7D # 0 +0xACF4 0x7D02 # 0 +0xACF5 0x7D05 # 0 +0xACF6 0x7D00 # 0 +0xACF7 0x7D09 # 0 +0xACF8 0x7D07 # 0 +0xACF9 0x7D04 # 0 +0xACFA 0x7D06 # 0 +0xACFB 0x7F38 # 0 +0xACFC 0x7F8E # 0 +0xACFD 0x7FBF # 0 +0xACFE 0x8004 # 0 +0xAD40 0x8010 # 0 +0xAD41 0x800D # 0 +0xAD42 0x8011 # 0 +0xAD43 0x8036 # 0 +0xAD44 0x80D6 # 0 +0xAD45 0x80E5 # 0 +0xAD46 0x80DA # 0 +0xAD47 0x80C3 # 0 +0xAD48 0x80C4 # 0 +0xAD49 0x80CC # 0 +0xAD4A 0x80E1 # 0 +0xAD4B 0x80DB # 0 +0xAD4C 0x80CE # 0 +0xAD4D 0x80DE # 0 +0xAD4E 0x80E4 # 0 +0xAD4F 0x80DD # 0 +0xAD50 0x81F4 # 0 +0xAD51 0x8222 # 0 +0xAD52 0x82E7 # 0 +0xAD53 0x8303 # 0 +0xAD54 0x8305 # 0 +0xAD55 0x82E3 # 0 +0xAD56 0x82DB # 0 +0xAD57 0x82E6 # 0 +0xAD58 0x8304 # 0 +0xAD59 0x82E5 # 0 +0xAD5A 0x8302 # 0 +0xAD5B 0x8309 # 0 +0xAD5C 0x82D2 # 0 +0xAD5D 0x82D7 # 0 +0xAD5E 0x82F1 # 0 +0xAD5F 0x8301 # 0 +0xAD60 0x82DC # 0 +0xAD61 0x82D4 # 0 +0xAD62 0x82D1 # 0 +0xAD63 0x82DE # 0 +0xAD64 0x82D3 # 0 +0xAD65 0x82DF # 0 +0xAD66 0x82EF # 0 +0xAD67 0x8306 # 0 +0xAD68 0x8650 # 0 +0xAD69 0x8679 # 0 +0xAD6A 0x867B # 0 +0xAD6B 0x867A # 0 +0xAD6C 0x884D # 0 +0xAD6D 0x886B # 0 +0xAD6E 0x8981 # 0 +0xAD6F 0x89D4 # 0 +0xAD70 0x8A08 # 0 +0xAD71 0x8A02 # 0 +0xAD72 0x8A03 # 0 +0xAD73 0x8C9E # 0 +0xAD74 0x8CA0 # 0 +0xAD75 0x8D74 # 0 +0xAD76 0x8D73 # 0 +0xAD77 0x8DB4 # 0 +0xAD78 0x8ECD # 0 +0xAD79 0x8ECC # 0 +0xAD7A 0x8FF0 # 0 +0xAD7B 0x8FE6 # 0 +0xAD7C 0x8FE2 # 0 +0xAD7D 0x8FEA # 0 +0xAD7E 0x8FE5 # 0 +0xADA1 0x8FED # 0 +0xADA2 0x8FEB # 0 +0xADA3 0x8FE4 # 0 +0xADA4 0x8FE8 # 0 +0xADA5 0x90CA # 0 +0xADA6 0x90CE # 0 +0xADA7 0x90C1 # 0 +0xADA8 0x90C3 # 0 +0xADA9 0x914B # 0 +0xADAA 0x914A # 0 +0xADAB 0x91CD # 0 +0xADAC 0x9582 # 0 +0xADAD 0x9650 # 0 +0xADAE 0x964B # 0 +0xADAF 0x964C # 0 +0xADB0 0x964D # 0 +0xADB1 0x9762 # 0 +0xADB2 0x9769 # 0 +0xADB3 0x97CB # 0 +0xADB4 0x97ED # 0 +0xADB5 0x97F3 # 0 +0xADB6 0x9801 # 0 +0xADB7 0x98A8 # 0 +0xADB8 0x98DB # 0 +0xADB9 0x98DF # 0 +0xADBA 0x9996 # 0 +0xADBB 0x9999 # 0 +0xADBC 0x4E58 # 0 +0xADBD 0x4EB3 # 0 +0xADBE 0x500C # 0 +0xADBF 0x500D # 0 +0xADC0 0x5023 # 0 +0xADC1 0x4FEF # 0 +0xADC2 0x5026 # 0 +0xADC3 0x5025 # 0 +0xADC4 0x4FF8 # 0 +0xADC5 0x5029 # 0 +0xADC6 0x5016 # 0 +0xADC7 0x5006 # 0 +0xADC8 0x503C # 0 +0xADC9 0x501F # 0 +0xADCA 0x501A # 0 +0xADCB 0x5012 # 0 +0xADCC 0x5011 # 0 +0xADCD 0x4FFA # 0 +0xADCE 0x5000 # 0 +0xADCF 0x5014 # 0 +0xADD0 0x5028 # 0 +0xADD1 0x4FF1 # 0 +0xADD2 0x5021 # 0 +0xADD3 0x500B # 0 +0xADD4 0x5019 # 0 +0xADD5 0x5018 # 0 +0xADD6 0x4FF3 # 0 +0xADD7 0x4FEE # 0 +0xADD8 0x502D # 0 +0xADD9 0x502A # 0 +0xADDA 0x4FFE # 0 +0xADDB 0x502B # 0 +0xADDC 0x5009 # 0 +0xADDD 0x517C # 0 +0xADDE 0x51A4 # 0 +0xADDF 0x51A5 # 0 +0xADE0 0x51A2 # 0 +0xADE1 0x51CD # 0 +0xADE2 0x51CC # 0 +0xADE3 0x51C6 # 0 +0xADE4 0x51CB # 0 +0xADE5 0x5256 # 0 +0xADE6 0x525C # 0 +0xADE7 0x5254 # 0 +0xADE8 0x525B # 0 +0xADE9 0x525D # 0 +0xADEA 0x532A # 0 +0xADEB 0x537F # 0 +0xADEC 0x539F # 0 +0xADED 0x539D # 0 +0xADEE 0x53DF # 0 +0xADEF 0x54E8 # 0 +0xADF0 0x5510 # 0 +0xADF1 0x5501 # 0 +0xADF2 0x5537 # 0 +0xADF3 0x54FC # 0 +0xADF4 0x54E5 # 0 +0xADF5 0x54F2 # 0 +0xADF6 0x5506 # 0 +0xADF7 0x54FA # 0 +0xADF8 0x5514 # 0 +0xADF9 0x54E9 # 0 +0xADFA 0x54ED # 0 +0xADFB 0x54E1 # 0 +0xADFC 0x5509 # 0 +0xADFD 0x54EE # 0 +0xADFE 0x54EA # 0 +0xAE40 0x54E6 # 0 +0xAE41 0x5527 # 0 +0xAE42 0x5507 # 0 +0xAE43 0x54FD # 0 +0xAE44 0x550F # 0 +0xAE45 0x5703 # 0 +0xAE46 0x5704 # 0 +0xAE47 0x57C2 # 0 +0xAE48 0x57D4 # 0 +0xAE49 0x57CB # 0 +0xAE4A 0x57C3 # 0 +0xAE4B 0x5809 # 0 +0xAE4C 0x590F # 0 +0xAE4D 0x5957 # 0 +0xAE4E 0x5958 # 0 +0xAE4F 0x595A # 0 +0xAE50 0x5A11 # 0 +0xAE51 0x5A18 # 0 +0xAE52 0x5A1C # 0 +0xAE53 0x5A1F # 0 +0xAE54 0x5A1B # 0 +0xAE55 0x5A13 # 0 +0xAE56 0x59EC # 0 +0xAE57 0x5A20 # 0 +0xAE58 0x5A23 # 0 +0xAE59 0x5A29 # 0 +0xAE5A 0x5A25 # 0 +0xAE5B 0x5A0C # 0 +0xAE5C 0x5A09 # 0 +0xAE5D 0x5B6B # 0 +0xAE5E 0x5C58 # 0 +0xAE5F 0x5BB0 # 0 +0xAE60 0x5BB3 # 0 +0xAE61 0x5BB6 # 0 +0xAE62 0x5BB4 # 0 +0xAE63 0x5BAE # 0 +0xAE64 0x5BB5 # 0 +0xAE65 0x5BB9 # 0 +0xAE66 0x5BB8 # 0 +0xAE67 0x5C04 # 0 +0xAE68 0x5C51 # 0 +0xAE69 0x5C55 # 0 +0xAE6A 0x5C50 # 0 +0xAE6B 0x5CED # 0 +0xAE6C 0x5CFD # 0 +0xAE6D 0x5CFB # 0 +0xAE6E 0x5CEA # 0 +0xAE6F 0x5CE8 # 0 +0xAE70 0x5CF0 # 0 +0xAE71 0x5CF6 # 0 +0xAE72 0x5D01 # 0 +0xAE73 0x5CF4 # 0 +0xAE74 0x5DEE # 0 +0xAE75 0x5E2D # 0 +0xAE76 0x5E2B # 0 +0xAE77 0x5EAB # 0 +0xAE78 0x5EAD # 0 +0xAE79 0x5EA7 # 0 +0xAE7A 0x5F31 # 0 +0xAE7B 0x5F92 # 0 +0xAE7C 0x5F91 # 0 +0xAE7D 0x5F90 # 0 +0xAE7E 0x6059 # 0 +0xAEA1 0x6063 # 0 +0xAEA2 0x6065 # 0 +0xAEA3 0x6050 # 0 +0xAEA4 0x6055 # 0 +0xAEA5 0x606D # 0 +0xAEA6 0x6069 # 0 +0xAEA7 0x606F # 0 +0xAEA8 0x6084 # 0 +0xAEA9 0x609F # 0 +0xAEAA 0x609A # 0 +0xAEAB 0x608D # 0 +0xAEAC 0x6094 # 0 +0xAEAD 0x608C # 0 +0xAEAE 0x6085 # 0 +0xAEAF 0x6096 # 0 +0xAEB0 0x6247 # 0 +0xAEB1 0x62F3 # 0 +0xAEB2 0x6308 # 0 +0xAEB3 0x62FF # 0 +0xAEB4 0x634E # 0 +0xAEB5 0x633E # 0 +0xAEB6 0x632F # 0 +0xAEB7 0x6355 # 0 +0xAEB8 0x6342 # 0 +0xAEB9 0x6346 # 0 +0xAEBA 0x634F # 0 +0xAEBB 0x6349 # 0 +0xAEBC 0x633A # 0 +0xAEBD 0x6350 # 0 +0xAEBE 0x633D # 0 +0xAEBF 0x632A # 0 +0xAEC0 0x632B # 0 +0xAEC1 0x6328 # 0 +0xAEC2 0x634D # 0 +0xAEC3 0x634C # 0 +0xAEC4 0x6548 # 0 +0xAEC5 0x6549 # 0 +0xAEC6 0x6599 # 0 +0xAEC7 0x65C1 # 0 +0xAEC8 0x65C5 # 0 +0xAEC9 0x6642 # 0 +0xAECA 0x6649 # 0 +0xAECB 0x664F # 0 +0xAECC 0x6643 # 0 +0xAECD 0x6652 # 0 +0xAECE 0x664C # 0 +0xAECF 0x6645 # 0 +0xAED0 0x6641 # 0 +0xAED1 0x66F8 # 0 +0xAED2 0x6714 # 0 +0xAED3 0x6715 # 0 +0xAED4 0x6717 # 0 +0xAED5 0x6821 # 0 +0xAED6 0x6838 # 0 +0xAED7 0x6848 # 0 +0xAED8 0x6846 # 0 +0xAED9 0x6853 # 0 +0xAEDA 0x6839 # 0 +0xAEDB 0x6842 # 0 +0xAEDC 0x6854 # 0 +0xAEDD 0x6829 # 0 +0xAEDE 0x68B3 # 0 +0xAEDF 0x6817 # 0 +0xAEE0 0x684C # 0 +0xAEE1 0x6851 # 0 +0xAEE2 0x683D # 0 +0xAEE3 0x67F4 # 0 +0xAEE4 0x6850 # 0 +0xAEE5 0x6840 # 0 +0xAEE6 0x683C # 0 +0xAEE7 0x6843 # 0 +0xAEE8 0x682A # 0 +0xAEE9 0x6845 # 0 +0xAEEA 0x6813 # 0 +0xAEEB 0x6818 # 0 +0xAEEC 0x6841 # 0 +0xAEED 0x6B8A # 0 +0xAEEE 0x6B89 # 0 +0xAEEF 0x6BB7 # 0 +0xAEF0 0x6C23 # 0 +0xAEF1 0x6C27 # 0 +0xAEF2 0x6C28 # 0 +0xAEF3 0x6C26 # 0 +0xAEF4 0x6C24 # 0 +0xAEF5 0x6CF0 # 0 +0xAEF6 0x6D6A # 0 +0xAEF7 0x6D95 # 0 +0xAEF8 0x6D88 # 0 +0xAEF9 0x6D87 # 0 +0xAEFA 0x6D66 # 0 +0xAEFB 0x6D78 # 0 +0xAEFC 0x6D77 # 0 +0xAEFD 0x6D59 # 0 +0xAEFE 0x6D93 # 0 +0xAF40 0x6D6C # 0 +0xAF41 0x6D89 # 0 +0xAF42 0x6D6E # 0 +0xAF43 0x6D5A # 0 +0xAF44 0x6D74 # 0 +0xAF45 0x6D69 # 0 +0xAF46 0x6D8C # 0 +0xAF47 0x6D8A # 0 +0xAF48 0x6D79 # 0 +0xAF49 0x6D85 # 0 +0xAF4A 0x6D65 # 0 +0xAF4B 0x6D94 # 0 +0xAF4C 0x70CA # 0 +0xAF4D 0x70D8 # 0 +0xAF4E 0x70E4 # 0 +0xAF4F 0x70D9 # 0 +0xAF50 0x70C8 # 0 +0xAF51 0x70CF # 0 +0xAF52 0x7239 # 0 +0xAF53 0x7279 # 0 +0xAF54 0x72FC # 0 +0xAF55 0x72F9 # 0 +0xAF56 0x72FD # 0 +0xAF57 0x72F8 # 0 +0xAF58 0x72F7 # 0 +0xAF59 0x7386 # 0 +0xAF5A 0x73ED # 0 +0xAF5B 0x7409 # 0 +0xAF5C 0x73EE # 0 +0xAF5D 0x73E0 # 0 +0xAF5E 0x73EA # 0 +0xAF5F 0x73DE # 0 +0xAF60 0x7554 # 0 +0xAF61 0x755D # 0 +0xAF62 0x755C # 0 +0xAF63 0x755A # 0 +0xAF64 0x7559 # 0 +0xAF65 0x75BE # 0 +0xAF66 0x75C5 # 0 +0xAF67 0x75C7 # 0 +0xAF68 0x75B2 # 0 +0xAF69 0x75B3 # 0 +0xAF6A 0x75BD # 0 +0xAF6B 0x75BC # 0 +0xAF6C 0x75B9 # 0 +0xAF6D 0x75C2 # 0 +0xAF6E 0x75B8 # 0 +0xAF6F 0x768B # 0 +0xAF70 0x76B0 # 0 +0xAF71 0x76CA # 0 +0xAF72 0x76CD # 0 +0xAF73 0x76CE # 0 +0xAF74 0x7729 # 0 +0xAF75 0x771F # 0 +0xAF76 0x7720 # 0 +0xAF77 0x7728 # 0 +0xAF78 0x77E9 # 0 +0xAF79 0x7830 # 0 +0xAF7A 0x7827 # 0 +0xAF7B 0x7838 # 0 +0xAF7C 0x781D # 0 +0xAF7D 0x7834 # 0 +0xAF7E 0x7837 # 0 +0xAFA1 0x7825 # 0 +0xAFA2 0x782D # 0 +0xAFA3 0x7820 # 0 +0xAFA4 0x781F # 0 +0xAFA5 0x7832 # 0 +0xAFA6 0x7955 # 0 +0xAFA7 0x7950 # 0 +0xAFA8 0x7960 # 0 +0xAFA9 0x795F # 0 +0xAFAA 0x7956 # 0 +0xAFAB 0x795E # 0 +0xAFAC 0x795D # 0 +0xAFAD 0x7957 # 0 +0xAFAE 0x795A # 0 +0xAFAF 0x79E4 # 0 +0xAFB0 0x79E3 # 0 +0xAFB1 0x79E7 # 0 +0xAFB2 0x79DF # 0 +0xAFB3 0x79E6 # 0 +0xAFB4 0x79E9 # 0 +0xAFB5 0x79D8 # 0 +0xAFB6 0x7A84 # 0 +0xAFB7 0x7A88 # 0 +0xAFB8 0x7AD9 # 0 +0xAFB9 0x7B06 # 0 +0xAFBA 0x7B11 # 0 +0xAFBB 0x7C89 # 0 +0xAFBC 0x7D21 # 0 +0xAFBD 0x7D17 # 0 +0xAFBE 0x7D0B # 0 +0xAFBF 0x7D0A # 0 +0xAFC0 0x7D20 # 0 +0xAFC1 0x7D22 # 0 +0xAFC2 0x7D14 # 0 +0xAFC3 0x7D10 # 0 +0xAFC4 0x7D15 # 0 +0xAFC5 0x7D1A # 0 +0xAFC6 0x7D1C # 0 +0xAFC7 0x7D0D # 0 +0xAFC8 0x7D19 # 0 +0xAFC9 0x7D1B # 0 +0xAFCA 0x7F3A # 0 +0xAFCB 0x7F5F # 0 +0xAFCC 0x7F94 # 0 +0xAFCD 0x7FC5 # 0 +0xAFCE 0x7FC1 # 0 +0xAFCF 0x8006 # 0 +0xAFD0 0x8018 # 0 +0xAFD1 0x8015 # 0 +0xAFD2 0x8019 # 0 +0xAFD3 0x8017 # 0 +0xAFD4 0x803D # 0 +0xAFD5 0x803F # 0 +0xAFD6 0x80F1 # 0 +0xAFD7 0x8102 # 0 +0xAFD8 0x80F0 # 0 +0xAFD9 0x8105 # 0 +0xAFDA 0x80ED # 0 +0xAFDB 0x80F4 # 0 +0xAFDC 0x8106 # 0 +0xAFDD 0x80F8 # 0 +0xAFDE 0x80F3 # 0 +0xAFDF 0x8108 # 0 +0xAFE0 0x80FD # 0 +0xAFE1 0x810A # 0 +0xAFE2 0x80FC # 0 +0xAFE3 0x80EF # 0 +0xAFE4 0x81ED # 0 +0xAFE5 0x81EC # 0 +0xAFE6 0x8200 # 0 +0xAFE7 0x8210 # 0 +0xAFE8 0x822A # 0 +0xAFE9 0x822B # 0 +0xAFEA 0x8228 # 0 +0xAFEB 0x822C # 0 +0xAFEC 0x82BB # 0 +0xAFED 0x832B # 0 +0xAFEE 0x8352 # 0 +0xAFEF 0x8354 # 0 +0xAFF0 0x834A # 0 +0xAFF1 0x8338 # 0 +0xAFF2 0x8350 # 0 +0xAFF3 0x8349 # 0 +0xAFF4 0x8335 # 0 +0xAFF5 0x8334 # 0 +0xAFF6 0x834F # 0 +0xAFF7 0x8332 # 0 +0xAFF8 0x8339 # 0 +0xAFF9 0x8336 # 0 +0xAFFA 0x8317 # 0 +0xAFFB 0x8340 # 0 +0xAFFC 0x8331 # 0 +0xAFFD 0x8328 # 0 +0xAFFE 0x8343 # 0 +0xB040 0x8654 # 0 +0xB041 0x868A # 0 +0xB042 0x86AA # 0 +0xB043 0x8693 # 0 +0xB044 0x86A4 # 0 +0xB045 0x86A9 # 0 +0xB046 0x868C # 0 +0xB047 0x86A3 # 0 +0xB048 0x869C # 0 +0xB049 0x8870 # 0 +0xB04A 0x8877 # 0 +0xB04B 0x8881 # 0 +0xB04C 0x8882 # 0 +0xB04D 0x887D # 0 +0xB04E 0x8879 # 0 +0xB04F 0x8A18 # 0 +0xB050 0x8A10 # 0 +0xB051 0x8A0E # 0 +0xB052 0x8A0C # 0 +0xB053 0x8A15 # 0 +0xB054 0x8A0A # 0 +0xB055 0x8A17 # 0 +0xB056 0x8A13 # 0 +0xB057 0x8A16 # 0 +0xB058 0x8A0F # 0 +0xB059 0x8A11 # 0 +0xB05A 0x8C48 # 0 +0xB05B 0x8C7A # 0 +0xB05C 0x8C79 # 0 +0xB05D 0x8CA1 # 0 +0xB05E 0x8CA2 # 0 +0xB05F 0x8D77 # 0 +0xB060 0x8EAC # 0 +0xB061 0x8ED2 # 0 +0xB062 0x8ED4 # 0 +0xB063 0x8ECF # 0 +0xB064 0x8FB1 # 0 +0xB065 0x9001 # 0 +0xB066 0x9006 # 0 +0xB067 0x8FF7 # 0 +0xB068 0x9000 # 0 +0xB069 0x8FFA # 0 +0xB06A 0x8FF4 # 0 +0xB06B 0x9003 # 0 +0xB06C 0x8FFD # 0 +0xB06D 0x9005 # 0 +0xB06E 0x8FF8 # 0 +0xB06F 0x9095 # 0 +0xB070 0x90E1 # 0 +0xB071 0x90DD # 0 +0xB072 0x90E2 # 0 +0xB073 0x9152 # 0 +0xB074 0x914D # 0 +0xB075 0x914C # 0 +0xB076 0x91D8 # 0 +0xB077 0x91DD # 0 +0xB078 0x91D7 # 0 +0xB079 0x91DC # 0 +0xB07A 0x91D9 # 0 +0xB07B 0x9583 # 0 +0xB07C 0x9662 # 0 +0xB07D 0x9663 # 0 +0xB07E 0x9661 # 0 +0xB0A1 0x965B # 0 +0xB0A2 0x965D # 0 +0xB0A3 0x9664 # 0 +0xB0A4 0x9658 # 0 +0xB0A5 0x965E # 0 +0xB0A6 0x96BB # 0 +0xB0A7 0x98E2 # 0 +0xB0A8 0x99AC # 0 +0xB0A9 0x9AA8 # 0 +0xB0AA 0x9AD8 # 0 +0xB0AB 0x9B25 # 0 +0xB0AC 0x9B32 # 0 +0xB0AD 0x9B3C # 0 +0xB0AE 0x4E7E # 0 +0xB0AF 0x507A # 0 +0xB0B0 0x507D # 0 +0xB0B1 0x505C # 0 +0xB0B2 0x5047 # 0 +0xB0B3 0x5043 # 0 +0xB0B4 0x504C # 0 +0xB0B5 0x505A # 0 +0xB0B6 0x5049 # 0 +0xB0B7 0x5065 # 0 +0xB0B8 0x5076 # 0 +0xB0B9 0x504E # 0 +0xB0BA 0x5055 # 0 +0xB0BB 0x5075 # 0 +0xB0BC 0x5074 # 0 +0xB0BD 0x5077 # 0 +0xB0BE 0x504F # 0 +0xB0BF 0x500F # 0 +0xB0C0 0x506F # 0 +0xB0C1 0x506D # 0 +0xB0C2 0x515C # 0 +0xB0C3 0x5195 # 0 +0xB0C4 0x51F0 # 0 +0xB0C5 0x526A # 0 +0xB0C6 0x526F # 0 +0xB0C7 0x52D2 # 0 +0xB0C8 0x52D9 # 0 +0xB0C9 0x52D8 # 0 +0xB0CA 0x52D5 # 0 +0xB0CB 0x5310 # 0 +0xB0CC 0x530F # 0 +0xB0CD 0x5319 # 0 +0xB0CE 0x533F # 0 +0xB0CF 0x5340 # 0 +0xB0D0 0x533E # 0 +0xB0D1 0x53C3 # 0 +0xB0D2 0x66FC # 0 +0xB0D3 0x5546 # 0 +0xB0D4 0x556A # 0 +0xB0D5 0x5566 # 0 +0xB0D6 0x5544 # 0 +0xB0D7 0x555E # 0 +0xB0D8 0x5561 # 0 +0xB0D9 0x5543 # 0 +0xB0DA 0x554A # 0 +0xB0DB 0x5531 # 0 +0xB0DC 0x5556 # 0 +0xB0DD 0x554F # 0 +0xB0DE 0x5555 # 0 +0xB0DF 0x552F # 0 +0xB0E0 0x5564 # 0 +0xB0E1 0x5538 # 0 +0xB0E2 0x552E # 0 +0xB0E3 0x555C # 0 +0xB0E4 0x552C # 0 +0xB0E5 0x5563 # 0 +0xB0E6 0x5533 # 0 +0xB0E7 0x5541 # 0 +0xB0E8 0x5557 # 0 +0xB0E9 0x5708 # 0 +0xB0EA 0x570B # 0 +0xB0EB 0x5709 # 0 +0xB0EC 0x57DF # 0 +0xB0ED 0x5805 # 0 +0xB0EE 0x580A # 0 +0xB0EF 0x5806 # 0 +0xB0F0 0x57E0 # 0 +0xB0F1 0x57E4 # 0 +0xB0F2 0x57FA # 0 +0xB0F3 0x5802 # 0 +0xB0F4 0x5835 # 0 +0xB0F5 0x57F7 # 0 +0xB0F6 0x57F9 # 0 +0xB0F7 0x5920 # 0 +0xB0F8 0x5962 # 0 +0xB0F9 0x5A36 # 0 +0xB0FA 0x5A41 # 0 +0xB0FB 0x5A49 # 0 +0xB0FC 0x5A66 # 0 +0xB0FD 0x5A6A # 0 +0xB0FE 0x5A40 # 0 +0xB140 0x5A3C # 0 +0xB141 0x5A62 # 0 +0xB142 0x5A5A # 0 +0xB143 0x5A46 # 0 +0xB144 0x5A4A # 0 +0xB145 0x5B70 # 0 +0xB146 0x5BC7 # 0 +0xB147 0x5BC5 # 0 +0xB148 0x5BC4 # 0 +0xB149 0x5BC2 # 0 +0xB14A 0x5BBF # 0 +0xB14B 0x5BC6 # 0 +0xB14C 0x5C09 # 0 +0xB14D 0x5C08 # 0 +0xB14E 0x5C07 # 0 +0xB14F 0x5C60 # 0 +0xB150 0x5C5C # 0 +0xB151 0x5C5D # 0 +0xB152 0x5D07 # 0 +0xB153 0x5D06 # 0 +0xB154 0x5D0E # 0 +0xB155 0x5D1B # 0 +0xB156 0x5D16 # 0 +0xB157 0x5D22 # 0 +0xB158 0x5D11 # 0 +0xB159 0x5D29 # 0 +0xB15A 0x5D14 # 0 +0xB15B 0x5D19 # 0 +0xB15C 0x5D24 # 0 +0xB15D 0x5D27 # 0 +0xB15E 0x5D17 # 0 +0xB15F 0x5DE2 # 0 +0xB160 0x5E38 # 0 +0xB161 0x5E36 # 0 +0xB162 0x5E33 # 0 +0xB163 0x5E37 # 0 +0xB164 0x5EB7 # 0 +0xB165 0x5EB8 # 0 +0xB166 0x5EB6 # 0 +0xB167 0x5EB5 # 0 +0xB168 0x5EBE # 0 +0xB169 0x5F35 # 0 +0xB16A 0x5F37 # 0 +0xB16B 0x5F57 # 0 +0xB16C 0x5F6C # 0 +0xB16D 0x5F69 # 0 +0xB16E 0x5F6B # 0 +0xB16F 0x5F97 # 0 +0xB170 0x5F99 # 0 +0xB171 0x5F9E # 0 +0xB172 0x5F98 # 0 +0xB173 0x5FA1 # 0 +0xB174 0x5FA0 # 0 +0xB175 0x5F9C # 0 +0xB176 0x607F # 0 +0xB177 0x60A3 # 0 +0xB178 0x6089 # 0 +0xB179 0x60A0 # 0 +0xB17A 0x60A8 # 0 +0xB17B 0x60CB # 0 +0xB17C 0x60B4 # 0 +0xB17D 0x60E6 # 0 +0xB17E 0x60BD # 0 +0xB1A1 0x60C5 # 0 +0xB1A2 0x60BB # 0 +0xB1A3 0x60B5 # 0 +0xB1A4 0x60DC # 0 +0xB1A5 0x60BC # 0 +0xB1A6 0x60D8 # 0 +0xB1A7 0x60D5 # 0 +0xB1A8 0x60C6 # 0 +0xB1A9 0x60DF # 0 +0xB1AA 0x60B8 # 0 +0xB1AB 0x60DA # 0 +0xB1AC 0x60C7 # 0 +0xB1AD 0x621A # 0 +0xB1AE 0x621B # 0 +0xB1AF 0x6248 # 0 +0xB1B0 0x63A0 # 0 +0xB1B1 0x63A7 # 0 +0xB1B2 0x6372 # 0 +0xB1B3 0x6396 # 0 +0xB1B4 0x63A2 # 0 +0xB1B5 0x63A5 # 0 +0xB1B6 0x6377 # 0 +0xB1B7 0x6367 # 0 +0xB1B8 0x6398 # 0 +0xB1B9 0x63AA # 0 +0xB1BA 0x6371 # 0 +0xB1BB 0x63A9 # 0 +0xB1BC 0x6389 # 0 +0xB1BD 0x6383 # 0 +0xB1BE 0x639B # 0 +0xB1BF 0x636B # 0 +0xB1C0 0x63A8 # 0 +0xB1C1 0x6384 # 0 +0xB1C2 0x6388 # 0 +0xB1C3 0x6399 # 0 +0xB1C4 0x63A1 # 0 +0xB1C5 0x63AC # 0 +0xB1C6 0x6392 # 0 +0xB1C7 0x638F # 0 +0xB1C8 0x6380 # 0 +0xB1C9 0x637B # 0 +0xB1CA 0x6369 # 0 +0xB1CB 0x6368 # 0 +0xB1CC 0x637A # 0 +0xB1CD 0x655D # 0 +0xB1CE 0x6556 # 0 +0xB1CF 0x6551 # 0 +0xB1D0 0x6559 # 0 +0xB1D1 0x6557 # 0 +0xB1D2 0x555F # 0 +0xB1D3 0x654F # 0 +0xB1D4 0x6558 # 0 +0xB1D5 0x6555 # 0 +0xB1D6 0x6554 # 0 +0xB1D7 0x659C # 0 +0xB1D8 0x659B # 0 +0xB1D9 0x65AC # 0 +0xB1DA 0x65CF # 0 +0xB1DB 0x65CB # 0 +0xB1DC 0x65CC # 0 +0xB1DD 0x65CE # 0 +0xB1DE 0x665D # 0 +0xB1DF 0x665A # 0 +0xB1E0 0x6664 # 0 +0xB1E1 0x6668 # 0 +0xB1E2 0x6666 # 0 +0xB1E3 0x665E # 0 +0xB1E4 0x66F9 # 0 +0xB1E5 0x52D7 # 0 +0xB1E6 0x671B # 0 +0xB1E7 0x6881 # 0 +0xB1E8 0x68AF # 0 +0xB1E9 0x68A2 # 0 +0xB1EA 0x6893 # 0 +0xB1EB 0x68B5 # 0 +0xB1EC 0x687F # 0 +0xB1ED 0x6876 # 0 +0xB1EE 0x68B1 # 0 +0xB1EF 0x68A7 # 0 +0xB1F0 0x6897 # 0 +0xB1F1 0x68B0 # 0 +0xB1F2 0x6883 # 0 +0xB1F3 0x68C4 # 0 +0xB1F4 0x68AD # 0 +0xB1F5 0x6886 # 0 +0xB1F6 0x6885 # 0 +0xB1F7 0x6894 # 0 +0xB1F8 0x689D # 0 +0xB1F9 0x68A8 # 0 +0xB1FA 0x689F # 0 +0xB1FB 0x68A1 # 0 +0xB1FC 0x6882 # 0 +0xB1FD 0x6B32 # 0 +0xB1FE 0x6BBA # 0 +0xB240 0x6BEB # 0 +0xB241 0x6BEC # 0 +0xB242 0x6C2B # 0 +0xB243 0x6D8E # 0 +0xB244 0x6DBC # 0 +0xB245 0x6DF3 # 0 +0xB246 0x6DD9 # 0 +0xB247 0x6DB2 # 0 +0xB248 0x6DE1 # 0 +0xB249 0x6DCC # 0 +0xB24A 0x6DE4 # 0 +0xB24B 0x6DFB # 0 +0xB24C 0x6DFA # 0 +0xB24D 0x6E05 # 0 +0xB24E 0x6DC7 # 0 +0xB24F 0x6DCB # 0 +0xB250 0x6DAF # 0 +0xB251 0x6DD1 # 0 +0xB252 0x6DAE # 0 +0xB253 0x6DDE # 0 +0xB254 0x6DF9 # 0 +0xB255 0x6DB8 # 0 +0xB256 0x6DF7 # 0 +0xB257 0x6DF5 # 0 +0xB258 0x6DC5 # 0 +0xB259 0x6DD2 # 0 +0xB25A 0x6E1A # 0 +0xB25B 0x6DB5 # 0 +0xB25C 0x6DDA # 0 +0xB25D 0x6DEB # 0 +0xB25E 0x6DD8 # 0 +0xB25F 0x6DEA # 0 +0xB260 0x6DF1 # 0 +0xB261 0x6DEE # 0 +0xB262 0x6DE8 # 0 +0xB263 0x6DC6 # 0 +0xB264 0x6DC4 # 0 +0xB265 0x6DAA # 0 +0xB266 0x6DEC # 0 +0xB267 0x6DBF # 0 +0xB268 0x6DE6 # 0 +0xB269 0x70F9 # 0 +0xB26A 0x7109 # 0 +0xB26B 0x710A # 0 +0xB26C 0x70FD # 0 +0xB26D 0x70EF # 0 +0xB26E 0x723D # 0 +0xB26F 0x727D # 0 +0xB270 0x7281 # 0 +0xB271 0x731C # 0 +0xB272 0x731B # 0 +0xB273 0x7316 # 0 +0xB274 0x7313 # 0 +0xB275 0x7319 # 0 +0xB276 0x7387 # 0 +0xB277 0x7405 # 0 +0xB278 0x740A # 0 +0xB279 0x7403 # 0 +0xB27A 0x7406 # 0 +0xB27B 0x73FE # 0 +0xB27C 0x740D # 0 +0xB27D 0x74E0 # 0 +0xB27E 0x74F6 # 0 +0xB2A1 0x74F7 # 0 +0xB2A2 0x751C # 0 +0xB2A3 0x7522 # 0 +0xB2A4 0x7565 # 0 +0xB2A5 0x7566 # 0 +0xB2A6 0x7562 # 0 +0xB2A7 0x7570 # 0 +0xB2A8 0x758F # 0 +0xB2A9 0x75D4 # 0 +0xB2AA 0x75D5 # 0 +0xB2AB 0x75B5 # 0 +0xB2AC 0x75CA # 0 +0xB2AD 0x75CD # 0 +0xB2AE 0x768E # 0 +0xB2AF 0x76D4 # 0 +0xB2B0 0x76D2 # 0 +0xB2B1 0x76DB # 0 +0xB2B2 0x7737 # 0 +0xB2B3 0x773E # 0 +0xB2B4 0x773C # 0 +0xB2B5 0x7736 # 0 +0xB2B6 0x7738 # 0 +0xB2B7 0x773A # 0 +0xB2B8 0x786B # 0 +0xB2B9 0x7843 # 0 +0xB2BA 0x784E # 0 +0xB2BB 0x7965 # 0 +0xB2BC 0x7968 # 0 +0xB2BD 0x796D # 0 +0xB2BE 0x79FB # 0 +0xB2BF 0x7A92 # 0 +0xB2C0 0x7A95 # 0 +0xB2C1 0x7B20 # 0 +0xB2C2 0x7B28 # 0 +0xB2C3 0x7B1B # 0 +0xB2C4 0x7B2C # 0 +0xB2C5 0x7B26 # 0 +0xB2C6 0x7B19 # 0 +0xB2C7 0x7B1E # 0 +0xB2C8 0x7B2E # 0 +0xB2C9 0x7C92 # 0 +0xB2CA 0x7C97 # 0 +0xB2CB 0x7C95 # 0 +0xB2CC 0x7D46 # 0 +0xB2CD 0x7D43 # 0 +0xB2CE 0x7D71 # 0 +0xB2CF 0x7D2E # 0 +0xB2D0 0x7D39 # 0 +0xB2D1 0x7D3C # 0 +0xB2D2 0x7D40 # 0 +0xB2D3 0x7D30 # 0 +0xB2D4 0x7D33 # 0 +0xB2D5 0x7D44 # 0 +0xB2D6 0x7D2F # 0 +0xB2D7 0x7D42 # 0 +0xB2D8 0x7D32 # 0 +0xB2D9 0x7D31 # 0 +0xB2DA 0x7F3D # 0 +0xB2DB 0x7F9E # 0 +0xB2DC 0x7F9A # 0 +0xB2DD 0x7FCC # 0 +0xB2DE 0x7FCE # 0 +0xB2DF 0x7FD2 # 0 +0xB2E0 0x801C # 0 +0xB2E1 0x804A # 0 +0xB2E2 0x8046 # 0 +0xB2E3 0x812F # 0 +0xB2E4 0x8116 # 0 +0xB2E5 0x8123 # 0 +0xB2E6 0x812B # 0 +0xB2E7 0x8129 # 0 +0xB2E8 0x8130 # 0 +0xB2E9 0x8124 # 0 +0xB2EA 0x8202 # 0 +0xB2EB 0x8235 # 0 +0xB2EC 0x8237 # 0 +0xB2ED 0x8236 # 0 +0xB2EE 0x8239 # 0 +0xB2EF 0x838E # 0 +0xB2F0 0x839E # 0 +0xB2F1 0x8398 # 0 +0xB2F2 0x8378 # 0 +0xB2F3 0x83A2 # 0 +0xB2F4 0x8396 # 0 +0xB2F5 0x83BD # 0 +0xB2F6 0x83AB # 0 +0xB2F7 0x8392 # 0 +0xB2F8 0x838A # 0 +0xB2F9 0x8393 # 0 +0xB2FA 0x8389 # 0 +0xB2FB 0x83A0 # 0 +0xB2FC 0x8377 # 0 +0xB2FD 0x837B # 0 +0xB2FE 0x837C # 0 +0xB340 0x8386 # 0 +0xB341 0x83A7 # 0 +0xB342 0x8655 # 0 +0xB343 0x5F6A # 0 +0xB344 0x86C7 # 0 +0xB345 0x86C0 # 0 +0xB346 0x86B6 # 0 +0xB347 0x86C4 # 0 +0xB348 0x86B5 # 0 +0xB349 0x86C6 # 0 +0xB34A 0x86CB # 0 +0xB34B 0x86B1 # 0 +0xB34C 0x86AF # 0 +0xB34D 0x86C9 # 0 +0xB34E 0x8853 # 0 +0xB34F 0x889E # 0 +0xB350 0x8888 # 0 +0xB351 0x88AB # 0 +0xB352 0x8892 # 0 +0xB353 0x8896 # 0 +0xB354 0x888D # 0 +0xB355 0x888B # 0 +0xB356 0x8993 # 0 +0xB357 0x898F # 0 +0xB358 0x8A2A # 0 +0xB359 0x8A1D # 0 +0xB35A 0x8A23 # 0 +0xB35B 0x8A25 # 0 +0xB35C 0x8A31 # 0 +0xB35D 0x8A2D # 0 +0xB35E 0x8A1F # 0 +0xB35F 0x8A1B # 0 +0xB360 0x8A22 # 0 +0xB361 0x8C49 # 0 +0xB362 0x8C5A # 0 +0xB363 0x8CA9 # 0 +0xB364 0x8CAC # 0 +0xB365 0x8CAB # 0 +0xB366 0x8CA8 # 0 +0xB367 0x8CAA # 0 +0xB368 0x8CA7 # 0 +0xB369 0x8D67 # 0 +0xB36A 0x8D66 # 0 +0xB36B 0x8DBE # 0 +0xB36C 0x8DBA # 0 +0xB36D 0x8EDB # 0 +0xB36E 0x8EDF # 0 +0xB36F 0x9019 # 0 +0xB370 0x900D # 0 +0xB371 0x901A # 0 +0xB372 0x9017 # 0 +0xB373 0x9023 # 0 +0xB374 0x901F # 0 +0xB375 0x901D # 0 +0xB376 0x9010 # 0 +0xB377 0x9015 # 0 +0xB378 0x901E # 0 +0xB379 0x9020 # 0 +0xB37A 0x900F # 0 +0xB37B 0x9022 # 0 +0xB37C 0x9016 # 0 +0xB37D 0x901B # 0 +0xB37E 0x9014 # 0 +0xB3A1 0x90E8 # 0 +0xB3A2 0x90ED # 0 +0xB3A3 0x90FD # 0 +0xB3A4 0x9157 # 0 +0xB3A5 0x91CE # 0 +0xB3A6 0x91F5 # 0 +0xB3A7 0x91E6 # 0 +0xB3A8 0x91E3 # 0 +0xB3A9 0x91E7 # 0 +0xB3AA 0x91ED # 0 +0xB3AB 0x91E9 # 0 +0xB3AC 0x9589 # 0 +0xB3AD 0x966A # 0 +0xB3AE 0x9675 # 0 +0xB3AF 0x9673 # 0 +0xB3B0 0x9678 # 0 +0xB3B1 0x9670 # 0 +0xB3B2 0x9674 # 0 +0xB3B3 0x9676 # 0 +0xB3B4 0x9677 # 0 +0xB3B5 0x966C # 0 +0xB3B6 0x96C0 # 0 +0xB3B7 0x96EA # 0 +0xB3B8 0x96E9 # 0 +0xB3B9 0x7AE0 # 0 +0xB3BA 0x7ADF # 0 +0xB3BB 0x9802 # 0 +0xB3BC 0x9803 # 0 +0xB3BD 0x9B5A # 0 +0xB3BE 0x9CE5 # 0 +0xB3BF 0x9E75 # 0 +0xB3C0 0x9E7F # 0 +0xB3C1 0x9EA5 # 0 +0xB3C2 0x9EBB # 0 +0xB3C3 0x50A2 # 0 +0xB3C4 0x508D # 0 +0xB3C5 0x5085 # 0 +0xB3C6 0x5099 # 0 +0xB3C7 0x5091 # 0 +0xB3C8 0x5080 # 0 +0xB3C9 0x5096 # 0 +0xB3CA 0x5098 # 0 +0xB3CB 0x509A # 0 +0xB3CC 0x6700 # 0 +0xB3CD 0x51F1 # 0 +0xB3CE 0x5272 # 0 +0xB3CF 0x5274 # 0 +0xB3D0 0x5275 # 0 +0xB3D1 0x5269 # 0 +0xB3D2 0x52DE # 0 +0xB3D3 0x52DD # 0 +0xB3D4 0x52DB # 0 +0xB3D5 0x535A # 0 +0xB3D6 0x53A5 # 0 +0xB3D7 0x557B # 0 +0xB3D8 0x5580 # 0 +0xB3D9 0x55A7 # 0 +0xB3DA 0x557C # 0 +0xB3DB 0x558A # 0 +0xB3DC 0x559D # 0 +0xB3DD 0x5598 # 0 +0xB3DE 0x5582 # 0 +0xB3DF 0x559C # 0 +0xB3E0 0x55AA # 0 +0xB3E1 0x5594 # 0 +0xB3E2 0x5587 # 0 +0xB3E3 0x558B # 0 +0xB3E4 0x5583 # 0 +0xB3E5 0x55B3 # 0 +0xB3E6 0x55AE # 0 +0xB3E7 0x559F # 0 +0xB3E8 0x553E # 0 +0xB3E9 0x55B2 # 0 +0xB3EA 0x559A # 0 +0xB3EB 0x55BB # 0 +0xB3EC 0x55AC # 0 +0xB3ED 0x55B1 # 0 +0xB3EE 0x557E # 0 +0xB3EF 0x5589 # 0 +0xB3F0 0x55AB # 0 +0xB3F1 0x5599 # 0 +0xB3F2 0x570D # 0 +0xB3F3 0x582F # 0 +0xB3F4 0x582A # 0 +0xB3F5 0x5834 # 0 +0xB3F6 0x5824 # 0 +0xB3F7 0x5830 # 0 +0xB3F8 0x5831 # 0 +0xB3F9 0x5821 # 0 +0xB3FA 0x581D # 0 +0xB3FB 0x5820 # 0 +0xB3FC 0x58F9 # 0 +0xB3FD 0x58FA # 0 +0xB3FE 0x5960 # 0 +0xB440 0x5A77 # 0 +0xB441 0x5A9A # 0 +0xB442 0x5A7F # 0 +0xB443 0x5A92 # 0 +0xB444 0x5A9B # 0 +0xB445 0x5AA7 # 0 +0xB446 0x5B73 # 0 +0xB447 0x5B71 # 0 +0xB448 0x5BD2 # 0 +0xB449 0x5BCC # 0 +0xB44A 0x5BD3 # 0 +0xB44B 0x5BD0 # 0 +0xB44C 0x5C0A # 0 +0xB44D 0x5C0B # 0 +0xB44E 0x5C31 # 0 +0xB44F 0x5D4C # 0 +0xB450 0x5D50 # 0 +0xB451 0x5D34 # 0 +0xB452 0x5D47 # 0 +0xB453 0x5DFD # 0 +0xB454 0x5E45 # 0 +0xB455 0x5E3D # 0 +0xB456 0x5E40 # 0 +0xB457 0x5E43 # 0 +0xB458 0x5E7E # 0 +0xB459 0x5ECA # 0 +0xB45A 0x5EC1 # 0 +0xB45B 0x5EC2 # 0 +0xB45C 0x5EC4 # 0 +0xB45D 0x5F3C # 0 +0xB45E 0x5F6D # 0 +0xB45F 0x5FA9 # 0 +0xB460 0x5FAA # 0 +0xB461 0x5FA8 # 0 +0xB462 0x60D1 # 0 +0xB463 0x60E1 # 0 +0xB464 0x60B2 # 0 +0xB465 0x60B6 # 0 +0xB466 0x60E0 # 0 +0xB467 0x611C # 0 +0xB468 0x6123 # 0 +0xB469 0x60FA # 0 +0xB46A 0x6115 # 0 +0xB46B 0x60F0 # 0 +0xB46C 0x60FB # 0 +0xB46D 0x60F4 # 0 +0xB46E 0x6168 # 0 +0xB46F 0x60F1 # 0 +0xB470 0x610E # 0 +0xB471 0x60F6 # 0 +0xB472 0x6109 # 0 +0xB473 0x6100 # 0 +0xB474 0x6112 # 0 +0xB475 0x621F # 0 +0xB476 0x6249 # 0 +0xB477 0x63A3 # 0 +0xB478 0x638C # 0 +0xB479 0x63CF # 0 +0xB47A 0x63C0 # 0 +0xB47B 0x63E9 # 0 +0xB47C 0x63C9 # 0 +0xB47D 0x63C6 # 0 +0xB47E 0x63CD # 0 +0xB4A1 0x63D2 # 0 +0xB4A2 0x63E3 # 0 +0xB4A3 0x63D0 # 0 +0xB4A4 0x63E1 # 0 +0xB4A5 0x63D6 # 0 +0xB4A6 0x63ED # 0 +0xB4A7 0x63EE # 0 +0xB4A8 0x6376 # 0 +0xB4A9 0x63F4 # 0 +0xB4AA 0x63EA # 0 +0xB4AB 0x63DB # 0 +0xB4AC 0x6452 # 0 +0xB4AD 0x63DA # 0 +0xB4AE 0x63F9 # 0 +0xB4AF 0x655E # 0 +0xB4B0 0x6566 # 0 +0xB4B1 0x6562 # 0 +0xB4B2 0x6563 # 0 +0xB4B3 0x6591 # 0 +0xB4B4 0x6590 # 0 +0xB4B5 0x65AF # 0 +0xB4B6 0x666E # 0 +0xB4B7 0x6670 # 0 +0xB4B8 0x6674 # 0 +0xB4B9 0x6676 # 0 +0xB4BA 0x666F # 0 +0xB4BB 0x6691 # 0 +0xB4BC 0x667A # 0 +0xB4BD 0x667E # 0 +0xB4BE 0x6677 # 0 +0xB4BF 0x66FE # 0 +0xB4C0 0x66FF # 0 +0xB4C1 0x671F # 0 +0xB4C2 0x671D # 0 +0xB4C3 0x68FA # 0 +0xB4C4 0x68D5 # 0 +0xB4C5 0x68E0 # 0 +0xB4C6 0x68D8 # 0 +0xB4C7 0x68D7 # 0 +0xB4C8 0x6905 # 0 +0xB4C9 0x68DF # 0 +0xB4CA 0x68F5 # 0 +0xB4CB 0x68EE # 0 +0xB4CC 0x68E7 # 0 +0xB4CD 0x68F9 # 0 +0xB4CE 0x68D2 # 0 +0xB4CF 0x68F2 # 0 +0xB4D0 0x68E3 # 0 +0xB4D1 0x68CB # 0 +0xB4D2 0x68CD # 0 +0xB4D3 0x690D # 0 +0xB4D4 0x6912 # 0 +0xB4D5 0x690E # 0 +0xB4D6 0x68C9 # 0 +0xB4D7 0x68DA # 0 +0xB4D8 0x696E # 0 +0xB4D9 0x68FB # 0 +0xB4DA 0x6B3E # 0 +0xB4DB 0x6B3A # 0 +0xB4DC 0x6B3D # 0 +0xB4DD 0x6B98 # 0 +0xB4DE 0x6B96 # 0 +0xB4DF 0x6BBC # 0 +0xB4E0 0x6BEF # 0 +0xB4E1 0x6C2E # 0 +0xB4E2 0x6C2F # 0 +0xB4E3 0x6C2C # 0 +0xB4E4 0x6E2F # 0 +0xB4E5 0x6E38 # 0 +0xB4E6 0x6E54 # 0 +0xB4E7 0x6E21 # 0 +0xB4E8 0x6E32 # 0 +0xB4E9 0x6E67 # 0 +0xB4EA 0x6E4A # 0 +0xB4EB 0x6E20 # 0 +0xB4EC 0x6E25 # 0 +0xB4ED 0x6E23 # 0 +0xB4EE 0x6E1B # 0 +0xB4EF 0x6E5B # 0 +0xB4F0 0x6E58 # 0 +0xB4F1 0x6E24 # 0 +0xB4F2 0x6E56 # 0 +0xB4F3 0x6E6E # 0 +0xB4F4 0x6E2D # 0 +0xB4F5 0x6E26 # 0 +0xB4F6 0x6E6F # 0 +0xB4F7 0x6E34 # 0 +0xB4F8 0x6E4D # 0 +0xB4F9 0x6E3A # 0 +0xB4FA 0x6E2C # 0 +0xB4FB 0x6E43 # 0 +0xB4FC 0x6E1D # 0 +0xB4FD 0x6E3E # 0 +0xB4FE 0x6ECB # 0 +0xB540 0x6E89 # 0 +0xB541 0x6E19 # 0 +0xB542 0x6E4E # 0 +0xB543 0x6E63 # 0 +0xB544 0x6E44 # 0 +0xB545 0x6E72 # 0 +0xB546 0x6E69 # 0 +0xB547 0x6E5F # 0 +0xB548 0x7119 # 0 +0xB549 0x711A # 0 +0xB54A 0x7126 # 0 +0xB54B 0x7130 # 0 +0xB54C 0x7121 # 0 +0xB54D 0x7136 # 0 +0xB54E 0x716E # 0 +0xB54F 0x711C # 0 +0xB550 0x724C # 0 +0xB551 0x7284 # 0 +0xB552 0x7280 # 0 +0xB553 0x7336 # 0 +0xB554 0x7325 # 0 +0xB555 0x7334 # 0 +0xB556 0x7329 # 0 +0xB557 0x743A # 0 +0xB558 0x742A # 0 +0xB559 0x7433 # 0 +0xB55A 0x7422 # 0 +0xB55B 0x7425 # 0 +0xB55C 0x7435 # 0 +0xB55D 0x7436 # 0 +0xB55E 0x7434 # 0 +0xB55F 0x742F # 0 +0xB560 0x741B # 0 +0xB561 0x7426 # 0 +0xB562 0x7428 # 0 +0xB563 0x7525 # 0 +0xB564 0x7526 # 0 +0xB565 0x756B # 0 +0xB566 0x756A # 0 +0xB567 0x75E2 # 0 +0xB568 0x75DB # 0 +0xB569 0x75E3 # 0 +0xB56A 0x75D9 # 0 +0xB56B 0x75D8 # 0 +0xB56C 0x75DE # 0 +0xB56D 0x75E0 # 0 +0xB56E 0x767B # 0 +0xB56F 0x767C # 0 +0xB570 0x7696 # 0 +0xB571 0x7693 # 0 +0xB572 0x76B4 # 0 +0xB573 0x76DC # 0 +0xB574 0x774F # 0 +0xB575 0x77ED # 0 +0xB576 0x785D # 0 +0xB577 0x786C # 0 +0xB578 0x786F # 0 +0xB579 0x7A0D # 0 +0xB57A 0x7A08 # 0 +0xB57B 0x7A0B # 0 +0xB57C 0x7A05 # 0 +0xB57D 0x7A00 # 0 +0xB57E 0x7A98 # 0 +0xB5A1 0x7A97 # 0 +0xB5A2 0x7A96 # 0 +0xB5A3 0x7AE5 # 0 +0xB5A4 0x7AE3 # 0 +0xB5A5 0x7B49 # 0 +0xB5A6 0x7B56 # 0 +0xB5A7 0x7B46 # 0 +0xB5A8 0x7B50 # 0 +0xB5A9 0x7B52 # 0 +0xB5AA 0x7B54 # 0 +0xB5AB 0x7B4D # 0 +0xB5AC 0x7B4B # 0 +0xB5AD 0x7B4F # 0 +0xB5AE 0x7B51 # 0 +0xB5AF 0x7C9F # 0 +0xB5B0 0x7CA5 # 0 +0xB5B1 0x7D5E # 0 +0xB5B2 0x7D50 # 0 +0xB5B3 0x7D68 # 0 +0xB5B4 0x7D55 # 0 +0xB5B5 0x7D2B # 0 +0xB5B6 0x7D6E # 0 +0xB5B7 0x7D72 # 0 +0xB5B8 0x7D61 # 0 +0xB5B9 0x7D66 # 0 +0xB5BA 0x7D62 # 0 +0xB5BB 0x7D70 # 0 +0xB5BC 0x7D73 # 0 +0xB5BD 0x5584 # 0 +0xB5BE 0x7FD4 # 0 +0xB5BF 0x7FD5 # 0 +0xB5C0 0x800B # 0 +0xB5C1 0x8052 # 0 +0xB5C2 0x8085 # 0 +0xB5C3 0x8155 # 0 +0xB5C4 0x8154 # 0 +0xB5C5 0x814B # 0 +0xB5C6 0x8151 # 0 +0xB5C7 0x814E # 0 +0xB5C8 0x8139 # 0 +0xB5C9 0x8146 # 0 +0xB5CA 0x813E # 0 +0xB5CB 0x814C # 0 +0xB5CC 0x8153 # 0 +0xB5CD 0x8174 # 0 +0xB5CE 0x8212 # 0 +0xB5CF 0x821C # 0 +0xB5D0 0x83E9 # 0 +0xB5D1 0x8403 # 0 +0xB5D2 0x83F8 # 0 +0xB5D3 0x840D # 0 +0xB5D4 0x83E0 # 0 +0xB5D5 0x83C5 # 0 +0xB5D6 0x840B # 0 +0xB5D7 0x83C1 # 0 +0xB5D8 0x83EF # 0 +0xB5D9 0x83F1 # 0 +0xB5DA 0x83F4 # 0 +0xB5DB 0x8457 # 0 +0xB5DC 0x840A # 0 +0xB5DD 0x83F0 # 0 +0xB5DE 0x840C # 0 +0xB5DF 0x83CC # 0 +0xB5E0 0x83FD # 0 +0xB5E1 0x83F2 # 0 +0xB5E2 0x83CA # 0 +0xB5E3 0x8438 # 0 +0xB5E4 0x840E # 0 +0xB5E5 0x8404 # 0 +0xB5E6 0x83DC # 0 +0xB5E7 0x8407 # 0 +0xB5E8 0x83D4 # 0 +0xB5E9 0x83DF # 0 +0xB5EA 0x865B # 0 +0xB5EB 0x86DF # 0 +0xB5EC 0x86D9 # 0 +0xB5ED 0x86ED # 0 +0xB5EE 0x86D4 # 0 +0xB5EF 0x86DB # 0 +0xB5F0 0x86E4 # 0 +0xB5F1 0x86D0 # 0 +0xB5F2 0x86DE # 0 +0xB5F3 0x8857 # 0 +0xB5F4 0x88C1 # 0 +0xB5F5 0x88C2 # 0 +0xB5F6 0x88B1 # 0 +0xB5F7 0x8983 # 0 +0xB5F8 0x8996 # 0 +0xB5F9 0x8A3B # 0 +0xB5FA 0x8A60 # 0 +0xB5FB 0x8A55 # 0 +0xB5FC 0x8A5E # 0 +0xB5FD 0x8A3C # 0 +0xB5FE 0x8A41 # 0 +0xB640 0x8A54 # 0 +0xB641 0x8A5B # 0 +0xB642 0x8A50 # 0 +0xB643 0x8A46 # 0 +0xB644 0x8A34 # 0 +0xB645 0x8A3A # 0 +0xB646 0x8A36 # 0 +0xB647 0x8A56 # 0 +0xB648 0x8C61 # 0 +0xB649 0x8C82 # 0 +0xB64A 0x8CAF # 0 +0xB64B 0x8CBC # 0 +0xB64C 0x8CB3 # 0 +0xB64D 0x8CBD # 0 +0xB64E 0x8CC1 # 0 +0xB64F 0x8CBB # 0 +0xB650 0x8CC0 # 0 +0xB651 0x8CB4 # 0 +0xB652 0x8CB7 # 0 +0xB653 0x8CB6 # 0 +0xB654 0x8CBF # 0 +0xB655 0x8CB8 # 0 +0xB656 0x8D8A # 0 +0xB657 0x8D85 # 0 +0xB658 0x8D81 # 0 +0xB659 0x8DCE # 0 +0xB65A 0x8DDD # 0 +0xB65B 0x8DCB # 0 +0xB65C 0x8DDA # 0 +0xB65D 0x8DD1 # 0 +0xB65E 0x8DCC # 0 +0xB65F 0x8DDB # 0 +0xB660 0x8DC6 # 0 +0xB661 0x8EFB # 0 +0xB662 0x8EF8 # 0 +0xB663 0x8EFC # 0 +0xB664 0x8F9C # 0 +0xB665 0x902E # 0 +0xB666 0x9035 # 0 +0xB667 0x9031 # 0 +0xB668 0x9038 # 0 +0xB669 0x9032 # 0 +0xB66A 0x9036 # 0 +0xB66B 0x9102 # 0 +0xB66C 0x90F5 # 0 +0xB66D 0x9109 # 0 +0xB66E 0x90FE # 0 +0xB66F 0x9163 # 0 +0xB670 0x9165 # 0 +0xB671 0x91CF # 0 +0xB672 0x9214 # 0 +0xB673 0x9215 # 0 +0xB674 0x9223 # 0 +0xB675 0x9209 # 0 +0xB676 0x921E # 0 +0xB677 0x920D # 0 +0xB678 0x9210 # 0 +0xB679 0x9207 # 0 +0xB67A 0x9211 # 0 +0xB67B 0x9594 # 0 +0xB67C 0x958F # 0 +0xB67D 0x958B # 0 +0xB67E 0x9591 # 0 +0xB6A1 0x9593 # 0 +0xB6A2 0x9592 # 0 +0xB6A3 0x958E # 0 +0xB6A4 0x968A # 0 +0xB6A5 0x968E # 0 +0xB6A6 0x968B # 0 +0xB6A7 0x967D # 0 +0xB6A8 0x9685 # 0 +0xB6A9 0x9686 # 0 +0xB6AA 0x968D # 0 +0xB6AB 0x9672 # 0 +0xB6AC 0x9684 # 0 +0xB6AD 0x96C1 # 0 +0xB6AE 0x96C5 # 0 +0xB6AF 0x96C4 # 0 +0xB6B0 0x96C6 # 0 +0xB6B1 0x96C7 # 0 +0xB6B2 0x96EF # 0 +0xB6B3 0x96F2 # 0 +0xB6B4 0x97CC # 0 +0xB6B5 0x9805 # 0 +0xB6B6 0x9806 # 0 +0xB6B7 0x9808 # 0 +0xB6B8 0x98E7 # 0 +0xB6B9 0x98EA # 0 +0xB6BA 0x98EF # 0 +0xB6BB 0x98E9 # 0 +0xB6BC 0x98F2 # 0 +0xB6BD 0x98ED # 0 +0xB6BE 0x99AE # 0 +0xB6BF 0x99AD # 0 +0xB6C0 0x9EC3 # 0 +0xB6C1 0x9ECD # 0 +0xB6C2 0x9ED1 # 0 +0xB6C3 0x4E82 # 0 +0xB6C4 0x50AD # 0 +0xB6C5 0x50B5 # 0 +0xB6C6 0x50B2 # 0 +0xB6C7 0x50B3 # 0 +0xB6C8 0x50C5 # 0 +0xB6C9 0x50BE # 0 +0xB6CA 0x50AC # 0 +0xB6CB 0x50B7 # 0 +0xB6CC 0x50BB # 0 +0xB6CD 0x50AF # 0 +0xB6CE 0x50C7 # 0 +0xB6CF 0x527F # 0 +0xB6D0 0x5277 # 0 +0xB6D1 0x527D # 0 +0xB6D2 0x52DF # 0 +0xB6D3 0x52E6 # 0 +0xB6D4 0x52E4 # 0 +0xB6D5 0x52E2 # 0 +0xB6D6 0x52E3 # 0 +0xB6D7 0x532F # 0 +0xB6D8 0x55DF # 0 +0xB6D9 0x55E8 # 0 +0xB6DA 0x55D3 # 0 +0xB6DB 0x55E6 # 0 +0xB6DC 0x55CE # 0 +0xB6DD 0x55DC # 0 +0xB6DE 0x55C7 # 0 +0xB6DF 0x55D1 # 0 +0xB6E0 0x55E3 # 0 +0xB6E1 0x55E4 # 0 +0xB6E2 0x55EF # 0 +0xB6E3 0x55DA # 0 +0xB6E4 0x55E1 # 0 +0xB6E5 0x55C5 # 0 +0xB6E6 0x55C6 # 0 +0xB6E7 0x55E5 # 0 +0xB6E8 0x55C9 # 0 +0xB6E9 0x5712 # 0 +0xB6EA 0x5713 # 0 +0xB6EB 0x585E # 0 +0xB6EC 0x5851 # 0 +0xB6ED 0x5858 # 0 +0xB6EE 0x5857 # 0 +0xB6EF 0x585A # 0 +0xB6F0 0x5854 # 0 +0xB6F1 0x586B # 0 +0xB6F2 0x584C # 0 +0xB6F3 0x586D # 0 +0xB6F4 0x584A # 0 +0xB6F5 0x5862 # 0 +0xB6F6 0x5852 # 0 +0xB6F7 0x584B # 0 +0xB6F8 0x5967 # 0 +0xB6F9 0x5AC1 # 0 +0xB6FA 0x5AC9 # 0 +0xB6FB 0x5ACC # 0 +0xB6FC 0x5ABE # 0 +0xB6FD 0x5ABD # 0 +0xB6FE 0x5ABC # 0 +0xB740 0x5AB3 # 0 +0xB741 0x5AC2 # 0 +0xB742 0x5AB2 # 0 +0xB743 0x5D69 # 0 +0xB744 0x5D6F # 0 +0xB745 0x5E4C # 0 +0xB746 0x5E79 # 0 +0xB747 0x5EC9 # 0 +0xB748 0x5EC8 # 0 +0xB749 0x5F12 # 0 +0xB74A 0x5F59 # 0 +0xB74B 0x5FAC # 0 +0xB74C 0x5FAE # 0 +0xB74D 0x611A # 0 +0xB74E 0x610F # 0 +0xB74F 0x6148 # 0 +0xB750 0x611F # 0 +0xB751 0x60F3 # 0 +0xB752 0x611B # 0 +0xB753 0x60F9 # 0 +0xB754 0x6101 # 0 +0xB755 0x6108 # 0 +0xB756 0x614E # 0 +0xB757 0x614C # 0 +0xB758 0x6144 # 0 +0xB759 0x614D # 0 +0xB75A 0x613E # 0 +0xB75B 0x6134 # 0 +0xB75C 0x6127 # 0 +0xB75D 0x610D # 0 +0xB75E 0x6106 # 0 +0xB75F 0x6137 # 0 +0xB760 0x6221 # 0 +0xB761 0x6222 # 0 +0xB762 0x6413 # 0 +0xB763 0x643E # 0 +0xB764 0x641E # 0 +0xB765 0x642A # 0 +0xB766 0x642D # 0 +0xB767 0x643D # 0 +0xB768 0x642C # 0 +0xB769 0x640F # 0 +0xB76A 0x641C # 0 +0xB76B 0x6414 # 0 +0xB76C 0x640D # 0 +0xB76D 0x6436 # 0 +0xB76E 0x6416 # 0 +0xB76F 0x6417 # 0 +0xB770 0x6406 # 0 +0xB771 0x656C # 0 +0xB772 0x659F # 0 +0xB773 0x65B0 # 0 +0xB774 0x6697 # 0 +0xB775 0x6689 # 0 +0xB776 0x6687 # 0 +0xB777 0x6688 # 0 +0xB778 0x6696 # 0 +0xB779 0x6684 # 0 +0xB77A 0x6698 # 0 +0xB77B 0x668D # 0 +0xB77C 0x6703 # 0 +0xB77D 0x6994 # 0 +0xB77E 0x696D # 0 +0xB7A1 0x695A # 0 +0xB7A2 0x6977 # 0 +0xB7A3 0x6960 # 0 +0xB7A4 0x6954 # 0 +0xB7A5 0x6975 # 0 +0xB7A6 0x6930 # 0 +0xB7A7 0x6982 # 0 +0xB7A8 0x694A # 0 +0xB7A9 0x6968 # 0 +0xB7AA 0x696B # 0 +0xB7AB 0x695E # 0 +0xB7AC 0x6953 # 0 +0xB7AD 0x6979 # 0 +0xB7AE 0x6986 # 0 +0xB7AF 0x695D # 0 +0xB7B0 0x6963 # 0 +0xB7B1 0x695B # 0 +0xB7B2 0x6B47 # 0 +0xB7B3 0x6B72 # 0 +0xB7B4 0x6BC0 # 0 +0xB7B5 0x6BBF # 0 +0xB7B6 0x6BD3 # 0 +0xB7B7 0x6BFD # 0 +0xB7B8 0x6EA2 # 0 +0xB7B9 0x6EAF # 0 +0xB7BA 0x6ED3 # 0 +0xB7BB 0x6EB6 # 0 +0xB7BC 0x6EC2 # 0 +0xB7BD 0x6E90 # 0 +0xB7BE 0x6E9D # 0 +0xB7BF 0x6EC7 # 0 +0xB7C0 0x6EC5 # 0 +0xB7C1 0x6EA5 # 0 +0xB7C2 0x6E98 # 0 +0xB7C3 0x6EBC # 0 +0xB7C4 0x6EBA # 0 +0xB7C5 0x6EAB # 0 +0xB7C6 0x6ED1 # 0 +0xB7C7 0x6E96 # 0 +0xB7C8 0x6E9C # 0 +0xB7C9 0x6EC4 # 0 +0xB7CA 0x6ED4 # 0 +0xB7CB 0x6EAA # 0 +0xB7CC 0x6EA7 # 0 +0xB7CD 0x6EB4 # 0 +0xB7CE 0x714E # 0 +0xB7CF 0x7159 # 0 +0xB7D0 0x7169 # 0 +0xB7D1 0x7164 # 0 +0xB7D2 0x7149 # 0 +0xB7D3 0x7167 # 0 +0xB7D4 0x715C # 0 +0xB7D5 0x716C # 0 +0xB7D6 0x7166 # 0 +0xB7D7 0x714C # 0 +0xB7D8 0x7165 # 0 +0xB7D9 0x715E # 0 +0xB7DA 0x7146 # 0 +0xB7DB 0x7168 # 0 +0xB7DC 0x7156 # 0 +0xB7DD 0x723A # 0 +0xB7DE 0x7252 # 0 +0xB7DF 0x7337 # 0 +0xB7E0 0x7345 # 0 +0xB7E1 0x733F # 0 +0xB7E2 0x733E # 0 +0xB7E3 0x746F # 0 +0xB7E4 0x745A # 0 +0xB7E5 0x7455 # 0 +0xB7E6 0x745F # 0 +0xB7E7 0x745E # 0 +0xB7E8 0x7441 # 0 +0xB7E9 0x743F # 0 +0xB7EA 0x7459 # 0 +0xB7EB 0x745B # 0 +0xB7EC 0x745C # 0 +0xB7ED 0x7576 # 0 +0xB7EE 0x7578 # 0 +0xB7EF 0x7600 # 0 +0xB7F0 0x75F0 # 0 +0xB7F1 0x7601 # 0 +0xB7F2 0x75F2 # 0 +0xB7F3 0x75F1 # 0 +0xB7F4 0x75FA # 0 +0xB7F5 0x75FF # 0 +0xB7F6 0x75F4 # 0 +0xB7F7 0x75F3 # 0 +0xB7F8 0x76DE # 0 +0xB7F9 0x76DF # 0 +0xB7FA 0x775B # 0 +0xB7FB 0x776B # 0 +0xB7FC 0x7766 # 0 +0xB7FD 0x775E # 0 +0xB7FE 0x7763 # 0 +0xB840 0x7779 # 0 +0xB841 0x776A # 0 +0xB842 0x776C # 0 +0xB843 0x775C # 0 +0xB844 0x7765 # 0 +0xB845 0x7768 # 0 +0xB846 0x7762 # 0 +0xB847 0x77EE # 0 +0xB848 0x788E # 0 +0xB849 0x78B0 # 0 +0xB84A 0x7897 # 0 +0xB84B 0x7898 # 0 +0xB84C 0x788C # 0 +0xB84D 0x7889 # 0 +0xB84E 0x787C # 0 +0xB84F 0x7891 # 0 +0xB850 0x7893 # 0 +0xB851 0x787F # 0 +0xB852 0x797A # 0 +0xB853 0x797F # 0 +0xB854 0x7981 # 0 +0xB855 0x842C # 0 +0xB856 0x79BD # 0 +0xB857 0x7A1C # 0 +0xB858 0x7A1A # 0 +0xB859 0x7A20 # 0 +0xB85A 0x7A14 # 0 +0xB85B 0x7A1F # 0 +0xB85C 0x7A1E # 0 +0xB85D 0x7A9F # 0 +0xB85E 0x7AA0 # 0 +0xB85F 0x7B77 # 0 +0xB860 0x7BC0 # 0 +0xB861 0x7B60 # 0 +0xB862 0x7B6E # 0 +0xB863 0x7B67 # 0 +0xB864 0x7CB1 # 0 +0xB865 0x7CB3 # 0 +0xB866 0x7CB5 # 0 +0xB867 0x7D93 # 0 +0xB868 0x7D79 # 0 +0xB869 0x7D91 # 0 +0xB86A 0x7D81 # 0 +0xB86B 0x7D8F # 0 +0xB86C 0x7D5B # 0 +0xB86D 0x7F6E # 0 +0xB86E 0x7F69 # 0 +0xB86F 0x7F6A # 0 +0xB870 0x7F72 # 0 +0xB871 0x7FA9 # 0 +0xB872 0x7FA8 # 0 +0xB873 0x7FA4 # 0 +0xB874 0x8056 # 0 +0xB875 0x8058 # 0 +0xB876 0x8086 # 0 +0xB877 0x8084 # 0 +0xB878 0x8171 # 0 +0xB879 0x8170 # 0 +0xB87A 0x8178 # 0 +0xB87B 0x8165 # 0 +0xB87C 0x816E # 0 +0xB87D 0x8173 # 0 +0xB87E 0x816B # 0 +0xB8A1 0x8179 # 0 +0xB8A2 0x817A # 0 +0xB8A3 0x8166 # 0 +0xB8A4 0x8205 # 0 +0xB8A5 0x8247 # 0 +0xB8A6 0x8482 # 0 +0xB8A7 0x8477 # 0 +0xB8A8 0x843D # 0 +0xB8A9 0x8431 # 0 +0xB8AA 0x8475 # 0 +0xB8AB 0x8466 # 0 +0xB8AC 0x846B # 0 +0xB8AD 0x8449 # 0 +0xB8AE 0x846C # 0 +0xB8AF 0x845B # 0 +0xB8B0 0x843C # 0 +0xB8B1 0x8435 # 0 +0xB8B2 0x8461 # 0 +0xB8B3 0x8463 # 0 +0xB8B4 0x8469 # 0 +0xB8B5 0x846D # 0 +0xB8B6 0x8446 # 0 +0xB8B7 0x865E # 0 +0xB8B8 0x865C # 0 +0xB8B9 0x865F # 0 +0xB8BA 0x86F9 # 0 +0xB8BB 0x8713 # 0 +0xB8BC 0x8708 # 0 +0xB8BD 0x8707 # 0 +0xB8BE 0x8700 # 0 +0xB8BF 0x86FE # 0 +0xB8C0 0x86FB # 0 +0xB8C1 0x8702 # 0 +0xB8C2 0x8703 # 0 +0xB8C3 0x8706 # 0 +0xB8C4 0x870A # 0 +0xB8C5 0x8859 # 0 +0xB8C6 0x88DF # 0 +0xB8C7 0x88D4 # 0 +0xB8C8 0x88D9 # 0 +0xB8C9 0x88DC # 0 +0xB8CA 0x88D8 # 0 +0xB8CB 0x88DD # 0 +0xB8CC 0x88E1 # 0 +0xB8CD 0x88CA # 0 +0xB8CE 0x88D5 # 0 +0xB8CF 0x88D2 # 0 +0xB8D0 0x899C # 0 +0xB8D1 0x89E3 # 0 +0xB8D2 0x8A6B # 0 +0xB8D3 0x8A72 # 0 +0xB8D4 0x8A73 # 0 +0xB8D5 0x8A66 # 0 +0xB8D6 0x8A69 # 0 +0xB8D7 0x8A70 # 0 +0xB8D8 0x8A87 # 0 +0xB8D9 0x8A7C # 0 +0xB8DA 0x8A63 # 0 +0xB8DB 0x8AA0 # 0 +0xB8DC 0x8A71 # 0 +0xB8DD 0x8A85 # 0 +0xB8DE 0x8A6D # 0 +0xB8DF 0x8A62 # 0 +0xB8E0 0x8A6E # 0 +0xB8E1 0x8A6C # 0 +0xB8E2 0x8A79 # 0 +0xB8E3 0x8A7B # 0 +0xB8E4 0x8A3E # 0 +0xB8E5 0x8A68 # 0 +0xB8E6 0x8C62 # 0 +0xB8E7 0x8C8A # 0 +0xB8E8 0x8C89 # 0 +0xB8E9 0x8CCA # 0 +0xB8EA 0x8CC7 # 0 +0xB8EB 0x8CC8 # 0 +0xB8EC 0x8CC4 # 0 +0xB8ED 0x8CB2 # 0 +0xB8EE 0x8CC3 # 0 +0xB8EF 0x8CC2 # 0 +0xB8F0 0x8CC5 # 0 +0xB8F1 0x8DE1 # 0 +0xB8F2 0x8DDF # 0 +0xB8F3 0x8DE8 # 0 +0xB8F4 0x8DEF # 0 +0xB8F5 0x8DF3 # 0 +0xB8F6 0x8DFA # 0 +0xB8F7 0x8DEA # 0 +0xB8F8 0x8DE4 # 0 +0xB8F9 0x8DE6 # 0 +0xB8FA 0x8EB2 # 0 +0xB8FB 0x8F03 # 0 +0xB8FC 0x8F09 # 0 +0xB8FD 0x8EFE # 0 +0xB8FE 0x8F0A # 0 +0xB940 0x8F9F # 0 +0xB941 0x8FB2 # 0 +0xB942 0x904B # 0 +0xB943 0x904A # 0 +0xB944 0x9053 # 0 +0xB945 0x9042 # 0 +0xB946 0x9054 # 0 +0xB947 0x903C # 0 +0xB948 0x9055 # 0 +0xB949 0x9050 # 0 +0xB94A 0x9047 # 0 +0xB94B 0x904F # 0 +0xB94C 0x904E # 0 +0xB94D 0x904D # 0 +0xB94E 0x9051 # 0 +0xB94F 0x903E # 0 +0xB950 0x9041 # 0 +0xB951 0x9112 # 0 +0xB952 0x9117 # 0 +0xB953 0x916C # 0 +0xB954 0x916A # 0 +0xB955 0x9169 # 0 +0xB956 0x91C9 # 0 +0xB957 0x9237 # 0 +0xB958 0x9257 # 0 +0xB959 0x9238 # 0 +0xB95A 0x923D # 0 +0xB95B 0x9240 # 0 +0xB95C 0x923E # 0 +0xB95D 0x925B # 0 +0xB95E 0x924B # 0 +0xB95F 0x9264 # 0 +0xB960 0x9251 # 0 +0xB961 0x9234 # 0 +0xB962 0x9249 # 0 +0xB963 0x924D # 0 +0xB964 0x9245 # 0 +0xB965 0x9239 # 0 +0xB966 0x923F # 0 +0xB967 0x925A # 0 +0xB968 0x9598 # 0 +0xB969 0x9698 # 0 +0xB96A 0x9694 # 0 +0xB96B 0x9695 # 0 +0xB96C 0x96CD # 0 +0xB96D 0x96CB # 0 +0xB96E 0x96C9 # 0 +0xB96F 0x96CA # 0 +0xB970 0x96F7 # 0 +0xB971 0x96FB # 0 +0xB972 0x96F9 # 0 +0xB973 0x96F6 # 0 +0xB974 0x9756 # 0 +0xB975 0x9774 # 0 +0xB976 0x9776 # 0 +0xB977 0x9810 # 0 +0xB978 0x9811 # 0 +0xB979 0x9813 # 0 +0xB97A 0x980A # 0 +0xB97B 0x9812 # 0 +0xB97C 0x980C # 0 +0xB97D 0x98FC # 0 +0xB97E 0x98F4 # 0 +0xB9A1 0x98FD # 0 +0xB9A2 0x98FE # 0 +0xB9A3 0x99B3 # 0 +0xB9A4 0x99B1 # 0 +0xB9A5 0x99B4 # 0 +0xB9A6 0x9AE1 # 0 +0xB9A7 0x9CE9 # 0 +0xB9A8 0x9E82 # 0 +0xB9A9 0x9F0E # 0 +0xB9AA 0x9F13 # 0 +0xB9AB 0x9F20 # 0 +0xB9AC 0x50E7 # 0 +0xB9AD 0x50EE # 0 +0xB9AE 0x50E5 # 0 +0xB9AF 0x50D6 # 0 +0xB9B0 0x50ED # 0 +0xB9B1 0x50DA # 0 +0xB9B2 0x50D5 # 0 +0xB9B3 0x50CF # 0 +0xB9B4 0x50D1 # 0 +0xB9B5 0x50F1 # 0 +0xB9B6 0x50CE # 0 +0xB9B7 0x50E9 # 0 +0xB9B8 0x5162 # 0 +0xB9B9 0x51F3 # 0 +0xB9BA 0x5283 # 0 +0xB9BB 0x5282 # 0 +0xB9BC 0x5331 # 0 +0xB9BD 0x53AD # 0 +0xB9BE 0x55FE # 0 +0xB9BF 0x5600 # 0 +0xB9C0 0x561B # 0 +0xB9C1 0x5617 # 0 +0xB9C2 0x55FD # 0 +0xB9C3 0x5614 # 0 +0xB9C4 0x5606 # 0 +0xB9C5 0x5609 # 0 +0xB9C6 0x560D # 0 +0xB9C7 0x560E # 0 +0xB9C8 0x55F7 # 0 +0xB9C9 0x5616 # 0 +0xB9CA 0x561F # 0 +0xB9CB 0x5608 # 0 +0xB9CC 0x5610 # 0 +0xB9CD 0x55F6 # 0 +0xB9CE 0x5718 # 0 +0xB9CF 0x5716 # 0 +0xB9D0 0x5875 # 0 +0xB9D1 0x587E # 0 +0xB9D2 0x5883 # 0 +0xB9D3 0x5893 # 0 +0xB9D4 0x588A # 0 +0xB9D5 0x5879 # 0 +0xB9D6 0x5885 # 0 +0xB9D7 0x587D # 0 +0xB9D8 0x58FD # 0 +0xB9D9 0x5925 # 0 +0xB9DA 0x5922 # 0 +0xB9DB 0x5924 # 0 +0xB9DC 0x596A # 0 +0xB9DD 0x5969 # 0 +0xB9DE 0x5AE1 # 0 +0xB9DF 0x5AE6 # 0 +0xB9E0 0x5AE9 # 0 +0xB9E1 0x5AD7 # 0 +0xB9E2 0x5AD6 # 0 +0xB9E3 0x5AD8 # 0 +0xB9E4 0x5AE3 # 0 +0xB9E5 0x5B75 # 0 +0xB9E6 0x5BDE # 0 +0xB9E7 0x5BE7 # 0 +0xB9E8 0x5BE1 # 0 +0xB9E9 0x5BE5 # 0 +0xB9EA 0x5BE6 # 0 +0xB9EB 0x5BE8 # 0 +0xB9EC 0x5BE2 # 0 +0xB9ED 0x5BE4 # 0 +0xB9EE 0x5BDF # 0 +0xB9EF 0x5C0D # 0 +0xB9F0 0x5C62 # 0 +0xB9F1 0x5D84 # 0 +0xB9F2 0x5D87 # 0 +0xB9F3 0x5E5B # 0 +0xB9F4 0x5E63 # 0 +0xB9F5 0x5E55 # 0 +0xB9F6 0x5E57 # 0 +0xB9F7 0x5E54 # 0 +0xB9F8 0x5ED3 # 0 +0xB9F9 0x5ED6 # 0 +0xB9FA 0x5F0A # 0 +0xB9FB 0x5F46 # 0 +0xB9FC 0x5F70 # 0 +0xB9FD 0x5FB9 # 0 +0xB9FE 0x6147 # 0 +0xBA40 0x613F # 0 +0xBA41 0x614B # 0 +0xBA42 0x6177 # 0 +0xBA43 0x6162 # 0 +0xBA44 0x6163 # 0 +0xBA45 0x615F # 0 +0xBA46 0x615A # 0 +0xBA47 0x6158 # 0 +0xBA48 0x6175 # 0 +0xBA49 0x622A # 0 +0xBA4A 0x6487 # 0 +0xBA4B 0x6458 # 0 +0xBA4C 0x6454 # 0 +0xBA4D 0x64A4 # 0 +0xBA4E 0x6478 # 0 +0xBA4F 0x645F # 0 +0xBA50 0x647A # 0 +0xBA51 0x6451 # 0 +0xBA52 0x6467 # 0 +0xBA53 0x6434 # 0 +0xBA54 0x646D # 0 +0xBA55 0x647B # 0 +0xBA56 0x6572 # 0 +0xBA57 0x65A1 # 0 +0xBA58 0x65D7 # 0 +0xBA59 0x65D6 # 0 +0xBA5A 0x66A2 # 0 +0xBA5B 0x66A8 # 0 +0xBA5C 0x669D # 0 +0xBA5D 0x699C # 0 +0xBA5E 0x69A8 # 0 +0xBA5F 0x6995 # 0 +0xBA60 0x69C1 # 0 +0xBA61 0x69AE # 0 +0xBA62 0x69D3 # 0 +0xBA63 0x69CB # 0 +0xBA64 0x699B # 0 +0xBA65 0x69B7 # 0 +0xBA66 0x69BB # 0 +0xBA67 0x69AB # 0 +0xBA68 0x69B4 # 0 +0xBA69 0x69D0 # 0 +0xBA6A 0x69CD # 0 +0xBA6B 0x69AD # 0 +0xBA6C 0x69CC # 0 +0xBA6D 0x69A6 # 0 +0xBA6E 0x69C3 # 0 +0xBA6F 0x69A3 # 0 +0xBA70 0x6B49 # 0 +0xBA71 0x6B4C # 0 +0xBA72 0x6C33 # 0 +0xBA73 0x6F33 # 0 +0xBA74 0x6F14 # 0 +0xBA75 0x6EFE # 0 +0xBA76 0x6F13 # 0 +0xBA77 0x6EF4 # 0 +0xBA78 0x6F29 # 0 +0xBA79 0x6F3E # 0 +0xBA7A 0x6F20 # 0 +0xBA7B 0x6F2C # 0 +0xBA7C 0x6F0F # 0 +0xBA7D 0x6F02 # 0 +0xBA7E 0x6F22 # 0 +0xBAA1 0x6EFF # 0 +0xBAA2 0x6EEF # 0 +0xBAA3 0x6F06 # 0 +0xBAA4 0x6F31 # 0 +0xBAA5 0x6F38 # 0 +0xBAA6 0x6F32 # 0 +0xBAA7 0x6F23 # 0 +0xBAA8 0x6F15 # 0 +0xBAA9 0x6F2B # 0 +0xBAAA 0x6F2F # 0 +0xBAAB 0x6F88 # 0 +0xBAAC 0x6F2A # 0 +0xBAAD 0x6EEC # 0 +0xBAAE 0x6F01 # 0 +0xBAAF 0x6EF2 # 0 +0xBAB0 0x6ECC # 0 +0xBAB1 0x6EF7 # 0 +0xBAB2 0x7194 # 0 +0xBAB3 0x7199 # 0 +0xBAB4 0x717D # 0 +0xBAB5 0x718A # 0 +0xBAB6 0x7184 # 0 +0xBAB7 0x7192 # 0 +0xBAB8 0x723E # 0 +0xBAB9 0x7292 # 0 +0xBABA 0x7296 # 0 +0xBABB 0x7344 # 0 +0xBABC 0x7350 # 0 +0xBABD 0x7464 # 0 +0xBABE 0x7463 # 0 +0xBABF 0x746A # 0 +0xBAC0 0x7470 # 0 +0xBAC1 0x746D # 0 +0xBAC2 0x7504 # 0 +0xBAC3 0x7591 # 0 +0xBAC4 0x7627 # 0 +0xBAC5 0x760D # 0 +0xBAC6 0x760B # 0 +0xBAC7 0x7609 # 0 +0xBAC8 0x7613 # 0 +0xBAC9 0x76E1 # 0 +0xBACA 0x76E3 # 0 +0xBACB 0x7784 # 0 +0xBACC 0x777D # 0 +0xBACD 0x777F # 0 +0xBACE 0x7761 # 0 +0xBACF 0x78C1 # 0 +0xBAD0 0x789F # 0 +0xBAD1 0x78A7 # 0 +0xBAD2 0x78B3 # 0 +0xBAD3 0x78A9 # 0 +0xBAD4 0x78A3 # 0 +0xBAD5 0x798E # 0 +0xBAD6 0x798F # 0 +0xBAD7 0x798D # 0 +0xBAD8 0x7A2E # 0 +0xBAD9 0x7A31 # 0 +0xBADA 0x7AAA # 0 +0xBADB 0x7AA9 # 0 +0xBADC 0x7AED # 0 +0xBADD 0x7AEF # 0 +0xBADE 0x7BA1 # 0 +0xBADF 0x7B95 # 0 +0xBAE0 0x7B8B # 0 +0xBAE1 0x7B75 # 0 +0xBAE2 0x7B97 # 0 +0xBAE3 0x7B9D # 0 +0xBAE4 0x7B94 # 0 +0xBAE5 0x7B8F # 0 +0xBAE6 0x7BB8 # 0 +0xBAE7 0x7B87 # 0 +0xBAE8 0x7B84 # 0 +0xBAE9 0x7CB9 # 0 +0xBAEA 0x7CBD # 0 +0xBAEB 0x7CBE # 0 +0xBAEC 0x7DBB # 0 +0xBAED 0x7DB0 # 0 +0xBAEE 0x7D9C # 0 +0xBAEF 0x7DBD # 0 +0xBAF0 0x7DBE # 0 +0xBAF1 0x7DA0 # 0 +0xBAF2 0x7DCA # 0 +0xBAF3 0x7DB4 # 0 +0xBAF4 0x7DB2 # 0 +0xBAF5 0x7DB1 # 0 +0xBAF6 0x7DBA # 0 +0xBAF7 0x7DA2 # 0 +0xBAF8 0x7DBF # 0 +0xBAF9 0x7DB5 # 0 +0xBAFA 0x7DB8 # 0 +0xBAFB 0x7DAD # 0 +0xBAFC 0x7DD2 # 0 +0xBAFD 0x7DC7 # 0 +0xBAFE 0x7DAC # 0 +0xBB40 0x7F70 # 0 +0xBB41 0x7FE0 # 0 +0xBB42 0x7FE1 # 0 +0xBB43 0x7FDF # 0 +0xBB44 0x805E # 0 +0xBB45 0x805A # 0 +0xBB46 0x8087 # 0 +0xBB47 0x8150 # 0 +0xBB48 0x8180 # 0 +0xBB49 0x818F # 0 +0xBB4A 0x8188 # 0 +0xBB4B 0x818A # 0 +0xBB4C 0x817F # 0 +0xBB4D 0x8182 # 0 +0xBB4E 0x81E7 # 0 +0xBB4F 0x81FA # 0 +0xBB50 0x8207 # 0 +0xBB51 0x8214 # 0 +0xBB52 0x821E # 0 +0xBB53 0x824B # 0 +0xBB54 0x84C9 # 0 +0xBB55 0x84BF # 0 +0xBB56 0x84C6 # 0 +0xBB57 0x84C4 # 0 +0xBB58 0x8499 # 0 +0xBB59 0x849E # 0 +0xBB5A 0x84B2 # 0 +0xBB5B 0x849C # 0 +0xBB5C 0x84CB # 0 +0xBB5D 0x84B8 # 0 +0xBB5E 0x84C0 # 0 +0xBB5F 0x84D3 # 0 +0xBB60 0x8490 # 0 +0xBB61 0x84BC # 0 +0xBB62 0x84D1 # 0 +0xBB63 0x84CA # 0 +0xBB64 0x873F # 0 +0xBB65 0x871C # 0 +0xBB66 0x873B # 0 +0xBB67 0x8722 # 0 +0xBB68 0x8725 # 0 +0xBB69 0x8734 # 0 +0xBB6A 0x8718 # 0 +0xBB6B 0x8755 # 0 +0xBB6C 0x8737 # 0 +0xBB6D 0x8729 # 0 +0xBB6E 0x88F3 # 0 +0xBB6F 0x8902 # 0 +0xBB70 0x88F4 # 0 +0xBB71 0x88F9 # 0 +0xBB72 0x88F8 # 0 +0xBB73 0x88FD # 0 +0xBB74 0x88E8 # 0 +0xBB75 0x891A # 0 +0xBB76 0x88EF # 0 +0xBB77 0x8AA6 # 0 +0xBB78 0x8A8C # 0 +0xBB79 0x8A9E # 0 +0xBB7A 0x8AA3 # 0 +0xBB7B 0x8A8D # 0 +0xBB7C 0x8AA1 # 0 +0xBB7D 0x8A93 # 0 +0xBB7E 0x8AA4 # 0 +0xBBA1 0x8AAA # 0 +0xBBA2 0x8AA5 # 0 +0xBBA3 0x8AA8 # 0 +0xBBA4 0x8A98 # 0 +0xBBA5 0x8A91 # 0 +0xBBA6 0x8A9A # 0 +0xBBA7 0x8AA7 # 0 +0xBBA8 0x8C6A # 0 +0xBBA9 0x8C8D # 0 +0xBBAA 0x8C8C # 0 +0xBBAB 0x8CD3 # 0 +0xBBAC 0x8CD1 # 0 +0xBBAD 0x8CD2 # 0 +0xBBAE 0x8D6B # 0 +0xBBAF 0x8D99 # 0 +0xBBB0 0x8D95 # 0 +0xBBB1 0x8DFC # 0 +0xBBB2 0x8F14 # 0 +0xBBB3 0x8F12 # 0 +0xBBB4 0x8F15 # 0 +0xBBB5 0x8F13 # 0 +0xBBB6 0x8FA3 # 0 +0xBBB7 0x9060 # 0 +0xBBB8 0x9058 # 0 +0xBBB9 0x905C # 0 +0xBBBA 0x9063 # 0 +0xBBBB 0x9059 # 0 +0xBBBC 0x905E # 0 +0xBBBD 0x9062 # 0 +0xBBBE 0x905D # 0 +0xBBBF 0x905B # 0 +0xBBC0 0x9119 # 0 +0xBBC1 0x9118 # 0 +0xBBC2 0x911E # 0 +0xBBC3 0x9175 # 0 +0xBBC4 0x9178 # 0 +0xBBC5 0x9177 # 0 +0xBBC6 0x9174 # 0 +0xBBC7 0x9278 # 0 +0xBBC8 0x9280 # 0 +0xBBC9 0x9285 # 0 +0xBBCA 0x9298 # 0 +0xBBCB 0x9296 # 0 +0xBBCC 0x927B # 0 +0xBBCD 0x9293 # 0 +0xBBCE 0x929C # 0 +0xBBCF 0x92A8 # 0 +0xBBD0 0x927C # 0 +0xBBD1 0x9291 # 0 +0xBBD2 0x95A1 # 0 +0xBBD3 0x95A8 # 0 +0xBBD4 0x95A9 # 0 +0xBBD5 0x95A3 # 0 +0xBBD6 0x95A5 # 0 +0xBBD7 0x95A4 # 0 +0xBBD8 0x9699 # 0 +0xBBD9 0x969C # 0 +0xBBDA 0x969B # 0 +0xBBDB 0x96CC # 0 +0xBBDC 0x96D2 # 0 +0xBBDD 0x9700 # 0 +0xBBDE 0x977C # 0 +0xBBDF 0x9785 # 0 +0xBBE0 0x97F6 # 0 +0xBBE1 0x9817 # 0 +0xBBE2 0x9818 # 0 +0xBBE3 0x98AF # 0 +0xBBE4 0x98B1 # 0 +0xBBE5 0x9903 # 0 +0xBBE6 0x9905 # 0 +0xBBE7 0x990C # 0 +0xBBE8 0x9909 # 0 +0xBBE9 0x99C1 # 0 +0xBBEA 0x9AAF # 0 +0xBBEB 0x9AB0 # 0 +0xBBEC 0x9AE6 # 0 +0xBBED 0x9B41 # 0 +0xBBEE 0x9B42 # 0 +0xBBEF 0x9CF4 # 0 +0xBBF0 0x9CF6 # 0 +0xBBF1 0x9CF3 # 0 +0xBBF2 0x9EBC # 0 +0xBBF3 0x9F3B # 0 +0xBBF4 0x9F4A # 0 +0xBBF5 0x5104 # 0 +0xBBF6 0x5100 # 0 +0xBBF7 0x50FB # 0 +0xBBF8 0x50F5 # 0 +0xBBF9 0x50F9 # 0 +0xBBFA 0x5102 # 0 +0xBBFB 0x5108 # 0 +0xBBFC 0x5109 # 0 +0xBBFD 0x5105 # 0 +0xBBFE 0x51DC # 0 +0xBC40 0x5287 # 0 +0xBC41 0x5288 # 0 +0xBC42 0x5289 # 0 +0xBC43 0x528D # 0 +0xBC44 0x528A # 0 +0xBC45 0x52F0 # 0 +0xBC46 0x53B2 # 0 +0xBC47 0x562E # 0 +0xBC48 0x563B # 0 +0xBC49 0x5639 # 0 +0xBC4A 0x5632 # 0 +0xBC4B 0x563F # 0 +0xBC4C 0x5634 # 0 +0xBC4D 0x5629 # 0 +0xBC4E 0x5653 # 0 +0xBC4F 0x564E # 0 +0xBC50 0x5657 # 0 +0xBC51 0x5674 # 0 +0xBC52 0x5636 # 0 +0xBC53 0x562F # 0 +0xBC54 0x5630 # 0 +0xBC55 0x5880 # 0 +0xBC56 0x589F # 0 +0xBC57 0x589E # 0 +0xBC58 0x58B3 # 0 +0xBC59 0x589C # 0 +0xBC5A 0x58AE # 0 +0xBC5B 0x58A9 # 0 +0xBC5C 0x58A6 # 0 +0xBC5D 0x596D # 0 +0xBC5E 0x5B09 # 0 +0xBC5F 0x5AFB # 0 +0xBC60 0x5B0B # 0 +0xBC61 0x5AF5 # 0 +0xBC62 0x5B0C # 0 +0xBC63 0x5B08 # 0 +0xBC64 0x5BEE # 0 +0xBC65 0x5BEC # 0 +0xBC66 0x5BE9 # 0 +0xBC67 0x5BEB # 0 +0xBC68 0x5C64 # 0 +0xBC69 0x5C65 # 0 +0xBC6A 0x5D9D # 0 +0xBC6B 0x5D94 # 0 +0xBC6C 0x5E62 # 0 +0xBC6D 0x5E5F # 0 +0xBC6E 0x5E61 # 0 +0xBC6F 0x5EE2 # 0 +0xBC70 0x5EDA # 0 +0xBC71 0x5EDF # 0 +0xBC72 0x5EDD # 0 +0xBC73 0x5EE3 # 0 +0xBC74 0x5EE0 # 0 +0xBC75 0x5F48 # 0 +0xBC76 0x5F71 # 0 +0xBC77 0x5FB7 # 0 +0xBC78 0x5FB5 # 0 +0xBC79 0x6176 # 0 +0xBC7A 0x6167 # 0 +0xBC7B 0x616E # 0 +0xBC7C 0x615D # 0 +0xBC7D 0x6155 # 0 +0xBC7E 0x6182 # 0 +0xBCA1 0x617C # 0 +0xBCA2 0x6170 # 0 +0xBCA3 0x616B # 0 +0xBCA4 0x617E # 0 +0xBCA5 0x61A7 # 0 +0xBCA6 0x6190 # 0 +0xBCA7 0x61AB # 0 +0xBCA8 0x618E # 0 +0xBCA9 0x61AC # 0 +0xBCAA 0x619A # 0 +0xBCAB 0x61A4 # 0 +0xBCAC 0x6194 # 0 +0xBCAD 0x61AE # 0 +0xBCAE 0x622E # 0 +0xBCAF 0x6469 # 0 +0xBCB0 0x646F # 0 +0xBCB1 0x6479 # 0 +0xBCB2 0x649E # 0 +0xBCB3 0x64B2 # 0 +0xBCB4 0x6488 # 0 +0xBCB5 0x6490 # 0 +0xBCB6 0x64B0 # 0 +0xBCB7 0x64A5 # 0 +0xBCB8 0x6493 # 0 +0xBCB9 0x6495 # 0 +0xBCBA 0x64A9 # 0 +0xBCBB 0x6492 # 0 +0xBCBC 0x64AE # 0 +0xBCBD 0x64AD # 0 +0xBCBE 0x64AB # 0 +0xBCBF 0x649A # 0 +0xBCC0 0x64AC # 0 +0xBCC1 0x6499 # 0 +0xBCC2 0x64A2 # 0 +0xBCC3 0x64B3 # 0 +0xBCC4 0x6575 # 0 +0xBCC5 0x6577 # 0 +0xBCC6 0x6578 # 0 +0xBCC7 0x66AE # 0 +0xBCC8 0x66AB # 0 +0xBCC9 0x66B4 # 0 +0xBCCA 0x66B1 # 0 +0xBCCB 0x6A23 # 0 +0xBCCC 0x6A1F # 0 +0xBCCD 0x69E8 # 0 +0xBCCE 0x6A01 # 0 +0xBCCF 0x6A1E # 0 +0xBCD0 0x6A19 # 0 +0xBCD1 0x69FD # 0 +0xBCD2 0x6A21 # 0 +0xBCD3 0x6A13 # 0 +0xBCD4 0x6A0A # 0 +0xBCD5 0x69F3 # 0 +0xBCD6 0x6A02 # 0 +0xBCD7 0x6A05 # 0 +0xBCD8 0x69ED # 0 +0xBCD9 0x6A11 # 0 +0xBCDA 0x6B50 # 0 +0xBCDB 0x6B4E # 0 +0xBCDC 0x6BA4 # 0 +0xBCDD 0x6BC5 # 0 +0xBCDE 0x6BC6 # 0 +0xBCDF 0x6F3F # 0 +0xBCE0 0x6F7C # 0 +0xBCE1 0x6F84 # 0 +0xBCE2 0x6F51 # 0 +0xBCE3 0x6F66 # 0 +0xBCE4 0x6F54 # 0 +0xBCE5 0x6F86 # 0 +0xBCE6 0x6F6D # 0 +0xBCE7 0x6F5B # 0 +0xBCE8 0x6F78 # 0 +0xBCE9 0x6F6E # 0 +0xBCEA 0x6F8E # 0 +0xBCEB 0x6F7A # 0 +0xBCEC 0x6F70 # 0 +0xBCED 0x6F64 # 0 +0xBCEE 0x6F97 # 0 +0xBCEF 0x6F58 # 0 +0xBCF0 0x6ED5 # 0 +0xBCF1 0x6F6F # 0 +0xBCF2 0x6F60 # 0 +0xBCF3 0x6F5F # 0 +0xBCF4 0x719F # 0 +0xBCF5 0x71AC # 0 +0xBCF6 0x71B1 # 0 +0xBCF7 0x71A8 # 0 +0xBCF8 0x7256 # 0 +0xBCF9 0x729B # 0 +0xBCFA 0x734E # 0 +0xBCFB 0x7357 # 0 +0xBCFC 0x7469 # 0 +0xBCFD 0x748B # 0 +0xBCFE 0x7483 # 0 +0xBD40 0x747E # 0 +0xBD41 0x7480 # 0 +0xBD42 0x757F # 0 +0xBD43 0x7620 # 0 +0xBD44 0x7629 # 0 +0xBD45 0x761F # 0 +0xBD46 0x7624 # 0 +0xBD47 0x7626 # 0 +0xBD48 0x7621 # 0 +0xBD49 0x7622 # 0 +0xBD4A 0x769A # 0 +0xBD4B 0x76BA # 0 +0xBD4C 0x76E4 # 0 +0xBD4D 0x778E # 0 +0xBD4E 0x7787 # 0 +0xBD4F 0x778C # 0 +0xBD50 0x7791 # 0 +0xBD51 0x778B # 0 +0xBD52 0x78CB # 0 +0xBD53 0x78C5 # 0 +0xBD54 0x78BA # 0 +0xBD55 0x78CA # 0 +0xBD56 0x78BE # 0 +0xBD57 0x78D5 # 0 +0xBD58 0x78BC # 0 +0xBD59 0x78D0 # 0 +0xBD5A 0x7A3F # 0 +0xBD5B 0x7A3C # 0 +0xBD5C 0x7A40 # 0 +0xBD5D 0x7A3D # 0 +0xBD5E 0x7A37 # 0 +0xBD5F 0x7A3B # 0 +0xBD60 0x7AAF # 0 +0xBD61 0x7AAE # 0 +0xBD62 0x7BAD # 0 +0xBD63 0x7BB1 # 0 +0xBD64 0x7BC4 # 0 +0xBD65 0x7BB4 # 0 +0xBD66 0x7BC6 # 0 +0xBD67 0x7BC7 # 0 +0xBD68 0x7BC1 # 0 +0xBD69 0x7BA0 # 0 +0xBD6A 0x7BCC # 0 +0xBD6B 0x7CCA # 0 +0xBD6C 0x7DE0 # 0 +0xBD6D 0x7DF4 # 0 +0xBD6E 0x7DEF # 0 +0xBD6F 0x7DFB # 0 +0xBD70 0x7DD8 # 0 +0xBD71 0x7DEC # 0 +0xBD72 0x7DDD # 0 +0xBD73 0x7DE8 # 0 +0xBD74 0x7DE3 # 0 +0xBD75 0x7DDA # 0 +0xBD76 0x7DDE # 0 +0xBD77 0x7DE9 # 0 +0xBD78 0x7D9E # 0 +0xBD79 0x7DD9 # 0 +0xBD7A 0x7DF2 # 0 +0xBD7B 0x7DF9 # 0 +0xBD7C 0x7F75 # 0 +0xBD7D 0x7F77 # 0 +0xBD7E 0x7FAF # 0 +0xBDA1 0x7FE9 # 0 +0xBDA2 0x8026 # 0 +0xBDA3 0x819B # 0 +0xBDA4 0x819C # 0 +0xBDA5 0x819D # 0 +0xBDA6 0x81A0 # 0 +0xBDA7 0x819A # 0 +0xBDA8 0x8198 # 0 +0xBDA9 0x8517 # 0 +0xBDAA 0x853D # 0 +0xBDAB 0x851A # 0 +0xBDAC 0x84EE # 0 +0xBDAD 0x852C # 0 +0xBDAE 0x852D # 0 +0xBDAF 0x8513 # 0 +0xBDB0 0x8511 # 0 +0xBDB1 0x8523 # 0 +0xBDB2 0x8521 # 0 +0xBDB3 0x8514 # 0 +0xBDB4 0x84EC # 0 +0xBDB5 0x8525 # 0 +0xBDB6 0x84FF # 0 +0xBDB7 0x8506 # 0 +0xBDB8 0x8782 # 0 +0xBDB9 0x8774 # 0 +0xBDBA 0x8776 # 0 +0xBDBB 0x8760 # 0 +0xBDBC 0x8766 # 0 +0xBDBD 0x8778 # 0 +0xBDBE 0x8768 # 0 +0xBDBF 0x8759 # 0 +0xBDC0 0x8757 # 0 +0xBDC1 0x874C # 0 +0xBDC2 0x8753 # 0 +0xBDC3 0x885B # 0 +0xBDC4 0x885D # 0 +0xBDC5 0x8910 # 0 +0xBDC6 0x8907 # 0 +0xBDC7 0x8912 # 0 +0xBDC8 0x8913 # 0 +0xBDC9 0x8915 # 0 +0xBDCA 0x890A # 0 +0xBDCB 0x8ABC # 0 +0xBDCC 0x8AD2 # 0 +0xBDCD 0x8AC7 # 0 +0xBDCE 0x8AC4 # 0 +0xBDCF 0x8A95 # 0 +0xBDD0 0x8ACB # 0 +0xBDD1 0x8AF8 # 0 +0xBDD2 0x8AB2 # 0 +0xBDD3 0x8AC9 # 0 +0xBDD4 0x8AC2 # 0 +0xBDD5 0x8ABF # 0 +0xBDD6 0x8AB0 # 0 +0xBDD7 0x8AD6 # 0 +0xBDD8 0x8ACD # 0 +0xBDD9 0x8AB6 # 0 +0xBDDA 0x8AB9 # 0 +0xBDDB 0x8ADB # 0 +0xBDDC 0x8C4C # 0 +0xBDDD 0x8C4E # 0 +0xBDDE 0x8C6C # 0 +0xBDDF 0x8CE0 # 0 +0xBDE0 0x8CDE # 0 +0xBDE1 0x8CE6 # 0 +0xBDE2 0x8CE4 # 0 +0xBDE3 0x8CEC # 0 +0xBDE4 0x8CED # 0 +0xBDE5 0x8CE2 # 0 +0xBDE6 0x8CE3 # 0 +0xBDE7 0x8CDC # 0 +0xBDE8 0x8CEA # 0 +0xBDE9 0x8CE1 # 0 +0xBDEA 0x8D6D # 0 +0xBDEB 0x8D9F # 0 +0xBDEC 0x8DA3 # 0 +0xBDED 0x8E2B # 0 +0xBDEE 0x8E10 # 0 +0xBDEF 0x8E1D # 0 +0xBDF0 0x8E22 # 0 +0xBDF1 0x8E0F # 0 +0xBDF2 0x8E29 # 0 +0xBDF3 0x8E1F # 0 +0xBDF4 0x8E21 # 0 +0xBDF5 0x8E1E # 0 +0xBDF6 0x8EBA # 0 +0xBDF7 0x8F1D # 0 +0xBDF8 0x8F1B # 0 +0xBDF9 0x8F1F # 0 +0xBDFA 0x8F29 # 0 +0xBDFB 0x8F26 # 0 +0xBDFC 0x8F2A # 0 +0xBDFD 0x8F1C # 0 +0xBDFE 0x8F1E # 0 +0xBE40 0x8F25 # 0 +0xBE41 0x9069 # 0 +0xBE42 0x906E # 0 +0xBE43 0x9068 # 0 +0xBE44 0x906D # 0 +0xBE45 0x9077 # 0 +0xBE46 0x9130 # 0 +0xBE47 0x912D # 0 +0xBE48 0x9127 # 0 +0xBE49 0x9131 # 0 +0xBE4A 0x9187 # 0 +0xBE4B 0x9189 # 0 +0xBE4C 0x918B # 0 +0xBE4D 0x9183 # 0 +0xBE4E 0x92C5 # 0 +0xBE4F 0x92BB # 0 +0xBE50 0x92B7 # 0 +0xBE51 0x92EA # 0 +0xBE52 0x92AC # 0 +0xBE53 0x92E4 # 0 +0xBE54 0x92C1 # 0 +0xBE55 0x92B3 # 0 +0xBE56 0x92BC # 0 +0xBE57 0x92D2 # 0 +0xBE58 0x92C7 # 0 +0xBE59 0x92F0 # 0 +0xBE5A 0x92B2 # 0 +0xBE5B 0x95AD # 0 +0xBE5C 0x95B1 # 0 +0xBE5D 0x9704 # 0 +0xBE5E 0x9706 # 0 +0xBE5F 0x9707 # 0 +0xBE60 0x9709 # 0 +0xBE61 0x9760 # 0 +0xBE62 0x978D # 0 +0xBE63 0x978B # 0 +0xBE64 0x978F # 0 +0xBE65 0x9821 # 0 +0xBE66 0x982B # 0 +0xBE67 0x981C # 0 +0xBE68 0x98B3 # 0 +0xBE69 0x990A # 0 +0xBE6A 0x9913 # 0 +0xBE6B 0x9912 # 0 +0xBE6C 0x9918 # 0 +0xBE6D 0x99DD # 0 +0xBE6E 0x99D0 # 0 +0xBE6F 0x99DF # 0 +0xBE70 0x99DB # 0 +0xBE71 0x99D1 # 0 +0xBE72 0x99D5 # 0 +0xBE73 0x99D2 # 0 +0xBE74 0x99D9 # 0 +0xBE75 0x9AB7 # 0 +0xBE76 0x9AEE # 0 +0xBE77 0x9AEF # 0 +0xBE78 0x9B27 # 0 +0xBE79 0x9B45 # 0 +0xBE7A 0x9B44 # 0 +0xBE7B 0x9B77 # 0 +0xBE7C 0x9B6F # 0 +0xBE7D 0x9D06 # 0 +0xBE7E 0x9D09 # 0 +0xBEA1 0x9D03 # 0 +0xBEA2 0x9EA9 # 0 +0xBEA3 0x9EBE # 0 +0xBEA4 0x9ECE # 0 +0xBEA5 0x58A8 # 0 +0xBEA6 0x9F52 # 0 +0xBEA7 0x5112 # 0 +0xBEA8 0x5118 # 0 +0xBEA9 0x5114 # 0 +0xBEAA 0x5110 # 0 +0xBEAB 0x5115 # 0 +0xBEAC 0x5180 # 0 +0xBEAD 0x51AA # 0 +0xBEAE 0x51DD # 0 +0xBEAF 0x5291 # 0 +0xBEB0 0x5293 # 0 +0xBEB1 0x52F3 # 0 +0xBEB2 0x5659 # 0 +0xBEB3 0x566B # 0 +0xBEB4 0x5679 # 0 +0xBEB5 0x5669 # 0 +0xBEB6 0x5664 # 0 +0xBEB7 0x5678 # 0 +0xBEB8 0x566A # 0 +0xBEB9 0x5668 # 0 +0xBEBA 0x5665 # 0 +0xBEBB 0x5671 # 0 +0xBEBC 0x566F # 0 +0xBEBD 0x566C # 0 +0xBEBE 0x5662 # 0 +0xBEBF 0x5676 # 0 +0xBEC0 0x58C1 # 0 +0xBEC1 0x58BE # 0 +0xBEC2 0x58C7 # 0 +0xBEC3 0x58C5 # 0 +0xBEC4 0x596E # 0 +0xBEC5 0x5B1D # 0 +0xBEC6 0x5B34 # 0 +0xBEC7 0x5B78 # 0 +0xBEC8 0x5BF0 # 0 +0xBEC9 0x5C0E # 0 +0xBECA 0x5F4A # 0 +0xBECB 0x61B2 # 0 +0xBECC 0x6191 # 0 +0xBECD 0x61A9 # 0 +0xBECE 0x618A # 0 +0xBECF 0x61CD # 0 +0xBED0 0x61B6 # 0 +0xBED1 0x61BE # 0 +0xBED2 0x61CA # 0 +0xBED3 0x61C8 # 0 +0xBED4 0x6230 # 0 +0xBED5 0x64C5 # 0 +0xBED6 0x64C1 # 0 +0xBED7 0x64CB # 0 +0xBED8 0x64BB # 0 +0xBED9 0x64BC # 0 +0xBEDA 0x64DA # 0 +0xBEDB 0x64C4 # 0 +0xBEDC 0x64C7 # 0 +0xBEDD 0x64C2 # 0 +0xBEDE 0x64CD # 0 +0xBEDF 0x64BF # 0 +0xBEE0 0x64D2 # 0 +0xBEE1 0x64D4 # 0 +0xBEE2 0x64BE # 0 +0xBEE3 0x6574 # 0 +0xBEE4 0x66C6 # 0 +0xBEE5 0x66C9 # 0 +0xBEE6 0x66B9 # 0 +0xBEE7 0x66C4 # 0 +0xBEE8 0x66C7 # 0 +0xBEE9 0x66B8 # 0 +0xBEEA 0x6A3D # 0 +0xBEEB 0x6A38 # 0 +0xBEEC 0x6A3A # 0 +0xBEED 0x6A59 # 0 +0xBEEE 0x6A6B # 0 +0xBEEF 0x6A58 # 0 +0xBEF0 0x6A39 # 0 +0xBEF1 0x6A44 # 0 +0xBEF2 0x6A62 # 0 +0xBEF3 0x6A61 # 0 +0xBEF4 0x6A4B # 0 +0xBEF5 0x6A47 # 0 +0xBEF6 0x6A35 # 0 +0xBEF7 0x6A5F # 0 +0xBEF8 0x6A48 # 0 +0xBEF9 0x6B59 # 0 +0xBEFA 0x6B77 # 0 +0xBEFB 0x6C05 # 0 +0xBEFC 0x6FC2 # 0 +0xBEFD 0x6FB1 # 0 +0xBEFE 0x6FA1 # 0 +0xBF40 0x6FC3 # 0 +0xBF41 0x6FA4 # 0 +0xBF42 0x6FC1 # 0 +0xBF43 0x6FA7 # 0 +0xBF44 0x6FB3 # 0 +0xBF45 0x6FC0 # 0 +0xBF46 0x6FB9 # 0 +0xBF47 0x6FB6 # 0 +0xBF48 0x6FA6 # 0 +0xBF49 0x6FA0 # 0 +0xBF4A 0x6FB4 # 0 +0xBF4B 0x71BE # 0 +0xBF4C 0x71C9 # 0 +0xBF4D 0x71D0 # 0 +0xBF4E 0x71D2 # 0 +0xBF4F 0x71C8 # 0 +0xBF50 0x71D5 # 0 +0xBF51 0x71B9 # 0 +0xBF52 0x71CE # 0 +0xBF53 0x71D9 # 0 +0xBF54 0x71DC # 0 +0xBF55 0x71C3 # 0 +0xBF56 0x71C4 # 0 +0xBF57 0x7368 # 0 +0xBF58 0x749C # 0 +0xBF59 0x74A3 # 0 +0xBF5A 0x7498 # 0 +0xBF5B 0x749F # 0 +0xBF5C 0x749E # 0 +0xBF5D 0x74E2 # 0 +0xBF5E 0x750C # 0 +0xBF5F 0x750D # 0 +0xBF60 0x7634 # 0 +0xBF61 0x7638 # 0 +0xBF62 0x763A # 0 +0xBF63 0x76E7 # 0 +0xBF64 0x76E5 # 0 +0xBF65 0x77A0 # 0 +0xBF66 0x779E # 0 +0xBF67 0x779F # 0 +0xBF68 0x77A5 # 0 +0xBF69 0x78E8 # 0 +0xBF6A 0x78DA # 0 +0xBF6B 0x78EC # 0 +0xBF6C 0x78E7 # 0 +0xBF6D 0x79A6 # 0 +0xBF6E 0x7A4D # 0 +0xBF6F 0x7A4E # 0 +0xBF70 0x7A46 # 0 +0xBF71 0x7A4C # 0 +0xBF72 0x7A4B # 0 +0xBF73 0x7ABA # 0 +0xBF74 0x7BD9 # 0 +0xBF75 0x7C11 # 0 +0xBF76 0x7BC9 # 0 +0xBF77 0x7BE4 # 0 +0xBF78 0x7BDB # 0 +0xBF79 0x7BE1 # 0 +0xBF7A 0x7BE9 # 0 +0xBF7B 0x7BE6 # 0 +0xBF7C 0x7CD5 # 0 +0xBF7D 0x7CD6 # 0 +0xBF7E 0x7E0A # 0 +0xBFA1 0x7E11 # 0 +0xBFA2 0x7E08 # 0 +0xBFA3 0x7E1B # 0 +0xBFA4 0x7E23 # 0 +0xBFA5 0x7E1E # 0 +0xBFA6 0x7E1D # 0 +0xBFA7 0x7E09 # 0 +0xBFA8 0x7E10 # 0 +0xBFA9 0x7F79 # 0 +0xBFAA 0x7FB2 # 0 +0xBFAB 0x7FF0 # 0 +0xBFAC 0x7FF1 # 0 +0xBFAD 0x7FEE # 0 +0xBFAE 0x8028 # 0 +0xBFAF 0x81B3 # 0 +0xBFB0 0x81A9 # 0 +0xBFB1 0x81A8 # 0 +0xBFB2 0x81FB # 0 +0xBFB3 0x8208 # 0 +0xBFB4 0x8258 # 0 +0xBFB5 0x8259 # 0 +0xBFB6 0x854A # 0 +0xBFB7 0x8559 # 0 +0xBFB8 0x8548 # 0 +0xBFB9 0x8568 # 0 +0xBFBA 0x8569 # 0 +0xBFBB 0x8543 # 0 +0xBFBC 0x8549 # 0 +0xBFBD 0x856D # 0 +0xBFBE 0x856A # 0 +0xBFBF 0x855E # 0 +0xBFC0 0x8783 # 0 +0xBFC1 0x879F # 0 +0xBFC2 0x879E # 0 +0xBFC3 0x87A2 # 0 +0xBFC4 0x878D # 0 +0xBFC5 0x8861 # 0 +0xBFC6 0x892A # 0 +0xBFC7 0x8932 # 0 +0xBFC8 0x8925 # 0 +0xBFC9 0x892B # 0 +0xBFCA 0x8921 # 0 +0xBFCB 0x89AA # 0 +0xBFCC 0x89A6 # 0 +0xBFCD 0x8AE6 # 0 +0xBFCE 0x8AFA # 0 +0xBFCF 0x8AEB # 0 +0xBFD0 0x8AF1 # 0 +0xBFD1 0x8B00 # 0 +0xBFD2 0x8ADC # 0 +0xBFD3 0x8AE7 # 0 +0xBFD4 0x8AEE # 0 +0xBFD5 0x8AFE # 0 +0xBFD6 0x8B01 # 0 +0xBFD7 0x8B02 # 0 +0xBFD8 0x8AF7 # 0 +0xBFD9 0x8AED # 0 +0xBFDA 0x8AF3 # 0 +0xBFDB 0x8AF6 # 0 +0xBFDC 0x8AFC # 0 +0xBFDD 0x8C6B # 0 +0xBFDE 0x8C6D # 0 +0xBFDF 0x8C93 # 0 +0xBFE0 0x8CF4 # 0 +0xBFE1 0x8E44 # 0 +0xBFE2 0x8E31 # 0 +0xBFE3 0x8E34 # 0 +0xBFE4 0x8E42 # 0 +0xBFE5 0x8E39 # 0 +0xBFE6 0x8E35 # 0 +0xBFE7 0x8F3B # 0 +0xBFE8 0x8F2F # 0 +0xBFE9 0x8F38 # 0 +0xBFEA 0x8F33 # 0 +0xBFEB 0x8FA8 # 0 +0xBFEC 0x8FA6 # 0 +0xBFED 0x9075 # 0 +0xBFEE 0x9074 # 0 +0xBFEF 0x9078 # 0 +0xBFF0 0x9072 # 0 +0xBFF1 0x907C # 0 +0xBFF2 0x907A # 0 +0xBFF3 0x9134 # 0 +0xBFF4 0x9192 # 0 +0xBFF5 0x9320 # 0 +0xBFF6 0x9336 # 0 +0xBFF7 0x92F8 # 0 +0xBFF8 0x9333 # 0 +0xBFF9 0x932F # 0 +0xBFFA 0x9322 # 0 +0xBFFB 0x92FC # 0 +0xBFFC 0x932B # 0 +0xBFFD 0x9304 # 0 +0xBFFE 0x931A # 0 +0xC040 0x9310 # 0 +0xC041 0x9326 # 0 +0xC042 0x9321 # 0 +0xC043 0x9315 # 0 +0xC044 0x932E # 0 +0xC045 0x9319 # 0 +0xC046 0x95BB # 0 +0xC047 0x96A7 # 0 +0xC048 0x96A8 # 0 +0xC049 0x96AA # 0 +0xC04A 0x96D5 # 0 +0xC04B 0x970E # 0 +0xC04C 0x9711 # 0 +0xC04D 0x9716 # 0 +0xC04E 0x970D # 0 +0xC04F 0x9713 # 0 +0xC050 0x970F # 0 +0xC051 0x975B # 0 +0xC052 0x975C # 0 +0xC053 0x9766 # 0 +0xC054 0x9798 # 0 +0xC055 0x9830 # 0 +0xC056 0x9838 # 0 +0xC057 0x983B # 0 +0xC058 0x9837 # 0 +0xC059 0x982D # 0 +0xC05A 0x9839 # 0 +0xC05B 0x9824 # 0 +0xC05C 0x9910 # 0 +0xC05D 0x9928 # 0 +0xC05E 0x991E # 0 +0xC05F 0x991B # 0 +0xC060 0x9921 # 0 +0xC061 0x991A # 0 +0xC062 0x99ED # 0 +0xC063 0x99E2 # 0 +0xC064 0x99F1 # 0 +0xC065 0x9AB8 # 0 +0xC066 0x9ABC # 0 +0xC067 0x9AFB # 0 +0xC068 0x9AED # 0 +0xC069 0x9B28 # 0 +0xC06A 0x9B91 # 0 +0xC06B 0x9D15 # 0 +0xC06C 0x9D23 # 0 +0xC06D 0x9D26 # 0 +0xC06E 0x9D28 # 0 +0xC06F 0x9D12 # 0 +0xC070 0x9D1B # 0 +0xC071 0x9ED8 # 0 +0xC072 0x9ED4 # 0 +0xC073 0x9F8D # 0 +0xC074 0x9F9C # 0 +0xC075 0x512A # 0 +0xC076 0x511F # 0 +0xC077 0x5121 # 0 +0xC078 0x5132 # 0 +0xC079 0x52F5 # 0 +0xC07A 0x568E # 0 +0xC07B 0x5680 # 0 +0xC07C 0x5690 # 0 +0xC07D 0x5685 # 0 +0xC07E 0x5687 # 0 +0xC0A1 0x568F # 0 +0xC0A2 0x58D5 # 0 +0xC0A3 0x58D3 # 0 +0xC0A4 0x58D1 # 0 +0xC0A5 0x58CE # 0 +0xC0A6 0x5B30 # 0 +0xC0A7 0x5B2A # 0 +0xC0A8 0x5B24 # 0 +0xC0A9 0x5B7A # 0 +0xC0AA 0x5C37 # 0 +0xC0AB 0x5C68 # 0 +0xC0AC 0x5DBC # 0 +0xC0AD 0x5DBA # 0 +0xC0AE 0x5DBD # 0 +0xC0AF 0x5DB8 # 0 +0xC0B0 0x5E6B # 0 +0xC0B1 0x5F4C # 0 +0xC0B2 0x5FBD # 0 +0xC0B3 0x61C9 # 0 +0xC0B4 0x61C2 # 0 +0xC0B5 0x61C7 # 0 +0xC0B6 0x61E6 # 0 +0xC0B7 0x61CB # 0 +0xC0B8 0x6232 # 0 +0xC0B9 0x6234 # 0 +0xC0BA 0x64CE # 0 +0xC0BB 0x64CA # 0 +0xC0BC 0x64D8 # 0 +0xC0BD 0x64E0 # 0 +0xC0BE 0x64F0 # 0 +0xC0BF 0x64E6 # 0 +0xC0C0 0x64EC # 0 +0xC0C1 0x64F1 # 0 +0xC0C2 0x64E2 # 0 +0xC0C3 0x64ED # 0 +0xC0C4 0x6582 # 0 +0xC0C5 0x6583 # 0 +0xC0C6 0x66D9 # 0 +0xC0C7 0x66D6 # 0 +0xC0C8 0x6A80 # 0 +0xC0C9 0x6A94 # 0 +0xC0CA 0x6A84 # 0 +0xC0CB 0x6AA2 # 0 +0xC0CC 0x6A9C # 0 +0xC0CD 0x6ADB # 0 +0xC0CE 0x6AA3 # 0 +0xC0CF 0x6A7E # 0 +0xC0D0 0x6A97 # 0 +0xC0D1 0x6A90 # 0 +0xC0D2 0x6AA0 # 0 +0xC0D3 0x6B5C # 0 +0xC0D4 0x6BAE # 0 +0xC0D5 0x6BDA # 0 +0xC0D6 0x6C08 # 0 +0xC0D7 0x6FD8 # 0 +0xC0D8 0x6FF1 # 0 +0xC0D9 0x6FDF # 0 +0xC0DA 0x6FE0 # 0 +0xC0DB 0x6FDB # 0 +0xC0DC 0x6FE4 # 0 +0xC0DD 0x6FEB # 0 +0xC0DE 0x6FEF # 0 +0xC0DF 0x6F80 # 0 +0xC0E0 0x6FEC # 0 +0xC0E1 0x6FE1 # 0 +0xC0E2 0x6FE9 # 0 +0xC0E3 0x6FD5 # 0 +0xC0E4 0x6FEE # 0 +0xC0E5 0x6FF0 # 0 +0xC0E6 0x71E7 # 0 +0xC0E7 0x71DF # 0 +0xC0E8 0x71EE # 0 +0xC0E9 0x71E6 # 0 +0xC0EA 0x71E5 # 0 +0xC0EB 0x71ED # 0 +0xC0EC 0x71EC # 0 +0xC0ED 0x71F4 # 0 +0xC0EE 0x71E0 # 0 +0xC0EF 0x7235 # 0 +0xC0F0 0x7246 # 0 +0xC0F1 0x7370 # 0 +0xC0F2 0x7372 # 0 +0xC0F3 0x74A9 # 0 +0xC0F4 0x74B0 # 0 +0xC0F5 0x74A6 # 0 +0xC0F6 0x74A8 # 0 +0xC0F7 0x7646 # 0 +0xC0F8 0x7642 # 0 +0xC0F9 0x764C # 0 +0xC0FA 0x76EA # 0 +0xC0FB 0x77B3 # 0 +0xC0FC 0x77AA # 0 +0xC0FD 0x77B0 # 0 +0xC0FE 0x77AC # 0 +0xC140 0x77A7 # 0 +0xC141 0x77AD # 0 +0xC142 0x77EF # 0 +0xC143 0x78F7 # 0 +0xC144 0x78FA # 0 +0xC145 0x78F4 # 0 +0xC146 0x78EF # 0 +0xC147 0x7901 # 0 +0xC148 0x79A7 # 0 +0xC149 0x79AA # 0 +0xC14A 0x7A57 # 0 +0xC14B 0x7ABF # 0 +0xC14C 0x7C07 # 0 +0xC14D 0x7C0D # 0 +0xC14E 0x7BFE # 0 +0xC14F 0x7BF7 # 0 +0xC150 0x7C0C # 0 +0xC151 0x7BE0 # 0 +0xC152 0x7CE0 # 0 +0xC153 0x7CDC # 0 +0xC154 0x7CDE # 0 +0xC155 0x7CE2 # 0 +0xC156 0x7CDF # 0 +0xC157 0x7CD9 # 0 +0xC158 0x7CDD # 0 +0xC159 0x7E2E # 0 +0xC15A 0x7E3E # 0 +0xC15B 0x7E46 # 0 +0xC15C 0x7E37 # 0 +0xC15D 0x7E32 # 0 +0xC15E 0x7E43 # 0 +0xC15F 0x7E2B # 0 +0xC160 0x7E3D # 0 +0xC161 0x7E31 # 0 +0xC162 0x7E45 # 0 +0xC163 0x7E41 # 0 +0xC164 0x7E34 # 0 +0xC165 0x7E39 # 0 +0xC166 0x7E48 # 0 +0xC167 0x7E35 # 0 +0xC168 0x7E3F # 0 +0xC169 0x7E2F # 0 +0xC16A 0x7F44 # 0 +0xC16B 0x7FF3 # 0 +0xC16C 0x7FFC # 0 +0xC16D 0x8071 # 0 +0xC16E 0x8072 # 0 +0xC16F 0x8070 # 0 +0xC170 0x806F # 0 +0xC171 0x8073 # 0 +0xC172 0x81C6 # 0 +0xC173 0x81C3 # 0 +0xC174 0x81BA # 0 +0xC175 0x81C2 # 0 +0xC176 0x81C0 # 0 +0xC177 0x81BF # 0 +0xC178 0x81BD # 0 +0xC179 0x81C9 # 0 +0xC17A 0x81BE # 0 +0xC17B 0x81E8 # 0 +0xC17C 0x8209 # 0 +0xC17D 0x8271 # 0 +0xC17E 0x85AA # 0 +0xC1A1 0x8584 # 0 +0xC1A2 0x857E # 0 +0xC1A3 0x859C # 0 +0xC1A4 0x8591 # 0 +0xC1A5 0x8594 # 0 +0xC1A6 0x85AF # 0 +0xC1A7 0x859B # 0 +0xC1A8 0x8587 # 0 +0xC1A9 0x85A8 # 0 +0xC1AA 0x858A # 0 +0xC1AB 0x8667 # 0 +0xC1AC 0x87C0 # 0 +0xC1AD 0x87D1 # 0 +0xC1AE 0x87B3 # 0 +0xC1AF 0x87D2 # 0 +0xC1B0 0x87C6 # 0 +0xC1B1 0x87AB # 0 +0xC1B2 0x87BB # 0 +0xC1B3 0x87BA # 0 +0xC1B4 0x87C8 # 0 +0xC1B5 0x87CB # 0 +0xC1B6 0x893B # 0 +0xC1B7 0x8936 # 0 +0xC1B8 0x8944 # 0 +0xC1B9 0x8938 # 0 +0xC1BA 0x893D # 0 +0xC1BB 0x89AC # 0 +0xC1BC 0x8B0E # 0 +0xC1BD 0x8B17 # 0 +0xC1BE 0x8B19 # 0 +0xC1BF 0x8B1B # 0 +0xC1C0 0x8B0A # 0 +0xC1C1 0x8B20 # 0 +0xC1C2 0x8B1D # 0 +0xC1C3 0x8B04 # 0 +0xC1C4 0x8B10 # 0 +0xC1C5 0x8C41 # 0 +0xC1C6 0x8C3F # 0 +0xC1C7 0x8C73 # 0 +0xC1C8 0x8CFA # 0 +0xC1C9 0x8CFD # 0 +0xC1CA 0x8CFC # 0 +0xC1CB 0x8CF8 # 0 +0xC1CC 0x8CFB # 0 +0xC1CD 0x8DA8 # 0 +0xC1CE 0x8E49 # 0 +0xC1CF 0x8E4B # 0 +0xC1D0 0x8E48 # 0 +0xC1D1 0x8E4A # 0 +0xC1D2 0x8F44 # 0 +0xC1D3 0x8F3E # 0 +0xC1D4 0x8F42 # 0 +0xC1D5 0x8F45 # 0 +0xC1D6 0x8F3F # 0 +0xC1D7 0x907F # 0 +0xC1D8 0x907D # 0 +0xC1D9 0x9084 # 0 +0xC1DA 0x9081 # 0 +0xC1DB 0x9082 # 0 +0xC1DC 0x9080 # 0 +0xC1DD 0x9139 # 0 +0xC1DE 0x91A3 # 0 +0xC1DF 0x919E # 0 +0xC1E0 0x919C # 0 +0xC1E1 0x934D # 0 +0xC1E2 0x9382 # 0 +0xC1E3 0x9328 # 0 +0xC1E4 0x9375 # 0 +0xC1E5 0x934A # 0 +0xC1E6 0x9365 # 0 +0xC1E7 0x934B # 0 +0xC1E8 0x9318 # 0 +0xC1E9 0x937E # 0 +0xC1EA 0x936C # 0 +0xC1EB 0x935B # 0 +0xC1EC 0x9370 # 0 +0xC1ED 0x935A # 0 +0xC1EE 0x9354 # 0 +0xC1EF 0x95CA # 0 +0xC1F0 0x95CB # 0 +0xC1F1 0x95CC # 0 +0xC1F2 0x95C8 # 0 +0xC1F3 0x95C6 # 0 +0xC1F4 0x96B1 # 0 +0xC1F5 0x96B8 # 0 +0xC1F6 0x96D6 # 0 +0xC1F7 0x971C # 0 +0xC1F8 0x971E # 0 +0xC1F9 0x97A0 # 0 +0xC1FA 0x97D3 # 0 +0xC1FB 0x9846 # 0 +0xC1FC 0x98B6 # 0 +0xC1FD 0x9935 # 0 +0xC1FE 0x9A01 # 0 +0xC240 0x99FF # 0 +0xC241 0x9BAE # 0 +0xC242 0x9BAB # 0 +0xC243 0x9BAA # 0 +0xC244 0x9BAD # 0 +0xC245 0x9D3B # 0 +0xC246 0x9D3F # 0 +0xC247 0x9E8B # 0 +0xC248 0x9ECF # 0 +0xC249 0x9EDE # 0 +0xC24A 0x9EDC # 0 +0xC24B 0x9EDD # 0 +0xC24C 0x9EDB # 0 +0xC24D 0x9F3E # 0 +0xC24E 0x9F4B # 0 +0xC24F 0x53E2 # 0 +0xC250 0x5695 # 0 +0xC251 0x56AE # 0 +0xC252 0x58D9 # 0 +0xC253 0x58D8 # 0 +0xC254 0x5B38 # 0 +0xC255 0x5F5D # 0 +0xC256 0x61E3 # 0 +0xC257 0x6233 # 0 +0xC258 0x64F4 # 0 +0xC259 0x64F2 # 0 +0xC25A 0x64FE # 0 +0xC25B 0x6506 # 0 +0xC25C 0x64FA # 0 +0xC25D 0x64FB # 0 +0xC25E 0x64F7 # 0 +0xC25F 0x65B7 # 0 +0xC260 0x66DC # 0 +0xC261 0x6726 # 0 +0xC262 0x6AB3 # 0 +0xC263 0x6AAC # 0 +0xC264 0x6AC3 # 0 +0xC265 0x6ABB # 0 +0xC266 0x6AB8 # 0 +0xC267 0x6AC2 # 0 +0xC268 0x6AAE # 0 +0xC269 0x6AAF # 0 +0xC26A 0x6B5F # 0 +0xC26B 0x6B78 # 0 +0xC26C 0x6BAF # 0 +0xC26D 0x7009 # 0 +0xC26E 0x700B # 0 +0xC26F 0x6FFE # 0 +0xC270 0x7006 # 0 +0xC271 0x6FFA # 0 +0xC272 0x7011 # 0 +0xC273 0x700F # 0 +0xC274 0x71FB # 0 +0xC275 0x71FC # 0 +0xC276 0x71FE # 0 +0xC277 0x71F8 # 0 +0xC278 0x7377 # 0 +0xC279 0x7375 # 0 +0xC27A 0x74A7 # 0 +0xC27B 0x74BF # 0 +0xC27C 0x7515 # 0 +0xC27D 0x7656 # 0 +0xC27E 0x7658 # 0 +0xC2A1 0x7652 # 0 +0xC2A2 0x77BD # 0 +0xC2A3 0x77BF # 0 +0xC2A4 0x77BB # 0 +0xC2A5 0x77BC # 0 +0xC2A6 0x790E # 0 +0xC2A7 0x79AE # 0 +0xC2A8 0x7A61 # 0 +0xC2A9 0x7A62 # 0 +0xC2AA 0x7A60 # 0 +0xC2AB 0x7AC4 # 0 +0xC2AC 0x7AC5 # 0 +0xC2AD 0x7C2B # 0 +0xC2AE 0x7C27 # 0 +0xC2AF 0x7C2A # 0 +0xC2B0 0x7C1E # 0 +0xC2B1 0x7C23 # 0 +0xC2B2 0x7C21 # 0 +0xC2B3 0x7CE7 # 0 +0xC2B4 0x7E54 # 0 +0xC2B5 0x7E55 # 0 +0xC2B6 0x7E5E # 0 +0xC2B7 0x7E5A # 0 +0xC2B8 0x7E61 # 0 +0xC2B9 0x7E52 # 0 +0xC2BA 0x7E59 # 0 +0xC2BB 0x7F48 # 0 +0xC2BC 0x7FF9 # 0 +0xC2BD 0x7FFB # 0 +0xC2BE 0x8077 # 0 +0xC2BF 0x8076 # 0 +0xC2C0 0x81CD # 0 +0xC2C1 0x81CF # 0 +0xC2C2 0x820A # 0 +0xC2C3 0x85CF # 0 +0xC2C4 0x85A9 # 0 +0xC2C5 0x85CD # 0 +0xC2C6 0x85D0 # 0 +0xC2C7 0x85C9 # 0 +0xC2C8 0x85B0 # 0 +0xC2C9 0x85BA # 0 +0xC2CA 0x85B9 # 0 +0xC2CB 0x85A6 # 0 +0xC2CC 0x87EF # 0 +0xC2CD 0x87EC # 0 +0xC2CE 0x87F2 # 0 +0xC2CF 0x87E0 # 0 +0xC2D0 0x8986 # 0 +0xC2D1 0x89B2 # 0 +0xC2D2 0x89F4 # 0 +0xC2D3 0x8B28 # 0 +0xC2D4 0x8B39 # 0 +0xC2D5 0x8B2C # 0 +0xC2D6 0x8B2B # 0 +0xC2D7 0x8C50 # 0 +0xC2D8 0x8D05 # 0 +0xC2D9 0x8E59 # 0 +0xC2DA 0x8E63 # 0 +0xC2DB 0x8E66 # 0 +0xC2DC 0x8E64 # 0 +0xC2DD 0x8E5F # 0 +0xC2DE 0x8E55 # 0 +0xC2DF 0x8EC0 # 0 +0xC2E0 0x8F49 # 0 +0xC2E1 0x8F4D # 0 +0xC2E2 0x9087 # 0 +0xC2E3 0x9083 # 0 +0xC2E4 0x9088 # 0 +0xC2E5 0x91AB # 0 +0xC2E6 0x91AC # 0 +0xC2E7 0x91D0 # 0 +0xC2E8 0x9394 # 0 +0xC2E9 0x938A # 0 +0xC2EA 0x9396 # 0 +0xC2EB 0x93A2 # 0 +0xC2EC 0x93B3 # 0 +0xC2ED 0x93AE # 0 +0xC2EE 0x93AC # 0 +0xC2EF 0x93B0 # 0 +0xC2F0 0x9398 # 0 +0xC2F1 0x939A # 0 +0xC2F2 0x9397 # 0 +0xC2F3 0x95D4 # 0 +0xC2F4 0x95D6 # 0 +0xC2F5 0x95D0 # 0 +0xC2F6 0x95D5 # 0 +0xC2F7 0x96E2 # 0 +0xC2F8 0x96DC # 0 +0xC2F9 0x96D9 # 0 +0xC2FA 0x96DB # 0 +0xC2FB 0x96DE # 0 +0xC2FC 0x9724 # 0 +0xC2FD 0x97A3 # 0 +0xC2FE 0x97A6 # 0 +0xC340 0x97AD # 0 +0xC341 0x97F9 # 0 +0xC342 0x984D # 0 +0xC343 0x984F # 0 +0xC344 0x984C # 0 +0xC345 0x984E # 0 +0xC346 0x9853 # 0 +0xC347 0x98BA # 0 +0xC348 0x993E # 0 +0xC349 0x993F # 0 +0xC34A 0x993D # 0 +0xC34B 0x992E # 0 +0xC34C 0x99A5 # 0 +0xC34D 0x9A0E # 0 +0xC34E 0x9AC1 # 0 +0xC34F 0x9B03 # 0 +0xC350 0x9B06 # 0 +0xC351 0x9B4F # 0 +0xC352 0x9B4E # 0 +0xC353 0x9B4D # 0 +0xC354 0x9BCA # 0 +0xC355 0x9BC9 # 0 +0xC356 0x9BFD # 0 +0xC357 0x9BC8 # 0 +0xC358 0x9BC0 # 0 +0xC359 0x9D51 # 0 +0xC35A 0x9D5D # 0 +0xC35B 0x9D60 # 0 +0xC35C 0x9EE0 # 0 +0xC35D 0x9F15 # 0 +0xC35E 0x9F2C # 0 +0xC35F 0x5133 # 0 +0xC360 0x56A5 # 0 +0xC361 0x58DE # 0 +0xC362 0x58DF # 0 +0xC363 0x58E2 # 0 +0xC364 0x5BF5 # 0 +0xC365 0x9F90 # 0 +0xC366 0x5EEC # 0 +0xC367 0x61F2 # 0 +0xC368 0x61F7 # 0 +0xC369 0x61F6 # 0 +0xC36A 0x61F5 # 0 +0xC36B 0x6500 # 0 +0xC36C 0x650F # 0 +0xC36D 0x66E0 # 0 +0xC36E 0x66DD # 0 +0xC36F 0x6AE5 # 0 +0xC370 0x6ADD # 0 +0xC371 0x6ADA # 0 +0xC372 0x6AD3 # 0 +0xC373 0x701B # 0 +0xC374 0x701F # 0 +0xC375 0x7028 # 0 +0xC376 0x701A # 0 +0xC377 0x701D # 0 +0xC378 0x7015 # 0 +0xC379 0x7018 # 0 +0xC37A 0x7206 # 0 +0xC37B 0x720D # 0 +0xC37C 0x7258 # 0 +0xC37D 0x72A2 # 0 +0xC37E 0x7378 # 0 +0xC3A1 0x737A # 0 +0xC3A2 0x74BD # 0 +0xC3A3 0x74CA # 0 +0xC3A4 0x74E3 # 0 +0xC3A5 0x7587 # 0 +0xC3A6 0x7586 # 0 +0xC3A7 0x765F # 0 +0xC3A8 0x7661 # 0 +0xC3A9 0x77C7 # 0 +0xC3AA 0x7919 # 0 +0xC3AB 0x79B1 # 0 +0xC3AC 0x7A6B # 0 +0xC3AD 0x7A69 # 0 +0xC3AE 0x7C3E # 0 +0xC3AF 0x7C3F # 0 +0xC3B0 0x7C38 # 0 +0xC3B1 0x7C3D # 0 +0xC3B2 0x7C37 # 0 +0xC3B3 0x7C40 # 0 +0xC3B4 0x7E6B # 0 +0xC3B5 0x7E6D # 0 +0xC3B6 0x7E79 # 0 +0xC3B7 0x7E69 # 0 +0xC3B8 0x7E6A # 0 +0xC3B9 0x7F85 # 0 +0xC3BA 0x7E73 # 0 +0xC3BB 0x7FB6 # 0 +0xC3BC 0x7FB9 # 0 +0xC3BD 0x7FB8 # 0 +0xC3BE 0x81D8 # 0 +0xC3BF 0x85E9 # 0 +0xC3C0 0x85DD # 0 +0xC3C1 0x85EA # 0 +0xC3C2 0x85D5 # 0 +0xC3C3 0x85E4 # 0 +0xC3C4 0x85E5 # 0 +0xC3C5 0x85F7 # 0 +0xC3C6 0x87FB # 0 +0xC3C7 0x8805 # 0 +0xC3C8 0x880D # 0 +0xC3C9 0x87F9 # 0 +0xC3CA 0x87FE # 0 +0xC3CB 0x8960 # 0 +0xC3CC 0x895F # 0 +0xC3CD 0x8956 # 0 +0xC3CE 0x895E # 0 +0xC3CF 0x8B41 # 0 +0xC3D0 0x8B5C # 0 +0xC3D1 0x8B58 # 0 +0xC3D2 0x8B49 # 0 +0xC3D3 0x8B5A # 0 +0xC3D4 0x8B4E # 0 +0xC3D5 0x8B4F # 0 +0xC3D6 0x8B46 # 0 +0xC3D7 0x8B59 # 0 +0xC3D8 0x8D08 # 0 +0xC3D9 0x8D0A # 0 +0xC3DA 0x8E7C # 0 +0xC3DB 0x8E72 # 0 +0xC3DC 0x8E87 # 0 +0xC3DD 0x8E76 # 0 +0xC3DE 0x8E6C # 0 +0xC3DF 0x8E7A # 0 +0xC3E0 0x8E74 # 0 +0xC3E1 0x8F54 # 0 +0xC3E2 0x8F4E # 0 +0xC3E3 0x8FAD # 0 +0xC3E4 0x908A # 0 +0xC3E5 0x908B # 0 +0xC3E6 0x91B1 # 0 +0xC3E7 0x91AE # 0 +0xC3E8 0x93E1 # 0 +0xC3E9 0x93D1 # 0 +0xC3EA 0x93DF # 0 +0xC3EB 0x93C3 # 0 +0xC3EC 0x93C8 # 0 +0xC3ED 0x93DC # 0 +0xC3EE 0x93DD # 0 +0xC3EF 0x93D6 # 0 +0xC3F0 0x93E2 # 0 +0xC3F1 0x93CD # 0 +0xC3F2 0x93D8 # 0 +0xC3F3 0x93E4 # 0 +0xC3F4 0x93D7 # 0 +0xC3F5 0x93E8 # 0 +0xC3F6 0x95DC # 0 +0xC3F7 0x96B4 # 0 +0xC3F8 0x96E3 # 0 +0xC3F9 0x972A # 0 +0xC3FA 0x9727 # 0 +0xC3FB 0x9761 # 0 +0xC3FC 0x97DC # 0 +0xC3FD 0x97FB # 0 +0xC3FE 0x985E # 0 +0xC440 0x9858 # 0 +0xC441 0x985B # 0 +0xC442 0x98BC # 0 +0xC443 0x9945 # 0 +0xC444 0x9949 # 0 +0xC445 0x9A16 # 0 +0xC446 0x9A19 # 0 +0xC447 0x9B0D # 0 +0xC448 0x9BE8 # 0 +0xC449 0x9BE7 # 0 +0xC44A 0x9BD6 # 0 +0xC44B 0x9BDB # 0 +0xC44C 0x9D89 # 0 +0xC44D 0x9D61 # 0 +0xC44E 0x9D72 # 0 +0xC44F 0x9D6A # 0 +0xC450 0x9D6C # 0 +0xC451 0x9E92 # 0 +0xC452 0x9E97 # 0 +0xC453 0x9E93 # 0 +0xC454 0x9EB4 # 0 +0xC455 0x52F8 # 0 +0xC456 0x56A8 # 0 +0xC457 0x56B7 # 0 +0xC458 0x56B6 # 0 +0xC459 0x56B4 # 0 +0xC45A 0x56BC # 0 +0xC45B 0x58E4 # 0 +0xC45C 0x5B40 # 0 +0xC45D 0x5B43 # 0 +0xC45E 0x5B7D # 0 +0xC45F 0x5BF6 # 0 +0xC460 0x5DC9 # 0 +0xC461 0x61F8 # 0 +0xC462 0x61FA # 0 +0xC463 0x6518 # 0 +0xC464 0x6514 # 0 +0xC465 0x6519 # 0 +0xC466 0x66E6 # 0 +0xC467 0x6727 # 0 +0xC468 0x6AEC # 0 +0xC469 0x703E # 0 +0xC46A 0x7030 # 0 +0xC46B 0x7032 # 0 +0xC46C 0x7210 # 0 +0xC46D 0x737B # 0 +0xC46E 0x74CF # 0 +0xC46F 0x7662 # 0 +0xC470 0x7665 # 0 +0xC471 0x7926 # 0 +0xC472 0x792A # 0 +0xC473 0x792C # 0 +0xC474 0x792B # 0 +0xC475 0x7AC7 # 0 +0xC476 0x7AF6 # 0 +0xC477 0x7C4C # 0 +0xC478 0x7C43 # 0 +0xC479 0x7C4D # 0 +0xC47A 0x7CEF # 0 +0xC47B 0x7CF0 # 0 +0xC47C 0x8FAE # 0 +0xC47D 0x7E7D # 0 +0xC47E 0x7E7C # 0 +0xC4A1 0x7E82 # 0 +0xC4A2 0x7F4C # 0 +0xC4A3 0x8000 # 0 +0xC4A4 0x81DA # 0 +0xC4A5 0x8266 # 0 +0xC4A6 0x85FB # 0 +0xC4A7 0x85F9 # 0 +0xC4A8 0x8611 # 0 +0xC4A9 0x85FA # 0 +0xC4AA 0x8606 # 0 +0xC4AB 0x860B # 0 +0xC4AC 0x8607 # 0 +0xC4AD 0x860A # 0 +0xC4AE 0x8814 # 0 +0xC4AF 0x8815 # 0 +0xC4B0 0x8964 # 0 +0xC4B1 0x89BA # 0 +0xC4B2 0x89F8 # 0 +0xC4B3 0x8B70 # 0 +0xC4B4 0x8B6C # 0 +0xC4B5 0x8B66 # 0 +0xC4B6 0x8B6F # 0 +0xC4B7 0x8B5F # 0 +0xC4B8 0x8B6B # 0 +0xC4B9 0x8D0F # 0 +0xC4BA 0x8D0D # 0 +0xC4BB 0x8E89 # 0 +0xC4BC 0x8E81 # 0 +0xC4BD 0x8E85 # 0 +0xC4BE 0x8E82 # 0 +0xC4BF 0x91B4 # 0 +0xC4C0 0x91CB # 0 +0xC4C1 0x9418 # 0 +0xC4C2 0x9403 # 0 +0xC4C3 0x93FD # 0 +0xC4C4 0x95E1 # 0 +0xC4C5 0x9730 # 0 +0xC4C6 0x98C4 # 0 +0xC4C7 0x9952 # 0 +0xC4C8 0x9951 # 0 +0xC4C9 0x99A8 # 0 +0xC4CA 0x9A2B # 0 +0xC4CB 0x9A30 # 0 +0xC4CC 0x9A37 # 0 +0xC4CD 0x9A35 # 0 +0xC4CE 0x9C13 # 0 +0xC4CF 0x9C0D # 0 +0xC4D0 0x9E79 # 0 +0xC4D1 0x9EB5 # 0 +0xC4D2 0x9EE8 # 0 +0xC4D3 0x9F2F # 0 +0xC4D4 0x9F5F # 0 +0xC4D5 0x9F63 # 0 +0xC4D6 0x9F61 # 0 +0xC4D7 0x5137 # 0 +0xC4D8 0x5138 # 0 +0xC4D9 0x56C1 # 0 +0xC4DA 0x56C0 # 0 +0xC4DB 0x56C2 # 0 +0xC4DC 0x5914 # 0 +0xC4DD 0x5C6C # 0 +0xC4DE 0x5DCD # 0 +0xC4DF 0x61FC # 0 +0xC4E0 0x61FE # 0 +0xC4E1 0x651D # 0 +0xC4E2 0x651C # 0 +0xC4E3 0x6595 # 0 +0xC4E4 0x66E9 # 0 +0xC4E5 0x6AFB # 0 +0xC4E6 0x6B04 # 0 +0xC4E7 0x6AFA # 0 +0xC4E8 0x6BB2 # 0 +0xC4E9 0x704C # 0 +0xC4EA 0x721B # 0 +0xC4EB 0x72A7 # 0 +0xC4EC 0x74D6 # 0 +0xC4ED 0x74D4 # 0 +0xC4EE 0x7669 # 0 +0xC4EF 0x77D3 # 0 +0xC4F0 0x7C50 # 0 +0xC4F1 0x7E8F # 0 +0xC4F2 0x7E8C # 0 +0xC4F3 0x7FBC # 0 +0xC4F4 0x8617 # 0 +0xC4F5 0x862D # 0 +0xC4F6 0x861A # 0 +0xC4F7 0x8823 # 0 +0xC4F8 0x8822 # 0 +0xC4F9 0x8821 # 0 +0xC4FA 0x881F # 0 +0xC4FB 0x896A # 0 +0xC4FC 0x896C # 0 +0xC4FD 0x89BD # 0 +0xC4FE 0x8B74 # 0 +0xC540 0x8B77 # 0 +0xC541 0x8B7D # 0 +0xC542 0x8D13 # 0 +0xC543 0x8E8A # 0 +0xC544 0x8E8D # 0 +0xC545 0x8E8B # 0 +0xC546 0x8F5F # 0 +0xC547 0x8FAF # 0 +0xC548 0x91BA # 0 +0xC549 0x942E # 0 +0xC54A 0x9433 # 0 +0xC54B 0x9435 # 0 +0xC54C 0x943A # 0 +0xC54D 0x9438 # 0 +0xC54E 0x9432 # 0 +0xC54F 0x942B # 0 +0xC550 0x95E2 # 0 +0xC551 0x9738 # 0 +0xC552 0x9739 # 0 +0xC553 0x9732 # 0 +0xC554 0x97FF # 0 +0xC555 0x9867 # 0 +0xC556 0x9865 # 0 +0xC557 0x9957 # 0 +0xC558 0x9A45 # 0 +0xC559 0x9A43 # 0 +0xC55A 0x9A40 # 0 +0xC55B 0x9A3E # 0 +0xC55C 0x9ACF # 0 +0xC55D 0x9B54 # 0 +0xC55E 0x9B51 # 0 +0xC55F 0x9C2D # 0 +0xC560 0x9C25 # 0 +0xC561 0x9DAF # 0 +0xC562 0x9DB4 # 0 +0xC563 0x9DC2 # 0 +0xC564 0x9DB8 # 0 +0xC565 0x9E9D # 0 +0xC566 0x9EEF # 0 +0xC567 0x9F19 # 0 +0xC568 0x9F5C # 0 +0xC569 0x9F66 # 0 +0xC56A 0x9F67 # 0 +0xC56B 0x513C # 0 +0xC56C 0x513B # 0 +0xC56D 0x56C8 # 0 +0xC56E 0x56CA # 0 +0xC56F 0x56C9 # 0 +0xC570 0x5B7F # 0 +0xC571 0x5DD4 # 0 +0xC572 0x5DD2 # 0 +0xC573 0x5F4E # 0 +0xC574 0x61FF # 0 +0xC575 0x6524 # 0 +0xC576 0x6B0A # 0 +0xC577 0x6B61 # 0 +0xC578 0x7051 # 0 +0xC579 0x7058 # 0 +0xC57A 0x7380 # 0 +0xC57B 0x74E4 # 0 +0xC57C 0x758A # 0 +0xC57D 0x766E # 0 +0xC57E 0x766C # 0 +0xC5A1 0x79B3 # 0 +0xC5A2 0x7C60 # 0 +0xC5A3 0x7C5F # 0 +0xC5A4 0x807E # 0 +0xC5A5 0x807D # 0 +0xC5A6 0x81DF # 0 +0xC5A7 0x8972 # 0 +0xC5A8 0x896F # 0 +0xC5A9 0x89FC # 0 +0xC5AA 0x8B80 # 0 +0xC5AB 0x8D16 # 0 +0xC5AC 0x8D17 # 0 +0xC5AD 0x8E91 # 0 +0xC5AE 0x8E93 # 0 +0xC5AF 0x8F61 # 0 +0xC5B0 0x9148 # 0 +0xC5B1 0x9444 # 0 +0xC5B2 0x9451 # 0 +0xC5B3 0x9452 # 0 +0xC5B4 0x973D # 0 +0xC5B5 0x973E # 0 +0xC5B6 0x97C3 # 0 +0xC5B7 0x97C1 # 0 +0xC5B8 0x986B # 0 +0xC5B9 0x9955 # 0 +0xC5BA 0x9A55 # 0 +0xC5BB 0x9A4D # 0 +0xC5BC 0x9AD2 # 0 +0xC5BD 0x9B1A # 0 +0xC5BE 0x9C49 # 0 +0xC5BF 0x9C31 # 0 +0xC5C0 0x9C3E # 0 +0xC5C1 0x9C3B # 0 +0xC5C2 0x9DD3 # 0 +0xC5C3 0x9DD7 # 0 +0xC5C4 0x9F34 # 0 +0xC5C5 0x9F6C # 0 +0xC5C6 0x9F6A # 0 +0xC5C7 0x9F94 # 0 +0xC5C8 0x56CC # 0 +0xC5C9 0x5DD6 # 0 +0xC5CA 0x6200 # 0 +0xC5CB 0x6523 # 0 +0xC5CC 0x652B # 0 +0xC5CD 0x652A # 0 +0xC5CE 0x66EC # 0 +0xC5CF 0x6B10 # 0 +0xC5D0 0x74DA # 0 +0xC5D1 0x7ACA # 0 +0xC5D2 0x7C64 # 0 +0xC5D3 0x7C63 # 0 +0xC5D4 0x7C65 # 0 +0xC5D5 0x7E93 # 0 +0xC5D6 0x7E96 # 0 +0xC5D7 0x7E94 # 0 +0xC5D8 0x81E2 # 0 +0xC5D9 0x8638 # 0 +0xC5DA 0x863F # 0 +0xC5DB 0x8831 # 0 +0xC5DC 0x8B8A # 0 +0xC5DD 0x9090 # 0 +0xC5DE 0x908F # 0 +0xC5DF 0x9463 # 0 +0xC5E0 0x9460 # 0 +0xC5E1 0x9464 # 0 +0xC5E2 0x9768 # 0 +0xC5E3 0x986F # 0 +0xC5E4 0x995C # 0 +0xC5E5 0x9A5A # 0 +0xC5E6 0x9A5B # 0 +0xC5E7 0x9A57 # 0 +0xC5E8 0x9AD3 # 0 +0xC5E9 0x9AD4 # 0 +0xC5EA 0x9AD1 # 0 +0xC5EB 0x9C54 # 0 +0xC5EC 0x9C57 # 0 +0xC5ED 0x9C56 # 0 +0xC5EE 0x9DE5 # 0 +0xC5EF 0x9E9F # 0 +0xC5F0 0x9EF4 # 0 +0xC5F1 0x56D1 # 0 +0xC5F2 0x58E9 # 0 +0xC5F3 0x652C # 0 +0xC5F4 0x705E # 0 +0xC5F5 0x7671 # 0 +0xC5F6 0x7672 # 0 +0xC5F7 0x77D7 # 0 +0xC5F8 0x7F50 # 0 +0xC5F9 0x7F88 # 0 +0xC5FA 0x8836 # 0 +0xC5FB 0x8839 # 0 +0xC5FC 0x8862 # 0 +0xC5FD 0x8B93 # 0 +0xC5FE 0x8B92 # 0 +0xC640 0x8B96 # 0 +0xC641 0x8277 # 0 +0xC642 0x8D1B # 0 +0xC643 0x91C0 # 0 +0xC644 0x946A # 0 +0xC645 0x9742 # 0 +0xC646 0x9748 # 0 +0xC647 0x9744 # 0 +0xC648 0x97C6 # 0 +0xC649 0x9870 # 0 +0xC64A 0x9A5F # 0 +0xC64B 0x9B22 # 0 +0xC64C 0x9B58 # 0 +0xC64D 0x9C5F # 0 +0xC64E 0x9DF9 # 0 +0xC64F 0x9DFA # 0 +0xC650 0x9E7C # 0 +0xC651 0x9E7D # 0 +0xC652 0x9F07 # 0 +0xC653 0x9F77 # 0 +0xC654 0x9F72 # 0 +0xC655 0x5EF3 # 0 +0xC656 0x6B16 # 0 +0xC657 0x7063 # 0 +0xC658 0x7C6C # 0 +0xC659 0x7C6E # 0 +0xC65A 0x883B # 0 +0xC65B 0x89C0 # 0 +0xC65C 0x8EA1 # 0 +0xC65D 0x91C1 # 0 +0xC65E 0x9472 # 0 +0xC65F 0x9470 # 0 +0xC660 0x9871 # 0 +0xC661 0x995E # 0 +0xC662 0x9AD6 # 0 +0xC663 0x9B23 # 0 +0xC664 0x9ECC # 0 +0xC665 0x7064 # 0 +0xC666 0x77DA # 0 +0xC667 0x8B9A # 0 +0xC668 0x9477 # 0 +0xC669 0x97C9 # 0 +0xC66A 0x9A62 # 0 +0xC66B 0x9A65 # 0 +0xC66C 0x7E9C # 0 +0xC66D 0x8B9C # 0 +0xC66E 0x8EAA # 0 +0xC66F 0x91C5 # 0 +0xC670 0x947D # 0 +0xC671 0x947E # 0 +0xC672 0x947C # 0 +0xC673 0x9C77 # 0 +0xC674 0x9C78 # 0 +0xC675 0x9EF7 # 0 +0xC676 0x8C54 # 0 +0xC677 0x947F # 0 +0xC678 0x9E1A # 0 +0xC679 0x7228 # 0 +0xC67A 0x9A6A # 0 +0xC67B 0x9B31 # 0 +0xC67C 0x9E1B # 0 +0xC67D 0x9E1E # 0 +0xC67E 0x7C72 # 0 +0xC6A1 0xF6B1 # 0 +0xC6A2 0xF6B2 # 0 +0xC6A3 0xF6B3 # 0 +0xC6A4 0xF6B4 # 0 +0xC6A5 0xF6B5 # 0 +0xC6A6 0xF6B6 # 0 +0xC6A7 0xF6B7 # 0 +0xC6A8 0xF6B8 # 0 +0xC6A9 0xF6B9 # 0 +0xC6AA 0xF6BA # 0 +0xC6AB 0xF6BB # 0 +0xC6AC 0xF6BC # 0 +0xC6AD 0xF6BD # 0 +0xC6AE 0xF6BE # 0 +0xC6AF 0xF6BF # 0 +0xC6B0 0xF6C0 # 0 +0xC6B1 0xF6C1 # 0 +0xC6B2 0xF6C2 # 0 +0xC6B3 0xF6C3 # 0 +0xC6B4 0xF6C4 # 0 +0xC6B5 0xF6C5 # 0 +0xC6B6 0xF6C6 # 0 +0xC6B7 0xF6C7 # 0 +0xC6B8 0xF6C8 # 0 +0xC6B9 0xF6C9 # 0 +0xC6BA 0xF6CA # 0 +0xC6BB 0xF6CB # 0 +0xC6BC 0xF6CC # 0 +0xC6BD 0xF6CD # 0 +0xC6BE 0xF6CE # 0 +0xC6BF 0xF6CF # 0 +0xC6C0 0xF6D0 # 0 +0xC6C1 0xF6D1 # 0 +0xC6C2 0xF6D2 # 0 +0xC6C3 0xF6D3 # 0 +0xC6C4 0xF6D4 # 0 +0xC6C5 0xF6D5 # 0 +0xC6C6 0xF6D6 # 0 +0xC6C7 0xF6D7 # 0 +0xC6C8 0xF6D8 # 0 +0xC6C9 0xF6D9 # 0 +0xC6CA 0xF6DA # 0 +0xC6CB 0xF6DB # 0 +0xC6CC 0xF6DC # 0 +0xC6CD 0xF6DD # 0 +0xC6CE 0xF6DE # 0 +0xC6CF 0xF6DF # 0 +0xC6D0 0xF6E0 # 0 +0xC6D1 0xF6E1 # 0 +0xC6D2 0xF6E2 # 0 +0xC6D3 0xF6E3 # 0 +0xC6D4 0xF6E4 # 0 +0xC6D5 0xF6E5 # 0 +0xC6D6 0xF6E6 # 0 +0xC6D7 0xF6E7 # 0 +0xC6D8 0xF6E8 # 0 +0xC6D9 0xF6E9 # 0 +0xC6DA 0xF6EA # 0 +0xC6DB 0xF6EB # 0 +0xC6DC 0xF6EC # 0 +0xC6DD 0xF6ED # 0 +0xC6DE 0xF6EE # 0 +0xC6DF 0xF6EF # 0 +0xC6E0 0xF6F0 # 0 +0xC6E1 0xF6F1 # 0 +0xC6E2 0xF6F2 # 0 +0xC6E3 0xF6F3 # 0 +0xC6E4 0xF6F4 # 0 +0xC6E5 0xF6F5 # 0 +0xC6E6 0xF6F6 # 0 +0xC6E7 0xF6F7 # 0 +0xC6E8 0xF6F8 # 0 +0xC6E9 0xF6F9 # 0 +0xC6EA 0xF6FA # 0 +0xC6EB 0xF6FB # 0 +0xC6EC 0xF6FC # 0 +0xC6ED 0xF6FD # 0 +0xC6EE 0xF6FE # 0 +0xC6EF 0xF6FF # 0 +0xC6F0 0xF700 # 0 +0xC6F1 0xF701 # 0 +0xC6F2 0xF702 # 0 +0xC6F3 0xF703 # 0 +0xC6F4 0xF704 # 0 +0xC6F5 0xF705 # 0 +0xC6F6 0xF706 # 0 +0xC6F7 0xF707 # 0 +0xC6F8 0xF708 # 0 +0xC6F9 0xF709 # 0 +0xC6FA 0xF70A # 0 +0xC6FB 0xF70B # 0 +0xC6FC 0xF70C # 0 +0xC6FD 0xF70D # 0 +0xC6FE 0xF70E # 0 +0xC740 0xF70F # 0 +0xC741 0xF710 # 0 +0xC742 0xF711 # 0 +0xC743 0xF712 # 0 +0xC744 0xF713 # 0 +0xC745 0xF714 # 0 +0xC746 0xF715 # 0 +0xC747 0xF716 # 0 +0xC748 0xF717 # 0 +0xC749 0xF718 # 0 +0xC74A 0xF719 # 0 +0xC74B 0xF71A # 0 +0xC74C 0xF71B # 0 +0xC74D 0xF71C # 0 +0xC74E 0xF71D # 0 +0xC74F 0xF71E # 0 +0xC750 0xF71F # 0 +0xC751 0xF720 # 0 +0xC752 0xF721 # 0 +0xC753 0xF722 # 0 +0xC754 0xF723 # 0 +0xC755 0xF724 # 0 +0xC756 0xF725 # 0 +0xC757 0xF726 # 0 +0xC758 0xF727 # 0 +0xC759 0xF728 # 0 +0xC75A 0xF729 # 0 +0xC75B 0xF72A # 0 +0xC75C 0xF72B # 0 +0xC75D 0xF72C # 0 +0xC75E 0xF72D # 0 +0xC75F 0xF72E # 0 +0xC760 0xF72F # 0 +0xC761 0xF730 # 0 +0xC762 0xF731 # 0 +0xC763 0xF732 # 0 +0xC764 0xF733 # 0 +0xC765 0xF734 # 0 +0xC766 0xF735 # 0 +0xC767 0xF736 # 0 +0xC768 0xF737 # 0 +0xC769 0xF738 # 0 +0xC76A 0xF739 # 0 +0xC76B 0xF73A # 0 +0xC76C 0xF73B # 0 +0xC76D 0xF73C # 0 +0xC76E 0xF73D # 0 +0xC76F 0xF73E # 0 +0xC770 0xF73F # 0 +0xC771 0xF740 # 0 +0xC772 0xF741 # 0 +0xC773 0xF742 # 0 +0xC774 0xF743 # 0 +0xC775 0xF744 # 0 +0xC776 0xF745 # 0 +0xC777 0xF746 # 0 +0xC778 0xF747 # 0 +0xC779 0xF748 # 0 +0xC77A 0xF749 # 0 +0xC77B 0xF74A # 0 +0xC77C 0xF74B # 0 +0xC77D 0xF74C # 0 +0xC77E 0xF74D # 0 +0xC7A1 0xF74E # 0 +0xC7A2 0xF74F # 0 +0xC7A3 0xF750 # 0 +0xC7A4 0xF751 # 0 +0xC7A5 0xF752 # 0 +0xC7A6 0xF753 # 0 +0xC7A7 0xF754 # 0 +0xC7A8 0xF755 # 0 +0xC7A9 0xF756 # 0 +0xC7AA 0xF757 # 0 +0xC7AB 0xF758 # 0 +0xC7AC 0xF759 # 0 +0xC7AD 0xF75A # 0 +0xC7AE 0xF75B # 0 +0xC7AF 0xF75C # 0 +0xC7B0 0xF75D # 0 +0xC7B1 0xF75E # 0 +0xC7B2 0xF75F # 0 +0xC7B3 0xF760 # 0 +0xC7B4 0xF761 # 0 +0xC7B5 0xF762 # 0 +0xC7B6 0xF763 # 0 +0xC7B7 0xF764 # 0 +0xC7B8 0xF765 # 0 +0xC7B9 0xF766 # 0 +0xC7BA 0xF767 # 0 +0xC7BB 0xF768 # 0 +0xC7BC 0xF769 # 0 +0xC7BD 0xF76A # 0 +0xC7BE 0xF76B # 0 +0xC7BF 0xF76C # 0 +0xC7C0 0xF76D # 0 +0xC7C1 0xF76E # 0 +0xC7C2 0xF76F # 0 +0xC7C3 0xF770 # 0 +0xC7C4 0xF771 # 0 +0xC7C5 0xF772 # 0 +0xC7C6 0xF773 # 0 +0xC7C7 0xF774 # 0 +0xC7C8 0xF775 # 0 +0xC7C9 0xF776 # 0 +0xC7CA 0xF777 # 0 +0xC7CB 0xF778 # 0 +0xC7CC 0xF779 # 0 +0xC7CD 0xF77A # 0 +0xC7CE 0xF77B # 0 +0xC7CF 0xF77C # 0 +0xC7D0 0xF77D # 0 +0xC7D1 0xF77E # 0 +0xC7D2 0xF77F # 0 +0xC7D3 0xF780 # 0 +0xC7D4 0xF781 # 0 +0xC7D5 0xF782 # 0 +0xC7D6 0xF783 # 0 +0xC7D7 0xF784 # 0 +0xC7D8 0xF785 # 0 +0xC7D9 0xF786 # 0 +0xC7DA 0xF787 # 0 +0xC7DB 0xF788 # 0 +0xC7DC 0xF789 # 0 +0xC7DD 0xF78A # 0 +0xC7DE 0xF78B # 0 +0xC7DF 0xF78C # 0 +0xC7E0 0xF78D # 0 +0xC7E1 0xF78E # 0 +0xC7E2 0xF78F # 0 +0xC7E3 0xF790 # 0 +0xC7E4 0xF791 # 0 +0xC7E5 0xF792 # 0 +0xC7E6 0xF793 # 0 +0xC7E7 0xF794 # 0 +0xC7E8 0xF795 # 0 +0xC7E9 0xF796 # 0 +0xC7EA 0xF797 # 0 +0xC7EB 0xF798 # 0 +0xC7EC 0xF799 # 0 +0xC7ED 0xF79A # 0 +0xC7EE 0xF79B # 0 +0xC7EF 0xF79C # 0 +0xC7F0 0xF79D # 0 +0xC7F1 0xF79E # 0 +0xC7F2 0xF79F # 0 +0xC7F3 0xF7A0 # 0 +0xC7F4 0xF7A1 # 0 +0xC7F5 0xF7A2 # 0 +0xC7F6 0xF7A3 # 0 +0xC7F7 0xF7A4 # 0 +0xC7F8 0xF7A5 # 0 +0xC7F9 0xF7A6 # 0 +0xC7FA 0xF7A7 # 0 +0xC7FB 0xF7A8 # 0 +0xC7FC 0xF7A9 # 0 +0xC7FD 0xF7AA # 0 +0xC7FE 0xF7AB # 0 +0xC840 0xF7AC # 0 +0xC841 0xF7AD # 0 +0xC842 0xF7AE # 0 +0xC843 0xF7AF # 0 +0xC844 0xF7B0 # 0 +0xC845 0xF7B1 # 0 +0xC846 0xF7B2 # 0 +0xC847 0xF7B3 # 0 +0xC848 0xF7B4 # 0 +0xC849 0xF7B5 # 0 +0xC84A 0xF7B6 # 0 +0xC84B 0xF7B7 # 0 +0xC84C 0xF7B8 # 0 +0xC84D 0xF7B9 # 0 +0xC84E 0xF7BA # 0 +0xC84F 0xF7BB # 0 +0xC850 0xF7BC # 0 +0xC851 0xF7BD # 0 +0xC852 0xF7BE # 0 +0xC853 0xF7BF # 0 +0xC854 0xF7C0 # 0 +0xC855 0xF7C1 # 0 +0xC856 0xF7C2 # 0 +0xC857 0xF7C3 # 0 +0xC858 0xF7C4 # 0 +0xC859 0xF7C5 # 0 +0xC85A 0xF7C6 # 0 +0xC85B 0xF7C7 # 0 +0xC85C 0xF7C8 # 0 +0xC85D 0xF7C9 # 0 +0xC85E 0xF7CA # 0 +0xC85F 0xF7CB # 0 +0xC860 0xF7CC # 0 +0xC861 0xF7CD # 0 +0xC862 0xF7CE # 0 +0xC863 0xF7CF # 0 +0xC864 0xF7D0 # 0 +0xC865 0xF7D1 # 0 +0xC866 0xF7D2 # 0 +0xC867 0xF7D3 # 0 +0xC868 0xF7D4 # 0 +0xC869 0xF7D5 # 0 +0xC86A 0xF7D6 # 0 +0xC86B 0xF7D7 # 0 +0xC86C 0xF7D8 # 0 +0xC86D 0xF7D9 # 0 +0xC86E 0xF7DA # 0 +0xC86F 0xF7DB # 0 +0xC870 0xF7DC # 0 +0xC871 0xF7DD # 0 +0xC872 0xF7DE # 0 +0xC873 0xF7DF # 0 +0xC874 0xF7E0 # 0 +0xC875 0xF7E1 # 0 +0xC876 0xF7E2 # 0 +0xC877 0xF7E3 # 0 +0xC878 0xF7E4 # 0 +0xC879 0xF7E5 # 0 +0xC87A 0xF7E6 # 0 +0xC87B 0xF7E7 # 0 +0xC87C 0xF7E8 # 0 +0xC87D 0xF7E9 # 0 +0xC87E 0xF7EA # 0 +0xC8A1 0xF7EB # 0 +0xC8A2 0xF7EC # 0 +0xC8A3 0xF7ED # 0 +0xC8A4 0xF7EE # 0 +0xC8A5 0xF7EF # 0 +0xC8A6 0xF7F0 # 0 +0xC8A7 0xF7F1 # 0 +0xC8A8 0xF7F2 # 0 +0xC8A9 0xF7F3 # 0 +0xC8AA 0xF7F4 # 0 +0xC8AB 0xF7F5 # 0 +0xC8AC 0xF7F6 # 0 +0xC8AD 0xF7F7 # 0 +0xC8AE 0xF7F8 # 0 +0xC8AF 0xF7F9 # 0 +0xC8B0 0xF7FA # 0 +0xC8B1 0xF7FB # 0 +0xC8B2 0xF7FC # 0 +0xC8B3 0xF7FD # 0 +0xC8B4 0xF7FE # 0 +0xC8B5 0xF7FF # 0 +0xC8B6 0xF800 # 0 +0xC8B7 0xF801 # 0 +0xC8B8 0xF802 # 0 +0xC8B9 0xF803 # 0 +0xC8BA 0xF804 # 0 +0xC8BB 0xF805 # 0 +0xC8BC 0xF806 # 0 +0xC8BD 0xF807 # 0 +0xC8BE 0xF808 # 0 +0xC8BF 0xF809 # 0 +0xC8C0 0xF80A # 0 +0xC8C1 0xF80B # 0 +0xC8C2 0xF80C # 0 +0xC8C3 0xF80D # 0 +0xC8C4 0xF80E # 0 +0xC8C5 0xF80F # 0 +0xC8C6 0xF810 # 0 +0xC8C7 0xF811 # 0 +0xC8C8 0xF812 # 0 +0xC8C9 0xF813 # 0 +0xC8CA 0xF814 # 0 +0xC8CB 0xF815 # 0 +0xC8CC 0xF816 # 0 +0xC8CD 0xF817 # 0 +0xC8CE 0xF818 # 0 +0xC8CF 0xF819 # 0 +0xC8D0 0xF81A # 0 +0xC8D1 0xF81B # 0 +0xC8D2 0xF81C # 0 +0xC8D3 0xF81D # 0 +0xC8D4 0xF81E # 0 +0xC8D5 0xF81F # 0 +0xC8D6 0xF820 # 0 +0xC8D7 0xF821 # 0 +0xC8D8 0xF822 # 0 +0xC8D9 0xF823 # 0 +0xC8DA 0xF824 # 0 +0xC8DB 0xF825 # 0 +0xC8DC 0xF826 # 0 +0xC8DD 0xF827 # 0 +0xC8DE 0xF828 # 0 +0xC8DF 0xF829 # 0 +0xC8E0 0xF82A # 0 +0xC8E1 0xF82B # 0 +0xC8E2 0xF82C # 0 +0xC8E3 0xF82D # 0 +0xC8E4 0xF82E # 0 +0xC8E5 0xF82F # 0 +0xC8E6 0xF830 # 0 +0xC8E7 0xF831 # 0 +0xC8E8 0xF832 # 0 +0xC8E9 0xF833 # 0 +0xC8EA 0xF834 # 0 +0xC8EB 0xF835 # 0 +0xC8EC 0xF836 # 0 +0xC8ED 0xF837 # 0 +0xC8EE 0xF838 # 0 +0xC8EF 0xF839 # 0 +0xC8F0 0xF83A # 0 +0xC8F1 0xF83B # 0 +0xC8F2 0xF83C # 0 +0xC8F3 0xF83D # 0 +0xC8F4 0xF83E # 0 +0xC8F5 0xF83F # 0 +0xC8F6 0xF840 # 0 +0xC8F7 0xF841 # 0 +0xC8F8 0xF842 # 0 +0xC8F9 0xF843 # 0 +0xC8FA 0xF844 # 0 +0xC8FB 0xF845 # 0 +0xC8FC 0xF846 # 0 +0xC8FD 0xF847 # 0 +0xC8FE 0xF848 # 0 +0xC940 0x4E42 # 0 +0xC941 0x4E5C # 0 +0xC942 0x51F5 # 0 +0xC943 0x531A # 0 +0xC944 0x5382 # 0 +0xC945 0x4E07 # 0 +0xC946 0x4E0C # 0 +0xC947 0x4E47 # 0 +0xC948 0x4E8D # 0 +0xC949 0x56D7 # 0 +0xC94A 0xFA0C # 0 +0xC94B 0x5C6E # 0 +0xC94C 0x5F73 # 0 +0xC94D 0x4E0F # 0 +0xC94E 0x5187 # 0 +0xC94F 0x4E0E # 0 +0xC950 0x4E2E # 0 +0xC951 0x4E93 # 0 +0xC952 0x4EC2 # 0 +0xC953 0x4EC9 # 0 +0xC954 0x4EC8 # 0 +0xC955 0x5198 # 0 +0xC956 0x52FC # 0 +0xC957 0x536C # 0 +0xC958 0x53B9 # 0 +0xC959 0x5720 # 0 +0xC95A 0x5903 # 0 +0xC95B 0x592C # 0 +0xC95C 0x5C10 # 0 +0xC95D 0x5DFF # 0 +0xC95E 0x65E1 # 0 +0xC95F 0x6BB3 # 0 +0xC960 0x6BCC # 0 +0xC961 0x6C14 # 0 +0xC962 0x723F # 0 +0xC963 0x4E31 # 0 +0xC964 0x4E3C # 0 +0xC965 0x4EE8 # 0 +0xC966 0x4EDC # 0 +0xC967 0x4EE9 # 0 +0xC968 0x4EE1 # 0 +0xC969 0x4EDD # 0 +0xC96A 0x4EDA # 0 +0xC96B 0x520C # 0 +0xC96C 0x531C # 0 +0xC96D 0x534C # 0 +0xC96E 0x5722 # 0 +0xC96F 0x5723 # 0 +0xC970 0x5917 # 0 +0xC971 0x592F # 0 +0xC972 0x5B81 # 0 +0xC973 0x5B84 # 0 +0xC974 0x5C12 # 0 +0xC975 0x5C3B # 0 +0xC976 0x5C74 # 0 +0xC977 0x5C73 # 0 +0xC978 0x5E04 # 0 +0xC979 0x5E80 # 0 +0xC97A 0x5E82 # 0 +0xC97B 0x5FC9 # 0 +0xC97C 0x6209 # 0 +0xC97D 0x6250 # 0 +0xC97E 0x6C15 # 0 +0xC9A1 0x6C36 # 0 +0xC9A2 0x6C43 # 0 +0xC9A3 0x6C3F # 0 +0xC9A4 0x6C3B # 0 +0xC9A5 0x72AE # 0 +0xC9A6 0x72B0 # 0 +0xC9A7 0x738A # 0 +0xC9A8 0x79B8 # 0 +0xC9A9 0x808A # 0 +0xC9AA 0x961E # 0 +0xC9AB 0x4F0E # 0 +0xC9AC 0x4F18 # 0 +0xC9AD 0x4F2C # 0 +0xC9AE 0x4EF5 # 0 +0xC9AF 0x4F14 # 0 +0xC9B0 0x4EF1 # 0 +0xC9B1 0x4F00 # 0 +0xC9B2 0x4EF7 # 0 +0xC9B3 0x4F08 # 0 +0xC9B4 0x4F1D # 0 +0xC9B5 0x4F02 # 0 +0xC9B6 0x4F05 # 0 +0xC9B7 0x4F22 # 0 +0xC9B8 0x4F13 # 0 +0xC9B9 0x4F04 # 0 +0xC9BA 0x4EF4 # 0 +0xC9BB 0x4F12 # 0 +0xC9BC 0x51B1 # 0 +0xC9BD 0x5213 # 0 +0xC9BE 0x5209 # 0 +0xC9BF 0x5210 # 0 +0xC9C0 0x52A6 # 0 +0xC9C1 0x5322 # 0 +0xC9C2 0x531F # 0 +0xC9C3 0x534D # 0 +0xC9C4 0x538A # 0 +0xC9C5 0x5407 # 0 +0xC9C6 0x56E1 # 0 +0xC9C7 0x56DF # 0 +0xC9C8 0x572E # 0 +0xC9C9 0x572A # 0 +0xC9CA 0x5734 # 0 +0xC9CB 0x593C # 0 +0xC9CC 0x5980 # 0 +0xC9CD 0x597C # 0 +0xC9CE 0x5985 # 0 +0xC9CF 0x597B # 0 +0xC9D0 0x597E # 0 +0xC9D1 0x5977 # 0 +0xC9D2 0x597F # 0 +0xC9D3 0x5B56 # 0 +0xC9D4 0x5C15 # 0 +0xC9D5 0x5C25 # 0 +0xC9D6 0x5C7C # 0 +0xC9D7 0x5C7A # 0 +0xC9D8 0x5C7B # 0 +0xC9D9 0x5C7E # 0 +0xC9DA 0x5DDF # 0 +0xC9DB 0x5E75 # 0 +0xC9DC 0x5E84 # 0 +0xC9DD 0x5F02 # 0 +0xC9DE 0x5F1A # 0 +0xC9DF 0x5F74 # 0 +0xC9E0 0x5FD5 # 0 +0xC9E1 0x5FD4 # 0 +0xC9E2 0x5FCF # 0 +0xC9E3 0x625C # 0 +0xC9E4 0x625E # 0 +0xC9E5 0x6264 # 0 +0xC9E6 0x6261 # 0 +0xC9E7 0x6266 # 0 +0xC9E8 0x6262 # 0 +0xC9E9 0x6259 # 0 +0xC9EA 0x6260 # 0 +0xC9EB 0x625A # 0 +0xC9EC 0x6265 # 0 +0xC9ED 0x65EF # 0 +0xC9EE 0x65EE # 0 +0xC9EF 0x673E # 0 +0xC9F0 0x6739 # 0 +0xC9F1 0x6738 # 0 +0xC9F2 0x673B # 0 +0xC9F3 0x673A # 0 +0xC9F4 0x673F # 0 +0xC9F5 0x673C # 0 +0xC9F6 0x6733 # 0 +0xC9F7 0x6C18 # 0 +0xC9F8 0x6C46 # 0 +0xC9F9 0x6C52 # 0 +0xC9FA 0x6C5C # 0 +0xC9FB 0x6C4F # 0 +0xC9FC 0x6C4A # 0 +0xC9FD 0x6C54 # 0 +0xC9FE 0x6C4B # 0 +0xCA40 0x6C4C # 0 +0xCA41 0x7071 # 0 +0xCA42 0x725E # 0 +0xCA43 0x72B4 # 0 +0xCA44 0x72B5 # 0 +0xCA45 0x738E # 0 +0xCA46 0x752A # 0 +0xCA47 0x767F # 0 +0xCA48 0x7A75 # 0 +0xCA49 0x7F51 # 0 +0xCA4A 0x8278 # 0 +0xCA4B 0x827C # 0 +0xCA4C 0x8280 # 0 +0xCA4D 0x827D # 0 +0xCA4E 0x827F # 0 +0xCA4F 0x864D # 0 +0xCA50 0x897E # 0 +0xCA51 0x9099 # 0 +0xCA52 0x9097 # 0 +0xCA53 0x9098 # 0 +0xCA54 0x909B # 0 +0xCA55 0x9094 # 0 +0xCA56 0x9622 # 0 +0xCA57 0x9624 # 0 +0xCA58 0x9620 # 0 +0xCA59 0x9623 # 0 +0xCA5A 0x4F56 # 0 +0xCA5B 0x4F3B # 0 +0xCA5C 0x4F62 # 0 +0xCA5D 0x4F49 # 0 +0xCA5E 0x4F53 # 0 +0xCA5F 0x4F64 # 0 +0xCA60 0x4F3E # 0 +0xCA61 0x4F67 # 0 +0xCA62 0x4F52 # 0 +0xCA63 0x4F5F # 0 +0xCA64 0x4F41 # 0 +0xCA65 0x4F58 # 0 +0xCA66 0x4F2D # 0 +0xCA67 0x4F33 # 0 +0xCA68 0x4F3F # 0 +0xCA69 0x4F61 # 0 +0xCA6A 0x518F # 0 +0xCA6B 0x51B9 # 0 +0xCA6C 0x521C # 0 +0xCA6D 0x521E # 0 +0xCA6E 0x5221 # 0 +0xCA6F 0x52AD # 0 +0xCA70 0x52AE # 0 +0xCA71 0x5309 # 0 +0xCA72 0x5363 # 0 +0xCA73 0x5372 # 0 +0xCA74 0x538E # 0 +0xCA75 0x538F # 0 +0xCA76 0x5430 # 0 +0xCA77 0x5437 # 0 +0xCA78 0x542A # 0 +0xCA79 0x5454 # 0 +0xCA7A 0x5445 # 0 +0xCA7B 0x5419 # 0 +0xCA7C 0x541C # 0 +0xCA7D 0x5425 # 0 +0xCA7E 0x5418 # 0 +0xCAA1 0x543D # 0 +0xCAA2 0x544F # 0 +0xCAA3 0x5441 # 0 +0xCAA4 0x5428 # 0 +0xCAA5 0x5424 # 0 +0xCAA6 0x5447 # 0 +0xCAA7 0x56EE # 0 +0xCAA8 0x56E7 # 0 +0xCAA9 0x56E5 # 0 +0xCAAA 0x5741 # 0 +0xCAAB 0x5745 # 0 +0xCAAC 0x574C # 0 +0xCAAD 0x5749 # 0 +0xCAAE 0x574B # 0 +0xCAAF 0x5752 # 0 +0xCAB0 0x5906 # 0 +0xCAB1 0x5940 # 0 +0xCAB2 0x59A6 # 0 +0xCAB3 0x5998 # 0 +0xCAB4 0x59A0 # 0 +0xCAB5 0x5997 # 0 +0xCAB6 0x598E # 0 +0xCAB7 0x59A2 # 0 +0xCAB8 0x5990 # 0 +0xCAB9 0x598F # 0 +0xCABA 0x59A7 # 0 +0xCABB 0x59A1 # 0 +0xCABC 0x5B8E # 0 +0xCABD 0x5B92 # 0 +0xCABE 0x5C28 # 0 +0xCABF 0x5C2A # 0 +0xCAC0 0x5C8D # 0 +0xCAC1 0x5C8F # 0 +0xCAC2 0x5C88 # 0 +0xCAC3 0x5C8B # 0 +0xCAC4 0x5C89 # 0 +0xCAC5 0x5C92 # 0 +0xCAC6 0x5C8A # 0 +0xCAC7 0x5C86 # 0 +0xCAC8 0x5C93 # 0 +0xCAC9 0x5C95 # 0 +0xCACA 0x5DE0 # 0 +0xCACB 0x5E0A # 0 +0xCACC 0x5E0E # 0 +0xCACD 0x5E8B # 0 +0xCACE 0x5E89 # 0 +0xCACF 0x5E8C # 0 +0xCAD0 0x5E88 # 0 +0xCAD1 0x5E8D # 0 +0xCAD2 0x5F05 # 0 +0xCAD3 0x5F1D # 0 +0xCAD4 0x5F78 # 0 +0xCAD5 0x5F76 # 0 +0xCAD6 0x5FD2 # 0 +0xCAD7 0x5FD1 # 0 +0xCAD8 0x5FD0 # 0 +0xCAD9 0x5FED # 0 +0xCADA 0x5FE8 # 0 +0xCADB 0x5FEE # 0 +0xCADC 0x5FF3 # 0 +0xCADD 0x5FE1 # 0 +0xCADE 0x5FE4 # 0 +0xCADF 0x5FE3 # 0 +0xCAE0 0x5FFA # 0 +0xCAE1 0x5FEF # 0 +0xCAE2 0x5FF7 # 0 +0xCAE3 0x5FFB # 0 +0xCAE4 0x6000 # 0 +0xCAE5 0x5FF4 # 0 +0xCAE6 0x623A # 0 +0xCAE7 0x6283 # 0 +0xCAE8 0x628C # 0 +0xCAE9 0x628E # 0 +0xCAEA 0x628F # 0 +0xCAEB 0x6294 # 0 +0xCAEC 0x6287 # 0 +0xCAED 0x6271 # 0 +0xCAEE 0x627B # 0 +0xCAEF 0x627A # 0 +0xCAF0 0x6270 # 0 +0xCAF1 0x6281 # 0 +0xCAF2 0x6288 # 0 +0xCAF3 0x6277 # 0 +0xCAF4 0x627D # 0 +0xCAF5 0x6272 # 0 +0xCAF6 0x6274 # 0 +0xCAF7 0x6537 # 0 +0xCAF8 0x65F0 # 0 +0xCAF9 0x65F4 # 0 +0xCAFA 0x65F3 # 0 +0xCAFB 0x65F2 # 0 +0xCAFC 0x65F5 # 0 +0xCAFD 0x6745 # 0 +0xCAFE 0x6747 # 0 +0xCB40 0x6759 # 0 +0xCB41 0x6755 # 0 +0xCB42 0x674C # 0 +0xCB43 0x6748 # 0 +0xCB44 0x675D # 0 +0xCB45 0x674D # 0 +0xCB46 0x675A # 0 +0xCB47 0x674B # 0 +0xCB48 0x6BD0 # 0 +0xCB49 0x6C19 # 0 +0xCB4A 0x6C1A # 0 +0xCB4B 0x6C78 # 0 +0xCB4C 0x6C67 # 0 +0xCB4D 0x6C6B # 0 +0xCB4E 0x6C84 # 0 +0xCB4F 0x6C8B # 0 +0xCB50 0x6C8F # 0 +0xCB51 0x6C71 # 0 +0xCB52 0x6C6F # 0 +0xCB53 0x6C69 # 0 +0xCB54 0x6C9A # 0 +0xCB55 0x6C6D # 0 +0xCB56 0x6C87 # 0 +0xCB57 0x6C95 # 0 +0xCB58 0x6C9C # 0 +0xCB59 0x6C66 # 0 +0xCB5A 0x6C73 # 0 +0xCB5B 0x6C65 # 0 +0xCB5C 0x6C7B # 0 +0xCB5D 0x6C8E # 0 +0xCB5E 0x7074 # 0 +0xCB5F 0x707A # 0 +0xCB60 0x7263 # 0 +0xCB61 0x72BF # 0 +0xCB62 0x72BD # 0 +0xCB63 0x72C3 # 0 +0xCB64 0x72C6 # 0 +0xCB65 0x72C1 # 0 +0xCB66 0x72BA # 0 +0xCB67 0x72C5 # 0 +0xCB68 0x7395 # 0 +0xCB69 0x7397 # 0 +0xCB6A 0x7393 # 0 +0xCB6B 0x7394 # 0 +0xCB6C 0x7392 # 0 +0xCB6D 0x753A # 0 +0xCB6E 0x7539 # 0 +0xCB6F 0x7594 # 0 +0xCB70 0x7595 # 0 +0xCB71 0x7681 # 0 +0xCB72 0x793D # 0 +0xCB73 0x8034 # 0 +0xCB74 0x8095 # 0 +0xCB75 0x8099 # 0 +0xCB76 0x8090 # 0 +0xCB77 0x8092 # 0 +0xCB78 0x809C # 0 +0xCB79 0x8290 # 0 +0xCB7A 0x828F # 0 +0xCB7B 0x8285 # 0 +0xCB7C 0x828E # 0 +0xCB7D 0x8291 # 0 +0xCB7E 0x8293 # 0 +0xCBA1 0x828A # 0 +0xCBA2 0x8283 # 0 +0xCBA3 0x8284 # 0 +0xCBA4 0x8C78 # 0 +0xCBA5 0x8FC9 # 0 +0xCBA6 0x8FBF # 0 +0xCBA7 0x909F # 0 +0xCBA8 0x90A1 # 0 +0xCBA9 0x90A5 # 0 +0xCBAA 0x909E # 0 +0xCBAB 0x90A7 # 0 +0xCBAC 0x90A0 # 0 +0xCBAD 0x9630 # 0 +0xCBAE 0x9628 # 0 +0xCBAF 0x962F # 0 +0xCBB0 0x962D # 0 +0xCBB1 0x4E33 # 0 +0xCBB2 0x4F98 # 0 +0xCBB3 0x4F7C # 0 +0xCBB4 0x4F85 # 0 +0xCBB5 0x4F7D # 0 +0xCBB6 0x4F80 # 0 +0xCBB7 0x4F87 # 0 +0xCBB8 0x4F76 # 0 +0xCBB9 0x4F74 # 0 +0xCBBA 0x4F89 # 0 +0xCBBB 0x4F84 # 0 +0xCBBC 0x4F77 # 0 +0xCBBD 0x4F4C # 0 +0xCBBE 0x4F97 # 0 +0xCBBF 0x4F6A # 0 +0xCBC0 0x4F9A # 0 +0xCBC1 0x4F79 # 0 +0xCBC2 0x4F81 # 0 +0xCBC3 0x4F78 # 0 +0xCBC4 0x4F90 # 0 +0xCBC5 0x4F9C # 0 +0xCBC6 0x4F94 # 0 +0xCBC7 0x4F9E # 0 +0xCBC8 0x4F92 # 0 +0xCBC9 0x4F82 # 0 +0xCBCA 0x4F95 # 0 +0xCBCB 0x4F6B # 0 +0xCBCC 0x4F6E # 0 +0xCBCD 0x519E # 0 +0xCBCE 0x51BC # 0 +0xCBCF 0x51BE # 0 +0xCBD0 0x5235 # 0 +0xCBD1 0x5232 # 0 +0xCBD2 0x5233 # 0 +0xCBD3 0x5246 # 0 +0xCBD4 0x5231 # 0 +0xCBD5 0x52BC # 0 +0xCBD6 0x530A # 0 +0xCBD7 0x530B # 0 +0xCBD8 0x533C # 0 +0xCBD9 0x5392 # 0 +0xCBDA 0x5394 # 0 +0xCBDB 0x5487 # 0 +0xCBDC 0x547F # 0 +0xCBDD 0x5481 # 0 +0xCBDE 0x5491 # 0 +0xCBDF 0x5482 # 0 +0xCBE0 0x5488 # 0 +0xCBE1 0x546B # 0 +0xCBE2 0x547A # 0 +0xCBE3 0x547E # 0 +0xCBE4 0x5465 # 0 +0xCBE5 0x546C # 0 +0xCBE6 0x5474 # 0 +0xCBE7 0x5466 # 0 +0xCBE8 0x548D # 0 +0xCBE9 0x546F # 0 +0xCBEA 0x5461 # 0 +0xCBEB 0x5460 # 0 +0xCBEC 0x5498 # 0 +0xCBED 0x5463 # 0 +0xCBEE 0x5467 # 0 +0xCBEF 0x5464 # 0 +0xCBF0 0x56F7 # 0 +0xCBF1 0x56F9 # 0 +0xCBF2 0x576F # 0 +0xCBF3 0x5772 # 0 +0xCBF4 0x576D # 0 +0xCBF5 0x576B # 0 +0xCBF6 0x5771 # 0 +0xCBF7 0x5770 # 0 +0xCBF8 0x5776 # 0 +0xCBF9 0x5780 # 0 +0xCBFA 0x5775 # 0 +0xCBFB 0x577B # 0 +0xCBFC 0x5773 # 0 +0xCBFD 0x5774 # 0 +0xCBFE 0x5762 # 0 +0xCC40 0x5768 # 0 +0xCC41 0x577D # 0 +0xCC42 0x590C # 0 +0xCC43 0x5945 # 0 +0xCC44 0x59B5 # 0 +0xCC45 0x59BA # 0 +0xCC46 0x59CF # 0 +0xCC47 0x59CE # 0 +0xCC48 0x59B2 # 0 +0xCC49 0x59CC # 0 +0xCC4A 0x59C1 # 0 +0xCC4B 0x59B6 # 0 +0xCC4C 0x59BC # 0 +0xCC4D 0x59C3 # 0 +0xCC4E 0x59D6 # 0 +0xCC4F 0x59B1 # 0 +0xCC50 0x59BD # 0 +0xCC51 0x59C0 # 0 +0xCC52 0x59C8 # 0 +0xCC53 0x59B4 # 0 +0xCC54 0x59C7 # 0 +0xCC55 0x5B62 # 0 +0xCC56 0x5B65 # 0 +0xCC57 0x5B93 # 0 +0xCC58 0x5B95 # 0 +0xCC59 0x5C44 # 0 +0xCC5A 0x5C47 # 0 +0xCC5B 0x5CAE # 0 +0xCC5C 0x5CA4 # 0 +0xCC5D 0x5CA0 # 0 +0xCC5E 0x5CB5 # 0 +0xCC5F 0x5CAF # 0 +0xCC60 0x5CA8 # 0 +0xCC61 0x5CAC # 0 +0xCC62 0x5C9F # 0 +0xCC63 0x5CA3 # 0 +0xCC64 0x5CAD # 0 +0xCC65 0x5CA2 # 0 +0xCC66 0x5CAA # 0 +0xCC67 0x5CA7 # 0 +0xCC68 0x5C9D # 0 +0xCC69 0x5CA5 # 0 +0xCC6A 0x5CB6 # 0 +0xCC6B 0x5CB0 # 0 +0xCC6C 0x5CA6 # 0 +0xCC6D 0x5E17 # 0 +0xCC6E 0x5E14 # 0 +0xCC6F 0x5E19 # 0 +0xCC70 0x5F28 # 0 +0xCC71 0x5F22 # 0 +0xCC72 0x5F23 # 0 +0xCC73 0x5F24 # 0 +0xCC74 0x5F54 # 0 +0xCC75 0x5F82 # 0 +0xCC76 0x5F7E # 0 +0xCC77 0x5F7D # 0 +0xCC78 0x5FDE # 0 +0xCC79 0x5FE5 # 0 +0xCC7A 0x602D # 0 +0xCC7B 0x6026 # 0 +0xCC7C 0x6019 # 0 +0xCC7D 0x6032 # 0 +0xCC7E 0x600B # 0 +0xCCA1 0x6034 # 0 +0xCCA2 0x600A # 0 +0xCCA3 0x6017 # 0 +0xCCA4 0x6033 # 0 +0xCCA5 0x601A # 0 +0xCCA6 0x601E # 0 +0xCCA7 0x602C # 0 +0xCCA8 0x6022 # 0 +0xCCA9 0x600D # 0 +0xCCAA 0x6010 # 0 +0xCCAB 0x602E # 0 +0xCCAC 0x6013 # 0 +0xCCAD 0x6011 # 0 +0xCCAE 0x600C # 0 +0xCCAF 0x6009 # 0 +0xCCB0 0x601C # 0 +0xCCB1 0x6214 # 0 +0xCCB2 0x623D # 0 +0xCCB3 0x62AD # 0 +0xCCB4 0x62B4 # 0 +0xCCB5 0x62D1 # 0 +0xCCB6 0x62BE # 0 +0xCCB7 0x62AA # 0 +0xCCB8 0x62B6 # 0 +0xCCB9 0x62CA # 0 +0xCCBA 0x62AE # 0 +0xCCBB 0x62B3 # 0 +0xCCBC 0x62AF # 0 +0xCCBD 0x62BB # 0 +0xCCBE 0x62A9 # 0 +0xCCBF 0x62B0 # 0 +0xCCC0 0x62B8 # 0 +0xCCC1 0x653D # 0 +0xCCC2 0x65A8 # 0 +0xCCC3 0x65BB # 0 +0xCCC4 0x6609 # 0 +0xCCC5 0x65FC # 0 +0xCCC6 0x6604 # 0 +0xCCC7 0x6612 # 0 +0xCCC8 0x6608 # 0 +0xCCC9 0x65FB # 0 +0xCCCA 0x6603 # 0 +0xCCCB 0x660B # 0 +0xCCCC 0x660D # 0 +0xCCCD 0x6605 # 0 +0xCCCE 0x65FD # 0 +0xCCCF 0x6611 # 0 +0xCCD0 0x6610 # 0 +0xCCD1 0x66F6 # 0 +0xCCD2 0x670A # 0 +0xCCD3 0x6785 # 0 +0xCCD4 0x676C # 0 +0xCCD5 0x678E # 0 +0xCCD6 0x6792 # 0 +0xCCD7 0x6776 # 0 +0xCCD8 0x677B # 0 +0xCCD9 0x6798 # 0 +0xCCDA 0x6786 # 0 +0xCCDB 0x6784 # 0 +0xCCDC 0x6774 # 0 +0xCCDD 0x678D # 0 +0xCCDE 0x678C # 0 +0xCCDF 0x677A # 0 +0xCCE0 0x679F # 0 +0xCCE1 0x6791 # 0 +0xCCE2 0x6799 # 0 +0xCCE3 0x6783 # 0 +0xCCE4 0x677D # 0 +0xCCE5 0x6781 # 0 +0xCCE6 0x6778 # 0 +0xCCE7 0x6779 # 0 +0xCCE8 0x6794 # 0 +0xCCE9 0x6B25 # 0 +0xCCEA 0x6B80 # 0 +0xCCEB 0x6B7E # 0 +0xCCEC 0x6BDE # 0 +0xCCED 0x6C1D # 0 +0xCCEE 0x6C93 # 0 +0xCCEF 0x6CEC # 0 +0xCCF0 0x6CEB # 0 +0xCCF1 0x6CEE # 0 +0xCCF2 0x6CD9 # 0 +0xCCF3 0x6CB6 # 0 +0xCCF4 0x6CD4 # 0 +0xCCF5 0x6CAD # 0 +0xCCF6 0x6CE7 # 0 +0xCCF7 0x6CB7 # 0 +0xCCF8 0x6CD0 # 0 +0xCCF9 0x6CC2 # 0 +0xCCFA 0x6CBA # 0 +0xCCFB 0x6CC3 # 0 +0xCCFC 0x6CC6 # 0 +0xCCFD 0x6CED # 0 +0xCCFE 0x6CF2 # 0 +0xCD40 0x6CD2 # 0 +0xCD41 0x6CDD # 0 +0xCD42 0x6CB4 # 0 +0xCD43 0x6C8A # 0 +0xCD44 0x6C9D # 0 +0xCD45 0x6C80 # 0 +0xCD46 0x6CDE # 0 +0xCD47 0x6CC0 # 0 +0xCD48 0x6D30 # 0 +0xCD49 0x6CCD # 0 +0xCD4A 0x6CC7 # 0 +0xCD4B 0x6CB0 # 0 +0xCD4C 0x6CF9 # 0 +0xCD4D 0x6CCF # 0 +0xCD4E 0x6CE9 # 0 +0xCD4F 0x6CD1 # 0 +0xCD50 0x7094 # 0 +0xCD51 0x7098 # 0 +0xCD52 0x7085 # 0 +0xCD53 0x7093 # 0 +0xCD54 0x7086 # 0 +0xCD55 0x7084 # 0 +0xCD56 0x7091 # 0 +0xCD57 0x7096 # 0 +0xCD58 0x7082 # 0 +0xCD59 0x709A # 0 +0xCD5A 0x7083 # 0 +0xCD5B 0x726A # 0 +0xCD5C 0x72D6 # 0 +0xCD5D 0x72CB # 0 +0xCD5E 0x72D8 # 0 +0xCD5F 0x72C9 # 0 +0xCD60 0x72DC # 0 +0xCD61 0x72D2 # 0 +0xCD62 0x72D4 # 0 +0xCD63 0x72DA # 0 +0xCD64 0x72CC # 0 +0xCD65 0x72D1 # 0 +0xCD66 0x73A4 # 0 +0xCD67 0x73A1 # 0 +0xCD68 0x73AD # 0 +0xCD69 0x73A6 # 0 +0xCD6A 0x73A2 # 0 +0xCD6B 0x73A0 # 0 +0xCD6C 0x73AC # 0 +0xCD6D 0x739D # 0 +0xCD6E 0x74DD # 0 +0xCD6F 0x74E8 # 0 +0xCD70 0x753F # 0 +0xCD71 0x7540 # 0 +0xCD72 0x753E # 0 +0xCD73 0x758C # 0 +0xCD74 0x7598 # 0 +0xCD75 0x76AF # 0 +0xCD76 0x76F3 # 0 +0xCD77 0x76F1 # 0 +0xCD78 0x76F0 # 0 +0xCD79 0x76F5 # 0 +0xCD7A 0x77F8 # 0 +0xCD7B 0x77FC # 0 +0xCD7C 0x77F9 # 0 +0xCD7D 0x77FB # 0 +0xCD7E 0x77FA # 0 +0xCDA1 0x77F7 # 0 +0xCDA2 0x7942 # 0 +0xCDA3 0x793F # 0 +0xCDA4 0x79C5 # 0 +0xCDA5 0x7A78 # 0 +0xCDA6 0x7A7B # 0 +0xCDA7 0x7AFB # 0 +0xCDA8 0x7C75 # 0 +0xCDA9 0x7CFD # 0 +0xCDAA 0x8035 # 0 +0xCDAB 0x808F # 0 +0xCDAC 0x80AE # 0 +0xCDAD 0x80A3 # 0 +0xCDAE 0x80B8 # 0 +0xCDAF 0x80B5 # 0 +0xCDB0 0x80AD # 0 +0xCDB1 0x8220 # 0 +0xCDB2 0x82A0 # 0 +0xCDB3 0x82C0 # 0 +0xCDB4 0x82AB # 0 +0xCDB5 0x829A # 0 +0xCDB6 0x8298 # 0 +0xCDB7 0x829B # 0 +0xCDB8 0x82B5 # 0 +0xCDB9 0x82A7 # 0 +0xCDBA 0x82AE # 0 +0xCDBB 0x82BC # 0 +0xCDBC 0x829E # 0 +0xCDBD 0x82BA # 0 +0xCDBE 0x82B4 # 0 +0xCDBF 0x82A8 # 0 +0xCDC0 0x82A1 # 0 +0xCDC1 0x82A9 # 0 +0xCDC2 0x82C2 # 0 +0xCDC3 0x82A4 # 0 +0xCDC4 0x82C3 # 0 +0xCDC5 0x82B6 # 0 +0xCDC6 0x82A2 # 0 +0xCDC7 0x8670 # 0 +0xCDC8 0x866F # 0 +0xCDC9 0x866D # 0 +0xCDCA 0x866E # 0 +0xCDCB 0x8C56 # 0 +0xCDCC 0x8FD2 # 0 +0xCDCD 0x8FCB # 0 +0xCDCE 0x8FD3 # 0 +0xCDCF 0x8FCD # 0 +0xCDD0 0x8FD6 # 0 +0xCDD1 0x8FD5 # 0 +0xCDD2 0x8FD7 # 0 +0xCDD3 0x90B2 # 0 +0xCDD4 0x90B4 # 0 +0xCDD5 0x90AF # 0 +0xCDD6 0x90B3 # 0 +0xCDD7 0x90B0 # 0 +0xCDD8 0x9639 # 0 +0xCDD9 0x963D # 0 +0xCDDA 0x963C # 0 +0xCDDB 0x963A # 0 +0xCDDC 0x9643 # 0 +0xCDDD 0x4FCD # 0 +0xCDDE 0x4FC5 # 0 +0xCDDF 0x4FD3 # 0 +0xCDE0 0x4FB2 # 0 +0xCDE1 0x4FC9 # 0 +0xCDE2 0x4FCB # 0 +0xCDE3 0x4FC1 # 0 +0xCDE4 0x4FD4 # 0 +0xCDE5 0x4FDC # 0 +0xCDE6 0x4FD9 # 0 +0xCDE7 0x4FBB # 0 +0xCDE8 0x4FB3 # 0 +0xCDE9 0x4FDB # 0 +0xCDEA 0x4FC7 # 0 +0xCDEB 0x4FD6 # 0 +0xCDEC 0x4FBA # 0 +0xCDED 0x4FC0 # 0 +0xCDEE 0x4FB9 # 0 +0xCDEF 0x4FEC # 0 +0xCDF0 0x5244 # 0 +0xCDF1 0x5249 # 0 +0xCDF2 0x52C0 # 0 +0xCDF3 0x52C2 # 0 +0xCDF4 0x533D # 0 +0xCDF5 0x537C # 0 +0xCDF6 0x5397 # 0 +0xCDF7 0x5396 # 0 +0xCDF8 0x5399 # 0 +0xCDF9 0x5398 # 0 +0xCDFA 0x54BA # 0 +0xCDFB 0x54A1 # 0 +0xCDFC 0x54AD # 0 +0xCDFD 0x54A5 # 0 +0xCDFE 0x54CF # 0 +0xCE40 0x54C3 # 0 +0xCE41 0x830D # 0 +0xCE42 0x54B7 # 0 +0xCE43 0x54AE # 0 +0xCE44 0x54D6 # 0 +0xCE45 0x54B6 # 0 +0xCE46 0x54C5 # 0 +0xCE47 0x54C6 # 0 +0xCE48 0x54A0 # 0 +0xCE49 0x5470 # 0 +0xCE4A 0x54BC # 0 +0xCE4B 0x54A2 # 0 +0xCE4C 0x54BE # 0 +0xCE4D 0x5472 # 0 +0xCE4E 0x54DE # 0 +0xCE4F 0x54B0 # 0 +0xCE50 0x57B5 # 0 +0xCE51 0x579E # 0 +0xCE52 0x579F # 0 +0xCE53 0x57A4 # 0 +0xCE54 0x578C # 0 +0xCE55 0x5797 # 0 +0xCE56 0x579D # 0 +0xCE57 0x579B # 0 +0xCE58 0x5794 # 0 +0xCE59 0x5798 # 0 +0xCE5A 0x578F # 0 +0xCE5B 0x5799 # 0 +0xCE5C 0x57A5 # 0 +0xCE5D 0x579A # 0 +0xCE5E 0x5795 # 0 +0xCE5F 0x58F4 # 0 +0xCE60 0x590D # 0 +0xCE61 0x5953 # 0 +0xCE62 0x59E1 # 0 +0xCE63 0x59DE # 0 +0xCE64 0x59EE # 0 +0xCE65 0x5A00 # 0 +0xCE66 0x59F1 # 0 +0xCE67 0x59DD # 0 +0xCE68 0x59FA # 0 +0xCE69 0x59FD # 0 +0xCE6A 0x59FC # 0 +0xCE6B 0x59F6 # 0 +0xCE6C 0x59E4 # 0 +0xCE6D 0x59F2 # 0 +0xCE6E 0x59F7 # 0 +0xCE6F 0x59DB # 0 +0xCE70 0x59E9 # 0 +0xCE71 0x59F3 # 0 +0xCE72 0x59F5 # 0 +0xCE73 0x59E0 # 0 +0xCE74 0x59FE # 0 +0xCE75 0x59F4 # 0 +0xCE76 0x59ED # 0 +0xCE77 0x5BA8 # 0 +0xCE78 0x5C4C # 0 +0xCE79 0x5CD0 # 0 +0xCE7A 0x5CD8 # 0 +0xCE7B 0x5CCC # 0 +0xCE7C 0x5CD7 # 0 +0xCE7D 0x5CCB # 0 +0xCE7E 0x5CDB # 0 +0xCEA1 0x5CDE # 0 +0xCEA2 0x5CDA # 0 +0xCEA3 0x5CC9 # 0 +0xCEA4 0x5CC7 # 0 +0xCEA5 0x5CCA # 0 +0xCEA6 0x5CD6 # 0 +0xCEA7 0x5CD3 # 0 +0xCEA8 0x5CD4 # 0 +0xCEA9 0x5CCF # 0 +0xCEAA 0x5CC8 # 0 +0xCEAB 0x5CC6 # 0 +0xCEAC 0x5CCE # 0 +0xCEAD 0x5CDF # 0 +0xCEAE 0x5CF8 # 0 +0xCEAF 0x5DF9 # 0 +0xCEB0 0x5E21 # 0 +0xCEB1 0x5E22 # 0 +0xCEB2 0x5E23 # 0 +0xCEB3 0x5E20 # 0 +0xCEB4 0x5E24 # 0 +0xCEB5 0x5EB0 # 0 +0xCEB6 0x5EA4 # 0 +0xCEB7 0x5EA2 # 0 +0xCEB8 0x5E9B # 0 +0xCEB9 0x5EA3 # 0 +0xCEBA 0x5EA5 # 0 +0xCEBB 0x5F07 # 0 +0xCEBC 0x5F2E # 0 +0xCEBD 0x5F56 # 0 +0xCEBE 0x5F86 # 0 +0xCEBF 0x6037 # 0 +0xCEC0 0x6039 # 0 +0xCEC1 0x6054 # 0 +0xCEC2 0x6072 # 0 +0xCEC3 0x605E # 0 +0xCEC4 0x6045 # 0 +0xCEC5 0x6053 # 0 +0xCEC6 0x6047 # 0 +0xCEC7 0x6049 # 0 +0xCEC8 0x605B # 0 +0xCEC9 0x604C # 0 +0xCECA 0x6040 # 0 +0xCECB 0x6042 # 0 +0xCECC 0x605F # 0 +0xCECD 0x6024 # 0 +0xCECE 0x6044 # 0 +0xCECF 0x6058 # 0 +0xCED0 0x6066 # 0 +0xCED1 0x606E # 0 +0xCED2 0x6242 # 0 +0xCED3 0x6243 # 0 +0xCED4 0x62CF # 0 +0xCED5 0x630D # 0 +0xCED6 0x630B # 0 +0xCED7 0x62F5 # 0 +0xCED8 0x630E # 0 +0xCED9 0x6303 # 0 +0xCEDA 0x62EB # 0 +0xCEDB 0x62F9 # 0 +0xCEDC 0x630F # 0 +0xCEDD 0x630C # 0 +0xCEDE 0x62F8 # 0 +0xCEDF 0x62F6 # 0 +0xCEE0 0x6300 # 0 +0xCEE1 0x6313 # 0 +0xCEE2 0x6314 # 0 +0xCEE3 0x62FA # 0 +0xCEE4 0x6315 # 0 +0xCEE5 0x62FB # 0 +0xCEE6 0x62F0 # 0 +0xCEE7 0x6541 # 0 +0xCEE8 0x6543 # 0 +0xCEE9 0x65AA # 0 +0xCEEA 0x65BF # 0 +0xCEEB 0x6636 # 0 +0xCEEC 0x6621 # 0 +0xCEED 0x6632 # 0 +0xCEEE 0x6635 # 0 +0xCEEF 0x661C # 0 +0xCEF0 0x6626 # 0 +0xCEF1 0x6622 # 0 +0xCEF2 0x6633 # 0 +0xCEF3 0x662B # 0 +0xCEF4 0x663A # 0 +0xCEF5 0x661D # 0 +0xCEF6 0x6634 # 0 +0xCEF7 0x6639 # 0 +0xCEF8 0x662E # 0 +0xCEF9 0x670F # 0 +0xCEFA 0x6710 # 0 +0xCEFB 0x67C1 # 0 +0xCEFC 0x67F2 # 0 +0xCEFD 0x67C8 # 0 +0xCEFE 0x67BA # 0 +0xCF40 0x67DC # 0 +0xCF41 0x67BB # 0 +0xCF42 0x67F8 # 0 +0xCF43 0x67D8 # 0 +0xCF44 0x67C0 # 0 +0xCF45 0x67B7 # 0 +0xCF46 0x67C5 # 0 +0xCF47 0x67EB # 0 +0xCF48 0x67E4 # 0 +0xCF49 0x67DF # 0 +0xCF4A 0x67B5 # 0 +0xCF4B 0x67CD # 0 +0xCF4C 0x67B3 # 0 +0xCF4D 0x67F7 # 0 +0xCF4E 0x67F6 # 0 +0xCF4F 0x67EE # 0 +0xCF50 0x67E3 # 0 +0xCF51 0x67C2 # 0 +0xCF52 0x67B9 # 0 +0xCF53 0x67CE # 0 +0xCF54 0x67E7 # 0 +0xCF55 0x67F0 # 0 +0xCF56 0x67B2 # 0 +0xCF57 0x67FC # 0 +0xCF58 0x67C6 # 0 +0xCF59 0x67ED # 0 +0xCF5A 0x67CC # 0 +0xCF5B 0x67AE # 0 +0xCF5C 0x67E6 # 0 +0xCF5D 0x67DB # 0 +0xCF5E 0x67FA # 0 +0xCF5F 0x67C9 # 0 +0xCF60 0x67CA # 0 +0xCF61 0x67C3 # 0 +0xCF62 0x67EA # 0 +0xCF63 0x67CB # 0 +0xCF64 0x6B28 # 0 +0xCF65 0x6B82 # 0 +0xCF66 0x6B84 # 0 +0xCF67 0x6BB6 # 0 +0xCF68 0x6BD6 # 0 +0xCF69 0x6BD8 # 0 +0xCF6A 0x6BE0 # 0 +0xCF6B 0x6C20 # 0 +0xCF6C 0x6C21 # 0 +0xCF6D 0x6D28 # 0 +0xCF6E 0x6D34 # 0 +0xCF6F 0x6D2D # 0 +0xCF70 0x6D1F # 0 +0xCF71 0x6D3C # 0 +0xCF72 0x6D3F # 0 +0xCF73 0x6D12 # 0 +0xCF74 0x6D0A # 0 +0xCF75 0x6CDA # 0 +0xCF76 0x6D33 # 0 +0xCF77 0x6D04 # 0 +0xCF78 0x6D19 # 0 +0xCF79 0x6D3A # 0 +0xCF7A 0x6D1A # 0 +0xCF7B 0x6D11 # 0 +0xCF7C 0x6D00 # 0 +0xCF7D 0x6D1D # 0 +0xCF7E 0x6D42 # 0 +0xCFA1 0x6D01 # 0 +0xCFA2 0x6D18 # 0 +0xCFA3 0x6D37 # 0 +0xCFA4 0x6D03 # 0 +0xCFA5 0x6D0F # 0 +0xCFA6 0x6D40 # 0 +0xCFA7 0x6D07 # 0 +0xCFA8 0x6D20 # 0 +0xCFA9 0x6D2C # 0 +0xCFAA 0x6D08 # 0 +0xCFAB 0x6D22 # 0 +0xCFAC 0x6D09 # 0 +0xCFAD 0x6D10 # 0 +0xCFAE 0x70B7 # 0 +0xCFAF 0x709F # 0 +0xCFB0 0x70BE # 0 +0xCFB1 0x70B1 # 0 +0xCFB2 0x70B0 # 0 +0xCFB3 0x70A1 # 0 +0xCFB4 0x70B4 # 0 +0xCFB5 0x70B5 # 0 +0xCFB6 0x70A9 # 0 +0xCFB7 0x7241 # 0 +0xCFB8 0x7249 # 0 +0xCFB9 0x724A # 0 +0xCFBA 0x726C # 0 +0xCFBB 0x7270 # 0 +0xCFBC 0x7273 # 0 +0xCFBD 0x726E # 0 +0xCFBE 0x72CA # 0 +0xCFBF 0x72E4 # 0 +0xCFC0 0x72E8 # 0 +0xCFC1 0x72EB # 0 +0xCFC2 0x72DF # 0 +0xCFC3 0x72EA # 0 +0xCFC4 0x72E6 # 0 +0xCFC5 0x72E3 # 0 +0xCFC6 0x7385 # 0 +0xCFC7 0x73CC # 0 +0xCFC8 0x73C2 # 0 +0xCFC9 0x73C8 # 0 +0xCFCA 0x73C5 # 0 +0xCFCB 0x73B9 # 0 +0xCFCC 0x73B6 # 0 +0xCFCD 0x73B5 # 0 +0xCFCE 0x73B4 # 0 +0xCFCF 0x73EB # 0 +0xCFD0 0x73BF # 0 +0xCFD1 0x73C7 # 0 +0xCFD2 0x73BE # 0 +0xCFD3 0x73C3 # 0 +0xCFD4 0x73C6 # 0 +0xCFD5 0x73B8 # 0 +0xCFD6 0x73CB # 0 +0xCFD7 0x74EC # 0 +0xCFD8 0x74EE # 0 +0xCFD9 0x752E # 0 +0xCFDA 0x7547 # 0 +0xCFDB 0x7548 # 0 +0xCFDC 0x75A7 # 0 +0xCFDD 0x75AA # 0 +0xCFDE 0x7679 # 0 +0xCFDF 0x76C4 # 0 +0xCFE0 0x7708 # 0 +0xCFE1 0x7703 # 0 +0xCFE2 0x7704 # 0 +0xCFE3 0x7705 # 0 +0xCFE4 0x770A # 0 +0xCFE5 0x76F7 # 0 +0xCFE6 0x76FB # 0 +0xCFE7 0x76FA # 0 +0xCFE8 0x77E7 # 0 +0xCFE9 0x77E8 # 0 +0xCFEA 0x7806 # 0 +0xCFEB 0x7811 # 0 +0xCFEC 0x7812 # 0 +0xCFED 0x7805 # 0 +0xCFEE 0x7810 # 0 +0xCFEF 0x780F # 0 +0xCFF0 0x780E # 0 +0xCFF1 0x7809 # 0 +0xCFF2 0x7803 # 0 +0xCFF3 0x7813 # 0 +0xCFF4 0x794A # 0 +0xCFF5 0x794C # 0 +0xCFF6 0x794B # 0 +0xCFF7 0x7945 # 0 +0xCFF8 0x7944 # 0 +0xCFF9 0x79D5 # 0 +0xCFFA 0x79CD # 0 +0xCFFB 0x79CF # 0 +0xCFFC 0x79D6 # 0 +0xCFFD 0x79CE # 0 +0xCFFE 0x7A80 # 0 +0xD040 0x7A7E # 0 +0xD041 0x7AD1 # 0 +0xD042 0x7B00 # 0 +0xD043 0x7B01 # 0 +0xD044 0x7C7A # 0 +0xD045 0x7C78 # 0 +0xD046 0x7C79 # 0 +0xD047 0x7C7F # 0 +0xD048 0x7C80 # 0 +0xD049 0x7C81 # 0 +0xD04A 0x7D03 # 0 +0xD04B 0x7D08 # 0 +0xD04C 0x7D01 # 0 +0xD04D 0x7F58 # 0 +0xD04E 0x7F91 # 0 +0xD04F 0x7F8D # 0 +0xD050 0x7FBE # 0 +0xD051 0x8007 # 0 +0xD052 0x800E # 0 +0xD053 0x800F # 0 +0xD054 0x8014 # 0 +0xD055 0x8037 # 0 +0xD056 0x80D8 # 0 +0xD057 0x80C7 # 0 +0xD058 0x80E0 # 0 +0xD059 0x80D1 # 0 +0xD05A 0x80C8 # 0 +0xD05B 0x80C2 # 0 +0xD05C 0x80D0 # 0 +0xD05D 0x80C5 # 0 +0xD05E 0x80E3 # 0 +0xD05F 0x80D9 # 0 +0xD060 0x80DC # 0 +0xD061 0x80CA # 0 +0xD062 0x80D5 # 0 +0xD063 0x80C9 # 0 +0xD064 0x80CF # 0 +0xD065 0x80D7 # 0 +0xD066 0x80E6 # 0 +0xD067 0x80CD # 0 +0xD068 0x81FF # 0 +0xD069 0x8221 # 0 +0xD06A 0x8294 # 0 +0xD06B 0x82D9 # 0 +0xD06C 0x82FE # 0 +0xD06D 0x82F9 # 0 +0xD06E 0x8307 # 0 +0xD06F 0x82E8 # 0 +0xD070 0x8300 # 0 +0xD071 0x82D5 # 0 +0xD072 0x833A # 0 +0xD073 0x82EB # 0 +0xD074 0x82D6 # 0 +0xD075 0x82F4 # 0 +0xD076 0x82EC # 0 +0xD077 0x82E1 # 0 +0xD078 0x82F2 # 0 +0xD079 0x82F5 # 0 +0xD07A 0x830C # 0 +0xD07B 0x82FB # 0 +0xD07C 0x82F6 # 0 +0xD07D 0x82F0 # 0 +0xD07E 0x82EA # 0 +0xD0A1 0x82E4 # 0 +0xD0A2 0x82E0 # 0 +0xD0A3 0x82FA # 0 +0xD0A4 0x82F3 # 0 +0xD0A5 0x82ED # 0 +0xD0A6 0x8677 # 0 +0xD0A7 0x8674 # 0 +0xD0A8 0x867C # 0 +0xD0A9 0x8673 # 0 +0xD0AA 0x8841 # 0 +0xD0AB 0x884E # 0 +0xD0AC 0x8867 # 0 +0xD0AD 0x886A # 0 +0xD0AE 0x8869 # 0 +0xD0AF 0x89D3 # 0 +0xD0B0 0x8A04 # 0 +0xD0B1 0x8A07 # 0 +0xD0B2 0x8D72 # 0 +0xD0B3 0x8FE3 # 0 +0xD0B4 0x8FE1 # 0 +0xD0B5 0x8FEE # 0 +0xD0B6 0x8FE0 # 0 +0xD0B7 0x90F1 # 0 +0xD0B8 0x90BD # 0 +0xD0B9 0x90BF # 0 +0xD0BA 0x90D5 # 0 +0xD0BB 0x90C5 # 0 +0xD0BC 0x90BE # 0 +0xD0BD 0x90C7 # 0 +0xD0BE 0x90CB # 0 +0xD0BF 0x90C8 # 0 +0xD0C0 0x91D4 # 0 +0xD0C1 0x91D3 # 0 +0xD0C2 0x9654 # 0 +0xD0C3 0x964F # 0 +0xD0C4 0x9651 # 0 +0xD0C5 0x9653 # 0 +0xD0C6 0x964A # 0 +0xD0C7 0x964E # 0 +0xD0C8 0x501E # 0 +0xD0C9 0x5005 # 0 +0xD0CA 0x5007 # 0 +0xD0CB 0x5013 # 0 +0xD0CC 0x5022 # 0 +0xD0CD 0x5030 # 0 +0xD0CE 0x501B # 0 +0xD0CF 0x4FF5 # 0 +0xD0D0 0x4FF4 # 0 +0xD0D1 0x5033 # 0 +0xD0D2 0x5037 # 0 +0xD0D3 0x502C # 0 +0xD0D4 0x4FF6 # 0 +0xD0D5 0x4FF7 # 0 +0xD0D6 0x5017 # 0 +0xD0D7 0x501C # 0 +0xD0D8 0x5020 # 0 +0xD0D9 0x5027 # 0 +0xD0DA 0x5035 # 0 +0xD0DB 0x502F # 0 +0xD0DC 0x5031 # 0 +0xD0DD 0x500E # 0 +0xD0DE 0x515A # 0 +0xD0DF 0x5194 # 0 +0xD0E0 0x5193 # 0 +0xD0E1 0x51CA # 0 +0xD0E2 0x51C4 # 0 +0xD0E3 0x51C5 # 0 +0xD0E4 0x51C8 # 0 +0xD0E5 0x51CE # 0 +0xD0E6 0x5261 # 0 +0xD0E7 0x525A # 0 +0xD0E8 0x5252 # 0 +0xD0E9 0x525E # 0 +0xD0EA 0x525F # 0 +0xD0EB 0x5255 # 0 +0xD0EC 0x5262 # 0 +0xD0ED 0x52CD # 0 +0xD0EE 0x530E # 0 +0xD0EF 0x539E # 0 +0xD0F0 0x5526 # 0 +0xD0F1 0x54E2 # 0 +0xD0F2 0x5517 # 0 +0xD0F3 0x5512 # 0 +0xD0F4 0x54E7 # 0 +0xD0F5 0x54F3 # 0 +0xD0F6 0x54E4 # 0 +0xD0F7 0x551A # 0 +0xD0F8 0x54FF # 0 +0xD0F9 0x5504 # 0 +0xD0FA 0x5508 # 0 +0xD0FB 0x54EB # 0 +0xD0FC 0x5511 # 0 +0xD0FD 0x5505 # 0 +0xD0FE 0x54F1 # 0 +0xD140 0x550A # 0 +0xD141 0x54FB # 0 +0xD142 0x54F7 # 0 +0xD143 0x54F8 # 0 +0xD144 0x54E0 # 0 +0xD145 0x550E # 0 +0xD146 0x5503 # 0 +0xD147 0x550B # 0 +0xD148 0x5701 # 0 +0xD149 0x5702 # 0 +0xD14A 0x57CC # 0 +0xD14B 0x5832 # 0 +0xD14C 0x57D5 # 0 +0xD14D 0x57D2 # 0 +0xD14E 0x57BA # 0 +0xD14F 0x57C6 # 0 +0xD150 0x57BD # 0 +0xD151 0x57BC # 0 +0xD152 0x57B8 # 0 +0xD153 0x57B6 # 0 +0xD154 0x57BF # 0 +0xD155 0x57C7 # 0 +0xD156 0x57D0 # 0 +0xD157 0x57B9 # 0 +0xD158 0x57C1 # 0 +0xD159 0x590E # 0 +0xD15A 0x594A # 0 +0xD15B 0x5A19 # 0 +0xD15C 0x5A16 # 0 +0xD15D 0x5A2D # 0 +0xD15E 0x5A2E # 0 +0xD15F 0x5A15 # 0 +0xD160 0x5A0F # 0 +0xD161 0x5A17 # 0 +0xD162 0x5A0A # 0 +0xD163 0x5A1E # 0 +0xD164 0x5A33 # 0 +0xD165 0x5B6C # 0 +0xD166 0x5BA7 # 0 +0xD167 0x5BAD # 0 +0xD168 0x5BAC # 0 +0xD169 0x5C03 # 0 +0xD16A 0x5C56 # 0 +0xD16B 0x5C54 # 0 +0xD16C 0x5CEC # 0 +0xD16D 0x5CFF # 0 +0xD16E 0x5CEE # 0 +0xD16F 0x5CF1 # 0 +0xD170 0x5CF7 # 0 +0xD171 0x5D00 # 0 +0xD172 0x5CF9 # 0 +0xD173 0x5E29 # 0 +0xD174 0x5E28 # 0 +0xD175 0x5EA8 # 0 +0xD176 0x5EAE # 0 +0xD177 0x5EAA # 0 +0xD178 0x5EAC # 0 +0xD179 0x5F33 # 0 +0xD17A 0x5F30 # 0 +0xD17B 0x5F67 # 0 +0xD17C 0x605D # 0 +0xD17D 0x605A # 0 +0xD17E 0x6067 # 0 +0xD1A1 0x6041 # 0 +0xD1A2 0x60A2 # 0 +0xD1A3 0x6088 # 0 +0xD1A4 0x6080 # 0 +0xD1A5 0x6092 # 0 +0xD1A6 0x6081 # 0 +0xD1A7 0x609D # 0 +0xD1A8 0x6083 # 0 +0xD1A9 0x6095 # 0 +0xD1AA 0x609B # 0 +0xD1AB 0x6097 # 0 +0xD1AC 0x6087 # 0 +0xD1AD 0x609C # 0 +0xD1AE 0x608E # 0 +0xD1AF 0x6219 # 0 +0xD1B0 0x6246 # 0 +0xD1B1 0x62F2 # 0 +0xD1B2 0x6310 # 0 +0xD1B3 0x6356 # 0 +0xD1B4 0x632C # 0 +0xD1B5 0x6344 # 0 +0xD1B6 0x6345 # 0 +0xD1B7 0x6336 # 0 +0xD1B8 0x6343 # 0 +0xD1B9 0x63E4 # 0 +0xD1BA 0x6339 # 0 +0xD1BB 0x634B # 0 +0xD1BC 0x634A # 0 +0xD1BD 0x633C # 0 +0xD1BE 0x6329 # 0 +0xD1BF 0x6341 # 0 +0xD1C0 0x6334 # 0 +0xD1C1 0x6358 # 0 +0xD1C2 0x6354 # 0 +0xD1C3 0x6359 # 0 +0xD1C4 0x632D # 0 +0xD1C5 0x6347 # 0 +0xD1C6 0x6333 # 0 +0xD1C7 0x635A # 0 +0xD1C8 0x6351 # 0 +0xD1C9 0x6338 # 0 +0xD1CA 0x6357 # 0 +0xD1CB 0x6340 # 0 +0xD1CC 0x6348 # 0 +0xD1CD 0x654A # 0 +0xD1CE 0x6546 # 0 +0xD1CF 0x65C6 # 0 +0xD1D0 0x65C3 # 0 +0xD1D1 0x65C4 # 0 +0xD1D2 0x65C2 # 0 +0xD1D3 0x664A # 0 +0xD1D4 0x665F # 0 +0xD1D5 0x6647 # 0 +0xD1D6 0x6651 # 0 +0xD1D7 0x6712 # 0 +0xD1D8 0x6713 # 0 +0xD1D9 0x681F # 0 +0xD1DA 0x681A # 0 +0xD1DB 0x6849 # 0 +0xD1DC 0x6832 # 0 +0xD1DD 0x6833 # 0 +0xD1DE 0x683B # 0 +0xD1DF 0x684B # 0 +0xD1E0 0x684F # 0 +0xD1E1 0x6816 # 0 +0xD1E2 0x6831 # 0 +0xD1E3 0x681C # 0 +0xD1E4 0x6835 # 0 +0xD1E5 0x682B # 0 +0xD1E6 0x682D # 0 +0xD1E7 0x682F # 0 +0xD1E8 0x684E # 0 +0xD1E9 0x6844 # 0 +0xD1EA 0x6834 # 0 +0xD1EB 0x681D # 0 +0xD1EC 0x6812 # 0 +0xD1ED 0x6814 # 0 +0xD1EE 0x6826 # 0 +0xD1EF 0x6828 # 0 +0xD1F0 0x682E # 0 +0xD1F1 0x684D # 0 +0xD1F2 0x683A # 0 +0xD1F3 0x6825 # 0 +0xD1F4 0x6820 # 0 +0xD1F5 0x6B2C # 0 +0xD1F6 0x6B2F # 0 +0xD1F7 0x6B2D # 0 +0xD1F8 0x6B31 # 0 +0xD1F9 0x6B34 # 0 +0xD1FA 0x6B6D # 0 +0xD1FB 0x8082 # 0 +0xD1FC 0x6B88 # 0 +0xD1FD 0x6BE6 # 0 +0xD1FE 0x6BE4 # 0 +0xD240 0x6BE8 # 0 +0xD241 0x6BE3 # 0 +0xD242 0x6BE2 # 0 +0xD243 0x6BE7 # 0 +0xD244 0x6C25 # 0 +0xD245 0x6D7A # 0 +0xD246 0x6D63 # 0 +0xD247 0x6D64 # 0 +0xD248 0x6D76 # 0 +0xD249 0x6D0D # 0 +0xD24A 0x6D61 # 0 +0xD24B 0x6D92 # 0 +0xD24C 0x6D58 # 0 +0xD24D 0x6D62 # 0 +0xD24E 0x6D6D # 0 +0xD24F 0x6D6F # 0 +0xD250 0x6D91 # 0 +0xD251 0x6D8D # 0 +0xD252 0x6DEF # 0 +0xD253 0x6D7F # 0 +0xD254 0x6D86 # 0 +0xD255 0x6D5E # 0 +0xD256 0x6D67 # 0 +0xD257 0x6D60 # 0 +0xD258 0x6D97 # 0 +0xD259 0x6D70 # 0 +0xD25A 0x6D7C # 0 +0xD25B 0x6D5F # 0 +0xD25C 0x6D82 # 0 +0xD25D 0x6D98 # 0 +0xD25E 0x6D2F # 0 +0xD25F 0x6D68 # 0 +0xD260 0x6D8B # 0 +0xD261 0x6D7E # 0 +0xD262 0x6D80 # 0 +0xD263 0x6D84 # 0 +0xD264 0x6D16 # 0 +0xD265 0x6D83 # 0 +0xD266 0x6D7B # 0 +0xD267 0x6D7D # 0 +0xD268 0x6D75 # 0 +0xD269 0x6D90 # 0 +0xD26A 0x70DC # 0 +0xD26B 0x70D3 # 0 +0xD26C 0x70D1 # 0 +0xD26D 0x70DD # 0 +0xD26E 0x70CB # 0 +0xD26F 0x7F39 # 0 +0xD270 0x70E2 # 0 +0xD271 0x70D7 # 0 +0xD272 0x70D2 # 0 +0xD273 0x70DE # 0 +0xD274 0x70E0 # 0 +0xD275 0x70D4 # 0 +0xD276 0x70CD # 0 +0xD277 0x70C5 # 0 +0xD278 0x70C6 # 0 +0xD279 0x70C7 # 0 +0xD27A 0x70DA # 0 +0xD27B 0x70CE # 0 +0xD27C 0x70E1 # 0 +0xD27D 0x7242 # 0 +0xD27E 0x7278 # 0 +0xD2A1 0x7277 # 0 +0xD2A2 0x7276 # 0 +0xD2A3 0x7300 # 0 +0xD2A4 0x72FA # 0 +0xD2A5 0x72F4 # 0 +0xD2A6 0x72FE # 0 +0xD2A7 0x72F6 # 0 +0xD2A8 0x72F3 # 0 +0xD2A9 0x72FB # 0 +0xD2AA 0x7301 # 0 +0xD2AB 0x73D3 # 0 +0xD2AC 0x73D9 # 0 +0xD2AD 0x73E5 # 0 +0xD2AE 0x73D6 # 0 +0xD2AF 0x73BC # 0 +0xD2B0 0x73E7 # 0 +0xD2B1 0x73E3 # 0 +0xD2B2 0x73E9 # 0 +0xD2B3 0x73DC # 0 +0xD2B4 0x73D2 # 0 +0xD2B5 0x73DB # 0 +0xD2B6 0x73D4 # 0 +0xD2B7 0x73DD # 0 +0xD2B8 0x73DA # 0 +0xD2B9 0x73D7 # 0 +0xD2BA 0x73D8 # 0 +0xD2BB 0x73E8 # 0 +0xD2BC 0x74DE # 0 +0xD2BD 0x74DF # 0 +0xD2BE 0x74F4 # 0 +0xD2BF 0x74F5 # 0 +0xD2C0 0x7521 # 0 +0xD2C1 0x755B # 0 +0xD2C2 0x755F # 0 +0xD2C3 0x75B0 # 0 +0xD2C4 0x75C1 # 0 +0xD2C5 0x75BB # 0 +0xD2C6 0x75C4 # 0 +0xD2C7 0x75C0 # 0 +0xD2C8 0x75BF # 0 +0xD2C9 0x75B6 # 0 +0xD2CA 0x75BA # 0 +0xD2CB 0x768A # 0 +0xD2CC 0x76C9 # 0 +0xD2CD 0x771D # 0 +0xD2CE 0x771B # 0 +0xD2CF 0x7710 # 0 +0xD2D0 0x7713 # 0 +0xD2D1 0x7712 # 0 +0xD2D2 0x7723 # 0 +0xD2D3 0x7711 # 0 +0xD2D4 0x7715 # 0 +0xD2D5 0x7719 # 0 +0xD2D6 0x771A # 0 +0xD2D7 0x7722 # 0 +0xD2D8 0x7727 # 0 +0xD2D9 0x7823 # 0 +0xD2DA 0x782C # 0 +0xD2DB 0x7822 # 0 +0xD2DC 0x7835 # 0 +0xD2DD 0x782F # 0 +0xD2DE 0x7828 # 0 +0xD2DF 0x782E # 0 +0xD2E0 0x782B # 0 +0xD2E1 0x7821 # 0 +0xD2E2 0x7829 # 0 +0xD2E3 0x7833 # 0 +0xD2E4 0x782A # 0 +0xD2E5 0x7831 # 0 +0xD2E6 0x7954 # 0 +0xD2E7 0x795B # 0 +0xD2E8 0x794F # 0 +0xD2E9 0x795C # 0 +0xD2EA 0x7953 # 0 +0xD2EB 0x7952 # 0 +0xD2EC 0x7951 # 0 +0xD2ED 0x79EB # 0 +0xD2EE 0x79EC # 0 +0xD2EF 0x79E0 # 0 +0xD2F0 0x79EE # 0 +0xD2F1 0x79ED # 0 +0xD2F2 0x79EA # 0 +0xD2F3 0x79DC # 0 +0xD2F4 0x79DE # 0 +0xD2F5 0x79DD # 0 +0xD2F6 0x7A86 # 0 +0xD2F7 0x7A89 # 0 +0xD2F8 0x7A85 # 0 +0xD2F9 0x7A8B # 0 +0xD2FA 0x7A8C # 0 +0xD2FB 0x7A8A # 0 +0xD2FC 0x7A87 # 0 +0xD2FD 0x7AD8 # 0 +0xD2FE 0x7B10 # 0 +0xD340 0x7B04 # 0 +0xD341 0x7B13 # 0 +0xD342 0x7B05 # 0 +0xD343 0x7B0F # 0 +0xD344 0x7B08 # 0 +0xD345 0x7B0A # 0 +0xD346 0x7B0E # 0 +0xD347 0x7B09 # 0 +0xD348 0x7B12 # 0 +0xD349 0x7C84 # 0 +0xD34A 0x7C91 # 0 +0xD34B 0x7C8A # 0 +0xD34C 0x7C8C # 0 +0xD34D 0x7C88 # 0 +0xD34E 0x7C8D # 0 +0xD34F 0x7C85 # 0 +0xD350 0x7D1E # 0 +0xD351 0x7D1D # 0 +0xD352 0x7D11 # 0 +0xD353 0x7D0E # 0 +0xD354 0x7D18 # 0 +0xD355 0x7D16 # 0 +0xD356 0x7D13 # 0 +0xD357 0x7D1F # 0 +0xD358 0x7D12 # 0 +0xD359 0x7D0F # 0 +0xD35A 0x7D0C # 0 +0xD35B 0x7F5C # 0 +0xD35C 0x7F61 # 0 +0xD35D 0x7F5E # 0 +0xD35E 0x7F60 # 0 +0xD35F 0x7F5D # 0 +0xD360 0x7F5B # 0 +0xD361 0x7F96 # 0 +0xD362 0x7F92 # 0 +0xD363 0x7FC3 # 0 +0xD364 0x7FC2 # 0 +0xD365 0x7FC0 # 0 +0xD366 0x8016 # 0 +0xD367 0x803E # 0 +0xD368 0x8039 # 0 +0xD369 0x80FA # 0 +0xD36A 0x80F2 # 0 +0xD36B 0x80F9 # 0 +0xD36C 0x80F5 # 0 +0xD36D 0x8101 # 0 +0xD36E 0x80FB # 0 +0xD36F 0x8100 # 0 +0xD370 0x8201 # 0 +0xD371 0x822F # 0 +0xD372 0x8225 # 0 +0xD373 0x8333 # 0 +0xD374 0x832D # 0 +0xD375 0x8344 # 0 +0xD376 0x8319 # 0 +0xD377 0x8351 # 0 +0xD378 0x8325 # 0 +0xD379 0x8356 # 0 +0xD37A 0x833F # 0 +0xD37B 0x8341 # 0 +0xD37C 0x8326 # 0 +0xD37D 0x831C # 0 +0xD37E 0x8322 # 0 +0xD3A1 0x8342 # 0 +0xD3A2 0x834E # 0 +0xD3A3 0x831B # 0 +0xD3A4 0x832A # 0 +0xD3A5 0x8308 # 0 +0xD3A6 0x833C # 0 +0xD3A7 0x834D # 0 +0xD3A8 0x8316 # 0 +0xD3A9 0x8324 # 0 +0xD3AA 0x8320 # 0 +0xD3AB 0x8337 # 0 +0xD3AC 0x832F # 0 +0xD3AD 0x8329 # 0 +0xD3AE 0x8347 # 0 +0xD3AF 0x8345 # 0 +0xD3B0 0x834C # 0 +0xD3B1 0x8353 # 0 +0xD3B2 0x831E # 0 +0xD3B3 0x832C # 0 +0xD3B4 0x834B # 0 +0xD3B5 0x8327 # 0 +0xD3B6 0x8348 # 0 +0xD3B7 0x8653 # 0 +0xD3B8 0x8652 # 0 +0xD3B9 0x86A2 # 0 +0xD3BA 0x86A8 # 0 +0xD3BB 0x8696 # 0 +0xD3BC 0x868D # 0 +0xD3BD 0x8691 # 0 +0xD3BE 0x869E # 0 +0xD3BF 0x8687 # 0 +0xD3C0 0x8697 # 0 +0xD3C1 0x8686 # 0 +0xD3C2 0x868B # 0 +0xD3C3 0x869A # 0 +0xD3C4 0x8685 # 0 +0xD3C5 0x86A5 # 0 +0xD3C6 0x8699 # 0 +0xD3C7 0x86A1 # 0 +0xD3C8 0x86A7 # 0 +0xD3C9 0x8695 # 0 +0xD3CA 0x8698 # 0 +0xD3CB 0x868E # 0 +0xD3CC 0x869D # 0 +0xD3CD 0x8690 # 0 +0xD3CE 0x8694 # 0 +0xD3CF 0x8843 # 0 +0xD3D0 0x8844 # 0 +0xD3D1 0x886D # 0 +0xD3D2 0x8875 # 0 +0xD3D3 0x8876 # 0 +0xD3D4 0x8872 # 0 +0xD3D5 0x8880 # 0 +0xD3D6 0x8871 # 0 +0xD3D7 0x887F # 0 +0xD3D8 0x886F # 0 +0xD3D9 0x8883 # 0 +0xD3DA 0x887E # 0 +0xD3DB 0x8874 # 0 +0xD3DC 0x887C # 0 +0xD3DD 0x8A12 # 0 +0xD3DE 0x8C47 # 0 +0xD3DF 0x8C57 # 0 +0xD3E0 0x8C7B # 0 +0xD3E1 0x8CA4 # 0 +0xD3E2 0x8CA3 # 0 +0xD3E3 0x8D76 # 0 +0xD3E4 0x8D78 # 0 +0xD3E5 0x8DB5 # 0 +0xD3E6 0x8DB7 # 0 +0xD3E7 0x8DB6 # 0 +0xD3E8 0x8ED1 # 0 +0xD3E9 0x8ED3 # 0 +0xD3EA 0x8FFE # 0 +0xD3EB 0x8FF5 # 0 +0xD3EC 0x9002 # 0 +0xD3ED 0x8FFF # 0 +0xD3EE 0x8FFB # 0 +0xD3EF 0x9004 # 0 +0xD3F0 0x8FFC # 0 +0xD3F1 0x8FF6 # 0 +0xD3F2 0x90D6 # 0 +0xD3F3 0x90E0 # 0 +0xD3F4 0x90D9 # 0 +0xD3F5 0x90DA # 0 +0xD3F6 0x90E3 # 0 +0xD3F7 0x90DF # 0 +0xD3F8 0x90E5 # 0 +0xD3F9 0x90D8 # 0 +0xD3FA 0x90DB # 0 +0xD3FB 0x90D7 # 0 +0xD3FC 0x90DC # 0 +0xD3FD 0x90E4 # 0 +0xD3FE 0x9150 # 0 +0xD440 0x914E # 0 +0xD441 0x914F # 0 +0xD442 0x91D5 # 0 +0xD443 0x91E2 # 0 +0xD444 0x91DA # 0 +0xD445 0x965C # 0 +0xD446 0x965F # 0 +0xD447 0x96BC # 0 +0xD448 0x98E3 # 0 +0xD449 0x9ADF # 0 +0xD44A 0x9B2F # 0 +0xD44B 0x4E7F # 0 +0xD44C 0x5070 # 0 +0xD44D 0x506A # 0 +0xD44E 0x5061 # 0 +0xD44F 0x505E # 0 +0xD450 0x5060 # 0 +0xD451 0x5053 # 0 +0xD452 0x504B # 0 +0xD453 0x505D # 0 +0xD454 0x5072 # 0 +0xD455 0x5048 # 0 +0xD456 0x504D # 0 +0xD457 0x5041 # 0 +0xD458 0x505B # 0 +0xD459 0x504A # 0 +0xD45A 0x5062 # 0 +0xD45B 0x5015 # 0 +0xD45C 0x5045 # 0 +0xD45D 0x505F # 0 +0xD45E 0x5069 # 0 +0xD45F 0x506B # 0 +0xD460 0x5063 # 0 +0xD461 0x5064 # 0 +0xD462 0x5046 # 0 +0xD463 0x5040 # 0 +0xD464 0x506E # 0 +0xD465 0x5073 # 0 +0xD466 0x5057 # 0 +0xD467 0x5051 # 0 +0xD468 0x51D0 # 0 +0xD469 0x526B # 0 +0xD46A 0x526D # 0 +0xD46B 0x526C # 0 +0xD46C 0x526E # 0 +0xD46D 0x52D6 # 0 +0xD46E 0x52D3 # 0 +0xD46F 0x532D # 0 +0xD470 0x539C # 0 +0xD471 0x5575 # 0 +0xD472 0x5576 # 0 +0xD473 0x553C # 0 +0xD474 0x554D # 0 +0xD475 0x5550 # 0 +0xD476 0x5534 # 0 +0xD477 0x552A # 0 +0xD478 0x5551 # 0 +0xD479 0x5562 # 0 +0xD47A 0x5536 # 0 +0xD47B 0x5535 # 0 +0xD47C 0x5530 # 0 +0xD47D 0x5552 # 0 +0xD47E 0x5545 # 0 +0xD4A1 0x550C # 0 +0xD4A2 0x5532 # 0 +0xD4A3 0x5565 # 0 +0xD4A4 0x554E # 0 +0xD4A5 0x5539 # 0 +0xD4A6 0x5548 # 0 +0xD4A7 0x552D # 0 +0xD4A8 0x553B # 0 +0xD4A9 0x5540 # 0 +0xD4AA 0x554B # 0 +0xD4AB 0x570A # 0 +0xD4AC 0x5707 # 0 +0xD4AD 0x57FB # 0 +0xD4AE 0x5814 # 0 +0xD4AF 0x57E2 # 0 +0xD4B0 0x57F6 # 0 +0xD4B1 0x57DC # 0 +0xD4B2 0x57F4 # 0 +0xD4B3 0x5800 # 0 +0xD4B4 0x57ED # 0 +0xD4B5 0x57FD # 0 +0xD4B6 0x5808 # 0 +0xD4B7 0x57F8 # 0 +0xD4B8 0x580B # 0 +0xD4B9 0x57F3 # 0 +0xD4BA 0x57CF # 0 +0xD4BB 0x5807 # 0 +0xD4BC 0x57EE # 0 +0xD4BD 0x57E3 # 0 +0xD4BE 0x57F2 # 0 +0xD4BF 0x57E5 # 0 +0xD4C0 0x57EC # 0 +0xD4C1 0x57E1 # 0 +0xD4C2 0x580E # 0 +0xD4C3 0x57FC # 0 +0xD4C4 0x5810 # 0 +0xD4C5 0x57E7 # 0 +0xD4C6 0x5801 # 0 +0xD4C7 0x580C # 0 +0xD4C8 0x57F1 # 0 +0xD4C9 0x57E9 # 0 +0xD4CA 0x57F0 # 0 +0xD4CB 0x580D # 0 +0xD4CC 0x5804 # 0 +0xD4CD 0x595C # 0 +0xD4CE 0x5A60 # 0 +0xD4CF 0x5A58 # 0 +0xD4D0 0x5A55 # 0 +0xD4D1 0x5A67 # 0 +0xD4D2 0x5A5E # 0 +0xD4D3 0x5A38 # 0 +0xD4D4 0x5A35 # 0 +0xD4D5 0x5A6D # 0 +0xD4D6 0x5A50 # 0 +0xD4D7 0x5A5F # 0 +0xD4D8 0x5A65 # 0 +0xD4D9 0x5A6C # 0 +0xD4DA 0x5A53 # 0 +0xD4DB 0x5A64 # 0 +0xD4DC 0x5A57 # 0 +0xD4DD 0x5A43 # 0 +0xD4DE 0x5A5D # 0 +0xD4DF 0x5A52 # 0 +0xD4E0 0x5A44 # 0 +0xD4E1 0x5A5B # 0 +0xD4E2 0x5A48 # 0 +0xD4E3 0x5A8E # 0 +0xD4E4 0x5A3E # 0 +0xD4E5 0x5A4D # 0 +0xD4E6 0x5A39 # 0 +0xD4E7 0x5A4C # 0 +0xD4E8 0x5A70 # 0 +0xD4E9 0x5A69 # 0 +0xD4EA 0x5A47 # 0 +0xD4EB 0x5A51 # 0 +0xD4EC 0x5A56 # 0 +0xD4ED 0x5A42 # 0 +0xD4EE 0x5A5C # 0 +0xD4EF 0x5B72 # 0 +0xD4F0 0x5B6E # 0 +0xD4F1 0x5BC1 # 0 +0xD4F2 0x5BC0 # 0 +0xD4F3 0x5C59 # 0 +0xD4F4 0x5D1E # 0 +0xD4F5 0x5D0B # 0 +0xD4F6 0x5D1D # 0 +0xD4F7 0x5D1A # 0 +0xD4F8 0x5D20 # 0 +0xD4F9 0x5D0C # 0 +0xD4FA 0x5D28 # 0 +0xD4FB 0x5D0D # 0 +0xD4FC 0x5D26 # 0 +0xD4FD 0x5D25 # 0 +0xD4FE 0x5D0F # 0 +0xD540 0x5D30 # 0 +0xD541 0x5D12 # 0 +0xD542 0x5D23 # 0 +0xD543 0x5D1F # 0 +0xD544 0x5D2E # 0 +0xD545 0x5E3E # 0 +0xD546 0x5E34 # 0 +0xD547 0x5EB1 # 0 +0xD548 0x5EB4 # 0 +0xD549 0x5EB9 # 0 +0xD54A 0x5EB2 # 0 +0xD54B 0x5EB3 # 0 +0xD54C 0x5F36 # 0 +0xD54D 0x5F38 # 0 +0xD54E 0x5F9B # 0 +0xD54F 0x5F96 # 0 +0xD550 0x5F9F # 0 +0xD551 0x608A # 0 +0xD552 0x6090 # 0 +0xD553 0x6086 # 0 +0xD554 0x60BE # 0 +0xD555 0x60B0 # 0 +0xD556 0x60BA # 0 +0xD557 0x60D3 # 0 +0xD558 0x60D4 # 0 +0xD559 0x60CF # 0 +0xD55A 0x60E4 # 0 +0xD55B 0x60D9 # 0 +0xD55C 0x60DD # 0 +0xD55D 0x60C8 # 0 +0xD55E 0x60B1 # 0 +0xD55F 0x60DB # 0 +0xD560 0x60B7 # 0 +0xD561 0x60CA # 0 +0xD562 0x60BF # 0 +0xD563 0x60C3 # 0 +0xD564 0x60CD # 0 +0xD565 0x60C0 # 0 +0xD566 0x6332 # 0 +0xD567 0x6365 # 0 +0xD568 0x638A # 0 +0xD569 0x6382 # 0 +0xD56A 0x637D # 0 +0xD56B 0x63BD # 0 +0xD56C 0x639E # 0 +0xD56D 0x63AD # 0 +0xD56E 0x639D # 0 +0xD56F 0x6397 # 0 +0xD570 0x63AB # 0 +0xD571 0x638E # 0 +0xD572 0x636F # 0 +0xD573 0x6387 # 0 +0xD574 0x6390 # 0 +0xD575 0x636E # 0 +0xD576 0x63AF # 0 +0xD577 0x6375 # 0 +0xD578 0x639C # 0 +0xD579 0x636D # 0 +0xD57A 0x63AE # 0 +0xD57B 0x637C # 0 +0xD57C 0x63A4 # 0 +0xD57D 0x633B # 0 +0xD57E 0x639F # 0 +0xD5A1 0x6378 # 0 +0xD5A2 0x6385 # 0 +0xD5A3 0x6381 # 0 +0xD5A4 0x6391 # 0 +0xD5A5 0x638D # 0 +0xD5A6 0x6370 # 0 +0xD5A7 0x6553 # 0 +0xD5A8 0x65CD # 0 +0xD5A9 0x6665 # 0 +0xD5AA 0x6661 # 0 +0xD5AB 0x665B # 0 +0xD5AC 0x6659 # 0 +0xD5AD 0x665C # 0 +0xD5AE 0x6662 # 0 +0xD5AF 0x6718 # 0 +0xD5B0 0x6879 # 0 +0xD5B1 0x6887 # 0 +0xD5B2 0x6890 # 0 +0xD5B3 0x689C # 0 +0xD5B4 0x686D # 0 +0xD5B5 0x686E # 0 +0xD5B6 0x68AE # 0 +0xD5B7 0x68AB # 0 +0xD5B8 0x6956 # 0 +0xD5B9 0x686F # 0 +0xD5BA 0x68A3 # 0 +0xD5BB 0x68AC # 0 +0xD5BC 0x68A9 # 0 +0xD5BD 0x6875 # 0 +0xD5BE 0x6874 # 0 +0xD5BF 0x68B2 # 0 +0xD5C0 0x688F # 0 +0xD5C1 0x6877 # 0 +0xD5C2 0x6892 # 0 +0xD5C3 0x687C # 0 +0xD5C4 0x686B # 0 +0xD5C5 0x6872 # 0 +0xD5C6 0x68AA # 0 +0xD5C7 0x6880 # 0 +0xD5C8 0x6871 # 0 +0xD5C9 0x687E # 0 +0xD5CA 0x689B # 0 +0xD5CB 0x6896 # 0 +0xD5CC 0x688B # 0 +0xD5CD 0x68A0 # 0 +0xD5CE 0x6889 # 0 +0xD5CF 0x68A4 # 0 +0xD5D0 0x6878 # 0 +0xD5D1 0x687B # 0 +0xD5D2 0x6891 # 0 +0xD5D3 0x688C # 0 +0xD5D4 0x688A # 0 +0xD5D5 0x687D # 0 +0xD5D6 0x6B36 # 0 +0xD5D7 0x6B33 # 0 +0xD5D8 0x6B37 # 0 +0xD5D9 0x6B38 # 0 +0xD5DA 0x6B91 # 0 +0xD5DB 0x6B8F # 0 +0xD5DC 0x6B8D # 0 +0xD5DD 0x6B8E # 0 +0xD5DE 0x6B8C # 0 +0xD5DF 0x6C2A # 0 +0xD5E0 0x6DC0 # 0 +0xD5E1 0x6DAB # 0 +0xD5E2 0x6DB4 # 0 +0xD5E3 0x6DB3 # 0 +0xD5E4 0x6E74 # 0 +0xD5E5 0x6DAC # 0 +0xD5E6 0x6DE9 # 0 +0xD5E7 0x6DE2 # 0 +0xD5E8 0x6DB7 # 0 +0xD5E9 0x6DF6 # 0 +0xD5EA 0x6DD4 # 0 +0xD5EB 0x6E00 # 0 +0xD5EC 0x6DC8 # 0 +0xD5ED 0x6DE0 # 0 +0xD5EE 0x6DDF # 0 +0xD5EF 0x6DD6 # 0 +0xD5F0 0x6DBE # 0 +0xD5F1 0x6DE5 # 0 +0xD5F2 0x6DDC # 0 +0xD5F3 0x6DDD # 0 +0xD5F4 0x6DDB # 0 +0xD5F5 0x6DF4 # 0 +0xD5F6 0x6DCA # 0 +0xD5F7 0x6DBD # 0 +0xD5F8 0x6DED # 0 +0xD5F9 0x6DF0 # 0 +0xD5FA 0x6DBA # 0 +0xD5FB 0x6DD5 # 0 +0xD5FC 0x6DC2 # 0 +0xD5FD 0x6DCF # 0 +0xD5FE 0x6DC9 # 0 +0xD640 0x6DD0 # 0 +0xD641 0x6DF2 # 0 +0xD642 0x6DD3 # 0 +0xD643 0x6DFD # 0 +0xD644 0x6DD7 # 0 +0xD645 0x6DCD # 0 +0xD646 0x6DE3 # 0 +0xD647 0x6DBB # 0 +0xD648 0x70FA # 0 +0xD649 0x710D # 0 +0xD64A 0x70F7 # 0 +0xD64B 0x7117 # 0 +0xD64C 0x70F4 # 0 +0xD64D 0x710C # 0 +0xD64E 0x70F0 # 0 +0xD64F 0x7104 # 0 +0xD650 0x70F3 # 0 +0xD651 0x7110 # 0 +0xD652 0x70FC # 0 +0xD653 0x70FF # 0 +0xD654 0x7106 # 0 +0xD655 0x7113 # 0 +0xD656 0x7100 # 0 +0xD657 0x70F8 # 0 +0xD658 0x70F6 # 0 +0xD659 0x710B # 0 +0xD65A 0x7102 # 0 +0xD65B 0x710E # 0 +0xD65C 0x727E # 0 +0xD65D 0x727B # 0 +0xD65E 0x727C # 0 +0xD65F 0x727F # 0 +0xD660 0x731D # 0 +0xD661 0x7317 # 0 +0xD662 0x7307 # 0 +0xD663 0x7311 # 0 +0xD664 0x7318 # 0 +0xD665 0x730A # 0 +0xD666 0x7308 # 0 +0xD667 0x72FF # 0 +0xD668 0x730F # 0 +0xD669 0x731E # 0 +0xD66A 0x7388 # 0 +0xD66B 0x73F6 # 0 +0xD66C 0x73F8 # 0 +0xD66D 0x73F5 # 0 +0xD66E 0x7404 # 0 +0xD66F 0x7401 # 0 +0xD670 0x73FD # 0 +0xD671 0x7407 # 0 +0xD672 0x7400 # 0 +0xD673 0x73FA # 0 +0xD674 0x73FC # 0 +0xD675 0x73FF # 0 +0xD676 0x740C # 0 +0xD677 0x740B # 0 +0xD678 0x73F4 # 0 +0xD679 0x7408 # 0 +0xD67A 0x7564 # 0 +0xD67B 0x7563 # 0 +0xD67C 0x75CE # 0 +0xD67D 0x75D2 # 0 +0xD67E 0x75CF # 0 +0xD6A1 0x75CB # 0 +0xD6A2 0x75CC # 0 +0xD6A3 0x75D1 # 0 +0xD6A4 0x75D0 # 0 +0xD6A5 0x768F # 0 +0xD6A6 0x7689 # 0 +0xD6A7 0x76D3 # 0 +0xD6A8 0x7739 # 0 +0xD6A9 0x772F # 0 +0xD6AA 0x772D # 0 +0xD6AB 0x7731 # 0 +0xD6AC 0x7732 # 0 +0xD6AD 0x7734 # 0 +0xD6AE 0x7733 # 0 +0xD6AF 0x773D # 0 +0xD6B0 0x7725 # 0 +0xD6B1 0x773B # 0 +0xD6B2 0x7735 # 0 +0xD6B3 0x7848 # 0 +0xD6B4 0x7852 # 0 +0xD6B5 0x7849 # 0 +0xD6B6 0x784D # 0 +0xD6B7 0x784A # 0 +0xD6B8 0x784C # 0 +0xD6B9 0x7826 # 0 +0xD6BA 0x7845 # 0 +0xD6BB 0x7850 # 0 +0xD6BC 0x7964 # 0 +0xD6BD 0x7967 # 0 +0xD6BE 0x7969 # 0 +0xD6BF 0x796A # 0 +0xD6C0 0x7963 # 0 +0xD6C1 0x796B # 0 +0xD6C2 0x7961 # 0 +0xD6C3 0x79BB # 0 +0xD6C4 0x79FA # 0 +0xD6C5 0x79F8 # 0 +0xD6C6 0x79F6 # 0 +0xD6C7 0x79F7 # 0 +0xD6C8 0x7A8F # 0 +0xD6C9 0x7A94 # 0 +0xD6CA 0x7A90 # 0 +0xD6CB 0x7B35 # 0 +0xD6CC 0x7B47 # 0 +0xD6CD 0x7B34 # 0 +0xD6CE 0x7B25 # 0 +0xD6CF 0x7B30 # 0 +0xD6D0 0x7B22 # 0 +0xD6D1 0x7B24 # 0 +0xD6D2 0x7B33 # 0 +0xD6D3 0x7B18 # 0 +0xD6D4 0x7B2A # 0 +0xD6D5 0x7B1D # 0 +0xD6D6 0x7B31 # 0 +0xD6D7 0x7B2B # 0 +0xD6D8 0x7B2D # 0 +0xD6D9 0x7B2F # 0 +0xD6DA 0x7B32 # 0 +0xD6DB 0x7B38 # 0 +0xD6DC 0x7B1A # 0 +0xD6DD 0x7B23 # 0 +0xD6DE 0x7C94 # 0 +0xD6DF 0x7C98 # 0 +0xD6E0 0x7C96 # 0 +0xD6E1 0x7CA3 # 0 +0xD6E2 0x7D35 # 0 +0xD6E3 0x7D3D # 0 +0xD6E4 0x7D38 # 0 +0xD6E5 0x7D36 # 0 +0xD6E6 0x7D3A # 0 +0xD6E7 0x7D45 # 0 +0xD6E8 0x7D2C # 0 +0xD6E9 0x7D29 # 0 +0xD6EA 0x7D41 # 0 +0xD6EB 0x7D47 # 0 +0xD6EC 0x7D3E # 0 +0xD6ED 0x7D3F # 0 +0xD6EE 0x7D4A # 0 +0xD6EF 0x7D3B # 0 +0xD6F0 0x7D28 # 0 +0xD6F1 0x7F63 # 0 +0xD6F2 0x7F95 # 0 +0xD6F3 0x7F9C # 0 +0xD6F4 0x7F9D # 0 +0xD6F5 0x7F9B # 0 +0xD6F6 0x7FCA # 0 +0xD6F7 0x7FCB # 0 +0xD6F8 0x7FCD # 0 +0xD6F9 0x7FD0 # 0 +0xD6FA 0x7FD1 # 0 +0xD6FB 0x7FC7 # 0 +0xD6FC 0x7FCF # 0 +0xD6FD 0x7FC9 # 0 +0xD6FE 0x801F # 0 +0xD740 0x801E # 0 +0xD741 0x801B # 0 +0xD742 0x8047 # 0 +0xD743 0x8043 # 0 +0xD744 0x8048 # 0 +0xD745 0x8118 # 0 +0xD746 0x8125 # 0 +0xD747 0x8119 # 0 +0xD748 0x811B # 0 +0xD749 0x812D # 0 +0xD74A 0x811F # 0 +0xD74B 0x812C # 0 +0xD74C 0x811E # 0 +0xD74D 0x8121 # 0 +0xD74E 0x8115 # 0 +0xD74F 0x8127 # 0 +0xD750 0x811D # 0 +0xD751 0x8122 # 0 +0xD752 0x8211 # 0 +0xD753 0x8238 # 0 +0xD754 0x8233 # 0 +0xD755 0x823A # 0 +0xD756 0x8234 # 0 +0xD757 0x8232 # 0 +0xD758 0x8274 # 0 +0xD759 0x8390 # 0 +0xD75A 0x83A3 # 0 +0xD75B 0x83A8 # 0 +0xD75C 0x838D # 0 +0xD75D 0x837A # 0 +0xD75E 0x8373 # 0 +0xD75F 0x83A4 # 0 +0xD760 0x8374 # 0 +0xD761 0x838F # 0 +0xD762 0x8381 # 0 +0xD763 0x8395 # 0 +0xD764 0x8399 # 0 +0xD765 0x8375 # 0 +0xD766 0x8394 # 0 +0xD767 0x83A9 # 0 +0xD768 0x837D # 0 +0xD769 0x8383 # 0 +0xD76A 0x838C # 0 +0xD76B 0x839D # 0 +0xD76C 0x839B # 0 +0xD76D 0x83AA # 0 +0xD76E 0x838B # 0 +0xD76F 0x837E # 0 +0xD770 0x83A5 # 0 +0xD771 0x83AF # 0 +0xD772 0x8388 # 0 +0xD773 0x8397 # 0 +0xD774 0x83B0 # 0 +0xD775 0x837F # 0 +0xD776 0x83A6 # 0 +0xD777 0x8387 # 0 +0xD778 0x83AE # 0 +0xD779 0x8376 # 0 +0xD77A 0x839A # 0 +0xD77B 0x8659 # 0 +0xD77C 0x8656 # 0 +0xD77D 0x86BF # 0 +0xD77E 0x86B7 # 0 +0xD7A1 0x86C2 # 0 +0xD7A2 0x86C1 # 0 +0xD7A3 0x86C5 # 0 +0xD7A4 0x86BA # 0 +0xD7A5 0x86B0 # 0 +0xD7A6 0x86C8 # 0 +0xD7A7 0x86B9 # 0 +0xD7A8 0x86B3 # 0 +0xD7A9 0x86B8 # 0 +0xD7AA 0x86CC # 0 +0xD7AB 0x86B4 # 0 +0xD7AC 0x86BB # 0 +0xD7AD 0x86BC # 0 +0xD7AE 0x86C3 # 0 +0xD7AF 0x86BD # 0 +0xD7B0 0x86BE # 0 +0xD7B1 0x8852 # 0 +0xD7B2 0x8889 # 0 +0xD7B3 0x8895 # 0 +0xD7B4 0x88A8 # 0 +0xD7B5 0x88A2 # 0 +0xD7B6 0x88AA # 0 +0xD7B7 0x889A # 0 +0xD7B8 0x8891 # 0 +0xD7B9 0x88A1 # 0 +0xD7BA 0x889F # 0 +0xD7BB 0x8898 # 0 +0xD7BC 0x88A7 # 0 +0xD7BD 0x8899 # 0 +0xD7BE 0x889B # 0 +0xD7BF 0x8897 # 0 +0xD7C0 0x88A4 # 0 +0xD7C1 0x88AC # 0 +0xD7C2 0x888C # 0 +0xD7C3 0x8893 # 0 +0xD7C4 0x888E # 0 +0xD7C5 0x8982 # 0 +0xD7C6 0x89D6 # 0 +0xD7C7 0x89D9 # 0 +0xD7C8 0x89D5 # 0 +0xD7C9 0x8A30 # 0 +0xD7CA 0x8A27 # 0 +0xD7CB 0x8A2C # 0 +0xD7CC 0x8A1E # 0 +0xD7CD 0x8C39 # 0 +0xD7CE 0x8C3B # 0 +0xD7CF 0x8C5C # 0 +0xD7D0 0x8C5D # 0 +0xD7D1 0x8C7D # 0 +0xD7D2 0x8CA5 # 0 +0xD7D3 0x8D7D # 0 +0xD7D4 0x8D7B # 0 +0xD7D5 0x8D79 # 0 +0xD7D6 0x8DBC # 0 +0xD7D7 0x8DC2 # 0 +0xD7D8 0x8DB9 # 0 +0xD7D9 0x8DBF # 0 +0xD7DA 0x8DC1 # 0 +0xD7DB 0x8ED8 # 0 +0xD7DC 0x8EDE # 0 +0xD7DD 0x8EDD # 0 +0xD7DE 0x8EDC # 0 +0xD7DF 0x8ED7 # 0 +0xD7E0 0x8EE0 # 0 +0xD7E1 0x8EE1 # 0 +0xD7E2 0x9024 # 0 +0xD7E3 0x900B # 0 +0xD7E4 0x9011 # 0 +0xD7E5 0x901C # 0 +0xD7E6 0x900C # 0 +0xD7E7 0x9021 # 0 +0xD7E8 0x90EF # 0 +0xD7E9 0x90EA # 0 +0xD7EA 0x90F0 # 0 +0xD7EB 0x90F4 # 0 +0xD7EC 0x90F2 # 0 +0xD7ED 0x90F3 # 0 +0xD7EE 0x90D4 # 0 +0xD7EF 0x90EB # 0 +0xD7F0 0x90EC # 0 +0xD7F1 0x90E9 # 0 +0xD7F2 0x9156 # 0 +0xD7F3 0x9158 # 0 +0xD7F4 0x915A # 0 +0xD7F5 0x9153 # 0 +0xD7F6 0x9155 # 0 +0xD7F7 0x91EC # 0 +0xD7F8 0x91F4 # 0 +0xD7F9 0x91F1 # 0 +0xD7FA 0x91F3 # 0 +0xD7FB 0x91F8 # 0 +0xD7FC 0x91E4 # 0 +0xD7FD 0x91F9 # 0 +0xD7FE 0x91EA # 0 +0xD840 0x91EB # 0 +0xD841 0x91F7 # 0 +0xD842 0x91E8 # 0 +0xD843 0x91EE # 0 +0xD844 0x957A # 0 +0xD845 0x9586 # 0 +0xD846 0x9588 # 0 +0xD847 0x967C # 0 +0xD848 0x966D # 0 +0xD849 0x966B # 0 +0xD84A 0x9671 # 0 +0xD84B 0x966F # 0 +0xD84C 0x96BF # 0 +0xD84D 0x976A # 0 +0xD84E 0x9804 # 0 +0xD84F 0x98E5 # 0 +0xD850 0x9997 # 0 +0xD851 0x509B # 0 +0xD852 0x5095 # 0 +0xD853 0x5094 # 0 +0xD854 0x509E # 0 +0xD855 0x508B # 0 +0xD856 0x50A3 # 0 +0xD857 0x5083 # 0 +0xD858 0x508C # 0 +0xD859 0x508E # 0 +0xD85A 0x509D # 0 +0xD85B 0x5068 # 0 +0xD85C 0x509C # 0 +0xD85D 0x5092 # 0 +0xD85E 0x5082 # 0 +0xD85F 0x5087 # 0 +0xD860 0x515F # 0 +0xD861 0x51D4 # 0 +0xD862 0x5312 # 0 +0xD863 0x5311 # 0 +0xD864 0x53A4 # 0 +0xD865 0x53A7 # 0 +0xD866 0x5591 # 0 +0xD867 0x55A8 # 0 +0xD868 0x55A5 # 0 +0xD869 0x55AD # 0 +0xD86A 0x5577 # 0 +0xD86B 0x5645 # 0 +0xD86C 0x55A2 # 0 +0xD86D 0x5593 # 0 +0xD86E 0x5588 # 0 +0xD86F 0x558F # 0 +0xD870 0x55B5 # 0 +0xD871 0x5581 # 0 +0xD872 0x55A3 # 0 +0xD873 0x5592 # 0 +0xD874 0x55A4 # 0 +0xD875 0x557D # 0 +0xD876 0x558C # 0 +0xD877 0x55A6 # 0 +0xD878 0x557F # 0 +0xD879 0x5595 # 0 +0xD87A 0x55A1 # 0 +0xD87B 0x558E # 0 +0xD87C 0x570C # 0 +0xD87D 0x5829 # 0 +0xD87E 0x5837 # 0 +0xD8A1 0x5819 # 0 +0xD8A2 0x581E # 0 +0xD8A3 0x5827 # 0 +0xD8A4 0x5823 # 0 +0xD8A5 0x5828 # 0 +0xD8A6 0x57F5 # 0 +0xD8A7 0x5848 # 0 +0xD8A8 0x5825 # 0 +0xD8A9 0x581C # 0 +0xD8AA 0x581B # 0 +0xD8AB 0x5833 # 0 +0xD8AC 0x583F # 0 +0xD8AD 0x5836 # 0 +0xD8AE 0x582E # 0 +0xD8AF 0x5839 # 0 +0xD8B0 0x5838 # 0 +0xD8B1 0x582D # 0 +0xD8B2 0x582C # 0 +0xD8B3 0x583B # 0 +0xD8B4 0x5961 # 0 +0xD8B5 0x5AAF # 0 +0xD8B6 0x5A94 # 0 +0xD8B7 0x5A9F # 0 +0xD8B8 0x5A7A # 0 +0xD8B9 0x5AA2 # 0 +0xD8BA 0x5A9E # 0 +0xD8BB 0x5A78 # 0 +0xD8BC 0x5AA6 # 0 +0xD8BD 0x5A7C # 0 +0xD8BE 0x5AA5 # 0 +0xD8BF 0x5AAC # 0 +0xD8C0 0x5A95 # 0 +0xD8C1 0x5AAE # 0 +0xD8C2 0x5A37 # 0 +0xD8C3 0x5A84 # 0 +0xD8C4 0x5A8A # 0 +0xD8C5 0x5A97 # 0 +0xD8C6 0x5A83 # 0 +0xD8C7 0x5A8B # 0 +0xD8C8 0x5AA9 # 0 +0xD8C9 0x5A7B # 0 +0xD8CA 0x5A7D # 0 +0xD8CB 0x5A8C # 0 +0xD8CC 0x5A9C # 0 +0xD8CD 0x5A8F # 0 +0xD8CE 0x5A93 # 0 +0xD8CF 0x5A9D # 0 +0xD8D0 0x5BEA # 0 +0xD8D1 0x5BCD # 0 +0xD8D2 0x5BCB # 0 +0xD8D3 0x5BD4 # 0 +0xD8D4 0x5BD1 # 0 +0xD8D5 0x5BCA # 0 +0xD8D6 0x5BCE # 0 +0xD8D7 0x5C0C # 0 +0xD8D8 0x5C30 # 0 +0xD8D9 0x5D37 # 0 +0xD8DA 0x5D43 # 0 +0xD8DB 0x5D6B # 0 +0xD8DC 0x5D41 # 0 +0xD8DD 0x5D4B # 0 +0xD8DE 0x5D3F # 0 +0xD8DF 0x5D35 # 0 +0xD8E0 0x5D51 # 0 +0xD8E1 0x5D4E # 0 +0xD8E2 0x5D55 # 0 +0xD8E3 0x5D33 # 0 +0xD8E4 0x5D3A # 0 +0xD8E5 0x5D52 # 0 +0xD8E6 0x5D3D # 0 +0xD8E7 0x5D31 # 0 +0xD8E8 0x5D59 # 0 +0xD8E9 0x5D42 # 0 +0xD8EA 0x5D39 # 0 +0xD8EB 0x5D49 # 0 +0xD8EC 0x5D38 # 0 +0xD8ED 0x5D3C # 0 +0xD8EE 0x5D32 # 0 +0xD8EF 0x5D36 # 0 +0xD8F0 0x5D40 # 0 +0xD8F1 0x5D45 # 0 +0xD8F2 0x5E44 # 0 +0xD8F3 0x5E41 # 0 +0xD8F4 0x5F58 # 0 +0xD8F5 0x5FA6 # 0 +0xD8F6 0x5FA5 # 0 +0xD8F7 0x5FAB # 0 +0xD8F8 0x60C9 # 0 +0xD8F9 0x60B9 # 0 +0xD8FA 0x60CC # 0 +0xD8FB 0x60E2 # 0 +0xD8FC 0x60CE # 0 +0xD8FD 0x60C4 # 0 +0xD8FE 0x6114 # 0 +0xD940 0x60F2 # 0 +0xD941 0x610A # 0 +0xD942 0x6116 # 0 +0xD943 0x6105 # 0 +0xD944 0x60F5 # 0 +0xD945 0x6113 # 0 +0xD946 0x60F8 # 0 +0xD947 0x60FC # 0 +0xD948 0x60FE # 0 +0xD949 0x60C1 # 0 +0xD94A 0x6103 # 0 +0xD94B 0x6118 # 0 +0xD94C 0x611D # 0 +0xD94D 0x6110 # 0 +0xD94E 0x60FF # 0 +0xD94F 0x6104 # 0 +0xD950 0x610B # 0 +0xD951 0x624A # 0 +0xD952 0x6394 # 0 +0xD953 0x63B1 # 0 +0xD954 0x63B0 # 0 +0xD955 0x63CE # 0 +0xD956 0x63E5 # 0 +0xD957 0x63E8 # 0 +0xD958 0x63EF # 0 +0xD959 0x63C3 # 0 +0xD95A 0x649D # 0 +0xD95B 0x63F3 # 0 +0xD95C 0x63CA # 0 +0xD95D 0x63E0 # 0 +0xD95E 0x63F6 # 0 +0xD95F 0x63D5 # 0 +0xD960 0x63F2 # 0 +0xD961 0x63F5 # 0 +0xD962 0x6461 # 0 +0xD963 0x63DF # 0 +0xD964 0x63BE # 0 +0xD965 0x63DD # 0 +0xD966 0x63DC # 0 +0xD967 0x63C4 # 0 +0xD968 0x63D8 # 0 +0xD969 0x63D3 # 0 +0xD96A 0x63C2 # 0 +0xD96B 0x63C7 # 0 +0xD96C 0x63CC # 0 +0xD96D 0x63CB # 0 +0xD96E 0x63C8 # 0 +0xD96F 0x63F0 # 0 +0xD970 0x63D7 # 0 +0xD971 0x63D9 # 0 +0xD972 0x6532 # 0 +0xD973 0x6567 # 0 +0xD974 0x656A # 0 +0xD975 0x6564 # 0 +0xD976 0x655C # 0 +0xD977 0x6568 # 0 +0xD978 0x6565 # 0 +0xD979 0x658C # 0 +0xD97A 0x659D # 0 +0xD97B 0x659E # 0 +0xD97C 0x65AE # 0 +0xD97D 0x65D0 # 0 +0xD97E 0x65D2 # 0 +0xD9A1 0x667C # 0 +0xD9A2 0x666C # 0 +0xD9A3 0x667B # 0 +0xD9A4 0x6680 # 0 +0xD9A5 0x6671 # 0 +0xD9A6 0x6679 # 0 +0xD9A7 0x666A # 0 +0xD9A8 0x6672 # 0 +0xD9A9 0x6701 # 0 +0xD9AA 0x690C # 0 +0xD9AB 0x68D3 # 0 +0xD9AC 0x6904 # 0 +0xD9AD 0x68DC # 0 +0xD9AE 0x692A # 0 +0xD9AF 0x68EC # 0 +0xD9B0 0x68EA # 0 +0xD9B1 0x68F1 # 0 +0xD9B2 0x690F # 0 +0xD9B3 0x68D6 # 0 +0xD9B4 0x68F7 # 0 +0xD9B5 0x68EB # 0 +0xD9B6 0x68E4 # 0 +0xD9B7 0x68F6 # 0 +0xD9B8 0x6913 # 0 +0xD9B9 0x6910 # 0 +0xD9BA 0x68F3 # 0 +0xD9BB 0x68E1 # 0 +0xD9BC 0x6907 # 0 +0xD9BD 0x68CC # 0 +0xD9BE 0x6908 # 0 +0xD9BF 0x6970 # 0 +0xD9C0 0x68B4 # 0 +0xD9C1 0x6911 # 0 +0xD9C2 0x68EF # 0 +0xD9C3 0x68C6 # 0 +0xD9C4 0x6914 # 0 +0xD9C5 0x68F8 # 0 +0xD9C6 0x68D0 # 0 +0xD9C7 0x68FD # 0 +0xD9C8 0x68FC # 0 +0xD9C9 0x68E8 # 0 +0xD9CA 0x690B # 0 +0xD9CB 0x690A # 0 +0xD9CC 0x6917 # 0 +0xD9CD 0x68CE # 0 +0xD9CE 0x68C8 # 0 +0xD9CF 0x68DD # 0 +0xD9D0 0x68DE # 0 +0xD9D1 0x68E6 # 0 +0xD9D2 0x68F4 # 0 +0xD9D3 0x68D1 # 0 +0xD9D4 0x6906 # 0 +0xD9D5 0x68D4 # 0 +0xD9D6 0x68E9 # 0 +0xD9D7 0x6915 # 0 +0xD9D8 0x6925 # 0 +0xD9D9 0x68C7 # 0 +0xD9DA 0x6B39 # 0 +0xD9DB 0x6B3B # 0 +0xD9DC 0x6B3F # 0 +0xD9DD 0x6B3C # 0 +0xD9DE 0x6B94 # 0 +0xD9DF 0x6B97 # 0 +0xD9E0 0x6B99 # 0 +0xD9E1 0x6B95 # 0 +0xD9E2 0x6BBD # 0 +0xD9E3 0x6BF0 # 0 +0xD9E4 0x6BF2 # 0 +0xD9E5 0x6BF3 # 0 +0xD9E6 0x6C30 # 0 +0xD9E7 0x6DFC # 0 +0xD9E8 0x6E46 # 0 +0xD9E9 0x6E47 # 0 +0xD9EA 0x6E1F # 0 +0xD9EB 0x6E49 # 0 +0xD9EC 0x6E88 # 0 +0xD9ED 0x6E3C # 0 +0xD9EE 0x6E3D # 0 +0xD9EF 0x6E45 # 0 +0xD9F0 0x6E62 # 0 +0xD9F1 0x6E2B # 0 +0xD9F2 0x6E3F # 0 +0xD9F3 0x6E41 # 0 +0xD9F4 0x6E5D # 0 +0xD9F5 0x6E73 # 0 +0xD9F6 0x6E1C # 0 +0xD9F7 0x6E33 # 0 +0xD9F8 0x6E4B # 0 +0xD9F9 0x6E40 # 0 +0xD9FA 0x6E51 # 0 +0xD9FB 0x6E3B # 0 +0xD9FC 0x6E03 # 0 +0xD9FD 0x6E2E # 0 +0xD9FE 0x6E5E # 0 +0xDA40 0x6E68 # 0 +0xDA41 0x6E5C # 0 +0xDA42 0x6E61 # 0 +0xDA43 0x6E31 # 0 +0xDA44 0x6E28 # 0 +0xDA45 0x6E60 # 0 +0xDA46 0x6E71 # 0 +0xDA47 0x6E6B # 0 +0xDA48 0x6E39 # 0 +0xDA49 0x6E22 # 0 +0xDA4A 0x6E30 # 0 +0xDA4B 0x6E53 # 0 +0xDA4C 0x6E65 # 0 +0xDA4D 0x6E27 # 0 +0xDA4E 0x6E78 # 0 +0xDA4F 0x6E64 # 0 +0xDA50 0x6E77 # 0 +0xDA51 0x6E55 # 0 +0xDA52 0x6E79 # 0 +0xDA53 0x6E52 # 0 +0xDA54 0x6E66 # 0 +0xDA55 0x6E35 # 0 +0xDA56 0x6E36 # 0 +0xDA57 0x6E5A # 0 +0xDA58 0x7120 # 0 +0xDA59 0x711E # 0 +0xDA5A 0x712F # 0 +0xDA5B 0x70FB # 0 +0xDA5C 0x712E # 0 +0xDA5D 0x7131 # 0 +0xDA5E 0x7123 # 0 +0xDA5F 0x7125 # 0 +0xDA60 0x7122 # 0 +0xDA61 0x7132 # 0 +0xDA62 0x711F # 0 +0xDA63 0x7128 # 0 +0xDA64 0x713A # 0 +0xDA65 0x711B # 0 +0xDA66 0x724B # 0 +0xDA67 0x725A # 0 +0xDA68 0x7288 # 0 +0xDA69 0x7289 # 0 +0xDA6A 0x7286 # 0 +0xDA6B 0x7285 # 0 +0xDA6C 0x728B # 0 +0xDA6D 0x7312 # 0 +0xDA6E 0x730B # 0 +0xDA6F 0x7330 # 0 +0xDA70 0x7322 # 0 +0xDA71 0x7331 # 0 +0xDA72 0x7333 # 0 +0xDA73 0x7327 # 0 +0xDA74 0x7332 # 0 +0xDA75 0x732D # 0 +0xDA76 0x7326 # 0 +0xDA77 0x7323 # 0 +0xDA78 0x7335 # 0 +0xDA79 0x730C # 0 +0xDA7A 0x742E # 0 +0xDA7B 0x742C # 0 +0xDA7C 0x7430 # 0 +0xDA7D 0x742B # 0 +0xDA7E 0x7416 # 0 +0xDAA1 0x741A # 0 +0xDAA2 0x7421 # 0 +0xDAA3 0x742D # 0 +0xDAA4 0x7431 # 0 +0xDAA5 0x7424 # 0 +0xDAA6 0x7423 # 0 +0xDAA7 0x741D # 0 +0xDAA8 0x7429 # 0 +0xDAA9 0x7420 # 0 +0xDAAA 0x7432 # 0 +0xDAAB 0x74FB # 0 +0xDAAC 0x752F # 0 +0xDAAD 0x756F # 0 +0xDAAE 0x756C # 0 +0xDAAF 0x75E7 # 0 +0xDAB0 0x75DA # 0 +0xDAB1 0x75E1 # 0 +0xDAB2 0x75E6 # 0 +0xDAB3 0x75DD # 0 +0xDAB4 0x75DF # 0 +0xDAB5 0x75E4 # 0 +0xDAB6 0x75D7 # 0 +0xDAB7 0x7695 # 0 +0xDAB8 0x7692 # 0 +0xDAB9 0x76DA # 0 +0xDABA 0x7746 # 0 +0xDABB 0x7747 # 0 +0xDABC 0x7744 # 0 +0xDABD 0x774D # 0 +0xDABE 0x7745 # 0 +0xDABF 0x774A # 0 +0xDAC0 0x774E # 0 +0xDAC1 0x774B # 0 +0xDAC2 0x774C # 0 +0xDAC3 0x77DE # 0 +0xDAC4 0x77EC # 0 +0xDAC5 0x7860 # 0 +0xDAC6 0x7864 # 0 +0xDAC7 0x7865 # 0 +0xDAC8 0x785C # 0 +0xDAC9 0x786D # 0 +0xDACA 0x7871 # 0 +0xDACB 0x786A # 0 +0xDACC 0x786E # 0 +0xDACD 0x7870 # 0 +0xDACE 0x7869 # 0 +0xDACF 0x7868 # 0 +0xDAD0 0x785E # 0 +0xDAD1 0x7862 # 0 +0xDAD2 0x7974 # 0 +0xDAD3 0x7973 # 0 +0xDAD4 0x7972 # 0 +0xDAD5 0x7970 # 0 +0xDAD6 0x7A02 # 0 +0xDAD7 0x7A0A # 0 +0xDAD8 0x7A03 # 0 +0xDAD9 0x7A0C # 0 +0xDADA 0x7A04 # 0 +0xDADB 0x7A99 # 0 +0xDADC 0x7AE6 # 0 +0xDADD 0x7AE4 # 0 +0xDADE 0x7B4A # 0 +0xDADF 0x7B3B # 0 +0xDAE0 0x7B44 # 0 +0xDAE1 0x7B48 # 0 +0xDAE2 0x7B4C # 0 +0xDAE3 0x7B4E # 0 +0xDAE4 0x7B40 # 0 +0xDAE5 0x7B58 # 0 +0xDAE6 0x7B45 # 0 +0xDAE7 0x7CA2 # 0 +0xDAE8 0x7C9E # 0 +0xDAE9 0x7CA8 # 0 +0xDAEA 0x7CA1 # 0 +0xDAEB 0x7D58 # 0 +0xDAEC 0x7D6F # 0 +0xDAED 0x7D63 # 0 +0xDAEE 0x7D53 # 0 +0xDAEF 0x7D56 # 0 +0xDAF0 0x7D67 # 0 +0xDAF1 0x7D6A # 0 +0xDAF2 0x7D4F # 0 +0xDAF3 0x7D6D # 0 +0xDAF4 0x7D5C # 0 +0xDAF5 0x7D6B # 0 +0xDAF6 0x7D52 # 0 +0xDAF7 0x7D54 # 0 +0xDAF8 0x7D69 # 0 +0xDAF9 0x7D51 # 0 +0xDAFA 0x7D5F # 0 +0xDAFB 0x7D4E # 0 +0xDAFC 0x7F3E # 0 +0xDAFD 0x7F3F # 0 +0xDAFE 0x7F65 # 0 +0xDB40 0x7F66 # 0 +0xDB41 0x7FA2 # 0 +0xDB42 0x7FA0 # 0 +0xDB43 0x7FA1 # 0 +0xDB44 0x7FD7 # 0 +0xDB45 0x8051 # 0 +0xDB46 0x804F # 0 +0xDB47 0x8050 # 0 +0xDB48 0x80FE # 0 +0xDB49 0x80D4 # 0 +0xDB4A 0x8143 # 0 +0xDB4B 0x814A # 0 +0xDB4C 0x8152 # 0 +0xDB4D 0x814F # 0 +0xDB4E 0x8147 # 0 +0xDB4F 0x813D # 0 +0xDB50 0x814D # 0 +0xDB51 0x813A # 0 +0xDB52 0x81E6 # 0 +0xDB53 0x81EE # 0 +0xDB54 0x81F7 # 0 +0xDB55 0x81F8 # 0 +0xDB56 0x81F9 # 0 +0xDB57 0x8204 # 0 +0xDB58 0x823C # 0 +0xDB59 0x823D # 0 +0xDB5A 0x823F # 0 +0xDB5B 0x8275 # 0 +0xDB5C 0x833B # 0 +0xDB5D 0x83CF # 0 +0xDB5E 0x83F9 # 0 +0xDB5F 0x8423 # 0 +0xDB60 0x83C0 # 0 +0xDB61 0x83E8 # 0 +0xDB62 0x8412 # 0 +0xDB63 0x83E7 # 0 +0xDB64 0x83E4 # 0 +0xDB65 0x83FC # 0 +0xDB66 0x83F6 # 0 +0xDB67 0x8410 # 0 +0xDB68 0x83C6 # 0 +0xDB69 0x83C8 # 0 +0xDB6A 0x83EB # 0 +0xDB6B 0x83E3 # 0 +0xDB6C 0x83BF # 0 +0xDB6D 0x8401 # 0 +0xDB6E 0x83DD # 0 +0xDB6F 0x83E5 # 0 +0xDB70 0x83D8 # 0 +0xDB71 0x83FF # 0 +0xDB72 0x83E1 # 0 +0xDB73 0x83CB # 0 +0xDB74 0x83CE # 0 +0xDB75 0x83D6 # 0 +0xDB76 0x83F5 # 0 +0xDB77 0x83C9 # 0 +0xDB78 0x8409 # 0 +0xDB79 0x840F # 0 +0xDB7A 0x83DE # 0 +0xDB7B 0x8411 # 0 +0xDB7C 0x8406 # 0 +0xDB7D 0x83C2 # 0 +0xDB7E 0x83F3 # 0 +0xDBA1 0x83D5 # 0 +0xDBA2 0x83FA # 0 +0xDBA3 0x83C7 # 0 +0xDBA4 0x83D1 # 0 +0xDBA5 0x83EA # 0 +0xDBA6 0x8413 # 0 +0xDBA7 0x83C3 # 0 +0xDBA8 0x83EC # 0 +0xDBA9 0x83EE # 0 +0xDBAA 0x83C4 # 0 +0xDBAB 0x83FB # 0 +0xDBAC 0x83D7 # 0 +0xDBAD 0x83E2 # 0 +0xDBAE 0x841B # 0 +0xDBAF 0x83DB # 0 +0xDBB0 0x83FE # 0 +0xDBB1 0x86D8 # 0 +0xDBB2 0x86E2 # 0 +0xDBB3 0x86E6 # 0 +0xDBB4 0x86D3 # 0 +0xDBB5 0x86E3 # 0 +0xDBB6 0x86DA # 0 +0xDBB7 0x86EA # 0 +0xDBB8 0x86DD # 0 +0xDBB9 0x86EB # 0 +0xDBBA 0x86DC # 0 +0xDBBB 0x86EC # 0 +0xDBBC 0x86E9 # 0 +0xDBBD 0x86D7 # 0 +0xDBBE 0x86E8 # 0 +0xDBBF 0x86D1 # 0 +0xDBC0 0x8848 # 0 +0xDBC1 0x8856 # 0 +0xDBC2 0x8855 # 0 +0xDBC3 0x88BA # 0 +0xDBC4 0x88D7 # 0 +0xDBC5 0x88B9 # 0 +0xDBC6 0x88B8 # 0 +0xDBC7 0x88C0 # 0 +0xDBC8 0x88BE # 0 +0xDBC9 0x88B6 # 0 +0xDBCA 0x88BC # 0 +0xDBCB 0x88B7 # 0 +0xDBCC 0x88BD # 0 +0xDBCD 0x88B2 # 0 +0xDBCE 0x8901 # 0 +0xDBCF 0x88C9 # 0 +0xDBD0 0x8995 # 0 +0xDBD1 0x8998 # 0 +0xDBD2 0x8997 # 0 +0xDBD3 0x89DD # 0 +0xDBD4 0x89DA # 0 +0xDBD5 0x89DB # 0 +0xDBD6 0x8A4E # 0 +0xDBD7 0x8A4D # 0 +0xDBD8 0x8A39 # 0 +0xDBD9 0x8A59 # 0 +0xDBDA 0x8A40 # 0 +0xDBDB 0x8A57 # 0 +0xDBDC 0x8A58 # 0 +0xDBDD 0x8A44 # 0 +0xDBDE 0x8A45 # 0 +0xDBDF 0x8A52 # 0 +0xDBE0 0x8A48 # 0 +0xDBE1 0x8A51 # 0 +0xDBE2 0x8A4A # 0 +0xDBE3 0x8A4C # 0 +0xDBE4 0x8A4F # 0 +0xDBE5 0x8C5F # 0 +0xDBE6 0x8C81 # 0 +0xDBE7 0x8C80 # 0 +0xDBE8 0x8CBA # 0 +0xDBE9 0x8CBE # 0 +0xDBEA 0x8CB0 # 0 +0xDBEB 0x8CB9 # 0 +0xDBEC 0x8CB5 # 0 +0xDBED 0x8D84 # 0 +0xDBEE 0x8D80 # 0 +0xDBEF 0x8D89 # 0 +0xDBF0 0x8DD8 # 0 +0xDBF1 0x8DD3 # 0 +0xDBF2 0x8DCD # 0 +0xDBF3 0x8DC7 # 0 +0xDBF4 0x8DD6 # 0 +0xDBF5 0x8DDC # 0 +0xDBF6 0x8DCF # 0 +0xDBF7 0x8DD5 # 0 +0xDBF8 0x8DD9 # 0 +0xDBF9 0x8DC8 # 0 +0xDBFA 0x8DD7 # 0 +0xDBFB 0x8DC5 # 0 +0xDBFC 0x8EEF # 0 +0xDBFD 0x8EF7 # 0 +0xDBFE 0x8EFA # 0 +0xDC40 0x8EF9 # 0 +0xDC41 0x8EE6 # 0 +0xDC42 0x8EEE # 0 +0xDC43 0x8EE5 # 0 +0xDC44 0x8EF5 # 0 +0xDC45 0x8EE7 # 0 +0xDC46 0x8EE8 # 0 +0xDC47 0x8EF6 # 0 +0xDC48 0x8EEB # 0 +0xDC49 0x8EF1 # 0 +0xDC4A 0x8EEC # 0 +0xDC4B 0x8EF4 # 0 +0xDC4C 0x8EE9 # 0 +0xDC4D 0x902D # 0 +0xDC4E 0x9034 # 0 +0xDC4F 0x902F # 0 +0xDC50 0x9106 # 0 +0xDC51 0x912C # 0 +0xDC52 0x9104 # 0 +0xDC53 0x90FF # 0 +0xDC54 0x90FC # 0 +0xDC55 0x9108 # 0 +0xDC56 0x90F9 # 0 +0xDC57 0x90FB # 0 +0xDC58 0x9101 # 0 +0xDC59 0x9100 # 0 +0xDC5A 0x9107 # 0 +0xDC5B 0x9105 # 0 +0xDC5C 0x9103 # 0 +0xDC5D 0x9161 # 0 +0xDC5E 0x9164 # 0 +0xDC5F 0x915F # 0 +0xDC60 0x9162 # 0 +0xDC61 0x9160 # 0 +0xDC62 0x9201 # 0 +0xDC63 0x920A # 0 +0xDC64 0x9225 # 0 +0xDC65 0x9203 # 0 +0xDC66 0x921A # 0 +0xDC67 0x9226 # 0 +0xDC68 0x920F # 0 +0xDC69 0x920C # 0 +0xDC6A 0x9200 # 0 +0xDC6B 0x9212 # 0 +0xDC6C 0x91FF # 0 +0xDC6D 0x91FD # 0 +0xDC6E 0x9206 # 0 +0xDC6F 0x9204 # 0 +0xDC70 0x9227 # 0 +0xDC71 0x9202 # 0 +0xDC72 0x921C # 0 +0xDC73 0x9224 # 0 +0xDC74 0x9219 # 0 +0xDC75 0x9217 # 0 +0xDC76 0x9205 # 0 +0xDC77 0x9216 # 0 +0xDC78 0x957B # 0 +0xDC79 0x958D # 0 +0xDC7A 0x958C # 0 +0xDC7B 0x9590 # 0 +0xDC7C 0x9687 # 0 +0xDC7D 0x967E # 0 +0xDC7E 0x9688 # 0 +0xDCA1 0x9689 # 0 +0xDCA2 0x9683 # 0 +0xDCA3 0x9680 # 0 +0xDCA4 0x96C2 # 0 +0xDCA5 0x96C8 # 0 +0xDCA6 0x96C3 # 0 +0xDCA7 0x96F1 # 0 +0xDCA8 0x96F0 # 0 +0xDCA9 0x976C # 0 +0xDCAA 0x9770 # 0 +0xDCAB 0x976E # 0 +0xDCAC 0x9807 # 0 +0xDCAD 0x98A9 # 0 +0xDCAE 0x98EB # 0 +0xDCAF 0x9CE6 # 0 +0xDCB0 0x9EF9 # 0 +0xDCB1 0x4E83 # 0 +0xDCB2 0x4E84 # 0 +0xDCB3 0x4EB6 # 0 +0xDCB4 0x50BD # 0 +0xDCB5 0x50BF # 0 +0xDCB6 0x50C6 # 0 +0xDCB7 0x50AE # 0 +0xDCB8 0x50C4 # 0 +0xDCB9 0x50CA # 0 +0xDCBA 0x50B4 # 0 +0xDCBB 0x50C8 # 0 +0xDCBC 0x50C2 # 0 +0xDCBD 0x50B0 # 0 +0xDCBE 0x50C1 # 0 +0xDCBF 0x50BA # 0 +0xDCC0 0x50B1 # 0 +0xDCC1 0x50CB # 0 +0xDCC2 0x50C9 # 0 +0xDCC3 0x50B6 # 0 +0xDCC4 0x50B8 # 0 +0xDCC5 0x51D7 # 0 +0xDCC6 0x527A # 0 +0xDCC7 0x5278 # 0 +0xDCC8 0x527B # 0 +0xDCC9 0x527C # 0 +0xDCCA 0x55C3 # 0 +0xDCCB 0x55DB # 0 +0xDCCC 0x55CC # 0 +0xDCCD 0x55D0 # 0 +0xDCCE 0x55CB # 0 +0xDCCF 0x55CA # 0 +0xDCD0 0x55DD # 0 +0xDCD1 0x55C0 # 0 +0xDCD2 0x55D4 # 0 +0xDCD3 0x55C4 # 0 +0xDCD4 0x55E9 # 0 +0xDCD5 0x55BF # 0 +0xDCD6 0x55D2 # 0 +0xDCD7 0x558D # 0 +0xDCD8 0x55CF # 0 +0xDCD9 0x55D5 # 0 +0xDCDA 0x55E2 # 0 +0xDCDB 0x55D6 # 0 +0xDCDC 0x55C8 # 0 +0xDCDD 0x55F2 # 0 +0xDCDE 0x55CD # 0 +0xDCDF 0x55D9 # 0 +0xDCE0 0x55C2 # 0 +0xDCE1 0x5714 # 0 +0xDCE2 0x5853 # 0 +0xDCE3 0x5868 # 0 +0xDCE4 0x5864 # 0 +0xDCE5 0x584F # 0 +0xDCE6 0x584D # 0 +0xDCE7 0x5849 # 0 +0xDCE8 0x586F # 0 +0xDCE9 0x5855 # 0 +0xDCEA 0x584E # 0 +0xDCEB 0x585D # 0 +0xDCEC 0x5859 # 0 +0xDCED 0x5865 # 0 +0xDCEE 0x585B # 0 +0xDCEF 0x583D # 0 +0xDCF0 0x5863 # 0 +0xDCF1 0x5871 # 0 +0xDCF2 0x58FC # 0 +0xDCF3 0x5AC7 # 0 +0xDCF4 0x5AC4 # 0 +0xDCF5 0x5ACB # 0 +0xDCF6 0x5ABA # 0 +0xDCF7 0x5AB8 # 0 +0xDCF8 0x5AB1 # 0 +0xDCF9 0x5AB5 # 0 +0xDCFA 0x5AB0 # 0 +0xDCFB 0x5ABF # 0 +0xDCFC 0x5AC8 # 0 +0xDCFD 0x5ABB # 0 +0xDCFE 0x5AC6 # 0 +0xDD40 0x5AB7 # 0 +0xDD41 0x5AC0 # 0 +0xDD42 0x5ACA # 0 +0xDD43 0x5AB4 # 0 +0xDD44 0x5AB6 # 0 +0xDD45 0x5ACD # 0 +0xDD46 0x5AB9 # 0 +0xDD47 0x5A90 # 0 +0xDD48 0x5BD6 # 0 +0xDD49 0x5BD8 # 0 +0xDD4A 0x5BD9 # 0 +0xDD4B 0x5C1F # 0 +0xDD4C 0x5C33 # 0 +0xDD4D 0x5D71 # 0 +0xDD4E 0x5D63 # 0 +0xDD4F 0x5D4A # 0 +0xDD50 0x5D65 # 0 +0xDD51 0x5D72 # 0 +0xDD52 0x5D6C # 0 +0xDD53 0x5D5E # 0 +0xDD54 0x5D68 # 0 +0xDD55 0x5D67 # 0 +0xDD56 0x5D62 # 0 +0xDD57 0x5DF0 # 0 +0xDD58 0x5E4F # 0 +0xDD59 0x5E4E # 0 +0xDD5A 0x5E4A # 0 +0xDD5B 0x5E4D # 0 +0xDD5C 0x5E4B # 0 +0xDD5D 0x5EC5 # 0 +0xDD5E 0x5ECC # 0 +0xDD5F 0x5EC6 # 0 +0xDD60 0x5ECB # 0 +0xDD61 0x5EC7 # 0 +0xDD62 0x5F40 # 0 +0xDD63 0x5FAF # 0 +0xDD64 0x5FAD # 0 +0xDD65 0x60F7 # 0 +0xDD66 0x6149 # 0 +0xDD67 0x614A # 0 +0xDD68 0x612B # 0 +0xDD69 0x6145 # 0 +0xDD6A 0x6136 # 0 +0xDD6B 0x6132 # 0 +0xDD6C 0x612E # 0 +0xDD6D 0x6146 # 0 +0xDD6E 0x612F # 0 +0xDD6F 0x614F # 0 +0xDD70 0x6129 # 0 +0xDD71 0x6140 # 0 +0xDD72 0x6220 # 0 +0xDD73 0x9168 # 0 +0xDD74 0x6223 # 0 +0xDD75 0x6225 # 0 +0xDD76 0x6224 # 0 +0xDD77 0x63C5 # 0 +0xDD78 0x63F1 # 0 +0xDD79 0x63EB # 0 +0xDD7A 0x6410 # 0 +0xDD7B 0x6412 # 0 +0xDD7C 0x6409 # 0 +0xDD7D 0x6420 # 0 +0xDD7E 0x6424 # 0 +0xDDA1 0x6433 # 0 +0xDDA2 0x6443 # 0 +0xDDA3 0x641F # 0 +0xDDA4 0x6415 # 0 +0xDDA5 0x6418 # 0 +0xDDA6 0x6439 # 0 +0xDDA7 0x6437 # 0 +0xDDA8 0x6422 # 0 +0xDDA9 0x6423 # 0 +0xDDAA 0x640C # 0 +0xDDAB 0x6426 # 0 +0xDDAC 0x6430 # 0 +0xDDAD 0x6428 # 0 +0xDDAE 0x6441 # 0 +0xDDAF 0x6435 # 0 +0xDDB0 0x642F # 0 +0xDDB1 0x640A # 0 +0xDDB2 0x641A # 0 +0xDDB3 0x6440 # 0 +0xDDB4 0x6425 # 0 +0xDDB5 0x6427 # 0 +0xDDB6 0x640B # 0 +0xDDB7 0x63E7 # 0 +0xDDB8 0x641B # 0 +0xDDB9 0x642E # 0 +0xDDBA 0x6421 # 0 +0xDDBB 0x640E # 0 +0xDDBC 0x656F # 0 +0xDDBD 0x6592 # 0 +0xDDBE 0x65D3 # 0 +0xDDBF 0x6686 # 0 +0xDDC0 0x668C # 0 +0xDDC1 0x6695 # 0 +0xDDC2 0x6690 # 0 +0xDDC3 0x668B # 0 +0xDDC4 0x668A # 0 +0xDDC5 0x6699 # 0 +0xDDC6 0x6694 # 0 +0xDDC7 0x6678 # 0 +0xDDC8 0x6720 # 0 +0xDDC9 0x6966 # 0 +0xDDCA 0x695F # 0 +0xDDCB 0x6938 # 0 +0xDDCC 0x694E # 0 +0xDDCD 0x6962 # 0 +0xDDCE 0x6971 # 0 +0xDDCF 0x693F # 0 +0xDDD0 0x6945 # 0 +0xDDD1 0x696A # 0 +0xDDD2 0x6939 # 0 +0xDDD3 0x6942 # 0 +0xDDD4 0x6957 # 0 +0xDDD5 0x6959 # 0 +0xDDD6 0x697A # 0 +0xDDD7 0x6948 # 0 +0xDDD8 0x6949 # 0 +0xDDD9 0x6935 # 0 +0xDDDA 0x696C # 0 +0xDDDB 0x6933 # 0 +0xDDDC 0x693D # 0 +0xDDDD 0x6965 # 0 +0xDDDE 0x68F0 # 0 +0xDDDF 0x6978 # 0 +0xDDE0 0x6934 # 0 +0xDDE1 0x6969 # 0 +0xDDE2 0x6940 # 0 +0xDDE3 0x696F # 0 +0xDDE4 0x6944 # 0 +0xDDE5 0x6976 # 0 +0xDDE6 0x6958 # 0 +0xDDE7 0x6941 # 0 +0xDDE8 0x6974 # 0 +0xDDE9 0x694C # 0 +0xDDEA 0x693B # 0 +0xDDEB 0x694B # 0 +0xDDEC 0x6937 # 0 +0xDDED 0x695C # 0 +0xDDEE 0x694F # 0 +0xDDEF 0x6951 # 0 +0xDDF0 0x6932 # 0 +0xDDF1 0x6952 # 0 +0xDDF2 0x692F # 0 +0xDDF3 0x697B # 0 +0xDDF4 0x693C # 0 +0xDDF5 0x6B46 # 0 +0xDDF6 0x6B45 # 0 +0xDDF7 0x6B43 # 0 +0xDDF8 0x6B42 # 0 +0xDDF9 0x6B48 # 0 +0xDDFA 0x6B41 # 0 +0xDDFB 0x6B9B # 0 +0xDDFC 0xFA0D # 0 +0xDDFD 0x6BFB # 0 +0xDDFE 0x6BFC # 0 +0xDE40 0x6BF9 # 0 +0xDE41 0x6BF7 # 0 +0xDE42 0x6BF8 # 0 +0xDE43 0x6E9B # 0 +0xDE44 0x6ED6 # 0 +0xDE45 0x6EC8 # 0 +0xDE46 0x6E8F # 0 +0xDE47 0x6EC0 # 0 +0xDE48 0x6E9F # 0 +0xDE49 0x6E93 # 0 +0xDE4A 0x6E94 # 0 +0xDE4B 0x6EA0 # 0 +0xDE4C 0x6EB1 # 0 +0xDE4D 0x6EB9 # 0 +0xDE4E 0x6EC6 # 0 +0xDE4F 0x6ED2 # 0 +0xDE50 0x6EBD # 0 +0xDE51 0x6EC1 # 0 +0xDE52 0x6E9E # 0 +0xDE53 0x6EC9 # 0 +0xDE54 0x6EB7 # 0 +0xDE55 0x6EB0 # 0 +0xDE56 0x6ECD # 0 +0xDE57 0x6EA6 # 0 +0xDE58 0x6ECF # 0 +0xDE59 0x6EB2 # 0 +0xDE5A 0x6EBE # 0 +0xDE5B 0x6EC3 # 0 +0xDE5C 0x6EDC # 0 +0xDE5D 0x6ED8 # 0 +0xDE5E 0x6E99 # 0 +0xDE5F 0x6E92 # 0 +0xDE60 0x6E8E # 0 +0xDE61 0x6E8D # 0 +0xDE62 0x6EA4 # 0 +0xDE63 0x6EA1 # 0 +0xDE64 0x6EBF # 0 +0xDE65 0x6EB3 # 0 +0xDE66 0x6ED0 # 0 +0xDE67 0x6ECA # 0 +0xDE68 0x6E97 # 0 +0xDE69 0x6EAE # 0 +0xDE6A 0x6EA3 # 0 +0xDE6B 0x7147 # 0 +0xDE6C 0x7154 # 0 +0xDE6D 0x7152 # 0 +0xDE6E 0x7163 # 0 +0xDE6F 0x7160 # 0 +0xDE70 0x7141 # 0 +0xDE71 0x715D # 0 +0xDE72 0x7162 # 0 +0xDE73 0x7172 # 0 +0xDE74 0x7178 # 0 +0xDE75 0x716A # 0 +0xDE76 0x7161 # 0 +0xDE77 0x7142 # 0 +0xDE78 0x7158 # 0 +0xDE79 0x7143 # 0 +0xDE7A 0x714B # 0 +0xDE7B 0x7170 # 0 +0xDE7C 0x715F # 0 +0xDE7D 0x7150 # 0 +0xDE7E 0x7153 # 0 +0xDEA1 0x7144 # 0 +0xDEA2 0x714D # 0 +0xDEA3 0x715A # 0 +0xDEA4 0x724F # 0 +0xDEA5 0x728D # 0 +0xDEA6 0x728C # 0 +0xDEA7 0x7291 # 0 +0xDEA8 0x7290 # 0 +0xDEA9 0x728E # 0 +0xDEAA 0x733C # 0 +0xDEAB 0x7342 # 0 +0xDEAC 0x733B # 0 +0xDEAD 0x733A # 0 +0xDEAE 0x7340 # 0 +0xDEAF 0x734A # 0 +0xDEB0 0x7349 # 0 +0xDEB1 0x7444 # 0 +0xDEB2 0x744A # 0 +0xDEB3 0x744B # 0 +0xDEB4 0x7452 # 0 +0xDEB5 0x7451 # 0 +0xDEB6 0x7457 # 0 +0xDEB7 0x7440 # 0 +0xDEB8 0x744F # 0 +0xDEB9 0x7450 # 0 +0xDEBA 0x744E # 0 +0xDEBB 0x7442 # 0 +0xDEBC 0x7446 # 0 +0xDEBD 0x744D # 0 +0xDEBE 0x7454 # 0 +0xDEBF 0x74E1 # 0 +0xDEC0 0x74FF # 0 +0xDEC1 0x74FE # 0 +0xDEC2 0x74FD # 0 +0xDEC3 0x751D # 0 +0xDEC4 0x7579 # 0 +0xDEC5 0x7577 # 0 +0xDEC6 0x6983 # 0 +0xDEC7 0x75EF # 0 +0xDEC8 0x760F # 0 +0xDEC9 0x7603 # 0 +0xDECA 0x75F7 # 0 +0xDECB 0x75FE # 0 +0xDECC 0x75FC # 0 +0xDECD 0x75F9 # 0 +0xDECE 0x75F8 # 0 +0xDECF 0x7610 # 0 +0xDED0 0x75FB # 0 +0xDED1 0x75F6 # 0 +0xDED2 0x75ED # 0 +0xDED3 0x75F5 # 0 +0xDED4 0x75FD # 0 +0xDED5 0x7699 # 0 +0xDED6 0x76B5 # 0 +0xDED7 0x76DD # 0 +0xDED8 0x7755 # 0 +0xDED9 0x775F # 0 +0xDEDA 0x7760 # 0 +0xDEDB 0x7752 # 0 +0xDEDC 0x7756 # 0 +0xDEDD 0x775A # 0 +0xDEDE 0x7769 # 0 +0xDEDF 0x7767 # 0 +0xDEE0 0x7754 # 0 +0xDEE1 0x7759 # 0 +0xDEE2 0x776D # 0 +0xDEE3 0x77E0 # 0 +0xDEE4 0x7887 # 0 +0xDEE5 0x789A # 0 +0xDEE6 0x7894 # 0 +0xDEE7 0x788F # 0 +0xDEE8 0x7884 # 0 +0xDEE9 0x7895 # 0 +0xDEEA 0x7885 # 0 +0xDEEB 0x7886 # 0 +0xDEEC 0x78A1 # 0 +0xDEED 0x7883 # 0 +0xDEEE 0x7879 # 0 +0xDEEF 0x7899 # 0 +0xDEF0 0x7880 # 0 +0xDEF1 0x7896 # 0 +0xDEF2 0x787B # 0 +0xDEF3 0x797C # 0 +0xDEF4 0x7982 # 0 +0xDEF5 0x797D # 0 +0xDEF6 0x7979 # 0 +0xDEF7 0x7A11 # 0 +0xDEF8 0x7A18 # 0 +0xDEF9 0x7A19 # 0 +0xDEFA 0x7A12 # 0 +0xDEFB 0x7A17 # 0 +0xDEFC 0x7A15 # 0 +0xDEFD 0x7A22 # 0 +0xDEFE 0x7A13 # 0 +0xDF40 0x7A1B # 0 +0xDF41 0x7A10 # 0 +0xDF42 0x7AA3 # 0 +0xDF43 0x7AA2 # 0 +0xDF44 0x7A9E # 0 +0xDF45 0x7AEB # 0 +0xDF46 0x7B66 # 0 +0xDF47 0x7B64 # 0 +0xDF48 0x7B6D # 0 +0xDF49 0x7B74 # 0 +0xDF4A 0x7B69 # 0 +0xDF4B 0x7B72 # 0 +0xDF4C 0x7B65 # 0 +0xDF4D 0x7B73 # 0 +0xDF4E 0x7B71 # 0 +0xDF4F 0x7B70 # 0 +0xDF50 0x7B61 # 0 +0xDF51 0x7B78 # 0 +0xDF52 0x7B76 # 0 +0xDF53 0x7B63 # 0 +0xDF54 0x7CB2 # 0 +0xDF55 0x7CB4 # 0 +0xDF56 0x7CAF # 0 +0xDF57 0x7D88 # 0 +0xDF58 0x7D86 # 0 +0xDF59 0x7D80 # 0 +0xDF5A 0x7D8D # 0 +0xDF5B 0x7D7F # 0 +0xDF5C 0x7D85 # 0 +0xDF5D 0x7D7A # 0 +0xDF5E 0x7D8E # 0 +0xDF5F 0x7D7B # 0 +0xDF60 0x7D83 # 0 +0xDF61 0x7D7C # 0 +0xDF62 0x7D8C # 0 +0xDF63 0x7D94 # 0 +0xDF64 0x7D84 # 0 +0xDF65 0x7D7D # 0 +0xDF66 0x7D92 # 0 +0xDF67 0x7F6D # 0 +0xDF68 0x7F6B # 0 +0xDF69 0x7F67 # 0 +0xDF6A 0x7F68 # 0 +0xDF6B 0x7F6C # 0 +0xDF6C 0x7FA6 # 0 +0xDF6D 0x7FA5 # 0 +0xDF6E 0x7FA7 # 0 +0xDF6F 0x7FDB # 0 +0xDF70 0x7FDC # 0 +0xDF71 0x8021 # 0 +0xDF72 0x8164 # 0 +0xDF73 0x8160 # 0 +0xDF74 0x8177 # 0 +0xDF75 0x815C # 0 +0xDF76 0x8169 # 0 +0xDF77 0x815B # 0 +0xDF78 0x8162 # 0 +0xDF79 0x8172 # 0 +0xDF7A 0x6721 # 0 +0xDF7B 0x815E # 0 +0xDF7C 0x8176 # 0 +0xDF7D 0x8167 # 0 +0xDF7E 0x816F # 0 +0xDFA1 0x8144 # 0 +0xDFA2 0x8161 # 0 +0xDFA3 0x821D # 0 +0xDFA4 0x8249 # 0 +0xDFA5 0x8244 # 0 +0xDFA6 0x8240 # 0 +0xDFA7 0x8242 # 0 +0xDFA8 0x8245 # 0 +0xDFA9 0x84F1 # 0 +0xDFAA 0x843F # 0 +0xDFAB 0x8456 # 0 +0xDFAC 0x8476 # 0 +0xDFAD 0x8479 # 0 +0xDFAE 0x848F # 0 +0xDFAF 0x848D # 0 +0xDFB0 0x8465 # 0 +0xDFB1 0x8451 # 0 +0xDFB2 0x8440 # 0 +0xDFB3 0x8486 # 0 +0xDFB4 0x8467 # 0 +0xDFB5 0x8430 # 0 +0xDFB6 0x844D # 0 +0xDFB7 0x847D # 0 +0xDFB8 0x845A # 0 +0xDFB9 0x8459 # 0 +0xDFBA 0x8474 # 0 +0xDFBB 0x8473 # 0 +0xDFBC 0x845D # 0 +0xDFBD 0x8507 # 0 +0xDFBE 0x845E # 0 +0xDFBF 0x8437 # 0 +0xDFC0 0x843A # 0 +0xDFC1 0x8434 # 0 +0xDFC2 0x847A # 0 +0xDFC3 0x8443 # 0 +0xDFC4 0x8478 # 0 +0xDFC5 0x8432 # 0 +0xDFC6 0x8445 # 0 +0xDFC7 0x8429 # 0 +0xDFC8 0x83D9 # 0 +0xDFC9 0x844B # 0 +0xDFCA 0x842F # 0 +0xDFCB 0x8442 # 0 +0xDFCC 0x842D # 0 +0xDFCD 0x845F # 0 +0xDFCE 0x8470 # 0 +0xDFCF 0x8439 # 0 +0xDFD0 0x844E # 0 +0xDFD1 0x844C # 0 +0xDFD2 0x8452 # 0 +0xDFD3 0x846F # 0 +0xDFD4 0x84C5 # 0 +0xDFD5 0x848E # 0 +0xDFD6 0x843B # 0 +0xDFD7 0x8447 # 0 +0xDFD8 0x8436 # 0 +0xDFD9 0x8433 # 0 +0xDFDA 0x8468 # 0 +0xDFDB 0x847E # 0 +0xDFDC 0x8444 # 0 +0xDFDD 0x842B # 0 +0xDFDE 0x8460 # 0 +0xDFDF 0x8454 # 0 +0xDFE0 0x846E # 0 +0xDFE1 0x8450 # 0 +0xDFE2 0x870B # 0 +0xDFE3 0x8704 # 0 +0xDFE4 0x86F7 # 0 +0xDFE5 0x870C # 0 +0xDFE6 0x86FA # 0 +0xDFE7 0x86D6 # 0 +0xDFE8 0x86F5 # 0 +0xDFE9 0x874D # 0 +0xDFEA 0x86F8 # 0 +0xDFEB 0x870E # 0 +0xDFEC 0x8709 # 0 +0xDFED 0x8701 # 0 +0xDFEE 0x86F6 # 0 +0xDFEF 0x870D # 0 +0xDFF0 0x8705 # 0 +0xDFF1 0x88D6 # 0 +0xDFF2 0x88CB # 0 +0xDFF3 0x88CD # 0 +0xDFF4 0x88CE # 0 +0xDFF5 0x88DE # 0 +0xDFF6 0x88DB # 0 +0xDFF7 0x88DA # 0 +0xDFF8 0x88CC # 0 +0xDFF9 0x88D0 # 0 +0xDFFA 0x8985 # 0 +0xDFFB 0x899B # 0 +0xDFFC 0x89DF # 0 +0xDFFD 0x89E5 # 0 +0xDFFE 0x89E4 # 0 +0xE040 0x89E1 # 0 +0xE041 0x89E0 # 0 +0xE042 0x89E2 # 0 +0xE043 0x89DC # 0 +0xE044 0x89E6 # 0 +0xE045 0x8A76 # 0 +0xE046 0x8A86 # 0 +0xE047 0x8A7F # 0 +0xE048 0x8A61 # 0 +0xE049 0x8A3F # 0 +0xE04A 0x8A77 # 0 +0xE04B 0x8A82 # 0 +0xE04C 0x8A84 # 0 +0xE04D 0x8A75 # 0 +0xE04E 0x8A83 # 0 +0xE04F 0x8A81 # 0 +0xE050 0x8A74 # 0 +0xE051 0x8A7A # 0 +0xE052 0x8C3C # 0 +0xE053 0x8C4B # 0 +0xE054 0x8C4A # 0 +0xE055 0x8C65 # 0 +0xE056 0x8C64 # 0 +0xE057 0x8C66 # 0 +0xE058 0x8C86 # 0 +0xE059 0x8C84 # 0 +0xE05A 0x8C85 # 0 +0xE05B 0x8CCC # 0 +0xE05C 0x8D68 # 0 +0xE05D 0x8D69 # 0 +0xE05E 0x8D91 # 0 +0xE05F 0x8D8C # 0 +0xE060 0x8D8E # 0 +0xE061 0x8D8F # 0 +0xE062 0x8D8D # 0 +0xE063 0x8D93 # 0 +0xE064 0x8D94 # 0 +0xE065 0x8D90 # 0 +0xE066 0x8D92 # 0 +0xE067 0x8DF0 # 0 +0xE068 0x8DE0 # 0 +0xE069 0x8DEC # 0 +0xE06A 0x8DF1 # 0 +0xE06B 0x8DEE # 0 +0xE06C 0x8DD0 # 0 +0xE06D 0x8DE9 # 0 +0xE06E 0x8DE3 # 0 +0xE06F 0x8DE2 # 0 +0xE070 0x8DE7 # 0 +0xE071 0x8DF2 # 0 +0xE072 0x8DEB # 0 +0xE073 0x8DF4 # 0 +0xE074 0x8F06 # 0 +0xE075 0x8EFF # 0 +0xE076 0x8F01 # 0 +0xE077 0x8F00 # 0 +0xE078 0x8F05 # 0 +0xE079 0x8F07 # 0 +0xE07A 0x8F08 # 0 +0xE07B 0x8F02 # 0 +0xE07C 0x8F0B # 0 +0xE07D 0x9052 # 0 +0xE07E 0x903F # 0 +0xE0A1 0x9044 # 0 +0xE0A2 0x9049 # 0 +0xE0A3 0x903D # 0 +0xE0A4 0x9110 # 0 +0xE0A5 0x910D # 0 +0xE0A6 0x910F # 0 +0xE0A7 0x9111 # 0 +0xE0A8 0x9116 # 0 +0xE0A9 0x9114 # 0 +0xE0AA 0x910B # 0 +0xE0AB 0x910E # 0 +0xE0AC 0x916E # 0 +0xE0AD 0x916F # 0 +0xE0AE 0x9248 # 0 +0xE0AF 0x9252 # 0 +0xE0B0 0x9230 # 0 +0xE0B1 0x923A # 0 +0xE0B2 0x9266 # 0 +0xE0B3 0x9233 # 0 +0xE0B4 0x9265 # 0 +0xE0B5 0x925E # 0 +0xE0B6 0x9283 # 0 +0xE0B7 0x922E # 0 +0xE0B8 0x924A # 0 +0xE0B9 0x9246 # 0 +0xE0BA 0x926D # 0 +0xE0BB 0x926C # 0 +0xE0BC 0x924F # 0 +0xE0BD 0x9260 # 0 +0xE0BE 0x9267 # 0 +0xE0BF 0x926F # 0 +0xE0C0 0x9236 # 0 +0xE0C1 0x9261 # 0 +0xE0C2 0x9270 # 0 +0xE0C3 0x9231 # 0 +0xE0C4 0x9254 # 0 +0xE0C5 0x9263 # 0 +0xE0C6 0x9250 # 0 +0xE0C7 0x9272 # 0 +0xE0C8 0x924E # 0 +0xE0C9 0x9253 # 0 +0xE0CA 0x924C # 0 +0xE0CB 0x9256 # 0 +0xE0CC 0x9232 # 0 +0xE0CD 0x959F # 0 +0xE0CE 0x959C # 0 +0xE0CF 0x959E # 0 +0xE0D0 0x959B # 0 +0xE0D1 0x9692 # 0 +0xE0D2 0x9693 # 0 +0xE0D3 0x9691 # 0 +0xE0D4 0x9697 # 0 +0xE0D5 0x96CE # 0 +0xE0D6 0x96FA # 0 +0xE0D7 0x96FD # 0 +0xE0D8 0x96F8 # 0 +0xE0D9 0x96F5 # 0 +0xE0DA 0x9773 # 0 +0xE0DB 0x9777 # 0 +0xE0DC 0x9778 # 0 +0xE0DD 0x9772 # 0 +0xE0DE 0x980F # 0 +0xE0DF 0x980D # 0 +0xE0E0 0x980E # 0 +0xE0E1 0x98AC # 0 +0xE0E2 0x98F6 # 0 +0xE0E3 0x98F9 # 0 +0xE0E4 0x99AF # 0 +0xE0E5 0x99B2 # 0 +0xE0E6 0x99B0 # 0 +0xE0E7 0x99B5 # 0 +0xE0E8 0x9AAD # 0 +0xE0E9 0x9AAB # 0 +0xE0EA 0x9B5B # 0 +0xE0EB 0x9CEA # 0 +0xE0EC 0x9CED # 0 +0xE0ED 0x9CE7 # 0 +0xE0EE 0x9E80 # 0 +0xE0EF 0x9EFD # 0 +0xE0F0 0x50E6 # 0 +0xE0F1 0x50D4 # 0 +0xE0F2 0x50D7 # 0 +0xE0F3 0x50E8 # 0 +0xE0F4 0x50F3 # 0 +0xE0F5 0x50DB # 0 +0xE0F6 0x50EA # 0 +0xE0F7 0x50DD # 0 +0xE0F8 0x50E4 # 0 +0xE0F9 0x50D3 # 0 +0xE0FA 0x50EC # 0 +0xE0FB 0x50F0 # 0 +0xE0FC 0x50EF # 0 +0xE0FD 0x50E3 # 0 +0xE0FE 0x50E0 # 0 +0xE140 0x51D8 # 0 +0xE141 0x5280 # 0 +0xE142 0x5281 # 0 +0xE143 0x52E9 # 0 +0xE144 0x52EB # 0 +0xE145 0x5330 # 0 +0xE146 0x53AC # 0 +0xE147 0x5627 # 0 +0xE148 0x5615 # 0 +0xE149 0x560C # 0 +0xE14A 0x5612 # 0 +0xE14B 0x55FC # 0 +0xE14C 0x560F # 0 +0xE14D 0x561C # 0 +0xE14E 0x5601 # 0 +0xE14F 0x5613 # 0 +0xE150 0x5602 # 0 +0xE151 0x55FA # 0 +0xE152 0x561D # 0 +0xE153 0x5604 # 0 +0xE154 0x55FF # 0 +0xE155 0x55F9 # 0 +0xE156 0x5889 # 0 +0xE157 0x587C # 0 +0xE158 0x5890 # 0 +0xE159 0x5898 # 0 +0xE15A 0x5886 # 0 +0xE15B 0x5881 # 0 +0xE15C 0x587F # 0 +0xE15D 0x5874 # 0 +0xE15E 0x588B # 0 +0xE15F 0x587A # 0 +0xE160 0x5887 # 0 +0xE161 0x5891 # 0 +0xE162 0x588E # 0 +0xE163 0x5876 # 0 +0xE164 0x5882 # 0 +0xE165 0x5888 # 0 +0xE166 0x587B # 0 +0xE167 0x5894 # 0 +0xE168 0x588F # 0 +0xE169 0x58FE # 0 +0xE16A 0x596B # 0 +0xE16B 0x5ADC # 0 +0xE16C 0x5AEE # 0 +0xE16D 0x5AE5 # 0 +0xE16E 0x5AD5 # 0 +0xE16F 0x5AEA # 0 +0xE170 0x5ADA # 0 +0xE171 0x5AED # 0 +0xE172 0x5AEB # 0 +0xE173 0x5AF3 # 0 +0xE174 0x5AE2 # 0 +0xE175 0x5AE0 # 0 +0xE176 0x5ADB # 0 +0xE177 0x5AEC # 0 +0xE178 0x5ADE # 0 +0xE179 0x5ADD # 0 +0xE17A 0x5AD9 # 0 +0xE17B 0x5AE8 # 0 +0xE17C 0x5ADF # 0 +0xE17D 0x5B77 # 0 +0xE17E 0x5BE0 # 0 +0xE1A1 0x5BE3 # 0 +0xE1A2 0x5C63 # 0 +0xE1A3 0x5D82 # 0 +0xE1A4 0x5D80 # 0 +0xE1A5 0x5D7D # 0 +0xE1A6 0x5D86 # 0 +0xE1A7 0x5D7A # 0 +0xE1A8 0x5D81 # 0 +0xE1A9 0x5D77 # 0 +0xE1AA 0x5D8A # 0 +0xE1AB 0x5D89 # 0 +0xE1AC 0x5D88 # 0 +0xE1AD 0x5D7E # 0 +0xE1AE 0x5D7C # 0 +0xE1AF 0x5D8D # 0 +0xE1B0 0x5D79 # 0 +0xE1B1 0x5D7F # 0 +0xE1B2 0x5E58 # 0 +0xE1B3 0x5E59 # 0 +0xE1B4 0x5E53 # 0 +0xE1B5 0x5ED8 # 0 +0xE1B6 0x5ED1 # 0 +0xE1B7 0x5ED7 # 0 +0xE1B8 0x5ECE # 0 +0xE1B9 0x5EDC # 0 +0xE1BA 0x5ED5 # 0 +0xE1BB 0x5ED9 # 0 +0xE1BC 0x5ED2 # 0 +0xE1BD 0x5ED4 # 0 +0xE1BE 0x5F44 # 0 +0xE1BF 0x5F43 # 0 +0xE1C0 0x5F6F # 0 +0xE1C1 0x5FB6 # 0 +0xE1C2 0x612C # 0 +0xE1C3 0x6128 # 0 +0xE1C4 0x6141 # 0 +0xE1C5 0x615E # 0 +0xE1C6 0x6171 # 0 +0xE1C7 0x6173 # 0 +0xE1C8 0x6152 # 0 +0xE1C9 0x6153 # 0 +0xE1CA 0x6172 # 0 +0xE1CB 0x616C # 0 +0xE1CC 0x6180 # 0 +0xE1CD 0x6174 # 0 +0xE1CE 0x6154 # 0 +0xE1CF 0x617A # 0 +0xE1D0 0x615B # 0 +0xE1D1 0x6165 # 0 +0xE1D2 0x613B # 0 +0xE1D3 0x616A # 0 +0xE1D4 0x6161 # 0 +0xE1D5 0x6156 # 0 +0xE1D6 0x6229 # 0 +0xE1D7 0x6227 # 0 +0xE1D8 0x622B # 0 +0xE1D9 0x642B # 0 +0xE1DA 0x644D # 0 +0xE1DB 0x645B # 0 +0xE1DC 0x645D # 0 +0xE1DD 0x6474 # 0 +0xE1DE 0x6476 # 0 +0xE1DF 0x6472 # 0 +0xE1E0 0x6473 # 0 +0xE1E1 0x647D # 0 +0xE1E2 0x6475 # 0 +0xE1E3 0x6466 # 0 +0xE1E4 0x64A6 # 0 +0xE1E5 0x644E # 0 +0xE1E6 0x6482 # 0 +0xE1E7 0x645E # 0 +0xE1E8 0x645C # 0 +0xE1E9 0x644B # 0 +0xE1EA 0x6453 # 0 +0xE1EB 0x6460 # 0 +0xE1EC 0x6450 # 0 +0xE1ED 0x647F # 0 +0xE1EE 0x643F # 0 +0xE1EF 0x646C # 0 +0xE1F0 0x646B # 0 +0xE1F1 0x6459 # 0 +0xE1F2 0x6465 # 0 +0xE1F3 0x6477 # 0 +0xE1F4 0x6573 # 0 +0xE1F5 0x65A0 # 0 +0xE1F6 0x66A1 # 0 +0xE1F7 0x66A0 # 0 +0xE1F8 0x669F # 0 +0xE1F9 0x6705 # 0 +0xE1FA 0x6704 # 0 +0xE1FB 0x6722 # 0 +0xE1FC 0x69B1 # 0 +0xE1FD 0x69B6 # 0 +0xE1FE 0x69C9 # 0 +0xE240 0x69A0 # 0 +0xE241 0x69CE # 0 +0xE242 0x6996 # 0 +0xE243 0x69B0 # 0 +0xE244 0x69AC # 0 +0xE245 0x69BC # 0 +0xE246 0x6991 # 0 +0xE247 0x6999 # 0 +0xE248 0x698E # 0 +0xE249 0x69A7 # 0 +0xE24A 0x698D # 0 +0xE24B 0x69A9 # 0 +0xE24C 0x69BE # 0 +0xE24D 0x69AF # 0 +0xE24E 0x69BF # 0 +0xE24F 0x69C4 # 0 +0xE250 0x69BD # 0 +0xE251 0x69A4 # 0 +0xE252 0x69D4 # 0 +0xE253 0x69B9 # 0 +0xE254 0x69CA # 0 +0xE255 0x699A # 0 +0xE256 0x69CF # 0 +0xE257 0x69B3 # 0 +0xE258 0x6993 # 0 +0xE259 0x69AA # 0 +0xE25A 0x69A1 # 0 +0xE25B 0x699E # 0 +0xE25C 0x69D9 # 0 +0xE25D 0x6997 # 0 +0xE25E 0x6990 # 0 +0xE25F 0x69C2 # 0 +0xE260 0x69B5 # 0 +0xE261 0x69A5 # 0 +0xE262 0x69C6 # 0 +0xE263 0x6B4A # 0 +0xE264 0x6B4D # 0 +0xE265 0x6B4B # 0 +0xE266 0x6B9E # 0 +0xE267 0x6B9F # 0 +0xE268 0x6BA0 # 0 +0xE269 0x6BC3 # 0 +0xE26A 0x6BC4 # 0 +0xE26B 0x6BFE # 0 +0xE26C 0x6ECE # 0 +0xE26D 0x6EF5 # 0 +0xE26E 0x6EF1 # 0 +0xE26F 0x6F03 # 0 +0xE270 0x6F25 # 0 +0xE271 0x6EF8 # 0 +0xE272 0x6F37 # 0 +0xE273 0x6EFB # 0 +0xE274 0x6F2E # 0 +0xE275 0x6F09 # 0 +0xE276 0x6F4E # 0 +0xE277 0x6F19 # 0 +0xE278 0x6F1A # 0 +0xE279 0x6F27 # 0 +0xE27A 0x6F18 # 0 +0xE27B 0x6F3B # 0 +0xE27C 0x6F12 # 0 +0xE27D 0x6EED # 0 +0xE27E 0x6F0A # 0 +0xE2A1 0x6F36 # 0 +0xE2A2 0x6F73 # 0 +0xE2A3 0x6EF9 # 0 +0xE2A4 0x6EEE # 0 +0xE2A5 0x6F2D # 0 +0xE2A6 0x6F40 # 0 +0xE2A7 0x6F30 # 0 +0xE2A8 0x6F3C # 0 +0xE2A9 0x6F35 # 0 +0xE2AA 0x6EEB # 0 +0xE2AB 0x6F07 # 0 +0xE2AC 0x6F0E # 0 +0xE2AD 0x6F43 # 0 +0xE2AE 0x6F05 # 0 +0xE2AF 0x6EFD # 0 +0xE2B0 0x6EF6 # 0 +0xE2B1 0x6F39 # 0 +0xE2B2 0x6F1C # 0 +0xE2B3 0x6EFC # 0 +0xE2B4 0x6F3A # 0 +0xE2B5 0x6F1F # 0 +0xE2B6 0x6F0D # 0 +0xE2B7 0x6F1E # 0 +0xE2B8 0x6F08 # 0 +0xE2B9 0x6F21 # 0 +0xE2BA 0x7187 # 0 +0xE2BB 0x7190 # 0 +0xE2BC 0x7189 # 0 +0xE2BD 0x7180 # 0 +0xE2BE 0x7185 # 0 +0xE2BF 0x7182 # 0 +0xE2C0 0x718F # 0 +0xE2C1 0x717B # 0 +0xE2C2 0x7186 # 0 +0xE2C3 0x7181 # 0 +0xE2C4 0x7197 # 0 +0xE2C5 0x7244 # 0 +0xE2C6 0x7253 # 0 +0xE2C7 0x7297 # 0 +0xE2C8 0x7295 # 0 +0xE2C9 0x7293 # 0 +0xE2CA 0x7343 # 0 +0xE2CB 0x734D # 0 +0xE2CC 0x7351 # 0 +0xE2CD 0x734C # 0 +0xE2CE 0x7462 # 0 +0xE2CF 0x7473 # 0 +0xE2D0 0x7471 # 0 +0xE2D1 0x7475 # 0 +0xE2D2 0x7472 # 0 +0xE2D3 0x7467 # 0 +0xE2D4 0x746E # 0 +0xE2D5 0x7500 # 0 +0xE2D6 0x7502 # 0 +0xE2D7 0x7503 # 0 +0xE2D8 0x757D # 0 +0xE2D9 0x7590 # 0 +0xE2DA 0x7616 # 0 +0xE2DB 0x7608 # 0 +0xE2DC 0x760C # 0 +0xE2DD 0x7615 # 0 +0xE2DE 0x7611 # 0 +0xE2DF 0x760A # 0 +0xE2E0 0x7614 # 0 +0xE2E1 0x76B8 # 0 +0xE2E2 0x7781 # 0 +0xE2E3 0x777C # 0 +0xE2E4 0x7785 # 0 +0xE2E5 0x7782 # 0 +0xE2E6 0x776E # 0 +0xE2E7 0x7780 # 0 +0xE2E8 0x776F # 0 +0xE2E9 0x777E # 0 +0xE2EA 0x7783 # 0 +0xE2EB 0x78B2 # 0 +0xE2EC 0x78AA # 0 +0xE2ED 0x78B4 # 0 +0xE2EE 0x78AD # 0 +0xE2EF 0x78A8 # 0 +0xE2F0 0x787E # 0 +0xE2F1 0x78AB # 0 +0xE2F2 0x789E # 0 +0xE2F3 0x78A5 # 0 +0xE2F4 0x78A0 # 0 +0xE2F5 0x78AC # 0 +0xE2F6 0x78A2 # 0 +0xE2F7 0x78A4 # 0 +0xE2F8 0x7998 # 0 +0xE2F9 0x798A # 0 +0xE2FA 0x798B # 0 +0xE2FB 0x7996 # 0 +0xE2FC 0x7995 # 0 +0xE2FD 0x7994 # 0 +0xE2FE 0x7993 # 0 +0xE340 0x7997 # 0 +0xE341 0x7988 # 0 +0xE342 0x7992 # 0 +0xE343 0x7990 # 0 +0xE344 0x7A2B # 0 +0xE345 0x7A4A # 0 +0xE346 0x7A30 # 0 +0xE347 0x7A2F # 0 +0xE348 0x7A28 # 0 +0xE349 0x7A26 # 0 +0xE34A 0x7AA8 # 0 +0xE34B 0x7AAB # 0 +0xE34C 0x7AAC # 0 +0xE34D 0x7AEE # 0 +0xE34E 0x7B88 # 0 +0xE34F 0x7B9C # 0 +0xE350 0x7B8A # 0 +0xE351 0x7B91 # 0 +0xE352 0x7B90 # 0 +0xE353 0x7B96 # 0 +0xE354 0x7B8D # 0 +0xE355 0x7B8C # 0 +0xE356 0x7B9B # 0 +0xE357 0x7B8E # 0 +0xE358 0x7B85 # 0 +0xE359 0x7B98 # 0 +0xE35A 0x5284 # 0 +0xE35B 0x7B99 # 0 +0xE35C 0x7BA4 # 0 +0xE35D 0x7B82 # 0 +0xE35E 0x7CBB # 0 +0xE35F 0x7CBF # 0 +0xE360 0x7CBC # 0 +0xE361 0x7CBA # 0 +0xE362 0x7DA7 # 0 +0xE363 0x7DB7 # 0 +0xE364 0x7DC2 # 0 +0xE365 0x7DA3 # 0 +0xE366 0x7DAA # 0 +0xE367 0x7DC1 # 0 +0xE368 0x7DC0 # 0 +0xE369 0x7DC5 # 0 +0xE36A 0x7D9D # 0 +0xE36B 0x7DCE # 0 +0xE36C 0x7DC4 # 0 +0xE36D 0x7DC6 # 0 +0xE36E 0x7DCB # 0 +0xE36F 0x7DCC # 0 +0xE370 0x7DAF # 0 +0xE371 0x7DB9 # 0 +0xE372 0x7D96 # 0 +0xE373 0x7DBC # 0 +0xE374 0x7D9F # 0 +0xE375 0x7DA6 # 0 +0xE376 0x7DAE # 0 +0xE377 0x7DA9 # 0 +0xE378 0x7DA1 # 0 +0xE379 0x7DC9 # 0 +0xE37A 0x7F73 # 0 +0xE37B 0x7FE2 # 0 +0xE37C 0x7FE3 # 0 +0xE37D 0x7FE5 # 0 +0xE37E 0x7FDE # 0 +0xE3A1 0x8024 # 0 +0xE3A2 0x805D # 0 +0xE3A3 0x805C # 0 +0xE3A4 0x8189 # 0 +0xE3A5 0x8186 # 0 +0xE3A6 0x8183 # 0 +0xE3A7 0x8187 # 0 +0xE3A8 0x818D # 0 +0xE3A9 0x818C # 0 +0xE3AA 0x818B # 0 +0xE3AB 0x8215 # 0 +0xE3AC 0x8497 # 0 +0xE3AD 0x84A4 # 0 +0xE3AE 0x84A1 # 0 +0xE3AF 0x849F # 0 +0xE3B0 0x84BA # 0 +0xE3B1 0x84CE # 0 +0xE3B2 0x84C2 # 0 +0xE3B3 0x84AC # 0 +0xE3B4 0x84AE # 0 +0xE3B5 0x84AB # 0 +0xE3B6 0x84B9 # 0 +0xE3B7 0x84B4 # 0 +0xE3B8 0x84C1 # 0 +0xE3B9 0x84CD # 0 +0xE3BA 0x84AA # 0 +0xE3BB 0x849A # 0 +0xE3BC 0x84B1 # 0 +0xE3BD 0x84D0 # 0 +0xE3BE 0x849D # 0 +0xE3BF 0x84A7 # 0 +0xE3C0 0x84BB # 0 +0xE3C1 0x84A2 # 0 +0xE3C2 0x8494 # 0 +0xE3C3 0x84C7 # 0 +0xE3C4 0x84CC # 0 +0xE3C5 0x849B # 0 +0xE3C6 0x84A9 # 0 +0xE3C7 0x84AF # 0 +0xE3C8 0x84A8 # 0 +0xE3C9 0x84D6 # 0 +0xE3CA 0x8498 # 0 +0xE3CB 0x84B6 # 0 +0xE3CC 0x84CF # 0 +0xE3CD 0x84A0 # 0 +0xE3CE 0x84D7 # 0 +0xE3CF 0x84D4 # 0 +0xE3D0 0x84D2 # 0 +0xE3D1 0x84DB # 0 +0xE3D2 0x84B0 # 0 +0xE3D3 0x8491 # 0 +0xE3D4 0x8661 # 0 +0xE3D5 0x8733 # 0 +0xE3D6 0x8723 # 0 +0xE3D7 0x8728 # 0 +0xE3D8 0x876B # 0 +0xE3D9 0x8740 # 0 +0xE3DA 0x872E # 0 +0xE3DB 0x871E # 0 +0xE3DC 0x8721 # 0 +0xE3DD 0x8719 # 0 +0xE3DE 0x871B # 0 +0xE3DF 0x8743 # 0 +0xE3E0 0x872C # 0 +0xE3E1 0x8741 # 0 +0xE3E2 0x873E # 0 +0xE3E3 0x8746 # 0 +0xE3E4 0x8720 # 0 +0xE3E5 0x8732 # 0 +0xE3E6 0x872A # 0 +0xE3E7 0x872D # 0 +0xE3E8 0x873C # 0 +0xE3E9 0x8712 # 0 +0xE3EA 0x873A # 0 +0xE3EB 0x8731 # 0 +0xE3EC 0x8735 # 0 +0xE3ED 0x8742 # 0 +0xE3EE 0x8726 # 0 +0xE3EF 0x8727 # 0 +0xE3F0 0x8738 # 0 +0xE3F1 0x8724 # 0 +0xE3F2 0x871A # 0 +0xE3F3 0x8730 # 0 +0xE3F4 0x8711 # 0 +0xE3F5 0x88F7 # 0 +0xE3F6 0x88E7 # 0 +0xE3F7 0x88F1 # 0 +0xE3F8 0x88F2 # 0 +0xE3F9 0x88FA # 0 +0xE3FA 0x88FE # 0 +0xE3FB 0x88EE # 0 +0xE3FC 0x88FC # 0 +0xE3FD 0x88F6 # 0 +0xE3FE 0x88FB # 0 +0xE440 0x88F0 # 0 +0xE441 0x88EC # 0 +0xE442 0x88EB # 0 +0xE443 0x899D # 0 +0xE444 0x89A1 # 0 +0xE445 0x899F # 0 +0xE446 0x899E # 0 +0xE447 0x89E9 # 0 +0xE448 0x89EB # 0 +0xE449 0x89E8 # 0 +0xE44A 0x8AAB # 0 +0xE44B 0x8A99 # 0 +0xE44C 0x8A8B # 0 +0xE44D 0x8A92 # 0 +0xE44E 0x8A8F # 0 +0xE44F 0x8A96 # 0 +0xE450 0x8C3D # 0 +0xE451 0x8C68 # 0 +0xE452 0x8C69 # 0 +0xE453 0x8CD5 # 0 +0xE454 0x8CCF # 0 +0xE455 0x8CD7 # 0 +0xE456 0x8D96 # 0 +0xE457 0x8E09 # 0 +0xE458 0x8E02 # 0 +0xE459 0x8DFF # 0 +0xE45A 0x8E0D # 0 +0xE45B 0x8DFD # 0 +0xE45C 0x8E0A # 0 +0xE45D 0x8E03 # 0 +0xE45E 0x8E07 # 0 +0xE45F 0x8E06 # 0 +0xE460 0x8E05 # 0 +0xE461 0x8DFE # 0 +0xE462 0x8E00 # 0 +0xE463 0x8E04 # 0 +0xE464 0x8F10 # 0 +0xE465 0x8F11 # 0 +0xE466 0x8F0E # 0 +0xE467 0x8F0D # 0 +0xE468 0x9123 # 0 +0xE469 0x911C # 0 +0xE46A 0x9120 # 0 +0xE46B 0x9122 # 0 +0xE46C 0x911F # 0 +0xE46D 0x911D # 0 +0xE46E 0x911A # 0 +0xE46F 0x9124 # 0 +0xE470 0x9121 # 0 +0xE471 0x911B # 0 +0xE472 0x917A # 0 +0xE473 0x9172 # 0 +0xE474 0x9179 # 0 +0xE475 0x9173 # 0 +0xE476 0x92A5 # 0 +0xE477 0x92A4 # 0 +0xE478 0x9276 # 0 +0xE479 0x929B # 0 +0xE47A 0x927A # 0 +0xE47B 0x92A0 # 0 +0xE47C 0x9294 # 0 +0xE47D 0x92AA # 0 +0xE47E 0x928D # 0 +0xE4A1 0x92A6 # 0 +0xE4A2 0x929A # 0 +0xE4A3 0x92AB # 0 +0xE4A4 0x9279 # 0 +0xE4A5 0x9297 # 0 +0xE4A6 0x927F # 0 +0xE4A7 0x92A3 # 0 +0xE4A8 0x92EE # 0 +0xE4A9 0x928E # 0 +0xE4AA 0x9282 # 0 +0xE4AB 0x9295 # 0 +0xE4AC 0x92A2 # 0 +0xE4AD 0x927D # 0 +0xE4AE 0x9288 # 0 +0xE4AF 0x92A1 # 0 +0xE4B0 0x928A # 0 +0xE4B1 0x9286 # 0 +0xE4B2 0x928C # 0 +0xE4B3 0x9299 # 0 +0xE4B4 0x92A7 # 0 +0xE4B5 0x927E # 0 +0xE4B6 0x9287 # 0 +0xE4B7 0x92A9 # 0 +0xE4B8 0x929D # 0 +0xE4B9 0x928B # 0 +0xE4BA 0x922D # 0 +0xE4BB 0x969E # 0 +0xE4BC 0x96A1 # 0 +0xE4BD 0x96FF # 0 +0xE4BE 0x9758 # 0 +0xE4BF 0x977D # 0 +0xE4C0 0x977A # 0 +0xE4C1 0x977E # 0 +0xE4C2 0x9783 # 0 +0xE4C3 0x9780 # 0 +0xE4C4 0x9782 # 0 +0xE4C5 0x977B # 0 +0xE4C6 0x9784 # 0 +0xE4C7 0x9781 # 0 +0xE4C8 0x977F # 0 +0xE4C9 0x97CE # 0 +0xE4CA 0x97CD # 0 +0xE4CB 0x9816 # 0 +0xE4CC 0x98AD # 0 +0xE4CD 0x98AE # 0 +0xE4CE 0x9902 # 0 +0xE4CF 0x9900 # 0 +0xE4D0 0x9907 # 0 +0xE4D1 0x999D # 0 +0xE4D2 0x999C # 0 +0xE4D3 0x99C3 # 0 +0xE4D4 0x99B9 # 0 +0xE4D5 0x99BB # 0 +0xE4D6 0x99BA # 0 +0xE4D7 0x99C2 # 0 +0xE4D8 0x99BD # 0 +0xE4D9 0x99C7 # 0 +0xE4DA 0x9AB1 # 0 +0xE4DB 0x9AE3 # 0 +0xE4DC 0x9AE7 # 0 +0xE4DD 0x9B3E # 0 +0xE4DE 0x9B3F # 0 +0xE4DF 0x9B60 # 0 +0xE4E0 0x9B61 # 0 +0xE4E1 0x9B5F # 0 +0xE4E2 0x9CF1 # 0 +0xE4E3 0x9CF2 # 0 +0xE4E4 0x9CF5 # 0 +0xE4E5 0x9EA7 # 0 +0xE4E6 0x50FF # 0 +0xE4E7 0x5103 # 0 +0xE4E8 0x5130 # 0 +0xE4E9 0x50F8 # 0 +0xE4EA 0x5106 # 0 +0xE4EB 0x5107 # 0 +0xE4EC 0x50F6 # 0 +0xE4ED 0x50FE # 0 +0xE4EE 0x510B # 0 +0xE4EF 0x510C # 0 +0xE4F0 0x50FD # 0 +0xE4F1 0x510A # 0 +0xE4F2 0x528B # 0 +0xE4F3 0x528C # 0 +0xE4F4 0x52F1 # 0 +0xE4F5 0x52EF # 0 +0xE4F6 0x5648 # 0 +0xE4F7 0x5642 # 0 +0xE4F8 0x564C # 0 +0xE4F9 0x5635 # 0 +0xE4FA 0x5641 # 0 +0xE4FB 0x564A # 0 +0xE4FC 0x5649 # 0 +0xE4FD 0x5646 # 0 +0xE4FE 0x5658 # 0 +0xE540 0x565A # 0 +0xE541 0x5640 # 0 +0xE542 0x5633 # 0 +0xE543 0x563D # 0 +0xE544 0x562C # 0 +0xE545 0x563E # 0 +0xE546 0x5638 # 0 +0xE547 0x562A # 0 +0xE548 0x563A # 0 +0xE549 0x571A # 0 +0xE54A 0x58AB # 0 +0xE54B 0x589D # 0 +0xE54C 0x58B1 # 0 +0xE54D 0x58A0 # 0 +0xE54E 0x58A3 # 0 +0xE54F 0x58AF # 0 +0xE550 0x58AC # 0 +0xE551 0x58A5 # 0 +0xE552 0x58A1 # 0 +0xE553 0x58FF # 0 +0xE554 0x5AFF # 0 +0xE555 0x5AF4 # 0 +0xE556 0x5AFD # 0 +0xE557 0x5AF7 # 0 +0xE558 0x5AF6 # 0 +0xE559 0x5B03 # 0 +0xE55A 0x5AF8 # 0 +0xE55B 0x5B02 # 0 +0xE55C 0x5AF9 # 0 +0xE55D 0x5B01 # 0 +0xE55E 0x5B07 # 0 +0xE55F 0x5B05 # 0 +0xE560 0x5B0F # 0 +0xE561 0x5C67 # 0 +0xE562 0x5D99 # 0 +0xE563 0x5D97 # 0 +0xE564 0x5D9F # 0 +0xE565 0x5D92 # 0 +0xE566 0x5DA2 # 0 +0xE567 0x5D93 # 0 +0xE568 0x5D95 # 0 +0xE569 0x5DA0 # 0 +0xE56A 0x5D9C # 0 +0xE56B 0x5DA1 # 0 +0xE56C 0x5D9A # 0 +0xE56D 0x5D9E # 0 +0xE56E 0x5E69 # 0 +0xE56F 0x5E5D # 0 +0xE570 0x5E60 # 0 +0xE571 0x5E5C # 0 +0xE572 0x7DF3 # 0 +0xE573 0x5EDB # 0 +0xE574 0x5EDE # 0 +0xE575 0x5EE1 # 0 +0xE576 0x5F49 # 0 +0xE577 0x5FB2 # 0 +0xE578 0x618B # 0 +0xE579 0x6183 # 0 +0xE57A 0x6179 # 0 +0xE57B 0x61B1 # 0 +0xE57C 0x61B0 # 0 +0xE57D 0x61A2 # 0 +0xE57E 0x6189 # 0 +0xE5A1 0x619B # 0 +0xE5A2 0x6193 # 0 +0xE5A3 0x61AF # 0 +0xE5A4 0x61AD # 0 +0xE5A5 0x619F # 0 +0xE5A6 0x6192 # 0 +0xE5A7 0x61AA # 0 +0xE5A8 0x61A1 # 0 +0xE5A9 0x618D # 0 +0xE5AA 0x6166 # 0 +0xE5AB 0x61B3 # 0 +0xE5AC 0x622D # 0 +0xE5AD 0x646E # 0 +0xE5AE 0x6470 # 0 +0xE5AF 0x6496 # 0 +0xE5B0 0x64A0 # 0 +0xE5B1 0x6485 # 0 +0xE5B2 0x6497 # 0 +0xE5B3 0x649C # 0 +0xE5B4 0x648F # 0 +0xE5B5 0x648B # 0 +0xE5B6 0x648A # 0 +0xE5B7 0x648C # 0 +0xE5B8 0x64A3 # 0 +0xE5B9 0x649F # 0 +0xE5BA 0x6468 # 0 +0xE5BB 0x64B1 # 0 +0xE5BC 0x6498 # 0 +0xE5BD 0x6576 # 0 +0xE5BE 0x657A # 0 +0xE5BF 0x6579 # 0 +0xE5C0 0x657B # 0 +0xE5C1 0x65B2 # 0 +0xE5C2 0x65B3 # 0 +0xE5C3 0x66B5 # 0 +0xE5C4 0x66B0 # 0 +0xE5C5 0x66A9 # 0 +0xE5C6 0x66B2 # 0 +0xE5C7 0x66B7 # 0 +0xE5C8 0x66AA # 0 +0xE5C9 0x66AF # 0 +0xE5CA 0x6A00 # 0 +0xE5CB 0x6A06 # 0 +0xE5CC 0x6A17 # 0 +0xE5CD 0x69E5 # 0 +0xE5CE 0x69F8 # 0 +0xE5CF 0x6A15 # 0 +0xE5D0 0x69F1 # 0 +0xE5D1 0x69E4 # 0 +0xE5D2 0x6A20 # 0 +0xE5D3 0x69FF # 0 +0xE5D4 0x69EC # 0 +0xE5D5 0x69E2 # 0 +0xE5D6 0x6A1B # 0 +0xE5D7 0x6A1D # 0 +0xE5D8 0x69FE # 0 +0xE5D9 0x6A27 # 0 +0xE5DA 0x69F2 # 0 +0xE5DB 0x69EE # 0 +0xE5DC 0x6A14 # 0 +0xE5DD 0x69F7 # 0 +0xE5DE 0x69E7 # 0 +0xE5DF 0x6A40 # 0 +0xE5E0 0x6A08 # 0 +0xE5E1 0x69E6 # 0 +0xE5E2 0x69FB # 0 +0xE5E3 0x6A0D # 0 +0xE5E4 0x69FC # 0 +0xE5E5 0x69EB # 0 +0xE5E6 0x6A09 # 0 +0xE5E7 0x6A04 # 0 +0xE5E8 0x6A18 # 0 +0xE5E9 0x6A25 # 0 +0xE5EA 0x6A0F # 0 +0xE5EB 0x69F6 # 0 +0xE5EC 0x6A26 # 0 +0xE5ED 0x6A07 # 0 +0xE5EE 0x69F4 # 0 +0xE5EF 0x6A16 # 0 +0xE5F0 0x6B51 # 0 +0xE5F1 0x6BA5 # 0 +0xE5F2 0x6BA3 # 0 +0xE5F3 0x6BA2 # 0 +0xE5F4 0x6BA6 # 0 +0xE5F5 0x6C01 # 0 +0xE5F6 0x6C00 # 0 +0xE5F7 0x6BFF # 0 +0xE5F8 0x6C02 # 0 +0xE5F9 0x6F41 # 0 +0xE5FA 0x6F26 # 0 +0xE5FB 0x6F7E # 0 +0xE5FC 0x6F87 # 0 +0xE5FD 0x6FC6 # 0 +0xE5FE 0x6F92 # 0 +0xE640 0x6F8D # 0 +0xE641 0x6F89 # 0 +0xE642 0x6F8C # 0 +0xE643 0x6F62 # 0 +0xE644 0x6F4F # 0 +0xE645 0x6F85 # 0 +0xE646 0x6F5A # 0 +0xE647 0x6F96 # 0 +0xE648 0x6F76 # 0 +0xE649 0x6F6C # 0 +0xE64A 0x6F82 # 0 +0xE64B 0x6F55 # 0 +0xE64C 0x6F72 # 0 +0xE64D 0x6F52 # 0 +0xE64E 0x6F50 # 0 +0xE64F 0x6F57 # 0 +0xE650 0x6F94 # 0 +0xE651 0x6F93 # 0 +0xE652 0x6F5D # 0 +0xE653 0x6F00 # 0 +0xE654 0x6F61 # 0 +0xE655 0x6F6B # 0 +0xE656 0x6F7D # 0 +0xE657 0x6F67 # 0 +0xE658 0x6F90 # 0 +0xE659 0x6F53 # 0 +0xE65A 0x6F8B # 0 +0xE65B 0x6F69 # 0 +0xE65C 0x6F7F # 0 +0xE65D 0x6F95 # 0 +0xE65E 0x6F63 # 0 +0xE65F 0x6F77 # 0 +0xE660 0x6F6A # 0 +0xE661 0x6F7B # 0 +0xE662 0x71B2 # 0 +0xE663 0x71AF # 0 +0xE664 0x719B # 0 +0xE665 0x71B0 # 0 +0xE666 0x71A0 # 0 +0xE667 0x719A # 0 +0xE668 0x71A9 # 0 +0xE669 0x71B5 # 0 +0xE66A 0x719D # 0 +0xE66B 0x71A5 # 0 +0xE66C 0x719E # 0 +0xE66D 0x71A4 # 0 +0xE66E 0x71A1 # 0 +0xE66F 0x71AA # 0 +0xE670 0x719C # 0 +0xE671 0x71A7 # 0 +0xE672 0x71B3 # 0 +0xE673 0x7298 # 0 +0xE674 0x729A # 0 +0xE675 0x7358 # 0 +0xE676 0x7352 # 0 +0xE677 0x735E # 0 +0xE678 0x735F # 0 +0xE679 0x7360 # 0 +0xE67A 0x735D # 0 +0xE67B 0x735B # 0 +0xE67C 0x7361 # 0 +0xE67D 0x735A # 0 +0xE67E 0x7359 # 0 +0xE6A1 0x7362 # 0 +0xE6A2 0x7487 # 0 +0xE6A3 0x7489 # 0 +0xE6A4 0x748A # 0 +0xE6A5 0x7486 # 0 +0xE6A6 0x7481 # 0 +0xE6A7 0x747D # 0 +0xE6A8 0x7485 # 0 +0xE6A9 0x7488 # 0 +0xE6AA 0x747C # 0 +0xE6AB 0x7479 # 0 +0xE6AC 0x7508 # 0 +0xE6AD 0x7507 # 0 +0xE6AE 0x757E # 0 +0xE6AF 0x7625 # 0 +0xE6B0 0x761E # 0 +0xE6B1 0x7619 # 0 +0xE6B2 0x761D # 0 +0xE6B3 0x761C # 0 +0xE6B4 0x7623 # 0 +0xE6B5 0x761A # 0 +0xE6B6 0x7628 # 0 +0xE6B7 0x761B # 0 +0xE6B8 0x769C # 0 +0xE6B9 0x769D # 0 +0xE6BA 0x769E # 0 +0xE6BB 0x769B # 0 +0xE6BC 0x778D # 0 +0xE6BD 0x778F # 0 +0xE6BE 0x7789 # 0 +0xE6BF 0x7788 # 0 +0xE6C0 0x78CD # 0 +0xE6C1 0x78BB # 0 +0xE6C2 0x78CF # 0 +0xE6C3 0x78CC # 0 +0xE6C4 0x78D1 # 0 +0xE6C5 0x78CE # 0 +0xE6C6 0x78D4 # 0 +0xE6C7 0x78C8 # 0 +0xE6C8 0x78C3 # 0 +0xE6C9 0x78C4 # 0 +0xE6CA 0x78C9 # 0 +0xE6CB 0x799A # 0 +0xE6CC 0x79A1 # 0 +0xE6CD 0x79A0 # 0 +0xE6CE 0x799C # 0 +0xE6CF 0x79A2 # 0 +0xE6D0 0x799B # 0 +0xE6D1 0x6B76 # 0 +0xE6D2 0x7A39 # 0 +0xE6D3 0x7AB2 # 0 +0xE6D4 0x7AB4 # 0 +0xE6D5 0x7AB3 # 0 +0xE6D6 0x7BB7 # 0 +0xE6D7 0x7BCB # 0 +0xE6D8 0x7BBE # 0 +0xE6D9 0x7BAC # 0 +0xE6DA 0x7BCE # 0 +0xE6DB 0x7BAF # 0 +0xE6DC 0x7BB9 # 0 +0xE6DD 0x7BCA # 0 +0xE6DE 0x7BB5 # 0 +0xE6DF 0x7CC5 # 0 +0xE6E0 0x7CC8 # 0 +0xE6E1 0x7CCC # 0 +0xE6E2 0x7CCB # 0 +0xE6E3 0x7DF7 # 0 +0xE6E4 0x7DDB # 0 +0xE6E5 0x7DEA # 0 +0xE6E6 0x7DE7 # 0 +0xE6E7 0x7DD7 # 0 +0xE6E8 0x7DE1 # 0 +0xE6E9 0x7E03 # 0 +0xE6EA 0x7DFA # 0 +0xE6EB 0x7DE6 # 0 +0xE6EC 0x7DF6 # 0 +0xE6ED 0x7DF1 # 0 +0xE6EE 0x7DF0 # 0 +0xE6EF 0x7DEE # 0 +0xE6F0 0x7DDF # 0 +0xE6F1 0x7F76 # 0 +0xE6F2 0x7FAC # 0 +0xE6F3 0x7FB0 # 0 +0xE6F4 0x7FAD # 0 +0xE6F5 0x7FED # 0 +0xE6F6 0x7FEB # 0 +0xE6F7 0x7FEA # 0 +0xE6F8 0x7FEC # 0 +0xE6F9 0x7FE6 # 0 +0xE6FA 0x7FE8 # 0 +0xE6FB 0x8064 # 0 +0xE6FC 0x8067 # 0 +0xE6FD 0x81A3 # 0 +0xE6FE 0x819F # 0 +0xE740 0x819E # 0 +0xE741 0x8195 # 0 +0xE742 0x81A2 # 0 +0xE743 0x8199 # 0 +0xE744 0x8197 # 0 +0xE745 0x8216 # 0 +0xE746 0x824F # 0 +0xE747 0x8253 # 0 +0xE748 0x8252 # 0 +0xE749 0x8250 # 0 +0xE74A 0x824E # 0 +0xE74B 0x8251 # 0 +0xE74C 0x8524 # 0 +0xE74D 0x853B # 0 +0xE74E 0x850F # 0 +0xE74F 0x8500 # 0 +0xE750 0x8529 # 0 +0xE751 0x850E # 0 +0xE752 0x8509 # 0 +0xE753 0x850D # 0 +0xE754 0x851F # 0 +0xE755 0x850A # 0 +0xE756 0x8527 # 0 +0xE757 0x851C # 0 +0xE758 0x84FB # 0 +0xE759 0x852B # 0 +0xE75A 0x84FA # 0 +0xE75B 0x8508 # 0 +0xE75C 0x850C # 0 +0xE75D 0x84F4 # 0 +0xE75E 0x852A # 0 +0xE75F 0x84F2 # 0 +0xE760 0x8515 # 0 +0xE761 0x84F7 # 0 +0xE762 0x84EB # 0 +0xE763 0x84F3 # 0 +0xE764 0x84FC # 0 +0xE765 0x8512 # 0 +0xE766 0x84EA # 0 +0xE767 0x84E9 # 0 +0xE768 0x8516 # 0 +0xE769 0x84FE # 0 +0xE76A 0x8528 # 0 +0xE76B 0x851D # 0 +0xE76C 0x852E # 0 +0xE76D 0x8502 # 0 +0xE76E 0x84FD # 0 +0xE76F 0x851E # 0 +0xE770 0x84F6 # 0 +0xE771 0x8531 # 0 +0xE772 0x8526 # 0 +0xE773 0x84E7 # 0 +0xE774 0x84E8 # 0 +0xE775 0x84F0 # 0 +0xE776 0x84EF # 0 +0xE777 0x84F9 # 0 +0xE778 0x8518 # 0 +0xE779 0x8520 # 0 +0xE77A 0x8530 # 0 +0xE77B 0x850B # 0 +0xE77C 0x8519 # 0 +0xE77D 0x852F # 0 +0xE77E 0x8662 # 0 +0xE7A1 0x8756 # 0 +0xE7A2 0x8763 # 0 +0xE7A3 0x8764 # 0 +0xE7A4 0x8777 # 0 +0xE7A5 0x87E1 # 0 +0xE7A6 0x8773 # 0 +0xE7A7 0x8758 # 0 +0xE7A8 0x8754 # 0 +0xE7A9 0x875B # 0 +0xE7AA 0x8752 # 0 +0xE7AB 0x8761 # 0 +0xE7AC 0x875A # 0 +0xE7AD 0x8751 # 0 +0xE7AE 0x875E # 0 +0xE7AF 0x876D # 0 +0xE7B0 0x876A # 0 +0xE7B1 0x8750 # 0 +0xE7B2 0x874E # 0 +0xE7B3 0x875F # 0 +0xE7B4 0x875D # 0 +0xE7B5 0x876F # 0 +0xE7B6 0x876C # 0 +0xE7B7 0x877A # 0 +0xE7B8 0x876E # 0 +0xE7B9 0x875C # 0 +0xE7BA 0x8765 # 0 +0xE7BB 0x874F # 0 +0xE7BC 0x877B # 0 +0xE7BD 0x8775 # 0 +0xE7BE 0x8762 # 0 +0xE7BF 0x8767 # 0 +0xE7C0 0x8769 # 0 +0xE7C1 0x885A # 0 +0xE7C2 0x8905 # 0 +0xE7C3 0x890C # 0 +0xE7C4 0x8914 # 0 +0xE7C5 0x890B # 0 +0xE7C6 0x8917 # 0 +0xE7C7 0x8918 # 0 +0xE7C8 0x8919 # 0 +0xE7C9 0x8906 # 0 +0xE7CA 0x8916 # 0 +0xE7CB 0x8911 # 0 +0xE7CC 0x890E # 0 +0xE7CD 0x8909 # 0 +0xE7CE 0x89A2 # 0 +0xE7CF 0x89A4 # 0 +0xE7D0 0x89A3 # 0 +0xE7D1 0x89ED # 0 +0xE7D2 0x89F0 # 0 +0xE7D3 0x89EC # 0 +0xE7D4 0x8ACF # 0 +0xE7D5 0x8AC6 # 0 +0xE7D6 0x8AB8 # 0 +0xE7D7 0x8AD3 # 0 +0xE7D8 0x8AD1 # 0 +0xE7D9 0x8AD4 # 0 +0xE7DA 0x8AD5 # 0 +0xE7DB 0x8ABB # 0 +0xE7DC 0x8AD7 # 0 +0xE7DD 0x8ABE # 0 +0xE7DE 0x8AC0 # 0 +0xE7DF 0x8AC5 # 0 +0xE7E0 0x8AD8 # 0 +0xE7E1 0x8AC3 # 0 +0xE7E2 0x8ABA # 0 +0xE7E3 0x8ABD # 0 +0xE7E4 0x8AD9 # 0 +0xE7E5 0x8C3E # 0 +0xE7E6 0x8C4D # 0 +0xE7E7 0x8C8F # 0 +0xE7E8 0x8CE5 # 0 +0xE7E9 0x8CDF # 0 +0xE7EA 0x8CD9 # 0 +0xE7EB 0x8CE8 # 0 +0xE7EC 0x8CDA # 0 +0xE7ED 0x8CDD # 0 +0xE7EE 0x8CE7 # 0 +0xE7EF 0x8DA0 # 0 +0xE7F0 0x8D9C # 0 +0xE7F1 0x8DA1 # 0 +0xE7F2 0x8D9B # 0 +0xE7F3 0x8E20 # 0 +0xE7F4 0x8E23 # 0 +0xE7F5 0x8E25 # 0 +0xE7F6 0x8E24 # 0 +0xE7F7 0x8E2E # 0 +0xE7F8 0x8E15 # 0 +0xE7F9 0x8E1B # 0 +0xE7FA 0x8E16 # 0 +0xE7FB 0x8E11 # 0 +0xE7FC 0x8E19 # 0 +0xE7FD 0x8E26 # 0 +0xE7FE 0x8E27 # 0 +0xE840 0x8E14 # 0 +0xE841 0x8E12 # 0 +0xE842 0x8E18 # 0 +0xE843 0x8E13 # 0 +0xE844 0x8E1C # 0 +0xE845 0x8E17 # 0 +0xE846 0x8E1A # 0 +0xE847 0x8F2C # 0 +0xE848 0x8F24 # 0 +0xE849 0x8F18 # 0 +0xE84A 0x8F1A # 0 +0xE84B 0x8F20 # 0 +0xE84C 0x8F23 # 0 +0xE84D 0x8F16 # 0 +0xE84E 0x8F17 # 0 +0xE84F 0x9073 # 0 +0xE850 0x9070 # 0 +0xE851 0x906F # 0 +0xE852 0x9067 # 0 +0xE853 0x906B # 0 +0xE854 0x912F # 0 +0xE855 0x912B # 0 +0xE856 0x9129 # 0 +0xE857 0x912A # 0 +0xE858 0x9132 # 0 +0xE859 0x9126 # 0 +0xE85A 0x912E # 0 +0xE85B 0x9185 # 0 +0xE85C 0x9186 # 0 +0xE85D 0x918A # 0 +0xE85E 0x9181 # 0 +0xE85F 0x9182 # 0 +0xE860 0x9184 # 0 +0xE861 0x9180 # 0 +0xE862 0x92D0 # 0 +0xE863 0x92C3 # 0 +0xE864 0x92C4 # 0 +0xE865 0x92C0 # 0 +0xE866 0x92D9 # 0 +0xE867 0x92B6 # 0 +0xE868 0x92CF # 0 +0xE869 0x92F1 # 0 +0xE86A 0x92DF # 0 +0xE86B 0x92D8 # 0 +0xE86C 0x92E9 # 0 +0xE86D 0x92D7 # 0 +0xE86E 0x92DD # 0 +0xE86F 0x92CC # 0 +0xE870 0x92EF # 0 +0xE871 0x92C2 # 0 +0xE872 0x92E8 # 0 +0xE873 0x92CA # 0 +0xE874 0x92C8 # 0 +0xE875 0x92CE # 0 +0xE876 0x92E6 # 0 +0xE877 0x92CD # 0 +0xE878 0x92D5 # 0 +0xE879 0x92C9 # 0 +0xE87A 0x92E0 # 0 +0xE87B 0x92DE # 0 +0xE87C 0x92E7 # 0 +0xE87D 0x92D1 # 0 +0xE87E 0x92D3 # 0 +0xE8A1 0x92B5 # 0 +0xE8A2 0x92E1 # 0 +0xE8A3 0x92C6 # 0 +0xE8A4 0x92B4 # 0 +0xE8A5 0x957C # 0 +0xE8A6 0x95AC # 0 +0xE8A7 0x95AB # 0 +0xE8A8 0x95AE # 0 +0xE8A9 0x95B0 # 0 +0xE8AA 0x96A4 # 0 +0xE8AB 0x96A2 # 0 +0xE8AC 0x96D3 # 0 +0xE8AD 0x9705 # 0 +0xE8AE 0x9708 # 0 +0xE8AF 0x9702 # 0 +0xE8B0 0x975A # 0 +0xE8B1 0x978A # 0 +0xE8B2 0x978E # 0 +0xE8B3 0x9788 # 0 +0xE8B4 0x97D0 # 0 +0xE8B5 0x97CF # 0 +0xE8B6 0x981E # 0 +0xE8B7 0x981D # 0 +0xE8B8 0x9826 # 0 +0xE8B9 0x9829 # 0 +0xE8BA 0x9828 # 0 +0xE8BB 0x9820 # 0 +0xE8BC 0x981B # 0 +0xE8BD 0x9827 # 0 +0xE8BE 0x98B2 # 0 +0xE8BF 0x9908 # 0 +0xE8C0 0x98FA # 0 +0xE8C1 0x9911 # 0 +0xE8C2 0x9914 # 0 +0xE8C3 0x9916 # 0 +0xE8C4 0x9917 # 0 +0xE8C5 0x9915 # 0 +0xE8C6 0x99DC # 0 +0xE8C7 0x99CD # 0 +0xE8C8 0x99CF # 0 +0xE8C9 0x99D3 # 0 +0xE8CA 0x99D4 # 0 +0xE8CB 0x99CE # 0 +0xE8CC 0x99C9 # 0 +0xE8CD 0x99D6 # 0 +0xE8CE 0x99D8 # 0 +0xE8CF 0x99CB # 0 +0xE8D0 0x99D7 # 0 +0xE8D1 0x99CC # 0 +0xE8D2 0x9AB3 # 0 +0xE8D3 0x9AEC # 0 +0xE8D4 0x9AEB # 0 +0xE8D5 0x9AF3 # 0 +0xE8D6 0x9AF2 # 0 +0xE8D7 0x9AF1 # 0 +0xE8D8 0x9B46 # 0 +0xE8D9 0x9B43 # 0 +0xE8DA 0x9B67 # 0 +0xE8DB 0x9B74 # 0 +0xE8DC 0x9B71 # 0 +0xE8DD 0x9B66 # 0 +0xE8DE 0x9B76 # 0 +0xE8DF 0x9B75 # 0 +0xE8E0 0x9B70 # 0 +0xE8E1 0x9B68 # 0 +0xE8E2 0x9B64 # 0 +0xE8E3 0x9B6C # 0 +0xE8E4 0x9CFC # 0 +0xE8E5 0x9CFA # 0 +0xE8E6 0x9CFD # 0 +0xE8E7 0x9CFF # 0 +0xE8E8 0x9CF7 # 0 +0xE8E9 0x9D07 # 0 +0xE8EA 0x9D00 # 0 +0xE8EB 0x9CF9 # 0 +0xE8EC 0x9CFB # 0 +0xE8ED 0x9D08 # 0 +0xE8EE 0x9D05 # 0 +0xE8EF 0x9D04 # 0 +0xE8F0 0x9E83 # 0 +0xE8F1 0x9ED3 # 0 +0xE8F2 0x9F0F # 0 +0xE8F3 0x9F10 # 0 +0xE8F4 0x511C # 0 +0xE8F5 0x5113 # 0 +0xE8F6 0x5117 # 0 +0xE8F7 0x511A # 0 +0xE8F8 0x5111 # 0 +0xE8F9 0x51DE # 0 +0xE8FA 0x5334 # 0 +0xE8FB 0x53E1 # 0 +0xE8FC 0x5670 # 0 +0xE8FD 0x5660 # 0 +0xE8FE 0x566E # 0 +0xE940 0x5673 # 0 +0xE941 0x5666 # 0 +0xE942 0x5663 # 0 +0xE943 0x566D # 0 +0xE944 0x5672 # 0 +0xE945 0x565E # 0 +0xE946 0x5677 # 0 +0xE947 0x571C # 0 +0xE948 0x571B # 0 +0xE949 0x58C8 # 0 +0xE94A 0x58BD # 0 +0xE94B 0x58C9 # 0 +0xE94C 0x58BF # 0 +0xE94D 0x58BA # 0 +0xE94E 0x58C2 # 0 +0xE94F 0x58BC # 0 +0xE950 0x58C6 # 0 +0xE951 0x5B17 # 0 +0xE952 0x5B19 # 0 +0xE953 0x5B1B # 0 +0xE954 0x5B21 # 0 +0xE955 0x5B14 # 0 +0xE956 0x5B13 # 0 +0xE957 0x5B10 # 0 +0xE958 0x5B16 # 0 +0xE959 0x5B28 # 0 +0xE95A 0x5B1A # 0 +0xE95B 0x5B20 # 0 +0xE95C 0x5B1E # 0 +0xE95D 0x5BEF # 0 +0xE95E 0x5DAC # 0 +0xE95F 0x5DB1 # 0 +0xE960 0x5DA9 # 0 +0xE961 0x5DA7 # 0 +0xE962 0x5DB5 # 0 +0xE963 0x5DB0 # 0 +0xE964 0x5DAE # 0 +0xE965 0x5DAA # 0 +0xE966 0x5DA8 # 0 +0xE967 0x5DB2 # 0 +0xE968 0x5DAD # 0 +0xE969 0x5DAF # 0 +0xE96A 0x5DB4 # 0 +0xE96B 0x5E67 # 0 +0xE96C 0x5E68 # 0 +0xE96D 0x5E66 # 0 +0xE96E 0x5E6F # 0 +0xE96F 0x5EE9 # 0 +0xE970 0x5EE7 # 0 +0xE971 0x5EE6 # 0 +0xE972 0x5EE8 # 0 +0xE973 0x5EE5 # 0 +0xE974 0x5F4B # 0 +0xE975 0x5FBC # 0 +0xE976 0x619D # 0 +0xE977 0x61A8 # 0 +0xE978 0x6196 # 0 +0xE979 0x61C5 # 0 +0xE97A 0x61B4 # 0 +0xE97B 0x61C6 # 0 +0xE97C 0x61C1 # 0 +0xE97D 0x61CC # 0 +0xE97E 0x61BA # 0 +0xE9A1 0x61BF # 0 +0xE9A2 0x61B8 # 0 +0xE9A3 0x618C # 0 +0xE9A4 0x64D7 # 0 +0xE9A5 0x64D6 # 0 +0xE9A6 0x64D0 # 0 +0xE9A7 0x64CF # 0 +0xE9A8 0x64C9 # 0 +0xE9A9 0x64BD # 0 +0xE9AA 0x6489 # 0 +0xE9AB 0x64C3 # 0 +0xE9AC 0x64DB # 0 +0xE9AD 0x64F3 # 0 +0xE9AE 0x64D9 # 0 +0xE9AF 0x6533 # 0 +0xE9B0 0x657F # 0 +0xE9B1 0x657C # 0 +0xE9B2 0x65A2 # 0 +0xE9B3 0x66C8 # 0 +0xE9B4 0x66BE # 0 +0xE9B5 0x66C0 # 0 +0xE9B6 0x66CA # 0 +0xE9B7 0x66CB # 0 +0xE9B8 0x66CF # 0 +0xE9B9 0x66BD # 0 +0xE9BA 0x66BB # 0 +0xE9BB 0x66BA # 0 +0xE9BC 0x66CC # 0 +0xE9BD 0x6723 # 0 +0xE9BE 0x6A34 # 0 +0xE9BF 0x6A66 # 0 +0xE9C0 0x6A49 # 0 +0xE9C1 0x6A67 # 0 +0xE9C2 0x6A32 # 0 +0xE9C3 0x6A68 # 0 +0xE9C4 0x6A3E # 0 +0xE9C5 0x6A5D # 0 +0xE9C6 0x6A6D # 0 +0xE9C7 0x6A76 # 0 +0xE9C8 0x6A5B # 0 +0xE9C9 0x6A51 # 0 +0xE9CA 0x6A28 # 0 +0xE9CB 0x6A5A # 0 +0xE9CC 0x6A3B # 0 +0xE9CD 0x6A3F # 0 +0xE9CE 0x6A41 # 0 +0xE9CF 0x6A6A # 0 +0xE9D0 0x6A64 # 0 +0xE9D1 0x6A50 # 0 +0xE9D2 0x6A4F # 0 +0xE9D3 0x6A54 # 0 +0xE9D4 0x6A6F # 0 +0xE9D5 0x6A69 # 0 +0xE9D6 0x6A60 # 0 +0xE9D7 0x6A3C # 0 +0xE9D8 0x6A5E # 0 +0xE9D9 0x6A56 # 0 +0xE9DA 0x6A55 # 0 +0xE9DB 0x6A4D # 0 +0xE9DC 0x6A4E # 0 +0xE9DD 0x6A46 # 0 +0xE9DE 0x6B55 # 0 +0xE9DF 0x6B54 # 0 +0xE9E0 0x6B56 # 0 +0xE9E1 0x6BA7 # 0 +0xE9E2 0x6BAA # 0 +0xE9E3 0x6BAB # 0 +0xE9E4 0x6BC8 # 0 +0xE9E5 0x6BC7 # 0 +0xE9E6 0x6C04 # 0 +0xE9E7 0x6C03 # 0 +0xE9E8 0x6C06 # 0 +0xE9E9 0x6FAD # 0 +0xE9EA 0x6FCB # 0 +0xE9EB 0x6FA3 # 0 +0xE9EC 0x6FC7 # 0 +0xE9ED 0x6FBC # 0 +0xE9EE 0x6FCE # 0 +0xE9EF 0x6FC8 # 0 +0xE9F0 0x6F5E # 0 +0xE9F1 0x6FC4 # 0 +0xE9F2 0x6FBD # 0 +0xE9F3 0x6F9E # 0 +0xE9F4 0x6FCA # 0 +0xE9F5 0x6FA8 # 0 +0xE9F6 0x7004 # 0 +0xE9F7 0x6FA5 # 0 +0xE9F8 0x6FAE # 0 +0xE9F9 0x6FBA # 0 +0xE9FA 0x6FAC # 0 +0xE9FB 0x6FAA # 0 +0xE9FC 0x6FCF # 0 +0xE9FD 0x6FBF # 0 +0xE9FE 0x6FB8 # 0 +0xEA40 0x6FA2 # 0 +0xEA41 0x6FC9 # 0 +0xEA42 0x6FAB # 0 +0xEA43 0x6FCD # 0 +0xEA44 0x6FAF # 0 +0xEA45 0x6FB2 # 0 +0xEA46 0x6FB0 # 0 +0xEA47 0x71C5 # 0 +0xEA48 0x71C2 # 0 +0xEA49 0x71BF # 0 +0xEA4A 0x71B8 # 0 +0xEA4B 0x71D6 # 0 +0xEA4C 0x71C0 # 0 +0xEA4D 0x71C1 # 0 +0xEA4E 0x71CB # 0 +0xEA4F 0x71D4 # 0 +0xEA50 0x71CA # 0 +0xEA51 0x71C7 # 0 +0xEA52 0x71CF # 0 +0xEA53 0x71BD # 0 +0xEA54 0x71D8 # 0 +0xEA55 0x71BC # 0 +0xEA56 0x71C6 # 0 +0xEA57 0x71DA # 0 +0xEA58 0x71DB # 0 +0xEA59 0x729D # 0 +0xEA5A 0x729E # 0 +0xEA5B 0x7369 # 0 +0xEA5C 0x7366 # 0 +0xEA5D 0x7367 # 0 +0xEA5E 0x736C # 0 +0xEA5F 0x7365 # 0 +0xEA60 0x736B # 0 +0xEA61 0x736A # 0 +0xEA62 0x747F # 0 +0xEA63 0x749A # 0 +0xEA64 0x74A0 # 0 +0xEA65 0x7494 # 0 +0xEA66 0x7492 # 0 +0xEA67 0x7495 # 0 +0xEA68 0x74A1 # 0 +0xEA69 0x750B # 0 +0xEA6A 0x7580 # 0 +0xEA6B 0x762F # 0 +0xEA6C 0x762D # 0 +0xEA6D 0x7631 # 0 +0xEA6E 0x763D # 0 +0xEA6F 0x7633 # 0 +0xEA70 0x763C # 0 +0xEA71 0x7635 # 0 +0xEA72 0x7632 # 0 +0xEA73 0x7630 # 0 +0xEA74 0x76BB # 0 +0xEA75 0x76E6 # 0 +0xEA76 0x779A # 0 +0xEA77 0x779D # 0 +0xEA78 0x77A1 # 0 +0xEA79 0x779C # 0 +0xEA7A 0x779B # 0 +0xEA7B 0x77A2 # 0 +0xEA7C 0x77A3 # 0 +0xEA7D 0x7795 # 0 +0xEA7E 0x7799 # 0 +0xEAA1 0x7797 # 0 +0xEAA2 0x78DD # 0 +0xEAA3 0x78E9 # 0 +0xEAA4 0x78E5 # 0 +0xEAA5 0x78EA # 0 +0xEAA6 0x78DE # 0 +0xEAA7 0x78E3 # 0 +0xEAA8 0x78DB # 0 +0xEAA9 0x78E1 # 0 +0xEAAA 0x78E2 # 0 +0xEAAB 0x78ED # 0 +0xEAAC 0x78DF # 0 +0xEAAD 0x78E0 # 0 +0xEAAE 0x79A4 # 0 +0xEAAF 0x7A44 # 0 +0xEAB0 0x7A48 # 0 +0xEAB1 0x7A47 # 0 +0xEAB2 0x7AB6 # 0 +0xEAB3 0x7AB8 # 0 +0xEAB4 0x7AB5 # 0 +0xEAB5 0x7AB1 # 0 +0xEAB6 0x7AB7 # 0 +0xEAB7 0x7BDE # 0 +0xEAB8 0x7BE3 # 0 +0xEAB9 0x7BE7 # 0 +0xEABA 0x7BDD # 0 +0xEABB 0x7BD5 # 0 +0xEABC 0x7BE5 # 0 +0xEABD 0x7BDA # 0 +0xEABE 0x7BE8 # 0 +0xEABF 0x7BF9 # 0 +0xEAC0 0x7BD4 # 0 +0xEAC1 0x7BEA # 0 +0xEAC2 0x7BE2 # 0 +0xEAC3 0x7BDC # 0 +0xEAC4 0x7BEB # 0 +0xEAC5 0x7BD8 # 0 +0xEAC6 0x7BDF # 0 +0xEAC7 0x7CD2 # 0 +0xEAC8 0x7CD4 # 0 +0xEAC9 0x7CD7 # 0 +0xEACA 0x7CD0 # 0 +0xEACB 0x7CD1 # 0 +0xEACC 0x7E12 # 0 +0xEACD 0x7E21 # 0 +0xEACE 0x7E17 # 0 +0xEACF 0x7E0C # 0 +0xEAD0 0x7E1F # 0 +0xEAD1 0x7E20 # 0 +0xEAD2 0x7E13 # 0 +0xEAD3 0x7E0E # 0 +0xEAD4 0x7E1C # 0 +0xEAD5 0x7E15 # 0 +0xEAD6 0x7E1A # 0 +0xEAD7 0x7E22 # 0 +0xEAD8 0x7E0B # 0 +0xEAD9 0x7E0F # 0 +0xEADA 0x7E16 # 0 +0xEADB 0x7E0D # 0 +0xEADC 0x7E14 # 0 +0xEADD 0x7E25 # 0 +0xEADE 0x7E24 # 0 +0xEADF 0x7F43 # 0 +0xEAE0 0x7F7B # 0 +0xEAE1 0x7F7C # 0 +0xEAE2 0x7F7A # 0 +0xEAE3 0x7FB1 # 0 +0xEAE4 0x7FEF # 0 +0xEAE5 0x802A # 0 +0xEAE6 0x8029 # 0 +0xEAE7 0x806C # 0 +0xEAE8 0x81B1 # 0 +0xEAE9 0x81A6 # 0 +0xEAEA 0x81AE # 0 +0xEAEB 0x81B9 # 0 +0xEAEC 0x81B5 # 0 +0xEAED 0x81AB # 0 +0xEAEE 0x81B0 # 0 +0xEAEF 0x81AC # 0 +0xEAF0 0x81B4 # 0 +0xEAF1 0x81B2 # 0 +0xEAF2 0x81B7 # 0 +0xEAF3 0x81A7 # 0 +0xEAF4 0x81F2 # 0 +0xEAF5 0x8255 # 0 +0xEAF6 0x8256 # 0 +0xEAF7 0x8257 # 0 +0xEAF8 0x8556 # 0 +0xEAF9 0x8545 # 0 +0xEAFA 0x856B # 0 +0xEAFB 0x854D # 0 +0xEAFC 0x8553 # 0 +0xEAFD 0x8561 # 0 +0xEAFE 0x8558 # 0 +0xEB40 0x8540 # 0 +0xEB41 0x8546 # 0 +0xEB42 0x8564 # 0 +0xEB43 0x8541 # 0 +0xEB44 0x8562 # 0 +0xEB45 0x8544 # 0 +0xEB46 0x8551 # 0 +0xEB47 0x8547 # 0 +0xEB48 0x8563 # 0 +0xEB49 0x853E # 0 +0xEB4A 0x855B # 0 +0xEB4B 0x8571 # 0 +0xEB4C 0x854E # 0 +0xEB4D 0x856E # 0 +0xEB4E 0x8575 # 0 +0xEB4F 0x8555 # 0 +0xEB50 0x8567 # 0 +0xEB51 0x8560 # 0 +0xEB52 0x858C # 0 +0xEB53 0x8566 # 0 +0xEB54 0x855D # 0 +0xEB55 0x8554 # 0 +0xEB56 0x8565 # 0 +0xEB57 0x856C # 0 +0xEB58 0x8663 # 0 +0xEB59 0x8665 # 0 +0xEB5A 0x8664 # 0 +0xEB5B 0x879B # 0 +0xEB5C 0x878F # 0 +0xEB5D 0x8797 # 0 +0xEB5E 0x8793 # 0 +0xEB5F 0x8792 # 0 +0xEB60 0x8788 # 0 +0xEB61 0x8781 # 0 +0xEB62 0x8796 # 0 +0xEB63 0x8798 # 0 +0xEB64 0x8779 # 0 +0xEB65 0x8787 # 0 +0xEB66 0x87A3 # 0 +0xEB67 0x8785 # 0 +0xEB68 0x8790 # 0 +0xEB69 0x8791 # 0 +0xEB6A 0x879D # 0 +0xEB6B 0x8784 # 0 +0xEB6C 0x8794 # 0 +0xEB6D 0x879C # 0 +0xEB6E 0x879A # 0 +0xEB6F 0x8789 # 0 +0xEB70 0x891E # 0 +0xEB71 0x8926 # 0 +0xEB72 0x8930 # 0 +0xEB73 0x892D # 0 +0xEB74 0x892E # 0 +0xEB75 0x8927 # 0 +0xEB76 0x8931 # 0 +0xEB77 0x8922 # 0 +0xEB78 0x8929 # 0 +0xEB79 0x8923 # 0 +0xEB7A 0x892F # 0 +0xEB7B 0x892C # 0 +0xEB7C 0x891F # 0 +0xEB7D 0x89F1 # 0 +0xEB7E 0x8AE0 # 0 +0xEBA1 0x8AE2 # 0 +0xEBA2 0x8AF2 # 0 +0xEBA3 0x8AF4 # 0 +0xEBA4 0x8AF5 # 0 +0xEBA5 0x8ADD # 0 +0xEBA6 0x8B14 # 0 +0xEBA7 0x8AE4 # 0 +0xEBA8 0x8ADF # 0 +0xEBA9 0x8AF0 # 0 +0xEBAA 0x8AC8 # 0 +0xEBAB 0x8ADE # 0 +0xEBAC 0x8AE1 # 0 +0xEBAD 0x8AE8 # 0 +0xEBAE 0x8AFF # 0 +0xEBAF 0x8AEF # 0 +0xEBB0 0x8AFB # 0 +0xEBB1 0x8C91 # 0 +0xEBB2 0x8C92 # 0 +0xEBB3 0x8C90 # 0 +0xEBB4 0x8CF5 # 0 +0xEBB5 0x8CEE # 0 +0xEBB6 0x8CF1 # 0 +0xEBB7 0x8CF0 # 0 +0xEBB8 0x8CF3 # 0 +0xEBB9 0x8D6C # 0 +0xEBBA 0x8D6E # 0 +0xEBBB 0x8DA5 # 0 +0xEBBC 0x8DA7 # 0 +0xEBBD 0x8E33 # 0 +0xEBBE 0x8E3E # 0 +0xEBBF 0x8E38 # 0 +0xEBC0 0x8E40 # 0 +0xEBC1 0x8E45 # 0 +0xEBC2 0x8E36 # 0 +0xEBC3 0x8E3C # 0 +0xEBC4 0x8E3D # 0 +0xEBC5 0x8E41 # 0 +0xEBC6 0x8E30 # 0 +0xEBC7 0x8E3F # 0 +0xEBC8 0x8EBD # 0 +0xEBC9 0x8F36 # 0 +0xEBCA 0x8F2E # 0 +0xEBCB 0x8F35 # 0 +0xEBCC 0x8F32 # 0 +0xEBCD 0x8F39 # 0 +0xEBCE 0x8F37 # 0 +0xEBCF 0x8F34 # 0 +0xEBD0 0x9076 # 0 +0xEBD1 0x9079 # 0 +0xEBD2 0x907B # 0 +0xEBD3 0x9086 # 0 +0xEBD4 0x90FA # 0 +0xEBD5 0x9133 # 0 +0xEBD6 0x9135 # 0 +0xEBD7 0x9136 # 0 +0xEBD8 0x9193 # 0 +0xEBD9 0x9190 # 0 +0xEBDA 0x9191 # 0 +0xEBDB 0x918D # 0 +0xEBDC 0x918F # 0 +0xEBDD 0x9327 # 0 +0xEBDE 0x931E # 0 +0xEBDF 0x9308 # 0 +0xEBE0 0x931F # 0 +0xEBE1 0x9306 # 0 +0xEBE2 0x930F # 0 +0xEBE3 0x937A # 0 +0xEBE4 0x9338 # 0 +0xEBE5 0x933C # 0 +0xEBE6 0x931B # 0 +0xEBE7 0x9323 # 0 +0xEBE8 0x9312 # 0 +0xEBE9 0x9301 # 0 +0xEBEA 0x9346 # 0 +0xEBEB 0x932D # 0 +0xEBEC 0x930E # 0 +0xEBED 0x930D # 0 +0xEBEE 0x92CB # 0 +0xEBEF 0x931D # 0 +0xEBF0 0x92FA # 0 +0xEBF1 0x9325 # 0 +0xEBF2 0x9313 # 0 +0xEBF3 0x92F9 # 0 +0xEBF4 0x92F7 # 0 +0xEBF5 0x9334 # 0 +0xEBF6 0x9302 # 0 +0xEBF7 0x9324 # 0 +0xEBF8 0x92FF # 0 +0xEBF9 0x9329 # 0 +0xEBFA 0x9339 # 0 +0xEBFB 0x9335 # 0 +0xEBFC 0x932A # 0 +0xEBFD 0x9314 # 0 +0xEBFE 0x930C # 0 +0xEC40 0x930B # 0 +0xEC41 0x92FE # 0 +0xEC42 0x9309 # 0 +0xEC43 0x9300 # 0 +0xEC44 0x92FB # 0 +0xEC45 0x9316 # 0 +0xEC46 0x95BC # 0 +0xEC47 0x95CD # 0 +0xEC48 0x95BE # 0 +0xEC49 0x95B9 # 0 +0xEC4A 0x95BA # 0 +0xEC4B 0x95B6 # 0 +0xEC4C 0x95BF # 0 +0xEC4D 0x95B5 # 0 +0xEC4E 0x95BD # 0 +0xEC4F 0x96A9 # 0 +0xEC50 0x96D4 # 0 +0xEC51 0x970B # 0 +0xEC52 0x9712 # 0 +0xEC53 0x9710 # 0 +0xEC54 0x9799 # 0 +0xEC55 0x9797 # 0 +0xEC56 0x9794 # 0 +0xEC57 0x97F0 # 0 +0xEC58 0x97F8 # 0 +0xEC59 0x9835 # 0 +0xEC5A 0x982F # 0 +0xEC5B 0x9832 # 0 +0xEC5C 0x9924 # 0 +0xEC5D 0x991F # 0 +0xEC5E 0x9927 # 0 +0xEC5F 0x9929 # 0 +0xEC60 0x999E # 0 +0xEC61 0x99EE # 0 +0xEC62 0x99EC # 0 +0xEC63 0x99E5 # 0 +0xEC64 0x99E4 # 0 +0xEC65 0x99F0 # 0 +0xEC66 0x99E3 # 0 +0xEC67 0x99EA # 0 +0xEC68 0x99E9 # 0 +0xEC69 0x99E7 # 0 +0xEC6A 0x9AB9 # 0 +0xEC6B 0x9ABF # 0 +0xEC6C 0x9AB4 # 0 +0xEC6D 0x9ABB # 0 +0xEC6E 0x9AF6 # 0 +0xEC6F 0x9AFA # 0 +0xEC70 0x9AF9 # 0 +0xEC71 0x9AF7 # 0 +0xEC72 0x9B33 # 0 +0xEC73 0x9B80 # 0 +0xEC74 0x9B85 # 0 +0xEC75 0x9B87 # 0 +0xEC76 0x9B7C # 0 +0xEC77 0x9B7E # 0 +0xEC78 0x9B7B # 0 +0xEC79 0x9B82 # 0 +0xEC7A 0x9B93 # 0 +0xEC7B 0x9B92 # 0 +0xEC7C 0x9B90 # 0 +0xEC7D 0x9B7A # 0 +0xEC7E 0x9B95 # 0 +0xECA1 0x9B7D # 0 +0xECA2 0x9B88 # 0 +0xECA3 0x9D25 # 0 +0xECA4 0x9D17 # 0 +0xECA5 0x9D20 # 0 +0xECA6 0x9D1E # 0 +0xECA7 0x9D14 # 0 +0xECA8 0x9D29 # 0 +0xECA9 0x9D1D # 0 +0xECAA 0x9D18 # 0 +0xECAB 0x9D22 # 0 +0xECAC 0x9D10 # 0 +0xECAD 0x9D19 # 0 +0xECAE 0x9D1F # 0 +0xECAF 0x9E88 # 0 +0xECB0 0x9E86 # 0 +0xECB1 0x9E87 # 0 +0xECB2 0x9EAE # 0 +0xECB3 0x9EAD # 0 +0xECB4 0x9ED5 # 0 +0xECB5 0x9ED6 # 0 +0xECB6 0x9EFA # 0 +0xECB7 0x9F12 # 0 +0xECB8 0x9F3D # 0 +0xECB9 0x5126 # 0 +0xECBA 0x5125 # 0 +0xECBB 0x5122 # 0 +0xECBC 0x5124 # 0 +0xECBD 0x5120 # 0 +0xECBE 0x5129 # 0 +0xECBF 0x52F4 # 0 +0xECC0 0x5693 # 0 +0xECC1 0x568C # 0 +0xECC2 0x568D # 0 +0xECC3 0x5686 # 0 +0xECC4 0x5684 # 0 +0xECC5 0x5683 # 0 +0xECC6 0x567E # 0 +0xECC7 0x5682 # 0 +0xECC8 0x567F # 0 +0xECC9 0x5681 # 0 +0xECCA 0x58D6 # 0 +0xECCB 0x58D4 # 0 +0xECCC 0x58CF # 0 +0xECCD 0x58D2 # 0 +0xECCE 0x5B2D # 0 +0xECCF 0x5B25 # 0 +0xECD0 0x5B32 # 0 +0xECD1 0x5B23 # 0 +0xECD2 0x5B2C # 0 +0xECD3 0x5B27 # 0 +0xECD4 0x5B26 # 0 +0xECD5 0x5B2F # 0 +0xECD6 0x5B2E # 0 +0xECD7 0x5B7B # 0 +0xECD8 0x5BF1 # 0 +0xECD9 0x5BF2 # 0 +0xECDA 0x5DB7 # 0 +0xECDB 0x5E6C # 0 +0xECDC 0x5E6A # 0 +0xECDD 0x5FBE # 0 +0xECDE 0x5FBB # 0 +0xECDF 0x61C3 # 0 +0xECE0 0x61B5 # 0 +0xECE1 0x61BC # 0 +0xECE2 0x61E7 # 0 +0xECE3 0x61E0 # 0 +0xECE4 0x61E5 # 0 +0xECE5 0x61E4 # 0 +0xECE6 0x61E8 # 0 +0xECE7 0x61DE # 0 +0xECE8 0x64EF # 0 +0xECE9 0x64E9 # 0 +0xECEA 0x64E3 # 0 +0xECEB 0x64EB # 0 +0xECEC 0x64E4 # 0 +0xECED 0x64E8 # 0 +0xECEE 0x6581 # 0 +0xECEF 0x6580 # 0 +0xECF0 0x65B6 # 0 +0xECF1 0x65DA # 0 +0xECF2 0x66D2 # 0 +0xECF3 0x6A8D # 0 +0xECF4 0x6A96 # 0 +0xECF5 0x6A81 # 0 +0xECF6 0x6AA5 # 0 +0xECF7 0x6A89 # 0 +0xECF8 0x6A9F # 0 +0xECF9 0x6A9B # 0 +0xECFA 0x6AA1 # 0 +0xECFB 0x6A9E # 0 +0xECFC 0x6A87 # 0 +0xECFD 0x6A93 # 0 +0xECFE 0x6A8E # 0 +0xED40 0x6A95 # 0 +0xED41 0x6A83 # 0 +0xED42 0x6AA8 # 0 +0xED43 0x6AA4 # 0 +0xED44 0x6A91 # 0 +0xED45 0x6A7F # 0 +0xED46 0x6AA6 # 0 +0xED47 0x6A9A # 0 +0xED48 0x6A85 # 0 +0xED49 0x6A8C # 0 +0xED4A 0x6A92 # 0 +0xED4B 0x6B5B # 0 +0xED4C 0x6BAD # 0 +0xED4D 0x6C09 # 0 +0xED4E 0x6FCC # 0 +0xED4F 0x6FA9 # 0 +0xED50 0x6FF4 # 0 +0xED51 0x6FD4 # 0 +0xED52 0x6FE3 # 0 +0xED53 0x6FDC # 0 +0xED54 0x6FED # 0 +0xED55 0x6FE7 # 0 +0xED56 0x6FE6 # 0 +0xED57 0x6FDE # 0 +0xED58 0x6FF2 # 0 +0xED59 0x6FDD # 0 +0xED5A 0x6FE2 # 0 +0xED5B 0x6FE8 # 0 +0xED5C 0x71E1 # 0 +0xED5D 0x71F1 # 0 +0xED5E 0x71E8 # 0 +0xED5F 0x71F2 # 0 +0xED60 0x71E4 # 0 +0xED61 0x71F0 # 0 +0xED62 0x71E2 # 0 +0xED63 0x7373 # 0 +0xED64 0x736E # 0 +0xED65 0x736F # 0 +0xED66 0x7497 # 0 +0xED67 0x74B2 # 0 +0xED68 0x74AB # 0 +0xED69 0x7490 # 0 +0xED6A 0x74AA # 0 +0xED6B 0x74AD # 0 +0xED6C 0x74B1 # 0 +0xED6D 0x74A5 # 0 +0xED6E 0x74AF # 0 +0xED6F 0x7510 # 0 +0xED70 0x7511 # 0 +0xED71 0x7512 # 0 +0xED72 0x750F # 0 +0xED73 0x7584 # 0 +0xED74 0x7643 # 0 +0xED75 0x7648 # 0 +0xED76 0x7649 # 0 +0xED77 0x7647 # 0 +0xED78 0x76A4 # 0 +0xED79 0x76E9 # 0 +0xED7A 0x77B5 # 0 +0xED7B 0x77AB # 0 +0xED7C 0x77B2 # 0 +0xED7D 0x77B7 # 0 +0xED7E 0x77B6 # 0 +0xEDA1 0x77B4 # 0 +0xEDA2 0x77B1 # 0 +0xEDA3 0x77A8 # 0 +0xEDA4 0x77F0 # 0 +0xEDA5 0x78F3 # 0 +0xEDA6 0x78FD # 0 +0xEDA7 0x7902 # 0 +0xEDA8 0x78FB # 0 +0xEDA9 0x78FC # 0 +0xEDAA 0x78F2 # 0 +0xEDAB 0x7905 # 0 +0xEDAC 0x78F9 # 0 +0xEDAD 0x78FE # 0 +0xEDAE 0x7904 # 0 +0xEDAF 0x79AB # 0 +0xEDB0 0x79A8 # 0 +0xEDB1 0x7A5C # 0 +0xEDB2 0x7A5B # 0 +0xEDB3 0x7A56 # 0 +0xEDB4 0x7A58 # 0 +0xEDB5 0x7A54 # 0 +0xEDB6 0x7A5A # 0 +0xEDB7 0x7ABE # 0 +0xEDB8 0x7AC0 # 0 +0xEDB9 0x7AC1 # 0 +0xEDBA 0x7C05 # 0 +0xEDBB 0x7C0F # 0 +0xEDBC 0x7BF2 # 0 +0xEDBD 0x7C00 # 0 +0xEDBE 0x7BFF # 0 +0xEDBF 0x7BFB # 0 +0xEDC0 0x7C0E # 0 +0xEDC1 0x7BF4 # 0 +0xEDC2 0x7C0B # 0 +0xEDC3 0x7BF3 # 0 +0xEDC4 0x7C02 # 0 +0xEDC5 0x7C09 # 0 +0xEDC6 0x7C03 # 0 +0xEDC7 0x7C01 # 0 +0xEDC8 0x7BF8 # 0 +0xEDC9 0x7BFD # 0 +0xEDCA 0x7C06 # 0 +0xEDCB 0x7BF0 # 0 +0xEDCC 0x7BF1 # 0 +0xEDCD 0x7C10 # 0 +0xEDCE 0x7C0A # 0 +0xEDCF 0x7CE8 # 0 +0xEDD0 0x7E2D # 0 +0xEDD1 0x7E3C # 0 +0xEDD2 0x7E42 # 0 +0xEDD3 0x7E33 # 0 +0xEDD4 0x9848 # 0 +0xEDD5 0x7E38 # 0 +0xEDD6 0x7E2A # 0 +0xEDD7 0x7E49 # 0 +0xEDD8 0x7E40 # 0 +0xEDD9 0x7E47 # 0 +0xEDDA 0x7E29 # 0 +0xEDDB 0x7E4C # 0 +0xEDDC 0x7E30 # 0 +0xEDDD 0x7E3B # 0 +0xEDDE 0x7E36 # 0 +0xEDDF 0x7E44 # 0 +0xEDE0 0x7E3A # 0 +0xEDE1 0x7F45 # 0 +0xEDE2 0x7F7F # 0 +0xEDE3 0x7F7E # 0 +0xEDE4 0x7F7D # 0 +0xEDE5 0x7FF4 # 0 +0xEDE6 0x7FF2 # 0 +0xEDE7 0x802C # 0 +0xEDE8 0x81BB # 0 +0xEDE9 0x81C4 # 0 +0xEDEA 0x81CC # 0 +0xEDEB 0x81CA # 0 +0xEDEC 0x81C5 # 0 +0xEDED 0x81C7 # 0 +0xEDEE 0x81BC # 0 +0xEDEF 0x81E9 # 0 +0xEDF0 0x825B # 0 +0xEDF1 0x825A # 0 +0xEDF2 0x825C # 0 +0xEDF3 0x8583 # 0 +0xEDF4 0x8580 # 0 +0xEDF5 0x858F # 0 +0xEDF6 0x85A7 # 0 +0xEDF7 0x8595 # 0 +0xEDF8 0x85A0 # 0 +0xEDF9 0x858B # 0 +0xEDFA 0x85A3 # 0 +0xEDFB 0x857B # 0 +0xEDFC 0x85A4 # 0 +0xEDFD 0x859A # 0 +0xEDFE 0x859E # 0 +0xEE40 0x8577 # 0 +0xEE41 0x857C # 0 +0xEE42 0x8589 # 0 +0xEE43 0x85A1 # 0 +0xEE44 0x857A # 0 +0xEE45 0x8578 # 0 +0xEE46 0x8557 # 0 +0xEE47 0x858E # 0 +0xEE48 0x8596 # 0 +0xEE49 0x8586 # 0 +0xEE4A 0x858D # 0 +0xEE4B 0x8599 # 0 +0xEE4C 0x859D # 0 +0xEE4D 0x8581 # 0 +0xEE4E 0x85A2 # 0 +0xEE4F 0x8582 # 0 +0xEE50 0x8588 # 0 +0xEE51 0x8585 # 0 +0xEE52 0x8579 # 0 +0xEE53 0x8576 # 0 +0xEE54 0x8598 # 0 +0xEE55 0x8590 # 0 +0xEE56 0x859F # 0 +0xEE57 0x8668 # 0 +0xEE58 0x87BE # 0 +0xEE59 0x87AA # 0 +0xEE5A 0x87AD # 0 +0xEE5B 0x87C5 # 0 +0xEE5C 0x87B0 # 0 +0xEE5D 0x87AC # 0 +0xEE5E 0x87B9 # 0 +0xEE5F 0x87B5 # 0 +0xEE60 0x87BC # 0 +0xEE61 0x87AE # 0 +0xEE62 0x87C9 # 0 +0xEE63 0x87C3 # 0 +0xEE64 0x87C2 # 0 +0xEE65 0x87CC # 0 +0xEE66 0x87B7 # 0 +0xEE67 0x87AF # 0 +0xEE68 0x87C4 # 0 +0xEE69 0x87CA # 0 +0xEE6A 0x87B4 # 0 +0xEE6B 0x87B6 # 0 +0xEE6C 0x87BF # 0 +0xEE6D 0x87B8 # 0 +0xEE6E 0x87BD # 0 +0xEE6F 0x87DE # 0 +0xEE70 0x87B2 # 0 +0xEE71 0x8935 # 0 +0xEE72 0x8933 # 0 +0xEE73 0x893C # 0 +0xEE74 0x893E # 0 +0xEE75 0x8941 # 0 +0xEE76 0x8952 # 0 +0xEE77 0x8937 # 0 +0xEE78 0x8942 # 0 +0xEE79 0x89AD # 0 +0xEE7A 0x89AF # 0 +0xEE7B 0x89AE # 0 +0xEE7C 0x89F2 # 0 +0xEE7D 0x89F3 # 0 +0xEE7E 0x8B1E # 0 +0xEEA1 0x8B18 # 0 +0xEEA2 0x8B16 # 0 +0xEEA3 0x8B11 # 0 +0xEEA4 0x8B05 # 0 +0xEEA5 0x8B0B # 0 +0xEEA6 0x8B22 # 0 +0xEEA7 0x8B0F # 0 +0xEEA8 0x8B12 # 0 +0xEEA9 0x8B15 # 0 +0xEEAA 0x8B07 # 0 +0xEEAB 0x8B0D # 0 +0xEEAC 0x8B08 # 0 +0xEEAD 0x8B06 # 0 +0xEEAE 0x8B1C # 0 +0xEEAF 0x8B13 # 0 +0xEEB0 0x8B1A # 0 +0xEEB1 0x8C4F # 0 +0xEEB2 0x8C70 # 0 +0xEEB3 0x8C72 # 0 +0xEEB4 0x8C71 # 0 +0xEEB5 0x8C6F # 0 +0xEEB6 0x8C95 # 0 +0xEEB7 0x8C94 # 0 +0xEEB8 0x8CF9 # 0 +0xEEB9 0x8D6F # 0 +0xEEBA 0x8E4E # 0 +0xEEBB 0x8E4D # 0 +0xEEBC 0x8E53 # 0 +0xEEBD 0x8E50 # 0 +0xEEBE 0x8E4C # 0 +0xEEBF 0x8E47 # 0 +0xEEC0 0x8F43 # 0 +0xEEC1 0x8F40 # 0 +0xEEC2 0x9085 # 0 +0xEEC3 0x907E # 0 +0xEEC4 0x9138 # 0 +0xEEC5 0x919A # 0 +0xEEC6 0x91A2 # 0 +0xEEC7 0x919B # 0 +0xEEC8 0x9199 # 0 +0xEEC9 0x919F # 0 +0xEECA 0x91A1 # 0 +0xEECB 0x919D # 0 +0xEECC 0x91A0 # 0 +0xEECD 0x93A1 # 0 +0xEECE 0x9383 # 0 +0xEECF 0x93AF # 0 +0xEED0 0x9364 # 0 +0xEED1 0x9356 # 0 +0xEED2 0x9347 # 0 +0xEED3 0x937C # 0 +0xEED4 0x9358 # 0 +0xEED5 0x935C # 0 +0xEED6 0x9376 # 0 +0xEED7 0x9349 # 0 +0xEED8 0x9350 # 0 +0xEED9 0x9351 # 0 +0xEEDA 0x9360 # 0 +0xEEDB 0x936D # 0 +0xEEDC 0x938F # 0 +0xEEDD 0x934C # 0 +0xEEDE 0x936A # 0 +0xEEDF 0x9379 # 0 +0xEEE0 0x9357 # 0 +0xEEE1 0x9355 # 0 +0xEEE2 0x9352 # 0 +0xEEE3 0x934F # 0 +0xEEE4 0x9371 # 0 +0xEEE5 0x9377 # 0 +0xEEE6 0x937B # 0 +0xEEE7 0x9361 # 0 +0xEEE8 0x935E # 0 +0xEEE9 0x9363 # 0 +0xEEEA 0x9367 # 0 +0xEEEB 0x9380 # 0 +0xEEEC 0x934E # 0 +0xEEED 0x9359 # 0 +0xEEEE 0x95C7 # 0 +0xEEEF 0x95C0 # 0 +0xEEF0 0x95C9 # 0 +0xEEF1 0x95C3 # 0 +0xEEF2 0x95C5 # 0 +0xEEF3 0x95B7 # 0 +0xEEF4 0x96AE # 0 +0xEEF5 0x96B0 # 0 +0xEEF6 0x96AC # 0 +0xEEF7 0x9720 # 0 +0xEEF8 0x971F # 0 +0xEEF9 0x9718 # 0 +0xEEFA 0x971D # 0 +0xEEFB 0x9719 # 0 +0xEEFC 0x979A # 0 +0xEEFD 0x97A1 # 0 +0xEEFE 0x979C # 0 +0xEF40 0x979E # 0 +0xEF41 0x979D # 0 +0xEF42 0x97D5 # 0 +0xEF43 0x97D4 # 0 +0xEF44 0x97F1 # 0 +0xEF45 0x9841 # 0 +0xEF46 0x9844 # 0 +0xEF47 0x984A # 0 +0xEF48 0x9849 # 0 +0xEF49 0x9845 # 0 +0xEF4A 0x9843 # 0 +0xEF4B 0x9925 # 0 +0xEF4C 0x992B # 0 +0xEF4D 0x992C # 0 +0xEF4E 0x992A # 0 +0xEF4F 0x9933 # 0 +0xEF50 0x9932 # 0 +0xEF51 0x992F # 0 +0xEF52 0x992D # 0 +0xEF53 0x9931 # 0 +0xEF54 0x9930 # 0 +0xEF55 0x9998 # 0 +0xEF56 0x99A3 # 0 +0xEF57 0x99A1 # 0 +0xEF58 0x9A02 # 0 +0xEF59 0x99FA # 0 +0xEF5A 0x99F4 # 0 +0xEF5B 0x99F7 # 0 +0xEF5C 0x99F9 # 0 +0xEF5D 0x99F8 # 0 +0xEF5E 0x99F6 # 0 +0xEF5F 0x99FB # 0 +0xEF60 0x99FD # 0 +0xEF61 0x99FE # 0 +0xEF62 0x99FC # 0 +0xEF63 0x9A03 # 0 +0xEF64 0x9ABE # 0 +0xEF65 0x9AFE # 0 +0xEF66 0x9AFD # 0 +0xEF67 0x9B01 # 0 +0xEF68 0x9AFC # 0 +0xEF69 0x9B48 # 0 +0xEF6A 0x9B9A # 0 +0xEF6B 0x9BA8 # 0 +0xEF6C 0x9B9E # 0 +0xEF6D 0x9B9B # 0 +0xEF6E 0x9BA6 # 0 +0xEF6F 0x9BA1 # 0 +0xEF70 0x9BA5 # 0 +0xEF71 0x9BA4 # 0 +0xEF72 0x9B86 # 0 +0xEF73 0x9BA2 # 0 +0xEF74 0x9BA0 # 0 +0xEF75 0x9BAF # 0 +0xEF76 0x9D33 # 0 +0xEF77 0x9D41 # 0 +0xEF78 0x9D67 # 0 +0xEF79 0x9D36 # 0 +0xEF7A 0x9D2E # 0 +0xEF7B 0x9D2F # 0 +0xEF7C 0x9D31 # 0 +0xEF7D 0x9D38 # 0 +0xEF7E 0x9D30 # 0 +0xEFA1 0x9D45 # 0 +0xEFA2 0x9D42 # 0 +0xEFA3 0x9D43 # 0 +0xEFA4 0x9D3E # 0 +0xEFA5 0x9D37 # 0 +0xEFA6 0x9D40 # 0 +0xEFA7 0x9D3D # 0 +0xEFA8 0x7FF5 # 0 +0xEFA9 0x9D2D # 0 +0xEFAA 0x9E8A # 0 +0xEFAB 0x9E89 # 0 +0xEFAC 0x9E8D # 0 +0xEFAD 0x9EB0 # 0 +0xEFAE 0x9EC8 # 0 +0xEFAF 0x9EDA # 0 +0xEFB0 0x9EFB # 0 +0xEFB1 0x9EFF # 0 +0xEFB2 0x9F24 # 0 +0xEFB3 0x9F23 # 0 +0xEFB4 0x9F22 # 0 +0xEFB5 0x9F54 # 0 +0xEFB6 0x9FA0 # 0 +0xEFB7 0x5131 # 0 +0xEFB8 0x512D # 0 +0xEFB9 0x512E # 0 +0xEFBA 0x5698 # 0 +0xEFBB 0x569C # 0 +0xEFBC 0x5697 # 0 +0xEFBD 0x569A # 0 +0xEFBE 0x569D # 0 +0xEFBF 0x5699 # 0 +0xEFC0 0x5970 # 0 +0xEFC1 0x5B3C # 0 +0xEFC2 0x5C69 # 0 +0xEFC3 0x5C6A # 0 +0xEFC4 0x5DC0 # 0 +0xEFC5 0x5E6D # 0 +0xEFC6 0x5E6E # 0 +0xEFC7 0x61D8 # 0 +0xEFC8 0x61DF # 0 +0xEFC9 0x61ED # 0 +0xEFCA 0x61EE # 0 +0xEFCB 0x61F1 # 0 +0xEFCC 0x61EA # 0 +0xEFCD 0x61F0 # 0 +0xEFCE 0x61EB # 0 +0xEFCF 0x61D6 # 0 +0xEFD0 0x61E9 # 0 +0xEFD1 0x64FF # 0 +0xEFD2 0x6504 # 0 +0xEFD3 0x64FD # 0 +0xEFD4 0x64F8 # 0 +0xEFD5 0x6501 # 0 +0xEFD6 0x6503 # 0 +0xEFD7 0x64FC # 0 +0xEFD8 0x6594 # 0 +0xEFD9 0x65DB # 0 +0xEFDA 0x66DA # 0 +0xEFDB 0x66DB # 0 +0xEFDC 0x66D8 # 0 +0xEFDD 0x6AC5 # 0 +0xEFDE 0x6AB9 # 0 +0xEFDF 0x6ABD # 0 +0xEFE0 0x6AE1 # 0 +0xEFE1 0x6AC6 # 0 +0xEFE2 0x6ABA # 0 +0xEFE3 0x6AB6 # 0 +0xEFE4 0x6AB7 # 0 +0xEFE5 0x6AC7 # 0 +0xEFE6 0x6AB4 # 0 +0xEFE7 0x6AAD # 0 +0xEFE8 0x6B5E # 0 +0xEFE9 0x6BC9 # 0 +0xEFEA 0x6C0B # 0 +0xEFEB 0x7007 # 0 +0xEFEC 0x700C # 0 +0xEFED 0x700D # 0 +0xEFEE 0x7001 # 0 +0xEFEF 0x7005 # 0 +0xEFF0 0x7014 # 0 +0xEFF1 0x700E # 0 +0xEFF2 0x6FFF # 0 +0xEFF3 0x7000 # 0 +0xEFF4 0x6FFB # 0 +0xEFF5 0x7026 # 0 +0xEFF6 0x6FFC # 0 +0xEFF7 0x6FF7 # 0 +0xEFF8 0x700A # 0 +0xEFF9 0x7201 # 0 +0xEFFA 0x71FF # 0 +0xEFFB 0x71F9 # 0 +0xEFFC 0x7203 # 0 +0xEFFD 0x71FD # 0 +0xEFFE 0x7376 # 0 +0xF040 0x74B8 # 0 +0xF041 0x74C0 # 0 +0xF042 0x74B5 # 0 +0xF043 0x74C1 # 0 +0xF044 0x74BE # 0 +0xF045 0x74B6 # 0 +0xF046 0x74BB # 0 +0xF047 0x74C2 # 0 +0xF048 0x7514 # 0 +0xF049 0x7513 # 0 +0xF04A 0x765C # 0 +0xF04B 0x7664 # 0 +0xF04C 0x7659 # 0 +0xF04D 0x7650 # 0 +0xF04E 0x7653 # 0 +0xF04F 0x7657 # 0 +0xF050 0x765A # 0 +0xF051 0x76A6 # 0 +0xF052 0x76BD # 0 +0xF053 0x76EC # 0 +0xF054 0x77C2 # 0 +0xF055 0x77BA # 0 +0xF056 0x78FF # 0 +0xF057 0x790C # 0 +0xF058 0x7913 # 0 +0xF059 0x7914 # 0 +0xF05A 0x7909 # 0 +0xF05B 0x7910 # 0 +0xF05C 0x7912 # 0 +0xF05D 0x7911 # 0 +0xF05E 0x79AD # 0 +0xF05F 0x79AC # 0 +0xF060 0x7A5F # 0 +0xF061 0x7C1C # 0 +0xF062 0x7C29 # 0 +0xF063 0x7C19 # 0 +0xF064 0x7C20 # 0 +0xF065 0x7C1F # 0 +0xF066 0x7C2D # 0 +0xF067 0x7C1D # 0 +0xF068 0x7C26 # 0 +0xF069 0x7C28 # 0 +0xF06A 0x7C22 # 0 +0xF06B 0x7C25 # 0 +0xF06C 0x7C30 # 0 +0xF06D 0x7E5C # 0 +0xF06E 0x7E50 # 0 +0xF06F 0x7E56 # 0 +0xF070 0x7E63 # 0 +0xF071 0x7E58 # 0 +0xF072 0x7E62 # 0 +0xF073 0x7E5F # 0 +0xF074 0x7E51 # 0 +0xF075 0x7E60 # 0 +0xF076 0x7E57 # 0 +0xF077 0x7E53 # 0 +0xF078 0x7FB5 # 0 +0xF079 0x7FB3 # 0 +0xF07A 0x7FF7 # 0 +0xF07B 0x7FF8 # 0 +0xF07C 0x8075 # 0 +0xF07D 0x81D1 # 0 +0xF07E 0x81D2 # 0 +0xF0A1 0x81D0 # 0 +0xF0A2 0x825F # 0 +0xF0A3 0x825E # 0 +0xF0A4 0x85B4 # 0 +0xF0A5 0x85C6 # 0 +0xF0A6 0x85C0 # 0 +0xF0A7 0x85C3 # 0 +0xF0A8 0x85C2 # 0 +0xF0A9 0x85B3 # 0 +0xF0AA 0x85B5 # 0 +0xF0AB 0x85BD # 0 +0xF0AC 0x85C7 # 0 +0xF0AD 0x85C4 # 0 +0xF0AE 0x85BF # 0 +0xF0AF 0x85CB # 0 +0xF0B0 0x85CE # 0 +0xF0B1 0x85C8 # 0 +0xF0B2 0x85C5 # 0 +0xF0B3 0x85B1 # 0 +0xF0B4 0x85B6 # 0 +0xF0B5 0x85D2 # 0 +0xF0B6 0x8624 # 0 +0xF0B7 0x85B8 # 0 +0xF0B8 0x85B7 # 0 +0xF0B9 0x85BE # 0 +0xF0BA 0x8669 # 0 +0xF0BB 0x87E7 # 0 +0xF0BC 0x87E6 # 0 +0xF0BD 0x87E2 # 0 +0xF0BE 0x87DB # 0 +0xF0BF 0x87EB # 0 +0xF0C0 0x87EA # 0 +0xF0C1 0x87E5 # 0 +0xF0C2 0x87DF # 0 +0xF0C3 0x87F3 # 0 +0xF0C4 0x87E4 # 0 +0xF0C5 0x87D4 # 0 +0xF0C6 0x87DC # 0 +0xF0C7 0x87D3 # 0 +0xF0C8 0x87ED # 0 +0xF0C9 0x87D8 # 0 +0xF0CA 0x87E3 # 0 +0xF0CB 0x87A4 # 0 +0xF0CC 0x87D7 # 0 +0xF0CD 0x87D9 # 0 +0xF0CE 0x8801 # 0 +0xF0CF 0x87F4 # 0 +0xF0D0 0x87E8 # 0 +0xF0D1 0x87DD # 0 +0xF0D2 0x8953 # 0 +0xF0D3 0x894B # 0 +0xF0D4 0x894F # 0 +0xF0D5 0x894C # 0 +0xF0D6 0x8946 # 0 +0xF0D7 0x8950 # 0 +0xF0D8 0x8951 # 0 +0xF0D9 0x8949 # 0 +0xF0DA 0x8B2A # 0 +0xF0DB 0x8B27 # 0 +0xF0DC 0x8B23 # 0 +0xF0DD 0x8B33 # 0 +0xF0DE 0x8B30 # 0 +0xF0DF 0x8B35 # 0 +0xF0E0 0x8B47 # 0 +0xF0E1 0x8B2F # 0 +0xF0E2 0x8B3C # 0 +0xF0E3 0x8B3E # 0 +0xF0E4 0x8B31 # 0 +0xF0E5 0x8B25 # 0 +0xF0E6 0x8B37 # 0 +0xF0E7 0x8B26 # 0 +0xF0E8 0x8B36 # 0 +0xF0E9 0x8B2E # 0 +0xF0EA 0x8B24 # 0 +0xF0EB 0x8B3B # 0 +0xF0EC 0x8B3D # 0 +0xF0ED 0x8B3A # 0 +0xF0EE 0x8C42 # 0 +0xF0EF 0x8C75 # 0 +0xF0F0 0x8C99 # 0 +0xF0F1 0x8C98 # 0 +0xF0F2 0x8C97 # 0 +0xF0F3 0x8CFE # 0 +0xF0F4 0x8D04 # 0 +0xF0F5 0x8D02 # 0 +0xF0F6 0x8D00 # 0 +0xF0F7 0x8E5C # 0 +0xF0F8 0x8E62 # 0 +0xF0F9 0x8E60 # 0 +0xF0FA 0x8E57 # 0 +0xF0FB 0x8E56 # 0 +0xF0FC 0x8E5E # 0 +0xF0FD 0x8E65 # 0 +0xF0FE 0x8E67 # 0 +0xF140 0x8E5B # 0 +0xF141 0x8E5A # 0 +0xF142 0x8E61 # 0 +0xF143 0x8E5D # 0 +0xF144 0x8E69 # 0 +0xF145 0x8E54 # 0 +0xF146 0x8F46 # 0 +0xF147 0x8F47 # 0 +0xF148 0x8F48 # 0 +0xF149 0x8F4B # 0 +0xF14A 0x9128 # 0 +0xF14B 0x913A # 0 +0xF14C 0x913B # 0 +0xF14D 0x913E # 0 +0xF14E 0x91A8 # 0 +0xF14F 0x91A5 # 0 +0xF150 0x91A7 # 0 +0xF151 0x91AF # 0 +0xF152 0x91AA # 0 +0xF153 0x93B5 # 0 +0xF154 0x938C # 0 +0xF155 0x9392 # 0 +0xF156 0x93B7 # 0 +0xF157 0x939B # 0 +0xF158 0x939D # 0 +0xF159 0x9389 # 0 +0xF15A 0x93A7 # 0 +0xF15B 0x938E # 0 +0xF15C 0x93AA # 0 +0xF15D 0x939E # 0 +0xF15E 0x93A6 # 0 +0xF15F 0x9395 # 0 +0xF160 0x9388 # 0 +0xF161 0x9399 # 0 +0xF162 0x939F # 0 +0xF163 0x938D # 0 +0xF164 0x93B1 # 0 +0xF165 0x9391 # 0 +0xF166 0x93B2 # 0 +0xF167 0x93A4 # 0 +0xF168 0x93A8 # 0 +0xF169 0x93B4 # 0 +0xF16A 0x93A3 # 0 +0xF16B 0x93A5 # 0 +0xF16C 0x95D2 # 0 +0xF16D 0x95D3 # 0 +0xF16E 0x95D1 # 0 +0xF16F 0x96B3 # 0 +0xF170 0x96D7 # 0 +0xF171 0x96DA # 0 +0xF172 0x5DC2 # 0 +0xF173 0x96DF # 0 +0xF174 0x96D8 # 0 +0xF175 0x96DD # 0 +0xF176 0x9723 # 0 +0xF177 0x9722 # 0 +0xF178 0x9725 # 0 +0xF179 0x97AC # 0 +0xF17A 0x97AE # 0 +0xF17B 0x97A8 # 0 +0xF17C 0x97AB # 0 +0xF17D 0x97A4 # 0 +0xF17E 0x97AA # 0 +0xF1A1 0x97A2 # 0 +0xF1A2 0x97A5 # 0 +0xF1A3 0x97D7 # 0 +0xF1A4 0x97D9 # 0 +0xF1A5 0x97D6 # 0 +0xF1A6 0x97D8 # 0 +0xF1A7 0x97FA # 0 +0xF1A8 0x9850 # 0 +0xF1A9 0x9851 # 0 +0xF1AA 0x9852 # 0 +0xF1AB 0x98B8 # 0 +0xF1AC 0x9941 # 0 +0xF1AD 0x993C # 0 +0xF1AE 0x993A # 0 +0xF1AF 0x9A0F # 0 +0xF1B0 0x9A0B # 0 +0xF1B1 0x9A09 # 0 +0xF1B2 0x9A0D # 0 +0xF1B3 0x9A04 # 0 +0xF1B4 0x9A11 # 0 +0xF1B5 0x9A0A # 0 +0xF1B6 0x9A05 # 0 +0xF1B7 0x9A07 # 0 +0xF1B8 0x9A06 # 0 +0xF1B9 0x9AC0 # 0 +0xF1BA 0x9ADC # 0 +0xF1BB 0x9B08 # 0 +0xF1BC 0x9B04 # 0 +0xF1BD 0x9B05 # 0 +0xF1BE 0x9B29 # 0 +0xF1BF 0x9B35 # 0 +0xF1C0 0x9B4A # 0 +0xF1C1 0x9B4C # 0 +0xF1C2 0x9B4B # 0 +0xF1C3 0x9BC7 # 0 +0xF1C4 0x9BC6 # 0 +0xF1C5 0x9BC3 # 0 +0xF1C6 0x9BBF # 0 +0xF1C7 0x9BC1 # 0 +0xF1C8 0x9BB5 # 0 +0xF1C9 0x9BB8 # 0 +0xF1CA 0x9BD3 # 0 +0xF1CB 0x9BB6 # 0 +0xF1CC 0x9BC4 # 0 +0xF1CD 0x9BB9 # 0 +0xF1CE 0x9BBD # 0 +0xF1CF 0x9D5C # 0 +0xF1D0 0x9D53 # 0 +0xF1D1 0x9D4F # 0 +0xF1D2 0x9D4A # 0 +0xF1D3 0x9D5B # 0 +0xF1D4 0x9D4B # 0 +0xF1D5 0x9D59 # 0 +0xF1D6 0x9D56 # 0 +0xF1D7 0x9D4C # 0 +0xF1D8 0x9D57 # 0 +0xF1D9 0x9D52 # 0 +0xF1DA 0x9D54 # 0 +0xF1DB 0x9D5F # 0 +0xF1DC 0x9D58 # 0 +0xF1DD 0x9D5A # 0 +0xF1DE 0x9E8E # 0 +0xF1DF 0x9E8C # 0 +0xF1E0 0x9EDF # 0 +0xF1E1 0x9F01 # 0 +0xF1E2 0x9F00 # 0 +0xF1E3 0x9F16 # 0 +0xF1E4 0x9F25 # 0 +0xF1E5 0x9F2B # 0 +0xF1E6 0x9F2A # 0 +0xF1E7 0x9F29 # 0 +0xF1E8 0x9F28 # 0 +0xF1E9 0x9F4C # 0 +0xF1EA 0x9F55 # 0 +0xF1EB 0x5134 # 0 +0xF1EC 0x5135 # 0 +0xF1ED 0x5296 # 0 +0xF1EE 0x52F7 # 0 +0xF1EF 0x53B4 # 0 +0xF1F0 0x56AB # 0 +0xF1F1 0x56AD # 0 +0xF1F2 0x56A6 # 0 +0xF1F3 0x56A7 # 0 +0xF1F4 0x56AA # 0 +0xF1F5 0x56AC # 0 +0xF1F6 0x58DA # 0 +0xF1F7 0x58DD # 0 +0xF1F8 0x58DB # 0 +0xF1F9 0x5912 # 0 +0xF1FA 0x5B3D # 0 +0xF1FB 0x5B3E # 0 +0xF1FC 0x5B3F # 0 +0xF1FD 0x5DC3 # 0 +0xF1FE 0x5E70 # 0 +0xF240 0x5FBF # 0 +0xF241 0x61FB # 0 +0xF242 0x6507 # 0 +0xF243 0x6510 # 0 +0xF244 0x650D # 0 +0xF245 0x6509 # 0 +0xF246 0x650C # 0 +0xF247 0x650E # 0 +0xF248 0x6584 # 0 +0xF249 0x65DE # 0 +0xF24A 0x65DD # 0 +0xF24B 0x66DE # 0 +0xF24C 0x6AE7 # 0 +0xF24D 0x6AE0 # 0 +0xF24E 0x6ACC # 0 +0xF24F 0x6AD1 # 0 +0xF250 0x6AD9 # 0 +0xF251 0x6ACB # 0 +0xF252 0x6ADF # 0 +0xF253 0x6ADC # 0 +0xF254 0x6AD0 # 0 +0xF255 0x6AEB # 0 +0xF256 0x6ACF # 0 +0xF257 0x6ACD # 0 +0xF258 0x6ADE # 0 +0xF259 0x6B60 # 0 +0xF25A 0x6BB0 # 0 +0xF25B 0x6C0C # 0 +0xF25C 0x7019 # 0 +0xF25D 0x7027 # 0 +0xF25E 0x7020 # 0 +0xF25F 0x7016 # 0 +0xF260 0x702B # 0 +0xF261 0x7021 # 0 +0xF262 0x7022 # 0 +0xF263 0x7023 # 0 +0xF264 0x7029 # 0 +0xF265 0x7017 # 0 +0xF266 0x7024 # 0 +0xF267 0x701C # 0 +0xF268 0x702A # 0 +0xF269 0x720C # 0 +0xF26A 0x720A # 0 +0xF26B 0x7207 # 0 +0xF26C 0x7202 # 0 +0xF26D 0x7205 # 0 +0xF26E 0x72A5 # 0 +0xF26F 0x72A6 # 0 +0xF270 0x72A4 # 0 +0xF271 0x72A3 # 0 +0xF272 0x72A1 # 0 +0xF273 0x74CB # 0 +0xF274 0x74C5 # 0 +0xF275 0x74B7 # 0 +0xF276 0x74C3 # 0 +0xF277 0x7516 # 0 +0xF278 0x7660 # 0 +0xF279 0x77C9 # 0 +0xF27A 0x77CA # 0 +0xF27B 0x77C4 # 0 +0xF27C 0x77F1 # 0 +0xF27D 0x791D # 0 +0xF27E 0x791B # 0 +0xF2A1 0x7921 # 0 +0xF2A2 0x791C # 0 +0xF2A3 0x7917 # 0 +0xF2A4 0x791E # 0 +0xF2A5 0x79B0 # 0 +0xF2A6 0x7A67 # 0 +0xF2A7 0x7A68 # 0 +0xF2A8 0x7C33 # 0 +0xF2A9 0x7C3C # 0 +0xF2AA 0x7C39 # 0 +0xF2AB 0x7C2C # 0 +0xF2AC 0x7C3B # 0 +0xF2AD 0x7CEC # 0 +0xF2AE 0x7CEA # 0 +0xF2AF 0x7E76 # 0 +0xF2B0 0x7E75 # 0 +0xF2B1 0x7E78 # 0 +0xF2B2 0x7E70 # 0 +0xF2B3 0x7E77 # 0 +0xF2B4 0x7E6F # 0 +0xF2B5 0x7E7A # 0 +0xF2B6 0x7E72 # 0 +0xF2B7 0x7E74 # 0 +0xF2B8 0x7E68 # 0 +0xF2B9 0x7F4B # 0 +0xF2BA 0x7F4A # 0 +0xF2BB 0x7F83 # 0 +0xF2BC 0x7F86 # 0 +0xF2BD 0x7FB7 # 0 +0xF2BE 0x7FFD # 0 +0xF2BF 0x7FFE # 0 +0xF2C0 0x8078 # 0 +0xF2C1 0x81D7 # 0 +0xF2C2 0x81D5 # 0 +0xF2C3 0x8264 # 0 +0xF2C4 0x8261 # 0 +0xF2C5 0x8263 # 0 +0xF2C6 0x85EB # 0 +0xF2C7 0x85F1 # 0 +0xF2C8 0x85ED # 0 +0xF2C9 0x85D9 # 0 +0xF2CA 0x85E1 # 0 +0xF2CB 0x85E8 # 0 +0xF2CC 0x85DA # 0 +0xF2CD 0x85D7 # 0 +0xF2CE 0x85EC # 0 +0xF2CF 0x85F2 # 0 +0xF2D0 0x85F8 # 0 +0xF2D1 0x85D8 # 0 +0xF2D2 0x85DF # 0 +0xF2D3 0x85E3 # 0 +0xF2D4 0x85DC # 0 +0xF2D5 0x85D1 # 0 +0xF2D6 0x85F0 # 0 +0xF2D7 0x85E6 # 0 +0xF2D8 0x85EF # 0 +0xF2D9 0x85DE # 0 +0xF2DA 0x85E2 # 0 +0xF2DB 0x8800 # 0 +0xF2DC 0x87FA # 0 +0xF2DD 0x8803 # 0 +0xF2DE 0x87F6 # 0 +0xF2DF 0x87F7 # 0 +0xF2E0 0x8809 # 0 +0xF2E1 0x880C # 0 +0xF2E2 0x880B # 0 +0xF2E3 0x8806 # 0 +0xF2E4 0x87FC # 0 +0xF2E5 0x8808 # 0 +0xF2E6 0x87FF # 0 +0xF2E7 0x880A # 0 +0xF2E8 0x8802 # 0 +0xF2E9 0x8962 # 0 +0xF2EA 0x895A # 0 +0xF2EB 0x895B # 0 +0xF2EC 0x8957 # 0 +0xF2ED 0x8961 # 0 +0xF2EE 0x895C # 0 +0xF2EF 0x8958 # 0 +0xF2F0 0x895D # 0 +0xF2F1 0x8959 # 0 +0xF2F2 0x8988 # 0 +0xF2F3 0x89B7 # 0 +0xF2F4 0x89B6 # 0 +0xF2F5 0x89F6 # 0 +0xF2F6 0x8B50 # 0 +0xF2F7 0x8B48 # 0 +0xF2F8 0x8B4A # 0 +0xF2F9 0x8B40 # 0 +0xF2FA 0x8B53 # 0 +0xF2FB 0x8B56 # 0 +0xF2FC 0x8B54 # 0 +0xF2FD 0x8B4B # 0 +0xF2FE 0x8B55 # 0 +0xF340 0x8B51 # 0 +0xF341 0x8B42 # 0 +0xF342 0x8B52 # 0 +0xF343 0x8B57 # 0 +0xF344 0x8C43 # 0 +0xF345 0x8C77 # 0 +0xF346 0x8C76 # 0 +0xF347 0x8C9A # 0 +0xF348 0x8D06 # 0 +0xF349 0x8D07 # 0 +0xF34A 0x8D09 # 0 +0xF34B 0x8DAC # 0 +0xF34C 0x8DAA # 0 +0xF34D 0x8DAD # 0 +0xF34E 0x8DAB # 0 +0xF34F 0x8E6D # 0 +0xF350 0x8E78 # 0 +0xF351 0x8E73 # 0 +0xF352 0x8E6A # 0 +0xF353 0x8E6F # 0 +0xF354 0x8E7B # 0 +0xF355 0x8EC2 # 0 +0xF356 0x8F52 # 0 +0xF357 0x8F51 # 0 +0xF358 0x8F4F # 0 +0xF359 0x8F50 # 0 +0xF35A 0x8F53 # 0 +0xF35B 0x8FB4 # 0 +0xF35C 0x9140 # 0 +0xF35D 0x913F # 0 +0xF35E 0x91B0 # 0 +0xF35F 0x91AD # 0 +0xF360 0x93DE # 0 +0xF361 0x93C7 # 0 +0xF362 0x93CF # 0 +0xF363 0x93C2 # 0 +0xF364 0x93DA # 0 +0xF365 0x93D0 # 0 +0xF366 0x93F9 # 0 +0xF367 0x93EC # 0 +0xF368 0x93CC # 0 +0xF369 0x93D9 # 0 +0xF36A 0x93A9 # 0 +0xF36B 0x93E6 # 0 +0xF36C 0x93CA # 0 +0xF36D 0x93D4 # 0 +0xF36E 0x93EE # 0 +0xF36F 0x93E3 # 0 +0xF370 0x93D5 # 0 +0xF371 0x93C4 # 0 +0xF372 0x93CE # 0 +0xF373 0x93C0 # 0 +0xF374 0x93D2 # 0 +0xF375 0x93E7 # 0 +0xF376 0x957D # 0 +0xF377 0x95DA # 0 +0xF378 0x95DB # 0 +0xF379 0x96E1 # 0 +0xF37A 0x9729 # 0 +0xF37B 0x972B # 0 +0xF37C 0x972C # 0 +0xF37D 0x9728 # 0 +0xF37E 0x9726 # 0 +0xF3A1 0x97B3 # 0 +0xF3A2 0x97B7 # 0 +0xF3A3 0x97B6 # 0 +0xF3A4 0x97DD # 0 +0xF3A5 0x97DE # 0 +0xF3A6 0x97DF # 0 +0xF3A7 0x985C # 0 +0xF3A8 0x9859 # 0 +0xF3A9 0x985D # 0 +0xF3AA 0x9857 # 0 +0xF3AB 0x98BF # 0 +0xF3AC 0x98BD # 0 +0xF3AD 0x98BB # 0 +0xF3AE 0x98BE # 0 +0xF3AF 0x9948 # 0 +0xF3B0 0x9947 # 0 +0xF3B1 0x9943 # 0 +0xF3B2 0x99A6 # 0 +0xF3B3 0x99A7 # 0 +0xF3B4 0x9A1A # 0 +0xF3B5 0x9A15 # 0 +0xF3B6 0x9A25 # 0 +0xF3B7 0x9A1D # 0 +0xF3B8 0x9A24 # 0 +0xF3B9 0x9A1B # 0 +0xF3BA 0x9A22 # 0 +0xF3BB 0x9A20 # 0 +0xF3BC 0x9A27 # 0 +0xF3BD 0x9A23 # 0 +0xF3BE 0x9A1E # 0 +0xF3BF 0x9A1C # 0 +0xF3C0 0x9A14 # 0 +0xF3C1 0x9AC2 # 0 +0xF3C2 0x9B0B # 0 +0xF3C3 0x9B0A # 0 +0xF3C4 0x9B0E # 0 +0xF3C5 0x9B0C # 0 +0xF3C6 0x9B37 # 0 +0xF3C7 0x9BEA # 0 +0xF3C8 0x9BEB # 0 +0xF3C9 0x9BE0 # 0 +0xF3CA 0x9BDE # 0 +0xF3CB 0x9BE4 # 0 +0xF3CC 0x9BE6 # 0 +0xF3CD 0x9BE2 # 0 +0xF3CE 0x9BF0 # 0 +0xF3CF 0x9BD4 # 0 +0xF3D0 0x9BD7 # 0 +0xF3D1 0x9BEC # 0 +0xF3D2 0x9BDC # 0 +0xF3D3 0x9BD9 # 0 +0xF3D4 0x9BE5 # 0 +0xF3D5 0x9BD5 # 0 +0xF3D6 0x9BE1 # 0 +0xF3D7 0x9BDA # 0 +0xF3D8 0x9D77 # 0 +0xF3D9 0x9D81 # 0 +0xF3DA 0x9D8A # 0 +0xF3DB 0x9D84 # 0 +0xF3DC 0x9D88 # 0 +0xF3DD 0x9D71 # 0 +0xF3DE 0x9D80 # 0 +0xF3DF 0x9D78 # 0 +0xF3E0 0x9D86 # 0 +0xF3E1 0x9D8B # 0 +0xF3E2 0x9D8C # 0 +0xF3E3 0x9D7D # 0 +0xF3E4 0x9D6B # 0 +0xF3E5 0x9D74 # 0 +0xF3E6 0x9D75 # 0 +0xF3E7 0x9D70 # 0 +0xF3E8 0x9D69 # 0 +0xF3E9 0x9D85 # 0 +0xF3EA 0x9D73 # 0 +0xF3EB 0x9D7B # 0 +0xF3EC 0x9D82 # 0 +0xF3ED 0x9D6F # 0 +0xF3EE 0x9D79 # 0 +0xF3EF 0x9D7F # 0 +0xF3F0 0x9D87 # 0 +0xF3F1 0x9D68 # 0 +0xF3F2 0x9E94 # 0 +0xF3F3 0x9E91 # 0 +0xF3F4 0x9EC0 # 0 +0xF3F5 0x9EFC # 0 +0xF3F6 0x9F2D # 0 +0xF3F7 0x9F40 # 0 +0xF3F8 0x9F41 # 0 +0xF3F9 0x9F4D # 0 +0xF3FA 0x9F56 # 0 +0xF3FB 0x9F57 # 0 +0xF3FC 0x9F58 # 0 +0xF3FD 0x5337 # 0 +0xF3FE 0x56B2 # 0 +0xF440 0x56B5 # 0 +0xF441 0x56B3 # 0 +0xF442 0x58E3 # 0 +0xF443 0x5B45 # 0 +0xF444 0x5DC6 # 0 +0xF445 0x5DC7 # 0 +0xF446 0x5EEE # 0 +0xF447 0x5EEF # 0 +0xF448 0x5FC0 # 0 +0xF449 0x5FC1 # 0 +0xF44A 0x61F9 # 0 +0xF44B 0x6517 # 0 +0xF44C 0x6516 # 0 +0xF44D 0x6515 # 0 +0xF44E 0x6513 # 0 +0xF44F 0x65DF # 0 +0xF450 0x66E8 # 0 +0xF451 0x66E3 # 0 +0xF452 0x66E4 # 0 +0xF453 0x6AF3 # 0 +0xF454 0x6AF0 # 0 +0xF455 0x6AEA # 0 +0xF456 0x6AE8 # 0 +0xF457 0x6AF9 # 0 +0xF458 0x6AF1 # 0 +0xF459 0x6AEE # 0 +0xF45A 0x6AEF # 0 +0xF45B 0x703C # 0 +0xF45C 0x7035 # 0 +0xF45D 0x702F # 0 +0xF45E 0x7037 # 0 +0xF45F 0x7034 # 0 +0xF460 0x7031 # 0 +0xF461 0x7042 # 0 +0xF462 0x7038 # 0 +0xF463 0x703F # 0 +0xF464 0x703A # 0 +0xF465 0x7039 # 0 +0xF466 0x7040 # 0 +0xF467 0x703B # 0 +0xF468 0x7033 # 0 +0xF469 0x7041 # 0 +0xF46A 0x7213 # 0 +0xF46B 0x7214 # 0 +0xF46C 0x72A8 # 0 +0xF46D 0x737D # 0 +0xF46E 0x737C # 0 +0xF46F 0x74BA # 0 +0xF470 0x76AB # 0 +0xF471 0x76AA # 0 +0xF472 0x76BE # 0 +0xF473 0x76ED # 0 +0xF474 0x77CC # 0 +0xF475 0x77CE # 0 +0xF476 0x77CF # 0 +0xF477 0x77CD # 0 +0xF478 0x77F2 # 0 +0xF479 0x7925 # 0 +0xF47A 0x7923 # 0 +0xF47B 0x7927 # 0 +0xF47C 0x7928 # 0 +0xF47D 0x7924 # 0 +0xF47E 0x7929 # 0 +0xF4A1 0x79B2 # 0 +0xF4A2 0x7A6E # 0 +0xF4A3 0x7A6C # 0 +0xF4A4 0x7A6D # 0 +0xF4A5 0x7AF7 # 0 +0xF4A6 0x7C49 # 0 +0xF4A7 0x7C48 # 0 +0xF4A8 0x7C4A # 0 +0xF4A9 0x7C47 # 0 +0xF4AA 0x7C45 # 0 +0xF4AB 0x7CEE # 0 +0xF4AC 0x7E7B # 0 +0xF4AD 0x7E7E # 0 +0xF4AE 0x7E81 # 0 +0xF4AF 0x7E80 # 0 +0xF4B0 0x7FBA # 0 +0xF4B1 0x7FFF # 0 +0xF4B2 0x8079 # 0 +0xF4B3 0x81DB # 0 +0xF4B4 0x81D9 # 0 +0xF4B5 0x820B # 0 +0xF4B6 0x8268 # 0 +0xF4B7 0x8269 # 0 +0xF4B8 0x8622 # 0 +0xF4B9 0x85FF # 0 +0xF4BA 0x8601 # 0 +0xF4BB 0x85FE # 0 +0xF4BC 0x861B # 0 +0xF4BD 0x8600 # 0 +0xF4BE 0x85F6 # 0 +0xF4BF 0x8604 # 0 +0xF4C0 0x8609 # 0 +0xF4C1 0x8605 # 0 +0xF4C2 0x860C # 0 +0xF4C3 0x85FD # 0 +0xF4C4 0x8819 # 0 +0xF4C5 0x8810 # 0 +0xF4C6 0x8811 # 0 +0xF4C7 0x8817 # 0 +0xF4C8 0x8813 # 0 +0xF4C9 0x8816 # 0 +0xF4CA 0x8963 # 0 +0xF4CB 0x8966 # 0 +0xF4CC 0x89B9 # 0 +0xF4CD 0x89F7 # 0 +0xF4CE 0x8B60 # 0 +0xF4CF 0x8B6A # 0 +0xF4D0 0x8B5D # 0 +0xF4D1 0x8B68 # 0 +0xF4D2 0x8B63 # 0 +0xF4D3 0x8B65 # 0 +0xF4D4 0x8B67 # 0 +0xF4D5 0x8B6D # 0 +0xF4D6 0x8DAE # 0 +0xF4D7 0x8E86 # 0 +0xF4D8 0x8E88 # 0 +0xF4D9 0x8E84 # 0 +0xF4DA 0x8F59 # 0 +0xF4DB 0x8F56 # 0 +0xF4DC 0x8F57 # 0 +0xF4DD 0x8F55 # 0 +0xF4DE 0x8F58 # 0 +0xF4DF 0x8F5A # 0 +0xF4E0 0x908D # 0 +0xF4E1 0x9143 # 0 +0xF4E2 0x9141 # 0 +0xF4E3 0x91B7 # 0 +0xF4E4 0x91B5 # 0 +0xF4E5 0x91B2 # 0 +0xF4E6 0x91B3 # 0 +0xF4E7 0x940B # 0 +0xF4E8 0x9413 # 0 +0xF4E9 0x93FB # 0 +0xF4EA 0x9420 # 0 +0xF4EB 0x940F # 0 +0xF4EC 0x9414 # 0 +0xF4ED 0x93FE # 0 +0xF4EE 0x9415 # 0 +0xF4EF 0x9410 # 0 +0xF4F0 0x9428 # 0 +0xF4F1 0x9419 # 0 +0xF4F2 0x940D # 0 +0xF4F3 0x93F5 # 0 +0xF4F4 0x9400 # 0 +0xF4F5 0x93F7 # 0 +0xF4F6 0x9407 # 0 +0xF4F7 0x940E # 0 +0xF4F8 0x9416 # 0 +0xF4F9 0x9412 # 0 +0xF4FA 0x93FA # 0 +0xF4FB 0x9409 # 0 +0xF4FC 0x93F8 # 0 +0xF4FD 0x940A # 0 +0xF4FE 0x93FF # 0 +0xF540 0x93FC # 0 +0xF541 0x940C # 0 +0xF542 0x93F6 # 0 +0xF543 0x9411 # 0 +0xF544 0x9406 # 0 +0xF545 0x95DE # 0 +0xF546 0x95E0 # 0 +0xF547 0x95DF # 0 +0xF548 0x972E # 0 +0xF549 0x972F # 0 +0xF54A 0x97B9 # 0 +0xF54B 0x97BB # 0 +0xF54C 0x97FD # 0 +0xF54D 0x97FE # 0 +0xF54E 0x9860 # 0 +0xF54F 0x9862 # 0 +0xF550 0x9863 # 0 +0xF551 0x985F # 0 +0xF552 0x98C1 # 0 +0xF553 0x98C2 # 0 +0xF554 0x9950 # 0 +0xF555 0x994E # 0 +0xF556 0x9959 # 0 +0xF557 0x994C # 0 +0xF558 0x994B # 0 +0xF559 0x9953 # 0 +0xF55A 0x9A32 # 0 +0xF55B 0x9A34 # 0 +0xF55C 0x9A31 # 0 +0xF55D 0x9A2C # 0 +0xF55E 0x9A2A # 0 +0xF55F 0x9A36 # 0 +0xF560 0x9A29 # 0 +0xF561 0x9A2E # 0 +0xF562 0x9A38 # 0 +0xF563 0x9A2D # 0 +0xF564 0x9AC7 # 0 +0xF565 0x9ACA # 0 +0xF566 0x9AC6 # 0 +0xF567 0x9B10 # 0 +0xF568 0x9B12 # 0 +0xF569 0x9B11 # 0 +0xF56A 0x9C0B # 0 +0xF56B 0x9C08 # 0 +0xF56C 0x9BF7 # 0 +0xF56D 0x9C05 # 0 +0xF56E 0x9C12 # 0 +0xF56F 0x9BF8 # 0 +0xF570 0x9C40 # 0 +0xF571 0x9C07 # 0 +0xF572 0x9C0E # 0 +0xF573 0x9C06 # 0 +0xF574 0x9C17 # 0 +0xF575 0x9C14 # 0 +0xF576 0x9C09 # 0 +0xF577 0x9D9F # 0 +0xF578 0x9D99 # 0 +0xF579 0x9DA4 # 0 +0xF57A 0x9D9D # 0 +0xF57B 0x9D92 # 0 +0xF57C 0x9D98 # 0 +0xF57D 0x9D90 # 0 +0xF57E 0x9D9B # 0 +0xF5A1 0x9DA0 # 0 +0xF5A2 0x9D94 # 0 +0xF5A3 0x9D9C # 0 +0xF5A4 0x9DAA # 0 +0xF5A5 0x9D97 # 0 +0xF5A6 0x9DA1 # 0 +0xF5A7 0x9D9A # 0 +0xF5A8 0x9DA2 # 0 +0xF5A9 0x9DA8 # 0 +0xF5AA 0x9D9E # 0 +0xF5AB 0x9DA3 # 0 +0xF5AC 0x9DBF # 0 +0xF5AD 0x9DA9 # 0 +0xF5AE 0x9D96 # 0 +0xF5AF 0x9DA6 # 0 +0xF5B0 0x9DA7 # 0 +0xF5B1 0x9E99 # 0 +0xF5B2 0x9E9B # 0 +0xF5B3 0x9E9A # 0 +0xF5B4 0x9EE5 # 0 +0xF5B5 0x9EE4 # 0 +0xF5B6 0x9EE7 # 0 +0xF5B7 0x9EE6 # 0 +0xF5B8 0x9F30 # 0 +0xF5B9 0x9F2E # 0 +0xF5BA 0x9F5B # 0 +0xF5BB 0x9F60 # 0 +0xF5BC 0x9F5E # 0 +0xF5BD 0x9F5D # 0 +0xF5BE 0x9F59 # 0 +0xF5BF 0x9F91 # 0 +0xF5C0 0x513A # 0 +0xF5C1 0x5139 # 0 +0xF5C2 0x5298 # 0 +0xF5C3 0x5297 # 0 +0xF5C4 0x56C3 # 0 +0xF5C5 0x56BD # 0 +0xF5C6 0x56BE # 0 +0xF5C7 0x5B48 # 0 +0xF5C8 0x5B47 # 0 +0xF5C9 0x5DCB # 0 +0xF5CA 0x5DCF # 0 +0xF5CB 0x5EF1 # 0 +0xF5CC 0x61FD # 0 +0xF5CD 0x651B # 0 +0xF5CE 0x6B02 # 0 +0xF5CF 0x6AFC # 0 +0xF5D0 0x6B03 # 0 +0xF5D1 0x6AF8 # 0 +0xF5D2 0x6B00 # 0 +0xF5D3 0x7043 # 0 +0xF5D4 0x7044 # 0 +0xF5D5 0x704A # 0 +0xF5D6 0x7048 # 0 +0xF5D7 0x7049 # 0 +0xF5D8 0x7045 # 0 +0xF5D9 0x7046 # 0 +0xF5DA 0x721D # 0 +0xF5DB 0x721A # 0 +0xF5DC 0x7219 # 0 +0xF5DD 0x737E # 0 +0xF5DE 0x7517 # 0 +0xF5DF 0x766A # 0 +0xF5E0 0x77D0 # 0 +0xF5E1 0x792D # 0 +0xF5E2 0x7931 # 0 +0xF5E3 0x792F # 0 +0xF5E4 0x7C54 # 0 +0xF5E5 0x7C53 # 0 +0xF5E6 0x7CF2 # 0 +0xF5E7 0x7E8A # 0 +0xF5E8 0x7E87 # 0 +0xF5E9 0x7E88 # 0 +0xF5EA 0x7E8B # 0 +0xF5EB 0x7E86 # 0 +0xF5EC 0x7E8D # 0 +0xF5ED 0x7F4D # 0 +0xF5EE 0x7FBB # 0 +0xF5EF 0x8030 # 0 +0xF5F0 0x81DD # 0 +0xF5F1 0x8618 # 0 +0xF5F2 0x862A # 0 +0xF5F3 0x8626 # 0 +0xF5F4 0x861F # 0 +0xF5F5 0x8623 # 0 +0xF5F6 0x861C # 0 +0xF5F7 0x8619 # 0 +0xF5F8 0x8627 # 0 +0xF5F9 0x862E # 0 +0xF5FA 0x8621 # 0 +0xF5FB 0x8620 # 0 +0xF5FC 0x8629 # 0 +0xF5FD 0x861E # 0 +0xF5FE 0x8625 # 0 +0xF640 0x8829 # 0 +0xF641 0x881D # 0 +0xF642 0x881B # 0 +0xF643 0x8820 # 0 +0xF644 0x8824 # 0 +0xF645 0x881C # 0 +0xF646 0x882B # 0 +0xF647 0x884A # 0 +0xF648 0x896D # 0 +0xF649 0x8969 # 0 +0xF64A 0x896E # 0 +0xF64B 0x896B # 0 +0xF64C 0x89FA # 0 +0xF64D 0x8B79 # 0 +0xF64E 0x8B78 # 0 +0xF64F 0x8B45 # 0 +0xF650 0x8B7A # 0 +0xF651 0x8B7B # 0 +0xF652 0x8D10 # 0 +0xF653 0x8D14 # 0 +0xF654 0x8DAF # 0 +0xF655 0x8E8E # 0 +0xF656 0x8E8C # 0 +0xF657 0x8F5E # 0 +0xF658 0x8F5B # 0 +0xF659 0x8F5D # 0 +0xF65A 0x9146 # 0 +0xF65B 0x9144 # 0 +0xF65C 0x9145 # 0 +0xF65D 0x91B9 # 0 +0xF65E 0x943F # 0 +0xF65F 0x943B # 0 +0xF660 0x9436 # 0 +0xF661 0x9429 # 0 +0xF662 0x943D # 0 +0xF663 0x943C # 0 +0xF664 0x9430 # 0 +0xF665 0x9439 # 0 +0xF666 0x942A # 0 +0xF667 0x9437 # 0 +0xF668 0x942C # 0 +0xF669 0x9440 # 0 +0xF66A 0x9431 # 0 +0xF66B 0x95E5 # 0 +0xF66C 0x95E4 # 0 +0xF66D 0x95E3 # 0 +0xF66E 0x9735 # 0 +0xF66F 0x973A # 0 +0xF670 0x97BF # 0 +0xF671 0x97E1 # 0 +0xF672 0x9864 # 0 +0xF673 0x98C9 # 0 +0xF674 0x98C6 # 0 +0xF675 0x98C0 # 0 +0xF676 0x9958 # 0 +0xF677 0x9956 # 0 +0xF678 0x9A39 # 0 +0xF679 0x9A3D # 0 +0xF67A 0x9A46 # 0 +0xF67B 0x9A44 # 0 +0xF67C 0x9A42 # 0 +0xF67D 0x9A41 # 0 +0xF67E 0x9A3A # 0 +0xF6A1 0x9A3F # 0 +0xF6A2 0x9ACD # 0 +0xF6A3 0x9B15 # 0 +0xF6A4 0x9B17 # 0 +0xF6A5 0x9B18 # 0 +0xF6A6 0x9B16 # 0 +0xF6A7 0x9B3A # 0 +0xF6A8 0x9B52 # 0 +0xF6A9 0x9C2B # 0 +0xF6AA 0x9C1D # 0 +0xF6AB 0x9C1C # 0 +0xF6AC 0x9C2C # 0 +0xF6AD 0x9C23 # 0 +0xF6AE 0x9C28 # 0 +0xF6AF 0x9C29 # 0 +0xF6B0 0x9C24 # 0 +0xF6B1 0x9C21 # 0 +0xF6B2 0x9DB7 # 0 +0xF6B3 0x9DB6 # 0 +0xF6B4 0x9DBC # 0 +0xF6B5 0x9DC1 # 0 +0xF6B6 0x9DC7 # 0 +0xF6B7 0x9DCA # 0 +0xF6B8 0x9DCF # 0 +0xF6B9 0x9DBE # 0 +0xF6BA 0x9DC5 # 0 +0xF6BB 0x9DC3 # 0 +0xF6BC 0x9DBB # 0 +0xF6BD 0x9DB5 # 0 +0xF6BE 0x9DCE # 0 +0xF6BF 0x9DB9 # 0 +0xF6C0 0x9DBA # 0 +0xF6C1 0x9DAC # 0 +0xF6C2 0x9DC8 # 0 +0xF6C3 0x9DB1 # 0 +0xF6C4 0x9DAD # 0 +0xF6C5 0x9DCC # 0 +0xF6C6 0x9DB3 # 0 +0xF6C7 0x9DCD # 0 +0xF6C8 0x9DB2 # 0 +0xF6C9 0x9E7A # 0 +0xF6CA 0x9E9C # 0 +0xF6CB 0x9EEB # 0 +0xF6CC 0x9EEE # 0 +0xF6CD 0x9EED # 0 +0xF6CE 0x9F1B # 0 +0xF6CF 0x9F18 # 0 +0xF6D0 0x9F1A # 0 +0xF6D1 0x9F31 # 0 +0xF6D2 0x9F4E # 0 +0xF6D3 0x9F65 # 0 +0xF6D4 0x9F64 # 0 +0xF6D5 0x9F92 # 0 +0xF6D6 0x4EB9 # 0 +0xF6D7 0x56C6 # 0 +0xF6D8 0x56C5 # 0 +0xF6D9 0x56CB # 0 +0xF6DA 0x5971 # 0 +0xF6DB 0x5B4B # 0 +0xF6DC 0x5B4C # 0 +0xF6DD 0x5DD5 # 0 +0xF6DE 0x5DD1 # 0 +0xF6DF 0x5EF2 # 0 +0xF6E0 0x6521 # 0 +0xF6E1 0x6520 # 0 +0xF6E2 0x6526 # 0 +0xF6E3 0x6522 # 0 +0xF6E4 0x6B0B # 0 +0xF6E5 0x6B08 # 0 +0xF6E6 0x6B09 # 0 +0xF6E7 0x6C0D # 0 +0xF6E8 0x7055 # 0 +0xF6E9 0x7056 # 0 +0xF6EA 0x7057 # 0 +0xF6EB 0x7052 # 0 +0xF6EC 0x721E # 0 +0xF6ED 0x721F # 0 +0xF6EE 0x72A9 # 0 +0xF6EF 0x737F # 0 +0xF6F0 0x74D8 # 0 +0xF6F1 0x74D5 # 0 +0xF6F2 0x74D9 # 0 +0xF6F3 0x74D7 # 0 +0xF6F4 0x766D # 0 +0xF6F5 0x76AD # 0 +0xF6F6 0x7935 # 0 +0xF6F7 0x79B4 # 0 +0xF6F8 0x7A70 # 0 +0xF6F9 0x7A71 # 0 +0xF6FA 0x7C57 # 0 +0xF6FB 0x7C5C # 0 +0xF6FC 0x7C59 # 0 +0xF6FD 0x7C5B # 0 +0xF6FE 0x7C5A # 0 +0xF740 0x7CF4 # 0 +0xF741 0x7CF1 # 0 +0xF742 0x7E91 # 0 +0xF743 0x7F4F # 0 +0xF744 0x7F87 # 0 +0xF745 0x81DE # 0 +0xF746 0x826B # 0 +0xF747 0x8634 # 0 +0xF748 0x8635 # 0 +0xF749 0x8633 # 0 +0xF74A 0x862C # 0 +0xF74B 0x8632 # 0 +0xF74C 0x8636 # 0 +0xF74D 0x882C # 0 +0xF74E 0x8828 # 0 +0xF74F 0x8826 # 0 +0xF750 0x882A # 0 +0xF751 0x8825 # 0 +0xF752 0x8971 # 0 +0xF753 0x89BF # 0 +0xF754 0x89BE # 0 +0xF755 0x89FB # 0 +0xF756 0x8B7E # 0 +0xF757 0x8B84 # 0 +0xF758 0x8B82 # 0 +0xF759 0x8B86 # 0 +0xF75A 0x8B85 # 0 +0xF75B 0x8B7F # 0 +0xF75C 0x8D15 # 0 +0xF75D 0x8E95 # 0 +0xF75E 0x8E94 # 0 +0xF75F 0x8E9A # 0 +0xF760 0x8E92 # 0 +0xF761 0x8E90 # 0 +0xF762 0x8E96 # 0 +0xF763 0x8E97 # 0 +0xF764 0x8F60 # 0 +0xF765 0x8F62 # 0 +0xF766 0x9147 # 0 +0xF767 0x944C # 0 +0xF768 0x9450 # 0 +0xF769 0x944A # 0 +0xF76A 0x944B # 0 +0xF76B 0x944F # 0 +0xF76C 0x9447 # 0 +0xF76D 0x9445 # 0 +0xF76E 0x9448 # 0 +0xF76F 0x9449 # 0 +0xF770 0x9446 # 0 +0xF771 0x973F # 0 +0xF772 0x97E3 # 0 +0xF773 0x986A # 0 +0xF774 0x9869 # 0 +0xF775 0x98CB # 0 +0xF776 0x9954 # 0 +0xF777 0x995B # 0 +0xF778 0x9A4E # 0 +0xF779 0x9A53 # 0 +0xF77A 0x9A54 # 0 +0xF77B 0x9A4C # 0 +0xF77C 0x9A4F # 0 +0xF77D 0x9A48 # 0 +0xF77E 0x9A4A # 0 +0xF7A1 0x9A49 # 0 +0xF7A2 0x9A52 # 0 +0xF7A3 0x9A50 # 0 +0xF7A4 0x9AD0 # 0 +0xF7A5 0x9B19 # 0 +0xF7A6 0x9B2B # 0 +0xF7A7 0x9B3B # 0 +0xF7A8 0x9B56 # 0 +0xF7A9 0x9B55 # 0 +0xF7AA 0x9C46 # 0 +0xF7AB 0x9C48 # 0 +0xF7AC 0x9C3F # 0 +0xF7AD 0x9C44 # 0 +0xF7AE 0x9C39 # 0 +0xF7AF 0x9C33 # 0 +0xF7B0 0x9C41 # 0 +0xF7B1 0x9C3C # 0 +0xF7B2 0x9C37 # 0 +0xF7B3 0x9C34 # 0 +0xF7B4 0x9C32 # 0 +0xF7B5 0x9C3D # 0 +0xF7B6 0x9C36 # 0 +0xF7B7 0x9DDB # 0 +0xF7B8 0x9DD2 # 0 +0xF7B9 0x9DDE # 0 +0xF7BA 0x9DDA # 0 +0xF7BB 0x9DCB # 0 +0xF7BC 0x9DD0 # 0 +0xF7BD 0x9DDC # 0 +0xF7BE 0x9DD1 # 0 +0xF7BF 0x9DDF # 0 +0xF7C0 0x9DE9 # 0 +0xF7C1 0x9DD9 # 0 +0xF7C2 0x9DD8 # 0 +0xF7C3 0x9DD6 # 0 +0xF7C4 0x9DF5 # 0 +0xF7C5 0x9DD5 # 0 +0xF7C6 0x9DDD # 0 +0xF7C7 0x9EB6 # 0 +0xF7C8 0x9EF0 # 0 +0xF7C9 0x9F35 # 0 +0xF7CA 0x9F33 # 0 +0xF7CB 0x9F32 # 0 +0xF7CC 0x9F42 # 0 +0xF7CD 0x9F6B # 0 +0xF7CE 0x9F95 # 0 +0xF7CF 0x9FA2 # 0 +0xF7D0 0x513D # 0 +0xF7D1 0x5299 # 0 +0xF7D2 0x58E8 # 0 +0xF7D3 0x58E7 # 0 +0xF7D4 0x5972 # 0 +0xF7D5 0x5B4D # 0 +0xF7D6 0x5DD8 # 0 +0xF7D7 0x882F # 0 +0xF7D8 0x5F4F # 0 +0xF7D9 0x6201 # 0 +0xF7DA 0x6203 # 0 +0xF7DB 0x6204 # 0 +0xF7DC 0x6529 # 0 +0xF7DD 0x6525 # 0 +0xF7DE 0x6596 # 0 +0xF7DF 0x66EB # 0 +0xF7E0 0x6B11 # 0 +0xF7E1 0x6B12 # 0 +0xF7E2 0x6B0F # 0 +0xF7E3 0x6BCA # 0 +0xF7E4 0x705B # 0 +0xF7E5 0x705A # 0 +0xF7E6 0x7222 # 0 +0xF7E7 0x7382 # 0 +0xF7E8 0x7381 # 0 +0xF7E9 0x7383 # 0 +0xF7EA 0x7670 # 0 +0xF7EB 0x77D4 # 0 +0xF7EC 0x7C67 # 0 +0xF7ED 0x7C66 # 0 +0xF7EE 0x7E95 # 0 +0xF7EF 0x826C # 0 +0xF7F0 0x863A # 0 +0xF7F1 0x8640 # 0 +0xF7F2 0x8639 # 0 +0xF7F3 0x863C # 0 +0xF7F4 0x8631 # 0 +0xF7F5 0x863B # 0 +0xF7F6 0x863E # 0 +0xF7F7 0x8830 # 0 +0xF7F8 0x8832 # 0 +0xF7F9 0x882E # 0 +0xF7FA 0x8833 # 0 +0xF7FB 0x8976 # 0 +0xF7FC 0x8974 # 0 +0xF7FD 0x8973 # 0 +0xF7FE 0x89FE # 0 +0xF840 0x8B8C # 0 +0xF841 0x8B8E # 0 +0xF842 0x8B8B # 0 +0xF843 0x8B88 # 0 +0xF844 0x8C45 # 0 +0xF845 0x8D19 # 0 +0xF846 0x8E98 # 0 +0xF847 0x8F64 # 0 +0xF848 0x8F63 # 0 +0xF849 0x91BC # 0 +0xF84A 0x9462 # 0 +0xF84B 0x9455 # 0 +0xF84C 0x945D # 0 +0xF84D 0x9457 # 0 +0xF84E 0x945E # 0 +0xF84F 0x97C4 # 0 +0xF850 0x97C5 # 0 +0xF851 0x9800 # 0 +0xF852 0x9A56 # 0 +0xF853 0x9A59 # 0 +0xF854 0x9B1E # 0 +0xF855 0x9B1F # 0 +0xF856 0x9B20 # 0 +0xF857 0x9C52 # 0 +0xF858 0x9C58 # 0 +0xF859 0x9C50 # 0 +0xF85A 0x9C4A # 0 +0xF85B 0x9C4D # 0 +0xF85C 0x9C4B # 0 +0xF85D 0x9C55 # 0 +0xF85E 0x9C59 # 0 +0xF85F 0x9C4C # 0 +0xF860 0x9C4E # 0 +0xF861 0x9DFB # 0 +0xF862 0x9DF7 # 0 +0xF863 0x9DEF # 0 +0xF864 0x9DE3 # 0 +0xF865 0x9DEB # 0 +0xF866 0x9DF8 # 0 +0xF867 0x9DE4 # 0 +0xF868 0x9DF6 # 0 +0xF869 0x9DE1 # 0 +0xF86A 0x9DEE # 0 +0xF86B 0x9DE6 # 0 +0xF86C 0x9DF2 # 0 +0xF86D 0x9DF0 # 0 +0xF86E 0x9DE2 # 0 +0xF86F 0x9DEC # 0 +0xF870 0x9DF4 # 0 +0xF871 0x9DF3 # 0 +0xF872 0x9DE8 # 0 +0xF873 0x9DED # 0 +0xF874 0x9EC2 # 0 +0xF875 0x9ED0 # 0 +0xF876 0x9EF2 # 0 +0xF877 0x9EF3 # 0 +0xF878 0x9F06 # 0 +0xF879 0x9F1C # 0 +0xF87A 0x9F38 # 0 +0xF87B 0x9F37 # 0 +0xF87C 0x9F36 # 0 +0xF87D 0x9F43 # 0 +0xF87E 0x9F4F # 0 +0xF8A1 0x9F71 # 0 +0xF8A2 0x9F70 # 0 +0xF8A3 0x9F6E # 0 +0xF8A4 0x9F6F # 0 +0xF8A5 0x56D3 # 0 +0xF8A6 0x56CD # 0 +0xF8A7 0x5B4E # 0 +0xF8A8 0x5C6D # 0 +0xF8A9 0x652D # 0 +0xF8AA 0x66ED # 0 +0xF8AB 0x66EE # 0 +0xF8AC 0x6B13 # 0 +0xF8AD 0x705F # 0 +0xF8AE 0x7061 # 0 +0xF8AF 0x705D # 0 +0xF8B0 0x7060 # 0 +0xF8B1 0x7223 # 0 +0xF8B2 0x74DB # 0 +0xF8B3 0x74E5 # 0 +0xF8B4 0x77D5 # 0 +0xF8B5 0x7938 # 0 +0xF8B6 0x79B7 # 0 +0xF8B7 0x79B6 # 0 +0xF8B8 0x7C6A # 0 +0xF8B9 0x7E97 # 0 +0xF8BA 0x7F89 # 0 +0xF8BB 0x826D # 0 +0xF8BC 0x8643 # 0 +0xF8BD 0x8838 # 0 +0xF8BE 0x8837 # 0 +0xF8BF 0x8835 # 0 +0xF8C0 0x884B # 0 +0xF8C1 0x8B94 # 0 +0xF8C2 0x8B95 # 0 +0xF8C3 0x8E9E # 0 +0xF8C4 0x8E9F # 0 +0xF8C5 0x8EA0 # 0 +0xF8C6 0x8E9D # 0 +0xF8C7 0x91BE # 0 +0xF8C8 0x91BD # 0 +0xF8C9 0x91C2 # 0 +0xF8CA 0x946B # 0 +0xF8CB 0x9468 # 0 +0xF8CC 0x9469 # 0 +0xF8CD 0x96E5 # 0 +0xF8CE 0x9746 # 0 +0xF8CF 0x9743 # 0 +0xF8D0 0x9747 # 0 +0xF8D1 0x97C7 # 0 +0xF8D2 0x97E5 # 0 +0xF8D3 0x9A5E # 0 +0xF8D4 0x9AD5 # 0 +0xF8D5 0x9B59 # 0 +0xF8D6 0x9C63 # 0 +0xF8D7 0x9C67 # 0 +0xF8D8 0x9C66 # 0 +0xF8D9 0x9C62 # 0 +0xF8DA 0x9C5E # 0 +0xF8DB 0x9C60 # 0 +0xF8DC 0x9E02 # 0 +0xF8DD 0x9DFE # 0 +0xF8DE 0x9E07 # 0 +0xF8DF 0x9E03 # 0 +0xF8E0 0x9E06 # 0 +0xF8E1 0x9E05 # 0 +0xF8E2 0x9E00 # 0 +0xF8E3 0x9E01 # 0 +0xF8E4 0x9E09 # 0 +0xF8E5 0x9DFF # 0 +0xF8E6 0x9DFD # 0 +0xF8E7 0x9E04 # 0 +0xF8E8 0x9EA0 # 0 +0xF8E9 0x9F1E # 0 +0xF8EA 0x9F46 # 0 +0xF8EB 0x9F74 # 0 +0xF8EC 0x9F75 # 0 +0xF8ED 0x9F76 # 0 +0xF8EE 0x56D4 # 0 +0xF8EF 0x652E # 0 +0xF8F0 0x65B8 # 0 +0xF8F1 0x6B18 # 0 +0xF8F2 0x6B19 # 0 +0xF8F3 0x6B17 # 0 +0xF8F4 0x6B1A # 0 +0xF8F5 0x7062 # 0 +0xF8F6 0x7226 # 0 +0xF8F7 0x72AA # 0 +0xF8F8 0x77D8 # 0 +0xF8F9 0x77D9 # 0 +0xF8FA 0x7939 # 0 +0xF8FB 0x7C69 # 0 +0xF8FC 0x7C6B # 0 +0xF8FD 0x7CF6 # 0 +0xF8FE 0x7E9A # 0 +0xF940 0x7E98 # 0 +0xF941 0x7E9B # 0 +0xF942 0x7E99 # 0 +0xF943 0x81E0 # 0 +0xF944 0x81E1 # 0 +0xF945 0x8646 # 0 +0xF946 0x8647 # 0 +0xF947 0x8648 # 0 +0xF948 0x8979 # 0 +0xF949 0x897A # 0 +0xF94A 0x897C # 0 +0xF94B 0x897B # 0 +0xF94C 0x89FF # 0 +0xF94D 0x8B98 # 0 +0xF94E 0x8B99 # 0 +0xF94F 0x8EA5 # 0 +0xF950 0x8EA4 # 0 +0xF951 0x8EA3 # 0 +0xF952 0x946E # 0 +0xF953 0x946D # 0 +0xF954 0x946F # 0 +0xF955 0x9471 # 0 +0xF956 0x9473 # 0 +0xF957 0x9749 # 0 +0xF958 0x9872 # 0 +0xF959 0x995F # 0 +0xF95A 0x9C68 # 0 +0xF95B 0x9C6E # 0 +0xF95C 0x9C6D # 0 +0xF95D 0x9E0B # 0 +0xF95E 0x9E0D # 0 +0xF95F 0x9E10 # 0 +0xF960 0x9E0F # 0 +0xF961 0x9E12 # 0 +0xF962 0x9E11 # 0 +0xF963 0x9EA1 # 0 +0xF964 0x9EF5 # 0 +0xF965 0x9F09 # 0 +0xF966 0x9F47 # 0 +0xF967 0x9F78 # 0 +0xF968 0x9F7B # 0 +0xF969 0x9F7A # 0 +0xF96A 0x9F79 # 0 +0xF96B 0x571E # 0 +0xF96C 0x7066 # 0 +0xF96D 0x7C6F # 0 +0xF96E 0x883C # 0 +0xF96F 0x8DB2 # 0 +0xF970 0x8EA6 # 0 +0xF971 0x91C3 # 0 +0xF972 0x9474 # 0 +0xF973 0x9478 # 0 +0xF974 0x9476 # 0 +0xF975 0x9475 # 0 +0xF976 0x9A60 # 0 +0xF977 0x9C74 # 0 +0xF978 0x9C73 # 0 +0xF979 0x9C71 # 0 +0xF97A 0x9C75 # 0 +0xF97B 0x9E14 # 0 +0xF97C 0x9E13 # 0 +0xF97D 0x9EF6 # 0 +0xF97E 0x9F0A # 0 +0xF9A1 0x9FA4 # 0 +0xF9A2 0x7068 # 0 +0xF9A3 0x7065 # 0 +0xF9A4 0x7CF7 # 0 +0xF9A5 0x866A # 0 +0xF9A6 0x883E # 0 +0xF9A7 0x883D # 0 +0xF9A8 0x883F # 0 +0xF9A9 0x8B9E # 0 +0xF9AA 0x8C9C # 0 +0xF9AB 0x8EA9 # 0 +0xF9AC 0x8EC9 # 0 +0xF9AD 0x974B # 0 +0xF9AE 0x9873 # 0 +0xF9AF 0x9874 # 0 +0xF9B0 0x98CC # 0 +0xF9B1 0x9961 # 0 +0xF9B2 0x99AB # 0 +0xF9B3 0x9A64 # 0 +0xF9B4 0x9A66 # 0 +0xF9B5 0x9A67 # 0 +0xF9B6 0x9B24 # 0 +0xF9B7 0x9E15 # 0 +0xF9B8 0x9E17 # 0 +0xF9B9 0x9F48 # 0 +0xF9BA 0x6207 # 0 +0xF9BB 0x6B1E # 0 +0xF9BC 0x7227 # 0 +0xF9BD 0x864C # 0 +0xF9BE 0x8EA8 # 0 +0xF9BF 0x9482 # 0 +0xF9C0 0x9480 # 0 +0xF9C1 0x9481 # 0 +0xF9C2 0x9A69 # 0 +0xF9C3 0x9A68 # 0 +0xF9C4 0x9B2E # 0 +0xF9C5 0x9E19 # 0 +0xF9C6 0x7229 # 0 +0xF9C7 0x864B # 0 +0xF9C8 0x8B9F # 0 +0xF9C9 0x9483 # 0 +0xF9CA 0x9C79 # 0 +0xF9CB 0x9EB7 # 0 +0xF9CC 0x7675 # 0 +0xF9CD 0x9A6B # 0 +0xF9CE 0x9C7A # 0 +0xF9CF 0x9E1D # 0 +0xF9D0 0x7069 # 0 +0xF9D1 0x706A # 0 +0xF9D2 0x9EA4 # 0 +0xF9D3 0x9F7E # 0 +0xF9D4 0x9F49 # 0 +0xF9D5 0x9F98 # 0 +0xF9D6 0x7881 # 0 +0xF9D7 0x92B9 # 0 +0xF9D8 0x88CF # 0 +0xF9D9 0x58BB # 0 +0xF9DA 0x6052 # 0 +0xF9DB 0x7CA7 # 0 +0xF9DC 0x5AFA # 0 +0xF9DD 0x2554 # 0 +0xF9DE 0x2566 # 0 +0xF9DF 0x2557 # 0 +0xF9E0 0x2560 # 0 +0xF9E1 0x256C # 0 +0xF9E2 0x2563 # 0 +0xF9E3 0x255A # 0 +0xF9E4 0x2569 # 0 +0xF9E5 0x255D # 0 +0xF9E6 0x2552 # 0 +0xF9E7 0x2564 # 0 +0xF9E8 0x2555 # 0 +0xF9E9 0x255E # 0 +0xF9EA 0x256A # 0 +0xF9EB 0x2561 # 0 +0xF9EC 0x2558 # 0 +0xF9ED 0x2567 # 0 +0xF9EE 0x255B # 0 +0xF9EF 0x2553 # 0 +0xF9F0 0x2565 # 0 +0xF9F1 0x2556 # 0 +0xF9F2 0x255F # 0 +0xF9F3 0x256B # 0 +0xF9F4 0x2562 # 0 +0xF9F5 0x2559 # 0 +0xF9F6 0x2568 # 0 +0xF9F7 0x255C # 0 +0xF9F8 0x2551 # 0 +0xF9F9 0x2550 # 0 +0xF9FE 0x2593 # 0 +0xFA40 0xE000 # 0 +0xFA41 0xE001 # 0 +0xFA42 0xE002 # 0 +0xFA43 0xE003 # 0 +0xFA44 0xE004 # 0 +0xFA45 0xE005 # 0 +0xFA46 0xE006 # 0 +0xFA47 0xE007 # 0 +0xFA48 0xE008 # 0 +0xFA49 0xE009 # 0 +0xFA4A 0xE00A # 0 +0xFA4B 0xE00B # 0 +0xFA4C 0xE00C # 0 +0xFA4D 0xE00D # 0 +0xFA4E 0xE00E # 0 +0xFA4F 0xE00F # 0 +0xFA50 0xE010 # 0 +0xFA51 0xE011 # 0 +0xFA52 0xE012 # 0 +0xFA53 0xE013 # 0 +0xFA54 0xE014 # 0 +0xFA55 0xE015 # 0 +0xFA56 0xE016 # 0 +0xFA57 0xE017 # 0 +0xFA58 0xE018 # 0 +0xFA59 0xE019 # 0 +0xFA5A 0xE01A # 0 +0xFA5B 0xE01B # 0 +0xFA5C 0xE01C # 0 +0xFA5D 0xE01D # 0 +0xFA5E 0xE01E # 0 +0xFA5F 0xE01F # 0 +0xFA60 0xE020 # 0 +0xFA61 0xE021 # 0 +0xFA62 0xE022 # 0 +0xFA63 0xE023 # 0 +0xFA64 0xE024 # 0 +0xFA65 0xE025 # 0 +0xFA66 0xE026 # 0 +0xFA67 0xE027 # 0 +0xFA68 0xE028 # 0 +0xFA69 0xE029 # 0 +0xFA6A 0xE02A # 0 +0xFA6B 0xE02B # 0 +0xFA6C 0xE02C # 0 +0xFA6D 0xE02D # 0 +0xFA6E 0xE02E # 0 +0xFA6F 0xE02F # 0 +0xFA70 0xE030 # 0 +0xFA71 0xE031 # 0 +0xFA72 0xE032 # 0 +0xFA73 0xE033 # 0 +0xFA74 0xE034 # 0 +0xFA75 0xE035 # 0 +0xFA76 0xE036 # 0 +0xFA77 0xE037 # 0 +0xFA78 0xE038 # 0 +0xFA79 0xE039 # 0 +0xFA7A 0xE03A # 0 +0xFA7B 0xE03B # 0 +0xFA7C 0xE03C # 0 +0xFA7D 0xE03D # 0 +0xFA7E 0xE03E # 0 +0xFAA1 0xE03F # 0 +0xFAA2 0xE040 # 0 +0xFAA3 0xE041 # 0 +0xFAA4 0xE042 # 0 +0xFAA5 0xE043 # 0 +0xFAA6 0xE044 # 0 +0xFAA7 0xE045 # 0 +0xFAA8 0xE046 # 0 +0xFAA9 0xE047 # 0 +0xFAAA 0xE048 # 0 +0xFAAB 0xE049 # 0 +0xFAAC 0xE04A # 0 +0xFAAD 0xE04B # 0 +0xFAAE 0xE04C # 0 +0xFAAF 0xE04D # 0 +0xFAB0 0xE04E # 0 +0xFAB1 0xE04F # 0 +0xFAB2 0xE050 # 0 +0xFAB3 0xE051 # 0 +0xFAB4 0xE052 # 0 +0xFAB5 0xE053 # 0 +0xFAB6 0xE054 # 0 +0xFAB7 0xE055 # 0 +0xFAB8 0xE056 # 0 +0xFAB9 0xE057 # 0 +0xFABA 0xE058 # 0 +0xFABB 0xE059 # 0 +0xFABC 0xE05A # 0 +0xFABD 0xE05B # 0 +0xFABE 0xE05C # 0 +0xFABF 0xE05D # 0 +0xFAC0 0xE05E # 0 +0xFAC1 0xE05F # 0 +0xFAC2 0xE060 # 0 +0xFAC3 0xE061 # 0 +0xFAC4 0xE062 # 0 +0xFAC5 0xE063 # 0 +0xFAC6 0xE064 # 0 +0xFAC7 0xE065 # 0 +0xFAC8 0xE066 # 0 +0xFAC9 0xE067 # 0 +0xFACA 0xE068 # 0 +0xFACB 0xE069 # 0 +0xFACC 0xE06A # 0 +0xFACD 0xE06B # 0 +0xFACE 0xE06C # 0 +0xFACF 0xE06D # 0 +0xFAD0 0xE06E # 0 +0xFAD1 0xE06F # 0 +0xFAD2 0xE070 # 0 +0xFAD3 0xE071 # 0 +0xFAD4 0xE072 # 0 +0xFAD5 0xE073 # 0 +0xFAD6 0xE074 # 0 +0xFAD7 0xE075 # 0 +0xFAD8 0xE076 # 0 +0xFAD9 0xE077 # 0 +0xFADA 0xE078 # 0 +0xFADB 0xE079 # 0 +0xFADC 0xE07A # 0 +0xFADD 0xE07B # 0 +0xFADE 0xE07C # 0 +0xFADF 0xE07D # 0 +0xFAE0 0xE07E # 0 +0xFAE1 0xE07F # 0 +0xFAE2 0xE080 # 0 +0xFAE3 0xE081 # 0 +0xFAE4 0xE082 # 0 +0xFAE5 0xE083 # 0 +0xFAE6 0xE084 # 0 +0xFAE7 0xE085 # 0 +0xFAE8 0xE086 # 0 +0xFAE9 0xE087 # 0 +0xFAEA 0xE088 # 0 +0xFAEB 0xE089 # 0 +0xFAEC 0xE08A # 0 +0xFAED 0xE08B # 0 +0xFAEE 0xE08C # 0 +0xFAEF 0xE08D # 0 +0xFAF0 0xE08E # 0 +0xFAF1 0xE08F # 0 +0xFAF2 0xE090 # 0 +0xFAF3 0xE091 # 0 +0xFAF4 0xE092 # 0 +0xFAF5 0xE093 # 0 +0xFAF6 0xE094 # 0 +0xFAF7 0xE095 # 0 +0xFAF8 0xE096 # 0 +0xFAF9 0xE097 # 0 +0xFAFA 0xE098 # 0 +0xFAFB 0xE099 # 0 +0xFAFC 0xE09A # 0 +0xFAFD 0xE09B # 0 +0xFAFE 0xE09C # 0 +0xFB40 0xE09D # 0 +0xFB41 0xE09E # 0 +0xFB42 0xE09F # 0 +0xFB43 0xE0A0 # 0 +0xFB44 0xE0A1 # 0 +0xFB45 0xE0A2 # 0 +0xFB46 0xE0A3 # 0 +0xFB47 0xE0A4 # 0 +0xFB48 0xE0A5 # 0 +0xFB49 0xE0A6 # 0 +0xFB4A 0xE0A7 # 0 +0xFB4B 0xE0A8 # 0 +0xFB4C 0xE0A9 # 0 +0xFB4D 0xE0AA # 0 +0xFB4E 0xE0AB # 0 +0xFB4F 0xE0AC # 0 +0xFB50 0xE0AD # 0 +0xFB51 0xE0AE # 0 +0xFB52 0xE0AF # 0 +0xFB53 0xE0B0 # 0 +0xFB54 0xE0B1 # 0 +0xFB55 0xE0B2 # 0 +0xFB56 0xE0B3 # 0 +0xFB57 0xE0B4 # 0 +0xFB58 0xE0B5 # 0 +0xFB59 0xE0B6 # 0 +0xFB5A 0xE0B7 # 0 +0xFB5B 0xE0B8 # 0 +0xFB5C 0xE0B9 # 0 +0xFB5D 0xE0BA # 0 +0xFB5E 0xE0BB # 0 +0xFB5F 0xE0BC # 0 +0xFB60 0xE0BD # 0 +0xFB61 0xE0BE # 0 +0xFB62 0xE0BF # 0 +0xFB63 0xE0C0 # 0 +0xFB64 0xE0C1 # 0 +0xFB65 0xE0C2 # 0 +0xFB66 0xE0C3 # 0 +0xFB67 0xE0C4 # 0 +0xFB68 0xE0C5 # 0 +0xFB69 0xE0C6 # 0 +0xFB6A 0xE0C7 # 0 +0xFB6B 0xE0C8 # 0 +0xFB6C 0xE0C9 # 0 +0xFB6D 0xE0CA # 0 +0xFB6E 0xE0CB # 0 +0xFB6F 0xE0CC # 0 +0xFB70 0xE0CD # 0 +0xFB71 0xE0CE # 0 +0xFB72 0xE0CF # 0 +0xFB73 0xE0D0 # 0 +0xFB74 0xE0D1 # 0 +0xFB75 0xE0D2 # 0 +0xFB76 0xE0D3 # 0 +0xFB77 0xE0D4 # 0 +0xFB78 0xE0D5 # 0 +0xFB79 0xE0D6 # 0 +0xFB7A 0xE0D7 # 0 +0xFB7B 0xE0D8 # 0 +0xFB7C 0xE0D9 # 0 +0xFB7D 0xE0DA # 0 +0xFB7E 0xE0DB # 0 +0xFBA1 0xE0DC # 0 +0xFBA2 0xE0DD # 0 +0xFBA3 0xE0DE # 0 +0xFBA4 0xE0DF # 0 +0xFBA5 0xE0E0 # 0 +0xFBA6 0xE0E1 # 0 +0xFBA7 0xE0E2 # 0 +0xFBA8 0xE0E3 # 0 +0xFBA9 0xE0E4 # 0 +0xFBAA 0xE0E5 # 0 +0xFBAB 0xE0E6 # 0 +0xFBAC 0xE0E7 # 0 +0xFBAD 0xE0E8 # 0 +0xFBAE 0xE0E9 # 0 +0xFBAF 0xE0EA # 0 +0xFBB0 0xE0EB # 0 +0xFBB1 0xE0EC # 0 +0xFBB2 0xE0ED # 0 +0xFBB3 0xE0EE # 0 +0xFBB4 0xE0EF # 0 +0xFBB5 0xE0F0 # 0 +0xFBB6 0xE0F1 # 0 +0xFBB7 0xE0F2 # 0 +0xFBB8 0xE0F3 # 0 +0xFBB9 0xE0F4 # 0 +0xFBBA 0xE0F5 # 0 +0xFBBB 0xE0F6 # 0 +0xFBBC 0xE0F7 # 0 +0xFBBD 0xE0F8 # 0 +0xFBBE 0xE0F9 # 0 +0xFBBF 0xE0FA # 0 +0xFBC0 0xE0FB # 0 +0xFBC1 0xE0FC # 0 +0xFBC2 0xE0FD # 0 +0xFBC3 0xE0FE # 0 +0xFBC4 0xE0FF # 0 +0xFBC5 0xE100 # 0 +0xFBC6 0xE101 # 0 +0xFBC7 0xE102 # 0 +0xFBC8 0xE103 # 0 +0xFBC9 0xE104 # 0 +0xFBCA 0xE105 # 0 +0xFBCB 0xE106 # 0 +0xFBCC 0xE107 # 0 +0xFBCD 0xE108 # 0 +0xFBCE 0xE109 # 0 +0xFBCF 0xE10A # 0 +0xFBD0 0xE10B # 0 +0xFBD1 0xE10C # 0 +0xFBD2 0xE10D # 0 +0xFBD3 0xE10E # 0 +0xFBD4 0xE10F # 0 +0xFBD5 0xE110 # 0 +0xFBD6 0xE111 # 0 +0xFBD7 0xE112 # 0 +0xFBD8 0xE113 # 0 +0xFBD9 0xE114 # 0 +0xFBDA 0xE115 # 0 +0xFBDB 0xE116 # 0 +0xFBDC 0xE117 # 0 +0xFBDD 0xE118 # 0 +0xFBDE 0xE119 # 0 +0xFBDF 0xE11A # 0 +0xFBE0 0xE11B # 0 +0xFBE1 0xE11C # 0 +0xFBE2 0xE11D # 0 +0xFBE3 0xE11E # 0 +0xFBE4 0xE11F # 0 +0xFBE5 0xE120 # 0 +0xFBE6 0xE121 # 0 +0xFBE7 0xE122 # 0 +0xFBE8 0xE123 # 0 +0xFBE9 0xE124 # 0 +0xFBEA 0xE125 # 0 +0xFBEB 0xE126 # 0 +0xFBEC 0xE127 # 0 +0xFBED 0xE128 # 0 +0xFBEE 0xE129 # 0 +0xFBEF 0xE12A # 0 +0xFBF0 0xE12B # 0 +0xFBF1 0xE12C # 0 +0xFBF2 0xE12D # 0 +0xFBF3 0xE12E # 0 +0xFBF4 0xE12F # 0 +0xFBF5 0xE130 # 0 +0xFBF6 0xE131 # 0 +0xFBF7 0xE132 # 0 +0xFBF8 0xE133 # 0 +0xFBF9 0xE134 # 0 +0xFBFA 0xE135 # 0 +0xFBFB 0xE136 # 0 +0xFBFC 0xE137 # 0 +0xFBFD 0xE138 # 0 +0xFBFE 0xE139 # 0 +0xFC40 0xE13A # 0 +0xFC41 0xE13B # 0 +0xFC42 0xE13C # 0 +0xFC43 0xE13D # 0 +0xFC44 0xE13E # 0 +0xFC45 0xE13F # 0 +0xFC46 0xE140 # 0 +0xFC47 0xE141 # 0 +0xFC48 0xE142 # 0 +0xFC49 0xE143 # 0 +0xFC4A 0xE144 # 0 +0xFC4B 0xE145 # 0 +0xFC4C 0xE146 # 0 +0xFC4D 0xE147 # 0 +0xFC4E 0xE148 # 0 +0xFC4F 0xE149 # 0 +0xFC50 0xE14A # 0 +0xFC51 0xE14B # 0 +0xFC52 0xE14C # 0 +0xFC53 0xE14D # 0 +0xFC54 0xE14E # 0 +0xFC55 0xE14F # 0 +0xFC56 0xE150 # 0 +0xFC57 0xE151 # 0 +0xFC58 0xE152 # 0 +0xFC59 0xE153 # 0 +0xFC5A 0xE154 # 0 +0xFC5B 0xE155 # 0 +0xFC5C 0xE156 # 0 +0xFC5D 0xE157 # 0 +0xFC5E 0xE158 # 0 +0xFC5F 0xE159 # 0 +0xFC60 0xE15A # 0 +0xFC61 0xE15B # 0 +0xFC62 0xE15C # 0 +0xFC63 0xE15D # 0 +0xFC64 0xE15E # 0 +0xFC65 0xE15F # 0 +0xFC66 0xE160 # 0 +0xFC67 0xE161 # 0 +0xFC68 0xE162 # 0 +0xFC69 0xE163 # 0 +0xFC6A 0xE164 # 0 +0xFC6B 0xE165 # 0 +0xFC6C 0xE166 # 0 +0xFC6D 0xE167 # 0 +0xFC6E 0xE168 # 0 +0xFC6F 0xE169 # 0 +0xFC70 0xE16A # 0 +0xFC71 0xE16B # 0 +0xFC72 0xE16C # 0 +0xFC73 0xE16D # 0 +0xFC74 0xE16E # 0 +0xFC75 0xE16F # 0 +0xFC76 0xE170 # 0 +0xFC77 0xE171 # 0 +0xFC78 0xE172 # 0 +0xFC79 0xE173 # 0 +0xFC7A 0xE174 # 0 +0xFC7B 0xE175 # 0 +0xFC7C 0xE176 # 0 +0xFC7D 0xE177 # 0 +0xFC7E 0xE178 # 0 +0xFCA1 0xE179 # 0 +0xFCA2 0xE17A # 0 +0xFCA3 0xE17B # 0 +0xFCA4 0xE17C # 0 +0xFCA5 0xE17D # 0 +0xFCA6 0xE17E # 0 +0xFCA7 0xE17F # 0 +0xFCA8 0xE180 # 0 +0xFCA9 0xE181 # 0 +0xFCAA 0xE182 # 0 +0xFCAB 0xE183 # 0 +0xFCAC 0xE184 # 0 +0xFCAD 0xE185 # 0 +0xFCAE 0xE186 # 0 +0xFCAF 0xE187 # 0 +0xFCB0 0xE188 # 0 +0xFCB1 0xE189 # 0 +0xFCB2 0xE18A # 0 +0xFCB3 0xE18B # 0 +0xFCB4 0xE18C # 0 +0xFCB5 0xE18D # 0 +0xFCB6 0xE18E # 0 +0xFCB7 0xE18F # 0 +0xFCB8 0xE190 # 0 +0xFCB9 0xE191 # 0 +0xFCBA 0xE192 # 0 +0xFCBB 0xE193 # 0 +0xFCBC 0xE194 # 0 +0xFCBD 0xE195 # 0 +0xFCBE 0xE196 # 0 +0xFCBF 0xE197 # 0 +0xFCC0 0xE198 # 0 +0xFCC1 0xE199 # 0 +0xFCC2 0xE19A # 0 +0xFCC3 0xE19B # 0 +0xFCC4 0xE19C # 0 +0xFCC5 0xE19D # 0 +0xFCC6 0xE19E # 0 +0xFCC7 0xE19F # 0 +0xFCC8 0xE1A0 # 0 +0xFCC9 0xE1A1 # 0 +0xFCCA 0xE1A2 # 0 +0xFCCB 0xE1A3 # 0 +0xFCCC 0xE1A4 # 0 +0xFCCD 0xE1A5 # 0 +0xFCCE 0xE1A6 # 0 +0xFCCF 0xE1A7 # 0 +0xFCD0 0xE1A8 # 0 +0xFCD1 0xE1A9 # 0 +0xFCD2 0xE1AA # 0 +0xFCD3 0xE1AB # 0 +0xFCD4 0xE1AC # 0 +0xFCD5 0xE1AD # 0 +0xFCD6 0xE1AE # 0 +0xFCD7 0xE1AF # 0 +0xFCD8 0xE1B0 # 0 +0xFCD9 0xE1B1 # 0 +0xFCDA 0xE1B2 # 0 +0xFCDB 0xE1B3 # 0 +0xFCDC 0xE1B4 # 0 +0xFCDD 0xE1B5 # 0 +0xFCDE 0xE1B6 # 0 +0xFCDF 0xE1B7 # 0 +0xFCE0 0xE1B8 # 0 +0xFCE1 0xE1B9 # 0 +0xFCE2 0xE1BA # 0 +0xFCE3 0xE1BB # 0 +0xFCE4 0xE1BC # 0 +0xFCE5 0xE1BD # 0 +0xFCE6 0xE1BE # 0 +0xFCE7 0xE1BF # 0 +0xFCE8 0xE1C0 # 0 +0xFCE9 0xE1C1 # 0 +0xFCEA 0xE1C2 # 0 +0xFCEB 0xE1C3 # 0 +0xFCEC 0xE1C4 # 0 +0xFCED 0xE1C5 # 0 +0xFCEE 0xE1C6 # 0 +0xFCEF 0xE1C7 # 0 +0xFCF0 0xE1C8 # 0 +0xFCF1 0xE1C9 # 0 +0xFCF2 0xE1CA # 0 +0xFCF3 0xE1CB # 0 +0xFCF4 0xE1CC # 0 +0xFCF5 0xE1CD # 0 +0xFCF6 0xE1CE # 0 +0xFCF7 0xE1CF # 0 +0xFCF8 0xE1D0 # 0 +0xFCF9 0xE1D1 # 0 +0xFCFA 0xE1D2 # 0 +0xFCFB 0xE1D3 # 0 +0xFCFC 0xE1D4 # 0 +0xFCFD 0xE1D5 # 0 +0xFCFE 0xE1D6 # 0 +0xFD40 0xE1D7 # 0 +0xFD41 0xE1D8 # 0 +0xFD42 0xE1D9 # 0 +0xFD43 0xE1DA # 0 +0xFD44 0xE1DB # 0 +0xFD45 0xE1DC # 0 +0xFD46 0xE1DD # 0 +0xFD47 0xE1DE # 0 +0xFD48 0xE1DF # 0 +0xFD49 0xE1E0 # 0 +0xFD4A 0xE1E1 # 0 +0xFD4B 0xE1E2 # 0 +0xFD4C 0xE1E3 # 0 +0xFD4D 0xE1E4 # 0 +0xFD4E 0xE1E5 # 0 +0xFD4F 0xE1E6 # 0 +0xFD50 0xE1E7 # 0 +0xFD51 0xE1E8 # 0 +0xFD52 0xE1E9 # 0 +0xFD53 0xE1EA # 0 +0xFD54 0xE1EB # 0 +0xFD55 0xE1EC # 0 +0xFD56 0xE1ED # 0 +0xFD57 0xE1EE # 0 +0xFD58 0xE1EF # 0 +0xFD59 0xE1F0 # 0 +0xFD5A 0xE1F1 # 0 +0xFD5B 0xE1F2 # 0 +0xFD5C 0xE1F3 # 0 +0xFD5D 0xE1F4 # 0 +0xFD5E 0xE1F5 # 0 +0xFD5F 0xE1F6 # 0 +0xFD60 0xE1F7 # 0 +0xFD61 0xE1F8 # 0 +0xFD62 0xE1F9 # 0 +0xFD63 0xE1FA # 0 +0xFD64 0xE1FB # 0 +0xFD65 0xE1FC # 0 +0xFD66 0xE1FD # 0 +0xFD67 0xE1FE # 0 +0xFD68 0xE1FF # 0 +0xFD69 0xE200 # 0 +0xFD6A 0xE201 # 0 +0xFD6B 0xE202 # 0 +0xFD6C 0xE203 # 0 +0xFD6D 0xE204 # 0 +0xFD6E 0xE205 # 0 +0xFD6F 0xE206 # 0 +0xFD70 0xE207 # 0 +0xFD71 0xE208 # 0 +0xFD72 0xE209 # 0 +0xFD73 0xE20A # 0 +0xFD74 0xE20B # 0 +0xFD75 0xE20C # 0 +0xFD76 0xE20D # 0 +0xFD77 0xE20E # 0 +0xFD78 0xE20F # 0 +0xFD79 0xE210 # 0 +0xFD7A 0xE211 # 0 +0xFD7B 0xE212 # 0 +0xFD7C 0xE213 # 0 +0xFD7D 0xE214 # 0 +0xFD7E 0xE215 # 0 +0xFDA1 0xE216 # 0 +0xFDA2 0xE217 # 0 +0xFDA3 0xE218 # 0 +0xFDA4 0xE219 # 0 +0xFDA5 0xE21A # 0 +0xFDA6 0xE21B # 0 +0xFDA7 0xE21C # 0 +0xFDA8 0xE21D # 0 +0xFDA9 0xE21E # 0 +0xFDAA 0xE21F # 0 +0xFDAB 0xE220 # 0 +0xFDAC 0xE221 # 0 +0xFDAD 0xE222 # 0 +0xFDAE 0xE223 # 0 +0xFDAF 0xE224 # 0 +0xFDB0 0xE225 # 0 +0xFDB1 0xE226 # 0 +0xFDB2 0xE227 # 0 +0xFDB3 0xE228 # 0 +0xFDB4 0xE229 # 0 +0xFDB5 0xE22A # 0 +0xFDB6 0xE22B # 0 +0xFDB7 0xE22C # 0 +0xFDB8 0xE22D # 0 +0xFDB9 0xE22E # 0 +0xFDBA 0xE22F # 0 +0xFDBB 0xE230 # 0 +0xFDBC 0xE231 # 0 +0xFDBD 0xE232 # 0 +0xFDBE 0xE233 # 0 +0xFDBF 0xE234 # 0 +0xFDC0 0xE235 # 0 +0xFDC1 0xE236 # 0 +0xFDC2 0xE237 # 0 +0xFDC3 0xE238 # 0 +0xFDC4 0xE239 # 0 +0xFDC5 0xE23A # 0 +0xFDC6 0xE23B # 0 +0xFDC7 0xE23C # 0 +0xFDC8 0xE23D # 0 +0xFDC9 0xE23E # 0 +0xFDCA 0xE23F # 0 +0xFDCB 0xE240 # 0 +0xFDCC 0xE241 # 0 +0xFDCD 0xE242 # 0 +0xFDCE 0xE243 # 0 +0xFDCF 0xE244 # 0 +0xFDD0 0xE245 # 0 +0xFDD1 0xE246 # 0 +0xFDD2 0xE247 # 0 +0xFDD3 0xE248 # 0 +0xFDD4 0xE249 # 0 +0xFDD5 0xE24A # 0 +0xFDD6 0xE24B # 0 +0xFDD7 0xE24C # 0 +0xFDD8 0xE24D # 0 +0xFDD9 0xE24E # 0 +0xFDDA 0xE24F # 0 +0xFDDB 0xE250 # 0 +0xFDDC 0xE251 # 0 +0xFDDD 0xE252 # 0 +0xFDDE 0xE253 # 0 +0xFDDF 0xE254 # 0 +0xFDE0 0xE255 # 0 +0xFDE1 0xE256 # 0 +0xFDE2 0xE257 # 0 +0xFDE3 0xE258 # 0 +0xFDE4 0xE259 # 0 +0xFDE5 0xE25A # 0 +0xFDE6 0xE25B # 0 +0xFDE7 0xE25C # 0 +0xFDE8 0xE25D # 0 +0xFDE9 0xE25E # 0 +0xFDEA 0xE25F # 0 +0xFDEB 0xE260 # 0 +0xFDEC 0xE261 # 0 +0xFDED 0xE262 # 0 +0xFDEE 0xE263 # 0 +0xFDEF 0xE264 # 0 +0xFDF0 0xE265 # 0 +0xFDF1 0xE266 # 0 +0xFDF2 0xE267 # 0 +0xFDF3 0xE268 # 0 +0xFDF4 0xE269 # 0 +0xFDF5 0xE26A # 0 +0xFDF6 0xE26B # 0 +0xFDF7 0xE26C # 0 +0xFDF8 0xE26D # 0 +0xFDF9 0xE26E # 0 +0xFDFA 0xE26F # 0 +0xFDFB 0xE270 # 0 +0xFDFC 0xE271 # 0 +0xFDFD 0xE272 # 0 +0xFDFE 0xE273 # 0 +0xFE40 0xE274 # 0 +0xFE41 0xE275 # 0 +0xFE42 0xE276 # 0 +0xFE43 0xE277 # 0 +0xFE44 0xE278 # 0 +0xFE45 0xE279 # 0 +0xFE46 0xE27A # 0 +0xFE47 0xE27B # 0 +0xFE48 0xE27C # 0 +0xFE49 0xE27D # 0 +0xFE4A 0xE27E # 0 +0xFE4B 0xE27F # 0 +0xFE4C 0xE280 # 0 +0xFE4D 0xE281 # 0 +0xFE4E 0xE282 # 0 +0xFE4F 0xE283 # 0 +0xFE50 0xE284 # 0 +0xFE51 0xE285 # 0 +0xFE52 0xE286 # 0 +0xFE53 0xE287 # 0 +0xFE54 0xE288 # 0 +0xFE55 0xE289 # 0 +0xFE56 0xE28A # 0 +0xFE57 0xE28B # 0 +0xFE58 0xE28C # 0 +0xFE59 0xE28D # 0 +0xFE5A 0xE28E # 0 +0xFE5B 0xE28F # 0 +0xFE5C 0xE290 # 0 +0xFE5D 0xE291 # 0 +0xFE5E 0xE292 # 0 +0xFE5F 0xE293 # 0 +0xFE60 0xE294 # 0 +0xFE61 0xE295 # 0 +0xFE62 0xE296 # 0 +0xFE63 0xE297 # 0 +0xFE64 0xE298 # 0 +0xFE65 0xE299 # 0 +0xFE66 0xE29A # 0 +0xFE67 0xE29B # 0 +0xFE68 0xE29C # 0 +0xFE69 0xE29D # 0 +0xFE6A 0xE29E # 0 +0xFE6B 0xE29F # 0 +0xFE6C 0xE2A0 # 0 +0xFE6D 0xE2A1 # 0 +0xFE6E 0xE2A2 # 0 +0xFE6F 0xE2A3 # 0 +0xFE70 0xE2A4 # 0 +0xFE71 0xE2A5 # 0 +0xFE72 0xE2A6 # 0 +0xFE73 0xE2A7 # 0 +0xFE74 0xE2A8 # 0 +0xFE75 0xE2A9 # 0 +0xFE76 0xE2AA # 0 +0xFE77 0xE2AB # 0 +0xFE78 0xE2AC # 0 +0xFE79 0xE2AD # 0 +0xFE7A 0xE2AE # 0 +0xFE7B 0xE2AF # 0 +0xFE7C 0xE2B0 # 0 +0xFE7D 0xE2B1 # 0 +0xFE7E 0xE2B2 # 0 +0xFEA1 0xE2B3 # 0 +0xFEA2 0xE2B4 # 0 +0xFEA3 0xE2B5 # 0 +0xFEA4 0xE2B6 # 0 +0xFEA5 0xE2B7 # 0 +0xFEA6 0xE2B8 # 0 +0xFEA7 0xE2B9 # 0 +0xFEA8 0xE2BA # 0 +0xFEA9 0xE2BB # 0 +0xFEAA 0xE2BC # 0 +0xFEAB 0xE2BD # 0 +0xFEAC 0xE2BE # 0 +0xFEAD 0xE2BF # 0 +0xFEAE 0xE2C0 # 0 +0xFEAF 0xE2C1 # 0 +0xFEB0 0xE2C2 # 0 +0xFEB1 0xE2C3 # 0 +0xFEB2 0xE2C4 # 0 +0xFEB3 0xE2C5 # 0 +0xFEB4 0xE2C6 # 0 +0xFEB5 0xE2C7 # 0 +0xFEB6 0xE2C8 # 0 +0xFEB7 0xE2C9 # 0 +0xFEB8 0xE2CA # 0 +0xFEB9 0xE2CB # 0 +0xFEBA 0xE2CC # 0 +0xFEBB 0xE2CD # 0 +0xFEBC 0xE2CE # 0 +0xFEBD 0xE2CF # 0 +0xFEBE 0xE2D0 # 0 +0xFEBF 0xE2D1 # 0 +0xFEC0 0xE2D2 # 0 +0xFEC1 0xE2D3 # 0 +0xFEC2 0xE2D4 # 0 +0xFEC3 0xE2D5 # 0 +0xFEC4 0xE2D6 # 0 +0xFEC5 0xE2D7 # 0 +0xFEC6 0xE2D8 # 0 +0xFEC7 0xE2D9 # 0 +0xFEC8 0xE2DA # 0 +0xFEC9 0xE2DB # 0 +0xFECA 0xE2DC # 0 +0xFECB 0xE2DD # 0 +0xFECC 0xE2DE # 0 +0xFECD 0xE2DF # 0 +0xFECE 0xE2E0 # 0 +0xFECF 0xE2E1 # 0 +0xFED0 0xE2E2 # 0 +0xFED1 0xE2E3 # 0 +0xFED2 0xE2E4 # 0 +0xFED3 0xE2E5 # 0 +0xFED4 0xE2E6 # 0 +0xFED5 0xE2E7 # 0 +0xFED6 0xE2E8 # 0 +0xFED7 0xE2E9 # 0 +0xFED8 0xE2EA # 0 +0xFED9 0xE2EB # 0 +0xFEDA 0xE2EC # 0 +0xFEDB 0xE2ED # 0 +0xFEDC 0xE2EE # 0 +0xFEDD 0xE2EF # 0 +0xFEDE 0xE2F0 # 0 +0xFEDF 0xE2F1 # 0 +0xFEE0 0xE2F2 # 0 +0xFEE1 0xE2F3 # 0 +0xFEE2 0xE2F4 # 0 +0xFEE3 0xE2F5 # 0 +0xFEE4 0xE2F6 # 0 +0xFEE5 0xE2F7 # 0 +0xFEE6 0xE2F8 # 0 +0xFEE7 0xE2F9 # 0 +0xFEE8 0xE2FA # 0 +0xFEE9 0xE2FB # 0 +0xFEEA 0xE2FC # 0 +0xFEEB 0xE2FD # 0 +0xFEEC 0xE2FE # 0 +0xFEED 0xE2FF # 0 +0xFEEE 0xE300 # 0 +0xFEEF 0xE301 # 0 +0xFEF0 0xE302 # 0 +0xFEF1 0xE303 # 0 +0xFEF2 0xE304 # 0 +0xFEF3 0xE305 # 0 +0xFEF4 0xE306 # 0 +0xFEF5 0xE307 # 0 +0xFEF6 0xE308 # 0 +0xFEF7 0xE309 # 0 +0xFEF8 0xE30A # 0 +0xFEF9 0xE30B # 0 +0xFEFA 0xE30C # 0 +0xFEFB 0xE30D # 0 +0xFEFC 0xE30E # 0 +0xFEFD 0xE30F # 0 +0xFEFE 0xE310 # 0 diff --git a/desktop/cups-128.png b/desktop/cups-128.png new file mode 100644 index 0000000000000000000000000000000000000000..5c0f6ff20b6a79d23874eb72563f4fdc32b6ae1e GIT binary patch literal 4888 zc-jFN6X)!SP)i z`Qy~J@4Ixr?yjot+x=euKA-!!eXDCZb?e+y+c~F1RcWF7qDS5Yw2&`a4A9NdVt{Ur z76Wv1v>2e9qgUPp)C(daz^=fazz)FHKtFd+es2WcE^(~_R;lX7x)WbRNLQQ&ib#K8 zBybS07uM)Qfvp0w{t%c8Jd<3i+7_5+uILgBAR>K$Lx9olIuPhtr{b4WV2H<5_5bQr zZWJ^%1Bl3{fwO^=FfrZ;m>*g0oXV&i_`d{uolZ$cW90Yv2Ez)irhdDBuutOdRgOi|Shc@fcY3?L$> z0@nil^QNUvm=Bz!s(;F(@P=Uk5!o8J4LBihT5`ZUz?W3@_w_EgAs9eJ1_8eY_RE`= z9I+1ghN?bL&q8x&01-I|_!apL^wwjmdCRfY!~Vdw?%uo3v}^>Kc}jDor()3pftj zT+td_^MM~>8$!J!)7=AGf&4MBqDJ&9a7kU-A*aS4iS>CgUsyZv05H0a_2`WaT7Qj+ z@7VP@w#zX9@L5bO$9!3L07LU&=2X3g0uM&6*BijjU4{YNOIj821-%J;HP41GQpYjC z!iaTz1nAN93;=8i%!&A7?gw_vyTMD;bqio3upv@iFX{>ma9yOAu^Ko%??$e$&PQX5 zJfU^o0E}o_1^|wa)cB7ByXM`nRo4BJKwE^mw*lM4rmyB&!6LE?FfBq>PXNcL>T415 zsvA`G&)C2>R8?#@;Jk2(I-=$aK_W5(Q`ri^TwtWCz8it0Tp%I?fZ4#{fNYingH?5X z6r!lHU4V!jL3rc8gnju<+xP%#D~?~qmY#jF6L3l#iVQWA03y;Gcn%mIkj+xy5N&eR z>oi2>+1MCaDpefB-r!s!7d%RIqSBc2E*cbLxnwdmocZ@+-s_IQ5 zG7vb^{rwZ*P~cP8=FYY1^z}q!JK)EiO3;U#J?VR46`P_0hsE-FLNtWk*Y4h#P?Rf<>d+yk)GI$V+-J6;9YE6cT$CPRtw*5pf5IM^+psQ zK~8=83!ce00(Vvzcb>Z+B_hLB^)Di_18|xPU#hBamq>8ZGF6qb~e zup?7(ORWP82R?Am-*Rz!08hKH`9Po8>nC|#vATee!N~2EMpWAeAB9cJmSJO#53v#Y z*Hm?SD*9q<=WJ~%{lmb|T=)_f{DFIZ5tByaG3L1kxW%Pw$2^iOz-AO@Ra3!6MwF#s z5&0kN>#7!OFvU(UuNfk;g{pq&lePszumo@eCf@~#dwm-ppw;-{h|vY?kH4*4-OZs} z=!h7zfRO%wb~TZmzo0EM!E3S$G;ViLGVwO3>iZ?~+n}oNyE%0~pj|U6XwH8@FKkR9 zlyN$#s;g6J)~V|HY!iAp>Oej}Bm*yGwJRwuwYBDBYDVm3+!gj+{ z;oDPrFH6@U^vY8LJg@$~ao)gI&w2vG91V|($lj{DBo%Kq@D}!E9RTbO+$tiARP}$$ zlyQTI?5o8!a93ip2C)77ov>-?q6+EX7Gs8z8)qUi7^`D{Y)kuD%;oJcV7iF3t7^qF zs8R?T1Bl2FtnxmnO8jT=w5lGXsz+jtIvZQH`(`HI#V+2_j?ULGW*AdJ8AE}Kiv6Lg zH>v6{RUL+zfC0Rfgt_o?__~O6<^*dB*7&n91(~s`x;N%OiBhyxi_k$}HCwD%gfPHI zP}@G9?;dyPB;F^09cJ=!prG@W57rW5c(Y}_$2fYxG| zi7hIP1^$(S0!o5}>Dqy(;3GBrL~?!L?%QEqoHs%lz*q5e1E&4si^JHwv1bBzWx~c4 zNjpg^bI>>i_P=) zz^Tj}G;Fu%ehurK&37dA~q%GxWq0qQx}$oopdw496O{~Gr7_reTC z($m(YOWT5iG+2wNrJaH8PDVkf1n~9UyE?Gk7gY7T6~tShs?WIJPm0KK*b5yAl+`~_ z)jx>HG;HlZDg!uNirFb5t)l^^-dCz6Ws?hT|~YBY!i!syd*#<1Nb6Qyx6gd zG#3)s&z6E4z$4b#NuRF+kBG=cBJyAOZyOgyCd7u#?7Tg*H>Ss6SKcuq~T*c;vq;FLf&;3q|{ zSJe;|vKAsCqzmXDkUp<2poI)V7$9U+++u(RLC7>P&*Jlen^pBO z*T+xB=F~T<>K{_+cEt{80PBKgiO7M#`7W<^Y;|s`sy^xZ-g0JYKX>=jI*D_g%Qv0Z z6`C?Gbz_5zQ~#fr9tYGE0o%Z%@mB<$=vn6B6t+!QVv?kTLMXNxm?&@dPNlumh0nuW zydFuxSMghPbmw*w*2R^p$2k-hi%MO`7s>1UnR;EC`M-ax?cTEQG=KpP3SfYL^DJ{_ zk{D*AxS+ z$iz>sfkhbLrA)n^&x-*hp8Q;w4o}1R0!Xk57$PDE zsp=oy)OKHNr*dGG?;{)m5?}!S5@3dBnLkM7u^h7~Iu#g@iPsxj>Q&%XcYhbyB^Br2 zQ+X}LEP+nR=9P+{bUnvs!V?Mb4knq>*LW8vEddg(rXRciCc5XJkb?vWVSpZVR8^|x zs@NDLQ)Vwrt6WeduPZP~md)!-4+bc9wH0B2q&rHKQ)av8gPV#0 zT*X#*Qu)rV-v^f43sVET9NQUG$BaWV@$Ps3Eu@5350}^HU0!W2{w6XmX)9oWW!R=p z`ubE62I!9sL=~GoDDbCjoMvHwCHOJG^B!dl#`eA+rQ_(n5AfIIg=W$uN|-Y%%&Q;P z7b|vvQ#B0G)(P!d2KX2EJCQyU@?wC{%^=@_pwA%iub5WPC`?r=8Nhymf&#^oVhPLS zH9nQst`r^O_(sfX)(0o3>V4jYw-5z+jRC;+xLe2>p$xFNe3X)CF+c+# zbPN#UDy78$DTv6&unjgJ%u&^aJ_$n^-~~)w+2`oj-9)6n2C6i5A&jChJ**aghb?wh zji4?-&D?5E*@&glolgtTq7vs-rSO7p!Wa%Bo()Lb>IMoJT0TlqtRrA77J~so#sQy? zP<~f|F9Xce%`KuTM&1%&jEF?Da%pn-b^+evA0jY-nor%$ymMBFJ`^l_yDi*D;HwOh zF9SG)NP&|h(a_8|ARuj!`}$Z65Hb!J?JRP-Grkm%w&^86Pi#}9JLAiq>E6mLFEtm7z4mJ~ZlQ0cm>zSH~ix zNpLY%Zy$7~g;X)3o*e3Y1}w(^>>z+ItLg)BC~91Y$Q~3-(5l6H%+3Bgp>#x*0B%is zYT1aLV@l{jNKJxE@ZXM~8Kd!`Hit*wLYPwHP>TEa>oO3Lp_mUsUqn+QkIn#Uhd$pO zn9ZeKe06XV{(b*iAX*n$tK;MUBQX88zymSP#%(l+$jO8)eEnQAXAK0=6LS#QA!CtW z628;-1aPdXeo!uAGeAW4!+ihxsL+8KuncihHVSGb0RX;7!Ktw?Mgn(tg+ZZ+48ROn zd>bFknMJh5hZ-_~TNt`BLRMpd+uaniDdA|Jft_vOi&rR|6%Y@#v^&GNJ#o+wdfi+v zd%4K(Krjy_q4hthCiK0Q|W28DCTr)cB^fG#4Cws+Wf_5iX8&VozZr)#yRM$IdN^2co${-3J zxVoe?z|In!NWo2A=rtGEx=S#CdqE>9eWqWiG}u1JhVO|voQU<+tIO--HK#p?mvsWB z%n*|a6k8&_5%^@C>+?lSGdE^k)&Tq0gZ`SW1a<}yIh!JfBt*pHn6}JAsv2U#z8Tz6 zZ3koP6JG>kE3s_Cw#0uEIp3nlg#iFWWCC_9TdlDObN#Xqa|pRCxwL{MX15&4w0K|{=Ck+)RgHG& zb1XCk1HeZsa9_jL+(*-((kq39m`2p?s=7XJVoITD7$6Pjg8dZWbYRbXsp)|An9}D@ zfqON;c~ia6lnjuDJD+zn=4kOyVCy;-{~p%hzjN2DM*iB1q3IbQ4R`RvXRvMOeSkeM z=L;dHoF-U@O;6`gXz;meN5D5Nx)cMHf;+Zt2xhdp4W_Ht7dvUBFQ&-xJ~l;L>FynV ztE%^Dr;Utm!2m6kMx&3UTc|Nw4A9NdVt{Ur76Wv1v>2e9aR8bTK;BT8469vHxB0*C~6iFe1je?DZjW1v! z>I+PY_y{&hz(()|^Z|STEiA+$1QA0lg=i2G?50Q}7~K}LCrqw)JaD-8p1aoCKWm@J zOrusrOkx(_GjqQcl$l31PGAY2@C%7Q_>4ywJA!YJFX3a6-eVbEyh5+eUn2eyKvdM< zSR9er>k?UL6L?TRpW_A|;vVkfR$*pvfDZ%S_)t5#75ynX*u_33s~0kJJ0fo5R76B( z=CHsOY-Z+Gf#$J;^H`6Fn>dHP!X^3{L_`N?s)4Xp`&f|@Tb0Sl0ngCO@y7SHs&~A~ z>ftJWqL-N~1A!O}Qbg=xCo|_F;zHFA)A)hQ^}L8FyvxkJVHY;4!?R5b8+L9~A10bM zKCW7y{f9hXCB12zg9&U_7Tp%|G*yug== tmSx{M?l$pXH=6ELQ^z=ND%=A1SEn= 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 I71!nlAN6Mw77Tjc^{wG zdEP1Lz=iWX_ul{cpO1U)O%dV$l-V=clv0|Di!qGFID|2bN5o`LU=h)3pdXv?I*ub6 z#$ScV1DMwex25qLu(ylRZsQ0ZoQ}wJh7%s|V&EV?!5jD(zjj&oAqIOUfLYkq0Jt3^ zNDX^dU<;1b_PmDKy%M;$266)Tv`pDjjMw&WX-xpDYF_+-4Q&gyU@XHA6^uzNY)jyU z8v8piuMoQumt$ekuf{rDge5hcjWwJ*>$Xz85v7!t6y|4@Uq6-HuE4d$vk45AwDgxk zyAiiW#K{U)KlWpO`So^0tgqT@YD60=#^KS3IG$2Eh}9U9kK`WQR0uAWd&3ZZo7xx= z6Dg&;aas9wBBj(95hqj@)x%${{NFLBGIxR8`OZV19QLIpI_F|hFLe?TjS;w{qVI}` zqa~ad;y!#Y*F(amh0t=jC!CW~T90?i{$=~X%l}%P$L99h{OXG5gGFCcfLF_@SYGrcm?NiXpluEG*S-fT z(OD_qay#U+-zTSNs6=E`Zqu9O8W@&O#5z3eR9$pPy#~f>-^(ld1m2VL`ji~%kFZaE z8+?Oz^<4B3dW}Mvy_q0~rMp8=W%a4m;`6~VvyCdS~p0Q>^;J=i=0UucMa*88~Q~&?~ M07*qoM6N<$f~`{K-T(jq literal 0 Hc-jL100001 diff --git a/desktop/cups-512.png b/desktop/cups-512.png new file mode 100644 index 0000000000000000000000000000000000000000..54a1b3bdcf22b97a1c286199f221c056f9f44452 GIT binary patch literal 21029 zc-qXni9eLz`#*lq45qS9L|HQk*|Sf!GM34{6%taB?8_kQ%*(4xWEoK3>J_i5*Ge#e64ggT# z^mB#*{Mrf{H~_!s{BB|_&wziSXC4y3-)Ft`ZTtX0ck=WDiMw*`E_m~jzmB!Pg_pB` z;CQ2RUL5og}b^rEh7{P32A_)jbys=G}? zqd)5hCx>>AgZ~aa{S`Lh7WUUKH{^In@hVbQUcR!iD-nfDPfu6ur3b%kp4$Ow>FJNY z{{Q92{4G9mSB40Nj3ig$#48);SE(%v4E%6@2)`6zPK6_z?v zdPb5_@|>hnXKv+5L=51k#3m(n?wL)@vj*H<+}+M0Df#24chQD!mosg4KuVvoNbO?$ z)XL`DS7~+%Hnr2WF(ZtT>9j_1x@{Bw>m+NM(M&U9{E&a3# zNaxON2k!Ex{aS#MOYajor_)&vKH)#%o|(^c!{T9gV5xEz_t_B2qDGGf&82~^=lcD2 z<%T~o?A58FNe-!GQZl+Vxsq9daw??wuu*;Y1?h|I2%mAAFc*^9kzTW?m_;2 zlsAKpocB$%T7pWvjfXTK=|-G~R~H5S@ro0r+N|-@8#BZ~jN=G;=NIIbLA^fG>*pn3 z;b1-HqZ)@O1+hX!O*vpidTm=Eedpg$@<+kNeR2b?#)3EN!Qj6kxZmQ@_+rHRLy&zO zBf#S~S9I)wZ^CzVS$5NLM3DB>6gy9_(3io-9tjfmlBrxGyOq4Y<$NWlnu*OD5kSn+VPH4cvD> z0(&HixOzsXALTOKHsbAYH(iCYz?yjwH3cjWes_Y@crg~ZK-eKv0u+OiK7$W#?^C82_bygEoKbQ1SieYBccc+&MX?uo?nwis*zY#SYjn;3#!o6{c7>5s z#dpr9rJ!EM@^b-$SBXmW&1XxKP%$HfTD+4;SKqY5pFw)?$vNU6&}{r6XR50{P>#Az zNXtMGVxOy;!z&swws!r3XSvLFz3w+{&;9-8R?aNbBq1gXg#UZxM|l;c)^d&f-$= ztgDOO7)DUSi=h19Bq$V-;>~z{>K`qsIq$rhz_nmD`bN?>*>KERq)(uFmkWBFoRiK` z4#^sbb<-u;LA70AnEbXv*;_DtFY{A2jul8vmGG042PcJ3*y5$=Q$D@OPqW#Ds-!th z;i4>}J~-C`70sAYmOV|!^#Pl%Qke)?bqrzI0{&qdq_b_X&+yRE7NQq7{ddi35VwJ51+wKpY(0d?kQFnj|w}dkbjYvkuysJH{89| z=p2)UJZZHncoTAU`pfdKtrc)Mr>O}qMqA&j4n--NHt zcHt365{%1`udV*KAfVkZiZ3_iWqtDd_YF$*Mlbxzo?jl#>%a1DwULtXOP=GZz6f_iLV1QIu$;@^6etH9*a^e(WjrX9 zGRw~>aYjOc*tvfS@N>8Y3tsf*&CrSgu|xKXPcgVY3iPrC=y~A`jdEDdk~wEezm5IS zmy0K`lqwDrE|?76Aas!Q$Eso{^PD?7f)x}^b{+6Ff#d=ah42*hII-6wRCx9z=2|t7 ztHwOy??2W&xj<`{H~^yscE{xPC>pdumc{FLiciYKlpd_*Dc0e}yu*;t2_-=qBld492GSWvKmxJ(s1+^H4`gOh$}THqFh#<&uR9)Pdf3H*G#h{Lc5r zD5teB8^`Xy75>soanlJ$Zp%e7=oy00W>Z52_bg3pQR3?TXVGjS6$cU3O4Zo(EJtG;gJdsV-AjhlM z^`gWV&a5znLagO{vdnh9C?W_Sucga%J`mX%;rC~=V3I^s=b4c6DolF42DyzdU_s5Xtaipl_` zSVD1edn7szo4AFHLyDKePe{6C-W%3xCv>t2q32|+5@1fO|T zAb(E(h`RR0MBJEvvvrCXO>h$nU{g~An|-)SEf^5|k{tr*{!213ch`RMs}Ld(N6@x_ z%Vj2$?%~#8n?*hSz9vu}y|y}#v;;_6tG@&c1ayujNw;i3{2R>ov$O zm^(RJ%8vMH4!@+w4}GkP>1BxfkClcBhnFrywS2mVK4K1%(?K{U-G%MhEwTOnPOo*y zcTO@Dh3-_x$aO}H{V!oxqL4E!hz~+kIm-ILQ`;4GqS{m6Gir1{oQMGo;Y5^P=fv4Y zDP)g6Ut8%NqEg`>X6tL%l$3hjARn}$3E#u4TKMY%;rDdBL>1k!V|wc$)(9Rf!iS~3 zCr7!Ur{CPo!hOO6Hp`FWBr1r?UKm#Kd8Ksy%y38U8TTxGTfEbM<)ZMORXN9FLM;*$ z;WR%k;D951&tx7$QAeyJG><&S(QUD0391Z3VgyWm+4 z5b%PK3&uw!!?~s0DF{ztPybB~Id3gHpo&1+$G6N(oLsqKA8d{qitjDTb_=)H6NaJXAY@ zOXJsf0pTmII+U1VzpAcdGAD==)TNNC4Aqdv3G97W$F%`L-SiOPeA3o+$C3e6+gbkT zC|Wx>$4`l*JErcO3L+q1wXD`6$WrYQ7t30-*Z0fl6v~i z#{jv8d`^~NgGAr__z1uNRNQ$QL(GN3u?d~)?Pb4Wkb6TcuTex6W zd?@q?AETwq`E9JP6`G$-9bRJD0&$o!0>qIl(Vo<-Zk-QF@35cM0p_GFUCJIfwHdVI z;c3`pt2Dc^7)cH^U(jE{IL>XLbxJ<)=tVaE5RrE zDkP+VjBP>3Mbu+Ft4>>bv36Q)K0$@^Ynb`p)neGob0$!C z9O)C@fa)3%rPFq35hcsxLga)Onq-SPxpd>@m-e zn;uif;@bF0Y3plIEjE=JXVp?rXruwG+<-6duN}aYNa8Zjn#!&WL(W7G2zL2elvSy! zVB`LsOhsvpJw4+{5I$xKy1T@CHk;o4{E48vL0%Tyo{Zy%0h{wd=dBfyWhQ*2_h3jB zCf&GlK|6wL>9pJzgoq-R`_7>PwJ0nB zJt^c`HXu0qou165AIw568&ExuV%-Z^VsmCd$YsyKFmX9BcQ6>;tphH`#X~nqEQwzg zDC!!s9i{5X8D$PXU*FkpxFo7D86qJ%F@8o81OrGKJHo-3@4v1bO#cD-8P43rb=cog zPC!Em^cAK_``JTk3*DYANJFWCP6S+*SqV(pL8l;p0>C6$7_ksQQ& z6wA=w*@_!ALka#W)bHGKGA{|)ZdI9*Qzdw9H-%#>wB>QrBTPRh*%cHKHIhIzB}=MZ z_pJyJ>5bAP&g9-|P1hn&JAC)a{wWy<5DLZu_Rg zjaUD}R6F#-R6{+99Zc@g0hNggGTtiG#^}O8=+x5AK^=kcQ{>*+(sYzTYqcTY>sU29 z*~`Rv28|q)9`X+00LHC0KH){1V(qQGai3Lo#mtDi{r{+sJ8QlZH~~Ota6P0p+}PLd zO=Tl#JUZu=G{CUHH~aKxo}Hue#Bahc)HH=bH(=u-I#ggUEVi(-f9{LIT*@f++{*_- zGqs*&*~Pigz#^7JTnNN@8tMoLci-@#>c+7|6BsR`F0!wsZuJic9#HKmC)|H`QnvC? zT#_^oz8i9hB}p_OWU$V86*+^TRDgytd=-nU1~JA(uh+pV{=5@04JU9{7D|QLM4cqk z6RKgCznDdSLtK*78;e&b(Hm0-`Fjgv;VE6 zB9k|%U6qWS(WkU=8!3~VA~`V<0DPc!5G0AhEWlI{^_ZOt2qRXh zR)mA@Fs?hP7t8W|ZR~bGk44lUD>N_c=%en>>`vzJ9OUB2z}=j?T)^>&2o{IdxRWF6+`7$&$!~nW1s8K(xU-)_5|=+-^D=ec z8Ti)yl4|#YQWRm{-H z^<|gBWCCl&>*@`<=xmXw!5ekHGcN~Jx#yv$y#q577QSfauA8;Qj#~7`oO1k>>93h$ zM!0T2lx5clb`Lui+BF98y5qH;;M@;{uvWP%oW%vmH)u)_guoNn~-z{h&S!1I=-JZWa4$eZiD0_(iXG=#tgZ0ap7N_$y9&>U<9`*B9=}5OUSqa? z=6)JKOyf?UvpOY``QfE#-*Uq4;A2}X=S^U3yKXhoiltySz>sPHit3c?2!1K4_e=LB zgpczQ+k>UMK6?DwC)S^22h*xSiFx~TGC*}$_ESSGRjV2}oalYXy6gAJ!TBNpL>gQno+1=p7b66~b51OUWCSG^X<%9crZqq=EX|o+cS%qcn$oa_)3A zVe@ScP}4*jQciTah@81Wnc%p$e=kgey1H@baRxafNFjlutlD_X-=eM$cCL{(U0_S{ z+1MX|T>Bv79io#N*{LcfB#tbEPAzVXvBVK7pR;x3h}Yc5*@~LS$#Ve{o$n86rGz~& z1gnaPKCtretW=}6Gt4mkY_=>vmo}}dwqGS)^y8_{_u6ma7s>QmT*4k_N>fmJt<7Nk zH%87_zjJxGCgnPDWrOKkJ-J_TOapHHh+qSHMm%((pr`LL7XYTTv~i8&DV8HJpfml& zESNa?nXfR*`qIKXnXSXo$5ZMSI3ba4#YRh|q~cYV1*aN)=-&+w~d=}aDfE|?^Iu9{?qY{O@D-A4ldMr<|3(d?A z2>M#>G_Dvgi1;!7Jbrl~9Q@}XH#rK*&4&0%Rl~X00&j2hpPvo<$1+othHZ!oO?#dq zf;?g3HS2SSW5!q{T7m8UZOxKxYBcVOp%LHf8#XfZ{t(mNFcwnhyb0I= z!?VKgb^5l`V)SrA7Ey0a7v9_r%zi40J%>ZJ>pLK4Tr79LR$&S6JcnqL98G)?<$VG7 z)Hq}n(z{{Smi-&W+N2ri>(Mb#$isbeMLkLlCAyhdVX5(ju-j#Q^F11CW<&hseC7$a z%k_T_XdY-@9z;B(!OY9P-9`A3dieE+r}{CiZUR(e-FBZW4?wtgjt3x5Y7=Gz`xXtK z(~IBs-17e?ht!Qnb*w3EV8oFpB8!0S=r7F@>G~5IW2oa78iCNFk9w6yS$z1#l*}+$ z;v{Cwpmd8bPjIu4B_Wy-$097nJgYGM=RZQN7?yAq;gd@0EYA7dP(;!W&g!L(aC?-+ z5SBw~1In9qvK+k|djnwB0Hw0Nt@sJM8iz+*`-iSW*S?PU_iaaTdheCeT+l~c z!zJ^7HKfGHr0puh!LYva2{h?H2uf$# zc0@#8dy+!KpMwaFVULfK=>!#g@PcU<^U-h#w5xtW5QljMfA0?F+L)BcV0yp7p48FxwXF#Ob%5P%CgsZX|YE~MLDjcch^XuiWiVG z8PQ51kW90cpy6+$WEWiTuiEnTWIMpnQ+;%wF~C}PeW0b+q8vz@R-JRJ)L7#ohlknc z?`G$YMv;jTznbg;HXZi@d+^wB5XyYj8tK=$mwF^$gKX^Cy( zs;FdP5L*NaDXs54RfKMfFIHyFL)`N})?{f^M&`VIx~PrU9D1zG)ox0Dl`*8)nZtva!|_IMbjdi~@q1&HQbwiQH{L5W;KAbkhs&<|tF zdTmq1w5fe@%yM7|Yb7t3M~9tf6*Xu69e^Al5I==xgvf>DZSC52D{`mMj67m}maS|m zzT8yJI_Xc|vL^1HP~Ol4Qw!5krEWu=n9`XIQ=APw7r@@>dPE}b;Y+{0WRMQ_B{ngl# zV#W+XB)|xoaQxk8>w`rAeG7Mx>;5~`_(E{>`>*ZE%4xMiga|ncHQO8@O zOxADnM)natcca|g4Y$9i7L^HN$kpU5MdXPf@<0P+(|?6r`9vX`A0fIMqFLz!qHa#& z?fgF*-R-srpGQk`N|z1 z2-Q#(OQSh|Od9U$I(^{~R9JcrHvsAClH`+tNn&idYeA^}Tn(ZY!nXXeyUSgn4o-1B zb;8%3$5dtc&P+yJQIjMV$B>37?Nh!BjkB55eoqW zbKdJ=@pojI;}~%_jnx4m2SDGJ!}`8fY9_-t^Ee;EWGh4t;|BHH&3+Q_6W@SqIOrC4 z6?FU+?F^Q3ihN}s&QzGUE1vKmh5{~m<%PVr=$joR)ILaAv&r6S4K~qjo0F#r%smzA zE#GTi%r;(pRdty<9_^;aji8ls`S~h_=d48&G7p=24R`Ne3R15SsX$h6P*-e54dExu zS@eeV#xaBtc(R}bBJr59mW#k-ziVoI#5>1DEfZ{1HZkXbib4c{+beQof3;7phn}zH zPyvE yi@^~v45TDG3TJrs1t+7*bHvfAArpquh@Wjtw8N8Kn>d=fhK_rh97iJRT; zvy=i@&{|1&4l5s7ofFVtwj2C?cyz{FxZ?izDTDmI@8K+3Ha^lsl%Dnp?_7&YW-Lwz z?}1x`4q*-oNQ(VmGGcLDW=H=uTJ}ST^F~>&*ETI0QwJMWajn9is#EVg%f^?8pBw!Y z(m2pazK-`3$-eA5a^n$i;0PBm`|Eh^EN=VkFrxNmf2xQ$_Vw8=qy2A~{u1-3^tM4_ zfFU2!LI$dlg=#|!zdx77ctmIIj7tqyrv_rycqxhO>G9vDWj(kSjVum#;S9b+3m)B4pQ%0K2AUP$DxGHE%UnG4w80t{i&hI~%{ z{snk*P-r-mC9%qK=`y?Z^Sqd$j2ggOe~C?AKbX0_t?5d*af{eu1W#@6S6@hi3B=nB zZD;`2OHJDShvrd#9OWp7#oC55Frtz^$o1H*Q9&$WBZ>Bne3N-{M~E2kgc>eX@QEFr zVH$30ivn$bR_TOx+1nthT*gpt(JM!~{O}P*GnNn)V$3iEiU0MuhONEVMR}8T^75h) zV!bnm$lUu9<0=yek*ujI3)Aag6Pjre_mp;pP!`Cqq?`ZVr?^veDbCRgzx?nEW`-9_ zL*8qPWb+`D1ANvbAKn8JdW#~&Qgr5KSrH$?tnz)0jt0rnWH<3IN7rpi-9sJ=j8w;E zxK(vxe@j3bAR*>mL1iD=e^f&OM?Q+S7W>3U2Po%S-mx40U2bZnIKLBCeNt!a{@v#@ z>Lb_tj#;6%%SU#uQh3N8JNi(&{y=<8`lAQ0&X#I!IW`^Uk$yivc9lfN zEfeK50vPfH6i?@iJJOMfUQUGrj z3SBr4u*jHbdi0CBRgWnnHB7guxi;t{SP);kvsQMO&WF#b-NL)j%c=Z0x6>D^g1R^M zzpXDtI~(ZR=Dkp3S2_1~GjL?y9`{$c2{Z=7_Xd%z0CA9^`fcBq9+>E4b_s+{T>RkU zgD>`Fnmr$-fbZCEB_uEnV0JImoINhk&9rO+OrS}teVR#1((tU2!0-E9gN-t`Y@6SN zgf;4B>fyo;8hg#OehJU)t$@xIleqFXMVhP`OXIWPhv4N&?ROC;Si=@%Hi0 z=Mh}*r=gcw!7`=NELKT;>gT&T%XqWWOyj?;|$ALEC{(M=Hhr6vf2r)Kn}?QE7W zs@DCN5bKnLYwqUx-Iw~N|NQoRB>`(3Y++Pog$&$FLM=i69NJO4s;Ys6ttVF^UiVNt zJ)O;2`;5p7S4T@(SAJ=wjH_vFKWw?r+S*vJo0T|tKHd??ou6_Bj?!}lBu!teX~ zyVcwuB|+s>)VV`eE&z&{;7jf3ym#N;#I_X830_?Q+$Vw|sHhN;S$%o|ihhRv+BFwg5{HkX| zDBn6zqi(Zw+Z(P2%70CUV0XX0y$5D8;%E2CfZ)0;rI0#KKozSzZwt61i!FvWksK|g zB{ix`fDAQ1$Kpc3;^v{KFTBDCJ+A(*8|!~X;z~}71DgQ^l4goQy}LIHbn?c66$Gw- z@C&H#^m_ns+_xarhK?7>!s zKEen5zenCi=6xDdPc8Zp24a?TWG)^;QZgYZYd-4!yPgtU-s4aI+5ss%255r$a)eKxaC?jf+v_NS zlzlHjYkdfAp?-ensW}6J&T`7$d8A0;Phrbbmv%@h3t`u^(_c9QD~#jzee-M>Mkb0q zR%1d&u((I}hLUjIiBM+&{B=*x`k)Ok1+}00SVp@v|K^WvODIQ5f3hg|ZS1BOu+pcM zRf=vq=E#)Cene9DA>(D9yWvH#(e7VC4s2;LzFM9Je2#6|XB&l)8YqfQYmIqn#Ol^k zK&U^4a%b*j*<-hbeBpvev!r-xL4E8C!UO!zs~KU|=0#^Cv8(d2!L2}D=tZ{zyE~BC z4edL>CR}>AWW5EcA(SdY?PLAj5lQ6LK$lkvn(Z4cQutm|^$$xTeFy8}jv=V>OPW=0 zBKDp^lPqc=<-IQkiFMY26nDr?a@IVxK za-+$JP<=5V1q9|H_;^c&&c!LW2S_JWyXcXzo`Yu0t^GO#Dn{r9rUl(4c;=g_X zzCNM{X4T=2c18u8MM@XnKwnqECo>e2!D63f{lFprU;%4PIfGGWRo1ut_oU`ek8vEm zmb5zXQ}=$L%Ca$f9A@Xx=l+Z#kI4{y#Hex^B$%ve61nnE?)E`M(J;E?yPH@v&OR42 zC6YV!7Y3F-p>>B5p;mmuAH9Xd8J69&=KA${8VP&i)F{Ep832{5E!!$h7HAmxajX9v zF%B|0=vJFGXAR6=qoaVGCv4ZZp9vdPH#a9EXXFkX0-T%1BAqZRKP5q3!{hPvJ_`JvCu3Bc5Ne>_i2CTRaTE`tL$mQtYaeBAVSl^1EW?r&kwz&Yz2`8DUDik=ZLM}R3 z(E|h5<37b|K*p27bjw2b+?VA4RCxWaxYESZ7b3ZytVEtCf9FVI@Bltu1;ki#E*6*d zY19H29fpP;%M&}_AZI+Ikz{VAmHTOgTK*u_?eOr!bznP$=VQuUklkI)pfiqH_w4e! zH=}Z#^pP|AOKYrNFb;$TUVwG|;EtKQOW0z9=en$p*XQ2n{>LAPcOkOAzw^SpS;=Y9 z1UGz$LwC4r9^GZ#6C}Q! z!tX3q(~9%G3an!I90@tEgTI--Gl`Ek&-P$zN$Y{z_f0Pwn3l$B`2JJ=>nZJBv;6}1 z@kt;*u%hqt&|Nfs_i65>p|=NX=^D60HJjfWRt?C(I^CAF<9IO^#^9$q4b78Dggu^$ zI+77y8B(5~R$?`jOvcaIGsrva3S#a6B_{r3_M34$Il0KAkDD06al zPV$AwHlOZz93g>jRkVnZ`#PuS?5yMr{t}Hi0L#R<(<>7|0le~+0On2jUJI^5WdGl< zahRjC^K(X=&m2D>FTebio*Z;qZ94PS0T)g9p|bzidlwwvMh_HuQV7u1RVu^<{Qjm6 z@-t}WSp*3dINiv?Yn?n}xNjvknaT5gXdB_<@?X$)wZq-n`zrXv1=!+&R3u8#?%m%4K9u zXdWjOJG1U-)Gl6aXs$Ce!7#hcF(PH64jZ=8VvQNU)f{m7%+}&jsiV*n~_wINF zJxvL!^7tQjxJXy!957WrhErvrR$ieL@~^hsUz(y1{}nN(0Kc4SLIXCz>Y4-NXK--U zTc|>_0-c*0s^krLCzCv`j;>;wCR55^v>K}uL-dmnDhSh#y zfz>|$WM@oIRx5@nJYHc0Fq@`oT}nJN9`kg~GOlZ2mH@_Wf7><~ECr}t05Dz!lSTDE zg=Y3JWgpnuYmYmFznT6VCz}x`RogyJVll1u2IZ=guyNKvT{9BLg=SF)c3$wA)qM{a{6M`%`|}k3g-c@`&0miu`mM zXOH|px)bfc{4|g(sZVndbOp8c`b(1sbyCbV{_O`2e<(k#7p+9Eg;u*F{?=Ywo#hLN z(yN3kJaj5u$vi?cf!W+TZ4P+WTPQ}AlqJCrfpQoK8-kYL&qjR_?WP9bjv;6hgiEcsIxR6O**uKr&<_(U3ut7$&)Tq zec#C>A9_KhqGRpv>}Nr{%@K|@gN_JTC9#UTVxDcon(>hZ@QPm~{ul6D4NiGv8S!1C zerZ~>lAvPTufef-4mD!mZ-2HyNdga%5hI?UXT!@I=(i?Sh-Gdi~AS$ZJ@SoGm z*!t=Cx50b8lE`o|*GJLQFN`PYLLCd&LZG$ft6_lfuMw@q&xAiq_3FV@Zw{Hh8~fV; z6cd`wH`nu*XXTk>tJMMWImOYV4^hkf#@iVu`(hfOO~jD=B>U83JC4qSE0$&6DsR7F z`RP&bO>x1S@ZhH{&3E#n)d56?+Nx5w1 zI^-{2yD+p*@2wlV?0$8zJ1O+@PHvOG+Wcrn9nksP1gc`UZupX+Yz=-jgCM0}9F>-LDEh7m|rSmcGf z6|ny~3h{uvyVGrY(&RPp=9>{Yw;{&aBlQ$RumUf=hL#rxBxVauyS}%W^^XvDo_xG0 z*08Ng~(C$1mE+f3$>H`VgbC3I{gA7O}*`8{UA1#4|zt}m5}P9 z%}t7R^v@Ibm$OQArz3OFYt1>!=U+kcC-_6DgBerEXunBi29}g98A{iN;-{=GB@Tp7 zBk3nz>S~6kPG54v?buF!u;%kmoYs8wygupk{OjR9Z+40-hBmvnyIe}B&0lTm`0)=+ zI+|bdPTbb=g8!=OsBQm07k1xq(=;rAg&I#hy70a{%blW|S z%-L~uT<3e1MuEKx-Zi9RV!$hfga{slkK!*LreB}#p#8(%TA|0G?l3i39FvtsR5(zDQ)C2vKCOLHJt zE!MPhzNw*`_!vrjv(7a_RcfZ(j2xw+A35E@*t(n=wH*x~9P{lCEr%;Ar3qV2d5nPx9BCiOMp0x1kV2~`G~TrUXhIE&z;onxWA9^!u} z)t(qaEUpF^VxGyUw5H$ldrJ2~Q8@a+yZHBymHK4KO8)%PTSYXvQ~Ybes>Ml9W ziJEcy@4^L#h**+M6vOrI6IQho%|Q^F`7S{&9tz@YblTVvpfnpJXIdiIDR&3PDx1G& zk>%!YH#N;4a#24?w|JEQ`D?g~dRnN{W+F7x%^@LS&&Uh4Q^a-l!gxiC$9_kQxpRBd z00-Ey)_DY%S!rB)*Lc?!S!SWeALX;r_{Zs6acs``Ibaufh(z+o6N(Y*eFW>68IG13 zv#bYGZh;3*45g15G{wtabuIeg{^hkyI_BE>>iUKliy3vVHWTE{m;3fZEF4edo`%hLO1P?9;TK zwV{G0drc&N93kFx<+XLe_S#TdF{*aqg1?68lHAg9(#G9F?40P=79srJCH<+cAVpye9VXHF&lQEteA! zX{YNZl?-xLl{97hWPBcSRHU1ky7M$X)2*sFxT0F;SMMP&Ip(lYFWYD4M%IYqL@_tR zpSB5F`q%eBZFbMS2fv-cUIXbtgRV{%eAp|cztY==7_b2c%e%*;BwZepD{hlM9HK|q z<@?bV7E-X&qV)OI{EbBqwlDADlp)1YFm|tojX$V9?iZyFX_QToP-{a`!heT5)T>MS z3dagk28#%_aFzE_Ug~m4er|t$x1!Q>ICJAo;B)}XC6D!x3X)MnUB$UWpuGI?!5ME~ zH8X<~u}El<4!OIxo8zhI_0A>o#> zg?<*il+EjyY-3dBIwj()HjqT6Qx`<#MJeOsSR?}+gwws6dByYK4%2x&|LaAQp z^~DW&4tlg`2eX^RZ#oT8@#oYG6sfVLVA%9s+2P_b`6|y1)trfJ3y7?zIsoJr4EKiC zMF&8uq18lx^>$rN<&^S8GLmDhmy_fA#IN;>+X3rtNhYRUdu6tDvha3l#}4sC=R?ua z%Uwo_4ab;xOUl8sxd^ubsN+N+L&O}XynC^h_iTf?-;LSfbJagsV+rT8gIwCeCy z)&gl>rc7`|r7(@j;A&DbmtT?yd(aByZVn^8(+y!+DdW}Vs zvXh0fUk)qu+T!uCc*ZFIm_z&o(y7QSe6N=c0k_}{_1{nM^x>jb6NbB4X}60jxj}9( zfu-)rZ4*AnG~|q0^aO2^{>VcswTVlGF6aiDSMIf2^-Z)P{UB@yDC7R|XpOGd5+6#IzZp!JF$SVptfd>&oqjP`Zlgy(o7H<5Uj~5@TY+(z!UV+eA>$qkq zV--1*N_k55!u=LFBfraNCvR9`_ zMyogPFNuo`AL@qaEos?IotmQiv^5gSVy^5J0zuU1oDEURva0NuPvL&*JNnpTR=gtz zg{d*8aZS9vjzk6+@F6dNHJ0IXyMj3y>0{pbbACa#GzDAzb_$!xAmwNAR{ykk6 z2zhR|3t^*PmW^1FWKL)4T4>ei>T-WB83KIwkSRCJ&cER&|0N2Vo^G@IQ4+WniBfU4 z47v!C$N{Md^qTO2m!qxpS{h3F|GN}gfKs9dAl%jWPZu=?`EAOeX*c@$$mfgw6duxw zwlcBOeF2eX;?Bjr<8D zCbA5D{c21W#|X$T-qI{>^x{!UCW{+A%ko3OPxGk9X{Wb1F@8{kf}TD$EC0AI=@f( z`S3o-T;?r%Js8Yg&~@^3fKR@QCvX#J*B$iuS-W(UUMnY{bUKKwL@Jb0MyM6R5(-cE zF7QS{8o9|`SCR}M-Zz#2@!HdSj5rSwaZuZCTo^yV?f(hoi_NSutD}u$)9L8g+w}7$ ze0hQkMJx&bFyhi*jcM8Ep!A@iX;<2uu2ru>D$L_r0cij4u`&Cw;?%W45}Eq8vZt&*>jr`5*9YW+|84eibh5C3>pPyK7M`+u z!B-prVX5o?J#vAWkXRDQtHrQ18(Si$U~bcmk9;&Z7r-7(ph3BcdJ@S7B6C$cLtW0h zPaJy&1i6WS_dqrM5$<>j0BZ)ILlM6hoN_%Z47%*3pm^$E&2IOAIu2kLG6W7yWW;^T zh8ddhA@MGd>jmIcyOXMzs7C{;+`c!^vjIDupwp+J(Q4@C3GE!F$07(*+=7P#Mgx_JzORnk%AQ$I+X+ zU?@j~;ZqUvNMkH;G$4l5)1Pn$-3E?Bn&-!zL#)eEmqFpLKh&yJbJx*erG?=9EdIBJ zb$b@Y1f238nN?3Si6!v%2B*hH0Z$SXM7ZMFioTLezL^oF%5m)oLj(>@S~aNyH9^V zC9|fG<;QD3p_!Zk!O{QdwTuuxg5KCA-WQV0D~Vv}U``>mmq{ zNX1}OrJpJAxLk+&6|nSOE~n-G?};5Cd3GiFw3nrECC%$4LBjlh8=vnH2obP_f}X@5 zqQX+Iz~|d0{ZGhWK%e_ML96tJ{AkMBrL$(*Gd0W@!$yZ4FLP3!ti0E+bpj5p!qhjrAQnvQMTsWK;=}Q4;(f^z;xKgN(&x`$!ZZ(3ak;br$>>7RgvKt zsDEwZgx{YzVoy`XrqJ25A!z!1P8_vxM;vm7lg!%mUyZO-4%n!$SvQB3rg=E+kjses ze2AiWUa;m>5yPIT9Dmh$GMRJm=F1;w}?eHT8&N?O{|87r=s*?=%|IKkb z(d+7>THkWeDZOKP@*qnM*iRODr+8|7#kM>53B-R^y!`!C%6!+!R& z*LuF|yVm-CK5Omg+3Vo4^lKp=Tz`q*%QZ&Imt`;T)80JC)sd+UpY0(6at6OI4xn6+ zL#b~P5drI8+j~s-fsyfV`SR(m*bgj|&tc>TlqIo_Q&^L=9z^stMfq=kIM=tVsc4cplqjSbo zNeI{DWv>)qGZ22WT!ZWQVeG~QJC)-ENuY)2txb^H%YZOPHpZ&(rJTnWSqBe!$+G zTudLPEzbA-24bAowAP2;?EzJ0=L(d8Y`eY%EOr}4AlKmCqp2qB&{VA3|Ggu<4k<)e z%CDhLg!K<~n@;2-D6)1Fk3gFsc2z@T=Lcx%V_!ARM1pdS^1Rp)cl_k|m2bZy^pHn( zgB0&G6r!geGZb(O&cwp47Gu^(1}4__#2d_E85eLS+6=Cl=9 zv!!XiO(ofDnqmrPKrzJkuhvG-xaOfr8f_Mdxw%6O@_si%7AZx=q@JHldV8If*~>`P zj7_k0h@{cX%z=XQ2)i!*YAo;gfG)xI2<{n8)lU5hoiH;mVDN`bTmzNphHveVm1ZNW z)*~!z6pWJRFgp2f)tZ^&(^b5i^Si~rK;9u`onFJA4ie*1ktm7cfk39X2Ra7rs%psO zM?l@=iN}a);y$q&v<{m4g%eR4&%Kc<{uD-) z7^agJur_hF5XtsN^5-W|`|4k$jROy%K;o?Hw2AHNJf`z-13iS9;Iq7 z*jJ}_{^Sy-=A&H_7UoUr+V170gwjUg_eShx9jf!G>My^L%j`-HC7;uc(Z{;$F*D6y zZ;ouqLU(lK@(o)WeQ;VgJEY&TSF#GYEd{*=3n>dn#yuaz@1MLsZZ=ggpZX>+_1>~$ zE6?dTr=h_#mdy;Z8xAn{IL}8|@Tq&!vuvJXvTz1=bkG4+uM5Vp4grN_m1Al_#>5|f zxU1xeV~{5|$%i9|)n!j6Rqt->+yJW57}CjL?uNmD(~)X)bE>0{Av5|SKMB1BJY3!2 z-aL*@JvM1SxHE7<9a8EQZEEG6SgyF4ZwPw2bXJs|Su6Hub{;gHpul#dWzK{*PBGg6 zxHpS}FeL2V`+ef0Cr~k$`3ubRj&p$ri1mEQf%^--oX;2V)VY~yE%U##Lp8%DeIQ(Q z{I`*Y&$n6W`b3;>M*nu_&Uf4>uAeuenh$E%>~8F_2kh4nZvYuSQ+lA%Q*_&S#GYt8 zan=rYZxeB7uhBn_O-3Wz{HX3EB;iK93|Ro0uG4Hz9DW1dXPT9_#Lr}2yl-?Z$dhCW^yqa+9G_ihLtPX5o7H@-X zqfyiS4Vi`NCXxO~l((ZHuMOzcKLV!2ta@o6$U}tsuoO zQSVPrCZ)na793o7EJRYdV`l30w8?2pJOna3*F(oZ+`G&dN1?TlF4!An^yvma88Zr{ zA4tsQGRRb+m*K8_HcIa%pPnPh1iw@_Sbd6t_d!E~#Y+>E;Y|M9>oL&^vk>6~efOzA zcG0Rj2c=iSrz^`g#~i87NysQnGnDzV<*l?VmnjAXhY-BljCX#x)FDq`TuUf5ZvfQ2 znQeHw?mnl7O0~*cQCs8KA!%gR4mbqXYmHwj_R7DruK1Zqc#lwe4^j4Kk~GtZo|JsE znom7Q<+}WN8%(nqex9x_CBQ9Rae)nFs%JH!R8SA72Qdp&?m}y}Uyxv)dNu{c`mo2m z4JwOWqLy&z`^s5>&fvz#*C|lFV9`HO>(5MV35pnJDIJ<74OgcQHEWFo8E`C}JBy&4 z{<+N|7F!d29_!J?RQZoC^h-XUj-@v+GT0xJpv#cPtD=0%_`?y^7W(%-2n)J#%Nvs6 z!SY2~tp7g88@of1TF7k6kjPIun$N%a$7p@0fm*v^g0AkUK%nWZoS)5q`>RC$tFGsd zRy{f(EBifs_(2W0n>trIZIWk?cREU*h=tSAG$Q%(j9PW~bcxbgjNSGxEsoU6Kh{ym zMY|TBuXK4P)6~DGW>T{sT_^^6mxAmLaZuq0m?ZZm{OD2MyN6kq_q7}MwCl)McD7<} zpE~<{L$A6#Iw_>Pe))wJ!RF=RFF)QP=62wn%E%Mf6QYtH`*E%gY^mW^2vUNP@ML34 zLW#3$;JqO)CVtLYdhf{PS;l)Hg5vyk{aiuQt1s2^fJ7ZP?GtOI`Z&e=I>0LCTW{NM zlFgxR!@pgJ*4%$;q=N_bqW=}(l2mce%p+-|l%4cLGdmS%yxL#IEk>WZ(?_lvD1$Z$ z78j>Y0`+tNdp9Np`xIqY$+%R$CW>onIoE>-=sH03FU&Sjau-C%=c<)&61w-vC6;Ui zQ{vGh3Kk!3Jn4mOHgEXYeYpa8>nMayT{MjFfZ@Y-T=-C-3{fnWiFOtL@F=p$H+ zYi&}JKSoSoXRnIvHd2vud21H=;$|bE#TICgd<&h$v{@CYMATNo;Q#RgT@rAKe+~2m zJZt*M5q%O2p;u(=gY(kBgOg_D@3#+8N1Bk;0v?m-{YTHdn=}Icd>(#7Du*g-8eH@0 zA3~~vmXY@0J|KLI%(9Io95JVOJV-}n89$lWVv8wR>=j*y#-NnJ05kjNU%5i%Tw7Tb zg99{rICmOw8$exO&ecv$?gz`cEF@oc$TImoqAg%of(<_<`HJ@kBJ3Sf#S_xH*8%1T za6!ok=y

Z2d2N*gt!2@HHJ%g1shiL>*CGHm$3rXIUj2Ob|xl7_z911*n%usp$Qb zi#-xt=&WDjlTf^L;tt`KJXYE1=v6^e*rWmY5i%c4Dd+m*3kWk)@cp5ah)9?C4)Yc3 zfVQilXASJp#1x|(as`S*hAt~%r~?B2TMe1k=#HKpI^9>7U@thR_1%xQ!h>@x)PWYh zztS>Q`e>RWKED_K3;HZbNlnz#;9;G#P06`vg;HBJ+a)wYK{zo3(Z{acGJ&IXt~RG9T;o1o0bnLV3UP5gap`9AT=73C8$_O%4u* zmTOP|{onY>o1{0OIH>kv#6a^Pqz3m27W1dKi?ss)D_3GYRq6}>3~P;SDVg=h1-Ump zQmi1tT*Sp>;;ehC25%4QKK4(ohLq?8`VUPJ4y5y9g{3FLh2bVJALU54aw( zI9&!?Cr~l_xMyNpLR@38TPqE|rC$;Jb#c!1XejCmdlUH->N|#@Bv1P`Z(C7nrL8(b z2(md{i>+NSJoB&zZ4!+^T8zv1_NUPIiqhdnMG}*usFXBFxSslTo5uzZEj-u=xb!Ng zVlM3owy{e^dsgkExgLaGq@T$5NEAIw$Zj?5!Kk>_T0O;vl=7V z<;ZV|)}tW`>YFbWLk)ndc1S{LzcJ>8vHiB2-&g+0S$F{A|FURJn)#adeR*1S{Qh&% z{4v!E)C0iPo=Ds=o4oEVCV5i5h?BYL2s#_kjDDX2_;*~xEm{j~t#23PxKIEwc$uwp zs%#5-M^=#`TefogkzI*ry3yA-&-tBe!+!Z762~+R>SlXa0_r!&3LV`;C+DWfc6>-UY`C9d=cpLh5-PW1Z*r=@ba_~n9!pD z;FjdObr!rd?FVLbm;b7iprj*!p8(SnT0zvpkb1<|YxB)n-3ZVM{R|1=J zjyJX*0Nk2`nf1Uq)#{j%F&lu-1|ehP{tXyV7y!Un;6Q?jp8Z2UV5 z0U%7r^@+jn2YMGFd%;u;GE>-<+=nfx8~_5w;7Z)6xaeB znNejcaGIIDo~y$uNm2vwA}}nYN*i#3neB=7Q^|Jt3bKUVqns51;#UfTk53vu(d0AE^-z(0ZOaZR2yoxsQlPX>HD)koeL&;-0CQhs&LegIYh zUoFoxv#q$#@FieYo~2}FEup_GdQYm4ya0SAQuef&ttrcE1A2$&ez?YN5C3ljCIh3p z=&K3e@=nXi7r>7qWoJkl5Nn)_2uT_YjE_|5Y8^fX94qNY;0$27nYDRPh;|&%hs(yf z0vLk(8Ba@EWM+?~_zUAd94T*)l%=hJq^ZEtjN*epqnYjOqFo~}1rKp8H?!9yT@EY` z&(ra+*I-~Dz6n}uW-XG&S zs1f)j{?@Jvc_Z;H?PLyJKKto+VU^N4oJoK`;In<;4wa5nDjJb^2y6=t?a(wTGySDJA1^#H!# z7*W#Aj_`Y2N#3Kt1^5zsDp;zCz(zA$pOEJeO6h<;k+ObS1(MFgP0}EI*Ebor+h37% zH1G%x?owQs3vj_s#{szyn1Q>+bAiu?{HD-u34T@xZYGz|>338_sTuHUr0nQO*--qg z?gBmr{2h1-cn&xT_dDcdJ$jG682qRVrEqj2Bi ziIBGt_$2OQBt5P#)c~xavk^WH0Po1v zSA_##k^sPf`E>x`o&*oY+z|?cFU|qN*D2th5N@?@PmJ9L3@H+TA$Uwa1;XR_m6=)z z|7PI99OKTZsNZffb20H-S{-RG9U<)iCu@(w7!H(kuA+;P|{s z5?8t(!adPEW2^=GS1L!fm!+HV1C7}EVL5FH%x*79yYXo6(2&Le&sO}3?Dh)y zaH_%DoJjE>NW{__;KXk8Uo8Lugty@V&Uy%g1bN<|oc~Gw z|C>;@T;`@=Ln1;x5+WrMsEHwx?z4!CvaP%5F%`BO7u%40^-QvbN>PHr*idg!-IdVf$)!yw1?Hl z3H2ZqHdL(j^&pH9rd1(00f^GAWu#?{$0UvrL{;VMcjRN-Ljj`Erhl0+|1-v0q zKp-Rx2!RBF2mzqB$4P5>L43i>54=9!2ZJr^3Go5tKBk^0t?mJ)-rxnkB40=d*xcYv z7|8u}bIgJT08lje7!G5B-p0owC|1cLX+f*;e5rSkh!N`J7# z$E6MgYY+t52?J{s1?J}h|JCpR-}N&)8LzO2kY6D*R!MDXYPjz+5p^Ez1IKhQ;)?z) zTY41ulU6;yl7Naj$zSNK>{vOudx7#L8#?JYFO&DgVUXY30Us)0zu;Sg86UmK37sDU zpYQ$2rUn(Z<-d?8odSRl*qL2*5FYBpwUHV!@tJTONM%rW?bjR)529XySZzk85> zxLOwUab=eQp!Q328wgf-;%)W3aOaehs;T+=`+V|u5U}tYXCM$_TtXO%^W+$3ziyi6 zV09r7l5iUjPdNiWC5>clZFg;UU!6brO8}4!fzaf7r$rh0SC-+2GrQMRM$@`|Vq<~u zpid`Ng4k17S=@}lwx>2yO63U*{>0}7`M1E71`{6zlLd{2jEn~F3@-9#cp;E)4uMc+ zXy3c<=&h1{t;o{PsY3A2)&%*XVDXI;7~F*QZ@XjUX?TR@{mF*`o2L*0fxE?r%0OUB zehL1%5g#KX;h*&z0f4Tr>&zV&7sv4Fz6t;~QNQ8`gP{1I?xVqb>#z9F0ATQsdtQ+L z7WNby9em@_pPza`fg7jzabS+Z=O+d5Y5B?*Y~CXPc=^TH$O8pF7=C^fp8g>+({TBrQ@<1mw1H?hbfMm!pkOAof@*tf+5u^<$g|q+_ zkS3rC(f~Yx)B<&oCt%2}0-i!Dfrp@HN`O>=dg0(z2E;&O!EsmuzKR6!DgvS)$>3E0 zUa3GNm_|S{!7C5EvcW3{ymCQLl>=V+;FSelg@!D zH1P5~nW1=`Ol|&{!GNyw*lmV_V4){dmyZG-ALl)vB|<^R_!kl$CsJV`Ga08PlneY3D5w8)czoU4}e0YlK{t5Xb>M=hNH0*o2 z$ey2z9dRNMaxw!vVV=|$ax(w(1YceV7#_S&8tYVpHJn5|2xJsY-+#J}V~WSg<^E~% z81Sh)?k9Q2^TFg3xf3Hkf3~0dXGxC}7?9x&);ahjpnk0H$5Mlg(~`%`(6(fP7u-%RX5&*SqT_|zXf zK6hiU6YE}|1dm^;_s2f>(Lwlpg7^B2;(pRdKA);`%nt+|PB0jNKK2OD&tv3IUcets z@BU{aeOZJ*q&&YU+L!lHC;Y%qi!F~&sXM6m#{kIuRQ%&od45X2=6~71$AdN=bO!Zc zdffQmrorG#429Hz>G8Oz{p1^JKRJ<_&uK8|bV5Ow{?Thye~})$z{g;k@;MEIJUa2N zVW1lh0o`yIr2Le74hLO-=!yF-I&tF>pvwY zZ_^;tKSe)N2>cUT<@;ywL_NSiqivag0)OcT9dCD{wS8n^|L;UTX#PID?ABixT`!Gr z)D)%1`eXN;OewJ8ul&Q2_3y$+it}?tHH{Wmo=M15UpD zd%@{Q;&Q7tQ!amNXHn@V6s2B&t5^g5tMCY2-&!g8xw94U z&L6%}z5T2Bk>9!!?Vnb@y7tW|iGM+ze&TEO3AA5B4keb5L_oGl&em5U^v8da-#fE14R7XBIm18TYSt;29l3Y zZUO)eWCEDSgh0fBVF)t-;8ScKAGUi4bi)3q0XlyQKl!v$KkRq#f%rf1A*R4KnJ}>T zolc6ee#+DV>QBI9e--rwA>YG4;`tLFsurjk`F@1SJ8etsC-5CktK>kwhyM_G3HKQv zavrSa3z+X2(>ZO-^T+VeU-?bC@8S#A1GoRghdclP#qV0fKRRWs?#KAjf7NA@{=la` z#;4iaHvNo$aS!Y!-#?Std3r(ghb~a3$L_62RWM#OhZoa5l4VO@STAbd=uc{yS6cyPZ7qC@P$v8 zx8jQl*${9z29{3yBmQwqe8i{Q1w$Kj3o!I=e9d(`jj#Fziy-dZ(bkLO8EEbBab52X zKZ4K<51&mL&IcnK{m`)KzkpwTdYSXpM-2G?>(5&-r|0}B|Ld=cY`;5Y`IpG@H2#-o zypb?KI&pI7$9E_n^H3mg7$;N1GZ^p)7@r7yKse!@2%juH&T!NJ%*#9NulK%m7jY-6 z`6e)if1KEjX+a?2KruuW0E9ty1EB5nhaRLAob84KtH-OZUC>`b&ewx}a8~Qb__L?* z+aag$=N~_r0`|y3lO2z%7LP;FC;Zn4C;0lq!?VD_@bK^_{FB&mj8D1(%#{oQfX0vD zFPv`vxYPK>5D07sxR~Ar#KE3A33|Lw_{Tef4abfFq7BR)%YMQKBtGI70BvZ;jWzU( zGcWyb@F8j7B<2Jk(gB!#!k^sUqxl~GFffjMjF0*;h@+`qhxq}%>uG$})A)^C+}fL< zOWFk@jf|6kagtB?txiD0_wd7ufq-LtcHj^m0w)L3*&pDCpMu|qhkV`t0H6~3Q~v`# z_rF%Smw?Xq@QF7+Fo5`iz#bF?qj|n!v;PH1q0znSQ1uzd+ko9Bc@k9_` z@bd8ks~`!;yKwAx1qF|P>4bdQNDduU@CVZm=)+U^G5_o6gLQiN`~0u*DNp0u|F7{m zPve`N<}xRDcV`Mi2$GVI*RjOO$s7>2l%B3k0SI#PClV6+bi;a_b-W(E0H(-4i+|-b z{^_4^3G4#zSC4ynE-(al{F}i6IMIDz2^>{7F#gamGWz3F!*Q0^r}-qt&*EP?jqiVo z`55qrg7yO5LWnj22M9j^2tjJW5D4uJ48w|xi|+#-;^M?cz`Xb|;U43UfLeXOf=_W8 zKlT*!CEx=M!L+i31y_h0=X-!G2xJiOhK68USwf#Uh2zgFM!>|Uc|QQIPcA{Ifcam* z|Em9Io??0fz+9^4@yLf81SWxX!s8_oFq5o-^~ouH#9#9V$?+IJ4hRO9CQ-kD4}J7E z{twpc_?zUG-ls*1?QxdR@z&Iq?w9xS^zDy7 zXQ3I>7S<{+!@35go&l zgEmNi3BTqP{^lv3E&yyy908?JpYe~g*1@bosIT8YV08l90yIN@3ID6lHDsrl+{rIq zRvMfv2{f~vK4(4BJ?RRm*_Xh-BH15F0y#Sy8KRJ_06Dq&S&IL?52pVb1)Ror|6k)9 ze6@l8zs6_&YR}|fFo~mjim3j6`Tx~^E5<*^zkb@H!rx0bot75(=lCwCE&gEpGWf5) zzWp|x{+hh~gMCPq)A;%S9RK-Wujs!+=TGDBp#5X~(_7*Xe@z_F`ls+{r|tdlC_w3H z`Ko`4FL>IX=#S*@oR&Yp{fGD=r|seYNM029+d23z)5z)l`ya}~FZ|w~*AMO5Z2a(`(Q#{uhhiq0|2K!_OQHEdQzpUi=5}WT#J~Jo*_Osjpr@ z^*_K*{0(pN^#&C1`v<5fPH(2{qW_eZ)7N|dzkP@<`M0JsID20ez~*;9Cmj6sX3F1D z#@7d5e$xqlWoHZJC-u0$K7G-K`aAGyUs<{L)0*ELIjsMUtu3an=5lK|Kdnmo&B3$s zU+#lgV_%tY`~_vtZ%!X&|Kb5I=*M55Kl+s>M4tSn0Kaw!1L~XOTQ`15U+n1H0-*dt z`3t_*ZvDjr*}mVNetYxNvvI;J`p z-a0di?^d19|9j}bf#mPTPp7{;)I1Vpu6UX3PnUv9p^^Pp$JC8~fBvHX;qQ-MFAvnD zr9JMP-1!@skbg3N6kYp=$IlO3{@E`8R-_&K3}x`4yZ{s-_4_>g~2DoekKe&h=S z`8No!__yHSOG5rF5^nqTA71$3LHlwD_VVqF)^CU8_Ed>2`~UDake8Hn%^W;}q5~ZD z6a*R0AwmA5|L8yZMKZp{%mslMz5;L0n8=Zmq9Xep@0Oi4uyeLDv0^1Xmid&*f~gUh z;u;(2*?=oN$jJqZfN(OwLBC~bX7h2XbG&IneoIf^0P@itKtW*skcL1*j(sD{C$qNz zSwJ4b3W0n!_vZrg^fN316x8Q`fCA)rJply;2MY^<0@NYcq;jgN+JF30m6KBi^dOiJ zC@CFN9X)#n2X;nQMiw9(aSFyBZrbd6Vc85UOp@9P%DvX z68-h<>r{uv2Rn@u0^?=l0=4y~*y6dUOWY=*EfZk^m;4X<8VJ4b>A9*dTzBtXp4aH+ zdZoMU@jjs-Cwq4k2`Tj5F!2M>u<+3GQ`mmY(%F6PEU z4qln?n_I(Lg-foDy$j^fCc#W-H*a3MdLfa(74z0@pCoob-UXL)d6`N?2=w>T@z%n(eKrV%UDg?fBJ7*Y&p-mqGC z_m+tOflEeiNDzW{iP@)ViRw8~7v8IHF6VP3m7Am{Cd2Q$uD01+Uk|EdcHyxYS&J7ca0_`J~^M*a3_X!@ZA&t_R`hs@9Cs&G~7vDgVW0GsAy_o zthQuU6nwet@1!iyaZ!8R5p`xD>&!*ZBCV^*m6Q6ft!PyOLMBnY-*|tT&4y zdfi^CnLcvSnvQ!NO#Y!iZG1uIUBm*>xhv8-W``Jy$|=^o`r%}{Q3*^%)mjC0&y*!i ztdIqfo{zRnk{EjG)V4?MF?A~<%o2Ox+V+v(lXw+RVTyGg4=?1g>J^3qWTWR7thHA- zuWXSh=Al@_sB^!TV`}w2R5QrR-#}8p2b|Zj?iQ*y_Z?>f>0jo(X0m>sC61j3=k35$ncnr#G+1gdcB(o`p~m3erCJ|P!nc1)XO9v`e-%x8O^(V{T7Dy+&?N|^55;tIxTT)fAyHJCM8;%T4z zDsWBCqMIUS>rf@so(6ux{Z(hHeC{~%9WE?wTg-ydP3?wrO$`{sIwKyg#-OMm|ugp0FXmb>@ zbDQ0IUC8>r>45%>JDpBFL4aSi+z|yu&V|5)xv@K@X$Ym<5{QOSb2sCBtcXp+I4`3M zY2Q6}15iec$h9Mn#2eEV=Qg8smQK5h270WnfuzK;^NFRdA`uk^`O&6SWTfw^r-)T> zP_b-k~LbGivhZ~s1Np+JmiQ4uT!z%kshms;yNvqBMa(6 zeCgu==$wK_LQJKIMxJw{jCF=m9Vm%KIZTcJve=M} zFy!ezi|es0Myg5Uzb;77=X?E5Z^CFRTJJY2Sc-+!^0zTK z`H38A!>FP*W`slxkan0lavR8|U&xtvIA|8B(Qa6Uk7^n|YOTXo$fbBW`l^53M+1<1 z(k#nDpmIy8p?{a z&2Bu6eoFEHhL_#HJeL^E~Mq$q$!bEakysyZN>K>VseuF zLue7N9Kkr>TM^;;eT7V{m4>~5=ad5VD{*dTBP5<9i^Wzvx}!pPaWLiSnLQ+~H5g53 zvv*e*fpcjRuZeul52c1N=V`QSm1svu8r3s>;Eo$)6fnam4=}8bdxXk|(Ij7Ojxc|F z=P(xuFj14PD5&6aeQYTXf7=m$miJ&9TA)A|edj(F6;G~I#l)eDu*|aCc8Q_pnIh34 zbK9XEw;fce4HY`&w~3@E-Q8K-dz)?NlVnJ1V`5HOnQgh!j-%_QW?Z9&trmrM zsnm##{46&Qv1nzRm7x%Z2OmV`D})|h>}FujD&u}389Khq`ZP@`xdD!wj2&^chU7@G zo-tj7l_amlr#*=Hb^lGP7+uPE&gCSu88KGkA{3dii-f_R9jkE2IRcon2~SJ1W5U@q z4&LI^ZkDwqKe}BczM@E!Vtp^;VJrL01YbKm$5x`pMS03ctsV;_#P8L|L(Ak0XJE<2 zCDhwtOJFX-jY={;y$&Gfij^~56*#A)K&PLK)7PIey<^bvxE}^uW3w`Zywe{SW67B6 z^*-O5M@Oi)<2CNnpH<2C7`vSPF!Eq@-W3|X;LflDmd#bQ&i7Xt1)2)w>1z>FcX&z49RTO2C*){BnCbd`PW#=R>r1c-s?Uu=A zX?F2<>SgrklP$=d50)3DU_T#QhCX2uIT2b{fU{ADD_Xb38HZk)@#@+VIfHmwllb(Q z1K#Tkw3v5^{Nmo1h27ooOo{Rn4UVJK$Z35IbtwDcP59zicbQ<0Nwc)yV_vt7>6u_R zOu{K-hl1MkBE#Wo^I>bO(R#5;2v+j_gd$jn4#NV(#sQd`_V^lZkA^+YNzHKGz9>-? zoV*z~9)>0B^Z<2fQp@0#BRec2u_^m(8Ph^}PC-Omq0F}=*)&1e%i;BW2o+EhEP^O_{o7;Wt;GHP#dP3;X7I%Fr^i{#@p zt`)+sL}pl1p!r(Kh|G&1{No4sZvga>=nsv^&K2g^N0J@qcWa}ZIum7jcY;WFlJBZ` zoHwEEYlcTuwL|38P`QUB9(+Sgs&qC#km#PHImv@+JUfHA#f}0S8z$~}b1PD<$2U-` z`R#MU$vyY6W`>#6RG3hzIChdS6rFK#DO*_MWi5ld&MCfnpN`0Wm=O}scNZ5YMv&h( zZJ@F9emFU0ti&}rIO>DB3{(`BZbT>**F~xa?yVW30nfd1Y!l1|*=>Y~U6-P$9tFo= z+_)KbDO>@@s&D;?hvGIK0o6+}f+2*v;=W76J*5$%1m)z*RfRX{2aCNGk}m}n=BNn2 z;ur3#J9>cU-}bKf>LuX<)K$(Qm<{?%`JOFWYA~6C`7amVOXYJ_ z#=d_O-O#5r12Z}vJ1ofUR zP|FHmzol4#WopbPijW_)RDRaOy<3&QuIpwmBRL91Gb6!H7J1eC+y7 z!x`ZyGH$Bnq4DqiQWtnJIN)!3KCfgOaZ9{w>_6Upqz}tLrL(6ScsET-@SrC z^HPS51HM@EZBE1op*Mvc^8DzMOdDwNN6o!DZ@W5W;%SuixbNbK>cU=;#GKw(;Z@Lr zrGJg_+W48CKjw_-8R^l-mH}`Ebsl?XFB+298Bm=+>%TphFps`WOgJ31TFDX7mZ9=Q z$$!))-Rco^;MLBONm6uSOw2(oLw~VnY^^!lRe`YXxUeLb)11V^(RvlDOXR<6igY2iLKm@<4JkAZ82!>-{Jr~@yzVepR+!=dh;#|Gmpeu zEiVZ_DXC3_waMn!$qJ%Vfm1Zq<8rC`jN^mh*a2O%!v4+A$s%Fwi*HX)+7I(yje15% z9l_=`W1Hwjz;y$~SL-=-^~7ZairRVhk=<7X7Y<3q0b}2b4ww+JwZ2GCNKXktZO-$1 z7IV0^-Q=vhP2pbdg=gG@Z(%E&SgPn;#2MF7q{$d#o$jXJ&(yf8r_p|GC{;d#?h=!G z_tL{DKZYj6v7$iD={6MH^!Z}WsNg|cNj1N#iTkgS+HQvO_~8|VZVGUb^J~wZF>N7q z&A(YFK~tLv>Fv3?MbERyUDBffWvUGkYt1h75@y{x(!$``Y9pDiw(}ie-L_Vh{BtI*}4rSDo(oUNN~R63NSJZIHE9f~*#6EJ~1I*)1T@+fPbuk=vi zcAgRS;s6yc>+>DBVwUr;Hv;OyBm#9xT~JpmeJ6PzhP)pgp{*k+O9~4%6~5l{P?L$K zHq?_%F?_=#iFW|5gTk;M%0Tq!n)uf4D+g?2_vk2bjgs6sE9R8p!owFU3B~jG+4`d= zh;p3R)l;-KngZTk!;6x?md8^gZ9qE1h@TsR5Ld$dPE2L<{Qa|uFS8k58#a=;U0)q% zA$nFPAw^$fJnvB5Fa1WYAkpjX2FoK0?$$Xs(fupAy}~!T!>(P%c4{}2L07vT(sI~d z@9fH%5Qn^w`MjM!vY_VRUE2jGJg5gvhutE3%7+(}?KU&x6x?xG-WPJ*#ns4+bZq5c zpD=XHqg8aSH;gB&cw>KQ>zp<*(k)C9+n}~woM)?O=E7%lYI8^op+^Lb;Q|Xr%bR!V zRAhr1_#_)I83|AiPfX*jF7s|)R>X0GfwdZvgwS^wMx$TU7CHdV4yzOpHE=Wv=s8wm z$fhk$G9Ki=a*jk}^I4mI1S11KKWES;Z|CyhK%h)?GT~m2;~<@HBl3IGc728FEA{8Pxq6FP~TC9BbMM^cXnC%tj9AiqJyMv@u4!y+{C9ivpqG# zVV>PgnR;eDVr|U#*@3%VrCT2>sYv9r-i}eHfeSZnDJb=$7l?4;l%8LY<#%}>v}dp7 z0gZ9yVeA{D^0_M1fb02=&G++Zzs&hp_Nz{f_ho+8bSq$9?r>NAvL7aSGr#ku8>S(oi5!AtLeDwd+D;}N~qVV3K(MC+&XJ{WQ3(=n;8Q+FL6u} z>qEbl_Fr$td*gVJT*Gb9g58w-Vna;`jj2Rx6>Scn2VexX-zpy(Sk6_-0eT7(k<)Wi z*cO{|Wwfr{7I9Zo(CywHRl;ut+Oc0r$J8LNN|fNzbSvl5fmzrPCzF7kit>#%zyI$W z#zF^QyTe`)d67-0ynO}k#@iSbM{fDLNU(2Lcvg!2XIXG@kySSsrYmPF>Fy8V<{__^Z#(IcD7W0G}mC7Ml4)4vItQ zsAgZ(wVlWS1)AxM_v5R^ zC|wf{B|`7<=zhGod{rbjy;HNnV~y3>Y5(;g3Jafsi=~OLF|j~*_n@zvTXEFJ7Vor@ z(S|EttQ_@DeY|F6naRe$)3eRjtnLJen%#P7-Osm7IBlj|Qg$nabJ|xH@q^>L>n=o< zPAaWag&Bi5SOfR%<%L`*FoH8C`|gKuS|%Tw*Y)`g)mi4btL@j}z$#nZ;7c+>OBb(W z@x9Ybdx$eUj*3(&Q%#aFSZ-+_Ev$g6QE%oy{|wn$3{R{{G>{kBt<dsACy*WW< zoM(x^f5dCjkV!X+ooC=LHR2y3Ww(qcrX(AS*SGb<{xTd2_o&T#lX$HjJS`n?J(6 zWaT_?)^DU17r!q}%Xh|rFnMtnd*Bjhd-tB~>%Joar(3?ACW(Fx09t5@>X`~2b=qoV zpJ0C1+Gqx9xLZY!KU}gv(lx6$?@y{yz;=8rDSMycT@C%}2F4}(3OPnYByMuDwJO&# zoO)|Fmf8a(bhIkY@!^|uI*Ksx!kt^IIa%)u%lVin7u|eJC?Xt3x*Ge@OIfXDdaPDk zAKa)If$vqs98%D6ahqR#s0hkFoLG-BX4w!=)b5T)#EYe8SjZpM%V87Ij`gOaxBe zdnvz9sl<5x!e&5=<1<2ufH`G!WHGf@Zt_SoiI|bJhs)`GWUtE|>YP%mIBgez$N_Jl&y+~)iZB9u}a_C^Vmt0$UArpgAZ8N%vA&s7_0?@aQTtk{#6ufSQr^xSn4<8AY0 zXAWsnH^&U2>qaDkD6T<6w=T1Bak?hUu54W2D4vpz&_WnV_bEe zrHNLMiQ@V7jmxrkZt%KHS=CGOx8Xl8JkyjvgTT^-3au=8vEG`=@38=>y+G69T0{;~ z%K5oQA?>)7#GAJ~Fte-{2`-g0x6n8{}un z5y=|0Y_w&2(YY$GnF$1lrom;u$RNOMZ0n5<$Yswjpmn^5oG~JN6@oiiy!PCVo=n~t zW=U{_va0dCmkCvqD=xLyBnQpb_84VC_eR9kXDlS`2yaMk;96?w?U$NMz#ZvF!fXi3 zJ@>%Kd{rAE5Y_6a>!t3K^%lEk9L*bvk$YDkYgcTRTw(RK6wxwDO~|FvCrILYCHUOA zIC4D6_B;tHS4DJ6mdfjJl8wp{BCd`u%)8D!ze%g{@ay%kznDq7`CO0)|( zR)|W}Io85YYLs5aWdeL{<EhOb=HdI`|~%mhb=MGcw3*2mdB8X4Tc*R z(ghcLkV13o2?|jXN%3%#<2_;44?vca%^)L)U2@Ti?S8jD9mhc0Zcbp@h^yGLYdoZ| z;wQy~d{Inc#6)5z6XL5W=`h@S`E_F5rV?yksrs5P@AanXx9J_K4=802`)$Lf70(o0 zj^c7sA)SGg_u}t}lQ64RDm2V(k~>`OH3?K`rZ^MK-x+d){atJcKBPZKgj;(#CC$de z6HuEi=e(Rfs5Ry`;}z*c(kOa|tXB0p%stH)8sRWN(9W4BS^+**O&C*kOvY>&k=bLsSSQ z*bHknT0APW@zdu?MDH{m=GU-3tcS)qBlD7oHO6x%AKQbrylZ8V@lt~4&i2K-Y7x8b zdjgZ;NkUCHb*5dxt}hXD+dI|qCAfk|=_V3f2GVDOZ!toMclv}WuwqrOsiON8ppsN4 zY*Y=NKYJ@mZe{c8)Kju??*@k@%9jfSj4o`AMu=18dP?Q!ZBw4Sk9AEEUtPPh@RWI> zTdneCVEH5)g4lY;*`l?9^gt5d5XMx5Cmd)CIDPjgahSRkZivP;1uVJ=>55W>&2{RK z>|T;OjN(PuOb~Eoc@RIFzpaZAQTWDo`dMu>wQ|B^gzi%8V10I+;rwd<7t|qT!~<{p z&ssn9jjig6aMHr$7eFONtSs<1pXPsF2212QUC#cDM>s1znt~#->k$mLH=F_muGn>0 z4W18S8{F#SuaH)6$O_0-+pTseNp1UIl%8Ig&7*v;vE%X{iGW}$42@nO zBq|IQbGCEjk>nZG6tx~Pm?09{K-m;KqsMsNclvN^D>x=n{S3!g8ZI)9NBLB>m|HrX z&&l9o$B}k=$M}lUD6Em+kGkNd=vdn12dC)5}UjoNPF;t!<(F_(ErFyvH2bJfY; zd`RbH2%NKh^yZGQ{v3=6GZv$}E)Uv;#-~s4gFj%WWbKNav8wH(>yd3Dr@t%fgwO5W zn9;xAg(M{LCN?#`Qlfz&t1j5+;Th#ou~p(r8Yn3DYG!4`hwUEL)xS`(jSIATID=b~ zR5W(pjO|%LG8S3?1Jc4YH$_-=$0Ty3ZMQZ2exoLBxCS{|-$pIhA@B2~-a5}nH@T>l z2UgSyT7(#i-L4!;3SUpc?(m^E`{pF z+PQtUbF(z?xPg+jPlFGb(-Q;Yuh29`rVBcd9ptC3Hon~zd`~+Kg-C3!I?balAQHjQ zw6obOhwQ3MBd1WE)9x8Ra?^QcOg<_@QNBVb{5iVSqwB~(d;TKjTKez3Ft4k#Bpcn z$i3W&C5sftd{`%XpbQ7q9LtbP2mNF6Fi^VECqxOn|~_n@S&?&x2`^Vz%6y-3JT*4so#6^8l1 zi?M?zO;FzIY!{=w;JLoqG2I;FX@qA%cX8WC&Y2?5QQql@)abmC8S7?CWxGe$qd6X- z?*X^lY(!dvwK9xZj&h9pR!2P~K}&D6#M8JIh_y zocCskQ}lsRC6!B%K^HFP6naT?_2sk*(=2X-he6$rHC9xDfgJY8*1ZrUu6m8F^OmZp zR(5?_s|iJYhk;nt>eGO;^M)xZ#^_BPI(}N=EQP%_`ZVBb6x0)RnjzJ42RHnuu~&t$ zEUvLR@EeE<$@os0P|U=4C>uoCU>A*T^e1PV;V`t$4fA&`M@Qn8v=w9M-tYFtQJ{}# zBh+VmHA#z4ki;Pj3jU+vMG{oC@Z7D`$v6(eOJ1!en z+wo~tLuwTHE+yycj6{(mQf&xySRuh}%roVQ$9r&e`MWp8li|597 z#pf3QksDbLH^T%P>*Wm#U$tDht-@9?ljwo;g_W97IPXE7wZG8*Bn0#*;X#W)Yv8DPZHXP?gu~#_luL&spb|sZ7jP$`NWt!LM`BCQAa~WwOJq3 zMPiyS))(1wjSUVtFn{a6^`w+i8tO(PAi@$F8*&(%3?;bPcEJATnxTQdM z0qI%XX)NJV0W>j6Txj~;d7@P7r{xIcxJNYd@6&2TXuH_<|?0xhK2ILO~PlH(58Zg=wsqI@3`3B+LCEb%kb#y%wV<0dcO@U zwJM%)8FpsrC^udr%WXHBL2c<;_ z!Y$k9%F&p0#nmEiEzxxS59s{gp35MMnS2AMfd7J){m`?^$aMuT+4sO6iHyKM1mlB_ z$$b*Fhm?7)2RiYF+Yv$XHKxkj+aWJHV@S~&xg?0*2eW0>wYU@@iG{UIc$XAgT8~ar zoh$S;Vwme0;Z1Pb?2S|9Bi@72!86+w#d$&OpyS?U+%U20eMYOoTHoe9tB?3?x^CyN zy09CKW7Kh>JG<>i73u=+>Tn30?b=U;b;16xT$+wtlBhQrb@S*AV-jVhPIBMF1a>I3 zSuREf>OIB%?0Vtqpv=P8M@NcQ#60oDsjc|lJx`85xDVjExus$5-ZpUGIDflPztOc0 zIe?)IXT19XkB$mCO5D3Xx<|&PH6oTkdHY#~7x-{l+xr?WUg?oSZKDk(AN^pCCgbOu>=bG-F+s*C5 zrMQYX;Vj;PV>a77;V+{rDr54;(&Rs&VF(}{q9NK!Px?^0IAXZJh;_I(O@8)HZqb$5 z@_@JOhBlG|j4e%qS9xzqyy9ai#J+H+(C3i>6XH#>EBj^b!?`GucDWe$=g$RTX@?T@ z&SS(N<@T%(?cNJ&+PXlTSCfdnBmYJNB5ieh{Vd)o1SxNA6?0TlbnrQMSAV(mhsTk2gZ z7Y^Om(YGHvG7ZhUieh+l$XDCD@-9j=(?8FGB~z7ljod;5Y*q)^^rvv2)ybc?yvKH1 z?1j;V`Kv)>!m*c-Jj@orTGw#osD*$j5eCXGj4#7U-kQs5I_A1ob5IG1(U`_B7qjDj;01zCb} zsq0ZlI9XV)Vl$)Eo%*ra$XjA=0+5aoH%fC+{6sFPn}lg9TZ28_qEwtOMXv?kncIJH zpUT9)k%x-zwhS#zIy3%@&?CPd@)w~TKGEsTNH1I7taC%ShG#*`%r(;TN>L2M{RQ{VXi+uTkyeNo zCu(T1xk{lv*r%RBqe!{F!ZrApeQQE;)TV~y>cRA=wszh&Guj?Uoajf#$MxlXlX zYJ4d{)oG-cdGpFyBQGR!wrLV+ruuW8uy#&p1p{2vuh&B*1r+twZH3-O-atkV(d?zW zZg43pBQ8aTSg6_vO}UAjFVUPvlZRGb6xNz~ga&7CI^X&MBL;k*EetmHaFV%}=jdl8Nc5%zx6IyvOC z#$L`zik8jzl?IQR-kDGECJBjWHEo=kim`f8ZswS6M;!oz1sgx5lAOt|%>DWe&am}M z*hE~)g=JKfi2?V=HTd4hu-6P*LKjdH^@wRJuDZ-^tH;wFo{QEsu34{qj$hac7@KNa zLp8%WBP5|n_$;XxZ{NP{uwJeAKESU`Z89;Gu54q?jpO1dsh?eW~svB;28cmgFrcB z_%2ZpAi_(yL6fGpEJ!^D6_~MZbhoDCvSmb)$(jVIjaft8{OA!@jK?$l-bM3^&CzxN z&yjGn1Q1^=>6dYiU^kDXQ!OdVkBi4vFAh@$BqQ3Ix547#CdsZcR0jAx-73xZPK3$I zfDRX?UWinobr7_(<=Y~>pcc7)zb@O+gvvGG`gxPgW;U%Sg70x!%eC)TGLE&W=}bl? zY~TY7hK_4DR3G9W)v@{p;5=6D)Zbo>n<~=5ajlDL0vcd{`x+aUidvm{U z&+d8NjTKh?Yx$@{XT9Xe&uPm8tf*Y29^_nEd6U6OxSDwdy2Q&EUcz^_Jucbg_A;-@ zjVw!ebIPDau22Xtl_K)vcRj_!pG`s-fLf3CMG17H3Ng=U5xhY^WY{)C7>di)VwH1E z#=g?5^Q~~!j@z?%N$Q{kD=2w;9ajE(r11^S>Vo9t^T`M?vsD{IZ(2tEt)4J;T_w$^ zSGGSS@tJ;|&S_GgULH(+tr8b^RG^BZGYjfkpLi1yMg2g!kuIlU_yNG;&Vf%q&@29= zR9e=_BF)Fvc;zvJs@ygoWI-{`!=>bwlx)%+ZNV6>nnfNvWuoXr`@0Z4wwQKm*Iy$q-I%Y z9z6lQ>3Ahg7hxi&njG+!E1sVlV?<|0`~b`R1dgy;zIW1QFC6|U|BW&^T<&}7xAJ6h z&n73RA=2J-sC9bh;fJ5rZA~KeQfV;SAtGqgViLDc6We@#aQ@+H7xw;o@Vh9LK1+Iu zNhu|VcSDyumK3o72hF-_L!`M#vP^#2+e{j3n6n~je+yTj{WnD#&L2T)v+nZNq^wPXh?pP>Zabi0-ONvX*BZ7N*qpK(;T2+!hTb4U! zVFmxKA}@n4wkVE%SQ=&J5OEo13j+>!?tBz&rgZF=hnm5+reJpal6$J#vw2?GGzfganoZQHhO{$ty= zZQHhO+qUhQ+}uhkmE9~WkKI-0ymr5RfiE0OgH}|srK47#hv&n89#;`PTNMOu0-5X# zZV*}}Q0a-SlR>B9C*_hfq5t5ycHHiV88jPvAlxl?0Ax ziUPATOhSw9>VvY7pRdo5letel6^QH;|1n0)eDE+l`6#8u-mo@iD>|WVd6V~)F#)Rn z@^>x{p+e^v{K+e!Xyti5{n*RkJJX5a@@M81_dDt7vj7o?vt9-DD@*>1D3(Ryfu&u4 zmD?u)Bp=wjVMa#A@76WZ%>^&_RUabzRwejzMaO)yD-nF);NJikUzCPN7wt#s^%>&~ z{@m%e>Uc5fM=6_2aK114t~sCGl!&&w2z4_I2Ytx7Io};Z+PwE5V(-UtDJ9{%Ww-NU z01EL%<84~JE)ccYjnh9`;s3OwEt}TKVu)JfZQzI&4aSPN6I7HnNWH!mT%1(d(?FC! zfLo|O+z7vd>Tz=1$kDI~aD38R^!R$k;4zoT=BMY?S$!4g&}4{j)fpJGhkzjrI`weh zqkL3^t8N@tR=T=BFZy_X^Tk&8#n#Ll%Ev!g0>5AHJ80qf#rpHb7XD`0dpCc-i9l0_ z5`kfuH0Vmkh$V?*EVkv4c|~#n+fM9mil7$o0X0<&FUH@eA{>!dnoD4>IG?f0w_p0j zLKj#+l%i#)76qUB)*&NS0dJ|I{@9<+>YgK6GZ$;#@bN*h=`B?r1@kJVBzcRxHEwt0 zlIT0Y8=0K8*O*M zY5NUT!qt|3QYDIzG1Z+pPiCQBcblp#G&yKcy=a)+H%U_A0@g-Zo)e7gb@^a77-vUW zvLw0tM=Ak0Z<<{|RkKE=OvE-!=v0A?qFJ<+K=W7?92jB|BHhCnzdVt*TkOWia zKhB@xtMpWC+!>}JBi1X~!vk;(Dd8&}B4CgIJtIL=T}&mJ-)}rGeIN`RAyXLMhsW3u zW#+sSiv3Puyibq-^M1v)MV0-DN9^I8Zbot_ zyRYhgsm7Jrx&}hd^Lf|O3g!;E0slfBPXdSqV6(v}?L^X}W7KG78=QLjEzQeDhJ>-( zi5`?`Y^zU50OX!rR1dFW&Y~;u57yHJf>=DZ7>rTvUE}|Y1Z*WLjzl1f|0aX}a}Atu zte10olEi1XRc8+;O1SP45CK%Sxbi%}_)Bsco3X3aq_mZN9v2e+2BScMo~)yF3!;n1 zmHt+<2$454C3v|@L{$vLYDy2ZzR8Nt#7P)DSz}a*u4Qbe zm=8oR!>q#=@0h#z^X##FIF^IF-0W~%CxPEh zG4NbxW_|+8;(_c)h9y|QA1S9lq6bZ@aFS+6oH4+|F1ou04_@+Y>3eulAxX$XLo+ZguV`PA+lKq!B z!vBw~c|aspQrISkzy5pYjouHPULB<%R3+3FKyF^ce6{W%Qb!Y7q^lhA`tT*~^v9i! z5I3*`bmpe?j7UlZ_t;Wu*By0yZ{?XWgyqcFIZ$N=GmdA%-zr^5N z3iFZt9yP-L*XH&VbI~JbOP$o0mxN8|A0?d6kCQ9x(X2)L2zm5=60mIyrUi%nG7F=7 zP`D90Wq*PGZ#q9sc9A`_BZbf_fqSeE1LoyferRBfQQFd?|E99Hip4!p>2E<| z+I_>3MZ&Op0e|Ewn)QTFs^o3aN5m^nq%}}edBIB(D2{}HHg_OaeHg(30oyZqx=N8u zr>_^uo8tHI7oI2^pysl|=R{yE2?1@+0IY^^ynQ^jC-O9v!V2lfb<&Rb6Y{kO$~vf- zqVN?N6i2*&s~ZTbA)Mf#fX%r)LkZ*$s(wkV$5HqM$Gr`d!>o#HmGau#z{L41^c7+V zmHRT3h<1T#(z_H+jN*fv&XcwE4ppXnSdYrRZ*zdq7SY-Lt>}kZiT2wfIxrobg9(Pi zXYRE&t_iy<&aDg{WHbKIhmcgRhDVilHmIOu@Rsgd?=%9e8nu}_z~E>e;yPT6|FMef z9!AO~@6ZEg3zm#Jz7j=tR_Z6*lR<)m6fPR{wS_{ER1PoPMxopdKfu)MP$mqKsG-Hj z>-JWc76Vv*B~zzKNI?Viog2lL@{oS~H*cbT77ox4F#bxZ4}gh+c}vUv6Nm(V?w!nX zKi36k`di@_jcrNGyrq_VPrCONZ20HC2S`uFjqS#2?Khl%COJHKHCoS@_kH8C^KKAC+C4Zy^NkN@u-eq207-%bE$*QP z+=WX@Q2|L#=8khqiMNGTOh4M#tI; zdbOE1%*@?~c|0Z3hPb+~)4?$n(xt>AVKd}j!uZ#lxMQcur)8N|m>Be73JfUH* z=flIz%0F6%>drr`yfUT7KlZ)2VowR7tL#rvh9GAqlkh()j@k%6>b|;DvCRqov;fAFU_#xfmm^@{Yo=O{jA4AIQ_L?j=0{+VWjCZ*Oq@-~<{CgvmW6t3N z^_4Ma^^#4p3mw!8X?7fDffg?K%H548G$o~5>s&mFs`y?}o&*-Uy% z3ur|!Zy9pL-CeWcI9Jd7-KFU4@wWV^+3LG{OXMOuQiA^yQZFy#&qNK(5&s~r>`&I~ zu#5^KZ%LN%-xoy|hyR@G&evREvw}3Kg;Inz~I+S(Z zFK2S>{m#J~F6|##9ES>EGb<7q2RxL@5567V+(?k-q!|tK27ca(6F0EpeG7OdZ7YN| zR#Or->-`Z*NhTk1Yr0;uMB;EJCcX=s6nwhRQz#H^-C5&IoiuWPl6~Cbn zUROa$*r0bOmCBSMjxJ5W__O^h6d40PlF19X8`;{7m*%D$3HJhh*^U)AvgCdDe<5!# zfH&1p5;m{Rf-3AM2z?%xp-#jv7=(O?Xi5KrlD~AfE4VJa%MGXgcOKd(AIulJX9=Ws z0h#(ix&<+-;miIIHRO_`ZWDw&A0@+nq6Y!rTcx7(sZQ}z+5R)SOjE-H4JEG7g4 zR^i8954g6t7;!{JMtHO<14PL++-v;G=@@ThphLw*cl*z1w8R1M059rcVUqtN!(zn& z{FF(V1X6Ol-EncPQ4Q)q*8(G2vNM;0wG0>%q7e3PxNCA0#=&VC$CCxtR+%K6-yjJ3hB6r!-cmYX6#QaK-8_CT@$i+L8RyD5HNri_Sw;#spwDXj(tOUw zb&5s>DKwOX6exf;{#NWHg6f7eoGm`ZJd3rE(c;IfRhEP}h75-f%i&r5%@#Y7Z^7S) z$yKoKnE>5JH>#rr*hsKcRVK@yzAGMQptuVSp$VmtXD5xGn9+GcN*6c(?5aPpig3Eh z>G_@|msi#(LmFIQfeV321i7A4b*v^KZ}C8~3?&&Am9_cduCUMY)GOlrvj2Cv-tbl# zo%{R}lG32yT#-emR92-O?PM2&G>^jlk@~gPtUWij8vaHa4DW=|sW&!1F%=3g1X*;_ zWJNl_R`(!K^N~k44O^11kVyphpbUJ0YbBXLD&snFZu5q1xZ;%O^uP$OwP-c}&FP_fg_Fc_3w z$nJt-W7RJY{!LOr!Y9mq6-#Z+WF~-l=Ur7Arj>o=#u9>&a<{*@ zM?wnTtH~`Z++4*_4W9V(O5HU4O_lSs1ecFWofVuhfxAo_;hs@uEI&YnrVbh^jG=rl ztdpqfHbxJS5c13FqKT=3laQCY(5n#cIrGAIv~=3F^@l0c>ka%YhD?^^G6VQJdpxdF zzc*vgNZjn=hP4R&9rMr82Y4r?vb&GC1NhIqLL$w#uM374%ou%Fh#X@Ic#iR-EQ5iO{%shI zwP8qf4Oe16;S%ntnOYE_gM04Wd0p1^D2a{J{58PdO2n&@1?j2XL(Tk6#ppDjj8Kf9 z^3dZ~(<3xUPR zIwSk0IB+BI0D}kvZ1R>`hMT595kEqjd|?^LpVA{Hl?jSz!J%A3B|nI~Asv=Di+t;{ zK(?Y5 zvJUTniH$D`qvZh-uG=R`{y)DZQza}B@pBWMa9^>{f3uB)XjBrS|Ca4IdE5Ec-ieAN z%mgRwXLHK%F@2cLG?jbr-pZ^C#q=I6z3X;q)OiOo?j3cQ%Phu5^<_3zRqnceF19EV z(z-MAsNce@&%n$E{;$$IUu^Bnd~njC&Nm$IQx{oWlR0mGJ=~^9Om9ibC%%gjxve!C z*V}v*<1JJ`cZv8gQfW3>U+Q043oRFHp;Dy2u=vCT4^tw0si1Ktu^YshG{)v7hNByF zMesx0-kvbH%DA^nHtg6*NzS%ZF|XMK4wLi~EYvJ}R{}kWs4aqF)M{WnS=Izng=J~eShAu zw)by1>a8qxs|6ePPVk~85rRn1=Mb*zKJ)y4xQ}%B*^8y)XVdlVU z5;rGa^nCMX=iG|vmEWJUq2K#dSGEw&%Ca}vOzB)H{DPa&BkE_X&g^G^>e}|gg&8+b zFr{!M^7F1mjH(|mIj|r7s;k=w=cPcq*#D~{QB2vB`YEF%LTCebBQk|sq>8guw2MW8 zAhOalJM`jgb--hCB976yH2G-rPA_YMd`nTShgHCl z4bC(Dp*42`DiAvZt!~TIb6yzt$H?G+6-pnNQ5=P6m{7-anMDoB?I&hGiAI4 zQviN{eqkxcE>+&C8MSZII~J;|lC?ltXQ%hJ z)$?aKUrXOs_-B8y`{joAZ4s2s%AS44~_~{Nkw`s z_)-7qE~E}pp~A;%-iNa375#ZD9h|k#rA3e)z4HhMFmj~tMSiO=c2?*KE0u`u4T*Zb zeF#PGQbsV>k-l@Xm7lS1tHqLgh?P*?6p`=QSQ@Tm!rtD)!q;Uuy+a|8g^Jw!hs@GC zXLAb1xV2yjQ-?L_G8VL#ahva#s9PyIO2P7vVsedn?Su5uS{#+NOv;(-r_*2?HN^;# z)9>Bs#6VAs2MH%9mT@L~UX2>0kmUWWG-vmw*>)*Q{7UIp9S=HTbKH51V|xAqan`!K;~ELETRF-yW>wdt$8P~m*%|~V@2sO?7X>Ln z4rpsxl&L3nY8}Lz7&I-bH62wGW*nyWE96GHzY9j_vf^grR< zWCd3g@qESI(Vtk3Kx?w$X7}PdKOpg&B8nsiAJJ$i^-rqA?_0G@(7s>0|2G|Dxlo-m zn$}fj$qsIVMIpYM3xDZjFbuIay0|c)^CO-24-Ni@5j^nu`I!2P>>g)%Fh!`x3`S!`x~b_2 z-yKQv(4JqtyeOxV1S6g~EH&VM9e)_Rp#NM@4raYk zqeeje(=vK#4De-3_H~7B5OJWa9aAkUN3po_VN9h`5D@FpV@IkUKjZBMNM)&*=cLJU zy58~H4f4mI24kGYL=+K|t_0?2;=7`$^2`>kXCW0d7Fhb*icGF%}}g~W>| zoN|s>+n1RWQ#02f0BpWinltM10 z&pt!0oIzeHa~Iq=;>{(9?qu!ZL)#t9VpiQ4hP5ZG-~)(*&#tJe zARFw6RFjM^WI%(frAu_W_L5Z!F47BAV*QG~b|YK7)pGK4o32td*bkGS(z}Bf zJh-KZpW@}}-Cc9;drLo2!_iD>y8p|C)fl6yjHGF3sv?@hR(lo7xzWw7SR%uAMt-=RxJ(pZj{{EixJuA7n+0&5`z;x~@>51T^yYSwFr# zsW@kZHhQB5j{VLMu5oE3pA$8XyuQ*w=L%GSAwD>sPpFvBT|qBe~WTguR?Cg$H&f6U8L`f zngM8YK3>Qi5?eoK>1TjvAFP1OjJHmTZCVbh(8`=nx%nIR0RwbWTmsEzaE6a6hO*z% z_2Ug!1iIR(*}sU@j=+;2wO(VD7{u9q3c983+@mS?F&|;WV(n+?+PtB6@}tISiEFB5 zzp@;ouuddi1=@ud_5<|$c8{gY+j2g(L1(DWL3mn?k4B~wmjw*UX_!N$R)1DNJpVZf z1NBc6R`QQ|en}~xT_C2diWDOMsJ`}lKUx<5#(KkRl2&&P^xr_Ei1czx@U~6`3LRP? z?;U{cSsSvuvGfgkA&jEUz^h6jx{`k;(>kDcwpJfWC-o@o_hye3k_#s&Gpo2sk zu|MH?!5#FQxbWBJTT`pOA{X@!&*$3UJ}Y5jpnaZ}h6%3jgkQGSt#C1WjwEz=1WNK! z%7@|Fj6jYQusHZ3XIO7j*vo?MdEwwXWI<${gq7}dsm@C9ZCD}a$Qs#V_0*wW$E9GX zUILQgrCz%TB%p#kCue6RMm{6B6V?tnelkx*QY*$29XGBawx^(OoS3spG`P;R$E_aj zF2~#qDY6K!z8I-+WRO}W)ZORmCORZ&dKp|T=Vo(SV4jdrAE$;>czz>pxU{(MVEbh- zd8oNGNBAVOeN&NwOv#$UBC*1gD3bJ+(NlDiv*-LesAEEv8|W?JH8xgm45X>idggt` z+GPK1EbL<=S;9F=?|sx>$b4x*wDIvFE8Wv4dtF(#6+#ll2R=Mo(7OBXtsW5FF9f}; zV^E!a!{l4`M4xbx(8BT73=k|Olz_^GF{ktT>&a5So#?ak1%?gcrr@W6MijqQ&2n+^ zbF@ekJ5Xj#trScrEw(iUflu&$22S=tJDNHu6zbzq>{QaFM{QEfsunGi52*~ZFfp~a z&LX*mRIilKS{%5fQd-x`tOmmFs!shB_e%SD1Ez$wp>7H)c5DE9Kv_EBswR7B>sIOB zIni--q8m8)nz10)PF&KZ;=`)-WEtJ4`}~bacrnHO2F;(&$*LPqARvxE%Wg9&DAo05 z@QF~|IPWrbu&IWfKQt&$RSQqU)U^8J0yufMbJI*dVL}o0hQDY0?rX;fOY4kzUaIbS z4jqeNXK5-?LG1J8pQ+kdK1Km@!Jon3iR!!1Xx!u*F05%_kf0QnC&g z;KV^D*$*Ly@LF@Hd=*Gv#*(FWi&cDqNNfZ-GB%6#!dru{l1_A4l$ig>7gJ*nL3jSw znAd`wb3FfNb&JBoOM|k>=;QF-&qqagK!FOL-a9w~4o;gnU znE;7nH6*iZ?P@|7tQ#nZUXetEzzoSj?;caL{CnpHj*{RI&?n|WW2LpaRgrL@LP$DB zr6VR8dAkZy2Bj%~AV>JEGkSr?YC+?{Te=2PIFr?7J)PJ;vg2}*@72feG}{#X{+rNx z-kq~+J7mW+X%3)~^p*G^ud@)=w_5p36h`Sxs^N*1FYC^p&0p+O!6X+sYu@=_&5FXb z+7qGVg(~$cnDrX@vnK^a?w_)%#xgnmAJ&UMJ+ZHL(N4hDT!~P~`yGqS+P5EZ6aA!O zbiZ>%P9U#GT@X3Zn}#4V`#Fa_il49}8X}K{BcL?iPeQI3ohQY|F`1sNx~whJVDtPN zV?0K&p%tmK0LFUT7AjW+MZeQ_?xvBP?-fpvf8q-f@(`G)0WE=FDGFRKVfzU))4{#2 z_Swt{zHb$dH`)Pe-Gr+d23-5J}d9MzSBz915vo7p6c*964RxrWU>qhqJ6$3WAGiRG}WX4D6q)Gg% zHnI|jUgKKv#kpcXgv?u~JZ%RW8P-7RQ=j^9=0Ade3aj)hqTg3|gb)KK1319-2rH-Q zV4${Jo=*|x%7M1ru(J*3Xq*yt+#IEH6(t~dHxW!LzRBYwcIqp$%) zS35JajW0XpXD9`@k{~LK zH5SgsmZ=LDxsvkS`S$BW4&DULqAYdS_0p+)6g%d!TN|OCv6A0yNkTRg;LwO|?|4oq zHq0wb3u!KzF!Gn+xJ&~Q?0gs0^R_B{g{!NRM{Ghw^j&?q9mHn`_MplVlv7iB161{> z(b8q78i`bBew2dG`yx^v$lnyN!aP=5GzkJ@$=&A$(D z&=sqCnb9b8%}@~43j%wyrQRF>pYA*!aW@Xu-Z3O@gsg2g+6%0Fc)A=YyiscXO;ckK z-b&8M${1Z_f`gRL+V~f@L#=>fQg_eP`OeRrJ7;jhzOCy(>#gJd0ks8gA9tnol|v-_2+mD3%SUUI zVj$+ssTdZ4^5^~*3d<4AtT&a~%#YD>l95dhj7obA?EAL@h}&2H6kFDFf8cb| zKyxVILjbkU4TU^fv3Bhh5p-WpoX4d_e!+SC9)JNIu-T{1h0~zr=}c4O0Wg38+eQ*z z+IYl$)S*`0Pox#7*DEpKjmb*)(Bs^WELFq%Cn~Y>i_3mTg76L_w78$)c_SKmEdpX2~mQA zp7BTXfxSz9Jsl#q!Hz5Az7@*D0JD4aQj2nYV8%nNmRyN@=;v$uhZXJYmwY0E4n!nQ z@V&-12GS<&Z_n0_u#+dW)3H>aLzj7XEr%8A*;WJOp_p^YnTdj@UqG;U%@Ml&t?6`m zU~}`Vr;3fqj(XUxZN(&K!Qa@PdMM;2r|)NyE5e!MX3L3VMpIdh3~|`E-EU`fpcB~_ z+!g9@c7sd3$YI3e&u$B#{%s>~e*XH>{uQgf+5j9SuD=6SeX!@R#41~XTqkSO=m`|V zeOtY@N?}?g;fMvQKs`3i(8;tP= zx5lrx1=f}Jv!=M8-DM2@P>yhR^Aw&ojzvq}I-K1RD55(z0N2CJG2^RP&`>JWgWeEj zoh?skH3#6jJW%zCk)TRE_pMGU$*t`3c zhkIq!chbZ6Bq#YfCC%pn9RB1-5$@Oa-3^*vd*tZScWO*_LaNWuj-;~r*RUDAG*G4% zKbsQb4th+c6W$1Fq%Fku$0jf?Mv7!InlOSe!jI`HcZcIArxTBywXC{X(qTs=%<|j5 zAd&E!ewkTzTvjRuk~YTRgHJwnPaJRI-zP_18Ha-I-WaP@`@2GYizB;K{Knm)*vRi* zmEb@Ww-N~NaB3~l6j(iC1K}{r37{-9l9PjNFlEne$;;B0#jyKtT<*cYa1Vc5#(#Rx zRYpJyBfAjyc@g-^8h3v|jZalgTSkptPV+FMnNE2Ht_m z_~?wrSGWsh*E|ZdTCR$Wq%2%VnDPtZAYaZ&`ksKDe8K+|`)HxT^w?Sq zb1qW$?%N@C^bn1r{vfEs#c#E`RL5+!emGB3llQYfAf^$ex22qPE zcYk%DnC6nrD8WJ_sE7MhFcWLD=Kz3ZP*FT zrenrN=qs2&Je$Zfr>1oJsI_l5aT2$@DK;D~4~5kl6l7IFUCh!@JFIMTQVYUW$p6Rb zV(HoRd%s!@w>5j`CA7NAfpEVxf1le(z9LmcBN&j(_T*w92J*Xt?KMWc)bE^hYhPzE zIQd`{hqYlDb2U^}Nu-76L1dG`=P6q1q&&i_+oq~mGAg>T_S;v{OAr+7CRBYTHx zzRAL$Z_BL}`J8?w6tfD(~lcbUVTk)gCdt#EkiE3SBd_ z(;)YY9szdI9E>hQmMsCU(YUK3C<2>QdYUiM;`NU0OoYn5K^gjF`EpRRzUmBR4={^n zu@xY0&1)u=Is*?z(XAFGzn@LxH@r-$dsUFo1Jl()QLd{CQ0Ocx)+DUH^koOEmf<%U z@;@*ldp;~yPl*89#qp-yfmMc%w0MqFq~N)5A$pluDmzpzf%R&Io8M8q$fP#XT*B2d zl(=|pL*HMR3xw$TM}7m4lY(6(?ylx!Xfo=Sqe&!}RO^b$u@El5SC8;&{Yg;vhASit z;5OD@UkRr2JRTJui*0)Pr`dS%`rs4`UaPO*H0nNa(>~D@62vE)7lNpFGZI)6B!U5yhq&el*F=qjK|I4u4CmN9=JMqTWY>`*hM`j~Xy9(W#BCf+@llB(Z+=|;6 z>(pzx7S-jZupoF0!bCFDQb~>v4P#!tlv)agOIHj1eR|u@#(+U{zg#bYp7?&dSgVxC zx?om1@sJ>B6njj+YpoDzs|WBT4X#QHQ;saG8<=`e3L2CJJO6eP3rnL&V>i-*w51zA zKsVCn_OAm{52&2wDd+H*duR&7r<@Goz(>+IsNZp61CPawTW2fomUf3$bGMUP#q!vB zXkClA8zh(DbNnV?6ZF&)Di?qRp-ZAfb5QTErE#d$$bv$1ZM` zZm{v1%kia!+1kPQ$*wNi?J=v-VL1}G`wyi%avI5M24J=gYeM>Ggj;6_y&0ikqU;15 z!sP;t$r%W5$3Fa7g}Ys+e?0q~lenY+O|St|fL3loYJ&3U?Ym}D)@{z$1RxXicA**J zYUk}sPHSG?*Vr0LQ5r^S8Ej`2LXUXx2g^7EiSt~8W5!?LiUaN&aVG#6>G=S31 z?c3M-2_pgl-sm(yKZ$(VzlsB7jO8fNBNS~h0dFz5ugmmOlfGmB4D1hz!S#=x%1!+n z9lBiM{>RivWC(ykss0(5ZH9iwREv&tHzKU9W+$(1ktvzLm~tL(-)|eYzBu*}-&#sx zVl{U&jb*TFCFV&Nv?>0jfJ1x|KFL^vGqT-&+ffj5T)tz}p|No{vS|-4Og|L(4pbpt zBR3SDVgs6Y+yANb=&C7d9l76&jE#_76L$(w$(|4~gndEcPeE=J%|52bH}P}|&(?pj zykwHhS7;*!dwtI(^18?DkTARMKoem-r^BUW>~@JXMZi2EF_p{4dT6tKBV`x=1>^pm z+fKn5I5_-m3YKKaFb9p@&!ech8BG-1HQqxnBeH418C{Q4=Tq233V?Pbdg# z#jKEq2BPv6a7_r2^Cxw=0ag4>J-N>y7{cFy)d41R8NPckA4E0}De6z+=*@~{p3}t7 za~%s?P~y)#pURL;7VfL@Yi;Z0yx}!G2z4+V?I~K|4F3#m=6Pk;K_6GB@lwsr2W}g@ zA}F?S_@W{H><_UwSq~ws@5 z{j@uZrSo`c21&88z$kI4AHd+d2H<>J*veox`j8xyEDO;E-gSX^boLlNphzd zLN)ywj&W>D{0$UlP_Gc??wAT-`0@vWh_F3NOF>%*I$<+KfPNegHk`WeUO9G%3hz`t zH~7#8vTxAPFEUPshC2b4*LbO%etT>rw<%tV^vVc0B%|q?N%V_O`Cns$+^vbT9!24Y z;Ad2=KT2%>Wn)cScm)5y4GUuiP5^*ifdB8X572)yJ^$NapZ`|(KVaJbdH&xB`|Ke9 zC+ssMEP$6X2)*{f;_z|mvc_>lAVT6HO3d;nA4cLABZ9EKJNvxawROUdmB80;=OtQ(*jL1Bp_W^*&K?}7;(SdnFB0Cl*)Q_wotD4bW~pG!pKkTRfFW{( z_*_;MWL3KS{d+c=mboHBVg=;HWtwDLV83+VLv!#576r!Oy3i1XXv6C+Qe?%n#pwF% zlx#ZbWoXP;2u^U1O#HQY~bcqvIB>Q7AwAM9_Z5`V%?{g?< z$WY{G5Aq1>KOpe$c2a-PAU!K>6oZQGzvf!_E_6V0q{aq)pj ze3(3IpY;^2F~o)~IBL-|`vx%XZ6SQ6Q6?tv*hto|9`D^>(e}inn)4u&{MAp<(tI$l5OtIXuH|L+KT5FEwAth82xuyT z6(->EwlIQhGY&Ul1I17e^beeSa-+h}4E~j`auy@H-^OruF2D(uA@b_o8Ky z@Sd+NUHTwc3e?7>a{w;8T@W@Q{W*+-0m&&3BgNKGtc%G|4rG#<#}12Z5(6T#^j&n5 z{rFq9=dD$Fhs8m8{kj+)nz*hKsr4^;P-|f(ghBex(-+(+kY&<~BSR-WY+TVa&f7Lw z+y(TR1mGngl0G31aKHEjAx92$e{}*i68$l+Kn8dD9NM(5=mgj&B0g+7aneOhzKj>O zh$&o(vb>KkE)j_D+m?Ld1|K?c)!8b5EEc-b*}939RX^=>!MokV3&>5$7Jvr>@SUQL z5NHP}BcH{Wc2FDY*&RnE_Nnek z)qgA_b!Eq?$4|nu1vuJcr!rRHGZL698=xrP)ON?Z68fQ$NS7A0qD2A3;sd9`Jw9@D z!KTpQ!L7JRUWo6V6iy$vr8_nc`%k_7G}V=x-KWFzWSdWRhEgAen~r) z=g@zZcvkarTK*Rj50WZRsb|1x1QTl)l@P59T|~wYf5(UsigYZ5KrzuS_(QCNItvtP zdr$T5ajU>K!)60-1%)X(V24ms3S->{XfXn2VWOoi+f2eQ24zJH>dEH@NT=vl3Qrzv zz4Eep)W{)}Lz`R~_YAsUGJM}BOwD=Gjga|QnvX2!1uPkn6Vcul4MqszRj?0;rz1;y zRtBwgh(z2U5($5l5j!TH;#ew;n%GGDh_F+L)&} z(A0Jbq>b_>t>o>U|E}@vj0G>@&Y@db@;P|P;yzq}68CoWdYW zh5!0w0j3@+(9f;iXWAE;^gH&0SK4G&24R&0;w2mb4FW!Qq*@qRPg;0b<*l~f1k*7Q zXO37k4KGivNLgaxD$-dM0xWs8ZY4A}A=%Hv5q1%fuBKs7T0Wmb)MhXyZ>U-Wv37gB z>m1u-Acu1k4yF22)PJ>jpsf*>>Z*pC8&7wWI?sV@NZq3~QkU|$^?=vx@Da30rQ}V$ z^0YZ1nQV|?Q+qBqG~goS#-}C{d;-C(g>jR1?@y6MFoLmMBqd#yMRX&pQPxtEuvx@t zen(+IzoP|om0+3q8uQ1VprX7r8K?n!q|v7wqJMum`t{mf zgdGDiV%4seG{kM>WPE9P>TyEY>gMK3DL$Yl0^1tt;G%@lJ4gG`K3blYWQQK7Zv>KgIdLmG6L}Q)8VsmnbCce%0o)`01$vc$m6u`UtyD`D@11_fM(K6V3+F<|)q*ezwe^>#1x(wS2ag#C zz{oL06|x!I)Mv(T7la*0B!Q^qOu2gA2#e*Gn0>nMOR1$?&HjOk@NHzV`@G7Hq{X~P z)?Tq7_eo%}R*9}exmcNbZ7QvI9fPb%gd3hC)Bh-B7>&)>eCm3VZYm}2~DdCnn5NM98 z#iqk5n$yoe%WD(Gg>hDkR=VML*pyLAFr6+X*x zf1|RrWVf>Zi!P5GmBkW!pcfreK>TxTlqwHXB3ViPea>;gGgs2TLCmDgXKfqC3$?}h zR~fjk|1k1wergd*#(@9+Uj!G5O=JgcT3MyuoKX>CCb!gjj$-d&&l z%GVm9={d{%<&bAtc9C*(%quTtsQA~*ZXTEG;iv>%(HtfE!_SwDU|hv%2@we{ zM;Z$qkD)nQU!?;4HBiv`a6){pn0$WyCva?RrQ^E5Qb(4$-YxkLqDSO|8xL9EH3UB< zV=-nfd)y5PuGXskj&suy*Iw}3uoVDl>s^bn1yGU$tT8dFXW{hXl!xaG8SRF@tli~< z$)D#R*X)%9n47Ia@~E)qvvpT;eoE4h%q)bGA9mu~IN0V&-iK69+fuauHK)ZlI6P2A zQo-G}m}YSExwtnX4l<0sjPm^0OhjDPCx(BwS`XU(C>)N!Li4cUl^wC+u|4p>D0mU{ z%pcts>_{Xq8Iuie(!39tn1p!Z-e9_LOd zs$qM)N>ckKx9&F!q4621MQQB33i{2m=bd0e&n`#SKb1l?qn#}LPVguhv}!6dv>q%( zZ8osNdJ~?>rX;sr6lDNMLdZu7*NL0qi#UoUK6EjpoVe554wE`LLEYoEB;fE4Z)g!k zjFn5x?o}$1L)R=%F0DU9Pn=UvI=rBnv}k&o(tW0ie*Vm=Y|l;ZY@Pwtb*e@%VYsd2 zd@1zuQS^%8j6zr-zvkRsQ>f@9lu6*rD(!&ZPYNQL)y`<~1aBfdIE%^HE^oz3PUpkE~vC2 zQWax*vB7>8EEX`fFypV`P?B(5;9dH8@XT(VnfOi}R^8@2bbfdhpSjX2kVM>H=MV8U zv0;z(x5&QhoYOK7U~=cZeKUT}-&)7vq3p1zB`!}|XPumXf3(uc=a!jlbKxp0j>eP7 zw47u|+=)abKg}F=vwWK(gEmu@4o~O{w+^IBdrC{Z?f(TPK-s_Zpbz*G%p@NTjqlFX z%wDW#s~*o!=AyWf*})BjkHk1?f%IN0vcVW!e~??$nTp!kUwCsnNV4QeJOQxSq;(*c ze;+lEhzxBp4UDN{7(BjR2ToAm$I`6uhh?c`2l)Bw)cPxe_Ycx6m}WXEb%|*oNFFe^ z({w2WtW&u}a!tEqJ!RzJ2$e|n6pM7XCK0lNY0e3z@u>TgCPjkwgIx`;2kM1-c5G7= z`&nmdbCG|}fAD>EKz9@wDwN$;M2(w))$)hp11@lqUxClYGF~N8_QrK)!PJ(K0 ziK4j?zGkR@y>HmG%U&>QL&gT%nziLC%WCzP14vco5}Z>WihYiOeC}m%8YhQN9$(fO zQ#_`Qn?G{r0|=6}o}G6N1;Nvh#OYF71YqI2j@OzI9+p^u|!E&EPw zob}8%On)Jh`#71dxE&>=q(zvYUElnkO{>%O{b8S*uN!b)Bnp6>2BT znw7mNY!i}k`K+TmIDjA9?X#MW{djtbA7`%+9O$DHkx$wVU|yh2{`nWqummshUD&@H zcmtVeV%MhE%1tX3yr8A0ZHN^#Da3!R(wJ6Bk%O}%60rGih<0D3m071SP4BV1x?qMz z+}*M3AsuH)&2why z&XuASxKTp(F+seBKNd<;fV{o8U(^2R!l1bz5YTAQJV#3JzfUDT#3h8 z(jVnyl~E3)NvkUpn*iIiioppN?`0kYaq=vXrXM-pc4a~wKKvsb67SbWq<+~5Qe*Ci zrrI7fJ!D7BnfPZ@aH>>0F5+{}YD{$3=K6T`PHj5UmRLcrY$;nAk3exBlCI1F29~AK zOj@BxmZw#%g6kd8Ceo6CHV1hGDC%KN!Uk5V{r^57Z0O0!nPv=5_1e(rdp_Wgkl~#J zO%X2Hg_#6t={n2NtHYw z3`*L=Xj4|JpLQ5_D;O`}x_(9$9jjQHlKA6IaUC^phAr{-D-+byOc8C8_FDVfWldbepRGQap zfBeg)whsp~(q-m9-s18HI&vStXuD6CT)m%Iang`D)(5|5VpX3LW?aDfC7eBy)n|NLR2Xf zyi9wQ?a1>Q)BU>KuV|*43HM!Bqw*&`SZR7i1Xz?XREzGmCIm`#K-dSTUPT^}YSPK< z^R0zY-~|w%Af0RP1{I(-Y%Rfn(g5b@hd|5K>X5P2wk;{KzbWBjwFC1^kB3ZEuQ{P-%f zKtI$2R3|qWOun^$#aj#S0<1on!4cmtlC-*hFZnf8_b`|H{k7i$-xb!v28Ss5@_kQa zlyt4_%P5TiFbCs+1 z=Ld+)4ZnR&(d>PD{3gZYb45hA%!VPc+6fYe#>@i{l}*z90Tx%+hZgr~VRt%_FAq5T zyT0M6ygaY;B=WPNBB(3WQS^ZnOSjsLah}IEsWFt47gEw4en`ABswOVy{MJ!l*pjxP zaz9eexjb7k9DpWYQ#8tfikY=RXRWW%$f9d#K0(`ByJ)LRh!a<-~8+*JpJm_485Z+Z^T&(^Abez5WR z`m+G#RA|NS4PkSMZmlUM9 z!p_wTvWEebl>i?? zN7Qort~7)aKcmKLXC~eg&VK2PlE#mThpg2<%D`%tbeWGRDCe0Xj2E}emmXXJ8ko(Nl#Nr+qbh2K2*w5|%5chMgSuLLEC;I6aLj zzoC#iYD(=H{QnP@#7XVs!?l!gpdfqtJrFMT0pRwv-`~3ADz@s_{$I(Hatx2mwJ!;( z^D$zrWQK1EgEggcbuY@nvTB&&VV3ttG8gC}XfP5t+(U`V5Muu`T&VYaBR*u|#r#a0 zMh`DJ022sr+aTgzM z(soE){N}Ge{{UBsEIV1NaNgGrztB6`5L~ur794ui-9c+R`^1bk=xV=Q$ol~Jl&BDM zCbN0*pfqNyXB?{Q_xOpPl84i)oKlpUo8N~$6=9x|dJ`NU2PLf>Q9f-~6*dW~49a+E z)D{3QK1yH}x=t#V-l{?(Fyh31E~|p^4VlMq7jfFV+Rpg!)7&eLZ)YoPg#5|%{paq; zwUcmHNsKIq<3#C*jWI9>gpV!c*qXQfsX~k}TAjg|Y9iS95M3X5UBpQyy?EA;02y1! zOKiH4K=UPWD;-qdXu@Zt>)Nfv^5)5}!?xo3p3Xz|r~J`|SH(hILvTfo_6a7W8-j{s zw&E!*ee8pcmmGi|huc<2a-9UR9K}cx_b8jkNoxskmA(V_RNhhGGvW{=?#>afJHd>a z6c^X?YsU-eI(_z0hF?|d+W52OjD^Wsa7T595S5H7Q=#o${!K^-d=h;VpMH13K94%f z=NYz1$h%|#y8h#o^|}eKB3w?#Upf`4ft)rp>8?5c49JjdTxjaT_Lg2A2G6w+_TWWU(V*1!MS*~&wjACbB-YYyZEH&H=kv@T+zsxIG;8i6X zRPYnY?o=~aFhK~+d*FbE`ObX`-TOpulE=q==YM)iul5!KaW(?=SO>dN9B(g@?JDW9 z7Z9%N079Er$er@A7`&eaT2Bjga;Tg>f{Y^MzGk~m9Ll*RQg0n@wf>`cLJ#W0UoY+2 zC8^1fq%_3C0WgPMvNvRUgt3!BH`gcQCzaG)A;- zP)ww;j|MevqpWY(fw86H%CJaubS2v*c|F?zMaLnbqO^)p_zVx^QHEW0bGN9Ivs)h& z!bpRLZLLZhA0<`+IH_tW;~C*(29bWQA3a9X>`5N{iUcnS0P%g%kfGUM;>h2^Zc?K` zc7#u5VbXY=)5&QbNg+aK}1tZh%M$Z2oB{ObXTJMKT zFA6J0NRiX>vGADZ_pM!^g!lHT^fz$%04V%JGQ_%DyffG_JN8%s?^Z7r|5x0jq3Zg% zoGrUI?u^e`hV;#M3!6h5t@ZoG2GguF8dqnMae>|exEHUHUpNlKA=v@}MBqp?nC2kD7 zpRvq!Ua(ar=UtAQe4*P{;W*~6_%+luj>%5)YlZmTuwX`uhgPX9YK430_gc}R(RXnM zkynS(e~yFLezRjUhxiO@3C}X~GCEAbu>z`RT5U1D{OG9YN)i?{cbk`oSu}Kz>80q? zvkNiPm76sUpAH_NFASQHME#zT{J?B+q;rJr#fLfanXL)vUBL@(!tTq|0w43ywad2n zhP{JK!^wz%9=aar5L0%Y{8of=etB}jgPMe z+Fq&v&_pr*3l<_DQXzQn)mLto8G-|!dRXqfS*8nr#Z|>8#F3Z)$H1ukrOx!9M5sX) zYFK%u8L3idd^iC-Z(>5nKG=~T)5$FzFcXyH+zaB4>th*eE6r5-;D}+;QdaB-(c)2_ zFoKqGq5_g-1f4Cse=B`O(29HTvXdd^a)rQjTig}oj{GUd0;(A`oD%`nmuzvgpqHB} z=-;xBaT)i^_7`oZ+Q+q7yW1NbTdzW(YUx&{h6uUNYd`%?=$pJg11vk4K(!|f(Hak0 zw=wHsk-_~dw@Py>V{ksba$6HlhivBX=VUV!cwhfT7>U$jiFN1<=3mje8l4r_Djy7@ zHl;v@=|$EPPi0G7xq~PI^SKgK8Gy_=J@S)kk0~pMFl8+HO-;#ff%HE0MbDKbF`C~K zq{+iz3U`46QzJ-gduy}B_O5LDYZE(9h(G)V)XfoXG46NUoP64D527RENnYg`Ixb~g z`nZA(UcpiU?4T(Ts@CY8YeLO!r7ep}99SyJmB)=(D>jZpV&wd_WVO_oDRVsf0@KA- zt+2V1HEszDJOEPIPTT>*EHWcN^ufG>&mX(tc`nLZD-sinww4*!Ez>7!6A9eR9B=Ck$L5tQF z1_Z3odLX{Dp`$%&9`t>sGYv`WJn7mD^Ga*5gF#tOPPjlHc=_~R(xIIY(&aF8WcIFv z?(T8Idp1Y(X+?uz(O^niz^xQuk@md;06W#f#)S&=p+c0tn5;ZEl19nHOwuQb6ekCS zQVz3-MF9VAvDFU1&=G+9)g45RWOHhp)R^nD0G`NRhjHU#70cl>aZI~^dlrdG8d1tO z=JTe#o#{I`F?$=)Lw1pnzPdWsqnhbg%PI^Fp9)$_?%8IV7>_H*pVK?Q{BJ4H8Vdb=GvKiD-?Agqr3 z-uL5YHC;&VlT>Ivtpn=)it1ntL!70*#C9ocP9%cJ6Pk^j$#<t&gsXvX~vT;dBj zZM9IC>;erivkj$w8)J*ifptovL%dz=da4naY({Yw;weRa-yrI(T4N)k-Z=DZcb!;! z?+q5y9?I+?!6`DwJ91qV#L{NK81}x|shnX`a=MEBa-$E)w;9*CxfJdg(6A883Ej*K z4HLh#^!x-JSozb7rtoH6kV>|6l~IE2D)e|=X6SxXYhhp5Y?fUnvy0s|XGpMwh^V^& zbtmd_vT-PwdTz4s zRAOJLzwisfZO+wVnQ=rIR!HWNumz9~9%@`M_~RL&mwlmx1r|lnRUmA?ov3 zw_Vueoz0(s0;H@hMtlpaFv?H>eJdz?7lbI%-6(%z^;4%p&-$Fd0LhS9Z~6>c9@i>9wJ zl}S3op^Yrhpru(9>K!NN_==*Rs(1x|qVwS|C3V;2MU*}nq@SmB6>+U%)c8k)BkDgO zCKM7!8Lus*%Z$Et8=bvhLdVvqP9;-F+5s}q*5y(o#P8l1q!;P)Z`b70g8T%?%4u4OrCUpt2@YFm_^0;!I_xInrUe2(4PF=!dq z$1K~-DwEbLb=erLJmN~2ngPGCr;#L&0_ccZqzJifLcwSdl971y5K=%MpQQE$42^sSwURXOjr&V5v~Qp-6t>9!8sk#(dG z%p0n}q+A#w!r7=F*pRZ$25>uA=gAjmS&?9qC$*8xjJ4bMKw$}w!4qpbaD+0Ni|u)N zAfPyxmkqOhsu35XjpKw@v1vK2G*&I`;P`RS>E{5m*(iF>>@8A@2QEyK7oYkvM;HDS z%MJQzYYU@3g|T}=I#;TYeFhIkO+}SQt$AP_9%uJnq?0RY$?8}h--j=&(GD?etxd7{5?y+ z>6N6rF?#PKe0TT2(cf6L^H0j4DIHP7!$l!Fcj#NzJ~u^kb%@#r%wY{H9rw{LG~S>3o zA_6^uVK9?yu1=NPP7I&72O{QT^q1^=o=sZ7(R{&CkOdcczNfo8)d;tsT$-<*Vhn#Y zrJenylrsRUkJ61e<0oh7tbAIfwk&~p-FjQC#Rh18Tbx$xs2*>a<$9bG1w!K)m6q)c zKga%~!kZgbJc3V-UG>kjez1+98Fy8615{lS5q)Ho{E%zv!f7%m+>T8`dggqm){j7m z*G6xc)1Uf^;FA_Q*OAmjm9I9(dEUb_88~yZg}wDaC^&n@^517MZZxC0$h4H2n&yVk z`Q>m{8oAsE!on*;Li4-Nvl8)P*L7q=&U|k%C5FrlzkRXSNUmSFWtEIj7 ztVSLOou0Rlz#uf!v>iXb@&!*Zd2P$m9_tYFm&pe{d-J3qk-$~hc{<}QH=BR$|1U(n z#aP62YN3M~`gi_lF59#X_5*7x)fboF#}yj+Vf4P#L{1FY5vXq6U>Jrk~j1x+6%= zWugBp4R?N2!A)~VsV2N#o@im-F7gOvmlJODb{t7J$@W8dVV+j^Wt$_XAop8*-`Dv$ zfGBm6KrDASXtg^qC2jTD&JuFfNi20^iQ~cdD`&X8HoE@7m=dOl)JdB8Ta#;0%gD(i)M5HtO+@IDM%`&c0Qd#RHuC>VzqG==LRDZia8>fzx z^ffg_G2+G=P?+>IwSl-`;6kd6naXg&c4UPYV3mTd$VG=h2JtrijSlXcN4%HD z7~j=?c`Sxo^jD4>;GiB~ll9|Aeu6v{DJO*-CKT?!Nk{`PqemF^qU_r->yQW}REHhf zJk}s0d7@nOCQht{7QqRm)y@S4Dq%!{VE8l<&KECqYY_ruebB=Mbyw8t!x!u@UggHWqzsj9F%#}ZZGTa|BlQ_Q|`rSTr4 zW#>XA<*AV;HChq5hL&~qIomaL9AzeKTQUhx#qJno8jpg0i6^9UybJ$to$rOHY&NzC z0~*%%vj=h_CZHGtzc0+iR`8Ek11Cr+@ZDo*zT_vnY9nd6CHQT+k77@^{;m(?5c@aE z6Wv9}lw3?2Q1BuppKKqjwPI)QRKKkJs)rNL5gw+hY3Yi5YIQ?5iX9xhG3n&M@LKtY z@I*iJaAvD|$5|$knJ2SE!QecN?z+2%vq|z1C@o$hADj-irIOk%TGhAgl}-SpWJ!Pc z3L-}|#?LZd#CC^b!wz1hrDK-cRE89per33UjgJ1jTt`UFetj~SX#%_*s0>m6V>j@y z_c+>xG9)da7wR>0R@Uds-xY9X4PGYCY2=6R!$a-Rf;ZM$XN8^pA`iDcMt5WDcUuRp zj)F!B2C|-|I4lzSKuC7?>k3@FLY^jzMoY1=H;{1@ja@o!Uwe(Jy;9roZyHalMpcM1 zP{KK%OY&jjBh3`3IV5(VF67>W`5!b{56?q1EQM|l(39_h#-I@y1L9< zOe}<)^s5F=MNSb?8FU?7nVu8S8nyKFtV9ftp_N;Ef-(}v51n?fs{W5 z-e*Z9CNb%-UxB4ffw?>^T+42FZY^&uk!9?|@Ti1iViH%OCO5_=nCi`?yQ}-6#42AG zb!+4=FAHM0RV^|J%5xLWpj3`%yi;QlwaTRUe`xBGwp8epAjt79f^{nqGIkS{`RBxO z^k@1hz)-SI`dndYKSKgVcO@BG-vHx$nsBUR+=}bc5WZ@rz$yeKJ$4nEPihEKvA0JR z+&2uN!)w~uZP(Zn#I4V3tLr$2yNq$v_ftl5UClR5x^F0A`A z)uU1*#@dI_^rEa{qPIfgAuJ~adZghLp=8{giqs74vQ{{gUYfQyQUPk6PKd?+f#JJN zSi7f%l(@tZoyY~VAv2S1(PFBmKIn!5>8=wU7JtE)!jDy^&=1$AeJCL^dth2Gm}esq z2^%!=sX?f5vY4HJj8PSOp_;@*ZJo6I|6MW~;-$na<7&Ovt*`ZJZ2-HC zF&rvpL(}C?t=j!mEdk!_XKm1orsyRNk~MTlr%Ev z1@}0{24+g_Vru1V;v=MGJ~9ICBB(Pe2htMQ20W$X7qwGma9e< zDX~;WamnI3m`{C-^SJ^|^ANtb|7&%zhLl%~_I- zslaDN7|Uj!u5`bvg|ni01KU?dfHy79L(q?LTw|oohx~++)?c{W(uLGP&GI2aEI@6< zXN-=@uJjn5<8GFSw!wf+A68a|E7uAGTLnMS-^tY~-|#??Uf3H1ja7UQjr6N-dlTF; z_D*o!k#rZ0qGqsS1#1Q#bgllHxh-v28<~PDk?e%d*@8q~gWJHxs(39?To`BqT+OXH z`P}0N&NlBZ?Uc=_^xD1Q=$Tt%rqfcu_is?>zzJu{$ya;Ws+_zlf7=ImWLXJvj2rR_ zz4cYK>wS&24>`q-_HoF#o-9tFbLGT*$*B;qKFTI!7jh0t$nvN)9@yb4+HC6dkOxGYJXt{{33Qk>W5w>BW9e5~wrHZgwL+ zM5bJuC3x)36&?W9@r(`(Ia;O795(+3Gq!@IJjVJB#A3Yt?tu4~b+K^6&TPy zlyOEOE$L`EwJxhB1(DiMfpn=dDyizc+OfxE9D07Ayt`d+VLYFrP?JQejEI$Mp$8;< zA0sY=u3Sh1w1%i7RkG&u{4)ctarun?#LISQNJ9LjBpGm#dwnKwujWKTh(s5A@4Ui{ zTT`-tC>I)NXFMnD#&e=Sokz-!$Hg>bW4pxdwH_!K2*8VieK-!7h;(+70*z@Hi50pv zJkc3JZWlI6WDXOO4=ZvS3EW8^p!#^V7gi|EMQ4#tZrwE8U)2FmLnD?co+7{_{|RNp zNPz|XMj-%xy0bE8ylWR?p5pJDA@i(-s7j zr7us57klFeCN%N$XhfpC99K3b57 z8T&7>f(fdg{7&mq0aQ^m8)ESH(6KdpM}e-;Z@GUW_h5b+`u}%@4$`MiY7&Ln0KvTB zX@iU>H%u#**36_i{~$U*`Y7vj(=>1>7r;PgSJSJ{N}8hL`^%2Hp1Ct`1d=KbaQl&3 zlqvvDIz|PsDvIW{;4gSPAZgZ^>mIA{ahaJBm@AWuvqYUu1{8YH`*IwwF>Qd%ZAt6$ zFp$wgYLH_7Ofc~?t&4D6zzb@W>q))Gk7{S(1(E_<3=ALo`lY+@W~og$rrujyQ7*eH z!}e5C&&4tGz`ZNb+$soquc{gN_V3i?q<6SI(&8q#mo z&;exY--uu_r+o;R{ytHKk%=;!n9Li{`RzYeAUPpWKx4$HrXb^l@0pYZCdFT=3=@a-%4^!a`r zB>?kRmFiP5T2`ooaZ39VCzemY2gOBWkN;Pd%y}W*NH%jLCtt&La3bL~nBAx{HLexW z^KcpKLvJeryx*c$Y%_oiN(7_0Kx?aJM}Z+Sb&F@iuAZ;u}vI$D$-A1UAiD^?FjFx^}mAQR6d!y69x zvrPUAc0j|5sJxH5+2Ft7$+qJ<(XcM$i{N>%eg#q{KciR3>jVDQ?B;2*6E#XG4+cG# z=r(%KO$+!LG2a}y3Pn)Sqx&5btXrE={>s={t`Lr18wc&bb2xbwBcZ0RN60T#VmsvE z<5KF8;bjZoWaA`M{X1+TVb+AEHt98t=Wo;`$U5a>{Nroi0kXCPw|<8(e%}MJ3W@2v z6<+K?Z?Yn(Q(q@tJ2%3mq+3FiC%X^es1L{Mm<@+2MTfcS{yZl+;Y+d+sOkfj@EN@k z7iBXMsr1lQZ<62ZTX1q}VNYtkk8%&mdo?iyn{2fr!aO;QldJ!7T>jqys=PvFGlR6)Kitcy`Bed ztQ{N4IQ24pojK{EoUUl9Sp72WsKbpfzSz(1gD>5U@PkEM)EJIY2%r@wB>zRzBOR0g z3hp(H!sa!24hn_zF`IYpA;|f=wfI55M%9zy<^85{AF;0FaqxdSfUT-M^m@)?T_-m} zQZllV0&RE4GQI*i$as+bMB_WhDr*mR9d|VCmxU^6vl=8$=|^;9mDBUEn`gkwkLiW> zojLt9X*9(oaKsd=RoMTRsHKwO~2x8kj-J3 zS&Z3#EHipaBc;2jb;L};Q-~lSbauFL{{^H3m>=p>qkJpjxJG6rVPPM(%z{L!)$rTs zdd>1Y;+O;EzyM3%5soqJlahUPS~)Y?!Tr7ty;#J$wZ&^Y&1tM<+yP9A(q?6; zOno9rRsqE%s8rF)F<{;$@R2S_0whQZ$I*9hO9Cdicoz#m(IAXNRG~Iagni2U% zv8fh0BN*20JnUtJ;A9hd6J*lpY&KBBUoH%I9kS%};`{PaW-4=p0-o?&FktzpySDcu z_>RZ7)3FwtP$u^=SsJc)Bb*|l2liQY(nrtzQqW+}X6=CZy#+K&>O)t~ZIFt=YKmA4 z)!6(%#k{>uYz7nnWTu;x^w2_K?Jaup%kd;CAK0bUrni_IYvp141pRvj+p~IDrywM+ z7jRjjP~>1>8f>5y4lXO!P#6kkR0N&|4s`GrJu5pbX;HFS*5kJWjaOLnDO9%ht@wq~ zQ|~sG<}gG!S{RA+GQJOYu4dLQ9qj|8wxW{_KNdNbs3(cdhSyvJ8@}#MXTUXhr5psv zC4~@8Sbm8L)vZz$4%2DSQgse7KHhf^(ZSGif!PW~kfGxuVKBLQz3`1b;&_*rC%mj= ztGT<|ELsjf$$=j8N`6>!EQzW{rAW^PHmJMGXR!W~=O176zB(Az6#AM7VW(S~CL3EU zit~Lhgu*;(RDy--#?;$Y|2nO>Pz1-|j)w+x^I@3&K0Bd9U{l&6!1-}rvcgVl$nTfo zS#=CfF+wMYgNt=OB`kVYZ$b`f#Vs>>al`Hg-KBdZC-!;yrv~A-HS7*Lo%n%=Efy6k z8|b?w6ZeC!(17C&2JU>cQRB(oNd>DQk5lcxZGHPxHTMwjSJp8Gy>2DV*rRCK*BO6v zhPevYC=F$jsH*Q4N66#Y=A@3<0P`Xs&yMkm60H8|R!{v#2K7zc@7bPeOEIRKlg&9+ zUdy2pZhm$7rHC(X`m8Yo#gFiD`%C9HLCaKdYbMr@^h=!N{TUS%Cnx}Y)BwakW7B6* z@{_MkQ@&fxVa$y9$CnlUlz`cv`x6y_L`szQaEkRJ*zqMpHj-#2F%>1J(|x^|jPLzB zI<6C)CjODqWe1DL#|Q<#{l5ANipZi%F^a7$`Vc>h<}^ga zFD<;vIvp7G5EkV5gbrPG73O|xLbTGK`NY;FkYp7IHfdy(YO8dv8|wx(%ZUQWTYqo* z2sB`Ou-MMbsN}Zd5vDH%L!w57E+t?vW!)_X7r2wTk@L?9AYo!k1HgV_pjw}&m=-ZaG58TpBN z@rYDe-G`fn(YRdS9cF=)2$0&#N5&aMOP)bu;5Uk!-EmZ_nBcPjCzJPJfRYYitWv zv86|Oda9W_hpM>csv_wiuk%VFbdlx+=f=Zw3VMI0-pQMo$682!}1!Cm)iZ z_dc;)+dL>N8Hl5eeAg8yyEBa-&wvKOh7=JjZ9Km*d14g>1r%S2YG`muV(tKYZPM+u z(G;L1P@`+PIj_^kC(Is&^D4d!mXl)%651Yabut36v?bXxG;s-r$yeuzPbfmQk*X!B z*Dgj^v7Zm0-+4lD)6o+J%~X%kwe=ta$YFX*tHRb#9j8q?Ai}W-jAbd=weTGQEBg+^ zG2oaFMi4jJP8@eT*86B4P>g$dR#B--;YO%zJC|Tq`9OW+~bNTVYG-5KHB6ymy!5 zHL{e|x5bTPrtyl_bKct9Jt4d}Wb8#ccp5yhhtGG|H=jTe#E2-*Hk1Dmd{H$gep-@t;#23x)k*F=B1<8id0IQ2$HZpHqe? z0eE4+mw&b2G0s4Ro2B$pUe^f0I!ehSyWoXCzQgK|GM~?^C2zK;g}aQKwGZ7c&&1(q zIGR(2Adwk%>FNIfpEjX9XzfHD=c|Lp=UU49M1fT6LIFPzxF{Zggi@Ve#AKD2C&il{ zIoJaF^|M*ewdjs{rIO$jroOi(St>ZBw>-t(7$7B60+1A*jlP8!HwLIb;gX{0{DH0-srM!w)usY*GotphesiTs2pr zWPoXJg87KIt^FKHysw83hb4C^MMc9;(Y(sh&-8tC+k>>nTDJAqX(j6$V z0xtguG0;Ou0S0g|c~YL&J52!hAJymtKr?6Y%JLjBRw2W;?qXyJMyJ#SznR9sM#pB4 znL$pE_;ViHTM8pH@w?G5U5FvdRnNf_4!>>8^6R5P(eEb}7*gr^S_~kSxqVEFI}- zg}UO4DXAVDlROt?lYQt|J8^QvDNIGdy9(a9Z?xl_9X=26X}!fO22x4`KMYzO%^1*1?0MXTE&*X|v&81lq~-<=dU*72$DJ$LO4vpOZ=LXNe{IeRhXTiq+X{@2%bgeiO^B}@b8Zr4Pv~GgUo{y( zPD$eo4R%G+jFDvL_fWw3K``uGqaEQuO4)@#1KuS7pDB5wfGA-TYxSeJZ8|m^UoN%v z+?UO{>(~tea4Zv@^Z6bUtPFq<_Q8$^EC)a;g&U<6i6AXNk%rF9Y!y)L} zUd{qv`unr>CAlX^NAqkKq$YJZF0Fx~Ph>H4xY5V(u&0TIDthT5^qCKo0hinb_$$Wf zq5BSCTh}W_w|j7^NGr0J>*-&#DO*Uwrd=mo-a6%q=dvj`ldmt99Okl*hp~425{)zx zn(KKM%LfwCQVavPUWJ?2ro;X@X2D7LWm}lx~m=rG9l`zFI!+(6Z6rb^MF^69D$S{HX zLJq-mzT-eXu(m;V2vIPZ&5?^fa4J>Lx)eqxA@ZTaDBc?HAWdzna7l!Vq^fg!uejR5 z6Vku_TRyl!iYf&-I9;-=_MI-admj9epo}Mh<2&~^|8?siglDwbpO0d`P_ZGZS;^80 z6|5KTBMns1SNTs9u);UYrGT zW&?+Jsrc(Hj^7YP*r}WrOUv8nnQb%TUNDo=aWx7|sO|%f+{G%;%LV=Sc;sA@D0<}Z z>2s-1f?_E|vU6j+5$z|VXhJwAx$^h!gFcni0pgjK1S7*GLlSpb%V)bImBUsc9b}ALKCrmn>Koe($ z#GHVIJ)HF!8i%kM(Pa|cp_T3%C}{|WLG#UtM_?!@yuI*6VeD)`6-gg^Q(sMWvF38u z&cSugF|9v@T@U$Sh`HzkeRD%riSQFmSvw}K2sMHUQv8F4t-I z0`Qq0(fL)V_}f&f(22)7;&^V<1F+4b1`y8X*b^)(PbWp%OG`*I*w)XMcsAdsA0=5| zqtVf0_Q57y^K%`P&kfg?+*l-3gA}MR1)ifbuBl6itU#?mZapwe4enjDS8F>OhT6CJ@*oIW8nvx()-?o%s0n2#{x=dsUXU5>-Q$xT8d? z{u;g--~dzcEZCz>rw266pKpTZr`##HhARa@#4ZN|e5{gbq#+F@!l-=%td0;Hh+A!F z3LvUijeK5UeGIV+P3MtNQ_zQQJlm?mDMc~(iRaZN3<>rgDw`6lt4OiA=YoRH1gd+A zkY2>bcV9GUWj~Ej#N(K$uaV=~D0QMU3M`FVGOs2j_m_H`1*p?~#y8723$6qAoYF!+ zf_g>=s# zc5bXn^UT3VG(s|SnKy6LNbrwm?j}Rv=fo3%u&=OdFIDLnDaQE4G|lNaKue^=)+=(v z>ez$aaLsNVmc!z06daQ-2K7paVgn$Xr$}Ywvqz{ZzhN$ETYrs|j$*;Upy^(Md>S23 zw!2n_p{+P-Y#Z)H-#}2^ZaLSP$`lHS{L-wKAaezI zEYzBW30-MFu=XBk&K)5#&D+H+FLOY|BNL7>_b<={Pi zy;|p=rH^k5V{Fg`+oi*MZBGP+zjLAaeVk3>=VrD}wY5sK5`w^7s`Pf;DN#g9`uEjm z^sXgQ#l&y}d>) zt8#H7_K}W(0-1hYfZsw+-h-dd;n>qNWjYTbxDsb-SUo?ntT6F=`5CsxYlZ z#UWgPpp{o{U^-Cpe1zH3Ux*;Fp=edc5{?wAp9?Tx790zYWYM0^Dhc>60n7h_|8CS5 zwS1aZ>Pt})@F5Pi7I|5VMHYZl;juKDf}NOmEK|#rG6vUw=J^n?2%f)KPF{I9J;5_D zFG88zpp?Tf-=HgH`^0_m<)ax<7>n8eama;k>MauVO{B4*soH=LU?wFA{&5obbi_y_ z0eZXatl+X$5+Nz7#`koScoiAFbJ`2eZhl9?oXYa|*}|o#Gk%{>VuCGj;$^*-M(IeB zdj38kco1ZIO^Y2A%A{24ayh%&^jI;~T>Enfa|S{~uxIP?1nG z;wp@sT*pmb#UdL0$iIgi4Gl3aIokA3Itv5d(Ekj(qYqT?DV}%e6h|wyOg|N0kpVtD zY;mBH;zjHOpz>h4J7-??2Ad*+n99i`J%T$rm?vRhJu}b!$c)uYq$Hl>B2A?5vV=AS zx?a+9H1X{s>QdP-baPdbhw+}i-(oFeM^NsR%PWZ4RhT?Nnm26}kT|pJ79+flA>!C= zIiComLukNzL1tVPd(H0^yW2GQHKu}PVIuFrR93Py6h{G(te>}$r5Y^s;n?R0(oScg z!}DXBM8|QJg?eVVsl?v7S8QI@m<{+1Kz+g0@l)aT_RXsqjmVX2OUupaAGHV!xIze# z%Wm=a3Mwt@Gita`Op+K8o>t2PNp1J5IzI26e!tBTc#UZ(7{l9Yx&*VVIoD^7r{6a^Tk`x9g?*hJ%=n-BGM6BbIEElu$k9Lf+$tMfs^l5yCCdZB#TK@1L&~F? zLyC}Q7zXy7NIkkoQ^E9FKyrG0Y(e;Z19M z@oz$+=1-h{*|kejvdB> zA>4eCy^_Usq?2t4yB?KGz?1W9#2%3;Zm;k`p+6Y8S8y^S##s}f7IjkGDity4B z6o=-d-ibtu>bFj{Y)10zp7%Ux`!_szo<9aJ;*?a$QFK}Z72FJ0m|tUu0esX;#h%^v zfFLfuHY%U8UuAqIbQiq>d7U_R{U1GcQz;u)&47)758$OK+xR08y5#T1p6GzwD=19; zH#A7XI+~AA>xu+owAcil?pkG}c@yB@e>SP2A%gt6C8l(qNatP83h3Koz)}gDbu45o zt>BlpXml&Wky$6f*4P%%_0YrVSZwW0#Nndp%4G+$QMPKk3kMI7Bk+ayPSBFWvKQ;5 znblvK({6z+Mr?vz5jI>7#sWBn+5axKRTfjJXaS+iE(s5ocec!_jngM_oMNHY9z8B) zNe5TUS*uh(XRhW4$<;2`bsJ`TlIoGBLd;E6fqQH~*+rcHq5trG$j|y<)C=(s8SG8O8xOl&m$0VxZzT8#`EplAdiYH zSMJ_FS?FH9ZjmiE)I_fqYyLsg^2=<&V@^b2TVK#tnmGV_xdAz%@OJF@@8W--Smp|3MBMqU)6ZCEnSMtwr{NSd5j7Mv=lodS7g$M zN@N`DV!Q+KPkltvQnL1VWe;Wlyor@GeG7NK_P7btcTis8`0K3Q7O3W+2 znPnhb!DumvPXKwSC1S!_l{$h1#D`17m*V+;RqVao=z{nd1wZ|OQ1eukEgN~K0hA%F1^!e8`CWJr z%*Rd387iIdwb1pgBscLcx2T)}`7BWGRpBeT5OeRS83_7KWbJrKH1L(jh4m>R+)Emc zZ&rf?%mp#D$B9sHGxUPJou6gUUQ%%2!2)OVc}X$P*if^rxz2kxJO`l;*HNL{q0J?d zY}+w9lat?xfXgpUAdL)UoQ1wCxTO=%Cf%W9?00+l+~VgS1Wv=$GI@$E=T15km#-g-s?gV?M301|kXI%{25Y5XkQGs8`~WFxdXNK{F0CflAp z4`x%Lm2>b%e&i{}w)$$mxpZ(O0`!1Z@MusV5OMhk*j_3c*-q6FfO1_S4Am#|cCpLJ z$@uUOPMAd2zz>=t!+(Jto)BpOPsHr^cb*so5rtM2kGjXznC$GDGQ3el%|cbo|F4~L z{d+iu13mASR_w?LowhU+F&y8J8q3i&RAJMZTzGXoRn(NBRxj&6Z9n5Fl+B9E-j8wb zAEaLvG90oVZr3BXuu-c)s~fAUW9VI<1VZ~bh_cpF;Z01rWl2qJ*p}h%em^tRgXT?S zBeo>lXY0Zj1w3I2PIyoB=k=?%e19;eEnT40GLytQH2ym3=bY7FJY3KA`M{kGbuHbA z#BtwaXLb!-uA`>h?|@4Ei||yb(H~Ee(!7=*oF@KZMejuEnZSKulSp?hqss8rh;zb8%?)-#C0~2C8qm;|AGbv{%iQ^1 zrb}plfhs$ErUg77cY865YiU&H6gs!xRJ!95UW5|hm+js~4fVZf%h60o5+$7$Tv!?P zfz^Mkw431is*)G}VKGp7aqLdZW+;DJbgs*Kcs+;Ko^i*-JEHw^ISBCgOAxlFqwg4IfWHLH_sW7z#m}Ro+gPvUXA3!Lk$P+3b1+vu8bYpgP`{W=g54TGbABT z^q^*{{vyE0)Py{3o58CZf(AGPK-AAcy2j;y=KRJFm}R3r*vhjhg%qWw`o|e|%HQr6 z7@mZV)ZD)2E{z4Qtz>w78piOR$g+JnfLtCPgTx{#)t0v~YL7g-E}K&4wC2&)BF44`oapenh{CoR*`kx-!%x8s-t|W64C(nE1$DFu!|$ zE^kw^bJLI2-l~)0G>5Qj%~N*g3-#^T|!@5@@VFs>18aU(T-!w zA#ExlHO7!jI*F2|OAI$SM`!D6E!c}+5L$GI_EpBKc^>ftmQ@o&PLel9$=a@^m(v-wuv0aoZ#sk-BY#{3ZgH-W)J4 zrG3&z_;kgpJ7Ub=$_$@G$;)A^#$50E5cRTdpPkS29^d*2)1$9V8Yyw$sI`?&HQB*N{M$Kx5J5SaPnpv<4!9mL5Jdg zGpAYW-a0rW&e+9IkFD*^x$y-C|G3-ut6#UIRS!zdoDs4WE#H9MsWVL52RZxVS0*wq zZG^RZY%a%Fw{WL_nJA*9D4s@3+n`+0WgzWdn)$z^Eg_07&5aqi!y2mx5<_Z_rI>Fx zC>!RW{>@Vf|j(+V;F#HhML>yf}|(p7qDV z6_Hbyw6IGfx@d>+ z{hZl=(`c9m4rVQ~QT>|Qr$uY33;iK|C6#J^(F!ms_bA*oMwj7zk?oTzovaSBj1H#uOXnx=9R3L z8!3`CpwN{X)Po?m8RL2}Nr&jDz3GMlS>4x%JxA#EygF)P+AeCvpayx80*h^jXGEgx z?5c8ozT8#R{D~tO+)dcK_S)0QCSyzbN)S0}NkORws5Jg-!bR1*rwb%ETd+|7qgJ~n zk#rsYe6d>ATQI3Ntp$$8-I zDZ||QxWN?8PV7_1O9rWB8`@``Y9{cJ`97W)WcS6)ISF=@zD}!RO9-$naH3$TBcHDV#|*a|Ycnr-m;;cds!{1fk^5Ki)|yWCee(rDn_S-Mkor0v5J)16 ztYxQpK=-B)$Yz4FBSC9NLIPQ`+uoUMre+f;yu+S4D=)Z6(i}UzdJS3IB4Dt=G<_1= zTUOMlK*eVkTz+Vh7~pHoCW9@% z_?V4$Ta#-pz%0}_3I}dox9IPG_H?uP&3)bnm-8oI$>Rst*B54&H&i@#uzboNrqwsp z_-B8C{_ZUIq%MF3Os?vI5vb@C1?4KCpG?Tp*lX{g(FPKUL+MV9Wz6j=No$c(wYLFX z2QWRW3`Ie|)0QIhOO~nez(duhqxE%8FXn;|Qw&R>3q?_xmrOM(A3A-WHYizmpZPVN zs&Tm?80#t>uyE=H5OOO+4Vjy`>ljpUj#O8)0;*Tr;G%t`9c^8mJ_ByAxw_sZ0megB zweJl^v%I$Y!a-BzCByEIQHh*7%1JC6-rNGBJX?yiF~=Rr2ZzUu;_ntly|vrrL0Q?r z?*C|`Hrfk>@Ch{){e8Dy`u6&XW3>`_!;FX}totR0ZH??lS#Tf1UVM(AERYT$+a-`H z;YSe_zoZE{+^kiDLaEws48tYqn-Xck>8vZA4U4@^>Gc5aI!MlleGPn_SF_S^$^Y*7 z5cAnCxHW?fnCQf{a%kZ&6=!1N94`_TKHk=noqrrFi9iI4JT8y?9V1BEa)>MA)DZ1% zn@(~^mhp+5ZcU=(<2Y_EI8{T%P6tT=GOu1f`7&;Z+{Fwhht%32I1gsnZ)sbR^xJN3 z<`p2w+g!lfY9&JwuG9JQtq#NE3^~u{2 z$KdxzS>{*{>gQmb7W;_Y7U(4Y5AK%@$LDGLH_oMB)OQN9{mF2X8MBsK?!ZD4*S+<( z_m6((2fxA!^JM+wt(ga%~=!1Xh#)*9oDz3p%N_L_*I zgyEU^^~Q5EXN1~Xj$__2z}kZE5+B>wPS{xD=wzcbAyQsM8Au>C*D~_j=1?id0 zOO4O-H6}dPxPn{j?9m-O6#ZO)jC4)iXW~=`fQkI761n$H z!87L;6)nlMH;wF{y9Qq`WN|?JTJ6_tWrEbfkSn5(fJaf4x= z;WW4-tX)5<8fLO&MJqw<3eVwv9=P5ifnNlgh#yRYc+pw^q*&w=<=Ry9ZlC5eAyx$_ zFu-TQ@1pPc=l*RMX90pQJ0H{Q1AGQ&Krkw+`FS(Vq)`gigpy|D=&Am~WnF&1FHx<+ z;*lMQWhVlU2DOklac!-rpeg1ce-=%+$xJAQlA9@nTf!_@)ZQ!u)tT5E~{A zDcQ5xAk|tQTpp+!8yg`rY@@gu0A^TFF0dP2OtlA;_FKISv`- zVs>NPTmUgF$9=+1J1{Cf=p?f(ckk16z&HZh(;~0;(!p509VfCfB&+NPWplEdu^P#r z?!M-S9Ud#>DxI~7CL3V(I+s*YzJ^Sht8YY`X(*37r%Rtk&qKJwCBZm}(E)$F{X3o8 zXfnY8a!25(tnvUPieiivMyUst;9OQ4@~=PBFU_KCi=8ydGnZidD;Y(+)%gND(V{q= zsN;zC5-sPvHi9eBcWh@=TPK4#M`$QxNB$+zCtpVI$fYl3oc>S^cXri(bFqmK) zrA)0^5XAR>gy;5D&Ts=Ru#yy;U5h(YUTOQ;cYKA@UMT-gy+PWt#*6p05dV1OrKycC z^FilT-rDwxYQ$XL7e#GNu0KK9LnX3&whx5#s0=JsCFSL(ATJR#M7pVzP&b>O==^69 zyYWh-z{K>&=AOA>hl%!k1qejMb04^oQacC$B$%U^M511%-Wn7Zl3^~$PxY07<(s%@aHQg^3f;ULaV zW#Vr5&wex$wX5{L6g}Ut<+F65*~OH{Z)3xq{9S0|THe)0T_DX=*+kqeY3Xuzr6u6> zX=LHNHT0wF_7;P+^BQztS?AO;;wS`yMu>EYdGH3T85I`ei5zXo?=> z0m}!z8#sBOiTg%;m+LKbxoKJ%`%31PMsDEw_@k!t&vIR{ciP&OM31(!_*#7WVV5Kt6<6Rn9?{rH(;+{UM?9z;#>p{meU*^16!-^{5*)gJfM$nW?0xJk_wuE7;U z^SLGRK%5_MO4Cn0$M1eg#)!e(=w0q2dD31l2A0=fgi>Yk$-nBD7hJ0YTtYH$t5A0K zi*9u-tMmI88K7_}VU9dD(YR3<{^N3!A68fXdc&2uj`^F@p$nOv70cQ@1+`2VNLLA$ zEFyC{wO> z5CO~$l6gBU$A;%@t=Gb@DRTFdL@%V0^2|^`#@Dm|;bU7pSRVMhzTFH|VE9C&p9xhl zx@-a-FJ>7e_nPD;iq*xIu{&u@H>`~>A@b<78%nt39uxP3l%Ad!dOMFV&u0U*BpG$D zC8~V+(LWHO-6xP#x8dd$p+5&6)WKH5LhjfmIVGCck3K+RL?0qK zYVRLi^ouF-Ci?R@>$AxXtDl53Dh7ac47YD)P-_kCi29NNI3UFee{-PhNDolvHgn=^ zY?U$?w+lC8u}m&*t6UM*;7_&U)7X|I-K>8XCgOuh++IeG7tN;5YhT-~?2%{WIgFbk zkc=4G=`c~=j_l-KEb0J@l_ohiRGx84m=-G-GD%Aiec@$QaH{q5F8?e$%b$E)>WIx& zjk#`)AAcax)k}Wb4EMUj^|dU;eDM+>XSAWrkcMRJYo5Pc zjppe}!pZxWcme32wc~7#)I&RQ9%;I2K1Dtu@3-yejdLI>uhCaS4QqiR4B=TeUMaI) z>GO`_*X#uf!U{g|D#OoLkex{WYa3ER->&tCk(;K6&f>5qBrvtx5+#|cX>H8fwAs1{ zkFv6#rI1Cot5!KWBS8AHhA;LWq<{2QY8r-l5sOJ=k6?I{9nPw>sHOscsS)rv=dinmUO zkqAlp?L(5Z#nI&laVo9RNIhL_Ze--PoUI;6(^i8LHGH<4pgEnA#1Z5i=`>7xF_B5S(ZN1!&?77!+L*g zVJz_E(dn(zTc`Jp7;8(ws(VT>>8 z1A}unQfQo)T2Gp!hr$8u4(>1B6CUH}3+JfScMdnXt4{wplH4JH*6cb)2!pnE)=YHisme6# znbpKZkBo3&SvZO|tw!Qxo9-taA_0KP^T#N(RndJ&JNd)Ch0zxe6Y6$+3+Q0qEge03 zcztu_Y&P0BM5ve2%cWO@QYf2idr_Wn&io0?_o*_ zr7|I{=kp_M$70ZytRe=CbL6YXX@xk_N{-_cOfoQxP;HcIM3eDbwzL+QZCh8@8 z#v4lTVHu6Nxt1m^K;3-+e&w5!heCGh(Z-|@A$b`%{|JUt^|5)l9OMehxYv+hAZt;s zX9=~-&(R^Ru(a6qHVP7LJ6DHTCO@QvWJH)8r{?$eHV#pr3K2&072sMIh8N_PUx0CA z>3YsNPs_PN5B=Oo6MD#^7}ker5(j9TZGyYqWq$z~y~bNc5EJ&(wr?8`CXD?A#+Ydj zMb=Eq0>(UDtNbO}jR!#o86SYykik05=XA$PSpH{o2M^__mMK3GF+m_`Byq62ixhDY zhLukxmVO8-L72#RlhTOP4FGi!f(2HEf;B#tHNp@_z*>DB0Kj~ZX63#dxRe$`v+z4U znsRUzwnm+ehus8QV9~N=YpJ)J$$S>xpyoTM^OL$r=AZrivQSIjFdqkzxz{K!`g{mk zy4;^sTOERsiz%iWHY$jNr@~QH|5snA7uh7h>I|m;?>aE+l_<7o8Q^G9&Ot&iB7Ik_ zmc(8IrKiX!Zsu53GSFhct8~^2)k5*7o)}w@6MBw*+V<)vfPqksez3Or%M8maz|k;_ zgpaM$5ON`{<2EvSua^44I}D~qTGgwH3t7-V=CVO;hj*|vXM(bhq7DUJk<`^OjoSi`3s9Lm-a%{PZ=piPd7>DtLdYKdD>Ggtqu__jS7jkU#c6+P=fjZ%od! z_y*v*MXGI#>4nm8)M)pl7zCH1cC@Xm;)yo{nqN3T$X?md;stTu3z?c9!x4HpwPy

FMfP4|Tn$}2 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 MRsaA13_|Vz09H$3z5oCK literal 0 Hc-jL100001 diff --git a/desktop/cups.svg b/desktop/cups.svg new file mode 100644 index 0000000000..8d19c358cb --- /dev/null +++ b/desktop/cups.svg @@ -0,0 +1,533 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + CUPS Icon + + + Michael Sweet + + + + + Apple Inc. + + + + + + + + + + + + + + + + + + + + diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000000..e2b224fc0c --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,260 @@ +# +# "$Id$" +# +# Documentation makefile for CUPS. +# +# Copyright 2007-2011 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +# +# Document files... +# + +WEBPAGES = \ + cups.css \ + cups-printable.css \ + index.html \ + robots.txt +WEBIMAGES = \ + images/color-wheel.png \ + images/cups.png \ + images/cups-icon.png \ + images/generic.png \ + images/left.gif \ + images/right.gif \ + images/sel.gif \ + images/unsel.gif \ + images/wait.gif +HELPIMAGES = \ + images/cups-block-diagram.png \ + images/cups-command-chain.png \ + images/cups-postscript-chain.png \ + images/cups-raster-chain.png \ + images/raster.png \ + images/raster-organization.png \ + images/sample-image.png \ + images/smiley.jpg +HELPFILES = \ + help/accounting.html \ + help/api-array.html \ + help/api-cgi.html \ + help/api-cups.html \ + help/api-driver.html \ + help/api-filedir.html \ + help/api-filter.html \ + help/api-httpipp.html \ + help/api-mime.html \ + help/api-overview.html \ + help/api-ppd.html \ + help/api-ppdc.html \ + help/api-raster.html \ + help/cgi.html \ + help/glossary.html \ + help/kerberos.html \ + help/license.html \ + help/man-cupsaccept.html \ + help/man-backend.html \ + help/man-cancel.html \ + help/man-cups-config.html \ + help/man-cups-lpd.html \ + help/man-cups-polld.html \ + help/man-cupsaddsmb.html \ + help/man-cupsd.html \ + help/man-cupsenable.html \ + help/man-cupstestdsc.html \ + help/man-cupstestppd.html \ + help/man-filter.html \ + help/man-lp.html \ + help/man-lpadmin.html \ + help/man-lpc.html \ + help/man-lpinfo.html \ + help/man-lpmove.html \ + help/man-lpoptions.html \ + help/man-lppasswd.html \ + help/man-lpq.html \ + help/man-lpr.html \ + help/man-lprm.html \ + help/man-lpstat.html \ + help/man-mime.convs.html \ + help/man-mime.types.html \ + help/man-notifier.html \ + help/man-ppdc.html \ + help/man-ppdhtml.html \ + help/man-ppdi.html \ + help/man-ppdmerge.html \ + help/man-ppdpo.html \ + help/network.html \ + help/options.html \ + help/overview.html \ + help/policies.html \ + help/postscript-driver.html \ + help/ppd-compiler.html \ + help/raster-driver.html \ + help/ref-access_log.html \ + help/ref-classes-conf.html \ + help/ref-client-conf.html \ + help/ref-cupsd-conf.html \ + help/ref-error_log.html \ + help/ref-mailto-conf.html \ + help/ref-page_log.html \ + help/ref-ppdcfile.html \ + help/ref-printers-conf.html \ + help/ref-snmp-conf.html \ + help/ref-subscriptions-conf.html \ + help/security.html \ + help/sharing.html \ + help/spec-banner.html \ + help/spec-browsing.html \ + help/spec-cmp.html \ + help/spec-command.html \ + help/spec-design.html \ + help/spec-ipp.html \ + help/spec-pdf.html \ + help/spec-postscript.html \ + help/spec-ppd.html \ + help/spec-raster.html \ + help/spec-stp.html \ + help/standard.html \ + help/translation.html \ + help/whatsnew.html + + +# +# Make all documents... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Remove all generated files... +# + +clean: + + +# +# Dummy depend target... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: $(INSTALL_LANGUAGES) + $(INSTALL_DIR) -m 755 $(DOCDIR) + for file in $(WEBPAGES); do \ + $(INSTALL_MAN) $$file $(DOCDIR); \ + done + $(INSTALL_DIR) -m 755 $(DOCDIR)/help + for file in $(HELPFILES); do \ + $(INSTALL_MAN) $$file $(DOCDIR)/help; \ + done + $(INSTALL_DIR) -m 755 $(DOCDIR)/images + for file in $(WEBIMAGES) $(HELPIMAGES); do \ + $(INSTALL_MAN) $$file $(DOCDIR)/images; \ + done + +install-languages: + for lang in $(LANGUAGES); do \ + if test -d $$lang; then \ + $(INSTALL_DIR) -m 755 $(DOCDIR)/$$lang; \ + $(INSTALL_DATA) $$lang/index.html $(DOCDIR)/$$lang; \ + $(INSTALL_DATA) $$lang/cups.css $(DOCDIR)/$$lang >/dev/null 2>&1 || true; \ + fi; \ + done + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall all documentation files... +# + +uninstall: $(UNINSTALL_LANGUAGES) + for file in $(WEBPAGES); do \ + $(RM) $(DOCDIR)/$$file; \ + done + for file in $(HELPFILES); do \ + $(RM) $(DOCDIR)/$$file; \ + done + for file in $(WEBIMAGES); do \ + $(RM) $(DOCDIR)/$$file; \ + done + -$(RMDIR) $(DOCDIR)/images + -$(RMDIR) $(DOCDIR)/help + -$(RMDIR) $(DOCDIR) + +uninstall-languages: + -for lang in $(LANGUAGES); do \ + $(RM) $(DOCDIR)/$$lang/index.html; \ + $(RM) $(DOCDIR)/$$lang/cups.css; \ + $(RMDIR) $(DOCDIR)/$$lang; \ + done + + +# +# Install the docset bits locally... +# + +docset: + cp $(HELPFILES) ../org.cups.docset/Contents/Resources/Documentation/help + cp cups-printable.css ../org.cups.docset/Contents/Resources/Documentation + cp $(HELPIMAGES) ../org.cups.docset/Contents/Resources/Documentation/images + + +# +# End of Makefile. +# diff --git a/doc/cups-printable.css b/doc/cups-printable.css new file mode 100644 index 0000000000..cc11262fde --- /dev/null +++ b/doc/cups-printable.css @@ -0,0 +1,327 @@ +BODY { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; +} + +H1, H2, H3, H4, H5, H6, P, TD, TH { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; +} + +KBD { + font-family: monaco, courier, monospace; + font-weight: bold; +} + +PRE { + font-family: monaco, courier, monospace; +} + +PRE.command { + margin-left: 36pt; +} + +P.compact { + margin: 0; +} + +P.example { + font-style: italic; + margin-left: 36pt; +} + +PRE.example { + background: #eeeeee; + border: dotted thin #999999; + margin-left: 36pt; + padding: 10pt; +} + +PRE.command EM, PRE.example EM { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; +} + +P.command { + font-family: monaco, courier, monospace; + margin-left: 36pt; +} + +P.formula { + font-style: italic; + margin-left: 36pt; +} + +BLOCKQUOTE { + background: #eeeeee; + border: solid thin #999999; + padding: 10pt; +} + +A IMG { + border: none; +} + +A:link:hover IMG { + background: #f0f0f0; + border-radius: 10px; + -moz-border-radius: 10px; +} + +A:link, A:visited { + font-weight: normal; + text-decoration: none; +} + +A:link:hover, A:visited:hover, A:active { + text-decoration: underline; +} + +SUB, SUP { + font-size: 50%; +} + +TR.data, TD.data, TR.data TD { + margin-top: 10pt; + padding: 5pt; + border-bottom: solid 1pt #999999; +} + +TR.data TH { + border-bottom: solid 1pt #999999; + padding-top: 10pt; + padding-left: 5pt; + text-align: left; +} + +DIV.table TABLE { + border: solid thin #999999; + border-collapse: collapse; + border-spacing: 0; + margin-left: auto; + margin-right: auto; +} + +DIV.table CAPTION { + caption-side: top; + font-size: 120%; + font-style: italic; + font-weight: bold; + margin-left: auto; + margin-right: auto; +} + +DIV.table TABLE TD { + border: solid thin #cccccc; + padding-top: 5pt; +} + +DIV.table TABLE TH { + background: #cccccc; + border: none; + border-bottom: solid thin #999999; +} + +DIV.figure TABLE { + margin-left: auto; + margin-right: auto; +} + +DIV.figure CAPTION { + caption-side: bottom; + font-size: 120%; + font-style: italic; + font-weight: bold; + margin-left: auto; + margin-right: auto; +} + +TH.label { + text-align: right; + vertical-align: top; +} + +TH.sublabel { + text-align: right; + font-weight: normal; +} + +HR { + border: solid thin; +} + +SPAN.info { + background: black; + border: thin solid black; + color: white; + font-size: 80%; + font-style: italic; + font-weight: bold; + white-space: nowrap; +} + +H2 SPAN.info, H3 SPAN.info, H4 SPAN.info { + float: right; + font-size: 100%; +} + +H1.title { +} + +H2.title, H3.title { + border-bottom: solid 2pt #000000; +} + +DIV.indent, TABLE.indent { + margin-top: 2em; + margin-left: auto; + margin-right: auto; + width: 90%; +} + +TABLE.indent { + border-collapse: collapse; +} + +TABLE.indent TD, TABLE.indent TH { + padding: 0; +} + +TABLE.list { + border-collapse: collapse; + margin-left: auto; + margin-right: auto; + width: 90%; +} + +TABLE.list TH { + background: white; + border-bottom: solid thin #cccccc; + color: #444444; + padding-top: 10pt; + padding-left: 5pt; + text-align: left; + vertical-align: bottom; + white-space: nowrap; +} + +TABLE.list TH A { + color: #4444cc; +} + +TABLE.list TD { + border-bottom: solid thin #eeeeee; + padding-top: 5pt; + padding-left: 5pt; +} + +TABLE.list TR:nth-child(even) { + background: #f8f8f8; +} + +TABLE.list TR:nth-child(odd) { + background: #f4f4f4; +} + +DT { + margin-left: 36pt; + margin-top: 12pt; +} + +DD { + margin-left: 54pt; +} + +DL.category DT { + font-weight: bold; +} + +P.summary { + margin-left: 36pt; + font-family: monaco, courier, monospace; +} + +DIV.summary TABLE { + border: solid thin #999999; + border-collapse: collapse; + border-spacing: 0; + margin: 10px; +} + +DIV.summary TABLE TD, DIV.summary TABLE TH { + border: solid thin #999999; + padding: 5px; + text-align: left; + vertical-align: top; +} + +DIV.summary TABLE THEAD TH { + background: #eeeeee; +} + +/* API documentation styles... */ +div.body h1 { + margin: 0; +} +div.body h2 { + margin-top: 1.5em; +} +div.body h3, div.body h4, div.body h5 { + margin-bottom: 0.5em; + margin-top: 1.5em; +} +.class, .enumeration, .function, .struct, .typedef, .union { + border-bottom: solid thin #999999; + margin-bottom: 0; + margin-top: 2em; +} +.description { + margin-top: 0.5em; +} +code, p.code, pre, ul.code li { + font-family: monaco, courier, monospace; + font-size: 90%; +} +ul.code, ul.contents, ul.subcontents { + list-style-type: none; + margin: 0; + padding-left: 0; +} +ul.code li { + margin: 0; +} +ul.contents > li { + margin-top: 1em; +} +ul.contents li ul.code, ul.contents li ul.subcontents { + padding-left: 2em; +} +div.body dl { + margin-left: 0; + margin-top: 0; +} +div.body dt { + font-style: italic; + margin-left: 0; + margin-top: 0; +} +div.body dd { + margin-bottom: 0.5em; +} + +/* This is just for the HTML files generated with the framedhelp target */ +div.contents { + background: #e8e8e8; + border: solid thin black; + padding: 10px; +} +div.contents h1 { + font-size: 110%; +} +div.contents h2 { + font-size: 100%; +} +div.contents ul.contents { + font-size: 80%; +} +div.contents ul.subcontents li { + margin-left: 1em; + text-indent: -1em; +} diff --git a/doc/cups.css b/doc/cups.css new file mode 100644 index 0000000000..51c4f4c327 --- /dev/null +++ b/doc/cups.css @@ -0,0 +1,459 @@ +BODY { + background: white; + color: black; + font-family: lucida grande, geneva, helvetica, arial, sans-serif; +} + +H1, H2, H3, H4, H5, H6, P, TD, TH { + font-family: lucida grande, geneva, helvetica, arial, sans-serif; +} + +KBD { + color: #006600; + font-family: monaco, courier, monospace; + font-weight: bold; +} + +PRE { + font-family: monaco, courier, monospace; +} + +PRE.command { + color: #7f0000; + margin-left: 36pt; +} + +P.example { + font-style: italic; + margin-left: 36pt; +} + +PRE.example { + background: white; + border: dotted thin #999999; + margin-left: 36pt; + padding: 10px; +} + +PRE.command EM, PRE.example EM { + color: #3f0000; + font-family: lucida grande, geneva, helvetica, arial, sans-serif; +} + +P.command { + color: #7f0000; + font-family: monaco, courier, monospace; + margin-left: 36pt; +} + +P.formula { + font-style: italic; + margin-left: 36pt; +} + +BLOCKQUOTE { + background: #f0f0f0; + border: inset 1px #eeeeee; + padding: 10px; + /* These are not implemented by all browsers, but that's OK */ + border-radius: 5px; + -moz-border-radius: 5px; +} + +A IMG { + border: none; +} + +A:link:hover IMG { + background: #f0f0f0; + border-radius: 10px; + -moz-border-radius: 10px; +} + +A:link, A:visited { + font-weight: inherit; + text-decoration: none; + color: #000099; +} + +A:link:hover, A:visited:hover, A:active { + text-decoration: underline; + color: #990099; +} + +TABLE.page { + border: none; + border-collapse: collapse; + height: 100%; + margin: 0; + padding: 0; + width: 100%; +} + +TD.body { + height: 100%; + vertical-align: top; +} + +TD.sel, TD.unsel { + border-left: thin solid #cccccc; + padding: 0px 5px; + text-align: center; + vertical-align: middle; + width: 14%; +} + +TD.sel { + background: url(images/sel.gif); +} + +TD.unsel { + background: url(images/unsel.gif); +} + +TD.sel A, TD.sel A:hover, TD.unsel A:link:hover, TD.unsel A:visited:hover, +TD.unsel A:active, TD.unsel A, TD.unsel A:visited { + color: #666666; + display: block; + font-weight: normal; + padding: 8px; + text-decoration: none; +} + +TD.trailer { + background: #f0f0f0; + border: solid thin #e0e0e0; + color: #666666; + font-size: 80%; + padding: 5px; +} + +TD.trailer A { + color: #666699; +} + +FORM { + display: inline; +} + +INPUT[TYPE="TEXT"], TEXTAREA { + font-family: monaco, courier, monospace; +} + +INPUT[TYPE="IMAGE"] { + border: none; + padding: 2pt; + vertical-align: bottom; +} + +SUB, SUP { + font-size: 50%; +} + +TR.data, TD.data, TR.data TD { + margin-top: 10pt; + padding: 5pt; + border-bottom: solid 1pt #999999; +} + +TR.data TH { + border-bottom: solid 1pt #999999; + padding-top: 10pt; + padding-left: 5pt; + text-align: left; +} + +DIV.table TABLE { + border: solid thin #999999; + border-collapse: collapse; + border-spacing: 0; + margin-left: auto; + margin-right: auto; +} + +DIV.table CAPTION { + caption-side: top; + font-size: 120%; + font-style: italic; + font-weight: bold; + margin-left: auto; + margin-right: auto; +} + +DIV.table TABLE TD { + background: white; + border: solid thin #bbbbbb; + padding-top: 5pt; +} + +DIV.table TABLE TH { + background: #f0f0f0; + border: none; + border-bottom: solid thin #999999; +} + +DIV.figure TABLE { + margin-left: auto; + margin-right: auto; +} + +DIV.figure CAPTION { + caption-side: bottom; + font-size: 120%; + font-style: italic; + font-weight: bold; + margin-left: auto; + margin-right: auto; +} + +TH.label { + text-align: right; + vertical-align: top; +} + +TH.sublabel { + text-align: right; + font-weight: normal; +} + +HR { + border: solid thin; +} + +SPAN.info { + background: black; + border: thin solid black; + color: white; + font-size: 80%; + font-style: italic; + font-weight: bold; + white-space: nowrap; +} + +H2 SPAN.info, H3 SPAN.info, H4 SPAN.info { + float: right; + font-size: 100%; +} + +.conflict { + background: red; + color: white; +} + +TH.conflict { + text-align: right; +} + +H1.title { + display: none; +} + +H2.title, H3.title { + border-bottom: solid 1pt #999999; +} + +DIV.indent, TABLE.indent { + margin-top: 2em; + margin-left: auto; + margin-right: auto; + width: 90%; +} + +TABLE.indent { + border-collapse: collapse; +} + +TABLE.indent TD, TABLE.indent TH { + padding: 0; +} + +TABLE.list { + border-collapse: collapse; + margin-left: auto; + margin-right: auto; + width: 90%; +} + +TABLE.list TH { + background: white; + border-bottom: solid thin #cccccc; + color: #444444; + padding-top: 10pt; + padding-left: 5pt; + text-align: left; + vertical-align: bottom; + white-space: nowrap; +} + +TABLE.list TH A { + color: #4444cc; +} + +TABLE.list TD { + border-bottom: solid thin #eeeeee; + padding-top: 5pt; + padding-left: 5pt; +} + +TABLE.list TR:nth-child(even) { + background: #f8f8f8; +} + +TABLE.list TR:nth-child(odd) { + background: #f4f4f4; +} + +DIV.sidebar { + float: right; + min-width: 25%; + margin-left: 10px; + max-width: 33%; +} + +DIV.sidebar P.l0 { + margin-bottom: 0; + margin-left: 0; + margin-right: 0; + margin-top: 12pt; +} + +DIV.sidebar P.l1 { + margin-bottom: 0; + margin-left: 36pt; + margin-right: 0; + margin-top: 0; + text-indent: -18pt; +} + +DIV.sidebar P.l2 { + font-style: italic; + margin-bottom: 0; + margin-left: 54pt; + margin-right: 0; + margin-top: 0; + text-indent: -18pt; +} + +TABLE.inset { + background: #f0f0f0; + border: thin solid #e0e0e0; + margin-top: 1em; + padding: 0; + width: 100%; + /* These are not implemented by all browsers, but that's OK */ + border-radius: 5px; + -moz-border-radius: 5px; +} + +TABLE.inset CAPTION { + caption-side: top; + color: #666666; + font-size: 80%; + margin-left: 10px; + margin-bottom: 2px; + text-align: left; +} + +TABLE.inset TD { + padding: 2px; +} + +DT { + margin-left: 36pt; + margin-top: 12pt; +} + +DD { + margin-left: 54pt; +} + +DL.category DT { + font-weight: bold; +} + +P.summary { + margin-left: 36pt; + font-family: monaco, courier, monospace; +} + +DIV.summary TABLE { + border: solid thin #999999; + border-collapse: collapse; + border-spacing: 0; + margin: 10px; +} + +DIV.summary TABLE TD, DIV.summary TABLE TH { + background: white; + border: solid thin #999999; + border-spacing: 0; + padding: 5px; + text-align: left; + vertical-align: top; +} + +DIV.summary TABLE THEAD TH { + background: #f0f0f0; +} + +DIV.tabs { + height: 480px; + overflow: hidden; +} + +DIV.tab { + float: left; + height: 100%; + overflow-y: auto; + width: 100%; +} + +/* API documentation styles... */ +div.body h1 { + margin: 0; +} +div.body h2 { + margin-top: 1.5em; +} +div.body h3, div.body h4, div.body h5 { + margin-bottom: 0.5em; + margin-top: 1.5em; +} +.class, .enumeration, .function, .struct, .typedef, .union { + border-bottom: solid thin #999999; + margin-bottom: 0; + margin-top: 2em; +} +.description { + margin-top: 0.5em; +} +code, p.code, pre, ul.code li { + font-family: monaco, courier, monospace; + font-size: 90%; +} +ul.code, ul.contents, ul.subcontents { + list-style-type: none; + margin: 0; + padding-left: 0; +} +ul.code li { + margin: 0; +} +ul.contents > li { + margin-top: 1em; +} +ul.contents li ul.code, ul.contents li ul.subcontents { + padding-left: 2em; +} +div.body dl { + margin-left: 0; + margin-top: 0; +} +div.body dt { + font-style: italic; + margin-left: 0; + margin-top: 0; +} +div.body dd { + margin-bottom: 0.5em; +} diff --git a/doc/de/index.html.in b/doc/de/index.html.in new file mode 100644 index 0000000000..a73d771796 --- /dev/null +++ b/doc/de/index.html.in @@ -0,0 +1,107 @@ + + + + + Home - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Startseite    Verwaltung    Klassen    Online- Hilfe    Aufträge    Drucker  
+ + + + + +
+ +

Common UNIX Printing System @CUPS_VERSION@

+ +

CUPS ist das auf Standards basierte, Opensource-Drucksystem, welches von +Apple Inc. für Mac OS® X und +andere UNIX®-ähnliche Betriebssysteme entwickelt wird.

+ +
CUPS
+ + + +
+ +

CUPS für Benutzer

+ +

CUPS.Übersicht

+ +

Kommandozeilendruck und Einstellungen

+ +

Neues in CUPS 1.4

+ +

Benutzerforum

+ +
+ +

CUPS für Administratoren

+ +

Drucker und Klassen hinzufügen

+ +

Betriebsrichtlinien verwalten

+ +

Basiswissen Druckabrechnung

+ +

Sicherheit des Servers

+ +

Verwenden der Kerberos Authentifizierung

+ +

Benutzen von Netzwerkdruckern

+ +

cupsd.conf Referenz

+ +

Druckertreiber finden

+ +
+ +

CUPS für Entwickler

+ +

Einführung in die CUPS-Programmierung

+ +

CUPS-API

+ +

Filter- und Backend-Programmierung

+ +

HTTP- und IPP-APIs

+ +

PPD-API

+ +

Raster-API

+ +

PPD Compiler Driver Information File Reference

+ +

Entwicklerforum

+ +
+ +
 
CUPS und das CUPS Logo sind +eingetragene Warenzeichen der Apple Inc. +CUPS ist urheberrechtlich geschützt 2007-2011 von Apple Inc, alle Rechte vorbehalten.
+ + diff --git a/doc/es/index.html.in b/doc/es/index.html.in new file mode 100755 index 0000000000..5afb0d0c05 --- /dev/null +++ b/doc/es/index.html.in @@ -0,0 +1,107 @@ + + + + + Inicio - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Inicio    Administración    Clases    Ayuda en línea    Trabajos    Impresoras  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS es el sistema de impresión de código abierto basado en +estándares desarrollado por Apple Inc. para Mac +OS® X y otros sistemas operativos tipo UNIX®.

+ +
CUPS
+ + + +
+ +

CUPS para usuarios

+ +

Descripción de CUPS

+ +

Impresión desde la línea de comandos y opciones

+ +

Qué hay de nuevo en CUPS 1.4

+ +

Foro de usuarios

+ +
+ +

CUPS para administradores

+ +

Añadiendo impresoras y clases

+ +

Gestionando políticas de funcionamiento

+ +

Contabilidad básica de impresora

+ +

Seguridad del servidor

+ +

Usando autentificación Kerberos

+ +

Usando impresoras de red

+ +

Referencia de cupsd.conf

+ +

Encontrar controladores de impresora

+ +
+ +

CUPS para desarrolladores

+ +

Introducción a la programación de CUPS

+ +

La API de CUPS

+ +

Programación de filtros y programas de conexión

+ +

Las APIs HTTP e IPP

+ +

La API PPD

+ +

La API Raster

+ +

Referencia del archivo de información del compilador de controladores PPD

+ +

Foro de desarrollo

+ +
+ +
 
CUPS y el logo de CUPS son +marcas registradas de Apple Inc. Los derechos +de copia de CUPS 2007-2011 son de Apple Inc. Todos los derechos reservados.
+ + diff --git a/doc/eu/index.html.in b/doc/eu/index.html.in new file mode 100644 index 0000000000..5b79b6ae25 --- /dev/null +++ b/doc/eu/index.html.in @@ -0,0 +1,106 @@ + + + + + Hasiera - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Hasiera    Administrazioa    Klaseak    Lineako laguntza    Lanak    Inprimagailuak  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

Apple Inc.-ek Mac OS® X eta +beste UNIX® bezalako sistema eragileentzako iturburu irekiko +inprimatzeko sisteman oinarrituta dago.

+ +
CUPS
+ + + +
+ +

CUPS erabiltzaileentzako

+ +

CUPSen gainbegiraketa

+ +

Komando-lerroaren bidez inprimatzea eta aukerak

+ +

CUPS 1.4 bertsioak dakartzan berrikuntza.

+ +

Erabiltzaileen foroa

+ +
+ +

CUPS administratzaileentzako

+ +

Inprimagailuak eta klaseak gehitzea

+ +

Kudeaketako eragiketen politikak

+ +

Inprimagailuaren oinarrizko kontabilitatea

+ +

Zerbitzariaren segurtasuna

+ +

Kerberos autentifikazioa erabiltzea

+ +

Sareko inprimagailuak erabiltzea

+ +

cupsd.conf erreferentzia

+ +

Bilatu inprimagailuaren kontrolatzaileak

+ +
+ +

CUPS garatzaileentzako

+ +

Sarrera CUPSen programaziora

+ +

CUPSen APIa

+ +

Iragazkien eta atzeko planoan programatzeea

+ +

HTTP eta IPP APIak

+ +

PPD APIa

+ +

Bilbearen APIa

+ +

PPD kontrolatzaileen konpilatzailearen informazioaren fitxategiaren erreferentzia

+ +

Garatzaileen forua

+ +
+ +
 
CUPS eta CUPSen logotipoa Apple Inc. en marka erregistratuak dira. +CUPSen copyright-a 2007-2011 Apple Inc. Eskubide guztiak gordeta.
+ + diff --git a/doc/help/accounting.html b/doc/help/accounting.html new file mode 100644 index 0000000000..66c34ec1f3 --- /dev/null +++ b/doc/help/accounting.html @@ -0,0 +1,62 @@ + + + + Printer Accounting Basics + + + + +

Printer Accounting Basics

+ +

CUPS supports a variety of printer accounting schemes. Aside from the +built-in quota and page logging +support, there are several third-party solutions that can be found on +www.cups.org.

+ + +

Quota Support

+ +

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

+ +

The job-k-limit, job-page-limit, and job-quota-period +options determine whether and how quotas are enforced for a printer. +The job-quota-period 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 +job-k-limit option specifies the job size limit in killobytes. The +job-page-limit option specifies the number of pages limit.

+ +

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 +weekly quotas with the given size and page count limits:

+ +
+/usr/sbin/lpadmin -p printer -o job-quota-period=604800 \
+    -o job-k-limit=1024 ENTER
+/usr/sbin/lpadmin -p printer -o job-quota-period=604800 \
+    -o job-page-limit=100 ENTER
+
+ +

Or, you can combine all three options on the same line.

+ +

While there is no way to query the current quota state for a particular +user, any application can request a list of jobs for a user and printer that +can be used to easily determine that information.

+ + +

Page Logging

+ +

CUPS logs every page that is printed on a system to the +page_log file. Page logging +is only available for drivers that provide page accounting information, +typically all PostScript and CUPS raster devices. Raw queues and queues +using third-party solutions such as Foomatic generally do not have +useful page accounting information available.

+ + + + diff --git a/doc/help/api-array.html b/doc/help/api-array.html new file mode 100644 index 0000000000..8d38149566 --- /dev/null +++ b/doc/help/api-array.html @@ -0,0 +1,983 @@ + + + + +Array API + + + + + +
+ + +

Array API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/array.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • + + +

      Overview

      + +

      The CUPS array API provides a high-performance generic array container. +The contents of the array container can be sorted and the container itself is +designed for optimal speed and memory usage under a wide variety of conditions. +Sorted arrays use a binary search algorithm from the last found or inserted +element to quickly find matching elements in the array. Arrays created with the +optional hash function can often find elements with a single lookup. The +cups_array_t type is used when +referring to a CUPS array.

      + +

      The CUPS scheduler (cupsd) and many of the CUPS API +functions use the array API to efficiently manage large lists of +data.

      + +

      Managing Arrays

      + +

      Arrays are created using either the +cupsArrayNew or +cupsArrayNew2 functions. The +first function creates a new array with the specified callback function +and user data pointer:

      + +
      +#include <cups/array.h>
      +
      +static int compare_func(void *first, void *second, void *user_data);
      +
      +void *user_data;
      +cups_array_t *array = cupsArrayNew(compare_func, user_data);
      +
      + +

      The comparison function (type +cups_arrayfunc_t) is called +whenever an element is added to the array and can be NULL to +create an unsorted array. The function returns -1 if the first element should +come before the second, 0 if the first and second elements should have the same +ordering, and 1 if the first element should come after the second.

      + +

      The "user_data" pointer is passed to your comparison function. Pass +NULL if you do not need to associate the elements in your array +with additional information.

      + +

      The cupsArrayNew2 function adds +two more arguments to support hashed lookups, which can potentially provide +instantaneous ("O(1)") lookups in your array:

      + +
      +#include <cups/array.h>
      +
      +#define HASH_SIZE 512 /* Size of hash table */
      +
      +static int compare_func(void *first, void *second, void *user_data);
      +static int hash_func(void *element, void *user_data);
      +
      +void *user_data;
      +cups_array_t *array = cupsArrayNew2(compare_func, user_data, hash_func, HASH_SIZE);
      +
      + +

      The hash function (type +cups_ahash_func_t) should return a +number from 0 to (hash_size-1) that (hopefully) uniquely identifies the +element and is called whenever you look up an element in the array with +cupsArrayFind. The hash size is +only limited by available memory, but generally should not be larger than +16384 to realize any performance improvement.

      + +

      Once you have created the array, you add elements using the +cupsArrayAdd +cupsArrayInsert functions. +The first function adds an element to the array, adding the new element +after any elements that have the same order, while the second inserts the +element before others with the same order. For unsorted arrays, +cupsArrayAdd appends the element to +the end of the array while +cupsArrayInsert inserts the +element at the beginning of the array. For example, the following code +creates a sorted array of character strings:

      + +
      +#include <cups/array.h>
      +
      +/* Use strcmp() to compare strings - it will ignore the user_data pointer */
      +cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
      +
      +/* Add four strings to the array */
      +cupsArrayAdd(array, "One Fish");
      +cupsArrayAdd(array, "Two Fish");
      +cupsArrayAdd(array, "Red Fish");
      +cupsArrayAdd(array, "Blue Fish");
      +
      + +

      Elements are removed using the +cupsArrayRemove function, for +example:

      + +
      +#include <cups/array.h>
      +
      +/* Use strcmp() to compare strings - it will ignore the user_data pointer */
      +cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
      +
      +/* Add four strings to the array */
      +cupsArrayAdd(array, "One Fish");
      +cupsArrayAdd(array, "Two Fish");
      +cupsArrayAdd(array, "Red Fish");
      +cupsArrayAdd(array, "Blue Fish");
      +
      +/* Remove "Red Fish" */
      +cupsArrayRemove(array, "Red Fish");
      +
      + +

      Finally, you free the memory used by the array using the +cupsArrayDelete function. All +of the memory for the array and hash table (if any) is freed, however CUPS +does not free the elements - if necessary, you must allocate and free the +elements yourself.

      + +

      Finding and Enumerating Elements

      + +

      CUPS provides several functions to find and enumerate elements in an +array. Each one sets or updates a "current index" into the array, such that +future lookups will start where the last one left off:

      + +
      +
      cupsArrayFind
      +
      Returns the first matching element.
      +
      cupsArrayFirst
      +
      Returns the first element in the array.
      +
      cupsArrayIndex
      +
      Returns the Nth element in the array, starting at 0.
      +
      cupsArrayLast
      +
      Returns the last element in the array.
      +
      cupsArrayNext
      +
      Returns the next element in the array.
      +
      cupsArrayPrev
      +
      Returns the previous element in the array.
      +
      + +

      Each of these functions returns NULL when there is no +corresponding element. For example, a simple for loop using the +cupsArrayFirst and +cupsArrayNext functions will +enumerate all of the strings in our previous example:

      + +
      +#include <cups/array.h>
      +
      +/* Use strcmp() to compare strings - it will ignore the user_data pointer */
      +cups_array_t *array = cupsArrayNew((cups_array_func_t)strcmp, NULL);
      +
      +/* Add four strings to the array */
      +cupsArrayAdd(array, "One Fish");
      +cupsArrayAdd(array, "Two Fish");
      +cupsArrayAdd(array, "Red Fish");
      +cupsArrayAdd(array, "Blue Fish");
      +
      +/* Show all of the strings in the array */
      +char *s;
      +for (s = (char *)cupsArrayFirst(array); s != NULL; s = (char *)cupsArrayNext(array))
      +  puts(s);
      +
      +

      Functions

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayAdd

      +

      Add an element to the array.

      +

      +int cupsArrayAdd (
      +    cups_array_t *a,
      +    void *e
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      e
      +
      Element
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      When adding an element to a sorted array, non-unique elements are +appended at the end of the run of identical elements. For unsorted arrays, +the element is appended to the end of the array. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayClear

      +

      Clear the array.

      +

      +void cupsArrayClear (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Discussion

      +

      This function is equivalent to removing all elements in the array. +The caller is responsible for freeing the memory used by the +elements themselves. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayCount

      +

      Get the number of elements in the array.

      +

      +int cupsArrayCount (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Number of elements

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayCurrent

      +

      Return the current element in the array.

      +

      +void *cupsArrayCurrent (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Element

      +

      Discussion

      +

      The current element is undefined until you call cupsArrayFind, +cupsArrayFirst, or cupsArrayIndex, or cupsArrayLast. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayDelete

      +

      Free all memory used by the array.

      +

      +void cupsArrayDelete (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Discussion

      +

      The caller is responsible for freeing the memory used by the +elements themselves. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayDup

      +

      Duplicate the array.

      +

      +cups_array_t *cupsArrayDup (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Duplicate array

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayFind

      +

      Find an element in the array.

      +

      +void *cupsArrayFind (
      +    cups_array_t *a,
      +    void *e
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      e
      +
      Element
      +
      +

      Return Value

      +

      Element found or NULL

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayFirst

      +

      Get the first element in the array.

      +

      +void *cupsArrayFirst (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      First element or NULL if the array is empty

      +

       CUPS 1.3/Mac OS X 10.5 cupsArrayGetIndex

      +

      Get the index of the current element.

      +

      +int cupsArrayGetIndex (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Index of the current element, starting at 0

      +

      Discussion

      +

      The current element is undefined until you call cupsArrayFind, +cupsArrayFirst, or cupsArrayIndex, or cupsArrayLast. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsArrayGetInsert

      +

      Get the index of the last inserted element.

      +

      +int cupsArrayGetInsert (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Index of the last inserted element, starting at 0

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayIndex

      +

      Get the N-th element in the array.

      +

      +void *cupsArrayIndex (
      +    cups_array_t *a,
      +    int n
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      n
      +
      Index into array, starting at 0
      +
      +

      Return Value

      +

      N-th element or NULL

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayInsert

      +

      Insert an element in the array.

      +

      +int cupsArrayInsert (
      +    cups_array_t *a,
      +    void *e
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      e
      +
      Element
      +
      +

      Return Value

      +

      0 on failure, 1 on success

      +

      Discussion

      +

      When inserting an element in a sorted array, non-unique elements are +inserted at the beginning of the run of identical elements. For unsorted +arrays, the element is inserted at the beginning of the array. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayLast

      +

      Get the last element in the array.

      +

      +void *cupsArrayLast (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Last element or NULL if the array is empty

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayNew

      +

      Create a new array.

      +

      +cups_array_t *cupsArrayNew (
      +    cups_array_func_t f,
      +    void *d
      +);

      +

      Parameters

      +
      +
      f
      +
      Comparison function or NULL for an unsorted array
      +
      d
      +
      User data pointer or NULL
      +
      +

      Return Value

      +

      Array

      +

      Discussion

      +

      The comparison function ("f") is used to create a sorted array. The function +receives pointers to two elements and the user data pointer ("d") - the user +data pointer argument can safely be omitted when not required so functions +like strcmp can be used for sorted string arrays. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsArrayNew2

      +

      Create a new array with hash.

      +

      +cups_array_t *cupsArrayNew2 (
      +    cups_array_func_t f,
      +    void *d,
      +    cups_ahash_func_t h,
      +    int hsize
      +);

      +

      Parameters

      +
      +
      f
      +
      Comparison function or NULL for an unsorted array
      +
      d
      +
      User data or NULL
      +
      h
      +
      Hash function or NULL for unhashed lookups
      +
      hsize
      +
      Hash size (>= 0)
      +
      +

      Return Value

      +

      Array

      +

      Discussion

      +

      The comparison function ("f") is used to create a sorted array. The function +receives pointers to two elements and the user data pointer ("d") - the user +data pointer argument can safely be omitted when not required so functions +like strcmp can be used for sorted string arrays.
      +
      +The hash function ("h") is used to implement cached lookups with the +specified hash size ("hsize"). + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayNext

      +

      Get the next element in the array.

      +

      +void *cupsArrayNext (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Next element or NULL

      +

      Discussion

      +

      This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) + 1)".
      +
      +The next element is undefined until you call cupsArrayFind, +cupsArrayFirst, or cupsArrayIndex, or cupsArrayLast +to set the current element. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayPrev

      +

      Get the previous element in the array.

      +

      +void *cupsArrayPrev (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      Previous element or NULL

      +

      Discussion

      +

      This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) - 1)".
      +
      +The previous element is undefined until you call cupsArrayFind, +cupsArrayFirst, or cupsArrayIndex, or cupsArrayLast +to set the current element. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayRemove

      +

      Remove an element from the array.

      +

      +int cupsArrayRemove (
      +    cups_array_t *a,
      +    void *e
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      e
      +
      Element
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      If more than one element matches "e", only the first matching element is +removed.
      +
      +The caller is responsible for freeing the memory used by the +removed element. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayRestore

      +

      Reset the current element to the last cupsArraySave.

      +

      +void *cupsArrayRestore (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      New current element

      +

       CUPS 1.2/Mac OS X 10.5 cupsArraySave

      +

      Mark the current element for a later cupsArrayRestore.

      +

      +int cupsArraySave (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      The current element is undefined until you call cupsArrayFind, +cupsArrayFirst, or cupsArrayIndex, or cupsArrayLast +to set the current element.
      +
      +The save/restore stack is guaranteed to be at least 32 elements deep. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsArrayUserData

      +

      Return the user data for an array.

      +

      +void *cupsArrayUserData (
      +    cups_array_t *a
      +);

      +

      Parameters

      +
      +
      a
      +
      Array
      +
      +

      Return Value

      +

      User data

      +

      Data Types

      +

      cups_ahash_func_t

      +

      Array hash function

      +

      +typedef int (*cups_ahash_func_t)(void *element, void *data); +

      +

      cups_array_func_t

      +

      Array comparison function

      +

      +typedef int (*cups_array_func_t)(void *first, void *second, void *data); +

      +

      cups_array_t

      +

      CUPS array type

      +

      +typedef struct _cups_array_s cups_array_t; +

      +
+ + diff --git a/doc/help/api-cgi.html b/doc/help/api-cgi.html new file mode 100644 index 0000000000..5a0a99e66c --- /dev/null +++ b/doc/help/api-cgi.html @@ -0,0 +1,1123 @@ + + + + +CGI API + + + + + +
+ + +

CGI API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/cgi.h
Library-lcupscgi
See AlsoProgramming: Introduction to CUPS Programming
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • + + +

      Overview

      + +

      The CGI API provides Common Gateway Interface functions for CUPS.

      +

      Functions

      +

      cgiCheckVariables

      +

      Check for the presence of "required" variables.

      +

      +int cgiCheckVariables (
      +    const char *names
      +);

      +

      Parameters

      +
      +
      names
      +
      Variables to look for
      +
      +

      Return Value

      +

      1 if all variables present, 0 otherwise

      +

      Discussion

      +

      Names may be separated by spaces and/or commas.

      +

      cgiClearVariables

      +

      Clear all form variables.

      +

      +void cgiClearVariables (void);

      +

      cgiCompileSearch

      +

      Compile a search string.

      +

      +void *cgiCompileSearch (
      +    const char *query
      +);

      +

      Parameters

      +
      +
      query
      +
      Query string
      +
      +

      Return Value

      +

      Search context

      +

      cgiCopyTemplateFile

      +

      Copy a template file and replace all the +'{variable}' strings with the variable value.

      +

      +void cgiCopyTemplateFile (
      +    FILE *out,
      +    const char *tmpl
      +);

      +

      Parameters

      +
      +
      out
      +
      Output file
      +
      tmpl
      +
      Template file to read
      +
      +

      cgiCopyTemplateLang

      +

      Copy a template file using a language...

      +

      +void cgiCopyTemplateLang (
      +    const char *tmpl
      +);

      +

      Parameters

      +
      +
      tmpl
      +
      Base filename
      +
      +

      cgiDoSearch

      +

      Do a search of some text.

      +

      +int cgiDoSearch (
      +    void *search,
      +    const char *text
      +);

      +

      Parameters

      +
      +
      search
      +
      Search context
      +
      text
      +
      Text to search
      +
      +

      Return Value

      +

      Number of matches

      +

      cgiEndHTML

      +

      End a HTML page.

      +

      +void cgiEndHTML (void);

      +

      cgiEndMultipart

      +

      End the delivery of a multipart web page.

      +

      +void cgiEndMultipart (void);

      +

      cgiFormEncode

      +

      Encode a string as a form variable.

      +

      +char *cgiFormEncode (
      +    char *dst,
      +    const char *src,
      +    size_t dstsize
      +);

      +

      Parameters

      +
      +
      dst
      +
      Destination string
      +
      src
      +
      Source string
      +
      dstsize
      +
      Size of destination string
      +
      +

      Return Value

      +

      Destination string

      +

      cgiFreeSearch

      +

      Free a compiled search context.

      +

      +void cgiFreeSearch (
      +    void *search
      +);

      +

      Parameters

      +
      +
      search
      +
      Search context
      +
      +

      cgiGetArray

      +

      Get an element from a form array.

      +

      +const char *cgiGetArray (
      +    const char *name,
      +    int element
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of array variable
      +
      element
      +
      Element number (0 to N)
      +
      +

      Return Value

      +

      Element value or NULL

      +

      cgiGetAttributes

      +

      Get the list of attributes that are needed +by the template file.

      +

      +void cgiGetAttributes (
      +    ipp_t *request,
      +    const char *tmpl
      +);

      +

      Parameters

      +
      +
      request
      +
      IPP request
      +
      tmpl
      +
      Base filename
      +
      +

      cgiGetCookie

      +

      Get a cookie value.

      +

      +const char *cgiGetCookie (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of cookie
      +
      +

      Return Value

      +

      Value or NULL

      +

      cgiGetFile

      +

      Get the file (if any) that was submitted in the form.

      +

      +const cgi_file_t *cgiGetFile (void);

      +

      Return Value

      +

      Attached file or NULL

      +

      cgiGetIPPObjects

      +

      Get the objects in an IPP response.

      +

      +cups_array_t *cgiGetIPPObjects (
      +    ipp_t *response,
      +    void *search
      +);

      +

      Parameters

      +
      +
      response
      +
      IPP response
      +
      search
      +
      Search filter
      +
      +

      Return Value

      +

      Array of objects

      +

      cgiGetSize

      +

      Get the size of a form array value.

      +

      +int cgiGetSize (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of variable
      +
      +

      Return Value

      +

      Number of elements

      +

      cgiGetTemplateDir

      +

      Get the templates directory...

      +

      +char *cgiGetTemplateDir (void);

      +

      Return Value

      +

      Template directory

      +

      cgiGetVariable

      +

      Get a CGI variable from the database.

      +

      +const char *cgiGetVariable (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of variable
      +
      +

      Return Value

      +

      Value of variable

      +

      Discussion

      +

      Returns NULL if the variable doesn't exist. If the variable is an +array of values, returns the last element.

      +

      cgiInitialize

      +

      Initialize the CGI variable "database".

      +

      +int cgiInitialize (void);

      +

      Return Value

      +

      Non-zero if there was form data

      +

      cgiIsPOST

      +

      Determine whether this page was POSTed.

      +

      +int cgiIsPOST (void);

      +

      Return Value

      +

      1 if POST, 0 if GET

      +

      cgiMoveJobs

      +

      Move one or more jobs.

      +

      +void cgiMoveJobs (
      +    http_t *http,
      +    const char *dest,
      +    int job_id
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      dest
      +
      Destination or NULL
      +
      job_id
      +
      Job ID or 0 for all
      +
      +

      Discussion

      +

      At least one of dest or job_id must be non-zero/NULL.

      +

      cgiPrintCommand

      +

      Print a CUPS command job.

      +

      +void cgiPrintCommand (
      +    http_t *http,
      +    const char *dest,
      +    const char *command,
      +    const char *title
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      dest
      +
      Destination printer
      +
      command
      +
      Command to send
      +
      title
      +
      Page/job title
      +
      +

      cgiPrintTestPage

      +

      Print a test page.

      +

      +void cgiPrintTestPage (
      +    http_t *http,
      +    const char *dest
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      dest
      +
      Destination printer/class
      +
      +

      cgiRewriteURL

      +

      Rewrite a printer URI into a web browser URL...

      +

      +char *cgiRewriteURL (
      +    const char *uri,
      +    char *url,
      +    int urlsize,
      +    const char *newresource
      +);

      +

      Parameters

      +
      +
      uri
      +
      Current URI
      +
      url
      +
      New URL
      +
      urlsize
      +
      Size of URL buffer
      +
      newresource
      +
      Replacement resource
      +
      +

      Return Value

      +

      New URL

      +

      cgiSetArray

      +

      Set array element N to the specified string.

      +

      +void cgiSetArray (
      +    const char *name,
      +    int element,
      +    const char *value
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of variable
      +
      element
      +
      Element number (0 to N)
      +
      value
      +
      Value of variable
      +
      +

      Discussion

      +

      If the variable array is smaller than (element + 1), the intervening +elements are set to NULL.

      +

      cgiSetCookie

      +

      Set a cookie value.

      +

      +void cgiSetCookie (
      +    const char *name,
      +    const char *value,
      +    const char *path,
      +    const char *domain,
      +    time_t expires,
      +    int secure
      +);

      +

      Parameters

      +
      +
      name
      +
      Name
      +
      value
      +
      Value
      +
      path
      +
      Path (typically "/")
      +
      domain
      +
      Domain name
      +
      expires
      +
      Expiration date (0 for session)
      +
      secure
      +
      Require SSL
      +
      +

      cgiSetIPPObjectVars

      +

      Set CGI variables from an IPP object.

      +

      +ipp_attribute_t *cgiSetIPPObjectVars (
      +    ipp_attribute_t *obj,
      +    const char *prefix,
      +    int element
      +);

      +

      Parameters

      +
      +
      obj
      +
      Response data to be copied...
      +
      prefix
      +
      Prefix for name or NULL
      +
      element
      +
      Parent element number
      +
      +

      Return Value

      +

      Next object

      +

      cgiSetIPPVars

      +

      Set CGI variables from an IPP response.

      +

      +int cgiSetIPPVars (
      +    ipp_t *response,
      +    const char *filter_name,
      +    const char *filter_value,
      +    const char *prefix,
      +    int parent_el
      +);

      +

      Parameters

      +
      +
      response
      +
      Response data to be copied...
      +
      filter_name
      +
      Filter name
      +
      filter_value
      +
      Filter value
      +
      prefix
      +
      Prefix for name or NULL
      +
      parent_el
      +
      Parent element number
      +
      +

      Return Value

      +

      Maximum number of elements

      +

      cgiSetServerVersion

      +

      Set the server name and CUPS version...

      +

      +void cgiSetServerVersion (void);

      +

      cgiSetSize

      +

      Set the array size.

      +

      +void cgiSetSize (
      +    const char *name,
      +    int size
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of variable
      +
      size
      +
      Number of elements (0 to N)
      +
      +

      cgiSetVariable

      +

      Set a CGI variable in the database.

      +

      +void cgiSetVariable (
      +    const char *name,
      +    const char *value
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of variable
      +
      value
      +
      Value of variable
      +
      +

      Discussion

      +

      If the variable is an array, this truncates the array to a single element.

      +

      cgiShowIPPError

      +

      Show the last IPP error message.

      +

      +void cgiShowIPPError (
      +    const char *message
      +);

      +

      Parameters

      +
      +
      message
      +
      Contextual message
      +
      +

      Discussion

      +

      The caller must still call cgiStartHTML() and cgiEndHTML().

      +

      cgiShowJobs

      +

      Show print jobs.

      +

      +void cgiShowJobs (
      +    http_t *http,
      +    const char *dest
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      dest
      +
      Destination name or NULL
      +
      +

      cgiStartHTML

      +

      Start a HTML page.

      +

      +void cgiStartHTML (
      +    const char *title
      +);

      +

      Parameters

      +
      +
      title
      +
      Title of page
      +
      +

      cgiStartMultipart

      +

      Start a multipart delivery of a web page.

      +

      +void cgiStartMultipart (void);

      +

      cgiSupportsMultipart

      +

      Does the browser support multi-part documents?

      +

      +int cgiSupportsMultipart (void);

      +

      Return Value

      +

      1 if multi-part supported, 0 otherwise

      +

      cgiText

      +

      Return localized text.

      +

      +const char *cgiText (
      +    const char *message
      +);

      +

      Parameters

      +
      +
      message
      +
      Message
      +
      +

      Return Value

      +

      Localized message

      +

      helpDeleteIndex

      +

      Delete an index, freeing all memory used.

      +

      +void helpDeleteIndex (
      +    help_index_t *hi
      +);

      +

      Parameters

      +
      +
      hi
      +
      Help index
      +
      +

      helpFindNode

      +

      Find a node in an index.

      +

      +help_node_t *helpFindNode (
      +    help_index_t *hi,
      +    const char *filename,
      +    const char *anchor
      +);

      +

      Parameters

      +
      +
      hi
      +
      Index
      +
      filename
      +
      Filename
      +
      anchor
      +
      Anchor
      +
      +

      Return Value

      +

      Node pointer or NULL

      +

      helpLoadIndex

      +

      Load a help index from disk.

      +

      +help_index_t *helpLoadIndex (
      +    const char *hifile,
      +    const char *directory
      +);

      +

      Parameters

      +
      +
      hifile
      +
      Index filename
      +
      directory
      +
      Directory that is indexed
      +
      +

      Return Value

      +

      Index pointer or NULL

      +

      helpSaveIndex

      +

      Save a help index to disk.

      +

      +int helpSaveIndex (
      +    help_index_t *hi,
      +    const char *hifile
      +);

      +

      Parameters

      +
      +
      hi
      +
      Index
      +
      hifile
      +
      Index filename
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

      helpSearchIndex

      +

      Search an index.

      +

      +help_index_t *helpSearchIndex (
      +    help_index_t *hi,
      +    const char *query,
      +    const char *section,
      +    const char *filename
      +);

      +

      Parameters

      +
      +
      hi
      +
      Index
      +
      query
      +
      Query string
      +
      section
      +
      Limit search to this section
      +
      filename
      +
      Limit search to this file
      +
      +

      Return Value

      +

      Search index

      +

      Data Types

      +

      cgi_file_t

      +

      Uploaded file data

      +

      +typedef struct cgi_file_s cgi_file_t; +

      +

      help_index_t

      +

      Help index structure

      +

      +typedef struct help_index_s help_index_t; +

      +

      help_node_t

      +

      Help node structure...

      +

      +typedef struct help_node_s help_node_t; +

      +

      help_word_t

      +

      Help word structure...

      +

      +typedef struct help_word_s help_word_t; +

      +

      Structures

      +

      cgi_file_s

      +

      Uploaded file data

      +

      struct cgi_file_s {
      +    size_t filesize;
      +    char tempfile[1024], *name, *filename, *mimetype;
      +};

      +

      Members

      +
      +
      filesize
      +
      Size of uploaded file
      +
      mimetype
      +
      MIME media type
      +
      +

      help_index_s

      +

      Help index structure

      +

      struct help_index_s {
      +    cups_array_t *nodes;
      +    int search;
      +    cups_array_t *sorted;
      +};

      +

      Members

      +
      +
      nodes
      +
      Nodes sorted by filename
      +
      search
      +
      1 = search index, 0 = normal
      +
      sorted
      +
      Nodes sorted by score + text
      +
      +

      help_node_s

      +

      Help node structure...

      +

      struct help_node_s {
      +    char *anchor;
      +    char *filename;
      +    size_t length;
      +    time_t mtime;
      +    off_t offset;
      +    int score;
      +    char *section;
      +    char *text;
      +    cups_array_t *words;
      +};

      +

      Members

      +
      +
      anchor
      +
      Anchor name (NULL if none)
      +
      filename
      +
      Filename, relative to help dir
      +
      length
      +
      Length in bytes
      +
      mtime
      +
      Last modification time
      +
      offset
      +
      Offset in file
      +
      score
      +
      Search score
      +
      section
      +
      Section name (NULL if none)
      +
      text
      +
      Text in anchor
      +
      words
      +
      Words after this node
      +
      +

      help_word_s

      +

      Help word structure...

      +

      struct help_word_s {
      +    int count;
      +    char *text;
      +};

      +

      Members

      +
      +
      count
      +
      Number of occurrences
      +
      text
      +
      Word text
      +
      +
+ + diff --git a/doc/help/api-cups.html b/doc/help/api-cups.html new file mode 100644 index 0000000000..d12cbc6066 --- /dev/null +++ b/doc/help/api-cups.html @@ -0,0 +1,2426 @@ + + + + +CUPS API + + + + + +
+ + +

CUPS API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/cups.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: Array API
+ Programming: File and Directory APIs
+ Programming: Filter and Backend Programming
+ Programming: HTTP and IPP APIs
+ Programming: PPD API
+ Programming: Raster API
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • +
    • Constants
    • + + +

      Overview

      + +

      The CUPS API provides the convenience functions needed to support +applications, filters, printer drivers, and backends that need to interface +with the CUPS scheduler.

      + +

      Clients and Servers

      + +

      CUPS is based on the Internet Printing Protocol ("IPP"), which allows +clients (applications) to communicate with a server (the scheduler) to get a +list of printers, send print jobs, and so forth. You identify which server +you want to communicate with using a pointer to the opaque structure +http_t. All of the examples in this document use the +CUPS_HTTP_DEFAULT constant, referring to the default connection +to the scheduler. The HTTP and IPP +APIs document provides more information on server connections.

      + +

      Printers and Classes

      + +

      Printers and classes (collections of printers) are accessed through +the cups_dest_t structure which +includes the name (name), instance (instance - +a way of selecting certain saved options/settings), and the options and +attributes associated with that destination (num_options and +options). Destinations are created using the +cupsGetDests function and freed +using the cupsFreeDests function. +The cupsGetDest function finds a +specific destination for printing:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dests;
      +int num_dests = cupsGetDests(&dests);
      +cups_dest_t *dest = cupsGetDest("name", NULL, num_dests, dests);
      +
      +/* do something with dest */
      +
      +cupsFreeDests(num_dests, dests);
      +
      + +

      Passing NULL to +cupsGetDest for the destination name +will return the default destination. Similarly, passing a NULL +instance will return the default instance for that destination.

      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Table 1: Printer Attributes
      Attribute NameDescription
      "auth-info-required"The type of authentication required for printing to this + destination: "none", "username,password", "domain,username,password", + or "negotiate" (Kerberos)
      "printer-info"The human-readable description of the destination such as "My + Laser Printer".
      "printer-is-accepting-jobs""true" if the destination is accepting new jobs, "false" if + not.
      "printer-is-shared""true" if the destination is being shared with other computers, + "false" if not.
      "printer-location"The human-readable location of the destination such as "Lab 4".
      "printer-make-and-model"The human-readable make and model of the destination such as "HP + LaserJet 4000 Series".
      "printer-state""3" if the destination is idle, "4" if the destination is printing + a job, and "5" if the destination is stopped.
      "printer-state-change-time"The UNIX time when the destination entered the current state.
      "printer-state-reasons"Additional comma-delimited state keywords for the destination + such as "media-tray-empty-error" and "toner-low-warning".
      "printer-type"The cups_printer_t + value associated with the destination.
      + +

      Options

      + +

      Options are stored in arrays of +cups_option_t structures. Each +option has a name (name) and value (value) +associated with it. The cups_dest_t +num_options and options members contain the +default options for a particular destination, along with several informational +attributes about the destination as shown in Table 1. +The cupsGetOption function gets +the value for the named option. For example, the following code lists the +available destinations and their human-readable descriptions:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dests;
      +int num_dests = cupsGetDests(&dests);
      +cups_dest_t *dest;
      +int i;
      +const char *value;
      +
      +for (i = num_dests, dest = dests; i > 0; i --, dest ++)
      +  if (dest->instance == NULL)
      +  {
      +    value = cupsGetOption("printer-info", dest->num_options, dest->options);
      +    printf("%s (%s)\n", dest->name, value ? value : "no description");
      +  }
      +
      +cupsFreeDests(num_dests, dests);
      +
      + +

      You can create your own option arrays using the +cupsAddOption function, which +adds a single named option to an array:

      + +
      +#include <cups/cups.h>
      +
      +int num_options = 0;
      +cups_option_t *options = NULL;
      +
      +/* The returned num_options value is updated as needed */
      +num_options = cupsAddOption("first", "value", num_options, &options);
      +
      +/* This adds a second option value */
      +num_options = cupsAddOption("second", "value", num_options, &options);
      +
      +/* This replaces the first option we added */
      +num_options = cupsAddOption("first", "new value", num_options, &options);
      +
      + +

      Use a for loop to copy the options from a destination:

      + +
      +#include <cups/cups.h>
      +
      +int i;
      +int num_options = 0;
      +cups_option_t *options = NULL;
      +cups_dest_t *dest;
      +
      +for (i = 0; i < dest->num_options; i ++)
      +  num_options = cupsAddOption(dest->options[i].name, dest->options[i].value,
      +                              num_options, &options);
      +
      + +

      Use the cupsFreeOptions +function to free the options array when you are done using it:

      + +
      +cupsFreeOptions(num_options, options);
      +
      + +

      Print Jobs

      + +

      Print jobs are identified by a locally-unique job ID number from 1 to +231-1 and have options and one or more files for printing to a +single destination. The cupsPrintFile +function creates a new job with one file. The following code prints the CUPS +test page file:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dest;
      +int num_options;
      +cups_option_t *options;
      +int job_id;
      +
      +/* Print a single file */
      +job_id = cupsPrintFile(dest->name, "/usr/share/cups/data/testprint.ps",
      +                        "Test Print", num_options, options);
      +
      + +

      The cupsPrintFiles function +creates a job with multiple files. The files are provided in a +char * array:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dest;
      +int num_options;
      +cups_option_t *options;
      +int job_id;
      +char *files[3] = { "file1.pdf", "file2.pdf", "file3.pdf" };
      +
      +/* Print three files */
      +job_id = cupsPrintFiles(dest->name, 3, files, "Test Print", num_options, options);
      +
      + +

      Finally, the cupsCreateJob +function creates a new job with no files in it. Files are added using the +cupsStartDocument, +cupsWriteRequestData, +and cupsFinishDocument functions. +The following example creates a job with 10 text files for printing:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dest;
      +int num_options;
      +cups_option_t *options;
      +int job_id;
      +int i;
      +char buffer[1024];
      +
      +/* Create the job */
      +job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, dest->name, "10 Text Files",
      +                       num_options, options);
      +
      +/* If the job is created, add 10 files */
      +if (job_id > 0)
      +{
      +  for (i = 1; i <= 10; i ++)
      +  {
      +    snprintf(buffer, sizeof(buffer), "file%d.txt", i);
      +
      +    cupsStartDocument(CUPS_HTTP_DEFAULT, dest->name, job_id, buffer,
      +                      CUPS_FORMAT_TEXT, i == 10);
      +
      +    snprintf(buffer, sizeof(buffer),
      +             "File %d\n"
      +             "\n"
      +             "One fish,\n"
      +             "Two fish,\n
      +             "Red fish,\n
      +             "Blue fish\n", i);
      +
      +    /* cupsWriteRequestData can be called as many times as needed */
      +    cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, strlen(buffer));
      +
      +    cupsFinishDocument(CUPS_HTTP_DEFAULT, dest->name);
      +  }
      +}
      +
      + +

      Once you have created a job, you can monitor its status using the +cupsGetJobs function, which returns +an array of cups_job_t structures. +Each contains the job ID (id), destination name +(dest), title (title), and other information +associated with the job. The job array is freed using the +cupsFreeJobs function. The following +example monitors a specific job ID, showing the current job state once every +5 seconds until the job is completed:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dest;
      +int job_id;
      +int num_jobs;
      +cups_job_t *jobs;
      +int i;
      +ipp_jstate_t job_state = IPP_JOB_PENDING;
      + 
      +while (job_state < IPP_JOB_STOPPED)
      +{
      +  /* Get my jobs (1) with any state (-1) */
      +  num_jobs = cupsGetJobs(&jobs, dest->name, 1, -1);
      +
      +  /* Loop to find my job */
      +  job_state = IPP_JOB_COMPLETED;
      +
      +  for (i = 0; i < num_jobs; i ++)
      +    if (jobs[i].id == job_id)
      +    {
      +      job_state = jobs[i].state;
      +      break;
      +    }
      +
      +  /* Free the job array */
      +  cupsFreeJobs(num_jobs, jobs);
      +
      +  /* Show the current state */
      +  switch (job_state)
      +  {
      +    case IPP_JOB_PENDING :
      +        printf("Job %d is pending.\n", job_id);
      +        break;
      +    case IPP_JOB_HELD :
      +        printf("Job %d is held.\n", job_id);
      +        break;
      +    case IPP_JOB_PROCESSING :
      +        printf("Job %d is processing.\n", job_id);
      +        break;
      +    case IPP_JOB_STOPPED :
      +        printf("Job %d is stopped.\n", job_id);
      +        break;
      +    case IPP_JOB_CANCELED :
      +        printf("Job %d is canceled.\n", job_id);
      +        break;
      +    case IPP_JOB_ABORTED :
      +        printf("Job %d is aborted.\n", job_id);
      +        break;
      +    case IPP_JOB_COMPLETED :
      +        printf("Job %d is completed.\n", job_id);
      +        break;
      +  }
      +
      +  /* Sleep if the job is not finished */
      +  if (job_state < IPP_JOB_STOPPED)
      +    sleep(5);
      +}
      +
      + +

      To cancel a job, use the +cupsCancelJob function with the +job ID:

      + +
      +#include <cups/cups.h>
      +
      +cups_dest_t *dest;
      +int job_id;
      +
      +cupsCancelJob(dest->name, job_id);
      +
      + +

      Error Handling

      + +

      If any of the CUPS API printing functions returns an error, the reason for +that error can be found by calling the +cupsLastError and +cupsLastErrorString functions. +cupsLastError returns the last IPP +error code +(ipp_status_t) +that was encountered, while +cupsLastErrorString returns +a (localized) human-readable string that can be shown to the user. For example, +if any of the job creation functions returns a job ID of 0, you can use +cupsLastErrorString to show +the reason why the job could not be created:

      + +
      +#include <cups/cups.h>
      +
      +int job_id;
      +
      +if (job_id == 0)
      +  puts(cupsLastErrorString());
      +
      + +

      Passwords and Authentication

      + +

      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.

      + +

      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.

      + +

      The cupsSetPasswordCB +function is used to set a password callback in your program. Only one +function can be used at any time.

      + +

      The cupsSetUser function sets the +current username for authentication. This function can be called by your +password callback function to change the current username as needed.

      + +

      The following example shows a simple password callback that gets a +username and password from the user:

      + +
      +#include <cups/cups.h>
      +
      +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);
      +
      + +

      Similarly, a GUI could display the prompt string in a window with input +fields for the username and password. The username should default to the +string returned by the cupsUser +function.

      +

      Functions

      +

      cupsAddDest

      +

      Add a destination to the list of destinations.

      +

      +int cupsAddDest (
      +    const char *name,
      +    const char *instance,
      +    int num_dests,
      +    cups_dest_t **dests
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name
      +
      instance
      +
      Instance name or NULL for none/primary
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      Return Value

      +

      New number of destinations

      +

      Discussion

      +

      This function cannot be used to add a new class or printer queue, +it only adds a new container of saved options for the named +destination or instance.
      +
      +If the named destination already exists, the destination list is +returned unchanged. Adding a new instance of a destination creates +a copy of that destination's options.
      +
      +Use the cupsSaveDests function to save the updated list of +destinations to the user's lpoptions file.

      +

      cupsAddOption

      +

      Add an option to an option array.

      +

      +int cupsAddOption (
      +    const char *name,
      +    const char *value,
      +    int num_options,
      +    cups_option_t **options
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of option
      +
      value
      +
      Value of option
      +
      num_options
      +
      Number of options
      +
      options
      +
      Pointer to options
      +
      +

      Return Value

      +

      Number of options

      +

      Discussion

      +

      New option arrays can be initialized simply by passing 0 for the +"num_options" parameter.

      +

       CUPS 1.2/Mac OS X 10.5 cupsAdminCreateWindowsPPD

      +

      Create the Windows PPD file for a printer.

      +

      +char *cupsAdminCreateWindowsPPD (
      +    http_t *http,
      +    const char *dest,
      +    char *buffer,
      +    int bufsize
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      dest
      +
      Printer or class
      +
      buffer
      +
      Filename buffer
      +
      bufsize
      +
      Size of filename buffer
      +
      +

      Return Value

      +

      PPD file or NULL

      +

       CUPS 1.2/Mac OS X 10.5 cupsAdminExportSamba

      +

      Export a printer to Samba.

      +

      +int cupsAdminExportSamba (
      +    const char *dest,
      +    const char *ppd,
      +    const char *samba_server,
      +    const char *samba_user,
      +    const char *samba_password,
      +    FILE *logfile
      +);

      +

      Parameters

      +
      +
      dest
      +
      Destination to export
      +
      ppd
      +
      PPD file
      +
      samba_server
      +
      Samba server
      +
      samba_user
      +
      Samba username
      +
      samba_password
      +
      Samba password
      +
      logfile
      +
      Log file, if any
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

       CUPS 1.3/Mac OS X 10.5 cupsAdminGetServerSettings

      +

      Get settings from the server.

      +

      +int cupsAdminGetServerSettings (
      +    http_t *http,
      +    int *num_settings,
      +    cups_option_t **settings
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      num_settings
      +
      Number of settings
      +
      settings
      +
      Settings
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      The returned settings should be freed with cupsFreeOptions() when +you are done with them. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsAdminSetServerSettings

      +

      Set settings on the server.

      +

      +int cupsAdminSetServerSettings (
      +    http_t *http,
      +    int num_settings,
      +    cups_option_t *settings
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      num_settings
      +
      Number of settings
      +
      settings
      +
      Settings
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      cupsCancelJob

      +

      Cancel a print job on the default server.

      +

      +int cupsCancelJob (
      +    const char *name,
      +    int job_id
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of printer or class
      +
      job_id
      +
      Job ID, CUPS_JOBID_CURRENT for the current job, or CUPS_JOBID_ALL for all jobs
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      Pass CUPS_JOBID_ALL to cancel all jobs or CUPS_JOBID_CURRENT +to cancel the current job on the named destination.
      +
      +Use the cupsLastError and cupsLastErrorString functions to get +the cause of any failure.

      +

       CUPS 1.4/Mac OS X 10.6 cupsCancelJob2

      +

      Cancel or purge a print job.

      +

      +ipp_status_t cupsCancelJob2 (
      +    http_t *http,
      +    const char *name,
      +    int job_id,
      +    int purge
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Name of printer or class
      +
      job_id
      +
      Job ID, CUPS_JOBID_CURRENT for the current job, or CUPS_JOBID_ALL for all jobs
      +
      purge
      +
      1 to purge, 0 to cancel
      +
      +

      Return Value

      +

      IPP status

      +

      Discussion

      +

      Canceled jobs remain in the job history while purged jobs are removed +from the job history.
      +
      +Pass CUPS_JOBID_ALL to cancel all jobs or CUPS_JOBID_CURRENT +to cancel the current job on the named destination.
      +
      +Use the cupsLastError and cupsLastErrorString functions to get +the cause of any failure. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsCreateJob

      +

      Create an empty job for streaming.

      +

      +int cupsCreateJob (
      +    http_t *http,
      +    const char *name,
      +    const char *title,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name
      +
      title
      +
      Title of job
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      Job ID or 0 on error

      +

      Discussion

      +

      Use this function when you want to stream print data using the +cupsStartDocument, cupsWriteRequestData, and +cupsFinishDocument functions. If you have one or more files to +print, use the cupsPrintFile2 or cupsPrintFiles2 function +instead. + +

      +

      cupsEncryption

      +

      Get the current encryption settings.

      +

      +http_encryption_t cupsEncryption (void);

      +

      Return Value

      +

      Encryption settings

      +

      Discussion

      +

      The default encryption setting comes from the CUPS_ENCRYPTION +environment variable, then the ~/.cups/client.conf file, and finally the +/etc/cups/client.conf file. If not set, the default is +HTTP_ENCRYPT_IF_REQUESTED.
      +
      +Note: The current encryption setting is tracked separately for each thread +in a program. Multi-threaded programs that override the setting via the +cupsSetEncryption function need to do so in each thread for the same +setting to be used.

      +

       CUPS 1.4/Mac OS X 10.6 cupsFinishDocument

      +

      Finish sending a document.

      +

      +ipp_status_t cupsFinishDocument (
      +    http_t *http,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name
      +
      +

      Return Value

      +

      Status of document submission

      +

      Discussion

      +

      The document must have been started using cupsStartDocument. + +

      +

      cupsFreeDests

      +

      Free the memory used by the list of destinations.

      +

      +void cupsFreeDests (
      +    int num_dests,
      +    cups_dest_t *dests
      +);

      +

      Parameters

      +
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      cupsFreeJobs

      +

      Free memory used by job data.

      +

      +void cupsFreeJobs (
      +    int num_jobs,
      +    cups_job_t *jobs
      +);

      +

      Parameters

      +
      +
      num_jobs
      +
      Number of jobs
      +
      jobs
      +
      Jobs
      +
      +

      cupsFreeOptions

      +

      Free all memory used by options.

      +

      +void cupsFreeOptions (
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      num_options
      +
      Number of options
      +
      options
      +
      Pointer to options
      +
      +

       DEPRECATED cupsGetClasses

      +

      Get a list of printer classes from the default server.

      +

      +int cupsGetClasses (
      +    char ***classes
      +);

      +

      Parameters

      +
      +
      classes
      +
      Classes
      +
      +

      Return Value

      +

      Number of classes

      +

      Discussion

      +

      This function is deprecated - use cupsGetDests instead. + +

      +

      cupsGetDefault

      +

      Get the default printer or class for the default server.

      +

      +const char *cupsGetDefault (void);

      +

      Return Value

      +

      Default printer or NULL

      +

      Discussion

      +

      This function returns the default printer or class as defined by +the LPDEST or PRINTER environment variables. If these environment +variables are not set, the server default destination is returned. +Applications should use the cupsGetDests and cupsGetDest +functions to get the user-defined default printer, as this function does +not support the lpoptions-defined default printer.

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsGetDefault2

      +

      Get the default printer or class for the specified server.

      +

      +const char *cupsGetDefault2 (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      +

      Return Value

      +

      Default printer or NULL

      +

      Discussion

      +

      This function returns the default printer or class as defined by +the LPDEST or PRINTER environment variables. If these environment +variables are not set, the server default destination is returned. +Applications should use the cupsGetDests and cupsGetDest +functions to get the user-defined default printer, as this function does +not support the lpoptions-defined default printer. + +

      +

      cupsGetDest

      +

      Get the named destination from the list.

      +

      +cups_dest_t *cupsGetDest (
      +    const char *name,
      +    const char *instance,
      +    int num_dests,
      +    cups_dest_t *dests
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name or NULL for the default destination
      +
      instance
      +
      Instance name or NULL
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      Return Value

      +

      Destination pointer or NULL

      +

      Discussion

      +

      Use the cupsGetDests or cupsGetDests2 functions to get a +list of supported destinations for the current user.

      +

      cupsGetDests

      +

      Get the list of destinations from the default server.

      +

      +int cupsGetDests (
      +    cups_dest_t **dests
      +);

      +

      Parameters

      +
      +
      dests
      +
      Destinations
      +
      +

      Return Value

      +

      Number of destinations

      +

      Discussion

      +

      Starting with CUPS 1.2, the returned list of destinations include the +printer-info, printer-is-accepting-jobs, printer-is-shared, +printer-make-and-model, printer-state, printer-state-change-time, +printer-state-reasons, and printer-type attributes as options. CUPS 1.4 +adds the marker-change-time, marker-colors, marker-high-levels, +marker-levels, marker-low-levels, marker-message, marker-names, +marker-types, and printer-commands attributes as well.
      +
      +Use the cupsFreeDests function to free the destination list and +the cupsGetDest function to find a particular destination.

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsGetDests2

      +

      Get the list of destinations from the specified server.

      +

      +int cupsGetDests2 (
      +    http_t *http,
      +    cups_dest_t **dests
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      dests
      +
      Destinations
      +
      +

      Return Value

      +

      Number of destinations

      +

      Discussion

      +

      Starting with CUPS 1.2, the returned list of destinations include the +printer-info, printer-is-accepting-jobs, printer-is-shared, +printer-make-and-model, printer-state, printer-state-change-time, +printer-state-reasons, and printer-type attributes as options. CUPS 1.4 +adds the marker-change-time, marker-colors, marker-high-levels, +marker-levels, marker-low-levels, marker-message, marker-names, +marker-types, and printer-commands attributes as well.
      +
      +Use the cupsFreeDests function to free the destination list and +the cupsGetDest function to find a particular destination. + +

      +

      cupsGetJobs

      +

      Get the jobs from the default server.

      +

      +int cupsGetJobs (
      +    cups_job_t **jobs,
      +    const char *name,
      +    int myjobs,
      +    int whichjobs
      +);

      +

      Parameters

      +
      +
      jobs
      +
      Job data
      +
      name
      +
      NULL = all destinations, otherwise show jobs for named destination
      +
      myjobs
      +
      0 = all users, 1 = mine
      +
      whichjobs
      +
      CUPS_WHICHJOBS_ALL, CUPS_WHICHJOBS_ACTIVE, or CUPS_WHICHJOBS_COMPLETED
      +
      +

      Return Value

      +

      Number of jobs

      +

      Discussion

      +

      A "whichjobs" value of CUPS_WHICHJOBS_ALL returns all jobs regardless +of state, while CUPS_WHICHJOBS_ACTIVE returns jobs that are +pending, processing, or held and CUPS_WHICHJOBS_COMPLETED returns +jobs that are stopped, canceled, aborted, or completed.

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsGetJobs2

      +

      Get the jobs from the specified server.

      +

      +int cupsGetJobs2 (
      +    http_t *http,
      +    cups_job_t **jobs,
      +    const char *name,
      +    int myjobs,
      +    int whichjobs
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      jobs
      +
      Job data
      +
      name
      +
      NULL = all destinations, otherwise show jobs for named destination
      +
      myjobs
      +
      0 = all users, 1 = mine
      +
      whichjobs
      +
      CUPS_WHICHJOBS_ALL, CUPS_WHICHJOBS_ACTIVE, or CUPS_WHICHJOBS_COMPLETED
      +
      +

      Return Value

      +

      Number of jobs

      +

      Discussion

      +

      A "whichjobs" value of CUPS_WHICHJOBS_ALL returns all jobs regardless +of state, while CUPS_WHICHJOBS_ACTIVE returns jobs that are +pending, processing, or held and CUPS_WHICHJOBS_COMPLETED returns +jobs that are stopped, canceled, aborted, or completed. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsGetNamedDest

      +

      Get options for the named destination.

      +

      +cups_dest_t *cupsGetNamedDest (
      +    http_t *http,
      +    const char *name,
      +    const char *instance
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name or NULL for the default destination
      +
      instance
      +
      Instance name or NULL
      +
      +

      Return Value

      +

      Destination or NULL

      +

      Discussion

      +

      This function is optimized for retrieving a single destination and should +be used instead of cupsGetDests and cupsGetDest when you either +know the name of the destination or want to print to the default destination. +If NULL is returned, the destination does not exist or there is no +default destination.
      +
      +If "http" is CUPS_HTTP_DEFAULT, the connection to the default print +server will be used.
      +
      +If "name" is NULL, the default printer for the current user will be +returned.
      +
      +The returned destination must be freed using cupsFreeDests with a +"num_dests" value of 1. + +

      +

      cupsGetOption

      +

      Get an option value.

      +

      +const char *cupsGetOption (
      +    const char *name,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      name
      +
      Name of option
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      Option value or NULL

      +

      cupsGetPPD

      +

      Get the PPD file for a printer on the default server.

      +

      +const char *cupsGetPPD (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name
      +
      +

      Return Value

      +

      Filename for PPD file

      +

      Discussion

      +

      For classes, cupsGetPPD returns the PPD file for the first printer +in the class.
      +
      +The returned filename is stored in a static buffer and is overwritten with +each call to cupsGetPPD or cupsGetPPD2. The caller "owns" the +file that is created and must unlink the returned filename.

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsGetPPD2

      +

      Get the PPD file for a printer from the specified server.

      +

      +const char *cupsGetPPD2 (
      +    http_t *http,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name
      +
      +

      Return Value

      +

      Filename for PPD file

      +

      Discussion

      +

      For classes, cupsGetPPD2 returns the PPD file for the first printer +in the class.
      +
      +The returned filename is stored in a static buffer and is overwritten with +each call to cupsGetPPD or cupsGetPPD2. The caller "owns" the +file that is created and must unlink the returned filename. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsGetPPD3

      +

      Get the PPD file for a printer on the specified +server if it has changed.

      +

      +http_status_t cupsGetPPD3 (
      +    http_t *http,
      +    const char *name,
      +    time_t *modtime,
      +    char *buffer,
      +    size_t bufsize
      +);

      +

      Parameters

      +
      +
      http
      +
      HTTP connection or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name
      +
      modtime
      +
      Modification time
      +
      buffer
      +
      Filename buffer
      +
      bufsize
      +
      Size of filename buffer
      +
      +

      Return Value

      +

      HTTP status

      +

      Discussion

      +

      The "modtime" parameter contains the modification time of any +locally-cached content and is updated with the time from the PPD file on +the server.
      +
      +The "buffer" parameter contains the local PPD filename. If it contains +the empty string, a new temporary file is created, otherwise the existing +file will be overwritten as needed. The caller "owns" the file that is +created and must unlink the returned filename.
      +
      +On success, HTTP_OK is returned for a new PPD file and +HTTP_NOT_MODIFIED if the existing PPD file is up-to-date. Any other +status is an error.
      +
      +For classes, cupsGetPPD3 returns the PPD file for the first printer +in the class. + +

      +

      cupsGetPassword

      +

      Get a password from the user.

      +

      +const char *cupsGetPassword (
      +    const char *prompt
      +);

      +

      Parameters

      +
      +
      prompt
      +
      Prompt string
      +
      +

      Return Value

      +

      Password

      +

      Discussion

      +

      Uses the current password callback function. Returns NULL if the +user does not provide a password.
      +
      +Note: The current password callback function is tracked separately for each +thread in a program. Multi-threaded programs that override the setting via +the cupsSetPasswordCB or cupsSetPasswordCB2 functions need to +do so in each thread for the same function to be used.

      +

       CUPS 1.4/Mac OS X 10.6 cupsGetPassword2

      +

      Get a password from the user using the advanced +password callback.

      +

      +const char *cupsGetPassword2 (
      +    const char *prompt,
      +    http_t *http,
      +    const char *method,
      +    const char *resource
      +);

      +

      Parameters

      +
      +
      prompt
      +
      Prompt string
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      method
      +
      Request method ("GET", "POST", "PUT")
      +
      resource
      +
      Resource path
      +
      +

      Return Value

      +

      Password

      +

      Discussion

      +

      Uses the current password callback function. Returns NULL if the +user does not provide a password.
      +
      +Note: The current password callback function is tracked separately for each +thread in a program. Multi-threaded programs that override the setting via +the cupsSetPasswordCB or cupsSetPasswordCB2 functions need to +do so in each thread for the same function to be used. + +

      +

       DEPRECATED cupsGetPrinters

      +

      Get a list of printers from the default server.

      +

      +int cupsGetPrinters (
      +    char ***printers
      +);

      +

      Parameters

      +
      +
      printers
      +
      Printers
      +
      +

      Return Value

      +

      Number of printers

      +

      Discussion

      +

      This function is deprecated - use cupsGetDests instead. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsGetServerPPD

      +

      Get an available PPD file from the server.

      +

      +char *cupsGetServerPPD (
      +    http_t *http,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Name of PPD file ("ppd-name")
      +
      +

      Return Value

      +

      Name of PPD file or NULL on error

      +

      Discussion

      +

      This function returns the named PPD file from the server. The +list of available PPDs is provided by the IPP CUPS_GET_PPDS +operation.
      +
      +You must remove (unlink) the PPD file when you are finished with +it. The PPD filename is stored in a static location that will be +overwritten on the next call to cupsGetPPD, cupsGetPPD2, +or cupsGetServerPPD. + +

      +

      cupsLangDefault

      +

      Return the default language.

      +

      +cups_lang_t *cupsLangDefault (void);

      +

      Return Value

      +

      Language data

      +

      cupsLangEncoding

      +

      Return the character encoding (us-ascii, etc.) +for the given language.

      +

      +const char *cupsLangEncoding (
      +    cups_lang_t *lang
      +);

      +

      Parameters

      +
      +
      lang
      +
      Language data
      +
      +

      Return Value

      +

      Character encoding

      +

      cupsLangFlush

      +

      Flush all language data out of the cache.

      +

      +void cupsLangFlush (void);

      +

      cupsLangFree

      +

      Free language data.

      +

      +void cupsLangFree (
      +    cups_lang_t *lang
      +);

      +

      Parameters

      +
      +
      lang
      +
      Language to free
      +
      +

      Discussion

      +

      This does not actually free anything; use cupsLangFlush for that.

      +

      cupsLangGet

      +

      Get a language.

      +

      +cups_lang_t *cupsLangGet (
      +    const char *language
      +);

      +

      Parameters

      +
      +
      language
      +
      Language or locale
      +
      +

      Return Value

      +

      Language data

      +

      cupsLastError

      +

      Return the last IPP status code.

      +

      +ipp_status_t cupsLastError (void);

      +

      Return Value

      +

      IPP status code from last request

      +

       CUPS 1.2/Mac OS X 10.5 cupsLastErrorString

      +

      Return the last IPP status-message.

      +

      +const char *cupsLastErrorString (void);

      +

      Return Value

      +

      status-message text from last request

      +

       CUPS 1.2/Mac OS X 10.5 cupsNotifySubject

      +

      Return the subject for the given notification message.

      +

      +char *cupsNotifySubject (
      +    cups_lang_t *lang,
      +    ipp_t *event
      +);

      +

      Parameters

      +
      +
      lang
      +
      Language data
      +
      event
      +
      Event data
      +
      +

      Return Value

      +

      Subject string or NULL

      +

      Discussion

      +

      The returned string must be freed by the caller using free. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsNotifyText

      +

      Return the text for the given notification message.

      +

      +char *cupsNotifyText (
      +    cups_lang_t *lang,
      +    ipp_t *event
      +);

      +

      Parameters

      +
      +
      lang
      +
      Language data
      +
      event
      +
      Event data
      +
      +

      Return Value

      +

      Message text or NULL

      +

      Discussion

      +

      The returned string must be freed by the caller using free. + +

      +

      cupsParseOptions

      +

      Parse options from a command-line argument.

      +

      +int cupsParseOptions (
      +    const char *arg,
      +    int num_options,
      +    cups_option_t **options
      +);

      +

      Parameters

      +
      +
      arg
      +
      Argument to parse
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options found
      +
      +

      Return Value

      +

      Number of options found

      +

      Discussion

      +

      This function converts space-delimited name/value pairs according +to the PAPI text option ABNF specification. Collection values +("name={a=... b=... c=...}") are stored with the curley brackets +intact - use cupsParseOptions on the value to extract the +collection attributes.

      +

      cupsPrintFile

      +

      Print a file to a printer or class on the default server.

      +

      +int cupsPrintFile (
      +    const char *name,
      +    const char *filename,
      +    const char *title,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name
      +
      filename
      +
      File to print
      +
      title
      +
      Title of job
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      Job ID or 0 on error

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsPrintFile2

      +

      Print a file to a printer or class on the specified +server.

      +

      +int cupsPrintFile2 (
      +    http_t *http,
      +    const char *name,
      +    const char *filename,
      +    const char *title,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      name
      +
      Destination name
      +
      filename
      +
      File to print
      +
      title
      +
      Title of job
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      Job ID or 0 on error

      +

      cupsPrintFiles

      +

      Print one or more files to a printer or class on the +default server.

      +

      +int cupsPrintFiles (
      +    const char *name,
      +    int num_files,
      +    const char **files,
      +    const char *title,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name
      +
      num_files
      +
      Number of files
      +
      files
      +
      File(s) to print
      +
      title
      +
      Title of job
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      Job ID or 0 on error

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsPrintFiles2

      +

      Print one or more files to a printer or class on the +specified server.

      +

      +int cupsPrintFiles2 (
      +    http_t *http,
      +    const char *name,
      +    int num_files,
      +    const char **files,
      +    const char *title,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name
      +
      num_files
      +
      Number of files
      +
      files
      +
      File(s) to print
      +
      title
      +
      Title of job
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      Job ID or 0 on error

      +

       CUPS 1.3/Mac OS X 10.5 cupsRemoveDest

      +

      Remove a destination from the destination list.

      +

      +int cupsRemoveDest (
      +    const char *name,
      +    const char *instance,
      +    int num_dests,
      +    cups_dest_t **dests
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name
      +
      instance
      +
      Instance name or NULL
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      Return Value

      +

      New number of destinations

      +

      Discussion

      +

      Removing a destination/instance does not delete the class or printer +queue, merely the lpoptions for that destination/instance. Use the +cupsSetDests or cupsSetDests2 functions to save the new +options for the user. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsRemoveOption

      +

      Remove an option from an option array.

      +

      +int cupsRemoveOption (
      +    const char *name,
      +    int num_options,
      +    cups_option_t **options
      +);

      +

      Parameters

      +
      +
      name
      +
      Option name
      +
      num_options
      +
      Current number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      New number of options

      +

      cupsServer

      +

      Return the hostname/address of the current server.

      +

      +const char *cupsServer (void);

      +

      Return Value

      +

      Server name

      +

      Discussion

      +

      The default server comes from the CUPS_SERVER environment variable, then the +~/.cups/client.conf file, and finally the /etc/cups/client.conf file. If not +set, the default is the local system - either "localhost" or a domain socket +path.
      +
      +The returned value can be a fully-qualified hostname, a numeric IPv4 or IPv6 +address, or a domain socket pathname.
      +
      +Note: The current server is tracked separately for each thread in a program. +Multi-threaded programs that override the server via the +cupsSetServer function need to do so in each thread for the same +server to be used.

      +

       CUPS 1.3/Mac OS X 10.5 cupsSetDefaultDest

      +

      Set the default destination.

      +

      +void cupsSetDefaultDest (
      +    const char *name,
      +    const char *instance,
      +    int num_dests,
      +    cups_dest_t *dests
      +);

      +

      Parameters

      +
      +
      name
      +
      Destination name
      +
      instance
      +
      Instance name or NULL
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      cupsSetDests

      +

      Save the list of destinations for the default server.

      +

      +void cupsSetDests (
      +    int num_dests,
      +    cups_dest_t *dests
      +);

      +

      Parameters

      +
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      Discussion

      +

      This function saves the destinations to /etc/cups/lpoptions when run +as root and ~/.cups/lpoptions when run as a normal user.

      +

       CUPS 1.1.21/Mac OS X 10.4 cupsSetDests2

      +

      Save the list of destinations for the specified server.

      +

      +int cupsSetDests2 (
      +    http_t *http,
      +    int num_dests,
      +    cups_dest_t *dests
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      num_dests
      +
      Number of destinations
      +
      dests
      +
      Destinations
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

      Discussion

      +

      This function saves the destinations to /etc/cups/lpoptions when run +as root and ~/.cups/lpoptions when run as a normal user. + +

      +

      cupsSetEncryption

      +

      Set the encryption preference.

      +

      +void cupsSetEncryption (
      +    http_encryption_t e
      +);

      +

      Parameters

      +
      +
      e
      +
      New encryption preference
      +
      +

      Discussion

      +

      The default encryption setting comes from the CUPS_ENCRYPTION +environment variable, then the ~/.cups/client.conf file, and finally the +/etc/cups/client.conf file. If not set, the default is +HTTP_ENCRYPT_IF_REQUESTED.
      +
      +Note: The current encryption setting is tracked separately for each thread +in a program. Multi-threaded programs that override the setting need to do +so in each thread for the same setting to be used.

      +

      cupsSetPasswordCB

      +

      Set the password callback for CUPS.

      +

      +void cupsSetPasswordCB (
      +    cups_password_cb_t cb
      +);

      +

      Parameters

      +
      +
      cb
      +
      Callback function
      +
      +

      Discussion

      +

      Pass NULL to restore the default (console) password callback, which +reads the password from the console. Programs should call either this +function or cupsSetPasswordCB2, as only one callback can be registered +by a program per thread.
      +
      +Note: The current password callback is tracked separately for each thread +in a program. Multi-threaded programs that override the callback need to do +so in each thread for the same callback to be used.

      +

       CUPS 1.4/Mac OS X 10.6 cupsSetPasswordCB2

      +

      Set the advanced password callback for CUPS.

      +

      +void cupsSetPasswordCB2 (
      +    cups_password_cb2_t cb,
      +    void *user_data
      +);

      +

      Parameters

      +
      +
      cb
      +
      Callback function
      +
      user_data
      +
      User data pointer
      +
      +

      Discussion

      +

      Pass NULL to restore the default (console) password callback, which +reads the password from the console. Programs should call either this +function or cupsSetPasswordCB2, as only one callback can be registered +by a program per thread.
      +
      +Note: The current password callback is tracked separately for each thread +in a program. Multi-threaded programs that override the callback need to do +so in each thread for the same callback to be used. + +

      +

      cupsSetServer

      +

      Set the default server name and port.

      +

      +void cupsSetServer (
      +    const char *server
      +);

      +

      Parameters

      +
      +
      server
      +
      Server name
      +
      +

      Discussion

      +

      The "server" string can be a fully-qualified hostname, a numeric +IPv4 or IPv6 address, or a domain socket pathname. Hostnames and numeric IP +addresses can be optionally followed by a colon and port number to override +the default port 631, e.g. "hostname:8631". Pass NULL to restore the +default server name and port.
      +
      +Note: The current server is tracked separately for each thread in a program. +Multi-threaded programs that override the server need to do so in each +thread for the same server to be used.

      +

      cupsSetUser

      +

      Set the default user name.

      +

      +void cupsSetUser (
      +    const char *user
      +);

      +

      Parameters

      +
      +
      user
      +
      User name
      +
      +

      Discussion

      +

      Pass NULL to restore the default user name.
      +
      +Note: The current user name is tracked separately for each thread in a +program. Multi-threaded programs that override the user name need to do so +in each thread for the same user name to be used.

      +

       CUPS 1.4/Mac OS X 10.6 cupsStartDocument

      +

      Add a document to a job created with cupsCreateJob().

      +

      +http_status_t cupsStartDocument (
      +    http_t *http,
      +    const char *name,
      +    int job_id,
      +    const char *docname,
      +    const char *format,
      +    int last_document
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      name
      +
      Destination name
      +
      job_id
      +
      Job ID from cupsCreateJob
      +
      docname
      +
      Name of document
      +
      format
      +
      MIME type or CUPS_FORMAT_foo
      +
      last_document
      +
      1 for last document in job, 0 otherwise
      +
      +

      Return Value

      +

      HTTP status of request

      +

      Discussion

      +

      Use cupsWriteRequestData to write data for the document and +cupsFinishDocument to finish the document and get the submission status.
      +
      +The MIME type constants CUPS_FORMAT_AUTO, CUPS_FORMAT_PDF, +CUPS_FORMAT_POSTSCRIPT, CUPS_FORMAT_RAW, and +CUPS_FORMAT_TEXT are provided for the "format" argument, although +any supported MIME type string can be supplied. + +

      +

      cupsTempFd

      +

      Creates a temporary file.

      +

      +int cupsTempFd (
      +    char *filename,
      +    int len
      +);

      +

      Parameters

      +
      +
      filename
      +
      Pointer to buffer
      +
      len
      +
      Size of buffer
      +
      +

      Return Value

      +

      New file descriptor or -1 on error

      +

      Discussion

      +

      The temporary filename is returned in the filename buffer. +The temporary file is opened for reading and writing.

      +

       DEPRECATED cupsTempFile

      +

      Generates a temporary filename.

      +

      +char *cupsTempFile (
      +    char *filename,
      +    int len
      +);

      +

      Parameters

      +
      +
      filename
      +
      Pointer to buffer
      +
      len
      +
      Size of buffer
      +
      +

      Return Value

      +

      Filename or NULL on error

      +

      Discussion

      +

      The temporary filename is returned in the filename buffer. +This function is deprecated - use cupsTempFd or +cupsTempFile2 instead. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsTempFile2

      +

      Creates a temporary CUPS file.

      +

      +cups_file_t *cupsTempFile2 (
      +    char *filename,
      +    int len
      +);

      +

      Parameters

      +
      +
      filename
      +
      Pointer to buffer
      +
      len
      +
      Size of buffer
      +
      +

      Return Value

      +

      CUPS file or NULL on error

      +

      Discussion

      +

      The temporary filename is returned in the filename buffer. +The temporary file is opened for writing. + +

      +

      cupsUser

      +

      Return the current user's name.

      +

      +const char *cupsUser (void);

      +

      Return Value

      +

      User name

      +

      Discussion

      +

      Note: The current user name is tracked separately for each thread in a +program. Multi-threaded programs that override the user name with the +cupsSetUser function need to do so in each thread for the same user +name to be used.

      +

      Data Types

      +

      cups_dest_t

      +

      Destination

      +

      +typedef struct cups_dest_s cups_dest_t; +

      +

       CUPS 1.4/Mac OS X 10.6 cups_device_cb_t

      +

      Device callback

      +

      +typedef void (*cups_device_cb_t)(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, const char *device_location, void *user_data); +

      +

      cups_job_t

      +

      Job

      +

      +typedef struct cups_job_s cups_job_t; +

      +

      cups_option_t

      +

      Printer Options

      +

      +typedef struct cups_option_s cups_option_t; +

      +

       CUPS 1.4/Mac OS X 10.6 cups_password_cb2_t

      +

      New password callback

      +

      +typedef const char *(*cups_password_cb2_t)(const char *prompt, http_t *http, const char *method, const char *resource, void *user_data); +

      +

      cups_password_cb_t

      +

      Password callback

      +

      +typedef const char *(*cups_password_cb_t)(const char *prompt); +

      +

      cups_ptype_t

      +

      Printer type/capability bits

      +

      +typedef unsigned cups_ptype_t; +

      +

      Structures

      +

      cups_dest_s

      +

      Destination

      +

      struct cups_dest_s {
      +    char *name, *instance;
      +    int is_default;
      +    int num_options;
      +    cups_option_t *options;
      +};

      +

      Members

      +
      +
      instance
      +
      Local instance name or NULL
      +
      is_default
      +
      Is this printer the default?
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      cups_job_s

      +

      Job

      +

      struct cups_job_s {
      +    time_t completed_time;
      +    time_t creation_time;
      +    char *dest;
      +    char *format;
      +    int id;
      +    int priority;
      +    time_t processing_time;
      +    int size;
      +    ipp_jstate_t state;
      +    char *title;
      +    char *user;
      +};

      +

      Members

      +
      +
      completed_time
      +
      Time the job was completed
      +
      creation_time
      +
      Time the job was created
      +
      dest
      +
      Printer or class name
      +
      format
      +
      Document format
      +
      id
      +
      The job ID
      +
      priority
      +
      Priority (1-100)
      +
      processing_time
      +
      Time the job was processed
      +
      size
      +
      Size in kilobytes
      +
      state
      +
      Job state
      +
      title
      +
      Title/job name
      +
      user
      +
      User the submitted the job
      +
      +

      cups_option_s

      +

      Printer Options

      +

      struct cups_option_s {
      +    char *name;
      +    char *value;
      +};

      +

      Members

      +
      +
      name
      +
      Name of option
      +
      value
      +
      Value of option
      +
      +

      Constants

      +

      cups_ptype_e

      +

      Printer type/capability bit constants

      +

      Constants

      +
      +
      CUPS_PRINTER_AUTHENTICATED  CUPS 1.2/Mac OS X 10.5 
      +
      Printer requires authentication
      +
      CUPS_PRINTER_BIND
      +
      Can bind output
      +
      CUPS_PRINTER_BW
      +
      Can do B&W printing
      +
      CUPS_PRINTER_CLASS
      +
      Printer class
      +
      CUPS_PRINTER_COLLATE
      +
      Can collage copies
      +
      CUPS_PRINTER_COLOR
      +
      Can do color printing
      +
      CUPS_PRINTER_COMMANDS  CUPS 1.2/Mac OS X 10.5 
      +
      Printer supports maintenance commands
      +
      CUPS_PRINTER_COPIES
      +
      Can do copies
      +
      CUPS_PRINTER_COVER
      +
      Can cover output
      +
      CUPS_PRINTER_DEFAULT
      +
      Default printer on network
      +
      CUPS_PRINTER_DELETE  CUPS 1.2/Mac OS X 10.5 
      +
      Delete printer
      +
      CUPS_PRINTER_DISCOVERED  CUPS 1.3/Mac OS X 10.5 
      +
      Printer was automatically discovered and added
      +
      CUPS_PRINTER_DUPLEX
      +
      Can do duplexing
      +
      CUPS_PRINTER_FAX
      +
      Fax queue
      +
      CUPS_PRINTER_IMPLICIT
      +
      Implicit class
      +
      CUPS_PRINTER_LARGE
      +
      Can do D/E/A1/A0
      +
      CUPS_PRINTER_LOCAL
      +
      Local printer or class
      +
      CUPS_PRINTER_MEDIUM
      +
      Can do Tabloid/B/C/A3/A2
      +
      CUPS_PRINTER_MFP  CUPS 1.4/Mac OS X 10.6 
      +
      Printer with scanning capabilities
      +
      CUPS_PRINTER_NOT_SHARED  CUPS 1.2/Mac OS X 10.5 
      +
      Printer is not shared
      +
      CUPS_PRINTER_PUNCH
      +
      Can punch output
      +
      CUPS_PRINTER_REJECTING
      +
      Printer is rejecting jobs
      +
      CUPS_PRINTER_REMOTE
      +
      Remote printer or class
      +
      CUPS_PRINTER_SCANNER  CUPS 1.4/Mac OS X 10.6 
      +
      Scanner-only device
      +
      CUPS_PRINTER_SMALL
      +
      Can do Letter/Legal/A4
      +
      CUPS_PRINTER_SORT
      +
      Can sort output
      +
      CUPS_PRINTER_STAPLE
      +
      Can staple output
      +
      CUPS_PRINTER_VARIABLE
      +
      Can do variable sizes
      +
      +
+ + diff --git a/doc/help/api-driver.html b/doc/help/api-driver.html new file mode 100644 index 0000000000..b021207c7a --- /dev/null +++ b/doc/help/api-driver.html @@ -0,0 +1,1153 @@ + + + + +Printer Driver API + + + + + +
+ + +

Driver API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/driver.h
Library-lcupsdriver
See AlsoProgramming: Introduction to CUPS Programming
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • +
    • Variables
    • + + +

      Overview

      + +

      The driver API provides common dithering, color conversion, and utility +functions for CUPS drivers.

      +

      Functions

      +

      cupsCMYKDelete

      +

      Delete a color separation.

      +

      +void cupsCMYKDelete (
      +    cups_cmyk_t *cmyk
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      Color separation
      +
      +

      cupsCMYKDoBlack

      +

      Do a black separation...

      +

      +void cupsCMYKDoBlack (
      +    const cups_cmyk_t *cmyk,
      +    const unsigned char *input,
      +    short *output,
      +    int num_pixels
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      Color separation
      +
      input
      +
      Input grayscale pixels
      +
      output
      +
      Output Device-N pixels
      +
      num_pixels
      +
      Number of pixels
      +
      +

      cupsCMYKDoCMYK

      +

      Do a CMYK separation...

      +

      +void cupsCMYKDoCMYK (
      +    const cups_cmyk_t *cmyk,
      +    const unsigned char *input,
      +    short *output,
      +    int num_pixels
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      Color separation
      +
      input
      +
      Input grayscale pixels
      +
      output
      +
      Output Device-N pixels
      +
      num_pixels
      +
      Number of pixels
      +
      +

      cupsCMYKDoGray

      +

      Do a grayscale separation...

      +

      +void cupsCMYKDoGray (
      +    const cups_cmyk_t *cmyk,
      +    const unsigned char *input,
      +    short *output,
      +    int num_pixels
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      Color separation
      +
      input
      +
      Input grayscale pixels
      +
      output
      +
      Output Device-N pixels
      +
      num_pixels
      +
      Number of pixels
      +
      +

      cupsCMYKDoRGB

      +

      Do an sRGB separation...

      +

      +void cupsCMYKDoRGB (
      +    const cups_cmyk_t *cmyk,
      +    const unsigned char *input,
      +    short *output,
      +    int num_pixels
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      Color separation
      +
      input
      +
      Input grayscale pixels
      +
      output
      +
      Output Device-N pixels
      +
      num_pixels
      +
      Number of pixels
      +
      +

      cupsCMYKLoad

      +

      Load a CMYK color profile from PPD attributes.

      +

      +cups_cmyk_t *cupsCMYKLoad (
      +    ppd_file_t *ppd,
      +    const char *colormodel,
      +    const char *media,
      +    const char *resolution
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      colormodel
      +
      ColorModel value
      +
      media
      +
      MediaType value
      +
      resolution
      +
      Resolution value
      +
      +

      Return Value

      +

      CMYK color separation

      +

      cupsCMYKNew

      +

      Create a new CMYK color separation.

      +

      +cups_cmyk_t *cupsCMYKNew (
      +    int num_channels
      +);

      +

      Parameters

      +
      +
      num_channels
      +
      Number of color components
      +
      +

      Return Value

      +

      New CMYK separation or NULL

      +

      cupsCMYKSetBlack

      +

      Set the transition range for CMY to black.

      +

      +void cupsCMYKSetBlack (
      +    cups_cmyk_t *cmyk,
      +    float lower,
      +    float upper
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      CMYK color separation
      +
      lower
      +
      No black ink
      +
      upper
      +
      Only black ink
      +
      +

      cupsCMYKSetCurve

      +

      Set a color transform curve using points.

      +

      +void cupsCMYKSetCurve (
      +    cups_cmyk_t *cmyk,
      +    int channel,
      +    int num_xypoints,
      +    const float *xypoints
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      CMYK color separation
      +
      channel
      +
      Color channel
      +
      num_xypoints
      +
      Number of X,Y points
      +
      xypoints
      +
      X,Y points
      +
      +

      cupsCMYKSetGamma

      +

      Set a color transform curve using gamma and density.

      +

      +void cupsCMYKSetGamma (
      +    cups_cmyk_t *cmyk,
      +    int channel,
      +    float gamval,
      +    float density
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      CMYK color separation
      +
      channel
      +
      Ink channel
      +
      gamval
      +
      Gamma correction
      +
      density
      +
      Maximum density
      +
      +

      cupsCMYKSetInkLimit

      +

      Set the limit on the amount of ink.

      +

      +void cupsCMYKSetInkLimit (
      +    cups_cmyk_t *cmyk,
      +    float limit
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      CMYK color separation
      +
      limit
      +
      Limit of ink
      +
      +

      cupsCMYKSetLtDk

      +

      Set light/dark ink transforms.

      +

      +void cupsCMYKSetLtDk (
      +    cups_cmyk_t *cmyk,
      +    int channel,
      +    float light,
      +    float dark
      +);

      +

      Parameters

      +
      +
      cmyk
      +
      CMYK color separation
      +
      channel
      +
      Dark ink channel (+1 for light)
      +
      light
      +
      Light ink only level
      +
      dark
      +
      Dark ink only level
      +
      +

      cupsCheckBytes

      +

      Check to see if all bytes are zero.

      +

      +int cupsCheckBytes (
      +    const unsigned char *bytes,
      +    int length
      +);

      +

      Parameters

      +
      +
      bytes
      +
      Bytes to check
      +
      length
      +
      Number of bytes to check
      +
      +

      Return Value

      +

      1 if they match

      +

      cupsCheckValue

      +

      Check to see if all bytes match the given value.

      +

      +int cupsCheckValue (
      +    const unsigned char *bytes,
      +    int length,
      +    const unsigned char value
      +);

      +

      Parameters

      +
      +
      bytes
      +
      Bytes to check
      +
      length
      +
      Number of bytes to check
      +
      value
      +
      Value to check
      +
      +

      Return Value

      +

      1 if they match

      +

      cupsDitherDelete

      +

      Free a dithering buffer.

      +

      +void cupsDitherDelete (
      +    cups_dither_t *d
      +);

      +

      Parameters

      +
      +
      d
      +
      Dithering buffer
      +
      +

      Discussion

      +

      Returns 0 on success, -1 on failure.

      +

      cupsDitherLine

      +

      Dither a line of pixels...

      +

      +void cupsDitherLine (
      +    cups_dither_t *d,
      +    const cups_lut_t *lut,
      +    const short *data,
      +    int num_channels,
      +    unsigned char *p
      +);

      +

      Parameters

      +
      +
      d
      +
      Dither data
      +
      lut
      +
      Lookup table
      +
      data
      +
      Separation data
      +
      num_channels
      +
      Number of components
      +
      p
      +
      Pixels
      +
      +

      cupsDitherNew

      +

      Create an error-diffusion dithering buffer.

      +

      +cups_dither_t *cupsDitherNew (
      +    int width
      +);

      +

      Parameters

      +
      +
      width
      +
      Width of output in pixels
      +
      +

      Return Value

      +

      New state array

      +

      cupsFindAttr

      +

      Find a PPD attribute based on the colormodel, +media, and resolution.

      +

      +ppd_attr_t *cupsFindAttr (
      +    ppd_file_t *ppd,
      +    const char *name,
      +    const char *colormodel,
      +    const char *media,
      +    const char *resolution,
      +    char *spec,
      +    int specsize
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      name
      +
      Attribute name
      +
      colormodel
      +
      Color model
      +
      media
      +
      Media type
      +
      resolution
      +
      Resolution
      +
      spec
      +
      Final selection string
      +
      specsize
      +
      Size of string buffer
      +
      +

      Return Value

      +

      Matching attribute or NULL

      +

      cupsLutDelete

      +

      Free the memory used by a lookup table.

      +

      +void cupsLutDelete (
      +    cups_lut_t *lut
      +);

      +

      Parameters

      +
      +
      lut
      +
      Lookup table to free
      +
      +

      cupsLutLoad

      +

      Load a LUT from a PPD file.

      +

      +cups_lut_t *cupsLutLoad (
      +    ppd_file_t *ppd,
      +    const char *colormodel,
      +    const char *media,
      +    const char *resolution,
      +    const char *ink
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      colormodel
      +
      Color model
      +
      media
      +
      Media type
      +
      resolution
      +
      Resolution
      +
      ink
      +
      Ink name
      +
      +

      Return Value

      +

      New lookup table

      +

      cupsLutNew

      +

      Make a lookup table from a list of pixel values.

      +

      +cups_lut_t *cupsLutNew (
      +    int num_values,
      +    const float *values
      +);

      +

      Parameters

      +
      +
      num_values
      +
      Number of values
      +
      values
      +
      Lookup table values
      +
      +

      Return Value

      +

      New lookup table

      +

      Discussion

      +

      Returns a pointer to the lookup table on success, NULL on failure.

      +

      cupsPackHorizontal

      +

      Pack pixels horizontally...

      +

      +void cupsPackHorizontal (
      +    const unsigned char *ipixels,
      +    unsigned char *obytes,
      +    int width,
      +    const unsigned char clearto,
      +    const int step
      +);

      +

      Parameters

      +
      +
      ipixels
      +
      Input pixels
      +
      obytes
      +
      Output bytes
      +
      width
      +
      Number of pixels
      +
      clearto
      +
      Initial value of bytes
      +
      step
      +
      Step value between pixels
      +
      +

      cupsPackHorizontal2

      +

      Pack 2-bit pixels horizontally...

      +

      +void cupsPackHorizontal2 (
      +    const unsigned char *ipixels,
      +    unsigned char *obytes,
      +    int width,
      +    const int step
      +);

      +

      Parameters

      +
      +
      ipixels
      +
      Input pixels
      +
      obytes
      +
      Output bytes
      +
      width
      +
      Number of pixels
      +
      step
      +
      Stepping value
      +
      +

      cupsPackHorizontalBit

      +

      Pack pixels horizontally by bit...

      +

      +void cupsPackHorizontalBit (
      +    const unsigned char *ipixels,
      +    unsigned char *obytes,
      +    int width,
      +    const unsigned char clearto,
      +    const unsigned char bit
      +);

      +

      Parameters

      +
      +
      ipixels
      +
      Input pixels
      +
      obytes
      +
      Output bytes
      +
      width
      +
      Number of pixels
      +
      clearto
      +
      Initial value of bytes
      +
      bit
      +
      Bit to check
      +
      +

      cupsPackVertical

      +

      Pack pixels vertically...

      +

      +void cupsPackVertical (
      +    const unsigned char *ipixels,
      +    unsigned char *obytes,
      +    int width,
      +    const unsigned char bit,
      +    const int step
      +);

      +

      Parameters

      +
      +
      ipixels
      +
      Input pixels
      +
      obytes
      +
      Output bytes
      +
      width
      +
      Number of input pixels
      +
      bit
      +
      Output bit
      +
      step
      +
      Number of bytes between columns
      +
      +

      cupsRGBDelete

      +

      Delete a color separation.

      +

      +void cupsRGBDelete (
      +    cups_rgb_t *rgbptr
      +);

      +

      Parameters

      +
      +
      rgbptr
      +
      Color separation
      +
      +

      cupsRGBDoGray

      +

      Do a grayscale separation...

      +

      +void cupsRGBDoGray (
      +    cups_rgb_t *rgbptr,
      +    const unsigned char *input,
      +    unsigned char *output,
      +    int num_pixels
      +);

      +

      Parameters

      +
      +
      rgbptr
      +
      Color separation
      +
      input
      +
      Input grayscale pixels
      +
      output
      +
      Output Device-N pixels
      +
      num_pixels
      +
      Number of pixels
      +
      +

      cupsRGBDoRGB

      +

      Do a RGB separation...

      +

      +void cupsRGBDoRGB (
      +    cups_rgb_t *rgbptr,
      +    const unsigned char *input,
      +    unsigned char *output,
      +    int num_pixels
      +);

      +

      Parameters

      +
      +
      rgbptr
      +
      Color separation
      +
      input
      +
      Input RGB pixels
      +
      output
      +
      Output Device-N pixels
      +
      num_pixels
      +
      Number of pixels
      +
      +

      cupsRGBLoad

      +

      Load a RGB color profile from a PPD file.

      +

      +cups_rgb_t *cupsRGBLoad (
      +    ppd_file_t *ppd,
      +    const char *colormodel,
      +    const char *media,
      +    const char *resolution
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      colormodel
      +
      Color model
      +
      media
      +
      Media type
      +
      resolution
      +
      Resolution
      +
      +

      Return Value

      +

      New color profile

      +

      cupsRGBNew

      +

      Create a new RGB color separation.

      +

      +cups_rgb_t *cupsRGBNew (
      +    int num_samples,
      +    cups_sample_t *samples,
      +    int cube_size,
      +    int num_channels
      +);

      +

      Parameters

      +
      +
      num_samples
      +
      Number of samples
      +
      samples
      +
      Samples
      +
      cube_size
      +
      Size of LUT cube
      +
      num_channels
      +
      Number of color components
      +
      +

      Return Value

      +

      New color separation or NULL

      +

      Data Types

      +

      cups_cmyk_t

      +

      Simple CMYK lookup table

      +

      +typedef struct cups_cmyk_s cups_cmyk_t; +

      +

      cups_dither_t

      +

      Dithering State

      +

      +typedef struct cups_dither_s cups_dither_t; +

      +

      cups_lut_t

      +

      Lookup Table for Dithering

      +

      +typedef struct cups_lut_s cups_lut_t; +

      +

      cups_rgb_t

      +

      Color separation lookup table

      +

      +typedef struct cups_rgb_s cups_rgb_t; +

      +

      cups_sample_t

      +

      Color sample point

      +

      +typedef struct cups_sample_s cups_sample_t; +

      +

      Structures

      +

      cups_cmyk_s

      +

      Simple CMYK lookup table

      +

      struct cups_cmyk_s {
      +    unsigned char black_lut[256];
      +    short *channels[CUPS_MAX_CHAN];
      +    unsigned char color_lut[256];
      +    int ink_limit;
      +    int num_channels;
      +};

      +

      Members

      +
      +
      black_lut[256]
      +
      Black generation LUT
      +
      channels[CUPS_MAX_CHAN]
      +
      Lookup tables
      +
      color_lut[256]
      +
      Color removal LUT
      +
      ink_limit
      +
      Ink limit
      +
      num_channels
      +
      Number of components
      +
      +

      cups_dither_s

      +

      Dithering State

      +

      struct cups_dither_s {
      +    int errors[96];
      +    int row;
      +    int width;
      +};

      +

      Members

      +
      +
      errors[96]
      +
      Error values
      +
      row
      +
      Current row
      +
      width
      +
      Width of buffer
      +
      +

      cups_lut_s

      +

      Lookup Table for Dithering

      +

      struct cups_lut_s {
      +    int error;
      +    short intensity;
      +    short pixel;
      +};

      +

      Members

      +
      +
      error
      +
      Error from desired value
      +
      intensity
      +
      Adjusted intensity
      +
      pixel
      +
      Output pixel value
      +
      +

      cups_rgb_s

      +

      Color separation lookup table

      +

      struct cups_rgb_s {
      +    unsigned char black[CUPS_MAX_RGB];
      +    int cache_init;
      +    unsigned char ****colors;
      +    int cube_index[256];
      +    int cube_mult[256];
      +    int cube_size;
      +    int num_channels;
      +    unsigned char white[CUPS_MAX_RGB];
      +};

      +

      Members

      +
      +
      black[CUPS_MAX_RGB]
      +
      Cached black (sRGB = 0,0,0)
      +
      cache_init
      +
      Are cached values initialized?
      +
      colors
      +
      4-D array of sample values
      +
      cube_index[256]
      +
      Index into cube for a given sRGB value
      +
      cube_mult[256]
      +
      Multiplier value for a given sRGB value
      +
      cube_size
      +
      Size of color cube (2-N) on a side
      +
      num_channels
      +
      Number of colors per sample
      +
      white[CUPS_MAX_RGB]
      +
      Cached white (sRGB = 255,255,255)
      +
      +

      cups_sample_s

      +

      Color sample point

      +

      struct cups_sample_s {
      +    unsigned char colors[CUPS_MAX_RGB];
      +    unsigned char rgb[3];
      +};

      +

      Members

      +
      +
      colors[CUPS_MAX_RGB]
      +
      Color values
      +
      rgb[3]
      +
      sRGB values
      +
      +

      Variables

      +

      cups_scmy_lut[256]

      +

      sRGB gamma lookup table (inverted)

      +

      extern const unsigned char cups_scmy_lut[256];

      +

      cups_srgb_lut[256]

      +

      sRGB gamma lookup table

      +

      extern const unsigned char cups_srgb_lut[256];

      +
+ + diff --git a/doc/help/api-filedir.html b/doc/help/api-filedir.html new file mode 100644 index 0000000000..ada05aba56 --- /dev/null +++ b/doc/help/api-filedir.html @@ -0,0 +1,992 @@ + + + + +File and Directory APIs + + + + + +
+ + +

File and Directory APIs

+ +
+ + + + + + + + + + + + + + + + +
Headerscups/file.h
+ cups/dir.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • + + +

      Overview

      + +

      The CUPS file and directory APIs provide portable interfaces +for manipulating files and listing files and directories. Unlike +stdio FILE streams, the cupsFile functions +allow you to open more than 256 files at any given time. They +also manage the platform-specific details of locking, large file +support, line endings (CR, LF, or CR LF), and reading and writing +files using Flate ("gzip") compression. Finally, you can also +connect, read from, and write to network connections using the +cupsFile functions.

      + +

      The cupsDir functions manage the platform-specific +details of directory access/listing and provide a convenient way +to get both a list of files and the information (permissions, +size, timestamp, etc.) for each of those files.

      +

      Functions

      +

       CUPS 1.2/Mac OS X 10.5 cupsDirClose

      +

      Close a directory.

      +

      +void cupsDirClose (
      +    cups_dir_t *dp
      +);

      +

      Parameters

      +
      +
      dp
      +
      Directory pointer
      +
      +

       CUPS 1.2/Mac OS X 10.5 cupsDirOpen

      +

      Open a directory.

      +

      +cups_dir_t *cupsDirOpen (
      +    const char *directory
      +);

      +

      Parameters

      +
      +
      directory
      +
      Directory name
      +
      +

      Return Value

      +

      Directory pointer or NULL if the directory could not be opened.

      +

       CUPS 1.2/Mac OS X 10.5 cupsDirRead

      +

      Read the next directory entry.

      +

      +cups_dentry_t *cupsDirRead (
      +    cups_dir_t *dp
      +);

      +

      Parameters

      +
      +
      dp
      +
      Directory pointer
      +
      +

      Return Value

      +

      Directory entry or NULL when there are no more

      +

       CUPS 1.2/Mac OS X 10.5 cupsDirRewind

      +

      Rewind to the start of the directory.

      +

      +void cupsDirRewind (
      +    cups_dir_t *dp
      +);

      +

      Parameters

      +
      +
      dp
      +
      Directory pointer
      +
      +

       CUPS 1.2/Mac OS X 10.5 cupsFileClose

      +

      Close a CUPS file.

      +

      +int cupsFileClose (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileCompression

      +

      Return whether a file is compressed.

      +

      +int cupsFileCompression (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      CUPS_FILE_NONE or CUPS_FILE_GZIP

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileEOF

      +

      Return the end-of-file status.

      +

      +int cupsFileEOF (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      1 on end of file, 0 otherwise

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileFind

      +

      Find a file using the specified path.

      +

      +const char *cupsFileFind (
      +    const char *filename,
      +    const char *path,
      +    int executable,
      +    char *buffer,
      +    int bufsize
      +);

      +

      Parameters

      +
      +
      filename
      +
      File to find
      +
      path
      +
      Colon/semicolon-separated path
      +
      executable
      +
      1 = executable files, 0 = any file/dir
      +
      buffer
      +
      Filename buffer
      +
      bufsize
      +
      Size of filename buffer
      +
      +

      Return Value

      +

      Full path to file or NULL if not found

      +

      Discussion

      +

      This function allows the paths in the path string to be separated by +colons (UNIX standard) or semicolons (Windows standard) and stores the +result in the buffer supplied. If the file cannot be found in any of +the supplied paths, NULL is returned. A NULL path only +matches the current directory. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileFlush

      +

      Flush pending output.

      +

      +int cupsFileFlush (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileGetChar

      +

      Get a single character from a file.

      +

      +int cupsFileGetChar (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      Character or -1 on end of file

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileGetConf

      +

      Get a line from a configuration file...

      +

      +char *cupsFileGetConf (
      +    cups_file_t *fp,
      +    char *buf,
      +    size_t buflen,
      +    char **value,
      +    int *linenum
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      buf
      +
      String buffer
      +
      buflen
      +
      Size of string buffer
      +
      value
      +
      Pointer to value
      +
      linenum
      +
      Current line number
      +
      +

      Return Value

      +

      Line read or NULL on end of file or error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileGetLine

      +

      Get a CR and/or LF-terminated line that may +contain binary data.

      +

      +size_t cupsFileGetLine (
      +    cups_file_t *fp,
      +    char *buf,
      +    size_t buflen
      +);

      +

      Parameters

      +
      +
      fp
      +
      File to read from
      +
      buf
      +
      Buffer
      +
      buflen
      +
      Size of buffer
      +
      +

      Return Value

      +

      Number of bytes on line or 0 on end of file

      +

      Discussion

      +

      This function differs from cupsFileGets in that the trailing CR +and LF are preserved, as is any binary data on the line. The buffer is +nul-terminated, however you should use the returned length to determine +the number of bytes on the line. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileGets

      +

      Get a CR and/or LF-terminated line.

      +

      +char *cupsFileGets (
      +    cups_file_t *fp,
      +    char *buf,
      +    size_t buflen
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      buf
      +
      String buffer
      +
      buflen
      +
      Size of string buffer
      +
      +

      Return Value

      +

      Line read or NULL on end of file or error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileLock

      +

      Temporarily lock access to a file.

      +

      +int cupsFileLock (
      +    cups_file_t *fp,
      +    int block
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      block
      +
      1 to wait for the lock, 0 to fail right away
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileNumber

      +

      Return the file descriptor associated with a CUPS file.

      +

      +int cupsFileNumber (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      File descriptor

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileOpen

      +

      Open a CUPS file.

      +

      +cups_file_t *cupsFileOpen (
      +    const char *filename,
      +    const char *mode
      +);

      +

      Parameters

      +
      +
      filename
      +
      Name of file
      +
      mode
      +
      Open mode
      +
      +

      Return Value

      +

      CUPS file or NULL if the file or socket cannot be opened

      +

      Discussion

      +

      The "mode" parameter can be "r" to read, "w" to write, overwriting any +existing file, "a" to append to an existing file or create a new file, +or "s" to open a socket connection.
      +
      +When opening for writing ("w"), an optional number from 1 to 9 can be +supplied which enables Flate compression of the file. Compression is +not supported for the "a" (append) mode.
      +
      +When opening a socket connection, the filename is a string of the form +"address:port" or "hostname:port". The socket will make an IPv4 or IPv6 +connection as needed, generally preferring IPv6 connections when there is +a choice. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileOpenFd

      +

      Open a CUPS file using a file descriptor.

      +

      +cups_file_t *cupsFileOpenFd (
      +    int fd,
      +    const char *mode
      +);

      +

      Parameters

      +
      +
      fd
      +
      File descriptor
      +
      mode
      +
      Open mode
      +
      +

      Return Value

      +

      CUPS file or NULL if the file could not be opened

      +

      Discussion

      +

      The "mode" parameter can be "r" to read, "w" to write, "a" to append, +or "s" to treat the file descriptor as a bidirectional socket connection.
      +
      +When opening for writing ("w"), an optional number from 1 to 9 can be +supplied which enables Flate compression of the file. Compression is +not supported for the "a" (append) mode. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsFilePeekChar

      +

      Peek at the next character from a file.

      +

      +int cupsFilePeekChar (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      Character or -1 on end of file

      +

       CUPS 1.2/Mac OS X 10.5 cupsFilePrintf

      +

      Write a formatted string.

      +

      +int cupsFilePrintf (
      +    cups_file_t *fp,
      +    const char *format,
      +    ...
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      format
      +
      Printf-style format string
      +
      ...
      +
      Additional args as necessary
      +
      +

      Return Value

      +

      Number of bytes written or -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFilePutChar

      +

      Write a character.

      +

      +int cupsFilePutChar (
      +    cups_file_t *fp,
      +    int c
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      c
      +
      Character to write
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

       CUPS 1.4/Mac OS X 10.6 cupsFilePutConf

      +

      Write a configuration line.

      +

      +ssize_t cupsFilePutConf (
      +    cups_file_t *fp,
      +    const char *directive,
      +    const char *value
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      directive
      +
      Directive
      +
      value
      +
      Value
      +
      +

      Return Value

      +

      Number of bytes written or -1 on error

      +

      Discussion

      +

      This function handles any comment escaping of the value. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsFilePuts

      +

      Write a string.

      +

      +int cupsFilePuts (
      +    cups_file_t *fp,
      +    const char *s
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      s
      +
      String to write
      +
      +

      Return Value

      +

      Number of bytes written or -1 on error

      +

      Discussion

      +

      Like the fputs function, no newline is appended to the string. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileRead

      +

      Read from a file.

      +

      +ssize_t cupsFileRead (
      +    cups_file_t *fp,
      +    char *buf,
      +    size_t bytes
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      buf
      +
      Buffer
      +
      bytes
      +
      Number of bytes to read
      +
      +

      Return Value

      +

      Number of bytes read or -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileRewind

      +

      Set the current file position to the beginning of the +file.

      +

      +off_t cupsFileRewind (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      New file position or -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileSeek

      +

      Seek in a file.

      +

      +off_t cupsFileSeek (
      +    cups_file_t *fp,
      +    off_t pos
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      pos
      +
      Position in file
      +
      +

      Return Value

      +

      New file position or -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileStderr

      +

      Return a CUPS file associated with stderr.

      +

      +cups_file_t *cupsFileStderr (void);

      +

      Return Value

      +

      CUPS file

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileStdin

      +

      Return a CUPS file associated with stdin.

      +

      +cups_file_t *cupsFileStdin (void);

      +

      Return Value

      +

      CUPS file

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileStdout

      +

      Return a CUPS file associated with stdout.

      +

      +cups_file_t *cupsFileStdout (void);

      +

      Return Value

      +

      CUPS file

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileTell

      +

      Return the current file position.

      +

      +off_t cupsFileTell (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      File position

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileUnlock

      +

      Unlock access to a file.

      +

      +int cupsFileUnlock (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

       CUPS 1.2/Mac OS X 10.5 cupsFileWrite

      +

      Write to a file.

      +

      +ssize_t cupsFileWrite (
      +    cups_file_t *fp,
      +    const char *buf,
      +    size_t bytes
      +);

      +

      Parameters

      +
      +
      fp
      +
      CUPS file
      +
      buf
      +
      Buffer
      +
      bytes
      +
      Number of bytes to write
      +
      +

      Return Value

      +

      Number of bytes written or -1 on error

      +

      Data Types

      +

      cups_dentry_t

      +

      Directory entry type

      +

      +typedef struct cups_dentry_s cups_dentry_t; +

      +

      cups_dir_t

      +

      Directory type

      +

      +typedef struct _cups_dir_s cups_dir_t; +

      +

      cups_file_t

      +

      CUPS file type

      +

      +typedef struct _cups_file_s cups_file_t; +

      +

      Structures

      +

      cups_dentry_s

      +

      Directory entry type

      +

      struct cups_dentry_s {
      +    struct stat fileinfo;
      +    char filename[260];
      +};

      +

      Members

      +
      +
      fileinfo
      +
      File information
      +
      filename[260]
      +
      File name
      +
      +
+ + diff --git a/doc/help/api-filter.html b/doc/help/api-filter.html new file mode 100644 index 0000000000..22a1ff402c --- /dev/null +++ b/doc/help/api-filter.html @@ -0,0 +1,1420 @@ + + + + +Filter and Backend Programming + + + + + +
+ + +

Filter and Backend Programming

+ +
+ + + + + + + + + + + + + + + + +
Headerscups/backend.h
+ cups/sidechannel.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ Programming: PPD API
+ Programming: Raster API
+ Programming: Developing PostScript Printer Drivers
+ Programming: Developing Raster Printer Drivers
+ Specifications: CUPS Design Description
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Constants
    • + + +

      Overview

      + +

      Filters (which include printer drivers and port monitors) and backends +are used to convert job files to a printable format and send that data to the +printer itself. All of these programs use a common interface for processing +print jobs and communicating status information to the scheduler. Each is run +with a standard set of command-line arguments:

      + +

      + +
      argv[1]
      +
      The job ID
      + +
      argv[2]
      +
      The user printing the job
      + +
      argv[3]
      +
      The job name/title
      + +
      argv[4]
      +
      The number of copies to print
      + +
      argv[5]
      +
      The options that were provided when the job was submitted
      + +
      argv[6]
      +
      The file to print (first program only)
      +
      + +

      The scheduler runs one or more of these programs to print any given job. The +first filter reads from the print file and writes to the standard output, while +the remaining filters read from the standard input and write to the standard +output. The backend is the last filter in the chain and writes to the +device.

      + +

      Filters are always run as a non-privileged user, typically "lp", with no +connection to the user's desktop. Backends are run either as a non-privileged +user or as root if the file permissions do not allow user or group execution. +The file permissions section talks about this in +more detail.

      + +

      Security Considerations

      + +

      It is always important to use security programming practices. Filters and +most backends are run as a non-privileged user, so the major security +consideration is resource utilization - filters should not depend on unlimited +amounts of CPU, memory, or disk space, and should protect against conditions +that could lead to excess usage of any resource like infinite loops and +unbounded recursion. In addition, filters must never allow the user to +specify an arbitrary file path to a separator page, template, or other file +used by the filter since that can lead to an unauthorized disclosure of +information. Always treat input as suspect and validate it!

      + +

      If you are developing a backend that runs as root, make sure to check for +potential buffer overflows, integer under/overflow conditions, and file +accesses since these can lead to privilege escalations. When writing files, +always validate the file path and never allow a user to determine +where to store a file.

      + +
      Note: + +

      Never write files to a user's home directory. Aside from the +security implications, CUPS is a network print service and as such the network +user may not be the same as the local user and/or there may not be a local home +directory to write to.

      + +

      In addition, some operating systems provide additional security mechanisms +that further limit file system access, even for backends running as root. On +Mac OS X, for example, no backend may write to a user's home directory.

      +
      + +

      File Permissions

      + +

      For security reasons, CUPS will only run filters and backends that are owned +by root and do not have world or group write permissions. The recommended +permissions for filters and backends are 0555 - read and execute but no write. +Backends that must run as root should use permissions of 0500 - read and execute +by root, no access for other users. Write permissions can be enabled for the +root user only.

      + +

      To avoid a warning message, the directory containing your filter(s) must also +be owned by root and have world and group write disabled - permissions of 0755 +or 0555 are strongly encouraged.

      + +

      Temporary Files

      + +

      Temporary files should be created in the directory specified by the +"TMPDIR" environment variable. The +cupsTempFile2 function can be +used to safely create temporary files in this directory.

      + +

      Copy Generation

      + +

      The argv[4] argument specifies the number of copies to produce +of the input file. In general, you should only generate copies if the +filename argument is supplied. The only exception to this are +filters that produce device-independent PostScript output, since the PostScript +filter pstops is responsible for generating copies of PostScript +files.

      + +

      Exit Codes

      + +

      Filters must exit with status 0 when they successfully generate print data +or 1 when they encounter an error. Backends can return any of the +cups_backend_t constants.

      + +

      Environment Variables

      + +

      The following environment variables are defined by the printing system +when running print filters and backends:

      + +
      + +
      APPLE_LANGUAGE
      +
      The Apple language identifier associated with the job + (Mac OS X only).
      + +
      CHARSET
      +
      The job character set, typically "utf-8".
      + +
      CLASS
      +
      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.
      + +
      CONTENT_TYPE
      +
      The MIME type associated with the file (e.g. + application/postscript).
      + +
      CUPS_CACHEDIR
      +
      The directory where cache files can be stored. Cache files can be + used to retain information between jobs or files in a job.
      + +
      CUPS_DATADIR
      +
      The directory where (read-only) CUPS data files can be found.
      + +
      CUPS_FILETYPE
      +
      The type of file being printed: "job-sheet" for a banner page and + "document" for a regular print file.
      + +
      CUPS_SERVERROOT
      +
      The root directory of the server.
      + +
      DEVICE_URI
      +
      The device-uri associated with the printer.
      + +
      FINAL_CONTENT_TYPE
      +
      The MIME type associated with the printer (e.g. + application/vnd.cups-postscript).
      + +
      LANG
      +
      The language locale associated with the job.
      + +
      PPD
      +
      The full pathname of the PostScript Printer Description (PPD) + file for this printer.
      + +
      PRINTER
      +
      The queue name of the class or printer.
      + +
      RIP_CACHE
      +
      The recommended amount of memory to use for Raster Image + Processors (RIPs).
      + +
      TMPDIR
      +
      The directory where temporary files should be created.
      + +
      + +

      Communicating with the Scheduler

      + +

      Filters and backends communicate with the scheduler by writing messages +to the standard error file. The scheduler reads messages from all filters in +a job and processes the message based on its prefix. For example, the following +code sets the current printer state message to "Printing page 5":

      + +
      +int page = 5;
      +
      +fprintf(stderr, "INFO: Printing page %d\n", page);
      +
      + +

      Each message is a single line of text starting with one of the following +prefix strings:

      + +
      + +
      ALERT: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "alert" log level.
      + +
      ATTR: attribute=value [attribute=value]
      +
      Sets the named printer or job attribute(s). Typically this is used + to set the marker-colors, marker-levels, + marker-message, marker-names, + marker-types, printer-alert, and + printer-alert-description printer attributes. Standard + marker-types values are listed in Table + 1.
      + +
      CRIT: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "critical" log + level.
      + +
      DEBUG: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "debug" log level.
      + +
      DEBUG2: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "debug2" log level.
      + +
      EMERG: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "emergency" log + level.
      + +
      ERROR: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "error" log level. + Use "ERROR:" messages for non-persistent processing errors.
      + +
      INFO: message
      +
      Sets the printer-state-message attribute. If the current log level + is set to "debug2", also adds the specified message to the current error + log file using the "info" log level.
      + +
      NOTICE: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "notice" log level.
      + +
      PAGE: page-number #-copies
      +
      PAGE: total #-pages
      +
      Adds an entry to the current page log file. The first form adds + #-copies to the job-media-sheets-completed attribute. The second + form sets the job-media-sheets-completed attribute to #-pages.
      + +
      PPD: keyword=value [keyword=value ...]
      +
      Changes or adds keywords to the printer's PPD file. Typically + this is used to update installable options or default media settings + based on the printer configuration.
      + +
      STATE: printer-state-reason [printer-state-reason ...]
      +
      STATE: + printer-state-reason [printer-state-reason ...]
      +
      STATE: - printer-state-reason [printer-state-reason ...]
      +
      Sets, adds, or removes printer-state-reason keywords to the + current queue. Typically this is used to indicate persistent media, + ink, toner, and configuration conditions or errors on a printer. + Table 2 lists the standard state keywords - + use vendor-prefixed ("com.acme.foo") keywords for custom states. + +
      Note: + +

      "STATE:" messages often provide visible alerts to the user. For example, on + Mac OS X setting a printer-state-reason value with an "-error" or "-warning" + suffix will cause the printer's dock item to bounce if the corresponding reason + is localized with a cupsIPPReason keyword in the printer's PPD file.

      + +
      + +
      WARNING: message
      +
      Sets the printer-state-message attribute and adds the specified + message to the current error log file using the "warning" log + level.
      + +
      + +

      Messages without one of these prefixes are treated as if they began with +the "DEBUG:" prefix string.

      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Table 1: Standard marker-types Values
      marker-typeDescription
      developerDeveloper unit
      fuserFuser unit
      fuserCleaningPadFuser cleaning pad
      fuserOilFuser oil
      inkInk supply
      opcPhoto conductor
      solidWaxWax supply
      staplesStaple supply
      tonerToner supply
      transferUnitTransfer unit
      wasteInkWaste ink tank
      wasteTonerWaste toner tank
      wasteWaxWaste wax tank
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Table 2: Standard State Keywords
      KeywordDescription
      connecting-to-deviceConnecting to printer but not printing yet
      cover-openA cover is open on the printer
      input-tray-missingAn input tray is missing from the printer
      marker-supply-emptyOut of ink
      marker-supply-lowLow on ink
      marker-waste-almost-fullWaste tank almost full
      marker-waste-fullWaste tank full
      media-emptyOut of media
      media-jamMedia is jammed in the printer
      media-lowLow on media
      pausedStop the printer
      timed-outUnable to connect to printer
      toner-emptyOut of toner
      toner-lowLow on toner
      + +

      Communicating with the Backend

      + +

      Filters can communicate with the backend via the +cupsBackChannelRead and +cupsSideChannelDoRequest +functions. The +cupsBackChannelRead function +reads data that has been sent back from the device and is typically used to +obtain status and configuration information. For example, the following code +polls the backend for back-channel data:

      + +
      +#include <cups/cups.h>
      +
      +char buffer[8192];
      +ssize_t bytes;
      +
      +/* Use a timeout of 0.0 seconds to poll for back-channel data */
      +bytes = cupsBackChannelRead(buffer, sizeof(buffer), 0.0);
      +
      + +

      Filters can also use select() or poll() on the +back-channel file descriptor (3 or CUPS_BC_FD) to read data only +when it is available.

      + +

      The +cupsSideChannelDoRequest +function allows you to get out-of-band status information and do synchronization +with the device. For example, the following code gets the current IEEE-1284 +device ID string from the backend:

      + +
      +#include <cups/sidechannel.h>
      +
      +char data[2049];
      +int datalen;
      +cups_sc_status_t status;
      +
      +/* Tell cupsSideChannelDoRequest() how big our buffer is, less 1 byte for
      +   nul-termination... */
      +datalen = sizeof(data) - 1;
      +
      +/* Get the IEEE-1284 device ID, waiting for up to 1 second */
      +status = cupsSideChannelDoRequest(CUPS_SC_CMD_GET_DEVICE_ID, data, &datalen, 1.0);
      +
      +/* Use the returned value if OK was returned and the length is non-zero */
      +if (status == CUPS_SC_STATUS_OK && datalen > 0)
      +  data[datalen] = '\0';
      +else
      +  data[0] = '\0';
      +
      + +

      Communicating with Filters

      + +

      Backends communicate with filters using the reciprocal functions +cupsBackChannelWrite, +cupsSideChannelRead, and +cupsSideChannelWrite. We +recommend writing back-channel data using a timeout of 1.0 seconds:

      + +
      +#include <cups/cups.h>
      +
      +char buffer[8192];
      +ssize_t bytes;
      +
      +/* Obtain data from printer/device */
      +...
      +
      +/* Use a timeout of 1.0 seconds to give filters a chance to read */
      +cupsBackChannelWrite(buffer, bytes, 1.0);
      +
      + +

      The cupsSideChannelRead +function reads a side-channel command from a filter, driver, or port monitor. +Backends can either poll for commands using a timeout of 0.0, wait +indefinitely for commands using a timeout of -1.0 (probably in a +separate thread for that purpose), or use select or +poll on the CUPS_SC_FD file descriptor (4) to handle +input and output on several file descriptors at the same time.

      + +

      Once a command is processed, the backend uses the +cupsSideChannelWrite function +to send its response. For example, the following code shows how to poll for a +side-channel command and respond to it:

      + +
      +#include <cups/sidechannel.h>
      +
      +cups_sc_command_t command;
      +cups_sc_status_t status;
      +char data[2048];
      +int datalen = sizeof(data);
      +
      +/* Poll for a command... */
      +if (!cupsSideChannelRead(&command, &status, data, &datalen, 0.0))
      +{
      +  switch (command)
      +  {
      +    /* handle supported commands, fill data/datalen/status with values as needed */
      +
      +    default :
      +        status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
      +	datalen = 0;
      +	break;
      +  }
      +
      +  /* Send a response... */
      +  cupsSideChannelWrite(command, status, data, datalen, 1.0);
      +}
      +
      + +

      Doing SNMP Queries with Network Printers

      + +

      The Simple Network Management Protocol (SNMP) allows you to get the current +status, page counter, and supply levels from most network printers. Every +piece of information is associated with an Object Identifier (OID), and +every printer has a community name associated with it. OIDs can be +queried directly or by "walking" over a range of OIDs with a common prefix.

      + +

      The two CUPS SNMP functions provide a simple API for querying network +printers through the side-channel interface. Each accepts a string containing +an OID like ".1.3.6.1.2.1.43.10.2.1.4.1.1" (the standard page counter OID) +along with a timeout for the query.

      + +

      The cupsSideChannelSNMPGet +function queries a single OID and returns the value as a string in a buffer +you supply:

      + +
      +#include <cups/sidechannel.h>
      +
      +char data[512];
      +int datalen = sizeof(data);
      +
      +if (cupsSideChannelSNMPGet(".1.3.6.1.2.1.43.10.2.1.4.1.1", data, &datalen, 5.0)
      +        == CUPS_SC_STATUS_OK)
      +{
      +  /* Do something with the value */
      +  printf("Page counter is: %s\n", data);
      +}
      +
      + +

      The +cupsSideChannelSNMPWalk +function allows you to query a whole group of OIDs, calling a function of your +choice for each OID that is found:

      + +
      +#include <cups/sidechannel.h>
      +
      +void
      +my_callback(const char *oid, const char *data, int datalen, void *context)
      +{
      +  /* Do something with the value */
      +  printf("%s=%s\n", oid, data);
      +}
      +
      +...
      +
      +void *my_data;
      +
      +cupsSNMPSideChannelWalk(".1.3.6.1.2.1.43", 5.0, my_callback, my_data);
      +
      +

      Functions

      +

       CUPS 1.2/Mac OS X 10.5 cupsBackChannelRead

      +

      Read data from the backchannel.

      +

      +ssize_t cupsBackChannelRead (
      +    char *buffer,
      +    size_t bytes,
      +    double timeout
      +);

      +

      Parameters

      +
      +
      buffer
      +
      Buffer to read into
      +
      bytes
      +
      Bytes to read
      +
      timeout
      +
      Timeout in seconds, typically 0.0 to poll
      +
      +

      Return Value

      +

      Bytes read or -1 on error

      +

      Discussion

      +

      Reads up to "bytes" bytes from the backchannel/backend. The "timeout" +parameter controls how many seconds to wait for the data - use 0.0 to +return immediately if there is no data, -1.0 to wait for data indefinitely. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsBackChannelWrite

      +

      Write data to the backchannel.

      +

      +ssize_t cupsBackChannelWrite (
      +    const char *buffer,
      +    size_t bytes,
      +    double timeout
      +);

      +

      Parameters

      +
      +
      buffer
      +
      Buffer to write
      +
      bytes
      +
      Bytes to write
      +
      timeout
      +
      Timeout in seconds, typically 1.0
      +
      +

      Return Value

      +

      Bytes written or -1 on error

      +

      Discussion

      +

      Writes "bytes" bytes to the backchannel/filter. The "timeout" parameter +controls how many seconds to wait for the data to be written - use +0.0 to return immediately if the data cannot be written, -1.0 to wait +indefinitely. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsBackendDeviceURI

      +

      Get the device URI for a backend.

      +

      +const char *cupsBackendDeviceURI (
      +    char **argv
      +);

      +

      Parameters

      +
      +
      argv
      +
      Command-line arguments
      +
      +

      Return Value

      +

      Device URI or NULL

      +

      Discussion

      +

      The "argv" argument is the argv argument passed to main(). This +function returns the device URI passed in the DEVICE_URI environment +variable or the device URI passed in argv[0], whichever is found +first. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsBackendReport

      +

      Write a device line from a backend.

      +

      +void cupsBackendReport (
      +    const char *device_scheme,
      +    const char *device_uri,
      +    const char *device_make_and_model,
      +    const char *device_info,
      +    const char *device_id,
      +    const char *device_location
      +);

      +

      Parameters

      +
      +
      device_scheme
      +
      device-scheme string
      +
      device_uri
      +
      device-uri string
      +
      device_make_and_model
      +
      device-make-and-model string or NULL
      +
      device_info
      +
      device-info string or NULL
      +
      device_id
      +
      device-id string or NULL
      +
      device_location
      +
      device-location string or NULL
      +
      +

      Discussion

      +

      This function writes a single device line to stdout for a backend. +It handles quoting of special characters in the device-make-and-model, +device-info, device-id, and device-location strings. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsSideChannelDoRequest

      +

      Send a side-channel command to a backend and wait for a response.

      +

      +cups_sc_status_t cupsSideChannelDoRequest (
      +    cups_sc_command_t command,
      +    char *data,
      +    int *datalen,
      +    double timeout
      +);

      +

      Parameters

      +
      +
      command
      +
      Command to send
      +
      data
      +
      Response data buffer pointer
      +
      datalen
      +
      Size of data buffer on entry, number of bytes in buffer on return
      +
      timeout
      +
      Timeout in seconds
      +
      +

      Return Value

      +

      Status of command

      +

      Discussion

      +

      This function is normally only called by filters, drivers, or port +monitors in order to communicate with the backend used by the current +printer. Programs must be prepared to handle timeout or "not +implemented" status codes, which indicate that the backend or device +do not support the specified side-channel command.
      +
      +The "datalen" parameter must be initialized to the size of the buffer +pointed to by the "data" parameter. cupsSideChannelDoRequest() will +update the value to contain the number of data bytes in the buffer. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsSideChannelRead

      +

      Read a side-channel message.

      +

      +int cupsSideChannelRead (
      +    cups_sc_command_t *command,
      +    cups_sc_status_t *status,
      +    char *data,
      +    int *datalen,
      +    double timeout
      +);

      +

      Parameters

      +
      +
      command
      +
      Command code
      +
      status
      +
      Status code
      +
      data
      +
      Data buffer pointer
      +
      datalen
      +
      Size of data buffer on entry, number of bytes in buffer on return
      +
      timeout
      +
      Timeout in seconds
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

      Discussion

      +

      This function is normally only called by backend programs to read +commands from a filter, driver, or port monitor program. The +caller must be prepared to handle incomplete or invalid messages +and return the corresponding status codes.
      +
      +The "datalen" parameter must be initialized to the size of the buffer +pointed to by the "data" parameter. cupsSideChannelDoRequest() will +update the value to contain the number of data bytes in the buffer. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsSideChannelSNMPGet

      +

      Query a SNMP OID's value.

      +

      +cups_sc_status_t cupsSideChannelSNMPGet (
      +    const char *oid,
      +    char *data,
      +    int *datalen,
      +    double timeout
      +);

      +

      Parameters

      +
      +
      oid
      +
      OID to query
      +
      data
      +
      Buffer for OID value
      +
      datalen
      +
      Size of OID buffer on entry, size of value on return
      +
      timeout
      +
      Timeout in seconds
      +
      +

      Return Value

      +

      Query status

      +

      Discussion

      +

      This function asks the backend to do a SNMP OID query on behalf of the +filter, port monitor, or backend using the default community name.
      +
      +"oid" contains a numeric OID consisting of integers separated by periods, +for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not +supported and must be converted to their numeric forms.
      +
      +On input, "data" and "datalen" provide the location and size of the +buffer to hold the OID value as a string. HEX-String (binary) values are +converted to hexadecimal strings representing the binary data, while +NULL-Value and unknown OID types are returned as the empty string. +The returned "datalen" does not include the trailing nul. + +CUPS_SC_STATUS_NOT_IMPLEMENTED is returned by backends that do not +support SNMP queries. CUPS_SC_STATUS_NO_RESPONSE is returned when +the printer does not respond to the SNMP query. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsSideChannelSNMPWalk

      +

      Query multiple SNMP OID values.

      +

      +cups_sc_status_t cupsSideChannelSNMPWalk (
      +    const char *oid,
      +    double timeout,
      +    cups_sc_walk_func_t cb,
      +    void *context
      +);

      +

      Parameters

      +
      +
      oid
      +
      First numeric OID to query
      +
      timeout
      +
      Timeout for each query in seconds
      +
      cb
      +
      Function to call with each value
      +
      context
      +
      Application-defined pointer to send to callback
      +
      +

      Return Value

      +

      Status of first query of CUPS_SC_STATUS_OK on success

      +

      Discussion

      +

      This function asks the backend to do multiple SNMP OID queries on behalf +of the filter, port monitor, or backend using the default community name. +All OIDs under the "parent" OID are queried and the results are sent to +the callback function you provide.
      +
      +"oid" contains a numeric OID consisting of integers separated by periods, +for example ".1.3.6.1.2.1.43". Symbolic names from SNMP MIBs are not +supported and must be converted to their numeric forms.
      +
      +"timeout" specifies the timeout for each OID query. The total amount of +time will depend on the number of OID values found and the time required +for each query.
      +
      +"cb" provides a function to call for every value that is found. "context" +is an application-defined pointer that is sent to the callback function +along with the OID and current data. The data passed to the callback is the +same as returned by cupsSideChannelSNMPGet. + +CUPS_SC_STATUS_NOT_IMPLEMENTED is returned by backends that do not +support SNMP queries. CUPS_SC_STATUS_NO_RESPONSE is returned when +the printer does not respond to the first SNMP query. + +

      +

       CUPS 1.3/Mac OS X 10.5 cupsSideChannelWrite

      +

      Write a side-channel message.

      +

      +int cupsSideChannelWrite (
      +    cups_sc_command_t command,
      +    cups_sc_status_t status,
      +    const char *data,
      +    int datalen,
      +    double timeout
      +);

      +

      Parameters

      +
      +
      command
      +
      Command code
      +
      status
      +
      Status code
      +
      data
      +
      Data buffer pointer
      +
      datalen
      +
      Number of bytes of data
      +
      timeout
      +
      Timeout in seconds
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

      Discussion

      +

      This function is normally only called by backend programs to send +responses to a filter, driver, or port monitor program. + +

      +

      Data Types

      +

      cups_backend_t

      +

      Backend exit codes

      +

      +typedef enum cups_backend_e cups_backend_t; +

      +

      cups_sc_bidi_t

      +

      Bidirectional capabilities

      +

      +typedef enum cups_sc_bidi_e cups_sc_bidi_t; +

      +

      cups_sc_command_t

      +

      Request command codes

      +

      +typedef enum cups_sc_command_e cups_sc_command_t; +

      +

      cups_sc_state_t

      +

      Printer state bits

      +

      +typedef enum cups_sc_state_e cups_sc_state_t; +

      +

      cups_sc_status_t

      +

      Response status codes

      +

      +typedef enum cups_sc_status_e cups_sc_status_t; +

      +

      cups_sc_walk_func_t

      +

      SNMP walk callback

      +

      +typedef void (*cups_sc_walk_func_t)(const char *oid, const char *data, int datalen, void *context); +

      +

      Constants

      +

      cups_backend_e

      +

      Backend exit codes

      +

      Constants

      +
      +
      CUPS_BACKEND_AUTH_REQUIRED
      +
      Job failed, authentication required
      +
      CUPS_BACKEND_CANCEL
      +
      Job failed, cancel job
      +
      CUPS_BACKEND_FAILED
      +
      Job failed, use error-policy
      +
      CUPS_BACKEND_HOLD
      +
      Job failed, hold job
      +
      CUPS_BACKEND_OK
      +
      Job completed successfully
      +
      CUPS_BACKEND_STOP
      +
      Job failed, stop queue
      +
      +

      cups_sc_bidi_e

      +

      Bidirectional capability values

      +

      Constants

      +
      +
      CUPS_SC_BIDI_NOT_SUPPORTED
      +
      Bidirectional I/O is not supported
      +
      CUPS_SC_BIDI_SUPPORTED
      +
      Bidirectional I/O is supported
      +
      +

      cups_sc_command_e

      +

      Request command codes

      +

      Constants

      +
      +
      CUPS_SC_CMD_DRAIN_OUTPUT
      +
      Drain all pending output
      +
      CUPS_SC_CMD_GET_BIDI
      +
      Return bidirectional capabilities
      +
      CUPS_SC_CMD_GET_DEVICE_ID
      +
      Return the IEEE-1284 device ID
      +
      CUPS_SC_CMD_GET_STATE
      +
      Return the device state
      +
      CUPS_SC_CMD_SNMP_GET  CUPS 1.4/Mac OS X 10.6 
      +
      Query an SNMP OID
      +
      CUPS_SC_CMD_SNMP_GET_NEXT  CUPS 1.4/Mac OS X 10.6 
      +
      Query the next SNMP OID
      +
      CUPS_SC_CMD_SOFT_RESET
      +
      Do a soft reset
      +
      +

      cups_sc_state_e

      +

      Printer state bits

      +

      Constants

      +
      +
      CUPS_SC_STATE_BUSY
      +
      Device is busy
      +
      CUPS_SC_STATE_ERROR
      +
      Other error condition
      +
      CUPS_SC_STATE_MARKER_EMPTY
      +
      Toner/ink out condition
      +
      CUPS_SC_STATE_MARKER_LOW
      +
      Toner/ink low condition
      +
      CUPS_SC_STATE_MEDIA_EMPTY
      +
      Paper out condition
      +
      CUPS_SC_STATE_MEDIA_LOW
      +
      Paper low condition
      +
      CUPS_SC_STATE_OFFLINE
      +
      Device is offline
      +
      CUPS_SC_STATE_ONLINE
      +
      Device is online
      +
      +

      cups_sc_status_e

      +

      Response status codes

      +

      Constants

      +
      +
      CUPS_SC_STATUS_BAD_MESSAGE
      +
      The command/response message was invalid
      +
      CUPS_SC_STATUS_IO_ERROR
      +
      An I/O error occurred
      +
      CUPS_SC_STATUS_NONE
      +
      No status
      +
      CUPS_SC_STATUS_NOT_IMPLEMENTED
      +
      Command not implemented
      +
      CUPS_SC_STATUS_NO_RESPONSE
      +
      The device did not respond
      +
      CUPS_SC_STATUS_OK
      +
      Operation succeeded
      +
      CUPS_SC_STATUS_TIMEOUT
      +
      The backend did not respond
      +
      CUPS_SC_STATUS_TOO_BIG
      +
      Response too big
      +
      +
+ + diff --git a/doc/help/api-httpipp.html b/doc/help/api-httpipp.html new file mode 100644 index 0000000000..76c45bde8f --- /dev/null +++ b/doc/help/api-httpipp.html @@ -0,0 +1,4191 @@ + + + + +HTTP and IPP APIs + + + + + +
+ + +

HTTP and IPP APIs

+ +
+ + + + + + + + + + + + + + + + +
Headercups/cups.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ References: CUPS Implementation of IPP
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • +
    • Unions
    • +
    • Constants
    • + + +

      Overview

      + +

      The CUPS HTTP and IPP APIs provide low-level access to the HTTP and IPP +protocols and CUPS scheduler. They are typically used by monitoring and +administration programs to perform specific functions not supported by the +high-level CUPS API functions.

      + +

      The HTTP APIs use an opaque structure called +http_t to manage connections to +a particular HTTP or IPP server. The +httpConnectEncrypt function is +used to create an instance of this structure for a particular server. +The constant CUPS_HTTP_DEFAULT can be used with all of the +cups functions to refer to the default CUPS server - the functions +create a per-thread http_t as needed.

      + +

      The IPP APIs use two structures for requests (messages sent to the CUPS +scheduler) and responses (messages sent back to your application from the +scheduler). The ipp_t structure holds a +complete request or response and is allocated using the +ippNew or +ippNewRequest functions and +freed using the ippDelete function.

      + +

      The second structure is called +ipp_attribute_t and holds a +single IPP attribute which consists of a group tag (group_tag), a +value type tag (value_tag), the attribute name (name), +and 1 or more values (values[]). Attributes are added to an +ipp_t structure using one of the +ippAdd functions. For example, use +ippAddString to add a +"requesting-user-name" string attribute to a request:

      + +
      +ipp_t *request = ippNewRequest(IPP_GET_JOBS);
      +
      +ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
      +             NULL, cupsUser());
      +
      + +

      Once you have created an IPP request, use the cups +functions to send the request to and read the response from the server. +For example, the cupsDoRequest +function can be used for simple query operations that do not involve files:

      + +
      +#include <cups/cups.h>
      +
      +
      +ipp_t *get_jobs(void)
      +{
      +  ipp_t *request = ippNewRequest(IPP_GET_JOBS);
      +
      +  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
      +               NULL, cupsUser());
      +
      +  return (cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/"));
      +}
      +
      + +

      The cupsDoRequest function frees +the request structure and returns an IPP response structure or NULL pointer if +the request could not be sent to the server. Once you have a response from +the server, you can either use the +ippFindAttribute and +ippFindNextAttribute functions +to find specific attributes, for example:

      + +
      +ipp_t *response;
      +ipp_attribute_t *attr;
      +
      +attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM);
      +
      + +

      You can also walk the list of attributes with a simple for loop +like this:

      + +
      +ipp_t *response;
      +ipp_attribute_t *attr;
      +
      +for (attr = response->attrs; attr != NULL; attr = attr->next)
      +  if (attr->name == NULL)
      +    puts("--SEPARATOR--");
      +  else
      +    puts(attr->name);
      +
      + +

      The for loop approach is normally used when collecting +attributes for multiple objects (jobs, printers, etc.) in a response. Attributes +with NULL names indicate a separator between the attributes of +each object. For example, the following code will list the jobs returned from +our previous get_jobs example code:

      + +
      +ipp_t *response = get_jobs();
      +
      +if (response != NULL)
      +{
      +  ipp_attribute_t *attr;
      +  int job_id = 0;
      +  char *job_name = NULL;
      +  char *job_originating_user_name = NULL;
      +
      +  puts("Job ID  Owner             Title");
      +  puts("------  ----------------  ---------------------------------");
      +
      +  for (attr = response->attrs; attr != NULL; attr = attr->next)
      +  {
      +   /* Attributes without names are separators between jobs */
      +    if (attr->name == NULL)
      +    {
      +      if (job_id > 0 && job_name != NULL && job_originating_user_name != NULL)
      +        printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
      +
      +      job_id = 0;
      +      job_name = NULL;
      +      job_originating_user_name = NULL;
      +      continue;
      +    }
      +    else if (!strcmp(attr->name, "job-id") && attr->value_tag == IPP_TAG_INTEGER)
      +      job_id = attr->values[0].integer;
      +    else if (!strcmp(attr->name, "job-name") && attr->value_tag == IPP_TAG_NAME)
      +      job_name = attr->values[0].string.text;
      +    else if (!strcmp(attr->name, "job-originating-user-name") &&
      +             attr->value_tag == IPP_TAG_NAME)
      +      job_originating_user_name = attr->values[0].string.text;
      +  }
      +
      +  if (job_id > 0 && job_name != NULL && job_originating_user_name != NULL)
      +    printf("%5d  %-16s  %s\n", job_id, job_originating_user_name, job_name);
      +}
      +
      + +

      Creating URI Strings

      + +

      To ensure proper encoding, the +httpAssembleURIf function must be +used to format a "printer-uri" string for all printer-based requests:

      + +
      +const char *name = "Foo";
      +char uri[1024];
      +ipp_t *request;
      +
      +httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
      +                 ippPort(), "/printers/%s", name);
      +ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
      +
      + +

      Sending Requests with Files

      + +

      The cupsDoFileRequest and +cupsDoIORequest functions are +used for requests involving files. The +cupsDoFileRequest function +attaches the named file to a request and is typically used when sending a print +file or changing a printer's PPD file:

      + +
      +const char *filename = "/usr/share/cups/data/testprint.ps";
      +const char *name = "Foo";
      +char uri[1024];
      +char resource[1024];
      +ipp_t *request = ippNewRequest(IPP_PRINT_JOB);
      +ipp_t *response;
      +
      +/* Use httpAssembleURIf for the printer-uri string */
      +httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, cupsServer(),
      +                 ippPort(), "/printers/%s", name);
      +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());
      +ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
      +             NULL, "testprint.ps");
      +
      +/* Use snprintf for the resource path */
      +snprintf(resource, sizeof(resource), "/printers/%s", name);
      +
      +response = cupsDoFileRequest(CUPS_HTTP_DEFAULT, request, resource, filename);
      +
      + +

      The cupsDoIORequest function +optionally attaches a file to the request and optionally saves a file in the +response from the server. It is used when using a pipe for the request +attachment or when using a request that returns a file, currently only +CUPS_GET_DOCUMENT and CUPS_GET_PPD. For example, +the following code will download the PPD file for the sample HP LaserJet +printer driver:

      + +
      +char tempfile[1024];
      +int tempfd;
      +ipp_t *request = ippNewRequest(CUPS_GET_PPD);
      +ipp_t *response;
      +
      +ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
      +             NULL, "laserjet.ppd");
      +
      +tempfd = cupsTempFd(tempfile, sizeof(tempfile));
      +
      +response = cupsDoIORequest(CUPS_HTTP_DEFAULT, request, "/", -1, tempfd);
      +
      + +

      The example passes -1 for the input file descriptor to specify +that no file is to be attached to the request. The PPD file attached to the +response is written to the temporary file descriptor we created using the +cupsTempFd function.

      + +

      Asynchronous Request Processing

      + +

      The cupsSendRequest and +cupsGetResponse support +asynchronous communications with the server. Unlike the other request +functions, the IPP request is not automatically freed, so remember to +free your request with the ippDelete +function.

      + +

      File data is attached to the request using the +cupsWriteRequestData +function, while file data returned from the server is read using the +cupsReadResponseData +function. We can rewrite the previous CUPS_GET_PPD example +to use the asynchronous functions quite easily:

      + +
      +char tempfile[1024];
      +int tempfd;
      +ipp_t *request = ippNewRequest(CUPS_GET_PPD);
      +ipp_t *response;
      +
      +ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
      +             NULL, "laserjet.ppd");
      +
      +tempfd = cupsTempFd(tempfile, sizeof(tempfile));
      +
      +if (cupsSendRequest(CUPS_HTTP_DEFAULT, request, "/") == HTTP_CONTINUE)
      +{
      +  response = cupsGetResponse(CUPS_HTTP_DEFAULT, "/");
      +
      +  if (response != NULL)
      +  {
      +    ssize_t bytes;
      +    char buffer[8192];
      +
      +    while ((bytes = cupsReadResponseData(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
      +      write(tempfd, buffer, bytes);
      +  }
      +}
      +
      +/* Free the request! */
      +ippDelete(request);
      +
      + +

      The cupsSendRequest function +returns the initial HTTP request status, typically either +HTTP_CONTINUE or HTTP_UNAUTHORIZED. The latter status +is returned when the request requires authentication of some sort. The +cupsDoAuthentication function +must be called when your see HTTP_UNAUTHORIZED and the request +re-sent. We can add authentication support to our example code by using a +do ... while loop:

      + +
      +char tempfile[1024];
      +int tempfd;
      +ipp_t *request = ippNewRequest(CUPS_GET_PPD);
      +ipp_t *response;
      +http_status_t status;
      +
      +ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
      +             NULL, "laserjet.ppd");
      +
      +tempfd = cupsTempFd(tempfile, sizeof(tempfile));
      +
      +/* Loop for authentication */
      +do
      +{
      +  status = cupsSendRequest(CUPS_HTTP_DEFAULT, request, "/");
      +
      +  if (status == HTTP_UNAUTHORIZED)
      +  {
      +    /* Try to authenticate, break out of the loop if that fails */
      +    if (cupsDoAuthentication(CUPS_HTTP_DEFAULT, "POST", "/"))
      +      break;
      +  }
      +}
      +while (status != HTTP_CONTINUE && status != HTTP_UNAUTHORIZED);
      +
      +if (status == HTTP_CONTINUE)
      +{
      +  response = cupsGetResponse(CUPS_HTTP_DEFAULT, "/");
      +
      +  if (response != NULL)
      +  {
      +    ssize_t bytes;
      +    char buffer[8192];
      +
      +    while ((bytes = cupsReadResponseData(CUPS_HTTP_DEFAULT, buffer, sizeof(buffer))) > 0)
      +      write(tempfd, buffer, bytes);
      +  }
      +}
      +
      +/* Free the request! */
      +ippDelete(request);
      +
      +

      Functions

      +

       CUPS 1.1.20/Mac OS X 10.4 cupsDoAuthentication

      +

      Authenticate a request.

      +

      +int cupsDoAuthentication (
      +    http_t *http,
      +    const char *method,
      +    const char *resource
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      method
      +
      Request method ("GET", "POST", "PUT")
      +
      resource
      +
      Resource path
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

      Discussion

      +

      This function should be called in response to a HTTP_UNAUTHORIZED +status, prior to resubmitting your request. + +

      +

      cupsDoFileRequest

      +

      Do an IPP request with a file.

      +

      +ipp_t *cupsDoFileRequest (
      +    http_t *http,
      +    ipp_t *request,
      +    const char *resource,
      +    const char *filename
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      request
      +
      IPP request
      +
      resource
      +
      HTTP resource for POST
      +
      filename
      +
      File to send or NULL for none
      +
      +

      Return Value

      +

      Response data

      +

      Discussion

      +

      This function sends the IPP request to the specified server, retrying +and authenticating as necessary. The request is freed with ippDelete +after receiving a valid IPP response.

      +

       CUPS 1.3/Mac OS X 10.5 cupsDoIORequest

      +

      Do an IPP request with file descriptors.

      +

      +ipp_t *cupsDoIORequest (
      +    http_t *http,
      +    ipp_t *request,
      +    const char *resource,
      +    int infile,
      +    int outfile
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      request
      +
      IPP request
      +
      resource
      +
      HTTP resource for POST
      +
      infile
      +
      File to read from or -1 for none
      +
      outfile
      +
      File to write to or -1 for none
      +
      +

      Return Value

      +

      Response data

      +

      Discussion

      +

      This function sends the IPP request to the specified server, retrying +and authenticating as necessary. The request is freed with ippDelete() +after receiving a valid IPP response.
      +
      +If "infile" is a valid file descriptor, cupsDoIORequest() copies +all of the data from the file after the IPP request message.
      +
      +If "outfile" is a valid file descriptor, cupsDoIORequest() copies +all of the data after the IPP response message to the file. + +

      +

      cupsDoRequest

      +

      Do an IPP request.

      +

      +ipp_t *cupsDoRequest (
      +    http_t *http,
      +    ipp_t *request,
      +    const char *resource
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      request
      +
      IPP request
      +
      resource
      +
      HTTP resource for POST
      +
      +

      Return Value

      +

      Response data

      +

      Discussion

      +

      This function sends the IPP request to the specified server, retrying +and authenticating as necessary. The request is freed with ippDelete() +after receiving a valid IPP response.

      +

      cupsEncodeOptions

      +

      Encode printer options into IPP attributes.

      +

      +void cupsEncodeOptions (
      +    ipp_t *ipp,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      ipp
      +
      Request to add to
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Discussion

      +

      This function adds operation, job, and then subscription attributes, +in that order. Use the cupsEncodeOptions2() function to add attributes +for a single group.

      +

       CUPS 1.2/Mac OS X 10.5 cupsEncodeOptions2

      +

      Encode printer options into IPP attributes for a group.

      +

      +void cupsEncodeOptions2 (
      +    ipp_t *ipp,
      +    int num_options,
      +    cups_option_t *options,
      +    ipp_tag_t group_tag
      +);

      +

      Parameters

      +
      +
      ipp
      +
      Request to add to
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      group_tag
      +
      Group to encode
      +
      +

      Discussion

      +

      This function only adds attributes for a single group. Call this +function multiple times for each group, or use cupsEncodeOptions() +to add the standard groups. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsGetDevices

      +

      Get available printer devices.

      +

      +ipp_status_t cupsGetDevices (
      +    http_t *http,
      +    int timeout,
      +    const char *include_schemes,
      +    const char *exclude_schemes,
      +    cups_device_cb_t callback,
      +    void *user_data
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      timeout
      +
      Timeout in seconds or CUPS_TIMEOUT_DEFAULT
      +
      include_schemes
      +
      Comma-separated URI schemes to include or CUPS_INCLUDE_ALL
      +
      exclude_schemes
      +
      Comma-separated URI schemes to exclude or CUPS_EXCLUDE_NONE
      +
      callback
      +
      Callback function
      +
      user_data
      +
      User data pointer
      +
      +

      Return Value

      +

      Request status - IPP_OK on success.

      +

      Discussion

      +

      This function sends a CUPS-Get-Devices request and streams the discovered +devices to the specified callback function. The "timeout" parameter controls +how long the request lasts, while the "include_schemes" and "exclude_schemes" +parameters provide comma-delimited lists of backends to include or omit from +the request respectively. + +

      +

       CUPS 1.1.20/Mac OS X 10.4 cupsGetFd

      +

      Get a file from the server.

      +

      +http_status_t cupsGetFd (
      +    http_t *http,
      +    const char *resource,
      +    int fd
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      resource
      +
      Resource name
      +
      fd
      +
      File descriptor
      +
      +

      Return Value

      +

      HTTP status

      +

      Discussion

      +

      This function returns HTTP_OK when the file is successfully retrieved. + +

      +

       CUPS 1.1.20/Mac OS X 10.4 cupsGetFile

      +

      Get a file from the server.

      +

      +http_status_t cupsGetFile (
      +    http_t *http,
      +    const char *resource,
      +    const char *filename
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      resource
      +
      Resource name
      +
      filename
      +
      Filename
      +
      +

      Return Value

      +

      HTTP status

      +

      Discussion

      +

      This function returns HTTP_OK when the file is successfully retrieved. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsGetResponse

      +

      Get a response to an IPP request.

      +

      +ipp_t *cupsGetResponse (
      +    http_t *http,
      +    const char *resource
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      resource
      +
      HTTP resource for POST
      +
      +

      Return Value

      +

      Response or NULL on HTTP error

      +

      Discussion

      +

      Use this function to get the response for an IPP request sent using +cupsSendDocument() or cupsSendRequest(). For requests that return +additional data, use httpRead() after getting a successful response. + +

      +

       CUPS 1.1.20/Mac OS X 10.4 cupsPutFd

      +

      Put a file on the server.

      +

      +http_status_t cupsPutFd (
      +    http_t *http,
      +    const char *resource,
      +    int fd
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      resource
      +
      Resource name
      +
      fd
      +
      File descriptor
      +
      +

      Return Value

      +

      HTTP status

      +

      Discussion

      +

      This function returns HTTP_CREATED when the file is stored +successfully. + +

      +

       CUPS 1.1.20/Mac OS X 10.4 cupsPutFile

      +

      Put a file on the server.

      +

      +http_status_t cupsPutFile (
      +    http_t *http,
      +    const char *resource,
      +    const char *filename
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      resource
      +
      Resource name
      +
      filename
      +
      Filename
      +
      +

      Return Value

      +

      HTTP status

      +

      Discussion

      +

      This function returns HTTP_CREATED when the file is stored +successfully. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsReadResponseData

      +

      Read additional data after the IPP response.

      +

      +ssize_t cupsReadResponseData (
      +    http_t *http,
      +    char *buffer,
      +    size_t length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      buffer
      +
      Buffer to use
      +
      length
      +
      Number of bytes to read
      +
      +

      Return Value

      +

      Bytes read, 0 on EOF, -1 on error

      +

      Discussion

      +

      This function is used after cupsGetResponse() to read the PPD or document +files for CUPS_GET_PPD and CUPS_GET_DOCUMENT requests, respectively. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsSendRequest

      +

      Send an IPP request.

      +

      +http_status_t cupsSendRequest (
      +    http_t *http,
      +    ipp_t *request,
      +    const char *resource,
      +    size_t length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      request
      +
      IPP request
      +
      resource
      +
      Resource path
      +
      length
      +
      Length of data to follow or CUPS_LENGTH_VARIABLE
      +
      +

      Return Value

      +

      Initial HTTP status

      +

      Discussion

      +

      Use httpWrite() to write any additional data (document, PPD file, etc.) +for the request, cupsGetResponse() to get the IPP response, and httpRead() +to read any additional data following the response. Only one request can be +sent/queued at a time.
      +
      +Unlike cupsDoFileRequest(), cupsDoIORequest(), and cupsDoRequest(), the +request is not freed. + +

      +

       CUPS 1.4/Mac OS X 10.6 cupsWriteRequestData

      +

      Write additional data after an IPP request.

      +

      +http_status_t cupsWriteRequestData (
      +    http_t *http,
      +    const char *buffer,
      +    size_t length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server or CUPS_HTTP_DEFAULT
      +
      buffer
      +
      Bytes to write
      +
      length
      +
      Number of bytes to write
      +
      +

      Return Value

      +

      HTTP_CONTINUE if OK or HTTP status on error

      +

      Discussion

      +

      This function is used after cupsSendRequest to provide a PPD and +after cupsStartDocument to provide a document file. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpAddrAny

      +

      Check for the "any" address.

      +

      +int httpAddrAny (
      +    const http_addr_t *addr
      +);

      +

      Parameters

      +
      +
      addr
      +
      Address to check
      +
      +

      Return Value

      +

      1 if "any", 0 otherwise

      +

       CUPS 1.2/Mac OS X 10.5 httpAddrEqual

      +

      Compare two addresses.

      +

      +int httpAddrEqual (
      +    const http_addr_t *addr1,
      +    const http_addr_t *addr2
      +);

      +

      Parameters

      +
      +
      addr1
      +
      First address
      +
      addr2
      +
      Second address
      +
      +

      Return Value

      +

      1 if equal, 0 if not

      +

       CUPS 1.2/Mac OS X 10.5 httpAddrLength

      +

      Return the length of the address in bytes.

      +

      +int httpAddrLength (
      +    const http_addr_t *addr
      +);

      +

      Parameters

      +
      +
      addr
      +
      Address
      +
      +

      Return Value

      +

      Length in bytes

      +

       CUPS 1.2/Mac OS X 10.5 httpAddrLocalhost

      +

      Check for the local loopback address.

      +

      +int httpAddrLocalhost (
      +    const http_addr_t *addr
      +);

      +

      Parameters

      +
      +
      addr
      +
      Address to check
      +
      +

      Return Value

      +

      1 if local host, 0 otherwise

      +

       CUPS 1.2/Mac OS X 10.5 httpAddrLookup

      +

      Lookup the hostname associated with the address.

      +

      +char *httpAddrLookup (
      +    const http_addr_t *addr,
      +    char *name,
      +    int namelen
      +);

      +

      Parameters

      +
      +
      addr
      +
      Address to lookup
      +
      name
      +
      Host name buffer
      +
      namelen
      +
      Size of name buffer
      +
      +

      Return Value

      +

      Host name

      +

       CUPS 1.2/Mac OS X 10.5 httpAddrString

      +

      Convert an address to a numeric string.

      +

      +char *httpAddrString (
      +    const http_addr_t *addr,
      +    char *s,
      +    int slen
      +);

      +

      Parameters

      +
      +
      addr
      +
      Address to convert
      +
      s
      +
      String buffer
      +
      slen
      +
      Length of string
      +
      +

      Return Value

      +

      Numeric address string

      +

       CUPS 1.2/Mac OS X 10.5 httpAssembleURI

      +

      Assemble a uniform resource identifier from its +components.

      +

      +http_uri_status_t httpAssembleURI (
      +    http_uri_coding_t encoding,
      +    char *uri,
      +    int urilen,
      +    const char *scheme,
      +    const char *username,
      +    const char *host,
      +    int port,
      +    const char *resource
      +);

      +

      Parameters

      +
      +
      encoding
      +
      Encoding flags
      +
      uri
      +
      URI buffer
      +
      urilen
      +
      Size of URI buffer
      +
      scheme
      +
      Scheme name
      +
      username
      +
      Username
      +
      host
      +
      Hostname or address
      +
      port
      +
      Port number
      +
      resource
      +
      Resource
      +
      +

      Return Value

      +

      URI status

      +

      Discussion

      +

      This function escapes reserved characters in the URI depending on the +value of the "encoding" argument. You should use this function in +place of traditional string functions whenever you need to create a +URI string. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpAssembleURIf

      +

      Assemble a uniform resource identifier from its +components with a formatted resource.

      +

      +http_uri_status_t httpAssembleURIf (
      +    http_uri_coding_t encoding,
      +    char *uri,
      +    int urilen,
      +    const char *scheme,
      +    const char *username,
      +    const char *host,
      +    int port,
      +    const char *resourcef,
      +    ...
      +);

      +

      Parameters

      +
      +
      encoding
      +
      Encoding flags
      +
      uri
      +
      URI buffer
      +
      urilen
      +
      Size of URI buffer
      +
      scheme
      +
      Scheme name
      +
      username
      +
      Username
      +
      host
      +
      Hostname or address
      +
      port
      +
      Port number
      +
      resourcef
      +
      Printf-style resource
      +
      ...
      +
      Additional arguments as needed
      +
      +

      Return Value

      +

      URI status

      +

      Discussion

      +

      This function creates a formatted version of the resource string +argument "resourcef" and escapes reserved characters in the URI +depending on the value of the "encoding" argument. You should use +this function in place of traditional string functions whenever +you need to create a URI string. + +

      +

      httpBlocking

      +

      Set blocking/non-blocking behavior on a connection.

      +

      +void httpBlocking (
      +    http_t *http,
      +    int b
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      b
      +
      1 = blocking, 0 = non-blocking
      +
      +

      httpCheck

      +

      Check to see if there is a pending response from the server.

      +

      +int httpCheck (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      0 = no data, 1 = data available

      +

       CUPS 1.1.19/Mac OS X 10.3 httpClearCookie

      +

      Clear the cookie value(s).

      +

      +void httpClearCookie (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      httpClearFields

      +

      Clear HTTP request fields.

      +

      +void httpClearFields (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      httpClose

      +

      Close an HTTP connection.

      +

      +void httpClose (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

       DEPRECATED httpConnect

      +

      Connect to a HTTP server.

      +

      +http_t *httpConnect (
      +    const char *host,
      +    int port
      +);

      +

      Parameters

      +
      +
      host
      +
      Host to connect to
      +
      port
      +
      Port number
      +
      +

      Return Value

      +

      New HTTP connection

      +

      Discussion

      +

      This function is deprecated - use httpConnectEncrypt instead. + +

      +

      httpConnectEncrypt

      +

      Connect to a HTTP server using encryption.

      +

      +http_t *httpConnectEncrypt (
      +    const char *host,
      +    int port,
      +    http_encryption_t encryption
      +);

      +

      Parameters

      +
      +
      host
      +
      Host to connect to
      +
      port
      +
      Port number
      +
      encryption
      +
      Type of encryption to use
      +
      +

      Return Value

      +

      New HTTP connection

      +

       DEPRECATED httpDecode64

      +

      Base64-decode a string.

      +

      +char *httpDecode64 (
      +    char *out,
      +    const char *in
      +);

      +

      Parameters

      +
      +
      out
      +
      String to write to
      +
      in
      +
      String to read from
      +
      +

      Return Value

      +

      Decoded string

      +

      Discussion

      +

      This function is deprecated. Use the httpDecode64_2() function instead +which provides buffer length arguments. + +

      +

       CUPS 1.1.21/Mac OS X 10.4 httpDecode64_2

      +

      Base64-decode a string.

      +

      +char *httpDecode64_2 (
      +    char *out,
      +    int *outlen,
      +    const char *in
      +);

      +

      Parameters

      +
      +
      out
      +
      String to write to
      +
      outlen
      +
      Size of output string
      +
      in
      +
      String to read from
      +
      +

      Return Value

      +

      Decoded string

      +

      httpDelete

      +

      Send a DELETE request to the server.

      +

      +int httpDelete (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI to delete
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

       DEPRECATED httpEncode64

      +

      Base64-encode a string.

      +

      +char *httpEncode64 (
      +    char *out,
      +    const char *in
      +);

      +

      Parameters

      +
      +
      out
      +
      String to write to
      +
      in
      +
      String to read from
      +
      +

      Return Value

      +

      Encoded string

      +

      Discussion

      +

      This function is deprecated. Use the httpEncode64_2() function instead +which provides buffer length arguments. + +

      +

       CUPS 1.1.21/Mac OS X 10.4 httpEncode64_2

      +

      Base64-encode a string.

      +

      +char *httpEncode64_2 (
      +    char *out,
      +    int outlen,
      +    const char *in,
      +    int inlen
      +);

      +

      Parameters

      +
      +
      out
      +
      String to write to
      +
      outlen
      +
      Size of output string
      +
      in
      +
      String to read from
      +
      inlen
      +
      Size of input string
      +
      +

      Return Value

      +

      Encoded string

      +

      httpEncryption

      +

      Set the required encryption on the link.

      +

      +int httpEncryption (
      +    http_t *http,
      +    http_encryption_t e
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      e
      +
      New encryption preference
      +
      +

      Return Value

      +

      -1 on error, 0 on success

      +

      httpError

      +

      Get the last error on a connection.

      +

      +int httpError (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      Error code (errno) value

      +

      httpFlush

      +

      Flush data from a HTTP connection.

      +

      +void httpFlush (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

       CUPS 1.2/Mac OS X 10.5 httpFlushWrite

      +

      Flush data in write buffer.

      +

      +int httpFlushWrite (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      Bytes written or -1 on error

      +

      httpGet

      +

      Send a GET request to the server.

      +

      +int httpGet (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI to get
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

       CUPS 1.3/Mac OS X 10.5 httpGetAuthString

      +

      Get the current authorization string.

      +

      +char *httpGetAuthString (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      Authorization string

      +

      Discussion

      +

      The authorization string is set by cupsDoAuthentication() and +httpSetAuthString(). Use httpGetAuthString() to retrieve the +string to use with httpSetField() for the HTTP_FIELD_AUTHORIZATION +value. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpGetBlocking

      +

      Get the blocking/non-block state of a connection.

      +

      +int httpGetBlocking (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      1 if blocking, 0 if non-blocking

      +

       CUPS 1.1.19/Mac OS X 10.3 httpGetCookie

      +

      Get any cookie data from the response.

      +

      +const char *httpGetCookie (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      HTTP connecion
      +
      +

      Return Value

      +

      Cookie data or NULL

      +

       DEPRECATED httpGetDateString

      +

      Get a formatted date/time string from a time value.

      +

      +const char *httpGetDateString (
      +    time_t t
      +);

      +

      Parameters

      +
      +
      t
      +
      UNIX time
      +
      +

      Return Value

      +

      Date/time string

      +

       CUPS 1.2/Mac OS X 10.5 httpGetDateString2

      +

      Get a formatted date/time string from a time value.

      +

      +const char *httpGetDateString2 (
      +    time_t t,
      +    char *s,
      +    int slen
      +);

      +

      Parameters

      +
      +
      t
      +
      UNIX time
      +
      s
      +
      String buffer
      +
      slen
      +
      Size of string buffer
      +
      +

      Return Value

      +

      Date/time string

      +

      httpGetDateTime

      +

      Get a time value from a formatted date/time string.

      +

      +time_t httpGetDateTime (
      +    const char *s
      +);

      +

      Parameters

      +
      +
      s
      +
      Date/time string
      +
      +

      Return Value

      +

      UNIX time

      +

       CUPS 1.2/Mac OS X 10.5 httpGetFd

      +

      Get the file descriptor associated with a connection.

      +

      +int httpGetFd (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      File descriptor or -1 if none

      +

      httpGetField

      +

      Get a field value from a request/response.

      +

      +const char *httpGetField (
      +    http_t *http,
      +    http_field_t field
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      field
      +
      Field to get
      +
      +

      Return Value

      +

      Field value

      +

       DEPRECATED httpGetHostByName

      +

      Lookup a hostname or IPv4 address, and return +address records for the specified name.

      +

      +struct hostent *httpGetHostByName (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Hostname or IP address
      +
      +

      Return Value

      +

      Host entry

      +

       CUPS 1.2/Mac OS X 10.5 httpGetHostname

      +

      Get the FQDN for the connection or local system.

      +

      +const char *httpGetHostname (
      +    http_t *http,
      +    char *s,
      +    int slen
      +);

      +

      Parameters

      +
      +
      http
      +
      HTTP connection or NULL
      +
      s
      +
      String buffer for name
      +
      slen
      +
      Size of buffer
      +
      +

      Return Value

      +

      FQDN for connection or system

      +

      Discussion

      +

      When "http" points to a connected socket, return the hostname or +address that was used in the call to httpConnect() or httpConnectEncrypt(). +Otherwise, return the FQDN for the local system using both gethostname() +and gethostbyname() to get the local hostname with domain. + +

      +

       DEPRECATED httpGetLength

      +

      Get the amount of data remaining from the +content-length or transfer-encoding fields.

      +

      +int httpGetLength (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      Content length

      +

      Discussion

      +

      This function is deprecated and will not return lengths larger than +2^31 - 1; use httpGetLength2() instead. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpGetLength2

      +

      Get the amount of data remaining from the +content-length or transfer-encoding fields.

      +

      +off_t httpGetLength2 (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      Content length

      +

      Discussion

      +

      This function returns the complete content length, even for +content larger than 2^31 - 1. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpGetStatus

      +

      Get the status of the last HTTP request.

      +

      +http_status_t httpGetStatus (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      HTTP status

      +

       DEPRECATED httpGetSubField

      +

      Get a sub-field value.

      +

      +char *httpGetSubField (
      +    http_t *http,
      +    http_field_t field,
      +    const char *name,
      +    char *value
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      field
      +
      Field index
      +
      name
      +
      Name of sub-field
      +
      value
      +
      Value string
      +
      +

      Return Value

      +

      Value or NULL

      +

       CUPS 1.2/Mac OS X 10.5 httpGetSubField2

      +

      Get a sub-field value.

      +

      +char *httpGetSubField2 (
      +    http_t *http,
      +    http_field_t field,
      +    const char *name,
      +    char *value,
      +    int valuelen
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      field
      +
      Field index
      +
      name
      +
      Name of sub-field
      +
      value
      +
      Value string
      +
      valuelen
      +
      Size of value buffer
      +
      +

      Return Value

      +

      Value or NULL

      +

      httpGets

      +

      Get a line of text from a HTTP connection.

      +

      +char *httpGets (
      +    char *line,
      +    int length,
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      line
      +
      Line to read into
      +
      length
      +
      Max length of buffer
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      Line or NULL

      +

      httpHead

      +

      Send a HEAD request to the server.

      +

      +int httpHead (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI for head
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

      httpInitialize

      +

      Initialize the HTTP interface library and set the +default HTTP proxy (if any).

      +

      +void httpInitialize (void);

      +

      httpMD5

      +

      Compute the MD5 sum of the username:group:password.

      +

      +char *httpMD5 (
      +    const char *username,
      +    const char *realm,
      +    const char *passwd,
      +    char md5[33]
      +);

      +

      Parameters

      +
      +
      username
      +
      User name
      +
      realm
      +
      Realm name
      +
      passwd
      +
      Password string
      +
      md5[33]
      +
      MD5 string
      +
      +

      Return Value

      +

      MD5 sum

      +

      httpMD5Final

      +

      Combine the MD5 sum of the username, group, and password +with the server-supplied nonce value, method, and +request-uri.

      +

      +char *httpMD5Final (
      +    const char *nonce,
      +    const char *method,
      +    const char *resource,
      +    char md5[33]
      +);

      +

      Parameters

      +
      +
      nonce
      +
      Server nonce value
      +
      method
      +
      METHOD (GET, POST, etc.)
      +
      resource
      +
      Resource path
      +
      md5[33]
      +
      MD5 sum
      +
      +

      Return Value

      +

      New sum

      +

      httpMD5String

      +

      Convert an MD5 sum to a character string.

      +

      +char *httpMD5String (
      +    const unsigned char *sum,
      +    char md5[33]
      +);

      +

      Parameters

      +
      +
      sum
      +
      MD5 sum data
      +
      md5[33]
      +
      MD5 sum in hex
      +
      +

      Return Value

      +

      MD5 sum in hex

      +

      httpOptions

      +

      Send an OPTIONS request to the server.

      +

      +int httpOptions (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI for options
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

      httpPost

      +

      Send a POST request to the server.

      +

      +int httpPost (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI for post
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

      httpPut

      +

      Send a PUT request to the server.

      +

      +int httpPut (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI to put
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

       DEPRECATED httpRead

      +

      Read data from a HTTP connection.

      +

      +int httpRead (
      +    http_t *http,
      +    char *buffer,
      +    int length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      buffer
      +
      Buffer for data
      +
      length
      +
      Maximum number of bytes
      +
      +

      Return Value

      +

      Number of bytes read

      +

      Discussion

      +

      This function is deprecated. Use the httpRead2() function which can +read more than 2GB of data. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpRead2

      +

      Read data from a HTTP connection.

      +

      +ssize_t httpRead2 (
      +    http_t *http,
      +    char *buffer,
      +    size_t length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      buffer
      +
      Buffer for data
      +
      length
      +
      Maximum number of bytes
      +
      +

      Return Value

      +

      Number of bytes read

      +

      httpReconnect

      +

      Reconnect to a HTTP server.

      +

      +int httpReconnect (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      0 on success, non-zero on failure

      +

       DEPRECATED httpSeparate

      +

      Separate a Universal Resource Identifier into its +components.

      +

      +void httpSeparate (
      +    const char *uri,
      +    char *scheme,
      +    char *username,
      +    char *host,
      +    int *port,
      +    char *resource
      +);

      +

      Parameters

      +
      +
      uri
      +
      Universal Resource Identifier
      +
      scheme
      +
      Scheme [32] (http, https, etc.)
      +
      username
      +
      Username [1024]
      +
      host
      +
      Hostname [1024]
      +
      port
      +
      Port number to use
      +
      resource
      +
      Resource/filename [1024]
      +
      +

      Discussion

      +

      This function is deprecated; use the httpSeparateURI() function instead. + +

      +

       CUPS 1.1.21/Mac OS X 10.4 httpSeparate2

      +

      Separate a Universal Resource Identifier into its +components.

      +

      +void httpSeparate2 (
      +    const char *uri,
      +    char *scheme,
      +    int schemelen,
      +    char *username,
      +    int usernamelen,
      +    char *host,
      +    int hostlen,
      +    int *port,
      +    char *resource,
      +    int resourcelen
      +);

      +

      Parameters

      +
      +
      uri
      +
      Universal Resource Identifier
      +
      scheme
      +
      Scheme (http, https, etc.)
      +
      schemelen
      +
      Size of scheme buffer
      +
      username
      +
      Username
      +
      usernamelen
      +
      Size of username buffer
      +
      host
      +
      Hostname
      +
      hostlen
      +
      Size of hostname buffer
      +
      port
      +
      Port number to use
      +
      resource
      +
      Resource/filename
      +
      resourcelen
      +
      Size of resource buffer
      +
      +

      Discussion

      +

      This function is deprecated; use the httpSeparateURI() function instead. + + +

      +

       CUPS 1.2/Mac OS X 10.5 httpSeparateURI

      +

      Separate a Universal Resource Identifier into its +components.

      +

      +http_uri_status_t httpSeparateURI (
      +    http_uri_coding_t decoding,
      +    const char *uri,
      +    char *scheme,
      +    int schemelen,
      +    char *username,
      +    int usernamelen,
      +    char *host,
      +    int hostlen,
      +    int *port,
      +    char *resource,
      +    int resourcelen
      +);

      +

      Parameters

      +
      +
      decoding
      +
      Decoding flags
      +
      uri
      +
      Universal Resource Identifier
      +
      scheme
      +
      Scheme (http, https, etc.)
      +
      schemelen
      +
      Size of scheme buffer
      +
      username
      +
      Username
      +
      usernamelen
      +
      Size of username buffer
      +
      host
      +
      Hostname
      +
      hostlen
      +
      Size of hostname buffer
      +
      port
      +
      Port number to use
      +
      resource
      +
      Resource/filename
      +
      resourcelen
      +
      Size of resource buffer
      +
      +

      Return Value

      +

      Result of separation

      +

       CUPS 1.3/Mac OS X 10.5 httpSetAuthString

      +

      Set the current authorization string.

      +

      +void httpSetAuthString (
      +    http_t *http,
      +    const char *scheme,
      +    const char *data
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      scheme
      +
      Auth scheme (NULL to clear it)
      +
      data
      +
      Auth data (NULL for none)
      +
      +

      Discussion

      +

      This function just stores a copy of the current authorization string in +the HTTP connection object. You must still call httpSetField() to set +HTTP_FIELD_AUTHORIZATION prior to issuing a HTTP request using httpGet(), +httpHead(), httpOptions(), httpPost, or httpPut(). + +

      +

       CUPS 1.1.19/Mac OS X 10.3 httpSetCookie

      +

      Set the cookie value(s).

      +

      +void httpSetCookie (
      +    http_t *http,
      +    const char *cookie
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection
      +
      cookie
      +
      Cookie string
      +
      +

       CUPS 1.2/Mac OS X 10.5 httpSetExpect

      +

      Set the Expect: header in a request.

      +

      +void httpSetExpect (
      +    http_t *http,
      +    http_status_t expect
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      expect
      +
      HTTP status to expect (HTTP_CONTINUE)
      +
      +

      Discussion

      +

      Currently only HTTP_CONTINUE is supported for the "expect" argument. + +

      +

      httpSetField

      +

      Set the value of an HTTP header.

      +

      +void httpSetField (
      +    http_t *http,
      +    http_field_t field,
      +    const char *value
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      field
      +
      Field index
      +
      value
      +
      Value
      +
      +

       CUPS 1.2/Mac OS X 10.5 httpSetLength

      +

      Set the content-length and content-encoding.

      +

      +void httpSetLength (
      +    http_t *http,
      +    size_t length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      length
      +
      Length (0 for chunked)
      +
      +

      httpStatus

      +

      Return a short string describing a HTTP status code.

      +

      +const char *httpStatus (
      +    http_status_t status
      +);

      +

      Parameters

      +
      +
      status
      +
      HTTP status code
      +
      +

      Return Value

      +

      Localized status string

      +

      Discussion

      +

      The returned string is localized to the current POSIX locale and is based +on the status strings defined in RFC 2616.

      +

      httpTrace

      +

      Send an TRACE request to the server.

      +

      +int httpTrace (
      +    http_t *http,
      +    const char *uri
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      uri
      +
      URI for trace
      +
      +

      Return Value

      +

      Status of call (0 = success)

      +

      httpUpdate

      +

      Update the current HTTP state for incoming data.

      +

      +http_status_t httpUpdate (
      +    http_t *http
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      +

      Return Value

      +

      HTTP status

      +

       CUPS 1.1.19/Mac OS X 10.3 httpWait

      +

      Wait for data available on a connection.

      +

      +int httpWait (
      +    http_t *http,
      +    int msec
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      msec
      +
      Milliseconds to wait
      +
      +

      Return Value

      +

      1 if data is available, 0 otherwise

      +

       DEPRECATED httpWrite

      +

      Write data to a HTTP connection.

      +

      +int httpWrite (
      +    http_t *http,
      +    const char *buffer,
      +    int length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      buffer
      +
      Buffer for data
      +
      length
      +
      Number of bytes to write
      +
      +

      Return Value

      +

      Number of bytes written

      +

      Discussion

      +

      This function is deprecated. Use the httpWrite2() function which can +write more than 2GB of data. + +

      +

       CUPS 1.2/Mac OS X 10.5 httpWrite2

      +

      Write data to a HTTP connection.

      +

      +ssize_t httpWrite2 (
      +    http_t *http,
      +    const char *buffer,
      +    size_t length
      +);

      +

      Parameters

      +
      +
      http
      +
      Connection to server
      +
      buffer
      +
      Buffer for data
      +
      length
      +
      Number of bytes to write
      +
      +

      Return Value

      +

      Number of bytes written

      +

      ippAddBoolean

      +

      Add a boolean attribute to an IPP message.

      +

      +ipp_attribute_t *ippAddBoolean (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    char value
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      value
      +
      Value of attribute
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddBooleans

      +

      Add an array of boolean values.

      +

      +ipp_attribute_t *ippAddBooleans (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    int num_values,
      +    const char *values
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      num_values
      +
      Number of values
      +
      values
      +
      Values
      +
      +

      Return Value

      +

      New attribute

      +

       CUPS 1.1.19/Mac OS X 10.3 ippAddCollection

      +

      Add a collection value.

      +

      +ipp_attribute_t *ippAddCollection (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    ipp_t *value
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      value
      +
      Value
      +
      +

      Return Value

      +

      New attribute

      +

       CUPS 1.1.19/Mac OS X 10.3 ippAddCollections

      +

      Add an array of collection values.

      +

      +ipp_attribute_t *ippAddCollections (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    int num_values,
      +    const ipp_t **values
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      num_values
      +
      Number of values
      +
      values
      +
      Values
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddDate

      +

      Add a date attribute to an IPP message.

      +

      +ipp_attribute_t *ippAddDate (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    const ipp_uchar_t *value
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      value
      +
      Value
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddInteger

      +

      Add a integer attribute to an IPP message.

      +

      +ipp_attribute_t *ippAddInteger (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    ipp_tag_t type,
      +    const char *name,
      +    int value
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      type
      +
      Type of attribute
      +
      name
      +
      Name of attribute
      +
      value
      +
      Value of attribute
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddIntegers

      +

      Add an array of integer values.

      +

      +ipp_attribute_t *ippAddIntegers (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    ipp_tag_t type,
      +    const char *name,
      +    int num_values,
      +    const int *values
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      type
      +
      Type of attribute
      +
      name
      +
      Name of attribute
      +
      num_values
      +
      Number of values
      +
      values
      +
      Values
      +
      +

      Return Value

      +

      New attribute

      +

       CUPS 1.2/Mac OS X 10.5 ippAddOctetString

      +

      Add an octetString value to an IPP message.

      +

      +ipp_attribute_t *ippAddOctetString (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    const void *data,
      +    int datalen
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      data
      +
      octetString data
      +
      datalen
      +
      Length of data in bytes
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddRange

      +

      Add a range of values to an IPP message.

      +

      +ipp_attribute_t *ippAddRange (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    int lower,
      +    int upper
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      lower
      +
      Lower value
      +
      upper
      +
      Upper value
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddRanges

      +

      Add ranges of values to an IPP message.

      +

      +ipp_attribute_t *ippAddRanges (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    int num_values,
      +    const int *lower,
      +    const int *upper
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      num_values
      +
      Number of values
      +
      lower
      +
      Lower values
      +
      upper
      +
      Upper values
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddResolution

      +

      Add a resolution value to an IPP message.

      +

      +ipp_attribute_t *ippAddResolution (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    const char *name,
      +    ipp_res_t units,
      +    int xres,
      +    int yres
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      units
      +
      Units for resolution
      +
      xres
      +
      X resolution
      +
      yres
      +
      Y resolution
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddResolutions

      +

      Add resolution values to an IPP message.

      +

      +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
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      name
      +
      Name of attribute
      +
      num_values
      +
      Number of values
      +
      units
      +
      Units for resolution
      +
      xres
      +
      X resolutions
      +
      yres
      +
      Y resolutions
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddSeparator

      +

      Add a group separator to an IPP message.

      +

      +ipp_attribute_t *ippAddSeparator (
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddString

      +

      Add a language-encoded string to an IPP message.

      +

      +ipp_attribute_t *ippAddString (
      +    ipp_t *ipp,
      +    ipp_tag_t group,
      +    ipp_tag_t type,
      +    const char *name,
      +    const char *charset,
      +    const char *value
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      type
      +
      Type of attribute
      +
      name
      +
      Name of attribute
      +
      charset
      +
      Character set
      +
      value
      +
      Value
      +
      +

      Return Value

      +

      New attribute

      +

      ippAddStrings

      +

      Add language-encoded strings to an IPP message.

      +

      +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 *const *values
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      group
      +
      IPP group
      +
      type
      +
      Type of attribute
      +
      name
      +
      Name of attribute
      +
      num_values
      +
      Number of values
      +
      charset
      +
      Character set
      +
      values
      +
      Values
      +
      +

      Return Value

      +

      New attribute

      +

      ippDateToTime

      +

      Convert from RFC 1903 Date/Time format to UNIX time +in seconds.

      +

      +time_t ippDateToTime (
      +    const ipp_uchar_t *date
      +);

      +

      Parameters

      +
      +
      date
      +
      RFC 1903 date info
      +
      +

      Return Value

      +

      UNIX time value

      +

      ippDelete

      +

      Delete an IPP message.

      +

      +void ippDelete (
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      +

       CUPS 1.1.19/Mac OS X 10.3 ippDeleteAttribute

      +

      Delete a single attribute in an IPP message.

      +

      +void ippDeleteAttribute (
      +    ipp_t *ipp,
      +    ipp_attribute_t *attr
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      attr
      +
      Attribute to delete
      +
      +

      ippErrorString

      +

      Return a name for the given status code.

      +

      +const char *ippErrorString (
      +    ipp_status_t error
      +);

      +

      Parameters

      +
      +
      error
      +
      Error status
      +
      +

      Return Value

      +

      Text string

      +

       CUPS 1.2/Mac OS X 10.5 ippErrorValue

      +

      Return a status code for the given name.

      +

      +ipp_status_t ippErrorValue (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Name
      +
      +

      Return Value

      +

      IPP status code

      +

      ippFindAttribute

      +

      Find a named attribute in a request...

      +

      +ipp_attribute_t *ippFindAttribute (
      +    ipp_t *ipp,
      +    const char *name,
      +    ipp_tag_t type
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      name
      +
      Name of attribute
      +
      type
      +
      Type of attribute
      +
      +

      Return Value

      +

      Matching attribute

      +

      ippFindNextAttribute

      +

      Find the next named attribute in a request...

      +

      +ipp_attribute_t *ippFindNextAttribute (
      +    ipp_t *ipp,
      +    const char *name,
      +    ipp_tag_t type
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      name
      +
      Name of attribute
      +
      type
      +
      Type of attribute
      +
      +

      Return Value

      +

      Matching attribute

      +

      ippLength

      +

      Compute the length of an IPP message.

      +

      +size_t ippLength (
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      ipp
      +
      IPP message
      +
      +

      Return Value

      +

      Size of IPP message

      +

      ippNew

      +

      Allocate a new IPP message.

      +

      +ipp_t *ippNew (void);

      +

      Return Value

      +

      New IPP message

      +

       CUPS 1.2/Mac OS X 10.5 ippNewRequest

      +

      Allocate a new IPP request message.

      +

      +ipp_t *ippNewRequest (
      +    ipp_op_t op
      +);

      +

      Parameters

      +
      +
      op
      +
      Operation code
      +
      +

      Return Value

      +

      IPP request message

      +

      Discussion

      +

      The new request message is initialized with the attributes-charset and +attributes-natural-language attributes added. The +attributes-natural-language value is derived from the current locale. + +

      +

       CUPS 1.2/Mac OS X 10.5 ippOpString

      +

      Return a name for the given operation id.

      +

      +const char *ippOpString (
      +    ipp_op_t op
      +);

      +

      Parameters

      +
      +
      op
      +
      Operation ID
      +
      +

      Return Value

      +

      Name

      +

       CUPS 1.2/Mac OS X 10.5 ippOpValue

      +

      Return an operation id for the given name.

      +

      +ipp_op_t ippOpValue (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Textual name
      +
      +

      Return Value

      +

      Operation ID

      +

      ippPort

      +

      Return the default IPP port number.

      +

      +int ippPort (void);

      +

      Return Value

      +

      Port number

      +

      ippRead

      +

      Read data for an IPP message from a HTTP connection.

      +

      +ipp_state_t ippRead (
      +    http_t *http,
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      http
      +
      HTTP connection
      +
      ipp
      +
      IPP data
      +
      +

      Return Value

      +

      Current state

      +

       CUPS 1.1.19/Mac OS X 10.3 ippReadFile

      +

      Read data for an IPP message from a file.

      +

      +ipp_state_t ippReadFile (
      +    int fd,
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      fd
      +
      HTTP data
      +
      ipp
      +
      IPP data
      +
      +

      Return Value

      +

      Current state

      +

       CUPS 1.2/Mac OS X 10.5 ippReadIO

      +

      Read data for an IPP message.

      +

      +ipp_state_t ippReadIO (
      +    void *src,
      +    ipp_iocb_t cb,
      +    int blocking,
      +    ipp_t *parent,
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      src
      +
      Data source
      +
      cb
      +
      Read callback function
      +
      blocking
      +
      Use blocking IO?
      +
      parent
      +
      Parent request, if any
      +
      ipp
      +
      IPP data
      +
      +

      Return Value

      +

      Current state

      +

      ippSetPort

      +

      Set the default port number.

      +

      +void ippSetPort (
      +    int p
      +);

      +

      Parameters

      +
      +
      p
      +
      Port number to use
      +
      +

       CUPS 1.4/Mac OS X 10.6 ippTagString

      +

      Return the tag name corresponding to a tag value.

      +

      +const char *ippTagString (
      +    ipp_tag_t tag
      +);

      +

      Parameters

      +
      +
      tag
      +
      Tag value
      +
      +

      Return Value

      +

      Tag name

      +

      Discussion

      +

      The returned names are defined in RFC 2911 and 3382. + +

      +

       CUPS 1.4/Mac OS X 10.6 ippTagValue

      +

      Return the tag value corresponding to a tag name.

      +

      +ipp_tag_t ippTagValue (
      +    const char *name
      +);

      +

      Parameters

      +
      +
      name
      +
      Tag name
      +
      +

      Return Value

      +

      Tag value

      +

      Discussion

      +

      The tag names are defined in RFC 2911 and 3382. + +

      +

      ippTimeToDate

      +

      Convert from UNIX time to RFC 1903 format.

      +

      +const ipp_uchar_t *ippTimeToDate (
      +    time_t t
      +);

      +

      Parameters

      +
      +
      t
      +
      UNIX time value
      +
      +

      Return Value

      +

      RFC-1903 date/time data

      +

      ippWrite

      +

      Write data for an IPP message to a HTTP connection.

      +

      +ipp_state_t ippWrite (
      +    http_t *http,
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      http
      +
      HTTP connection
      +
      ipp
      +
      IPP data
      +
      +

      Return Value

      +

      Current state

      +

       CUPS 1.1.19/Mac OS X 10.3 ippWriteFile

      +

      Write data for an IPP message to a file.

      +

      +ipp_state_t ippWriteFile (
      +    int fd,
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      fd
      +
      HTTP data
      +
      ipp
      +
      IPP data
      +
      +

      Return Value

      +

      Current state

      +

       CUPS 1.2/Mac OS X 10.5 ippWriteIO

      +

      Write data for an IPP message.

      +

      +ipp_state_t ippWriteIO (
      +    void *dst,
      +    ipp_iocb_t cb,
      +    int blocking,
      +    ipp_t *parent,
      +    ipp_t *ipp
      +);

      +

      Parameters

      +
      +
      dst
      +
      Destination
      +
      cb
      +
      Write callback function
      +
      blocking
      +
      Use blocking IO?
      +
      parent
      +
      Parent IPP message
      +
      ipp
      +
      IPP data
      +
      +

      Return Value

      +

      Current state

      +

      Data Types

      +

       CUPS 1.2/Mac OS X 10.5 http_addr_t

      +

      Socket address union, which +makes using IPv6 and other +address types easier and +more portable.

      +

      +typedef union _http_addr_u / http_addr_t; +

      +

       CUPS 1.2/Mac OS X 10.5 http_addrlist_t

      +

      Socket address list, which is +used to enumerate all of the +addresses that are associated +with a hostname.

      +

      +typedef struct http_addrlist_s / http_addrlist_t; +

      +

      http_auth_t

      +

      HTTP authentication types

      +

      +typedef enum http_auth_e http_auth_t; +

      +

      http_encoding_t

      +

      HTTP transfer encoding values

      +

      +typedef enum http_encoding_e http_encoding_t; +

      +

      http_encryption_t

      +

      HTTP encryption values

      +

      +typedef enum http_encryption_e http_encryption_t; +

      +

      http_field_t

      +

      HTTP field names

      +

      +typedef enum http_field_e http_field_t; +

      +

      http_keepalive_t

      +

      HTTP keep-alive values

      +

      +typedef enum http_keepalive_e http_keepalive_t; +

      +

      http_state_t

      +

      HTTP state values; states +are server-oriented...

      +

      +typedef enum http_state_e / http_state_t; +

      +

      http_status_t

      +

      HTTP status codes

      +

      +typedef enum http_status_e http_status_t; +

      +

      http_t

      +

      HTTP connection type

      +

      +typedef struct _http_s http_t; +

      +

      http_uri_coding_t

      +

      URI en/decode flags

      +

      +typedef enum http_uri_coding_e http_uri_coding_t; +

      +

       CUPS1.2 http_uri_status_t

      +

      URI separation status

      +

      +typedef enum http_uri_status_e http_uri_status_t; +

      +

      http_version_t

      +

      HTTP version numbers

      +

      +typedef enum http_version_e http_version_t; +

      +

      ipp_attribute_t

      +

      Attribute

      +

      +typedef struct ipp_attribute_s ipp_attribute_t; +

      +

      ipp_finish_t

      +

      Finishings

      +

      +typedef enum ipp_finish_e ipp_finish_t; +

      +

       CUPS 1.2/Mac OS X 10.5 ipp_iocb_t

      +

      IPP IO Callback Function

      +

      +typedef ssize_t (*ipp_iocb_t)(void *, ipp_uchar_t *, size_t); +

      +

      ipp_jstate_t

      +

      Job states

      +

      +typedef enum ipp_jstate_e ipp_jstate_t; +

      +

      ipp_op_t

      +

      IPP operations

      +

      +typedef enum ipp_op_e ipp_op_t; +

      +

      ipp_orient_t

      +

      Orientation values

      +

      +typedef enum ipp_orient_e ipp_orient_t; +

      +

      ipp_pstate_t

      +

      Printer states

      +

      +typedef enum ipp_pstate_e ipp_pstate_t; +

      +

      ipp_quality_t

      +

      Qualities

      +

      +typedef enum ipp_quality_e ipp_quality_t; +

      +

      ipp_request_t

      +

      Request Header

      +

      +typedef union ipp_request_u ipp_request_t; +

      +

      ipp_res_t

      +

      Resolution units

      +

      +typedef enum ipp_res_e ipp_res_t; +

      +

      ipp_state_t

      +

      IPP states

      +

      +typedef enum ipp_state_e ipp_state_t; +

      +

      ipp_t

      +

      Attribute Value

      +

      +typedef struct ipp_s ipp_t; +

      +

      ipp_uchar_t

      +

      IPP status codes

      +

      +typedef typedef unsigned char ipp_uchar_t; +

      +

      ipp_tag_t

      +

      Format tags for attributes

      +

      +typedef enum ipp_tag_e ipp_tag_t; +

      +

      ipp_value_t

      +

      Attribute Value

      +

      +typedef union ipp_value_u ipp_value_t; +

      +

      Structures

      +

       CUPS 1.2/Mac OS X 10.5 http_addrlist_s

      +

      Socket address list, which is +used to enumerate all of the +addresses that are associated +with a hostname.

      +

      struct http_addrlist_s {
      +    http_addr_t addr;
      +    struct http_addrlist_s *next;
      +};

      +

      Members

      +
      +
      addr
      +
      Address
      +
      next
      +
      Pointer to next address in list
      +
      +

      ipp_attribute_s

      +

      Attribute

      +

      struct ipp_attribute_s {
      +    char *name;
      +    struct ipp_attribute_s *next;
      +    int num_values;
      +    ipp_tag_t group_tag, value_tag;
      +    ipp_value_t values[1];
      +};

      +

      Members

      +
      +
      name
      +
      Name of attribute
      +
      next
      +
      Next attribute in list
      +
      num_values
      +
      Number of values
      +
      value_tag
      +
      What type of value is it?
      +
      values[1]
      +
      Values
      +
      +

      ipp_s

      +

      IPP Request/Response/Notification

      +

      struct ipp_s {
      +    ipp_attribute_t *attrs;
      +    ipp_attribute_t *current;
      +    ipp_tag_t curtag;
      +    ipp_attribute_t *last;
      +    ipp_attribute_t *prev;
      +    ipp_request_t request;
      +    ipp_state_t state;
      +    int use;
      +};

      +

      Members

      +
      +
      attrs
      +
      Attributes
      +
      current
      +
      Current attribute (for read/write)
      +
      curtag
      +
      Current attribute group tag
      +
      last
      +
      Last attribute in list
      +
      prev  CUPS 1.2/Mac OS X 10.5 
      +
      Previous attribute (for read)
      +
      request
      +
      Request header
      +
      state
      +
      State of request
      +
      use
      +
      Use count
      +
      +

      Unions

      +

      ipp_request_u

      +

      Request Header

      +

      union ipp_request_u {
      +};

      +

      Members

      +
      +
      +

      ipp_value_u

      +

      Attribute Value

      +

      union ipp_value_u {
      +    char boolean;
      +    ipp_t *collection;
      +    ipp_uchar_t date[11];
      +    int integer;
      +};

      +

      Members

      +
      +
      boolean
      +
      Boolean value
      +
      collection  CUPS 1.1.19/Mac OS X 10.3 
      +
      Collection value
      +
      date[11]
      +
      Date/time value
      +
      integer
      +
      Integer/enumerated value
      +
      +

      Constants

      +

      http_auth_e

      +

      HTTP authentication types

      +

      Constants

      +
      +
      HTTP_AUTH_BASIC
      +
      Basic authentication in use
      +
      HTTP_AUTH_MD5
      +
      Digest authentication in use
      +
      HTTP_AUTH_MD5_INT
      +
      Digest authentication in use for body
      +
      HTTP_AUTH_MD5_SESS
      +
      MD5-session authentication in use
      +
      HTTP_AUTH_MD5_SESS_INT
      +
      MD5-session authentication in use for body
      +
      HTTP_AUTH_NEGOTIATE  CUPS 1.3/Mac OS X 10.5 
      +
      GSSAPI authentication in use
      +
      HTTP_AUTH_NONE
      +
      No authentication in use
      +
      +

      http_encoding_e

      +

      HTTP transfer encoding values

      +

      Constants

      +
      +
      HTTP_ENCODE_CHUNKED
      +
      Data is chunked
      +
      HTTP_ENCODE_FIELDS
      +
      Sending HTTP fields
      +
      HTTP_ENCODE_LENGTH
      +
      Data is sent with Content-Length
      +
      +

      http_encryption_e

      +

      HTTP encryption values

      +

      Constants

      +
      +
      HTTP_ENCRYPT_ALWAYS
      +
      Always encrypt (SSL)
      +
      HTTP_ENCRYPT_IF_REQUESTED
      +
      Encrypt if requested (TLS upgrade)
      +
      HTTP_ENCRYPT_NEVER
      +
      Never encrypt
      +
      HTTP_ENCRYPT_REQUIRED
      +
      Encryption is required (TLS upgrade)
      +
      +

      http_field_e

      +

      HTTP field names

      +

      Constants

      +
      +
      HTTP_FIELD_ACCEPT_LANGUAGE
      +
      Accept-Language field
      +
      HTTP_FIELD_ACCEPT_RANGES
      +
      Accept-Ranges field
      +
      HTTP_FIELD_AUTHORIZATION
      +
      Authorization field
      +
      HTTP_FIELD_CONNECTION
      +
      Connection field
      +
      HTTP_FIELD_CONTENT_ENCODING
      +
      Content-Encoding field
      +
      HTTP_FIELD_CONTENT_LANGUAGE
      +
      Content-Language field
      +
      HTTP_FIELD_CONTENT_LENGTH
      +
      Content-Length field
      +
      HTTP_FIELD_CONTENT_LOCATION
      +
      Content-Location field
      +
      HTTP_FIELD_CONTENT_MD5
      +
      Content-MD5 field
      +
      HTTP_FIELD_CONTENT_RANGE
      +
      Content-Range field
      +
      HTTP_FIELD_CONTENT_TYPE
      +
      Content-Type field
      +
      HTTP_FIELD_CONTENT_VERSION
      +
      Content-Version field
      +
      HTTP_FIELD_DATE
      +
      Date field
      +
      HTTP_FIELD_HOST
      +
      Host field
      +
      HTTP_FIELD_IF_MODIFIED_SINCE
      +
      If-Modified-Since field
      +
      HTTP_FIELD_IF_UNMODIFIED_SINCE
      +
      If-Unmodified-Since field
      +
      HTTP_FIELD_KEEP_ALIVE
      +
      Keep-Alive field
      +
      HTTP_FIELD_LAST_MODIFIED
      +
      Last-Modified field
      +
      HTTP_FIELD_LINK
      +
      Link field
      +
      HTTP_FIELD_LOCATION
      +
      Location field
      +
      HTTP_FIELD_MAX
      +
      Maximum field index
      +
      HTTP_FIELD_RANGE
      +
      Range field
      +
      HTTP_FIELD_REFERER
      +
      Referer field
      +
      HTTP_FIELD_RETRY_AFTER
      +
      Retry-After field
      +
      HTTP_FIELD_TRANSFER_ENCODING
      +
      Transfer-Encoding field
      +
      HTTP_FIELD_UNKNOWN
      +
      Unknown field
      +
      HTTP_FIELD_UPGRADE
      +
      Upgrade field
      +
      HTTP_FIELD_USER_AGENT
      +
      User-Agent field
      +
      HTTP_FIELD_WWW_AUTHENTICATE
      +
      WWW-Authenticate field
      +
      +

      http_keepalive_e

      +

      HTTP keep-alive values

      +

      Constants

      +
      +
      HTTP_KEEPALIVE_OFF
      +
      No keep alive support
      +
      HTTP_KEEPALIVE_ON
      +
      Use keep alive
      +
      +

      http_state_e

      +

      HTTP state values; states +are server-oriented...

      +

      Constants

      +
      +
      HTTP_CLOSE
      +
      CLOSE command, waiting for blank line
      +
      HTTP_DELETE
      +
      DELETE 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_OPTIONS
      +
      OPTIONS 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_STATUS
      +
      Command complete, sending status
      +
      HTTP_TRACE
      +
      TRACE command, waiting for blank line
      +
      HTTP_WAITING
      +
      Waiting for command
      +
      +

      http_status_e

      +

      HTTP status codes

      +

      Constants

      +
      +
      HTTP_ACCEPTED
      +
      DELETE command was successful
      +
      HTTP_AUTHORIZATION_CANCELED
      +
      User canceled authorization
      +
      HTTP_BAD_GATEWAY
      +
      Bad gateway
      +
      HTTP_BAD_REQUEST
      +
      Bad request
      +
      HTTP_CONFLICT
      +
      Request is self-conflicting
      +
      HTTP_CONTINUE
      +
      Everything OK, keep going...
      +
      HTTP_CREATED
      +
      PUT command was successful
      +
      HTTP_ERROR
      +
      An error response from httpXxxx()
      +
      HTTP_EXPECTATION_FAILED
      +
      The expectation given in an Expect header field was not met
      +
      HTTP_FORBIDDEN
      +
      Forbidden to access this URI
      +
      HTTP_GATEWAY_TIMEOUT
      +
      Gateway connection timed out
      +
      HTTP_GONE
      +
      Server has gone away
      +
      HTTP_LENGTH_REQUIRED
      +
      A content length or encoding is required
      +
      HTTP_METHOD_NOT_ALLOWED
      +
      Method is not allowed
      +
      HTTP_MOVED_PERMANENTLY
      +
      Document has moved permanently
      +
      HTTP_MOVED_TEMPORARILY
      +
      Document has moved temporarily
      +
      HTTP_MULTIPLE_CHOICES
      +
      Multiple files match request
      +
      HTTP_NOT_ACCEPTABLE
      +
      Not Acceptable
      +
      HTTP_NOT_AUTHORITATIVE
      +
      Information isn't authoritative
      +
      HTTP_NOT_FOUND
      +
      URI was not found
      +
      HTTP_NOT_IMPLEMENTED
      +
      Feature not implemented
      +
      HTTP_NOT_MODIFIED
      +
      File not modified
      +
      HTTP_NOT_SUPPORTED
      +
      HTTP version not supported
      +
      HTTP_NO_CONTENT
      +
      Successful command, no new data
      +
      HTTP_OK
      +
      OPTIONS/GET/HEAD/POST/TRACE command was successful
      +
      HTTP_PARTIAL_CONTENT
      +
      Only a partial file was recieved/sent
      +
      HTTP_PAYMENT_REQUIRED
      +
      Payment required
      +
      HTTP_PRECONDITION
      +
      Precondition failed
      +
      HTTP_PROXY_AUTHENTICATION
      +
      Proxy Authentication is Required
      +
      HTTP_REQUESTED_RANGE
      +
      The requested range is not satisfiable
      +
      HTTP_REQUEST_TIMEOUT
      +
      Request timed out
      +
      HTTP_REQUEST_TOO_LARGE
      +
      Request entity too large
      +
      HTTP_RESET_CONTENT
      +
      Content was reset/recreated
      +
      HTTP_SEE_OTHER
      +
      See this other link...
      +
      HTTP_SERVER_ERROR
      +
      Internal server error
      +
      HTTP_SERVICE_UNAVAILABLE
      +
      Service is unavailable
      +
      HTTP_SWITCHING_PROTOCOLS
      +
      HTTP upgrade to TLS/SSL
      +
      HTTP_UNAUTHORIZED
      +
      Unauthorized to access host
      +
      HTTP_UNSUPPORTED_MEDIATYPE
      +
      The requested media type is unsupported
      +
      HTTP_UPGRADE_REQUIRED
      +
      Upgrade to SSL/TLS required
      +
      HTTP_URI_TOO_LONG
      +
      URI too long
      +
      HTTP_USE_PROXY
      +
      Must use a proxy to access this URI
      +
      +

      http_uri_coding_e

      +

      URI en/decode flags

      +

      Constants

      +
      +
      HTTP_URI_CODING_ALL
      +
      En/decode everything
      +
      HTTP_URI_CODING_HOSTNAME
      +
      En/decode the hostname portion
      +
      HTTP_URI_CODING_MOST
      +
      En/decode all but the query
      +
      HTTP_URI_CODING_NONE
      +
      Don't en/decode anything
      +
      HTTP_URI_CODING_QUERY
      +
      En/decode the query portion
      +
      HTTP_URI_CODING_RESOURCE
      +
      En/decode the resource portion
      +
      HTTP_URI_CODING_USERNAME
      +
      En/decode the username portion
      +
      +

       CUPS1.2 http_uri_status_e

      +

      URI separation status

      +

      Constants

      +
      +
      HTTP_URI_BAD_ARGUMENTS
      +
      Bad arguments to function (error)
      +
      HTTP_URI_BAD_HOSTNAME
      +
      Bad hostname in URI (error)
      +
      HTTP_URI_BAD_PORT
      +
      Bad port number in URI (error)
      +
      HTTP_URI_BAD_RESOURCE
      +
      Bad resource in URI (error)
      +
      HTTP_URI_BAD_SCHEME
      +
      Bad scheme in URI (error)
      +
      HTTP_URI_BAD_URI
      +
      Bad/empty URI (error)
      +
      HTTP_URI_BAD_USERNAME
      +
      Bad username in URI (error)
      +
      HTTP_URI_MISSING_RESOURCE
      +
      Missing resource in URI (warning)
      +
      HTTP_URI_MISSING_SCHEME
      +
      Missing scheme in URI (warning)
      +
      HTTP_URI_OK
      +
      URI decoded OK
      +
      HTTP_URI_OVERFLOW
      +
      URI buffer for httpAssembleURI is too small
      +
      HTTP_URI_UNKNOWN_SCHEME
      +
      Unknown scheme in URI (warning)
      +
      +

      http_version_e

      +

      HTTP version numbers

      +

      Constants

      +
      +
      HTTP_0_9
      +
      HTTP/0.9
      +
      HTTP_1_0
      +
      HTTP/1.0
      +
      HTTP_1_1
      +
      HTTP/1.1
      +
      +

      ipp_finish_e

      +

      Finishings

      +

      Constants

      +
      +
      IPP_FINISHINGS_BALE
      +
      Bale (any type)
      +
      IPP_FINISHINGS_BIND
      +
      Bind
      +
      IPP_FINISHINGS_BIND_BOTTOM
      +
      Bind on bottom
      +
      IPP_FINISHINGS_BIND_LEFT
      +
      Bind on left
      +
      IPP_FINISHINGS_BIND_RIGHT
      +
      Bind on right
      +
      IPP_FINISHINGS_BIND_TOP
      +
      Bind on top
      +
      IPP_FINISHINGS_BOOKLET_MAKER
      +
      Fold to make booklet
      +
      IPP_FINISHINGS_COVER
      +
      Add cover
      +
      IPP_FINISHINGS_EDGE_STITCH
      +
      Stitch along any side
      +
      IPP_FINISHINGS_EDGE_STITCH_BOTTOM
      +
      Stitch along bottom edge
      +
      IPP_FINISHINGS_EDGE_STITCH_LEFT
      +
      Stitch along left side
      +
      IPP_FINISHINGS_EDGE_STITCH_RIGHT
      +
      Stitch along right side
      +
      IPP_FINISHINGS_EDGE_STITCH_TOP
      +
      Stitch along top edge
      +
      IPP_FINISHINGS_FOLD
      +
      Fold (any type)
      +
      IPP_FINISHINGS_JOB_OFFSET
      +
      Offset for binding (any type)
      +
      IPP_FINISHINGS_NONE
      +
      No finishing
      +
      IPP_FINISHINGS_PUNCH
      +
      Punch (any location/count)
      +
      IPP_FINISHINGS_SADDLE_STITCH
      +
      Staple interior
      +
      IPP_FINISHINGS_STAPLE
      +
      Staple (any location)
      +
      IPP_FINISHINGS_STAPLE_BOTTOM_LEFT
      +
      Staple bottom left corner
      +
      IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT
      +
      Staple bottom right corner
      +
      IPP_FINISHINGS_STAPLE_DUAL_BOTTOM
      +
      Two staples on bottom
      +
      IPP_FINISHINGS_STAPLE_DUAL_LEFT
      +
      Two staples on left
      +
      IPP_FINISHINGS_STAPLE_DUAL_RIGHT
      +
      Two staples on right
      +
      IPP_FINISHINGS_STAPLE_DUAL_TOP
      +
      Two staples on top
      +
      IPP_FINISHINGS_STAPLE_TOP_LEFT
      +
      Staple top left corner
      +
      IPP_FINISHINGS_STAPLE_TOP_RIGHT
      +
      Staple top right corner
      +
      IPP_FINISHINGS_TRIM
      +
      Trim (any type)
      +
      +

      ipp_jstate_e

      +

      Job states

      +

      Constants

      +
      +
      IPP_JOB_ABORTED
      +
      Job has aborted due to error
      +
      IPP_JOB_CANCELED
      +
      Job has been canceled
      +
      IPP_JOB_COMPLETED
      +
      Job has completed successfully
      +
      IPP_JOB_HELD
      +
      Job is held for printing
      +
      IPP_JOB_PENDING
      +
      Job is waiting to be printed
      +
      IPP_JOB_PROCESSING
      +
      Job is currently printing
      +
      IPP_JOB_STOPPED
      +
      Job has been stopped
      +
      +

      ipp_op_e

      +

      IPP operations

      +

      Constants

      +
      +
      CUPS_ACCEPT_JOBS
      +
      Accept new jobs on a printer
      +
      CUPS_ADD_MODIFY_CLASS
      +
      Add or modify a class
      +
      CUPS_ADD_MODIFY_PRINTER
      +
      Add or modify a printer
      +
      CUPS_AUTHENTICATE_JOB  CUPS 1.2/Mac OS X 10.5 
      +
      Authenticate a job
      +
      CUPS_DELETE_CLASS
      +
      Delete a class
      +
      CUPS_DELETE_PRINTER
      +
      Delete a printer
      +
      CUPS_GET_CLASSES  DEPRECATED 
      +
      Get a list of classes
      +
      CUPS_GET_DEFAULT
      +
      Get the default printer
      +
      CUPS_GET_DEVICES
      +
      Get a list of supported devices
      +
      CUPS_GET_DOCUMENT  CUPS 1.4/Mac OS X 10.6 
      +
      Get a document file
      +
      CUPS_GET_PPD  CUPS 1.3/Mac OS X 10.5 
      +
      Get a PPD file
      +
      CUPS_GET_PPDS
      +
      Get a list of supported drivers
      +
      CUPS_GET_PRINTERS
      +
      Get a list of printers and/or classes
      +
      CUPS_MOVE_JOB
      +
      Move a job to a different printer
      +
      CUPS_REJECT_JOBS
      +
      Reject new jobs on a printer
      +
      CUPS_SET_DEFAULT
      +
      Set the default printer
      +
      IPP_CANCEL_JOB
      +
      Cancel a job
      +
      IPP_CANCEL_SUBSCRIPTION  CUPS 1.2/Mac OS X 10.5 
      +
      Cancel a subscription
      +
      IPP_CREATE_JOB
      +
      Create an empty print job
      +
      IPP_CREATE_JOB_SUBSCRIPTION  CUPS 1.2/Mac OS X 10.5 
      +
      Create a job subscription
      +
      IPP_CREATE_PRINTER_SUBSCRIPTION  CUPS 1.2/Mac OS X 10.5 
      +
      Create a printer subscription
      +
      IPP_DISABLE_PRINTER
      +
      Stop a printer
      +
      IPP_ENABLE_PRINTER
      +
      Start a printer
      +
      IPP_GET_JOBS
      +
      Get a list of jobs
      +
      IPP_GET_JOB_ATTRIBUTES
      +
      Get job attributes
      +
      IPP_GET_NOTIFICATIONS  CUPS 1.2/Mac OS X 10.5 
      +
      Get notification events
      +
      IPP_GET_PRINTER_ATTRIBUTES
      +
      Get printer attributes
      +
      IPP_GET_PRINTER_SUPPORTED_VALUES
      +
      Get supported attribute values
      +
      IPP_GET_SUBSCRIPTIONS  CUPS 1.2/Mac OS X 10.5 
      +
      Get list of subscriptions
      +
      IPP_GET_SUBSCRIPTION_ATTRIBUTES  CUPS 1.2/Mac OS X 10.5 
      +
      Get subscription attributes
      +
      IPP_HOLD_JOB
      +
      Hold a job for printing
      +
      IPP_PAUSE_PRINTER
      +
      Stop a printer
      +
      IPP_PRINT_JOB
      +
      Print a single file
      +
      IPP_PURGE_JOBS
      +
      Cancel all jobs
      +
      IPP_RELEASE_JOB
      +
      Release a job for printing
      +
      IPP_RENEW_SUBSCRIPTION  CUPS 1.2/Mac OS X 10.5 
      +
      Renew a printer subscription
      +
      IPP_RESTART_JOB
      +
      Reprint a job
      +
      IPP_RESUME_PRINTER
      +
      Start a printer
      +
      IPP_SEND_DOCUMENT
      +
      Add a file to a job
      +
      IPP_SET_JOB_ATTRIBUTES
      +
      Set job attributes
      +
      IPP_VALIDATE_JOB
      +
      Validate job options
      +
      +

      ipp_orient_e

      +

      Orientation values

      +

      Constants

      +
      +
      IPP_LANDSCAPE
      +
      90 degrees counter-clockwise
      +
      IPP_PORTRAIT
      +
      No rotation
      +
      IPP_REVERSE_LANDSCAPE
      +
      90 degrees clockwise
      +
      IPP_REVERSE_PORTRAIT
      +
      180 degrees
      +
      +

      ipp_pstate_e

      +

      Printer states

      +

      Constants

      +
      +
      IPP_PRINTER_IDLE
      +
      Printer is idle
      +
      IPP_PRINTER_PROCESSING
      +
      Printer is working
      +
      IPP_PRINTER_STOPPED
      +
      Printer is stopped
      +
      +

      ipp_quality_e

      +

      Qualities

      +

      Constants

      +
      +
      IPP_QUALITY_DRAFT
      +
      Draft quality
      +
      IPP_QUALITY_HIGH
      +
      High quality
      +
      IPP_QUALITY_NORMAL
      +
      Normal quality
      +
      +

      ipp_res_e

      +

      Resolution units

      +

      Constants

      +
      +
      IPP_RES_PER_CM
      +
      Pixels per centimeter
      +
      IPP_RES_PER_INCH
      +
      Pixels per inch
      +
      +

      ipp_state_e

      +

      IPP states

      +

      Constants

      +
      +
      IPP_ATTRIBUTE
      +
      One or more attributes need to be sent/received
      +
      IPP_DATA
      +
      IPP request data needs to be sent/received
      +
      IPP_ERROR
      +
      An error occurred
      +
      IPP_HEADER
      +
      The request header needs to be sent/received
      +
      IPP_IDLE
      +
      Nothing is happening/request completed
      +
      +

      ipp_status_e

      +

      IPP status codes

      +

      Constants

      +
      +
      CUPS_SEE_OTHER
      +
      cups-see-other
      +
      IPP_ATTRIBUTES
      +
      client-error-attributes-or-values-not-supported
      +
      IPP_ATTRIBUTES_NOT_SETTABLE
      +
      client-error-attributes-not-settable
      +
      IPP_BAD_REQUEST
      +
      client-error-bad-request
      +
      IPP_CHARSET
      +
      client-error-charset-not-supported
      +
      IPP_COMPRESSION_ERROR
      +
      client-error-compression-error
      +
      IPP_COMPRESSION_NOT_SUPPORTED
      +
      client-error-compression-not-supported
      +
      IPP_CONFLICT
      +
      client-error-conflicting-attributes
      +
      IPP_DEVICE_ERROR
      +
      server-error-device-error
      +
      IPP_DOCUMENT_ACCESS_ERROR
      +
      client-error-document-access-error
      +
      IPP_DOCUMENT_FORMAT
      +
      client-error-document-format-not-supported
      +
      IPP_DOCUMENT_FORMAT_ERROR
      +
      client-error-document-format-error
      +
      IPP_ERROR_JOB_CANCELED
      +
      server-error-job-canceled
      +
      IPP_FORBIDDEN
      +
      client-error-forbidden
      +
      IPP_GONE
      +
      client-error-gone
      +
      IPP_IGNORED_ALL_NOTIFICATIONS
      +
      client-error-ignored-all-notifications
      +
      IPP_IGNORED_ALL_SUBSCRIPTIONS
      +
      client-error-ignored-all-subscriptions
      +
      IPP_INTERNAL_ERROR
      +
      server-error-internal-error
      +
      IPP_MULTIPLE_JOBS_NOT_SUPPORTED
      +
      server-error-multiple-document-jobs-not-supported
      +
      IPP_NOT_ACCEPTING
      +
      server-error-not-accepting-jobs
      +
      IPP_NOT_AUTHENTICATED
      +
      client-error-not-authenticated
      +
      IPP_NOT_AUTHORIZED
      +
      client-error-not-authorized
      +
      IPP_NOT_FOUND
      +
      client-error-not-found
      +
      IPP_NOT_POSSIBLE
      +
      client-error-not-possible
      +
      IPP_OK
      +
      successful-ok
      +
      IPP_OK_BUT_CANCEL_SUBSCRIPTION
      +
      successful-ok-but-cancel-subscription
      +
      IPP_OK_CONFLICT
      +
      successful-ok-conflicting-attributes
      +
      IPP_OK_EVENTS_COMPLETE
      +
      successful-ok-events-complete
      +
      IPP_OK_IGNORED_NOTIFICATIONS
      +
      successful-ok-ignored-notifications
      +
      IPP_OK_IGNORED_SUBSCRIPTIONS
      +
      successful-ok-ignored-subscriptions
      +
      IPP_OK_SUBST
      +
      successful-ok-ignored-or-substituted-attributes
      +
      IPP_OK_TOO_MANY_EVENTS
      +
      successful-ok-too-many-events
      +
      IPP_OPERATION_NOT_SUPPORTED
      +
      server-error-operation-not-supported
      +
      IPP_PRINTER_BUSY
      +
      server-error-busy
      +
      IPP_PRINTER_IS_DEACTIVATED
      +
      server-error-printer-is-deactivated
      +
      IPP_PRINT_SUPPORT_FILE_NOT_FOUND
      +
      client-error-print-support-file-not-found
      +
      IPP_REQUEST_ENTITY
      +
      client-error-request-entity-too-large
      +
      IPP_REQUEST_VALUE
      +
      client-error-request-value-too-long
      +
      IPP_SERVICE_UNAVAILABLE
      +
      server-error-service-unavailable
      +
      IPP_TEMPORARY_ERROR
      +
      server-error-temporary-error
      +
      IPP_TIMEOUT
      +
      client-error-timeout
      +
      IPP_TOO_MANY_SUBSCRIPTIONS
      +
      client-error-too-many-subscriptions
      +
      IPP_URI_SCHEME
      +
      client-error-uri-scheme-not-supported
      +
      IPP_VERSION_NOT_SUPPORTED
      +
      server-error-version-not-supported
      +
      +

      ipp_tag_e

      +

      Format tags for attributes

      +

      Constants

      +
      +
      IPP_TAG_ADMINDEFINE
      +
      Admin-defined value
      +
      IPP_TAG_BEGIN_COLLECTION
      +
      Beginning of collection value
      +
      IPP_TAG_BOOLEAN
      +
      Boolean value
      +
      IPP_TAG_CHARSET
      +
      Character set value
      +
      IPP_TAG_COPY
      +
      Bitflag for copied attribute values
      +
      IPP_TAG_DATE
      +
      Date/time value
      +
      IPP_TAG_DEFAULT
      +
      Default value
      +
      IPP_TAG_DELETEATTR
      +
      Delete-attribute value
      +
      IPP_TAG_END
      +
      End-of-attributes
      +
      IPP_TAG_END_COLLECTION
      +
      End of collection value
      +
      IPP_TAG_ENUM
      +
      Enumeration value
      +
      IPP_TAG_EVENT_NOTIFICATION
      +
      Event group
      +
      IPP_TAG_INTEGER
      +
      Integer value
      +
      IPP_TAG_JOB
      +
      Job group
      +
      IPP_TAG_KEYWORD
      +
      Keyword value
      +
      IPP_TAG_LANGUAGE
      +
      Language value
      +
      IPP_TAG_MASK
      +
      Mask for copied attribute values
      +
      IPP_TAG_MEMBERNAME
      +
      Collection member name value
      +
      IPP_TAG_MIMETYPE
      +
      MIME media type value
      +
      IPP_TAG_NAME
      +
      Name value
      +
      IPP_TAG_NAMELANG
      +
      Name-with-language value
      +
      IPP_TAG_NOTSETTABLE
      +
      Not-settable value
      +
      IPP_TAG_NOVALUE
      +
      No-value value
      +
      IPP_TAG_OPERATION
      +
      Operation group
      +
      IPP_TAG_PRINTER
      +
      Printer group
      +
      IPP_TAG_RANGE
      +
      Range value
      +
      IPP_TAG_RESOLUTION
      +
      Resolution value
      +
      IPP_TAG_STRING
      +
      Octet string value
      +
      IPP_TAG_SUBSCRIPTION
      +
      Subscription group
      +
      IPP_TAG_TEXT
      +
      Text value
      +
      IPP_TAG_TEXTLANG
      +
      Text-with-language value
      +
      IPP_TAG_UNKNOWN
      +
      Unknown value
      +
      IPP_TAG_UNSUPPORTED_GROUP
      +
      Unsupported attributes group
      +
      IPP_TAG_UNSUPPORTED_VALUE
      +
      Unsupported value
      +
      IPP_TAG_URI
      +
      URI value
      +
      IPP_TAG_URISCHEME
      +
      URI scheme value
      +
      IPP_TAG_ZERO
      +
      Zero tag - used for separators
      +
      +
+ + diff --git a/doc/help/api-mime.html b/doc/help/api-mime.html new file mode 100644 index 0000000000..7d370aad06 --- /dev/null +++ b/doc/help/api-mime.html @@ -0,0 +1,771 @@ + + + + +MIME API + + + + + +
+ + +

MIME API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/mime.h
Library-lcupsmime
See AlsoProgramming: Introduction to CUPS Programming
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • + + +

      Overview

      + +

      The MIME API provides file typing and conversion services for CUPS.

      +

      Functions

      +

      mimeAddFilter

      +

      Add a filter to the current MIME database.

      +

      +mime_filter_t *mimeAddFilter (
      +    mime_t *mime,
      +    mime_type_t *src,
      +    mime_type_t *dst,
      +    int cost,
      +    const char *filter
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      src
      +
      Source type
      +
      dst
      +
      Destination type
      +
      cost
      +
      Relative time/resource cost
      +
      filter
      +
      Filter program to run
      +
      +

      Return Value

      +

      New filter

      +

      mimeAddType

      +

      Add a MIME type to a database.

      +

      +mime_type_t *mimeAddType (
      +    mime_t *mime,
      +    const char *super,
      +    const char *type
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      super
      +
      Super-type name
      +
      type
      +
      Type name
      +
      +

      Return Value

      +

      New (or existing) MIME type

      +

      mimeAddTypeRule

      +

      Add a detection rule for a file type.

      +

      +int mimeAddTypeRule (
      +    mime_type_t *mt,
      +    const char *rule
      +);

      +

      Parameters

      +
      +
      mt
      +
      Type to add to
      +
      rule
      +
      Rule to add
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

      mimeDelete

      +

      Delete (free) a MIME database.

      +

      +void mimeDelete (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      mimeDeleteFilter

      +

      Delete a filter from the MIME database.

      +

      +void mimeDeleteFilter (
      +    mime_t *mime,
      +    mime_filter_t *filter
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      filter
      +
      Filter
      +
      +

      mimeDeleteType

      +

      Delete a type from the MIME database.

      +

      +void mimeDeleteType (
      +    mime_t *mime,
      +    mime_type_t *mt
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      mt
      +
      Type
      +
      +

      mimeFileType

      +

      Determine the type of a file.

      +

      +mime_type_t *mimeFileType (
      +    mime_t *mime,
      +    const char *pathname,
      +    const char *filename,
      +    int *compression
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      pathname
      +
      Name of file to check on disk
      +
      filename
      +
      Original filename or NULL
      +
      compression
      +
      Is the file compressed?
      +
      +

      Return Value

      +

      Type of file

      +

      mimeFilter

      +

      Find the fastest way to convert from one type to another.

      +

      +cups_array_t *mimeFilter (
      +    mime_t *mime,
      +    mime_type_t *src,
      +    mime_type_t *dst,
      +    int *cost
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      src
      +
      Source file type
      +
      dst
      +
      Destination file type
      +
      cost
      +
      Cost of filters
      +
      +

      Return Value

      +

      Array of filters to run

      +

      mimeFilterLookup

      +

      Lookup a filter...

      +

      +mime_filter_t *mimeFilterLookup (
      +    mime_t *mime,
      +    mime_type_t *src,
      +    mime_type_t *dst
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      src
      +
      Source type
      +
      dst
      +
      Destination type
      +
      +

      Return Value

      +

      Filter for src->dst

      +

      mimeFirstFilter

      +

      Get the first filter in the MIME database.

      +

      +mime_filter_t *mimeFirstFilter (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      Return Value

      +

      Filter or NULL

      +

      mimeFirstType

      +

      Get the first type in the MIME database.

      +

      +mime_type_t *mimeFirstType (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      Return Value

      +

      Type or NULL

      +

      mimeLoad

      +

      Create a new MIME database from disk.

      +

      +mime_t *mimeLoad (
      +    const char *pathname,
      +    const char *filterpath
      +);

      +

      Parameters

      +
      +
      pathname
      +
      Directory to load
      +
      filterpath
      +
      Directory to load
      +
      +

      Return Value

      +

      New MIME database

      +

      Discussion

      +

      This function uses mimeLoadFilters and mimeLoadTypes to +create a MIME database from a single directory.

      +

      mimeLoadFilters

      +

      Load filter definitions from disk.

      +

      +mime_t *mimeLoadFilters (
      +    mime_t *mime,
      +    const char *pathname,
      +    const char *filterpath
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      pathname
      +
      Directory to load from
      +
      filterpath
      +
      Default filter program directory
      +
      +

      Return Value

      +

      MIME database

      +

      Discussion

      +

      This function loads all of the .convs files from the specified directory. +Use mimeLoadTypes to load all types before you load the filters.

      +

      mimeLoadTypes

      +

      Load type definitions from disk.

      +

      +mime_t *mimeLoadTypes (
      +    mime_t *mime,
      +    const char *pathname
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database or NULL to create a new one
      +
      pathname
      +
      Directory to load from
      +
      +

      Return Value

      +

      MIME database

      +

      Discussion

      +

      This function loads all of the .types files from the specified directory. +Use mimeLoadFilters to load all filters after you load the types.

      +

      mimeNextFilter

      +

      Get the next filter in the MIME database.

      +

      +mime_filter_t *mimeNextFilter (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      Return Value

      +

      Filter or NULL

      +

      mimeNextType

      +

      Get the next type in the MIME database.

      +

      +mime_type_t *mimeNextType (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      Return Value

      +

      Type or NULL

      +

      mimeNumFilters

      +

      MIME database

      +

      +int mimeNumFilters (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      Return Value

      +

      Get the number of filters in a MIME database.

      +

      mimeNumTypes

      +

      MIME database

      +

      +int mimeNumTypes (
      +    mime_t *mime
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      +

      Return Value

      +

      Get the number of types in a MIME database.

      +

      mimeType

      +

      Lookup a file type.

      +

      +mime_type_t *mimeType (
      +    mime_t *mime,
      +    const char *super,
      +    const char *type
      +);

      +

      Parameters

      +
      +
      mime
      +
      MIME database
      +
      super
      +
      Super-type name
      +
      type
      +
      Type name
      +
      +

      Return Value

      +

      Matching file type definition

      +

      Data Types

      +

      mime_filter_t

      +

      MIME Conversion Filter Data

      +

      +typedef struct _mime_filter_s mime_filter_t; +

      +

      mime_magic_t

      +

      MIME Magic Data

      +

      +typedef struct _mime_magic_s mime_magic_t; +

      +

      mime_op_t

      +

      Types/structures...

      +

      +typedef enum mime_op_t; +

      +

      mime_t

      +

      MIME Database

      +

      +typedef struct _mime_s mime_t; +

      +

      mime_type_t

      +

      MIME Type Data

      +

      +typedef struct _mime_type_s mime_type_t; +

      +
+ + diff --git a/doc/help/api-overview.html b/doc/help/api-overview.html new file mode 100644 index 0000000000..3cb894a23c --- /dev/null +++ b/doc/help/api-overview.html @@ -0,0 +1,499 @@ + + + + +Introduction to CUPS Programming + + + + + +
+ + +

Introduction to CUPS Programming

+ +
+ + + + + + + + + + + + + + + + +
Headerscups/cups.h
+ cups/array.h
+ cups/backend.h
+ cups/dir.h
+ cups/file.h
+ cups/ppd.h
+ cups/raster.h
+ cups/sidechannel.h
Libraries-lcups
+ -lcupsimage
See AlsoProgramming: Developing Raster Printer Drivers
+ Programming: Developing PostScript Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Introduction to the PPD Compiler
+ Programming: Array API
+ Programming: CUPS API
+ Programming: File and Directory APIs
+ Programming: HTTP and IPP APIs
+ Programming: PPD API
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
+

Contents

+
    +
      +
    • Overview
    • +
    • Compiling Programs
    • +
    • Where to Go Next
    • + + +

      Overview

      + +

      CUPS provides two libraries that interface with the different parts of the +printing system. The "cups" library provides all of the common application and +filter functions while the "cupsimage" library provides all of the imaging +functions used in raster printer drivers. The "cups" library functions are +accessed by including the <cups/cups.h> header, while +"cupsimage" functions are found in the <cups/raster.h> +header.

      + +

      Compiling Programs

      + +

      The CUPS libraries can be used from any C, C++, or Objective C program. +The method of compiling against the libraries varies depending on the +operating system and installation of CUPS. The following sections show how +to compile a simple program (shown below) in two common environments.

      + +

      The following simple program lists the available printers on the system:

      + +
      +#include <stdio.h>
      +#include <cups/cups.h>
      +
      +int main(void)
      +{
      +  int i;
      +  cups_dest_t *dests, *dest;
      +  int num_dests = cupsGetDests(&dests);
      +
      +  for (i = num_dests, dest = dests; i > 0; i --, dest ++)
      +  {
      +    if (dest->instance)
      +      printf("%s/%s\n", dest->name, dest->instance);
      +    else
      +      puts(dest->name);
      +  }
      +
      +  return (0);
      +}
      +
      + +

      Compiling with Xcode

      + +

      In Xcode, choose New Project... from the File menu, +then select the Standard Tool project type under Command Line +Utility. Click Next and choose a project directory. Click +Next to create the project.

      + +

      In the project window, double-click on the Targets group and +control-click on the simple target to show the context menu. Choose +Existing Framework... from the Add submenu. When the file +chooser sheet appears, press the / key and enter "/usr/lib". Scroll +down the file list and select the libcups.dylib file. Click the +Add button in the file chooser and attributes sheets.

      + +

      In the project window, double-click on the main.c source file. +Replace the template source code with the listing above and save it. Click the +Build and Go button to build the sample program and run it.

      + +

      Compiling with GCC

      + +

      From the command-line, create a file called sample.c using your +favorite editor and then run the following command to compile it with GCC and +run it:

      + +
      +gcc -o simple `cups-config --cflags` simple.c `cups-config --libs`
      +./simple
      +
      + +

      The cups-config command provides the compiler flags +("cups-config --cflags") and libraries ("cups-config --libs") needed for the +local system.

      + +

      Where to Go Next

      + +

      If you are developing a print filter, driver, or backend, see the +Filter and Backend Programming +guide. Raster printer driver developers should also read the +Raster API reference.

      +
+ + diff --git a/doc/help/api-ppd.html b/doc/help/api-ppd.html new file mode 100644 index 0000000000..135350171c --- /dev/null +++ b/doc/help/api-ppd.html @@ -0,0 +1,2208 @@ + + + + +PPD API + + + + + +
+ + +

PPD API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/ppd.h
Library-lcups
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ Specifications: CUPS PPD Extensions
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • +
    • Unions
    • +
    • Constants
    • + + +

      Overview

      + +

      The CUPS PPD API provides read-only access the data in PostScript Printer +Description ("PPD") files which are used for all printers with a driver. With +it you can obtain the data necessary to display printer options to users, mark +option choices and check for conflicting choices, and output marked choices in +PostScript output. The ppd_file_t +structure contains all of the information in a PPD file.

      + +
      Note: + +

      The CUPS PPD API uses the terms "option" and "choice" instead of the Adobe +terms "MainKeyword" and "OptionKeyword" to refer to specific printer options and +features. CUPS also treats option ("MainKeyword") and choice ("OptionKeyword") +values as case-insensitive strings, so option "InputSlot" and choice "Upper" +are equivalent to "inputslot" and "upper", respectively.

      +
      + +

      Loading a PPD File

      + +

      The ppdOpenFile function "opens" a +PPD file and loads it into memory. For example, the following code opens the +current printer's PPD file in a CUPS filter:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd = ppdOpenFile(getenv("PPD"));
      +
      + +

      The return value is a pointer to a new +ppd_file_t structure or NULL +if the PPD file does not exist or cannot be loaded. The +ppdClose function frees the memory used +by the structure:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd;
      +
      +ppdClose(ppd);
      +
      + +

      Once closed, pointers to the ppd_file_t +structure and any data in it will no longer be valid.

      + +

      Options and Groups

      + +

      PPD files support multiple options, which are stored in arrays of +ppd_option_t and +ppd_choice_t structures.

      + +

      Each option in turn is associated with a group stored in a +ppd_group_t structure. Groups can be +specified in the PPD file; if an option is not associated with a group +then it is put in an automatically-generated "General" group. Groups can also +have sub-groups, however CUPS currently ignores sub-groups because of past +abuses of this functionality.

      + +

      Option choices are selected by marking them using one of three functions. The +first is ppdMarkDefaults which +selects all of the default options in the PPD file:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd;
      +
      +ppdMarkDefaults(ppd);
      +
      + +

      The second is ppdMarkOption +which selects a single option choice in the PPD file. For example, the following +code selects the upper paper tray:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd;
      +
      +ppdMarkOption(ppd, "InputSlot", "Upper");
      +
      + +

      The last function is +cupsMarkOptions which selects +multiple option choices in the PPD file from an array of CUPS options, mapping +IPP attributes like "media" and "sides" to their corresponding PPD options. You +typically use this function in a print filter with +cupsParseOptions and +ppdMarkDefaults to select all of +the option choices needed for the job, for example:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd = ppdOpenFile(getenv("PPD"));
      +cups_option_t *options = NULL;
      +int num_options = cupsParseOptions(argv[5], 0, &options);
      +
      +ppdMarkDefaults(ppd);
      +cupsMarkOptions(ppd, num_options, options);
      +cupsFreeOptions(num_options, options);
      +
      + +

      Constraints

      + +

      PPD files support specification of conflict conditions, called +constraints, between different options. Constraints are stored in an array of +ppd_const_t structures which specify +the options and choices that conflict with each other. The +ppdConflicts function tells you +how many of the selected options are incompatible. Since constraints are +normally specified in pairs, the returned value is typically an even number.

      + +

      Page Sizes

      + +

      Page sizes are special options which have physical dimensions and margins +associated with them. The size information is stored in +ppd_size_t structures and is available +by looking up the named size with the +ppdPageSize function. The page size and +margins are returned in units called points; there are 72 points per inch. If +you pass NULL for the size, the currently selected size is +returned:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd;
      +ppd_size_t *size = ppdPageSize(ppd, NULL);
      +
      + +

      Besides the standard page sizes listed in a PPD file, some printers +support variable or custom page sizes. Custom page sizes are supported if the +variables_sizes member of the +ppd_file_t structure is non-zero. +The custom_min, custom_max, and +custom_margins members of the +ppd_file_t structure define the limits +of the printable area. To get the resulting media size, use a page size string +of the form "Custom.widthxlength", where "width" and "length" are +in points. Custom page size names can also be specified in inches +("Custom.widthxheightin"), centimeters +("Custom.widthxheightcm"), or millimeters +("Custom.widthxheightmm"):

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd;
      +
      +/* Get an 576x720 point custom page size */
      +ppd_size_t *size = ppdPageSize(ppd, "Custom.576x720");
      +
      +/* Get an 8x10 inch custom page size */
      +ppd_size_t *size = ppdPageSize(ppd, "Custom.8x10in");
      +
      +/* Get a 100x200 millimeter custom page size */
      +ppd_size_t *size = ppdPageSize(ppd, "Custom.100x200mm");
      +
      +/* Get a 12.7x34.5 centimeter custom page size */
      +ppd_size_t *size = ppdPageSize(ppd, "Custom.12.7x34.5cm");
      +
      + +

      If the PPD does not support variable page sizes, the +ppdPageSize function will return +NULL.

      + +

      Attributes

      + +

      Every PPD file is composed of one or more attributes. Most of these +attributes are used to define groups, options, choices, and page sizes, +however several informational attributes may be present which you can access +in your program or filter. Attributes normally look like one of the following +examples in a PPD file:

      + +
      +*name: "value"
      +*name spec: "value"
      +*name spec/text: "value"
      +
      + +

      The ppdFindAttr and +ppdFindNextAttr functions find the +first and next instances, respectively, of the named attribute with the given +"spec" string and return a ppd_attr_t +structure. If you provide a NULL specifier string, all attributes with the +given name will be returned. For example, the following code lists all of the +Product attributes in a PPD file:

      + +
      +#include <cups/ppd.h>
      +
      +ppd_file_t *ppd;
      +ppd_attr_t *attr;
      +
      +for (attr = ppdFindAttr(ppd, "Product", NULL);
      +     attr != NULL;
      +     attr = ppdFindNextAttr(ppd, "Product", NULL))
      +  puts(attr->value);
      +
      +

      Functions

      +

       CUPS 1.4/Mac OS X 10.6 cupsGetConflicts

      +

      Get a list of conflicting options in a marked PPD.

      +

      +int cupsGetConflicts (
      +    ppd_file_t *ppd,
      +    const char *option,
      +    const char *choice,
      +    cups_option_t **options
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      option
      +
      Option to test
      +
      choice
      +
      Choice to test
      +
      options
      +
      Conflicting options
      +
      +

      Return Value

      +

      Number of conflicting options

      +

      Discussion

      +

      This function gets a list of options that would conflict if "option" and +"choice" were marked in the PPD. You would typically call this function +after marking the currently selected options in the PPD in order to +determine whether a new option selection would cause a conflict.
      +
      +The number of conflicting options are returned with "options" pointing to +the conflicting options. The returned option array must be freed using +cupsFreeOptions. + +

      +

      cupsMarkOptions

      +

      Mark command-line options in a PPD file.

      +

      +int cupsMarkOptions (
      +    ppd_file_t *ppd,
      +    int num_options,
      +    cups_option_t *options
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      +

      Return Value

      +

      1 if conflicts exist, 0 otherwise

      +

      Discussion

      +

      This function maps the IPP "finishings", "media", "mirror", +"multiple-document-handling", "output-bin", "printer-resolution", and +"sides" attributes to their corresponding PPD options and choices.

      +

       CUPS 1.4/Mac OS X 10.6 cupsResolveConflicts

      +

      Resolve conflicts in a marked PPD.

      +

      +int cupsResolveConflicts (
      +    ppd_file_t *ppd,
      +    const char *option,
      +    const char *choice,
      +    int *num_options,
      +    cups_option_t **options
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      option
      +
      Newly selected option or NULL for none
      +
      choice
      +
      Newly selected choice or NULL for none
      +
      num_options
      +
      Number of additional selected options
      +
      options
      +
      Additional selected options
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      This function attempts to resolve any conflicts in a marked PPD, returning +a list of option changes that are required to resolve them. On input, +"num_options" and "options" contain any pending option changes that have +not yet been marked, while "option" and "choice" contain the most recent +selection which may or may not be in "num_options" or "options".
      +
      +On successful return, "num_options" and "options" are updated to contain +"option" and "choice" along with any changes required to resolve conflicts +specified in the PPD file and 1 is returned.
      +
      +If option conflicts cannot be resolved, "num_options" and "options" are not +changed and 0 is returned.
      +
      +When resolving conflicts, cupsResolveConflicts does not consider +changes to the current page size (media, PageSize, and +PageRegion) or to the most recent option specified in "option". +Thus, if the only way to resolve a conflict is to change the page size +or the option the user most recently changed, cupsResolveConflicts +will return 0 to indicate it was unable to resolve the conflicts.
      +
      +The cupsResolveConflicts function uses one of two sources of option +constraint information. The preferred constraint information is defined by +cupsUIConstraints and cupsUIResolver attributes - in this +case, the PPD file provides constraint resolution actions.
      +
      +The backup constraint information is defined by the +UIConstraints and NonUIConstraints attributes. These +constraints are resolved algorithmically by first selecting the default +choice for the conflicting option, then iterating over all possible choices +until a non-conflicting option choice is found. + +

      +

      ppdClose

      +

      Free all memory used by the PPD file.

      +

      +void ppdClose (
      +    ppd_file_t *ppd
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      +

      ppdCollect

      +

      Collect all marked options that reside in the specified +section.

      +

      +int ppdCollect (
      +    ppd_file_t *ppd,
      +    ppd_section_t section,
      +    ppd_choice_t ***choices
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file data
      +
      section
      +
      Section to collect
      +
      choices
      +
      Pointers to choices
      +
      +

      Return Value

      +

      Number of options marked

      +

      Discussion

      +

      The choices array should be freed using free when you are +finished with it.

      +

       CUPS 1.2/Mac OS X 10.5 ppdCollect2

      +

      Collect all marked options that reside in the +specified section and minimum order.

      +

      +int ppdCollect2 (
      +    ppd_file_t *ppd,
      +    ppd_section_t section,
      +    float min_order,
      +    ppd_choice_t ***choices
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file data
      +
      section
      +
      Section to collect
      +
      min_order
      +
      Minimum OrderDependency value
      +
      choices
      +
      Pointers to choices
      +
      +

      Return Value

      +

      Number of options marked

      +

      Discussion

      +

      The choices array should be freed using free when you are +finished with it. + +

      +

      ppdConflicts

      +

      Check to see if there are any conflicts among the +marked option choices.

      +

      +int ppdConflicts (
      +    ppd_file_t *ppd
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD to check
      +
      +

      Return Value

      +

      Number of conflicts found

      +

      Discussion

      +

      The returned value is the same as returned by ppdMarkOption.

      +

      ppdEmit

      +

      Emit code for marked options to a file.

      +

      +int ppdEmit (
      +    ppd_file_t *ppd,
      +    FILE *fp,
      +    ppd_section_t section
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      fp
      +
      File to write to
      +
      section
      +
      Section to write
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

       CUPS 1.2/Mac OS X 10.5 ppdEmitAfterOrder

      +

      Emit a subset of the code for marked options to a file.

      +

      +int ppdEmitAfterOrder (
      +    ppd_file_t *ppd,
      +    FILE *fp,
      +    ppd_section_t section,
      +    int limit,
      +    float min_order
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      fp
      +
      File to write to
      +
      section
      +
      Section to write
      +
      limit
      +
      Non-zero to use min_order
      +
      min_order
      +
      Lowest OrderDependency
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

      Discussion

      +

      When "limit" is non-zero, this function only emits options whose +OrderDependency value is greater than or equal to "min_order".
      +
      +When "limit" is zero, this function is identical to ppdEmit(). + +

      +

      ppdEmitFd

      +

      Emit code for marked options to a file.

      +

      +int ppdEmitFd (
      +    ppd_file_t *ppd,
      +    int fd,
      +    ppd_section_t section
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      fd
      +
      File to write to
      +
      section
      +
      Section to write
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

      ppdEmitJCL

      +

      Emit code for JCL options to a file.

      +

      +int ppdEmitJCL (
      +    ppd_file_t *ppd,
      +    FILE *fp,
      +    int job_id,
      +    const char *user,
      +    const char *title
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      fp
      +
      File to write to
      +
      job_id
      +
      Job ID
      +
      user
      +
      Username
      +
      title
      +
      Title
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

       CUPS 1.2/Mac OS X 10.5 ppdEmitJCLEnd

      +

      Emit JCLEnd code to a file.

      +

      +int ppdEmitJCLEnd (
      +    ppd_file_t *ppd,
      +    FILE *fp
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      fp
      +
      File to write to
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

       CUPS 1.2/Mac OS X 10.5 ppdEmitString

      +

      Get a string containing the code for marked options.

      +

      +char *ppdEmitString (
      +    ppd_file_t *ppd,
      +    ppd_section_t section,
      +    float min_order
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      section
      +
      Section to write
      +
      min_order
      +
      Lowest OrderDependency
      +
      +

      Return Value

      +

      String containing option code or NULL if there is no option code

      +

      Discussion

      +

      When "min_order" is greater than zero, this function only includes options +whose OrderDependency value is greater than or equal to "min_order". +Otherwise, all options in the specified section are included in the +returned string.
      +
      +The return string is allocated on the heap and should be freed using +free when you are done with it. + +

      +

       CUPS 1.1.19/Mac OS X 10.3 ppdErrorString

      +

      Returns the text assocated with a status.

      +

      +const char *ppdErrorString (
      +    ppd_status_t status
      +);

      +

      Parameters

      +
      +
      status
      +
      PPD status
      +
      +

      Return Value

      +

      Status string

      +

       CUPS 1.1.19/Mac OS X 10.3 ppdFindAttr

      +

      Find the first matching attribute.

      +

      +ppd_attr_t *ppdFindAttr (
      +    ppd_file_t *ppd,
      +    const char *name,
      +    const char *spec
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file data
      +
      name
      +
      Attribute name
      +
      spec
      +
      Specifier string or NULL
      +
      +

      Return Value

      +

      Attribute or NULL if not found

      +

      ppdFindChoice

      +

      Return a pointer to an option choice.

      +

      +ppd_choice_t *ppdFindChoice (
      +    ppd_option_t *o,
      +    const char *choice
      +);

      +

      Parameters

      +
      +
      o
      +
      Pointer to option
      +
      choice
      +
      Name of choice
      +
      +

      Return Value

      +

      Choice pointer or NULL

      +

       CUPS 1.2/Mac OS X 10.5 ppdFindCustomOption

      +

      Find a custom option.

      +

      +ppd_coption_t *ppdFindCustomOption (
      +    ppd_file_t *ppd,
      +    const char *keyword
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      keyword
      +
      Custom option name
      +
      +

      Return Value

      +

      Custom option or NULL

      +

       CUPS 1.2/Mac OS X 10.5 ppdFindCustomParam

      +

      Find a parameter for a custom option.

      +

      +ppd_cparam_t *ppdFindCustomParam (
      +    ppd_coption_t *opt,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      opt
      +
      Custom option
      +
      name
      +
      Parameter name
      +
      +

      Return Value

      +

      Custom parameter or NULL

      +

      ppdFindMarkedChoice

      +

      Return the marked choice for the specified option.

      +

      +ppd_choice_t *ppdFindMarkedChoice (
      +    ppd_file_t *ppd,
      +    const char *option
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      option
      +
      Keyword/option name
      +
      +

      Return Value

      +

      Pointer to choice or NULL

      +

       CUPS 1.1.19/Mac OS X 10.3 ppdFindNextAttr

      +

      Find the next matching attribute.

      +

      +ppd_attr_t *ppdFindNextAttr (
      +    ppd_file_t *ppd,
      +    const char *name,
      +    const char *spec
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file data
      +
      name
      +
      Attribute name
      +
      spec
      +
      Specifier string or NULL
      +
      +

      Return Value

      +

      Attribute or NULL if not found

      +

      ppdFindOption

      +

      Return a pointer to the specified option.

      +

      +ppd_option_t *ppdFindOption (
      +    ppd_file_t *ppd,
      +    const char *option
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file data
      +
      option
      +
      Option/Keyword name
      +
      +

      Return Value

      +

      Pointer to option or NULL

      +

       CUPS 1.2/Mac OS X 10.5 ppdFirstCustomParam

      +

      Return the first parameter for a custom option.

      +

      +ppd_cparam_t *ppdFirstCustomParam (
      +    ppd_coption_t *opt
      +);

      +

      Parameters

      +
      +
      opt
      +
      Custom option
      +
      +

      Return Value

      +

      Custom parameter or NULL

      +

       CUPS 1.2/Mac OS X 10.5 ppdFirstOption

      +

      Return the first option in the PPD file.

      +

      +ppd_option_t *ppdFirstOption (
      +    ppd_file_t *ppd
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      +

      Return Value

      +

      First option or NULL

      +

      Discussion

      +

      Options are returned from all groups in ascending alphanumeric order. + +

      +

       CUPS 1.4/Mac OS X 10.6 ppdInstallableConflict

      +

      Test whether an option choice conflicts with +an installable option.

      +

      +int ppdInstallableConflict (
      +    ppd_file_t *ppd,
      +    const char *option,
      +    const char *choice
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      option
      +
      Option
      +
      choice
      +
      Choice
      +
      +

      Return Value

      +

      1 if conflicting, 0 if not conflicting

      +

      Discussion

      +

      This function tests whether a particular option choice is available based +on constraints against options in the "InstallableOptions" group. + +

      +

      ppdIsMarked

      +

      Check to see if an option is marked.

      +

      +int ppdIsMarked (
      +    ppd_file_t *ppd,
      +    const char *option,
      +    const char *choice
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file data
      +
      option
      +
      Option/Keyword name
      +
      choice
      +
      Choice name
      +
      +

      Return Value

      +

      Non-zero if option is marked

      +

       CUPS 1.1.19/Mac OS X 10.3 ppdLastError

      +

      Return the status from the last ppdOpen*().

      +

      +ppd_status_t ppdLastError (
      +    int *line
      +);

      +

      Parameters

      +
      +
      line
      +
      Line number
      +
      +

      Return Value

      +

      Status code

      +

       CUPS 1.2/Mac OS X 10.5 ppdLocalize

      +

      Localize the PPD file to the current locale.

      +

      +int ppdLocalize (
      +    ppd_file_t *ppd
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      +

      Return Value

      +

      0 on success, -1 on error

      +

      Discussion

      +

      All groups, options, and choices are localized, as are ICC profile +descriptions, printer presets, and custom option parameters. Each +localized string uses the UTF-8 character encoding. + +

      +

      ppdLocalizeAttr

      +

      Localize an attribute.

      +

      +ppd_attr_t *ppdLocalizeAttr (
      +    ppd_file_t *ppd,
      +    const char *keyword,
      +    const char *spec
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      keyword
      +
      Main keyword
      +
      spec
      +
      Option keyword or NULL for none
      +
      +

      Return Value

      +

      Localized attribute or NULL if none exists

      +

      Discussion

      +

      This function uses the current locale to find the localized attribute for +the given main and option keywords. If no localized version of the +attribute exists for the current locale, the unlocalized version is returned.

      +

       CUPS 1.3/Mac OS X 10.5 ppdLocalizeIPPReason

      +

      Get the localized version of a cupsIPPReason +attribute.

      +

      +const char *ppdLocalizeIPPReason (
      +    ppd_file_t *ppd,
      +    const char *reason,
      +    const char *scheme,
      +    char *buffer,
      +    size_t bufsize
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      reason
      +
      IPP reason keyword to look up
      +
      scheme
      +
      URI scheme or NULL for text
      +
      buffer
      +
      Value buffer
      +
      bufsize
      +
      Size of value buffer
      +
      +

      Return Value

      +

      Value or NULL if not found

      +

      Discussion

      +

      This function uses the current locale to find the corresponding reason +text or URI from the attribute value. If "scheme" is NULL or "text", +the returned value contains human-readable (UTF-8) text from the translation +string or attribute value. Otherwise the corresponding URI is returned.
      +
      +If no value of the requested scheme can be found, NULL is returned. + +

      +

       CUPS 1.4/Mac OS X 10.6 ppdLocalizeMarkerName

      +

      Get the localized version of a marker-names +attribute value.

      +

      +const char *ppdLocalizeMarkerName (
      +    ppd_file_t *ppd,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      name
      +
      Marker name to look up
      +
      +

      Return Value

      +

      Value or NULL if not found

      +

      Discussion

      +

      This function uses the current locale to find the corresponding name +text from the attribute value. If no localized text for the requested +name can be found, NULL is returned. + +

      +

      ppdMarkDefaults

      +

      Mark all default options in the PPD file.

      +

      +void ppdMarkDefaults (
      +    ppd_file_t *ppd
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      +

      ppdMarkOption

      +

      Mark an option in a PPD file and return the number of +conflicts.

      +

      +int ppdMarkOption (
      +    ppd_file_t *ppd,
      +    const char *option,
      +    const char *choice
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      option
      +
      Keyword
      +
      choice
      +
      Option name
      +
      +

      Return Value

      +

      Number of conflicts

      +

       CUPS 1.2/Mac OS X 10.5 ppdNextCustomParam

      +

      Return the next parameter for a custom option.

      +

      +ppd_cparam_t *ppdNextCustomParam (
      +    ppd_coption_t *opt
      +);

      +

      Parameters

      +
      +
      opt
      +
      Custom option
      +
      +

      Return Value

      +

      Custom parameter or NULL

      +

       CUPS 1.2/Mac OS X 10.5 ppdNextOption

      +

      Return the next option in the PPD file.

      +

      +ppd_option_t *ppdNextOption (
      +    ppd_file_t *ppd
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      +

      Return Value

      +

      Next option or NULL

      +

      Discussion

      +

      Options are returned from all groups in ascending alphanumeric order. + +

      +

      ppdOpen

      +

      Read a PPD file into memory.

      +

      +ppd_file_t *ppdOpen (
      +    FILE *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      File to read from
      +
      +

      Return Value

      +

      PPD file record

      +

       CUPS 1.2/Mac OS X 10.5 ppdOpen2

      +

      Read a PPD file into memory.

      +

      +ppd_file_t *ppdOpen2 (
      +    cups_file_t *fp
      +);

      +

      Parameters

      +
      +
      fp
      +
      File to read from
      +
      +

      Return Value

      +

      PPD file record or NULL if the PPD file could not be opened.

      +

      ppdOpenFd

      +

      Read a PPD file into memory.

      +

      +ppd_file_t *ppdOpenFd (
      +    int fd
      +);

      +

      Parameters

      +
      +
      fd
      +
      File to read from
      +
      +

      Return Value

      +

      PPD file record or NULL if the PPD file could not be opened.

      +

      ppdOpenFile

      +

      Read a PPD file into memory.

      +

      +ppd_file_t *ppdOpenFile (
      +    const char *filename
      +);

      +

      Parameters

      +
      +
      filename
      +
      File to read from
      +
      +

      Return Value

      +

      PPD file record or NULL if the PPD file could not be opened.

      +

      ppdPageLength

      +

      Get the page length for the given size.

      +

      +float ppdPageLength (
      +    ppd_file_t *ppd,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file
      +
      name
      +
      Size name
      +
      +

      Return Value

      +

      Length of page in points or 0.0

      +

      ppdPageSize

      +

      Get the page size record for the given size.

      +

      +ppd_size_t *ppdPageSize (
      +    ppd_file_t *ppd,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      name
      +
      Size name
      +
      +

      Return Value

      +

      Size record for page or NULL

      +

       CUPS 1.4/Mac OS X 10.6 ppdPageSizeLimits

      +

      Return the custom page size limits.

      +

      +int ppdPageSizeLimits (
      +    ppd_file_t *ppd,
      +    ppd_size_t *minimum,
      +    ppd_size_t *maximum
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      minimum
      +
      Minimum custom size
      +
      maximum
      +
      Maximum custom size
      +
      +

      Return Value

      +

      1 if custom sizes are supported, 0 otherwise

      +

      Discussion

      +

      This function returns the minimum and maximum custom page sizes and printable +areas based on the currently-marked (selected) options.
      +
      +If the specified PPD file does not support custom page sizes, both +"minimum" and "maximum" are filled with zeroes. + +

      +

      ppdPageWidth

      +

      Get the page width for the given size.

      +

      +float ppdPageWidth (
      +    ppd_file_t *ppd,
      +    const char *name
      +);

      +

      Parameters

      +
      +
      ppd
      +
      PPD file record
      +
      name
      +
      Size name
      +
      +

      Return Value

      +

      Width of page in points or 0.0

      +

       CUPS 1.1.20/Mac OS X 10.4 ppdSetConformance

      +

      Set the conformance level for PPD files.

      +

      +void ppdSetConformance (
      +    ppd_conform_t c
      +);

      +

      Parameters

      +
      +
      c
      +
      Conformance level
      +
      +

      Data Types

      +

       CUPS 1.1.19/Mac OS X 10.3 ppd_attr_t

      +

      PPD Attribute Structure

      +

      +typedef struct ppd_attr_s ppd_attr_t; +

      +

      ppd_choice_t

      +

      Option choices

      +

      +typedef struct ppd_choice_s ppd_choice_t; +

      +

       CUPS 1.1.19/Mac OS X 10.3 ppd_conform_t

      +

      Conformance Levels

      +

      +typedef enum ppd_conform_e ppd_conform_t; +

      +

      ppd_const_t

      +

      Constraints

      +

      +typedef struct ppd_const_s ppd_const_t; +

      +

       CUPS 1.2/Mac OS X 10.5 ppd_coption_t

      +

      Custom Option

      +

      +typedef struct ppd_coption_s ppd_coption_t; +

      +

       CUPS 1.2/Mac OS X 10.5 ppd_cparam_t

      +

      Custom Parameter

      +

      +typedef struct ppd_cparam_s ppd_cparam_t; +

      +

       CUPS 1.2/Mac OS X 10.5 ppd_cplimit_t

      +

      Custom Parameter Limit

      +

      +typedef union ppd_cplimit_u ppd_cplimit_t; +

      +

       CUPS 1.2/Mac OS X 10.5 ppd_cptype_t

      +

      Custom Parameter Type

      +

      +typedef enum ppd_cptype_e ppd_cptype_t; +

      +

       CUPS 1.2/Mac OS X 10.5 ppd_cpvalue_t

      +

      Custom Parameter Value

      +

      +typedef union ppd_cpvalue_u ppd_cpvalue_t; +

      +

      ppd_cs_t

      +

      Colorspaces

      +

      +typedef enum ppd_cs_e ppd_cs_t; +

      +

      ppd_emul_t

      +

      Emulators

      +

      +typedef struct ppd_emul_s ppd_emul_t; +

      +

      ppd_file_t

      +

      PPD File

      +

      +typedef struct ppd_file_s ppd_file_t; +

      +

      ppd_group_t

      +

      Groups

      +

      +typedef struct ppd_group_s ppd_group_t; +

      +

      ppd_option_t

      +

      Options

      +

      +typedef struct ppd_option_s ppd_option_t; +

      +

      ppd_profile_t

      +

      sRGB Color Profiles

      +

      +typedef struct ppd_profile_s ppd_profile_t; +

      +

      ppd_section_t

      +

      Order dependency sections

      +

      +typedef enum ppd_section_e ppd_section_t; +

      +

      ppd_size_t

      +

      Page Sizes

      +

      +typedef struct ppd_size_s ppd_size_t; +

      +

       CUPS 1.1.19/Mac OS X 10.3 ppd_status_t

      +

      Status Codes

      +

      +typedef enum ppd_status_e ppd_status_t; +

      +

      ppd_ui_t

      +

      UI Types

      +

      +typedef enum ppd_ui_e ppd_ui_t; +

      +

      Structures

      +

       CUPS 1.1.19/Mac OS X 10.3 ppd_attr_s

      +

      PPD Attribute Structure

      +

      struct ppd_attr_s {
      +    char name[PPD_MAX_NAME];
      +    char spec[PPD_MAX_NAME];
      +    char text[PPD_MAX_TEXT];
      +    char *value;
      +};

      +

      Members

      +
      +
      name[PPD_MAX_NAME]
      +
      Name of attribute (cupsXYZ)
      +
      spec[PPD_MAX_NAME]
      +
      Specifier string, if any
      +
      text[PPD_MAX_TEXT]
      +
      Human-readable text, if any
      +
      value
      +
      Value string
      +
      +

      ppd_choice_s

      +

      Option choices

      +

      struct ppd_choice_s {
      +    char choice[PPD_MAX_NAME];
      +    char *code;
      +    char marked;
      +    ppd_option_t *option;
      +    char text[PPD_MAX_TEXT];
      +};

      +

      Members

      +
      +
      choice[PPD_MAX_NAME]
      +
      Computer-readable option name
      +
      code
      +
      Code to send for this option
      +
      marked
      +
      0 if not selected, 1 otherwise
      +
      option
      +
      Pointer to parent option structure
      +
      text[PPD_MAX_TEXT]
      +
      Human-readable option name
      +
      +

      ppd_const_s

      +

      Constraints

      +

      struct ppd_const_s {
      +    char choice1[PPD_MAX_NAME];
      +    char choice2[PPD_MAX_NAME];
      +    char option1[PPD_MAX_NAME];
      +    char option2[PPD_MAX_NAME];
      +};

      +

      Members

      +
      +
      choice1[PPD_MAX_NAME]
      +
      First option/choice (blank for all)
      +
      choice2[PPD_MAX_NAME]
      +
      Second option/choice (blank for all)
      +
      option1[PPD_MAX_NAME]
      +
      First keyword
      +
      option2[PPD_MAX_NAME]
      +
      Second keyword
      +
      +

       CUPS 1.2/Mac OS X 10.5 ppd_coption_s

      +

      Custom Option

      +

      struct ppd_coption_s {
      +    char keyword[PPD_MAX_NAME];
      +    int marked;
      +    ppd_option_t *option;
      +    cups_array_t *params;
      +};

      +

      Members

      +
      +
      keyword[PPD_MAX_NAME]
      +
      Name of option that is being extended...
      +
      marked
      +
      Extended option is marked
      +
      option
      +
      Option that is being extended...
      +
      params
      +
      Parameters
      +
      +

       CUPS 1.2/Mac OS X 10.5 ppd_cparam_s

      +

      Custom Parameter

      +

      struct ppd_cparam_s {
      +    ppd_cpvalue_t current;
      +    ppd_cplimit_t minimum, maximum;
      +    char name[PPD_MAX_NAME];
      +    int order;
      +    char text[PPD_MAX_TEXT];
      +    ppd_cptype_t type;
      +};

      +

      Members

      +
      +
      current
      +
      Current value
      +
      maximum
      +
      Maximum value
      +
      name[PPD_MAX_NAME]
      +
      Parameter name
      +
      order
      +
      Order (0 to N)
      +
      text[PPD_MAX_TEXT]
      +
      Human-readable text
      +
      type
      +
      Parameter type
      +
      +

      ppd_emul_s

      +

      Emulators

      +

      struct ppd_emul_s {
      +    char name[PPD_MAX_NAME];
      +    char *start;
      +    char *stop;
      +};

      +

      Members

      +
      +
      name[PPD_MAX_NAME]
      +
      Emulator name
      +
      start
      +
      Code to switch to this emulation
      +
      stop
      +
      Code to stop this emulation
      +
      +

      ppd_file_s

      +

      PPD File

      +

      struct ppd_file_s {
      +    int accurate_screens;
      +    int color_device;
      +    ppd_cs_t colorspace;
      +    ppd_const_t *consts;
      +    int contone_only;
      +    float custom_margins[4];
      +    float custom_max[2];
      +    float custom_min[2];
      +    ppd_emul_t *emulations;
      +    char **filters;
      +    int flip_duplex;
      +    char **fonts;
      +    ppd_group_t *groups;
      +    char *jcl_begin;
      +    char *jcl_end;
      +    char *jcl_ps;
      +    int landscape;
      +    char *lang_encoding;
      +    char *lang_version;
      +    int language_level;
      +    int manual_copies;
      +    char *manufacturer;
      +    int model_number;
      +    char *modelname;
      +    char *nickname;
      +    int num_consts;
      +    int num_emulations;
      +    int num_filters;
      +    int num_fonts;
      +    int num_groups;
      +    int num_profiles;
      +    int num_sizes;
      +    char *patches;
      +    char *pcfilename;
      +    char *product;
      +    ppd_profile_t *profiles;
      +    char *protocols;
      +    void *pwg;
      +    char *shortnickname;
      +    ppd_size_t *sizes;
      +    int throughput;
      +    char *ttrasterizer;
      +    int variable_sizes;
      +};

      +

      Members

      +
      +
      accurate_screens
      +
      1 = supports accurate screens, 0 = not
      +
      color_device
      +
      1 = color device, 0 = grayscale
      +
      colorspace
      +
      Default colorspace
      +
      consts
      +
      UI/Non-UI constraints
      +
      contone_only
      +
      1 = continuous tone only, 0 = not
      +
      custom_margins[4]
      +
      Margins around page
      +
      custom_max[2]
      +
      Maximum variable page size
      +
      custom_min[2]
      +
      Minimum variable page size
      +
      emulations
      +
      Emulations and the code to invoke them
      +
      filters
      +
      Filter strings...
      +
      flip_duplex  DEPRECATED 
      +
      1 = Flip page for back sides
      +
      fonts
      +
      Pre-loaded fonts
      +
      groups
      +
      UI groups
      +
      jcl_begin
      +
      Start JCL commands
      +
      jcl_end
      +
      End JCL commands
      +
      jcl_ps
      +
      Enter PostScript interpreter
      +
      landscape
      +
      -90 or 90
      +
      lang_encoding
      +
      Language encoding
      +
      lang_version
      +
      Language version (English, Spanish, etc.)
      +
      language_level
      +
      Language level of device
      +
      manual_copies
      +
      1 = Copies done manually, 0 = hardware
      +
      manufacturer
      +
      Manufacturer name
      +
      model_number
      +
      Device-specific model number
      +
      modelname
      +
      Model name (general)
      +
      nickname
      +
      Nickname (specific)
      +
      num_consts
      +
      Number of UI/Non-UI constraints
      +
      num_emulations
      +
      Number of emulations supported
      +
      num_filters
      +
      Number of filters
      +
      num_fonts
      +
      Number of pre-loaded fonts
      +
      num_groups
      +
      Number of UI groups
      +
      num_profiles  DEPRECATED 
      +
      Number of sRGB color profiles
      +
      num_sizes
      +
      Number of page sizes
      +
      patches
      +
      Patch commands to be sent to printer
      +
      pcfilename  CUPS 1.1.19/Mac OS X 10.3 
      +
      PCFileName string
      +
      product
      +
      Product name (from PS RIP/interpreter)
      +
      profiles  DEPRECATED 
      +
      sRGB color profiles
      +
      protocols  CUPS 1.1.19/Mac OS X 10.3 
      +
      Protocols (BCP, TBCP) string
      +
      pwg
      +
      PWG to/from PPD mappings
      +
      shortnickname
      +
      Short version of nickname
      +
      sizes
      +
      Page sizes
      +
      throughput
      +
      Pages per minute
      +
      ttrasterizer
      +
      Truetype rasterizer
      +
      variable_sizes
      +
      1 = supports variable sizes, 0 = doesn't
      +
      +

      ppd_group_s

      +

      Groups

      +

      struct ppd_group_s {
      +    char text[PPD_MAX_TEXT - PPD_MAX_NAME];
      +    char name[PPD_MAX_NAME];
      +    int num_options;
      +    int num_subgroups;
      +    ppd_option_t *options;
      +    struct ppd_group_s *subgroups;
      +};

      +

      Members

      +
      +
      PPD_MAX_NAME]
      +
      Human-readable group name
      +
      name[PPD_MAX_NAME]  CUPS 1.1.18/Mac OS X 10.3 
      +
      Group name
      +
      num_options
      +
      Number of options
      +
      num_subgroups
      +
      Number of sub-groups
      +
      options
      +
      Options
      +
      subgroups
      +
      Sub-groups (max depth = 1)
      +
      +

      ppd_option_s

      +

      Options

      +

      struct ppd_option_s {
      +    ppd_choice_t *choices;
      +    char conflicted;
      +    char defchoice[PPD_MAX_NAME];
      +    char keyword[PPD_MAX_NAME];
      +    int num_choices;
      +    float order;
      +    ppd_section_t section;
      +    char text[PPD_MAX_TEXT];
      +    ppd_ui_t ui;
      +};

      +

      Members

      +
      +
      choices
      +
      Option choices
      +
      conflicted
      +
      0 if no conflicts exist, 1 otherwise
      +
      defchoice[PPD_MAX_NAME]
      +
      Default option choice
      +
      keyword[PPD_MAX_NAME]
      +
      Option keyword name ("PageSize", etc.)
      +
      num_choices
      +
      Number of option choices
      +
      order
      +
      Order number
      +
      section
      +
      Section for command
      +
      text[PPD_MAX_TEXT]
      +
      Human-readable text
      +
      ui
      +
      Type of UI option
      +
      +

      ppd_profile_s

      +

      sRGB Color Profiles

      +

      struct ppd_profile_s {
      +    float density;
      +    float gamma;
      +    float matrix[3][3];
      +    char media_type[PPD_MAX_NAME];
      +    char resolution[PPD_MAX_NAME];
      +};

      +

      Members

      +
      +
      density
      +
      Ink density to use
      +
      gamma
      +
      Gamma correction to use
      +
      matrix[3][3]
      +
      Transform matrix
      +
      media_type[PPD_MAX_NAME]
      +
      Media type or "-"
      +
      resolution[PPD_MAX_NAME]
      +
      Resolution or "-"
      +
      +

      ppd_size_s

      +

      Page Sizes

      +

      struct ppd_size_s {
      +    float bottom;
      +    float left;
      +    float length;
      +    int marked;
      +    char name[PPD_MAX_NAME];
      +    float right;
      +    float top;
      +    float width;
      +};

      +

      Members

      +
      +
      bottom
      +
      Bottom printable margin in points
      +
      left
      +
      Left printable margin in points
      +
      length
      +
      Length of media in points
      +
      marked
      +
      Page size selected?
      +
      name[PPD_MAX_NAME]
      +
      Media size option
      +
      right
      +
      Right printable margin in points
      +
      top
      +
      Top printable margin in points
      +
      width
      +
      Width of media in points
      +
      +

      Unions

      +

       CUPS 1.2/Mac OS X 10.5 ppd_cplimit_u

      +

      Custom Parameter Limit

      +

      union ppd_cplimit_u {
      +    float custom_curve;
      +    int custom_int;
      +    float custom_invcurve;
      +    int custom_passcode;
      +    int custom_password;
      +    float custom_points;
      +    float custom_real;
      +    int custom_string;
      +};

      +

      Members

      +
      +
      custom_curve
      +
      Gamma value
      +
      custom_int
      +
      Integer value
      +
      custom_invcurve
      +
      Gamma value
      +
      custom_passcode
      +
      Passcode length
      +
      custom_password
      +
      Password length
      +
      custom_points
      +
      Measurement value
      +
      custom_real
      +
      Real value
      +
      custom_string
      +
      String length
      +
      +

       CUPS 1.2/Mac OS X 10.5 ppd_cpvalue_u

      +

      Custom Parameter Value

      +

      union ppd_cpvalue_u {
      +    float custom_curve;
      +    int custom_int;
      +    float custom_invcurve;
      +    char *custom_passcode;
      +    char *custom_password;
      +    float custom_points;
      +    float custom_real;
      +    char *custom_string;
      +};

      +

      Members

      +
      +
      custom_curve
      +
      Gamma value
      +
      custom_int
      +
      Integer value
      +
      custom_invcurve
      +
      Gamma value
      +
      custom_passcode
      +
      Passcode value
      +
      custom_password
      +
      Password value
      +
      custom_points
      +
      Measurement value
      +
      custom_real
      +
      Real value
      +
      custom_string
      +
      String value
      +
      +

      Constants

      +

       CUPS 1.1.19/Mac OS X 10.3 ppd_conform_e

      +

      Conformance Levels

      +

      Constants

      +
      +
      PPD_CONFORM_RELAXED
      +
      Relax whitespace and control char
      +
      PPD_CONFORM_STRICT
      +
      Require strict conformance
      +
      +

       CUPS 1.2/Mac OS X 10.5 ppd_cptype_e

      +

      Custom Parameter Type

      +

      Constants

      +
      +
      PPD_CUSTOM_CURVE
      +
      Curve value for f(x) = x^value
      +
      PPD_CUSTOM_INT
      +
      Integer number value
      +
      PPD_CUSTOM_INVCURVE
      +
      Curve value for f(x) = x^(1/value)
      +
      PPD_CUSTOM_PASSCODE
      +
      String of (hidden) numbers
      +
      PPD_CUSTOM_PASSWORD
      +
      String of (hidden) characters
      +
      PPD_CUSTOM_POINTS
      +
      Measurement value in points
      +
      PPD_CUSTOM_REAL
      +
      Real number value
      +
      PPD_CUSTOM_STRING
      +
      String of characters
      +
      +

      ppd_cs_e

      +

      Colorspaces

      +

      Constants

      +
      +
      PPD_CS_CMY
      +
      CMY colorspace
      +
      PPD_CS_CMYK
      +
      CMYK colorspace
      +
      PPD_CS_GRAY
      +
      Grayscale colorspace
      +
      PPD_CS_N
      +
      DeviceN colorspace
      +
      PPD_CS_RGB
      +
      RGB colorspace
      +
      PPD_CS_RGBK
      +
      RGBK (K = gray) colorspace
      +
      +

      ppd_section_e

      +

      Order dependency sections

      +

      Constants

      +
      +
      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
      +
      +

       CUPS 1.1.19/Mac OS X 10.3 ppd_status_e

      +

      Status Codes

      +

      Constants

      +
      +
      PPD_ALLOC_ERROR
      +
      Memory allocation error
      +
      PPD_BAD_CUSTOM_PARAM
      +
      Bad custom parameter
      +
      PPD_BAD_OPEN_GROUP
      +
      Bad OpenGroup
      +
      PPD_BAD_OPEN_UI
      +
      Bad OpenUI/JCLOpenUI
      +
      PPD_BAD_ORDER_DEPENDENCY
      +
      Bad OrderDependency
      +
      PPD_BAD_UI_CONSTRAINTS
      +
      Bad UIConstraints
      +
      PPD_BAD_VALUE
      +
      Bad value string
      +
      PPD_FILE_OPEN_ERROR
      +
      Unable to open PPD file
      +
      PPD_ILLEGAL_CHARACTER
      +
      Illegal control character
      +
      PPD_ILLEGAL_MAIN_KEYWORD
      +
      Illegal main keyword string
      +
      PPD_ILLEGAL_OPTION_KEYWORD
      +
      Illegal option keyword string
      +
      PPD_ILLEGAL_TRANSLATION
      +
      Illegal translation string
      +
      PPD_ILLEGAL_WHITESPACE
      +
      Illegal whitespace character
      +
      PPD_INTERNAL_ERROR
      +
      Internal error
      +
      PPD_LINE_TOO_LONG
      +
      Line longer than 255 chars
      +
      PPD_MISSING_ASTERISK
      +
      Missing asterisk in column 0
      +
      PPD_MISSING_OPTION_KEYWORD
      +
      Missing option keyword
      +
      PPD_MISSING_PPDADOBE4
      +
      Missing PPD-Adobe-4.x header
      +
      PPD_MISSING_VALUE
      +
      Missing value string
      +
      PPD_NESTED_OPEN_GROUP
      +
      OpenGroup without a CloseGroup first
      +
      PPD_NESTED_OPEN_UI
      +
      OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first
      +
      PPD_NULL_FILE
      +
      NULL PPD file pointer
      +
      PPD_OK
      +
      OK
      +
      +

      ppd_ui_e

      +

      UI Types

      +

      Constants

      +
      +
      PPD_UI_BOOLEAN
      +
      True or False option
      +
      PPD_UI_PICKMANY
      +
      Pick zero or more from a list
      +
      PPD_UI_PICKONE
      +
      Pick one from a list
      +
      +
+ + diff --git a/doc/help/api-ppdc.html b/doc/help/api-ppdc.html new file mode 100644 index 0000000000..4b95f6a5af --- /dev/null +++ b/doc/help/api-ppdc.html @@ -0,0 +1,2194 @@ + + + + +PPD Compiler API + + + + + +
+ + +

PPD Compiler API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/ppdc.h
Library-lcupsppdc
See AlsoProgramming: Introduction to CUPS Programming
+

Contents

+
    +
      +
    • Overview
    • +
    • Classes
    • +
    • Data Types
    • +
    • Variables
    • +
    • Constants
    • + + +

      Overview

      + +

      The PPD Compiler API provides access to CUPS driver information files and +methods for generating and importing PPD files.

      +

      Classes

      +

      ppdcArray

      +

      // Shared Array

      +

      class ppdcArray : public ppdcShared {
      +  public:
      +    int count, alloc, current;
      +    ppdcShared **data;
      +};

      +

      Members

      +
      +
      current
      +
      Current element
      +
      data
      +
      Elements
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    void add(ppdcShared *d
      +);

      +
      Parameters
      +
      +
      d
      +
      +

      add

      +

      +

      +void add (
      +    ppdcShared *d
      +);

      +
      Parameters
      +
      +
      d
      +
      +

      first

      +

      Return the first element in the array.

      +

      +ppdcShared *first (void);

      +
      Return Value
      +

      +

      next

      +

      Return the next element in the array.

      +

      +ppdcShared *next (void);

      +
      Return Value
      +

      +

      ppdcArray

      +

      +

      +void ppdcArray (
      +    ppdcArray *a
      +);

      +
      Parameters
      +
      +
      a
      +
      +

      remove

      +

      +

      +void remove (
      +    ppdcShared *d
      +);

      +
      Parameters
      +
      +
      d
      +
      Data element
      +
      +

      ~ppdcArray

      +

      +

      +void ~ppdcArray (void);

      +

      ppdcAttr

      +

      // Attribute

      +

      class ppdcAttr : public ppdcShared {
      +  public:
      +    bool localizable;
      +    ppdcString *name, *selector, *text, *value;
      +};

      +

      Members

      +
      +
      localizable
      +
      Should this attribute be localized?
      +
      value
      +
      Value string
      +
      +

      ppdcAttr

      +

      +

      +void ppdcAttr (
      +    const char *n,
      +    const char *s,
      +    const char *t,
      +    const char *v,
      +    bool loc
      +);

      +
      Parameters
      +
      +
      n
      +
      Name
      +
      s
      +
      Spec string
      +
      t
      +
      Human-readable text
      +
      v
      +
      Value
      +
      loc
      +
      Localize this attribute?
      +
      +

      ~ppdcAttr

      +

      +

      +void ~ppdcAttr (void);

      +

      ppdcCatalog

      +

      // Translation catalog

      +

      class ppdcCatalog : public ppdcShared {
      +  public:
      +    ppdcString *filename;
      +    ppdcString *locale;
      +    ppdcArray *messages;
      +};

      +

      Members

      +
      +
      filename
      +
      Name of translation file
      +
      locale
      +
      Name of locale
      +
      messages
      +
      Array of translation messages
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    void add_message(const char *id,
      +    const char *string = NULL
      +);

      +
      Parameters
      +
      +
      id
      +
      string
      +
      +

      add_message

      +

      +

      +void add_message (
      +    const char *id,
      +    const char *string
      +);

      +
      Parameters
      +
      +
      id
      +
      Message ID to add
      +
      string
      +
      Translation string
      +
      +

      find_message

      +

      +

      +const char *find_message (
      +    const char *id
      +);

      +
      Parameters
      +
      +
      id
      +
      Message ID
      +
      +
      Return Value
      +

      Message text

      +

      load_messages

      +

      +

      +int load_messages (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      Message catalog file
      +
      +
      Return Value
      +

      0 on success, -1 on failure

      +

      ppdcCatalog

      +

      +

      +void ppdcCatalog (
      +    const char *l,
      +    const char *f
      +);

      +
      Parameters
      +
      +
      l
      +
      Locale
      +
      f
      +
      Message catalog file
      +
      +

      save_messages

      +

      +

      +int save_messages (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      File to save to
      +
      +
      Return Value
      +

      0 on success, -1 on error

      +

      ~ppdcCatalog

      +

      +

      +void ~ppdcCatalog (void);

      +

      ppdcChoice

      +

      // Option Choice

      +

      class ppdcChoice : public ppdcShared {
      +  public:
      +    ppdcString *name, *text, *code;
      +};

      +

      Members

      +
      +
      code
      +
      PS code of choice
      +
      +

      ppdcChoice

      +

      +

      +void ppdcChoice (
      +    const char *n,
      +    const char *t,
      +    const char *c
      +);

      +
      Parameters
      +
      +
      n
      +
      Name of choice
      +
      t
      +
      Text of choice
      +
      c
      +
      Code of choice
      +
      +

      ~ppdcChoice

      +

      +

      +void ~ppdcChoice (void);

      +

      ppdcConstraint

      +

      // Constraint

      +

      class ppdcConstraint : public ppdcShared {
      +  public:
      +    ppdcString *option1, *choice1, *option2, *choice2;
      +};

      +

      Members

      +
      +
      choice2
      +
      Second choice
      +
      +

      ppdcConstraint

      +

      +

      +void ppdcConstraint (
      +    const char *o1,
      +    const char *c1,
      +    const char *o2,
      +    const char *c2
      +);

      +
      Parameters
      +
      +
      o1
      +
      First option
      +
      c1
      +
      First choice
      +
      o2
      +
      Second option
      +
      c2
      +
      Second choice
      +
      +

      ~ppdcConstraint

      +

      +

      +void ~ppdcConstraint (void);

      +

      ppdcDriver

      +

      // Printer Driver Data

      +

      class ppdcDriver : public ppdcShared {
      +  public:
      +    ppdcArray *copyright;
      +    ppdcString *custom_size_code;
      +    ppdcString *default_font, *default_size;
      +    float left_margin, bottom_margin, right_margin, top_margin, max_width, max_length, min_width, min_length;
      +    ppdcArray *attrs, *constraints, *filters, *fonts, *groups, *profiles, *sizes;
      +    int model_number, manual_copies, color_device, throughput;
      +    ppdcDrvType type;
      +    int variable_paper_size;
      +    ppdcString *manufacturer, *model_name, *file_name, *pc_file_name, *version;
      +};

      +

      Members

      +
      +
      copyright
      +
      Copyright strings
      +
      custom_size_code
      +
      Custom page size code, if any
      +
      default_size
      +
      Default size option
      +
      min_length
      +
      Minimum length (points)
      +
      sizes
      +
      Fixed sizes
      +
      throughput
      +
      Throughput in pages per minute
      +
      type
      +
      Driver type
      +
      variable_paper_size
      +
      Support variable sizes?
      +
      version
      +
      Version number
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    void add_attr(ppdcAttr *a
      +);

      +
      Parameters
      +
      +
      a
      +
      +

      add_constraint

      +

      +

      +void add_constraint (
      +    ppdcConstraint *c
      +);

      +
      Parameters
      +
      +
      c
      +
      +

      add_copyright

      +

      +

      +void add_copyright (
      +    const char *c
      +);

      +
      Parameters
      +
      +
      c
      +
      +

      add_filter

      +

      +

      +void add_filter (
      +    ppdcFilter *f
      +);

      +
      Parameters
      +
      +
      f
      +
      +

      add_font

      +

      +

      +void add_font (
      +    ppdcFont *f
      +);

      +
      Parameters
      +
      +
      f
      +
      +

      add_group

      +

      +

      +void add_group (
      +    ppdcGroup *g
      +);

      +
      Parameters
      +
      +
      g
      +
      +

      add_profile

      +

      +

      +void add_profile (
      +    ppdcProfile *p
      +);

      +
      Parameters
      +
      +
      p
      +
      +

      add_size

      +

      +

      +void add_size (
      +    ppdcMediaSize *m
      +);

      +
      Parameters
      +
      +
      m
      +
      +

      find_attr

      +

      +

      +ppdcAttr *find_attr (
      +    const char *k,
      +    const char *s
      +);

      +
      Parameters
      +
      +
      k
      +
      Keyword string
      +
      s
      +
      Spec string
      +
      +
      Return Value
      +

      Attribute or NULL

      +

      find_group

      +

      +

      +ppdcGroup *find_group (
      +    const char *n
      +);

      +
      Parameters
      +
      +
      n
      +
      Group name
      +
      +
      Return Value
      +

      Matching group or NULL

      +

      find_option

      +

      +

      +ppdcOption *find_option (
      +    const char *n
      +);

      +
      Parameters
      +
      +
      n
      +
      Option name
      +
      +
      Return Value
      +

      Matching option or NULL

      +

      find_option_group

      +

      +

      +ppdcOption *find_option_group (
      +    const char *n,
      +    ppdcGroup **mg
      +);

      +
      Parameters
      +
      +
      n
      +
      Option name
      +
      mg
      +
      Matching group or NULL
      +
      +
      Return Value
      +

      Matching option or NULL

      +

      ppdcDriver

      +

      +

      +void ppdcDriver (
      +    ppdcDriver *d
      +);

      +
      Parameters
      +
      +
      d
      +
      Printer driver template
      +
      +

      set_custom_size_code

      +

      +

      +void set_custom_size_code (
      +    const char *c
      +);

      +
      Parameters
      +
      +
      c
      +
      CustomPageSize code
      +
      +

      set_default_font

      +

      +

      +void set_default_font (
      +    ppdcFont *f
      +);

      +
      Parameters
      +
      +
      f
      +
      Font
      +
      +

      set_default_size

      +

      +

      +void set_default_size (
      +    ppdcMediaSize *m
      +);

      +
      Parameters
      +
      +
      m
      +
      Media size
      +
      +

      set_file_name

      +

      +

      +void set_file_name (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      Filename
      +
      +

      set_manufacturer

      +

      +

      +void set_manufacturer (
      +    const char *m
      +);

      +
      Parameters
      +
      +
      m
      +
      Model name
      +
      +

      set_model_name

      +

      +

      +void set_model_name (
      +    const char *m
      +);

      +
      Parameters
      +
      +
      m
      +
      Model name
      +
      +

      set_pc_file_name

      +

      +

      +void set_pc_file_name (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      Filename
      +
      +

      set_version

      +

      +

      +void set_version (
      +    const char *v
      +);

      +
      Parameters
      +
      +
      v
      +
      Version
      +
      +

      write_ppd_file

      +

      +

      +int write_ppd_file (
      +    cups_file_t *fp,
      +    ppdcCatalog *catalog,
      +    ppdcArray *locales,
      +    ppdcSource *src,
      +    ppdcLineEnding le
      +);

      +
      Parameters
      +
      +
      fp
      +
      PPD file
      +
      catalog
      +
      Message catalog
      +
      locales
      +
      Additional languages to add
      +
      src
      +
      Driver source
      +
      le
      +
      Line endings to use
      +
      +
      Return Value
      +

      0 on success, -1 on failure

      +

      ~ppdcDriver

      +

      +

      +void ~ppdcDriver (void);

      +

      ppdcFile

      +

      // File

      +

      class ppdcFile {
      +  public:
      +    const char *filename;
      +    cups_file_t *fp;
      +    int line;
      +};

      +

      Members

      +
      +
      filename
      +
      Filename
      +
      fp
      +
      File pointer
      +
      line
      +
      Line in file
      +
      +

      get

      +

      Get a character from a file.

      +

      +int get (void);

      +
      Return Value
      +

      +

      peek

      +

      +

      +int peek (void);

      +
      Return Value
      +

      Next character in file

      +

      ppdcFile

      +

      +

      +void ppdcFile (
      +    const char *f,
      +    cups_file_t *ffp
      +);

      +
      Parameters
      +
      +
      f
      +
      File to open
      +
      ffp
      +
      File pointer to use
      +
      +

      ~ppdcFile

      +

      +

      +void ~ppdcFile (void);

      +

      ppdcFilter

      +

      // Filter Program

      +

      class ppdcFilter : public ppdcShared {
      +  public:
      +    int cost;
      +    ppdcString *mime_type, *program;
      +};

      +

      Members

      +
      +
      cost
      +
      Relative cost of filter
      +
      program
      +
      Filter program
      +
      +

      ppdcFilter

      +

      +

      +void ppdcFilter (
      +    const char *t,
      +    const char *p,
      +    int c
      +);

      +
      Parameters
      +
      +
      t
      +
      MIME type
      +
      p
      +
      Filter program
      +
      c
      +
      Relative cost
      +
      +

      ~ppdcFilter

      +

      +

      +void ~ppdcFilter (void);

      +

      ppdcFont

      +

      // Shared Font

      +

      class ppdcFont : public ppdcShared {
      +  public:
      +    ppdcString *name, *encoding, *version, *charset;
      +    ppdcFontStatus status;
      +};

      +

      Members

      +
      +
      charset
      +
      Font charset
      +
      status
      +
      Font status (ROM or Disk)
      +
      +

      ppdcFont

      +

      +

      +void ppdcFont (
      +    const char *n,
      +    const char *e,
      +    const char *v,
      +    const char *c,
      +    ppdcFontStatus s
      +);

      +
      Parameters
      +
      +
      n
      +
      Name of font
      +
      e
      +
      Font encoding
      +
      v
      +
      Font version
      +
      c
      +
      Font charset
      +
      s
      +
      Font status
      +
      +

      ~ppdcFont

      +

      +

      +void ~ppdcFont (void);

      +

      ppdcGroup

      +

      // Group of Options

      +

      class ppdcGroup : public ppdcShared {
      +  public:
      +    ppdcArray *options;
      +    ppdcString *name, *text;
      +};

      +

      Members

      +
      +
      options
      +
      Options
      +
      text
      +
      Human-readable text of option
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    void add_option(ppdcOption *o
      +);

      +
      Parameters
      +
      +
      o
      +
      +

      find_option

      +

      Find an option in a group.

      +

      +ppdcOption *find_option (
      +    const char *n
      +);

      +
      Parameters
      +
      +
      n
      +
      Name of option
      +
      +
      Return Value
      +

      +

      ppdcGroup

      +

      +

      +void ppdcGroup (
      +    ppdcGroup *g
      +);

      +
      Parameters
      +
      +
      g
      +
      Group template
      +
      +

      ~ppdcGroup

      +

      +

      +void ~ppdcGroup (void);

      +

      ppdcInteger

      +

      // Shared integer

      +

      class ppdcInteger : public ppdcShared {
      +  public:
      +    int *value;
      +};

      +

      Members

      +
      +
      value
      +
      Integer value
      +
      +

      ppdcInteger

      +

      Integer value

      +

      +void ppdcInteger (
      +    int *v
      +);

      +
      Parameters
      +
      +
      v
      +
      +

      ppdcMediaSize

      +

      // Media Size

      +

      class ppdcMediaSize : public ppdcShared {
      +  public:
      +    ppdcString *size_code, *region_code;
      +    ppdcString *name, *text;
      +    float width, length, left, bottom, right, top;
      +};

      +

      Members

      +
      +
      region_code
      +
      PageRegion code, if any
      +
      text
      +
      Human-readable text
      +
      top
      +
      Top limit in points
      +
      +

      ppdcMediaSize

      +

      +

      +void ppdcMediaSize (
      +    const char *n,
      +    const char *t,
      +    float w,
      +    float l,
      +    float lm,
      +    float bm,
      +    float rm,
      +    float tm,
      +    const char *sc,
      +    const char *rc
      +);

      +
      Parameters
      +
      +
      n
      +
      Name of media size
      +
      t
      +
      Text of media size
      +
      w
      +
      Width in points
      +
      l
      +
      Length in points
      +
      lm
      +
      Left margin in points
      +
      bm
      +
      Bottom margin in points
      +
      rm
      +
      Right margin in points
      +
      tm
      +
      Top margin in points
      +
      sc
      +
      PageSize code, if any
      +
      rc
      +
      PageRegion code, if any
      +
      +

      ~ppdcMediaSize

      +

      +

      +void ~ppdcMediaSize (void);

      +

      ppdcMessage

      +

      // Translation message

      +

      class ppdcMessage : public ppdcShared {
      +  public:
      +    ppdcString *id, *string;
      +};

      +

      Members

      +
      +
      string
      +
      Translation string
      +
      +

      ppdcMessage

      +

      +

      +void ppdcMessage (
      +    const char *i,
      +    const char *s
      +);

      +
      Parameters
      +
      +
      i
      +
      ID
      +
      s
      +
      Text
      +
      +

      ~ppdcMessage

      +

      +

      +void ~ppdcMessage (void);

      +

      ppdcOption

      +

      // Option

      +

      class ppdcOption : public ppdcShared {
      +  public:
      +    ppdcArray *choices;
      +    ppdcString *defchoice;
      +    float order;
      +    ppdcOptSection section;
      +    ppdcString *name, *text;
      +    ppdcOptType type;
      +};

      +

      Members

      +
      +
      choices
      +
      Choices
      +
      defchoice
      +
      Default choice
      +
      order
      +
      Order number
      +
      section
      +
      Section for option code
      +
      text
      +
      Human-readable text of option
      +
      type
      +
      Type of option
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    void add_choice(ppdcChoice *c
      +);

      +
      Parameters
      +
      +
      c
      +
      +

      find_choice

      +

      +

      +ppdcChoice *find_choice (
      +    const char *n
      +);

      +
      Parameters
      +
      +
      n
      +
      Name of choice
      +
      +
      Return Value
      +

      Choice or NULL

      +

      ppdcOption

      +

      +

      +void ppdcOption (
      +    ppdcOption *o
      +);

      +
      Parameters
      +
      +
      o
      +
      Template option
      +
      +

      set_defchoice

      +

      +

      +void set_defchoice (
      +    ppdcChoice *c
      +);

      +
      Parameters
      +
      +
      c
      +
      Choice
      +
      +

      ~ppdcOption

      +

      +

      +void ~ppdcOption (void);

      +

      ppdcProfile

      +

      // Color Profile

      +

      class ppdcProfile : public ppdcShared {
      +  public:
      +    ppdcString *resolution, *media_type;
      +    float density, gamma, profile[9];
      +};

      +

      Members

      +
      +
      media_type
      +
      Media type name
      +
      profile[9]
      +
      Color profile matrix
      +
      +

      ppdcProfile

      +

      +

      +void ppdcProfile (
      +    const char *r,
      +    const char *m,
      +    float d,
      +    float g,
      +    const float *p
      +);

      +
      Parameters
      +
      +
      r
      +
      Resolution name
      +
      m
      +
      Media type name
      +
      d
      +
      Density
      +
      g
      +
      Gamma
      +
      p
      +
      3x3 transform matrix
      +
      +

      ~ppdcProfile

      +

      +

      +void ~ppdcProfile (void);

      +

      ppdcShared

      +

      // Shared Data Value

      +

      class ppdcShared {
      +  private:
      +    int use;
      +};

      +

      Members

      +
      +
      use
      +
      Use count (delete when 0)
      +
      +

      class_name

      +

      +

      +virtual const char *class_name (void);

      +
      Return Value
      +

      +

      ppdcShared

      +

      +

      +void ppdcShared (void);

      +

      release

      +

      +

      +void release (void);

      +

      retain

      +

      +

      +void retain (void);

      +

      ~ppdcShared

      +

      +

      +void ~ppdcShared (void);

      +

      ppdcSource

      +

      // Source File

      +

      class ppdcSource : public ppdcShared {
      +  public:
      +    int cond_state, *cond_current, cond_stack[101];
      +    static const char *driver_types[];
      +    ppdcString *filename;
      +    static ppdcArray *includes;
      +    ppdcArray *base_fonts, *drivers, *po_files, *sizes, *vars;
      +};

      +

      Members

      +
      +
      cond_stack[101]
      +
      #if state stack
      +
      driver_types[]
      +
      Driver types
      +
      filename
      +
      Filename
      +
      includes
      +
      Include directories
      +
      vars
      +
      Defined variables
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    static void add_include(const char *d
      +);

      +
      Parameters
      +
      +
      d
      +
      +

      add_include

      +

      +

      +void add_include (
      +    const char *d
      +);

      +
      Parameters
      +
      +
      d
      +
      Include directory
      +
      +

      find_driver

      +

      +

      +ppdcDriver *find_driver (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      Driver file name
      +
      +
      Return Value
      +

      Driver

      +

      find_include

      +

      +

      +char *find_include (
      +    const char *f,
      +    const char *base,
      +    char *n,
      +    int nlen
      +);

      +
      Parameters
      +
      +
      f
      +
      Include filename
      +
      base
      +
      Current directory
      +
      n
      +
      Path buffer
      +
      nlen
      +
      Path buffer length
      +
      +
      Return Value
      +

      Found path or NULL

      +

      find_po

      +

      +

      +ppdcCatalog *find_po (
      +    const char *l
      +);

      +
      Parameters
      +
      +
      l
      +
      Locale name
      +
      +
      Return Value
      +

      Message catalog or NULL

      +

      find_size

      +

      +

      +ppdcMediaSize *find_size (
      +    const char *s
      +);

      +
      Parameters
      +
      +
      s
      +
      Size name
      +
      +
      Return Value
      +

      Size

      +

      find_variable

      +

      +

      +ppdcVariable *find_variable (
      +    const char *n
      +);

      +
      Parameters
      +
      +
      n
      +
      Variable name
      +
      +
      Return Value
      +

      Variable

      +

      get_attr

      +

      +

      +ppdcAttr *get_attr (
      +    ppdcFile *fp,
      +    bool loc
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      loc
      +
      Localize this attribute?
      +
      +
      Return Value
      +

      Attribute

      +

      get_boolean

      +

      +

      +int get_boolean (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Boolean value

      +

      get_choice

      +

      +

      +ppdcChoice *get_choice (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Choice data

      +

      get_color_model

      +

      +

      +ppdcChoice *get_color_model (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Choice data

      +

      get_color_order

      +

      +

      +int get_color_order (
      +    const char *co
      +);

      +
      Parameters
      +
      +
      co
      +
      Color order string
      +
      +
      Return Value
      +

      Color order value

      +

      get_color_profile

      +

      +

      +ppdcProfile *get_color_profile (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Color profile

      +

      get_color_space

      +

      +

      +int get_color_space (
      +    const char *cs
      +);

      +
      Parameters
      +
      +
      cs
      +
      Colorspace string
      +
      +
      Return Value
      +

      Colorspace value

      +

      get_constraint

      +

      +

      +ppdcConstraint *get_constraint (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Constraint

      +

      get_custom_size

      +

      +

      +ppdcMediaSize *get_custom_size (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Media size

      +

      get_duplex

      +

      +

      +void get_duplex (
      +    ppdcFile *fp,
      +    ppdcDriver *d
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read from
      +
      d
      +
      Current driver
      +
      +

      get_filter

      +

      +

      +ppdcFilter *get_filter (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Filter

      +

      get_float

      +

      +

      +float get_float (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Number

      +

      get_font

      +

      +

      +ppdcFont *get_font (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Font data

      +

      get_generic

      +

      +

      +ppdcChoice *get_generic (
      +    ppdcFile *fp,
      +    const char *keyword,
      +    const char *tattr,
      +    const char *nattr
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      keyword
      +
      Keyword name
      +
      tattr
      +
      Text attribute
      +
      nattr
      +
      Numeric attribute
      +
      +
      Return Value
      +

      Choice data

      +

      get_group

      +

      +

      +ppdcGroup *get_group (
      +    ppdcFile *fp,
      +    ppdcDriver *d
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      d
      +
      Printer driver
      +
      +
      Return Value
      +

      Group

      +

      get_installable

      +

      +

      +ppdcOption *get_installable (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Option

      +

      get_integer

      +

      +

      +int get_integer (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Integer value

      +

      get_measurement

      +

      +

      +float get_measurement (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Measurement value in points

      +

      get_option

      +

      +

      +ppdcOption *get_option (
      +    ppdcFile *fp,
      +    ppdcDriver *d,
      +    ppdcGroup *g
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      d
      +
      Printer driver
      +
      g
      +
      Current group
      +
      +
      Return Value
      +

      Option

      +

      get_po

      +

      +

      +ppdcCatalog *get_po (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Message catalog

      +

      get_resolution

      +

      +

      +ppdcChoice *get_resolution (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Choice data

      +

      get_simple_profile

      +

      +

      +ppdcProfile *get_simple_profile (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Color profile

      +

      get_size

      +

      +

      +ppdcMediaSize *get_size (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Media size

      +

      get_token

      +

      +

      +char *get_token (
      +    ppdcFile *fp,
      +    char *buffer,
      +    int buflen
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      buffer
      +
      Buffer
      +
      buflen
      +
      Length of buffer
      +
      +
      Return Value
      +

      Token string or NULL

      +

      get_variable

      +

      +

      +ppdcVariable *get_variable (
      +    ppdcFile *fp
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      +
      Return Value
      +

      Variable

      +

      import_ppd

      +

      +

      +int import_ppd (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      Filename
      +
      +
      Return Value
      +

      1 on success, 0 on failure

      +

      ppdcSource

      +

      +

      +void ppdcSource (
      +    const char *f,
      +    cups_file_t *ffp
      +);

      +
      Parameters
      +
      +
      f
      +
      File to read
      +
      ffp
      +
      File pointer to use
      +
      +

      quotef

      +

      +

      +int quotef (
      +    cups_file_t *fp,
      +    const char *format,
      +    ...
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to write to
      +
      format
      +
      Printf-style format string
      +
      ...
      +
      Additional args as needed
      +
      +
      Return Value
      +

      Number bytes on success, -1 on failure

      +

      read_file

      +

      +

      +void read_file (
      +    const char *f,
      +    cups_file_t *ffp
      +);

      +
      Parameters
      +
      +
      f
      +
      File to read
      +
      ffp
      +
      File pointer to use
      +
      +

      scan_file

      +

      +

      +void scan_file (
      +    ppdcFile *fp,
      +    ppdcDriver *td,
      +    bool inc
      +);

      +
      Parameters
      +
      +
      fp
      +
      File to read
      +
      td
      +
      Driver template
      +
      inc
      +
      Including?
      +
      +

      set_variable

      +

      +

      +ppdcVariable *set_variable (
      +    const char *name,
      +    const char *value
      +);

      +
      Parameters
      +
      +
      name
      +
      Name
      +
      value
      +
      Value
      +
      +
      Return Value
      +

      Variable

      +

      write_file

      +

      +

      +int write_file (
      +    const char *f
      +);

      +
      Parameters
      +
      +
      f
      +
      File to write
      +
      +
      Return Value
      +

      0 on success, -1 on error

      +

      ~ppdcSource

      +

      +

      +void ~ppdcSource (void);

      +

      ppdcString

      +

      // Shared String

      +

      class ppdcString : public ppdcShared {
      +  public:
      +    char *value;
      +};

      +

      Members

      +
      +
      value
      +
      String value
      +
      +

      ppdcString

      +

      +

      +void ppdcString (
      +    const char *v
      +);

      +
      Parameters
      +
      +
      v
      +
      String
      +
      +

      ~ppdcString

      +

      +

      +void ~ppdcString (void);

      +

      ppdcVariable

      +

      // Variable Definition

      +

      class ppdcVariable : public ppdcShared {
      +  public:
      +    ppdcString *name, *value;
      +};

      +

      Members

      +
      +
      value
      +
      Value of variable
      +
      +

      PPDC_NAME

      +

      +

      +void PPDC_NAME (
      +    void set_value(const char *v
      +);

      +
      Parameters
      +
      +
      v
      +
      +

      ppdcVariable

      +

      +

      +void ppdcVariable (
      +    const char *n,
      +    const char *v
      +);

      +
      Parameters
      +
      +
      n
      +
      Name of variable
      +
      v
      +
      Value of variable
      +
      +

      set_value

      +

      +

      +void set_value (
      +    const char *v
      +);

      +
      Parameters
      +
      +
      v
      +
      +

      ~ppdcVariable

      +

      +

      +void ~ppdcVariable (void);

      +

      Data Types

      +

      ppdc_cs_t

      +

      +

      +typedef enum ppdc_cs_t; +

      +

      Variables

      +

      ppdcSource

      +

      // Printer Driver Data

      +

      class ppdcSource;

      +

      Constants

      +

      ppdcCondFlags

      +

      // Condition flags

      +

      Constants

      +
      +
      PPDC_COND_NORMAL
      +
      Normal state
      +
      PPDC_COND_SATISFIED
      +
      At least one condition satisfied
      +
      PPDC_COND_SKIP
      +
      Skip state
      +
      +

      ppdcDrvType

      +

      // Driver type

      +

      Constants

      +
      +
      PPDC_DRIVER_CUSTOM
      +
      Custom driver
      +
      PPDC_DRIVER_EPSON
      +
      rastertoepson driver
      +
      PPDC_DRIVER_ESCP
      +
      rastertoescpx driver
      +
      PPDC_DRIVER_HP
      +
      rastertohp driver
      +
      PPDC_DRIVER_LABEL
      +
      rastertolabel/rastertodymo driver
      +
      PPDC_DRIVER_MAX
      +
      Number of driver types defined
      +
      PPDC_DRIVER_PCL
      +
      rastertopclx driver
      +
      PPDC_DRIVER_PS
      +
      PostScript driver
      +
      +

      ppdcFontStatus

      +

      // Load status of font

      +

      Constants

      +
      +
      PPDC_FONT_DISK
      +
      Font is on disk
      +
      PPDC_FONT_ROM
      +
      Font is in ROM
      +
      +

      ppdcLineEnding

      +

      // Line endings

      +

      Constants

      +
      +
      PPDC_CRLF
      +
      CR + LF
      +
      PPDC_CRONLY
      +
      CR only
      +
      PPDC_LFONLY
      +
      LF only
      +
      +

      ppdcOptSection

      +

      // Option section

      +

      Constants

      +
      +
      PPDC_SECTION_ANY
      +
      AnySetup
      +
      PPDC_SECTION_DOCUMENT
      +
      DocumentSetup
      +
      PPDC_SECTION_EXIT
      +
      ExitServer
      +
      PPDC_SECTION_JCL
      +
      JCLSetup
      +
      PPDC_SECTION_PAGE
      +
      PageSetup
      +
      PPDC_SECTION_PROLOG
      +
      Prolog
      +
      +

      ppdcOptType

      +

      // Option type

      +

      Constants

      +
      +
      PPDC_BOOLEAN
      +
      True/false option
      +
      PPDC_PICKMANY
      +
      Multiple choices from list
      +
      PPDC_PICKONE
      +
      Single choice from list
      +
      +
+ + diff --git a/doc/help/api-raster.html b/doc/help/api-raster.html new file mode 100644 index 0000000000..b592be87a1 --- /dev/null +++ b/doc/help/api-raster.html @@ -0,0 +1,1372 @@ + + + + +Raster API + + + + + +
+ + +

Raster API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/raster.h
Library-lcupsimage
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ Programming: PPD API
+ References: CUPS PPD Specification
+

Contents

+
    +
      +
    • Overview
    • +
    • Functions by Task
    • +
    • Functions
    • +
    • Data Types
    • +
    • Structures
    • +
    • Constants
    • + + +

      Overview

      + +

      The CUPS raster API provides a standard interface for reading and writing +CUPS raster streams which are used for printing to raster printers. Because the +raster format is updated from time to time, it is important to use this API to +avoid incompatibilities with newer versions of CUPS.

      + +

      Two kinds of CUPS filters use the CUPS raster API - raster image processor +(RIP) filters such as pstoraster and cgpdftoraster +(Mac OS X) that produce CUPS raster files and printer driver filters that +convert CUPS raster files into a format usable by the printer. Printer +driver filters are by far the most common.

      + +

      CUPS raster files (application/vnd.cups-raster) consists of +a stream of raster page descriptions produced by one of the RIP filters such as +pstoraster, imagetoraster, or +cgpdftoraster. CUPS raster files are referred to using the +cups_raster_t type and are +opened using the cupsRasterOpen +function. For example, to read raster data from the standard input, open +file descriptor 0:

      + +
      +#include <cups/raster.h>>
      +
      +cups_raster_t *ras = cupsRasterOpen(0, CUPS_RASTER_READ);
      +
      + +

      Each page of data begins with a page dictionary structure called +cups_page_header2_t. This +structure contains the colorspace, bits per color, media size, media type, +hardware resolution, and so forth used for the page.

      + +
      Note: + +

      Do not confuse the colorspace in the page header with the PPD + ColorModel keyword. ColorModel refers to the general type of + color used for a device (Gray, RGB, CMYK, DeviceN) and is often used to + select a particular colorspace for the page header along with the associate + color profile. The page header colorspace (cupsColorSpace) describes + both the type and organization of the color data, for example KCMY (black + first) instead of CMYK and RGBA (RGB + alpha) instead of RGB.

      + +
      + +

      You read the page header using the +cupsRasterReadHeader2 +function:

      + +
      +#include <cups/raster.h>>
      +
      +cups_raster_t *ras = cupsRasterOpen(0, CUPS_RASTER_READ);
      +cups_page_header2_t header;
      +
      +while (cupsRasterReadHeader2(ras, &header))
      +{
      +  /* setup this page */
      +
      +  /* read raster data */
      +
      +  /* finish this page */
      +}
      +
      + +

      After the page dictionary comes the page data which is a full-resolution, +possibly compressed bitmap representing the page in the printer's output +colorspace. You read uncompressed raster data using the +cupsRasterReadPixels +function. A for loop is normally used to read the page one line +at a time:

      + +
      +#include <cups/raster.h>>
      +
      +cups_raster_t *ras = cupsRasterOpen(0, CUPS_RASTER_READ);
      +cups_page_header2_t header;
      +int page = 0;
      +int y;
      +char *buffer;
      +
      +while (cupsRasterReadHeader2(ras, &header))
      +{
      +  /* setup this page */
      +  page ++;
      +  fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
      +
      +  /* allocate memory for 1 line */
      +  buffer = malloc(header.cupsBytesPerLine);
      +
      +  /* read raster data */
      +  for (y = 0; y < header.cupsHeight; y ++)
      +  {
      +    if (cupsRasterReadPixels(ras, buffer, header.cupsBytesPerLine) == 0)
      +      break;
      +
      +    /* write raster data to printer on stdout */
      +  }
      +
      +  /* finish this page */
      +}
      +
      + +

      When you are done reading the raster data, call the +cupsRasterClose function to free +the memory used to read the raster file:

      + +
      +cups_raster_t *ras;
      +
      +cupsRasterClose(ras);
      +
      + + +

      Functions by Task

      + +

      Opening and Closing Raster Streams

      + + + +

      Reading Raster Streams

      + + + +

      Writing Raster Streams

      + + +

      Functions

      +

      cupsRasterClose

      +

      Close a raster stream.

      +

      +void cupsRasterClose (
      +    cups_raster_t *r
      +);

      +

      Parameters

      +
      +
      r
      +
      Stream to close
      +
      +

      Discussion

      +

      The file descriptor associated with the raster stream must be closed +separately as needed.

      +

       CUPS 1.2/Mac OS X 10.5 cupsRasterInterpretPPD

      +

      Interpret PPD commands to create a page header.

      +

      +int cupsRasterInterpretPPD (
      +    cups_page_header2_t *h,
      +    ppd_file_t *ppd,
      +    int num_options,
      +    cups_option_t *options,
      +    cups_interpret_cb_t func
      +);

      +

      Parameters

      +
      +
      h
      +
      Page header to create
      +
      ppd
      +
      PPD file
      +
      num_options
      +
      Number of options
      +
      options
      +
      Options
      +
      func
      +
      Optional page header callback (NULL for none)
      +
      +

      Return Value

      +

      0 on success, -1 on failure

      +

      Discussion

      +

      This function is used by raster image processing (RIP) filters like +cgpdftoraster and imagetoraster when writing CUPS raster data for a page. +It is not used by raster printer driver filters which only read CUPS +raster data.
      +
      + +cupsRasterInterpretPPD does not mark the options in the PPD using +the "num_options" and "options" arguments. Instead, mark the options with +cupsMarkOptions and ppdMarkOption prior to calling it - +this allows for per-page options without manipulating the options array.
      +
      +The "func" argument specifies an optional callback function that is +called prior to the computation of the final raster data. The function +can make changes to the cups_page_header2_t data as needed to use a +supported raster format and then returns 0 on success and -1 if the +requested attributes cannot be supported.
      +
      + +cupsRasterInterpretPPD supports a subset of the PostScript language. +Currently only the [, ], <<, >>, {, +}, cleartomark, copy, dup, index, +pop, roll, setpagedevice, and stopped operators +are supported. + +

      +

      cupsRasterOpen

      +

      Open a raster stream using a file descriptor.

      +

      +cups_raster_t *cupsRasterOpen (
      +    int fd,
      +    cups_mode_t mode
      +);

      +

      Parameters

      +
      +
      fd
      +
      File descriptor
      +
      mode
      +
      Mode - CUPS_RASTER_READ, +CUPS_RASTER_WRITE, or +CUPS_RASTER_WRITE_COMPRESSED
      +
      +

      Return Value

      +

      New stream

      +

      Discussion

      +

      This function associates a raster stream with the given file descriptor. +For most printer driver filters, "fd" will be 0 (stdin). For most raster +image processor (RIP) filters that generate raster data, "fd" will be 1 +(stdout).
      +
      +When writing raster data, the CUPS_RASTER_WRITE or +CUPS_RASTER_WRITE_COMPRESS mode can be used - compressed output is +generally 25-50% smaller but adds a 100-300% execution time overhead.

      +

       DEPRECATED cupsRasterReadHeader

      +

      Read a raster page header and store it in a +version 1 page header structure.

      +

      +unsigned cupsRasterReadHeader (
      +    cups_raster_t *r,
      +    cups_page_header_t *h
      +);

      +

      Parameters

      +
      +
      r
      +
      Raster stream
      +
      h
      +
      Pointer to header data
      +
      +

      Return Value

      +

      1 on success, 0 on failure/end-of-file

      +

      Discussion

      +

      This function is deprecated. Use cupsRasterReadHeader2 instead.
      +
      +Version 1 page headers were used in CUPS 1.0 and 1.1 and contain a subset +of the version 2 page header data. This function handles reading version 2 +page headers and copying only the version 1 data into the provided buffer. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsRasterReadHeader2

      +

      Read a raster page header and store it in a +version 2 page header structure.

      +

      +unsigned cupsRasterReadHeader2 (
      +    cups_raster_t *r,
      +    cups_page_header2_t *h
      +);

      +

      Parameters

      +
      +
      r
      +
      Raster stream
      +
      h
      +
      Pointer to header data
      +
      +

      Return Value

      +

      1 on success, 0 on failure/end-of-file

      +

      cupsRasterReadPixels

      +

      Read raster pixels.

      +

      +unsigned cupsRasterReadPixels (
      +    cups_raster_t *r,
      +    unsigned char *p,
      +    unsigned len
      +);

      +

      Parameters

      +
      +
      r
      +
      Raster stream
      +
      p
      +
      Pointer to pixel buffer
      +
      len
      +
      Number of bytes to read
      +
      +

      Return Value

      +

      Number of bytes read

      +

      Discussion

      +

      For best performance, filters should read one or more whole lines. +The "cupsBytesPerLine" value from the page header can be used to allocate +the line buffer and as the number of bytes to read.

      +

       DEPRECATED cupsRasterWriteHeader

      +

      Write a raster page header from a version 1 page +header structure.

      +

      +unsigned cupsRasterWriteHeader (
      +    cups_raster_t *r,
      +    cups_page_header_t *h
      +);

      +

      Parameters

      +
      +
      r
      +
      Raster stream
      +
      h
      +
      Raster page header
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      This function is deprecated. Use cupsRasterWriteHeader2 instead. + +

      +

       CUPS 1.2/Mac OS X 10.5 cupsRasterWriteHeader2

      +

      Write a raster page header from a version 2 +page header structure.

      +

      +unsigned cupsRasterWriteHeader2 (
      +    cups_raster_t *r,
      +    cups_page_header2_t *h
      +);

      +

      Parameters

      +
      +
      r
      +
      Raster stream
      +
      h
      +
      Raster page header
      +
      +

      Return Value

      +

      1 on success, 0 on failure

      +

      Discussion

      +

      The page header can be initialized using cupsRasterInterpretPPD. + +

      +

      cupsRasterWritePixels

      +

      Write raster pixels.

      +

      +unsigned cupsRasterWritePixels (
      +    cups_raster_t *r,
      +    unsigned char *p,
      +    unsigned len
      +);

      +

      Parameters

      +
      +
      r
      +
      Raster stream
      +
      p
      +
      Bytes to write
      +
      len
      +
      Number of bytes to write
      +
      +

      Return Value

      +

      Number of bytes written

      +

      Discussion

      +

      For best performance, filters should write one or more whole lines. +The "cupsBytesPerLine" value from the page header can be used to allocate +the line buffer and as the number of bytes to write.

      +

      Data Types

      +

      cups_adv_t

      +

      AdvanceMedia attribute values

      +

      +typedef enum cups_adv_e cups_adv_t; +

      +

      cups_bool_t

      +

      Boolean type

      +

      +typedef enum cups_bool_e cups_bool_t; +

      +

      cups_cspace_t

      +

      cupsColorSpace attribute values

      +

      +typedef enum cups_cspace_e cups_cspace_t; +

      +

      cups_cut_t

      +

      CutMedia attribute values

      +

      +typedef enum cups_cut_e cups_cut_t; +

      +

      cups_edge_t

      +

      LeadingEdge attribute values

      +

      +typedef enum cups_edge_e cups_edge_t; +

      +

      cups_interpret_cb_t

      +

      cupsRasterInterpretPPD callback function

      +

      +typedef int (*cups_interpret_cb_t)(cups_page_header2_t *header, int preferred_bits); +

      +

      cups_jog_t

      +

      Jog attribute values

      +

      +typedef enum cups_jog_e cups_jog_t; +

      +

      cups_mode_t

      +

      cupsRasterOpen modes

      +

      +typedef enum cups_mode_e cups_mode_t; +

      +

      cups_order_t

      +

      cupsColorOrder attribute values

      +

      +typedef enum cups_order_e cups_order_t; +

      +

      cups_orient_t

      +

      Orientation attribute values

      +

      +typedef enum cups_orient_e cups_orient_t; +

      +

       CUPS 1.2/Mac OS X 10.5 cups_page_header2_t

      +

      Version 2 page header

      +

      +typedef struct cups_page_header2_s cups_page_header2_t; +

      +

       DEPRECATED cups_page_header_t

      +

      Version 1 page header

      +

      +typedef struct cups_page_header_s cups_page_header_t; +

      +

      cups_raster_t

      +

      Raster stream data

      +

      +typedef struct _cups_raster_s cups_raster_t; +

      +

      Structures

      +

       CUPS 1.2/Mac OS X 10.5 cups_page_header2_s

      +

      Version 2 page header

      +

      struct cups_page_header2_s {
      +    unsigned AdvanceDistance;
      +    cups_adv_t AdvanceMedia;
      +    cups_bool_t Collate;
      +    cups_cut_t CutMedia;
      +    cups_bool_t Duplex;
      +    unsigned HWResolution[2];
      +    unsigned ImagingBoundingBox[4];
      +    cups_bool_t InsertSheet;
      +    cups_jog_t Jog;
      +    cups_edge_t LeadingEdge;
      +    cups_bool_t ManualFeed;
      +    unsigned Margins[2];
      +    char MediaClass[64];
      +    char MediaColor[64];
      +    unsigned MediaPosition;
      +    char MediaType[64];
      +    unsigned MediaWeight;
      +    cups_bool_t MirrorPrint;
      +    cups_bool_t NegativePrint;
      +    unsigned NumCopies;
      +    cups_orient_t Orientation;
      +    cups_bool_t OutputFaceUp;
      +    char OutputType[64];
      +    unsigned PageSize[2];
      +    cups_bool_t Separations;
      +    cups_bool_t TraySwitch;
      +    cups_bool_t Tumble;
      +    unsigned cupsBitsPerColor;
      +    unsigned cupsBitsPerPixel;
      +    float cupsBorderlessScalingFactor;
      +    unsigned cupsBytesPerLine;
      +    cups_order_t cupsColorOrder;
      +    cups_cspace_t cupsColorSpace;
      +    unsigned cupsCompression;
      +    unsigned cupsHeight;
      +    float cupsImagingBBox[4];
      +    unsigned cupsInteger[16];
      +    char cupsMarkerType[64];
      +    unsigned cupsMediaType;
      +    unsigned cupsNumColors;
      +    char cupsPageSizeName[64];
      +    float cupsPageSize[2];
      +    float cupsReal[16];
      +    char cupsRenderingIntent[64];
      +    unsigned cupsRowCount;
      +    unsigned cupsRowFeed;
      +    unsigned cupsRowStep;
      +    char cupsString[16][64];
      +    unsigned cupsWidth;
      +};

      +

      Members

      +
      +
      AdvanceDistance
      +
      AdvanceDistance value in points
      +
      AdvanceMedia
      +
      AdvanceMedia value (cups_adv_t)
      +
      Collate
      +
      Collated copies value
      +
      CutMedia
      +
      CutMedia value (cups_cut_t)
      +
      Duplex
      +
      Duplexed (double-sided) value
      +
      HWResolution[2]
      +
      Resolution in dots-per-inch
      +
      ImagingBoundingBox[4]
      +
      Pixel region that is painted (points, left, bottom, right, top)
      +
      InsertSheet
      +
      InsertSheet value
      +
      Jog
      +
      Jog value (cups_jog_t)
      +
      LeadingEdge
      +
      LeadingEdge value (cups_edge_t)
      +
      ManualFeed
      +
      ManualFeed value
      +
      Margins[2]
      +
      Lower-lefthand margins in points
      +
      MediaClass[64]
      +
      MediaClass string
      +
      MediaColor[64]
      +
      MediaColor string
      +
      MediaPosition
      +
      MediaPosition value
      +
      MediaType[64]
      +
      MediaType string
      +
      MediaWeight
      +
      MediaWeight value in grams/m^2
      +
      MirrorPrint
      +
      MirrorPrint value
      +
      NegativePrint
      +
      NegativePrint value
      +
      NumCopies
      +
      Number of copies to produce
      +
      Orientation
      +
      Orientation value (cups_orient_t)
      +
      OutputFaceUp
      +
      OutputFaceUp value
      +
      OutputType[64]
      +
      OutputType string
      +
      PageSize[2]
      +
      Width and length of page in points
      +
      Separations
      +
      Separations value
      +
      TraySwitch
      +
      TraySwitch value
      +
      Tumble
      +
      Tumble value
      +
      cupsBitsPerColor
      +
      Number of bits for each color
      +
      cupsBitsPerPixel
      +
      Number of bits for each pixel
      +
      cupsBorderlessScalingFactor  CUPS 1.2/Mac OS X 10.5 
      +
      Scaling that was applied to page data
      +
      cupsBytesPerLine
      +
      Number of bytes per line
      +
      cupsColorOrder
      +
      Order of colors
      +
      cupsColorSpace
      +
      True colorspace
      +
      cupsCompression
      +
      Device compression to use
      +
      cupsHeight
      +
      Height of page image in pixels
      +
      cupsImagingBBox[4]  CUPS 1.2/Mac OS X 10.5 
      +
      Floating point ImagingBoundingBox +(scaling factor not applied, left, +bottom, right, top)
      +
      cupsInteger[16]  CUPS 1.2/Mac OS X 10.5 
      +
      User-defined integer values
      +
      cupsMarkerType[64]  CUPS 1.2/Mac OS X 10.5 
      +
      Ink/toner type
      +
      cupsMediaType
      +
      Media type code
      +
      cupsNumColors  CUPS 1.2/Mac OS X 10.5 
      +
      Number of color compoents
      +
      cupsPageSizeName[64]  CUPS 1.2/Mac OS X 10.5 
      +
      PageSize name
      +
      cupsPageSize[2]  CUPS 1.2/Mac OS X 10.5 
      +
      Floating point PageSize (scaling * +factor not applied)
      +
      cupsReal[16]  CUPS 1.2/Mac OS X 10.5 
      +
      User-defined floating-point values
      +
      cupsRenderingIntent[64]  CUPS 1.2/Mac OS X 10.5 
      +
      Color rendering intent
      +
      cupsRowCount
      +
      Rows per band
      +
      cupsRowFeed
      +
      Feed between bands
      +
      cupsRowStep
      +
      Spacing between lines
      +
      cupsString[16][64]  CUPS 1.2/Mac OS X 10.5 
      +
      User-defined string values
      +
      cupsWidth
      +
      Width of page image in pixels
      +
      +

       DEPRECATED cups_page_header_s

      +

      Version 1 page header

      +

      struct cups_page_header_s {
      +    unsigned AdvanceDistance;
      +    cups_adv_t AdvanceMedia;
      +    cups_bool_t Collate;
      +    cups_cut_t CutMedia;
      +    cups_bool_t Duplex;
      +    unsigned HWResolution[2];
      +    unsigned ImagingBoundingBox[4];
      +    cups_bool_t InsertSheet;
      +    cups_jog_t Jog;
      +    cups_edge_t LeadingEdge;
      +    cups_bool_t ManualFeed;
      +    unsigned Margins[2];
      +    char MediaClass[64];
      +    char MediaColor[64];
      +    unsigned MediaPosition;
      +    char MediaType[64];
      +    unsigned MediaWeight;
      +    cups_bool_t MirrorPrint;
      +    cups_bool_t NegativePrint;
      +    unsigned NumCopies;
      +    cups_orient_t Orientation;
      +    cups_bool_t OutputFaceUp;
      +    char OutputType[64];
      +    unsigned PageSize[2];
      +    cups_bool_t Separations;
      +    cups_bool_t TraySwitch;
      +    cups_bool_t Tumble;
      +    unsigned cupsBitsPerColor;
      +    unsigned cupsBitsPerPixel;
      +    unsigned cupsBytesPerLine;
      +    cups_order_t cupsColorOrder;
      +    cups_cspace_t cupsColorSpace;
      +    unsigned cupsCompression;
      +    unsigned cupsHeight;
      +    unsigned cupsMediaType;
      +    unsigned cupsRowCount;
      +    unsigned cupsRowFeed;
      +    unsigned cupsRowStep;
      +    unsigned cupsWidth;
      +};

      +

      Members

      +
      +
      AdvanceDistance
      +
      AdvanceDistance value in points
      +
      AdvanceMedia
      +
      AdvanceMedia value (cups_adv_t)
      +
      Collate
      +
      Collated copies value
      +
      CutMedia
      +
      CutMedia value (cups_cut_t)
      +
      Duplex
      +
      Duplexed (double-sided) value
      +
      HWResolution[2]
      +
      Resolution in dots-per-inch
      +
      ImagingBoundingBox[4]
      +
      Pixel region that is painted (points, left, bottom, right, top)
      +
      InsertSheet
      +
      InsertSheet value
      +
      Jog
      +
      Jog value (cups_jog_t)
      +
      LeadingEdge
      +
      LeadingEdge value (cups_edge_t)
      +
      ManualFeed
      +
      ManualFeed value
      +
      Margins[2]
      +
      Lower-lefthand margins in points
      +
      MediaClass[64]
      +
      MediaClass string
      +
      MediaColor[64]
      +
      MediaColor string
      +
      MediaPosition
      +
      MediaPosition value
      +
      MediaType[64]
      +
      MediaType string
      +
      MediaWeight
      +
      MediaWeight value in grams/m^2
      +
      MirrorPrint
      +
      MirrorPrint value
      +
      NegativePrint
      +
      NegativePrint value
      +
      NumCopies
      +
      Number of copies to produce
      +
      Orientation
      +
      Orientation value (cups_orient_t)
      +
      OutputFaceUp
      +
      OutputFaceUp value
      +
      OutputType[64]
      +
      OutputType string
      +
      PageSize[2]
      +
      Width and length of page in points
      +
      Separations
      +
      Separations value
      +
      TraySwitch
      +
      TraySwitch value
      +
      Tumble
      +
      Tumble value
      +
      cupsBitsPerColor
      +
      Number of bits for each color
      +
      cupsBitsPerPixel
      +
      Number of bits for each pixel
      +
      cupsBytesPerLine
      +
      Number of bytes per line
      +
      cupsColorOrder
      +
      Order of colors
      +
      cupsColorSpace
      +
      True colorspace
      +
      cupsCompression
      +
      Device compression to use
      +
      cupsHeight
      +
      Height of page image in pixels
      +
      cupsMediaType
      +
      Media type code
      +
      cupsRowCount
      +
      Rows per band
      +
      cupsRowFeed
      +
      Feed between bands
      +
      cupsRowStep
      +
      Spacing between lines
      +
      cupsWidth
      +
      Width of page image in pixels
      +
      +

      Constants

      +

      cups_adv_e

      +

      AdvanceMedia attribute values

      +

      Constants

      +
      +
      CUPS_ADVANCE_FILE
      +
      Advance the roll after this file
      +
      CUPS_ADVANCE_JOB
      +
      Advance the roll after this job
      +
      CUPS_ADVANCE_NONE
      +
      Never advance the roll
      +
      CUPS_ADVANCE_PAGE
      +
      Advance the roll after this page
      +
      CUPS_ADVANCE_SET
      +
      Advance the roll after this set
      +
      +

      cups_bool_e

      +

      Boolean type

      +

      Constants

      +
      +
      CUPS_FALSE
      +
      Logical false
      +
      CUPS_TRUE
      +
      Logical true
      +
      +

      cups_cspace_e

      +

      cupsColorSpace attribute values

      +

      Constants

      +
      +
      CUPS_CSPACE_ADOBERGB  CUPS 1.4.5 
      +
      Red, green, blue (Adobe RGB)
      +
      CUPS_CSPACE_CIELab  CUPS 1.1.19/Mac OS X 10.3 
      +
      CIE Lab
      +
      CUPS_CSPACE_CIEXYZ  CUPS 1.1.19/Mac OS X 10.3 
      +
      CIE XYZ
      +
      CUPS_CSPACE_CMY
      +
      Cyan, magenta, yellow (DeviceCMY)
      +
      CUPS_CSPACE_CMYK
      +
      Cyan, magenta, yellow, black (DeviceCMYK)
      +
      CUPS_CSPACE_DEVICE1  CUPS 1.4.5 
      +
      DeviceN, 1 color
      +
      CUPS_CSPACE_DEVICE2  CUPS 1.4.5 
      +
      DeviceN, 2 colors
      +
      CUPS_CSPACE_DEVICE3  CUPS 1.4.5 
      +
      DeviceN, 3 colors
      +
      CUPS_CSPACE_DEVICE4  CUPS 1.4.5 
      +
      DeviceN, 4 colors
      +
      CUPS_CSPACE_DEVICE5  CUPS 1.4.5 
      +
      DeviceN, 5 colors
      +
      CUPS_CSPACE_DEVICE6  CUPS 1.4.5 
      +
      DeviceN, 6 colors
      +
      CUPS_CSPACE_DEVICE7  CUPS 1.4.5 
      +
      DeviceN, 7 colors
      +
      CUPS_CSPACE_DEVICE8  CUPS 1.4.5 
      +
      DeviceN, 8 colors
      +
      CUPS_CSPACE_DEVICE9  CUPS 1.4.5 
      +
      DeviceN, 9 colors
      +
      CUPS_CSPACE_DEVICEA  CUPS 1.4.5 
      +
      DeviceN, 10 colors
      +
      CUPS_CSPACE_DEVICEB  CUPS 1.4.5 
      +
      DeviceN, 11 colors
      +
      CUPS_CSPACE_DEVICEC  CUPS 1.4.5 
      +
      DeviceN, 12 colors
      +
      CUPS_CSPACE_DEVICED  CUPS 1.4.5 
      +
      DeviceN, 13 colors
      +
      CUPS_CSPACE_DEVICEE  CUPS 1.4.5 
      +
      DeviceN, 14 colors
      +
      CUPS_CSPACE_DEVICEF  CUPS 1.4.5 
      +
      DeviceN, 15 colors
      +
      CUPS_CSPACE_GMCK  DEPRECATED 
      +
      Gold, magenta, yellow, black
      +
      CUPS_CSPACE_GMCS  DEPRECATED 
      +
      Gold, magenta, yellow, silver
      +
      CUPS_CSPACE_GOLD  DEPRECATED 
      +
      Gold foil
      +
      CUPS_CSPACE_ICC1  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 1 color
      +
      CUPS_CSPACE_ICC2  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 2 colors
      +
      CUPS_CSPACE_ICC3  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 3 colors
      +
      CUPS_CSPACE_ICC4  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 4 colors
      +
      CUPS_CSPACE_ICC5  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 5 colors
      +
      CUPS_CSPACE_ICC6  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 6 colors
      +
      CUPS_CSPACE_ICC7  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 7 colors
      +
      CUPS_CSPACE_ICC8  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 8 colors
      +
      CUPS_CSPACE_ICC9  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 9 colors
      +
      CUPS_CSPACE_ICCA  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 10 colors
      +
      CUPS_CSPACE_ICCB  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 11 colors
      +
      CUPS_CSPACE_ICCC  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 12 colors
      +
      CUPS_CSPACE_ICCD  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 13 colors
      +
      CUPS_CSPACE_ICCE  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 14 colors
      +
      CUPS_CSPACE_ICCF  CUPS 1.1.19/Mac OS X 10.3 
      +
      ICC-based, 15 colors
      +
      CUPS_CSPACE_K
      +
      Black (DeviceK)
      +
      CUPS_CSPACE_KCMY  DEPRECATED 
      +
      Black, cyan, magenta, yellow
      +
      CUPS_CSPACE_KCMYcm  DEPRECATED 
      +
      Black, cyan, magenta, yellow, light-cyan, light-magenta
      +
      CUPS_CSPACE_RGB
      +
      Red, green, blue (DeviceRGB, sRGB by default)
      +
      CUPS_CSPACE_RGBA
      +
      Red, green, blue, alpha (DeviceRGB, sRGB by default)
      +
      CUPS_CSPACE_RGBW  CUPS 1.2/Mac OS X 10.5 
      +
      Red, green, blue, white (DeviceRGB, sRGB by default)
      +
      CUPS_CSPACE_SILVER  DEPRECATED 
      +
      Silver foil
      +
      CUPS_CSPACE_SRGB  CUPS 1.4.5 
      +
      Red, green, blue (sRGB)
      +
      CUPS_CSPACE_SW  CUPS 1.4.5 
      +
      Luminance (gamma 2.2)
      +
      CUPS_CSPACE_W
      +
      Luminance (DeviceGray, gamma 2.2 by default)
      +
      CUPS_CSPACE_WHITE  DEPRECATED 
      +
      White ink (as black)
      +
      CUPS_CSPACE_YMC  DEPRECATED 
      +
      Yellow, magenta, cyan
      +
      CUPS_CSPACE_YMCK  DEPRECATED 
      +
      Yellow, magenta, cyan, black
      +
      +

      cups_cut_e

      +

      CutMedia attribute values

      +

      Constants

      +
      +
      CUPS_CUT_FILE
      +
      Cut the roll after this file
      +
      CUPS_CUT_JOB
      +
      Cut the roll after this job
      +
      CUPS_CUT_NONE
      +
      Never cut the roll
      +
      CUPS_CUT_PAGE
      +
      Cut the roll after this page
      +
      CUPS_CUT_SET
      +
      Cut the roll after this set
      +
      +

      cups_edge_e

      +

      LeadingEdge attribute values

      +

      Constants

      +
      +
      CUPS_EDGE_BOTTOM
      +
      Leading edge is the bottom of the page
      +
      CUPS_EDGE_LEFT
      +
      Leading edge is the left of the page
      +
      CUPS_EDGE_RIGHT
      +
      Leading edge is the right of the page
      +
      CUPS_EDGE_TOP
      +
      Leading edge is the top of the page
      +
      +

      cups_jog_e

      +

      Jog attribute values

      +

      Constants

      +
      +
      CUPS_JOG_FILE
      +
      Move pages after this file
      +
      CUPS_JOG_JOB
      +
      Move pages after this job
      +
      CUPS_JOG_NONE
      +
      Never move pages
      +
      CUPS_JOG_SET
      +
      Move pages after this set
      +
      +

      cups_mode_e

      +

      cupsRasterOpen modes

      +

      Constants

      +
      +
      CUPS_RASTER_READ
      +
      Open stream for reading
      +
      CUPS_RASTER_WRITE
      +
      Open stream for writing
      +
      CUPS_RASTER_WRITE_COMPRESSED  CUPS 1.3/Mac OS X 10.5 
      +
      Open stream for compressed writing
      +
      +

      cups_order_e

      +

      cupsColorOrder attribute values

      +

      Constants

      +
      +
      CUPS_ORDER_BANDED
      +
      CCC MMM YYY KKK ...
      +
      CUPS_ORDER_CHUNKED
      +
      CMYK CMYK CMYK ...
      +
      CUPS_ORDER_PLANAR
      +
      CCC ... MMM ... YYY ... KKK ...
      +
      +

      cups_orient_e

      +

      Orientation attribute values

      +

      Constants

      +
      +
      CUPS_ORIENT_0
      +
      Don't rotate the page
      +
      CUPS_ORIENT_180
      +
      Turn the page upside down
      +
      CUPS_ORIENT_270
      +
      Rotate the page clockwise
      +
      CUPS_ORIENT_90
      +
      Rotate the page counter-clockwise
      +
      +
+ + diff --git a/doc/help/cgi.html b/doc/help/cgi.html new file mode 100644 index 0000000000..c50a2a5014 --- /dev/null +++ b/doc/help/cgi.html @@ -0,0 +1,86 @@ + + + + Using CGI Programs + + + + +

Using CGI Programs

+ +

CUPS provides a dynamic web interface through dedicated CGI programs that +are executed when users open special directories on the CUPS server. Each CGI +performs administration, class, help, job, and printer functions as directed by +the user, but the actual programs that are run and functions that are available +are limited to those that were originally designed into the scheduler.

+ +

CUPS also supports CGI programs and specific scripting languages (Java, Perl, +PHP, and Python) for pages you want to provide. The interpreters for these +languages are currently configured at compile time and are associated with +MIME media types. Table 1 shows the MIME media types that +are reserved for each type of page and are the same as those used by the Apache +web server.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: CGI MIME Media Types
MIME Media TypeDescription
application/x-httpd-cgiCGI script/program
application/x-httpd-javaJava program
application/x-httpd-perlPerl script
application/x-httpd-phpPHP script
application/x-httpd-pythonPython script
+ +

Configuring the Server

+ +

In order to enable the corresponding type, you must create a +new /etc/cups/cgi.types file which maps the filename +extensions to the appropriate MIME types, for example:

+ +
+application/x-httpd-cgi cgi
+application/x-httpd-java class
+application/x-httpd-perl pl
+application/x-httpd-php php
+application/x-httpd-python py
+
+ +

CGI scripts/programs (application/x-httpd-cgi) also must have execution +permissions to be treated as a CGI script or program.

+ +

Limitations

+ +

CUPS implements most of the CGI/1.1 specification, with the +following exceptions:

+ +
    + +
  • No PATH_INFO or PATH_TRANSLATED support
  • + +
  • Limited HTTP field support; only the Content-Length + (CONTENT_LENGTH), Cookie (HTTP_COOKIE), and User-Agent + (HTTP_USER_AGENT) fields are placed in environment + variables at this time
  • + +
+ + + diff --git a/doc/help/glossary.html b/doc/help/glossary.html new file mode 100644 index 0000000000..c6898dc7df --- /dev/null +++ b/doc/help/glossary.html @@ -0,0 +1,219 @@ + + + + Glossary + + + + +

Glossary

+ +

A

+ +
+ +
ASCII +
American Standard Code for Information Interchange + +
+ + +

C

+ +
+ +
C +
A computer language + +
Character Set +
The association of numbers with specific printed or + displayed characters or symbols + +
+ + +

E

+ +
+ +
ESC/P +
EPSON Standard Code for Printers + +
+ + +

F

+ +
+ +
FTP +
File Transfer Protocol + +
+ + +

G

+ +
+ +
GIF +
Graphics Interchange Format + +
+ + +

H

+ +
+ +
HP-GL +
Hewlett-Packard Graphics Language + +
HP-PCL +
Hewlett-Packard Page Control Language + +
HP-PJL +
Hewlett-Packard Printer Job Language + +
+ + +

I

+ +
+ +
IETF +
Internet Engineering Task Force + +
IP +
Internet Protocol + +
IPv4 +
Internet Protocol, version 4; IPv4 addresses are 32-bits in + length and often look like "nnn.nnn.nnn.nnn" and "127.0.0.1" + +
IPv6 +
Internet Protocol, version 6: IPv6 addresses are 128-bits in + length and look like "xxxx::xxxx:xxxx:xxxx:xxxx" and "::1" + +
IPP +
Internet Printing Protocol + +
ISO +
International Standards Organization + +
+ + +

J

+ +
+ +
JFIF +
JPEG File Interchange Format + +
JPEG +
Joint Photographic Experts Group + +
+ + +

L

+ +
+ +
LPD +
Line Printer Daemon + +
+ + +

M

+ +
+ +
MIME +
Multimedia Internet Mail Exchange + +
+ + +

P

+ +
+ +
parallel +
Sending or receiving data more than 1 bit at a time + +
PDF +
Portable Document Format + +
pipe +
A one-way communications channel between two programs + +
PNG +
Portable Network Graphics + +
PostScript +
A page description language that is most often used + for printing + +
PPD +
PostScript Printer Description + +
+ + +

S

+ +
+ +
SCSI +
Small Computer Systems Interface + +
serial +
Sending or receiving data 1 bit at a time + +
SMB +
Server Message Block + +
socket +
A two-way network communications channel + +
+ + +

T

+ +
+ +
TCP +
Transmission Control Protocol + +
TFTP +
Trivial File Transfer Protocol + +
TIFF +
Tagged Image File Format + +
+ + +

U

+ +
+ +
UDP +
Unicast Datagram Protocol + +
Unicode +
A universal character set for all languages of the + world + +
UTF-8 +
Unicode Transfer Format 8-Bit + +
+ + + diff --git a/doc/help/kerberos.html b/doc/help/kerberos.html new file mode 100644 index 0000000000..82c9b5ffe0 --- /dev/null +++ b/doc/help/kerberos.html @@ -0,0 +1,122 @@ + + + + Using Kerberos Authentication + + + + +

Using Kerberos Authentication

+ +

CUPS allows you to use a Key Distribution Center (KDC) for authentication +on your local CUPS server and when printing to a remote authenticated queue. +This document describes how to configure CUPS to use Kerberos authentication +and provides links to the MIT help pages for configuring Kerberos on your +systems and network.

+ + +

System Requirements

+ +

The following are required to use Kerberos with CUPS:

+ +
    + +
  1. Heimdal Kerberos (any version) or MIT Kerberos (1.6.3 or newer)
  2. + +
  3. Properly configured Domain Name System (DNS) + infrastructure:
      +
    1. DNS server(s) with static IP addresses for all CUPS clients + and servers or configured to allow DHCP updates to the host + addresses
    2. +
    3. All CUPS clients and servers configured to use the same + DNS server(s)
    4. +
  4. + +
  5. Properly configured Kerberos infrastructure:
      +
    1. KDC configured to allow CUPS clients and servers to obtain + Service Granting Tickets (SGTs) for the "ipp" service
    2. +
    3. LDAP-based user accounts - both OpenDirectory and + ActiveDirectory provide this with the KDC
    4. +
    5. CUPS clients and servers bound to the KDC and LDAP + server(s)
    6. +
  6. + +
  7. An "ipp" Service Granting Ticket (SGT) for every CUPS client and + server
  8. + +
+ + +

Configuring Kerberos on Your System

+ +

Before you can use Kerberos with CUPS, you will need to configure +Kerberos on your system and setup a system as a KDC. Because this +configuration is highly system and site-specific, please consult +the following on-line resources provided by the creators of Kerberos +at the Massachusetts Institute of Technology (MIT):

+ + + +

The Linux Documentation Project also has a HOWTO on Kerberos:

+ + + + +

Configuring CUPS to Use Kerberos

+ +

Once you have configured Kerberos on your system(s), you can then +enable Kerberos authentication by selecting the Negotiate +authentication type. The simplest way to do this is using the +cupsctl(8) command:

+ +
+cupsctl DefaultAuthType=Negotiate
+
+ +

You can also enable Kerberos from the web interface by checking the +Use Kerberos Authentication box and clicking Change +Settings:

+ +
+http://localhost:631/admin
+
+ +

After you have enabled Kerberos authentication, use the built-in +"authenticated" policy or your own custom policies with the printers you +will be sharing. See Managing Operation Policies +for more information.

+ + +

Implementation Information

+ +

CUPS implements Kerberos over HTTP using GSSAPI and the service name +"host". Because of limitations in the HTTP GSSAPI protocol extension, only +a single domain/KDC is supported for authentication.

+ +

When doing printing tasks that require authentication, CUPS requests a +single-use "ticket" from your login session to authenticate who you are. +This ticket gives CUPS a username of the form "user@REALM", which is then +converted to just "user" for purposes of user and group checks.

+ +

In order to support printing to a shared printer, CUPS has to ask the KDC +for a copy of your credentials (this is called delegation) that can be sent to +the remote server for authentication. Delegation only works when the system +has a stable hostname which maps to the current address of the system, which +is why you need a static IP address or DHCP that updates the DNS entry for your +system.

+ + + diff --git a/doc/help/license.html b/doc/help/license.html new file mode 100644 index 0000000000..a86babdd56 --- /dev/null +++ b/doc/help/license.html @@ -0,0 +1,1078 @@ + + + + Software License Agreement + + + + +

Software License Agreement

+ +

Copyright 2007-2009 by Apple Inc.
+1 Infinite Loop
+Cupertino, CA 95014 USA
+
+WWW: http://www.cups.org/ + +

Introduction

+ +

CUPSTM 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 and CUPS Imaging libraries +located in the "cups" and "filter" subdirectories 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.

+ +

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.
  • + +
+ +

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 +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 and CUPS Imaging +libraries under other licenses and/or conditions as appropriate +for your application, driver, or filter.

+ + +

License Exceptions

+ +

In addition, as the copyright holder of CUPS, Apple Inc. grants +the following special exceptions:

+ +
    + +
  1. Apple Operating System Development License + Exception; + +
      + +
    1. 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.
    2. + +
    3. 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.
    4. + +
    5. 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.
    6. + +
    7. 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.
    8. + +
    + +
  2. OpenSSL Toolkit License Exception; + +
      + +
    1. Apple Inc. explicitly allows the + compilation and distribution of the CUPS + software with the OpenSSL Toolkit.
    2. + +
    + +
+ +

No developer is required to provide these exceptions in a +derived work.

+ + +

Kerberos Support Code

+ +

The Kerberos support code ("KSC") is copyright 2006 by Jelmer +Vernooij and is provided 'as-is', without any express or implied +warranty. In no event will the author or Apple Inc. be held liable +for any damages arising from the use of the KSC.

+ +

Sources files containing KSC have the following text at the top +of each source file:

+ +
This file contains Kerberos support code, copyright +2006 by Jelmer Vernooij.
+ +

The KSC copyright and license apply only to +Kerberos-related feature code in CUPS. Such code is typically +conditionally compiled based on the present of the +HAVE_GSSAPI preprocessor definition.

+ +

Permission is granted to anyone to use the KSC for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following +restrictions:

+ +
    + +
  1. The origin of the KSC must not be misrepresented; you + must not claim that you wrote the original software. If + you use the KSC in a product, an acknowledgment in the + product documentation would be appreciated but is not + required.
  2. + +
  3. Altered source versions must be plainly marked as + such, and must not be misrepresented as being the + original software.
  4. + +
  5. This notice may not be removed or altered from any + source distribution.
  6. + +
+ + +

Trademarks

+ +

CUPS and the CUPS logo (the "CUPS Marks") are trademarks of Apple Inc. Apple +grants you a non-exclusive and non-transferable right to use the CUPS Marks in +any direct port or binary distribution incorporating CUPS software and in any +promotional material therefor. You agree that your products will meet the +highest levels of quality and integrity for similar goods, not be unlawful, and +be developed, manufactured, and distributed in compliance with this license. +You will not interfere with Apple's rights in the CUPS Marks, and all use of the +CUPS Marks shall inure to the benefit of Apple. This license does not apply to +use of the CUPS Marks in a derivative products, which requires prior written +permission from Apple Inc.

+ + +

GNU GENERAL PUBLIC LICENSE

+ +

Version 2, June 1991 + +

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

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

+ +
    + +
  1. 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. + +

  2. 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. + +

  3. 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: + +
      + +
    1. You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + +
    2. 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. + +
    3. 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. + +

  4. 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: + +
      + +
    1. 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, + +
    2. 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, + +
    3. 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. + +

  5. 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. + +
  6. 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. + +
  7. 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. + +
  8. 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. + +

  9. 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. + +
  10. 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. + +

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

+ +
    + +
  1. 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. + +
  2. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +
+ +

END OF TERMS AND CONDITIONS

+ +

How to Apply These Terms to Your New Programs

+ +

If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +

To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + +

+one line to give the program's name and an idea of what it does.
+Copyright (C) yyyy  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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+ +

Also add information on how to contact you by electronic and paper mail. + +

If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + +

+Gnomovision version 69, Copyright (C) year name of author
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'.  This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c' 
+for details.
+
+ +

The hypothetical commands `show w' and `show c' should show +the appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and +`show c'; they could even be mouse-clicks or menu items--whatever +suits your program. + +

You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + +

+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written 
+by James Hacker.
+
+signature of Ty Coon, 1 April 1989
+Ty Coon, President of Vice
+
+ +

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

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: + +

    + +
  1. The modified work must itself be a software library. + +

    +

  2. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + +

    +

  3. You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + +

    +

  4. 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: + +

    + +
  1. 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.) + +

    +

  2. 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. + +

    +

  3. 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. + +

    +

  4. 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: + +

    + +
  1. 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. + +

    +

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

+ +

How to Apply These Terms to Your New Libraries

+ +

If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + +

To apply these terms, attach the following notices to the library. 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 library's name and an idea of what it does.
+Copyright (C) year  name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+ +

Also add information on how to contact you by electronic and paper mail. + +

You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + +

+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+ +

That's all there is to it! + + + diff --git a/doc/help/network.html b/doc/help/network.html new file mode 100644 index 0000000000..d02d4f4036 --- /dev/null +++ b/doc/help/network.html @@ -0,0 +1,684 @@ + + + + Using Network Printers + + + + +

Using Network Printers

+ +

This help document describes how to discover, configure, and use TCP/IP network printers with CUPS.

+ +

Getting the IP Address

+ +

Every network printer or print server has a unique Internet Protocol (IP) address associated with it. This address is either configured manually or set using an automatic network protocol such as the Boot Protocol (BOOTP), Dynamic Host Control Protocol (DHCP), Reverse Address Resolution Protocol (RARP), or ZeroConf.

+ +

You can normally find the IP address of a printer on the printer's control panel or by printing the configuration or status page. The Simple Network Management Protocol (SNMP) can also be used to get the IP address remotely, which happens automatically when you visit the CUPS administration web page or choose an available CUPS device when adding a printer.

+ + +

Configuring the IP Address

+ +

When you first install a network printer or print server on your LAN, you need to set the Internet Protocol ("IP") address. Most higher-end "workgroup" printers allow you to set the address through the printer control panel. However, if you have many printers you will want to assign the addresses remotely - this makes administration a bit easier and avoids assigning duplicate addresses accidentally.

+ +

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.

+ +

Configuring the IP Address Using DHCP

+ +

The DHCP protocol is the usual way of setting the IP address of a printer on a managed network. Using the standard dhcpd(8) program supplied with UNIX you simply need to add a line to the /etc/dhcpd.conf file:

+ +
+host hostname {
+  hardware ethernet mac-address;
+  fixed-address ip-address;
+}
+
+ +

Make sure that the hostname you use is also listed in the /etc/hosts file or is registered with your DNS server.

+ +

Configuring the IP Address Using BOOTP

+ +

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 bootpd(8) program supplied with UNIX you simply need to add a line to the /etc/bootptab file; for IRIX:

+ +
+myprinter 08:00:69:00:12:34 192.0.2.2 myprinter.boot
+
+ +

Newer versions of bootpd use a different format:

+ +
+myprinter:ha=080069001234:ip=192.0.2.2:t144=myprinter.boot
+
+ +

The myprinter.boot file resides in the /usr/local/boot directory by default. If you do not need to provide a boot file you may leave the last part of the line blank.

+ +
Note: Some versions of UNIX do not enable the BOOTP service by default. The /etc/inetd.conf or /etc/xinetd.d/bootp file usually contains a line for the BOOTP service that can be uncommented if needed.
+ + +

Verifying the Printer Connection

+ +

To test that the IP address has been successfully assigned and +that the printer is properly connected to your LAN, type:

+ +
+ping ip-address
+
+ +

If the connection is working properly you will see something +like:

+ +
+ping myprinter
+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
+
+ +

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.

+ + +

Network Protocols Supported by CUPS

+ +

CUPS supports most network printers using one of three TCP/IP-based protocols. Printer discovery is currently accomplished using the SNMP protocol, however future versions of CUPS will also include support for multicast DNS service discovery as well.

+ +

AppSocket Protocol

+ +

The AppSocket protocol (sometimes also called the JetDirect protocol, owing to its origins with the HP JetDirect network interfaces) is the simplest, fastest, and generally the most reliable network protocol used for printers. AppSocket printing normally happens over port 9100 and uses the socket URI scheme:

+ +
+socket://ip-address-or-hostname
+socket://ip-address-or-hostname/?waiteof=false
+socket://ip-address-or-hostname:port-number
+socket://ip-address-or-hostname:port-number/?waiteof=false
+
+ +

The "waiteof" option controls whether the socket backend waits for the printer to complete the printing of the job. The default is to wait.

+ +

Internet Printing Protocol (IPP)

+ +

IPP is the only protocol that CUPS supports natively and is supported by some network printers and print servers. However, since many printers do not implement IPP properly, only use IPP when the vendor actually documents official support for it. IPP printing normally happens over port 631 and uses the http and ipp URI schemes:

+ +
+http://ip-address-or-hostname:port-number/resource
+http://ip-address-or-hostname:port-number/resource?option=value
+http://ip-address-or-hostname:port-number/resource?option=value&option=value
+ipp://ip-address-or-hostname/resource
+ipp://ip-address-or-hostname/resource?option=value
+ipp://ip-address-or-hostname/resource?option=value&option=value
+ipp://ip-address-or-hostname:port-number/resource
+ipp://ip-address-or-hostname:port-number/resource?option=value
+ipp://ip-address-or-hostname:port-number/resource?option=value&option=value
+
+ +

The ipp backend supports many options, which are summarized in Table 2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: IPP URI Options
OptionDescription
compression=gzipSpecifies that print data should be compressed before sending.
encryption=alwaysSpecifies that the connection to the IPP server should be encrypted using SSL.
encryption=ifrequestedSpecifies that the connection to the IPP server should only be encrypted if the server requests it.
encryption=neverSpecifies that the connection to the IPP server should not be encrypted.
encryption=requiredSpecifies that the connection to the IPP server should be encrypted using TLS.
version=1.0Specifies that version 1.0 of the IPP protocol should be used instead of the default version 1.1.
version=2.0Specifies that version 2.0 of the IPP protocol should be used instead of the default version 1.1.
version=2.1Specifies that version 2.1 of the IPP protocol should be used instead of the default version 1.1.
waitjob=falseSpecifies that the IPP backend should not wait for the job to complete.
waitprinter=falseSpecifies that the IPP backend should not wait for the printer to become idle before sending the print job.
+ +

Line Printer Daemon (LPD) Protocol

+ +

LPD is the original network printing protocol and is supported by many network printers. Due to limitations in the LPD protocol, we do not recommend using it if the printer or server supports one of the other protocols. LPD printing normally happens over port 515 and uses the lpd URI scheme:

+ +
+lpd://ip-address-or-hostname/queue
+lpd://username@ip-address-or-hostname/queue
+lpd://ip-address-or-hostname/queue?option=value
+lpd://username@ip-address-or-hostname/queue?option=value
+lpd://ip-address-or-hostname/queue?option=value&option=value
+lpd://username@ip-address-or-hostname/queue?option=value&option=value
+
+ +

Table 3 summarizes the options supported by the lpd backend.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3: LPD URI Options
OptionDescription
banner=onSpecifies that a banner page should be printed by the server.
contimeout=secondsSpecifies the number of seconds to wait for the connection to the server to complete.
format=cSpecifies that the print data is a CIF file.
format=dSpecifies that the print data is a DVI file.
format=fSpecifies that the print data is a plain text file.
format=gSpecifies that the print data is a Berkeley plot file.
format=lSpecifies that the print data is a raw (preformatted) print file.
format=nSpecifies that the print data is a ditroff file.
format=oSpecifies that the print data is a PostScript file.
format=pSpecifies that the print data is a plain text file that should be "pretty" printed with a header and footer.
format=rSpecifies that the print data is a FORTRAN carriage control file.
format=tSpecifies that the print data is a troff Graphic Systems C/A/T phototypesetter file.
format=vSpecifies that the print data is a Sun raster file.
order=data,controlSpecifies that the print data files should be sent before the control file.
reserve=noneSpecifies that the backend should not reserve a source port.
reserve=rfc1179Specifies that the backend should reserve a source port from 721 to 731 as required by RFC 1179.
sanitize_title=noSpecifies that the job title string should not be restricted to ASCII characters.
sanitize_title=yesSpecifies that the job title string should be restricted to ASCII characters.
timeout=secondsSpecifies the number of seconds to wait for LPD commands to complete.
+ + +

Common Network Printer URIs

+ +

Once you have set the IP address you can access the printer or print server using the ipp, lpd, or socket backends. Table 1 shows a list of common network interfaces and printer servers and the settings you should use with CUPS:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Common Device URIs
Model/ManufacturerDevice URI(s)
Apple LaserWriterlpd://address/PASSTHRU
Axis w/o IPP
+ Axis OfficeBasic
+ (see directions)
socket://address:9100
+ socket://address:9101
+ socket://address:9102
Axis w/IPPipp://address/LPT1
+ ipp://address/LPT2
+ ipp://address/COM1
Castelle LANpressTMlpd://address/pr1
+ lpd://address/pr2
+ lpd://address/pr3
DPI NETPrintlpd://address/pr1
+ lpd://address/pr2
+ lpd://address/pr3
DLink DP-301P+socket://address
EFI® Fiery® RIPlpd://address/print
EPSON® Multiprotocol Ethernet Interface Boardsocket://address
Extended System ExtendNETlpd://address/pr1
+ lpd://address/pr2
+ lpd://address/pr3
Hewlett Packard JetDirectsocket://address:9100
+ socket://address:9101
+ socket://address:9102
Intel® NetportExpress XL, PRO/100lpd://address/LPT1_PASSTHRU
+ lpd://address/LPT2_PASSTHRU
+ lpd://address/COM1_PASSTHRU
LexmarkTM MarkNetlpd://address/ps
Linksys EtherFast®
+ (see directions)
socket://address:4010
+ socket://address:4020
+ socket://address:4030
Linksys PSUS4lpd://address/lp
Kodak®lpd://address/ps
Netgear WGPS606lpd://address/L1
+ lpd://address/L2
QMS® CrownNetTMlpd://address/ps
Tektronix® PhaserShareTMsocket://address:9100
XEROX® 4512 NIClpd://address/PORT1
XEROX® XNIClpd://address/PASSTHRU
XEROX® (most others)socket://address:5503
+ + +

Troubleshooting SNMP Discovery Problems

+ +

Whenever you view the administration web page or a list of supported device URIs, the snmp backend will probe the local network(s) using Simple Network Management Protocol (SNMP) broadcasts. Printers that respond to these broadcasts are then interrogated for the make and model and supported protocols, yielding a device URI that can be used to add the printer.

+ +

That said, the SNMP requests sometimes expose problems in vendor SNMP or IPP implementations. If you are experiencing long delays in loading the CUPS web interface administration page, or if you don't see your printer listed, the following instructions will help you to diagnose those problems and/or provide important feedback to the CUPS developers so that we can correct problems and improve the SNMP backend in future releases.

+ +

Quick Fixes

+ +

If you don't use "public" as your community name, create a text file called /etc/cups/snmp.conf and put the following line in it:

+ +
+Community your community name
+
+ +

If you have more than one community name, list them all on separate lines.

+ +

If you don't support SNMP v1 on your network, you are currently "out of luck". That said, we will be adding v2, v2c, and v3 support in future CUPS releases once we have a handle on the actual requirements people have for such things. Please file or update an SNMP enhancement request with specific requirements you have - what you need supported, why you need it supported, and how you would like to see the functionality provided/exposed - so that we can do it "right" the first time.

+ +

Basic Debugging

+ +

The SNMP backend supports a debugging mode that is activated by running it from a shell prompt. If you are using Bash (/bin/bash), Bourne shell (/bin/sh), Korn shell (/bin/ksh), or Z shell (/bin/zsh), you can run the following command to get a verbose log of the SNMP backend:

+ +
+CUPS_DEBUG_LEVEL=2 /usr/lib/cups/backend/snmp 2>&1 | tee snmp.log
+
+ +

For C shell (/bin/csh) and TCsh (/bin/tcsh), use the following command instead:

+ +
+(setenv CUPS_DEBUG_LEVEL 2; /usr/lib/cups/backend/snmp) |& tee snmp.log
+
+ +

On MacOS X you'll find the SNMP backend in /usr/libexec/cups/backend instead:

+ +
+CUPS_DEBUG_LEVEL=2 /usr/libexec/cups/backend/snmp 2>&1 | tee snmp.log
+
+ +

The output will look something like this:

+ +
+ 1  INFO: Using default SNMP Address @LOCAL
+ 2  INFO: Using default SNMP Community public
+ 3  DEBUG: Scanning for devices in "public" via "@LOCAL"...
+ 4  DEBUG: 0.000 Sending 46 bytes to 192.168.2.255...
+ 5  DEBUG: SEQUENCE 44 bytes
+ 6  DEBUG:     INTEGER 1 bytes 0
+ 7  DEBUG:     OCTET STRING 6 bytes "public"
+ 8  DEBUG:     Get-Request-PDU 31 bytes
+ 9  DEBUG:         INTEGER 4 bytes 1149539174
+10  DEBUG:         INTEGER 1 bytes 0
+11  DEBUG:         INTEGER 1 bytes 0
+12  DEBUG:         SEQUENCE 17 bytes
+13  DEBUG:             SEQUENCE 15 bytes
+14  DEBUG:                 OID 11 bytes .1.3.6.1.2.1.25.3.2.1.2.1
+15  DEBUG:                 NULL VALUE 0 bytes
+16  DEBUG: 0.001 Received 55 bytes from 192.168.2.229...
+17  DEBUG: community="public"
+18  DEBUG: request-id=1149539174
+19  DEBUG: error-status=0
+20  DEBUG: SEQUENCE 53 bytes
+21  DEBUG:     INTEGER 1 bytes 0
+22  DEBUG:     OCTET STRING 6 bytes "public"
+23  DEBUG:     Get-Response-PDU 40 bytes
+24  DEBUG:         INTEGER 4 bytes 1149539174
+25  DEBUG:         INTEGER 1 bytes 0
+26  DEBUG:         INTEGER 1 bytes 0
+27  DEBUG:         SEQUENCE 26 bytes
+28  DEBUG:             SEQUENCE 24 bytes
+29  DEBUG:                 OID 11 bytes .1.3.6.1.2.1.25.3.2.1.2.1
+30  DEBUG:                 OID 9 bytes .1.3.6.1.2.1.25.3.1.5
+31  DEBUG: add_cache(addr=0xbfffe170, addrname="192.168.2.229",
+    uri="(null)", id="(null)", make_and_model="(null)")
+32  DEBUG: 0.002 Sending 46 bytes to 192.168.2.229...
+33  DEBUG: SEQUENCE 44 bytes
+34  DEBUG:     INTEGER 1 bytes 0
+35  DEBUG:     OCTET STRING 6 bytes "public"
+36  DEBUG:     Get-Request-PDU 31 bytes
+37  DEBUG:         INTEGER 4 bytes 1149539175
+38  DEBUG:         INTEGER 1 bytes 0
+39  DEBUG:         INTEGER 1 bytes 0
+40  DEBUG:         SEQUENCE 17 bytes
+41  DEBUG:             SEQUENCE 15 bytes
+42  DEBUG:                 OID 11 bytes .1.3.6.1.2.1.25.3.2.1.3.1
+43  DEBUG:                 NULL VALUE 0 bytes
+44  DEBUG: 0.003 Received 69 bytes from 192.168.2.229...
+45  DEBUG: community="public"
+46  DEBUG: request-id=1149539175
+47  DEBUG: error-status=0
+48  DEBUG: SEQUENCE 67 bytes
+49  DEBUG:     INTEGER 1 bytes 0
+50  DEBUG:     OCTET STRING 6 bytes "public"
+51  DEBUG:     Get-Response-PDU 54 bytes
+52  DEBUG:         INTEGER 4 bytes 1149539175
+53  DEBUG:         INTEGER 1 bytes 0
+54  DEBUG:         INTEGER 1 bytes 0
+55  DEBUG:         SEQUENCE 40 bytes
+56  DEBUG:             SEQUENCE 38 bytes
+57  DEBUG:                 OID 11 bytes .1.3.6.1.2.1.25.3.2.1.3.1
+58  DEBUG:                 OCTET STRING 23 bytes "HP LaserJet 4000
+    Series"
+59  DEBUG: 1.001 Probing 192.168.2.229...
+60  DEBUG: 1.001 Trying socket://192.168.2.229:9100...
+61  DEBUG: 192.168.2.229 supports AppSocket!
+62  DEBUG: 1.002 Scan complete!
+63  network socket://192.168.2.229 "HP LaserJet 4000 Series"
+    "HP LaserJet 4000 Series 192.168.2.229" ""
+
+ +

Dissecting the Output

+ +

The first two lines are just informational and let you know that the default community name and address are being used. Lines 3-15 contain the initial SNMP query for the device type OID (.1.3.6.1.2.1.25.3.2.1.2.1) from the Host MIB.

+ +

Lines 16-31 show the response we got from an HP LaserJet 4000 network printer. At this point we discover that it is a printer device and then send another SNMP query (lines 32-43) for the device description OID (.1.3.6.1.2.1.25.3.2.1.3.1) from the Host MIB as well.

+ +

Lines 44-58 show the response to the device description query, which tells us that this is an HP LaserJet 4000 Series printer.

+ +

On line 59 we start our active connection probe and discover that this print server supports the AppSocket (JetDirect) protocol on port 9100.

+ +

Finally, line 63 shows the device information line for the print server that is sent to CUPS.

+ +

Reporting Problems

+ +If you don't see your printer listed, or the wrong information is listed, then you need to gather more information on the printer. The easiest way to do this is to run the snmpwalk command: + +
+snmpwalk -Cc -v 1 -c public ip-address | tee snmpwalk.log
+
+ +

where "ip-address" is the IP address of the printer or print server. You should see a lot of values stream by - the ones you want to see are:

+ +
+HOST-RESOURCES-MIB::hrDeviceType.1 = OID: HOST-RESOURCES-TYPES::hrDevicePrinter
+HOST-RESOURCES-MIB::hrDeviceDescr.1 = STRING: HP LaserJet 4000 Series
+
+ +

The hrDeviceType line should show hrDevicePrinter; if not, then your printer or print server doesn't identify itself as a printer. The hrDeviceDescr line should provide a human-readable string for the make and model of the printer, although in some cases you'll just see something less useful like "Axis OfficeBASIC Parallel Print Server".

+ +

Once you have collected the snmpwalk output, you should go to the CUPS Bugs & Features page to submit a feature request to support your printer or print server. Be sure to attach those two log files you created - they will help us to identify the SNMP values we need to look for.

+ + +

Configuring Print Servers

+ +

Configuring Axis Print Servers

+ +

The Axis print servers can be configured using BOOTP or DHCP. 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.

+ +

Each print server contains a configuration file named config 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 ftp(1) program:

+ +
+ftp ip-address
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp> user root
+331 User name ok, need password
+Password: pass (this is not echoed)
+230 User logged in
+ftp> get config
+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> quit
+221 Goodbye.
+
+ +

Next, edit the file with your favorite text editor and locate the lines beginning with:

+ +
+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
+
+ +

Change the RTN_OPT line to read:

+ +
+RTN_OPT.     : NO
+
+ +

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:

+ +
+RTEL_PR1.    : 9100
+RTEL_PR2.    : 9101
+RTEL_PR3.    : 9102
+RTEL_PR4.    : 9103
+RTEL_PR5.    : 9104
+RTEL_PR6.    : 9105
+RTEL_PR7.    : 9106
+RTEL_PR8.    : 9107
+
+ +

This essentially makes the Axis print server look like a Hewlett Packard JetDirect EX print server. Save the file and then upload the new config file using the ftp command:

+ +
+ftp ip-address
+Connected to ip-address.
+220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
+ftp> user root
+331 User name ok, need password
+Password: pass (this is not echoed)
+230 User logged in
+ftp> put config CONFIG
+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> get hardreset
+local: hardreset remote: hardreset
+200 PORT command successful.
+421 Axis NPS ### hard reset, closing connection.
+ftp> quit
+221 Goodbye.
+
+ +

Your Axis print server is now ready for use!

+ +

Configuring Linksys Print Servers

+ +

The Linksys print servers can be configured using BOOTP or DHCP. 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.

+ +

Each print server contains a configuration file named CONFIG 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 ftp(1) program:

+ +
+ftp -n ip-address
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp> get CONFIG
+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> quit
+221 Goodbye.
+
+ +

Next, edit the file with your favorite text editor and locate the lines beginning with:

+ +
+0100 L1_PROUT:P1
+0120 L2_PROUT:P1
+0140 L3_PROUT:P1
+
+ +

Change the port number for each parallel and serial port on the server as follows:

+ +
+0100 L1_PROUT:P1
+0120 L2_PROUT:P2
+0140 L3_PROUT:P3
+
+ +

This maps each virtual printer with a physical port. Save the file and then upload the new CONFIG file using the ftp command:

+ +
+ftp -n ip-address
+Connected to ip-address.
+220 Print Server Ready.
+Remote system type is Print.
+ftp> put CONFIG
+local: CONFIG remote: CONFIG
+200 Command OK.
+150 Open ASCII Mode Connection.
+226 Transfer complete.
+##### bytes received in #.## seconds (##### Kbytes/s)
+ftp> quit
+221 Goodbye.
+
+ +

Your Linksys print server is now ready for use!

+ + + diff --git a/doc/help/options.html b/doc/help/options.html new file mode 100644 index 0000000000..0cfa741354 --- /dev/null +++ b/doc/help/options.html @@ -0,0 +1,778 @@ + + + + Command-Line Printing and Options + + + + +

Command-Line Printing and Options

+ +

CUPS provides both the System V (lp(1)) and Berkeley (lpr(1)) printing commands for printing +files. In addition, it supported a large number of standard and +printer-specific options that allow you to control how and where +files are printed.

+ + +

Printing Files

+ +

CUPS understands many different types of files directly, +including text, PostScript, PDF, and image files. This allows you +to print from inside your applications or at the command-line, +whichever is most convenient! Type either of the following +commands to print a file to the default (or only) printer on the +system:

+ +
+lp filename
+lpr filename
+
+ +

Choosing a Printer

+ +

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. Use +the lpstat(1) command to see a list +of available printers:

+ +
+lpstat -p -d
+
+ +

The -p option specifies that you want to see a +list of printers, and the -d option reports the +current default printer or class.

+ +

Use the -d option with the lp command to +print to a specific printer:

+ +
+lp -d printer filename
+
+ +

or the -P option with the lpr command:

+ +
+lpr -P printer filename
+
+ +

Setting the Default Printer

+ +

If you normally use a particular printer, you can tell CUPS to +use it by default using the lpoptions(1) command:

+ +
+lpoptions -d printer
+
+ +

Printing the Output of a Program

+ +

Both the lp and lpr commands support printing +from the standard input:

+ +
+program | lp
+program | lp -d printer
+program | lpr
+program | lpr -P printer
+
+ +

If the program does not provide any output, then nothing will +be queued for printing.

+ +

Specifying Printer Options

+ +

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.

+ +

The lp and lpr commands allow you to pass +printer options using the -o option:

+ +
+lp -o landscape -o scaling=75 -o media=A4 filename.jpg
+lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
+
+ +

The available printer options vary depending on the printer. +The standard options are described in the "Standard Printing Options" section +below. Printer-specific options are also available and can be +listed using the lpoptions command:

+ +
+lpoptions -p printer -l
+
+ +

Creating Saved Options

+ +

Saved options are supported in CUPS through printer +instances. Printer instances are, as their name implies, copies +of a printer that have certain options associated with them. Use the +lpoptions command to create a printer instance:

+ +
+lpoptions -p printer/instance -o name=value ...
+
+ +

The -p printer/instance option provides the name of +the instance, which is always the printer name, a slash, and the +instance name which can contain any printable characters except +space and slash. The remaining options are then associated with the +instance instead of the main queue. For example, the following +command creates a duplex instance of the LaserJet queue:

+ +
+lpoptions -p LaserJet/duplex -o sides=two-sided-long-edge
+
+ +

Instances do not inherit lpoptions from the main +queue.

+ +

Printing Multiple Copies

+ +

Both the lp and lpr commands have options for +printing more than one copy of a file:

+ +
+lp -n num-copies filename
+lpr -#num-copies filename
+
+ +

Copies are normally not collated for you. Use the +-o Collate=True option to get collated copies:

+ +
+lp -n num-copies -o Collate=True filename
+lpr -#num-copies -o Collate=True filename
+
+ + +

Canceling a Print Job

+ +

The cancel(1) and lprm(1) commands cancel a print job:

+ +
+cancel job-id
+lprm job-id
+
+ +

The job-id is the number that was reported to you by +the lp command. You can also get the job ID using the lpq(1) or lpstat commands:

+ +
+lpq
+lpstat
+
+ + +

Moving a Print Job

+ +

The lpmove(8) command moves a print +job to a new printer or class:

+ +
+lpmove job-id destination
+
+ +

The job-id is the number that was reported to you by +the lp or lpstat commands. Destination is the +name of a printer or class that you want to actually print the job. + +

Note: + +

The lpmove command is located in the system command +directory (typically /usr/sbin or /usr/local/sbin), +and so may not be in your command path. Specify the full path to the +command if you get a "command not found" error, for example: + +

+/usr/sbin/lpmove foo-123 bar
+
+ +
+ + +

Standard Printing Options

+ +

The following options apply when printing all types of +files.

+ +

Selecting the Media Size, Type, and Source

+ +

The -o media=xyz option sets the media size, +type, and/or source:

+ +
+lp -o media=Letter filename
+lp -o media=Letter,MultiPurpose filename
+lpr -o media=Letter,Transparency filename
+lpr -o media=Letter,MultiPurpose,Transparency filename
+
+ +

The available media sizes, types, and sources depend on the +printer, but most support the following options (case is not +significant):

+ +
    + +
  • Letter - US Letter (8.5x11 inches, or 216x279mm) + +
  • Legal - US Legal (8.5x14 inches, or 216x356mm) + +
  • A4 - ISO A4 (8.27x11.69 inches, or 210x297mm) + +
  • COM10 - US #10 Envelope (9.5x4.125 inches, or + 241x105mm) + +
  • DL - ISO DL Envelope (8.66x4.33 inches, or 220x110mm) + +
  • Transparency - Transparency media type or source + +
  • Upper - Upper paper tray + +
  • Lower - Lower paper tray + +
  • MultiPurpose - Multi-purpose paper tray + +
  • LargeCapacity - Large capacity paper tray + +
+ +

The actual options supported are defined in the printer's PPD +file in the PageSize, InputSlot, and +MediaType options. You can list them using the +lpoptions(1) command:

+ +
+lpoptions -p printer -l
+
+ +

When Custom is listed for the PageSize option, you can specify custom media sizes using one of the following forms:

+ +
+lp -o media=Custom.WIDTHxLENGTH filename
+lp -o media=Custom.WIDTHxLENGTHin filename
+lp -o media=Custom.WIDTHxLENGTHcm filename
+lp -o media=Custom.WIDTHxLENGTHmm filename
+
+ +

where "WIDTH" and "LENGTH" are the width and length of the media in points, inches, centimeters, or millimeters, respectively.

+ + +

Setting the Orientation

+ +

The -o landscape option will rotate the page 90 +degrees to print in landscape orientation:

+ +
+lp -o landscape filename
+lpr -o landscape filename
+
+ +

The -o orientation-requested=N option rotates the +page depending on the value of N:

+ +
    + +
  • -o orientation-requested=3 - portrait + orientation (no rotation)
  • + +
  • -o orientation-requested=4 - landscape + orientation (90 degrees)
  • + +
  • -o orientation-requested=5 - reverse + landscape or seascape orientation (270 degrees)
  • + +
  • -o orientation-requested=6 - reverse + portrait or upside-down orientation (180 degrees)
  • + +
+ + +

Printing On Both Sides of the Paper

+ +

The -o sides=two-sided-short-edge and -o +sides=two-sided-long-edge options will enable two-sided +printing on the printer if the printer supports it. The -o +sides=two-sided-short-edge option is suitable for +landscape pages, while the -o +sides=two-sided-long-edge option is suitable for portrait +pages:

+ +
+lp -o sides=two-sided-short-edge filename
+lp -o sides=two-sided-long-edge filename
+lpr -o sides=two-sided-long-edge filename
+
+ +

The default is to print single-sided:

+ +
+lp -o sides=one-sided filename
+lpr -o sides=one-sided filename
+
+ + +

Selecting the Banner Page(s)

+ +

The -o job-sheets=start,end option sets the banner +page(s) to use for a job:

+ +
+lp -o job-sheets=none filename
+lp -o job-sheets=standard filename
+lpr -o job-sheets=classified,classified filename
+
+ +

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.

+ +

The available banner pages depend on the local system +configuration; CUPS includes the following banner files:

+ +
    + +
  • none - Do not produce a banner page. + +
  • classified - A banner page with a "classified" + label at the top and bottom. + +
  • confidential - A banner page with a + "confidential" label at the top and bottom. + +
  • secret - A banner page with a "secret" label + at the top and bottom. + +
  • standard - A banner page with no label at the + top and bottom. + +
  • topsecret - A banner page with a "top secret" + label at the top and bottom. + +
  • unclassified - A banner page with an + "unclassified" label at the top and bottom. + +
+ + +

Holding Jobs for Later Printing

+ +

The -o job-hold-until=when option tells CUPS to +delay printing until the "when" time, which can be one of the +following:

+ +
    + +
  • -o job-hold-until=indefinite; print only + after released by the user or an administrator
  • + +
  • -o job-hold-until=day-time; print from + 6am to 6pm local time
  • + +
  • -o job-hold-until=night; print from + 6pm to 6am local time
  • + +
  • -o job-hold-until=second-shift; print from + 4pm to 12am local time
  • + +
  • -o job-hold-until=third-shift; print from + 12am to 8am local time
  • + +
  • -o job-hold-until=weekend; print on Saturday + or Sunday
  • + +
  • -o job-hold-until=HH:MM; print at the specified + UTC time
  • + +
+ +

Releasing Held Jobs

+ +

Aside from the web interface, you can use the lp command +to release a held job:

+ +
+lp -i job-id -H resume
+
+ +

where "job-id" is the job ID reported by the lpstat +command.

+ + +

Setting the Job Priority

+ +

The -o job-priority=NNN option tells CUPS to +assign a priority to your job from 1 (lowest) to 100 (highest), +which influences where the job appears in the print queue. Higher +priority jobs are printed before lower priority jobs, however +submitting a new job with a high priority will not interrupt an +already printing job.

+ + +

Specifying the Output Order

+ +

The -o outputorder=normal and -o outputorder=reverse options specify the order of the pages. Normal order prints page 1 first, page 2 second, and so forth. Reverse order prints page 1 last.

+ + +

Selecting a Range of Pages

+ +

The -o page-ranges=pages option selects a range +of pages for printing:

+ +
+lp -o page-ranges=1 filename
+lp -o page-ranges=1-4 filename
+lp -o page-ranges=1-4,7,9-12 filename
+lpr -o page-ranges=1-4,7,9-12 filename
+
+ +

As shown above, the pages 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 page-ranges option. + +

The default is to print all pages. + +

Note: + +

The page numbers used by page-ranges refer to the output +pages and not the document's page numbers. Options like number-up +can make the output page numbering not match the document page numbers.

+ +
+ + +

Selecting Even or Odd Pages

+ +

Use the -o page-set=set option to select the even or odd pages:

+ +
+lp -o page-set=odd filename
+lp -o page-set=even filename
+lpr -o page-set=even filename
+
+ +

The default is to print all pages. + +

N-Up Printing

+ +

The -o number-up=value 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:

+ +
+lp -o number-up=1 filename
+lp -o number-up=2 filename
+lp -o number-up=4 filename
+lpr -o number-up=16 filename
+
+ +

The -o page-border=value option chooses the +border to draw around each page:

+ +
    +
  • -o page-border=double; draw two hairline borders around each page
  • +
  • -o page-border=double-thick; draw two 1pt borders around each page
  • +
  • -o page-border=none; do not draw a border (default)
  • +
  • -o page-border=single; draw one hairline border around each page
  • +
  • -o page-border=single-thick; draw one 1pt border around each page
  • +
+ +

The -o number-up-layout=value option chooses the +layout of the pages on each output page:

+ +
    +
  • -o number-up-layout=btlr; Bottom to top, left to right
  • +
  • -o number-up-layout=btrl; Bottom to top, right to left
  • +
  • -o number-up-layout=lrbt; Left to right, bottom to top
  • +
  • -o number-up-layout=lrtb; Left to right, top to bottom (default)
  • +
  • -o number-up-layout=rlbt; Right to left, bottom to top
  • +
  • -o number-up-layout=rltb; Right to left, top to bottom
  • +
  • -o number-up-layout=tblr; Top to bottom, left to right
  • +
  • -o number-up-layout=tbrl; Top to bottom, right to left
  • +
+ +

Scaling to Fit

+ +

The -o fit-to-page option specifies that the document +should be scaled to fit on the page:

+ +
+lp -o fit-to-page filename
+lpr -o fit-to-page filename
+
+ +

The default is to use the size specified in the file.

+ +
Note: + +

This feature depends upon an accurate size in +the print file. If no size is given in the file, the page may be +scaled incorrectly! + +

+ +

Printing in Reverse Order

+ +

The -o outputorder=reverse option will print the +pages in reverse order:

+ +
+lp -o outputorder=reverse filename
+lpr -o outputorder=reverse filename
+
+ +

Similarly, the -o outputorder=normal option will +print starting with page 1:

+ +
+lp -o outputorder=normal filename
+lpr -o outputorder=normal filename
+
+ +

The default is -o outputorder=normal for +printers that print face down and -o outputorder=reverse +for printers that print face up. + +

Printing Mirrored Pages

+ +

The -o mirror option flips each page along the +vertical axis to produce a mirrored image:

+ +
+lp -o mirror filename
+lpr -o mirror filename
+
+ +

This is typically used when printing on T-shirt transfer +media or sometimes on transparencies.

+ +

Raw or Unfiltered Output

+ +

The -o raw 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:

+ +
+lp -o raw filename
+lpr -o raw filename
+
+ +

The -l option can also be used with the +lpr command to send files directly to a printer:

+ +
+lpr -l filename
+
+ + +

Text Options

+ +

CUPS supports several options that are only used when printing +plain text files. These options have absolutely no effect on +PostScript, PDF, HP-GL/2, or image files.

+ +

Setting the Number of Characters Per Inch

+ +

The -o cpi=value option sets the number of +characters per inch:

+ +
+lp -o cpi=10 filename
+lp -o cpi=12 filename
+lpr -o cpi=17 filename
+
+ +

The default characters per inch is 10.

+ +

Setting the Number of Lines Per Inch

+ +

The -o lpi=value option sets the number of lines +per inch:

+ +
+lp -o lpi=6 filename
+lpr -o lpi=8 filename
+
+ +

The default lines per inch is 6.

+ +

Setting the Number of Columns

+ +

The -o columns=value option sets the number of +text columns:

+ +
+lp -o columns=2 filename
+lpr -o columns=3 filename
+
+ +

The default number of columns is 1.

+ +

Setting the Page Margins

+ +

Normally the page margins are set to the hard limits of the +printer. Use the -o page-left=value, -o +page-right=value, -o page-top=value, and +-o page-bottom=value options to adjust the page +margins:

+ +
+lp -o page-left=value filename
+lp -o page-right=value filename
+lp -o page-top=value filename
+lp -o page-bottom=value filename
+lpr -o page-left=value -o page-right=value -o page-top=value -o page-bottom=value filename
+
+ +

The value argument is the margin in points; each +point is 1/72 inch or 0.35mm.

+ +

Pretty Printing

+ +

The -o prettyprint 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:

+ +
+lp -o prettyprint filename
+lpr -o prettyprint filename
+
+ +

Turning Off Text Wrapping

+ +

The -o nowrap option disables wrapping of long lines:

+ +
+lp -o nowrap filename
+lpr -o nowrap filename
+
+ + +

Not Supported on Mac OS XImage Options

+ +

CUPS supports several options that are only used when printing +image files. These options have absolutely no effect on PostScript, PDF, +HP-GL/2, or text files.

+ +

Positioning Images

+ +

The -o position=name option specifies the position of the +image on the page: + +

    + +
  • center - Center the image on the page (default) + +
  • top - Print the image centered at the top of the page + +
  • left - Print the image centered on the left of page + +
  • right - Print the image centered on the right of the page + +
  • top-left - Print the image at the top left corner of + the page + +
  • top-right - Print the image at the top right corner of + the page + +
  • bottom - Print the image centered at the bottom of + the page + +
  • bottom-left - Print the image at the bottom left + corner of the page + +
  • bottom-right - Print the image at the bottom right + corner of the page + +
+ +

Scaling Images

+ +

The -o scaling=percent, -o +ppi=value, and -o natural-scaling=percent +options change the size of a printed image: + +

+lp -o scaling=percent filename 
+lp -o ppi=value filename
+lpr -o natural-scaling=percent filename
+
+ +

The scaling=percent value is a number from 1 to 800 +specifying the size in relation to the page (not 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. + +

The ppi=value 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. + +

The natural-scaling=percent 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. + + +

HP-GL/2 Options

+ +

CUPS supports several options that are only used when printing +HP-GL/2 files. These options have absolutely no effect on PostScript, PDF, +image, or text files.

+ +

Printing in Black

+ +

The -o blackplot option specifies that all pens should +plot in black:

+ +
+lp -o blackplot filename
+lpr -o blackplot filename
+
+ +

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

Setting the Default Pen Width

+ +

The -o penwidth=value option specifies the default pen +width for HP-GL/2 files:

+ +
+lp -o penwidth=value filename
+lpr -o penwidth=value filename
+
+ +

The pen width value 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.

+ +
Note: + +

This option is ignored when the pen widths are set in the plot +file. + +

+ + + diff --git a/doc/help/overview.html b/doc/help/overview.html new file mode 100644 index 0000000000..59a2ac0677 --- /dev/null +++ b/doc/help/overview.html @@ -0,0 +1,70 @@ + + + + Overview of CUPS + + + + +

Overview of CUPS

+ +

CUPS is the software you use to print from applications like the web browser +you are using to read this page. It converts the page descriptions +produced by your application (put a paragraph here, draw a line there, and so +forth) into something your printer can understand and then sends the information +to the printer for printing.

+ +

Now, since every printer manufacturer does things differently, printing can +be very complicated. CUPS does its best to hide this from you and your +application so that you can concentrate on printing and less on how to +print. Generally, the only time you need to know anything about your printer is +when you use it for the first time, and even then CUPS can often figure things +out on its own.

+ +

How Does It Work?

+ +

The first time you print to a printer, CUPS creates a queue to keep +track of the current status of the printer (everything OK, out of paper, etc.) +and any pages you have printed. Most of the time the queue points to a printer +connected directly to your computer via a USB or parallel port, however it can +also point to a printer on your network, a printer on the Internet, or multiple +printers depending on the configuration. Regardless of where the queue +points, it will look like any other printer to you and your applications.

+ +

Every time you print something, CUPS creates a job which contains +the queue you are sending the print to, the name of the document you are +printing, and the page descriptions. Job are numbered (queue-1, queue-2, and so +forth) so you can monitor the job as it is printed or cancel it if you see a +mistake. When CUPS gets a job for printing, it determines the best programs +(filters, printer drivers, port monitors, and +backends) to convert the pages into a printable format and then runs +them to actually print the job.

+ +

When the print job is completely printed, CUPS removes the job from the queue +and moves on to any other jobs you have submitted. You can also be notified when +the job is finished, or if there are any errors during printing, in several +different ways.

+ +

Where Do I Begin?

+ +

Click on the Administration tab at +the top of this page. Click on the Add Printer button and follow the +prompts.

+ +
When you are asked for a username and password, enter your login +username and password or the "root" username and password. On MacOS X, the login +username (or "short name") is typically your first and last name in +lowercase.
+ +

After the printer is added, CUPS will ask you to set the default printer +options (paper size, output mode, etc.) for the printer. Make any changes as +needed and then click on the Set Default Options button to save +them. Some printers also support auto-configuration - click on the Query +Printer for Default Options button to update the options automatically.

+ +

Once you have added the printer, you can print to it from any application. +You can also choose Print Test Page from the maintenance menu to print +a simple test page and verify that everything is working properly.

+ + + diff --git a/doc/help/policies.html b/doc/help/policies.html new file mode 100644 index 0000000000..14a5b4b870 --- /dev/null +++ b/doc/help/policies.html @@ -0,0 +1,601 @@ + + + + Managing Operation Policies + + + + +

Managing Operation Policies

+ +

Operation policies are the rules used for each IPP operation in CUPS. These rules include things like "user must provide a password", "user must be in the system group", "allow only from the local system", and so forth. Until CUPS 1.2, these rules were largely hardcoded and could only be customized at a very basic level.

+ +

CUPS 1.2 and later provides a fine-grained policy layer which allows you to completely redefine the rules for each operation and/or printer. Each policy is named and defines access control rules for each IPP operation. This document describes how to manage policies and their rules.

+ +

The Basics

+ +

Operation policies are used for all IPP requests sent to the scheduler and are evaluated after the Location based access control rules. This means that operation policies can only add additional security restrictions to a request, never relax them. Use Location based access control rules for server-wide limits and operation policies for limits on individual printers, tasks, or services.

+ +

Policies are stored in the cupsd.conf file in Policy sections. Each policy has an alphanumeric name that is used to select it. Inside the policy section are one or more Limit subsections which list the operations that are affected by the rules inside it. Listing 1 shows the default operation policy, appropriately called "default", that is shipped with CUPS.

+ +

The easiest way to add a policy to the cupsd.conf file is to use the web interface. Click on the Administration tab and then the Edit Configuration File button to edit the current cupsd.conf file. Click on the Save Changes button to save the changes and restart the scheduler. If you edit the cupsd.conf file from the console, make sure to restart the cupsd process before trying to use the new policy.

+ +
+Listing 1: Default Operation Policy
+
+ 1    <Policy default>
+ 2      # Job-related operations must be done by the owner or an
+      administrator...
+ 3      <Limit Send-Document Send-URI Hold-Job Release-Job
+      Restart-Job Purge-Jobs Set-Job-Attributes
+      Create-Job-Subscription Renew-Subscription
+      Cancel-Subscription Get-Notifications Reprocess-Job
+      Cancel-Current-Job Suspend-Current-Job Resume-Job
+      CUPS-Move-Job CUPS-Get-Document>
+ 4        Require user @OWNER @SYSTEM
+ 5        Order deny,allow
+ 6      </Limit>
+ 7    
+ 8      # All administration operations require an administrator
+      to authenticate...
+ 9      <Limit CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class
+      CUPS-Delete-Class CUPS-Set-Default>
+10        AuthType Default
+11        Require user @SYSTEM
+12        Order deny,allow
+13      </Limit>
+14    
+15      # All printer operations require a printer operator
+      to authenticate...
+16      <Limit Pause-Printer Resume-Printer
+      Set-Printer-Attributes Enable-Printer Disable-Printer
+      Pause-Printer-After-Current-Job Hold-New-Jobs
+      Release-Held-New-Jobs Deactivate-Printer Activate-Printer
+      Restart-Printer Shutdown-Printer Startup-Printer
+      Promote-Job Schedule-Job-After CUPS-Accept-Jobs
+      CUPS-Reject-Jobs>
+17        AuthType Default
+18        Require user varies by OS
+19        Order deny,allow
+20      </Limit>
+21    
+22      # Only the owner or an administrator can cancel or
+      authenticate a job...
+23      <Limit Cancel-Job CUPS-Authenticate-Job>
+24        Require user @OWNER @SYSTEM
+25        Order deny,allow
+26      </Limit>
+27    
+28      <Limit All>
+29        Order deny,allow
+30      </Limit>
+31    </Policy>
+
+ +

The Default CUPS Operation Policy

+ +

The policy definition starts with an opening Policy directive:

+ +
+ 1    <Policy default>
+
+ +

The first Limit subsection defines the rules for IPP job operations:

+ +
+ 3      <Limit Send-Document Send-URI Hold-Job Release-Job
+      Restart-Job Purge-Jobs Set-Job-Attributes
+      Create-Job-Subscription Renew-Subscription
+      Cancel-Subscription Get-Notifications Reprocess-Job
+      Cancel-Current-Job Suspend-Current-Job Resume-Job
+      CUPS-Move-Job CUPS-Get-Document>
+ 4        Require user @OWNER @SYSTEM
+ 5        Order deny,allow
+ 6      </Limit>
+
+ +

The operation names are listed on a single line with spaces separating them. Each name corresponds to the IPP operation described in any of the IETF or PWG standards documents for the Internet Printing Protocol. Table 1 lists all of the operations that have been defined along with their usage in CUPS.

+ +

The access control rules are listed after the Limit line and are the same as those used for Location sections. In this case, we require the owner of the job ("@OWNER") or a member of the SystemGroup ("@SYSTEM") to do the operation. Because we do not include an AuthType directive here, the user information can come from the IPP request itself or the authenticated username from the HTTP request. The administrative operations starting on line 9, however, do use the AuthType directive, and so administrative operations need to be authenticated:

+ +
+ 9      <Limit CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class
+      CUPS-Delete-Class CUPS-Set-Default>
+10        AuthType Default
+11        Require user @SYSTEM
+12        Order deny,allow
+13      </Limit>
+14    
+15      # All printer operations require a printer operator
+      to authenticate...
+16      <Limit Pause-Printer Resume-Printer
+      Set-Printer-Attributes Enable-Printer Disable-Printer
+      Pause-Printer-After-Current-Job Hold-New-Jobs
+      Release-Held-New-Jobs Deactivate-Printer Activate-Printer
+      Restart-Printer Shutdown-Printer Startup-Printer
+      Promote-Job Schedule-Job-After CUPS-Accept-Jobs
+      CUPS-Reject-Jobs>
+17        AuthType Default
+18        Require user varies by OS
+19        Order deny,allow
+20      </Limit>
+
+ +

The "Order deny,allow" line at the end of both Limit subsections allows the request to come from any system allowed by the Location sections elsewhere in the cupsd.conf file.

+ +

The Cancel-Job and CUPS-Authenticate-Job operations are listed separately to allow the web interface to more easily edit their policy without disturbing the rest. Like the rest of the job operations, we want the job's owner ("@OWNER") or an administrator ("@SYSTEM") to do it:

+ +
+16      <Limit Cancel-Job CUPS-Authenticate-Job>
+17        Require user @OWNER @SYSTEM
+18        Order deny,allow
+19      </Limit>
+
+ +

The last Limit subsection in any policy uses the special operation name All. CUPS will use the rules in this subsection for any operation you don't list specifically in the policy. In this case, all other operations are allowed without a username or authentication:

+ +
+21      <Limit All>
+22        Order deny,allow
+23      </Limit>
+24    </Policy>
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: IPP Operation Names
NameUsed by CUPS?Description
Print-JobYesCreates a print job with a single file.
Print-URINoCreate a print job with a single URI.
Validate-JobYesValidates a print request before printing.
Create-JobYesCreates a print job with no files or URIs.
Send-DocumentYesAdds a file to a print job.
Send-URINoAdds a URI to a print job.
Cancel-JobYesCancels a print job.
Get-Job-AttributesYesGets information and options associated with a job.
Get-JobsYesGets a list of jobs.
Get-Printer-AttributesYesGets information and options associated with a printer or class.
Hold-JobYesHolds a print job for printing.
Release-JobYesReleases a print job for printing.
Restart-JobYesReprints a print job.
Pause-PrinterYesStops a printer or class.
Resume-PrinterYesStarts a printer or class.
Purge-JobsYesCancels all jobs on the server or a printer or class + and removes the job history information.
Set-Printer-AttributesNoSets printer or class information; CUPS uses + CUPS-Add-Modify-Printer and CUPS-Add-Modify-Class + instead.
Set-Job-AttributesYesChanges job options.
Get-Printer-Supported-ValuesNoGets -supported attributes for a printer based on job + options.
Create-Printer-SubscriptionYesCreates an event subscription for a printer or the server.
Create-Job-SubscriptionYesCreates an event subscription for a job.
Get-Subscription-AttributesYesGets information for an event subscription.
Get-SubscriptionsYesGets a list of event subscriptions.
Renew-SubscriptionYesRenews an event subscription that is about to expire.
Cancel-SubscriptionYesCancels an event subscription.
Get-NotificationsYesGets (pending) events for an event subscription.
Send-NotificationsNoSends events for an event subscription.
Get-Printer-Support-FilesNoGets printer driver files for a Novell client.
Enable-PrinterYesStarts a printer or class.
Disable-PrinterYesStops a printer or class.
Pause-Printer-After-Current-JobNoStops a printer or class after the current job is finished.
Hold-New-JobsNoHolds new jobs submitted to a printer or class.
Release-Held-New-JobsNoReleases jobs that were held because of the + Hold-New-Jobs operation.
Deactivate-PrinterNoDeactivates a printer or class.
Activate-PrinterNoActivates a printer or class.
Restart-PrinterNoRestarts a printer or class, resuming print jobs as needed.
Shutdown-PrinterNoPowers a printer or class off.
Startup-PrinterNoPowers a printer or class on.
Reprocess-JobNoReprints a job on a different printer or class; CUPS has the + CUPS-Move-Job operation instead.
Cancel-Current-JobNoCancels the current job on a printer or class.
Suspend-Current-JobNoStops the current job on a printer or class.
Resume-JobNoResumes printing of a stopped job.
Promote-JobNoPrints a job before others.
Schedule-Job-AfterNoPrints a job after others.
CUPS-Get-DefaultYesGets the server/network default printer or class.
CUPS-Get-PrintersYesGets a list of printers and/or classes.
CUPS-Add-Modify-PrinterYesAdds or modifies a printer.
CUPS-Delete-PrinterYesRemoves a printer.
CUPS-Get-ClassesYesGets a list of classes.
CUPS-Add-Modify-ClassYesAdds or modifies a class.
CUPS-Delete-ClassYesRemoves a class.
CUPS-Accept-JobsYesSets a printer's or class' printer-is-accepting-jobs + attribute to true.
CUPS-Reject-JobsYesSets a printer's or class' printer-is-accepting-jobs + attribute to false.
CUPS-Set-DefaultYesSets the server/network default printer or class.
CUPS-Get-DevicesYesGets a list of printer devices.
CUPS-Get-PPDsYesGets a list of printer drivers or manufacturers.
CUPS-Move-JobYesMoves a job to a different printer or class.
CUPS-Authenticate-JobYesAuthenticates a job for printing.
CUPS-Get-DocumentYesRetrieves a document file from a job.
+ + +

Creating Your Own Policies

+ +

The easiest way to create a new policy is to start with the default policy and then make changes to the copy. The first change you'll make is to give the policy a new name. Policy names can use the same characters as a printer name, specifically all printable characters except space, slash (/), and pound (#):

+ +
+<Policy mypolicy>
+
+ +

Then you need to decide exactly what limits you want for the policy. For example, if you want to allow any user to cancel any other users' jobs, you can change the Cancel-Job limits to:

+ +
+<Limit Cancel-Job>
+  Order deny,allow
+</Limit>
+
+ +

The directives inside the Limit subsection can use any of the normal limiting directives: Allow, AuthType, Deny, Encryption, Require, and Satisfy. Table 2 lists some basic "recipes" for different access control rules.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Access Control Recipes
Access LevelDirectives to Use
Allow Everyone
Order deny,allow
+Allow from all
Allow Everyone on the Local Network
Order deny,allow
+Allow from @LOCAL
Deny Everyone/Disable Operation(s)
Order deny,allow
Require Login (System) Password
AuthType Basic
Require CUPS (lppasswd) Password
AuthType BasicDigest
Require Kerberos
AuthType Negotiate
Require the Owner of a Job or Subscription
Require user @OWNER
Require an Administrative User
Require user @SYSTEM
Require Member of Group "foogroup"
Require user @foogroup
Require "john" or "mary"
Require user john mary
Require Encryption
Encryption Required
+ + +

Creating a Policy for a Computer Lab

+ +

One common operating scenario is a computer lab. The lab is managed by one or more technicians that assist the users of the lab and handle the basic administration tasks. Listing 2 shows an operation policy that only allows access from the lab's subnet, 10.0.2.x, and allows the lab technicians, who are members of a special UNIX group for that lab called "lab999", to do job, printer, and subscription management operations.

+ +
+Listing 2: Operation Policy for a Lab
+
+ 1    <Policy lab999>
+ 2      # Job- and subscription-related operations must be done
+      by the owner, a lab technician, or an administrator...
+ 3      <Limit Send-Document Send-URI Hold-Job Release-Job
+      Restart-Job Purge-Jobs Set-Job-Attributes
+      Create-Job-Subscription Renew-Subscription
+      Cancel-Subscription Get-Notifications Reprocess-Job
+      Cancel-Current-Job Suspend-Current-Job Resume-Job
+      CUPS-Move-Job Cancel-Job CUPS-Authenticate-Job CUPS-Get-Document>
+ 4        Require user @OWNER @lab999 @SYSTEM
+ 5        Order allow,deny
+ 6        Allow from 10.0.2.0/24
+ 7      </Limit>
+ 8    
+ 9      # All administration operations require a lab technician
+      or an administrator to authenticate...
+10      <Limit Pause-Printer Resume-Printer
+      Set-Printer-Attributes Enable-Printer Disable-Printer
+      Pause-Printer-After-Current-Job Hold-New-Jobs
+      Release-Held-New-Jobs Deactivate-Printer Activate-Printer
+      Restart-Printer Shutdown-Printer Startup-Printer
+      Promote-Job Schedule-Job-After CUPS-Accept-Jobs
+      CUPS-Reject-Jobs CUPS-Set-Default>
+11        AuthType Default
+12        Require user @lab999 @SYSTEM
+13        Order allow,deny
+14        Allow from 10.0.2.0/24
+15      </Limit>
+16
+17      # All other operations are allowed from the lab network...
+18      <Limit All>
+19        Order allow,deny
+20        Allow from 10.0.2.0/24
+21      </Limit>
+22    </Policy>
+
+ + +

Using Policies

+ +

Once you have created a policy, you can use it in two ways. The first way is to assign it as the default policy for the system using the DefaultPolicy directive in the cupsd.conf file. For example, add the following line to the cupsd.conf file to use the "lab999" policy from the previous section:

+ +
+DefaultPolicy lab999
+
+ +

To associate the policy with one or more printers, use either the lpadmin(8) command or the web interface to change the operation policy for each printer. When using the lpadmin command, the -o printer-op-policy=name option sets the operation policy for a printer. For example, enter the following command to use the "lab999" policy from the previous section with a printer named "LaserJet4000":

+ +
+lpadmin -p LaserJet4000 -o printer-op-policy=lab999
+
+ +

To make the same change in the web interface, go to the printer's web page, for example "http://localhost:631/printers/LaserJet4000", and choose Set Default Options from the Administration menu button. Click on the Policies link and choose the desired policy from the pull-down list. Click on Set Default Options to change the policy for the printer.

+ + + diff --git a/doc/help/postscript-driver.html b/doc/help/postscript-driver.html new file mode 100644 index 0000000000..c2b35b7e72 --- /dev/null +++ b/doc/help/postscript-driver.html @@ -0,0 +1,645 @@ + + + + +Developing PostScript Printer Drivers + + + + + +
+

Developing PostScript Printer Drivers

+ +

This document describes how to develop printer drivers for PostScript printers. Topics include: printer driver basics, creating new PPD files, importing existing PPD files, using custom filters, implementing color management, and adding Mac OS X features.

+ +
+ + + + + + +
See AlsoProgramming: Developing Raster Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Introduction to the PPD Compiler
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
+

Contents

+
    +
      +
    • Printer Driver Basics
    • +
    • Creating New PPD Files
    • +
    • Using Custom Filters
    • +
    • Implementing Color Management
    • +
    • Adding Mac OS X Features
    • +

      Printer Driver Basics

      + +

      A CUPS PostScript printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, zero or more filter programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.

      + +

      Every time a user prints something the scheduler program, cupsd(8), determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into device-independent PostScript, and then from device-independent PostScript to device-dependent PostScript. Figure 1 shows the data flow of a typical print job.

      + +
      + + +
      Figure 1: PostScript Filter Chain
      PostScript Filter Chain
      + +

      The optional PostScript filter can be provided to add printer-specific commands to the PostScript output that cannot be represented in the PPD file or to reorganize the output for special printer features. Typically this is used to support advanced job management or finishing functions on the printer. CUPS includes a generic PostScript filter that handles all PPD-defined commands.

      + +

      The optional port monitor handles interface-specific protocol or encoding issues. For example, many PostScript printers support the Binary Communications Protocol (BCP) and Tagged Binary Communications Protocol (TBCP) to allow applications to print 8-bit ("binary") PostScript jobs. CUPS includes port monitors for BCP and TBCP, and you can supply your own port monitors as needed.

      + +

      The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.

      + +

      The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. Figure 2 shows the data flow of a typical command job.

      + +
      + + +
      Figure 2: Command Filter Chain
      Command Filter Chain
      + +

      PostScript printer drivers typically do not require their own command filter since CUPS includes a generic PostScript command filter that supports all of the standard functions using PPD-defined commands.

      + + +

      Creating New PPD Files

      + +

      We recommend using the CUPS PPD compiler, ppdc(1), to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "Introduction to the PPD Compiler" document. Listing 1 shows a driver information file for a black-and-white PostScript printer.

      + +

      Listing 1: "examples/postscript.drv"

      + +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// Specify this is a PostScript printer driver
      +DriverType ps
      +
      +// List the fonts that are supported, in this case all standard fonts
      +Font *
      +
      +// Manufacturer, model name, and version
      +Manufacturer "Foo"
      +ModelName "Foo LaserProofer 2000"
      +Version 1.0
      +
      +// PostScript printer attributes
      +Attribute DefaultColorSpace "" Gray
      +Attribute LandscapeOrientation "" Minus90
      +Attribute LanguageLevel "" "3"
      +Attribute Product "" "(Foo LaserProofer 2000)"
      +Attribute PSVersion "" "(3010) 0"
      +Attribute TTRasterizer "" Type42
      +
      +// Supported page sizes
      +*MediaSize Letter
      +MediaSize Legal
      +MediaSize A4
      +
      +// Query command for page size
      +Attribute "?PageSize" "" "
      +      save
      +      currentpagedevice /PageSize get aload pop
      +      2 copy gt {exch} if (Unknown)
      +      23 dict
      +              dup [612 792] (Letter) put
      +              dup [612 1008] (Legal) put
      +              dup [595 842] (A4) put
      +              {exch aload pop 4 index sub abs 5 le exch 
      +               5 index sub abs 5 le and
      +              {exch pop exit} {pop} ifelse
      +      } bind forall = flush pop pop
      +      restore"
      +
      +// Specify the name of the PPD file we want to generate
      +PCFileName "fooproof.ppd"
      +
      + +

      Required Attributes

      + +

      PostScript drivers require the attributes listed in Table 1. If not specified, the defaults for CUPS drivers are used. A typical PostScript driver information file would include the following attributes:

      + +
      +Attribute DefaultColorSpace "" Gray
      +Attribute LandscapeOrientation "" Minus90
      +Attribute LanguageLevel "" "3"
      +Attribute Product "" "(Foo LaserProofer 2000)"
      +Attribute PSVersion "" "(3010) 0"
      +Attribute TTRasterizer "" Type42
      +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Table 1: Required PostScript Printer Driver Attributes
      AttributeDescription
      DefaultColorSpaceThe default colorspace: + Gray, RGB, CMY, or + CMYK. If not specified, then RGB is + assumed.
      LandscapeOrientationThe preferred landscape + orientation: Plus90, Minus90, or + Any. If not specified, Plus90 is + assumed.
      LanguageLevelThe PostScript language + level supported by the device: 1, 2, or 3. If not + specified, 2 is assumed.
      ProductThe string returned by + the PostScript product operator, which + must include parenthesis to conform with + PostScript syntax rules for strings. Multiple + Product attributes may be specified to support + multiple products with the same PPD file. If not + specified, "(ESP Ghostscript)" and "(GNU Ghostscript)" + are assumed.
      PSVersionThe PostScript + interpreter version numbers as returned by the + version and revision operators. The + required format is "(version) revision". Multiple + PSVersion attributes may be specified to + support multiple interpreter version numbers. If not + specified, "(3010) 705" and "(3010) 707" are + assumed.
      TTRasterizerThe type of TrueType + font rasterizer supported by the device, if any. The + supported values are None, Accept68k, + Type42, and TrueImage. If not + specified, None is assumed.
      + +

      Query Commands

      + +

      Most PostScript printer PPD files include query commands (?PageSize, etc.) that allow applications to query the printer for its current settings and configuration. Query commands are included in driver information files as attributes. For example, the example in Listing 1 uses the following definition for the PageSize query command:

      + +
      +Attribute "?PageSize" "" "
      +      save
      +      currentpagedevice /PageSize get aload pop
      +      2 copy gt {exch} if (Unknown)
      +      23 dict
      +              dup [612 792] (Letter) put
      +              dup [612 1008] (Legal) put
      +              dup [595 842] (A4) put
      +              {exch aload pop 4 index sub abs 5 le exch 
      +               5 index sub abs 5 le and
      +              {exch pop exit} {pop} ifelse
      +      } bind forall = flush pop pop
      +      restore"
      +
      + +

      Query commands can span multiple lines, however no single line may contain more than 255 characters.

      + +

      Importing Existing PPD Files

      + +

      CUPS includes a utility called ppdi(1) +which allows you to import existing PPD files into the driver information file +format used by the PPD compiler ppdc(1). Once +imported, you can modify, localize, and regenerate the PPD files easily. Type +the following command to import the PPD file mydevice.ppd into the +driver information file mydevice.drv:

      + +
      +ppdi -o mydevice.drv mydevice.ppd
      +
      + +

      If you have a whole directory of PPD files that you would like to import, +you can list multiple filenames or use shell wildcards to import more than one +PPD file on the command-line:

      + +
      +ppdi -o mydevice.drv mydevice1.ppd mydevice2.ppd
      +ppdi -o mydevice.drv *.ppd
      +
      + +

      If the driver information file already exists, the new PPD +file entries are appended to the end of the file. Each PPD file +is placed in its own group of curly braces within the driver +information file.

      + + +

      Using Custom Filters

      + +

      Normally a PostScript printer driver will not utilize any additional print filters. For drivers that provide additional filters such as a CUPS command file filter for doing printer maintenance, you must also list the following Filter directive to handle printing PostScript files:

      + +
      +Filter application/vnd.cups-postscript 0 -
      +
      + +

      Custom Command Filters

      + +

      The application/vnd.cups-command file type is used for CUPS command files. Use the following Filter directive to handle CUPS command files:

      + +
      +Filter application/vnd.cups-command 100 /path/to/command/filter
      +
      + +

      To use the standard PostScript command filter, specify commandtops as the path to the command filter.

      + +

      Custom PDF Filters

      + +

      The application/pdf file type is used for unfiltered PDF files while the application/vnd.cups-pdf file type is used for filtered PDF files. Use the following Filter directive to handle filtered PDF files:

      + +
      +Filter application/vnd.cups-pdf 100 /path/to/pdf/filter
      +
      + +

      For unfiltered PDF files, use:

      + +
      +Filter application/pdf 100 /path/to/pdf/filter
      +
      + +

      Custom PDF filters that accept filtered data do not need to perform number-up processing and other types of page imposition, while those that accept unfiltered data MUST do the number-up processing themselves.

      + +

      Custom PostScript Filters

      + +

      The application/vnd.cups-postscript file type is used for filtered PostScript files. Use the following Filter directive to handle PostScript files:

      + +
      +Filter application/vnd.cups-postscript 100 /path/to/postscript/filter
      +
      + + +

      Implementing Color Management

      + +

      CUPS uses ICC color profiles to provide more accurate color reproduction. The cupsICCProfile attribute defines the color profiles that are available for a given printer, for example:

      + +
      +Attribute cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
      +
      + +

      where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:

      + +
      +Attribute cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
      +Attribute cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
      +
      + +

      The options used for profile selection can be customized using the cupsICCQualifier2 and cupsICCQualifier3 attributes.

      + + +

      Adding Mac OS X Features

      + +

      Mac OS X printer drivers can provide additional attributes to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:

      + +
      +Attribute APDialogExtension "" /Library/Printers/Vendor/filename.plugin
      +Attribute APHelpBook "" /Library/Printers/Vendor/filename.bundle
      +Attribute APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
      +Attribute APPrinterPreset "name/text" "*option choice ..."
      +
      +
+ + diff --git a/doc/help/ppd-compiler.html b/doc/help/ppd-compiler.html new file mode 100644 index 0000000000..d0aedaf254 --- /dev/null +++ b/doc/help/ppd-compiler.html @@ -0,0 +1,1261 @@ + + + + +Introduction to the PPD Compiler + + + + + +
+

Introduction to the PPD Compiler

+ +

This document describes how to use the CUPS PostScript Printer Description +(PPD) file compiler. The PPD compiler generates PPD files from simple text files +that describe the features and capabilities of one or more printers.

+ +
+ + + + + + +
See AlsoProgramming: Developing Raster Printer Drivers
+ Programming: Developing PostScript Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
+

Contents

+
    +
      +
    • The Basics
    • +
    • Driver Information Files
    • +
    • Localization
    • +

      The Basics

      + +

      The PPD compiler, ppdc(1), is a +simple command-line tool that takes a single driver information file, +which by convention uses the extension .drv, and produces one or more +PPD files that may be distributed with your printer drivers for use with CUPS. +For example, you would run the following command to create the English language +PPD files defined by the driver information file mydrivers.drv:

      + +
      +ppdc mydrivers.drv
      +
      + +

      The PPD files are placed in a subdirectory called +ppd. The -d option is used to put the PPD +files in a different location, for example:

      + +
      +ppdc -d myppds mydrivers.drv
      +
      + +

      places the PPD files in a subdirectory named +myppds. Finally, use the -l option to +specify the language localization for the PPD files that are +created, for example:

      + +
      +ppdc -d myppds/de -l de mydrivers.drv
      +ppdc -d myppds/en -l en mydrivers.drv
      +ppdc -d myppds/es -l es mydrivers.drv
      +ppdc -d myppds/fr -l fr mydrivers.drv
      +ppdc -d myppds/it -l it mydrivers.drv
      +
      + +

      creates PPD files in German (de), English (en), Spanish (es), +French (fr), and Italian (it) in the corresponding +subdirectories. Specify multiple languages (separated by commas) to produce +"globalized" PPD files:

      + +
      +ppdc -d myppds -l de,en,es,fr,it mydrivers.drv
      +
      + + +

      Driver Information Files

      + +

      The driver information files accepted by the PPD compiler are +plain text files that define the various attributes and options +that are included in the PPD files that are generated. A driver +information file can define the information for one or more printers and +their corresponding PPD files.

      + +

      Listing 1: "examples/minimum.drv"

      + +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// List the fonts that are supported, in this case all standard fonts...
      +Font *
      +
      +// Manufacturer, model name, and version
      +Manufacturer "Foo"
      +ModelName "FooJet 2000"
      +Version 1.0
      +
      +// Each filter provided by the driver...
      +Filter application/vnd.cups-raster 100 rastertofoo
      +
      +// Supported page sizes
      +*MediaSize Letter
      +MediaSize A4
      +
      +// Supported resolutions
      +*Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      +// Specify the name of the PPD file we want to generate...
      +PCFileName "foojet2k.ppd"
      +
      + + +

      A Simple Example

      + +

      The example in Listing 1 shows a driver information +file which defines the minimum required attributes to provide a valid PPD file. +The first part of the file includes standard definition files for fonts and +media sizes:

      + +
      +#include <font.defs>
      +#include <media.defs>
      +
      + +

      The #include directive works just like the C/C++ include directive; +files included using the angle brackets (<filename>) are found +in any of the standard include directories and files included using quotes +("filename") are found in the same directory as the source or include +file. The <font.defs> include file defines the standard fonts +which are included with GPL Ghostscript and the Apple PDF RIP, while the +<media.defs> include file defines the standard media sizes +listed in Appendix B of the Adobe PostScript Printer Description File Format +Specification.

      + +

      CUPS provides several other standard include files:

      + +
        + +
      • <epson.h> - Defines all of the rastertoepson driver + constants.
      • + +
      • <escp.h> - Defines all of the rastertoescpx driver + constants.
      • + +
      • <hp.h> - Defines all of the rastertohp driver + constants.
      • + +
      • <label.h> - Defines all of the rastertolabel driver + constants.
      • + +
      • <pcl.h> - Defines all of the rastertopclx driver + constants.
      • + +
      • <raster.defs> - Defines all of the CUPS raster format + constants.
      • + +
      + +

      Next we list all of the fonts that are available in the driver; for CUPS +raster drivers, the following line is all that is usually supplied:

      + +
      +Font *
      +
      + +

      The Font directive specifies the name of a single font or the +asterisk to specify all fonts. For example, you would use the following line to +define an additional bar code font that you are supplying with your printer +driver:

      + +
      +//   name         encoding  version  charset  status
      +Font Barcode-Foo  Special   "(1.0)"  Special  ROM
      +
      + +

      The name of the font is Barcode-Foo. Since it is not a standard +text font, the encoding and charset name Special is used. The version +number is 1.0 and the status (where the font is located) is +ROM to indicate that the font does not need to be embedded in +documents that use the font for this printer.

      + +

      Third comes the manufacturer, model name, and version number information +strings:

      + +
      +Manufacturer "Foo"
      +ModelName "FooJet 2000"
      +Version 1.0
      +
      + +

      These strings are used when the user (or auto-configuration program) selects +the printer driver for a newly connected device.

      + +

      The list of filters comes after the information strings; for the example in +Listing 1, we have a single filter that takes CUPS +raster data:

      + +
      +Filter application/vnd.cups-raster 100 rastertofoo
      +
      + +

      Each filter specified in the driver information file is the equivalent of a +printer driver for that format; if a user submits a print job in a different +format, CUPS figures out the sequence of commands that will produce a supported +format for the least relative cost.

      + +

      Once we have defined the driver information we specify the supported options. +For the example driver we support a single resolution of 600 dots per inch and +two media sizes, A4 and Letter:

      + +
      +*MediaSize Letter
      +MediaSize A4
      +
      +*Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      + +

      The asterisk in front of the MediaSize and Resolution +directives specify that those option choices are the default. The +MediaSize directive is followed by a media size name which is normally +defined in the <media.defs> file and corresponds to a standard +Adobe media size name. If the default media size is Letter, the PPD +compiler will override it to be A4 for non-English localizations for +you automatically.

      + +

      The Resolution directive accepts several values after it as +follows:

      + +
        + +
      1. Colorspace for this resolution, if any. In the example file, the + colorspace k is used which corresponds to black. For printer + drivers that support color printing, this field is usually specified as + "-" for "no change".
      2. + +
      3. Bits per color. In the example file, we define 8 bits per color, for + a continuous-tone grayscale output. All versions of CUPS support 1 and + 8 bits per color. CUPS 1.2 and higher (Mac OS X 10.5 and higher) also + supports 16 bits per color.
      4. + +
      5. Rows per band. In the example file, we define 0 rows per band to + indicate that our printer driver does not process the page in + bands.
      6. + +
      7. Row feed. In the example, we define the feed value to be 0 to + indicate that our printer driver does not interleave the output.
      8. + +
      9. Row step. In the example, we define the step value to be 0 to + indicate that our printer driver does not interleave the output. This + value normally indicates the spacing between the nozzles of an inkjet + printer - when combined with the previous two values, it informs the + driver how to stagger the output on the page to produce interleaved + lines on the page for higher-resolution output.
      10. + +
      11. Choice name and text. In the example, we define the choice name and + text to be "600dpi/600 DPI". The name and text are separated by + slash (/) character; if no text is specified, then the name is + used as the text. The PPD compiler parses the name to determine the + actual resolution; the name can be of the form + RESOLUTIONdpi for resolutions that are equal + horizontally and vertically or HRESxVRESdpi for + isometric resolutions. Only integer resolution values are supported, so + a resolution name of 300dpi is valid while 300.1dpi is + not.
      12. + +
      + +

      Finally, the PCFileName directive specifies that the named PPD file +should be written for the current driver definitions:

      + +
      +PCFileName "foojet2k.ppd"
      +
      + +

      The filename follows the directive and must conform to the Adobe +filename requirements in the Adobe Postscript Printer Description File Format +Specification. Specifically, the filename may not exceed 8 characters followed +by the extension .ppd. The FileName directive can be used to +specify longer filenames:

      + +
      +FileName "FooJet 2000"
      +
      + + +

      Grouping and Inheritance

      + +

      The previous example created a single PPD file. Driver information files can +also define multiple printers by using the PPD compiler grouping functionality. +Directives are grouped using the curly braces ({ and }) and +every group that uses the PCFileName or FileName directives +produces a PPD file with that name. Listing 2 shows a +variation of the original example that uses two groups to define two printers +that share the same printer driver filter but provide two different resolution +options.

      + +

      Listing 2: "examples/grouping.drv"

      + +
      +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// List the fonts that are supported, in this case all standard fonts...
      +Font *
      +
      +// Manufacturer and version
      +Manufacturer "Foo"
      +Version 1.0
      +
      +// Each filter provided by the driver...
      +Filter application/vnd.cups-raster 100 rastertofoo
      +
      +// Supported page sizes
      +*MediaSize Letter
      +MediaSize A4
      +
      +{
      +  // Supported resolutions
      +  *Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      +  // Specify the model name and filename...
      +  ModelName "FooJet 2000"
      +  PCFileName "foojet2k.ppd"
      +}
      +
      +{
      +  // Supported resolutions
      +  *Resolution k 8 0 0 0 "1200dpi/1200 DPI"
      +
      +  // Specify the model name and filename...
      +  ModelName "FooJet 2001"
      +  PCFileName "foojt2k1.ppd"
      +}
      +
      + +

      The second example is essentially the same as the first, except that each +printer model is defined inside of a pair of curly braces. For example, the +first printer is defined using:

      + +
      +{
      +  // Supported resolutions
      +  *Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      +  // Specify the model name and filename...
      +  ModelName "FooJet 2000"
      +  PCFileName "foojet2k.ppd"
      +}
      +
      + +

      The printer inherits all of the definitions from the parent group (the +top part of the file) and adds the additional definitions inside the curly +braces for that printer driver. When we define the second group, it also +inherits the same definitions from the parent group but none of the +definitions from the first driver. Groups can be nested to any number of levels +to support variations of similar models without duplication of information.

      + + +

      Color Support

      + +

      For printer drivers that support color printing, the +ColorDevice and ColorModel directives should be +used to tell the printing system that color output is desired +and in what formats. Listing 3 shows a +variation of the previous example which includes a color printer +that supports printing at 300 and 600 DPI.

      + +

      The key changes are the addition of the ColorDevice +directive:

      + +
      +ColorDevice true
      +
      + +

      which tells the printing system that the printer supports +color printing, and the ColorModel directives:

      + +
      +ColorModel Gray/Grayscale w chunky 0
      +*ColorModel RGB/Color rgb chunky 0
      +
      + +

      which tell the printing system which colorspaces are supported by the printer +driver for color printing. Each of the ColorModel directives is +followed by the option name and text (Gray/Grayscale and +RGB/Color), the colorspace name (w and rgb), the +color organization (chunky), and the compression mode number +(0) to be passed to the driver. The option name can be any of the +standard Adobe ColorModel names:

      + +
        + +
      • Gray - Grayscale output. + +
      • RGB - Color output, typically using the RGB + colorspace, but without a separate black channel. + +
      • CMYK - Color output with a separate black + channel. + +
      + +

      Custom names can be used, however it is recommended that you use your vendor +prefix for any custom names, for example "fooName".

      + +

      The colorspace name can be any of the following universally supported +colorspaces:

      + +
        +
      • w - Luminance
      • + +
      • rgb - Red, green, blue
      • + +
      • k - Black
      • + +
      • cmy - Cyan, magenta, yellow
      • + +
      • cmyk - Cyan, magenta, yellow, black
      • + +
      + +

      The color organization can be any of the following values:

      + +
        + +
      • chunky - Color values are passed together on a line + as RGB RGB RGB RGB
      • + +
      • banded - Color values are passed separately + on a line as RRRR GGGG BBBB; not supported by the Apple + RIP filters
      • + +
      • planar - Color values are passed separately + on a page as RRRR RRRR RRRR ... GGGG GGGG GGGG ... BBBB + BBBB BBBB; not supported by the Apple RIP filters
      • + +
      + +

      The compression mode value is passed to the driver in the +cupsCompression attribute. It is traditionally used to select an +appropriate compression mode for the color model but can be used for any +purpose, such as specifying a photo mode vs. standard mode.

      + +

      Listing 3: "examples/color.drv"

      + +
      +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// List the fonts that are supported, in this case all standard fonts...
      +Font *
      +
      +// Manufacturer and version
      +Manufacturer "Foo"
      +Version 1.0
      +
      +// Each filter provided by the driver...
      +Filter application/vnd.cups-raster 100 rastertofoo
      +
      +// Supported page sizes
      +*MediaSize Letter
      +MediaSize A4
      +
      +{
      +  // Supported resolutions
      +  *Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      +  // Specify the model name and filename...
      +  ModelName "FooJet 2000"
      +  PCFileName "foojet2k.ppd"
      +}
      +
      +{
      +  // Supports color printing
      +  ColorDevice true
      +
      +  // Supported colorspaces
      +  ColorModel Gray/Grayscale w chunky 0
      +  *ColorModel RGB/Color rgb chunky 0
      +
      +  // Supported resolutions
      +  *Resolution - 8 0 0 0 "300dpi/300 DPI"
      +  Resolution - 8 0 0 0 "600dpi/600 DPI"
      +
      +  // Specify the model name and filename...
      +  ModelName "FooJet Color"
      +  PCFileName "foojetco.ppd"
      +}
      +
      + + +

      Defining Custom Options and Option Groups

      + +

      The Group, Option, and Choice +directives are used to define or select a group, option, or +choice. Listing 4 shows a variation of +the first example that provides two custom options in a group +named "Footasm".

      + +

      Listing 4: "examples/custom.drv"

      + +
      +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// List the fonts that are supported, in this case all standard fonts...
      +Font *
      +
      +// Manufacturer, model name, and version
      +Manufacturer "Foo"
      +ModelName "FooJet 2000"
      +Version 1.0
      +
      +// Each filter provided by the driver...
      +Filter application/vnd.cups-raster 100 rastertofoo
      +
      +// Supported page sizes
      +*MediaSize Letter
      +MediaSize A4
      +
      +// Supported resolutions
      +*Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      +// Option Group
      +Group "Footasm"
      +
      +  // Boolean option
      +  Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
      +    *Choice True/Yes "<</cupsCompression 1>>setpagedevice"
      +    Choice False/No "<</cupsCompression 0>>setpagedevice"
      +
      +  // Multiple choice option
      +  Option "fooOutputType/Output Quality" PickOne AnySetup 10
      +    *Choice "Auto/Automatic Selection"
      +            "<</OutputType(Auto)>>setpagedevice""
      +    Choice "Text/Optimize for Text"
      +            "<</OutputType(Text)>>setpagedevice""
      +    Choice "Graph/Optimize for Graphics"
      +            "<</OutputType(Graph)>>setpagedevice""
      +    Choice "Photo/Optimize for Photos"
      +            "<</OutputType(Photo)>>setpagedevice""
      +
      +// Specify the name of the PPD file we want to generate...
      +PCFileName "foojet2k.ppd"
      +
      + +

      The custom group is introduced by the Group +directive which is followed by the name and optionally text for +the user:

      + +
      +Group "Footasm/Footastic Options"
      +
      + +

      The group name must conform to the PPD specification and +cannot exceed 40 characters in length. If you specify user text, +it cannot exceed 80 characters in length. The groups +General, Extra, and +InstallableOptions are predefined by CUPS; the general +and extra groups are filled by the UI options defined by the PPD +specification. The InstallableOptions group is reserved +for options that define whether accessories for the printer +(duplexer unit, finisher, stapler, etc.) are installed.

      + +

      Once the group is specified, the Option directive is +used to introduce a new option:

      + +
      +Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
      +
      + +

      The directive is followed by the name of the option and any +optional user text, the option type, the PostScript document group, and +the sort order number. The option name must conform to the PPD specification +and cannot exceed 40 characters in length. If you specify user text, it +cannot exceed 80 characters in length.

      + +

      The option type can be Boolean for true/false +selections, PickOne for picking one of many choices, or +PickMany for picking zero or more choices. Boolean +options can have at most two choices with the names +False and True. Pick options can have any +number of choices, although for Windows compatibility reasons +the number of choices should not exceed 255.

      + +

      The PostScript document group is typically AnySetup, +meaning that the option can be introduced at any point in the +PostScript document. Other values include PageSetup to +include the option before each page and DocumentSetup +to include the option once at the beginning of the document.

      + +

      The sort order number is used to sort the printer commands +associated with each option choice within the PostScript +document. This allows you to setup certain options before others +as required by the printer. For most CUPS raster printer +drivers, the value 10 can be used for all options.

      + +

      Once the option is specified, each option choice can be +listed using the Choice directive:

      + +
      +*Choice True/Yes "<</cupsCompression 1>>setpagedevice"
      +Choice False/No "<</cupsCompression 0>>setpagedevice"
      +
      + +

      The directive is followed by the choice name and optionally +user text, and the PostScript commands that should be inserted +when printing a file to this printer. The option name must +conform to the PPD specification and cannot exceed 40 characters +in length. If you specify user text, it cannot exceed 80 +characters in length.

      + +

      The PostScript commands are also interpreted by any RIP +filters, so these commands typically must be present for all +option choices. Most commands take the form:

      + +
      +<</name value>>setpagedevice
      +
      + +

      where name is the name of the PostScript page device +attribute and value is the numeric or string value for +that attribute.

      + + +

      Defining Constants

      + +

      Sometimes you will want to define constants for your drivers +so that you can share values in different groups within the same +driver information file, or to share values between different +driver information files using the #include directive. +The #define directive is used to define constants for +use in your printer definitions:

      + +
      +#define NAME value
      +
      + +

      The NAME is any sequence of letters, numbers, and +the underscore. The value is a number or string; if the +value contains spaces you must put double quotes around it, for +example:

      + +
      +#define FOO "My String Value"
      +
      + +

      Constants can also be defined on the command-line using the -D +option:

      + +
      +ppdc -DNAME="value" filename.drv
      +
      + +

      Once defined, you use the notation $NAME to substitute the value of +the constant in the file, for example:

      + +
      +#define MANUFACTURER "Foo"
      +#define FOO_600      0
      +#define FOO_1200     1
      +
      +{
      +  Manufacturer "$MANUFACTURER"
      +  ModelNumber $FOO_600
      +  ModelName "FooJet 2000"
      +  ...
      +}
      +
      +{
      +  Manufacturer "$MANUFACTURER"
      +  ModelNumber $FOO_1200
      +  ModelName "FooJet 2001"
      +  ...
      +}
      +
      + +

      Numeric constants can be bitwise OR'd together by placing the constants +inside parenthesis, for example:

      + +
      +// ModelNumber capability bits
      +#define DUPLEX 1
      +#define COLOR  2
      +
      +...
      +
      +{
      +  // Define a model number specifying the capabilities of the printer...
      +  ModelNumber ($DUPLEX $COLOR)
      +  ...
      +}
      +
      + + +

      Conditional Statements

      + +

      The PPD compiler supports conditional compilation using the #if, +#elif, #else, and #endif directives. The #if +and #elif directives are followed by a constant name or an expression. +For example, to include a group of options when "ADVANCED" is defined:

      + +
      +#if ADVANCED
      +Group "Advanced/Advanced Options"
      +  Option "fooCyanAdjust/Cyan Adjustment"
      +    Choice "plus10/+10%" ""
      +    Choice "plus5/+5%" ""
      +    *Choice "none/No Adjustment" ""
      +    Choice "minus5/-5%" ""
      +    Choice "minus10/-10%" ""
      +  Option "fooMagentaAdjust/Magenta Adjustment"
      +    Choice "plus10/+10%" ""
      +    Choice "plus5/+5%" ""
      +    *Choice "none/No Adjustment" ""
      +    Choice "minus5/-5%" ""
      +    Choice "minus10/-10%" ""
      +  Option "fooYellowAdjust/Yellow Adjustment"
      +    Choice "plus10/+10%" ""
      +    Choice "plus5/+5%" ""
      +    *Choice "none/No Adjustment" ""
      +    Choice "minus5/-5%" ""
      +    Choice "minus10/-10%" ""
      +  Option "fooBlackAdjust/Black Adjustment"
      +    Choice "plus10/+10%" ""
      +    Choice "plus5/+5%" ""
      +    *Choice "none/No Adjustment" ""
      +    Choice "minus5/-5%" ""
      +    Choice "minus10/-10%" ""
      +#endif
      +
      + + +

      Defining Constraints

      + +

      Constraints are strings that are used to specify that one or more option +choices are incompatible, for example two-sided printing on transparency media. +Constraints are also used to prevent the use of uninstalled features such as the +duplexer unit, additional media trays, and so forth.

      + +

      The UIConstraints directive is used to specify a constraint that is +placed in the PPD file. The directive is followed by a string using one of the +following formats:

      + +
      +UIConstraints "*Option1 *Option2"
      +UIConstraints "*Option1 Choice1 *Option2"
      +UIConstraints "*Option1 *Option2 Choice2"
      +UIConstraints "*Option1 Choice1 *Option2 Choice2"
      +
      + +

      Each option name is preceded by the asterisk (*). If no choice is +given for an option, then all choices except False and +None will conflict with the other option and choice(s). Since the PPD +compiler automatically adds reciprocal constraints (option A conflicts with +option B, so therefore option B conflicts with option A), you need only specify +the constraint once.

      + +

      Listing 5: "examples/constraint.drv"

      + +
      +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// List the fonts that are supported, in this case all standard fonts...
      +Font *
      +
      +// Manufacturer, model name, and version
      +Manufacturer "Foo"
      +ModelName "FooJet 2000"
      +Version 1.0
      +
      +// Each filter provided by the driver...
      +Filter application/vnd.cups-raster 100 rastertofoo
      +
      +// Supported page sizes
      +*MediaSize Letter
      +MediaSize A4
      +
      +// Supported resolutions
      +*Resolution k 8 0 0 0 "600dpi/600 DPI"
      +
      +// Installable Option Group
      +Group "InstallableOptions/Options Installed"
      +
      +  // Duplexing unit option
      +  Option "OptionDuplexer/Duplexing Unit" Boolean AnySetup 10
      +    Choice True/Installed ""
      +    *Choice "False/Not Installed" ""
      +
      +// General Option Group
      +Group General
      +
      +  // Duplexing option
      +  Option "Duplex/Two-Sided Printing" PickOne AnySetup 10
      +    *Choice "None/No" "<</Duplex false>>setpagedevice""
      +    Choice "DuplexNoTumble/Long Edge Binding"
      +           "<</Duplex true/Tumble false>>setpagedevice""
      +    Choice "DuplexTumble/Short Edge Binding"
      +           "<</Duplex true/Tumble true>>setpagedevice""
      +
      +// Only allow duplexing if the duplexer is installed
      +UIConstraints "*Duplex *OptionDuplexer False"
      +
      +// Specify the name of the PPD file we want to generate...
      +PCFileName "foojet2k.ppd"
      +
      + +

      Listing 5 shows a variation of the first example with +an added Duplex option and installable option for the duplexer, +OptionDuplex. A constraint is added at the end to specify that any +choice of the Duplex option that is not None is incompatible +with the "Duplexer Installed" option set to "Not Installed" +(False):

      + +
      +UIConstraints "*Duplex *OptionDuplexer False"
      +
      + +

      Enhanced Constraints

      + +

      CUPS 1.4 supports constraints between 2 or more options using the +Attribute directive. cupsUIConstraints attributes define +the constraints, while cupsUIResolver attributes define option changes +to resolve constraints. For example, we can specify the previous duplex +constraint with a resolver that turns off duplexing with the following two +lines:

      + +
      +Attribute cupsUIConstraints DuplexOff "*Duplex *OptionDuplexer False"
      +Attribute cupsUIResolver DuplexOff "*Duplex None"
      +
      + +

      Localization

      + +

      The PPD compiler provides localization of PPD files in different languages +through message catalog files in the GNU gettext or Apple .strings +formats. Each user text string and several key PPD attribute values such as +LanguageVersion and LanguageEncoding are looked up in the +corresponding message catalog and the translated text is substituted in the +generated PPD files. One message catalog file can be used by multiple driver +information files, and each file contains a single language translation.

      + +

      The ppdpo Utility

      + +

      While CUPS includes localizations of all standard media sizes and options in +several languages, your driver information files may provide their own media +sizes and options that need to be localized. CUPS provides a utility program to +aid in the localization of drivers called ppdpo(1). The ppdpo program creates +or updates a message catalog file based upon one or more driver information +files. New messages are added with the word "TRANSLATE" added to the front of +the translation string to make locating new strings for translation easier. The +program accepts the message catalog filename and one or more driver information +files.

      + +

      For example, run the following command to create a new German message catalog +called de.po for all of the driver information files in the current +directory:

      + +
      +ppdpo -o de.po *.drv
      +
      + +

      If the file de.po already exists, ppdpo will update the +contents of the file with any new messages that need to be translated. To create +an Apple .strings file instead, specify the output filename with a .strings +extension, for example:

      + +
      +ppdpo -o de.strings *.drv
      +
      + +

      Using Message Catalogs with the PPD Compiler

      + +

      Once you have created a message catalog, use the #po directive to declare it in each +driver information file. For example, to declare the German message catalog for +a driver use:

      + +
      +#po de "de.po"  // German
      +
      + +

      In fact, you can use the #po directive as many times as needed:

      + +
      +#po de "de.po"  // German
      +#po es "es.po"  // Spanish
      +#po fr "fr.po"  // French
      +#po it "it.po"  // Italian
      +#po ja "ja.po"  // Japanese
      +
      + +

      The filename ("de.po", etc.) can be relative to the location of the driver +information file or an absolute path. Once defined, the PPD compiler will +automatically generate a globalized PPD for every language declared in your +driver information file. To generate a single-language PPD file, simply use the +-l option to list the corresponding locale, for example:

      + +
      +ppdc -l de -d ppd/de mydrivers.drv
      +
      + +

      to generate German PPD files.

      +
+ + diff --git a/doc/help/raster-driver.html b/doc/help/raster-driver.html new file mode 100644 index 0000000000..bb133ace7a --- /dev/null +++ b/doc/help/raster-driver.html @@ -0,0 +1,561 @@ + + + + +Developing Raster Printer Drivers + + + + + +
+

Developing Raster Printer Drivers

+ +

This document describes how to develop printer drivers for raster printers. Topics include: printer driver basics, creating new PPD files, using filters, implementing color management, and adding Mac OS X features.

+ +
+ + + + + + +
See AlsoProgramming: Developing PostScript Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Introduction to the PPD Compiler
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
+

Contents

+
    +
      +
    • Printer Driver Basics
    • +
    • Creating New PPD Files
    • +
    • Using Filters
    • +
    • Implementing Color Management
    • +
    • Adding Mac OS X Features
    • +

      Printer Driver Basics

      + +

      A CUPS raster printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, one or more filter programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.

      + +

      Every time a user prints something the scheduler program, cupsd(8), determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into CUPS raster data. Figure 1 shows the data flow of a typical print job.

      + +
      + + +
      Figure 1: Raster Filter Chain
      Raster Filter Chain
      + +

      The raster filter converts CUPS raster data into a format the printer understands, for example HP-PCL. CUPS includes several sample raster filters supporting standard page description languages (PDLs). Table 1 shows the raster filters that are bundled with CUPS and the languages they support.

      + +
      + + + + + + + + + + + +
      Table 1: Standard CUPS Raster Filters
      FilterPDLsppdc DriverTypeppdc #include file
      rastertoepsonESC/P, ESC/P2epsonepson.h
      rastertoescpxESC/P, ESC/P2, EPSON Remote Modeescpescp.h
      rastertohpHP-PCL3, HP-PCL5hphp.h
      rastertolabelCPCL, Dymo, EPL1, EPL2, Intellitech PCL, ZPLlabellabel.h
      rastertopclxHP-RTL, HP-PCL3, HP-PCL3GUI, HP-PCL5, HP-PCL5c, HP-PCL5epclpcl.h
      + +

      The optional port monitor handles interface-specific protocol or encoding issues. For example, some raster printers use the 1284.4 communications protocol.

      + +

      The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.

      + +

      The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. Figure 2 shows the data flow of a typical command job.

      + +
      + + +
      Figure 2: Command Filter Chain
      Command Filter Chain
      + +

      Raster printer drivers must provide their own command filter.

      + + +

      Creating New PPD Files

      + +

      We recommend using the CUPS PPD compiler, ppdc(1), to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "Introduction to the PPD Compiler" document. Listing 1 shows a driver information file for several similar black-and-white HP-PCL5 laser printers.

      + +

      Listing 1: "examples/laserjet-basic.drv"

      + +
      +// Include standard font and media definitions
      +#include <font.defs>
      +#include <media.defs>
      +
      +// Include HP-PCL driver definitions
      +#include <pcl.h>
      +
      +// Specify that this driver uses the HP-PCL driver...
      +DriverType pcl
      +
      +// Specify the driver options via the model number...
      +ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
      +
      +// List the fonts that are supported, in this case all standard fonts...
      +Font *
      +
      +// Manufacturer and driver version
      +Manufacturer "HP"
      +Version 1.0
      +
      +// Supported page sizes and their margins
      +HWMargins 18 12 18 12
      +*MediaSize Letter
      +MediaSize Legal
      +MediaSize Executive
      +MediaSize Monarch
      +MediaSize Statement
      +MediaSize FanFoldGermanLegal
      +
      +HWMargins 18 12.72 18 12.72
      +MediaSize Env10
      +
      +HWMargins 9.72 12 9.72 12
      +MediaSize A4
      +MediaSize A5
      +MediaSize B5
      +MediaSize EnvC5
      +MediaSize EnvDL
      +MediaSize EnvISOB5
      +MediaSize Postcard
      +MediaSize DoublePostcard
      +
      +// Only black-and-white output with mode 3 compression...
      +ColorModel Gray k chunky 3
      +
      +// Supported resolutions
      +Resolution - 1 0 0 0 "300dpi/300 DPI"
      +*Resolution - 8 0 0 0 "600dpi/600 DPI"
      +
      +// Supported input slots
      +*InputSlot 7 "Auto/Automatic Selection"
      +InputSlot 2 "Manual/Tray 1 - Manual Feed"
      +InputSlot 4 "Upper/Tray 1"
      +InputSlot 1 "Lower/Tray 2"
      +InputSlot 5 "LargeCapacity/Tray 3"
      +
      +// Tray 3 is an option...
      +Installable "OptionLargeCapacity/Tray 3 Installed"
      +UIConstraints "*OptionLargeCapacity False *InputSlot LargeCapacity"
      +
      +{
      +  // HP LaserJet 2100 Series
      +  Throughput 10
      +  ModelName "LaserJet 2100 Series"
      +  PCFileName "hpljt211.ppd"
      +}
      +
      +{
      +  // LaserJet 2200 and 2300 series have duplexer option...
      +  Duplex normal
      +  Installable "OptionDuplex/Duplexer Installed"
      +  UIConstraints "*OptionDuplex False *Duplex"
      +
      +  {
      +    // HP LaserJet 2200 Series
      +    Throughput 19
      +    ModelName "LaserJet 2200 Series"
      +    PCFileName "hpljt221.ppd"
      +  }
      +
      +  {
      +    // HP LaserJet 2300 Series
      +    Throughput 25
      +    ModelName "LaserJet 2300 Series"
      +    PCFileName "hpljt231.ppd"
      +  }
      +}
      +
      + + +

      Using Filters

      + +

      The standard CUPS raster filters can be specified using the +DriverType directive, for example:

      + +
      +// Specify that this driver uses the HP-PCL driver...
      +DriverType pcl
      +
      + +

      Table 1 shows the driver types for each of the standard CUPS raster filters. For drivers that do not use the standard raster filters, the "custom" type is used with Filter directives:

      + +
      +DriverType custom
      +Filter application/vnd.cups-raster 100 /path/to/raster/filter
      +Filter application/vnd.cups-command 100 /path/to/command/filter
      +
      + + +

      Implementing Color Management

      + +

      CUPS uses ICC color profiles to provide more accurate color reproduction. The cupsICCProfile attribute defines the color profiles that are available for a given printer, for example:

      + +
      +Attribute cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
      +
      + +

      where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:

      + +
      +Attribute cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
      +Attribute cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
      +
      + +

      The options used for profile selection can be customized using the cupsICCQualifier2 and cupsICCQualifier3 attributes.

      + +

      Since Mac OS X 10.5Custom Color Matching Support

      + +

      Mac OS X printer drivers that are based on an existing standard RGB colorspace can tell the system to use the corresponding colorspace instead of an arbitrary ICC color profile when doing color management. The APSupportsCustomColorMatching and APDefaultCustomColorMatchingProfile attributes can be used to enable this mode:

      + +
      +Attribute APSupportsCustomColorMatching "" true
      +Attribute APDefaultCustomColorMatchingProfile "" sRGB
      +
      + + +

      Adding Mac OS X Features

      + +

      Mac OS X printer drivers can provide additional attributes to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:

      + +
      +Attribute APDialogExtension "" /Library/Printers/Vendor/filename.plugin
      +Attribute APHelpBook "" /Library/Printers/Vendor/filename.bundle
      +Attribute APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
      +Attribute APPrinterPreset "name/text" "*option choice ..."
      +
      +
+ + diff --git a/doc/help/ref-access_log.html b/doc/help/ref-access_log.html new file mode 100644 index 0000000000..015ea17bdb --- /dev/null +++ b/doc/help/ref-access_log.html @@ -0,0 +1,140 @@ + + + + access_log + + + + +

access_log

+ +

The access_log file lists each HTTP resource that +is accessed by a web browser or client. Each line is in an +extended version of the so-called "Common Log Format" used by +many web servers and web reporting tools:

+ +

+ +host group user date-time \"method resource version\" status +bytes ipp-operation ipp-status
+ +
+ +10.0.1.2 - - [01/Dec/2005:21:50:28 +0000] "POST / HTTP/1.1" 200 +317 CUPS-Get-Printers +successful-ok-ignored-or-substituted-attributes
+ +localhost - - [01/Dec/2005:21:50:32 +0000] "GET /admin HTTP/1.1" +200 0 - -
+ +localhost - - [01/Dec/2005:21:50:32 +0000] "POST / HTTP/1.1" 200 +157 CUPS-Get-Printers +successful-ok-ignored-or-substituted-attributes
+ +localhost - - [01/Dec/2005:21:50:32 +0000] "POST / HTTP/1.1" 200 +1411 CUPS-Get-Devices -
+ +localhost - - [01/Dec/2005:21:50:32 +0000] "GET /admin HTTP/1.1" +200 6667 - -
+ +

+ +

The host field will normally only be an IP address +unless you have enabled the HostNameLookups +directive in the cupsd.conf file or if the IP address +corresponds to your local machine.

+ +

The group field always contains "-".

+ +

The user field is the authenticated username of the +requesting user. If no username and password is supplied for the +request then this field contains "-".

+ +

The date-time field is the date and time of the request +in local time and is in the format:

+ +

+[DD/MON/YYYY:HH:MM:SS +ZZZZ] +

+ +

The method field is the HTTP method used: "GET", +"OPTIONS", "PUT", or "POST". "GET" requests are used to get files +from the server, both for the web interface and to get +configuration and log files. "OPTIONS" requests are used to +upgrade connections to TLS encryption. "PUT" requests are used to +upload configuration files. "POST" requests are used for web +interface forms and IPP requests.

+ +

The resource field is the filename of the requested +resource.

+ +

The version field is the HTTP specification version used by the +client. For CUPS clients this will always be "HTTP/1.1".

+ +

The status field contains the HTTP result status of the +request, as follows:

+ +
    + +
  • 200 - Successful operation.
  • + +
  • 201 - File created/modified successfully.
  • + +
  • 304 - The requested file has not changed.
  • + +
  • 400 - Bad HTTP request; typically this + means that you have a malicious program trying to access + your server.
  • + +
  • 401 - Unauthorized, authentication + (username + password) is required.
  • + +
  • 403 - Access is forbidden; typically + this means that a client tried to access a file or + resource they do not have permission to access.
  • + +
  • 404 - The file or resource does not + exist.
  • + +
  • 405 - URL access method is not allowed; + typically this means you have a web browser using your + server as a proxy.
  • + +
  • 413 - Request too large; typically this + means that a client tried to print a file larger than the + MaxRequestSize + allows.
  • + +
  • 426 - Upgrading to TLS-encrypted + connection.
  • + +
  • 500 - Server error; typically this + happens when the server is unable to open/create a file - + consult the error_log file for details.
  • + +
  • 501 - The client requested encryption + but encryption support is not enabled/compiled in.
  • + +
  • 505 - HTTP version number not supported; + typically this means that you have a malicious program + trying to access your server.
  • + +
+ +

The bytes field contains the number of bytes in the +request. For POST requests the bytes field contains the +number of bytes of non-IPP data that is received from the +client.

+ +

The ipp-operation field contains either "-" for non-IPP +requests or the IPP operation name for POST requests containing +an IPP request.

+ +

The ipp-status field contains either "-" for non-IPP +requests or the IPP status code name for POST requests containing +an IPP response.

+ + + diff --git a/doc/help/ref-classes-conf.html b/doc/help/ref-classes-conf.html new file mode 100644 index 0000000000..40bc3d5e27 --- /dev/null +++ b/doc/help/ref-classes-conf.html @@ -0,0 +1,566 @@ + + + + classes.conf + + + + +

classes.conf

+ +

The CUPS scheduler (cupsd) uses the +/etc/cups/classes.conf file to store the list of +available classes. This file contains only locally defined +classes, not remote classes that are created automatically via +browsing. 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.

+ +

While the class configuration file consists of plain text and +can be modified using your favorite text editor, you should +normally use the lpadmin(8) +command, web interface, or any of the available GUIs to manage +your classes instead. If you do choose to edit this file +manually, you will need to stop the scheduler first, make your +changes, and then start the scheduler to make them active.

+ + +

Accepting

+ +

Examples

+ +
+<Class name>
+  ...
+  Accepting yes
+</Class>
+
+ +

Description

+ +

The Accepting directive defines the initial state +of the printer-is-accepting-jobs attribute. This state +is also set by the accept(8) and +reject(8) commands:

+ +
+/usr/sbin/accept classname
+/usr/sbin/reject classname
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

AllowUser

+ +

Examples

+ +
+<Class name>
+  ...
+  AllowUser foo_user
+  AllowUser @bar_group
+</Class>
+
+ +

Description

+ +

The AllowUser directive adds a username or group +name to the requesting-user-name-allowed attribute +which can be set by the lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p classname -u allow:foo_user,@bar_group
+
+ +

This directive must appear inside a Class or DefaultClass directive. +This directive cannot be used with DenyUser.

+ + +

Class

+ +

Examples

+ +
+<Class name>
+  ...
+</Class>
+
+ +

Description

+ +

The Class directive begins a class definition. +Classes are added using the lpadmin(8) command: + +

+/usr/sbin/lpadmin -p printername -c classname
+
+ + +

DefaultClass

+ +

Examples

+ +
+<DefaultClass name>
+  ...
+</Class>
+
+ +

Description

+ +

The DefaultClass directive begins a class +definition as the default server destination. The default server +destination can be set using the lpadmin(8) +command:

+ +
+/usr/sbin/lpadmin -d classname
+
+ +

Note that the server default destination settings can be +overridden by the user's default destination settings which are +normally set using the lpoptions(1) command.

+ + +

DenyUser

+ +

Examples

+ +
+<Class name>
+  ...
+  DenyUser foo_user
+  DenyUser @bar_group
+</Class>
+
+ +

Description

+ +

The DenyUser directive adds a username or group +name to the requesting-user-name-denied attribute +which can be set by the lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p classname -u deny:foo_user,@bar_group
+
+ +

This directive must appear inside a Class or DefaultClass directive. +This directive cannot be used with AllowUser

+ + +

Info

+ +

Examples

+ +
+<Class name>
+  ...
+  Info My Class
+</Class>
+
+ +

Description

+ +

The Info directive defines the string for the +printer-info attribute. It is normally set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p classname -D "My Class"
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

JobSheets

+ +

Examples

+ +
+<Class name>
+  ...
+  JobSheets none,standard
+</Class>
+
+ +

Description

+ +

The JobSheets directive specifies the default +banner pages to print before and after a print job. In the above +example, only a standard banner will print after each +job. The lpadmin(8) command is normally used to set +the default banners: + +

+/usr/sbin/lpadmin -p classname -o job-sheets-default=none,standard
+
+ +

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.

+ +

The available banner pages depend on the local system +configuration; CUPS includes the following standard banner +files:

+ +
    + +
  • none - Do not produce a banner + page.
  • + +
  • classified - A banner page with a + "classified" label at the top and bottom.
  • + +
  • confidential - A banner page with a + "confidential" label at the top and bottom.
  • + +
  • secret - A banner page with a + "secret" label at the top and bottom.
  • + +
  • standard - A banner page with no label + at the top and bottom.
  • + +
  • topsecret - A banner page with a + "top secret" label at the top and bottom.
  • + +
  • unclassified - A banner page with an + "unclassified" label at the top and bottom.
  • + +
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

KLimit

+ +

Examples

+ +
+<Class name>
+  ...
+  KLimit 1234
+</Class>
+
+ +

Description

+ +

The KLimit directive defines the value of the +job-k-limit attribute. It is normally set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p classname -o job-k-limit=1234
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

Location

+ +

Examples

+ +
+<Class name>
+  ...
+  Location Building 3321
+</Class>
+
+ +

Description

+ +

The Location directive defines the string for the +printer-location attribute. It is normally set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p classname -L "Building 3321"
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

CUPS 1.2OpPolicy

+ +

Examples

+ +
+<Class name>
+  ...
+  OpPolicy default
+</Class>
+
+ +

Description

+ +

The OpPolicy directive sets the operation policy +that is used for the printer. The lpadmin(8) command +sets the current operation policy:

+ +
+/usr/sbin/lpadmin -p classname -o printer-op-policy=default
+
+ +

The default policy is named "default". All policies correspond +to those defined using the cupsd.conf Policy +section.

+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

CUPS 1.2Option

+ +

Examples

+ +
+<Class name>
+  ...
+  Option name value
+  Option scaling 100
+  Option page-left 72
+</Class>
+
+ +

Description

+ +

The Option directive specifies a default job +template attribute value. It is mapped to +name-default in the printer attributes and applied +to jobs as name.

+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

PageLimit

+ +

Examples

+ +
+<Class name>
+  ...
+  PageLimit 1234
+</Class>
+
+ +

Description

+ +

The PageLimit directive defines the value of the +job-page-limit attribute. It can be set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p classname -o job-page-limit=1234
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

Printer

+ +

Examples

+ +
+<Class name>
+  ...
+  Printer foo
+  Printer bar
+  Printer bleep
+</Class>
+
+ +

Description

+ +

The Printer directive adds a printer to a class. +Printers are added to a class using the lpadmin(8) +command:

+ +
+/usr/sbin/lpadmin -p printername -c classname
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

QuotaPeriod

+ +

Examples

+ +
+<Class name>
+  ...
+  QuotaPeriod 604800
+</Class>
+
+ +

Description

+ +

The QuotaPeriod directive defines the value of +the job-quota-period attribute. Typical values are +86400 (1 day), 604800 (1 week), 2592000 (1 month), and 31536000 +(1 year). It is set using the lpadmin(8) +command:

+ +
+/usr/sbin/lpadmin -p classname -o job-quota-period=604800
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

CUPS 1.2Shared

+ +

Examples

+ +
+<Class name>
+  ...
+  Shared yes
+</Class>
+
+ +

Description

+ +

The Shared directive defines the initial value of +the printer-is-shared attribute. The strings +yes and no correspond to the true and false +values, respectively. The lpadmin(8) command sets +the current state:

+ +
+/usr/sbin/lpadmin -p classname -o printer-is-shared=true
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

State

+ +

Examples

+ +
+<Class name>
+  ...
+  State idle
+</Class>
+
+ +

Description

+ +

The State directive defines the initial value of +the printer-state attribute. The strings +idle and stopped correspond to the IPP +enumeration values 3 and 5, respectively. The +cupsenable(8) and cupsdisable(8) +commands set the current state:

+ +
+/usr/sbin/cupsenable classname
+/usr/sbin/cupsdisable classname
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

StateMessage

+ +

Examples

+ +
+<Class name>
+  ...
+  StateMessage Ready to print.
+</Class>
+
+ +

Description

+ +

The StateMessage directive defines the initial +string for the printer-state-message attribute. The +following are some example messages:

+ +
+StateMessage Connected to host_name...
+StateMessage Connecting to printer_queue on port port_number...
+StateMessage Network host host_name is busy; will retry in 30 seconds...
+StateMessage Class busy; will retry in 10 seconds...
+StateMessage Class is busy; retrying print job...
+StateMessage Print file accepted - job ID id_number.
+StateMessage Ready to print.
+StateMessage Waiting for job to complete
+
+ +

This directive must appear inside a Class or DefaultClass +section.

+ + +

CUPS 1.2StateTime

+ +

Examples

+ +
+<Class name>
+  ...
+  StateTime 1133542425
+</Class>
+
+ +

Description

+ +

The StateTime directive defines the UNIX time +(seconds since Jan 1, 1970) for the last state change of the +queue. It is mapped to the printer-state-change-time +attribute.

+ +

This directive must appear inside a Class or DefaultClass +section.

+ + + + diff --git a/doc/help/ref-client-conf.html b/doc/help/ref-client-conf.html new file mode 100644 index 0000000000..0229b00400 --- /dev/null +++ b/doc/help/ref-client-conf.html @@ -0,0 +1,56 @@ + + + + client.conf + + + + +

client.conf

+ +

The /etc/cups/client.conf and +~/.cups/client.conf files contain up to two directives +that determine how the client behaves. 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.

+ +

Encryption

+ +

Examples

+ +
+Encryption Never
+Encryption IfRequested
+Encryption Required
+Encryption Always
+
+ +

Description

+ +

The Encryption directive specifies the default +encryption settings for the client.

+ +

The default setting is IfRequested.

+ + +

ServerName

+ +

Examples

+ +
+ServerName foo.bar.com
+ServerName 11.22.33.44
+ServerName foo.bar.com:8631
+
+ +

Description

+ +

The ServerName directive specifies sets the remote server that is to be used for all client operations. That is, it redirects all client requests to the remote server.

+ +

The default port number is 631 but can be overridden by adding a colon followed by the desired port number to the value.

+ +

The default is to use the local server ("localhost") or domain socket, if so configured.

+ + + diff --git a/doc/help/ref-cupsd-conf.html.in b/doc/help/ref-cupsd-conf.html.in new file mode 100644 index 0000000000..abeeeba7c4 --- /dev/null +++ b/doc/help/ref-cupsd-conf.html.in @@ -0,0 +1,3099 @@ + + + + cupsd.conf + + + + +

cupsd.conf

+ +

The /etc/cups/cupsd.conf file contains +configuration directives 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. +After making any changes, restart the cupsd(8) +process using the startup script for your operating system:

+ +
    + +
  • AIX, IRIX, Linux, Solaris: +
    +/etc/init.d/cups restart
    +	
  • + +
  • HP-UX: +
    +/sbin/init.d/cups restart
    +	
  • + +
  • MacOS X: +
    +sudo launchctl unload /System/Library/LaunchDaemons/org.cups.cupsd.plist
    +sudo launchctl load /System/Library/LaunchDaemons/org.cups.cupsd.plist
    +	
  • + +
+ +

You can also edit this file from the CUPS web interface, which +automatically handles restarting the scheduler.

+ + +

AccessLog

+ +

Examples

+ +
+AccessLog /var/log/cups/access_log
+AccessLog /var/log/cups/access_log-%s
+AccessLog syslog
+
+ +

Description

+ +

The AccessLog directive sets the name of the +access log file. If the filename is not absolute then it is +assumed to be relative to the ServerRoot 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.

+ +

The server name can be included in the filename by using +%s in the name.

+ +

The special name "syslog" can be used to send the access +information to the system log instead of a plain file.

+ +

The default access log file is +@CUPS_LOGDIR@/access_log.

+ + +

AccessLogLevel

+ +

Examples

+ +
+AccessLogLevel config
+AccessLogLevel actions
+AccessLogLevel all
+
+ +

Description

+ +

The AccessLogLevel directive controls which requests are logged +to the access log file. The following levels are defined:

+ +
    + +
  • config; Log when printers and classes are added, + deleted, or modified and when configuration files are accessed or + updated.
  • + +
  • actions; Log when print jobs are submitted, + held, released, modified, or canceled, and any of the conditions + for config.
  • + +
  • all; Log all requests.
  • + +
+ +

The default access log level is @CUPS_ACCESS_LOG_LEVEL@.

+ + +

Allow

+ +

Examples

+ +
+<Location /path>
+  ...
+  Allow from All
+  Allow from None
+  Allow from *.example.com
+  Allow from .example.com
+  Allow from host.example.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 [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
+  Allow from [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]/mmm
+  Allow from @LOCAL
+  Allow from @IF(name)
+</Location>
+
+ +

Description

+ +

The Allow directive specifies a hostname, IP +address, or network that is allowed access to the server. +Allow directives are cumulative, so multiple +Allow directives can be used to allow access for +multiple hosts or networks.

+ +

Host and domain name matching require that you enable the HostNameLookups +directive.

+ +

The /mm notation specifies a CIDR netmask, as shown in +Table 1.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: CIDR Netmasks
mmnetmaskmmnetmask
00.0.0.08255.0.0.0
1128.0.0.016255.255.0.0
2192.0.0.024255.255.255.0
......32255.255.255.255
+ +

The @LOCAL name will allow access from all local +interfaces. The @IF(name) name will allow access +from the named interface. In both cases, CUPS only allows access +from the network that the interface(s) are configured for - +requests arriving on the interface from a foreign network will +not be accepted.

+ +

The Allow directive must appear inside a Location or Limit section.

+ + +

DeprecatedAuthClass

+ +

Examples

+ +
+<Location /path>
+  ...
+  AuthClass Anonymous
+  AuthClass User
+  AuthClass System
+  AuthClass Group
+</Location>
+
+ +

Description

+ +

The AuthClass directive defines what level of +authentication is required:

+ +
    + +
  • Anonymous - No authentication should be + performed (default)
  • + +
  • User - A valid username and password is + required
  • + +
  • System - A valid username and password + is required, and the username must belong to the "sys" + group; this can be changed using the SystemGroup + directive
  • + +
  • Group - A valid username and password is + required, and the username must belong to the group named + by the AuthGroupName + directive
  • + +
+ +

The AuthClass directive must appear inside a Location or Limit section.

+ +

This directive is deprecated and will be removed from a +future release of CUPS. Consider using the more flexible Require directive instead.

+ + +

DeprecatedAuthGroupName

+ +

Examples

+ +
+<Location /path>
+  ...
+  AuthGroupName mygroup
+  AuthGroupName lp
+</Location>
+
+ +

Description

+ +

The AuthGroupName directive sets the group to use +for Group authentication.

+ +

The AuthGroupName directive must appear inside a +Location or Limit section.

+ +

This directive is deprecated and will be removed from a +future release of CUPS. Consider using the more flexible Require directive instead.

+ + +

AuthType

+ +

Examples

+ +
+<Location /path>
+  ...
+  AuthType None
+  AuthType Basic
+  AuthType Digest
+  AuthType BasicDigest
+  AuthType Negotiate
+</Location>
+
+ +

Description

+ +

The AuthType directive defines the type of +authentication to perform:

+ +
    + +
  • None - No authentication should be + performed (default)
  • + +
  • Basic - Basic authentication should be + performed using the UNIX password and group files
  • + +
  • Digest - Digest authentication should be + performed using the /etc/cups/passwd.md5 + file
  • + +
  • BasicDigest - Basic authentication + should be performed using the + /etc/cups/passwd.md5 file
  • + +
  • Negotiate - Kerberos authentication + should be performed
  • + +
+ +

When using Basic, Digest, +BasicDigest, or Negotiate authentication, +clients connecting through the localhost interface can +also authenticate using certificates.

+ +

The AuthType directive must appear inside a Location or Limit section.

+ + +

AutoPurgeJobs

+ +

Examples

+ +
+AutoPurgeJobs Yes
+AutoPurgeJobs No
+
+ +

Description

+ +

The AutoPurgeJobs 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 No.

+ + +

BrowseAddress

+ +

Examples

+ +
+BrowseAddress 255.255.255.255:631
+BrowseAddress 192.0.2.255:631
+BrowseAddress host.example.com:631
+BrowseAddress @LOCAL
+BrowseAddress @IF(name)
+
+ +

Description

+ +

The BrowseAddress directive specifies an address +to send browsing information to. Multiple +BrowseAddress directives can be specified to send +browsing information to different networks or systems.

+ +

The @LOCAL name will broadcast printer +information to all local interfaces. The @IF(name) +name will broadcast to the named interface.

+ +

There is no default browse address.

+ +
Note: + +

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.

+ +
+ + +

BrowseAllow

+ +

Examples

+ +
+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 *.example.com
+BrowseAllow from @LOCAL
+BrowseAllow from @IF(name)
+
+ +

Description

+ +

The BrowseAllow directive specifies a system or +network to accept browse packets from. The default is to accept +browse packets from all hosts.

+ +

Host and domain name matching require that you enable the HostNameLookups +directive.

+ +

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. The /mm +notation specifies a CIDR netmask, a shown in Table 1.

+ +

The @LOCAL name will allow browse data from all +local interfaces. The @IF(name) name will allow +browse data from the named interface. In both cases, CUPS only +allows data from the network that the interface(s) are configured +for - data arriving on the interface from a foreign network will +not be allowed.

+ + +

BrowseDeny

+ +

Examples

+ +
+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 *.example.com
+BrowseDeny from @LOCAL
+BrowseDeny from @IF(name)
+
+ +

Description

+ +

The BrowseDeny directive specifies a system or +network to reject browse packets from. The default is to not deny +browse packets from any hosts.

+ +

Host and domain name matching require that you enable the HostNameLookups +directive.

+ +

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. The /mm +notation specifies a CIDR netmask, a shown in Table 1.

+ +

The @LOCAL name will block browse data from all +local interfaces. The @IF(name) name will block +browse data from the named interface. In both cases, CUPS only +blocks data from the network that the interface(s) are configured +for - data arriving on the interface from a foreign network will +not be blocked.

+ + +

BrowseInterval

+ +

Examples

+ +
+BrowseInterval 0
+BrowseInterval 30
+
+ +

Description

+ +

The BrowseInterval 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.

+ +

The BrowseInterval value should always be less +than the BrowseTimeout +value. Otherwise printers and classes will disappear from client +systems between updates.

+ + +

CUPS 1.2/Mac OS X 10.5BrowseLDAPBindDN

+ +

Examples

+ +
+BrowseLDAPBindDN foo
+
+ +

Description

+ +

The BrowseLDAPBindDN directive specifies the LDAP +domain name to use when listening for printer registrations. The +default is undefined.

+ + +

CUPS 1.4/Mac OS X 10.6BrowseLDAPCACertFile

+ +

Examples

+ +
+BrowseLDAPCACertFile /etc/cups/ssl/certs
+
+ +

Description

+ +

The BrowseLDAPCACertFile directive specifies the SSL certificate +authority file to use for LDAP + SSL. The default is undefined.

+ + +

CUPS 1.2/Mac OS X 10.5BrowseLDAPDN

+ +

Examples

+ +
+BrowseLDAPDN bar
+
+ +

Description

+ +

The BrowseLDAPDN directive specifies the LDAP +domain name to use when registering local shared printers. The +default is undefined.

+ + +

CUPS 1.2/Mac OS X 10.5BrowseLDAPPassword

+ +

Examples

+ +
+BrowseLDAPPassword foo123
+
+ +

Description

+ +

The BrowseLDAPPassword directive specifies the +access password to use when connecting to the LDAP server. The +default is undefined.

+ + +

CUPS 1.2/Mac OS X 10.5BrowseLDAPServer

+ +

Examples

+ +
+BrowseLDAPServer localhost
+
+ +

Description

+ +

The BrowseLDAPServer directive specifies the name +of the LDAP server to connect to. The default is undefined.

+ + +

BrowseLocalOptions

+ +

Examples

+ +
+BrowseLocalOptions compression=yes
+BrowseLocalOptions encryption=required
+BrowseLocalOptions compression=yes&encryption=required
+
+ +

Description

+ +

The BrowseLocalOptions directive specifies +additional IPP backend options to advertise with local shared +printers. The default is to not include any options.

+ + +

CUPS 1.2/Mac OS X 10.5BrowseLocalProtocols

+ +

Examples

+ +
+BrowseLocalProtocols all
+BrowseLocalProtocols none
+BrowseLocalProtocols cups
+BrowseLocalProtocols dnssd
+BrowseLocalProtocols ldap
+BrowseLocalProtocols lpd
+BrowseLocalProtocols slp
+BrowseLocalProtocols smb
+BrowseLocalProtocols cups dnssd
+
+ +

Description

+ +

The BrowseLocalProtocols directive specifies the +protocols to use when advertising local shared printers on the +network. Multiple protocols can be specified by separating them +with spaces. The default is "@CUPS_BROWSE_LOCAL_PROTOCOLS@".

+ + +

BrowseOrder

+ +

Examples

+ +
+BrowseOrder allow,deny
+BrowseOrder deny,allow
+
+ +

Description

+ +

The BrowseOrder directive specifies the order of +allow/deny processing. The default order is +deny,allow:

+ +
    + +
  • allow,deny - Deny browse packets by + default, then check BrowseAllow lines + followed by BrowseDeny lines.
  • + +
  • deny,allow - Allow browse packets by + default, then check BrowseDeny lines + followed by BrowseAllow lines.
  • + +
+ + +

BrowsePoll

+ +

Examples

+ +
+BrowsePoll 192.0.2.2:631
+BrowsePoll host.example.com:631
+
+ +

Description

+ +

The BrowsePoll directive polls a server for +available printers once every BrowseInterval seconds. +Multiple BrowsePoll directives can be specified to +poll multiple servers.

+ +

If BrowseInterval is set to 0 then the server is +polled once every 30 seconds.

+ + +

BrowsePort

+ +

Examples

+ +
+BrowsePort 631
+BrowsePort 9999
+
+ +

Description

+ +

The BrowsePort directive specifies the UDP port number +used for browse packets. The default port number is 631.

+ +
Note: + +

You must set the BrowsePort to the same value +on all of the systems that you want to see. + +

+ + +

CUPS 1.1.10BrowseProtocols

+ +

Examples

+ +
+BrowseProtocols all
+BrowseProtocols none
+BrowseProtocols cups
+BrowseProtocols dnssd
+BrowseProtocols ldap
+BrowseProtocols lpd
+BrowseProtocols slp
+BrowseProtocols smb
+BrowseProtocols cups dnssd
+
+ +

Description

+ +

The BrowseProtocols directive specifies the +protocols to use when showing and advertising shared printers on +the local network. Multiple protocols can be specified by +separating them with spaces. The default protocol is +"@CUPS_BROWSE_LOCAL_PROTOCOLS@" for +BrowseLocalProtocols and +"@CUPS_BROWSE_REMOTE_PROTOCOLS@" for +BrowseRemoteProtocols.

+ +
Note: + +

When using the SLP protocol, you must have at least +one Directory Agent (DA) server on your network. Otherwise the +CUPS scheduler (cupsd) will not respond to client +requests for several seconds while polling the network.

+ +
+ + +

BrowseRelay

+ +

Examples

+ +
+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 *.example.com 192.0.2.255
+BrowseRelay host.example.com 192.0.2.255
+
+ +

Description

+ +

The BrowseRelay directive specifies source and +destination addresses for relaying browsing information from one +host or network to another. Multiple BrowseRelay +directives can be specified as needed.

+ +

BrowseRelay 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:

+ +
+BrowseRelay 127.0.0.1 192.0.2.255
+
+ +

This effectively provides access to printers on a WAN for all +clients on the LAN. Use multiple BrowseRelay lines to +relay information to multiple subnets.

+ + +

BrowseRemoteOptions

+ +

Examples

+ +
+BrowseRemoteOptions compression=yes
+BrowseRemoteOptions encryption=required
+BrowseRemoteOptions ?compression=yes&encryption=required
+
+ +

Description

+ +

The BrowseRemoteOptions directive specifies +additional IPP backend options to include with remote shared +printers. If the options string begins with a question mark (?), +the options replace any options specified by the remote server. +The default is to not include any options.

+ + +

CUPS 1.2/Mac OS X 10.5BrowseRemoteProtocols

+ +

Examples

+ +
+BrowseRemoteProtocols all
+BrowseRemoteProtocols none
+BrowseRemoteProtocols cups
+BrowseRemoteProtocols ldap
+BrowseRemoteProtocols slp
+
+ +

Description

+ +

The BrowseRemoteProtocols directive specifies the +protocols to use when finding remote shared printers on the +network. Multiple protocols can be specified by separating them +with spaces. The default is "@CUPS_BROWSE_REMOTE_PROTOCOLS@".

+ + +

BrowseShortNames

+ +

Examples

+ +
+BrowseShortNames Yes
+BrowseShortNames No
+
+ +

Description

+ +

The BrowseShortNames 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".)

+ +

The default value for this option is @CUPS_BROWSE_SHORT_NAMES@.

+ + +

BrowseTimeout

+ +

Examples

+ +
+BrowseTimeout 300
+BrowseTimeout 60
+
+ +

Description

+ +

The BrowseTimeout 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.

+ +

The BrowseTimeout value should always be greater +than the BrowseInterval value. +Otherwise printers and classes will disappear from client systems +between updates.

+ + +

BrowseWebIF

+ +

Examples

+ +
+BrowseWebIF On
+BrowseWebIF Off
+
+ +

Description

+ +

The BrowseWebIF directive controls whether the CUPS web +interface is advertised via DNS-SD. The default setting is +Off.

+ + +

Browsing

+ +

Examples

+ +
+Browsing On
+Browsing Off
+
+ +

Description

+ +

The Browsing directive controls whether or not +network printer browsing is enabled. The default setting is +@CUPS_BROWSING@.

+ +

This directive does not enable sharing of local printers by +itself; you must also use the BrowseAddress or BrowseProtocols +directives to advertise local printers to other systems.

+ +
Note: + +

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.

+ +
+ + +

CUPS 1.1.7Classification

+ +

Examples

+ +
+Classification
+Classification classified
+Classification confidential
+Classification secret
+Classification topsecret
+Classification unclassified
+
+ +

Description

+ +

The Classification 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.

+ + +

CUPS 1.1.10ClassifyOverride

+ +

Examples

+ +
+ClassifyOverride Yes
+ClassifyOverride No
+
+ +

Description

+ +

The ClassifyOverride 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 job-sheets option and +can choose to only print one security banner before or after the +job. If the job-sheets option is set to +none then the server default classification is +used.

+ +

The default is to not allow classification overrides.

+ + +

CUPS 1.1.15ConfigFilePerm

+ +

Examples

+ +
+ConfigFilePerm 0644
+ConfigFilePerm 0640
+
+ +

Description

+ +

The ConfigFilePerm directive specifies the +permissions to use when writing configuration files. The default +is @CUPS_CONFIG_FILE_PERM@.

+ + +

DataDir

+ +

Examples

+ +
+DataDir /usr/share/cups
+
+ +

Description

+ +

The DataDir directive sets the directory to use +for data files.

+ + +

CUPS 1.2/Mac OS X 10.5DefaultAuthType

+ +

Examples

+ +
+DefaultAuthType Basic
+DefaultAuthType BasicDigest
+DefaultAuthType Digest
+DefaultAuthType Negotiate
+
+ +

Description

+ +

The DefaultAuthType directive specifies the type +of authentication to use for IPP operations that require a +username. The default is Basic.

+ + +

CUPS 1.2/Mac OS X 10.5DefaultEncryption

+ +

Examples

+ +
+DefaultEncryption Never
+DefaultEncryption IfRequested
+DefaultEncryption Required
+
+ +

Description

+ +

The DefaultEncryption directive specifies the +type of encryption to use when performing authentication. The +default is Required.

+ + +

DefaultLanguage

+ +

Examples

+ +
+DefaultLanguage de
+DefaultLanguage en
+DefaultLanguage es
+DefaultLanguage fr
+DefaultLanguage it
+
+ +

Description

+ +

The DefaultLanguage 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.

+ + +

CUPS 1.4/Mac OS X 10.6DefaultPaperSize

+ +

Examples

+ +
+DefaultPaperSize Letter
+DefaultPaperSize A4
+DefaultPaperSize Auto
+DefaultPaperSize None
+
+ +

Description

+ +

The DefaultPaperSize directive specifies the default paper +size to use when creating new printers. The default is Auto +which uses a paper size appropriate for the system default locale. A value +of None tells the scheduler to not set the default paper +size.

+ + +

CUPS 1.2/Mac OS X 10.5DefaultPolicy

+ +

Examples

+ +
+DefaultPolicy default
+DefaultPolicy authenticated
+DefaultPolicy foo
+
+ +

Description

+ +

The DefaultPolicy directive specifies the default +policy to use for IPP operation. The default is +default. CUPS also includes a policy called +authenticated that requires a username and password for printing +and other job operations.

+ + +

CUPS 1.2/Mac OS X 10.5DefaultShared

+ +

Examples

+ +
+DefaultShared yes
+DefaultShared no
+
+ +

Description

+ +

The DefaultShared directive specifies whether +printers are shared (published) by default. The default is +@CUPS_DEFAULT_SHARED@.

+ + +

Deny

+ +

Examples

+ +
+<Location /path>
+  ..
+  Deny from All
+  Deny from None
+  Deny from *.example.com
+  Deny from .example.com
+  Deny from host.example.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 [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]
+  Deny from [xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx]/mmm
+  Deny from @LOCAL
+  Deny from @IF(name)
+</Location>
+
+ +

Description

+ +

The Deny directive specifies a hostname, IP +address, or network that is denied access to the server. +Deny directives are cumulative, so multiple +Deny directives can be used to deny access for +multiple hosts or networks.

+ +

Host and domain name matching require that you enable the HostNameLookups +directive.

+ +

The /mm notation specifies a CIDR netmask, a shown in +Table 1.

+ +

The @LOCAL name will deny access from all local +interfaces. The @IF(name) name will deny access from +the named interface. In both cases, CUPS only denies access from +the network that the interface(s) are configured for - requests +arriving on the interface from a foreign network will +not be denied.

+ +

The Deny directive must appear inside a Location or Limit section.

+ + +

CUPS 1.4/Mac OS X 10.6DirtyCleanInterval

+ +

Examples

+ +
+DirtyCleanInterval 30
+DirtyCleanInterval 0
+
+ +

Description

+ +

The DirtyCleanInterval directive specifies the number of +seconds to wait before updating configuration and state files for printers, +classes, subscriptions, and jobs. The default is 30 seconds. A value of 0 +causes the update to occur as soon as possible, typically within a few +milliseconds.

+ + +

DocumentRoot

+ +

Examples

+ +
+DocumentRoot /usr/share/doc/cups
+DocumentRoot /foo/bar/doc/cups
+
+ +

Description

+ +

The DocumentRoot 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 ServerRoot directory. The +default directory is @CUPS_DOCROOT@.

+ +

Documents are first looked up in a sub-directory for the +primary language requested by the client (e.g. +@CUPS_DOCROOT@/fr/...) and then directly under +the DocumentRoot directory (e.g. +@CUPS_DOCROOT@/...), so it is possible to +localize the web content by providing subdirectories for each +language needed.

+ + +

Encryption

+ +

Examples

+ +
+<Location /path>
+  ...
+  Encryption Never
+  Encryption IfRequested
+  Encryption Required
+</Location>
+
+ +

Description

+ +

The Encryption directive must appear instead a Location or Limit section and specifies the +encryption settings for that location. The default setting is +IfRequested for all locations.

+ + +

ErrorLog

+ +

Examples

+ +
+ErrorLog /var/log/cups/error_log
+ErrorLog /var/log/cups/error_log-%s
+ErrorLog syslog
+
+ +

Description

+ +

The ErrorLog directive sets the name of the error +log file. If the filename is not absolute then it is assumed to +be relative to the ServerRoot directory. The +default error log file is @CUPS_LOGDIR@/error_log.

+ +

The server name can be included in the filename by using +%s in the name.

+ +

The special name "syslog" can be used to send the error +information to the system log instead of a plain file.

+ + +

CUPS 1.3/Mac OS X 10.5ErrorPolicy

+ +

Examples

+ +
+ErrorPolicy abort-job
+ErrorPolicy retry-job
+ErrorPolicy stop-printer
+
+ +

Description

+ +

The ErrorPolicy directive defines the default policy that +is used when a backend is unable to send a print job to the +printer.

+ +

The following values are supported:

+ +
    + +
  • abort-job - Abort the job and proceed + with the next job in the queue
  • + +
  • retry-job - Retry the job after waiting + for N seconds; the cupsd.conf JobRetryInterval + directive controls the value of N
  • + +
  • retry-this-job - Retry the current job immediately + and indefinitely.
  • + +
  • stop-printer - Stop the printer and keep + the job for future printing; this is the default + value
  • + +
+ + + +

CUPS 1.4/Mac OS X 10.6FatalErrors

+ +

Examples

+ +
+FatalErrors none
+FatalErrors all
+FatalErrors browse
+FatalErrors config
+FatalErrors listen
+FatalErrors log
+FatalErrors permissions
+FatalErrors all -permissions
+FatalErrors config permissions log
+
+ +

Description

+ +

The FatalErrors directive determines whether certain kinds of +errors are fatal. The following kinds of errors are currently recognized:

+ +
    + +
  • none - No errors are fatal
  • + +
  • all - All of the errors below are fatal
  • + +
  • browse - Browsing initialization errors are fatal, + for example failed binding to the CUPS browse port or failed connections + to LDAP servers
  • + +
  • config - Configuration file syntax errors are + fatal
  • + +
  • listen - Listen or Port errors are fatal, except for + IPv6 failures on the loopback or "any" addresses
  • + +
  • log - Log file creation or write errors are fatal
  • + +
  • permissions - Bad startup file permissions are + fatal, for example shared SSL certificate and key files with world- + read permissions
  • + +
+ +

Multiple errors can be listed, and the form "-kind" can be used with +all to remove specific kinds of errors. The default setting is +@CUPS_FATAL_ERRORS@.

+ + +

CUPS 1.1.18FileDevice

+ +

Examples

+ +
+FileDevice Yes
+FileDevice No
+
+ +

Description

+ +

The FileDevice directive determines whether the +scheduler allows new printers to be added using device URIs of +the form file:/filename. File devices are most often +used to test new printer drivers and do not support raw file +printing.

+ +

The default setting is No.

+ +
Note: + +

File devices are managed by the scheduler. Since the +scheduler normally runs as the root user, file devices +can be used to overwrite system files and potentially +gain unauthorized access to the system. If you must +create printers using file devices, we recommend that +you set the FileDevice directive to +Yes for only as long as you need to add the +printers to the system, and then reset the directive to +No.

+ +
+ + +

CUPS 1.1.3FilterLimit

+ +

Examples

+ +
+FilterLimit 0
+FilterLimit 200
+FilterLimit 1000
+
+ +

Description

+ +

The FilterLimit 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.

+ +

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.

+ +

The default limit is 0.

+ + +

CUPS 1.1.16FilterNice

+ +

Examples

+ +
+FilterNice 0
+FilterNice 10
+FilterNice 19
+
+ +

Description

+ +

The FilterNice directive sets the nice(1) +value to assign to filter processes. The nice value ranges from +0, the highest priority, to 19, the lowest priority. The default +is 0.

+ + +

CUPS 1.1.3FontPath

+ +

Examples

+ +
+FontPath /foo/bar/fonts
+FontPath /usr/share/cups/fonts:/foo/bar/fonts
+
+ +

Description

+ +

The FontPath directive specifies the font path to +use when searching for fonts. The default font path is +/usr/share/cups/fonts.

+ + +

Group

+ +

Examples

+ +
+Group lp
+Group nobody
+
+ +

Description

+ +

The Group directive specifies the UNIX group that +filter and CGI programs run as. The default group is +system-specific but is usually lp or +nobody.

+ + +

CUPS 1.1.10HideImplicitMembers

+ +

Examples

+ +
+HideImplicitMembers Yes
+HideImplicitMembers No
+
+ +

Description

+ +

The HideImplicitMembers directive controls +whether the individual printers in an implicit class are hidden +from the user. The default is Yes.

+ +

ImplicitClasses +must be enabled for this directive to have any effect.

+ + +

HostNameLookups

+ +

Examples

+ +
+HostNameLookups On
+HostNameLookups Off
+HostNameLookups Double
+
+ +

Description

+ +

The HostNameLookups directive controls whether or +not CUPS looks up the hostname for connecting clients. The +Double setting causes CUPS to verify that the +hostname resolved from the address matches one of the addresses +returned for that hostname. Double lookups also +prevent clients with unregistered addresses from connecting to +your server.

+ +

The default is Off to avoid the potential server +performance problems with hostname lookups. Set this option to +On or Double only if absolutely +required.

+ + +

CUPS 1.1.10ImplicitAnyClasses

+ +

Examples

+ +
+ImplicitAnyClasses On
+ImplicitAnyClasses Off
+
+ +

Description

+ +

The ImplicitAnyClasses directive controls +whether implicit classes for local and remote printers are +created with the name AnyPrinter. The default +setting is Off.

+ +

ImplicitClasses +must be enabled for this directive to have any effect.

+ + +

ImplicitClasses

+ +

Examples

+ +
+ImplicitClasses On
+ImplicitClasses Off
+
+ +

Description

+ +

The ImplicitClasses directive controls whether +implicit classes are created based upon the available network +printers and classes. The default setting is +@CUPS_IMPLICIT_CLASSES@ but is automatically turned +Off if Browsing is turned +Off.

+ + +

CUPS 1.1.9Include

+ +

Examples

+ +
+Include filename
+Include /foo/bar/filename
+
+ +

Description

+ +

The Include directive includes the named file in +the cupsd.conf file. If no leading path is provided, +the file is assumed to be relative to the ServerRoot directory.

+ + +

CUPS 1.2/Mac OS X 10.5JobRetryInterval

+ +

Examples

+ +
+JobRetryInterval 30
+JobRetryInterval 120
+
+ +

Description

+ +

The JobRetryInterval directive specifies the +number of seconds to wait before retrying a job. This is +typically used for fax queues but can also be used with normal +print queues whose error policy is retry-job. The +default is 30 seconds.

+ + +

CUPS 1.4/Mac OS X 10.6JobKillDelay

+ +

Examples

+ +
+JobKillDelay 30
+JobKillDelay 120
+
+ +

Description

+ +

The JobKillDelay directive specifies the number of seconds to +wait before killing the filters and backend associated with a canceled or held +job. The default is 30 seconds.

+ + +

CUPS 1.2/Mac OS X 10.5JobRetryLimit

+ +

Examples

+ +
+JobRetryLimit 5
+JobRetryLimit 50
+
+ +

Description

+ +

The JobRetryLimit directive specifies the maximum +number of times the scheduler will try to print a job. This is +typically used for fax queues but can also be used with normal +print queues whose error policy is retry-job. The +default is 5 times.

+ + +

KeepAlive

+ +

Examples

+ +
+KeepAlive On
+KeepAlive Off
+
+ +

Description

+ +

The KeepAlive directive controls whether or not +to support persistent HTTP connections. The default is +On.

+ +

HTTP/1.1 clients automatically support persistent connections, +while HTTP/1.0 clients must specifically request them using the +Keep-Alive attribute in the Connection: +field of each request.

+ + +

KeepAliveTimeout

+ +

Examples

+ +
+KeepAliveTimeout 60
+KeepAliveTimeout 30
+
+ +

Description

+ +

The KeepAliveTimeout directive controls how long +a persistent HTTP connection will remain open after the last +request. The default is 30 seconds.

+ + +

CUPS 1.1.7Limit (Location)

+ +

Examples

+ +
+<Location /path>
+  <Limit GET POST>
+  ...
+  </Limit>
+
+  <Limit ALL>
+  ...
+  </Limit>
+</Location>
+
+ +

Description

+ +

The Limit directive groups access control +directives for specific types of HTTP requests and must appear +inside a Location section. +Access can be limited for individual request types +(DELETE, GET, HEAD, +OPTIONS, POST, PUT, and +TRACE) or for all request types (ALL). +The request type names are case-sensitive for compatibility with +Apache.

+ + +

CUPS 1.2/Mac OS X 10.5Limit (Policy)

+ +

Examples

+ +
+<Policy name>
+  <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer>
+  ...
+  </Limit>
+
+  <Limit All>
+  ...
+  </Limit>
+</Policy>
+
+ +

Description

+ +

When included in Policy +sections, the Limit directive groups access control +directives for specific IPP operations. Multiple operations can +be listed, separated by spaces. Table 2 lists the supported +operations.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Supported IPP Operations
Operation NameDescription
AllAll operations - used as the default limit for + operations that are not listed
Cancel-JobCancel a job
Cancel-SubscriptionCancel a subscription
Create-JobCreate a new, empty job
Create-Job-SubscriptionCreates a notification subscription on a job
Create-Printer-SubscriptionCreates a notification subscription on a printer
CUPS-Accept-JobsSets the printer-is-accepting-jobs value for a printer to true
CUPS-Add-Modify-ClassAdds or modifies a class
CUPS-Add-Modify-PrinterAdds or modifies a printer
CUPS-Authenticate-JobAuthenticates a job for printing
CUPS-Delete-ClassDeletes a class
CUPS-Delete-PrinterDeletes a printer
CUPS-Get-ClassesGets a list of classes
CUPS-Get-DefaultGets the (network/server) default printer or class
CUPS-Get-DevicesGets a list of available devices
CUPS-Get-PPDsGets a list of available manufacturers or drivers
CUPS-Get-PrintersGets a list of printers and/or classes
CUPS-Move-JobMoves a job to a new destination
CUPS-Reject-JobsSets the printer-is-accepting-jobs value for a printer to false
CUPS-Set-DefaultSets the network/server default printer or class
Disable-PrinterSets the printer-state value for a printer to stopped
Enable-PrinterSets the printer-state value for a printer to idle/processing
Get-Job-AttributesGets information about a job
Get-JobsGets a list of jobs
Get-NotificationsGets a list of events
Get-Printer-AttributesGets information about a printer or class
Get-Subscription-AttributesGets information about a notification subscription
Get-SubscriptionsGets a list of notification subscriptions
Hold-JobHolds a job for printing
Pause-PrinterSets the printer-state value for a printer to stopped
Print-JobCreates a job with a single file for printing
Purge-JobsRemoves all jobs from a printer
Release-JobReleases a previously held job for printing
Renew-SubscriptionRenews a notification subscription
Restart-JobReprints a job
Resume-PrinterSets the printer-state value for a printer to idle/processing
Send-DocumentAdds a file to an job created with Create-Job
Set-Job-AttributesChanges job options
Validate-JobValidates job options prior to printing
+ + +

CUPS 1.1.7LimitExcept

+ +

Examples

+ +
+<Location /path>
+  <LimitExcept GET POST>
+  ...
+  </LimitExcept>
+</Location>
+
+ +

Description

+ +

The LimitExcept directive groups access control +directives for specific types of HTTP requests and must appear +inside a Location section. +Unlike the Limit directive, +LimitExcept restricts access for all requests +except those listed on the LimitExcept +line.

+ + +

LimitRequestBody

+ +

Examples

+ +
+LimitRequestBody 10485760
+LimitRequestBody 10m
+LimitRequestBody 0
+
+ +

Description

+ +

The LimitRequestBody 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.

+ + +

Listen

+ +

Examples

+ +
+Listen 127.0.0.1:631
+Listen 192.0.2.1:631
+Listen [::1]:631
+Listen *:631
+
+ +

Description

+ +

The Listen directive specifies a network address +and port to listen for connections. Multiple Listen +directives can be provided to listen on multiple addresses.

+ +

The Listen directive is similar to the Port directive but allows you to +restrict access to specific interfaces or networks.

+ + +

CUPS 1.1.7ListenBackLog

+ +

Examples

+ +
+ListenBackLog 5
+ListenBackLog 10
+
+ +

Description

+ +

The ListenBackLog directive sets the maximum +number of pending connections the scheduler will allow. This +normally only affects very busy servers that have reached the MaxClients limit, but can +also be triggered by large numbers of simultaneous connections. +When the limit is reached, the operating system will refuse +additional connections until the scheduler can accept the pending +ones. The default is the OS-defined default limit, typically +either 5 for older operating systems or 128 for newer operating +systems.

+ + +

Location

+ +

Examples

+ +
+<Location />
+...
+</Location>
+
+<Location /admin>
+...
+</Location>
+
+<Location /admin/conf>
+...
+</Location>
+
+<Location /admin/log>
+...
+</Location>
+
+<Location /classes>
+...
+</Location>
+
+<Location /classes/name>
+...
+</Location>
+
+<Location /jobs>
+...
+</Location>
+
+<Location /printers>
+...
+</Location>
+
+<Location /printers/name>
+...
+</Location>
+
+
+ +

Description

+ +

The Location directive specifies access control +and authentication options for the specified HTTP resource or +path. The Allow, AuthType, Deny, Encryption, Limit, LimitExcept, Order, Require, and Satisfy directives may all +appear inside a location.

+ +

Note that more specific resources override the less specific +ones. So the directives inside the /printers/name +location will override ones from /printers. +Directives inside /printers will override ones from +/. None of the directives are inherited.

+ +
+ + + + + + + + + + + + + + + + + +
Table 3: Common Locations on the Server
LocationDescription
/The path for all get operations (get-printers, get-jobs, etc.)
/adminThe path for all administration operations (add-printer, delete-printer, start-printer, etc.)
/admin/confThe path for access to the CUPS configuration files (cupsd.conf, client.conf, etc.)
/admin/logThe path for access to the CUPS log files (access_log, error_log, page_log)
/classesThe path for all classes
/classes/nameThe resource for class name
/jobsThe path for all jobs (hold-job, release-job, etc.)
/jobs/idThe resource for job id
/printersThe path for all printers
/printers/nameThe path for printer name
/printers/name.ppdThe PPD file path for printer name
+ + +

LogDebugHistory

+ +

Examples

+ +
+LogDebugHistory 0
+LogDebugHistory 200
+
+ +

Description

+ +

When LogLevel is not set to +debug or debug2, the LogDebugHistory +directive specifies the number of debugging messages that are logged when an +error occurs during printing. The default is 200 messages. A value of 0 +disables debugging history entirely and is not recommended.

+ + +

CUPS 1.1.15LogFilePerm

+ +

Examples

+ +
+LogFilePerm 0644
+LogFilePerm 0600
+
+ +

Description

+ +

The LogFilePerm directive specifies the +permissions to use when writing configuration files. The default +is @CUPS_LOG_FILE_PERM@.

+ + +

LogLevel

+ +

Examples

+ +
+LogLevel none
+LogLevel emerg
+LogLevel alert
+LogLevel crit
+LogLevel error
+LogLevel warn
+LogLevel notice
+LogLevel info
+LogLevel debug
+LogLevel debug2
+
+ +

Description

+ +

The LogLevel directive specifies the level of +logging for the ErrorLog +file. The following values are recognized (each level logs +everything under the preceding levels):

+ +
    + +
  • none - Log nothing
  • + +
  • emerg - Log emergency conditions that + prevent the server from running
  • + +
  • alert - Log alerts that must be handled + immediately
  • + +
  • crit - Log critical errors that don't + prevent the server from running
  • + +
  • error - Log general errors
  • + +
  • warn - Log errors and warnings
  • + +
  • notice - Log temporary error conditions
  • + +
  • info - Log all requests and state + changes
  • + +
  • debug - Log basic debugging + information
  • + +
  • debug2 - Log all debugging + information
  • + +
+ +

The default LogLevel is @CUPS_LOG_LEVEL@.

+ + +

LogTimeFormat

+ +

Examples

+ +
+LogTimeFormat standard
+LogTimeFormat usecs
+
+ +

Description

+ +

The LogTimeFormat directive specifies the format used for the +date and time in the log files. Standard uses the standard Apache +Common Log Format date and time while usecs adds microseconds. +The default is standard.

+ + +

MaxClients

+ +

Examples

+ +
+MaxClients 100
+MaxClients 1024
+
+ +

Description

+ +

The MaxClients directive controls the maximum +number of simultaneous clients that will be allowed by the +server. The default is 100 clients.

+ +
Note: + +

Since each print job requires a file descriptor for the status +pipe, the scheduler internally limits the MaxClients +value to 1/3 of the available file descriptors to avoid possible +problems when printing large numbers of jobs.

+ +
+ + +

CUPS 1.1.18MaxClientsPerHost

+ +

Examples

+ +
+MaxClientsPerHost 10
+
+ +

Description

+ +

The MaxClientsPerHost directive controls the +maximum number of simultaneous clients that will be allowed from +a single host by the server. The default is the +MaxClients value.

+ +

This directive provides a small measure of protection against +Denial of Service attacks from a single host.

+ + +

CUPS 1.1.16MaxCopies

+ +

Examples

+ +
+MaxCopies 100
+MaxCopies 65535
+
+ +

Description

+ +

The MaxCopies directive controls the maximum +number of copies that a user can print of a job. The default is +@CUPS_MAX_COPIES@ copies.

+ +
Note: + +

Most HP PCL laser printers internally limit the number of +copies to 100.

+ +
+ + + +

MaxJobs

+ +

Examples

+ +
+MaxJobs 100
+MaxJobs 9999
+MaxJobs 0
+
+ +

Description

+ +

The MaxJobs 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.

+ +

Setting the maximum size to 0 disables this functionality. The +default setting is 500.

+ + +

CUPS 1.1.7MaxJobsPerPrinter

+ +

Examples

+ +
+MaxJobsPerPrinter 100
+MaxJobsPerPrinter 9999
+MaxJobsPerPrinter 0
+
+ +

Description

+ +

The MaxJobsPerPrinter 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 canceled.

+ +

Setting the maximum to 0 disables this functionality. The +default setting is 0.

+ + +

CUPS 1.1.7MaxJobsPerUser

+ +

Examples

+ +
+MaxJobsPerUser 100
+MaxJobsPerUser 9999
+MaxJobsPerUser 0
+
+ +

Description

+ +

The MaxJobsPerUser 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 canceled.

+ +

Setting the maximum to 0 disables this functionality. The +default setting is 0.

+ + +

MaxLogSize

+ +

Examples

+ +
+MaxLogSize 1048576
+MaxLogSize 1m
+MaxLogSize 0
+
+ +

Description

+ +

The MaxLogSize 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 filename.O. +This allows you to rotate the logs automatically. The default +size is 1048576 bytes (1MB).

+ +

Setting the maximum size to 0 disables log rotation.

+ + +

DeprecatedMaxRequestSize

+ +

Examples

+ +
+MaxRequestSize 10485760
+MaxRequestSize 10m
+MaxRequestSize 0
+
+ +

Description

+ +

The MaxRequestSize 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.

+ +

This directive is deprecated and will be removed in a +future CUPS release. Use the LimitRequestBody +directive instead.

+ + +

CUPS 1.4/Mac OS X 10.6MultipleOperationTimeout

+ +

Examples

+ +
+MultipleOperationTimeout 60
+MultipleOperationTimeout 300
+MultipleOperationTimeout 86400
+
+ +

Description

+ +

The MultipleOperationTimeout directive sets the maximum amount +of time between files in a multi-file print job. The default is 300 seconds.

+ + +

Order

+ +

Examples

+ +
+<Location /path>
+  ...
+  Order Allow,Deny
+  Order Deny,Allow
+</Location>
+
+ +

Description

+ +

The Order directive defines the default access +control. The following values are supported:

+ +
    + +
  • allow,deny - Deny requests by default, + then check the Allow + lines followed by the Deny lines
  • + +
  • deny,allow - Allow requests by default, + then check the Deny + lines followed by the Allow lines
  • + +
+ +

The Order directive must appear inside a Location or Limit section.

+ + +

PageLog

+ +

Examples

+ +
+PageLog /var/log/cups/page_log
+PageLog /var/log/cups/page_log-%s
+PageLog syslog
+
+ +

Description

+ +

The PageLog directive sets the name of the page +log file. If the filename is not absolute then it is assumed to +be relative to the ServerRoot directory. The +default page log file is @CUPS_LOGDIR@/page_log.

+ +

The server name can be included in the filename by using +%s in the name.

+ +

The special name "syslog" can be used to send the page +information to the system log instead of a plain file.

+ + +

PageLogFormat

+ +

Examples

+ +
+PageLogFormat %p %u %j %T %P %C %{job-billing} %{job-originating-host-name} %{job-name} %{media} %{sides}
+PageLogFormat PAGE %p %u %j %P %C %{job-billing} %{job-originating-host-name}
+
+ +

Description

+ +

The PageLogFormat directive sets the format of lines +that are logged to the page log file. Sequences beginning with percent (%) +characters are replaced with the corresponding information, while all other +characters are copied literally. The following percent sequences are +recognized:

+ +
    + +
  • %%: Inserts a single percent character.
  • + +
  • %{name}: Inserts the value of the specified IPP + attribute.
  • + +
  • %C: Inserts the number of copies for the current page.
  • + +
  • %P: Inserts the current page number.
  • + +
  • %T: Inserts the current date and time in common log + format.
  • + +
  • %j: Inserts the job ID.
  • + +
  • %p: Inserts the printer name.
  • + +
  • %u: Inserts the username.
  • + +
+ +

The default is "%p %u %j %T %P %C %{job-billing} %{job-originating-host-name} %{job-name} %{media} %{sides}".

+ + +

CUPS 1.2/Mac OS X 10.5PassEnv

+ +

Examples

+ +
+PassEnv MY_ENV_VARIABLE
+
+ +

Description

+ +

The PassEnv directive specifies an environment +variable that should be passed to child processes. Normally, the +scheduler only passes the DYLD_LIBRARY_PATH, +LD_ASSUME_KERNEL, LD_LIBRARY_PATH, +LD_PRELOAD, NLSPATH, +SHLIB_PATH, TZ, and VGARGS +environment variables to child processes.

+ + +

CUPS 1.2/Mac OS X 10.5Policy

+ +

Examples

+ +
+<Policy name>
+  <Limit operation ... operation>
+  ...
+  </Limit>
+  <Limit operation ... operation>
+  ...
+  </Limit>
+  <Limit All>
+  ...
+  </Limit>
+</Policy>
+
+ +

Description

+ +

The Policy directive specifies IPP operation +access control limits. Each policy contains 1 or more Limit sections to set the +access control limits for specific operations - user limits, +authentication, encryption, and allowed/denied addresses, +domains, or hosts. The <Limit All> section +specifies the default access control limits for operations that +are not listed.

+ +

Policies are named and associated with printers via the +printer's operation policy setting +(printer-op-policy). The default policy for the +scheduler is specified using the DefaultPolicy +directive.

+ + +

Port

+ +

Examples

+ +
+Port 631
+Port 80
+
+ +

Description

+ +

The Port directive specifies a port to listen on. +Multiple Port lines can be specified to listen on +multiple ports. The Port directive is equivalent to +"Listen *:nnn". The default port is 631.

+ +
Note: + +

On systems that support IPv6, this directive will bind to both +the IPv4 and IPv6 wildcard address.

+ +
+ + +

PreserveJobHistory

+ +

Examples

+ +
+PreserveJobHistory On
+PreserveJobHistory Off
+
+ +

Description

+ +

The PreserveJobHistory directive controls whether +the history of completed, canceled, or aborted print jobs is +stored on disk.

+ +

A value of On (the default) preserves job +information until the administrator purges it with the +cancel command.

+ +

A value of Off removes the job information as +soon as each job is completed, canceled, or aborted.

+ + +

PreserveJobFiles

+ +

Examples

+ +
+PreserveJobFiles On
+PreserveJobFiles Off
+
+ +

Description

+ +

The PreserveJobFiles directive controls whether +the document files of completed, canceled, or aborted print jobs +are stored on disk.

+ +

A value of On preserves job files until the +administrator purges them with the cancel command. +Jobs can be restarted (and reprinted) as desired until they are +purged.

+ +

A value of Off (the default) removes the job +files as soon as each job is completed, canceled, or aborted.

+ + +

Printcap

+ +

Examples

+ +
+Printcap
+Printcap /etc/printcap
+Printcap /etc/printers.conf
+Printcap /Library/Preferences/org.cups.printers.plist
+
+ +

Description

+ +

The Printcap 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 @CUPS_DEFAUL_PRINTCAP@.

+ +

When a filename is specified (e.g. @CUPS_DEFAULT_PRINTCAP@), +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.

+ + +

PrintcapFormat

+ +

Examples

+ +
+PrintcapFormat BSD
+PrintcapFormat Solaris
+PrintcapFormat plist
+
+ +

Description

+ +

The PrintcapFormat directive controls the output format of the +printcap file. The default is to generate the plist format on Mac OS X, the +Solaris format on Solaris, and the BSD format on other operating systems.

+ + +

CUPS 1.1.13PrintcapGUI

+ +

Examples

+ +
+PrintGUI /usr/bin/glpoptions
+
+ +

Description

+ +

The PrintcapGUI directive sets the program to +associate with the IRIX printer GUI interface script which is +used by IRIX applications to display printer-specific options. +There is no default program.

+ + +

CUPS 1.1.21ReloadTimeout

+ +

Examples

+ +
+ReloadTimeout 0
+ReloadTimeout 30
+
+ +

Description

+ +

The ReloadTimeout directive specifies the number +of seconds the scheduler will wait for active jobs to complete +before doing a restart. The default is 30 seconds.

+ + +

CUPS 1.1.3RemoteRoot

+ +

Examples

+ +
+RemoteRoot remroot
+RemoteRoot root
+
+ +

Description

+ +

The RemoteRoot directive sets the username for +unauthenticated root requests from remote hosts. The default +username is remroot. Setting RemoteRoot +to root effectively disables this security +mechanism.

+ + +

RequestRoot

+ +

Examples

+ +
+RequestRoot /var/spool/cups
+RequestRoot /foo/bar/spool/cups
+
+ +

Description

+ +

The RequestRoot 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 ServerRoot directory. The +default request directory is @CUPS_REQUESTS@.

+ + +

CUPS 1.1.7Require

+ +

Examples

+ +
+<Location /path>
+  ...
+  Require group foo bar
+  Require user john mary
+  Require valid-user
+  Require user @groupname
+  Require user @SYSTEM
+  Require user @OWNER
+</Location>
+
+ +

Description

+ +

The Require directive specifies that +authentication is required for the resource. The +group keyword specifies that the authenticated user +must be a member of one or more of the named groups that +follow.

+ +

The user keyword specifies that the +authenticated user must be one of the named users or groups that +follow. Group names are specified using the "@" prefix.

+ +

The valid-user keyword specifies that any +authenticated user may access the resource.

+ +

The default is to do no authentication. This directive must +appear inside a Location or +Limit section.

+ + +

RIPCache

+ +

Examples

+ +
+RIPCache 8m
+RIPCache 1g
+RIPCache 2048k
+
+ +

Description

+ +

The RIPCache directive sets the size of the +memory cache used by Raster Image Processor ("RIP") filters such +as imagetoraster and pstoraster. 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.

+ + +

CUPS 1.1.16RootCertDuration

+ +

Examples

+ +
+RootCertDuration 0
+RootCertDuration 300
+
+ +

Description

+ +

The RootCertDuration directive specifies the +number of seconds the root certificate remains valid. +The scheduler will generate a new certificate as needed when the +number of seconds has expired. If set to 0, the root certificate +is generated only once on startup or on a restart. The default is +300 seconds.

+ + +

CUPS 1.1.7Satisfy

+ +

Examples

+ +
+<Location /path>
+  ...
+  Satisfy all
+  Satisfy any
+</Location>
+
+ +

Description

+ +

The Satisfy directive specifies whether all +conditions must be satisfied to allow access to the resource. If +set to all, then all authentication and access +control conditions must be satisfied to allow access.

+ +

Setting Satisfy to any 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.

+ +

The default is all. This directive must appear +inside a Location or Limit section.

+ + +

ServerAdmin

+ +

Examples

+ +
+ServerAdmin user@host
+ServerAdmin root@foo.bar.com
+
+ +

Description

+ +

The ServerAdmin directive identifies the email +address for the administrator on the system. By default the +administrator email address is root@server, where +server is the ServerName.

+ + +

CUPS 1.3.10ServerAlias

+ +

Examples

+ +
+ServerAlias althost
+ServerAlias foo.example.com
+ServerAlias bar.example.com
+ServerAlias *
+
+ +

Description

+ +

The ServerAlias directive specifies alternate names that the server is known by. By default it contains a list of all aliases associated with the ServerName. The special name "*" can be used to allow any hostname when accessing CUPS via an external network interfaces.

+ +
Note + +

The ServerAlias directive is used for HTTP Host header +validation when clients connect to the scheduler from external interfaces. +Using the special name "*" can expose your system to known browser-based +DNS rebinding attacks, even when accessing sites through a firewall. If the +auto-discovery of alternate names does not work, we recommend listing each +alternate name with a ServerAlias directive instead of using "*".

+ +
+ + +

ServerBin

+ +

Examples

+ +
+ServerBin /usr/lib/cups
+ServerBin /foo/bar/lib/cups
+
+ +

Description

+ +

The ServerBin directive sets the directory for +server-run executables. If an absolute path is not provided then +it is assumed to be relative to the ServerRoot directory. The +default executable directory is /usr/lib/cups, +/usr/lib32/cups, or /usr/libexec/cups +depending on the operating system.

+ + +

ServerCertificate

+ +

Examples

+ +
+ServerCertificate /etc/cups/ssl/server.crt
+
+ +

Description

+ +

The ServerCertificate 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 +/etc/cups/ssl/server.crt.

+ + +

ServerKey

+ +

Examples

+ +
+ServerKey /etc/cups/ssl/server.key
+
+ +

Description

+ +

The ServerKey directive specifies the location of +the SSL private key file used by the server when negotiating +encrypted connections.

+ +

The default key file is +/etc/cups/ssl/server.crt.

+ + +

ServerName

+ +

Examples

+ +
+ServerName foo.example.com
+ServerName myserver.example.com
+
+ +

Description

+ +

The ServerName directive specifies the hostname +that is reported to clients. By default the server name is the +hostname.

+ + +

ServerRoot

+ +

Examples

+ +
+ServerRoot /etc/cups
+ServerRoot /foo/bar/cups
+
+ +

Description

+ +

The ServerRoot directive specifies the absolute +path to the server configuration and state files. It is also used +to resolve relative paths in the cupsd.conf file. The +default server directory is /etc/cups.

+ + +

CUPS 1.1.21ServerTokens

+ +

Examples

+ +
+ServerTokens None
+ServerTokens ProductOnly
+ServerTokens Major
+ServerTokens Minor
+ServerTokens Minimal
+ServerTokens OS
+ServerTokens Full
+
+ +

Description

+ +

The ServerTokens directive specifies the +information that is included in the Server: header +of all HTTP responses. Table 4 lists the token name along with +the text that is returned. The default is +Minimal.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4: ServerToken Names and Values
NameValue
NoneNo Server: header is returned
ProductOnly"CUPS"
Major"CUPS 1"
Minor"CUPS 1.2"
Minimal"CUPS 1.2.N" where N is the patch release
OS"CUPS 1.2.N (UNAME)" where N is the patch release and + UNAME is the output of the uname(1) command
Full"CUPS 1.2.N (UNAME) IPP/1.1" where N is the patch + release and UNAME is the output of the uname(1) + command
+ + +

CUPS 1.2/Mac OS X 10.5SetEnv

+ +

Examples

+ +
+SetEnv PATH /usr/lib/cups/filter:/bin:/usr/bin:/usr/local/bin
+SetEnv MY_ENV_VAR foo
+
+ +

Description

+ +

The SetEnv directive specifies an environment +variable that should be passed to child processes.

+ + +

SSLListen

+ +

Examples

+ +
+SSLListen 127.0.0.1:443
+SSLListen 192.0.2.1:443
+
+ +

Description

+ +

The SSLListen directive specifies a network +address and port to listen for secure connections. Multiple +SSLListen directives can be provided to listen on +multiple addresses.

+ +

The SSLListen directive is similar to the SSLPort directive but allows you +to restrict access to specific interfaces or networks.

+ + +

SSLOptions

+ +

Examples

+ +
+SSLOptions None
+SSLOptions NoEmptyFragments
+
+ +

Description

+ +

The SSLOptions directive specifies additional SSL/TLS +protocol options to use for encrypted connected. Currently only two +options are supported - None (the default) for the most +secure mode and NoEmptyFragments to allow CUPS to work with +Microsoft Windows with the FIPS conformance mode enabled.

+ + +

SSLPort

+ +

Examples

+ +
+SSLPort 443
+
+ +

Description

+ +

The SSLPort directive specifies a port to listen +on for secure connections. Multiple SSLPort lines +can be specified to listen on multiple ports.

+ + +

SystemGroup

+ +

Examples

+ +
+SystemGroup lpadmin
+SystemGroup sys
+SystemGroup system
+SystemGroup root
+SystemGroup root lpadmin
+
+ +

Description

+ +

The SystemGroup directive specifies the system +administration group for System authentication. +Multiple groups can be listed, separated with spaces. The default +group list is @CUPS_SYSTEM_GROUPS@.

+ + +

TempDir

+ +

Examples

+ +
+TempDir /var/tmp
+TempDir /foo/bar/tmp
+
+ +

Description

+ +

The TempDir directive specifies an absolute path +for the directory to use for temporary files. The default +directory is @CUPS_REQUESTS@/tmp.

+ +

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 +/foo/bar/tmp:

+ +
+mkdir /foo/bar/tmp
+chmod a+rwxt /foo/bar/tmp
+
+ + +

Timeout

+ +

Examples

+ +
+Timeout 300
+Timeout 90
+
+ +

Description

+ +

The Timeout directive controls the amount of time +to wait before an active HTTP or IPP request times out. The +default timeout is 300 seconds.

+ + +

CUPS 1.2/Mac OS X 10.5UseNetworkDefault

+ +

Examples

+ +
+UseNetworkDefault yes
+UseNetworkDefault no
+
+ +

Description

+ +

The UseNetworkDefault directive controls whether +the client will use a network/remote printer as a default +printer. If enabled, the default printer of a server is used as +the default printer on a client. When multiple servers are +advertising a default printer, the client's default printer is +set to the first discovered printer, or to the implicit class for +the same printer available from multiple servers.

+ +

The default is @CUPS_USE_NETWORK_DEFAULT@.

+ + +

User

+ +

Examples

+ +
+User lp
+User guest
+
+ +

Description

+ +

The User directive specifies the UNIX user that +filter and CGI programs run as. The default user is +@CUPS_USER@.

+ +
Note: + +

You may not use user root, as that would expose +the system to unacceptable security risks. The scheduler will +automatically choose user nobody if you specify a +user whose ID is 0.

+ +
+ + + + diff --git a/doc/help/ref-error_log.html b/doc/help/ref-error_log.html new file mode 100644 index 0000000000..0109278022 --- /dev/null +++ b/doc/help/ref-error_log.html @@ -0,0 +1,55 @@ + + + + error_log + + + + +

error_log

+ +

The error_log file lists messages from the +scheduler - errors, warnings, etc. The LogLevel +directive controls which messages are logged:

+ +

+ +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'.
+ +

+ +

The level field contains the type of message:

+ +
    + +
  • A - Alert message (LogLevel alert) +
  • C - Critical error message (LogLevel crit) +
  • D - Debugging message (LogLevel debug) +
  • d - Detailed debugging message (LogLevel debug2) +
  • E - Normal error message (LogLevel error) +
  • I - Informational message (LogLevel info) +
  • N - Notice message (LogLevel notice) +
  • W - Warning message (LogLevel warn) +
  • X - Emergency error message (LogLevel emerg) + +
+ +

The date-time field contains the date and time of when +the page started printing. The format of this field is identical +to the data-time field in the access_log file.

+ +

The message fields contains a free-form textual +message. Messages from job filters are prefixed with "[Job +NNN]".

+ + + diff --git a/doc/help/ref-mailto-conf.html b/doc/help/ref-mailto-conf.html new file mode 100644 index 0000000000..0b9513220b --- /dev/null +++ b/doc/help/ref-mailto-conf.html @@ -0,0 +1,108 @@ + + + + mailto.conf + + + + +

mailto.conf

+ +

The /etc/cups/mailto.conf file contains several +directives that defines the local mail server and email +notification preferences for CUPS. 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.

+ + +

Cc

+ +

Examples

+ +
+Cc bigbrother@example.com
+Cc John Doe <jd@example.com>
+
+ +

Description

+ +

The Cc directive specifies an additional +recipient ("carbon copy") for all email notifications. The +default is to not send a copy to anyone but the subscriber.

+ + +

From

+ +

Examples

+ +
+From printserver@example.com
+From Your Happy Printer <printserver@example.com>
+
+ +

Description

+ +

The From directive specifies the sender of email +notifications. The default is the ServerAdmin +address defined in the cupsd.conf file.

+ + +

Sendmail

+ +

Examples

+ +
+Sendmail /usr/sbin/sendmail
+Sendmail /usr/lib/sendmail -bm -i
+
+ +

Description

+ +

The Sendmail directive specifies the command to +run to deliver an email locally. This directive cannot be used +with the SMTPServer directive, and if both +Sendmail and SMTPServer lines appear in the +mailto.conf file, only the last line is used. The +default is /usr/sbin/sendmail.

+ + +

SMTPServer

+ +

Examples

+ +
+SMTPServer mail.example.com
+SMTPServer 192.168.2.1
+
+ +

Description

+ +

The SMTPServer directive specifies a hostname or +IP address of a (possibly remote) SMTP mail server. This +directive cannot be used with the Sendmail directive, +and if both Sendmail and SMTPServer lines +appear in the mailto.conf file, only the last line is +used. The default is to use the Sendmail command +instead.

+ + +

Subject

+ +

Examples

+ +
+Subject [CUPS]
+Subject URGENT EMAIL NOTIFICATION
+
+ +

Description

+ +

The Subject directive specifies a prefix string to +add to the subject of each email notification. The default is to +not add a prefix string.

+ + + + diff --git a/doc/help/ref-page_log.html b/doc/help/ref-page_log.html new file mode 100644 index 0000000000..076cc4b9c6 --- /dev/null +++ b/doc/help/ref-page_log.html @@ -0,0 +1,77 @@ + + + + page_log + + + + +

page_log

+ +

The page_log file lists each page that is sent to a +printer. By default, each line contains the following information:

+ +

+ +printer user job-id date-time page-number num-copies job-billing job-originating-host-name job-name media sides
+ +
+ +DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 1 acme-123 localhost myjob letter one-sided
+ +DeskJet root 2 [20/May/1999:19:21:05 +0000] 2 1 acme-123 localhost myjob letter one-sided
+ +

+ +

The PageLogFormat +directive can be used to change this information.

+ +

The printer 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.

+ +

The user field contains the name of the user (the IPP +requesting-user-name attribute) that submitted this +file for printing.

+ +

The job-id field contains the job number of the page +being printed. Job numbers are reset to 1 whenever the spool +directory (/var/spool/cups) is cleared, so don't +depend on this number being unique!

+ +

The date-time field contains the date and time of when +the page started printing. The format of this field is identical +to the data-time field in the access_log +file.

+ +

The page-number and num-copies fields contain the +page number and number of copies being printed of that page. For +printers that cannot produce copies on their own, the +num-copies field will always be 1.

+ +

The job-billing field contains a copy of the +job-billing attribute provided with the IPP +Create-Job or Print-Job requests or "-" +if none was provided. + +

The job-originating-host-name field contains the hostname or IP +address of the client that printed the job.

+ +

The job-name field contains a copy of the +job-name attribute provided with the IPP +Create-Job or Print-Job requests or "-" +if none was provided. + +

The media field contains a copy of the +media attribute provided with the IPP +Create-Job or Print-Job requests or "-" +if none was provided. + +

The sides field contains a copy of the +sides attribute provided with the IPP +Create-Job or Print-Job requests or "-" +if none was provided. + + + diff --git a/doc/help/ref-ppdcfile.html b/doc/help/ref-ppdcfile.html new file mode 100644 index 0000000000..c3967f1c23 --- /dev/null +++ b/doc/help/ref-ppdcfile.html @@ -0,0 +1,2449 @@ + + + + PPD Compiler Driver Information File Reference + + + + +

PPD Compiler Driver Information File Reference

+ +

The CUPS PPD compiler reads meta files that contain descriptions +of one or more PPD files to be generated by +ppdc(1) or the corresponding driver interface +program drv(1). The source file format is plain +ASCII text that can be edited using your favorite text editor.

+ +

Directives may be placed anywhere on a line and are followed by +zero or more values.

+ +

Comments are supported using the C (/* ... */) and C++ (// ...) comment +mechanisms.

+ +

Directives that accept expressions look for sequences of the form:

+ +
+ +
NAME
+
Evaluates to 1 if NAME is defined, otherwise 0.
+ +
number
+ +
Evaluates to the specified integer; the number can be preceded by + a leading sign (+/-) followed by a decimal number (1234), octal number + (01234), or hexadecimal number (0x1234) using the same rules as C and + C++.
+ +
(NAME NAME ... number number ...)
+
Evaluates to the bitwise OR of each named #define constant or + number.
+ +
(NAME == OTHERNAME)
+
(NAME == number)
+
Evaluates to 1 if NAME is equal to the other named constant or + number, otherwise 0.
+ +
(NAME != OTHERNAME)
+
(NAME != number)
+
Evaluates to 1 if NAME is not equal to the other named constant or + number, otherwise 0.
+ +
(NAME < OTHERNAME)
+
(NAME < number)
+
Evaluates to 1 if NAME is less than to the other named constant or + number, otherwise 0.
+ +
(NAME <= OTHERNAME)
+
(NAME <= number)
+
Evaluates to 1 if NAME is less than or equal to the other named + constant or number, otherwise 0.
+ +
(NAME > OTHERNAME)
+
(NAME > number)
+
Evaluates to 1 if NAME is greater than to the other named constant + or number, otherwise 0.
+ +
(NAME >= OTHERNAME)
+
(NAME >= number)
+
Evaluates to 1 if NAME is greater than or equal to the other named + constant or number, otherwise 0.
+ +
+ +

Printer driver information can be grouped and shared using +curly braces ({ ... }); PPD files are written when a close +brace or end-of-file is seen and a PCFileName +directive has been defined.

+ + +

#define

+ +

Syntax

+ +
+#define name expression
+
+ +

Examples

+ +
+#define FOO 100
+#define BAR "Bar, Inc."
+
+ +

Description

+ +

The #define directive assigns a value to a name +which can be later referenced using $name. The name is +case-insensitive and can be any sequence of letters, numbers, +and the underscore. The value can be any valid expression.

+ +

Predefined Names

+ +

The following #define names are set by the PPD compiler:

+ +
    + +
  • CUPS_VERSION - The full CUPS version string, e.g. + "1.4.0"
  • + +
  • CUPS_VERSION_MAJOR - The major version number, e.g. + "1"
  • + +
  • CUPS_VERSION_MINOR - The minor version number, e.g. + "4"
  • + +
  • CUPS_VERSION_PATCH - The patch version number, e.g. + "0"
  • + +
  • PLATFORM_NAME - The operating system name used by the + current system as reported by "uname" ("Windows" on Microsoft + Windows)
  • + +
  • PLATFORM_ARCH - The processor architecture used by the + current system as reported by "uname -m" ("X86" or "X64" on Microsoft + Windows)
  • + +
+ +

See Also

+ +

#include

+ + +

#elif

+ +

Syntax

+ +
+#elif expression
+
+ +

Examples

+ +
+#if HAVE_FOO
+...
+#elif (HAVE_BAR >= 999)
+...
+#else
+...
+#endif 
+
+ +

Description

+ +

The #elif directive allows portions of a driver information file +to be used conditionally. #elif directives must appear after a +corresponding #if directive.

+ +

See Also

+ +

#else, +#endif, +#if

+ + +

#else

+ +

Syntax

+ +
+#else
+
+ +

Examples

+ +
+#if HAVE_FOO
+...
+#elif (HAVE_BAR >= 999)
+...
+#else
+...
+#endif 
+
+ +

Description

+ +

The #else directive allows portions of a driver information file +to be used conditionally when the corresponding +#if and #elif +expressions are non-zero.

+ +

See Also

+ +

#elif, +#endif, +#if

+ + +

#endif

+ +

Syntax

+ +
+#endif
+
+ +

Examples

+ +
+#if HAVE_FOO
+...
+#elif (HAVE_BAR >= 999)
+...
+#else
+...
+#endif 
+
+ +

Description

+ +

The #endif directive ends a conditional block of a driver +information file. It must appear after all of the +#if, #elif, +and #else directives for the current +conditional block.

+ +

See Also

+ +

#elif, +#else, +#if

+ + +

#font

+ +

Syntax

+ +
+#font name encoding "version" charset status
+
+ +

Examples

+ +
+#font Courier Standard "(1.05)" Standard ROM
+#font Symbol Special "(001.005)" Special ROM
+#font Barcode-Foo Special "(1.0)" Special Disk
+#font Unicode-Foo Expert "(2.0)" Adobe-Identity ROM
+
+ +

Description

+ +

The #font directive defines a "base font" for all +printer drivers. The name is the PostScript font name.

+ +

The encoding is the default encoding of the font, usually +Standard, Expert, or Special, as +defined in the Adobe PPD file specification.

+ +

The version is the PostScript string definition that +corresponds to the font version number.

+ +

The charset defines the available characters in the font, +usually Standard or Special, as defined in the +Adobe PPD file specification.

+ +

The status is the installation status of the font and must be +either the word ROM or Disk. + +

Base fonts differ from fonts defined using the Font directive in that they are not +automatically associated with all drivers - you must use the +special Font * directive to include them in a +driver.

+ +

Currently the #font directive is used mainly for +defining the standard raster fonts in the +<font.defs> include file.

+ +

See Also

+ +

#include, +Font

+ + +

#if

+ +

Syntax

+ +
+#if name or expression
+
+ +

Examples

+ +
+#if HAVE_FOO
+...
+#elif (HAVE_BAR >= 999)
+...
+#else
+...
+#endif 
+
+ +

Description

+ +

The #if directive allows portions of a driver information file +to be used conditionally. When followed by a name, the data that follows is +used only when the name is defined, otherwise the data is ignored. +#if directives can be nested up to 100 times.

+ +

See Also

+ +

#elif, +#else, +#endif

+ + +

#include

+ +

Syntax

+ +
+#include <filename>
+#include "filename"
+
+ +

Examples

+ +
+#include <font.defs>
+#include "myfile.h"
+
+ +

Description

+ +

The #include directive reads the named driver +information file. If the filename is included inside angle +brackets (<filename>), then the PPD compiler will +look for the file in all of the include directories it knows +about. Otherwise, the file is opened in the current directory +relative to the current driver information file, and if that +fails then it looks in the include directories for the file.

+ +

The #include directive can be nested to as many +files as are allowed by the host operating system, typically at +least 100 files.

+ +

See Also

+ +

#define, +#font, +#media

+ + +

#media

+ +

Syntax

+ +
+#media name width length
+#media "name/text" width length
+
+ +

Examples

+ +
+#media "Letter/Letter - 8.5x11in" 8.5in 11in
+#media "A4/A4 - 210x297mm" 210mm 297mm
+#media "w936h1368/Super B/A3 - 13x19in" 936 1368
+#media Photo 4in 6in
+
+ +

Description

+ +

The #media directive defines a named media size for +inclusion in a driver. The name with optional user text defines +the name for the media size and is used with the MediaSize directive to associate +the media size with the driver. The name may contain up to 40 ASCII +characters within the range of decimal 33 to decimal 126 inclusive, +except for the characters comma (44), slash (47) and colon (58). +The user text, if supplied, may not exceed 80 bytes in length.

+ +

The width and length define the dimensions of the media. Each +number is optionally followed by one of the following unit +suffixes:

+ +
    + +
  • cm - centimeters
  • + +
  • ft - feet
  • + +
  • in - inches
  • + +
  • m - meters
  • + +
  • mm - millimeters
  • + +
  • pt - points (72 points = 1 inch)
  • + +
+ +

Points are assumed if no units are specified. + +

See Also

+ +

#include, +CustomMedia, +MediaSize

+ + +

#po

+ +

Syntax

+ +
+#po locale filename
+
+ +

Examples

+ +
+#po es "es.po"
+#po fr_CA "mydriver-fr_CA.po"
+
+ +

Description

+ +

The #po directive defines a message catalog to use for the +given POSIX language abbreviation. Multiple #po directives can be +specified to list multiple catalogs. The filename can be an absolute path or +relative to the driver information file. GNU gettext and Mac OS X .strings +files are supported.

+ + +

Attribute

+ +

Syntax

+ +
+Attribute name "" value
+Attribute name keyword value
+Attribute name "keyword/text" value
+
+ +

Examples

+ +
+Attribute cupsInkChannels "" 1
+Attribute cupsAllDither 600dpi "1.0"
+Attribute fooProfile "Photo/Photographic Profile" "photopro.icc"
+
+ +

Description

+ +

The Attribute directive creates a PPD attribute. The +name may contain up to 40 ASCII characters within the range of decimal +33 to decimal 126 inclusive, except for the characters comma (44), +slash (47) and colon (58).

+ +

The selector can be the empty string ("") or text of up +to 80 bytes.

+ +

The value is any string or number; the string may contain multiple +lines, however no one line may exceed 255 bytes.

+ +

See Also

+ +

LocAttribute

+ + +

Choice

+ +

Syntax

+ +
+Choice name "code"
+Choice "name/text" "code"
+
+ +

Examples

+ +
+Choice None "<</MediaType (None)>>setpagedevice"
+Choice "False/No" "<</cupsCompression 0>>setpagedevice"
+
+ +

Description

+ +

The Choice directive adds a single choice to the +current option. The name may contain up to 40 ASCII characters within +the range of decimal 33 to decimal 126 inclusive, except for the +characters comma (44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes +in length. If no text is provided, the name is used.

+ +

The code is any string and may contain multiple lines, +however no one line may exceed 255 bytes.

+ +

See Also

+ +

ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

ColorDevice

+ +

Syntax

+ +
+ColorDevice boolean-value
+
+ +

Examples

+ +
+ColorDevice no
+ColorDevice yes
+
+ +

Description

+ +

The ColorDevice directive tells the application if +the printer supports color. It is typically used in conjunction +with the ColorModel directive +to provide color printing support.

+ +

See Also

+ +

ColorModel

+ + +

DeprecatedColorModel

+ +

Syntax

+ +
+ColorModel name colorspace colororder compression
+ColorModel "name/text" colorspace colororder compression
+
+ +

Examples

+ +
+ColorModel Gray/Grayscale w chunky 0
+ColorModel RGB/Color rgb chunky 0
+ColorModel CMYK cmyk chunky 0
+
+ +

Description

+ +

The ColorModel directive is a convenience directive +which creates a ColorModel option and choice for the current +printer driver. The name may contain up to 40 ASCII characters within +the range of decimal 33 to decimal 126 inclusive, except for the +characters comma (44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

The colorspace argument is one of the standard colorspace +keywords defined later in this appendix in the section titled, +"Colorspace Keywords".

+ +

The colororder argument is one of the standard color order +keywords defined later in this appendix in the section titled, +"Color Order Keywords".

+ +

The compression argument is any number and is assigned to the +cupsCompression attribute in the PostScript page device +dictionary.

+ +

See Also

+ +

Choice, +ColorDevice, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

DeprecatedColorProfile

+ +

Syntax

+ +
+ColorProfile resolution/mediatype gamma density matrix
+
+ +

Examples

+ +
+ColorProfile -/- 1.7 1.0
+     1.0    0.0    0.0
+     0.0    1.0    0.0
+     0.0    0.0    1.0
+
+ColorProfile 360dpi/- 1.6 1.0
+     1.0   -0.05  -0.3
+    -0.35   1.0   -0.15
+    -0.095 -0.238  0.95
+
+ColorProfile 720dpi/Special 1.5 1.0
+     1.0    0.0   -0.38
+    -0.4    1.0    0.0
+     0.0   -0.38   0.9
+
+ +

Description

+ +

The ColorProfile directive defines a CMY +transform-based color profile. The resolution and mediatype +arguments specify the Resolution and MediaType +choices which use the profile; the hyphen (-) is used to +specify that any resolution or mediatype can be used with the +profile.

+ +

The gamma argument specifies the gamma correction to apply to +the color values (P = pg) and is a real number +greater than 0. Values larger than 1 cause a general lightening +of the print while values smaller than 1 cause a general +darkening of the print. A value of 1 disables gamma +correction.

+ +

The density argument specifies the linear density correction +to apply to the color values (P = d * pg) and is a +real number greater than 0 and less than or equal to 1. A value +1 of disables density correction while lower values produce +proportionately lighter output.

+ +

The matrix argument specifies a 3x3 linear transformation +matrix in row-major order. The matrix is applied only to the CMY +component of a RGB to CMYK transformation and is not used when +printing in grayscale or CMYK mode unless the printer only +supports printing with 3 colors.

+ +

See Also

+ +

SimpleColorProfile

+ + +

Copyright

+ +

Syntax

+ +
+Copyright "text"
+
+ +

Examples

+ +
+Copyright "Copyright 2008 by Foo Enterprises"
+
+Copyright
+"This software 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 software 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 software; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+MA 02111 USA"
+
+ +

Description

+ +

The Copyright directive adds text comments to the +top of a PPD file, typically for use in copyright notices. The +text argument can contain multiple lines of text, but no line +may exceed 255 bytes.

+ + +

CustomMedia

+ +

Syntax

+ +
+CustomMedia name width length left bottom right top
+    "size-code" "region-code"
+
+CustomMedia "name/text" width length left bottom right top
+    "size-code" "region-code"
+
+ +

Examples

+ +
+CustomMedia Letter 8.5in 11in 0.25in 0.46in 0.25in 0.04in
+    "<</PageSize[612 792]/ImagingBBox null/ManualFeed false>>
+     setpagedevice"
+    "<</PageSize[612 792]/ImagingBBox null/ManualFeed true>>
+     setpagedevice"
+
+CustomMedia "A4/A4 - 210x297mm" 210mm 297mm 12 12 12 12
+    "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+    "<</PageSize[595 842]/ImagingBBox null>>setpagedevice"
+
+ +

Description

+ +

The CustomMedia directive adds a custom media size to +the driver. The name may contain up to 40 ASCII characters within the +range of decimal 33 to decimal 126 inclusive, except for the characters +comma (44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

The width and length arguments specify the dimensions of the +media as defined for the #media +directive.

+ +

The left, bottom, right, and top arguments specify the +printable margins of the media.

+ +

The size-code and region-code arguments specify the +PostScript commands to run for the PageSize and +PageRegion options, respectively. The commands can +contain multiple lines, however no line may be more than 255 +bytes in length.

+ +

See Also

+ +

#media, +MediaSize

+ + +

Cutter

+ +

Syntax

+ +
+Cutter boolean-value
+
+ +

Examples

+ +
+Cutter yes
+Cutter no
+
+ +

Description

+ +

The Cutter directive specifies whether the printer +has a built-in media cutter. When a cutter is present, the +printer's PPD file will contain a CutMedia option that +allows the user to control whether the media is cut at the end +of the job.

+ +

See Also

+ +

Choice, +ColorModel, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

DeprecatedDarkness

+ +

Syntax

+ +
+Darkness temperature name
+Darkness temperature "name/text"
+
+ +

Examples

+ +
+Darkness 0 Light
+Darkness 2 "Normal/Standard"
+
+ +

Description

+ +

The Darkness directive defines a choice for the +cupsDarkness option which sets the +cupsCompression attribute in the PostScript page device +dictionary. It is used with the CUPS rastertolabel +sample driver to control the print head temperature and +therefore the darkness of the print.

+ +

The temperature argument specifies a temperature value for +the Dymo driver from 0 (lowest) to 3 (highest), with 2 +representing the normal setting.

+ +

The name may contain up to 40 ASCII characters within the range of +decimal 33 to decimal 126 inclusive, except for the characters comma +(44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

DriverType

+ +

Syntax

+ +
+DriverType type
+
+ +

Examples

+ +
+DriverType custom
+DriverType escp
+DriverType pcl
+DriverType ps
+
+ +

Description

+ +

The DriverType directive tells the PPD compiler +which DDK filters to include in the PPD file. The following +types are supported:

+ +
    + +
  • custom - Use only those filters that are + defined in the driver information file
  • + +
  • epson - Use the CUPS sample Epson driver filter + rastertoepson
  • + +
  • escp - Use the ESC/P DDK driver filters + commandtoescpx and + rastertoescpx
  • + +
  • hp - Use the CUPS sample HP driver filter + rastertohp
  • + +
  • label - Use the CUPS sample label driver filter rastertolabel
  • + +
  • pcl - Use the HP-PCL DDK driver filters + commandtopclx and + rastertopclx
  • + +
  • ps - Use no filters; this driver is for a + standard PostScript device
  • + +
+ +

See Also

+ +

Filter, +ModelNumber

+ + +

Duplex

+ +

Syntax

+ +
+Duplex type
+
+ +

Examples

+ +
+Duplex none
+Duplex normal
+Duplex flip
+Duplex rotated
+Duplex manualtumble
+
+ +

Description

+ +

The Duplex directive determines whether double-sided printing +is supported in the current driver. The type argument specifies the type +of duplexing that is supported:

+ +
    + +
  • none - double-sided printing is not + supported
  • + +
  • normal - double-sided printing is + supported
  • + +
  • flip - double-sided printing is supported, + but the back side image needs to be flipped vertically + (used primarily with inkjet printers)
  • + +
  • rotated - double-sided printing is supported, + but the back side image needs to be rotated 180 degrees for + DuplexNoTumble
  • + +
  • manualtumble - double-sided printing is supported, + but the back side image needs to be rotated 180 degrees for + DuplexTumble
  • + +
+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

FileName

+ +

Syntax

+ +
+FileName "filename"
+
+ +

Examples

+ +
+FileName "Acme Laser Printer 2000"
+FileName "Acme Ink Waster 1000"
+
+ +

Description

+ +

The FileName attribute specifies the "long" name of the +PPD file for the current driver.

+ +

See Also

+ +

Manufacturer, +ModelName, +PCFileName, +Version

+ + +

Filter

+ +

Syntax

+ +
+Filter mime-type cost program
+
+ +

Examples

+ +
+Filter application/vnd.cups-raster 50 rastertofoo
+Filter application/vnd.hp-HPGL 25 /usr/foo/filter/hpgltofoo
+
+ +

Description

+ +

The Filter directive adds a filter for the current +driver. The mime-type argument is a valid MIME media type name +as defined in a CUPS mime.types file.

+ +

The cost argument specifies the relative cost of the filter. +In general, use a number representing the average percentage of +CPU time that is used when printing the specified MIME media +type.

+ +

The program argument specifies the program to run; if the +program is not an absolute filename, then CUPS will look for the +program in the CUPS filter directory.

+ +

See Also

+ +

DriverType

+ + +

DeprecatedFinishing

+ +

Syntax

+ +
+Finishing name
+Finishing "name/text"
+
+ +

Examples

+ +
+Finishing None
+Finishing "Glossy/Photo Overcoat"
+
+ +

Description

+ +

The Finishing directive adds a choice to the +cupsFinishing option. The name may contain up to 40 ASCII +characters within the range of decimal 33 to decimal 126 inclusive, +except for the characters comma (44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

The name is stored in the OutputType attribute in the +PostScript page device dictionary.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

Font

+ +

Syntax

+ +
+Font name encoding "version" charset status
+Font *
+
+ +

Examples

+ +
+Font *
+Font Courier Standard "(1.05)" Standard ROM
+Font Symbol Special "(001.005)" Special ROM
+Font Barcode-Foo Special "(1.0)" Special Disk
+Font Unicode-Foo Expert "(2.0)" Adobe-Identity ROM
+
+ +

Description

+ +

The Font directive defines a "device font" for the +current printer driver. The name is the PostScript font name.

+ +

The encoding is the default encoding of the font, usually +Standard, Expert, or Special, as +defined in the Adobe PPD file specification.

+ +

The version is the PostScript string definition that +corresponds to the font version number.

+ +

The charset defines the available characters in the font, +usually Standard or Special, as defined in the +Adobe PPD file specification.

+ +

The status is the installation status of the font and must be +either the word ROM or Disk.

+ +

Device fonts differ from fonts defined using the #font directive in that they are +automatically associated with the current driver. Fonts defined +using #font may be imported into the current driver +using the Font * form of this directive.

+ +

See Also

+ +

#font

+ + +

Group

+ +

Syntax

+ +
+Group name
+Group "name/text"
+
+ +

Examples

+ +
+Group General
+Group "InstallableOptions/Options Installed"
+Group "Special/Vendor Options"
+
+ +

Description

+ +

The Group directive specifies the group for new +Option directives. The name may contain up to 40 ASCII +characters within the range of decimal 33 to decimal 126 inclusive, +except for the characters comma (44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 40 bytes in length. +If no text is provided, the name is used.

+ +

The names General and InstallableOptions +are predefined for the standard Adobe UI keywords and for installable +options, respectively.

+ +
+ + + +
Note: + +

Because of certain API binary compatibility issues, + CUPS limits the length of PPD group translation strings + (text) to 40 bytes, while the PPD specification + allows for up to 80 bytes.

+ +
+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +InputSlot, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

HWMargins

+ +

Syntax

+ +
+HWMargins left bottom right top
+
+ +

Examples

+ +
+HWMargins 18 36 18 36
+HWMargins 0.25in 0.5in 0.25in 0.5in
+HWMargins 0.6cm 1.2cm 0.6cm 1.2cm
+
+ +

Description

+ +

The HWMargins directive specifies the current +margins for MediaSize that +follow. The left, bottom, right, and top margin values specify +the printable margins.

+ +

See Also

+ +

MediaSize

+ + +

InputSlot

+ +

Syntax

+ +
+InputSlot position name
+InputSlot position "name/text"
+
+ +

Examples

+ +
+InputSlot 0 Auto
+InputSlot 1 "Upper/Tray 1"
+
+ +

Description

+ +

The InputSlot directive adds a new choice to the +InputSlot option. The position argument is a number +from 0 to 232-1 specifying the value that is placed +in the MediaPosition attribute in the PostScript page +device dictionary.

+ +

The name may contain up to 40 ASCII characters within the range of +decimal 33 to decimal 126 inclusive, except for the characters comma +(44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +Installable, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

Installable

+ +

Syntax

+ +
+Installable name
+Installable "name/text"
+
+ +

Examples

+ +
+Installable EnvTray
+Installable "Option1/Duplexer Installed"
+
+ +

Description

+ +

The Installable directive adds a new boolean option +to the InstallableOptions group with a default value of +False. The name may contain up to 40 ASCII characters +within the range of decimal 33 to decimal 126 inclusive, except for +the characters comma (44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ + +

LocAttribute

+ +

Syntax

+ +
+LocAttribute name "keyword/text" value
+
+ +

Examples

+ +
+LocAttribute fooProfile "Photo/Photographic Profile" "photopro.icc"
+
+ +

Description

+ +

The LocAttribute directive creates a localized PPD +attribute. The name may contain up to 40 ASCII characters within the +range of decimal 33 to decimal 126 inclusive, except for the characters +comma (44), slash (47) and colon (58).

+ +

The selector can be the empty string ("") or text of up +to 80 bytes.

+ +

The value is any string or number; the string may contain multiple +lines, however no one line may exceed 255 bytes.

+ +

See Also

+ +

Attribute

+ + +

ManualCopies

+ +

Syntax

+ +
+ManualCopies boolean-value
+
+ +

Examples

+ +
+ManualCopies no
+ManualCopies yes
+
+ +

Description

+ +

The ManualCopies directive specifies whether copies +need to be produced by the RIP filters. The default is +no.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +MediaType, +Option, +Resolution, +UIConstraints

+ + +

Manufacturer

+ +

Syntax

+ +
+Manufacturer "name"
+
+ +

Examples

+ +
+Manufacturer "Foo"
+Manufacturer "HP"
+
+ +

Description

+ +

The Manufacturer directive specifies the +manufacturer name for the current driver. The name argument must +conform to the manufacturer name requirements in the Adobe PPD +file specification.

+ +

See Also

+ +

FileName, +ModelName, +PCFileName, +Version

+ + +

MaxSize

+ +

Syntax

+ +
+MaxSize width length
+
+ +

Examples

+ +
+MaxSize 36in 100ft
+MaxSize 300cm 30m
+
+ +

Description

+ +

The MaxSize directive specifies the maximum width +and length that is supported for custom page sizes.

+ +

See Also

+ +

MinSize, +VariablePaperSize

+ + +

MediaSize

+ +

Syntax

+ +
+MediaSize name
+
+ +

Examples

+ +
+MediaSize Letter
+MediaSize A4
+
+ +

Description

+ +

The MediaSize directive adds the named size to the +current printer driver using the current margins defined with +the HWMargins directive. The +name argument must match a media size defined using the #media directive.

+ +

See Also

+ +

#media, +HWMargins

+ + +

MediaType

+ +

Syntax

+ +
+MediaType type name
+MediaType type "name/text"
+
+ +

Examples

+ +
+MediaType 0 Auto
+MediaType 1 "Plain/Plain Paper"
+
+ +

Description

+ +

The MediaType directive adds a new choice to the +MediaType option. The type argument is a number +from 0 to 232-1 specifying the value that is placed +in the cupsMediaType attribute in the PostScript page +device dictionary.

+ +

The name may contain up to 40 ASCII characters within the range of +decimal 33 to decimal 126 inclusive, except for the characters comma +(44), slash (47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

The name is placed in the MediaType attribute in the +PostScript page device dictionary.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +Option, +Resolution, +UIConstraints

+ + +

MinSize

+ +

Syntax

+ +
+MinSize width length
+
+ +

Examples

+ +
+MinSize 4in 8in
+MinSize 10cm 20cm
+
+ +

Description

+ +

The MinSize directive specifies the minimum width +and length that is supported for custom page sizes.

+ +

See Also

+ +

MaxSize, +VariablePaperSize

+ + +

ModelName

+ +

Syntax

+ +
+ModelName "name"
+
+ +

Examples

+ +
+ModelName "Foo Laser Printer 2000"
+ModelName "Colorific 123"
+
+ +

Description

+ +

The ModelName directive sets the printer name for +the ModelName, NickName, and +ShortNickName attributes for the printer driver. The +name is any string of letters, numbers, spaces, and the +characters ".", "/", "-", and "+" and should not begin with the +manufacturer name since the PPD compiler will add this +automatically for you. The maximum length of the name string is +31 bytes to conform to the Adobe limits on the length of +ShortNickName.

+ +

See Also

+ +

FileName, +Manufacturer, +PCFileName, +Version

+ + +

ModelNumber

+ +

Syntax

+ +
+ModelNumber expression
+
+ +

Examples

+ +
+ModelNumber 123
+ModelNumber ($PCL_PAPER_SIZE $PCL_PJL)
+
+ +

Description

+ +

The ModelNumber directive sets the +cupsModelNumber attribute for the printer driver, which +is often used by the printer driver filter to tailor its output +for the current device. The number is any integer or bitwise OR +of integers and constants that is appropriate for the printer +driver filters.

+ +

A complete list of printer driver model number constants is +available later in this appendix in the section titled, "Printer Driver ModelNumber +Constants".

+ +

See Also

+ +

DriverType, +Filter

+ + +

Option

+ +

Syntax

+ +
+Option name type section order
+Option "name/text" type section order
+
+ +

Examples

+ +
+Option Punch Boolean AnySetup 10
+Option "fooFinish/Finishing Option" PickOne DocumentSetup 10 
+
+ +

Description

+ +

The Option directive creates a new option in the +current group, by default the General group. The name +may contain up to 40 ASCII characters within the range of decimal 33 +to decimal 126 inclusive, except for the characters comma (44), slash +(47) and colon (58).

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

The type argument is one of the following keywords:

+ +
    + +
  • Boolean - a true/false option
  • + +
  • PickOne - allows the user to pick one + choice from a list
  • + +
  • PickMany - allows the user to pick zero or + more choices from a list
  • + +
+ +

The section argument is one of the following keywords:

+ +
    + +
  • AnySetup - The option can be placed in + either the DocumentSetup or PageSetup sections of the + PostScript document
  • + +
  • DocumentSetup - The option must be placed + in the DocumentSetup section of the PostScript document; + this does not allow the option to be overridden on + individual pages
  • + +
  • ExitServer - The option must be placed in a + separate initialization job prior to the document (not + used for raster printer drivers)
  • + +
  • JCLSetup - The option contains job control + language commands and must be sent prior to the document + using the JCLBegin and + JCLToPSInterpreter attributes (not used for + raster printer drivers)
  • + +
  • PageSetup - The option must be placed at the + beginning of each page in the PostScript document
  • + +
  • Prolog - The option must be placed in the + prolog section of the PostScript document; this is + typically used to add special comments for high-end + typesetters, but can also be used to add CUPS PostScript + job ticket comments.
  • + +
+ +

The order argument is a real number greater than or equal to +0.0 and is used to sort the printer commands from many options +before sending them to the printer or RIP filter.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Resolution, +UIConstraints

+ + +

PCFileName

+ +

Syntax

+ +
+PCFileName "filename.ppd"
+
+ +

Examples

+ +
+PCFileName "foljt2k1.ppd"
+PCFileName "deskjet.ppd"
+
+ +

Description

+ +

The PCFileName attribute specifies the name of the +PPD file for the current driver. The filename argument must +conform to the Adobe PPD file specification and can be no more +than 8 filename characters plus the extension ".ppd".

+ +

See Also

+ +

FileName, +Manufacturer, +ModelName, +Version

+ + +

DeprecatedResolution

+ +

Syntax

+ +
+Resolution colorspace bits-per-color row-count row-feed row-step name
+Resolution colorspace bits-per-color row-count row-feed row-step "name/text"
+
+ +

Examples

+ +
+Resolution - 8 0 0 0 300dpi
+Resolution k 8 0 0 0 "600x300dpi/600 DPI Grayscale"
+
+ +

Description

+ +

The Resolution directive creates a new +Resolution option choice which sets the +HWResolution, cupsBitsPerColor, +cupsRowCount, cupsRowFeed, +cupsRowStep, and optionally the cupsColorSpace +page device dictionary attributes. The colorspace argument +specifies a colorspace to use for the specified resolution and +can be the hyphen (-) character to make no change to +the selected color model or any keyword listed in the section +titled, "Colorspace Keywords", to +force the named colorspace.

+ +

The bits-per-color argument specifies the number of bits per +color to generate when RIP'ing a job. The values 1, 2, 4, and 8 +are currently supported by CUPS.

+ +

The row-count, row-feed, and row-step argument specify the +driver-dependent values for the cupsRowCount, +cupsRowFeed, and cupsRowStep attributes, +respectively. Most drivers leave these attributes set to 0, but +any number from 0 to 232-1 is allowed.

+ +

The name argument must conform to the resolution naming +conventions in the Adobe PPD file specification, either +HHHdpi for symmetric resolutions or HHHxVVVdpi +for asymmetric resolutions. The HHH and VVV in +the examples represent the horizontal and vertical resolutions +which must be positive integer values.

+ +

If provided, the text can be any string up to 80 bytes in length. +If no text is provided, the name is used.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +UIConstraints

+ + +

DeprecatedSimpleColorProfile

+ +

Syntax

+ +
+SimpleColorProfile resolution/mediatype density
+    yellow-density red-density gamma
+    red-adjust green-adjust blue-adjust
+
+ +

Examples

+ +
+SimpleColorProfile -/- 100 100 200 1.0 0 0 0
+
+SimpleColorProfile 360dpi/- 100 95 150 1.2 5 10 15
+
+SimpleColorProfile 720dpi/Glossy 100 90 120 1.5 -5 5 10
+
+ +

Description

+ +

The SimpleColorProfile directive creates a +matrix-based ColorProfile. +The resolution and mediatype arguments specify the +Resolution and MediaType choices which use the +profile; the hyphen (-) is used to specify that any +resolution or mediatype can be used with the profile.

+ +

The density argument specifies the linear density correction +to apply to the color values (P = d * 0.01 * pg) and +is an integer greater than 0 and less than or equal to 100. A +value 100 of disables density correction while lower values +produce proportionately lighter output. The density value +adjusts all color channels equally in all color modes.

+ +

The yellow-density argument specifies the density of the +yellow channel when printing in grayscale or RGB mode and is an +integer greater than 0 and less then or equal to 100. A value of +100 disables yellow density correction while lower values +produce proportionately lighter output.

+ +

The red-density argument specifies the two-color density +limit (e.g. C + M, C + Y, M + Y) when printing in grayscale or +RGB mode and is an integer greater than 0 and less then or equal +to 200. A value of 200 disables two-color density correction +while lower values produce proportionately lighter output.

+ +

The gamma argument specifies the gamma correction to apply to +the color values (P = pg) and is a real number +greater than 0. Values larger than 1 cause a general lightening +of the print while values smaller than 1 cause a general +darkening of the print. A value of 1 disables gamma +correction.

+ +

The red-adjust, green-adjust, blue-adjust arguments specify +the percentage of color to add or remove. Positive red-adjust +values add magenta and negative values add yellow. Positive +green-adjust values add cyan and negative values add yellow. +Positive blue-adjust values add cyan and negative values add +magenta. Values of 0 disable color adjustments.

+ +

See Also

+ +

ColorProfile

+ + +

Throughput

+ +

Syntax

+ +
+Throughput pages-per-minute
+
+ +

Examples

+ +
+Throughput 1
+Throughput 10
+
+ +

Description

+ +

The Throughput directive sets the Throughput +attribute for the current printer driver. The pages-per-minute +argument is a positive integer representing the peak number of +pages per minute that the printer is capable of producing. Use a +value of 1 for printers that produce less than 1 page per +minute.

+ + +

UIConstraints

+ +

Syntax

+ +
+UIConstraints "*Option1 *Option2"
+UIConstraints "*Option1 Choice1 *Option2"
+UIConstraints "*Option1 *Option2 Choice2"
+UIConstraints "*Option1 Choice1 *Option2 Choice2"
+
+ +

Examples

+ +
+UIConstraints "*Finishing *MediaType"
+UIConstraints "*Option1 False *Duplex"
+UIConstraints "*Duplex *MediaType Transparency"
+UIConstraints "*Resolution 600dpi *ColorModel RGB"
+
+ +

Description

+ +

The UIConstraints directive adds a constraint +between two options. Constraints inform the application when a +user has chosen incompatible options. Each option name is +preceded by the asterisk (*). If no choice is given for +an option, then all choices except False and +None will conflict with the other option and choice(s). +Since the PPD compiler automatically adds reciprocal constraints +(option A conflicts with option B, so therefore option B +conflicts with option A), you need only specify the constraint +once.

+ +

See Also

+ +

Choice, +ColorModel, +Cutter, +Darkness, +Duplex, +Finishing, +Group, +InputSlot, +Installable, +MediaType, +Option, +Resolution

+ + +

VariablePaperSize

+ +

Syntax

+ +
+VariablePaperSize boolean-value
+
+ +

Examples

+ +
+VariablePaperSize yes
+VariablePaperSize no
+
+ +

Description

+ +

The VariablePaperSize directive specifies whether +the current printer supports variable (custom) page sizes. When +yes is specified, the PPD compiler will include the +standard PPD attributes required to support custom page +sizes.

+ +

See Also

+ +

MaxSize, +MinSize

+ + +

Version

+ +

Syntax

+ +
+Version number
+
+ +

Examples

+ +
+Version 1.0
+Version 3.7
+
+ +

Description

+ +

The Version directive sets the FileVersion +attribute in the PPD file and is also used for the +NickName attribute. The number argument is a positive +real number.

+ +

See Also

+ +

Manufacturer, +ModelName, +PCFileName

+ + +

Standard Include Files

+ +

Table B-1 shows the standard include +files which are provided with the DDK.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table B-1, +Standard Include Files
Include FileDescription
<font.defs>Defines all of the + standard fonts which are included with ESP Ghostscript + and the Apple PDF RIP.
<epson.h>Defines all of the + CUPS ESC/P sample driver constants.
<escp.h>Defines all of the + DDK ESC/P driver constants.
<hp.h>Defines all of the + CUPS HP-PCL sample driver constants.
<label.h>Defines all of the + CUPS label sample driver constants.
<media.defs>Defines all of the + standard media sizes listed in Appendix B of the Adobe + PostScript Printer Description File Format + Specification.
<pcl.h>Defines all of the + DDK HP-PCL driver constants.
<raster.defs>Defines all of the CUPS + raster format constants.
+ +

Printer Driver ModelNumber Constants

+ +

The CUPS DDK and sample drivers use the +cupsModelNumber attribute in the PPD file to tailor +their output to the printer. The following sections describe the +constants for each driver.

+ +

The CUPS ESC/P Sample Driver (epson)

+ +

The epson driver supports Epson and Okidata +dot-matrix, Epson Stylus Color, and Epson Stylus Photo printers. +Table B-2 lists the constants for the ModelNumber directive. +ModelNumber values should be inserted by referencing +only one of these constants.

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table B-2, epson driver +constants
ConstantDescription
EPSON_9PINEpson and Okidata 9-pin + dot-matrix printers
EPSON_24PINEpson and Okidata 24-pin + dot-matrix printers
EPSON_COLOROlder Epson Stylus Color + printers that use the ESC . graphics command
EPSON_PHOTOOlder Epson Stylus Photo + printers that use the ESC . graphics command
EPSON_ICOLORNewer Epson Stylus Color + printers that use the ESC i graphics command
EPSON_IPHOTONewer Epson Stylus Photo + printers that use the ESC i graphics command
+ +

The CUPS HP-PCL Sample Driver (hp)

+ +

The hp driver supports HP LaserJet and DeskJet +printers. Table B-3 lists the constants +for the ModelNumber +directive. ModelNumber values should be inserted by +referencing only one of these constants.

+ +
+ + + + + + + + + + + + + + + + + +
Table B-3, hp driver +constants
ConstantDescription
HP_LASERJETHP LaserJet printers supporting + PCL 3, 4, or 5
HP_DESKJETHP DeskJet printers + supporting PCL 3 and using the simple color graphics + command (ESC * r # U)
HP_DESKJET2HP DeskJet printers + supporting PCL3GUI and using the configure raster graphics + command (ESC * g # W)
+ +

The CUPS Label Sample Driver (label)

+ +

The label driver supports the Dymo Labelwriter, Zebra CPCL, Zebra EPL, and Zebra ZPL, and Intellitech PCL label printers. Table B-4 +lists the constants for the ModelNumber directive. +ModelNumber values should be inserted by referencing +only one of these constants.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table B-4, label driver +constants
ConstantDescription
DYMO_3x0Format output for the + Dymo Labelwriter 300, 330, or 330 Turbo.
INTELLITECH_PCLFormat output for the Intellitech PCL printers.
ZEBRA_CPCLFormat output for the Zebra CPCL printers.
ZEBRA_EPL_LINEFormat output for the Zebra EPL line mode (EPL 1) printers.
ZEBRA_EPL_PAGEFormat output for the Zebra EPL page mode (EPL 2) printers.
ZEBRA_ZPLFormat output for the Zebra ZPL printers.
+ +

The DDK ESC/P Driver (escp)

+ +

The escp driver supports all Epson inkjet printers. +Table B-6 lists the constants for the ModelNumber directive. +ModelNumber values should be specified as the bitwise +OR of one or more of these constants.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table B-6, escp driver +constants
ConstantDescription
ESCP_MICROWEAVEUse microweave command?
ESCP_STAGGERAre color jets staggered?
ESCP_ESCKUse print mode command?
ESCP_EXT_UNITSUse extended unit commands?
ESCP_EXT_MARGINSUse extended margin command?
ESCP_USBSend USB packet mode escape
ESCP_PAGE_SIZEUse page size command
ESCP_RASTER_ESCIUse ESC i graphics command
ESCP_REMOTEUse remote mode commands
ESCP_REMOTE_ACUse auto-cutter command
ESCP_REMOTE_COUse cutter-operation command
ESCP_REMOTE_EXUse media-position command
ESCP_REMOTE_MSUse media-size command
ESCP_REMOTE_MTUse media-type command
ESCP_REMOTE_PCUse paper-check command
ESCP_REMOTE_PHUse paper-thickness command
ESCP_REMOTE_PPUse paper-path command
ESCP_REMOTE_SN0Use feed-sequence-0 command
ESCP_REMOTE_SN1Use platten-gap command
ESCP_REMOTE_SN2Use feed-sequence-2 command
ESCP_REMOTE_SN6Use eject-delay command
ESCP_REMOTE_FPUse print-position command
+ +

The DDK HP-PCL Driver (pcl)

+ +

The pcl driver supports all HP LaserJet, DeskJet, +and DesignJet printers. Table B-5 lists +the constants for the ModelNumber directive. +ModelNumber values should be specified as the bitwise +OR of one or more of these constants.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table B-5, pcl driver +constants
ConstantDescription
PCL_PAPER_SIZEUse paper size command (ESC & l # A)
PCL_INKJETUse inkjet commands
PCL_RASTER_END_COLORUse new end-raster command (ESC * r C)
PCL_RASTER_CIDUse configure-image-data command (ESC * v # W)
PCL_RASTER_CRDUse configure-raster-data command (ESC * g # W)
PCL_RASTER_SIMPLEUse simple-raster-color command (ESC * r # U)
PCL_RASTER_RGB24Use 24-bit RGB mode
PCL_PJLUse PJL commands
PCL_PJL_PAPERWIDTHUse PJL PAPERWIDTH/LENGTH commands
PCL_PJL_HPGL2Use PJL ENTER HPGL2 command
PCL_PJL_PCL3GUIUse PJL ENTER PCL3GUI command
PCL_PJL_RESOLUTIONUse PJL SET RESOLUTION command
+ +

Color Keywords

+ +

The PPD compiler defines two types of color keywords: +colorspace and color order. The following sections list the +supported keywords for each type.

+ +

Colorspace Keywords

+ +

The following colorspace keywords are recognized:

+ +
    + +
  • cielab - CIE Lab **
  • + +
  • ciexyz - CIE XYZ **
  • + +
  • cmy - Cyan, magenta, yellow
  • + +
  • cmyk - Cyan, magenta, yellow, black
  • + +
  • gmck - Gold, magenta, yellow, black **
  • + +
  • gmcs - Gold, magenta, yellow, silver **
  • + +
  • gold - Gold foil **
  • + +
  • icc1 - ICC-based, 1 color **
  • + +
  • icc2 - ICC-based, 2 colors **
  • + +
  • icc3 - ICC-based, 3 colors **
  • + +
  • icc4 - ICC-based, 4 colors **
  • + +
  • icc5 - ICC-based, 5 colors **
  • + +
  • icc6 - ICC-based, 6 colors **
  • + +
  • icc7 - ICC-based, 7 colors **
  • + +
  • icc8 - ICC-based, 8 colors **
  • + +
  • icc9 - ICC-based, 9 colors **
  • + +
  • icca - ICC-based, 10 colors **
  • + +
  • iccb - ICC-based, 11 colors **
  • + +
  • iccc - ICC-based, 12 colors **
  • + +
  • iccd - ICC-based, 13 colors **
  • + +
  • icce - ICC-based, 14 colors **
  • + +
  • iccf - ICC-based, 15 colors **
  • + +
  • k - Black
  • + +
  • kcmy - Black, cyan, magenta, yellow *
  • + +
  • kcmycm - Black, cyan, magenta, yellow, light-cyan, light-magenta *
  • + +
  • rgb - Red, green, blue
  • + +
  • rgba - Red, green, blue, alpha
  • + +
  • rgbw - Red, green, blue, luminance *
  • + +
  • silver - Silver foil **
  • + +
  • w - Luminance
  • + +
  • white - White ink (as black) **
  • + +
  • ymc - Yellow, magenta, cyan *
  • + +
  • ymck - Yellow, magenta, cyan, black * + +
      + +
    * = This colorspace is not supported on Mac OS X prior to 10.4. +
    ** = This colorspace is not supported on Mac OS X.
  • + +
+ +

Color Order Keywords

+ +

The following color order keywords are recognized:

+ +
    + +
  • chunked or chunky - Color values + are passed together on a line as RGB RGB RGB RGB
  • + +
  • banded - Color values are passed separately + on a line as RRRR GGGG BBBB *
  • + +
  • planar - Color values are passed separately + on a page as RRRR RRRR RRRR ... GGGG GGGG GGGG ... BBBB + BBBB BBBB * + +
      + +
    * = This color order + is not supported by the current Apple RIP filters and + should not be used when developing printer drivers for + Mac OS X.
  • + +
+ + + diff --git a/doc/help/ref-printers-conf.html b/doc/help/ref-printers-conf.html new file mode 100644 index 0000000000..9568fc7c83 --- /dev/null +++ b/doc/help/ref-printers-conf.html @@ -0,0 +1,720 @@ + + + + printers.conf + + + + +

printers.conf

+ +

The CUPS scheduler (cupsd) uses the +/etc/cups/printers.conf file to store the list of +available printers. This file contains only locally defined +printers, not remote printers that are created automatically via +browsing. 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.

+ +

While the printer configuration file consists of plain text +and can be modified using your favorite text editor, you should +normally use the lpadmin(8) +command, web interface, or any of the available GUIs to manage +your printers instead. If you do choose to edit this file +manually, you will need to stop the scheduler first, make your +changes, and then start the scheduler to make them active.

+ + +

Accepting

+ +

Examples

+ +
+<Printer name>
+  ...
+  Accepting yes
+</Printer>
+
+ +

Description

+ +

The Accepting directive defines the initial state +of the printer-is-accepting-jobs attribute. This state +is also set by the cupsaccept(8) and +cupsreject(8) commands:

+ +
+/usr/sbin/cupsaccept printername
+/usr/sbin/cupsreject printername
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

AllowUser

+ +

Examples

+ +
+<Printer name>
+  ...
+  AllowUser foo_user
+  AllowUser @bar_group
+</Printer>
+
+ +

Description

+ +

The AllowUser directive adds a username or group +name to the requesting-user-name-allowed attribute +which can be set by the lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -u allow:foo_user,@bar_group
+
+ +

This directive must appear inside a Printer or DefaultPrinter directive. +This directive cannot be used with DenyUser.

+ + +

DefaultPrinter

+ +

Examples

+ +
+<DefaultPrinter name>
+  ...
+</Printer>
+
+ +

Description

+ +

The DefaultPrinter directive begins a printer +definition as the default server destination. The default server +destination can be set using the lpadmin(8) +command:

+ +
+/usr/sbin/lpadmin -d printername
+
+ +

Note that the server default destination settings can be +overridden by the user's default destination settings which are +normally set using the lpoptions(1) command.

+ + +

DenyUser

+ +

Examples

+ +
+<Printer name>
+  ...
+  DenyUser foo_user
+  DenyUser @bar_group
+</Printer>
+
+ +

Description

+ +

The DenyUser directive adds a username or group +name to the requesting-user-name-denied attribute +which can be set by the lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -u deny:foo_user,@bar_group
+
+ +

This directive must appear inside a Printer or DefaultPrinter directive. +This directive cannot be used with AllowUser

+ + +

DeviceURI

+ +

Examples

+ +
+<Printer name>
+  ...
+  DeviceURI socket://foo.bar.com:9100
+</Printer>
+
+ +

Description

+ +

The DeviceURI directive defines the value of the +device-uri-attribute attribute. It is normally set +using the lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -v device-uri
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.2ErrorPolicy

+ +

Examples

+ +
+<Printer name>
+  ...
+  ErrorPolicy abort-job
+</Printer>
+
+ +

Description

+ +

The ErrorPolicy directive defines the policy that +is used when a backend is unable to send a print job to the +printer. The lpadmin(8) command sets the current +error policy:

+ +
+/usr/sbin/lpadmin -p printername -o printer-error-policy=stop-printer
+
+ +

The following values are supported:

+ +
    + +
  • abort-job - Abort the job and proceed + with the next job in the queue
  • + +
  • retry-current-job - Retry the current job + immediately
  • + +
  • retry-job - Retry the job after waiting + for N seconds; the cupsd.conf JobRetryInterval + directive controls the value of N
  • + +
  • stop-printer - Stop the printer and keep + the job for future printing; this is the default + value
  • + +
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.4Filter

+ +

Examples

+ +
+<Printer name>
+  ...
+  Filter mime/type 100 program
+</Printer>
+
+ +

Description

+ +

The Filter directive lists a single filter program as defined +in the printer's PPD file.

+ +

This directive must appear inside a +Printer or +DefaultPrinter section.

+ + +

Info

+ +

Examples

+ +
+<Printer name>
+  ...
+  Info My Printer
+</Printer>
+
+ +

Description

+ +

The Info directive defines the string for the +printer-info attribute. It is normally set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -D "My Printer"
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

JobSheets

+ +

Examples

+ +
+<Printer name>
+  ...
+  JobSheets none,standard
+</Printer>
+
+ +

Description

+ +

The JobSheets directive specifies the default +banner pages to print before and after a print job. In the above +example, only a standard banner will print after each +job. The lpadmin(8) command is normally used to set +the default banners: + +

+/usr/sbin/lpadmin -p printername -o job-sheets-default=none,standard
+
+ +

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.

+ +

The available banner pages depend on the local system +configuration; CUPS includes the following standard banner +files:

+ +
    + +
  • none - Do not produce a banner + page.
  • + +
  • classified - A banner page with a + "classified" label at the top and bottom.
  • + +
  • confidential - A banner page with a + "confidential" label at the top and bottom.
  • + +
  • secret - A banner page with a + "secret" label at the top and bottom.
  • + +
  • standard - A banner page with no label + at the top and bottom.
  • + +
  • topsecret - A banner page with a + "top secret" label at the top and bottom.
  • + +
  • unclassified - A banner page with an + "unclassified" label at the top and bottom.
  • + +
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

KLimit

+ +

Examples

+ +
+<Printer name>
+  ...
+  KLimit 1234
+</Printer>
+
+ +

Description

+ +

The KLimit directive defines the value of the +job-k-limit attribute. It is normally set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -o job-k-limit=1234
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

Location

+ +

Examples

+ +
+<Printer name>
+  ...
+  Location Building 3321
+</Printer>
+
+ +

Description

+ +

The Location directive defines the string for the +printer-location attribute. It is normally set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -L "Building 3321"
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.2OpPolicy

+ +

Examples

+ +
+<Printer name>
+  ...
+  OpPolicy default
+</Printer>
+
+ +

Description

+ +

The OpPolicy directive sets the operation policy +that is used for the printer. The lpadmin(8) command +sets the current operation policy:

+ +
+/usr/sbin/lpadmin -p printername -o printer-op-policy=default
+
+ +

The default policy is named "default". All policies correspond +to those defined using the cupsd.conf Policy +section.

+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.2Option

+ +

Examples

+ +
+<Printer name>
+  ...
+  Option name value
+  Option scaling 100
+  Option page-left 72
+</Printer>
+
+ +

Description

+ +

The Option directive specifies a default job +template attribute value. It is mapped to +name-default in the printer attributes and applied +to jobs as name.

+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

PageLimit

+ +

Examples

+ +
+<Printer name>
+  ...
+  PageLimit 1234
+</Printer>
+
+ +

Description

+ +

The PageLimit directive defines the value of the +job-page-limit attribute. It can be set using the +lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -o job-page-limit=1234
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.2PortMonitor

+ +

Examples

+ +
+<Printer name>
+  ...
+  PortMonitor bcp
+</Printer>
+
+ +

Description

+ +

The PortMonitor directive sets the filter program that +is used for every print job, typically to encode or package the print +data in a format acceptable for a particular printer interface. It is +set using the lpadmin(8) command:

+ +
+/usr/sbin/lpadmin -p printername -o port-monitor=tbcp
+
+ +

The following standard port monitors are included with CUPS:

+ +
    + +
  • bcp - Encode PostScript print data using + the Adobe Binary Control Protocol (BCP)
  • + +
  • none - Do not use a port monitor
  • + +
  • tbcp - Encode PostScript print data + using the Adobe Tagged Binary Control Protocol + (TBCP)
  • + +
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.4PreFilter

+ +

Examples

+ +
+<Printer name>
+  ...
+  PreFilter mime/type 100 program
+</Printer>
+
+ +

Description

+ +

The PreFilter directive lists a single pre-filter program as +defined in the printer's PPD file.

+ +

This directive must appear inside a +Printer or +DefaultPrinter section.

+ + +

Printer

+ +

Examples

+ +
+<Printer name>
+  ...
+</Printer>
+
+ +

Description

+ +

The Printer directive begins a printer +definition. Printers are added using the lpadmin(8) +command: + +

+/usr/sbin/lpadmin -p printername ...
+
+ + +

CUPS 1.4Product

+ +

Examples

+ +
+<Printer name>
+  ...
+  Product Acme PaperWriter
+</Printer>
+
+ +

Description

+ +

The Product directive defines the main product string from the +printer's PPD file and is used when advertising the queue via DNS-SD.

+ +

This directive must appear inside a +Printer or +DefaultPrinter section.

+ + +

QuotaPeriod

+ +

Examples

+ +
+<Printer name>
+  ...
+  QuotaPeriod 604800
+</Printer>
+
+ +

Description

+ +

The QuotaPeriod directive defines the value of +the job-quota-period attribute. Typical values are +86400 (1 day), 604800 (1 week), 2592000 (1 month), and 31536000 +(1 year). It is set using the lpadmin(8) +command:

+ +
+/usr/sbin/lpadmin -p printername -o job-quota-period=604800
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.2Shared

+ +

Examples

+ +
+<Printer name>
+  ...
+  Shared yes
+</Printer>
+
+ +

Description

+ +

The Shared directive defines the initial value of +the printer-is-shared attribute. The strings +yes and no correspond to the true and false +values, respectively. The lpadmin(8) command sets +the current state:

+ +
+/usr/sbin/lpadmin -p printername -o printer-is-shared=true
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

State

+ +

Examples

+ +
+<Printer name>
+  ...
+  State idle
+</Printer>
+
+ +

Description

+ +

The State directive defines the initial value of +the printer-state attribute. The strings +idle and stopped correspond to the IPP +enumeration values 3 and 5, respectively. The +cupsenable(8) and cupsdisable(8) +commands set the current state:

+ +
+/usr/sbin/cupsenable printername
+/usr/sbin/cupsdisable printername
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

StateMessage

+ +

Examples

+ +
+<Printer name>
+  ...
+  StateMessage Ready to print.
+</Printer>
+
+ +

Description

+ +

The StateMessage directive defines the initial +string for the printer-state-message attribute. The +following are some example messages:

+ +
+StateMessage Connected to host_name...
+StateMessage Connecting to printer_queue on port port_number...
+StateMessage Network host host_name is busy; will retry in 30 seconds...
+StateMessage Printer busy; will retry in 10 seconds...
+StateMessage Printer is busy; retrying print job...
+StateMessage Print file accepted - job ID id_number.
+StateMessage Ready to print.
+StateMessage Waiting for job to complete
+
+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + +

CUPS 1.2StateTime

+ +

Examples

+ +
+<Printer name>
+  ...
+  StateTime 1133542425
+</Printer>
+
+ +

Description

+ +

The StateTime directive defines the UNIX time +(seconds since Jan 1, 1970) for the last state change of the +queue. It is mapped to the printer-state-change-time +attribute.

+ +

This directive must appear inside a Printer or DefaultPrinter +section.

+ + + + diff --git a/doc/help/ref-snmp-conf.html b/doc/help/ref-snmp-conf.html new file mode 100644 index 0000000000..db4aacee53 --- /dev/null +++ b/doc/help/ref-snmp-conf.html @@ -0,0 +1,146 @@ + + + + snmp.conf + + + + +

snmp.conf

+ +

The /etc/cups/snmp.conf file contains several +directives that determine how the SNMP printer discovery backend +behaves. 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.

+ +

The SNMP backend uses the SNMPv1 protocol to discover network +printers, collecting information from the Host MIB along with +intelligent port probes to determine the correct device URI and +make and model for each printer. Future versions of CUPS will +likely support the new Port Monitor MIB as well.

+ +

Address

+ +

Examples

+ +
+Address @LOCAL
+Address @IF(name)
+Address 255.255.255.255
+Address 192.168.2.255
+
+ +

Description

+ +

The Address directive specifies a broadcast +address to use when discovering printers. Multiple +Address lines can be provided to scan different +subnets.

+ +

The default address is @LOCAL, which broadcasts to +all LANs.

+ + +

Community

+ +

Examples

+ +
+Community public
+Community easysw
+Community BigCorp
+
+ +

Description

+ +

The Community directive specifies a community +name to use when discovering printers. Multiple +Community lines can be provided to scan different +SNMP communities.

+ +

The default community is "public".

+ + +

DebugLevel

+ +

Examples

+ +
+DebugLevel 0
+DebugLevel 1
+DebugLevel 2
+DebugLevel 3
+
+ +

Description

+ +

The DebugLevel directive specifies the debugging +level to use when searching for network printers. Level 0 +produces no debugging information. Level 1 produces basic +debugging information. Level 2 adds printing of the SNMP +messages. Level 3 adds a hex dump of the network data.

+ +

The default setting is 0.

+ +

DeviceURI

+ +

Examples

+ +
+DeviceURI "HP.*JetDirect.*" socket://%s:9100 socket://%s:9101 socket://%s:9102
+DeviceURI "HP.*" socket://%s
+DeviceURI "Acme.*Laser.*" lpd://%s/print
+DeviceURI "Xerox.*"
+
+ +

Description

+ +

The DeviceURI directive specifies a regular expression +(enclosed in double quotes) that is matched against the SNMP device +description OID returned by a printer. If the description matches the +regular expression, each device URI that follows the regular expression +is listed by the backend, with any occurrences of %s +replaced by the device's hostname or IP address. If no URIs are listed, +the device is ignored.

+ +

The DeviceURI directives are processed serially in +the order specified in the snmp.conf file until a match +is found.

+ + +

HostNameLookups

+ +

Examples

+ +
+HostNameLookups on
+HostNameLookups off
+
+ +

Description

+ +

The HostNameLookups directive specifies whether printer +addresses are converted to hostnames or left as numeric IP addresses.

+ +

The default setting is off.

+ +

MaxRunTime

+ +

Examples

+ +
+MaxRunTime 10
+MaxRunTime 300
+
+ +

Description

+ +

The MaxRunTime directive specifies the maximum +number of seconds that the SNMP backend will spend looking for +printer devices on the network.

+ +

The default setting is 10.

+ + + diff --git a/doc/help/ref-subscriptions-conf.html b/doc/help/ref-subscriptions-conf.html new file mode 100644 index 0000000000..d4f4defc33 --- /dev/null +++ b/doc/help/ref-subscriptions-conf.html @@ -0,0 +1,354 @@ + + + + subscriptions.conf + + + + +

subscriptions.conf

+ +

The CUPS scheduler (cupsd) uses the +/etc/cups/subscriptions.conf file to store the list +of active subscriptions. 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. + +

While the subscriptions configuration file consists of plain +text and can be modified using your favorite text editor, you +should normally use the command-line programs (lp(1) and lpr(1)) or specific applications via IPP +requests to manage your subscriptions.

+ +

Events

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  Events job-completed
+</Subscription>
+
+ +

Description

+ +

The Events directive lists the events, separated +by spaces, that the subscriber is interested in. Table 1 lists +the supported event names.

+ +

The Events directive must appear inside a Subscription section.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Event Names
NameDescription
allAll events
job-completedSend notification when the job is completed
job-config-changedSend notification when the job is changed
job-createdSend notification when a job is created
job-progressSend notification for job progress
job-state-changedSend notification when the job-state changes
job-stoppedSend notification when the job is stopped
printer-addedSend notification when a printer is added
printer-changedSend notification when a printer is changed
printer-config-changedSend notification when a printer's configuration is changed
printer-deletedSend notification when a printer is deleted
printer-modifiedSend notification when a printer is modified
printer-state-changedSend notification when the printer-state changes
printer-stoppedSend notification when a printer is stopped
server-auditSend notification when a bad request, security error, or + authentication error occurs
server-restartedSend notification when the server is restarted
server-startedSend notification when the server is initially started
server-stoppedSend notification when the server is shutdown
+ + +

ExpirationTime

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  ExpirationTime 1012563145
+</Subscription>
+
+ +

Description

+ +

The ExpirationTime directive specifies the +expiration time of the subscription as a UNIX time value. It is 0 +for subscriptions with no predefined expiration time.

+ +

The ExpirationTime directive must appear inside a +Subscription +section.

+ + +

Interval

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  Interval 30
+</Subscription>
+
+ +

Description

+ +

The Interval directive specifies the preferred +time interval for event notifications in seconds.

+ +

The Interval directive must appear inside a Subscription section.

+ + +

JobId

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  JobId 123
+</Subscription>
+
+ +

Description

+ +

The JobId directive specifies the +job-id for job subscriptions.

+ +

The JobId directive must appear inside a Subscription section.

+ + +

LeaseDuration

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  LeaseDuration 
+</Subscription>
+
+ +

Description

+ +

The LeaseDuration directive specifies the number +of seconds that the subscription is valid. A value of 0 means +that the subscription will last forever or the life of the print +job the subscription is attached to.

+ +

The LeaseDuration directive must appear inside a Subscription section.

+ + +

NextEventId

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  NextEventId 999
+</Subscription>
+
+ +

Description

+ +

The NextEventId directive specifies the +notify-sequence-number value for the next +notification event. It starts at 1 and increases for every event +that is delivered for the subscription.

+ +

The NextEventId directive must appear inside a Subscription section.

+ + +

NextSubscriptionId

+ +

Examples

+ +
+NextSubscriptionId 999
+
+ +

Description

+ +

The NextSubscriptionId directive specifies the +next subscription ID to use. It defaults to 1 more than the +highest subscription number seen.

+ + +

Owner

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  Owner username
+</Subscription>
+
+ +

Description

+ +

The Owner directive specifies the user that owns +this subscription.

+ +

The Owner directive must appear inside a Subscription section.

+ + +

PrinterName

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  PrinterName name
+</Subscription>
+
+ +

Description

+ +

The PrinterName directive specifies the name of +the printer or class that is associated with this +subscription.

+ +

The PrinterName directive must appear inside a Subscription section.

+ + +

Recipient

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  Recipient mailto:foo@domain.com
+</Subscription>
+
+ +

Description

+ +

The Recipient directive specifies the +notify-recipient-uri value for push-type +notifications. The URI scheme name determines which notifier +program is used to send the event(s).

+ +

The Recipient directive must appear inside a Subscription section.

+ + +

Subscription

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+</Subscription>
+
+ +

Description

+ +

The Subscription section defines a single +subscription in the system. Each subscription is assigned a +unique (to the server) number starting at 1.

+ + +

UserData

+ +

Examples

+ +
+<Subscription NNN>
+  ...
+  UserData mailto:bar<40>domain.com
+</Subscription>
+
+ +

Description

+ +

The UserData directive specifies the +notify-user-data value, which is normally the "from" +address used in mailto notifications. Binary values +are introduced by encoding the bytes as hexadecimal values inside +angle brackets, e.g. "<1234>".

+ +

The UserData directive must appear inside a Subscription section.

+ + + diff --git a/doc/help/security.html b/doc/help/security.html new file mode 100644 index 0000000000..c86151d176 --- /dev/null +++ b/doc/help/security.html @@ -0,0 +1,172 @@ + + + + Server Security + + + + +

Server Security

+ +

In the default "standalone" configuration, there are few +potential security risks - the CUPS server does not accept remote +connections, and only accepts shared printer information from the +local subnet. When you share printers and/or enable remote +administration, you expose your system to potential unauthorized +access. This help page provides an analysis of possible CUPS +security concerns and describes how to better secure your +server.

+ +

Authentication Issues

+ +

When you enable remote administration, the server will use +Basic authentication for administration tasks. The current CUPS +server supports Basic, Digest, Kerberos, and local certificate +authentication:

+ +
    + +
  1. Basic authentication essentially places the clear + text of the username and password on the network. + +

    Since CUPS uses the system username and password + account information, the authentication information could + be used to gain access to possibly privileged accounts on + the server.

    + +

    Recommendation: Enable encryption to hide the + username and password information - this is the default on + MacOS X and systems with GNU TLS or OpenSSL installed.

  2. + +
  3. 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. + +

    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.

    + +

    Recommendation: Enable encryption to hide the + username and password information.

  4. + +
  5. 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 /var/run/cups/certs. + They have restricted read permissions: root + + system-group(s) for the root certificate, and lp + lp + 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 + loopback interface (127.0.0.1 or ::1) or domain + socket.

    + +

    Recommendation: Ensure that unauthorized users + are not added to the system group(s).

  6. + +
+ +

Denial of Service Attacks

+ +

When printer sharing or remote administration is enabled, the +CUPS server, like all Internet services, is vulnerable to a +variety of denial of service attacks:

+ +
    + +
  1. Establishing multiple connections to the server until + the server will accept no more. + +

    This cannot be protected against by any known + software. The MaxClientsPerHost directive + can be used to configure CUPS to limit the number of + connections allowed from a single host, however that does + not prevent a distributed attack.

    + +

    Recommendation: Limit access to trusted systems + and networks.

  2. + +
  3. Repeatedly opening and closing connections to the + server as fast as possible. + +

    There is no easy way of protecting against this in the + CUPS software. If the attack is coming from outside the + local network, it may 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.

    + +

    Recommendation: None.

  4. + +
  5. Flooding the network with broadcast packets on port + 631. + +

    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.

    + +

    Recommendation: Block browse packets from + foreign or untrusted networks using a router or + firewall.

  6. + +
  7. Sending partial IPP requests; specifically, sending + part of an attribute value and then stopping + transmission. + +

    The current code will wait up to 1 second before + timing out the partial value and closing the connection. + This will slow the server responses to valid requests and + may lead to dropped browsing packets, but will otherwise + not affect the operation of the server.

    + +

    Recommendation: Block IPP packets from foreign + or untrusted networks using a router or + firewall.

  8. + +
  9. Sending large/long print jobs to printers, preventing + other users from printing. + +

    There are limited facilities for protecting against + large print jobs (the MaxRequestSize + attribute), however this will not protect printers from + malicious users and print files that generate hundreds or + thousands of pages.

    + +

    Recommendation: Restrict printer access to + known hosts or networks, and add user-level access + controls as needed for expensive printers.

  10. + +
+ +

Encryption Issues

+ +

CUPS supports 128-bit SSL 3.0 and TLS 1.0 encryption of +network connections via the OpenSSL, GNU TLS, and CDSA encryption +libraries. In additional to the potential security issues posed +by the SSL and TLS protocols, CUPS currently has the following +additional issue:

+ +
    + +
  1. Certification validation/revocation; currently CUPS + does not validate or revoke server or client certificates + when establishing a secure connection. This can + potentially lead to "man in the middle" and + impersonation/spoofing attacks over unsecured networks. + Future versions of CUPS will support both validation and + revocation of server certificates. + +

    Recommendation: Do not depend on encryption for + security when connecting to servers over the Internet or + untrusted WAN links.

  2. + +
+ + + diff --git a/doc/help/sharing.html b/doc/help/sharing.html new file mode 100644 index 0000000000..00ccb6fe87 --- /dev/null +++ b/doc/help/sharing.html @@ -0,0 +1,184 @@ + + + + Printer Sharing + + + + +

Printer Sharing

+ +

This document discusses several ways to configure printer sharing.

+ +

The Basics

+ +

A "server" is any machine that communicates directly to a printer. A "client" +is any machine that sends print jobs to a server for final printing. Clients can +also be servers if they communicate directly with any printers of their own.

+ +

By default, CUPS uses the Internet Printing Protocol (IPP) to send jobs from +a client to a server. When printing to legacy print servers you may also use the +Line Printer Daemon (LPD) when printing to older UNIX-based servers or Server +Message Block (SMB) when printing to Windows® servers.

+ +

Clients can automatically discover and access shared printers via CUPS +browsing, IPP, Service Location Protocol (SLP), and Lightweight Directory Access +Protocol (LDAP). DNS Service Discovery (DNS-SD a.k.a. Bonjour®) +and SMB browsing can also be used to manually discover and access shared +printers.

+ + +

Configuring the Server

+ +

You must enable printer sharing on the server before clients can print +through it. The simplest way to do this is to use the +cupsctl(8) command on the server:

+ +
+cupsctl --share-printers
+
+ +

By default, the above command will allow printing from other clients on the +same subnet as your server. To allow printing from any subnet, use the following +command instead:

+ +
+cupsctl --share-printers --remote-any
+
+ +

Next, you need to choose which protocols to use for printer sharing. The +default is CUPS browsing and DNS-SD on Mac OS X and CUPS browsing alone on +other platforms. To set the sharing protocols, run the cupsctl command +to set the +BrowseLocalProtocols +value. For example, run the following command to allow shared printing via +CUPS, DNS-SD, LPD, and SMB:

+ +
+cupsctl 'BrowseLocalProtocols="cups dnssd lpd smb"'
+
+ + +

Automatic Configuration using CUPS Browsing

+ +

CUPS browsing works by periodically broadcasting information about printers +that are being shared to client systems on the same subnet. Each client +maintains its own list of shared printers, and when more than one server shares +the same printer (or the same kind of printer) the client uses all of the +servers and printers to provide high-availability and failsafe printing.

+ +

To configure printers on the same subnet, do nothing. 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.

+ +
Note: + +

Due to user interface changes in Mac OS X 10.5, CUPS shared printers will not +automatically appear in the print dialog. Instead, you must first run the +following command to enable CUPS browsing on your system:

+ +
+cupsctl BrowseRemoteProtocols=cups
+
+ +

Then choose each of the CUPS shared printers you want to see in the print +dialog by adding them, either from the Add Printer... item in the +print dialog or from the Print & Fax preference pane in the +System Preferences window.

+ +
+ +

Seeing Printers on Other Subnets

+ +

You can automatically access printers on other subnets by adding +BrowsePoll lines +to the cupsd.conf file on your local system. For a single +server you can use the cupsctl command:

+ +
+cupsctl BrowsePoll=server:port
+
+ +

For multiple servers, use the CUPS web interface (http://localhost:631/admin) +to edit the configuration file instead. Enter one BrowsePoll line +per server at the bottom of the file, as follows:

+ +
+BrowsePoll server1:port
+BrowsePoll server2:port
+BrowsePoll server3:port
+
+ +

If you have more than one client on your subnet that wants to see the +printers on those servers, add a +BrowseRely line +to the cupsd.conf file on your local system using the cupsctl +command:

+ +
+cupsctl 'BrowseRelay="127.0.0.1 @LOCAL"'
+
+ +

or CUPS web interface (again, at the bottom of the file):

+ +
+BrowseRelay 127.0.0.1 @LOCAL
+
+ + +

Automatic Configuration using IPP

+ +

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

+ +

The default server is normally the local system ("localhost"). To override +the default server create a file named /etc/cups/client.conf with a +line as follows:

+ +
+ServerName server
+
+ +

The server name can be the hostname or IP address of the default +server. If the server is not using the default IPP port (631), you can add the +port number at the end like this:

+ +
+ServerName server:port
+
+ +

The default server can also be customized on a per-user basis. To set a +user-specific server create a file named ~/.cups/client.conf instead. +The user client.conf file takes precedence over the system one.

+ +

Finally, you can set the CUPS_SERVER environment variable to +override the default server for a single process, for example:

+ +
+CUPS_SERVER=server:port firefox http://www.cups.org
+
+ +

will run the Firefox web browser pointed to the specified server and +port. The environment variable overrides both the user and system +client.conf files, if any.

+ + +

Manual Configuration of Print Queues

+ +

The most tedious method of configuring client machines is to configure +each remote queue by hand using the lpadmin(8) +command:

+ +
+lpadmin -p printer -E -v ipp://server/printers/printer
+
+ +

The printer name is the name of the printer on the server machine. +The server name is the hostname or IP address of the server machine. +Repeat the lpadmin command for each remote printer you wish to use.

+ + + + diff --git a/doc/help/spec-banner.html b/doc/help/spec-banner.html new file mode 100644 index 0000000000..7393a21e9c --- /dev/null +++ b/doc/help/spec-banner.html @@ -0,0 +1,156 @@ + + + + + CUPS Banner File Format + + + + + + +

CUPS Banner File Format

+ +

Introduction

+ +

This specification describes the CUPS banner file format +(application/vnd.cups-banner) which is used to generate print job cover pages +and the CUPS test page. The format itself consists of a header followed by +lines of UTF-8 text containing comments or keywords and values:

+ +
+#CUPS-BANNER
+
+# What to show on the cover page
+Show job-id job-name job-originating-user-name time-at-creation
+
+# The header and footer text
+Header Cover Page
+Footer Cover Page
+
+# Arbitrary "notice" text
+Notice All work and no play makes Johnny a dull boy.
+Notice All work and no play makes Johnny a dull boy.
+Notice All work and no play makes Johnny a dull boy.
+Notice All work and no play makes Johnny a dull boy.
+
+# Images to place below the rest
+Image /usr/share/doc/cups/images/cups-icon.png
+Image /usr/share/doc/cups/images/smiley.jpg
+
+ + +

Standard Keywords

+ +

Footer

+ +

+Footer text for footer +

+ +

The Footer key defines the text that is centered at the bottom +of the page. Only one Footer key can be specified.

+ + +

Header

+ +

+Header text for Header +

+ +

The Header key defines the text that is centered at the top +of the page. Only one Header key can be specified.

+ + +

Image

+ +

+Image /path/to/image/filename
+Image relative/path/in/DocumentRoot/filename +

+ +

The Image key defines images that are centered above the footer +text. Multiple images are centered as a group from left to right. Images are +scaled as needed to fit on the page with a nominal size of 1"/25cm.

+ + +

Notice

+ +

+Notice Text to display below the job information.
+Notice More text to display below the job information. +

+ +

The Notice key defines lines of text that are centered below +the job information.

+ + +

Show

+ +

+Show value value ... value +

+ +

The Show key lists the job information that is shown. The +following values are supported:

+ +
    + +
  • imageable-area: The imageable area of the current + page size
  • + +
  • job-billing: Billing information for the job
  • + +
  • job-id: The job ID
  • + +
  • job-name: The title of the job
  • + +
  • job-originating-host-name: The computer that printed + the job
  • + +
  • job-originating-user-name: The user that printed the + job
  • + +
  • job-uuid: The job UUID
  • + +
  • options: The options that were provided with the + job
  • + +
  • paper-name: The name of the paper size used
  • + +
  • paper-size: The dimensions of the paper size used.
  • + +
  • printer-driver-name: The printer driver used
  • + +
  • printer-driver-version: The driver version
  • + +
  • printer-info: The printer description
  • + +
  • printer-location: The location of the printer
  • + +
  • printer-make-and-model: The make and model strings + reported by the printer driver
  • + +
  • printer-name: The printer used
  • + +
  • time-at-creation: When the job was submitted
  • + +
  • time-at-processing: The current date and time
  • + +
+ + + + diff --git a/doc/help/spec-browsing.html b/doc/help/spec-browsing.html new file mode 100644 index 0000000000..e2ab44c799 --- /dev/null +++ b/doc/help/spec-browsing.html @@ -0,0 +1,118 @@ + + + + + CUPS Browse Protocol + + + + + + +
Note: + +

The CUPS Browse Protocol is deprecated and will no longer be used in a future release of CUPS.

+ +
+ +

CUPS Browse Protocol

+ +

Introduction

+ +

This specification describes the CUPS browsing protocol which is used for +printer sharing. The protocol is a UDP/IP-based broadcast service that +operates on IP service port 631 by default. Each broadcast packet describes +a single printer or class being shared.

+ +

For simple networks with a single subnet, a CUPS system sharing a printer +(the server) will periodically broadcast that printer's availability +and status information to the subnet. Every other CUPS system on the subnet +(the clients) will receive the broadcast and make that printer +available to local users. If a client stops receiving broadcasts from the +server, or if the server sends a special "deleted" broadcast message, the +client will remove its copy of the printer.

+ +

For larger networks with multiple subnets, a relay configuration can be used +where one or more client systems poll the server and then broadcast the +availability and status information for the server's shared printers to the +clients' local subnets.

+ +

A key feature of CUPS printer sharing is support for implicit +classes, which are automatically-created classes for printers that are +shared by multiple servers. These implicit classes provide automatic load +balancing and fail-safe printing functionality transparently to the user.

+ + +

Security Considerations

+ +

Like most discovery protocols, CUPS browse packets are not encrypted or +signed, so it is possible for malicious systems on a network to advertise +or remove printers on that network to cause denial of service or information +disclosure. In order to combat this, CUPS logs incoming browse packets and +provides access controls to limit browse packet reception to known hosts.

+ + +

Browse Packet Format

+ +

Each broadcast packet is an ASCII text string of up to 1450 bytes ending +with a line feed (0x0a). The general format is:

+ +

+printer-type printer-state printer-uri "printer-location" "printer-info" +"printer-make-and-model" name=value name2=value2 ... +

+ +

Each of the fields contains the value of the corresponding IPP attribute. +The trailing "name=value" information is used to convey default job template +attribute values (job-sheets-default, media-default, etc.), authentication +requirements (auth-info-required), and additional IPP URI options that are +requested by the server (ipp-options).

+ +

ABNF Definition

+ +

The following ABNF definition [RFC4234, RFC3986] defines the format of each +browse packet:

+ +
+PACKET         = TYPE WSP STATE WSP URI WSP LOCATION WSP INFO WSP
+                 MAKE-AND-MODEL WSP *[ WSP ATTR-NAME "=" ATTR-VALUE ] LF
+
+TYPE           = 1*HEXDIG
+
+STATE          = "3" / "4" / "5"
+
+URI            = "ipp://" ( 1*NAMECHAR / IP-literal / IPv4address )
+                 [ ":" 1*DIGIT ] ( "/printers/" / "/classes/" ) 1*NAMECHAR
+NAMECHAR       = %x21.22.24.26-2E.30-7E / %x25 HEXDIG HEXDIG
+IP-literal     = See RFC 3986
+IPv4address    = See RFC 3986
+
+LOCATION       = QUOTED-STRING
+INFO           = QUOTED-STRING
+MAKE-AND-MODEL = QUOTED-STRING
+
+ATTR-NAME      = 1*( ALPHA / DIGIT / "-" / "." )
+ATTR-VALUE     = QUOTED-STRING / 1*UNQUOTE-CHAR
+
+QUOTED-STRING  = DQUOTE *QUOTED-CHAR DQUOTE
+QUOTED-CHAR    = %x20.21.23-5B.5D-7E / UTF8-CHAR / %x5C %x5C / %x5C %x22
+UNQUOTE-CHAR   = %x21.23-26.28-5B.5D-7E / UTF8-CHAR
+UTF8-CHAR      = %xC0.DF %x80.BF / %xE0.EF %x80.BF %x80.BF /
+                 %xF0.F7 %x80.BF %x80.BF %x80.BF
+
+ + + diff --git a/doc/help/spec-cmp.html b/doc/help/spec-cmp.html new file mode 100644 index 0000000000..47f56d31d3 --- /dev/null +++ b/doc/help/spec-cmp.html @@ -0,0 +1,1218 @@ + + + + + CUPS Developer Guide + + + + +

CUPS Developer Guide

+ +

This developer guide documents the guidelines and processes we use when developing and maintaining CUPS and related software. Our goal is to provide reliable and efficient software and documentation that addresses the needs of our users.

+ +

Communication

+ +

How to Contact the Developers

+ +

The CUPS +Forums are the primary means of asking questions and +informally discussing issues and feature requests with the CUPS +developers. Table 1 shows the available forums and their +focus:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: CUPS Forums
ForumFocus/Purpose
cups.bugsDiscussion of bugs and issues in the CUPS + software
cups.commitReport of all commits to the Subversion repository + (read-only)
cups.ddkUsage and development questions for the CUPS Driver + Development Kit
cups.developmentDevelopment questions and discussion of new features + in the CUPS software
cups.generalUsage questions for the CUPS software
+ +

How to Submit a Bug Report or Feature Request

+ +

The CUPS "Bugs & +Features" page provides access to the CUPS software +trouble report database and is the formal way to submit a +bug report or feature request to the CUPS developers. Please +note, however, that we do not provide answers to usage +questions or resolve problems in third-party software on this +page - use the CUPS Forums for that instead.

+ +

Unlike discussions that occur on the CUPS Forums, formal bug +reports and feature requests must be acted on by the CUPS +developers. This does not mean that every bug report is resolved +or every feature request is implemented, but we do respond and +keep track of them all for posterity.

+ +
Please use the search feature of the Bugs & +Features page before submitting a new bug report or feature +request. If you see an existing report that matches your issue, +please post a message to that report ("I have this issue as +well", "I would also like to see", etc.) rather than submitting a +new report. This helps speed the resolution of your issue by +reducing the CUPS developers' work load.
+ +

How to Prepare a Patch

+ +

When submitting a bug report or feature request, you can +include patch files that resolve the bug or implement the feature +to speed the inclusion of that bug fix or feature in a new CUPS +release. For changes to existing files, we prefer a unified diff +against the current Subversion trunk branch, which can +be generated easily using the following Subversion command:

+ +
+svn diff >filename.patch
+
+ +

If you produce a patch using a released source archive, use +one of the following commands instead:

+ +
+diff -u oldfilename filename >filename.patch
+
+diff -urN olddirectory directory >filename.patch
+
+ +

New files and files with significant changes can be submitted +in their entirety, however that may delay the adoption of your +changes.

+ +
Patches and files must conform to the standards outlined in the +"Coding Guidelines" and "Makefile +Guidelines" sections in this document. In addition, since Apple Inc. +provides CUPS under multiple licenses, we require that you assign the copyright +for your changes and files to us for inclusion in CUPS.
+ + +

Software Development Practices

+ +

Version Numbering

+ +

CUPS uses a three-part version number separated by periods to +represent the major, minor, and patch release numbers. Major +release numbers indicate large design changes or +backwards-incompatible changes to the CUPS API or CUPS Imaging +API. Minor release numbers indicate new features and other +smaller changes which are backwards-compatible with previous CUPS +releases. Patch numbers indicate bug fixes to the previous +release.

+ +
When we talk about compatibility, we are talking +about binary compatibility for public APIs and output format +compatibility for program interfaces. Changes to configuration +file formats or the default behavior of programs are not +generally considered incompatible as the upgrade process can +normally address such changes gracefully.
+ +

Production releases use the plain version numbers:

+ +
+MAJOR.MINOR.PATCH
+1.0.0
+1.0.1
+1.0.2
+...
+1.1.0
+...
+1.1.23
+1.2.0
+1.2.1
+...
+1.3.0
+...
+2.0.0
+
+ +

The first production release in a MAJOR.MINOR series (MAJOR.MINOR.0) is +called a feature release. Feature releases are the only releases that may +contain new features. Subsequent production releases in a MAJOR.MINOR series may +only contain bug fixes.

+ +
We did not hold to this limitation in the CUPS 1.1 series for a +variety of reasons. Starting with CUPS 1.2, the "no new features in a patch +release" policy has been strictly enforced. The policy has also resulted in +fewer new features (and interactions!) to validate/test in the subsequence +feature releases.
+ +

Beta-test releases are identified by appending the letter B to the major and +minor version numbers followed by the beta release number:

+ +
+MAJOR.MINORbNUMBER
+1.2b1
+
+ +

Release candidates are identified by appending the letters RC to the major +and minor version numbers followed by the release candidate number:

+ +
+MAJOR.MINORrcNUMBER
+1.2rc1
+
+ +

Developer snapshots are identified by appending the letters SVN-R to the +major and minor version numbers followed by the revision number:

+ +
+MAJOR.MINORsvn-rREV
+1.2svn-r1234
+
+ +

Beta-test releases, release candidates, and developer snapshots are only +created for new minor releases. Once a production release has been made +(MAJOR.MINOR.0), subsequent patch releases are issues without preliminary beta +or release testing.

+ +

Version Control (Subversion)

+ +

The CUPS source files are managed by the Subversion ("SVN") +software, available at:

+ +
+subversion.tigris.org
+
+ +

Source files are "checked in" with each change so that +modifications can be tracked, and each checkin must reference any +applicable STRs. The following format must be used for +commit log messages:

+ +
+Summary of the change on one line followed by bug number (STR #NNNN)
+
+Detailed list of changes.
+
+ +

Primary development occurs on the trunk branch, +with changes merged back to release branches as needed. Table 2 +shows the URLs developers use for the various CUPS sub-projects +and branches:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: CUPS Subversion URLs
URLPurpose
https://svn.easysw.com/public/cups/trunk/Primary CUPS development branch
https://svn.easysw.com/public/cups/branches/CUPS maintenance branches (merge-only)
https://svn.easysw.com/public/cups/tags/CUPS release tags (read-only)
https://svn.easysw.com/public/windows/trunk/Primary CUPS Windows Driver development branch
https://svn.easysw.com/public/windows/branches/CUPS Windows Driver maintenance branches (merge-only)
https://svn.easysw.com/public/windows/tags/CUPS Windows Driver release tags (read-only)
+ +

The branch for a MAJOR.MINOR release are created when the +first production release (MAJOR.MINOR.0) is made using the name +"branch-MAJOR.MINOR". Release tags are created for every beta, +candidate, and production release using the name +"release-MAJOR.MINOR.PATCHbNUMBER", +"release-MAJOR.MINOR.PATCHrcNUMBER", or +"release-MAJOR.MINOR.PATCH", respectively. No release tags are +created for developer snapshots.

+ + +

Files and Directories

+ +

File and directory names may not exceed 16 characters in +length to ensure compatibility with older UNIX filesystems. In +addition, to avoid problems with case-insensitive filesystems, +you may not use names which differ only by case, for example +"ReadMe" and "README" are not allowed in the same directory.

+ +

Source files must be documented and formatted as described in +"Coding Requirements". Make files must +follow the guidelines in "Makefile +Guidelines".

+ + +

Build System

+ +

The CUPS build system uses GNU autoconf to +tailor the library to the local operating system. Project files +for major IDEs are also provided for Microsoft +Windows®. To improve portability, makefiles must +not make use of the unique features offered by GNU make. See the Makefile Guidelines section for a +description of the allowed make features and makefile +guidelines.

+ +

Additional GNU build programs such as GNU automake and +GNU libtool +must not be used. GNU automake produces non-portable makefiles +which depend on GNU-specific extensions, and GNU libtool is not +portable or reliable enough for CUPS.

+ + +

Packaging

+ +

Source packages are created using the +tools/makesrcdist script in the Subversion repository. +The script optionally uses a version number argument:

+ +
+tools/makesrcdist
+tools/makesrcdist version
+
+ +

When run with no arguments, the script creates a snapshot of +the current working copy and names it using the highest revision +number in the WC, for example +"/tmp/cups-1.3svn-r1234-source.tar.bz2" and +"/tmp/cups-1.3svn-r1234-source.tar.gz". When run with two +arguments, the script creates a release tag in the repository and +exports that tag, creating the files +"/tmp/cups-version-source.tar.bz2" and +"/tmp/cups-version-source.tar.gz".

+ +

Binary packages are not generally distributed by the CUPS +team, however the packaging/cups.spec and +packaging/cups.list files may be used to create binary +packages on Linux, Mac OS X, and UNIX. The +packaging/cups.spec file produces a binary package +using the rpmbuild(8) software:

+ +
+rpmbuild -ta cups-version-source.tar.gz
+
+ +

The cups.list file is generated by the +configure script and produces binary packages for many +platforms using the EPM software. Table 3 shows the targets that +are available for each type of binary package:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3: Binary Package Targets
TargetType of Package
aixAIX installp
bsd*BSD pkg_install
debDebian dpkg
depotHP-UX swinstall
epmPortable tarball with install script
instIRIX inst/tardist
osxMac OS X Install
pkgSolaris pkgadd
rpmRPM binary
setldTru64 UNIX setld
slackwareSlackware install
swinstallHP-UX swinstall
tardistIRIX inst/tardist
+ +

Finally, the tools/testrpm and +tools/testosx scripts can be used to create binary +packages from the current working copy for testing on Linux and +Mac OS X, respectively:

+ +
+tools/testrpm
+sudo rpm -U /usr/src/redhat/RPMS/i386/cups*.rpm
+
+sudo tools/testosx
+open cups.pkg
+
+ + +

Testing

+ +

Software testing is conducted according to the CUPS Software Test Plan. This testing is +automated via the top-level makefile test target:

+ +
+make test
+
+ +

The test environment allows for both short-term automated +testing and long-term testing and development without the +automated test script.

+ + +

Trouble Report Processing

+ +

A Software Trouble Report ("STR") must be submitted every time +a user or vendor experiences a problem with the CUPS software. +Trouble reports are maintained on the Bugs & +Features page with one of the following states:

+ +
    + +
  1. STR is closed with complete resolution
  2. + +
  3. STR is closed without resolution
  4. + +
  5. STR is active, waiting on information from submitter
  6. + +
  7. STR is pending with additional information from submitter
  8. + +
  9. STR is newly submitted
  10. + +
+ +

Trouble reports are processed using the following steps.

+ +
    + +
  1. Classification + +

    When a trouble report is received it must be classified at one +of the following priority levels:

    + +
      + +
    1. Request for enhancement, e.g. asking for a + feature + +
    2. Low, e.g. a documentation error or undocumented + side-effect + +
    3. Moderate, e.g. unable to print a file or unable to + compile the software + +
    4. High, e.g. unable to print to a printer or key + functionality not working + +
    5. Critical, e.g. unable to print at all + +
    + +

    Level 4 and 5 trouble reports must be resolved in the next +software release. Level 2 and 3 trouble reports are scheduled for +resolution in a specific release at the discretion of the release +coordinator. Level 1 trouble reports are scheduled for resolution +in a future feature release.

    + +

    The scope of the problem is also determined as:

    + +
      + +
    1. Specific to a machine or printer + +
    2. Specific to an operating system + +
    3. Applies to all machines, printers, and operating systems + +
    + +
  2. Identification + +

    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.

    + +

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

    + +
  3. Correction + +

    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.

    + +
  4. Notification + +

    The user or vendor is notified when the fix is available or if +the problem was caused by user error.

    + +
+ + +

Release Management

+ +

When testing has been completed successfully, a new source +package is created using the tools/makesrcdist script. +Three types of releases, beta, candidate, and production, are +created and released to the public using the basic schedule in +Table 4. At least one beta and one release candidate must be +created prior to a production release, and there must be at least +two weeks between the last beta and first candidate and last +candidate and first production release.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table: CUPS Basic Release Schedule
WeekVersionDescription
T-6 weeks1.2b1First beta release
T-5 weeks1.2b2Second beta release
T-3 weeks1.2rc1First release candidate
T-2 weeks1.2rc2Second release candidate
T-0 weeks1.2.0Production (feature) release
+ + +

Coding Guidelines

+ +

These coding guidelines provide detailed information on source +file formatting and documentation content and must be applied to +all C and C++ source files provided with CUPS. Source code for +other languages should conform to these guidelines as allowed by +the language.

+ +

Source Files

+ +

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

+ +

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 Subversion "$Id$" tag:

+ +
+/*
+ * "$Id$"
+ *
+ *   Description of file contents.
+ *
+ *   Copyright 2010 by Apple Inc.
+ *
+ *   These coded instructions, statements, and computer programs are the
+ *   property of Apple Inc. 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
+ *   file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * Contents:
+ *
+ *   function1() - Description 1.
+ *   function2() - Description 2.
+ *   function3() - Description 3.
+ */
+
+ +

For source files that are subject to the Apple OS-Developed +Software exception, the following additional comment should +appear after the contact information:

+ +
+ *   This file is subject to the Apple OS-Developed Software exception.
+
+ +

The bottom of each source file shall contain a trailer giving +the name of the file using the Subversion "$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:

+ +
+/*
+ * End of "$Id$".
+ */
+
+ +

Functions

+ +

Functions with a global scope shall have a lowercase prefix +followed by capitalized words ("cupsDoThis", "cupsDoThat", +"cupsDoSomethingElse", etc.) Private global functions shall begin +with a leading underscore ("_cupsDoThis", "_cupsDoThat", +etc.)

+ +

Functions with a local scope shall be declared "static" and be +lowercase with underscores between words ("do_this", "do_that", +"do_something_else", etc.)

+ +

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:

+ +
+/*
+ * 'do_this()' - Compute y = this(x).
+ *
+ * Notes: none.
+ */
+
+static float                            /* O - Inverse power value, 0.0 <= y <= 1.1 */
+do_this(float x)                        /* I - Power value (0.0 <= x <= 1.1) */
+{
+  ...
+  return (y);
+}
+
+ +

Return/output values are indicated using an "O" prefix, input +values are indicated using the "I" prefix, and values that are +both input and output use the "IO" prefix for the corresponding +in-line comment.

+ +

The Mini-XML documentation generator also understands the following +special text in the function description comment:

+ +
    + +
  • @deprecated@ - Marks the function as + deprecated (not recommended for new development and + scheduled for removal)
  • + +
  • @since CUPS version@ - Marks the + function as new in the specified version of CUPS.
  • + +
  • @private@ - Marks the function as private.
  • + +
+ +

Variables

+ +

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.

+ +

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

+ +

Each variable shall be declared on a separate line and shall +be immediately followed by a comment block describing the +variable:

+ +
+int this_variable;   /* The current state of this */
+int that_variable;   /* The current state of that */
+
+ +

Types

+ +

All type names shall be lowercase with underscores between +words and "_t" appended to the end of the name +("cups_this_type_t", "cups_that_type_t", etc.) Type names must +start with a prefix, typically "cups" or the name of the program, +to avoid conflicts with system types. Private type names must +start with an underscore ("_cups_this_t", "_cups_that_t", +etc.)

+ +

Each type shall have a comment block immediately after the +typedef:

+ +
+typedef int cups_this_type_t;           /* This type is for CUPS foobar options. */
+
+ +

Structures

+ +

All structure names shall be lowercase with underscores +between words and "_s" appended to the end of the name +("cups_this_s", "cups_that_s", etc.) Structure names must start +with a prefix, typically "cups" or the name of the program, to +avoid conflicts with system types. Private structure names must +start with an underscore ("_cups_this_s", "_cups_that_s", +etc.)

+ +

Each structure shall have a comment block immediately after +the struct and each member shall be documented in accordance with +the variable naming policy above:

+ +
+struct cups_this_struct_s               /* This structure is for CUPS foobar options. */
+{
+  int this_member;                      /* Current state for this */
+  int that_member;                      /* Current state for that */
+};
+
+ +

Constants

+ +

All constant names shall be uppercase with underscored between +words ("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.) +Constants must begin with an uppercase prefix, typically "CUPS" +or the program name.

+ +

Typed enumerations shall be used whenever possible to allow +for type checking by the compiler.

+ +

Comment blocks shall immediately follow each constant:

+ +
+enum
+{
+  CUPS_THIS_TRAY,                       /* This tray */
+  CUPS_THAT_TRAY                        /* That tray */
+};
+
+ +

Code

+ +

All source code shall utilize block comments within functions +to describe the operations being performed by a group of +statements; avoid putting a comment per line unless absolutely +necessary, and then consider refactoring the code so that it is +not necessary:

+ +
+/*
+ * Clear the state array before we begin...
+ */
+
+for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
+  array[i] = STATE_IDLE;
+
+/*
+ * Wait for state changes...
+ */
+
+do
+{
+  for (i = 0; i < (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])));
+
+ +

Indentation

+ +

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:

+ +
+{
+  int i; /* Looping var */
+
+ /*
+  * Process foobar values from 0 to 999...
+  */
+
+  for (i = 0; i < 1000; i ++)
+  {
+    do_this(i);
+    do_that(i);
+  }
+}
+
+ +

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:

+ +
+switch (array[i])
+{
+  case STATE_IDLE :
+      do_this(i);
+      do_that(i);
+      break;
+  default :
+      do_nothing(i);
+      break;
+}
+
+ +

Spacing

+ +

A space shall follow each reserved word ("if", "while", etc.) +Spaces shall not be inserted between a function name and the +arguments in parenthesis.

+ +

Return Values

+ +

Parenthesis shall surround values returned from a function +using "return":

+ +
+return (CUPS_STATE_IDLE);
+
+ +

Loops

+ +

Whenever convenient loops should count downward to zero to +improve program performance:

+ +
+for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
+  array[i] = CUPS_STATE_IDLE;
+
+ +

Makefile Guidelines

+ +

The following is a guide to the makefile-based build system +used by CUPS. These standards have been developed over the years +to allow CUPS to be built on as many systems and environments as +possible.

+ +

General Organization

+ +

The CUPS source code is organized functionally into a +top-level makefile, include file, and subdirectories each with +their own makefile and dependencies files. The ".in" files are +template files for the autoconf software and are +used to generate a static version of the corresponding file.

+ +

Makefile Documentation

+ +

Each make file must start with the standard CUPS header +containing the Subversion "$Id$" keyword, description of the +file, and CUPS copyright and license notice:

+ +
+#
+# "$Id$"
+#
+#   Makefile for ...
+#
+#   Copyright 2007 by Apple Inc.
+#
+#   These coded instructions, statements, and computer programs are the
+#   property of Apple Inc. 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
+#   file is missing or damaged, see the license at "http://www.cups.org/".
+#
+
+ +

The end of each makefile must have a comment saying:

+ +
+#
+# End of "$Id$".
+#
+
+ +

The purpose of the trailer is to indicate the end of the +makefile so that truncations are immediately obvious.

+ +

Portable Makefile Construction

+ +

CUPS uses a common subset of make program syntax to ensure +that the software can be compiled "out of the box" on as many +systems as possible. The following is a list of assumptions we +follow when constructing makefiles:

+ +
    + +
  • Targets; we assume that the make program + supports the notion of simple targets of the form + "name:" that perform tab-indented commands that follow + the target, e.g.: +
    +target:
    +→ target commands
  • + +
  • Dependencies; we assume that the make program + supports recursive dependencies on targets, e.g.: +
    +target: foo bar
    +→ target commands
    +
    +foo: bla
    +→ foo commands
    +
    +bar:
    +→ bar commands
    +
    +bla:
    +→ bla commands
  • + +
  • Variable Definition; we assume that the make program + supports variable definition on the command-line or in the makefile + using the following form: +
    +name=value
    + +
  • Variable Substitution; we assume that the make program + supports variable substitution using the following forms: +
      +
    • $(name); substitutes the value of "name",
    • +
    • ($name:.old=.new); substitutes the value of "name" + with the filename extensions ".old" changed to ".new",
    • +
    • $(MAKEFLAGS); substitutes the + command-line options passed to the program + without the leading hyphen (-),
    • +
    • $$; substitutes a single $ character,
    • +
    • $<; substitutes the current source file or dependency, and
    • +
    • $@; substitutes the current target name.
    • +
  • + +
  • Suffixes; we assume that the make program + supports filename suffixes with assumed dependencies, e.g.: +
    +.SUFFIXES: .c .o
    +.c.o:
    +→ $(CC) $(CFLAGS) -o $@ -c $<
  • + +
  • Include Files; we assume that the make program + supports the include directive, e.g.: +
    +include ../Makedefs
    +include Dependencies
  • + +
  • Comments; we assume that comments begin with + a # character and proceed to the end of the + current line.
  • + +
  • Line Length; we assume that there is no + practical limit to the length of lines.
  • + +
  • Continuation of long lines; we assume that + the \ character may be placed at the end of a + line to concatenate two or more lines in a + makefile to form a single long line.
  • + +
  • Shell; we assume a POSIX-compatible shell is + present on the build system.
  • + +
+ +

Standard Variables

+ +

The following variables are defined in the "Makedefs" file +generated by the autoconf software:

+ +
    + +
  • AR; the library archiver command,
  • + +
  • ARFLAGS; options for the library archiver command,
  • + +
  • BUILDROOT; optional installation prefix,
  • + +
  • MAN1EXT; extension for man pages in section 1,
  • + +
  • MAN3EXT; extension for man pages in section 3,
  • + +
  • MAN5EXT; extension for man pages in section 5,
  • + +
  • MAN7EXT; extension for man pages in section 7,
  • + +
  • MAN8DIR; subdirectory for man pages in section 8,
  • + +
  • MAN8EXT; extension for man pages in section 8,
  • + +
  • CC; the C compiler command,
  • + +
  • CFLAGS; options for the C compiler command,
  • + +
  • CXX; the C++ compiler command,
  • + +
  • CXXFLAGS; options for the C++ compiler command,
  • + +
  • DSOCOMMAND; the shared library building command,
  • + +
  • DSOFLAGS; options for the shared library building command,
  • + +
  • INSTALL; the install command,
  • + +
  • INSTALL_BIN; the program installation command,
  • + +
  • INSTALL_DATA; the data file installation command,
  • + +
  • INSTALL_DIR; the directory installation command,
  • + +
  • INSTALL_LIB; the library installation command,
  • + +
  • INSTALL_MAN; the documentation installation command,
  • + +
  • INSTALL_SCRIPT; the shell script installation command,
  • + +
  • LDFLAGS; options for the linker,
  • + +
  • LIBS; libraries for all programs,
  • + +
  • LN; the ln command,
  • + +
  • OPTIM; common compiler optimization options,
  • + +
  • RM; the rm command,
  • + +
  • SHELL; the sh (POSIX shell) command,
  • + +
  • STRIP; the strip command,
  • + +
  • bindir; the binary installation directory,
  • + +
  • datadir; the data file installation directory,
  • + +
  • exec_prefix; the installation prefix for executable files,
  • + +
  • libdir; the library installation directory,
  • + +
  • mandir; the man page installation directory,
  • + +
  • prefix; the installation prefix for non-executable files, and
  • + +
  • srcdir; the source directory.
  • + +
+ +

Standard Targets

+ +

The following standard targets must be defined in each +makefile:

+ +
    + +
  • all; creates all target programs, + libraries, and documentation files,
  • + +
  • clean; removes all target programs, + libraries, documentation files, and object files,
  • + +
  • depend; generates automatic dependencies + for any C or C++ source files (also see "Dependencies"),
  • + +
  • distclean; removes autoconf-generated files + in addition to those removed by the "clean" target,
  • + +
  • install; installs all distribution files in + their corresponding locations (also see "Install/Uninstall Support"),
  • + +
  • uninstall; removes all distribution files from + their corresponding locations (also see "Install/Uninstall Support"), and
  • + +
+ + +

Object Files

+ +

Object files (the result of compiling a C or C++ source file) +have the extension ".o".

+ +

Programs

+ +

Program files are the result of linking object files and +libraries together to form an executable file. A typical +program target looks like:

+ +
+program: $(OBJS)
+→ echo Linking $@...
+→ $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+ +

Static Libraries

+ +

Static libraries have a prefix of "lib" and the extension +".a". A typical static library target looks like:

+ +
+libname.a: $(OBJECTS)
+→ echo Creating $@...
+→ $(RM) $@
+→ $(AR) $(ARFLAGS) $@ $(OBJECTS)
+→ $(RANLIB) $@
+
+ +

Shared Libraries

+ +

Shared libraries have a prefix of "lib" and the extension +".dylib", ".sl", ".so", or "_s.a" depending on the operating +system. A typical shared library is composed of several targets +that look like:

+ +
+libname.so: $(OBJECTS)
+→ echo $(DSOCOMMAND) libname.so.$(DSOVERSION) ...
+→ $(DSOCOMMAND) libname.so.$(DSOVERSION) $(OBJECTS)
+→ $(RM) libname.so libname.so.$(DSOMAJOR)
+→ $(LN) libname.so.$(DSOVERSION) libname.so.$(DSOMAJOR)
+→ $(LN) libname.so.$(DSOVERSION) libname.so
+
+libname.sl: $(OBJECTS)
+→ echo $(DSOCOMMAND) libname.sl.$(DSOVERSION) ...
+→ $(DSOCOMMAND) libname.sl.$(DSOVERSION) $(OBJECTS)
+→ $(RM) libname.sl libname.sl.$(DSOMAJOR)
+→ $(LN) libname.sl.$(DSOVERSION) libname.sl.$(DSOMAJOR)
+→ $(LN) libname.sl.$(DSOVERSION) libname.sl
+
+libname.dylib: $(OBJECTS)
+→ echo $(DSOCOMMAND) libname.$(DSOVERSION).dylib ...
+→ $(DSOCOMMAND) libname.$(DSOVERSION).dylib \
+→ → -install_name $(libdir)/libname.$(DSOMAJOR).dylib \
+→ → -current_version libname.$(DSOVERSION).dylib \
+→ → -compatibility_version $(DSOMAJOR).0 \
+→ → $(OBJECTS) $(LIBS)
+→ $(RM) libname.dylib
+→ $(RM) libname.$(DSOMAJOR).dylib
+→ $(LN) libname.$(DSOVERSION).dylib libname.$(DSOMAJOR).dylib
+→ $(LN) libname.$(DSOVERSION).dylib libname.dylib
+
+libname_s.a: $(OBJECTS)
+→ echo $(DSOCOMMAND) libname_s.o ...
+→ $(DSOCOMMAND) libname_s.o $(OBJECTS) $(LIBS)
+→ echo $(LIBCOMMAND) libname_s.a libname_s.o
+→ $(RM) $@
+→ $(LIBCOMMAND) libname_s.a libname_s.o
+→ $(CHMOD) +x libname_s.a
+
+ + +

Dependencies

+ +

Static dependencies are expressed in each makefile following the +target, for example:

+ +
+foo: bar
+
+ +

Static dependencies shall only be used when it is not +possible to automatically generate them. Automatic dependencies +are stored in a file named "Dependencies" and included at the +end of the makefile. The following "depend" target rule shall be +used to create the automatic dependencies: + +

+depend:
+→ $(MAKEDEPEND) -Y -I.. -f Dependencies $(OBJS:.o=.c)
+
+ +

We only regenerate the automatic dependencies on a Linux +system and express any non-Linux dependencies statically in the +makefile.

+ +

Install/Uninstall Support

+ +

All makefiles must contain install and uninstall rules which +install or remove the corresponding software. These rules must +use the $(BUILDROOT) variable as a prefix to any +installation directory so that CUPS can be installed in a +temporary location for packaging by programs like +rpmbuild.

+ +

The $(INSTALL_BIN), $(INSTALL_DATA), +$(INSTALL_DIR), $(INSTALL_LIB), +$(INSTALL_MAN), and $(INSTALL_SCRIPT) +variables must be used when installing files so that the proper +ownership and permissions are set on the installed files.

+ +

The $(RANLIB) command must be run on any static +libraries after installation since the symbol table is +invalidated when the library is copied on some platforms.

+ + + diff --git a/doc/help/spec-command.html b/doc/help/spec-command.html new file mode 100644 index 0000000000..bf731ccbd3 --- /dev/null +++ b/doc/help/spec-command.html @@ -0,0 +1,218 @@ + + + + + CUPS Command File Format + + + + + + +

CUPS Command File Format

+ +

Introduction

+ +

This specification describes the CUPS command file format +(application/vnd.cups-command) which is used to send printer +maintenance commands to a printer in a device-independent way. +The current specification supports basic maintenance functions +such as head cleaning and self-test pages and query functions +such as auto-configure, report supply levels, and report status.

+ +

Printer drivers advertise support for the CUPS command file +format by providing a filter for the +application/vnd.cups-command file type. Applications +can determine if a printer supports printing of CUPS command +files by checking the printer-type attribute for the +CUPS_PRINTER_COMMANDS capability bit.

+ +

In addition, the PPD file for a printer can contain a +cupsCommands keyword that provides a list of supported +commands separated by spaces, for example:

+ +
+*cupsCommand: "AutoConfigure Clean PrintSelfTestPage ReportLevels ReportStatus"
+
+ +

If no cupsCommands keyword is provided, the command filter +must support AutoConfigure, +Clean, +PrintSelfTestPage, +and ReportLevels. The scheduler also +provides the printer-commands attribute containing the list of +supported commands.

+ + +

File Syntax

+ +

CUPS command files are ASCII text files. The first line of a +CUPS command file MUST contain:

+ +
+#CUPS-COMMAND
+
+ +

After that, each line is either a command or a comment. +Comments begin with the # character, e.g.:

+ +
+# This is a comment
+
+ +

Commands are any sequence of letters, numbers, and punctuation characters +optionally followed by parameters separated by whitespace, e.g.:

+ +
+Clean all
+PrintSelfTestPage
+
+ +

Command names are case-insensitive, so "PRINTSELFTESTPAGE", +"printselftestpage", and "PrintSelfTestPage" are equivalent. Vendor-specific +commands should use a domain name prefix, e.g.:

+ +
+com.vendor.foo
+com.vendor.bar param param2 ... paramN
+
+ + +

Standard Commands

+ +

The following are the standard commands supported by the format. The only +required command is +PrintSelfTestPage.

+ + +

AutoConfigure

+ +

AutoConfigure

+ +

The AutoConfigure command updates the printer's PPD file +and driver state information to reflect the current configuration of the +printer. There are no arguments for this command.

+ +

Example:

+ +
+#CUPS-COMMAND
+AutoConfigure
+
+ + +

Clean

+ +

Clean colorname

+ +

The Clean command performs a standard print head cleaning. The +"colorname" parameter specifies which color or head to clean. If a printer does +not support cleaning of individual colors or cartridges, then all colors are +cleaned. Command filters MUST support the "all" colorname. Other standard color +names include "black", "color", "photo", "cyan", "magenta", "yellow", +"light-cyan", "light-magenta", "light-black", "light-gray", and "dark-gray".

+ +

Example:

+ +
+#CUPS-COMMAND
+Clean all
+
+ + +

PrintAlignmentPage

+ +

PrintAlignmentPage pass

+ +

The PrintAlignmentPage command prints a head alignment page on +the printer. The "pass" parameter provides a pass number from 1 to N. The number +of passes is device-dependent.

+ +

Example:

+ +
+#CUPS-COMMAND
+PrintAlignmentPage 1
+
+ + +

PrintSelfTestPage

+ +

PrintSelfTestPage

+ +

The PrintSelfTestPage command prints a self-test page on the +printer. Typically this page shows whether all jets on a print head are +functioning and that the print feed mechanisms are working properly.

+ +

Example:

+ +
+#CUPS-COMMAND
+PrintSelfTestPage
+
+ + +

ReportLevels

+ +

ReportLevels

+ +

The ReportLevels command queries the supply levels on a printer +and reports "marker-colors", "marker-levels", "marker-names", and +"marker-types" attributes using "ATTR:" messages sent to the scheduler. This +command should also report the current printer status using "STATE:" messages +like the ReportStatus command.

+ +

Example:

+ +
+#CUPS-COMMAND
+ReportLevels
+
+ + +

ReportStatus

+ +

ReportStatus

+ +

The ReportStatus command queries the printer for its current +status and reports it using "STATE:" messages sent to the scheduler.

+ +

Example:

+ +
+#CUPS-COMMAND
+ReportLevels
+
+ + +

SetAlignment

+ +

SetAlignment pass value ... valueN

+ +

The SetAlignment command sets print head alignment values. The +"pass" parameter is a number from 1 to N. All parameters are +device-dependent.

+ +

Example:

+ +
+#CUPS-COMMAND
+SetAlignment 1 14
+
+ + + + diff --git a/doc/help/spec-design.html b/doc/help/spec-design.html new file mode 100644 index 0000000000..28a14eb31d --- /dev/null +++ b/doc/help/spec-design.html @@ -0,0 +1,184 @@ + + + + + CUPS Design Description + + + + +

CUPS Design Description

+ +

This design description documents the overall organization of CUPS. The purpose is not to provide a line-by-line description of the CUPS source code, but rather to describe the overall architecture and location of key pieces so that developers can more easily understand the underlying operation of CUPS.

+ +

Introduction

+ +

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.

+ +

Scheduler

+ +

The scheduler is a HTTP/1.1 and IPP/2.1 server application that manages HTTP and IPP requests, printers, classes, jobs, subscriptions, and notifications on the system. HTTP is used for normal web browser services as well as IPP operation messages passed via HTTP POST requests with the application/ipp content type. The scheduler uses a series of helper applications based on the Common Gateway Interface ("CGI") to provide dynamic web interfaces and can be configured to run additional site-specific programs or scripts for the web interface.

+ +

The scheduler is designed as a traditional single-threaded server process which runs external processes to do longer-term operations such as printing, notification, device/driver enumeration, and remote printer monitoring. External processes are normally run as a non-privileged account ("lp") and, on some platforms, with additional restrictions that limit what the processes are allowed to do.

+ +

The maximum number of simultaneous clients and print jobs that can be supported is primarily limited by the available server memory, file descriptors, and CPU - the scheduler itself imposes no hard limits.

+ +
+ + +
Figure 1: CUPS Block Diagram
CUPS Block Diagram
+ +

Config Files

+ +

The scheduler uses several configuration files to store the server settings (cupsd.conf), available classes (classes.conf), available printers (printers.conf), current notification subscriptions (subscriptions.conf), and supported file types and filters (mime.types, mime.convs). In addition, PostScript Printer Description ("PPD") files or interface scripts are associated with each printer, and the scheduler has cache files for remote printers, PPD files, and current jobs to optimize the scheduler's startup speed and availability.

+ +

Job Files

+ +

The scheduler stores job files in a spool directory, typically /var/spool/cups. Two types of files will be found in the spool directory: control files starting with the letter "c" ("c00001", "c99999", "c100000", etc.) and data files starting with the letter "d" ("d00001-001", "d99999-001", "d100000-001", etc.) Control files are IPP messages based on the original IPP Print-Job or Create-Job messages, while data files are the original print files that were submitted for printing. There is one control file for every job known to the system and 0 or more data files for each job. + +

Control files are normally cleaned out after the 500th job is submitted, while data files are removed immediately after a job has successfully printed. Both behaviors can be configured.

+ +

Log Files

+ +

The scheduler keeps three kinds of log files which are normally stored in the /var/log/cups directory. The access_log file lists every HTTP and IPP request that is processed by the scheduler. The error_log file contains messages from the scheduler and its helper applications that can be used +to track down problems. The page_log file lists every page that is printed, allowing for simple print accounting.

+ +

Log files are rotated automatically by the scheduler when they reach the configured size limit, by default 1MB. If the limit is set to 0 then no rotation is performed in the scheduler - this mode is often used by Linux distributions so they can use the logrotated(8) program to rotate them instead.

+ +

Berkeley Commands

+ +

CUPS provides the Berkeley lpc(8), lpq(1), lpr(1), and lprm(1) commands. In general, they function identically to the original Berkeley commands with the following exceptions:

+ +
    + +
  1. The lpc command currently only supports the "status" sub-command.
  2. + +
  3. The lpr command does not support the format modifier options "1" (TROFF font set 1), "2" (TROFF font set 2), "3" (TROFF font set 3), "4" (TROFF font set 4), "c" (CIFPLOT), "d" (DVI), "f" (FORTRAN), "g" (GNU plot), "i" (indentation), "n" (Ditroff), "r" (Sun raster), "t" (Troff), or "w" (width), as they do not map to the IPP MIME media type based document formats.
  4. + +
+ +

System V Commands

+ +

CUPS provides the System V cancel(1), lp(1), lpadmin(8), lpmove(8), and lpstat(1) commands. In general, they function identically to the original System V commands with the following exceptions:

+ +
    + +
  1. All commands may ask for a password; the System V print spooler requires root access to perform administration tasks, while CUPS allows for more flexible configurations.
  2. + +
  3. The lpadmin command does not implement the Solaris "-A" (alert), "-F" (fault recovery), "-M" (mount form/wheel), "-P" (paper list), "-S" (print wheels), "-T" (type list), "-U" (dialer info), "-W" (wait), "-f" (form name), "-l" (content-type list), "-s" (remote printer), or "-t" (number of trays) options.
  4. + +
+ +

CUPS Commands

+ +

CUPS provides the cupsaccept(8), cupsaddsmb(8), cupsdisable(8), cupsenable(8), cupsreject(8), cupstestppd(1), lpinfo(8), and lppasswd(1) commands. The cupsaccept, cupsdisable, cupsenable, and cupsreject commands correspond to the System V accept, disable, enable, and reject commands but have been renamed to avoid confusion and conflicts with the bash(1) internal enable command of the same name.

+ +

LPD Support

+ +

LPD client support is provided via the cups-lpd(8) program. Incoming LPD requests are accepted on TCP port 515 by the local inetd(8), launchd(8), or xinetd(8) process and forwarded to the cups-lpd program for conversion to the corresponding IPP request(s).

+ +

The cups-lpd program conforms, for the most part, to RFC 1179: Line Printer Daemon Protocol, but does not enforce the privileged source port restriction specified in that document. In addition, the banner page and output format options are usually overridden via command-line options to the cups-lpd program when it is invoked by the corresponding super-daemon program.

+ +

Web Interface

+ +

The web interface is supported by five CGI programs. Table 1 describes the purpose of each of the programs.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: CGI Programs
ProgramLocationDescription
admin.cgi/adminProvides all of the administrative functions
classes.cgi/classesLists classes and provides class management functions
help.cgi/helpProvides access to online help documents
jobs.cgi/jobsLists jobs and provides job management functions
printers.cgi/printersLists printers and provides printer management functions
+ +

Notifiers

+ +

Notifiers (notifier(7)) provide the means for sending asynchronous event notifications from the scheduler. Notifiers are executed with the recipient information on the command-line and the event data on the standard input. For example:

+ +
+CUPS_SERVERBIN/notifier/foo recipient user-data
+
+ +

CUPS includes two notifiers: mailto to provide SMTP-based email notifications and rss to provide Really Simple Syndication ("RSS") notifications from the scheduler. Additional notifiers can be installed in the notifier directory as needed to support other methods.

+ +

Filters

+ +

Filters (filter(7)) convert job files into a printable format. Multiple filters are run, as needed, to convert from the job file format to the printable format. 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.

+ +

CUPS provides filters for printing text, PostScript, PDF, HP-GL/2, and many types of image files. CUPS also provides printer driver filters for HP-PCL, ESC/P, and several types of label printers. Additional filters can be registered with CUPS via mime.convs and PPD files.

+ +

Port Monitors

+ +

Port monitors handle the device- and channel-specific data formatting for a printer. Port monitors use the same interface as filters.

+ +

CUPS includes two port monitors: the bcp port monitor which supports the PostScript Binary Communications Protocol ("BCP") and the tbcp port monitor which supports the PostScript Tagged Binary Communications Protocol ("TBCP"). Additional port monitors can be registered in PPD files.

+ +

Backends

+ +

Backends (backend(7)) send print data to the printer and enumerate available printers/devices as needed. Backends use the same interface as filters.

+ +

CUPS includes backends for AppSocket (JetDirect), IPP, LPD, parallel, SCSI, serial, and USB connections. Additional backends can be added as needed without additional configuration.

+ + +

Programming Interfaces

+ +

CUPS makes use of several general-purpose libraries to provide its printing services. Unlike the rest of CUPS, the libraries are provided under the terms of the GNU LGPL so they may be used by non-GPL applications.

+ +

CUPS Library (libcups)

+ +

The CUPS library contains all of the core HTTP and IPP communications code as well as convenience functions for queuing print jobs, getting printer information, accessing resources via HTTP and IPP, and manipulating PPD files. The scheduler and all commands, filters, and backends use this library.

+ +

CUPS CGI Library (libcupscgi)

+ +

The CUPS CGI library provides all of the web interface support functions. It is used by the CGI programs to provide the CUPS web interface.

+ +

CUPS Driver Library (libcupsdriver)

+ +

The CUPS driver library provides access to the dithering, color conversion, and helper functions used by the CUPS sample printer drivers.

+ +

CUPS Imaging Library (libcupsimage)

+ +

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.

+ +

CUPS MIME Library (libcupsmime)

+ +

The CUPS MIME library provides file typing and conversion functions and is used by the scheduler and cupsfilter(8) command to auto-type and convert print files to a printable format.

+ +

CUPS PPD Compiler Library (libcupsppdc)

+ +

The CUPS PPD compiler library provides access to driver information files and is used by the PPD compiler tools as well as the cups-driverd(8) helper program to generate PPD files and message catalogs for localization.

+ + + + diff --git a/doc/help/spec-ipp.html b/doc/help/spec-ipp.html new file mode 100644 index 0000000000..c87672797d --- /dev/null +++ b/doc/help/spec-ipp.html @@ -0,0 +1,2879 @@ + + + + + CUPS Implementation of IPP + + + + + + +

CUPS Implementation of IPP

+ +

Introduction

+ +

CUPS implements IPP/2.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.

+ +

CUPS also provides 16 new operations and many new attributes +to support multiple IPP printers and printer classes on a single +host.

+ +

IPP URIs

+ +

CUPS supports the "http", "https", and "ipp" schemes. The +following resource names are used:

+ +
+ +
scheme://hostname:port/
+ +
Can be used for all "get" operations and for server + subscriptions.
+ +
scheme://hostname:port/admin/
+ +
Used for all administrative operations.
+ +
scheme://hostname:port/classes/name
+ +
Specifies a printer class.
+ +
scheme://hostname:port/jobs/id
+ +
Specifies a job.
+ +
scheme://hostname:port/printers/name
+ +
Specifies a printer.
+ +
+ +

So a typical printer URI would be +"ipp://foo.bar.com/printers/LaserJet". In addition, the CUPS +server also supports normal browser access via +"http://hostname:port/" and "https://hostname:port/".

+ +

CUPS IPP Operations

+ +

CUPS provides 16 extension operations in addition to most of the +standard IPP and registered extension operations: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Operation NameCUPSCodeBrief Description
Print-Job1.00x0002Print a file.
Validate-Job1.00x0004Validate job attributes.
Create-Job1.10x0005Create a print job.
Send-Document1.10x0006Send a file for a print job.
Cancel-Job1.00x0008Cancel a print job.
Get-Job-Attributes1.00x0009Get job attributes.
Get-Jobs1.00x000AGet all jobs.
Get-Printer-Attributes1.00x000BGet printer attributes.
Hold-Job1.10x000CHold a job for printing.
Release-Job1.10x000DRelease a job for printing.
Restart-Job1.10x000ERestarts a print job.
Pause-Printer1.00x0010Pause printing on a printer.
Resume-Printer1.00x0011Resume printing on a printer.
Purge-Jobs1.00x0012Purge all jobs.
Set-Job-Attributes1.10x0014Set attributes for a pending or held job.
Create-Printer-Subscription1.20x0016Creates a subscription associated with a printer or the server.
Create-Job-Subscription1.20x0017Creates a subscription associated with a job.
Get-Subscription-Attributes1.20x0018Gets the attributes for a subscription.
Get-Subscriptions1.20x0019Gets the attributes for zero or more subscriptions.
Renew-Subscription1.20x001ARenews a subscription.
Cancel-Subscription1.20x001BCancels a subscription.
Get-Notifications1.20x001CGet notification events for ippget subscriptions.
Enable-Printer1.20x0022Accepts jobs on a printer.
Disable-Printer1.20x0023Rejects jobs on a printer.
CUPS-Get-Default1.00x4001Get the default destination.
CUPS-Get-Printers1.00x4002Get all of the available printers.
CUPS-Add-Modify-Printer1.00x4003Add or modify a printer.
CUPS-Delete-Printer1.00x4004Delete a printer.
CUPS-Get-Classes1.00x4005Get all of the available printer classes.
CUPS-Add-Modify-Class1.00x4006Add or modify a printer class.
CUPS-Delete-Class1.00x4007Delete a printer class.
CUPS-Accept-Jobs1.00x4008Accept jobs on a printer or printer class.
CUPS-Reject-Jobs1.00x4009Reject jobs on a printer or printer class.
CUPS-Set-Default1.00x400ASet the default destination.
CUPS-Get-Devices1.10x400BGet all of the available devices.
CUPS-Get-PPDs1.10x400CGet all of the available PPDs.
CUPS-Move-Job1.10x400DMove a job to a different printer.
CUPS-Authenticate-Job1.20x400EAuthenticate a job for printing.
CUPS-Get-PPD1.30x400FGet a PPD file.
CUPS-Get-Document1.40x4027Get a document file from a job.
+ +

Operations

+ +

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

Print-Job Operation

+ +

The Print-Job operation (0x0002) prints a file. + +

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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer. + +
+ +

Group 2: Job Template Attributes + +

+ +
"auth-info" (1setOf text(MAX)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies one or more authentication values as specified by the "auth-info-required" attribute. + +
"job-billing" (text(MAX)):CUPS 1.1 + +
The client OPTIONALLY supplies a billing string that is logged + with the page accounting information. + +
"job-sheets" (1setof type3 keyword | name(MAX)):CUPS 1.1 + +
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. + +
Note: Standard IPP only allows + specification of a single job-sheets attribute + value.
+ +
"media" (1setof type3 keyword | name(MAX)): + +
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. + +
Note: Standard IPP only allows + specification of a single media attribute + value.
+ +
Other Job Template Attributes + +
+ +

The Print-Job request is followed by a file to be printed. + +

Print-Job Response

+ +

The following groups of attributes are send as part of the Print-Job +Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Job Attributes + +

+ +
Standard Job Attributes + +
+ +

Group 3: Unsupported Attributes (status=client-eror-attributes-or-values-not-supported) + +

+ +
auth-info-required (1setOf Type2 keyword) + +
The required authentication information. + +
+ +

CUPS 1.1Create-Job Operation

+ +

The Create-Job operation (0x0005) creates a new, empty print job. + +

Create-Job Request

+ +

The following groups of attributes are supplied as part of the +Create-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer. + +
+ +

Group 2: Job Template Attributes + +

+ +
"auth-info" (1setOf text(MAX)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies one or more authentication values as specified by the "auth-info-required" attribute. + +
"job-billing" (text(MAX)):CUPS 1.1 + +
The client OPTIONALLY supplies a billing string that is logged + with the page accounting information. + +
"job-sheets" (1setof type3 keyword | name(MAX)):CUPS 1.1 + +
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. + +
Note: Standard IPP only allows + specification of a single job-sheets attribute + value.
+ +
"media" (1setof type3 keyword | name(MAX)): + +
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. + +
Note: Standard IPP only allows + specification of a single media attribute + value.
+ +
Standard Job Template Attributes + +
+ +

Create-Job Response

+ +

The following groups of attributes are send as part of the +Create-Job Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Job Attributes + +

+ +
Standard Job Attributes + +
+ +

Group 3: Unsupported Attributes (status=client-eror-attributes-or-values-not-supported) + +

+ +
auth-info-required (1setOf Type2 keyword) + +
The required authentication information. + +
+ +

Cancel Job Operation

+ +

The Cancel-Job operation (0x0008) cancels the specified job. CUPS 1.4 adds +a new purge-job (boolean) attribute that allows you to purge both +active and completed jobs, removing all history and document files for the +job as well. + +

Cancel-Job Request

+ +

The following groups of attributes are supplied as 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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) and "job-id" (integer) +
OR +
"job-uri": + +
The client MUST supply a URI for the specified printer and + a job ID number, or the job URI. + +
CUPS 1.4/Mac OS X 10.6"purge-job" (boolean): + +
The client OPTIONALLY supplies this attribute. When true, + all job files (history and document) are purged. The default + is false, leading to the standard IPP behavior. + +
+ +

Cancel-Job Response

+ +

The following groups of attributes are send as part of the Cancel-Job +Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Purge-Jobs Operation

+ +

The Purge-Jobs operation (0x0012) cancels all of the jobs on a +given destination and optionally removes all history and document +files for the jobs as well. + +

Purge-Jobs Request

+ +

The following groups of attributes are supplied as part of the +Purge-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer or + "ipp://.../printers" for all printers and classes. + +
CUPS 1.2/Mac OS X 10.5"requesting-user-name" (name(MAX)): + +
The client OPTIONALLY supplies this attribute to specify whose jobs + jobs are purged or canceled. + +
CUPS 1.2/Mac OS X 10.5"my-jobs" (boolean): + +
The client OPTIONALLY supplies this attribute to specify that only + the jobs owned by the requesting user are purged or canceled. The + default is false. + +
CUPS 1.2/Mac OS X 10.5"purge-jobs" (boolean): + +
The client OPTIONALLY supplies this attribute to specify + whether the jobs are purged (true) or just canceled (false). + The default is true. + +
+ +

Purge-Jobs Response

+ +

The following groups of attributes are send as part of the Purge-Jobs +Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS 1.1Set-Job-Attributes Operation

+ +

The Set-Job-Attributes operation (0x0014) changes the attributes of +an active (not completed) job. + +

Set-Job-Attributes Request

+ +

The following groups of attributes are supplied as part of the +Set-Job-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) and "job-id" (integer) +
OR +
"job-uri": + +
The client MUST supply a URI for the specified printer and + a job ID number, or the job URI. + +
+ +

Group 2: Job Template Attributes + +

+ +
"job-sheets" (1setof type3 keyword | name(MAX)):CUPS 1.1 + +
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. + +
Note: Standard IPP only allows + specification of a single job-sheets attribute + value.
+ +
"media" (1setof type3 keyword | name(MAX)): + +
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. + +
Note: Standard IPP only allows + specification of a single media attribute + value.
+ +
Other Job Template Attributes + +
+ +

Set-Job-Attributes Response

+ +

The following groups of attributes are send as part of the Set-Job-Attributes +Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS 1.2/Mac OS X 10.5Create-Printer-Subscription

+ +

The Create-Printer-Subscription operation (0x0016) creates a +subscription for printer or server event notifications. CUPS +provides several additional events in addition to the standard +events in the IPP notifications specification.

+ +

Create-Printer-Subscription Request

+ +

The following groups of attributes are supplied as part of the +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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The printer + (ipp://server/printers/printername), class + (ipp://server/classes/classname), or server + (ipp://server/) URI for event notifications. + +
"notify-events" (1setOf keyword): + +
The events to monitor. In addition to the standard + events, CUPS adds the following keywords: +
    + +
  • printer-added - Get notified + whenever a printer or class is added
  • + +
  • printer-deleted - Get notified + whenever a printer or class is deleted
  • + +
  • printer-modified - Get notified + whenever a printer or class is modified
  • + +
  • server-audit - Get notified when a + security condition occurs
  • + +
  • server-restarted - Get notified when + the server is restarted
  • + +
  • server-started - Get notified when + the server is started
  • + +
  • server-stopped - Get notified when + the server is stopped
  • + +
+ +
+ +

Create-Printer-Subscription Response

+ +

The following groups of attributes are send as part of the +response:

+ +

Group 1: Operation Attributes

+ +
+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Subscription Object Attributes

+ +
+ +
"subscription-id" (integer): + +
The subscription number. + +
+ +

CUPS-Get-Default Operation

+ +

The CUPS-Get-Default operation (0x4001) returns the default printer +URI and attributes. + +

CUPS-Get-Default Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Default 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 of the IPP Model and + Semantics document. + +
"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. If the client omits this attribute, the server + responds as if this attribute had been supplied with a value of + 'all'. + +
+ +

CUPS-Get-Default Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Default Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Printer Object Attributes + +

+ +
The set of requested attributes and their current values. + +
+ +

CUPS-Get-Printers Operation

+ +

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

CUPS-Get-Printers Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Printers 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 of the IPP Model and + Semantics document. + +
"first-printer-name" (name(127)):CUPS 1.2/Mac OS X 10.5 + +
The client OPTIONALLY supplies this attribute to + select the first printer that is returned. + +
"limit" (integer (1:MAX)): + +
The client OPTIONALLY supplies this attribute limiting the + number of printers that are returned. + +
"printer-location" (text(127)): CUPS 1.1.7 + +
The client OPTIONALLY supplies this attribute to + select which printers are returned. + +
"printer-type" (type2 enum): CUPS 1.1.7 + +
The client OPTIONALLY supplies a printer type enumeration to + select which printers are returned. + +
"printer-type-mask" (type2 enum): CUPS 1.1.7 + +
The client OPTIONALLY supplies a printer type mask + enumeration to select which bits are used in the "printer-type" + attribute. + +
"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. If the client omits this attribute, the server + responds as if this attribute had been supplied with a value of + 'all'. + +
"requested-user-name" (name(127)) : CUPS 1.2/Mac OS X 10.5 + +
The client OPTIONALLY supplies a user name that is used to filter + the returned printers. + +
+ +

CUPS-Get-Printers Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Printers Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Printer Object Attributes + +

+ +
The set of requested attributes and their current values for + each printer. + +
+ +

CUPS-Add-Modify-Printer Operation

+ +

The CUPS-Add-Modify-Printer operation (0x4003) adds a new printer or +modifies an existing printer on the system. + +

CUPS-Add-Modify-Printer Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Add-Modify-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer. + +
+ +

Group 2: Printer Object Attributes + +

+ +
"auth-info-required" (1setOf type2 keyword):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies one or more authentication keywords that are required to communicate with the printer/remote queue. + +
"job-sheets-default" (1setOf name(127)): CUPS 1.1.7 + +
The client OPTIONALLY supplies one or two banner page + names that are printed before and after files in a job. + The reserved name "none" is used to specify that no + banner page should be printed. + +
"device-uri" (uri): + +
The client OPTIONALLY supplies a device URI for the + specified printer. + +
"port-monitor" (name(127)): + +
The client OPTIONALLY supplies a port monitor name for the + specified printer. + +
"ppd-name" (name(127)): + +
The client OPTIONALLY supplies a PPD name for the specified + printer. + +
"printer-is-accepting-jobs" (boolean): + +
The client OPTIONALLY supplies this boolean attribute + indicating whether or not the printer object should accept new jobs. + +
"printer-info" (text(127)): + +
The client OPTIONALLY supplies this attribute indicating the + printer information string. + +
"printer-location" (text(127)): + +
The client OPTIONALLY supplies this attribute indicating a + textual location of the printer. + +
"printer-more-info" (uri): + +
The client OPTIONALLY supplies this attribute indicating a + URI for additional printer information. + +
"printer-state" (type2 enum): + +
The client OPTIONALLY supplies this attribute indicating the + initial/current state of the printer. Only the "idle" and "stopped" + enumerations are recognized. + +
"printer-state-message" (text(MAX)): + +
The client OPTIONALLY supplies this attribute indicating a + textual reason for the current printer state. + +
"requesting-user-name-allowed" (1setof name(127) | delete) +
OR +
"requesting-user-name-denied" (1setof name(127) | delete): + +
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. + +
+ +

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

CUPS-Add-Modify-Printer Response

+ +

The following groups of attributes are send as part of the +CUPS-Add-Modify-Printer Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS-Delete-Printer Operation

+ +

The CUPS-Delete-Printer operation (0x4004) removes an existing +printer from the system. + +

CUPS-Delete-Printer Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Delete-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer. + +
+ +

CUPS-Delete-Printer Response

+ +

The following groups of attributes are send as part of the +CUPS-Delete-Printer Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS-Get-Classes Operation

+ +

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

CUPS-Get-Classes Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Classes 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 of the IPP Model and + Semantics document. + +
"first-printer-name" (name(127)):CUPS 1.2/Mac OS X 10.5 + +
The client OPTIONALLY supplies this attribute to + select the first printer that is returned. + +
"limit" (integer (1:MAX)): + +
The client OPTIONALLY supplies this attribute limiting the + number of printer classes that are returned. + +
"printer-location" (text(127)): CUPS 1.1.7 +
The client OPTIONALLY supplies this attribute to + select which printer classes are returned. + +
"printer-type" (type2 enum): CUPS 1.1.7 +
The client OPTIONALLY supplies a printer type enumeration to + select which printer classes are returned. + +
"printer-type-mask" (type2 enum): CUPS 1.1.7 +
The client OPTIONALLY supplies a printer type mask + enumeration to select which bits are used in the "printer-type" + attribute. + +
"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. If the client omits this attribute, the server responds as + if this attribute had been supplied with a value of 'all'. + +
"requested-user-name" (name(127)) : CUPS 1.2/Mac OS X 10.5 + +
The client OPTIONALLY supplies a user name that is used to filter + the returned printers. + +
+ +

CUPS-Get-Classes Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Classes Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Printer Class Object Attributes + +

+ +
The set of requested attributes and their current values for + each printer class. + +
+ +

CUPS-Add-Modify-Class Operation

+ +

The CUPS-Add-Modify-Class operation (0x4006) adds a new printer class or +modifies and existing printer class on the system. + +

CUPS-Add-Modify-Class Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Add-Modify-Class 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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer class. + +
+ +

Group 2: Printer Object Attributes + +

+ +
"auth-info-required" (1setOf type2 keyword):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies one or more authentication keywords that are required to communicate with the printer/remote queue. + +
"member-uris" (1setof uri): + +
The client OPTIONALLY supplies the "member-uris" set + specifying the printers and printer classes that are part of the class. + +
"printer-is-accepting-jobs" (boolean): + +
The client OPTIONALLY supplies this boolean attribute + indicating whether or not the class object should accept new jobs. + +
"printer-info" (text(127)): + +
The client OPTIONALLY supplies this attribute indicating the + printer information string. + +
"printer-location" (text(127)): + +
The client OPTIONALLY supplies this attribute indicating a + textual location of the class. + +
"printer-more-info" (uri): + +
The client OPTIONALLY supplies this attribute indicating a + URI for additional class information. + +
"printer-state" (type2 enum): + +
The client OPTIONALLY supplies this attribute indicating the + initial/current state of the class. Only the "idle" and "stopped" + enumerations are recognized. + +
"printer-state-message" (text(MAX)): + +
The client OPTIONALLY supplies this attribute indicating a + textual reason for the current class state. + +
"requesting-user-name-allowed" (1setof name(127)) +
OR +
"requesting-user-name-denied" (1setof name(127)): + +
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. + +
+ +

CUPS-Add-Modify-Class Response

+ +

The following groups of attributes are send as part of the CUPS-Add-Modify-Class Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS-Delete-Class Operation

+ +

The CUPS-Delete-Class operation (0x4007) removes an existing printer +class from the system. + +

CUPS-Delete-Class Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Delete-Class 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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer class. + +
+ +

CUPS-Delete-Class Response

+ +

The following groups of attributes are send as part of the +CUPS-Delete-Class Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS-Accept-Jobs Operation

+ +

The CUPS-Accept-Jobs operation (0x4008) sets the +"printer-is-accepting-jobs" attribute to true for the specified printer +or printer class. + +

CUPS-Accept-Jobs Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Accept-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer or printer class. + +
+ +

CUPS-Accept-Jobs Response

+ +

The following groups of attributes are send as part of the +CUPS-Accept-Jobs Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS-Reject-Jobs Operation

+ +

The CUPS-Reject-Jobs operation (0x4009) sets +the"printer-is-accepting-jobs" attribute to false for the specified +printer or printer class. + +

CUPS-Reject-Jobs Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Reject-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer or printer class. + +
+ +

Group 2: Printer Object Attributes + +

+ +
"printer-state-message" (text(MAX)): + +
The client OPTIONALLY supplies this attribute indicating a + textual reason for the current printer state. + +
+ +

CUPS-Reject-Jobs Response

+ +

The following groups of attributes are send as part of the +CUPS-Reject-Jobs Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS-Set-Default Operation

+ +

The CUPS-Set-Default operation (0x400A) sets the default printer +destination for all clients when a resource name of "/printers" is +specified. + +

CUPS-Set-Default Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Set-Default 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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The client MUST supply a URI for the specified printer or + printer class. + +
+ +

CUPS-Set-Default Response

+ +

The following groups of attributes are send as part of the +CUPS-Set-Default Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS 1.1CUPS-Get-Devices Operation

+ +

The CUPS-Get-Devices operation (0x400B) returns all of the +supported device-uri's for the server.

+ +

CUPS-Get-Devices Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Devices 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 of the IPP Model and + Semantics document. + +
"device-class" (type1 keyword): + +
The client OPTIONALLY supplies a device class keyword to select + which devices are returned. + +
"exclude-schemes" (1setOf name) :CUPS 1.4/Mac OS X 10.6 + +
The client OPTIONALLY supplies a set of scheme names that the + requestor does not want to discover. If the client omits this attribute, + the server responds with devices of all schemes specified by + the "include-schemes" attribute. + +
"include-schemes" (1setOf name) :CUPS 1.4/Mac OS X 10.6 + +
The client OPTIONALLY supplies a set of scheme names that the + requestor wants to discover. If the client omits this attribute, + the server responds with devices of all schemes except those specified + by the "exclude-schemes" attribute. + +
"limit" (integer (1:MAX)): + +
The client OPTIONALLY supplies this attribute limiting the number of + devices that are returned. + +
"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. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'. + +
"timeout" (integer (1:MAX)) :CUPS 1.4/Mac OS X 10.6 + +
The client OPTIONALLY supplies this attribute to limit the duration + of the lookup. The default timeout is 15 seconds. + +
+ +

CUPS-Get-Devices Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Devices Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Device Object Attributes + +

+ +
The set of requested attributes and their current values for + each device. + +
+ +

CUPS 1.1CUPS-Get-PPDs Operation

+ +

The CUPS-Get-PPDs operation (0x400C) returns all of the +locally available PPD files on the system.

+ +

CUPS-Get-PPDs Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-PPDs 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 of the IPP Model and + Semantics document. + +
"exclude-schemes" (1setOf name) :CUPS 1.4/Mac OS X 10.6 + +
The client OPTIONALLY supplies a set of scheme names that the + requestor does not want to list. If the client omits this attribute, + the server responds with PPDs of all schemes specified by the + "include-schemes" attribute. + +
"include-schemes" (1setOf name) :CUPS 1.4/Mac OS X 10.6 + +
The client OPTIONALLY supplies a set of scheme names that the + requestor wants to list. If the client omits this attribute, the server + responds with PPDs of all schemes except those specified by the + "exclude-schemes" attribute. + +
"limit" (integer (1:MAX)): + +
The client OPTIONALLY supplies this attribute limiting the number of PPDs that are returned. + +
"ppd-make" (text(127)): + +
The client OPTIONALLY supplies a printer manufacturer to select which PPDs are returned. + +
"ppd-make-and-model" (text(127)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a make and model to select which PPDs are returned. + +
"ppd-model-number" (integer):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a model number to select which PPDs are returned. + +
"ppd-natural-language" (naturalLanguage):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a language to select which PPDs are returned. + +
"ppd-product" (text(127)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a PostScript product string to select which PPDs are returned. + +
"ppd-psversion" (text(127)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a PostScript version string to select which PPDs are returned. + +
"ppd-type" (type1 keyword):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a driver type to select which PPDs are returned. + +
"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. If the client omits this attribute, the server responds as if this attribute had been supplied with a value of 'all'. Specify "ppd-make" to get a list of manufacturers. + +
+ +

CUPS-Get-PPDs Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-PPDs Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: PPD Attributes + +

+ +
The set of requested attributes and their current values for each + PPD file. + +
+ +

CUPS 1.1CUPS-Move-Job Operation

+ +

The CUPS-Move-Job operation (0x400D) moves an active print job or all print +jobs for a printer to a different printer.

+ +

CUPS-Move-Job Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Move-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) +
OR +
"printer-uri" (uri) and "job-id" (integer) +
OR +
"job-uri": + +
The client MUST supply a URI for the specified printer, the URI for + the specified printer and a job ID number, or the job URI. + +
+ +

Group 2: Job Template Attributes + +

+ +
"job-printer-uri" (uri) + +
The client MUST supply a URI for a printer on the same server. + +
+ +

CUPS-Move-Job Response

+ +

The following groups of attributes are send as part of the +CUPS-Move-Job Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

CUPS 1.2/Mac OS X 10.5CUPS-Authenticate-Job Operation

+ +

The CUPS-Authenticate-Job operation (0x400E) authenticates a print job for +printing, releasing the job if it is held. Typically this is used when printing +to a remote server. The authentication information is passed in the HTTP +request; the HTTP connection is normally encrypted for this type of request.

+ +

CUPS-Authenticate-Job Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Authenticate-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) and "job-id" (integer) +
OR +
"job-uri": + +
The client MUST supply a URI for the specified printer and + a job ID number, or the job URI. + +
+ +

Group 2: Job Attributes + +

+ +
"auth-info" (1setOf text(MAX)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies one or more authentication values as specified by the "auth-info-required" attribute. + +
"job-hold-until" (keyword | name(MAX)):CUPS 1.3/Mac OS X 10.5 + +
The client OPTIONALLY supplies a new job-hold-until value for the + job. If specified and not the "no-hold" value, the job is held instead + of released for printing. + +
+ +

CUPS-Authenticate-Job Response

+ +

The following groups of attributes are send as part of the +CUPS-Authenticate-Job Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
+ +

Group 2: Unsupported Attributes (status=client-eror-attributes-or-values-not-supported) + +

+ +
auth-info-required (1setOf Type2 keyword) + +
The required authentication information. + +
+ +

CUPS 1.3/Mac OS X 10.5CUPS-Get-PPD Operation

+ +

The CUPS-Get-PPD operation (0x400F) gets a PPD file from the +server. The PPD file can be specified using a ppd-name +returned by CUPS-Get-PPDs +or using the printer-uri for a queue.

+ +

If the PPD file is found, successful-ok is returned with +the PPD file following the response data.

+ +

If the PPD file cannot be served by the local server because +the printer-uri attribute points to an external printer, +a cups-see-other status is returned with the correct +URI to use.

+ +

If the PPD file does not exist, client-error-not-found is +returned.

+ +

CUPS-Get-PPD Request

+ +

The following group of attributes is supplied as part of the +CUPS-Get-PPD 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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) +
OR +
"ppd-name" (name(255)): + +
The client MUST supply a printer URI or PPD name. + +
+ +

CUPS-Get-PPD Response

+ +

The following group of attributes is sent as part of the +CUPS-Get-PPD Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
"printer-uri" (uri): + +
The printer that provides the actual PPD file when + the status code is cups-see-other (0x280) + +
+ +

If the status code is successful-ok, the PPD file follows +the end of the IPP response.

+ +

CUPS 1.4/Mac OS X 10.6CUPS-Get-Document Operation

+ +

The CUPS-Get-Document operation (0x4027) gets a document file from a +job on the server. The document file is specified using the +document-number and either the job-uri or printer-uri +and job-id identifying the job.

+ +

If the document file is found, successful-ok is returned with +the document file following the response data.

+ +

If the document file does not exist, client-error-not-found is +returned.

+ +

If the requesting user does not have access to the document file, +client-error-not-authorized is returned. + +

CUPS-Get-Document Request

+ +

The following group of attributes is supplied as part of the +CUPS-Get-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 of the IPP Model and + Semantics document. + +
"printer-uri" (uri) and "job-id" (integer) +
OR +
"job-uri" (uri): + +
The client MUST supply a printer URI and job ID or job URI. + +
"document-number" (integer(1:MAX)): + +
The client MUST supply a document number to retrieve. The + document-count attribute for the job defines the maximum + document number that can be specified. In the case of jobs with + banners (job-sheets is not "none"), document number 1 + will typically contain the start banner and document number N + will typically contain the end banner. + +
+ +

CUPS-Get-Document Response

+ +

The following group of attributes is sent as part of the +CUPS-Get-Document Response: + +

Group 1: Operation Attributes + +

+ +
Status Message: + +
The standard response status message. + +
Natural Language and Character Set: + +
The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +
"document-format" (mimeType): + +
The format of the document file. + +
"document-number" (integer(1:MAX)): + +
The requested document number. + +
"document-name" (name(MAX)): + +
The name that was supplied with the document, if any. + +
+ +

If the status code is successful-ok, the document file follows +the end of the IPP response.

+ + +

Attributes

+ +

CUPS provides many extension attributes to support multiple +devices, PPD files, standard job filters, printers, and printer +classes.

+ +

Device Attributes

+ +

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.

+ +

device-class (type2 keyword)

+ +

The device-class attribute specifies the class of device and can be +one of the following: + +

    + +
  • "file" - a disk file. + +
  • "direct" - a parallel or fixed-rate serial data port, + currently used for Centronics, IEEE-1284, and USB printer + ports. + +
  • "serial" - a variable-rate serial port. + +
  • "network" - a network connection, typically via AppSocket, + HTTP, IPP, LPD, or SMB/CIFS protocols. + +
+ +

device-id (text(127))CUPS 1.2/Mac OS X 10.5

+ +

The device-id attribute specifies the IEEE-1284 device ID +string for the device.

+ +

device-info (text(127))

+ +

The device-info attribute specifies a human-readable string describing +the device, e.g. "Parallel Port #1". + +

device-location (text(127))CUPS 1.4/Mac OS X 10.6

+ +

The device-location attribute specifies the physical location of the +printer. + +

device-make-and-model (text(127))

+ +

The device-make-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". + +

device-uri (uri)

+ +

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: + +

    + +
  • "file" - The device-uri will be of the form + "file:///path/to/filename". + +
  • "direct" - The device-uri will be of the form + "scheme:/dev/filename" or "scheme://vendor/identifier", + where scheme may be "parallel" or "usb" in the current + implementation. + +
  • "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). + +

    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"). + +

  • "network" - The device-uri will be of the form + "scheme://[username:password@]hostname[:port]/[resource]", + where scheme may be "http", "https", "ipp", "lpd", "smb", or + "socket" in the current implementation. + +

    The URI returned by CUPS-Get-Devices will only contain + the scheme name ("scheme"). It is up to the client + application to add the appropriate host and other + information when adding a new printer. + +

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

+ +

Job Template Attributes

+ +

auth-info (1setOf text(MAX))CUPS 1.3/Mac OS X 10.5

+ +

The auth-info attribute specifies the authentication information to use when printing to a remote device. The order and content of each text value is specifed by the auth-info-required printer attribute. + +

blackplot (boolean)

+ +

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

brightness (integer(0:200))Deprecated

+ +

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

Brightness is applied to the Cyan, Magenta, Yellow, and Black values using +the function "f(x) = brightness / 100 * x". + +

Note: + +

This attribute is deprecated and will be removed from a future CUPS +release.

+ +
+ +

columns (integer(1:4)) Deprecated

+ +

The columns attribute specifies the number of columns to generate when +printing text files. The default value is 1. + +

cpi (type2 enum)

+ +

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

document-count (integer(1:MAX))

+ +

The document-count attribute specifies the number of documents that +are present in the job. + +

fit-to-page (boolean)CUPS 1.4/Mac OS X 10.6

+ +

The fit-to-page attribute specifies whether to scale documents to fit on the +selected media (fit-to-page=true) or use the physical size specified in the +document (fit-to-page=false). The default value is false. + +

fitplot (boolean)Deprecated

+ +

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

gamma (integer(1:10000))Deprecated

+ +

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

Gamma is applied to the Red, Green, and Blue values (or luminance for +grayscale output) using the function "f(x) = x(1000/gamma)". + +

Note: + +

This attribute is deprecated and will be removed from a future CUPS +release.

+ +
+ +

hue (integer(-180:180))Deprecated

+ +

The hue attribute specifies a color hue rotation when printing image +files. The default value is 0. + +

Note: + +

This attribute is deprecated and will be removed from a future CUPS +release.

+ +
+ +

job-billing (text(MAX))CUPS 1.1

+ +

The job-billing attribute provides a text value to associate with a job +for billing purposes. + +

job-hold-until (keyword | name(MAX))CUPS 1.1

+ +

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 +Universal Coordinated Time (UTC) and not in the local time zone. If the +specified time is less than the current time, the job is held until the +next day. + +

job-media-progress (integer(0:100))CUPS 1.4/Mac OS X 10.6

+ +

The job-media-progress attribute specifies the percentage of completion of +the current page. It is only valid when the job-state attribute has the +"processing" value (5).

+ +

job-printer-state-message (text(MAX))CUPS 1.3/Mac OS X 10.5

+ +

The job-printer-state-message attribute provides the last known value of the printer-state-message attribute for the printer that processed (or is processing) the job.

+ +

job-printer-state-reasons (1setOf type2 keyword)CUPS 1.3/Mac OS X 10.5

+ +

The job-printer-state-reasons attribute provides the last known value of the printer-state-reasons attribute for the printer that processed (or is processing) the job.

+ +

job-sheets (1setof type3 keyword | name(MAX))CUPS 1.1

+ +

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

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

job-originating-host-name (name(MAX))

+ +

(CUPS 1.1.5 and higher) + +

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 +always resolved to the name "localhost". + +

This attribute is read-only. + +

lpi (type2 enum)

+ +

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

mirror (boolean)

+ +

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

natural-scaling (integer(1:1000))CUPS 1.1.9

+

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

The ppi option can be used to override the natural resolution of the +image, which controls the natural size. + +

number-up-layout (type2 keyword)CUPS 1.1.15

+

The number-up-layout attribute specifies the order each input +page is placed on each output page. The following keywords are +presently defined: + +

    + +
  • btlr - Bottom to top, left to right
  • + +
  • btrl - Bottom to top, right to left
  • + +
  • lrbt - Left to right, bottom to top
  • + +
  • lrtb - Left to right, top to bottom (default)
  • + +
  • rlbt - Right to left, bottom to top
  • + +
  • rltb - Right to left, top to bottom
  • + +
  • tblr - Top to bottom, left to right
  • + +
  • tbrl - Top to bottom, right to left
  • + +
+ +

page-border (type2 keyword)CUPS 1.1.15

+

The page-border attribute specifies whether a border is +draw around each page. The following keywords are presently +defined: + +

    + +
  • double - Two hairline borders are drawn
  • + +
  • double-thick - Two 1pt borders are drawn
  • + +
  • none - No border is drawn (default)
  • + +
  • single - A single hairline border is drawn
  • + +
  • single-thick - A single 1pt border is drawn
  • + +
+ +

page-bottom (integer(0:MAX))

+ +

The page-bottom attribute specifies the bottom margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

page-label (text(MAX))CUPS 1.1.7

+

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

page-left (integer(0:MAX))

+ +

The page-left attribute specifies the left margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

page-right (integer(0:MAX))

+ +

The page-right attribute specifies the right margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

page-set (type2 keyword)

+ +

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". + +

page-top (integer(0:MAX))

+ +

The page-top attribute specifies the top margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

penwidth (integer(0:MAX))

+ +

The penwidth attribute specifies the default pen width in micrometers +when printing HP-GL/2 plot files. The default value is 1000 (1 millimeter). + +

position (type2 keyword)

+ +

The position attribute specifies the location of image files on the +media. The following keyword values are recognized: + +

    + +
  • center - Center the image on the page (default) + +
  • top - Print the image centered at the top of the page + +
  • left - Print the image centered on the left of page + +
  • right - Print the image centered on the right of the page + +
  • top-left - Print the image at the top left corner of + the page + +
  • top-right - Print the image at the top right corner of + the page + +
  • bottom - Print the image centered at the bottom of + the page + +
  • bottom-left - Print the image at the bottom left + corner of the page + +
  • bottom-right - Print the image at the bottom right + corner of the page + +
+ +

ppi (integer(1:MAX))

+ +

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

prettyprint (boolean)

+ +

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

saturation (integer(0:200))Deprecated

+ +

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

Note: + +

This attribute is deprecated and will be removed from a future CUPS +release.

+ +
+ +

scaling (integer(1:1000))

+ +

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

The scaling attribute overrides the ppi attribute if specified. + +

wrap (boolean)

+ +

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

PPD Attributes

+ +

ppd-device-id (text(127))

+ +

The ppd-device-id attribute specifies the IEEE-1284 device ID +string for the device described by the PPD file.

+ +

ppd-make (text(127))

+ +

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

ppd-make-and-model (text(127))

+ +

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

ppd-model-number (integer)CUPS 1.3/Mac OS X 10.5

+ +

The ppd-model-number attribute provides the cupsModelNumber value from the PPD file. + +

ppd-name (name(255))

+ +

The ppd-name attribute specifies either the PPD filename on the server relative to the model directory or a URI that maps to a specific driver interface in the driver directory. The forward slash (/) is used to delineate directories. + +

ppd-natural-language (1setOf naturalLanguage)

+ +

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

ppd-product (1setOf text(127))

+ +

The ppd-product attribute specifies the Product attribute values in the PPD file. + +

ppd-psversion (1setOf text(127))CUPS 1.3/Mac OS X 10.5

+ +

The ppd-product attribute specifies the PSVersion attribute values in the PPD file. + +

ppd-type (type1 keyword)CUPS 1.3/Mac OS X 10.5

+ +

The ppd-type attribute specifies the type of driver described by the PPD file:

+ +
    + +
  • fax - A facsimile or multi-function device
  • + +
  • pdf - A PDF printer
  • + +
  • postscript - A PostScript printer (no filters)
  • + +
  • raster - A CUPS raster driver
  • + +
  • unknown - An unknown or hybrid driver
  • + +
+ + +

Printer Attributes

+ +

auth-info-required (1setOf type2 keyword)CUPS 1.3/Mac OS X 10.5

+ +

The auth-info-required attribute specifies the authentication information that is required for printing a job. The following keywords are recognized:

+ +
    + +
  • domain - A domain name is required.
  • + +
  • none - No authentication is required - this keyword can only appear by itself.
  • + +
  • password - A password is required.
  • + +
  • username - A username is required.
  • + +
+ +

job-k-limit (integer)CUPS 1.1

+ +

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

job-page-limit (integer)CUPS 1.1

+ +

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

job-quota-period (integer)CUPS 1.1

+ +

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

job-sheets-supported (1setof type3 keyword | name(MAX))CUPS 1.1

+ +

The job-sheets-supported attribute specifies the available banner files. +There will always be at least one banner file available called "none". + +

marker-change-time (integer)CUPS 1.3/Mac OS X 10.5

+ +

The marker-change-time attribute specifies the printer-up-time value when +the last change to the marker-colors, marker-levels, marker-message, +marker-names, or marker-types attributes was made.

+ +

marker-colors (1setof name(MAX))CUPS 1.3/Mac OS X 10.5

+ +

The marker-colors attribute specifies the color(s) for each supply in the +printer. It is only available when the driver provides supply levels. The +color is either "none" or one or more hex-encoded sRGB colors of the form +"#RRGGBB".

+ +

marker-high-levels (1setof integer(0:100))CUPS 1.4/Mac OS X 10.6

+ +

The marker-high-levels attribute specifies the supply levels that indicate +a near-full condition. A value of 100 should be used for supplies that are +consumed/emptied, e.g. ink cartridges.

+ +

marker-levels (1setof integer(-3:100))CUPS 1.3/Mac OS X 10.5

+ +

The marker-levels attribute specifies the current supply levels for the +printer. It is only available when the driver provides supply levels. A +value of -1 indicates the level is unavailable, -2 indicates unknown, and -3 +indicates the level is unknown but has not yet reached capacity. Values from 0 +to 100 indicate the corresponding percentage.

+ +

marker-low-levels (1setof integer(0:100))CUPS 1.4/Mac OS X 10.6

+ +

The marker-low-levels attribute specifies the supply levels that indicate +a near-empty condition. A value of 0 should be used for supplies that are +filled, e.g. waste ink tanks.

+ +

marker-message (text(MAX))CUPS 1.4/Mac OS X 10.6

+ +

The marker-message attribute provides a human-readable status message +for the current supply levels, e.g. "12 pages of ink remaining." It is only +available when the driver provides supply levels.

+ +

marker-names (1setof name(MAX))CUPS 1.3/Mac OS X 10.5

+ +

The marker-names attribute specifies the name(s) for each supply in the +printer. It is only available when the driver provides supply levels.

+ +

marker-types (1setof type3 keyword)CUPS 1.3/Mac OS X 10.5

+ +

The marker-types attribute specifies the type(s) of each supply in the +printer. It is only available when the driver provides supply levels. The +following (RFC 3805) types are currently supported:

+ +
    + +
  • toner
  • + +
  • wasteToner
  • + +
  • ink
  • + +
  • inkCartridge
  • + +
  • inkRibbon
  • + +
  • wasteInk
  • + +
  • opc
  • + +
  • developer
  • + +
  • fuserOil
  • + +
  • solidWax
  • + +
  • ribbonWax
  • + +
  • wasteWax
  • + +
  • fuser
  • + +
  • coronaWire
  • + +
  • fuserOilWick
  • + +
  • cleanerUnit
  • + +
  • fuserCleaningPad
  • + +
  • transferUnit
  • + +
  • tonerCartridge
  • + +
  • fuserOiler
  • + +
  • water
  • + +
  • wasteWater
  • + +
  • bindingSupply
  • + +
  • bandingSupply
  • + +
  • stichingWire
  • + +
  • shrinkWrap
  • + +
  • paperWrap
  • + +
  • staples
  • + +
  • inserts
  • + +
  • covers
  • + +
+ +

port-monitor" (name(127))

+ +

The port-monitor attribute specifies the port monitor to use when printing +to this printer. The default port monitor is "none". + +

port-monitor-supported" (1setOf name(127))

+ +

The port-monitor-supported attribute specifies the available port monitors. + +

printer-commands (1setOf Type3 keyword)CUPS 1.4/Mac OS X 10.6

+ +

The printer-commands attribute specifies the commands that are supported +by the CUPS command file filter. The keyword "none" indicates that no commands +are supported.

+ +

printer-dns-sd-name (name(MAX) | noValue)CUPS 1.4/Mac OS X 10.6

+ +

The printer-dns-sd-name attribute specifies the registered DNS-SD service +name for the printer. If the printer is not being shared using this protocol, +printer-dns-sd-name will have the noValue value.

+ +

printer-state-reasons (1setOf type2 keyword)

+ +

The printer-state-reasons attribute provides additional persistent state +information for a printer. In addition to the keywords defined in RFC 2911, +CUPS supports vendor-specific keywords with a domain prefix ("com.vendor.foo") +and the following CUPS-specific keywords:

+ +
    + +
  • cups-insecure-filter-warning - a filter or backend (or the + directory containing the filter or backend) has insecure file + permissions. CUPS will not execute programs with world write permissions + or setuid programs. When run as root (the default), CUPS also does not + execute programs that are not owned by root. + CUPS 1.4/Mac OS X 10.6
  • + +
  • cups-missing-filter-warning - a filter or backend is not + installed. CUPS 1.4/Mac OS X 10.6
  • + +
+ +

printer-type (type2 enum)

+ +

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:

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitDescription
0x00000001Is a printer class.
0x00000002Is a remote destination.
0x00000004Can print in black.
0x00000008Can print in color.
0x00000010Can print on both sides of the page in hardware.
0x00000020Can staple output.
0x00000040Can do fast copies in hardware.
0x00000080Can do fast copy collation in hardware.
0x00000100Can punch output.
0x00000200Can cover output.
0x00000400Can bind output.
0x00000800Can sort output.
0x00001000Can handle media up to US-Legal/A4.
0x00002000Can handle media from US-Legal/A4 to ISO-C/A2.
0x00004000Can handle media larger than ISO-C/A2.
0x00008000Can handle user-defined media sizes.
0x00010000Is an implicit (server-generated) class.
0x00020000Is the a default printer on the network.
0x00040000Is a facsimile device.
0x00080000Is rejecting jobs.
0x00100000Delete this queue.
0x00200000Queue is not shared.
0x00400000Queue requires authentication.
0x00800000Queue supports CUPS command files.
0x01000000Queue was automatically discovered and added.
0x02000000Queue is a scanner with no printing capabilities.
0x04000000Queue is a printer with scanning capabilities.
+ +

printer-type-mask (type2 enum)CUPS 1.1

+ +

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

requesting-user-name-allowed (1setof name(127))CUPS 1.1

+ +

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

requesting-user-name-denied (1setof name(127))CUPS 1.1

+ +

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

Printer Class Attributes

+ +

member-names (1setof name(127))

+ +

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

member-uris (1setof uri)

+ +

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. + + + diff --git a/doc/help/spec-pdf.html b/doc/help/spec-pdf.html new file mode 100644 index 0000000000..407f47887f --- /dev/null +++ b/doc/help/spec-pdf.html @@ -0,0 +1,24 @@ + + + + + CUPS PDF Format + + + + +

CUPS PDF Format

+ +

CUPS PDF files (application/vnd.cups-pdf) are device-dependent +PDF/A files that contain a job ticket information. These files +are typically produced by the CUPS pdftopdf filter +which handles job ticket generation, imposition, page labeling, +scaling, and other formatting options requested by the user. CUPS +PDF files are intended for direct consumption by a PDF-capable +printer, PDF RIP, or the pdftops filter.

+ +

More information will be posted here as the PDF workflow +filters are added to CUPS.

+ + + diff --git a/doc/help/spec-postscript.html b/doc/help/spec-postscript.html new file mode 100644 index 0000000000..3bff7fbd6e --- /dev/null +++ b/doc/help/spec-postscript.html @@ -0,0 +1,148 @@ + + + + + Generating PostScript for CUPS + + + + + + +

Generating PostScript for CUPS

+ +

Introduction

+ +

This document describes how to generate PostScript output for +CUPS and is largely based on the +Adobe TechNote #5001: PostScript Language Document Structuring +Conventions Specification Version 3.0. While CUPS can +generally print any PostScript file, following the rules in the +Adobe TechNote and this document will ensure that your PostScript +output will work reliably.

+ +
Note: While PostScript is currently the +de-facto standard print job file format/language for UNIX-based +applications, it is slowly being phased out in favor of Adobe's +Portable Document Format ("PDF") which offers many advantages +over PostScript. Mac OS X uses PDF as the primary print job file +format and Linux is making the transition. Both PostScript and +PDF are complex formats, and we highly recommend using high-level +toolkits whenever possible to create your print jobs.
+ +

Anatomy of a PostScript File

+ +

PostScript files are ASCII text files starting with a header +line (%!PS-Adobe-3.0) followed by a combination of +comment lines starting with the percent sign (%) and +PostScript code lines. The lines themselves should not exceed 255 +characters to conform to the DSC. The following short PostScript +file produces a box with a smiley face in it:

+ +
+%!PS-Adobe-3.0
+%%BoundingBox: 36 36 576 756
+%%Pages: 1
+%%LanguageLevel: 2
+%%EndComments
+%%BeginSetup
+% this is where fonts would be embedded
+%%EndSetup
+%%Page: (1) 1
+%%BeginPageSetup
+% this is where page-specific features would be specified
+%%EndPageSetup
+% Draw a black box around the page
+0 setgray
+1 setlinewidth
+36 36 540 720 rectstroke
+
+% Draw a two inch blue circle in the middle of the page
+0 0 1 setrgbcolor
+306 396 144 0 360 arc closepath fill
+
+% Draw two half inch yellow circles for eyes
+1 1 0 setrgbcolor
+252 432 36 0 360 arc closepath fill
+360 432 36 0 360 arc closepath fill
+
+% Draw the smile
+1 setlinecap
+18 setlinewidth
+306 396 99 200 340 arc stroke
+
+% Print it!
+showpage
+%%EOF
+
+ + + + +

Embedding Printer Options

+ +

There are two main strategies for embedding printer options in PostScript +files. The first is to list CUPS options using the %cupsJobTicket +comment:

+ +
+%!PS-Adobe-3.0
+%cupsJobTicket: media=A4 sides=two-sided-long-edge
+%cupsJobTicket: PrinterOption=foo PrinterOption2=bar
+...
+%%EndComments
+
+ +

CUPS options apply to the entire job. To apply options to individual pages, +use the %%IncludeFeature comment instead:

+ +
+%%Page: label 123
+%%BeginPageSetup
+%%IncludeFeature: *PageSize A4
+%%IncludeFeature: *PrinterOption Foo
+%%IncludeFeature: *PrinterOption2 Bar
+%%EndPageSetup
+...
+
+ + +

Embedding Fonts and Text

+ +

Always embed the fonts used by your print job, and for best performance +embed the fonts and character encodings in the setup section of the PostScript +file. Type 1 and Type 3 fonts are supported by all PostScript printers, while +Type 42 (TrueType) and CID fonts are supported by most level 2 and all level 3 +PostScript printers. Binary font files should always be converted to the +corresponding ASCII (hex) encoding to avoid problems when printing over +interfaces that do not support binary PostScript.

+ + +

Embedding Images

+ +

The image operator should be used to embed images in PostScript +files. Always use ASCII hex or Base-85 encoding for the image data to avoid +problems when printing over interfaces that do not support binary PostScript. +In most cases, the Base-85 encoding and compression filters can be used to +embed images with very little, if any, increase in data size.

+ + + diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html new file mode 100644 index 0000000000..1acd847da4 --- /dev/null +++ b/doc/help/spec-ppd.html @@ -0,0 +1,2036 @@ + + + + + CUPS PPD Extensions + + + + + + +

CUPS PPD Extensions

+ +

Introduction

+ +

This specification describes the attributes and extensions +that CUPS adds to +Adobe TechNote #5003: PostScript Printer Description File Format +Specification Version 4.3. PostScript Printer Description +("PPD") files describe the capabilities of each printer and are +used by CUPS to support printer-specific features and intelligent +filtering.

+ +

PPD File Syntax

+ +

The PPD format is text-based and uses lines of up to 255 +characters terminated by a carriage return, linefeed, or +combination of carriage return and line feed. The following ABNF +definition [RFC4234] defines the general format of lines in a PPD +file:

+ +
+PPD-FILE = HEADER +(DATA / COMMENT / LINE-END)
+
+HEADER   = "*PPD-Adobe:" *WSP DQUOTE VERSION DQUOTE LINE-END
+
+VERSION  = "4.0" / "4.1" / "4.2" / "4.3"
+
+COMMENT  = "*%" *TCHAR LINE-END
+
+DATA     = "*" 1*KCHAR [ WSP 1*KCHAR [ "/" 1*TCHAR ] ] ":"
+           1*(*WSP VALUE) LINE-END
+
+VALUE    = 1*TCHAR / DQUOTE 1*SCHAR DQUOTE
+
+KCHAR    = ALPHA / DIGIT / "_" / "." / "-"
+
+SCHAR    = LINE-END / WSP / %x21.23-7E.A0-FF
+
+TCHAR    = %x20-7E.A0-FF
+
+LINE-END = CR / LF / CR LF
+
+ + +

Auto-Configuration

+ +

CUPS supports several methods of auto-configuration via PPD attributes. +Currently these methods are only implemented on Mac OS X.

+ +

Mac OS X 10.5APAutoSetupTool

+ +

*APAutoSetupTool: "/LibraryPrinters/vendor/filename"

+ +

This attribute defines a program that sets the default option choices. It +is run when a printer is added from the printer browser instead of the +normal PostScript query and SNMP OID attribute lookups.

+ +

The program is provided with two arguments: the printer's device URI and +the PPD file to be used for the printer. The program must write an updated +PPD file to stdout.

+ +

Examples:

+ +
+*% Use our setup tool when adding a printer
+*APAutoSetupTool: "/Library/Printers/vendor/Tools/autosetuptool"
+
+ +

Mac OS X 10.2?MainKeyword

+ +

*?MainKeyword: "
+ PostScript query code that writes a message using the = operator...
+"
+*End

+ +

The ?MainKeyword attribute defines PostScript code that +determines the currently selected/enabled option keyword (choice) for the +main keyword (option). It is typically used when communicating with USB, +serial, Appletalk, and AppSocket (port 9100) printers.

+ +

The PostScript code typically sends its response back using the = +operator.

+ +

Example:

+ +
+*OpenUI OptionDuplex/Duplexer Installed: Boolean
+*DuplexOptionDuplex: False
+*OptionDuplex False/Not Installed: ""
+*OptionDuplex True/Installed: ""
+
+*% Query the printer for the presence of the duplexer option...
+*?OptionDuplex: "
+  currentpagedevice /Duplex known
+  {(True)} {(False)} ifelse
+  = flush
+"
+*End
+*CloseUI: OptionDuplex
+
+ +

Mac OS X 10.4OIDMainKeyword

+ +

*?OIDMainKeyword: ".n.n.n..."
+*OIDMainKeyword OptionKeyword1: "value"
+...
+*OIDMainKeyword OptionKeywordN: "value"

+ +

The OIDMainKeyword attribute is used to define +SNMP OIDs that map to installable options. The first (query) line +defines the OID to lookup on the network device. The second and +subsequent attributes define a mapping from OID value to option +keyword. Since SNMP is an IP-based network protocol, this method +is typically only used to configure AppSocket, IPP, and LPD network +printers.

+ +

Examples:

+ +
+*% Get the installed memory on the printer...
+*?OIDInstalledMemory: ".1.3.6.1.2.1.25.2.2.0"
+*OIDInstalledMemory 16MB: "16384 KBytes"
+*OIDInstalledMemory 32MB: "32768 KBytes"
+*OIDInstalledMemory 48MB: "49152 KBytes"
+*OIDInstalledMemory 72MB: "73728 KBytes"
+
+ + +

Color Profiles

+ +

CUPS supports three types of color profiles. The first type is +based on sRGB and is used by the standard CUPS raster filters and +GPL Ghostscript. The second type is based on ICC profiles and is +used by the Quartz-based filters on MacOS X. The final type is +based on well-known colorspaces such as sRGB and Adobe RGB.

+ +
Note: + +

At this time, none of the CUPS raster filters support ICC profiles. This +will be addressed as time and resources permit.

+ +
+ +

DeprecatedcupsColorProfile

+ +

*cupsColorProfile Resolution/MediaType: "density +gamma m00 m01 m02 m10 m11 m12 m20 m21 m22"

+ +

This string attribute specifies an sRGB-based color profile +consisting of gamma and density controls and a 3x3 CMY color +transform matrix. This attribute is not supported on Mac OS X.

+ +

The Resolution and MediaType values may be "-" +to act as a wildcard. Otherwise they must match one of the +Resolution or MediaType attributes defined in +the PPD file.

+ +

The density and gamma values define gamma and +density adjustment function such that:

+ +
+f(x) = density * x gamma
+
+ +

The m00 through m22 values define a 3x3 +transformation matrix for the CMY color values. The density +function is applied after the CMY transformation:

+ +
+| m00 m01 m02 |
+| m10 m11 m12 |
+| m20 m21 m22 |
+
+ +

Examples:

+ +
+*% Specify a profile for printing at 360dpi on all media types 
+*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+
+*% Specify a profile for printing at 720dpi on Glossy media 
+*cupsColorProfile 720dpi/Glossy: "1.0 2.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+
+*% Specify a default profile for printing at all other resolutions and media types 
+*cupsColorProfile -/-: "0.9 2.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0"
+
+ + +

Mac OS X 10.3/CUPS 1.2/Mac OS X 10.5cupsICCProfile

+ +

*cupsICCProfile +ColorModel.MediaType.Resolution/Description: "filename"

+ +

This attribute specifies an ICC color profile that is +used to convert the document colors to the device +colorspace. The ColorModel, MediaType, and +Resolution keywords specify a selector for color +profiles. If omitted, the color profile will match any option +keyword for the corresponding main keyword.

+ +

The Description specifies human-readable text that +is associated with the color profile. The filename +portion specifies the ICC color profile to use; if the filename +is not absolute, it is loaded relative to the +/usr/share/cups/profiles directory.

+ +

Examples:

+ +
+*% Specify a profile for CMYK printing at 360dpi on all media types 
+*cupsICCProfile CMYK..360dpi/360dpi CMYK: "/Library/Printers/vendor/Profiles/foo-360-cmyk.icc"
+
+*% Specify a profile for RGB printing at 720dpi on Glossy media 
+*cupsColorProfile RGB.Glossy.720dpi/720dpi Glossy: "/Library/Printers/vendor/Profiles/foo-720-glossy-rgb.icc"
+
+*% Specify a default profile for printing at all other resolutions and media types 
+*cupsICCProfile ../Default: "/Library/Printers/vendor/Profiles/foo-default.icc"
+
+ +

Customizing the Profile Selection Keywords

+ +

The MediaType and Resolution keywords can be +reassigned to different main keywords, allowing drivers to do +color profile selection based on different parameters. The +cupsICCQualifier2 and cupsICCQualifier3 +attributes define the mapping from selector to main keyword:

+ +
+*cupsICCQualifier2: MainKeyword2
+*cupsICCQualifier3: MainKeyword3
+
+ +

The default mapping is as follows:

+ +
+*cupsICCQualifier2: MediaType
+*cupsICCQualifier3: Resolution
+
+ +

Mac OS X 10.4Custom Color Matching Support

+ +

*APSupportsCustomColorMatching: true
+*APCustomColorMatchingName name/text: ""
+*APCustomColorMatchingProfile: profile
+*APDefaultCustomColorMatchingProfile: profile

+ +

These attributes tell the Mac OS X raster filters that the printer +driver provides its own custom color matching and that generic color +profiles should be used when generating 1-, 3-, and 4-component raster +data as requested by the driver. The APCustomColorMatchingProfile +and APDefaultColorMatchingProfile attributes specify alternate +color profiles (sRGB or AdobeRGB) to use for 3-color (RGB) raster data.

+ +
Note: + +

Prior to Mac OS X 10.6, the default RGB color space was Apple's "GenericRGB". +The new default in Mac OS X 10.6 and later is "sRGB". For more information, see +"Mac OS X v10.6: About gamma +2.2" on Apple's support site.

+ +
+ +

Mac OS X 10.5APCustomColorMatchingName

+ +

*APCustomColorMatchingName name/text: ""

+ +

This attribute defines an alternate name for the color matching +provided by a driver in the Color Matching print panel. +The default is to use the name "Vendor Matching" or its localized +equivalent.

+ +

Examples:

+ +
+*% Define the names for our color matching...
+*APCustomColorMatchingName name/AcmeColor(tm): ""
+*fr.APCustomColorMatchingName name/La AcmeColor(tm): ""
+
+ +

Mac OS X 10.5APCustomColorMatchingProfile

+ +

*APCustomColorMatchingProfile: name

+ +

This attribute defines a supported RGB color profile that can be used +when doing custom color matching. Currently only sRGB, +AdobeRGB, and GenericRGB are supported. If not specified, RGB +data will use the GenericRGB colorspace.

+ +
Note: + +

If you provide multiple APCustomColorMatchingProfile attributes, +you are responsible for providing the necessary user interface controls to +select the profile in a print dialog pane. +Add the named profile to the print settings using the key +kPMCustomColorMatchingProfileKey.

+ +
+ +

Examples:

+ +
+*% Use sRGB for RGB color by default, but support both sRGB and AdobeRGB
+*APSupportsCustomColorMatching: true
+*APDefaultCustomColorMatchingProfile: sRGB
+*APCustomColorMatchingProfile: sRGB
+*APCustomColorMatchingProfile: AdobeRGB
+
+ +

Mac OS X 10.5APDefaultCustomColorMatchingProfile

+ +

*APDefaultCustomColorMatchingProfile: name

+ +

This attribute defines the default RGB color profile that will be used +when doing custom color matching. Currently only sRGB, +AdobeRGB, and GenericRGB are supported.

+ +

Examples:

+ +
+*% Use sRGB for RGB color by default
+*APSupportsCustomColorMatching: true
+*APDefaultCustomColorMatchingProfile: sRGB
+
+ +

Mac OS X 10.4APSupportsCustomColorMatching

+ +

*APSupportsCustomColorMatching: boolean

+ +

This attribute specifies that the driver provides its own custom color +matching. When true, the default hand-off colorspace will be +GenericGray, GenericRGB, or GenericCMYK depending on the number of +components the driver requests. The APDefaultCustomColorMatchingProfile +attribute can be used to override the default 3-component (RGB) colorspace.

+ +

The default for APSupportsCustomColorMatching is false.

+ +

Examples:

+ +
+*APSupportsCustomColorMatching: true
+*APDefaultCustomColorMatchingProfile: sRGB
+
+ + +

Constraints

+ +

Constraints are option choices that are not allowed by the driver or +device, for example printing 2-sided transparencies. All versions of CUPS +support constraints defined by the legacy Adobe UIConstraints and +NonUIConstraints attributes which support conflicts between any two +option choices, for example:

+ +
+*% Do not allow 2-sided printing on transparency media
+*UIConstraints: "*Duplex *MediaType Transparency"
+*UIConstraints: "*MediaType Transparency *Duplex"
+
+ +

While nearly all constraints can be expressed using these attributes, there +are valid scenarios requiring constraints between more than two option choices. +In addition, resolution of constraints is problematic since users and software +have to guess how a particular constraint is best resolved.

+ +

CUPS 1.4 and higher define two new attributes for constraints, +cupsUIConstraints and cupsUIResolver. Each +cupsUIConstraints attribute points to a cupsUIResolver +attribute which specifies alternate options that resolve the conflict condition. +The same cupsUIResolver can be used by multiple +cupsUIConstraints.

+ +
Note: + +

When developing PPD files that contain constraints, it is very important + to use the cupstestppd(1) program to + verify that your constraints are accurate and cannot result in unresolvable + option selections.

+ +
+ +

CUPS 1.4/Mac OS X 10.6cupsUIConstraints

+ +

*cupsUIConstraints resolver: "*Keyword1 *Keyword2 ..."
+*cupsUIConstraints resolver: "*Keyword1 OptionKeyword1 *Keyword2 ..."
+*cupsUIConstraints resolver: "*Keyword1 *Keyword2 OptionKeyword2 ..."
+*cupsUIConstraints resolver: "*Keyword1 OptionKeyword1 *Keyword2 OptionKeyword2 ..."
+*cupsUIConstraints: "*InstallableKeyword1 OptionKeyword1 *Keyword2 OptionKeyword2 ..."

+ +

Lists two or more options which conflict. The "resolver" string is a +(possibly unique) keyword which specifies which options to change when the +constraint exists. When no resolver is provided, CUPS first tries the default +choice followed by testing each option choice to resolve the conflict.

+ +

Examples:

+ +
+*% Specify that 2-sided printing cannot happen on transparencies 
+*cupsUIConstraints transparency: "*Duplex *MediaType Transparency"
+
+*% Specify that envelope printing cannot happen from the paper trays 
+*cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
+*cupsUIConstraints envelope: "*PageSize Env10 *InputSlot Tray1"
+*cupsUIConstraints envelope: "*PageSize EnvDL *InputSlot Tray2"
+*cupsUIConstraints envelope: "*PageSize EnvDL *InputSlot Tray2"
+
+*% Specify an installable option constraint for the envelope feeder
+*cupsUIConstraints: "*InputSlot EnvFeeder *InstalledEnvFeeder"
+
+*% Specify that photo printing cannot happen on plain paper or transparencies at 1200dpi 
+*cupsUIConstraints photo: "*OutputMode Photo *MediaType Plain *Resolution 1200dpi"
+*cupsUIConstraints photo: "*OutputMode Photo *MediaType Transparency *Resolution 1200dpi"
+
+ +

CUPS 1.4/Mac OS X 10.6cupsUIResolver

+ +

*cupsUIResolver resolver: "*Keyword1 OptionKeyword1 *Keyword2 OptionKeyword2 ..."

+ +

Specifies two or more options to mark/select to resolve a constraint. The +"resolver" string identifies a particular action to take for one or more +cupsUIConstraints. The same action +can be used for multiple constraints. The option keyword pairs are treated as +an ordered list of option selections to try - only the first N selections will +be used, where N is the minimum number of selections required. Because +cupsResolveConflicts() +will not change the most recent option selection passed to it, at least two +options from the constraints must be listed to avoid situations where conflicts +cannot be resolved.

+ +

Examples:

+ +
+*% Specify the options to change for the 2-sided transparency constraint 
+*cupsUIResolver transparency: "*Duplex None *MediaType Plain"
+
+*% Specify the options to change for the envelope printing constraints.  Notice
+*% that we try to change the InputSlot to either the envelope feeder or the
+*% manual feed first, then we change the page size...
+*cupsUIResolver envelope: "*InputSlot EnvFeeder *InputSlot ManualFeed *PageSize Letter"
+
+*% Specify the options to change for the photo printing constraints 
+*cupsUIResolver photo: "*OutputMode Best *Resolution 600dpi"
+
+ + +

Globalized PPD Support

+ +

CUPS 1.2 and higher adds support for PPD files containing multiple +languages by following the following additional rules:

+ +
    + +
  1. The LanguageVersion MUST be English
  2. + +
  3. The LanguageEncoding MUST be ISOLatin1
  4. + +
  5. The cupsLanguages attribute MUST be provided and + list each of the supported locales in the PPD file
  6. + +
  7. Main and option keywords MUST NOT exceed 34 (instead of 40) + characters to allow room for the locale prefixes in translation + attributes
  8. + +
  9. The main keyword "Translation" MUST NOT be used
  10. + +
  11. Translation strings included with the main and option + keywords MUST NOT contain characters outside the ASCII + subset of ISOLatin1 and UTF-8; developers wishing to use + characters outside ASCII MUST provide a separate set of + English localization attributes for the affected keywords.
  12. + +
  13. Localizations are specified using a locale prefix of + the form "ll" or "ll_CC." where "ll" is the 2-letter ISO + language code and "CC" is the 2-letter ISO country + code
      +
    • A generic language translation ("ll") SHOULD be provided with country-specific differences ("ll_CC") provided only as needed
    • +
    • For historical reasons, the "zh" and "zh_CN" locales map to Simplified Chinese while the "zh_TW" locale maps to Traditional Chinese
    • +
  14. + +
  15. Locale-specific translation strings MUST be encoded + using UTF-8.
  16. + +
  17. Main keywords MUST be localized using one of the + following forms: +

    *ll.Translation MainKeyword/translation + text: ""
    + *ll_CC.Translation MainKeyword/translation + text: ""

  18. + +
  19. Option keywords MUST be localized using one of the + following forms: +

    *ll.MainKeyword OptionKeyword/translation + text: ""
    + *ll_CC.MainKeyword OptionKeyword/translation + text: ""

  20. + +
  21. Localization attributes MAY appear anywhere after the + first line of the PPD file
  22. + +
+ +
Note: + +

We use a LanguageEncoding value of ISOLatin1 +and limit the allowed base translation strings to ASCII to avoid +character coding issues that would otherwise occur. In addition, +requiring the base translation strings to be in English allows +for easier fallback translation when no localization is provided +in the PPD file for a given locale.

+ +
+ +

Examples:

+ +
+*LanguageVersion: English
+*LanguageEncoding: ISOLatin1
+*cupsLanguages: "de fr_CA"
+*ModelName: "Foobar Laser 9999"
+
+*% Localize ModelName for French and German
+*fr_CA.Translation ModelName/La Foobar Laser 9999: ""
+*de.Translation ModelName/Foobar LaserDrucken 9999: ""
+
+*cupsIPPReason com.vendor-error/A serious error occurred: "/help/com.vendor/error.html"
+*% Localize printer-state-reason for French and German
+*fr_CA.cupsIPPReason com.vendor-error/Une erreur sèrieuse s'est produite: "/help/com.vendor/error.html"
+*de.cupsIPPReason com.vendor-error/Eine ernste Störung trat: "/help/com.vendor/error.html"
+
+...
+
+*OpenUI *InputSlot/Paper Source: PickOne
+*OrderDependency: 10 AnySetup *InputSlot
+*DefaultInputSlot: Auto
+*% Localize InputSlot for French and German
+*fr_CA.Translation InputSlot/Papier source: ""
+*de.Translation InputSlot/Papiereinzug: ""
+*InputSlot Auto/Default: "<</ManualFeed false>>setpagedevice"
+*% Localize InputSlot=Auto for French and German
+*fr_CA.InputSlot Auto/Par Defaut: ""
+*de.InputSlot Auto/Standard: ""
+*InputSlot Manual/Manual Feed: "<</ManualFeed true>>setpagedevice"
+*% Localize InputSlot=Manual for French and German
+*fr_CA.InputSlot Manual/Manuel mecanisme de alimentation: ""
+*de.InputSlot Manual/Manueller Einzug: ""
+*CloseUI: *InputSlot
+
+ + +

Custom Options

+ +

CUPS supports custom options using an extension of the +CustomPageSize and ParamCustomPageSize +syntax:

+ +
+*CustomFoo True: "command"
+*ParamCustomFoo Name1/Text 1: order type minimum maximum
+*ParamCustomFoo Name2/Text 2: order type minimum maximum
+...
+*ParamCustomFoo NameN/Text N: order type minimum maximum
+
+ +

When the base option is part of the JCLSetup section, +the "command" string contains JCL commands with "\order" +placeholders for each numbered parameter. The CUPS API handles +any necessary value quoting for HP-PJL commands. For example, if +the JCL command string is "@PJL SET PASSCODE=\1" and the first +option value is "1234" then CUPS will output the string +"@PJL SET PASSCODE=1234".

+ +

For non-JCLSetup options, the "order" value is a +number from 1 to N and specifies the order of values as they are +placed on the stack before the command. For example, if the +PostScript command string is +"<</cupsReal1 2 1 roll>>setpagedevice" and the +option value is "2.0" then CUPS will output the string +"2.0 <</cupsReal1 2 1 roll>>setpagedevice".

+ +

The "type" is one of the following keywords:

+ +
    + +
  • curve - a real value from "minimum" to + "maximum" representing a gamma correction curve using the + function: f(x) = x value
  • + +
  • int - an integer value from "minimum" to + "maximum"
  • + +
  • invcurve - a real value from "minimum" to + "maximum" representing a gamma correction curve using the + function: f(x) = x 1 / value
  • + +
  • passcode - a string of numbers value with a + minimum of "minimum" numbers and a maximum of "maximum" + numbers ("minimum" and "maximum" are numbers and passcode + strings are not displayed in the user interface)
  • + +
  • password - a string value with a minimum of + "minimum" characters and a maximum of "maximum" + characters ("minimum" and "maximum" are numbers and password + strings are not displayed in the user interface)
  • + +
  • points - a measurement value in points from + "minimum" to "maximum"
  • + +
  • real - a real value from "minimum" to + "maximum"
  • + +
  • string - a string value with a minimum of + "minimum" characters and a maximum of "maximum" + characters ("minimum" and "maximum" are numbers)
  • + +
+ +
Note: + +

Custom options are not directly supported by the Mac OS X Print Dialog +nor by the CUPS web interface at this time. Vendors that use custom +options on Mac OS X must provide their own user interface via the +APDialogExtension attribute.

+ +
+ +

Examples:

+ +
+*% Base JCL key code option 
+*JCLOpenUI JCLPasscode/Key Code: PickOne
+*OrderDependency: 10 JCLSetup *JCLPasscode
+*DefaultJCLPasscode: None
+*JCLPasscode None/No Code: ""
+*JCLPasscode 1111: "@PJL SET PASSCODE = 1111<0A>"
+*JCLPasscode 2222: "@PJL SET PASSCODE = 2222<0A>"
+*JCLPasscode 3333: "@PJL SET PASSCODE = 3333<0A>"
+*JCLCloseUI: *JCLPasscode
+
+*% Custom JCL key code option 
+*CustomJCLPasscode True: "@PJL SET PASSCODE = \1<0A>"
+*ParamCustomJCLPasscode Code/Key Code: 1 passcode 4 4
+
+
+*% Base PostScript watermark option
+*OpenUI WatermarkText/Watermark Text: PickOne
+*OrderDependency: 10 AnySetup *WatermarkText
+*DefaultWatermarkText: None
+*WatermarkText None: ""
+*WatermarkText Draft: "<</cupsString1(Draft)>>setpagedevice"
+*CloseUI: *WatermarkText
+
+*% Custom PostScript watermark option
+*CustomWatermarkText True: "<</cupsString1 3 -1 roll>>setpagedevice"
+*ParamCustomWatermarkText Text: 1 string 0 32
+
+
+*% Base PostScript gamma/density option 
+*OpenUI GammaDensity/Gamma and Density: PickOne
+*OrderDependency: 10 AnySetup *GammaDensity
+*DefaultGammaDensity: Normal
+*GammaDensity Normal/Normal: "<</cupsReal1 1.0/cupsReal2 1.0>>setpagedevice"
+*GammaDensity Light/Lighter: "<</cupsReal1 0.9/cupsReal2 0.67>>setpagedevice"
+*GammaDensity Dark/Darker: "<</cupsReal1 1.1/cupsReal2 1.5>>setpagedevice"
+*CloseUI: *GammaDensity
+
+*% Custom PostScript gamma/density option 
+*CustomGammaDensity True: "<</cupsReal1 3 -1 roll/cupsReal2 5 -1>>setpagedevice"
+*ParamCustomGammaDensity Gamma: 1 curve 0.1 10
+*ParamCustomGammaDensity Density: 2 real 0 2
+
+ + +

Writing PostScript Option Commands for Raster Drivers

+ +

PPD files are used for both PostScript and non-PostScript printers. For CUPS raster drivers, you use a subset of the PostScript language to set page device attributes such as page size, resolution, and so forth. For example, the following code sets the page size to A4 size:

+ +
+*PageSize A4: "<</PageSize[595 842]>>setpagedevice"
+
+ +

Custom options typically use other operators to organize the values into a key/value dictionary for setpagedevice. For example, our previous CustomWatermarkText option code uses the roll operator to move the custom string value into the dictionary for setpagedevice:

+ +
+*CustomWatermarkText True: "<</cupsString1 3 -1 roll>>setpagedevice"
+
+ +

For a custom string value of "My Watermark", CUPS will produce the following PostScript code for the option:

+ +
+(My Watermark)
+<</cupsString1 3 -1 roll>>setpagedevice
+
+ +

The code moves the string value ("My Watermark") from the bottom of the stack to the top, creating a dictionary that looks like:

+ +
+<</cupsString1(My Watermark)>>setpagedevice
+
+ +

The resulting dictionary sets the page device attributes that are sent to your raster driver in the page header.

+ +

Custom Page Size Code

+ +

There are many possible implementations of the CustomPageSize code. For CUPS raster drivers, the following code is recommended:

+ +
+*ParamCustomPageSize Width:        1 points min-width max-width
+*ParamCustomPageSize Height:       2 points min-height max-height
+*ParamCustomPageSize WidthOffset:  3 points 0 0
+*ParamCustomPageSize HeightOffset: 4 points 0 0
+*ParamCustomPageSize Orientation:  5 int 0 0
+*CustomPageSize True: "pop pop pop <</PageSize[5 -2 roll]/ImagingBBox null>>setpagedevice"
+
+ +

Supported PostScript Operators

+ +

CUPS supports the following PostScript operators in addition to the usual PostScript number, string (literal and hex-encoded), boolean, null, and name values:

+ +
    + +
  • << - Start a dictionary.
  • + +
  • >> - End a dictionary.
  • + +
  • [ - Start an array.
  • + +
  • ] - End an array.
  • + +
  • copy - Copy the top N objects on the stack.
  • + +
  • dup - Copy the top object on the stack.
  • + +
  • index - Copy the Nth from the top object on the stack.
  • + +
  • pop - Pop the top object on the stack.
  • + +
  • roll - Shift the top N objects on the stack.
  • + +
  • setpagedevice - Set the page header values according to the key/value dictionary on the stack.
  • + +
+ +
Note: + +

Never use the unsupported dict or put +operators in your option code. These operators are typically used in +option code dating back to Level 1 PostScript printers, which did not +support the simpler << or >> operators. +If you have old option code using dict or put, you can +rewrite it very easily to use the newer << and +>> operators instead. For example, the following code +to set the page size:

+ + + +
+1 dict dup /PageSize [612 792] put setpagedevice
+
+ +

can be rewritten as:

+ +
+<< /PageSize [612 792] >> setpagedevice
+
+ +
+ +

Supported Page Device Attributes

+ +

Table 2 shows the supported page device attributes along with PostScript code examples.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Supported Page Device Attributes
Name(s)TypeDescriptionExample(s)
AdvanceDistanceIntegerSpecifies the number of points to advance roll media after printing.<</AdvanceDistance 18>>setpagedevice
AdvanceMediaIntegerSpecifies when to advance the media: 0 = never, 1 = after the file, 2 = after the job, 3 = after the set, and 4 = after the page.<</AdvanceMedia 4>>setpagedevice
CollateBooleanSpecifies whether collated copies are required.<</Collate true>>setpagedevice
CutMediaIntegerSpecifies when to cut the media: 0 = never, 1 = after the file, 2 = after the job, 3 = after the set, and 4 = after the page.<</CutMedia 1>>setpagedevice
DuplexBooleanSpecifies whether 2-sided printing is required.<</Duplex true>>setpagedevice
HWResolutionInteger ArraySpecifies the resolution of the page image in pixels per inch.<</HWResolution[1200 1200]>>setpagedevice
InsertSheetBooleanSpecifies whether to insert a blank sheet before the job.<</InsertSheet true>>setpagedevice
JogIntegerSpecifies when to shift the media in the output bin: 0 = never, 1 = after the file, 2 = after the job, 3 = after the set, and 4 = after the page.<</Jog 2>>setpagedevice
LeadingEdgeIntegerSpecifies the leading edge of the media: 0 = top, 1 = right, 2 = bottom, 3 = left.<</LeadingEdge 0>>setpagedevice
ManualFeedBooleanSpecifies whether media should be drawn from the manual feed tray. Note: The MediaPosition attribute is preferred over the ManualFeed attribute.<</ManualFeed true>>setpagedevice
MediaClassStringSpecifies a named media.<</MediaClass (Invoices)>>setpagedevice
MediaColorStringSpecifies the color of the media.<</MediaColor >>setpagedevice
MediaPositionIntegerSpecifies the tray or source of the media.<</MediaPosition 12>>setpagedevice
MediaTypeStringSpecifies the general media type.<</MediaType (Glossy)>>setpagedevice
MediaWeightIntegerSpecifies the media weight in grams per meter2.<</MediaWeight 100>>setpagedevice
MirrorPrintBooleanSpecifies whether to flip the output image horizontally.<</MirrorPrint true>>setpagedevice
NegativePrintBooleanSpecifies whether to invert the output image.<</NegativePrint true>>setpagedevice
NumCopiesIntegerSpecifies the number of copies to produce of each page.<</NumCopies 100>>setpagedevice
OrientationIntegerSpecifies the orientation of the output: 0 = portrait, 1 = landscape rotated counter-clockwise, 2 = upside-down, 3 = landscape rotated clockwise.<</Orientation 3>>setpagedevice
OutputFaceUpBooleanSpecifies whether to place the media face-up in the output bin/tray.<</OutputFaceUp true>>setpagedevice
OutputTypeStringSpecifies the output type name.<</OutputType (Photo)>>setpagedevice
PageSizeInteger/Real ArraySpecifies the width and length/height of the page in points.<</PageSize[595 842]>>setpagedevice
SeparationsBooleanSpecifies whether to produce color separations.<</Separations true>>setpagedevice
TraySwitchBooleanSpecifies whether to switch trays automatically.<</TraySwitch true>>setpagedevice
TumbleBooleanSpecifies whether the back sides of pages are rotated 180 degrees.<</Tumble true>>setpagedevice
cupsBorderlessScalingFactorRealSpecifies the amount to scale the page image dimensions.<</cupsBorderlessScalingFactor 1.01>>setpagedevice
cupsColorOrderIntegerSpecifies the order of colors: 0 = chunked, 1 = banded, 2 = planar.<</cupsColorOrder 0>>setpagedevice
cupsColorSpaceIntegerSpecifies the page image colorspace: 0 = W, 1 = RGB, 2 = RGBA, 3 = K, 4 = CMY, 5 = YMC, 6 = CMYK, 7 = YMCK, 8 = KCMY, 9 = KCMYcm, 10 = GMCK, 11 = GMCS, 12 = White, 13 = Gold, 14 = Silver, 15 = CIE XYZ, 16 = CIE Lab, 17 = RGBW, 32 to 46 = CIE Lab (1 to 15 inks)<</cupsColorSpace 1 >>setpagedevice
cupsCompressionIntegerSpecifies a driver compression type/mode.<</cupsCompression 2>>setpagedevice
cupsInteger0
+ ...
+ cupsInteger15
IntegerSpecifies driver integer values.<</cupsInteger11 1234>>setpagedevice
cupsMarkerTypeStringSpecifies the type of ink/toner to use.<</cupsMarkerType (Black+Color)>>setpagedevice
cupsMediaTypeIntegerSpecifies a numeric media type.<</cupsMediaType 999>>setpagedevice
cupsPageSizeNameStringSpecifies the name of the page size.<</cupsPageSizeName (A4.Full)>>setpagedevice
cupsPreferredBitsPerColorIntegerSpecifies the preferred number of bits per color, typically 8 or 16.<</cupsPreferredBitsPerColor 16>>setpagedevice
cupsReal0
+ ...
+ cupsReal15
RealSpecifies driver real number values.<</cupsReal15 1.234>>setpagedevice
cupsRenderingIntentStringSpecifies the color rendering intent.<</cupsRenderingIntent (AbsoluteColorimetric)>>setpagedevice
cupsRowCountIntegerSpecifies the number of rows of raster data to print on each line for some drivers.<</cupsRowCount 24>>setpagedevice
cupsRowFeedIntegerSpecifies the number of rows to feed between passes for some drivers.<</cupsRowFeed 17>>setpagedevice
cupsRowStepIntegerSpecifies the number of lines between columns/rows on the print head for some drivers.<</cupsRowStep 2>>setpagedevice
cupsString0
+ ...
+ cupsString15
StringSpecifies driver string values.<</cupsString0(String Value)>>setpagedevice
+ + +

Media Attributes

+ +

The CUPS media attributes allow drivers to specify alternate custom page +size limits based on up to two options.

+ +

CUPS 1.4/Mac OS X 10.6cupsMediaQualifier2

+ +

*cupsMediaQualifier2: MainKeyword

+ +

This attribute specifies the second option to use for overriding the +custom page size limits.

+ +

Example:

+ +
+*% Specify alternate custom page size limits based on InputSlot and Quality
+*cupsMediaQualifier2: InputSlot
+*cupsMediaQualifier3: Quality
+*cupsMaxSize .Manual.: "1000 1000"
+*cupsMinSize .Manual.: "100 100"
+*cupsMinSize .Manual.Photo: "200 200"
+*cupsMinSize ..Photo: "300 300"
+
+ +

CUPS 1.4/Mac OS X 10.6cupsMediaQualifier3

+ +

*cupsMediaQualifier3: MainKeyword

+ +

This attribute specifies the third option to use for overriding the +custom page size limits.

+ +

Example:

+ +
+*% Specify alternate custom page size limits based on InputSlot and Quality
+*cupsMediaQualifier2: InputSlot
+*cupsMediaQualifier3: Quality
+*cupsMaxSize .Manual.: "1000 1000"
+*cupsMinSize .Manual.: "100 100"
+*cupsMinSize .Manual.Photo: "200 200"
+*cupsMinSize ..Photo: "300 300"
+
+ +

CUPS 1.4/Mac OS X 10.6cupsMinSize

+ +

*cupsMinSize .Qualifier2.Qualifier3: "width length"
+*cupsMinSize .Qualifier2.: "width length"
+*cupsMinSize ..Qualifier3: "width length"

+ +

This attribute specifies alternate minimum custom page sizes in points. +The cupsMediaQualifier2 and +cupsMediaQualifier3 attributes +are used to identify options to use for matching.

+ +

Example:

+ +
+*% Specify alternate custom page size limits based on InputSlot and Quality
+*cupsMediaQualifier2: InputSlot
+*cupsMediaQualifier3: Quality
+*cupsMaxSize .Manual.: "1000 1000"
+*cupsMinSize .Manual.: "100 100"
+*cupsMinSize .Manual.Photo: "200 200"
+*cupsMinSize ..Photo: "300 300"
+
+ +

CUPS 1.4/Mac OS X 10.6cupsMaxSize

+ +

*cupsMaxSize .Qualifier2.Qualifier3: "width length"
+*cupsMaxSize .Qualifier2.: "width length"
+*cupsMaxSize ..Qualifier3: "width length"

+ +

This attribute specifies alternate maximum custom page sizes in points. +The cupsMediaQualifier2 and +cupsMediaQualifier3 attributes +are used to identify options to use for matching.

+ +

Example:

+ +
+*% Specify alternate custom page size limits based on InputSlot and Quality
+*cupsMediaQualifier2: InputSlot
+*cupsMediaQualifier3: Quality
+*cupsMaxSize .Manual.: "1000 1000"
+*cupsMinSize .Manual.: "100 100"
+*cupsMinSize .Manual.Photo: "200 200"
+*cupsMinSize ..Photo: "300 300"
+
+ + +

General Attributes

+ +

CUPS 1.3/Mac OS X 10.5cupsBackSide

+ +

*cupsBackSide: keyword

+ +

This attribute requests special handling of the back side of pages +when doing duplexed (2-sided) output. Table 1 +shows the supported keyword values for this attribute and their effect +on the raster data sent to your driver. For example, when cupsBackSide +is Rotated and Tumble is false, your driver +will receive print data starting at the bottom right corner of the page, with +each line going right-to-left instead of left-to-right. The default value is +Normal.

+ +
Note: + +

cupsBackSide replaces the older cupsFlipDuplex +attribute - if cupsBackSide is specified, cupsFlipDuplex +will be ignored.

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Back Side Raster Coordinate System
cupsBackSideTumble ValueImage Presentation
NormalfalseLeft-to-right, top-to-bottom
NormaltrueLeft-to-right, top-to-bottom
ManualTumblefalseLeft-to-right, top-to-bottom
ManualTumbletrueRight-to-left, bottom-to-top
RotatedfalseRight-to-left, bottom-to-top
RotatedtrueRight-to-left, top-to-bottom
Flipped *falseLeft-to-right, bottom-to-top
Flipped *trueRight-to-left, top-to-bottom
+
+ +

* - Not supported in Mac OS X 10.5.x and earlier

+ +
+ + +
Figure 1: Back side images
Back side images
+ +

Examples:

+ +
+*% Flip the page image for the back side of duplexed output 
+*cupsBackSide: Flipped
+
+*% Rotate the page image for the back side of duplexed output 
+*cupsBackSide: Rotated
+
+ +

Also see the related APDuplexRequiresFlippedMargin +attribute.

+ +

CUPS 1.4/Mac OS X 10.6cupsCommands

+ +

*cupsCommands: "name name2 ... nameN"

+ +

This string attribute specifies the commands that are supported by the +CUPS command file filter for this device. The command names are separated +by whitespace.

+ +

Example:

+ +
+*% Specify the list of commands we support 
+*cupsCommands: "AutoConfigure Clean PrintSelfTestPage ReportLevels com.vendor.foo"
+
+ + +

CUPS 1.3/Mac OS X 10.5cupsEvenDuplex

+ +

*cupsEvenDuplex: boolean

+ +

This boolean attribute notifies the RIP filters that the +destination printer requires an even number of pages when 2-sided +printing is selected. The default value is false.

+ +

Example:

+ +
+*% Always send an even number of pages when duplexing 
+*cupsEvenDuplex: true
+
+ +

cupsFax

+ +

*cupsFax: boolean

+ +

This boolean attribute specifies whether the PPD defines a facsimile device. The default is false.

+ +

Examples:

+ +
+*cupsFax: true
+
+ +

cupsFilter

+ +

*cupsFilter: "source/type cost program"

+ +

This string attribute provides a conversion rule from the +given source type to the printer's native format using the +filter "program". If a printer supports the source type directly, +the special filter program "-" may be specified.

+ +

Examples:

+ +
+*% Standard raster printer driver filter 
+*cupsFilter: "application/vnd.cups-raster 100 rastertofoo"
+
+*% Plain text filter 
+*cupsFilter: "text/plain 10 texttofoo"
+
+*% Pass-through filter for PostScript printers 
+*cupsFilter: "application/vnd.cups-postscript 0 -"
+
+ +

DeprecatedcupsFlipDuplex

+ +

*cupsFlipDuplex: boolean

+ +

Due to implementation differences between Mac OS X and Ghostscript, +the cupsFlipDuplex attribute is deprecated. Instead, use +the cupsBackSide attribute to specify +the coordinate system (pixel layout) of the page data on the back side of +duplex pages.

+ +

The value true maps to a cupsBackSide value +of Rotated on Mac OS X and Flipped with +Ghostscript.

+ +

The default value is false.

+ +
Note: + +

Mac OS X drivers that previously used +cupsFlipDuplex may wish to provide both the old and +new attributes for maximum compatibility, for example:

+ +
+*cupsBackSide: Rotated
+*cupsFlipDuplex: true
+
+ +

Similarly, drivers written for other operating systems using +Ghostscript can use:

+ +
+*cupsBackSide: Flipped
+*cupsFlipDuplex: true
+
+ +

CUPS 1.3/Mac OS X 10.5cupsIPPFinishings

+ +

*cupsIPPFinishings number/text: "*Option Choice ..."

+ +

This attribute defines a mapping from IPP finishings +values to PPD options and choices.

+ +

Examples:

+ +
+*cupsIPPFinishings 4/staple: "*StapleLocation SinglePortrait"
+*cupsIPPFinishings 5/punch: "*PunchMedia Yes *PunchLocation LeftSide"
+*cupsIPPFinishings 20/staple-top-left: "*StapleLocation SinglePortrait"
+*cupsIPPFinishings 21/staple-bottom-left: "*StapleLocation SingleLandscape"
+
+ +

CUPS 1.3/Mac OS X 10.5cupsIPPReason

+ +

*cupsIPPReason reason/Reason Text: "optional URIs"

+ +

This optional attribute maps custom +printer-state-reasons keywords that are generated by +the driver to human readable text. The optional URIs string +contains zero or more URIs separated by a newline. Each URI can +be a CUPS server absolute path to a help file under the +scheduler's DocumentRoot directory, a full HTTP URL +("http://www.domain.com/path/to/help/page.html"), or any other +valid URI which directs the user at additional information +concerning the condition that is being reported.

+ +

Since the reason text is limited to 80 characters by the PPD specification, +longer text strings can be included by URI-encoding the text with the "text" +scheme, for example "text:some%20text". Multiple text URIs are +combined (with spaces between each URI) by the ppdLocalizeIPPReason +into a single string that can be displayed to the user.

+ +

Examples:

+ +
+*% Map com.vendor-error to text but no page
+*cupsIPPReason com.vendor-error/A serious error occurred: ""
+
+*% Map com.vendor-error to more than 80 characters of text but no page
+*cupsIPPReason com.vendor-error/A serious error occurred: "text:Now%20is%20the%20time
+text:for%20all%20good%20men%20to%20come%20to%20the%20aid%20of%20their%20country."
+
+*% Map com.vendor-error to text and a local page
+*cupsIPPReason com.vendor-error/A serious error occurred: "/help/com.vendor/error.html"
+
+*% Map com.vendor-error to text and a remote page
+*cupsIPPReason com.vendor-error/A serious error occurred: "http://www.vendor.com/help"
+
+*% Map com.vendor-error to text and a local, Apple help book, and remote page
+*APHelpBook: "file:///Library/Printers/vendor/Help.bundle"
+*cupsIPPReason com.vendor-error/A serious error occurred: "/help/com.vendor/error.html
+help:anchor='com.vendor-error'%20bookID=Vendor%20Help
+http://www.vendor.com/help"
+*End
+
+ +

CUPS 1.2/Mac OS X 10.5cupsLanguages

+ +

*cupsLanguages: "locale list"

+ +

This attribute describes which language localizations are +included in the PPD. The "locale list" string is a space-delimited +list of locale names ("en", "en_US", "fr_CA", etc.)

+ +

Example:

+ +
+*% Specify Canadian, UK, and US English, and Candian and French French 
+*cupsLanguages: "en_CA en_UK en_US fr_CA fr_FR"
+
+ +

cupsManualCopies

+ +

*cupsManualCopies: boolean

+ +

This boolean attribute notifies the RIP filters that the +destination printer does not support copy generation in +hardware. The default value is false.

+ +

Example:

+ +
+*% Tell the RIP filters to generate the copies for us 
+*cupsManualCopies: true
+
+ +

CUPS 1.4/Mac OS X 10.6cupsMarkerName

+ +

*cupsMarkerName/Name Text: ""

+ +

This optional attribute maps marker-names strings that are +generated by the driver to human readable text.

+ +

Examples:

+ +
+*% Map cyanToner to "Cyan Toner"
+*cupsMarkerName cyanToner/Cyan Toner: ""
+
+ +

CUPS 1.4/Mac OS X 10.6cupsMarkerNotice

+ +

*cupsMarkerNotice: "disclaimer text"

+ +

This optional attribute provides disclaimer text for the supply level +information provided by the driver, typically something like "supply levels +are approximate".

+ +

Examples:

+ +
+*cupsMarkerNotice: "Supply levels are approximate."
+
+ +

cupsModelNumber

+ +

*cupsModelNumber: number

+ +

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.

+ +

Example:

+ +
+*% Specify an integer for a driver-specific model number 
+*cupsModelNumber: 1234
+
+ +

CUPS 1.3/Mac OS X 10.5cupsPJLCharset

+ +

*cupsPJLCharset: "ISO character set name"

+ +

This string attribute specifies the character set that is used +for strings in PJL commands. If not specified, US-ASCII is +assumed.

+ +

Example:

+ +
+*% Specify UTF-8 is used in PJL strings
+*cupsPJLCharset: "UTF-8"
+
+ +

CUPS 1.4/Mac OS X 10.6cupsPJLDisplay

+ +

*cupsPJLDisplay: "what"

+ +

This optional attribute specifies which command is used to display the +job ID, name, and user on the printer's control panel. "What" is either "none" +to disable this functionality, "job" to use "@PJL JOB DISPLAY", or "rdymsg" +to use "@PJL RDYMSG DISPLAY". The default is "job".

+ +

Examples:

+ +
+*% Display job information using @PJL SET RDYMSG DISPLAY="foo"
+*cupsPJLDisplay: "rdymsg"
+
+*% Display job information display
+*cupsPJLDisplay: "none"
+
+ +

CUPS 1.2/Mac OS X 10.5cupsPortMonitor

+ +

*cupsPortMonitor urischeme/Descriptive Text: "port monitor"

+ +

This string attribute specifies printer-specific "port +monitor" filters that may be used with the printer. The CUPS +scheduler also looks for the Protocols attribute to see +if the BCP or TBCP protocols are supported. If +so, the corresponding port monitor ("bcp" and "tbcp", +respectively) is listed in the printer's +port-monitor-supported attribute.

+ +

The "urischeme" portion of the attribute specifies the URI scheme +that this port monitor should be used for. Typically this is used to +pre-select a particular port monitor for each type of connection that +is supported by the printer. The "port monitor" string can be "none" +to disable the port monitor for the given URI scheme.

+ +

Examples:

+ +
+*% Specify a PostScript printer that supports the TBCP protocol
+*Protocols: TBCP PJL
+
+*% Specify that TBCP should be used for socket connections but not USB
+*cupsPortMonitor socket/AppSocket Printing: "tbcp"
+*cupsPortMonitor usb/USB Printing: "none"
+
+*% Specify a printer-specific port monitor for an Epson USB printer 
+*cupsPortMonitor usb/USB Status Monitor: "epson-usb"
+
+ +

CUPS 1.3/Mac OS X 10.5cupsPreFilter

+ +

*cupsPreFilter: "source/type cost program"

+ +

This string attribute provides a pre-filter rule. The pre-filter +program will be inserted in the conversion chain immediately +before the filter that accepts the given MIME type.

+ +

Examples:

+ +
+*% PDF pre-filter
+*cupsPreFilter: "application/pdf 100 mypdfprefilter"
+
+*% PNG pre-filter
+*cupsPreFilter: "image/png 0 mypngprefilter"
+
+ + +

CUPS 1.5cupsPrintQuality

+ +

*cupsPrintQuality keyword/text: "code"

+ +

This UI keyword defines standard print qualities that directly map from the IPP "print-quality" job template attribute. Standard keyword values are "Draft", "Normal", and "High" which are mapped from the IPP "print-quality" values 3, 4, and 5 respectively. Each cupsPrintQuality option typically sets output mode and resolution parameters in the page device dictionary, eliminating the need for separate (and sometimes confusing) output mode and resolution options.

+ +
Note: + +

Unlike all of the other keywords defined in this document, cupsPrintQuality is a UI keyword that MUST be enclosed inside the PPD OpenUI and CloseUI keywords.

+ +
+ +

Examples:

+ +
+*OpenUI *cupsPrintQuality/Print Quality: PickOne
+*OrderDependency: 10 AnySetup *cupsPrintQuality
+*DefaultcupsPrintQuality: Normal
+*cupsPrintQuality Draft/Draft: "code"
+*cupsPrintQuality Normal/Normal: "code"
+*cupsPrintQuality High/Photo: "code"
+*CloseUI: *cupsPrintQuality
+
+ +

CUPS 1.4/Mac OS X 10.6cupsSNMPSupplies

+ +

*cupsSNMPSupplies: boolean

+ +

This attribute tells the standard network backends whether they should query +the standard SNMP Printer MIB OIDs for supply levels. The default value is +True. + +

Example:

+ +
+*% Do not use SNMP queries to report supply levels
+*cupsSNMPSupplies: False
+
+ +

cupsVersion

+ +

*cupsVersion: major.minor

+ +

This required attribute describes which version of the CUPS +PPD file extensions was used. Currently it must be the string +"1.0", "1.1", "1.2", or "1.3".

+ +

Example:

+ +
+*% Specify a CUPS 1.2 driver 
+*cupsVersion: "1.2"
+
+ + +

Mac OS X Attributes

+ +

Mac OS X 10.3APDialogExtension

+ +

*APDialogExtension: "/Library/Printers/vendor/filename.plugin"

+ +

This attribute defines additional option panes that are displayed in the +print dialog. Each attribute adds one or more option panes. See the "OutputBinsPDE" +example and Apple +Technical Q&A QA1352 for information on writing your own print dialog +plug-ins.

+ +
Note: + +

Starting with Mac OS X 10.5, each plug-in must be compiled "4-way fat" +(32-bit and 64-bit for both PowerPC and Intel) with garbage collection enabled +in order to be usable with all applications.

+ +
+ +

Examples:

+ +
+*% Add two panes for finishing and driver options
+*APDialogExtension: "/Library/Printers/vendor/finishing.plugin"
+*APDialogExtension: "/Library/Printers/vendor/options.plugin"
+
+ +

Mac OS X 10.4APDuplexRequiresFlippedMargin

+ +

*APDuplexRequiresFlippedMargin: boolean

+ +

This boolean attribute notifies the RIP filters that the +destination printer requires the top and bottom margins of the +ImageableArea to be swapped for the back page. The +default is true when cupsBackSide is Flipped +and false otherwise. Table 2 shows how +APDuplexRequiresFlippedMargin interacts with cupsBackSide +and the Tumble page attribute.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Margin Flipping Modes
APDuplexRequiresFlippedMargincupsBackSideTumble ValueMargins
falseanyanyNormal
anyNormalanyNormal
trueManualDuplexfalseNormal
trueManualDuplextrueFlipped
trueRotatedfalseFlipped
trueRotatedtrueNormal
true or unspecifiedFlippedanyFlipped
+ +

Example:

+ +
+*% Rotate the back side images
+*cupsBackSide: Rotated
+
+*% Don't swap the top and bottom margins for the back side 
+*APDuplexRequiresFlippedMargin: false
+
+ +

Also see the related cupsBackSide +attribute.

+ +

APHelpBook

+ +

*APHelpBook: "bundle URL"

+ +

This string attribute specifies the Apple help book bundle to use when +looking up IPP reason codes for this printer driver. The +cupsIPPReason attribute maps +"help" URIs to this file.

+ +

Example:

+ +
+*APHelpBook: "file:///Library/Printers/vendor/Help.bundle"
+
+ +

Mac OS X 10.6APICADriver

+ +

*APICADriver: boolean

+ +

This attribute specifies whether the device has a matching Image Capture +Architecture (ICA) driver for scanning. The default is False.

+ +

Examples:

+ +
+*APICADriver: True
+*APScanAppBundleID: "com.apple.ImageCaptureApp"
+
+ +

Mac OS X 10.3APPrinterIconPath

+ +

*APPrinterIconPath: "/Library/Printers/vendor/filename.icns"

+ +

This attribute defines the location of a printer icon file to use when +displaying the printer. The file must be in the Apple icon format.

+ +

Examples:

+ +
+*% Apple icon file
+*APPrinterIconPath: "/Library/Printers/vendor/Icons/filename.icns"
+
+ +

Mac OS X 10.4APPrinterLowInkTool

+ +

*APPrinterLowInkTool: "/Library/Printers/vendor/program"

+ +

This attribute defines an program that checks the ink/toner/marker levels +on a printer, returning an XML document with those levels. See the "InkTool" +example and +Apple +Technical Note TN2144 for more information.

+ +

Examples:

+ +
+*% Use a vendor monitoring program
+*APPrinterLowInkTool: "/Library/Printers/vendor/Tools/lowinktool"
+
+ +

Mac OS X 10.5APPrinterPreset

+ +

*APPrinterPreset name/text: "*Option Choice ..."

+ +

This attribute defines presets for multiple options that show up +in the print dialog of applications (such as iPhoto) that set the job +style hint to NSPrintPhotoJobStyleHint. Each preset maps to one or +more pairs of PPD options and choices as well as providing key/value data for +the application. The following standard preset names are currently defined:

+ +
    + +
  • General_with_Paper_Auto-Detect; Normal quality general printing with auto-detected media.
  • + +
  • General_with_Paper_Auto-Detect_-_Draft; Draft quality general printing with auto-detected media.
  • + +
  • General_on_Plain_Paper; Normal quality general printing on plain paper.
  • + +
  • General_on_Plain_Paper_-_Draft; Draft quality general printing on plain paper.
  • + +
  • Photo_with_Paper_Auto-Detect; Normal quality photo printing with auto-detected media.
  • + +
  • Photo_with_Paper_Auto-Detect_-_Fine; High quality photo printing with auto-detected media.
  • + +
  • Photo_on_Plain_Paper; Normal quality photo printing on plain paper.
  • + +
  • Photo_on_Plain_Paper_-_Fine; High quality photo printing on plain paper.
  • + +
  • Photo_on_Photo_Paper; Normal quality photo printing on glossy photo paper.
  • + +
  • Photo_on_Photo_Paper_-_Fine; High quality photo printing on glossy photo paper.
  • + +
  • Photo_on_Matte_Paper; Normal quality photo printing on matte paper.
  • + +
  • Photo_on_Matte_Paper_-_Fine; High quality photo printing on matte paper.
  • + +
+ +

The value string consists of pairs of keywords, either an option name and +choice (*MainKeyword OptionKeyword) or a preset identifier and value +(com.apple.print.preset.foo value). The following preset identifiers are currently used:

+ +
    + +
  • com.apple.print.preset.graphicsType; specifies the type of printing used for this printing - "General" for general purpose printing and "Photo" for photo printing.
  • + +
  • com.apple.print.preset.media-front-coating; specifies the media type selected by this preset - "none" (plain paper), "glossy", "high-gloss", "semi-gloss", "satin", "matte", and "autodetect".
  • + +
  • com.apple.print.preset.output-mode; specifies the output mode for this preset - "color" (default for color printers) or "monochrome" (grayscale, default for B&W printers).
  • + +
  • com.apple.print.preset.quality; specifies the overall print quality selected by this preset - "low" (draft), "mid" (normal), or "high".
  • + +
+ +

Presets, like options, can also be localized in multiple languages.

+ +

Examples:

+ +
+*APPrinterPreset Photo_on_Photo_Paper/Photo on Photo Paper: "
+  *MediaType Glossy
+  *ColorModel RGB
+  *Resolution 300dpi
+  com.apple.print.preset.graphicsType Photo
+  com.apple.print.preset.quality mid
+  com.apple.print.preset.media-front-coating glossy"
+*End
+*fr.APPrinterPreset Photo_on_Photo_Paper/Photo sur papier photographique: ""
+
+ +

Mac OS X 10.3APPrinterUtilityPath

+ +

*APPrinterPrinterUtilityPath: "/Library/Printers/vendor/filename.app"

+ +

This attribute defines a GUI application that can be used to do printer +maintenance functions such as cleaning the print head(s). See ... for more +information.

+ +

Examples:

+ +
+*% Define the printer utility application
+*APPrinterPrinterUtilityPath: "/Library/Printers/vendor/Tools/utility.app"
+
+ +

Mac OS X 10.6APScannerOnly

+ +

*APScannerOnly: boolean

+ +

This attribute specifies whether the device has scanning but no printing +capabilities. The default is False.

+ +

Examples:

+ +
+*APICADriver: True
+*APScannerOnly: True
+
+ +

Mac OS X 10.3APScanAppBundleID

+ +

*APScanAppBundleID: "bundle ID"

+ +

This attribute defines the application to use when scanning pages from +the device.

+ +

Examples:

+ +
+*APICADriver: True
+*APScanAppBundleID: "com.apple.ImageCaptureApp"
+
+ + +

Change History

+ +

Changes in CUPS 1.4.5

+ + + + +

Changes in CUPS 1.4

+ + + + +

Changes in CUPS 1.3.1

+ +
    + +
  • Added missing Mac OS X AP attributes.
  • + +
  • Added section on auto-configuration including the + OIDMainKeyword and ?MainKeyword + attributes.
  • + +
  • Minor reorganization.
  • + +
+ + +

Changes in CUPS 1.3

+ + + +

Changes in CUPS 1.2.8

+ +
    + +
  • Added section on supported PostScript commands for raster + drivers
  • + +
+ +

Changes in CUPS 1.2

+ + + +

Changes in CUPS 1.1

+ +
    + +
  • Added cupsFlipDuplex attribute
  • + +
  • Added cupsProtocol attribute
  • + +
+ + + diff --git a/doc/help/spec-raster.html b/doc/help/spec-raster.html new file mode 100644 index 0000000000..50fca220ac --- /dev/null +++ b/doc/help/spec-raster.html @@ -0,0 +1,720 @@ + + + + + CUPS Raster Format + + + + +

CUPS Raster Format

+ +

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.

+ +

CUPS 1.0 and 1.1 used version 1 of the raster format. CUPS 1.2 and later use version 2 (compressed) and version 3 (uncompressed) that are a superset of the version 1 raster format. All three versions of CUPS Raster are streamable formats, and applications using the CUPS Imaging API (the cupsRaster* functions) can read all formats without code changes.

+ +

The registered MIME media type for CUPS Raster files is application/vnd.cups-raster.

+ + +

Organization of a CUPS Raster File

+ +

Figure 1, "Raster Organization", shows the general organization of all CUPS Raster files. Each file begins with a 32-bit synchronization word followed by zero or more pages. Each page consists of a header (the PostScript page device dictionary and raster-specific values) followed by the bitmap image for the page.

+ + + +

Each page bitmap is stored as described by the cupsBitsPerColor, cupsBytesPerLine, cupsColorOrder, cupsColorSpace, cupsHeight, and cupsWidth values in the page header. Pixels for the front side of a sheet are always stored left-to-right, top-to-bottom. When doing duplex printing, pixels for the back side of a sheet may be stored differently depending on the value of the cupsBackSide keyword ("Normal", "ManualTumble", "Rotated", or "Flipped") in the PPD file and the Tumble value ("true" or "false") in the page header. Figure 2, "Page Bitmaps", shows the pixel order for each combination.

+ + + + +

Version 1 Raster File Format

+ +

A version 1 raster file begins with a 32-bit synchronization word: 0x52615374 ("RaSt") for big-endian architectures or 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 Imaging API raster functions perform this function automatically.

+ +

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 (uncompressed/raw) raster data for that page.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: CUPS Version 1 Raster Page Device Dictionary
BytesTypeDescriptionValues
0-63C StringMediaClassMedia class string
64-127C StringMediaColorMedia color string
128-191C StringMediaTypeMedia type string
192-255C StringOutputTypeOutput type string
256-259Unsigned IntegerAdvanceDistance0 to 232 - 1 points
260-263Unsigned IntegerAdvanceMedia0 = Never advance roll
+ 1 = Advance roll after file
+ 2 = Advance roll after job
+ 3 = Advance roll after set
+ 4 = Advance roll after page
264-267Unsigned IntegerCollate0 = do not collate copies
+ 1 = collate copies
268-271Unsigned IntegerCutMedia0 = Never cut media
+ 1 = Cut roll after file
+ 2 = Cut roll after job
+ 3 = Cut roll after set
+ 4 = Cut roll after page
272-275Unsigned IntegerDuplex0 = Print single-sided
+ 1 = Print double-sided
276-283Unsigned Integers (2)HWResolutionHorizontal and vertical resolution in dots-per-inch.
284-299Unsigned Integers (4)ImagingBoundingBoxFour integers giving the left, bottom, right, and top positions + of the page bounding box in points
300-303Unsigned IntegerInsertSheet0 = Do not insert separator sheets
+ 1 = Insert separator sheets
304-307Unsigned IntegerJog0 = Do no jog pages
+ 1 = Jog pages after file
+ 2 = Jog pages after job
+ 3 = Jog pages after set
308-311Unsigned IntegerLeadingEdge0 = Top edge is first
+ 1 = Right edge is first
+ 2 = Bottom edge is first
+ 3 = Left edge is first
312-319Unsigned Integers (2)MarginsLeft and bottom origin of image in points
320-323Unsigned IntegerManualFeed0 = Do not manually feed media
+ 1 = Manually feed media
324-327Unsigned IntegerMediaPositionInput slot position from 0 to N
328-331Unsigned IntegerMediaWeightMedia weight in grams per meter squared, 0 = printer default
332-335Unsigned IntegerMirrorPrint0 = Do not mirror prints
+ 1 = Mirror prints
336-339Unsigned IntegerNegativePrint0 = Do not invert prints
+ 1 = Invert prints
340-343Unsigned IntegerNumCopies0 to 232 - 1, 0 = printer default
344-347Unsigned IntegerOrientation0 = Do not rotate page
+ 1 = Rotate page counter-clockwise
+ 2 = Turn page upside down
+ 3 = Rotate page clockwise
348-351Unsigned IntegerOutputFaceUp0 = Output face down
+ 1 = Output face up
352-359Unsigned Integers (2)PageSizeWidth and length in points
360-363Unsigned IntegerSeparations0 = Print composite image
+ 1 = Print color separations
364-367Unsigned IntegerTraySwitch0 = Do not change trays if selected tray is empty
+ 1 = Change trays if selected tray is empty
368-371Unsigned IntegerTumble0 = Do not rotate even pages when duplexing
+ 1 = Rotate even pages when duplexing
372-375Unsigned IntegercupsWidthWidth of page image in pixels
376-379Unsigned IntegercupsHeightHeight of page image in pixels
380-383Unsigned IntegercupsMediaTypeDriver-specific 0 to 232 - 1
384-387Unsigned IntegercupsBitsPerColor1, 2, 4, 8 bits for version 1 raster files
+ 1, 2, 4, 8, and 16 bits for version 2/3 raster files
388-391Unsigned IntegercupsBitsPerPixel1 to 32 bits for version 1 raster files
+ 1 to 240 bits for version 2/3 raster files
392-395Unsigned IntegercupsBytesPerLine1 to 232 - 1 bytes
396-399Unsigned IntegercupsColorOrder0 = chunky pixels (CMYK CMYK CMYK)
+ 1 = banded pixels (CCC MMM YYY KKK)
+ 2 = planar pixels (CCC... MMM... YYY... KKK...)
400-403Unsigned IntegercupsColorSpace0 = gray (device, typically sRGB-based)
+ 1 = RGB (device, typically sRGB)
+ 2 = RGBA (device, typically sRGB)
+ 3 = black
+ 4 = CMY
+ 5 = YMC
+ 6 = CMYK
+ 7 = YMCK
+ 8 = KCMY
+ 9 = KCMYcm
+ 10 = GMCK
+ 11 = GMCS
+ 12 = WHITE
+ 13 = GOLD
+ 14 = SILVER
+ 15 = CIE XYZ
+ 16 = CIE Lab
+ 17 = RGBW (sRGB)
+ 18 = sGray (gray using sRGB gamma/white point)
+ 19 = sRGB
+ 20 = AdobeRGB
+ 32 = ICC1 (CIE Lab with hint for 1 color)
+ 33 = ICC2 (CIE Lab with hint for 2 colors)
+ 34 = ICC3 (CIE Lab with hint for 3 colors)
+ 35 = ICC4 (CIE Lab with hint for 4 colors)
+ 36 = ICC5 (CIE Lab with hint for 5 colors)
+ 37 = ICC6 (CIE Lab with hint for 6 colors)
+ 38 = ICC7 (CIE Lab with hint for 7 colors)
+ 39 = ICC8 (CIE Lab with hint for 8 colors)
+ 40 = ICC9 (CIE Lab with hint for 9 colors)
+ 41 = ICCA (CIE Lab with hint for 10 colors)
+ 42 = ICCB (CIE Lab with hint for 11 colors)
+ 43 = ICCC (CIE Lab with hint for 12 colors)
+ 44 = ICCD (CIE Lab with hint for 13 colors)
+ 45 = ICCE (CIE Lab with hint for 14 colors)
+ 46 = ICCF (CIE Lab with hint for 15 colors)
+ 48 = Device1 (DeviceN for 1 color)
+ 49 = Device2 (DeviceN for 2 colors)
+ 50 = Device3 (DeviceN for 3 colors)
+ 51 = Device4 (DeviceN for 4 colors)
+ 52 = Device5 (DeviceN for 5 colors)
+ 53 = Device6 (DeviceN for 6 colors)
+ 54 = Device7 (DeviceN for 7 colors)
+ 55 = Device8 (DeviceN for 8 colors)
+ 56 = Device9 (DeviceN for 9 colors)
+ 57 = DeviceA (DeviceN for 10 colors)
+ 58 = DeviceB (DeviceN for 11 colors)
+ 59 = DeviceC (DeviceN for 12 colors)
+ 60 = DeviceD (DeviceN for 13 colors)
+ 61 = DeviceE (DeviceN for 14 colors)
+ 62 = DeviceF (DeviceN for 15 colors) +
404-407Unsigned IntegercupsCompressionDriver-specific 0 to 232 - 1
408-411Unsigned IntegercupsRowCountDriver-specific 0 to 232 - 1
412-415Unsigned IntegercupsRowFeedDriver-specific 0 to 232 - 1
416-419Unsigned IntegercupsRowStepDriver-specific 0 to 232 - 1
+ + +

Version 2 Raster File Format

+ +

A version 2 raster file begins with a 32-bit synchronization word: 0x52615332 ("RaS2") for big-endian architectures or 0x32536152 ("2SaR") 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 Imaging API raster functions perform this function automatically.

+ +

Following the synchronization word are a series of raster pages. Each page starts with a version 2 page device dictionary header and is followed immediately by the compressed raster data for that page.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: CUPS Version 2 Raster Page Device Dictionary
BytesTypeDescriptionValues
0-419Version 1 header dataSee Table 1
420-423Unsigned IntegercupsNumColors1 to 15 colors
424-427IEEE Single PrecisioncupsBorderlessScalingFactor0.0 or 1.0 or greater
428-435IEEE Single Precision (2)cupsPageSizeWidth and length in points
436-451IEEE Single Precision (4)cupsImagingBBoxFour floating point numbers giving the left, bottom, right, and top positions of the page bounding box in points
452-515Unsigned Integers (16)cupsInteger16 driver-defined integer values
516-579IEEE Single Precision (16)cupsReal16 driver-defined floating point values
580-1603C Strings (16x64)cupsString16 driver-defined strings
1604-1667C StringcupsMarkerTypeInk/toner type string
1668-1731C StringcupsRenderingIntentColor rendering intent string
1732-1795C StringcupsPageSizeNamePage size name/keyword string from PPD
+ +

Compressed Raster Data Format

+ +

The version 2 raster data is compressed using a PackBits-like algorithm. Lines are grouped into an integral number of color values based upon the cupsColorOrder setting:

+ +
+ + + + + + + + + + + + + + + + + +
Table 3: Color Value Sizes
cupsColorOrderBytes per color value
0 (chunky)(cupsBitsPerPixel + 7) / 8
1 (banded)(cupsBitsPerColor + 7) / 8
2 (planar)(cupsBitsPerColor + 7) / 8
+ +

Each line of raster data begins with a repetition count from 1 to 256 that is encoded using a single byte of "count - 1".

+ +

After the repetition count, whole color values for that line are run-length encoded using a PackBits-like run-length encoding algorithm: 1 to 128 repeated colors are encoded using an initial byte of "count - 1" followed by the color value byte(s) while 2 to 128 non-repeating colors are encoded using an initial byte of "257 - count" followed by the color value bytes.

+ +

For example, the 8x8 24-bit sRGB image shown in Figure 3, "Sample Image", would be encoded as the following 89 octets:

+ +
+%x00 %x00.FF.FF.FF %x02.FF.FF.00 %x03.FF.FF.FF
+%x00 %xFE.FF.FF.00.00.00.FF.FF.FF.00 %x02.FF.FF.FF %x00.00.FF.00 %x00.FF.FF.FF
+%x00 %x01.FF.FF.00 %x02.FF.FF.FF %x02.00.FF.00
+%x00 %x02.FF.FF.00 %x02.FF.FF.FF %x00.00.FF.00 %x00.FF.FF.FF
+%x00 %x00.FF.FF.FF %x02.FF.FF.00 %x03.FF.FF.FF
+%x00 %x07.FF.FF.FF
+%x01 %x07.FF.00.00
+
+ +

The first line (%x00) contains 1 white pixel (%x00.FF.FF.FF), 3 yellow pixels (%x02.FF.FF.00), and 4 white pixels (%x03.FF.FF.FF).

+ +

The second line (%x00) contains a sequence of yellow + blue + yellow pixels (%xFE.FF.FF.00.00.00.FF.FF.FF.00), 3 white pixels (%x02.FF.FF.FF), 1 green pixel (%x00.00.FF.00), and 1 white pixel (%x00.FF.FF.FF).

+ +

The third line (%x00) contains 2 yellow pixels (%x01.FF.FF.00), 3 white pixels (%x02.FF.FF.FF), and 3 green pixels (%x02.00.FF.00)

+ +

The fourth line (%x00) contains 3 yellow pixels (%x02.FF.FF.00), 3 white pixels (%x02.FF.FF.FF), 1 green pixel (%x00.00.FF.00), and 1 white pixel (%x00.FF.FF.FF).

+ +

The fifth line (%x00) contains 1 white pixel (%x00.FF.FF.FF), 3 yellow pixels (%x02.FF.FF.00), and 4 white pixels (%x03.FF.FF.FF).

+ +

The sixth line (%x00) contains 8 white pixels (%x07.FF.FF.FF).

+ +

The seventh and eighth lines (%x01) contain 8 red pixels (%x07.FF.00.00).

+ + + + +

Version 3 Raster File Format

+ +

A version 3 raster file begins with a 32-bit synchronization word: 0x52615333 ("RaS3") for big-endian architectures and 0x33536152 ("3SaR") 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 Imaging API raster functions perform this function automatically.

+ +

Following the synchronization word are a series of raster pages. Each page starts with a version 2 page device dictionary header and is followed immediately by the uncompressed/raw raster data for that page.

+ + +

Pixel Value Coding

+ +

The following sections describe the encoding and decoding of the color values in a CUPS Raster file. In general, colors are packed into the minimum number of bytes, with special consideration provided for efficiency of encoding and access. Multi-byte values are stored in the native byte order and automatically swapped as needed when reading them using the CUPS imaging API.

+ +

CUPS_ORDER_CHUNKED

+ +

The chunked order provides the pixel value packed in a single place. Pixel values with 8 or more bits per color are stored as an array of colors in order, e.g. for CUPS_CSPACE_RGB you will see 8/16-bits of red, then blue, then green, then red, green, blue, etc. Pixel values with less than 8 bits per color are packed together as shown in Table 4. Multi-byte pixel values are stored in the native word order, just as for 16-bit color values.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 4: Chunked Color Values
Bits1-color3-color4-color6-color
1W/W/W/W/W/W/W/W0RGB/0RGBCMYK/CMYK00KCMYcm
2WW/WW/WW/WW00RRGGBBCCMMYYKKN/A
4WWWW/WWWW0000RRRRGGGGBBBB
+ (multi-byte)
CCCCMMMMYYYYKKKK
+ (multi-byte)
N/A
+ +

CUPS_ORDER_BANDED

+ +

The banded order provides each color as a separate line of data. Each color plane for a line is written in sequence, e.g. for the CUPS_CSPACE_CMYK color space you would see all of the cyan pixels for a line followed by the magenta, yellow, and black pixels for that line. This is repeated for all of the lines on the page. Color values are packed starting with the most-significant bit (MSB) first.

+ +

CUPS_ORDER_PLANAR

+ +

The planar order provides each color as a separate page of data using a shared page header. Each color plane for a page is written in sequence, e.g. for the CUPS_CSPACE_CMYK color space you would see all of the cyan pixels for a page followed by the magenta, yellow, and black pixels for that page. Color values are packed starting with the most-significant bit (MSB) first. Each line starts on an 8-bit boundary.

+ +

CUPS_CSPACE_RGBW

+ +

This color space provides a dedicated black text channel and uses the sRGB color space definition and white point for the RGB color channels. The white channel is 0 for text (or "true") black, otherwise it must contain the maximum color value: 1 for 1-bit, 3 for 2-bit, 15 for 4-bit, 255 for 8-bit, or 65535 for 16-bit.

+ +

CUPS_CSPACE_KCMYcm

+ +

When cupsBitsPerColor is 1, 6 color planes are provided - black, cyan, magenta, yellow, light cyan, and light magenta. When cupsBitsPerColor is greater than 1, 4 color planes are provided using the CUPS_CSPACE_KCMY color space instead.

+ +

When cupsColorOrder is CUPS_ORDER_CHUNKED, bit 5 corresponds to black and bit 0 corresponds to light magenta. For CUPS_ORDER_BANDED and CUPS_ORDER_PLANAR, each color plane is encoded separately.

+ +

CUPS_CSPACE_CIELab and CUPS_CSPACE_ICCn

+ +

These color spaces map a CIE Lab color value with a D65 white point to either a 8- or 16-bit per color chunked (CUPS_ORDER_CHUNKED) format; the banded (CUPS_ORDER_BANDED) and planar (CUPS_ORDER_PLANAR) color orders are not supported.

+ +

The values are encoded and decoded using the following formulas:

+ +
    + +
  • 8-bit Encoding:
    + L8 = 2.55 * L + 0.5
    + a8 = a + 128.5
    + b8 = b + 128.5
    +  
  • + +
  • 8-bit Decoding:
    + L = L8 / 2.55
    + a = a8 - 128
    + b = b8 - 128
    +  
  • + +
  • 16-bit Encoding:
    + L16 = 655.35 * L + 0.5
    + a16 = 256 * (a + 128) + 0.5
    + b16 = 256 * (b + 128) + 0.5
    +  
  • + +
  • 16-bit Decoding:
    + L = L16 / 655.35
    + a = a16 / 256 - 128
    + b = b16 / 256 - 128
    +  
  • + +
+ +

CUPS_CSPACE_CIEXYZ

+ +

These color spaces map a CIE XYZ color value with a D65 white point to either a 8- or 16-bit per color chunked (CUPS_ORDER_CHUNKED) format; the banded (CUPS_ORDER_BANDED) and planar (CUPS_ORDER_PLANAR) color orders are not supported.

+ +

The values are encoded and decoded using the following formulas:

+ +
    + +
  • 8-bit Encoding:
    + X8 = 231.8181 * X + 0.5
    + Y8 = 231.8181 * Y + 0.5
    + Z8 = 231.8181 * Z + 0.5
    +  
  • + +
  • 8-bit Decoding:
    + X = X8 / 231.8181
    + Y = Y8 / 231.8181
    + Z = Z8 / 231.8181
    +  
  • + +
  • 16-bit Encoding:
    + X16 = 59577.2727 * X + 0.5
    + Y16 = 59577.2727 * Y + 0.5
    + Z16 = 59577.2727 * Z + 0.5
    +  
  • + +
  • 16-bit Decoding:
    + X = X16 / 59577.2727
    + Y = Y16 / 59577.2727
    + Z = Z16 / 59577.2727
    +  
  • + +
+ +

The scaling factor for XYZ values is 1/1.1, or 231.8181 for 8-bit values and 59577.2727 for 16-bit values. This allows for a slight overflow of XYZ values when converting from RGB, improving accuracy.

+ + +

Change History

+ +

Changes in CUPS 1.4.7

+ +
    + +
  • Greatly improved the detail and now include an example of the bitmap compression.
  • +
  • Added all missing cupsColorSpace values and a separate description of CUPS_CSPACE_RGBW.
  • + +
+ + +

Changes in CUPS 1.2.2

+ +
    + +
  • Added version 3 (uncompressed) format.
  • + +
+ + +

Changes in CUPS 1.2.1

+ +
    + +
  • Added new sections on coding pixel values.
  • + +
  • Clarified definitions of color spaces.
  • + +
+ + +

Changes in CUPS 1.2

+ +
    + +
  • Bumped raster version to 2
  • + +
  • Added RGBW color space
  • + +
  • Added 16 bit per color support
  • + +
  • Added cupsNumColors, cupsBorderlessScalingFactor, cupsPageSize, cupsImagingBBox, cupsInteger, cupsReal, cupsString, cupsMarkerType, cupsRenderingIntent, and cupsPageSizeName attributes to the page device dictionary
  • + +
  • Added raster data compression
  • + +
  • Added data type column to device dictionary documentation.
  • + +
+ +

Changes in CUPS 1.1.19

+ +
    + +
  • Added ICC and CIE color spaces.
  • + +
+ + + diff --git a/doc/help/spec-stp.html b/doc/help/spec-stp.html new file mode 100644 index 0000000000..06c099b55f --- /dev/null +++ b/doc/help/spec-stp.html @@ -0,0 +1,133 @@ + + + + + CUPS Software Test Plan + + + + +

CUPS Software Test Plan

+ +

This software test plan provides detailed tests that are used +to evaluate the stability and compliance of CUPS.

+ + +

Test Procedure

+ +

The test software and data files are located in the +test subdirectory of the source distribution. A script +is provided to compile the ipptool program and run +all of the tests that follow, producing a success/fail +report.

+ +

The test target of the top-level makefile can be +used to run this script:

+ +
+make test
+
+ +

or you can run the test script directly:

+ +
+cd test
+./run-stp-tests
+
+ +

A Software Test Report is stored in a HTML file in the +test subdirectory at the conclusion of the test.

+ + +

IPP Compliance Tests

+ +

This section describes the tests used to validate the IPP +standards compliance of the CUPS server.

+ +

Request Tests

+ +

These tests verify that the CUPS scheduler only accepts valid +IPP requests that start with the attributes-charset +and attributes-natural-language attributes and also +contain a printer-uri or job-uri +attribute.

+ +

It also verifies that the CUPS scheduler always responds with +attributes-charset and +attributes-natural-language attributes, using +default values if they are not provided by the client.

+ +

CUPS Printer Operation Tests

+ +

These tests verify that the CUPS printer operations are +supported and function properly. Two printers called +Test1 and Test2 are created, one as a +PostScript printer and one as a raster printer.

+ +

Job Operation Tests

+ +

These test verify that the CUPS scheduler accepts print jobs +for all supported file formats and that the +cancel-job, hold-job, and +resume-job operations work.

+ +

Subscription Operation Tests

+ +

These test verify that the CUPS scheduler accepts +subscriptions with print jobs and that all subscription +operations work as required by the IPP notification and mailto +specifications.

+ + +

Command Tests

+ +

This section describes the tests used to validate the Berkeley +and System V commands included with CUPS.

+ +

lpadmin

+ +

This test verifies that printers can be added, modified, and +defaulted using the lpadmin command.

+ +

lpc

+ +

This test verifies that the lpc command can show +the current status of all print queues.

+ +

lpq

+ +

This test verifies that the lpq command lists +any jobs in the queue.

+ +

lpstat

+ +

This test verifies that the lpstat command works +with all reports using the "-t" option.

+ +

lp

+ +

This test verifies that the lp command works with +both the default destination and a specific destination.

+ +

lpr

+ +

This test verifies that the lpr command works +with both the default destination and a specific destination.

+ +

lprm

+ +

This test verifies that the lprm command can +properly cancel a job.

+ +

cancel

+ +

This test verifies that the cancel command can +properly cancel a job or all jobs.

+ +

lpinfo

+ +

This test verifies that the lpinfo command +returns a list of available printer drivers and devices.

+ + + diff --git a/doc/help/standard.html.in b/doc/help/standard.html.in new file mode 100644 index 0000000000..f957fe249c --- /dev/null +++ b/doc/help/standard.html.in @@ -0,0 +1,181 @@ + + + + Standard Configuration + + + + +

Standard Configuration

+ +

This document describes the standard configuration for this CUPS +server.

+ +
Note: + + +

This file reflects the standard CUPS configuration as distributed +by Apple Inc, the developer of CUPS.

+ +
+ + +

cupsd Configuration

+ +

cupsd(8) is configured by default to show +printers shared by other systems and only allow local access to +the system and its printers. Administration operations require +Basic authentication with membership in the group +"@CUPS_GROUP@".

+ +

Connections are accepted via domain socket +(@CUPS_DEFAULT_DOMAINSOCKET@) or "localhost" +(127.0.0.1).

+ +

Settings

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Default Values
DirectiveValue
Browsing@CUPS_BROWSING@
BrowseLocalProtocols@CUPS_BROWSE_LOCAL_PROTOCOLS@
BrowseRemoteProtocols@CUPS_BROWSE_REMOTE_PROTOCOLS@
BrowseShortNames@CUPS_BROWSE_SHORT_NAMES@
ConfigFilePerm@CUPS_CONFIG_FILE_PERM@
DefaultShared@CUPS_DEFAULT_SHARED@
ImplicitClasses@CUPS_IMPLICIT_CLASSES@
LogFilePerm@CUPS_LOG_FILE_PERM@
MaxCopies@CUPS_MAX_COPIES@
UseNetworkDefault@CUPS_USE_NETWORK_DEFAULT@
+ + +

Directories

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Directories
DirectoryPurpose
@CUPS_SERVERROOT@The location of configuration files such as + printers.conf. Overridden by the ServerRoot + directive in cupsd.conf.
@bindir@The location of user programs.
@includedir@The location of CUPS include files.
@libdir@The location of CUPS library files.
@CUPS_SERVERBIN@The location of server programs such as backends and + filters. Overridden by the ServerBin + directive in cupsd.conf.
@sbindir@The location of administrator programs.
@CUPS_DATADIR@The location of data files such as fonts. Overridden + by the DataDir + directive in cupsd.conf.
@CUPS_DOCROOT@The location of documentation files. Overridden by + the DocumentRoot + directive in cupsd.conf.
@CUPS_LOCALEDIR@The location of localization files.
@CUPS_CACHEDIR@The location of cache files such as + ppds.dat and remote.cache. + Overridden by the CacheDir + directive in cupsd.conf.
@CUPS_LOGDIR@The location of the access_log, + error_log, and page_log files. + Overridden by the AccessLog, + ErrorLog, + PageLog, + directive in cupsd.conf.
@CUPS_STATEDIR@The location of the domain socket file and state data + such as authentication certificates. Overridden by the StateDir + directive in cupsd.conf.
@CUPS_REQUESTS@The location of spooled print jobs. Overridden by the + RequestRoot + directive in cupsd.conf.
+ + + diff --git a/doc/help/translation.html b/doc/help/translation.html new file mode 100644 index 0000000000..a4ada4a70e --- /dev/null +++ b/doc/help/translation.html @@ -0,0 +1,852 @@ + + + + Translating and Customizing CUPS + + + + +

Translating and Customizing CUPS

+ +

Thanks to its extensive use of templates, images, and message +catalogs, CUPS can be easily translated (or customized!) to suit +your needs. This help file will guide you through the CUPS +localization files so you can get the most out of it.

+ + +

Getting Started

+ +

Start by downloading the CUPS source code from www.cups.org. After you extract the files +from the source archive, you will want to copy the following +files and directories:

+ +
    + +
  • desktop/cups.desktop - the GNOME/KDE + desktop file pointing to the CUPS web interface
  • + +
  • doc/index.html - the web interface home + page
  • + +
  • locale/cups.pot - the message catalog
  • + +
  • templates/*.tmpl - the web interface + template files
  • + +
+ +

With the exception of the message catalogs and desktop file, +localization files are placed in subdirectories under the +doc and templates using the locale name. +Locale names are either ll or ll_CC, where +"ll" is the 2-letter language code and "CC" is the 2-letter +country code. CUPS does not currently use or support the newer +ll-region syntax for locale names.

+ +

All non-image files must be encoded using the UTF-8 character +set.

+ + +

Submitting a Translation for CUPS

+ +

To submit a translation for inclusion in CUPS, translate the +desktop file, all of the template files, the index.html.in +file, and the message catalog. Place these files in the correct +subdirectories in the CUPS source code archive and run the following +command to create an archive with your files:

+ +
+tar cvf ll_CC.tar.gz desktop/cups.desktop doc/ll_CC \
+    locale/cups_ll_CC.po templates/ll_CC
+
+ +

Replace "ll_CC" with the locale name for your translation. +Once you have created the archive, go to the CUPS Bugs +& Features page and submit a bug report, attaching the +translation to the report.

+ + +

The Desktop File

+ +

The desktop/cups.desktop file provides a link to +the CUPS web interface from desktop environments such as +GNOME and KDE. To translate this file, add two lines to the +bottom with the Name and Comment keys:

+ +
+Name[ll_CC]=Translation of "Manage Printing"
+Comment[ll_CC]=Translation of "CUPS Web Interface"
+
+ + +

The Home Page

+ +

The index.html file is a complete HTML file that is +displayed when the user visits "http://localhost:631/". Edit the +existing doc/index.html and save it in the +doc/ll_CC subdirectory so that the makefile can +install it. Run "make install" in the doc subdirectory +to test the new home page.

+ + +

Message Catalogs

+ +

CUPS message catalogs are GNU gettext ".po" text files that +provide a list of localized message strings for the CUPS +software. Message catalogs are named cups_ll.po or +cups_ll_CC.po, where "ll" is the standard 2-letter +abbreviation for the language and "CC" is the standard 2-letter +abbreviation for the country.

+ +

When translating a new message catalog, copy the +cups.pot message catalog file in the locale +subdirectory of the CUPS source code. For example, to start +translating the message catalog to Canadian French, you would +type the following commands:

+ +
+cd locale
+cp cups.pot cups_fr_CA.po
+
+ +

Alternatively, you can copy the existing cups_fr.po +message catalog and then make any necessary changes.

+ +

Once you have make your copy of the file, edit it using your +favorite text editor or translation program to translate the text +to the desired language.

+ +

Then validate your translation using the locale/checkpo utility:

+ +
+cd locale
+./checkpo cups_ll_CC.po
+
+ +

After fixing any errors in your translation, add your locale to the LANGUAGES +variable in the Makedefs file and run the "make +install" command in the locale subdirectory to test +the translation.

+ + +

Template Files

+ +

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.

+ +

Template files are HTML files with special formatting +characters in them that allow substitution of variables and arrays. +The CUPS CGI programs (admin.cgi, +classes.cgi, help.cgi, +jobs.cgi, and printers.cgi) use these +template file to provide dynamic content for the web interface. +Template files are installed in the +/usr/share/cups/templates directory by default. Table +2 lists the various template files and their purpose.

+ +

Translated versions of the template files should be saved in +the templates/ll_CC subdirectory. For example, +Canadian French template files should be saved in the +templates/fr_CA subdirectory. After you have +translated all of the templates, add the locale to the +LANGUAGES variable in the +Makedefs file and run "make install" in the +templates subdirectory to test the translation.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 2: Web Interface Template Files
FilenamePurpose
add-class.tmplThis is the initial form that is shown to add a new + printer class.
add-printer.tmplThis is the initial form that is shown to add a new + printer.
add-rss-subscription.tmplThis is the form that is shown to add a new RSS subscription.
admin.tmplThis is the main administration page.
choose-device.tmplThis is the form that shows the list of available + devices.
choose-make.tmplThis is the form that shows the list of available + manufacturers.
choose-model.tmplThis is the form that shows the list of available + printer models/drivers.
choose-serial.tmplThis is the form that allows the user to choose + a serial port and any options.
choose-uri.tmplThis is the form that allows the user to enter + a device URI for network printers.
class-added.tmplThis template shows the "class added" message.
class-confirm.tmplThis is the template used to confirm the + deletion of a class.
class-deleted.tmplThis template shows the "class deleted" message.
class-jobs-header.tmplThis template shows the "jobs" header for jobs in a + class.
class-modified.tmplThis template shows the "class modified" message.
classes.tmplThis template shows one or more printer classes.
classes-header.tmplThis template shows the "showing N of M classes" header in + the class list.
edit-config.tmplThis is the cupsd.conf editor page.
error.tmplThis template displays a generic error message.
error-op.tmplThis is the "unknown operation" error page.
header.tmplThis template is used as the standard header on all dynamic + content.
help-header.tmplThis is the top part of the help page.
help-printable.tmplThis is the standard page header for the printable + version of help files.
job-cancel.tmplThis template shows "job canceled".
job-hold.tmplThis template shows "job held".
job-move.tmplThis template shows the move-job form.
job-moved.tmplThis template shows "job moved".
job-release.tmplThis template shows "job released".
job-restart.tmplThis template shows "job reprinted".
jobs.tmplThis template is used to list the print jobs on a server, + class, or printer.
jobs-header.tmplThis template shows the "showing N or M jobs" header in the + jobs list.
list-available-printers.tmplThis template shows a list of new printers that have been found.
maintenance.tmplThis template shows "maintenance commands sent".
modify-class.tmplThis template is used as the first form when modifying a + class.
modify-printer.tmplThis template is used as the first form when modifying a + printer.
norestart.tmplThis template shows "server not restarted because no + changes were made to the configuration".
option-boolean.tmplThis template is used to select a boolean PPD option.
option-conflict.tmplThis template shows the conflicting options.
option-header.tmplThis template is used to start a PPD option group.
option-pickmany.tmplThis template is used to select a multi-valued PPD option.
option-pickone.tmplThis template is used to select a single-valued PPD option.
option-trailer.tmplThis template is used to end a PPD option group.
pager.tmplThis template shows the previous/next pager bar.
printer-accept.tmplThis template shows "printer now accepting jobs".
printer-added.tmplThis template shows "printer added".
printer-configured.tmplThis template shows "printer configured".
printer-confirm.tmplThis template asks the user to confirm the deletion + of a printer.
printer-default.tmplThis template shows "default printer set".
printer-deleted.tmplThis template shows "printer deleted".
printer-jobs-header.tmplThis templates shows the "jobs" header for jobs on a + printer.
printer-modified.tmplThis template shows "printer modified".
printer-purge.tmplThis template shows "printer has been purged of all jobs".
printer-reject.tmplThis template shows "printer now rejecting jobs".
printer-start.tmplThis template shows "printer started".
printer-stop.tmplThis template shows "printer stopped".
printers.tmplThis template is used to list information on one or more + printers.
printers-header.tmplThis template shows the "showing printer N of M" header in + the printers list.
restart.tmplThis template shows "server restarting".
samba-export.tmplThis template shows the export printers to Samba form.
samba-exported.tmplThis template shows "printers exported to Samba".
search.tmplThis template shows the search form.
set-printer-options-header.tmplThis template shows the first part of the set printer options + form.
set-printer-options-trailer.tmplThis template shows the last part of the set printer options + form.
subscription-added.tmplThis template shows "subscription ... added".
subscription-canceled.tmplThis template shows "subscription #NNN canceled".
test-page.tmplThis template shows "test page printed".
trailer.tmplThis template is used as the standard trailer on all dynamic + content.
users.tmplThis template shows the set allowed users form.
+ +

Inserting Attributes and Values

+ +

Template files consist of HTML with variable substitutions for +named inside curly braces "{name}". Variable names are generally +the IPP attribute names with the hyphen ("-") replaced by the +underscore ("_") character. For example, the +job-printer-uri attribute is renamed to +job_printer_uri.

+ +

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 +&name; mechanism or prefix each special +character with the backslash ("\".)

+ +

You substitute the value of a variable using +{NAME} in your template file. If the variable is +undefined then the {NAME} string is output +as-is.

+ +

To substitute an empty string if the variable is undefined, +use {?NAME} instead.

+ +

Array Substitutions

+ +

The number of array elements can be inserted using +{#NAME}. If the array is undefined then 0 is output. +The current array element (starting at 1) is inserted with +{#}.

+ +

Arrays are handled using {[NAME] at the beginning +of a section and } 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 job_id array:

+ +
+<TABLE>
+<TR>
+	<TH>Job ID</TH>
+	<TH>Destination</TH>
+	<TH>Title</TH>
+</TR>
+
+{[job_id]
+<TR>
+	<TD>{?job_id}</TD>
+	<TD>{?job_printer_name}</TD>
+	<TD>{?job_name}</TD>
+</TR>
+}
+</TABLE>
+
+ +

Arrays can be nested, however all elements within the curly +braces ("{" and "}") are indexed using the innermost array.

+ +

Conditional Tests

+ +

Templates can also test variables against specific values and +conditionally include text in the template. The format is:

+ +
+{variable?true:false}
+{variable=value?true:false}
+{variable!value?true:false}
+{variable<value?true:false}
+{variable>value?true:false}
+
+ +

where true is the text that is included if the +condition is true and false is the text that is +included if the condition is false. A value of # is +replaced with the current element number (starting at 1.) The +character after the variable name specifies the condition to +test. Table 3 shows the available test conditions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3: Template Substitution Conditions
CharCondition
?True if variable exists.
=True if variable is equal to value.
!True if variable is not equal to value.
<True if variable is less than value.
>True if variable is greater than value.
+ +

CGI Programs

+ +

CUPS uses five CGI programs to manage the dynamic web +interfaces:

+ +
    + +
  • admin.cgi
  • +
  • classes.cgi
  • +
  • help.cgi
  • +
  • jobs.cgi
  • +
  • printers.cgi
  • + +
+ +

Each CGI program accepts standard form variables such as +OP for the operation to perform, +PRINTER_NAME for the printer or class name to +operate on, QUERY for any search words, +FIRST for the first class, job, or printer to +display, and ORDER to control the order that +classes, jobs, or printers are displayed.

+ +

In addition, the classes.cgi, +jobs.cgi, and printers.cgi programs +support a WHICH_JOBS variable to control which jobs +are displayed. Table 4 lists the supported values.

+ +
+ + + + + + + + + + + + + + + + + + + +
Table 4: WHICH_JOBS Values
WHICH_JOBS ValueDescription
allShow all jobs
completedShow completed jobs
not-completedShow active jobs
+ +

admin.cgi

+ +

The admin.cgi program handles all of the printer +and class administration functions and is run for all direct +accesses to the /admin resource. For most operations +it uses the PRINTER_NAME and OP form +variables to specify the action requested. Table 5 shows the +supported OP values.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 5: admin.cgi OP Values
OP ValueDescription
accept-jobsAccepts jobs on the named destination.
add-classAdds a new printer class.
add-printerAdds a new printer.
config-serverConfigures the server.
delete-classDeletes a printer class. The form variable CONFIRM + may be set to any value to bypass the confirmation page.
delete-printerDeletes a printer. The form variable CONFIRM + may be set to any value to bypass the confirmation page.
export-sambaExports printers to Samba.
find-new-printersFind new printers that have not yet been added.
modify-classModifies a printer class.
modify-printerModifies a printer.
purge-jobsPurges all jobs on the named destination.
redirectRedirects the web browser to the location referenced by + the URL form variable.
reject-jobsRejects new jobs on the named destination.
set-allowed-usersSets the allowed users for a destination.
set-as-defaultSets the default destination.
set-printer-optionsSets the default options for a printer.
set-sharingSets the printer-is-shared attribute for a destination.
start-classStarts the named class.
start-printerStarts the named printer.
stop-classStops the named class.
stop-printerStops the named printer.
+ +

classes.cgi

+ +

The classes.cgi program is responsible for +listing class information, including jobs destined for that +class. It is for all direct accesses to the /classes +resource and supports the optional form variables OP +and WHICH_JOBS. If no form variables are supplied +then the CGI lists all or a specific class and the active jobs on +each class. Table 6 shows the supported OP +values.

+ +
+ + + + + + + + + + + + + + + + + +
Table 6: classes.cgi OP Values
OP ValueDescription
move-jobsMoves the jobs on this class to another destination.
print-test-pagePrints the standard PostScript test page.
+ + +

help.cgi

+ +

The help.cgi program handles all of the on-line +help functions and is run for all direct accesses to the +/help resource.

+ + +

jobs.cgi

+ +

The jobs.cgi program handles all of the job +functions and is run for all direct accesses to the +/jobs resource. For most operations it uses the +JOB_ID, OP, and WHICH_JOBS +form variables to specify the action requested. Table 7 shows the +supported OP values.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 7: jobs.cgi OP Values
OP ValueDescription
cancel-jobCancels a job.
hold-jobHolds a job indefinitely.
move-jobMoves a job to another destination.
release-jobReleases a job for printing.
restart-jobRestarts/reprints a stopped, canceled, completed, or aborted + print job.
+ + +

printers.cgi

+ +

The printers.cgi program is responsible for +listing printer information, including jobs destined for that +printer. It is for all direct accesses to the +/printers resource and supports the optional form +variables OP and WHICH_JOBS. If no form +variables are supplied then the CGI lists all printers or a +specific printer and the active jobs on that printer. Table 8 +shows the supported OP values.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Table 8: printers.cgi OP Values
OP ValueDescription
clean-print-headsClean the print heads.
move-jobsMove all jobs to a different destination.
print-self-test-pagePrint a printer self-test page.
print-test-pagePrint a PostScript test page.
+ + + diff --git a/doc/help/whatsnew.html b/doc/help/whatsnew.html new file mode 100644 index 0000000000..9ffe6aedcf --- /dev/null +++ b/doc/help/whatsnew.html @@ -0,0 +1,204 @@ + + + + What's New in CUPS 1.4 + + + + +

What's New in CUPS 1.4

+ +

CUPS 1.4 adds over 67 changes and new features to CUPS 1.3.x. This page provides a high-level outline of these changes. If you have never used CUPS before, read the "Overview of CUPS" document instead.

+ +

Commands

+ +
    + +
  1. accept and reject; the accept and reject commands have been officially renamed to cupsaccept and cupsreject. The old names are still supported via symlinks.
  2. + +
  3. cupsdisable and cupsenable; the cupsdisable command now supports a --hold option to stop printing after the current job and the cupsenable command now supports a --release option to release pending jobs for printing.
  4. + +
  5. cupsfilter; the cupsfilter program now supports filtering of already-queued print job files and can also run printer-specific filters specified in the PPD file.
  6. + +
  7. cupstestdsc; the cupstestdsc utility has been improved to better detect problems with PostScript print files.
  8. + +
  9. cupstestppd; the cupstestppd utility has been improved to test new PPD keywords and better detect impossible contraints.
  10. + +
  11. lpadmin; the lpadmin command now supports options to hold and release new jobs on a printer or all printers.
  12. + +
  13. lpoptions; the lpoptions command now describes custom options and their parameters.
  14. + +
  15. lppasswd; the lppasswd program is no longer installed setuid by default.
  16. + +
  17. lpstat; the lpstat command now supports a -H option to show the current default server and no longer slows down when a printer is specified.
  18. + +
+ + +

Web Interface

+ +
    + +
  1. Look-n-feel; the web interface has been given a new look.
  2. + +
  3. PHP support; the "php-cgi" program is used, when available, to process PHP pages in the CUPS web interface.
  4. + +
  5. Printer configuration; improvements have been made to the add and modify printer pages.
  6. + +
  7. Printer options; the Set Default Options page now provides a "query" button that queries the default and installed options from the printer.
  8. + +
  9. Printer sharing; the "share printer" and "unshare printer" buttons are now only shown when printer sharing is enabled in the scheduler.
  10. + +
  11. Security; the web interface has been updated to support authentication for printing of test pages and RSS subscription operations.
  12. + +
  13. Server settings; the Administration page now provides access to common "advanced" server settings.
  14. + +
+ + +

Networking

+ +
    + +
  1. Bonjour (DNS-SD) printing support; a new mdns backend provides Bonjour-based printer discovery and the ipp, lpd, and socket backends now support Bonjour address resolution.
  2. + +
  3. Bonjour (DNS-SD) perforance tuning; the scheduler now only uses a single file descriptor for printer sharing. It previously used one per printer.
  4. + +
  5. Bonjour (DNS-SD) web interface registry; when remote access is enabled, the scheduler can register the web interface for easier access.
  6. + +
  7. LPD client support; the cups-lpd mini-daemon now provides the document-name for print jobs and supports specification of a CUPS server.
  8. + +
  9. PWG Port Monitor MIB; the snmp backend now supports the PWG Port Monitor MIB to better choose the device URI to use.
  10. + +
  11. SNMP-based monitoring; the ipp, lpd, and socket backends now report supply levels and printer status using SNMP queries.
  12. + +
+ + +

IPP Support

+ +
    + +
  1. IPP/2.x support; CUPS now conforms to the draft IPP/2.0 and IPP/2.1 specifications.
  2. + +
  3. CUPS-Add-Modify-Printer operation; the scheduler now supports setting the printer-state-reasons attribute using this operation.
  4. + +
  5. CUPS-Get-Document operation; the scheduler now supports a "get document" operation to download files from a print job.
  6. + +
  7. Device location; the scheduler and backend discovery interface now support a device-location attribute.
  8. + +
  9. Hold-New-Jobs and Release-Held-New-Jobs operations; the scheduler now supports the Hold-New-Jobs and Release-Held-New-Jobs operations.
  10. + +
+ + +

Scheduler

+ +
    + +
  1. Access control; the scheduler now supports multiple addresses in Allow and Deny lines. It also now returns a HTTP 403 (forbidden) status when a user authenticates successfully but is not allowed to perform an operation.
  2. + +
  3. Access logging; the scheduler now supports an AccessLogLevel directive to control what is logged in the access_log file.
  4. + +
  5. Configuration files; the default cupsd.conf file now provides an "authenticated" policy that can be used to require a username and password to print or cancel a job.
  6. + +
  7. Default LogLevel; the default LogLevel is now "warn" instead of "info".
  8. + +
  9. Automatic debug logging; the scheduler now records up to the last N (default 200) debug messages for failed print jobs.
  10. + +
  11. Default paper size; the scheduler now supports a DefaultPaperSize directive to override the default paper size defined by the locale or libpaper configuration.
  12. + +
  13. Encryption support; the scheduler now supports a SSLOptions directive to optionally support Windows clients in "FIPS" mode. It also now loads both the server and CA certificates (if present) from the ServerCertificate file.
  14. + +
  15. Error logging; the scheduler now logs unsuccessful operations as errors in the error_log file.
  16. + +
  17. Error policies; the scheduler now supports a retry-current-job error policy that retries the current job immediately.
  18. + +
  19. Fatal error handling; the scheduler now supports a FatalErrors directive to control which startup errors should be considered fatal.
  20. + +
  21. Filter command-line; the scheduer now passes the job-originating-host-name attribute as a CUPS option to filters and backends.
  22. + +
  23. Filter environment; the scheduler now includes CUPS_JOBTYPE, PRINTER_INFO, and PRINTER_LOCATION variables in the environment passed to filters and backends.
  24. + +
  25. Job progress; the scheduler now supports a job-media-progress attribute to track the printing progress of each page.
  26. + +
  27. MIME database; MIME types now support a priority attribute to override the default (alphabetical) rules of precedence.
  28. + +
  29. Page logging; the scheduler now supports a PageLogFormat directive to control the format of the page_log file.
  30. + +
  31. PAM support; the scheduler now sets more PAM attributes to better support third-party authentication schemes.
  32. + +
  33. PDF job ticket support; the scheduler now supports cupsJobTicket comments at the beginning of PDF print jobs.
  34. + +
  35. Performance tuning; the scheduler now coalesces configuration and state file changes to reduce the amount of disk activity and caches printer attributes to further reduce startup time.
  36. + +
  37. Printcap support; the scheduler no longer clears the printcap file when shutting down, and can now create XML "plist" printcap files as well.
  38. + +
  39. RSS subscriptions; the scheduler now starts the notifier for RSS subscriptions after creation so the feed is available immediately.
  40. + +
  41. Sandbox support; the scheduler now runs child processes using restrictive policies on Mac OS X for improved security and job isolation.
  42. + +
  43. Test option; the scheduler now supports a test mode via the "-t" option.
  44. + +
+ + +

Printer Drivers

+ +
    + +
  1. Device discovery; the cups-deviced helper now runs backends in parallel for faster discovery and streams the results of discovery as the backends provide them.
  2. + +
  3. Driver development kit; the CUPS DDK is now a standard part of CUPS.
  4. + +
  5. Driver information file support; the cups-driverd helper program now directly supports PPD compiler driver information files.
  6. + +
  7. Dynamic PPD support; drivers can now set PPD keywords dynamically using PPD: messages.
  8. + +
  9. Generic PostScript command filter; a new CUPS command file filter for PostScript printers provides auto-configuration, self-test page, and status and supply level reporting functions.
  10. + +
  11. New printer drivers; new generic PostScript and PCL drivers provide improved support for laser printers, the CUPS DDK drivers offer support for many HP DesignJet printers, and new label drivers offer support for Seiko and Tharo label printers.
  12. + +
  13. PJL support; the cupsPJLDisplay PPD attribute controls the PJL commands used to display the current user and job on the printer.
  14. + +
  15. PPD compiler improvements; the PPD compiler now supports Mac OS X .strings files, OID query strings, conditional directives, long file names, and a test mode. It also fixes many other bugs from the CUPS DDK 1.2.3 release.
  16. + +
  17. USB printer support; the usb backend now uses libusb when available to allow it to better work with third-party scanning and printing solutions.
  18. + +
+ + +

Print Filters

+ +
    + +
  1. Banner filter; the bundled banner ("job-sheets") pages are now generated using a new banner filter provides easier customization and better support for UTF-8 text.
  2. + +
  3. Image filters; the standard image filters now support image files larger than 2GB.
  4. + +
  5. PDF filter; the pdftops filter has been replaced with a wrapper program that runs the Xpdf, poppler, or Ghostscript PDF to PostScript utilities.
  6. + +
+ + +

CUPS API

+ +
    + +
  1. Backend API; a new cupsBackendReport function is provided to report a device from a backend and handles any needed quoting of the make-and-model, info, device-id, and location strings.
  2. + +
  3. Device discovery; the new cupsGetDevices function streams discovered devices to an application-provided callback function.
  4. + +
  5. IPP API; the IPP read and write functions no longer use a large stack-based buffer when reading and writing IPP attributes.
  6. + +
  7. PPD support; several new functions are provided: cupsGetPPD3, cupsResolveConflicts, ppdInstallableConflict, ppdLocalizeAttr, ppdLocalizeMarkerName and ppdPageSizeLimits.
  8. + +
  9. Side-Channel API; new cupsSideChannelSNMPGet and cupsSideChannelSNMPWalk functions allow printer drivers to do SNMP queries via the standard network backends.
  10. + +
  11. Streaming API; a new streaming request API provides asynchronous job creation and request submission.
  12. + +
+ + + + diff --git a/doc/id/index.html.in b/doc/id/index.html.in new file mode 100644 index 0000000000..93b4621e76 --- /dev/null +++ b/doc/id/index.html.in @@ -0,0 +1,107 @@ + + + + + Beranda - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Beranda    Administrasi    Kelas    Bantuan Langsung    Tugas    Pencetak  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS adalah sistem pencetakan berstandar dan berkode sumber terbuka, dikembangkan oleh +Apple Inc. untuk Mac OS® X dan sistem +operasi serupa UNIX® lainnya.

+ +
CUPS
+ + + +
+ +

CUPS bagi Pengguna

+ +

Ikhtisar CUPS

+ +

Opsi dan Pencetakan dari Baris Perintah

+ +

Apa yang Baru di CUPS 1.4

+ +

Forum Pengguna

+ +
+ +

CUPS bagi Administrator

+ +

Menambah Pencetak dan Kelas

+ +

Mengatur Kebijakan Operasi

+ +

Dasar Akunting Pencetak

+ +

Keamanan Server

+ +

Menggunakan Otentikasi Kerberos

+ +

Menggunakan Pencetak di Jaringan

+ +

Referensi cupsd.conf

+ +

Mencari Penggerak Pencetak

+ +
+ +

CUPS bagi Pengembang

+ +

Pengenalan untuk Pemrograman CUPS

+ +

API di CUPS

+ +

Penyaring dan Pemrograman Balik (Backend Programming)

+ +

API di HTTP dan IPP

+ +

API di PPD

+ +

API di Raster

+ +

Referensi Kompiler Berkas Penggerak PPD

+ +

Forum Pengembang

+ +
+ +
 
CUPS dan logo CUPS logo adalah merek dagang dari +Apple Inc. Hak cipta CUPS pada 2007-2011 Apple +Inc. Semua hak terpelihara.
+ + diff --git a/doc/images/color-wheel.png b/doc/images/color-wheel.png new file mode 100644 index 0000000000000000000000000000000000000000..301e3fd59adceacf495738adc24618e7f8a20b51 GIT binary patch literal 13148 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 z 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + Scheduler (cupsd) + + + + + Filter + PPD Filter + Backend + PortMonitor + + + + + + + JobFiles + Web Interface(CGI) + + + + + BerkeleyCommands + CUPSCommands + System VCommands + + + + + + + ConfigFiles + + + + + + + LogFiles + + Notifiers + EmailRSS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LPD Support(cups-lpd) + + + + Printer + + + + + + + + + + + + diff --git a/doc/images/cups-command-chain.png b/doc/images/cups-command-chain.png new file mode 100644 index 0000000000000000000000000000000000000000..a7218e5ce45e57783db68fb655cdd0de11d91749 GIT binary patch literal 14902 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + PPD + + + + OptionalCommandFilter + + + + + + + + + CommandFile + + + + + + Printer + + + + + OptionalPortMonitor + + + + + Backend + + + diff --git a/doc/images/cups-icon.png b/doc/images/cups-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5c0f6ff20b6a79d23874eb72563f4fdc32b6ae1e GIT binary patch literal 4888 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 B#y9`~ literal 0 Hc-jL100001 diff --git a/doc/images/cups-postscript-chain.svg b/doc/images/cups-postscript-chain.svg new file mode 100644 index 0000000000..d1e2d3e844 --- /dev/null +++ b/doc/images/cups-postscript-chain.svg @@ -0,0 +1,531 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + PPD + + + + + Printer + + + + + OptionalPortMonitor + + + + + Backend + + + + OptionalPostScriptFilter + + OptionalPostScriptFilter + + + + + + + + + + + + PrintFile + + + + + + + CUPSFilters + + + CUPSFilters + + + + + diff --git a/doc/images/cups-raster-chain.png b/doc/images/cups-raster-chain.png new file mode 100644 index 0000000000000000000000000000000000000000..5349bd9f573c0ffd8e630deb29a1c24f593da68c GIT binary patch literal 16916 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 literal 0 Hc-jL100001 diff --git a/doc/images/cups-raster-chain.svg b/doc/images/cups-raster-chain.svg new file mode 100644 index 0000000000..5130c81914 --- /dev/null +++ b/doc/images/cups-raster-chain.svg @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + PPD + + + + + Printer + + + + + OptionalPortMonitor + + + + + Backend + + + + OptionalPostScriptFilter + + + RequiredRasterFilter + + + + + + + + + + + + + PrintFile + + + + + + + CUPSFilters + + + CUPSFilters + + + + + diff --git a/doc/images/cups.png b/doc/images/cups.png new file mode 100644 index 0000000000000000000000000000000000000000..5c0f6ff20b6a79d23874eb72563f4fdc32b6ae1e GIT binary patch literal 4888 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + CUPS Icon + + + Michael Sweet + + + + + Apple Inc. + + + + + + + + + + + + + + + + + + + + diff --git a/doc/images/generic.png b/doc/images/generic.png new file mode 100644 index 0000000000000000000000000000000000000000..2abe9de9ec6a3f00e2ebb2649aa3e3b0ade4037c GIT binary patch literal 16913 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 literal 0 Hc-jL100001 diff --git a/doc/images/left.gif b/doc/images/left.gif new file mode 100644 index 0000000000000000000000000000000000000000..e82004257b70460672d89924f77a284f09ea1e28 GIT binary patch literal 1492 zc-r05{Z~?V90%~rK?|{|88vO%pyABwY}VY4Eo)|`WY&PJtm8T=F%jiBm1A^7g)5K( zW)P*>>ImUPe8i_rt>i%_rlyISc{D*6_T*z)_Cwpf_+RYx{(Rr>`w!gkqhW#j;(`G@ zU~32B;^N}t<0%vhl}b%WNTAVZiHV7HIz1^ViNRo`q@<*#rlzH(rKhJenaqrgjEfg9 zUb=KCGc%LTW@lw(WoKvSy?uRs zPo6yK@9!TN7#JKJG((2WLqkKu!^0yZBhMhC&qhZ_pF_r;kByCuPmE7YOuT?hzL=bx zv{)=wt95E>YI=J5AIMAS*4S)t!DEBX%-G;SYxn9ET<}6(!w>cbzBl%=(edydXFwjPM#7-aH_EDF?s7rxWgcb_KuLz z)&W2$<_jS*QBX#_`xp0c`3ZAnbOYVzXWMY~x&3-!bzXUtADKdOG(}UQFx!vidHIpM zurje9F)Jd;%@rShrP-wbe9tRAcqTD6SQ|D^4&r>mW&|^*GooJT5&DQ~Lrx?)_ZaR1vgo+-Bq zcQ?;iMgGPe6p@YYZ0Cn(s?FE+M(7l!tWa9e7EI^N}7P6cykmk)B{% zxK7_T6!F540xh#AdVf!at*DGn>bn$KAYw{eH;k&6@OBG=T<^U~5XL ccyVV59=z-oFp|8~8)&Oq>I-_|RqO>aW*Ay*Y#!gJo8an2+e!3wE1DqS&sMam1Md^U z3|9kM1=wS6 zkyy#fmdl_G;@BBWHOg7|1)vk_kz)X}mdD)Bd5*epyu$z=k(;n9Z2byoW9@q%9Q$Nu z0cWe3|9leD0*SU|;Y(88ySM4yea*XDwl|PF>TySS0AQN5e0FN_#gFHP-X1&m*6=gD zKkNc{mfSrs@aW6_cRC*FpMBlw#fQOzCIJRXUC*wL2X^msJlu6pTcv;pDX#(?A-2=A zCxfq@99f(>JBOE#90l-@T31)|{ZDt^6*$t@%^uJ~@(%$lAXX7=^4s}3^t6^J{Di#a zw_bruyhl3=+9B-7_W+#14_HX6KoV9}mS|+U~ zRfk%LNmRDWT7)L^IeShM)!aWEv)PPlS2dc==$KA3EYh@)c3_xFr+JtXQVs-lKju_C z(Y}U7nh+AKHIdNMiFll+<3gNmQ3S;yYgCCT?E5sP#5hJ{I!2;V#3GFd5!M!tgn2p~ zj_4?}xPYyB}WFleaCC)>{xWdy0 zAu&bagU5sz4-FooLe#-&(dUnZOK9SuNag*QlVpk4WJ%&%C7ll{ZQ?^@UE-B%oR66J z=kH7QB`pbOk<>>|l#ojU z#b6*(!Y5D+QRtlf2N{M&iZm>Q9h<0-WfKK!Oh}XybY0{MK`N+NP8tRkGt~tC1zFMU I?_CH00G^a!ApigX literal 0 Hc-jL100001 diff --git a/doc/images/raster-organization.png b/doc/images/raster-organization.png new file mode 100644 index 0000000000000000000000000000000000000000..c390f4144deee31bf5abb3c7f9a1c47a06ba4091 GIT binary patch literal 20974 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 A<^TWy literal 0 Hc-jL100001 diff --git a/doc/images/raster-organization.svg b/doc/images/raster-organization.svg new file mode 100644 index 0000000000..8f611f266f --- /dev/null +++ b/doc/images/raster-organization.svg @@ -0,0 +1,378 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + Synchronization Word + + + Page Header 1 Page Bitmap 1 + + + + Page Header N Page Bitmap N + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Synchronization Word + + + Page Header 1 Page Bitmap 1 + + + + Page Header N Page Bitmap N + + + + + + diff --git a/doc/images/raster.png b/doc/images/raster.png new file mode 100644 index 0000000000000000000000000000000000000000..17ba3b230885d209f95cf1b36a6e03e296af8fd8 GIT binary patch literal 37656 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 literal 0 Hc-jL100001 diff --git a/doc/images/raster.svg b/doc/images/raster.svg new file mode 100644 index 0000000000..58277e70c6 --- /dev/null +++ b/doc/images/raster.svg @@ -0,0 +1,386 @@ + + + + + + + + + image/svg+xml + + + + + + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + + + BackSide + Normalfalse + Normaltrue + ManualTumblefalse + ManualTumbletrue + Rotatedfalse + Rotatedtrue + Flippedfalse + Flippedtrue + + diff --git a/doc/images/right.gif b/doc/images/right.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ebe464332e62bea0ed1ac92853bcbf479a094db GIT binary patch literal 341 zc-mFZzb^w(0KoBUl_D5uqC)%@P0*mIzAh}9P7;GfB4L%7G!ltFKs9 zNkk;3s&G=hd++Yv&wKCAS*X!x{BGY|erZ0v5z&UVv#bUoa$O;%q?8(_p`_xRyERgp z&?J-?hM|;XjMkEa9n&;}@4$rc?fnf|2oq9zDODyI$Fh(R zoHC|==$_{b&IzT}YPI}YmadC2K@jP>E`(5?60UHi>-#<-1Y>O5HbRIoW?7cwI7%r9 z;m?2LTFu|fLc`u|=fm0kR5LhP$!%FX2la=sL$rQzv|T)hiOb{U>Hg>Abu3)8<1OHM zp?Fs+T-~&3PmALnksdJHJQ?qfHYJm*nfeR}w}nA86ao_iBl)>5&|B9Eri*K-RAF}} ZJp=mFo3mrf%k7<`Lx~9J8*E(EvcD`S-G~4H literal 0 Hc-jL100001 diff --git a/doc/images/sample-image.png b/doc/images/sample-image.png new file mode 100644 index 0000000000000000000000000000000000000000..f78760e071d5b75a28ca417ba47fea8d91671d25 GIT binary patch literal 3541 zc-rNcYfw{X8po4ENC_9irYe+H6I>&>ZV9?BV7VkNs9apkf?CU@B1|UT7Cl5kqi;fC5b|2;~wk0TKi;fgt2~PR`jAr?VfNo$2iCbY|WC z@P0VwopgMLV&0UO6L8qXijK>@G zbRX3aNSRRPC5G3E6OFCSPPB$AE}LBToM9AgXi(IUYNn~~Z&qDg>GLape=kCR|0L6q zlis?8b0ab?piD(<@pGnRkUypq{|0^M{bU0}Ogm*GwfF&9K#jpAQuJiI5;@Al^_>)|8ewz{%p_Cen;({38eBQQrU90XSpJw z5a!(WBzZe;^{!6(gHU*Zva)Io@#EJD)8!6#$2xq)Wbgd1d>gLUxIQ@W`%Q-gjFuf` z8+V+P-38Y>ICRiYl|``}G{7n{8NKAR@z>#GGEqv-mmVQ#YPljq-Q;7OAmziz_l^(< zuh-fa@qposhCp!L85Oa0w}d#W(o~`?7c7nR)g!LFTZ+3R!ROij5sO5mxm2mA;u930DVZZ}QVD-S6rl>gt^Sy(a#u z6KD@y%I<e6Pd-V`DuIhD}3Kvi#&Cy+^G76+C_DoS!`zV*vA?(HtVvO5hCKozNkbLp68J|~ew zndoBDe3=ST^i_>NXXi2VMqA9+zxEX&}*_~WkdwI-S zZZwBdl2DN3G~rmn8Ro5##R1WZo_Acs87u{9-aw=Llo2@W$SkqAcM+C`NE>yFos+5# zZ%i11AxH|8*PPLCPK?d_%+aYp5r2nf=@`~U1xU-{6d>)EZLuRY=Xvy7qjxndSZL-q zEr{Vq8df>BdJdoZueRLFel|z#~5AF{FPROLmEm9S%r|A5zlU%dYLcES`dDRp~>+ zCjv2q{lI=2Z zbY#!MN?3x{iN47;%nwgqtOXl*u^IB5M&0lo)Ip0)sXD~Zd@%%E9JjC^p>28B$NL_d zr8>}(N08+$pOTZ(s7w7uB?LdA=EF}eFVzn8K=HZ)er=y^v-N^;#Ou7eZ{$83q*Jvc z5-)^n!E8&SL4M9sZEuVqAUN%GFn-iSBVEL0Xyx_y_Wumy3y>hZBG)zU;xn=Oz%zs8 zCWBnQY%`j;mbSbr|H9Fj-H{o0WF8mJhilnewg@dy2uirt zH|I(_%BG2{~3&U<5-x4YOBR%5l?hs)}@|Zv4ir&(u_Kq`$E8-h3u?aM z`xW%5i&)@`wkR`#3&RH+vr0ge4L^qD?O;e`aLy{Xkv>}>+sQpBQiete{t8dcJi9G# zZ3-PKkjo7w4cqgnrbzja8VXL^I@oqqiJV5=HTgOd)BlllVQ#!Vx!&t(9sTCL3Pfr> zJr;)S1Li+S{d!*u{qLBGk1j{;qbQf{+De!H&sD|C5ft>bp~1l^uq|wLlP>K=BP)I( zq+4nY*Yf?8IyDl7wB>#Ea$VrC4Pl6V%Jf4Pxz;!b49tpcn=@Im{!XcNJ+6S>w)gU$ zaT8RohX#L`6vOKOi%B6C2i%t~%!&v3=I^9gC@e+B*b7EcNa4$ucl4@9(SQi70B!V; zhBT`D`Z~GV$ih%~qOmszJf_Q{3}ubgR5X>)^%i3wlkvl@`EohUTyXb}>Q(;``q2pA zQqQ8oTds)q19nR{Hh1)if<8dUHrP4X$cWZb-ty&`eCFt_5P&r8w6F^hsU$r^1zOf* zo=+ftF|*NX2_~J_bqVJaft!gz$xk)Lm{B{*<`GNaJ=mnFO^a@(lPxCct48MEj(}IX zE;Kb23IZ=6wIjp4?WNigODTwjW(72135}T^hK?O;h`=@y`da1tt-#*h#O?Uc1|e!& LY{a$S2u}V3{-81j literal 0 Hc-jL100001 diff --git a/doc/images/sel.gif b/doc/images/sel.gif new file mode 100644 index 0000000000000000000000000000000000000000..36b16bf69c82311944f29eb457db67bada16d82c GIT binary patch literal 362 zc-jGK0hRtoNk%v~VITk`0E8L<($dn|+1cRW;O6G$>FMd}>gwz3>+J08?d|RE?(XmJ z@9^;O@$vEU^78ZZ^Yrxe_4W1k_V)Mp_xSku`T6TbqLDK%+1cv%nH)e)YaD4)L7cvRSn+X;Njxq;1A~K z=;`X~=wR;eT@v#1^!4`l^c4F0{Qds_{D24?*yDo1g9sBUT!;{j!-r*1Nt{@UmBot~ IF@^vDJGY4K7XSbN literal 0 Hc-jL100001 diff --git a/doc/images/smiley.jpg b/doc/images/smiley.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0076fae2d11978f27ec632236d0c3ce2de771b2f GIT binary patch literal 14120 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 literal 0 Hc-jL100001 diff --git a/doc/images/unsel.gif b/doc/images/unsel.gif new file mode 100644 index 0000000000000000000000000000000000000000..10477fe55faa5da33d2f7a87dd3f18515139a98a GIT binary patch literal 127 zc-nLKbh9u|RA5kHIK;|u_1e{E&!4|~_3HEI&p&_u{0{><3_t)<T4%}S)%A3T9(7t)Q0Jw0b~O5<>kq2y``70_e|+wB z?{D(DB*Ur_h(N@NAaiqb2!hPa%(&g|si~=?q@?=#dfz55FHbI)4-E}@JRY%F+}GC! z0MP68<>lpb|L29w(HV&w*2fz&6C+pZFhAevkVgQ)kvT-|n~`}2g4ar=D9R7{b^uK< zkynjfgDJtTscYUL(V5F7!`QnCb}#&nlRkG|Y`mBEuq(5ln|)8V(P2N670Unkw#il) zclZWD?VvN}>8v;*S+C2vqi0U=GXz+N1Rl01Zc9yG-OUeo~@y*-Ae%R=TY zemL^v-z_`lEf%h9RY!u6yl#YTqwa~>ae=>fFwkr*mrL5?OTsuQ-gfn#HRU)-9)iPl zV@asZTeIFJh7P~F&}N(kz`OF&H_qLg#9KQ2K{{G2!*I$XcHoqY(48W&ln(& z_(A05AZgefkRnn`Rg-sg63x5pOl4B8JGBx8B>miAX$Ri@lx zt!o#`a>a6&y)muY7Hh1I{pT)UMEfw#5He*}_K`}|xrDx%)v4tiBdr<%6xpJiAi%F2 zx58*aTXy(w7d0Z{@ZEFPljOBy=E+ROem&{9edJKk%tq~FDW9ZOYT#4?OcAavl2tt0 ztlh0LZtLE)&rPTGw7H9nje7kN{eqN=Kfg#a-$h1Von7Xmv@D^SF%N=iJ~QZ2fXF`5 z^i)RNQRe1{{u`W$_iw_nfK!Wqs#*+#?)LvUQuZeE{l=HlB8zkLfBB{@$8|Ph>kGM{ zjC;8zMXRkfKi%xw(ipnewO`+}FLXgb<2>MfwGUvIk&fA*2^FjaoK`J!&a|(Eazm93t*-@o*W=#Yj!$i zr38VOWLUHeQA99GWxIwTk@T{PU3`MBwCqFx!B&XWuCMS`bb_G`OL5S36*z1 z7MpluzthGgD-`L=Z&|Cha{0~2T#qjJOBv_SVcbao@!Fw$r4%}?6_|qRY_Z)s*+G(3 z4{B740tg~|c_|O_2{R#7DisWY5!-har*?tXwZ(-3Vuc{NGL~$UFRZEkOM|M^d!&j9 zl}GW|6jLCIkob*C-^m~SbX`e#2rv1-iLyFL{pkHvU2EAT{kWIQY1lZ3gW2c{=MySN zo5SRS8*ltzl`s^)kie4>td7rTcOqOkXaEd@3W=w}DI#K@hM!mxgH|a2rHry~df?3! z#=f-Udrwb&*{*);{O=?+R|Fp ze`wTcJ*r3NC(u0uy2EtI!MM-&+#L4XWUy^EN8fv~e;Mr^Fl|Qcn?I-v_TcJ~%eVXk zJ>5q}J__*MSTsGU;ERZBW5Y|OfF^li)LM*SNt|Y=NEIN2s2k-8Eh?I?#qrg!H(ZWk zI~LZ|{H3WVI3d4Hji$n?g15a@OjNHqtKgv^W|8gT>Og_}wHdH3FGM$9ZA>sonD`xo zUDw6<*D0A>EdHKp3zF3XIvvJL&bkD~^VqNigw5nZAk2!^Gq?}KT1qV_Br~?^YFVc; z^xwOzWU4#^lsXxuPo+YnT5&o!wadVeE%7tcDt~v&Zqr$HZ%{|`_sb<~sAgN+*{=dc z^xIX|UO);JT literal 0 Hc-jL100001 diff --git a/doc/images/webinterface.png b/doc/images/webinterface.png new file mode 100644 index 0000000000000000000000000000000000000000..feca5d66abd4e70a33567b88f9491a2558b04628 GIT binary patch literal 150003 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 axVBZc@wF9zru|_H|6_Ow_7}mxCHg;iCHN}< literal 0 Hc-jL100001 diff --git a/doc/index.html.in b/doc/index.html.in new file mode 100644 index 0000000000..26f8de13b8 --- /dev/null +++ b/doc/index.html.in @@ -0,0 +1,107 @@ + + + + + Home - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Home    Administration    Classes    Online Help    Jobs    Printers  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS is the standards-based, open source printing system developed by +Apple Inc. for Mac OS® X and +other UNIX®-like operating systems.

+ +
CUPS
+ + + +
+ +

CUPS for Users

+ +

Overview of CUPS

+ +

Command-Line Printing and Options

+ +

What's New in CUPS 1.4

+ +

User Forum

+ +
+ +

CUPS for Administrators

+ +

Adding Printers and Classes

+ +

Managing Operation Policies

+ +

Printer Accounting Basics

+ +

Server Security

+ +

Using Kerberos Authentication

+ +

Using Network Printers

+ +

cupsd.conf Reference

+ +

Find Printer Drivers

+ +
+ +

CUPS for Developers

+ +

Introduction to CUPS Programming

+ +

CUPS API

+ +

Filter and Backend Programming

+ +

HTTP and IPP APIs

+ +

PPD API

+ +

Raster API

+ +

PPD Compiler Driver Information File Reference

+ +

Developer Forum

+ +
+ +
 
CUPS and the CUPS logo are trademarks of +Apple Inc. CUPS is copyright 2007-2011 Apple +Inc. All rights reserved.
+ + diff --git a/doc/it/index.html.in b/doc/it/index.html.in new file mode 100644 index 0000000000..f65954f034 --- /dev/null +++ b/doc/it/index.html.in @@ -0,0 +1,107 @@ + + + + + Home - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Home    Amministrazione    Classi    Guida    Stampe    Stampanti  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS è un sistema di stampa basato su standard, open source sviluppato da +Apple Inc. per Mac OS® X e +altri sistemi UNIX® e derivati.

+ +
CUPS
+ + + +
+ +

CUPS per utenti

+ +

Panoramica di CUPS

+ +

Stampa e opzioni da riga di comando

+ +

Cosa c'è di nuovo in CUPS 1.4

+ +

Forum degli utenti

+ +
+ +

CUPS per amministratori

+ +

Aggiungere stampanti e classi

+ +

Gestire i criteri di funzionamento

+ +

Basi di controllo di accesso alle stampanti

+ +

Sicurezza del server

+ +

Utilizzare l'autenticazione Kerberos

+ +

Utilizzare stampanti di rete

+ +

Riferimenti al cupsd.conf

+ +

Trovare driver per le stampanti

+ +
+ +

CUPS per sviluppatori

+ +

Introduzione alla programmazione di CUPS

+ +

API di CUPS

+ +

Programmazione di filtri e motori

+ +

API HTTP e IPP

+ +

API PPD

+ +

API Raster

+ +

Riferimenti al file del compilatore di driver PPD

+ +

Forum degli sviluppatori

+ +
+ +
 
CUPS e il logo CUPS sono marchi di +Apple Inc. CUPS è un copyright 2007-2011 di Apple +Inc. Tutti i diritti sono riservati.
+ + diff --git a/doc/ja/index.html.in b/doc/ja/index.html.in new file mode 100644 index 0000000000..4271c7adf5 --- /dev/null +++ b/doc/ja/index.html.in @@ -0,0 +1,107 @@ + + + + + ホーム - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  ãƒ›ãƒ¼ãƒ     ç®¡ç†    ã‚¯ãƒ©ã‚¹    ãƒ˜ãƒ«ãƒ—    ã‚¸ãƒ§ãƒ–   ãƒ—リンター 
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS は、Mac OS® X およびその他の UNIX ç³» OS のために、 +Apple Inc. +によって開発された標準ベースのオープンソース印刷システムです。

+ +
CUPS
+ + + +
+ +

ユーザー向け

+ +

CUPS の概要

+ +

コマンドラインからの印刷とオプション

+ +

CUPS 1.4 の新機能

+ +

ユーザーフォーラム

+ +
+ +

管理者向け

+ +

プリンターとクラスの追加

+ +

操作ポリシーの管理について

+ +

プリンターアカウンティングの基本

+ +

サーバーのセキュリティー

+ +

Kerberos 認証の使い方

+ +

ネットワークプリンターの使い方

+ +

cupsd.conf リファレンス

+ +

プリンタードライバーの検索

+ +
+ +

開発者向け

+ +

イントロダクション

+ +

CUPS API

+ +

フィルタとバックエンドのプログラミング

+ +

HTTP と IPP の API

+ +

PPD API

+ +

ラスター API

+ +

PPD コンパイラー用ドライバー情報ファイル リファレンス

+ +

開発者フォーラム

+ +
+ +
 
CUPS and the CUPS logo are trademarks of +Apple Inc. CUPS is copyright 2007-2011 Apple +Inc. All rights reserved.
+ + diff --git a/doc/pl/index.html.in b/doc/pl/index.html.in new file mode 100644 index 0000000000..943cb9e966 --- /dev/null +++ b/doc/pl/index.html.in @@ -0,0 +1,107 @@ + + + + + Strona domowa - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  Strona domowa    Administracja    Klasy    Pomoc online    Zadania    Drukowanie  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS jest opartym na standardach systemem drukowania na licencji open source, tworzonym przez +Apple Inc. dla Mac OS® X i +innych systemów operacyjnych podobnych do Uniksa®.

+ +
CUPS
+ + + +
+ +

CUPS dla użytkowników

+ +

Przegląd CUPS

+ +

Drukowanie i opcje w wierszu poleceń

+ +

Co nowego w CUPS 1.4

+ +

Forum użytkowników

+ +
+ +

CUPS dla administratorów

+ +

Dodawanie drukarek i klas

+ +

Zarządzanie politykami operacji

+ +

Podstawy kont drukowania

+ +

Bezpieczeństwo systemu

+ +

Używanie uwierzytelniania Kerberosa

+ +

Używanie drukarek sieciowych

+ +

Informacje o cupsd.conf

+ +

Wyszukiwanie sterowników drukarek

+ +
+ +

CUPS dla programistów

+ +

Wprowadzenie do programowania CUPS

+ +

API CUPS

+ +

Programowanie filtrów i modułów przetwarzających

+ +

API HTTP i IPP

+ +

API PPD

+ +

API rastrowe

+ +

Informacje o kompilatorze plików informacji o sterownikach PPD

+ +

Forum programistów

+ +
+ +
 
CUPS i logo CUPS +są znakami handlowymi Apple Inc. CUPS +copyright 2007-2011 Apple Inc. Wszystkie prawa zastrzeżone.
+ + diff --git a/doc/robots.txt b/doc/robots.txt new file mode 100644 index 0000000000..45dcdc2210 --- /dev/null +++ b/doc/robots.txt @@ -0,0 +1,31 @@ +# +# "$Id: robots.txt 3494 2003-03-19 15:37:44Z mike $" +# +# This file tells search engines not to index your CUPS server. +# +# Copyright 1993-2003 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 +# + +User-agent: * +Disallow: / + +# +# End of "$Id: robots.txt 3494 2003-03-19 15:37:44Z mike $". +# + diff --git a/doc/ru/index.html.in b/doc/ru/index.html.in new file mode 100644 index 0000000000..7b2b745a20 --- /dev/null +++ b/doc/ru/index.html.in @@ -0,0 +1,103 @@ + + + + + Начало — CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + + + + + + +
+ + + + + + + + + + + + +
  ÐÐ°Ñ‡Ð°Ð»Ð¾    ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚рирование    Ð“руппы    Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ°    Ð—адания    ÐŸÑ€Ð¸Ð½Ñ‚еры  
+ + + + + +
+ +

CUPS @CUPS_VERSION@

+ +

CUPS — поддерживающая большинство стандартов, свободная подсистема печати, разрабатываемая компанией Apple Inc. для операционной системы Mac OS® X и других UNIX®-подобных операционных систем.

+ +
CUPS
+ + + +
+ +

CUPS for Users

+ +

Введение в CUPS

+ +

Печать из командной строки

+ +

Что нового в CUPS 1.4

+ +

Форум пользователей

+ +
+ +

CUPS для администраторов

+ +

Добавление принтеров и групп

+ +

Управление доступом

+ +

Использование ресурсов

+ +

Безопасность системы

+ +

Использование аутентификации Kerberos

+ +

Использование сетевых принтеров

+ +

Справочник по cupsd.conf

+ +

Поиск драйверов принтера

+ +
+ +

CUPS для разработчиков

+ +

Введение в разработку CUPS

+ +

CUPS API

+ +

Разработка фильтров и модулей

+ +

API доступа по HTTP и IPP

+ +

PPD API

+ +

Raster API

+ +

Справочник по компилятору PPD

+ +

Форум разработчиков

+ +
+ +
 
CUPS а также логотип CUPS являются зарегистрированными торговыми марками Apple Inc. Авторские права на CUPS принадлежат (2007-2011) компании Apple Inc. Все права защищены.
+ + diff --git a/driver/Dependencies b/driver/Dependencies new file mode 100644 index 0000000000..2111f79f0e --- /dev/null +++ b/driver/Dependencies @@ -0,0 +1,59 @@ +# DO NOT DELETE + +commandtoescpx.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +commandtoescpx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +commandtoescpx.o: ../cups/file.h ../cups/language.h driver.h ../cups/raster.h +commandtoescpx.o: ../cups/string.h ../config.h ../data/escp.h +commandtopclx.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +commandtopclx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +commandtopclx.o: ../cups/file.h ../cups/language.h driver.h ../cups/raster.h +commandtopclx.o: ../cups/string.h ../config.h ../data/pcl.h +rastertoescpx.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertoescpx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertoescpx.o: ../cups/file.h ../cups/language.h ../cups/raster.h +rastertoescpx.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h +rastertoescpx.o: ../config.h ../data/escp.h +rastertopclx.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertopclx.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertopclx.o: ../cups/file.h ../cups/language.h ../cups/raster.h +rastertopclx.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h +rastertopclx.o: ../config.h pcl-common.h ../data/pcl.h +pcl-common.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pcl-common.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +pcl-common.o: ../cups/file.h ../cups/language.h ../cups/raster.h pcl-common.h +pcl-common.o: ../cups/string.h ../config.h ../data/pcl.h +testcmyk.o: ../cups/string.h ../config.h driver.h ../cups/cups.h +testcmyk.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testcmyk.o: ../cups/array.h ../cups/file.h ../cups/language.h +testcmyk.o: ../cups/raster.h +testdither.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +testdither.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +testdither.o: ../cups/file.h ../cups/language.h ../cups/raster.h +testdither.o: ../cups/string.h ../config.h +testrgb.o: ../cups/string.h ../config.h driver.h ../cups/cups.h ../cups/ipp.h +testrgb.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h +testrgb.o: ../cups/file.h ../cups/language.h ../cups/raster.h +attr.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +attr.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +attr.o: ../cups/language.h ../cups/raster.h ../cups/string.h ../config.h +check.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +check.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +check.o: ../cups/language.h ../cups/raster.h +cmyk.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +cmyk.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +cmyk.o: ../cups/language.h ../cups/raster.h ../cups/string.h ../config.h +dither.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +dither.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +dither.o: ../cups/language.h ../cups/raster.h +lut.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +lut.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +lut.o: ../cups/language.h ../cups/raster.h +pack.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pack.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pack.o: ../cups/language.h ../cups/raster.h +rgb.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rgb.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +rgb.o: ../cups/language.h ../cups/raster.h +srgb.o: driver.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +srgb.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +srgb.o: ../cups/language.h ../cups/raster.h diff --git a/driver/Makefile b/driver/Makefile new file mode 100644 index 0000000000..8f017ace1d --- /dev/null +++ b/driver/Makefile @@ -0,0 +1,382 @@ +# +# "$Id$" +# +# Makefile for the CUPS base drivers. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 2002-2005 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Include standard definitions... +# + +include ../Makedefs + + +# +# Object files... +# + +LIBOBJS = \ + attr.o \ + check.o \ + cmyk.o \ + dither.o \ + lut.o \ + pack.o \ + rgb.o \ + srgb.o +OBJS = \ + commandtoescpx.o \ + commandtopclx.o \ + rastertoescpx.o \ + rastertopclx.o \ + pcl-common.o \ + testcmyk.o \ + testdither.o \ + testrgb.o \ + $(LIBOBJS) + +LIBTARGETS = \ + $(LIBCUPSDRIVER) \ + libcupsdriver.a +UNITTARGETS = \ + testcmyk \ + testdither \ + testrgb +FILTERS = \ + commandtoescpx \ + commandtopclx \ + rastertoescpx \ + rastertopclx +TARGETS = \ + $(LIBTARGETS) \ + $(FILTERS) + + +# +# Make everything... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: $(LIBTARGETS) + + +# +# Make unit tests... +# + +unittests: $(UNITTARGETS) + + +# +# Clean everything... +# + +clean: + $(RM) $(OBJS) core + $(RM) *.bck core.* + $(RM) $(TARGETS) $(UNITTARGETS) + $(RM) -r test + $(RM) libcupsdriver.so libcupsdriver.sl libcupsdriver.dylib + + +# +# Update dependencies... +# + +depend: + makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + $(INSTALL_DIR) $(SERVERBIN)/filter + for file in $(FILTERS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \ + done + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(FILTERS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + echo Installing header files in $(INCLUDEDIR)/cups... + $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups + $(INSTALL_DATA) driver.h $(INCLUDEDIR)/cups + + +# +# Install libraries... +# + +install-libs: $(INSTALLSTATIC) + echo Installing libraries in $(LIBDIR)... + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) $(LIBCUPSDRIVER) $(LIBDIR) + if test $(LIBCUPSDRIVER) = "libcupsdriver.so.1" -o $(LIBCUPSDRIVER) = "libcupsdriver.sl.1"; then \ + $(RM) $(LIBDIR)/`basename $(LIBCUPSDRIVER) .1`; \ + $(LN) $(LIBCUPSDRIVER) $(LIBDIR)/`basename $(LIBCUPSDRIVER) .1`; \ + fi + if test $(LIBCUPSDRIVER) = "libcupsdriver.1.dylib"; then \ + $(RM) $(LIBDIR)/libcupsdriver.dylib; \ + $(LN) $(LIBCUPSDRIVER) $(LIBDIR)/libcupsdriver.dylib; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(LIBCUPSDRIVER) $(SYMROOT); \ + fi + +installstatic: + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) -m 755 libcupsdriver.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcupsdriver.a + $(CHMOD) 555 $(LIBDIR)/libcupsdriver.a + + +# +# Uninstall... +# + +uninstall: + for file in commandtoescpx commandtopclx rastertoescpx rastertopclx; do \ + $(RM) $(SERVERBIN)/filter/$$file; \ + done + $(RM) $(LIBDIR)/libcupsdriver.1.dylib + $(RM) $(LIBDIR)/libcupsdriver.a + $(RM) $(LIBDIR)/libcupsdriver.dylib + $(RM) $(LIBDIR)/libcupsdriver_s.a + $(RM) $(LIBDIR)/libcupsdriver.sl + $(RM) $(LIBDIR)/libcupsdriver.sl.1 + $(RM) $(LIBDIR)/libcupsdriver.so + $(RM) $(LIBDIR)/libcupsdriver.so.1 + -$(RMDIR) $(LIBDIR) + $(RM) $(INCLUDEDIR)/cups/driver.h + -$(RMDIR) $(INCLUDEDIR)/cups + + +# +# Automatic API help files... +# + +apihelp: + mxmldoc --section "Programming" \ + --title "Printer Driver API" \ + --css ../doc/cups-printable.css \ + --header api-driver.header --intro api-driver.shtml \ + api-driver.xml \ + driver.h $(LIBOBJS:.o=.c) >../doc/help/api-driver.html + mxmldoc --tokens help/api-driver.html >../doc/help/api-driver.tokens + $(RM) api-driver.xml + +framedhelp: + mxmldoc --framed api-driver \ + --section "Programming" \ + --title "Printer Driver API" \ + --css ../doc/cups-printable.css \ + --header api-driver.header --intro api-driver.shtml \ + driver.h $(LIBOBJS:.o=.c) + + +# +# commandtopclx, the PCL command printer driver. +# + +commandtopclx: commandtopclx.o $(LIBCUPSDRIVER) ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ commandtopclx.o -L. -lcupsdriver $(LIBS) + + +# +# commandtoescpx, the ESC/P command printer driver. +# + +commandtoescpx: commandtoescpx.o $(LIBCUPSDRIVER) ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ commandtoescpx.o -L. -lcupsdriver $(LIBS) + + +# +# rastertoescpx, the ESC/P raster printer driver. +# + +rastertoescpx: rastertoescpx.o $(LIBCUPSDRIVER) ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertoescpx.o -L. -lcupsdriver \ + $(LINKCUPSIMAGE) $(LIBS) + + +# +# rastertopclx, the ESC/P raster printer driver. +# + +rastertopclx: rastertopclx.o pcl-common.o $(LIBCUPSDRIVER) \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertopclx.o pcl-common.o -L. -lcupsdriver \ + $(LINKCUPSIMAGE) $(LIBS) + + +# +# test, make a common test subdirectory for the other test programs. +# + +test: + if test ! -d test; then \ + rm -rf test; \ + mkdir test; \ + fi + + +# +# testcmyk, test cmyk separation functions. +# + +testcmyk: test testcmyk.o libcupsdriver.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testcmyk.o libcupsdriver.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + echo Running CMYK API tests... + ./testcmyk > test/testcmyk.log + + +# +# testdither, test dithering functions. +# + +testdither: test testdither.o libcupsdriver.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testdither.o libcupsdriver.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + echo Running dither API tests... + ./testdither > test/0-255.pgm 2>test/0-255.log + ./testdither 0 127 255 > test/0-127-255.pgm 2>test/0-127-255.log + ./testdither 0 85 170 255 > test/0-85-170-255.pgm 2>test/0-85-170-255.log + ./testdither 0 63 127 170 198 227 255 > test/0-63-127-170-198-227-255.pgm 2>test/0-63-127-170-198-227-255.log + ./testdither 0 210 383 > test/0-210-383.pgm 2>test/0-210-383.log + ./testdither 0 82 255 > test/0-82-255.pgm 2>test/0-82-255.log + ./testdither 0 510 > test/0-510.pgm 2>test/0-510.log + ./testdither 0 1020 > test/0-1020.pgm 2>test/0-1020.log + + +# +# testrgb, test RGB separation functions. +# + +testrgb: test testrgb.o libcupsdriver.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testrgb.o libcupsdriver.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + echo Running RGB API tests... + ./testrgb > test/testrgb.log 2>&1 || echo "RGB tests failed!" + + +# +# libcupsdriver.so.1, libcupsdriver.sl.1 +# + +libcupsdriver.so.1 libcupsdriver.sl.1: $(LIBOBJS) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) + $(RM) `basename $@ .1` + $(LN) $@ `basename $@ .1` + + +# +# libcupsdriver.1.dylib +# + +libcupsdriver.1.dylib: $(LIBOBJS) libcupsdriver.exp + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.0.0 \ + -compatibility_version 1.0.0 \ + -exported_symbols_list libcupsdriver.exp \ + $(LIBOBJS) $(LIBS) + $(RM) libcupsdriver.dylib + $(LN) $@ libcupsdriver.dylib + + +# +# libcupsdriver_s.a +# + +libcupsdriver_s.a: $(LIBOBJS) + echo Creating $@... + $(DSO) $(DSOFLAGS) -o libcupsdriver_s.o $(LIBOBJS) $(LIBS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcupsdriver_s.o + + +# +# libcupsdriver.la +# + +libcupsdriver.la: $(LIBOBJS) + echo Linking $@... + $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \ + -version-info 1:0 $(LIBS) + + +# +# libcupsdriver.a +# + +libcupsdriver.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# Include dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/driver/api-driver.header b/driver/api-driver.header new file mode 100644 index 0000000000..0f3937bc1d --- /dev/null +++ b/driver/api-driver.header @@ -0,0 +1,34 @@ + + +

Driver API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/driver.h
Library-lcupsdriver
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/driver/api-driver.shtml b/driver/api-driver.shtml new file mode 100644 index 0000000000..0e8bcff27b --- /dev/null +++ b/driver/api-driver.shtml @@ -0,0 +1,18 @@ + + +

Overview

+ +

The driver API provides common dithering, color conversion, and utility +functions for CUPS drivers.

diff --git a/driver/attr.c b/driver/attr.c new file mode 100644 index 0000000000..320e1c7da6 --- /dev/null +++ b/driver/attr.c @@ -0,0 +1,109 @@ +/* + * "$Id$" + * + * PPD attribute lookup routine for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsFindAttr() - Find a PPD attribute based on the colormodel, + * media, and resolution. + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" +#include + + +/* + * 'cupsFindAttr()' - Find a PPD attribute based on the colormodel, + * media, and resolution. + */ + +ppd_attr_t * /* O - Matching attribute or NULL */ +cupsFindAttr(ppd_file_t *ppd, /* I - PPD file */ + const char *name, /* I - Attribute name */ + const char *colormodel, /* I - Color model */ + const char *media, /* I - Media type */ + const char *resolution, /* I - Resolution */ + char *spec, /* O - Final selection string */ + int specsize) /* I - Size of string buffer */ +{ + ppd_attr_t *attr; /* Attribute */ + + + /* + * Range check input... + */ + + if (!ppd || !name || !colormodel || !media || !resolution || !spec || + specsize < PPD_MAX_NAME) + return (NULL); + + /* + * Look for the attribute with the following keywords: + * + * ColorModel.MediaType.Resolution + * ColorModel.Resolution + * ColorModel + * MediaType.Resolution + * MediaType + * Resolution + * "" + */ + + snprintf(spec, specsize, "%s.%s.%s", colormodel, media, resolution); + fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + snprintf(spec, specsize, "%s.%s", colormodel, resolution); + fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + strlcpy(spec, colormodel, specsize); + fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + snprintf(spec, specsize, "%s.%s", media, resolution); + fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + strlcpy(spec, media, specsize); + fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + strlcpy(spec, resolution, specsize); + fprintf(stderr, "DEBUG2: Looking for \"*%s %s\"...\n", name, spec); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + spec[0] = '\0'; + fprintf(stderr, "DEBUG2: Looking for \"*%s\"...\n", name); + if ((attr = ppdFindAttr(ppd, name, spec)) != NULL && attr->value != NULL) + return (attr); + + fprintf(stderr, "DEBUG2: No instance of \"*%s\" found...\n", name); + + return (NULL); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/check.c b/driver/check.c new file mode 100644 index 0000000000..d7ceb3d448 --- /dev/null +++ b/driver/check.c @@ -0,0 +1,111 @@ +/* + * "$Id$" + * + * Byte checking routines for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsCheckBytes() - Check to see if all bytes are zero. + * cupsCheckValue() - Check to see if all bytes match the given value. + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" + + +/* + * 'cupsCheckBytes()' - Check to see if all bytes are zero. + */ + +int /* O - 1 if they match */ +cupsCheckBytes(const unsigned char *bytes, /* I - Bytes to check */ + int length) /* I - Number of bytes to check */ +{ + while (length > 7) + { + if (*bytes++) + return (0); + if (*bytes++) + return (0); + if (*bytes++) + return (0); + if (*bytes++) + return (0); + if (*bytes++) + return (0); + if (*bytes++) + return (0); + if (*bytes++) + return (0); + if (*bytes++) + return (0); + + length -= 8; + } + + while (length > 0) + if (*bytes++) + return (0); + else + length --; + + return (1); +} + + +/* + * 'cupsCheckValue()' - Check to see if all bytes match the given value. + */ + +int /* O - 1 if they match */ +cupsCheckValue(const unsigned char *bytes, /* I - Bytes to check */ + int length, /* I - Number of bytes to check */ + const unsigned char value) /* I - Value to check */ +{ + while (length > 7) + { + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + if (*bytes++ != value) + return (0); + + length -= 8; + } + + while (length > 0) + if (*bytes++ != value) + return (0); + else + length --; + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/cmyk.c b/driver/cmyk.c new file mode 100644 index 0000000000..b5ab4ede4b --- /dev/null +++ b/driver/cmyk.c @@ -0,0 +1,1955 @@ +/* + * "$Id$" + * + * CMYK color separation code for CUPS. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsCMYKDelete() - Delete a color separation. + * cupsCMYKDoBlack() - Do a black separation... + * cupsCMYKDoCMYK() - Do a CMYK separation... + * cupsCMYKDoGray() - Do a grayscale separation... + * cupsCMYKDoRGB() - Do an sRGB separation... + * cupsCMYKLoad() - Load a CMYK color profile from PPD attributes. + * cupsCMYKNew() - Create a new CMYK color separation. + * cupsCMYKSetBlack() - Set the transition range for CMY to black. + * cupsCMYKSetCurve() - Set a color transform curve using points. + * cupsCMYKSetGamma() - Set a color transform curve using gamma and + * density. + * cupsCMYKSetInkLimit() - Set the limit on the amount of ink. + * cupsCMYKSetLtDk() - Set light/dark ink transforms. + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" +#include + + +/* + * 'cupsCMYKDelete()' - Delete a color separation. + */ + +void +cupsCMYKDelete(cups_cmyk_t *cmyk) /* I - Color separation */ +{ + /* + * Range check input... + */ + + if (cmyk == NULL) + return; + + /* + * Free memory used... + */ + + free(cmyk->channels[0]); + free(cmyk); +} + + +/* + * 'cupsCMYKDoBlack()' - Do a black separation... + */ + +void +cupsCMYKDoBlack(const cups_cmyk_t *cmyk, + /* I - Color separation */ + const unsigned char *input, + /* I - Input grayscale pixels */ + short *output, + /* O - Output Device-N pixels */ + int num_pixels) + /* I - Number of pixels */ +{ + int k; /* Current black value */ + const short **channels; /* Copy of channel LUTs */ + int ink, /* Amount of ink */ + ink_limit; /* Ink limit from separation */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) + return; + + /* + * Loop through it all... + */ + + channels = (const short **)cmyk->channels; + ink_limit = cmyk->ink_limit; + + switch (cmyk->num_channels) + { + case 1 : /* Black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = *input++; + *output++ = channels[0][k]; + + num_pixels --; + } + break; + + case 2 : /* Black, light black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = *input++; + output[0] = channels[0][k]; + output[1] = channels[1][k]; + + if (ink_limit) + { + ink = output[0] + output[1]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + } + } + + output += 2; + num_pixels --; + } + break; + + case 3 : /* CMY */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = *input++; + output[0] = channels[0][k]; + output[1] = channels[1][k]; + output[2] = channels[2][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + } + } + + output += 3; + num_pixels --; + } + break; + + case 4 : /* CMYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = *input++; + *output++ = 0; + *output++ = 0; + *output++ = 0; + *output++ = channels[3][k]; + + num_pixels --; + } + break; + + case 6 : /* CcMmYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = *input++; + *output++ = 0; + *output++ = 0; + *output++ = 0; + *output++ = 0; + *output++ = 0; + *output++ = channels[5][k]; + + num_pixels --; + } + break; + + case 7 : /* CcMmYKk */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = *input++; + output[0] = 0; + output[1] = 0; + output[2] = 0; + output[3] = 0; + output[4] = 0; + output[5] = channels[5][k]; + output[6] = channels[6][k]; + + if (ink_limit) + { + ink = output[5] + output[6]; + + if (ink > ink_limit) + { + output[5] = ink_limit * output[5] / ink; + output[6] = ink_limit * output[6] / ink; + } + } + + output += 7; + num_pixels --; + } + break; + } +} + + +/* + * 'cupsCMYKDoCMYK()' - Do a CMYK separation... + */ + +void +cupsCMYKDoCMYK(const cups_cmyk_t *cmyk, + /* I - Color separation */ + const unsigned char *input, + /* I - Input grayscale pixels */ + short *output, + /* O - Output Device-N pixels */ + int num_pixels) + /* I - Number of pixels */ +{ + int c, /* Current cyan value */ + m, /* Current magenta value */ + y, /* Current yellow value */ + k; /* Current black value */ + const short **channels; /* Copy of channel LUTs */ + int ink, /* Amount of ink */ + ink_limit; /* Ink limit from separation */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) + return; + + /* + * Loop through it all... + */ + + channels = (const short **)cmyk->channels; + ink_limit = cmyk->ink_limit; + + switch (cmyk->num_channels) + { + case 1 : /* Black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = *input++; + m = *input++; + y = *input++; + k = *input++ + (c * 31 + m * 61 + y * 8) / 100; + + if (k < 255) + *output++ = channels[0][k]; + else + *output++ = channels[0][255]; + + num_pixels --; + } + break; + + case 2 : /* Black, light black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = *input++; + m = *input++; + y = *input++; + k = *input++ + (c * 31 + m * 61 + y * 8) / 100; + + if (k < 255) + { + output[0] = channels[0][k]; + output[1] = channels[1][k]; + } + else + { + output[0] = channels[0][255]; + output[1] = channels[1][255]; + } + + if (ink_limit) + { + ink = output[0] + output[1]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + } + } + + output += 2; + num_pixels --; + } + break; + + case 3 : /* CMY */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = *input++; + m = *input++; + y = *input++; + k = *input++; + c += k; + m += k; + y += k; + + if (c < 255) + output[0] = channels[0][c]; + else + output[0] = channels[0][255]; + + if (m < 255) + output[1] = channels[1][m]; + else + output[1] = channels[1][255]; + + if (y < 255) + output[2] = channels[2][y]; + else + output[2] = channels[2][255]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + } + } + + output += 3; + num_pixels --; + } + break; + + case 4 : /* CMYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = *input++; + m = *input++; + y = *input++; + k = *input++; + + output[0] = channels[0][c]; + output[1] = channels[1][m]; + output[2] = channels[2][y]; + output[3] = channels[3][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + } + } + + output += 4; + num_pixels --; + } + break; + + case 6 : /* CcMmYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = *input++; + m = *input++; + y = *input++; + k = *input++; + + output[0] = channels[0][c]; + output[1] = channels[1][c]; + output[2] = channels[2][m]; + output[3] = channels[3][m]; + output[4] = channels[4][y]; + output[5] = channels[5][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3] + + output[4] + output[5]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + output[4] = ink_limit * output[4] / ink; + output[5] = ink_limit * output[5] / ink; + } + } + + output += 6; + num_pixels --; + } + break; + + case 7 : /* CcMmYKk */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = *input++; + m = *input++; + y = *input++; + k = *input++; + + output[0] = channels[0][c]; + output[1] = channels[1][c]; + output[2] = channels[2][m]; + output[3] = channels[3][m]; + output[4] = channels[4][y]; + output[5] = channels[5][k]; + output[6] = channels[6][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3] + + output[4] + output[5] + output[6]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + output[4] = ink_limit * output[4] / ink; + output[5] = ink_limit * output[5] / ink; + output[6] = ink_limit * output[6] / ink; + } + } + + output += 7; + num_pixels --; + } + break; + } +} + + +/* + * 'cupsCMYKDoGray()' - Do a grayscale separation... + */ + +void +cupsCMYKDoGray(const cups_cmyk_t *cmyk, + /* I - Color separation */ + const unsigned char *input, + /* I - Input grayscale pixels */ + short *output, + /* O - Output Device-N pixels */ + int num_pixels) + /* I - Number of pixels */ +{ + int k, /* Current black value */ + kc; /* Current black color value */ + const short **channels; /* Copy of channel LUTs */ + int ink, /* Amount of ink */ + ink_limit; /* Ink limit from separation */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) + return; + + /* + * Loop through it all... + */ + + channels = (const short **)cmyk->channels; + ink_limit = cmyk->ink_limit; + + switch (cmyk->num_channels) + { + case 1 : /* Black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = cups_scmy_lut[*input++]; + *output++ = channels[0][k]; + + num_pixels --; + } + break; + + case 2 : /* Black, light black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = cups_scmy_lut[*input++]; + output[0] = channels[0][k]; + output[1] = channels[1][k]; + + if (ink_limit) + { + ink = output[0] + output[1]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + } + } + + output += 2; + num_pixels --; + } + break; + + case 3 : /* CMY */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = cups_scmy_lut[*input++]; + output[0] = channels[0][k]; + output[1] = channels[1][k]; + output[2] = channels[2][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + } + } + + output += 3; + num_pixels --; + } + break; + + case 4 : /* CMYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = cups_scmy_lut[*input++]; + kc = cmyk->color_lut[k]; + k = cmyk->black_lut[k]; + output[0] = channels[0][kc]; + output[1] = channels[1][kc]; + output[2] = channels[2][kc]; + output[3] = channels[3][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + } + } + + output += 4; + num_pixels --; + } + break; + + case 6 : /* CcMmYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = cups_scmy_lut[*input++]; + kc = cmyk->color_lut[k]; + k = cmyk->black_lut[k]; + output[0] = channels[0][kc]; + output[1] = channels[1][kc]; + output[2] = channels[2][kc]; + output[3] = channels[3][kc]; + output[4] = channels[4][kc]; + output[5] = channels[5][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3] + + output[4] + output[5]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + output[4] = ink_limit * output[4] / ink; + output[5] = ink_limit * output[5] / ink; + } + } + + output += 6; + num_pixels --; + } + break; + + case 7 : /* CcMmYKk */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + k = cups_scmy_lut[*input++]; + kc = cmyk->color_lut[k]; + k = cmyk->black_lut[k]; + output[0] = channels[0][kc]; + output[1] = channels[1][kc]; + output[2] = channels[2][kc]; + output[3] = channels[3][kc]; + output[4] = channels[4][kc]; + output[5] = channels[5][k]; + output[6] = channels[6][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3] + + output[4] + output[5] + output[6]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + output[4] = ink_limit * output[4] / ink; + output[5] = ink_limit * output[5] / ink; + output[6] = ink_limit * output[6] / ink; + } + } + + output += 7; + num_pixels --; + } + break; + } +} + + +/* + * 'cupsCMYKDoRGB()' - Do an sRGB separation... + */ + +void +cupsCMYKDoRGB(const cups_cmyk_t *cmyk, + /* I - Color separation */ + const unsigned char *input, + /* I - Input grayscale pixels */ + short *output, + /* O - Output Device-N pixels */ + int num_pixels) + /* I - Number of pixels */ +{ + int c, /* Current cyan value */ + m, /* Current magenta value */ + y, /* Current yellow value */ + k, /* Current black value */ + kc, /* Current black color value */ + km; /* Maximum black value */ + const short **channels; /* Copy of channel LUTs */ + int ink, /* Amount of ink */ + ink_limit; /* Ink limit from separation */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0) + return; + + /* + * Loop through it all... + */ + + channels = (const short **)cmyk->channels; + ink_limit = cmyk->ink_limit; + + switch (cmyk->num_channels) + { + case 1 : /* Black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = cups_scmy_lut[*input++]; + m = cups_scmy_lut[*input++]; + y = cups_scmy_lut[*input++]; + k = (c * 31 + m * 61 + y * 8) / 100; + + *output++ = channels[0][k]; + + num_pixels --; + } + break; + + case 2 : /* Black, light black */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = cups_scmy_lut[*input++]; + m = cups_scmy_lut[*input++]; + y = cups_scmy_lut[*input++]; + k = (c * 31 + m * 61 + y * 8) / 100; + + output[0] = channels[0][k]; + output[1] = channels[1][k]; + + if (ink_limit) + { + ink = output[0] + output[1]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + } + } + + output += 2; + num_pixels --; + } + break; + + case 3 : /* CMY */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = cups_scmy_lut[*input++]; + m = cups_scmy_lut[*input++]; + y = cups_scmy_lut[*input++]; + + output[0] = channels[0][c]; + output[1] = channels[1][m]; + output[2] = channels[2][y]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + } + } + + output += 3; + num_pixels --; + } + break; + + case 4 : /* CMYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = cups_scmy_lut[*input++]; + m = cups_scmy_lut[*input++]; + y = cups_scmy_lut[*input++]; + k = min(c, min(m, y)); + + if ((km = max(c, max(m, y))) > k) + k = k * k * k / (km * km); + + kc = cmyk->color_lut[k] - k; + k = cmyk->black_lut[k]; + c += kc; + m += kc; + y += kc; + + output[0] = channels[0][c]; + output[1] = channels[1][m]; + output[2] = channels[2][y]; + output[3] = channels[3][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + } + } + + output += 4; + num_pixels --; + } + break; + + case 6 : /* CcMmYK */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = cups_scmy_lut[*input++]; + m = cups_scmy_lut[*input++]; + y = cups_scmy_lut[*input++]; + k = min(c, min(m, y)); + + if ((km = max(c, max(m, y))) > k) + k = k * k * k / (km * km); + + kc = cmyk->color_lut[k] - k; + k = cmyk->black_lut[k]; + c += kc; + m += kc; + y += kc; + + output[0] = channels[0][c]; + output[1] = channels[1][c]; + output[2] = channels[2][m]; + output[3] = channels[3][m]; + output[4] = channels[4][y]; + output[5] = channels[5][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3] + + output[4] + output[5]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + output[4] = ink_limit * output[4] / ink; + output[5] = ink_limit * output[5] / ink; + } + } + + output += 6; + num_pixels --; + } + break; + + case 7 : /* CcMmYKk */ + while (num_pixels > 0) + { + /* + * Get the input black value and then set the corresponding color + * channel values... + */ + + c = cups_scmy_lut[*input++]; + m = cups_scmy_lut[*input++]; + y = cups_scmy_lut[*input++]; + k = min(c, min(m, y)); + + if ((km = max(c, max(m, y))) > k) + k = k * k * k / (km * km); + + kc = cmyk->color_lut[k] - k; + k = cmyk->black_lut[k]; + c += kc; + m += kc; + y += kc; + + output[0] = channels[0][c]; + output[1] = channels[1][c]; + output[2] = channels[2][m]; + output[3] = channels[3][m]; + output[4] = channels[4][y]; + output[5] = channels[5][k]; + output[6] = channels[6][k]; + + if (ink_limit) + { + ink = output[0] + output[1] + output[2] + output[3] + + output[4] + output[5] + output[6]; + + if (ink > ink_limit) + { + output[0] = ink_limit * output[0] / ink; + output[1] = ink_limit * output[1] / ink; + output[2] = ink_limit * output[2] / ink; + output[3] = ink_limit * output[3] / ink; + output[4] = ink_limit * output[4] / ink; + output[5] = ink_limit * output[5] / ink; + output[6] = ink_limit * output[6] / ink; + } + } + + output += 7; + num_pixels --; + } + break; + } +} + + +/* + * 'cupsCMYKLoad()' - Load a CMYK color profile from PPD attributes. + */ + +cups_cmyk_t * /* O - CMYK color separation */ +cupsCMYKLoad(ppd_file_t *ppd, /* I - PPD file */ + const char *colormodel, /* I - ColorModel value */ + const char *media, /* I - MediaType value */ + const char *resolution) /* I - Resolution value */ +{ + cups_cmyk_t *cmyk; /* CMYK color separation */ + char spec[PPD_MAX_NAME]; /* Profile name */ + ppd_attr_t *attr; /* Attribute from PPD file */ + int num_channels; /* Number of color components */ + float gamval, /* Gamma correction value */ + density, /* Density value */ + light, /* Light ink limit */ + dark, /* Light ink cut-off */ + lower, /* Start of black ink */ + upper; /* End of color ink */ + int num_xypoints; /* Number of X,Y points */ + float xypoints[100 * 2], /* X,Y points */ + *xyptr; /* Current X,Y point */ + + + /* + * Range check input... + */ + + if (ppd == NULL || colormodel == NULL || resolution == NULL || media == NULL) + return (NULL); + + /* + * Find the following attributes: + * + * cupsAllGamma - Set default curve using gamma + density + * cupsAllXY - Set default curve using XY points + * cupsBlackGamma - Set black curve using gamma + density + * cupsBlackGeneration - Set black generation + * cupsBlackLightDark - Set black light/dark transition + * cupsBlackXY - Set black curve using XY points + * cupsCyanGamma - Set cyan curve using gamma + density + * cupsCyanLightDark - Set cyan light/dark transition + * cupsCyanXY - Set cyan curve using XY points + * cupsInkChannels - Set number of color channels + * cupsInkLimit - Set total ink limit + * cupsLightBlackGamma - Set light black curve using gamma + density + * cupsLightBlackXY - Set light black curve using XY points + * cupsLightCyanGamma - Set light cyan curve using gamma + density + * cupsLightCyanXY - Set light cyan curve using XY points + * cupsLightMagentaGamma - Set light magenta curve using gamma + density + * cupsLightMagentaXY - Set light magenta curve using XY points + * cupsMagentaGamma - Set magenta curve using gamma + density + * cupsMagentaLightDark - Set magenta light/dark transition + * cupsMagentaXY - Set magenta curve using XY points + * cupsYellowGamma - Set yellow curve using gamma + density + * cupsYellowXY - Set yellow curve using XY points + * + * The only required attribute is cupsInkChannels. + * + * The *XY attributes have precedence over the *Gamma attributes, and + * the *Light* attributes have precedence over the corresponding + * *LightDark* attributes. + */ + + /* + * Get the required cupsInkChannels attribute... + */ + + if ((attr = cupsFindAttr(ppd, "cupsInkChannels", colormodel, media, + resolution, spec, sizeof(spec))) == NULL) + return (NULL); + + num_channels = atoi(attr->value); + + if (num_channels < 1 || num_channels > 7 || num_channels == 5) + return (NULL); + + if ((cmyk = cupsCMYKNew(num_channels)) == NULL) + return (NULL); + + /* + * Get the optional cupsInkLimit attribute... + */ + + if ((attr = cupsFindAttr(ppd, "cupsInkLimit", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + cupsCMYKSetInkLimit(cmyk, atof(attr->value)); + + /* + * Get the optional cupsBlackGeneration attribute... + */ + + if ((attr = cupsFindAttr(ppd, "cupsBlackGeneration", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &lower, &upper) == 2) + cupsCMYKSetBlack(cmyk, lower, upper); + } + + /* + * Get the optional cupsBlackXY or cupsBlackGamma attributes... + */ + + if (num_channels != 3) + { + if ((attr = cupsFindAttr(ppd, "cupsBlackXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsBlackXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 1 : + case 2 : + cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); + break; + case 4 : + cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints); + break; + case 6 : + case 7 : + cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsBlackGamma", colormodel, + media, resolution, spec, + sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 1 : + case 2 : + cupsCMYKSetGamma(cmyk, 0, gamval, density); + break; + case 4 : + cupsCMYKSetGamma(cmyk, 3, gamval, density); + break; + case 6 : + case 7 : + cupsCMYKSetGamma(cmyk, 5, gamval, density); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 1 : + case 2 : + cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); + break; + case 4 : + cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints); + break; + case 6 : + case 7 : + cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, + media, resolution, spec, + sizeof(spec))) != NULL && + num_channels != 3) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 1 : + case 2 : + cupsCMYKSetGamma(cmyk, 0, gamval, density); + break; + case 4 : + cupsCMYKSetGamma(cmyk, 3, gamval, density); + break; + case 6 : + case 7 : + cupsCMYKSetGamma(cmyk, 5, gamval, density); + break; + } + } + } + + if (num_channels > 2) + { + /* + * Get the optional cupsCyanXY or cupsCyanGamma attributes... + */ + + if ((attr = cupsFindAttr(ppd, "cupsCyanXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsCyanXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); + } + else if ((attr = cupsFindAttr(ppd, "cupsCyanGamma", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + cupsCMYKSetGamma(cmyk, 0, gamval, density); + } + else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints); + } + else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + cupsCMYKSetGamma(cmyk, 0, gamval, density); + } + + /* + * Get the optional cupsMagentaXY or cupsMagentaGamma attributes... + */ + + if ((attr = cupsFindAttr(ppd, "cupsMagentaXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsMagentaXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); + break; + case 6 : + case 7 : + cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsMagentaGamma", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetGamma(cmyk, 1, gamval, density); + break; + case 6 : + case 7 : + cupsCMYKSetGamma(cmyk, 2, gamval, density); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); + break; + case 6 : + case 7 : + cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetGamma(cmyk, 1, gamval, density); + break; + case 6 : + case 7 : + cupsCMYKSetGamma(cmyk, 2, gamval, density); + break; + } + } + + /* + * Get the optional cupsYellowXY or cupsYellowGamma attributes... + */ + + if ((attr = cupsFindAttr(ppd, "cupsYellowXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsYellowXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); + break; + case 6 : + case 7 : + cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsYellowGamma", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetGamma(cmyk, 2, gamval, density); + break; + case 6 : + case 7 : + cupsCMYKSetGamma(cmyk, 4, gamval, density); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsAllXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints); + break; + case 6 : + case 7 : + cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 3 : + case 4 : + cupsCMYKSetGamma(cmyk, 2, gamval, density); + break; + case 6 : + case 7 : + cupsCMYKSetGamma(cmyk, 4, gamval, density); + break; + } + } + } + + /* + * Get the optional cupsLightBlackXY, cupsLightBlackGamma, or + * cupsBlackLtDk attributes... + */ + + if (num_channels == 2 || num_channels == 7) + { + if ((attr = cupsFindAttr(ppd, "cupsLightBlackXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsLightBlackXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + switch (num_channels) + { + case 2 : + cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); + break; + case 7 : + cupsCMYKSetCurve(cmyk, 6, num_xypoints, xypoints); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsLightBlackGamma", colormodel, + media, resolution, spec, + sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + switch (num_channels) + { + case 2 : + cupsCMYKSetGamma(cmyk, 1, gamval, density); + break; + case 7 : + cupsCMYKSetGamma(cmyk, 6, gamval, density); + break; + } + } + else if ((attr = cupsFindAttr(ppd, "cupsBlackLtDk", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &light, &dark) == 2) + switch (num_channels) + { + case 2 : + cupsCMYKSetLtDk(cmyk, 0, light, dark); + break; + case 7 : + cupsCMYKSetLtDk(cmyk, 5, light, dark); + break; + } + else + fprintf(stderr, "ERROR: Bad cupsBlackLtDk value \"%s\"!\n", + attr->value); + } + else + fprintf(stderr, "WARNING: No light black attribute found for %s!\n", + spec); + } + + if (num_channels >= 6) + { + /* + * Get the optional cupsLightCyanXY, cupsLightCyanGamma, or + * cupsCyanLtDk attributes... + */ + + if ((attr = cupsFindAttr(ppd, "cupsLightCyanXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsLightCyanXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints); + } + else if ((attr = cupsFindAttr(ppd, "cupsLightCyanGamma", colormodel, + media, resolution, spec, + sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + cupsCMYKSetGamma(cmyk, 1, gamval, density); + } + else if ((attr = cupsFindAttr(ppd, "cupsCyanLtDk", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &light, &dark) == 2) + cupsCMYKSetLtDk(cmyk, 0, light, dark); + else + fprintf(stderr, "ERROR: Bad cupsCyanLtDk value \"%s\"!\n", + attr->value); + } + else + fprintf(stderr, "WARNING: No light cyan attribute found for %s!\n", + spec); + + /* + * Get the optional cupsLightMagentaXY, cupsLightMagentaGamma, or + * cupsMagentaLtDk attributes... + */ + + if ((attr = cupsFindAttr(ppd, "cupsLightMagentaXY", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + for (num_xypoints = 0, xyptr = xypoints; + attr != NULL && attr->value != NULL && num_xypoints < 100; + attr = ppdFindNextAttr(ppd, "cupsLightMagentaXY", spec)) + if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2) + { + num_xypoints ++; + xyptr += 2; + } + + cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints); + } + else if ((attr = cupsFindAttr(ppd, "cupsLightMagentaGamma", colormodel, + media, resolution, spec, + sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &gamval, &density) == 2) + cupsCMYKSetGamma(cmyk, 3, gamval, density); + } + else if ((attr = cupsFindAttr(ppd, "cupsMagentaLtDk", colormodel, media, + resolution, spec, sizeof(spec))) != NULL) + { + if (sscanf(attr->value, "%f%f", &light, &dark) == 2) + cupsCMYKSetLtDk(cmyk, 2, light, dark); + else + fprintf(stderr, "ERROR: Bad cupsMagentaLtDk value \"%s\"!\n", + attr->value); + } + else + fprintf(stderr, "WARNING: No light magenta attribute found for %s!\n", + spec); + } + + /* + * Return the new profile... + */ + + return (cmyk); +} + + +/* + * 'cupsCMYKNew()' - Create a new CMYK color separation. + */ + +cups_cmyk_t * /* O - New CMYK separation or NULL */ +cupsCMYKNew(int num_channels) /* I - Number of color components */ +{ + cups_cmyk_t *cmyk; /* New color separation */ + int i; /* Looping var */ + + + /* + * Range-check the input... + */ + + if (num_channels < 1) + return (NULL); + + /* + * Allocate memory for the separation... + */ + + if ((cmyk = calloc(1, sizeof(cups_cmyk_t))) == NULL) + return (NULL); + + /* + * Allocate memory for the LUTs... + */ + + cmyk->num_channels = num_channels; + + if ((cmyk->channels[0] = calloc(num_channels * 256, sizeof(short))) == NULL) + { + free(cmyk); + return (NULL); + } + + for (i = 1; i < num_channels; i ++) + cmyk->channels[i] = cmyk->channels[0] + i * 256; + + /* + * Fill in the LUTs with unity transitions... + */ + + for (i = 0; i < 256; i ++) + cmyk->black_lut[i] = i; + + switch (num_channels) + { + case 1 : /* K */ + case 2 : /* Kk */ + for (i = 0; i < 256; i ++) + { + cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; + } + break; + case 3 : /* CMY */ + for (i = 0; i < 256; i ++) + { + cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255; + } + break; + case 4 : /* CMYK */ + for (i = 0; i < 256; i ++) + { + cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[3][i] = CUPS_MAX_LUT * i / 255; + } + break; + case 6 : /* CcMmYK */ + case 7 : /* CcMmYKk */ + for (i = 0; i < 256; i ++) + { + cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[4][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[5][i] = CUPS_MAX_LUT * i / 255; + } + break; + } + + /* + * Return the separation... + */ + + return (cmyk); +} + + +/* + * 'cupsCMYKSetBlack()' - Set the transition range for CMY to black. + */ + +void +cupsCMYKSetBlack(cups_cmyk_t *cmyk, /* I - CMYK color separation */ + float lower, /* I - No black ink */ + float upper) /* I - Only black ink */ +{ + int i, /* Looping var */ + delta, /* Difference between lower and upper */ + ilower, /* Lower level from 0 to 255 */ + iupper; /* Upper level from 0 to 255 */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || lower < 0.0 || lower > 1.0 || upper < 0.0 || upper > 1.0 || + lower > upper) + return; + + /* + * Convert lower and upper to integers from 0 to 255... + */ + + ilower = (int)(255.0 * lower + 0.5); + iupper = (int)(255.0 * upper + 0.5); + delta = iupper - ilower; + + /* + * Generate the CMY-only data... + */ + + for (i = 0; i < ilower; i ++) + { + cmyk->black_lut[i] = 0; + cmyk->color_lut[i] = i; + } + + /* + * Then the transition data... + */ + + for (; i < iupper; i ++) + { + cmyk->black_lut[i] = iupper * (i - ilower) / delta; + cmyk->color_lut[i] = ilower - ilower * (i - ilower) / delta; + } + + /* + * Then the K-only data... + */ + + for (; i < 256; i ++) + { + cmyk->black_lut[i] = i; + cmyk->color_lut[i] = 0; + } + + fprintf(stderr, "DEBUG: cupsCMYKSetBlack(cmyk, lower=%.3f, upper=%.3f)\n", lower, upper); + + for (i = 0; i < 256; i += 17) + fprintf(stderr, "DEBUG: %3d = %3dk + %3dc\n", i, + cmyk->black_lut[i], cmyk->color_lut[i]); +} + + +/* + * 'cupsCMYKSetCurve()' - Set a color transform curve using points. + */ + +void +cupsCMYKSetCurve(cups_cmyk_t *cmyk, /* I - CMYK color separation */ + int channel, /* I - Color channel */ + int num_xypoints, + /* I - Number of X,Y points */ + const float *xypoints) /* I - X,Y points */ +{ + int i; /* Looping var */ + int xstart; /* Start position */ + int xend; /* End position */ + int xdelta; /* Difference in position */ + int ystart; /* Start value */ + int yend; /* End value */ + int ydelta; /* Difference in value */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels || + num_xypoints < 1 || xypoints == NULL) + return; + + /* + * Initialize the lookup table for the specified channel... + */ + + for (xstart = xend = 0, ystart = yend = 0; + num_xypoints > 0; + num_xypoints --, xypoints += 2, xstart = xend, ystart = yend) + { + xend = (int)(255.0 * xypoints[1] + 0.5); + yend = (int)(CUPS_MAX_LUT * xypoints[0] + 0.5); + xdelta = xend - xstart; + ydelta = yend - ystart; + + for (i = xstart; i < xend; i ++) + cmyk->channels[channel][i] = ystart + ydelta * (i - xstart) / xdelta; + } + + /* + * Initialize any trailing values to the maximum of the last data point... + */ + + for (i = xend; i < 256; i ++) + cmyk->channels[channel][i] = yend; + + fprintf(stderr, "DEBUG: cupsCMYKSetXY(cmyk, channel=%d, num_xypoints=%d, " + "xypoints=[%.3f %.3f %.3f %.3f ...])\n", channel, + num_xypoints, xypoints[0], xypoints[1], xypoints[2], xypoints[3]); + + for (i = 0; i < 256; i += 17) + fprintf(stderr, "DEBUG: %3d = %4d\n", i, + cmyk->channels[channel + 0][i]); +} + + +/* + * 'cupsCMYKSetGamma()' - Set a color transform curve using gamma and density. + */ + +void +cupsCMYKSetGamma(cups_cmyk_t *cmyk, /* I - CMYK color separation */ + int channel, /* I - Ink channel */ + float gamval, /* I - Gamma correction */ + float density) /* I - Maximum density */ +{ + int i; /* Looping var */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels || + gamval <= 0.0 || density <= 0.0 || density > 1.0) + return; + + /* + * Initialize the lookup table for the specified channel... + */ + + for (i = 0; i < 256; i ++) + cmyk->channels[channel][i] = (int)(density * CUPS_MAX_LUT * + pow((float)i / 255.0, gamval) + 0.5); + + fprintf(stderr, "DEBUG: cupsCMYKSetGamma(cmyk, channel=%d, gamval=%.3f, " + "density=%.3f)\n", channel, gamval, density); + + for (i = 0; i < 256; i += 17) + fprintf(stderr, "DEBUG: %3d = %4d\n", i, + cmyk->channels[channel + 0][i]); +} + + +/* + * 'cupsCMYKSetInkLimit()' - Set the limit on the amount of ink. + */ + +void +cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, /* I - CMYK color separation */ + float limit) /* I - Limit of ink */ +{ + if (!cmyk || limit < 0.0) + return; + + cmyk->ink_limit = limit * CUPS_MAX_LUT; +} + + +/* + * 'cupsCMYKSetLtDk()' - Set light/dark ink transforms. + */ + +void +cupsCMYKSetLtDk(cups_cmyk_t *cmyk, /* I - CMYK color separation */ + int channel, /* I - Dark ink channel (+1 for light) */ + float light, /* I - Light ink only level */ + float dark) /* I - Dark ink only level */ +{ + int i, /* Looping var */ + delta, /* Difference between lower and upper */ + ilight, /* Light level from 0 to 255 */ + idark; /* Dark level from 0 to 255 */ + short lut[256]; /* Original LUT data */ + + + /* + * Range check input... + */ + + if (cmyk == NULL || light < 0.0 || light > 1.0 || dark < 0.0 || dark > 1.0 || + light > dark || channel < 0 || channel > (cmyk->num_channels - 2)) + return; + + /* + * Convert lower and upper to integers from 0 to 255... + */ + + ilight = (int)(255.0 * light + 0.5); + idark = (int)(255.0 * dark + 0.5); + delta = idark - ilight; + + /* + * Copy the dark ink LUT... + */ + + memcpy(lut, cmyk->channels[channel], sizeof(lut)); + + /* + * Generate the light-only data... + */ + + for (i = 0; i < ilight; i ++) + { + cmyk->channels[channel + 0][i] = 0; + cmyk->channels[channel + 1][i] = CUPS_MAX_LUT * i / ilight; + } + + /* + * Then the transition data... + */ + + for (; i < idark; i ++) + { + cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * idark * (i - ilight) / + delta / 255; + cmyk->channels[channel + 1][i] = CUPS_MAX_LUT - CUPS_MAX_LUT * + (i - ilight) / delta; + } + + /* + * Then the K-only data... + */ + + for (; i < 256; i ++) + { + cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * i / 255; + cmyk->channels[channel + 1][i] = 0; + } + + fprintf(stderr, "DEBUG: cupsCMYKSetLtDk(cmyk, channel=%d, light=%.3f, " + "dark=%.3f)\n", channel, light, dark); + + for (i = 0; i < 256; i += 17) + fprintf(stderr, "DEBUG: %3d = %4dlt + %4ddk\n", i, + cmyk->channels[channel + 0][i], cmyk->channels[channel + 1][i]); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/commandtoescpx.c b/driver/commandtoescpx.c new file mode 100644 index 0000000000..ce09ebcad9 --- /dev/null +++ b/driver/commandtoescpx.c @@ -0,0 +1,244 @@ +/* + * "$Id$" + * + * Advanced EPSON ESC/P command filter for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * + * Contents: + * + * main() - Main entry and command processing. + */ + +/* + * Include necessary headers... + */ + +#include +#include "driver.h" +#include +#include "data/escp.h" + + +/* + * '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 */ +{ + FILE *fp; /* Command file */ + char line[1024], /* Line from file */ + *lineptr; /* Pointer into line */ + int feedpage; /* Feed the page */ + ppd_file_t *ppd; /* PPD file */ + + + /* + * Check for valid arguments... + */ + + if (argc < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + fputs("ERROR: commandtoescpx job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * Open the PPD file... + */ + + if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL) + { + fputs("ERROR: Unable to open PPD file!\n", stderr); + return (1); + } + + /* + * Open the command file as needed... + */ + + if (argc == 7) + { + if ((fp = fopen(argv[6], "r")) == NULL) + { + perror("ERROR: Unable to open command file - "); + return (1); + } + } + else + fp = stdin; + + /* + * Some EPSON printers need an additional command issued at the + * beginning of each job to exit from USB "packet" mode... + */ + + if (ppd->model_number & ESCP_USB) + cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29); + + /* + * Reset the printer... + */ + + cupsWritePrintData("\033@", 2); + + /* + * Enter remote mode... + */ + + cupsWritePrintData("\033(R\010\000\000REMOTE1", 13); + feedpage = 0; + + /* + * Read the commands from the file and send the appropriate commands... + */ + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* + * Drop trailing newline... + */ + + lineptr = line + strlen(line) - 1; + if (*lineptr == '\n') + *lineptr = '\0'; + + /* + * Skip leading whitespace... + */ + + for (lineptr = line; isspace(*lineptr); lineptr ++); + + /* + * Skip comments and blank lines... + */ + + if (*lineptr == '#' || !*lineptr) + continue; + + /* + * Parse the command... + */ + + if (strncasecmp(lineptr, "Clean", 5) == 0) + { + /* + * Clean heads... + */ + + cupsWritePrintData("CH\002\000\000\000", 6); + } + else if (strncasecmp(lineptr, "PrintAlignmentPage", 18) == 0) + { + /* + * Print alignment page... + */ + + int phase; + + phase = atoi(lineptr + 18); + + cupsWritePrintData("DT\003\000\000", 5); + putchar(phase & 255); + putchar(phase >> 8); + feedpage = 1; + } + else if (strncasecmp(lineptr, "PrintSelfTestPage", 17) == 0) + { + /* + * Print version info and nozzle check... + */ + + cupsWritePrintData("VI\002\000\000\000", 6); + cupsWritePrintData("NC\002\000\000\000", 6); + feedpage = 1; + } + else if (strncasecmp(lineptr, "ReportLevels", 12) == 0) + { + /* + * Report ink levels... + */ + + cupsWritePrintData("IQ\001\000\001", 5); + } + else if (strncasecmp(lineptr, "SetAlignment", 12) == 0) + { + /* + * Set head alignment... + */ + + int phase, x; + + if (sscanf(lineptr + 12, "%d%d", &phase, &x) != 2) + { + fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr); + continue; + } + + cupsWritePrintData("DA\004\000", 4); + putchar(0); + putchar(phase); + putchar(0); + putchar(x); + cupsWritePrintData("SV\000\000", 4); + } + else + fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr); + } + + /* + * Exit remote mode... + */ + + cupsWritePrintData("\033\000\000\000", 4); + + /* + * Eject the page as needed... + */ + + if (feedpage) + { + fputs("PAGE: 1 1\n", stderr); + + putchar(13); + putchar(10); + putchar(12); + } + + /* + * Reset the printer... + */ + + cupsWritePrintData("\033@", 2); + + /* + * Close the command file and return... + */ + + ppdClose(ppd); + + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/commandtopclx.c b/driver/commandtopclx.c new file mode 100644 index 0000000000..1c5c10df18 --- /dev/null +++ b/driver/commandtopclx.c @@ -0,0 +1,171 @@ +/* + * "$Id$" + * + * Advanced PCL command filter for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * + * Contents: + * + * main() - Main entry and command processing. + */ + +/* + * Include necessary headers... + */ + +#include +#include "driver.h" +#include +#include "data/pcl.h" + + +/* + * '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 */ +{ + FILE *fp; /* Command file */ + char line[1024], /* Line from file */ + *lineptr; /* Pointer into line */ + int feedpage; /* Feed the page */ + ppd_file_t *ppd; /* PPD file */ + + + /* + * Check for valid arguments... + */ + + if (argc < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + fputs("ERROR: commandtopclx job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * Open the PPD file... + */ + + if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL) + { + fputs("ERROR: Unable to open PPD file!\n", stderr); + return (1); + } + + /* + * Open the command file as needed... + */ + + if (argc == 7) + { + if ((fp = fopen(argv[6], "r")) == NULL) + { + perror("ERROR: Unable to open command file - "); + return (1); + } + } + else + fp = stdin; + + /* + * Reset the printer... + */ + + cupsWritePrintData("\033E", 2); + + /* + * Read the commands from the file and send the appropriate commands... + */ + + feedpage = 0; + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* + * Drop trailing newline... + */ + + lineptr = line + strlen(line) - 1; + if (*lineptr == '\n') + *lineptr = '\0'; + + /* + * Skip leading whitespace... + */ + + for (lineptr = line; isspace(*lineptr); lineptr ++); + + /* + * Skip comments and blank lines... + */ + + if (*lineptr == '#' || !*lineptr) + continue; + + /* + * Parse the command... + */ + + if (strncasecmp(lineptr, "Clean", 5) == 0 && + (ppd->model_number & PCL_INKJET)) + { + /* + * Clean heads... + */ + + cupsWritePrintData("\033&b16WPML \004\000\006\001\004\001\005\001" + "\001\004\001\144", 22); + } + else + fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", lineptr); + } + + /* + * Eject the page as needed... + */ + + if (feedpage) + { + fputs("PAGE: 1 1\n", stderr); + + putchar(12); + } + + /* + * Reset the printer... + */ + + cupsWritePrintData("\033E", 2); + + /* + * Close the command file and return... + */ + + ppdClose(ppd); + + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/dither.c b/driver/dither.c new file mode 100644 index 0000000000..dfefed7c1d --- /dev/null +++ b/driver/dither.c @@ -0,0 +1,306 @@ +/* + * "$Id$" + * + * Dithering routines for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsDitherDelete() - Free a dithering buffer. + * cupsDitherLine() - Dither a line of pixels... + * cupsDitherNew() - Create a dithering buffer. + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" +#include + + +/* + * 'cupsDitherDelete()' - Free a dithering buffer. + * + * Returns 0 on success, -1 on failure. + */ + +void +cupsDitherDelete(cups_dither_t *d) /* I - Dithering buffer */ +{ + if (d != NULL) + free(d); +} + + +/* + * 'cupsDitherLine()' - Dither a line of pixels... + */ + +void +cupsDitherLine(cups_dither_t *d, /* I - Dither data */ + const cups_lut_t *lut, /* I - Lookup table */ + const short *data, /* I - Separation data */ + int num_channels, + /* I - Number of components */ + unsigned char *p) /* O - Pixels */ +{ + register int x, /* Horizontal position in line... */ + pixel, /* Current adjusted pixel... */ + e, /* Current error */ + e0,e1,e2; /* Error values */ + register int errval0, /* First half of error value */ + errval1, /* Second half of error value */ + errbase, /* Base multiplier */ + errbase0, /* Base multiplier for large values */ + errbase1, /* Base multiplier for small values */ + errrange; /* Range of random multiplier */ + register int *p0, /* Error buffer pointers... */ + *p1; + static char logtable[16384]; /* Error magnitude for randomness */ + static char loginit = 0; /* Has the table been initialized? */ + + + if (!loginit) + { + /* + * Initialize a logarithmic table for the magnitude of randomness + * that is introduced. + */ + + loginit = 1; + + logtable[0] = 0; + for (x = 1; x < 2049; x ++) + logtable[x] = (int)(log(x / 16.0) / log(2.0) + 1.0); + for (; x < 16384; x ++) + logtable[x] = logtable[2049]; + } + + if (d->row == 0) + { + /* + * Dither from left to right: + * + * e0 == p0[0] + * e1 e2 == p1[-1] p1[0] + */ + + p0 = d->errors + 2; + p1 = d->errors + 2 + d->width + 4; + e0 = p0[0]; + e1 = 0; + e2 = 0; + + /* + * Error diffuse each output pixel... + */ + + for (x = d->width; + x > 0; + x --, p0 ++, p1 ++, p ++, data += num_channels) + { + /* + * Skip blank pixels... + */ + + if (*data == 0) + { + *p = 0; + e0 = p0[1]; + p1[-1] = e1; + e1 = e2; + e2 = 0; + continue; + } + + /* + * Compute the net pixel brightness and brightness error. Set a dot + * if necessary... + */ + + pixel = lut[*data].intensity + e0 / 128; + + if (pixel > CUPS_MAX_LUT) + pixel = CUPS_MAX_LUT; + else if (pixel < 0) + pixel = 0; + + *p = lut[pixel].pixel; + e = lut[pixel].error; + + /* + * Set the randomness factor... + */ + + if (e > 0) + errrange = logtable[e]; + else + errrange = logtable[-e]; + + errbase = 8 - errrange; + errrange = errrange * 2 + 1; + + /* + * Randomize the error value. + */ + + if (errrange > 1) + { + errbase0 = errbase + (CUPS_RAND() % errrange); + errbase1 = errbase + (CUPS_RAND() % errrange); + } + else + errbase0 = errbase1 = errbase; + + /* + * X 7/16 = X e0 + * 3/16 5/16 1/16 = e1 e2 + */ + + errval0 = errbase0 * e; + errval1 = (16 - errbase0) * e; + e0 = p0[1] + 7 * errval0; + e1 = e2 + 5 * errval1; + + errval0 = errbase1 * e; + errval1 = (16 - errbase1) * e; + e2 = errval0; + p1[-1] = e1 + 3 * errval1; + } + } + else + { + /* + * Dither from right to left: + * + * e0 == p0[0] + * e2 e1 == p1[0] p1[1] + */ + + p0 = d->errors + d->width + 1 + d->width + 4; + p1 = d->errors + d->width + 1; + p += d->width - 1; + data += num_channels * (d->width - 1); + e0 = p0[0]; + e1 = 0; + e2 = 0; + + /* + * Error diffuse each output pixel... + */ + + for (x = d->width; + x > 0; + x --, p0 --, p1 --, p --, data -= num_channels) + { + /* + * Skip blank pixels... + */ + + if (*data == 0) + { + *p = 0; + e0 = p0[-1]; + p1[1] = e1; + e1 = e2; + e2 = 0; + continue; + } + + /* + * Compute the net pixel brightness and brightness error. Set a dot + * if necessary... + */ + + pixel = lut[*data].intensity + e0 / 128; + + if (pixel > CUPS_MAX_LUT) + pixel = CUPS_MAX_LUT; + else if (pixel < 0) + pixel = 0; + + *p = lut[pixel].pixel; + e = lut[pixel].error; + + /* + * Set the randomness factor... + */ + + if (e > 0) + errrange = logtable[e]; + else + errrange = logtable[-e]; + + errbase = 8 - errrange; + errrange = errrange * 2 + 1; + + /* + * Randomize the error value. + */ + + if (errrange > 1) + { + errbase0 = errbase + (CUPS_RAND() % errrange); + errbase1 = errbase + (CUPS_RAND() % errrange); + } + else + errbase0 = errbase1 = errbase; + + /* + * X 7/16 = X e0 + * 3/16 5/16 1/16 = e1 e2 + */ + + errval0 = errbase0 * e; + errval1 = (16 - errbase0) * e; + e0 = p0[-1] + 7 * errval0; + e1 = e2 + 5 * errval1; + + errval0 = errbase1 * e; + errval1 = (16 - errbase1) * e; + e2 = errval0; + p1[1] = e1 + 3 * errval1; + } + } + + /* + * Update to the next row... + */ + + d->row = 1 - d->row; +} + + +/* + * 'cupsDitherNew()' - Create an error-diffusion dithering buffer. + */ + +cups_dither_t * /* O - New state array */ +cupsDitherNew(int width) /* I - Width of output in pixels */ +{ + cups_dither_t *d; /* New dithering buffer */ + + + if ((d = (cups_dither_t *)calloc(1, sizeof(cups_dither_t) + + 2 * (width + 4) * + sizeof(int))) == NULL) + return (NULL); + + d->width = width; + + return (d); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/driver.h b/driver/driver.h new file mode 100644 index 0000000000..ed4eab96d7 --- /dev/null +++ b/driver/driver.h @@ -0,0 +1,249 @@ +/* + * "$Id$" + * + * Printer driver utilities header file for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_DRIVER_H_ +# define _CUPS_DRIVER_H_ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include + +# if defined(WIN32) || defined(__EMX__) +# include +# else +# include +# include +# endif /* WIN32 || __EMX__ */ + +# include +# include + + +/* + * Common macros... + */ + +# ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +# define max(a,b) ((a) > (b) ? (a) : (b)) +# endif /* !min */ + + +/* + * Constants... + */ + +#define CUPS_MAX_CHAN 15 /* Maximum number of color components */ +#define CUPS_MAX_LUT 4095 /* Maximum LUT value */ +#define CUPS_MAX_RGB 4 /* Maximum number of sRGB components */ + + +/* + * Types/structures for the various routines. + */ + +typedef struct cups_lut_s /**** Lookup Table for Dithering ****/ +{ + short intensity; /* Adjusted intensity */ + short pixel; /* Output pixel value */ + int error; /* Error from desired value */ +} cups_lut_t; + +typedef struct cups_dither_s /**** Dithering State ****/ +{ + int width; /* Width of buffer */ + int row; /* Current row */ + int errors[96]; /* Error values */ +} cups_dither_t; + +typedef struct cups_sample_s /**** Color sample point ****/ +{ + unsigned char rgb[3]; /* sRGB values */ + unsigned char colors[CUPS_MAX_RGB]; /* Color values */ +} cups_sample_t; + +typedef struct cups_rgb_s /**** Color separation lookup table ****/ +{ + int cube_size; /* Size of color cube (2-N) on a side */ + int num_channels; /* Number of colors per sample */ + unsigned char ****colors; /* 4-D array of sample values */ + int cube_index[256]; /* Index into cube for a given sRGB value */ + int cube_mult[256]; /* Multiplier value for a given sRGB value */ + int cache_init; /* Are cached values initialized? */ + unsigned char black[CUPS_MAX_RGB]; /* Cached black (sRGB = 0,0,0) */ + unsigned char white[CUPS_MAX_RGB]; /* Cached white (sRGB = 255,255,255) */ +} cups_rgb_t; + +typedef struct cups_cmyk_s /**** Simple CMYK lookup table ****/ +{ + unsigned char black_lut[256]; /* Black generation LUT */ + unsigned char color_lut[256]; /* Color removal LUT */ + int ink_limit; /* Ink limit */ + int num_channels; /* Number of components */ + short *channels[CUPS_MAX_CHAN]; + /* Lookup tables */ +} cups_cmyk_t; + + +/* + * Globals... + */ + +extern const unsigned char + cups_srgb_lut[256]; + /* sRGB gamma lookup table */ +extern const unsigned char + cups_scmy_lut[256]; + /* sRGB gamma lookup table (inverted) */ + + +/* + * Prototypes... + */ + +/* + * Attribute function... + */ + +extern ppd_attr_t *cupsFindAttr(ppd_file_t *ppd, const char *name, + const char *colormodel, + const char *media, + const char *resolution, + char *spec, int specsize); + +/* + * Byte checking functions... + */ + +extern int cupsCheckBytes(const unsigned char *, int); +extern int cupsCheckValue(const unsigned char *, int, + const unsigned char); + +/* + * Dithering functions... + */ + +extern void cupsDitherLine(cups_dither_t *d, const cups_lut_t *lut, + const short *data, int num_channels, + unsigned char *p); +extern cups_dither_t *cupsDitherNew(int width); +extern void cupsDitherDelete(cups_dither_t *); + +/* + * Lookup table functions for dithering... + */ + +extern cups_lut_t *cupsLutNew(int num_vals, const float *vals); +extern void cupsLutDelete(cups_lut_t *lut); +extern cups_lut_t *cupsLutLoad(ppd_file_t *ppd, + const char *colormodel, + const char *media, + const char *resolution, + const char *ink); + + +/* + * Bit packing functions... + */ + +extern void cupsPackHorizontal(const unsigned char *, + unsigned char *, int, + const unsigned char, const int); +extern void cupsPackHorizontal2(const unsigned char *, + unsigned char *, int, const int); +extern void cupsPackHorizontalBit(const unsigned char *, + unsigned char *, int, + const unsigned char, + const unsigned char); +extern void cupsPackVertical(const unsigned char *, unsigned char *, + int, const unsigned char, const int); + +/* + * Color separation functions... + */ + +extern void cupsRGBDelete(cups_rgb_t *rgb); +extern void cupsRGBDoGray(cups_rgb_t *rgb, + const unsigned char *input, + unsigned char *output, int num_pixels); +extern void cupsRGBDoRGB(cups_rgb_t *rgb, + const unsigned char *input, + unsigned char *output, int num_pixels); +extern cups_rgb_t *cupsRGBLoad(ppd_file_t *ppd, + const char *colormodel, + const char *media, + const char *resolution); +extern cups_rgb_t *cupsRGBNew(int num_samples, cups_sample_t *samples, + int cube_size, int num_channels); + +/* + * CMYK separation functions... + */ + +extern cups_cmyk_t *cupsCMYKNew(int num_channels); +extern void cupsCMYKDelete(cups_cmyk_t *cmyk); +extern void cupsCMYKDoBlack(const cups_cmyk_t *cmyk, + const unsigned char *input, + short *output, int num_pixels); +extern void cupsCMYKDoCMYK(const cups_cmyk_t *cmyk, + const unsigned char *input, + short *output, int num_pixels); +extern void cupsCMYKDoGray(const cups_cmyk_t *cmyk, + const unsigned char *input, + short *output, int num_pixels); +extern void cupsCMYKDoRGB(const cups_cmyk_t *cmyk, + const unsigned char *input, + short *output, int num_pixels); +extern cups_cmyk_t *cupsCMYKLoad(ppd_file_t *ppd, + const char *colormodel, + const char *media, + const char *resolution); +extern void cupsCMYKSetBlack(cups_cmyk_t *cmyk, + float lower, float upper); +extern void cupsCMYKSetCurve(cups_cmyk_t *cmyk, int channel, + int num_xypoints, + const float *xypoints); +extern void cupsCMYKSetGamma(cups_cmyk_t *cmyk, int channel, + float gamval, float density); +extern void cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, float limit); +extern void cupsCMYKSetLtDk(cups_cmyk_t *cmyk, int channel, + float light, float dark); + + +/* + * Convenience macro for writing print data... + */ + +# define cupsWritePrintData(s,n) fwrite((s), 1, (n), stdout) + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_DRIVER_H_ */ + +/* + * End of "$Id$". + */ + diff --git a/driver/image.pgm b/driver/image.pgm new file mode 100644 index 0000000000000000000000000000000000000000..c0b7a22f7feb992bb441fb93b9a88a7da6341857 GIT binary patch literal 152380 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

>3N@phAhq?B6*q1)Hxn3iDh1gIL8UU- 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

dy?XcE*B?&rA3q)@ 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 R>gwv^^aR`ZhrRWy{|C9b3Z?)6 literal 0 Hc-jL100001 diff --git a/driver/image.ppm b/driver/image.ppm new file mode 100644 index 0000000000000000000000000000000000000000..3823fe48b0ef0e6342cd8c3c13e7bb1d26e79ff1 GIT binary patch literal 457020 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

\n%s", start_fonts[font]); + } + else if (!strncmp(line, ".LP", 3) || !strncmp(line, ".PP", 3)) + { + /* + * New paragraph... + */ + + fputs(end_fonts[font], outfile); + + if (blist) + { + fputs("\n\n", outfile); + blist = 0; + } + + if (list) + { + if (list == 1) + fputs("\n", outfile); + else if (list) + fputs("\n", outfile); + + fputs("\n", outfile); + list = 0; + } + + fputs("

", outfile); + font = 0; + } + else if (!strncmp(line, ".TP ", 4)) + { + /* + * Grab list... + */ + + fputs(end_fonts[font], outfile); + + if (blist) + { + fputs("\n\n", outfile); + blist = 0; + } + + if (!list) + fputs("

\n", outfile); + else if (list == 1) + fputs("\n", outfile); + else if (list) + fputs("\n", outfile); + + fputs("
", outfile); + list = 1; + font = 0; + } + else if (!strncmp(line, ".br", 3)) + { + /* + * Grab line break... + */ + + if (list == 1) + { + fputs("
\n
", outfile); + list = 2; + } + else if (list) + fputs("
\n
", outfile); + else + fputs("
\n", outfile); + } + else if (!strncmp(line, ".de ", 4)) + { + /* + * Define macro - ignore... + */ + + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + + if (!strncmp(line, "..", 2)) + break; + } + } + else if (!strncmp(line, ".RS", 3)) + { + /* + * Indent... + */ + + fputs("
\n", outfile); + } + else if (!strncmp(line, ".RE", 3)) + { + /* + * Unindent... + */ + + fputs("
\n", outfile); + } + else if (!strncmp(line, ".ds ", 4) || !strncmp(line, ".rm ", 4) || + !strncmp(line, ".tr ", 4) || !strncmp(line, ".hy ", 4) || + !strncmp(line, ".IX ", 4) || !strncmp(line, ".PD", 3) || + !strncmp(line, ".Sp", 3)) + { + /* + * Ignore unused commands... + */ + } + else if (!strncmp(line, ".Vb", 3) || !strncmp(line, ".nf", 3)) + { + /* + * Start preformatted... + */ + + pre = 1; + fputs("
\n", outfile);
+      }
+      else if (!strncmp(line, ".Ve", 3) || !strncmp(line, ".fi", 3))
+      {
+       /*
+        * End preformatted...
+	*/
+
+        if (pre)
+	{
+          pre = 0;
+	  fputs("
\n", outfile); + } + } + else if (!strncmp(line, ".IP \\(bu", 8)) + { + /* + * Bullet list... + */ + + if (blist) + fputs("\n", outfile); + else + { + fputs("
    \n", outfile); + blist = 1; + } + + fputs("
  • ", outfile); + } + else if (!strncmp(line, ".IP ", 4)) + { + /* + * Indented paragraph... + */ + + if (blist) + { + fputs("
  • \n
\n", outfile); + blist = 0; + } + + fputs("

", outfile); + + for (lineptr = line + 4; isspace(*lineptr); lineptr ++); + + if (*lineptr == '\"') + { + strmove(line, lineptr + 1); + + if ((lineptr = strchr(line, '\"')) != NULL) + *lineptr = '\0'; + } + else + { + strmove(line, lineptr); + + if ((lineptr = strchr(line, ' ')) != NULL) + *lineptr = '\0'; + } + + /* + * Process the text as if it was in-line... + */ + + post = "\n
\n
"; + goto process_text; + } + else if (!strncmp(line, ".\\}", 3)) + { + /* + * Ignore close block... + */ + } + else if (!strncmp(line, ".ie", 3) || !strncmp(line, ".if", 3) || + !strncmp(line, ".el", 3)) + { + /* + * If/else - ignore... + */ + + if (strchr(line, '{') != NULL) + { + /* + * Skip whole block... + */ + + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + + if (strchr(line, '}') != NULL) + break; + } + } + } +#if 0 + else if (!strncmp(line, ". ", 4)) + { + /* + * Grab ... + */ + } +#endif /* 0 */ + else if (!strncmp(line, ".B ", 3)) + { + /* + * Grab bold text... + */ + + fprintf(outfile, "%s%s%s", end_fonts[font], line + 3, + start_fonts[font]); + } + else if (!strncmp(line, ".I ", 3)) + { + /* + * Grab italic text... + */ + + fprintf(outfile, "%s%s%s", end_fonts[font], line + 3, + start_fonts[font]); + } + else if (strncmp(line, ".\\\"", 3)) + { + /* + * Unknown... + */ + + if ((lineptr = strchr(line, ' ')) != NULL) + *lineptr = '\0'; + else if ((lineptr = strchr(line, '\n')) != NULL) + *lineptr = '\0'; + + fprintf(stderr, "mantohtml: Unknown man page command \'%s\' on line %d!\n", + line, linenum); + } + + /* + * Skip continuation lines... + */ + + lineptr = line + strlen(line) - 2; + if (lineptr >= line && *lineptr == '\\') + { + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + lineptr = line + strlen(line) - 2; + + if (lineptr < line || *lineptr != '\\') + break; + } + } + } + else + { + /* + * Process man page text... + */ + +process_text: + + for (lineptr = line; *lineptr; lineptr ++) + { + if (!strncmp(lineptr, "http://", 7)) + { + /* + * Embed URL... + */ + + for (endptr = lineptr + 7; + *endptr && !isspace(*endptr & 255); + endptr ++); + + endchar = *endptr; + *endptr = '\0'; + + fprintf(outfile, "%s", lineptr, lineptr); + *endptr = endchar; + lineptr = endptr - 1; + } + else if (!strncmp(lineptr, "\\fI", 3) && + (endptr = strstr(lineptr, "\\fR")) != NULL && + (paren = strchr(lineptr, '(')) != NULL && + paren < endptr) + { + /* + * Link to man page? + */ + + char manfile[1024], /* Man page filename */ + manurl[1024]; /* Man page URL */ + + + /* + * See if the man file is available locally... + */ + + lineptr += 3; + endchar = *paren; + *paren = '\0'; + + snprintf(manfile, sizeof(manfile), "%s.man", lineptr); + snprintf(manurl, sizeof(manurl), "man-%s.html?TOPIC=Man+Pages", + lineptr); + + *paren = endchar; + endchar = *endptr; + *endptr = '\0'; + + if (access(manfile, 0)) + { + /* + * Not a local man page, just do it italic... + */ + + fputs("", outfile); + while (*lineptr) + putc_entity(*lineptr++, outfile); + fputs("", outfile); + } + else + { + /* + * Local man page, do a link... + */ + + fprintf(outfile, "", manurl); + while (*lineptr) + putc_entity(*lineptr++, outfile); + fputs("", outfile); + } + + *endptr = endchar; + lineptr = endptr + 2; + } + else if (*lineptr == '\\') + { + lineptr ++; + if (!*lineptr) + break; + else if (isdigit(lineptr[0]) && isdigit(lineptr[1]) && + isdigit(lineptr[2])) + { + fprintf(outfile, "&#%d;", ((lineptr[0] - '0') * 8 + + lineptr[1] - '0') * 8 + + lineptr[2] - '0'); + lineptr += 2; + } + else if (*lineptr == '&') + continue; + else if (*lineptr == 's') + { + while (lineptr[1] == '-' || isdigit(lineptr[1])) + lineptr ++; + } + else if (*lineptr == '*') + { + lineptr += 2; + } + else if (*lineptr != 'f') + putc_entity(*lineptr, outfile); + else + { + lineptr ++; + if (!*lineptr) + break; + else + { + fputs(end_fonts[font], outfile); + + switch (*lineptr) + { + default : /* Regular */ + font = 0; + break; + case 'B' : /* Bold */ + case 'b' : + font = 1; + break; + case 'I' : /* Italic */ + case 'i' : + font = 2; + break; + } + + fputs(start_fonts[font], outfile); + } + } + } + else + putc_entity(*lineptr, outfile); + } + + if (post) + { + fputs(post, outfile); + post = NULL; + } + } + } + + fprintf(outfile, "%s\n", end_fonts[font]); + + if (blist) + { + fputs("\n\n", outfile); + } + + if (list) + { + if (list == 1) + fputs("\n", outfile); + else if (list) + fputs("

\n", outfile); + + fputs("
\n", outfile); + } + + fputs("\n" + "\n", outfile); + + /* + * Close files... + */ + + if (infile != stdin) + fclose(infile); + + if (outfile != stdout) + fclose(outfile); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'putc_entity()' - Put a single character, using entities as needed. + */ + +static void +putc_entity(int ch, /* I - Character */ + FILE *fp) /* I - File */ +{ + if (ch == '&') + fputs("&", fp); + else if (ch == '<') + fputs("<", fp); + else + putc(ch, fp); +} + + +/* + * 'strmove()' - Move characters within a string. + */ + +static void +strmove(char *d, /* I - Destination */ + const char *s) /* I - Source */ +{ + while (*s) + *d++ = *s++; + + *d = '\0'; +} + + +/* + * End of "$Id$". + */ diff --git a/man/mime.convs.man b/man/mime.convs.man new file mode 100644 index 0000000000..e3670eb91a --- /dev/null +++ b/man/mime.convs.man @@ -0,0 +1,46 @@ +.\" +.\" "$Id: mime.convs.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" mime.convs man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH mime.convs 5 "CUPS" "20 March 2006" "Apple Inc." +.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 +(preferably) to other files in the CUPS configuration directory. +.LP +Each line in the \fImime.convs\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 +\fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, +\fImime.types(5)\fR, \fIprinters.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: mime.convs.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/mime.types.man b/man/mime.types.man new file mode 100644 index 0000000000..b45e80a766 --- /dev/null +++ b/man/mime.types.man @@ -0,0 +1,115 @@ +.\" +.\" "$Id: mime.types.man 8652 2009-05-16 23:48:35Z mike $" +.\" +.\" mime.types man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH mime.types 5 "CUPS" "16 May 2009" "Apple Inc." +.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 +(preferably) in additional files in the CUPS configuration +directory 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 +MIME type names are case-insensitive and are sorted in ascending alphanumeric +order for the purposes of matching. See the "TYPE MATCHING AND PRIORITY" +section for more information. +.LP +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 +priority(number) +.br +Specifies the relative priority of this MIME type. The default priority is 100. +Larger values have higher priority while smaller values have lower priority. +.TP 5 +string(offset,"string") +.br +True if bytes are identical to string +.TP 5 +istring(offset,"string") +.br +True if a case-insensitive comparison of the bytes is identical +.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 TYPE MATCHING AND PRIORITY +When CUPS needs to determine the MIME type of a given file, it checks every +MIME type defined in the .types files. When two types have the same matching +rules, the type chosen will depend on the type name and priority, with higher- +priority types being used over lower-priority ones. If the types have the same +priority, the type names are sorted alphanumerically in ascending order and the +first type is chosen. +.LP +For example, if two types "text/bar" and "text/foo" are defined as matching the +extension "doc", normally the type "text/bar" will be chosen since its name is +alphanumerically smaller than "text/foo". However, if "text/foo" also defines a +higher priority than "text/bar", "text/foo" will be chosen instead. +.SH SEE ALSO +\fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, +\fImime.convs(5)\fR, \fIprinters.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: mime.types.man 8652 2009-05-16 23:48:35Z mike $". +.\" diff --git a/man/notifier.man b/man/notifier.man new file mode 100644 index 0000000000..d2cd149eb6 --- /dev/null +++ b/man/notifier.man @@ -0,0 +1,157 @@ +.\" +.\" "$Id$" +.\" +.\" notifier man page for CUPS. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH notifier 7 "CUPS" "12 May 2009" "Apple Inc." +.SH NAME +notifier \- cups notification interface +.SH SYNOPSIS +.B notifier +.I recipient +[ +.I user-data +] +.SH DESCRIPTION +The CUPS notifier interface provides a standard method for adding support for +new event notification methods to CUPS. Each notifier delivers one or more IPP +events from the standard input to the specified recipient. +.LP +Notifiers \fBmust\fR read IPP messages from the standard input using the +ippNew and ippReadFile functions and exit on error. Notifiers are encouraged to +exit after a suitable period of inactivity, however they may exit after reading +the first message or stay running until an error is seen. +.SH LOG MESSAGES +Messages sent to stderr are generally logged to the current \fIErrorLog\fR. +Each line begins with a standard prefix: + +.TP 5 +ALERT: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "alert" log level. + +.TP 5 +CRIT: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "critical" log level. + +.TP 5 +DEBUG: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "debug" log level. + +.TP 5 +DEBUG2: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "debug2" log level. + +.TP 5 +EMERG: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "emergency" log level. + +.TP 5 +ERROR: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "error" log level. + +.TP 5 +INFO: message +.br +Sets the printer-state-message attribute. If the current \fILogLevel\fR +is set to "debug2", also adds the specified message to the +current \fIErrorLog\fR using the "info" log level. + +.TP 5 +NOTICE: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "notice" log level. + +.TP 5 +WARNING: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "warning" log level. + +.SH ENVIRONMENT VARIABLES +The following environment variables are defined by the CUPS server when +executing the notifier: + +.TP 5 +CHARSET +.br +The default text character set, typically utf-8. + +.TP 5 +CUPS_CACHEDIR +.br +The directory for semi-persistent cache files can be found. + +.TP 5 +CUPS_DATADIR +.br +The directory where data files can be found. + +.TP 5 +CUPS_FILETYPE +.br +The type of file being printed: "job-sheet" for a banner page and "document" +for a regular print file. + +.TP 5 +CUPS_SERVERROOT +.br +The root directory of the server. + +.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 +SOFTWARE +.br +The name and version number of the server (typically CUPS/1.2). + +.TP 5 +TZ +.br +The timezone of the server. + +.TP 5 +USER +.br +The user executing the filter, typically "lp"; consult the \fIcupsd.conf(5)\fR +file for the current setting. + +.SH SEE ALSO +\fIbackend(7)\fR, \fIcupsd(8)\fR, \fIfilter(7)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/ppdc.man b/man/ppdc.man new file mode 100644 index 0000000000..98f1c06f05 --- /dev/null +++ b/man/ppdc.man @@ -0,0 +1,80 @@ +.\" +.\" "$Id: ppdc.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" ppdc man page for the Common UNIX Printing System. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH ppdc 1 "CUPS" "10 October 2008" "Apple Inc." +.SH NAME +ppdc \- cups ppd compiler +.SH SYNOPSIS +.B ppdc +[ -D +.I name[=value] +] [ -I +.I include-directory +] [ -c +.I message-catalog +] [ -d +.I output-directory +] [ -l +.I language(s) +] [-m] [-t] [ -v ] [ -z ] [ --cr ] [ --crlf ] [ --lf ] +.I source-file +.SH DESCRIPTION +\fIppdc\fR compiles PPDC source files into one or more PPD +files. +.PP +The \fI-D\fR option sets the named variable for use in the +source file. It is equivalent to using the #define directive +in the source file. +.PP +The \fI-I\fR option specifies an alternate include directory; +multiple \fI-I\fR options can be supplied to add additional +directories. +.PP +The \fI-c\fR option specifies a single message catalog file in GNU +gettext source format (filename.po) to be used for localization. +.PP +The \fI-d\fR option specifies the output directory for PPD +files. The default output directory is "ppd". +.PP +The \fI-l\fR option specifies one or more languages to use when +localizing the PPD file(s). The default language is "en" +(English). Separate multiple languages with commas, for example +"de_DE,en_UK,es_ES,es_MX,es_US,fr_CA,fr_FR,it_IT" will create PPD +files with German, UK English, Spanish (Spain, Mexico, and US), +French (France and Canada), and Italian languages in each file. +.PP +The \fI-m\fR option specifies that the output filename should be +based on the ModelName value instead of FileName or PCFilenName. +.PP +The \fI-t\fR option specifies that PPD files should be tested instead +of generated. +.PP +The \fI-v\fR option provides more verbose output, basically a +running status of which files are being loaded or written. +.PP +The \fI-z\fR option generates compressed PPD files (filename.ppd.gz). +The default is to generate uncompressed PPD files. +.PP +The \fI--cr\fR, \fI--crlf\fR, and \fI--lf\fR options specify the +line ending to use - carriage return, carriage return and line feed, +or line feed. The default is to use the line feed character alone. +.SH SEE ALSO +ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5) +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: ppdc.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/ppdcfile.man b/man/ppdcfile.man new file mode 100644 index 0000000000..ec5db8d040 --- /dev/null +++ b/man/ppdcfile.man @@ -0,0 +1,171 @@ +.\" +.\" "$Id: ppdcfile.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" ppdcfile man page for the Common UNIX Printing System. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH ppdcfile 5 "CUPS" "20 May 2008" "Apple Inc." +.SH NAME +ppdcfile \- cups ppd compiler source file format +.SH DESCRIPTION +The CUPS PPD compiler reads meta files that contain descriptions +of one or more PPD files to be generated by \fIppdc\fR. This man +page provides a quick reference to the supported keywords and +should be used in conjuction with the Common UNIX Printing System +Developers Manual. +.PP +The source file format is plain ASCII text that can be edited +using your favorite text editor. Comments are supported using +the C (/* ... */) and C++ (// ...) comment mechanisms. +.PP +Printer driver information can be grouped and shared using +curley braces ({ ... }); PPD files are written when a close +brace or end-of-file is seen and a PCFileName directive has been +defined. +.PP +Directives may be placed anywhere on a line and are followed by +one or more values. The following is a list of the available +directives and the values they accept: +.TP 5 +\fB#define\fR name value +.TP 5 +\fB#elif\fR {name | value} +.TP 5 +\fB#else\fR +.TP 5 +\fB#endif\fR +.TP 5 +\fB#font\fR name encoding "version" charset status +.TP 5 +\fB#if\fR {name | value} +.TP 5 +\fB#include\fR +.TP 5 +\fB#include\fR "filename" +.TP 5 +\fB#media\fR name width length +.TP 5 +\fB#media\fR "name/text" width length +.TP 5 +\fB#po\fR locale "filename.po" +.TP 5 +\fBAttribute\fR name "" value +.TP 5 +\fBAttribute\fR name keyword value +.TP 5 +\fBAttribute\fR name "keyword/text" value +.TP 5 +\fBChoice\fR name "code" +.TP 5 +\fBChoice\fR "name/text" "code" +.TP 5 +\fBColorDevice\fR boolean-value +.TP 5 +\fBColorModel\fR name colorspace colororder compression +.TP 5 +\fBColorModel\fR "name/text" colorspace colororder compression +.TP 5 +\fBColorProfile\fR resolution/mediatype gamma density matrix +.TP 5 +\fBCopyright\fR "text" +.TP 5 +\fBCustomMedia\fR name width length left bottom right top "size-code" "region-code" +.TP 5 +\fBCustomMedia\fR "name/text" width length left bottom right top "size-code" "region-code" +.TP 5 +\fBCutter\fR boolean-value +.TP 5 +\fBDarkness\fR temperature name +.TP 5 +\fBDarkness\fR temperature "name/text" +.TP 5 +\fBDriverType\fR type +.TP 5 +\fBDuplex\fR type +.TP 5 +\fBFilter\fR mime-type cost program +.TP 5 +\fBFinishing\fR name +.TP 5 +\fBFinishing\fR "name/text" +.TP 5 +\fBFont\fR * +.TP 5 +\fBFont\fR name encoding "version" charset status +.TP 5 +\fBGroup\fR name +.TP 5 +\fBGroup\fR "name/text" +.TP 5 +\fBHWMargins\fR left bottom right top +.TP 5 +\fBInputSlot\fR position name +.TP 5 +\fBInputSlot\fR position "name/text" +.TP 5 +\fBInstallable\fR name +.TP 5 +\fBInstallable\fR "name/text" +.TP 5 +\fBLocAttribute\fR name "keyword/text" value +.TP 5 +\fBManualCopies\fR boolean-value +.TP 5 +\fBManufacturer\fR "name" +.TP 5 +\fBMaxSize\fR width length +.TP 5 +\fBMediaSize\fR name +.TP 5 +\fBMediaType\fR type name +.TP 5 +\fBMediaType\fR type "name/text" +.TP 5 +\fBMinSize\fR width length +.TP 5 +\fBModelName\fR "name" +.TP 5 +\fBModelNumber\fR number +.TP 5 +\fBOption\fR name type section order +.TP 5 +\fBOption\fR "name/text" type section order +.TP 5 +\fBPCFileName\fR "filename.ppd" +.TP 5 +\fBResolution\fR colorspace bits-per-color row-count row-feed row-step name +.TP 5 +\fBResolution\fR colorspace bits-per-color row-count row-feed row-step "name/text" +.TP 5 +\fBSimpleColorProfile\fR resolution/mediatype density yellow-density red-density gamma red-adjust green-adjust blue-adjust +.TP 5 +\fBThroughput\fR pages-per-minute +.TP 5 +\fBUIConstraints\fR "*Option1 *Option2" +.TP 5 +\fBUIConstraints\fR "*Option1 Choice1 *Option2" +.TP 5 +\fBUIConstraints\fR "*Option1 *Option2 Choice2" +.TP 5 +\fBUIConstraints\fR "*Option1 Choice1 *Option2 Choice2" +.TP 5 +\fBVariablePaperSize\fR boolean-value +.TP 5 +\fBVersion\fR number +.SH SEE ALSO +ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1) +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: ppdcfile.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/ppdhtml.man b/man/ppdhtml.man new file mode 100644 index 0000000000..34c9e70ca9 --- /dev/null +++ b/man/ppdhtml.man @@ -0,0 +1,46 @@ +.\" +.\" "$Id: ppdhtml.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" ppdhtml man page for the Common UNIX Printing System. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH ppdhtml 1 "CUPS" "10 October 2008" "Apple Inc." +.SH NAME +ppdhtml \- cups html summary generator +.SH SYNOPSIS +.B ppdhtml +[ -D +.I name[=value] +] [ -I +.I include-directory +] +.I source-file +.SH DESCRIPTION +\fIppdhtml\fR reads a driver information file and produces a +HTML summary page that lists all of the drivers in a file and +the supported options. +.PP +The \fI-D\fR option sets the named variable for use in the +source file. It is equivalent to using the #define directive +in the source file. +.PP +The \fI-I\fR option specifies an alternate include directory; +multiple \fI-I\fR options can be supplied to add additional +directories. +.SH SEE ALSO +ppdc(1), ppdcfile(5), ppdi(1), ppdmerge(1), ppdpo(1) +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: ppdhtml.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/ppdi.man b/man/ppdi.man new file mode 100644 index 0000000000..95a5225dc6 --- /dev/null +++ b/man/ppdi.man @@ -0,0 +1,46 @@ +.\" +.\" "$Id: ppdi.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" ppdi man page for the Common UNIX Printing System. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH ppdi 1 "CUPS" "20 May 2008" "Apple Inc." +.SH NAME +ppdi \- import ppd files +.SH SYNOPSIS +.B ppdi +[ \-I +.I include-directory +] [ \-o +.I source-file +] +.I ppd-file +[ +.I ppd-file2 ... ppd-fileN +] +.SH DESCRIPTION +\fIppdi\fR imports one or more PPD files into a PPD compiler source file. +Multiple languages of the same PPD file are merged into a single printer +definition to facilitate accurate changes for all localizations. +.PP +The \fI-o\fR option specifies the PPD source file to update. If the source +file does not exist, a new source file is created. Otherwise the existing +file is merged with the new PPD file(s) on the command-line. If no source +file is specified, the filename "ppdi.drv" is used. +.SH SEE ALSO +ppdc(1), ppdhtml(1), ppdmerge(1), ppdpo(1), ppdcfile(5) +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: ppdi.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/ppdmerge.man b/man/ppdmerge.man new file mode 100644 index 0000000000..701fca1f8e --- /dev/null +++ b/man/ppdmerge.man @@ -0,0 +1,47 @@ +.\" +.\" "$Id: ppdmerge.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" ppdmerge man page for the Common UNIX Printing System. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH ppdmerge 1 "CUPS" "20 May 2008" "Apple Inc." +.SH NAME +ppdmerge \- merge ppd files +.SH SYNOPSIS +.B ppdmerge +[ \-o +.I output-ppd-file +] +.I ppd-file +.I ppd-file2 +[ +.I ... ppd-fileN +] +.SH DESCRIPTION +\fIppdmerge\fR merges two or more PPD files into a single, multi-language +PPD file. +.PP +The \fI-o\fR option specifies the PPD file to create. If not specified, +the merged PPD file is written to the standard output. If the output file +already exists, the new +.SH NOTES +\fIppdmerge\fR does not check whether the merged PPD files are for the +same device. Merging of different device PPDs will yield unpredictable +results. +.SH SEE ALSO +cupsprofile(1), ppdc(1), ppdhtml(1), ppdi(1), ppdpo(1), ppdcfile(5) +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: ppdmerge.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/ppdpo.man b/man/ppdpo.man new file mode 100644 index 0000000000..8c3b1793b1 --- /dev/null +++ b/man/ppdpo.man @@ -0,0 +1,52 @@ +.\" +.\" "$Id: ppdpo.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" ppdpo man page for the Common UNIX Printing System. +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH ppdpo 1 "CUPS" "10 October 2008" "Apple Inc." +.SH NAME +ppdpo \- ppd message catalog generator +.SH SYNOPSIS +.B ppdpo +[ -D +.I name[=value] +] [ -I +.I include-directory +] [ -o +.I output-file +] +.I source-file +.SH DESCRIPTION +\fIppdpo\fR extracts UI strings from PPDC source files and updates either +a GNU gettext or Mac OS X strings format message catalog source file for +translation. +.PP +The \fI-D\fR option sets the named variable for use in the +source file. It is equivalent to using the #define directive +in the source file. +.PP +The \fI-I\fR option specifies an alternate include directory; +multiple \fI-I\fR options can be supplied to add additional +directories. +.PP +The \fI-o\fR option specifies the output file. The supported extensions are +".po" or ".po.gz" for GNU gettext format message catalogs and ".strings" for +Mac OS X strings files. +.SH SEE ALSO +ppdc(1), ppdhtml(1), ppdi(1), ppdmerge(1), ppdcfile(5) +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: ppdpo.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/printers.conf.man b/man/printers.conf.man new file mode 100644 index 0000000000..54f7886e30 --- /dev/null +++ b/man/printers.conf.man @@ -0,0 +1,124 @@ +.\" +.\" "$Id: printers.conf.man 8581 2009-04-29 22:54:48Z mike $" +.\" +.\" printers.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH printers.conf 5 "CUPS" "29 April 2009" "Apple Inc." +.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 + ... +.br +Defines a specific printer. +.TP 5 + ... +.br +Defines a default printer. +.TP 5 +Accepting Yes +.TP 5 +Accepting No +.br +Specifies whether the printer is accepting new jobs. +.TP 5 +AllowUser [ user @group ... ] +.br +Allows specific users and groups to print to the printer. +.TP 5 +DenyUser [ user @group ... ] +.br +Prevents specific users and groups from printing to the printer. +.TP 5 +DeviceURI uri +.br +Specifies the device URI for a printer. +.TP 5 +ErrorPolicy abort-job +.TP 5 +ErrorPolicy retry-current-job +.TP 5 +ErrorPolicy retry-job +.TP 5 +ErrorPolicy stop-printer +.br +Specifies the error policy for the printer. +.TP 5 +Info text +.br +Specifies human-readable text describing the printer. +.TP 5 +JobSheets banner banner +.br +Specifies the banner pages to use for the printer. +.TP 5 +KLimit number +.br +Specifies the job-k-limit value for the printer. +.TP 5 +Location text +.br +Specifies human-readable text describing the location of the printer. +.TP 5 +OpPolicy name +.br +Specifies the operation policy for the printer. +.TP 5 +PageLimit number +.br +Specifies the job-page-limit value for the printer. +.TP 5 +PortMonitor monitor +.br +Specifies the port monitor for a printer. +.TP 5 +QuotaPeriod seconds +.br +Specifies the job-quota-period value for the printer. +.TP 5 +Shared Yes +.TP 5 +Shared No +.br +Specifies whether the printer is shared. +.TP 5 +State idle +.TP 5 +State stopped +.br +Specifies the initial state of the printer (Idle or Stopped) +.TP 5 +StateMessage text +.br +Specifies the message associated with the state. +.TP 5 +StateTime seconds +.br +Specifies the date/time associated with the state. +.SH SEE ALSO +\fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, +\fImime.convs(5)\fR, \fImime.types(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: printers.conf.man 8581 2009-04-29 22:54:48Z mike $". +.\" diff --git a/man/subscriptions.conf.man b/man/subscriptions.conf.man new file mode 100644 index 0000000000..75f893342b --- /dev/null +++ b/man/subscriptions.conf.man @@ -0,0 +1,89 @@ +.\" +.\" "$Id: subscriptions.conf.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" subscriptions.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH subscriptions.conf 5 "CUPS" "30 April 2006" "Apple Inc." +.SH NAME +subscriptions.conf \- subscriptions file for cups +.SH DESCRIPTION +The \fIsubscriptions.conf\fR file defines the local subscriptions +that are active. It is normally located in the \fI/etc/cups\fR +directory and is generated automatically by the \fIcupsd(8)\fR +program when subscriptions are created, renewed, or cancelled. +.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 + ... +.br +Defines a subscription. +.TP 5 +Events name [ ... name ] +.br +Specifies the events that are subscribed. +.TP 5 +ExpirationTime unix-time +.br +Specifies the expiration time of a subscription as a UNIX time +value in seconds since January 1st, 1970. +.TP 5 +Interval seconds +.br +Specifies the preferred time interval for event notifications in +seconds. +.TP 5 +JobId job-id +.br +Specifies the job ID associated with the subscription. +.TP 5 +LeaseDuration seconds +.br +Specifies the number of seconds that the subscription is valid +for. If 0, the subscription does not expire. +.TP 5 +NextEventId number +.br +Specifies the next notify-sequence-number to use for the +subscription. +.TP 5 +NextSubscriptionId number +.br +Specifies the next subscription-id to use. +.TP 5 +Owner username +.br +Specifies the user that owns the subscription. +.TP 5 +PrinterName printername +.br +Specifies the printer or class associated with the subscription. +.TP 5 +Recipient uri +.br +Specifies the notify-recipient-uri value for push-type notifications. +.TP 5 +UserData hex-escaped-data +.br +Specifies user data to be included in event notifications. This +is typically the "from" address in mailto: notifications. +.SH SEE ALSO +\fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, +\fImime.convs(5)\fR, \fImime.types(5)\fR, \fRprinters.conf(5)\fR +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: subscriptions.conf.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/monitor/Dependencies b/monitor/Dependencies new file mode 100644 index 0000000000..af96766440 --- /dev/null +++ b/monitor/Dependencies @@ -0,0 +1,8 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +bcp.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +bcp.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h +bcp.o: ../cups/file.h ../cups/language.h +tbcp.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +tbcp.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h +tbcp.o: ../cups/file.h ../cups/language.h diff --git a/monitor/Makefile b/monitor/Makefile new file mode 100644 index 0000000000..7fb7f267e9 --- /dev/null +++ b/monitor/Makefile @@ -0,0 +1,146 @@ +# +# "$Id$" +# +# Port monitor makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +# This file is subject to the Apple OS-Developed Software exception. +# + +include ../Makedefs + +TARGETS = bcp tbcp + +OBJS = bcp.o tbcp.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# 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-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + $(INSTALL_DIR) -m 755 $(SERVERBIN)/monitor + for file in $(TARGETS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/monitor; \ + done + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(TARGETS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall all targets... +# + +uninstall: + for file in $(TARGETS); do \ + $(RM) $(SERVERBIN)/monitor/$$file; \ + done + -$(RMDIR) $(SERVERBIN)/monitor + -$(RMDIR) $(SERVERBIN) + + +# +# bcp +# + +bcp: bcp.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ bcp.o $(LIBS) + + +# +# tbcp +# + +tbcp: tbcp.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ tbcp.o $(LIBS) + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/monitor/bcp.c b/monitor/bcp.c new file mode 100644 index 0000000000..3b8eaccba1 --- /dev/null +++ b/monitor/bcp.c @@ -0,0 +1,290 @@ +/* + * "$Id$" + * + * TBCP port monitor for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry... + * psgets() - Get a line from a file. + * pswrite() - Write data from a file. + */ + +/* + * Include necessary headers... + */ + +#include +#include + + +/* + * Local functions... + */ + +static char *psgets(char *buf, size_t *bytes, FILE *fp); +static size_t pswrite(const char *buf, size_t bytes, FILE *fp); + + +/* + * 'main()' - Main entry... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *fp; /* File to print */ + int copies; /* Number of copies left */ + char line[1024]; /* Line/buffer from stream/file */ + size_t linelen; /* Length of line */ + ppd_file_t *ppd; /* PPD file */ + + + /* + * Check command-line... + */ + + if (argc < 6 || argc > 7) + { + fputs("ERROR: tbcp job-id user title copies options [file]\n", stderr); + return (1); + } + + if (argc == 6) + { + copies = 1; + fp = stdin; + } + else + { + copies = atoi(argv[4]); + fp = fopen(argv[6], "rb"); + + if (!fp) + { + perror(argv[6]); + return (1); + } + } + + /* + * Open the PPD file as needed... + */ + + ppd = ppdOpenFile(getenv("PPD")); + + /* + * Copy the print file to stdout... + */ + + while (copies > 0) + { + copies --; + + if (ppd && ppd->jcl_begin) + fputs(ppd->jcl_begin, stdout); + if (ppd && ppd->jcl_ps) + fputs(ppd->jcl_ps, stdout); + + if (!ppd || ppd->language_level == 1) + { + /* + * Use setsoftwareiomode for BCP mode... + */ + + puts("%!PS-Adobe-3.0 ExitServer"); + puts("%%Title: (BCP - Level 1)"); + puts("%%EndComments"); + puts("%%BeginExitServer: 0"); + puts("serverdict begin 0 exitserver"); + puts("%%EndExitServer"); + puts("statusdict begin"); + puts("/setsoftwareiomode known {100 setsoftwareiomode}"); + puts("end"); + puts("%EOF"); + } + else + { + /* + * Use setdevparams for BCP mode... + */ + + puts("%!PS-Adobe-3.0"); + puts("%%Title: (BCP - Level 2)"); + puts("%%EndComments"); + puts("currentsysparams"); + puts("/CurInputDevice 2 copy known {"); + puts("get"); + puts("<> setdevparams"); + puts("}{"); + puts("pop pop"); + puts("} ifelse"); + puts("%EOF"); + } + + if (ppd && ppd->jcl_end) + fputs(ppd->jcl_end, stdout); + else if (!ppd || ppd->num_filters == 0) + putchar(0x04); + + /* + * Loop until we see end-of-file... + */ + + do + { + linelen = sizeof(line); + if (psgets(line, &linelen, fp) == NULL) + break; + } + while (pswrite(line, linelen, stdout) > 0); + + fflush(stdout); + } + + return (0); +} + + +/* + * '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 *bytes, /* IO - Length of buffer */ + FILE *fp) /* I - File to read from */ +{ + char *bufptr; /* Pointer into buffer */ + int ch; /* Character from file */ + size_t len; /* Max length of string */ + + + len = *bytes - 1; + bufptr = buf; + ch = EOF; + + while ((bufptr - buf) < len) + { + if ((ch = getc(fp)) == EOF) + break; + + if (ch == '\r') + { + /* + * Got a CR; see if there is a LF as well... + */ + + ch = getc(fp); + + if (ch != EOF && ch != '\n') + { + ungetc(ch, fp); /* Nope, save it for later... */ + ch = '\r'; + } + else + *bufptr++ = '\r'; + break; + } + else if (ch == '\n') + break; + else + *bufptr++ = ch; + } + + /* + * Add a trailing newline if it is there... + */ + + if (ch == '\n' || ch == '\r') + { + if ((bufptr - buf) < len) + *bufptr++ = ch; + else + ungetc(ch, fp); + } + + /* + * Nul-terminate the string and return it (or NULL for EOF). + */ + + *bufptr = '\0'; + *bytes = bufptr - buf; + + if (ch == EOF && bufptr == buf) + return (NULL); + else + return (buf); +} + + +/* + * 'pswrite()' - Write data from a file. + */ + +static size_t /* O - Number of bytes written */ +pswrite(const char *buf, /* I - Buffer to write */ + size_t bytes, /* I - Bytes to write */ + FILE *fp) /* I - File to write to */ +{ + size_t count; /* Remaining bytes */ + + + for (count = bytes; count > 0; count --, buf ++) + switch (*buf) + { + case 0x04 : /* CTRL-D */ + if (bytes == 1) + { + /* + * Don't quote the last CTRL-D... + */ + + putchar(0x04); + break; + } + + case 0x01 : /* CTRL-A */ + case 0x03 : /* CTRL-C */ + case 0x05 : /* CTRL-E */ + case 0x11 : /* CTRL-Q */ + case 0x13 : /* CTRL-S */ + case 0x14 : /* CTRL-T */ + case 0x1c : /* CTRL-\ */ + if (putchar(0x01) < 0) + return (-1); + if (putchar(*buf ^ 0x40) < 0) + return (-1); + break; + + default : + if (putchar(*buf) < 0) + return (-1); + break; + } + + return (bytes); +} + + +/* + * End of "$Id$". + */ diff --git a/monitor/tbcp.c b/monitor/tbcp.c new file mode 100644 index 0000000000..d10ee345fb --- /dev/null +++ b/monitor/tbcp.c @@ -0,0 +1,283 @@ +/* + * "$Id$" + * + * TBCP port monitor for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry... + * psgets() - Get a line from a file. + * pswrite() - Write data from a file. + */ + +/* + * Include necessary headers... + */ + +#include +#include + + +/* + * Local functions... + */ + +static char *psgets(char *buf, size_t *bytes, FILE *fp); +static size_t pswrite(const char *buf, size_t bytes, FILE *fp); + + +/* + * 'main()' - Main entry... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *fp; /* File to print */ + int copies; /* Number of copies left */ + char line[1024]; /* Line/buffer from stream/file */ + size_t linelen; /* Length of line */ + + + /* + * Check command-line... + */ + + if (argc < 6 || argc > 7) + { + fputs("ERROR: tbcp job-id user title copies options [file]\n", stderr); + return (1); + } + + if (argc == 6) + { + copies = 1; + fp = stdin; + } + else + { + copies = atoi(argv[4]); + fp = fopen(argv[6], "rb"); + + if (!fp) + { + perror(argv[6]); + return (1); + } + } + + /* + * Copy the print file to stdout... + */ + + while (copies > 0) + { + copies --; + + /* + * Read the first line... + */ + + linelen = sizeof(line); + if (psgets(line, &linelen, fp) == NULL) + { + fputs("ERROR: Empty print file!\n", stderr); + return (1); + } + + /* + * Handle leading PJL fun... + */ + + if (!strncmp(line, "\033%-12345X", 9) || !strncmp(line, "@PJL ", 5)) + { + /* + * Yup, we have leading PJL fun, so copy it until we hit a line + * with "ENTER LANGUAGE"... + */ + + while (strstr(line, "ENTER LANGUAGE") == NULL) + { + fwrite(line, 1, linelen, stdout); + + linelen = sizeof(line); + if (psgets(line, &linelen, fp) == NULL) + break; + } + } + else + { + /* + * No PJL stuff, just add the UEL... + */ + + fputs("\033%-12345X", stdout); + } + + /* + * Switch to TBCP mode... + */ + + fputs("\001M", stdout); + + /* + * Loop until we see end-of-file... + */ + + while (pswrite(line, linelen, stdout) > 0) + { + linelen = sizeof(line); + if (psgets(line, &linelen, fp) == NULL) + break; + } + + fflush(stdout); + } + + return (0); +} + + +/* + * '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 *bytes, /* IO - Length of buffer */ + FILE *fp) /* I - File to read from */ +{ + char *bufptr; /* Pointer into buffer */ + int ch; /* Character from file */ + size_t len; /* Max length of string */ + + + len = *bytes - 1; + bufptr = buf; + ch = EOF; + + while ((bufptr - buf) < len) + { + if ((ch = getc(fp)) == EOF) + break; + + if (ch == '\r') + { + /* + * Got a CR; see if there is a LF as well... + */ + + ch = getc(fp); + + if (ch != EOF && ch != '\n') + { + ungetc(ch, fp); /* Nope, save it for later... */ + ch = '\r'; + } + else + *bufptr++ = '\r'; + break; + } + else if (ch == '\n') + break; + else + *bufptr++ = ch; + } + + /* + * Add a trailing newline if it is there... + */ + + if (ch == '\n' || ch == '\r') + { + if ((bufptr - buf) < len) + *bufptr++ = ch; + else + ungetc(ch, fp); + } + + /* + * Nul-terminate the string and return it (or NULL for EOF). + */ + + *bufptr = '\0'; + *bytes = bufptr - buf; + + if (ch == EOF && bufptr == buf) + return (NULL); + else + return (buf); +} + + +/* + * 'pswrite()' - Write data from a file. + */ + +static size_t /* O - Number of bytes written */ +pswrite(const char *buf, /* I - Buffer to write */ + size_t bytes, /* I - Bytes to write */ + FILE *fp) /* I - File to write to */ +{ + size_t count; /* Remaining bytes */ + + + for (count = bytes; count > 0; count --, buf ++) + switch (*buf) + { + case 0x04 : /* CTRL-D */ + if (bytes == 1) + { + /* + * Don't quote the last CTRL-D... + */ + + putchar(0x04); + break; + } + + case 0x01 : /* CTRL-A */ + case 0x03 : /* CTRL-C */ + case 0x05 : /* CTRL-E */ + case 0x11 : /* CTRL-Q */ + case 0x13 : /* CTRL-S */ + case 0x14 : /* CTRL-T */ + case 0x1b : /* CTRL-[ (aka ESC) */ + case 0x1c : /* CTRL-\ */ + if (putchar(0x01) < 0) + return (-1); + if (putchar(*buf ^ 0x40) < 0) + return (-1); + break; + + default : + if (putchar(*buf) < 0) + return (-1); + break; + } + + return (bytes); +} + + +/* + * End of "$Id$". + */ diff --git a/notifier/Dependencies b/notifier/Dependencies new file mode 100644 index 0000000000..8f5cfed1d4 --- /dev/null +++ b/notifier/Dependencies @@ -0,0 +1,15 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +dbus.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +dbus.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +dbus.o: ../cups/string.h ../config.h +mailto.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +mailto.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +mailto.o: ../cups/i18n.h ../cups/transcode.h ../cups/string.h ../config.h +rss.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +rss.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +rss.o: ../cups/language.h ../cups/string.h ../config.h ../cups/array.h +testnotify.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +testnotify.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +testnotify.o: ../cups/file.h ../cups/language.h ../cups/language.h +testnotify.o: ../cups/string.h ../config.h diff --git a/notifier/Makefile b/notifier/Makefile new file mode 100644 index 0000000000..fd7eecbd95 --- /dev/null +++ b/notifier/Makefile @@ -0,0 +1,162 @@ +# +# "$Id$" +# +# Notifier makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + + +NOTIFIERS = $(DBUS_NOTIFIER) mailto rss +TARGETS = $(NOTIFIERS) testnotify +OBJS = dbus.o mailto.o rss.o testnotify.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) dbus.h + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + $(INSTALL_DIR) -m 775 -g $(CUPS_GROUP) $(CACHEDIR)/rss + + +# +# Install programs... +# + +install-exec: + echo Installing notifiers in $(SERVERBIN)/notifier... + $(INSTALL_DIR) -m 755 $(SERVERBIN)/notifier + for file in $(NOTIFIERS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/notifier; \ + done + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(NOTIFIERS) $(SYMROOT); \ + fi + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall all targets... +# + +uninstall: + for file in $(NOTIFIERS); do \ + $(RM) $(SERVERBIN)/notifier/$$file; \ + done + -$(RMDIR) $(SERVERBIN)/notifier + -$(RMDIR) $(SERVERBIN) + -$(RMDIR) $(CACHEDIR)/rss + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + + +# +# dbus +# + +dbus: dbus.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o dbus dbus.o $(DBUS_NOTIFIERLIBS) $(LIBS) + + +# +# mailto +# + +mailto: mailto.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o mailto mailto.o $(LIBS) + + +# +# rss +# + +rss: rss.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o rss rss.o $(LIBS) + + +# +# testnotify +# + +testnotify: testnotify.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o testnotify testnotify.o $(LIBS) + + +$(OBJS): ../Makedefs + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/notifier/dbus.c b/notifier/dbus.c new file mode 100644 index 0000000000..5804db7d2f --- /dev/null +++ b/notifier/dbus.c @@ -0,0 +1,552 @@ +/* + * "$Id$" + * + * D-Bus notifier for the Common UNIX Printing System (CUPS). + * + * Copyright 2008 by Apple Inc. + * Copyright (C) 2007 Red Hat, Inc. + * Copyright (C) 2007 Tim Waugh + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Read events and send DBUS notifications. + * acquire_lock() - Acquire a lock so we only have a single notifier running. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND +# define dbus_message_append_iter_init dbus_message_iter_init_append +# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, v) +# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, v) +# define dbus_message_iter_append_boolean(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, v) +#endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */ + + +/* + * D-Bus object: org.cups.cupsd.Notifier + * D-Bus object path: /org/cups/cupsd/Notifier + * + * D-Bus interface name: org.cups.cupsd.Notifier + * + * Signals: + * + * ServerRestarted(STRING text) + * Server has restarted. + * + * ServerStarted(STRING text) + * Server has started. + * + * ServerStopped(STRING text) + * Server has stopped. + * + * ServerAudit(STRING text) + * Security-related event. + * + * PrinterRestarted(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer has restarted. + * + * PrinterShutdown(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer has shutdown. + * + * PrinterStopped(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer has stopped. + * + * PrinterStateChanged(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer state has changed. + * + * PrinterFinishingsChanged(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer's finishings-supported attribute has changed. + * + * PrinterMediaChanged(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer's media-supported attribute has changed. + * + * PrinterAdded(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer has been added. + * + * PrinterDeleted(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer has been deleted. + * + * PrinterModified(STRING text, + * STRING printer-uri, + * STRING printer-name, + * UINT32 printer-state, + * STRING printer-state-reasons, + * BOOLEAN printer-is-accepting-jobs) + * Printer has been modified. + * + * text describes the event. + * printer-state-reasons is a comma-separated list. + * If printer-uri is "" in a Job* signal, the other printer-* parameters + * must be ignored. + * If the job name is not know, job-name will be "". + */ + +/* + * Constants... + */ + +enum +{ + PARAMS_NONE, + PARAMS_PRINTER, + PARAMS_JOB +}; + + +/* + * Local functions... + */ + +static int acquire_lock(int *fd, char *lockfile, size_t locksize); + + +/* + * 'main()' - Read events and send DBUS notifications. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + ipp_t *msg; /* Event message from scheduler */ + ipp_state_t state; /* IPP event state */ + struct sigaction action; /* POSIX sigaction data */ + DBusConnection *con = NULL; /* Connection to DBUS server */ + DBusError error; /* Error, if any */ + DBusMessage *message; /* Message to send */ + DBusMessageIter iter; /* Iterator for message data */ + int lock_fd = -1; /* Lock file descriptor */ + char lock_filename[1024]; + /* Lock filename */ + + + /* + * Don't buffer stderr... + */ + + setbuf(stderr, NULL); + + /* + * Ignore SIGPIPE signals... + */ + + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); + + /* + * Validate command-line options... + */ + + if (argc != 3) + { + fputs("Usage: dbus dbus:/// notify-user-data\n", stderr); + return (1); + } + + if (strncmp(argv[1], "dbus:", 5)) + { + fprintf(stderr, "ERROR: Bad URI \"%s\"!\n", argv[1]); + return (1); + } + + /* + * Loop forever until we run out of events... + */ + + for (;;) + { + ipp_attribute_t *attr; /* Current attribute */ + const char *event; /* Event name */ + const char *signame = NULL;/* DBUS signal name */ + char *printer_reasons = NULL; + /* Printer reasons string */ + const char *nul = ""; /* Empty string value */ + int no = 0; /* Boolean "no" value */ + int params = PARAMS_NONE; + /* What parameters to include? */ + + + /* + * Get the next event... + */ + + msg = ippNew(); + while ((state = ippReadFile(0, msg)) != IPP_DATA) + { + if (state <= IPP_IDLE) + break; + } + + fprintf(stderr, "DEBUG: state=%d\n", state); + + if (state == IPP_ERROR) + fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); + + if (state <= IPP_IDLE) + { + /* + * Out of messages, free memory and then exit... + */ + + ippDelete(msg); + break; + } + + /* + * Verify connection to DBUS server... + */ + + if (con && !dbus_connection_get_is_connected(con)) + { + dbus_connection_unref(con); + con = NULL; + } + + if (!con) + { + dbus_error_init(&error); + + con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (!con) + dbus_error_free(&error); + else + fputs("DEBUG: Connected to D-BUS\n", stderr); + } + + if (!con) + continue; + + if (lock_fd == -1 && + acquire_lock(&lock_fd, lock_filename, sizeof(lock_filename))) + continue; + + attr = ippFindAttribute(msg, "notify-subscribed-event", + IPP_TAG_KEYWORD); + if (!attr) + continue; + + event = attr->values[0].string.text; + if (!strncmp(event, "server-", 7)) + { + const char *word2 = event + 7; /* Second word */ + + if (!strcmp(word2, "restarted")) + signame = "ServerRestarted"; + else if (!strcmp(word2, "started")) + signame = "ServerStarted"; + else if (!strcmp(word2, "stopped")) + signame = "ServerStopped"; + else if (!strcmp(word2, "audit")) + signame = "ServerAudit"; + else + continue; + } + else if (!strncmp(event, "printer-", 8)) + { + const char *word2 = event + 8; /* Second word */ + + params = PARAMS_PRINTER; + if (!strcmp(word2, "restarted")) + signame = "PrinterRestarted"; + else if (!strcmp(word2, "shutdown")) + signame = "PrinterShutdown"; + else if (!strcmp(word2, "stopped")) + signame = "PrinterStopped"; + else if (!strcmp(word2, "state-changed")) + signame = "PrinterStateChanged"; + else if (!strcmp(word2, "finishings-changed")) + signame = "PrinterFinishingsChanged"; + else if (!strcmp(word2, "media-changed")) + signame = "PrinterMediaChanged"; + else if (!strcmp(word2, "added")) + signame = "PrinterAdded"; + else if (!strcmp(word2, "deleted")) + signame = "PrinterDeleted"; + else if (!strcmp(word2, "modified")) + signame = "PrinterModified"; + else + continue; + } + else if (!strncmp(event, "job-", 4)) + { + const char *word2 = event + 4; /* Second word */ + + params = PARAMS_JOB; + if (!strcmp(word2, "state-changed")) + signame = "JobState"; + else if (!strcmp(word2, "created")) + signame = "JobCreated"; + else if (!strcmp(word2, "completed")) + signame = "JobCompleted"; + else if (!strcmp(word2, "stopped")) + signame = "JobStopped"; + else if (!strcmp(word2, "config-changed")) + signame = "JobConfigChanged"; + else if (!strcmp(word2, "progress")) + signame = "JobProgress"; + else + continue; + } + else + continue; + + /* + * Create and send the new message... + */ + + fprintf(stderr, "DEBUG: %s\n", signame); + message = dbus_message_new_signal("/org/cups/cupsd/Notifier", + "org.cups.cupsd.Notifier", + signame); + + dbus_message_append_iter_init(message, &iter); + attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT); + if (!attr) + goto bail; + dbus_message_iter_append_string(&iter, &(attr->values[0].string.text)); + + if (params >= PARAMS_PRINTER) + { + char *p; /* Pointer into printer_reasons */ + size_t reasons_length; /* Required size of printer_reasons */ + int i; /* Looping var */ + int have_printer_params = 1;/* Do we have printer URI? */ + + /* STRING printer-uri or "" */ + attr = ippFindAttribute(msg, "notify-printer-uri", IPP_TAG_URI); + if (attr) + dbus_message_iter_append_string(&iter, &(attr->values[0].string.text)); + else + { + have_printer_params = 0; + dbus_message_iter_append_string(&iter, &nul); + } + + /* STRING printer-name */ + if (have_printer_params) + { + attr = ippFindAttribute(msg, "printer-name", IPP_TAG_NAME); + if (attr) + dbus_message_iter_append_string(&iter, + &(attr->values[0].string.text)); + else + goto bail; + } + else + dbus_message_iter_append_string(&iter, &nul); + + /* UINT32 printer-state */ + if (have_printer_params) + { + attr = ippFindAttribute(msg, "printer-state", IPP_TAG_ENUM); + if (attr) + dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer)); + else + goto bail; + } + else + dbus_message_iter_append_uint32(&iter, &no); + + /* STRING printer-state-reasons */ + if (have_printer_params) + { + attr = ippFindAttribute(msg, "printer-state-reasons", + IPP_TAG_KEYWORD); + if (attr) + { + for (reasons_length = 0, i = 0; i < attr->num_values; i++) + /* All need commas except the last, which needs a nul byte. */ + reasons_length += 1 + strlen(attr->values[i].string.text); + printer_reasons = malloc(reasons_length); + if (!printer_reasons) + goto bail; + p = printer_reasons; + for (i = 0; i < attr->num_values; i++) + { + strcpy(p, attr->values[i].string.text); + p += strlen(p); + if (i) + *p++ = ','; + } + dbus_message_iter_append_string(&iter, &printer_reasons); + } + else + goto bail; + } + else + dbus_message_iter_append_string(&iter, &nul); + + /* BOOL printer-is-accepting-jobs */ + if (have_printer_params) + { + attr = ippFindAttribute(msg, "printer-is-accepting-jobs", + IPP_TAG_BOOLEAN); + if (attr) + dbus_message_iter_append_boolean(&iter, &(attr->values[0].boolean)); + else + goto bail; + } + else + dbus_message_iter_append_boolean(&iter, &no); + } + + if (params >= PARAMS_JOB) + { + /* UINT32 job-id */ + attr = ippFindAttribute(msg, "notify-job-id", IPP_TAG_INTEGER); + if (!attr) + goto bail; + dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer)); + + /* UINT32 job-state */ + attr = ippFindAttribute(msg, "job-state", IPP_TAG_ENUM); + if (!attr) + goto bail; + dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer)); + + /* STRING job-state-reasons */ + attr = ippFindAttribute(msg, "job-state-reasons", IPP_TAG_KEYWORD); + if (!attr) + goto bail; + dbus_message_iter_append_string(&iter, &(attr->values[0].string.text)); + + /* STRING job-name or "" */ + attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME); + if (attr) + dbus_message_iter_append_string(&iter, &(attr->values[0].string.text)); + else + dbus_message_iter_append_string(&iter, &nul); + + /* UINT32 job-impressions-completed */ + attr = ippFindAttribute(msg, "job-impressions-completed", + IPP_TAG_INTEGER); + if (!attr) + goto bail; + dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer)); + } + + dbus_connection_send(con, message, NULL); + dbus_connection_flush(con); + + /* + * Cleanup... + */ + + bail: + + if (printer_reasons) + free(printer_reasons); + + dbus_message_unref(message); + ippDelete(msg); + } + + /* + * Remove lock file... + */ + + if (lock_fd >= 0) + { + close(lock_fd); + unlink(lock_filename); + } + + return (0); +} + + +/* + * 'acquire_lock()' - Acquire a lock so we only have a single notifier running. + */ + +static int /* O - 0 on success, -1 on failure */ +acquire_lock(int *fd, /* O - Lock file descriptor */ + char *lockfile, /* I - Lock filename buffer */ + size_t locksize) /* I - Size of filename buffer */ +{ + const char *tmpdir; /* Temporary directory */ + + + /* + * Figure out where to put the lock file... + */ + + if ((tmpdir = getenv("TMPDIR")) == NULL) + tmpdir = "/tmp"; + + snprintf(lockfile, locksize, "%s/cups-dbus-notifier-lockfile", tmpdir); + + /* + * Create the lock file and fail if it already exists... + */ + + if ((*fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0) + return (-1); + else + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/notifier/mailto.c b/notifier/mailto.c new file mode 100644 index 0000000000..689a555522 --- /dev/null +++ b/notifier/mailto.c @@ -0,0 +1,792 @@ +/* + * "$Id$" + * + * "mailto" notifier for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for the mailto notifier. + * email_message() - Email a notification message. + * load_configuration() - Load the mailto.conf file. + * pipe_sendmail() - Open a pipe to sendmail... + * print_attributes() - Print the attributes in a request... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Globals... + */ + +char mailtoCc[1024]; /* Cc email address */ +char mailtoFrom[1024]; /* From email address */ +char mailtoReplyTo[1024]; /* Reply-To email address */ +char mailtoSubject[1024]; /* Subject prefix */ +char mailtoSMTPServer[1024]; /* SMTP server to use */ +char mailtoSendmail[1024]; /* Sendmail program to use */ + + +/* + * Local functions... + */ + +void email_message(const char *to, const char *subject, + const char *text); +int load_configuration(void); +cups_file_t *pipe_sendmail(const char *to); +void print_attributes(ipp_t *ipp, int indent); + + +/* + * 'main()' - Main entry for the mailto notifier. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + ipp_t *msg; /* Event message from scheduler */ + ipp_state_t state; /* IPP event state */ + char *subject, /* Subject for notification message */ + *text; /* Text for notification message */ + cups_lang_t *lang; /* Language info */ + char temp[1024]; /* Temporary string */ + int templen; /* Length of temporary string */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* POSIX sigaction data */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * Don't buffer stderr... + */ + + setbuf(stderr, NULL); + + /* + * Ignore SIGPIPE signals... + */ + +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Validate command-line options... + */ + + if (argc != 3) + { + fputs("Usage: mailto mailto:user@domain.com notify-user-data\n", stderr); + return (1); + } + + if (strncmp(argv[1], "mailto:", 7)) + { + fprintf(stderr, "ERROR: Bad recipient \"%s\"!\n", argv[1]); + return (1); + } + + fprintf(stderr, "DEBUG: argc=%d\n", argc); + for (i = 0; i < argc; i ++) + fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + + /* + * Load configuration data... + */ + + if ((lang = cupsLangDefault()) == NULL) + return (1); + + if (!load_configuration()) + return (1); + + /* + * Get the reply-to address... + */ + + templen = sizeof(temp); + httpDecode64_2(temp, &templen, argv[2]); + + if (!strncmp(temp, "mailto:", 7)) + strlcpy(mailtoReplyTo, temp + 7, sizeof(mailtoReplyTo)); + else if (temp[0]) + fprintf(stderr, "WARNING: Bad notify-user-data value (%d bytes) ignored!\n", + templen); + + /* + * Loop forever until we run out of events... + */ + + for (;;) + { + /* + * Get the next event... + */ + + msg = ippNew(); + while ((state = ippReadFile(0, msg)) != IPP_DATA) + { + if (state <= IPP_IDLE) + break; + } + + fprintf(stderr, "DEBUG: state=%d\n", state); + + if (state == IPP_ERROR) + fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); + + if (state <= IPP_IDLE) + { + /* + * Out of messages, free memory and then exit... + */ + + ippDelete(msg); + return (0); + } + + /* + * Get the subject and text for the message, then email it... + */ + + subject = cupsNotifySubject(lang, msg); + text = cupsNotifyText(lang, msg); + + fprintf(stderr, "DEBUG: subject=\"%s\"\n", subject); + fprintf(stderr, "DEBUG: text=\"%s\"\n", text); + + if (subject && text) + email_message(argv[1] + 7, subject, text); + else + { + fputs("ERROR: Missing attributes in event notification!\n", stderr); + print_attributes(msg, 4); + } + + /* + * Free the memory used for this event... + */ + + if (subject) + free(subject); + + if (text) + free(text); + + ippDelete(msg); + } +} + + +/* + * 'email_message()' - Email a notification message. + */ + +void +email_message(const char *to, /* I - Recipient of message */ + const char *subject, /* I - Subject of message */ + const char *text) /* I - Text of message */ +{ + cups_file_t *fp; /* Pipe/socket to mail server */ + const char *nl; /* Newline to use */ + char response[1024]; /* SMTP response buffer */ + + + /* + * Connect to the mail server... + */ + + if (mailtoSendmail[0]) + { + /* + * Use the sendmail command... + */ + + fp = pipe_sendmail(to); + + if (!fp) + return; + + nl = "\n"; + } + else + { + /* + * Use an SMTP server... + */ + + char hostbuf[1024]; /* Local hostname */ + + + if (strchr(mailtoSMTPServer, ':')) + fp = cupsFileOpen(mailtoSMTPServer, "s"); + else + { + char spec[1024]; /* Host:service spec */ + + + snprintf(spec, sizeof(spec), "%s:smtp", mailtoSMTPServer); + fp = cupsFileOpen(spec, "s"); + } + + if (!fp) + { + fprintf(stderr, "ERROR: Unable to connect to SMTP server \"%s\"!\n", + mailtoSMTPServer); + return; + } + + fprintf(stderr, "DEBUG: Connected to \"%s\"...\n", mailtoSMTPServer); + + cupsFilePrintf(fp, "HELO %s\r\n", + httpGetHostname(NULL, hostbuf, sizeof(hostbuf))); + fprintf(stderr, "DEBUG: >>> HELO %s\n", hostbuf); + + if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500) + goto smtp_error; + fprintf(stderr, "DEBUG: <<< %s\n", response); + + cupsFilePrintf(fp, "MAIL FROM:%s\r\n", mailtoFrom); + fprintf(stderr, "DEBUG: >>> MAIL FROM:%s\n", mailtoFrom); + + if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500) + goto smtp_error; + fprintf(stderr, "DEBUG: <<< %s\n", response); + + cupsFilePrintf(fp, "RCPT TO:%s\r\n", to); + fprintf(stderr, "DEBUG: >>> RCPT TO:%s\n", to); + + if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500) + goto smtp_error; + fprintf(stderr, "DEBUG: <<< %s\n", response); + + cupsFilePuts(fp, "DATA\r\n"); + fputs("DEBUG: DATA\n", stderr); + + if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500) + goto smtp_error; + fprintf(stderr, "DEBUG: <<< %s\n", response); + + nl = "\r\n"; + } + + /* + * Send the message... + */ + + cupsFilePrintf(fp, "Date: %s%s", httpGetDateString(time(NULL)), nl); + cupsFilePrintf(fp, "From: %s%s", mailtoFrom, nl); + cupsFilePrintf(fp, "Subject: %s %s%s", mailtoSubject, subject, nl); + if (mailtoReplyTo[0]) + { + cupsFilePrintf(fp, "Sender: %s%s", mailtoReplyTo, nl); + cupsFilePrintf(fp, "Reply-To: %s%s", mailtoReplyTo, nl); + } + cupsFilePrintf(fp, "To: %s%s", to, nl); + if (mailtoCc[0]) + cupsFilePrintf(fp, "Cc: %s%s", mailtoCc, nl); + cupsFilePrintf(fp, "Content-Type: text/plain%s", nl); + cupsFilePuts(fp, nl); + cupsFilePrintf(fp, "%s%s", text, nl); + cupsFilePrintf(fp, ".%s", nl); + + /* + * Close the connection to the mail server... + */ + + if (mailtoSendmail[0]) + { + /* + * Close the pipe and wait for the sendmail command to finish... + */ + + int status; /* Exit status */ + + + cupsFileClose(fp); + + if (wait(&status)) + status = errno << 8; + + /* + * Report any non-zero status... + */ + + if (status) + { + if (WIFEXITED(status)) + fprintf(stderr, "ERROR: Sendmail command returned status %d!\n", + WEXITSTATUS(status)); + else + fprintf(stderr, "ERROR: Sendmail command crashed on signal %d!\n", + WTERMSIG(status)); + } + } + else + { + /* + * Finish up the SMTP submission and close the connection... + */ + + if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500) + goto smtp_error; + fprintf(stderr, "DEBUG: <<< %s\n", response); + + /* + * Process SMTP errors here... + */ + + smtp_error: + + cupsFilePuts(fp, "QUIT\r\n"); + fputs("DEBUG: QUIT\n", stderr); + + if (!cupsFileGets(fp, response, sizeof(response)) || atoi(response) >= 500) + fprintf(stderr, "ERROR: Got \"%s\" trying to QUIT connection.\n", + response); + else + fprintf(stderr, "DEBUG: <<< %s\n", response); + + cupsFileClose(fp); + + fprintf(stderr, "DEBUG: Closed connection to \"%s\"...\n", + mailtoSMTPServer); + } +} + + +/* + * 'load_configuration()' - Load the mailto.conf file. + */ + +int /* I - 1 on success, 0 on failure */ +load_configuration(void) +{ + cups_file_t *fp; /* mailto.conf file */ + const char *server_root, /* CUPS_SERVERROOT environment variable */ + *server_admin; /* SERVER_ADMIN environment variable */ + char line[1024], /* Line from file */ + *value; /* Value for directive */ + int linenum; /* Line number in file */ + + + /* + * Initialize defaults... + */ + + mailtoCc[0] = '\0'; + + if ((server_admin = getenv("SERVER_ADMIN")) != NULL) + strlcpy(mailtoFrom, server_admin, sizeof(mailtoFrom)); + else + snprintf(mailtoFrom, sizeof(mailtoFrom), "root@%s", + httpGetHostname(NULL, line, sizeof(line))); + + strlcpy(mailtoSendmail, "/usr/sbin/sendmail", sizeof(mailtoSendmail)); + + mailtoSMTPServer[0] = '\0'; + + mailtoSubject[0] = '\0'; + + /* + * Try loading the config file... + */ + + if ((server_root = getenv("CUPS_SERVERROOT")) == NULL) + server_root = CUPS_SERVERROOT; + + snprintf(line, sizeof(line), "%s/mailto.conf", server_root); + + if ((fp = cupsFileOpen(line, "r")) == NULL) + { + fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", line, + strerror(errno)); + return (1); + } + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!value) + { + fprintf(stderr, "ERROR: No value found for %s directive on line %d!\n", + line, linenum); + cupsFileClose(fp); + return (0); + } + + if (!strcasecmp(line, "Cc")) + strlcpy(mailtoCc, value, sizeof(mailtoCc)); + else if (!strcasecmp(line, "From")) + strlcpy(mailtoFrom, value, sizeof(mailtoFrom)); + else if (!strcasecmp(line, "Sendmail")) + { + strlcpy(mailtoSendmail, value, sizeof(mailtoSendmail)); + mailtoSMTPServer[0] = '\0'; + } + else if (!strcasecmp(line, "SMTPServer")) + { + mailtoSendmail[0] = '\0'; + strlcpy(mailtoSMTPServer, value, sizeof(mailtoSMTPServer)); + } + else if (!strcasecmp(line, "Subject")) + strlcpy(mailtoSubject, value, sizeof(mailtoSubject)); + else + { + fprintf(stderr, + "ERROR: Unknown configuration directive \"%s\" on line %d!\n", + line, linenum); + } + } + + /* + * Close file and return... + */ + + cupsFileClose(fp); + + return (1); +} + + +/* + * 'pipe_sendmail()' - Open a pipe to sendmail... + */ + +cups_file_t * /* O - CUPS file */ +pipe_sendmail(const char *to) /* I - To: address */ +{ + cups_file_t *fp; /* CUPS file */ + int pid; /* Process ID */ + int pipefds[2]; /* Pipe file descriptors */ + int argc; /* Number of arguments */ + char *argv[100], /* Argument array */ + line[1024], /* Sendmail command + args */ + *lineptr; /* Pointer into line */ + + + /* + * First break the mailtoSendmail string into arguments... + */ + + strlcpy(line, mailtoSendmail, sizeof(line)); + argv[0] = line; + argc = 1; + + for (lineptr = strchr(line, ' '); lineptr; lineptr = strchr(lineptr, ' ')) + { + while (*lineptr == ' ') + *lineptr++ = '\0'; + + if (*lineptr) + { + /* + * Point to the next argument... + */ + + argv[argc ++] = lineptr; + + /* + * Stop if we have too many... + */ + + if (argc >= (int)(sizeof(argv) / sizeof(argv[0]) - 2)) + break; + } + } + + argv[argc ++] = (char *)to; + argv[argc] = NULL; + + /* + * Create the pipe... + */ + + if (pipe(pipefds)) + { + perror("ERROR: Unable to create pipe"); + return (NULL); + } + + /* + * Then run the command... + */ + + if ((pid = fork()) == 0) + { + /* + * Child goes here - redirect stdin to the input side of the pipe, + * redirect stdout to stderr, and exec... + */ + + close(0); + dup(pipefds[0]); + + close(1); + dup(2); + + close(pipefds[0]); + close(pipefds[1]); + + execvp(argv[0], argv); + exit(errno); + } + else if (pid < 0) + { + /* + * Unable to fork - error out... + */ + + perror("ERROR: Unable to fork command"); + + close(pipefds[0]); + close(pipefds[1]); + + return (NULL); + } + + /* + * Create a CUPS file using the output side of the pipe and close the + * input side... + */ + + close(pipefds[0]); + + if ((fp = cupsFileOpenFd(pipefds[1], "w")) == NULL) + { + int status; /* Status of command */ + + + close(pipefds[1]); + wait(&status); + } + + return (fp); +} + + +/* + * 'print_attributes()' - Print the attributes in a request... + */ + +void +print_attributes(ipp_t *ipp, /* I - IPP request */ + int indent) /* I - Indentation */ +{ + int i; /* Looping var */ + ipp_tag_t group; /* Current group */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_value_t *val; /* Current value */ + static const char * const tags[] = /* Value/group tag strings */ + { + "reserved-00", + "operation-attributes-tag", + "job-attributes-tag", + "end-of-attributes-tag", + "printer-attributes-tag", + "unsupported-attributes-tag", + "subscription-attributes-tag", + "event-attributes-tag", + "reserved-08", + "reserved-09", + "reserved-0A", + "reserved-0B", + "reserved-0C", + "reserved-0D", + "reserved-0E", + "reserved-0F", + "unsupported", + "default", + "unknown", + "no-value", + "reserved-14", + "not-settable", + "delete-attr", + "admin-define", + "reserved-18", + "reserved-19", + "reserved-1A", + "reserved-1B", + "reserved-1C", + "reserved-1D", + "reserved-1E", + "reserved-1F", + "reserved-20", + "integer", + "boolean", + "enum", + "reserved-24", + "reserved-25", + "reserved-26", + "reserved-27", + "reserved-28", + "reserved-29", + "reserved-2a", + "reserved-2b", + "reserved-2c", + "reserved-2d", + "reserved-2e", + "reserved-2f", + "octetString", + "dateTime", + "resolution", + "rangeOfInteger", + "begCollection", + "textWithLanguage", + "nameWithLanguage", + "endCollection", + "reserved-38", + "reserved-39", + "reserved-3a", + "reserved-3b", + "reserved-3c", + "reserved-3d", + "reserved-3e", + "reserved-3f", + "reserved-40", + "textWithoutLanguage", + "nameWithoutLanguage", + "reserved-43", + "keyword", + "uri", + "uriScheme", + "charset", + "naturalLanguage", + "mimeMediaType", + "memberName" + }; + + + for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next) + { + if ((attr->group_tag == IPP_TAG_ZERO && indent <= 8) || !attr->name) + { + group = IPP_TAG_ZERO; + fputc('\n', stderr); + continue; + } + + if (group != attr->group_tag) + { + group = attr->group_tag; + + fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", tags[group]); + } + + fprintf(stderr, "DEBUG: %*s%s (", indent, "", attr->name); + if (attr->num_values > 1) + fputs("1setOf ", stderr); + fprintf(stderr, "%s):", tags[attr->value_tag]); + + switch (attr->value_tag) + { + case IPP_TAG_ENUM : + case IPP_TAG_INTEGER : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %d", val->integer); + fputc('\n', stderr); + break; + + case IPP_TAG_BOOLEAN : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %s", val->boolean ? "true" : "false"); + fputc('\n', stderr); + break; + + case IPP_TAG_RANGE : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %d-%d", val->range.lower, val->range.upper); + fputc('\n', stderr); + break; + + case IPP_TAG_DATE : + { + time_t vtime; /* Date/Time value */ + struct tm *vdate; /* Date info */ + char vstring[256]; /* Formatted time */ + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + vtime = ippDateToTime(val->date); + vdate = localtime(&vtime); + strftime(vstring, sizeof(vstring), "%c", vdate); + fprintf(stderr, " (%s)", vstring); + } + } + fputc('\n', stderr); + break; + + case IPP_TAG_RESOLUTION : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %dx%d%s", val->resolution.xres, + val->resolution.yres, + val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); + fputc('\n', stderr); + break; + + 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 : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " \"%s\"", val->string.text); + fputc('\n', stderr); + break; + + case IPP_TAG_BEGIN_COLLECTION : + fputc('\n', stderr); + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + if (i) + fputc('\n', stderr); + print_attributes(val->collection, indent + 4); + } + break; + + default : + fprintf(stderr, "UNKNOWN (%d values)\n", attr->num_values); + break; + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/notifier/rss.c b/notifier/rss.c new file mode 100644 index 0000000000..eb919092eb --- /dev/null +++ b/notifier/rss.c @@ -0,0 +1,732 @@ +/* + * "$Id$" + * + * RSS notifier for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for the test notifier. + * compare_rss() - Compare two messages. + * delete_message() - Free all memory used by a message. + * load_rss() - Load an existing RSS feed file. + * new_message() - Create a new RSS message. + * password_cb() - Return the cached password. + * save_rss() - Save messages to a RSS file. + * xml_escape() - Copy a string, escaping &, <, and > as needed. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Structures... + */ + +typedef struct _cups_rss_s /**** RSS message data ****/ +{ + int sequence_number; /* notify-sequence-number */ + char *subject, /* Message subject/summary */ + *text, /* Message text */ + *link_url; /* Link to printer */ + time_t event_time; /* When the event occurred */ +} _cups_rss_t; + + +/* + * Local globals... + */ + +static char *rss_password; /* Password for remote RSS */ + + +/* + * Local functions... + */ + +static int compare_rss(_cups_rss_t *a, _cups_rss_t *b); +static void delete_message(_cups_rss_t *rss); +static void load_rss(cups_array_t *rss, const char *filename); +static _cups_rss_t *new_message(int sequence_number, char *subject, + char *text, char *link_url, + time_t event_time); +static const char *password_cb(const char *prompt); +static int save_rss(cups_array_t *rss, const char *filename, + const char *baseurl); +static char *xml_escape(const char *s); + + +/* + * 'main()' - Main entry for the test notifier. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + ipp_t *event; /* Event from scheduler */ + ipp_state_t state; /* IPP event state */ + char scheme[32], /* URI scheme ("rss") */ + username[256], /* Username for remote RSS */ + host[1024], /* Hostname for remote RSS */ + resource[1024], /* RSS file */ + *options; /* Options */ + int port, /* Port number for remote RSS */ + max_events; /* Maximum number of events */ + http_t *http; /* Connection to remote server */ + http_status_t status; /* HTTP GET/PUT status code */ + char filename[1024], /* Local filename */ + newname[1024]; /* filename.N */ + cups_lang_t *language; /* Language information */ + ipp_attribute_t *printer_up_time, /* Timestamp on event */ + *notify_sequence_number,/* Sequence number */ + *notify_printer_uri; /* Printer URI */ + char *subject, /* Subject for notification message */ + *text, /* Text for notification message */ + link_url[1024], /* Link to printer */ + link_scheme[32], /* Scheme for link */ + link_username[256], /* Username for link */ + link_host[1024], /* Host for link */ + link_resource[1024]; /* Resource for link */ + int link_port; /* Link port */ + cups_array_t *rss; /* RSS message array */ + _cups_rss_t *msg; /* RSS message */ + char baseurl[1024]; /* Base URL */ + fd_set input; /* Input set for select() */ + struct timeval timeout; /* Timeout for select() */ + int changed; /* Has the RSS data changed? */ + int exit_status; /* Exit status */ + + + fprintf(stderr, "DEBUG: argc=%d\n", argc); + for (i = 0; i < argc; i ++) + fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + + /* + * See whether we are publishing this RSS feed locally or remotely... + */ + + if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme), + username, sizeof(username), host, sizeof(host), &port, + resource, sizeof(resource)) < HTTP_URI_OK) + { + fprintf(stderr, "ERROR: Bad RSS URI \"%s\"!\n", argv[1]); + return (1); + } + + max_events = 20; + + if ((options = strchr(resource, '?')) != NULL) + { + *options++ = '\0'; + + if (!strncmp(options, "max_events=", 11)) + { + max_events = atoi(options + 11); + + if (max_events <= 0) + max_events = 20; + } + } + + rss = cupsArrayNew((cups_array_func_t)compare_rss, NULL); + + if (host[0]) + { + /* + * Remote feed, see if we can get the current file... + */ + + int fd; /* Temporary file */ + + + if ((rss_password = strchr(username, ':')) != NULL) + *rss_password++ = '\0'; + + cupsSetPasswordCB(password_cb); + cupsSetUser(username); + + if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) + { + fprintf(stderr, "ERROR: Unable to create temporary file: %s\n", + strerror(errno)); + + return (1); + } + + if ((http = httpConnect(host, port)) == NULL) + { + fprintf(stderr, "ERROR: Unable to connect to %s on port %d: %s\n", + host, port, strerror(errno)); + + close(fd); + unlink(filename); + + return (1); + } + + status = cupsGetFd(http, resource, fd); + + close(fd); + + if (status != HTTP_OK && status != HTTP_NOT_FOUND) + { + fprintf(stderr, "ERROR: Unable to GET %s from %s on port %d: %d %s\n", + resource, host, port, status, httpStatus(status)); + + httpClose(http); + unlink(filename); + + return (1); + } + + strlcpy(newname, filename, sizeof(newname)); + + httpAssembleURI(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http", + NULL, host, port, resource); + } + else + { + const char *cachedir, /* CUPS_CACHEDIR */ + *server_name, /* SERVER_NAME */ + *server_port; /* SERVER_PORT */ + + + http = NULL; + + if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL) + cachedir = CUPS_CACHEDIR; + + if ((server_name = getenv("SERVER_NAME")) == NULL) + server_name = "localhost"; + + if ((server_port = getenv("SERVER_PORT")) == NULL) + server_port = "631"; + + snprintf(filename, sizeof(filename), "%s/rss%s", cachedir, resource); + snprintf(newname, sizeof(newname), "%s.N", filename); + + httpAssembleURIf(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http", + NULL, server_name, atoi(server_port), "/rss%s", resource); + } + + /* + * Load the previous RSS file, if any... + */ + + load_rss(rss, filename); + + changed = cupsArrayCount(rss) == 0; + + /* + * Localize for the user's chosen language... + */ + + language = cupsLangDefault(); + + /* + * Read events and update the RSS file until we are out of events. + */ + + for (exit_status = 0, event = NULL;;) + { + if (changed) + { + /* + * Save the messages to the file again, uploading as needed... + */ + + if (save_rss(rss, newname, baseurl)) + { + if (http) + { + /* + * Upload the RSS file... + */ + + if ((status = cupsPutFile(http, resource, filename)) != HTTP_CREATED) + fprintf(stderr, "ERROR: Unable to PUT %s from %s on port %d: %d %s\n", + resource, host, port, status, httpStatus(status)); + } + else + { + /* + * Move the new RSS file over top the old one... + */ + + if (rename(newname, filename)) + fprintf(stderr, "ERROR: Unable to rename %s to %s: %s\n", + newname, filename, strerror(errno)); + } + + changed = 0; + } + } + + /* + * Wait up to 30 seconds for an event... + */ + + timeout.tv_sec = 30; + timeout.tv_usec = 0; + + FD_ZERO(&input); + FD_SET(0, &input); + + if (select(1, &input, NULL, NULL, &timeout) < 0) + continue; + else if (!FD_ISSET(0, &input)) + { + fprintf(stderr, "DEBUG: %s is bored, exiting...\n", argv[1]); + break; + } + + /* + * Read the next event... + */ + + event = ippNew(); + while ((state = ippReadFile(0, event)) != IPP_DATA) + { + if (state <= IPP_IDLE) + break; + } + + if (state == IPP_ERROR) + fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); + + if (state <= IPP_IDLE) + break; + + /* + * Collect the info from the event... + */ + + printer_up_time = ippFindAttribute(event, "printer-up-time", + IPP_TAG_INTEGER); + notify_sequence_number = ippFindAttribute(event, "notify-sequence-number", + IPP_TAG_INTEGER); + notify_printer_uri = ippFindAttribute(event, "notify-printer-uri", + IPP_TAG_URI); + subject = cupsNotifySubject(language, event); + text = cupsNotifyText(language, event); + + if (printer_up_time && notify_sequence_number && subject && text) + { + /* + * Create a new RSS message... + */ + + if (notify_printer_uri) + { + httpSeparateURI(HTTP_URI_CODING_ALL, + notify_printer_uri->values[0].string.text, + link_scheme, sizeof(link_scheme), + link_username, sizeof(link_username), + link_host, sizeof(link_host), &link_port, + link_resource, sizeof(link_resource)); + httpAssembleURI(HTTP_URI_CODING_ALL, link_url, sizeof(link_url), + "http", link_username, link_host, link_port, + link_resource); + } + + msg = new_message(notify_sequence_number->values[0].integer, + xml_escape(subject), xml_escape(text), + notify_printer_uri ? xml_escape(link_url) : NULL, + printer_up_time->values[0].integer); + + if (!msg) + { + fprintf(stderr, "ERROR: Unable to create message: %s\n", + strerror(errno)); + exit_status = 1; + break; + } + + /* + * Add it to the array... + */ + + cupsArrayAdd(rss, msg); + + changed = 1; + + /* + * Trim the array as needed... + */ + + while (cupsArrayCount(rss) > max_events) + { + msg = cupsArrayFirst(rss); + + cupsArrayRemove(rss, msg); + + delete_message(msg); + } + } + + if (subject) + free(subject); + + if (text) + free(text); + + ippDelete(event); + event = NULL; + } + + /* + * We only get here when idle or error... + */ + + ippDelete(event); + + if (http) + { + unlink(filename); + httpClose(http); + } + + return (exit_status); +} + + +/* + * 'compare_rss()' - Compare two messages. + */ + +static int /* O - Result of comparison */ +compare_rss(_cups_rss_t *a, /* I - First message */ + _cups_rss_t *b) /* I - Second message */ +{ + return (a->sequence_number - b->sequence_number); +} + + +/* + * 'delete_message()' - Free all memory used by a message. + */ + +static void +delete_message(_cups_rss_t *msg) /* I - RSS message */ +{ + if (msg->subject) + free(msg->subject); + + if (msg->text) + free(msg->text); + + if (msg->link_url) + free(msg->link_url); + + free(msg); +} + + +/* + * 'load_rss()' - Load an existing RSS feed file. + */ + +static void +load_rss(cups_array_t *rss, /* I - RSS messages */ + const char *filename) /* I - File to load */ +{ + FILE *fp; /* File pointer */ + char line[4096], /* Line from file */ + *subject, /* Subject */ + *text, /* Text */ + *link_url, /* Link URL */ + *start, /* Start of element */ + *end; /* End of element */ + time_t event_time; /* Event time */ + int sequence_number; /* Sequence number */ + int in_item; /* In an item */ + _cups_rss_t *msg; /* New message */ + + + if ((fp = fopen(filename, "r")) == NULL) + { + if (errno != ENOENT) + fprintf(stderr, "ERROR: Unable to open %s: %s\n", filename, + strerror(errno)); + + return; + } + + subject = NULL; + text = NULL; + link_url = NULL; + event_time = 0; + sequence_number = 0; + in_item = 0; + + while (fgets(line, sizeof(line), fp)) + { + if (strstr(line, "")) + in_item = 1; + else if (strstr(line, "") && in_item) + { + if (subject && text) + { + msg = new_message(sequence_number, subject, text, link_url, + event_time); + + if (msg) + cupsArrayAdd(rss, msg); + + } + else + { + if (subject) + free(subject); + + if (text) + free(text); + + if (link_url) + free(link_url); + } + + subject = NULL; + text = NULL; + link_url = NULL; + event_time = 0; + sequence_number = 0; + in_item = 0; + } + else if (!in_item) + continue; + else if ((start = strstr(line, "")) != NULL) + { + start += 7; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + subject = strdup(start); + } + } + else if ((start = strstr(line, "")) != NULL) + { + start += 13; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + text = strdup(start); + } + } + else if ((start = strstr(line, "")) != NULL) + { + start += 6; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + link_url = strdup(start); + } + } + else if ((start = strstr(line, "")) != NULL) + { + start += 9; + if ((end = strstr(start, "")) != NULL) + { + *end = '\0'; + event_time = httpGetDateTime(start); + } + } + else if ((start = strstr(line, "")) != NULL) + sequence_number = atoi(start + 6); + } + + fclose(fp); +} + + +/* + * 'new_message()' - Create a new RSS message. + */ + +static _cups_rss_t * /* O - New message */ +new_message(int sequence_number, /* I - notify-sequence-number */ + char *subject, /* I - Subject/summary */ + char *text, /* I - Text */ + char *link_url, /* I - Link to printer */ + time_t event_time) /* I - Date/time of event */ +{ + _cups_rss_t *msg; /* New message */ + + + if ((msg = calloc(1, sizeof(_cups_rss_t))) == NULL) + return (NULL); + + msg->sequence_number = sequence_number; + msg->subject = subject; + msg->text = text; + msg->link_url = link_url; + msg->event_time = event_time; + + return (msg); +} + + +/* + * 'password_cb()' - Return the cached password. + */ + +static const char * /* O - Cached password */ +password_cb(const char *prompt) /* I - Prompt string, unused */ +{ + (void)prompt; + + return (rss_password); +} + + +/* + * 'save_rss()' - Save messages to a RSS file. + */ + +static int /* O - 1 on success, 0 on failure */ +save_rss(cups_array_t *rss, /* I - RSS messages */ + const char *filename, /* I - File to save to */ + const char *baseurl) /* I - Base URL */ +{ + FILE *fp; /* File pointer */ + _cups_rss_t *msg; /* Current message */ + char date[1024]; /* Current date */ + char *href; /* Escaped base URL */ + + + if ((fp = fopen(filename, "w")) == NULL) + { + fprintf(stderr, "ERROR: Unable to create %s: %s\n", filename, + strerror(errno)); + return (0); + } + + fputs("\n", fp); + fputs("\n", fp); + fputs(" \n", fp); + fputs(" CUPS RSS Feed\n", fp); + + href = xml_escape(baseurl); + fprintf(fp, " %s\n", href); + free(href); + + fputs(" CUPS RSS Feed\n", fp); + fputs(" " CUPS_SVERSION "\n", fp); + fputs(" 1\n", fp); + + fprintf(fp, " %s\n", + httpGetDateString2(time(NULL), date, sizeof(date))); + + for (msg = (_cups_rss_t *)cupsArrayLast(rss); + msg; + msg = (_cups_rss_t *)cupsArrayPrev(rss)) + { + fputs(" \n", fp); + fprintf(fp, " %s\n", msg->subject); + fprintf(fp, " %s\n", msg->text); + if (msg->link_url) + fprintf(fp, " %s\n", msg->link_url); + fprintf(fp, " %s\n", + httpGetDateString2(msg->event_time, date, sizeof(date))); + fprintf(fp, " %d\n", msg->sequence_number); + fputs(" \n", fp); + } + + fputs(" \n", fp); + fputs("\n", fp); + + return (!fclose(fp)); +} + + +/* + * 'xml_escape()' - Copy a string, escaping &, <, and > as needed. + */ + +static char * /* O - Escaped string */ +xml_escape(const char *s) /* I - String to escape */ +{ + char *e, /* Escaped string */ + *eptr; /* Pointer into escaped string */ + const char *sptr; /* Pointer into string */ + size_t bytes; /* Bytes needed for string */ + + + /* + * First figure out how many extra bytes we need... + */ + + for (bytes = 0, sptr = s; *sptr; sptr ++) + if (*sptr == '&') + bytes += 4; /* & */ + else if (*sptr == '<' || *sptr == '>') + bytes += 3; /* < and > */ + + /* + * If there is nothing to escape, just strdup() it... + */ + + if (bytes == 0) + return (strdup(s)); + + /* + * Otherwise allocate memory and copy... + */ + + if ((e = malloc(bytes + 1 + strlen(s))) == NULL) + return (NULL); + + for (eptr = e, sptr = s; *sptr; sptr ++) + if (*sptr == '&') + { + *eptr++ = '&'; + *eptr++ = 'a'; + *eptr++ = 'm'; + *eptr++ = 'p'; + *eptr++ = ';'; + } + else if (*sptr == '<') + { + *eptr++ = '&'; + *eptr++ = 'l'; + *eptr++ = 't'; + *eptr++ = ';'; + } + else if (*sptr == '>') + { + *eptr++ = '&'; + *eptr++ = 'g'; + *eptr++ = 't'; + *eptr++ = ';'; + } + else + *eptr++ = *sptr; + + *eptr = '\0'; + + return (e); +} + + +/* + * End of "$Id$". + */ diff --git a/notifier/testnotify.c b/notifier/testnotify.c new file mode 100644 index 0000000000..eaa3e7391f --- /dev/null +++ b/notifier/testnotify.c @@ -0,0 +1,285 @@ +/* + * "$Id$" + * + * Test notifier for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for the test notifier. + * print_attributes() - Print the attributes in a request... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + + +/* + * Local functions... + */ + +void print_attributes(ipp_t *ipp, int indent); + + +/* + * 'main()' - Main entry for the test notifier. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + ipp_t *event; /* Event from scheduler */ + ipp_state_t state; /* IPP event state */ + + + setbuf(stderr, NULL); + + fprintf(stderr, "DEBUG: argc=%d\n", argc); + for (i = 0; i < argc; i ++) + fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + fprintf(stderr, "DEBUG: TMPDIR=\"%s\"\n", getenv("TMPDIR")); + + for (;;) + { + event = ippNew(); + while ((state = ippReadFile(0, event)) != IPP_DATA) + { + if (state <= IPP_IDLE) + break; + } + + if (state == IPP_ERROR) + fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); + + if (state <= IPP_IDLE) + { + ippDelete(event); + return (0); + } + + print_attributes(event, 4); + ippDelete(event); + + /* + * If the recipient URI is "testnotify://nowait", then we exit after each + * event... + */ + + if (!strcmp(argv[1], "testnotify://nowait")) + return (0); + } +} + + +/* + * 'print_attributes()' - Print the attributes in a request... + */ + +void +print_attributes(ipp_t *ipp, /* I - IPP request */ + int indent) /* I - Indentation */ +{ + int i; /* Looping var */ + ipp_tag_t group; /* Current group */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_value_t *val; /* Current value */ + static const char * const tags[] = /* Value/group tag strings */ + { + "reserved-00", + "operation-attributes-tag", + "job-attributes-tag", + "end-of-attributes-tag", + "printer-attributes-tag", + "unsupported-attributes-tag", + "subscription-attributes-tag", + "event-attributes-tag", + "reserved-08", + "reserved-09", + "reserved-0A", + "reserved-0B", + "reserved-0C", + "reserved-0D", + "reserved-0E", + "reserved-0F", + "unsupported", + "default", + "unknown", + "no-value", + "reserved-14", + "not-settable", + "delete-attr", + "admin-define", + "reserved-18", + "reserved-19", + "reserved-1A", + "reserved-1B", + "reserved-1C", + "reserved-1D", + "reserved-1E", + "reserved-1F", + "reserved-20", + "integer", + "boolean", + "enum", + "reserved-24", + "reserved-25", + "reserved-26", + "reserved-27", + "reserved-28", + "reserved-29", + "reserved-2a", + "reserved-2b", + "reserved-2c", + "reserved-2d", + "reserved-2e", + "reserved-2f", + "octetString", + "dateTime", + "resolution", + "rangeOfInteger", + "begCollection", + "textWithLanguage", + "nameWithLanguage", + "endCollection", + "reserved-38", + "reserved-39", + "reserved-3a", + "reserved-3b", + "reserved-3c", + "reserved-3d", + "reserved-3e", + "reserved-3f", + "reserved-40", + "textWithoutLanguage", + "nameWithoutLanguage", + "reserved-43", + "keyword", + "uri", + "uriScheme", + "charset", + "naturalLanguage", + "mimeMediaType", + "memberName" + }; + + + for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next) + { + if ((attr->group_tag == IPP_TAG_ZERO && indent <= 8) || !attr->name) + { + group = IPP_TAG_ZERO; + fputc('\n', stderr); + continue; + } + + if (group != attr->group_tag) + { + group = attr->group_tag; + + fprintf(stderr, "DEBUG: %*s%s:\n\n", indent - 4, "", tags[group]); + } + + fprintf(stderr, "DEBUG: %*s%s (", indent, "", attr->name); + if (attr->num_values > 1) + fputs("1setOf ", stderr); + fprintf(stderr, "%s):", tags[attr->value_tag]); + + switch (attr->value_tag) + { + case IPP_TAG_ENUM : + case IPP_TAG_INTEGER : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %d", val->integer); + fputc('\n', stderr); + break; + + case IPP_TAG_BOOLEAN : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %s", val->boolean ? "true" : "false"); + fputc('\n', stderr); + break; + + case IPP_TAG_RANGE : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %d-%d", val->range.lower, val->range.upper); + fputc('\n', stderr); + break; + + case IPP_TAG_DATE : + { + time_t vtime; /* Date/Time value */ + struct tm *vdate; /* Date info */ + char vstring[256]; /* Formatted time */ + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + vtime = ippDateToTime(val->date); + vdate = localtime(&vtime); + strftime(vstring, sizeof(vstring), "%c", vdate); + fprintf(stderr, " (%s)", vstring); + } + } + fputc('\n', stderr); + break; + + case IPP_TAG_RESOLUTION : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " %dx%d%s", val->resolution.xres, + val->resolution.yres, + val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); + fputc('\n', stderr); + break; + + 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 : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + fprintf(stderr, " \"%s\"", val->string.text); + fputc('\n', stderr); + break; + + case IPP_TAG_BEGIN_COLLECTION : + fputc('\n', stderr); + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + if (i) + fputc('\n', stderr); + print_attributes(val->collection, indent + 4); + } + break; + + default : + fprintf(stderr, "UNKNOWN (%d values)\n", attr->num_values); + break; + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/packaging/InstallationCheck b/packaging/InstallationCheck new file mode 100755 index 0000000000..4e3405caa1 --- /dev/null +++ b/packaging/InstallationCheck @@ -0,0 +1,11 @@ +#!/bin/sh +case `uname -r` in + # Mac OS X 10.4.x + 8.*) exit 0;; + + # Mac OS X 10.5.x + 9.*) exit 0;; + + # Older Mac OS X... + *) exit 97;; +esac diff --git a/packaging/LICENSE.rtf b/packaging/LICENSE.rtf new file mode 100644 index 0000000000..b348f6b08a --- /dev/null +++ b/packaging/LICENSE.rtf @@ -0,0 +1,434 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1011 +{\fonttbl\f0\froman\fcharset0 Times-Roman;\f1\fnil\fcharset0 LucidaGrande;\f2\fmodern\fcharset0 Courier; +\f3\fmodern\fcharset0 Courier-Oblique;} +{\colortbl;\red255\green255\blue255;\red0\green0\blue238;} +{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{disc\}}{\leveltext\leveltemplateid1\'01\uc0\u8226 ;}{\levelnumbers;}\fi-360\li720\lin720 }{\listname ;}\listid1} +{\list\listtemplateid2\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid101\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid102\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1440\lin1440 }{\listname ;}\listid2} +{\list\listtemplateid3\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid201\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid202\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1440\lin1440 }{\listname ;}\listid3} +{\list\listtemplateid4\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid301\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid4} +{\list\listtemplateid5\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid401\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid5} +{\list\listtemplateid6\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid501\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid6} +{\list\listtemplateid7\listhybrid{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{decimal\}.}{\leveltext\leveltemplateid601\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\lin720 }{\listname ;}\listid7}} +{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}{\listoverride\listid3\listoverridecount0\ls3}{\listoverride\listid4\listoverridecount0\ls4}{\listoverride\listid5\listoverridecount0\ls5}{\listoverride\listid6\listoverridecount0\ls6}{\listoverride\listid7\listoverridecount0\ls7}} +\margl1440\margr1440\margb1800\margt1800\vieww9000\viewh8400\viewkind0 +\deftab720 +\pard\pardeftab720\sa280\qc + +\f0\b\fs36 \cf0 CUPS License Agreement\ +\pard\pardeftab720\sa240\qc + +\b0\fs24 \cf0 Copyright 2007-2009 by Apple Inc. +\f1 \uc0\u8232 +\f0 1 Infinite Loop +\f1 \uc0\u8232 +\f0 Cupertino, CA 95014 USA +\f1 \uc0\u8232 \u8232 +\f0 WWW: {\field{\*\fldinst{HYPERLINK "http://www.cups.org/"}}{\fldrslt \cf2 \ul \ulc2 http://www.cups.org}}\ +\pard\pardeftab720\sa280\ql\qnatural + +\b\fs28 \cf0 Introduction\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0\fs24 \cf0 CUPS +\fs20 \super TM +\fs24 \nosupersub 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:\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls1\ilvl0\cf0 {\listtext \'95 }Use the CUPS software at no charge.\ +{\listtext \'95 }Distribute verbatim copies of the software in source or binary form.\ +{\listtext \'95 }Sell verbatim copies of the software for a media fee, or sell support for the software.\ +{\listtext \'95 }Distribute or sell printer drivers and filters that use CUPS so long as source code is made available under the GPL.\ +\pard\pardeftab720\sa240\ql\qnatural +\cf0 What this license +\b does not +\b0 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.\ +\pard\pardeftab720\sa280\ql\qnatural + +\b\fs28 \cf0 License Exceptions\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0\fs24 \cf0 In addition, as the copyright holder of CUPS, Apple Inc. grants the following special exceptions:\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls2\ilvl0 +\b \cf0 {\listtext 1. }Apple Operating System Development License Exception +\b0 ;\ +\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\ql\qnatural +\ls2\ilvl1\cf0 {\listtext 1. }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.\ +{\listtext 2. }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.\ +{\listtext 3. }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.\ +{\listtext 4. }All CUPS software that falls under this license exception have the following text at the top of each source file:\ +{\listtext 5. }This file is subject to the Apple OS-Developed Software exception.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls2\ilvl0 +\b \cf0 {\listtext 2. }OpenSSL Toolkit License Exception +\b0 ;\ +\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\ql\qnatural +\ls2\ilvl1\cf0 {\listtext 1. }Apple Inc. explicitly allows the compilation and distribution of the CUPS software with the OpenSSL Toolkit.\ +\pard\pardeftab720\sa240\ql\qnatural +\cf0 No developer is required to provide these exceptions in a derived work.\ +\pard\pardeftab720\sa280\ql\qnatural + +\b\fs28 \cf0 Trademarks\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0\fs24 \cf0 CUPS and the CUPS logo (the "CUPS Marks") are trademarks of Apple Inc. Apple grants you a non-exclusive and non-transferable right to use the CUPS Marks in any direct port or binary distribution incorporating CUPS software and in any promotional material therefor. You agree that your products will meet the highest levels of quality and integrity for similar goods, not be unlawful, and be developed, manufactured, and distributed in compliance with this license. You will not interfere with Apple's rights in the CUPS Marks, and all use of the CUPS Marks shall inure to the benefit of Apple. This license does not apply to use of the CUPS Marks in a derivative products, which requires prior written permission from Apple Inc.\ +\pard\pardeftab720\sa280\ql\qnatural + +\b\fs28 \cf0 \page \pard\pardeftab720\sa280\ql\qnatural + +\fs36 \cf0 GNU GENERAL PUBLIC LICENSE\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0\fs24 \cf0 Version 2, June 1991\ +\pard\pardeftab720\ql\qnatural + +\f2 \cf0 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.\ +\pard\pardeftab720\sa300\ql\qnatural + +\f0\b \cf0 Preamble\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0 \cf0 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.\ +\pard\pardeftab720\sa300\ql\qnatural + +\b \cf0 GNU GENERAL PUBLIC LICENSE +\f1 \uc0\u8232 +\f0 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0 +\b0 \cf0 {\listtext 1. }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".\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 2. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 3. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 4. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 5. }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:\ +\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\ql\qnatural +\ls3\ilvl1\cf0 {\listtext 1. }You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.\ +{\listtext 2. }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.\ +{\listtext 3. }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.)\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 6. }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.\ +{\listtext 7. }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.\ +{\listtext 8. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 9. }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:\ +\pard\tx940\tx1440\pardeftab720\li1440\fi-1440\ql\qnatural +\ls3\ilvl1\cf0 {\listtext 1. }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,\ +{\listtext 2. }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,\ +{\listtext 3. }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.)\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 10. }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.\ +{\listtext 11. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 12. }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.\ +{\listtext 13. }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.\ +{\listtext 14. }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.\ +{\listtext 15. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 16. }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.\ +{\listtext 17. }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.\ +{\listtext 18. }This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 19. }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.\ +{\listtext 20. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 21. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls3\ilvl0\cf0 {\listtext 22. }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.\ +\pard\pardeftab720\sa300\ql\qnatural + +\b \cf0 NO WARRANTY\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls4\ilvl0 +\b0 \cf0 {\listtext 1. }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.\ +{\listtext 2. }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.\ +\pard\pardeftab720\sa300\ql\qnatural + +\b \cf0 END OF TERMS AND CONDITIONS\ +How to Apply These Terms to Your New Programs\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0 \cf0 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.\ +\pard\pardeftab720\ql\qnatural + +\f3\i \cf0 one line to give the program's name and an idea of what it does. +\f2\i0 \ +Copyright (C) +\f3\i yyyy +\f2\i0 +\f3\i name of author +\f2\i0 \ +\ +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.\ +\pard\pardeftab720\sa240\ql\qnatural + +\f0 \cf0 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:\ +\pard\pardeftab720\ql\qnatural + +\f2 \cf0 Gnomovision version 69, Copyright (C) +\f3\i year +\f2\i0 +\f3\i name of author +\f2\i0 \ +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.\ +\pard\pardeftab720\sa240\ql\qnatural + +\f0 \cf0 The hypothetical commands +\f2 `show w' +\f0 and +\f2 `show c' +\f0 should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than +\f2 `show w' +\f0 and +\f2 `show c' +\f0 ; 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:\ +\pard\pardeftab720\ql\qnatural + +\f2 \cf0 Yoyodyne, Inc., hereby disclaims all copyright\ +interest in the program `Gnomovision'\ +(which makes passes at compilers) written \ +by James Hacker.\ +\ +\pard\pardeftab720\ql\qnatural + +\f3\i \cf0 signature of Ty Coon +\f2\i0 , 1 April 1989\ +Ty Coon, President of Vice\ +\pard\pardeftab720\sa280\ql\qnatural + +\f0\b\fs36 \cf0 GNU LIBRARY GENERAL PUBLIC LICENSE\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0\fs24 \cf0 Version 2, June 1991\ +\pard\pardeftab720\ql\qnatural + +\f2 \cf0 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.]\ +\pard\pardeftab720\sa300\ql\qnatural + +\f0\b \cf0 Preamble\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0 \cf0 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.\ +\pard\pardeftab720\sa300\ql\qnatural + +\b \cf0 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\ +\pard\pardeftab720\sa240\ql\qnatural +\cf0 0. +\b0 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.\ + +\b 1. +\b0 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.\ + +\b 2. +\b0 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:\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 1. }The modified work must itself be a software library.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 2. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 3. }You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 4. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 5. }You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 6. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 7. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls5\ilvl0\cf0 {\listtext 8. }(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.)\ +\pard\pardeftab720\sa240\ql\qnatural +\cf0 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.\ +\pard\pardeftab720\sa240\ql\qnatural + +\b \cf0 3. +\b0 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.\ + +\b 4. +\b0 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.\ + +\b 5. +\b0 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.\ + +\b 6. +\b0 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:\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 1. }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.)\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 2. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 3. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 4. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 5. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 6. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls6\ilvl0\cf0 {\listtext 7. }Verify that the user has already received a copy of these materials or that you have already sent this user a copy.\ +\pard\pardeftab720\sa240\ql\qnatural +\cf0 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.\ +\pard\pardeftab720\sa240\ql\qnatural + +\b \cf0 7. +\b0 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:\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls7\ilvl0\cf0 {\listtext 1. }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.\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\sa240\ql\qnatural +\ls7\ilvl0\cf0 {\listtext 2. }\ +\pard\tx220\tx720\pardeftab720\li720\fi-720\ql\qnatural +\ls7\ilvl0\cf0 {\listtext 3. }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.\ +\pard\pardeftab720\sa240\ql\qnatural + +\b \cf0 8. +\b0 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.\ + +\b 9. +\b0 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.\ + +\b 10. +\b0 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.\ + +\b 11. +\b0 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.\ + +\b 12. +\b0 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.\ + +\b 13. +\b0 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.\ + +\b 14. +\b0 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.\ + +\b NO WARRANTY +\b0 \ + +\b 15. +\b0 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.\ + +\b 16. +\b0 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.\ +\pard\pardeftab720\sa300\ql\qnatural + +\b \cf0 END OF TERMS AND CONDITIONS\ +How to Apply These Terms to Your New Libraries\ +\pard\pardeftab720\sa240\ql\qnatural + +\b0 \cf0 If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).\ +To apply these terms, attach the following notices to the library. 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.\ +\pard\pardeftab720\ql\qnatural + +\f3\i \cf0 one line to give the library's name and an idea of what it does. +\f2\i0 \ +Copyright (C) +\f3\i year +\f2\i0 +\f3\i name of author +\f2\i0 \ +\ +This library is free software; you can redistribute it and/or\ +modify it under the terms of the GNU Lesser General Public\ +License as published by the Free Software Foundation; either\ +version 2.1 of the License, or (at your option) any later version.\ +\ +This library 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\ +Lesser General Public License for more details.\ +\ +You should have received a copy of the GNU Lesser General Public\ +License along with this library; if not, write to the Free Software\ +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\ +\pard\pardeftab720\sa240\ql\qnatural + +\f0 \cf0 Also add information on how to contact you by electronic and paper mail.\ +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:\ +\pard\pardeftab720\ql\qnatural + +\f2 \cf0 Yoyodyne, Inc., hereby disclaims all copyright interest in\ +the library `Frob' (a library for tweaking knobs) written\ +by James Random Hacker.\ +\ +\pard\pardeftab720\ql\qnatural + +\f3\i \cf0 signature of Ty Coon +\f2\i0 , 1 April 1990\ +Ty Coon, President of Vice\ +\pard\pardeftab720\sa240\ql\qnatural + +\f0 \cf0 That's all there is to it!\ +} \ No newline at end of file diff --git a/packaging/WELCOME.rtf b/packaging/WELCOME.rtf new file mode 100644 index 0000000000..aae1174793 --- /dev/null +++ b/packaging/WELCOME.rtf @@ -0,0 +1,24 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1009\cocoasubrtf300 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;} +{\colortbl;\red255\green255\blue255;} +\margl1440\margr1440\margb1800\margt1800\vieww9000\viewh8400\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural + +\f0\fs24 \cf0 This program will install CUPS @CUPS_VERSION@, replacing the CUPS software that is included with Mac OS X.\ +\ + +\b WARNING\ + +\b0 \ +This is pre-release software and should not be used in production environments. Because Mac OS X packages cannot be uninstalled, you will need to reinstall Mac OS X to revert to the original CUPS software.\ +\ +Please report all problems using the Bugs & Features page on the CUPS home page:\ +\ + {\field{\*\fldinst{HYPERLINK "http://www.cups.org/str.php"}}{\fldrslt http://www.cups.org/str.php}}\ +\ + +\b NO WARRANTY\ + +\b0 \ +CUPS is provided under the terms of the GNU General Public License and GNU Library General Public License versions 2. 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.\ +} \ No newline at end of file diff --git a/packaging/cups-dbus.conf b/packaging/cups-dbus.conf new file mode 100644 index 0000000000..537ac77657 --- /dev/null +++ b/packaging/cups-dbus.conf @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/packaging/cups-desc.plist.in b/packaging/cups-desc.plist.in new file mode 100644 index 0000000000..4d1d296887 --- /dev/null +++ b/packaging/cups-desc.plist.in @@ -0,0 +1,14 @@ + + + + + IFPkgDescriptionDeleteWarning + + IFPkgDescriptionDescription + CUPS provides a portable printing layer for UNIX(r) operating systems. + IFPkgDescriptionTitle + CUPS + IFPkgDescriptionVersion + @CUPS_RELEASE@ + + diff --git a/packaging/cups-info.plist.in b/packaging/cups-info.plist.in new file mode 100644 index 0000000000..d1f61348b6 --- /dev/null +++ b/packaging/cups-info.plist.in @@ -0,0 +1,26 @@ + + + + + IFPkgFlagAuthorizationAction + RootAuthorization + IFPkgFlagBackgroundAlignment + bottomleft + IFPkgFlagBackgroundScaling + none + IFPkgFormatVersion + 0.1 + CFBundleIdentifier + org.cups.cups + CFBundleName + CUPS + CFBundleGetInfoString + CUPS, @CUPS_VERSION@ + CFBundleShortVersionString + @CUPS_RELEASE@ + IFPkgFlagAllowBackRev + + IFPkgFlagRootVolumeOnly + + + diff --git a/packaging/cups.list.in b/packaging/cups.list.in new file mode 100644 index 0000000000..b99d0bd31c --- /dev/null +++ b/packaging/cups.list.in @@ -0,0 +1,779 @@ +# +# "$Id$" +# +# ESP Package Manager (EPM) file list for CUPS. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# Product information +%product CUPS +%copyright 2007-2010 by Apple Inc. +%vendor Apple Inc. +#%license LICENSE.txt +%readme LICENSE.txt +%format rpm +# Red Hat and their epochs... +%version 1:@CUPS_VERSION@ +%format !rpm +%version @CUPS_VERSION@ +%format all +%description CUPS is the standards-based, open source printing system developed by +%description Apple Inc. for Mac OS® X and other UNIX®-like operating systems. + +%format rpm +%provides lpd +%provides lpr +%provides LPRng +%replaces lpd +%replaces lpr +%replaces LPRng +%requires cups-libs 1:@CUPS_VERSION@ + +# Replace all of the old localization subpackages from CUPS 1.2/1.3 +%replaces cups-da +%replaces cups-de +%replaces cups-es +%replaces cups-et +%replaces cups-fi +%replaces cups-fr +%replaces cups-he +%replaces cups-id +%replaces cups-it +%replaces cups-ja +%replaces cups-ko +%replaces cups-nl +%replaces cups-no +%replaces cups-pl +%replaces cups-pt +%replaces cups-ru +%replaces cups-sv +%replaces cups-zh + + +%format deb +%provides cupsys +%provides cupsys-client +%provides cupsys-bsd +%requires cups-libs + +# Replace all of the old localization subpackages from CUPS 1.2/1.3 +%replaces cups-da +%replaces cups-de +%replaces cups-es +%replaces cups-et +%replaces cups-fi +%replaces cups-fr +%replaces cups-he +%replaces cups-id +%replaces cups-it +%replaces cups-ja +%replaces cups-ko +%replaces cups-nl +%replaces cups-no +%replaces cups-pl +%replaces cups-pt +%replaces cups-ru +%replaces cups-sv +%replaces cups-zh + + +%format pkg +%replaces SUNWlpmsg LP Alerts +%replaces SUNWlpr LP Print Service, (Root) +%replaces SUNWlps LP Print Service - Server, (Usr) +%replaces SUNWlpu LP Print Service - Client, (Usr) +%replaces SUNWpsu LP Print Server, (Usr) +%replaces SUNWpsr LP Print Server, (Root) +%replaces SUNWpcu LP Print Client, (Usr) +%replaces SUNWpcr LP Print Client, (Root) +%replaces SUNWppm +%replaces SUNWmp +%replaces SUNWscplp SunOS Print Compatibility + +%format inst +%replaces patch*.print_*.* 0 0 1289999999 1289999999 +%replaces maint*.print_*.* 0 0 1289999999 1289999999 +%replaces print 0 0 1289999999 1289999999 +%replaces fw_cups 0 0 1289999999 1289999999 +%incompat patch*.print_*.* 0 0 1289999999 1289999999 +%incompat maint*.print_*.* 0 0 1289999999 1289999999 +%incompat print 0 0 1289999999 1289999999 +%incompat fw_cups 0 0 1289999999 1289999999 +%requires cups.sw.libs + +# Replace all of the old localization subpackages from CUPS 1.2/1.3 +%replaces cups.sw.da +%replaces cups.sw.de +%replaces cups.sw.es +%replaces cups.sw.et +%replaces cups.sw.fi +%replaces cups.sw.fr +%replaces cups.sw.he +%replaces cups.sw.id +%replaces cups.sw.it +%replaces cups.sw.ja +%replaces cups.sw.ko +%replaces cups.sw.nl +%replaces cups.sw.no +%replaces cups.sw.pl +%replaces cups.sw.pt +%replaces cups.sw.ru +%replaces cups.sw.sv +%replaces cups.sw.zh + +%format portable +%requires cups-libs + +# Replace all of the old localization subpackages from CUPS 1.2/1.3 +%replaces cups-da +%replaces cups-de +%replaces cups-es +%replaces cups-et +%replaces cups-fi +%replaces cups-fr +%replaces cups-he +%replaces cups-id +%replaces cups-it +%replaces cups-ja +%replaces cups-ko +%replaces cups-nl +%replaces cups-no +%replaces cups-pl +%replaces cups-pt +%replaces cups-ru +%replaces cups-sv +%replaces cups-zh + +%format all + +%subpackage libs +%description Shared libraries +%format deb +%provides libcups1 +%provides libcupsys2 +%provides libcupsys2-gnutls10 +%provides libcupsimage2 +%format all + +%subpackage devel +%description Development environment +%format deb +%provides libcupsys2-dev +%provides libcupsimage2-dev +%format all + +%subpackage lpd +%description LPD support + +%subpackage + + +# +# GNU variables... +# + +$prefix=@prefix@ +$exec_prefix=@exec_prefix@ +$bindir=@bindir@ +$datarootdir=@datarootdir@ +$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@ +$CACHEDIR=@CUPS_CACHEDIR@ +$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@ +$STATEDIR=@CUPS_STATEDIR@ +$XINETD=@XINETD@ +$LIB32DIR=@LIB32DIR@ +$LIB64DIR=@LIB64DIR@ + +$IMGFILTERS=@IMGFILTERS@ +$MDNS=@MDNS@ +$PDFTOPS=@PDFTOPS@ + +$CUPS_USER=@CUPS_USER@ +$CUPS_GROUP=@CUPS_GROUP@ +$CUPS_PRIMARY_SYSTEM_GROUP=@CUPS_PRIMARY_SYSTEM_GROUP@ +$CUPS_PERM=0@CUPS_CONFIG_FILE_PERM@ + +$INSTALLSTATIC=@INSTALLSTATIC@ + +$MAN1EXT=@MAN1EXT@ +$MAN3EXT=@MAN3EXT@ +$MAN5EXT=@MAN5EXT@ +$MAN7EXT=@MAN7EXT@ +$MAN8EXT=@MAN8EXT@ +$MAN8DIR=@MAN8DIR@ + +$DSOLIBS=@DSOLIBS@ + +# 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... +%subpackage libs +%system linux +%postinstall ldconfig +%system all +%subpackage + +# Server programs +%system all +# Server files +f 0555 root sys $SBINDIR/cupsd scheduler/cupsd + +d 0755 root sys $SERVERBIN - +d 0755 root sys $SERVERBIN/backend - +f 0500 root sys $SERVERBIN/backend/ipp backend/ipp +l 0700 root sys $SERVERBIN/backend/http ipp +f 0500 root sys $SERVERBIN/backend/lpd backend/lpd +%if DNSSD_BACKEND +f 0500 root sys $SERVERBIN/backend/dnssd backend/dnssd +l 0700 root sys $SERVERBIN/backend/mdns dnssd +%endif +%system !darwin +f 0555 root sys $SERVERBIN/backend/parallel backend/parallel +f 0555 root sys $SERVERBIN/backend/scsi backend/scsi +%system all +f 0555 root sys $SERVERBIN/backend/serial backend/serial +f 0555 root sys $SERVERBIN/backend/snmp backend/snmp +f 0555 root sys $SERVERBIN/backend/socket backend/socket +f 0555 root sys $SERVERBIN/backend/usb backend/usb +d 0755 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/help.cgi cgi-bin/help.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 0755 root sys $SERVERBIN/daemon - +f 0555 root sys $SERVERBIN/daemon/cups-deviced scheduler/cups-deviced +f 0555 root sys $SERVERBIN/daemon/cups-driverd scheduler/cups-driverd +f 0555 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld +d 0755 root sys $SERVERBIN/driver - +d 0755 root sys $SERVERBIN/filter - +f 0555 root sys $SERVERBIN/filter/bannertops filter/bannertops +f 0555 root sys $SERVERBIN/filter/commandtoespcx driver/commandtoescpx +f 0555 root sys $SERVERBIN/filter/commandtopclx driver/commandtopclx +f 0555 root sys $SERVERBIN/filter/commandtops filter/commandtops +f 0555 root sys $SERVERBIN/filter/gziptoany filter/gziptoany +f 0555 root sys $SERVERBIN/filter/hpgltops filter/hpgltops +%if IMGFILTERS +f 0555 root sys $SERVERBIN/filter/imagetops filter/imagetops +f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster +%endif +%if PDFTOPS +f 0555 root sys $SERVERBIN/filter/pdftops filter/pdftops +%endif +f 0555 root sys $SERVERBIN/filter/pstops filter/pstops +f 0555 root sys $SERVERBIN/filter/rastertoespcx driver/rastertoescpx +f 0555 root sys $SERVERBIN/filter/rastertolabel filter/rastertolabel +l 0755 root sys $SERVERBIN/filter/rastertodymo rastertolabel +f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson +f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp +f 0555 root sys $SERVERBIN/filter/rastertopclx driver/rastertopclx +f 0555 root sys $SERVERBIN/filter/texttops filter/texttops +d 0755 root sys $SERVERBIN/notifier - +f 0555 root sys $SERVERBIN/notifier/mailto notifier/mailto + +%subpackage lpd +d 0755 root sys $SERVERBIN/daemon - +f 0555 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd +%subpackage + +# Admin commands +d 0755 root sys $BINDIR - +l 0755 root sys $BINDIR/enable $SBINDIR/cupsaccept +l 0755 root sys $BINDIR/disable $SBINDIR/cupsaccept +d 0755 root sys $LIBDIR - +l 0755 root sys $LIBDIR/accept $SBINDIR/cupsaccept +l 0755 root sys $LIBDIR/lpadmin $SBINDIR/lpadmin +l 0755 root sys $LIBDIR/reject $SBINDIR/cupsaccept +d 0755 root sys $SBINDIR - +l 0755 root sys $SBINDIR/accept cupsaccept +f 0555 root sys $SBINDIR/cupsaccept systemv/cupsaccept +f 0555 root sys $SBINDIR/cupsaddsmb systemv/cupsaddsmb +f 0555 root sys $SBINDIR/cupsctl systemv/cupsctl +l 0755 root sys $SBINDIR/cupsdisable accept +l 0755 root sys $SBINDIR/cupsenable accept +l 0755 root sys $SBINDIR/cupsreject accept +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 0755 root sys $SBINDIR/reject cupsaccept + +%system irix +l 0755 root sys /usr/etc/lpc $SBINDIR/lpc +%system all + +# User commands +d 0755 root sys $BINDIR - +f 0555 root sys $BINDIR/cancel systemv/cancel +f 0555 root sys $BINDIR/cupstestdsc systemv/cupstestdsc +f 0555 root sys $BINDIR/cupstestppd systemv/cupstestppd +f 0555 root sys $BINDIR/lp systemv/lp +f 0555 root sys $BINDIR/lpoptions systemv/lpoptions +f 0555 root 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 0755 root sys /usr/bsd/lpq $BINDIR/lpq +l 0755 root sys /usr/bsd/lpr $BINDIR/lpr +l 0755 root sys /usr/bsd/lprm $BINDIR/lprm +%system all + +# DSOs +%if DSOLIBS +%subpackage libs +%system hpux +f 0555 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2 nostrip() +l 0755 root sys $LIBDIR/libcups.sl libcups.sl.2 +f 0555 root sys $LIBDIR/libcupscgi.sl.1 cgi-bin/libcupscgi.sl.1 nostrip() +l 0755 root sys $LIBDIR/libcupscgi.sl libcupscgi.sl.1 +f 0555 root sys $LIBDIR/libcupsdriver.sl.1 driver/libcupsdriver.sl.1 nostrip() +l 0755 root sys $LIBDIR/libcupsdriver.sl libcupsdriver.sl.1 +f 0555 root sys $LIBDIR/libcupsimage.sl.2 filter/libcupsimage.sl.2 nostrip() +l 0755 root sys $LIBDIR/libcupsimage.sl libcupsimage.sl.2 +f 0555 root sys $LIBDIR/libcupsmime.sl.1 scheduler/libcupsmime.sl.1 nostrip() +l 0755 root sys $LIBDIR/libcupsmime.sl libcupsmime.sl.1 +f 0555 root sys $LIBDIR/libcupsppdc.sl.1 ppdc/libcupsppdc.sl.1 nostrip() +l 0755 root sys $LIBDIR/libcupsppdc.sl libcupsppdc.sl.1 +%system aix +f 0555 root sys $LIBDIR/libcups_s.a cups/libcups_s.a nostrip() +f 0555 root sys $LIBDIR/libcupscgi_s.a cgi-bin/libcupscgi_s.a nostrip() +f 0555 root sys $LIBDIR/libcupsdriver_s.a driver/libcupsdriver_s.a nostrip() +f 0555 root sys $LIBDIR/libcupsimage_s.a filter/libcupsimage_s.a nostrip() +f 0555 root sys $LIBDIR/libcupsmime_s.a scheduler/libcupsmime_s.a nostrip() +f 0555 root sys $LIBDIR/libcupsppdc_s.a ppdc/libcupsppdc_s.a nostrip() +%system darwin +f 0555 root sys $LIBDIR/libcups.2.dylib cups/libcups.2.dylib nostrip() +l 0755 root sys $LIBDIR/libcups.dylib libcups.2.dylib +f 0555 root sys $LIBDIR/libcupscgi.1.dylib cgi-bin/libcupscgi.1.dylib nostrip() +l 0755 root sys $LIBDIR/libcupscgi.dylib libcupscgi.1.dylib +f 0555 root sys $LIBDIR/libcupsdriver.1.dylib driver/libcupsdriver.1.dylib nostrip() +l 0755 root sys $LIBDIR/libcupsdriver.dylib libcupsdriver.1.dylib +f 0555 root sys $LIBDIR/libcupsimage.2.dylib filter/libcupsimage.2.dylib nostrip() +l 0755 root sys $LIBDIR/libcupsimage.dylib libcupsimage.2.dylib +f 0555 root sys $LIBDIR/libcupsmime.1.dylib scheduler/libcupsmime.1.dylib nostrip() +l 0755 root sys $LIBDIR/libcupsmime.dylib libcupsmime.1.dylib +f 0555 root sys $LIBDIR/libcupsppdc.1.dylib ppdc/libcupsppdc.1.dylib nostrip() +l 0755 root sys $LIBDIR/libcupsppdc.dylib libcupsppdc.1.dylib +%system !hpux !aix !darwin +f 0555 root sys $LIBDIR/libcups.so.2 cups/libcups.so.2 nostrip() +l 0755 root sys $LIBDIR/libcups.so libcups.so.2 +f 0555 root sys $LIBDIR/libcupscgi.so.1 cgi-bin/libcupscgi.so.1 nostrip() +l 0755 root sys $LIBDIR/libcupscgi.so libcupscgi.so.1 +f 0555 root sys $LIBDIR/libcupsdriver.so.1 driver/libcupsdriver.so.1 nostrip() +l 0755 root sys $LIBDIR/libcupsdriver.so libcupsdriver.so.1 +f 0555 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2 nostrip() +l 0755 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2 +f 0555 root sys $LIBDIR/libcupsmime.so.1 scheduler/libcupsmime.so.1 nostrip() +l 0755 root sys $LIBDIR/libcupsmime.so libcupsmime.so.1 +f 0555 root sys $LIBDIR/libcupsppdc.so.1 ppdc/libcupsppdc.so.1 nostrip() +l 0755 root sys $LIBDIR/libcupsppdc.so libcupsppdc.so.1 +%system all +%subpackage +%endif + +%if LIB32DIR +%subpackage libs +f 0555 root sys $LIB32DIR/libcups.so.2 cups/libcups.32.so.2 nostrip() +l 0755 root sys $LIB32DIR/libcups.so libcups.so.2 +f 0555 root sys $LIB32DIR/libcupscgi.so.1 cgi-bin/libcupscgi.32.so.1 nostrip() +l 0755 root sys $LIB32DIR/libcupscgi.so libcupscgi.so.1 +f 0555 root sys $LIB32DIR/libcupsdriver.so.1 driver/libcupsdriver.32.so.1 nostrip() +l 0755 root sys $LIB32DIR/libcupsdriver.so libcupsdriver.so.1 +f 0555 root sys $LIB32DIR/libcupsimage.so.2 filter/libcupsimage.32.so.2 nostrip() +l 0755 root sys $LIB32DIR/libcupsimage.so libcupsimage.so.2 +f 0555 root sys $LIB32DIR/libcupsmime.so.1 scheduler/libcupsmime.32.so.1 nostrip() +l 0755 root sys $LIB32DIR/libcupsmime.so libcupsmime.so.1 +f 0555 root sys $LIB32DIR/libcupsppdc.so.1 ppdc/libcupsppdc.32.so.1 nostrip() +l 0755 root sys $LIB32DIR/libcupsppdc.so libcupsppdc.so.1 +%system all +%subpackage +%endif + +%if LIB64DIR +%subpackage libs +f 0555 root sys $LIB64DIR/libcups.so.2 cups/libcups.64.so.2 nostrip() +l 0755 root sys $LIB64DIR/libcups.so libcups.so.2 +f 0555 root sys $LIB64DIR/libcupscgi.so.1 cgi-bin/libcupscgi.64.so.1 nostrip() +l 0755 root sys $LIB64DIR/libcupscgi.so libcupscgi.so.1 +f 0555 root sys $LIB64DIR/libcupsdriver.so.1 driver/libcupsdriver.64.so.1 nostrip() +l 0755 root sys $LIB64DIR/libcupsdriver.so libcupsdriver.so.1 +f 0555 root sys $LIB64DIR/libcupsimage.so.2 filter/libcupsimage.64.so.2 nostrip() +l 0755 root sys $LIB64DIR/libcupsimage.so libcupsimage.so.2 +f 0555 root sys $LIB64DIR/libcupsmime.so.1 scheduler/libcupsmime.64.so.1 nostrip() +l 0755 root sys $LIB64DIR/libcupsmime.so libcupsmime.so.1 +f 0555 root sys $LIB64DIR/libcupsppdc.so.1 ppdc/libcupsppdc.64.so.1 nostrip() +l 0755 root sys $LIB64DIR/libcupsppdc.so libcupsppdc.so.1 +%system all +%subpackage +%endif + +# Directories +d 0755 root sys $LOGDIR - +d 0710 root $CUPS_GROUP $REQUESTS - +d 1770 root $CUPS_GROUP $REQUESTS/tmp - +d 0775 root $CUPS_GROUP $CACHEDIR - +d 0775 root $CUPS_GROUP $CACHEDIR/rss - +#d 0755 root $CUPS_GROUP $CACHEDIR/ppd - +d 0755 root $CUPS_GROUP $STATEDIR - +d 0511 root $CUPS_PRIMARY_SYSTEM_GROUP $STATEDIR/certs - + +# Data files +#f 0444 root sys $LOCALEDIR/da/cups_da.po locale/cups_da.po +#f 0444 root sys $LOCALEDIR/de/cups_de.po locale/cups_de.po +f 0444 root sys $LOCALEDIR/es/cups_es.po locale/cups_es.po +#f 0444 root sys $LOCALEDIR/et/cups_et.po locale/cups_et.po +f 0444 root sys $LOCALEDIR/eu/cups_eu.po locale/cups_eu.po +#f 0444 root sys $LOCALEDIR/fi/cups_fi.po locale/cups_fi.po +#f 0444 root sys $LOCALEDIR/fr/cups_fr.po locale/cups_fr.po +#f 0444 root sys $LOCALEDIR/he/cups_he.po locale/cups_he.po +#f 0444 root sys $LOCALEDIR/it/cups_it.po locale/cups_it.po +#f 0444 root sys $LOCALEDIR/ja/cups_ja.po locale/cups_ja.po +#f 0444 root sys $LOCALEDIR/ko/cups_ko.po locale/cups_ko.po +#f 0444 root sys $LOCALEDIR/nl/cups_nl.po locale/cups_nl.po +#f 0444 root sys $LOCALEDIR/no/cups_no.po locale/cups_no.po +#f 0444 root sys $LOCALEDIR/pl/cups_pl.po locale/cups_pl.po +#f 0444 root sys $LOCALEDIR/pt/cups_pt.po locale/cups_pt.po +#f 0444 root sys $LOCALEDIR/pt_BR/cups_pt_BR.po locale/cups_pt_BR.po +#f 0444 root sys $LOCALEDIR/ru/cups_ru.po locale/cups_ru.po +#f 0444 root sys $LOCALEDIR/sv/cups_sv.po locale/cups_sv.po +#f 0444 root sys $LOCALEDIR/zh/cups_zh.po locale/cups_zh.po +#f 0444 root sys $LOCALEDIR/zh_TW/cups_zh_TW.po locale/cups_zh_TW.po + +d 0755 root sys $DATADIR - + +d 0755 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 0755 root sys $DATADIR/charmaps - +f 0444 root sys $DATADIR/charmaps data/*.txt + +d 0755 root sys $DATADIR/charsets - +f 0444 root sys $DATADIR/charsets/utf-8 data/utf-8 + +d 0755 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 data/testprint + +d 0755 root sys $DATADIR/drv - +f 0444 root sys $DATADIR/drv/sample.drv ppdc/sample.drv + +d 0755 root sys $DATADIR/examples - +f 0444 root sys $DATADIR/examples examples/*.drv + +d 0755 root sys $DATADIR/fonts - +f 0444 root sys $DATADIR/fonts fonts/Monospace* + +d 0755 root sys $DATADIR/mime - +f 0444 root sys $DATADIR/mime/mime.convs conf/mime.convs +f 0444 root sys $DATADIR/mime/mime.types conf/mime.types + +d 0755 root sys $DATADIR/model - + +d 0755 root sys $DATADIR/ppdc - +f 0444 root sys $DATADIR/ppdc data/*.defs +f 0444 root sys $DATADIR/ppdc data/*.h + +d 0755 root sys $DATADIR/templates - +f 0444 root sys $DATADIR/templates templates/*.tmpl + +## Template files +#d 0755 root sys $DATADIR/templates/de +#f 0444 root sys $DATADIR/templates/de templates/de/*.tmpl + +d 0755 root sys $DATADIR/templates/es +f 0444 root sys $DATADIR/templates/es templates/es/*.tmpl + +#d 0755 root sys $DATADIR/templates/et +#f 0444 root sys $DATADIR/templates/et templates/et/*.tmpl + +d 0755 root sys $DATADIR/templates/eu +f 0444 root sys $DATADIR/templates/eu templates/eu/*.tmpl + +#d 0755 root sys $DATADIR/templates/fr +#f 0444 root sys $DATADIR/templates/fr templates/fr/*.tmpl + +#d 0755 root sys $DATADIR/templates/he +#f 0444 root sys $DATADIR/templates/he templates/he/*.tmpl + +#d 0755 root sys $DATADIR/templates/it +#f 0444 root sys $DATADIR/templates/it templates/it/*.tmpl + +d 0755 root sys $DATADIR/templates/ja +f 0444 root sys $DATADIR/templates/ja templates/ja/*.tmpl + +d 0755 root sys $DATADIR/templates/pl +f 0444 root sys $DATADIR/templates/pl templates/pl/*.tmpl + +d 0755 root sys $DATADIR/templates/ru +f 0444 root sys $DATADIR/templates/ru templates/ru/*.tmpl + +#d 0755 root sys $DATADIR/templates/sv +#f 0444 root sys $DATADIR/templates/sv templates/sv/*.tmpl + +#d 0755 root sys $DATADIR/templates/zh_TW +#f 0444 root sys $DATADIR/templates/zh_TW templates/zh_TW/*.tmpl + +# Config files +d 0755 root sys $SERVERROOT - +d 0755 root $CUPS_GROUP $SERVERROOT/interfaces - +d 0755 root $CUPS_GROUP $SERVERROOT/ppd - +d 0700 root $CUPS_GROUP $SERVERROOT/ssl - +c $CUPS_PERM root $CUPS_GROUP $SERVERROOT conf/*.conf +f $CUPS_PERM root $CUPS_GROUP $SERVERROOT/cupsd.conf.default conf/cupsd.conf + +%if PAMDIR +d 0755 root sys $PAMDIR - +c 0644 root sys $PAMDIR/cups conf/@PAMFILE@ +%endif + +%subpackage devel +# Developer files +f 0555 root sys $BINDIR/cups-config cups-config +d 0755 root sys $INCLUDEDIR/cups - +f 0444 root sys $INCLUDEDIR/cups/adminutil.h cups/adminutil.h +f 0444 root sys $INCLUDEDIR/cups/array.h cups/array.h +f 0444 root sys $INCLUDEDIR/cups/backend.h cups/backend.h +f 0444 root sys $INCLUDEDIR/cups/cups.h cups/cups.h +f 0444 root sys $INCLUDEDIR/cups/dir.h cups/dir.h +f 0444 root sys $INCLUDEDIR/cups/driver.h driver/driver.h +f 0444 root sys $INCLUDEDIR/cups/file.h cups/file.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/mime.h scheduler/mime.h +f 0444 root sys $INCLUDEDIR/cups/language.h cups/language.h +f 0444 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h +f 0444 root sys $INCLUDEDIR/cups/raster.h cups/raster.h +f 0444 root sys $INCLUDEDIR/cups/transcode.h cups/transcode.h + +%if INSTALLSTATIC +f 0444 root sys $LIBDIR/libcups.a cups/libcups.a +f 0444 root sys $LIBDIR/libcupscgi.a cgi-bin/libcupscgi.a +f 0444 root sys $LIBDIR/libcupsdriver.a driver/libcupsdriver.a +f 0444 root sys $LIBDIR/libcupsimage.a filter/libcupsimage.a +f 0444 root sys $LIBDIR/libcupsmime.a scheduler/libcupsmime.a +f 0444 root sys $LIBDIR/libcupsppdc.a ppdc/libcupsppdc.a +%endif + +d 0755 root sys $DOCDIR/help - +f 0444 root sys $DOCDIR/help doc/help/api*.html +f 0444 root sys $DOCDIR/help/postscript-driver.html doc/help/postscript-driver.html +f 0444 root sys $DOCDIR/help/ppd-compiler.html doc/help/ppd-compiler.html +f 0444 root sys $DOCDIR/help/raster-driver.html doc/help/raster-driver.html +f 0444 root sys $DOCDIR/help doc/help/spec*.html +%subpackage + +# Documentation files +d 0755 root sys $DOCDIR - +f 0444 root sys $DOCDIR doc/*.css +f 0444 root sys $DOCDIR doc/*.html +d 0755 root sys $DOCDIR/help - +f 0444 root sys $DOCDIR/help/accounting.html doc/help/accounting.html +f 0444 root sys $DOCDIR/help/cgi.html doc/help/cgi.html +f 0444 root sys $DOCDIR/help/glossary.html doc/help/glossary.html +f 0444 root sys $DOCDIR/help/kerberos.html doc/help/kerberos.html +f 0444 root sys $DOCDIR/help/license.html doc/help/license.html +f 0444 root sys $DOCDIR/help/network.html doc/help/network.html +f 0444 root sys $DOCDIR/help/options.html doc/help/options.html +f 0444 root sys $DOCDIR/help/overview.html doc/help/overview.html +f 0444 root sys $DOCDIR/help/policies.html doc/help/policies.html +f 0444 root sys $DOCDIR/help/security.html doc/help/security.html +f 0444 root sys $DOCDIR/help/sharing.html doc/help/sharing.html +f 0444 root sys $DOCDIR/help/standard.html doc/help/standard.html +f 0444 root sys $DOCDIR/help/translation.html doc/help/translation.html +f 0444 root sys $DOCDIR/help/whatsnew.html doc/help/whatsnew.html +f 0444 root sys $DOCDIR/help doc/help/man-*.html +f 0444 root sys $DOCDIR/help doc/help/ref-*.html +d 0755 root sys $DOCDIR/images - +f 0444 root sys $DOCDIR/images doc/images/*.gif +f 0444 root sys $DOCDIR/images doc/images/*.jpg +f 0444 root sys $DOCDIR/images doc/images/*.png +f 0444 root sys $DOCDIR/robots.txt doc/robots.txt + +# Localized documentation files +#d 0755 root sys $DOCDIR/de +#f 0444 root sys $DOCDIR/de doc/de/*.html + +d 0755 root sys $DOCDIR/es +f 0444 root sys $DOCDIR/es doc/es/*.html + +#d 0755 root sys $DOCDIR/et +#f 0444 root sys $DOCDIR/et doc/et/*.html + +d 0755 root sys $DOCDIR/eu +f 0444 root sys $DOCDIR/eu doc/eu/*.html + +#d 0755 root sys $DOCDIR/fr +#f 0444 root sys $DOCDIR/fr doc/fr/*.html + +#d 0755 root sys $DOCDIR/he +#f 0444 root sys $DOCDIR/he doc/he/*.html +#f 0444 root sys $DOCDIR/he/cups.css doc/he/cups.css + +#d 0755 root sys $DOCDIR/it +#f 0444 root sys $DOCDIR/it doc/it/*.html + +d 0755 root sys $DOCDIR/ja +f 0444 root sys $DOCDIR/ja doc/ja/*.html + +d 0755 root sys $DOCDIR/pl +f 0444 root sys $DOCDIR/pl doc/pl/*.html + +d 0755 root sys $DOCDIR/ru +f 0444 root sys $DOCDIR/ru doc/ru/*.html + +#d 0755 root sys $DOCDIR/sv +#f 0444 root sys $DOCDIR/sv doc/sv/*.html + +#d 0755 root sys $DOCDIR/zh_TW +#f 0444 root sys $DOCDIR/zh_TW doc/zh_TW/*.html + +# Man pages +d 0755 root sys $AMANDIR - +d 0755 root sys $AMANDIR/man$MAN8DIR - +d 0755 root sys $MANDIR - +d 0755 root sys $MANDIR/man1 - +d 0755 root sys $MANDIR/man5 - +d 0755 root sys $MANDIR/man7 - + +f 0444 root sys $MANDIR/man1/cancel.$MAN1EXT man/cancel.$MAN1EXT +f 0444 root sys $MANDIR/man1/cupstestdsc.$MAN1EXT man/cupstestdsc.$MAN1EXT +f 0444 root sys $MANDIR/man1/cupstestppd.$MAN1EXT man/cupstestppd.$MAN1EXT +f 0444 root sys $MANDIR/man1/lpoptions.$MAN1EXT man/lpoptions.$MAN1EXT +f 0444 root sys $MANDIR/man1/lppasswd.$MAN1EXT man/lppasswd.$MAN1EXT +f 0444 root sys $MANDIR/man1/lpq.$MAN1EXT man/lpq.$MAN1EXT +f 0444 root sys $MANDIR/man1/lprm.$MAN1EXT man/lprm.$MAN1EXT +f 0444 root sys $MANDIR/man1/lpr.$MAN1EXT man/lpr.$MAN1EXT +f 0444 root sys $MANDIR/man1/lpstat.$MAN1EXT man/lpstat.$MAN1EXT +f 0444 root sys $MANDIR/man1/lp.$MAN1EXT man/lp.$MAN1EXT + +f 0444 root sys $MANDIR/man5/classes.conf.$MAN5EXT man/classes.conf.$MAN5EXT +f 0444 root sys $MANDIR/man5/cupsd.conf.$MAN5EXT man/cupsd.conf.$MAN5EXT +f 0444 root sys $MANDIR/man5/mailto.conf.$MAN5EXT man/mailto.conf.$MAN5EXT +f 0444 root sys $MANDIR/man5/mime.convs.$MAN5EXT man/mime.convs.$MAN5EXT +f 0444 root sys $MANDIR/man5/mime.types.$MAN5EXT man/mime.types.$MAN5EXT +f 0444 root sys $MANDIR/man5/printers.conf.$MAN5EXT man/printers.conf.$MAN5EXT + +l 0644 root sys $AMANDIR/man$MAN8DIR/accept.$MAN8EXT cupsaccept.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cupsaccept.$MAN8EXT man/cupsaccept.$MAN8EXT +l 0644 root sys $AMANDIR/man$MAN8DIR/cupsreject.$MAN8EXT cupsaccept.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cupsaddsmb.$MAN8EXT man/cupsaddsmb.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cupsctl.$MAN8EXT man/cupsctl.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cupsfilter.$MAN8EXT man/cupsfilter.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cups-polld.$MAN8EXT man/cups-polld.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cupsd.$MAN8EXT man/cupsd.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/cupsenable.$MAN8EXT man/cupsenable.$MAN8EXT +l 0644 root sys $AMANDIR/man$MAN8DIR/cupsdisable.$MAN8EXT cupsenable.$MAN8EXT +l 0644 root sys $AMANDIR/man$MAN8DIR/disable.$MAN8EXT cupsenable.$MAN8EXT +l 0644 root sys $AMANDIR/man$MAN8DIR/enable.$MAN8EXT cupsenable.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/lpadmin.$MAN8EXT man/lpadmin.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/lpc.$MAN8EXT man/lpc.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/lpinfo.$MAN8EXT man/lpinfo.$MAN8EXT +f 0444 root sys $AMANDIR/man$MAN8DIR/lpmove.$MAN8EXT man/lpmove.$MAN8EXT +l 0644 root sys $AMANDIR/man$MAN8DIR/reject.$MAN8EXT cupsaccept.$MAN8EXT + +%subpackage devel +f 0444 root sys $MANDIR/man1/cups-config.$MAN1EXT man/cups-config.$MAN1EXT +f 0444 root sys $MANDIR/man1/ man/ppd*.$MAN1EXT +f 0444 root sys $MANDIR/man5/ppdcfile.$MAN5EXT man/ppdcfile.$MAN5EXT +f 0444 root sys $MANDIR/man7/backend.$MAN7EXT man/backend.$MAN7EXT +f 0444 root sys $MANDIR/man7/filter.$MAN7EXT man/filter.$MAN7EXT +f 0444 root sys $MANDIR/man7/notifier.$MAN7EXT man/notifier.$MAN7EXT + +%subpackage lpd +d 0755 root sys $AMANDIR/man$MAN8DIR - +f 0444 root sys $AMANDIR/man$MAN8DIR/cups-lpd.$MAN8EXT man/cups-lpd.$MAN8EXT +%subpackage + +# Startup scripts +%system darwin +f 0444 root sys /System/Library/LaunchDaemons/org.cups.cupsd.plist init/org.cups.cupsd.plist +%preremove <. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1999-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# Conditional build options (--with name/--without name): +# +# dbus - Enable/disable DBUS support (default = enable) +# php - Enable/disable PHP support (default = enable) + +%{!?_with_dbus: %{!?_without_dbus: %define _with_dbus --with-dbus}} +%{?_with_dbus: %define _dbus --enable-dbus} +%{!?_with_dbus: %define _dbus --disable-dbus} + +%{!?_with_php: %{!?_without_php: %define _with_php --with-php}} +%{?_with_php: %define _php --with-php} +%{!?_with_php: %define _php --without-php} + +%{!?_with_static: %{!?_without_static: %define _without_static --without-static}} +%{?_with_static: %define _static --enable-static} +%{!?_with_static: %define _static --disable-static} + +Summary: CUPS +Name: cups +Version: @CUPS_VERSION@ +Release: 0 +Epoch: 1 +License: GPL +Group: System Environment/Daemons +Source: http://ftp.easysw.com/pub/cups/%{version}/cups-%{version}-source.tar.bz2 +Url: http://www.cups.org +Packager: Anonymous +Vendor: Apple Inc. + +# Use buildroot so as not to disturb the version already installed +BuildRoot: /tmp/%{name}-root + +# Dependencies... +Requires: %{name}-libs = %{epoch}:%{version} +Obsoletes: lpd, lpr, LPRng +Provides: lpd, lpr, LPRng +Obsoletes: cups-da, cups-de, cups-es, cups-et, cups-fi, cups-fr, cups-he +Obsoletes: cups-id, cups-it, cups-ja, cups-ko, cups-nl, cups-no, cups-pl +Obsoletes: cups-pt, cups-ru, cups-sv, cups-zh + +%package devel +Summary: CUPS - development environment +Group: Development/Libraries +Requires: %{name}-libs = %{epoch}:%{version} + +%package libs +Summary: CUPS - shared libraries +Group: System Environment/Libraries +Provides: libcups1 + +%package lpd +Summary: CUPS - LPD support +Group: System Environment/Daemons +Requires: %{name} = %{epoch}:%{version} xinetd + +%if %{?_with_php:1}%{!?_with_php:0} +%package php +Summary: CUPS - PHP support +Group: Development/Languages +Requires: %{name}-libs = %{epoch}:%{version} +%endif + +%description +CUPS is the standards-based, open source printing system developed by +Apple Inc. for Mac OS¨ X and other UNIX¨-like operating systems. + +%description devel +This package provides the CUPS headers and development environment. + +%description libs +This package provides the CUPS shared libraries. + +%description lpd +This package provides LPD client support. + +%if %{?_with_php:1}%{!?_with_php:0} +%description php +This package provides PHP support for CUPS. +%endif + +%prep +%setup + +%build +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" \ + ./configure %{_dbus} %{_php} %{_static} +# 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 +/sbin/chkconfig --add cups +/sbin/chkconfig cups on + +# Restart cupsd if we are upgrading... +if test $1 -gt 1; then + /sbin/service cups stop + /sbin/service cups start +fi + +%post libs +/sbin/ldconfig + +%preun +if test $1 = 0; then + /sbin/service cups stop + /sbin/chkconfig --del cups +fi + +%postun +if test $1 -ge 1; then + /sbin/service cups stop + /sbin/service cups start +fi + +%postun libs +/sbin/ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%docdir /usr/share/doc/cups +%defattr(-,root,root) +%dir /etc/cups +%config(noreplace) /etc/cups/*.conf +/etc/cups/cupsd.conf.default +%dir /etc/cups/interfaces +%dir /etc/cups/ppd +%attr(0700,root,root) %dir /etc/cups/ssl + +%if %{?_with_dbus:1}%{!?_with_dbus:0} +# DBUS +/etc/dbus-1/system.d/* +%endif + +# PAM +%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/init.d/* +/etc/rc0.d/* +/etc/rc2.d/* +/etc/rc3.d/* +/etc/rc5.d/* + +# OLD RedHat/Mandrake +#/etc/rc.d/init.d/* +#/etc/rc.d/rc0.d/* +#/etc/rc.d/rc2.d/* +#/etc/rc.d/rc3.d/* +#/etc/rc.d/rc5.d/* + +#/sbin/rc.d/* +#/sbin/rc.d/rc0.d/* +#/sbin/rc.d/rc2.d/* +#/sbin/rc.d/rc3.d/* +#/sbin/rc.d/rc5.d/* + +/usr/bin/cancel +/usr/bin/cupstestdsc +/usr/bin/cupstestppd +/usr/bin/lp* +%dir /usr/lib/cups +%dir /usr/lib/cups/backend +/usr/lib/cups/backend/http +%attr(0700,root,root) /usr/lib/cups/backend/ipp +%attr(0700,root,root) /usr/lib/cups/backend/lpd +/usr/lib/cups/backend/parallel +/usr/lib/cups/backend/scsi +/usr/lib/cups/backend/serial +/usr/lib/cups/backend/snmp +/usr/lib/cups/backend/socket +/usr/lib/cups/backend/usb +%dir /usr/lib/cups/cgi-bin +/usr/lib/cups/cgi-bin/* +%dir /usr/lib/cups/daemon +/usr/lib/cups/daemon/cups-deviced +/usr/lib/cups/daemon/cups-driverd +/usr/lib/cups/daemon/cups-polld +%dir /usr/lib/cups/driver +%dir /usr/lib/cups/filter +/usr/lib/cups/filter/* +%dir /usr/lib/cups/monitor +/usr/lib/cups/monitor/* +%dir /usr/lib/cups/notifier +/usr/lib/cups/notifier/* + +/usr/sbin/* +%dir /usr/share/cups +%dir /usr/share/cups/banners +/usr/share/cups/banners/* +%dir /usr/share/cups/charmaps +/usr/share/cups/charmaps/* +%dir /usr/share/cups/charsets +/usr/share/cups/charsets/* +%dir /usr/share/cups/data +/usr/share/cups/data/* +%dir /usr/share/cups/drv +/usr/share/cups/drv/* +%dir /usr/share/cups/fonts +/usr/share/cups/fonts/* +%dir /usr/share/cups/mime +/usr/share/cups/mime/* +%dir /usr/share/cups/model +%dir /usr/share/cups/ppdc +/usr/share/cups/ppdc/* +%dir /usr/share/cups/templates +/usr/share/cups/templates/* +%dir /usr/share/doc/cups +/usr/share/doc/cups/*.* +%dir /usr/share/doc/cups/de +/usr/share/doc/cups/de/* +%dir /usr/share/doc/cups/es +/usr/share/doc/cups/es/* +%dir /usr/share/doc/cups/eu +/usr/share/doc/cups/eu/* +%dir /usr/share/doc/cups/id +/usr/share/doc/cups/id/* +%dir /usr/share/doc/cups/it +/usr/share/doc/cups/it/* +%dir /usr/share/doc/cups/ja +/usr/share/doc/cups/ja/* +%dir /usr/share/doc/cups/pl +/usr/share/doc/cups/pl/* +%dir /usr/share/doc/cups/ru +/usr/share/doc/cups/ru/* +%dir /usr/share/doc/cups/help +/usr/share/doc/cups/help/accounting.html +/usr/share/doc/cups/help/cgi.html +/usr/share/doc/cups/help/glossary.html +/usr/share/doc/cups/help/kerberos.html +/usr/share/doc/cups/help/license.html +/usr/share/doc/cups/help/man-*.html +/usr/share/doc/cups/help/network.html +/usr/share/doc/cups/help/options.html +/usr/share/doc/cups/help/overview.html +/usr/share/doc/cups/help/policies.html +/usr/share/doc/cups/help/ref-*.html +/usr/share/doc/cups/help/security.html +/usr/share/doc/cups/help/sharing.html +/usr/share/doc/cups/help/standard.html +/usr/share/doc/cups/help/translation.html +/usr/share/doc/cups/help/whatsnew.html +%dir /usr/share/doc/cups/images +/usr/share/doc/cups/images/* +/usr/share/locale/* + +%dir /usr/share/man/man1 +/usr/share/man/man1/cancel.1.gz +/usr/share/man/man1/cupstestdsc.1.gz +/usr/share/man/man1/cupstestppd.1.gz +/usr/share/man/man1/lp.1.gz +/usr/share/man/man1/lpoptions.1.gz +/usr/share/man/man1/lppasswd.1.gz +/usr/share/man/man1/lpq.1.gz +/usr/share/man/man1/lpr.1.gz +/usr/share/man/man1/lprm.1.gz +/usr/share/man/man1/lpstat.1.gz +%dir /usr/share/man/man5 +/usr/share/man/man5/*.conf.5.gz +/usr/share/man/man5/mime.*.5.gz +%dir /usr/share/man/man8 +/usr/share/man/man8/accept.8.gz +/usr/share/man/man8/cupsaddsmb.8.gz +/usr/share/man/man8/cupsaccept.8.gz +/usr/share/man/man8/cupsctl.8.gz +/usr/share/man/man8/cupsfilter.8.gz +/usr/share/man/man8/cupsd.8.gz +/usr/share/man/man8/cupsdisable.8.gz +/usr/share/man/man8/cupsenable.8.gz +/usr/share/man/man8/cupsreject.8.gz +/usr/share/man/man8/cups-deviced.8.gz +/usr/share/man/man8/cups-driverd.8.gz +/usr/share/man/man8/cups-polld.8.gz +/usr/share/man/man8/lpadmin.8.gz +/usr/share/man/man8/lpc.8.gz +/usr/share/man/man8/lpinfo.8.gz +/usr/share/man/man8/lpmove.8.gz +/usr/share/man/man8/reject.8.gz + +%dir /var/cache/cups +%attr(0775,root,sys) %dir /var/cache/cups/rss +%dir /var/log/cups +%dir /var/run/cups +%attr(0711,lp,sys) %dir /var/run/cups/certs +%attr(0710,lp,sys) %dir /var/spool/cups +%attr(1770,lp,sys) %dir /var/spool/cups/tmp + +# Desktop files +/usr/share/applications/* +/usr/share/icons/* + +%files devel +%defattr(-,root,root) +%dir /usr/share/cups/examples +/usr/share/cups/examples/* +%dir /usr/share/man/man1 +/usr/share/man/man1/cups-config.1.gz +/usr/share/man/man1/ppd*.1.gz +%dir /usr/share/man/man5 +/usr/share/man/man5/ppdcfile.5.gz +/usr/share/man/man7/backend.7.gz +/usr/share/man/man7/filter.7.gz +/usr/share/man/man7/notifier.7.gz + +/usr/bin/cups-config +/usr/bin/ppd* +%dir /usr/include/cups +/usr/include/cups/* +/usr/lib*/*.so + +%if %{?_with_static:1}%{!?_with_static:0} +/usr/lib*/*.a +%endif + +%dir /usr/share/doc/cups/help +/usr/share/doc/cups/help/api*.html +/usr/share/doc/cups/help/postscript-driver.html +/usr/share/doc/cups/help/ppd-compiler.html +/usr/share/doc/cups/help/raster-driver.html +/usr/share/doc/cups/help/spec*.html + +%files libs +%defattr(-,root,root) +/usr/lib*/*.so.* + +%files lpd +%defattr(-,root,root) +/etc/xinetd.d/cups-lpd +%dir /usr/lib/cups +%dir /usr/lib/cups/daemon +/usr/lib/cups/daemon/cups-lpd +%dir /usr/share/man/man8 +/usr/share/man/man8/cups-lpd.8.gz + +%if %{?_with_php:1}%{!?_with_php:0} +%files php +# PHP +/usr/lib*/php* +%endif + + +# +# End of "$Id$". +# diff --git a/packaging/installer.gif b/packaging/installer.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ae6ea77a8c02cd6dc5e5e2a90d4fe4d495076a9 GIT binary patch literal 3392 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 YpH<-Rh5!FZVTAstvH$M>ar_?t2g=;5{{R30 literal 0 Hc-jL100001 diff --git a/ppdc/Dependencies b/ppdc/Dependencies new file mode 100644 index 0000000000..4320ad74c6 --- /dev/null +++ b/ppdc/Dependencies @@ -0,0 +1,160 @@ +# DO NOT DELETE + +ppdc-array.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-array.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-array.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-array.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-array.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +ppdc-array.o: ../cups/i18n.h ../cups/transcode.h +ppdc-attr.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-attr.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-attr.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-attr.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdc-attr.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdc-attr.o: ../cups/transcode.h +ppdc-catalog.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-catalog.o: ../cups/debug.h ../cups/globals.h ../cups/string.h +ppdc-catalog.o: ../config.h ../cups/http-private.h ../cups/http.h +ppdc-catalog.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ppdc-catalog.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-catalog.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-choice.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-choice.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-choice.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-choice.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-choice.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-choice.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-constraint.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-constraint.o: ../cups/debug.h ../cups/globals.h ../cups/string.h +ppdc-constraint.o: ../config.h ../cups/http-private.h ../cups/http.h +ppdc-constraint.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ppdc-constraint.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h +ppdc-constraint.o: ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdc-constraint.o: ../cups/transcode.h +ppdc-driver.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-driver.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-driver.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-driver.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-driver.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-driver.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-file.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-file.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-file.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-file.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdc-file.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdc-file.o: ../cups/transcode.h ../cups/i18n.h +ppdc-filter.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-filter.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-filter.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-filter.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-filter.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-filter.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-font.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-font.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-font.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-font.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdc-font.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdc-font.o: ../cups/transcode.h +ppdc-group.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-group.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-group.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-group.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-group.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +ppdc-group.o: ../cups/i18n.h ../cups/transcode.h +ppdc-import.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-import.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-import.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-import.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-import.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-import.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-import.o: ../cups/ppd.h ../cups/i18n.h +ppdc-mediasize.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-mediasize.o: ../cups/debug.h ../cups/globals.h ../cups/string.h +ppdc-mediasize.o: ../config.h ../cups/http-private.h ../cups/http.h +ppdc-mediasize.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ppdc-mediasize.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-mediasize.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-message.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-message.o: ../cups/debug.h ../cups/globals.h ../cups/string.h +ppdc-message.o: ../config.h ../cups/http-private.h ../cups/http.h +ppdc-message.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ppdc-message.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-message.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-option.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-option.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-option.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-option.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-option.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-option.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-profile.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-profile.o: ../cups/debug.h ../cups/globals.h ../cups/string.h +ppdc-profile.o: ../config.h ../cups/http-private.h ../cups/http.h +ppdc-profile.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ppdc-profile.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-profile.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-shared.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-shared.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-shared.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-shared.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-shared.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-shared.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-source.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-source.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-source.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-source.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-source.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-source.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-source.o: ../cups/raster.h ../cups/cups.h ../data/epson.h ../data/escp.h +ppdc-source.o: ../data/hp.h ../data/label.h ../data/pcl.h +ppdc-string.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-string.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc-string.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc-string.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +ppdc-string.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-string.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +ppdc-variable.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc-variable.o: ../cups/debug.h ../cups/globals.h ../cups/string.h +ppdc-variable.o: ../config.h ../cups/http-private.h ../cups/http.h +ppdc-variable.o: ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ppdc-variable.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +ppdc-variable.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h +genstrings.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +genstrings.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +genstrings.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +genstrings.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +genstrings.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +genstrings.o: ../cups/i18n.h ../cups/transcode.h +ppdc.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdc.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdc.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdc.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdc.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdc.o: ../cups/transcode.h +ppdhtml.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdhtml.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdhtml.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdhtml.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdhtml.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdhtml.o: ../cups/transcode.h +ppdi.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdi.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdi.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdi.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdi.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdi.o: ../cups/transcode.h +ppdmerge.o: ../cups/ppd-private.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +ppdmerge.o: ../cups/versioning.h ../cups/string.h ../config.h ../cups/ppd.h +ppdmerge.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/cups.h +ppdmerge.o: ../cups/array.h ../cups/string.h ../cups/i18n.h +ppdpo.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +ppdpo.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +ppdpo.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +ppdpo.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h ../cups/ppd.h +ppdpo.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/i18n.h +ppdpo.o: ../cups/transcode.h +testcatalog.o: ppdc-private.h ppdc.h ../cups/file.h ../cups/versioning.h +testcatalog.o: ../cups/debug.h ../cups/globals.h ../cups/string.h ../config.h +testcatalog.o: ../cups/http-private.h ../cups/http.h ../cups/md5.h +testcatalog.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/cups.h +testcatalog.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +testcatalog.o: ../cups/language.h ../cups/i18n.h ../cups/transcode.h diff --git a/ppdc/Makefile b/ppdc/Makefile new file mode 100644 index 0000000000..a1bd6f950c --- /dev/null +++ b/ppdc/Makefile @@ -0,0 +1,404 @@ +# +# "$Id$" +# +# Makefile for the CUPS PPD Compiler. +# +# Copyright 2007-2011 by Apple Inc. +# Copyright 2002-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Include standard definitions... +# + +include ../Makedefs + + +# +# Object files... +# + +LIBOBJS = \ + ppdc-array.o \ + ppdc-attr.o \ + ppdc-catalog.o \ + ppdc-choice.o \ + ppdc-constraint.o \ + ppdc-driver.o \ + ppdc-file.o \ + ppdc-filter.o \ + ppdc-font.o \ + ppdc-group.o \ + ppdc-import.o \ + ppdc-mediasize.o \ + ppdc-message.o \ + ppdc-option.o \ + ppdc-profile.o \ + ppdc-shared.o \ + ppdc-source.o \ + ppdc-string.o \ + ppdc-variable.o +OBJS = \ + $(LIBOBJS) \ + genstrings.o \ + ppdc.o \ + ppdhtml.o \ + ppdi.o \ + ppdmerge.o \ + ppdpo.o \ + testcatalog.o +LIBTARGETS = \ + $(LIBCUPSPPDC) \ + libcupsppdc.a +UNITTARGETS = \ + ppdc-static \ + ppdi-static \ + testcatalog +EXECTARGETS = \ + ppdc \ + ppdhtml \ + ppdi \ + ppdmerge \ + ppdpo + +TARGETS = \ + $(LIBTARGETS) \ + $(EXECTARGETS) \ + genstrings + + +# +# Make everything... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: $(LIBTARGETS) + + +# +# Make unit tests... +# + +unittests: $(UNITTARGETS) + + +# +# Clean everything... +# + +clean: + $(RM) $(OBJS) core + $(RM) *.bak *.bck core.* + $(RM) $(TARGETS) $(UNITTARGETS) + $(RM) -r ppd ppd2 + $(RM) sample-import.drv sample.c test.drv + $(RM) libcupsppdc.so libcupsppdc.sl libcupsppdc.dylib + + +# +# Update dependencies... +# + +depend: + makedepend -Y -I.. -fDependencies $(OBJS:.o=.cxx) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + $(INSTALL_DIR) $(DATADIR)/drv + $(INSTALL_DATA) sample.drv $(DATADIR)/drv + + +# +# Install programs... +# + +install-exec: + echo Installing PPD compiler programs... + $(INSTALL_DIR) $(BINDIR) + for file in $(EXECTARGETS); do \ + $(INSTALL_BIN) $$file $(BINDIR); \ + done + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(EXECTARGETS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + echo Installing header files in $(INCLUDEDIR)/cups... + $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups + $(INSTALL_DATA) ppdc.h $(INCLUDEDIR)/cups + + +# +# Install libraries... +# + +install-libs: $(INSTALLSTATIC) + echo Installing libraries in $(LIBDIR)... + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) $(LIBCUPSPPDC) $(LIBDIR) + if test $(LIBCUPSPPDC) = "libcupsppdc.so.1" -o $(LIBCUPSPPDC) = "libcupsppdc.sl.1"; then \ + $(RM) $(LIBDIR)/`basename $(LIBCUPSPPDC) .1`; \ + $(LN) $(LIBCUPSPPDC) $(LIBDIR)/`basename $(LIBCUPSPPDC) .1`; \ + fi + if test $(LIBCUPSPPDC) = "libcupsppdc.1.dylib"; then \ + $(RM) $(LIBDIR)/libcupsppdc.dylib; \ + $(LN) $(LIBCUPSPPDC) $(LIBDIR)/libcupsppdc.dylib; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(LIBCUPSPPDC) $(SYMROOT); \ + fi + +installstatic: + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) -m 755 libcupsppdc.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcupsppdc.a + $(CHMOD) 555 $(LIBDIR)/libcupsppdc.a + + +# +# Uninstall... +# + +uninstall: + for file in $(EXECTARGETS); do \ + $(RM) $(BINDIR)/$$file; \ + done + $(RM) $(DATADIR)/drv/sample.drv + $(RMDIR) $(DATADIR)/drv + $(RM) $(LIBDIR)/libcupsppdc.1.dylib + $(RM) $(LIBDIR)/libcupsppdc.a + $(RM) $(LIBDIR)/libcupsppdc.dylib + $(RM) $(LIBDIR)/libcupsppdc_s.a + $(RM) $(LIBDIR)/libcupsppdc.sl + $(RM) $(LIBDIR)/libcupsppdc.sl.1 + $(RM) $(LIBDIR)/libcupsppdc.so + $(RM) $(LIBDIR)/libcupsppdc.so.1 + -$(RMDIR) $(LIBDIR) + $(RM) $(INCLUDEDIR)/cups/ppdc.h + -$(RMDIR) $(INCLUDEDIR)/cups + + +# +# Automatic API help files... +# + +apihelp: + mxmldoc --section "Programming" \ + --title "PPD Compiler API" \ + --css ../doc/cups-printable.css \ + --header api-ppdc.header --intro api-ppdc.shtml \ + api-ppdc.xml \ + ppdc.h $(LIBOBJS:.o=.cxx) >../doc/help/api-ppdc.html + mxmldoc --tokens help/api-ppdc.html api-ppdc.xml >../doc/help/api-ppdc.tokens + $(RM) api-ppdc.xml + +framedhelp: + mxmldoc --framed api-ppdc \ + --section "Programming" \ + --title "PPD Compiler API" \ + --css ../doc/cups-printable.css \ + --header api-ppdc.header --intro api-ppdc.shtml \ + ppdc.h $(LIBOBJS:.o=.cxx) + + +# +# genstrings - generate GNU gettext strings. +# + +genstrings: genstrings.o libcupsppdc.a ../cups/libcups.a \ + sample.drv ../data/media.defs + echo Linking $@... + $(CXX) $(ARCHFLAGS) $(LDFLAGS) -o genstrings genstrings.o \ + libcupsppdc.a ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) \ + $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + echo Generating localization strings... + ./genstrings >sample.c + + +# +# ppdc, the PPD compiler. +# + +ppdc: ppdc.o $(LIBCUPSPPDC) ../cups/$(LIBCUPS) + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ ppdc.o -L. -lcupsppdc $(LIBS) + + +ppdc-static: ppdc.o libcupsppdc.a ../cups/libcups.a foo.drv foo-fr.po + echo Linking $@... + $(CXX) $(ARCHFLAGS) $(LDFLAGS) -o ppdc-static ppdc.o libcupsppdc.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + echo Testing PPD compiler... + ./ppdc-static -l en,fr -I ../data foo.drv + ./ppdc-static -l en,fr -z -I ../data foo.drv + + +# +# ppdhtml, the PPD to HTML utility. +# + +ppdhtml: ppdhtml.o $(LIBCUPSPPDC) ../cups/$(LIBCUPS) + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ ppdhtml.o -L. -lcupsppdc $(LIBS) + + +# +# ppdi, import PPD files. +# + +ppdi: ppdi.o $(LIBCUPSPPDC) ../cups/$(LIBCUPS) + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ ppdi.o -L. -lcupsppdc $(LIBS) + + +ppdi-static: ppdc-static ppdi.o libcupsppdc.a ../cups/libcups.a + echo Linking $@... + $(CXX) $(ARCHFLAGS) $(LDFLAGS) -o ppdi-static ppdi.o libcupsppdc.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + echo Testing PPD importer... + $(RM) -r ppd ppd2 sample-import.drv + ./ppdc-static -I ../data sample.drv + ./ppdi-static -I ../data -o sample-import.drv ppd/* + ./ppdc-static -I ../data -d ppd2 sample-import.drv + if diff -r ppd ppd2 >/dev/null; then \ + echo PPD import OK; \ + else \ + echo PPD import FAILED; \ + exit 1; \ + fi + + +# +# ppdmerge, merge PPD files. +# + +ppdmerge: ppdmerge.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ ppdmerge.o $(LIBS) + + +# +# ppdpo, create message catalog files. +# + +ppdpo: ppdpo.o $(LIBCUPSPPDC) ../cups/$(LIBCUPS) + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ ppdpo.o -L. -lcupsppdc $(LIBS) + + +# +# testcatalog, test ppdcCatalog class. +# + +testcatalog: testcatalog.o libcupsppdc.a ../cups/libcups.a + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ testcatalog.o libcupsppdc.a \ + ../cups/libcups.a $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) \ + $(COMMONLIBS) $(LIBZ) + + +# +# libcupsppdc.so.1, libcupsppdc.sl.1 +# + +libcupsppdc.so.1 libcupsppdc.sl.1: $(LIBOBJS) ../cups/$(LIBCUPS) + echo Linking $@... + $(DSOXX) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LINKCUPS) + $(RM) `basename $@ .1` + $(LN) $@ `basename $@ .1` + + +# +# libcupsppdc.1.dylib +# + +libcupsppdc.1.dylib: $(LIBOBJS) ../cups/$(LIBCUPS) + echo Creating export list for $@... + nm $(LIBOBJS) | grep "T __" | awk '{print $$3}' | sort >t.exp + echo Linking $@... + $(DSOXX) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.0.0 \ + -compatibility_version 1.0.0 \ + -exported_symbols_list t.exp \ + $(LIBOBJS) $(LINKCUPS) + $(RM) libcupsppdc.dylib t.exp + $(LN) $@ libcupsppdc.dylib + + +# +# libcupsppdc_s.a +# + +libcupsppdc_s.a: $(LIBOBJS) ../cups/$(LIBCUPS) + echo Creating $@... + $(DSOXX) $(DSOFLAGS) -o libcupsppdc_s.o $(LIBOBJS) $(LINKCUPS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcupsppdc_s.o + + +# +# libcupsppdc.la +# + +libcupsppdc.la: $(LIBOBJS) ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \ + -version-info 1:0 $(LINKCUPS) + + +# +# libcupsppdc.a +# + +libcupsppdc.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# Include dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/ppdc/api-ppdc.header b/ppdc/api-ppdc.header new file mode 100644 index 0000000000..418686560e --- /dev/null +++ b/ppdc/api-ppdc.header @@ -0,0 +1,34 @@ + + +

PPD Compiler API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/ppdc.h
Library-lcupsppdc
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/ppdc/api-ppdc.shtml b/ppdc/api-ppdc.shtml new file mode 100644 index 0000000000..e305dcb9d0 --- /dev/null +++ b/ppdc/api-ppdc.shtml @@ -0,0 +1,18 @@ + + +

Overview

+ +

The PPD Compiler API provides access to CUPS driver information files and +methods for generating and importing PPD files.

diff --git a/ppdc/foo-fr.po b/ppdc/foo-fr.po new file mode 100644 index 0000000000..1b1561b395 --- /dev/null +++ b/ppdc/foo-fr.po @@ -0,0 +1,11 @@ +msgid "A Serious Error" +msgstr "La Error Serious" + +msgid "http://foo.com/serious.html" +msgstr "http://foo.com/fr/serious.html" + +msgid "Foo Letter" +msgstr "La Foo Letter" + +msgid "Foo Photo" +msgstr "La Foo Photo" diff --git a/ppdc/foo.drv b/ppdc/foo.drv new file mode 100644 index 0000000000..fa84f3d1f6 --- /dev/null +++ b/ppdc/foo.drv @@ -0,0 +1,548 @@ +// +// "$Id$" +// +// PPD file compiler test data file for the Common UNIX Printing +// System (CUPS). +// +// Copyright 2007 by Apple Inc. +// Copyright 1997-2003 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// + +/* + * C-style comments are supported. + */ + +// +// C++-style comments are supported. +// + +// +// Include the common media size definitions... +// +// #include directives support both to include a standard file +// and "name" or just name without the quotes for a local file. Local +// files resolve relative to the current file's path. Unlike C/C++, +// #include does not look in multiple directories, and +// #include "name" does not look in the standard directory. +// + +#include + + +// +// Include the CUPS raster definitions... +// + +#include + + +// +// Include the standard CUPS fonts... +// + +#include + + +// +// Define variables using the #define directive. In this case we +// are defining constants for the model number, which is used by +// our imaginary rastertofoo filter to determine which model-specific +// features to use/support. +// + +#define MODEL_BW 0 +#define MODEL_COLOR 1 + +#define MODEL_LASER 0 +#define MODEL_PHOTO 2 + + +// +// Media sizes are defined using the #media directive. The order of +// values is: size name/text, width, length. +// +// "Size name" is an alphanumeric string of up to 40 characters as +// defined by the Adobe PPD specification. +// +// "Size text" is a text string of up to 80 characters as defined by +// the Adobe PPD specification. +// +// "Width" and "length" are the width and length of the media size. +// Numbers by themselves represent points (72 points = 1 inch). The +// suffixes "cm", "ft", "in", "m", "mm", and "pt" are recognized to +// specify centimeters, feet, inches, meters, millimeters, and points, +// respectively. +// + +#media "FooLetter/Foo Letter" 8in 10in +#media "FooPhoto/Foo Photo" 200mm 300mm + + +// +// Message catalogs can be included using #po... +// + +#po fr foo-fr.po + + +// +// Specify that the drivers use all of the standard base fonts... +// + +Font * + + +// +// All copyright lines are put at the top of the PPD file in order +// of their appearance. Copyright text can span multiple lines and +// will be properly included in the PPD file with comment prefixes +// on each line. +// +// First an MIT-style copyright/license notice... +// + +Copyright "Copyright 2007 by Foo Industries." +Copyright " +Permission is granted for redistribution of this file as long as +this copyright notice is intact and the contents of the file are +not altered in any way from their original form. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the \"Software\"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +" + +// +// Then a GPL notice... +// + +Copyright "Copyright 2007 by Foo Industries." +Copyright " +This software 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 software 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 software; if not, write to the Free +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +MA 02111 USA +" + + +// +// All printer drivers must define the manufacturer, model, PC +// filename, and version strings; since this test file contains +// drivers for an imaginary manufacturer "Foo", all of the drivers +// listed in this file share common manufacturer and version +// strings. +// + +Manufacturer "Foo" +Version 1.0 + + +// +// Printer drivers can access driver-specific attributes in a PPD +// file; these attributes are specified using lines of the form: +// +// Attribute name selector value +// +// "Name" is the name of the attribute and should start with either +// the "cups" prefix or the name of the vendor, e.g. "hpFoo", +// "epsonBar", etc. The name can be any alphanumeric character (a-z, +// A-Z, and 0-9) and cannot be a common prefix of another attribute, +// e.g. "fooLines" and "fooLinesPerInch" cannot be in the same file. +// +// "Selector" is a selector string containing any characters except +// colon (:). Typically this will be one or more keywords separated +// by the forward slash (/), however the empty string ("") can be used +// to omit the selector. +// +// "Value" is a quoted value string that can contain any printable +// characters except the double quote ("). Hexadecimal numbers +// inside angle brackets () can be used to substitute escape +// codes and other special characters. +// + +Attribute fooOutputFormat "" "PCL" +Attribute fooPJL Begin "<1B>%-12345X@PJL<0D0A>" +Attribute fooPJL Enter/PCL "@PJL ENTER LANGUAGE=PCL<0D0A>" +Attribute fooPJL End "<1B>%-12345X@PJL END JOB<0D0A>" + +// +// Most printer drivers use filters; exceptions include PostScript +// printers and PPD files for software RIPs. +// +// The format is: +// +// Filter mime-type cost program +// +// The "mime-type" field defines the MIME type that the filter program +// accepts; for CUPS raster printer drivers, this will be +// "application/vnd.cups-raster". +// +// The "cost" field defines the relative cost of the filter in terms of +// both CPU and memory usage, and is used to limit the number of +// simultaneous jobs in some configurations. Most raster filters should +// have a cost of 100, unless the filter does no dithering - then a cost +// of 33 is more appropriate. +// +// The "program" field defined the filter program to run; use the null +// filter "-" to define a MIME type that the printer accepts directly. +// If no path information is provided, then the program will be run +// from the standard CUPS filter directory, usually +// /usr/lib/cups/filter. +// +// When compiling PPD files for PostScript capable devices that use +// additional filters, add a null filter for the MIME type +// "application/vnd.cups-postscript" so that printer commands, user +// job filters, and page markings can be added to the PostScript +// output that is sent to the printer. +// + +Filter application/vnd.cups-raster 100 rastertofoo + + +// +// Attributes are included thusly... +// + +Attribute cupsIPPReason "com.foo-serious-error/A Serious Error" "http://foo.com/serious.html" + + +// +// Curley braces are used for grouping common data and for isolating +// individual printer models. All data values are inherited *except* +// for the PCFilename and ModelName strings. +// + +{ + // + // Define two printer drivers that support only the FooLetter and + // FooPhoto media size. One is color, the other is black-and-white. + // + // Both printers share two MediaSize definitions; the name listed + // after the MediaSize keyword must be one of the Adobe standard + // names listed in the PPD specification or any named size defined + // using the #media directive. + // + // Default options are indicated by placing an asterisk (*) before + // the keyword. + // + // For custom size and margin specification, see the next group of + // printer drivers. + // + + MediaSize FooLetter + *MediaSize FooPhoto + + + // + // These imaginary printers support printing at 300, 600x300, + // and 600 DPI. We'll use the old-style Resolution convenience + // keyword which accepts the following parameters: colorspace/ + // order, bits-per-color, row count, row feed, row step, and + // name/text. + // + // The name must be of the form NNNsuffix or NNNxMMMsuffix, + // where NNN and MMM represent the X and Y resolution in dots + // per inch. + // + + Resolution - 8 0 0 0 "300dpi/300 DPI" + Resolution - 8 0 0 0 "600x300dpi/600 x 300 DPI" + *Resolution - 8 0 0 0 "600dpi/600 DPI" + + + // + // One printer is grayscale only, and the other does grayscale + // and color. Define the grayscale color model for both printers + // using the old-style ColorModel convenience keyword which + // accepts the name/text, colorspace, color order, and compression + // parameters. + // + + ColorModel Gray/Grayscale w chunked 0 + + + { + // + // The first sub-group contains the grayscale printer, which + // only needs the model name, PC filename, and model number + // values set... + // + // The ModelName keyword defines the string that is shown to + // the user. + // + + ModelName "Mono Photo Printer" + + + // + // The ModelNumber keyword defines the cupsModelNumber + // attribute value. We use the "(name name)" notation + // to perform a bitwise OR of the #define'd constants. + // + + ModelNumber ($MODEL_BW $MODEL_PHOTO) + + + // + // The PCFileName keyword defines the filename of the PPD + // file and should be 8 characters or less + the .ppd + // extension. + // + + PCFileName "foogphot.ppd" + } + + + { + // + // The second sub-group contains the color printer, which + // needs another ColorModel definition along with the model + // name, PC filename, and model number values. For fun, we'll + // add some input slots (paper trays) as well. + // + // The ModelName keyword defines the string that is shown to + // the user. + // + + ModelName "Color Photo Printer" + + + // + // The ModelNumber keyword defines the cupsModelNumber + // attribute value. We use the "(name name)" notation + // to perform a bitwise OR of the #define'd constants. + // + + ModelNumber ($MODEL_COLOR $MODEL_PHOTO) + + + // + // The PCFileName keyword defines the filename of the PPD + // file and should be 8 characters or less + the .ppd + // extension. + // + + PCFileName "foocphot.ppd" + + + // + // This printer does color printing, too, so add it and make + // RGB the default... + // + + ColorDevice Yes + + *ColorModel RGB/Color rgb chunked 0 + + + // + // The old-style InputSlot keyword accepts tray definitions + // of the form: + // + // InputSlot position name/text + // + + InputSlot 0 "Upper/Main Paper Tray" + InputSlot 1 "LargeCapacity/Large Paper Tray" + } +} + + +{ + // + // Define two printer drivers that support two typical laser + // printers with custom page sizes. One is color, the other is + // black-and-white. + // + // Both printers share several MediaSize definitions and support + // custom page sizes from 3x5 to 13x19 inches. + // + // All US media sizes use hardware margins of 0.25 inches on the sides + // and 12 points (1/6th inch) at the top and bottom. European sizes + // and custom sizes use margins of 12 points all around. + // + // The order of the HWMargins numbers are left, bottom, right, and top. + // The current HWMargins values are used when defining each media size. + // The last HWMargins values are used for custom page size margins. + // + + HWMargins 0.25in 12pt 0.25in 12pt + + *MediaSize Letter + MediaSize Legal + MediaSize Tabloid + MediaSize TabloidExtra + + HWMargins 12pt 12pt 12pt 12pt + MediaSize A4 + MediaSize A3 + + // + // Specify that custom/variable paper sizes are supported, and the + // range of sizes that are supported... + // + + VariablePaperSize Yes + MinSize 3in 5in + MaxSize 13in 19in + + + // + // These imaginary printers support printing at 600 and 1200 DPI. + // We'll use the new Option and Choice keywords to define the + // Resolution options... + // + // Option option-name option-text option-type + // Choice choice-name choice-text code + // + // "Option-type" is the type of option: boolean, pickone, or pickmany. + // + + Option Resolution PickOne AnySetup 10 + Choice "600dpi/600 DPI" "<>setpagedevice" + Choice "1200dpi/1200 DPI" "<>setpagedevice" + + + // + // One printer is grayscale only, and the other does grayscale + // and color. Define the grayscale color model for both printers + // using the new Option and Choice keywords. + // + + Option "ColorModel/Color Mode" PickOne AnySetup 10 + Choice Gray/Grayscale "<>setpagedevice" + + + // + // Both printers provide two paper trays, which we'll define using + // the new Option and Choice keywords... + // + + Option "InputSlot/Input Slot" PickOne AnySetup 10 + Choice "Upper/Main Paper Tray" "<>setpagedevice" + Choice "LargeCapacity/Large Paper Tray" "<>setpagedevice" + + + // + // Both printers support duplexing... + // + // The Duplex keyword accepts values of "none" (no duplexing capability), + // "normal" (standard duplexing capability), and "flip" (auto-duplex that + // requires the back side to be flipped by the RIP...) + // + + Duplex normal + + + { + // + // The first sub-group contains the grayscale printer, which + // only needs the model name, PC filename, and model number + // values set... + // + // The ModelName keyword defines the string that is shown to + // the user. + // + + ModelName "Mono Laser Printer" + + + // + // The ModelNumber keyword defines the cupsModelNumber + // attribute value. We use the "(name name)" notation + // to perform a bitwise OR of the #define'd constants. + // + + ModelNumber ($MODEL_BW $MODEL_LASER) + + + // + // The PCFileName keyword defines the filename of the PPD + // file and should be 8 characters or less + the .ppd + // extension. + // + + PCFileName "fooglasr.ppd" + } + + + { + // + // The second sub-group contains the color printer, which + // needs another ColorModel definition along with the model + // name, PC filename, and model number values. + // + // The ModelName keyword defines the string that is shown to + // the user. + // + + ModelName "Color Laser Printer" + + + // + // The ModelNumber keyword defines the cupsModelNumber + // attribute value. We use the "(name name)" notation + // to perform a bitwise OR of the #define'd constants. + // + + ModelNumber ($MODEL_COLOR $MODEL_LASER) + + + // + // The PCFileName keyword defines the filename of the PPD + // file and should be 8 characters or less + the .ppd + // extension. + // + + PCFileName "fooclasr.ppd" + + + // + // This printer does color printing, too, so add it and make + // RGB the default... + // + + ColorDevice Yes + + Option "ColorModel/Color Mode" PickOne AnySetup 10 + *Choice RGB/Color "<>setpagedevice" + } +} + + +// +// End of "$Id$". +// diff --git a/ppdc/genstrings.cxx b/ppdc/genstrings.cxx new file mode 100644 index 0000000000..76b3e3f82b --- /dev/null +++ b/ppdc/genstrings.cxx @@ -0,0 +1,215 @@ +// +// "$Id$" +// +// GNU gettext message generator for the CUPS PPD Compiler. +// +// This program is used to generate a dummy source file containing all of +// the standard media and sample driver strings. The results are picked up +// by GNU gettext and placed in the CUPS message catalog. +// +// Copyright 2008-2010 by Apple Inc. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Usage: +// +// ./genstrings >sample.c +// +// Contents: +// +// main() - Main entry for the PPD compiler. +// add_ui_strings() - Add all UI strings from the driver. +// write_cstring() - Write a translation string as a valid C string to +// stdout. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include + + +// +// Local functions... +// + +static void add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog); +static void write_cstring(const char *s); + + +// +// 'main()' - Main entry for the PPD compiler. +// + +int // O - Exit status +main(void) +{ + ppdcSource *src; // PPD source file data + ppdcCatalog *catalog; // Catalog to hold all of the UI strings + + + // Make sure we are in the right place... + if (access("../data", 0) || access("sample.drv", 0)) + { + puts("You must run genstrings from the ppdc directory."); + return (1); + } + + // Load the sample drivers... + ppdcSource::add_include("../data"); + + src = new ppdcSource("sample.drv"); + catalog = new ppdcCatalog(NULL); + + catalog->add_message("ISOLatin1"); + catalog->add_message("English"); + + // Add the media size strings... + ppdcMediaSize *size; // Current media size + + for (size = (ppdcMediaSize *)src->sizes->first(); + size; + size = (ppdcMediaSize *)src->sizes->next()) + catalog->add_message(size->text->value); + + // Then collect all of the UI strings from the sample drivers... + ppdcDriver *d; // Current driver + + for (d = (ppdcDriver *)src->drivers->first(); + d; + d = (ppdcDriver *)src->drivers->next()) + add_ui_strings(d, catalog); + + // Finally, write all of the strings... + ppdcMessage *message; + + for (message = (ppdcMessage *)catalog->messages->first(); + message; + message = (ppdcMessage *)catalog->messages->next()) + write_cstring(message->id->value); + + src->release(); + catalog->release(); + + // Return with no errors. + return (0); +} + + +// +// 'add_ui_strings()' - Add all UI strings from the driver. +// + +static void +add_ui_strings(ppdcDriver *d, // I - Driver data + ppdcCatalog *catalog) // I - Message catalog +{ + // Add the make/model/language strings... + catalog->add_message(d->manufacturer->value); + catalog->add_message(d->model_name->value); + + // Add the group/option/choice strings... + ppdcGroup *g; // Current group + ppdcOption *o; // Current option + ppdcChoice *c; // Current choice + + for (g = (ppdcGroup *)d->groups->first(); + g; + g = (ppdcGroup *)d->groups->next()) + { + if (!g->options->count) + continue; + + if (strcasecmp(g->name->value, "General")) + catalog->add_message(g->text->value); + + for (o = (ppdcOption *)g->options->first(); + o; + o = (ppdcOption *)g->options->next()) + { + if (!o->choices->count) + continue; + + if (o->text->value && strcmp(o->name->value, o->text->value)) + catalog->add_message(o->text->value); + else + catalog->add_message(o->name->value); + + for (c = (ppdcChoice *)o->choices->first(); + c; + c = (ppdcChoice *)o->choices->next()) + if (c->text->value && strcmp(c->name->value, c->text->value)) + catalog->add_message(c->text->value); + else + catalog->add_message(c->name->value); + } + } + + // Add profile and preset strings... + ppdcAttr *a; // Current attribute + for (a = (ppdcAttr *)d->attrs->first(); + a; + a = (ppdcAttr *)d->attrs->next()) + { + if (a->text->value && a->text->value[0] && + (a->localizable || + !strncmp(a->name->value, "Custom", 6) || + !strncmp(a->name->value, "ParamCustom", 11) || + !strcmp(a->name->value, "APCustomColorMatchingName") || + !strcmp(a->name->value, "APPrinterPreset") || + !strcmp(a->name->value, "cupsICCProfile") || + !strcmp(a->name->value, "cupsIPPReason") || + !strcmp(a->name->value, "cupsMarkerName"))) + { + catalog->add_message(a->text->value); + + if ((a->localizable && a->value->value[0]) || + !strcmp(a->name->value, "cupsIPPReason")) + catalog->add_message(a->value->value); + } + else if (!strncmp(a->name->value, "Custom", 6) || + !strncmp(a->name->value, "ParamCustom", 11)) + catalog->add_message(a->name->value); + } +} + + +// +// 'write_cstring()' - Write a translation string as a valid C string to stdout. +// + +static void +write_cstring(const char *s) /* I - String to write */ +{ + fputs("_(\"", stdout); + if (s) + { + while (*s) + { + if (*s == '\\') + fputs("\\\\", stdout); + else if (*s == '\"') + fputs("\\\"", stdout); + else if (*s == '\t') + fputs("\\t", stdout); + else if (*s == '\n') + fputs("\\n", stdout); + else + putchar(*s); + + s ++; + } + } + puts("\");"); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-array.cxx b/ppdc/ppdc-array.cxx new file mode 100644 index 0000000000..33d8bf7736 --- /dev/null +++ b/ppdc/ppdc-array.cxx @@ -0,0 +1,168 @@ +// +// "$Id$" +// +// Array class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcArray::ppdcArray() - Create a new array. +// ppdcArray::~ppdcArray() - Destroy an array. +// ppdcArray::add() - Add an element to an array. +// ppdcArray::first() - Return the first element in the array. +// ppdcArray::next() - Return the next element in the array. +// ppdcArray::remove() - Remove an element from the array. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcArray::ppdcArray()' - Create a new array. +// + +ppdcArray::ppdcArray(ppdcArray *a) + : ppdcShared() +{ + PPDC_NEW; + + if (a) + { + count = a->count; + alloc = count; + + if (count) + { + // Make a copy of the array... + data = new ppdcShared *[count]; + + memcpy(data, a->data, count * sizeof(ppdcShared *)); + + for (int i = 0; i < count; i ++) + data[i]->retain(); + } + else + data = 0; + } + else + { + count = 0; + alloc = 0; + data = 0; + } + + current = 0; +} + + +// +// 'ppdcArray::~ppdcArray()' - Destroy an array. +// + +ppdcArray::~ppdcArray() +{ + PPDC_DELETE; + + for (int i = 0; i < count; i ++) + data[i]->release(); + + if (alloc) + delete[] data; +} + + +// +// 'ppdcArray::add()' - Add an element to an array. +// + +void +ppdcArray::add(ppdcShared *d) +{ + ppdcShared **temp; + + + if (count >= alloc) + { + alloc += 10; + temp = new ppdcShared *[alloc]; + + memcpy(temp, data, count * sizeof(ppdcShared *)); + + delete[] data; + data = temp; + } + + data[count++] = d; +} + + +// +// 'ppdcArray::first()' - Return the first element in the array. +// + +ppdcShared * +ppdcArray::first() +{ + current = 0; + + if (current >= count) + return (0); + else + return (data[current ++]); +} + + +// +// 'ppdcArray::next()' - Return the next element in the array. +// + +ppdcShared * +ppdcArray::next() +{ + if (current >= count) + return (0); + else + return (data[current ++]); +} + + +// +// 'ppdcArray::remove()' - Remove an element from the array. +// + +void +ppdcArray::remove(ppdcShared *d) // I - Data element +{ + int i; // Looping var + + + for (i = 0; i < count; i ++) + if (d == data[i]) + break; + + if (i >= count) + return; + + count --; + d->release(); + + if (i < count) + memmove(data + i, data + i + 1, (count - i) * sizeof(ppdcShared *)); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-attr.cxx b/ppdc/ppdc-attr.cxx new file mode 100644 index 0000000000..1ea0337a93 --- /dev/null +++ b/ppdc/ppdc-attr.cxx @@ -0,0 +1,66 @@ +// +// "$Id$" +// +// Attribute class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcAttr::ppdcAttr() - Create an attribute. +// ppdcAttr::~ppdcAttr() - Destroy an attribute. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcAttr::ppdcAttr()' - Create an attribute. +// + +ppdcAttr::ppdcAttr(const char *n, // I - Name + const char *s, // I - Spec string + const char *t, // I - Human-readable text + const char *v, // I - Value + bool loc) // I - Localize this attribute? + : ppdcShared() +{ + PPDC_NEW; + + name = new ppdcString(n); + selector = new ppdcString(s); + text = new ppdcString(t); + value = new ppdcString(v); + localizable = loc; +} + + +// +// 'ppdcAttr::~ppdcAttr()' - Destroy an attribute. +// + +ppdcAttr::~ppdcAttr() +{ + PPDC_DELETE; + + name->release(); + selector->release(); + text->release(); + value->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-catalog.cxx b/ppdc/ppdc-catalog.cxx new file mode 100644 index 0000000000..37b5305cf9 --- /dev/null +++ b/ppdc/ppdc-catalog.cxx @@ -0,0 +1,897 @@ +// +// "$Id$" +// +// Shared message catalog class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2006 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcCatalog::ppdcCatalog() - Create a shared message catalog. +// ppdcCatalog::~ppdcCatalog() - Destroy a shared message catalog. +// ppdcCatalog::add_message() - Add a new message. +// ppdcCatalog::find_message() - Find a message in a catalog... +// ppdcCatalog::load_messages() - Load messages from a .po file. +// ppdcCatalog::save_messages() - Save the messages to a .po file. +// get_utf8() - Get a UTF-8 character. +// get_utf16() - Get a UTF-16 character... +// put_utf8() - Add a UTF-8 character to a string. +// put_utf16() - Write a UTF-16 character to a file. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// Character encodings... +// + +typedef enum +{ + PPDC_CS_AUTO, + PPDC_CS_UTF8, + PPDC_CS_UTF16BE, + PPDC_CS_UTF16LE +} ppdc_cs_t; + + +// +// Local functions... +// + +static int get_utf8(char *&ptr); +static int get_utf16(cups_file_t *fp, ppdc_cs_t &cs); +static int put_utf8(int ch, char *&ptr, char *end); +static int put_utf16(cups_file_t *fp, int ch); + + +// +// 'ppdcCatalog::ppdcCatalog()' - Create a shared message catalog. +// + +ppdcCatalog::ppdcCatalog(const char *l, // I - Locale + const char *f) // I - Message catalog file + : ppdcShared() +{ + _cups_globals_t *cg = _cupsGlobals(); + // Global information + + + PPDC_NEW; + + locale = new ppdcString(l); + filename = new ppdcString(f); + messages = new ppdcArray(); + + if (l) + { + // Try loading the base messages for this locale... + char pofile[1024]; // Message catalog file + + + snprintf(pofile, sizeof(pofile), "%s/%s/cups_%s.po", cg->localedir, l, l); + + if (load_messages(pofile) && strchr(l, '_')) + { + // Try the base locale... + char baseloc[3]; // Base locale... + + + strlcpy(baseloc, l, sizeof(baseloc)); + snprintf(pofile, sizeof(pofile), "%s/%s/cups_%s.po", cg->localedir, + baseloc, baseloc); + + load_messages(pofile); + } + } + + if (f) + load_messages(f); +} + + +// +// 'ppdcCatalog::~ppdcCatalog()' - Destroy a shared message catalog. +// + +ppdcCatalog::~ppdcCatalog() +{ + PPDC_DELETE; + + locale->release(); + filename->release(); + messages->release(); +} + + +// +// 'ppdcCatalog::add_message()' - Add a new message. +// + +void +ppdcCatalog::add_message( + const char *id, // I - Message ID to add + const char *string) // I - Translation string +{ + ppdcMessage *m; // Current message + char text[1024]; // Text to translate + + + // Range check input... + if (!id) + return; + + // Verify that we don't already have the message ID... + for (m = (ppdcMessage *)messages->first(); + m; + m = (ppdcMessage *)messages->next()) + if (!strcmp(m->id->value, id)) + { + if (string) + { + m->string->release(); + m->string = new ppdcString(string); + } + return; + } + + // Add the message... + if (!string) + { + snprintf(text, sizeof(text), "TRANSLATE %s", id); + string = text; + } + + messages->add(new ppdcMessage(id, string)); +} + + +// +// 'ppdcCatalog::find_message()' - Find a message in a catalog... +// + +const char * // O - Message text +ppdcCatalog::find_message( + const char *id) // I - Message ID +{ + ppdcMessage *m; // Current message + + + if (!*id) + return (id); + + for (m = (ppdcMessage *)messages->first(); + m; + m = (ppdcMessage *)messages->next()) + if (!strcmp(m->id->value, id)) + return (m->string->value); + + return (id); +} + + +// +// 'ppdcCatalog::load_messages()' - Load messages from a .po file. +// + +int // O - 0 on success, -1 on failure +ppdcCatalog::load_messages( + const char *f) // I - Message catalog file +{ + cups_file_t *fp; // Message file + char line[4096], // Line buffer + *ptr, // Pointer into buffer + id[4096], // Translation ID + str[4096]; // Translation string + int linenum; // Line number + + + // Open the message catalog file... + if ((fp = cupsFileOpen(f, "r")) == NULL) + return (-1); + + if ((ptr = (char *)strrchr(f, '.')) == NULL) + goto unknown_load_format; + else if (!strcmp(ptr, ".strings")) + { + /* + * Read messages in Mac OS X ".strings" format, which are UTF-16 text + * files of the format: + * + * "id" = "str"; + * + * Strings files can also contain C-style comments. + */ + + ppdc_cs_t cs = PPDC_CS_AUTO; // Character set for file + int ch; // Current character from file + char *end; // End of buffer + + + id[0] = '\0'; + str[0] = '\0'; + ptr = NULL; + end = NULL; + + while ((ch = get_utf16(fp, cs)) != 0) + { + if (ptr) + { + if (ch == '\\') + { + if ((ch = get_utf16(fp, cs)) == 0) + break; + + if (ch == 'n') + ch = '\n'; + else if (ch == 't') + ch = '\t'; + } + else if (ch == '\"') + { + *ptr = '\0'; + ptr = NULL; + } + + if (ptr) + put_utf8(ch, ptr, end); + } + else if (ch == '/') + { + // Start of a comment? + if ((ch = get_utf16(fp, cs)) == 0) + break; + + if (ch == '*') + { + // Skip C comment... + int lastch = 0; + + while ((ch = get_utf16(fp, cs)) != 0) + { + if (ch == '/' && lastch == '*') + break; + + lastch = ch; + } + } + else if (ch == '/') + { + // Skip C++ comment... + while ((ch = get_utf16(fp, cs)) != 0) + if (ch == '\n') + break; + } + } + else if (ch == '\"') + { + // Start quoted string... + if (id[0]) + { + ptr = str; + end = str + sizeof(str) - 1; + } + else + { + ptr = id; + end = id + sizeof(id) - 1; + } + } + else if (ch == ';') + { + // Add string... + add_message(id, str); + id[0] = '\0'; + } + } + } + else if (!strcmp(ptr, ".po") || !strcmp(ptr, ".gz")) + { + /* + * Read messages from the catalog file until EOF... + * + * The format is the GNU gettext .po format, which is fairly simple: + * + * msgid "some text" + * msgstr "localized text" + * + * The ID and localized text can span multiple lines using the form: + * + * msgid "" + * "some long text" + * msgstr "" + * "localized text spanning " + * "multiple lines" + */ + + int which, // In msgid? + haveid, // Did we get a msgid string? + havestr; // Did we get a msgstr string? + + linenum = 0; + id[0] = '\0'; + str[0] = '\0'; + haveid = 0; + havestr = 0; + which = 0; + + while (cupsFileGets(fp, line, sizeof(line))) + { + linenum ++; + + // Skip blank and comment lines... + if (line[0] == '#' || !line[0]) + continue; + + // Strip the trailing quote... + if ((ptr = (char *)strrchr(line, '\"')) == NULL) + { + _cupsLangPrintf(stderr, + _("ERROR: Expected quoted string on line %d of %s!\n"), + linenum, f); + cupsFileClose(fp); + return (-1); + } + + *ptr = '\0'; + + // Find start of value... + if ((ptr = strchr(line, '\"')) == NULL) + { + _cupsLangPrintf(stderr, + _("ERROR: Expected quoted string on line %d of %s!\n"), + linenum, f); + cupsFileClose(fp); + return (-1); + } + + ptr ++; + + // Unquote the text... + char *sptr, *dptr; // Source/destination pointers + + for (sptr = ptr, dptr = ptr; *sptr;) + { + if (*sptr == '\\') + { + sptr ++; + if (isdigit(*sptr)) + { + *dptr = 0; + + while (isdigit(*sptr)) + { + *dptr = *dptr * 8 + *sptr - '0'; + sptr ++; + } + + dptr ++; + } + else + { + if (*sptr == 'n') + *dptr++ = '\n'; + else if (*sptr == 'r') + *dptr++ = '\r'; + else if (*sptr == 't') + *dptr++ = '\t'; + else + *dptr++ = *sptr; + + sptr ++; + } + } + else + *dptr++ = *sptr++; + } + + *dptr = '\0'; + + // Create or add to a message... + if (!strncmp(line, "msgid", 5)) + { + if (haveid && havestr) + add_message(id, str); + + strlcpy(id, ptr, sizeof(id)); + str[0] = '\0'; + haveid = 1; + havestr = 0; + which = 1; + } + else if (!strncmp(line, "msgstr", 6)) + { + if (!haveid) + { + _cupsLangPrintf(stderr, + _("ERROR: Need a msgid line before any " + "translation strings on line %d of %s!\n"), + linenum, f); + cupsFileClose(fp); + return (-1); + } + + strlcpy(str, ptr, sizeof(str)); + havestr = 1; + which = 2; + } + else if (line[0] == '\"' && which == 2) + strlcat(str, ptr, sizeof(str)); + else if (line[0] == '\"' && which == 1) + strlcat(id, ptr, sizeof(id)); + else + { + _cupsLangPrintf(stderr, _("ERROR: Unexpected text on line %d of %s!\n"), + linenum, f); + cupsFileClose(fp); + return (-1); + } + } + + if (haveid && havestr) + add_message(id, str); + } + else + goto unknown_load_format; + + /* + * Close the file and return... + */ + + cupsFileClose(fp); + + return (0); + + /* + * Unknown format error... + */ + + unknown_load_format: + + _cupsLangPrintf(stderr, + _("ERROR: Unknown message catalog format for \"%s\"!\n"), f); + cupsFileClose(fp); + return (-1); +} + + +// +// 'ppdcCatalog::save_messages()' - Save the messages to a .po file. +// + +int // O - 0 on success, -1 on error +ppdcCatalog::save_messages( + const char *f) // I - File to save to +{ + cups_file_t *fp; // Message file + ppdcMessage *m; // Current message + char *ptr; // Pointer into string + int utf16; // Output UTF-16 .strings file? + int ch; // Current character + + + // Open the file... + if ((ptr = (char *)strrchr(f, '.')) == NULL) + return (-1); + + if (!strcmp(ptr, ".gz")) + fp = cupsFileOpen(f, "w9"); + else + fp = cupsFileOpen(f, "w"); + + if (!fp) + return (-1); + + // For .strings files, write a BOM for big-endian output... + utf16 = !strcmp(ptr, ".strings"); + + if (utf16) + put_utf16(fp, 0xfeff); + + // Loop through all of the messages... + for (m = (ppdcMessage *)messages->first(); + m; + m = (ppdcMessage *)messages->next()) + { + if (utf16) + { + put_utf16(fp, '\"'); + + ptr = m->id->value; + while ((ch = get_utf8(ptr)) != 0) + switch (ch) + { + case '\n' : + put_utf16(fp, '\\'); + put_utf16(fp, 'n'); + break; + case '\\' : + put_utf16(fp, '\\'); + put_utf16(fp, '\\'); + break; + case '\"' : + put_utf16(fp, '\\'); + put_utf16(fp, '\"'); + break; + default : + put_utf16(fp, ch); + break; + } + + put_utf16(fp, '\"'); + put_utf16(fp, ' '); + put_utf16(fp, '='); + put_utf16(fp, ' '); + put_utf16(fp, '\"'); + + ptr = m->string->value; + while ((ch = get_utf8(ptr)) != 0) + switch (ch) + { + case '\n' : + put_utf16(fp, '\\'); + put_utf16(fp, 'n'); + break; + case '\\' : + put_utf16(fp, '\\'); + put_utf16(fp, '\\'); + break; + case '\"' : + put_utf16(fp, '\\'); + put_utf16(fp, '\"'); + break; + default : + put_utf16(fp, ch); + break; + } + + put_utf16(fp, '\"'); + put_utf16(fp, ';'); + put_utf16(fp, '\n'); + } + else + { + cupsFilePuts(fp, "msgid \""); + for (ptr = m->id->value; *ptr; ptr ++) + switch (*ptr) + { + case '\n' : + cupsFilePuts(fp, "\\n"); + break; + case '\\' : + cupsFilePuts(fp, "\\\\"); + break; + case '\"' : + cupsFilePuts(fp, "\\\""); + break; + default : + cupsFilePutChar(fp, *ptr); + break; + } + cupsFilePuts(fp, "\"\n"); + + cupsFilePuts(fp, "msgstr \""); + for (ptr = m->string->value; *ptr; ptr ++) + switch (*ptr) + { + case '\n' : + cupsFilePuts(fp, "\\n"); + break; + case '\\' : + cupsFilePuts(fp, "\\\\"); + break; + case '\"' : + cupsFilePuts(fp, "\\\""); + break; + default : + cupsFilePutChar(fp, *ptr); + break; + } + cupsFilePuts(fp, "\"\n"); + + cupsFilePutChar(fp, '\n'); + } + } + + cupsFileClose(fp); + + return (0); +} + + +// +// 'get_utf8()' - Get a UTF-8 character. +// + +static int // O - Unicode character or 0 on EOF +get_utf8(char *&ptr) // IO - Pointer to character +{ + int ch; // Current character + + + if ((ch = *ptr++ & 255) < 0xc0) + return (ch); + + if ((ch & 0xe0) == 0xc0) + { + // Two-byte UTF-8... + if ((*ptr & 0xc0) != 0x80) + return (0); + + ch = ((ch & 0x1f) << 6) | (*ptr++ & 0x3f); + } + else if ((ch & 0xf0) == 0xe0) + { + // Three-byte UTF-8... + if ((*ptr & 0xc0) != 0x80) + return (0); + + ch = ((ch & 0x0f) << 6) | (*ptr++ & 0x3f); + + if ((*ptr & 0xc0) != 0x80) + return (0); + + ch = (ch << 6) | (*ptr++ & 0x3f); + } + else if ((ch & 0xf8) == 0xf0) + { + // Four-byte UTF-8... + if ((*ptr & 0xc0) != 0x80) + return (0); + + ch = ((ch & 0x07) << 6) | (*ptr++ & 0x3f); + + if ((*ptr & 0xc0) != 0x80) + return (0); + + ch = (ch << 6) | (*ptr++ & 0x3f); + + if ((*ptr & 0xc0) != 0x80) + return (0); + + ch = (ch << 6) | (*ptr++ & 0x3f); + } + + return (ch); +} + + +// +// 'get_utf16()' - Get a UTF-16 character... +// + +static int // O - Unicode character or 0 on EOF +get_utf16(cups_file_t *fp, // I - File to read from + ppdc_cs_t &cs) // IO - Character set of file +{ + int ch; // Current character + unsigned char buffer[3]; // Bytes + + + if (cs == PPDC_CS_AUTO) + { + // Get byte-order-mark, if present... + if (cupsFileRead(fp, (char *)buffer, 2) != 2) + return (0); + + if (buffer[0] == 0xfe && buffer[1] == 0xff) + { + // Big-endian UTF-16... + cs = PPDC_CS_UTF16BE; + + if (cupsFileRead(fp, (char *)buffer, 2) != 2) + return (0); + } + else if (buffer[0] == 0xff && buffer[1] == 0xfe) + { + // Little-endian UTF-16... + cs = PPDC_CS_UTF16LE; + + if (cupsFileRead(fp, (char *)buffer, 2) != 2) + return (0); + } + else if (buffer[0] == 0x00 && buffer[1] != 0x00) + { + // No BOM, assume big-endian UTF-16... + cs = PPDC_CS_UTF16BE; + } + else if (buffer[0] != 0x00 && buffer[1] == 0x00) + { + // No BOM, assume little-endian UTF-16... + cs = PPDC_CS_UTF16LE; + } + else + { + // No BOM, assume UTF-8... + cs = PPDC_CS_UTF8; + + cupsFileRewind(fp); + } + } + else if (cs != PPDC_CS_UTF8) + { + if (cupsFileRead(fp, (char *)buffer, 2) != 2) + return (0); + } + + if (cs == PPDC_CS_UTF8) + { + // UTF-8 character... + if ((ch = cupsFileGetChar(fp)) < 0) + return (0); + + if ((ch & 0xe0) == 0xc0) + { + // Two-byte UTF-8... + if (cupsFileRead(fp, (char *)buffer, 1) != 1) + return (0); + + if ((buffer[0] & 0xc0) != 0x80) + return (0); + + ch = ((ch & 0x1f) << 6) | (buffer[0] & 0x3f); + } + else if ((ch & 0xf0) == 0xe0) + { + // Three-byte UTF-8... + if (cupsFileRead(fp, (char *)buffer, 2) != 2) + return (0); + + if ((buffer[0] & 0xc0) != 0x80 || + (buffer[1] & 0xc0) != 0x80) + return (0); + + ch = ((((ch & 0x0f) << 6) | (buffer[0] & 0x3f)) << 6) | + (buffer[1] & 0x3f); + } + else if ((ch & 0xf8) == 0xf0) + { + // Four-byte UTF-8... + if (cupsFileRead(fp, (char *)buffer, 3) != 3) + return (0); + + if ((buffer[0] & 0xc0) != 0x80 || + (buffer[1] & 0xc0) != 0x80 || + (buffer[2] & 0xc0) != 0x80) + return (0); + + ch = ((((((ch & 0x07) << 6) | (buffer[0] & 0x3f)) << 6) | + (buffer[1] & 0x3f)) << 6) | (buffer[2] & 0x3f); + } + } + else + { + // UTF-16 character... + if (cs == PPDC_CS_UTF16BE) + ch = (buffer[0] << 8) | buffer[1]; + else + ch = (buffer[1] << 8) | buffer[0]; + + if (ch >= 0xd800 && ch <= 0xdbff) + { + // Handle multi-word encoding... + int lch; + + if (cupsFileRead(fp, (char *)buffer, 2) != 2) + return (0); + + if (cs == PPDC_CS_UTF16BE) + lch = (buffer[0] << 8) | buffer[1]; + else + lch = (buffer[1] << 8) | buffer[0]; + + if (lch < 0xdc00 || lch >= 0xdfff) + return (0); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + } + + return (ch); +} + + +// +// 'put_utf8()' - Add a UTF-8 character to a string. +// + +static int // O - 0 on success, -1 on failure +put_utf8(int ch, // I - Unicode character + char *&ptr, // IO - String pointer + char *end) // I - End of buffer +{ + if (ch < 0x80) + { + // One-byte ASCII... + if (ptr >= end) + return (-1); + + *ptr++ = ch; + } + else if (ch < 0x800) + { + // Two-byte UTF-8... + if ((ptr + 1) >= end) + return (-1); + + *ptr++ = 0xc0 | (ch >> 6); + *ptr++ = 0x80 | (ch & 0x3f); + } + else if (ch < 0x10000) + { + // Three-byte UTF-8... + if ((ptr + 2) >= end) + return (-1); + + *ptr++ = 0xe0 | (ch >> 12); + *ptr++ = 0x80 | ((ch >> 6) & 0x3f); + *ptr++ = 0x80 | (ch & 0x3f); + } + else + { + // Four-byte UTF-8... + if ((ptr + 3) >= end) + return (-1); + + *ptr++ = 0xf0 | (ch >> 18); + *ptr++ = 0x80 | ((ch >> 12) & 0x3f); + *ptr++ = 0x80 | ((ch >> 6) & 0x3f); + *ptr++ = 0x80 | (ch & 0x3f); + } + + return (0); +} + + +// +// 'put_utf16()' - Write a UTF-16 character to a file. +// + +static int // O - 0 on success, -1 on failure +put_utf16(cups_file_t *fp, // I - File to write to + int ch) // I - Unicode character +{ + unsigned char buffer[4]; // Output buffer + + + if (ch < 0x10000) + { + // One-word UTF-16 big-endian... + buffer[0] = ch >> 8; + buffer[1] = ch; + + if (cupsFileWrite(fp, (char *)buffer, 2) == 2) + return (0); + } + else + { + // Two-word UTF-16 big-endian... + ch -= 0x10000; + + buffer[0] = 0xd8 | (ch >> 18); + buffer[1] = ch >> 10; + buffer[2] = 0xdc | ((ch >> 8) & 0x03); + buffer[3] = ch; + + if (cupsFileWrite(fp, (char *)buffer, 4) == 4) + return (0); + } + + return (-1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-choice.cxx b/ppdc/ppdc-choice.cxx new file mode 100644 index 0000000000..2c12de2b9c --- /dev/null +++ b/ppdc/ppdc-choice.cxx @@ -0,0 +1,61 @@ +// +// "$Id$" +// +// Option choice class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcChoice::ppdcChoice() - Create a new option choice. +// ppdcChoice::~ppdcChoice() - Destroy an option choice. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcChoice::ppdcChoice()' - Create a new option choice. +// + +ppdcChoice::ppdcChoice(const char *n, // I - Name of choice + const char *t, // I - Text of choice + const char *c) // I - Code of choice + : ppdcShared() +{ + PPDC_NEW; + + name = new ppdcString(n); + text = new ppdcString(t); + code = new ppdcString(c); +} + + +// +// 'ppdcChoice::~ppdcChoice()' - Destroy an option choice. +// + +ppdcChoice::~ppdcChoice() +{ + PPDC_DELETE; + + name->release(); + text->release(); + code->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-constraint.cxx b/ppdc/ppdc-constraint.cxx new file mode 100644 index 0000000000..6e6f0241e7 --- /dev/null +++ b/ppdc/ppdc-constraint.cxx @@ -0,0 +1,64 @@ +// +// "$Id$" +// +// Contraint class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcConstraint::ppdcConstraint() - Create a constraint. +// ppdcConstraint::~ppdcConstraint() - Destroy a constraint. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcConstraint::ppdcConstraint()' - Create a constraint. +// + +ppdcConstraint::ppdcConstraint(const char *o1, // I - First option + const char *c1, // I - First choice + const char *o2, // I - Second option + const char *c2) // I - Second choice + : ppdcShared() +{ + PPDC_NEW; + + option1 = new ppdcString(o1); + choice1 = new ppdcString(c1); + option2 = new ppdcString(o2); + choice2 = new ppdcString(c2); +} + + +// +// 'ppdcConstraint::~ppdcConstraint()' - Destroy a constraint. +// + +ppdcConstraint::~ppdcConstraint() +{ + PPDC_DELETE; + + option1->release(); + choice1->release(); + option2->release(); + choice2->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-driver.cxx b/ppdc/ppdc-driver.cxx new file mode 100644 index 0000000000..c2b8fe845a --- /dev/null +++ b/ppdc/ppdc-driver.cxx @@ -0,0 +1,1340 @@ +// +// "$Id$" +// +// PPD file compiler definitions for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2006 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcDriver::ppdcDriver() - Create a new printer driver. +// ppdcDriver::~ppdcDriver() - Destroy a printer driver. +// ppdcDriver::find_attr() - Find an attribute. +// ppdcDriver::find_group() - Find a group. +// ppdcDriver::find_option() - Find an option. +// ppdcDriver::find_option_group() - Find an option and its group. +// ppdcDriver::set_custom_size_code() - Set the custom page size code. +// ppdcDriver::set_default_font() - Set the default font name. +// ppdcDriver::set_default_size() - Set the default size name. +// ppdcDriver::set_file_name() - Set the full filename. +// ppdcDriver::set_manufacturer() - Set the manufacturer name. +// ppdcDriver::set_model_name() - Set the model name. +// ppdcDriver::set_pc_file_name() - Set the PC filename. +// ppdcDriver::set_version() - Set the version string. +// ppdcDriver::write_ppd_file() - Write a PPD file... +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include + + +// +// 'ppdcDriver::ppdcDriver()' - Create a new printer driver. +// + +ppdcDriver::ppdcDriver(ppdcDriver *d) // I - Printer driver template + : ppdcShared() +{ + ppdcGroup *g; // Current group + + + PPDC_NEW; + + if (d) + { + // Bump the use count of any strings we inherit... + if (d->manufacturer) + d->manufacturer->retain(); + if (d->version) + d->version->retain(); + if (d->default_font) + d->default_font->retain(); + if (d->default_size) + d->default_size->retain(); + if (d->custom_size_code) + d->custom_size_code->retain(); + + // Copy all of the data from the driver template... + copyright = new ppdcArray(d->copyright); + manufacturer = d->manufacturer; + model_name = 0; + file_name = 0; + pc_file_name = 0; + type = d->type; + version = d->version; + model_number = d->model_number; + manual_copies = d->manual_copies; + color_device = d->color_device; + throughput = d->throughput; + attrs = new ppdcArray(d->attrs); + constraints = new ppdcArray(d->constraints); + filters = new ppdcArray(d->filters); + fonts = new ppdcArray(d->fonts); + profiles = new ppdcArray(d->profiles); + sizes = new ppdcArray(d->sizes); + default_font = d->default_font; + default_size = d->default_size; + variable_paper_size = d->variable_paper_size; + custom_size_code = d->custom_size_code; + left_margin = d->left_margin; + bottom_margin = d->bottom_margin; + right_margin = d->right_margin; + top_margin = d->top_margin; + max_width = d->max_width; + max_length = d->max_length; + min_width = d->min_width; + min_length = d->min_length; + + // Then copy the groups manually, since we want separate copies + // of the groups and options... + groups = new ppdcArray(); + + for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next()) + groups->add(new ppdcGroup(g)); + } + else + { + // Zero all of the data in the driver... + copyright = new ppdcArray(); + manufacturer = 0; + model_name = 0; + file_name = 0; + pc_file_name = 0; + version = 0; + type = PPDC_DRIVER_CUSTOM; + model_number = 0; + manual_copies = 0; + color_device = 0; + throughput = 1; + attrs = new ppdcArray(); + constraints = new ppdcArray(); + fonts = new ppdcArray(); + filters = new ppdcArray(); + groups = new ppdcArray(); + profiles = new ppdcArray(); + sizes = new ppdcArray(); + default_font = 0; + default_size = 0; + variable_paper_size = 0; + custom_size_code = 0; + left_margin = 0; + bottom_margin = 0; + right_margin = 0; + top_margin = 0; + max_width = 0; + max_length = 0; + min_width = 0; + min_length = 0; + } +} + + +// +// 'ppdcDriver::~ppdcDriver()' - Destroy a printer driver. +// + +ppdcDriver::~ppdcDriver() +{ + PPDC_DELETE; + + copyright->release(); + + if (manufacturer) + manufacturer->release(); + if (model_name) + model_name->release(); + if (file_name) + file_name->release(); + if (pc_file_name) + pc_file_name->release(); + if (version) + version->release(); + if (default_font) + default_font->release(); + if (default_size) + default_size->release(); + if (custom_size_code) + custom_size_code->release(); + + attrs->release(); + constraints->release(); + filters->release(); + fonts->release(); + groups->release(); + profiles->release(); + sizes->release(); +} + + +// +// 'ppdcDriver::find_attr()' - Find an attribute. +// + +ppdcAttr * // O - Attribute or NULL +ppdcDriver::find_attr(const char *k, // I - Keyword string + const char *s) // I - Spec string +{ + ppdcAttr *a; // Current attribute + + + for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next()) + if (!strcmp(a->name->value, k) && + ((!s && (!a->selector->value || !a->selector->value[0])) || + (s && a->selector->value && !strcmp(a->selector->value, s)))) + return (a); + + return (NULL); +} + + +// +// 'ppdcDriver::find_group()' - Find a group. +// + +ppdcGroup * // O - Matching group or NULL +ppdcDriver::find_group(const char *n) // I - Group name +{ + ppdcGroup *g; // Current group + + + for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next()) + if (!strcasecmp(n, g->name->value)) + return (g); + + return (0); +} + + +// +// 'ppdcDriver::find_option()' - Find an option. +// + +ppdcOption * // O - Matching option or NULL +ppdcDriver::find_option(const char *n) // I - Option name +{ + return (find_option_group(n, (ppdcGroup **)0)); +} + + +// +// 'ppdcDriver::find_option_group()' - Find an option and its group. +// + +ppdcOption * // O - Matching option or NULL +ppdcDriver::find_option_group( + const char *n, // I - Option name + ppdcGroup **mg) // O - Matching group or NULL +{ + ppdcGroup *g; // Current group + ppdcOption *o; // Current option + + + for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next()) + for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next()) + if (!strcasecmp(n, o->name->value)) + { + if (mg) + *mg = g; + + return (o); + } + + if (mg) + *mg = (ppdcGroup *)0; + + return (0); +} + + +// +// 'ppdcDriver::set_custom_size_code()' - Set the custom page size code. +// + +void +ppdcDriver::set_custom_size_code( + const char *c) // I - CustomPageSize code +{ + if (custom_size_code) + custom_size_code->release(); + + custom_size_code = new ppdcString(c); +} + + +// +// 'ppdcDriver::set_default_font()' - Set the default font name. +// + +void +ppdcDriver::set_default_font( + ppdcFont *f) // I - Font +{ + if (default_font) + default_font->release(); + + if (f) + { + f->name->retain(); + default_font = f->name; + } + else + default_font = 0; +} + + +// +// 'ppdcDriver::set_default_size()' - Set the default size name. +// + +void +ppdcDriver::set_default_size( + ppdcMediaSize *m) // I - Media size +{ + if (default_size) + default_size->release(); + + if (m) + { + m->name->retain(); + default_size = m->name; + } + else + default_size = 0; +} + + +// +// 'ppdcDriver::set_file_name()' - Set the full filename. +// + +void +ppdcDriver::set_file_name(const char *f)// I - Filename +{ + if (file_name) + file_name->release(); + + file_name = new ppdcString(f); +} + + +// +// 'ppdcDriver::set_manufacturer()' - Set the manufacturer name. +// + +void +ppdcDriver::set_manufacturer( + const char *m) // I - Model name +{ + if (manufacturer) + manufacturer->release(); + + manufacturer = new ppdcString(m); +} + + +// +// 'ppdcDriver::set_model_name()' - Set the model name. +// + +void +ppdcDriver::set_model_name( + const char *m) // I - Model name +{ + if (model_name) + model_name->release(); + + model_name = new ppdcString(m); +} + + +// +// 'ppdcDriver::set_pc_file_name()' - Set the PC filename. +// + +void +ppdcDriver::set_pc_file_name( + const char *f) // I - Filename +{ + if (pc_file_name) + pc_file_name->release(); + + pc_file_name = new ppdcString(f); +} + + +// +// 'ppdcDriver::set_version()' - Set the version string. +// + +void +ppdcDriver::set_version(const char *v) // I - Version +{ + if (version) + version->release(); + + version = new ppdcString(v); +} + + +// +// 'ppdcDriver::write_ppd_file()' - Write a PPD file... +// + +int // O - 0 on success, -1 on failure +ppdcDriver::write_ppd_file( + cups_file_t *fp, // I - PPD file + ppdcCatalog *catalog, // I - Message catalog + ppdcArray *locales, // I - Additional languages to add + ppdcSource *src, // I - Driver source + ppdcLineEnding le) // I - Line endings to use +{ + bool delete_cat; // Delete the catalog when we are done? + char query[42], // Query attribute + custom[42]; // Custom attribute + ppdcString *s; // Copyright string + ppdcGroup *g; // Current group + ppdcOption *o; // Current option + ppdcChoice *c; // Current choice + ppdcMediaSize *m; // Current media size + ppdcProfile *p; // Current color profile + ppdcFilter *f; // Current filter + ppdcFont *fn, // Current font + *bfn; // Current base font + ppdcConstraint *cn; // Current constraint + ppdcAttr *a; // Current attribute + const char *lf; // Linefeed character to use + + + // If we don't have a message catalog, use an empty (English) one... + if (!catalog) + { + catalog = new ppdcCatalog("en"); + delete_cat = true; + } + else + delete_cat = false; + + // Figure out the end-of-line string... + if (le == PPDC_LFONLY) + lf = "\n"; + else if (le == PPDC_CRONLY) + lf = "\r"; + else + lf = "\r\n"; + + // Write the standard header stuff... + cupsFilePrintf(fp, "*PPD-Adobe: \"4.3\"%s", lf); + cupsFilePrintf(fp, "*%%%%%%%% PPD file for %s with CUPS.%s", + model_name->value, lf); + cupsFilePrintf(fp, + "*%%%%%%%% Created by the CUPS PPD Compiler " CUPS_SVERSION + ".%s", lf); + for (s = (ppdcString *)copyright->first(); + s; + s = (ppdcString *)copyright->next()) + cupsFilePrintf(fp, "*%% %s%s", catalog->find_message(s->value), lf); + cupsFilePrintf(fp, "*FormatVersion: \"4.3\"%s", lf); + cupsFilePrintf(fp, "*FileVersion: \"%s\"%s", version->value, lf); + + a = find_attr("LanguageVersion", NULL); + cupsFilePrintf(fp, "*LanguageVersion: %s%s", + catalog->find_message(a ? a->value->value : "English"), lf); + + a = find_attr("LanguageEncoding", NULL); + cupsFilePrintf(fp, "*LanguageEncoding: %s%s", + catalog->find_message(a ? a->value->value : "ISOLatin1"), lf); + + cupsFilePrintf(fp, "*PCFileName: \"%s\"%s", pc_file_name->value, lf); + + for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next()) + if (!strcmp(a->name->value, "Product")) + break; + + if (a) + { + for (; a; a = (ppdcAttr *)attrs->next()) + if (!strcmp(a->name->value, "Product")) + cupsFilePrintf(fp, "*Product: \"%s\"%s", a->value->value, lf); + } + else + cupsFilePrintf(fp, "*Product: \"(%s)\"%s", model_name->value, lf); + + cupsFilePrintf(fp, "*Manufacturer: \"%s\"%s", + catalog->find_message(manufacturer->value), lf); + + if ((a = find_attr("ModelName", NULL)) != NULL) + cupsFilePrintf(fp, "*ModelName: \"%s\"%s", + catalog->find_message(a->value->value), lf); + else if (strncasecmp(model_name->value, manufacturer->value, + strlen(manufacturer->value))) + cupsFilePrintf(fp, "*ModelName: \"%s %s\"%s", + catalog->find_message(manufacturer->value), + catalog->find_message(model_name->value), lf); + else + cupsFilePrintf(fp, "*ModelName: \"%s\"%s", + catalog->find_message(model_name->value), lf); + + if ((a = find_attr("ShortNickName", NULL)) != NULL) + cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s", + catalog->find_message(a->value->value), lf); + else if (strncasecmp(model_name->value, manufacturer->value, + strlen(manufacturer->value))) + cupsFilePrintf(fp, "*ShortNickName: \"%s %s\"%s", + catalog->find_message(manufacturer->value), + catalog->find_message(model_name->value), lf); + else + cupsFilePrintf(fp, "*ShortNickName: \"%s\"%s", + catalog->find_message(model_name->value), lf); + + if ((a = find_attr("NickName", NULL)) != NULL) + cupsFilePrintf(fp, "*NickName: \"%s\"%s", + catalog->find_message(a->value->value), lf); + else if (strncasecmp(model_name->value, manufacturer->value, + strlen(manufacturer->value))) + cupsFilePrintf(fp, "*NickName: \"%s %s, %s\"%s", + catalog->find_message(manufacturer->value), + catalog->find_message(model_name->value), version->value, + lf); + else + cupsFilePrintf(fp, "*NickName: \"%s, %s\"%s", + catalog->find_message(model_name->value), version->value, + lf); + + for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next()) + if (!strcmp(a->name->value, "PSVersion")) + break; + + if (a) + { + for (; a; a = (ppdcAttr *)attrs->next()) + if (!strcmp(a->name->value, "PSVersion")) + cupsFilePrintf(fp, "*PSVersion: \"%s\"%s", a->value->value, lf); + } + else + cupsFilePrintf(fp, "*PSVersion: \"(3010.000) 0\"%s", lf); + + if ((a = find_attr("LanguageLevel", NULL)) != NULL) + cupsFilePrintf(fp, "*LanguageLevel: \"%s\"%s", a->value->value, lf); + else + cupsFilePrintf(fp, "*LanguageLevel: \"3\"%s", lf); + + cupsFilePrintf(fp, "*ColorDevice: %s%s", color_device ? "True" : "False", lf); + + if ((a = find_attr("DefaultColorSpace", NULL)) != NULL) + cupsFilePrintf(fp, "*DefaultColorSpace: %s%s", a->value->value, lf); + else + cupsFilePrintf(fp, "*DefaultColorSpace: %s%s", + color_device ? "RGB" : "Gray", lf); + + if ((a = find_attr("FileSystem", NULL)) != NULL) + cupsFilePrintf(fp, "*FileSystem: %s%s", a->value->value, lf); + else + cupsFilePrintf(fp, "*FileSystem: False%s", lf); + + cupsFilePrintf(fp, "*Throughput: \"%d\"%s", throughput, lf); + + if ((a = find_attr("LandscapeOrientation", NULL)) != NULL) + cupsFilePrintf(fp, "*LandscapeOrientation: %s%s", a->value->value, lf); + else + cupsFilePrintf(fp, "*LandscapeOrientation: Plus90%s", lf); + + if ((a = find_attr("TTRasterizer", NULL)) != NULL) + cupsFilePrintf(fp, "*TTRasterizer: %s%s", a->value->value, lf); + else if (type != PPDC_DRIVER_PS) + cupsFilePrintf(fp, "*TTRasterizer: Type42%s", lf); + + struct lconv *loc = localeconv(); + + if (attrs->count) + { + // Write driver-defined attributes... + cupsFilePrintf(fp, "*%% Driver-defined attributes...%s", lf); + for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next()) + { + if (!strcmp(a->name->value, "Product") || + !strcmp(a->name->value, "PSVersion") || + !strcmp(a->name->value, "LanguageLevel") || + !strcmp(a->name->value, "DefaultColorSpace") || + !strcmp(a->name->value, "FileSystem") || + !strcmp(a->name->value, "LandscapeOrientation") || + !strcmp(a->name->value, "TTRasterizer") || + !strcmp(a->name->value, "LanguageVersion") || + !strcmp(a->name->value, "LanguageEncoding") || + !strcmp(a->name->value, "ModelName") || + !strcmp(a->name->value, "NickName") || + !strcmp(a->name->value, "ShortNickName") || + !strcmp(a->name->value, "cupsVersion")) + continue; + + if (a->name->value[0] == '?' && + (find_option(a->name->value + 1) || + !strcmp(a->name->value, "?ImageableArea") || + !strcmp(a->name->value, "?PageRegion") || + !strcmp(a->name->value, "?PageSize") || + !strcmp(a->name->value, "?PaperDimension"))) + continue; + + if (!strncmp(a->name->value, "Custom", 6) && + find_option(a->name->value + 6)) + continue; + + if (!strncmp(a->name->value, "ParamCustom", 11) && + find_option(a->name->value + 11)) + continue; + + if (!a->selector->value || !a->selector->value[0]) + cupsFilePrintf(fp, "*%s", a->name->value); + else if (!a->text->value || !a->text->value[0]) + cupsFilePrintf(fp, "*%s %s", a->name->value, a->selector->value); + else + cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value, + a->text->value); + + if (strcmp(a->value->value, "False") && + strcmp(a->value->value, "True") && + strcmp(a->name->value, "1284Modes") && + strcmp(a->name->value, "InkName") && + strcmp(a->name->value, "PageStackOrder") && + strncmp(a->name->value, "ParamCustom", 11) && + strcmp(a->name->value, "Protocols") && + strcmp(a->name->value, "ReferencePunch") && + strncmp(a->name->value, "Default", 7)) + { + cupsFilePrintf(fp, ": \"%s\"%s", a->value->value, lf); + + if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + else + cupsFilePrintf(fp, ": %s%s", a->value->value, lf); + } + } + + if (type != PPDC_DRIVER_PS || filters->count) + { + if ((a = find_attr("cupsVersion", NULL)) != NULL) + cupsFilePrintf(fp, "*cupsVersion: %s%s", a->value->value, lf); + else + cupsFilePrintf(fp, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR, + CUPS_VERSION_MINOR, lf); + cupsFilePrintf(fp, "*cupsModelNumber: %d%s", model_number, lf); + cupsFilePrintf(fp, "*cupsManualCopies: %s%s", + manual_copies ? "True" : "False", lf); + + if (filters->count) + { + for (f = (ppdcFilter *)filters->first(); + f; + f = (ppdcFilter *)filters->next()) + cupsFilePrintf(fp, "*cupsFilter: \"%s %d %s\"%s", f->mime_type->value, + f->cost, f->program->value, lf); + } + else + { + switch (type) + { + case PPDC_DRIVER_LABEL : + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 " + "rastertolabel\"%s", lf); + break; + + case PPDC_DRIVER_EPSON : + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 " + "rastertoepson\"%s", lf); + break; + + case PPDC_DRIVER_ESCP : + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 " + "commandtoescpx\"%s", lf); + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 " + "rastertoescpx\"%s", lf); + break; + + case PPDC_DRIVER_HP : + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 " + "rastertohp\"%s", lf); + break; + + case PPDC_DRIVER_PCL : + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-command 50 " + "commandtopclx\"%s", lf); + cupsFilePrintf(fp, "*cupsFilter: \"application/vnd.cups-raster 50 " + "rastertopclx\"%s", lf); + break; + + default : + break; + } + } + + for (p = (ppdcProfile *)profiles->first(); + p; + p = (ppdcProfile *)profiles->next()) + { + char density[255], gamma[255], profile[9][255]; + + _cupsStrFormatd(density, density + sizeof(density), p->density, loc); + _cupsStrFormatd(gamma, gamma + sizeof(gamma), p->gamma, loc); + + for (int i = 0; i < 9; i ++) + _cupsStrFormatd(profile[i], profile[i] + sizeof(profile[0]), + p->profile[i], loc); + + cupsFilePrintf(fp, + "*cupsColorProfile %s/%s: \"%s %s %s %s %s %s %s %s %s %s " + "%s\"%s", p->resolution->value, p->media_type->value, + density, gamma, profile[0], profile[1], profile[2], + profile[3], profile[4], profile[5], profile[6], profile[7], + profile[8], lf); + } + } + + if (locales) + { + // Add localizations for additional languages... + ppdcString *locale; // Locale name + ppdcCatalog *locatalog; // Message catalog for locale + + + // Write the list of languages... + cupsFilePrintf(fp, "*cupsLanguages: \"en"); + + for (locale = (ppdcString *)locales->first(); + locale; + locale = (ppdcString *)locales->next()) + { + // Skip (US) English... + if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US")) + continue; + + // See if we have a po file for this language... + if (!src->find_po(locale->value)) + { + // No, see if we can use the base file? + locatalog = new ppdcCatalog(locale->value); + + if (locatalog->messages->count == 0) + { + // No, skip this one... + _cupsLangPrintf(stderr, + _("ppdc: No message catalog provided for locale " + "%s!\n"), locale->value); + continue; + } + + // Add the base file to the list... + src->po_files->add(locatalog); + } + + cupsFilePrintf(fp, " %s", locale->value); + } + + cupsFilePrintf(fp, "\"%s", lf); + } + + for (cn = (ppdcConstraint *)constraints->first(); + cn; + cn = (ppdcConstraint *)constraints->next()) + { + // First constrain 1 against 2... + if (!strncmp(cn->option1->value, "*Custom", 7) || + !strncmp(cn->option2->value, "*Custom", 7)) + cupsFilePuts(fp, "*NonUIConstraints: "); + else + cupsFilePuts(fp, "*UIConstraints: "); + + if (cn->option1->value[0] != '*') + cupsFilePutChar(fp, '*'); + + cupsFilePuts(fp, cn->option1->value); + + if (cn->choice1->value) + cupsFilePrintf(fp, " %s", cn->choice1->value); + + cupsFilePutChar(fp, ' '); + + if (cn->option2->value[0] != '*') + cupsFilePutChar(fp, '*'); + + cupsFilePuts(fp, cn->option2->value); + + if (cn->choice2->value) + cupsFilePrintf(fp, " %s", cn->choice2->value); + + cupsFilePuts(fp, lf); + + // Then constrain 2 against 1... + if (!strncmp(cn->option1->value, "*Custom", 7) || + !strncmp(cn->option2->value, "*Custom", 7)) + cupsFilePuts(fp, "*NonUIConstraints: "); + else + cupsFilePuts(fp, "*UIConstraints: "); + + if (cn->option2->value[0] != '*') + cupsFilePutChar(fp, '*'); + + cupsFilePuts(fp, cn->option2->value); + + if (cn->choice2->value) + cupsFilePrintf(fp, " %s", cn->choice2->value); + + cupsFilePutChar(fp, ' '); + + if (cn->option1->value[0] != '*') + cupsFilePutChar(fp, '*'); + + cupsFilePuts(fp, cn->option1->value); + + if (cn->choice1->value) + cupsFilePrintf(fp, " %s", cn->choice1->value); + + cupsFilePuts(fp, lf); + } + + // PageSize option... + cupsFilePrintf(fp, "*OpenUI *PageSize/Media Size: PickOne%s", lf); + cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageSize%s", lf); + cupsFilePrintf(fp, "*DefaultPageSize: %s%s", + default_size ? default_size->value : "Letter", lf); + + for (m = (ppdcMediaSize *)sizes->first(); + m; + m = (ppdcMediaSize *)sizes->next()) + if (m->size_code->value) + { + cupsFilePrintf(fp, "*PageSize %s/%s: \"%s\"%s", + m->name->value, catalog->find_message(m->text->value), + m->size_code->value, lf); + + if (strchr(m->size_code->value, '\n') || + strchr(m->size_code->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + else + cupsFilePrintf(fp, + "*PageSize %s/%s: \"<>setpagedevice\"%s", + m->name->value, catalog->find_message(m->text->value), + m->width, m->length, lf); + + if ((a = find_attr("?PageSize", NULL)) != NULL) + { + cupsFilePrintf(fp, "*?PageSize: \"%s\"%s", a->value->value, lf); + + if (strchr(a->value->value, '\n') || + strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + + cupsFilePrintf(fp, "*CloseUI: *PageSize%s", lf); + + // PageRegion option... + cupsFilePrintf(fp, "*OpenUI *PageRegion/Media Size: PickOne%s", lf); + cupsFilePrintf(fp, "*OrderDependency: 10 AnySetup *PageRegion%s", lf); + cupsFilePrintf(fp, "*DefaultPageRegion: %s%s", + default_size ? default_size->value : "Letter", lf); + + for (m = (ppdcMediaSize *)sizes->first(); + m; + m = (ppdcMediaSize *)sizes->next()) + if (m->region_code->value) + { + cupsFilePrintf(fp, "*PageRegion %s/%s: \"%s\"%s", + m->name->value, catalog->find_message(m->text->value), + m->region_code->value, lf); + + if (strchr(m->region_code->value, '\n') || + strchr(m->region_code->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + else + cupsFilePrintf(fp, + "*PageRegion %s/%s: \"<>setpagedevice\"%s", + m->name->value, catalog->find_message(m->text->value), + m->width, m->length, lf); + + if ((a = find_attr("?PageRegion", NULL)) != NULL) + { + cupsFilePrintf(fp, "*?PageRegion: \"%s\"%s", a->value->value, lf); + + if (strchr(a->value->value, '\n') || + strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + + cupsFilePrintf(fp, "*CloseUI: *PageRegion%s", lf); + + // ImageableArea info... + cupsFilePrintf(fp, "*DefaultImageableArea: %s%s", + default_size ? default_size->value : "Letter", lf); + + char left[255], right[255], bottom[255], top[255]; + + for (m = (ppdcMediaSize *)sizes->first(); + m; + m = (ppdcMediaSize *)sizes->next()) + { + _cupsStrFormatd(left, left + sizeof(left), m->left, loc); + _cupsStrFormatd(bottom, bottom + sizeof(bottom), m->bottom, loc); + _cupsStrFormatd(right, right + sizeof(right), m->width - m->right, loc); + _cupsStrFormatd(top, top + sizeof(top), m->length - m->top, loc); + + cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%s %s %s %s\"%s", + m->name->value, catalog->find_message(m->text->value), + left, bottom, right, top, lf); + } + + if ((a = find_attr("?ImageableArea", NULL)) != NULL) + { + cupsFilePrintf(fp, "*?ImageableArea: \"%s\"%s", a->value->value, lf); + + if (strchr(a->value->value, '\n') || + strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + + // PaperDimension info... + cupsFilePrintf(fp, "*DefaultPaperDimension: %s%s", + default_size ? default_size->value : "Letter", lf); + + char width[255], length[255]; + + for (m = (ppdcMediaSize *)sizes->first(); + m; + m = (ppdcMediaSize *)sizes->next()) + { + _cupsStrFormatd(width, width + sizeof(width), m->width, loc); + _cupsStrFormatd(length, length + sizeof(length), m->length, loc); + + cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%s %s\"%s", + m->name->value, catalog->find_message(m->text->value), + width, length, lf); + } + + if ((a = find_attr("?PaperDimension", NULL)) != NULL) + { + cupsFilePrintf(fp, "*?PaperDimension: \"%s\"%s", a->value->value, lf); + + if (strchr(a->value->value, '\n') || + strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + + // Custom size support... + if (variable_paper_size) + { + _cupsStrFormatd(width, width + sizeof(width), max_width, loc); + _cupsStrFormatd(length, length + sizeof(length), max_length, loc); + + _cupsStrFormatd(left, left + sizeof(left), left_margin, loc); + _cupsStrFormatd(bottom, bottom + sizeof(bottom), bottom_margin, loc); + _cupsStrFormatd(right, right + sizeof(right), right_margin, loc); + _cupsStrFormatd(top, top + sizeof(top), top_margin, loc); + + cupsFilePrintf(fp, "*MaxMediaWidth: \"%s\"%s", width, lf); + cupsFilePrintf(fp, "*MaxMediaHeight: \"%s\"%s", length, lf); + cupsFilePrintf(fp, "*HWMargins: %s %s %s %s%s", left, bottom, right, top, + lf); + + if (custom_size_code && custom_size_code->value) + { + cupsFilePrintf(fp, "*CustomPageSize True: \"%s\"%s", + custom_size_code->value, lf); + + if (strchr(custom_size_code->value, '\n') || + strchr(custom_size_code->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + else + cupsFilePrintf(fp, + "*CustomPageSize True: \"pop pop pop <>setpagedevice\"%s", lf); + + if ((a = find_attr("ParamCustomPageSize", "Width")) != NULL) + cupsFilePrintf(fp, "*ParamCustomPageSize Width: %s%s", a->value->value, + lf); + else + { + char width0[255]; + + _cupsStrFormatd(width0, width0 + sizeof(width0), min_width, loc); + _cupsStrFormatd(width, width + sizeof(width), max_width, loc); + + cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s%s", + width0, width, lf); + } + + if ((a = find_attr("ParamCustomPageSize", "Height")) != NULL) + cupsFilePrintf(fp, "*ParamCustomPageSize Height: %s%s", a->value->value, + lf); + else + { + char length0[255]; + + _cupsStrFormatd(length0, length0 + sizeof(length0), min_length, loc); + _cupsStrFormatd(length, length + sizeof(length), max_length, loc); + + cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s%s", + length0, length, lf); + } + + if ((a = find_attr("ParamCustomPageSize", "WidthOffset")) != NULL) + cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: %s%s", + a->value->value, lf); + else + cupsFilePrintf(fp, "*ParamCustomPageSize WidthOffset: 3 points 0 0%s", lf); + + if ((a = find_attr("ParamCustomPageSize", "HeightOffset")) != NULL) + cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: %s%s", + a->value->value, lf); + else + cupsFilePrintf(fp, "*ParamCustomPageSize HeightOffset: 4 points 0 0%s", lf); + + if ((a = find_attr("ParamCustomPageSize", "Orientation")) != NULL) + cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: %s%s", + a->value->value, lf); + else + cupsFilePrintf(fp, "*ParamCustomPageSize Orientation: 5 int 0 0%s", lf); + } + + // All other options... + for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next()) + { + if (!g->options->count) + continue; + + if (strcasecmp(g->name->value, "General")) + cupsFilePrintf(fp, "*OpenGroup: %s/%s%s", g->name->value, + catalog->find_message(g->text->value), lf); + + for (o = (ppdcOption *)g->options->first(); + o; + o = (ppdcOption *)g->options->next()) + { + if (!o->choices->count) + continue; + + if (!o->text->value) + cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value, + catalog->find_message(o->name->value)); + else + cupsFilePrintf(fp, "*OpenUI *%s/%s: ", o->name->value, + catalog->find_message(o->text->value)); + + switch (o->type) + { + case PPDC_BOOLEAN : + cupsFilePrintf(fp, "Boolean%s", lf); + break; + default : + cupsFilePrintf(fp, "PickOne%s", lf); + break; + case PPDC_PICKMANY : + cupsFilePrintf(fp, "PickMany%s", lf); + break; + } + + char order[255]; + _cupsStrFormatd(order, order + sizeof(order), o->order, loc); + + cupsFilePrintf(fp, "*OrderDependency: %s ", order); + switch (o->section) + { + default : + cupsFilePrintf(fp, "AnySetup"); + break; + case PPDC_SECTION_DOCUMENT : + cupsFilePrintf(fp, "DocumentSetup"); + break; + case PPDC_SECTION_EXIT : + cupsFilePrintf(fp, "ExitServer"); + break; + case PPDC_SECTION_JCL : + cupsFilePrintf(fp, "JCLSetup"); + break; + case PPDC_SECTION_PAGE : + cupsFilePrintf(fp, "PageSetup"); + break; + case PPDC_SECTION_PROLOG : + cupsFilePrintf(fp, "Prolog"); + break; + } + + cupsFilePrintf(fp, " *%s%s", o->name->value, lf); + + if (o->defchoice) + { + // Use the programmer-supplied default... + cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value, + o->defchoice->value, lf); + } + else + { + // Make the first choice the default... + c = (ppdcChoice *)o->choices->first(); + cupsFilePrintf(fp, "*Default%s: %s%s", o->name->value, c->name->value, + lf); + } + + for (c = (ppdcChoice *)o->choices->first(); + c; + c = (ppdcChoice *)o->choices->next()) + { + // Write this choice... + if (!c->text->value) + cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value, + c->name->value, catalog->find_message(c->name->value), + c->code->value, lf); + else + cupsFilePrintf(fp, "*%s %s/%s: \"%s\"%s", o->name->value, + c->name->value, catalog->find_message(c->text->value), + c->code->value, lf); + + // Multi-line commands need a *End line to terminate them. + if (strchr(c->code->value, '\n') || + strchr(c->code->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + + snprintf(query, sizeof(query), "?%s", o->name->value); + + if ((a = find_attr(query, NULL)) != NULL) + { + cupsFilePrintf(fp, "*%s: \"%s\"%s", query, a->value->value, lf); + + if (strchr(a->value->value, '\n') || + strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + } + + cupsFilePrintf(fp, "*CloseUI: *%s%s", o->name->value, lf); + + snprintf(custom, sizeof(custom), "Custom%s", o->name->value); + if ((a = find_attr(custom, "True")) != NULL) + { + // Output custom option information... + cupsFilePrintf(fp, "*%s True: \"%s\"%s", custom, a->value->value, lf); + if (strchr(a->value->value, '\n') || strchr(a->value->value, '\r')) + cupsFilePrintf(fp, "*End%s", lf); + + snprintf(custom, sizeof(custom), "ParamCustom%s", o->name->value); + for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next()) + { + if (strcmp(a->name->value, custom)) + continue; + + if (!a->selector->value || !a->selector->value[0]) + cupsFilePrintf(fp, "*%s", a->name->value); + else if (!a->text->value || !a->text->value[0]) + cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value, + catalog->find_message(a->selector->value)); + else + cupsFilePrintf(fp, "*%s %s/%s", a->name->value, a->selector->value, + catalog->find_message(a->text->value)); + + cupsFilePrintf(fp, ": %s%s", a->value->value, lf); + } + } + } + + if (strcasecmp(g->name->value, "General")) + cupsFilePrintf(fp, "*CloseGroup: %s%s", g->name->value, lf); + } + + if (locales) + { + // Add localizations for additional languages... + ppdcString *locale; // Locale name + ppdcCatalog *locatalog; // Message catalog for locale + + + // Write the translation strings for each language... + for (locale = (ppdcString *)locales->first(); + locale; + locale = (ppdcString *)locales->next()) + { + // Skip (US) English... + if (!strcmp(locale->value, "en") || !strcmp(locale->value, "en_US")) + continue; + + // Skip missing languages... + if ((locatalog = src->find_po(locale->value)) == NULL) + continue; + + // Do the core stuff first... + cupsFilePrintf(fp, "*%s.Translation Manufacturer/%s: \"\"%s", + locale->value, + locatalog->find_message(manufacturer->value), lf); + + if ((a = find_attr("ModelName", NULL)) != NULL) + cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s", + locale->value, + locatalog->find_message(a->value->value), lf); + else if (strncasecmp(model_name->value, manufacturer->value, + strlen(manufacturer->value))) + cupsFilePrintf(fp, "*%s.Translation ModelName/%s %s: \"\"%s", + locale->value, + locatalog->find_message(manufacturer->value), + locatalog->find_message(model_name->value), lf); + else + cupsFilePrintf(fp, "*%s.Translation ModelName/%s: \"\"%s", + locale->value, + locatalog->find_message(model_name->value), lf); + + if ((a = find_attr("ShortNickName", NULL)) != NULL) + cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s", + locale->value, + locatalog->find_message(a->value->value), lf); + else if (strncasecmp(model_name->value, manufacturer->value, + strlen(manufacturer->value))) + cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s %s: \"\"%s", + locale->value, + locatalog->find_message(manufacturer->value), + locatalog->find_message(model_name->value), lf); + else + cupsFilePrintf(fp, "*%s.Translation ShortNickName/%s: \"\"%s", + locale->value, + locatalog->find_message(model_name->value), lf); + + if ((a = find_attr("NickName", NULL)) != NULL) + cupsFilePrintf(fp, "*%s.Translation NickName/%s: \"\"%s", + locale->value, + locatalog->find_message(a->value->value), lf); + else if (strncasecmp(model_name->value, manufacturer->value, + strlen(manufacturer->value))) + cupsFilePrintf(fp, "*%s.Translation NickName/%s %s, %s: \"\"%s", + locale->value, + locatalog->find_message(manufacturer->value), + locatalog->find_message(model_name->value), + version->value, lf); + else + cupsFilePrintf(fp, "*%s.Translation NickName/%s, %s: \"\"%s", + locale->value, + locatalog->find_message(model_name->value), + version->value, lf); + + // Then the page sizes... + cupsFilePrintf(fp, "*%s.Translation PageSize/%s: \"\"%s", locale->value, + locatalog->find_message("Media Size"), lf); + + for (m = (ppdcMediaSize *)sizes->first(); + m; + m = (ppdcMediaSize *)sizes->next()) + { + cupsFilePrintf(fp, "*%s.PageSize %s/%s: \"\"%s", locale->value, + m->name->value, locatalog->find_message(m->text->value), + lf); + } + + // Next the groups and options... + for (g = (ppdcGroup *)groups->first(); g; g = (ppdcGroup *)groups->next()) + { + if (!g->options->count) + continue; + + if (strcasecmp(g->name->value, "General")) + cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value, + g->name->value, + locatalog->find_message(g->text->value), lf); + + for (o = (ppdcOption *)g->options->first(); + o; + o = (ppdcOption *)g->options->next()) + { + if (!o->choices->count) + continue; + + cupsFilePrintf(fp, "*%s.Translation %s/%s: \"\"%s", locale->value, + o->name->value, + locatalog->find_message(o->text->value ? + o->text->value : + o->name->value), lf); + + for (c = (ppdcChoice *)o->choices->first(); + c; + c = (ppdcChoice *)o->choices->next()) + { + // Write this choice... + cupsFilePrintf(fp, "*%s.%s %s/%s: \"\"%s", locale->value, + o->name->value, c->name->value, + locatalog->find_message(c->text->value ? + c->text->value : + c->name->value), lf); + } + } + } + + // Finally the localizable attributes... + for (a = (ppdcAttr *)attrs->first(); a; a = (ppdcAttr *)attrs->next()) + { + if (!a->localizable && + (!a->text || !a->text->value || !a->text->value[0]) && + strcmp(a->name->value, "APCustomColorMatchingName") && + strcmp(a->name->value, "APPrinterPreset") && + strcmp(a->name->value, "cupsICCProfile") && + strcmp(a->name->value, "cupsIPPReason") && + strcmp(a->name->value, "cupsMarkerName") && + strncmp(a->name->value, "Custom", 6) && + strncmp(a->name->value, "ParamCustom", 11)) + continue; + + cupsFilePrintf(fp, "*%s.%s %s/%s: \"%s\"%s", locale->value, + a->name->value, a->selector->value, + locatalog->find_message(a->text && a->text->value ? + a->text->value : a->name->value), + ((a->localizable && a->value->value[0]) || + !strcmp(a->name->value, "cupsIPPReason")) ? + locatalog->find_message(a->value->value) : "", + lf); + } + } + } + + if (default_font && default_font->value) + cupsFilePrintf(fp, "*DefaultFont: %s%s", default_font->value, lf); + else + cupsFilePrintf(fp, "*DefaultFont: Courier%s", lf); + + for (fn = (ppdcFont *)fonts->first(); fn; fn = (ppdcFont *)fonts->next()) + if (!strcmp(fn->name->value, "*")) + { + for (bfn = (ppdcFont *)src->base_fonts->first(); + bfn; + bfn = (ppdcFont *)src->base_fonts->next()) + cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s", + bfn->name->value, bfn->encoding->value, + bfn->version->value, bfn->charset->value, + bfn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf); + } + else + cupsFilePrintf(fp, "*Font %s: %s \"%s\" %s %s%s", + fn->name->value, fn->encoding->value, fn->version->value, + fn->charset->value, + fn->status == PPDC_FONT_ROM ? "ROM" : "Disk", lf); + + cupsFilePrintf(fp, "*%% End of %s, %05d bytes.%s", pc_file_name->value, + (int)(cupsFileTell(fp) + 25 + strlen(pc_file_name->value)), + lf); + + if (delete_cat) + catalog->release(); + + return (0); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-file.cxx b/ppdc/ppdc-file.cxx new file mode 100644 index 0000000000..9b30bcca46 --- /dev/null +++ b/ppdc/ppdc-file.cxx @@ -0,0 +1,110 @@ +// +// "$Id$" +// +// File class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcFile::ppdcFile() - Create (open) a file. +// ppdcFile::~ppdcFile() - Delete (close) a file. +// ppdcFile::get() - Get a character from a file. +// ppdcFile::peek() - Look at the next character from a file. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include + + +// +// 'ppdcFile::ppdcFile()' - Create (open) a file. +// + +ppdcFile::ppdcFile(const char *f, // I - File to open + cups_file_t *ffp) // I - File pointer to use +{ + if (ffp) + { + fp = ffp; + cupsFileRewind(fp); + } + else + fp = cupsFileOpen(f, "r"); + + filename = f; + line = 1; + + if (!fp) + _cupsLangPrintf(stderr, _("%s: Unable to open %s: %s\n"), "ppdc", f, + strerror(errno)); +} + + +// +// 'ppdcFile::~ppdcFile()' - Delete (close) a file. +// + +ppdcFile::~ppdcFile() +{ + if (fp) + cupsFileClose(fp); +} + + +// +// 'ppdcFile::get()' - Get a character from a file. +// + +int +ppdcFile::get() +{ + int ch; // Character from file + + + // Return EOF if there is no open file... + if (!fp) + return (EOF); + + // Get the character... + ch = cupsFileGetChar(fp); + + // Update the line number as needed... + if (ch == '\n') + line ++; + + // Return the character... + return (ch); +} + + +// +// 'ppdcFile::peek()' - Look at the next character from a file. +// + +int // O - Next character in file +ppdcFile::peek() +{ + // Return immediaely if there is no open file... + if (!fp) + return (EOF); + + // Otherwise return the next character without advancing... + return (cupsFilePeekChar(fp)); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-filter.cxx b/ppdc/ppdc-filter.cxx new file mode 100644 index 0000000000..33994849b8 --- /dev/null +++ b/ppdc/ppdc-filter.cxx @@ -0,0 +1,60 @@ +// +// "$Id$" +// +// Filter class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcFilter::ppdcFilter() - Create a filter. +// ppdcFilter::~ppdcFilter() - Destroy a filter. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcFilter::ppdcFilter()' - Create a filter. +// + +ppdcFilter::ppdcFilter(const char *t, // I - MIME type + const char *p, // I - Filter program + int c) // I - Relative cost + : ppdcShared() +{ + PPDC_NEW; + + mime_type = new ppdcString(t); + program = new ppdcString(p); + cost = c; +} + + +// +// 'ppdcFilter::~ppdcFilter()' - Destroy a filter. +// + +ppdcFilter::~ppdcFilter() +{ + PPDC_DELETE; + + mime_type->release(); + program->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-font.cxx b/ppdc/ppdc-font.cxx new file mode 100644 index 0000000000..b6d9bcb2ab --- /dev/null +++ b/ppdc/ppdc-font.cxx @@ -0,0 +1,66 @@ +// +// "$Id$" +// +// Shared font class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcFont::ppdcFont() - Create a shared font. +// ppdcFont::~ppdcFont() - Destroy a shared font. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcFont::ppdcFont()' - Create a shared font. +// + +ppdcFont::ppdcFont(const char *n, // I - Name of font + const char *e, // I - Font encoding + const char *v, // I - Font version + const char *c, // I - Font charset + ppdcFontStatus s) // I - Font status + : ppdcShared() +{ + PPDC_NEW; + + name = new ppdcString(n); + encoding = new ppdcString(e); + version = new ppdcString(v); + charset = new ppdcString(c); + status = s; +} + + +// +// 'ppdcFont::~ppdcFont()' - Destroy a shared font. +// + +ppdcFont::~ppdcFont() +{ + PPDC_DELETE; + + name->release(); + encoding->release(); + version->release(); + charset->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-group.cxx b/ppdc/ppdc-group.cxx new file mode 100644 index 0000000000..413a8f28a0 --- /dev/null +++ b/ppdc/ppdc-group.cxx @@ -0,0 +1,103 @@ +// +// "$Id$" +// +// Group class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcGroup::ppdcGroup() - Copy a new group. +// ppdcGroup::~ppdcGroup() - Destroy a group. +// ppdcGroup::find_option() - Find an option in a group. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcGroup::ppdcGroup()' - Create a new group. +// + +ppdcGroup::ppdcGroup(const char *n, // I - Name of group + const char *t) // I - Text of group +{ + PPDC_NEWVAL(n); + + name = new ppdcString(n); + text = new ppdcString(t); + options = new ppdcArray(); +} + + +// +// 'ppdcGroup::ppdcGroup()' - Copy a new group. +// + +ppdcGroup::ppdcGroup(ppdcGroup *g) // I - Group template +{ + PPDC_NEWVAL(g->name->value); + + g->name->retain(); + g->text->retain(); + + name = g->name; + text = g->text; + + options = new ppdcArray(); + for (ppdcOption *o = (ppdcOption *)g->options->first(); + o; + o = (ppdcOption *)g->options->next()) + options->add(new ppdcOption(o)); +} + + +// +// 'ppdcGroup::~ppdcGroup()' - Destroy a group. +// + +ppdcGroup::~ppdcGroup() +{ + PPDC_DELETEVAL(name ? name->value : NULL); + + name->release(); + text->release(); + options->release(); + + name = text = 0; + options = 0; +} + + +// +// 'ppdcGroup::find_option()' - Find an option in a group. +// + +ppdcOption * +ppdcGroup::find_option(const char *n) // I - Name of option +{ + ppdcOption *o; // Current option + + + for (o = (ppdcOption *)options->first(); o; o = (ppdcOption *)options->next()) + if (!strcasecmp(n, o->name->value)) + return (o); + + return (0); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-import.cxx b/ppdc/ppdc-import.cxx new file mode 100644 index 0000000000..eb04648f2f --- /dev/null +++ b/ppdc/ppdc-import.cxx @@ -0,0 +1,343 @@ +// +// "$Id$" +// +// PPD file import methods for the CUPS PPD Compiler. +// +// Copyright 2007-2008 by Apple Inc. +// Copyright 2002-2006 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcSource::import_ppd() - Import a PPD file. +// ppd_gets() - Get a line from a PPD file. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include +#include + + +// +// 'ppdcSource::import_ppd()' - Import a PPD file. +// + +int // O - 1 on success, 0 on failure +ppdcSource::import_ppd(const char *f) // I - Filename +{ + int i, j, k; // Looping vars + cups_file_t *fp; // File + char line[256], // Comment line + *ptr; // Pointer into line + int cost; // Cost for filter + ppd_file_t *ppd; // PPD file data + ppd_group_t *group; // PPD group + ppd_option_t *option; // PPD option + ppd_choice_t *choice; // PPD choice + ppd_attr_t *attr; // PPD attribute + ppd_const_t *constraint; // PPD UI constraint + ppd_const_t *constraint2; // Temp PPD UI constraint + ppd_size_t *size; // PPD page size + ppdcDriver *driver; // Driver + ppdcFilter *filter; // Current filter + ppdcFont *font; // Font + ppdcGroup *cgroup; // UI group + ppdcOption *coption; // UI option + ppdcChoice *cchoice; // UI choice + ppdcConstraint *cconstraint; // UI constraint + ppdcMediaSize *csize; // Media size + + + // Try opening the PPD file... + if ((ppd = ppdOpenFile(f)) == NULL) + return (0); + + // All PPD files need a PCFileName attribute... + if (!ppd->pcfilename) + { + ppdClose(ppd); + return (0); + } + + // See if the driver has already been imported... + if ((driver = find_driver(ppd->pcfilename)) == NULL) + { + // Create a new PPD file... + if ((fp = cupsFileOpen(f, "r")) == NULL) + { + ppdClose(ppd); + return (0); + } + + driver = new ppdcDriver(); + driver->type = PPDC_DRIVER_PS; + + drivers->add(driver); + + // Read the initial comments from the PPD file and use them as the + // copyright/license text... + cupsFileGets(fp, line, sizeof(line)); + // Skip *PPD-Adobe-M.m + + while (cupsFileGets(fp, line, sizeof(line))) + if (strncmp(line, "*%", 2)) + break; + else if (strncmp(line, "*%%%% ", 6)) + { + for (ptr = line + 2; isspace(*ptr); ptr ++); + + driver->add_copyright(ptr); + } + + cupsFileClose(fp); + + // Then add the stuff from the PPD file... + if (ppd->modelname && ppd->manufacturer && + !strncasecmp(ppd->modelname, ppd->manufacturer, + strlen(ppd->manufacturer))) + { + ptr = ppd->modelname + strlen(ppd->manufacturer); + + while (isspace(*ptr)) + ptr ++; + } + else + ptr = ppd->modelname; + + if (ppd->nickname) + driver->add_attr(new ppdcAttr("NickName", NULL, NULL, ppd->nickname)); + + if (ppd->shortnickname) + driver->add_attr(new ppdcAttr("ShortNickName", NULL, NULL, + ppd->shortnickname)); + + driver->manufacturer = new ppdcString(ppd->manufacturer); + driver->model_name = new ppdcString(ptr); + driver->pc_file_name = new ppdcString(ppd->pcfilename); + attr = ppdFindAttr(ppd, "FileVersion", NULL); + driver->version = new ppdcString(attr ? attr->value : NULL); + driver->model_number = ppd->model_number; + driver->manual_copies = ppd->manual_copies; + driver->color_device = ppd->color_device; + driver->throughput = ppd->throughput; + driver->variable_paper_size = ppd->variable_sizes; + driver->max_width = ppd->custom_max[0]; + driver->max_length = ppd->custom_max[1]; + driver->min_width = ppd->custom_min[0]; + driver->min_length = ppd->custom_min[1]; + driver->left_margin = ppd->custom_margins[0]; + driver->bottom_margin = ppd->custom_margins[1]; + driver->right_margin = ppd->custom_margins[2]; + driver->top_margin = ppd->custom_margins[3]; + + for (i = 0; i < ppd->num_filters; i ++) + { + strlcpy(line, ppd->filters[i], sizeof(line)); + + for (ptr = line; *ptr; ptr ++) + if (isspace(*ptr & 255)) + break; + *ptr++ = '\0'; + + cost = strtol(ptr, &ptr, 10); + + while (isspace(*ptr & 255)) + ptr ++; + + filter = new ppdcFilter(line, ptr, cost); + driver->add_filter(filter); + } + + attr = ppdFindAttr(ppd, "DefaultFont", NULL); + driver->default_font = new ppdcString(attr ? attr->value : NULL); + + // Collect media sizes... + ppd_option_t *region_option, // PageRegion option + *size_option; // PageSize option + ppd_choice_t *region_choice, // PageRegion choice + *size_choice; // PageSize choice + + region_option = ppdFindOption(ppd, "PageRegion"); + size_option = ppdFindOption(ppd, "PageSize"); + + for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) + { + // Don't do custom size here... + if (!strcasecmp(size->name, "Custom")) + continue; + + // Get the code for the PageSize and PageRegion options... + region_choice = ppdFindChoice(region_option, size->name); + size_choice = ppdFindChoice(size_option, size->name); + + // Create a new media size record and add it to the driver... + csize = new ppdcMediaSize(size->name, size_choice->text, size->width, + size->length, size->left, size->bottom, + size->width - size->right, + size->length - size->top, + size_choice->code, region_choice->code); + + driver->add_size(csize); + + if (!strcasecmp(size_option->defchoice, size->name)) + driver->set_default_size(csize); + } + + // Now all of the options... + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + { + cgroup = new ppdcGroup(group->name, group->text); + driver->add_group(cgroup); + + for (j = group->num_options, option = group->options; j > 0; j --, option ++) + { + if (!strcmp(option->keyword, "PageSize") || !strcmp(option->keyword, "PageRegion")) + continue; + + coption = new ppdcOption((ppdcOptType)option->ui, option->keyword, + option->text, (ppdcOptSection)option->section, + option->order); + cgroup->add_option(coption); + + for (k = option->num_choices, choice = option->choices; k > 0; k --, choice ++) + { + if (!strcmp(choice->choice, "Custom")) + continue; + + cchoice = new ppdcChoice(choice->choice, choice->text, choice->code); + coption->add_choice(cchoice); + + if (!strcasecmp(option->defchoice, choice->choice)) + coption->set_defchoice(cchoice); + } + } + } + + // Now the constraints... + for (i = ppd->num_consts, constraint = ppd->consts; + i > 0; + i --, constraint ++) + { + // Look for mirrored constraints... + for (j = i - 1, constraint2 = constraint + 1; + j > 0; + j --, constraint2 ++) + if (!strcmp(constraint->option1, constraint2->option2) && + !strcmp(constraint->choice1, constraint2->choice2) && + !strcmp(constraint->option2, constraint2->option1) && + !strcmp(constraint->choice2, constraint2->choice1)) + break; + + if (j) + continue; + + cconstraint = new ppdcConstraint(constraint->option2, constraint->choice2, + constraint->option1, constraint->choice1); + driver->add_constraint(cconstraint); + } + + for (i = 0; i < ppd->num_attrs; i ++) + { + attr = ppd->attrs[i]; + + if (!strcmp(attr->name, "Font")) + { + // Font... + char encoding[256], // Encoding string + version[256], // Version string + charset[256], // Charset string + status[256]; // Status string + ppdcFontStatus fstatus; // Status enumeration + + + if (sscanf(attr->value, "%s%*[^\"]\"%[^\"]\"%s%s", encoding, version, + charset, status) != 4) + { + _cupsLangPrintf(stderr, _("Bad font attribute: %s\n"), attr->value); + continue; + } + + if (!strcmp(status, "ROM")) + fstatus = PPDC_FONT_ROM; + else + fstatus = PPDC_FONT_DISK; + + font = new ppdcFont(attr->spec, encoding, version, charset, fstatus); + + driver->add_font(font); + } + else if (!strcmp(attr->name, "CustomPageSize")) + { + driver->set_custom_size_code(attr->value); + } + else if ((strncmp(attr->name, "Default", 7) || + !strcmp(attr->name, "DefaultColorSpace")) && + strcmp(attr->name, "ColorDevice") && + strcmp(attr->name, "Manufacturer") && + strcmp(attr->name, "ModelName") && + strcmp(attr->name, "MaxMediaHeight") && + strcmp(attr->name, "MaxMediaWidth") && + strcmp(attr->name, "NickName") && + strcmp(attr->name, "ParamCustomPageSize") && + strcmp(attr->name, "ShortNickName") && + strcmp(attr->name, "Throughput") && + strcmp(attr->name, "PCFileName") && + strcmp(attr->name, "FileVersion") && + strcmp(attr->name, "FormatVersion") && + strcmp(attr->name, "HWMargins") && + strcmp(attr->name, "VariablePaperSize") && + strcmp(attr->name, "LanguageEncoding") && + strcmp(attr->name, "LanguageVersion") && + strcmp(attr->name, "cupsFilter") && + strcmp(attr->name, "cupsFlipDuplex") && + strcmp(attr->name, "cupsLanguages") && + strcmp(attr->name, "cupsManualCopies") && + strcmp(attr->name, "cupsModelNumber") && + strcmp(attr->name, "cupsVersion")) + { + if ((ptr = strchr(attr->name, '.')) != NULL && + ((ptr - attr->name) == 2 || (ptr - attr->name) == 5)) + { + // Might be a localization attribute; test further... + if (isalpha(attr->name[0] & 255) && + isalpha(attr->name[1] & 255) && + (attr->name[2] == '.' || + (attr->name[2] == '_' && isalpha(attr->name[3] & 255) && + isalpha(attr->name[4] & 255)))) + continue; + } + + // Attribute... + driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text, + attr->value)); + } + else if (!strncmp(attr->name, "Default", 7) && + !ppdFindOption(ppd, attr->name + 7) && + strcmp(attr->name, "DefaultFont") && + strcmp(attr->name, "DefaultImageableArea") && + strcmp(attr->name, "DefaultPaperDimension") && + strcmp(attr->name, "DefaultFont")) + { + // Default attribute... + driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text, + attr->value)); + } + } + } + + return (1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-mediasize.cxx b/ppdc/ppdc-mediasize.cxx new file mode 100644 index 0000000000..844028a39c --- /dev/null +++ b/ppdc/ppdc-mediasize.cxx @@ -0,0 +1,85 @@ +// +// "$Id$" +// +// Shared media size class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcMediaSize::ppdcMediaSize() - Create a new media size. +// ppdcMediaSize::~ppdcMediaSize() - Destroy a media size. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcMediaSize::ppdcMediaSize()' - Create a new media size. +// + +ppdcMediaSize::ppdcMediaSize(const char *n, // I - Name of media size + const char *t, // I - Text of media size + float w, // I - Width in points + float l, // I - Length in points + float lm, // I - Left margin in points + float bm, // I - Bottom margin in points + float rm, // I - Right margin in points + float tm, // I - Top margin in points + const char *sc, // I - PageSize code, if any + const char *rc) // I - PageRegion code, if any + : ppdcShared() +{ + PPDC_NEW; + + name = new ppdcString(n); + text = new ppdcString(t); + width = w; + length = l; + left = lm; + bottom = bm; + right = rm; + top = tm; + size_code = new ppdcString(sc); + region_code = new ppdcString(rc); + + if (left < 0.0f) + left = 0.0f; + if (bottom < 0.0f) + bottom = 0.0f; + if (right < 0.0f) + right = 0.0f; + if (top < 0.0f) + top = 0.0f; +} + + +// +// 'ppdcMediaSize::~ppdcMediaSize()' - Destroy a media size. +// + +ppdcMediaSize::~ppdcMediaSize() +{ + PPDC_DELETE; + + name->release(); + text->release(); + size_code->release(); + region_code->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-message.cxx b/ppdc/ppdc-message.cxx new file mode 100644 index 0000000000..11e5e3eaa7 --- /dev/null +++ b/ppdc/ppdc-message.cxx @@ -0,0 +1,58 @@ +// +// "$Id$" +// +// Shared message class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcMessage::ppdcMessage() - Create a shared message. +// ppdcMessage::~ppdcMessage() - Destroy a shared message. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcMessage::ppdcMessage()' - Create a shared message. +// + +ppdcMessage::ppdcMessage(const char *i, // I - ID + const char *s) // I - Text + : ppdcShared() +{ + PPDC_NEW; + + id = new ppdcString(i); + string = new ppdcString(s); +} + + +// +// 'ppdcMessage::~ppdcMessage()' - Destroy a shared message. +// + +ppdcMessage::~ppdcMessage() +{ + PPDC_DELETE; + + id->release(); + string->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-option.cxx b/ppdc/ppdc-option.cxx new file mode 100644 index 0000000000..c495264ba6 --- /dev/null +++ b/ppdc/ppdc-option.cxx @@ -0,0 +1,129 @@ +// +// "$Id$" +// +// Option class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcOption::ppdcOption() - Copy a new option. +// ppdcOption::~ppdcOption() - Destroy an option. +// ppdcOption::find_choice() - Find an option choice. +// ppdcOption::set_defchoice() - Set the default choice. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcOption::ppdcOption()' - Create a new option. +// + +ppdcOption::ppdcOption(ppdcOptType ot, // I - Option type + const char *n, // I - Option name + const char *t, // I - Option text + ppdcOptSection s, // I - Section + float o) // I - Ordering number + : ppdcShared() +{ + PPDC_NEW; + + type = ot; + name = new ppdcString(n); + text = new ppdcString(t); + section = s; + order = o; + choices = new ppdcArray(); + defchoice = 0; +} + + +// +// 'ppdcOption::ppdcOption()' - Copy a new option. +// + +ppdcOption::ppdcOption(ppdcOption *o) // I - Template option +{ + PPDC_NEW; + + o->name->retain(); + o->text->retain(); + if (o->defchoice) + o->defchoice->retain(); + + type = o->type; + name = o->name; + text = o->text; + section = o->section; + order = o->order; + choices = new ppdcArray(o->choices); + defchoice = o->defchoice; +} + + +// +// 'ppdcOption::~ppdcOption()' - Destroy an option. +// + +ppdcOption::~ppdcOption() +{ + PPDC_DELETE; + + name->release(); + text->release(); + if (defchoice) + defchoice->release(); + choices->release(); +} + + +// +// 'ppdcOption::find_choice()' - Find an option choice. +// + +ppdcChoice * // O - Choice or NULL +ppdcOption::find_choice(const char *n) // I - Name of choice +{ + ppdcChoice *c; // Current choice + + + for (c = (ppdcChoice *)choices->first(); c; c = (ppdcChoice *)choices->next()) + if (!strcasecmp(n, c->name->value)) + return (c); + + return (0); +} + + +// +// 'ppdcOption::set_defchoice()' - Set the default choice. +// + +void +ppdcOption::set_defchoice(ppdcChoice *c) // I - Choice +{ + if (defchoice) + defchoice->release(); + + if (c->name) + c->name->retain(); + + defchoice = c->name; +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-private.h b/ppdc/ppdc-private.h new file mode 100644 index 0000000000..04ae2ada91 --- /dev/null +++ b/ppdc/ppdc-private.h @@ -0,0 +1,42 @@ +// +// "$Id$" +// +// Private definitions for the CUPS PPD Compiler. +// +// Copyright 2009 by Apple Inc. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// + +#ifndef _PPDC_PRIVATE_H_ +# define _PPDC_PRIVATE_H_ + +// +// Include necessary headers... +// + +# include "ppdc.h" +# include +# include +# include + + +// +// Macros... +// + +# define PPDC_NEW DEBUG_printf(("%s: %p new", class_name(), this)) +# define PPDC_NEWVAL(s) DEBUG_printf(("%s(\"%s\"): %p new", class_name(), s, this)) +# define PPDC_DELETE DEBUG_printf(("%s: %p delete", class_name(), this)) +# define PPDC_DELETEVAL(s) DEBUG_printf(("%s(\"%s\"): %p delete", class_name(), s, this)) + + +#endif // !_PPDC_PRIVATE_H_ + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-profile.cxx b/ppdc/ppdc-profile.cxx new file mode 100644 index 0000000000..90625f423d --- /dev/null +++ b/ppdc/ppdc-profile.cxx @@ -0,0 +1,65 @@ +// +// "$Id$" +// +// Color profile class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcProfile::ppdcProfile() - Create a color profile. +// ppdcProfile::~ppdcProfile() - Destroy a color profile. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcProfile::ppdcProfile()' - Create a color profile. +// + +ppdcProfile::ppdcProfile(const char *r, // I - Resolution name + const char *m, // I - Media type name + float d, // I - Density + float g, // I - Gamma + const float *p) // I - 3x3 transform matrix + : ppdcShared() +{ + PPDC_NEW; + + resolution = new ppdcString(r); + media_type = new ppdcString(m); + density = d; + gamma = g; + + memcpy(profile, p, sizeof(profile)); +} + + +// +// 'ppdcProfile::~ppdcProfile()' - Destroy a color profile. +// + +ppdcProfile::~ppdcProfile() +{ + PPDC_DELETE; + + resolution->release(); + media_type->release(); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-shared.cxx b/ppdc/ppdc-shared.cxx new file mode 100644 index 0000000000..0c99c08597 --- /dev/null +++ b/ppdc/ppdc-shared.cxx @@ -0,0 +1,88 @@ +// +// "$Id$" +// +// Shared data class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcShared::ppdcShared() - Create shared data. +// ppdcShared::~ppdcShared() - Destroy shared data. +// ppdcShared::release() - Decrement the use count and delete as needed. +// ppdcShared::retain() - Increment the use count for this data. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcShared::ppdcShared()' - Create shared data. +// + +ppdcShared::ppdcShared() +{ + use = 1; +} + + +// +// 'ppdcShared::~ppdcShared()' - Destroy shared data. +// + +ppdcShared::~ppdcShared() +{ +} + + +// +// 'ppdcShared::release()' - Decrement the use count and delete as needed. +// + +void +ppdcShared::release(void) +{ + DEBUG_printf(("%s: %p release use=%d", class_name(), this, use)); + + use --; + +#ifdef DEBUG + if (use < 0) + { + fprintf(stderr, "ERROR: Over-release of %s: %p\n", class_name(), this); + abort(); + } +#endif /* DEBUG */ + + if (use == 0) + delete this; +} + + +// +// 'ppdcShared::retain()' - Increment the use count for this data. +// + +void +ppdcShared::retain() +{ + use ++; + + DEBUG_printf(("%s: %p retain use=%d", class_name(), this, use)); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-source.cxx b/ppdc/ppdc-source.cxx new file mode 100644 index 0000000000..84f5725400 --- /dev/null +++ b/ppdc/ppdc-source.cxx @@ -0,0 +1,3901 @@ +// +// "$Id$" +// +// Source class for the CUPS PPD Compiler. +// +// Copyright 2007-2010 by Apple Inc. +// Copyright 2002-2007 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcSource::ppdcSource() - Load a driver source file. +// ppdcSource::~ppdcSource() - Free a driver source file. +// ppdcSource::add_include() - Add an include directory. +// ppdcSource::find_driver() - Find a driver. +// ppdcSource::find_include() - Find an include file. +// ppdcSource::find_po() - Find a message catalog for the given +// locale... +// ppdcSource::find_size() - Find a media size. +// ppdcSource::find_variable() - Find a variable. +// ppdcSource::get_attr() - Get an attribute. +// ppdcSource::get_boolean() - Get a boolean value. +// ppdcSource::get_choice() - Get a choice. +// ppdcSource::get_color_model() - Get an old-style color model option. +// ppdcSource::get_color_order() - Get an old-style color order value. +// ppdcSource::get_color_profile() - Get a color profile definition. +// ppdcSource::get_color_space() - Get an old-style colorspace value. +// ppdcSource::get_constraint() - Get a constraint. +// ppdcSource::get_custom_size() - Get a custom media size definition from +// a file. +// ppdcSource::get_duplex() - Get a duplex option. +// ppdcSource::get_filter() - Get a filter. +// ppdcSource::get_float() - Get a single floating-point number. +// ppdcSource::get_font() - Get a font definition. +// ppdcSource::get_generic() - Get a generic old-style option. +// ppdcSource::get_group() - Get an option group. +// ppdcSource::get_installable() - Get an installable option. +// ppdcSource::get_integer() - Get an integer value from a file. +// ppdcSource::get_measurement() - Get a measurement value. +// ppdcSource::get_option() - Get an option definition. +// ppdcSource::get_po() - Get a message catalog. +// ppdcSource::get_resolution() - Get an old-style resolution option. +// ppdcSource::get_simple_profile() - Get a simple color profile definition. +// ppdcSource::get_size() - Get a media size definition from a file. +// ppdcSource::get_token() - Get a token from a file. +// ppdcSource::get_variable() - Get a variable definition. +// ppdcSource::quotef() - Write a formatted, quoted string... +// ppdcSource::read_file() - Read a driver source file. +// ppdcSource::scan_file() - Scan a driver source file. +// ppdcSource::set_variable() - Set a variable. +// ppdcSource::write_file() - Write the current source data to a file. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include +#include +#include +#include +#include +#include "data/epson.h" +#include "data/escp.h" +#include "data/hp.h" +#include "data/label.h" +#include "data/pcl.h" +#ifndef WIN32 +# include +#endif // !WIN32 + + +// +// Class globals... +// + +ppdcArray *ppdcSource::includes = 0; +const char *ppdcSource::driver_types[] = + { + "custom", + "ps", + "escp", + "pcl", + "label", + "epson", + "hp" + }; + + +// +// 'ppdcSource::ppdcSource()' - Load a driver source file. +// + +ppdcSource::ppdcSource(const char *f, // I - File to read + cups_file_t *ffp)// I - File pointer to use + : ppdcShared() +{ + PPDC_NEW; + + filename = new ppdcString(f); + base_fonts = new ppdcArray(); + drivers = new ppdcArray(); + po_files = new ppdcArray(); + sizes = new ppdcArray(); + vars = new ppdcArray(); + cond_state = PPDC_COND_NORMAL; + cond_current = cond_stack; + cond_stack[0] = PPDC_COND_NORMAL; + + // Add standard #define variables... +#define MAKE_STRING(x) #x + + vars->add(new ppdcVariable("CUPS_VERSION", MAKE_STRING(CUPS_VERSION))); + vars->add(new ppdcVariable("CUPS_VERSION_MAJOR", MAKE_STRING(CUPS_VERSION_MAJOR))); + vars->add(new ppdcVariable("CUPS_VERSION_MINOR", MAKE_STRING(CUPS_VERSION_MINOR))); + vars->add(new ppdcVariable("CUPS_VERSION_PATCH", MAKE_STRING(CUPS_VERSION_PATCH))); + +#ifdef WIN32 + vars->add(new ppdcVariable("PLATFORM_NAME", "Windows")); + vars->add(new ppdcVariable("PLATFORM_ARCH", "X86")); + +#else + struct utsname name; // uname information + + if (!uname(&name)) + { + vars->add(new ppdcVariable("PLATFORM_NAME", name.sysname)); + vars->add(new ppdcVariable("PLATFORM_ARCH", name.machine)); + } + else + { + vars->add(new ppdcVariable("PLATFORM_NAME", "unknown")); + vars->add(new ppdcVariable("PLATFORM_ARCH", "unknown")); + } +#endif // WIN32 + + if (f) + read_file(f, ffp); +} + + +// +// 'ppdcSource::~ppdcSource()' - Free a driver source file. +// + +ppdcSource::~ppdcSource() +{ + PPDC_DELETE; + + filename->release(); + base_fonts->release(); + drivers->release(); + po_files->release(); + sizes->release(); + vars->release(); +} + + +// +// 'ppdcSource::add_include()' - Add an include directory. +// + +void +ppdcSource::add_include(const char *d) // I - Include directory +{ + if (!d) + return; + + if (!includes) + includes = new ppdcArray(); + + includes->add(new ppdcString(d)); +} + + +// +// 'ppdcSource::find_driver()' - Find a driver. +// + +ppdcDriver * // O - Driver +ppdcSource::find_driver(const char *f) // I - Driver file name +{ + ppdcDriver *d; // Current driver + + + for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next()) + if (!strcasecmp(f, d->pc_file_name->value)) + return (d); + + return (NULL); +} + + +// +// 'ppdcSource::find_include()' - Find an include file. +// + +char * // O - Found path or NULL +ppdcSource::find_include( + const char *f, // I - Include filename + const char *base, // I - Current directory + char *n, // I - Path buffer + int nlen) // I - Path buffer length +{ + ppdcString *dir; // Include directory + char temp[1024], // Temporary path + *ptr; // Pointer to end of path + + + // Range check input... + if (!f || !*f || !n || nlen < 2) + return (0); + + // Check the first character to see if we have or "name"... + if (*f == '<') + { + // Remove the surrounding <> from the name... + strlcpy(temp, f + 1, sizeof(temp)); + ptr = temp + strlen(temp) - 1; + + if (*ptr != '>') + { + _cupsLangPrintf(stderr, + _("ppdc: Invalid #include/#po filename \"%s\"!\n"), n); + return (0); + } + + *ptr = '\0'; + f = temp; + } + else + { + // Check for the local file relative to the current directory... + if (base && *base && f[0] != '/') + snprintf(n, nlen, "%s/%s", base, f); + else + strlcpy(n, f, nlen); + + if (!access(n, 0)) + return (n); + else if (*f == '/') + { + // Absolute path that doesn't exist... + return (0); + } + } + + // Search the include directories, if any... + if (includes) + { + for (dir = (ppdcString *)includes->first(); dir; dir = (ppdcString *)includes->next()) + { + snprintf(n, nlen, "%s/%s", dir->value, f); + if (!access(n, 0)) + return (n); + } + } + + // Search the standard include directories... + _cups_globals_t *cg = _cupsGlobals(); // Global data + + snprintf(n, nlen, "%s/ppdc/%s", cg->cups_datadir, f); + if (!access(n, 0)) + return (n); + + snprintf(n, nlen, "%s/po/%s", cg->cups_datadir, f); + if (!access(n, 0)) + return (n); + else + return (0); +} + + +// +// 'ppdcSource::find_po()' - Find a message catalog for the given locale... +// + +ppdcCatalog * // O - Message catalog or NULL +ppdcSource::find_po(const char *l) // I - Locale name +{ + ppdcCatalog *cat; // Current message catalog + + + for (cat = (ppdcCatalog *)po_files->first(); + cat; + cat = (ppdcCatalog *)po_files->next()) + if (!strcasecmp(l, cat->locale->value)) + return (cat); + + return (NULL); +} + + +// +// 'ppdcSource::find_size()' - Find a media size. +// + +ppdcMediaSize * // O - Size +ppdcSource::find_size(const char *s) // I - Size name +{ + ppdcMediaSize *m; // Current media size + + + for (m = (ppdcMediaSize *)sizes->first(); m; m = (ppdcMediaSize *)sizes->next()) + if (!strcasecmp(s, m->name->value)) + return (m); + + return (NULL); +} + + +// +// 'ppdcSource::find_variable()' - Find a variable. +// + +ppdcVariable * // O - Variable +ppdcSource::find_variable(const char *n)// I - Variable name +{ + ppdcVariable *v; // Current variable + + + for (v = (ppdcVariable *)vars->first(); v; v = (ppdcVariable *)vars->next()) + if (!strcasecmp(n, v->name->value)) + return (v); + + return (NULL); +} + + +// +// 'ppdcSource::get_attr()' - Get an attribute. +// + +ppdcAttr * // O - Attribute +ppdcSource::get_attr(ppdcFile *fp, // I - File to read + bool loc) // I - Localize this attribute? +{ + char name[1024], // Name string + selector[1024], // Selector string + *text, // Text string + value[1024]; // Value string + + + // Get the attribute parameters: + // + // Attribute name selector value + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after %s on line %d of %s!\n"), + loc ? "LocAttribute" : "Attribute", fp->line, fp->filename); + return (0); + } + + if (!get_token(fp, selector, sizeof(selector))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected selector after %s on line %d of %s!\n"), + loc ? "LocAttribute" : "Attribute", fp->line, fp->filename); + return (0); + } + + if ((text = strchr(selector, '/')) != NULL) + *text++ = '\0'; + + if (!get_token(fp, value, sizeof(value))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected value after %s on line %d of %s!\n"), + loc ? "LocAttribute" : "Attribute", fp->line, fp->filename); + return (0); + } + + return (new ppdcAttr(name, selector, text, value, loc)); +} + + +// +// 'ppdcSource::get_boolean()' - Get a boolean value. +// + +int // O - Boolean value +ppdcSource::get_boolean(ppdcFile *fp) // I - File to read +{ + char buffer[256]; // String buffer + + + if (!get_token(fp, buffer, sizeof(buffer))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected boolean value on line %d of %s.\n"), + fp->line, fp->filename); + return (-1); + } + + if (!strcasecmp(buffer, "on") || + !strcasecmp(buffer, "yes") || + !strcasecmp(buffer, "true")) + return (1); + else if (!strcasecmp(buffer, "off") || + !strcasecmp(buffer, "no") || + !strcasecmp(buffer, "false")) + return (0); + else + { + _cupsLangPrintf(stderr, + _("ppdc: Bad boolean value (%s) on line %d of %s.\n"), + buffer, fp->line, fp->filename); + return (-1); + } +} + + +// +// 'ppdcSource::get_choice()' - Get a choice. +// + +ppdcChoice * // O - Choice data +ppdcSource::get_choice(ppdcFile *fp) // I - File to read +{ + char name[1024], // Name + *text, // Text + code[10240]; // Code + + + // Read a choice from the file: + // + // Choice name/text code + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected choice name/text on line %d of %s.\n"), + fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + if (!get_token(fp, code, sizeof(code))) + { + _cupsLangPrintf(stderr, _("ppdc: Expected choice code on line %d of %s.\n"), + fp->line, fp->filename); + return (NULL); + } + + // Return the new choice + return (new ppdcChoice(name, text, code)); +} + + +// +// 'ppdcSource::get_color_model()' - Get an old-style color model option. +// + +ppdcChoice * // O - Choice data +ppdcSource::get_color_model(ppdcFile *fp) + // I - File to read +{ + char name[1024], // Option name + *text, // Text option + temp[256]; // Temporary string + int color_space, // Colorspace + color_order, // Color order + compression; // Compression mode + + + // Get the ColorModel parameters: + // + // ColorModel name/text colorspace colororder compression + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name/text combination for ColorModel on " + "line %d of %s!\n"), fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected colorspace for ColorModel on line %d of " + "%s!\n"), fp->line, fp->filename); + return (NULL); + } + + if ((color_space = get_color_space(temp)) < 0) + color_space = get_integer(temp); + + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected color order for ColorModel on line %d of " + "%s!\n"), fp->line, fp->filename); + return (NULL); + } + + if ((color_order = get_color_order(temp)) < 0) + color_order = get_integer(temp); + + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected compression for ColorModel on line %d of " + "%s!\n"), fp->line, fp->filename); + return (NULL); + } + + compression = get_integer(temp); + + snprintf(temp, sizeof(temp), + "<>" + "setpagedevice", + color_space, color_order, compression); + + return (new ppdcChoice(name, text, temp)); +} + + +// +// 'ppdcSource::get_color_order()' - Get an old-style color order value. +// + +int // O - Color order value +ppdcSource::get_color_order( + const char *co) // I - Color order string +{ + if (!strcasecmp(co, "chunked") || + !strcasecmp(co, "chunky")) + return (CUPS_ORDER_CHUNKED); + else if (!strcasecmp(co, "banded")) + return (CUPS_ORDER_BANDED); + else if (!strcasecmp(co, "planar")) + return (CUPS_ORDER_PLANAR); + else + return (-1); +} + + +// +// 'ppdcSource::get_color_profile()' - Get a color profile definition. +// + +ppdcProfile * // O - Color profile +ppdcSource::get_color_profile( + ppdcFile *fp) // I - File to read +{ + char resolution[1024], // Resolution/media type + *media_type; // Media type + int i; // Looping var + float g, // Gamma value + d, // Density value + m[9]; // Transform matrix + + + // Get the ColorProfile parameters: + // + // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22 + if (!get_token(fp, resolution, sizeof(resolution))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected resolution/mediatype following " + "ColorProfile on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if ((media_type = strchr(resolution, '/')) != NULL) + *media_type++ = '\0'; + else + media_type = resolution; + + g = get_float(fp); + d = get_float(fp); + for (i = 0; i < 9; i ++) + m[i] = get_float(fp); + + return (new ppdcProfile(resolution, media_type, g, d, m)); +} + + +// +// 'ppdcSource::get_color_space()' - Get an old-style colorspace value. +// + +int // O - Colorspace value +ppdcSource::get_color_space( + const char *cs) // I - Colorspace string +{ + if (!strcasecmp(cs, "w")) + return (CUPS_CSPACE_W); + else if (!strcasecmp(cs, "rgb")) + return (CUPS_CSPACE_RGB); + else if (!strcasecmp(cs, "rgba")) + return (CUPS_CSPACE_RGBA); + else if (!strcasecmp(cs, "k")) + return (CUPS_CSPACE_K); + else if (!strcasecmp(cs, "cmy")) + return (CUPS_CSPACE_CMY); + else if (!strcasecmp(cs, "ymc")) + return (CUPS_CSPACE_YMC); + else if (!strcasecmp(cs, "cmyk")) + return (CUPS_CSPACE_CMYK); + else if (!strcasecmp(cs, "ymck")) + return (CUPS_CSPACE_YMCK); + else if (!strcasecmp(cs, "kcmy")) + return (CUPS_CSPACE_KCMY); + else if (!strcasecmp(cs, "kcmycm")) + return (CUPS_CSPACE_KCMYcm); + else if (!strcasecmp(cs, "gmck")) + return (CUPS_CSPACE_GMCK); + else if (!strcasecmp(cs, "gmcs")) + return (CUPS_CSPACE_GMCS); + else if (!strcasecmp(cs, "white")) + return (CUPS_CSPACE_WHITE); + else if (!strcasecmp(cs, "gold")) + return (CUPS_CSPACE_GOLD); + else if (!strcasecmp(cs, "silver")) + return (CUPS_CSPACE_SILVER); + else if (!strcasecmp(cs, "CIEXYZ")) + return (CUPS_CSPACE_CIEXYZ); + else if (!strcasecmp(cs, "CIELab")) + return (CUPS_CSPACE_CIELab); + else if (!strcasecmp(cs, "RGBW")) + return (CUPS_CSPACE_RGBW); + else if (!strcasecmp(cs, "ICC1")) + return (CUPS_CSPACE_ICC1); + else if (!strcasecmp(cs, "ICC2")) + return (CUPS_CSPACE_ICC2); + else if (!strcasecmp(cs, "ICC3")) + return (CUPS_CSPACE_ICC3); + else if (!strcasecmp(cs, "ICC4")) + return (CUPS_CSPACE_ICC4); + else if (!strcasecmp(cs, "ICC5")) + return (CUPS_CSPACE_ICC5); + else if (!strcasecmp(cs, "ICC6")) + return (CUPS_CSPACE_ICC6); + else if (!strcasecmp(cs, "ICC7")) + return (CUPS_CSPACE_ICC7); + else if (!strcasecmp(cs, "ICC8")) + return (CUPS_CSPACE_ICC8); + else if (!strcasecmp(cs, "ICC9")) + return (CUPS_CSPACE_ICC9); + else if (!strcasecmp(cs, "ICCA")) + return (CUPS_CSPACE_ICCA); + else if (!strcasecmp(cs, "ICCB")) + return (CUPS_CSPACE_ICCB); + else if (!strcasecmp(cs, "ICCC")) + return (CUPS_CSPACE_ICCC); + else if (!strcasecmp(cs, "ICCD")) + return (CUPS_CSPACE_ICCD); + else if (!strcasecmp(cs, "ICCE")) + return (CUPS_CSPACE_ICCE); + else if (!strcasecmp(cs, "ICCF")) + return (CUPS_CSPACE_ICCF); + else + return (-1); +} + + +// +// 'ppdcSource::get_constraint()' - Get a constraint. +// + +ppdcConstraint * // O - Constraint +ppdcSource::get_constraint(ppdcFile *fp)// I - File to read +{ + char temp[1024], // One string to rule them all + *ptr, // Pointer into string + *option1, // Constraint option 1 + *choice1, // Constraint choice 1 + *option2, // Constraint option 2 + *choice2; // Constraint choice 2 + + + // Read the UIConstaints parameter in one of the following forms: + // + // UIConstraints "*Option1 *Option2" + // UIConstraints "*Option1 Choice1 *Option2" + // UIConstraints "*Option1 *Option2 Choice2" + // UIConstraints "*Option1 Choice1 *Option2 Choice2" + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected constraints string for UIConstraints on " + "line %d of %s!\n"), fp->line, fp->filename); + return (NULL); + } + + for (ptr = temp; isspace(*ptr); ptr ++); + + if (*ptr != '*') + { + _cupsLangPrintf(stderr, + _("ppdc: Option constraint must *name on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + option1 = ptr; + + for (; *ptr && !isspace(*ptr); ptr ++); + for (; isspace(*ptr); *ptr++ = '\0'); + + if (*ptr != '*') + { + choice1 = ptr; + + for (; *ptr && !isspace(*ptr); ptr ++); + for (; isspace(*ptr); *ptr++ = '\0'); + } + else + choice1 = NULL; + + if (*ptr != '*') + { + _cupsLangPrintf(stderr, + _("ppdc: Expected two option names on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + option2 = ptr; + + for (; *ptr && !isspace(*ptr); ptr ++); + for (; isspace(*ptr); *ptr++ = '\0'); + + if (*ptr) + choice2 = ptr; + else + choice2 = NULL; + + return (new ppdcConstraint(option1, choice1, option2, choice2)); +} + + +// +// 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file. +// + +ppdcMediaSize * // O - Media size +ppdcSource::get_custom_size(ppdcFile *fp) + // I - File to read +{ + char name[1024], // Name + *text, // Text + size_code[10240], // PageSize code + region_code[10240]; // PageRegion + float width, // Width + length, // Length + left, // Left margin + bottom, // Bottom margin + right, // Right margin + top; // Top margin + + + // Get the name, text, width, length, margins, and code: + // + // CustomMedia name/text width length left bottom right top size-code region-code + if (!get_token(fp, name, sizeof(name))) + return (NULL); + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + if ((width = get_measurement(fp)) < 0.0f) + return (NULL); + + if ((length = get_measurement(fp)) < 0.0f) + return (NULL); + + if ((left = get_measurement(fp)) < 0.0f) + return (NULL); + + if ((bottom = get_measurement(fp)) < 0.0f) + return (NULL); + + if ((right = get_measurement(fp)) < 0.0f) + return (NULL); + + if ((top = get_measurement(fp)) < 0.0f) + return (NULL); + + if (!get_token(fp, size_code, sizeof(size_code))) + return (NULL); + + if (!get_token(fp, region_code, sizeof(region_code))) + return (NULL); + + // Return the new media size... + return (new ppdcMediaSize(name, text, width, length, left, bottom, + right, top, size_code, region_code)); +} + + +// +// 'ppdcSource::get_duplex()' - Get a duplex option. +// + +void +ppdcSource::get_duplex(ppdcFile *fp, // I - File to read from + ppdcDriver *d) // I - Current driver +{ + char temp[256]; // Duplex keyword + ppdcAttr *attr; // cupsFlipDuplex attribute + ppdcGroup *g; // Current group + ppdcOption *o; // Duplex option + + + // Duplex {boolean|none|normal|flip} + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected duplex type after Duplex on line %d of " + "%s!\n"), fp->line, fp->filename); + return; + } + + if (cond_state) + return; + + if (!strcasecmp(temp, "none") || !strcasecmp(temp, "false") || + !strcasecmp(temp, "no") || !strcasecmp(temp, "off")) + { + g = d->find_group("General"); + if ((o = g->find_option("Duplex")) != NULL) + g->options->remove(o); + + for (attr = (ppdcAttr *)d->attrs->first(); + attr; + attr = (ppdcAttr *)d->attrs->next()) + if (!strcmp(attr->name->value, "cupsFlipDuplex")) + { + d->attrs->remove(attr); + break; + } + } + else if (!strcasecmp(temp, "normal") || !strcasecmp(temp, "true") || + !strcasecmp(temp, "yes") || !strcasecmp(temp, "on") || + !strcasecmp(temp, "flip") || !strcasecmp(temp, "rotated") || + !strcasecmp(temp, "manualtumble")) + { + g = d->find_group("General"); + o = g->find_option("Duplex"); + + if (!o) + { + o = new ppdcOption(PPDC_PICKONE, "Duplex", "2-Sided Printing", + !strcasecmp(temp, "flip") ? PPDC_SECTION_PAGE : + PPDC_SECTION_ANY, 10.0f); + o->add_choice(new ppdcChoice("None", "Off (1-Sided)", + "<>setpagedevice")); + o->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)", + "<>setpagedevice")); + o->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)", + "<>setpagedevice")); + + g->add_option(o); + } + + for (attr = (ppdcAttr *)d->attrs->first(); + attr; + attr = (ppdcAttr *)d->attrs->next()) + if (!strcmp(attr->name->value, "cupsFlipDuplex")) + { + if (strcasecmp(temp, "flip")) + d->attrs->remove(attr); + break; + } + + if (!strcasecmp(temp, "flip") && !attr) + d->add_attr(new ppdcAttr("cupsFlipDuplex", NULL, NULL, "true")); + + for (attr = (ppdcAttr *)d->attrs->first(); + attr; + attr = (ppdcAttr *)d->attrs->next()) + if (!strcmp(attr->name->value, "cupsBackSide")) + { + d->attrs->remove(attr); + break; + } + + if (!strcasecmp(temp, "flip")) + d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "Flipped")); + else if (!strcasecmp(temp, "rotated")) + d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "Rotated")); + else if (!strcasecmp(temp, "manualtumble")) + d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "ManualTumble")); + else + d->add_attr(new ppdcAttr("cupsBackSide", NULL, NULL, "Normal")); + } + else + _cupsLangPrintf(stderr, + _("ppdc: Unknown duplex type \"%s\" on line %d of %s!\n"), + temp, fp->line, fp->filename); +} + + +// +// 'ppdcSource::get_filter()' - Get a filter. +// + +ppdcFilter * // O - Filter +ppdcSource::get_filter(ppdcFile *fp) // I - File to read +{ + char type[1024], // MIME type + program[1024], // Filter program + *ptr; // Pointer into MIME type + int cost; // Relative cost + + + // Read filter parameters in one of the following formats: + // + // Filter "type cost program" + // Filter type cost program + + if (!get_token(fp, type, sizeof(type))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected a filter definition on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if ((ptr = strchr(type, ' ')) != NULL) + { + // Old-style filter definition in one string... + *ptr++ = '\0'; + cost = strtol(ptr, &ptr, 10); + + while (isspace(*ptr)) + ptr ++; + + strcpy(program, ptr); + } + else + { + cost = get_integer(fp); + + if (!get_token(fp, program, sizeof(program))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected a program name on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + } + + if (!type[0]) + { + _cupsLangPrintf(stderr, + _("ppdc: Invalid empty MIME type for filter on line %d of " + "%s!\n"), fp->line, fp->filename); + return (NULL); + } + + if (cost < 0 || cost > 200) + { + _cupsLangPrintf(stderr, + _("ppdc: Invalid cost for filter on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if (!program[0]) + { + _cupsLangPrintf(stderr, + _("ppdc: Invalid empty program name for filter on line %d " + "of %s!\n"), fp->line, fp->filename); + return (NULL); + } + + return (new ppdcFilter(type, program, cost)); +} + + +// +// 'ppdcSource::get_float()' - Get a single floating-point number. +// + +float // O - Number +ppdcSource::get_float(ppdcFile *fp) // I - File to read +{ + char temp[256], // String buffer + *ptr; // Pointer into buffer + float val; // Floating point value + + + // Get the number from the file and range-check... + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, _("ppdc: Expected real number on line %d of %s!\n"), + fp->line, fp->filename); + return (-1.0f); + } + + val = (float)strtod(temp, &ptr); + + if (*ptr) + { + _cupsLangPrintf(stderr, + _("ppdc: Unknown trailing characters in real number \"%s\" " + "on line %d of %s!\n"), temp, fp->line, fp->filename); + return (-1.0f); + } + else + return (val); +} + + +// +// 'ppdcSource::get_font()' - Get a font definition. +// + +ppdcFont * // O - Font data +ppdcSource::get_font(ppdcFile *fp) // I - File to read +{ + char name[256], // Font name + encoding[256], // Font encoding + version[256], // Font version + charset[256], // Font charset + temp[256]; // Font status string + ppdcFontStatus status; // Font status enumeration + + + // Read font parameters as follows: + // + // Font * + // Font name encoding version charset status + // %font name encoding version charset status + // + // "Name" is the PostScript font name. + // + // "Encoding" is the default encoding of the font: Standard, ISOLatin1, + // Special, Expert, ExpertSubset, etc. + // + // "Version" is the version number string. + // + // "Charset" specifies the characters that are included in the font: + // Standard, Special, Expert, Adobe-Identity, etc. + // + // "Status" is the keyword ROM or Disk. + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after Font on line %d of %s!\n"), + fp->line, fp->filename); + return (0); + } + + if (!strcmp(name, "*")) + { + // Include all base fonts... + encoding[0] = '\0'; + version[0] = '\0'; + charset[0] = '\0'; + status = PPDC_FONT_ROM; + } + else + { + // Load a full font definition... + if (!get_token(fp, encoding, sizeof(encoding))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected encoding after Font on line %d of " + "%s!\n"), fp->line, fp->filename); + return (0); + } + + if (!get_token(fp, version, sizeof(version))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected version after Font on line %d of " + "%s!\n"), fp->line, fp->filename); + return (0); + } + + if (!get_token(fp, charset, sizeof(charset))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected charset after Font on line %d of " + "%s!\n"), fp->line, fp->filename); + return (0); + } + + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected status after Font on line %d of %s!\n"), + fp->line, fp->filename); + return (0); + } + + if (!strcasecmp(temp, "ROM")) + status = PPDC_FONT_ROM; + else if (!strcasecmp(temp, "Disk")) + status = PPDC_FONT_DISK; + else + { + _cupsLangPrintf(stderr, + _("ppdc: Bad status keyword %s on line %d of %s!\n"), + temp, fp->line, fp->filename); + return (0); + } + } + +// printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp); + + return (new ppdcFont(name, encoding, version, charset, status)); +} + + +// +// 'ppdcSource::get_generic()' - Get a generic old-style option. +// + +ppdcChoice * // O - Choice data +ppdcSource::get_generic(ppdcFile *fp, // I - File to read + const char *keyword, + // I - Keyword name + const char *tattr, + // I - Text attribute + const char *nattr) + // I - Numeric attribute +{ + char name[1024], // Name + *text, // Text + command[256]; // Command string + int val; // Numeric value + + + // Read one of the following parameters: + // + // Foo name/text + // Foo integer name/text + if (nattr) + val = get_integer(fp); + else + val = 0; + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name/text after %s on line %d of %s!\n"), + keyword, fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + if (nattr) + { + if (tattr) + snprintf(command, sizeof(command), + "<>setpagedevice", + tattr, name, nattr, val); + else + snprintf(command, sizeof(command), + "<>setpagedevice", + nattr, val); + } + else + snprintf(command, sizeof(command), + "<>setpagedevice", + tattr, name); + + return (new ppdcChoice(name, text, command)); +} + + +// +// 'ppdcSource::get_group()' - Get an option group. +// + +ppdcGroup * // O - Group +ppdcSource::get_group(ppdcFile *fp, // I - File to read + ppdcDriver *d) // I - Printer driver +{ + char name[1024], // UI name + *text; // UI text + ppdcGroup *g; // Group + + + // Read the Group parameters: + // + // Group name/text + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected group name/text on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + // See if the group already exists... + if ((g = d->find_group(name)) == NULL) + { + // Nope, add a new one... + g = new ppdcGroup(name, text); + } + + return (g); +} + + +// +// 'ppdcSource::get_installable()' - Get an installable option. +// + +ppdcOption * // O - Option +ppdcSource::get_installable(ppdcFile *fp) + // I - File to read +{ + char name[1024], // Name for installable option + *text; // Text for installable option + ppdcOption *o; // Option + + + // Read the parameter for an installable option: + // + // Installable name/text + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name/text after Installable on line %d " + "of %s!\n"), fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + // Create the option... + o = new ppdcOption(PPDC_BOOLEAN, name, text, PPDC_SECTION_ANY, 10.0f); + + // Add the false and true choices... + o->add_choice(new ppdcChoice("False", "Not Installed", "")); + o->add_choice(new ppdcChoice("True", "Installed", "")); + + return (o); +} + + +// +// 'ppdcSource::get_integer()' - Get an integer value from a string. +// + +#define PPDC_XX -1 // Bad +#define PPDC_EQ 0 // == +#define PPDC_NE 1 // != +#define PPDC_LT 2 // < +#define PPDC_LE 3 // <= +#define PPDC_GT 4 // > +#define PPDC_GE 5 // >= + +int // O - Integer value +ppdcSource::get_integer(const char *v) // I - Value string +{ + long val; // Value + long temp, // Temporary value + temp2; // Second temporary value + char *newv, // New value string pointer + ch; // Temporary character + ppdcVariable *var; // #define variable + int compop; // Comparison operator + + + // Parse the value string... + if (!v) + return (-1); + + if (isdigit(*v & 255) || *v == '-' || *v == '+') + { + // Return a simple integer value + val = strtol(v, (char **)&v, 0); + if (*v || val == LONG_MIN) + return (-1); + else + return ((int)val); + } + else if (*v == '(') + { + // Evaluate and expression in any of the following formats: + // + // (number number ... number) Bitwise OR of all numbers + // (NAME == value) 1 if equal, 0 otherwise + // (NAME != value) 1 if not equal, 0 otherwise + // (NAME < value) 1 if less than, 0 otherwise + // (NAME <= value) 1 if less than or equal, 0 otherwise + // (NAME > value) 1 if greater than, 0 otherwise + // (NAME >= value) 1 if greater than or equal, 0 otherwise + + v ++; + val = 0; + + while (*v && *v != ')') + { + // Skip leading whitespace... + while (*v && isspace(*v & 255)) + v ++; + + if (!*v || *v == ')') + break; + + if (isdigit(*v & 255) || *v == '-' || *v == '+') + { + // Bitwise OR a number... + temp = strtol(v, &newv, 0); + + if (!*newv || newv == v || !(isspace(*newv) || *newv == ')') || + temp == LONG_MIN) + return (-1); + } + else + { + // NAME logicop value + for (newv = (char *)v + 1; + *newv && (isalnum(*newv & 255) || *newv == '_'); + newv ++); + + ch = *newv; + *newv = '\0'; + + if ((var = find_variable(v)) != NULL) + { + if (!var->value || !var->value->value || !var->value->value[0]) + temp = 0; + else if (isdigit(var->value->value[0] & 255) || + var->value->value[0] == '-' || + var->value->value[0] == '+') + temp = strtol(var->value->value, NULL, 0); + else + temp = 1; + } + else + temp = 0; + + *newv = ch; + while (isspace(*newv & 255)) + newv ++; + + if (!strncmp(newv, "==", 2)) + { + compop = PPDC_EQ; + newv += 2; + } + else if (!strncmp(newv, "!=", 2)) + { + compop = PPDC_NE; + newv += 2; + } + else if (!strncmp(newv, "<=", 2)) + { + compop = PPDC_LE; + newv += 2; + } + else if (*newv == '<') + { + compop = PPDC_LT; + newv ++; + } + else if (!strncmp(newv, ">=", 2)) + { + compop = PPDC_GE; + newv += 2; + } + else if (*newv == '>') + { + compop = PPDC_GT; + newv ++; + } + else + compop = PPDC_XX; + + if (compop != PPDC_XX) + { + while (isspace(*newv & 255)) + newv ++; + + if (*newv == ')' || !*newv) + return (-1); + + if (isdigit(*newv & 255) || *newv == '-' || *newv == '+') + { + // Get the second number... + temp2 = strtol(newv, &newv, 0); + if (!*newv || newv == v || !(isspace(*newv) || *newv == ')') || + temp == LONG_MIN) + return (-1); + } + else + { + // Lookup the second name... + for (v = newv, newv ++; + *newv && (isalnum(*newv & 255) || *newv == '_'); + newv ++); + + ch = *newv; + *newv = '\0'; + + if ((var = find_variable(v)) != NULL) + { + if (!var->value || !var->value->value || !var->value->value[0]) + temp2 = 0; + else if (isdigit(var->value->value[0] & 255) || + var->value->value[0] == '-' || + var->value->value[0] == '+') + temp2 = strtol(var->value->value, NULL, 0); + else + temp2 = 1; + } + else + temp2 = 0; + + *newv = ch; + } + + // Do the comparison... + switch (compop) + { + case PPDC_EQ : + temp = temp == temp2; + break; + case PPDC_NE : + temp = temp != temp2; + break; + case PPDC_LT : + temp = temp < temp2; + break; + case PPDC_LE : + temp = temp <= temp2; + break; + case PPDC_GT : + temp = temp > temp2; + break; + case PPDC_GE : + temp = temp >= temp2; + break; + } + } + } + + val |= temp; + v = newv; + } + + if (*v == ')' && !v[1]) + return ((int)val); + else + return (-1); + } + else if ((var = find_variable(v)) != NULL) + { + // NAME by itself returns 1 if the #define variable is not blank and + // not "0"... + return (var->value->value && var->value->value[0] && + strcmp(var->value->value, "0")); + } + else + { + // Anything else is an error... + return (-1); + } +} + + +// +// 'ppdcSource::get_integer()' - Get an integer value from a file. +// + +int // O - Integer value +ppdcSource::get_integer(ppdcFile *fp) // I - File to read +{ + char temp[1024]; // String buffer + + + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, _("ppdc: Expected integer on line %d of %s!\n"), + fp->line, fp->filename); + return (-1); + } + else + return (get_integer(temp)); +} + + +// +// 'ppdcSource::get_measurement()' - Get a measurement value. +// + +float // O - Measurement value in points +ppdcSource::get_measurement(ppdcFile *fp) + // I - File to read +{ + char buffer[256], // Number buffer + *ptr; // Pointer into buffer + float val; // Measurement value + + + // Grab a token from the file... + if (!get_token(fp, buffer, sizeof(buffer))) + return (-1.0f); + + // Get the floating point value of "s" and skip all digits and decimal points. + val = (float)strtod(buffer, &ptr); + + // Check for a trailing unit specifier... + if (!strcasecmp(ptr, "mm")) + val *= 72.0f / 25.4f; + else if (!strcasecmp(ptr, "cm")) + val *= 72.0f / 2.54f; + else if (!strcasecmp(ptr, "m")) + val *= 72.0f / 0.0254f; + else if (!strcasecmp(ptr, "in")) + val *= 72.0f; + else if (!strcasecmp(ptr, "ft")) + val *= 72.0f * 12.0f; + else if (strcasecmp(ptr, "pt") && *ptr) + return (-1.0f); + + return (val); +} + + +// +// 'ppdcSource::get_option()' - Get an option definition. +// + +ppdcOption * // O - Option +ppdcSource::get_option(ppdcFile *fp, // I - File to read + ppdcDriver *d, // I - Printer driver + ppdcGroup *g) // I - Current group +{ + char name[1024], // UI name + *text, // UI text + type[256]; // UI type string + ppdcOptType ot; // Option type value + ppdcOptSection section; // Option section + float order; // Option order + ppdcOption *o; // Option + ppdcGroup *mg; // Matching group, if any + + + // Read the Option parameters: + // + // Option name/text type section order + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected option name/text on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + if (!get_token(fp, type, sizeof(type))) + { + _cupsLangPrintf(stderr, _("ppdc: Expected option type on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if (!strcasecmp(type, "boolean")) + ot = PPDC_BOOLEAN; + else if (!strcasecmp(type, "pickone")) + ot = PPDC_PICKONE; + else if (!strcasecmp(type, "pickmany")) + ot = PPDC_PICKMANY; + else + { + _cupsLangPrintf(stderr, + _("ppdc: Invalid option type \"%s\" on line %d of %s!\n"), + type, fp->line, fp->filename); + return (NULL); + } + + if (!get_token(fp, type, sizeof(type))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected option section on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if (!strcasecmp(type, "AnySetup")) + section = PPDC_SECTION_ANY; + else if (!strcasecmp(type, "DocumentSetup")) + section = PPDC_SECTION_DOCUMENT; + else if (!strcasecmp(type, "ExitServer")) + section = PPDC_SECTION_EXIT; + else if (!strcasecmp(type, "JCLSetup")) + section = PPDC_SECTION_JCL; + else if (!strcasecmp(type, "PageSetup")) + section = PPDC_SECTION_PAGE; + else if (!strcasecmp(type, "Prolog")) + section = PPDC_SECTION_PROLOG; + else + { + _cupsLangPrintf(stderr, + _("ppdc: Invalid option section \"%s\" on line %d of " + "%s!\n"), type, fp->line, fp->filename); + return (NULL); + } + + order = get_float(fp); + + // See if the option already exists... + if ((o = d->find_option_group(name, &mg)) == NULL) + { + // Nope, add a new one... + o = new ppdcOption(ot, name, text, section, order); + } + else if (o->type != ot) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s redefined with a different type on line " + "%d of %s!\n"), name, fp->line, fp->filename); + return (NULL); + } + else if (g != mg) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s defined in two different groups on line " + "%d of %s!\n"), name, fp->line, fp->filename); + return (NULL); + } + + return (o); +} + + +// +// 'ppdcSource::get_po()' - Get a message catalog. +// + +ppdcCatalog * // O - Message catalog +ppdcSource::get_po(ppdcFile *fp) // I - File to read +{ + char locale[32], // Locale name + poname[1024], // Message catalog filename + basedir[1024], // Base directory + *baseptr, // Pointer into directory + pofilename[1024]; // Full filename of message catalog + ppdcCatalog *cat; // Message catalog + + + // Read the #po parameters: + // + // #po locale "filename.po" + if (!get_token(fp, locale, sizeof(locale))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected locale after #po on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if (!get_token(fp, poname, sizeof(poname))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected filename after #po %s on line %d of " + "%s!\n"), locale, fp->line, fp->filename); + return (NULL); + } + + // See if the locale is already loaded... + if (find_po(locale)) + { + _cupsLangPrintf(stderr, + _("ppdc: Duplicate #po for locale %s on line %d of %s!\n"), + locale, fp->line, fp->filename); + return (NULL); + } + + // Figure out the current directory... + strlcpy(basedir, fp->filename, sizeof(basedir)); + + if ((baseptr = strrchr(basedir, '/')) != NULL) + *baseptr = '\0'; + else + strcpy(basedir, "."); + + // Find the po file... + pofilename[0] = '\0'; + + if (!poname[0] || + find_include(poname, basedir, pofilename, sizeof(pofilename))) + { + // Found it, so load it... + cat = new ppdcCatalog(locale, pofilename); + + // Reset the filename to the name supplied by the user... + cat->filename->release(); + cat->filename = new ppdcString(poname); + + // Return the catalog... + return (cat); + } + else + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to find #po file %s on line %d of %s!\n"), + poname, fp->line, fp->filename); + return (NULL); + } +} + + +// +// 'ppdcSource::get_resolution()' - Get an old-style resolution option. +// + +ppdcChoice * // O - Choice data +ppdcSource::get_resolution(ppdcFile *fp)// I - File to read +{ + char name[1024], // Name + *text, // Text + temp[256], // Temporary string + command[256], // Command string + *commptr; // Pointer into command + int xdpi, ydpi, // X + Y resolution + color_order, // Color order + color_space, // Colorspace + compression, // Compression mode + depth, // Bits per color + row_count, // Row count + row_feed, // Row feed + row_step; // Row step/interval + + + // Read the resolution parameters: + // + // Resolution colorspace bits row-count row-feed row-step name/text + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected override field after Resolution on line " + "%d of %s!\n"), fp->line, fp->filename); + return (NULL); + } + + color_order = get_color_order(temp); + color_space = get_color_space(temp); + compression = get_integer(temp); + + depth = get_integer(fp); + row_count = get_integer(fp); + row_feed = get_integer(fp); + row_step = get_integer(fp); + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name/text after Resolution on line %d of " + "%s!\n"), fp->line, fp->filename); + return (NULL); + } + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + switch (sscanf(name, "%dx%d", &xdpi, &ydpi)) + { + case 0 : + _cupsLangPrintf(stderr, + _("ppdc: Bad resolution name \"%s\" on line %d of " + "%s!\n"), name, fp->line, fp->filename); + break; + case 1 : + ydpi = xdpi; + break; + } + + // Create the necessary PS commands... + snprintf(command, sizeof(command), + "<= 0) + { + snprintf(commptr, sizeof(command) - (commptr - command), + "/cupsColorOrder %d", color_order); + commptr += strlen(commptr); + } + + if (color_space >= 0) + { + snprintf(commptr, sizeof(command) - (commptr - command), + "/cupsColorSpace %d", color_space); + commptr += strlen(commptr); + } + + if (compression >= 0) + { + snprintf(commptr, sizeof(command) - (commptr - command), + "/cupsCompression %d", compression); + commptr += strlen(commptr); + } + + snprintf(commptr, sizeof(command) - (commptr - command), ">>setpagedevice"); + + // Return the new choice... + return (new ppdcChoice(name, text, command)); +} + + +// +// 'ppdcSource::get_simple_profile()' - Get a simple color profile definition. +// + +ppdcProfile * // O - Color profile +ppdcSource::get_simple_profile(ppdcFile *fp) + // I - File to read +{ + char resolution[1024], // Resolution/media type + *media_type; // Media type + float m[9]; // Transform matrix + float kd, rd, g; // Densities and gamma + float red, green, blue; // RGB adjustments + float yellow; // Yellow density + float color; // Color density values + + + // Get the SimpleColorProfile parameters: + // + // SimpleColorProfile resolution/mediatype black-density yellow-density + // red-density gamma red-adjust green-adjust blue-adjust + if (!get_token(fp, resolution, sizeof(resolution))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected resolution/mediatype following " + "SimpleColorProfile on line %d of %s!\n"), + fp->line, fp->filename); + return (NULL); + } + + if ((media_type = strchr(resolution, '/')) != NULL) + *media_type++ = '\0'; + else + media_type = resolution; + + // Collect the profile parameters... + kd = get_float(fp); + yellow = get_float(fp); + rd = get_float(fp); + g = get_float(fp); + red = get_float(fp); + green = get_float(fp); + blue = get_float(fp); + + // Build the color profile... + color = 0.5f * rd / kd - kd; + m[0] = 1.0f; // C + m[1] = color + blue; // C + M (blue) + m[2] = color - green; // C + Y (green) + m[3] = color - blue; // M + C (blue) + m[4] = 1.0f; // M + m[5] = color + red; // M + Y (red) + m[6] = yellow * (color + green); // Y + C (green) + m[7] = yellow * (color - red); // Y + M (red) + m[8] = yellow; // Y + + if (m[1] > 0.0f) + { + m[3] -= m[1]; + m[1] = 0.0f; + } + else if (m[3] > 0.0f) + { + m[1] -= m[3]; + m[3] = 0.0f; + } + + if (m[2] > 0.0f) + { + m[6] -= m[2]; + m[2] = 0.0f; + } + else if (m[6] > 0.0f) + { + m[2] -= m[6]; + m[6] = 0.0f; + } + + if (m[5] > 0.0f) + { + m[7] -= m[5]; + m[5] = 0.0f; + } + else if (m[7] > 0.0f) + { + m[5] -= m[7]; + m[7] = 0.0f; + } + + // Return the new profile... + return (new ppdcProfile(resolution, media_type, g, kd, m)); +} + + +// +// 'ppdcSource::get_size()' - Get a media size definition from a file. +// + +ppdcMediaSize * // O - Media size +ppdcSource::get_size(ppdcFile *fp) // I - File to read +{ + char name[1024], // Name + *text; // Text + float width, // Width + length; // Length + + + // Get the name, text, width, and length: + // + // #media name/text width length + if (!get_token(fp, name, sizeof(name))) + return (NULL); + + if ((text = strchr(name, '/')) != NULL) + *text++ = '\0'; + else + text = name; + + if ((width = get_measurement(fp)) < 0.0f) + return (NULL); + + if ((length = get_measurement(fp)) < 0.0f) + return (NULL); + + // Return the new media size... + return (new ppdcMediaSize(name, text, width, length, 0.0f, 0.0f, 0.0f, 0.0f)); +} + + +// +// 'ppdcSource::get_token()' - Get a token from a file. +// + +char * // O - Token string or NULL +ppdcSource::get_token(ppdcFile *fp, // I - File to read + char *buffer, // I - Buffer + int buflen) // I - Length of buffer +{ + char *bufptr, // Pointer into string buffer + *bufend; // End of string buffer + int ch, // Character from file + nextch, // Next char in file + quote, // Quote character used... + empty, // Empty input? + startline; // Start line for quote + char name[256], // Name string + *nameptr; // Name pointer + ppdcVariable *var; // Variable pointer + + + // Mark the beginning and end of the buffer... + bufptr = buffer; + bufend = buffer + buflen - 1; + + // Loop intil we've read a token... + quote = 0; + startline = 0; + empty = 1; + + while ((ch = fp->get()) != EOF) + { + if (isspace(ch) && !quote) + { + if (empty) + continue; + else + break; + } + else if (ch == '$') + { + // Variable substitution + empty = 0; + + for (nameptr = name; (ch = fp->peek()) != EOF;) + { + if (!isalnum(ch) && ch != '_') + break; + else if (nameptr < (name + sizeof(name) - 1)) + *nameptr++ = fp->get(); + } + + if (nameptr == name) + { + // Just substitute this character... + if (ch == '$') + { + // $$ = $ + if (bufptr < bufend) + *bufptr++ = fp->get(); + } + else + { + // $ch = $ch + _cupsLangPrintf(stderr, + _("ppdc: Bad variable substitution ($%c) on line %d " + "of %s.\n"), ch, fp->line, fp->filename); + + if (bufptr < bufend) + *bufptr++ = '$'; + } + } + else + { + // Substitute the variable value... + *nameptr = '\0'; + var = find_variable(name); + if (var) + { + strlcpy(bufptr, var->value->value, bufend - bufptr + 1); + bufptr += strlen(bufptr); + } + else + { + if (!(cond_state & PPDC_COND_SKIP)) + _cupsLangPrintf(stderr, + _("ppdc: Undefined variable (%s) on line %d of " + "%s.\n"), name, fp->line, fp->filename); + + snprintf(bufptr, bufend - bufptr + 1, "$%s", name); + bufptr += strlen(bufptr); + } + } + } + else if (ch == '/' && !quote) + { + // Possibly a comment... + nextch = fp->peek(); + + if (nextch == '*') + { + // C comment... + fp->get(); + ch = fp->get(); + while ((nextch = fp->get()) != EOF) + { + if (ch == '*' && nextch == '/') + break; + + ch = nextch; + } + + if (nextch == EOF) + break; + } + else if (nextch == '/') + { + // C++ comment... + while ((nextch = fp->get()) != EOF) + if (nextch == '\n') + break; + + if (nextch == EOF) + break; + } + else + { + // Not a comment... + empty = 0; + + if (bufptr < bufend) + *bufptr++ = ch; + } + } + else if (ch == '\'' || ch == '\"') + { + empty = 0; + + if (quote == ch) + { + // Ending the current quoted string... + quote = 0; + } + else if (quote) + { + // Insert the opposing quote char... + if (bufptr < bufend) + *bufptr++ = ch; + } + else + { + // Start a new quoted string... + startline = fp->line; + quote = ch; + } + } + else if ((ch == '(' || ch == '<') && !quote) + { + empty = 0; + quote = ch; + startline = fp->line; + + if (bufptr < bufend) + *bufptr++ = ch; + } + else if ((ch == ')' && quote == '(') || (ch == '>' && quote == '<')) + { + quote = 0; + + if (bufptr < bufend) + *bufptr++ = ch; + } + else if (ch == '\\') + { + empty = 0; + + if ((ch = fp->get()) == EOF) + break; + + if (bufptr < bufend) + *bufptr++ = ch; + } + else if (bufptr < bufend) + { + empty = 0; + + *bufptr++ = ch; + + if ((ch == '{' || ch == '}') && !quote) + break; + } + } + + if (quote) + { + _cupsLangPrintf(stderr, + _("ppdc: Unterminated string starting with %c on line %d " + "of %s!\n"), quote, startline, fp->filename); + return (NULL); + } + + if (empty) + return (NULL); + else + { + *bufptr = '\0'; +// puts(buffer); + return (buffer); + } +} + + +// +// 'ppdcSource::get_variable()' - Get a variable definition. +// + +ppdcVariable * // O - Variable +ppdcSource::get_variable(ppdcFile *fp) // I - File to read +{ + char name[1024], // Name + value[1024]; // Value + + + // Get the name and value: + // + // #define name value + if (!get_token(fp, name, sizeof(name))) + return (NULL); + + if (!get_token(fp, value, sizeof(value))) + return (NULL); + + // Set the variable... + return (set_variable(name, value)); +} + + +// +// 'ppdcSource::quotef()' - Write a formatted, quoted string... +// + +int // O - Number bytes on success, -1 on failure +ppdcSource::quotef(cups_file_t *fp, // I - File to write to + const char *format, // I - Printf-style format string + ...) // I - Additional args as needed +{ + va_list ap; // Pointer to additional arguments + int bytes; // Bytes written + char 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 fprintf() + char *s; // Pointer to string + int slen; // Length of string + int i; // Looping var + + + // Range check input... + if (!fp || !format) + return (-1); + + // Loop through the format string, formatting as needed... + va_start(ap, format); + + bytes = 0; + + while (*format) + { + if (*format == '%') + { + bufformat = format; + format ++; + + if (*format == '%') + { + cupsFilePutChar(fp, *format++); + bytes ++; + 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) > (int)sizeof(tformat)) + break; + + strncpy(tformat, bufformat, format - bufformat); + tformat[format - bufformat] = '\0'; + + bytes += cupsFilePrintf(fp, tformat, va_arg(ap, double)); + break; + + case 'B' : // Integer formats + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((format - bufformat + 1) > (int)sizeof(tformat)) + break; + + strncpy(tformat, bufformat, format - bufformat); + tformat[format - bufformat] = '\0'; + + bytes += cupsFilePrintf(fp, tformat, va_arg(ap, int)); + break; + + case 'p' : // Pointer value + if ((format - bufformat + 1) > (int)sizeof(tformat)) + break; + + strncpy(tformat, bufformat, format - bufformat); + tformat[format - bufformat] = '\0'; + + bytes += cupsFilePrintf(fp, tformat, va_arg(ap, void *)); + break; + + case 'c' : // Character or character array + if (width <= 1) + { + bytes ++; + cupsFilePutChar(fp, va_arg(ap, int)); + } + else + { + cupsFileWrite(fp, va_arg(ap, char *), width); + bytes += width; + } + break; + + case 's' : // String + if ((s = va_arg(ap, char *)) == NULL) + s = (char *)"(nil)"; + + slen = strlen(s); + if (slen > width && prec != width) + width = slen; + + if (slen > width) + slen = width; + + if (sign != '-') + { + for (i = width - slen; i > 0; i --, bytes ++) + cupsFilePutChar(fp, ' '); + } + + for (i = slen; i > 0; i --, s ++, bytes ++) + { + if (*s == '\\' || *s == '\"') + { + cupsFilePutChar(fp, '\\'); + bytes ++; + } + + cupsFilePutChar(fp, *s); + } + + if (sign == '-') + { + for (i = width - slen; i > 0; i --, bytes ++) + cupsFilePutChar(fp, ' '); + } + break; + } + } + else + { + cupsFilePutChar(fp, *format++); + bytes ++; + } + } + + va_end(ap); + + // Return the number of characters written. + return (bytes); +} + + +// +// 'ppdcSource::read_file()' - Read a driver source file. +// + +void +ppdcSource::read_file(const char *f, // I - File to read + cups_file_t *ffp) // I - File pointer to use +{ + ppdcFile *fp = new ppdcFile(f, ffp); + scan_file(fp); + delete fp; + + if (cond_current != cond_stack) + _cupsLangPrintf(stderr, _("ppdc: Missing #endif at end of \"%s\"!\n"), f); +} + + +// +// 'ppdcSource::scan_file()' - Scan a driver source file. +// + +void +ppdcSource::scan_file(ppdcFile *fp, // I - File to read + ppdcDriver *td, // I - Driver template + bool inc) // I - Including? +{ + ppdcDriver *d; // Current driver + ppdcGroup *g, // Current group + *mg, // Matching group + *general, // General options group + *install; // Installable options group + ppdcOption *o; // Current option + ppdcChoice *c; // Current choice + char temp[256], // Token from file... + *ptr; // Pointer into token + int isdefault; // Default option? + + + // Initialize things as needed... + if (inc && td) + { + d = td; + d->retain(); + } + else + d = new ppdcDriver(td); + + if ((general = d->find_group("General")) == NULL) + { + general = new ppdcGroup("General", NULL); + d->add_group(general); + } + + if ((install = d->find_group("InstallableOptions")) == NULL) + { + install = new ppdcGroup("InstallableOptions", "Installable Options"); + d->add_group(install); + } + + // Loop until EOF or } + o = 0; + g = general; + + while (get_token(fp, temp, sizeof(temp))) + { + if (temp[0] == '*') + { + // Mark the next choice as the default + isdefault = 1; + + for (ptr = temp; ptr[1]; ptr ++) + *ptr = ptr[1]; + + *ptr = '\0'; + } + else + { + // Don't mark the next choice as the default + isdefault = 0; + } + + if (!strcasecmp(temp, "}")) + { + // Close this one out... + break; + } + else if (!strcasecmp(temp, "{")) + { + // Open a new child... + scan_file(fp, d); + } + else if (!strcasecmp(temp, "#if")) + { + if ((cond_current - cond_stack) >= 100) + { + _cupsLangPrintf(stderr, + _("ppdc: Too many nested #if's on line %d of %s!\n"), + fp->line, fp->filename); + break; + } + + cond_current ++; + if (get_integer(fp) > 0) + *cond_current = PPDC_COND_SATISFIED; + else + { + *cond_current = PPDC_COND_SKIP; + cond_state |= PPDC_COND_SKIP; + } + } + else if (!strcasecmp(temp, "#elif")) + { + if (cond_current == cond_stack) + { + _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s!\n"), + fp->line, fp->filename); + break; + } + + if (*cond_current & PPDC_COND_SATISFIED) + { + get_integer(fp); + *cond_current |= PPDC_COND_SKIP; + } + else if (get_integer(fp) > 0) + { + *cond_current |= PPDC_COND_SATISFIED; + *cond_current &= ~PPDC_COND_SKIP; + } + else + *cond_current |= PPDC_COND_SKIP; + + // Update the current state + int *cond_temp = cond_current; // Temporary stack pointer + + cond_state = PPDC_COND_NORMAL; + while (cond_temp > cond_stack) + if (*cond_temp & PPDC_COND_SKIP) + { + cond_state = PPDC_COND_SKIP; + break; + } + else + cond_temp --; + } + else if (!strcasecmp(temp, "#else")) + { + if (cond_current == cond_stack) + { + _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s!\n"), + fp->line, fp->filename); + break; + } + + if (*cond_current & PPDC_COND_SATISFIED) + *cond_current |= PPDC_COND_SKIP; + else + { + *cond_current |= PPDC_COND_SATISFIED; + *cond_current &= ~PPDC_COND_SKIP; + } + + // Update the current state + int *cond_temp = cond_current; // Temporary stack pointer + + cond_state = PPDC_COND_NORMAL; + while (cond_temp > cond_stack) + if (*cond_temp & PPDC_COND_SKIP) + { + cond_state = PPDC_COND_SKIP; + break; + } + else + cond_temp --; + } + else if (!strcasecmp(temp, "#endif")) + { + if (cond_current == cond_stack) + { + _cupsLangPrintf(stderr, _("ppdc: Missing #if on line %d of %s!\n"), + fp->line, fp->filename); + break; + } + + cond_current --; + + // Update the current state + int *cond_temp = cond_current; // Temporary stack pointer + + cond_state = PPDC_COND_NORMAL; + while (cond_temp > cond_stack) + if (*cond_temp & PPDC_COND_SKIP) + { + cond_state = PPDC_COND_SKIP; + break; + } + else + cond_temp --; + } + else if (!strcasecmp(temp, "#define")) + { + // Get the variable... + get_variable(fp); + } + else if (!strcasecmp(temp, "#include")) + { + // #include filename + char basedir[1024], // Base directory + *baseptr, // Pointer into directory + inctemp[1024], // Initial filename + incname[1024]; // Include filename + ppdcFile *incfile; // Include file + int *old_current = cond_current; + // Previous current stack + + + // Get the include name... + if (!get_token(fp, inctemp, sizeof(inctemp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected include filename on line %d of " + "%s!\n"), fp->line, fp->filename); + break; + } + + if (cond_state) + continue; + + // Figure out the current directory... + strlcpy(basedir, fp->filename, sizeof(basedir)); + + if ((baseptr = strrchr(basedir, '/')) != NULL) + *baseptr = '\0'; + else + strcpy(basedir, "."); + + // Find the include file... + if (find_include(inctemp, basedir, incname, sizeof(incname))) + { + // Open the include file, scan it, and then close it... + incfile = new ppdcFile(incname); + scan_file(incfile, d, true); + delete incfile; + + if (cond_current != old_current) + _cupsLangPrintf(stderr, _("ppdc: Missing #endif at end of \"%s\"!\n"), + incname); + } + else + { + // Can't find it! + _cupsLangPrintf(stderr, + _("ppdc: Unable to find include file \"%s\" on line %d " + "of %s!\n"), inctemp, fp->line, fp->filename); + break; + } + } + else if (!strcasecmp(temp, "#media")) + { + ppdcMediaSize *m; // Media size + + + // Get a media size... + m = get_size(fp); + if (m) + { + if (cond_state) + m->release(); + else + sizes->add(m); + } + } + else if (!strcasecmp(temp, "#po")) + { + ppdcCatalog *cat; // Message catalog + + + // Get a message catalog... + cat = get_po(fp); + if (cat) + { + if (cond_state) + cat->release(); + else + po_files->add(cat); + } + } + else if (!strcasecmp(temp, "Attribute") || + !strcasecmp(temp, "LocAttribute")) + { + ppdcAttr *a; // Attribute + + + // Get an attribute... + a = get_attr(fp, !strcasecmp(temp, "LocAttribute")); + if (a) + { + if (cond_state) + a->release(); + else + d->add_attr(a); + } + } + else if (!strcasecmp(temp, "Choice")) + { + // Get a choice... + c = get_choice(fp); + if (!c) + break; + + if (cond_state) + { + c->release(); + continue; + } + + // Add it to the current option... + if (!o) + { + _cupsLangPrintf(stderr, + _("ppdc: Choice found on line %d of %s with no " + "Option!\n"), fp->line, fp->filename); + break; + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + } + else if (!strcasecmp(temp, "ColorDevice")) + { + // ColorDevice boolean + if (cond_state) + get_boolean(fp); + else + d->color_device = get_boolean(fp); + } + else if (!strcasecmp(temp, "ColorModel")) + { + // Get the color model + c = get_color_model(fp); + if (!c) + continue; + + if (cond_state) + { + c->release(); + continue; + } + + // Add the choice to the ColorModel option... + if ((o = d->find_option("ColorModel")) == NULL) + { + // Create the ColorModel option... + o = new ppdcOption(PPDC_PICKONE, "ColorModel", "Color Mode", PPDC_SECTION_ANY, 10.0f); + g = general; + g->add_option(o); + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + + o = NULL; + } + else if (!strcasecmp(temp, "ColorProfile")) + { + ppdcProfile *p; // Color profile + + + // Get the color profile... + p = get_color_profile(fp); + + if (p) + { + if (cond_state) + p->release(); + else + d->profiles->add(p); + } + } + else if (!strcasecmp(temp, "Copyright")) + { + // Copyright string + char copytemp[8192], // Copyright string + *copyptr, // Pointer into string + *copyend; // Pointer to end of string + + + // Get the copyright string... + if (!get_token(fp, copytemp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected string after Copyright on line %d " + "of %s!\n"), fp->line, fp->filename); + break; + } + + if (cond_state) + continue; + + // Break it up into individual lines... + for (copyptr = copytemp; copyptr; copyptr = copyend) + { + if ((copyend = strchr(copyptr, '\n')) != NULL) + *copyend++ = '\0'; + + d->copyright->add(new ppdcString(copyptr)); + } + } + else if (!strcasecmp(temp, "CustomMedia")) + { + ppdcMediaSize *m; // Media size + + + // Get a custom media size... + m = get_custom_size(fp); + + if (cond_state) + { + m->release(); + continue; + } + + if (m) + d->sizes->add(m); + + if (isdefault) + d->set_default_size(m); + } + else if (!strcasecmp(temp, "Cutter")) + { + // Cutter boolean + int have_cutter; // Have a paper cutter? + + + have_cutter = get_boolean(fp); + if (have_cutter <= 0 || cond_state) + continue; + + if ((o = d->find_option("CutMedia")) == NULL) + { + o = new ppdcOption(PPDC_BOOLEAN, "CutMedia", "Cut Media", PPDC_SECTION_ANY, 10.0f); + + g = general; + g->add_option(o); + + c = new ppdcChoice("False", NULL, "<>setpagedevice"); + o->add_choice(c); + o->set_defchoice(c); + + c = new ppdcChoice("True", NULL, "<>setpagedevice"); + o->add_choice(c); + } + + o = NULL; + } + else if (!strcasecmp(temp, "Darkness")) + { + // Get the darkness choice... + c = get_generic(fp, "Darkness", NULL, "cupsCompression"); + if (!c) + continue; + + if (cond_state) + { + c->release(); + continue; + } + + // Add the choice to the cupsDarkness option... + if ((o = d->find_option_group("cupsDarkness", &mg)) == NULL) + { + // Create the cupsDarkness option... + o = new ppdcOption(PPDC_PICKONE, "cupsDarkness", "Darkness", PPDC_SECTION_ANY, 10.0f); + g = general; + g->add_option(o); + } + else if (mg != general) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s defined in two different groups on " + "line %d of %s!\n"), "cupsDarkness", fp->line, + fp->filename); + c->release(); + continue; + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + + o = NULL; + } + else if (!strcasecmp(temp, "DriverType")) + { + int i; // Looping var + + + // DriverType keyword + if (!get_token(fp, temp, sizeof(temp))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected driver type keyword following " + "DriverType on line %d of %s!\n"), + fp->line, fp->filename); + continue; + } + + if (cond_state) + continue; + + for (i = 0; i < (int)(sizeof(driver_types) / sizeof(driver_types[0])); i ++) + if (!strcasecmp(temp, driver_types[i])) + break; + + if (i < (int)(sizeof(driver_types) / sizeof(driver_types[0]))) + d->type = (ppdcDrvType)i; + else if (!strcasecmp(temp, "dymo")) + d->type = PPDC_DRIVER_LABEL; + else + _cupsLangPrintf(stderr, + _("ppdc: Unknown driver type %s on line %d of %s!\n"), + temp, fp->line, fp->filename); + } + else if (!strcasecmp(temp, "Duplex")) + get_duplex(fp, d); + else if (!strcasecmp(temp, "Filter")) + { + ppdcFilter *f; // Filter + + + // Get the filter value... + f = get_filter(fp); + if (f) + { + if (cond_state) + f->release(); + else + d->filters->add(f); + } + } + else if (!strcasecmp(temp, "Finishing")) + { + // Get the finishing choice... + c = get_generic(fp, "Finishing", "OutputType", NULL); + if (!c) + continue; + + if (cond_state) + { + c->release(); + continue; + } + + // Add the choice to the cupsFinishing option... + if ((o = d->find_option_group("cupsFinishing", &mg)) == NULL) + { + // Create the cupsFinishing option... + o = new ppdcOption(PPDC_PICKONE, "cupsFinishing", "Finishing", PPDC_SECTION_ANY, 10.0f); + g = general; + g->add_option(o); + } + else if (mg != general) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s defined in two different groups on " + "line %d of %s!\n"), "cupsFinishing", fp->line, + fp->filename); + c->release(); + continue; + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + + o = NULL; + } + else if (!strcasecmp(temp, "Font") || + !strcasecmp(temp, "#font")) + { + ppdcFont *f; // Font + + + // Get a font... + f = get_font(fp); + if (f) + { + if (cond_state) + f->release(); + else + { + if (!strcasecmp(temp, "#font")) + base_fonts->add(f); + else + d->add_font(f); + + if (isdefault) + d->set_default_font(f); + } + } + } + else if (!strcasecmp(temp, "Group")) + { + // Get a group... + ppdcGroup *tempg = get_group(fp, d); + + if (!tempg) + break; + + if (cond_state) + { + if (!d->find_group(tempg->name->value)) + tempg->release(); + } + else + { + if (!d->find_group(tempg->name->value)) + d->add_group(tempg); + + g = tempg; + } + } + else if (!strcasecmp(temp, "HWMargins")) + { + // HWMargins left bottom right top + d->left_margin = get_measurement(fp); + d->bottom_margin = get_measurement(fp); + d->right_margin = get_measurement(fp); + d->top_margin = get_measurement(fp); + } + else if (!strcasecmp(temp, "InputSlot")) + { + // Get the input slot choice... + c = get_generic(fp, "InputSlot", NULL, "MediaPosition"); + if (!c) + continue; + + if (cond_state) + { + c->release(); + continue; + } + + // Add the choice to the InputSlot option... + + if ((o = d->find_option_group("InputSlot", &mg)) == NULL) + { + // Create the InputSlot option... + o = new ppdcOption(PPDC_PICKONE, "InputSlot", "Media Source", + PPDC_SECTION_ANY, 10.0f); + g = general; + g->add_option(o); + } + else if (mg != general) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s defined in two different groups on " + "line %d of %s!\n"), "InputSlot", fp->line, + fp->filename); + c->release(); + continue; + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + + o = NULL; + } + else if (!strcasecmp(temp, "Installable")) + { + // Get the installable option... + o = get_installable(fp); + + // Add it as needed... + if (o) + { + if (cond_state) + o->release(); + else + install->add_option(o); + + o = NULL; + } + } + else if (!strcasecmp(temp, "ManualCopies")) + { + // ManualCopies boolean + if (cond_state) + get_boolean(fp); + else + d->manual_copies = get_boolean(fp); + } + else if (!strcasecmp(temp, "Manufacturer")) + { + // Manufacturer name + char name[256]; // Model name string + + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after Manufacturer on line %d " + "of %s!\n"), fp->line, fp->filename); + break; + } + + if (!cond_state) + d->set_manufacturer(name); + } + else if (!strcasecmp(temp, "MaxSize")) + { + // MaxSize width length + if (cond_state) + { + get_measurement(fp); + get_measurement(fp); + } + else + { + d->max_width = get_measurement(fp); + d->max_length = get_measurement(fp); + } + } + else if (!strcasecmp(temp, "MediaSize")) + { + // MediaSize keyword + char name[41]; // Media size name + ppdcMediaSize *m, // Matching media size... + *dm; // Driver media size... + + + if (get_token(fp, name, sizeof(name)) == NULL) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after MediaSize on line %d of " + "%s!\n"), fp->line, fp->filename); + break; + } + + if (cond_state) + continue; + + m = find_size(name); + + if (!m) + { + _cupsLangPrintf(stderr, + _("ppdc: Unknown media size \"%s\" on line %d of " + "%s!\n"), name, fp->line, fp->filename); + break; + } + + // Add this size to the driver... + dm = new ppdcMediaSize(m->name->value, m->text->value, + m->width, m->length, d->left_margin, + d->bottom_margin, d->right_margin, + d->top_margin); + d->sizes->add(dm); + + if (isdefault) + d->set_default_size(dm); + } + else if (!strcasecmp(temp, "MediaType")) + { + // Get the media type choice... + c = get_generic(fp, "MediaType", "MediaType", "cupsMediaType"); + if (!c) + continue; + + if (cond_state) + { + c->release(); + continue; + } + + // Add the choice to the MediaType option... + if ((o = d->find_option_group("MediaType", &mg)) == NULL) + { + // Create the MediaType option... + o = new ppdcOption(PPDC_PICKONE, "MediaType", "Media Type", + PPDC_SECTION_ANY, 10.0f); + g = general; + g->add_option(o); + } + else if (mg != general) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s defined in two different groups on " + "line %d of %s!\n"), "MediaType", fp->line, + fp->filename); + c->release(); + continue; + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + + o = NULL; + } + else if (!strcasecmp(temp, "MinSize")) + { + // MinSize width length + if (cond_state) + { + get_measurement(fp); + get_measurement(fp); + } + else + { + d->min_width = get_measurement(fp); + d->min_length = get_measurement(fp); + } + } + else if (!strcasecmp(temp, "ModelName")) + { + // ModelName name + char name[256]; // Model name string + + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after ModelName on line %d of " + "%s!\n"), fp->line, fp->filename); + break; + } + + if (!cond_state) + d->set_model_name(name); + } + else if (!strcasecmp(temp, "ModelNumber")) + { + // ModelNumber number + if (cond_state) + get_integer(fp); + else + d->model_number = get_integer(fp); + } + else if (!strcasecmp(temp, "Option")) + { + // Get an option... + ppdcOption *tempo = get_option(fp, d, g); + + if (!tempo) + break; + + if (cond_state) + { + if (!g->find_option(tempo->name->value)) + tempo->release(); + } + else + { + if (!g->find_option(tempo->name->value)) + g->add_option(tempo); + + o = tempo; + } + } + else if (!strcasecmp(temp, "FileName")) + { + // FileName name + char name[256]; // Filename string + + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after FileName on line %d of " + "%s!\n"), fp->line, fp->filename); + break; + } + + if (!cond_state) + d->set_file_name(name); + } + else if (!strcasecmp(temp, "PCFileName")) + { + // PCFileName name + char name[256]; // PC filename string + + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected name after PCFileName on line %d of " + "%s!\n"), fp->line, fp->filename); + break; + } + + if (!cond_state) + d->set_pc_file_name(name); + } + else if (!strcasecmp(temp, "Resolution")) + { + // Get the resolution choice... + c = get_resolution(fp); + if (!c) + continue; + + if (cond_state) + { + c->release(); + continue; + } + + // Add the choice to the Resolution option... + if ((o = d->find_option_group("Resolution", &mg)) == NULL) + { + // Create the Resolution option... + o = new ppdcOption(PPDC_PICKONE, "Resolution", NULL, PPDC_SECTION_ANY, + 10.0f); + g = general; + g->add_option(o); + } + else if (mg != general) + { + _cupsLangPrintf(stderr, + _("ppdc: Option %s defined in two different groups on " + "line %d of %s!\n"), "Resolution", fp->line, + fp->filename); + c->release(); + continue; + } + + o->add_choice(c); + + if (isdefault) + o->set_defchoice(c); + + o = NULL; + } + else if (!strcasecmp(temp, "SimpleColorProfile")) + { + ppdcProfile *p; // Color profile + + + // Get the color profile... + p = get_simple_profile(fp); + + if (p) + { + if (cond_state) + p->release(); + else + d->profiles->add(p); + } + } + else if (!strcasecmp(temp, "Throughput")) + { + // Throughput number + if (cond_state) + get_integer(fp); + else + d->throughput = get_integer(fp); + } + else if (!strcasecmp(temp, "UIConstraints")) + { + ppdcConstraint *con; // Constraint + + + con = get_constraint(fp); + + if (con) + { + if (cond_state) + con->release(); + else + d->constraints->add(con); + } + } + else if (!strcasecmp(temp, "VariablePaperSize")) + { + // VariablePaperSize boolean + if (cond_state) + get_boolean(fp); + else + d->variable_paper_size = get_boolean(fp); + } + else if (!strcasecmp(temp, "Version")) + { + // Version string + char name[256]; // Model name string + + + if (!get_token(fp, name, sizeof(name))) + { + _cupsLangPrintf(stderr, + _("ppdc: Expected string after Version on line %d of " + "%s!\n"), fp->line, fp->filename); + break; + } + + if (!cond_state) + d->set_version(name); + } + else + { + _cupsLangPrintf(stderr, + _("ppdc: Unknown token \"%s\" seen on line %d of %s!\n"), + temp, fp->line, fp->filename); + break; + } + } + + // Done processing this block, is there anything to save? + if (!inc) + { + if (!d->pc_file_name || !d->model_name || !d->manufacturer || !d->version || + !d->sizes->count) + { + // Nothing to save... + d->release(); + } + else + { + // Got a driver, save it... + drivers->add(d); + } + } + else if (inc && td) + td->release(); +} + + +// +// 'ppdcSource::set_variable()' - Set a variable. +// + +ppdcVariable * // O - Variable +ppdcSource::set_variable( + const char *name, // I - Name + const char *value) // I - Value +{ + ppdcVariable *v; // Variable + + + // See if the variable exists already... + v = find_variable(name); + if (v) + { + // Change the variable value... + v->set_value(value); + } + else + { + // Create a new variable and add it... + v = new ppdcVariable(name, value); + vars->add(v); + } + + return (v); +} + + +// +// 'ppdcSource::write_file()' - Write the current source data to a file. +// + +int // O - 0 on success, -1 on error +ppdcSource::write_file(const char *f) // I - File to write +{ + cups_file_t *fp; // Output file + char bckname[1024]; // Backup file + ppdcDriver *d; // Current driver + ppdcString *st; // Current string + ppdcAttr *a; // Current attribute + ppdcConstraint *co; // Current constraint + ppdcFilter *fi; // Current filter + ppdcFont *fo; // Current font + ppdcGroup *g; // Current group + ppdcOption *o; // Current option + ppdcChoice *ch; // Current choice + ppdcProfile *p; // Current color profile + ppdcMediaSize *si; // Current media size + float left, // Current left margin + bottom, // Current bottom margin + right, // Current right margin + top; // Current top margin + int dtused[PPDC_DRIVER_MAX];// Driver type usage... + + + // Rename the current file, if any, to .bck... + snprintf(bckname, sizeof(bckname), "%s.bck", f); + rename(f, bckname); + + // Open the output file... + fp = cupsFileOpen(f, "w"); + + if (!fp) + { + // Can't create file; restore backup and return... + rename(bckname, f); + return (-1); + } + + cupsFilePuts(fp, "// CUPS PPD Compiler " CUPS_SVERSION "\n\n"); + + // Include standard files... + cupsFilePuts(fp, "// Include necessary files...\n"); + cupsFilePuts(fp, "#include \n"); + cupsFilePuts(fp, "#include \n"); + + memset(dtused, 0, sizeof(dtused)); + + for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next()) + if (d->type > PPDC_DRIVER_PS && !dtused[d->type]) + { + cupsFilePrintf(fp, "#include <%s.h>\n", driver_types[d->type]); + dtused[d->type] = 1; + } + + // Output each driver... + for (d = (ppdcDriver *)drivers->first(); d; d = (ppdcDriver *)drivers->next()) + { + // Start the driver... + cupsFilePrintf(fp, "\n// %s %s\n", d->manufacturer->value, + d->model_name->value); + cupsFilePuts(fp, "{\n"); + + // Write the copyright stings... + for (st = (ppdcString *)d->copyright->first(); + st; + st = (ppdcString *)d->copyright->next()) + quotef(fp, " Copyright \"%s\"\n", st->value); + + // Write other strings and values... + if (d->manufacturer && d->manufacturer->value) + quotef(fp, " Manufacturer \"%s\"\n", d->manufacturer->value); + if (d->model_name->value) + quotef(fp, " ModelName \"%s\"\n", d->model_name->value); + if (d->file_name && d->file_name->value) + quotef(fp, " FileName \"%s\"\n", d->file_name->value); + if (d->pc_file_name && d->pc_file_name->value) + quotef(fp, " PCFileName \"%s\"\n", d->pc_file_name->value); + if (d->version && d->version->value) + quotef(fp, " Version \"%s\"\n", d->version->value); + + cupsFilePrintf(fp, " DriverType %s\n", driver_types[d->type]); + + if (d->model_number) + { + switch (d->type) + { + case PPDC_DRIVER_ESCP : + cupsFilePuts(fp, " ModelNumber ("); + + if (d->model_number & ESCP_DOTMATRIX) + cupsFilePuts(fp, " $ESCP_DOTMATRIX"); + if (d->model_number & ESCP_MICROWEAVE) + cupsFilePuts(fp, " $ESCP_MICROWEAVE"); + if (d->model_number & ESCP_STAGGER) + cupsFilePuts(fp, " $ESCP_STAGGER"); + if (d->model_number & ESCP_ESCK) + cupsFilePuts(fp, " $ESCP_ESCK"); + if (d->model_number & ESCP_EXT_UNITS) + cupsFilePuts(fp, " $ESCP_EXT_UNITS"); + if (d->model_number & ESCP_EXT_MARGINS) + cupsFilePuts(fp, " $ESCP_EXT_MARGINS"); + if (d->model_number & ESCP_USB) + cupsFilePuts(fp, " $ESCP_USB"); + if (d->model_number & ESCP_PAGE_SIZE) + cupsFilePuts(fp, " $ESCP_PAGE_SIZE"); + if (d->model_number & ESCP_RASTER_ESCI) + cupsFilePuts(fp, " $ESCP_RASTER_ESCI"); + if (d->model_number & ESCP_REMOTE) + cupsFilePuts(fp, " $ESCP_REMOTE"); + + cupsFilePuts(fp, ")\n"); + break; + + case PPDC_DRIVER_PCL : + cupsFilePuts(fp, " ModelNumber ("); + + if (d->model_number & PCL_PAPER_SIZE) + cupsFilePuts(fp, " $PCL_PAPER_SIZE"); + if (d->model_number & PCL_INKJET) + cupsFilePuts(fp, " $PCL_INKJET"); + if (d->model_number & PCL_RASTER_END_COLOR) + cupsFilePuts(fp, " $PCL_RASTER_END_COLOR"); + if (d->model_number & PCL_RASTER_CID) + cupsFilePuts(fp, " $PCL_RASTER_CID"); + if (d->model_number & PCL_RASTER_CRD) + cupsFilePuts(fp, " $PCL_RASTER_CRD"); + if (d->model_number & PCL_RASTER_SIMPLE) + cupsFilePuts(fp, " $PCL_RASTER_SIMPLE"); + if (d->model_number & PCL_RASTER_RGB24) + cupsFilePuts(fp, " $PCL_RASTER_RGB24"); + if (d->model_number & PCL_PJL) + cupsFilePuts(fp, " $PCL_PJL"); + if (d->model_number & PCL_PJL_PAPERWIDTH) + cupsFilePuts(fp, " $PCL_PJL_PAPERWIDTH"); + if (d->model_number & PCL_PJL_HPGL2) + cupsFilePuts(fp, " $PCL_PJL_HPGL2"); + if (d->model_number & PCL_PJL_PCL3GUI) + cupsFilePuts(fp, " $PCL_PJL_PCL3GUI"); + if (d->model_number & PCL_PJL_RESOLUTION) + cupsFilePuts(fp, " $PCL_PJL_RESOLUTION"); + + cupsFilePuts(fp, ")\n"); + break; + + case PPDC_DRIVER_LABEL : + cupsFilePuts(fp, " ModelNumber "); + + switch (d->model_number) + { + case DYMO_3x0 : + cupsFilePuts(fp, "$DYMO_3x0\n"); + break; + + case ZEBRA_EPL_LINE : + cupsFilePuts(fp, "$ZEBRA_EPL_LINE\n"); + break; + + case ZEBRA_EPL_PAGE : + cupsFilePuts(fp, "$ZEBRA_EPL_PAGE\n"); + break; + + case ZEBRA_ZPL : + cupsFilePuts(fp, "$ZEBRA_ZPL\n"); + break; + + case ZEBRA_CPCL : + cupsFilePuts(fp, "$ZEBRA_CPCL\n"); + break; + + case INTELLITECH_PCL : + cupsFilePuts(fp, "$INTELLITECH_PCL\n"); + break; + + default : + cupsFilePrintf(fp, "%d\n", d->model_number); + break; + } + break; + + case PPDC_DRIVER_EPSON : + cupsFilePuts(fp, " ModelNumber "); + + switch (d->model_number) + { + case EPSON_9PIN : + cupsFilePuts(fp, "$EPSON_9PIN\n"); + break; + + case EPSON_24PIN : + cupsFilePuts(fp, "$EPSON_24PIN\n"); + break; + + case EPSON_COLOR : + cupsFilePuts(fp, "$EPSON_COLOR\n"); + break; + + case EPSON_PHOTO : + cupsFilePuts(fp, "$EPSON_PHOTO\n"); + break; + + case EPSON_ICOLOR : + cupsFilePuts(fp, "$EPSON_ICOLOR\n"); + break; + + case EPSON_IPHOTO : + cupsFilePuts(fp, "$EPSON_IPHOTO\n"); + break; + + default : + cupsFilePrintf(fp, "%d\n", d->model_number); + break; + } + break; + + case PPDC_DRIVER_HP : + cupsFilePuts(fp, " ModelNumber "); + switch (d->model_number) + { + case HP_LASERJET : + cupsFilePuts(fp, "$HP_LASERJET\n"); + break; + + case HP_DESKJET : + cupsFilePuts(fp, "$HP_DESKJET\n"); + break; + + case HP_DESKJET2 : + cupsFilePuts(fp, "$HP_DESKJET2\n"); + break; + + default : + cupsFilePrintf(fp, "%d\n", d->model_number); + break; + } + + cupsFilePuts(fp, ")\n"); + break; + + default : + cupsFilePrintf(fp, " ModelNumber %d\n", d->model_number); + break; + } + } + + if (d->manual_copies) + cupsFilePuts(fp, " ManualCopies Yes\n"); + + if (d->color_device) + cupsFilePuts(fp, " ColorDevice Yes\n"); + + if (d->throughput) + cupsFilePrintf(fp, " Throughput %d\n", d->throughput); + + // Output all of the attributes... + for (a = (ppdcAttr *)d->attrs->first(); + a; + a = (ppdcAttr *)d->attrs->next()) + if (a->text->value && a->text->value[0]) + quotef(fp, " Attribute \"%s\" \"%s/%s\" \"%s\"\n", + a->name->value, a->selector->value ? a->selector->value : "", + a->text->value, a->value->value ? a->value->value : ""); + else + quotef(fp, " Attribute \"%s\" \"%s\" \"%s\"\n", + a->name->value, a->selector->value ? a->selector->value : "", + a->value->value ? a->value->value : ""); + + // Output all of the constraints... + for (co = (ppdcConstraint *)d->constraints->first(); + co; + co = (ppdcConstraint *)d->constraints->next()) + { + if (co->option1->value[0] == '*') + cupsFilePrintf(fp, " UIConstraints \"%s %s", co->option1->value, + co->choice1->value ? co->choice1->value : ""); + else + cupsFilePrintf(fp, " UIConstraints \"*%s %s", co->option1->value, + co->choice1->value ? co->choice1->value : ""); + + if (co->option2->value[0] == '*') + cupsFilePrintf(fp, " %s %s\"\n", co->option2->value, + co->choice2->value ? co->choice2->value : ""); + else + cupsFilePrintf(fp, " *%s %s\"\n", co->option2->value, + co->choice2->value ? co->choice2->value : ""); + } + + // Output all of the filters... + for (fi = (ppdcFilter *)d->filters->first(); + fi; + fi = (ppdcFilter *)d->filters->next()) + cupsFilePrintf(fp, " Filter \"%s %d %s\"\n", + fi->mime_type->value, fi->cost, fi->program->value); + + // Output all of the fonts... + for (fo = (ppdcFont *)d->fonts->first(); + fo; + fo = (ppdcFont *)d->fonts->next()) + if (!strcmp(fo->name->value, "*")) + cupsFilePuts(fp, " Font *\n"); + else + cupsFilePrintf(fp, " Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n", + fo->name->value, fo->encoding->value, + fo->version->value, fo->charset->value, + fo->status == PPDC_FONT_ROM ? "ROM" : "Disk"); + + // Output all options... + for (g = (ppdcGroup *)d->groups->first(); + g; + g = (ppdcGroup *)d->groups->next()) + { + if (g->options->count == 0) + continue; + + if (g->text->value && g->text->value[0]) + quotef(fp, " Group \"%s/%s\"\n", g->name->value, g->text->value); + else + cupsFilePrintf(fp, " Group \"%s\"\n", g->name->value); + + for (o = (ppdcOption *)g->options->first(); + o; + o = (ppdcOption *)g->options->next()) + { + if (o->choices->count == 0) + continue; + + if (o->text->value && o->text->value[0]) + quotef(fp, " Option \"%s/%s\"", o->name->value, o->text->value); + else + cupsFilePrintf(fp, " Option \"%s\"", o->name->value); + + cupsFilePrintf(fp, " %s %s %.1f\n", + o->type == PPDC_BOOLEAN ? "Boolean" : + o->type == PPDC_PICKONE ? "PickOne" : "PickMany", + o->section == PPDC_SECTION_ANY ? "AnySetup" : + o->section == PPDC_SECTION_DOCUMENT ? "DocumentSetup" : + o->section == PPDC_SECTION_EXIT ? "ExitServer" : + o->section == PPDC_SECTION_JCL ? "JCLSetup" : + o->section == PPDC_SECTION_PAGE ? "PageSetup" : + "Prolog", + o->order); + + for (ch = (ppdcChoice *)o->choices->first(); + ch; + ch = (ppdcChoice *)o->choices->next()) + { + if (ch->text->value && ch->text->value[0]) + quotef(fp, " %sChoice \"%s/%s\" \"%s\"\n", + o->defchoice == ch->name ? "*" : "", + ch->name->value, ch->text->value, + ch->code->value ? ch->code->value : ""); + else + quotef(fp, " %sChoice \"%s\" \"%s\"\n", + o->defchoice == ch->name ? "*" : "", + ch->name->value, + ch->code->value ? ch->code->value : ""); + } + } + } + + // Output all of the color profiles... + for (p = (ppdcProfile *)d->profiles->first(); + p; + p = (ppdcProfile *)d->profiles->next()) + cupsFilePrintf(fp, " ColorProfile \"%s/%s\" %.3f %.3f " + "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n", + p->resolution->value, p->media_type->value, + p->density, p->gamma, + p->profile[0], p->profile[1], p->profile[2], + p->profile[3], p->profile[4], p->profile[5], + p->profile[6], p->profile[7], p->profile[8]); + + // Output all of the media sizes... + left = 0.0; + bottom = 0.0; + right = 0.0; + top = 0.0; + + for (si = (ppdcMediaSize *)d->sizes->first(); + si; + si = (ppdcMediaSize *)d->sizes->next()) + if (si->size_code->value && si->region_code->value) + { + // Output a custom media size... + quotef(fp, " %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n", + si->name == d->default_size ? "*" : "", si->name->value, + si->text->value, si->width, si->length, si->left, si->bottom, + si->right, si->top, si->size_code->value, + si->region_code->value); + } + else + { + // Output a standard media size... + if (fabs(left - si->left) > 0.1 || + fabs(bottom - si->bottom) > 0.1 || + fabs(right - si->right) > 0.1 || + fabs(top - si->top) > 0.1) + { + cupsFilePrintf(fp, " HWMargins %.2f %.2f %.2f %.2f\n", + si->left, si->bottom, si->right, si->top); + + left = si->left; + bottom = si->bottom; + right = si->right; + top = si->top; + } + + cupsFilePrintf(fp, " %sMediaSize %s\n", + si->name == d->default_size ? "*" : "", + si->name->value); + } + + if (d->variable_paper_size) + { + cupsFilePuts(fp, " VariablePaperSize Yes\n"); + + if (fabs(left - d->left_margin) > 0.1 || + fabs(bottom - d->bottom_margin) > 0.1 || + fabs(right - d->right_margin) > 0.1 || + fabs(top - d->top_margin) > 0.1) + { + cupsFilePrintf(fp, " HWMargins %.2f %.2f %.2f %.2f\n", + d->left_margin, d->bottom_margin, d->right_margin, + d->top_margin); + } + + cupsFilePrintf(fp, " MinSize %.2f %.2f\n", d->min_width, d->min_length); + cupsFilePrintf(fp, " MaxSize %.2f %.2f\n", d->max_width, d->max_length); + } + + // End the driver... + cupsFilePuts(fp, "}\n"); + } + + // Close the file and return... + cupsFileClose(fp); + + return (0); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-string.cxx b/ppdc/ppdc-string.cxx new file mode 100644 index 0000000000..caf8f8015d --- /dev/null +++ b/ppdc/ppdc-string.cxx @@ -0,0 +1,62 @@ +// +// "$Id$" +// +// Shared string class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcString::ppdcString() - Create a shared string. +// ppdcString::~ppdcString() - Destroy a shared string. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcString::ppdcString()' - Create a shared string. +// + +ppdcString::ppdcString(const char *v) // I - String + : ppdcShared() +{ + PPDC_NEWVAL(v); + + if (v) + { + value = new char[strlen(v) + 1]; + strcpy(value, v); + } + else + value = 0; +} + + +// +// 'ppdcString::~ppdcString()' - Destroy a shared string. +// + +ppdcString::~ppdcString() +{ + PPDC_DELETEVAL(value); + + if (value) + delete[] value; +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc-variable.cxx b/ppdc/ppdc-variable.cxx new file mode 100644 index 0000000000..22a175ad44 --- /dev/null +++ b/ppdc/ppdc-variable.cxx @@ -0,0 +1,71 @@ +// +// "$Id$" +// +// Variable class for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// ppdcVariable::ppdcVariable() - Create a variable. +// ppdcVariable::~ppdcVariable() - Destroy a variable. +// ppdcVariable::set_value() - Set the value of a variable. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'ppdcVariable::ppdcVariable()' - Create a variable. +// + +ppdcVariable::ppdcVariable(const char *n, // I - Name of variable + const char *v) // I - Value of variable + : ppdcShared() +{ + PPDC_NEW; + + name = new ppdcString(n); + value = new ppdcString(v); +} + + +// +// 'ppdcVariable::~ppdcVariable()' - Destroy a variable. +// + +ppdcVariable::~ppdcVariable() +{ + PPDC_DELETE; + + name->release(); + value->release(); +} + + +// +// 'ppdcVariable::set_value()' - Set the value of a variable. +// + +void +ppdcVariable::set_value(const char *v) +{ + value->release(); + value = new ppdcString(v); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc.cxx b/ppdc/ppdc.cxx new file mode 100644 index 0000000000..eaf88fa42e --- /dev/null +++ b/ppdc/ppdc.cxx @@ -0,0 +1,464 @@ +// +// "$Id$" +// +// PPD file compiler main entry for the CUPS PPD Compiler. +// +// Copyright 2007-2010 by Apple Inc. +// Copyright 2002-2007 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// main() - Main entry for the PPD compiler. +// usage() - Show usage and exit. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include +#include +#include + + +// +// Local functions... +// + +static void usage(void); + + +// +// 'main()' - Main entry for the PPD compiler. +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + int i, j; // Looping vars + ppdcCatalog *catalog; // Message catalog + const char *outdir; // Output directory + ppdcSource *src; // PPD source file data + ppdcDriver *d; // Current driver + cups_file_t *fp; // PPD file + char *opt, // Current option + *value, // Value in option + *outname, // Output filename + make_model[1024], + // Make and model + pcfilename[1024], + // Lowercase pcfilename + filename[1024]; // PPD filename + int comp, // Compress + do_test, // Test PPD files + single_language,// Generate single-language files + use_model_name, // Use ModelName for filename + verbose; // Verbosity + ppdcLineEnding le; // Line ending to use + ppdcArray *locales; // List of locales + cups_array_t *filenames; // List of generated filenames + + + _cupsSetLocale(argv); + + // Scan the command-line... + catalog = NULL; + comp = 0; + do_test = 0; + le = PPDC_LFONLY; + locales = NULL; + outdir = "ppd"; + single_language = 0; + src = new ppdcSource(); + use_model_name = 0; + verbose = 0; + filenames = cupsArrayNew((cups_array_func_t)strcasecmp, NULL); + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'D' : // Define variable + i ++; + if (i >= argc) + usage(); + + if ((value = strchr(argv[i], '=')) != NULL) + { + *value++ = '\0'; + + src->set_variable(argv[i], value); + } + else + src->set_variable(argv[i], "1"); + break; + + case 'I' : // Include directory... + i ++; + if (i >= argc) + usage(); + + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Adding include directory \"%s\"...\n"), + argv[i]); + + ppdcSource::add_include(argv[i]); + break; + + case 'c' : // Message catalog... + i ++; + if (i >= argc) + usage(); + + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Loading messages from \"%s\"...\n"), + argv[i]); + + if (!catalog) + catalog = new ppdcCatalog("en"); + + if (catalog->load_messages(argv[i])) + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to load localization file " + "\"%s\" - %s\n"), argv[i], strerror(errno)); + return (1); + } + break; + + case 'd' : // Output directory... + i ++; + if (i >= argc) + usage(); + + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Writing PPD files to directory " + "\"%s\"...\n"), argv[i]); + + outdir = argv[i]; + break; + + case 'l' : // Language(s)... + i ++; + if (i >= argc) + usage(); + + if (strchr(argv[i], ',')) + { + // Comma-delimited list of languages... + char temp[1024], // Copy of language list + *start, // Start of current locale name + *end; // End of current locale name + + + locales = new ppdcArray(); + + strlcpy(temp, argv[i], sizeof(temp)); + for (start = temp; *start; start = end) + { + if ((end = strchr(start, ',')) != NULL) + *end++ = '\0'; + else + end = start + strlen(start); + + if (end > start) + locales->add(new ppdcString(start)); + } + } + else + { + single_language = 1; + + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Loading messages for locale " + "\"%s\"...\n"), argv[i]); + + if (catalog) + catalog->release(); + + catalog = new ppdcCatalog(argv[i]); + + if (catalog->messages->count == 0) + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to find localization for " + "\"%s\" - %s\n"), argv[i], strerror(errno)); + return (1); + } + } + break; + + case 'm' : // Use ModelName for filename + use_model_name = 1; + break; + + case 't' : // Test PPDs instead of generating them + do_test = 1; + break; + + case 'v' : // Be verbose... + verbose ++; + break; + + case 'z' : // Compress files... + comp = 1; + break; + + case '-' : // --option + if (!strcmp(opt, "-lf")) + { + le = PPDC_LFONLY; + opt += strlen(opt) - 1; + break; + } + else if (!strcmp(opt, "-cr")) + { + le = PPDC_CRONLY; + opt += strlen(opt) - 1; + break; + } + else if (!strcmp(opt, "-crlf")) + { + le = PPDC_CRLF; + opt += strlen(opt) - 1; + break; + } + + default : // Unknown + usage(); + break; + } + } + else + { + // Open and load the driver info file... + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Loading driver information file \"%s\"...\n"), + argv[i]); + + src->read_file(argv[i]); + } + + + if (src->drivers->count > 0) + { + // Create the output directory... + if (mkdir(outdir, 0777)) + { + if (errno != EEXIST) + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to create output directory %s: %s\n"), + outdir, strerror(errno)); + return (1); + } + } + + // Write PPD files... + for (d = (ppdcDriver *)src->drivers->first(); + d; + d = (ppdcDriver *)src->drivers->next()) + { + if (do_test) + { + // Test the PPD file for this driver... + int pid, // Process ID + fds[2]; // Pipe file descriptors + + + if (pipe(fds)) + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to create output pipes: %s\n"), + strerror(errno)); + return (1); + } + + if ((pid = fork()) == 0) + { + // Child process comes here... + dup2(fds[0], 0); + + close(fds[0]); + close(fds[1]); + + execlp("cupstestppd", "cupstestppd", "-", (char *)0); + + _cupsLangPrintf(stderr, + _("ppdc: Unable to execute cupstestppd: %s\n"), + strerror(errno)); + return (errno); + } + else if (pid < 0) + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to execute cupstestppd: %s\n"), + strerror(errno)); + return (errno); + } + + close(fds[0]); + fp = cupsFileOpenFd(fds[1], "w"); + } + else + { + // Write the PPD file for this driver... + if (use_model_name) + { + if (!strncasecmp(d->model_name->value, d->manufacturer->value, + strlen(d->manufacturer->value))) + { + // Model name already starts with the manufacturer... + outname = d->model_name->value; + } + else + { + // Add manufacturer to the front of the model name... + snprintf(make_model, sizeof(make_model), "%s %s", + d->manufacturer->value, d->model_name->value); + outname = make_model; + } + } + else if (d->file_name) + outname = d->file_name->value; + else + outname = d->pc_file_name->value; + + if (strstr(outname, ".PPD")) + { + // Convert PCFileName to lowercase... + for (j = 0; + outname[j] && j < (int)(sizeof(pcfilename) - 1); + j ++) + pcfilename[j] = tolower(outname[j] & 255); + + pcfilename[j] = '\0'; + } + else + { + // Leave PCFileName as-is... + strlcpy(pcfilename, outname, sizeof(pcfilename)); + } + + // Open the PPD file for writing... + if (comp) + snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename); + else + snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename); + + if (cupsArrayFind(filenames, filename)) + _cupsLangPrintf(stderr, + _("ppdc: Warning - overlapping filename \"%s\".\n"), + filename); + else + cupsArrayAdd(filenames, strdup(filename)); + + fp = cupsFileOpen(filename, comp ? "w9" : "w"); + if (!fp) + { + _cupsLangPrintf(stderr, + _("ppdc: Unable to create PPD file \"%s\" - %s.\n"), + filename, strerror(errno)); + return (1); + } + + if (verbose) + _cupsLangPrintf(stdout, _("ppdc: Writing %s...\n"), filename); + } + + /* + * Write the PPD file... + */ + + ppdcArray *templocales = locales; + + if (!templocales && !single_language) + { + templocales = new ppdcArray(); + for (ppdcCatalog *tempcatalog = (ppdcCatalog *)src->po_files->first(); + tempcatalog; + tempcatalog = (ppdcCatalog *)src->po_files->next()) + { + tempcatalog->locale->retain(); + templocales->add(tempcatalog->locale); + } + } + + if (d->write_ppd_file(fp, catalog, templocales, src, le)) + { + cupsFileClose(fp); + return (1); + } + + if (templocales != locales) + templocales->release(); + + cupsFileClose(fp); + } + } + else + usage(); + + // Delete the printer driver information... + src->release(); + + // Message catalog... + if (catalog) + catalog->release(); + + // Return with no errors. + return (0); +} + + +// +// 'usage()' - Show usage and exit. +// + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" + "Options:\n" + " -D name=value Set named variable to value.\n" + " -I include-dir Add include directory to search " + "path.\n" + " -c catalog.po Load the specified message catalog.\n" + " -d output-dir Specify the output directory.\n" + " -l lang[,lang,...] Specify the output language(s) " + "(locale).\n" + " -m Use the ModelName value as the " + "filename.\n" + " -t Test PPDs instead of generating " + "them.\n" + " -v Be verbose (more v's for more " + "verbosity).\n" + " -z Compress PPD files using GNU zip.\n" + " --cr End lines with CR (Mac OS 9).\n" + " --crlf End lines with CR + LF (Windows).\n" + " --lf End lines with LF (UNIX/Linux/Mac " + "OS X).\n")); + + exit(1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdc.h b/ppdc/ppdc.h new file mode 100644 index 0000000000..24c9f2c269 --- /dev/null +++ b/ppdc/ppdc.h @@ -0,0 +1,532 @@ +// +// "$Id$" +// +// Definitions for the CUPS PPD Compiler. +// +// Copyright 2007-2009 by Apple Inc. +// Copyright 2002-2007 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// + +#ifndef _PPDC_H_ +# define _PPDC_H_ + +// +// Include necessary headers... +// + +# include +# include + + +// +// Macros... +// + +# define PPDC_NAME(s) const char *class_name() { return (s); } + + +// +// Enumerations... +// + +enum ppdcDrvType //// Driver type +{ + PPDC_DRIVER_CUSTOM, // Custom driver + PPDC_DRIVER_PS, // PostScript driver + PPDC_DRIVER_ESCP, // rastertoescpx driver + PPDC_DRIVER_PCL, // rastertopclx driver + PPDC_DRIVER_LABEL, // rastertolabel/rastertodymo driver + PPDC_DRIVER_EPSON, // rastertoepson driver + PPDC_DRIVER_HP, // rastertohp driver + PPDC_DRIVER_MAX // Number of driver types defined +}; + +enum ppdcFontStatus //// Load status of font +{ + PPDC_FONT_ROM, // Font is in ROM + PPDC_FONT_DISK // Font is on disk +}; + +enum ppdcOptSection //// Option section +{ + PPDC_SECTION_ANY, // AnySetup + PPDC_SECTION_DOCUMENT, // DocumentSetup + PPDC_SECTION_EXIT, // ExitServer + PPDC_SECTION_JCL, // JCLSetup + PPDC_SECTION_PAGE, // PageSetup + PPDC_SECTION_PROLOG // Prolog +}; + +enum ppdcOptType //// Option type +{ + PPDC_BOOLEAN, // True/false option + PPDC_PICKONE, // Single choice from list + PPDC_PICKMANY // Multiple choices from list +}; + +enum ppdcLineEnding //// Line endings +{ + PPDC_LFONLY, // LF only + PPDC_CRONLY, // CR only + PPDC_CRLF // CR + LF +}; + +enum ppdcCondFlags //// Condition flags +{ + PPDC_COND_NORMAL = 0, // Normal state + PPDC_COND_SKIP = 1, // Skip state + PPDC_COND_SATISFIED = 2 // At least one condition satisfied +}; + + +// +// Printer description data... +// + +class ppdcShared //// Shared Data Value +{ + private: + + int use; // Use count (delete when 0) + + public: + + ppdcShared(); + virtual ~ppdcShared(); + + virtual const char *class_name() = 0; + + void retain(); + void release(); +}; + +class ppdcArray //// Shared Array + : public ppdcShared +{ + public: + + int count, // Number of elements + alloc, // Allocated elements + current; // Current element + ppdcShared **data; // Elements + + ppdcArray(ppdcArray *a = 0); + ~ppdcArray(); + + PPDC_NAME("ppdcArray") + + void add(ppdcShared *d); + ppdcShared *first(); + ppdcShared *next(); + void remove(ppdcShared *d); +}; + +class ppdcString //// Shared String + : public ppdcShared +{ + public: + + char *value; // String value + + ppdcString(const char *v); + ~ppdcString(); + + PPDC_NAME("ppdcString") +}; + +class ppdcInteger //// Shared integer + : public ppdcShared +{ + public: + + int *value; // Integer value + + ppdcInteger(int *v) { value = v; } + + PPDC_NAME("ppdcInteger") +}; + +class ppdcMessage //// Translation message + : public ppdcShared +{ + public: + + ppdcString *id, // Translation ID + *string; // Translation string + + ppdcMessage(const char *i, const char *s); + ~ppdcMessage(); + + PPDC_NAME("ppdcMessage") +}; + +class ppdcCatalog //// Translation catalog + : public ppdcShared +{ + public: + + ppdcString *locale; // Name of locale + ppdcString *filename; // Name of translation file + ppdcArray *messages; // Array of translation messages + + ppdcCatalog(const char *l, const char *f = 0); + ~ppdcCatalog(); + + PPDC_NAME("ppdcCatalog") + + void add_message(const char *id, const char *string = NULL); + const char *find_message(const char *id); + int load_messages(const char *f); + int save_messages(const char *f); +}; + +class ppdcAttr //// Attribute + : public ppdcShared +{ + public: + + ppdcString *name, // Name of attribute + *selector, // Selector string + *text, // Text string + *value; // Value string + bool localizable; // Should this attribute be localized? + + ppdcAttr(const char *n, const char *s, const char *t, const char *v, + bool loc = false); + ~ppdcAttr(); + + PPDC_NAME("ppdcAttr") +}; + +class ppdcFont //// Shared Font + : public ppdcShared +{ + public: + + ppdcString *name, // Font name + *encoding, // Font base encoding + *version, // Font version + *charset; // Font charset + ppdcFontStatus status; // Font status (ROM or Disk) + + ppdcFont(const char *n, const char *e, const char *v, const char *c, + ppdcFontStatus s); + ~ppdcFont(); + + PPDC_NAME("ppdcFont") +}; + +class ppdcChoice //// Option Choice + : public ppdcShared +{ + public: + + ppdcString *name, // Name of choice + *text, // Human-readable text of choice + *code; // PS code of choice + + ppdcChoice(const char *n, const char *t, const char *c); + ~ppdcChoice(); + + PPDC_NAME("ppdcChoice") +}; + +class ppdcOption //// Option + : public ppdcShared +{ + public: + + ppdcOptType type; // Type of option + ppdcString *name, // Name of option + *text; // Human-readable text of option + ppdcOptSection section; // Section for option code + float order; // Order number + ppdcArray *choices; // Choices + ppdcString *defchoice; // Default choice + + ppdcOption(ppdcOptType ot, const char *n, const char *t, ppdcOptSection s, + float o); + ppdcOption(ppdcOption *o); + ~ppdcOption(); + + PPDC_NAME("ppdcOption") + + void add_choice(ppdcChoice *c) { choices->add(c); } + ppdcChoice *find_choice(const char *n); + void set_defchoice(ppdcChoice *c); +}; + +class ppdcGroup //// Group of Options + : public ppdcShared +{ + public: + + ppdcString *name, // Name of option + *text; // Human-readable text of option + ppdcArray *options; // Options + + ppdcGroup(const char *n, const char *t); + ppdcGroup(ppdcGroup *g); + ~ppdcGroup(); + + PPDC_NAME("ppdcGroup") + + void add_option(ppdcOption *o) { options->add(o); } + ppdcOption *find_option(const char *n); +}; + +class ppdcConstraint //// Constraint + : public ppdcShared +{ + public: + + ppdcString *option1, // First option + *choice1, // First choice + *option2, // Second option + *choice2; // Second choice + + ppdcConstraint(const char *o1, const char *c1, const char *o2, + const char *c2); + ~ppdcConstraint(); + + PPDC_NAME("ppdcConstraint") +}; + +class ppdcFilter //// Filter Program + : public ppdcShared +{ + public: + + ppdcString *mime_type, // MIME type + *program; // Filter program + int cost; // Relative cost of filter + + ppdcFilter(const char *t, const char *p, int c); + ~ppdcFilter(); + + PPDC_NAME("ppdcFilter") +}; + +class ppdcMediaSize //// Media Size + : public ppdcShared +{ + public: + + ppdcString *name, // Name of size + *text; // Human-readable text + float width, // Width in points + length, // Length in points + left, // Left limit in points + bottom, // Bottom limit in points + right, // Right limit in points + top; // Top limit in points + ppdcString *size_code, // PageSize code, if any + *region_code; // PageRegion code, if any + + ppdcMediaSize(const char *n, const char *t, float w, float l, + float lm, float bm, float rm, float tm, + const char *sc = 0, const char *rc = 0); + ~ppdcMediaSize(); + + PPDC_NAME("ppdcMediaSize") +}; + +class ppdcProfile //// Color Profile + : public ppdcShared +{ + public: + + ppdcString *resolution, // Resolution name + *media_type; // Media type name + float density, // Color profile density + gamma, // Color profile gamma + profile[9]; // Color profile matrix + + ppdcProfile(const char *r, const char *m, float d, float g, const float *p); + ~ppdcProfile(); + + PPDC_NAME("ppdcProfile") +}; + +class ppdcSource; + +class ppdcDriver //// Printer Driver Data + : public ppdcShared +{ + public: + + ppdcDrvType type; // Driver type + ppdcArray *copyright; // Copyright strings + ppdcString *manufacturer, // Manufacturer + *model_name, // Name of printer model + *file_name, // Output filename for PPD + *pc_file_name, // 8 character PC filename for PPD + *version; // Version number + int model_number, // Model number for driver + manual_copies, // Do manual copies? + color_device, // Support color? + throughput; // Throughput in pages per minute + ppdcArray *attrs, // Attributes + *constraints, // Constraints + *filters, // Filters + *fonts, // Fonts + *groups, // Option groups + *profiles, // Color profiles + *sizes; // Fixed sizes + ppdcString *default_font, // Default font + *default_size; // Default size option + int variable_paper_size; // Support variable sizes? + ppdcString *custom_size_code; // Custom page size code, if any + float left_margin, // Margins for device in points + bottom_margin, + right_margin, + top_margin, + max_width, // Maximum width (points) + max_length, // Maximum length (points) + min_width, // Minimum width (points) + min_length; // Minimum length (points) + + ppdcDriver(ppdcDriver *d = 0); + ~ppdcDriver(); + + PPDC_NAME("ppdcDriver") + + void add_attr(ppdcAttr *a) { attrs->add(a); } + void add_constraint(ppdcConstraint *c) { constraints->add(c); } + void add_copyright(const char *c) { + copyright->add(new ppdcString(c)); + } + void add_filter(ppdcFilter *f) { filters->add(f); } + void add_font(ppdcFont *f) { fonts->add(f); } + void add_group(ppdcGroup *g) { groups->add(g); } + void add_profile(ppdcProfile *p) { profiles->add(p); } + void add_size(ppdcMediaSize *m) { sizes->add(m); } + + ppdcAttr *find_attr(const char *k, const char *s); + ppdcGroup *find_group(const char *n); + ppdcOption *find_option(const char *n); + ppdcOption *find_option_group(const char *n, ppdcGroup **mg); + + void set_custom_size_code(const char *c); + void set_default_font(ppdcFont *f); + void set_default_size(ppdcMediaSize *m); + void set_file_name(const char *f); + void set_manufacturer(const char *m); + void set_model_name(const char *m); + void set_pc_file_name(const char *f); + void set_version(const char *v); + + int write_ppd_file(cups_file_t *fp, ppdcCatalog *catalog, + ppdcArray *locales, ppdcSource *src, + ppdcLineEnding le); +}; + +class ppdcVariable //// Variable Definition + : public ppdcShared +{ + public: + + ppdcString *name, // Name of variable + *value; // Value of variable + + ppdcVariable(const char *n, const char *v); + ~ppdcVariable(); + + PPDC_NAME("ppdcVariable") + + void set_value(const char *v); +}; + +class ppdcFile //// File +{ + public: + + cups_file_t *fp; // File pointer + const char *filename; // Filename + int line; // Line in file + + ppdcFile(const char *f, cups_file_t *ffp = (cups_file_t *)0); + ~ppdcFile(); + + int get(); + int peek(); +}; + +class ppdcSource //// Source File + : public ppdcShared +{ + public: + + static ppdcArray *includes; // Include directories + static const char *driver_types[]; // Driver types + + ppdcString *filename; // Filename + ppdcArray *base_fonts, // Base fonts + *drivers, // Printer drivers + *po_files, // Message catalogs + *sizes, // Predefined media sizes + *vars; // Defined variables + int cond_state, // Cummulative conditional state + *cond_current, // Current #if state + cond_stack[101]; // #if state stack + + + ppdcSource(const char *f = 0, cups_file_t *ffp = (cups_file_t *)0); + ~ppdcSource(); + + PPDC_NAME("ppdcSource") + + static void add_include(const char *d); + ppdcDriver *find_driver(const char *f); + static char *find_include(const char *f, const char *base, char *n, + int nlen); + ppdcCatalog *find_po(const char *l); + ppdcMediaSize *find_size(const char *s); + ppdcVariable *find_variable(const char *n); + ppdcAttr *get_attr(ppdcFile *fp, bool loc = false); + int get_boolean(ppdcFile *fp); + ppdcChoice *get_choice(ppdcFile *fp); + ppdcChoice *get_color_model(ppdcFile *fp); + int get_color_order(const char *co); + ppdcProfile *get_color_profile(ppdcFile *fp); + int get_color_space(const char *cs); + ppdcConstraint *get_constraint(ppdcFile *fp); + ppdcMediaSize *get_custom_size(ppdcFile *fp); + void get_duplex(ppdcFile *fp, ppdcDriver *d); + ppdcFilter *get_filter(ppdcFile *fp); + float get_float(ppdcFile *fp); + ppdcFont *get_font(ppdcFile *fp); + ppdcChoice *get_generic(ppdcFile *fp, const char *keyword, + const char *tattr, const char *nattr); + ppdcGroup *get_group(ppdcFile *fp, ppdcDriver *d); + ppdcOption *get_installable(ppdcFile *fp); + int get_integer(const char *v); + int get_integer(ppdcFile *fp); + float get_measurement(ppdcFile *fp); + ppdcOption *get_option(ppdcFile *fp, ppdcDriver *d, ppdcGroup *g); + ppdcCatalog *get_po(ppdcFile *fp); + ppdcChoice *get_resolution(ppdcFile *fp); + ppdcProfile *get_simple_profile(ppdcFile *fp); + ppdcMediaSize *get_size(ppdcFile *fp); + char *get_token(ppdcFile *fp, char *buffer, int buflen); + ppdcVariable *get_variable(ppdcFile *fp); + int import_ppd(const char *f); + int quotef(cups_file_t *fp, const char *format, ...); + void read_file(const char *f, cups_file_t *ffp = (cups_file_t *)0); + void scan_file(ppdcFile *fp, ppdcDriver *td = 0, bool inc = false); + ppdcVariable *set_variable(const char *name, const char *value); + int write_file(const char *f); +}; + + +#endif // !_PPDC_H_ + +// +// End of "$Id$". +// diff --git a/ppdc/ppdhtml.cxx b/ppdc/ppdhtml.cxx new file mode 100644 index 0000000000..bcbb81e940 --- /dev/null +++ b/ppdc/ppdhtml.cxx @@ -0,0 +1,185 @@ +// +// "$Id$" +// +// PPD to HTML utility for the CUPS PPD Compiler. +// +// Copyright 2007-2008 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// main() - Main entry for the PPD to HTML utility. +// usage() - Show usage and exit. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include +#include + + +// +// Local functions... +// + +static void usage(void); + + +// +// 'main()' - Main entry for the PPD compiler. +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + int i; // Looping var + ppdcSource *src; // PPD source file data + ppdcDriver *d; // Current driver + ppdcGroup *g, // Current group + *composite; // Composite of all drivers + ppdcOption *o, // Current option + *compo; // Composite option + ppdcChoice *c; // Current choice + char *opt; // Current option char + ppdcMediaSize *size; // Current media size + char *value; // Value in option + + + _cupsSetLocale(argv); + + // Scan the command-line... + src = 0; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'D' : // Define variable + i ++; + if (i >= argc) + usage(); + + if ((value = strchr(argv[i], '=')) != NULL) + { + *value++ = '\0'; + + src->set_variable(argv[i], value); + } + else + src->set_variable(argv[i], "1"); + break; + + case 'I' : // Include directory... + i ++; + if (i >= argc) + usage(); + + ppdcSource::add_include(argv[i]); + break; + + default : // Unknown + usage(); + break; + } + } + else + { + // Open and load the driver info file... + src = new ppdcSource(argv[i]); + + // Create a composite group with all of the features from the + // drivers in the info file... + composite = new ppdcGroup("", ""); + + for (d = (ppdcDriver *)src->drivers->first(); d; d = (ppdcDriver *)src->drivers->next()) + for (g = (ppdcGroup *)d->groups->first(); g; g = (ppdcGroup *)d->groups->next()) + for (o = (ppdcOption *)g->options->first(); o; o = (ppdcOption *)g->options->next()) + { + if ((compo = composite->find_option(o->name->value)) == NULL) + composite->add_option(new ppdcOption(o)); + } + + puts(""); + printf("Driver Summary for %s\n", argv[i]); + printf("

Driver Summary for %s

\n", argv[i]); + printf("

"); + for (compo = (ppdcOption *)composite->options->first(); compo; compo = (ppdcOption *)composite->options->next()) + printf("", compo->text->value); + puts(""); + + // Write HTML summary... + for (d = (ppdcDriver *)src->drivers->first(); d; d = (ppdcDriver *)src->drivers->next()) + { + // Write the summary for this driver... + printf(""); + + for (compo = (ppdcOption *)composite->options->first(); compo; + compo = (ppdcOption *)composite->options->next()) + if ((o = d->find_option(compo->name->value)) != NULL) + { + printf(""); + } + else + printf(""); + + puts(""); + } + + puts("
PrinterMedia Size%s
%s", d->model_name->value); + for (size = (ppdcMediaSize *)d->sizes->first(); size; + size = (ppdcMediaSize *)d->sizes->next()) + printf("%s
", size->text->value); + printf("
"); + for (c = (ppdcChoice *)o->choices->first(); c; + c = (ppdcChoice *)o->choices->next()) + printf("%s
", c->text->value); + printf("
N/A

"); + puts(""); + puts(""); + // Delete the printer driver information... + composite->release(); + src->release(); + } + + // If no drivers have been loaded, display the program usage message. + if (!src) + usage(); + + // Return with no errors. + return (0); +} + + +// +// 'usage()' - Show usage and exit. +// + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: ppdhtml [options] filename.drv >filename.html\n" + " -D name=value Set named variable to value.\n" + "Options:\n" + " -I include-dir Add include directory to search " + "path.\n")); + + exit(1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdi.cxx b/ppdc/ppdi.cxx new file mode 100644 index 0000000000..4e8aa3f505 --- /dev/null +++ b/ppdc/ppdi.cxx @@ -0,0 +1,140 @@ +// +// "$Id$" +// +// PPD file import utility for the CUPS PPD Compiler. +// +// Copyright 2007-2008 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// main() - Main entry for the PPD import utility. +// usage() - Show usage and exit. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include +#include +#include + + +// +// Local functions... +// + +static void usage(void); + + +// +// 'main()' - Main entry for the PPD import utility. +// + +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; // Current option + const char *srcfile; // Output file + ppdcSource *src; // PPD source file data + + + _cupsSetLocale(argv); + + // Scan the command-line... + srcfile = NULL; + src = NULL; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'o' : // Output file + if (srcfile || src) + usage(); + + i ++; + if (i >= argc) + usage(); + + srcfile = argv[i]; + break; + + case 'I' : // Include dir + i ++; + if (i >= argc) + usage(); + + ppdcSource::add_include(argv[i]); + break; + + default : // Unknown + usage(); + break; + } + } + else + { + // Open and load the driver info file... + if (!srcfile) + srcfile = "ppdi.drv"; + + if (!src) + { + if (access(srcfile, 0)) + src = new ppdcSource(); + else + src = new ppdcSource(srcfile); + } + + // Import the PPD file... + src->import_ppd(argv[i]); + } + + // If no drivers have been loaded, display the program usage message. + if (!src) + usage(); + + // Write the driver info file back to disk... + src->write_file(srcfile); + + // Delete the printer driver information... + src->release(); + + // Return with no errors. + return (0); +} + + +// +// 'usage()' - Show usage and exit. +// + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" + "Options:\n" + " -I include-dir\n" + " -o filename.drv\n")); + + exit(1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdmerge.cxx b/ppdc/ppdmerge.cxx new file mode 100644 index 0000000000..34e212d850 --- /dev/null +++ b/ppdc/ppdmerge.cxx @@ -0,0 +1,381 @@ +// +// "$Id$" +// +// PPD file merge utility for the CUPS PPD Compiler. +// +// Copyright 2007-2008 by Apple Inc. +// Copyright 2002-2007 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// main() - Main entry for the PPD merge utility. +// ppd_locale() - Return the locale associated with a PPD file. +// usage() - Show usage and exit. +// + +// +// Include necessary headers... +// + +#include +#include +#include +#include +#include +#include + + +// +// Local functions... +// + +static const char *ppd_locale(ppd_file_t *ppd); +static void usage(void); + + +// +// 'main()' - Main entry for the PPD merge utility. +// + +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; // Current option + ppd_file_t *ppd; // PPD file + cups_array_t *ppds; // Array of PPD files + const char *inname, // First input filename + *outname; // Output filename (if any) + cups_file_t *infile, // Input file + *outfile; // Output file + cups_array_t *languages; // Languages in file + const char *locale; // Current locale + char line[1024]; // Line from file + + + _cupsSetLocale(argv); + + // Scan the command-line... + inname = NULL; + outname = NULL; + outfile = NULL; + languages = NULL; + ppds = cupsArrayNew(NULL, NULL); + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'o' : // Output file + if (outname) + usage(); + + i ++; + if (i >= argc) + usage(); + + outname = argv[i]; + break; + + default : // Unknown + usage(); + break; + } + } + else + { + // Open and load the PPD file... + if ((infile = cupsFileOpen(argv[i], "r")) == NULL) + { + _cupsLangPrintf(stderr, _("%s: Unable to open %s: %s\n"), "ppdmerge", + argv[i], strerror(errno)); + return (1); + } + + // Open the PPD file... + if ((ppd = ppdOpen2(infile)) == NULL) + { + ppd_status_t status; // PPD open status + int linenum; // Line number + + + status = ppdLastError(&linenum); + + _cupsLangPrintf(stderr, _("%s: Unable to open PPD file: %s on line %d.\n"), + "ppdmerge", ppdErrorString(status), linenum); + + _cupsLangPrintf(stderr, "%d: ", linenum); + cupsFileRewind(infile); + + line[0] = '\0'; + + while (cupsFileGets(infile, line, sizeof(line))) + { + linenum --; + if (!linenum) + break; + } + + _cupsLangPrintf(stderr, "%s\n", line); + + cupsFileClose(infile); + return (1); + } + + // Figure out the locale... + if ((locale = ppd_locale(ppd)) == NULL) + { + _cupsLangPrintf(stderr, + _("ppdmerge: Bad LanguageVersion \"%s\" in %s!\n"), + ppd->lang_version, argv[i]); + cupsFileClose(infile); + ppdClose(ppd); + return (1); + } + + if (!strcmp(locale, "en") && !inname && !outfile) + { + // Set the English PPD's filename... + inname = argv[i]; + languages = _ppdGetLanguages(ppd); + + if (outname && !strcmp(inname, outname)) + { + // Rename input filename so that we don't overwrite it... + char bckname[1024]; // Backup filename + + + snprintf(bckname, sizeof(bckname), "%s.bck", inname); + + if (rename(inname, bckname)) + { + _cupsLangPrintf(stderr, + _("ppdmerge: Unable to backup %s to %s- %s\n"), + inname, bckname, strerror(errno)); + return (1); + } + + inname = bckname; + } + } + else if (strcmp(locale, "en")) + { + // Save this PPD for later processing... + cupsArrayAdd(ppds, ppd); + } + else + { + // Don't need this PPD... + _cupsLangPrintf(stderr, _("ppdmerge: Ignoring PPD file %s...\n"), + argv[i]); + ppdClose(ppd); + } + + // Close and move on... + cupsFileClose(infile); + } + + // If no PPDs have been loaded, display the program usage message. + if (!inname) + usage(); + + // Loop through the PPD files we loaded to generate a new language list... + if (!languages) + languages = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + for (ppd = (ppd_file_t *)cupsArrayFirst(ppds); + ppd; + ppd = (ppd_file_t *)cupsArrayNext(ppds)) + { + locale = ppd_locale(ppd); + + if (cupsArrayFind(languages, (void *)locale)) + { + // Already have this language, remove the PPD from the list. + ppdClose(ppd); + cupsArrayRemove(ppds, ppd); + } + else + cupsArrayAdd(languages, (void *)locale); + } + + // Copy the English PPD starting with a cupsLanguages line... + infile = cupsFileOpen(inname, "r"); + + if (outname) + { + const char *ext = strrchr(outname, '.'); + if (ext && !strcmp(ext, ".gz")) + outfile = cupsFileOpen(outname, "w9"); + else + outfile = cupsFileOpen(outname, "w"); + } + else + outfile = cupsFileStdout(); + + cupsFileGets(infile, line, sizeof(line)); + cupsFilePrintf(outfile, "%s\n", line); + if ((locale = (char *)cupsArrayFirst(languages)) != NULL) + { + cupsFilePrintf(outfile, "*cupsLanguages: \"%s", locale); + while ((locale = (char *)cupsArrayNext(languages)) != NULL) + cupsFilePrintf(outfile, " %s", locale); + cupsFilePuts(outfile, "\"\n"); + } + + while (cupsFileGets(infile, line, sizeof(line))) + { + if (strncmp(line, "*cupsLanguages:", 15)) + cupsFilePrintf(outfile, "%s\n", line); + } + + // Loop through the other PPD files we loaded to provide the translations... + for (ppd = (ppd_file_t *)cupsArrayFirst(ppds); + ppd; + ppd = (ppd_file_t *)cupsArrayNext(ppds)) + { + // Output all of the UI text for this language... + int j, k, l; // Looping vars + ppd_group_t *g; // Option group + ppd_option_t *o; // Option + ppd_choice_t *c; // Choice + ppd_coption_t *co; // Custom option + ppd_cparam_t *cp; // Custom parameter + ppd_attr_t *attr; // PPD attribute + + locale = ppd_locale(ppd); + + cupsFilePrintf(outfile, "*%% %s localization\n", ppd->lang_version); + cupsFilePrintf(outfile, "*%s.Translation ModelName/%s: \"\"\n", locale, + ppd->modelname); + + for (j = ppd->num_groups, g = ppd->groups; j > 0; j --, g ++) + { + cupsFilePrintf(outfile, "*%s.Translation %s/%s: \"\"\n", locale, + g->name, g->text); + + for (k = g->num_options, o = g->options; k > 0; k --, o ++) + { + cupsFilePrintf(outfile, "*%s.Translation %s/%s: \"\"\n", locale, + o->keyword, o->text); + + for (l = o->num_choices, c = o->choices; l > 0; l --, c ++) + cupsFilePrintf(outfile, "*%s.%s %s/%s: \"\"\n", locale, + o->keyword, c->choice, c->text); + + if ((co = ppdFindCustomOption(ppd, o->keyword)) != NULL) + { + snprintf(line, sizeof(line), "Custom%s", o->keyword); + attr = ppdFindAttr(ppd, line, "True"); + cupsFilePrintf(outfile, "*%s.Custom%s True/%s: \"\"\n", locale, + o->keyword, attr->text); + for (cp = ppdFirstCustomParam(co); cp; cp = ppdNextCustomParam(co)) + cupsFilePrintf(outfile, "*%s.ParamCustom%s %s/%s: \"\"\n", locale, + o->keyword, cp->name, cp->text); + } + } + } + + ppdClose(ppd); + } + + cupsArrayDelete(ppds); + + cupsFileClose(outfile); + + // Return with no errors. + return (0); +} + + +// +// 'ppd_locale()' - Return the locale associated with a PPD file. +// + +static const char * // O - Locale string +ppd_locale(ppd_file_t *ppd) // I - PPD file +{ + int i, // Looping var + vlen; // Length of LanguageVersion string + static char locale[255]; // Locale string + static struct // LanguageVersion translation table + { + const char *version, // LanguageVersion string */ + *language; // Language code */ + } languages[] = + { + { "chinese", "zh" }, + { "czech", "cs" }, + { "danish", "da" }, + { "dutch", "nl" }, + { "english", "en" }, + { "finnish", "fi" }, + { "french", "fr" }, + { "german", "de" }, + { "greek", "el" }, + { "hungarian", "hu" }, + { "italian", "it" }, + { "japanese", "ja" }, + { "korean", "ko" }, + { "norwegian", "no" }, + { "polish", "pl" }, + { "portuguese", "pt" }, + { "russian", "ru" }, + { "simplified chinese", "zh_CN" }, + { "slovak", "sk" }, + { "spanish", "es" }, + { "swedish", "sv" }, + { "traditional chinese", "zh_TW" }, + { "turkish", "tr" } + }; + + + for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++) + { + vlen = strlen(languages[i].version); + + if (!strncasecmp(ppd->lang_version, languages[i].version, vlen)) + { + if (ppd->lang_version[vlen] == '-' || + ppd->lang_version[vlen] == '_') + snprintf(locale, sizeof(locale), "%s_%s", languages[i].language, + ppd->lang_version + vlen + 1); + else + strlcpy(locale, languages[i].language, sizeof(locale)); + + return (locale); + } + } + + return (NULL); +} + +// +// 'usage()' - Show usage and exit. +// + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: ppdmerge [options] filename.ppd " + "[ ... filenameN.ppd ]\n" + "Options:\n" + " -o filename.ppd[.gz]\n")); + + exit(1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/ppdpo.cxx b/ppdc/ppdpo.cxx new file mode 100644 index 0000000000..3b7904f452 --- /dev/null +++ b/ppdc/ppdpo.cxx @@ -0,0 +1,268 @@ +// +// "$Id$" +// +// PPD file message catalog program for the CUPS PPD Compiler. +// +// Copyright 2007-2008 by Apple Inc. +// Copyright 2002-2005 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// main() - Main entry for the PPD compiler. +// add_ui_strings() - Add all UI strings from the driver. +// usage() - Show usage and exit. +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" +#include +#include + + +// +// Local functions... +// + +static void add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog); +static void usage(void); + + +// +// 'main()' - Main entry for the PPD compiler. +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + int i; // Looping var + ppdcCatalog *catalog; // Message catalog + ppdcSource *src; // PPD source file data + ppdcDriver *d; // Current driver + char *opt; // Current option + int verbose; // Verbosity + const char *outfile; // Output file + char *value; // Value in option + + + _cupsSetLocale(argv); + + // Scan the command-line... + catalog = new ppdcCatalog("en"); + src = 0; + verbose = 0; + outfile = 0; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'D' : // Define variable + i ++; + if (i >= argc) + usage(); + + if ((value = strchr(argv[i], '=')) != NULL) + { + *value++ = '\0'; + + src->set_variable(argv[i], value); + } + else + src->set_variable(argv[i], "1"); + break; + + case 'I' : // Include directory... + i ++; + if (i >= argc) + usage(); + + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Adding include directory \"%s\"...\n"), + argv[i]); + + ppdcSource::add_include(argv[i]); + break; + + case 'o' : // Output file... + i ++; + if (i >= argc || outfile) + usage(); + + outfile = argv[i]; + + catalog->load_messages(outfile); + break; + + case 'v' : // Be verbose... + verbose ++; + break; + + default : // Unknown + usage(); + break; + } + } + else + { + // Open and load the driver info file... + if (verbose > 1) + _cupsLangPrintf(stdout, + _("ppdc: Loading driver information file \"%s\"...\n"), + argv[i]); + + src = new ppdcSource(argv[i]); + + // Add UI strings... + for (d = (ppdcDriver *)src->drivers->first(); + d; + d = (ppdcDriver *)src->drivers->next()) + { + if (verbose) + _cupsLangPrintf(stderr, + _("ppdc: Adding/updating UI text from %s...\n"), + argv[i]); + + add_ui_strings(d, catalog); + } + + // Delete the printer driver information... + src->release(); + } + + // Write the message catalog... + if (!outfile) + usage(); + else + catalog->save_messages(outfile); + + catalog->release(); + + // If no drivers have been loaded, display the program usage message. + if (!src) + usage(); + + // Return with no errors. + return (0); +} + + +// +// 'add_ui_strings()' - Add all UI strings from the driver. +// + +static void +add_ui_strings(ppdcDriver *d, // I - Driver data + ppdcCatalog *catalog) // I - Message catalog +{ + // Add the make/model/language strings... + catalog->add_message(d->manufacturer->value); + catalog->add_message(d->model_name->value); + + // Add the media size strings... + ppdcMediaSize *m; // Current media size + + for (m = (ppdcMediaSize *)d->sizes->first(); + m; + m = (ppdcMediaSize *)d->sizes->next()) + catalog->add_message(m->text->value); + + // Add the group/option/choice strings... + ppdcGroup *g; // Current group + ppdcOption *o; // Current option + ppdcChoice *c; // Current choice + + for (g = (ppdcGroup *)d->groups->first(); + g; + g = (ppdcGroup *)d->groups->next()) + { + if (!g->options->count) + continue; + + if (strcasecmp(g->name->value, "General")) + catalog->add_message(g->text->value); + + for (o = (ppdcOption *)g->options->first(); + o; + o = (ppdcOption *)g->options->next()) + { + if (!o->choices->count) + continue; + + if (o->text->value) + catalog->add_message(o->text->value); + else + catalog->add_message(o->name->value); + + for (c = (ppdcChoice *)o->choices->first(); + c; + c = (ppdcChoice *)o->choices->next()) + if (c->text->value) + catalog->add_message(c->text->value); + else + catalog->add_message(c->name->value); + } + } + + // Add profile and preset strings... + ppdcAttr *a; // Current attribute + for (a = (ppdcAttr *)d->attrs->first(); + a; + a = (ppdcAttr *)d->attrs->next()) + if (a->text->value && a->text->value[0] && + (a->localizable || + !strncmp(a->name->value, "Custom", 6) || + !strncmp(a->name->value, "ParamCustom", 11) || + !strcmp(a->name->value, "APCustomColorMatchingName") || + !strcmp(a->name->value, "APPrinterPreset") || + !strcmp(a->name->value, "cupsICCProfile") || + !strcmp(a->name->value, "cupsIPPReason") || + !strcmp(a->name->value, "cupsMarkerName"))) + { + catalog->add_message(a->text->value); + + if ((a->localizable && a->value->value[0]) || + !strcmp(a->name->value, "cupsIPPReason")) + catalog->add_message(a->value->value); + } + else if (!strncmp(a->name->value, "Custom", 6) || + !strncmp(a->name->value, "ParamCustom", 11)) + catalog->add_message(a->name->value); +} + + +// +// 'usage()' - Show usage and exit. +// + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: ppdpo [options] -o filename.po filename.drv [ ... " + "filenameN.drv ]\n" + "Options:\n" + " -D name=value Set named variable to value.\n" + " -I include-dir Add include directory to search path.\n" + " -v Be verbose (more v's for more " + "verbosity).\n")); + + exit(1); +} + + +// +// End of "$Id$". +// diff --git a/ppdc/sample.drv b/ppdc/sample.drv new file mode 100644 index 0000000000..0bdbca192d --- /dev/null +++ b/ppdc/sample.drv @@ -0,0 +1,1250 @@ +// +// "$Id$" +// +// Driver info file for CUPS-supplied PPDs. +// +// Copyright 2007-2011 by Apple Inc. +// Copyright 1993-2006 by Easy Software Products. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// + +// Include necessary files... +#include +#include +#include +#include +#include + +// Localizations are provided for all of the base languages supported by +// CUPS... +//#po da "" +//#po de "" +//#po es "" +//#po et "" +//#po fi "" +//#po fr "" +//#po he "" +//#po id "" +//#po it "" +//#po ja "" +//#po ko "" +//#po nl "" +//#po no "" +//#po pl "" +//#po pt "" +//#po pt_BR "" +//#po ru "" +//#po sv "" +//#po zh "" +//#po zh_TW "" + +// MediaSize sizes used by label drivers... +#media "w81h252/Address - 1 1/8 x 3 1/2\"" 81 252 +#media "w101h252/Large Address - 1 4/10 x 3 1/2\"" 101 252 +#media "w54h144/Return Address - 3/4 x 2\"" 54 144 +#media "w167h288/Shipping Address - 2 5/16 x 4\"" 167 288 +#media "w162h540/Internet Postage 2-Part - 2 1/4 x 7 1/2\"" 162 540 +#media "w162h504/Internet Postage 3-Part - 2 1/4 x 7\"" 162 504 +#media "w41h248/File Folder - 9/16 x 3 7/16\"" 41 248 +#media "w41h144/Hanging Folder - 9/16 x 2\"" 41 144 +#media "w153h198/3.5\" Disk - 2 1/8 x 2 3/4\"" 153 198 +#media "w90h18/1.25x0.25\"" 90 18 +#media "w90h162/1.25x2.25\"" 90 162 +#media "w108h18/1.50x0.25\"" 108 18 +#media "w108h36/1.50x0.50\"" 108 36 +#media "w108h72/1.50x1.00\"" 108 72 +#media "w108h144/1.50x2.00\"" 108 144 +#media "w144h26/2.00x0.37\"" 144 26 +#media "w144h36/2.00x0.50\"" 144 36 +#media "w144h72/2.00x1.00\"" 144 72 +#media "w144h90/2.00x1.25\"" 144 90 +#media "w144h144/2.00x2.00\"" 144 144 +#media "w144h216/2.00x3.00\"" 144 216 +#media "w144h288/2.00x4.00\"" 144 288 +#media "w144h396/2.00x5.50\"" 144 396 +#media "w162h36/2.25x0.50\"" 162 36 +#media "w162h90/2.25x1.25\"" 162 90 +#media "w162h288/2.25x4.00\"" 162 288 +#media "w162h396/2.25x5.50\"" 162 396 +#media "w171h396/2.38x5.50\"" 171 396 +#media "w180h72/2.50x1.00\"" 180 72 +#media "w180h144/2.50x2.00\"" 180 144 +#media "w198h90/2.75x1.25\"" 198 90 +#media "w209h72/2.9 x 1\"" 209 72 +#media "w216h72/3.00x1.00\"" 216 72 +#media "w216h90/3.00x1.25\"" 216 90 +#media "w216h144/3.00x2.00\"" 216 144 +#media "w216h216/3.00x3.00\"" 216 216 +#media "w216h360/3.00x5.00\"" 216 360 +#media "w234h144/3.25x2.00\"" 234 144 +#media "w234h360/3.25x5.00\"" 234 360 +#media "w234h396/3.25x5.50\"" 234 396 +#media "w234h419/3.25x5.83\"" 234 419 +#media "w234h563/3.25x7.83\"" 234 563 +#media "w252h72/3.50x1.00\"" 252 72 +#media "w288h72/4.00x1.00\"" 288 72 +#media "w288h144/4.00x2.00\"" 288 144 +#media "w288h180/4.00x2.50\"" 288 180 +#media "w288h216/4.00x3.00\"" 288 216 +#media "w288h288/4.00x4.00\"" 288 288 +#media "w288h360/4.00x5.00\"" 288 360 +#media "w288h432/4.00x6.00\"" 288 432 +#media "w288h468/4.00x6.50\"" 288 468 +#media "w288h936/4.00x13.00\"" 288 936 +#media "w432h72/6.00x1.00\"" 432 72 +#media "w432h144/6.00x2.00\"" 432 144 +#media "w432h216/6.00x3.00\"" 432 216 +#media "w432h288/6.00x4.00\"" 432 288 +#media "w432h360/6.00x5.00\"" 432 360 +#media "w432h432/6.00x6.00\"" 432 432 +#media "w432h468/6.00x6.50\"" 432 468 +#media "w576h72/8.00x1.00\"" 576 72 +#media "w576h144/8.00x2.00\"" 576 144 +#media "w576h216/8.00x3.00\"" 576 216 +#media "w576h288/8.00x4.00\"" 576 288 +#media "w576h360/8.00x5.00\"" 576 360 +#media "w576h432/8.00x6.00\"" 576 432 +#media "w576h468/8.00x6.50\"" 576 468 + +// Common stuff for all drivers... +Attribute "cupsVersion" "" "1.4" +Attribute "FileSystem" "" "False" +Attribute "LandscapeOrientation" "" "Plus90" +Attribute "TTRasterizer" "" "Type42" + +Copyright "Copyright 2007-2011 by Apple Inc." +Copyright "Copyright 1997-2007 by Easy Software Products." +Copyright "" +Copyright "These coded instructions, statements, and computer programs are the" +Copyright "property of Apple Inc. and are protected by Federal copyright" +Copyright "law. Distribution and use rights are outlined in the file \"LICENSE.txt\"" +Copyright "which should have been included with this file. If this file is" +Copyright "file is missing or damaged, see the license at \"http://www.cups.org/\"." + +Font * + +Version "1.4" + +// Dymo Label Printer +{ + Manufacturer "Dymo" + ModelName "Label Printer" + Attribute NickName "" "Dymo Label Printer" + PCFileName "dymo.ppd" + DriverType label + ModelNumber $DYMO_3x0 + Throughput 8 + ManualCopies Yes + ColorDevice No + + HWMargins 2 14.9 2 14.9 + + *MediaSize w81h252 + MediaSize w101h252 + MediaSize w54h144 + MediaSize w167h288 + MediaSize w162h540 + MediaSize w162h504 + MediaSize w41h248 + MediaSize w41h144 + MediaSize w153h198 + + Resolution k 1 0 0 0 136dpi + Resolution k 1 0 0 0 203dpi + *Resolution k 1 0 0 0 300dpi + + Darkness 0 Light + Darkness 1 Medium + *Darkness 2 Normal + Darkness 3 Dark +} + +// Epson +{ + Manufacturer "Epson" + DriverType epson + ManualCopies Yes + ColorDevice No + Throughput 1 + + HWMargins 0 0 0 0 + VariablePaperSize Yes + MinSize 36 36 + MaxSize 1080 86400 + + // Epson 24-Pin Series + { + ModelName "24-Pin Series" + Attribute NickName "" "Epson 24-Pin Series" + PCFileName "epson24.ppd" + ModelNumber $EPSON_24PIN + + HWMargins 18 18 18 18 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + MediaSize FanFoldUS + + Resolution k 1 8 0 0 60dpi + *Resolution k 1 8 0 0 120x60dpi + Resolution k 1 24 0 0 180dpi + Resolution k 1 24 0 0 360x180dpi + Resolution k 1 48 0 0 360dpi + } + + // Epson 9-Pin Series + { + ModelName "9-Pin Series" + Attribute NickName "" "Epson 9-Pin Series" + PCFileName "epson9.ppd" + ModelNumber $EPSON_9PIN + ColorDevice No + + HWMargins 18 18 18 18 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + MediaSize FanFoldUS + + Resolution k 1 8 0 0 60x72dpi + *Resolution k 1 8 0 0 120x72dpi + Resolution k 1 8 0 0 240x72dpi + } + + // Epson Stylus Color Series + { + ModelName "Stylus Color Series" + Attribute NickName "" "Epson Stylus Color Series" + PCFileName "stcolor.ppd" + ModelNumber $EPSON_COLOR + ColorDevice Yes + + HWMargins 8.6 39.6 8.6 25.51 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + + Resolution - 1 0 0 0 180dpi + *Resolution - 1 0 0 0 360dpi + Resolution - 1 0 0 0 720dpi + + *ColorModel CMYK cmyk banded 1 + ColorModel Gray/Grayscale k chunky 1 + } + + // Epson New Stylus Color Series + { + ModelName "New Stylus Color Series" + Attribute NickName "" "Epson New Stylus Color Series" + PCFileName "stcolor2.ppd" + ModelNumber $EPSON_ICOLOR + ColorDevice Yes + + HWMargins 8.6 39.6 8.6 25.51 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + + Resolution - 1 0 0 0 180dpi + *Resolution - 1 0 0 0 360dpi + Resolution - 1 0 0 0 720dpi + + *ColorModel CMYK cmyk banded 1 + ColorModel Gray/Grayscale k chunky 1 + } + + // Epson Stylus Color Series + { + ModelName "Stylus Photo Series" + Attribute NickName "" "Epson Stylus Photo Series" + PCFileName "stphoto.ppd" + ModelNumber $EPSON_PHOTO + ColorDevice Yes + + HWMargins 8.6 39.6 8.6 25.51 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + + Resolution - 1 0 0 0 180dpi + *Resolution - 1 0 0 0 360dpi + Resolution - 1 0 0 0 720dpi + + *ColorModel CMYK cmykcm banded 1 + ColorModel Gray/Grayscale k chunky 1 + } + + // Epson New Stylus Color Series + { + ModelName "New Stylus Photo Series" + Attribute NickName "" "Epson New Stylus Photo Series" + PCFileName "stphoto2.ppd" + ModelNumber $EPSON_IPHOTO + ColorDevice Yes + + HWMargins 8.6 39.6 8.6 25.51 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + + Resolution - 1 0 0 0 180dpi + *Resolution - 1 0 0 0 360dpi + Resolution - 1 0 0 0 720dpi + + *ColorModel CMYK cmykcm banded 1 + ColorModel Gray/Grayscale k chunky 1 + } +} + +// Generic drivers +{ + Manufacturer "Generic" + + // Generic PCL Laser Printer + { + DriverType hp + + ModelName "PCL Laser Printer" + Attribute NickName "" "Generic PCL Laser Printer" + PCFileName "generpcl.ppd" + Throughput 8 + ModelNumber $HP_LASERJET + ColorDevice No + + UIConstraints "*Duplex *Option1 False" + UIConstraints "*PageSize A3 *InputSlot Envelope" + UIConstraints "*PageSize A4 *InputSlot Envelope" + UIConstraints "*PageSize A5 *InputSlot Envelope" + UIConstraints "*PageSize B5 *InputSlot Envelope" + UIConstraints "*PageSize Executive *InputSlot Envelope" + UIConstraints "*PageSize Legal *InputSlot Envelope" + UIConstraints "*PageSize Letter *InputSlot Envelope" + UIConstraints "*PageSize Tabloid *InputSlot Envelope" + + HWMargins 18 12 18 12 + *MediaSize Letter + MediaSize Legal + MediaSize Executive + MediaSize Tabloid + MediaSize A3 + MediaSize A4 + MediaSize A5 + MediaSize B5 + MediaSize EnvISOB5 + MediaSize Env10 + MediaSize EnvC5 + MediaSize EnvDL + MediaSize EnvMonarch + + *Resolution k 1 0 0 0 300dpi + Resolution k 1 0 0 0 600dpi + + *InputSlot 0 "Default/Printer Default" + InputSlot 8 "Tray1/Tray 1" + InputSlot 1 "Tray2/Tray 2" + InputSlot 4 "Tray3/Tray 3" + InputSlot 5 "Tray4/Tray 4" + InputSlot 2 "Manual/Manual Feed" + InputSlot 3 "Envelope/Envelope Feed" + + Duplex Yes + Installable "Option1/Duplexer" + } + + // Generic PostScript Printer + { + DriverType ps + + ModelName "PostScript Printer" + Attribute NickName "" "Generic PostScript Printer" + PCFileName "generic.ppd" + Throughput 8 + ColorDevice Yes + Attribute PSVersion "" "(2016.0) 0" + Attribute LanguageLevel "" 2 + + UIConstraints "*Duplex *Option1 False" + + HWMargins 12 12 12 12 + *MediaSize Letter + MediaSize Legal + MediaSize Executive + MediaSize Tabloid + MediaSize A3 + MediaSize A4 + MediaSize A5 + MediaSize B5 + MediaSize EnvISOB5 + MediaSize Env10 + MediaSize EnvC5 + MediaSize EnvDL + MediaSize EnvMonarch + + Option "InputSlot/Media Source" PickOne AnySetup 10 + *Choice "Default/Printer Default" "" + Choice "Upper/Cassette" "<>setpagedevice" + Choice "Manual/Manual Feed" "<>setpagedevice" + + Duplex Yes + Installable "Option1/Duplexer" + Attribute "?Option1" "" "save currentpagedevice/Duplex known{(True)}{(False)}ifelse = flush restore" + } +} + +// HP +{ + Manufacturer "HP" + DriverType hp + + // HP DeskJet Series + { + ModelName "DeskJet Series" + Attribute NickName "" "HP DeskJet Series" + PCFileName "deskjet.ppd" + ModelNumber $HP_DESKJET + ManualCopies Yes + ColorDevice Yes + Throughput 1 + + UIConstraints "*PageSize A3 *InputSlot Envelope" + UIConstraints "*PageSize A4 *InputSlot Envelope" + UIConstraints "*PageSize A5 *InputSlot Envelope" + UIConstraints "*PageSize B5 *InputSlot Envelope" + UIConstraints "*PageSize Executive *InputSlot Envelope" + UIConstraints "*PageSize Legal *InputSlot Envelope" + UIConstraints "*PageSize Letter *InputSlot Envelope" + UIConstraints "*PageSize Tabloid *InputSlot Envelope" + + HWMargins 18 36 18 36 + *MediaSize Letter + MediaSize Legal + MediaSize Executive + MediaSize Tabloid + MediaSize A3 + MediaSize A4 + MediaSize A5 + MediaSize B5 + MediaSize EnvISOB5 + MediaSize Env10 + MediaSize EnvC5 + MediaSize EnvDL + MediaSize EnvMonarch + + ColorModel Gray/Grayscale k chunky 2 + ColorModel RGB/Color cmy banded 2 + *ColorModel CMYK kcmy banded 2 + + Resolution - 1 0 0 0 150dpi + *Resolution - 1 0 0 0 300dpi + Resolution - 1 0 0 0 600dpi + + *InputSlot 1 Tray + InputSlot 2 "Manual/Manual Feed" + InputSlot 3 "Envelope/Envelope Feed" + + *MediaType 0 "Plain/Plain Paper" + MediaType 1 "Bond/Bond Paper" + MediaType 2 "Special/Special Paper" + MediaType 3 Transparency + MediaType 4 "Glossy/Glossy Paper" + } + + // HP LaserJet Series PCL 4/5 + { + ModelName "LaserJet Series PCL 4/5" + Attribute NickName "" "HP LaserJet Series PCL 4/5" + PCFileName "laserjet.ppd" + Throughput 8 + ModelNumber $HP_LASERJET + ColorDevice No + + UIConstraints "*Duplex *Option1 False" + UIConstraints "*PageSize A3 *InputSlot Envelope" + UIConstraints "*PageSize A4 *InputSlot Envelope" + UIConstraints "*PageSize A5 *InputSlot Envelope" + UIConstraints "*PageSize B5 *InputSlot Envelope" + UIConstraints "*PageSize Executive *InputSlot Envelope" + UIConstraints "*PageSize Legal *InputSlot Envelope" + UIConstraints "*PageSize Letter *InputSlot Envelope" + UIConstraints "*PageSize Tabloid *InputSlot Envelope" + + HWMargins 18 36 18 36 + *MediaSize Letter + MediaSize Legal + MediaSize Executive + MediaSize Tabloid + MediaSize A3 + MediaSize A4 + MediaSize A5 + MediaSize B5 + MediaSize EnvISOB5 + MediaSize Env10 + MediaSize EnvC5 + MediaSize EnvDL + MediaSize EnvMonarch + + Resolution k 1 0 0 0 150dpi + *Resolution k 1 0 0 0 300dpi + Resolution k 1 0 0 0 600dpi + + *InputSlot 0 "Default/Printer Default" + InputSlot 8 "Tray1/Tray 1" + InputSlot 1 "Tray2/Tray 2" + InputSlot 4 "Tray3/Tray 3" + InputSlot 5 "Tray4/Tray 4" + InputSlot 2 "Manual/Manual Feed" + InputSlot 3 "Envelope/Envelope Feed" + + Duplex Yes + Installable "Option1/Duplexer" + } +} + +// Intellitech IntelliBar Series Label Printer +{ + Manufacturer "Intellitech" + ModelName "IntelliBar Label Printer" + Attribute ShortNickName "" "IntelliBar Label Printer" + PCFileName "intelbar.ppd" + DriverType label + ModelNumber $INTELLITECH_PCL + Throughput 8 + ColorDevice No + + HWMargins 0 5.76 0 5.76 + VariablePaperSize Yes + MinSize 36 36 + MaxSize 630 7128 + + UIConstraints "*inPrintMode Standard *inCutInterval" + UIConstraints "*inPrintMode Tear *inCutInterval" + UIConstraints "*inPrintMode Standard *inTearInterval" + UIConstraints "*inPrintMode Cut *inTearInterval" + + *MediaSize w288h432 + + *Resolution k 1 0 0 0 300dpi + + Group "PrinterSettings/Printer Settings" + Option "inPrintDensity/Print Density" PickOne DocumentSetup 20.0 + *Choice "Default/Printer Default" "<>setpagedevice" + Choice "-15/-15" "<>setpagedevice" + Choice "-14/-14" "<>setpagedevice" + Choice "-13/-13" "<>setpagedevice" + Choice "-12/-12" "<>setpagedevice" + Choice "-11/-11" "<>setpagedevice" + Choice "-10/-10" "<>setpagedevice" + Choice "-9/-9" "<>setpagedevice" + Choice "-8/-8" "<>setpagedevice" + Choice "-7/-7" "<>setpagedevice" + Choice "-6/-6" "<>setpagedevice" + Choice "-5/-5" "<>setpagedevice" + Choice "-4/-4" "<>setpagedevice" + Choice "-3/-3" "<>setpagedevice" + Choice "-2/-2" "<>setpagedevice" + Choice "-1/-1" "<>setpagedevice" + Choice "0/0" "<>setpagedevice" + Choice "1/1" "<>setpagedevice" + Choice "2/2" "<>setpagedevice" + Choice "3/3" "<>setpagedevice" + Choice "4/4" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "6/6" "<>setpagedevice" + Choice "7/7" "<>setpagedevice" + Choice "8/8" "<>setpagedevice" + Choice "9/9" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "11/11" "<>setpagedevice" + Choice "12/12" "<>setpagedevice" + Choice "13/13" "<>setpagedevice" + Choice "14/14" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Option "inPrintRate/Print Speed" PickOne DocumentSetup 20.0 + *Choice "Default/Printer Default" "<>setpagedevice" + Choice "15/15 mm/sec." "<>setpagedevice" + Choice "20/20 mm/sec." "<>setpagedevice" + Choice "30/30 mm/sec." "<>setpagedevice" + Choice "40/40 mm/sec." "<>setpagedevice" + Choice "60/60 mm/sec." "<>setpagedevice" + Choice "80/80 mm/sec." "<>setpagedevice" + Choice "100/100 mm/sec." "<>setpagedevice" + Choice "120/120 mm/sec." "<>setpagedevice" + Choice "150/150 mm/sec." "<>setpagedevice" + Choice "200/200 mm/sec." "<>setpagedevice" + Choice "250/250 mm/sec." "<>setpagedevice" + Choice "300/300 mm/sec." "<>setpagedevice" + Option "inPrintMode/Print Mode" PickOne DocumentSetup 20.0 + *Choice "Standard/Standard" "" + Choice "Tear/Tear" "" + Choice "Cut/Cut" "" + Option "inTearInterval/Print and Tear" PickOne DocumentSetup 20.0 + *Choice "None/Disabled" "<>setpagedevice" + Choice "1/Every Label" "<>setpagedevice" + Choice "2/Every 2 Labels" "<>setpagedevice" + Choice "3/Every 3 Labels" "<>setpagedevice" + Choice "4/Every 4 Labels" "<>setpagedevice" + Choice "5/Every 5 Labels" "<>setpagedevice" + Choice "6/Every 6 Labels" "<>setpagedevice" + Choice "7/Every 7 Labels" "<>setpagedevice" + Choice "8/Every 8 Labels" "<>setpagedevice" + Choice "9/Every 9 Labels" "<>setpagedevice" + Choice "10/Every 10 Labels" "<>setpagedevice" + Attribute CustominTearInterval True "<>setpagedevice" + Attribute ParamCustominTearInterval Interval "1 int 1 99" + Option "inCutInterval/Print and Cut" PickOne DocumentSetup 20.0 + *Choice "None/Disabled" "<>setpagedevice" + Choice "1/Every Label" "<>setpagedevice" + Choice "2/Every 2 Labels" "<>setpagedevice" + Choice "3/Every 3 Labels" "<>setpagedevice" + Choice "4/Every 4 Labels" "<>setpagedevice" + Choice "5/Every 5 Labels" "<>setpagedevice" + Choice "6/Every 6 Labels" "<>setpagedevice" + Choice "7/Every 7 Labels" "<>setpagedevice" + Choice "8/Every 8 Labels" "<>setpagedevice" + Choice "9/Every 9 Labels" "<>setpagedevice" + Choice "10/Every 10 Labels" "<>setpagedevice" + Attribute CustominCutInterval True "<>setpagedevice" + Attribute ParamCustominCutInterval Interval "1 int 1 99" +} + +// Oki +{ + Manufacturer "Oki" + DriverType epson + ManualCopies Yes + ColorDevice No + Throughput 1 + + HWMargins 18 18 18 18 + *MediaSize Letter + MediaSize Legal + MediaSize A4 + MediaSize FanFoldUS + + HWMargins 0 0 0 0 + VariablePaperSize Yes + MinSize 36 36 + MaxSize 1080 86400 + + // Oki 24-Pin Series + { + ModelName "24-Pin Series" + Attribute NickName "" "Oki 24-Pin Series" + PCFileName "okidat24.ppd" + ModelNumber $EPSON_24PIN + + Resolution k 1 8 0 0 60dpi + *Resolution k 1 8 0 0 120x60dpi + Resolution k 1 24 0 0 180dpi + Resolution k 1 24 0 0 360x180dpi + Resolution k 1 48 0 0 360dpi + } + + // Oki 9-Pin Series + { + ModelName "9-Pin Series" + Attribute NickName "" "Oki 9-Pin Series" + PCFileName "okidata9.ppd" + ModelNumber $EPSON_9PIN + ColorDevice No + + Resolution k 1 8 0 0 60x72dpi + *Resolution k 1 8 0 0 120x72dpi + Resolution k 1 8 0 0 240x72dpi + } +} + + +// Zebra +{ + Manufacturer "Zebra" + DriverType label + Throughput 8 + ColorDevice False + + // Zebra CPCL Label Printer + { + ModelName "CPCL Label Printer" + Attribute NickName "" "Zebra CPCL Label Printer" + PCFileName "zebracpl.ppd" + ModelNumber $ZEBRA_CPCL + + HWMargins 0 0 0 0 + MediaSize w144h72 + MediaSize w144h90 + MediaSize w144h144 + MediaSize w144h216 + MediaSize w209h72 + + HWMargins 0 0 1 0 + MediaSize w288h144 + MediaSize w288h216 + MediaSize w288h288 + *MediaSize w288h360 + MediaSize w288h432 + + VariablePaperSize Yes + HWMargins 0 0 1 0 + MinSize 36 36 + MaxSize 288 3600 + + *Resolution k 1 0 0 0 203dpi + + Group "General/General" + Option "zeMediaTracking/Media Tracking" PickOne AnySetup 20.0 + Choice "Continuous/Continuous" "" + *Choice "Web/Non-continuous (Web sensing)" "" + Choice "Mark/Non-continuous (Mark sensing)" "" + + Group "PrinterSettings/Printer Settings" + Option "Darkness" PickOne AnySetup 20.0 + *Choice "-1/Printer Default" "<>setpagedevice" + Choice "1/1" "<>setpagedevice" + Choice "2/2" "<>setpagedevice" + Choice "3/3" "<>setpagedevice" + Choice "4/4" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "6/6" "<>setpagedevice" + Choice "7/7" "<>setpagedevice" + Choice "8/8" "<>setpagedevice" + Choice "9/9" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "11/11" "<>setpagedevice" + Choice "12/12" "<>setpagedevice" + Choice "13/13" "<>setpagedevice" + Choice "14/14" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "16/16" "<>setpagedevice" + Choice "17/17" "<>setpagedevice" + Choice "18/18" "<>setpagedevice" + Choice "19/19" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "21/21" "<>setpagedevice" + Choice "22/22" "<>setpagedevice" + Choice "23/23" "<>setpagedevice" + Choice "24/24" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "26/26" "<>setpagedevice" + Choice "27/27" "<>setpagedevice" + Choice "28/28" "<>setpagedevice" + Choice "29/29" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Option "zePrintRate/Print Rate" PickOne AnySetup 20.0 + *Choice "Default/Printer Default" "" + Choice "1/1 inch/sec." "" + Choice "2/2 inches/sec." "" + Choice "3/3 inches/sec." "" + Choice "4/4 inches/sec." "" + Option "zeTearOffPosition/Tear-Off Adjust Position" PickOne AnySetup 20.0 + *Choice "1000/Printer Default" "<>setpagedevice" + Choice "-120/-120" "<>setpagedevice" + Choice "-115/-115" "<>setpagedevice" + Choice "-110/-110" "<>setpagedevice" + Choice "-105/-105" "<>setpagedevice" + Choice "-100/-100" "<>setpagedevice" + Choice "-95/-95" "<>setpagedevice" + Choice "-90/-90" "<>setpagedevice" + Choice "-85/-85" "<>setpagedevice" + Choice "-80/-80" "<>setpagedevice" + Choice "-75/-75" "<>setpagedevice" + Choice "-70/-70" "<>setpagedevice" + Choice "-65/-65" "<>setpagedevice" + Choice "-60/-60" "<>setpagedevice" + Choice "-55/-55" "<>setpagedevice" + Choice "-50/-50" "<>setpagedevice" + Choice "-45/-45" "<>setpagedevice" + Choice "-40/-40" "<>setpagedevice" + Choice "-35/-35" "<>setpagedevice" + Choice "-30/-30" "<>setpagedevice" + Choice "-25/-25" "<>setpagedevice" + Choice "-20/-20" "<>setpagedevice" + Choice "-15/-15" "<>setpagedevice" + Choice "-10/-10" "<>setpagedevice" + Choice "-5/-5" "<>setpagedevice" + Choice "0/0" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Choice "35/35" "<>setpagedevice" + Choice "40/40" "<>setpagedevice" + Choice "45/45" "<>setpagedevice" + Choice "50/50" "<>setpagedevice" + Choice "55/55" "<>setpagedevice" + Choice "60/60" "<>setpagedevice" + Choice "65/65" "<>setpagedevice" + Choice "70/70" "<>setpagedevice" + Choice "75/75" "<>setpagedevice" + Choice "80/80" "<>setpagedevice" + Choice "85/85" "<>setpagedevice" + Choice "90/90" "<>setpagedevice" + Choice "95/95" "<>setpagedevice" + Choice "100/100" "<>setpagedevice" + Choice "105/105" "<>setpagedevice" + Choice "110/110" "<>setpagedevice" + Choice "115/115" "<>setpagedevice" + Choice "120/120" "<>setpagedevice" + Option "zeErrorReprint/Reprint After Error" PickOne AnySetup 20.0 + *Choice "Saved/Printer Default" "" + Choice "Always/Always" "" + Choice "Never/Never" "" + } + + // Zebra EPL1 Label Printer + { + ModelName "EPL1 Label Printer" + Attribute NickName "" "Zebra EPL1 Label Printer" + PCFileName "zebraep1.ppd" + ModelNumber $ZEBRA_EPL_LINE + + HWMargins 0 0 0 0 + VariablePaperSize Yes + MinSize 36 36 + MaxSize 288 3600 + + MediaSize w90h18 + MediaSize w90h162 + MediaSize w108h18 + MediaSize w108h36 + MediaSize w108h72 + MediaSize w108h144 + MediaSize w144h26 + MediaSize w144h36 + MediaSize w144h72 + MediaSize w144h90 + MediaSize w144h288 + MediaSize w144h396 + MediaSize w162h36 + MediaSize w162h90 + MediaSize w162h288 + MediaSize w162h396 + MediaSize w171h396 + MediaSize w180h72 + MediaSize w180h144 + MediaSize w198h90 + MediaSize w216h72 + MediaSize w216h90 + MediaSize w216h144 + MediaSize w216h216 + MediaSize w216h360 + MediaSize w234h144 + MediaSize w234h360 + MediaSize w234h396 + MediaSize w234h419 + MediaSize w234h563 + MediaSize w252h72 + MediaSize w288h72 + MediaSize w288h144 + MediaSize w288h180 + MediaSize w288h216 + MediaSize w288h288 + *MediaSize w288h360 + MediaSize w288h432 + MediaSize w288h468 + MediaSize w288h936 + + *Resolution k 1 0 0 0 203dpi + Resolution k 1 0 0 0 300dpi + Resolution k 1 0 0 0 600dpi + + Group "PrinterSettings/Printer Settings" + Option "Darkness" PickOne AnySetup 20.0 + *Choice "-1/Printer Default" "<>setpagedevice" + Choice "1/1" "<>setpagedevice" + Choice "2/2" "<>setpagedevice" + Choice "3/3" "<>setpagedevice" + Choice "4/4" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "6/6" "<>setpagedevice" + Choice "7/7" "<>setpagedevice" + Choice "8/8" "<>setpagedevice" + Choice "9/9" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "11/11" "<>setpagedevice" + Choice "12/12" "<>setpagedevice" + Choice "13/13" "<>setpagedevice" + Choice "14/14" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "16/16" "<>setpagedevice" + Choice "17/17" "<>setpagedevice" + Choice "18/18" "<>setpagedevice" + Choice "19/19" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "21/21" "<>setpagedevice" + Choice "22/22" "<>setpagedevice" + Choice "23/23" "<>setpagedevice" + Choice "24/24" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "26/26" "<>setpagedevice" + Choice "27/27" "<>setpagedevice" + Choice "28/28" "<>setpagedevice" + Choice "29/29" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Option "zePrintRate/Print Rate" PickOne AnySetup 20.0 + *Choice "Default/Printer Default" "" + Choice "1/1 inch/sec." "" + Choice "1.5/1.5 inch/sec." "" + Choice "2/2 inches/sec." "" + Choice "2.5/2.5 inches/sec." "" + } + + // Zebra EPL2 Label Printer + { + ModelName "EPL2 Label Printer" + Attribute NickName "" "Zebra EPL2 Label Printer" + PCFileName "zebraep2.ppd" + ModelNumber $ZEBRA_EPL_PAGE + + HWMargins 0 0 0 0 + VariablePaperSize Yes + MinSize 36 36 + MaxSize 288 3600 + + MediaSize w90h18 + MediaSize w90h162 + MediaSize w108h18 + MediaSize w108h36 + MediaSize w108h72 + MediaSize w108h144 + MediaSize w144h26 + MediaSize w144h36 + MediaSize w144h72 + MediaSize w144h90 + MediaSize w144h288 + MediaSize w144h396 + MediaSize w162h36 + MediaSize w162h90 + MediaSize w162h288 + MediaSize w162h396 + MediaSize w171h396 + MediaSize w180h72 + MediaSize w180h144 + MediaSize w198h90 + MediaSize w216h72 + MediaSize w216h90 + MediaSize w216h144 + MediaSize w216h216 + MediaSize w216h360 + MediaSize w234h144 + MediaSize w234h360 + MediaSize w234h396 + MediaSize w234h419 + MediaSize w234h563 + MediaSize w252h72 + MediaSize w288h72 + MediaSize w288h144 + MediaSize w288h180 + MediaSize w288h216 + MediaSize w288h288 + *MediaSize w288h360 + MediaSize w288h432 + MediaSize w288h468 + MediaSize w288h936 + + *Resolution k 1 0 0 0 203dpi + Resolution k 1 0 0 0 300dpi + Resolution k 1 0 0 0 600dpi + + Group "General/General" + Option "MediaType/Media Type" PickOne AnySetup 20.0 + *Choice "Saved/Printer Default" "" + Choice "Thermal/Thermal Transfer Media" "<>setpagedevice" + Choice "Direct/Direct Thermal Media" "<>setpagedevice" + Group "PrinterSettings/Printer Settings" + Option "Darkness" PickOne AnySetup 20.0 + *Choice "-1/Printer Default" "<>setpagedevice" + Choice "1/1" "<>setpagedevice" + Choice "2/2" "<>setpagedevice" + Choice "3/3" "<>setpagedevice" + Choice "4/4" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "6/6" "<>setpagedevice" + Choice "7/7" "<>setpagedevice" + Choice "8/8" "<>setpagedevice" + Choice "9/9" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "11/11" "<>setpagedevice" + Choice "12/12" "<>setpagedevice" + Choice "13/13" "<>setpagedevice" + Choice "14/14" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "16/16" "<>setpagedevice" + Choice "17/17" "<>setpagedevice" + Choice "18/18" "<>setpagedevice" + Choice "19/19" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "21/21" "<>setpagedevice" + Choice "22/22" "<>setpagedevice" + Choice "23/23" "<>setpagedevice" + Choice "24/24" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "26/26" "<>setpagedevice" + Choice "27/27" "<>setpagedevice" + Choice "28/28" "<>setpagedevice" + Choice "29/29" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Option "zePrintRate/Print Rate" PickOne AnySetup 20.0 + *Choice "Default/Printer Default" "" + Choice "1/1 inch/sec." "" + Choice "1.5/1.5 inch/sec." "" + Choice "2/2 inches/sec." "" + Choice "2.5/2.5 inches/sec." "" + Choice "3/3 inches/sec." "" + Choice "4/4 inches/sec." "" + Choice "5/5 inches/sec." "" + Choice "6/6 inches/sec." "" + } + + // Zebra ZPL Label Printer + { + ModelName "ZPL Label Printer" + Attribute NickName "" "Zebra ZPL Label Printer" + PCFileName "zebra.ppd" + ModelNumber $ZEBRA_ZPL + + HWMargins 0 0 0 0 + VariablePaperSize Yes + MinSize 36 36 + MaxSize 576 3600 + + MediaSize w90h18 + MediaSize w90h162 + MediaSize w108h18 + MediaSize w108h36 + MediaSize w108h72 + MediaSize w108h144 + MediaSize w144h26 + MediaSize w144h36 + MediaSize w144h72 + MediaSize w144h90 + MediaSize w144h288 + MediaSize w144h396 + MediaSize w162h36 + MediaSize w162h90 + MediaSize w162h288 + MediaSize w162h396 + MediaSize w171h396 + MediaSize w180h72 + MediaSize w180h144 + MediaSize w198h90 + MediaSize w216h72 + MediaSize w216h90 + MediaSize w216h144 + MediaSize w216h216 + MediaSize w216h360 + MediaSize w234h144 + MediaSize w234h360 + MediaSize w234h396 + MediaSize w234h419 + MediaSize w234h563 + MediaSize w252h72 + MediaSize w288h72 + MediaSize w288h144 + MediaSize w288h180 + MediaSize w288h216 + MediaSize w288h288 + *MediaSize w288h360 + MediaSize w288h432 + MediaSize w288h468 + MediaSize w288h936 + MediaSize w432h72 + MediaSize w432h144 + MediaSize w432h216 + MediaSize w432h288 + MediaSize w432h360 + MediaSize w432h432 + MediaSize w432h468 + MediaSize w576h72 + MediaSize w576h144 + MediaSize w576h216 + MediaSize w576h288 + MediaSize w576h360 + MediaSize w576h432 + MediaSize w576h468 + + *Resolution k 1 0 0 0 203dpi + Resolution k 1 0 0 0 300dpi + Resolution k 1 0 0 0 600dpi + + Group "General/General" + Option "zeMediaTracking/Media Tracking" PickOne AnySetup 20.0 + Choice "Continuous/Continuous" "" + *Choice "Web/Non-continuous (Web sensing)" "" + Choice "Mark/Non-continuous (Mark sensing)" "" + Option "MediaType/Media Type" PickOne AnySetup 20.0 + *Choice "Saved/Printer Default" "" + Choice "Thermal/Thermal Transfer Media" "<>setpagedevice" + Choice "Direct/Direct Thermal Media" "<>setpagedevice" + Group "PrinterSettings/Printer Settings" + Option "Darkness" PickOne AnySetup 20.0 + *Choice "-1/Printer Default" "<>setpagedevice" + Choice "1/1" "<>setpagedevice" + Choice "2/2" "<>setpagedevice" + Choice "3/3" "<>setpagedevice" + Choice "4/4" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "6/6" "<>setpagedevice" + Choice "7/7" "<>setpagedevice" + Choice "8/8" "<>setpagedevice" + Choice "9/9" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "11/11" "<>setpagedevice" + Choice "12/12" "<>setpagedevice" + Choice "13/13" "<>setpagedevice" + Choice "14/14" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "16/16" "<>setpagedevice" + Choice "17/17" "<>setpagedevice" + Choice "18/18" "<>setpagedevice" + Choice "19/19" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "21/21" "<>setpagedevice" + Choice "22/22" "<>setpagedevice" + Choice "23/23" "<>setpagedevice" + Choice "24/24" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "26/26" "<>setpagedevice" + Choice "27/27" "<>setpagedevice" + Choice "28/28" "<>setpagedevice" + Choice "29/29" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Option "zePrintRate/Print Rate" PickOne AnySetup 20.0 + *Choice "Default/Printer Default" "" + Choice "1/1 inch/sec." "" + Choice "2/2 inches/sec." "" + Choice "3/3 inches/sec." "" + Choice "4/4 inches/sec." "" + Choice "5/5 inches/sec." "" + Choice "6/6 inches/sec." "" + Choice "7/7 inches/sec." "" + Choice "8/8 inches/sec." "" + Choice "9/9 inches/sec." "" + Choice "10/10 inches/sec." "" + Choice "11/11 inches/sec." "" + Choice "12/12 inches/sec." "" + Option "zeLabelTop/Label Top" PickOne AnySetup 20.0 + *Choice "200/Printer Default" "<>setpagedevice" + Choice "-120/-120" "<>setpagedevice" + Choice "-115/-115" "<>setpagedevice" + Choice "-110/-110" "<>setpagedevice" + Choice "-105/-105" "<>setpagedevice" + Choice "-100/-100" "<>setpagedevice" + Choice "-95/-95" "<>setpagedevice" + Choice "-90/-90" "<>setpagedevice" + Choice "-85/-85" "<>setpagedevice" + Choice "-80/-80" "<>setpagedevice" + Choice "-75/-75" "<>setpagedevice" + Choice "-70/-70" "<>setpagedevice" + Choice "-65/-65" "<>setpagedevice" + Choice "-60/-60" "<>setpagedevice" + Choice "-55/-55" "<>setpagedevice" + Choice "-50/-50" "<>setpagedevice" + Choice "-45/-45" "<>setpagedevice" + Choice "-40/-40" "<>setpagedevice" + Choice "-35/-35" "<>setpagedevice" + Choice "-30/-30" "<>setpagedevice" + Choice "-25/-25" "<>setpagedevice" + Choice "-20/-20" "<>setpagedevice" + Choice "-15/-15" "<>setpagedevice" + Choice "-10/-10" "<>setpagedevice" + Choice "-5/-5" "<>setpagedevice" + Choice "0/0" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Choice "35/35" "<>setpagedevice" + Choice "40/40" "<>setpagedevice" + Choice "45/45" "<>setpagedevice" + Choice "50/50" "<>setpagedevice" + Choice "55/55" "<>setpagedevice" + Choice "60/60" "<>setpagedevice" + Choice "65/65" "<>setpagedevice" + Choice "70/70" "<>setpagedevice" + Choice "75/75" "<>setpagedevice" + Choice "80/80" "<>setpagedevice" + Choice "85/85" "<>setpagedevice" + Choice "90/90" "<>setpagedevice" + Choice "95/95" "<>setpagedevice" + Choice "100/100" "<>setpagedevice" + Choice "105/105" "<>setpagedevice" + Choice "110/110" "<>setpagedevice" + Choice "115/115" "<>setpagedevice" + Choice "120/120" "<>setpagedevice" + Option "zePrintMode/Print Mode" PickOne AnySetup 20.0 + *Choice "Saved/Printer Default" "" + Choice "Tear/Tear-Off" "" + Choice "Peel/Peel-Off" "" + Choice "Rewind/Rewind" "" + Choice "Applicator/Applicator" "" + Choice "Cutter/Cutter" "" + Option "zeTearOffPosition/Tear-Off Adjust Position" PickOne AnySetup 20.0 + *Choice "1000/Printer Default" "<>setpagedevice" + Choice "-120/-120" "<>setpagedevice" + Choice "-115/-115" "<>setpagedevice" + Choice "-110/-110" "<>setpagedevice" + Choice "-105/-105" "<>setpagedevice" + Choice "-100/-100" "<>setpagedevice" + Choice "-95/-95" "<>setpagedevice" + Choice "-90/-90" "<>setpagedevice" + Choice "-85/-85" "<>setpagedevice" + Choice "-80/-80" "<>setpagedevice" + Choice "-75/-75" "<>setpagedevice" + Choice "-70/-70" "<>setpagedevice" + Choice "-65/-65" "<>setpagedevice" + Choice "-60/-60" "<>setpagedevice" + Choice "-55/-55" "<>setpagedevice" + Choice "-50/-50" "<>setpagedevice" + Choice "-45/-45" "<>setpagedevice" + Choice "-40/-40" "<>setpagedevice" + Choice "-35/-35" "<>setpagedevice" + Choice "-30/-30" "<>setpagedevice" + Choice "-25/-25" "<>setpagedevice" + Choice "-20/-20" "<>setpagedevice" + Choice "-15/-15" "<>setpagedevice" + Choice "-10/-10" "<>setpagedevice" + Choice "-5/-5" "<>setpagedevice" + Choice "0/0" "<>setpagedevice" + Choice "5/5" "<>setpagedevice" + Choice "10/10" "<>setpagedevice" + Choice "15/15" "<>setpagedevice" + Choice "20/20" "<>setpagedevice" + Choice "25/25" "<>setpagedevice" + Choice "30/30" "<>setpagedevice" + Choice "35/35" "<>setpagedevice" + Choice "40/40" "<>setpagedevice" + Choice "45/45" "<>setpagedevice" + Choice "50/50" "<>setpagedevice" + Choice "55/55" "<>setpagedevice" + Choice "60/60" "<>setpagedevice" + Choice "65/65" "<>setpagedevice" + Choice "70/70" "<>setpagedevice" + Choice "75/75" "<>setpagedevice" + Choice "80/80" "<>setpagedevice" + Choice "85/85" "<>setpagedevice" + Choice "90/90" "<>setpagedevice" + Choice "95/95" "<>setpagedevice" + Choice "100/100" "<>setpagedevice" + Choice "105/105" "<>setpagedevice" + Choice "110/110" "<>setpagedevice" + Choice "115/115" "<>setpagedevice" + Choice "120/120" "<>setpagedevice" + Option "zeErrorReprint/Reprint After Error" PickOne AnySetup 20.0 + *Choice "Saved/Printer Default" "" + Choice "Always/Always" "" + Choice "Never/Never" "" + } +} + +// +// End of "$Id$". +// diff --git a/ppdc/testcatalog.cxx b/ppdc/testcatalog.cxx new file mode 100644 index 0000000000..a9e2e86556 --- /dev/null +++ b/ppdc/testcatalog.cxx @@ -0,0 +1,63 @@ +// +// "$Id$" +// +// Test program for message catalog class. +// +// Copyright 2008 by Apple Inc. +// +// These coded instructions, statements, and computer programs are the +// property of Apple Inc. 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 +// file is missing or damaged, see the license at "http://www.cups.org/". +// +// Contents: +// +// main() - Open a message catalog +// + +// +// Include necessary headers... +// + +#include "ppdc-private.h" + + +// +// 'main()' - Open a message catalog +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + ppdcCatalog *catalog; // Message catalog + ppdcMessage *m; // Current message + + + if (argc != 2) + { + puts("Usage: testcatalog filename"); + return (1); + } + + // Scan the command-line... + catalog = new ppdcCatalog(NULL, argv[1]); + + printf("%s: %d messages\n", argv[1], catalog->messages->count); + + for (m = (ppdcMessage *)catalog->messages->first(); + m; + m = (ppdcMessage *)catalog->messages->next()) + printf("%s: %s\n", m->id->value, m->string->value); + + catalog->release(); + + // Return with no errors. + return (0); +} + + +// +// End of "$Id$". +// diff --git a/scheduler/Dependencies b/scheduler/Dependencies new file mode 100644 index 0000000000..6a858b59a6 --- /dev/null +++ b/scheduler/Dependencies @@ -0,0 +1,260 @@ +# DO NOT DELETE + +auth.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +auth.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +auth.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +auth.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +auth.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +auth.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h auth.h +auth.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h +auth.o: conf.h banners.h dirsvc.h network.h subscriptions.h +banners.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +banners.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +banners.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +banners.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +banners.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +banners.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +banners.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h +banners.o: classes.h job.h conf.h banners.h dirsvc.h network.h +banners.o: subscriptions.h ../cups/dir.h +cert.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +cert.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +cert.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +cert.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +cert.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +cert.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h auth.h +cert.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h +cert.o: conf.h banners.h dirsvc.h network.h subscriptions.h +classes.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +classes.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +classes.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +classes.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +classes.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +classes.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +classes.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h +classes.o: classes.h job.h conf.h banners.h dirsvc.h network.h +classes.o: subscriptions.h +client.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +client.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +client.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +client.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +client.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +client.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +client.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +client.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +conf.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +conf.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +conf.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +conf.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +conf.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +conf.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h auth.h +conf.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h +conf.o: conf.h banners.h dirsvc.h network.h subscriptions.h +dirsvc.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +dirsvc.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +dirsvc.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +dirsvc.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +dirsvc.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +dirsvc.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +dirsvc.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +dirsvc.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +env.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +env.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +env.o: ../cups/string.h ../cups/array.h ../cups/cups.h ../cups/ppd.h +env.o: ../cups/array.h ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h +env.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +env.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +env.o: printers.h ../cups/pwg-private.h classes.h job.h conf.h banners.h +env.o: dirsvc.h network.h subscriptions.h +main.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +main.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +main.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +main.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +main.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +main.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h auth.h +main.o: client.h policy.h printers.h ../cups/pwg-private.h classes.h job.h +main.o: conf.h banners.h dirsvc.h network.h subscriptions.h ../cups/dir.h +ipp.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +ipp.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +ipp.o: ../cups/string.h ../cups/array.h ../cups/cups.h ../cups/ppd.h +ipp.o: ../cups/array.h ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h +ipp.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +ipp.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +ipp.o: printers.h ../cups/pwg-private.h classes.h job.h conf.h banners.h +ipp.o: dirsvc.h network.h subscriptions.h ../cups/ppd-private.h +ipp.o: ../cups/cups.h +listen.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +listen.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +listen.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +listen.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +listen.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +listen.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +listen.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +listen.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +job.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +job.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +job.o: ../cups/string.h ../cups/array.h ../cups/cups.h ../cups/ppd.h +job.o: ../cups/array.h ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h +job.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +job.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +job.o: printers.h ../cups/pwg-private.h classes.h job.h conf.h banners.h +job.o: dirsvc.h network.h subscriptions.h ../cups/backend.h ../cups/dir.h +log.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +log.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h ../cups/ipp.h +log.o: ../cups/string.h ../cups/array.h ../cups/cups.h ../cups/ppd.h +log.o: ../cups/array.h ../cups/file.h ../cups/language.h mime.h ../cups/ipp.h +log.o: ../cups/file.h ../cups/http.h ../cups/i18n.h ../cups/transcode.h +log.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h policy.h +log.o: printers.h ../cups/pwg-private.h classes.h job.h conf.h banners.h +log.o: dirsvc.h network.h subscriptions.h +network.o: ../cups/http-private.h ../config.h ../cups/http.h +network.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +network.o: ../cups/ipp.h cupsd.h ../cups/string.h ../cups/array.h +network.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +network.o: ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h +network.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +network.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +network.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h +network.o: network.h subscriptions.h +policy.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +policy.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +policy.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +policy.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +policy.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +policy.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +policy.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +policy.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +printers.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +printers.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +printers.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +printers.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +printers.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +printers.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +printers.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h +printers.o: classes.h job.h conf.h banners.h dirsvc.h network.h +printers.o: subscriptions.h ../cups/dir.h +process.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +process.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +process.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +process.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +process.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +process.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +process.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h +process.o: classes.h job.h conf.h banners.h dirsvc.h network.h +process.o: subscriptions.h +quotas.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +quotas.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +quotas.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +quotas.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +quotas.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +quotas.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +quotas.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +quotas.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +removefile.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +removefile.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +removefile.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +removefile.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +removefile.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h +removefile.o: ../cups/i18n.h ../cups/transcode.h ../cups/debug.h sysman.h +removefile.o: statbuf.h cert.h auth.h client.h policy.h printers.h +removefile.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h +removefile.o: network.h subscriptions.h +select.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +select.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +select.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +select.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +select.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +select.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +select.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +select.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +server.o: ../cups/http-private.h ../config.h ../cups/http.h +server.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +server.o: ../cups/ipp.h cupsd.h ../cups/string.h ../cups/array.h +server.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +server.o: ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h +server.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h ../cups/debug.h +server.o: sysman.h statbuf.h cert.h auth.h client.h policy.h printers.h +server.o: ../cups/pwg-private.h classes.h job.h conf.h banners.h dirsvc.h +server.o: network.h subscriptions.h +statbuf.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +statbuf.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +statbuf.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +statbuf.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +statbuf.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +statbuf.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +statbuf.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h +statbuf.o: classes.h job.h conf.h banners.h dirsvc.h network.h +statbuf.o: subscriptions.h +subscriptions.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +subscriptions.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +subscriptions.o: ../cups/ipp.h ../cups/string.h ../cups/array.h +subscriptions.o: ../cups/cups.h ../cups/ppd.h ../cups/array.h ../cups/file.h +subscriptions.o: ../cups/language.h mime.h ../cups/ipp.h ../cups/file.h +subscriptions.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h +subscriptions.o: ../cups/debug.h sysman.h statbuf.h cert.h auth.h client.h +subscriptions.o: policy.h printers.h ../cups/pwg-private.h classes.h job.h +subscriptions.o: conf.h banners.h dirsvc.h network.h subscriptions.h +sysman.o: cupsd.h ../cups/http-private.h ../config.h ../cups/http.h +sysman.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +sysman.o: ../cups/ipp.h ../cups/string.h ../cups/array.h ../cups/cups.h +sysman.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +sysman.o: mime.h ../cups/ipp.h ../cups/file.h ../cups/http.h ../cups/i18n.h +sysman.o: ../cups/transcode.h ../cups/debug.h sysman.h statbuf.h cert.h +sysman.o: auth.h client.h policy.h printers.h ../cups/pwg-private.h classes.h +sysman.o: job.h conf.h banners.h dirsvc.h network.h subscriptions.h +filter.o: ../cups/debug.h ../cups/string.h ../config.h mime.h ../cups/array.h +filter.o: ../cups/versioning.h ../cups/ipp.h ../cups/file.h +mime.o: ../cups/debug.h ../cups/dir.h ../cups/versioning.h ../cups/string.h +mime.o: ../config.h mime.h ../cups/array.h ../cups/ipp.h ../cups/file.h +type.o: ../cups/string.h ../config.h mime.h ../cups/array.h +type.o: ../cups/versioning.h ../cups/ipp.h ../cups/file.h ../cups/debug.h +cupsfilter.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +cupsfilter.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +cupsfilter.o: ../cups/file.h ../cups/language.h ../cups/i18n.h +cupsfilter.o: ../cups/transcode.h ../cups/string.h ../config.h mime.h +cupsfilter.o: ../cups/array.h ../cups/ipp.h ../cups/file.h +cups-deviced.o: util.h ../cups/file-private.h ../cups/http-private.h +cups-deviced.o: ../config.h ../cups/http.h ../cups/versioning.h ../cups/md5.h +cups-deviced.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/globals.h +cups-deviced.o: ../cups/string.h ../cups/cups.h ../cups/i18n.h +cups-deviced.o: ../cups/transcode.h ../cups/language.h ../cups/array.h +cups-deviced.o: ../cups/pwg-private.h ../cups/cups.h ../cups/ppd.h +cups-deviced.o: ../cups/file.h ../cups/debug.h ../cups/array.h ../cups/dir.h +cups-lpd.o: ../cups/http-private.h ../config.h ../cups/http.h +cups-lpd.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +cups-lpd.o: ../cups/ipp.h ../cups/cups.h ../cups/ppd.h ../cups/array.h +cups-lpd.o: ../cups/file.h ../cups/language.h ../cups/string.h +cups-lpd.o: ../cups/language.h +cups-polld.o: ../cups/http-private.h ../config.h ../cups/http.h +cups-polld.o: ../cups/versioning.h ../cups/md5.h ../cups/ipp-private.h +cups-polld.o: ../cups/ipp.h ../cups/cups.h ../cups/ppd.h ../cups/array.h +cups-polld.o: ../cups/file.h ../cups/language.h ../cups/language.h +cups-polld.o: ../cups/string.h +testdirsvc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +testdirsvc.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +testdirsvc.o: ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +testlpd.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +testlpd.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testlpd.o: ../cups/string.h ../config.h +testmime.o: ../cups/string.h ../config.h mime.h ../cups/array.h +testmime.o: ../cups/versioning.h ../cups/ipp.h ../cups/file.h ../cups/dir.h +testspeed.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +testspeed.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testspeed.o: ../cups/array.h ../cups/file.h ../cups/language.h +testspeed.o: ../cups/language.h ../cups/debug.h +testsub.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +testsub.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +testsub.o: ../cups/debug.h ../cups/string.h ../config.h +util.o: util.h ../cups/file-private.h ../cups/http-private.h ../config.h +util.o: ../cups/http.h ../cups/versioning.h ../cups/md5.h +util.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/globals.h +util.o: ../cups/string.h ../cups/cups.h ../cups/i18n.h ../cups/transcode.h +util.o: ../cups/language.h ../cups/array.h ../cups/debug.h +cups-driverd.o: util.h ../cups/file-private.h ../cups/http-private.h +cups-driverd.o: ../config.h ../cups/http.h ../cups/versioning.h ../cups/md5.h +cups-driverd.o: ../cups/ipp-private.h ../cups/ipp.h ../cups/globals.h +cups-driverd.o: ../cups/string.h ../cups/cups.h ../cups/i18n.h +cups-driverd.o: ../cups/transcode.h ../cups/language.h ../cups/array.h +cups-driverd.o: ../cups/debug.h ../cups/dir.h ../cups/transcode.h +cups-driverd.o: ../cups/ppd-private.h ../ppdc/ppdc.h ../cups/string.h +cups-driverd.o: ../cups/file.h diff --git a/scheduler/Makefile b/scheduler/Makefile new file mode 100644 index 0000000000..55bb20776e --- /dev/null +++ b/scheduler/Makefile @@ -0,0 +1,484 @@ +# +# "$Id$" +# +# Scheduler Makefile for CUPS. +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +CUPSDOBJS = \ + auth.o \ + banners.o \ + cert.o \ + classes.o \ + client.o \ + conf.o \ + dirsvc.o \ + env.o \ + main.o \ + ipp.o \ + listen.o \ + job.o \ + log.o \ + network.o \ + policy.o \ + printers.o \ + process.o \ + quotas.o \ + removefile.o \ + select.o \ + server.o \ + statbuf.o \ + subscriptions.o \ + sysman.o +LIBOBJS = \ + filter.o \ + mime.o \ + type.o +COBJS = \ + $(CUPSDOBJS) \ + $(LIBOBJS) \ + cupsfilter.o \ + cups-deviced.o \ + cups-lpd.o \ + cups-polld.o \ + testdirsvc.o \ + testlpd.o \ + testmime.o \ + testspeed.o \ + testsub.o \ + util.o +CXXOBJS = \ + cups-driverd.o +OBJS = \ + $(COBJS) \ + $(CXXOBJS) +LIBTARGETS = \ + $(LIBCUPSMIME) \ + libcupsmime.a + +UNITTARGETS = \ + testdirsvc \ + testlpd \ + testmime \ + testspeed \ + testsub + +DAEMONS = \ + cupsd \ + cupsfilter \ + cups-deviced \ + cups-driverd \ + cups-lpd \ + cups-polld + +TARGETS = \ + $(LIBTARGETS) \ + $(DAEMONS) + + +# +# Make everything... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: $(LIBTARGETS) + + +# +# Make unit tests... +# + +unittests: $(UNITTARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) + $(RM) $(TARGETS) $(UNITTARGETS) convert + $(RM) libcupsmime.so libcupsmime.sl libcupsmime.dylib + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + makedepend -Y -I.. -fDependencies $(COBJS:.o=.c) \ + $(CXXOBJS:.o=.cxx) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + echo Creating $(SERVERBIN)/driver... + $(INSTALL_DIR) -m 755 $(SERVERBIN)/driver + echo Creating $(SERVERROOT)... + $(INSTALL_DIR) -m 755 -g $(CUPS_GROUP) $(SERVERROOT) + echo Creating $(SERVERROOT)/interfaces... + $(INSTALL_DIR) -m 755 -g $(CUPS_GROUP) $(SERVERROOT)/interfaces + echo Creating $(SERVERROOT)/ppd... + $(INSTALL_DIR) -m 755 -g $(CUPS_GROUP) $(SERVERROOT)/ppd + if test "x`uname`" != xDarwin; then \ + echo Creating $(SERVERROOT)/ssl...; \ + $(INSTALL_DIR) -m 700 -g $(CUPS_GROUP) $(SERVERROOT)/ssl; \ + fi + if test "$(STATEDIR)" != "$(SERVERROOT)"; then \ + echo Creating $(STATEDIR)...; \ + $(INSTALL_DIR) -m 755 $(STATEDIR); \ + fi + echo Creating $(STATEDIR)/certs... + $(INSTALL_DIR) -m 511 -o $(CUPS_USER) -g $(CUPS_PRIMARY_SYSTEM_GROUP) \ + $(STATEDIR)/certs + echo Creating $(LOGDIR)... + $(INSTALL_DIR) -m 755 $(LOGDIR) + echo Creating $(REQUESTS)... + $(INSTALL_DIR) -m 710 -g $(CUPS_GROUP) $(REQUESTS) + echo Creating $(REQUESTS)/tmp... + $(INSTALL_DIR) -m 1770 -g $(CUPS_GROUP) $(REQUESTS)/tmp + echo Creating $(CACHEDIR)... + $(INSTALL_DIR) -m 775 -g $(CUPS_GROUP) $(CACHEDIR) + + +# +# Install programs... +# + +install-exec: + echo Installing programs in $(SBINDIR)... + $(INSTALL_DIR) -m 755 $(SBINDIR) + $(INSTALL_BIN) -m 500 cupsd $(SBINDIR) + $(INSTALL_BIN) cupsfilter $(SBINDIR) + -if test "x`uname`" = xDarwin; then \ + $(INSTALL_DIR) $(BUILDROOT)/System/Library/Printers/Libraries; \ + $(LN) $(sbindir)/cupsfilter $(BUILDROOT)/System/Library/Printers/Libraries/convert; \ + fi + echo Installing programs in $(SERVERBIN)/daemon... + $(INSTALL_DIR) -m 755 $(SERVERBIN) + $(INSTALL_DIR) -m 755 $(SERVERBIN)/daemon + $(INSTALL_BIN) cups-deviced $(SERVERBIN)/daemon + $(INSTALL_BIN) cups-driverd $(SERVERBIN)/daemon + $(INSTALL_BIN) cups-lpd $(SERVERBIN)/daemon + $(INSTALL_BIN) cups-polld $(SERVERBIN)/daemon + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(DAEMONS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + echo Installing header files in $(INCLUDEDIR)/cups... + $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups + $(INSTALL_DATA) mime.h $(INCLUDEDIR)/cups + + +# +# Install libraries... +# + +install-libs: $(INSTALLSTATIC) + echo Installing libraries in $(LIBDIR)... + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) $(LIBCUPSMIME) $(LIBDIR) + if test $(LIBCUPSMIME) = "libcupsmime.so.1" -o $(LIBCUPSMIME) = "libcupsmime.sl.1"; then \ + $(RM) $(LIBDIR)/`basename $(LIBCUPSMIME) .1`; \ + $(LN) $(LIBCUPSMIME) $(LIBDIR)/`basename $(LIBCUPSMIME) .1`; \ + fi + if test $(LIBCUPSMIME) = "libcupsmime.1.dylib"; then \ + $(RM) $(LIBDIR)/libcupsmime.dylib; \ + $(LN) $(LIBCUPSMIME) $(LIBDIR)/libcupsmime.dylib; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(LIBCUPSMIME) $(SYMROOT); \ + fi + +installstatic: + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) -m 755 libcupsmime.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcupsmime.a + $(CHMOD) 555 $(LIBDIR)/libcupsmime.a + + +# +# Uninstall the scheduler... +# + +uninstall: + $(RM) $(SBINDIR)/cupsd + $(RM) $(SBINDIR)/cupsfilter + $(RM) $(SERVERBIN)/daemon/cups-deviced + $(RM) $(SERVERBIN)/daemon/cups-driverd + $(RM) $(SERVERBIN)/daemon/cups-lpd + $(RM) $(SERVERBIN)/daemon/cups-polld + $(RM) $(BUILDROOT)/System/Library/Printers/Libraries/convert + -$(RMDIR) $(STATEDIR)/certs + -$(RMDIR) $(STATEDIR) + -$(RMDIR) $(SERVERROOT)/ppd + -$(RMDIR) $(SERVERROOT)/interfaces + -$(RMDIR) $(SERVERROOT) + -$(RMDIR) $(SERVERBIN)/driver + -$(RMDIR) $(SERVERBIN)/daemon + -$(RMDIR) $(SERVERBIN) + -$(RMDIR) $(SBINDIR) + -$(RMDIR) $(REQUESTS)/tmp + -$(RMDIR) $(REQUESTS) + -$(RMDIR) $(LOGDIR) + -$(RMDIR) $(CACHEDIR) + $(RM) $(LIBDIR)/libcupsmime.1.dylib + $(RM) $(LIBDIR)/libcupsmime.a + $(RM) $(LIBDIR)/libcupsmime.dylib + $(RM) $(LIBDIR)/libcupsmime_s.a + $(RM) $(LIBDIR)/libcupsmime.sl + $(RM) $(LIBDIR)/libcupsmime.sl.1 + $(RM) $(LIBDIR)/libcupsmime.so + $(RM) $(LIBDIR)/libcupsmime.so.1 + -$(RMDIR) $(LIBDIR) + $(RM) $(INCLUDEDIR)/cups/mime.h + -$(RMDIR) $(INCLUDEDIR)/cups + + +# +# Automatic API help files... +# + +apihelp: + mxmldoc --section "Programming" \ + --title "MIME API" \ + --css ../doc/cups-printable.css \ + --header api-mime.header --intro api-mime.shtml \ + mime.h $(LIBOBJS:.o=.c) >../doc/help/api-mime.html + mxmldoc --tokens help/api-mime.html api-mime.xml >../doc/help/api-mime.tokens + $(RM) api-mime.xml + +framedhelp: + mxmldoc --framed api-mime \ + --section "Programming" \ + --title "MIME API" \ + --css ../doc/cups-printable.css \ + --header api-mime.header --intro api-mime.shtml \ + mime.h $(LIBOBJS:.o=.c) + + +# +# Make the scheduler executable, "cupsd". +# + +cupsd: $(CUPSDOBJS) $(LIBCUPSMIME) ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime \ + $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \ + $(LIBPAPER) $(LIBMALLOC) $(CUPSDLIBS) $(DNSSDLIBS) $(LIBS) \ + $(LIBGSSAPI) $(LIBWRAP) + +cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsd-static $(CUPSDOBJS) libcupsmime.a \ + $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS) \ + ../cups/libcups.a $(COMMONLIBS) $(LIBZ) $(LIBPAPER) \ + $(LIBMALLOC) $(CUPSDLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \ + $(LIBWRAP) + + +# +# Make the cupsfilter utility. +# + +cupsfilter: cupsfilter.o $(LIBCUPSMIME) ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsfilter cupsfilter.o -L. -lcupsmime $(LIBS) + $(RM) convert + $(LN) cupsfilter convert + + +# +# Make the device daemon, "cups-deviced". +# + +cups-deviced: cups-deviced.o util.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cups-deviced cups-deviced.o util.o $(LIBS) + + +# +# Make the driver daemon, "cups-driverd". +# + +cups-driverd: cups-driverd.o util.o ../cups/$(LIBCUPS) ../ppdc/$(LIBCUPSPPDC) + echo Linking $@... + $(CXX) $(LDFLAGS) -o cups-driverd cups-driverd.o util.o \ + -L../ppdc -lcupsppdc $(LIBS) + + +# +# 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) + + +# +# libcupsmime.so.1, libcupsmime.sl.1 +# + +libcupsmime.so.1 libcupsmime.sl.1: $(LIBOBJS) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS) $(LIBS) + $(RM) `basename $@ .1` + $(LN) $@ `basename $@ .1` + + +# +# libcupsmime.1.dylib +# + +libcupsmime.1.dylib: $(LIBOBJS) libcupsmime.exp + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 1.0.0 \ + -compatibility_version 1.0.0 \ + -exported_symbols_list libcupsmime.exp \ + $(LIBOBJS) $(LIBS) + $(RM) libcupsmime.dylib + $(LN) $@ libcupsmime.dylib + + +# +# libcupsmime_s.a +# + +libcupsmime_s.a: $(LIBOBJS) + echo Creating $@... + $(DSO) $(DSOFLAGS) -o libcupsmime_s.o $(LIBOBJS) $(LIBS) + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcupsmime_s.o + + +# +# libcupsmime.la +# + +libcupsmime.la: $(LIBOBJS) + echo Linking $@... + $(CC) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) \ + -version-info 1:0 $(LIBS) + + +# +# libcupsmime.a +# + +libcupsmime.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# Make the test program, "testdirsvc". +# + +testdirsvc: testdirsvc.o + echo Linking $@... + $(CC) $(LDFLAGS) -o testdirsvc testdirsvc.o $(COMMONLIBS) $(NETLIBS) + + +# +# Make the test program, "testlpd". +# + +testlpd: testlpd.o ../cups/libcups.a cups-lpd + echo Linking $@... + $(CC) $(LDFLAGS) -o testlpd testlpd.o ../cups/libcups.a \ + $(COMMONLIBS) $(LIBZ) $(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI) + + +# +# testmime +# + +testmime: testmime.o libcupsmime.a ../cups/libcups.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testmime.o libcupsmime.a \ + ../cups/libcups.a $(COMMONLIBS) $(LIBZ) $(SSLLIBS) \ + $(DNSSDLIBS) $(LIBGSSAPI) + echo Running MIME tests... + ./testmime + + +# +# Make the test program, "testspeed". +# + +testspeed: testspeed.o ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o testspeed testspeed.o ../cups/libcups.a \ + $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) $(LIBGSSAPI) + + +# +# Make the test program, "testsub". +# + +testsub: testsub.o ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o testsub testsub.o ../cups/libcups.a \ + $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) $(LIBGSSAPI) + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/scheduler/api-mime.header b/scheduler/api-mime.header new file mode 100644 index 0000000000..8d5db2ad6f --- /dev/null +++ b/scheduler/api-mime.header @@ -0,0 +1,34 @@ + + +

MIME API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/mime.h
Library-lcupsmime
See AlsoProgramming: Introduction to CUPS Programming
diff --git a/scheduler/api-mime.shtml b/scheduler/api-mime.shtml new file mode 100644 index 0000000000..7d3125fadf --- /dev/null +++ b/scheduler/api-mime.shtml @@ -0,0 +1,17 @@ + + +

Overview

+ +

The MIME API provides file typing and conversion services for CUPS.

diff --git a/scheduler/auth.c b/scheduler/auth.c new file mode 100644 index 0000000000..d516787587 --- /dev/null +++ b/scheduler/auth.c @@ -0,0 +1,2861 @@ +/* + * "$Id$" + * + * Authorization routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddLocation() - Add a location for authorization. + * cupsdAddName() - Add a name to a location... + * cupsdAllowHost() - Add a host name that is allowed to access the + * location. + * cupsdAllowIP() - Add an IP address or network that is allowed to + * access the location. + * cupsdAuthorize() - Validate any authorization credentials. + * cupsdCheckAccess() - Check whether the given address is allowed to + * access a location. + * cupsdCheckAuth() - Check authorization masks. + * cupsdCheckGroup() - Check for a user's group membership. + * cupsdCopyKrb5Creds() - Get a copy of the Kerberos credentials. + * cupsdCopyLocation() - Make a copy of a location... + * cupsdDeleteAllLocations() - Free all memory used for location + * authorization. + * cupsdDeleteLocation() - Free all memory used by a location. + * cupsdDenyHost() - Add a host name that is not allowed to access + * the location. + * cupsdDenyIP() - Add an IP address or network that is not + * allowed to access the location. + * cupsdFindBest() - Find the location entry that best matches the + * resource. + * cupsdFindLocation() - Find the named location. + * cupsdIsAuthorized() - 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. + * check_authref() - Check if an authorization services reference + * has the supplied right. + * compare_locations() - Compare two locations. + * cups_crypt() - Encrypt the password using the DES or MD5 + * algorithms, as needed. + * get_md5_password() - Get an MD5 password. + * pam_func() - PAM conversation function. + * to64() - Base64-encode an integer value... + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include +#ifdef HAVE_SHADOW_H +# include +#endif /* HAVE_SHADOW_H */ +#ifdef HAVE_CRYPT_H +# include +#endif /* HAVE_CRYPT_H */ +#if HAVE_LIBPAM +# ifdef HAVE_PAM_PAM_APPL_H +# include +# else +# include +# endif /* HAVE_PAM_PAM_APPL_H */ +#endif /* HAVE_LIBPAM */ +#ifdef HAVE_USERSEC_H +# include +#endif /* HAVE_USERSEC_H */ +#ifdef HAVE_MEMBERSHIP_H +# include +#endif /* HAVE_MEMBERSHIP_H */ +#ifdef HAVE_AUTHORIZATION_H +# include +# ifdef HAVE_SECBASEPRIV_H +# include +# else +extern const char *cssmErrorString(int error); +# endif /* HAVE_SECBASEPRIV_H */ +#endif /* HAVE_AUTHORIZATION_H */ +#ifdef HAVE_SYS_PARAM_H +# include +#endif /* HAVE_SYS_PARAM_H */ +#ifdef HAVE_SYS_UCRED_H +# include +typedef struct xucred cupsd_ucred_t; +# define CUPSD_UCRED_UID(c) (c).cr_uid +#else +typedef struct ucred cupsd_ucred_t; +# define CUPSD_UCRED_UID(c) (c).uid +#endif /* HAVE_SYS_UCRED_H */ +#ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID +/* Not in public headers... */ +extern void krb5_ipc_client_set_target_uid(uid_t); +extern void krb5_ipc_client_clear_target(void); +#endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */ + + +/* + * Local functions... + */ + +static cupsd_authmask_t *add_allow(cupsd_location_t *loc); +static cupsd_authmask_t *add_deny(cupsd_location_t *loc); +#ifdef HAVE_AUTHORIZATION_H +static int check_authref(cupsd_client_t *con, const char *right); +#endif /* HAVE_AUTHORIZATION_H */ +static int compare_locations(cupsd_location_t *a, + cupsd_location_t *b); +#if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H) +static char *cups_crypt(const char *pw, const char *salt); +#endif /* !HAVE_LIBPAM && !HAVE_USERSEC_H */ +static char *get_md5_password(const char *username, + const char *group, char passwd[33]); +#if HAVE_LIBPAM +static int pam_func(int, const struct pam_message **, + struct pam_response **, void *); +#elif !defined(HAVE_USERSEC_H) +static void to64(char *s, unsigned long v, int n); +#endif /* HAVE_LIBPAM */ + + +/* + * Local structures... + */ + +#if HAVE_LIBPAM +typedef struct cupsd_authdata_s /**** Authentication data ****/ +{ + char username[33], /* Username string */ + password[33]; /* Password string */ +} cupsd_authdata_t; +#endif /* HAVE_LIBPAM */ + + +/* + * Local globals... + */ + +#if defined(__hpux) && HAVE_LIBPAM +static cupsd_authdata_t *auth_data; /* Current client being authenticated */ +#endif /* __hpux && HAVE_LIBPAM */ + + +/* + * 'cupsdAddLocation()' - Add a location for authorization. + */ + +cupsd_location_t * /* O - Pointer to new location record */ +cupsdAddLocation(const char *location) /* I - Location path */ +{ + cupsd_location_t *temp; /* New location */ + + + /* + * Make sure the locations array is created... + */ + + if (!Locations) + Locations = cupsArrayNew((cups_array_func_t)compare_locations, NULL); + + if (!Locations) + return (NULL); + + /* + * Try to allocate memory for the new location. + */ + + if ((temp = calloc(1, sizeof(cupsd_location_t))) == NULL) + return (NULL); + + /* + * Initialize the record and copy the name over... + */ + + if ((temp->location = strdup(location)) == NULL) + { + free(temp); + return (NULL); + } + + temp->length = strlen(temp->location); + + cupsArrayAdd(Locations, temp); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddLocation: added location \'%s\'", + location); + + /* + * Return the new record... + */ + + return (temp); +} + + +/* + * 'cupsdAddName()' - Add a name to a location... + */ + +void +cupsdAddName(cupsd_location_t *loc, /* I - Location to add to */ + char *name) /* I - Name to add */ +{ + char **temp; /* Pointer to names array */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddName(loc=%p, name=\"%s\")", + loc, name); + + if (loc->num_names == 0) + temp = malloc(sizeof(char *)); + else + temp = realloc(loc->names, (loc->num_names + 1) * sizeof(char *)); + + if (temp == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to add name to location %s: %s", + loc->location ? loc->location : "nil", strerror(errno)); + return; + } + + loc->names = temp; + + if ((temp[loc->num_names] = strdup(name)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to duplicate name for location %s: %s", + loc->location ? loc->location : "nil", strerror(errno)); + return; + } + + loc->num_names ++; +} + + +/* + * 'cupsdAllowHost()' - Add a host name that is allowed to access the location. + */ + +void +cupsdAllowHost(cupsd_location_t *loc, /* I - Location to add to */ + char *name) /* I - Name of host or domain to add */ +{ + cupsd_authmask_t *temp; /* New host/domain mask */ + char ifname[32], /* Interface name */ + *ifptr; /* Pointer to end of name */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAllowHost(loc=%p(%s), name=\"%s\")", + loc, loc->location ? loc->location : "nil", name); + + if ((temp = add_allow(loc)) == NULL) + return; + + if (!strcasecmp(name, "@LOCAL")) + { + /* + * Allow *interface*... + */ + + temp->type = CUPSD_AUTH_INTERFACE; + temp->mask.name.name = strdup("*"); + temp->mask.name.length = 1; + } + else if (!strncasecmp(name, "@IF(", 4)) + { + /* + * Allow *interface*... + */ + + strlcpy(ifname, name + 4, sizeof(ifname)); + + ifptr = ifname + strlen(ifname); + + if (ifptr[-1] == ')') + { + ifptr --; + *ifptr = '\0'; + } + + temp->type = CUPSD_AUTH_INTERFACE; + temp->mask.name.name = strdup(ifname); + temp->mask.name.length = ifptr - ifname; + } + else + { + /* + * Allow name... + */ + + temp->type = CUPSD_AUTH_NAME; + temp->mask.name.name = strdup(name); + temp->mask.name.length = strlen(name); + } +} + + +/* + * 'cupsdAllowIP()' - Add an IP address or network that is allowed to access + * the location. + */ + +void +cupsdAllowIP( + cupsd_location_t *loc, /* I - Location to add to */ + const unsigned address[4], /* I - IP address to add */ + const unsigned netmask[4]) /* I - Netmask of address */ +{ + cupsd_authmask_t *temp; /* New host/domain mask */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAllowIP(loc=%p(%s), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)", + loc, loc->location ? loc->location : "nil", + address[0], address[1], address[2], address[3], + netmask[0], netmask[1], netmask[2], netmask[3]); + + if ((temp = add_allow(loc)) == NULL) + return; + + temp->type = CUPSD_AUTH_IP; + memcpy(temp->mask.ip.address, address, sizeof(temp->mask.ip.address)); + memcpy(temp->mask.ip.netmask, netmask, sizeof(temp->mask.ip.netmask)); +} + + +/* + * 'cupsdAuthorize()' - Validate any authorization credentials. + */ + +void +cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ +{ + int type; /* Authentication type */ + const char *authorization; /* Pointer into Authorization string */ + char *ptr, /* Pointer into string */ + username[256], /* Username string */ + password[33]; /* Password string */ + cupsd_cert_t *localuser; /* Certificate username */ + char nonce[HTTP_MAX_VALUE], /* Nonce value from client */ + md5[33], /* MD5 password */ + basicmd5[33]; /* MD5 of Basic password */ + static const char * const states[] = /* HTTP client states... */ + { + "WAITING", + "OPTIONS", + "GET", + "GET", + "HEAD", + "POST", + "POST", + "POST", + "PUT", + "PUT", + "DELETE", + "TRACE", + "CLOSE", + "STATUS" + }; + + + /* + * Locate the best matching location so we know what kind of + * authentication to expect... + */ + + con->best = cupsdFindBest(con->uri, con->http.state); + con->type = CUPSD_AUTH_NONE; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAuthorize: con->uri=\"%s\", con->best=%p(%s)", + con->uri, con->best, con->best ? con->best->location : ""); + + if (con->best && con->best->type != CUPSD_AUTH_NONE) + { + if (con->best->type == CUPSD_AUTH_DEFAULT) + type = DefaultAuthType; + else + type = con->best->type; + } + else + type = DefaultAuthType; + + /* + * Decode the Authorization string... + */ + + authorization = httpGetField(&con->http, HTTP_FIELD_AUTHORIZATION); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAuthorize: Authorization=\"%s\"", + authorization); + + username[0] = '\0'; + password[0] = '\0'; + +#ifdef HAVE_AUTHORIZATION_H + if (con->authref) + { + AuthorizationFree(con->authref, kAuthorizationFlagDefaults); + con->authref = NULL; + } +#endif /* HAVE_AUTHORIZATION_H */ + + if (!*authorization) + { + /* + * No authorization data provided, return early... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: No authentication data provided."); + return; + } +#ifdef HAVE_AUTHORIZATION_H + else if (!strncmp(authorization, "AuthRef", 6) && + !strcasecmp(con->http.hostname, "localhost")) + { + OSStatus status; /* Status */ + int authlen; /* Auth string length */ + AuthorizationItemSet *authinfo; /* Authorization item set */ + + /* + * Get the Authorization Services data... + */ + + authorization += 7; + while (isspace(*authorization & 255)) + authorization ++; + + authlen = sizeof(nonce); + httpDecode64_2(nonce, &authlen, authorization); + + if (authlen != kAuthorizationExternalFormLength) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "External Authorization reference size is incorrect!"); + return; + } + + if ((status = AuthorizationCreateFromExternalForm( + (AuthorizationExternalForm *)nonce, &con->authref)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "AuthorizationCreateFromExternalForm returned %d (%s)", + (int)status, cssmErrorString(status)); + return; + } + + strlcpy(username, "_AUTHREF_", sizeof(username)); + + if (!AuthorizationCopyInfo(con->authref, kAuthorizationEnvironmentUsername, + &authinfo)) + { + if (authinfo->count == 1 && authinfo->items[0].value && + authinfo->items[0].valueLength >= 2) + strlcpy(username, authinfo->items[0].value, sizeof(username)); + + AuthorizationFreeItemSet(authinfo); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as \"%s\" using AuthRef", + username); + con->type = CUPSD_AUTH_BASIC; + } +#endif /* HAVE_AUTHORIZATION_H */ +#if defined(SO_PEERCRED) && defined(AF_LOCAL) + else if (!strncmp(authorization, "PeerCred ", 9) && + con->http.hostaddr->addr.sa_family == AF_LOCAL) + { + /* + * Use peer credentials from domain socket connection... + */ + + struct passwd *pwd; /* Password entry for this user */ + cupsd_ucred_t peercred; /* Peer credentials */ + socklen_t peersize; /* Size of peer credentials */ + + + if ((pwd = getpwnam(authorization + 9)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "User \"%s\" does not exist!", + authorization + 9); + return; + } + + peersize = sizeof(peercred); + +# ifdef __APPLE__ + if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize)) +# else + if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize)) +# endif /* __APPLE__ */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", + strerror(errno)); + return; + } + + if (pwd->pw_uid != CUPSD_UCRED_UID(peercred)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Invalid peer credentials for \"%s\" - got %d, " + "expected %d!", authorization + 9, + CUPSD_UCRED_UID(peercred), pwd->pw_uid); +# ifdef HAVE_SYS_UCRED_H + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_version=%d", + peercred.cr_version); + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_uid=%d", + peercred.cr_uid); + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_ngroups=%d", + peercred.cr_ngroups); + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAuthorize: cr_groups[0]=%d", + peercred.cr_groups[0]); +# endif /* HAVE_SYS_UCRED_H */ + return; + } + + strlcpy(username, authorization + 9, sizeof(username)); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using PeerCred", + username); + + con->type = CUPSD_AUTH_BASIC; + } +#endif /* SO_PEERCRED && AF_LOCAL */ + else if (!strncmp(authorization, "Local", 5) && + !strcasecmp(con->http.hostname, "localhost")) + { + /* + * Get Local certificate authentication data... + */ + + authorization += 5; + while (isspace(*authorization & 255)) + authorization ++; + + if ((localuser = cupsdFindCert(authorization)) != NULL) + { + strlcpy(username, localuser->username, sizeof(username)); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using Local", + username); + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Local authentication certificate not " + "found!"); + return; + } + +#ifdef HAVE_GSSAPI + if (localuser->ccache) + con->type = CUPSD_AUTH_NEGOTIATE; + else +#endif /* HAVE_GSSAPI */ + con->type = CUPSD_AUTH_BASIC; + } + else if (!strncmp(authorization, "Basic", 5)) + { + /* + * Get the Basic authentication data... + */ + + int userlen; /* Username:password length */ + + + authorization += 5; + while (isspace(*authorization & 255)) + authorization ++; + + userlen = sizeof(username); + httpDecode64_2(username, &userlen, authorization); + + /* + * Pull the username and password out... + */ + + if ((ptr = strchr(username, ':')) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Missing Basic password!"); + return; + } + + *ptr++ = '\0'; + + if (!username[0]) + { + /* + * Username must not be empty... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Empty Basic username!"); + return; + } + + if (!*ptr) + { + /* + * Password must not be empty... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Empty Basic password!"); + return; + } + + strlcpy(password, ptr, sizeof(password)); + + /* + * Validate the username and password... + */ + + switch (type) + { + default : + case CUPSD_AUTH_BASIC : + { +#if HAVE_LIBPAM + /* + * Only use PAM to do authentication. This supports MD5 + * passwords, among other things... + */ + + pam_handle_t *pamh; /* PAM authentication handle */ + int pamerr; /* PAM error code */ + struct pam_conv pamdata;/* PAM conversation data */ + cupsd_authdata_t data; /* Authentication data */ + + + strlcpy(data.username, username, sizeof(data.username)); + strlcpy(data.password, password, sizeof(data.password)); + +# if defined(__sun) || defined(__hpux) + pamdata.conv = (int (*)(int, struct pam_message **, + struct pam_response **, + void *))pam_func; +# else + pamdata.conv = pam_func; +# endif /* __sun || __hpux */ + pamdata.appdata_ptr = &data; + +# ifdef __hpux + /* + * Workaround for HP-UX bug in pam_unix; see pam_func() below for + * more info... + */ + + auth_data = &data; +# endif /* __hpux */ + + pamerr = pam_start("cups", username, &pamdata, &pamh); + if (pamerr != PAM_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: pam_start() returned %d (%s)!", + pamerr, pam_strerror(pamh, pamerr)); + return; + } + +# ifdef HAVE_PAM_SET_ITEM +# ifdef PAM_RHOST + pamerr = pam_set_item(pamh, PAM_RHOST, con->http.hostname); + if (pamerr != PAM_SUCCESS) + cupsdLogMessage(CUPSD_LOG_WARN, + "cupsdAuthorize: pam_set_item(PAM_RHOST) " + "returned %d (%s)!", pamerr, + pam_strerror(pamh, pamerr)); +# endif /* PAM_RHOST */ + +# ifdef PAM_TTY + pamerr = pam_set_item(pamh, PAM_TTY, "cups"); + if (pamerr != PAM_SUCCESS) + cupsdLogMessage(CUPSD_LOG_WARN, + "cupsdAuthorize: pam_set_item(PAM_TTY) " + "returned %d (%s)!", pamerr, + pam_strerror(pamh, pamerr)); +# endif /* PAM_TTY */ +# endif /* HAVE_PAM_SET_ITEM */ + + pamerr = pam_authenticate(pamh, PAM_SILENT); + if (pamerr != PAM_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: pam_authenticate() returned %d " + "(%s)!", + pamerr, pam_strerror(pamh, pamerr)); + pam_end(pamh, 0); + return; + } + +# ifdef HAVE_PAM_SETCRED + pamerr = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT); + if (pamerr != PAM_SUCCESS) + cupsdLogMessage(CUPSD_LOG_WARN, + "cupsdAuthorize: pam_setcred() " + "returned %d (%s)!", pamerr, + pam_strerror(pamh, pamerr)); +# endif /* HAVE_PAM_SETCRED */ + + pamerr = pam_acct_mgmt(pamh, PAM_SILENT); + if (pamerr != PAM_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: pam_acct_mgmt() returned %d " + "(%s)!", + pamerr, pam_strerror(pamh, pamerr)); + pam_end(pamh, 0); + return; + } + + pam_end(pamh, PAM_SUCCESS); + +#elif defined(HAVE_USERSEC_H) + /* + * Use AIX authentication interface... + */ + + char *authmsg; /* Authentication message */ + int reenter; /* ??? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: AIX authenticate of username " + "\"%s\"", username); + + reenter = 1; + if (authenticate(username, password, &reenter, &authmsg) != 0) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Unable to authenticate username " + "\"%s\": %s", + username, strerror(errno)); + return; + } + +#else + /* + * Use normal UNIX password file-based authentication... + */ + + char *pass; /* Encrypted password */ + struct passwd *pw; /* User password data */ +# ifdef HAVE_SHADOW_H + struct spwd *spw; /* Shadow password data */ +# endif /* HAVE_SHADOW_H */ + + + pw = getpwnam(username); /* Get the current password */ + endpwent(); /* Close the password file */ + + if (!pw) + { + /* + * No such user... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Unknown username \"%s\"!", + username); + return; + } + +# ifdef HAVE_SHADOW_H + spw = getspnam(username); + endspent(); + + if (!spw && !strcmp(pw->pw_passwd, "x")) + { + /* + * Don't allow blank passwords! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Username \"%s\" has no shadow " + "password!", username); + return; + } + + if (spw && !spw->sp_pwdp[0] && !pw->pw_passwd[0]) +# else + if (!pw->pw_passwd[0]) +# endif /* HAVE_SHADOW_H */ + { + /* + * Don't allow blank passwords! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Username \"%s\" has no password!", + username); + return; + } + + /* + * OK, the password isn't blank, so compare with what came from the + * client... + */ + + pass = cups_crypt(password, pw->pw_passwd); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAuthorize: pw_passwd=\"%s\", crypt=\"%s\"", + pw->pw_passwd, pass); + + if (!pass || strcmp(pw->pw_passwd, pass)) + { +# ifdef HAVE_SHADOW_H + if (spw) + { + pass = cups_crypt(password, spw->sp_pwdp); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAuthorize: sp_pwdp=\"%s\", crypt=\"%s\"", + spw->sp_pwdp, pass); + + if (pass == NULL || strcmp(spw->sp_pwdp, pass)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Authentication failed for " + "user \"%s\"!", + username); + return; + } + } + else +# endif /* HAVE_SHADOW_H */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Authentication failed for " + "user \"%s\"!", + username); + return; + } + } +#endif /* HAVE_LIBPAM */ + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using Basic", + username); + break; + + case CUPSD_AUTH_BASICDIGEST : + /* + * Do Basic authentication with the Digest password file... + */ + + if (!get_md5_password(username, NULL, md5)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Unknown MD5 username \"%s\"!", + username); + return; + } + + httpMD5(username, "CUPS", password, basicmd5); + + if (strcmp(md5, basicmd5)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Authentication failed for \"%s\"!", + username); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using BasicDigest", + username); + break; + } + + con->type = type; + } + else if (!strncmp(authorization, "Digest", 6)) + { + /* + * Get the username, password, and nonce from the Digest attributes... + */ + + if (!httpGetSubField2(&(con->http), HTTP_FIELD_AUTHORIZATION, "username", + username, sizeof(username)) || !username[0]) + { + /* + * Username must not be empty... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Empty or missing Digest username!"); + return; + } + + if (!httpGetSubField2(&(con->http), HTTP_FIELD_AUTHORIZATION, "response", + password, sizeof(password)) || !password[0]) + { + /* + * Password must not be empty... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Empty or missing Digest password!"); + return; + } + + if (!httpGetSubField(&(con->http), HTTP_FIELD_AUTHORIZATION, "nonce", + nonce)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: No nonce value for Digest " + "authentication!"); + return; + } + + if (strcmp(con->http.hostname, nonce)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Bad nonce value, expected \"%s\", " + "got \"%s\"!", con->http.hostname, nonce); + return; + } + + /* + * Validate the username and password... + */ + + if (!get_md5_password(username, NULL, md5)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Unknown MD5 username \"%s\"!", + username); + return; + } + + httpMD5Final(nonce, states[con->http.state], con->uri, md5); + + if (strcmp(md5, password)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdAuthorize: Authentication failed for \"%s\"!", + username); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using Digest", + username); + + con->type = CUPSD_AUTH_DIGEST; + } +#ifdef HAVE_GSSAPI + else if (!strncmp(authorization, "Negotiate", 9)) + { + int len; /* Length of authorization string */ + gss_ctx_id_t context; /* Authorization context */ + OM_uint32 major_status, /* Major status code */ + minor_status; /* Minor status code */ + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER, + /* Input token from string */ + output_token = GSS_C_EMPTY_BUFFER; + /* Output token for username */ + gss_name_t client_name; /* Client name */ + + +# ifdef __APPLE__ + /* + * If the weak-linked GSSAPI/Kerberos library is not present, don't try + * to use it... + */ + + if (gss_init_sec_context == NULL) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "GSSAPI/Kerberos authentication failed because the " + "Kerberos framework is not present."); + return; + } +# endif /* __APPLE__ */ + + con->gss_output_token.length = 0; + + /* + * Find the start of the Kerberos input token... + */ + + authorization += 9; + while (isspace(*authorization & 255)) + authorization ++; + + if (!*authorization) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAuthorize: No authentication data specified."); + return; + } + + /* + * Decode the authorization string to get the input token... + */ + + len = strlen(authorization); + input_token.value = malloc(len); + input_token.value = httpDecode64_2(input_token.value, &len, + authorization); + input_token.length = len; + + /* + * Accept the input token to get the authorization info... + */ + + context = GSS_C_NO_CONTEXT; + client_name = GSS_C_NO_NAME; + major_status = gss_accept_sec_context(&minor_status, + &context, + GSS_C_NO_CREDENTIAL, + &input_token, + GSS_C_NO_CHANNEL_BINDINGS, + &client_name, + NULL, + &con->gss_output_token, + &con->gss_flags, + NULL, + &con->gss_creds); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, + "cupsdAuthorize: Error accepting GSSAPI security " + "context"); + + if (context != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + return; + } + + con->have_gss = 1; + + /* + * Get the username associated with the client's credentials... + */ + + if (!con->gss_creds) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: No delegated credentials!"); + + if (major_status == GSS_S_CONTINUE_NEEDED) + cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, + "cupsdAuthorize: Credentials not complete"); + else if (major_status == GSS_S_COMPLETE) + { + major_status = gss_display_name(&minor_status, client_name, + &output_token, NULL); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_DEBUG, major_status, minor_status, + "cupsdAuthorize: Error getting username"); + gss_release_cred(&minor_status, &con->gss_creds); + gss_release_name(&minor_status, &client_name); + gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + return; + } + + strlcpy(username, output_token.value, sizeof(username)); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAuthorize: Authorized as %s using Negotiate", + username); + + gss_release_name(&minor_status, &client_name); + gss_release_buffer(&minor_status, &output_token); + + con->type = CUPSD_AUTH_NEGOTIATE; + } + else + gss_release_cred(&minor_status, &con->gss_creds); + + gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + } +#endif /* HAVE_GSSAPI */ + else + { + char scheme[256]; /* Auth scheme... */ + + + if (sscanf(authorization, "%255s", scheme) != 1) + strcpy(scheme, "UNKNOWN"); + + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad authentication data \"%s ...\"", + scheme); + return; + } + + /* + * If we get here, then we were able to validate the username and + * password - copy the validated username and password to the client + * data and return... + */ + + strlcpy(con->username, username, sizeof(con->username)); + strlcpy(con->password, password, sizeof(con->password)); +} + + +/* + * 'cupsdCheckAccess()' - Check whether the given address is allowed to + * access a location. + */ + +int /* O - 1 if allowed, 0 otherwise */ +cupsdCheckAccess( + unsigned ip[4], /* I - Client address */ + char *name, /* I - Client hostname */ + int namelen, /* I - Length of hostname */ + cupsd_location_t *loc) /* I - Location to check */ +{ + int allow; /* 1 if allowed, 0 otherwise */ + + + if (!strcasecmp(name, "localhost")) + { + /* + * Access from localhost (127.0.0.1 or ::1) is always allowed... + */ + + return (1); + } + else + { + /* + * Do authorization checks on the domain/address... + */ + + switch (loc->order_type) + { + default : + allow = 0; /* anti-compiler-warning-code */ + break; + + case CUPSD_AUTH_ALLOW : /* Order Deny,Allow */ + allow = 1; + + if (cupsdCheckAuth(ip, name, namelen, loc->num_deny, loc->deny)) + allow = 0; + + if (cupsdCheckAuth(ip, name, namelen, loc->num_allow, loc->allow)) + allow = 1; + break; + + case CUPSD_AUTH_DENY : /* Order Allow,Deny */ + allow = 0; + + if (cupsdCheckAuth(ip, name, namelen, loc->num_allow, loc->allow)) + allow = 1; + + if (cupsdCheckAuth(ip, name, namelen, loc->num_deny, loc->deny)) + allow = 0; + break; + } + } + + return (allow); +} + + +/* + * 'cupsdCheckAuth()' - Check authorization masks. + */ + +int /* O - 1 if mask matches, 0 otherwise */ +cupsdCheckAuth( + unsigned ip[4], /* I - Client address */ + char *name, /* I - Client hostname */ + int name_len, /* I - Length of hostname */ + int num_masks, /* I - Number of masks */ + cupsd_authmask_t *masks) /* I - Masks */ +{ + int i; /* Looping var */ + cupsd_netif_t *iface; /* Network interface */ + unsigned netip4; /* IPv4 network address */ +#ifdef AF_INET6 + unsigned netip6[4]; /* IPv6 network address */ +#endif /* AF_INET6 */ + + + while (num_masks > 0) + { + switch (masks->type) + { + case CUPSD_AUTH_INTERFACE : + /* + * Check for a match with a network interface... + */ + + netip4 = htonl(ip[3]); + +#ifdef AF_INET6 + netip6[0] = htonl(ip[0]); + netip6[1] = htonl(ip[1]); + netip6[2] = htonl(ip[2]); + netip6[3] = htonl(ip[3]); +#endif /* AF_INET6 */ + + if (!strcmp(masks->mask.name.name, "*")) + { +#ifdef __APPLE__ + /* + * Allow Back-to-My-Mac addresses... + */ + + if ((ip[0] & 0xff000000) == 0xfd000000) + return (1); +#endif /* __APPLE__ */ + + /* + * Check against all local interfaces... + */ + + cupsdNetIFUpdate(); + + for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + iface; + iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + { + /* + * Only check local interfaces... + */ + + if (!iface->is_local) + continue; + + if (iface->address.addr.sa_family == AF_INET) + { + /* + * Check IPv4 address... + */ + + if ((netip4 & iface->mask.ipv4.sin_addr.s_addr) == + (iface->address.ipv4.sin_addr.s_addr & + iface->mask.ipv4.sin_addr.s_addr)) + return (1); + } +#ifdef AF_INET6 + else + { + /* + * Check IPv6 address... + */ + + for (i = 0; i < 4; i ++) + if ((netip6[i] & iface->mask.ipv6.sin6_addr.s6_addr32[i]) != + (iface->address.ipv6.sin6_addr.s6_addr32[i] & + iface->mask.ipv6.sin6_addr.s6_addr32[i])) + break; + + if (i == 4) + return (1); + } +#endif /* AF_INET6 */ + } + } + else + { + /* + * Check the named interface... + */ + + for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + iface; + iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + { + if (strcmp(masks->mask.name.name, iface->name)) + continue; + + if (iface->address.addr.sa_family == AF_INET) + { + /* + * Check IPv4 address... + */ + + if ((netip4 & iface->mask.ipv4.sin_addr.s_addr) == + (iface->address.ipv4.sin_addr.s_addr & + iface->mask.ipv4.sin_addr.s_addr)) + return (1); + } +#ifdef AF_INET6 + else + { + /* + * Check IPv6 address... + */ + + for (i = 0; i < 4; i ++) + if ((netip6[i] & iface->mask.ipv6.sin6_addr.s6_addr32[i]) != + (iface->address.ipv6.sin6_addr.s6_addr32[i] & + iface->mask.ipv6.sin6_addr.s6_addr32[i])) + break; + + if (i == 4) + return (1); + } +#endif /* AF_INET6 */ + } + } + break; + + case CUPSD_AUTH_NAME : + /* + * Check for exact name match... + */ + + if (!strcasecmp(name, masks->mask.name.name)) + 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)) + return (1); + break; + + case CUPSD_AUTH_IP : + /* + * Check for IP/network address match... + */ + + for (i = 0; i < 4; i ++) + if ((ip[i] & masks->mask.ip.netmask[i]) != + masks->mask.ip.address[i]) + break; + + if (i == 4) + return (1); + break; + } + + masks ++; + num_masks --; + } + + return (0); +} + + +/* + * 'cupsdCheckGroup()' - Check for a user's group membership. + */ + +int /* O - 1 if user is a member, 0 otherwise */ +cupsdCheckGroup( + const char *username, /* I - User name */ + struct passwd *user, /* I - System user info */ + const char *groupname) /* I - Group name */ +{ + int i; /* Looping var */ + struct group *group; /* System group info */ + char junk[33]; /* MD5 password (not used) */ +#ifdef HAVE_MBR_UID_TO_UUID + uuid_t useruuid, /* UUID for username */ + groupuuid; /* UUID for groupname */ + int is_member; /* True if user is a member of group */ +#endif /* HAVE_MBR_UID_TO_UUID */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdCheckGroup(username=\"%s\", user=%p, groupname=\"%s\")", + username, user, groupname); + + /* + * Validate input... + */ + + if (!username || !groupname) + return (0); + + /* + * Check to see if the user is a member of the named group... + */ + + group = getgrnam(groupname); + endgrent(); + + if (group != NULL) + { + /* + * Group exists, check it... + */ + + for (i = 0; group->gr_mem[i]; i ++) + if (!strcasecmp(username, group->gr_mem[i])) + return (1); + } + + /* + * Group doesn't exist or user not in group list, check the group ID + * against the user's group ID... + */ + + if (user && group && group->gr_gid == user->pw_gid) + return (1); + +#ifdef HAVE_MBR_UID_TO_UUID + /* + * Check group membership through MacOS X membership API... + */ + + if (user && !mbr_uid_to_uuid(user->pw_uid, useruuid)) + { + if (group) + { + /* + * Map group name to UUID and check membership... + */ + + if (!mbr_gid_to_uuid(group->gr_gid, groupuuid)) + if (!mbr_check_membership(useruuid, groupuuid, &is_member)) + if (is_member) + return (1); + } + else if (groupname[0] == '#') + { + /* + * Use UUID directly and check for equality (user UUID) and + * membership (group UUID)... + */ + + if (!uuid_parse((char *)groupname + 1, groupuuid)) + { + if (!uuid_compare(useruuid, groupuuid)) + return (1); + else if (!mbr_check_membership(useruuid, groupuuid, &is_member)) + if (is_member) + return (1); + } + + return (0); + } + } + else if (groupname[0] == '#') + return (0); +#endif /* HAVE_MBR_UID_TO_UUID */ + + /* + * 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... + */ + + if (get_md5_password(username, groupname, junk) != NULL) + return (1); + + /* + * If we get this far, then the user isn't part of the named group... + */ + + return (0); +} + + +#ifdef HAVE_GSSAPI +/* + * 'cupsdCopyKrb5Creds()' - Get a copy of the Kerberos credentials. + */ + +krb5_ccache /* O - Credentials or NULL */ +cupsdCopyKrb5Creds(cupsd_client_t *con) /* I - Client connection */ +{ +# if !defined(HAVE_KRB5_CC_NEW_UNIQUE) && !defined(HAVE_HEIMDAL) + cupsdLogMessage(CUPSD_LOG_INFO, + "Sorry, your version of Kerberos does not support delegated " + "credentials!"); + return (NULL); + +# else + krb5_ccache ccache = NULL; /* Credentials */ + krb5_error_code error; /* Kerberos error code */ + OM_uint32 major_status, /* Major status code */ + minor_status; /* Minor status code */ + krb5_principal principal; /* Kerberos principal */ + + +# ifdef __APPLE__ + /* + * If the weak-linked GSSAPI/Kerberos library is not present, don't try + * to use it... + */ + + if (krb5_init_context == NULL) + return (NULL); +# endif /* __APPLE__ */ + + if (!KerberosInitialized) + { + /* + * Setup a Kerberos context for the scheduler to use... + */ + + KerberosInitialized = 1; + + if (krb5_init_context(&KerberosContext)) + { + KerberosContext = NULL; + + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize Kerberos context"); + return (NULL); + } + } + + /* + * We MUST create a file-based cache because memory-based caches are + * only valid for the current process/address space. + * + * Due to various bugs/features in different versions of Kerberos, we + * need either the krb5_cc_new_unique() function or Heimdal's version + * of krb5_cc_gen_new() to create a new FILE: credential cache that + * can be passed to the backend. These functions create a temporary + * file (typically in /tmp) containing the cached credentials, which + * are removed when we have successfully printed a job. + */ + +# ifdef HAVE_KRB5_CC_NEW_UNIQUE + if ((error = krb5_cc_new_unique(KerberosContext, "FILE", NULL, &ccache)) != 0) +# else /* HAVE_HEIMDAL */ + if ((error = krb5_cc_gen_new(KerberosContext, &krb5_fcc_ops, &ccache)) != 0) +# endif /* HAVE_KRB5_CC_NEW_UNIQUE */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create new credentials cache (%d/%s)", + error, strerror(errno)); + return (NULL); + } + + if ((error = krb5_parse_name(KerberosContext, con->username, &principal)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to parse kerberos username (%d/%s)", error, + strerror(errno)); + krb5_cc_destroy(KerberosContext, ccache); + return (NULL); + } + + if ((error = krb5_cc_initialize(KerberosContext, ccache, principal))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to initialize credentials cache (%d/%s)", error, + strerror(errno)); + krb5_cc_destroy(KerberosContext, ccache); + krb5_free_principal(KerberosContext, principal); + return (NULL); + } + + krb5_free_principal(KerberosContext, principal); + + /* + * Copy the user's credentials to the new cache file... + */ + +# ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID + if (con->http.hostaddr->addr.sa_family == AF_LOCAL && + !(con->gss_flags & GSS_C_DELEG_FLAG)) + { + /* + * Pull the credentials directly from the user... + */ + + cupsd_ucred_t peercred; /* Peer credentials */ + socklen_t peersize; /* Size of peer credentials */ + krb5_ccache peerccache; /* Peer Kerberos credentials */ + + peersize = sizeof(peercred); + +# ifdef __APPLE__ + if (getsockopt(con->http.fd, 0, LOCAL_PEERCRED, &peercred, &peersize)) +# else + if (getsockopt(con->http.fd, SOL_SOCKET, SO_PEERCRED, &peercred, &peersize)) +# endif /* __APPLE__ */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get peer credentials - %s", + strerror(errno)); + krb5_cc_destroy(KerberosContext, ccache); + return (NULL); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdCopyKrb5Creds: Copying credentials for UID %d...", + CUPSD_UCRED_UID(peercred)); + + krb5_ipc_client_set_target_uid(CUPSD_UCRED_UID(peercred)); + + if ((error = krb5_cc_default(KerberosContext, &peerccache)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to get credentials cache for UID %d (%d/%s)", + (int)CUPSD_UCRED_UID(peercred), error, strerror(errno)); + krb5_cc_destroy(KerberosContext, ccache); + return (NULL); + } + + error = krb5_cc_copy_creds(KerberosContext, peerccache, ccache); + krb5_cc_close(KerberosContext, peerccache); + krb5_ipc_client_clear_target(); + + if (error) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to copy credentials cache for UID %d (%d/%s)", + (int)CUPSD_UCRED_UID(peercred), error, strerror(errno)); + krb5_cc_destroy(KerberosContext, ccache); + return (NULL); + } + } + else +# endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */ + { + major_status = gss_krb5_copy_ccache(&minor_status, con->gss_creds, ccache); + + if (GSS_ERROR(major_status)) + { + cupsdLogGSSMessage(CUPSD_LOG_ERROR, major_status, minor_status, + "Unable to copy client credentials cache"); + krb5_cc_destroy(KerberosContext, ccache); + return (NULL); + } + } + + return (ccache); +# endif /* !HAVE_KRB5_CC_NEW_UNIQUE && !HAVE_HEIMDAL */ +} +#endif /* HAVE_GSSAPI */ + + +/* + * 'cupsdCopyLocation()' - Make a copy of a location... + */ + +cupsd_location_t * /* O - New location */ +cupsdCopyLocation( + cupsd_location_t **loc) /* IO - Original location */ +{ + int i; /* Looping var */ + cupsd_location_t *temp; /* New location */ + char location[HTTP_MAX_URI]; + /* Location of resource */ + + + /* + * Use a local copy of location because cupsdAddLocation may cause + * this memory to be moved... + */ + + strlcpy(location, (*loc)->location, sizeof(location)); + + if ((temp = cupsdAddLocation(location)) == NULL) + return (NULL); + + /* + * 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) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdCopyLocation: Unable to allocate memory for %d names: %s", + temp->num_names, strerror(errno)); + + cupsdDeleteLocation(temp); + return (NULL); + } + + for (i = 0; i < temp->num_names; i ++) + if ((temp->names[i] = strdup((*loc)->names[i])) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdCopyLocation: Unable to copy name \"%s\": %s", + (*loc)->names[i], strerror(errno)); + + cupsdDeleteLocation(temp); + return (NULL); + } + } + + if ((temp->num_allow = (*loc)->num_allow) > 0) + { + /* + * Copy allow rules... + */ + + if ((temp->allow = calloc(temp->num_allow, sizeof(cupsd_authmask_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdCopyLocation: Unable to allocate memory for %d allow rules: %s", + temp->num_allow, strerror(errno)); + cupsdDeleteLocation(temp); + return (NULL); + } + + for (i = 0; i < temp->num_allow; i ++) + switch (temp->allow[i].type = (*loc)->allow[i].type) + { + case CUPSD_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) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdCopyLocation: Unable to copy allow name \"%s\": %s", + (*loc)->allow[i].mask.name.name, strerror(errno)); + cupsdDeleteLocation(temp); + return (NULL); + } + break; + case CUPSD_AUTH_IP : + memcpy(&(temp->allow[i].mask.ip), &((*loc)->allow[i].mask.ip), + sizeof(cupsd_ipmask_t)); + break; + } + } + + if ((temp->num_deny = (*loc)->num_deny) > 0) + { + /* + * Copy deny rules... + */ + + if ((temp->deny = calloc(temp->num_deny, sizeof(cupsd_authmask_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdCopyLocation: Unable to allocate memory for %d deny rules: %s", + temp->num_deny, strerror(errno)); + cupsdDeleteLocation(temp); + return (NULL); + } + + for (i = 0; i < temp->num_deny; i ++) + switch (temp->deny[i].type = (*loc)->deny[i].type) + { + case CUPSD_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) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdCopyLocation: Unable to copy deny name \"%s\": %s", + (*loc)->deny[i].mask.name.name, strerror(errno)); + cupsdDeleteLocation(temp); + return (NULL); + } + break; + case CUPSD_AUTH_IP : + memcpy(&(temp->deny[i].mask.ip), &((*loc)->deny[i].mask.ip), + sizeof(cupsd_ipmask_t)); + break; + } + } + + return (temp); +} + + +/* + * 'cupsdDeleteAllLocations()' - Free all memory used for location authorization. + */ + +void +cupsdDeleteAllLocations(void) +{ + cupsd_location_t *loc; /* Current location */ + + + /* + * Free all of the allow/deny records first... + */ + + for (loc = (cupsd_location_t *)cupsArrayFirst(Locations); + loc; + loc = (cupsd_location_t *)cupsArrayNext(Locations)) + cupsdDeleteLocation(loc); + + /* + * Then free the location array... + */ + + cupsArrayDelete(Locations); + Locations = NULL; +} + + +/* + * 'cupsdDeleteLocation()' - Free all memory used by a location. + */ + +void +cupsdDeleteLocation( + cupsd_location_t *loc) /* I - Location to delete */ +{ + int i; /* Looping var */ + cupsd_authmask_t *mask; /* Current mask */ + + + cupsArrayRemove(Locations, loc); + + for (i = loc->num_names - 1; i >= 0; i --) + free(loc->names[i]); + + if (loc->num_names > 0) + free(loc->names); + + for (i = loc->num_allow, mask = loc->allow; i > 0; i --, mask ++) + if (mask->type == CUPSD_AUTH_NAME || mask->type == CUPSD_AUTH_INTERFACE) + free(mask->mask.name.name); + + if (loc->num_allow > 0) + free(loc->allow); + + for (i = loc->num_deny, mask = loc->deny; i > 0; i --, mask ++) + if (mask->type == CUPSD_AUTH_NAME || mask->type == CUPSD_AUTH_INTERFACE) + free(mask->mask.name.name); + + if (loc->num_deny > 0) + free(loc->deny); + + free(loc->location); + free(loc); +} + + +/* + * 'cupsdDenyHost()' - Add a host name that is not allowed to access the + * location. + */ + +void +cupsdDenyHost(cupsd_location_t *loc, /* I - Location to add to */ + char *name) /* I - Name of host or domain to add */ +{ + cupsd_authmask_t *temp; /* New host/domain mask */ + char ifname[32], /* Interface name */ + *ifptr; /* Pointer to end of name */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDenyHost(loc=%p(%s), name=\"%s\")", + loc, loc->location ? loc->location : "nil", name); + + if ((temp = add_deny(loc)) == NULL) + return; + + if (!strcasecmp(name, "@LOCAL")) + { + /* + * Deny *interface*... + */ + + temp->type = CUPSD_AUTH_INTERFACE; + temp->mask.name.name = strdup("*"); + temp->mask.name.length = 1; + } + else if (!strncasecmp(name, "@IF(", 4)) + { + /* + * Deny *interface*... + */ + + strlcpy(ifname, name + 4, sizeof(ifname)); + + ifptr = ifname + strlen(ifname); + + if (ifptr[-1] == ')') + { + ifptr --; + *ifptr = '\0'; + } + + temp->type = CUPSD_AUTH_INTERFACE; + temp->mask.name.name = strdup(ifname); + temp->mask.name.length = ifptr - ifname; + } + else + { + /* + * Deny name... + */ + + temp->type = CUPSD_AUTH_NAME; + temp->mask.name.name = strdup(name); + temp->mask.name.length = strlen(name); + } +} + + +/* + * 'cupsdDenyIP()' - Add an IP address or network that is not allowed to + * access the location. + */ + +void +cupsdDenyIP(cupsd_location_t *loc, /* I - Location to add to */ + const unsigned address[4],/* I - IP address to add */ + const unsigned netmask[4])/* I - Netmask of address */ +{ + cupsd_authmask_t *temp; /* New host/domain mask */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdDenyIP(loc=%p(%s), address=%x:%x:%x:%x, netmask=%x:%x:%x:%x)", + loc, loc->location ? loc->location : "nil", + address[0], address[1], address[2], address[3], + netmask[0], netmask[1], netmask[2], netmask[3]); + + if ((temp = add_deny(loc)) == NULL) + return; + + temp->type = CUPSD_AUTH_IP; + memcpy(temp->mask.ip.address, address, sizeof(temp->mask.ip.address)); + memcpy(temp->mask.ip.netmask, netmask, sizeof(temp->mask.ip.netmask)); +} + + +/* + * 'cupsdFindBest()' - Find the location entry that best matches the resource. + */ + +cupsd_location_t * /* O - Location that matches */ +cupsdFindBest(const char *path, /* I - Resource path */ + http_state_t state) /* I - HTTP state/request */ +{ + char uri[HTTP_MAX_URI], + /* URI in request... */ + *uriptr; /* Pointer into URI */ + cupsd_location_t *loc, /* Current location */ + *best; /* Best match for location so far */ + int bestlen; /* Length of best match */ + int limit; /* Limit field */ + static const int limits[] = /* Map http_status_t to CUPSD_AUTH_LIMIT_xyz */ + { + CUPSD_AUTH_LIMIT_ALL, + CUPSD_AUTH_LIMIT_OPTIONS, + CUPSD_AUTH_LIMIT_GET, + CUPSD_AUTH_LIMIT_GET, + CUPSD_AUTH_LIMIT_HEAD, + CUPSD_AUTH_LIMIT_POST, + CUPSD_AUTH_LIMIT_POST, + CUPSD_AUTH_LIMIT_POST, + CUPSD_AUTH_LIMIT_PUT, + CUPSD_AUTH_LIMIT_PUT, + CUPSD_AUTH_LIMIT_DELETE, + CUPSD_AUTH_LIMIT_TRACE, + CUPSD_AUTH_LIMIT_ALL, + CUPSD_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) || + !strncmp(uri, "/classes/", 9)) + { + /* + * Check if the URI has .ppd on the end... + */ + + uriptr = uri + strlen(uri) - 4; /* len > 4 if we get here... */ + + if (!strcmp(uriptr, ".ppd")) + *uriptr = '\0'; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: uri = \"%s\"...", uri); + + /* + * Loop through the list of locations to find a match... + */ + + limit = limits[state]; + best = NULL; + bestlen = 0; + + for (loc = (cupsd_location_t *)cupsArrayFirst(Locations); + loc; + loc = (cupsd_location_t *)cupsArrayNext(Locations)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: Location %s Limit %x", + loc->location ? loc->location : "nil", loc->limit); + + if (!strncmp(uri, "/printers/", 10) || !strncmp(uri, "/classes/", 9)) + { + /* + * Use case-insensitive comparison for queue names... + */ + + if (loc->length > bestlen && loc->location && + !strncasecmp(uri, loc->location, loc->length) && + loc->location[0] == '/' && + (limit & loc->limit) != 0) + { + best = loc; + bestlen = loc->length; + } + } + else + { + /* + * Use case-sensitive comparison for other URIs... + */ + + if (loc->length > bestlen && loc->location && + !strncmp(uri, loc->location, loc->length) && + loc->location[0] == '/' && + (limit & loc->limit) != 0) + { + best = loc; + bestlen = loc->length; + } + } + } + + /* + * Return the match, if any... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindBest: best = %s", + best ? best->location : "NONE"); + + return (best); +} + + +/* + * 'cupsdFindLocation()' - Find the named location. + */ + +cupsd_location_t * /* O - Location that matches */ +cupsdFindLocation(const char *location) /* I - Connection */ +{ + cupsd_location_t key; /* Search key */ + + + key.location = (char *)location; + + return ((cupsd_location_t *)cupsArrayFind(Locations, &key)); +} + + +/* + * 'cupsdIsAuthorized()' - Check to see if the user is authorized... + */ + +http_status_t /* O - HTTP_OK if authorized or error code */ +cupsdIsAuthorized(cupsd_client_t *con, /* I - Connection */ + const char *owner)/* I - Owner of object */ +{ + int i, j, /* Looping vars */ + auth, /* Authorization status */ + type; /* Type of authentication */ + unsigned address[4]; /* Authorization address */ + cupsd_location_t *best; /* Best match for location so far */ + int hostlen; /* Length of hostname */ + char username[256], /* Username to authorize */ + ownername[256], /* Owner name to authorize */ + *ptr; /* Pointer into username */ + struct passwd *pw; /* User password data */ + static const char * const levels[] = /* Auth levels */ + { + "ANON", + "USER", + "GROUP" + }; + static const char * const types[] = /* Auth types */ + { + "None", + "Basic", + "Digest", + "BasicDigest", + "Negotiate" + }; + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdIsAuthorized: con->uri=\"%s\", con->best=%p(%s)", + con->uri, con->best, con->best ? con->best->location ? + con->best->location : "(null)" : ""); + if (owner) + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdIsAuthorized: owner=\"%s\"", owner); + + /* + * If there is no "best" authentication rule for this request, then + * access is allowed from the local system and denied from other + * addresses... + */ + + if (!con->best) + { + if (!strcmp(con->http.hostname, "localhost") || + !strcmp(con->http.hostname, ServerName)) + return (HTTP_OK); + else + return (HTTP_FORBIDDEN); + } + + best = con->best; + + if ((type = best->type) == CUPSD_AUTH_DEFAULT) + type = DefaultAuthType; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdIsAuthorized: level=CUPSD_AUTH_%s, type=%s, " + "satisfy=CUPSD_AUTH_SATISFY_%s, num_names=%d", + levels[best->level], types[type], + best->satisfy ? "ANY" : "ALL", best->num_names); + + if (best->limit == CUPSD_AUTH_LIMIT_IPP) + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: op=%x(%s)", + best->op, ippOpString(best->op)); + + /* + * Check host/ip-based accesses... + */ + +#ifdef AF_INET6 + if (con->http.hostaddr->addr.sa_family == AF_INET6) + { + /* + * Copy IPv6 address... + */ + + address[0] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0]); + address[1] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1]); + address[2] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]); + address[3] = ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[3]); + } + else +#endif /* AF_INET6 */ + if (con->http.hostaddr->addr.sa_family == AF_INET) + { + /* + * Copy IPv4 address... + */ + + address[0] = 0; + address[1] = 0; + address[2] = 0; + address[3] = ntohl(con->http.hostaddr->ipv4.sin_addr.s_addr); + } + else + memset(address, 0, sizeof(address)); + + hostlen = strlen(con->http.hostname); + + auth = cupsdCheckAccess(address, con->http.hostname, hostlen, best) + ? CUPSD_AUTH_ALLOW : CUPSD_AUTH_DENY; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdIsAuthorized: auth=CUPSD_AUTH_%s...", + auth ? "DENY" : "ALLOW"); + + if (auth == CUPSD_AUTH_DENY && best->satisfy == CUPSD_AUTH_SATISFY_ALL) + return (HTTP_FORBIDDEN); + +#ifdef HAVE_SSL + /* + * See if encryption is required... + */ + + if ((best->encryption >= HTTP_ENCRYPT_REQUIRED && !con->http.tls && + strcasecmp(con->http.hostname, "localhost") && + best->satisfy == CUPSD_AUTH_SATISFY_ALL) && + !(type == CUPSD_AUTH_NEGOTIATE || + (type == CUPSD_AUTH_NONE && DefaultAuthType == CUPSD_AUTH_NEGOTIATE))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdIsAuthorized: Need upgrade to TLS..."); + return (HTTP_UPGRADE_REQUIRED); + } +#endif /* HAVE_SSL */ + + /* + * Now see what access level is required... + */ + + if (best->level == CUPSD_AUTH_ANON || /* Anonymous access - allow it */ + (type == CUPSD_AUTH_NONE && best->num_names == 0)) + return (HTTP_OK); + + if (!con->username[0] && type == CUPSD_AUTH_NONE && + best->limit == CUPSD_AUTH_LIMIT_IPP) + { + /* + * Check for unauthenticated username... + */ + + ipp_attribute_t *attr; /* requesting-user-name attribute */ + + + attr = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME); + if (attr) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdIsAuthorized: requesting-user-name=\"%s\"", + attr->values[0].string.text); + strlcpy(username, attr->values[0].string.text, sizeof(username)); + } + else if (best->satisfy == CUPSD_AUTH_SATISFY_ALL || auth == CUPSD_AUTH_DENY) + return (HTTP_UNAUTHORIZED); /* Non-anonymous needs user/pass */ + else + return (HTTP_OK); /* unless overridden with Satisfy */ + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdIsAuthorized: username=\"%s\"", + con->username); + +#ifdef HAVE_AUTHORIZATION_H + if (!con->username[0] && !con->authref) +#else + if (!con->username[0]) +#endif /* HAVE_AUTHORIZATION_H */ + { + if (best->satisfy == CUPSD_AUTH_SATISFY_ALL || auth == CUPSD_AUTH_DENY) + return (HTTP_UNAUTHORIZED); /* Non-anonymous needs user/pass */ + else + return (HTTP_OK); /* unless overridden with Satisfy */ + } + + if (con->type != type && type != CUPSD_AUTH_NONE && + (con->type != CUPSD_AUTH_BASIC || type != CUPSD_AUTH_BASICDIGEST)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Authorized using %s, expected %s!", + types[con->type], types[type]); + + return (HTTP_UNAUTHORIZED); + } + + strlcpy(username, con->username, sizeof(username)); + } + + /* + * OK, got a username. See if we need normal user access, or group + * access... (root always matches) + */ + + if (!strcmp(username, "root")) + return (HTTP_OK); + + /* + * Strip any @domain or @KDC from the username and owner... + */ + + if ((ptr = strchr(username, '@')) != NULL) + *ptr = '\0'; + + if (owner) + { + strlcpy(ownername, owner, sizeof(ownername)); + + if ((ptr = strchr(ownername, '@')) != NULL) + *ptr = '\0'; + } + else + ownername[0] = '\0'; + + /* + * Get the user info... + */ + + if (username[0]) + { + pw = getpwnam(username); + endpwent(); + } + else + pw = NULL; + + if (best->level == CUPSD_AUTH_USER) + { + /* + * If there are no names associated with this location, then + * any valid user is OK... + */ + + if (best->num_names == 0) + return (HTTP_OK); + + /* + * Otherwise check the user list and return OK if this user is + * allowed... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdIsAuthorized: Checking user membership..."); + +#ifdef HAVE_AUTHORIZATION_H + /* + * If an authorization reference was supplied it must match a right name... + */ + + if (con->authref) + { + for (i = 0; i < best->num_names; i ++) + { + if (!strncasecmp(best->names[i], "@AUTHKEY(", 9) && + check_authref(con, best->names[i] + 9)) + return (HTTP_OK); + else if (!strcasecmp(best->names[i], "@SYSTEM") && + SystemGroupAuthKey && + check_authref(con, SystemGroupAuthKey)) + return (HTTP_OK); + } + + return (HTTP_FORBIDDEN); + } +#endif /* HAVE_AUTHORIZATION_H */ + + for (i = 0; i < best->num_names; i ++) + { + if (!strcasecmp(best->names[i], "@OWNER") && owner && + !strcasecmp(username, ownername)) + return (HTTP_OK); + else if (!strcasecmp(best->names[i], "@SYSTEM")) + { + for (j = 0; j < NumSystemGroups; j ++) + if (cupsdCheckGroup(username, pw, SystemGroups[j])) + return (HTTP_OK); + } + else if (best->names[i][0] == '@') + { + if (cupsdCheckGroup(username, pw, best->names[i] + 1)) + return (HTTP_OK); + } + else if (!strcasecmp(username, best->names[i])) + return (HTTP_OK); + } + + return (HTTP_FORBIDDEN); + } + + /* + * Check to see if this user is in any of the named groups... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdIsAuthorized: Checking group membership..."); + + /* + * Check to see if this user is in any of the named groups... + */ + + for (i = 0; i < best->num_names; i ++) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdIsAuthorized: Checking group \"%s\" membership...", + best->names[i]); + + if (!strcasecmp(best->names[i], "@SYSTEM")) + { + for (j = 0; j < NumSystemGroups; j ++) + if (cupsdCheckGroup(username, pw, SystemGroups[j])) + return (HTTP_OK); + } + else if (cupsdCheckGroup(username, pw, best->names[i])) + return (HTTP_OK); + } + + /* + * The user isn't part of the specified group, so deny access... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdIsAuthorized: User not in group(s)!"); + + return (HTTP_FORBIDDEN); +} + + +/* + * 'add_allow()' - Add an allow mask to the location. + */ + +static cupsd_authmask_t * /* O - New mask record */ +add_allow(cupsd_location_t *loc) /* I - Location to add to */ +{ + cupsd_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(cupsd_authmask_t)); + else + temp = realloc(loc->allow, sizeof(cupsd_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(cupsd_authmask_t)); + return (temp); +} + + +/* + * 'add_deny()' - Add a deny mask to the location. + */ + +static cupsd_authmask_t * /* O - New mask record */ +add_deny(cupsd_location_t *loc) /* I - Location to add to */ +{ + cupsd_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(cupsd_authmask_t)); + else + temp = realloc(loc->deny, sizeof(cupsd_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(cupsd_authmask_t)); + return (temp); +} + + +#ifdef HAVE_AUTHORIZATION_H +/* + * 'check_authref()' - Check if an authorization services reference has the + * supplied right. + */ + +static int /* O - 1 if right is valid, 0 otherwise */ +check_authref(cupsd_client_t *con, /* I - Connection */ + const char *right) /* I - Right name */ +{ + OSStatus status; /* OS Status */ + AuthorizationItem authright; /* Authorization right */ + AuthorizationRights authrights; /* Authorization rights */ + AuthorizationFlags authflags; /* Authorization flags */ + + + /* + * Check to see if the user is allowed to perform the task... + */ + + if (!con->authref) + return (0); + + authright.name = right; + authright.valueLength = 0; + authright.value = NULL; + authright.flags = 0; + + authrights.count = 1; + authrights.items = &authright; + + authflags = kAuthorizationFlagDefaults | + kAuthorizationFlagExtendRights; + + if ((status = AuthorizationCopyRights(con->authref, &authrights, + kAuthorizationEmptyEnvironment, + authflags, NULL)) != 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "AuthorizationCopyRights(\"%s\") returned %d (%s)", + authright.name, (int)status, cssmErrorString(status)); + return (0); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "AuthorizationCopyRights(\"%s\") succeeded!", + authright.name); + + return (1); +} +#endif /* HAVE_AUTHORIZATION_H */ + + +/* + * 'compare_locations()' - Compare two locations. + */ + +static int /* O - Result of comparison */ +compare_locations(cupsd_location_t *a, /* I - First location */ + cupsd_location_t *b) /* I - Second location */ +{ + return (strcmp(b->location, a->location)); +} + + +#if !HAVE_LIBPAM && !defined(HAVE_USERSEC_H) +/* + * '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)) + { + /* + * 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 */ + _cups_md5_state_t state; /* Primary MD5 state info */ + _cups_md5_state_t state2; /* Secondary MD5 state info */ + unsigned char 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); + + _cupsMD5Init(&state); + _cupsMD5Append(&state, (unsigned char *)pw, pwlen); + _cupsMD5Append(&state, (unsigned char *)salt, salt_end - salt); + + _cupsMD5Init(&state2); + _cupsMD5Append(&state2, (unsigned char *)pw, pwlen); + _cupsMD5Append(&state2, (unsigned char *)salt + 3, salt_end - salt - 3); + _cupsMD5Append(&state2, (unsigned char *)pw, pwlen); + _cupsMD5Finish(&state2, digest); + + for (i = pwlen; i > 0; i -= 16) + _cupsMD5Append(&state, digest, i > 16 ? 16 : i); + + for (i = pwlen; i > 0; i >>= 1) + _cupsMD5Append(&state, (unsigned char *)((i & 1) ? "" : pw), 1); + + _cupsMD5Finish(&state, digest); + + for (i = 0; i < 1000; i ++) + { + _cupsMD5Init(&state); + + if (i & 1) + _cupsMD5Append(&state, (unsigned char *)pw, pwlen); + else + _cupsMD5Append(&state, digest, 16); + + if (i % 3) + _cupsMD5Append(&state, (unsigned char *)salt + 3, salt_end - salt - 3); + + if (i % 7) + _cupsMD5Append(&state, (unsigned char *)pw, pwlen); + + if (i & 1) + _cupsMD5Append(&state, digest, 16); + else + _cupsMD5Append(&state, (unsigned char *)pw, pwlen); + + _cupsMD5Finish(&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 && !HAVE_USERSEC_H */ + + +/* + * 'get_md5_password()' - Get an MD5 password. + */ + +static char * /* O - MD5 password string */ +get_md5_password(const char *username, /* I - Username */ + const char *group, /* I - Group */ + char passwd[33]) /* O - MD5 password string */ +{ + cups_file_t *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 */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_md5_password(username=\"%s\", group=\"%s\", passwd=%p)", + username, group ? group : "(null)", passwd); + + snprintf(filename, sizeof(filename), "%s/passwd.md5", ServerRoot); + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", filename, + strerror(errno)); + + return (NULL); + } + + while (cupsFileGets(fp, line, sizeof(line)) != NULL) + { + if (sscanf(line, "%32[^:]:%32[^:]:%32s", tempuser, tempgroup, passwd) != 3) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad MD5 password line: %s", line); + continue; + } + + if (!strcmp(username, tempuser) && + (group == NULL || !strcmp(group, tempgroup))) + { + /* + * Found the password entry! + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "Found MD5 user %s, group %s...", + username, tempgroup); + + cupsFileClose(fp); + return (passwd); + } + } + + /* + * Didn't find a password entry - return NULL! + */ + + cupsFileClose(fp); + return (NULL); +} + + +#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 */ + cupsd_authdata_t *data; /* Pointer to auth data */ + + + /* + * 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... + */ + + data = auth_data; + (void)appdata_ptr; +#else + data = (cupsd_authdata_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", + data->username)); + replies[i].resp_retcode = PAM_SUCCESS; + replies[i].resp = strdup(data->username); + break; + + case PAM_PROMPT_ECHO_OFF: + DEBUG_printf(("pam_func: PAM_PROMPT_ECHO_OFF, returning \"%s\"...\n", + data->password)); + replies[i].resp_retcode = PAM_SUCCESS; + replies[i].resp = strdup(data->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); +} +#elif !defined(HAVE_USERSEC_H) + + +/* + * '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 0000000000..29cb99b4f8 --- /dev/null +++ b/scheduler/auth.h @@ -0,0 +1,162 @@ +/* + * "$Id$" + * + * Authorization definitions for the Common UNIX Printing System (CUPS) + * scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Include necessary headers... + */ + +#include + + +/* + * HTTP authorization types and levels... + */ + +#define CUPSD_AUTH_DEFAULT -1 /* Use DefaultAuthType */ +#define CUPSD_AUTH_NONE 0 /* No authentication */ +#define CUPSD_AUTH_BASIC 1 /* Basic authentication */ +#define CUPSD_AUTH_DIGEST 2 /* Digest authentication */ +#define CUPSD_AUTH_BASICDIGEST 3 /* Basic authentication w/passwd.md5 */ +#define CUPSD_AUTH_NEGOTIATE 4 /* Kerberos authentication */ + +#define CUPSD_AUTH_ANON 0 /* Anonymous access */ +#define CUPSD_AUTH_USER 1 /* Must have a valid username/password */ +#define CUPSD_AUTH_GROUP 2 /* Must also be in a named group */ + +#define CUPSD_AUTH_ALLOW 0 /* Allow access */ +#define CUPSD_AUTH_DENY 1 /* Deny access */ + +#define CUPSD_AUTH_NAME 0 /* Authorize host by name */ +#define CUPSD_AUTH_IP 1 /* Authorize host by IP */ +#define CUPSD_AUTH_INTERFACE 2 /* Authorize host by interface */ + +#define CUPSD_AUTH_SATISFY_ALL 0 /* Satisfy both address and auth */ +#define CUPSD_AUTH_SATISFY_ANY 1 /* Satisfy either address or auth */ + +#define CUPSD_AUTH_LIMIT_DELETE 1 /* Limit DELETE requests */ +#define CUPSD_AUTH_LIMIT_GET 2 /* Limit GET requests */ +#define CUPSD_AUTH_LIMIT_HEAD 4 /* Limit HEAD requests */ +#define CUPSD_AUTH_LIMIT_OPTIONS 8 /* Limit OPTIONS requests */ +#define CUPSD_AUTH_LIMIT_POST 16 /* Limit POST requests */ +#define CUPSD_AUTH_LIMIT_PUT 32 /* Limit PUT requests */ +#define CUPSD_AUTH_LIMIT_TRACE 64 /* Limit TRACE requests */ +#define CUPSD_AUTH_LIMIT_ALL 127 /* Limit all requests */ +#define CUPSD_AUTH_LIMIT_IPP 128 /* Limit IPP requests */ + +#define IPP_ANY_OPERATION (ipp_op_t)0 + /* Any IPP operation */ +#define IPP_BAD_OPERATION (ipp_op_t)-1 + /* No IPP operation */ + + +/* + * HTTP access control structures... + */ + +typedef struct +{ + unsigned address[4], /* IP address */ + netmask[4]; /* IP netmask */ +} cupsd_ipmask_t; + +typedef struct +{ + int length; /* Length of name */ + char *name; /* Name string */ +} cupsd_namemask_t; + +typedef struct +{ + int type; /* Mask type */ + union + { + cupsd_namemask_t name; /* Host/Domain name */ + cupsd_ipmask_t ip; /* IP address/network */ + } mask; /* Mask data */ +} cupsd_authmask_t; + +typedef struct +{ + char *location; /* Location of resource */ + ipp_op_t op; /* IPP operation */ + 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 */ + cupsd_authmask_t *allow; /* Allow lines */ + int num_deny; /* Number of Deny lines */ + cupsd_authmask_t *deny; /* Deny lines */ + http_encryption_t encryption; /* To encrypt or not to encrypt... */ +} cupsd_location_t; + +typedef struct cupsd_client_s cupsd_client_t; + + +/* + * Globals... + */ + +VAR cups_array_t *Locations VALUE(NULL); + /* Authorization locations */ +VAR int DefaultAuthType VALUE(CUPSD_AUTH_BASIC); + /* Default AuthType, if not specified */ +#ifdef HAVE_SSL +VAR http_encryption_t DefaultEncryption VALUE(HTTP_ENCRYPT_REQUIRED); + /* Default encryption for authentication */ +#endif /* HAVE_SSL */ + + +/* + * Prototypes... + */ + +extern cupsd_location_t *cupsdAddLocation(const char *location); +extern void cupsdAddName(cupsd_location_t *loc, char *name); +extern void cupsdAllowHost(cupsd_location_t *loc, char *name); +extern void cupsdAllowIP(cupsd_location_t *loc, + const unsigned address[4], + const unsigned netmask[4]); +extern void cupsdAuthorize(cupsd_client_t *con); +extern int cupsdCheckAccess(unsigned ip[4], char *name, + int namelen, cupsd_location_t *loc); +extern int cupsdCheckAuth(unsigned ip[4], char *name, int namelen, + int num_masks, cupsd_authmask_t *masks); +extern int cupsdCheckGroup(const char *username, + struct passwd *user, + const char *groupname); +#ifdef HAVE_GSSAPI +extern krb5_ccache cupsdCopyKrb5Creds(cupsd_client_t *con); +#endif /* HAVE_GSSAPI */ +extern cupsd_location_t *cupsdCopyLocation(cupsd_location_t **loc); +extern void cupsdDeleteAllLocations(void); +extern void cupsdDeleteLocation(cupsd_location_t *loc); +extern void cupsdDenyHost(cupsd_location_t *loc, char *name); +extern void cupsdDenyIP(cupsd_location_t *loc, + const unsigned address[4], + const unsigned netmask[4]); +extern cupsd_location_t *cupsdFindBest(const char *path, http_state_t state); +extern cupsd_location_t *cupsdFindLocation(const char *location); +extern http_status_t cupsdIsAuthorized(cupsd_client_t *con, const char *owner); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/banners.c b/scheduler/banners.c new file mode 100644 index 0000000000..5722bf0fe3 --- /dev/null +++ b/scheduler/banners.c @@ -0,0 +1,224 @@ +/* + * "$Id$" + * + * Banner routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdFindBanner() - Find a named banner. + * cupsdLoadBanners() - Load all available banner files... + * add_banner() - Add a banner to the array. + * compare_banners() - Compare two banners. + * free_banners() - Free all banners. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include + + +/* + * Local functions... + */ + +static void add_banner(const char *name, const char *filename); +static int compare_banners(const cupsd_banner_t *b0, + const cupsd_banner_t *b1); +static void free_banners(void); + + +/* + * 'cupsdFindBanner()' - Find a named banner. + */ + +cupsd_banner_t * /* O - Pointer to banner or NULL */ +cupsdFindBanner(const char *name) /* I - Name of banner */ +{ + cupsd_banner_t key; /* Search key */ + + + key.name = (char *)name; + + return ((cupsd_banner_t *)cupsArrayFind(Banners, &key)); +} + + +/* + * 'cupsdLoadBanners()' - Load all available banner files... + */ + +void +cupsdLoadBanners(const char *d) /* I - Directory to search */ +{ + cups_dir_t *dir; /* Directory pointer */ + cups_dentry_t *dent; /* Directory entry */ + char filename[1024], /* Name of banner */ + *ext; /* Pointer to extension */ + + + /* + * Free old banner info... + */ + + free_banners(); + + /* + * Try opening the banner directory... + */ + + if ((dir = cupsDirOpen(d)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdLoadBanners: Unable to open banner directory \"%s\": %s", + d, strerror(errno)); + return; + } + + /* + * Read entries, skipping directories and backup files. + */ + + Banners = cupsArrayNew((cups_array_func_t)compare_banners, NULL); + + while ((dent = cupsDirRead(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->filename); + + if (S_ISDIR(dent->fileinfo.st_mode)) + continue; + + if (dent->filename[0] == '~' || + dent->filename[strlen(dent->filename) - 1] == '~') + continue; + + if ((ext = strrchr(dent->filename, '.')) != NULL) + if (!strcmp(ext, ".bck") || + !strcmp(ext, ".bak") || + !strcmp(ext, ".sav")) + continue; + + /* + * Must be a valid file; add it! + */ + + add_banner(dent->filename, filename); + } + + /* + * Close the directory... + */ + + cupsDirClose(dir); +} + + +/* + * 'add_banner()' - Add a banner to the array. + */ + +static void +add_banner(const char *name, /* I - Name of banner */ + const char *filename) /* I - Filename for banner */ +{ + mime_type_t *filetype; /* Filetype */ + cupsd_banner_t *temp; /* New banner data */ + + + /* + * See what the filetype is... + */ + + if ((filetype = mimeFileType(MimeDatabase, filename, NULL, NULL)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "add_banner: Banner \"%s\" (\"%s\") is of an unknown file " + "type - skipping!", name, filename); + return; + } + + /* + * Allocate memory... + */ + + if ((temp = calloc(1, sizeof(cupsd_banner_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "add_banner: Unable to allocate memory for banner \"%s\" - " + "skipping!", name); + return; + } + + /* + * Copy the new banner data over... + */ + + if ((temp->name = strdup(name)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "add_banner: Unable to allocate memory for banner \"%s\" - " + "skipping!", name); + free(temp); + return; + } + + temp->filetype = filetype; + + cupsArrayAdd(Banners, temp); +} + + +/* + * 'compare_banners()' - Compare two banners. + */ + +static int /* O - -1 if name0 < name1, etc. */ +compare_banners( + const cupsd_banner_t *b0, /* I - First banner */ + const cupsd_banner_t *b1) /* I - Second banner */ +{ + return (strcasecmp(b0->name, b1->name)); +} + + +/* + * 'free_banners()' - Free all banners. + */ + +static void +free_banners(void) +{ + cupsd_banner_t *temp; /* Current banner */ + + + for (temp = (cupsd_banner_t *)cupsArrayFirst(Banners); + temp; + temp = (cupsd_banner_t *)cupsArrayNext(Banners)) + { + free(temp->name); + free(temp); + } + + cupsArrayDelete(Banners); + Banners = NULL; +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/banners.h b/scheduler/banners.h new file mode 100644 index 0000000000..7a38e58a4b --- /dev/null +++ b/scheduler/banners.h @@ -0,0 +1,45 @@ +/* + * "$Id$" + * + * Banner definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Banner information structure... + */ + +typedef struct /**** Banner file information ****/ +{ + char *name; /* Name of banner */ + mime_type_t *filetype; /* Filetype for banner */ +} cupsd_banner_t; + + +/* + * Globals... + */ + +VAR cups_array_t *Banners VALUE(NULL); + /* Available banner files */ + + +/* + * Prototypes... + */ + +extern cupsd_banner_t *cupsdFindBanner(const char *name); +extern void cupsdLoadBanners(const char *d); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cert.c b/scheduler/cert.c new file mode 100644 index 0000000000..e4446a279e --- /dev/null +++ b/scheduler/cert.c @@ -0,0 +1,442 @@ +/* + * "$Id$" + * + * Authentication certificate routines for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddCert() - Add a certificate. + * cupsdDeleteCert() - Delete a single certificate. + * cupsdDeleteAllCerts() - Delete all certificates... + * cupsdFindCert() - Find a certificate. + * cupsdInitCerts() - Initialize the certificate "system" and root + * certificate. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#ifdef HAVE_ACL_INIT +# include +# ifdef HAVE_MEMBERSHIP_H +# include +# endif /* HAVE_MEMBERSHIP_H */ +#endif /* HAVE_ACL_INIT */ + + +/* + * 'cupsdAddCert()' - Add a certificate. + */ + +void +cupsdAddCert(int pid, /* I - Process ID */ + const char *username, /* I - Username */ + void *ccache) /* I - Kerberos credentials or NULL */ +{ + int i; /* Looping var */ + cupsd_cert_t *cert; /* Current certificate */ + int fd; /* Certificate file */ + char filename[1024]; /* Certificate filename */ + static const char hex[] = "0123456789ABCDEF"; + /* Hex constants... */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddCert: Adding certificate for PID %d", pid); + + /* + * Allocate memory for the certificate... + */ + + if ((cert = calloc(sizeof(cupsd_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[CUPS_RAND() & 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", StateDir, pid); + unlink(filename); + + if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create certificate file %s - %s", + filename, strerror(errno)); + free(cert); + return; + } + + if (pid == 0) + { +#ifdef HAVE_ACL_INIT + acl_t acl; /* ACL information */ + acl_entry_t entry; /* ACL entry */ + acl_permset_t permset; /* Permissions */ +# ifdef HAVE_MBR_UID_TO_UUID + uuid_t group; /* Group ID */ +# endif /* HAVE_MBR_UID_TO_UUID */ + static int acls_not_supported = 0; + /* Only warn once */ +#endif /* HAVE_ACL_INIT */ + + + /* + * Root certificate... + */ + + fchmod(fd, 0440); + fchown(fd, RunUser, SystemGroupIDs[0]); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d", + NumSystemGroups); + +#ifdef HAVE_ACL_INIT + if (NumSystemGroups > 1) + { + /* + * Set POSIX ACLs for the root certificate so that all system + * groups can access it... + */ + +# ifdef HAVE_MBR_UID_TO_UUID + /* + * On MacOS X, ACLs use UUIDs instead of GIDs... + */ + + acl = acl_init(NumSystemGroups - 1); + + for (i = 1; i < NumSystemGroups; i ++) + { + /* + * Add each group ID to the ACL... + */ + + acl_create_entry(&acl, &entry); + acl_get_permset(entry, &permset); + acl_add_perm(permset, ACL_READ_DATA); + acl_set_tag_type(entry, ACL_EXTENDED_ALLOW); + mbr_gid_to_uuid((gid_t)SystemGroupIDs[i], group); + acl_set_qualifier(entry, &group); + acl_set_permset(entry, permset); + } +# else + /* + * POSIX ACLs need permissions for owner, group, other, and mask + * in addition to the rest of the system groups... + */ + + acl = acl_init(NumSystemGroups + 3); + + /* Owner */ + acl_create_entry(&acl, &entry); + acl_get_permset(entry, &permset); + acl_add_perm(permset, ACL_READ); + acl_set_tag_type(entry, ACL_USER_OBJ); + acl_set_permset(entry, permset); + + /* Group */ + acl_create_entry(&acl, &entry); + acl_get_permset(entry, &permset); + acl_add_perm(permset, ACL_READ); + acl_set_tag_type(entry, ACL_GROUP_OBJ); + acl_set_permset(entry, permset); + + /* Others */ + acl_create_entry(&acl, &entry); + acl_get_permset(entry, &permset); + acl_add_perm(permset, 0); + acl_set_tag_type(entry, ACL_OTHER); + acl_set_permset(entry, permset); + + /* Mask */ + acl_create_entry(&acl, &entry); + acl_get_permset(entry, &permset); + acl_add_perm(permset, ACL_READ); + acl_set_tag_type(entry, ACL_MASK); + acl_set_permset(entry, permset); + + for (i = 1; i < NumSystemGroups; i ++) + { + /* + * Add each group ID to the ACL... + */ + + acl_create_entry(&acl, &entry); + acl_get_permset(entry, &permset); + acl_add_perm(permset, ACL_READ); + acl_set_tag_type(entry, ACL_GROUP); + acl_set_qualifier(entry, SystemGroupIDs + i); + acl_set_permset(entry, permset); + } + + if (acl_valid(acl)) + { + char *text, *textptr; /* Temporary string */ + + + cupsdLogMessage(CUPSD_LOG_ERROR, "ACL did not validate: %s", + strerror(errno)); + text = acl_to_text(acl, NULL); + for (textptr = strchr(text, '\n'); + textptr; + textptr = strchr(textptr + 1, '\n')) + *textptr = ','; + + cupsdLogMessage(CUPSD_LOG_ERROR, "ACL: %s", text); + free(text); + } +# endif /* HAVE_MBR_UID_TO_UUID */ + + if (acl_set_fd(fd, acl)) + { + if (errno != EOPNOTSUPP || !acls_not_supported) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to set ACLs on root certificate \"%s\" - %s", + filename, strerror(errno)); + + if (errno == EOPNOTSUPP) + acls_not_supported = 1; + } + + acl_free(acl); + } +#endif /* HAVE_ACL_INIT */ + + RootCertTime = time(NULL); + } + else + { + /* + * CGI certificate... + */ + + fchmod(fd, 0400); + fchown(fd, User, Group); + } + + DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username, + cert->certificate)); + + write(fd, cert->certificate, strlen(cert->certificate)); + close(fd); + + /* + * Add Kerberos credentials as needed... + */ + +#ifdef HAVE_GSSAPI + cert->ccache = (krb5_ccache)ccache; +#else + (void)ccache; +#endif /* HAVE_GSSAPI */ + + /* + * Insert the certificate at the front of the list... + */ + + cert->next = Certs; + Certs = cert; +} + + +/* + * 'cupsdDeleteCert()' - Delete a single certificate. + */ + +void +cupsdDeleteCert(int pid) /* I - Process ID */ +{ + cupsd_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... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDeleteCert: Removing certificate for PID %d", pid); + + DEBUG_printf(("DELETE pid=%d, username=%s, cert=%s\n", cert->pid, + cert->username, cert->certificate)); + + if (prev == NULL) + Certs = cert->next; + else + prev->next = cert->next; + +#ifdef HAVE_GSSAPI + /* + * Release Kerberos credentials as needed... + */ + + if (cert->ccache) + krb5_cc_destroy(KerberosContext, cert->ccache); +#endif /* HAVE_GSSAPI */ + + free(cert); + + /* + * Delete the file and return... + */ + + snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid); + if (unlink(filename)) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove %s!", filename); + + return; + } +} + + +/* + * 'cupsdDeleteAllCerts()' - Delete all certificates... + */ + +void +cupsdDeleteAllCerts(void) +{ + cupsd_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", StateDir, cert->pid); + if (unlink(filename)) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove %s!", filename); + + /* + * Free memory... + */ + + next = cert->next; + free(cert); + } + + Certs = NULL; + RootCertTime = 0; +} + + +/* + * 'cupsdFindCert()' - Find a certificate. + */ + +cupsd_cert_t * /* O - Matching certificate or NULL */ +cupsdFindCert(const char *certificate) /* I - Certificate */ +{ + cupsd_cert_t *cert; /* Current certificate */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert(certificate=%s)", + certificate); + for (cert = Certs; cert != NULL; cert = cert->next) + if (!strcasecmp(certificate, cert->certificate)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Returning %s...", + cert->username); + return (cert); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Certificate not found!"); + + return (NULL); +} + + +/* + * 'cupsdInitCerts()' - Initialize the certificate "system" and root + * certificate. + */ + +void +cupsdInitCerts(void) +{ +#ifndef HAVE_ARC4RANDOM + cups_file_t *fp; /* /dev/random file */ + + + /* + * Initialize the random number generator using the random device or + * the current time, as available... + */ + + if ((fp = cupsFileOpen("/dev/urandom", "rb")) == NULL) + { + struct timeval tod; /* Time of day */ + + /* + * Get the time in usecs and use it as the initial seed... + */ + + gettimeofday(&tod, NULL); + + CUPS_SRAND((unsigned)(tod.tv_sec + tod.tv_usec)); + } + else + { + unsigned seed; /* Seed for random number generator */ + + /* + * Read 4 random characters from the random device and use + * them as the seed... + */ + + seed = cupsFileGetChar(fp); + seed = (seed << 8) | cupsFileGetChar(fp); + seed = (seed << 8) | cupsFileGetChar(fp); + CUPS_SRAND((seed << 8) | cupsFileGetChar(fp)); + + cupsFileClose(fp); + } +#endif /* !HAVE_ARC4RANDOM */ + + /* + * Create a root certificate and return... + */ + + if (!RunUser) + cupsdAddCert(0, "root", NULL); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cert.h b/scheduler/cert.h new file mode 100644 index 0000000000..cad3ac2fca --- /dev/null +++ b/scheduler/cert.h @@ -0,0 +1,57 @@ +/* + * "$Id$" + * + * Authentication certificate definitions for the Common UNIX + * Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Certificate structure... + */ + +typedef struct cupsd_cert_s +{ + struct cupsd_cert_s *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 */ +#ifdef HAVE_GSSAPI + krb5_ccache ccache; /* Kerberos credential cache */ +#endif /* HAVE_GSSAPI */ +} cupsd_cert_t; + + +/* + * Globals... + */ + +VAR cupsd_cert_t *Certs /* List of certificates */ + VALUE(NULL); +VAR time_t RootCertTime /* Root certificate update time */ + VALUE(0); + + +/* + * Prototypes... + */ + +extern void cupsdAddCert(int pid, const char *username, + void *ccache); +extern void cupsdDeleteCert(int pid); +extern void cupsdDeleteAllCerts(void); +extern cupsd_cert_t *cupsdFindCert(const char *certificate); +extern void cupsdInitCerts(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/classes.c b/scheduler/classes.c new file mode 100644 index 0000000000..b37fb09f27 --- /dev/null +++ b/scheduler/classes.c @@ -0,0 +1,884 @@ +/* + * "$Id$" + * + * Printer class routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddClass() - Add a class to the system. + * cupsdAddPrinterToClass() - Add a printer to a class... + * cupsdDeletePrinterFromClass() - Delete a printer from a class. + * cupsdDeletePrinterFromClasses() - Delete a printer from all classes. + * cupsdFindAvailablePrinter() - Find an available printer in a class. + * cupsdFindClass() - Find the named class. + * cupsdLoadAllClasses() - Load classes from the classes.conf file. + * cupsdSaveAllClasses() - Save classes to the classes.conf file. + * cupsdUpdateImplicitClasses() - Update the accepting state of implicit + * classes. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + + +/* + * 'cupsdAddClass()' - Add a class to the system. + */ + +cupsd_printer_t * /* O - New class */ +cupsdAddClass(const char *name) /* I - Name of class */ +{ + cupsd_printer_t *c; /* New class */ + char uri[1024]; /* Class URI */ + + + /* + * Add the printer and set the type to "class"... + */ + + if ((c = cupsdAddPrinter(name)) != NULL) + { + /* + * Change from a printer to a class... + */ + + c->type = CUPS_PRINTER_CLASS; + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + ServerName, RemotePort, "/classes/%s", name); + cupsdSetString(&c->uri, uri); + + cupsdSetString(&c->error_policy, "retry-current-job"); + } + + return (c); +} + + +/* + * 'cupsdAddPrinterToClass()' - Add a printer to a class... + */ + +void +cupsdAddPrinterToClass( + cupsd_printer_t *c, /* I - Class to add to */ + cupsd_printer_t *p) /* I - Printer to add */ +{ + int i; /* Looping var */ + cupsd_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(cupsd_printer_t *)); + else + temp = realloc(c->printers, sizeof(cupsd_printer_t *) * (c->num_printers + 1)); + + if (temp == NULL) + { + cupsdLogMessage(CUPSD_LOG_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; +} + + +/* + * 'cupsdDeletePrinterFromClass()' - Delete a printer from a class. + */ + +int /* O - 1 if class changed, 0 otherwise */ +cupsdDeletePrinterFromClass( + cupsd_printer_t *c, /* I - Class to delete from */ + cupsd_printer_t *p) /* I - Printer to delete */ +{ + int i; /* Looping var */ + + + /* + * 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) + memmove(c->printers + i, c->printers + i + 1, + (c->num_printers - i) * sizeof(cupsd_printer_t *)); + } + else + return (0); + + /* + * Update the IPP attributes (have to do this for member-names)... + */ + + cupsdSetPrinterAttrs(c); + + return (1); +} + + +/* + * 'cupsdDeletePrinterFromClasses()' - Delete a printer from all classes. + */ + +int /* O - 1 if class changed, 0 otherwise */ +cupsdDeletePrinterFromClasses( + cupsd_printer_t *p) /* I - Printer to delete */ +{ + int changed = 0; /* Any class changed? */ + cupsd_printer_t *c; /* Pointer to current class */ + + + /* + * Loop through the printer/class list and remove the printer + * from each class listed... + */ + + for (c = (cupsd_printer_t *)cupsArrayFirst(Printers); + c; + c = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) + changed |= cupsdDeletePrinterFromClass(c, p); + + /* + * Then clean out any empty implicit classes... + */ + + for (c = (cupsd_printer_t *)cupsArrayFirst(ImplicitPrinters); + c; + c = (cupsd_printer_t *)cupsArrayNext(ImplicitPrinters)) + if (c->num_printers == 0) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "Deleting implicit class \"%s\"...", + c->name); + cupsdDeletePrinter(c, 0); + changed = 1; + } + + return (changed); +} + + +/* + * 'cupsdFindAvailablePrinter()' - Find an available printer in a class. + */ + +cupsd_printer_t * /* O - Available printer or NULL */ +cupsdFindAvailablePrinter( + const char *name) /* I - Class to check */ +{ + int i; /* Looping var */ + cupsd_printer_t *c; /* Printer class */ + + + /* + * Find the class... + */ + + if ((c = cupsdFindClass(name)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to find class \"%s\"!", name); + return (NULL); + } + + if (c->num_printers == 0) + return (NULL); + + /* + * Make sure that the last printer is also a valid index into the printer + * array. If not, reset the last printer to 0... + */ + + if (c->last_printer >= c->num_printers) + c->last_printer = 0; + + /* + * 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]->accepting && + (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); +} + + +/* + * 'cupsdFindClass()' - Find the named class. + */ + +cupsd_printer_t * /* O - Matching class or NULL */ +cupsdFindClass(const char *name) /* I - Name of class */ +{ + cupsd_printer_t *c; /* Current class/printer */ + + + if ((c = cupsdFindDest(name)) != NULL && + (c->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))) + return (c); + else + return (NULL); +} + + +/* + * 'cupsdLoadAllClasses()' - Load classes from the classes.conf file. + */ + +void +cupsdLoadAllClasses(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* classes.conf file */ + int linenum; /* Current line number */ + char line[4096], /* Line from file */ + *value, /* Pointer to value */ + *valueptr; /* Pointer into value */ + cupsd_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 = cupsFileOpen(line, "r")) == NULL) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", line, + strerror(errno)); + return; + } + + /* + * Read class configurations until we hit EOF... + */ + + linenum = 0; + p = NULL; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Decode the directive... + */ + + if (!strcasecmp(line, " or + */ + + if (p == NULL && value) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading class %s...", value); + + /* + * Since prior classes may have implicitly defined this class, + * see if it already exists... + */ + + if ((p = cupsdFindDest(value)) != NULL) + { + p->type = CUPS_PRINTER_CLASS; + cupsdSetStringf(&p->uri, "ipp://%s:%d/classes/%s", ServerName, + LocalPort, value); + cupsdSetString(&p->error_policy, "retry-job"); + } + else + p = cupsdAddClass(value); + + p->accepting = 1; + p->state = IPP_PRINTER_IDLE; + + if (!strcasecmp(line, "")) + { + if (p != NULL) + { + cupsdSetPrinterAttrs(p); + p = NULL; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!p) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "AuthInfoRequired")) + { + if (!cupsdSetAuthInfoRequired(p, value, NULL)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad AuthInfoRequired on line %d of classes.conf.", + linenum); + } + else if (!strcasecmp(line, "Info")) + { + if (value) + cupsdSetString(&p->info, value); + } + else if (!strcasecmp(line, "Location")) + { + if (value) + cupsdSetString(&p->location, value); + } + else if (!strcasecmp(line, "Option") && value) + { + /* + * Option name value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + p->num_options = cupsAddOption(value, valueptr, p->num_options, + &(p->options)); + } + } + else if (!strcasecmp(line, "Printer")) + { + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + continue; + } + else if ((temp = cupsdFindPrinter(value)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Unknown printer %s on line %d of classes.conf.", + value, linenum); + + /* + * Add the missing remote printer... + */ + + if ((temp = cupsdAddPrinter(value)) != NULL) + { + cupsdSetString(&temp->make_model, "Remote Printer on unknown"); + + temp->state = IPP_PRINTER_STOPPED; + temp->type |= CUPS_PRINTER_REMOTE; + temp->browse_time = 2147483647; + + cupsdSetString(&temp->location, "Location Unknown"); + cupsdSetString(&temp->info, "No Information Available"); + temp->hostname[0] = '\0'; + + cupsdSetPrinterAttrs(temp); + } + } + + if (temp) + cupsdAddPrinterToClass(p, temp); + } + else if (!strcasecmp(line, "State")) + { + /* + * Set the initial queue state... + */ + + if (!strcasecmp(value, "idle")) + p->state = IPP_PRINTER_IDLE; + else if (!strcasecmp(value, "stopped")) + { + p->state = IPP_PRINTER_STOPPED; + + for (i = 0 ; i < p->num_reasons; i ++) + if (!strcmp("paused", p->reasons[i])) + break; + + if (i >= p->num_reasons && + p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) + { + p->reasons[p->num_reasons] = _cupsStrAlloc("paused"); + p->num_reasons ++; + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", + linenum); + } + else if (!strcasecmp(line, "StateMessage")) + { + /* + * Set the initial queue state message... + */ + + if (value) + strlcpy(p->state_message, value, sizeof(p->state_message)); + } + else if (!strcasecmp(line, "StateTime")) + { + /* + * Set the state time... + */ + + if (value) + p->state_time = atoi(value); + } + else if (!strcasecmp(line, "Accepting")) + { + /* + * Set the initial accepting state... + */ + + if (value && + (!strcasecmp(value, "yes") || + !strcasecmp(value, "on") || + !strcasecmp(value, "true"))) + p->accepting = 1; + else if (value && + (!strcasecmp(value, "no") || + !strcasecmp(value, "off") || + !strcasecmp(value, "false"))) + p->accepting = 0; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", + linenum); + } + else if (!strcasecmp(line, "Shared")) + { + /* + * Set the initial shared state... + */ + + if (value && + (!strcasecmp(value, "yes") || + !strcasecmp(value, "on") || + !strcasecmp(value, "true"))) + p->shared = 1; + else if (value && + (!strcasecmp(value, "no") || + !strcasecmp(value, "off") || + !strcasecmp(value, "false"))) + p->shared = 0; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", + linenum); + } + else if (!strcasecmp(line, "JobSheets")) + { + /* + * Set the initial job sheets... + */ + + if (value) + { + for (valueptr = value; + *valueptr && !isspace(*valueptr & 255); + valueptr ++); + + if (*valueptr) + *valueptr++ = '\0'; + + cupsdSetString(&p->job_sheets[0], value); + + while (isspace(*valueptr & 255)) + valueptr ++; + + if (*valueptr) + { + for (value = valueptr; + *valueptr && !isspace(*valueptr & 255); + valueptr ++); + + if (*valueptr) + *valueptr = '\0'; + + cupsdSetString(&p->job_sheets[1], value); + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "AllowUser")) + { + if (value) + { + p->deny_users = 0; + cupsdAddPrinterUser(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "DenyUser")) + { + if (value) + { + p->deny_users = 1; + cupsdAddPrinterUser(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "QuotaPeriod")) + { + if (value) + p->quota_period = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "PageLimit")) + { + if (value) + p->page_limit = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "KLimit")) + { + if (value) + p->k_limit = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "OpPolicy")) + { + if (value) + { + cupsd_policy_t *pol; /* Policy */ + + + if ((pol = cupsdFindPolicy(value)) != NULL) + { + cupsdSetString(&p->op_policy, value); + p->op_policy_ptr = pol; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad policy \"%s\" on line %d of classes.conf", + value, linenum); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else if (!strcasecmp(line, "ErrorPolicy")) + { + if (value) + { + if (strcmp(value, "retry-current-job") && strcmp(value, "retry-job")) + cupsdLogMessage(CUPSD_LOG_WARN, + "ErrorPolicy %s ignored on line %d of classes.conf", + value, linenum); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of classes.conf.", linenum); + } + else + { + /* + * Something else we don't understand... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown configuration directive %s on line %d of classes.conf.", + line, linenum); + } + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdSaveAllClasses()' - Save classes to the classes.conf file. + */ + +void +cupsdSaveAllClasses(void) +{ + cups_file_t *fp; /* classes.conf file */ + char temp[1024], /* Temporary string */ + backup[1024], /* printers.conf.O file */ + value[2048]; /* Value string */ + cupsd_printer_t *pclass; /* Current printer class */ + int i; /* Looping var */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + cups_option_t *option; /* Current option */ + + + /* + * 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)) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup classes.conf - %s", + strerror(errno)); + } + + if ((fp = cupsFileOpen(temp, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to save classes.conf - %s", + strerror(errno)); + + if (rename(backup, temp)) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to restore classes.conf - %s", + strerror(errno)); + return; + } + else + cupsdLogMessage(CUPSD_LOG_INFO, "Saving classes.conf..."); + + /* + * Restrict access to the file... + */ + + fchown(cupsFileNumber(fp), RunUser, Group); + fchmod(cupsFileNumber(fp), ConfigFilePerm); + + /* + * Write a small header to the file... + */ + + curtime = time(NULL); + curdate = localtime(&curtime); + strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate); + + cupsFilePuts(fp, "# Class configuration file for " CUPS_SVERSION "\n"); + cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp); + cupsFilePuts(fp, "# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING\n"); + + /* + * Write each local class known to the system... + */ + + for (pclass = (cupsd_printer_t *)cupsArrayFirst(Printers); + pclass; + pclass = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * 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) + cupsFilePrintf(fp, "\n", pclass->name); + else + cupsFilePrintf(fp, "\n", pclass->name); + + if (pclass->num_auth_info_required > 0) + { + switch (pclass->num_auth_info_required) + { + case 1 : + strlcpy(value, pclass->auth_info_required[0], sizeof(value)); + break; + + case 2 : + snprintf(value, sizeof(value), "%s,%s", + pclass->auth_info_required[0], + pclass->auth_info_required[1]); + break; + + case 3 : + default : + snprintf(value, sizeof(value), "%s,%s,%s", + pclass->auth_info_required[0], + pclass->auth_info_required[1], + pclass->auth_info_required[2]); + break; + } + + cupsFilePutConf(fp, "AuthInfoRequired", value); + } + + if (pclass->info) + cupsFilePutConf(fp, "Info", pclass->info); + + if (pclass->location) + cupsFilePutConf(fp, "Location", pclass->location); + + if (pclass->state == IPP_PRINTER_STOPPED) + cupsFilePuts(fp, "State Stopped\n"); + else + cupsFilePuts(fp, "State Idle\n"); + + cupsFilePrintf(fp, "StateTime %d\n", (int)pclass->state_time); + + if (pclass->accepting) + cupsFilePuts(fp, "Accepting Yes\n"); + else + cupsFilePuts(fp, "Accepting No\n"); + + if (pclass->shared) + cupsFilePuts(fp, "Shared Yes\n"); + else + cupsFilePuts(fp, "Shared No\n"); + + snprintf(value, sizeof(value), "%s %s", pclass->job_sheets[0], + pclass->job_sheets[1]); + cupsFilePutConf(fp, "JobSheets", value); + + for (i = 0; i < pclass->num_printers; i ++) + cupsFilePrintf(fp, "Printer %s\n", pclass->printers[i]->name); + + cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period); + cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit); + cupsFilePrintf(fp, "KLimit %d\n", pclass->k_limit); + + for (i = 0; i < pclass->num_users; i ++) + cupsFilePutConf(fp, pclass->deny_users ? "DenyUser" : "AllowUser", + pclass->users[i]); + + if (pclass->op_policy) + cupsFilePutConf(fp, "OpPolicy", pclass->op_policy); + if (pclass->error_policy) + cupsFilePutConf(fp, "ErrorPolicy", pclass->error_policy); + + for (i = pclass->num_options, option = pclass->options; + i > 0; + i --, option ++) + { + snprintf(value, sizeof(value), "%s %s", option->name, option->value); + cupsFilePutConf(fp, "Option", value); + } + + cupsFilePuts(fp, "\n"); + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdUpdateImplicitClasses()' - Update the accepting state of implicit + * classes. + */ + +void +cupsdUpdateImplicitClasses(void) +{ + int i; /* Looping var */ + cupsd_printer_t *pclass; /* Current class */ + int accepting; /* printer-is-accepting-jobs value */ + + + for (pclass = (cupsd_printer_t *)cupsArrayFirst(ImplicitPrinters); + pclass; + pclass = (cupsd_printer_t *)cupsArrayNext(ImplicitPrinters)) + { + /* + * Loop through the printers to come up with a composite state... + */ + + for (i = 0, accepting = 0; i < pclass->num_printers; i ++) + if ((accepting = pclass->printers[i]->accepting) != 0) + break; + + pclass->accepting = accepting; + } +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/classes.h b/scheduler/classes.h new file mode 100644 index 0000000000..c24c3cb0b8 --- /dev/null +++ b/scheduler/classes.h @@ -0,0 +1,36 @@ +/* + * "$Id$" + * + * Printer class definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + + +/* + * Prototypes... + */ + +extern cupsd_printer_t *cupsdAddClass(const char *name); +extern void cupsdAddPrinterToClass(cupsd_printer_t *c, + cupsd_printer_t *p); +extern int cupsdDeletePrinterFromClass(cupsd_printer_t *c, + cupsd_printer_t *p); +extern int cupsdDeletePrinterFromClasses(cupsd_printer_t *p); +extern cupsd_printer_t *cupsdFindAvailablePrinter(const char *name); +extern cupsd_printer_t *cupsdFindClass(const char *name); +extern void cupsdLoadAllClasses(void); +extern void cupsdSaveAllClasses(void); +extern void cupsdUpdateImplicitClasses(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/client.c b/scheduler/client.c new file mode 100644 index 0000000000..3c480a1142 --- /dev/null +++ b/scheduler/client.c @@ -0,0 +1,5296 @@ +/* + * "$Id$" + * + * Client routines for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAcceptClient() - Accept a new client. + * cupsdCloseAllClients() - Close all remote clients immediately. + * cupsdCloseClient() - Close a remote client. + * cupsdFlushHeader() - Flush the header fields to the client. + * cupsdReadClient() - Read data from a client. + * cupsdSendCommand() - Send output from a command via HTTP. + * cupsdSendError() - Send an error message via HTTP. + * cupsdSendHeader() - Send an HTTP request. + * cupsdUpdateCGI() - Read status messages from CGI scripts and + * programs. + * cupsdWriteClient() - Write data to a client as needed. + * check_if_modified() - Decode an "If-Modified-Since" line. + * compare_clients() - Compare two client connections. + * data_ready() - Check whether data is available from a client. + * encrypt_client() - Enable encryption for the client... + * get_cdsa_certificate() - Get a SSL/TLS certificate from the System + * keychain. + * get_file() - Get a filename and state info. + * install_conf_file() - Install a configuration file. + * is_cgi() - Is the resource a CGI script/program? + * is_path_absolute() - Is a path absolute and free of relative elements + * (i.e. ".."). + * make_certificate() - Make a self-signed SSL/TLS certificate. + * pipe_command() - Pipe the output of a command to the remote client. + * valid_host() - Is the Host: field valid? + * write_file() - Send a file via HTTP. + * write_pipe() - Flag that data is available on the CGI pipe. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + +#ifdef HAVE_CDSASSL +# include +# ifdef HAVE_SECITEM_H +# include +# endif /* HAVE_SECITEM_H */ +# ifdef HAVE_SECITEMPRIV_H +# include +# else /* Declare constant from that header... */ +extern const CFTypeRef kSecClassIdentity; +# endif /* HAVE_SECITEMPRIV_H */ +# ifdef HAVE_SECIDENTITYSEARCHPRIV_H +# include +# else /* Declare prototype for function in that header... */ +extern OSStatus SecIdentitySearchCreateWithPolicy(SecPolicyRef policy, + CFStringRef idString, CSSM_KEYUSE keyUsage, + CFTypeRef keychainOrArray, + Boolean returnOnlyValidIdentities, + SecIdentitySearchRef* searchRef); +# endif /* HAVE_SECIDENTITYSEARCHPRIV_H */ +# ifdef HAVE_SECPOLICYPRIV_H +# include +# else /* Declare prototype for function in that header... */ +extern OSStatus SecPolicySetValue(SecPolicyRef policyRef, + const CSSM_DATA *value); +# endif /* HAVE_SECPOLICYPRIV_H */ +# ifdef HAVE_SECBASEPRIV_H +# include +# else /* Declare prototype for function in that header... */ +extern const char *cssmErrorString(int error); +# endif /* HAVE_SECBASEPRIV_H */ +#endif /* HAVE_CDSASSL */ + +#ifdef HAVE_GNUTLS +# include +#endif /* HAVE_GNUTLS */ + +#ifdef HAVE_TCPD_H +# include +#endif /* HAVE_TCPD_H */ + + +/* + * Local functions... + */ + +static int check_if_modified(cupsd_client_t *con, + struct stat *filestats); +static int compare_clients(cupsd_client_t *a, cupsd_client_t *b, + void *data); +static int data_ready(cupsd_client_t *con); +#ifdef HAVE_SSL +static int encrypt_client(cupsd_client_t *con); +#endif /* HAVE_SSL */ +#ifdef HAVE_CDSASSL +static CFArrayRef get_cdsa_certificate(cupsd_client_t *con); +#endif /* HAVE_CDSASSL */ +static char *get_file(cupsd_client_t *con, struct stat *filestats, + char *filename, int len); +static http_status_t install_conf_file(cupsd_client_t *con); +static int is_cgi(cupsd_client_t *con, const char *filename, + struct stat *filestats, mime_type_t *type); +static int is_path_absolute(const char *path); +#ifdef HAVE_SSL +static int make_certificate(cupsd_client_t *con); +#endif /* HAVE_SSL */ +static int pipe_command(cupsd_client_t *con, int infile, int *outfile, + char *command, char *options, int root); +static int valid_host(cupsd_client_t *con); +static int write_file(cupsd_client_t *con, http_status_t code, + char *filename, char *type, + struct stat *filestats); +static void write_pipe(cupsd_client_t *con); + + +/* + * 'cupsdAcceptClient()' - Accept a new client. + */ + +void +cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ +{ + int count; /* Count of connections on a host */ + int val; /* Parameter value */ + cupsd_client_t *con, /* New client pointer */ + *tempcon; /* Temporary client pointer */ + http_addrlist_t *addrlist, /* List of adddresses for host */ + *addr; /* Current address */ + socklen_t addrlen; /* Length of address */ + char *hostname; /* Hostname for address */ + http_addr_t temp; /* Temporary address variable */ + static time_t last_dos = 0; /* Time of last DoS attack */ +#ifdef HAVE_TCPD_H + struct request_info wrap_req; /* TCP wrappers request information */ +#endif /* HAVE_TCPD_H */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAcceptClient(lis=%p(%d)) Clients=%d", + lis, lis->fd, cupsArrayCount(Clients)); + + /* + * Make sure we don't have a full set of clients already... + */ + + if (cupsArrayCount(Clients) == MaxClients) + return; + + /* + * Get a pointer to the next available client... + */ + + if (!Clients) + Clients = cupsArrayNew(NULL, NULL); + + if (!Clients) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for clients array!"); + cupsdPauseListening(); + return; + } + + if (!ActiveClients) + ActiveClients = cupsArrayNew((cups_array_func_t)compare_clients, NULL); + + if (!ActiveClients) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for active clients array!"); + cupsdPauseListening(); + return; + } + + if ((con = calloc(1, sizeof(cupsd_client_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to allocate memory for client!"); + cupsdPauseListening(); + return; + } + + con->http.activity = time(NULL); + con->file = -1; + con->http.hostaddr = &(con->clientaddr); + + /* + * Accept the client and get the remote address... + */ + + addrlen = sizeof(http_addr_t); + + if ((con->http.fd = accept(lis->fd, (struct sockaddr *)con->http.hostaddr, + &addrlen)) < 0) + { + if (errno == ENFILE || errno == EMFILE) + cupsdPauseListening(); + + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to accept client connection - %s.", + strerror(errno)); + free(con); + + return; + } + +#ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + { + /* + * Save the connected port number... + */ + + con->http.hostaddr->ipv6.sin6_port = lis->address.ipv6.sin6_port; + + /* + * Convert IPv4 over IPv6 addresses (::ffff:n.n.n.n) to IPv4 forms we + * can more easily use... + */ + + if (con->http.hostaddr->ipv6.sin6_addr.s6_addr32[0] == 0 && + con->http.hostaddr->ipv6.sin6_addr.s6_addr32[1] == 0 && + ntohl(con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2]) == 0xffff) + con->http.hostaddr->ipv6.sin6_addr.s6_addr32[2] = 0; + } + else +#endif /* AF_INET6 */ + if (lis->address.addr.sa_family == AF_INET) + con->http.hostaddr->ipv4.sin_port = lis->address.ipv4.sin_port; + + /* + * Check the number of clients on the same address... + */ + + for (count = 0, tempcon = (cupsd_client_t *)cupsArrayFirst(Clients); + tempcon; + tempcon = (cupsd_client_t *)cupsArrayNext(Clients)) + if (httpAddrEqual(tempcon->http.hostaddr, con->http.hostaddr)) + { + count ++; + if (count >= MaxClientsPerHost) + break; + } + + if (count >= MaxClientsPerHost) + { + if ((time(NULL) - last_dos) >= 60) + { + last_dos = time(NULL); + cupsdLogMessage(CUPSD_LOG_WARN, + "Possible DoS attack - more than %d clients connecting " + "from %s!", + MaxClientsPerHost, + httpAddrString(con->http.hostaddr, con->http.hostname, + sizeof(con->http.hostname))); + } + +#ifdef WIN32 + closesocket(con->http.fd); +#else + close(con->http.fd); +#endif /* WIN32 */ + + free(con); + return; + } + + /* + * Get the hostname or format the IP address as needed... + */ + + if (httpAddrLocalhost(con->http.hostaddr)) + { + /* + * Map accesses from the loopback interface to "localhost"... + */ + + strlcpy(con->http.hostname, "localhost", sizeof(con->http.hostname)); + hostname = con->http.hostname; + } + else + { + /* + * Map accesses from the same host to the server name. + */ + + if (HostNameLookups) + hostname = httpAddrLookup(con->http.hostaddr, con->http.hostname, + sizeof(con->http.hostname)); + else + { + hostname = NULL; + httpAddrString(con->http.hostaddr, con->http.hostname, + sizeof(con->http.hostname)); + } + } + + if (hostname == NULL && 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 */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "Name lookup failed - connection from %s closed!", + con->http.hostname); + + free(con); + return; + } + + if (HostNameLookups == 2) + { + /* + * Do double lookups as needed... + */ + + if ((addrlist = httpAddrGetList(con->http.hostname, AF_UNSPEC, NULL)) + != NULL) + { + /* + * See if the hostname maps to the same IP address... + */ + + for (addr = addrlist; addr; addr = addr->next) + if (httpAddrEqual(con->http.hostaddr, &(addr->addr))) + break; + } + else + addr = NULL; + + httpAddrFreeList(addrlist); + + if (!addr) + { + /* + * 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 */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "IP lookup failed - connection from %s closed!", + con->http.hostname); + free(con); + return; + } + } + +#ifdef HAVE_TCPD_H + /* + * See if the connection is denied by TCP wrappers... + */ + + request_init(&wrap_req, RQ_DAEMON, "cupsd", RQ_FILE, con->http.fd, NULL); + fromhost(&wrap_req); + + if (!hosts_access(&wrap_req)) + { +#ifdef WIN32 + closesocket(con->http.fd); +#else + close(con->http.fd); +#endif /* WIN32 */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "Connection from %s refused by /etc/hosts.allow and " + "/etc/hosts.deny rules.", con->http.hostname); + free(con); + return; + } +#endif /* HAVE_TCPD_H */ + +#ifdef AF_INET6 + if (con->http.hostaddr->addr.sa_family == AF_INET6) + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv6)", + con->http.fd, con->http.hostname, + ntohs(con->http.hostaddr->ipv6.sin6_port)); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (con->http.hostaddr->addr.sa_family == AF_LOCAL) + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s (Domain)", + con->http.fd, con->http.hostname); + else +#endif /* AF_LOCAL */ + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAcceptClient: %d from %s:%d (IPv4)", + con->http.fd, con->http.hostname, + ntohs(con->http.hostaddr->ipv4.sin_port)); + + /* + * Get the local address the client connected to... + */ + + addrlen = sizeof(temp); + if (getsockname(con->http.fd, (struct sockaddr *)&temp, &addrlen)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get local address - %s", + strerror(errno)); + + strcpy(con->servername, "localhost"); + con->serverport = LocalPort; + } + else + { +#ifdef AF_INET6 + if (temp.addr.sa_family == AF_INET6) + { + if (httpAddrLocalhost(&temp)) + strlcpy(con->servername, "localhost", sizeof(con->servername)); + else if (HostNameLookups || RemotePort) + httpAddrLookup(&temp, con->servername, sizeof(con->servername)); + else + httpAddrString(&temp, con->servername, sizeof(con->servername)); + + con->serverport = ntohs(lis->address.ipv6.sin6_port); + } + else +#endif /* AF_INET6 */ + if (temp.addr.sa_family == AF_INET) + { + if (httpAddrLocalhost(&temp)) + strlcpy(con->servername, "localhost", sizeof(con->servername)); + else if (HostNameLookups || RemotePort) + httpAddrLookup(&temp, con->servername, sizeof(con->servername)); + else + httpAddrString(&temp, con->servername, sizeof(con->servername)); + + con->serverport = ntohs(lis->address.ipv4.sin_port); + } + else + { + strcpy(con->servername, "localhost"); + con->serverport = LocalPort; + } + } + + cupsArrayAdd(Clients, con); + + /* + * 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)); + + /* + * Close this file on all execs... + */ + + fcntl(con->http.fd, F_SETFD, fcntl(con->http.fd, F_GETFD) | FD_CLOEXEC); + + /* + * Add the socket to the server select. + */ + + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con); + + /* + * Temporarily suspend accept()'s until we lose a client... + */ + + if (cupsArrayCount(Clients) == MaxClients) + cupsdPauseListening(); + +#ifdef HAVE_SSL + /* + * 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; + + if (!encrypt_client(con)) + cupsdCloseClient(con); + } + else + con->auto_ssl = 1; +#endif /* HAVE_SSL */ +} + + +/* + * 'cupsdCloseAllClients()' - Close all remote clients immediately. + */ + +void +cupsdCloseAllClients(void) +{ + cupsd_client_t *con; /* Current client */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCloseAllClients() Clients=%d", + cupsArrayCount(Clients)); + + for (con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + con = (cupsd_client_t *)cupsArrayNext(Clients)) + if (cupsdCloseClient(con)) + cupsdCloseClient(con); +} + + +/* + * 'cupsdCloseClient()' - Close a remote client. + */ + +int /* O - 1 if partial close, 0 if fully closed */ +cupsdCloseClient(cupsd_client_t *con) /* I - Client to close */ +{ + int partial; /* Do partial close for SSL? */ +#ifdef HAVE_LIBSSL + SSL_CTX *context; /* Context for encryption */ + SSL *conn; /* Connection for encryption */ + unsigned long error; /* Error code */ +#elif defined(HAVE_GNUTLS) + http_tls_t *conn; /* TLS connection information */ + int error; /* Error code */ + gnutls_certificate_server_credentials *credentials; + /* TLS credentials */ +# elif defined(HAVE_CDSASSL) + http_tls_t *conn; /* CDSA connection information */ +#endif /* HAVE_LIBSSL */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdCloseClient: %d", con->http.fd); + + /* + * Flush pending writes before closing... + */ + + httpFlushWrite(HTTP(con)); + + partial = 0; + +#ifdef HAVE_SSL + /* + * Shutdown encryption as needed... + */ + + if (con->http.tls) + { + partial = 1; + +# ifdef HAVE_LIBSSL + conn = (SSL *)(con->http.tls); + context = SSL_get_SSL_CTX(conn); + + switch (SSL_shutdown(conn)) + { + case 1 : + cupsdLogMessage(CUPSD_LOG_DEBUG, + "SSL shutdown successful!"); + break; + case -1 : + cupsdLogMessage(CUPSD_LOG_ERROR, + "Fatal error during SSL shutdown!"); + default : + while ((error = ERR_get_error()) != 0) + cupsdLogMessage(CUPSD_LOG_ERROR, "SSL shutdown failed: %s", + ERR_error_string(error, NULL)); + break; + } + + SSL_CTX_free(context); + SSL_free(conn); + +# elif defined(HAVE_GNUTLS) + conn = (http_tls_t *)(con->http.tls); + credentials = (gnutls_certificate_server_credentials *)(conn->credentials); + + error = gnutls_bye(conn->session, GNUTLS_SHUT_WR); + switch (error) + { + case GNUTLS_E_SUCCESS: + cupsdLogMessage(CUPSD_LOG_DEBUG, + "SSL shutdown successful!"); + break; + default: + cupsdLogMessage(CUPSD_LOG_ERROR, + "SSL shutdown failed: %s", gnutls_strerror(error)); + break; + } + + gnutls_deinit(conn->session); + gnutls_certificate_free_credentials(*credentials); + free(credentials); + free(conn); + +# elif defined(HAVE_CDSASSL) + conn = (http_tls_t *)(con->http.tls); + + while (SSLClose(conn->session) == errSSLWouldBlock) + usleep(1000); + + SSLDisposeContext(conn->session); + + if (conn->certsArray) + CFRelease(conn->certsArray); + + free(conn); +# endif /* HAVE_LIBSSL */ + + con->http.tls = NULL; + } +#endif /* HAVE_SSL */ + + if (con->pipe_pid != 0) + { + /* + * Stop any CGI process... + */ + + cupsdEndProcess(con->pipe_pid, 1); + con->pipe_pid = 0; + } + + if (con->file >= 0) + { + cupsdRemoveSelect(con->file); + + close(con->file); + con->file = -1; + } + + /* + * Close the socket and clear the file from the input set for select()... + */ + + if (con->http.fd >= 0) + { + cupsArrayRemove(ActiveClients, con); + cupsdSetBusyState(); + + if (partial) + { + /* + * Only do a partial close so that the encrypted client gets everything. + */ + + shutdown(con->http.fd, 0); + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con); + } + else + { + /* + * Shut the socket down fully... + */ + + cupsdRemoveSelect(con->http.fd); + close(con->http.fd); + con->http.fd = -1; + } + } + + if (!partial) + { + /* + * Free memory... + */ + + if (con->http.input_set) + free(con->http.input_set); + + httpClearCookie(HTTP(con)); + httpClearFields(HTTP(con)); + + cupsdClearString(&con->filename); + cupsdClearString(&con->command); + cupsdClearString(&con->options); + cupsdClearString(&con->query_string); + + 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; + } + +#ifdef HAVE_AUTHORIZATION_H + if (con->authref) + { + AuthorizationFree(con->authref, kAuthorizationFlagDefaults); + con->authref = NULL; + } +#endif /* HAVE_AUTHORIZATION_H */ + + /* + * Re-enable new client connections if we are going back under the + * limit... + */ + + if (cupsArrayCount(Clients) == MaxClients) + cupsdResumeListening(); + + /* + * Compact the list of clients as necessary... + */ + + cupsArrayRemove(Clients, con); + + free(con); + } + + return (partial); +} + + +/* + * 'cupsdFlushHeader()' - Flush the header fields to the client. + */ + +int /* I - Bytes written or -1 on error */ +cupsdFlushHeader(cupsd_client_t *con) /* I - Client to flush to */ +{ + int bytes = httpFlushWrite(HTTP(con)); + + con->http.data_encoding = HTTP_ENCODE_LENGTH; + + return (bytes); +} + + +/* + * 'cupsdReadClient()' - Read data from a client. + */ + +void +cupsdReadClient(cupsd_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 */ + locale[64], /* Locale */ + *ptr; /* Pointer into strings */ + 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 */ + char buf[1024]; /* Buffer for real filename */ + struct stat filestats; /* File information */ + mime_type_t *type; /* MIME type of file */ + cupsd_printer_t *p; /* Printer */ + static unsigned request_id = 0; /* Request ID for temp files */ + + + status = HTTP_CONTINUE; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadClient(con=%p(%d)) " + "con->http.error=%d " + "con->http.used=%d, " + "con->http.state=%d " + "con->data_encoding=HTTP_ENCODE_%s, " + "con->data_remaining=" CUPS_LLFMT ", " + "con->file=%d", + con, con->http.fd, con->http.error, con->http.used, + con->http.state, + con->http.data_encoding == HTTP_ENCODE_CHUNKED ? + "CHUNKED" : "LENGTH", + CUPS_LLCAST con->http.data_remaining, con->file); + +#ifdef HAVE_SSL + if (con->auto_ssl) + { + /* + * Automatically check for a SSL/TLS handshake... + */ + + con->auto_ssl = 0; + + if (recv(con->http.fd, buf, 1, MSG_PEEK) == 1 && + (!buf[0] || !strchr("DGHOPT", buf[0]))) + { + /* + * Encrypt this connection... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadClient: Saw first byte %02X, auto-negotiating " + "SSL/TLS session...", buf[0] & 255); + + if (!encrypt_client(con)) + cupsdCloseClient(con); + + return; + } + } +#endif /* HAVE_SSL */ + + switch (con->http.state) + { + case HTTP_WAITING : + /* + * See if we've received a request line... + */ + + if (httpGets(line, sizeof(line) - 1, HTTP(con)) == NULL) + { + if (con->http.error && con->http.error != EPIPE) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d WAITING Closing for error %d " + "(%s)", con->http.fd, con->http.error, + strerror(con->http.error)); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d WAITING Closing on EOF", + con->http.fd); + + cupsdCloseClient(con); + return; + } + + /* + * 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->http._data_remaining = 0; + con->operation = HTTP_WAITING; + con->bytes = 0; + con->file = -1; + con->file_ready = 0; + con->pipe_pid = 0; + con->username[0] = '\0'; + con->password[0] = '\0'; + con->uri[0] = '\0'; + + cupsdClearString(&con->command); + cupsdClearString(&con->options); + cupsdClearString(&con->query_string); + + 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; + } + +#ifdef HAVE_GSSAPI + con->have_gss = 0; + + if (con->gss_creds) + { + OM_uint32 minor_status; + gss_release_cred(&minor_status, &con->gss_creds); + } +#endif /* HAVE_GSSAPI */ + + /* + * Grab the request line... + */ + + switch (sscanf(line, "%63s%1023s%63s", operation, con->uri, version)) + { + case 1 : + if (line[0]) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad request line \"%s\" from %s!", line, + con->http.hostname); + cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + } + return; + case 2 : + con->http.version = HTTP_0_9; + break; + case 3 : + if (sscanf(version, "HTTP/%d.%d", &major, &minor) != 2) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad request line \"%s\" from %s!", line, + con->http.hostname); + cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + + 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 + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unsupported request line \"%s\" from %s!", + line, con->http.hostname); + cupsdSendError(con, HTTP_NOT_SUPPORTED, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + break; + } + + /* + * Handle full URLs in the request line... + */ + + if (strcmp(con->uri, "*")) + { + char scheme[HTTP_MAX_URI], /* Method/scheme */ + userpass[HTTP_MAX_URI], /* Username:password */ + hostname[HTTP_MAX_URI], /* Hostname */ + resource[HTTP_MAX_URI]; /* Resource path */ + int port; /* Port number */ + + + /* + * Separate the URI into its components... + */ + + httpSeparateURI(HTTP_URI_CODING_MOST, con->uri, + scheme, sizeof(scheme), + userpass, sizeof(userpass), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + /* + * Only allow URIs with the servername, localhost, or an IP + * address... + */ + + if (strcmp(scheme, "file") && + strcasecmp(hostname, ServerName) && + strcasecmp(hostname, "localhost") && + !isdigit(hostname[0]) && hostname[0] != '[') + { + /* + * Nope, we don't do proxies... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad URI \"%s\" in request!", + con->uri); + cupsdSendError(con, HTTP_METHOD_NOT_ALLOWED, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + + /* + * Copy the resource portion back into the URI; both resource and + * con->uri are HTTP_MAX_URI bytes in size... + */ + + strcpy(con->uri, resource); + } + + /* + * Process the request... + */ + + if (!strcmp(operation, "GET")) + con->http.state = HTTP_GET; + else if (!strcmp(operation, "PUT")) + con->http.state = HTTP_PUT; + else if (!strcmp(operation, "POST")) + con->http.state = HTTP_POST; + else if (!strcmp(operation, "DELETE")) + con->http.state = HTTP_DELETE; + else if (!strcmp(operation, "TRACE")) + con->http.state = HTTP_TRACE; + else if (!strcmp(operation, "OPTIONS")) + con->http.state = HTTP_OPTIONS; + else if (!strcmp(operation, "HEAD")) + con->http.state = HTTP_HEAD; + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad operation \"%s\"!", operation); + cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + + gettimeofday(&(con->start), NULL); + con->operation = con->http.state; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %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; + + if (!cupsArrayFind(ActiveClients, con)) + { + cupsArrayAdd(ActiveClients, con); + cupsdSetBusyState(); + } + + 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... + */ + + while ((status = httpUpdate(HTTP(con))) == HTTP_CONTINUE) + if (!data_ready(con)) + break; + + if (status != HTTP_OK && status != HTTP_CONTINUE) + { + if (con->http.error && con->http.error != EPIPE) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d FIELDS Closing for error %d " + "(%s)", con->http.fd, con->http.error, + strerror(con->http.error)); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d FIELDS Closing on EOF", + con->http.fd); + + cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + break; + + default : + if (!data_ready(con) && recv(con->http.fd, buf, 1, MSG_PEEK) < 1) + { + /* + * Connection closed... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d Closing on EOF", con->http.fd); + cupsdCloseClient(con); + return; + } + break; /* Anti-compiler-warning-code */ + } + + /* + * Handle new transfers... + */ + + if (status == HTTP_OK) + { + if (con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE][0]) + { + /* + * Figure out the locale from the Accept-Language and Content-Type + * fields... + */ + + if ((ptr = strchr(con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE], + ',')) != NULL) + *ptr = '\0'; + + if ((ptr = strchr(con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE], + ';')) != NULL) + *ptr = '\0'; + + if ((ptr = strstr(con->http.fields[HTTP_FIELD_CONTENT_TYPE], + "charset=")) != NULL) + { + /* + * Combine language and charset, and trim any extra params in the + * content-type. + */ + + snprintf(locale, sizeof(locale), "%s.%s", + con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE], ptr + 8); + + if ((ptr = strchr(locale, ',')) != NULL) + *ptr = '\0'; + } + else + snprintf(locale, sizeof(locale), "%s.UTF-8", + con->http.fields[HTTP_FIELD_ACCEPT_LANGUAGE]); + + con->language = cupsLangGet(locale); + } + else + con->language = cupsLangGet(DefaultLocale); + + cupsdAuthorize(con); + + if (!strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Keep-Alive", + 10) && KeepAlive) + con->http.keep_alive = HTTP_KEEPALIVE_ON; + else if (!strncasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "close", 5)) + con->http.keep_alive = HTTP_KEEPALIVE_OFF; + + if (!con->http.fields[HTTP_FIELD_HOST][0] && + con->http.version >= HTTP_1_1) + { + /* + * HTTP/1.1 and higher require the "Host:" field... + */ + + if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Missing Host: field in request!"); + cupsdCloseClient(con); + return; + } + } + else if (!valid_host(con)) + { + /* + * Access to localhost must use "localhost" or the corresponding IPv4 + * or IPv6 values in the Host: field. + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Request from \"%s\" using invalid Host: field \"%s\"", + con->http.hostname, con->http.fields[HTTP_FIELD_HOST]); + + if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else if (con->operation == HTTP_OPTIONS) + { + /* + * Do OPTIONS command... + */ + + if (con->best && con->best->type != CUPSD_AUTH_NONE) + { + if (!cupsdSendHeader(con, HTTP_UNAUTHORIZED, NULL, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + + if (!strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") && + con->http.tls == NULL) + { +#ifdef HAVE_SSL + /* + * Do encryption stuff... + */ + + if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + 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"); + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + + if (!encrypt_client(con)) + { + cupsdCloseClient(con); + return; + } +#else + if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } +#endif /* HAVE_SSL */ + } + + if (!cupsdSendHeader(con, HTTP_OK, NULL, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + httpPrintf(HTTP(con), "Allow: GET, HEAD, OPTIONS, POST, PUT\r\n"); + httpPrintf(HTTP(con), "Content-Length: 0\r\n"); + httpPrintf(HTTP(con), "\r\n"); + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + } + else if (!is_path_absolute(con->uri)) + { + /* + * Protect against malicious users! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Request for non-absolute resource \"%s\"!", con->uri); + + if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else + { + if (!strcasecmp(con->http.fields[HTTP_FIELD_CONNECTION], "Upgrade") && + con->http.tls == NULL) + { +#ifdef HAVE_SSL + /* + * Do encryption stuff... + */ + + if (!cupsdSendHeader(con, HTTP_SWITCHING_PROTOCOLS, NULL, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + 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"); + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + + if (!encrypt_client(con)) + { + cupsdCloseClient(con); + return; + } +#else + if (!cupsdSendError(con, HTTP_NOT_IMPLEMENTED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } +#endif /* HAVE_SSL */ + } + + if ((status = cupsdIsAuthorized(con, NULL)) != HTTP_OK) + { + cupsdSendError(con, status, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + + if (con->http.expect && + (con->operation == HTTP_POST || con->operation == HTTP_PUT)) + { + if (con->http.expect == HTTP_CONTINUE) + { + /* + * Send 100-continue header... + */ + + if (!cupsdSendHeader(con, HTTP_CONTINUE, NULL, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else + { + /* + * Send 417-expectation-failed header... + */ + + if (!cupsdSendHeader(con, HTTP_EXPECTATION_FAILED, NULL, + CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + httpPrintf(HTTP(con), "Content-Length: 0\r\n"); + httpPrintf(HTTP(con), "\r\n"); + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + } + } + + switch (con->http.state) + { + case HTTP_GET_SEND : + if (!strncmp(con->uri, "/printers/", 10) && + !strcmp(con->uri + strlen(con->uri) - 4, ".ppd")) + { + /* + * 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 = cupsdFindPrinter(con->uri + 10)) != NULL) + snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name); + else + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + } + else if ((!strncmp(con->uri, "/printers/", 10) || + !strncmp(con->uri, "/classes/", 9)) && + !strcmp(con->uri + strlen(con->uri) - 4, ".png")) + { + /* + * Send icon file - get the real queue name since queue names are + * not case sensitive but filenames can be... + */ + + con->uri[strlen(con->uri) - 4] = '\0'; /* Drop ".png" */ + + if (!strncmp(con->uri, "/printers/", 10)) + p = cupsdFindPrinter(con->uri + 10); + else + p = cupsdFindClass(con->uri + 9); + + if (p) + snprintf(con->uri, sizeof(con->uri), "/icons/%s.png", p->name); + else + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + } + + if ((!strncmp(con->uri, "/admin", 6) && + strncmp(con->uri, "/admin/conf/", 12) && + strncmp(con->uri, "/admin/log/", 11)) || + !strncmp(con->uri, "/printers", 9) || + !strncmp(con->uri, "/classes", 8) || + !strncmp(con->uri, "/help", 5) || + !strncmp(con->uri, "/jobs", 5)) + { + /* + * Send CGI output... + */ + + if (!strncmp(con->uri, "/admin", 6)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", + ServerBin); + + cupsdSetString(&con->options, strchr(con->uri + 6, '?')); + } + else if (!strncmp(con->uri, "/printers", 9)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", + ServerBin); + + if (con->uri[9] && con->uri[10]) + cupsdSetString(&con->options, con->uri + 9); + else + cupsdSetString(&con->options, NULL); + } + else if (!strncmp(con->uri, "/classes", 8)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", + ServerBin); + + if (con->uri[8] && con->uri[9]) + cupsdSetString(&con->options, con->uri + 8); + else + cupsdSetString(&con->options, NULL); + } + else if (!strncmp(con->uri, "/jobs", 5)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", + ServerBin); + + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); + } + else + { + cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", + ServerBin); + + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); + } + + if (!cupsdSendCommand(con, con->command, con->options, 0)) + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else + cupsdLogRequest(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) && + (strchr(con->uri + 12, '/') || + strlen(con->uri) == 12)) || + (!strncmp(con->uri, "/admin/log/", 11) && + (strchr(con->uri + 11, '/') || + strlen(con->uri) == 11))) + { + /* + * GET can only be done to configuration files directly under + * /admin/conf... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Request for subdirectory \"%s\"!", con->uri); + + if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + else + { + /* + * Serve a file... + */ + + if ((filename = get_file(con, &filestats, buf, + sizeof(buf))) == NULL) + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + + type = mimeFileType(MimeDatabase, filename, NULL, NULL); + + if (is_cgi(con, filename, &filestats, type)) + { + /* + * Note: con->command and con->options were set by + * is_cgi()... + */ + + if (!cupsdSendCommand(con, con->command, con->options, 0)) + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else + cupsdLogRequest(con, HTTP_OK); + + if (con->http.version <= HTTP_1_0) + con->http.keep_alive = HTTP_KEEPALIVE_OFF; + break; + } + + if (!check_if_modified(con, &filestats)) + { + if (!cupsdSendError(con, HTTP_NOT_MODIFIED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else + { + if (type == NULL) + strcpy(line, "text/plain"); + else + snprintf(line, sizeof(line), "%s/%s", type->super, type->type); + + if (!write_file(con, HTTP_OK, filename, line, &filestats)) + { + cupsdCloseClient(con); + return; + } + } + } + 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... + */ + + if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] && + MaxRequestSize > 0 && + con->http.data_remaining > MaxRequestSize) + { + /* + * Request too large... + */ + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + else if (con->http.data_remaining < 0 || + (!con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] && + con->http.data_encoding == HTTP_ENCODE_LENGTH)) + { + /* + * Negative content lengths are invalid! + */ + + if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + 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")) + con->request = ippNew(); + else if ((!strncmp(con->uri, "/admin", 6) && + strncmp(con->uri, "/admin/conf/", 12) && + strncmp(con->uri, "/admin/log/", 11)) || + !strncmp(con->uri, "/printers", 9) || + !strncmp(con->uri, "/classes", 8) || + !strncmp(con->uri, "/help", 5) || + !strncmp(con->uri, "/jobs", 5)) + { + /* + * CGI request... + */ + + if (!strncmp(con->uri, "/admin", 6)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/admin.cgi", + ServerBin); + + cupsdSetString(&con->options, strchr(con->uri + 6, '?')); + } + else if (!strncmp(con->uri, "/printers", 9)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/printers.cgi", + ServerBin); + + if (con->uri[9] && con->uri[10]) + cupsdSetString(&con->options, con->uri + 9); + else + cupsdSetString(&con->options, NULL); + } + else if (!strncmp(con->uri, "/classes", 8)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/classes.cgi", + ServerBin); + + if (con->uri[8] && con->uri[9]) + cupsdSetString(&con->options, con->uri + 8); + else + cupsdSetString(&con->options, NULL); + } + else if (!strncmp(con->uri, "/jobs", 5)) + { + cupsdSetStringf(&con->command, "%s/cgi-bin/jobs.cgi", + ServerBin); + + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); + } + else + { + cupsdSetStringf(&con->command, "%s/cgi-bin/help.cgi", + ServerBin); + + if (con->uri[5] && con->uri[6]) + cupsdSetString(&con->options, con->uri + 5); + else + cupsdSetString(&con->options, NULL); + } + + if (con->http.version <= HTTP_1_0) + con->http.keep_alive = HTTP_KEEPALIVE_OFF; + } + else + { + /* + * POST to a file... + */ + + if ((filename = get_file(con, &filestats, buf, + sizeof(buf))) == NULL) + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + + type = mimeFileType(MimeDatabase, filename, NULL, NULL); + + if (!is_cgi(con, filename, &filestats, type)) + { + /* + * Only POST to CGI's... + */ + + if (!cupsdSendError(con, HTTP_UNAUTHORIZED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + } + break; + + case HTTP_PUT_RECV : + /* + * Validate the resource name... + */ + + if (strncmp(con->uri, "/admin/conf/", 12) || + strchr(con->uri + 12, '/') || + strlen(con->uri) == 12) + { + /* + * PUT can only be done to configuration files under + * /admin/conf... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Request for subdirectory \"%s\"!", con->uri); + + if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + + /* + * See if the PUT request includes a Content-Length field, and if + * so check the length against any limits that are set... + */ + + if (con->http.fields[HTTP_FIELD_CONTENT_LENGTH][0] && + MaxRequestSize > 0 && + con->http.data_remaining > MaxRequestSize) + { + /* + * Request too large... + */ + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + else if (con->http.data_remaining < 0) + { + /* + * Negative content lengths are invalid! + */ + + if (!cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + + /* + * Open a temporary file to hold the request... + */ + + cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, + request_id ++); + con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640); + + if (con->file < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create request file %s: %s", + con->filename, strerror(errno)); + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + + fchmod(con->file, 0640); + fchown(con->file, RunUser, Group); + fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); + break; + + case HTTP_DELETE : + case HTTP_TRACE : + cupsdSendError(con, HTTP_NOT_IMPLEMENTED, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + + case HTTP_HEAD : + if (!strncmp(con->uri, "/printers/", 10) && + !strcmp(con->uri + strlen(con->uri) - 4, ".ppd")) + { + /* + * 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 = cupsdFindPrinter(con->uri + 10)) != NULL) + snprintf(con->uri, sizeof(con->uri), "/ppd/%s.ppd", p->name); + else + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + } + + if ((!strncmp(con->uri, "/admin", 6) && + strncmp(con->uri, "/admin/conf/", 12) && + strncmp(con->uri, "/admin/log/", 11)) || + !strncmp(con->uri, "/printers", 9) || + !strncmp(con->uri, "/classes", 8) || + !strncmp(con->uri, "/help", 5) || + !strncmp(con->uri, "/jobs", 5)) + { + /* + * CGI output... + */ + + if (!cupsdSendHeader(con, HTTP_OK, "text/html", CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + if (httpPrintf(HTTP(con), "\r\n") < 0) + { + cupsdCloseClient(con); + return; + } + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + + cupsdLogRequest(con, HTTP_OK); + } + else if ((!strncmp(con->uri, "/admin/conf/", 12) && + (strchr(con->uri + 12, '/') || + strlen(con->uri) == 12)) || + (!strncmp(con->uri, "/admin/log/", 11) && + (strchr(con->uri + 11, '/') || + strlen(con->uri) == 11))) + { + /* + * HEAD can only be done to configuration files under + * /admin/conf... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Request for subdirectory \"%s\"!", con->uri); + + if (!cupsdSendError(con, HTTP_FORBIDDEN, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + break; + } + else if ((filename = get_file(con, &filestats, buf, + sizeof(buf))) == NULL) + { + if (!cupsdSendHeader(con, HTTP_NOT_FOUND, "text/html", + CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + cupsdLogRequest(con, HTTP_NOT_FOUND); + } + else if (!check_if_modified(con, &filestats)) + { + if (!cupsdSendError(con, HTTP_NOT_MODIFIED, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + cupsdLogRequest(con, HTTP_NOT_MODIFIED); + } + else + { + /* + * Serve a file... + */ + + type = mimeFileType(MimeDatabase, filename, NULL, NULL); + if (type == NULL) + strcpy(line, "text/plain"); + else + snprintf(line, sizeof(line), "%s/%s", type->super, type->type); + + if (!cupsdSendHeader(con, HTTP_OK, line, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + + if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n", + httpGetDateString(filestats.st_mtime)) < 0) + { + cupsdCloseClient(con); + return; + } + + if (httpPrintf(HTTP(con), "Content-Length: %lu\r\n", + (unsigned long)filestats.st_size) < 0) + { + cupsdCloseClient(con); + return; + } + + cupsdLogRequest(con, HTTP_OK); + } + + if (httpPrintf(HTTP(con), "\r\n") < 0) + { + cupsdCloseClient(con); + return; + } + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + + con->http.state = HTTP_WAITING; + break; + + default : + break; /* Anti-compiler-warning-code */ + } + } + } + + /* + * Handle any incoming data... + */ + + switch (con->http.state) + { + case HTTP_PUT_RECV : + do + { + if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0) + { + if (con->http.error && con->http.error != EPIPE) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d PUT_RECV Closing for error " + "%d (%s)", con->http.fd, con->http.error, + strerror(con->http.error)); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d PUT_RECV Closing on EOF", + con->http.fd); + + cupsdCloseClient(con); + return; + } + else if (bytes > 0) + { + con->bytes += bytes; + + if (write(con->file, line, bytes) < bytes) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdReadClient: Unable to write %d bytes to %s: %s", + bytes, con->filename, strerror(errno)); + + close(con->file); + con->file = -1; + unlink(con->filename); + cupsdClearString(&con->filename); + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + } + } + while (con->http.state == HTTP_PUT_RECV && data_ready(con)); + + if (con->http.state == HTTP_WAITING) + { + /* + * End of file, see how big it is... + */ + + fstat(con->file, &filestats); + + close(con->file); + con->file = -1; + + if (filestats.st_size > MaxRequestSize && + MaxRequestSize > 0) + { + /* + * Request is too big; remove it and send an error... + */ + + unlink(con->filename); + cupsdClearString(&con->filename); + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + + /* + * Install the configuration file... + */ + + status = install_conf_file(con); + + /* + * Return the status to the client... + */ + + if (!cupsdSendError(con, status, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + break; + + case HTTP_POST_RECV : + do + { + if (con->request && con->file < 0) + { + /* + * Grab any request data from the connection... + */ + + if ((ipp_state = ippRead(&(con->http), con->request)) == IPP_ERROR) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdReadClient: %d IPP Read Error!", + con->http.fd); + + cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + else if (ipp_state != IPP_DATA) + { + if (con->http.state == HTTP_POST_SEND) + { + cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE); + cupsdCloseClient(con); + return; + } + + break; + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdReadClient: %d %d.%d %s %d", + con->http.fd, con->request->request.op.version[0], + con->request->request.op.version[1], + ippOpString(con->request->request.op.operation_id), + con->request->request.op.request_id); + con->bytes += ippLength(con->request); + } + } + + if (con->file < 0 && con->http.state != HTTP_POST_SEND) + { + /* + * Create a file as needed for the request data... + */ + + cupsdSetStringf(&con->filename, "%s/%08x", RequestRoot, + request_id ++); + con->file = open(con->filename, O_WRONLY | O_CREAT | O_TRUNC, 0640); + + if (con->file < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create request file %s: %s", + con->filename, strerror(errno)); + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + + fchmod(con->file, 0640); + fchown(con->file, RunUser, Group); + fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); + } + + if (con->http.state != HTTP_POST_SEND) + { + if ((bytes = httpRead2(HTTP(con), line, sizeof(line))) < 0) + { + if (con->http.error && con->http.error != EPIPE) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d POST_SEND Closing for " + "error %d (%s)", con->http.fd, con->http.error, + strerror(con->http.error)); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d POST_SEND Closing on EOF", + con->http.fd); + + cupsdCloseClient(con); + return; + } + else if (bytes > 0) + { + con->bytes += bytes; + + if (write(con->file, line, bytes) < bytes) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdReadClient: Unable to write %d bytes to " + "%s: %s", bytes, con->filename, + strerror(errno)); + + close(con->file); + con->file = -1; + unlink(con->filename); + cupsdClearString(&con->filename); + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, + CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + } + else if (con->http.state == HTTP_POST_RECV) + return; + else if (con->http.state != HTTP_POST_SEND) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d Closing on unknown HTTP " + "state %d", con->http.fd, con->http.state); + cupsdCloseClient(con); + return; + } + } + } + while (con->http.state == HTTP_POST_RECV && data_ready(con)); + + if (con->http.state == HTTP_POST_SEND) + { + if (con->file >= 0) + { + fstat(con->file, &filestats); + + close(con->file); + con->file = -1; + + if (filestats.st_size > MaxRequestSize && + MaxRequestSize > 0) + { + /* + * Request is too big; remove it and send an error... + */ + + unlink(con->filename); + cupsdClearString(&con->filename); + + if (con->request) + { + /* + * Delete any IPP request data... + */ + + ippDelete(con->request); + con->request = NULL; + } + + if (!cupsdSendError(con, HTTP_REQUEST_TOO_LARGE, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else if (filestats.st_size == 0) + { + /* + * Don't allow empty file... + */ + + unlink(con->filename); + cupsdClearString(&con->filename); + } + + if (con->command) + { + if (!cupsdSendCommand(con, con->command, con->options, 0)) + { + if (!cupsdSendError(con, HTTP_NOT_FOUND, CUPSD_AUTH_NONE)) + { + cupsdCloseClient(con); + return; + } + } + else + cupsdLogRequest(con, HTTP_OK); + } + } + + if (con->request) + { + cupsdProcessIPPRequest(con); + + if (con->filename) + { + unlink(con->filename); + cupsdClearString(&con->filename); + } + + return; + } + } + break; + + default : + break; /* Anti-compiler-warning-code */ + } + + if (con->http.state == HTTP_WAITING) + { + if (!con->http.keep_alive) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdReadClient: %d Closing because Keep-Alive disabled", + con->http.fd); + cupsdCloseClient(con); + } + else + { + cupsArrayRemove(ActiveClients, con); + cupsdSetBusyState(); + } + } +} + + +/* + * 'cupsdSendCommand()' - Send output from a command via HTTP. + */ + +int /* O - 1 on success, 0 on failure */ +cupsdSendCommand( + cupsd_client_t *con, /* I - Client connection */ + char *command, /* I - Command to run */ + char *options, /* I - Command-line options */ + int root) /* I - Run as root? */ +{ + int fd; /* Standard input file descriptor */ + + + if (con->filename) + { + fd = open(con->filename, O_RDONLY); + + if (fd < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdSendCommand: %d Unable to open \"%s\" for reading: %s", + con->http.fd, con->filename ? con->filename : "/dev/null", + strerror(errno)); + return (0); + } + + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + } + else + fd = -1; + + con->pipe_pid = pipe_command(con, fd, &(con->file), command, options, root); + + if (fd >= 0) + close(fd); + + cupsdLogMessage(CUPSD_LOG_INFO, "Started \"%s\" (pid=%d)", command, + con->pipe_pid); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSendCommand: %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); + + cupsdAddSelect(con->file, (cupsd_selfunc_t)write_pipe, NULL, con); + + con->sent_header = 0; + con->file_ready = 0; + con->got_fields = 0; + con->header_used = 0; + + return (1); +} + + +/* + * 'cupsdSendError()' - Send an error message via HTTP. + */ + +int /* O - 1 if successful, 0 otherwise */ +cupsdSendError(cupsd_client_t *con, /* I - Connection */ + http_status_t code, /* I - Error code */ + int auth_type)/* I - Authentication type */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSendError(con=%p(%d), code=%d, auth_type=%d", con, + con->http.fd, code, auth_type); + +#ifdef HAVE_SSL + /* + * Force client to upgrade for authentication if that is how the + * server is configured... + */ + + if (code == HTTP_UNAUTHORIZED && + DefaultEncryption == HTTP_ENCRYPT_REQUIRED && + strcasecmp(con->http.hostname, "localhost") && + !con->http.tls) + { + code = HTTP_UPGRADE_REQUIRED; + } +#endif /* HAVE_SSL */ + + /* + * Put the request in the access_log file... + */ + + cupsdLogRequest(con, code); + + /* + * To work around bugs in some proxies, don't use Keep-Alive for some + * error messages... + * + * Kerberos authentication doesn't work without Keep-Alive, so + * never disable it in that case. + */ + + if (code >= HTTP_BAD_REQUEST && con->http.auth_type != CUPSD_AUTH_NEGOTIATE) + 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 (!cupsdSendHeader(con, code, NULL, auth_type)) + return (0); + +#ifdef HAVE_SSL + 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_SSL */ + + if (con->http.version >= HTTP_1_1 && + con->http.keep_alive == HTTP_KEEPALIVE_OFF) + { + if (httpPrintf(HTTP(con), "Connection: close\r\n") < 0) + return (0); + } + + if (code >= HTTP_BAD_REQUEST) + { + /* + * Send a human-readable error message. + */ + + char message[4096], /* Message for user */ + urltext[1024], /* URL redirection text */ + redirect[1024]; /* Redirection link */ + const char *text; /* Status-specific text */ + + + redirect[0] = '\0'; + + if (code == HTTP_UNAUTHORIZED) + text = _cupsLangString(con->language, + _("Enter your username and password or the " + "root username and password to access this " + "page. If you are using Kerberos authentication, " + "make sure you have a valid Kerberos ticket.")); + else if (code == HTTP_UPGRADE_REQUIRED) + { + text = urltext; + + snprintf(urltext, sizeof(urltext), + _cupsLangString(con->language, + _("You must access this page using the URL " + "" + "https://%s:%d%s.")), + con->servername, con->serverport, con->uri, + con->servername, con->serverport, con->uri); + + snprintf(redirect, sizeof(redirect), + "\n", + con->servername, con->serverport, con->uri); + } + else + text = ""; + + snprintf(message, sizeof(message), + "\n" + "\n" + "\n" + "\t\n" + "\t%d %s\n" + "\t\n" + "%s" + "\n" + "\n" + "

%d %s

\n" + "

%s

\n" + "\n" + "\n", + code, httpStatus(code), redirect, code, httpStatus(code), text); + + if (httpPrintf(HTTP(con), "Content-Type: text/html; charset=utf-8\r\n") < 0) + return (0); + if (httpPrintf(HTTP(con), "Content-Length: %d\r\n", + (int)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); + + if (cupsdFlushHeader(con) < 0) + return (0); + + con->http.state = HTTP_WAITING; + + return (1); +} + + +/* + * 'cupsdSendHeader()' - Send an HTTP request. + */ + +int /* O - 1 on success, 0 on failure */ +cupsdSendHeader( + cupsd_client_t *con, /* I - Client to send to */ + http_status_t code, /* I - HTTP status code */ + char *type, /* I - MIME type of document */ + int auth_type) /* I - Type of authentication */ +{ + char auth_str[1024]; /* Authorization string */ +#ifdef HAVE_GSSAPI + static char *gss_buf = NULL; /* Kerberos auth data buffer */ + static int gss_bufsize = 0; /* Size of Kerberos auth data buffer */ +#endif /* HAVE_GSSAPI */ + + + /* + * Send the HTTP status header... + */ + + if (code == HTTP_CONTINUE) + { + /* + * 100-continue doesn't send any headers... + */ + + return (httpPrintf(HTTP(con), "HTTP/%d.%d 100 Continue\r\n\r\n", + con->http.version / 100, con->http.version % 100) > 0); + } + + httpFlushWrite(HTTP(con)); + + con->http.data_encoding = HTTP_ENCODE_FIELDS; + + 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 (ServerHeader) + if (httpPrintf(HTTP(con), "Server: %s\r\n", ServerHeader) < 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, PUT\r\n") < 0) + return (0); + + if (code == HTTP_UNAUTHORIZED) + { + if (auth_type == CUPSD_AUTH_NONE) + { + if (!con->best || con->best->type <= CUPSD_AUTH_NONE) + auth_type = DefaultAuthType; + else + auth_type = con->best->type; + } + + auth_str[0] = '\0'; + + if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST) + strlcpy(auth_str, "Basic realm=\"CUPS\"", sizeof(auth_str)); + else if (auth_type == CUPSD_AUTH_DIGEST) + snprintf(auth_str, sizeof(auth_str), "Digest realm=\"CUPS\", nonce=\"%s\"", + con->http.hostname); +#ifdef HAVE_GSSAPI + else if (auth_type == CUPSD_AUTH_NEGOTIATE && con->gss_output_token.length == 0) + strlcpy(auth_str, "Negotiate", sizeof(auth_str)); +#endif /* HAVE_GSSAPI */ + + if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE && + !strcasecmp(con->http.hostname, "localhost")) + { + /* + * Add a "trc" (try root certification) parameter for local non-Kerberos + * requests when the request requires system group membership - then the + * client knows the root certificate can/should be used. + * + * Also, for Mac OS X we also look for @AUTHKEY and add an "authkey" + * parameter as needed... + */ + + int i; /* Looping var */ + char *auth_key; /* Auth key buffer */ + size_t auth_size; /* Size of remaining buffer */ + + auth_key = auth_str + strlen(auth_str); + auth_size = sizeof(auth_str) - (auth_key - auth_str); + + for (i = 0; i < con->best->num_names; i ++) + { +#ifdef HAVE_AUTHORIZATION_H + if (!strncasecmp(con->best->names[i], "@AUTHKEY(", 9)) + { + snprintf(auth_key, auth_size, ", authkey=\"%s\"", + con->best->names[i] + 9); + /* end parenthesis is stripped in conf.c */ + break; + } + else +#endif /* HAVE_AUTHORIZATION_H */ + if (!strcasecmp(con->best->names[i], "@SYSTEM")) + { +#ifdef HAVE_AUTHORIZATION_H + if (SystemGroupAuthKey) + snprintf(auth_key, auth_size, + ", authkey=\"%s\", trc=\"y\"", + SystemGroupAuthKey); + else +#else + strlcpy(auth_key, ", trc=\"y\"", auth_size); +#endif /* HAVE_AUTHORIZATION_H */ + break; + } + } + } + + if (auth_str[0]) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdSendHeader: %d WWW-Authenticate: %s", con->http.fd, + auth_str); + + if (httpPrintf(HTTP(con), "WWW-Authenticate: %s\r\n", auth_str) < 0) + return (0); + } + } + +#ifdef HAVE_GSSAPI + /* + * WWW-Authenticate: Negotiate can be included even for + * non-401 replies... + */ + + if (con->gss_output_token.length > 0 && con->gss_output_token.length <= 65536) + { + OM_uint32 minor_status; /* Minor status code */ + int bufsize; /* Size of output token buffer */ + + + bufsize = con->gss_output_token.length * 4 / 3 + 2; + + if (bufsize > gss_bufsize) + { + char *buf; /* New buffer */ + + + bufsize = (bufsize + 1023) & 1023;/* Round up */ + + if (gss_buf) + buf = realloc(gss_buf, bufsize); + else + buf = malloc(bufsize); + + if (!buf) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate %d bytes for Kerberos credentials!", + bufsize); + return (0); + } + + gss_buf = buf; + gss_bufsize = bufsize; + } + + httpEncode64_2(gss_buf, gss_bufsize, + con->gss_output_token.value, + con->gss_output_token.length); + gss_release_buffer(&minor_status, &con->gss_output_token); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdSendHeader: WWW-Authenticate: Negotiate %s", gss_buf); + + if (httpPrintf(HTTP(con), "WWW-Authenticate: Negotiate %s\r\n", + gss_buf) < 0) + return (0); + } + else if (con->gss_output_token.length > 65536) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Kerberos credentials larger than 64k (%d)!", + (int)con->gss_output_token.length); + return (0); + } +#endif /* HAVE_GSSAPI */ + + if (con->language && strcmp(con->language->language, "C")) + { + if (httpPrintf(HTTP(con), "Content-Language: %s\r\n", + con->language->language) < 0) + return (0); + } + + if (type) + { + if (!strcmp(type, "text/html")) + { + if (httpPrintf(HTTP(con), + "Content-Type: text/html; charset=utf-8\r\n") < 0) + return (0); + } + else if (httpPrintf(HTTP(con), "Content-Type: %s\r\n", type) < 0) + return (0); + } + + return (1); +} + + +/* + * 'cupsdUpdateCGI()' - Read status messages from CGI scripts and programs. + */ + +void +cupsdUpdateCGI(void) +{ + char *ptr, /* Pointer to end of line in buffer */ + message[1024]; /* Pointer to message text */ + int loglevel; /* Log level for message */ + + + while ((ptr = cupsdStatBufUpdate(CGIStatusBuffer, &loglevel, + message, sizeof(message))) != NULL) + { + if (loglevel == CUPSD_LOG_INFO) + cupsdLogMessage(CUPSD_LOG_INFO, "%s", message); + + if (!strchr(CGIStatusBuffer->buffer, '\n')) + break; + } + + if (ptr == NULL && !CGIStatusBuffer->bufused) + { + /* + * Fatal error on pipe - should never happen! + */ + + cupsdLogMessage(CUPSD_LOG_CRIT, + "cupsdUpdateCGI: error reading from CGI error pipe - %s", + strerror(errno)); + } +} + + +/* + * 'cupsdWriteClient()' - Write data to a client as needed. + */ + +void +cupsdWriteClient(cupsd_client_t *con) /* I - Client connection */ +{ + int bytes, /* Number of bytes written */ + field_col; /* Current column */ + char *bufptr, /* Pointer into buffer */ + *bufend; /* Pointer to end of buffer */ + ipp_state_t ipp_state; /* IPP state value */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdWriteClient(con=%p(%d)) response=%p(%d), file=%d " + "pipe_pid=%d state=%d", + con, con->http.fd, con->response, + con->response ? con->response->state : -1, + con->file, con->pipe_pid, con->http.state); + + if (con->http.state != HTTP_GET_SEND && + con->http.state != HTTP_POST_SEND) + { + /* + * If we get called in the wrong state, then something went wrong with the + * connection and we need to shut it down... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdWriteClient: %d Closing on unknown HTTP state %d", + con->http.fd, con->http.state); + cupsdCloseClient(con); + return; + } + + if (con->pipe_pid) + { + /* + * Make sure we select on the CGI output... + */ + + cupsdAddSelect(con->file, (cupsd_selfunc_t)write_pipe, NULL, con); + + if (!con->file_ready) + { + /* + * Try again later when there is CGI output available... + */ + + cupsdRemoveSelect(con->http.fd); + return; + } + + con->file_ready = 0; + } + + if (con->response && con->response->state != IPP_DATA) + { + ipp_state = ippWrite(HTTP(con), con->response); + bytes = ipp_state != IPP_ERROR && + (con->file >= 0 || ipp_state != IPP_DATA); + } + else if ((bytes = read(con->file, con->header, + sizeof(con->header) - con->header_used)) > 0) + { + con->header_used += bytes; + + if (con->pipe_pid && !con->got_fields) + { + /* + * Inspect the data for Content-Type and other fields. + */ + + for (bufptr = con->header, bufend = con->header + con->header_used, + field_col = 0; + !con->got_fields && bufptr < bufend; + bufptr ++) + { + if (*bufptr == '\n') + { + /* + * Send line to client... + */ + + if (bufptr > con->header && bufptr[-1] == '\r') + bufptr[-1] = '\0'; + *bufptr++ = '\0'; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Script header: %s", con->header); + + if (!con->sent_header) + { + /* + * Handle redirection and CGI status codes... + */ + + if (!strncasecmp(con->header, "Location:", 9)) + { + cupsdSendHeader(con, HTTP_SEE_OTHER, NULL, CUPSD_AUTH_NONE); + con->sent_header = 2; + + if (httpPrintf(HTTP(con), "Content-Length: 0\r\n") < 0) + return; + } + else if (!strncasecmp(con->header, "Status:", 7)) + { + cupsdSendError(con, (http_status_t)atoi(con->header + 7), + CUPSD_AUTH_NONE); + con->sent_header = 2; + } + else + { + cupsdSendHeader(con, HTTP_OK, NULL, CUPSD_AUTH_NONE); + con->sent_header = 1; + + if (con->http.version == HTTP_1_1) + { + if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n") < 0) + return; + } + } + } + + if (strncasecmp(con->header, "Status:", 7)) + httpPrintf(HTTP(con), "%s\r\n", con->header); + + /* + * Update buffer... + */ + + con->header_used -= bufptr - con->header; + + if (con->header_used > 0) + memmove(con->header, bufptr, con->header_used); + + bufptr = con->header - 1; + + /* + * See if the line was empty... + */ + + if (field_col == 0) + { + con->got_fields = 1; + + if (cupsdFlushHeader(con) < 0) + { + cupsdCloseClient(con); + return; + } + + if (con->http.version == HTTP_1_1) + con->http.data_encoding = HTTP_ENCODE_CHUNKED; + } + else + field_col = 0; + } + else if (*bufptr != '\r') + field_col ++; + } + + if (!con->got_fields) + { + con->http.activity = time(NULL); + return; + } + } + + if (con->header_used > 0) + { + if (httpWrite2(HTTP(con), con->header, con->header_used) < 0) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdWriteClient: %d Closing for error %d (%s)", + con->http.fd, con->http.error, + strerror(con->http.error)); + cupsdCloseClient(con); + return; + } + + if (con->http.data_encoding == HTTP_ENCODE_CHUNKED) + httpFlushWrite(HTTP(con)); + + con->bytes += con->header_used; + + if (con->http.state == HTTP_WAITING) + bytes = 0; + else + bytes = con->header_used; + + con->header_used = 0; + } + } + + if (bytes <= 0 || + (con->http.state != HTTP_GET_SEND && con->http.state != HTTP_POST_SEND)) + { + if (!con->sent_header && con->pipe_pid) + cupsdSendError(con, HTTP_SERVER_ERROR, CUPSD_AUTH_NONE); + else + { + cupsdLogRequest(con, HTTP_OK); + + httpFlushWrite(HTTP(con)); + + if (con->http.data_encoding == HTTP_ENCODE_CHUNKED && con->sent_header == 1) + { + if (httpWrite2(HTTP(con), "", 0) < 0) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdWriteClient: %d Closing for error %d (%s)", + con->http.fd, con->http.error, + strerror(con->http.error)); + cupsdCloseClient(con); + return; + } + } + } + + con->http.state = HTTP_WAITING; + + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, NULL, con); + + if (con->file >= 0) + { + cupsdRemoveSelect(con->file); + + if (con->pipe_pid) + cupsdEndProcess(con->pipe_pid, 0); + + close(con->file); + con->file = -1; + con->pipe_pid = 0; + } + + if (con->filename) + { + unlink(con->filename); + cupsdClearString(&con->filename); + } + + if (con->request) + { + ippDelete(con->request); + con->request = NULL; + } + + if (con->response) + { + ippDelete(con->response); + con->response = NULL; + } + + cupsdClearString(&con->command); + cupsdClearString(&con->options); + cupsdClearString(&con->query_string); + + if (!con->http.keep_alive) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdWriteClient: %d Closing because Keep-Alive disabled", + con->http.fd); + cupsdCloseClient(con); + return; + } + else + { + cupsArrayRemove(ActiveClients, con); + cupsdSetBusyState(); + } + } + + con->http.activity = time(NULL); +} + + +/* + * 'check_if_modified()' - Decode an "If-Modified-Since" line. + */ + +static int /* O - 1 if modified since */ +check_if_modified( + cupsd_client_t *con, /* I - Client connection */ + struct stat *filestats) /* I - File information */ +{ + char *ptr; /* Pointer into field */ + time_t date; /* Time/date value */ + off_t size; /* Size/length value */ + + + size = 0; + date = 0; + ptr = con->http.fields[HTTP_FIELD_IF_MODIFIED_SINCE]; + + if (*ptr == '\0') + return (1); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "check_if_modified(con=%p(%d), " + "filestats=%p(" CUPS_LLFMT ", %d)) If-Modified-Since=\"%s\"", + con, con->http.fd, filestats, CUPS_LLCAST filestats->st_size, + (int)filestats->st_mtime, ptr); + + while (*ptr != '\0') + { + while (isspace(*ptr) || *ptr == ';') + ptr ++; + + if (strncasecmp(ptr, "length=", 7) == 0) + { + ptr += 7; + size = strtoll(ptr, NULL, 10); + + while (isdigit(*ptr)) + ptr ++; + } + else if (isalpha(*ptr)) + { + date = httpGetDateTime(ptr); + while (*ptr != '\0' && *ptr != ';') + ptr ++; + } + else + ptr ++; + } + + return ((size != filestats->st_size && size != 0) || + (date < filestats->st_mtime && date != 0) || + (size == 0 && date == 0)); +} + + +/* + * 'compare_clients()' - Compare two client connections. + */ + +static int /* O - Result of comparison */ +compare_clients(cupsd_client_t *a, /* I - First client */ + cupsd_client_t *b, /* I - Second client */ + void *data) /* I - User data (not used) */ +{ + (void)data; + + if (a == b) + return (0); + else if (a < b) + return (-1); + else + return (1); +} + + +/* + * 'data_ready()' - Check whether data is available from a client. + */ + +static int /* O - 1 if data is ready, 0 otherwise */ +data_ready(cupsd_client_t *con) /* I - Client */ +{ + if (con->http.used > 0) + return (1); +#ifdef HAVE_SSL + else if (con->http.tls) + { +# ifdef HAVE_LIBSSL + if (SSL_pending((SSL *)(con->http.tls))) + return (1); +# elif defined(HAVE_GNUTLS) + if (gnutls_record_check_pending(((http_tls_t *)(con->http.tls))->session)) + return (1); +# elif defined(HAVE_CDSASSL) + size_t bytes; /* Bytes that are available */ + + if (!SSLGetBufferedReadSize(((http_tls_t *)(con->http.tls))->session, + &bytes) && bytes > 0) + return (1); +# endif /* HAVE_LIBSSL */ + } +#endif /* HAVE_SSL */ + + return (0); +} + + +#ifdef HAVE_SSL +/* + * 'encrypt_client()' - Enable encryption for the client... + */ + +static int /* O - 1 on success, 0 on error */ +encrypt_client(cupsd_client_t *con) /* I - Client to encrypt */ +{ +# ifdef HAVE_LIBSSL + SSL_CTX *context; /* Context for encryption */ + SSL *conn; /* Connection for encryption */ + BIO *bio; /* BIO data */ + unsigned long error; /* Error code */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con, + con->http.fd); + + /* + * Verify that we have a certificate... + */ + + if (access(ServerKey, 0) || access(ServerCertificate, 0)) + { + /* + * Nope, make a self-signed certificate... + */ + + if (!make_certificate(con)) + return (0); + } + + /* + * Create the SSL context and accept the connection... + */ + + context = SSL_CTX_new(SSLv23_server_method()); + + SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */ + if (SSLOptions & CUPSD_SSL_NOEMPTY) + SSL_CTX_set_options(context, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); + SSL_CTX_use_PrivateKey_file(context, ServerKey, SSL_FILETYPE_PEM); + SSL_CTX_use_certificate_chain_file(context, ServerCertificate); + + bio = BIO_new(_httpBIOMethods()); + BIO_ctrl(bio, BIO_C_SET_FILE_PTR, 0, (char *)HTTP(con)); + + conn = SSL_new(context); + SSL_set_bio(conn, bio, bio); + + if (SSL_accept(conn) != 1) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s!", + con->http.hostname); + + while ((error = ERR_get_error()) != 0) + cupsdLogMessage(CUPSD_LOG_ERROR, "%s", ERR_error_string(error, NULL)); + + SSL_CTX_free(context); + SSL_free(conn); + return (0); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", + con->http.hostname); + + con->http.tls = conn; + return (1); + +# elif defined(HAVE_GNUTLS) + http_tls_t *conn; /* TLS session object */ + int error; /* Error code */ + gnutls_certificate_server_credentials *credentials; + /* TLS credentials */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con, + con->http.fd); + + /* + * Verify that we have a certificate... + */ + + if (access(ServerKey, 0) || access(ServerCertificate, 0)) + { + /* + * Nope, make a self-signed certificate... + */ + + if (!make_certificate(con)) + return (0); + } + + /* + * Create the SSL object and perform the SSL handshake... + */ + + conn = (http_tls_t *)malloc(sizeof(http_tls_t)); + + if (conn == NULL) + return (0); + + credentials = (gnutls_certificate_server_credentials *) + malloc(sizeof(gnutls_certificate_server_credentials)); + if (credentials == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to encrypt connection from %s - %s", + con->http.hostname, strerror(errno)); + + free(conn); + return (0); + } + + gnutls_certificate_allocate_credentials(credentials); + gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate, + ServerKey, GNUTLS_X509_FMT_PEM); + + gnutls_init(&(conn->session), GNUTLS_SERVER); + gnutls_set_default_priority(conn->session); + gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials); + gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr)HTTP(con)); + gnutls_transport_set_pull_function(conn->session, _httpReadGNUTLS); + gnutls_transport_set_push_function(conn->session, _httpWriteGNUTLS); + + error = gnutls_handshake(conn->session); + + if (error != GNUTLS_E_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to encrypt connection from %s - %s", + con->http.hostname, gnutls_strerror(error)); + + gnutls_deinit(conn->session); + gnutls_certificate_free_credentials(*credentials); + free(conn); + free(credentials); + return (0); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", + con->http.hostname); + + conn->credentials = credentials; + con->http.tls = conn; + return (1); + +# elif defined(HAVE_CDSASSL) + OSStatus error; /* Error code */ + http_tls_t *conn; /* CDSA connection information */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "encrypt_client(con=%p(%d))", con, + con->http.fd); + + if ((conn = (http_tls_t *)malloc(sizeof(http_tls_t))) == NULL) + return (0); + + error = 0; + conn->session = NULL; + conn->certsArray = get_cdsa_certificate(con); + + if (!conn->certsArray) + { + /* + * No keychain (yet), make a self-signed certificate... + */ + + if (make_certificate(con)) + conn->certsArray = get_cdsa_certificate(con); + } + + if (!conn->certsArray) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Could not find signing key in keychain \"%s\"", + ServerCertificate); + error = errSSLBadCert; /* errSSLBadConfiguration is a better choice, but not available on 10.2.x */ + } + + if (!error) + error = SSLNewContext(true, &conn->session); + + if (!error) + error = SSLSetIOFuncs(conn->session, _httpReadCDSA, _httpWriteCDSA); + + if (!error) + error = SSLSetProtocolVersionEnabled(conn->session, kSSLProtocol2, false); + + if (!error) + error = SSLSetConnection(conn->session, HTTP(con)); + + if (!error) + error = SSLSetAllowsExpiredCerts(conn->session, true); + + if (!error) + error = SSLSetAllowsAnyRoot(conn->session, true); + + if (!error) + error = SSLSetCertificate(conn->session, conn->certsArray); + + if (!error) + { + /* + * Perform SSL/TLS handshake + */ + + while ((error = SSLHandshake(conn->session)) == errSSLWouldBlock) + usleep(1000); + } + + if (error) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to encrypt connection from %s - %s (%d)", + con->http.hostname, cssmErrorString(error), (int)error); + + con->http.error = error; + con->http.status = HTTP_ERROR; + + if (conn->session) + SSLDisposeContext(conn->session); + + if (conn->certsArray) + CFRelease(conn->certsArray); + + free(conn); + + return (0); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", + con->http.hostname); + + con->http.tls = conn; + return (1); + +# endif /* HAVE_LIBSSL */ +} +#endif /* HAVE_SSL */ + + +#ifdef HAVE_CDSASSL +/* + * 'get_cdsa_certificate()' - Get a SSL/TLS certificate from the System keychain. + */ + +static CFArrayRef /* O - Array of certificates */ +get_cdsa_certificate( + cupsd_client_t *con) /* I - Client connection */ +{ + OSStatus err; /* Error info */ + SecKeychainRef keychain = NULL;/* Keychain reference */ + SecIdentitySearchRef search = NULL; /* Search reference */ + SecIdentityRef identity = NULL;/* Identity */ + CFArrayRef certificates = NULL; + /* Certificate array */ +# if HAVE_SECPOLICYCREATESSL + SecPolicyRef policy = NULL; /* Policy ref */ + CFStringRef servername = NULL; + /* Server name */ + CFMutableDictionaryRef query = NULL; /* Query qualifiers */ + char localname[1024];/* Local hostname */ +# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) + SecPolicyRef policy = NULL; /* Policy ref */ + SecPolicySearchRef policy_search = NULL; + /* Policy search ref */ + CSSM_DATA options; /* Policy options */ + CSSM_APPLE_TP_SSL_OPTIONS + ssl_options; /* SSL Option for hostname */ + char localname[1024];/* Local hostname */ +# endif /* HAVE_SECPOLICYCREATESSL */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "get_cdsa_certificate: Looking for certs for \"%s\"...", + con->servername); + + if ((err = SecKeychainOpen(ServerCertificate, &keychain))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot open keychain \"%s\" - %s (%d)", + ServerCertificate, cssmErrorString(err), (int)err); + goto cleanup; + } + +# if HAVE_SECPOLICYCREATESSL + servername = CFStringCreateWithCString(kCFAllocatorDefault, con->servername, + kCFStringEncodingUTF8); + + policy = SecPolicyCreateSSL(1, servername); + + if (servername) + CFRelease(servername); + + if (!policy) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference"); + goto cleanup; + } + + if (!(query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create query dictionary"); + goto cleanup; + } + + CFDictionaryAddValue(query, kSecClass, kSecClassIdentity); + CFDictionaryAddValue(query, kSecMatchPolicy, policy); + CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); + CFDictionaryAddValue(query, kSecMatchLimit, kSecMatchLimitOne); + + err = SecItemCopyMatching(query, (CFTypeRef *)&identity); + + if (err && DNSSDHostName) + { + /* + * Search for the connection server name failed; try the DNS-SD .local + * hostname instead... + */ + + snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "get_cdsa_certificate: Looking for certs for \"%s\"...", + localname); + + servername = CFStringCreateWithCString(kCFAllocatorDefault, localname, + kCFStringEncodingUTF8); + + CFRelease(policy); + + policy = SecPolicyCreateSSL(1, servername); + + if (servername) + CFRelease(servername); + + if (!policy) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create ssl policy reference"); + goto cleanup; + } + + CFDictionarySetValue(query, kSecMatchPolicy, policy); + + err = SecItemCopyMatching(query, (CFTypeRef *)&identity); + } + + if (err) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Cannot find signing key in keychain \"%s\": %s (%d)", + ServerCertificate, cssmErrorString(err), (int)err); + goto cleanup; + } + +# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) + /* + * Use a policy to search for valid certificates who's common name matches the + * servername... + */ + + if (SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_TP_SSL, + NULL, &policy_search)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create a policy search reference"); + goto cleanup; + } + + if (SecPolicySearchCopyNext(policy_search, &policy)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Cannot find a policy to use for searching"); + goto cleanup; + } + + memset(&ssl_options, 0, sizeof(ssl_options)); + ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; + ssl_options.ServerName = con->servername; + ssl_options.ServerNameLen = strlen(con->servername); + + options.Data = (uint8 *)&ssl_options; + options.Length = sizeof(ssl_options); + + if (SecPolicySetValue(policy, &options)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Cannot set policy value to use for searching"); + goto cleanup; + } + + if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN, + keychain, FALSE, &search))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Cannot create identity search reference: %s (%d)", + cssmErrorString(err), (int)err); + goto cleanup; + } + + err = SecIdentitySearchCopyNext(search, &identity); + + if (err && DNSSDHostName) + { + /* + * Search for the connection server name failed; try the DNS-SD .local + * hostname instead... + */ + + snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); + + ssl_options.ServerName = localname; + ssl_options.ServerNameLen = strlen(localname); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "get_cdsa_certificate: Looking for certs for \"%s\"...", + localname); + + if (SecPolicySetValue(policy, &options)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Cannot set policy value to use for searching"); + goto cleanup; + } + + CFRelease(search); + search = NULL; + if ((err = SecIdentitySearchCreateWithPolicy(policy, NULL, CSSM_KEYUSE_SIGN, + keychain, FALSE, &search))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Cannot create identity search reference: %s (%d)", + cssmErrorString(err), (int)err); + goto cleanup; + } + + err = SecIdentitySearchCopyNext(search, &identity); + + } + + if (err) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Cannot find signing key in keychain \"%s\": %s (%d)", + ServerCertificate, cssmErrorString(err), (int)err); + goto cleanup; + } + +# else + /* + * Assume there is exactly one SecIdentity in the keychain... + */ + + if ((err = SecIdentitySearchCreate(keychain, CSSM_KEYUSE_SIGN, &search))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Cannot create identity search reference (%d)", (int)err); + goto cleanup; + } + + if ((err = SecIdentitySearchCopyNext(search, &identity))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Cannot find signing key in keychain \"%s\": %s (%d)", + ServerCertificate, cssmErrorString(err), (int)err); + goto cleanup; + } +# endif /* HAVE_SECPOLICYCREATESSL */ + + if (CFGetTypeID(identity) != SecIdentityGetTypeID()) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "SecIdentity CFTypeID failure!"); + goto cleanup; + } + + if ((certificates = CFArrayCreate(NULL, (const void **)&identity, + 1, &kCFTypeArrayCallBacks)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Cannot create certificate array"); + goto cleanup; + } + + cleanup : + + if (keychain) + CFRelease(keychain); + if (search) + CFRelease(search); + if (identity) + CFRelease(identity); + +# if HAVE_SECPOLICYCREATESSL + if (policy) + CFRelease(policy); + if (query) + CFRelease(query); + +# elif defined(HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY) + if (policy) + CFRelease(policy); + if (policy_search) + CFRelease(policy_search); +# endif /* HAVE_SECPOLICYCREATESSL */ + + return (certificates); +} +#endif /* HAVE_CDSASSL */ + + +/* + * 'get_file()' - Get a filename and state info. + */ + +static char * /* O - Real filename */ +get_file(cupsd_client_t *con, /* I - Client connection */ + struct stat *filestats, /* O - File information */ + char *filename, /* IO - Filename buffer */ + int len) /* I - Buffer length */ +{ + int status; /* Status of filesystem calls */ + char *ptr; /* Pointer info filename */ + int plen; /* Remaining length after pointer */ + char language[7]; /* Language subdirectory, if any */ + + + /* + * Figure out the real filename... + */ + + language[0] = '\0'; + + if (!strncmp(con->uri, "/ppd/", 5)) + snprintf(filename, len, "%s%s", ServerRoot, con->uri); + else if (!strncmp(con->uri, "/icons/", 7) && !strchr(con->uri + 7, '/')) + { + snprintf(filename, len, "%s/%s", CacheDir, con->uri + 7); + if (access(filename, F_OK) < 0) + snprintf(filename, len, "%s/images/generic.png", DocumentRoot); + } + else if (!strncmp(con->uri, "/rss/", 5) && !strchr(con->uri + 5, '/')) + snprintf(filename, len, "%s/rss/%s", CacheDir, con->uri + 5); + else if (!strncmp(con->uri, "/admin/conf/", 12)) + snprintf(filename, len, "%s%s", ServerRoot, con->uri + 11); + else if (!strncmp(con->uri, "/admin/log/", 11)) + { + if (!strncmp(con->uri + 11, "access_log", 10) && AccessLog[0] == '/') + strlcpy(filename, AccessLog, len); + else if (!strncmp(con->uri + 11, "error_log", 9) && ErrorLog[0] == '/') + strlcpy(filename, ErrorLog, len); + else if (!strncmp(con->uri + 11, "page_log", 8) && PageLog[0] == '/') + strlcpy(filename, PageLog, len); + else + return (NULL); + } + else if (con->language) + { + snprintf(language, sizeof(language), "/%s", con->language->language); + snprintf(filename, len, "%s%s%s", DocumentRoot, language, con->uri); + } + else + snprintf(filename, len, "%s%s", DocumentRoot, con->uri); + + if ((ptr = strchr(filename, '?')) != NULL) + *ptr = '\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 && language[0] && + strncmp(con->uri, "/icons/", 7) && + strncmp(con->uri, "/ppd/", 5) && + strncmp(con->uri, "/admin/conf/", 12) && + strncmp(con->uri, "/admin/log/", 11)) + { + /* + * Drop the country code... + */ + + language[3] = '\0'; + snprintf(filename, len, "%s%s%s", DocumentRoot, language, con->uri); + + if ((ptr = strchr(filename, '?')) != NULL) + *ptr = '\0'; + + if ((status = stat(filename, filestats)) != 0) + { + /* + * Drop the language prefix and try the root directory... + */ + + language[0] = '\0'; + snprintf(filename, len, "%s%s", DocumentRoot, con->uri); + + if ((ptr = strchr(filename, '?')) != NULL) + *ptr = '\0'; + + status = stat(filename, filestats); + } + } + + /* + * If we're found a directory, get the index.html file instead... + */ + + if (!status && S_ISDIR(filestats->st_mode)) + { + /* + * Make sure the URI ends with a slash... + */ + + if (con->uri[strlen(con->uri) - 1] != '/') + strlcat(con->uri, "/", sizeof(con->uri)); + + /* + * Find the directory index file, trying every language... + */ + + do + { + if (status && language[0]) + { + /* + * Try a different language subset... + */ + + if (language[3]) + language[0] = '\0'; /* Strip country code */ + else + language[0] = '\0'; /* Strip language */ + } + + /* + * Look for the index file... + */ + + snprintf(filename, len, "%s%s%s", DocumentRoot, language, con->uri); + + if ((ptr = strchr(filename, '?')) != NULL) + *ptr = '\0'; + + ptr = filename + strlen(filename); + plen = len - (ptr - filename); + + strlcpy(ptr, "index.html", plen); + status = stat(filename, filestats); + +#ifdef HAVE_JAVA + if (status) + { + strlcpy(ptr, "index.class", plen); + status = stat(filename, filestats); + } +#endif /* HAVE_JAVA */ + +#ifdef HAVE_PERL + if (status) + { + strlcpy(ptr, "index.pl", plen); + status = stat(filename, filestats); + } +#endif /* HAVE_PERL */ + +#ifdef HAVE_PHP + if (status) + { + strlcpy(ptr, "index.php", plen); + status = stat(filename, filestats); + } +#endif /* HAVE_PHP */ + +#ifdef HAVE_PYTHON + if (status) + { + strlcpy(ptr, "index.pyc", plen); + status = stat(filename, filestats); + } + + if (status) + { + strlcpy(ptr, "index.py", plen); + status = stat(filename, filestats); + } +#endif /* HAVE_PYTHON */ + + } + while (status && language[0]); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_file(con=%p(%d), filestats=%p, filename=%p, len=%d) = " + "%s", con, con->http.fd, filestats, filename, len, + status ? "(null)" : filename); + + if (status) + return (NULL); + else + return (filename); +} + + +/* + * 'install_conf_file()' - Install a configuration file. + */ + +static http_status_t /* O - Status */ +install_conf_file(cupsd_client_t *con) /* I - Connection */ +{ + cups_file_t *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); + + cupsdLogMessage(CUPSD_LOG_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 = ConfigFilePerm; + } + + /* + * Open the request file and new config file... + */ + + if ((in = cupsFileOpen(con->filename, "rb")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open request file \"%s\" - %s", + con->filename, strerror(errno)); + return (HTTP_SERVER_ERROR); + } + + if ((out = cupsFileOpen(newfile, "wb")) == NULL) + { + cupsFileClose(in); + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open config file \"%s\" - %s", + newfile, strerror(errno)); + return (HTTP_SERVER_ERROR); + } + + fchmod(cupsFileNumber(out), confinfo.st_mode); + fchown(cupsFileNumber(out), confinfo.st_uid, confinfo.st_gid); + + /* + * Copy from the request to the new config file... + */ + + while ((bytes = cupsFileRead(in, buffer, sizeof(buffer))) > 0) + if (cupsFileWrite(out, buffer, bytes) < bytes) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to copy to config file \"%s\" - %s", + newfile, strerror(errno)); + + cupsFileClose(in); + cupsFileClose(out); + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + /* + * Close the files... + */ + + cupsFileClose(in); + if (cupsFileClose(out)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Error file closing config file \"%s\" - %s", + newfile, strerror(errno)); + + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + /* + * Remove the request file... + */ + + unlink(con->filename); + cupsdClearString(&con->filename); + + /* + * 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) + { + cupsdLogMessage(CUPSD_LOG_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) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to rename old config file \"%s\" - %s", + conffile, strerror(errno)); + + unlink(newfile); + + return (HTTP_SERVER_ERROR); + } + + if (rename(newfile, conffile)) + { + cupsdLogMessage(CUPSD_LOG_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")) + NeedReload = RELOAD_CUPSD; + else + NeedReload = RELOAD_ALL; + + ReloadTime = time(NULL); + + /* + * Return that the file was created successfully... + */ + + return (HTTP_CREATED); +} + + +/* + * 'is_cgi()' - Is the resource a CGI script/program? + */ + +static int /* O - 1 = CGI, 0 = file */ +is_cgi(cupsd_client_t *con, /* I - Client connection */ + const char *filename, /* I - Real filename */ + struct stat *filestats, /* I - File information */ + mime_type_t *type) /* I - MIME type */ +{ + const char *options; /* Options on URL */ + + + /* + * Get the options, if any... + */ + + if ((options = strchr(con->uri, '?')) != NULL) + { + options ++; + cupsdSetStringf(&(con->query_string), "QUERY_STRING=%s", options); + } + + /* + * Check for known types... + */ + + if (!type || strcasecmp(type->super, "application")) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 0", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (0); + } + + if (!strcasecmp(type->type, "x-httpd-cgi") && + (filestats->st_mode & 0111)) + { + /* + * "application/x-httpd-cgi" is a CGI script. + */ + + cupsdSetString(&con->command, filename); + + if (options) + cupsdSetStringf(&con->options, " %s", options); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 1", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (1); + } +#ifdef HAVE_JAVA + else if (!strcasecmp(type->type, "x-httpd-java")) + { + /* + * "application/x-httpd-java" is a Java servlet. + */ + + cupsdSetString(&con->command, CUPS_JAVA); + + if (options) + cupsdSetStringf(&con->options, " %s %s", filename, options); + else + cupsdSetStringf(&con->options, " %s", filename); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 1", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (1); + } +#endif /* HAVE_JAVA */ +#ifdef HAVE_PERL + else if (!strcasecmp(type->type, "x-httpd-perl")) + { + /* + * "application/x-httpd-perl" is a Perl page. + */ + + cupsdSetString(&con->command, CUPS_PERL); + + if (options) + cupsdSetStringf(&con->options, " %s %s", filename, options); + else + cupsdSetStringf(&con->options, " %s", filename); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 1", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (1); + } +#endif /* HAVE_PERL */ +#ifdef HAVE_PHP + else if (!strcasecmp(type->type, "x-httpd-php")) + { + /* + * "application/x-httpd-php" is a PHP page. + */ + + cupsdSetString(&con->command, CUPS_PHP); + + if (options) + cupsdSetStringf(&con->options, " %s %s", filename, options); + else + cupsdSetStringf(&con->options, " %s", filename); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 1", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (1); + } +#endif /* HAVE_PHP */ +#ifdef HAVE_PYTHON + else if (!strcasecmp(type->type, "x-httpd-python")) + { + /* + * "application/x-httpd-python" is a Python page. + */ + + cupsdSetString(&con->command, CUPS_PYTHON); + + if (options) + cupsdSetStringf(&con->options, " %s %s", filename, options); + else + cupsdSetStringf(&con->options, " %s", filename); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 1", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (1); + } +#endif /* HAVE_PYTHON */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "is_cgi(con=%p(%d), filename=\"%s\", filestats=%p, " + "type=%s/%s) = 0", con, con->http.fd, filename, filestats, + type ? type->super : "unknown", + type ? type->type : "unknown"); + return (0); +} + + +/* + * 'is_path_absolute()' - Is a path absolute and free of relative elements (i.e. ".."). + */ + +static int /* O - 0 if relative, 1 if absolute */ +is_path_absolute(const char *path) /* I - Input path */ +{ + /* + * Check for a leading slash... + */ + + if (path[0] != '/') + return (0); + + /* + * Check for "/.." in the path... + */ + + while ((path = strstr(path, "/..")) != NULL) + { + if (!path[3] || path[3] == '/') + return (0); + + path ++; + } + + /* + * If we haven't found any relative paths, return 1 indicating an + * absolute path... + */ + + return (1); +} + + +#ifdef HAVE_SSL +/* + * 'make_certificate()' - Make a self-signed SSL/TLS certificate. + */ + +static int /* O - 1 on success, 0 on failure */ +make_certificate(cupsd_client_t *con) /* I - Client connection */ +{ +#if defined(HAVE_LIBSSL) && defined(HAVE_WAITPID) + int pid, /* Process ID of command */ + status; /* Status of command */ + char command[1024], /* Command */ + *argv[12], /* Command-line arguments */ + *envp[MAX_ENV + 1], /* Environment variables */ + infofile[1024], /* Type-in information for cert */ + seedfile[1024]; /* Random number seed file */ + int envc, /* Number of environment variables */ + bytes; /* Bytes written */ + cups_file_t *fp; /* Seed/info file */ + int infofd; /* Info file descriptor */ + + + /* + * Run the "openssl" command to seed the random number generator and + * generate a self-signed certificate that is good for 10 years: + * + * openssl rand -rand seedfile 1 + * + * openssl req -new -x509 -keyout ServerKey \ + * -out ServerCertificate -days 3650 -nodes + * + * The seeding step is crucial in ensuring that the openssl command + * does not block on systems without sufficient entropy... + */ + + if (!cupsFileFind("openssl", getenv("PATH"), 1, command, sizeof(command))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "No SSL certificate and openssl command not found!"); + return (0); + } + + if (access("/dev/urandom", 0)) + { + /* + * If the system doesn't provide /dev/urandom, then any random source + * will probably be blocking-style, so generate some random data to + * use as a seed for the certificate. Note that we have already + * seeded the random number generator in cupsdInitCerts()... + */ + + cupsdLogMessage(CUPSD_LOG_INFO, + "Seeding the random number generator..."); + + /* + * Write the seed file... + */ + + if ((fp = cupsTempFile2(seedfile, sizeof(seedfile))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create seed file %s - %s", + seedfile, strerror(errno)); + return (0); + } + + for (bytes = 0; bytes < 262144; bytes ++) + cupsFilePutChar(fp, random()); + + cupsFileClose(fp); + + /* + * Run the openssl command to seed its random number generator... + */ + + argv[0] = "openssl"; + argv[1] = "rand"; + argv[2] = "-rand"; + argv[3] = seedfile; + argv[4] = "1"; + argv[5] = NULL; + + envc = cupsdLoadEnv(envp, MAX_ENV); + envp[envc] = NULL; + + if (!cupsdStartProcess(command, argv, envp, -1, -1, -1, -1, -1, 1, NULL, + NULL, &pid)) + { + unlink(seedfile); + return (0); + } + + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + { + status = 1; + break; + } + + cupsdFinishProcess(pid, command, sizeof(command), NULL); + + /* + * Remove the seed file, as it is no longer needed... + */ + + unlink(seedfile); + + if (status) + { + if (WIFEXITED(status)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to seed random number generator - " + "the openssl command stopped with status %d!", + WEXITSTATUS(status)); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to seed random number generator - " + "the openssl command crashed on signal %d!", + WTERMSIG(status)); + + return (0); + } + } + + /* + * Create a file with the certificate information fields... + * + * Note: This assumes that the default questions are asked by the openssl + * command... + */ + + if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create certificate information file %s - %s", + infofile, strerror(errno)); + return (0); + } + + cupsFilePrintf(fp, ".\n.\n.\n%s\n.\n%s\n%s\n", + ServerName, ServerName, ServerAdmin); + cupsFileClose(fp); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Generating SSL server key and certificate..."); + + argv[0] = "openssl"; + argv[1] = "req"; + argv[2] = "-new"; + argv[3] = "-x509"; + argv[4] = "-keyout"; + argv[5] = ServerKey; + argv[6] = "-out"; + argv[7] = ServerCertificate; + argv[8] = "-days"; + argv[9] = "3650"; + argv[10] = "-nodes"; + argv[11] = NULL; + + cupsdLoadEnv(envp, MAX_ENV); + + infofd = open(infofile, O_RDONLY); + + if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, NULL, + NULL, &pid)) + { + close(infofd); + unlink(infofile); + return (0); + } + + close(infofd); + unlink(infofile); + + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + { + status = 1; + break; + } + + cupsdFinishProcess(pid, command, sizeof(command), NULL); + + if (status) + { + if (WIFEXITED(status)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server key and certificate - " + "the openssl command stopped with status %d!", + WEXITSTATUS(status)); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server key and certificate - " + "the openssl command crashed on signal %d!", + WTERMSIG(status)); + } + else + { + cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...", + ServerKey); + cupsdLogMessage(CUPSD_LOG_INFO, + "Created SSL server certificate file \"%s\"...", + ServerCertificate); + } + + return (!status); + +#elif defined(HAVE_GNUTLS) + gnutls_x509_crt crt; /* Self-signed certificate */ + gnutls_x509_privkey key; /* Encryption key */ + cups_lang_t *language; /* Default language info */ + cups_file_t *fp; /* Key/cert file */ + unsigned char buffer[8192]; /* Buffer for x509 data */ + size_t bytes; /* Number of bytes of data */ + unsigned char serial[4]; /* Serial number buffer */ + time_t curtime; /* Current time */ + int result; /* Result of GNU TLS calls */ + + + /* + * Create the encryption key... + */ + + cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key..."); + + gnutls_x509_privkey_init(&key); + gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0); + + /* + * Save it... + */ + + bytes = sizeof(buffer); + + if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, + buffer, &bytes)) < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s", + gnutls_strerror(result)); + gnutls_x509_privkey_deinit(key); + return (0); + } + else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL) + { + cupsFileWrite(fp, (char *)buffer, bytes); + cupsFileClose(fp); + + cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...", + ServerKey); + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server key file \"%s\" - %s", + ServerKey, strerror(errno)); + gnutls_x509_privkey_deinit(key); + return (0); + } + + /* + * Create the self-signed certificate... + */ + + cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate..."); + + language = cupsLangDefault(); + curtime = time(NULL); + serial[0] = curtime >> 24; + serial[1] = curtime >> 16; + serial[2] = curtime >> 8; + serial[3] = curtime; + + gnutls_x509_crt_init(&crt); + if (strlen(language->language) == 5) + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, + language->language + 3, 2); + else + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, + "US", 2); + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, + ServerName, strlen(ServerName)); + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, + ServerName, strlen(ServerName)); + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, + 0, "Unknown", 7); + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, + "Unknown", 7); + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0, + "Unknown", 7); + gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0, + ServerAdmin, strlen(ServerAdmin)); + gnutls_x509_crt_set_key(crt, key); + gnutls_x509_crt_set_serial(crt, serial, sizeof(serial)); + gnutls_x509_crt_set_activation_time(crt, curtime); + gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400); + gnutls_x509_crt_set_ca_status(crt, 0); + gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, + ServerName); + gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); + gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT); + gnutls_x509_crt_set_version(crt, 3); + + bytes = sizeof(buffer); + if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0) + gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes); + + gnutls_x509_crt_sign(crt, crt, key); + + /* + * Save it... + */ + + bytes = sizeof(buffer); + if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, + buffer, &bytes)) < 0) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to export SSL server certificate - %s", + gnutls_strerror(result)); + else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL) + { + cupsFileWrite(fp, (char *)buffer, bytes); + cupsFileClose(fp); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Created SSL server certificate file \"%s\"...", + ServerCertificate); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server certificate file \"%s\" - %s", + ServerCertificate, strerror(errno)); + + /* + * Cleanup... + */ + + gnutls_x509_crt_deinit(crt); + gnutls_x509_privkey_deinit(key); + + return (1); + +#elif defined(HAVE_CDSASSL) && defined(HAVE_WAITPID) + int pid, /* Process ID of command */ + status; /* Status of command */ + char command[1024], /* Command */ + *argv[4], /* Command-line arguments */ + *envp[MAX_ENV + 1], /* Environment variables */ + keychain[1024], /* Keychain argument */ + infofile[1024], /* Type-in information for cert */ + localname[1024], /* Local hostname */ + *servername; /* Name of server in cert */ + cups_file_t *fp; /* Seed/info file */ + int infofd; /* Info file descriptor */ + + if (con->servername && isdigit(con->servername[0] & 255) && DNSSDHostName) + { + snprintf(localname, sizeof(localname), "%s.local", DNSSDHostName); + servername = localname; + } + else + servername = con->servername; + + /* + * Run the "certtool" command to generate a self-signed certificate... + */ + + if (!cupsFileFind("certtool", getenv("PATH"), 1, command, sizeof(command))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "No SSL certificate and certtool command not found!"); + return (0); + } + + /* + * Create a file with the certificate information fields... + * + * Note: This assumes that the default questions are asked by the certtool + * command... + */ + + if ((fp = cupsTempFile2(infofile, sizeof(infofile))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create certificate information file %s - %s", + infofile, strerror(errno)); + return (0); + } + + cupsFilePrintf(fp, "%s\nr\n\ny\nb\ns\ny\n%s\n\n\n\n\n%s\ny\n", + servername, servername, ServerAdmin); + cupsFileClose(fp); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Generating SSL server key and certificate..."); + + snprintf(keychain, sizeof(keychain), "k=%s", ServerCertificate); + + argv[0] = "certtool"; + argv[1] = "c"; + argv[2] = keychain; + argv[3] = NULL; + + cupsdLoadEnv(envp, MAX_ENV); + + infofd = open(infofile, O_RDONLY); + + if (!cupsdStartProcess(command, argv, envp, infofd, -1, -1, -1, -1, 1, NULL, + NULL, &pid)) + { + close(infofd); + unlink(infofile); + return (0); + } + + close(infofd); + unlink(infofile); + + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + { + status = 1; + break; + } + + cupsdFinishProcess(pid, command, sizeof(command), NULL); + + if (status) + { + if (WIFEXITED(status)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server key and certificate - " + "the certtool command stopped with status %d!", + WEXITSTATUS(status)); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create SSL server key and certificate - " + "the certtool command crashed on signal %d!", + WTERMSIG(status)); + } + else + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Created SSL server certificate file \"%s\"...", + ServerCertificate); + } + + return (!status); + +#else + return (0); +#endif /* HAVE_LIBSSL && HAVE_WAITPID */ +} +#endif /* HAVE_SSL */ + + +/* + * 'pipe_command()' - Pipe the output of a command to the remote client. + */ + +static int /* O - Process ID */ +pipe_command(cupsd_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 root) /* I - Run as root? */ +{ + int i; /* Looping var */ + int pid; /* Process ID */ + char *commptr, /* Command string pointer */ + commch; /* Command string character */ + char *uriptr; /* URI string pointer */ + 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[MAX_ENV + 20]; /* Environment variables */ + char auth_type[256], /* AUTH_TYPE environment variable */ + content_length[1024], /* CONTENT_LENGTH environment variable */ + content_type[1024], /* CONTENT_TYPE environment variable */ + http_cookie[32768], /* HTTP_COOKIE environment variable */ + http_referer[1024], /* HTTP_REFERER environment variable */ + http_user_agent[1024], /* HTTP_USER_AGENT environment variable */ + lang[1024], /* LANG environment variable */ + path_info[1024], /* PATH_INFO environment variable */ + remote_addr[1024], /* REMOTE_ADDR environment variable */ + remote_host[1024], /* REMOTE_HOST environment variable */ + remote_user[1024], /* REMOTE_USER environment variable */ + script_filename[1024], /* SCRIPT_FILENAME environment variable */ + script_name[1024], /* SCRIPT_NAME environment variable */ + server_name[1024], /* SERVER_NAME environment variable */ + server_port[1024]; /* SERVER_PORT environment variable */ + ipp_attribute_t *attr; /* attributes-natural-language attribute */ + void *ccache = NULL; /* Kerberos credentials */ + + + /* + * Parse a copy of the options string, which is of the form: + * + * argument+argument+argument + * ?argument+argument+argument + * param=value¶m=value + * ?param=value¶m=value + * /name?argument+argument+argument + * /name?param=value¶m=value + * + * If the string contains an "=" character after the initial name, + * then we treat it as a HTTP GET form request and make a copy of + * the remaining string for the environment variable. + * + * The string is always parsed out as command-line arguments, to + * be consistent with Apache... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "pipe_command(con=%p(%d), infile=%d, outfile=%p, " + "command=\"%s\", options=\"%s\", root=%d)", + con, con->http.fd, infile, outfile, command, + options ? options : "(null)", root); + + argv[0] = command; + + if (options) + { + commptr = options; + if (*commptr == ' ') + commptr ++; + strlcpy(argbuf, commptr, sizeof(argbuf)); + } + else + argbuf[0] = '\0'; + + if (argbuf[0] == '/') + { + /* + * Found some trailing path information, set PATH_INFO... + */ + + if ((commptr = strchr(argbuf, '?')) == NULL) + commptr = argbuf + strlen(argbuf); + + commch = *commptr; + *commptr = '\0'; + snprintf(path_info, sizeof(path_info), "PATH_INFO=%s", argbuf); + *commptr = commch; + } + else + { + commptr = argbuf; + path_info[0] = '\0'; + + if (*commptr == ' ') + commptr ++; + } + + if (*commptr == '?' && con->operation == HTTP_GET && !con->query_string) + { + commptr ++; + cupsdSetStringf(&(con->query_string), "QUERY_STRING=%s", commptr); + } + + argc = 1; + + if (*commptr) + { + argv[argc ++] = commptr; + + for (; *commptr && argc < 99; commptr ++) + { + /* + * Break arguments whenever we see a + or space... + */ + + if (*commptr == ' ' || *commptr == '+') + { + while (*commptr == ' ' || *commptr == '+') + *commptr++ = '\0'; + + /* + * If we don't have a blank string, save it as another argument... + */ + + if (*commptr) + { + argv[argc] = commptr; + argc ++; + } + else + break; + } + else if (*commptr == '%' && isxdigit(commptr[1] & 255) && + isxdigit(commptr[2] & 255)) + { + /* + * Convert the %xx notation to the individual character. + */ + + 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; + + _cups_strcpy(commptr + 1, commptr + 3); + + /* + * Check for a %00 and break if that is the case... + */ + + if (!*commptr) + break; + } + } + } + + argv[argc] = NULL; + + /* + * Setup the environment variables as needed... + */ + + if (con->username[0]) + { + snprintf(auth_type, sizeof(auth_type), "AUTH_TYPE=%s", + httpGetField(HTTP(con), HTTP_FIELD_AUTHORIZATION)); + + if ((uriptr = strchr(auth_type + 10, ' ')) != NULL) + *uriptr = '\0'; + } + else + auth_type[0] = '\0'; + + if (con->request && + (attr = ippFindAttribute(con->request, "attributes-natural-language", + IPP_TAG_LANGUAGE)) != NULL) + { + switch (strlen(attr->values[0].string.text)) + { + default : + /* + * This is an unknown or badly formatted language code; use + * the POSIX locale... + */ + + strcpy(lang, "LANG=C"); + break; + + case 2 : + /* + * Just the language code (ll)... + */ + + snprintf(lang, sizeof(lang), "LANG=%s.UTF8", + attr->values[0].string.text); + break; + + case 5 : + /* + * Language and country code (ll-cc)... + */ + + snprintf(lang, sizeof(lang), "LANG=%c%c_%c%c.UTF8", + attr->values[0].string.text[0], + attr->values[0].string.text[1], + toupper(attr->values[0].string.text[3] & 255), + toupper(attr->values[0].string.text[4] & 255)); + break; + } + } + else if (con->language) + snprintf(lang, sizeof(lang), "LANG=%s.UTF8", con->language->language); + else + strcpy(lang, "LANG=C"); + + strcpy(remote_addr, "REMOTE_ADDR="); + httpAddrString(con->http.hostaddr, remote_addr + 12, + sizeof(remote_addr) - 12); + + snprintf(remote_host, sizeof(remote_host), "REMOTE_HOST=%s", + con->http.hostname); + + snprintf(script_name, sizeof(script_name), "SCRIPT_NAME=%s", con->uri); + if ((uriptr = strchr(script_name, '?')) != NULL) + *uriptr = '\0'; + + snprintf(script_filename, sizeof(script_filename), "SCRIPT_FILENAME=%s%s", + DocumentRoot, script_name + 12); + + sprintf(server_port, "SERVER_PORT=%d", con->serverport); + + if (con->http.fields[HTTP_FIELD_HOST][0]) + { + char *nameptr; /* Pointer to ":port" */ + + snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s", + con->http.fields[HTTP_FIELD_HOST]); + if ((nameptr = strrchr(server_name, ':')) != NULL && !strchr(nameptr, ']')) + *nameptr = '\0'; /* Strip trailing ":port" */ + } + else + snprintf(server_name, sizeof(server_name), "SERVER_NAME=%s", + con->servername); + + envc = cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + + if (auth_type[0]) + envp[envc ++] = auth_type; + + envp[envc ++] = lang; + envp[envc ++] = "REDIRECT_STATUS=1"; + envp[envc ++] = "GATEWAY_INTERFACE=CGI/1.1"; + envp[envc ++] = server_name; + envp[envc ++] = server_port; + envp[envc ++] = remote_addr; + envp[envc ++] = remote_host; + envp[envc ++] = script_name; + envp[envc ++] = script_filename; + + if (path_info[0]) + envp[envc ++] = path_info; + + if (con->username[0]) + { + snprintf(remote_user, sizeof(remote_user), "REMOTE_USER=%s", con->username); + + envp[envc ++] = remote_user; + + /* + * Save Kerberos credentials, if any... + */ + +#ifdef HAVE_GSSAPI + if (con->gss_creds) + ccache = cupsdCopyKrb5Creds(con); +#endif /* HAVE_GSSAPI */ + } + + if (con->http.version == HTTP_1_1) + envp[envc ++] = "SERVER_PROTOCOL=HTTP/1.1"; + else if (con->http.version == HTTP_1_0) + envp[envc ++] = "SERVER_PROTOCOL=HTTP/1.0"; + else + envp[envc ++] = "SERVER_PROTOCOL=HTTP/0.9"; + + if (con->http.cookie) + { + snprintf(http_cookie, sizeof(http_cookie), "HTTP_COOKIE=%s", + con->http.cookie); + envp[envc ++] = http_cookie; + } + + if (con->http.fields[HTTP_FIELD_USER_AGENT][0]) + { + snprintf(http_user_agent, sizeof(http_user_agent), "HTTP_USER_AGENT=%s", + con->http.fields[HTTP_FIELD_USER_AGENT]); + envp[envc ++] = http_user_agent; + } + + if (con->http.fields[HTTP_FIELD_REFERER][0]) + { + snprintf(http_referer, sizeof(http_referer), "HTTP_REFERER=%s", + con->http.fields[HTTP_FIELD_REFERER]); + envp[envc ++] = http_referer; + } + + if (con->operation == HTTP_GET) + { + envp[envc ++] = "REQUEST_METHOD=GET"; + + if (con->query_string) + { + /* + * Add GET form variables after ?... + */ + + envp[envc ++] = con->query_string; + } + else + envp[envc ++] = "QUERY_STRING="; + } + else + { + sprintf(content_length, "CONTENT_LENGTH=" CUPS_LLFMT, + CUPS_LLCAST 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.tls) + envp[envc ++] = "HTTPS=ON"; + + /* + * Terminate the environment array... + */ + + envp[envc] = NULL; + + if (LogLevel >= CUPSD_LOG_DEBUG) + { + for (i = 0; i < argc; i ++) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "[CGI] argv[%d] = \"%s\"", i, argv[i]); + for (i = 0; i < envc; i ++) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "[CGI] envp[%d] = \"%s\"", i, envp[i]); + } + + /* + * Create a pipe for the output... + */ + + if (cupsdOpenPipe(fds)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "[CGI] Unable to create pipe for %s - %s", + argv[0], strerror(errno)); + return (0); + } + + /* + * Then execute the command... + */ + + if (cupsdStartProcess(command, argv, envp, infile, fds[1], CGIPipes[1], + -1, -1, root, DefaultProfile, NULL, &pid) < 0) + { + /* + * Error - can't fork! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "[CGI] Unable to start %s - %s", argv[0], + strerror(errno)); + + cupsdClosePipe(fds); + pid = 0; + } + else + { + /* + * Fork successful - return the PID... + */ + + if (con->username[0]) + cupsdAddCert(pid, con->username, ccache); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "[CGI] Started %s (PID %d)", command, pid); + + *outfile = fds[0]; + close(fds[1]); + } + + return (pid); +} + + +/* + * 'valid_host()' - Is the Host: field valid? + */ + +static int /* O - 1 if valid, 0 if not */ +valid_host(cupsd_client_t *con) /* I - Client connection */ +{ + cupsd_alias_t *a; /* Current alias */ + cupsd_netif_t *netif; /* Current network interface */ + const char *host, /* Host field */ + *end; /* End character */ + + + host = con->http.fields[HTTP_FIELD_HOST]; + + if (httpAddrLocalhost(con->http.hostaddr)) + { + /* + * Only allow "localhost" or the equivalent IPv4 or IPv6 numerical + * addresses when accessing CUPS via the loopback interface... + */ + + return (!strcasecmp(host, "localhost") || + !strncasecmp(host, "localhost:", 10) || + !strcasecmp(host, "localhost.") || + !strncasecmp(host, "localhost.:", 11) || +#ifdef __linux + !strcasecmp(host, "localhost.localdomain") || + !strncasecmp(host, "localhost.localdomain:", 22) || +#endif /* __linux */ + !strcmp(host, "127.0.0.1") || + !strncmp(host, "127.0.0.1:", 10) || + !strcmp(host, "[::1]") || + !strncmp(host, "[::1]:", 6)); + } + +#ifdef HAVE_DNSSD + /* + * Check if the hostname is something.local (Bonjour); if so, allow it. + */ + + if ((end = strrchr(host, '.')) != NULL && + (!strcasecmp(end, ".local") || !strncasecmp(end, ".local:", 7) || + !strcasecmp(end, ".local.") || !strncasecmp(end, ".local.:", 8))) + return (1); +#endif /* HAVE_DNSSD */ + + /* + * Check if the hostname is an IP address... + */ + + if (isdigit(*host & 255) || *host == '[') + { + /* + * Possible IPv4/IPv6 address... + */ + + char temp[1024], /* Temporary string */ + *ptr; /* Pointer into temporary string */ + http_addrlist_t *addrlist; /* List of addresses */ + + + strlcpy(temp, host, sizeof(temp)); + if ((ptr = strrchr(temp, ':')) != NULL && !strchr(ptr, ']')) + *ptr = '\0'; /* Strip :port from host value */ + + if ((addrlist = httpAddrGetList(temp, AF_UNSPEC, NULL)) != NULL) + { + /* + * Good IPv4/IPv6 address... + */ + + httpAddrFreeList(addrlist); + return (1); + } + } + + /* + * Check for (alias) name matches... + */ + + for (a = (cupsd_alias_t *)cupsArrayFirst(ServerAlias); + a; + a = (cupsd_alias_t *)cupsArrayNext(ServerAlias)) + { + /* + * "ServerAlias *" allows all host values through... + */ + + if (!strcmp(a->name, "*")) + return (1); + + if (!strncasecmp(host, a->name, a->namelen)) + { + /* + * Prefix matches; check the character at the end - it must be ":", ".", + * ".:", or nul... + */ + + end = host + a->namelen; + + if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':'))) + return (1); + } + } + +#ifdef HAVE_DNSSD + for (a = (cupsd_alias_t *)cupsArrayFirst(DNSSDAlias); + a; + a = (cupsd_alias_t *)cupsArrayNext(DNSSDAlias)) + { + /* + * "ServerAlias *" allows all host values through... + */ + + if (!strcmp(a->name, "*")) + return (1); + + if (!strncasecmp(host, a->name, a->namelen)) + { + /* + * Prefix matches; check the character at the end - it must be ":", ".", + * ".:", or nul... + */ + + end = host + a->namelen; + + if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':'))) + return (1); + } + } +#endif /* HAVE_DNSSD */ + + /* + * Check for interface hostname matches... + */ + + for (netif = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + netif; + netif = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + { + if (!strncasecmp(host, netif->hostname, netif->hostlen)) + { + /* + * Prefix matches; check the character at the end - it must be ":", ".", + * ".:", or nul... + */ + + end = host + netif->hostlen; + + if (!*end || *end == ':' || (*end == '.' && (!end[1] || end[1] == ':'))) + return (1); + } + } + + return (0); +} + + +/* + * 'write_file()' - Send a file via HTTP. + */ + +static int /* O - 0 on failure, 1 on success */ +write_file(cupsd_client_t *con, /* I - Client connection */ + http_status_t code, /* I - HTTP status */ + char *filename, /* I - Filename */ + char *type, /* I - File type */ + struct stat *filestats) /* O - File information */ +{ + con->file = open(filename, O_RDONLY); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "write_file(con=%p(%d), code=%d, filename=\"%s\" (%d), " + "type=\"%s\", filestats=%p)", con, con->http.fd, + code, filename, con->file, type ? type : "(null)", filestats); + + if (con->file < 0) + return (0); + + fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); + + con->pipe_pid = 0; + + if (!cupsdSendHeader(con, code, type, CUPSD_AUTH_NONE)) + return (0); + + if (httpPrintf(HTTP(con), "Last-Modified: %s\r\n", + httpGetDateString(filestats->st_mtime)) < 0) + return (0); + if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n", + CUPS_LLCAST filestats->st_size) < 0) + return (0); + if (httpPrintf(HTTP(con), "\r\n") < 0) + return (0); + + if (cupsdFlushHeader(con) < 0) + return (0); + + con->http.data_encoding = HTTP_ENCODE_LENGTH; + con->http.data_remaining = filestats->st_size; + + if (con->http.data_remaining <= INT_MAX) + con->http._data_remaining = con->http.data_remaining; + else + con->http._data_remaining = INT_MAX; + + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, + (cupsd_selfunc_t)cupsdWriteClient, con); + + return (1); +} + + +/* + * 'write_pipe()' - Flag that data is available on the CGI pipe. + */ + +static void +write_pipe(cupsd_client_t *con) /* I - Client connection */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "write_pipe(con=%p(%d)) CGI output on fd %d", + con, con->http.fd, con->file); + + con->file_ready = 1; + + cupsdRemoveSelect(con->file); + cupsdAddSelect(con->http.fd, NULL, (cupsd_selfunc_t)cupsdWriteClient, con); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/client.h b/scheduler/client.h new file mode 100644 index 0000000000..f0f56aca10 --- /dev/null +++ b/scheduler/client.h @@ -0,0 +1,140 @@ +/* + * "$Id$" + * + * Client definitions for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifdef HAVE_AUTHORIZATION_H +# include +#endif /* HAVE_AUTHORIZATION_H */ + + +/* + * HTTP client structure... + */ + +struct cupsd_client_s +{ + http_t http; /* HTTP client connection */ + ipp_t *request, /* IPP request information */ + *response; /* IPP response information */ + cupsd_location_t *best; /* Best match for AAA */ + struct timeval start; /* Request start time */ + http_state_t operation; /* Request operation */ + off_t bytes; /* Bytes transferred for this request */ + int type; /* AuthType for username */ + char username[256], /* Username from Authorization: line */ + password[33], /* Password from Authorization: line */ + uri[HTTP_MAX_URI], + /* Localized URL/URI for GET/PUT */ + *filename, /* Filename of output file */ + *command, /* Command to run */ + *options, /* Options for command */ + *query_string; /* QUERY_STRING environment variable */ + int file; /* Input/output file */ + int file_ready; /* Input ready on file/pipe? */ + int pipe_pid; /* Pipe process ID (or 0 if not a pipe) */ + int sent_header, /* Non-zero if sent HTTP header */ + got_fields, /* Non-zero if all fields seen */ + header_used; /* Number of header bytes used */ + char header[2048]; /* Header from CGI program */ + cups_lang_t *language; /* Language to use */ +#ifdef HAVE_SSL + int auto_ssl; /* Automatic test for SSL/TLS */ +#endif /* HAVE_SSL */ + http_addr_t clientaddr; /* Client address */ + char servername[256];/* Server name for connection */ + int serverport; /* Server port for connection */ +#ifdef HAVE_GSSAPI + int have_gss; /* Have GSS credentials? */ + gss_cred_id_t gss_creds; /* Delegated credentials from client */ + unsigned gss_flags; /* Credential flags */ + gss_buffer_desc gss_output_token; + /* Output token for Negotiate header */ +#endif /* HAVE_GSSAPI */ +#ifdef HAVE_AUTHORIZATION_H + AuthorizationRef authref; /* Authorization ref */ +#endif /* HAVE_AUTHORIZATION_H */ +}; + +#define HTTP(con) &((con)->http) + + +/* + * HTTP listener structure... + */ + +typedef struct +{ + int fd; /* File descriptor for this server */ + http_addr_t address; /* Bind address of socket */ + http_encryption_t encryption; /* To encrypt or not to encrypt... */ +} cupsd_listener_t; + + +/* + * Globals... + */ + +VAR int ListenBackLog VALUE(SOMAXCONN), + /* Max backlog of pending connections */ + LocalPort VALUE(631), + /* Local port to use */ + RemotePort VALUE(0); + /* Remote port to use */ +VAR http_encryption_t LocalEncryption VALUE(HTTP_ENCRYPT_IF_REQUESTED); + /* Local port encryption to use */ +VAR cups_array_t *Listeners VALUE(NULL); + /* Listening sockets */ +VAR time_t ListeningPaused VALUE(0); + /* Time when listening was paused */ +VAR cups_array_t *Clients VALUE(NULL), + /* HTTP clients */ + *ActiveClients VALUE(NULL); + /* Active HTTP clients */ +VAR char *ServerHeader VALUE(NULL); + /* Server header in requests */ +VAR int CGIPipes[2] VALUE2(-1,-1); + /* Pipes for CGI error/debug output */ +VAR cupsd_statbuf_t *CGIStatusBuffer VALUE(NULL); + /* Status buffer for pipes */ + + +/* + * Prototypes... + */ + +extern void cupsdAcceptClient(cupsd_listener_t *lis); +extern void cupsdCloseAllClients(void); +extern int cupsdCloseClient(cupsd_client_t *con); +extern void cupsdDeleteAllListeners(void); +extern int cupsdFlushHeader(cupsd_client_t *con); +extern void cupsdPauseListening(void); +extern int cupsdProcessIPPRequest(cupsd_client_t *con); +extern void cupsdReadClient(cupsd_client_t *con); +extern void cupsdResumeListening(void); +extern int cupsdSendCommand(cupsd_client_t *con, char *command, + char *options, int root); +extern int cupsdSendError(cupsd_client_t *con, http_status_t code, + int auth_type); +extern int cupsdSendHeader(cupsd_client_t *con, http_status_t code, + char *type, int auth_type); +extern void cupsdShutdownClient(cupsd_client_t *con); +extern void cupsdStartListening(void); +extern void cupsdStopListening(void); +extern void cupsdUpdateCGI(void); +extern void cupsdWriteClient(cupsd_client_t *con); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/conf.c b/scheduler/conf.c new file mode 100644 index 0000000000..c607404bff --- /dev/null +++ b/scheduler/conf.c @@ -0,0 +1,3863 @@ +/* + * "$Id$" + * + * Configuration routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddAlias() - Add a host alias. + * cupsdCheckPermissions() - Fix the mode and ownership of a file or + * directory. + * cupsdFreeAliases() - Free all of the alias entries. + * cupsdReadConfiguration() - Read the cupsd.conf file. + * get_address() - Get an address + port number from a line. + * get_addr_and_mask() - Get an IP address and netmask. + * parse_aaa() - Parse authentication, authorization, and access + * control lines. + * parse_fatal_errors() - Parse FatalErrors values in a string. + * parse_groups() - Parse system group names in a string. + * parse_protocols() - Parse browse protocols in a string. + * read_configuration() - Read a configuration file. + * read_location() - Read a definition. + * read_policy() - Read a definition. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include +#include +#include +#include + +#ifdef HAVE_LIBPAPER +# include +#endif /* HAVE_LIBPAPER */ + + +/* + * Possibly missing network definitions... + */ + +#ifndef INADDR_NONE +# define INADDR_NONE 0xffffffff +#endif /* !INADDR_NONE */ + + +/* + * Configuration variable structure... + */ + +typedef enum +{ + CUPSD_VARTYPE_INTEGER, /* Integer option */ + CUPSD_VARTYPE_STRING, /* String option */ + CUPSD_VARTYPE_BOOLEAN, /* Boolean option */ + CUPSD_VARTYPE_PATHNAME /* File/directory name option */ +} cupsd_vartype_t; + +typedef struct +{ + char *name; /* Name of variable */ + void *ptr; /* Pointer to variable */ + cupsd_vartype_t type; /* Type (int, string, address) */ +} cupsd_var_t; + + +/* + * Local globals... + */ + +static const cupsd_var_t variables[] = +{ + { "AccessLog", &AccessLog, CUPSD_VARTYPE_STRING }, +#ifdef __APPLE__ + { "AppleQuotas", &AppleQuotas, CUPSD_VARTYPE_BOOLEAN }, +#endif /* __APPLE__ */ + { "AutoPurgeJobs", &JobAutoPurge, CUPSD_VARTYPE_BOOLEAN }, + { "BrowseInterval", &BrowseInterval, CUPSD_VARTYPE_INTEGER }, +#ifdef HAVE_LDAP + { "BrowseLDAPBindDN", &BrowseLDAPBindDN, CUPSD_VARTYPE_STRING }, +# ifdef HAVE_LDAP_SSL + { "BrowseLDAPCACertFile", &BrowseLDAPCACertFile, CUPSD_VARTYPE_PATHNAME }, +# endif /* HAVE_LDAP_SSL */ + { "BrowseLDAPDN", &BrowseLDAPDN, CUPSD_VARTYPE_STRING }, + { "BrowseLDAPPassword", &BrowseLDAPPassword, CUPSD_VARTYPE_STRING }, + { "BrowseLDAPServer", &BrowseLDAPServer, CUPSD_VARTYPE_STRING }, +#endif /* HAVE_LDAP */ + { "BrowseLocalOptions", &BrowseLocalOptions, CUPSD_VARTYPE_STRING }, + { "BrowsePort", &BrowsePort, CUPSD_VARTYPE_INTEGER }, + { "BrowseRemoteOptions", &BrowseRemoteOptions, CUPSD_VARTYPE_STRING }, + { "BrowseShortNames", &BrowseShortNames, CUPSD_VARTYPE_BOOLEAN }, + { "BrowseTimeout", &BrowseTimeout, CUPSD_VARTYPE_INTEGER }, + { "BrowseWebIF", &BrowseWebIF, CUPSD_VARTYPE_BOOLEAN }, + { "Browsing", &Browsing, CUPSD_VARTYPE_BOOLEAN }, + { "CacheDir", &CacheDir, CUPSD_VARTYPE_STRING }, + { "Classification", &Classification, CUPSD_VARTYPE_STRING }, + { "ClassifyOverride", &ClassifyOverride, CUPSD_VARTYPE_BOOLEAN }, + { "ConfigFilePerm", &ConfigFilePerm, CUPSD_VARTYPE_INTEGER }, + { "DataDir", &DataDir, CUPSD_VARTYPE_STRING }, + { "DefaultLanguage", &DefaultLanguage, CUPSD_VARTYPE_STRING }, + { "DefaultLeaseDuration", &DefaultLeaseDuration, CUPSD_VARTYPE_INTEGER }, + { "DefaultPaperSize", &DefaultPaperSize, CUPSD_VARTYPE_STRING }, + { "DefaultPolicy", &DefaultPolicy, CUPSD_VARTYPE_STRING }, + { "DefaultShared", &DefaultShared, CUPSD_VARTYPE_BOOLEAN }, + { "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_INTEGER }, + { "DocumentRoot", &DocumentRoot, CUPSD_VARTYPE_STRING }, + { "ErrorLog", &ErrorLog, CUPSD_VARTYPE_STRING }, + { "ErrorPolicy", &ErrorPolicy, CUPSD_VARTYPE_STRING }, + { "FileDevice", &FileDevice, CUPSD_VARTYPE_BOOLEAN }, + { "FilterLimit", &FilterLimit, CUPSD_VARTYPE_INTEGER }, + { "FilterNice", &FilterNice, CUPSD_VARTYPE_INTEGER }, + { "FontPath", &FontPath, CUPSD_VARTYPE_STRING }, + { "HideImplicitMembers", &HideImplicitMembers, CUPSD_VARTYPE_BOOLEAN }, + { "ImplicitClasses", &ImplicitClasses, CUPSD_VARTYPE_BOOLEAN }, + { "ImplicitAnyClasses", &ImplicitAnyClasses, CUPSD_VARTYPE_BOOLEAN }, + { "JobKillDelay", &JobKillDelay, CUPSD_VARTYPE_INTEGER }, + { "JobRetryLimit", &JobRetryLimit, CUPSD_VARTYPE_INTEGER }, + { "JobRetryInterval", &JobRetryInterval, CUPSD_VARTYPE_INTEGER }, + { "KeepAliveTimeout", &KeepAliveTimeout, CUPSD_VARTYPE_INTEGER }, + { "KeepAlive", &KeepAlive, CUPSD_VARTYPE_BOOLEAN }, +#ifdef HAVE_LAUNCHD + { "LaunchdTimeout", &LaunchdTimeout, CUPSD_VARTYPE_INTEGER }, +#endif /* HAVE_LAUNCHD */ + { "LimitRequestBody", &MaxRequestSize, CUPSD_VARTYPE_INTEGER }, + { "ListenBackLog", &ListenBackLog, CUPSD_VARTYPE_INTEGER }, + { "LogDebugHistory", &LogDebugHistory, CUPSD_VARTYPE_INTEGER }, + { "LogFilePerm", &LogFilePerm, CUPSD_VARTYPE_INTEGER }, + { "LPDConfigFile", &LPDConfigFile, CUPSD_VARTYPE_STRING }, + { "MaxActiveJobs", &MaxActiveJobs, CUPSD_VARTYPE_INTEGER }, + { "MaxClients", &MaxClients, CUPSD_VARTYPE_INTEGER }, + { "MaxClientsPerHost", &MaxClientsPerHost, CUPSD_VARTYPE_INTEGER }, + { "MaxCopies", &MaxCopies, CUPSD_VARTYPE_INTEGER }, + { "MaxEvents", &MaxEvents, CUPSD_VARTYPE_INTEGER }, + { "MaxJobs", &MaxJobs, CUPSD_VARTYPE_INTEGER }, + { "MaxJobsPerPrinter", &MaxJobsPerPrinter, CUPSD_VARTYPE_INTEGER }, + { "MaxJobsPerUser", &MaxJobsPerUser, CUPSD_VARTYPE_INTEGER }, + { "MaxLeaseDuration", &MaxLeaseDuration, CUPSD_VARTYPE_INTEGER }, + { "MaxLogSize", &MaxLogSize, CUPSD_VARTYPE_INTEGER }, + { "MaxPrinterHistory", &MaxPrinterHistory, CUPSD_VARTYPE_INTEGER }, + { "MaxRequestSize", &MaxRequestSize, CUPSD_VARTYPE_INTEGER }, + { "MaxSubscriptions", &MaxSubscriptions, CUPSD_VARTYPE_INTEGER }, + { "MaxSubscriptionsPerJob", &MaxSubscriptionsPerJob, CUPSD_VARTYPE_INTEGER }, + { "MaxSubscriptionsPerPrinter",&MaxSubscriptionsPerPrinter, CUPSD_VARTYPE_INTEGER }, + { "MaxSubscriptionsPerUser", &MaxSubscriptionsPerUser, CUPSD_VARTYPE_INTEGER }, + { "MultipleOperationTimeout", &MultipleOperationTimeout, CUPSD_VARTYPE_INTEGER }, + { "PageLog", &PageLog, CUPSD_VARTYPE_STRING }, + { "PageLogFormat", &PageLogFormat, CUPSD_VARTYPE_STRING }, + { "PreserveJobFiles", &JobFiles, CUPSD_VARTYPE_BOOLEAN }, + { "PreserveJobHistory", &JobHistory, CUPSD_VARTYPE_BOOLEAN }, + { "Printcap", &Printcap, CUPSD_VARTYPE_STRING }, + { "PrintcapGUI", &PrintcapGUI, CUPSD_VARTYPE_STRING }, + { "ReloadTimeout", &ReloadTimeout, CUPSD_VARTYPE_INTEGER }, + { "RemoteRoot", &RemoteRoot, CUPSD_VARTYPE_STRING }, + { "RequestRoot", &RequestRoot, CUPSD_VARTYPE_STRING }, + { "RIPCache", &RIPCache, CUPSD_VARTYPE_STRING }, + { "RootCertDuration", &RootCertDuration, CUPSD_VARTYPE_INTEGER }, + { "ServerAdmin", &ServerAdmin, CUPSD_VARTYPE_STRING }, + { "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME }, +#ifdef HAVE_SSL + { "ServerCertificate", &ServerCertificate, CUPSD_VARTYPE_PATHNAME }, +# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) + { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME }, +# endif /* HAVE_LIBSSL || HAVE_GNUTLS */ +#endif /* HAVE_SSL */ + { "ServerName", &ServerName, CUPSD_VARTYPE_STRING }, + { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME }, + { "SMBConfigFile", &SMBConfigFile, CUPSD_VARTYPE_STRING }, + { "StateDir", &StateDir, CUPSD_VARTYPE_STRING }, +#ifdef HAVE_AUTHORIZATION_H + { "SystemGroupAuthKey", &SystemGroupAuthKey, CUPSD_VARTYPE_STRING }, +#endif /* HAVE_AUTHORIZATION_H */ + { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME }, + { "Timeout", &Timeout, CUPSD_VARTYPE_INTEGER }, + { "UseNetworkDefault", &UseNetworkDefault, CUPSD_VARTYPE_BOOLEAN } +}; +#define NUM_VARS (sizeof(variables) / sizeof(variables[0])) + + +static const unsigned ones[4] = + { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff + }; +static const unsigned zeros[4] = + { + 0x00000000, 0x00000000, 0x00000000, 0x00000000 + }; + + +/* + * Local functions... + */ + +static http_addrlist_t *get_address(const char *value, int defport); +static int get_addr_and_mask(const char *value, unsigned *ip, + unsigned *mask); +static int parse_aaa(cupsd_location_t *loc, char *line, + char *value, int linenum); +static int parse_fatal_errors(const char *s); +static int parse_groups(const char *s); +static int parse_protocols(const char *s); +static int read_configuration(cups_file_t *fp); +static int read_location(cups_file_t *fp, char *name, int linenum); +static int read_policy(cups_file_t *fp, char *name, int linenum); + + +/* + * 'cupsdAddAlias()' - Add a host alias. + */ + +void +cupsdAddAlias(cups_array_t *aliases, /* I - Array of aliases */ + const char *name) /* I - Name to add */ +{ + cupsd_alias_t *a; /* New alias */ + size_t namelen; /* Length of name */ + + + namelen = strlen(name); + + if ((a = (cupsd_alias_t *)malloc(sizeof(cupsd_alias_t) + namelen)) == NULL) + return; + + a->namelen = namelen; + strcpy(a->name, name); /* OK since a->name is allocated */ + + cupsArrayAdd(aliases, a); +} + + +/* + * 'cupsdCheckPermissions()' - Fix the mode and ownership of a file or directory. + */ + +int /* O - 0 on success, -1 on error, 1 on warning */ +cupsdCheckPermissions( + const char *filename, /* I - File/directory name */ + const char *suffix, /* I - Additional file/directory name */ + int mode, /* I - Permissions */ + int user, /* I - Owner */ + int group, /* I - Group */ + int is_dir, /* I - 1 = directory, 0 = file */ + int create_dir) /* I - 1 = create directory, -1 = create w/o logging, 0 = not */ +{ + int dir_created = 0; /* Did we create a directory? */ + char pathname[1024]; /* File name with prefix */ + struct stat fileinfo; /* Stat buffer */ + int is_symlink; /* Is "filename" a symlink? */ + + + /* + * Prepend the given root to the filename before testing it... + */ + + if (suffix) + { + snprintf(pathname, sizeof(pathname), "%s/%s", filename, suffix); + filename = pathname; + } + + /* + * See if we can stat the file/directory... + */ + + if (lstat(filename, &fileinfo)) + { + if (errno == ENOENT && create_dir) + { + if (create_dir > 0) + cupsdLogMessage(CUPSD_LOG_DEBUG, "Creating missing directory \"%s\"", + filename); + + if (mkdir(filename, mode)) + { + if (create_dir > 0) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create directory \"%s\" - %s", filename, + strerror(errno)); + else + syslog(LOG_ERR, "Unable to create directory \"%s\" - %s", filename, + strerror(errno)); + + return (-1); + } + + dir_created = 1; + fileinfo.st_mode = mode | S_IFDIR; + } + else + return (create_dir ? -1 : 1); + } + + if ((is_symlink = S_ISLNK(fileinfo.st_mode)) != 0) + { + if (stat(filename, &fileinfo)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is a bad symlink - %s", + filename, strerror(errno)); + return (-1); + } + } + + /* + * Make sure it's a regular file or a directory as needed... + */ + + if (!dir_created && !is_dir && !S_ISREG(fileinfo.st_mode)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a regular file!", filename); + return (-1); + } + + if (!dir_created && is_dir && !S_ISDIR(fileinfo.st_mode)) + { + if (create_dir >= 0) + cupsdLogMessage(CUPSD_LOG_ERROR, "\"%s\" is not a directory!", filename); + else + syslog(LOG_ERR, "\"%s\" is not a directory!", filename); + + return (-1); + } + + /* + * If the filename is a symlink, do not change permissions (STR #2937)... + */ + + if (is_symlink) + return (0); + + /* + * Fix owner, group, and mode as needed... + */ + + if (dir_created || fileinfo.st_uid != user || fileinfo.st_gid != group) + { + if (create_dir >= 0) + cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing ownership of \"%s\"", + filename); + + if (chown(filename, user, group) && !getuid()) + { + if (create_dir >= 0) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to change ownership of \"%s\" - %s", filename, + strerror(errno)); + else + syslog(LOG_ERR, "Unable to change ownership of \"%s\" - %s", filename, + strerror(errno)); + + return (1); + } + } + + if (dir_created || (fileinfo.st_mode & 07777) != mode) + { + if (create_dir >= 0) + cupsdLogMessage(CUPSD_LOG_DEBUG, "Repairing access permissions of \"%s\"", + filename); + + if (chmod(filename, mode)) + { + if (create_dir >= 0) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to change permissions of \"%s\" - %s", filename, + strerror(errno)); + else + syslog(LOG_ERR, "Unable to change permissions of \"%s\" - %s", filename, + strerror(errno)); + + return (1); + } + } + + /* + * Everything is OK... + */ + + return (0); +} + + +/* + * 'cupsdFreeAliases()' - Free all of the alias entries. + */ + +void +cupsdFreeAliases(cups_array_t *aliases) /* I - Array of aliases */ +{ + cupsd_alias_t *a; /* Current alias */ + + + for (a = (cupsd_alias_t *)cupsArrayFirst(aliases); + a; + a = (cupsd_alias_t *)cupsArrayNext(aliases)) + free(a); + + cupsArrayDelete(aliases); +} + + +/* + * 'cupsdReadConfiguration()' - Read the cupsd.conf file. + */ + +int /* O - 1 on success, 0 otherwise */ +cupsdReadConfiguration(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* Configuration file */ + int status; /* Return status */ + char temp[1024], /* Temporary buffer */ + mimedir[1024], /* MIME directory */ + *slash; /* Directory separator */ + cups_lang_t *language; /* Language */ + struct passwd *user; /* Default user */ + struct group *group; /* Default group */ + char *old_serverroot, /* Old ServerRoot */ + *old_requestroot; /* Old RequestRoot */ + int old_remote_port; /* Old RemotePort */ + const char *tmpdir; /* TMPDIR environment variable */ + struct stat tmpinfo; /* Temporary directory info */ + cupsd_policy_t *p; /* Policy */ + + + /* + * Save the old root paths... + */ + + old_serverroot = NULL; + cupsdSetString(&old_serverroot, ServerRoot); + old_requestroot = NULL; + cupsdSetString(&old_requestroot, RequestRoot); + + /* + * Reset the server configuration data... + */ + + cupsdDeleteAllLocations(); + + if (NumBrowsers > 0) + { + free(Browsers); + Browsers = NULL; + + NumBrowsers = 0; + } + + if (NumPolled > 0) + { + free(Polled); + + NumPolled = 0; + } + + if (NumRelays > 0) + { + for (i = 0; i < NumRelays; i ++) + if (Relays[i].from.type == CUPSD_AUTH_NAME) + free(Relays[i].from.mask.name.name); + + free(Relays); + + NumRelays = 0; + } + + cupsdDeleteAllListeners(); + + old_remote_port = RemotePort; + RemotePort = 0; + + /* + * String options... + */ + + cupsdFreeAliases(ServerAlias); + ServerAlias = NULL; + + cupsdClearString(&ServerName); + cupsdClearString(&ServerAdmin); + cupsdSetString(&ServerBin, CUPS_SERVERBIN); + cupsdSetString(&RequestRoot, CUPS_REQUESTS); + cupsdSetString(&CacheDir, CUPS_CACHEDIR); + cupsdSetString(&DataDir, CUPS_DATADIR); + cupsdSetString(&DocumentRoot, CUPS_DOCROOT); + cupsdSetString(&AccessLog, CUPS_LOGDIR "/access_log"); + cupsdSetString(&ErrorLog, CUPS_LOGDIR "/error_log"); + cupsdSetString(&PageLog, CUPS_LOGDIR "/page_log"); + cupsdSetString(&PageLogFormat, + "%p %u %j %T %P %C %{job-billing} " + "%{job-originating-host-name} %{job-name} %{media} %{sides}"); + cupsdSetString(&Printcap, CUPS_DEFAULT_PRINTCAP); + cupsdSetString(&PrintcapGUI, "/usr/bin/glpoptions"); + cupsdSetString(&FontPath, CUPS_FONTPATH); + cupsdSetString(&RemoteRoot, "remroot"); + cupsdSetString(&ServerHeader, "CUPS/1.4"); + cupsdSetString(&StateDir, CUPS_STATEDIR); + + if (!strcmp(CUPS_DEFAULT_PRINTCAP, "/etc/printers.conf")) + PrintcapFormat = PRINTCAP_SOLARIS; + else if (!strcmp(CUPS_DEFAULT_PRINTCAP, + "/Library/Preferences/org.cups.printers.plist")) + PrintcapFormat = PRINTCAP_PLIST; + else + PrintcapFormat = PRINTCAP_BSD; + + strlcpy(temp, ConfigurationFile, sizeof(temp)); + if ((slash = strrchr(temp, '/')) != NULL) + *slash = '\0'; + + cupsdSetString(&ServerRoot, temp); + + cupsdClearString(&Classification); + ClassifyOverride = 0; + +#ifdef HAVE_SSL +# ifdef HAVE_CDSASSL + cupsdSetString(&ServerCertificate, "/Library/Keychains/System.keychain"); +# else + cupsdSetString(&ServerCertificate, "ssl/server.crt"); + cupsdSetString(&ServerKey, "ssl/server.key"); +# endif /* HAVE_CDSASSL */ +#endif /* HAVE_SSL */ + + language = cupsLangDefault(); + + if (!strcmp(language->language, "C") || !strcmp(language->language, "POSIX")) + cupsdSetString(&DefaultLanguage, "en"); + else + cupsdSetString(&DefaultLanguage, language->language); + + cupsdClearString(&DefaultPaperSize); + + cupsdSetString(&RIPCache, "8m"); + + cupsdSetString(&TempDir, NULL); + + /* + * Find the default user... + */ + + if ((user = getpwnam(CUPS_DEFAULT_USER)) != NULL) + User = user->pw_uid; + else + { + /* + * Use the (historical) NFS nobody user ID (-2 as a 16-bit twos- + * complement number...) + */ + + User = 65534; + } + + endpwent(); + + /* + * Find the default group... + */ + + group = getgrnam(CUPS_DEFAULT_GROUP); + endgrent(); + + if (group) + Group = group->gr_gid; + else + { + /* + * Fallback to group "nobody"... + */ + + group = getgrnam("nobody"); + endgrent(); + + if (group) + Group = group->gr_gid; + else + { + /* + * Use the (historical) NFS nobody group ID (-2 as a 16-bit twos- + * complement number...) + */ + + Group = 65534; + } + } + + /* + * Numeric options... + */ + + AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS; + ConfigFilePerm = CUPS_DEFAULT_CONFIG_FILE_PERM; + FatalErrors = parse_fatal_errors(CUPS_DEFAULT_FATAL_ERRORS); + DefaultAuthType = CUPSD_AUTH_BASIC; +#ifdef HAVE_SSL + DefaultEncryption = HTTP_ENCRYPT_REQUIRED; + SSLOptions = CUPSD_SSL_NONE; +#endif /* HAVE_SSL */ + DirtyCleanInterval = DEFAULT_KEEPALIVE; + JobKillDelay = DEFAULT_TIMEOUT; + JobRetryLimit = 5; + JobRetryInterval = 300; + FileDevice = FALSE; + FilterLevel = 0; + FilterLimit = 0; + FilterNice = 0; + HostNameLookups = FALSE; + ImplicitClasses = CUPS_DEFAULT_IMPLICIT_CLASSES; + ImplicitAnyClasses = FALSE; + HideImplicitMembers = TRUE; + KeepAlive = TRUE; + KeepAliveTimeout = DEFAULT_KEEPALIVE; + ListenBackLog = SOMAXCONN; + LogDebugHistory = 200; + LogFilePerm = CUPS_DEFAULT_LOG_FILE_PERM; + LogLevel = CUPSD_LOG_WARN; + LogTimeFormat = CUPSD_TIME_STANDARD; + MaxClients = 100; + MaxClientsPerHost = 0; + MaxLogSize = 1024 * 1024; + MaxPrinterHistory = 0; + MaxRequestSize = 0; + MultipleOperationTimeout = DEFAULT_TIMEOUT; + ReloadTimeout = DEFAULT_KEEPALIVE; + RootCertDuration = 300; + Timeout = DEFAULT_TIMEOUT; + NumSystemGroups = 0; + + BrowseInterval = DEFAULT_INTERVAL; + BrowsePort = ippPort(); + BrowseLocalProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS); + BrowseRemoteProtocols = parse_protocols(CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS); + BrowseShortNames = CUPS_DEFAULT_BROWSE_SHORT_NAMES; + BrowseTimeout = DEFAULT_TIMEOUT; + BrowseWebIF = FALSE; + Browsing = CUPS_DEFAULT_BROWSING; + DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED; + + cupsdSetString(&LPDConfigFile, CUPS_DEFAULT_LPD_CONFIG_FILE); + cupsdSetString(&SMBConfigFile, CUPS_DEFAULT_SMB_CONFIG_FILE); + + cupsdClearString(&BrowseLocalOptions); + cupsdClearString(&BrowseRemoteOptions); + + cupsdSetString(&ErrorPolicy, "stop-printer"); + +#ifdef HAVE_LDAP + cupsdClearString(&BrowseLDAPBindDN); + cupsdClearString(&BrowseLDAPDN); + cupsdClearString(&BrowseLDAPPassword); + cupsdClearString(&BrowseLDAPServer); +# ifdef HAVE_LDAP_SSL + cupsdClearString(&BrowseLDAPCACertFile); +# endif /* HAVE_LDAP_SSL */ +#endif /* HAVE_LDAP */ + + JobHistory = DEFAULT_HISTORY; + JobFiles = DEFAULT_FILES; + JobAutoPurge = 0; + MaxJobs = 500; + MaxActiveJobs = 0; + MaxJobsPerUser = 0; + MaxJobsPerPrinter = 0; + MaxCopies = CUPS_DEFAULT_MAX_COPIES; + + cupsdDeleteAllPolicies(); + cupsdClearString(&DefaultPolicy); + +#ifdef HAVE_AUTHORIZATION_H + cupsdClearString(&SystemGroupAuthKey); +#endif /* HAVE_AUTHORIZATION_H */ + + MaxSubscriptions = 100; + MaxSubscriptionsPerJob = 0; + MaxSubscriptionsPerPrinter = 0; + MaxSubscriptionsPerUser = 0; + DefaultLeaseDuration = 86400; + MaxLeaseDuration = 0; + +#ifdef HAVE_LAUNCHD + LaunchdTimeout = DEFAULT_TIMEOUT + 10; +#endif /* HAVE_LAUNCHD */ + +#ifdef __APPLE__ + AppleQuotas = TRUE; +#endif /* __APPLE__ */ + + /* + * Setup environment variables... + */ + + cupsdInitEnv(); + + /* + * Read the configuration file... + */ + + if ((fp = cupsFileOpen(ConfigurationFile, "r")) == NULL) + return (0); + + status = read_configuration(fp); + + cupsFileClose(fp); + + if (!status) + return (0); + + RunUser = getuid(); + + cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.", + RemotePort ? "enabled" : "disabled"); + + if (!RemotePort) + BrowseLocalProtocols = 0; /* Disable sharing - no remote access */ + + /* + * See if the ServerName is an IP address... + */ + + if (ServerName) + { + if (!ServerAlias) + ServerAlias = cupsArrayNew(NULL, NULL); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", ServerName); + } + else + { + if (gethostname(temp, sizeof(temp))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to get hostname: %s", + strerror(errno)); + strlcpy(temp, "localhost", sizeof(temp)); + } + + cupsdSetString(&ServerName, temp); + + if (!ServerAlias) + ServerAlias = cupsArrayNew(NULL, NULL); + + cupsdAddAlias(ServerAlias, temp); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp); + + if (HostNameLookups || RemotePort) + { + struct hostent *host; /* Host entry to get FQDN */ + + if ((host = gethostbyname(temp)) != NULL) + { + if (strcasecmp(temp, host->h_name)) + { + cupsdSetString(&ServerName, host->h_name); + cupsdAddAlias(ServerAlias, host->h_name); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", + host->h_name); + } + + if (host->h_aliases) + { + for (i = 0; host->h_aliases[i]; i ++) + if (strcasecmp(temp, host->h_aliases[i])) + { + cupsdAddAlias(ServerAlias, host->h_aliases[i]); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", + host->h_aliases[i]); + } + } + } + } + + /* + * Make sure we have the base hostname added as an alias, too! + */ + + if ((slash = strchr(temp, '.')) != NULL) + { + *slash = '\0'; + cupsdAddAlias(ServerAlias, temp); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added auto ServerAlias %s", temp); + } + } + + for (slash = ServerName; isdigit(*slash & 255) || *slash == '.'; slash ++); + + ServerNameIsIP = !*slash; + + /* + * Make sure ServerAdmin is initialized... + */ + + if (!ServerAdmin) + cupsdSetStringf(&ServerAdmin, "root@%s", ServerName); + + /* + * Use the default system group if none was supplied in cupsd.conf... + */ + + if (NumSystemGroups == 0) + { + if (!parse_groups(CUPS_DEFAULT_SYSTEM_GROUPS)) + { + /* + * Find the group associated with GID 0... + */ + + group = getgrgid(0); + endgrent(); + + if (group != NULL) + cupsdSetString(&SystemGroups[0], group->gr_name); + else + cupsdSetString(&SystemGroups[0], "unknown"); + + SystemGroupIDs[0] = 0; + NumSystemGroups = 1; + } + } + + /* + * Get the access control list for browsing... + */ + + BrowseACL = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL"); + + /* + * Open the system log for cupsd if necessary... + */ + +#ifdef HAVE_VSYSLOG + if (!strcmp(AccessLog, "syslog") || + !strcmp(ErrorLog, "syslog") || + !strcmp(PageLog, "syslog")) + openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR); +#endif /* HAVE_VSYSLOG */ + + /* + * Log the configuration file that was used... + */ + + cupsdLogMessage(CUPSD_LOG_INFO, "Loaded configuration file \"%s\"", + ConfigurationFile); + + /* + * Validate the Group and SystemGroup settings - they cannot be the same, + * otherwise the CGI programs will be able to authenticate as root without + * a password! + */ + + if (!RunUser) + { + for (i = 0; i < NumSystemGroups; i ++) + if (Group == SystemGroupIDs[i]) + break; + + if (i < NumSystemGroups) + { + /* + * Log the error and reset the group to a safe value... + */ + + cupsdLogMessage(CUPSD_LOG_NOTICE, + "Group and SystemGroup cannot use the same groups!"); + cupsdLogMessage(CUPSD_LOG_INFO, "Resetting Group to \"nobody\"..."); + + group = getgrnam("nobody"); + endgrent(); + + if (group != NULL) + Group = group->gr_gid; + else + { + /* + * Use the (historical) NFS nobody group ID (-2 as a 16-bit twos- + * complement number...) + */ + + Group = 65534; + } + } + } + + /* + * Check that we have at least one listen/port line; if not, report this + * as an error and exit! + */ + + if (cupsArrayCount(Listeners) == 0) + { + /* + * No listeners! + */ + + cupsdLogMessage(CUPSD_LOG_EMERG, + "No valid Listen or Port lines were found in the " + "configuration file!"); + + /* + * Commit suicide... + */ + + cupsdEndProcess(getpid(), 0); + } + + /* + * Set the default locale using the language and charset... + */ + + cupsdSetStringf(&DefaultLocale, "%s.UTF-8", DefaultLanguage); + + /* + * Update all relative filenames to include the full path from ServerRoot... + */ + + if (DocumentRoot[0] != '/') + cupsdSetStringf(&DocumentRoot, "%s/%s", ServerRoot, DocumentRoot); + + if (RequestRoot[0] != '/') + cupsdSetStringf(&RequestRoot, "%s/%s", ServerRoot, RequestRoot); + + if (ServerBin[0] != '/') + cupsdSetStringf(&ServerBin, "%s/%s", ServerRoot, ServerBin); + + if (StateDir[0] != '/') + cupsdSetStringf(&StateDir, "%s/%s", ServerRoot, StateDir); + + if (CacheDir[0] != '/') + cupsdSetStringf(&CacheDir, "%s/%s", ServerRoot, CacheDir); + +#ifdef HAVE_SSL + if (ServerCertificate[0] != '/') + cupsdSetStringf(&ServerCertificate, "%s/%s", ServerRoot, ServerCertificate); + + if (!strncmp(ServerRoot, ServerCertificate, strlen(ServerRoot)) && + cupsdCheckPermissions(ServerCertificate, NULL, 0600, RunUser, Group, + 0, 0) < 0 && + (FatalErrors & CUPSD_FATAL_PERMISSIONS)) + return (0); + +# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) + if (ServerKey[0] != '/') + cupsdSetStringf(&ServerKey, "%s/%s", ServerRoot, ServerKey); + + if (!strncmp(ServerRoot, ServerKey, strlen(ServerRoot)) && + cupsdCheckPermissions(ServerKey, NULL, 0600, RunUser, Group, 0, 0) < 0 && + (FatalErrors & CUPSD_FATAL_PERMISSIONS)) + return (0); +# endif /* HAVE_LIBSSL || HAVE_GNUTLS */ +#endif /* HAVE_SSL */ + + /* + * Make sure that directories and config files are owned and + * writable by the user and group in the cupsd.conf file... + */ + + snprintf(temp, sizeof(temp), "%s/rss", CacheDir); + + if ((cupsdCheckPermissions(RequestRoot, NULL, 0710, RunUser, + Group, 1, 1) < 0 || + cupsdCheckPermissions(CacheDir, NULL, 0775, RunUser, + Group, 1, 1) < 0 || + cupsdCheckPermissions(temp, NULL, 0775, RunUser, + Group, 1, 1) < 0 || + cupsdCheckPermissions(StateDir, NULL, 0755, RunUser, + Group, 1, 1) < 0 || + cupsdCheckPermissions(StateDir, "certs", RunUser ? 0711 : 0511, User, + SystemGroupIDs[0], 1, 1) < 0 || + cupsdCheckPermissions(ServerRoot, NULL, 0755, RunUser, + Group, 1, 0) < 0 || + cupsdCheckPermissions(ServerRoot, "ppd", 0755, RunUser, + Group, 1, 1) < 0 || + cupsdCheckPermissions(ServerRoot, "ssl", 0700, RunUser, + Group, 1, 0) < 0 || + cupsdCheckPermissions(ServerRoot, "cupsd.conf", ConfigFilePerm, RunUser, + Group, 0, 0) < 0 || + cupsdCheckPermissions(ServerRoot, "classes.conf", 0600, RunUser, + Group, 0, 0) < 0 || + cupsdCheckPermissions(ServerRoot, "printers.conf", 0600, RunUser, + Group, 0, 0) < 0 || + cupsdCheckPermissions(ServerRoot, "passwd.md5", 0600, User, + Group, 0, 0) < 0) && + (FatalErrors & CUPSD_FATAL_PERMISSIONS)) + return (0); + + /* + * Update TempDir to the default if it hasn't been set already... + */ + + if (!TempDir) + { + if ((tmpdir = getenv("TMPDIR")) != NULL) + { + /* + * TMPDIR is defined, see if it is OK for us to use... + */ + + if (stat(tmpdir, &tmpinfo)) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to access TMPDIR (%s): %s", + tmpdir, strerror(errno)); + else if (!S_ISDIR(tmpinfo.st_mode)) + cupsdLogMessage(CUPSD_LOG_ERROR, "TMPDIR (%s) is not a directory!", + tmpdir); + else if ((tmpinfo.st_uid != User || !(tmpinfo.st_mode & S_IWUSR)) && + (tmpinfo.st_gid != Group || !(tmpinfo.st_mode & S_IWGRP)) && + !(tmpinfo.st_mode & S_IWOTH)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "TMPDIR (%s) has the wrong permissions!", tmpdir); + else + cupsdSetString(&TempDir, tmpdir); + } + + if (!TempDir) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Using default TempDir of %s/tmp...", + RequestRoot); + cupsdSetStringf(&TempDir, "%s/tmp", RequestRoot); + } + } + + /* + * Make sure the temporary directory has the right permissions... + */ + + if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot)) || + access(TempDir, 0)) + { + /* + * Update ownership and permissions if the CUPS temp directory + * is under the spool directory or does not exist... + */ + + if (cupsdCheckPermissions(TempDir, NULL, 01770, RunUser, Group, 1, 1) < 0 && + (FatalErrors & CUPSD_FATAL_PERMISSIONS)) + return (0); + } + + /* + * Update environment variables... + */ + + cupsdUpdateEnv(); + + /* + * Update default paper size setting as needed... + */ + + if (!DefaultPaperSize) + { +#ifdef HAVE_LIBPAPER + char *paper_result; /* Paper size name from libpaper */ + + if ((paper_result = systempapername()) != NULL) + cupsdSetString(&DefaultPaperSize, paper_result); + else +#endif /* HAVE_LIBPAPER */ + if (!DefaultLanguage || + !strcasecmp(DefaultLanguage, "C") || + !strcasecmp(DefaultLanguage, "POSIX") || + !strcasecmp(DefaultLanguage, "en") || + !strncasecmp(DefaultLanguage, "en.", 3) || + !strncasecmp(DefaultLanguage, "en_US", 5) || + !strncasecmp(DefaultLanguage, "en_CA", 5) || + !strncasecmp(DefaultLanguage, "fr_CA", 5)) + { + /* + * These are the only locales that will default to "letter" size... + */ + + cupsdSetString(&DefaultPaperSize, "Letter"); + } + else + cupsdSetString(&DefaultPaperSize, "A4"); + } + + /* + * Update classification setting as needed... + */ + + if (Classification && !strcasecmp(Classification, "none")) + cupsdClearString(&Classification); + + if (Classification) + cupsdLogMessage(CUPSD_LOG_INFO, "Security set to \"%s\"", Classification); + + /* + * Check the MaxClients setting, and then allocate memory for it... + */ + + if (MaxClients > (MaxFDs / 3) || MaxClients <= 0) + { + if (MaxClients > 0) + cupsdLogMessage(CUPSD_LOG_INFO, + "MaxClients limited to 1/3 (%d) of the file descriptor " + "limit (%d)...", + MaxFDs / 3, MaxFDs); + + MaxClients = MaxFDs / 3; + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Configured for up to %d clients.", + MaxClients); + + /* + * Check the MaxActiveJobs setting; limit to 1/3 the available + * file descriptors, since we need a pipe for each job... + */ + + if (MaxActiveJobs > (MaxFDs / 3)) + MaxActiveJobs = MaxFDs / 3; + + /* + * Update the MaxClientsPerHost value, as needed... + */ + + if (MaxClientsPerHost <= 0) + MaxClientsPerHost = MaxClients; + + if (MaxClientsPerHost > MaxClients) + MaxClientsPerHost = MaxClients; + + cupsdLogMessage(CUPSD_LOG_INFO, + "Allowing up to %d client connections per host.", + MaxClientsPerHost); + + /* + * Make sure that BrowseTimeout is at least twice the interval... + */ + + if (BrowseTimeout < (2 * BrowseInterval) || BrowseTimeout <= 0) + { + cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid BrowseTimeout value %d!", + BrowseTimeout); + + if (BrowseInterval) + BrowseTimeout = BrowseInterval * 2; + else + BrowseTimeout = DEFAULT_TIMEOUT; + + cupsdLogMessage(CUPSD_LOG_ALERT, "Reset BrowseTimeout to %d!", + BrowseTimeout); + } + + /* + * Update the default policy, as needed... + */ + + if (DefaultPolicy) + DefaultPolicyPtr = cupsdFindPolicy(DefaultPolicy); + else + DefaultPolicyPtr = NULL; + + if (!DefaultPolicyPtr) + { + cupsd_location_t *po; /* New policy operation */ + + + if (DefaultPolicy) + cupsdLogMessage(CUPSD_LOG_ERROR, "Default policy \"%s\" not found!", + DefaultPolicy); + + cupsdSetString(&DefaultPolicy, "default"); + + if ((DefaultPolicyPtr = cupsdFindPolicy("default")) != NULL) + cupsdLogMessage(CUPSD_LOG_INFO, + "Using policy \"default\" as the default!"); + else + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Creating CUPS default administrative policy:"); + + DefaultPolicyPtr = p = cupsdAddPolicy("default"); + + cupsdLogMessage(CUPSD_LOG_INFO, ""); + cupsdLogMessage(CUPSD_LOG_INFO, + ""); + cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); + + po = cupsdAddPolicyOp(p, NULL, IPP_CREATE_JOB); + po->order_type = CUPSD_AUTH_ALLOW; + + cupsdAddPolicyOp(p, po, IPP_PRINT_JOB); + cupsdAddPolicyOp(p, po, IPP_PRINT_URI); + cupsdAddPolicyOp(p, po, IPP_VALIDATE_JOB); + + cupsdLogMessage(CUPSD_LOG_INFO, ""); + + cupsdLogMessage(CUPSD_LOG_INFO, + ""); + cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); + + po = cupsdAddPolicyOp(p, NULL, IPP_SEND_DOCUMENT); + po->order_type = CUPSD_AUTH_ALLOW; + po->level = CUPSD_AUTH_USER; + + cupsdAddName(po, "@OWNER"); + cupsdAddName(po, "@SYSTEM"); + cupsdLogMessage(CUPSD_LOG_INFO, "Require user @OWNER @SYSTEM"); + + cupsdAddPolicyOp(p, po, IPP_SEND_URI); + cupsdAddPolicyOp(p, po, IPP_CANCEL_JOB); + cupsdAddPolicyOp(p, po, IPP_HOLD_JOB); + cupsdAddPolicyOp(p, po, IPP_RELEASE_JOB); + cupsdAddPolicyOp(p, po, IPP_RESTART_JOB); + cupsdAddPolicyOp(p, po, IPP_PURGE_JOBS); + cupsdAddPolicyOp(p, po, IPP_SET_JOB_ATTRIBUTES); + cupsdAddPolicyOp(p, po, IPP_CREATE_JOB_SUBSCRIPTION); + cupsdAddPolicyOp(p, po, IPP_RENEW_SUBSCRIPTION); + cupsdAddPolicyOp(p, po, IPP_CANCEL_SUBSCRIPTION); + cupsdAddPolicyOp(p, po, IPP_GET_NOTIFICATIONS); + cupsdAddPolicyOp(p, po, IPP_REPROCESS_JOB); + cupsdAddPolicyOp(p, po, IPP_CANCEL_CURRENT_JOB); + cupsdAddPolicyOp(p, po, IPP_SUSPEND_CURRENT_JOB); + cupsdAddPolicyOp(p, po, IPP_RESUME_JOB); + cupsdAddPolicyOp(p, po, CUPS_MOVE_JOB); + cupsdAddPolicyOp(p, po, CUPS_AUTHENTICATE_JOB); + cupsdAddPolicyOp(p, po, CUPS_GET_DOCUMENT); + + cupsdLogMessage(CUPSD_LOG_INFO, ""); + + cupsdLogMessage(CUPSD_LOG_INFO, + ""); + cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); + cupsdLogMessage(CUPSD_LOG_INFO, "AuthType Default"); + + po = cupsdAddPolicyOp(p, NULL, IPP_PAUSE_PRINTER); + po->order_type = CUPSD_AUTH_ALLOW; + po->type = CUPSD_AUTH_DEFAULT; + po->level = CUPSD_AUTH_USER; + + cupsdAddName(po, "@SYSTEM"); + cupsdLogMessage(CUPSD_LOG_INFO, "Require user @SYSTEM"); + + cupsdAddPolicyOp(p, po, IPP_RESUME_PRINTER); + cupsdAddPolicyOp(p, po, IPP_SET_PRINTER_ATTRIBUTES); + cupsdAddPolicyOp(p, po, IPP_ENABLE_PRINTER); + cupsdAddPolicyOp(p, po, IPP_DISABLE_PRINTER); + cupsdAddPolicyOp(p, po, IPP_PAUSE_PRINTER_AFTER_CURRENT_JOB); + cupsdAddPolicyOp(p, po, IPP_HOLD_NEW_JOBS); + cupsdAddPolicyOp(p, po, IPP_RELEASE_HELD_NEW_JOBS); + cupsdAddPolicyOp(p, po, IPP_DEACTIVATE_PRINTER); + cupsdAddPolicyOp(p, po, IPP_ACTIVATE_PRINTER); + cupsdAddPolicyOp(p, po, IPP_RESTART_PRINTER); + cupsdAddPolicyOp(p, po, IPP_SHUTDOWN_PRINTER); + cupsdAddPolicyOp(p, po, IPP_STARTUP_PRINTER); + cupsdAddPolicyOp(p, po, IPP_PROMOTE_JOB); + cupsdAddPolicyOp(p, po, IPP_SCHEDULE_JOB_AFTER); + cupsdAddPolicyOp(p, po, CUPS_ADD_PRINTER); + cupsdAddPolicyOp(p, po, CUPS_DELETE_PRINTER); + cupsdAddPolicyOp(p, po, CUPS_ADD_CLASS); + cupsdAddPolicyOp(p, po, CUPS_DELETE_CLASS); + cupsdAddPolicyOp(p, po, CUPS_ACCEPT_JOBS); + cupsdAddPolicyOp(p, po, CUPS_REJECT_JOBS); + cupsdAddPolicyOp(p, po, CUPS_SET_DEFAULT); + + cupsdLogMessage(CUPSD_LOG_INFO, ""); + + cupsdLogMessage(CUPSD_LOG_INFO, ""); + cupsdLogMessage(CUPSD_LOG_INFO, "Order Deny,Allow"); + + po = cupsdAddPolicyOp(p, NULL, IPP_ANY_OPERATION); + po->order_type = CUPSD_AUTH_ALLOW; + + cupsdLogMessage(CUPSD_LOG_INFO, ""); + cupsdLogMessage(CUPSD_LOG_INFO, ""); + } + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadConfiguration: NumPolicies=%d", + cupsArrayCount(Policies)); + for (i = 0, p = (cupsd_policy_t *)cupsArrayFirst(Policies); + p; + i ++, p = (cupsd_policy_t *)cupsArrayNext(Policies)) + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadConfiguration: Policies[%d]=\"%s\"", i, p->name); + + /* + * If we are doing a full reload or the server root has changed, flush + * the jobs, printers, etc. and start from scratch... + */ + + if (NeedReload == RELOAD_ALL || + old_remote_port != RemotePort || + !old_serverroot || !ServerRoot || strcmp(old_serverroot, ServerRoot) || + !old_requestroot || !RequestRoot || strcmp(old_requestroot, RequestRoot)) + { + mime_type_t *type; /* Current type */ + char mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE]; + /* MIME type name */ + + + cupsdLogMessage(CUPSD_LOG_INFO, "Full reload is required."); + + /* + * Free all memory... + */ + + cupsdDeleteAllSubscriptions(); + cupsdFreeAllJobs(); + cupsdDeleteAllPrinters(); + + DefaultPrinter = NULL; + + if (MimeDatabase != NULL) + mimeDelete(MimeDatabase); + + if (NumMimeTypes) + { + for (i = 0; i < NumMimeTypes; i ++) + _cupsStrFree(MimeTypes[i]); + + free(MimeTypes); + } + + /* + * Read the MIME type and conversion database... + */ + + snprintf(temp, sizeof(temp), "%s/filter", ServerBin); + snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir); + + MimeDatabase = mimeLoadTypes(NULL, mimedir); + MimeDatabase = mimeLoadTypes(MimeDatabase, ServerRoot); + MimeDatabase = mimeLoadFilters(MimeDatabase, mimedir, temp); + MimeDatabase = mimeLoadFilters(MimeDatabase, ServerRoot, temp); + + if (!MimeDatabase) + { + cupsdLogMessage(CUPSD_LOG_EMERG, + "Unable to load MIME database from \"%s\" or \"%s\"!", + mimedir, ServerRoot); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + + cupsdLogMessage(CUPSD_LOG_INFO, + "Loaded MIME database from \"%s\" and \"%s\": %d types, " + "%d filters...", mimedir, ServerRoot, + mimeNumTypes(MimeDatabase), mimeNumFilters(MimeDatabase)); + + /* + * Create a list of MIME types for the document-format-supported + * attribute... + */ + + NumMimeTypes = mimeNumTypes(MimeDatabase); + if (!mimeType(MimeDatabase, "application", "octet-stream")) + NumMimeTypes ++; + + if ((MimeTypes = calloc(NumMimeTypes, sizeof(const char *))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for %d MIME types!", + NumMimeTypes); + NumMimeTypes = 0; + } + else + { + for (i = 0, type = mimeFirstType(MimeDatabase); + type; + i ++, type = mimeNextType(MimeDatabase)) + { + snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type); + + MimeTypes[i] = _cupsStrAlloc(mimetype); + } + + if (i < NumMimeTypes) + MimeTypes[i] = _cupsStrAlloc("application/octet-stream"); + } + + if (LogLevel == CUPSD_LOG_DEBUG2) + { + mime_filter_t *filter; /* Current filter */ + + + for (type = mimeFirstType(MimeDatabase); + type; + type = mimeNextType(MimeDatabase)) + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReadConfiguration: type %s/%s", + type->super, type->type); + + for (filter = mimeFirstFilter(MimeDatabase); + filter; + filter = mimeNextFilter(MimeDatabase)) + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdReadConfiguration: filter %s/%s to %s/%s %d %s", + filter->src->super, filter->src->type, + filter->dst->super, filter->dst->type, + filter->cost, filter->filter); + } + + /* + * Load banners... + */ + + snprintf(temp, sizeof(temp), "%s/banners", DataDir); + cupsdLoadBanners(temp); + + /* + * Load printers and classes... + */ + + cupsdLoadAllPrinters(); + cupsdLoadAllClasses(); + cupsdLoadRemoteCache(); + + cupsdCreateCommonData(); + + /* + * Update the printcap file as needed... + */ + + if (Printcap && *Printcap && access(Printcap, 0)) + cupsdWritePrintcap(); + + /* + * Load queued jobs... + */ + + cupsdLoadAllJobs(); + + /* + * Load subscriptions... + */ + + cupsdLoadAllSubscriptions(); + + cupsdLogMessage(CUPSD_LOG_INFO, "Full reload complete."); + } + else + { + /* + * Not a full reload, so recreate the common printer attributes... + */ + + cupsdCreateCommonData(); + + /* + * Update all printers as needed... + */ + + cupsdUpdatePrinters(); + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); + + cupsdLogMessage(CUPSD_LOG_INFO, "Partial reload complete."); + } + + /* + * Reset the reload state... + */ + + NeedReload = RELOAD_NONE; + + cupsdClearString(&old_serverroot); + cupsdClearString(&old_requestroot); + + return (1); +} + + +/* + * 'get_address()' - Get an address + port number from a line. + */ + +static http_addrlist_t * /* O - Pointer to list if address good, NULL if bad */ +get_address(const char *value, /* I - Value string */ + int defport) /* I - Default port */ +{ + char buffer[1024], /* Hostname + port number buffer */ + defpname[255], /* Default port name */ + *hostname, /* Hostname or IP */ + *portname; /* Port number or name */ + http_addrlist_t *addrlist; /* Address list */ + + + /* + * Check for an empty value... + */ + + if (!*value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad (empty) address!"); + return (NULL); + } + + /* + * Grab a hostname and port number; if there is no colon and the port name + * is only digits, then we have a port number by itself... + */ + + strlcpy(buffer, value, sizeof(buffer)); + + if ((portname = strrchr(buffer, ':')) != NULL && !strchr(portname, ']')) + { + *portname++ = '\0'; + hostname = buffer; + } + else + { + for (portname = buffer; isdigit(*portname & 255); portname ++); + + if (*portname) + { + /* + * Use the default port... + */ + + sprintf(defpname, "%d", defport); + portname = defpname; + hostname = buffer; + } + else + { + /* + * The buffer contains just a port number... + */ + + portname = buffer; + hostname = NULL; + } + } + + if (hostname && !strcmp(hostname, "*")) + hostname = NULL; + + /* + * Now lookup the address using httpAddrGetList()... + */ + + if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) + cupsdLogMessage(CUPSD_LOG_ERROR, "Hostname lookup for \"%s\" failed!", + hostname ? hostname : "(nil)"); + + return (addrlist); +} + + +/* + * 'get_addr_and_mask()' - Get an IP address and netmask. + */ + +static int /* O - 1 on success, 0 on failure */ +get_addr_and_mask(const char *value, /* I - String from config file */ + unsigned *ip, /* O - Address value */ + unsigned *mask) /* O - Mask value */ +{ + int i, j, /* Looping vars */ + family, /* Address family */ + ipcount; /* Count of fields in address */ + unsigned ipval; /* Value */ + const char *maskval, /* Pointer to start of mask value */ + *ptr, /* Pointer into value */ + *ptr2; /* ... */ + + + /* + * Get the address... + */ + + ip[0] = ip[1] = ip[2] = ip[3] = 0x00000000; + mask[0] = mask[1] = mask[2] = mask[3] = 0xffffffff; + + if ((maskval = strchr(value, '/')) != NULL) + maskval ++; + else + maskval = value + strlen(value); + +#ifdef AF_INET6 + /* + * Check for an IPv6 address... + */ + + if (*value == '[') + { + /* + * Parse hexadecimal IPv6 address... + */ + + family = AF_INET6; + + for (i = 0, ptr = value + 1; *ptr && i < 8; i ++) + { + if (*ptr == ']') + break; + else if (!strncmp(ptr, "::", 2)) + { + for (ptr2 = strchr(ptr + 2, ':'), j = 0; + ptr2; + ptr2 = strchr(ptr2 + 1, ':'), j ++); + + i = 7 - j; + ptr ++; + } + else if (isxdigit(*ptr & 255)) + { + ipval = strtoul(ptr, (char **)&ptr, 16); + + if (ipval > 0xffff) + return (0); + + if (i & 1) + ip[i / 2] |= ipval; + else + ip[i / 2] |= ipval << 16; + } + else + return (0); + + while (*ptr == ':') + ptr ++; + } + + if (*ptr != ']') + return (0); + + ptr ++; + + if (*ptr && *ptr != '/') + return (0); + } + else +#endif /* AF_INET6 */ + { + /* + * Parse dotted-decimal IPv4 address... + */ + + unsigned val[4]; /* IPv4 address values */ + + + family = AF_INET; + ipcount = sscanf(value, "%u.%u.%u.%u", val + 0, val + 1, val + 2, val + 3); + + /* + * Range check the IP numbers... + */ + + for (i = 0; i < ipcount; i ++) + if (val[i] > 255) + return (0); + + /* + * Make sure the trailing values are zeroed, as some C libraries like + * glibc apparently like to fill the unused arguments with garbage... + */ + + for (i = ipcount; i < 4; i ++) + val[i] = 0; + + /* + * Merge everything into a 32-bit IPv4 address in ip[3]... + */ + + ip[3] = (((((val[0] << 8) | val[1]) << 8) | val[2]) << 8) | val[3]; + + if (ipcount < 4) + mask[3] = (0xffffffff << (32 - 8 * ipcount)) & 0xffffffff; + } + + if (*maskval) + { + /* + * Get the netmask value(s)... + */ + + memset(mask, 0, sizeof(unsigned) * 4); + + if (strchr(maskval, '.')) + { + /* + * Get dotted-decimal mask... + */ + + if (family != AF_INET) + return (0); + + if (sscanf(maskval, "%u.%u.%u.%u", mask + 0, mask + 1, mask + 2, mask + 3) != 4) + return (0); + + mask[3] |= ((((mask[0] << 8) | mask[1]) << 8) | mask[2]) << 8; + mask[0] = mask[1] = mask[2] = 0; + } + else + { + /* + * Get address/bits format... + */ + + i = atoi(maskval); + +#ifdef AF_INET6 + if (family == AF_INET6) + { + if (i > 128) + return (0); + + i = 128 - i; + + if (i <= 96) + mask[0] = 0xffffffff; + else + mask[0] = (0xffffffff << (i - 96)) & 0xffffffff; + + if (i <= 64) + mask[1] = 0xffffffff; + else if (i >= 96) + mask[1] = 0; + else + mask[1] = (0xffffffff << (i - 64)) & 0xffffffff; + + if (i <= 32) + mask[2] = 0xffffffff; + else if (i >= 64) + mask[2] = 0; + else + mask[2] = (0xffffffff << (i - 32)) & 0xffffffff; + + if (i == 0) + mask[3] = 0xffffffff; + else if (i >= 32) + mask[3] = 0; + else + mask[3] = (0xffffffff << i) & 0xffffffff; + } + else +#endif /* AF_INET6 */ + { + if (i > 32) + return (0); + + mask[0] = 0xffffffff; + mask[1] = 0xffffffff; + mask[2] = 0xffffffff; + + if (i < 32) + mask[3] = (0xffffffff << (32 - i)) & 0xffffffff; + else + mask[3] = 0xffffffff; + } + } + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_addr_and_mask(value=\"%s\", " + "ip=[%08x:%08x:%08x:%08x], mask=[%08x:%08x:%08x:%08x])", + value, ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], + mask[3]); + + /* + * Check for a valid netmask; no fallback like in CUPS 1.1.x! + */ + + if ((ip[0] & ~mask[0]) != 0 || + (ip[1] & ~mask[1]) != 0 || + (ip[2] & ~mask[2]) != 0 || + (ip[3] & ~mask[3]) != 0) + return (0); + + return (1); +} + + +/* + * 'parse_aaa()' - Parse authentication, authorization, and access control lines. + */ + +static int /* O - 1 on success, 0 on failure */ +parse_aaa(cupsd_location_t *loc, /* I - Location */ + char *line, /* I - Line from file */ + char *value, /* I - Start of value data */ + int linenum) /* I - Current line number */ +{ + char *valptr; /* Pointer into value */ + unsigned ip[4], /* IP address components */ + mask[4]; /* IP netmask components */ + + + if (!strcasecmp(line, "Encryption")) + { + /* + * "Encryption xxx" - set required encryption level... + */ + + if (!strcasecmp(value, "never")) + loc->encryption = HTTP_ENCRYPT_NEVER; + else if (!strcasecmp(value, "always")) + { + cupsdLogMessage(CUPSD_LOG_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")) + loc->encryption = HTTP_ENCRYPT_REQUIRED; + else if (!strcasecmp(value, "ifrequested")) + loc->encryption = HTTP_ENCRYPT_IF_REQUESTED; + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown Encryption value %s on line %d.", value, linenum); + return (0); + } + } + else if (!strcasecmp(line, "Order")) + { + /* + * "Order Deny,Allow" or "Order Allow,Deny"... + */ + + if (!strncasecmp(value, "deny", 4)) + loc->order_type = CUPSD_AUTH_ALLOW; + else if (!strncasecmp(value, "allow", 5)) + loc->order_type = CUPSD_AUTH_DENY; + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown Order value %s on line %d.", + value, linenum); + return (0); + } + } + else if (!strcasecmp(line, "Allow") || !strcasecmp(line, "Deny")) + { + /* + * Allow [From] host/ip... + * Deny [From] host/ip... + */ + + while (*value) + { + if (!strncasecmp(value, "from", 4)) + { + /* + * Strip leading "from"... + */ + + value += 4; + + while (isspace(*value & 255)) + value ++; + + if (!*value) + break; + } + + /* + * Find the end of the value... + */ + + for (valptr = value; *valptr && !isspace(*valptr & 255); valptr ++); + + while (isspace(*valptr & 255)) + *valptr++ = '\0'; + + /* + * 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")) + { + /* + * All hosts... + */ + + if (!strcasecmp(line, "Allow")) + cupsdAllowIP(loc, zeros, zeros); + else + cupsdDenyIP(loc, zeros, zeros); + } + else if (!strcasecmp(value, "none")) + { + /* + * No hosts... + */ + + if (!strcasecmp(line, "Allow")) + cupsdAllowIP(loc, ones, zeros); + else + cupsdDenyIP(loc, ones, zeros); + } +#ifdef AF_INET6 + else if (value[0] == '*' || value[0] == '.' || + (!isdigit(value[0] & 255) && value[0] != '[')) +#else + else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255)) +#endif /* AF_INET6 */ + { + /* + * Host or domain name... + */ + + if (value[0] == '*') + value ++; + + if (!strcasecmp(line, "Allow")) + cupsdAllowHost(loc, value); + else + cupsdDenyHost(loc, value); + } + else + { + /* + * One of many IP address forms... + */ + + if (!get_addr_and_mask(value, ip, mask)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.", + value, linenum); + return (0); + } + + if (!strcasecmp(line, "Allow")) + cupsdAllowIP(loc, ip, mask); + else + cupsdDenyIP(loc, ip, mask); + } + + /* + * Advance to next value... + */ + + value = valptr; + } + } + else if (!strcasecmp(line, "AuthType")) + { + /* + * AuthType {none,basic,digest,basicdigest,negotiate,default} + */ + + if (!strcasecmp(value, "none")) + { + loc->type = CUPSD_AUTH_NONE; + loc->level = CUPSD_AUTH_ANON; + } + else if (!strcasecmp(value, "basic")) + { + loc->type = CUPSD_AUTH_BASIC; + + if (loc->level == CUPSD_AUTH_ANON) + loc->level = CUPSD_AUTH_USER; + } + else if (!strcasecmp(value, "digest")) + { + loc->type = CUPSD_AUTH_DIGEST; + + if (loc->level == CUPSD_AUTH_ANON) + loc->level = CUPSD_AUTH_USER; + } + else if (!strcasecmp(value, "basicdigest")) + { + loc->type = CUPSD_AUTH_BASICDIGEST; + + if (loc->level == CUPSD_AUTH_ANON) + loc->level = CUPSD_AUTH_USER; + } + else if (!strcasecmp(value, "default")) + { + loc->type = CUPSD_AUTH_DEFAULT; + + if (loc->level == CUPSD_AUTH_ANON) + loc->level = CUPSD_AUTH_USER; + } +#ifdef HAVE_GSSAPI + else if (!strcasecmp(value, "negotiate")) + { + loc->type = CUPSD_AUTH_NEGOTIATE; + + if (loc->level == CUPSD_AUTH_ANON) + loc->level = CUPSD_AUTH_USER; + } +#endif /* HAVE_GSSAPI */ + else + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Unknown authorization type %s on line %d.", + value, linenum); + return (0); + } + } + else if (!strcasecmp(line, "AuthClass")) + { + /* + * AuthClass anonymous, user, system, group + */ + + if (!strcasecmp(value, "anonymous")) + { + loc->type = CUPSD_AUTH_NONE; + loc->level = CUPSD_AUTH_ANON; + + cupsdLogMessage(CUPSD_LOG_WARN, + "\"AuthClass %s\" is deprecated; consider removing " + "it from line %d.", + value, linenum); + } + else if (!strcasecmp(value, "user")) + { + loc->level = CUPSD_AUTH_USER; + + cupsdLogMessage(CUPSD_LOG_WARN, + "\"AuthClass %s\" is deprecated; consider using " + "\"Require valid-user\" on line %d.", + value, linenum); + } + else if (!strcasecmp(value, "group")) + { + loc->level = CUPSD_AUTH_GROUP; + + cupsdLogMessage(CUPSD_LOG_WARN, + "\"AuthClass %s\" is deprecated; consider using " + "\"Require user @groupname\" on line %d.", + value, linenum); + } + else if (!strcasecmp(value, "system")) + { + loc->level = CUPSD_AUTH_GROUP; + + cupsdAddName(loc, "@SYSTEM"); + + cupsdLogMessage(CUPSD_LOG_WARN, + "\"AuthClass %s\" is deprecated; consider using " + "\"Require user @SYSTEM\" on line %d.", + value, linenum); + } + else + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Unknown authorization class %s on line %d.", + value, linenum); + return (0); + } + } + else if (!strcasecmp(line, "AuthGroupName")) + { + cupsdAddName(loc, value); + + cupsdLogMessage(CUPSD_LOG_WARN, + "\"AuthGroupName %s\" directive is deprecated; consider " + "using \"Require user @%s\" on line %d.", + value, value, linenum); + } + else if (!strcasecmp(line, "Require")) + { + /* + * Apache synonym for AuthClass and AuthGroupName... + * + * Get initial word: + * + * Require valid-user + * Require group names + * Require user names + */ + + for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++); + + if (*valptr) + *valptr++ = '\0'; + + if (!strcasecmp(value, "valid-user") || + !strcasecmp(value, "user")) + loc->level = CUPSD_AUTH_USER; + else if (!strcasecmp(value, "group")) + loc->level = CUPSD_AUTH_GROUP; + else + { + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Require type %s on line %d.", + value, linenum); + return (0); + } + + /* + * Get the list of names from the line... + */ + + for (value = valptr; *value;) + { + while (isspace(*value & 255)) + value ++; + +#ifdef HAVE_AUTHORIZATION_H + if (!strncmp(value, "@AUTHKEY(", 9)) + { + /* + * Grab "@AUTHKEY(name)" value... + */ + + for (valptr = value + 9; *valptr != ')' && *valptr; valptr ++); + + if (*valptr) + *valptr++ = '\0'; + } + else +#endif /* HAVE_AUTHORIZATION_H */ + if (*value == '\"' || *value == '\'') + { + /* + * Grab quoted name... + */ + + for (valptr = value + 1; *valptr != *value && *valptr; valptr ++); + + value ++; + } + else + { + /* + * Grab literal name. + */ + + for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++); + } + + if (*valptr) + *valptr++ = '\0'; + + cupsdAddName(loc, value); + + for (value = valptr; isspace(*value & 255); value ++); + } + } + else if (!strcasecmp(line, "Satisfy")) + { + if (!strcasecmp(value, "all")) + loc->satisfy = CUPSD_AUTH_SATISFY_ALL; + else if (!strcasecmp(value, "any")) + loc->satisfy = CUPSD_AUTH_SATISFY_ANY; + else + { + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown Satisfy value %s on line %d.", + value, linenum); + return (0); + } + } + else + return (0); + + return (1); +} + + +/* + * 'parse_fatal_errors()' - Parse FatalErrors values in a string. + */ + +static int /* O - FatalErrors bits */ +parse_fatal_errors(const char *s) /* I - FatalErrors string */ +{ + int fatal; /* FatalErrors bits */ + char value[1024], /* Value string */ + *valstart, /* Pointer into value */ + *valend; /* End of value */ + + + /* + * Empty FatalErrors line yields NULL pointer... + */ + + if (!s) + return (CUPSD_FATAL_NONE); + + /* + * Loop through the value string,... + */ + + strlcpy(value, s, sizeof(value)); + + fatal = CUPSD_FATAL_NONE; + + for (valstart = value; *valstart;) + { + /* + * Get the current space/comma-delimited kind name... + */ + + for (valend = valstart; *valend; valend ++) + if (isspace(*valend & 255) || *valend == ',') + break; + + if (*valend) + *valend++ = '\0'; + + /* + * Add the error to the bitmask... + */ + + if (!strcasecmp(valstart, "all")) + fatal = CUPSD_FATAL_ALL; + else if (!strcasecmp(valstart, "browse")) + fatal |= CUPSD_FATAL_BROWSE; + else if (!strcasecmp(valstart, "-browse")) + fatal &= ~CUPSD_FATAL_BROWSE; + else if (!strcasecmp(valstart, "config")) + fatal |= CUPSD_FATAL_CONFIG; + else if (!strcasecmp(valstart, "-config")) + fatal &= ~CUPSD_FATAL_CONFIG; + else if (!strcasecmp(valstart, "listen")) + fatal |= CUPSD_FATAL_LISTEN; + else if (!strcasecmp(valstart, "-listen")) + fatal &= ~CUPSD_FATAL_LISTEN; + else if (!strcasecmp(valstart, "log")) + fatal |= CUPSD_FATAL_LOG; + else if (!strcasecmp(valstart, "-log")) + fatal &= ~CUPSD_FATAL_LOG; + else if (!strcasecmp(valstart, "permissions")) + fatal |= CUPSD_FATAL_PERMISSIONS; + else if (!strcasecmp(valstart, "-permissions")) + fatal &= ~CUPSD_FATAL_PERMISSIONS; + else if (strcasecmp(valstart, "none")) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown FatalErrors kind \"%s\" ignored!", valstart); + + for (valstart = valend; *valstart; valstart ++) + if (!isspace(*valstart & 255) || *valstart != ',') + break; + } + + return (fatal); +} + + +/* + * 'parse_groups()' - Parse system group names in a string. + */ + +static int /* O - 1 on success, 0 on failure */ +parse_groups(const char *s) /* I - Space-delimited groups */ +{ + int status; /* Return status */ + char value[1024], /* Value string */ + *valstart, /* Pointer into value */ + *valend, /* End of value */ + quote; /* Quote character */ + struct group *group; /* Group */ + + + /* + * Make a copy of the string and parse out the groups... + */ + + strlcpy(value, s, sizeof(value)); + + status = 1; + valstart = value; + + while (*valstart && NumSystemGroups < MAX_SYSTEM_GROUPS) + { + if (*valstart == '\'' || *valstart == '\"') + { + /* + * Scan quoted name... + */ + + quote = *valstart++; + + for (valend = valstart; *valend; valend ++) + if (*valend == quote) + break; + } + else + { + /* + * Scan space or comma-delimited name... + */ + + for (valend = valstart; *valend; valend ++) + if (isspace(*valend) || *valend == ',') + break; + } + + if (*valend) + *valend++ = '\0'; + + group = getgrnam(valstart); + if (group) + { + cupsdSetString(SystemGroups + NumSystemGroups, valstart); + SystemGroupIDs[NumSystemGroups] = group->gr_gid; + + NumSystemGroups ++; + } + else + status = 0; + + endgrent(); + + valstart = valend; + + while (*valstart == ',' || isspace(*valstart)) + valstart ++; + } + + return (status); +} + + +/* + * 'parse_protocols()' - Parse browse protocols in a string. + */ + +static int /* O - Browse protocol bits */ +parse_protocols(const char *s) /* I - Space-delimited protocols */ +{ + int protocols; /* Browse protocol bits */ + char value[1024], /* Value string */ + *valstart, /* Pointer into value */ + *valend; /* End of value */ + + + /* + * Empty protocol line yields NULL pointer... + */ + + if (!s) + return (0); + + /* + * Loop through the value string,... + */ + + strlcpy(value, s, sizeof(value)); + + protocols = 0; + + for (valstart = value; *valstart;) + { + /* + * Get the current space/comma-delimited protocol name... + */ + + for (valend = valstart; *valend; valend ++) + if (isspace(*valend & 255) || *valend == ',') + break; + + if (*valend) + *valend++ = '\0'; + + /* + * Add the protocol to the bitmask... + */ + + if (!strcasecmp(valstart, "cups")) + protocols |= BROWSE_CUPS; + else if (!strcasecmp(valstart, "slp")) + protocols |= BROWSE_SLP; + else if (!strcasecmp(valstart, "ldap")) + protocols |= BROWSE_LDAP; + else if (!strcasecmp(valstart, "dnssd") || + !strcasecmp(valstart, "dns-sd") || + !strcasecmp(valstart, "bonjour")) + protocols |= BROWSE_DNSSD; + else if (!strcasecmp(valstart, "lpd")) + protocols |= BROWSE_LPD; + else if (!strcasecmp(valstart, "smb")) + protocols |= BROWSE_SMB; + else if (!strcasecmp(valstart, "all")) + protocols |= BROWSE_ALL; + else if (strcasecmp(valstart, "none")) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown browse protocol \"%s\" ignored!", valstart); + + for (valstart = valend; *valstart; valstart ++) + if (!isspace(*valstart & 255) || *valstart != ',') + break; + } + + return (protocols); +} + + +/* + * 'read_configuration()' - Read a configuration file. + */ + +static int /* O - 1 on success, 0 on failure */ +read_configuration(cups_file_t *fp) /* I - File to read from */ +{ + int i; /* Looping var */ + int linenum; /* Current line number */ + char line[HTTP_MAX_BUFFER], + /* Line from file */ + temp[HTTP_MAX_BUFFER], + /* Temporary buffer for value */ + temp2[HTTP_MAX_BUFFER], + /* Temporary buffer 2 for value */ + *ptr, /* Pointer into line/temp */ + *value, /* Pointer to value */ + *valueptr; /* Pointer into value */ + int valuelen; /* Length of value */ + cupsd_var_t const *var; /* Current variable */ + http_addrlist_t *addrlist, /* Address list */ + *addr; /* Current address */ + unsigned ip[4], /* Address value */ + mask[4]; /* Netmask value */ + cupsd_dirsvc_relay_t *relay; /* Relay data */ + cupsd_dirsvc_poll_t *pollp; /* Polling data */ + cupsd_location_t *location; /* Browse location */ + cups_file_t *incfile; /* Include file */ + char incname[1024]; /* Include filename */ + struct group *group; /* Group */ + + + /* + * Loop through each line in the file... + */ + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Decode the directive... + */ + + if (!strcasecmp(line, "Include") && value) + { + /* + * Include filename + */ + + if (value[0] == '/') + strlcpy(incname, value, sizeof(incname)); + else + snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value); + + if ((incfile = cupsFileOpen(incname, "rb")) == NULL) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to include config file \"%s\" - %s", + incname, strerror(errno)); + else + { + read_configuration(incfile); + cupsFileClose(incfile); + } + } + else if (!strcasecmp(line, " + */ + + linenum = read_location(fp, value, linenum); + if (linenum == 0) + return (0); + } + else if (!strcasecmp(line, " + */ + + linenum = read_policy(fp, value, linenum); + if (linenum == 0) + return (0); + } + else if (!strcasecmp(line, "FatalErrors")) + FatalErrors = parse_fatal_errors(value); + else if (!strcasecmp(line, "FaxRetryInterval") && value) + { + JobRetryInterval = atoi(value); + cupsdLogMessage(CUPSD_LOG_WARN, + "FaxRetryInterval is deprecated; use " + "JobRetryInterval on line %d.", linenum); + } + else if (!strcasecmp(line, "FaxRetryLimit") && value) + { + JobRetryLimit = atoi(value); + cupsdLogMessage(CUPSD_LOG_WARN, + "FaxRetryLimit is deprecated; use " + "JobRetryLimit on line %d.", linenum); + } + else if (!strcasecmp(line, "Port") || !strcasecmp(line, "Listen") +#ifdef HAVE_SSL + || !strcasecmp(line, "SSLPort") || !strcasecmp(line, "SSLListen") +#endif /* HAVE_SSL */ + ) + { + /* + * Add listening address(es) to the list... + */ + + cupsd_listener_t *lis; /* New listeners array */ + + + /* + * Get the address list... + */ + + addrlist = get_address(value, IPP_PORT); + + if (!addrlist) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad %s address %s at line %d.", line, + value, linenum); + continue; + } + + /* + * Add each address... + */ + + for (addr = addrlist; addr; addr = addr->next) + { + /* + * See if this address is already present... + */ + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + if (httpAddrEqual(&(addr->addr), &(lis->address)) && + _httpAddrPort(&(addr->addr)) == _httpAddrPort(&(lis->address))) + break; + + if (lis) + { + httpAddrString(&lis->address, temp, sizeof(temp)); + cupsdLogMessage(CUPSD_LOG_WARN, + "Duplicate listen address \"%s\" ignored!", temp); + continue; + } + + /* + * Allocate another listener... + */ + + if (!Listeners) + Listeners = cupsArrayNew(NULL, NULL); + + if (!Listeners) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate %s at line %d - %s.", + line, linenum, strerror(errno)); + break; + } + + if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate %s at line %d - %s.", + line, linenum, strerror(errno)); + break; + } + + cupsArrayAdd(Listeners, lis); + + /* + * Copy the current address and log it... + */ + + memcpy(&(lis->address), &(addr->addr), sizeof(lis->address)); + lis->fd = -1; + +#ifdef HAVE_SSL + if (!strcasecmp(line, "SSLPort") || !strcasecmp(line, "SSLListen")) + lis->encryption = HTTP_ENCRYPT_ALWAYS; +#endif /* HAVE_SSL */ + + httpAddrString(&lis->address, temp, sizeof(temp)); + +#ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv6)", temp, + ntohs(lis->address.ipv6.sin6_port)); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (lis->address.addr.sa_family == AF_LOCAL) + cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s (Domain)", temp); + else +#endif /* AF_LOCAL */ + cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d (IPv4)", temp, + ntohs(lis->address.ipv4.sin_port)); + + if (!httpAddrLocalhost(&(lis->address))) + { +#ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + RemotePort = ntohs(lis->address.ipv6.sin6_port); + else +#endif /* AF_INET6 */ + RemotePort = ntohs(lis->address.ipv4.sin_port); + } + } + + /* + * Free the list... + */ + + httpAddrFreeList(addrlist); + } + else if (!strcasecmp(line, "BrowseAddress") && value) + { + /* + * Add a browse address to the list... + */ + + cupsd_dirsvc_addr_t *dira; /* New browse address array */ + + + if (NumBrowsers == 0) + dira = malloc(sizeof(cupsd_dirsvc_addr_t)); + else + dira = realloc(Browsers, (NumBrowsers + 1) * sizeof(cupsd_dirsvc_addr_t)); + + if (!dira) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate BrowseAddress at line %d - %s.", + linenum, strerror(errno)); + continue; + } + + Browsers = dira; + dira += NumBrowsers; + + memset(dira, 0, sizeof(cupsd_dirsvc_addr_t)); + + if (!strcasecmp(value, "@LOCAL")) + { + /* + * Send browse data to all local interfaces... + */ + + strcpy(dira->iface, "*"); + NumBrowsers ++; + } + else if (!strncasecmp(value, "@IF(", 4)) + { + /* + * Send browse data to the named interface... + */ + + strlcpy(dira->iface, value + 4, sizeof(Browsers[0].iface)); + + ptr = dira->iface + strlen(dira->iface) - 1; + if (*ptr == ')') + *ptr = '\0'; + + NumBrowsers ++; + } + else if ((addrlist = get_address(value, BrowsePort)) != NULL) + { + /* + * Only IPv4 addresses are supported... + */ + + for (addr = addrlist; addr; addr = addr->next) + if (addr->addr.addr.sa_family == AF_INET) + break; + + if (addr) + { + memcpy(&(dira->to), &(addrlist->addr), sizeof(dira->to)); + httpAddrString(&(dira->to), temp, sizeof(temp)); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Sending browsing info to %s:%d (IPv4)", + temp, ntohs(dira->to.ipv4.sin_port)); + + NumBrowsers ++; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.", + value, linenum); + + httpAddrFreeList(addrlist); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.", + value, linenum); + } + else if (!strcasecmp(line, "BrowseOrder") && value) + { + /* + * "BrowseOrder Deny,Allow" or "BrowseOrder Allow,Deny"... + */ + + if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL) + location = cupsdAddLocation("CUPS_INTERNAL_BROWSE_ACL"); + + if (location == NULL) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to initialize browse access control list!"); + else if (!strncasecmp(value, "deny", 4)) + location->order_type = CUPSD_AUTH_ALLOW; + else if (!strncasecmp(value, "allow", 5)) + location->order_type = CUPSD_AUTH_DENY; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown BrowseOrder value %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "BrowseProtocols") || + !strcasecmp(line, "BrowseLocalProtocols") || + !strcasecmp(line, "BrowseRemoteProtocols")) + { + /* + * "BrowseProtocols name [... name]" + * "BrowseLocalProtocols name [... name]" + * "BrowseRemoteProtocols name [... name]" + */ + + int protocols = parse_protocols(value); + + if (protocols < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown browse protocol \"%s\" on line %d.", + value, linenum); + break; + } + + if (strcasecmp(line, "BrowseLocalProtocols")) + BrowseRemoteProtocols = protocols; + if (strcasecmp(line, "BrowseRemoteProtocols")) + BrowseLocalProtocols = protocols; + } + else if ((!strcasecmp(line, "BrowseAllow") || + !strcasecmp(line, "BrowseDeny")) && value) + { + /* + * BrowseAllow [From] host/ip... + * BrowseDeny [From] host/ip... + */ + + if ((location = cupsdFindLocation("CUPS_INTERNAL_BROWSE_ACL")) == NULL) + location = cupsdAddLocation("CUPS_INTERNAL_BROWSE_ACL"); + + if (location == NULL) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to initialize browse access control list!"); + else + { + while (*value) + { + if (!strncasecmp(value, "from", 4)) + { + /* + * Strip leading "from"... + */ + + value += 4; + + while (isspace(*value & 255)) + value ++; + + if (!*value) + break; + } + + /* + * Find the end of the value... + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + while (isspace(*valueptr & 255)) + *valueptr++ = '\0'; + + /* + * 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")) + { + /* + * All hosts... + */ + + if (!strcasecmp(line, "BrowseAllow")) + cupsdAllowIP(location, zeros, zeros); + else + cupsdDenyIP(location, zeros, zeros); + } + else if (!strcasecmp(value, "none")) + { + /* + * No hosts... + */ + + if (!strcasecmp(line, "BrowseAllow")) + cupsdAllowIP(location, ones, zeros); + else + cupsdDenyIP(location, ones, zeros); + } +#ifdef AF_INET6 + else if (value[0] == '*' || value[0] == '.' || + (!isdigit(value[0] & 255) && value[0] != '[')) +#else + else if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255)) +#endif /* AF_INET6 */ + { + /* + * Host or domain name... + */ + + if (value[0] == '*') + value ++; + + if (!strcasecmp(line, "BrowseAllow")) + cupsdAllowHost(location, value); + else + cupsdDenyHost(location, value); + } + else + { + /* + * One of many IP address forms... + */ + + if (!get_addr_and_mask(value, ip, mask)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.", + value, linenum); + break; + } + + if (!strcasecmp(line, "BrowseAllow")) + cupsdAllowIP(location, ip, mask); + else + cupsdDenyIP(location, ip, mask); + } + + /* + * Advance to next value... + */ + + value = valueptr; + } + } + } + else if (!strcasecmp(line, "BrowseRelay") && value) + { + /* + * BrowseRelay [from] source [to] destination + */ + + if (NumRelays == 0) + relay = malloc(sizeof(cupsd_dirsvc_relay_t)); + else + relay = realloc(Relays, (NumRelays + 1) * sizeof(cupsd_dirsvc_relay_t)); + + if (!relay) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate BrowseRelay at line %d - %s.", + linenum, strerror(errno)); + continue; + } + + Relays = relay; + relay += NumRelays; + + memset(relay, 0, sizeof(cupsd_dirsvc_relay_t)); + + if (!strncasecmp(value, "from ", 5)) + { + /* + * 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 + */ + +#ifdef AF_INET6 + if (value[0] == '*' || value[0] == '.' || + (!isdigit(value[0] & 255) && value[0] != '[')) +#else + if (value[0] == '*' || value[0] == '.' || !isdigit(value[0] & 255)) +#endif /* AF_INET6 */ + { + /* + * Host or domain name... + */ + + if (value[0] == '*') + value ++; + + strlcpy(temp, value, sizeof(temp)); + if ((ptr = strchr(temp, ' ')) != NULL) + *ptr = '\0'; + + relay->from.type = CUPSD_AUTH_NAME; + + if ((relay->from.mask.name.name = strdup(temp)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate BrowseRelay name at line %d - %s.", + linenum, strerror(errno)); + continue; + } + + relay->from.mask.name.length = strlen(temp); + } + else + { + /* + * One of many IP address forms... + */ + + if (!get_addr_and_mask(value, ip, mask)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad netmask value %s on line %d.", + value, linenum); + break; + } + + relay->from.type = CUPSD_AUTH_IP; + memcpy(relay->from.mask.ip.address, ip, + sizeof(relay->from.mask.ip.address)); + memcpy(relay->from.mask.ip.netmask, mask, + sizeof(relay->from.mask.ip.netmask)); + } + + /* + * Skip value and trailing whitespace... + */ + + for (; *value; value ++) + if (isspace(*value)) + break; + + while (isspace(*value)) + value ++; + + if (!strncasecmp(value, "to ", 3)) + { + /* + * Strip leading "to"... + */ + + value += 3; + + while (isspace(*value)) + value ++; + } + + /* + * Get "to" address and port... + */ + + if ((addrlist = get_address(value, BrowsePort)) != NULL) + { + /* + * Only IPv4 addresses are supported... + */ + + for (addr = addrlist; addr; addr = addr->next) + if (addr->addr.addr.sa_family == AF_INET) + break; + + if (addr) + { + memcpy(&(relay->to), &(addrlist->addr), sizeof(relay->to)); + + httpAddrString(&(relay->to), temp, sizeof(temp)); + + if (relay->from.type == CUPSD_AUTH_IP) + snprintf(temp2, sizeof(temp2), "%u.%u.%u.%u/%u.%u.%u.%u", + relay->from.mask.ip.address[0] >> 24, + (relay->from.mask.ip.address[0] >> 16) & 255, + (relay->from.mask.ip.address[0] >> 8) & 255, + relay->from.mask.ip.address[0] & 255, + relay->from.mask.ip.netmask[0] >> 24, + (relay->from.mask.ip.netmask[0] >> 16) & 255, + (relay->from.mask.ip.netmask[0] >> 8) & 255, + relay->from.mask.ip.netmask[0] & 255); + else + strlcpy(temp2, relay->from.mask.name.name, sizeof(temp2)); + + cupsdLogMessage(CUPSD_LOG_INFO, "Relaying from %s to %s:%d (IPv4)", + temp2, temp, ntohs(relay->to.ipv4.sin_port)); + + NumRelays ++; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.", + value, linenum); + + httpAddrFreeList(addrlist); + } + else + { + if (relay->from.type == CUPSD_AUTH_NAME) + free(relay->from.mask.name.name); + + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad relay address %s at line %d.", + value, linenum); + } + } + else if (!strcasecmp(line, "BrowsePoll") && value) + { + /* + * BrowsePoll address[:port] + */ + + char *portname; /* Port name */ + int portnum; /* Port number */ + struct servent *service; /* Service */ + + + /* + * Extract the port name from the address... + */ + + if ((portname = strrchr(value, ':')) != NULL && !strchr(portname, ']')) + { + *portname++ = '\0'; + + if (isdigit(*portname & 255)) + portnum = atoi(portname); + else if ((service = getservbyname(portname, NULL)) != NULL) + portnum = ntohs(service->s_port); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Lookup of service \"%s\" failed!", + portname); + continue; + } + } + else + portnum = ippPort(); + + /* + * Add the poll entry... + */ + + if (NumPolled == 0) + pollp = malloc(sizeof(cupsd_dirsvc_poll_t)); + else + pollp = realloc(Polled, (NumPolled + 1) * sizeof(cupsd_dirsvc_poll_t)); + + if (!pollp) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate BrowsePoll at line %d - %s.", + linenum, strerror(errno)); + continue; + } + + Polled = pollp; + pollp += NumPolled; + + NumPolled ++; + memset(pollp, 0, sizeof(cupsd_dirsvc_poll_t)); + + strlcpy(pollp->hostname, value, sizeof(pollp->hostname)); + pollp->port = portnum; + + cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname, + pollp->port); + } + else if (!strcasecmp(line, "DefaultAuthType") && value) + { + /* + * DefaultAuthType {basic,digest,basicdigest,negotiate} + */ + + if (!strcasecmp(value, "none")) + DefaultAuthType = CUPSD_AUTH_NONE; + else if (!strcasecmp(value, "basic")) + DefaultAuthType = CUPSD_AUTH_BASIC; + else if (!strcasecmp(value, "digest")) + DefaultAuthType = CUPSD_AUTH_DIGEST; + else if (!strcasecmp(value, "basicdigest")) + DefaultAuthType = CUPSD_AUTH_BASICDIGEST; +#ifdef HAVE_GSSAPI + else if (!strcasecmp(value, "negotiate")) + DefaultAuthType = CUPSD_AUTH_NEGOTIATE; +#endif /* HAVE_GSSAPI */ + else + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Unknown default authorization type %s on line %d.", + value, linenum); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + } +#ifdef HAVE_SSL + else if (!strcasecmp(line, "DefaultEncryption")) + { + /* + * DefaultEncryption {Never,IfRequested,Required} + */ + + if (!value || !strcasecmp(value, "never")) + DefaultEncryption = HTTP_ENCRYPT_NEVER; + else if (!strcasecmp(value, "required")) + DefaultEncryption = HTTP_ENCRYPT_REQUIRED; + else if (!strcasecmp(value, "ifrequested")) + DefaultEncryption = HTTP_ENCRYPT_IF_REQUESTED; + else + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Unknown default encryption %s on line %d.", + value, linenum); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + } +#endif /* HAVE_SSL */ + else if (!strcasecmp(line, "User") && value) + { + /* + * User ID to run as... + */ + + if (isdigit(value[0] & 255)) + { + int uid = atoi(value); + + if (!uid) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Will not use User 0 as specified on line %d " + "for security reasons. You must use a non-" + "privileged account instead.", + linenum); + else + User = atoi(value); + } + else + { + struct passwd *p; /* Password information */ + + endpwent(); + p = getpwnam(value); + + if (p) + { + if (!p->pw_uid) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Will not use User %s (UID=0) as specified on line " + "%d for security reasons. You must use a non-" + "privileged account instead.", + value, linenum); + else + User = p->pw_uid; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown User \"%s\" on line %d, ignoring!", + value, linenum); + } + } + else if (!strcasecmp(line, "Group") && value) + { + /* + * Group ID to run as... + */ + + if (isdigit(value[0])) + Group = atoi(value); + else + { + endgrent(); + group = getgrnam(value); + + if (group != NULL) + Group = group->gr_gid; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown Group \"%s\" on line %d, ignoring!", + value, linenum); + } + } + else if (!strcasecmp(line, "SystemGroup") && value) + { + /* + * SystemGroup (admin) group(s)... + */ + + if (!parse_groups(value)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown SystemGroup \"%s\" on line %d, ignoring!", + value, linenum); + } + else if (!strcasecmp(line, "HostNameLookups") && value) + { + /* + * Do hostname lookups? + */ + + if (!strcasecmp(value, "off") || !strcasecmp(value, "no") || + !strcasecmp(value, "false")) + HostNameLookups = 0; + else if (!strcasecmp(value, "on") || !strcasecmp(value, "yes") || + !strcasecmp(value, "true")) + HostNameLookups = 1; + else if (!strcasecmp(value, "double")) + HostNameLookups = 2; + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "AccessLogLevel") && value) + { + /* + * Amount of logging to do to access log... + */ + + if (!strcasecmp(value, "all")) + AccessLogLevel = CUPSD_ACCESSLOG_ALL; + else if (!strcasecmp(value, "actions")) + AccessLogLevel = CUPSD_ACCESSLOG_ACTIONS; + else if (!strcasecmp(value, "config")) + AccessLogLevel = CUPSD_ACCESSLOG_CONFIG; + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown AccessLogLevel %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "LogLevel") && value) + { + /* + * Amount of logging to do to error log... + */ + + if (!strcasecmp(value, "debug2")) + LogLevel = CUPSD_LOG_DEBUG2; + else if (!strcasecmp(value, "debug")) + LogLevel = CUPSD_LOG_DEBUG; + else if (!strcasecmp(value, "info")) + LogLevel = CUPSD_LOG_INFO; + else if (!strcasecmp(value, "notice")) + LogLevel = CUPSD_LOG_NOTICE; + else if (!strcasecmp(value, "warn")) + LogLevel = CUPSD_LOG_WARN; + else if (!strcasecmp(value, "error")) + LogLevel = CUPSD_LOG_ERROR; + else if (!strcasecmp(value, "crit")) + LogLevel = CUPSD_LOG_CRIT; + else if (!strcasecmp(value, "alert")) + LogLevel = CUPSD_LOG_ALERT; + else if (!strcasecmp(value, "emerg")) + LogLevel = CUPSD_LOG_EMERG; + else if (!strcasecmp(value, "none")) + LogLevel = CUPSD_LOG_NONE; + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "LogTimeFormat") && value) + { + /* + * Amount of logging to do to error log... + */ + + if (!strcasecmp(value, "standard")) + LogTimeFormat = CUPSD_TIME_STANDARD; + else if (!strcasecmp(value, "usecs")) + LogTimeFormat = CUPSD_TIME_USECS; + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogTimeFormat %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "PrintcapFormat") && value) + { + /* + * Format of printcap file? + */ + + if (!strcasecmp(value, "bsd")) + PrintcapFormat = PRINTCAP_BSD; + else if (!strcasecmp(value, "plist")) + PrintcapFormat = PRINTCAP_PLIST; + else if (!strcasecmp(value, "solaris")) + PrintcapFormat = PRINTCAP_SOLARIS; + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "ServerTokens") && value) + { + /* + * Set the string used for the Server header... + */ + + struct utsname plat; /* Platform info */ + + + uname(&plat); + + if (!strcasecmp(value, "ProductOnly")) + cupsdSetString(&ServerHeader, "CUPS"); + else if (!strcasecmp(value, "Major")) + cupsdSetString(&ServerHeader, "CUPS/1"); + else if (!strcasecmp(value, "Minor")) + cupsdSetString(&ServerHeader, "CUPS/1.4"); + else if (!strcasecmp(value, "Minimal")) + cupsdSetString(&ServerHeader, CUPS_MINIMAL); + else if (!strcasecmp(value, "OS")) + cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s)", plat.sysname); + else if (!strcasecmp(value, "Full")) + cupsdSetStringf(&ServerHeader, CUPS_MINIMAL " (%s) IPP/1.1", + plat.sysname); + else if (!strcasecmp(value, "None")) + cupsdClearString(&ServerHeader); + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d.", + value, linenum); + } + else if (!strcasecmp(line, "PassEnv") && value) + { + /* + * PassEnv variable [... variable] + */ + + for (; *value;) + { + for (valuelen = 0; value[valuelen]; valuelen ++) + if (isspace(value[valuelen]) || value[valuelen] == ',') + break; + + if (value[valuelen]) + { + value[valuelen] = '\0'; + valuelen ++; + } + + cupsdSetEnv(value, NULL); + + for (value += valuelen; *value; value ++) + if (!isspace(*value) || *value != ',') + break; + } + } + else if (!strcasecmp(line, "ServerAlias") && value) + { + if (!ServerAlias) + ServerAlias = cupsArrayNew(NULL, NULL); + + cupsdAddAlias(ServerAlias, value); + } + else if (!strcasecmp(line, "SetEnv") && value) + { + /* + * SetEnv variable value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (*valueptr) + { + /* + * Found a value... + */ + + while (isspace(*valueptr & 255)) + *valueptr++ = '\0'; + + cupsdSetEnv(value, valueptr); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing value for SetEnv directive on line %d.", + linenum); + } +#ifdef HAVE_SSL + else if (!strcasecmp(line, "SSLOptions")) + { + /* + * SSLOptions options + */ + + if (!value || !strcasecmp(value, "none")) + SSLOptions = CUPSD_SSL_NONE; + else if (!strcasecmp(value, "noemptyfragments")) + SSLOptions = CUPSD_SSL_NOEMPTY; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown value \"%s\" for SSLOptions directive on " + "line %d.", value, linenum); + } +#endif /* HAVE_SSL */ + else + { + /* + * Find a simple variable in the list... + */ + + for (i = NUM_VARS, var = variables; i > 0; i --, var ++) + if (!strcasecmp(line, var->name)) + break; + + if (i == 0) + { + /* + * Unknown directive! Output an error message and continue... + */ + + if (!value) + cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.", + line, linenum); + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.", + line, linenum); + continue; + } + + switch (var->type) + { + case CUPSD_VARTYPE_INTEGER : + if (!value) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing integer value for %s on line %d!", + line, linenum); + else + { + int n; /* Number */ + char *units; /* Units */ + + + n = strtol(value, &units, 0); + + if (units && *units) + { + if (tolower(units[0] & 255) == 'g') + n *= 1024 * 1024 * 1024; + else if (tolower(units[0] & 255) == 'm') + n *= 1024 * 1024; + else if (tolower(units[0] & 255) == 'k') + n *= 1024; + else if (tolower(units[0] & 255) == 't') + n *= 262144; + } + + if (n < 0) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad negative integer value for %s on line %d!", + line, linenum); + else + *((int *)var->ptr) = n; + } + break; + + case CUPSD_VARTYPE_BOOLEAN : + if (!value) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing boolean value for %s on line %d!", + line, linenum); + else if (!strcasecmp(value, "true") || + !strcasecmp(value, "on") || + !strcasecmp(value, "enabled") || + !strcasecmp(value, "yes") || + atoi(value) != 0) + *((int *)var->ptr) = TRUE; + else if (!strcasecmp(value, "false") || + !strcasecmp(value, "off") || + !strcasecmp(value, "disabled") || + !strcasecmp(value, "no") || + !strcasecmp(value, "0")) + *((int *)var->ptr) = FALSE; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown boolean value %s on line %d.", + value, linenum); + break; + + case CUPSD_VARTYPE_PATHNAME : + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing pathname value for %s on line %d!", + line, linenum); + break; + } + + if (value[0] == '/') + strlcpy(temp, value, sizeof(temp)); + else + snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value); + + if (access(temp, 0)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "File or directory for \"%s %s\" on line %d " + "does not exist!", line, value, linenum); + break; + } + + case CUPSD_VARTYPE_STRING : + cupsdSetString((char **)var->ptr, value); + break; + } + } + } + + return (1); +} + + +/* + * 'read_location()' - Read a definition. + */ + +static int /* O - New line number or 0 on error */ +read_location(cups_file_t *fp, /* I - Configuration file */ + char *location, /* I - Location name/path */ + int linenum) /* I - Current line number */ +{ + cupsd_location_t *loc, /* New location */ + *parent; /* Parent location */ + char line[HTTP_MAX_BUFFER], + /* Line buffer */ + *value, /* Value for directive */ + *valptr; /* Pointer into value */ + + + if ((parent = cupsdAddLocation(location)) == NULL) + return (0); + + parent->limit = CUPSD_AUTH_LIMIT_ALL; + loc = parent; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Decode the directive... + */ + + if (!strcasecmp(line, "")) + return (linenum); + else if (!strcasecmp(line, "limit = 0; + while (*value) + { + for (valptr = value; !isspace(*valptr & 255) && *valptr; valptr ++); + + if (*valptr) + *valptr++ = '\0'; + + if (!strcmp(value, "ALL")) + loc->limit = CUPSD_AUTH_LIMIT_ALL; + else if (!strcmp(value, "GET")) + loc->limit |= CUPSD_AUTH_LIMIT_GET; + else if (!strcmp(value, "HEAD")) + loc->limit |= CUPSD_AUTH_LIMIT_HEAD; + else if (!strcmp(value, "OPTIONS")) + loc->limit |= CUPSD_AUTH_LIMIT_OPTIONS; + else if (!strcmp(value, "POST")) + loc->limit |= CUPSD_AUTH_LIMIT_POST; + else if (!strcmp(value, "PUT")) + loc->limit |= CUPSD_AUTH_LIMIT_PUT; + else if (!strcmp(value, "TRACE")) + loc->limit |= CUPSD_AUTH_LIMIT_TRACE; + else + cupsdLogMessage(CUPSD_LOG_WARN, "Unknown request type %s on line %d!", + value, linenum); + + for (value = valptr; isspace(*value & 255); value ++); + } + + if (!strcasecmp(line, "limit = CUPSD_AUTH_LIMIT_ALL ^ loc->limit; + + parent->limit &= ~loc->limit; + } + else if (!strcasecmp(line, "") || + !strcasecmp(line, "")) + loc = parent; + else if (!parse_aaa(loc, line, value, linenum)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown Location directive %s on line %d.", + line, linenum); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + } + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unexpected end-of-file at line %d while reading location!", + linenum); + + return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum); +} + + +/* + * 'read_policy()' - Read a definition. + */ + +static int /* O - New line number or 0 on error */ +read_policy(cups_file_t *fp, /* I - Configuration file */ + char *policy, /* I - Location name/path */ + int linenum) /* I - Current line number */ +{ + int i; /* Looping var */ + cupsd_policy_t *pol; /* Policy */ + cupsd_location_t *op; /* Policy operation */ + int num_ops; /* Number of IPP operations */ + ipp_op_t ops[100]; /* Operations */ + char line[HTTP_MAX_BUFFER], + /* Line buffer */ + *value, /* Value for directive */ + *valptr; /* Pointer into value */ + + + /* + * Create the policy... + */ + + if ((pol = cupsdAddPolicy(policy)) == NULL) + return (0); + + /* + * Read from the file... + */ + + op = NULL; + num_ops = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Decode the directive... + */ + + if (!strcasecmp(line, "")) + { + if (op) + cupsdLogMessage(CUPSD_LOG_WARN, + "Missing before on line %d!", + linenum); + + /* + * Verify that we have an explicit policy for Validate-Job and + * CUPS-Get-Document, which ensures that upgrades do not introduce new + * security issues... + */ + + if ((op = cupsdFindPolicyOp(pol, IPP_VALIDATE_JOB)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_PRINT_JOB)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for Validate-Job using the Print-Job limit as a + * template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for Validate-Job defined in policy %s " + "- using Print-Job's policy", pol->name); + + cupsdAddPolicyOp(pol, op, IPP_VALIDATE_JOB); + } + } + + if ((op = cupsdFindPolicyOp(pol, CUPS_GET_DOCUMENT)) == NULL || + op->op == IPP_ANY_OPERATION) + { + if ((op = cupsdFindPolicyOp(pol, IPP_SEND_DOCUMENT)) != NULL && + op->op != IPP_ANY_OPERATION) + { + /* + * Add a new limit for CUPS-Get-Document using the Send-Document + * limit as a template... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "No limit for CUPS-Get-Document defined in policy %s " + "- using Send-Document's policy", pol->name); + + cupsdAddPolicyOp(pol, op, CUPS_GET_DOCUMENT); + } + } + + return (linenum); + } + else if (!strcasecmp(line, "") && op) + { + /* + * Finish the current operation limit... + */ + + if (num_ops > 1) + { + /* + * Copy the policy to the other operations... + */ + + for (i = 1; i < num_ops; i ++) + cupsdAddPolicyOp(pol, op, ops[i]); + } + + op = NULL; + } + else if (!op) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing directive before %s on line %d.", + line, linenum); + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + else if (!parse_aaa(op, line, value, linenum)) + { + if (op) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown Policy Limit directive %s on line %d.", + line, linenum); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown Policy directive %s on line %d.", + line, linenum); + + if (FatalErrors & CUPSD_FATAL_CONFIG) + return (0); + } + } + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unexpected end-of-file at line %d while reading policy \"%s\"!", + linenum, policy); + + return ((FatalErrors & CUPSD_FATAL_CONFIG) ? 0 : linenum); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/conf.h b/scheduler/conf.h new file mode 100644 index 0000000000..963274fd35 --- /dev/null +++ b/scheduler/conf.h @@ -0,0 +1,300 @@ +/* + * "$Id$" + * + * Configuration file definitions for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + + +/* + * Log levels... + */ + +typedef enum +{ + CUPSD_LOG_PPD = -4, /* Used internally for PPD keywords */ + CUPSD_LOG_ATTR, /* Used internally for attributes */ + CUPSD_LOG_STATE, /* Used internally for state-reasons */ + CUPSD_LOG_PAGE, /* Used internally for page logging */ + CUPSD_LOG_NONE, + CUPSD_LOG_EMERG, /* Emergency issues */ + CUPSD_LOG_ALERT, /* Something bad happened that needs attention */ + CUPSD_LOG_CRIT, /* Critical error but server continues */ + CUPSD_LOG_ERROR, /* Error condition */ + CUPSD_LOG_WARN, /* Warning */ + CUPSD_LOG_NOTICE, /* Normal condition that needs logging */ + CUPSD_LOG_INFO, /* General information */ + CUPSD_LOG_DEBUG, /* General debugging */ + CUPSD_LOG_DEBUG2 /* Detailed debugging */ +} cupsd_loglevel_t; + +typedef enum +{ + CUPSD_ACCESSLOG_CONFIG, /* Log config requests */ + CUPSD_ACCESSLOG_ACTIONS, /* Log config, print, and job management requests */ + CUPSD_ACCESSLOG_ALL /* Log everything */ +} cupsd_accesslog_t; + +typedef enum +{ + CUPSD_TIME_STANDARD, /* "Standard" Apache/CLF format */ + CUPSD_TIME_USECS /* Standard format with microseconds */ +} cupsd_time_t; + + +/* + * FatalErrors flags... + */ + +#define CUPSD_FATAL_NONE 0 /* No errors are fatal */ +#define CUPSD_FATAL_BROWSE 1 /* Browse bind errors are fatal */ +#define CUPSD_FATAL_CONFIG 2 /* Config file syntax errors are fatal */ +#define CUPSD_FATAL_LISTEN 4 /* Listen/Port bind errors are fatal */ +#define CUPSD_FATAL_LOG 8 /* Log file errors are fatal */ +#define CUPSD_FATAL_PERMISSIONS 16 /* File permission errors are fatal */ +#define CUPSD_FATAL_ALL ~0 /* All errors are fatal */ + + +/* + * Printcap formats... + */ + +#define PRINTCAP_BSD 0 /* Berkeley LPD format */ +#define PRINTCAP_SOLARIS 1 /* Solaris lpsched format */ +#define PRINTCAP_PLIST 2 /* Mac OS X plist format */ + + +/* + * SSL options (bits)... + */ + +#define CUPSD_SSL_NONE 0 /* No special options */ +#define CUPSD_SSL_NOEMPTY 1 /* Do not insert empty fragments */ + + +/* + * ServerAlias data... + */ + +typedef struct +{ + size_t namelen; /* Length of alias name */ + char name[1]; /* Alias name */ +} cupsd_alias_t; + + +/* + * Globals... + */ + +VAR char *ConfigurationFile VALUE(NULL), + /* Configuration file to use */ + *ServerName VALUE(NULL), + /* FQDN for server */ + *ServerAdmin VALUE(NULL), + /* Administrator's email */ + *ServerRoot VALUE(NULL), + /* Root directory for scheduler */ + *ServerBin VALUE(NULL), + /* Root directory for binaries */ + *StateDir VALUE(NULL), + /* Root directory for state data */ + *RequestRoot VALUE(NULL), + /* Directory for request files */ + *DocumentRoot VALUE(NULL); + /* Root directory for documents */ +VAR cups_array_t *ServerAlias VALUE(NULL); + /* Alias names for server */ +VAR int ServerNameIsIP VALUE(0); + /* Is the ServerName an IP address? */ +VAR int NumSystemGroups VALUE(0); + /* Number of system group names */ +VAR char *SystemGroups[MAX_SYSTEM_GROUPS] + VALUE({0}); + /* System group names */ +VAR gid_t SystemGroupIDs[MAX_SYSTEM_GROUPS] + VALUE({0}); + /* System group IDs */ +VAR char *AccessLog VALUE(NULL), + /* Access log filename */ + *ErrorLog VALUE(NULL), + /* Error log filename */ + *PageLog VALUE(NULL), + /* Page log filename */ + *CacheDir VALUE(NULL), + /* Cache file directory */ + *DataDir VALUE(NULL), + /* Data file directory */ + *DefaultLanguage VALUE(NULL), + /* Default language encoding */ + *DefaultLocale VALUE(NULL), + /* Default locale */ + *DefaultPaperSize VALUE(NULL), + /* Default paper size */ + *ErrorPolicy VALUE(NULL), + /* Default printer-error-policy */ + *RIPCache VALUE(NULL), + /* Amount of memory for RIPs */ + *TempDir VALUE(NULL), + /* Temporary directory */ + *Printcap VALUE(NULL), + /* Printcap file */ + *PrintcapGUI VALUE(NULL), + /* GUI program to use for IRIX */ + *FontPath VALUE(NULL), + /* Font search path */ + *RemoteRoot VALUE(NULL), + /* Remote root user */ + *Classification VALUE(NULL); + /* Classification of system */ +VAR uid_t User VALUE(1); + /* User ID for server */ +VAR gid_t Group VALUE(0); + /* Group ID for server */ +VAR cupsd_accesslog_t AccessLogLevel VALUE(CUPSD_ACCESSLOG_ACTIONS); + /* Access log level */ +VAR int ClassifyOverride VALUE(0), + /* Allow overrides? */ + ConfigFilePerm VALUE(0640), + /* Permissions for config files */ + LogDebugHistory VALUE(200), + /* Amount of automatic debug history */ + FatalErrors VALUE(CUPSD_FATAL_CONFIG), + /* Which errors are fatal? */ + LogFilePerm VALUE(0644); + /* Permissions for log files */ +VAR cupsd_loglevel_t LogLevel VALUE(CUPSD_LOG_WARN); + /* Error log level */ +VAR cupsd_time_t LogTimeFormat VALUE(CUPSD_TIME_STANDARD); + /* Log file time format */ +VAR int MaxClients VALUE(100), + /* Maximum number of clients */ + MaxClientsPerHost VALUE(0), + /* Maximum number of clients per host */ + MaxCopies VALUE(CUPS_DEFAULT_MAX_COPIES), + /* Maximum number of copies per job */ + MaxLogSize VALUE(1024 * 1024), + /* Maximum size of log files */ + MaxPrinterHistory VALUE(10), + /* Maximum printer state history */ + 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? */ + FileDevice VALUE(FALSE), + /* Allow file: devices? */ + FilterLimit VALUE(0), + /* Max filter cost at any time */ + FilterLevel VALUE(0), + /* Current filter level */ + FilterNice VALUE(0), + /* Nice value for filters */ + ReloadTimeout VALUE(DEFAULT_KEEPALIVE), + /* Timeout before reload from SIGHUP */ + RootCertDuration VALUE(300), + /* Root certificate update interval */ + RunUser VALUE(0), + /* User to run as, used for files */ + PrintcapFormat VALUE(PRINTCAP_BSD), + /* Format of printcap file? */ + DefaultShared VALUE(TRUE), + /* Share printers by default? */ + MultipleOperationTimeout VALUE(DEFAULT_TIMEOUT); + /* multiple-operation-time-out value */ +VAR cups_file_t *AccessFile VALUE(NULL), + /* Access log file */ + *ErrorFile VALUE(NULL), + /* Error log file */ + *PageFile VALUE(NULL); + /* Page log file */ +VAR char *PageLogFormat VALUE(NULL); + /* Page log format */ +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_SSL +VAR char *ServerCertificate VALUE(NULL); + /* Server certificate file */ +# if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) +VAR char *ServerKey VALUE(NULL); + /* Server key file */ +# endif /* HAVE_LIBSSL || HAVE_GNUTLS */ +VAR int SSLOptions VALUE(CUPSD_SSL_NONE); + /* SSL/TLS options */ +#endif /* HAVE_SSL */ + +#ifdef HAVE_LAUNCHD +VAR int LaunchdTimeout VALUE(DEFAULT_KEEPALIVE); + /* Time after which an idle cupsd will exit */ +#endif /* HAVE_LAUNCHD */ + +#ifdef __APPLE__ +VAR int AppleQuotas VALUE(TRUE); + /* Use Apple PrintService Quotas instead of CUPS quotas */ +#endif /* __APPLE__ */ + +#ifdef HAVE_AUTHORIZATION_H +VAR char *SystemGroupAuthKey VALUE(NULL); + /* System group auth key */ +#endif /* HAVE_AUTHORIZATION_H */ + + +/* + * Prototypes... + */ + +extern void cupsdAddAlias(cups_array_t *aliases, const char *name); +extern int cupsdCheckPermissions(const char *filename, + const char *suffix, int mode, + int user, int group, int is_dir, + int create_dir); +extern void cupsdFreeAliases(cups_array_t *aliases); +extern char *cupsdGetDateTime(struct timeval *t, cupsd_time_t format); +#ifdef HAVE_GSSAPI +extern int cupsdLogGSSMessage(int level, int major_status, + int minor_status, + const char *message, ...); +#endif /* HAVE_GSSAPI */ +extern int cupsdLogJob(cupsd_job_t *job, int level, const char *message, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +#endif /* __GNUC__ */ +; +extern int cupsdLogMessage(int level, const char *message, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +#endif /* __GNUC__ */ +; +extern int cupsdLogPage(cupsd_job_t *job, const char *page); +extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code); +extern int cupsdReadConfiguration(void); +extern int cupsdWriteErrorLog(int level, const char *message); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cups-deviced.c b/scheduler/cups-deviced.c new file mode 100644 index 0000000000..4198e19d1d --- /dev/null +++ b/scheduler/cups-deviced.c @@ -0,0 +1,806 @@ +/* + * "$Id$" + * + * Device scanning mini-daemon for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Scan for devices and return an IPP response. + * add_device() - Add a new device to the list. + * compare_devices() - Compare device names to eliminate duplicates. + * get_current_time() - Get the current time as a double value in seconds. + * get_device() - Get a device from a backend. + * process_children() - Process all dead children... + * sigchld_handler() - Handle 'child' signals from old processes. + * start_backend() - Run a backend to gather the available devices. + */ + +/* + * Include necessary headers... + */ + +#include "util.h" +#include +#include +#include +#include +#include + + +/* + * Constants... + */ + +#define MAX_BACKENDS 200 /* Maximum number of backends we'll run */ + + +/* + * Backend information... + */ + +typedef struct +{ + char *name; /* Name of backend */ + int pid, /* Process ID */ + status; /* Exit status */ + cups_file_t *pipe; /* Pipe from backend stdout */ + int count; /* Number of devices found */ +} cupsd_backend_t; + + +/* + * Device information structure... + */ + +typedef struct +{ + char device_class[128], /* Device class */ + device_info[128], /* Device info/description */ + device_uri[1024]; /* Device URI */ +} cupsd_device_t; + + +/* + * Local globals... + */ + +static int num_backends = 0, + /* Total backends */ + active_backends = 0; + /* Active backends */ +static cupsd_backend_t backends[MAX_BACKENDS]; + /* Array of backends */ +static struct pollfd backend_fds[MAX_BACKENDS]; + /* Array for poll() */ +static cups_array_t *devices; /* Array of devices */ +static int normal_user; /* Normal user ID */ +static int device_limit; /* Maximum number of devices */ +static int send_class, /* Send device-class attribute? */ + send_info, /* Send device-info attribute? */ + send_make_and_model, + /* Send device-make-and-model attribute? */ + send_uri, /* Send device-uri attribute? */ + send_id, /* Send device-id attribute? */ + send_location; /* Send device-location attribute? */ +static int dead_children = 0; + /* Dead children? */ + + +/* + * Local functions... + */ + +static int add_device(const char *device_class, + const char *device_make_and_model, + const char *device_info, + const char *device_uri, + const char *device_id, + const char *device_location); +static int compare_devices(cupsd_device_t *p0, + cupsd_device_t *p1); +static double get_current_time(void); +static int get_device(cupsd_backend_t *backend); +static void process_children(void); +static void sigchld_handler(int sig); +static int start_backend(const char *backend, int root); + + +/* + * 'main()' - Scan for devices and return an IPP response. + * + * Usage: + * + * cups-deviced request_id limit options + */ + +int /* O - Exit code */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int request_id; /* Request ID */ + int timeout; /* Timeout in seconds */ + const char *server_bin; /* CUPS_SERVERBIN environment variable */ + char filename[1024]; /* Backend directory filename */ + cups_dir_t *dir; /* Directory pointer */ + cups_dentry_t *dent; /* Directory entry */ + double current_time, /* Current time */ + end_time; /* Ending time */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + cups_array_t *requested, /* requested-attributes values */ + *exclude, /* exclude-schemes values */ + *include; /* include-schemes values */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + setbuf(stderr, NULL); + + /* + * Check the command-line... + */ + + if (argc != 6) + { + fputs("Usage: cups-deviced request-id limit timeout user-id options\n", stderr); + + return (1); + } + + request_id = atoi(argv[1]); + if (request_id < 1) + { + fprintf(stderr, "ERROR: [cups-deviced] Bad request ID %d!\n", request_id); + + return (1); + } + + device_limit = atoi(argv[2]); + if (device_limit < 0) + { + fprintf(stderr, "ERROR: [cups-deviced] Bad limit %d!\n", device_limit); + + return (1); + } + + timeout = atoi(argv[3]); + if (timeout < 1) + { + fprintf(stderr, "ERROR: [cups-deviced] Bad timeout %d!\n", timeout); + + return (1); + } + + normal_user = atoi(argv[4]); + if (normal_user <= 0) + { + fprintf(stderr, "ERROR: [cups-deviced] Bad user %d!\n", normal_user); + + return (1); + } + + num_options = cupsParseOptions(argv[5], 0, &options); + requested = cupsdCreateStringsArray(cupsGetOption("requested-attributes", + num_options, options)); + exclude = cupsdCreateStringsArray(cupsGetOption("exclude-schemes", + num_options, options)); + include = cupsdCreateStringsArray(cupsGetOption("include-schemes", + num_options, options)); + + if (!requested || cupsArrayFind(requested, "all") != NULL) + { + send_class = send_info = send_make_and_model = send_uri = send_id = + send_location = 1; + } + else + { + send_class = cupsArrayFind(requested, "device-class") != NULL; + send_info = cupsArrayFind(requested, "device-info") != NULL; + send_make_and_model = cupsArrayFind(requested, "device-make-and-model") != NULL; + send_uri = cupsArrayFind(requested, "device-uri") != NULL; + send_id = cupsArrayFind(requested, "device-id") != NULL; + send_location = cupsArrayFind(requested, "device-location") != NULL; + } + + /* + * Listen to child signals... + */ + +#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, SIGCHLD); + action.sa_handler = sigchld_handler; + sigaction(SIGCHLD, &action, NULL); +#else + signal(SIGCLD, sigchld_handler); /* No, SIGCLD isn't a typo... */ +#endif /* HAVE_SIGSET */ + + /* + * Try opening the backend directory... + */ + + if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL) + server_bin = CUPS_SERVERBIN; + + snprintf(filename, sizeof(filename), "%s/backend", server_bin); + + if ((dir = cupsDirOpen(filename)) == NULL) + { + fprintf(stderr, "ERROR: [cups-deviced] Unable to open backend directory " + "\"%s\": %s", filename, strerror(errno)); + + return (1); + } + + /* + * Setup the devices array... + */ + + devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); + + /* + * Loop through all of the device backends... + */ + + while ((dent = cupsDirRead(dir)) != NULL) + { + /* + * Skip entries that are not executable files... + */ + + if (!S_ISREG(dent->fileinfo.st_mode) || + !isalnum(dent->filename[0] & 255) || + (dent->fileinfo.st_mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR)) + continue; + + /* + * Skip excluded or not included backends... + */ + + if (cupsArrayFind(exclude, dent->filename) || + (include && !cupsArrayFind(include, dent->filename))) + continue; + + /* + * Backends without permissions for normal users run as root, + * all others run as the unprivileged user... + */ + + start_backend(dent->filename, + !(dent->fileinfo.st_mode & (S_IRWXG | S_IRWXO))); + } + + cupsDirClose(dir); + + /* + * Collect devices... + */ + + if (getenv("SOFTWARE")) + puts("Content-Type: application/ipp\n"); + + cupsdSendIPPHeader(IPP_OK, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US"); + + end_time = get_current_time() + timeout; + + while (active_backends > 0 && (current_time = get_current_time()) < end_time) + { + /* + * Collect the output from the backends... + */ + + timeout = (int)(1000 * (end_time - current_time)); + + if (poll(backend_fds, num_backends, timeout) > 0) + { + for (i = 0; i < num_backends; i ++) + if (backend_fds[i].revents && backends[i].pipe) + { + cups_file_t *bpipe = backends[i].pipe; + /* Copy of pipe for backend... */ + + do + { + if (get_device(backends + i)) + { + backend_fds[i].fd = 0; + backend_fds[i].events = 0; + break; + } + } + while (bpipe->ptr && + memchr(bpipe->ptr, '\n', bpipe->end - bpipe->ptr)); + } + } + + /* + * Get exit status from children... + */ + + if (dead_children) + process_children(); + } + + cupsdSendIPPTrailer(); + + /* + * Terminate any remaining backends and exit... + */ + + if (active_backends > 0) + { + for (i = 0; i < num_backends; i ++) + if (backends[i].pid) + kill(backends[i].pid, SIGTERM); + } + + return (0); +} + + +/* + * 'add_device()' - Add a new device to the list. + */ + +static int /* O - 0 on success, -1 on error */ +add_device( + const char *device_class, /* I - Device class */ + const char *device_make_and_model, /* I - Device make and model */ + const char *device_info, /* I - Device information */ + const char *device_uri, /* I - Device URI */ + const char *device_id, /* I - 1284 device ID */ + const char *device_location) /* I - Physical location */ +{ + cupsd_device_t *device; /* New device */ + + + /* + * Allocate memory for the device record... + */ + + if ((device = calloc(1, sizeof(cupsd_device_t))) == NULL) + { + fputs("ERROR: [cups-deviced] Ran out of memory allocating a device!\n", + stderr); + return (-1); + } + + /* + * Copy the strings over... + */ + + strlcpy(device->device_class, device_class, sizeof(device->device_class)); + strlcpy(device->device_info, device_info, sizeof(device->device_info)); + strlcpy(device->device_uri, device_uri, sizeof(device->device_uri)); + + /* + * Add the device to the array and return... + */ + + if (cupsArrayFind(devices, device)) + { + /* + * Avoid duplicates! + */ + + free(device); + } + else + { + cupsArrayAdd(devices, device); + + if (device_limit <= 0 || cupsArrayCount(devices) < device_limit) + { + /* + * Send device info... + */ + + cupsdSendIPPGroup(IPP_TAG_PRINTER); + if (send_class) + cupsdSendIPPString(IPP_TAG_KEYWORD, "device-class", + device_class); + if (send_info) + cupsdSendIPPString(IPP_TAG_TEXT, "device-info", device_info); + if (send_make_and_model) + cupsdSendIPPString(IPP_TAG_TEXT, "device-make-and-model", + device_make_and_model); + if (send_uri) + cupsdSendIPPString(IPP_TAG_URI, "device-uri", device_uri); + if (send_id) + cupsdSendIPPString(IPP_TAG_TEXT, "device-id", + device_id ? device_id : ""); + if (send_location) + cupsdSendIPPString(IPP_TAG_TEXT, "device-location", + device_location ? device_location : ""); + + fflush(stdout); + fputs("DEBUG: Flushed attributes...\n", stderr); + } + } + + return (0); +} + + +/* + * 'compare_devices()' - Compare device names to eliminate duplicates. + */ + +static int /* O - Result of comparison */ +compare_devices(cupsd_device_t *d0, /* I - First device */ + cupsd_device_t *d1) /* I - Second device */ +{ + int diff; /* Difference between strings */ + + + /* + * Sort devices by device-info, device-class, and device-uri... + */ + + if ((diff = cupsdCompareNames(d0->device_info, d1->device_info)) != 0) + return (diff); + else if ((diff = strcasecmp(d0->device_class, d1->device_class)) != 0) + return (diff); + else + return (strcasecmp(d0->device_uri, d1->device_uri)); +} + + +/* + * 'get_current_time()' - Get the current time as a double value in seconds. + */ + +static double /* O - Time in seconds */ +get_current_time(void) +{ + struct timeval curtime; /* Current time */ + + + gettimeofday(&curtime, NULL); + + return (curtime.tv_sec + 0.000001 * curtime.tv_usec); +} + + +/* + * 'get_device()' - Get a device from a backend. + */ + +static int /* O - 0 on success, -1 on error */ +get_device(cupsd_backend_t *backend) /* I - Backend to read from */ +{ + char line[2048], /* Line from backend */ + temp[2048], /* Copy of line */ + *ptr, /* Pointer into line */ + *dclass, /* Device class */ + *uri, /* Device URI */ + *make_model, /* Make and model */ + *info, /* Device info */ + *device_id, /* 1284 device ID */ + *location; /* Physical location */ + + + if (cupsFileGets(backend->pipe, line, sizeof(line))) + { + /* + * Each line is of the form: + * + * class URI "make model" "name" ["1284 device ID"] ["location"] + */ + + strlcpy(temp, line, sizeof(temp)); + + /* + * device-class + */ + + dclass = temp; + + for (ptr = temp; *ptr; ptr ++) + if (isspace(*ptr & 255)) + break; + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + + /* + * device-uri + */ + + if (!*ptr) + goto error; + + for (uri = ptr; *ptr; ptr ++) + if (isspace(*ptr & 255)) + break; + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + + /* + * device-make-and-model + */ + + if (*ptr != '\"') + goto error; + + for (ptr ++, make_model = ptr; *ptr && *ptr != '\"'; ptr ++) + { + if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + } + + if (*ptr != '\"') + goto error; + + for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0'); + + /* + * device-info + */ + + if (*ptr != '\"') + goto error; + + for (ptr ++, info = ptr; *ptr && *ptr != '\"'; ptr ++) + { + if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + } + + if (*ptr != '\"') + goto error; + + for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0'); + + /* + * device-id + */ + + if (*ptr == '\"') + { + for (ptr ++, device_id = ptr; *ptr && *ptr != '\"'; ptr ++) + { + if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + } + + if (*ptr != '\"') + goto error; + + for (*ptr++ = '\0'; isspace(*ptr & 255); *ptr++ = '\0'); + + /* + * device-location + */ + + if (*ptr == '\"') + { + for (ptr ++, location = ptr; *ptr && *ptr != '\"'; ptr ++) + { + if (*ptr == '\\' && ptr[1]) + _cups_strcpy(ptr, ptr + 1); + } + + if (*ptr != '\"') + goto error; + + *ptr = '\0'; + } + else + location = NULL; + } + else + { + device_id = NULL; + location = NULL; + } + + /* + * Add the device to the array of available devices... + */ + + if (!add_device(dclass, make_model, info, uri, device_id, location)) + fprintf(stderr, "DEBUG: [cups-deviced] Found device \"%s\"...\n", uri); + + return (0); + } + + /* + * End of file... + */ + + cupsFileClose(backend->pipe); + backend->pipe = NULL; + + return (-1); + + /* + * Bad format; strip trailing newline and write an error message. + */ + + error: + + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + + fprintf(stderr, "ERROR: [cups-deviced] Bad line from \"%s\": %s\n", + backend->name, line); + return (0); +} + + +/* + * 'process_children()' - Process all dead children... + */ + +static void +process_children(void) +{ + int i; /* Looping var */ + int status; /* Exit status of child */ + int pid; /* Process ID of child */ + cupsd_backend_t *backend; /* Current backend */ + const char *name; /* Name of process */ + + + /* + * Reset the dead_children flag... + */ + + dead_children = 0; + + /* + * Collect the exit status of some children... + */ + +#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 */ + { + if (status == SIGTERM) + status = 0; + + for (i = num_backends, backend = backends; i > 0; i --, backend ++) + if (backend->pid == pid) + break; + + if (i > 0) + { + name = backend->name; + backend->pid = 0; + backend->status = status; + + active_backends --; + } + else + name = "Unknown"; + + if (status) + { + if (WIFEXITED(status)) + fprintf(stderr, + "ERROR: [cups-deviced] PID %d (%s) stopped with status %d!\n", + pid, name, WEXITSTATUS(status)); + else + fprintf(stderr, + "ERROR: [cups-deviced] PID %d (%s) crashed on signal %d!\n", + pid, name, WTERMSIG(status)); + } + else + fprintf(stderr, + "DEBUG: [cups-deviced] PID %d (%s) exited with no errors.\n", + pid, name); + } +} + + +/* + * 'sigchld_handler()' - Handle 'child' signals from old processes. + */ + +static void +sigchld_handler(int sig) /* I - Signal number */ +{ + (void)sig; + + /* + * Flag that we have dead children... + */ + + dead_children = 1; + + /* + * Reset the signal handler as needed... + */ + +#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) + signal(SIGCLD, sigchld_handler); +#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */ +} + + +/* + * 'start_backend()' - Run a backend to gather the available devices. + */ + +static int /* O - 0 on success, -1 on error */ +start_backend(const char *name, /* I - Backend to run */ + int root) /* I - Run as root? */ +{ + const char *server_bin; /* CUPS_SERVERBIN environment variable */ + char program[1024]; /* Full path to backend */ + cupsd_backend_t *backend; /* Current backend */ + char *argv[2]; /* Command-line arguments */ + + + if (num_backends >= MAX_BACKENDS) + { + fprintf(stderr, "ERROR: Too many backends (%d)!\n", num_backends); + return (-1); + } + + if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL) + server_bin = CUPS_SERVERBIN; + + snprintf(program, sizeof(program), "%s/backend/%s", server_bin, name); + + backend = backends + num_backends; + + argv[0] = (char *)name; + argv[1] = NULL; + + if ((backend->pipe = cupsdPipeCommand(&(backend->pid), program, argv, + root ? 0 : normal_user)) == NULL) + { + fprintf(stderr, "ERROR: [cups-deviced] Unable to execute \"%s\" - %s\n", + program, strerror(errno)); + return (-1); + } + + /* + * Fill in the rest of the backend information... + */ + + fprintf(stderr, "DEBUG: [cups-deviced] Started backend %s (PID %d)\n", + program, backend->pid); + + backend_fds[num_backends].fd = cupsFileNumber(backend->pipe); + backend_fds[num_backends].events = POLLIN; + + backend->name = strdup(name); + backend->status = 0; + backend->count = 0; + + active_backends ++; + num_backends ++; + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx new file mode 100644 index 0000000000..6f4e7be158 --- /dev/null +++ b/scheduler/cups-driverd.cxx @@ -0,0 +1,2530 @@ +/* + * "$Id$" + * + * PPD/driver support for the Common UNIX Printing System (CUPS). + * + * This program handles listing and installing static PPD files, PPD files + * created from driver information files, and dynamically generated PPD files + * using driver helper programs. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Scan for drivers and return an IPP response. + * add_ppd() - Add a PPD file. + * cat_drv() - Generate a PPD from a driver info file. + * cat_ppd() - Copy a PPD file to stdout. + * copy_static() - Copy a static PPD file to stdout. + * compare_inodes() - Compare two inodes. + * compare_matches() - Compare PPD match scores for sorting. + * compare_names() - Compare PPD filenames for sorting. + * compare_ppds() - Compare PPD file make and model names for sorting. + * dump_ppds_dat() - Dump the contents of the ppds.dat file. + * free_array() - Free an array of strings. + * list_ppds() - List PPD files. + * load_drv() - Load the PPDs from a driver information file. + * load_drivers() - Load driver-generated PPD files. + * load_ppds() - Load PPD files recursively. + * load_ppds_dat() - Load the ppds.dat file. + * regex_device_id() - Compile a regular expression based on the 1284 device + * ID. + * regex_string() - Construct a regular expression to compare a simple + * string. + */ + +/* + * Include necessary headers... + */ + +#include "util.h" +#include +#include +#include +#include +#include + + +/* + * Constants... + */ + +#define PPD_SYNC 0x50504437 /* Sync word for ppds.dat (PPD7) */ +#define PPD_MAX_LANG 32 /* Maximum languages */ +#define PPD_MAX_PROD 32 /* Maximum products */ +#define PPD_MAX_VERS 32 /* Maximum versions */ + +#define PPD_TYPE_POSTSCRIPT 0 /* PostScript PPD */ +#define PPD_TYPE_PDF 1 /* PDF PPD */ +#define PPD_TYPE_RASTER 2 /* CUPS raster PPD */ +#define PPD_TYPE_FAX 3 /* Facsimile/MFD PPD */ +#define PPD_TYPE_UNKNOWN 4 /* Other/hybrid PPD */ +#define PPD_TYPE_DRV 5 /* Driver info file */ + +static const char * const ppd_types[] = /* ppd-type values */ +{ + "postscript", + "pdf", + "raster", + "fax", + "unknown", + "drv" +}; + + +/* + * PPD information structures... + */ + +typedef struct /**** PPD record ****/ +{ + time_t mtime; /* Modification time */ + off_t size; /* Size in bytes */ + int model_number; /* cupsModelNumber */ + int type; /* ppd-type */ + char filename[512], /* Filename */ + name[512], /* PPD name */ + languages[PPD_MAX_LANG][6], + /* LanguageVersion/cupsLanguages */ + products[PPD_MAX_PROD][128], + /* Product strings */ + psversions[PPD_MAX_VERS][32], + /* PSVersion strings */ + make[128], /* Manufacturer */ + make_and_model[128], /* NickName/ModelName */ + device_id[256], /* IEEE 1284 Device ID */ + scheme[128]; /* PPD scheme */ +} ppd_rec_t; + +typedef struct /**** In-memory record ****/ +{ + int found; /* 1 if PPD is found */ + int matches; /* Match count */ + ppd_rec_t record; /* PPDs.dat record */ +} ppd_info_t; + + +/* + * Globals... + */ + +cups_array_t *Inodes = NULL, /* Inodes of directories we've visited */ + *PPDsByName = NULL, /* PPD files sorted by filename and name */ + *PPDsByMakeModel = NULL;/* PPD files sorted by make and model */ +int ChangedPPD; /* Did we change the PPD database? */ + + +/* + * Local functions... + */ + +static ppd_info_t *add_ppd(const char *filename, const char *name, + const char *language, const char *make, + const char *make_and_model, + const char *device_id, const char *product, + const char *psversion, time_t mtime, + size_t size, int model_number, int type, + const char *scheme); +static int cat_drv(const char *name, int request_id); +static int cat_ppd(const char *name, int request_id); +static int cat_static(const char *name, int request_id); +static int compare_inodes(struct stat *a, struct stat *b); +static int compare_matches(const ppd_info_t *p0, + const ppd_info_t *p1); +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 int dump_ppds_dat(void); +static void free_array(cups_array_t *a); +static int list_ppds(int request_id, int limit, const char *opt); +static int load_drivers(cups_array_t *include, + cups_array_t *exclude); +static int load_drv(const char *filename, const char *name, + cups_file_t *fp, time_t mtime, off_t size); +static int load_ppds(const char *d, const char *p, int descend); +static void load_ppds_dat(char *filename, size_t filesize, + int verbose); +static regex_t *regex_device_id(const char *device_id); +static regex_t *regex_string(const char *s); + + +/* + * 'main()' - Scan for drivers and return an IPP response. + * + * Usage: + * + * cups-driverd request_id limit options + */ + +int /* O - Exit code */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + /* + * Install or list PPDs... + */ + + if (argc == 3 && !strcmp(argv[1], "cat")) + return (cat_ppd(argv[2], 0)); + else if (argc == 2 && !strcmp(argv[1], "dump")) + return (dump_ppds_dat()); + else if (argc == 4 && !strcmp(argv[1], "get")) + return (cat_ppd(argv[3], atoi(argv[2]))); + else if (argc == 5 && !strcmp(argv[1], "list")) + return (list_ppds(atoi(argv[2]), atoi(argv[3]), argv[4])); + else + { + fputs("Usage: cups-driverd cat ppd-name\n", stderr); + fputs("Usage: cups-driverd dump\n", stderr); + fputs("Usage: cups-driverd get request_id ppd-name\n", stderr); + fputs("Usage: cups-driverd list request_id limit options\n", stderr); + return (1); + } +} + + +/* + * 'add_ppd()' - Add a PPD file. + */ + +static ppd_info_t * /* O - PPD */ +add_ppd(const char *filename, /* I - PPD filename */ + const char *name, /* I - PPD name */ + const char *language, /* I - LanguageVersion */ + const char *make, /* I - Manufacturer */ + const char *make_and_model, /* I - NickName/ModelName */ + const char *device_id, /* I - 1284DeviceID */ + const char *product, /* I - Product */ + const char *psversion, /* I - PSVersion */ + time_t mtime, /* I - Modification time */ + size_t size, /* I - File size */ + int model_number, /* I - Model number */ + int type, /* I - Driver type */ + const char *scheme) /* I - PPD scheme */ +{ + ppd_info_t *ppd; /* PPD */ + char *recommended; /* Foomatic driver string */ + + + /* + * Add a new PPD file... + */ + + if ((ppd = (ppd_info_t *)calloc(1, sizeof(ppd_info_t))) == NULL) + { + fprintf(stderr, + "ERROR: [cups-driverd] Ran out of memory for %d PPD files!\n", + cupsArrayCount(PPDsByName)); + return (NULL); + } + + /* + * Zero-out the PPD data and copy the values over... + */ + + ppd->found = 1; + ppd->record.mtime = mtime; + ppd->record.size = size; + ppd->record.model_number = model_number; + ppd->record.type = type; + + strlcpy(ppd->record.filename, filename, sizeof(ppd->record.filename)); + strlcpy(ppd->record.name, name, sizeof(ppd->record.name)); + strlcpy(ppd->record.languages[0], language, + sizeof(ppd->record.languages[0])); + strlcpy(ppd->record.products[0], product, sizeof(ppd->record.products[0])); + strlcpy(ppd->record.psversions[0], psversion, + sizeof(ppd->record.psversions[0])); + strlcpy(ppd->record.make, make, sizeof(ppd->record.make)); + strlcpy(ppd->record.make_and_model, make_and_model, + sizeof(ppd->record.make_and_model)); + strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id)); + strlcpy(ppd->record.scheme, scheme, sizeof(ppd->record.scheme)); + + /* + * Strip confusing (and often wrong) "recommended" suffix added by + * Foomatic drivers... + */ + + if ((recommended = strstr(ppd->record.make_and_model, + " (recommended)")) != NULL) + *recommended = '\0'; + + /* + * Add the PPD to the PPD arrays... + */ + + cupsArrayAdd(PPDsByName, ppd); + cupsArrayAdd(PPDsByMakeModel, ppd); + + /* + * Return the new PPD pointer... + */ + + return (ppd); +} + + +/* + * 'cat_drv()' - Generate a PPD from a driver info file. + */ + +static int /* O - Exit code */ +cat_drv(const char *name, /* I - PPD name */ + int request_id) /* I - Request ID for response? */ +{ + const char *datadir; // CUPS_DATADIR env var + ppdcSource *src; // PPD source file data + ppdcDriver *d; // Current driver + cups_file_t *out; // Stdout via CUPS file API + char message[2048], // status-message + filename[1024], // Full path to .drv file(s) + scheme[32], // URI scheme ("drv") + userpass[256], // User/password info (unused) + host[2], // Hostname (unused) + resource[1024], // Resource path (/dir/to/filename.drv) + *pc_file_name; // Filename portion of URI + int port; // Port number (unused) + + + // Determine where CUPS has installed the data files... + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + // Pull out the path to the .drv file... + if (httpSeparateURI(HTTP_URI_CODING_ALL, name, scheme, sizeof(scheme), + userpass, sizeof(userpass), host, sizeof(host), &port, + resource, sizeof(resource)) < HTTP_URI_OK || + strstr(resource, "../") || + (pc_file_name = strrchr(resource, '/')) == NULL || + pc_file_name == resource) + { + fprintf(stderr, "ERROR: Bad PPD name \"%s\"!\n", name); + + if (request_id) + { + snprintf(message, sizeof(message), "Bad PPD name \"%s\"!", name); + + cupsdSendIPPHeader(IPP_NOT_FOUND, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message); + cupsdSendIPPTrailer(); + } + + return (1); + } + + *pc_file_name++ = '\0'; + +#ifdef __APPLE__ + if (!strncmp(resource, "/Library/Printers/PPDs/Contents/Resources/", 42) || + !strncmp(resource, "/System/Library/Printers/PPDs/Contents/Resources/", 49)) + strlcpy(filename, resource, sizeof(filename)); + else +#endif // __APPLE__ + { + snprintf(filename, sizeof(filename), "%s/drv%s", datadir, resource); + if (access(filename, 0)) + snprintf(filename, sizeof(filename), "%s/model%s", datadir, resource); + } + + src = new ppdcSource(filename); + + for (d = (ppdcDriver *)src->drivers->first(); + d; + d = (ppdcDriver *)src->drivers->next()) + if (!strcmp(pc_file_name, d->pc_file_name->value) || + (d->file_name && !strcmp(pc_file_name, d->file_name->value))) + break; + + if (d) + { + ppdcArray *locales; // Locale names + ppdcCatalog *catalog; // Message catalog in .drv file + + + fprintf(stderr, "DEBUG2: [cups-driverd] %d locales defined in \"%s\"...\n", + src->po_files->count, filename); + + locales = new ppdcArray(); + for (catalog = (ppdcCatalog *)src->po_files->first(); + catalog; + catalog = (ppdcCatalog *)src->po_files->next()) + { + fprintf(stderr, "DEBUG2: [cups-driverd] Adding locale \"%s\"...\n", + catalog->locale->value); + catalog->locale->retain(); + locales->add(catalog->locale); + } + + if (request_id) + { + cupsdSendIPPHeader(IPP_OK, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPTrailer(); + fflush(stdout); + } + + out = cupsFileStdout(); + d->write_ppd_file(out, NULL, locales, src, PPDC_LFONLY); + cupsFileClose(out); + + locales->release(); + } + else + { + fprintf(stderr, "ERROR: PPD \"%s\" not found!\n", name); + + if (request_id) + { + snprintf(message, sizeof(message), "PPD \"%s\" not found!", name); + + cupsdSendIPPHeader(IPP_NOT_FOUND, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message); + cupsdSendIPPTrailer(); + } + } + + src->release(); + + return (!d); +} + + +/* + * 'cat_ppd()' - Copy a PPD file to stdout. + */ + +static int /* O - Exit code */ +cat_ppd(const char *name, /* I - PPD name */ + int request_id) /* I - Request ID for response? */ +{ + char scheme[256], /* Scheme from PPD name */ + *sptr, /* Pointer into scheme */ + line[1024], /* Line/filename */ + message[2048]; /* status-message */ + + + /* + * Figure out if this is a static or dynamic PPD file... + */ + + strlcpy(scheme, name, sizeof(scheme)); + if ((sptr = strchr(scheme, ':')) != NULL) + { + *sptr = '\0'; + + if (!strcmp(scheme, "file")) + { + /* + * "file:name" == "name"... + */ + + name += 5; + scheme[0] = '\0'; + } + } + else + scheme[0] = '\0'; + + if (request_id > 0) + puts("Content-Type: application/ipp\n"); + + if (!scheme[0]) + return (cat_static(name, request_id)); + else if (!strcmp(scheme, "drv")) + return (cat_drv(name, request_id)); + else + { + /* + * Dynamic PPD, see if we have a driver program to support it... + */ + + const char *serverbin; /* CUPS_SERVERBIN env var */ + char *argv[4]; /* Arguments for program */ + + + if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL) + serverbin = CUPS_SERVERBIN; + + snprintf(line, sizeof(line), "%s/driver/%s", serverbin, scheme); + if (access(line, X_OK)) + { + /* + * File does not exist or is not executable... + */ + + fprintf(stderr, "ERROR: [cups-driverd] Unable to access \"%s\" - %s\n", + line, strerror(errno)); + + if (request_id > 0) + { + snprintf(message, sizeof(message), "Unable to access \"%s\" - %s", + line, strerror(errno)); + + cupsdSendIPPHeader(IPP_NOT_FOUND, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message); + cupsdSendIPPTrailer(); + } + + return (1); + } + + /* + * Yes, let it cat the PPD file... + */ + + if (request_id) + { + cupsdSendIPPHeader(IPP_OK, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPTrailer(); + } + + argv[0] = scheme; + argv[1] = (char *)"cat"; + argv[2] = (char *)name; + argv[3] = NULL; + + if (cupsdExec(line, argv)) + { + /* + * Unable to execute driver... + */ + + fprintf(stderr, "ERROR: [cups-driverd] Unable to execute \"%s\" - %s\n", + line, strerror(errno)); + return (1); + } + } + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'copy_static()' - Copy a static PPD file to stdout. + */ + +static int /* O - Exit code */ +cat_static(const char *name, /* I - PPD name */ + int request_id) /* I - Request ID for response? */ +{ + cups_file_t *fp; /* PPD file */ + const char *datadir; /* CUPS_DATADIR env var */ + char line[1024], /* Line/filename */ + message[2048]; /* status-message */ +#ifdef __APPLE__ + const char *printerDriver, /* Pointer to .printerDriver extension */ + *slash; /* Pointer to next slash */ +#endif /* __APPLE__ */ + + + if (name[0] == '/' || strstr(name, "../") || strstr(name, "/..")) + { + /* + * Bad name... + */ + + fprintf(stderr, "ERROR: [cups-driverd] Bad PPD name \"%s\"!\n", name); + + if (request_id) + { + snprintf(message, sizeof(message), "Bad PPD name \"%s\"!", name); + + cupsdSendIPPHeader(IPP_NOT_FOUND, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message); + cupsdSendIPPTrailer(); + } + + return (1); + } + + /* + * Try opening the file... + */ + +#ifdef __APPLE__ + if (!strncmp(name, "System/Library/Printers/PPDs/Contents/Resources/", 48) || + !strncmp(name, "Library/Printers/PPDs/Contents/Resources/", 41) || + (!strncmp(name, "System/Library/Printers/", 24) && + (printerDriver = + strstr(name + 24, + ".printerDriver/Contents/Resources/PPDs")) != NULL && + (slash = strchr(name + 24, '/')) != NULL && + slash > printerDriver) || + (!strncmp(name, "Library/Printers/", 17) && + (printerDriver = + strstr(name + 17, + ".printerDriver/Contents/Resources/PPDs")) != NULL && + (slash = strchr(name + 17, '/')) != NULL && + slash > printerDriver)) + { + /* + * Map ppd-name to Mac OS X standard locations... + */ + + snprintf(line, sizeof(line), "/%s", name); + } + else + +#elif defined(__linux) + if (!strncmp(name, "lsb/usr/", 8)) + { + /* + * Map ppd-name to LSB standard /usr/share/ppd location... + */ + + snprintf(line, sizeof(line), "/usr/share/ppd/%s", name + 8); + } + else if (!strncmp(name, "lsb/opt/", 8)) + { + /* + * Map ppd-name to LSB standard /opt/share/ppd location... + */ + + snprintf(line, sizeof(line), "/opt/share/ppd/%s", name + 8); + } + else if (!strncmp(name, "lsb/local/", 10)) + { + /* + * Map ppd-name to LSB standard /usr/local/share/ppd location... + */ + + snprintf(line, sizeof(line), "/usr/local/share/ppd/%s", name + 10); + } + else + +#endif /* __APPLE__ */ + { + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + snprintf(line, sizeof(line), "%s/model/%s", datadir, name); + } + + if ((fp = cupsFileOpen(line, "r")) == NULL) + { + fprintf(stderr, "ERROR: [cups-driverd] Unable to open \"%s\" - %s\n", + line, strerror(errno)); + + if (request_id) + { + snprintf(message, sizeof(message), "Unable to open \"%s\" - %s", + line, strerror(errno)); + + cupsdSendIPPHeader(IPP_NOT_FOUND, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPString(IPP_TAG_TEXT, "status-message", message); + cupsdSendIPPTrailer(); + } + + return (1); + } + + if (request_id) + { + cupsdSendIPPHeader(IPP_OK, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + cupsdSendIPPTrailer(); + } + + /* + * Now copy the file to stdout... + */ + + while (cupsFileGets(fp, line, sizeof(line))) + puts(line); + + cupsFileClose(fp); + + return (0); +} + + +/* + * 'compare_inodes()' - Compare two inodes. + */ + +static int /* O - Result of comparison */ +compare_inodes(struct stat *a, /* I - First inode */ + struct stat *b) /* I - Second inode */ +{ + if (a->st_dev != b->st_dev) + return (a->st_dev - b->st_dev); + else + return (a->st_ino - b->st_ino); +} + + +/* + * 'compare_matches()' - Compare PPD match scores for sorting. + */ + +static int +compare_matches(const ppd_info_t *p0, /* I - First PPD */ + const ppd_info_t *p1) /* I - Second PPD */ +{ + if (p1->matches != p0->matches) + return (p1->matches - p0->matches); + else + return (cupsdCompareNames(p0->record.make_and_model, + p1->record.make_and_model)); +} + + +/* + * '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 */ +{ + int diff; /* Difference between strings */ + + + if ((diff = strcmp(p0->record.filename, p1->record.filename)) != 0) + return (diff); + else + return (strcmp(p0->record.name, p1->record.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 */ +{ + int diff; /* Difference between strings */ + + + /* + * First compare manufacturers... + */ + + if ((diff = strcasecmp(p0->record.make, p1->record.make)) != 0) + return (diff); + else if ((diff = cupsdCompareNames(p0->record.make_and_model, + p1->record.make_and_model)) != 0) + return (diff); + else + return (strcmp(p0->record.languages[0], p1->record.languages[0])); +} + + +/* + * 'dump_ppds_dat()' - Dump the contents of the ppds.dat file. + */ + +static int /* O - Exit status */ +dump_ppds_dat(void) +{ + char filename[1024]; /* ppds.dat filename */ + ppd_info_t *ppd; /* Current PPD */ + + + /* + * See if we a PPD database file... + */ + + load_ppds_dat(filename, sizeof(filename), 0); + + puts("mtime,size,model_number,type,filename,name,languages0,products0," + "psversions0,make,make_and_model,device_id,scheme"); + for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByName); + ppd; + ppd = (ppd_info_t *)cupsArrayNext(PPDsByName)) + printf("%d,%ld,%d,%d,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"," + "\"%s\",\"%s\"\n", + (int)ppd->record.mtime, (long)ppd->record.size, + ppd->record.model_number, ppd->record.type, ppd->record.filename, + ppd->record.name, ppd->record.languages[0], ppd->record.products[0], + ppd->record.psversions[0], ppd->record.make, + ppd->record.make_and_model, ppd->record.device_id, + ppd->record.scheme); + + return (0); +} + + +/* + * 'free_array()' - Free an array of strings. + */ + +static void +free_array(cups_array_t *a) /* I - Array to free */ +{ + char *ptr; /* Pointer to string */ + + + for (ptr = (char *)cupsArrayFirst(a); + ptr; + ptr = (char *)cupsArrayNext(a)) + free(ptr); + + cupsArrayDelete(a); +} + + +/* + * 'list_ppds()' - List PPD files. + */ + +static int /* O - Exit code */ +list_ppds(int request_id, /* I - Request ID */ + int limit, /* I - Limit */ + const char *opt) /* I - Option argument */ +{ + int i; /* Looping vars */ + int count; /* Number of PPDs to send */ + ppd_info_t *ppd; /* Current PPD file */ + cups_file_t *fp; /* ppds.dat file */ + char filename[1024], /* ppds.dat filename */ + model[1024]; /* Model directory */ + const char *cups_datadir; /* CUPS_DATADIR environment variable */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + cups_array_t *requested, /* requested-attributes values */ + *include, /* PPD schemes to include */ + *exclude; /* PPD schemes to exclude */ + const char *device_id, /* ppd-device-id option */ + *language, /* ppd-natural-language option */ + *make, /* ppd-make option */ + *make_and_model, /* ppd-make-and-model option */ + *model_number_str, /* ppd-model-number option */ + *product, /* ppd-product option */ + *psversion, /* ppd-psversion option */ + *type_str; /* ppd-type option */ + int model_number, /* ppd-model-number value */ + type, /* ppd-type value */ + make_and_model_len, /* Length of ppd-make-and-model */ + product_len, /* Length of ppd-product */ + send_device_id, /* Send ppd-device-id? */ + send_make, /* Send ppd-make? */ + send_make_and_model, /* Send ppd-make-and-model? */ + send_model_number, /* Send ppd-model-number? */ + send_name, /* Send ppd-name? */ + send_natural_language, /* Send ppd-natural-language? */ + send_product, /* Send ppd-product? */ + send_psversion, /* Send ppd-psversion? */ + send_type, /* Send ppd-type? */ + sent_header; /* Sent the IPP header? */ + regex_t *device_id_re, /* Regular expression for matching device ID */ + *make_and_model_re; /* Regular expression for matching make and model */ + regmatch_t re_matches[6]; /* Regular expression matches */ + cups_array_t *matches; /* Matching PPDs */ + + + fprintf(stderr, + "DEBUG2: [cups-driverd] list_ppds(request_id=%d, limit=%d, " + "opt=\"%s\"\n", request_id, limit, opt); + + /* + * See if we a PPD database file... + */ + + load_ppds_dat(filename, sizeof(filename), 1); + + /* + * Load all PPDs in the specified directory and below... + */ + + if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) + cups_datadir = CUPS_DATADIR; + + Inodes = cupsArrayNew((cups_array_func_t)compare_inodes, NULL); + + snprintf(model, sizeof(model), "%s/model", cups_datadir); + load_ppds(model, "", 1); + + snprintf(model, sizeof(model), "%s/drv", cups_datadir); + load_ppds(model, "", 1); + +#ifdef __APPLE__ + /* + * Load PPDs from standard Mac OS X locations... + */ + + load_ppds("/Library/Printers", + "Library/Printers", 0); + load_ppds("/Library/Printers/PPDs/Contents/Resources", + "Library/Printers/PPDs/Contents/Resources", 0); + load_ppds("/Library/Printers/PPDs/Contents/Resources/en.lproj", + "Library/Printers/PPDs/Contents/Resources/en.lproj", 0); + load_ppds("/System/Library/Printers", + "System/Library/Printers", 0); + load_ppds("/System/Library/Printers/PPDs/Contents/Resources", + "System/Library/Printers/PPDs/Contents/Resources", 0); + load_ppds("/System/Library/Printers/PPDs/Contents/Resources/en.lproj", + "System/Library/Printers/PPDs/Contents/Resources/en.lproj", 0); + +#elif defined(__linux) + /* + * Load PPDs from LSB-defined locations... + */ + + if (!access("/usr/local/share/ppd", 0)) + load_ppds("/usr/local/share/ppd", "lsb/local", 1); + if (!access("/usr/share/ppd", 0)) + load_ppds("/usr/share/ppd", "lsb/usr", 1); + if (!access("/opt/share/ppd", 0)) + load_ppds("/opt/share/ppd", "lsb/opt", 1); +#endif /* __APPLE__ */ + + /* + * Cull PPD files that are no longer present... + */ + + for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByName); + ppd; + ppd = (ppd_info_t *)cupsArrayNext(PPDsByName)) + if (!ppd->found) + { + /* + * Remove this PPD file from the list... + */ + + cupsArrayRemove(PPDsByName, ppd); + cupsArrayRemove(PPDsByMakeModel, ppd); + free(ppd); + + ChangedPPD = 1; + } + + /* + * Write the new ppds.dat file... + */ + + fprintf(stderr, "DEBUG: [cups-driverd] ChangedPPD=%d\n", ChangedPPD); + + if (ChangedPPD) + { + char newname[1024]; /* New filename */ + + snprintf(newname, sizeof(newname), "%s.%d", filename, (int)getpid()); + + if ((fp = cupsFileOpen(newname, "w")) != NULL) + { + unsigned ppdsync = PPD_SYNC; /* Sync word */ + + cupsFileWrite(fp, (char *)&ppdsync, sizeof(ppdsync)); + + for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByName); + ppd; + ppd = (ppd_info_t *)cupsArrayNext(PPDsByName)) + cupsFileWrite(fp, (char *)&(ppd->record), sizeof(ppd_rec_t)); + + cupsFileClose(fp); + + if (rename(newname, filename)) + fprintf(stderr, "ERROR: [cups-driverd] Unable to rename \"%s\" - %s\n", + newname, strerror(errno)); + else + fprintf(stderr, "INFO: [cups-driverd] Wrote \"%s\", %d PPDs...\n", + filename, cupsArrayCount(PPDsByName)); + } + else + fprintf(stderr, "ERROR: [cups-driverd] Unable to write \"%s\" - %s\n", + filename, strerror(errno)); + } + else + fputs("INFO: [cups-driverd] No new or changed PPDs...\n", stderr); + + /* + * Scan for dynamic PPD files... + */ + + num_options = cupsParseOptions(opt, 0, &options); + exclude = cupsdCreateStringsArray(cupsGetOption("exclude-schemes", + num_options, options)); + include = cupsdCreateStringsArray(cupsGetOption("include-schemes", + num_options, options)); + + load_drivers(include, exclude); + + /* + * Add the raw driver... + */ + + add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0, + PPD_TYPE_UNKNOWN, "raw"); + + /* + * Send IPP attributes... + */ + + requested = cupsdCreateStringsArray( + cupsGetOption("requested-attributes", num_options, + options)); + device_id = cupsGetOption("ppd-device-id", num_options, options); + language = cupsGetOption("ppd-natural-language", num_options, options); + make = cupsGetOption("ppd-make", num_options, options); + make_and_model = cupsGetOption("ppd-make-and-model", num_options, options); + model_number_str = cupsGetOption("ppd-model-number", num_options, options); + product = cupsGetOption("ppd-product", num_options, options); + psversion = cupsGetOption("ppd-psversion", num_options, options); + type_str = cupsGetOption("ppd-type", num_options, options); + + if (make_and_model) + make_and_model_len = strlen(make_and_model); + else + make_and_model_len = 0; + + if (product) + product_len = strlen(product); + else + product_len = 0; + + if (model_number_str) + model_number = atoi(model_number_str); + else + model_number = 0; + + if (type_str) + { + for (type = 0; + type < (int)(sizeof(ppd_types) / sizeof(ppd_types[0])); + type ++) + if (!strcmp(type_str, ppd_types[type])) + break; + + if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0]))) + { + fprintf(stderr, "ERROR: [cups-driverd] Bad ppd-type=\"%s\" ignored!\n", + type_str); + type_str = NULL; + } + } + else + type = 0; + + for (i = 0; i < num_options; i ++) + fprintf(stderr, "DEBUG2: [cups-driverd] %s=\"%s\"\n", options[i].name, + options[i].value); + + if (!requested || cupsArrayFind(requested, (void *)"all") != NULL) + { + send_name = 1; + send_make = 1; + send_make_and_model = 1; + send_model_number = 1; + send_natural_language = 1; + send_device_id = 1; + send_product = 1; + send_psversion = 1; + send_type = 1; + } + else + { + send_name = cupsArrayFind(requested, + (void *)"ppd-name") != NULL; + send_make = cupsArrayFind(requested, + (void *)"ppd-make") != NULL; + send_make_and_model = cupsArrayFind(requested, + (void *)"ppd-make-and-model") != NULL; + send_model_number = cupsArrayFind(requested, + (void *)"ppd-model-number") != NULL; + send_natural_language = cupsArrayFind(requested, + (void *)"ppd-natural-language") != NULL; + send_device_id = cupsArrayFind(requested, + (void *)"ppd-device-id") != NULL; + send_product = cupsArrayFind(requested, + (void *)"ppd-product") != NULL; + send_psversion = cupsArrayFind(requested, + (void *)"ppd-psversion") != NULL; + send_type = cupsArrayFind(requested, + (void *)"ppd-type") != NULL; + } + + /* + * Send the content type header to the scheduler; request_id can only be + * 0 when run manually since the scheduler enforces the IPP requirement for + * a request ID from 1 to 2^31-1... + */ + + if (request_id > 0) + puts("Content-Type: application/ipp\n"); + + sent_header = 0; + + if (limit <= 0 || limit > cupsArrayCount(PPDsByMakeModel)) + count = cupsArrayCount(PPDsByMakeModel); + else + count = limit; + + if (device_id || language || make || make_and_model || model_number_str || + product) + { + matches = cupsArrayNew((cups_array_func_t)compare_matches, NULL); + + if (device_id) + device_id_re = regex_device_id(device_id); + else + device_id_re = NULL; + + if (make_and_model) + make_and_model_re = regex_string(make_and_model); + else + make_and_model_re = NULL; + + for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByMakeModel); + ppd; + ppd = (ppd_info_t *)cupsArrayNext(PPDsByMakeModel)) + { + /* + * Filter PPDs based on make, model, product, language, model number, + * and/or device ID using the "matches" score value. An exact match + * for product, make-and-model, or device-id adds 3 to the score. + * Partial matches for make-and-model yield 1 or 2 points, and matches + * for the make and language add a single point. Results are then sorted + * by score, highest score first. + */ + + if (ppd->record.type < PPD_TYPE_POSTSCRIPT || + ppd->record.type >= PPD_TYPE_DRV) + continue; + + if (cupsArrayFind(exclude, ppd->record.scheme) || + (include && !cupsArrayFind(include, ppd->record.scheme))) + continue; + + ppd->matches = 0; + + if (device_id_re && + !regexec(device_id_re, ppd->record.device_id, + (int)(sizeof(re_matches) / sizeof(re_matches[0])), + re_matches, 0)) + { + /* + * Add the number of matching values from the device ID - it will be + * at least 2 (manufacturer and model), and as much as 3 (command set). + */ + + for (i = 1; i < (int)(sizeof(re_matches) / sizeof(re_matches[0])); i ++) + if (re_matches[i].rm_so >= 0) + ppd->matches ++; + } + + if (language) + { + for (i = 0; i < PPD_MAX_LANG; i ++) + if (!ppd->record.languages[i][0]) + break; + else if (!strcmp(ppd->record.languages[i], language)) + { + ppd->matches ++; + break; + } + } + + if (make && !strcasecmp(ppd->record.make, make)) + ppd->matches ++; + + if (make_and_model_re && + !regexec(make_and_model_re, ppd->record.make_and_model, + (int)(sizeof(re_matches) / sizeof(re_matches[0])), + re_matches, 0)) + { + // See how much of the make-and-model string we matched... + if (re_matches[0].rm_so == 0) + { + if (re_matches[0].rm_eo == make_and_model_len) + ppd->matches += 3; // Exact match + else + ppd->matches += 2; // Prefix match + } + else + ppd->matches ++; // Infix match + } + + if (model_number_str && ppd->record.model_number == model_number) + ppd->matches ++; + + if (product) + { + for (i = 0; i < PPD_MAX_PROD; i ++) + if (!ppd->record.products[i][0]) + break; + else if (!strcasecmp(ppd->record.products[i], product)) + { + ppd->matches += 3; + break; + } + } + + if (psversion) + { + for (i = 0; i < PPD_MAX_VERS; i ++) + if (!ppd->record.psversions[i][0]) + break; + else if (!strcasecmp(ppd->record.psversions[i], psversion)) + { + ppd->matches ++; + break; + } + } + + if (type_str && ppd->record.type == type) + ppd->matches ++; + + if (ppd->matches) + { + fprintf(stderr, "DEBUG2: [cups-driverd] %s matches with score %d!\n", + ppd->record.name, ppd->matches); + cupsArrayAdd(matches, ppd); + } + } + } + else if (include || exclude) + { + matches = cupsArrayNew((cups_array_func_t)compare_ppds, NULL); + + for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByMakeModel); + ppd; + ppd = (ppd_info_t *)cupsArrayNext(PPDsByMakeModel)) + { + /* + * Filter PPDs based on the include/exclude lists. + */ + + if (ppd->record.type < PPD_TYPE_POSTSCRIPT || + ppd->record.type >= PPD_TYPE_DRV) + continue; + + if (cupsArrayFind(exclude, ppd->record.scheme) || + (include && !cupsArrayFind(include, ppd->record.scheme))) + continue; + + cupsArrayAdd(matches, ppd); + } + } + else + matches = PPDsByMakeModel; + + for (ppd = (ppd_info_t *)cupsArrayFirst(matches); + count > 0 && ppd; + ppd = (ppd_info_t *)cupsArrayNext(matches)) + { + /* + * Skip invalid PPDs... + */ + + if (ppd->record.type < PPD_TYPE_POSTSCRIPT || + ppd->record.type >= PPD_TYPE_DRV) + continue; + + /* + * Send this PPD... + */ + + if (!sent_header) + { + sent_header = 1; + + cupsdSendIPPHeader(IPP_OK, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", + "en-US"); + } + + fprintf(stderr, "DEBUG2: [cups-driverd] Sending %s (%s)...\n", + ppd->record.name, ppd->record.make_and_model); + + count --; + + cupsdSendIPPGroup(IPP_TAG_PRINTER); + + if (send_name) + cupsdSendIPPString(IPP_TAG_NAME, "ppd-name", ppd->record.name); + + if (send_natural_language) + { + cupsdSendIPPString(IPP_TAG_LANGUAGE, "ppd-natural-language", + ppd->record.languages[0]); + + for (i = 1; i < PPD_MAX_LANG && ppd->record.languages[i][0]; i ++) + cupsdSendIPPString(IPP_TAG_LANGUAGE, "", ppd->record.languages[i]); + } + + if (send_make) + cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make", ppd->record.make); + + if (send_make_and_model) + cupsdSendIPPString(IPP_TAG_TEXT, "ppd-make-and-model", + ppd->record.make_and_model); + + if (send_device_id) + cupsdSendIPPString(IPP_TAG_TEXT, "ppd-device-id", + ppd->record.device_id); + + if (send_product) + { + cupsdSendIPPString(IPP_TAG_TEXT, "ppd-product", + ppd->record.products[0]); + + for (i = 1; i < PPD_MAX_PROD && ppd->record.products[i][0]; i ++) + cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.products[i]); + } + + if (send_psversion) + { + cupsdSendIPPString(IPP_TAG_TEXT, "ppd-psversion", + ppd->record.psversions[0]); + + for (i = 1; i < PPD_MAX_VERS && ppd->record.psversions[i][0]; i ++) + cupsdSendIPPString(IPP_TAG_TEXT, "", ppd->record.psversions[i]); + } + + if (send_type) + cupsdSendIPPString(IPP_TAG_KEYWORD, "ppd-type", + ppd_types[ppd->record.type]); + + if (send_model_number) + cupsdSendIPPInteger(IPP_TAG_INTEGER, "ppd-model-number", + ppd->record.model_number); + + /* + * If we have only requested the ppd-make attribute, then skip + * the remaining PPDs with this make... + */ + + if (cupsArrayFind(requested, (void *)"ppd-make") && + cupsArrayCount(requested) == 1) + { + const char *this_make; /* This ppd-make */ + + + for (this_make = ppd->record.make, + ppd = (ppd_info_t *)cupsArrayNext(matches); + ppd; + ppd = (ppd_info_t *)cupsArrayNext(matches)) + if (strcasecmp(this_make, ppd->record.make)) + break; + + cupsArrayPrev(matches); + } + } + + if (!sent_header) + { + cupsdSendIPPHeader(IPP_NOT_FOUND, request_id); + cupsdSendIPPGroup(IPP_TAG_OPERATION); + cupsdSendIPPString(IPP_TAG_CHARSET, "attributes-charset", "utf-8"); + cupsdSendIPPString(IPP_TAG_LANGUAGE, "attributes-natural-language", "en-US"); + } + + cupsdSendIPPTrailer(); + + return (0); +} + + +/* + * 'load_drv()' - Load the PPDs from a driver information file. + */ + +static int /* O - 1 on success, 0 on failure */ +load_drv(const char *filename, /* I - Actual filename */ + const char *name, /* I - Name to the rest of the world */ + cups_file_t *fp, /* I - File to read from */ + time_t mtime, /* I - Mod time of driver info file */ + off_t size) /* I - Size of driver info file */ +{ + ppdcSource *src; // Driver information file + ppdcDriver *d; // Current driver + ppdcAttr *device_id, // 1284DeviceID attribute + *product, // Current product value + *ps_version, // PSVersion attribute + *cups_fax, // cupsFax attribute + *nick_name; // NickName attribute + ppdcFilter *filter; // Current filter + ppd_info_t *ppd; // Current PPD + int products_found; // Number of products found + char uri[1024], // Driver URI + make_model[1024]; // Make and model + int type; // Driver type + + + /* + * Load the driver info file... + */ + + src = new ppdcSource(filename, fp); + + if (src->drivers->count == 0) + { + fprintf(stderr, + "ERROR: [cups-driverd] Bad driver information file \"%s\"!\n", + filename); + src->release(); + return (0); + } + + /* + * Add a dummy entry for the file... + */ + + add_ppd(name, name, "", "", "", "", "", "", mtime, size, 0, + PPD_TYPE_DRV, "drv"); + ChangedPPD = 1; + + /* + * Then the drivers in the file... + */ + + for (d = (ppdcDriver *)src->drivers->first(); + d; + d = (ppdcDriver *)src->drivers->next()) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0, + "/%s/%s", name, + d->file_name ? d->file_name->value : + d->pc_file_name->value); + + device_id = d->find_attr("1284DeviceID", NULL); + ps_version = d->find_attr("PSVersion", NULL); + nick_name = d->find_attr("NickName", NULL); + + if (nick_name) + strlcpy(make_model, nick_name->value->value, sizeof(make_model)); + else if (strncasecmp(d->model_name->value, d->manufacturer->value, + strlen(d->manufacturer->value))) + snprintf(make_model, sizeof(make_model), "%s %s, %s", + d->manufacturer->value, d->model_name->value, + d->version->value); + else + snprintf(make_model, sizeof(make_model), "%s, %s", d->model_name->value, + d->version->value); + + if ((cups_fax = d->find_attr("cupsFax", NULL)) != NULL && + !strcasecmp(cups_fax->value->value, "true")) + type = PPD_TYPE_FAX; + else if (d->type == PPDC_DRIVER_PS) + type = PPD_TYPE_POSTSCRIPT; + else if (d->type != PPDC_DRIVER_CUSTOM) + type = PPD_TYPE_RASTER; + else + { + for (filter = (ppdcFilter *)d->filters->first(), + type = PPD_TYPE_POSTSCRIPT; + filter; + filter = (ppdcFilter *)d->filters->next()) + if (strcasecmp(filter->mime_type->value, "application/vnd.cups-raster")) + type = PPD_TYPE_RASTER; + else if (strcasecmp(filter->mime_type->value, + "application/vnd.cups-pdf")) + type = PPD_TYPE_PDF; + } + + for (product = (ppdcAttr *)d->attrs->first(), products_found = 0, + ppd = NULL; + product; + product = (ppdcAttr *)d->attrs->next()) + if (!strcmp(product->name->value, "Product")) + { + if (!products_found) + ppd = add_ppd(name, uri, "en", d->manufacturer->value, make_model, + device_id ? device_id->value->value : "", + product->value->value, + ps_version ? ps_version->value->value : "(3010) 0", + mtime, size, d->model_number, type, "drv"); + else if (products_found < PPD_MAX_PROD) + strlcpy(ppd->record.products[products_found], product->value->value, + sizeof(ppd->record.products[0])); + else + break; + + products_found ++; + } + + if (!products_found) + add_ppd(name, uri, "en", d->manufacturer->value, make_model, + device_id ? device_id->value->value : "", + d->model_name->value, + ps_version ? ps_version->value->value : "(3010) 0", + mtime, size, d->model_number, type, "drv"); + } + + src->release(); + + return (1); +} + + +/* + * 'load_drivers()' - Load driver-generated PPD files. + */ + +static int /* O - 1 on success, 0 on failure */ +load_drivers(cups_array_t *include, /* I - Drivers to include */ + cups_array_t *exclude) /* I - Drivers to exclude */ +{ + int i; /* Looping var */ + char *start, /* Start of value */ + *ptr; /* Pointer into string */ + const char *server_bin, /* CUPS_SERVERBIN env variable */ + *scheme, /* Scheme for this driver */ + *scheme_end; /* Pointer to end of scheme */ + char drivers[1024]; /* Location of driver programs */ + int pid; /* Process ID for driver program */ + cups_file_t *fp; /* Pipe to driver program */ + cups_dir_t *dir; /* Directory pointer */ + cups_dentry_t *dent; /* Directory entry */ + char *argv[3], /* Arguments for command */ + filename[1024], /* Name of driver */ + line[2048], /* Line from driver */ + name[512], /* ppd-name */ + make[128], /* ppd-make */ + make_and_model[128], /* ppd-make-and-model */ + device_id[128], /* ppd-device-id */ + languages[128], /* ppd-natural-language */ + product[128], /* ppd-product */ + psversion[128], /* ppd-psversion */ + type_str[128]; /* ppd-type */ + int type; /* PPD type */ + ppd_info_t *ppd; /* Newly added PPD */ + + + /* + * Try opening the driver directory... + */ + + if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL) + server_bin = CUPS_SERVERBIN; + + snprintf(drivers, sizeof(drivers), "%s/driver", server_bin); + + if ((dir = cupsDirOpen(drivers)) == NULL) + { + fprintf(stderr, "ERROR: [cups-driverd] Unable to open driver directory " + "\"%s\": %s\n", + drivers, strerror(errno)); + return (0); + } + + /* + * Loop through all of the device drivers... + */ + + argv[1] = (char *)"list"; + argv[2] = NULL; + + while ((dent = cupsDirRead(dir)) != NULL) + { + /* + * Only look at executable files... + */ + + if (!(dent->fileinfo.st_mode & 0111) || !S_ISREG(dent->fileinfo.st_mode)) + continue; + + /* + * Include/exclude specific drivers... + */ + + if (exclude) + { + /* + * Look for "scheme" or "scheme*" (prefix match), and skip any matches. + */ + + for (scheme = (char *)cupsArrayFirst(exclude); + scheme; + scheme = (char *)cupsArrayNext(exclude)) + { + fprintf(stderr, "DEBUG: [cups-driverd] Exclude \"%s\" with \"%s\"?\n", + dent->filename, scheme); + scheme_end = scheme + strlen(scheme) - 1; + + if ((scheme_end > scheme && *scheme_end == '*' && + !strncmp(scheme, dent->filename, scheme_end - scheme)) || + !strcmp(scheme, dent->filename)) + { + fputs("DEBUG: [cups-driverd] Yes, exclude!\n", stderr); + break; + } + } + + if (scheme) + continue; + } + + if (include) + { + /* + * Look for "scheme" or "scheme*" (prefix match), and skip any non-matches. + */ + + for (scheme = (char *)cupsArrayFirst(include); + scheme; + scheme = (char *)cupsArrayNext(include)) + { + fprintf(stderr, "DEBUG: [cups-driverd] Include \"%s\" with \"%s\"?\n", + dent->filename, scheme); + scheme_end = scheme + strlen(scheme) - 1; + + if ((scheme_end > scheme && *scheme_end == '*' && + !strncmp(scheme, dent->filename, scheme_end - scheme)) || + !strcmp(scheme, dent->filename)) + { + fputs("DEBUG: [cups-driverd] Yes, include!\n", stderr); + break; + } + } + + if (!scheme) + continue; + } + else + scheme = dent->filename; + + /* + * Run the driver with no arguments and collect the output... + */ + + argv[0] = dent->filename; + snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename); + + if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL) + { + while (cupsFileGets(fp, line, sizeof(line))) + { + /* + * Each line is of the form: + * + * "ppd-name" ppd-natural-language "ppd-make" "ppd-make-and-model" \ + * "ppd-device-id" "ppd-product" "ppd-psversion" + */ + + device_id[0] = '\0'; + product[0] = '\0'; + psversion[0] = '\0'; + strcpy(type_str, "postscript"); + + if (sscanf(line, "\"%511[^\"]\"%127s%*[ \t]\"%127[^\"]\"" + "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\"" + "%*[ \t]\"%127[^\"]\"%*[ \t]\"%127[^\"]\"" + "%*[ \t]\"%127[^\"]\"", + name, languages, make, make_and_model, + device_id, product, psversion, type_str) < 4) + { + /* + * Bad format; strip trailing newline and write an error message. + */ + + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + + fprintf(stderr, "ERROR: [cups-driverd] Bad line from \"%s\": %s\n", + dent->filename, line); + break; + } + else + { + /* + * Add the device to the array of available devices... + */ + + if ((start = strchr(languages, ',')) != NULL) + *start++ = '\0'; + + for (type = 0; + type < (int)(sizeof(ppd_types) / sizeof(ppd_types[0])); + type ++) + if (!strcmp(type_str, ppd_types[type])) + break; + + if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0]))) + { + fprintf(stderr, + "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n", + type_str); + type = PPD_TYPE_UNKNOWN; + } + + ppd = add_ppd(filename, name, languages, make, make_and_model, + device_id, product, psversion, 0, 0, 0, type, scheme); + + if (!ppd) + { + cupsDirClose(dir); + cupsFileClose(fp); + return (0); + } + + if (start && *start) + { + for (i = 1; i < PPD_MAX_LANG && *start; i ++) + { + if ((ptr = strchr(start, ',')) != NULL) + *ptr++ = '\0'; + else + ptr = start + strlen(start); + + strlcpy(ppd->record.languages[i], start, + sizeof(ppd->record.languages[0])); + + start = ptr; + } + } + + fprintf(stderr, "DEBUG2: [cups-driverd] Added dynamic PPD \"%s\"...\n", + name); + } + } + + cupsFileClose(fp); + } + else + fprintf(stderr, "WARNING: [cups-driverd] Unable to execute \"%s\": %s\n", + filename, strerror(errno)); + } + + cupsDirClose(dir); + + return (1); +} + + +/* + * 'load_ppds()' - Load PPD files recursively. + */ + +static int /* O - 1 on success, 0 on failure */ +load_ppds(const char *d, /* I - Actual directory */ + const char *p, /* I - Virtual path in name */ + int descend) /* I - Descend into directories? */ +{ + struct stat dinfo, /* Directory information */ + *dinfoptr; /* Pointer to match */ + int i; /* Looping var */ + cups_file_t *fp; /* Pointer to file */ + cups_dir_t *dir; /* Directory pointer */ + cups_dentry_t *dent; /* Directory entry */ + char filename[1024], /* Name of PPD or directory */ + line[256], /* Line from backend */ + *ptr, /* Pointer into name */ + name[128], /* Name of PPD file */ + lang_version[64], /* PPD LanguageVersion */ + lang_encoding[64], /* PPD LanguageEncoding */ + country[64], /* Country code */ + manufacturer[256], /* Manufacturer */ + make_model[256], /* Make and Model */ + model_name[256], /* ModelName */ + nick_name[256], /* NickName */ + device_id[256], /* 1284DeviceID */ + product[256], /* Product */ + psversion[256], /* PSVersion */ + temp[512]; /* Temporary make and model */ + int model_number, /* cupsModelNumber */ + type; /* ppd-type */ + cups_array_t *products, /* Product array */ + *psversions, /* PSVersion array */ + *cups_languages; /* cupsLanguages array */ + 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", "zh" }, + { "czech", "cs" }, + { "danish", "da" }, + { "dutch", "nl" }, + { "english", "en" }, + { "finnish", "fi" }, + { "french", "fr" }, + { "german", "de" }, + { "greek", "el" }, + { "hungarian", "hu" }, + { "italian", "it" }, + { "japanese", "ja" }, + { "korean", "ko" }, + { "norwegian", "no" }, + { "polish", "pl" }, + { "portuguese", "pt" }, + { "russian", "ru" }, + { "simplified chinese", "zh_CN" }, + { "slovak", "sk" }, + { "spanish", "es" }, + { "swedish", "sv" }, + { "traditional chinese", "zh_TW" }, + { "turkish", "tr" } + }; + + + /* + * See if we've loaded this directory before... + */ + + if (stat(d, &dinfo)) + { + if (errno != ENOENT) + fprintf(stderr, "ERROR: [cups-driverd] Unable to stat \"%s\": %s\n", d, + strerror(errno)); + + return (0); + } + else if (cupsArrayFind(Inodes, &dinfo)) + { + fprintf(stderr, "ERROR: [cups-driverd] Skipping \"%s\": loop detected!\n", + d); + return (0); + } + + /* + * Nope, add it to the Inodes array and continue... + */ + + dinfoptr = (struct stat *)malloc(sizeof(struct stat)); + memcpy(dinfoptr, &dinfo, sizeof(struct stat)); + cupsArrayAdd(Inodes, dinfoptr); + + if ((dir = cupsDirOpen(d)) == NULL) + { + if (errno != ENOENT) + fprintf(stderr, + "ERROR: [cups-driverd] Unable to open PPD directory \"%s\": %s\n", + d, strerror(errno)); + + return (0); + } + + fprintf(stderr, "DEBUG: [cups-driverd] Loading \"%s\"...\n", d); + + while ((dent = cupsDirRead(dir)) != NULL) + { + /* + * Skip files/directories starting with "."... + */ + + if (dent->filename[0] == '.') + continue; + + /* + * See if this is a file... + */ + + snprintf(filename, sizeof(filename), "%s/%s", d, dent->filename); + + if (p[0]) + snprintf(name, sizeof(name), "%s/%s", p, dent->filename); + else + strlcpy(name, dent->filename, sizeof(name)); + + if (S_ISDIR(dent->fileinfo.st_mode)) + { + /* + * Do subdirectory... + */ + + if (descend) + { + if (!load_ppds(filename, name, 1)) + { + cupsDirClose(dir); + return (1); + } + } + else if ((ptr = filename + strlen(filename) - 14) > filename && + !strcmp(ptr, ".printerDriver")) + { + /* + * Load PPDs in a printer driver bundle. + */ + + strlcat(filename, "/Contents/Resources/PPDs", sizeof(filename)); + strlcat(name, "/Contents/Resources/PPDs", sizeof(name)); + + load_ppds(filename, name, 0); + } + + continue; + } + else if ((ptr = filename + strlen(filename) - 6) > filename && + !strcmp(ptr, ".plist")) + { + /* + * Skip plist files in the PPDs directory... + */ + + continue; + } + + /* + * See if this file has been scanned before... + */ + + strcpy(key.record.filename, name); + strcpy(key.record.name, name); + + ppd = (ppd_info_t *)cupsArrayFind(PPDsByName, &key); + + if (ppd && + ppd->record.size == dent->fileinfo.st_size && + ppd->record.mtime == dent->fileinfo.st_mtime) + { + /* + * Rewind to the first entry for this file... + */ + + while ((ppd = (ppd_info_t *)cupsArrayPrev(PPDsByName)) != NULL && + !strcmp(ppd->record.filename, name)); + + /* + * Then mark all of the matches for this file as found... + */ + + while ((ppd = (ppd_info_t *)cupsArrayNext(PPDsByName)) != NULL && + !strcmp(ppd->record.filename, name)) + ppd->found = 1; + + continue; + } + + /* + * No, file is new/changed, so re-scan it... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + continue; + + /* + * Now see if this is a PPD file... + */ + + line[0] = '\0'; + cupsFileGets(fp, line, sizeof(line)); + + if (strncmp(line, "*PPD-Adobe:", 11)) + { + /* + * Nope, treat it as a driver information file... + */ + + load_drv(filename, name, fp, dent->fileinfo.st_mtime, + dent->fileinfo.st_size); + continue; + } + + /* + * Now read until we get the NickName field... + */ + + cups_languages = cupsArrayNew(NULL, NULL); + products = cupsArrayNew(NULL, NULL); + psversions = cupsArrayNew(NULL, NULL); + + model_name[0] = '\0'; + nick_name[0] = '\0'; + manufacturer[0] = '\0'; + device_id[0] = '\0'; + lang_encoding[0] = '\0'; + strcpy(lang_version, "en"); + model_number = 0; + type = PPD_TYPE_POSTSCRIPT; + + while (cupsFileGets(fp, line, sizeof(line)) != NULL) + { + if (!strncmp(line, "*Manufacturer:", 14)) + sscanf(line, "%*[^\"]\"%255[^\"]", manufacturer); + else if (!strncmp(line, "*ModelName:", 11)) + sscanf(line, "%*[^\"]\"%127[^\"]", model_name); + else if (!strncmp(line, "*LanguageEncoding:", 18)) + sscanf(line, "%*[^:]:%63s", lang_encoding); + else if (!strncmp(line, "*LanguageVersion:", 17)) + sscanf(line, "%*[^:]:%63s", lang_version); + else if (!strncmp(line, "*NickName:", 10)) + sscanf(line, "%*[^\"]\"%255[^\"]", nick_name); + else if (!strncasecmp(line, "*1284DeviceID:", 14)) + { + sscanf(line, "%*[^\"]\"%255[^\"]", device_id); + + // Make sure device ID ends with a semicolon... + if (device_id[0] && device_id[strlen(device_id) - 1] != ';') + strlcat(device_id, ";", sizeof(device_id)); + } + else if (!strncmp(line, "*Product:", 9)) + { + if (sscanf(line, "%*[^\"]\"(%255[^\"]", product) == 1) + { + /* + * Make sure the value ends with a right parenthesis - can't stop at + * the first right paren since the product name may contain escaped + * parenthesis... + */ + + ptr = product + strlen(product) - 1; + if (ptr > product && *ptr == ')') + { + /* + * Yes, ends with a parenthesis, so remove it from the end and + * add the product to the list... + */ + + *ptr = '\0'; + cupsArrayAdd(products, strdup(product)); + } + } + } + else if (!strncmp(line, "*PSVersion:", 11)) + { + sscanf(line, "%*[^\"]\"%255[^\"]", psversion); + cupsArrayAdd(psversions, strdup(psversion)); + } + else if (!strncmp(line, "*cupsLanguages:", 15)) + { + char *start; /* Start of language */ + + + for (start = line + 15; *start && isspace(*start & 255); start ++); + + if (*start++ == '\"') + { + while (*start) + { + for (ptr = start + 1; + *ptr && *ptr != '\"' && !isspace(*ptr & 255); + ptr ++); + + if (*ptr) + { + *ptr++ = '\0'; + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + } + + cupsArrayAdd(cups_languages, strdup(start)); + start = ptr; + } + } + } + else if (!strncmp(line, "*cupsFax:", 9)) + { + for (ptr = line + 9; isspace(*ptr & 255); ptr ++); + + if (!strncasecmp(ptr, "true", 4)) + type = PPD_TYPE_FAX; + } + else if (!strncmp(line, "*cupsFilter:", 12) && type == PPD_TYPE_POSTSCRIPT) + { + if (strstr(line + 12, "application/vnd.cups-raster")) + type = PPD_TYPE_RASTER; + else if (strstr(line + 12, "application/vnd.cups-pdf")) + type = PPD_TYPE_PDF; + } + else if (!strncmp(line, "*cupsModelNumber:", 17)) + sscanf(line, "*cupsModelNumber:%d", &model_number); + else if (!strncmp(line, "*OpenUI", 7)) + { + /* + * Stop early if we have a NickName or ModelName attributes + * before the first OpenUI... + */ + + if ((model_name[0] || nick_name[0]) && cupsArrayCount(products) > 0 && + cupsArrayCount(psversions) > 0) + break; + } + } + + /* + * Close the file... + */ + + cupsFileClose(fp); + + /* + * See if we got all of the required info... + */ + + if (nick_name[0]) + cupsCharsetToUTF8((cups_utf8_t *)make_model, nick_name, + sizeof(make_model), _ppdGetEncoding(lang_encoding)); + else + strcpy(make_model, model_name); + + while (isspace(make_model[0] & 255)) + _cups_strcpy(make_model, make_model + 1); + + if (!make_model[0] || cupsArrayCount(products) == 0 || + cupsArrayCount(psversions) == 0) + { + /* + * We don't have all the info needed, so skip this file... + */ + + if (!make_model[0]) + fprintf(stderr, "WARNING: Missing NickName and ModelName in %s!\n", + filename); + + if (cupsArrayCount(products) == 0) + fprintf(stderr, "WARNING: Missing Product in %s!\n", filename); + + if (cupsArrayCount(psversions) == 0) + fprintf(stderr, "WARNING: Missing PSVersion in %s!\n", filename); + + free_array(products); + free_array(psversions); + free_array(cups_languages); + + continue; + } + + if (model_name[0]) + cupsArrayAdd(products, strdup(model_name)); + + /* + * Normalize the make and model string... + */ + + while (isspace(manufacturer[0] & 255)) + _cups_strcpy(manufacturer, manufacturer + 1); + + if (!strncasecmp(make_model, manufacturer, strlen(manufacturer))) + strlcpy(temp, make_model, sizeof(temp)); + else + snprintf(temp, sizeof(temp), "%s %s", manufacturer, make_model); + + _ppdNormalizeMakeAndModel(temp, make_model, sizeof(make_model)); + + /* + * See if we got a manufacturer... + */ + + if (!manufacturer[0] || !strcmp(manufacturer, "ESP")) + { + /* + * 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 + strcpy(manufacturer, "Other"); + } + else if (!strncasecmp(manufacturer, "LHAG", 4) || + !strncasecmp(manufacturer, "linotype", 8)) + strcpy(manufacturer, "LHAG"); + else if (!strncasecmp(manufacturer, "Hewlett", 7)) + strcpy(manufacturer, "HP"); + + /* + * Fix the lang_version as needed... + */ + + if ((ptr = strchr(lang_version, '-')) != NULL) + *ptr++ = '\0'; + else if ((ptr = strchr(lang_version, '_')) != NULL) + *ptr++ = '\0'; + + if (ptr) + { + /* + * Setup the country suffix... + */ + + country[0] = '_'; + _cups_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, lang_version)) + break; + + if (i < (int)(sizeof(languages) / sizeof(languages[0]))) + { + /* + * Found a known language... + */ + + snprintf(lang_version, sizeof(lang_version), "%s%s", + languages[i].language, country); + } + else + { + /* + * Unknown language; use "xx"... + */ + + strcpy(lang_version, "xx"); + } + + /* + * Record the PPD file... + */ + + new_ppd = !ppd; + + if (new_ppd) + { + /* + * Add new PPD file... + */ + + fprintf(stderr, "DEBUG2: [cups-driverd] Adding ppd \"%s\"...\n", name); + + ppd = add_ppd(name, name, lang_version, manufacturer, make_model, + device_id, (char *)cupsArrayFirst(products), + (char *)cupsArrayFirst(psversions), + dent->fileinfo.st_mtime, dent->fileinfo.st_size, + model_number, type, "file"); + + if (!ppd) + { + cupsDirClose(dir); + return (0); + } + } + else + { + /* + * Update existing record... + */ + + fprintf(stderr, "DEBUG2: [cups-driverd] Updating ppd \"%s\"...\n", name); + + memset(ppd, 0, sizeof(ppd_info_t)); + + ppd->found = 1; + ppd->record.mtime = dent->fileinfo.st_mtime; + ppd->record.size = dent->fileinfo.st_size; + ppd->record.model_number = model_number; + ppd->record.type = type; + + strlcpy(ppd->record.name, name, sizeof(ppd->record.name)); + strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make)); + strlcpy(ppd->record.make_and_model, make_model, + sizeof(ppd->record.make_and_model)); + strlcpy(ppd->record.languages[0], lang_version, + sizeof(ppd->record.languages[0])); + strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products), + sizeof(ppd->record.products[0])); + strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions), + sizeof(ppd->record.psversions[0])); + strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id)); + } + + /* + * Add remaining products, versions, and languages... + */ + + for (i = 1; + i < PPD_MAX_PROD && (ptr = (char *)cupsArrayNext(products)) != NULL; + i ++) + strlcpy(ppd->record.products[i], ptr, + sizeof(ppd->record.products[0])); + + for (i = 1; + i < PPD_MAX_VERS && (ptr = (char *)cupsArrayNext(psversions)) != NULL; + i ++) + strlcpy(ppd->record.psversions[i], ptr, + sizeof(ppd->record.psversions[0])); + + for (i = 1, ptr = (char *)cupsArrayFirst(cups_languages); + i < PPD_MAX_LANG && ptr; + i ++, ptr = (char *)cupsArrayNext(cups_languages)) + strlcpy(ppd->record.languages[i], ptr, + sizeof(ppd->record.languages[0])); + + /* + * Free products, versions, and languages... + */ + + free_array(cups_languages); + free_array(products); + free_array(psversions); + + ChangedPPD = 1; + } + + cupsDirClose(dir); + + return (1); +} + + +/* + * 'load_ppds_dat()' - Load the ppds.dat file. + */ + +static void +load_ppds_dat(char *filename, /* I - Filename buffer */ + size_t filesize, /* I - Size of filename buffer */ + int verbose) /* I - Be verbose? */ +{ + ppd_info_t *ppd; /* Current PPD file */ + cups_file_t *fp; /* ppds.dat file */ + struct stat fileinfo; /* ppds.dat information */ + const char *cups_cachedir; /* CUPS_CACHEDIR environment variable */ + + + PPDsByName = cupsArrayNew((cups_array_func_t)compare_names, NULL); + PPDsByMakeModel = cupsArrayNew((cups_array_func_t)compare_ppds, NULL); + ChangedPPD = 0; + + if ((cups_cachedir = getenv("CUPS_CACHEDIR")) == NULL) + cups_cachedir = CUPS_CACHEDIR; + + snprintf(filename, filesize, "%s/ppds.dat", cups_cachedir); + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + /* + * See if we have the right sync word... + */ + + unsigned ppdsync; /* Sync word */ + int num_ppds; /* Number of PPDs */ + + if (cupsFileRead(fp, (char *)&ppdsync, sizeof(ppdsync)) + == sizeof(ppdsync) && + ppdsync == PPD_SYNC && + !stat(filename, &fileinfo) && + ((fileinfo.st_size - sizeof(ppdsync)) % sizeof(ppd_rec_t)) == 0 && + (num_ppds = (fileinfo.st_size - sizeof(ppdsync)) / + sizeof(ppd_rec_t)) > 0) + { + /* + * We have a ppds.dat file, so read it! + */ + + for (; num_ppds > 0; num_ppds --) + { + if ((ppd = (ppd_info_t *)calloc(1, sizeof(ppd_info_t))) == NULL) + { + if (verbose) + fputs("ERROR: [cups-driverd] Unable to allocate memory for PPD!\n", + stderr); + exit(1); + } + + if (cupsFileRead(fp, (char *)&(ppd->record), sizeof(ppd_rec_t)) > 0) + { + cupsArrayAdd(PPDsByName, ppd); + cupsArrayAdd(PPDsByMakeModel, ppd); + } + else + { + free(ppd); + break; + } + } + + if (verbose) + fprintf(stderr, "INFO: [cups-driverd] Read \"%s\", %d PPDs...\n", + filename, cupsArrayCount(PPDsByName)); + } + + cupsFileClose(fp); + } +} + + +/* + * 'regex_device_id()' - Compile a regular expression based on the 1284 device + * ID. + */ + +static regex_t * /* O - Regular expression */ +regex_device_id(const char *device_id) /* I - IEEE-1284 device ID */ +{ + char res[2048], /* Regular expression string */ + *ptr; /* Pointer into string */ + regex_t *re; /* Regular expression */ + int cmd; /* Command set string? */ + + + fprintf(stderr, "DEBUG: [cups-driverd] regex_device_id(\"%s\")\n", device_id); + + /* + * Scan the device ID string and insert class, command set, manufacturer, and + * model attributes to match. We assume that the device ID in the PPD and the + * device ID reported by the device itself use the same attribute names and + * order of attributes. + */ + + ptr = res; + + while (*device_id && ptr < (res + sizeof(res) - 6)) + { + cmd = !strncasecmp(device_id, "COMMAND SET:", 12) || + !strncasecmp(device_id, "CMD:", 4); + + if (cmd || !strncasecmp(device_id, "MANUFACTURER:", 13) || + !strncasecmp(device_id, "MFG:", 4) || + !strncasecmp(device_id, "MFR:", 4) || + !strncasecmp(device_id, "MODEL:", 6) || + !strncasecmp(device_id, "MDL:", 4)) + { + if (ptr > res) + { + *ptr++ = '.'; + *ptr++ = '*'; + } + + *ptr++ = '('; + + while (*device_id && *device_id != ';' && ptr < (res + sizeof(res) - 4)) + { + if (strchr("[]{}().*\\|", *device_id)) + *ptr++ = '\\'; + *ptr++ = *device_id++; + } + + if (*device_id == ';' || !*device_id) + *ptr++ = ';'; + *ptr++ = ')'; + if (cmd) + *ptr++ = '?'; + } + else if ((device_id = strchr(device_id, ';')) == NULL) + break; + else + device_id ++; + } + + *ptr = '\0'; + + fprintf(stderr, "DEBUG: [cups-driverd] regex_device_id: \"%s\"\n", res); + + /* + * Compile the regular expression and return... + */ + + if (res[0] && (re = (regex_t *)calloc(1, sizeof(regex_t))) != NULL) + { + if (!regcomp(re, res, REG_EXTENDED | REG_ICASE)) + { + fputs("DEBUG: [cups-driverd] regex_device_id: OK\n", stderr); + return (re); + } + + free(re); + } + + return (NULL); +} + + +/* + * 'regex_string()' - Construct a regular expression to compare a simple string. + */ + +static regex_t * /* O - Regular expression */ +regex_string(const char *s) /* I - String to compare */ +{ + char res[2048], /* Regular expression string */ + *ptr; /* Pointer into string */ + regex_t *re; /* Regular expression */ + + + fprintf(stderr, "DEBUG: [cups-driverd] regex_string(\"%s\")\n", s); + + /* + * Convert the string to a regular expression, escaping special characters + * as needed. + */ + + ptr = res; + + while (*s && ptr < (res + sizeof(res) - 2)) + { + if (strchr("[]{}().*\\", *s)) + *ptr++ = '\\'; + + *ptr++ = *s++; + } + + *ptr = '\0'; + + fprintf(stderr, "DEBUG: [cups-driverd] regex_string: \"%s\"\n", res); + + /* + * Create a case-insensitive regular expression... + */ + + if (res[0] && (re = (regex_t *)calloc(1, sizeof(regex_t))) != NULL) + { + if (!regcomp(re, res, REG_ICASE)) + { + fputs("DEBUG: [cups-driverd] regex_string: OK\n", stderr); + return (re); + } + + free(re); + } + + return (NULL); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cups-lpd.c b/scheduler/cups-lpd.c new file mode 100644 index 0000000000..013f6798e2 --- /dev/null +++ b/scheduler/cups-lpd.c @@ -0,0 +1,1735 @@ +/* + * "$Id$" + * + * Line Printer Daemon interface for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Process an incoming LPD request... + * create_job() - Create a new print job. + * get_printer() - Get the named printer and its options. + * print_file() - Add a file to the current job. + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_INTTYPES_H +# include +#endif /* HAVE_INTTYPES_H */ + +#ifdef HAVE_COREFOUNDATION_H +# include +#endif /* HAVE_COREFOUNDATION_H */ +#ifdef HAVE_CFPRIV_H +# include +#endif /* HAVE_CFPRIV_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... + */ + +static int create_job(http_t *http, const char *dest, const char *title, + const char *docname, const char *user, + int num_options, cups_option_t *options); +static int get_printer(http_t *http, const char *name, char *dest, + int destsize, cups_option_t **options, + int *accepting, int *shared, ipp_pstate_t *state); +static int print_file(http_t *http, int id, const char *filename, + const char *docname, const char *user, + const char *format, int last); +static int recv_print_job(const char *name, int num_defaults, + cups_option_t *defaults); +static int remove_jobs(const char *name, const char *agent, + const char *list); +static int send_state(const char *name, const char *list, + int longstatus); +static 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 */ + socklen_t hostlen; /* Size of client address */ + http_addr_t hostaddr; /* Address of client */ + char hostname[256], /* Name of client */ + hostip[256], /* IP address */ + *hostfamily; /* Address family */ + int hostlookups; /* Do hostname lookups? */ + + + /* + * Don't buffer the output... + */ + + setbuf(stdout, NULL); + + /* + * Log things using the "cups-lpd" name... + */ + + openlog("cups-lpd", LOG_PID, LOG_LPR); + + /* + * Scan the command-line for options... + */ + + num_defaults = 0; + defaults = NULL; + hostlookups = 1; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'h' : /* -h hostname[:port] */ + if (argv[i][2]) + cupsSetServer(argv[i] + 2); + else + { + i ++; + if (i < argc) + cupsSetServer(argv[i]); + else + syslog(LOG_WARNING, "Expected hostname string after -h option!"); + } + break; + + 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; + + case 'n' : /* Don't do hostname lookups */ + hostlookups = 0; + 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]); + + /* + * 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 + { + httpAddrString(&hostaddr, hostip, sizeof(hostip)); + + if (hostlookups) + httpAddrLookup(&hostaddr, hostname, sizeof(hostname)); + else + strlcpy(hostname, hostip, sizeof(hostname)); + +#ifdef AF_INET6 + if (hostaddr.addr.sa_family == AF_INET6) + hostfamily = "IPv6"; + else +#endif /* AF_INET6 */ + hostfamily = "IPv4"; + + syslog(LOG_INFO, "Connection from %s (%s %s)", hostname, hostfamily, + hostip); + } + + num_defaults = cupsAddOption("job-originating-host-name", hostname, + num_defaults, &defaults); + + /* + * 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; + + if (command == 0x02) + list = NULL; + else + { + for (list = dest + 1; *list && !isspace(*list & 255); list ++); + + while (isspace(*list & 255)) + *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 */ + if (list) + { + /* + * Grab the agent and skip to the list of users and/or jobs. + */ + + agent = list; + + for (; *list && !isspace(*list & 255); list ++); + while (isspace(*list & 255)) + *list++ = '\0'; + + syslog(LOG_INFO, "Remove jobs %s on %s by %s", list, dest, agent); + + status = remove_jobs(dest, agent, list); + } + else + status = 1; + + putchar(status); + break; + } + + syslog(LOG_INFO, "Closing connection"); + closelog(); + + return (status); +} + + +/* + * 'create_job()' - Create a new print job. + */ + +static int /* O - Job ID or -1 on error */ +create_job(http_t *http, /* I - HTTP connection */ + const char *dest, /* I - Destination name */ + const char *title, /* I - job-name */ + const char *docname, /* I - Name of job file */ + const char *user, /* I - requesting-user-name */ + int num_options, /* I - Number of options for job */ + cups_option_t *options) /* I - Options for job */ +{ + ipp_t *request; /* IPP request */ + ipp_t *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + int id; /* Job ID */ + + + /* + * Setup the Create-Job request... + */ + + request = ippNewRequest(IPP_CREATE_JOB); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", dest); + + 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[0]) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", + NULL, title); + + if (docname[0]) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", + NULL, docname); + + cupsEncodeOptions(request, num_options, options); + + /* + * Do the request... + */ + + snprintf(uri, sizeof(uri), "/printers/%s", dest); + + response = cupsDoRequest(http, request, uri); + + if (!response || cupsLastError() > IPP_OK_CONFLICT) + { + syslog(LOG_ERR, "Unable to create job - %s", cupsLastErrorString()); + + ippDelete(response); + + return (-1); + } + + /* + * Get the job-id value from the response and return it... + */ + + if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) + { + id = -1; + + syslog(LOG_ERR, "No job-id attribute found in response from server!"); + } + else + { + id = attr->values[0].integer; + + syslog(LOG_INFO, "Print file - job ID = %d", id); + } + + ippDelete(response); + + return (id); +} + + +/* + * 'get_printer()' - Get the named printer and its options. + */ + +static int /* O - Number of options or -1 on error */ +get_printer(http_t *http, /* I - HTTP connection */ + const char *name, /* I - Printer name from request */ + char *dest, /* I - Destination buffer */ + int destsize, /* I - Size of destination buffer */ + cups_option_t **options, /* O - Printer options */ + int *accepting, /* O - printer-is-accepting-jobs value */ + int *shared, /* O - printer-is-shared value */ + ipp_pstate_t *state) /* O - printer-state value */ +{ + int num_options; /* Number of options */ + cups_file_t *fp; /* lpoptions file */ + char line[1024], /* Line from lpoptions file */ + *value, /* Pointer to value on line */ + *optptr; /* Pointer to options on line */ + int linenum; /* Line number in file */ + const char *cups_serverroot; /* CUPS_SERVERROOT env var */ + ipp_t *request; /* IPP request */ + ipp_t *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + static const char * const requested[] = + { /* Requested attributes */ + "printer-info", + "printer-is-accepting-jobs", + "printer-is-shared", + "printer-name", + "printer-state" + }; + + + /* + * Initialize everything... + */ + + if (accepting) + *accepting = 0; + if (shared) + *shared = 0; + if (state) + *state = IPP_PRINTER_STOPPED; + if (options) + *options = NULL; + + /* + * See if the name is a queue name optionally with an instance name. + */ + + strlcpy(dest, name, destsize); + if ((value = strchr(dest, '/')) != NULL) + *value = '\0'; + + /* + * Setup the Get-Printer-Attributes request... + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", dest); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(requested) / sizeof(requested[0])), + NULL, requested); + + /* + * Do the request... + */ + + response = cupsDoRequest(http, request, "/"); + + if (!response || cupsLastError() > IPP_OK_CONFLICT) + { + /* + * If we can't find the printer by name, look up the printer-name + * using the printer-info values... + */ + + ipp_attribute_t *accepting_attr,/* printer-is-accepting-jobs */ + *info_attr, /* printer-info */ + *name_attr, /* printer-name */ + *shared_attr, /* printer-is-shared */ + *state_attr; /* printer-state */ + + + ippDelete(response); + + /* + * Setup the CUPS-Get-Printers request... + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + (int)(sizeof(requested) / sizeof(requested[0])), + NULL, requested); + + /* + * Do the request... + */ + + response = cupsDoRequest(http, request, "/"); + + if (!response || cupsLastError() > IPP_OK_CONFLICT) + { + syslog(LOG_ERR, "Unable to get list of printers - %s", + cupsLastErrorString()); + + ippDelete(response); + + return (-1); + } + + /* + * Scan the response for printers... + */ + + *dest = '\0'; + attr = response->attrs; + + while (attr) + { + /* + * Skip to the next printer... + */ + + while (attr && attr->group_tag != IPP_TAG_PRINTER) + attr = attr->next; + + if (!attr) + break; + + /* + * Get all of the attributes for the current printer... + */ + + accepting_attr = NULL; + info_attr = NULL; + name_attr = NULL; + shared_attr = NULL; + state_attr = NULL; + + while (attr && attr->group_tag == IPP_TAG_PRINTER) + { + if (!strcmp(attr->name, "printer-is-accepting-jobs") && + attr->value_tag == IPP_TAG_BOOLEAN) + accepting_attr = attr; + else if (!strcmp(attr->name, "printer-info") && + attr->value_tag == IPP_TAG_TEXT) + info_attr = attr; + else if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) + name_attr = attr; + else if (!strcmp(attr->name, "printer-is-shared") && + attr->value_tag == IPP_TAG_BOOLEAN) + shared_attr = attr; + else if (!strcmp(attr->name, "printer-state") && + attr->value_tag == IPP_TAG_ENUM) + state_attr = attr; + + attr = attr->next; + } + + if (info_attr && name_attr && + !strcasecmp(name, info_attr->values[0].string.text)) + { + /* + * Found a match, use this one! + */ + + strlcpy(dest, name_attr->values[0].string.text, destsize); + + if (accepting && accepting_attr) + *accepting = accepting_attr->values[0].boolean; + + if (shared && shared_attr) + *shared = shared_attr->values[0].boolean; + + if (state && state_attr) + *state = (ipp_pstate_t)state_attr->values[0].integer; + + break; + } + } + + ippDelete(response); + + if (!*dest) + { + syslog(LOG_ERR, "Unable to find \"%s\" in list of printers!", name); + + return (-1); + } + + name = dest; + } + else + { + /* + * Get values from the response... + */ + + if (accepting) + { + if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", + IPP_TAG_BOOLEAN)) == NULL) + syslog(LOG_ERR, "No printer-is-accepting-jobs attribute found in " + "response from server!"); + else + *accepting = attr->values[0].boolean; + } + + if (shared) + { + if ((attr = ippFindAttribute(response, "printer-is-shared", + IPP_TAG_BOOLEAN)) == NULL) + { + syslog(LOG_ERR, "No printer-is-shared attribute found in " + "response from server!"); + *shared = 1; + } + else + *shared = attr->values[0].boolean; + } + + if (state) + { + if ((attr = ippFindAttribute(response, "printer-state", + IPP_TAG_ENUM)) == NULL) + syslog(LOG_ERR, "No printer-state attribute found in " + "response from server!"); + else + *state = (ipp_pstate_t)attr->values[0].integer; + } + + ippDelete(response); + } + + /* + * Override shared value for LPD using system-specific APIs... + */ + +#ifdef HAVE_CFPRIV_H /* MacOS X */ + if (shared && *shared) + { + CFURLRef prefsurl; /* URL for preferences file */ + CFDataRef xmldata; /* XML data from preferences file */ + CFPropertyListRef plist; /* Property list from XML data */ + CFStringRef queueid; /* CFString of destination name */ + CFArrayRef lprqarray; /* Array of shared "LPR" printers */ + CFBooleanRef serverflag; /* State of the print service */ + static const char printerprefsfile[] = + "/Library/Preferences/com.apple.printservice.plist"; + /* Preferences file */ + + + /* + * See if we are running on MacOS X Server... + */ + + CFDictionaryRef versdict = _CFCopyServerVersionDictionary(); + + if (versdict) + { + /* + * Yes, use the LPR sharing preference... + */ + + CFRelease(versdict); + + *shared = 0; + + prefsurl = CFURLCreateFromFileSystemRepresentation( + kCFAllocatorDefault, + (const UInt8 *)printerprefsfile, + (CFIndex)strlen(printerprefsfile), + false); + if (prefsurl) + { + if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, + prefsurl, &xmldata, NULL, + NULL, NULL)) + { + plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, xmldata, + kCFPropertyListImmutable, + NULL); + if (plist) + { + serverflag = (CFBooleanRef)CFDictionaryGetValue( + (CFDictionaryRef)plist, + CFSTR("serviceState")); + + if (serverflag && CFBooleanGetValue(serverflag)) + { + lprqarray = (CFArrayRef)CFDictionaryGetValue( + (CFDictionaryRef)plist, + CFSTR("lprSharedQueues")); + + if (lprqarray) + { + queueid = CFStringCreateWithCString(CFAllocatorGetDefault(), + dest, + kCFStringEncodingUTF8); + + if (queueid) + { + *shared = CFArrayContainsValue(lprqarray, + CFRangeMake(0, + CFArrayGetCount(lprqarray)), + queueid); + + CFRelease(queueid); + } + } + } + + CFRelease(plist); + } + + CFRelease(xmldata); + } + + CFRelease(prefsurl); + } + + if (!shared) + syslog(LOG_ERR, "Warning - Print Service sharing disabled for LPD " + "on queue: %s", name); + } + } +#endif /* HAVE_CFPRIV_H */ + + /* + * Next look for the printer in the lpoptions file... + */ + + num_options = 0; + + if (options && shared && accepting) + { + if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL) + cups_serverroot = CUPS_SERVERROOT; + + snprintf(line, sizeof(line), "%s/lpoptions", cups_serverroot); + if ((fp = cupsFileOpen(line, "r")) != NULL) + { + linenum = 0; + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Make sure we have "Dest name options" or "Default name options"... + */ + + if ((strcasecmp(line, "Dest") && strcasecmp(line, "Default")) || !value) + continue; + + /* + * Separate destination name from options... + */ + + for (optptr = value; *optptr && !isspace(*optptr & 255); optptr ++); + + while (*optptr == ' ') + *optptr++ = '\0'; + + /* + * If this is our destination, parse the options and break out of + * the loop - we're done! + */ + + if (!strcasecmp(value, name)) + { + num_options = cupsParseOptions(optptr, num_options, options); + break; + } + } + + cupsFileClose(fp); + } + } + else if (options) + *options = NULL; + + /* + * Return the number of options for this destination... + */ + + return (num_options); +} + + +/* + * 'print_file()' - Add a file to the current job. + */ + +static int /* O - 0 on success, -1 on failure */ +print_file(http_t *http, /* I - HTTP connection */ + int id, /* I - Job ID */ + const char *filename, /* I - File to print */ + const char *docname, /* I - document-name */ + const char *user, /* I - requesting-user-name */ + const char *format, /* I - document-format */ + int last) /* I - 1 = last file in job */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + + + /* + * Setup the Send-Document request... + */ + + request = ippNewRequest(IPP_SEND_DOCUMENT); + + snprintf(uri, sizeof(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, user); + + if (docname) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "document-name", NULL, docname); + + if (format) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, + "document-format", NULL, format); + + if (last) + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); + + /* + * Do the request... + */ + + snprintf(uri, sizeof(uri), "/jobs/%d", id); + + ippDelete(cupsDoFileRequest(http, request, uri, filename)); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + syslog(LOG_ERR, "Unable to send document - %s", cupsLastErrorString()); + + return (-1); + } + + return (0); +} + + +/* + * 'recv_print_job()' - Receive a print job from the client. + */ + +static int /* O - Command status */ +recv_print_job( + const char *queue, /* I - Printer name */ + int num_defaults, /* I - Number of default options */ + cups_option_t *defaults) /* I - Default options */ +{ + http_t *http; /* HTTP connection */ + 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 */ + const char *job_sheets; /* Job sheets */ + int num_data; /* Number of data files */ + char control[1024], /* Control filename */ + data[100][256], /* Data files */ + temp[100][1024]; /* Temporary files */ + char user[1024], /* User name */ + title[1024], /* Job title */ + docname[1024], /* Document name */ + dest[256]; /* Printer/class queue */ + int accepting, /* printer-is-accepting */ + shared, /* printer-is-shared */ + num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int id; /* Job ID */ + int docnumber, /* Current document number */ + doccount; /* Count of documents */ + + + /* + * Connect to the server... + */ + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + if (!http) + { + syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno)); + + putchar(1); + + return (1); + } + + /* + * See if the printer is available... + */ + + num_options = get_printer(http, queue, dest, sizeof(dest), &options, + &accepting, &shared, NULL); + + if (num_options < 0 || !accepting || !shared) + { + if (dest[0]) + syslog(LOG_INFO, "Rejecting job because \"%s\" is not %s", dest, + !accepting ? "accepting jobs" : "shared"); + else + syslog(LOG_ERR, "Unable to get printer information for \"%s\"", queue); + + httpClose(http); + + putchar(1); + + return (1); + } + + putchar(0); /* OK so far... */ + + /* + * Read the request... + */ + + status = 0; + num_data = 0; + fd = -1; + + control[0] = '\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 & 255); name ++); + while (isspace(*name & 255)) + *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\" - %s", + control, 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\" - %s", + control, 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 >= (int)(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\" - %s", + temp[num_data], 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 + { + /* + * Copy the default options... + */ + + for (i = 0; i < num_defaults; i ++) + num_options = cupsAddOption(defaults[i].name, + defaults[i].value, + num_options, &options); + + /* + * Grab the job information... + */ + + title[0] = '\0'; + user[0] = '\0'; + docname[0] = '\0'; + doccount = 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 */ + /* + * If a banner was requested and it's not overridden by a + * command line option and the destination's default is none + * then add the standard banner... + */ + + if (cupsGetOption("job-sheets", num_defaults, defaults) == NULL && + ((job_sheets = cupsGetOption("job-sheets", num_options, + options)) == NULL || + !strcmp(job_sheets, "none,none"))) + { + num_options = cupsAddOption("job-sheets", "standard", + num_options, &options); + } + break; + + 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 */ + doccount ++; + + if (line[0] == 'l' && + !cupsGetOption("document-format", num_options, options)) + num_options = cupsAddOption("raw", "", num_options, &options); + + if (line[0] == 'p') + num_options = cupsAddOption("prettyprint", "", num_options, + &options); + break; + } + + if (status) + break; + } + + /* + * Check that we have a username... + */ + + if (!user[0]) + { + syslog(LOG_WARNING, "No username specified by client! " + "Using \"anonymous\"..."); + strcpy(user, "anonymous"); + } + + /* + * Create the job... + */ + + if ((id = create_job(http, dest, title, docname, user, num_options, + options)) < 0) + status = 1; + else + { + /* + * Then print the job files... + */ + + rewind(fp); + + docname[0] = '\0'; + docnumber = 0; + + while (smart_gets(line, sizeof(line), fp) != NULL) + { + /* + * Process control lines... + */ + + switch (line[0]) + { + case 'N' : /* Document name */ + strlcpy(docname, line + 1, sizeof(docname)); + break; + + 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 */ + /* + * Figure out which file we are printing... + */ + + for (i = 0; i < num_data; i ++) + if (!strcmp(data[i], line + 1)) + break; + + if (i >= num_data) + { + status = 1; + break; + } + + /* + * Send the print file... + */ + + docnumber ++; + + if (print_file(http, id, temp[i], docname, user, + cupsGetOption("document-format", num_options, + options), + docnumber == doccount)) + status = 1; + else + status = 0; + + break; + } + + if (status) + break; + } + } + + fclose(fp); + } + } + + cupsFreeOptions(num_options, options); + + httpClose(http); + + /* + * Clean up all temporary files and return... + */ + + unlink(control); + + for (i = 0; i < num_data; i ++) + unlink(temp[i]); + + return (status); +} + + +/* + * 'remove_jobs()' - Cancel one or more jobs. + */ + +static 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 */ + 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: %s", cupsServer(), + strerror(errno)); + return (1); + } + + /* + * Loop for each job... + */ + + while ((id = atoi(list)) > 0) + { + /* + * Skip job ID in list... + */ + + while (isdigit(*list & 255)) + list ++; + while (isspace(*list & 255)) + list ++; + + /* + * Build an IPP_CANCEL_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * job-uri + * requesting-user-name + */ + + request = ippNewRequest(IPP_CANCEL_JOB); + + 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... + */ + + ippDelete(cupsDoRequest(http, request, "/jobs")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + syslog(LOG_WARNING, "Cancel of job ID %d failed: %s\n", id, + cupsLastErrorString()); + httpClose(http); + return (1); + } + else + syslog(LOG_INFO, "Job ID %d canceled", id); + } + + httpClose(http); + + return (0); +} + + +/* + * 'send_state()' - Send the queue state. + */ + +static int /* O - Command status */ +send_state(const char *queue, /* 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 */ + 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 dest[256]; /* Printer/class queue */ + static const char * const ranks[10] = /* Ranking strings */ + { + "th", + "st", + "nd", + "rd", + "th", + "th", + "th", + "th", + "th", + "th" + }; + static const char * const requested[] = + { /* Requested attributes */ + "job-id", + "job-k-octets", + "job-state", + "job-printer-uri", + "job-originating-user-name", + "job-name", + "copies" + }; + + + /* + * Try connecting to the local server... + */ + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(), + strerror(errno)); + printf("Unable to connect to server %s: %s", cupsServer(), strerror(errno)); + return (1); + } + + /* + * Get the actual destination name and printer state... + */ + + if (get_printer(http, queue, dest, sizeof(dest), NULL, NULL, NULL, &state)) + { + syslog(LOG_ERR, "Unable to get printer %s: %s", queue, + cupsLastErrorString()); + printf("Unable to get printer %s: %s", queue, cupsLastErrorString()); + return (1); + } + + /* + * Show the queue state... + */ + + 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; + } + + /* + * 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 = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", dest); + + 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; + response = cupsDoRequest(http, request, "/"); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + printf("get-jobs failed: %s\n", cupsLastErrorString()); + ippDelete(response); + return (1); + } + + /* + * Loop through the job list and display them... + */ + + for (attr = response->attrs, rank = 1; attr; attr = attr->next) + { + /* + * Skip leading attributes until we hit a job... + */ + + while (attr && (attr->group_tag != IPP_TAG_JOB || !attr->name)) + attr = attr->next; + + if (!attr) + 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 && attr->group_tag == IPP_TAG_JOB) + { + if (!strcmp(attr->name, "job-id") && + attr->value_tag == IPP_TAG_INTEGER) + jobid = attr->values[0].integer; + + if (!strcmp(attr->name, "job-k-octets") && + attr->value_tag == IPP_TAG_INTEGER) + jobsize = attr->values[0].integer; + + if (!strcmp(attr->name, "job-state") && + attr->value_tag == IPP_TAG_ENUM) + jobstate = (ipp_jstate_t)attr->values[0].integer; + + if (!strcmp(attr->name, "job-printer-uri") && + attr->value_tag == IPP_TAG_URI) + if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) + jobdest ++; + + if (!strcmp(attr->name, "job-originating-user-name") && + attr->value_tag == IPP_TAG_NAME) + jobuser = attr->values[0].string.text; + + if (!strcmp(attr->name, "job-name") && + attr->value_tag == IPP_TAG_NAME) + jobname = attr->values[0].string.text; + + if (!strcmp(attr->name, "copies") && + attr->value_tag == IPP_TAG_INTEGER) + jobcopies = attr->values[0].integer; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (!jobdest || !jobid) + { + if (!attr) + 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: %-33.33s [job %d localhost]\n", jobuser, rankstr, jobid); + printf(" %-39.39s %.0f bytes\n", namestr, 1024.0 * jobsize); + } + else + printf("%-7s %-7.7s %-7d %-31.31s %.0f bytes\n", rankstr, jobuser, + jobid, jobname, 1024.0 * jobsize); + + if (!attr) + break; + } + + ippDelete(response); + + if (jobcount == 0) + puts("no entries"); + + httpClose(http); + + return (0); +} + + +/* + * 'smart_gets()' - Get a line of text, removing the trailing CR and/or LF. + */ + +static 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 0000000000..09e8637b89 --- /dev/null +++ b/scheduler/cups-polld.c @@ -0,0 +1,475 @@ +/* + * "$Id$" + * + * Polling daemon for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Open sockets and poll until we are killed... + * dequote() - Remote quotes from a string. + * poll_server() - Poll the server for the given set of printers or + * classes. + * sighup_handler() - Handle 'hangup' signals to restart polling. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local globals... + */ + +static int restart_polling = 1; + + +/* + * Local functions... + */ + +static char *dequote(char *d, const char *s, int dlen); +static int poll_server(http_t *http, int sock, int port, int interval, + const char *prefix); +static void sighup_handler(int sig); + + +/* + * 'main()' - Open sockets and poll until we are killed... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + http_t *http; /* HTTP connection */ + int interval; /* Polling interval */ + int sock; /* Browser sock */ + int port; /* Browser port */ + int val; /* Socket option value */ + int seconds, /* Seconds left from poll */ + remain; /* Total remaining time to sleep */ + char prefix[1024]; /* Prefix for log messages */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * Catch hangup signals for when the network changes... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGHUP, sighup_handler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGHUP); + action.sa_handler = sighup_handler; + sigaction(SIGHUP, &action, NULL); +#else + signal(SIGHUP, sighup_handler); +#endif /* HAVE_SIGSET */ + + /* + * Don't buffer log messages... + */ + + 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]); + + if (interval < 2) + interval = 2; + + snprintf(prefix, sizeof(prefix), "[cups-polld %s:%d]", argv[1], atoi(argv[2])); + + /* + * Open a broadcast socket... + */ + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + fprintf(stderr, "ERROR: %s Unable to open broadcast socket: %s\n", prefix, + strerror(errno)); + return (1); + } + + /* + * Set the "broadcast" flag... + */ + + val = 1; + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) + { + fprintf(stderr, "ERROR: %s Unable to put socket in broadcast mode: %s\n", + prefix, strerror(errno)); + + close(sock); + return (1); + } + + /* + * Loop forever, asking for available printers and classes... + */ + + for (http = NULL; !ferror(stderr);) + { + /* + * Open a connection to the server... + */ + + if (restart_polling || !http) + { + restart_polling = 0; + httpClose(http); + + if ((http = httpConnectEncrypt(argv[1], atoi(argv[2]), + cupsEncryption())) == NULL) + { + fprintf(stderr, "ERROR: %s Unable to connect to %s on port %s: %s\n", + prefix, argv[1], argv[2], + h_errno ? hstrerror(h_errno) : strerror(errno)); + } + } + + /* + * Get the printers and classes... + */ + + remain = interval; + + if (http && (seconds = poll_server(http, sock, port, interval, prefix)) > 0) + remain -= seconds; + + /* + * Sleep for any remaining time... + */ + + if (remain > 0 && !restart_polling) + sleep(remain); + } + + return (1); +} + + +/* + * 'dequote()' - Remote quotes from a string. + */ + +static char * /* O - Dequoted string */ +dequote(char *d, /* I - Destination string */ + const char *s, /* I - Source string */ + int dlen) /* I - Destination length */ +{ + char *dptr; /* Pointer into destination */ + + + if (s) + { + for (dptr = d, dlen --; *s && dlen > 0; s ++) + if (*s != '\"') + { + *dptr++ = *s; + dlen --; + } + + *dptr = '\0'; + } + else + *d = '\0'; + + return (d); +} + + +/* + * 'poll_server()' - Poll the server for the given set of printers or classes. + */ + +static int /* O - Number of seconds or -1 on error */ +poll_server(http_t *http, /* I - HTTP connection */ + int sock, /* I - Broadcast sock */ + int port, /* I - Broadcast port */ + int interval, /* I - Polling interval */ + const char *prefix) /* I - Prefix for log messages */ +{ + int seconds; /* Number of seconds */ + 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 */ + char info[1024], /* printer-info */ + job_sheets[1024],/* job-sheets-default */ + location[1024], /* printer-location */ + make_model[1024]; + /* printer-make-and-model */ + cups_ptype_t type; /* printer-type */ + ipp_pstate_t state; /* printer-state */ + int accepting; /* printer-is-accepting-jobs */ + struct sockaddr_in addr; /* Broadcast address */ + char packet[1540]; /* Data packet */ + static const char * const attrs[] = /* Requested attributes */ + { + "job-sheets-default", + "printer-info", + "printer-is-accepting-jobs", + "printer-location", + "printer-make-and-model", + "printer-name", + "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 request and pass along a list of the + * attributes we are interested in along with the types of printers + * (and classes) we want. + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(attrs) / sizeof(attrs[0]), + NULL, attrs); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type", 0); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, + "printer-type-mask", + CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_NOT_SHARED); + + /* + * Do the request and get back a response... + */ + + seconds = time(NULL); + response = cupsDoRequest(http, request, "/"); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + fprintf(stderr, "ERROR: %s CUPS-Get-Printers failed: %s\n", prefix, + cupsLastErrorString()); + ippDelete(response); + return (-1); + } + + if (response) + { + /* + * 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 ++); + + fprintf(stderr, "DEBUG: %s Found %d printers.\n", prefix, max_count); + + count = 0; + max_count = 2 * max_count / interval + 1; + + /* + * Loop through the printers or classes returned in the list... + */ + + for (attr = response->attrs; attr; attr = attr->next) + { + /* + * Skip leading attributes until we hit a printer... + */ + + while (attr && attr->group_tag != IPP_TAG_PRINTER) + attr = attr->next; + + if (!attr) + break; + + /* + * Pull the needed attributes from this printer... + */ + + uri = NULL; + info[0] = '\0'; + job_sheets[0] = '\0'; + location[0] = '\0'; + make_model[0] = '\0'; + type = CUPS_PRINTER_REMOTE; + accepting = 1; + state = IPP_PRINTER_IDLE; + + while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) + { + if (!strcmp(attr->name, "job-sheets-default") && + (attr->value_tag == IPP_TAG_NAME || + attr->value_tag == IPP_TAG_KEYWORD)) + { + if (attr->num_values == 1) + snprintf(job_sheets, sizeof(job_sheets), " job-sheets=%s", + attr->values[0].string.text); + else + snprintf(job_sheets, sizeof(job_sheets), " job-sheets=%s,%s", + attr->values[0].string.text, + attr->values[1].string.text); + } + else if (!strcmp(attr->name, "printer-uri-supported") && + attr->value_tag == IPP_TAG_URI) + uri = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-info") && + attr->value_tag == IPP_TAG_TEXT) + dequote(info, attr->values[0].string.text, sizeof(info)); + else if (!strcmp(attr->name, "printer-is-accepting-jobs") && + attr->value_tag == IPP_TAG_BOOLEAN) + accepting = attr->values[0].boolean; + else if (!strcmp(attr->name, "printer-location") && + attr->value_tag == IPP_TAG_TEXT) + dequote(location, attr->values[0].string.text, sizeof(location)); + else if (!strcmp(attr->name, "printer-make-and-model") && + attr->value_tag == IPP_TAG_TEXT) + dequote(make_model, attr->values[0].string.text, sizeof(location)); + else if (!strcmp(attr->name, "printer-state") && + attr->value_tag == IPP_TAG_ENUM) + state = (ipp_pstate_t)attr->values[0].integer; + else if (!strcmp(attr->name, "printer-type") && + 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; + } + + /* + * Send the printer information... + */ + + type |= CUPS_PRINTER_REMOTE; + + if (!accepting) + type |= CUPS_PRINTER_REJECTING; + + snprintf(packet, sizeof(packet), + "%x %x %s \"%s\" \"%s\" \"%s\" lease-duration=%d%s\n", + type, state, uri, location, info, make_model, interval * 2, + job_sheets); + + fprintf(stderr, "DEBUG2: %s Sending %s", prefix, packet); + + if (sendto(sock, packet, strlen(packet), 0, + (struct sockaddr *)&addr, sizeof(addr)) <= 0) + { + ippDelete(response); + 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); + } + + if (!attr || restart_polling) + break; + } + + ippDelete(response); + } + + /* + * Return the number of seconds we used... + */ + + return (time(NULL) - seconds); +} + + +/* + * 'sighup_handler()' - Handle 'hangup' signals to restart polling. + */ + +static void +sighup_handler(int sig) /* I - Signal number */ +{ + (void)sig; + + restart_polling = 1; + +#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) + signal(SIGHUP, sighup_handler); +#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */ +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h new file mode 100644 index 0000000000..7226a5ce2b --- /dev/null +++ b/scheduler/cupsd.h @@ -0,0 +1,249 @@ +/* + * "$Id$" + * + * Main header file for the CUPS scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +# include +#else +# include +#endif /* WIN32 */ + +#include +#include +#include "mime.h" +#include +#include +#include +#include + +#if defined(HAVE_CDSASSL) +# include +#endif /* HAVE_CDSASSL */ + + +/* + * Some OS's don't have hstrerror(), most notably Solaris... + */ + +#ifndef HAVE_HSTRERROR +# ifdef hstrerror +# undef hstrerror +# endif /* hstrerror */ +# define hstrerror cups_hstrerror + +extern const char *cups_hstrerror(int); +#endif /* !HAVE_HSTRERROR */ + + +/* + * Common constants. + */ + +#ifndef FALSE +# define FALSE 0 +# define TRUE (!FALSE) +#endif /* !FALSE */ + + +/* + * Implementation limits... + */ + +#define MAX_ENV 100 /* Maximum number of environment strings */ +#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 30 /* Timeout between requests */ +#define DEFAULT_INTERVAL 30 /* Interval between browse updates */ +#define DEFAULT_CHARSET "utf-8" /* Default charset */ + + +/* + * Global variable macros... + */ + +#ifdef _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 /* _MAIN_C */ + + +/* + * Other stuff for the scheduler... + */ + +#include "sysman.h" +#include "statbuf.h" +#include "cert.h" +#include "auth.h" +#include "client.h" +#include "policy.h" +#include "printers.h" +#include "classes.h" +#include "job.h" +#include "conf.h" +#include "banners.h" +#include "dirsvc.h" +#include "network.h" +#include "subscriptions.h" + + +/* + * Reload types... + */ + +#define RELOAD_NONE 0 /* No reload needed */ +#define RELOAD_ALL 1 /* Reload everything */ +#define RELOAD_CUPSD 2 /* Reload only cupsd.conf */ + + +/* + * Select callback function type... + */ + +typedef void (*cupsd_selfunc_t)(void *data); + + +/* + * Globals... + */ + +VAR int TestConfigFile VALUE(0), + /* Test the cupsd.conf file? */ + UseProfiles VALUE(1); + /* Use security profiles for child procs? */ +VAR int MaxFDs VALUE(0); + /* Maximum number of files */ + +VAR time_t ReloadTime VALUE(0); + /* Time of reload request... */ +VAR int NeedReload VALUE(RELOAD_ALL), + /* Need to load configuration? */ + DoingShutdown VALUE(0); + /* Shutting down the scheduler? */ +VAR void *DefaultProfile VALUE(0); + /* Default security profile */ + +#ifdef HAVE_GSSAPI +VAR int KerberosInitialized VALUE(0); + /* Has Kerberos been initialized? */ +VAR krb5_context KerberosContext VALUE(NULL); + /* Kerberos context for credentials */ +#endif /* HAVE_GSSAPI */ + +#ifdef HAVE_LAUNCH_H +VAR int Launchd VALUE(0); + /* Running from launchd */ +#endif /* HAVE_LAUNCH_H */ + +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) +typedef int (*PSQUpdateQuotaProcPtr)(const char *printer, const char *info, + const char *user, int nPages, int options); +VAR PSQUpdateQuotaProcPtr PSQUpdateQuotaProc + VALUE(0); + /* Apple PrintService quota function */ +#endif /* __APPLE__ && HAVE_DLFCN_H */ + + + + +/* + * Prototypes... + */ + +extern void cupsdCheckProcess(void); +extern void cupsdClearString(char **s); +extern void cupsdHoldSignals(void); +extern void cupsdReleaseSignals(void); +extern void cupsdSetString(char **s, const char *v); +extern void cupsdSetStringf(char **s, const char *f, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +#endif /* __GNUC__ */ +; +extern void cupsdStartServer(void); +extern void cupsdStopServer(void); +extern void cupsdClosePipe(int *fds); +extern int cupsdOpenPipe(int *fds); + +extern void cupsdInitEnv(void); +extern int cupsdLoadEnv(char *envp[], int envmax); +extern void cupsdSetEnv(const char *name, const char *value); +extern void cupsdSetEnvf(const char *name, const char *value, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +#endif /* __GNUC__ */ +; +extern void cupsdUpdateEnv(void); + +extern void *cupsdCreateProfile(int job_id); +extern void cupsdDestroyProfile(void *profile); +extern int cupsdEndProcess(int pid, int force); +extern const char *cupsdFinishProcess(int pid, char *name, int namelen, + int *job_id); +extern int cupsdStartProcess(const char *command, char *argv[], + char *envp[], int infd, int outfd, + int errfd, int backfd, int sidefd, + int root, void *profile, cupsd_job_t *job, + int *pid); + +extern int cupsdAddSelect(int fd, cupsd_selfunc_t read_cb, + cupsd_selfunc_t write_cb, void *data); +extern int cupsdDoSelect(long timeout); +#ifdef CUPSD_IS_SELECTING +extern int cupsdIsSelecting(int fd); +#endif /* CUPSD_IS_SELECTING */ +extern void cupsdRemoveSelect(int fd); +extern void cupsdStartSelect(void); +extern void cupsdStopSelect(void); + +extern int cupsdRemoveFile(const char *filename); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/cupsd.order b/scheduler/cupsd.order new file mode 100644 index 0000000000..adf0c5bc59 --- /dev/null +++ b/scheduler/cupsd.order @@ -0,0 +1,93 @@ +506502610382 _dyld_func_lookup +506502685257 main +506502715804 cupsdSetString +506506372025 cupsdFindLocation +506506395599 cupsdAddLocation +506506422618 compare_locations +506506442028 cupsdAllowIP +506506459141 add_allow +506506478809 read_location +506506500685 parse_aaa +506506520354 cupsdAllowHost +506506554362 cupsdAddName +506506578477 read_policy +506506595949 cupsdAddPolicy +506506651840 cupsdAddPolicyOp +506506850180 cupsdCheckPermissions +506507063184 cupsdInitEnv +506507083008 clear_env +506507102454 cupsdSetEnv +506507138155 cupsdSetEnvf +506507189792 cupsdFindPolicy +506507227839 cupsdDeleteAllSubscriptions +506507248359 cupsdFreeAllJobs +506507267439 cupsdDeleteAllClasses +506507286520 cupsdDeleteAllPrinters +506507307556 mimeLoad +506507324314 mimeMerge +506507355197 mimeNew +506507441845 load_types +506507518598 mimeAddType +506507536778 mimeType +506507556897 mimeAddTypeRule +506507593083 compare_types +506508272080 load_convs +506508326621 add_fcache +506508359303 mimeAddFilter +506508378534 mimeFilterLookup +506508403668 compare_fcache +506508429895 compare_filters +506509114255 delete_fcache +506509154834 mimeNumFilters +506509172690 mimeNumTypes +506509206171 mimeFirstType +506509228911 mimeNextType +506509325837 cupsdLoadBanners +506509344611 free_banners +506509424863 add_banner +506509442851 mimeFileType +506509475474 checkrules +506509509518 patmatch +506509582672 compare_banners +506509797932 cupsdLoadAllPrinters +506509854963 cupsdAddPrinter +506509925950 cupsdSetPrinterAttrs +506509947124 cupsdCreateCommonData +506510213823 delete_printer_filters +506510235340 mimeFirstFilter +506510252530 mimeNextFilter +506510273476 cupsdFindBest +506510293397 cupsdFindPolicyOp +506510353536 cupsdSanitizeURI +506511563302 add_printer_filter +506511697758 add_printer_formats +506511719725 mimeFilter +506511737533 compare_srcs +506511764984 find_filters +506512606253 add_printer_defaults +506512654206 cupsdRegisterPrinter +506512674342 cupsdAddPrinterHistory +506512737170 compare_printers +506524108560 cupsdLoadAllClasses +506524143324 cupsdLoadRemoteCache +506524177711 cupsdWritePrintcap +506524527469 cupsdLoadAllJobs +506524564508 load_job_cache +506524756314 compare_jobs +506524815667 cupsdLoadJob +506524968952 cupsdLoadAllSubscriptions +506525011690 launchd_checkin +506503187119 cupsdStartSelect +506503230913 cupsdReadConfiguration +506503252142 cupsdDeleteAllLocations +506503274576 cupsdDeleteAllListeners +506503310703 cupsdSetStringf +506503363312 cupsdClearString +506505395867 parse_protocols +506505440694 cupsdDeleteAllPolicies +506505501913 read_configuration +506505561788 parse_groups +506505726179 get_address +506505986926 cupsdLogMessage +506506008280 check_log_file +506506240383 cupsdGetDateTime diff --git a/scheduler/cupsfilter.c b/scheduler/cupsfilter.c new file mode 100644 index 0000000000..1e6cc0defa --- /dev/null +++ b/scheduler/cupsfilter.c @@ -0,0 +1,1352 @@ +/* + * "$Id$" + * + * CUPS filtering program for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for the test program. + * compare_pids() - Compare two filter PIDs... + * escape_options() - Convert an options array to a string. + * exec_filter() - Execute a single filter. + * exec_filters() - Execute filters for the given file and options. + * get_job_file() - Get the specified job file. + * open_pipe() - Create a pipe which is closed on exec. + * read_cupsd_conf() - Read the cupsd.conf file to get the filter settings. + * set_string() - Copy and set a string. + * usage() - Show program usage... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include "mime.h" +#include +#include +#include +#include +#include +#include +#if defined(__APPLE__) +# include +#endif /* __APPLE__ */ + + +/* + * Local globals... + */ + +static char *DataDir = NULL;/* CUPS_DATADIR environment variable */ +static char *FontPath = NULL; + /* CUPS_FONTPATH environment variable */ +static mime_filter_t GZIPFilter = /* gziptoany filter */ +{ + NULL, /* Source type */ + NULL, /* Destination type */ + 0, /* Cost */ + "gziptoany" /* Filter program to run */ +}; +static char *Path = NULL; /* PATH environment variable */ +static char *ServerBin = NULL; + /* CUPS_SERVERBIN environment variable */ +static char *ServerRoot = NULL; + /* CUPS_SERVERROOT environment variable */ +static char *RIPCache = NULL; + /* RIP_MAX_CACHE environment variable */ +static char TempFile[1024] = ""; + /* Temporary file */ + + +/* + * Local functions... + */ + +static void add_printer_filter(const char *command, mime_t *mime, + mime_type_t *printer_type, + const char *filter); +static mime_type_t *add_printer_filters(const char *command, + mime_t *mime, const char *printer, + const char *ppdfile, + mime_type_t **prefilter_type); +static int compare_pids(mime_filter_t *a, mime_filter_t *b); +static char *escape_options(int num_options, cups_option_t *options); +static int exec_filter(const char *filter, char **argv, + char **envp, int infd, int outfd); +static int exec_filters(mime_type_t *srctype, + cups_array_t *filters, const char *infile, + const char *outfile, const char *ppdfile, + const char *printer, const char *user, + const char *title, int num_options, + cups_option_t *options); +static void get_job_file(const char *job); +static int open_pipe(int *fds); +static int read_cupsd_conf(const char *filename); +static void set_string(char **s, const char *val); +static void sighandler(int sig); +static void usage(const char *command, const char *opt); + + +/* + * '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 vars */ + const char *command, /* Command name */ + *opt, /* Current option */ + *printer; /* Printer name */ + mime_type_t *printer_type, /* Printer MIME type */ + *prefilter_type; /* Printer prefilter MIME type */ + char *srctype, /* Source type */ + *dsttype, /* Destination type */ + super[MIME_MAX_SUPER], /* Super-type name */ + type[MIME_MAX_TYPE]; /* Type name */ + int compression; /* Compression of file */ + int cost; /* Cost of filters */ + mime_t *mime; /* MIME database */ + char mimedir[1024]; /* MIME directory */ + char *infile, /* File to filter */ + *outfile; /* File to create */ + char cupsdconf[1024]; /* cupsd.conf file */ + const char *server_root; /* CUPS_SERVERROOT environment variable */ + mime_type_t *src, /* Source type */ + *dst; /* Destination type */ + cups_array_t *filters; /* Filters for the file */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + const char *ppdfile; /* PPD file */ + const char *title, /* Title string */ + *user; /* Username */ + int all_filters, /* Use all filters */ + removeppd, /* Remove PPD file */ + removeinfile; /* Remove input file */ + int status; /* Execution status */ + + + /* + * Setup defaults... + */ + + if ((command = strrchr(argv[0], '/')) != NULL) + command ++; + else + command = argv[0]; + + printer = !strcmp(command, "convert") ? "tofile" : "cupsfilter"; + mime = NULL; + srctype = NULL; + compression = 0; + dsttype = "application/pdf"; + infile = NULL; + outfile = NULL; + num_options = 0; + options = NULL; + ppdfile = NULL; + title = NULL; + user = cupsUser(); + all_filters = 0; + removeppd = 0; + removeinfile = 0; + + if ((server_root = getenv("CUPS_SERVERROOT")) == NULL) + server_root = CUPS_SERVERROOT; + + snprintf(cupsdconf, sizeof(cupsdconf), "%s/cupsd.conf", server_root); + + /* + * Process command-line arguments... + */ + + _cupsSetLocale(argv); + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case '-' : /* Next argument is a filename... */ + i ++; + if (i < argc && !infile) + infile = argv[i]; + else + usage(command, opt); + break; + + case 'a' : /* Specify option... */ + i ++; + if (i < argc) + num_options = cupsParseOptions(argv[i], num_options, &options); + else + usage(command, opt); + break; + + case 'c' : /* Specify cupsd.conf file location... */ + i ++; + if (i < argc) + { + if (!strcmp(command, "convert")) + num_options = cupsAddOption("copies", argv[i], num_options, + &options); + else + strlcpy(cupsdconf, argv[i], sizeof(cupsdconf)); + } + else + usage(command, opt); + break; + + case 'D' : /* Delete input file after conversion */ + removeinfile = 1; + break; + + case 'e' : /* Use every filter from the PPD file */ + all_filters = 1; + break; + + case 'f' : /* Specify input file... */ + i ++; + if (i < argc && !infile) + infile = argv[i]; + else + usage(command, opt); + break; + + case 'i' : /* Specify source MIME type... */ + i ++; + if (i < argc) + { + if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2) + usage(command, opt); + + srctype = argv[i]; + } + else + usage(command, opt); + break; + + case 'j' : /* Get job file or specify destination MIME type... */ + if (strcmp(command, "convert")) + { + i ++; + if (i < argc) + { + get_job_file(argv[i]); + infile = TempFile; + } + else + usage(command, opt); + + break; + } + + case 'm' : /* Specify destination MIME type... */ + i ++; + if (i < argc) + { + if (sscanf(argv[i], "%15[^/]/%255s", super, type) != 2) + usage(command, opt); + + dsttype = argv[i]; + } + else + usage(command, opt); + break; + + case 'n' : /* Specify number of copies... */ + i ++; + if (i < argc) + num_options = cupsAddOption("copies", argv[i], num_options, + &options); + else + usage(command, opt); + break; + + case 'o' : /* Specify option(s) or output filename */ + i ++; + if (i < argc) + { + if (!strcmp(command, "convert")) + { + if (outfile) + usage(command, NULL); + else + outfile = argv[i]; + } + else + num_options = cupsParseOptions(argv[i], num_options, + &options); + } + else + usage(command, opt); + break; + + case 'p' : /* Specify PPD file... */ + case 'P' : /* Specify PPD file... */ + i ++; + if (i < argc) + ppdfile = argv[i]; + else + usage(command, opt); + break; + + case 't' : /* Specify title... */ + case 'J' : /* Specify title... */ + i ++; + if (i < argc) + title = argv[i]; + else + usage(command, opt); + break; + + case 'u' : /* Delete PPD file after conversion */ + removeinfile = 1; + break; + + case 'U' : /* Specify username... */ + i ++; + if (i < argc) + user = argv[i]; + else + usage(command, opt); + break; + + default : /* Something we don't understand... */ + usage(command, opt); + break; + } + } + else if (!infile) + { + if (strcmp(command, "convert")) + infile = argv[i]; + else + { + _cupsLangPuts(stderr, + _("convert: Use the -f option to specify a file to " + "convert.\n")); + usage(command, NULL); + } + } + else + { + _cupsLangPuts(stderr, + _("cupsfilter: Only one filename can be specified!\n")); + usage(command, NULL); + } + + if (!infile && !srctype) + usage(command, NULL); + + if (!title) + { + if (!infile) + title = "(stdin)"; + else if ((title = strrchr(infile, '/')) != NULL) + title ++; + else + title = infile; + } + + /* + * Load the cupsd.conf file and create the MIME database... + */ + + if (read_cupsd_conf(cupsdconf)) + return (1); + + snprintf(mimedir, sizeof(mimedir), "%s/mime", DataDir); + + mime = mimeLoadTypes(NULL, mimedir); + mime = mimeLoadTypes(mime, ServerRoot); + mime = mimeLoadFilters(mime, mimedir, Path); + mime = mimeLoadFilters(mime, ServerRoot, Path); + + if (!mime) + { + _cupsLangPrintf(stderr, + _("%s: Unable to read MIME database from \"%s\" or " + "\"%s\"!\n"), + command, mimedir, ServerRoot); + return (1); + } + + if (all_filters) + { + printer_type = add_printer_filters(command, mime, printer, ppdfile, + &prefilter_type); + } + else + { + printer_type = mimeType(mime, "application", "vnd.cups-postscript"); + prefilter_type = NULL; + } + + /* + * Get the source and destination types... + */ + + if (srctype) + { + sscanf(srctype, "%15[^/]/%255s", super, type); + if ((src = mimeType(mime, super, type)) == NULL) + { + _cupsLangPrintf(stderr, + _("%s: Unknown source MIME type %s/%s!\n"), + command, super, type); + return (1); + } + } + else if ((src = mimeFileType(mime, infile, infile, &compression)) == NULL) + { + _cupsLangPrintf(stderr, + _("%s: Unable to determine MIME type of \"%s\"!\n"), + command, infile); + return (1); + } + + sscanf(dsttype, "%15[^/]/%255s", super, type); + if (!strcasecmp(super, "printer")) + dst = printer_type; + else if ((dst = mimeType(mime, super, type)) == NULL) + { + _cupsLangPrintf(stderr, + _("%s: Unknown destination MIME type %s/%s!\n"), + command, super, type); + return (1); + } + + /* + * Figure out how to filter the file... + */ + + if (src == dst) + { + /* + * Special case - no filtering needed... + */ + + filters = cupsArrayNew(NULL, NULL); + cupsArrayAdd(filters, &GZIPFilter); + GZIPFilter.src = src; + GZIPFilter.dst = dst; + } + else if ((filters = mimeFilter(mime, src, dst, &cost)) == NULL) + { + _cupsLangPrintf(stderr, + _("%s: No filter to convert from %s/%s to %s/%s!\n"), + command, src->super, src->type, dst->super, dst->type); + return (1); + } + else if (compression) + cupsArrayInsert(filters, &GZIPFilter); + + if (prefilter_type) + { + /* + * Add pre-filters... + */ + + mime_filter_t *filter, /* Current filter */ + *prefilter; /* Current pre-filter */ + cups_array_t *prefilters = cupsArrayNew(NULL, NULL); + /* New filters array */ + + + for (filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + { + if ((prefilter = mimeFilterLookup(mime, filter->src, + prefilter_type)) != NULL) + cupsArrayAdd(prefilters, prefilter); + + cupsArrayAdd(prefilters, filter); + } + + cupsArrayDelete(filters); + filters = prefilters; + } + + /* + * Do it! + */ + + status = exec_filters(src, filters, infile, outfile, ppdfile, printer, user, + title, num_options, options); + + /* + * Remove files as needed, then exit... + */ + + if (TempFile[0]) + unlink(TempFile); + + if (removeppd && ppdfile) + unlink(ppdfile); + + if (removeinfile && infile) + unlink(infile); + + return (status); +} + + +/* + * 'add_printer_filter()' - Add a single filters from a PPD file. + */ + +static void +add_printer_filter( + const char *command, /* I - Command name */ + mime_t *mime, /* I - MIME database */ + mime_type_t *filtertype, /* I - Printer or prefilter MIME type */ + const char *filter) /* I - Filter to add */ +{ + 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 */ + char filename[1024]; /* Full filter filename */ + + + /* + * Parse the filter string; it should be in the following format: + * + * super/type cost program + */ + + if (sscanf(filter, "%15[^/]/%31s%d%*[ \t]%1023[^\n]", super, type, &cost, + program) != 4) + { + _cupsLangPrintf(stderr, _("%s: Invalid filter string \"%s\"\n"), command, + filter); + return; + } + + /* + * See if the filter program exists; if not, stop the printer and flag + * the error! + */ + + if (strcmp(program, "-")) + { + if (program[0] == '/') + strlcpy(filename, program, sizeof(filename)); + else + snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program); + + if (access(filename, X_OK)) + { + _cupsLangPrintf(stderr, _("%s: Filter \"%s\" not available: %s\n"), + command, program, strerror(errno)); + return; + } + } + + /* + * Add the filter to the MIME database, supporting wildcards as needed... + */ + + for (temptype = mimeFirstType(mime); + temptype; + temptype = mimeNextType(mime)) + if (((super[0] == '*' && strcasecmp(temptype->super, "printer")) || + !strcasecmp(temptype->super, super)) && + (type[0] == '*' || !strcasecmp(temptype->type, type))) + mimeAddFilter(mime, temptype, filtertype, cost, program); +} + + +/* + * 'add_printer_filters()' - Add filters from a PPD file. + */ + +static mime_type_t * /* O - Printer type or NULL on error */ +add_printer_filters( + const char *command, /* I - Command name */ + mime_t *mime, /* I - MIME database */ + const char *printer, /* I - Printer name */ + const char *ppdfile, /* I - PPD file */ + mime_type_t **prefilter_type) /* O - Prefilter type */ +{ + int i; /* Looping var */ + mime_type_t *printer_type; /* Printer MIME type */ + ppd_file_t *ppd; /* PPD file data */ + ppd_attr_t *ppdattr; /* Current prefilter */ + + + *prefilter_type = NULL; + + if ((ppd = ppdOpenFile(ppdfile)) == NULL) + { + ppd_status_t status; /* PPD load status */ + + status = ppdLastError(&i); + _cupsLangPrintf(stderr, _("%s: Unable to open PPD file: %s on line %d\n"), + command, ppdErrorString(status), i); + return (NULL); + } + + printer_type = mimeAddType(mime, "printer", printer); + + if (ppd->num_filters > 0) + { + for (i = 0; i < ppd->num_filters; i ++) + add_printer_filter(command, mime, printer_type, ppd->filters[i]); + } + else + { + add_printer_filter(command, mime, printer_type, + "application/vnd.cups-command 0 commandtops"); + add_printer_filter(command, mime, printer_type, + "application/vnd.cups-postscript 0 -"); + } + + if ((ppdattr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL) + { + *prefilter_type = mimeAddType(mime, "prefilter", printer); + + for (; ppdattr; ppdattr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL)) + if (ppdattr->value) + add_printer_filter(command, mime, *prefilter_type, ppdattr->value); + } + else + *prefilter_type = NULL; + + return (printer_type); +} + + +/* + * 'compare_pids()' - Compare two filter PIDs... + */ + +static int /* O - Result of comparison */ +compare_pids(mime_filter_t *a, /* I - First filter */ + mime_filter_t *b) /* I - Second filter */ +{ + /* + * Because we're particularly lazy, we store the process ID in the "cost" + * variable... + */ + + return (a->cost - b->cost); +} + + +/* + * 'escape_options()' - Convert an options array to a string. + */ + +static char * /* O - Option string */ +escape_options( + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int i; /* Looping var */ + cups_option_t *option; /* Current option */ + int bytes; /* Number of bytes needed */ + char *s, /* Option string */ + *sptr, /* Pointer into string */ + *vptr; /* Pointer into value */ + + + /* + * Figure out the worst-case number of bytes we need for the option string. + */ + + for (i = num_options, option = options, bytes = 1; i > 0; i --, option ++) + bytes += 2 * (strlen(option->name) + strlen(option->value)) + 2; + + if ((s = malloc(bytes)) == NULL) + return (NULL); + + /* + * Copy the options to the string... + */ + + for (i = num_options, option = options, sptr = s; i > 0; i --, option ++) + { + if (!strcmp(option->name, "copies")) + continue; + + if (sptr > s) + *sptr++ = ' '; + + strcpy(sptr, option->name); + sptr += strlen(sptr); + *sptr++ = '='; + + for (vptr = option->value; *vptr;) + { + if (strchr("\\ \t\n", *vptr)) + *sptr++ = '\\'; + + *sptr++ = *vptr++; + } + } + + *sptr = '\0'; + + return (s); +} + + +/* + * 'exec_filter()' - Execute a single filter. + */ + +static int /* O - Process ID or -1 on error */ +exec_filter(const char *filter, /* I - Filter to execute */ + char **argv, /* I - Argument list */ + char **envp, /* I - Environment list */ + int infd, /* I - Stdin file descriptor */ + int outfd) /* I - Stdout file descriptor */ +{ + int pid, /* Process ID */ + fd; /* Temporary file descriptor */ +#if defined(__APPLE__) + char processPath[1024], /* CFProcessPath environment variable */ + linkpath[1024]; /* Link path for symlinks... */ + int linkbytes; /* Bytes for link path */ + + + /* + * Add special voodoo magic for MacOS X - this allows MacOS X + * programs to access their bundle resources properly... + */ + + if ((linkbytes = readlink(filter, linkpath, sizeof(linkpath) - 1)) > 0) + { + /* + * Yes, this is a symlink to the actual program, nul-terminate and + * use it... + */ + + linkpath[linkbytes] = '\0'; + + if (linkpath[0] == '/') + snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", + linkpath); + else + snprintf(processPath, sizeof(processPath), "CFProcessPath=%s/%s", + dirname((char *)filter), linkpath); + } + else + snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", filter); + + envp[0] = processPath; /* Replace string */ +#endif /* __APPLE__ */ + + if ((pid = fork()) == 0) + { + /* + * Child process goes here... + * + * Update stdin/stdout/stderr as needed... + */ + + if (infd != 0) + { + if (infd < 0) + infd = open("/dev/null", O_RDONLY); + + if (infd > 0) + { + dup2(infd, 0); + close(infd); + } + } + + if (outfd != 1) + { + if (outfd < 0) + outfd = open("/dev/null", O_WRONLY); + + if (outfd > 1) + { + dup2(outfd, 1); + close(outfd); + } + } + + if ((fd = open("/dev/null", O_RDWR)) > 3) + { + dup2(fd, 3); + close(fd); + } + fcntl(3, F_SETFL, O_NDELAY); + + if ((fd = open("/dev/null", O_RDWR)) > 4) + { + dup2(fd, 4); + close(fd); + } + fcntl(4, F_SETFL, O_NDELAY); + + /* + * Execute command... + */ + + execve(filter, argv, envp); + + perror(filter); + + exit(errno); + } + + return (pid); +} + + +/* + * 'exec_filters()' - Execute filters for the given file and options. + */ + +static int /* O - 0 on success, 1 on error */ +exec_filters(mime_type_t *srctype, /* I - Source type */ + cups_array_t *filters, /* I - Array of filters to run */ + const char *infile, /* I - File to filter */ + const char *outfile, /* I - File to create */ + const char *ppdfile, /* I - PPD file, if any */ + const char *printer, /* I - Printer name */ + const char *user, /* I - Username */ + const char *title, /* I - Job title */ + int num_options, /* I - Number of filter options */ + cups_option_t *options) /* I - Filter options */ +{ + int i; /* Looping var */ + const char *argv[8], /* Command-line arguments */ + *envp[12], /* Environment variables */ + *temp; /* Temporary string */ + char *optstr, /* Filter options */ + content_type[1024], /* CONTENT_TYPE */ + cups_datadir[1024], /* CUPS_DATADIR */ + cups_fontpath[1024], /* CUPS_FONTPATH */ + cups_serverbin[1024], /* CUPS_SERVERBIN */ + cups_serverroot[1024], /* CUPS_SERVERROOT */ + lang[1024], /* LANG */ + path[1024], /* PATH */ + ppd[1024], /* PPD */ + rip_max_cache[1024], /* RIP_MAX_CACHE */ + userenv[1024], /* USER */ + program[1024]; /* Program to run */ + mime_filter_t *filter, /* Current filter */ + *next; /* Next filter */ + int current, /* Current filter */ + filterfds[2][2], /* Pipes for filters */ + pid, /* Process ID of filter */ + status, /* Exit status */ + retval; /* Return value */ + cups_array_t *pids; /* Executed filters array */ + mime_filter_t key; /* Search key for filters */ + cups_lang_t *language; /* Current language */ + + + /* + * Setup the filter environment and command-line... + */ + + optstr = escape_options(num_options, options); + + snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s", + srctype->super, srctype->type); + snprintf(cups_datadir, sizeof(cups_datadir), "CUPS_DATADIR=%s", DataDir); + snprintf(cups_fontpath, sizeof(cups_fontpath), "CUPS_FONTPATH=%s", FontPath); + snprintf(cups_serverbin, sizeof(cups_serverbin), "CUPS_SERVERBIN=%s", + ServerBin); + snprintf(cups_serverroot, sizeof(cups_serverroot), "CUPS_SERVERROOT=%s", + ServerRoot); + language = cupsLangDefault(); + snprintf(lang, sizeof(lang), "LANG=%s.UTF8", language->language); + snprintf(path, sizeof(path), "PATH=%s", Path); + if (ppdfile) + snprintf(ppd, sizeof(ppd), "PPD=%s", ppdfile); + else if ((temp = getenv("PPD")) != NULL) + snprintf(ppd, sizeof(ppd), "PPD=%s", temp); + else +#ifdef __APPLE__ + if (!access("/System/Library/Frameworks/ApplicationServices.framework/" + "Versions/A/Frameworks/PrintCore.framework/Versions/A/" + "Resources/English.lproj/Generic.ppd", 0)) + strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/" + "Versions/A/Frameworks/PrintCore.framework/Versions/A/" + "Resources/English.lproj/Generic.ppd", sizeof(ppd)); + else + strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/" + "Versions/A/Frameworks/PrintCore.framework/Versions/A/" + "Resources/Generic.ppd", sizeof(ppd)); +#else + snprintf(ppd, sizeof(ppd), "PPD=%s/model/laserjet.ppd", DataDir); +#endif /* __APPLE__ */ + snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache); + snprintf(userenv, sizeof(userenv), "USER=%s", user); + + argv[0] = (char *)printer; + argv[1] = "1"; + argv[2] = user; + argv[3] = title; + argv[4] = cupsGetOption("copies", num_options, options); + argv[5] = optstr; + argv[6] = infile; + argv[7] = NULL; + + if (!argv[4]) + argv[4] = "1"; + + envp[0] = ""; + envp[1] = content_type; + envp[2] = cups_datadir; + envp[3] = cups_fontpath; + envp[4] = cups_serverbin; + envp[5] = cups_serverroot; + envp[6] = lang; + envp[7] = path; + envp[8] = ppd; + envp[9] = rip_max_cache; + envp[10] = userenv; + envp[11] = NULL; + + for (i = 0; argv[i]; i ++) + fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); + + for (i = 0; envp[i]; i ++) + fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]); + + /* + * Execute all of the filters... + */ + + pids = cupsArrayNew((cups_array_func_t)compare_pids, NULL); + current = 0; + filterfds[0][0] = -1; + filterfds[0][1] = -1; + filterfds[1][0] = -1; + filterfds[1][1] = -1; + + if (!infile) + filterfds[0][0] = 0; + + for (filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + filter = next, current = 1 - current) + { + next = (mime_filter_t *)cupsArrayNext(filters); + + if (filter->filter[0] == '/') + strlcpy(program, filter->filter, sizeof(program)); + else + snprintf(program, sizeof(program), "%s/filter/%s", ServerBin, + filter->filter); + + if (filterfds[!current][1] > 1) + { + close(filterfds[1 - current][0]); + close(filterfds[1 - current][1]); + + filterfds[1 - current][0] = -1; + filterfds[1 - current][0] = -1; + } + + if (next) + open_pipe(filterfds[1 - current]); + else if (outfile) + { + filterfds[1 - current][1] = open(outfile, O_CREAT | O_TRUNC | O_WRONLY, + 0666); + + if (filterfds[1 - current][1] < 0) + fprintf(stderr, "ERROR: Unable to create \"%s\" - %s\n", outfile, + strerror(errno)); + } + else + filterfds[1 - current][1] = 1; + + pid = exec_filter(program, (char **)argv, (char **)envp, + filterfds[current][0], filterfds[1 - current][1]); + + if (pid > 0) + { + fprintf(stderr, "INFO: %s (PID %d) started.\n", filter->filter, pid); + + filter->cost = pid; + cupsArrayAdd(pids, filter); + } + else + break; + + argv[6] = NULL; + } + + /* + * Close remaining pipes... + */ + + if (filterfds[0][1] > 1) + { + close(filterfds[0][0]); + close(filterfds[0][1]); + } + + if (filterfds[1][1] > 1) + { + close(filterfds[1][0]); + close(filterfds[1][1]); + } + + /* + * Wait for the children to exit... + */ + + retval = 0; + + while (cupsArrayCount(pids) > 0) + { + if ((pid = wait(&status)) < 0) + continue; + + key.cost = pid; + if ((filter = (mime_filter_t *)cupsArrayFind(pids, &key)) != NULL) + { + cupsArrayRemove(pids, filter); + + if (status) + { + if (WIFEXITED(status)) + fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d!\n", + filter->filter, pid, WEXITSTATUS(status)); + else + fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d!\n", + filter->filter, pid, WTERMSIG(status)); + + retval = 1; + } + else + fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n", + filter->filter, pid); + } + } + + cupsArrayDelete(pids); + + return (retval); +} + + +/* + * 'get_job_file()' - Get the specified job file. + */ + +static void +get_job_file(const char *job) /* I - Job ID */ +{ + long jobid, /* Job ID */ + docnum; /* Document number */ + const char *jobptr; /* Pointer into job ID string */ + char uri[1024]; /* job-uri */ + http_t *http; /* Connection to server */ + ipp_t *request; /* Request data */ + int tempfd; /* Temporary file */ + + + /* + * Get the job ID and document number, if any... + */ + + if ((jobptr = strrchr(job, '-')) != NULL) + jobptr ++; + else + jobptr = job; + + jobid = strtol(jobptr, (char **)&jobptr, 10); + + if (*jobptr == ',') + docnum = strtol(jobptr + 1, NULL, 10); + else + docnum = 1; + + if (jobid < 1 || jobid > INT_MAX) + { + _cupsLangPrintf(stderr, _("cupsfilter: Invalid job ID %d!\n"), (int)jobid); + exit(1); + } + + if (docnum < 1 || docnum > INT_MAX) + { + _cupsLangPrintf(stderr, _("cupsfilter: Invalid document number %d!\n"), + (int)docnum); + exit(1); + } + + /* + * Ask the server for the document file... + */ + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + _cupsLangPrintf(stderr, _("%s: Unable to connect to server\n"), + "cupsfilter"); + exit(1); + } + + request = ippNewRequest(CUPS_GET_DOCUMENT); + + snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", (int)jobid); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "document-number", + (int)docnum); + + if ((tempfd = cupsTempFd(TempFile, sizeof(TempFile))) == -1) + { + _cupsLangPrintError(_("ERROR: Unable to create temporary file")); + httpClose(http); + exit(1); + } + + signal(SIGTERM, sighandler); + + ippDelete(cupsDoIORequest(http, request, "/", -1, tempfd)); + + close(tempfd); + + httpClose(http); + + if (cupsLastError() != IPP_OK) + { + _cupsLangPrintf(stderr, _("cupsfilter: Unable to get job file - %s\n"), + cupsLastErrorString()); + unlink(TempFile); + exit(1); + } +} + + +/* + * 'open_pipe()' - Create a pipe which is closed on exec. + */ + +static int /* O - 0 on success, -1 on error */ +open_pipe(int *fds) /* O - Pipe file descriptors (2) */ +{ + /* + * Create the pipe... + */ + + if (pipe(fds)) + { + fds[0] = -1; + fds[1] = -1; + + return (-1); + } + + /* + * Set the "close on exec" flag on each end of the pipe... + */ + + if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) + { + close(fds[0]); + close(fds[1]); + + fds[0] = -1; + fds[1] = -1; + + return (-1); + } + + if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) + { + close(fds[0]); + close(fds[1]); + + fds[0] = -1; + fds[1] = -1; + + return (-1); + } + + /* + * Return 0 indicating success... + */ + + return (0); +} + + +/* + * 'read_cupsd_conf()' - Read the cupsd.conf file to get the filter settings. + */ + +static int /* O - 0 on success, 1 on error */ +read_cupsd_conf(const char *filename) /* I - File to read */ +{ + cups_file_t *fp; /* cupsd.conf file */ + const char *temp; /* Temporary string */ + char line[1024], /* Line from file */ + *ptr; /* Pointer into line */ + int linenum; /* Current line number */ + + + if ((temp = getenv("CUPS_DATADIR")) != NULL) + set_string(&DataDir, temp); + else + set_string(&DataDir, CUPS_DATADIR); + + if ((temp = getenv("CUPS_FONTPATH")) != NULL) + set_string(&FontPath, temp); + else + set_string(&FontPath, CUPS_FONTPATH); + + set_string(&RIPCache, "8m"); + + if ((temp = getenv("CUPS_SERVERBIN")) != NULL) + set_string(&ServerBin, temp); + else + set_string(&ServerBin, CUPS_SERVERBIN); + + strlcpy(line, filename, sizeof(line)); + if ((ptr = strrchr(line, '/')) != NULL) + *ptr = '\0'; + else + getcwd(line, sizeof(line)); + + set_string(&ServerRoot, line); + + if ((fp = cupsFileOpen(filename, "r")) != NULL) + { + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &ptr, &linenum)) + { + if (!strcasecmp(line, "DataDir")) + set_string(&DataDir, ptr); + else if (!strcasecmp(line, "FontPath")) + set_string(&FontPath, ptr); + else if (!strcasecmp(line, "RIPCache")) + set_string(&RIPCache, ptr); + else if (!strcasecmp(line, "ServerBin")) + set_string(&ServerBin, ptr); + else if (!strcasecmp(line, "ServerRoot")) + set_string(&ServerRoot, ptr); + } + + cupsFileClose(fp); + } + + snprintf(line, sizeof(line), + "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin", + ServerBin); + set_string(&Path, line); + + return (0); +} + + +/* + * 'set_string()' - Copy and set a string. + */ + +static void +set_string(char **s, /* O - Copy of string */ + const char *val) /* I - String to copy */ +{ + if (*s) + free(*s); + + *s = strdup(val); +} + + +/* + * 'sighandler()' - Signal catcher for when we print from stdin... + */ + +static void +sighandler(int s) /* I - Signal number */ +{ + /* + * Remove the temporary file we're using to print a job file... + */ + + if (TempFile[0]) + unlink(TempFile); + + /* + * Exit... + */ + + exit(s); +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(const char *command, /* I - Command name */ + const char *opt) /* I - Incorrect option, if any */ +{ + if (opt) + _cupsLangPrintf(stderr, _("%s: Unknown option '%c'!\n"), command, *opt); + + if (!strcmp(command, "cupsfilter")) + _cupsLangPuts(stdout, + _("Usage: cupsfilter -m mime/type [ options ] filename\n" + "\n" + "Options:\n" + "\n" + " -c cupsd.conf Set cupsd.conf file to use\n" + " -e Use every filter from the PPD file\n" + " -j job-id[,N] Filter file N from the specified job (default is file 1)\n" + " -n copies Set number of copies\n" + " -o name=value Set option(s)\n" + " -p filename.ppd Set PPD file\n" + " -t title Set title\n")); + else + _cupsLangPuts(stdout, + _("Usage: convert [ options ]\n" + "\n" + "Options:\n" + "\n" + " -e Use every filter from the PPD file\n" + " -f filename Set file to be converted (otherwise stdin)\n" + " -o filename Set file to be generated (otherwise stdout)\n" + " -i mime/type Set input MIME type (otherwise auto-typed)\n" + " -j mime/type Set output MIME type (otherwise application/pdf)\n" + " -P filename.ppd Set PPD file\n" + " -a 'name=value ...' Set option(s)\n" + " -U username Set username for job\n" + " -J title Set title\n" + " -c copies Set number of copies\n" + " -u Remove the PPD file when finished\n" + " -D Remove the input file when finished\n")); + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c new file mode 100644 index 0000000000..affa75941d --- /dev/null +++ b/scheduler/dirsvc.c @@ -0,0 +1,5552 @@ +/* + * "$Id$" + * + * Directory services routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdDeregisterPrinter() - Stop sending broadcast information for a local + * printer and remove any pending references to + * remote printers. + * cupsdLoadRemoteCache() - Load the remote printer cache. + * cupsdRegisterPrinter() - Start sending broadcast information for a + * printer or update the broadcast contents. + * cupsdRestartPolling() - Restart polling servers as needed. + * cupsdSaveRemoteCache() - Save the remote printer cache. + * cupsdSendBrowseList() - Send new browsing information as necessary. + * ldap_rebind_proc() - Callback function for LDAP rebind + * ldap_connect() - Start new LDAP connection + * ldap_reconnect() - Reconnect to LDAP Server + * ldap_disconnect() - Disconnect from LDAP Server + * cupsdStartBrowsing() - Start sending and receiving broadcast + * information. + * cupsdStartPolling() - Start polling servers as needed. + * cupsdStopBrowsing() - Stop sending and receiving broadcast + * information. + * cupsdStopPolling() - Stop polling servers as needed. + * cupsdUpdateDNSSDName() - Update the computer name we use for + * browsing... + * cupsdUpdateLDAPBrowse() - Scan for new printers via LDAP... + * cupsdUpdateSLPBrowse() - Get browsing information via SLP. + * dequote() - Remote quotes from a string. + * dnssdAddAlias() - Add a DNS-SD alias name. + * dnssdBuildTxtRecord() - Build a TXT record from printer info. + * dnssdComparePrinters() - Compare the registered names of two printers. + * dnssdDeregisterPrinter() - Stop sending broadcast information for a + * printer. + * dnssdPackTxtRecord() - Pack an array of key/value pairs into the TXT + * record format. + * dnssdRegisterCallback() - DNSServiceRegister callback. + * dnssdRegisterPrinter() - Start sending broadcast information for a + * printer or update the broadcast contents. + * dnssdStop() - Stop all DNS-SD registrations. + * dnssdUpdate() - Handle DNS-SD queries. + * get_auth_info_required() - Get the auth-info-required value to advertise. + * get_hostconfig() - Get an /etc/hostconfig service setting. + * is_local_queue() - Determine whether the URI points at a local + * queue. + * process_browse_data() - Process new browse data. + * process_implicit_classes() - Create/update implicit classes as needed. + * send_cups_browse() - Send new browsing information using the CUPS + * protocol. + * ldap_search_rec() - LDAP Search with reconnect + * ldap_freeres() - Free LDAPMessage + * ldap_getval_char() - Get first LDAP value and convert to string + * send_ldap_ou() - Send LDAP ou registrations. + * send_ldap_browse() - Send LDAP printer registrations. + * ldap_dereg_printer() - Delete printer from directory + * ldap_dereg_ou() - Remove the organizational unit. + * send_slp_browse() - Register the specified printer with SLP. + * slp_attr_callback() - SLP attribute callback + * slp_dereg_printer() - SLPDereg() the specified printer + * slp_get_attr() - Get an attribute from an SLP registration. + * slp_reg_callback() - Empty SLPRegReport. + * slp_url_callback() - SLP service url callback + * update_cups_browse() - Update the browse lists using the CUPS + * protocol. + * update_lpd() - Update the LPD configuration as needed. + * update_polling() - Read status messages from the poll daemons. + * update_smb() - Update the SMB configuration as needed. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include + +#ifdef HAVE_DNSSD +# include +# ifdef __APPLE__ +# include +# ifdef HAVE_COREFOUNDATION +# include +# endif /* HAVE_COREFOUNDATION */ +# ifdef HAVE_SYSTEMCONFIGURATION +# include +# endif /* HAVE_SYSTEMCONFIGURATION */ +# endif /* __APPLE__ */ +#endif /* HAVE_DNSSD */ + + +/* + * Local functions... + */ + +static char *dequote(char *d, const char *s, int dlen); +static char *get_auth_info_required(cupsd_printer_t *p, char *buffer, + size_t bufsize); +#ifdef __APPLE__ +static int get_hostconfig(const char *name); +#endif /* __APPLE__ */ +static int is_local_queue(const char *uri, char *host, int hostlen, + char *resource, int resourcelen); +static void process_browse_data(const char *uri, const char *host, + const char *resource, cups_ptype_t type, + ipp_pstate_t state, const char *location, + const char *info, const char *make_model, + int num_attrs, cups_option_t *attrs); +static void process_implicit_classes(void); +static void send_cups_browse(cupsd_printer_t *p); +#ifdef HAVE_LDAP +static LDAP *ldap_connect(void); +static LDAP *ldap_reconnect(void); +static void ldap_disconnect(LDAP *ld); +static int ldap_search_rec(LDAP *ld, char *base, int scope, + char *filter, char *attrs[], + int attrsonly, LDAPMessage **res); +static int ldap_getval_firststring(LDAP *ld, LDAPMessage *entry, + char *attr, char *retval, + unsigned long maxsize); +static void ldap_freeres(LDAPMessage *entry); +static void send_ldap_ou(char *ou, char *basedn, char *descstring); +static void send_ldap_browse(cupsd_printer_t *p); +static void ldap_dereg_printer(cupsd_printer_t *p); +static void ldap_dereg_ou(char *ou, char *basedn); +# ifdef HAVE_LDAP_REBIND_PROC +# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +static int ldap_rebind_proc(LDAP *RebindLDAPHandle, + LDAP_CONST char *refsp, + ber_tag_t request, + ber_int_t msgid, + void *params); +# else +static int ldap_rebind_proc(LDAP *RebindLDAPHandle, + char **dnp, + char **passwdp, + int *authmethodp, + int freeit, + void *arg); +# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */ +# endif /* HAVE_LDAP_REBIND_PROC */ +#endif /* HAVE_LDAP */ +#ifdef HAVE_LIBSLP +static void send_slp_browse(cupsd_printer_t *p); +#endif /* HAVE_LIBSLP */ +static void update_cups_browse(void); +static void update_lpd(int onoff); +static void update_polling(void); +static void update_smb(int onoff); + + +#ifdef HAVE_DNSSD +# ifdef HAVE_COREFOUNDATION +static void dnssdAddAlias(const void *key, const void *value, + void *context); +# endif /* HAVE_COREFOUNDATION */ +static char *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p, + int for_lpd); +static int dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b); +static void dnssdDeregisterPrinter(cupsd_printer_t *p); +static char *dnssdPackTxtRecord(int *txt_len, char *keyvalue[][2], + int count); +static void dnssdRegisterCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char *name, const char *regtype, + const char *domain, void *context); +static void dnssdRegisterPrinter(cupsd_printer_t *p); +static void dnssdStop(void); +static void dnssdUpdate(void); +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_LDAP +static const char * const ldap_attrs[] =/* CUPS LDAP attributes */ + { + "printerDescription", + "printerLocation", + "printerMakeAndModel", + "printerType", + "printerURI", + NULL + }; +#endif /* HAVE_LDAP */ + +#ifdef HAVE_LIBSLP +/* + * SLP definitions... + */ + +/* + * SLP service name for CUPS... + */ + +# define SLP_CUPS_SRVTYPE "service:printer" +# define SLP_CUPS_SRVLEN 15 + + +/* + * Printer service URL structure + */ + +typedef struct _slpsrvurl_s /**** SLP URL list ****/ +{ + struct _slpsrvurl_s *next; /* Next URL in list */ + char url[HTTP_MAX_URI]; + /* URL */ +} slpsrvurl_t; + + +/* + * Local functions... + */ + +static SLPBoolean slp_attr_callback(SLPHandle hslp, const char *attrlist, + SLPError errcode, void *cookie); +static void slp_dereg_printer(cupsd_printer_t *p); +static int slp_get_attr(const char *attrlist, const char *tag, + char **valbuf); +static void slp_reg_callback(SLPHandle hslp, SLPError errcode, + void *cookie); +static SLPBoolean slp_url_callback(SLPHandle hslp, const char *srvurl, + unsigned short lifetime, + SLPError errcode, void *cookie); +#endif /* HAVE_LIBSLP */ + + +/* + * 'cupsdDeregisterPrinter()' - Stop sending broadcast information for a + * local printer and remove any pending + * references to remote printers. + */ + +void +cupsdDeregisterPrinter( + cupsd_printer_t *p, /* I - Printer to register */ + int removeit) /* I - Printer being permanently removed */ +{ + /* + * Only deregister if browsing is enabled and it's a local printer... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdDeregisterPrinter(p=%p(%s), removeit=%d)", p, p->name, + removeit); + + if (!Browsing || !p->shared || + (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_SCANNER))) + return; + + /* + * Announce the deletion... + */ + + if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0) + { + cups_ptype_t savedtype = p->type; /* Saved printer type */ + + p->type |= CUPS_PRINTER_DELETE; + + send_cups_browse(p); + + p->type = savedtype; + } + +#ifdef HAVE_LIBSLP + if (BrowseLocalProtocols & BROWSE_SLP) + slp_dereg_printer(p); +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if (BrowseLocalProtocols & BROWSE_LDAP) + ldap_dereg_printer(p); +#endif /* HAVE_LDAP */ + +#ifdef HAVE_DNSSD + if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef) + dnssdDeregisterPrinter(p); +#endif /* HAVE_DNSSD */ +} + + +/* + * 'cupsdLoadRemoteCache()' - Load the remote printer cache. + */ + +void +cupsdLoadRemoteCache(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* remote.cache file */ + int linenum; /* Current line number */ + char line[4096], /* Line from file */ + *value, /* Pointer to value */ + *valueptr, /* Pointer into value */ + scheme[32], /* Scheme portion of URI */ + username[64], /* Username portion of URI */ + host[HTTP_MAX_HOST], + /* Hostname portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port number */ + cupsd_printer_t *p; /* Current printer */ + time_t now; /* Current time */ + + + /* + * Don't load the cache if the remote protocols are disabled... + */ + + if (!Browsing) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdLoadRemoteCache: Not loading remote cache."); + return; + } + + /* + * Open the remote.cache file... + */ + + snprintf(line, sizeof(line), "%s/remote.cache", CacheDir); + if ((fp = cupsFileOpen(line, "r")) == NULL) + return; + + /* + * Read printer configurations until we hit EOF... + */ + + linenum = 0; + p = NULL; + now = time(NULL); + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Decode the directive... + */ + + if (!strcasecmp(line, " or + */ + + if (p == NULL && value) + { + /* + * Add the printer and a base file type... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdLoadRemoteCache: Loading printer %s...", value); + + if ((p = cupsdFindDest(value)) != NULL) + { + if (p->type & CUPS_PRINTER_CLASS) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Cached remote printer \"%s\" conflicts with " + "existing class!", + value); + p = NULL; + continue; + } + } + else + p = cupsdAddPrinter(value); + + p->accepting = 1; + p->state = IPP_PRINTER_IDLE; + p->type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED; + p->browse_time = now; + p->browse_expire = now + BrowseTimeout; + + /* + * Set the default printer as needed... + */ + + if (!strcasecmp(line, " or + */ + + if (p == NULL && value) + { + /* + * Add the printer and a base file type... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdLoadRemoteCache: Loading class %s...", value); + + if ((p = cupsdFindDest(value)) != NULL) + p->type = CUPS_PRINTER_CLASS; + else + p = cupsdAddClass(value); + + p->accepting = 1; + p->state = IPP_PRINTER_IDLE; + p->type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED; + p->browse_time = now; + p->browse_expire = now + BrowseTimeout; + + /* + * Set the default printer as needed... + */ + + if (!strcasecmp(line, "") || + !strcasecmp(line, "")) + { + if (p != NULL) + { + /* + * Close out the current printer... + */ + + cupsdSetPrinterAttrs(p); + + p = NULL; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!p) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "Info")) + { + if (value) + cupsdSetString(&p->info, value); + } + else if (!strcasecmp(line, "MakeModel")) + { + if (value) + cupsdSetString(&p->make_model, value); + } + else if (!strcasecmp(line, "Location")) + { + if (value) + cupsdSetString(&p->location, value); + } + else if (!strcasecmp(line, "DeviceURI")) + { + if (value) + { + httpSeparateURI(HTTP_URI_CODING_ALL, value, scheme, sizeof(scheme), + username, sizeof(username), host, sizeof(host), &port, + resource, sizeof(resource)); + + cupsdSetString(&p->hostname, host); + cupsdSetString(&p->uri, value); + cupsdSetDeviceURI(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "Option") && value) + { + /* + * Option name value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + p->num_options = cupsAddOption(value, valueptr, p->num_options, + &(p->options)); + } + } + else if (!strcasecmp(line, "Reason")) + { + if (value) + { + for (i = 0 ; i < p->num_reasons; i ++) + if (!strcmp(value, p->reasons[i])) + break; + + if (i >= p->num_reasons && + p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) + { + p->reasons[p->num_reasons] = _cupsStrAlloc(value); + p->num_reasons ++; + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "State")) + { + /* + * Set the initial queue state... + */ + + if (value && !strcasecmp(value, "idle")) + p->state = IPP_PRINTER_IDLE; + else if (value && !strcasecmp(value, "stopped")) + { + p->state = IPP_PRINTER_STOPPED; + cupsdSetPrinterReasons(p, "+paused"); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "StateMessage")) + { + /* + * Set the initial queue state message... + */ + + if (value) + strlcpy(p->state_message, value, sizeof(p->state_message)); + } + else if (!strcasecmp(line, "Accepting")) + { + /* + * Set the initial accepting state... + */ + + if (value && + (!strcasecmp(value, "yes") || + !strcasecmp(value, "on") || + !strcasecmp(value, "true"))) + p->accepting = 1; + else if (value && + (!strcasecmp(value, "no") || + !strcasecmp(value, "off") || + !strcasecmp(value, "false"))) + p->accepting = 0; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "Type")) + { + if (value) + p->type = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "BrowseTime")) + { + if (value) + { + time_t t = atoi(value); + + if (t > p->browse_expire) + p->browse_expire = t; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "JobSheets")) + { + /* + * Set the initial job sheets... + */ + + if (value) + { + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (*valueptr) + *valueptr++ = '\0'; + + cupsdSetString(&p->job_sheets[0], value); + + while (isspace(*valueptr & 255)) + valueptr ++; + + if (*valueptr) + { + for (value = valueptr; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (*valueptr) + *valueptr = '\0'; + + cupsdSetString(&p->job_sheets[1], value); + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "AllowUser")) + { + if (value) + { + p->deny_users = 0; + cupsdAddPrinterUser(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else if (!strcasecmp(line, "DenyUser")) + { + if (value) + { + p->deny_users = 1; + cupsdAddPrinterUser(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of remote.cache.", linenum); + } + else + { + /* + * Something else we don't understand... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown configuration directive %s on line %d of remote.cache.", + line, linenum); + } + } + + cupsFileClose(fp); + + /* + * Do auto-classing if needed... + */ + + process_implicit_classes(); +} + + +/* + * 'cupsdRegisterPrinter()' - Start sending broadcast information for a + * printer or update the broadcast contents. + */ + +void +cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdRegisterPrinter(p=%p(%s))", p, + p->name); + + if (!Browsing || !BrowseLocalProtocols || + (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_SCANNER))) + return; + +#ifdef HAVE_LIBSLP +/* if (BrowseLocalProtocols & BROWSE_SLP) + slpRegisterPrinter(p); */ +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_DNSSD + if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef) + dnssdRegisterPrinter(p); +#endif /* HAVE_DNSSD */ +} + + +/* + * 'cupsdRestartPolling()' - Restart polling servers as needed. + */ + +void +cupsdRestartPolling(void) +{ + int i; /* Looping var */ + cupsd_dirsvc_poll_t *pollp; /* Current polling server */ + + + for (i = 0, pollp = Polled; i < NumPolled; i ++, pollp ++) + if (pollp->pid) + kill(pollp->pid, SIGHUP); +} + + +/* + * 'cupsdSaveRemoteCache()' - Save the remote printer cache. + */ + +void +cupsdSaveRemoteCache(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* printers.conf file */ + char temp[1024], /* Temporary string */ + value[2048]; /* Value string */ + cupsd_printer_t *printer; /* Current printer class */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + cups_option_t *option; /* Current option */ + + + /* + * Create the remote.cache file... + */ + + snprintf(temp, sizeof(temp), "%s/remote.cache", CacheDir); + + if ((fp = cupsFileOpen(temp, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to save remote.cache - %s", strerror(errno)); + return; + } + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "Saving remote.cache..."); + + /* + * Restrict access to the file... + */ + + fchown(cupsFileNumber(fp), getuid(), Group); + fchmod(cupsFileNumber(fp), ConfigFilePerm); + + /* + * Write a small header to the file... + */ + + curtime = time(NULL); + curdate = localtime(&curtime); + strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate); + + cupsFilePuts(fp, "# Remote cache file for " CUPS_SVERSION "\n"); + cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp); + + /* + * Write each local printer known to the system... + */ + + for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers); + printer; + printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * Skip local destinations... + */ + + if (!(printer->type & CUPS_PRINTER_DISCOVERED)) + continue; + + /* + * Write printers as needed... + */ + + if (printer == DefaultPrinter) + cupsFilePuts(fp, "type & CUPS_PRINTER_CLASS) + cupsFilePrintf(fp, "Class %s>\n", printer->name); + else + cupsFilePrintf(fp, "Printer %s>\n", printer->name); + + cupsFilePrintf(fp, "BrowseTime %d\n", (int)printer->browse_expire); + + if (printer->info) + cupsFilePutConf(fp, "Info", printer->info); + + if (printer->location) + cupsFilePutConf(fp, "Location", printer->location); + + if (printer->make_model) + cupsFilePutConf(fp, "MakeModel", printer->make_model); + + cupsFilePutConf(fp, "DeviceURI", printer->device_uri); + + if (printer->state == IPP_PRINTER_STOPPED) + cupsFilePuts(fp, "State Stopped\n"); + else + cupsFilePuts(fp, "State Idle\n"); + + for (i = 0; i < printer->num_reasons; i ++) + cupsFilePutConf(fp, "Reason", printer->reasons[i]); + + cupsFilePrintf(fp, "Type %d\n", printer->type); + + if (printer->accepting) + cupsFilePuts(fp, "Accepting Yes\n"); + else + cupsFilePuts(fp, "Accepting No\n"); + + snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0], + printer->job_sheets[1]); + cupsFilePutConf(fp, "JobSheets", value); + + for (i = 0; i < printer->num_users; i ++) + cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", + printer->users[i]); + + for (i = printer->num_options, option = printer->options; + i > 0; + i --, option ++) + { + snprintf(value, sizeof(value), "%s %s", option->name, option->value); + cupsFilePutConf(fp, "Option", value); + } + + if (printer->type & CUPS_PRINTER_CLASS) + cupsFilePuts(fp, "\n"); + else + cupsFilePuts(fp, "\n"); + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdSendBrowseList()' - Send new browsing information as necessary. + */ + +void +cupsdSendBrowseList(void) +{ + int count; /* Number of dests to update */ + cupsd_printer_t *p; /* Current printer */ + time_t ut, /* Minimum update time */ + to; /* Timeout time */ + + + if (!Browsing || !Printers) + return; + + /* + * Compute the update and timeout times... + */ + + to = time(NULL); + ut = to - BrowseInterval; + + /* + * Figure out how many printers need an update... + */ + + if (BrowseInterval > 0 && BrowseLocalProtocols) + { + int max_count; /* Maximum number to update */ + + + /* + * Throttle the number of printers we'll be updating this time + * around based on the number of queues that need updating and + * the maximum number of queues to update each second... + */ + + max_count = 2 * cupsArrayCount(Printers) / BrowseInterval + 1; + + for (count = 0, p = (cupsd_printer_t *)cupsArrayFirst(Printers); + count < max_count && p != NULL; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_SCANNER)) && + p->shared && p->browse_time < ut) + count ++; + + /* + * Loop through all of the printers and send local updates as needed... + */ + + if (BrowseNext) + p = (cupsd_printer_t *)cupsArrayFind(Printers, BrowseNext); + else + p = (cupsd_printer_t *)cupsArrayFirst(Printers); + + for (; + count > 0; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * Check for wraparound... + */ + + if (!p) + p = (cupsd_printer_t *)cupsArrayFirst(Printers); + + if (!p) + break; + else if ((p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_SCANNER)) || + !p->shared) + continue; + else if (p->browse_time < ut) + { + /* + * Need to send an update... + */ + + count --; + + p->browse_time = time(NULL); + + if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0) + send_cups_browse(p); + +#ifdef HAVE_LIBSLP + if (BrowseLocalProtocols & BROWSE_SLP) + send_slp_browse(p); +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if (BrowseLocalProtocols & BROWSE_LDAP) + send_ldap_browse(p); +#endif /* HAVE_LDAP */ + } + } + + /* + * Save where we left off so that all printers get updated... + */ + + BrowseNext = p; + } + + /* + * Loop through all of the printers and timeout old printers as needed... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * If this is a remote queue, see if it needs to be timed out... + */ + + if ((p->type & CUPS_PRINTER_DISCOVERED) && + !(p->type & CUPS_PRINTER_IMPLICIT) && + p->browse_expire < to) + { + cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL, + "%s \'%s\' deleted by directory services (timeout).", + (p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer", + p->name); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Remote destination \"%s\" has timed out; " + "deleting it...", + p->name); + + cupsArraySave(Printers); + cupsdDeletePrinter(p, 1); + cupsArrayRestore(Printers); + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE); + } + } +} + + +#ifdef HAVE_LDAP_REBIND_PROC +# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +/* + * 'ldap_rebind_proc()' - Callback function for LDAP rebind + */ + +static int /* O - Result code */ +ldap_rebind_proc( + LDAP *RebindLDAPHandle, /* I - LDAP handle */ + LDAP_CONST char *refsp, /* I - ??? */ + ber_tag_t request, /* I - ??? */ + ber_int_t msgid, /* I - ??? */ + void *params) /* I - ??? */ +{ + int rc; /* Result code */ +# if LDAP_API_VERSION > 3000 + struct berval bval; /* Bind value */ +# endif /* LDAP_API_VERSION > 3000 */ + + /* + * Bind to new LDAP server... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_rebind_proc: Rebind to %s", refsp); + +# if LDAP_API_VERSION > 3000 + bval.bv_val = BrowseLDAPPassword; + bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword); + + rc = ldap_sasl_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, + &bval, NULL, NULL, NULL); +# else + rc = ldap_bind_s(RebindLDAPHandle, BrowseLDAPBindDN, BrowseLDAPPassword, + LDAP_AUTH_SIMPLE); +# endif /* LDAP_API_VERSION > 3000 */ + + return (rc); +} + + +# else /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */ +/* + * 'ldap_rebind_proc()' - Callback function for LDAP rebind + */ + +static int /* O - Result code */ +ldap_rebind_proc( + LDAP *RebindLDAPHandle, /* I - LDAP handle */ + char **dnp, /* I - ??? */ + char **passwdp, /* I - ??? */ + int *authmethodp, /* I - ??? */ + int freeit, /* I - ??? */ + void *arg) /* I - ??? */ +{ + switch (freeit) + { + case 1: + /* + * Free current values... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_rebind_proc: Free values..."); + + if (dnp && *dnp) + free(*dnp); + + if (passwdp && *passwdp) + free(*passwdp); + break; + + case 0: + /* + * Return credentials for LDAP referal... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "ldap_rebind_proc: Return necessary values..."); + + *dnp = strdup(BrowseLDAPBindDN); + *passwdp = strdup(BrowseLDAPPassword); + *authmethodp = LDAP_AUTH_SIMPLE; + break; + + default: + /* + * Should never happen... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP rebind has been called with wrong freeit value!"); + break; + } + + return (LDAP_SUCCESS); +} +# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */ +#endif /* HAVE_LDAP_REBIND_PROC */ + + +#ifdef HAVE_LDAP +/* + * 'ldap_connect()' - Start new LDAP connection + */ + +static LDAP * /* O - LDAP handle */ +ldap_connect(void) +{ + int rc; /* LDAP API status */ + int version = 3; /* LDAP version */ + struct berval bv = {0, ""}; /* SASL bind value */ + LDAP *TempBrowseLDAPHandle=NULL; + /* Temporary LDAP Handle */ +# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) + int ldap_ssl = 0; /* LDAP SSL indicator */ + int ssl_err = 0; /* LDAP SSL error value */ +# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */ + + +# ifdef HAVE_OPENLDAP +# ifdef HAVE_LDAP_SSL + /* + * Set the certificate file to use for encrypted LDAP sessions... + */ + + if (BrowseLDAPCACertFile) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "ldap_connect: Setting CA certificate file \"%s\"", + BrowseLDAPCACertFile); + + if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, + (void *)BrowseLDAPCACertFile)) != LDAP_SUCCESS) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to set CA certificate file for LDAP " + "connections: %d - %s", rc, ldap_err2string(rc)); + } +# endif /* HAVE_LDAP_SSL */ + + /* + * Initialize OPENLDAP connection... + * LDAP stuff currently only supports ldapi EXTERNAL SASL binds... + */ + + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) + rc = ldap_initialize(&TempBrowseLDAPHandle, "ldapi:///"); + else + rc = ldap_initialize(&TempBrowseLDAPHandle, BrowseLDAPServer); + +# else /* HAVE_OPENLDAP */ + + int ldap_port = 0; /* LDAP port */ + char ldap_protocol[11], /* LDAP protocol */ + ldap_host[255]; /* LDAP host */ + + /* + * Split LDAP URI into its components... + */ + + if (!BrowseLDAPServer) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "BrowseLDAPServer not configured!"); + cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!"); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + return (NULL); + } + + sscanf(BrowseLDAPServer, "%10[^:]://%254[^:/]:%d", ldap_protocol, ldap_host, + &ldap_port); + + if (!strcmp(ldap_protocol, "ldap")) + ldap_ssl = 0; + else if (!strcmp(ldap_protocol, "ldaps")) + ldap_ssl = 1; + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unrecognized LDAP protocol (%s)!", + ldap_protocol); + cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!"); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + return (NULL); + } + + if (ldap_port == 0) + { + if (ldap_ssl) + ldap_port = LDAPS_PORT; + else + ldap_port = LDAP_PORT; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, "ldap_connect: PROT:%s HOST:%s PORT:%d", + ldap_protocol, ldap_host, ldap_port); + + /* + * Initialize LDAP connection... + */ + + if (!ldap_ssl) + { + if ((TempBrowseLDAPHandle = ldap_init(ldap_host, ldap_port)) == NULL) + rc = LDAP_OPERATIONS_ERROR; + else + rc = LDAP_SUCCESS; + +# ifdef HAVE_LDAP_SSL + } + else + { + /* + * Initialize SSL LDAP connection... + */ + + if (BrowseLDAPCACertFile) + { + rc = ldapssl_client_init(BrowseLDAPCACertFile, (void *)NULL); + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Failed to initialize LDAP SSL client!"); + rc = LDAP_OPERATIONS_ERROR; + } + else + { + if ((TempBrowseLDAPHandle = ldapssl_init(ldap_host, ldap_port, + 1)) == NULL) + rc = LDAP_OPERATIONS_ERROR; + else + rc = LDAP_SUCCESS; + } + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP SSL certificate file/database not configured!"); + rc = LDAP_OPERATIONS_ERROR; + } + +# else /* HAVE_LDAP_SSL */ + + /* + * Return error, because client libraries doesn't support SSL + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP client libraries do not support SSL"); + rc = LDAP_OPERATIONS_ERROR; + +# endif /* HAVE_LDAP_SSL */ + } +# endif /* HAVE_OPENLDAP */ + + /* + * Check return code from LDAP initialize... + */ + + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize LDAP!"); + + if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) + cupsdLogMessage(CUPSD_LOG_ERROR, "Temporarily disabling LDAP browsing..."); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!"); + + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + } + + ldap_disconnect(TempBrowseLDAPHandle); + + return (NULL); + } + + /* + * Upgrade LDAP version... + */ + + if (ldap_set_option(TempBrowseLDAPHandle, LDAP_OPT_PROTOCOL_VERSION, + (const void *)&version) != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set LDAP protocol version %d!", + version); + cupsdLogMessage(CUPSD_LOG_ERROR, "Disabling LDAP browsing!"); + + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + ldap_disconnect(TempBrowseLDAPHandle); + + return (NULL); + } + + /* + * Register LDAP rebind procedure... + */ + +# ifdef HAVE_LDAP_REBIND_PROC +# if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) + + rc = ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, + (void *)NULL); + if (rc != LDAP_SUCCESS) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Setting LDAP rebind function failed with status %d: %s", + rc, ldap_err2string(rc)); + +# else + + ldap_set_rebind_proc(TempBrowseLDAPHandle, &ldap_rebind_proc, (void *)NULL); + +# endif /* defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) */ +# endif /* HAVE_LDAP_REBIND_PROC */ + + /* + * Start LDAP bind... + */ + +# if LDAP_API_VERSION > 3000 + struct berval bval; + bval.bv_val = BrowseLDAPPassword; + bval.bv_len = (BrowseLDAPPassword == NULL) ? 0 : strlen(BrowseLDAPPassword); + + if (!BrowseLDAPServer || !strcasecmp(BrowseLDAPServer, "localhost")) + rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, NULL, "EXTERNAL", &bv, NULL, + NULL, NULL); + else + rc = ldap_sasl_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, LDAP_SASL_SIMPLE, &bval, NULL, NULL, NULL); + +# else + rc = ldap_bind_s(TempBrowseLDAPHandle, BrowseLDAPBindDN, + BrowseLDAPPassword, LDAP_AUTH_SIMPLE); +# endif /* LDAP_API_VERSION > 3000 */ + + if (rc != LDAP_SUCCESS) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP bind failed with error %d: %s", + rc, ldap_err2string(rc)); + +# if defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) + if (ldap_ssl && (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)) + { + ssl_err = PORT_GetError(); + if (ssl_err != 0) + cupsdLogMessage(CUPSD_LOG_ERROR, "LDAP SSL error %d: %s", ssl_err, + ldapssl_err2string(ssl_err)); + } +# endif /* defined(HAVE_LDAP_SSL) && defined (HAVE_MOZILLA_LDAP) */ + + ldap_disconnect(TempBrowseLDAPHandle); + + return (NULL); + } + + cupsdLogMessage(CUPSD_LOG_INFO, "LDAP connection established"); + + return (TempBrowseLDAPHandle); +} + + +/* + * 'ldap_reconnect()' - Reconnect to LDAP Server + */ + +static LDAP * /* O - New LDAP handle */ +ldap_reconnect(void) +{ + LDAP *TempBrowseLDAPHandle = NULL; /* Temp Handle to LDAP server */ + + + /* + * Get a new LDAP Handle and replace the global Handle + * if the new connection was successful. + */ + + cupsdLogMessage(CUPSD_LOG_INFO, "Try LDAP reconnect..."); + + TempBrowseLDAPHandle = ldap_connect(); + + if (TempBrowseLDAPHandle != NULL) + { + if (BrowseLDAPHandle != NULL) + ldap_disconnect(BrowseLDAPHandle); + + BrowseLDAPHandle = TempBrowseLDAPHandle; + } + + return (BrowseLDAPHandle); +} + + +/* + * 'ldap_disconnect()' - Disconnect from LDAP Server + */ + +static void +ldap_disconnect(LDAP *ld) /* I - LDAP handle */ +{ + int rc; /* Return code */ + + + /* + * Close LDAP handle... + */ + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + rc = ldap_unbind_ext_s(ld, NULL, NULL); +# else + rc = ldap_unbind_s(ld); +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + + if (rc != LDAP_SUCCESS) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unbind from LDAP server failed with status %d: %s", + rc, ldap_err2string(rc)); +} +#endif /* HAVE_LDAP */ + + +/* + * 'cupsdStartBrowsing()' - Start sending and receiving broadcast information. + */ + +void +cupsdStartBrowsing(void) +{ + int val; /* Socket option value */ + struct sockaddr_in addr; /* Broadcast address */ + cupsd_printer_t *p; /* Current printer */ + + + BrowseNext = NULL; + + if (!Browsing || !(BrowseLocalProtocols | BrowseRemoteProtocols)) + return; + + if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS) + { + if (BrowseSocket < 0) + { + /* + * Create the broadcast socket... + */ + + if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create broadcast socket - %s.", + strerror(errno)); + BrowseLocalProtocols &= ~BROWSE_CUPS; + BrowseRemoteProtocols &= ~BROWSE_CUPS; + + if (FatalErrors & CUPSD_FATAL_BROWSE) + cupsdEndProcess(getpid(), 0); + } + } + + if (BrowseSocket >= 0) + { + /* + * 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))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to bind broadcast socket - %s.", + strerror(errno)); + +#ifdef WIN32 + closesocket(BrowseSocket); +#else + close(BrowseSocket); +#endif /* WIN32 */ + + BrowseSocket = -1; + BrowseLocalProtocols &= ~BROWSE_CUPS; + BrowseRemoteProtocols &= ~BROWSE_CUPS; + + if (FatalErrors & CUPSD_FATAL_BROWSE) + cupsdEndProcess(getpid(), 0); + } + } + + if (BrowseSocket >= 0) + { + /* + * Set the "broadcast" flag... + */ + + val = 1; + if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set broadcast mode - %s.", + strerror(errno)); + +#ifdef WIN32 + closesocket(BrowseSocket); +#else + close(BrowseSocket); +#endif /* WIN32 */ + + BrowseSocket = -1; + BrowseLocalProtocols &= ~BROWSE_CUPS; + BrowseRemoteProtocols &= ~BROWSE_CUPS; + + if (FatalErrors & CUPSD_FATAL_BROWSE) + cupsdEndProcess(getpid(), 0); + } + } + + if (BrowseSocket >= 0) + { + /* + * Close the socket on exec... + */ + + fcntl(BrowseSocket, F_SETFD, fcntl(BrowseSocket, F_GETFD) | FD_CLOEXEC); + + /* + * Finally, add the socket to the input selection set as needed... + */ + + if (BrowseRemoteProtocols & BROWSE_CUPS) + { + /* + * We only listen if we want remote printers... + */ + + cupsdAddSelect(BrowseSocket, (cupsd_selfunc_t)update_cups_browse, + NULL, NULL); + } + } + } + else + BrowseSocket = -1; + +#ifdef HAVE_DNSSD + if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_DNSSD) + { + DNSServiceErrorType error; /* Error from service creation */ + cupsd_listener_t *lis; /* Current listening socket */ + + + /* + * First create a "master" connection for all registrations... + */ + + if ((error = DNSServiceCreateConnection(&DNSSDRef)) + != kDNSServiceErr_NoError) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create master DNS-SD reference: %d", error); + + if (FatalErrors & CUPSD_FATAL_BROWSE) + cupsdEndProcess(getpid(), 0); + } + else + { + /* + * Add the master connection to the select list... + */ + + int fd = DNSServiceRefSockFD(DNSSDRef); + + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); + + cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL); + + /* + * Then get the port we use for registrations. If we are not listening + * on any non-local ports, there is no sense sharing local printers via + * Bonjour... + */ + + DNSSDPort = 0; + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + { + if (httpAddrLocalhost(&(lis->address))) + continue; + + if (lis->address.addr.sa_family == AF_INET) + { + DNSSDPort = ntohs(lis->address.ipv4.sin_port); + break; + } + else if (lis->address.addr.sa_family == AF_INET6) + { + DNSSDPort = ntohs(lis->address.ipv6.sin6_port); + break; + } + } + + /* + * Create an array to track the printers we share... + */ + + if (BrowseRemoteProtocols & BROWSE_DNSSD) + DNSSDPrinters = cupsArrayNew((cups_array_func_t)dnssdComparePrinters, + NULL); + + /* + * Set the computer name and register the web interface... + */ + + cupsdUpdateDNSSDName(); + } + } +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_LIBSLP + if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) + { + /* + * Open SLP handle... + */ + + if (SLPOpen("en", SLP_FALSE, &BrowseSLPHandle) != SLP_OK) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open an SLP handle; disabling SLP browsing!"); + BrowseLocalProtocols &= ~BROWSE_SLP; + BrowseRemoteProtocols &= ~BROWSE_SLP; + BrowseSLPHandle = NULL; + + if (FatalErrors & CUPSD_FATAL_BROWSE) + cupsdEndProcess(getpid(), 0); + } + + BrowseSLPRefresh = 0; + } + else + BrowseSLPHandle = NULL; +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if ((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) + { + if (!BrowseLDAPDN) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Need to set BrowseLDAPDN to use LDAP browsing!"); + BrowseLocalProtocols &= ~BROWSE_LDAP; + BrowseRemoteProtocols &= ~BROWSE_LDAP; + + if (FatalErrors & CUPSD_FATAL_BROWSE) + cupsdEndProcess(getpid(), 0); + } + else + { + /* + * Open LDAP handle... + */ + + if ((BrowseLDAPHandle = ldap_connect()) == NULL && + (FatalErrors & CUPSD_FATAL_BROWSE)) + cupsdEndProcess(getpid(), 0); + } + + BrowseLDAPRefresh = 0; + } +#endif /* HAVE_LDAP */ + + /* + * Enable LPD and SMB printer sharing as needed through external programs... + */ + + if (BrowseLocalProtocols & BROWSE_LPD) + update_lpd(1); + + if (BrowseLocalProtocols & BROWSE_SMB) + update_smb(1); + + /* + * Register the individual printers + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_SCANNER))) + cupsdRegisterPrinter(p); +} + + +/* + * 'cupsdStartPolling()' - Start polling servers as needed. + */ + +void +cupsdStartPolling(void) +{ + int i; /* Looping var */ + cupsd_dirsvc_poll_t *pollp; /* Current polling server */ + char polld[1024]; /* Poll daemon path */ + char sport[255]; /* Server port */ + char bport[255]; /* Browser port */ + char interval[255]; /* Poll interval */ + int statusfds[2]; /* Status pipe */ + char *argv[6]; /* Arguments */ + char *envp[100]; /* Environment */ + + + /* + * Don't do anything if we aren't polling... + */ + + if (NumPolled == 0 || BrowseSocket < 0) + { + PollPipe = -1; + PollStatusBuffer = NULL; + return; + } + + /* + * Setup string arguments for polld, port and interval options. + */ + + snprintf(polld, sizeof(polld), "%s/daemon/cups-polld", ServerBin); + + sprintf(bport, "%d", BrowsePort); + + if (BrowseInterval) + sprintf(interval, "%d", BrowseInterval); + else + strcpy(interval, "30"); + + argv[0] = "cups-polld"; + argv[2] = sport; + argv[3] = interval; + argv[4] = bport; + argv[5] = NULL; + + cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + + /* + * Create a pipe that receives the status messages from each + * polling daemon... + */ + + if (cupsdOpenPipe(statusfds)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create polling status pipes - %s.", + strerror(errno)); + PollPipe = -1; + PollStatusBuffer = NULL; + return; + } + + PollPipe = statusfds[0]; + PollStatusBuffer = cupsdStatBufNew(PollPipe, "[Poll]"); + + /* + * Run each polling daemon, redirecting stderr to the polling pipe... + */ + + for (i = 0, pollp = Polled; i < NumPolled; i ++, pollp ++) + { + sprintf(sport, "%d", pollp->port); + + argv[1] = pollp->hostname; + + if (cupsdStartProcess(polld, argv, envp, -1, -1, statusfds[1], -1, -1, + 0, DefaultProfile, NULL, &(pollp->pid)) < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdStartPolling: Unable to fork polling daemon - %s", + strerror(errno)); + pollp->pid = 0; + break; + } + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdStartPolling: Started polling daemon for %s:%d, pid = %d", + pollp->hostname, pollp->port, pollp->pid); + } + + close(statusfds[1]); + + /* + * Finally, add the pipe to the input selection set... + */ + + cupsdAddSelect(PollPipe, (cupsd_selfunc_t)update_polling, NULL, NULL); +} + + +/* + * 'cupsdStopBrowsing()' - Stop sending and receiving broadcast information. + */ + +void +cupsdStopBrowsing(void) +{ + cupsd_printer_t *p; /* Current printer */ + + + if (!Browsing || !(BrowseLocalProtocols | BrowseRemoteProtocols)) + return; + + /* + * De-register the individual printers + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_SCANNER))) + cupsdDeregisterPrinter(p, 1); + + /* + * Shut down browsing sockets... + */ + + if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_CUPS) && + BrowseSocket >= 0) + { + /* + * Close the socket and remove it from the input selection set. + */ + +#ifdef WIN32 + closesocket(BrowseSocket); +#else + close(BrowseSocket); +#endif /* WIN32 */ + + cupsdRemoveSelect(BrowseSocket); + BrowseSocket = -1; + } + +#ifdef HAVE_DNSSD + if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef) + dnssdStop(); +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_LIBSLP + if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) && + BrowseSLPHandle) + { + /* + * Close SLP handle... + */ + + SLPClose(BrowseSLPHandle); + BrowseSLPHandle = NULL; + } +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_LDAP) && + BrowseLDAPHandle) + { + ldap_dereg_ou(ServerName, BrowseLDAPDN); + ldap_disconnect(BrowseLDAPHandle); + BrowseLDAPHandle = NULL; + } +#endif /* HAVE_OPENLDAP */ + + /* + * Disable LPD and SMB printer sharing as needed through external programs... + */ + + if (BrowseLocalProtocols & BROWSE_LPD) + update_lpd(0); + + if (BrowseLocalProtocols & BROWSE_SMB) + update_smb(0); +} + + +/* + * 'cupsdStopPolling()' - Stop polling servers as needed. + */ + +void +cupsdStopPolling(void) +{ + int i; /* Looping var */ + cupsd_dirsvc_poll_t *pollp; /* Current polling server */ + + + if (PollPipe >= 0) + { + cupsdStatBufDelete(PollStatusBuffer); + close(PollPipe); + + cupsdRemoveSelect(PollPipe); + + PollPipe = -1; + PollStatusBuffer = NULL; + } + + for (i = 0, pollp = Polled; i < NumPolled; i ++, pollp ++) + if (pollp->pid) + cupsdEndProcess(pollp->pid, 0); +} + + +#ifdef HAVE_DNSSD +/* + * 'cupsdUpdateDNSSDName()' - Update the computer name we use for browsing... + */ + +void +cupsdUpdateDNSSDName(void) +{ + DNSServiceErrorType error; /* Error from service creation */ + char webif[1024]; /* Web interface share name */ +#ifdef HAVE_COREFOUNDATION_H + SCDynamicStoreRef sc; /* Context for dynamic store */ + CFDictionaryRef btmm; /* Back-to-My-Mac domains */ + CFStringEncoding nameEncoding; /* Encoding of computer name */ + CFStringRef nameRef; /* Host name CFString */ + char nameBuffer[1024]; /* C-string buffer */ +#endif /* HAVE_COREFOUNDATION_H */ + + + /* + * Only share the web interface and printers when non-local listening is + * enabled... + */ + + + if (!DNSSDPort) + return; + + /* + * Get the computer name as a c-string... + */ + +#ifdef HAVE_COREFOUNDATION_H + sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL); + + if (sc) + { + /* + * Get the computer name from the dynamic store... + */ + + cupsdClearString(&DNSSDComputerName); + + if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL) + { + if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer), + kCFStringEncodingUTF8)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Dynamic store computer name is \"%s\".", nameBuffer); + cupsdSetString(&DNSSDComputerName, nameBuffer); + } + + CFRelease(nameRef); + } + + if (!DNSSDComputerName) + { + /* + * Use the ServerName instead... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Using ServerName \"%s\" as computer name.", ServerName); + cupsdSetString(&DNSSDComputerName, ServerName); + } + + /* + * Get the local hostname from the dynamic store... + */ + + cupsdClearString(&DNSSDHostName); + + if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL) + { + if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer), + kCFStringEncodingUTF8)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Dynamic store host name is \"%s\".", nameBuffer); + cupsdSetString(&DNSSDHostName, nameBuffer); + } + + CFRelease(nameRef); + } + + if (!DNSSDHostName) + { + /* + * Use the ServerName instead... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Using ServerName \"%s\" as host name.", ServerName); + cupsdSetString(&DNSSDHostName, ServerName); + } + + /* + * Get any Back-to-My-Mac domains and add them as aliases... + */ + + cupsdFreeAliases(DNSSDAlias); + DNSSDAlias = NULL; + + btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac")); + if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID()) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.", + (int)CFDictionaryGetCount(btmm)); + CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL); + } + else if (btmm) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad Back to My Mac data in dynamic store!"); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add."); + + if (btmm) + CFRelease(btmm); + + CFRelease(sc); + } + else +#endif /* HAVE_COREFOUNDATION_H */ + { + cupsdSetString(&DNSSDComputerName, ServerName); + cupsdSetString(&DNSSDHostName, ServerName); + } + + /* + * Then (re)register the web interface if enabled... + */ + + if (BrowseWebIF) + { + if (DNSSDComputerName) + snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName); + else + strlcpy(webif, "CUPS Web Interface", sizeof(webif)); + + if (WebIFRef) + DNSServiceRefDeallocate(WebIFRef); + + WebIFRef = DNSSDRef; + if ((error = DNSServiceRegister(&WebIFRef, + kDNSServiceFlagsShareConnection, + 0, webif, "_http._tcp", NULL, + NULL, htons(DNSSDPort), 7, + "\006path=/", dnssdRegisterCallback, + NULL)) != kDNSServiceErr_NoError) + cupsdLogMessage(CUPSD_LOG_ERROR, + "DNS-SD web interface registration failed: %d", error); + } +} +#endif /* HAVE_DNSSD */ + + +#ifdef HAVE_LDAP +/* + * 'cupsdUpdateLDAPBrowse()' - Scan for new printers via LDAP... + */ + +void +cupsdUpdateLDAPBrowse(void) +{ + char uri[HTTP_MAX_URI], /* Printer URI */ + host[HTTP_MAX_URI], /* Hostname */ + resource[HTTP_MAX_URI], /* Resource path */ + location[1024], /* Printer location */ + info[1024], /* Printer information */ + make_model[1024], /* Printer make and model */ + type_num[30]; /* Printer type number */ + int type; /* Printer type */ + int rc; /* LDAP status */ + int limit; /* Size limit */ + LDAPMessage *res, /* LDAP search results */ + *e; /* Current entry from search */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "UpdateLDAPBrowse: %s", ServerName); + + BrowseLDAPRefresh = time(NULL) + BrowseInterval; + + /* + * Reconnect if LDAP Handle is invalid... + */ + + if (! BrowseLDAPHandle) + { + ldap_reconnect(); + return; + } + + /* + * Search for cups printers in LDAP directory... + */ + + rc = ldap_search_rec(BrowseLDAPHandle, BrowseLDAPDN, LDAP_SCOPE_SUBTREE, + "(objectclass=cupsPrinter)", (char **)ldap_attrs, 0, &res); + + /* + * If ldap search was successfull then exit function + * and temporary disable LDAP updates... + */ + + if (rc != LDAP_SUCCESS) + { + if (BrowseLDAPUpdate && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) + { + BrowseLDAPUpdate = FALSE; + cupsdLogMessage(CUPSD_LOG_INFO, + "LDAP update temporary disabled"); + } + return; + } + + /* + * If LDAP updates were disabled, we will reenable them... + */ + + if (! BrowseLDAPUpdate) + { + BrowseLDAPUpdate = TRUE; + cupsdLogMessage(CUPSD_LOG_INFO, + "LDAP update enabled"); + } + + /* + * Count LDAP entries and return if no entry exist... + */ + + limit = ldap_count_entries(BrowseLDAPHandle, res); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "LDAP search returned %d entries", limit); + if (limit < 1) + { + ldap_freeres(res); + return; + } + + /* + * Loop through the available printers... + */ + + for (e = ldap_first_entry(BrowseLDAPHandle, res); + e; + e = ldap_next_entry(BrowseLDAPHandle, e)) + { + /* + * Get the required values from this entry... + */ + + if (ldap_getval_firststring(BrowseLDAPHandle, e, + "printerDescription", info, sizeof(info)) == -1) + continue; + + if (ldap_getval_firststring(BrowseLDAPHandle, e, + "printerLocation", location, sizeof(location)) == -1) + continue; + + if (ldap_getval_firststring(BrowseLDAPHandle, e, + "printerMakeAndModel", make_model, sizeof(make_model)) == -1) + continue; + + if (ldap_getval_firststring(BrowseLDAPHandle, e, + "printerType", type_num, sizeof(type_num)) == -1) + continue; + + type = atoi(type_num); + + if (ldap_getval_firststring(BrowseLDAPHandle, e, + "printerURI", uri, sizeof(uri)) == -1) + continue; + + /* + * Process the entry as browse data... + */ + + if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) + process_browse_data(uri, host, resource, type, IPP_PRINTER_IDLE, + location, info, make_model, 0, NULL); + + } + + ldap_freeres(res); +} +#endif /* HAVE_LDAP */ + + +#ifdef HAVE_LIBSLP +/* + * 'cupsdUpdateSLPBrowse()' - Get browsing information via SLP. + */ + +void +cupsdUpdateSLPBrowse(void) +{ + slpsrvurl_t *s, /* Temporary list of service URLs */ + *next; /* Next service in list */ + cupsd_printer_t p; /* Printer information */ + const char *uri; /* Pointer to printer URI */ + char host[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + + + /* + * Reset the refresh time... + */ + + BrowseSLPRefresh = time(NULL) + BrowseInterval; + + /* + * Poll for remote printers using SLP... + */ + + s = NULL; + + SLPFindSrvs(BrowseSLPHandle, SLP_CUPS_SRVTYPE, "", "", + slp_url_callback, &s); + + /* + * Loop through the list of available printers... + */ + + for (; s; s = next) + { + /* + * Save the "next" pointer... + */ + + next = s->next; + + /* + * Load a cupsd_printer_t structure with the SLP service attributes... + */ + + SLPFindAttrs(BrowseSLPHandle, s->url, "", "", slp_attr_callback, &p); + + /* + * Process this printer entry... + */ + + uri = s->url + SLP_CUPS_SRVLEN + 1; + + if (!strncmp(uri, "http://", 7) || !strncmp(uri, "ipp://", 6)) + { + /* + * Pull the URI apart to see if this is a local or remote printer... + */ + + if (!is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) + process_browse_data(uri, host, resource, p.type, IPP_PRINTER_IDLE, + p.location, p.info, p.make_model, 0, NULL); + } + + /* + * Free this listing... + */ + + cupsdClearString(&p.info); + cupsdClearString(&p.location); + cupsdClearString(&p.make_model); + + free(s); + } +} +#endif /* HAVE_LIBSLP */ + + +/* + * 'dequote()' - Remote quotes from a string. + */ + +static char * /* O - Dequoted string */ +dequote(char *d, /* I - Destination string */ + const char *s, /* I - Source string */ + int dlen) /* I - Destination length */ +{ + char *dptr; /* Pointer into destination */ + + + if (s) + { + for (dptr = d, dlen --; *s && dlen > 0; s ++) + if (*s != '\"') + { + *dptr++ = *s; + dlen --; + } + + *dptr = '\0'; + } + else + *d = '\0'; + + return (d); +} + + +#ifdef HAVE_DNSSD +# ifdef HAVE_COREFOUNDATION +/* + * 'dnssdAddAlias()' - Add a DNS-SD alias name. + */ + +static void +dnssdAddAlias(const void *key, /* I - Key */ + const void *value, /* I - Value (domain) */ + void *context) /* I - Unused */ +{ + char valueStr[1024], /* Domain string */ + hostname[1024]; /* Complete hostname */ + + + (void)context; + + if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() && + CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr), + kCFStringEncodingUTF8)) + { + snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDHostName, valueStr); + if (!DNSSDAlias) + DNSSDAlias = cupsArrayNew(NULL, NULL); + + cupsdAddAlias(DNSSDAlias, hostname); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s", + hostname); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad Back to My Mac domain in dynamic store!"); +} +# endif /* HAVE_COREFOUNDATION */ + + +/* + * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info. + */ + +static char * /* O - TXT record */ +dnssdBuildTxtRecord( + int *txt_len, /* O - TXT record length */ + cupsd_printer_t *p, /* I - Printer information */ + int for_lpd) /* I - 1 = LPD, 0 = IPP */ +{ + int i; /* Looping var */ + char adminurl_str[256], /* URL for th admin page */ + type_str[32], /* Type to string buffer */ + state_str[32], /* State to string buffer */ + rp_str[1024], /* Queue name string buffer */ + air_str[1024], /* auth-info-required string buffer */ + *keyvalue[32][2]; /* Table of key/value pairs */ + + + /* + * Load up the key value pairs... + */ + + i = 0; + + keyvalue[i ][0] = "txtvers"; + keyvalue[i++][1] = "1"; + + keyvalue[i ][0] = "qtotal"; + keyvalue[i++][1] = "1"; + + keyvalue[i ][0] = "rp"; + keyvalue[i++][1] = rp_str; + if (for_lpd) + strlcpy(rp_str, p->name, sizeof(rp_str)); + else + snprintf(rp_str, sizeof(rp_str), "%s/%s", + (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name); + + keyvalue[i ][0] = "ty"; + keyvalue[i++][1] = p->make_model ? p->make_model : "Unknown"; + + httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str), + "http", NULL, DNSSDHostName, DNSSDPort, "/%s/%s", + (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", + p->name); + keyvalue[i ][0] = "adminurl"; + keyvalue[i++][1] = adminurl_str; + + keyvalue[i ][0] = "note"; + keyvalue[i++][1] = p->location ? p->location : ""; + + keyvalue[i ][0] = "priority"; + keyvalue[i++][1] = for_lpd ? "100" : "0"; + + keyvalue[i ][0] = "product"; + keyvalue[i++][1] = p->product ? p->product : "Unknown"; + + snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE); + snprintf(state_str, sizeof(state_str), "%d", p->state); + + keyvalue[i ][0] = "printer-state"; + keyvalue[i++][1] = state_str; + + keyvalue[i ][0] = "printer-type"; + keyvalue[i++][1] = type_str; + + keyvalue[i ][0] = "Transparent"; + keyvalue[i++][1] = "T"; + + keyvalue[i ][0] = "Binary"; + keyvalue[i++][1] = "T"; + + keyvalue[i ][0] = "Fax"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_FAX) ? "T" : "F"; + + keyvalue[i ][0] = "Color"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F"; + + keyvalue[i ][0] = "Duplex"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F"; + + keyvalue[i ][0] = "Staple"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F"; + + keyvalue[i ][0] = "Copies"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F"; + + keyvalue[i ][0] = "Collate"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F"; + + keyvalue[i ][0] = "Punch"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F"; + + keyvalue[i ][0] = "Bind"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F"; + + keyvalue[i ][0] = "Sort"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F"; + + keyvalue[i ][0] = "Scan"; + keyvalue[i++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F"; + + keyvalue[i ][0] = "pdl"; + keyvalue[i++][1] = p->pdl ? p->pdl : "application/postscript"; + + if (get_auth_info_required(p, air_str, sizeof(air_str))) + { + keyvalue[i ][0] = "air"; + keyvalue[i++][1] = air_str; + } + + /* + * Then pack them into a proper txt record... + */ + + return (dnssdPackTxtRecord(txt_len, keyvalue, i)); +} + + +/* + * 'dnssdComparePrinters()' - Compare the registered names of two printers. + */ + +static int /* O - Result of comparison */ +dnssdComparePrinters(cupsd_printer_t *a,/* I - First printer */ + cupsd_printer_t *b)/* I - Second printer */ +{ + return (strcasecmp(a->reg_name, b->reg_name)); +} + + +/* + * 'dnssdDeregisterPrinter()' - Stop sending broadcast information for a + * printer. + */ + +static void +dnssdDeregisterPrinter( + cupsd_printer_t *p) /* I - Printer */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdDeregisterPrinter(%s)", p->name); + + /* + * Closing the socket deregisters the service + */ + + if (p->ipp_ref) + { + DNSServiceRefDeallocate(p->ipp_ref); + p->ipp_ref = NULL; + } + + if (p->ipp_txt) + { + /* + * p->ipp_txt is malloc'd, not _cupsStrAlloc'd... + */ + + free(p->ipp_txt); + p->ipp_txt = NULL; + } + + if (p->printer_ref) + { + DNSServiceRefDeallocate(p->printer_ref); + p->printer_ref = NULL; + } + + if (p->printer_txt) + { + /* + * p->printer_txt is malloc'd, not _cupsStrAlloc'd... + */ + + free(p->printer_txt); + p->printer_txt = NULL; + } + + /* + * Remove the printer from the array of DNS-SD printers, then clear the + * registered name... + */ + + cupsArrayRemove(DNSSDPrinters, p); + cupsdClearString(&p->reg_name); +} + + +/* + * 'dnssdPackTxtRecord()' - Pack an array of key/value pairs into the + * TXT record format. + */ + +static char * /* O - TXT record */ +dnssdPackTxtRecord(int *txt_len, /* O - TXT record length */ + char *keyvalue[][2], /* I - Table of key value pairs */ + int count) /* I - Items in table */ +{ + int i; /* Looping var */ + int length; /* Length of TXT record */ + int length2; /* Length of value */ + char *txtRecord; /* TXT record buffer */ + char *cursor; /* Looping pointer */ + + + /* + * Calculate the buffer size + */ + + if (count <= 0) + return (NULL); + + for (length = i = 0; i < count; i++) + length += 1 + strlen(keyvalue[i][0]) + + (keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0); + + /* + * Allocate and fill it + */ + + txtRecord = malloc(length); + if (txtRecord) + { + *txt_len = length; + + for (cursor = txtRecord, i = 0; i < count; i++) + { + /* + * Drop in the p-string style length byte followed by the data + */ + + length = strlen(keyvalue[i][0]); + length2 = keyvalue[i][1] ? 1 + strlen(keyvalue[i][1]) : 0; + + *cursor++ = (unsigned char)(length + length2); + + memcpy(cursor, keyvalue[i][0], length); + cursor += length; + + if (length2) + { + length2 --; + *cursor++ = '='; + memcpy(cursor, keyvalue[i][1], length2); + cursor += length2; + } + } + } + + return (txtRecord); +} + + +/* + * 'dnssdRegisterCallback()' - DNSServiceRegister callback. + */ + +static void +dnssdRegisterCallback( + DNSServiceRef sdRef, /* I - DNS Service reference */ + DNSServiceFlags flags, /* I - Reserved for future use */ + DNSServiceErrorType errorCode, /* I - Error code */ + const char *name, /* I - Service name */ + const char *regtype, /* I - Service type */ + const char *domain, /* I - Domain. ".local" for now */ + void *context) /* I - User-defined context */ +{ + cupsd_printer_t *p = (cupsd_printer_t *)context; + /* Current printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterCallback(%s, %s) for %s (%s)", + name, regtype, p ? p->name : "Web Interface", + p ? (p->reg_name ? p->reg_name : "(null)") : "NA"); + + if (errorCode) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "DNSServiceRegister failed with error %d", (int)errorCode); + return; + } + else if (p && (!p->reg_name || strcasecmp(name, p->reg_name))) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Using service name \"%s\" for \"%s\"", + name, p->name); + + cupsArrayRemove(DNSSDPrinters, p); + cupsdSetString(&p->reg_name, name); + cupsArrayAdd(DNSSDPrinters, p); + + LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED; + } +} + + +/* + * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer + * or update the broadcast contents. + */ + +static void +dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */ +{ + DNSServiceErrorType se; /* dnssd errors */ + char *ipp_txt, /* IPP TXT record buffer */ + *printer_txt, /* LPD TXT record buffer */ + name[1024], /* Service name */ + *nameptr; /* Pointer into name */ + int ipp_len, /* IPP TXT record length */ + printer_len; /* LPD TXT record length */ + const char *regtype; /* Registration type */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name, + !p->ipp_ref ? "new" : "update"); + + /* + * If per-printer sharing was just disabled make sure we're not + * registered before returning. + */ + + if (!p->shared) + { + dnssdDeregisterPrinter(p); + return; + } + + /* + * The registered name takes the form of " @ "... + */ + + if (p->info && strlen(p->info) > 0) + { + if (DNSSDComputerName) + snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName); + else + strlcpy(name, p->info, sizeof(name)); + } + else if (DNSSDComputerName) + snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName); + else + strlcpy(name, p->name, sizeof(name)); + + /* + * If an existing printer was renamed, unregister it and start over... + */ + + if (p->reg_name && strcmp(p->reg_name, name)) + dnssdDeregisterPrinter(p); + + if (!p->reg_name) + { + cupsdSetString(&p->reg_name, name); + cupsArrayAdd(DNSSDPrinters, p); + } + + /* + * Register IPP and (optionally) LPD... + */ + + ipp_len = 0; /* anti-compiler-warning-code */ + ipp_txt = dnssdBuildTxtRecord(&ipp_len, p, 0); + + if (p->ipp_ref && + (ipp_len != p->ipp_len || memcmp(ipp_txt, p->ipp_txt, ipp_len))) + { + /* + * Update the existing registration... + */ + + /* A TTL of 0 means use record's original value (Radar 3176248) */ + if ((se = DNSServiceUpdateRecord(p->ipp_ref, NULL, 0, ipp_len, ipp_txt, + 0)) == kDNSServiceErr_NoError) + { + if (p->ipp_txt) + free(p->ipp_txt); + + p->ipp_txt = ipp_txt; + p->ipp_len = ipp_len; + ipp_txt = NULL; + } + else + { + /* + * Failed to update record, lets close this reference and move on... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to update IPP DNS-SD record for %s - %d", p->name, + se); + + DNSServiceRefDeallocate(p->ipp_ref); + p->ipp_ref = NULL; + } + } + + if (!p->ipp_ref) + { + /* + * Initial registration. Use the _fax subtype for fax queues... + */ + + regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" : + "_ipp._tcp,_cups"; + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Registering DNS-SD printer %s with name \"%s\" and " + "type \"%s\"", p->name, name, regtype); + + /* + * Register the queue, dropping characters as needed until we succeed... + */ + + nameptr = name + strlen(name); + + do + { + p->ipp_ref = DNSSDRef; + if ((se = DNSServiceRegister(&p->ipp_ref, kDNSServiceFlagsShareConnection, + 0, name, regtype, NULL, NULL, + htons(DNSSDPort), ipp_len, ipp_txt, + dnssdRegisterCallback, + p)) == kDNSServiceErr_BadParam) + { + /* + * Name is too long, drop trailing characters, taking into account + * UTF-8 encoding... + */ + + nameptr --; + + while (nameptr > name && (*nameptr & 0xc0) == 0x80) + nameptr --; + + if (nameptr > name) + *nameptr = '\0'; + } + } + while (se == kDNSServiceErr_BadParam && nameptr > name); + + if (se == kDNSServiceErr_NoError) + { + p->ipp_txt = ipp_txt; + p->ipp_len = ipp_len; + ipp_txt = NULL; + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "DNS-SD IPP registration of \"%s\" failed: %d", + p->name, se); + } + + if (ipp_txt) + free(ipp_txt); + + if (BrowseLocalProtocols & BROWSE_LPD) + { + printer_len = 0; /* anti-compiler-warning-code */ + printer_txt = dnssdBuildTxtRecord(&printer_len, p, 1); + + if (p->printer_ref && + (printer_len != p->printer_len || + memcmp(printer_txt, p->printer_txt, printer_len))) + { + /* + * Update the existing registration... + */ + + /* A TTL of 0 means use record's original value (Radar 3176248) */ + if ((se = DNSServiceUpdateRecord(p->printer_ref, NULL, 0, printer_len, + printer_txt, + 0)) == kDNSServiceErr_NoError) + { + if (p->printer_txt) + free(p->printer_txt); + + p->printer_txt = printer_txt; + p->printer_len = printer_len; + printer_txt = NULL; + } + else + { + /* + * Failed to update record, lets close this reference and move on... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to update LPD DNS-SD record for %s - %d", + p->name, se); + + DNSServiceRefDeallocate(p->printer_ref); + p->printer_ref = NULL; + } + } + + if (!p->printer_ref) + { + /* + * Initial registration... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Registering DNS-SD printer %s with name \"%s\" and " + "type \"_printer._tcp\"", p->name, name); + + p->printer_ref = DNSSDRef; + if ((se = DNSServiceRegister(&p->printer_ref, + kDNSServiceFlagsShareConnection, + 0, name, "_printer._tcp", NULL, NULL, + htons(515), printer_len, printer_txt, + dnssdRegisterCallback, + p)) == kDNSServiceErr_NoError) + { + p->printer_txt = printer_txt; + p->printer_len = printer_len; + printer_txt = NULL; + } + else + cupsdLogMessage(CUPSD_LOG_WARN, + "DNS-SD LPD registration of \"%s\" failed: %d", + p->name, se); + } + + if (printer_txt) + free(printer_txt); + } +} + + +/* + * 'dnssdStop()' - Stop all DNS-SD registrations. + */ + +static void +dnssdStop(void) +{ + cupsd_printer_t *p; /* Current printer */ + + + /* + * De-register the individual printers + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + dnssdDeregisterPrinter(p); + + /* + * Shutdown the rest of the service refs... + */ + + if (WebIFRef) + { + DNSServiceRefDeallocate(WebIFRef); + WebIFRef = NULL; + } + + if (RemoteRef) + { + DNSServiceRefDeallocate(RemoteRef); + RemoteRef = NULL; + } + + cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDRef)); + + DNSServiceRefDeallocate(DNSSDRef); + DNSSDRef = NULL; + + cupsArrayDelete(DNSSDPrinters); + DNSSDPrinters = NULL; + + DNSSDPort = 0; +} + + +/* + * 'dnssdUpdate()' - Handle DNS-SD queries. + */ + +static void +dnssdUpdate(void) +{ + DNSServiceErrorType sdErr; /* Service discovery error */ + + + if ((sdErr = DNSServiceProcessResult(DNSSDRef)) != kDNSServiceErr_NoError) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "DNS Service Discovery registration error %d!", + sdErr); + dnssdStop(); + } +} +#endif /* HAVE_DNSSD */ + + +/* + * 'get_auth_info_required()' - Get the auth-info-required value to advertise. + */ + +static char * /* O - String or NULL if none */ +get_auth_info_required( + cupsd_printer_t *p, /* I - Printer */ + char *buffer, /* I - Value buffer */ + size_t bufsize) /* I - Size of value buffer */ +{ + cupsd_location_t *auth; /* Pointer to authentication element */ + char resource[1024]; /* Printer/class resource path */ + + + /* + * If auth-info-required is set for this printer, return that... + */ + + if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none")) + { + int i; /* Looping var */ + char *bufptr; /* Pointer into buffer */ + + for (i = 0, bufptr = buffer; i < p->num_auth_info_required; i ++) + { + if (bufptr >= (buffer + bufsize - 2)) + break; + + if (i) + *bufptr++ = ','; + + strlcpy(bufptr, p->auth_info_required[i], bufsize - (bufptr - buffer)); + bufptr += strlen(bufptr); + } + + return (buffer); + } + + /* + * Figure out the authentication data requirements to advertise... + */ + + 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 = cupsdFindBest(resource, HTTP_POST)) == NULL || + auth->type == CUPSD_AUTH_NONE) + auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB); + + if (auth) + { + int auth_type; /* Authentication type */ + + if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT) + auth_type = DefaultAuthType; + + switch (auth_type) + { + case CUPSD_AUTH_NONE : + return (NULL); + + case CUPSD_AUTH_NEGOTIATE : + strlcpy(buffer, "negotiate", bufsize); + break; + + default : + strlcpy(buffer, "username,password", bufsize); + break; + } + + return (buffer); + } + + return (NULL); +} + + +#ifdef __APPLE__ +/* + * 'get_hostconfig()' - Get an /etc/hostconfig service setting. + */ + +static int /* O - 1 for YES or AUTOMATIC, 0 for NO */ +get_hostconfig(const char *name) /* I - Name of service */ +{ + cups_file_t *fp; /* Hostconfig file */ + char line[1024], /* Line from file */ + *ptr; /* Pointer to value */ + int state = 1; /* State of service */ + + + /* + * Try opening the /etc/hostconfig file; if we can't open it, assume that + * the service is enabled/auto. + */ + + if ((fp = cupsFileOpen("/etc/hostconfig", "r")) != NULL) + { + /* + * Read lines from the file until we find the service... + */ + + while (cupsFileGets(fp, line, sizeof(line))) + { + if (line[0] == '#' || (ptr = strchr(line, '=')) == NULL) + continue; + + *ptr++ = '\0'; + + if (!strcasecmp(line, name)) + { + /* + * Found the service, see if it is set to "-NO-"... + */ + + if (!strncasecmp(ptr, "-NO-", 4)) + state = 0; + break; + } + } + + cupsFileClose(fp); + } + + return (state); +} +#endif /* __APPLE__ */ + + +/* + * 'is_local_queue()' - Determine whether the URI points at a local queue. + */ + +static int /* O - 1 = local, 0 = remote, -1 = bad URI */ +is_local_queue(const char *uri, /* I - Printer URI */ + char *host, /* O - Host string */ + int hostlen, /* I - Length of host buffer */ + char *resource, /* O - Resource string */ + int resourcelen) /* I - Length of resource buffer */ +{ + char scheme[32], /* Scheme portion of URI */ + username[HTTP_MAX_URI]; /* Username portion of URI */ + int port; /* Port portion of URI */ + cupsd_netif_t *iface; /* Network interface */ + + + /* + * Pull the URI apart to see if this is a local or remote printer... + */ + + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + username, sizeof(username), host, hostlen, &port, + resource, resourcelen) < HTTP_URI_OK) + return (-1); + + DEBUG_printf(("host=\"%s\", ServerName=\"%s\"\n", host, ServerName)); + + /* + * Check for local server addresses... + */ + + if (!strcasecmp(host, ServerName) && port == LocalPort) + return (1); + + cupsdNetIFUpdate(); + + for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + iface; + iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + if (!strcasecmp(host, iface->hostname) && port == iface->port) + return (1); + + /* + * If we get here, the printer is remote... + */ + + return (0); +} + + +/* + * 'process_browse_data()' - Process new browse data. + */ + +static void +process_browse_data( + const char *uri, /* I - URI of printer/class */ + const char *host, /* I - Hostname */ + const char *resource, /* I - Resource path */ + 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 num_attrs, /* I - Number of attributes */ + cups_option_t *attrs) /* I - Attributes */ +{ + int i; /* Looping var */ + int update; /* Update printer attributes? */ + char finaluri[HTTP_MAX_URI], /* Final URI for printer */ + name[IPP_MAX_NAME], /* Name of printer */ + newname[IPP_MAX_NAME], /* New name of printer */ + *hptr, /* Pointer into hostname */ + *sptr; /* Pointer into ServerName */ + const char *shortname; /* Short queue name (queue) */ + char local_make_model[IPP_MAX_NAME]; + /* Local make and model */ + cupsd_printer_t *p; /* Printer information */ + const char *ipp_options, /* ipp-options value */ + *lease_duration; /* lease-duration value */ + int is_class; /* Is this queue a class? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "process_browse_data(uri=\"%s\", host=\"%s\", " + "resource=\"%s\", type=%x, state=%d, location=\"%s\", " + "info=\"%s\", make_model=\"%s\", num_attrs=%d, attrs=%p)", + uri, host, resource, type, state, + location ? location : "(nil)", info ? info : "(nil)", + make_model ? make_model : "(nil)", num_attrs, attrs); + + /* + * Determine if the URI contains any illegal characters in it... + */ + + if (strncmp(uri, "ipp://", 6) || !host[0] || + (strncmp(resource, "/printers/", 10) && + strncmp(resource, "/classes/", 9))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad printer URI in browse data: %s", uri); + return; + } + + if (strchr(resource, '?') || + (!strncmp(resource, "/printers/", 10) && strchr(resource + 10, '/')) || + (!strncmp(resource, "/classes/", 9) && strchr(resource + 9, '/'))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad resource in browse data: %s", + resource); + return; + } + + /* + * OK, this isn't a local printer; add any remote options... + */ + + ipp_options = cupsGetOption("ipp-options", num_attrs, attrs); + + if (BrowseRemoteOptions) + { + if (BrowseRemoteOptions[0] == '?') + { + /* + * Override server-supplied options... + */ + + snprintf(finaluri, sizeof(finaluri), "%s%s", uri, BrowseRemoteOptions); + } + else if (ipp_options) + { + /* + * Combine the server and local options... + */ + + snprintf(finaluri, sizeof(finaluri), "%s?%s+%s", uri, ipp_options, + BrowseRemoteOptions); + } + else + { + /* + * Just use the local options... + */ + + snprintf(finaluri, sizeof(finaluri), "%s?%s", uri, BrowseRemoteOptions); + } + + uri = finaluri; + } + else if (ipp_options) + { + /* + * Just use the server-supplied options... + */ + + snprintf(finaluri, sizeof(finaluri), "%s?%s", uri, ipp_options); + uri = finaluri; + } + + /* + * See if we already have it listed in the Printers list, and add it if not... + */ + + type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED; + type &= ~CUPS_PRINTER_IMPLICIT; + update = 0; + hptr = strchr(host, '.'); + sptr = strchr(ServerName, '.'); + is_class = type & CUPS_PRINTER_CLASS; + + if (!ServerNameIsIP && sptr != NULL && hptr != NULL) + { + /* + * Strip the common domain name components... + */ + + while (hptr != NULL) + { + if (!strcasecmp(hptr, sptr)) + { + *hptr = '\0'; + break; + } + else + hptr = strchr(hptr + 1, '.'); + } + } + + if (is_class) + { + /* + * Remote destination is a class... + */ + + if (!strncmp(resource, "/classes/", 9)) + snprintf(name, sizeof(name), "%s@%s", resource + 9, host); + else + return; + + shortname = resource + 9; + } + else + { + /* + * Remote destination is a printer... + */ + + if (!strncmp(resource, "/printers/", 10)) + snprintf(name, sizeof(name), "%s@%s", resource + 10, host); + else + return; + + shortname = resource + 10; + } + + if (hptr && !*hptr) + *hptr = '.'; /* Resource FQDN */ + + if ((p = cupsdFindDest(name)) == NULL && BrowseShortNames) + { + /* + * Long name doesn't exist, try short name... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "process_browse_data: %s not found...", + name); + + if ((p = cupsdFindDest(shortname)) == NULL) + { + /* + * Short name doesn't exist, use it for this shared queue. + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "process_browse_data: %s not found...", + shortname); + strlcpy(name, shortname, sizeof(name)); + } + else + { + /* + * Short name exists... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "process_browse_data: %s found, type=%x, hostname=%s...", + shortname, p->type, p->hostname ? p->hostname : "(nil)"); + + if (p->type & CUPS_PRINTER_IMPLICIT) + p = NULL; /* Don't replace implicit classes */ + else if (p->hostname && strcasecmp(p->hostname, host)) + { + /* + * Short name exists but is for a different host. If this is a remote + * queue, rename it and use the long name... + */ + + if (p->type & CUPS_PRINTER_REMOTE) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Renamed remote %s \"%s\" to \"%s@%s\"...", + is_class ? "class" : "printer", p->name, p->name, + p->hostname); + cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL, + "%s \'%s\' deleted by directory services.", + is_class ? "Class" : "Printer", p->name); + + snprintf(newname, sizeof(newname), "%s@%s", p->name, p->hostname); + cupsdRenamePrinter(p, newname); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL, + "%s \'%s\' added by directory services.", + is_class ? "Class" : "Printer", p->name); + } + + /* + * Force creation with long name... + */ + + p = NULL; + } + } + } + else if (p) + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "process_browse_data: %s found, type=%x, hostname=%s...", + name, p->type, p->hostname ? p->hostname : "(nil)"); + + if (!p) + { + /* + * Queue doesn't exist; add it... + */ + + if (is_class) + p = cupsdAddClass(name); + else + p = cupsdAddPrinter(name); + + if (!p) + return; + + cupsdClearString(&(p->hostname)); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added remote %s \"%s\"...", + is_class ? "class" : "printer", name); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL, + "%s \'%s\' added by directory services.", + is_class ? "Class" : "Printer", name); + + /* + * Force the URI to point to the real server... + */ + + p->type = type & ~CUPS_PRINTER_REJECTING; + p->accepting = 1; + + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); + } + + if (!p->hostname) + { + /* + * Hostname not set, so this must be a cached remote printer + * that was created for a pending print job... + */ + + cupsdSetString(&p->hostname, host); + cupsdSetString(&p->uri, uri); + cupsdSetString(&p->device_uri, uri); + update = 1; + + cupsdMarkDirty(CUPSD_DIRTY_REMOTE); + } + + /* + * Update the state... + */ + + p->state = state; + p->browse_time = time(NULL); + + if ((lease_duration = cupsGetOption("lease-duration", num_attrs, + attrs)) != NULL) + { + /* + * Grab the lease-duration for the browse data; anything less then 1 + * second or more than 1 week gets the default BrowseTimeout... + */ + + i = atoi(lease_duration); + if (i < 1 || i > 604800) + i = BrowseTimeout; + + p->browse_expire = p->browse_time + i; + } + else + p->browse_expire = p->browse_time + BrowseTimeout; + + if (type & CUPS_PRINTER_REJECTING) + { + type &= ~CUPS_PRINTER_REJECTING; + + if (p->accepting) + { + update = 1; + p->accepting = 0; + } + } + else if (!p->accepting) + { + update = 1; + p->accepting = 1; + } + + if (p->type != type) + { + p->type = type; + update = 1; + } + + if (location && (!p->location || strcmp(p->location, location))) + { + cupsdSetString(&p->location, location); + update = 1; + } + + if (info && (!p->info || strcmp(p->info, info))) + { + cupsdSetString(&p->info, info); + update = 1; + + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE); + } + + if (!make_model || !make_model[0]) + { + if (is_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 (!p->make_model || strcmp(p->make_model, local_make_model)) + { + cupsdSetString(&p->make_model, local_make_model); + update = 1; + } + + if (p->num_options) + { + if (!update && !(type & CUPS_PRINTER_DELETE)) + { + /* + * See if we need to update the attributes... + */ + + if (p->num_options != num_attrs) + update = 1; + else + { + for (i = 0; i < num_attrs; i ++) + if (strcmp(attrs[i].name, p->options[i].name) || + (!attrs[i].value != !p->options[i].value) || + (attrs[i].value && strcmp(attrs[i].value, p->options[i].value))) + { + update = 1; + break; + } + } + } + + /* + * Free the old options... + */ + + cupsFreeOptions(p->num_options, p->options); + } + + p->num_options = num_attrs; + p->options = attrs; + + if (type & CUPS_PRINTER_DELETE) + { + cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, p, NULL, + "%s \'%s\' deleted by directory services.", + is_class ? "Class" : "Printer", p->name); + + cupsdExpireSubscriptions(p, NULL); + + cupsdDeletePrinter(p, 1); + cupsdUpdateImplicitClasses(); + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE); + } + else if (update) + { + cupsdSetPrinterAttrs(p); + cupsdUpdateImplicitClasses(); + } + + /* + * See if we have a default printer... If not, make the first network + * default printer the default. + */ + + if (DefaultPrinter == NULL && Printers != NULL && UseNetworkDefault) + { + /* + * Find the first network default printer and use it... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (p->type & CUPS_PRINTER_DEFAULT) + { + DefaultPrinter = p; + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE); + break; + } + } + + /* + * Do auto-classing if needed... + */ + + process_implicit_classes(); +} + + +/* + * 'process_implicit_classes()' - Create/update implicit classes as needed. + */ + +static void +process_implicit_classes(void) +{ + int i; /* Looping var */ + int update; /* Update printer attributes? */ + char name[IPP_MAX_NAME], /* Name of printer */ + *hptr; /* Pointer into hostname */ + cupsd_printer_t *p, /* Printer information */ + *pclass, /* Printer class */ + *first; /* First printer in class */ + int offset, /* Offset of name */ + len; /* Length of name */ + + + if (!ImplicitClasses || !Printers) + return; + + /* + * Loop through all available printers and create classes as needed... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers), len = 0, offset = 0, + update = 0, pclass = NULL, first = NULL; + p != NULL; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * Skip implicit classes... + */ + + if (p->type & CUPS_PRINTER_IMPLICIT) + { + len = 0; + continue; + } + + /* + * If len == 0, get the length of this printer name up to the "@" + * sign (if any). + */ + + cupsArraySave(Printers); + + if (len > 0 && + !strncasecmp(p->name, name + offset, len) && + (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 && strcasecmp(pclass->name, name)) + { + if (update) + cupsdSetPrinterAttrs(pclass); + + update = 0; + pclass = NULL; + } + + if (!pclass && (pclass = cupsdFindDest(name)) == NULL) + { + /* + * Need to add the class... + */ + + pclass = cupsdAddPrinter(name); + cupsArrayAdd(ImplicitPrinters, pclass); + + pclass->type |= CUPS_PRINTER_IMPLICIT; + pclass->accepting = 1; + pclass->state = IPP_PRINTER_IDLE; + + cupsdSetString(&pclass->location, p->location); + cupsdSetString(&pclass->info, p->info); + + cupsdSetString(&pclass->job_sheets[0], p->job_sheets[0]); + cupsdSetString(&pclass->job_sheets[1], p->job_sheets[1]); + + update = 1; + + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP | CUPSD_DIRTY_REMOTE); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added implicit class \"%s\"...", + name); + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL, + "Implicit class \'%s\' added by directory services.", + name); + } + + if (first != NULL) + { + for (i = 0; i < pclass->num_printers; i ++) + if (pclass->printers[i] == first) + break; + + if (i >= pclass->num_printers) + { + first->in_implicit_class = 1; + cupsdAddPrinterToClass(pclass, first); + } + + first = NULL; + } + + for (i = 0; i < pclass->num_printers; i ++) + if (pclass->printers[i] == p) + break; + + if (i >= pclass->num_printers) + { + p->in_implicit_class = 1; + cupsdAddPrinterToClass(pclass, p); + update = 1; + } + } + 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); + + if (len >= sizeof(name)) + { + /* + * If the printer name length somehow is greater than we normally allow, + * skip this printer... + */ + + len = 0; + cupsArrayRestore(Printers); + continue; + } + + strncpy(name, p->name, len); + name[len] = '\0'; + offset = 0; + + if ((first = (hptr ? cupsdFindDest(name) : p)) != NULL && + !(first->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 && len < (sizeof(name) - 4)) + { + /* + * 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; + cupsArrayRestore(Printers); + continue; + } + } + + first = p; + } + + cupsArrayRestore(Printers); + } + + /* + * Update the last printer class as needed... + */ + + if (pclass && update) + cupsdSetPrinterAttrs(pclass); +} + + +/* + * 'send_cups_browse()' - Send new browsing information using the CUPS + * protocol. + */ + +static void +send_cups_browse(cupsd_printer_t *p) /* I - Printer to send */ +{ + int i; /* Looping var */ + cups_ptype_t type; /* Printer type */ + cupsd_dirsvc_addr_t *b; /* Browse address */ + int bytes; /* Length of packet */ + char packet[1453], /* Browse data packet */ + uri[1024], /* Printer URI */ + location[1024], /* printer-location */ + info[1024], /* printer-info */ + make_model[1024], + /* printer-make-and-model */ + air[1024]; /* auth-info-required */ + cupsd_netif_t *iface; /* Network interface */ + + + /* + * Figure out the printer type value... + */ + + type = p->type | CUPS_PRINTER_REMOTE; + + if (!p->accepting) + type |= CUPS_PRINTER_REJECTING; + + if (p == DefaultPrinter) + type |= CUPS_PRINTER_DEFAULT; + + /* + * Remove quotes from printer-info, printer-location, and + * printer-make-and-model attributes... + */ + + dequote(location, p->location, sizeof(location)); + dequote(info, p->info, sizeof(info)); + + if (p->make_model) + dequote(make_model, p->make_model, sizeof(make_model)); + else if (p->type & CUPS_PRINTER_CLASS) + { + if (p->num_printers > 0 && p->printers[0]->make_model) + strlcpy(make_model, p->printers[0]->make_model, sizeof(make_model)); + else + strlcpy(make_model, "Local Printer Class", sizeof(make_model)); + } + else if (p->raw) + strlcpy(make_model, "Local Raw Printer", sizeof(make_model)); + else + strlcpy(make_model, "Local System V Printer", sizeof(make_model)); + + if (get_auth_info_required(p, packet, sizeof(packet))) + snprintf(air, sizeof(air), " auth-info-required=%s", packet); + else + air[0] = '\0'; + + /* + * 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, "*")) + { + /* + * Send to all local interfaces... + */ + + cupsdNetIFUpdate(); + + for (iface = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + iface; + iface = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + { + /* + * Only send to local, IPv4 interfaces... + */ + + if (!iface->is_local || !iface->port || + iface->address.addr.sa_family != AF_INET) + continue; + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + iface->hostname, iface->port, + (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : + "/printers/%s", + p->name); + snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n", + type, p->state, uri, location, info, make_model, + p->browse_attrs ? p->browse_attrs : "", air); + + bytes = strlen(packet); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSendBrowseList: (%d bytes to \"%s\") %s", bytes, + iface->name, packet); + + iface->broadcast.ipv4.sin_port = htons(BrowsePort); + + sendto(BrowseSocket, packet, bytes, 0, + (struct sockaddr *)&(iface->broadcast), + httpAddrLength(&(iface->broadcast))); + } + } + else if ((iface = cupsdNetIFFind(b->iface)) != NULL) + { + /* + * Send to the named interface using the IPv4 address... + */ + + while (iface) + if (strcmp(b->iface, iface->name)) + { + iface = NULL; + break; + } + else if (iface->address.addr.sa_family == AF_INET && iface->port) + break; + else + iface = (cupsd_netif_t *)cupsArrayNext(NetIFList); + + if (iface) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + iface->hostname, iface->port, + (p->type & CUPS_PRINTER_CLASS) ? "/classes/%s" : + "/printers/%s", + p->name); + snprintf(packet, sizeof(packet), + "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n", + type, p->state, uri, location, info, make_model, + p->browse_attrs ? p->browse_attrs : "", air); + + bytes = strlen(packet); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSendBrowseList: (%d bytes to \"%s\") %s", bytes, + iface->name, packet); + + iface->broadcast.ipv4.sin_port = htons(BrowsePort); + + sendto(BrowseSocket, packet, bytes, 0, + (struct sockaddr *)&(iface->broadcast), + httpAddrLength(&(iface->broadcast))); + } + } + } + else + { + /* + * Send the browse packet to the indicated address using + * the default server name... + */ + + snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\" %s%s\n", + type, p->state, p->uri, location, info, make_model, + p->browse_attrs ? p->browse_attrs : "", air); + + bytes = strlen(packet); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSendBrowseList: (%d bytes) %s", bytes, packet); + + if (sendto(BrowseSocket, packet, bytes, 0, + (struct sockaddr *)&(b->to), + httpAddrLength(&(b->to))) <= 0) + { + /* + * Unable to send browse packet, so remove this address from the + * list... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdSendBrowseList: sendto failed for browser " + "%d - %s.", + (int)(b - Browsers + 1), strerror(errno)); + + if (i > 1) + memmove(b, b + 1, (i - 1) * sizeof(cupsd_dirsvc_addr_t)); + + b --; + NumBrowsers --; + } + } +} + + +#ifdef HAVE_LDAP +/* + * 'ldap_search_rec()' - LDAP Search with reconnect + */ + +static int /* O - Return code */ +ldap_search_rec(LDAP *ld, /* I - LDAP handler */ + char *base, /* I - Base dn */ + int scope, /* I - LDAP search scope */ + char *filter, /* I - Filter string */ + char *attrs[], /* I - Requested attributes */ + int attrsonly, /* I - Return only attributes? */ + LDAPMessage **res) /* I - LDAP handler */ +{ + int rc; /* Return code */ + LDAP *ldr; /* LDAP handler after reconnect */ + + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + rc = ldap_search_ext_s(ld, base, scope, filter, attrs, attrsonly, NULL, NULL, + NULL, LDAP_NO_LIMIT, res); +# else + rc = ldap_search_s(ld, base, scope, filter, attrs, attrsonly, res); +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + + /* + * If we have a connection problem try again... + */ + + if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP search failed with status %d: %s", + rc, ldap_err2string(rc)); + cupsdLogMessage(CUPSD_LOG_INFO, + "We try the LDAP search once again after reconnecting to " + "the server"); + ldap_freeres(*res); + ldr = ldap_reconnect(); + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + rc = ldap_search_ext_s(ldr, base, scope, filter, attrs, attrsonly, NULL, + NULL, NULL, LDAP_NO_LIMIT, res); +# else + rc = ldap_search_s(ldr, base, scope, filter, attrs, attrsonly, res); +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + } + + if (rc == LDAP_NO_SUCH_OBJECT) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "ldap_search_rec: LDAP entry/object not found"); + else if (rc != LDAP_SUCCESS) + cupsdLogMessage(CUPSD_LOG_ERROR, + "ldap_search_rec: LDAP search failed with status %d: %s", + rc, ldap_err2string(rc)); + + if (rc != LDAP_SUCCESS) + ldap_freeres(*res); + + return (rc); +} + + +/* + * 'ldap_freeres()' - Free LDAPMessage + */ + +static void +ldap_freeres(LDAPMessage *entry) /* I - LDAP handler */ +{ + int rc; /* Return value */ + + + rc = ldap_msgfree(entry); + if (rc == -1) + cupsdLogMessage(CUPSD_LOG_WARN, "Can't free LDAPMessage!"); + else if (rc == 0) + cupsdLogMessage(CUPSD_LOG_DEBUG2, "Freeing LDAPMessage was unnecessary"); +} + + +/* + * 'ldap_getval_char()' - Get first LDAP value and convert to string + */ + +static int /* O - Return code */ +ldap_getval_firststring( + LDAP *ld, /* I - LDAP handler */ + LDAPMessage *entry, /* I - LDAP message or search result */ + char *attr, /* I - the wanted attribute */ + char *retval, /* O - String to return */ + unsigned long maxsize) /* I - Max string size */ +{ + char *dn; /* LDAP DN */ + int rc = 0; /* Return code */ +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + struct berval **bval; /* LDAP value array */ + unsigned long size; /* String size */ + + + /* + * Get value from LDAPMessage... + */ + + if ((bval = ldap_get_values_len(ld, entry, attr)) == NULL) + { + rc = -1; + dn = ldap_get_dn(ld, entry); + cupsdLogMessage(CUPSD_LOG_WARN, + "Failed to get LDAP value %s for %s!", + attr, dn); + ldap_memfree(dn); + } + else + { + /* + * Check size and copy value into our string... + */ + + size = maxsize; + if (size < (bval[0]->bv_len + 1)) + { + rc = -1; + dn = ldap_get_dn(ld, entry); + cupsdLogMessage(CUPSD_LOG_WARN, + "Attribute %s is too big! (dn: %s)", + attr, dn); + ldap_memfree(dn); + } + else + size = bval[0]->bv_len + 1; + + strlcpy(retval, bval[0]->bv_val, size); + ldap_value_free_len(bval); + } +# else + char **value; /* LDAP value */ + + /* + * Get value from LDAPMessage... + */ + + if ((value = (char **)ldap_get_values(ld, entry, attr)) == NULL) + { + rc = -1; + dn = ldap_get_dn(ld, entry); + cupsdLogMessage(CUPSD_LOG_WARN, "Failed to get LDAP value %s for %s!", + attr, dn); + ldap_memfree(dn); + } + else + { + strlcpy(retval, *value, maxsize); + ldap_value_free(value); + } +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + + return (rc); +} + + +/* + * 'send_ldap_ou()' - Send LDAP ou registrations. + */ + +static void +send_ldap_ou(char *ou, /* I - Servername/ou to register */ + char *basedn, /* I - Our base dn */ + char *descstring) /* I - Description for ou */ +{ + int i; /* Looping var... */ + LDAPMod mods[3]; /* The 3 attributes we will be adding */ + LDAPMod *pmods[4]; /* Pointers to the 3 attributes + NULL */ + LDAPMessage *res, /* Search result token */ + *e; /* Current entry from search */ + int rc; /* LDAP status */ + int rcmod; /* LDAP status for modifications */ + char dn[1024], /* DN of the organizational unit we are adding */ + *desc[2], /* Change records */ + *ou_value[2]; + char old_desc[1024]; /* Old description */ + static const char * const objectClass_values[] = + { /* The 2 objectClass's we use in */ + "top", /* our LDAP entries */ + "organizationalUnit", + NULL + }; + static const char * const ou_attrs[] =/* CUPS LDAP attributes */ + { + "description", + NULL + }; + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_ou: %s", ou); + + /* + * Reconnect if LDAP Handle is invalid... + */ + + if (!BrowseLDAPHandle) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_ou: LDAP Handle is invalid. Try reconnecting..."); + ldap_reconnect(); + return; + } + + /* + * Prepare ldap search... + */ + + snprintf(dn, sizeof(dn), "ou=%s, %s", ou, basedn); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_ou: dn=\"%s\"", dn); + + ou_value[0] = ou; + ou_value[1] = NULL; + desc[0] = descstring; + desc[1] = NULL; + + mods[0].mod_type = "ou"; + mods[0].mod_values = ou_value; + mods[1].mod_type = "description"; + mods[1].mod_values = desc; + mods[2].mod_type = "objectClass"; + mods[2].mod_values = (char **)objectClass_values; + + rc = ldap_search_rec(BrowseLDAPHandle, dn, LDAP_SCOPE_BASE, NULL, + (char **)ou_attrs, 0, &res); + + /* + * If ldap search was not successfull then exit function... + */ + + if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) + return; + + /* + * Check if we need to insert or update the LDAP entry... + */ + + if (ldap_count_entries(BrowseLDAPHandle, res) > 0 && + rc != LDAP_NO_SUCH_OBJECT) + { + /* + * Printserver has already been registered, check if + * modification is required... + */ + + e = ldap_first_entry(BrowseLDAPHandle, res); + + /* + * Get the required values from this entry... + */ + + if (ldap_getval_firststring(BrowseLDAPHandle, e, "description", old_desc, + sizeof(old_desc)) == -1) + old_desc[0] = '\0'; + + /* + * Check if modification is required... + */ + + if ( strcmp(desc[0], old_desc) == 0 ) + { + /* + * LDAP entry for the printer exists. + * Printer has already been registered, + * no modifications required... + */ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_ou: No updates required for %s", ou); + } + else + { + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_ou: Replace entry for %s", ou); + + for (i = 0; i < 3; i ++) + { + pmods[i] = mods + i; + pmods[i]->mod_op = LDAP_MOD_REPLACE; + } + pmods[i] = NULL; + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rcmod = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rcmod = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP modify for %s failed with status %d: %s", + ou, rcmod, ldap_err2string(rcmod)); + if (rcmod == LDAP_SERVER_DOWN) + ldap_reconnect(); + } + } + } + else + { + /* + * Printserver has never been registered, + * add registration... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_ou: Add entry for %s", ou); + + for (i = 0; i < 3; i ++) + { + pmods[i] = mods + i; + pmods[i]->mod_op = LDAP_MOD_ADD; + } + pmods[i] = NULL; + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rcmod = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rcmod = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP add for %s failed with status %d: %s", + ou, rcmod, ldap_err2string(rcmod)); + if (rcmod == LDAP_SERVER_DOWN) + ldap_reconnect(); + } + } + + if (rc == LDAP_SUCCESS) + ldap_freeres(res); +} + + +/* + * 'send_ldap_browse()' - Send LDAP printer registrations. + */ + +static void +send_ldap_browse(cupsd_printer_t *p) /* I - Printer to register */ +{ + int i; /* Looping var... */ + LDAPMod mods[7]; /* The 7 attributes we will be adding */ + LDAPMod *pmods[8]; /* Pointers to the 7 attributes + NULL */ + LDAPMessage *res, /* Search result token */ + *e; /* Current entry from search */ + char *cn_value[2], /* Change records */ + *uri[2], + *info[2], + *location[2], + *make_model[2], + *type[2], + typestring[255], /* String to hold printer-type */ + dn[1024]; /* DN of the printer we are adding */ + int rc; /* LDAP status */ + int rcmod; /* LDAP status for modifications */ + char old_uri[HTTP_MAX_URI], /* Printer URI */ + old_location[1024], /* Printer location */ + old_info[1024], /* Printer information */ + old_make_model[1024], /* Printer make and model */ + old_type_string[30]; /* Temporary type number */ + int old_type; /* Printer type */ + static const char * const objectClass_values[] = + { /* The 3 objectClass's we use in */ + "top", /* our LDAP entries */ + "device", + "cupsPrinter", + NULL + }; + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: %s", p->name); + + /* + * Exit function if LDAP updates has been disabled... + */ + + if (!BrowseLDAPUpdate) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_browse: Updates temporary disabled; " + "skipping..."); + return; + } + + /* + * Reconnect if LDAP Handle is invalid... + */ + + if (!BrowseLDAPHandle) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_browse: LDAP Handle is invalid. Try " + "reconnecting..."); + ldap_reconnect(); + return; + } + + /* + * Everything in ldap is ** so we fudge around it... + */ + + sprintf(typestring, "%u", p->type); + + cn_value[0] = p->name; + cn_value[1] = NULL; + info[0] = p->info ? p->info : "Unknown"; + info[1] = NULL; + location[0] = p->location ? p->location : "Unknown"; + location[1] = NULL; + make_model[0] = p->make_model ? p->make_model : "Unknown"; + make_model[1] = NULL; + type[0] = typestring; + type[1] = NULL; + uri[0] = p->uri; + uri[1] = NULL; + + /* + * Get ldap entry for printer ... + */ + + snprintf(dn, sizeof(dn), "cn=%s, ou=%s, %s", p->name, ServerName, + BrowseLDAPDN); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_ldap_browse: dn=\"%s\"", dn); + + rc = ldap_search_rec(BrowseLDAPHandle, dn, LDAP_SCOPE_BASE, NULL, + (char **)ldap_attrs, 0, &res); + + /* + * If ldap search was not successfull then exit function + * and temporary disable LDAP updates... + */ + + if (rc != LDAP_SUCCESS && rc != LDAP_NO_SUCH_OBJECT) + { + if (BrowseLDAPUpdate && + (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR)) + { + BrowseLDAPUpdate = FALSE; + cupsdLogMessage(CUPSD_LOG_INFO, + "LDAP update temporary disabled"); + } + + return; + } + + /* + * Fill modification array... + */ + + mods[0].mod_type = "cn"; + mods[0].mod_values = cn_value; + mods[1].mod_type = "printerDescription"; + mods[1].mod_values = info; + mods[2].mod_type = "printerURI"; + mods[2].mod_values = uri; + mods[3].mod_type = "printerLocation"; + mods[3].mod_values = location; + mods[4].mod_type = "printerMakeAndModel"; + mods[4].mod_values = make_model; + mods[5].mod_type = "printerType"; + mods[5].mod_values = type; + mods[6].mod_type = "objectClass"; + mods[6].mod_values = (char **)objectClass_values; + + /* + * Check if we need to insert or update the LDAP entry... + */ + + if (ldap_count_entries(BrowseLDAPHandle, res) > 0 && + rc != LDAP_NO_SUCH_OBJECT) + { + /* + * Printer has already been registered, check if + * modification is required... + */ + + e = ldap_first_entry(BrowseLDAPHandle, res); + + /* + * Get the required values from this entry... + */ + + if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerDescription", + old_info, sizeof(old_info)) == -1) + old_info[0] = '\0'; + + if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerLocation", + old_location, sizeof(old_location)) == -1) + old_info[0] = '\0'; + + if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerMakeAndModel", + old_make_model, sizeof(old_make_model)) == -1) + old_info[0] = '\0'; + + if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerType", + old_type_string, sizeof(old_type_string)) == -1) + old_info[0] = '\0'; + + old_type = atoi(old_type_string); + + if (ldap_getval_firststring(BrowseLDAPHandle, e, "printerURI", old_uri, + sizeof(old_uri)) == -1) + old_info[0] = '\0'; + + /* + * Check if modification is required... + */ + + if (!strcmp(info[0], old_info) && !strcmp(uri[0], old_uri) && + !strcmp(location[0], old_location) && + !strcmp(make_model[0], old_make_model) && p->type == old_type) + { + /* + * LDAP entry for the printer exists. Printer has already been registered, + * no modifications required... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_browse: No updates required for %s", p->name); + } + else + { + /* + * LDAP entry for the printer exists. Printer has already been registered, + * modify the current registration... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_browse: Replace entry for %s", p->name); + + for (i = 0; i < 7; i ++) + { + pmods[i] = mods + i; + pmods[i]->mod_op = LDAP_MOD_REPLACE; + } + pmods[i] = NULL; + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rcmod = ldap_modify_ext_s(BrowseLDAPHandle, dn, pmods, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rcmod = ldap_modify_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP modify for %s failed with status %d: %s", + p->name, rcmod, ldap_err2string(rcmod)); + if (rcmod == LDAP_SERVER_DOWN) + ldap_reconnect(); + } + } + } + else + { + /* + * No LDAP entry exists for the printer. Printer has never been registered, + * add the current registration... + */ + + send_ldap_ou(ServerName, BrowseLDAPDN, "CUPS Server"); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "send_ldap_browse: Add entry for %s", p->name); + + for (i = 0; i < 7; i ++) + { + pmods[i] = mods + i; + pmods[i]->mod_op = LDAP_MOD_ADD; + } + pmods[i] = NULL; + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rcmod = ldap_add_ext_s(BrowseLDAPHandle, dn, pmods, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rcmod = ldap_add_s(BrowseLDAPHandle, dn, pmods)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "LDAP add for %s failed with status %d: %s", + p->name, rcmod, ldap_err2string(rcmod)); + if (rcmod == LDAP_SERVER_DOWN) + ldap_reconnect(); + } + } + + if (rc == LDAP_SUCCESS) + ldap_freeres(res); +} + + +/* + * 'ldap_dereg_printer()' - Delete printer from directory + */ + +static void +ldap_dereg_printer(cupsd_printer_t *p) /* I - Printer to deregister */ +{ + char dn[1024]; /* DN of the printer */ + int rc; /* LDAP status */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_printer: Remove entry for %s", + p->name); + + /* + * Reconnect if LDAP Handle is invalid... + */ + + if (!BrowseLDAPHandle) + { + ldap_reconnect(); + return; + } + + /* + * Get dn for printer and delete LDAP entry... + */ + + snprintf(dn, sizeof(dn), "cn=%s, ou=%s, %s", p->name, ServerName, + BrowseLDAPDN); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_printer: dn=\"%s\"", dn); + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + { + cupsdLogMessage(CUPSD_LOG_WARN, + "LDAP delete for %s failed with status %d: %s", + p->name, rc, ldap_err2string(rc)); + + /* + * If we had a connection problem (connection timed out, etc.) + * we should reconnect and try again to delete the entry... + */ + + if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Retry deleting LDAP entry for %s after a reconnect...", p->name); + ldap_reconnect(); + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + cupsdLogMessage(CUPSD_LOG_WARN, + "LDAP delete for %s failed with status %d: %s", + p->name, rc, ldap_err2string(rc)); + } + } +} + + +/* + * 'ldap_dereg_ou()' - Remove the organizational unit. + */ + +static void +ldap_dereg_ou(char *ou, /* I - Organizational unit (servername) */ + char *basedn) /* I - Dase dn */ +{ + char dn[1024]; /* DN of the printer */ + int rc; /* LDAP status */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_ou: Remove entry for %s", ou); + + /* + * Reconnect if LDAP Handle is invalid... + */ + + if (!BrowseLDAPHandle) + { + ldap_reconnect(); + return; + } + + /* + * Get dn for printer and delete LDAP entry... + */ + + snprintf(dn, sizeof(dn), "ou=%s, %s", ou, basedn); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "ldap_dereg_ou: dn=\"%s\"", dn); + +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + { + cupsdLogMessage(CUPSD_LOG_WARN, + "LDAP delete for %s failed with status %d: %s", + ou, rc, ldap_err2string(rc)); + + /* + * If we had a connection problem (connection timed out, etc.) + * we should reconnect and try again to delete the entry... + */ + + if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Retry deleting LDAP entry for %s after a reconnect...", ou); + ldap_reconnect(); +# if defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 + if ((rc = ldap_delete_ext_s(BrowseLDAPHandle, dn, NULL, + NULL)) != LDAP_SUCCESS) +# else + if ((rc = ldap_delete_s(BrowseLDAPHandle, dn)) != LDAP_SUCCESS) +# endif /* defined(HAVE_OPENLDAP) && LDAP_API_VERSION > 3000 */ + cupsdLogMessage(CUPSD_LOG_WARN, + "LDAP delete for %s failed with status %d: %s", + ou, rc, ldap_err2string(rc)); + } + } +} +#endif /* HAVE_LDAP */ + + +#ifdef HAVE_LIBSLP +/* + * 'send_slp_browse()' - Register the specified printer with SLP. + */ + +static void +send_slp_browse(cupsd_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 */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, "send_slp_browse(%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); + + cupsdLogMessage(CUPSD_LOG_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... + */ + + for (src = p->make_model, dst = make_model; + src && *src && dst < (make_model + sizeof(make_model) - 2);) + { + if (*src == ',' || *src == '\\' || *src == ')') + *dst++ = '\\'; + + *dst++ = *src++; + } + + *dst = '\0'; + + if (!make_model[0]) + strcpy(make_model, "Unknown"); + + for (src = p->location, dst = location; + src && *src && dst < (location + sizeof(location) - 2);) + { + if (*src == ',' || *src == '\\' || *src == ')') + *dst++ = '\\'; + + *dst++ = *src++; + } + + *dst = '\0'; + + if (!location[0]) + strcpy(location, "Unknown"); + + for (src = p->info, dst = info; + src && *src && dst < (info + sizeof(info) - 2);) + { + 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_SSL + "(uri-security-supported=tls>)," +#else + "(uri-security-supported=none>)," +#endif /* HAVE_SSL */ + "(printer-name=%s)," + "(printer-location=%s)," + "(printer-info=%s)," + "(printer-more-info=%s)," + "(printer-make-and-model=%s)," + "(printer-type=%d)," + "(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, p->type, DefaultLanguage, + p->type & CUPS_PRINTER_COLOR ? "true" : "false", + finishings, + p->type & CUPS_PRINTER_DUPLEX ? + ",two-sided-long-edge,two-sided-short-edge" : ""); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "Attributes = \"%s\"", attrs); + + /* + * Register the printer with the SLP server... + */ + + error = SLPReg(BrowseSLPHandle, srvurl, BrowseTimeout, + SLP_CUPS_SRVTYPE, attrs, SLP_TRUE, slp_reg_callback, 0); + + if (error != SLP_OK) + cupsdLogMessage(CUPSD_LOG_ERROR, "SLPReg of \"%s\" failed with status %d!", p->name, + error); +} + + +/* + * 'slp_attr_callback()' - SLP attribute callback + */ + +static SLPBoolean /* O - SLP_TRUE for success */ +slp_attr_callback( + SLPHandle hslp, /* I - SLP handle */ + const char *attrlist, /* I - Attribute list */ + SLPError errcode, /* I - Parsing status for this attr */ + void *cookie) /* I - Current printer */ +{ + char *tmp = 0; /* Temporary string */ + cupsd_printer_t *p = (cupsd_printer_t*)cookie; + /* Current printer */ + + + (void)hslp; /* anti-compiler-warning-code */ + + /* + * 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(cupsd_printer_t)); + + if (slp_get_attr(attrlist, "(printer-location=", &(p->location))) + return (SLP_FALSE); + if (slp_get_attr(attrlist, "(printer-info=", &(p->info))) + return (SLP_FALSE); + if (slp_get_attr(attrlist, "(printer-make-and-model=", &(p->make_model))) + return (SLP_FALSE); + if (!slp_get_attr(attrlist, "(printer-type=", &tmp)) + p->type = atoi(tmp); + else + p->type = CUPS_PRINTER_REMOTE; + + cupsdClearString(&tmp); + + return (SLP_TRUE); +} + + +/* + * 'slp_dereg_printer()' - SLPDereg() the specified printer + */ + +static void +slp_dereg_printer(cupsd_printer_t *p) /* I - Printer */ +{ + char srvurl[HTTP_MAX_URI]; /* Printer service URI */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, "slp_dereg_printer: printer=\"%s\"", p->name); + + if (!(p->type & CUPS_PRINTER_REMOTE)) + { + /* + * 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, slp_reg_callback, 0); + } +} + + +/* + * 'slp_get_attr()' - Get an attribute from an SLP registration. + */ + +static int /* O - 0 on success */ +slp_get_attr(const char *attrlist, /* I - Attribute list string */ + const char *tag, /* I - Name of attribute */ + char **valbuf) /* O - Value */ +{ + char *ptr1, /* Pointer into string */ + *ptr2; /* ... */ + + + cupsdClearString(valbuf); + + if ((ptr1 = strstr(attrlist, tag)) != NULL) + { + ptr1 += strlen(tag); + + if ((ptr2 = strchr(ptr1,')')) != NULL) + { + /* + * Copy the value... + */ + + *valbuf = calloc(ptr2 - ptr1 + 1, 1); + strncpy(*valbuf, ptr1, ptr2 - ptr1); + + /* + * Dequote the value... + */ + + for (ptr1 = *valbuf; *ptr1; ptr1 ++) + if (*ptr1 == '\\' && ptr1[1]) + _cups_strcpy(ptr1, ptr1 + 1); + + return (0); + } + } + + return (-1); +} + + +/* + * 'slp_reg_callback()' - Empty SLPRegReport. + */ + +static void +slp_reg_callback(SLPHandle hslp, /* I - SLP handle */ + SLPError errcode, /* I - Error code, if any */ + void *cookie) /* I - App data */ +{ + (void)hslp; + (void)errcode; + (void)cookie; + + return; +} + + +/* + * 'slp_url_callback()' - SLP service url callback + */ + +static SLPBoolean /* O - TRUE = OK, FALSE = error */ +slp_url_callback( + 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); +} +#endif /* HAVE_LIBSLP */ + + +/* + * 'update_cups_browse()' - Update the browse lists using the CUPS protocol. + */ + +static void +update_cups_browse(void) +{ + int i; /* Looping var */ + int auth; /* Authorization status */ + int len; /* Length of name string */ + int bytes; /* Number of bytes left */ + char packet[1541], /* Broadcast packet */ + *pptr; /* Pointer into packet */ + socklen_t srclen; /* Length of source address */ + http_addr_t srcaddr; /* Source address */ + char srcname[1024]; /* Source hostname */ + unsigned address[4]; /* Source address */ + unsigned type; /* Printer type */ + unsigned state; /* Printer state */ + char uri[HTTP_MAX_URI], /* Printer 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 num_attrs; /* Number of attributes */ + cups_option_t *attrs; /* Attributes */ + + + /* + * Read a packet from the browse socket... + */ + + srclen = sizeof(srcaddr); + if ((bytes = recvfrom(BrowseSocket, packet, sizeof(packet) - 1, 0, + (struct sockaddr *)&srcaddr, &srclen)) < 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 && errno != EAGAIN) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Browse recv failed - %s.", + strerror(errno)); + cupsdLogMessage(CUPSD_LOG_ERROR, "CUPS browsing turned off."); + +#ifdef WIN32 + closesocket(BrowseSocket); +#else + close(BrowseSocket); +#endif /* WIN32 */ + + cupsdRemoveSelect(BrowseSocket); + BrowseSocket = -1; + + BrowseLocalProtocols &= ~BROWSE_CUPS; + BrowseRemoteProtocols &= ~BROWSE_CUPS; + } + + return; + } + + packet[bytes] = '\0'; + + /* + * If we're about to sleep, ignore incoming browse packets. + */ + + if (Sleeping) + return; + + /* + * Figure out where it came from... + */ + +#ifdef AF_INET6 + if (srcaddr.addr.sa_family == AF_INET6) + { + address[0] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[0]); + address[1] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[1]); + address[2] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[2]); + address[3] = ntohl(srcaddr.ipv6.sin6_addr.s6_addr32[3]); + } + else +#endif /* AF_INET6 */ + { + address[0] = 0; + address[1] = 0; + address[2] = 0; + address[3] = ntohl(srcaddr.ipv4.sin_addr.s_addr); + } + + if (HostNameLookups) + httpAddrLookup(&srcaddr, srcname, sizeof(srcname)); + else + httpAddrString(&srcaddr, srcname, sizeof(srcname)); + + len = strlen(srcname); + + /* + * Do ACL stuff... + */ + + if (BrowseACL) + { + if (httpAddrLocalhost(&srcaddr) || !strcasecmp(srcname, "localhost")) + { + /* + * Access from localhost (127.0.0.1) is always allowed... + */ + + auth = CUPSD_AUTH_ALLOW; + } + else + { + /* + * Do authorization checks on the domain/address... + */ + + switch (BrowseACL->order_type) + { + default : + auth = CUPSD_AUTH_DENY; /* anti-compiler-warning-code */ + break; + + case CUPSD_AUTH_ALLOW : /* Order Deny,Allow */ + auth = CUPSD_AUTH_ALLOW; + + if (cupsdCheckAuth(address, srcname, len, + BrowseACL->num_deny, BrowseACL->deny)) + auth = CUPSD_AUTH_DENY; + + if (cupsdCheckAuth(address, srcname, len, + BrowseACL->num_allow, BrowseACL->allow)) + auth = CUPSD_AUTH_ALLOW; + break; + + case CUPSD_AUTH_DENY : /* Order Allow,Deny */ + auth = CUPSD_AUTH_DENY; + + if (cupsdCheckAuth(address, srcname, len, + BrowseACL->num_allow, BrowseACL->allow)) + auth = CUPSD_AUTH_ALLOW; + + if (cupsdCheckAuth(address, srcname, len, + BrowseACL->num_deny, BrowseACL->deny)) + auth = CUPSD_AUTH_DENY; + break; + } + } + } + else + auth = CUPSD_AUTH_ALLOW; + + if (auth == CUPSD_AUTH_DENY) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "update_cups_browse: Refused %d bytes from %s", bytes, + srcname); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "update_cups_browse: (%d bytes from %s) %s", bytes, + srcname, packet); + + /* + * Parse packet... + */ + + if (sscanf(packet, "%x%x%1023s", &type, &state, uri) < 3) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "update_cups_browse: Garbled browse packet - %s", packet); + return; + } + + strcpy(location, "Location Unknown"); + strcpy(info, "No Information Available"); + make_model[0] = '\0'; + num_attrs = 0; + attrs = NULL; + + 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 & 255)) + pptr ++; + + if (*pptr == '\"') + { + for (i = 0, pptr ++; + i < (sizeof(info) - 1) && *pptr && *pptr != '\"'; + i ++, pptr ++) + info[i] = *pptr; + + info[i] = '\0'; + + if (*pptr == '\"') + pptr ++; + + while (*pptr && isspace(*pptr & 255)) + pptr ++; + + if (*pptr == '\"') + { + for (i = 0, pptr ++; + i < (sizeof(make_model) - 1) && *pptr && *pptr != '\"'; + i ++, pptr ++) + make_model[i] = *pptr; + + if (*pptr == '\"') + pptr ++; + + make_model[i] = '\0'; + + if (*pptr) + num_attrs = cupsParseOptions(pptr, num_attrs, &attrs); + } + } + } + + 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... + */ + + if (is_local_queue(uri, host, sizeof(host), resource, sizeof(resource))) + { + cupsFreeOptions(num_attrs, attrs); + return; + } + + /* + * Do relaying... + */ + + for (i = 0; i < NumRelays; i ++) + if (cupsdCheckAuth(address, srcname, len, 1, &(Relays[i].from))) + if (sendto(BrowseSocket, packet, bytes, 0, + (struct sockaddr *)&(Relays[i].to), + httpAddrLength(&(Relays[i].to))) <= 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "update_cups_browse: sendto failed for relay %d - %s.", + i + 1, strerror(errno)); + cupsFreeOptions(num_attrs, attrs); + return; + } + + /* + * Process the browse data... + */ + + process_browse_data(uri, host, resource, (cups_ptype_t)type, + (ipp_pstate_t)state, location, info, make_model, + num_attrs, attrs); +} + + +/* + * 'update_lpd()' - Update the LPD configuration as needed. + */ + +static void +update_lpd(int onoff) /* - 1 = turn on, 0 = turn off */ +{ + if (!LPDConfigFile) + return; + +#ifdef __APPLE__ + /* + * Allow /etc/hostconfig CUPS_LPD service setting to override cupsd.conf + * setting for backwards-compatibility. + */ + + if (onoff && !get_hostconfig("CUPS_LPD")) + onoff = 0; +#endif /* __APPLE__ */ + + if (!strncmp(LPDConfigFile, "xinetd:///", 10)) + { + /* + * Enable/disable LPD via the xinetd.d config file for cups-lpd... + */ + + char newfile[1024]; /* New cups-lpd.N file */ + cups_file_t *ofp, /* Original file pointer */ + *nfp; /* New file pointer */ + char line[1024]; /* Line from file */ + + + snprintf(newfile, sizeof(newfile), "%s.N", LPDConfigFile + 9); + + if ((ofp = cupsFileOpen(LPDConfigFile + 9, "r")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s", + LPDConfigFile + 9, strerror(errno)); + return; + } + + if ((nfp = cupsFileOpen(newfile, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s", + newfile, strerror(errno)); + cupsFileClose(ofp); + return; + } + + /* + * Copy all of the lines from the cups-lpd file... + */ + + while (cupsFileGets(ofp, line, sizeof(line))) + { + if (line[0] == '{') + { + cupsFilePrintf(nfp, "%s\n", line); + snprintf(line, sizeof(line), "\tdisable = %s", + onoff ? "no" : "yes"); + } + else if (!strstr(line, "disable =")) + cupsFilePrintf(nfp, "%s\n", line); + } + + cupsFileClose(nfp); + cupsFileClose(ofp); + rename(newfile, LPDConfigFile + 9); + } +#ifdef __APPLE__ + else if (!strncmp(LPDConfigFile, "launchd:///", 11)) + { + /* + * Enable/disable LPD via the launchctl command... + */ + + char *argv[5], /* Arguments for command */ + *envp[MAX_ENV]; /* Environment for command */ + int pid; /* Process ID */ + + + cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + argv[0] = (char *)"launchctl"; + argv[1] = (char *)(onoff ? "load" : "unload"); + argv[2] = (char *)"-w"; + argv[3] = LPDConfigFile + 10; + argv[4] = NULL; + + cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1, + NULL, NULL, &pid); + } +#endif /* __APPLE__ */ + else + cupsdLogMessage(CUPSD_LOG_INFO, "Unknown LPDConfigFile scheme!"); +} + + +/* + * 'update_polling()' - Read status messages from the poll daemons. + */ + +static void +update_polling(void) +{ + char *ptr, /* Pointer to end of line in buffer */ + message[1024]; /* Pointer to message text */ + int loglevel; /* Log level for message */ + + + while ((ptr = cupsdStatBufUpdate(PollStatusBuffer, &loglevel, + message, sizeof(message))) != NULL) + { + if (loglevel == CUPSD_LOG_INFO) + cupsdLogMessage(CUPSD_LOG_INFO, "%s", message); + + if (!strchr(PollStatusBuffer->buffer, '\n')) + break; + } + + if (ptr == NULL && !PollStatusBuffer->bufused) + { + /* + * All polling processes have died; stop polling... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "update_polling: all polling processes have exited!"); + cupsdStopPolling(); + } +} + + +/* + * 'update_smb()' - Update the SMB configuration as needed. + */ + +static void +update_smb(int onoff) /* I - 1 = turn on, 0 = turn off */ +{ + if (!SMBConfigFile) + return; + + if (!strncmp(SMBConfigFile, "samba:///", 9)) + { + /* + * Enable/disable SMB via the specified smb.conf config file... + */ + + char newfile[1024]; /* New smb.conf.N file */ + cups_file_t *ofp, /* Original file pointer */ + *nfp; /* New file pointer */ + char line[1024]; /* Line from file */ + int in_printers; /* In [printers] section? */ + + + snprintf(newfile, sizeof(newfile), "%s.N", SMBConfigFile + 8); + + if ((ofp = cupsFileOpen(SMBConfigFile + 8, "r")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s", + SMBConfigFile + 8, strerror(errno)); + return; + } + + if ((nfp = cupsFileOpen(newfile, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s", + newfile, strerror(errno)); + cupsFileClose(ofp); + return; + } + + /* + * Copy all of the lines from the smb.conf file... + */ + + in_printers = 0; + + while (cupsFileGets(ofp, line, sizeof(line))) + { + if (in_printers && strstr(line, "printable =")) + snprintf(line, sizeof(line), " printable = %s", + onoff ? "yes" : "no"); + + cupsFilePrintf(nfp, "%s\n", line); + + if (line[0] == '[') + in_printers = !strcmp(line, "[printers]"); + } + + cupsFileClose(nfp); + cupsFileClose(ofp); + rename(newfile, SMBConfigFile + 8); + } + else + cupsdLogMessage(CUPSD_LOG_INFO, "Unknown SMBConfigFile scheme!"); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h new file mode 100644 index 0000000000..4ab3804ba5 --- /dev/null +++ b/scheduler/dirsvc.h @@ -0,0 +1,212 @@ +/* + * "$Id$" + * + * Directory services definitions for the Common UNIX Printing System + * (CUPS) scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Include necessary headers... + */ + +#ifdef HAVE_LIBSLP +# include +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP +# ifdef __sun +# include +# endif /* __sun */ +# include +# ifdef HAVE_LDAP_SSL_H +# include +# endif /* HAVE_LDAP_SSL_H */ +#endif /* HAVE_LDAP */ + +/* + * Browse protocols... + */ + +#define BROWSE_CUPS 1 /* CUPS */ +#define BROWSE_SLP 2 /* SLPv2 */ +#define BROWSE_LDAP 4 /* LDAP */ +#define BROWSE_DNSSD 8 /* DNS Service Discovery (aka Bonjour) */ +#define BROWSE_SMB 16 /* SMB/Samba */ +#define BROWSE_LPD 32 /* LPD via xinetd or launchd */ +#define BROWSE_ALL 63 /* All protocols */ + + +/* + * Browse address... + */ + +typedef struct +{ + char iface[32]; /* Destination interface */ + http_addr_t to; /* Destination address */ +} cupsd_dirsvc_addr_t; + + +/* + * Relay structure... + */ + +typedef struct +{ + cupsd_authmask_t from; /* Source address/name mask */ + http_addr_t to; /* Destination address */ +} cupsd_dirsvc_relay_t; + + +/* + * Polling structure... + */ + +typedef struct +{ + char hostname[64]; /* Hostname (actually, IP address) */ + int port; /* Port number */ + int pid; /* Current poll server PID */ +} cupsd_dirsvc_poll_t; + + +/* + * Globals... + */ + +VAR int Browsing VALUE(TRUE), + /* Whether or not browsing is enabled */ + BrowseWebIF VALUE(FALSE), + /* Whether the web interface is advertised */ + BrowseLocalProtocols + VALUE(BROWSE_ALL), + /* Protocols to support for local printers */ + BrowseRemoteProtocols + VALUE(BROWSE_ALL), + /* Protocols to support for remote printers */ + 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 */ + UseNetworkDefault VALUE(CUPS_DEFAULT_USE_NETWORK_DEFAULT), + /* Use the network default printer? */ + NumBrowsers VALUE(0); + /* Number of broadcast addresses */ +VAR char *BrowseLocalOptions + VALUE(NULL), + /* Options to add to local printer URIs */ + *BrowseRemoteOptions + VALUE(NULL); + /* Options to add to remote printer URIs */ +VAR cupsd_dirsvc_addr_t *Browsers VALUE(NULL); + /* Broadcast addresses */ +VAR cupsd_location_t *BrowseACL VALUE(NULL); + /* Browser access control list */ +VAR cupsd_printer_t *BrowseNext VALUE(NULL); + /* Next class/printer to broadcast */ +VAR int NumRelays VALUE(0); + /* Number of broadcast relays */ +VAR cupsd_dirsvc_relay_t *Relays VALUE(NULL); + /* Broadcast relays */ +VAR int NumPolled VALUE(0); + /* Number of polled servers */ +VAR cupsd_dirsvc_poll_t *Polled VALUE(NULL); + /* Polled servers */ +VAR int PollPipe VALUE(0); + /* Status pipe for pollers */ +VAR cupsd_statbuf_t *PollStatusBuffer VALUE(NULL); + /* Status buffer for pollers */ + +#ifdef HAVE_DNSSD +VAR char *DNSSDComputerName VALUE(NULL), + /* Computer/server name */ + *DNSSDHostName VALUE(NULL); + /* Hostname */ +VAR cups_array_t *DNSSDAlias VALUE(NULL); + /* List of dynamic ServerAlias's */ +VAR int DNSSDPort VALUE(0); + /* Port number to register */ +VAR cups_array_t *DNSSDPrinters VALUE(NULL); + /* Printers we have registered */ +VAR DNSServiceRef DNSSDRef VALUE(NULL), + /* Master DNS-SD service reference */ + WebIFRef VALUE(NULL), + /* Service reference for the web interface */ + RemoteRef VALUE(NULL); + /* Remote printer browse reference */ +#endif /* HAVE_DNSSD */ + +#ifdef HAVE_LIBSLP +VAR SLPHandle BrowseSLPHandle VALUE(NULL); + /* SLP API handle */ +VAR time_t BrowseSLPRefresh VALUE(0); + /* Next SLP refresh time */ +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP +VAR LDAP *BrowseLDAPHandle VALUE(NULL); + /* Handle to LDAP server */ +VAR time_t BrowseLDAPRefresh VALUE(0); + /* Next LDAP refresh time */ +VAR char *BrowseLDAPBindDN VALUE(NULL), + /* LDAP login DN */ + *BrowseLDAPDN VALUE(NULL), + /* LDAP search DN */ + *BrowseLDAPPassword VALUE(NULL), + /* LDAP login password */ + *BrowseLDAPServer VALUE(NULL); + /* LDAP server to use */ +VAR int BrowseLDAPUpdate VALUE(TRUE); + /* enables LDAP updates */ +# ifdef HAVE_LDAP_SSL +VAR char *BrowseLDAPCACertFile VALUE(NULL); + /* LDAP CA CERT file to use */ +# endif /* HAVE_LDAP_SSL */ +#endif /* HAVE_LDAP */ +VAR char *LPDConfigFile VALUE(NULL), + /* LPD configuration file */ + *SMBConfigFile VALUE(NULL); + /* SMB configuration file */ + + +/* + * Prototypes... + */ + +extern void cupsdDeregisterPrinter(cupsd_printer_t *p, int removeit); +extern void cupsdLoadRemoteCache(void); +extern void cupsdRegisterPrinter(cupsd_printer_t *p); +extern void cupsdRestartPolling(void); +extern void cupsdSaveRemoteCache(void); +extern void cupsdSendBrowseList(void); +extern void cupsdStartBrowsing(void); +extern void cupsdStartPolling(void); +extern void cupsdStopBrowsing(void); +extern void cupsdStopPolling(void); +#ifdef HAVE_DNSSD +extern void cupsdUpdateDNSSDName(void); +#endif /* HAVE_DNSSD */ +#ifdef HAVE_LDAP +extern void cupsdUpdateLDAPBrowse(void); +#endif /* HAVE_LDAP */ +extern void cupsdUpdateSLPBrowse(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/env.c b/scheduler/env.c new file mode 100644 index 0000000000..19a942a070 --- /dev/null +++ b/scheduler/env.c @@ -0,0 +1,271 @@ +/* + * "$Id$" + * + * Environment management routines for the CUPS scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdInitEnv() - Initialize the current environment with standard + * variables. + * cupsdLoadEnv() - Copy common environment variables into an array. + * cupsdSetEnv() - Set a common environment variable. + * cupsdSetEnvf() - Set a formatted common environment variable. + * cupsdUpdateEnv() - Update the environment for the configured directories. + * clear_env() - Clear common environment variables. + * find_env() - Find a common environment variable. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + + +/* + * Local globals... + */ + +static int num_common_env = 0; /* Number of common env vars */ +static char *common_env[MAX_ENV]; /* Common env vars */ + + +/* + * Local functions... + */ + +static void clear_env(void); +static int find_env(const char *name); + + +/* + * 'cupsdInitEnv()' - Initialize the current environment with standard variables. + */ + +void +cupsdInitEnv(void) +{ + /* + * Clear existing environment variables... + */ + + clear_env(); + +#if defined(__APPLE__) + /* + * Add special voodoo magic for MacOS X - this allows MacOS X + * programs to access their bundle resources properly... + * + * This string is replaced in cupsdStartProcess()... + */ + + cupsdSetString(common_env, ""); + num_common_env = 1; +#endif /* __APPLE__ */ +} + + +/* + * 'cupsdLoadEnv()' - Copy common environment variables into an array. + */ + +int /* O - Number of environment variables */ +cupsdLoadEnv(char *envp[], /* I - Environment array */ + int envmax) /* I - Maximum number of elements */ +{ + int i; /* Looping var */ + + + /* + * Leave room for a NULL pointer at the end... + */ + + envmax --; + + /* + * Copy pointers to the environment... + */ + + for (i = 0; i < num_common_env && i < envmax; i ++) + envp[i] = common_env[i]; + + /* + * NULL terminate the environment array and return the number of + * elements we added... + */ + + envp[i] = NULL; + + return (i); +} + + +/* + * 'cupsdSetEnv()' - Set a common environment variable. + */ + +void +cupsdSetEnv(const char *name, /* I - Name of variable */ + const char *value) /* I - Value of variable */ +{ + int i; /* Index into environent array */ + + + /* + * If "value" is NULL, try getting value from current environment... + */ + + if (!value) + value = getenv(name); + + if (!value) + return; + + /* + * See if this variable has already been defined... + */ + + if ((i = find_env(name)) < 0) + { + /* + * Check for room... + */ + + if (num_common_env >= (int)(sizeof(common_env) / sizeof(common_env[0]))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdSetEnv: Too many environment variables set!"); + return; + } + + i = num_common_env; + num_common_env ++; + } + + /* + * Set the new environment variable... + */ + + cupsdSetStringf(common_env + i, "%s=%s", name, value); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSetEnv: %s", common_env[i]); +} + + +/* + * 'cupsdSetEnvf()' - Set a formatted common environment variable. + */ + +void +cupsdSetEnvf(const char *name, /* I - Name of variable */ + const char *value, /* I - Printf-style value of variable */ + ...) /* I - Additional args as needed */ +{ + char v[4096]; /* Formatting string value */ + va_list ap; /* Argument pointer */ + + + /* + * Format the value string... + */ + + va_start(ap, value); + vsnprintf(v, sizeof(v), value, ap); + va_end(ap); + + /* + * Set the env variable... + */ + + cupsdSetEnv(name, v); +} + + +/* + * 'cupsdUpdateEnv()' - Update the environment for the configured directories. + */ + +void +cupsdUpdateEnv(void) +{ + /* + * Set common variables... + */ + +#define set_if_undefined(name,value) if (find_env(name) < 0) cupsdSetEnv(name,value) + + set_if_undefined("CUPS_CACHEDIR", CacheDir); + set_if_undefined("CUPS_DATADIR", DataDir); + set_if_undefined("CUPS_DOCROOT", DocumentRoot); + set_if_undefined("CUPS_FONTPATH", FontPath); + set_if_undefined("CUPS_REQUESTROOT", RequestRoot); + set_if_undefined("CUPS_SERVERBIN", ServerBin); + set_if_undefined("CUPS_SERVERROOT", ServerRoot); + set_if_undefined("CUPS_STATEDIR", StateDir); + set_if_undefined("DYLD_LIBRARY_PATH", NULL); + set_if_undefined("HOME", TempDir); + set_if_undefined("LD_ASSUME_KERNEL", NULL); + set_if_undefined("LD_LIBRARY_PATH", NULL); + set_if_undefined("LD_PRELOAD", NULL); + set_if_undefined("NLSPATH", NULL); + if (find_env("PATH") < 0) + cupsdSetEnvf("PATH", "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR + ":/bin:/usr/bin", ServerBin); + set_if_undefined("SERVER_ADMIN", ServerAdmin); + set_if_undefined("SHLIB_PATH", NULL); + set_if_undefined("SOFTWARE", CUPS_MINIMAL); + set_if_undefined("TMPDIR", TempDir); + set_if_undefined("TZ", NULL); + set_if_undefined("USER", "root"); + set_if_undefined("VG_ARGS", NULL); +} + + +/* + * 'clear_env()' - Clear common environment variables. + */ + +static void +clear_env(void) +{ + int i; /* Looping var */ + + + for (i = 0; i < num_common_env; i ++) + cupsdClearString(common_env + i); + + num_common_env = 0; +} + + +/* + * 'find_env()' - Find a common environment variable. + */ + +static int /* O - Index or -1 if not found */ +find_env(const char *name) /* I - Variable name */ +{ + int i; /* Looping var */ + size_t namelen; /* Length of name */ + + + for (i = 0, namelen = strlen(name); i < num_common_env; i ++) + if (!strncmp(common_env[i], name, namelen) && common_env[i][namelen] == '=') + return (i); + + return (-1); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/filter.c b/scheduler/filter.c new file mode 100644 index 0000000000..5f1a15a6a3 --- /dev/null +++ b/scheduler/filter.c @@ -0,0 +1,408 @@ +/* + * "$Id$" + * + * File type conversion routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * mimeFilterLookup() - Lookup a filter... + * compare_filters() - Compare two filters... + * find_filters() - Find the filters to convert from one type to another. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + +#include +#include +#include "mime.h" + + +/* + * Local types... + */ + +typedef struct _mime_typelist_s /**** List of source types ****/ +{ + struct _mime_typelist_s *next; /* Next source type */ + mime_type_t *src; /* Source type */ +} _mime_typelist_t; + + +/* + * Local functions... + */ + +static int compare_filters(mime_filter_t *, mime_filter_t *); +static int compare_srcs(mime_filter_t *, mime_filter_t *); +static cups_array_t *find_filters(mime_t *mime, mime_type_t *src, + mime_type_t *dst, int *cost, + _mime_typelist_t *visited); + + +/* + * '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 || !src || !dst || !filter) + return (NULL); + + /* + * See if we already have an existing filter for the given source and + * destination... + */ + + if ((temp = mimeFilterLookup(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->filters) + mime->filters = cupsArrayNew((cups_array_func_t)compare_filters, NULL); + + if (!mime->filters) + return (NULL); + + if ((temp = calloc(1, sizeof(mime_filter_t))) == NULL) + return (NULL); + + /* + * Copy the information over and sort if necessary... + */ + + temp->src = src; + temp->dst = dst; + temp->cost = cost; + strlcpy(temp->filter, filter, sizeof(temp->filter)); + + cupsArrayAdd(mime->filters, temp); + cupsArrayAdd(mime->srcs, temp); + } + + /* + * Return the new/updated filter... + */ + + return (temp); +} + + +/* + * 'mimeFilter()' - Find the fastest way to convert from one type to another. + */ + +cups_array_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 *cost) /* O - Cost of filters */ +{ + /* + * Range-check the input... + */ + + DEBUG_printf(("mimeFilter(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), " + "cost=%p(%d))\n", + mime, src, src ? src->super : "?", src ? src->type : "?", + dst, dst ? dst->super : "?", dst ? dst->type : "?", + cost, cost ? *cost : 0)); + + + if (cost) + *cost = 0; + + if (!mime || !src || !dst) + return (NULL); + + /* + * (Re)build the source lookup array as needed... + */ + + if (!mime->srcs) + { + mime_filter_t *current; /* Current filter */ + + + mime->srcs = cupsArrayNew((cups_array_func_t)compare_srcs, NULL); + + for (current = mimeFirstFilter(mime); + current; + current = mimeNextFilter(mime)) + cupsArrayAdd(mime->srcs, current); + } + + /* + * Find the filters... + */ + + return (find_filters(mime, src, dst, cost, NULL)); +} + + +/* + * 'mimeFilterLookup()' - Lookup a filter... + */ + +mime_filter_t * /* O - Filter for src->dst */ +mimeFilterLookup(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 */ + + + key.src = src; + key.dst = dst; + + return ((mime_filter_t *)cupsArrayFind(mime->filters, &key)); +} + + +/* + * 'compare_filters()' - Compare two filters... + */ + +static int /* O - Comparison result */ +compare_filters(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); +} + + +/* + * 'compare_srcs()' - Compare two srcs... + */ + +static int /* O - Comparison result */ +compare_srcs(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) + i = strcmp(f0->src->type, f1->src->type); + + return (i); +} + + +/* + * 'find_filters()' - Find the filters to convert from one type to another. + */ + +static cups_array_t * /* O - Array of filters to run */ +find_filters(mime_t *mime, /* I - MIME database */ + mime_type_t *src, /* I - Source file type */ + mime_type_t *dst, /* I - Destination file type */ + int *cost, /* O - Cost of filters */ + _mime_typelist_t *list) /* I - Source types we've used */ +{ + int tempcost, /* Temporary cost */ + mincost; /* Current minimum */ + cups_array_t *temp, /* Temporary filter */ + *mintemp; /* Current minimum */ + mime_filter_t *current, /* Current filter */ + srckey; /* Source type key */ + _mime_typelist_t listnode, /* New list node */ + *listptr; /* Pointer in list */ + + + DEBUG_printf(("find_filters(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), " + "cost=%p, list=%p)\n", mime, src, src->super, src->type, + dst, dst->super, dst->type, cost, list)); + + /* + * See if there is a filter that can convert the files directly... + */ + + if ((current = mimeFilterLookup(mime, src, dst)) != NULL) + { + /* + * Got a direct filter! + */ + + DEBUG_puts("find_filters: Direct filter found!"); + + if ((mintemp = cupsArrayNew(NULL, NULL)) == NULL) + return (NULL); + + cupsArrayAdd(mintemp, current); + + mincost = current->cost; + + if (!cost) + return (mintemp); + + DEBUG_puts("find_filters: Found direct filter:"); + DEBUG_printf(("find_filters: %s (cost=%d)\n", current->filter, mincost)); + } + else + { + /* + * No direct filter... + */ + + mintemp = NULL; + mincost = 9999999; + } + + /* + * Initialize this node in the type list... + */ + + listnode.next = list; + + /* + * OK, now look for filters from the source type to any other type... + */ + + srckey.src = src; + + for (current = (mime_filter_t *)cupsArrayFind(mime->srcs, &srckey); + current && current->src == src; + current = (mime_filter_t *)cupsArrayNext(mime->srcs)) + { + /* + * See if we have already tried the destination type as a source + * type (this avoids extra filter looping...) + */ + + mime_type_t *current_dst; /* Current destination type */ + + + for (listptr = list, current_dst = current->dst; + listptr; + listptr = listptr->next) + if (current_dst == listptr->src) + break; + + if (listptr) + continue; + + /* + * See if we have any filters that can convert from the destination type + * of this filter to the final type... + */ + + listnode.src = current->src; + + cupsArraySave(mime->srcs); + temp = find_filters(mime, current->dst, dst, &tempcost, &listnode); + cupsArrayRestore(mime->srcs); + + if (!temp) + continue; + + if (!cost) + return (temp); + + /* + * Found a match; see if this one is less costly than the last (if + * any...) + */ + + tempcost += current->cost; + + if (tempcost < mincost) + { + cupsArrayDelete(mintemp); + + /* + * Hey, we got a match! Add the current filter to the beginning of the + * filter list... + */ + + mintemp = temp; + mincost = tempcost; + cupsArrayInsert(mintemp, current); + } + else + cupsArrayDelete(temp); + } + + if (mintemp) + { + /* + * Hey, we got a match! + */ + +#ifdef DEBUG + DEBUG_printf(("find_filters: Returning %d filters:\n", + cupsArrayCount(mintemp))); + + for (current = (mime_filter_t *)cupsArrayFirst(mintemp); + current; + current = (mime_filter_t *)cupsArrayNext(mintemp)) + DEBUG_printf(("find_filters: %s\n", current->filter)); +#endif /* DEBUG */ + + if (cost) + *cost = mincost; + + return (mintemp); + } + + DEBUG_puts("find_filters: Returning zippo..."); + + return (NULL); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/ipp.c b/scheduler/ipp.c new file mode 100644 index 0000000000..5d0ace3603 --- /dev/null +++ b/scheduler/ipp.c @@ -0,0 +1,11619 @@ +/* + * "$Id$" + * + * IPP routines for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * This file contains Kerberos support code, copyright 2006 by + * Jelmer Vernooij. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdProcessIPPRequest() - Process an incoming IPP request. + * cupsdTimeoutJob() - Timeout a job waiting on job files. + * 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() - Add a job to a print queue. + * add_job_state_reasons() - Add the "job-state-reasons" attribute based + * upon the job and printer state... + * add_job_subscriptions() - Add any subscriptions for a job. + * add_job_uuid() - Add job-uuid attribute to a job. + * 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 the + * specified printer or class. + * apple_init_profile() - Initialize a color profile. + * apple_register_profiles() - Register color profiles for a printer. + * apple_unregister_profiles() - Remove color profiles for the specified + * printer. + * apply_printer_defaults() - Apply printer default options to a job. + * authenticate_job() - Set job authentication info. + * cancel_all_jobs() - Cancel all print jobs. + * cancel_job() - Cancel a print job. + * cancel_subscription() - Cancel a subscription. + * check_quotas() - Check quotas for a printer and user. + * check_rss_recipient() - Check that we do not have a duplicate RSS + * feed URI. + * copy_attribute() - Copy a single attribute. + * copy_attrs() - Copy attributes from one request to another. + * copy_banner() - Copy a banner file to the requests directory + * for the specified job. + * copy_file() - Copy a PPD file or interface script... + * copy_model() - Copy a PPD model file, substituting default + * values as needed... + * copy_job_attrs() - Copy job attributes. + * copy_printer_attrs() - Copy printer attributes. + * copy_subscription_attrs() - Copy subscription attributes. + * create_job() - Print a file to a printer or class. + * create_requested_array() - Create an array for the requested-attributes. + * create_subscription() - Create a notification subscription. + * 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_document() - Get a copy of a job file. + * get_job_attrs() - Get job attributes. + * get_jobs() - Get a list of jobs for the specified printer. + * get_notifications() - Get events for a subscription. + * get_ppd() - Get a named PPD from the local system. + * 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 or classes. + * get_subscription_attrs() - Get subscription attributes. + * get_subscriptions() - Get subscriptions. + * get_username() - Get the username associated with a request. + * hold_job() - Hold a print job. + * move_job() - Move a job to a new destination. + * ppd_parse_line() - Parse a PPD default line. + * print_job() - Print a file to a printer or class. + * read_job_ticket() - Read a job ticket embedded in a print file. + * reject_jobs() - Reject print jobs to a printer. + * release_job() - Release a held print job. + * renew_subscription() - Renew an existing subscription... + * restart_job() - Restart an old print job. + * save_auth_info() - Save authentication information for a job. + * save_krb5_creds() - Save Kerberos credentials for the job. + * send_document() - Send a file to a printer or class. + * send_http_error() - Send a HTTP error back to the IPP client. + * send_ipp_status() - Send a status back to the IPP client. + * set_default() - Set the default destination... + * set_job_attrs() - Set job attributes. + * set_printer_attrs() - Set printer attributes. + * set_printer_defaults() - Set printer default options from a request. + * start_printer() - Start a printer. + * stop_printer() - Stop a printer. + * url_encode_attr() - URL-encode a string attribute. + * url_encode_string() - URL-encode a string. + * user_allowed() - See if a user is allowed to print to a queue. + * validate_job() - Validate printer options and destination. + * validate_name() - Make sure the printer name only contains + * valid chars. + * validate_user() - Validate the user for the request. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include + +#ifdef __APPLE__ +# include +# include +# ifdef HAVE_MEMBERSHIP_H +# include +# endif /* HAVE_MEMBERSHIP_H */ +# ifdef HAVE_MEMBERSHIPPRIV_H +# include +# else +extern int mbr_user_name_to_uuid(const char* name, uuid_t uu); +extern int mbr_group_name_to_uuid(const char* name, uuid_t uu); +extern int mbr_check_membership_by_id(uuid_t user, gid_t group, int* ismember); +# endif /* HAVE_MEMBERSHIPPRIV_H */ +#endif /* __APPLE__ */ + + +/* + * Local functions... + */ + +static void accept_jobs(cupsd_client_t *con, ipp_attribute_t *uri); +static void add_class(cupsd_client_t *con, ipp_attribute_t *uri); +static int add_file(cupsd_client_t *con, cupsd_job_t *job, + mime_type_t *filetype, int compression); +static cupsd_job_t *add_job(cupsd_client_t *con, cupsd_printer_t *printer, + mime_type_t *filetype); +static void add_job_state_reasons(cupsd_client_t *con, cupsd_job_t *job); +static void add_job_subscriptions(cupsd_client_t *con, cupsd_job_t *job); +static void add_job_uuid(cupsd_client_t *con, cupsd_job_t *job); +static void add_printer(cupsd_client_t *con, ipp_attribute_t *uri); +static void add_printer_state_reasons(cupsd_client_t *con, + cupsd_printer_t *p); +static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p); +#ifdef __APPLE__ +static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages, + CMDeviceProfileInfo *profile, unsigned id, + const char *name, const char *text, + const char *iccfile); +static void apple_register_profiles(cupsd_printer_t *p); +static void apple_unregister_profiles(cupsd_printer_t *p); +#endif /* __APPLE__ */ +static void apply_printer_defaults(cupsd_printer_t *printer, + cupsd_job_t *job); +static void authenticate_job(cupsd_client_t *con, ipp_attribute_t *uri); +static void cancel_all_jobs(cupsd_client_t *con, ipp_attribute_t *uri); +static void cancel_job(cupsd_client_t *con, ipp_attribute_t *uri); +static void cancel_subscription(cupsd_client_t *con, int id); +static int check_rss_recipient(const char *recipient); +static int check_quotas(cupsd_client_t *con, cupsd_printer_t *p); +static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr, + int quickcopy); +static void copy_attrs(ipp_t *to, ipp_t *from, cups_array_t *ra, + ipp_tag_t group, int quickcopy); +static int copy_banner(cupsd_client_t *con, cupsd_job_t *job, + const char *name); +static int copy_file(const char *from, const char *to); +static int copy_model(cupsd_client_t *con, const char *from, + const char *to); +static void copy_job_attrs(cupsd_client_t *con, + cupsd_job_t *job, + cups_array_t *ra); +static void copy_printer_attrs(cupsd_client_t *con, + cupsd_printer_t *printer, + cups_array_t *ra); +static void copy_subscription_attrs(cupsd_client_t *con, + cupsd_subscription_t *sub, + cups_array_t *ra); +static void create_job(cupsd_client_t *con, ipp_attribute_t *uri); +static cups_array_t *create_requested_array(ipp_t *request); +static void create_subscription(cupsd_client_t *con, ipp_attribute_t *uri); +static void delete_printer(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_default(cupsd_client_t *con); +static void get_devices(cupsd_client_t *con); +static void get_document(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_jobs(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_notifications(cupsd_client_t *con); +static void get_ppd(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_ppds(cupsd_client_t *con); +static void get_printers(cupsd_client_t *con, int type); +static void get_printer_attrs(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_printer_supported(cupsd_client_t *con, ipp_attribute_t *uri); +static void get_subscription_attrs(cupsd_client_t *con, int sub_id); +static void get_subscriptions(cupsd_client_t *con, ipp_attribute_t *uri); +static const char *get_username(cupsd_client_t *con); +static void hold_job(cupsd_client_t *con, ipp_attribute_t *uri); +static void hold_new_jobs(cupsd_client_t *con, ipp_attribute_t *uri); +static void move_job(cupsd_client_t *con, ipp_attribute_t *uri); +static int ppd_parse_line(const char *line, char *option, int olen, + char *choice, int clen); +static void print_job(cupsd_client_t *con, ipp_attribute_t *uri); +static void read_job_ticket(cupsd_client_t *con); +static void reject_jobs(cupsd_client_t *con, ipp_attribute_t *uri); +static void release_held_new_jobs(cupsd_client_t *con, + ipp_attribute_t *uri); +static void release_job(cupsd_client_t *con, ipp_attribute_t *uri); +static void renew_subscription(cupsd_client_t *con, int sub_id); +static void restart_job(cupsd_client_t *con, ipp_attribute_t *uri); +static void save_auth_info(cupsd_client_t *con, cupsd_job_t *job, + ipp_attribute_t *auth_info); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H) +static void save_krb5_creds(cupsd_client_t *con, cupsd_job_t *job); +#endif /* HAVE_GSSAPI && HAVE_KRB5_H */ +static void send_document(cupsd_client_t *con, ipp_attribute_t *uri); +static void send_http_error(cupsd_client_t *con, http_status_t status, + cupsd_printer_t *printer); +static void send_ipp_status(cupsd_client_t *con, ipp_status_t status, + const char *message, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +# endif /* __GNUC__ */ +; +static void set_default(cupsd_client_t *con, ipp_attribute_t *uri); +static void set_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri); +static void set_printer_attrs(cupsd_client_t *con, ipp_attribute_t *uri); +static void set_printer_defaults(cupsd_client_t *con, + cupsd_printer_t *printer); +static void start_printer(cupsd_client_t *con, ipp_attribute_t *uri); +static void stop_printer(cupsd_client_t *con, ipp_attribute_t *uri); +static void url_encode_attr(ipp_attribute_t *attr, char *buffer, + int bufsize); +static char *url_encode_string(const char *s, char *buffer, int bufsize); +static int user_allowed(cupsd_printer_t *p, const char *username); +static void validate_job(cupsd_client_t *con, ipp_attribute_t *uri); +static int validate_name(const char *name); +static int validate_user(cupsd_job_t *job, cupsd_client_t *con, + const char *owner, char *username, + int userlen); + + +/* + * 'cupsdProcessIPPRequest()' - Process an incoming IPP request. + */ + +int /* O - 1 on success, 0 on failure */ +cupsdProcessIPPRequest( + cupsd_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 = NULL; /* Printer or job URI attribute */ + ipp_attribute_t *username; /* requesting-user-name attr */ + int sub_id; /* Subscription ID */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdProcessIPPRequest(%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 && + con->request->request.any.version[0] != 2) + { + /* + * Return an error, since we only support IPP 1.x and 2.x. + */ + + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Bad request version number %d.%d", + IPP_VERSION_NOT_SUPPORTED, con->http.hostname, + con->request->request.any.version[0], + con->request->request.any.version[1]); + + send_ipp_status(con, IPP_VERSION_NOT_SUPPORTED, + _("Bad request version number %d.%d!"), + con->request->request.any.version[0], + con->request->request.any.version[1]); + } + else if (con->request->request.any.request_id < 1) + { + /* + * Return an error, since request IDs must be between 1 and 2^31-1 + */ + + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Bad request ID %d", + IPP_BAD_REQUEST, con->http.hostname, + con->request->request.any.request_id); + + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d!"), + con->request->request.any.request_id); + } + else if (!con->request->attrs) + { + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s No attributes in request", + IPP_BAD_REQUEST, con->http.hostname); + + send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in 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; + attr = attr->next) + if (attr->group_tag < group && attr->group_tag != IPP_TAG_ZERO) + { + /* + * Out of order; return an error... + */ + + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Attribute groups are out of order", + IPP_BAD_REQUEST, con->http.hostname); + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Attribute groups are out of order (%x < %x)!"), + attr->group_tag, group); + break; + } + else + group = attr->group_tag; + + if (!attr) + { + /* + * Then make sure that the first three attributes are: + * + * attributes-charset + * attributes-natural-language + * printer-uri/job-uri + */ + + attr = con->request->attrs; + if (attr && attr->name && + !strcmp(attr->name, "attributes-charset") && + (attr->value_tag & IPP_TAG_MASK) == IPP_TAG_CHARSET) + charset = attr; + else + charset = NULL; + + if (attr) + attr = attr->next; + + if (attr && attr->name && + !strcmp(attr->name, "attributes-natural-language") && + (attr->value_tag & IPP_TAG_MASK) == 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 if (con->request->request.op.operation_id == CUPS_GET_PPD) + uri = ippFindAttribute(con->request, "ppd-name", IPP_TAG_NAME); + 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, "utf-8"); + + 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 && + strcasecmp(charset->values[0].string.text, "us-ascii") && + strcasecmp(charset->values[0].string.text, "utf-8")) + { + /* + * Bad character set... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "Unsupported character set \"%s\"!", + charset->values[0].string.text); + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Unsupported attributes-charset value \"%s\"", + IPP_CHARSET, con->http.hostname, + charset->values[0].string.text); + send_ipp_status(con, IPP_BAD_REQUEST, + _("Unsupported character set \"%s\"!"), + charset->values[0].string.text); + } + else if (!charset || !language || + (!uri && + 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) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing attributes-charset attribute!"); + + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Missing attributes-charset attribute", + IPP_BAD_REQUEST, con->http.hostname); + } + + if (!language) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing attributes-natural-language attribute!"); + + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Missing attributes-natural-language attribute", + IPP_BAD_REQUEST, con->http.hostname); + } + + if (!uri) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing printer-uri, job-uri, or ppd-name " + "attribute!"); + + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Missing printer-uri, job-uri, or ppd-name " + "attribute", IPP_BAD_REQUEST, con->http.hostname); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Request attributes follow..."); + + for (attr = con->request->attrs; attr; attr = attr->next) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "attr \"%s\": group_tag = %x, value_tag = %x", + attr->name ? attr->name : "(null)", attr->group_tag, + attr->value_tag); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "End of attributes..."); + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Missing required attributes!")); + } + 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") && + strcasecmp(con->http.hostname, "localhost") && + strcmp(con->username, "root")) + { + /* + * Remote unauthenticated user masquerading as local root... + */ + + _cupsStrFree(username->values[0].string.text); + username->values[0].string.text = _cupsStrAlloc(RemoteRoot); + } + } + + if ((attr = ippFindAttribute(con->request, "notify-subscription-id", + IPP_TAG_INTEGER)) != NULL) + sub_id = attr->values[0].integer; + else + sub_id = 0; + + /* + * Then try processing the operation... + */ + + if (uri) + cupsdLogMessage(CUPSD_LOG_DEBUG, "%s %s", + ippOpString(con->request->request.op.operation_id), + uri->values[0].string.text); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "%s", + ippOpString(con->request->request.op.operation_id)); + + 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_GET_PRINTER_SUPPORTED_VALUES : + get_printer_supported(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 IPP_SET_PRINTER_ATTRIBUTES : + set_printer_attrs(con, uri); + break; + + case IPP_HOLD_NEW_JOBS : + hold_new_jobs(con, uri); + break; + + case IPP_RELEASE_HELD_NEW_JOBS : + release_held_new_jobs(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_DOCUMENT : + get_document(con, uri); + break; + + case CUPS_GET_PPD : + get_ppd(con, uri); + break; + + case CUPS_GET_PPDS : + get_ppds(con); + break; + + case CUPS_MOVE_JOB : + move_job(con, uri); + break; + + case CUPS_AUTHENTICATE_JOB : + authenticate_job(con, uri); + break; + + case IPP_CREATE_PRINTER_SUBSCRIPTION : + case IPP_CREATE_JOB_SUBSCRIPTION : + create_subscription(con, uri); + break; + + case IPP_GET_SUBSCRIPTION_ATTRIBUTES : + get_subscription_attrs(con, sub_id); + break; + + case IPP_GET_SUBSCRIPTIONS : + get_subscriptions(con, uri); + break; + + case IPP_RENEW_SUBSCRIPTION : + renew_subscription(con, sub_id); + break; + + case IPP_CANCEL_SUBSCRIPTION : + cancel_subscription(con, sub_id); + break; + + case IPP_GET_NOTIFICATIONS : + get_notifications(con); + break; + + default : + cupsdAddEvent(CUPSD_EVENT_SERVER_AUDIT, NULL, NULL, + "%04X %s Operation %04X (%s) not supported", + IPP_OPERATION_NOT_SUPPORTED, con->http.hostname, + con->request->request.op.operation_id, + ippOpString(con->request->request.op.operation_id)); + + send_ipp_status(con, IPP_OPERATION_NOT_SUPPORTED, + _("%s not supported!"), + ippOpString( + con->request->request.op.operation_id)); + break; + } + } + } + } + + if (con->response) + { + /* + * Sending data from the scheduler... + */ + + cupsdLogMessage(con->response->request.status.status_code + >= IPP_BAD_REQUEST && + con->response->request.status.status_code + != IPP_NOT_FOUND ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG, + "Returning IPP %s for %s (%s) from %s", + ippErrorString(con->response->request.status.status_code), + ippOpString(con->request->request.op.operation_id), + uri ? uri->values[0].string.text : "no URI", + con->http.hostname); + + if (LogLevel == CUPSD_LOG_DEBUG2) + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdProcessIPPRequest: ippLength(response)=%ld", + (long)ippLength(con->response)); + + if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE)) + { +#ifdef CUPSD_USE_CHUNKING + /* + * Because older versions of CUPS (1.1.17 and older) and some IPP + * clients do not implement chunking properly, we cannot use + * chunking by default. This may become the default in future + * CUPS releases, or we might add a configuration directive for + * it. + */ + + if (con->http.version == HTTP_1_1) + { + if (httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n\r\n") < 0) + return (0); + + if (cupsdFlushHeader(con) < 0) + return (0); + + con->http.data_encoding = HTTP_ENCODE_CHUNKED; + } + else +#endif /* CUPSD_USE_CHUNKING */ + { + size_t length; /* Length of response */ + + + length = ippLength(con->response); + + if (con->file >= 0 && !con->pipe_pid) + { + struct stat fileinfo; /* File information */ + + + if (!fstat(con->file, &fileinfo)) + length += fileinfo.st_size; + } + + if (httpPrintf(HTTP(con), "Content-Length: " CUPS_LLFMT "\r\n\r\n", + CUPS_LLCAST length) < 0) + return (0); + + if (cupsdFlushHeader(con) < 0) + return (0); + + con->http.data_encoding = HTTP_ENCODE_LENGTH; + con->http.data_remaining = length; + + if (con->http.data_remaining <= INT_MAX) + con->http._data_remaining = con->http.data_remaining; + else + con->http._data_remaining = INT_MAX; + } + + cupsdAddSelect(con->http.fd, (cupsd_selfunc_t)cupsdReadClient, + (cupsd_selfunc_t)cupsdWriteClient, con); + + /* + * Tell the caller the response header was sent successfully... + */ + + return (1); + } + else + { + /* + * Tell the caller the response header could not be sent... + */ + + return (0); + } + } + else + { + /* + * Sending data from a subprocess like cups-deviced; tell the caller + * everything is A-OK so far... + */ + + return (1); + } +} + + +/* + * 'cupsdTimeoutJob()' - Timeout a job waiting on job files. + */ + +int /* O - 0 on success, -1 on error */ +cupsdTimeoutJob(cupsd_job_t *job) /* I - Job to timeout */ +{ + cupsd_printer_t *printer; /* Destination printer or class */ + ipp_attribute_t *attr; /* job-sheets attribute */ + int kbytes; /* Kilobytes in banner */ + + + job->pending_timeout = 0; + + /* + * See if we need to add the ending sheet... + */ + + if (!cupsdLoadJob(job)) + return (-1); + + printer = cupsdFindDest(job->dest); + attr = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME); + + if (printer && + !(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) && + attr && attr->num_values > 1) + { + /* + * Yes... + */ + + cupsdLogJob(job, CUPSD_LOG_INFO, "Adding end banner page \"%s\".", + attr->values[1].string.text); + + if ((kbytes = copy_banner(NULL, job, attr->values[1].string.text)) < 0) + return (-1); + + cupsdUpdateQuota(printer, job->username, 0, kbytes); + } + + return (0); +} + + +/* + * 'accept_jobs()' - Accept print jobs to a printer. + */ + +static void +accept_jobs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer or class URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "accept_jobs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Accept jobs sent to the printer... + */ + + printer->accepting = 1; + printer->state_message[0] = '\0'; + + cupsdAddPrinterHistory(printer); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, + "Now accepting jobs."); + + if (dtype & CUPS_PRINTER_CLASS) + { + cupsdMarkDirty(CUPSD_DIRTY_CLASSES); + + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" now accepting jobs (\"%s\").", + printer->name, get_username(con)); + } + else + { + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Printer \"%s\" now accepting jobs (\"%s\").", + printer->name, get_username(con)); + } + + /* + * 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(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - URI of class */ +{ + http_status_t status; /* Policy status */ + int i; /* Looping var */ + char scheme[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 */ + cupsd_printer_t *pclass, /* Class */ + *member; /* Member printer/class */ + cups_ptype_t dtype; /* Destination type */ + ipp_attribute_t *attr; /* Printer attribute */ + int modify; /* Non-zero if we just modified */ + char newname[IPP_MAX_NAME]; /* New class name */ + int need_restart_job; /* Need to restart job? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_class(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Do we have a valid URI? + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + + if (strncmp(resource, "/classes/", 9) || strlen(resource) == 9) + { + /* + * No, return an error... + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri must be of the form " + "\"ipp://HOSTNAME/classes/CLASSNAME\".")); + return; + } + + /* + * Do we have a valid printer name? + */ + + if (!validate_name(resource + 9)) + { + /* + * No, return an error... + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri \"%s\" contains invalid characters."), + uri->values[0].string.text); + return; + } + + /* + * See if the class already exists; if not, create a new class... + */ + + if ((pclass = cupsdFindClass(resource + 9)) == NULL) + { + /* + * Class doesn't exist; see if we have a printer of the same name... + */ + + if ((pclass = cupsdFindPrinter(resource + 9)) != NULL && + !(pclass->type & CUPS_PRINTER_DISCOVERED)) + { + /* + * Yes, return an error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("A printer named \"%s\" already exists!"), + resource + 9); + return; + } + + /* + * No, check the default policy and then add the class... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + pclass = cupsdAddClass(resource + 9); + modify = 0; + } + else if (pclass->type & CUPS_PRINTER_IMPLICIT) + { + /* + * Check the default policy, then rename the implicit class to "AnyClass" + * or remove it... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + if (ImplicitAnyClasses) + { + snprintf(newname, sizeof(newname), "Any%s", resource + 9); + cupsdRenamePrinter(pclass, newname); + } + else + cupsdDeletePrinter(pclass, 1); + + /* + * Add the class as a new local class... + */ + + pclass = cupsdAddClass(resource + 9); + modify = 0; + } + else if (pclass->type & CUPS_PRINTER_DISCOVERED) + { + /* + * Check the default policy, then rename the remote class to "Class"... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + snprintf(newname, sizeof(newname), "%s@%s", resource + 9, pclass->hostname); + cupsdRenamePrinter(pclass, newname); + + /* + * Add the class as a new local class... + */ + + pclass = cupsdAddClass(resource + 9); + modify = 0; + } + else if ((status = cupsdCheckPolicy(pclass->op_policy_ptr, con, + NULL)) != HTTP_OK) + { + send_http_error(con, status, pclass); + return; + } + else + modify = 1; + + /* + * Look for attributes and copy them over as needed... + */ + + need_restart_job = 0; + + if ((attr = ippFindAttribute(con->request, "printer-location", + IPP_TAG_TEXT)) != NULL) + cupsdSetString(&pclass->location, attr->values[0].string.text); + + if ((attr = ippFindAttribute(con->request, "printer-info", + IPP_TAG_TEXT)) != NULL) + cupsdSetString(&pclass->info, attr->values[0].string.text); + + if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean != pclass->accepting) + { + cupsdLogMessage(CUPSD_LOG_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; + cupsdAddPrinterHistory(pclass); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s accepting jobs.", + pclass->accepting ? "Now" : "No longer"); + } + + if ((attr = ippFindAttribute(con->request, "printer-is-shared", + IPP_TAG_BOOLEAN)) != NULL) + { + if (pclass->shared && !attr->values[0].boolean) + cupsdDeregisterPrinter(pclass, 1); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s printer-is-shared to %d (was %d.)", + pclass->name, attr->values[0].boolean, pclass->shared); + + pclass->shared = attr->values[0].boolean; + } + + if ((attr = ippFindAttribute(con->request, "printer-state", + IPP_TAG_ENUM)) != NULL) + { + if (attr->values[0].integer != IPP_PRINTER_IDLE && + attr->values[0].integer != IPP_PRINTER_STOPPED) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Attempt to set %s printer-state to bad value %d!"), + pclass->name, attr->values[0].integer); + return; + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-state to %d (was %d.)", + pclass->name, attr->values[0].integer, pclass->state); + + if (attr->values[0].integer == IPP_PRINTER_STOPPED) + cupsdStopPrinter(pclass, 0); + else + { + cupsdSetPrinterState(pclass, (ipp_pstate_t)(attr->values[0].integer), 0); + need_restart_job = 1; + } + } + 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)); + cupsdAddPrinterHistory(pclass); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s", + pclass->state_message); + } + if ((attr = ippFindAttribute(con->request, "member-uris", + IPP_TAG_URI)) != NULL) + { + /* + * Clear the printer array as needed... + */ + + need_restart_job = 1; + + 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... + */ + + if (!cupsdValidateDest(attr->values[i].string.text, &dtype, &member)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + else if (dtype & CUPS_PRINTER_CLASS) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Nested classes are not allowed!")); + return; + } + + /* + * Add it to the class... + */ + + cupsdAddPrinterToClass(pclass, member); + } + } + + set_printer_defaults(con, pclass); + + if ((attr = ippFindAttribute(con->request, "auth-info-required", + IPP_TAG_KEYWORD)) != NULL) + cupsdSetAuthInfoRequired(pclass, NULL, attr); + + /* + * Update the printer class attributes and return... + */ + + cupsdSetPrinterAttrs(pclass); + cupsdMarkDirty(CUPSD_DIRTY_CLASSES); + + if (need_restart_job && pclass->job) + { + /* + * Reset the current job to a "pending" status... + */ + + cupsdSetJobState(pclass->job, IPP_JOB_PENDING, CUPSD_JOB_FORCE, + "Job restarted because the class was modified."); + } + + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); + + if (modify) + { + cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, + pclass, NULL, "Class \"%s\" modified by \"%s\".", + pclass->name, get_username(con)); + + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" modified by \"%s\".", + pclass->name, get_username(con)); + } + else + { + cupsdAddPrinterHistory(pclass); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, + pclass, NULL, "New class \"%s\" added by \"%s\".", + pclass->name, get_username(con)); + + cupsdLogMessage(CUPSD_LOG_INFO, "New class \"%s\" added by \"%s\".", + pclass->name, get_username(con)); + } + + 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(cupsd_client_t *con, /* I - Connection to client */ + cupsd_job_t *job, /* I - Job to add to */ + mime_type_t *filetype, /* I - Type of file */ + int compression) /* I - Compression */ +{ + mime_type_t **filetypes; /* New filetypes array... */ + int *compressions; /* New compressions array... */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_file(con=%p[%d], job=%d, filetype=%s/%s, " + "compression=%d)", con, con ? con->http.fd : -1, job->id, + filetype->super, filetype->type, compression); + + /* + * Add the file to the job... + */ + + if (job->num_files == 0) + { + compressions = (int *)malloc(sizeof(int)); + filetypes = (mime_type_t **)malloc(sizeof(mime_type_t *)); + } + else + { + compressions = (int *)realloc(job->compressions, + (job->num_files + 1) * sizeof(int)); + filetypes = (mime_type_t **)realloc(job->filetypes, + (job->num_files + 1) * + sizeof(mime_type_t *)); + } + + if (!compressions || !filetypes) + { + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_PURGE, + "Job aborted because the scheduler ran out of memory."); + + if (con) + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to allocate memory for file types!")); + + return (-1); + } + + job->compressions = compressions; + job->compressions[job->num_files] = compression; + job->filetypes = filetypes; + job->filetypes[job->num_files] = filetype; + + job->num_files ++; + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + + return (0); +} + + +/* + * 'add_job()' - Add a job to a print queue. + */ + +static cupsd_job_t * /* O - Job object */ +add_job(cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *printer, /* I - Destination printer */ + mime_type_t *filetype) /* I - First print file type, if any */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr, /* Current attribute */ + *auth_info; /* auth-info attribute */ + const char *val; /* Default option value */ + int priority; /* Job priority */ + cupsd_job_t *job; /* Current job */ + char job_uri[HTTP_MAX_URI]; /* Job URI */ + int kbytes; /* Size of print file */ + int i; /* Looping var */ + int lowerpagerange; /* Page range bound */ + int exact; /* Did we have an exact match? */ + ipp_attribute_t *media_col, /* media-col attribute */ + *media_margin; /* media-*-margin attribute */ + ipp_t *unsup_col; /* media-col in unsupported response */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))", + con, con->http.fd, printer, printer->name, + filetype, filetype ? filetype->super : "none", + filetype ? filetype->type : "none"); + + /* + * Check remote printing to non-shared printer... + */ + + if (!printer->shared && + strcasecmp(con->http.hostname, "localhost") && + strcasecmp(con->http.hostname, ServerName)) + { + send_ipp_status(con, IPP_NOT_AUTHORIZED, + _("The printer or class is not shared!")); + return (NULL); + } + + /* + * Check policy... + */ + + auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT); + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return (NULL); + } + else if (printer->num_auth_info_required == 1 && + !strcmp(printer->auth_info_required[0], "negotiate") && + !con->username[0]) + { + send_http_error(con, HTTP_UNAUTHORIZED, printer); + return (NULL); + } +#ifdef HAVE_SSL + else if (auth_info && !con->http.tls && + !httpAddrLocalhost(con->http.hostaddr)) + { + /* + * Require encryption of auth-info over non-local connections... + */ + + send_http_error(con, HTTP_UPGRADE_REQUIRED, printer); + return (NULL); + } +#endif /* HAVE_SSL */ + + /* + * See if the printer is accepting jobs... + */ + + if (!printer->accepting) + { + send_ipp_status(con, IPP_NOT_ACCEPTING, + _("Destination \"%s\" is not accepting jobs."), + printer->name); + return (NULL); + } + + /* + * Validate job template attributes; for now just document-format, + * copies, number-up, and page-ranges... + */ + + if (filetype && printer->filetypes && + !cupsArrayFind(printer->filetypes, filetype)) + { + char mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2]; + /* MIME media type string */ + + + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); + + send_ipp_status(con, IPP_DOCUMENT_FORMAT, + _("Unsupported format \'%s\'!"), mimetype); + + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); + + return (NULL); + } + + if ((attr = ippFindAttribute(con->request, "copies", + IPP_TAG_INTEGER)) != NULL) + { + if (attr->values[0].integer < 1 || attr->values[0].integer > MaxCopies) + { + send_ipp_status(con, IPP_ATTRIBUTES, _("Bad copies value %d."), + attr->values[0].integer); + ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, + "copies", attr->values[0].integer); + return (NULL); + } + } + + if ((attr = ippFindAttribute(con->request, "job-sheets", + IPP_TAG_ZERO)) != NULL) + { + if (attr->value_tag != IPP_TAG_KEYWORD && + attr->value_tag != IPP_TAG_NAME) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type!")); + return (NULL); + } + + if (attr->num_values > 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Too many job-sheets values (%d > 2)!"), + attr->num_values); + return (NULL); + } + + for (i = 0; i < attr->num_values; i ++) + if (strcmp(attr->values[i].string.text, "none") && + !cupsdFindBanner(attr->values[i].string.text)) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\"!"), + attr->values[i].string.text); + return (NULL); + } + } + + if ((attr = ippFindAttribute(con->request, "number-up", + IPP_TAG_INTEGER)) != NULL) + { + if (attr->values[0].integer != 1 && + attr->values[0].integer != 2 && + attr->values[0].integer != 4 && + attr->values[0].integer != 6 && + attr->values[0].integer != 9 && + attr->values[0].integer != 16) + { + send_ipp_status(con, IPP_ATTRIBUTES, _("Bad number-up value %d."), + attr->values[0].integer); + ippAddInteger(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, + "number-up", attr->values[0].integer); + return (NULL); + } + } + + if ((attr = ippFindAttribute(con->request, "page-ranges", + IPP_TAG_RANGE)) != NULL) + { + for (i = 0, lowerpagerange = 1; i < attr->num_values; i ++) + { + if (attr->values[i].range.lower < lowerpagerange || + attr->values[i].range.lower > attr->values[i].range.upper) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad page-ranges values %d-%d."), + attr->values[i].range.lower, + attr->values[i].range.upper); + return (NULL); + } + + lowerpagerange = attr->values[i].range.upper + 1; + } + } + + /* + * Do media selection as needed... + */ + + if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) && + !ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) && + _pwgGetPageSize(printer->pwg, con->request, NULL, &exact)) + { + if (!exact && + (media_col = ippFindAttribute(con->request, "media-col", + IPP_TAG_BEGIN_COLLECTION)) != NULL) + { + send_ipp_status(con, IPP_OK_SUBST, _("Unsupported margins.")); + + unsup_col = ippNew(); + if ((media_margin = ippFindAttribute(media_col->values[0].collection, + "media-bottom-margin", + IPP_TAG_INTEGER)) != NULL) + ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, + "media-bottom-margin", media_margin->values[0].integer); + + if ((media_margin = ippFindAttribute(media_col->values[0].collection, + "media-left-margin", + IPP_TAG_INTEGER)) != NULL) + ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, + "media-left-margin", media_margin->values[0].integer); + + if ((media_margin = ippFindAttribute(media_col->values[0].collection, + "media-right-margin", + IPP_TAG_INTEGER)) != NULL) + ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, + "media-right-margin", media_margin->values[0].integer); + + if ((media_margin = ippFindAttribute(media_col->values[0].collection, + "media-top-margin", + IPP_TAG_INTEGER)) != NULL) + ippAddInteger(unsup_col, IPP_TAG_ZERO, IPP_TAG_INTEGER, + "media-top-margin", media_margin->values[0].integer); + + ippAddCollection(con->response, IPP_TAG_UNSUPPORTED_GROUP, "media-col", + unsup_col); + ippDelete(unsup_col); + } + } + + /* + * Make sure we aren't over our limit... + */ + + if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) + cupsdCleanJobs(); + + if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Too many active jobs.")); + return (NULL); + } + + if ((i = check_quotas(con, printer)) < 0) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached.")); + return (NULL); + } + else if (i == 0) + { + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Not allowed to print.")); + return (NULL); + } + + /* + * Create the job and set things up... + */ + + if ((attr = ippFindAttribute(con->request, "job-priority", + IPP_TAG_INTEGER)) != NULL) + priority = attr->values[0].integer; + else + { + if ((val = cupsGetOption("job-priority", printer->num_options, + printer->options)) != NULL) + priority = atoi(val); + else + priority = 50; + + ippAddInteger(con->request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-priority", + priority); + } + + if (!ippFindAttribute(con->request, "job-name", IPP_TAG_NAME)) + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, + "Untitled"); + + if ((job = cupsdAddJob(priority, printer->name)) == NULL) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to add job for destination \"%s\"!"), + printer->name); + return (NULL); + } + + job->dtype = printer->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE); + job->attrs = con->request; + job->dirty = 1; + con->request = ippNewRequest(job->attrs->request.op.operation_id); + + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + + add_job_uuid(con, job); + apply_printer_defaults(printer, job); + + attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME); + + if (con->username[0]) + { + cupsdSetString(&job->username, con->username); + + if (attr) + cupsdSetString(&attr->values[0].string.text, con->username); + } + else if (attr) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "add_job: requesting-user-name=\"%s\"", + attr->values[0].string.text); + + cupsdSetString(&job->username, attr->values[0].string.text); + } + else + cupsdSetString(&job->username, "anonymous"); + + if (!attr) + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_NAME, + "job-originating-user-name", NULL, job->username); + else + { + attr->group_tag = IPP_TAG_JOB; + _cupsStrFree(attr->name); + attr->name = _cupsStrAlloc("job-originating-user-name"); + } + + if (con->username[0] || auth_info) + { + save_auth_info(con, job, auth_info); + + /* + * Remove the auth-info attribute from the attribute data... + */ + + if (auth_info) + ippDeleteAttribute(job->attrs, auth_info); + } + + 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")) + { + /* + * 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. + */ + + 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 ++) + { + _cupsStrFree(attr->values[i].string.text); + attr->values[i].string.text = NULL; + if (attr->values[i].string.charset) + { + _cupsStrFree(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 = _cupsStrAlloc(con->http.hostname); + } + + attr->group_tag = IPP_TAG_JOB; + } + 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->state_value = (ipp_jstate_t)job->state->values[0].integer; + 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); + + if ((attr = ippFindAttribute(job->attrs, "job-k-octets", + IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer = 0; + else + 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) + { + if ((val = cupsGetOption("job-hold-until", printer->num_options, + printer->options)) == NULL) + val = "no-hold"; + + attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-hold-until", NULL, val); + } + if (attr && strcmp(attr->values[0].string.text, "no-hold")) + { + /* + * Hold job until specified time... + */ + + cupsdSetJobHoldUntil(job, attr->values[0].string.text, 0); + + job->state->values[0].integer = IPP_JOB_HELD; + job->state_value = IPP_JOB_HELD; + } + else if (job->attrs->request.op.operation_id == IPP_CREATE_JOB) + { + job->hold_until = time(NULL) + MultipleOperationTimeout; + job->state->values[0].integer = IPP_JOB_HELD; + job->state_value = IPP_JOB_HELD; + } + else + { + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; + } + + if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) || + Classification) + { + /* + * Add job sheets options... + */ + + if ((attr = ippFindAttribute(job->attrs, "job-sheets", + IPP_TAG_ZERO)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_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 = _cupsStrRetain(printer->job_sheets[0]); + attr->values[1].string.text = _cupsStrRetain(printer->job_sheets[1]); + } + + job->job_sheets = attr; + + /* + * Enforce classification level if set... + */ + + if (Classification) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Classification=\"%s\", ClassifyOverride=%d", + Classification ? Classification : "(null)", + ClassifyOverride); + + if (ClassifyOverride) + { + if (!strcmp(attr->values[0].string.text, "none") && + (attr->num_values == 1 || + !strcmp(attr->values[1].string.text, "none"))) + { + /* + * Force the leading banner to have the classification on it... + */ + + cupsdSetString(&attr->values[0].string.text, Classification); + + cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED " + "job-sheets=\"%s,none\", " + "job-originating-user-name=\"%s\"", + Classification, job->username); + } + else if (attr->num_values == 2 && + strcmp(attr->values[0].string.text, + attr->values[1].string.text) && + strcmp(attr->values[0].string.text, "none") && + strcmp(attr->values[1].string.text, "none")) + { + /* + * Can't put two different security markings on the same document! + */ + + cupsdSetString(&attr->values[1].string.text, attr->values[0].string.text); + + cupsdLogJob(job, CUPSD_LOG_NOTICE, "CLASSIFICATION FORCED " + "job-sheets=\"%s,%s\", " + "job-originating-user-name=\"%s\"", + attr->values[0].string.text, + attr->values[1].string.text, job->username); + } + else if (strcmp(attr->values[0].string.text, Classification) && + strcmp(attr->values[0].string.text, "none") && + (attr->num_values == 1 || + (strcmp(attr->values[1].string.text, Classification) && + strcmp(attr->values[1].string.text, "none")))) + { + if (attr->num_values == 1) + cupsdLogJob(job, CUPSD_LOG_NOTICE, + "CLASSIFICATION OVERRIDDEN " + "job-sheets=\"%s\", " + "job-originating-user-name=\"%s\"", + attr->values[0].string.text, job->username); + else + cupsdLogJob(job, CUPSD_LOG_NOTICE, + "CLASSIFICATION OVERRIDDEN " + "job-sheets=\"%s,%s\",fffff " + "job-originating-user-name=\"%s\"", + attr->values[0].string.text, + attr->values[1].string.text, job->username); + } + } + else if (strcmp(attr->values[0].string.text, Classification) && + (attr->num_values == 1 || + strcmp(attr->values[1].string.text, Classification))) + { + /* + * Force the banner to have the classification on it... + */ + + if (attr->num_values > 1 && + !strcmp(attr->values[0].string.text, attr->values[1].string.text)) + { + cupsdSetString(&(attr->values[0].string.text), Classification); + cupsdSetString(&(attr->values[1].string.text), Classification); + } + else + { + if (attr->num_values == 1 || + strcmp(attr->values[0].string.text, "none")) + cupsdSetString(&(attr->values[0].string.text), Classification); + + if (attr->num_values > 1 && + strcmp(attr->values[1].string.text, "none")) + cupsdSetString(&(attr->values[1].string.text), Classification); + } + + if (attr->num_values > 1) + cupsdLogJob(job, CUPSD_LOG_NOTICE, + "CLASSIFICATION FORCED " + "job-sheets=\"%s,%s\", " + "job-originating-user-name=\"%s\"", + attr->values[0].string.text, + attr->values[1].string.text, job->username); + else + cupsdLogJob(job, CUPSD_LOG_NOTICE, + "CLASSIFICATION FORCED " + "job-sheets=\"%s\", " + "job-originating-user-name=\"%s\"", + Classification, job->username); + } + } + + /* + * See if we need to add the starting sheet... + */ + + if (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT))) + { + cupsdLogJob(job, CUPSD_LOG_INFO, "Adding start banner page \"%s\".", + attr->values[0].string.text); + + if ((kbytes = copy_banner(con, job, attr->values[0].string.text)) < 0) + { + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_PURGE, + "Aborting job because the start banner could not be " + "copied."); + return (NULL); + } + + cupsdUpdateQuota(printer, job->username, 0, kbytes); + } + } + else if ((attr = ippFindAttribute(job->attrs, "job-sheets", + IPP_TAG_ZERO)) != NULL) + job->job_sheets = attr; + + /* + * Fill in the response info... + */ + + snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName, + LocalPort, 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_value); + add_job_state_reasons(con, job); + + con->response->request.status.status_code = IPP_OK; + + /* + * Add any job subscriptions... + */ + + add_job_subscriptions(con, job); + + /* + * Set all but the first two attributes to the job attributes group... + */ + + for (attr = job->attrs->attrs->next->next; attr; attr = attr->next) + attr->group_tag = IPP_TAG_JOB; + + /* + * Fire the "job created" event... + */ + + cupsdAddEvent(CUPSD_EVENT_JOB_CREATED, printer, job, "Job created."); + + /* + * Return the new job... + */ + + return (job); +} + + +/* + * 'add_job_state_reasons()' - Add the "job-state-reasons" attribute based + * upon the job and printer state... + */ + +static void +add_job_state_reasons( + cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Job info */ +{ + cupsd_printer_t *dest; /* Destination printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job_state_reasons(%p[%d], %d)", + con, con->http.fd, job ? job->id : 0); + + switch (job ? job->state_value : IPP_JOB_CANCELED) + { + case IPP_JOB_PENDING : + dest = cupsdFindDest(job->dest); + + if (dest && 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_CANCELED : + 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_job_subscriptions()' - Add any subscriptions for a job. + */ + +static void +add_job_subscriptions( + cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Newly created job */ +{ + int i; /* Looping var */ + ipp_attribute_t *prev, /* Previous attribute */ + *next, /* Next attribute */ + *attr; /* Current attribute */ + cupsd_subscription_t *sub; /* Subscription object */ + const char *recipient, /* notify-recipient-uri */ + *pullmethod; /* notify-pull-method */ + ipp_attribute_t *user_data; /* notify-user-data */ + int interval; /* notify-time-interval */ + unsigned mask; /* notify-events */ + + + /* + * Find the first subscription group attribute; return if we have + * none... + */ + + for (attr = job->attrs->attrs; attr; attr = attr->next) + if (attr->group_tag == IPP_TAG_SUBSCRIPTION) + break; + + if (!attr) + return; + + /* + * Process the subscription attributes in the request... + */ + + while (attr) + { + recipient = NULL; + pullmethod = NULL; + user_data = NULL; + interval = 0; + mask = CUPSD_EVENT_NONE; + + while (attr && attr->group_tag != IPP_TAG_ZERO) + { + if (!strcmp(attr->name, "notify-recipient-uri") && + attr->value_tag == IPP_TAG_URI) + { + /* + * Validate the recipient scheme against the ServerBin/notifier + * directory... + */ + + char notifier[1024], /* Notifier filename */ + scheme[HTTP_MAX_URI], /* Scheme portion of URI */ + userpass[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 */ + + + recipient = attr->values[0].string.text; + + if (httpSeparateURI(HTTP_URI_CODING_ALL, recipient, + scheme, sizeof(scheme), userpass, sizeof(userpass), + host, sizeof(host), &port, + resource, sizeof(resource)) < HTTP_URI_OK) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Bad notify-recipient-uri URI \"%s\"!"), recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_URI_SCHEME); + return; + } + + snprintf(notifier, sizeof(notifier), "%s/notifier/%s", ServerBin, + scheme); + if (access(notifier, X_OK)) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("notify-recipient-uri URI \"%s\" uses unknown " + "scheme!"), recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_URI_SCHEME); + return; + } + + if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient)) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("notify-recipient-uri URI \"%s\" is already used!"), + recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_ATTRIBUTES); + return; + } + } + else if (!strcmp(attr->name, "notify-pull-method") && + attr->value_tag == IPP_TAG_KEYWORD) + { + pullmethod = attr->values[0].string.text; + + if (strcmp(pullmethod, "ippget")) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Bad notify-pull-method \"%s\"!"), pullmethod); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_ATTRIBUTES); + return; + } + } + else if (!strcmp(attr->name, "notify-charset") && + attr->value_tag == IPP_TAG_CHARSET && + strcmp(attr->values[0].string.text, "us-ascii") && + strcmp(attr->values[0].string.text, "utf-8")) + { + send_ipp_status(con, IPP_CHARSET, + _("Character set \"%s\" not supported!"), + attr->values[0].string.text); + return; + } + else if (!strcmp(attr->name, "notify-natural-language") && + (attr->value_tag != IPP_TAG_LANGUAGE || + strcmp(attr->values[0].string.text, DefaultLanguage))) + { + send_ipp_status(con, IPP_CHARSET, + _("Language \"%s\" not supported!"), + attr->values[0].string.text); + return; + } + else if (!strcmp(attr->name, "notify-user-data") && + attr->value_tag == IPP_TAG_STRING) + { + if (attr->num_values > 1 || attr->values[0].unknown.length > 63) + { + send_ipp_status(con, IPP_REQUEST_VALUE, + _("The notify-user-data value is too large " + "(%d > 63 octets)!"), + attr->values[0].unknown.length); + return; + } + + user_data = attr; + } + else if (!strcmp(attr->name, "notify-events") && + attr->value_tag == IPP_TAG_KEYWORD) + { + for (i = 0; i < attr->num_values; i ++) + mask |= cupsdEventValue(attr->values[i].string.text); + } + else if (!strcmp(attr->name, "notify-lease-duration")) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("The notify-lease-duration attribute cannot be " + "used with job subscriptions.")); + return; + } + else if (!strcmp(attr->name, "notify-time-interval") && + attr->value_tag == IPP_TAG_INTEGER) + interval = attr->values[0].integer; + + attr = attr->next; + } + + if (!recipient && !pullmethod) + break; + + if (mask == CUPSD_EVENT_NONE) + mask = CUPSD_EVENT_JOB_COMPLETED; + + if ((sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, + recipient, 0)) != NULL) + { + sub->interval = interval; + + cupsdSetString(&sub->owner, job->username); + + if (user_data) + { + sub->user_data_len = user_data->values[0].unknown.length; + memcpy(sub->user_data, user_data->values[0].unknown.data, + sub->user_data_len); + } + + ippAddSeparator(con->response); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); + } + + if (attr) + attr = attr->next; + } + + cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); + + /* + * Remove all of the subscription attributes from the job request... + * + * TODO: Optimize this since subscription groups have to come at the + * end of the request... + */ + + for (attr = job->attrs->attrs, prev = NULL; attr; attr = next) + { + next = attr->next; + + if (attr->group_tag == IPP_TAG_SUBSCRIPTION || + attr->group_tag == IPP_TAG_ZERO) + { + /* + * Free and remove this attribute... + */ + + _ippFreeAttr(attr); + + if (prev) + prev->next = next; + else + job->attrs->attrs = next; + } + else + prev = attr; + } + + job->attrs->last = prev; + job->attrs->current = prev; +} + + +/* + * 'add_job_uuid()' - Add job-uuid attribute to a job. + * + * See RFC 4122 for the definition of UUIDs and the format. + */ + +static void +add_job_uuid(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Job */ +{ + char uuid[1024]; /* job-uuid string */ + _cups_md5_state_t md5state; /* MD5 state */ + unsigned char md5sum[16]; /* MD5 digest/sum */ + + + /* + * First see if the job already has a job-uuid attribute; if so, return... + */ + + if (ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI)) + return; + + /* + * No job-uuid attribute, so build a version 3 UUID with the local job + * ID at the end; see RFC 4122 for details. Start with the MD5 sum of + * the ServerName, server name and port that the client connected to, + * and local job ID... + */ + + snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername, + con->serverport, job->id); + + _cupsMD5Init(&md5state); + _cupsMD5Append(&md5state, (unsigned char *)uuid, strlen(uuid)); + _cupsMD5Finish(&md5state, md5sum); + + /* + * Format the UUID URI using the MD5 sum and job ID. + */ + + snprintf(uuid, sizeof(uuid), + "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5], + (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40, + md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13], + md5sum[14], md5sum[15]); + + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid); +} + + +/* + * 'add_printer()' - Add a printer to the system. + */ + +static void +add_printer(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - URI of printer */ +{ + http_status_t status; /* Policy status */ + int i; /* Looping var */ + char scheme[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 */ + cupsd_printer_t *printer; /* Printer/class */ + ipp_attribute_t *attr; /* Printer attribute */ + cups_file_t *fp; /* Script/PPD file */ + 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 */ + char newname[IPP_MAX_NAME]; /* New printer name */ + int changed_driver, /* Changed the PPD/interface script? */ + need_restart_job, /* Need to restart job? */ + set_device_uri, /* Did we set the device URI? */ + set_port_monitor; /* Did we set the port monitor? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Do we have a valid URI? + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/printers/", 10) || strlen(resource) == 10) + { + /* + * No, return an error... + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri must be of the form " + "\"ipp://HOSTNAME/printers/PRINTERNAME\".")); + return; + } + + /* + * Do we have a valid printer name? + */ + + if (!validate_name(resource + 10)) + { + /* + * No, return an error... + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri \"%s\" contains invalid characters."), + uri->values[0].string.text); + return; + } + + /* + * See if the printer already exists; if not, create a new printer... + */ + + if ((printer = cupsdFindPrinter(resource + 10)) == NULL) + { + /* + * Printer doesn't exist; see if we have a class of the same name... + */ + + if ((printer = cupsdFindClass(resource + 10)) != NULL && + !(printer->type & CUPS_PRINTER_DISCOVERED)) + { + /* + * Yes, return an error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("A class named \"%s\" already exists!"), + resource + 10); + return; + } + + /* + * No, check the default policy then add the printer... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + printer = cupsdAddPrinter(resource + 10); + modify = 0; + } + else if (printer->type & CUPS_PRINTER_IMPLICIT) + { + /* + * Check the default policy, then rename the implicit printer to + * "AnyPrinter" or delete it... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + if (ImplicitAnyClasses) + { + snprintf(newname, sizeof(newname), "Any%s", resource + 10); + cupsdRenamePrinter(printer, newname); + } + else + cupsdDeletePrinter(printer, 1); + + /* + * Add the printer as a new local printer... + */ + + printer = cupsdAddPrinter(resource + 10); + modify = 0; + } + else if (printer->type & CUPS_PRINTER_DISCOVERED) + { + /* + * Check the default policy, then rename the remote printer to + * "Printer@server"... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + snprintf(newname, sizeof(newname), "%s@%s", resource + 10, + printer->hostname); + cupsdRenamePrinter(printer, newname); + + /* + * Add the printer as a new local printer... + */ + + printer = cupsdAddPrinter(resource + 10); + modify = 0; + } + else if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + else + modify = 1; + + /* + * Look for attributes and copy them over as needed... + */ + + changed_driver = 0; + need_restart_job = 0; + + if ((attr = ippFindAttribute(con->request, "printer-location", + IPP_TAG_TEXT)) != NULL) + cupsdSetString(&printer->location, attr->values[0].string.text); + + if ((attr = ippFindAttribute(con->request, "printer-info", + IPP_TAG_TEXT)) != NULL) + cupsdSetString(&printer->info, attr->values[0].string.text); + + set_device_uri = 0; + + if ((attr = ippFindAttribute(con->request, "device-uri", + IPP_TAG_URI)) != NULL) + { + /* + * Do we have a valid device URI? + */ + + http_uri_status_t uri_status; /* URI separation status */ + char old_device_uri[1024]; + /* Old device URI */ + + + need_restart_job = 1; + + uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, + attr->values[0].string.text, + scheme, sizeof(scheme), + username, sizeof(username), + host, sizeof(host), &port, + resource, sizeof(resource)); + + if (uri_status < HTTP_URI_OK) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"!"), + attr->values[0].string.text); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "add_printer: httpSeparateURI returned %d", uri_status); + return; + } + + if (!strcmp(scheme, "file")) + { + /* + * See if the administrator has enabled file devices... + */ + + if (!FileDevice && strcmp(resource, "/dev/null")) + { + /* + * File devices are disabled and the URL is not file:/dev/null... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("File device URIs have been disabled! " + "To enable, see the FileDevice directive in " + "\"%s/cupsd.conf\"."), + ServerRoot); + return; + } + } + else + { + /* + * See if the backend exists and is executable... + */ + + snprintf(srcfile, sizeof(srcfile), "%s/backend/%s", ServerBin, scheme); + if (access(srcfile, X_OK)) + { + /* + * Could not find device in list! + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri scheme \"%s\"!"), + scheme); + return; + } + } + + if (printer->sanitized_device_uri) + strlcpy(old_device_uri, printer->sanitized_device_uri, + sizeof(old_device_uri)); + else + old_device_uri[0] = '\0'; + + cupsdSetDeviceURI(printer, attr->values[0].string.text); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s device-uri to \"%s\" (was \"%s\".)", + printer->name, printer->sanitized_device_uri, + old_device_uri); + + set_device_uri = 1; + } + + set_port_monitor = 0; + + if ((attr = ippFindAttribute(con->request, "port-monitor", + IPP_TAG_NAME)) != NULL) + { + ipp_attribute_t *supported; /* port-monitor-supported attribute */ + + + need_restart_job = 1; + + supported = ippFindAttribute(printer->ppd_attrs, "port-monitor-supported", + IPP_TAG_NAME); + if (supported) + { + for (i = 0; i < supported->num_values; i ++) + if (!strcmp(supported->values[i].string.text, + attr->values[0].string.text)) + break; + } + + if (!supported || i >= supported->num_values) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"), + attr->values[0].string.text); + return; + } + + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s port-monitor to \"%s\" (was \"%s\".)", + printer->name, attr->values[0].string.text, + printer->port_monitor ? printer->port_monitor : "none"); + + if (strcmp(attr->values[0].string.text, "none")) + cupsdSetString(&printer->port_monitor, attr->values[0].string.text); + else + cupsdClearString(&printer->port_monitor); + + set_port_monitor = 1; + } + + if ((attr = ippFindAttribute(con->request, "printer-is-accepting-jobs", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean != printer->accepting) + { + cupsdLogMessage(CUPSD_LOG_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; + cupsdAddPrinterHistory(printer); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, + "%s accepting jobs.", + printer->accepting ? "Now" : "No longer"); + } + + if ((attr = ippFindAttribute(con->request, "printer-is-shared", + IPP_TAG_BOOLEAN)) != NULL) + { + if (printer->shared && !attr->values[0].boolean) + cupsdDeregisterPrinter(printer, 1); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s printer-is-shared to %d (was %d.)", + printer->name, attr->values[0].boolean, printer->shared); + + printer->shared = attr->values[0].boolean; + } + + if ((attr = ippFindAttribute(con->request, "printer-state", + IPP_TAG_ENUM)) != NULL) + { + if (attr->values[0].integer != IPP_PRINTER_IDLE && + attr->values[0].integer != IPP_PRINTER_STOPPED) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d!"), + attr->values[0].integer); + return; + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Setting %s printer-state to %d (was %d.)", + printer->name, attr->values[0].integer, printer->state); + + if (attr->values[0].integer == IPP_PRINTER_STOPPED) + cupsdStopPrinter(printer, 0); + else + { + need_restart_job = 1; + cupsdSetPrinterState(printer, (ipp_pstate_t)(attr->values[0].integer), 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)); + cupsdAddPrinterHistory(printer); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, "%s", + printer->state_message); + } + + if ((attr = ippFindAttribute(con->request, "printer-state-reasons", + IPP_TAG_KEYWORD)) != NULL) + { + if (attr->num_values > + (int)(sizeof(printer->reasons) / sizeof(printer->reasons[0]))) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Too many printer-state-reasons values (%d > %d)!"), + attr->num_values, + (int)(sizeof(printer->reasons) / + sizeof(printer->reasons[0]))); + return; + } + + for (i = 0; i < printer->num_reasons; i ++) + _cupsStrFree(printer->reasons[i]); + + printer->num_reasons = 0; + for (i = 0; i < attr->num_values; i ++) + { + if (!strcmp(attr->values[i].string.text, "none")) + continue; + + printer->reasons[printer->num_reasons] = + _cupsStrRetain(attr->values[i].string.text); + printer->num_reasons ++; + + if (!strcmp(attr->values[i].string.text, "paused") && + printer->state != IPP_PRINTER_STOPPED) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s printer-state to %d (was %d.)", + printer->name, IPP_PRINTER_STOPPED, printer->state); + cupsdStopPrinter(printer, 0); + } + } + + if (PrintcapFormat == PRINTCAP_PLIST) + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, + "Printer \"%s\" state changed.", printer->name); + } + + set_printer_defaults(con, printer); + + if ((attr = ippFindAttribute(con->request, "auth-info-required", + IPP_TAG_KEYWORD)) != NULL) + cupsdSetAuthInfoRequired(printer, NULL, attr); + + /* + * See if we have all required attributes... + */ + + if (!printer->device_uri) + cupsdSetString(&printer->device_uri, "file:///dev/null"); + + /* + * See if we have an interface script or PPD file attached to the request... + */ + + if (con->filename) + { + need_restart_job = 1; + changed_driver = 1; + + strlcpy(srcfile, con->filename, sizeof(srcfile)); + + if ((fp = cupsFileOpen(srcfile, "rb"))) + { + /* + * Yes; get the first line from it... + */ + + line[0] = '\0'; + cupsFileGets(fp, line, sizeof(line)); + cupsFileClose(fp); + + /* + * Then see what kind of file it is... + */ + + snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, + printer->name); + + if (!strncmp(line, "*PPD-Adobe", 10)) + { + /* + * 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)) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to copy interface script - %s!"), + strerror(errno)); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Copied interface script successfully!"); + chmod(dstfile, 0755); + } + + snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + + if (!strncmp(line, "*PPD-Adobe", 10)) + { + /* + * 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)) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("Unable to copy PPD file - %s!"), + strerror(errno)); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "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); + } + } + } + else if ((attr = ippFindAttribute(con->request, "ppd-name", + IPP_TAG_NAME)) != NULL) + { + need_restart_job = 1; + changed_driver = 1; + + if (!strcmp(attr->values[0].string.text, "raw")) + { + /* + * 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); + } + else + { + /* + * PPD model file... + */ + + snprintf(dstfile, sizeof(dstfile), "%s/interfaces/%s", ServerRoot, + printer->name); + unlink(dstfile); + + snprintf(dstfile, sizeof(dstfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + + if (copy_model(con, attr->values[0].string.text, dstfile)) + { + send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file!")); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Copied PPD file successfully!"); + chmod(dstfile, 0644); + } + } + + if (changed_driver) + { + /* + * If we changed the PPD/interface script, then remove the printer's cache + * file and clear the printer-state-reasons... + */ + + char cache_name[1024]; /* Cache filename for printer attrs */ + + snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp4", CacheDir, + printer->name); + unlink(cache_name); + + snprintf(cache_name, sizeof(cache_name), "%s/%s.pwg3", CacheDir, + printer->name); + unlink(cache_name); + + cupsdSetPrinterReasons(printer, "none"); + +#ifdef __APPLE__ + /* + * (Re)register color profiles... + */ + + if (!RunUser) + { + apple_unregister_profiles(printer); + apple_register_profiles(printer); + } +#endif /* __APPLE__ */ + } + + /* + * If we set the device URI but not the port monitor, check which port + * monitor to use by default... + */ + + if (set_device_uri && !set_port_monitor) + { + ppd_file_t *ppd; /* PPD file */ + ppd_attr_t *ppdattr; /* cupsPortMonitor attribute */ + + + httpSeparateURI(HTTP_URI_CODING_ALL, printer->device_uri, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + if ((ppd = ppdOpenFile(srcfile)) != NULL) + { + for (ppdattr = ppdFindAttr(ppd, "cupsPortMonitor", NULL); + ppdattr; + ppdattr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL)) + if (!strcmp(scheme, ppdattr->spec)) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Setting %s port-monitor to \"%s\" (was \"%s\".)", + printer->name, ppdattr->value, + printer->port_monitor ? printer->port_monitor + : "none"); + + if (strcmp(ppdattr->value, "none")) + cupsdSetString(&printer->port_monitor, ppdattr->value); + else + cupsdClearString(&printer->port_monitor); + + break; + } + + ppdClose(ppd); + } + } + + /* + * Update the printer attributes and return... + */ + + cupsdSetPrinterAttrs(printer); + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + if (need_restart_job && printer->job) + { + /* + * Restart the current job... + */ + + cupsdSetJobState(printer->job, IPP_JOB_PENDING, CUPSD_JOB_FORCE, + "Job restarted because the printer was modified."); + } + + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); + + if (modify) + { + cupsdAddEvent(CUPSD_EVENT_PRINTER_MODIFIED, + printer, NULL, "Printer \"%s\" modified by \"%s\".", + printer->name, get_username(con)); + + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" modified by \"%s\".", + printer->name, get_username(con)); + } + else + { + cupsdAddPrinterHistory(printer); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, + printer, NULL, "New printer \"%s\" added by \"%s\".", + printer->name, get_username(con)); + + cupsdLogMessage(CUPSD_LOG_INFO, "New printer \"%s\" added by \"%s\".", + printer->name, get_username(con)); + } + + 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( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *p) /* I - Printer info */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_state_reasons(%p[%d], %p[%s])", + con, con->http.fd, p, p->name); + + if (p->num_reasons == 0) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-state-reasons", NULL, "none"); + else + ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-state-reasons", p->num_reasons, NULL, + (const char * const *)p->reasons); +} + + +/* + * 'add_queued_job_count()' - Add the "queued-job-count" attribute for + * the specified printer or class. + */ + +static void +add_queued_job_count( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *p) /* I - Printer or class */ +{ + int count; /* Number of jobs on destination */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_queued_job_count(%p[%d], %p[%s])", + con, con->http.fd, p, p->name); + + count = cupsdGetPrinterJobCount(p->name); + + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "queued-job-count", count); +} + + +#ifdef __APPLE__ +/* + * 'apple_init_profile()' - Initialize a color profile. + */ + +static void +apple_init_profile( + ppd_file_t *ppd, /* I - PPD file */ + cups_array_t *languages, /* I - Languages in the PPD file */ + CMDeviceProfileInfo *profile, /* I - Profile record */ + unsigned id, /* I - Profile ID */ + const char *name, /* I - Profile name */ + const char *text, /* I - Profile UI text */ + const char *iccfile) /* I - ICC filename */ +{ + char url[1024]; /* URL for profile filename */ + CFMutableDictionaryRef dict; /* Dictionary for name */ + char *language; /* Current language */ + ppd_attr_t *attr; /* Profile attribute */ + CFStringRef cflang, /* Language string */ + cftext; /* Localized text */ + + + /* + * Build the profile name dictionary... + */ + + dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + cftext = CFStringCreateWithCString(kCFAllocatorDefault, text, + kCFStringEncodingUTF8); + + if (cftext) + { + CFDictionarySetValue(dict, CFSTR("en"), cftext); + CFRelease(cftext); + } + + if (languages) + { + /* + * Find localized names for the color profiles... + */ + + cupsArraySave(ppd->sorted_attrs); + + for (language = (char *)cupsArrayFirst(languages); + language; + language = (char *)cupsArrayNext(languages)) + { + if (iccfile) + { + if ((attr = _ppdLocalizedAttr(ppd, "cupsICCProfile", name, + language)) == NULL) + attr = _ppdLocalizedAttr(ppd, "APTiogaProfile", name, language); + } + else + attr = _ppdLocalizedAttr(ppd, "ColorModel", name, language); + + if (attr && attr->text[0]) + { + cflang = CFStringCreateWithCString(kCFAllocatorDefault, language, + kCFStringEncodingUTF8); + cftext = CFStringCreateWithCString(kCFAllocatorDefault, attr->text, + kCFStringEncodingUTF8); + + if (cflang && cftext) + CFDictionarySetValue(dict, cflang, cftext); + + if (cflang) + CFRelease(cflang); + + if (cftext) + CFRelease(cftext); + } + } + + cupsArrayRestore(ppd->sorted_attrs); + } + + /* + * Fill in the profile data... + */ + + if (iccfile) + httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "file", NULL, "", 0, + iccfile); + + profile->dataVersion = cmDeviceProfileInfoVersion1; + profile->profileID = id; + profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase; + profile->profileName = dict; + + if (iccfile) + strlcpy(profile->profileLoc.u.pathLoc.path, iccfile, + sizeof(profile->profileLoc.u.pathLoc.path)); +} + + +/* + * 'apple_register_profiles()' - Register color profiles for a printer. + */ + +static void +apple_register_profiles( + cupsd_printer_t *p) /* I - Printer */ +{ + int i; /* Looping var */ + char ppdfile[1024], /* PPD filename */ + iccfile[1024], /* ICC filename */ + selector[PPD_MAX_NAME]; + /* Profile selection string */ + ppd_file_t *ppd; /* PPD file */ + ppd_attr_t *attr, /* Profile attributes */ + *profileid_attr,/* cupsProfileID attribute */ + *q1_attr, /* ColorModel (or other) qualifier */ + *q2_attr, /* MediaType (or other) qualifier */ + *q3_attr; /* Resolution (or other) qualifier */ + char q_keyword[PPD_MAX_NAME]; + /* Qualifier keyword */ + const char *q1_choice, /* ColorModel (or other) choice */ + *q2_choice, /* MediaType (or other) choice */ + *q3_choice; /* Resolution (or other) choice */ + const char *profile_key; /* Profile keyword */ + ppd_option_t *cm_option; /* Color model option */ + ppd_choice_t *cm_choice; /* Color model choice */ + int num_profiles; /* Number of profiles */ + CMError error; /* Last error */ + unsigned device_id, /* Printer device ID */ + profile_id, /* Profile ID */ + default_profile_id = 0; + /* Default profile ID */ + CFMutableDictionaryRef device_name; /* Printer device name dictionary */ + CFStringRef printer_name; /* Printer name string */ + CMDeviceScope scope = /* Scope of the registration */ + { + kCFPreferencesAnyUser, + kCFPreferencesCurrentHost + }; + CMDeviceProfileArrayPtr profiles; /* Profiles */ + CMDeviceProfileInfo *profile; /* Current profile */ + cups_array_t *languages; /* Languages array */ + + + /* + * Make sure ColorSync is available... + */ + + if (CMRegisterColorDevice == NULL) + return; + + /* + * Try opening the PPD file for this printer... + */ + + snprintf(ppdfile, sizeof(ppdfile), "%s/ppd/%s.ppd", ServerRoot, p->name); + if ((ppd = ppdOpenFile(ppdfile)) == NULL) + return; + + /* + * See if we have any profiles... + */ + + if ((attr = ppdFindAttr(ppd, "APTiogaProfile", NULL)) != NULL) + profile_key = "APTiogaProfile"; + else + { + attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); + profile_key = "cupsICCProfile"; + } + + for (num_profiles = 0; attr; attr = ppdFindNextAttr(ppd, profile_key, NULL)) + if (attr->spec[0] && attr->value && attr->value[0]) + { + if (attr->value[0] != '/') + snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, + attr->value); + else + strlcpy(iccfile, attr->value, sizeof(iccfile)); + + if (access(iccfile, 0)) + continue; + + num_profiles ++; + } + + + /* + * If we have profiles, add them... + */ + + if (num_profiles > 0) + { + if (profile_key[0] == 'A') + { + /* + * For Tioga PPDs, get the default profile using the DefaultAPTiogaProfile + * attribute... + */ + + if ((attr = ppdFindAttr(ppd, "DefaultAPTiogaProfile", NULL)) != NULL && + attr->value) + default_profile_id = atoi(attr->value); + + q1_choice = q2_choice = q3_choice = NULL; + } + else + { + /* + * For CUPS PPDs, figure out the default profile selector values... + */ + + if ((attr = ppdFindAttr(ppd, "cupsICCQualifier1", NULL)) != NULL && + attr->value && attr->value[0]) + { + snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); + q1_attr = ppdFindAttr(ppd, q_keyword, NULL); + } + else if ((q1_attr = ppdFindAttr(ppd, "DefaultColorModel", NULL)) == NULL) + q1_attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL); + + if (q1_attr && q1_attr->value && q1_attr->value[0]) + q1_choice = q1_attr->value; + else + q1_choice = ""; + + if ((attr = ppdFindAttr(ppd, "cupsICCQualifier2", NULL)) != NULL && + attr->value && attr->value[0]) + { + snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); + q2_attr = ppdFindAttr(ppd, q_keyword, NULL); + } + else + q2_attr = ppdFindAttr(ppd, "DefaultMediaType", NULL); + + if (q2_attr && q2_attr->value && q2_attr->value[0]) + q2_choice = q2_attr->value; + else + q2_choice = NULL; + + if ((attr = ppdFindAttr(ppd, "cupsICCQualifier3", NULL)) != NULL && + attr->value && attr->value[0]) + { + snprintf(q_keyword, sizeof(q_keyword), "Default%s", attr->value); + q3_attr = ppdFindAttr(ppd, q_keyword, NULL); + } + else + q3_attr = ppdFindAttr(ppd, "DefaultResolution", NULL); + + if (q3_attr && q3_attr->value && q3_attr->value[0]) + q3_choice = q3_attr->value; + else + q3_choice = NULL; + } + + /* + * Build the array of profiles... + * + * Note: This calloc actually requests slightly more memory than needed. + */ + + if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for %d profiles!", + num_profiles); + ppdClose(ppd); + return; + } + + profiles->profileCount = num_profiles; + languages = _ppdGetLanguages(ppd); + + for (profile = profiles->profiles, + attr = ppdFindAttr(ppd, profile_key, NULL); + attr; + attr = ppdFindNextAttr(ppd, profile_key, NULL)) + if (attr->spec[0] && attr->value && attr->value[0]) + { + /* + * Add this profile... + */ + + if (attr->value[0] != '/') + snprintf(iccfile, sizeof(iccfile), "%s/profiles/%s", DataDir, + attr->value); + else + strlcpy(iccfile, attr->value, sizeof(iccfile)); + + if (access(iccfile, 0)) + continue; + + if (profile_key[0] == 'c') + { + cupsArraySave(ppd->sorted_attrs); + + if ((profileid_attr = ppdFindAttr(ppd, "cupsProfileID", + attr->spec)) != NULL && + profileid_attr->value && isdigit(profileid_attr->value[0] & 255)) + profile_id = (unsigned)strtoul(profileid_attr->value, NULL, 10); + else + profile_id = _ppdHashName(attr->spec); + + cupsArrayRestore(ppd->sorted_attrs); + } + else + profile_id = atoi(attr->spec); + + apple_init_profile(ppd, languages, profile, profile_id, attr->spec, + attr->text[0] ? attr->text : attr->spec, iccfile); + + profile ++; + + /* + * See if this is the default profile... + */ + + if (!default_profile_id && q1_choice && q2_choice && q3_choice) + { + snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice, + q3_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + + if (!default_profile_id && q1_choice && q2_choice) + { + snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + + if (!default_profile_id && q1_choice && q3_choice) + { + snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + + if (!default_profile_id && q1_choice) + { + snprintf(selector, sizeof(selector), "%s..", q1_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + + if (!default_profile_id && q2_choice && q3_choice) + { + snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + + if (!default_profile_id && q2_choice) + { + snprintf(selector, sizeof(selector), ".%s.", q2_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + + if (!default_profile_id && q3_choice) + { + snprintf(selector, sizeof(selector), "..%s", q3_choice); + if (!strcmp(selector, attr->spec)) + default_profile_id = profile_id; + } + } + + _ppdFreeLanguages(languages); + } + else if ((cm_option = ppdFindOption(ppd, "ColorModel")) != NULL) + { + /* + * Extract profiles from ColorModel option... + */ + + const char *profile_name; /* Name of generic profile */ + + + num_profiles = cm_option->num_choices; + + if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for %d profiles!", + num_profiles); + ppdClose(ppd); + return; + } + + profiles->profileCount = num_profiles; + + for (profile = profiles->profiles, i = cm_option->num_choices, + cm_choice = cm_option->choices; + i > 0; + i --, cm_choice ++, profile ++) + { + if (!strcmp(cm_choice->choice, "Gray") || + !strcmp(cm_choice->choice, "Black")) + profile_name = "Gray"; + else if (!strcmp(cm_choice->choice, "RGB") || + !strcmp(cm_choice->choice, "CMY")) + profile_name = "RGB"; + else if (!strcmp(cm_choice->choice, "CMYK") || + !strcmp(cm_choice->choice, "KCMY")) + profile_name = "CMYK"; + else + profile_name = "DeviceN"; + + snprintf(selector, sizeof(selector), "%s..", profile_name); + profile_id = _ppdHashName(selector); + + apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice, + cm_choice->text, NULL); + + if (cm_choice->marked) + default_profile_id = profile_id; + } + } + else + { + /* + * Use the default colorspace... + */ + + attr = ppdFindAttr(ppd, "DefaultColorSpace", NULL); + + num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2; + + if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for %d profiles!", + num_profiles); + ppdClose(ppd); + return; + } + + profiles->profileCount = num_profiles; + + apple_init_profile(ppd, NULL, profiles->profiles, _ppdHashName("Gray.."), + "Gray", "Gray", NULL); + + switch (ppd->colorspace) + { + case PPD_CS_RGB : + case PPD_CS_CMY : + apple_init_profile(ppd, NULL, profiles->profiles + 1, + _ppdHashName("RGB.."), "RGB", "RGB", NULL); + break; + case PPD_CS_RGBK : + case PPD_CS_CMYK : + apple_init_profile(ppd, NULL, profiles->profiles + 1, + _ppdHashName("CMYK.."), "CMYK", "CMYK", NULL); + break; + + case PPD_CS_GRAY : + if (attr) + break; + + case PPD_CS_N : + apple_init_profile(ppd, NULL, profiles->profiles + 1, + _ppdHashName("DeviceN.."), "DeviceN", "DeviceN", + NULL); + break; + } + } + + if (num_profiles > 0) + { + /* + * Make sure we have a default profile ID... + */ + + if (!default_profile_id) + default_profile_id = profiles->profiles[num_profiles - 1].profileID; + + /* + * Get the device ID hash and pathelogical name dictionary. + */ + + cupsdLogMessage(CUPSD_LOG_INFO, "Registering ICC color profiles for \"%s\"", + p->name); + + device_id = _ppdHashName(p->name); + device_name = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + printer_name = CFStringCreateWithCString(kCFAllocatorDefault, + p->name, kCFStringEncodingUTF8); + + if (device_name && printer_name) + { + CFDictionarySetValue(device_name, CFSTR("en"), printer_name); + + /* + * Register the device with ColorSync... + */ + + error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id, + device_name, &scope); + + /* + * Register the profiles... + */ + + if (error == noErr) + error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id, + default_profile_id, profiles); + } + else + error = 1000; + + /* + * Clean up... + */ + + if (error != noErr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to register ICC color profiles for \"%s\" - %d", + p->name, (int)error); + + for (profile = profiles->profiles; + num_profiles > 0; + profile ++, num_profiles --) + CFRelease(profile->profileName); + + free(profiles); + + if (printer_name) + CFRelease(printer_name); + + if (device_name) + CFRelease(device_name); + } + + ppdClose(ppd); +} + + +/* + * 'apple_unregister_profiles()' - Remove color profiles for the specified + * printer. + */ + +static void +apple_unregister_profiles( + cupsd_printer_t *p) /* I - Printer */ +{ + /* + * Make sure ColorSync is available... + */ + + if (CMUnregisterColorDevice != NULL) + CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name)); +} +#endif /* __APPLE__ */ + +/* + * 'apply_printer_defaults()' - Apply printer default options to a job. + */ + +static void +apply_printer_defaults( + cupsd_printer_t *printer, /* I - Printer */ + cupsd_job_t *job) /* I - Job */ +{ + int i, /* Looping var */ + num_options; /* Number of default options */ + cups_option_t *options, /* Default options */ + *option; /* Current option */ + + + /* + * Collect all of the default options and add the missing ones to the + * job object... + */ + + for (i = printer->num_options, num_options = 0, options = NULL, + option = printer->options; + i > 0; + i --, option ++) + if (!ippFindAttribute(job->attrs, option->name, IPP_TAG_ZERO)) + { + num_options = cupsAddOption(option->name, option->value, num_options, + &options); + } + + /* + * Encode these options as attributes in the job object... + */ + + cupsEncodeOptions2(job->attrs, num_options, options, IPP_TAG_JOB); + cupsFreeOptions(num_options, options); +} + + +/* + * 'authenticate_job()' - Set job authentication info. + */ + +static void +authenticate_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ +{ + ipp_attribute_t *attr, /* job-id attribute */ + *auth_info; /* auth-info attribute */ + int jobid; /* Job ID */ + cupsd_job_t *job; /* Current job */ + char scheme[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 */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "authenticate_job(%p[%d], %s)", + con, con->http.fd, uri->values[0].string.text); + + /* + * Start with "everything is OK" status... + */ + + con->response->request.status.status_code = IPP_OK; + + /* + * See if we have a job URI or a printer URI... + */ + + if (!strcmp(uri->name, "printer-uri")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if the job has been completed... + */ + + if (job->state_value != IPP_JOB_HELD) + { + /* + * Return a "not-possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is not held for authentication!"), + jobid); + return; + } + + /* + * See if we have already authenticated... + */ + + auth_info = ippFindAttribute(con->request, "auth-info", IPP_TAG_TEXT); + + if (!con->username[0] && !auth_info) + { + cupsd_printer_t *printer; /* Job destination */ + + + /* + * No auth data. If we need to authenticate via Kerberos, send a + * HTTP auth challenge, otherwise just return an IPP error... + */ + + printer = cupsdFindDest(job->dest); + + if (printer && printer->num_auth_info_required > 0 && + !strcmp(printer->auth_info_required[0], "negotiate")) + send_http_error(con, HTTP_UNAUTHORIZED, printer); + else + send_ipp_status(con, IPP_NOT_AUTHORIZED, + _("No authentication information provided!")); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * Save the authentication information for this job... + */ + + save_auth_info(con, job, auth_info); + + /* + * 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) + { + attr->value_tag = IPP_TAG_KEYWORD; + cupsdSetString(&(attr->values[0].string.text), "no-hold"); + } + + /* + * Release the job and return... + */ + + cupsdReleaseJob(job); + + cupsdLogJob(job, CUPSD_LOG_INFO, "Authenticated by \"%s\".", con->username); +} + + +/* + * 'cancel_all_jobs()' - Cancel all print jobs. + */ + +static void +cancel_all_jobs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job or Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type */ + char scheme[HTTP_MAX_URI], /* Scheme portion of URI */ + userpass[HTTP_MAX_URI], /* Username portion of URI */ + hostname[HTTP_MAX_URI], /* Host portion of URI */ + resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int port; /* Port portion of URI */ + ipp_attribute_t *attr; /* Attribute in request */ + const char *username; /* Username */ + cupsd_jobaction_t purge; /* Purge? */ + cupsd_printer_t *printer; /* Printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_all_jobs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * See if we have a printer URI... + */ + + if (strcmp(uri->name, "printer-uri")) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("The printer-uri attribute is required!")); + return; + } + + /* + * Get the username (if any) for the jobs we want to cancel (only if + * "my-jobs" is specified... + */ + + if ((attr = ippFindAttribute(con->request, "my-jobs", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean) + { + if ((attr = ippFindAttribute(con->request, "requesting-user-name", + IPP_TAG_NAME)) != NULL) + username = attr->values[0].string.text; + else + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Missing requesting-user-name attribute!")); + return; + } + } + else + username = NULL; + + /* + * Look for the "purge-jobs" attribute... + */ + + if ((attr = ippFindAttribute(con->request, "purge-jobs", + IPP_TAG_BOOLEAN)) != NULL) + purge = attr->values[0].boolean ? CUPSD_JOB_PURGE : CUPSD_JOB_DEFAULT; + else + purge = CUPSD_JOB_PURGE; + + /* + * And if the destination is valid... + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI? + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, + scheme, sizeof(scheme), userpass, sizeof(userpass), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + if ((!strncmp(resource, "/printers/", 10) && resource[10]) || + (!strncmp(resource, "/classes/", 9) && resource[9])) + { + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Cancel all jobs on all printers... + */ + + cupsdCancelJobs(NULL, username, purge); + + cupsdLogMessage(CUPSD_LOG_INFO, "All jobs were %s by \"%s\".", + purge == CUPSD_JOB_PURGE ? "purged" : "canceled", + get_username(con)); + } + else + { + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Cancel all of the jobs on the named printer... + */ + + cupsdCancelJobs(printer->name, username, purge); + + cupsdLogMessage(CUPSD_LOG_INFO, "All jobs on \"%s\" were %s by \"%s\".", + printer->name, + purge == CUPSD_JOB_PURGE ? "purged" : "canceled", + get_username(con)); + } + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'cancel_job()' - Cancel a print job. + */ + +static void +cancel_job(cupsd_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 scheme[HTTP_MAX_URI], /* Scheme 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 */ + cupsd_job_t *job; /* Job information */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + cupsd_jobaction_t purge; /* Purge the job? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + if ((jobid = attr->values[0].integer) == 0) + { + /* + * Find the current job on the specified printer... + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * See if there are any pending jobs... + */ + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + if (job->state_value <= IPP_JOB_PROCESSING && + !strcasecmp(job->dest, printer->name)) + break; + + if (job) + jobid = job->id; + else + { + /* + * No, try stopped jobs... + */ + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + if (job->state_value == IPP_JOB_STOPPED && + !strcasecmp(job->dest, printer->name)) + break; + + if (job) + jobid = job->id; + else + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s!"), + printer->name); + return; + } + } + } + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * Look for the "purge-job" attribute... + */ + + if ((attr = ippFindAttribute(con->request, "purge-job", + IPP_TAG_BOOLEAN)) != NULL) + purge = attr->values[0].boolean ? CUPSD_JOB_PURGE : CUPSD_JOB_DEFAULT; + else + purge = CUPSD_JOB_DEFAULT; + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * See if the job is already completed, canceled, or aborted; if so, + * we can't cancel... + */ + + if (job->state_value >= IPP_JOB_CANCELED && purge != CUPSD_JOB_PURGE) + { + switch (job->state_value) + { + case IPP_JOB_CANCELED : + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is already canceled - can\'t cancel."), + jobid); + break; + + case IPP_JOB_ABORTED : + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is already aborted - can\'t cancel."), + jobid); + break; + + default : + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is already completed - can\'t cancel."), + jobid); + break; + } + + return; + } + + /* + * Cancel the job and return... + */ + + cupsdSetJobState(job, IPP_JOB_CANCELED, purge, + purge == CUPSD_JOB_PURGE ? "Job purged by \"%s\"" : + "Job canceled by \"%s\"", + username); + cupsdCheckJobs(); + + if (purge == CUPSD_JOB_PURGE) + cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Purged by \"%s\".", jobid, + username); + else + cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Canceled by \"%s\".", jobid, + username); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'cancel_subscription()' - Cancel a subscription. + */ + +static void +cancel_subscription( + cupsd_client_t *con, /* I - Client connection */ + int sub_id) /* I - Subscription ID */ +{ + http_status_t status; /* Policy status */ + cupsd_subscription_t *sub; /* Subscription */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cancel_subscription(con=%p[%d], sub_id=%d)", + con, con->http.fd, sub_id); + + /* + * Is the subscription ID valid? + */ + + if ((sub = cupsdFindSubscription(sub_id)) == NULL) + { + /* + * Bad subscription ID... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("notify-subscription-id %d no good!"), sub_id); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : + DefaultPolicyPtr, + con, sub->owner)) != HTTP_OK) + { + send_http_error(con, status, sub->dest); + return; + } + + /* + * Cancel the subscription... + */ + + cupsdDeleteSubscription(sub, 1); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'check_rss_recipient()' - Check that we do not have a duplicate RSS feed URI. + */ + +static int /* O - 1 if OK, 0 if not */ +check_rss_recipient( + const char *recipient) /* I - Recipient URI */ +{ + cupsd_subscription_t *sub; /* Current subscription */ + + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (sub->recipient) + { + /* + * Compare the URIs up to the first ?... + */ + + const char *r1, *r2; + + for (r1 = recipient, r2 = sub->recipient; + *r1 == *r2 && *r1 && *r1 != '?' && *r2 && *r2 != '?'; + r1 ++, r2 ++); + + if (*r1 == *r2) + return (0); + } + + return (1); +} + + +/* + * 'check_quotas()' - Check quotas for a printer and user. + */ + +static int /* O - 1 if OK, 0 if forbidden, + -1 if limit reached */ +check_quotas(cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *p) /* I - Printer or class */ +{ + int i; /* Looping var */ + char username[33]; /* Username */ + cupsd_quota_t *q; /* Quota data */ +#ifdef HAVE_MBR_UID_TO_UUID + /* + * Use Apple membership APIs which require that all names represent + * valid user account or group records accessible by the server. + */ + + uuid_t usr_uuid; /* UUID for job requesting user */ + uuid_t usr2_uuid; /* UUID for ACL user name entry */ + uuid_t grp_uuid; /* UUID for ACL group name entry */ + int mbr_err; /* Error from membership function */ + int is_member; /* Is this user a member? */ +#else + /* + * Use standard POSIX APIs for checking users and groups... + */ + + struct passwd *pw; /* User password data */ +#endif /* HAVE_MBR_UID_TO_UUID */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])", + con, con->http.fd, p, p->name); + + /* + * Figure out who is printing... + */ + + strlcpy(username, get_username(con), sizeof(username)); + + /* + * Check global active job limits for printers and users... + */ + + if (MaxJobsPerPrinter) + { + /* + * Check if there are too many pending jobs on this printer... + */ + + if (cupsdGetPrinterJobCount(p->name) >= MaxJobsPerPrinter) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for printer \"%s\"...", + p->name); + return (-1); + } + } + + if (MaxJobsPerUser) + { + /* + * Check if there are too many pending jobs for this user... + */ + + if (cupsdGetUserJobCount(username) >= MaxJobsPerUser) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Too many jobs for user \"%s\"...", + username); + return (-1); + } + } + + /* + * Check against users... + */ + + if (p->num_users == 0 && p->k_limit == 0 && p->page_limit == 0) + return (1); + + if (p->num_users) + { +#ifdef HAVE_MBR_UID_TO_UUID + /* + * Get UUID for job requesting user... + */ + + if (mbr_user_name_to_uuid((char *)username, usr_uuid)) + { + /* + * Unknown user... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: UUID lookup failed for user \"%s\"", + username); + cupsdLogMessage(CUPSD_LOG_INFO, + "Denying user \"%s\" access to printer \"%s\" " + "(unknown user)...", + username, p->name); + return (0); + } +#else + /* + * Get UID and GID of requesting user... + */ + + pw = getpwnam(username); + endpwent(); +#endif /* HAVE_MBR_UID_TO_UUID */ + + for (i = 0; i < p->num_users; i ++) + if (p->users[i][0] == '@') + { + /* + * Check group membership... + */ + +#ifdef HAVE_MBR_UID_TO_UUID + if (p->users[i][1] == '#') + { + if (uuid_parse((char *)p->users[i] + 2, grp_uuid)) + uuid_clear(grp_uuid); + } + else if ((mbr_err = mbr_group_name_to_uuid((char *)p->users[i] + 1, + grp_uuid)) != 0) + { + /* + * Invalid ACL entries are ignored for matching; just record a + * warning in the log... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: UUID lookup failed for ACL entry " + "\"%s\" (err=%d)", p->users[i], mbr_err); + cupsdLogMessage(CUPSD_LOG_WARN, + "Access control entry \"%s\" not a valid group name; " + "entry ignored", p->users[i]); + } + + if ((mbr_err = mbr_check_membership(usr_uuid, grp_uuid, + &is_member)) != 0) + { + /* + * At this point, there should be no errors, but check anyways... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: group \"%s\" membership check " + "failed (err=%d)", p->users[i] + 1, mbr_err); + is_member = 0; + } + + /* + * Stop if we found a match... + */ + + if (is_member) + break; + +#else + if (cupsdCheckGroup(username, pw, p->users[i] + 1)) + break; +#endif /* HAVE_MBR_UID_TO_UUID */ + } +#ifdef HAVE_MBR_UID_TO_UUID + else + { + if (p->users[i][0] == '#') + { + if (uuid_parse((char *)p->users[i] + 1, usr2_uuid)) + uuid_clear(usr2_uuid); + } + else if ((mbr_err = mbr_user_name_to_uuid((char *)p->users[i], + usr2_uuid)) != 0) + { + /* + * Invalid ACL entries are ignored for matching; just record a + * warning in the log... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "check_quotas: UUID lookup failed for ACL entry " + "\"%s\" (err=%d)", p->users[i], mbr_err); + cupsdLogMessage(CUPSD_LOG_WARN, + "Access control entry \"%s\" not a valid user name; " + "entry ignored", p->users[i]); + } + + if (!uuid_compare(usr_uuid, usr2_uuid)) + break; + } +#else + else if (!strcasecmp(username, p->users[i])) + break; +#endif /* HAVE_MBR_UID_TO_UUID */ + + if ((i < p->num_users) == p->deny_users) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Denying user \"%s\" access to printer \"%s\"...", + username, p->name); + return (0); + } + } + + /* + * Check quotas... + */ + +#ifdef __APPLE__ + if (AppleQuotas && (q = cupsdFindQuota(p, username)) != NULL) + { + /* + * TODO: Define these special page count values as constants! + */ + + if (q->page_count == -4) /* special case: unlimited user */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request approved for printer %s (%s): " + "unlimited quota.", + username, p->name, p->info); + q->page_count = 0; /* allow user to print */ + return (1); + } + else if (q->page_count == -3) /* quota exceeded */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "quota limit exceeded.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (-1); + } + else if (q->page_count == -2) /* quota disabled for user */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "printing disabled for user.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (-1); + } + else if (q->page_count == -1) /* quota access error */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "unable to determine quota limit.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (-1); + } + else if (q->page_count < 0) /* user not found or other error */ + { + cupsdLogMessage(CUPSD_LOG_INFO, + "User \"%s\" request denied for printer %s (%s): " + "user disabled / missing quota.", + username, p->name, p->info); + q->page_count = 2; /* force quota exceeded failure */ + return (-1); + } + else /* page within user limits */ + { + q->page_count = 0; /* allow user to print */ + return (1); + } + } + else +#endif /* __APPLE__ */ + if (p->k_limit || p->page_limit) + { + if ((q = cupsdUpdateQuota(p, username, 0, 0)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate quota data for user \"%s\"!", + username); + return (-1); + } + + if ((q->k_count >= p->k_limit && p->k_limit) || + (q->page_count >= p->page_limit && p->page_limit)) + { + cupsdLogMessage(CUPSD_LOG_INFO, "User \"%s\" is over the quota limit...", + username); + return (-1); + } + } + + /* + * If we have gotten this far, we're done! + */ + + return (1); +} + + +/* + * 'copy_attribute()' - Copy a single attribute. + */ + +static ipp_attribute_t * /* O - New attribute */ +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 */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_attribute(%p, %p[%s,%x,%x])", to, attr, + attr->name ? attr->name : "(null)", attr->group_tag, + attr->value_tag); + + switch (attr->value_tag & ~IPP_TAG_COPY) + { + case IPP_TAG_ZERO : + toattr = 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 if (attr->value_tag & IPP_TAG_COPY) + { + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].string.text = + _cupsStrAlloc(attr->values[i].string.text); + } + else + { + for (i = 0; i < attr->num_values; i ++) + toattr->values[i].string.text = + _cupsStrRetain(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 if (attr->value_tag & IPP_TAG_COPY) + { + for (i = 0; i < attr->num_values; i ++) + { + if (!i) + toattr->values[i].string.charset = + _cupsStrAlloc(attr->values[i].string.charset); + else + toattr->values[i].string.charset = + toattr->values[0].string.charset; + + toattr->values[i].string.text = + _cupsStrAlloc(attr->values[i].string.text); + } + } + else + { + for (i = 0; i < attr->num_values; i ++) + { + if (!i) + toattr->values[i].string.charset = + _cupsStrRetain(attr->values[i].string.charset); + else + toattr->values[i].string.charset = + toattr->values[0].string.charset; + + toattr->values[i].string.text = + _cupsStrRetain(attr->values[i].string.text); + } + } + break; + + case IPP_TAG_BEGIN_COLLECTION : + toattr = ippAddCollections(to, attr->group_tag, attr->name, + attr->num_values, NULL); + + for (i = 0; i < attr->num_values; i ++) + { + toattr->values[i].collection = attr->values[i].collection; + attr->values[i].collection->use ++; + } + 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 */ + } + + return (toattr); +} + + +/* + * '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 */ + cups_array_t *ra, /* I - Requested attributes */ + ipp_tag_t group, /* I - Group to copy */ + int quickcopy) /* I - Do a quick copy? */ +{ + ipp_attribute_t *fromattr; /* Source attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_attrs(to=%p, from=%p, ra=%p, group=%x, quickcopy=%d)", + to, from, ra, group, quickcopy); + + if (!to || !from) + return; + + for (fromattr = from->attrs; fromattr; fromattr = fromattr->next) + { + /* + * Filter attributes as needed... + */ + + if ((group != IPP_TAG_ZERO && fromattr->group_tag != group && + fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name) + continue; + + if (!ra || cupsArrayFind(ra, fromattr->name)) + { + /* + * Don't send collection attributes by default to IPP/1.x clients + * since many do not support collections. Also don't send + * media-col-database unless specifically requested by the client. + */ + + if (fromattr->value_tag == IPP_TAG_BEGIN_COLLECTION && + !ra && + (to->request.status.version[0] == 1 || + !strcmp(fromattr->name, "media-col-database"))) + continue; + + copy_attribute(to, fromattr, quickcopy); + } + } +} + + +/* + * '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(cupsd_client_t *con, /* I - Client connection */ + cupsd_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 */ + cupsd_banner_t *banner; /* Pointer to banner */ + cups_file_t *in; /* Input file */ + cups_file_t *out; /* Output file */ + int ch; /* Character from file */ + char attrname[255], /* Name of attribute */ + *s; /* Pointer into name */ + ipp_attribute_t *attr; /* Attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_banner(con=%p[%d], job=%p[%d], name=\"%s\")", + con, con ? con->http.fd : -1, job, job->id, + name ? name : "(null)"); + + /* + * Find the banner; return if not found or "none"... + */ + + if (!name || !strcmp(name, "none") || + (banner = cupsdFindBanner(name)) == NULL) + return (0); + + /* + * Open the banner and job files... + */ + + if (add_file(con, job, banner->filetype, 0)) + return (-1); + + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, + job->num_files); + if ((out = cupsFileOpen(filename, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create banner job file %s - %s", + filename, strerror(errno)); + job->num_files --; + return (0); + } + + fchmod(cupsFileNumber(out), 0640); + fchown(cupsFileNumber(out), RunUser, Group); + + /* + * Try the localized banner file under the subdirectory... + */ + + strlcpy(attrname, job->attrs->attrs->next->values[0].string.text, + sizeof(attrname)); + if (strlen(attrname) > 2 && attrname[2] == '-') + { + /* + * Convert ll-cc to ll_CC... + */ + + attrname[2] = '_'; + attrname[3] = toupper(attrname[3] & 255); + attrname[4] = toupper(attrname[4] & 255); + } + + snprintf(filename, sizeof(filename), "%s/banners/%s/%s", DataDir, + attrname, name); + + if (access(filename, 0) && strlen(attrname) > 2) + { + /* + * Wasn't able to find "ll_CC" locale file; try the non-national + * localization banner directory. + */ + + 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); + } + + if ((in = cupsFileOpen(filename, "r")) == NULL) + { + cupsFileClose(out); + unlink(filename); + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open banner template file %s - %s", + filename, strerror(errno)); + job->num_files --; + return (0); + } + + /* + * Parse the file to the end... + */ + + while ((ch = cupsFileGetChar(in)) != EOF) + if (ch == '{') + { + /* + * Get an attribute name... + */ + + for (s = attrname; (ch = cupsFileGetChar(in)) != EOF;) + if (!isalpha(ch & 255) && 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... + */ + + cupsFilePrintf(out, "{%s%c", attrname, ch); + continue; + } + + /* + * See if it is defined... + */ + + if (attrname[0] == '?') + s = attrname + 1; + else + s = attrname; + + if (!strcmp(s, "printer-name")) + { + cupsFilePuts(out, job->dest); + 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... + */ + + cupsFilePrintf(out, "{%s}", attrname); + } + + continue; + } + + /* + * Output value(s)... + */ + + for (i = 0; i < attr->num_values; i ++) + { + if (i) + cupsFilePutChar(out, ','); + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + if (!strncmp(s, "time-at-", 8)) + { + struct timeval tv; /* Time value */ + + tv.tv_sec = attr->values[i].integer; + tv.tv_usec = 0; + + cupsFilePuts(out, cupsdGetDateTime(&tv, CUPSD_TIME_STANDARD)); + } + else + cupsFilePrintf(out, "%d", attr->values[i].integer); + break; + + case IPP_TAG_BOOLEAN : + cupsFilePrintf(out, "%d", attr->values[i].boolean); + break; + + case IPP_TAG_NOVALUE : + cupsFilePuts(out, "novalue"); + break; + + case IPP_TAG_RANGE : + cupsFilePrintf(out, "%d-%d", attr->values[i].range.lower, + attr->values[i].range.upper); + break; + + case IPP_TAG_RESOLUTION : + cupsFilePrintf(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")) + { + /* + * Need to quote strings for PS banners... + */ + + const char *p; + + for (p = attr->values[i].string.text; *p; p ++) + { + if (*p == '(' || *p == ')' || *p == '\\') + { + cupsFilePutChar(out, '\\'); + cupsFilePutChar(out, *p); + } + else if (*p < 32 || *p > 126) + cupsFilePrintf(out, "\\%03o", *p & 255); + else + cupsFilePutChar(out, *p); + } + } + else + cupsFilePuts(out, attr->values[i].string.text); + break; + + default : + break; /* anti-compiler-warning-code */ + } + } + } + else if (ch == '\\') /* Quoted char */ + { + ch = cupsFileGetChar(in); + + if (ch != '{') /* Only do special handling for \{ */ + cupsFilePutChar(out, '\\'); + + cupsFilePutChar(out, ch); + } + else + cupsFilePutChar(out, ch); + + cupsFileClose(in); + + kbytes = (cupsFileTell(out) + 1023) / 1024; + + if ((attr = ippFindAttribute(job->attrs, "job-k-octets", + IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + + cupsFileClose(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 */ +{ + cups_file_t *src, /* Source file */ + *dst; /* Destination file */ + int bytes; /* Bytes to read/write */ + char buffer[2048]; /* Copy buffer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "copy_file(\"%s\", \"%s\")", from, to); + + /* + * Open the source and destination file for a copy... + */ + + if ((src = cupsFileOpen(from, "rb")) == NULL) + return (-1); + + if ((dst = cupsFileOpen(to, "wb")) == NULL) + { + cupsFileClose(src); + return (-1); + } + + /* + * Copy the source file to the destination... + */ + + while ((bytes = cupsFileRead(src, buffer, sizeof(buffer))) > 0) + if (cupsFileWrite(dst, buffer, bytes) < bytes) + { + cupsFileClose(src); + cupsFileClose(dst); + return (-1); + } + + /* + * Close both files and return... + */ + + cupsFileClose(src); + + return (cupsFileClose(dst)); +} + + +/* + * 'copy_model()' - Copy a PPD model file, substituting default values + * as needed... + */ + +static int /* O - 0 = success, -1 = error */ +copy_model(cupsd_client_t *con, /* I - Client connection */ + const char *from, /* I - Source file */ + const char *to) /* I - Destination file */ +{ + fd_set input; /* select() input set */ + struct timeval timeout; /* select() timeout */ + int maxfd; /* Max file descriptor for select() */ + char tempfile[1024]; /* Temporary PPD file */ + int tempfd; /* Temporary PPD file descriptor */ + int temppid; /* Process ID of cups-driverd */ + int temppipe[2]; /* Temporary pipes */ + char *argv[4], /* Command-line arguments */ + *envp[MAX_ENV]; /* Environment */ + cups_file_t *src, /* Source file */ + *dst; /* Destination file */ + ppd_file_t *ppd; /* PPD file */ + int bytes, /* Bytes from pipe */ + total; /* Total bytes from pipe */ + char buffer[2048]; /* Copy buffer */ + int i; /* Looping var */ + char option[PPD_MAX_NAME], /* Option name */ + choice[PPD_MAX_NAME]; /* Choice name */ + ppd_size_t *size; /* Default size */ + int num_defaults; /* Number of default options */ + cups_option_t *defaults; /* Default options */ + char cups_protocol[PPD_MAX_LINE]; + /* cupsProtocol attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "copy_model(con=%p, from=\"%s\", to=\"%s\")", + con, from, to); + + /* + * Run cups-driverd to get the PPD file... + */ + + argv[0] = "cups-driverd"; + argv[1] = "cat"; + argv[2] = (char *)from; + argv[3] = NULL; + + cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + + snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin); + snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd); + tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (tempfd < 0) + return (-1); + + cupsdOpenPipe(temppipe); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "copy_model: Running \"cups-driverd cat %s\"...", from); + + if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1], + -1, -1, 0, DefaultProfile, NULL, &temppid)) + { + close(tempfd); + unlink(tempfile); + + return (-1); + } + + close(temppipe[1]); + + /* + * Wait up to 30 seconds for the PPD file to be copied... + */ + + total = 0; + + if (temppipe[0] > CGIPipes[0]) + maxfd = temppipe[0] + 1; + else + maxfd = CGIPipes[0] + 1; + + for (;;) + { + /* + * See if we have data ready... + */ + + FD_ZERO(&input); + FD_SET(temppipe[0], &input); + FD_SET(CGIPipes[0], &input); + + timeout.tv_sec = 30; + timeout.tv_usec = 0; + + if ((i = select(maxfd, &input, NULL, NULL, &timeout)) < 0) + { + if (errno == EINTR) + continue; + else + break; + } + else if (i == 0) + { + /* + * We have timed out... + */ + + break; + } + + if (FD_ISSET(temppipe[0], &input)) + { + /* + * Read the PPD file from the pipe, and write it to the PPD file. + */ + + if ((bytes = read(temppipe[0], buffer, sizeof(buffer))) > 0) + { + if (write(tempfd, buffer, bytes) < bytes) + break; + + total += bytes; + } + else + break; + } + + if (FD_ISSET(CGIPipes[0], &input)) + cupsdUpdateCGI(); + } + + close(temppipe[0]); + close(tempfd); + + if (!total) + { + /* + * No data from cups-deviced... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "copy_model: empty PPD file!"); + unlink(tempfile); + return (-1); + } + + /* + * Read the source file and see what page sizes are supported... + */ + + if ((ppd = ppdOpenFile(tempfile)) == NULL) + { + unlink(tempfile); + return (-1); + } + + /* + * Open the destination (if possible) and set the default options... + */ + + num_defaults = 0; + defaults = NULL; + cups_protocol[0] = '\0'; + + if ((dst = cupsFileOpen(to, "rb")) != NULL) + { + /* + * Read all of the default lines from the old PPD... + */ + + while (cupsFileGets(dst, buffer, sizeof(buffer))) + if (!strncmp(buffer, "*Default", 8)) + { + /* + * Add the default option... + */ + + if (!ppd_parse_line(buffer, option, sizeof(option), + choice, sizeof(choice))) + { + ppd_option_t *ppdo; /* PPD option */ + + + /* + * Only add the default if the default hasn't already been + * set and the choice exists in the new PPD... + */ + + if (!cupsGetOption(option, num_defaults, defaults) && + (ppdo = ppdFindOption(ppd, option)) != NULL && + ppdFindChoice(ppdo, choice)) + num_defaults = cupsAddOption(option, choice, num_defaults, + &defaults); + } + } + else if (!strncmp(buffer, "*cupsProtocol:", 14)) + strlcpy(cups_protocol, buffer, sizeof(cups_protocol)); + + cupsFileClose(dst); + } + else if ((size = ppdPageSize(ppd, DefaultPaperSize)) != NULL) + { + /* + * Add the default media sizes... + */ + + num_defaults = cupsAddOption("PageSize", size->name, + num_defaults, &defaults); + num_defaults = cupsAddOption("PageRegion", size->name, + num_defaults, &defaults); + num_defaults = cupsAddOption("PaperDimension", size->name, + num_defaults, &defaults); + num_defaults = cupsAddOption("ImageableArea", size->name, + num_defaults, &defaults); + } + + ppdClose(ppd); + + /* + * Open the source file for a copy... + */ + + if ((src = cupsFileOpen(tempfile, "rb")) == NULL) + { + cupsFreeOptions(num_defaults, defaults); + unlink(tempfile); + return (-1); + } + + /* + * Open the destination file for a copy... + */ + + if ((dst = cupsFileOpen(to, "wb")) == NULL) + { + cupsFreeOptions(num_defaults, defaults); + cupsFileClose(src); + unlink(tempfile); + return (-1); + } + + /* + * Copy the source file to the destination... + */ + + while (cupsFileGets(src, buffer, sizeof(buffer))) + { + if (!strncmp(buffer, "*Default", 8)) + { + /* + * Check for an previous default option choice... + */ + + if (!ppd_parse_line(buffer, option, sizeof(option), + choice, sizeof(choice))) + { + const char *val; /* Default option value */ + + + if ((val = cupsGetOption(option, num_defaults, defaults)) != NULL) + { + /* + * Substitute the previous choice... + */ + + snprintf(buffer, sizeof(buffer), "*Default%s: %s", option, val); + } + } + } + + cupsFilePrintf(dst, "%s\n", buffer); + } + + if (cups_protocol[0]) + cupsFilePrintf(dst, "%s\n", cups_protocol); + + cupsFreeOptions(num_defaults, defaults); + + /* + * Close both files and return... + */ + + cupsFileClose(src); + + unlink(tempfile); + + return (cupsFileClose(dst)); +} + + +/* + * 'copy_job_attrs()' - Copy job attributes. + */ + +static void +copy_job_attrs(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job, /* I - Job */ + cups_array_t *ra) /* I - Requested attributes array */ +{ + char job_uri[HTTP_MAX_URI]; /* Job URI */ + + + /* + * Send the requested attributes for each job... + */ + + httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL, + con->servername, con->serverport, "/jobs/%d", + job->id); + + if (!ra || cupsArrayFind(ra, "document-count")) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "document-count", job->num_files); + + if (!ra || cupsArrayFind(ra, "job-media-progress")) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-media-progress", job->progress); + + if (!ra || cupsArrayFind(ra, "job-more-info")) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, + "job-more-info", NULL, job_uri); + + if (job->state_value > IPP_JOB_PROCESSING && + (!ra || cupsArrayFind(ra, "job-preserved"))) + ippAddBoolean(con->response, IPP_TAG_JOB, "job-preserved", + job->num_files > 0); + + if (!ra || cupsArrayFind(ra, "job-printer-up-time")) + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, + "job-printer-up-time", time(NULL)); + + if (!ra || cupsArrayFind(ra, "job-state-reasons")) + add_job_state_reasons(con, job); + + if (!ra || cupsArrayFind(ra, "job-uri")) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI, + "job-uri", NULL, job_uri); + + copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0); +} + + +/* + * 'copy_printer_attrs()' - Copy printer attributes. + */ + +static void +copy_printer_attrs( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *printer, /* I - Printer */ + cups_array_t *ra) /* I - Requested attributes array */ +{ + char printer_uri[HTTP_MAX_URI]; + /* Printer URI */ + char printer_icons[HTTP_MAX_URI]; + /* Printer icons */ + time_t curtime; /* Current time */ + int i; /* Looping var */ + ipp_attribute_t *history; /* History collection */ + + + /* + * Copy the printer attributes to the response using requested-attributes + * and document-format attributes that may be provided by the client. + */ + + curtime = time(NULL); + +#ifdef __APPLE__ + if ((!ra || cupsArrayFind(ra, "com.apple.print.recoverable-message")) && + printer->recoverable) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "com.apple.print.recoverable-message", NULL, + printer->recoverable); +#endif /* __APPLE__ */ + + if (!ra || cupsArrayFind(ra, "marker-change-time")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "marker-change-time", printer->marker_time); + + if (printer->num_printers > 0 && + (!ra || cupsArrayFind(ra, "member-uris"))) + { + ipp_attribute_t *member_uris; /* member-uris attribute */ + cupsd_printer_t *p2; /* Printer in class */ + ipp_attribute_t *p2_uri; /* printer-uri-supported for class printer */ + + + if ((member_uris = ippAddStrings(con->response, IPP_TAG_PRINTER, + IPP_TAG_URI, "member-uris", + printer->num_printers, NULL, + NULL)) != NULL) + { + for (i = 0; i < printer->num_printers; i ++) + { + p2 = printer->printers[i]; + + if ((p2_uri = ippFindAttribute(p2->attrs, "printer-uri-supported", + IPP_TAG_URI)) != NULL) + member_uris->values[i].string.text = + _cupsStrRetain(p2_uri->values[0].string.text); + else + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, + sizeof(printer_uri), "ipp", NULL, con->servername, + con->serverport, + (p2->type & CUPS_PRINTER_CLASS) ? + "/classes/%s" : "/printers/%s", p2->name); + member_uris->values[i].string.text = _cupsStrAlloc(printer_uri); + } + } + } + } + + if (printer->alert && (!ra || cupsArrayFind(ra, "printer-alert"))) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING, + "printer-alert", NULL, printer->alert); + + if (printer->alert_description && + (!ra || cupsArrayFind(ra, "printer-alert-description"))) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-alert-description", NULL, + printer->alert_description); + + if (!ra || cupsArrayFind(ra, "printer-current-time")) + ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time", + ippTimeToDate(curtime)); + +#ifdef HAVE_DNSSD + if (!ra || cupsArrayFind(ra, "printer-dns-sd-name")) + { + if (printer->reg_name) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-dns-sd-name", NULL, printer->reg_name); + else + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, + "printer-dns-sd-name", 0); + } +#endif /* HAVE_DNSSD */ + + if (!ra || cupsArrayFind(ra, "printer-error-policy")) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-error-policy", NULL, printer->error_policy); + + if (!ra || cupsArrayFind(ra, "printer-error-policy-supported")) + { + static const char * const errors[] =/* printer-error-policy-supported values */ + { + "abort-job", + "retry-current-job", + "retry-job", + "stop-printer" + }; + + if (printer->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS)) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, + "printer-error-policy-supported", NULL, "retry-current-job"); + else + ippAddStrings(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, + "printer-error-policy-supported", + sizeof(errors) / sizeof(errors[0]), NULL, errors); + } + + if (!ra || cupsArrayFind(ra, "printer-icons")) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_icons, sizeof(printer_icons), + "http", NULL, con->servername, con->serverport, + "/icons/%s.png", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-icons", + NULL, printer_icons); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-icons=\"%s\"", printer_icons); + } + + if (!ra || cupsArrayFind(ra, "printer-is-accepting-jobs")) + ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", + printer->accepting); + + if (!ra || cupsArrayFind(ra, "printer-is-shared")) + ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-shared", + printer->shared); + + if ((!ra || cupsArrayFind(ra, "printer-more-info")) && + !(printer->type & CUPS_PRINTER_DISCOVERED)) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "http", NULL, con->servername, con->serverport, + (printer->type & CUPS_PRINTER_CLASS) ? + "/classes/%s" : "/printers/%s", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-more-info", NULL, printer_uri); + } + + if (!ra || cupsArrayFind(ra, "printer-op-policy")) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME, + "printer-op-policy", NULL, printer->op_policy); + + if (!ra || cupsArrayFind(ra, "printer-state")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", + printer->state); + + if (!ra || cupsArrayFind(ra, "printer-state-change-time")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "printer-state-change-time", printer->state_time); + + if (MaxPrinterHistory > 0 && printer->num_history > 0 && + cupsArrayFind(ra, "printer-state-history")) + { + /* + * Printer history is only sent if specifically requested, so that + * older CUPS/IPP clients won't barf on the collection attributes. + */ + + history = ippAddCollections(con->response, IPP_TAG_PRINTER, + "printer-state-history", + printer->num_history, NULL); + + for (i = 0; i < printer->num_history; i ++) + copy_attrs(history->values[i].collection = ippNew(), printer->history[i], + NULL, IPP_TAG_ZERO, 0); + } + + if (!ra || cupsArrayFind(ra, "printer-state-message")) + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-state-message", NULL, printer->state_message); + + if (!ra || cupsArrayFind(ra, "printer-state-reasons")) + add_printer_state_reasons(con, printer); + + if (!ra || cupsArrayFind(ra, "printer-type")) + { + int type; /* printer-type value */ + + + /* + * Add the CUPS-specific printer-type attribute... + */ + + type = printer->type; + + if (printer == DefaultPrinter) + type |= CUPS_PRINTER_DEFAULT; + + if (!printer->accepting) + type |= CUPS_PRINTER_REJECTING; + + if (!printer->shared) + type |= CUPS_PRINTER_NOT_SHARED; + + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-type", + type); + } + + if (!ra || cupsArrayFind(ra, "printer-up-time")) + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "printer-up-time", curtime); + + if ((!ra || cupsArrayFind(ra, "printer-uri-supported")) && + !(printer->type & CUPS_PRINTER_DISCOVERED)) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "ipp", NULL, con->servername, con->serverport, + (printer->type & CUPS_PRINTER_CLASS) ? + "/classes/%s" : "/printers/%s", printer->name); + ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-uri-supported", NULL, printer_uri); + cupsdLogMessage(CUPSD_LOG_DEBUG2, "printer-uri-supported=\"%s\"", + printer_uri); + } + + if (!ra || cupsArrayFind(ra, "queued-job-count")) + add_queued_job_count(con, printer); + + copy_attrs(con->response, printer->attrs, ra, IPP_TAG_ZERO, 0); + if (printer->ppd_attrs) + copy_attrs(con->response, printer->ppd_attrs, ra, IPP_TAG_ZERO, 0); + copy_attrs(con->response, CommonData, ra, IPP_TAG_ZERO, IPP_TAG_COPY); +} + + +/* + * 'copy_subscription_attrs()' - Copy subscription attributes. + */ + +static void +copy_subscription_attrs( + cupsd_client_t *con, /* I - Client connection */ + cupsd_subscription_t *sub, /* I - Subscription */ + cups_array_t *ra) /* I - Requested attributes array */ +{ + ipp_attribute_t *attr; /* Current attribute */ + char printer_uri[HTTP_MAX_URI]; + /* Printer URI */ + int count; /* Number of events */ + unsigned mask; /* Current event mask */ + const char *name; /* Current event name */ + + + /* + * Copy the subscription attributes to the response using the + * requested-attributes attribute that may be provided by the client. + */ + + if (!ra || cupsArrayFind(ra, "notify-events")) + { + if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL) + { + /* + * Simple event list... + */ + + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, + (ipp_tag_t)(IPP_TAG_KEYWORD | IPP_TAG_COPY), + "notify-events", NULL, name); + } + else + { + /* + * Complex event list... + */ + + for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + count ++; + + attr = ippAddStrings(con->response, IPP_TAG_SUBSCRIPTION, + (ipp_tag_t)(IPP_TAG_KEYWORD | IPP_TAG_COPY), + "notify-events", count, NULL, NULL); + + for (mask = 1, count = 0; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + { + attr->values[count].string.text = + (char *)cupsdEventName((cupsd_eventmask_t)mask); + + count ++; + } + } + } + + if (sub->job && (!ra || cupsArrayFind(ra, "notify-job-id"))) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-job-id", sub->job->id); + + if (!sub->job && (!ra || cupsArrayFind(ra, "notify-lease-duration"))) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-lease-duration", sub->lease); + + if (sub->dest && (!ra || cupsArrayFind(ra, "notify-printer-uri"))) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "ipp", NULL, con->servername, con->serverport, + "/printers/%s", sub->dest->name); + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-printer-uri", NULL, printer_uri); + } + + if (sub->recipient && (!ra || cupsArrayFind(ra, "notify-recipient-uri"))) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, + "notify-recipient-uri", NULL, sub->recipient); + else if (!ra || cupsArrayFind(ra, "notify-pull-method")) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, + "notify-pull-method", NULL, "ippget"); + + if (!ra || cupsArrayFind(ra, "notify-subscriber-user-name")) + ippAddString(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME, + "notify-subscriber-user-name", NULL, sub->owner); + + if (!ra || cupsArrayFind(ra, "notify-subscription-id")) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); + + if (!ra || cupsArrayFind(ra, "notify-time-interval")) + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-time-interval", sub->interval); + + if (sub->user_data_len > 0 && (!ra || cupsArrayFind(ra, "notify-user-data"))) + ippAddOctetString(con->response, IPP_TAG_SUBSCRIPTION, "notify-user-data", + sub->user_data, sub->user_data_len); +} + + +/* + * 'create_job()' - Print a file to a printer or class. + */ + +static void +create_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + cupsd_printer_t *printer; /* Printer */ + cupsd_job_t *job; /* New job */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "create_job(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, NULL, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Create the job object... + */ + + if ((job = add_job(con, printer, NULL)) == NULL) + return; + + job->pending_timeout = 1; + + /* + * Save and log the job... + */ + + cupsdLogJob(job, CUPSD_LOG_INFO, "Queued on \"%s\" by \"%s\".", + job->dest, job->username); +} + + +/* + * 'create_requested_array()' - Create an array for the requested-attributes. + */ + +static cups_array_t * /* O - Array of attributes or NULL */ +create_requested_array(ipp_t *request) /* I - IPP request */ +{ + int i; /* Looping var */ + ipp_attribute_t *requested; /* requested-attributes attribute */ + cups_array_t *ra; /* Requested attributes array */ + char *value; /* Current value */ + + + /* + * Get the requested-attributes attribute, and return NULL if we don't + * have one... + */ + + if ((requested = ippFindAttribute(request, "requested-attributes", + IPP_TAG_KEYWORD)) == NULL) + return (NULL); + + /* + * If the attribute contains a single "all" keyword, return NULL... + */ + + if (requested->num_values == 1 && + !strcmp(requested->values[0].string.text, "all")) + return (NULL); + + /* + * Create an array using "strcmp" as the comparison function... + */ + + ra = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + for (i = 0; i < requested->num_values; i ++) + { + value = requested->values[i].string.text; + + if (!strcmp(value, "job-template")) + { + cupsArrayAdd(ra, "copies"); + cupsArrayAdd(ra, "copies-default"); + cupsArrayAdd(ra, "copies-supported"); + cupsArrayAdd(ra, "finishings"); + cupsArrayAdd(ra, "finishings-default"); + cupsArrayAdd(ra, "finishings-supported"); + cupsArrayAdd(ra, "job-hold-until"); + cupsArrayAdd(ra, "job-hold-until-default"); + cupsArrayAdd(ra, "job-hold-until-supported"); + cupsArrayAdd(ra, "job-priority"); + cupsArrayAdd(ra, "job-priority-default"); + cupsArrayAdd(ra, "job-priority-supported"); + cupsArrayAdd(ra, "job-sheets"); + cupsArrayAdd(ra, "job-sheets-default"); + cupsArrayAdd(ra, "job-sheets-supported"); + cupsArrayAdd(ra, "media"); + cupsArrayAdd(ra, "media-default"); + cupsArrayAdd(ra, "media-supported"); + cupsArrayAdd(ra, "multiple-document-handling"); + cupsArrayAdd(ra, "multiple-document-handling-default"); + cupsArrayAdd(ra, "multiple-document-handling-supported"); + cupsArrayAdd(ra, "number-up"); + cupsArrayAdd(ra, "number-up-default"); + cupsArrayAdd(ra, "number-up-supported"); + cupsArrayAdd(ra, "orientation-requested"); + cupsArrayAdd(ra, "orientation-requested-default"); + cupsArrayAdd(ra, "orientation-requested-supported"); + cupsArrayAdd(ra, "page-ranges"); + cupsArrayAdd(ra, "page-ranges-supported"); + cupsArrayAdd(ra, "printer-resolution"); + cupsArrayAdd(ra, "printer-resolution-default"); + cupsArrayAdd(ra, "printer-resolution-supported"); + cupsArrayAdd(ra, "print-quality"); + cupsArrayAdd(ra, "print-quality-default"); + cupsArrayAdd(ra, "print-quality-supported"); + cupsArrayAdd(ra, "sides"); + cupsArrayAdd(ra, "sides-default"); + cupsArrayAdd(ra, "sides-supported"); + } + else if (!strcmp(value, "job-description")) + { + cupsArrayAdd(ra, "date-time-at-completed"); + cupsArrayAdd(ra, "date-time-at-creation"); + cupsArrayAdd(ra, "date-time-at-processing"); + cupsArrayAdd(ra, "job-detailed-status-message"); + cupsArrayAdd(ra, "job-document-access-errors"); + cupsArrayAdd(ra, "job-id"); + cupsArrayAdd(ra, "job-impressions"); + cupsArrayAdd(ra, "job-impressions-completed"); + cupsArrayAdd(ra, "job-k-octets"); + cupsArrayAdd(ra, "job-k-octets-processed"); + cupsArrayAdd(ra, "job-media-progress"); + cupsArrayAdd(ra, "job-media-sheets"); + cupsArrayAdd(ra, "job-media-sheets-completed"); + cupsArrayAdd(ra, "job-message-from-operator"); + cupsArrayAdd(ra, "job-more-info"); + cupsArrayAdd(ra, "job-name"); + cupsArrayAdd(ra, "job-originating-user-name"); + cupsArrayAdd(ra, "job-printer-up-time"); + cupsArrayAdd(ra, "job-printer-uri"); + cupsArrayAdd(ra, "job-state"); + cupsArrayAdd(ra, "job-state-message"); + cupsArrayAdd(ra, "job-state-reasons"); + cupsArrayAdd(ra, "job-uri"); + cupsArrayAdd(ra, "number-of-documents"); + cupsArrayAdd(ra, "number-of-intervening-jobs"); + cupsArrayAdd(ra, "output-device-assigned"); + cupsArrayAdd(ra, "time-at-completed"); + cupsArrayAdd(ra, "time-at-creation"); + cupsArrayAdd(ra, "time-at-processing"); + } + else if (!strcmp(value, "printer-description")) + { + cupsArrayAdd(ra, "charset-configured"); + cupsArrayAdd(ra, "charset-supported"); + cupsArrayAdd(ra, "color-supported"); + cupsArrayAdd(ra, "compression-supported"); + cupsArrayAdd(ra, "document-format-default"); + cupsArrayAdd(ra, "document-format-supported"); + cupsArrayAdd(ra, "generated-natural-language-supported"); + cupsArrayAdd(ra, "ipp-versions-supported"); + cupsArrayAdd(ra, "job-impressions-supported"); + cupsArrayAdd(ra, "job-k-octets-supported"); + cupsArrayAdd(ra, "job-media-sheets-supported"); + cupsArrayAdd(ra, "job-settable-attributes-supported"); + cupsArrayAdd(ra, "multiple-document-jobs-supported"); + cupsArrayAdd(ra, "multiple-operation-time-out"); + cupsArrayAdd(ra, "natural-language-configured"); + cupsArrayAdd(ra, "notify-attributes-supported"); + cupsArrayAdd(ra, "notify-lease-duration-default"); + cupsArrayAdd(ra, "notify-lease-duration-supported"); + cupsArrayAdd(ra, "notify-max-events-supported"); + cupsArrayAdd(ra, "notify-events-default"); + cupsArrayAdd(ra, "notify-events-supported"); + cupsArrayAdd(ra, "notify-pull-method-supported"); + cupsArrayAdd(ra, "notify-schemes-supported"); + cupsArrayAdd(ra, "operations-supported"); + cupsArrayAdd(ra, "pages-per-minute"); + cupsArrayAdd(ra, "pages-per-minute-color"); + cupsArrayAdd(ra, "pdl-override-supported"); + cupsArrayAdd(ra, "printer-alert"); + cupsArrayAdd(ra, "printer-alert-description"); + cupsArrayAdd(ra, "printer-commands"); + cupsArrayAdd(ra, "printer-current-time"); + cupsArrayAdd(ra, "printer-driver-installer"); + cupsArrayAdd(ra, "printer-dns-sd-name"); + cupsArrayAdd(ra, "printer-info"); + cupsArrayAdd(ra, "printer-is-accepting-jobs"); + cupsArrayAdd(ra, "printer-location"); + cupsArrayAdd(ra, "printer-make-and-model"); + cupsArrayAdd(ra, "printer-message-from-operator"); + cupsArrayAdd(ra, "printer-more-info"); + cupsArrayAdd(ra, "printer-more-info-manufacturer"); + cupsArrayAdd(ra, "printer-name"); + cupsArrayAdd(ra, "printer-state"); + cupsArrayAdd(ra, "printer-state-message"); + cupsArrayAdd(ra, "printer-state-reasons"); + cupsArrayAdd(ra, "printer-settable-attributes-supported"); + cupsArrayAdd(ra, "printer-type"); + cupsArrayAdd(ra, "printer-up-time"); + cupsArrayAdd(ra, "printer-uri-supported"); + cupsArrayAdd(ra, "queued-job-count"); + cupsArrayAdd(ra, "reference-uri-schemes-supported"); + cupsArrayAdd(ra, "uri-authentication-supported"); + cupsArrayAdd(ra, "uri-security-supported"); + } + else if (!strcmp(value, "printer-defaults")) + { + char *name; /* Option name */ + + + for (name = (char *)cupsArrayFirst(CommonDefaults); + name; + name = (char *)cupsArrayNext(CommonDefaults)) + cupsArrayAdd(ra, name); + } + else if (!strcmp(value, "subscription-template")) + { + cupsArrayAdd(ra, "notify-attributes"); + cupsArrayAdd(ra, "notify-charset"); + cupsArrayAdd(ra, "notify-events"); + cupsArrayAdd(ra, "notify-lease-duration"); + cupsArrayAdd(ra, "notify-natural-language"); + cupsArrayAdd(ra, "notify-pull-method"); + cupsArrayAdd(ra, "notify-recipient-uri"); + cupsArrayAdd(ra, "notify-time-interval"); + cupsArrayAdd(ra, "notify-user-data"); + } + else + cupsArrayAdd(ra, value); + } + + return (ra); +} + + +/* + * 'create_subscription()' - Create a notification subscription. + */ + +static void +create_subscription( + cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Current attribute */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + char scheme[HTTP_MAX_URI], + /* Scheme portion of URI */ + userpass[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 */ + cupsd_printer_t *printer; /* Printer/class */ + cupsd_job_t *job; /* Job */ + int jobid; /* Job ID */ + cupsd_subscription_t *sub; /* Subscription object */ + const char *username, /* requesting-user-name or + authenticated username */ + *recipient, /* notify-recipient-uri */ + *pullmethod; /* notify-pull-method */ + ipp_attribute_t *user_data; /* notify-user-data */ + int interval, /* notify-time-interval */ + lease; /* notify-lease-duration */ + unsigned mask; /* notify-events */ + ipp_attribute_t *notify_events,/* notify-events(-default) */ + *notify_lease; /* notify-lease-duration(-default) */ + + +#ifdef DEBUG + for (attr = con->request->attrs; attr; attr = attr->next) + { + if (attr->group_tag != IPP_TAG_ZERO) + cupsdLogMessage(CUPSD_LOG_DEBUG2, "g%04x v%04x %s", attr->group_tag, + attr->value_tag, attr->name); + else + cupsdLogMessage(CUPSD_LOG_DEBUG2, "----SEP----"); + } +#endif /* DEBUG */ + + /* + * Is the destination valid? + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdCreateSubscription(con=%p(%d), uri=\"%s\")", + con, con->http.fd, uri->values[0].string.text); + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), userpass, sizeof(userpass), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(resource, "/")) + { + dtype = (cups_ptype_t)0; + printer = NULL; + } + else if (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) + { + dtype = (cups_ptype_t)0; + printer = NULL; + } + else if (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9) + { + dtype = CUPS_PRINTER_CLASS; + printer = NULL; + } + else if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if (printer) + { + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + } + else if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Get the user that is requesting the subscription... + */ + + username = get_username(con); + + /* + * Find the first subscription group attribute; return if we have + * none... + */ + + for (attr = con->request->attrs; attr; attr = attr->next) + if (attr->group_tag == IPP_TAG_SUBSCRIPTION) + break; + + if (!attr) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("No subscription attributes in request!")); + return; + } + + /* + * Process the subscription attributes in the request... + */ + + con->response->request.status.status_code = IPP_BAD_REQUEST; + + while (attr) + { + recipient = NULL; + pullmethod = NULL; + user_data = NULL; + interval = 0; + lease = DefaultLeaseDuration; + jobid = 0; + mask = CUPSD_EVENT_NONE; + + if (printer) + { + notify_events = ippFindAttribute(printer->attrs, "notify-events-default", + IPP_TAG_KEYWORD); + notify_lease = ippFindAttribute(printer->attrs, + "notify-lease-duration-default", + IPP_TAG_INTEGER); + + if (notify_lease) + lease = notify_lease->values[0].integer; + } + else + { + notify_events = NULL; + notify_lease = NULL; + } + + while (attr && attr->group_tag != IPP_TAG_ZERO) + { + if (!strcmp(attr->name, "notify-recipient-uri") && + attr->value_tag == IPP_TAG_URI) + { + /* + * Validate the recipient scheme against the ServerBin/notifier + * directory... + */ + + char notifier[1024]; /* Notifier filename */ + + + recipient = attr->values[0].string.text; + + if (httpSeparateURI(HTTP_URI_CODING_ALL, recipient, + scheme, sizeof(scheme), userpass, sizeof(userpass), + host, sizeof(host), &port, + resource, sizeof(resource)) < HTTP_URI_OK) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Bad notify-recipient-uri URI \"%s\"!"), recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_URI_SCHEME); + return; + } + + snprintf(notifier, sizeof(notifier), "%s/notifier/%s", ServerBin, + scheme); + if (access(notifier, X_OK)) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("notify-recipient-uri URI \"%s\" uses unknown " + "scheme!"), recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_URI_SCHEME); + return; + } + + if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient)) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("notify-recipient-uri URI \"%s\" is already used!"), + recipient); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_ATTRIBUTES); + return; + } + } + else if (!strcmp(attr->name, "notify-pull-method") && + attr->value_tag == IPP_TAG_KEYWORD) + { + pullmethod = attr->values[0].string.text; + + if (strcmp(pullmethod, "ippget")) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Bad notify-pull-method \"%s\"!"), pullmethod); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, + "notify-status-code", IPP_ATTRIBUTES); + return; + } + } + else if (!strcmp(attr->name, "notify-charset") && + attr->value_tag == IPP_TAG_CHARSET && + strcmp(attr->values[0].string.text, "us-ascii") && + strcmp(attr->values[0].string.text, "utf-8")) + { + send_ipp_status(con, IPP_CHARSET, + _("Character set \"%s\" not supported!"), + attr->values[0].string.text); + return; + } + else if (!strcmp(attr->name, "notify-natural-language") && + (attr->value_tag != IPP_TAG_LANGUAGE || + strcmp(attr->values[0].string.text, DefaultLanguage))) + { + send_ipp_status(con, IPP_CHARSET, + _("Language \"%s\" not supported!"), + attr->values[0].string.text); + return; + } + else if (!strcmp(attr->name, "notify-user-data") && + attr->value_tag == IPP_TAG_STRING) + { + if (attr->num_values > 1 || attr->values[0].unknown.length > 63) + { + send_ipp_status(con, IPP_REQUEST_VALUE, + _("The notify-user-data value is too large " + "(%d > 63 octets)!"), + attr->values[0].unknown.length); + return; + } + + user_data = attr; + } + else if (!strcmp(attr->name, "notify-events") && + attr->value_tag == IPP_TAG_KEYWORD) + notify_events = attr; + else if (!strcmp(attr->name, "notify-lease-duration") && + attr->value_tag == IPP_TAG_INTEGER) + lease = attr->values[0].integer; + else if (!strcmp(attr->name, "notify-time-interval") && + attr->value_tag == IPP_TAG_INTEGER) + interval = attr->values[0].integer; + else if (!strcmp(attr->name, "notify-job-id") && + attr->value_tag == IPP_TAG_INTEGER) + jobid = attr->values[0].integer; + + attr = attr->next; + } + + if (notify_events) + { + for (i = 0; i < notify_events->num_values; i ++) + mask |= cupsdEventValue(notify_events->values[i].string.text); + } + + if (recipient) + cupsdLogMessage(CUPSD_LOG_DEBUG, "recipient=\"%s\"", recipient); + if (pullmethod) + cupsdLogMessage(CUPSD_LOG_DEBUG, "pullmethod=\"%s\"", pullmethod); + cupsdLogMessage(CUPSD_LOG_DEBUG, "notify-lease-duration=%d", lease); + cupsdLogMessage(CUPSD_LOG_DEBUG, "notify-time-interval=%d", interval); + + if (!recipient && !pullmethod) + break; + + if (mask == CUPSD_EVENT_NONE) + { + if (jobid) + mask = CUPSD_EVENT_JOB_COMPLETED; + else if (printer) + mask = CUPSD_EVENT_PRINTER_STATE_CHANGED; + else + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("notify-events not specified!")); + return; + } + } + + if (MaxLeaseDuration && (lease == 0 || lease > MaxLeaseDuration)) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "create_subscription: Limiting notify-lease-duration to " + "%d seconds.", + MaxLeaseDuration); + lease = MaxLeaseDuration; + } + + if (jobid) + { + if ((job = cupsdFindJob(jobid)) == NULL) + { + send_ipp_status(con, IPP_NOT_FOUND, _("Job %d not found!"), jobid); + return; + } + } + else + job = NULL; + + if ((sub = cupsdAddSubscription(mask, printer, job, recipient, 0)) == NULL) + { + send_ipp_status(con, IPP_TOO_MANY_SUBSCRIPTIONS, + _("There are too many subscriptions.")); + return; + } + + if (job) + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for job %d", + sub->id, job->id); + else if (printer) + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Added subscription %d for printer \"%s\"", + sub->id, printer->name); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for server", + sub->id); + + sub->interval = interval; + sub->lease = lease; + sub->expire = lease ? time(NULL) + lease : 0; + + cupsdSetString(&sub->owner, username); + + if (user_data) + { + sub->user_data_len = user_data->values[0].unknown.length; + memcpy(sub->user_data, user_data->values[0].unknown.data, + sub->user_data_len); + } + + ippAddSeparator(con->response); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); + + con->response->request.status.status_code = IPP_OK; + + if (attr) + attr = attr->next; + } + + cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); +} + + +/* + * 'delete_printer()' - Remove a printer or class from the system. + */ + +static void +delete_printer(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - URI of printer or class */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer/class */ + char filename[1024]; /* Script/PPD filename */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "delete_printer(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Do we have a valid URI? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Remove old jobs... + */ + + cupsdCancelJobs(printer->name, NULL, 1); + + /* + * Remove old subscriptions and send a "deleted printer" event... + */ + + cupsdAddEvent(CUPSD_EVENT_PRINTER_DELETED, printer, NULL, + "%s \"%s\" deleted by \"%s\".", + (dtype & CUPS_PRINTER_CLASS) ? "Class" : "Printer", + printer->name, get_username(con)); + + cupsdExpireSubscriptions(printer, NULL); + + /* + * Remove any old PPD or script files... + */ + + snprintf(filename, sizeof(filename), "%s/interfaces/%s", ServerRoot, + printer->name); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, + printer->name); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.ipp4", CacheDir, printer->name); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, printer->name); + unlink(filename); + + snprintf(filename, sizeof(filename), "%s/%s.pwg3", CacheDir, printer->name); + unlink(filename); + +#ifdef __APPLE__ + /* + * Unregister color profiles... + */ + + apple_unregister_profiles(printer); +#endif /* __APPLE__ */ + + if (dtype & CUPS_PRINTER_CLASS) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" deleted by \"%s\".", + printer->name, get_username(con)); + + cupsdDeletePrinter(printer, 0); + cupsdMarkDirty(CUPSD_DIRTY_CLASSES); + } + else + { + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" deleted by \"%s\".", + printer->name, get_username(con)); + + if (cupsdDeletePrinter(printer, 0)) + cupsdMarkDirty(CUPSD_DIRTY_CLASSES); + + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); + + /* + * Return with no errors... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_default()' - Get the default destination. + */ + +static void +get_default(cupsd_client_t *con) /* I - Client connection */ +{ + http_status_t status; /* Policy status */ + cups_array_t *ra; /* Requested attributes array */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_default(%p[%d])", con, con->http.fd); + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + if (DefaultPrinter) + { + ra = create_requested_array(con->request); + + copy_printer_attrs(con, DefaultPrinter, ra); + + cupsArrayDelete(ra); + + con->response->request.status.status_code = IPP_OK; + } + else + send_ipp_status(con, IPP_NOT_FOUND, _("No default printer")); +} + + +/* + * 'get_devices()' - Get the list of available devices on the local system. + */ + +static void +get_devices(cupsd_client_t *con) /* I - Client connection */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *limit, /* limit attribute */ + *timeout, /* timeout attribute */ + *requested, /* requested-attributes attribute */ + *exclude, /* exclude-schemes attribute */ + *include; /* include-schemes attribute */ + char command[1024], /* cups-deviced command */ + options[2048], /* Options to pass to command */ + requested_str[256], + /* String for requested attributes */ + exclude_str[512], + /* String for excluded schemes */ + include_str[512]; + /* String for included schemes */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_devices(%p[%d])", con, con->http.fd); + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Run cups-deviced command with the given options... + */ + + limit = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER); + timeout = ippFindAttribute(con->request, "timeout", IPP_TAG_INTEGER); + requested = ippFindAttribute(con->request, "requested-attributes", + IPP_TAG_KEYWORD); + exclude = ippFindAttribute(con->request, "exclude-schemes", IPP_TAG_NAME); + include = ippFindAttribute(con->request, "include-schemes", IPP_TAG_NAME); + + if (requested) + url_encode_attr(requested, requested_str, sizeof(requested_str)); + else + strlcpy(requested_str, "requested-attributes=all", sizeof(requested_str)); + + if (exclude) + url_encode_attr(exclude, exclude_str, sizeof(exclude_str)); + else + exclude_str[0] = '\0'; + + if (include) + url_encode_attr(include, include_str, sizeof(include_str)); + else + include_str[0] = '\0'; + + snprintf(command, sizeof(command), "%s/daemon/cups-deviced", ServerBin); + snprintf(options, sizeof(options), + "%d+%d+%d+%d+%s%s%s%s%s", + con->request->request.op.request_id, + limit ? limit->values[0].integer : 0, + timeout ? timeout->values[0].integer : 15, + (int)User, + requested_str, + exclude_str[0] ? "%20" : "", exclude_str, + include_str[0] ? "%20" : "", include_str); + + if (cupsdSendCommand(con, command, options, 1)) + { + /* + * Command started successfully, don't send an IPP response here... + */ + + ippDelete(con->response); + con->response = NULL; + } + else + { + /* + * Command failed, return "internal error" so the user knows something + * went wrong... + */ + + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("cups-deviced failed to execute.")); + } +} + + +/* + * 'get_document()' - Get a copy of a job file. + */ + +static void +get_document(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + int jobid; /* Job ID */ + int docnum; /* Document number */ + cupsd_job_t *job; /* Current job */ + char scheme[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 filename[1024], /* Filename for document */ + format[1024]; /* Format for document */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_document(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, + job->username)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Get the document number... + */ + + if ((attr = ippFindAttribute(con->request, "document-number", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Missing document-number attribute!")); + return; + } + + if ((docnum = attr->values[0].integer) < 1 || docnum > job->num_files || + attr->num_values > 1) + { + send_ipp_status(con, IPP_NOT_FOUND, _("Document %d not found in job %d."), + docnum, jobid); + return; + } + + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, jobid, + docnum); + if ((con->file = open(filename, O_RDONLY)) == -1) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open document %d in job %d - %s", docnum, jobid, + strerror(errno)); + send_ipp_status(con, IPP_NOT_FOUND, + _("Unable to open document %d in job %d!"), docnum, jobid); + return; + } + + fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); + + cupsdLoadJob(job); + + snprintf(format, sizeof(format), "%s/%s", job->filetypes[docnum - 1]->super, + job->filetypes[docnum - 1]->type); + + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", + NULL, format); + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_INTEGER, "document-number", + docnum); + if ((attr = ippFindAttribute(job->attrs, "document-name", + IPP_TAG_NAME)) != NULL) + ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_NAME, "document-name", + NULL, attr->values[0].string.text); +} + + +/* + * 'get_job_attrs()' - Get job attributes. + */ + +static void +get_job_attrs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + int jobid; /* Job ID */ + cupsd_job_t *job; /* Current job */ + cupsd_printer_t *printer; /* Current printer */ + char scheme[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 */ + cups_array_t *ra; /* Requested attributes array */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_job_attrs(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * Check policy... + */ + + if ((printer = job->printer) == NULL) + printer = cupsdFindDest(job->dest); + + if (printer) + { + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + } + else if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Copy attributes... + */ + + cupsdLoadJob(job); + + ra = create_requested_array(con->request); + copy_job_attrs(con, job, ra); + cupsArrayDelete(ra); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_jobs()' - Get a list of jobs for the specified printer. + */ + +static void +get_jobs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + const char *dest; /* Destination */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cups_ptype_t dmask; /* Destination type mask */ + char scheme[HTTP_MAX_URI], /* Scheme 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 first_job_id; /* First job ID */ + int limit; /* Maximum number of jobs to return */ + int count; /* Number of jobs that match */ + cupsd_job_t *job; /* Current job pointer */ + cupsd_printer_t *printer; /* Printer */ + cups_array_t *list; /* Which job list... */ + cups_array_t *ra; /* Requested attributes array */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs(%p[%d], %s)", con, con->http.fd, + uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (strcmp(uri->name, "printer-uri")) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request!")); + return; + } + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(resource, "/") || !strcmp(resource, "/jobs")) + { + dest = NULL; + dtype = (cups_ptype_t)0; + dmask = (cups_ptype_t)0; + printer = NULL; + } + else if (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) + { + dest = NULL; + dtype = (cups_ptype_t)0; + dmask = CUPS_PRINTER_CLASS; + printer = NULL; + } + else if (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9) + { + dest = NULL; + dtype = CUPS_PRINTER_CLASS; + dmask = CUPS_PRINTER_CLASS; + printer = NULL; + } + else if ((dest = cupsdValidateDest(uri->values[0].string.text, &dtype, + &printer)) == NULL) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + else + { + dtype &= CUPS_PRINTER_CLASS; + dmask = CUPS_PRINTER_CLASS; + } + + /* + * Check policy... + */ + + if (printer) + { + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, + NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + } + else if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * See if the "which-jobs" attribute have been specified... + */ + + if ((attr = ippFindAttribute(con->request, "which-jobs", + IPP_TAG_KEYWORD)) != NULL && + !strcmp(attr->values[0].string.text, "completed")) + { + completed = 1; + list = Jobs; + } + else if (attr && !strcmp(attr->values[0].string.text, "all")) + { + completed = 0; + list = Jobs; + } + else if (attr && !strcmp(attr->values[0].string.text, "processing")) + { + completed = 0; + list = PrintingJobs; + } + else + { + completed = 0; + list = ActiveJobs; + } + + /* + * 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 = 0; + + if ((attr = ippFindAttribute(con->request, "first-job-id", + IPP_TAG_INTEGER)) != NULL) + first_job_id = attr->values[0].integer; + else + first_job_id = 1; + + /* + * 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) + strlcpy(username, get_username(con), sizeof(username)); + else + username[0] = '\0'; + + if ((ra = create_requested_array(con->request)) == NULL && + !ippFindAttribute(con->request, "requested-attributes", IPP_TAG_KEYWORD)) + { + /* + * IPP conformance - Get-Jobs has a default requested-attributes value of + * "job-id" and "job-uri". + */ + + ra = cupsArrayNew((cups_array_func_t)strcmp, NULL); + cupsArrayAdd(ra, "job-id"); + cupsArrayAdd(ra, "job-uri"); + } + + /* + * OK, build a list of jobs for this printer... + */ + + for (count = 0, job = (cupsd_job_t *)cupsArrayFirst(list); + (limit <= 0 || count < limit) && job; + job = (cupsd_job_t *)cupsArrayNext(list)) + { + /* + * Filter out jobs that don't match... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_jobs: job->id=%d, dest=\"%s\", username=\"%s\", " + "state_value=%d, attrs=%p", job->id, job->dest, + job->username, job->state_value, job->attrs); + + if (!job->dest || !job->username) + cupsdLoadJob(job); + + if (!job->dest || !job->username) + continue; + + if ((dest && strcmp(job->dest, dest)) && + (!job->printer || !dest || strcmp(job->printer->name, dest))) + continue; + if ((job->dtype & dmask) != dtype && + (!job->printer || (job->printer->type & dmask) != dtype)) + continue; + if (completed && job->state_value <= IPP_JOB_STOPPED) + continue; + + if (job->id < first_job_id) + continue; + + cupsdLoadJob(job); + + if (!job->attrs) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: No attributes for job %d!", + job->id); + continue; + } + + if (username[0] && strcasecmp(username, job->username)) + continue; + + if (count > 0) + ippAddSeparator(con->response); + + count ++; + + copy_job_attrs(con, job, ra); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: count=%d", count); + + cupsArrayDelete(ra); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_notifications()' - Get events for a subscription. + */ + +static void +get_notifications(cupsd_client_t *con) /* I - Client connection */ +{ + int i, j; /* Looping vars */ + http_status_t status; /* Policy status */ + cupsd_subscription_t *sub; /* Subscription */ + ipp_attribute_t *ids, /* notify-subscription-ids */ + *sequences; /* notify-sequence-numbers */ + int min_seq; /* Minimum sequence number */ + int interval; /* Poll interval */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_notifications(con=%p[%d])", + con, con->http.fd); + + /* + * Get subscription attributes... + */ + + ids = ippFindAttribute(con->request, "notify-subscription-ids", + IPP_TAG_INTEGER); + sequences = ippFindAttribute(con->request, "notify-sequence-numbers", + IPP_TAG_INTEGER); + + if (!ids) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Missing notify-subscription-ids attribute!")); + return; + } + + /* + * Are the subscription IDs valid? + */ + + for (i = 0, interval = 60; i < ids->num_values; i ++) + { + if ((sub = cupsdFindSubscription(ids->values[i].integer)) == NULL) + { + /* + * Bad subscription ID... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("notify-subscription-id %d no good!"), + ids->values[i].integer); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : + DefaultPolicyPtr, + con, sub->owner)) != HTTP_OK) + { + send_http_error(con, status, sub->dest); + return; + } + + /* + * Check the subscription type and update the interval accordingly. + */ + + if (sub->job && sub->job->state_value == IPP_JOB_PROCESSING && + interval > 10) + interval = 10; + else if (sub->job && sub->job->state_value >= IPP_JOB_STOPPED) + interval = 0; + else if (sub->dest && sub->dest->state == IPP_PRINTER_PROCESSING && + interval > 30) + interval = 30; + } + + /* + * Tell the client to poll again in N seconds... + */ + + if (interval > 0) + ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "notify-get-interval", interval); + + ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "printer-up-time", time(NULL)); + + /* + * Copy the subscription event attributes to the response. + */ + + con->response->request.status.status_code = + interval ? IPP_OK : IPP_OK_EVENTS_COMPLETE; + + for (i = 0; i < ids->num_values; i ++) + { + /* + * Get the subscription and sequence number... + */ + + sub = cupsdFindSubscription(ids->values[i].integer); + + if (sequences && i < sequences->num_values) + min_seq = sequences->values[i].integer; + else + min_seq = 1; + + /* + * If we don't have any new events, nothing to do here... + */ + + if (min_seq > (sub->first_event_id + sub->num_events)) + continue; + + /* + * Otherwise copy all of the new events... + */ + + if (sub->first_event_id > min_seq) + j = 0; + else + j = min_seq - sub->first_event_id; + + for (; j < sub->num_events; j ++) + { + ippAddSeparator(con->response); + + copy_attrs(con->response, sub->events[j]->attrs, NULL, + IPP_TAG_EVENT_NOTIFICATION, 0); + } + } +} + + +/* + * 'get_ppd()' - Get a named PPD from the local system. + */ + +static void +get_ppd(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI or PPD name */ +{ + http_status_t status; /* Policy status */ + cupsd_printer_t *dest; /* Destination */ + cups_ptype_t dtype; /* Destination type */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppd(%p[%d], %p[%s=%s])", con, + con->http.fd, uri, uri->name, uri->values[0].string.text); + + if (!strcmp(uri->name, "ppd-name")) + { + /* + * Return a PPD file from cups-driverd... + */ + + char command[1024], /* cups-driverd command */ + options[1024], /* Options to pass to command */ + ppd_name[1024]; /* ppd-name */ + + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Run cups-driverd command with the given options... + */ + + snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin); + url_encode_string(uri->values[0].string.text, ppd_name, sizeof(ppd_name)); + snprintf(options, sizeof(options), "get+%d+%s", + con->request->request.op.request_id, ppd_name); + + if (cupsdSendCommand(con, command, options, 0)) + { + /* + * Command started successfully, don't send an IPP response here... + */ + + ippDelete(con->response); + con->response = NULL; + } + else + { + /* + * Command failed, return "internal error" so the user knows something + * went wrong... + */ + + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("cups-driverd failed to execute.")); + } + } + else if (!strcmp(uri->name, "printer-uri") && + cupsdValidateDest(uri->values[0].string.text, &dtype, &dest)) + { + int i; /* Looping var */ + char filename[1024]; /* PPD filename */ + + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(dest->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, dest); + return; + } + + /* + * See if we need the PPD for a class or remote printer... + */ + + snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, + dest->name); + + if ((dtype & CUPS_PRINTER_REMOTE) && access(filename, 0)) + { + con->response->request.status.status_code = CUPS_SEE_OTHER; + ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, dest->uri); + return; + } + else if (dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) + { + for (i = 0; i < dest->num_printers; i ++) + if (!(dest->printers[i]->type & + (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT))) + { + snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, + dest->printers[i]->name); + + if (!access(filename, 0)) + break; + } + + if (i < dest->num_printers) + dest = dest->printers[i]; + else + { + con->response->request.status.status_code = CUPS_SEE_OTHER; + ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, dest->printers[0]->uri); + return; + } + } + + /* + * Found the printer with the PPD file, now see if there is one... + */ + + if ((con->file = open(filename, O_RDONLY)) < 0) + { + send_ipp_status(con, IPP_NOT_FOUND, + _("The PPD file \"%s\" could not be opened: %s"), + uri->values[0].string.text, strerror(errno)); + return; + } + + fcntl(con->file, F_SETFD, fcntl(con->file, F_GETFD) | FD_CLOEXEC); + + con->pipe_pid = 0; + + con->response->request.status.status_code = IPP_OK; + } + else + send_ipp_status(con, IPP_NOT_FOUND, + _("The PPD file \"%s\" could not be found."), + uri->values[0].string.text); +} + + +/* + * 'get_ppds()' - Get the list of PPD files on the local system. + */ + +static void +get_ppds(cupsd_client_t *con) /* I - Client connection */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *limit, /* Limit attribute */ + *device, /* ppd-device-id attribute */ + *language, /* ppd-natural-language attribute */ + *make, /* ppd-make attribute */ + *model, /* ppd-make-and-model attribute */ + *model_number, /* ppd-model-number attribute */ + *product, /* ppd-product attribute */ + *psversion, /* ppd-psverion attribute */ + *type, /* ppd-type attribute */ + *requested, /* requested-attributes attribute */ + *exclude, /* exclude-schemes attribute */ + *include; /* include-schemes attribute */ + char command[1024], /* cups-driverd command */ + options[4096], /* Options to pass to command */ + device_str[256],/* Escaped ppd-device-id string */ + language_str[256], + /* Escaped ppd-natural-language */ + make_str[256], /* Escaped ppd-make string */ + model_str[256], /* Escaped ppd-make-and-model string */ + model_number_str[256], + /* ppd-model-number string */ + product_str[256], + /* Escaped ppd-product string */ + psversion_str[256], + /* Escaped ppd-psversion string */ + type_str[256], /* Escaped ppd-type string */ + requested_str[256], + /* String for requested attributes */ + exclude_str[512], + /* String for excluded schemes */ + include_str[512]; + /* String for included schemes */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_ppds(%p[%d])", con, con->http.fd); + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Run cups-driverd command with the given options... + */ + + limit = ippFindAttribute(con->request, "limit", IPP_TAG_INTEGER); + device = ippFindAttribute(con->request, "ppd-device-id", IPP_TAG_TEXT); + language = ippFindAttribute(con->request, "ppd-natural-language", + IPP_TAG_LANGUAGE); + make = ippFindAttribute(con->request, "ppd-make", IPP_TAG_TEXT); + model = ippFindAttribute(con->request, "ppd-make-and-model", + IPP_TAG_TEXT); + model_number = ippFindAttribute(con->request, "ppd-model-number", + IPP_TAG_INTEGER); + product = ippFindAttribute(con->request, "ppd-product", IPP_TAG_TEXT); + psversion = ippFindAttribute(con->request, "ppd-psversion", IPP_TAG_TEXT); + type = ippFindAttribute(con->request, "ppd-type", IPP_TAG_KEYWORD); + requested = ippFindAttribute(con->request, "requested-attributes", + IPP_TAG_KEYWORD); + exclude = ippFindAttribute(con->request, "exclude-schemes", + IPP_TAG_NAME); + include = ippFindAttribute(con->request, "include-schemes", + IPP_TAG_NAME); + + if (requested) + url_encode_attr(requested, requested_str, sizeof(requested_str)); + else + strlcpy(requested_str, "requested-attributes=all", sizeof(requested_str)); + + if (device) + url_encode_attr(device, device_str, sizeof(device_str)); + else + device_str[0] = '\0'; + + if (language) + url_encode_attr(language, language_str, sizeof(language_str)); + else + language_str[0] = '\0'; + + if (make) + url_encode_attr(make, make_str, sizeof(make_str)); + else + make_str[0] = '\0'; + + if (model) + url_encode_attr(model, model_str, sizeof(model_str)); + else + model_str[0] = '\0'; + + if (model_number) + snprintf(model_number_str, sizeof(model_number_str), "ppd-model-number=%d", + model_number->values[0].integer); + else + model_number_str[0] = '\0'; + + if (product) + url_encode_attr(product, product_str, sizeof(product_str)); + else + product_str[0] = '\0'; + + if (psversion) + url_encode_attr(psversion, psversion_str, sizeof(psversion_str)); + else + psversion_str[0] = '\0'; + + if (type) + url_encode_attr(type, type_str, sizeof(type_str)); + else + type_str[0] = '\0'; + + if (exclude) + url_encode_attr(exclude, exclude_str, sizeof(exclude_str)); + else + exclude_str[0] = '\0'; + + if (include) + url_encode_attr(include, include_str, sizeof(include_str)); + else + include_str[0] = '\0'; + + snprintf(command, sizeof(command), "%s/daemon/cups-driverd", ServerBin); + snprintf(options, sizeof(options), + "list+%d+%d+%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + con->request->request.op.request_id, + limit ? limit->values[0].integer : 0, + requested_str, + device ? "%20" : "", device_str, + language ? "%20" : "", language_str, + make ? "%20" : "", make_str, + model ? "%20" : "", model_str, + model_number ? "%20" : "", model_number_str, + product ? "%20" : "", product_str, + psversion ? "%20" : "", psversion_str, + type ? "%20" : "", type_str, + exclude_str[0] ? "%20" : "", exclude_str, + include_str[0] ? "%20" : "", include_str); + + if (cupsdSendCommand(con, command, options, 0)) + { + /* + * Command started successfully, don't send an IPP response here... + */ + + ippDelete(con->response); + con->response = NULL; + } + else + { + /* + * Command failed, return "internal error" so the user knows something + * went wrong... + */ + + send_ipp_status(con, IPP_INTERNAL_ERROR, + _("cups-driverd failed to execute.")); + } +} + + +/* + * 'get_printer_attrs()' - Get printer attributes. + */ + +static void +get_printer_attrs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer/class */ + cups_array_t *ra; /* Requested attributes array */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_attrs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Send the attributes... + */ + + ra = create_requested_array(con->request); + + copy_printer_attrs(con, printer, ra); + + cupsArrayDelete(ra); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_printer_supported()' - Get printer supported values. + */ + +static void +get_printer_supported( + cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer/class */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printer_supported(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Return a list of attributes that can be set via Set-Printer-Attributes. + */ + + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE, + "printer-info", 0); + ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ADMINDEFINE, + "printer-location", 0); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_printers()' - Get a list of printers or classes. + */ + +static void +get_printers(cupsd_client_t *con, /* I - Client connection */ + int type) /* I - 0 or CUPS_PRINTER_CLASS */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + int limit; /* Max number of printers to return */ + int count; /* Number of printers that match */ + cupsd_printer_t *printer; /* Current printer pointer */ + int printer_type, /* printer-type attribute */ + printer_mask; /* printer-type-mask attribute */ + char *location; /* Location string */ + const char *username; /* Current user */ + char *first_printer_name; /* first-printer-name attribute */ + cups_array_t *ra; /* Requested attributes array */ + int local; /* Local connection? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_printers(%p[%d], %x)", con, + con->http.fd, type); + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Check for printers... + */ + + if (!Printers || !cupsArrayCount(Printers)) + { + send_ipp_status(con, IPP_NOT_FOUND, _("No destinations added.")); + return; + } + + /* + * 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; + + if ((attr = ippFindAttribute(con->request, "first-printer-name", + IPP_TAG_NAME)) != NULL) + first_printer_name = attr->values[0].string.text; + else + first_printer_name = NULL; + + /* + * 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; + + local = httpAddrLocalhost(&(con->clientaddr)); + + if ((attr = ippFindAttribute(con->request, "printer-location", + IPP_TAG_TEXT)) != NULL) + location = attr->values[0].string.text; + else + location = NULL; + + if (con->username[0]) + username = con->username; + else if ((attr = ippFindAttribute(con->request, "requesting-user-name", + IPP_TAG_NAME)) != NULL) + username = attr->values[0].string.text; + else + username = NULL; + + ra = create_requested_array(con->request); + + /* + * OK, build a list of printers for this printer... + */ + + if (first_printer_name) + { + if ((printer = cupsdFindDest(first_printer_name)) == NULL) + printer = (cupsd_printer_t *)cupsArrayFirst(Printers); + } + else + printer = (cupsd_printer_t *)cupsArrayFirst(Printers); + + for (count = 0; + count < limit && printer; + printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + if (!local && !printer->shared) + continue; + + if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) && + (printer->type & printer_mask) == printer_type && + (!location || + (printer->location && !strcasecmp(printer->location, location)))) + { + /* + * If HideImplicitMembers is enabled, see if this printer or class + * is a member of an implicit class... + */ + + if (ImplicitClasses && HideImplicitMembers && + printer->in_implicit_class) + continue; + + /* + * If a username is specified, see if it is allowed or denied + * access... + */ + + if (printer->num_users && username && !user_allowed(printer, username)) + continue; + + /* + * Add the group separator as needed... + */ + + if (count > 0) + ippAddSeparator(con->response); + + count ++; + + /* + * Send the attributes... + */ + + copy_printer_attrs(con, printer, ra); + } + } + + cupsArrayDelete(ra); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_subscription_attrs()' - Get subscription attributes. + */ + +static void +get_subscription_attrs( + cupsd_client_t *con, /* I - Client connection */ + int sub_id) /* I - Subscription ID */ +{ + http_status_t status; /* Policy status */ + cupsd_subscription_t *sub; /* Subscription */ + cups_array_t *ra; /* Requested attributes array */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_subscription_attrs(con=%p[%d], sub_id=%d)", + con, con->http.fd, sub_id); + + /* + * Is the subscription ID valid? + */ + + if ((sub = cupsdFindSubscription(sub_id)) == NULL) + { + /* + * Bad subscription ID... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("notify-subscription-id %d no good!"), sub_id); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : + DefaultPolicyPtr, + con, sub->owner)) != HTTP_OK) + { + send_http_error(con, status, sub->dest); + return; + } + + /* + * Copy the subscription attributes to the response using the + * requested-attributes attribute that may be provided by the client. + */ + + ra = create_requested_array(con->request); + + copy_subscription_attrs(con, sub, ra); + + cupsArrayDelete(ra); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'get_subscriptions()' - Get subscriptions. + */ + +static void +get_subscriptions(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer/job URI */ +{ + http_status_t status; /* Policy status */ + int count; /* Number of subscriptions */ + int limit; /* Limit */ + cupsd_subscription_t *sub; /* Subscription */ + cups_array_t *ra; /* Requested attributes array */ + ipp_attribute_t *attr; /* Attribute */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + char scheme[HTTP_MAX_URI], + /* Scheme 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 */ + cupsd_job_t *job; /* Job pointer */ + cupsd_printer_t *printer; /* Printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "get_subscriptions(con=%p[%d], uri=%s)", + con, con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(resource, "/") || + (!strncmp(resource, "/jobs", 5) && strlen(resource) <= 6) || + (!strncmp(resource, "/printers", 9) && strlen(resource) <= 10) || + (!strncmp(resource, "/classes", 8) && strlen(resource) <= 9)) + { + printer = NULL; + job = NULL; + } + else if (!strncmp(resource, "/jobs/", 6) && resource[6]) + { + printer = NULL; + job = cupsdFindJob(atoi(resource + 6)); + + if (!job) + { + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist!"), + resource + 6); + return; + } + } + else if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + else if ((attr = ippFindAttribute(con->request, "notify-job-id", + IPP_TAG_INTEGER)) != NULL) + { + job = cupsdFindJob(attr->values[0].integer); + + if (!job) + { + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), + attr->values[0].integer); + return; + } + } + else + job = NULL; + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer ? printer->op_policy_ptr : + DefaultPolicyPtr, + con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Copy the subscription attributes to the response using the + * requested-attributes attribute that may be provided by the client. + */ + + ra = create_requested_array(con->request); + + if ((attr = ippFindAttribute(con->request, "limit", + IPP_TAG_INTEGER)) != NULL) + limit = attr->values[0].integer; + else + limit = 0; + + /* + * See if we only want to see subscriptions for a specific user... + */ + + if ((attr = ippFindAttribute(con->request, "my-subscriptions", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean) + strlcpy(username, get_username(con), sizeof(username)); + else + username[0] = '\0'; + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), count = 0; + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if ((!printer || sub->dest == printer) && (!job || sub->job == job) && + (!username[0] || !strcasecmp(username, sub->owner))) + { + ippAddSeparator(con->response); + copy_subscription_attrs(con, sub, ra); + + count ++; + if (limit && count >= limit) + break; + } + + cupsArrayDelete(ra); + + if (count) + con->response->request.status.status_code = IPP_OK; + else + send_ipp_status(con, IPP_NOT_FOUND, _("No subscriptions found.")); +} + + +/* + * 'get_username()' - Get the username associated with a request. + */ + +static const char * /* O - Username */ +get_username(cupsd_client_t *con) /* I - Connection */ +{ + ipp_attribute_t *attr; /* Attribute */ + + + if (con->username[0]) + return (con->username); + else if ((attr = ippFindAttribute(con->request, "requesting-user-name", + IPP_TAG_NAME)) != NULL) + return (attr->values[0].string.text); + else + return ("anonymous"); +} + + +/* + * 'hold_job()' - Hold a print job. + */ + +static void +hold_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job or Printer URI */ +{ + ipp_attribute_t *attr; /* Current job-hold-until */ + const char *when; /* New value */ + int jobid; /* Job ID */ + char scheme[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 */ + cupsd_job_t *job; /* Job information */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_job(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * Hold the job and return... + */ + + if ((attr = ippFindAttribute(con->request, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME); + + if (attr) + { + when = attr->values[0].string.text; + + cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job, + "Job job-hold-until value changed by user."); + } + else + when = "indefinite"; + + cupsdSetJobHoldUntil(job, when, 1); + cupsdSetJobState(job, IPP_JOB_HELD, CUPSD_JOB_DEFAULT, "Job held by \"%s\".", + username); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'hold_new_jobs()' - Hold pending/new jobs on a printer or class. + */ + +static void +hold_new_jobs(cupsd_client_t *con, /* I - Connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "hold_new_jobs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Hold pending/new jobs sent to the printer... + */ + + printer->holding_new_jobs = 1; + + cupsdSetPrinterReasons(printer, "+hold-new-jobs"); + cupsdAddPrinterHistory(printer); + + if (dtype & CUPS_PRINTER_CLASS) + cupsdLogMessage(CUPSD_LOG_INFO, + "Class \"%s\" now holding pending/new jobs (\"%s\").", + printer->name, get_username(con)); + else + cupsdLogMessage(CUPSD_LOG_INFO, + "Printer \"%s\" now holding pending/new jobs (\"%s\").", + printer->name, get_username(con)); + + /* + * Everything was ok, so return OK status... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'move_job()' - Move a job to a new destination. + */ + +static void +move_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ +{ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + int jobid; /* Job ID */ + cupsd_job_t *job; /* Current job */ + const char *src; /* Source printer/class */ + cups_ptype_t stype, /* Source type (printer or class) */ + dtype; /* Destination type (printer/class) */ + char scheme[HTTP_MAX_URI], /* Scheme 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 */ + cupsd_printer_t *sprinter, /* Source printer */ + *dprinter; /* Destination printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "move_job(%p[%d], %s)", con, con->http.fd, + uri->values[0].string.text); + + /* + * Get the new printer or class... + */ + + if ((attr = ippFindAttribute(con->request, "job-printer-uri", + IPP_TAG_URI)) == NULL) + { + /* + * Need job-printer-uri... + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("job-printer-uri attribute missing!")); + return; + } + + if (!cupsdValidateDest(attr->values[0].string.text, &dtype, &dprinter)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * See if we have a job URI or a printer URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (!strcmp(uri->name, "printer-uri")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + /* + * Move all jobs... + */ + + if ((src = cupsdValidateDest(uri->values[0].string.text, &stype, + &sprinter)) == NULL) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + job = NULL; + } + else + { + /* + * Otherwise, just move a single job... + */ + + if ((job = cupsdFindJob(attr->values[0].integer)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("Job #%d does not exist!"), attr->values[0].integer); + return; + } + else + { + /* + * Job found, initialize source pointers... + */ + + src = NULL; + sprinter = NULL; + } + } + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + /* + * See if the job exists... + */ + + jobid = atoi(resource + 6); + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("Job #%d does not exist!"), jobid); + return; + } + else + { + /* + * Job found, initialize source pointers... + */ + + src = NULL; + sprinter = NULL; + } + } + + /* + * Check the policy of the destination printer... + */ + + if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con, + job ? job->username : NULL)) != HTTP_OK) + { + send_http_error(con, status, dprinter); + return; + } + + /* + * Now move the job or jobs... + */ + + if (job) + { + /* + * See if the job has been completed... + */ + + if (job->state_value > IPP_JOB_STOPPED) + { + /* + * Return a "not-possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is finished and cannot be altered!"), + job->id); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * Move the job to a different printer or class... + */ + + cupsdMoveJob(job, dprinter); + } + else + { + /* + * Got the source printer, now look through the jobs... + */ + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + { + /* + * See if the job is pointing at the source printer or has not been + * completed... + */ + + if (strcasecmp(job->dest, src) || + job->state_value > IPP_JOB_STOPPED) + continue; + + /* + * See if the job can be moved by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + continue; + + /* + * Move the job to a different printer or class... + */ + + cupsdMoveJob(job, dprinter); + } + } + + /* + * Start jobs if possible... + */ + + cupsdCheckJobs(); + + /* + * Return with "everything is OK" status... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'ppd_parse_line()' - Parse a PPD default line. + */ + +static int /* O - 0 on success, -1 on failure */ +ppd_parse_line(const char *line, /* I - Line */ + char *option, /* O - Option name */ + int olen, /* I - Size of option name */ + char *choice, /* O - Choice name */ + int clen) /* I - Size of choice name */ +{ + /* + * Verify this is a default option line... + */ + + if (strncmp(line, "*Default", 8)) + return (-1); + + /* + * Read the option name... + */ + + for (line += 8, olen --; + *line > ' ' && *line < 0x7f && *line != ':' && *line != '/'; + line ++) + if (olen > 0) + { + *option++ = *line; + olen --; + } + + *option = '\0'; + + /* + * Skip everything else up to the colon (:)... + */ + + while (*line && *line != ':') + line ++; + + if (!*line) + return (-1); + + line ++; + + /* + * Now grab the option choice, skipping leading whitespace... + */ + + while (isspace(*line & 255)) + line ++; + + for (clen --; + *line > ' ' && *line < 0x7f && *line != ':' && *line != '/'; + line ++) + if (clen > 0) + { + *choice++ = *line; + clen --; + } + + *choice = '\0'; + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'print_job()' - Print a file to a printer or class. + */ + +static void +print_job(cupsd_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 *default_format; /* document-format-default value */ + cupsd_job_t *job; /* New job */ + char filename[1024]; /* Job filename */ + 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 */ + cupsd_printer_t *printer; /* Printer data */ + struct stat fileinfo; /* File information */ + int kbytes; /* Size of file */ + int compression; /* Document compression */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "print_job(%p[%d], %s)", con, con->http.fd, + uri->values[0].string.text); + + /* + * Validate print file attributes, for now just document-format and + * compression (CUPS only supports "none" and "gzip")... + */ + + compression = CUPS_FILE_NONE; + + if ((attr = ippFindAttribute(con->request, "compression", + IPP_TAG_KEYWORD)) != NULL) + { + if (strcmp(attr->values[0].string.text, "none") +#ifdef HAVE_LIBZ + && strcmp(attr->values[0].string.text, "gzip") +#endif /* HAVE_LIBZ */ + ) + { + send_ipp_status(con, IPP_ATTRIBUTES, + _("Unsupported compression \"%s\"!"), + attr->values[0].string.text); + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD, + "compression", NULL, attr->values[0].string.text); + return; + } + +#ifdef HAVE_LIBZ + if (!strcmp(attr->values[0].string.text, "gzip")) + compression = CUPS_FILE_GZIP; +#endif /* HAVE_LIBZ */ + } + + /* + * Do we have a file to print? + */ + + if (!con->filename) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!")); + return; + } + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, NULL, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + 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) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + format->values[0].string.text); + return; + } + } + else if ((default_format = cupsGetOption("document-format", + printer->num_options, + printer->options)) != NULL) + { + /* + * Use default document format... + */ + + if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + default_format); + return; + } + } + else + { + /* + * Auto-type it! + */ + + strcpy(super, "application"); + strcpy(type, "octet-stream"); + } + + if (!strcmp(super, "application") && !strcmp(type, "octet-stream")) + { + /* + * Auto-type the file... + */ + + ipp_attribute_t *doc_name; /* document-name attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job ???] Auto-typing file..."); + + doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME); + filetype = mimeFileType(MimeDatabase, con->filename, + doc_name ? doc_name->values[0].string.text : NULL, + &compression); + + if (!filetype) + filetype = mimeType(MimeDatabase, super, type); + + cupsdLogMessage(CUPSD_LOG_INFO, "[Job ???] Request file type is %s/%s.", + filetype->super, filetype->type); + } + else + filetype = mimeType(MimeDatabase, super, type); + + if (filetype && + (!format || + (!strcmp(super, "application") && !strcmp(type, "octet-stream")))) + { + /* + * Replace the document-format attribute value with the auto-typed or + * default one. + */ + + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); + + if (format) + { + _cupsStrFree(format->values[0].string.text); + + format->values[0].string.text = _cupsStrAlloc(mimetype); + } + else + ippAddString(con->request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); + } + else if (!filetype) + { + send_ipp_status(con, IPP_DOCUMENT_FORMAT, + _("Unsupported format \'%s/%s\'!"), super, type); + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Do you have the raw file printing rules enabled?"); + + if (format) + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, + "document-format", NULL, format->values[0].string.text); + + return; + } + + /* + * Read any embedded job ticket info from PS files... + */ + + if (!strcasecmp(filetype->super, "application") && + (!strcasecmp(filetype->type, "postscript") || + !strcasecmp(filetype->type, "pdf"))) + read_job_ticket(con); + + /* + * Create the job object... + */ + + if ((job = add_job(con, printer, filetype)) == NULL) + return; + + /* + * Update quota data... + */ + + if (stat(con->filename, &fileinfo)) + kbytes = 0; + else + kbytes = (fileinfo.st_size + 1023) / 1024; + + cupsdUpdateQuota(printer, job->username, 0, kbytes); + + if ((attr = ippFindAttribute(job->attrs, "job-k-octets", + IPP_TAG_INTEGER)) != NULL) + attr->values[0].integer += kbytes; + + /* + * Add the job file... + */ + + if (add_file(con, job, filetype, compression)) + return; + + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id, + job->num_files); + rename(con->filename, filename); + cupsdClearString(&con->filename); + + /* + * See if we need to add the ending sheet... + */ + + if (cupsdTimeoutJob(job)) + return; + + /* + * Log and save the job... + */ + + cupsdLogJob(job, CUPSD_LOG_INFO, + "File of type %s/%s queued by \"%s\".", + filetype->super, filetype->type, job->username); + cupsdLogJob(job, CUPSD_LOG_DEBUG, "hold_until=%d", (int)job->hold_until); + cupsdLogJob(job, CUPSD_LOG_INFO, "Queued on \"%s\" by \"%s\".", + job->dest, job->username); + + /* + * Start the job if possible... + */ + + cupsdCheckJobs(); +} + + +/* + * 'read_job_ticket()' - Read a job ticket embedded in a print file. + * + * This function only gets called when printing a single PDF or 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 job ticket stuff is here + * primarily 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 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 (%!PS-Adobe-3.0) or PDF (%PDF) format, and CUPS + * stops 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. + * + * 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_job_ticket(cupsd_client_t *con) /* I - Client connection */ +{ + cups_file_t *fp; /* File to read from */ + char line[256]; /* Line data */ + 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 = cupsFileOpen(con->filename, "rb")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open print file for job ticket - %s", + strerror(errno)); + return; + } + + /* + * Skip the first line... + */ + + if (cupsFileGets(fp, line, sizeof(line)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to read from print file for job ticket - %s", + strerror(errno)); + cupsFileClose(fp); + return; + } + + if (strncmp(line, "%!PS-Adobe-", 11) && strncmp(line, "%PDF-", 5)) + { + /* + * Not a DSC-compliant file, so no job ticket info will be available... + */ + + cupsFileClose(fp); + return; + } + + /* + * Read job ticket info from the file... + */ + + num_options = 0; + options = NULL; + + while (cupsFileGets(fp, line, sizeof(line))) + { + /* + * Stop at the first non-ticket line... + */ + + if (strncmp(line, "%cupsJobTicket:", 15)) + 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... + */ + + cupsFileClose(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; attr = attr->next) + { + if (attr->group_tag != IPP_TAG_JOB || !attr->name) + continue; + + if (!strcmp(attr->name, "job-originating-host-name") || + !strcmp(attr->name, "job-originating-user-name") || + !strcmp(attr->name, "job-media-sheets-completed") || + !strcmp(attr->name, "job-k-octets") || + !strcmp(attr->name, "job-id") || + !strncmp(attr->name, "job-state", 9) || + !strncmp(attr->name, "time-at-", 8)) + continue; /* Read-only attrs */ + + if ((attr2 = ippFindAttribute(con->request, attr->name, + IPP_TAG_ZERO)) != NULL) + { + /* + * Some other value; first free the old value... + */ + + if (con->request->attrs == attr2) + { + con->request->attrs = attr2->next; + prev2 = NULL; + } + else + { + for (prev2 = con->request->attrs; prev2; prev2 = prev2->next) + if (prev2->next == attr2) + { + prev2->next = attr2->next; + break; + } + } + + if (con->request->last == attr2) + con->request->last = prev2; + + _ippFreeAttr(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(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer or class URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + ipp_attribute_t *attr; /* printer-state-message text */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "reject_jobs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Reject jobs sent to the printer... + */ + + 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)); + + cupsdAddPrinterHistory(printer); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, + "No longer accepting jobs."); + + if (dtype & CUPS_PRINTER_CLASS) + { + cupsdMarkDirty(CUPSD_DIRTY_CLASSES); + + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" rejecting jobs (\"%s\").", + printer->name, get_username(con)); + } + else + { + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" rejecting jobs (\"%s\").", + printer->name, get_username(con)); + } + + /* + * Everything was ok, so return OK status... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'release_held_new_jobs()' - Release pending/new jobs on a printer or class. + */ + +static void +release_held_new_jobs( + cupsd_client_t *con, /* I - Connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_held_new_jobs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Hold pending/new jobs sent to the printer... + */ + + printer->holding_new_jobs = 0; + + cupsdSetPrinterReasons(printer, "-hold-new-jobs"); + cupsdAddPrinterHistory(printer); + + if (dtype & CUPS_PRINTER_CLASS) + cupsdLogMessage(CUPSD_LOG_INFO, + "Class \"%s\" now printing pending/new jobs (\"%s\").", + printer->name, get_username(con)); + else + cupsdLogMessage(CUPSD_LOG_INFO, + "Printer \"%s\" now printing pending/new jobs (\"%s\").", + printer->name, get_username(con)); + + /* + * 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(cupsd_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 scheme[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 */ + cupsd_job_t *job; /* Job information */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "release_job(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if job is "held"... + */ + + if (job->state_value != IPP_JOB_HELD) + { + /* + * Nope - return a "not possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held!"), jobid); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + 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) + { + _cupsStrFree(attr->values[0].string.text); + + attr->value_tag = IPP_TAG_KEYWORD; + attr->values[0].string.text = _cupsStrAlloc("no-hold"); + + cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job, + "Job job-hold-until value changed by user."); + } + + /* + * Release the job and return... + */ + + cupsdReleaseJob(job); + + cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job, + "Job released by user."); + + cupsdLogJob(job, CUPSD_LOG_INFO, "Released by \"%s\".", username); + + con->response->request.status.status_code = IPP_OK; + + cupsdCheckJobs(); +} + + +/* + * 'renew_subscription()' - Renew an existing subscription... + */ + +static void +renew_subscription( + cupsd_client_t *con, /* I - Client connection */ + int sub_id) /* I - Subscription ID */ +{ + http_status_t status; /* Policy status */ + cupsd_subscription_t *sub; /* Subscription */ + ipp_attribute_t *lease; /* notify-lease-duration */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "renew_subscription(con=%p[%d], sub_id=%d)", + con, con->http.fd, sub_id); + + /* + * Is the subscription ID valid? + */ + + if ((sub = cupsdFindSubscription(sub_id)) == NULL) + { + /* + * Bad subscription ID... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("notify-subscription-id %d no good!"), sub_id); + return; + } + + if (sub->job) + { + /* + * Job subscriptions cannot be renewed... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job subscriptions cannot be renewed!")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr : + DefaultPolicyPtr, + con, sub->owner)) != HTTP_OK) + { + send_http_error(con, status, sub->dest); + return; + } + + /* + * Renew the subscription... + */ + + lease = ippFindAttribute(con->request, "notify-lease-duration", + IPP_TAG_INTEGER); + + sub->lease = lease ? lease->values[0].integer : DefaultLeaseDuration; + + if (MaxLeaseDuration && (sub->lease == 0 || sub->lease > MaxLeaseDuration)) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "renew_subscription: Limiting notify-lease-duration to " + "%d seconds.", + MaxLeaseDuration); + sub->lease = MaxLeaseDuration; + } + + sub->expire = sub->lease ? time(NULL) + sub->lease : 0; + + cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); + + con->response->request.status.status_code = IPP_OK; + + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-lease-duration", sub->lease); +} + + +/* + * 'restart_job()' - Restart an old print job. + */ + +static void +restart_job(cupsd_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 */ + cupsd_job_t *job; /* Job information */ + char scheme[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 */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "restart_job(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if job is in any of the "completed" states... + */ + + if (job->state_value <= IPP_JOB_PROCESSING) + { + /* + * Nope - return a "not possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete!"), + jobid); + return; + } + + /* + * See if we have retained the job files... + */ + + cupsdLoadJob(job); + + if (!job->attrs || job->num_files == 0) + { + /* + * Nope - return a "not possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d cannot be restarted - no files!"), jobid); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * See if the job-hold-until attribute is specified... + */ + + if ((attr = ippFindAttribute(con->request, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(con->request, "job-hold-until", IPP_TAG_NAME); + + if (attr && strcmp(attr->values[0].string.text, "no-hold")) + { + /* + * Return the job to a held state... + */ + + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Restarted by \"%s\" with job-hold-until=%s.", + username, attr->values[0].string.text); + cupsdSetJobHoldUntil(job, attr->values[0].string.text, 0); + + cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED | CUPSD_EVENT_JOB_STATE, + NULL, job, "Job restarted by user with job-hold-until=%s", + attr->values[0].string.text); + } + else + { + /* + * Restart the job... + */ + + cupsdRestartJob(job); + cupsdCheckJobs(); + } + + cupsdLogJob(job, CUPSD_LOG_INFO, "Restarted by \"%s\".", username); + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'save_auth_info()' - Save authentication information for a job. + */ + +static void +save_auth_info( + cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job, /* I - Job */ + ipp_attribute_t *auth_info) /* I - auth-info attribute, if any */ +{ + int i; /* Looping var */ + char filename[1024]; /* Job authentication filename */ + cups_file_t *fp; /* Job authentication file */ + char line[2048]; /* Line for file */ + cupsd_printer_t *dest; /* Destination printer/class */ + + + /* + * This function saves the in-memory authentication information for + * a job so that it can be used to authenticate with a remote host. + * The information is stored in a file that is readable only by the + * root user. The fields are Base-64 encoded, each on a separate line, + * followed by random number (up to 1024) of newlines to limit the + * amount of information that is exposed. + * + * Because of the potential for exposing of authentication information, + * this functionality is only enabled when running cupsd as root. + * + * This caching only works for the Basic and BasicDigest authentication + * types. Digest authentication cannot be cached this way, and in + * the future Kerberos authentication may make all of this obsolete. + * + * Authentication information is saved whenever an authenticated + * Print-Job, Create-Job, or CUPS-Authenticate-Job operation is + * performed. + * + * This information is deleted after a job is completed or canceled, + * so reprints may require subsequent re-authentication. + */ + + if (RunUser) + return; + + if ((dest = cupsdFindDest(job->dest)) == NULL) + return; + + /* + * Create the authentication file and change permissions... + */ + + snprintf(filename, sizeof(filename), "%s/a%05d", RequestRoot, job->id); + if ((fp = cupsFileOpen(filename, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to save authentication info to \"%s\" - %s", + filename, strerror(errno)); + return; + } + + fchown(cupsFileNumber(fp), 0, 0); + fchmod(cupsFileNumber(fp), 0400); + + if (auth_info && auth_info->num_values == dest->num_auth_info_required) + { + /* + * Write 1 to 3 auth values... + */ + + cupsdClearString(&job->auth_username); + cupsdClearString(&job->auth_domain); + cupsdClearString(&job->auth_password); + + for (i = 0; i < auth_info->num_values; i ++) + { + httpEncode64_2(line, sizeof(line), auth_info->values[i].string.text, + strlen(auth_info->values[i].string.text)); + cupsFilePrintf(fp, "%s\n", line); + + if (!strcmp(dest->auth_info_required[i], "username")) + cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s", + auth_info->values[i].string.text); + else if (!strcmp(dest->auth_info_required[i], "domain")) + cupsdSetStringf(&job->auth_domain, "AUTH_DOMAIN=%s", + auth_info->values[i].string.text); + else if (!strcmp(dest->auth_info_required[i], "password")) + cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", + auth_info->values[i].string.text); + } + } + else if (con->username[0]) + { + /* + * Write the authenticated username... + */ + + httpEncode64_2(line, sizeof(line), con->username, strlen(con->username)); + cupsFilePrintf(fp, "%s\n", line); + + cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s", con->username); + cupsdClearString(&job->auth_domain); + + /* + * Write the authenticated password... + */ + + httpEncode64_2(line, sizeof(line), con->password, strlen(con->password)); + cupsFilePrintf(fp, "%s\n", line); + + cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", con->password); + } + + /* + * Write a random number of newlines to the end of the file... + */ + + for (i = (CUPS_RAND() % 1024); i >= 0; i --) + cupsFilePutChar(fp, '\n'); + + /* + * Close the file and return... + */ + + cupsFileClose(fp); + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H) +# ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID + if (con->have_gss && + (con->http.hostaddr->addr.sa_family == AF_LOCAL || con->gss_creds)) +# else + if (con->have_gss && con->gss_creds) +# endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */ + save_krb5_creds(con, job); + else if (job->ccname) + cupsdClearString(&(job->ccname)); +#endif /* HAVE_GSSAPI && HAVE_KRB5_H */ +} + + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H) +/* + * 'save_krb5_creds()' - Save Kerberos credentials for the job. + */ + +static void +save_krb5_creds(cupsd_client_t *con, /* I - Client connection */ + cupsd_job_t *job) /* I - Job */ +{ + /* + * Get the credentials... + */ + + job->ccache = cupsdCopyKrb5Creds(con); + + /* + * Add the KRB5CCNAME environment variable to the job so that the + * backend can use the credentials when printing. + */ + + if (job->ccache) + { + cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s", + krb5_cc_get_name(KerberosContext, job->ccache)); + + cupsdLogJob(job, CUPSD_LOG_DEBUG2, "save_krb5_creds: %s", job->ccname); + } + else + cupsdClearString(&(job->ccname)); +} +#endif /* HAVE_GSSAPI && HAVE_KRB5_H */ + + +/* + * 'send_document()' - Send a file to a printer or class. + */ + +static void +send_document(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + ipp_attribute_t *attr; /* Current attribute */ + ipp_attribute_t *format; /* Request's document-format attribute */ + ipp_attribute_t *jformat; /* Job's document-format attribute */ + const char *default_format;/* document-format-default value */ + int jobid; /* Job ID number */ + cupsd_job_t *job; /* Current job */ + char job_uri[HTTP_MAX_URI], + /* Job URI */ + scheme[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 */ + cupsd_printer_t *printer; /* Current printer */ + struct stat fileinfo; /* File information */ + int kbytes; /* Size of file */ + int compression; /* Type of compression */ + int start_job; /* Start the job? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "send_document(%p[%d], %s)", 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")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + printer = cupsdFindDest(job->dest); + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * OK, see if the client is sending the document compressed - CUPS + * only supports "none" and "gzip". + */ + + compression = CUPS_FILE_NONE; + + if ((attr = ippFindAttribute(con->request, "compression", + IPP_TAG_KEYWORD)) != NULL) + { + if (strcmp(attr->values[0].string.text, "none") +#ifdef HAVE_LIBZ + && strcmp(attr->values[0].string.text, "gzip") +#endif /* HAVE_LIBZ */ + ) + { + send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\"!"), + attr->values[0].string.text); + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD, + "compression", NULL, attr->values[0].string.text); + return; + } + +#ifdef HAVE_LIBZ + if (!strcmp(attr->values[0].string.text, "gzip")) + compression = CUPS_FILE_GZIP; +#endif /* HAVE_LIBZ */ + } + + /* + * Do we have a file to print? + */ + + if (!con->filename) + { + /* + * Check for an empty request with "last-document" set to true, which is + * used to close an "open" job by RFC 2911, section 3.3.2. + */ + + if (job->num_files > 0 && + (attr = ippFindAttribute(con->request, "last-document", + IPP_TAG_BOOLEAN)) != NULL && + attr->values[0].boolean) + goto last_document; + + send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?!")); + 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) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"!"), + format->values[0].string.text); + return; + } + } + else if ((default_format = cupsGetOption("document-format", + printer->num_options, + printer->options)) != NULL) + { + /* + * Use default document format... + */ + + if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Could not scan type \"%s\"!"), + default_format); + return; + } + } + else + { + /* + * No document format attribute? Auto-type it! + */ + + strcpy(super, "application"); + strcpy(type, "octet-stream"); + } + + if (!strcmp(super, "application") && !strcmp(type, "octet-stream")) + { + /* + * Auto-type the file... + */ + + ipp_attribute_t *doc_name; /* document-name attribute */ + + + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Auto-typing file..."); + + doc_name = ippFindAttribute(con->request, "document-name", IPP_TAG_NAME); + filetype = mimeFileType(MimeDatabase, con->filename, + doc_name ? doc_name->values[0].string.text : NULL, + &compression); + + if (!filetype) + filetype = mimeType(MimeDatabase, super, type); + + if (filetype) + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Request file type is %s/%s.", + filetype->super, filetype->type); + } + else + filetype = mimeType(MimeDatabase, super, type); + + if (filetype) + { + /* + * Replace the document-format attribute value with the auto-typed or + * default one. + */ + + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); + + if ((jformat = ippFindAttribute(job->attrs, "document-format", + IPP_TAG_MIMETYPE)) != NULL) + { + _cupsStrFree(jformat->values[0].string.text); + + jformat->values[0].string.text = _cupsStrAlloc(mimetype); + } + else + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); + } + else if (!filetype) + { + send_ipp_status(con, IPP_DOCUMENT_FORMAT, + _("Unsupported format \'%s/%s\'!"), super, type); + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Do you have the raw file printing rules enabled?"); + + if (format) + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, + "document-format", NULL, format->values[0].string.text); + + return; + } + + if (printer->filetypes && !cupsArrayFind(printer->filetypes, filetype)) + { + snprintf(mimetype, sizeof(mimetype), "%s/%s", filetype->super, + filetype->type); + + send_ipp_status(con, IPP_DOCUMENT_FORMAT, + _("Unsupported format \'%s\'!"), mimetype); + + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, + "document-format", NULL, mimetype); + + return; + } + + /* + * Add the file to the job... + */ + + cupsdLoadJob(job); + + if (add_file(con, job, filetype, compression)) + return; + + if (stat(con->filename, &fileinfo)) + kbytes = 0; + else + kbytes = (fileinfo.st_size + 1023) / 1024; + + cupsdUpdateQuota(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); + + cupsdClearString(&con->filename); + + cupsdLogJob(job, CUPSD_LOG_INFO, "File of type %s/%s queued by \"%s\".", + filetype->super, filetype->type, job->username); + + /* + * Start the job if this is the last document... + */ + + 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 (cupsdTimeoutJob(job)) + return; + + if (job->state_value == IPP_JOB_STOPPED) + { + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; + } + else if (job->state_value == 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 || !strcmp(attr->values[0].string.text, "no-hold")) + { + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; + } + } + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + + start_job = 1; + } + 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 || !strcmp(attr->values[0].string.text, "no-hold")) + { + job->state->values[0].integer = IPP_JOB_HELD; + job->state_value = IPP_JOB_HELD; + job->hold_until = time(NULL) + MultipleOperationTimeout; + job->dirty = 1; + + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + } + + start_job = 0; + } + + /* + * Fill in the response info... + */ + + snprintf(job_uri, sizeof(job_uri), "http://%s:%d/jobs/%d", ServerName, + LocalPort, jobid); + + 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", jobid); + + ippAddInteger(con->response, IPP_TAG_JOB, IPP_TAG_ENUM, "job-state", + job->state_value); + add_job_state_reasons(con, job); + + con->response->request.status.status_code = IPP_OK; + + /* + * Start the job if necessary... + */ + + if (start_job) + cupsdCheckJobs(); +} + + +/* + * 'send_http_error()' - Send a HTTP error back to the IPP client. + */ + +static void +send_http_error( + cupsd_client_t *con, /* I - Client connection */ + http_status_t status, /* I - HTTP status code */ + cupsd_printer_t *printer) /* I - Printer, if any */ +{ + ipp_attribute_t *uri; /* Request URI, if any */ + + + if ((uri = ippFindAttribute(con->request, "printer-uri", + IPP_TAG_URI)) == NULL) + uri = ippFindAttribute(con->request, "job-uri", IPP_TAG_URI); + + cupsdLogMessage(status == HTTP_FORBIDDEN ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG, + "Returning HTTP %s for %s (%s) from %s", + httpStatus(status), + ippOpString(con->request->request.op.operation_id), + uri ? uri->values[0].string.text : "no URI", + con->http.hostname); + + if (printer) + { + int auth_type; /* Type of authentication required */ + + + auth_type = CUPSD_AUTH_NONE; + + if (status == HTTP_UNAUTHORIZED && + printer->num_auth_info_required > 0 && + !strcmp(printer->auth_info_required[0], "negotiate") && + con->request && + (con->request->request.op.operation_id == IPP_PRINT_JOB || + con->request->request.op.operation_id == IPP_CREATE_JOB || + con->request->request.op.operation_id == CUPS_AUTHENTICATE_JOB)) + { + /* + * Creating and authenticating jobs requires Kerberos... + */ + + auth_type = CUPSD_AUTH_NEGOTIATE; + } + else + { + /* + * Use policy/location-defined authentication requirements... + */ + + char resource[HTTP_MAX_URI]; /* Resource portion of URI */ + cupsd_location_t *auth; /* Pointer to authentication element */ + + + if (printer->type & CUPS_PRINTER_CLASS) + snprintf(resource, sizeof(resource), "/classes/%s", printer->name); + else + snprintf(resource, sizeof(resource), "/printers/%s", printer->name); + + if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL || + auth->type == CUPSD_AUTH_NONE) + auth = cupsdFindPolicyOp(printer->op_policy_ptr, + con->request ? + con->request->request.op.operation_id : + IPP_PRINT_JOB); + + if (auth) + { + if (auth->type == CUPSD_AUTH_DEFAULT) + auth_type = DefaultAuthType; + else + auth_type = auth->type; + } + } + + cupsdSendError(con, status, auth_type); + } + else + cupsdSendError(con, status, CUPSD_AUTH_NONE); + + ippDelete(con->response); + con->response = NULL; + + return; +} + + +/* + * 'send_ipp_status()' - Send a status back to the IPP client. + */ + +static void +send_ipp_status(cupsd_client_t *con, /* I - Client connection */ + ipp_status_t status, /* I - IPP status code */ + const char *message,/* I - Status message */ + ...) /* I - Additional args as needed */ +{ + va_list ap; /* Pointer to additional args */ + char formatted[1024]; /* Formatted errror message */ + + + va_start(ap, message); + vsnprintf(formatted, sizeof(formatted), + _cupsLangString(con->language, message), ap); + va_end(ap); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "%s %s: %s", + ippOpString(con->request->request.op.operation_id), + ippErrorString(status), formatted); + + 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, "utf-8"); + + 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); + + ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_TEXT, + "status-message", NULL, formatted); +} + + +/* + * 'set_default()' - Set the default destination... + */ + +static void +set_default(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer, /* Printer */ + *oldprinter; /* Old default printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_default(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, NULL); + return; + } + + /* + * Set it as the default... + */ + + oldprinter = DefaultPrinter; + DefaultPrinter = printer; + + if (oldprinter) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, oldprinter, NULL, + "%s is no longer the default printer.", oldprinter->name); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, + "%s is now the default printer.", printer->name); + + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS | CUPSD_DIRTY_CLASSES | + CUPSD_DIRTY_REMOTE | CUPSD_DIRTY_PRINTCAP); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Default destination set to \"%s\" by \"%s\".", + printer->name, get_username(con)); + + /* + * 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(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Job URI */ +{ + ipp_attribute_t *attr, /* Current attribute */ + *attr2; /* Job attribute */ + int jobid; /* Job ID */ + cupsd_job_t *job; /* Current job */ + char scheme[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 event; /* Events? */ + int check_jobs; /* Check jobs? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_job_attrs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Start with "everything is OK" status... + */ + + con->response->request.status.status_code = IPP_OK; + + /* + * See if we have a job URI or a printer URI... + */ + + if (!strcmp(uri->name, "printer-uri")) + { + /* + * Got a printer URI; see if we also have a job-id attribute... + */ + + if ((attr = ippFindAttribute(con->request, "job-id", + IPP_TAG_INTEGER)) == NULL) + { + send_ipp_status(con, IPP_BAD_REQUEST, + _("Got a printer-uri attribute but no job-id!")); + return; + } + + jobid = attr->values[0].integer; + } + else + { + /* + * Got a job URI; parse it to get the job ID... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri->values[0].string.text, scheme, + sizeof(scheme), username, sizeof(username), host, + sizeof(host), &port, resource, sizeof(resource)); + + if (strncmp(resource, "/jobs/", 6)) + { + /* + * Not a valid URI! + */ + + send_ipp_status(con, IPP_BAD_REQUEST, + _("Bad job-uri attribute \"%s\"!"), + uri->values[0].string.text); + return; + } + + jobid = atoi(resource + 6); + } + + /* + * See if the job exists... + */ + + if ((job = cupsdFindJob(jobid)) == NULL) + { + /* + * Nope - return a "not found" error... + */ + + send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist!"), jobid); + return; + } + + /* + * See if the job has been completed... + */ + + if (job->state_value > IPP_JOB_STOPPED) + { + /* + * Return a "not-possible" error... + */ + + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job #%d is finished and cannot be altered!"), jobid); + return; + } + + /* + * See if the job is owned by the requesting user... + */ + + if (!validate_user(job, con, job->username, username, sizeof(username))) + { + send_http_error(con, con->username[0] ? HTTP_FORBIDDEN : HTTP_UNAUTHORIZED, + cupsdFindDest(job->dest)); + return; + } + + /* + * See what the user wants to change. + */ + + cupsdLoadJob(job); + + check_jobs = 0; + event = 0; + + for (attr = con->request->attrs; attr; attr = attr->next) + { + if (attr->group_tag != IPP_TAG_JOB || !attr->name) + continue; + + if (!strcmp(attr->name, "attributes-charset") || + !strcmp(attr->name, "attributes-natural-language") || + !strcmp(attr->name, "document-compression") || + !strcmp(attr->name, "document-format") || + !strcmp(attr->name, "job-detailed-status-messages") || + !strcmp(attr->name, "job-document-access-errors") || + !strcmp(attr->name, "job-id") || + !strcmp(attr->name, "job-impressions-completed") || + !strcmp(attr->name, "job-k-octets") || + !strcmp(attr->name, "job-originating-host-name") || + !strcmp(attr->name, "job-originating-user-name") || + !strcmp(attr->name, "job-printer-up-time") || + !strcmp(attr->name, "job-printer-uri") || + !strcmp(attr->name, "job-sheets") || + !strcmp(attr->name, "job-state-message") || + !strcmp(attr->name, "job-state-reasons") || + !strcmp(attr->name, "job-uri") || + !strcmp(attr->name, "number-of-documents") || + !strcmp(attr->name, "number-of-intervening-jobs") || + !strcmp(attr->name, "output-device-assigned") || + !strncmp(attr->name, "date-time-at-", 13) || + !strncmp(attr->name, "job-k-octets", 12) || + !strncmp(attr->name, "job-media-sheets", 16) || + !strncmp(attr->name, "time-at-", 8)) + { + /* + * Read-only attrs! + */ + + send_ipp_status(con, IPP_ATTRIBUTES_NOT_SETTABLE, + _("%s cannot be changed."), attr->name); + + if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL) + attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP; + + continue; + } + + if (!strcmp(attr->name, "job-priority")) + { + /* + * Change the job priority... + */ + + if (attr->value_tag != IPP_TAG_INTEGER) + { + send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value!")); + + if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL) + attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP; + } + else if (job->state_value >= IPP_JOB_PROCESSING) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job is completed and cannot be changed.")); + return; + } + else if (con->response->request.status.status_code == IPP_OK) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Setting job-priority to %d", + attr->values[0].integer); + cupsdSetJobPriority(job, attr->values[0].integer); + + check_jobs = 1; + event |= CUPSD_EVENT_JOB_CONFIG_CHANGED | + CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED; + } + } + else if (!strcmp(attr->name, "job-state")) + { + /* + * Change the job state... + */ + + if (attr->value_tag != IPP_TAG_ENUM) + { + send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value!")); + + if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL) + attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP; + } + else + { + switch (attr->values[0].integer) + { + case IPP_JOB_PENDING : + case IPP_JOB_HELD : + if (job->state_value > IPP_JOB_HELD) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job state cannot be changed.")); + return; + } + else if (con->response->request.status.status_code == IPP_OK) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Setting job-state to %d", + attr->values[0].integer); + cupsdSetJobState(job, attr->values[0].integer, + CUPSD_JOB_DEFAULT, + "Job state changed by \"%s\"", username); + check_jobs = 1; + } + break; + + case IPP_JOB_PROCESSING : + case IPP_JOB_STOPPED : + if (job->state_value != attr->values[0].integer) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job state cannot be changed.")); + return; + } + break; + + case IPP_JOB_CANCELED : + case IPP_JOB_ABORTED : + case IPP_JOB_COMPLETED : + if (job->state_value > IPP_JOB_PROCESSING) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Job state cannot be changed.")); + return; + } + else if (con->response->request.status.status_code == IPP_OK) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Setting job-state to %d", + attr->values[0].integer); + cupsdSetJobState(job, (ipp_jstate_t)attr->values[0].integer, + CUPSD_JOB_DEFAULT, + "Job state changed by \"%s\"", username); + check_jobs = 1; + } + break; + } + } + } + else if (con->response->request.status.status_code != IPP_OK) + continue; + else if ((attr2 = ippFindAttribute(job->attrs, attr->name, + IPP_TAG_ZERO)) != NULL) + { + /* + * Some other value; first free the old value... + */ + + if (job->attrs->prev) + job->attrs->prev->next = attr2->next; + else + job->attrs->attrs = attr2->next; + + if (job->attrs->last == attr2) + job->attrs->last = job->attrs->prev; + + _ippFreeAttr(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-hold-until")) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Setting job-hold-until to %s", + attr->values[0].string.text); + cupsdSetJobHoldUntil(job, attr->values[0].string.text, 0); + + if (!strcmp(attr->values[0].string.text, "no-hold")) + { + cupsdReleaseJob(job); + check_jobs = 1; + } + else + cupsdSetJobState(job, IPP_JOB_HELD, CUPSD_JOB_DEFAULT, + "Job held by \"%s\".", username); + + event |= CUPSD_EVENT_JOB_CONFIG_CHANGED | CUPSD_EVENT_JOB_STATE; + } + } + else if (attr->value_tag == IPP_TAG_DELETEATTR) + { + /* + * Delete the attribute... + */ + + if ((attr2 = ippFindAttribute(job->attrs, attr->name, + IPP_TAG_ZERO)) != NULL) + { + if (job->attrs->prev) + job->attrs->prev->next = attr2->next; + else + job->attrs->attrs = attr2->next; + + if (attr2 == job->attrs->last) + job->attrs->last = job->attrs->prev; + + _ippFreeAttr(attr2); + + event |= CUPSD_EVENT_JOB_CONFIG_CHANGED; + } + } + else + { + /* + * Add new option by copying it... + */ + + copy_attribute(job->attrs, attr, 0); + + event |= CUPSD_EVENT_JOB_CONFIG_CHANGED; + } + } + + /* + * Save the job... + */ + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + + /* + * Send events as needed... + */ + + if (event & CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED) + cupsdAddEvent(CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED, + cupsdFindDest(job->dest), job, + "Job priority changed by user."); + + if (event & CUPSD_EVENT_JOB_STATE) + cupsdAddEvent(CUPSD_EVENT_JOB_STATE, cupsdFindDest(job->dest), job, + job->state_value == IPP_JOB_HELD ? + "Job held by user." : "Job restarted by user."); + + if (event & CUPSD_EVENT_JOB_CONFIG_CHANGED) + cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job, + "Job options changed by user."); + + /* + * Start jobs if possible... + */ + + if (check_jobs) + cupsdCheckJobs(); +} + + +/* + * 'set_printer_attrs()' - Set printer attributes. + */ + +static void +set_printer_attrs(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer/class */ + ipp_attribute_t *attr; /* Printer attribute */ + int changed = 0; /* Was anything changed? */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_attrs(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Return a list of attributes that can be set via Set-Printer-Attributes. + */ + + if ((attr = ippFindAttribute(con->request, "printer-location", + IPP_TAG_TEXT)) != NULL) + { + cupsdSetString(&printer->location, attr->values[0].string.text); + changed = 1; + } + + if ((attr = ippFindAttribute(con->request, "printer-info", + IPP_TAG_TEXT)) != NULL) + { + cupsdSetString(&printer->info, attr->values[0].string.text); + changed = 1; + } + + /* + * Update the printer attributes and return... + */ + + if (changed) + { + cupsdSetPrinterAttrs(printer); + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + cupsdAddEvent(CUPSD_EVENT_PRINTER_CONFIG, printer, NULL, + "Printer \"%s\" description or location changed by \"%s\".", + printer->name, get_username(con)); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Printer \"%s\" description or location changed by \"%s\".", + printer->name, get_username(con)); + } + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'set_printer_defaults()' - Set printer default options from a request. + */ + +static void +set_printer_defaults( + cupsd_client_t *con, /* I - Client connection */ + cupsd_printer_t *printer) /* I - Printer */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Current attribute */ + int namelen; /* Length of attribute name */ + char name[256], /* New attribute name */ + value[256]; /* String version of integer attrs */ + + + for (attr = con->request->attrs; attr; attr = attr->next) + { + /* + * Skip non-printer attributes... + */ + + if (attr->group_tag != IPP_TAG_PRINTER || !attr->name) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "set_printer_defaults: %s", attr->name); + + if (!strcmp(attr->name, "job-sheets-default")) + { + /* + * Only allow keywords and names... + */ + + if (attr->value_tag != IPP_TAG_NAME && attr->value_tag != IPP_TAG_KEYWORD) + continue; + + /* + * Only allow job-sheets-default to be set when running without a + * system high classification level... + */ + + if (Classification) + continue; + + cupsdSetString(&printer->job_sheets[0], attr->values[0].string.text); + + if (attr->num_values > 1) + cupsdSetString(&printer->job_sheets[1], attr->values[1].string.text); + else + cupsdSetString(&printer->job_sheets[1], "none"); + } + else if (!strcmp(attr->name, "requesting-user-name-allowed")) + { + cupsdFreePrinterUsers(printer); + + printer->deny_users = 0; + + if (attr->value_tag == IPP_TAG_NAME && + (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "all"))) + { + for (i = 0; i < attr->num_values; i ++) + cupsdAddPrinterUser(printer, attr->values[i].string.text); + } + } + else if (!strcmp(attr->name, "requesting-user-name-denied")) + { + cupsdFreePrinterUsers(printer); + + printer->deny_users = 1; + + if (attr->value_tag == IPP_TAG_NAME && + (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "none"))) + { + for (i = 0; i < attr->num_values; i ++) + cupsdAddPrinterUser(printer, attr->values[i].string.text); + } + } + else if (!strcmp(attr->name, "job-quota-period")) + { + if (attr->value_tag != IPP_TAG_INTEGER) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-quota-period to %d...", + attr->values[0].integer); + cupsdFreeQuotas(printer); + + printer->quota_period = attr->values[0].integer; + } + else if (!strcmp(attr->name, "job-k-limit")) + { + if (attr->value_tag != IPP_TAG_INTEGER) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-k-limit to %d...", + attr->values[0].integer); + cupsdFreeQuotas(printer); + + printer->k_limit = attr->values[0].integer; + } + else if (!strcmp(attr->name, "job-page-limit")) + { + if (attr->value_tag != IPP_TAG_INTEGER) + continue; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Setting job-page-limit to %d...", + attr->values[0].integer); + cupsdFreeQuotas(printer); + + printer->page_limit = attr->values[0].integer; + } + else if (!strcmp(attr->name, "printer-op-policy")) + { + cupsd_policy_t *p; /* Policy */ + + + if (attr->value_tag != IPP_TAG_NAME) + continue; + + if ((p = cupsdFindPolicy(attr->values[0].string.text)) != NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting printer-op-policy to \"%s\"...", + attr->values[0].string.text); + cupsdSetString(&printer->op_policy, attr->values[0].string.text); + printer->op_policy_ptr = p; + } + else + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Unknown printer-op-policy \"%s\"."), + attr->values[0].string.text); + return; + } + } + else if (!strcmp(attr->name, "printer-error-policy")) + { + if (attr->value_tag != IPP_TAG_NAME && attr->value_tag != IPP_TAG_KEYWORD) + continue; + + if (strcmp(attr->values[0].string.text, "retry-current-job") && + ((printer->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS)) || + (strcmp(attr->values[0].string.text, "abort-job") && + strcmp(attr->values[0].string.text, "retry-job") && + strcmp(attr->values[0].string.text, "stop-printer")))) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, + _("Unknown printer-error-policy \"%s\"."), + attr->values[0].string.text); + return; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting printer-error-policy to \"%s\"...", + attr->values[0].string.text); + cupsdSetString(&printer->error_policy, attr->values[0].string.text); + } + + /* + * Skip any other non-default attributes... + */ + + namelen = strlen(attr->name); + if (namelen < 9 || strcmp(attr->name + namelen - 8, "-default") || + namelen > (sizeof(name) - 1) || attr->num_values != 1) + continue; + + /* + * OK, anything else must be a user-defined default... + */ + + strlcpy(name, attr->name, sizeof(name)); + name[namelen - 8] = '\0'; /* Strip "-default" */ + + switch (attr->value_tag) + { + case IPP_TAG_DELETEATTR : + printer->num_options = cupsRemoveOption(name, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Deleting %s", attr->name); + break; + + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_URI : + printer->num_options = cupsAddOption(name, + attr->values[0].string.text, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to \"%s\"...", attr->name, + attr->values[0].string.text); + break; + + case IPP_TAG_BOOLEAN : + printer->num_options = cupsAddOption(name, + attr->values[0].boolean ? + "true" : "false", + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, + attr->values[0].boolean ? "true" : "false"); + break; + + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + sprintf(value, "%d", attr->values[0].integer); + printer->num_options = cupsAddOption(name, value, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, value); + break; + + case IPP_TAG_RANGE : + sprintf(value, "%d-%d", attr->values[0].range.lower, + attr->values[0].range.upper); + printer->num_options = cupsAddOption(name, value, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, value); + break; + + case IPP_TAG_RESOLUTION : + sprintf(value, "%dx%d%s", attr->values[0].resolution.xres, + attr->values[0].resolution.yres, + attr->values[0].resolution.units == IPP_RES_PER_INCH ? + "dpi" : "dpc"); + printer->num_options = cupsAddOption(name, value, + printer->num_options, + &(printer->options)); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Setting %s to %s...", attr->name, value); + break; + + default : + /* Do nothing for other values */ + break; + } + } +} + + +/* + * 'start_printer()' - Start a printer. + */ + +static void +start_printer(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_printer(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Start the printer... + */ + + printer->state_message[0] = '\0'; + + cupsdStartPrinter(printer, 1); + + if (dtype & CUPS_PRINTER_CLASS) + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" started by \"%s\".", + printer->name, get_username(con)); + else + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" started by \"%s\".", + printer->name, get_username(con)); + + cupsdCheckJobs(); + + /* + * Everything was ok, so return OK status... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'stop_printer()' - Stop a printer. + */ + +static void +stop_printer(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + http_status_t status; /* Policy status */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + cupsd_printer_t *printer; /* Printer data */ + ipp_attribute_t *attr; /* printer-state-message attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_printer(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Stop the 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)); + } + + cupsdStopPrinter(printer, 1); + + if (dtype & CUPS_PRINTER_CLASS) + cupsdLogMessage(CUPSD_LOG_INFO, "Class \"%s\" stopped by \"%s\".", + printer->name, get_username(con)); + else + cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" stopped by \"%s\".", + printer->name, get_username(con)); + + /* + * Everything was ok, so return OK status... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'url_encode_attr()' - URL-encode a string attribute. + */ + +static void +url_encode_attr(ipp_attribute_t *attr, /* I - Attribute */ + char *buffer,/* I - String buffer */ + int bufsize)/* I - Size of buffer */ +{ + int i; /* Looping var */ + char *bufptr, /* Pointer into buffer */ + *bufend; /* End of buffer */ + + + strlcpy(buffer, attr->name, bufsize); + bufptr = buffer + strlen(buffer); + bufend = buffer + bufsize - 1; + + for (i = 0; i < attr->num_values; i ++) + { + if (bufptr >= bufend) + break; + + if (i) + *bufptr++ = ','; + else + *bufptr++ = '='; + + if (bufptr >= bufend) + break; + + *bufptr++ = '\''; + + bufptr = url_encode_string(attr->values[i].string.text, + bufptr, bufend - bufptr + 1); + + if (bufptr >= bufend) + break; + + *bufptr++ = '\''; + } + + *bufptr = '\0'; +} + + +/* + * 'url_encode_string()' - URL-encode a string. + */ + +static char * /* O - End of string */ +url_encode_string(const char *s, /* I - String */ + char *buffer, /* I - String buffer */ + int bufsize) /* I - Size of buffer */ +{ + char *bufptr, /* Pointer into buffer */ + *bufend; /* End of buffer */ + static const char *hex = "0123456789ABCDEF"; + /* Hex digits */ + + + bufptr = buffer; + bufend = buffer + bufsize - 1; + + while (*s && bufptr < bufend) + { + if (*s == ' ' || *s == '%' || *s == '+') + { + if (bufptr >= (bufend - 2)) + break; + + *bufptr++ = '%'; + *bufptr++ = hex[(*s >> 4) & 15]; + *bufptr++ = hex[*s & 15]; + + s ++; + } + else if (*s == '\'' || *s == '\\') + { + if (bufptr >= (bufend - 1)) + break; + + *bufptr++ = '\\'; + *bufptr++ = *s++; + } + else + *bufptr++ = *s++; + } + + *bufptr = '\0'; + + return (bufptr); +} + + +/* + * 'user_allowed()' - See if a user is allowed to print to a queue. + */ + +static int /* O - 0 if not allowed, 1 if allowed */ +user_allowed(cupsd_printer_t *p, /* I - Printer or class */ + const char *username) /* I - Username */ +{ + int i; /* Looping var */ + struct passwd *pw; /* User password data */ + char baseuser[256], /* Base username */ + *baseptr; /* Pointer to "@" in base username */ + + + if (p->num_users == 0) + return (1); + + if (!strcmp(username, "root")) + return (1); + + if (strchr(username, '@')) + { + /* + * Strip @REALM for username check... + */ + + strlcpy(baseuser, username, sizeof(baseuser)); + + if ((baseptr = strchr(baseuser, '@')) != NULL) + *baseptr = '\0'; + + username = baseuser; + } + + pw = getpwnam(username); + endpwent(); + + for (i = 0; i < p->num_users; i ++) + { + if (p->users[i][0] == '@') + { + /* + * Check group membership... + */ + + if (cupsdCheckGroup(username, pw, p->users[i] + 1)) + break; + } + else if (p->users[i][0] == '#') + { + /* + * Check UUID... + */ + + if (cupsdCheckGroup(username, pw, p->users[i])) + break; + } + else if (!strcasecmp(username, p->users[i])) + break; + } + + return ((i < p->num_users) != p->deny_users); +} + + +/* + * 'validate_job()' - Validate printer options and destination. + */ + +static void +validate_job(cupsd_client_t *con, /* I - Client connection */ + ipp_attribute_t *uri) /* I - Printer URI */ +{ + int i; /* Temporary variable */ + http_status_t status; /* Policy status */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_attribute_t *format; /* Document-format attribute */ + cups_ptype_t dtype; /* Destination type (printer/class) */ + char super[MIME_MAX_SUPER], + /* Supertype of file */ + type[MIME_MAX_TYPE]; + /* Subtype of file */ + cupsd_printer_t *printer; /* Printer */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "validate_job(%p[%d], %s)", con, + con->http.fd, uri->values[0].string.text); + + /* + * 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")) + { + send_ipp_status(con, IPP_ATTRIBUTES, + _("Unsupported compression attribute %s!"), + attr->values[0].string.text); + 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) + { + send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"!"), + format->values[0].string.text); + return; + } + + if ((strcmp(super, "application") || strcmp(type, "octet-stream")) && + !mimeType(MimeDatabase, super, type)) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Do you have the raw file printing rules enabled?"); + send_ipp_status(con, IPP_DOCUMENT_FORMAT, + _("Unsupported format \"%s\"!"), + format->values[0].string.text); + ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE, + "document-format", NULL, format->values[0].string.text); + return; + } + } + + /* + * Is the destination valid? + */ + + if (!cupsdValidateDest(uri->values[0].string.text, &dtype, &printer)) + { + /* + * Bad URI... + */ + + send_ipp_status(con, IPP_NOT_FOUND, + _("The printer or class was not found.")); + return; + } + + /* + * Check policy... + */ + + if ((status = cupsdCheckPolicy(printer->op_policy_ptr, con, NULL)) != HTTP_OK) + { + send_http_error(con, status, printer); + return; + } + + /* + * Check quotas... + */ + + if ((i = check_quotas(con, printer)) < 0) + { + send_ipp_status(con, IPP_NOT_POSSIBLE, _("Quota limit reached.")); + return; + } + else if (i == 0) + { + send_ipp_status(con, IPP_NOT_AUTHORIZED, _("Not allowed to print.")); + return; + } + + /* + * Everything was ok, so return OK status... + */ + + con->response->request.status.status_code = IPP_OK; +} + + +/* + * 'validate_name()' - Make sure the printer name only contains valid chars. + */ + +static int /* O - 0 if name is no good, 1 if 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 > 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#') + return (0); + + /* + * All the characters are good; validate the length, too... + */ + + return ((ptr - name) < 128); +} + + +/* + * 'validate_user()' - Validate the user for the request. + */ + +static int /* O - 1 if permitted, 0 otherwise */ +validate_user(cupsd_job_t *job, /* I - Job */ + cupsd_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 */ +{ + cupsd_printer_t *printer; /* Printer for job */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "validate_user(job=%d, con=%d, owner=\"%s\", username=%p, " + "userlen=%d)", + job->id, con ? con->http.fd : 0, + owner ? owner : "(null)", username, userlen); + + /* + * Validate input... + */ + + if (!con || !owner || !username || userlen <= 0) + return (0); + + /* + * Get the best authenticated username that is available. + */ + + strlcpy(username, get_username(con), userlen); + + /* + * Check the username against the owner... + */ + + printer = cupsdFindDest(job->dest); + + return (cupsdCheckPolicy(printer ? printer->op_policy_ptr : DefaultPolicyPtr, + con, owner) == HTTP_OK); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/job.c b/scheduler/job.c new file mode 100644 index 0000000000..b053f71133 --- /dev/null +++ b/scheduler/job.c @@ -0,0 +1,4610 @@ +/* + * "$Id$" + * + * Job management routines for the CUPS scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddJob() - Add a new job to the job queue. + * cupsdCancelJobs() - Cancel all jobs for the given + * destination/user. + * cupsdCheckJobs() - Check the pending jobs and start any if the + * destination is available. + * cupsdCleanJobs() - Clean out old jobs. + * cupsdContinueJob() - Continue printing with the next file in a job. + * cupsdDeleteJob() - Free all memory used by a job. + * cupsdFreeAllJobs() - Free all jobs from memory. + * cupsdFindJob() - Find the specified job. + * cupsdGetPrinterJobCount() - Get the number of pending, processing, or held + * jobs in a printer or class. + * cupsdGetUserJobCount() - Get the number of pending, processing, or held + * jobs for a user. + * cupsdLoadAllJobs() - Load all jobs from disk. + * cupsdLoadJob() - Load a single job. + * cupsdMoveJob() - Move the specified job to a different + * destination. + * cupsdReleaseJob() - Release the specified job. + * cupsdRestartJob() - Restart the specified job. + * cupsdSaveAllJobs() - Save a summary of all jobs to disk. + * cupsdSaveJob() - Save a job to disk. + * cupsdSetJobHoldUntil() - Set the hold time for a job. + * cupsdSetJobPriority() - Set the priority of a job, moving it up/down + * in the list as needed. + * cupsdSetJobState() - Set the state of the specified print job. + * cupsdStopAllJobs() - Stop all print jobs. + * cupsdUnloadCompletedJobs() - Flush completed job history from memory. + * compare_active_jobs() - Compare the job IDs and priorities of two + * jobs. + * compare_jobs() - Compare the job IDs of two jobs. + * dump_job_history() - Dump any debug messages for a job. + * free_job_history() - Free any log history. + * finalize_job() - Cleanup after job filter processes and support + * data. + * get_options() - Get a string containing the job options. + * ipp_length() - Compute the size of the buffer needed to hold + * the textual IPP attributes. + * load_job_cache() - Load jobs from the job.cache file. + * load_next_job_id() - Load the NextJobId value from the job.cache + * file. + * load_request_root() - Load jobs from the RequestRoot directory. + * set_time() - Set one of the "time-at-xyz" attributes. + * start_job() - Start a print job. + * stop_job() - Stop a print job. + * unload_job() - Unload a job from memory. + * update_job() - Read a status update from a job's filters. + * update_job_attrs() - Update the job-printer-* attributes. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include +#include +#include + + +/* + * Design Notes for Job Management + * ------------------------------- + * + * STATE CHANGES + * + * pending Do nothing/check jobs + * pending-held Send SIGTERM to filters and backend + * processing Do nothing/start job + * stopped Send SIGKILL to filters and backend + * canceled Send SIGTERM to filters and backend + * aborted Finalize + * completed Finalize + * + * Finalize clears the printer <-> job association, deletes the status + * buffer, closes all of the pipes, etc. and doesn't get run until all of + * the print processes are finished. + * + * UNLOADING OF JOBS (cupsdUnloadCompletedJobs) + * + * We unload the job attributes when they are not needed to reduce overall + * memory consumption. We don't unload jobs where job->state_value < + * IPP_JOB_STOPPED, job->printer != NULL, or job->access_time is recent. + * + * STARTING OF JOBS (start_job) + * + * When a job is started, a status buffer, several pipes, a security + * profile, and a backend process are created for the life of that job. + * These are shared for every file in a job. For remote print jobs, the + * IPP backend is provided with every file in the job and no filters are + * run. + * + * The job->printer member tracks which printer is printing a job, which + * can be different than the destination in job->dest for classes. The + * printer object also has a job pointer to track which job is being + * printed. + * + * PRINTING OF JOB FILES (cupsdContinueJob) + * + * Each file in a job is filtered by 0 or more programs. After getting the + * list of filters needed and the total cost, the job is either passed or + * put back to the processing state until the current FilterLevel comes down + * enough to allow printing. + * + * If we can print, we build a string for the print options and run each of + * the filters, piping the output from one into the next. + * + * JOB STATUS UPDATES (update_job) + * + * The update_job function gets called whenever there are pending messages + * on the status pipe. These generally are updates to the marker-*, + * printer-state-message, or printer-state-reasons attributes. On EOF, + * finalize_job is called to clean up. + * + * FINALIZING JOBS (finalize_job) + * + * When all filters and the backend are done, we set the job state to + * completed (no errors), aborted (filter errors or abort-job policy), + * pending-held (auth required or retry-job policy), or pending + * (retry-current-job or stop-printer policies) as appropriate. + * + * Then we close the pipes and free the status buffers and profiles. + * + * JOB FILE COMPLETION (process_children in main.c) + * + * For multiple-file jobs, process_children (in main.c) sees that all + * filters have exited and calls in to print the next file if there are + * more files in the job, otherwise it waits for the backend to exit and + * update_job to do the cleanup. + */ + + +/* + * Local globals... + */ + +static mime_filter_t gziptoany_filter = + { + NULL, /* Source type */ + NULL, /* Destination type */ + 0, /* Cost */ + "gziptoany" /* Filter program to run */ + }; + + +/* + * Local functions... + */ + +static int compare_active_jobs(void *first, void *second, void *data); +static int compare_jobs(void *first, void *second, void *data); +static void dump_job_history(cupsd_job_t *job); +static void finalize_job(cupsd_job_t *job, int set_job_state); +static void free_job_history(cupsd_job_t *job); +static char *get_options(cupsd_job_t *job, int banner_page, char *copies, + size_t copies_size, char *title, + size_t title_size); +static size_t ipp_length(ipp_t *ipp); +static void load_job_cache(const char *filename); +static void load_next_job_id(const char *filename); +static void load_request_root(void); +static void set_time(cupsd_job_t *job, const char *name); +static void start_job(cupsd_job_t *job, cupsd_printer_t *printer); +static void stop_job(cupsd_job_t *job, cupsd_jobaction_t action); +static void unload_job(cupsd_job_t *job); +static void update_job(cupsd_job_t *job); +static void update_job_attrs(cupsd_job_t *job, int do_message); + + +/* + * 'cupsdAddJob()' - Add a new job to the job queue. + */ + +cupsd_job_t * /* O - New job record */ +cupsdAddJob(int priority, /* I - Job priority */ + const char *dest) /* I - Job destination */ +{ + cupsd_job_t *job; /* New job record */ + + + if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL) + return (NULL); + + job->id = NextJobId ++; + job->priority = priority; + job->back_pipes[0] = -1; + job->back_pipes[1] = -1; + job->print_pipes[0] = -1; + job->print_pipes[1] = -1; + job->side_pipes[0] = -1; + job->side_pipes[1] = -1; + job->status_pipes[0] = -1; + job->status_pipes[1] = -1; + + cupsdSetString(&job->dest, dest); + + /* + * Add the new job to the "all jobs" and "active jobs" lists... + */ + + cupsArrayAdd(Jobs, job); + cupsArrayAdd(ActiveJobs, job); + + return (job); +} + + +/* + * 'cupsdCancelJobs()' - Cancel all jobs for the given destination/user. + */ + +void +cupsdCancelJobs(const char *dest, /* I - Destination to cancel */ + const char *username, /* I - Username or NULL */ + int purge) /* I - Purge jobs? */ +{ + cupsd_job_t *job; /* Current job */ + + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + { + if ((!job->dest || !job->username) && !cupsdLoadJob(job)) + continue; + + if ((!dest || !strcmp(job->dest, dest)) && + (!username || !strcmp(job->username, username))) + { + /* + * Cancel all jobs matching this destination/user... + */ + + if (purge) + cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_PURGE, + "Job purged by user."); + else if (job->state_value < IPP_JOB_CANCELED) + cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT, + "Job canceled by user."); + } + } + + cupsdCheckJobs(); +} + + +/* + * 'cupsdCheckJobs()' - Check the pending jobs and start any if the destination + * is available. + */ + +void +cupsdCheckJobs(void) +{ + cupsd_job_t *job; /* Current job in queue */ + cupsd_printer_t *printer, /* Printer destination */ + *pclass; /* Printer class destination */ + ipp_attribute_t *attr; /* Job attribute */ + time_t curtime; /* Current time */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdCheckJobs: %d active jobs, sleeping=%d, reload=%d", + cupsArrayCount(ActiveJobs), Sleeping, NeedReload); + + curtime = time(NULL); + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + { + /* + * Kill jobs if they are unresponsive... + */ + + if (job->kill_time && job->kill_time <= curtime) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Stopping unresponsive job!", + job->id); + + stop_job(job, CUPSD_JOB_FORCE); + continue; + } + + /* + * Start held jobs if they are ready... + */ + + if (job->state_value == IPP_JOB_HELD && + job->hold_until && + job->hold_until < curtime) + { + if (job->pending_timeout) + { + /* + * This job is pending; check that we don't have an active Send-Document + * operation in progress on any of the client connections, then timeout + * the job so we can start printing... + */ + + cupsd_client_t *con; /* Current client connection */ + + + for (con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + con = (cupsd_client_t *)cupsArrayNext(Clients)) + if (con->request && + con->request->request.op.operation_id == IPP_SEND_DOCUMENT) + break; + + if (con) + continue; + + if (cupsdTimeoutJob(job)) + continue; + } + + cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, + "Job submission timed out."); + } + + /* + * Continue jobs that are waiting on the FilterLimit... + */ + + if (job->pending_cost > 0 && + ((FilterLevel + job->pending_cost) < FilterLimit || FilterLevel == 0)) + cupsdContinueJob(job); + + /* + * Start pending jobs if the destination is available... + */ + + if (job->state_value == IPP_JOB_PENDING && !NeedReload && !Sleeping && + !DoingShutdown && !job->printer) + { + printer = cupsdFindDest(job->dest); + pclass = NULL; + + while (printer && + (printer->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS))) + { + /* + * If the class is remote, just pass it to the remote server... + */ + + pclass = printer; + + if (pclass->state == IPP_PRINTER_STOPPED) + printer = NULL; + else if (pclass->type & CUPS_PRINTER_REMOTE) + break; + else + printer = cupsdFindAvailablePrinter(printer->name); + } + + if (!printer && !pclass) + { + /* + * Whoa, the printer and/or class for this destination went away; + * cancel the job... + */ + + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_PURGE, + "Job aborted because the destination printer/class " + "has gone away."); + } + else if (printer && !printer->holding_new_jobs) + { + /* + * See if the printer is available or remote and not printing a job; + * if so, start the job... + */ + + if (pclass) + { + /* + * Add/update a job-actual-printer-uri attribute for this job + * so that we know which printer actually printed the job... + */ + + if ((attr = ippFindAttribute(job->attrs, "job-actual-printer-uri", + IPP_TAG_URI)) != NULL) + cupsdSetString(&attr->values[0].string.text, printer->uri); + else + ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, + "job-actual-printer-uri", NULL, printer->uri); + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + } + + if ((!(printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is local */ + printer->state == IPP_PRINTER_IDLE) || /* and idle, OR */ + ((printer->type & CUPS_PRINTER_DISCOVERED) && /* Printer is remote */ + !printer->job)) /* and not printing */ + { + /* + * Start the job... + */ + + start_job(job, printer); + } + } + } + } +} + + +/* + * 'cupsdCleanJobs()' - Clean out old jobs. + */ + +void +cupsdCleanJobs(void) +{ + cupsd_job_t *job; /* Current job */ + + + if (MaxJobs <= 0 && JobHistory) + return; + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job && (cupsArrayCount(Jobs) >= MaxJobs || !JobHistory); + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + if (job->state_value >= IPP_JOB_CANCELED && !job->printer) + cupsdDeleteJob(job, CUPSD_JOB_PURGE); +} + + +/* + * 'cupsdContinueJob()' - Continue printing with the next file in a job. + */ + +void +cupsdContinueJob(cupsd_job_t *job) /* I - Job */ +{ + int i; /* Looping var */ + int slot; /* Pipe slot */ + cups_array_t *filters = NULL,/* Filters for job */ + *prefilters; /* Filters with prefilters */ + mime_filter_t *filter, /* Current filter */ + *prefilter, /* Prefilter */ + port_monitor; /* Port monitor filter */ + char scheme[255]; /* Device URI scheme */ + ipp_attribute_t *attr; /* Current attribute */ + const char *ptr, /* Pointer into value */ + *abort_message; /* Abort message */ + ipp_jstate_t abort_state = IPP_JOB_STOPPED; + /* New job state on abort */ + struct stat backinfo; /* Backend file information */ + int backroot; /* Run backend as root? */ + int pid; /* Process ID of new filter process */ + int banner_page; /* 1 if banner page, 0 otherwise */ + int filterfds[2][2] = { { -1, -1 }, { -1, -1 } }; + /* Pipes used between filters */ + int envc; /* Number of environment variables */ + char **argv = NULL, /* Filter command-line arguments */ + filename[1024], /* Job filename */ + command[1024], /* Full path to command */ + jobid[255], /* Job ID string */ + title[IPP_MAX_NAME], + /* Job title string */ + copies[255], /* # copies string */ + *options, /* Options string */ + *envp[MAX_ENV + 19], + /* Environment variables */ + charset[255], /* CHARSET env variable */ + class_name[255],/* CLASS env variable */ + classification[1024], + /* CLASSIFICATION env variable */ + content_type[1024], + /* CONTENT_TYPE env variable */ + device_uri[1024], + /* DEVICE_URI env variable */ + final_content_type[1024], + /* FINAL_CONTENT_TYPE env variable */ + lang[255], /* LANG env variable */ +#ifdef __APPLE__ + apple_language[255], + /* APPLE_LANGUAGE env variable */ +#endif /* __APPLE__ */ + ppd[1024], /* PPD env variable */ + printer_info[255], + /* PRINTER_INFO env variable */ + printer_location[255], + /* PRINTER_LOCATION env variable */ + printer_name[255], + /* PRINTER env variable */ + rip_max_cache[255]; + /* RIP_MAX_CACHE env variable */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdContinueJob(job=%p(%d)): current_file=%d, num_files=%d", + job, job->id, job->current_file, job->num_files); + + /* + * Figure out what filters are required to convert from + * the source to the destination type... + */ + + FilterLevel -= job->cost; + + job->cost = 0; + job->pending_cost = 0; + + memset(job->filters, 0, sizeof(job->filters)); + + + if (job->printer->raw) + { + /* + * Remote jobs and raw queues go directly to the printer without + * filtering... + */ + + cupsdLogJob(job, CUPSD_LOG_DEBUG, "Sending job to queue tagged as raw..."); + } + else + { + /* + * Local jobs get filtered... + */ + + filters = mimeFilter(MimeDatabase, job->filetypes[job->current_file], + job->printer->filetype, &(job->cost)); + + if (!filters) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, + "Unable to convert file %d to printable format!", + job->current_file); + + abort_message = "Aborting job because it cannot be printed."; + abort_state = IPP_JOB_ABORTED; + + goto abort_job; + } + + /* + * Remove NULL ("-") filters... + */ + + for (filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + if (!strcmp(filter->filter, "-")) + cupsArrayRemove(filters, filter); + + if (cupsArrayCount(filters) == 0) + { + cupsArrayDelete(filters); + filters = NULL; + } + + /* + * If this printer has any pre-filters, insert the required pre-filter + * in the filters array... + */ + + if (job->printer->prefiltertype && filters) + { + prefilters = cupsArrayNew(NULL, NULL); + + for (filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + { + if ((prefilter = mimeFilterLookup(MimeDatabase, filter->src, + job->printer->prefiltertype))) + { + cupsArrayAdd(prefilters, prefilter); + job->cost += prefilter->cost; + } + + cupsArrayAdd(prefilters, filter); + } + + cupsArrayDelete(filters); + filters = prefilters; + } + } + + /* + * Set a minimum cost of 100 for all jobs so that FilterLimit + * works with raw queues and other low-cost paths. + */ + + if (job->cost < 100) + job->cost = 100; + + /* + * See if the filter cost is too high... + */ + + if ((FilterLevel + job->cost) > FilterLimit && FilterLevel > 0 && + FilterLimit > 0) + { + /* + * Don't print this job quite yet... + */ + + cupsArrayDelete(filters); + + cupsdLogJob(job, CUPSD_LOG_INFO, + "Holding because filter limit has been reached."); + cupsdLogJob(job, CUPSD_LOG_DEBUG2, + "cupsdContinueJob: file=%d, cost=%d, level=%d, limit=%d", + job->current_file, job->cost, FilterLevel, + FilterLimit); + + job->pending_cost = job->cost; + job->cost = 0; + return; + } + + FilterLevel += job->cost; + + /* + * Add decompression/raw filter as needed... + */ + + if ((!job->printer->raw && job->compressions[job->current_file]) || + (!filters && !job->printer->remote && + (job->num_files > 1 || !strncmp(job->printer->device_uri, "file:", 5)))) + { + /* + * Add gziptoany filter to the front of the list... + */ + + if (!filters) + filters = cupsArrayNew(NULL, NULL); + + if (!cupsArrayInsert(filters, &gziptoany_filter)) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Unable to add decompression filter - %s", strerror(errno)); + + cupsArrayDelete(filters); + + abort_message = "Stopping job because the scheduler ran out of memory."; + + goto abort_job; + } + } + + /* + * Add port monitor, if any... + */ + + if (job->printer->port_monitor) + { + /* + * Add port monitor to the end of the list... + */ + + if (!filters) + filters = cupsArrayNew(NULL, NULL); + + port_monitor.src = NULL; + port_monitor.dst = NULL; + port_monitor.cost = 0; + + snprintf(port_monitor.filter, sizeof(port_monitor.filter), + "%s/monitor/%s", ServerBin, job->printer->port_monitor); + + if (!cupsArrayAdd(filters, &port_monitor)) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Unable to add port monitor - %s", strerror(errno)); + + abort_message = "Stopping job because the scheduler ran out of memory."; + + goto abort_job; + } + } + + /* + * Make sure we don't go over the "MAX_FILTERS" limit... + */ + + if (cupsArrayCount(filters) > MAX_FILTERS) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Too many filters (%d > %d), unable to print!", + cupsArrayCount(filters), MAX_FILTERS); + + abort_message = "Aborting job because it needs too many filters to print."; + abort_state = IPP_JOB_ABORTED; + + goto abort_job; + } + + /* + * Determine if we are printing a banner page or not... + */ + + if (job->job_sheets == NULL) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, "No job-sheets attribute."); + if ((job->job_sheets = + ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_ZERO)) != NULL) + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "... but someone added one without setting job_sheets!"); + } + else if (job->job_sheets->num_values == 1) + cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s", + job->job_sheets->values[0].string.text); + else + cupsdLogJob(job, CUPSD_LOG_DEBUG, "job-sheets=%s,%s", + job->job_sheets->values[0].string.text, + job->job_sheets->values[1].string.text); + + if (job->printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) + banner_page = 0; + else if (job->job_sheets == NULL) + banner_page = 0; + else if (strcasecmp(job->job_sheets->values[0].string.text, "none") != 0 && + job->current_file == 0) + banner_page = 1; + else if (job->job_sheets->num_values > 1 && + strcasecmp(job->job_sheets->values[1].string.text, "none") != 0 && + job->current_file == (job->num_files - 1)) + banner_page = 1; + else + banner_page = 0; + + if ((options = get_options(job, banner_page, copies, sizeof(copies), title, + sizeof(title))) == NULL) + { + abort_message = "Stopping job because the scheduler ran out of memory."; + + goto abort_job; + } + + /* + * 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. + * + * For remote jobs, we send all of the files in the argument list. + */ + + if (job->printer->remote) + argv = calloc(7 + job->num_files, sizeof(char *)); + else + argv = calloc(8, sizeof(char *)); + + if (!argv) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "Unable to allocate argument array - %s", + strerror(errno)); + + abort_message = "Stopping job because the scheduler ran out of memory."; + + goto abort_job; + } + + sprintf(jobid, "%d", job->id); + + argv[0] = job->printer->name; + argv[1] = jobid; + argv[2] = job->username; + argv[3] = title; + argv[4] = copies; + argv[5] = options; + + if (job->printer->remote && job->num_files > 1) + { + for (i = 0; i < job->num_files; i ++) + { + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, + job->id, i + 1); + argv[6 + i] = strdup(filename); + } + } + else + { + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, + job->id, job->current_file + 1); + argv[6] = filename; + } + + for (i = 0; argv[i]; i ++) + cupsdLogJob(job, CUPSD_LOG_DEBUG, "argv[%d]=\"%s\"", i, argv[i]); + + /* + * Create environment variable strings for the filters... + */ + + attr = ippFindAttribute(job->attrs, "attributes-natural-language", + IPP_TAG_LANGUAGE); + +#ifdef __APPLE__ + strcpy(apple_language, "APPLE_LANGUAGE="); + _cupsAppleLanguage(attr->values[0].string.text, + apple_language + 15, sizeof(apple_language) - 15); +#endif /* __APPLE__ */ + + switch (strlen(attr->values[0].string.text)) + { + default : + /* + * This is an unknown or badly formatted language code; use + * the POSIX locale... + */ + + strcpy(lang, "LANG=C"); + break; + + case 2 : + /* + * Just the language code (ll)... + */ + + snprintf(lang, sizeof(lang), "LANG=%s.UTF-8", + attr->values[0].string.text); + break; + + case 5 : + /* + * Language and country code (ll-cc)... + */ + + snprintf(lang, sizeof(lang), "LANG=%c%c_%c%c.UTF-8", + attr->values[0].string.text[0], + attr->values[0].string.text[1], + toupper(attr->values[0].string.text[3] & 255), + toupper(attr->values[0].string.text[4] & 255)); + break; + } + + if ((attr = ippFindAttribute(job->attrs, "document-format", + IPP_TAG_MIMETYPE)) != NULL && + (ptr = strstr(attr->values[0].string.text, "charset=")) != NULL) + snprintf(charset, sizeof(charset), "CHARSET=%s", ptr + 8); + else + strlcpy(charset, "CHARSET=utf-8", sizeof(charset)); + + snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s", + job->filetypes[job->current_file]->super, + job->filetypes[job->current_file]->type); + snprintf(device_uri, sizeof(device_uri), "DEVICE_URI=%s", + job->printer->device_uri); + snprintf(ppd, sizeof(ppd), "PPD=%s/ppd/%s.ppd", ServerRoot, + job->printer->name); + snprintf(printer_info, sizeof(printer_name), "PRINTER_INFO=%s", + job->printer->info ? job->printer->info : ""); + snprintf(printer_location, sizeof(printer_name), "PRINTER_LOCATION=%s", + job->printer->location ? job->printer->location : ""); + snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", job->printer->name); + snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache); + + envc = cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + + envp[envc ++] = charset; + envp[envc ++] = lang; +#ifdef __APPLE__ + envp[envc ++] = apple_language; +#endif /* __APPLE__ */ + envp[envc ++] = ppd; + envp[envc ++] = rip_max_cache; + envp[envc ++] = content_type; + envp[envc ++] = device_uri; + envp[envc ++] = printer_info; + envp[envc ++] = printer_location; + envp[envc ++] = printer_name; + envp[envc ++] = banner_page ? "CUPS_FILETYPE=job-sheet" : + "CUPS_FILETYPE=document"; + + if (!job->printer->remote && !job->printer->raw) + { + filter = (mime_filter_t *)cupsArrayLast(filters); + + if (job->printer->port_monitor) + filter = (mime_filter_t *)cupsArrayPrev(filters); + + if (filter && filter->dst) + { + snprintf(final_content_type, sizeof(final_content_type), + "FINAL_CONTENT_TYPE=%s/%s", + filter->dst->super, filter->dst->type); + envp[envc ++] = final_content_type; + } + } + + if (Classification && !banner_page) + { + if ((attr = ippFindAttribute(job->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); + + envp[envc ++] = classification; + } + + if (job->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) + { + snprintf(class_name, sizeof(class_name), "CLASS=%s", job->dest); + envp[envc ++] = class_name; + } + + if (job->auth_username) + envp[envc ++] = job->auth_username; + if (job->auth_domain) + envp[envc ++] = job->auth_domain; + if (job->auth_password) + envp[envc ++] = job->auth_password; + +#ifdef HAVE_GSSAPI + if (job->ccname) + envp[envc ++] = job->ccname; +#endif /* HAVE_GSSAPI */ + + envp[envc] = NULL; + + for (i = 0; i < envc; i ++) + if (!strncmp(envp[i], "AUTH_", 5)) + cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"AUTH_%c****\"", i, + envp[i][5]); + else if (strncmp(envp[i], "DEVICE_URI=", 11)) + cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"%s\"", i, envp[i]); + else + cupsdLogJob(job, CUPSD_LOG_DEBUG, "envp[%d]=\"DEVICE_URI=%s\"", i, + job->printer->sanitized_device_uri); + + if (job->printer->remote) + job->current_file = job->num_files; + else + job->current_file ++; + + /* + * Now create processes for all of the filters... + */ + + for (i = 0, slot = 0, filter = (mime_filter_t *)cupsArrayFirst(filters); + filter; + i ++, filter = (mime_filter_t *)cupsArrayNext(filters)) + { + if (filter->filter[0] != '/') + snprintf(command, sizeof(command), "%s/filter/%s", ServerBin, + filter->filter); + else + strlcpy(command, filter->filter, sizeof(command)); + + if (i < (cupsArrayCount(filters) - 1)) + { + if (cupsdOpenPipe(filterfds[slot])) + { + abort_message = "Stopping job because the scheduler could not create " + "the filter pipes."; + + goto abort_job; + } + } + else + { + if (job->current_file == 1) + { + if (strncmp(job->printer->device_uri, "file:", 5) != 0) + { + if (cupsdOpenPipe(job->print_pipes)) + { + abort_message = "Stopping job because the scheduler could not " + "create the backend pipes."; + + goto abort_job; + } + } + else + { + job->print_pipes[0] = -1; + if (!strcmp(job->printer->device_uri, "file:/dev/null") || + !strcmp(job->printer->device_uri, "file:///dev/null")) + job->print_pipes[1] = -1; + else + { + if (!strncmp(job->printer->device_uri, "file:/dev/", 10)) + job->print_pipes[1] = open(job->printer->device_uri + 5, + O_WRONLY | O_EXCL); + else if (!strncmp(job->printer->device_uri, "file:///dev/", 12)) + job->print_pipes[1] = open(job->printer->device_uri + 7, + O_WRONLY | O_EXCL); + else if (!strncmp(job->printer->device_uri, "file:///", 8)) + job->print_pipes[1] = open(job->printer->device_uri + 7, + O_WRONLY | O_CREAT | O_TRUNC, 0600); + else + job->print_pipes[1] = open(job->printer->device_uri + 5, + O_WRONLY | O_CREAT | O_TRUNC, 0600); + + if (job->print_pipes[1] < 0) + { + abort_message = "Stopping job because the scheduler could not " + "open the output file."; + + goto abort_job; + } + + fcntl(job->print_pipes[1], F_SETFD, + fcntl(job->print_pipes[1], F_GETFD) | FD_CLOEXEC); + } + } + } + + filterfds[slot][0] = job->print_pipes[0]; + filterfds[slot][1] = job->print_pipes[1]; + } + + pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0], + filterfds[slot][1], job->status_pipes[1], + job->back_pipes[0], job->side_pipes[0], 0, + job->profile, job, job->filters + i); + + cupsdClosePipe(filterfds[!slot]); + + if (pid == 0) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "Unable to start filter \"%s\" - %s.", + filter->filter, strerror(errno)); + + abort_message = "Stopping job because the scheduler could not execute a " + "filter."; + + goto abort_job; + } + + cupsdLogJob(job, CUPSD_LOG_INFO, "Started filter %s (PID %d)", command, + pid); + + argv[6] = NULL; + slot = !slot; + } + + cupsArrayDelete(filters); + filters = NULL; + + /* + * Finally, pipe the final output into a backend process if needed... + */ + + if (strncmp(job->printer->device_uri, "file:", 5) != 0) + { + if (job->current_file == 1 || job->printer->remote) + { + sscanf(job->printer->device_uri, "%254[^:]", scheme); + snprintf(command, sizeof(command), "%s/backend/%s", ServerBin, scheme); + + /* + * See if the backend needs to run as root... + */ + + if (RunUser) + backroot = 0; + else if (stat(command, &backinfo)) + backroot = 0; + else + backroot = !(backinfo.st_mode & (S_IRWXG | S_IRWXO)); + + argv[0] = job->printer->sanitized_device_uri; + + filterfds[slot][0] = -1; + filterfds[slot][1] = -1; + + pid = cupsdStartProcess(command, argv, envp, filterfds[!slot][0], + filterfds[slot][1], job->status_pipes[1], + job->back_pipes[1], job->side_pipes[1], + backroot, job->profile, job, &(job->backend)); + + if (pid == 0) + { + abort_message = "Stopping job because the sheduler could not execute " + "the backend."; + + goto abort_job; + } + else + { + cupsdLogJob(job, CUPSD_LOG_INFO, "Started backend %s (PID %d)", + command, pid); + } + } + + if (job->current_file == job->num_files) + { + cupsdClosePipe(job->print_pipes); + cupsdClosePipe(job->back_pipes); + cupsdClosePipe(job->side_pipes); + + close(job->status_pipes[1]); + job->status_pipes[1] = -1; + } + } + else + { + filterfds[slot][0] = -1; + filterfds[slot][1] = -1; + + if (job->current_file == job->num_files) + { + cupsdClosePipe(job->print_pipes); + + close(job->status_pipes[1]); + job->status_pipes[1] = -1; + } + } + + cupsdClosePipe(filterfds[slot]); + + if (job->printer->remote && job->num_files > 1) + { + for (i = 0; i < job->num_files; i ++) + free(argv[i + 6]); + } + + free(argv); + + cupsdAddSelect(job->status_buffer->fd, (cupsd_selfunc_t)update_job, NULL, + job); + + cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "Job #%d started.", + job->id); + + /* + * If we get here than we are able to run the printer driver filters, so clear + * the missing and insecure warnings... + */ + + if (cupsdSetPrinterReasons(job->printer, "-cups-missing-filter-warning," + "cups-insecure-filter-warning")) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, + "Printer drivers now functional."); + + return; + + + /* + * If we get here, we need to abort the current job and close out all + * files and pipes... + */ + + abort_job: + + FilterLevel -= job->cost; + job->cost = 0; + + for (slot = 0; slot < 2; slot ++) + cupsdClosePipe(filterfds[slot]); + + cupsArrayDelete(filters); + + if (argv) + { + if (job->printer->remote && job->num_files > 1) + { + for (i = 0; i < job->num_files; i ++) + free(argv[i + 6]); + } + + free(argv); + } + + cupsdClosePipe(job->print_pipes); + cupsdClosePipe(job->back_pipes); + cupsdClosePipe(job->side_pipes); + + cupsdRemoveSelect(job->status_pipes[0]); + cupsdClosePipe(job->status_pipes); + cupsdStatBufDelete(job->status_buffer); + job->status_buffer = NULL; + + /* + * Update the printer and job state. + */ + + cupsdSetJobState(job, abort_state, CUPSD_JOB_DEFAULT, "%s", abort_message); + cupsdSetPrinterState(job->printer, IPP_PRINTER_IDLE, 0); + update_job_attrs(job, 0); + + if (job->history) + free_job_history(job); + + cupsArrayRemove(PrintingJobs, job); + + /* + * Clear the printer <-> job association... + */ + + job->printer->job = NULL; + job->printer = NULL; +} + + +/* + * 'cupsdDeleteJob()' - Free all memory used by a job. + */ + +void +cupsdDeleteJob(cupsd_job_t *job, /* I - Job */ + cupsd_jobaction_t action)/* I - Action */ +{ + char filename[1024]; /* Job filename */ + + + if (job->printer) + finalize_job(job, 1); + + if (action == CUPSD_JOB_PURGE) + { + /* + * Remove the job info file... + */ + + snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, + job->id); + unlink(filename); + } + + cupsdClearString(&job->username); + cupsdClearString(&job->dest); + cupsdClearString(&job->auth_username); + cupsdClearString(&job->auth_domain); + cupsdClearString(&job->auth_password); + +#ifdef HAVE_GSSAPI + /* + * Destroy the credential cache and clear the KRB5CCNAME env var string. + */ + + if (job->ccache) + { + krb5_cc_destroy(KerberosContext, job->ccache); + job->ccache = NULL; + } + + cupsdClearString(&job->ccname); +#endif /* HAVE_GSSAPI */ + + if (job->num_files > 0) + { + free(job->compressions); + free(job->filetypes); + + while (job->num_files > 0) + { + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, + job->id, job->num_files); + unlink(filename); + + job->num_files --; + } + } + + if (job->history) + free_job_history(job); + + unload_job(job); + + cupsArrayRemove(Jobs, job); + cupsArrayRemove(ActiveJobs, job); + cupsArrayRemove(PrintingJobs, job); + + free(job); +} + + +/* + * 'cupsdFreeAllJobs()' - Free all jobs from memory. + */ + +void +cupsdFreeAllJobs(void) +{ + cupsd_job_t *job; /* Current job */ + + + if (!Jobs) + return; + + cupsdHoldSignals(); + + cupsdStopAllJobs(CUPSD_JOB_FORCE, 0); + cupsdSaveAllJobs(); + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + cupsdDeleteJob(job, CUPSD_JOB_DEFAULT); + + cupsdReleaseSignals(); +} + + +/* + * 'cupsdFindJob()' - Find the specified job. + */ + +cupsd_job_t * /* O - Job data */ +cupsdFindJob(int id) /* I - Job ID */ +{ + cupsd_job_t key; /* Search key */ + + + key.id = id; + + return ((cupsd_job_t *)cupsArrayFind(Jobs, &key)); +} + + +/* + * 'cupsdGetPrinterJobCount()' - Get the number of pending, processing, + * or held jobs in a printer or class. + */ + +int /* O - Job count */ +cupsdGetPrinterJobCount( + const char *dest) /* I - Printer or class name */ +{ + int count; /* Job count */ + cupsd_job_t *job; /* Current job */ + + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0; + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + if (job->dest && !strcasecmp(job->dest, dest)) + count ++; + + return (count); +} + + +/* + * 'cupsdGetUserJobCount()' - Get the number of pending, processing, + * or held jobs for a user. + */ + +int /* O - Job count */ +cupsdGetUserJobCount( + const char *username) /* I - Username */ +{ + int count; /* Job count */ + cupsd_job_t *job; /* Current job */ + + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs), count = 0; + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + if (!strcasecmp(job->username, username)) + count ++; + + return (count); +} + + +/* + * 'cupsdLoadAllJobs()' - Load all jobs from disk. + */ + +void +cupsdLoadAllJobs(void) +{ + char filename[1024]; /* Full filename of job.cache file */ + struct stat fileinfo, /* Information on job.cache file */ + dirinfo; /* Information on RequestRoot dir */ + + + + /* + * Create the job arrays as needed... + */ + + if (!Jobs) + Jobs = cupsArrayNew(compare_jobs, NULL); + + if (!ActiveJobs) + ActiveJobs = cupsArrayNew(compare_active_jobs, NULL); + + if (!PrintingJobs) + PrintingJobs = cupsArrayNew(compare_jobs, NULL); + + /* + * See whether the job.cache file is older than the RequestRoot directory... + */ + + snprintf(filename, sizeof(filename), "%s/job.cache", CacheDir); + + if (stat(filename, &fileinfo)) + { + fileinfo.st_mtime = 0; + + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to get file information for \"%s\" - %s", + filename, strerror(errno)); + } + + if (stat(RequestRoot, &dirinfo)) + { + dirinfo.st_mtime = 0; + + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to get directory information for \"%s\" - %s", + RequestRoot, strerror(errno)); + } + + /* + * Load the most recent source for job data... + */ + + if (dirinfo.st_mtime > fileinfo.st_mtime) + { + load_request_root(); + + load_next_job_id(filename); + } + else + load_job_cache(filename); + + /* + * Clean out old jobs as needed... + */ + + if (MaxJobs > 0 && cupsArrayCount(Jobs) >= MaxJobs) + cupsdCleanJobs(); +} + + +/* + * 'cupsdLoadJob()' - Load a single job. + */ + +int /* O - 1 on success, 0 on failure */ +cupsdLoadJob(cupsd_job_t *job) /* I - Job */ +{ + char jobfile[1024]; /* Job filename */ + cups_file_t *fp; /* Job file */ + int fileid; /* Current file ID */ + ipp_attribute_t *attr; /* Job attribute */ + const char *dest; /* Destination name */ + cupsd_printer_t *destptr; /* Pointer to destination */ + mime_type_t **filetypes; /* New filetypes array */ + int *compressions; /* New compressions array */ + + + if (job->attrs) + { + if (job->state_value > IPP_JOB_STOPPED) + job->access_time = time(NULL); + + return (1); + } + + if ((job->attrs = ippNew()) == NULL) + { + cupsdLogJob(job, CUPSD_LOG_ERROR, "Ran out of memory for job attributes!"); + return (0); + } + + /* + * Load job attributes... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading attributes...", job->id); + + snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, job->id); + if ((fp = cupsFileOpen(jobfile, "r")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to open job control file \"%s\" - %s!", + job->id, jobfile, strerror(errno)); + goto error; + } + + if (ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL, job->attrs) != IPP_DATA) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to read job control file \"%s\"!", job->id, + jobfile); + cupsFileClose(fp); + goto error; + } + + cupsFileClose(fp); + + /* + * Copy attribute data to the job object... + */ + + if (!ippFindAttribute(job->attrs, "time-at-creation", IPP_TAG_INTEGER)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad time-at-creation attribute in " + "control file!", job->id); + goto error; + } + + if ((job->state = ippFindAttribute(job->attrs, "job-state", + IPP_TAG_ENUM)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad job-state attribute in control " + "file!", job->id); + goto error; + } + + job->state_value = (ipp_jstate_t)job->state->values[0].integer; + + if (!job->dest) + { + if ((attr = ippFindAttribute(job->attrs, "job-printer-uri", + IPP_TAG_URI)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] No job-printer-uri attribute in control file!", + job->id); + goto error; + } + + if ((dest = cupsdValidateDest(attr->values[0].string.text, &(job->dtype), + &destptr)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to queue job for destination \"%s\"!", + job->id, attr->values[0].string.text); + goto error; + } + + cupsdSetString(&job->dest, dest); + } + else if ((destptr = cupsdFindDest(job->dest)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to queue job for destination \"%s\"!", + job->id, job->dest); + goto error; + } + + job->sheets = ippFindAttribute(job->attrs, "job-media-sheets-completed", + IPP_TAG_INTEGER); + job->job_sheets = ippFindAttribute(job->attrs, "job-sheets", IPP_TAG_NAME); + + if (!job->priority) + { + if ((attr = ippFindAttribute(job->attrs, "job-priority", + IPP_TAG_INTEGER)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad job-priority attribute in " + "control file!", job->id); + goto error; + } + + job->priority = attr->values[0].integer; + } + + if (!job->username) + { + if ((attr = ippFindAttribute(job->attrs, "job-originating-user-name", + IPP_TAG_NAME)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Missing or bad job-originating-user-name " + "attribute in control file!", job->id); + goto error; + } + + cupsdSetString(&job->username, attr->values[0].string.text); + } + + /* + * Set the job hold-until time and state... + */ + + if (job->state_value == 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) + cupsdSetJobHoldUntil(job, attr->values[0].string.text, CUPSD_JOB_DEFAULT); + else + { + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; + } + } + else if (job->state_value == IPP_JOB_PROCESSING) + { + job->state->values[0].integer = IPP_JOB_PENDING; + job->state_value = IPP_JOB_PENDING; + } + + if (!job->num_files) + { + /* + * Find all the d##### files... + */ + + for (fileid = 1; fileid < 10000; fileid ++) + { + snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot, + job->id, fileid); + + if (access(jobfile, 0)) + break; + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "[Job %d] Auto-typing document file \"%s\"...", job->id, + jobfile); + + if (fileid > job->num_files) + { + if (job->num_files == 0) + { + compressions = (int *)calloc(fileid, sizeof(int)); + filetypes = (mime_type_t **)calloc(fileid, sizeof(mime_type_t *)); + } + else + { + compressions = (int *)realloc(job->compressions, + sizeof(int) * fileid); + filetypes = (mime_type_t **)realloc(job->filetypes, + sizeof(mime_type_t *) * + fileid); + } + + if (!compressions || !filetypes) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Ran out of memory for job file types!", + job->id); + + ippDelete(job->attrs); + job->attrs = NULL; + + if (compressions) + free(compressions); + + if (filetypes) + free(filetypes); + + if (job->compressions) + { + free(job->compressions); + job->compressions = NULL; + } + + if (job->filetypes) + { + free(job->filetypes); + job->filetypes = NULL; + } + + job->num_files = 0; + return (0); + } + + job->compressions = compressions; + job->filetypes = filetypes; + job->num_files = fileid; + } + + job->filetypes[fileid - 1] = mimeFileType(MimeDatabase, jobfile, NULL, + job->compressions + fileid - 1); + + if (!job->filetypes[fileid - 1]) + job->filetypes[fileid - 1] = mimeType(MimeDatabase, "application", + "vnd.cups-raw"); + } + } + + /* + * Load authentication information as needed... + */ + + if (job->state_value < IPP_JOB_STOPPED) + { + snprintf(jobfile, sizeof(jobfile), "%s/a%05d", RequestRoot, job->id); + + cupsdClearString(&job->auth_username); + cupsdClearString(&job->auth_domain); + cupsdClearString(&job->auth_password); + + if ((fp = cupsFileOpen(jobfile, "r")) != NULL) + { + int i, /* Looping var */ + bytes; /* Size of auth data */ + char line[255], /* Line from file */ + data[255]; /* Decoded data */ + + + for (i = 0; + i < destptr->num_auth_info_required && + cupsFileGets(fp, line, sizeof(line)); + i ++) + { + bytes = sizeof(data); + httpDecode64_2(data, &bytes, line); + + if (!strcmp(destptr->auth_info_required[i], "username")) + cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s", data); + else if (!strcmp(destptr->auth_info_required[i], "domain")) + cupsdSetStringf(&job->auth_domain, "AUTH_DOMAIN=%s", data); + else if (!strcmp(destptr->auth_info_required[i], "password")) + cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", data); + } + + cupsFileClose(fp); + } + } + + job->access_time = time(NULL); + return (1); + + /* + * If we get here then something bad happened... + */ + + error: + + ippDelete(job->attrs); + job->attrs = NULL; + + if (job->compressions) + { + free(job->compressions); + job->compressions = NULL; + } + + if (job->filetypes) + { + free(job->filetypes); + job->filetypes = NULL; + } + + job->num_files = 0; + + unlink(jobfile); + + return (0); +} + + +/* + * 'cupsdMoveJob()' - Move the specified job to a different destination. + */ + +void +cupsdMoveJob(cupsd_job_t *job, /* I - Job */ + cupsd_printer_t *p) /* I - Destination printer or class */ +{ + ipp_attribute_t *attr; /* job-printer-uri attribute */ + const char *olddest; /* Old destination */ + cupsd_printer_t *oldp; /* Old pointer */ + + + /* + * Don't move completed jobs... + */ + + if (job->state_value > IPP_JOB_STOPPED) + return; + + /* + * Get the old destination... + */ + + olddest = job->dest; + + if (job->printer) + oldp = job->printer; + else + oldp = cupsdFindDest(olddest); + + /* + * Change the destination information... + */ + + cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, + "Stopping job prior to move."); + + cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, oldp, job, + "Job #%d moved from %s to %s.", job->id, olddest, + p->name); + + cupsdSetString(&job->dest, p->name); + job->dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE | + CUPS_PRINTER_IMPLICIT); + + if ((attr = ippFindAttribute(job->attrs, "job-printer-uri", + IPP_TAG_URI)) != NULL) + cupsdSetString(&(attr->values[0].string.text), p->uri); + + cupsdAddEvent(CUPSD_EVENT_JOB_STOPPED, p, job, + "Job #%d moved from %s to %s.", job->id, olddest, + p->name); + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); +} + + +/* + * 'cupsdReleaseJob()' - Release the specified job. + */ + +void +cupsdReleaseJob(cupsd_job_t *job) /* I - Job */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdReleaseJob(job=%p(%d))", job, + job->id); + + if (job->state_value == IPP_JOB_HELD) + { + /* + * Add trailing banner as needed... + */ + + if (job->pending_timeout) + cupsdTimeoutJob(job); + + cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, + "Job released by user."); + } +} + + +/* + * 'cupsdRestartJob()' - Restart the specified job. + */ + +void +cupsdRestartJob(cupsd_job_t *job) /* I - Job */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdRestartJob(job=%p(%d))", job, + job->id); + + if (job->state_value == IPP_JOB_STOPPED || job->num_files) + cupsdSetJobState(job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, + "Job restarted by user."); +} + + +/* + * 'cupsdSaveAllJobs()' - Save a summary of all jobs to disk. + */ + +void +cupsdSaveAllJobs(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* Job cache file */ + char temp[1024]; /* Temporary string */ + cupsd_job_t *job; /* Current job */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + + + snprintf(temp, sizeof(temp), "%s/job.cache", CacheDir); + if ((fp = cupsFileOpen(temp, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create job cache file \"%s\" - %s", + temp, strerror(errno)); + return; + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Saving job cache file \"%s\"...", temp); + + /* + * Restrict access to the file... + */ + + fchown(cupsFileNumber(fp), getuid(), Group); + fchmod(cupsFileNumber(fp), ConfigFilePerm); + + /* + * Write a small header to the file... + */ + + curtime = time(NULL); + curdate = localtime(&curtime); + strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate); + + cupsFilePuts(fp, "# Job cache file for " CUPS_SVERSION "\n"); + cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp); + cupsFilePrintf(fp, "NextJobId %d\n", NextJobId); + + /* + * Write each job known to the system... + */ + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + { + cupsFilePrintf(fp, "\n", job->id); + cupsFilePrintf(fp, "State %d\n", job->state_value); + cupsFilePrintf(fp, "Priority %d\n", job->priority); + cupsFilePrintf(fp, "HoldUntil %d\n", (int)job->hold_until); + cupsFilePrintf(fp, "Username %s\n", job->username); + cupsFilePrintf(fp, "Destination %s\n", job->dest); + cupsFilePrintf(fp, "DestType %d\n", job->dtype); + cupsFilePrintf(fp, "NumFiles %d\n", job->num_files); + for (i = 0; i < job->num_files; i ++) + cupsFilePrintf(fp, "File %d %s/%s %d\n", i + 1, job->filetypes[i]->super, + job->filetypes[i]->type, job->compressions[i]); + cupsFilePuts(fp, "\n"); + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdSaveJob()' - Save a job to disk. + */ + +void +cupsdSaveJob(cupsd_job_t *job) /* I - Job */ +{ + char filename[1024]; /* Job control filename */ + cups_file_t *fp; /* Job file */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSaveJob(job=%p(%d)): job->attrs=%p", + job, job->id, job->attrs); + + snprintf(filename, sizeof(filename), "%s/c%05d", RequestRoot, job->id); + + if ((fp = cupsFileOpen(filename, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to create job control file \"%s\" - %s.", + job->id, filename, strerror(errno)); + return; + } + + fchmod(cupsFileNumber(fp), 0600); + fchown(cupsFileNumber(fp), RunUser, Group); + + job->attrs->state = IPP_IDLE; + + if (ippWriteIO(fp, (ipp_iocb_t)cupsFileWrite, 1, NULL, + job->attrs) != IPP_DATA) + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unable to write job control file!", job->id); + + cupsFileClose(fp); + + job->dirty = 0; +} + + +/* + * 'cupsdSetJobHoldUntil()' - Set the hold time for a job. + */ + +void +cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */ + const char *when, /* I - When to resume */ + int update)/* I - Update job-hold-until attr? */ +{ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + int hour; /* Hold hour */ + int minute; /* Hold minute */ + int second = 0; /* Hold second */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSetJobHoldUntil(job=%p(%d), when=\"%s\", update=%d)", + job, job->id, when, update); + + if (update) + { + /* + * Update the job-hold-until attribute... + */ + + ipp_attribute_t *attr; /* job-hold-until attribute */ + + if ((attr = ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); + + if (attr) + cupsdSetString(&(attr->values[0].string.text), when); + else + attr = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-hold-until", NULL, when); + + if (attr) + { + if (isdigit(when[0] & 255)) + attr->value_tag = IPP_TAG_NAME; + else + attr->value_tag = IPP_TAG_KEYWORD; + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + } + } + + /* + * Update the hold time... + */ + + if (!strcmp(when, "indefinite") || !strcmp(when, "auth-info-required")) + { + /* + * Hold indefinitely... + */ + + job->hold_until = 0; + } + else if (!strcmp(when, "day-time")) + { + /* + * 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") || !strcmp(when, "night")) + { + /* + * 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")) + { + /* + * 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")) + { + /* + * 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")) + { + /* + * 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; + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdSetJobHoldUntil: hold_until=%d", + (int)job->hold_until); +} + + +/* + * 'cupsdSetJobPriority()' - Set the priority of a job, moving it up/down in + * the list as needed. + */ + +void +cupsdSetJobPriority( + cupsd_job_t *job, /* I - Job ID */ + int priority) /* I - New priority (0 to 100) */ +{ + ipp_attribute_t *attr; /* Job attribute */ + + + /* + * Don't change completed jobs... + */ + + if (job->state_value >= IPP_JOB_PROCESSING) + return; + + /* + * Set the new priority and re-add the job into the active list... + */ + + cupsArrayRemove(ActiveJobs, job); + + 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); + + cupsArrayAdd(ActiveJobs, job); + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); +} + + +/* + * 'cupsdSetJobState()' - Set the state of the specified print job. + */ + +void +cupsdSetJobState( + cupsd_job_t *job, /* I - Job to cancel */ + ipp_jstate_t newstate, /* I - New job state */ + cupsd_jobaction_t action, /* I - Action to take */ + const char *message, /* I - Message to log */ + ...) /* I - Additional arguments as needed */ +{ + int i; /* Looping var */ + ipp_jstate_t oldstate; /* Old state */ + char filename[1024]; /* Job filename */ + ipp_attribute_t *attr; /* Job attribute */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSetJobState(job=%p(%d), state=%d, newstate=%d, " + "action=%d, message=\"%s\")", job, job->id, job->state_value, + newstate, action, message ? message : "(null)"); + + + /* + * Make sure we have the job attributes... + */ + + if (!cupsdLoadJob(job)) + return; + + /* + * Don't do anything if the state is unchanged and we aren't purging the + * job... + */ + + oldstate = job->state_value; + if (newstate == oldstate && action != CUPSD_JOB_PURGE) + return; + + /* + * Stop any processes that are working on the current job... + */ + + if (oldstate == IPP_JOB_PROCESSING) + stop_job(job, action); + + /* + * Set the new job state... + */ + + job->state->values[0].integer = newstate; + job->state_value = newstate; + + switch (newstate) + { + case IPP_JOB_PENDING : + /* + * Update job-hold-until as needed... + */ + + if ((attr = ippFindAttribute(job->attrs, "job-hold-until", + IPP_TAG_KEYWORD)) == NULL) + attr = ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME); + + if (attr) + { + attr->value_tag = IPP_TAG_KEYWORD; + cupsdSetString(&(attr->values[0].string.text), "no-hold"); + } + + default : + break; + + case IPP_JOB_ABORTED : + case IPP_JOB_CANCELED : + case IPP_JOB_COMPLETED : + set_time(job, "time-at-completed"); + break; + } + + /* + * Log message as needed... + */ + + if (message) + { + char buffer[2048]; /* Message buffer */ + va_list ap; /* Pointer to additional arguments */ + + va_start(ap, message); + vsnprintf(buffer, sizeof(buffer), message, ap); + va_end(ap); + + if (newstate > IPP_JOB_STOPPED) + cupsdAddEvent(CUPSD_EVENT_JOB_COMPLETED, job->printer, job, "%s", buffer); + else + cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job, "%s", buffer); + + if (newstate == IPP_JOB_STOPPED || newstate == IPP_JOB_ABORTED) + cupsdLogJob(job, CUPSD_LOG_ERROR, "%s", buffer); + else + cupsdLogJob(job, CUPSD_LOG_INFO, "%s", buffer); + } + + /* + * Handle post-state-change actions... + */ + + switch (newstate) + { + case IPP_JOB_PROCESSING : + /* + * Add the job to the "printing" list... + */ + + if (!cupsArrayFind(PrintingJobs, job)) + cupsArrayAdd(PrintingJobs, job); + + /* + * Set the processing time... + */ + + set_time(job, "time-at-processing"); + + case IPP_JOB_PENDING : + case IPP_JOB_HELD : + case IPP_JOB_STOPPED : + /* + * Make sure the job is in the active list... + */ + + if (!cupsArrayFind(ActiveJobs, job)) + cupsArrayAdd(ActiveJobs, job); + + /* + * Save the job state to disk... + */ + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + break; + + case IPP_JOB_ABORTED : + case IPP_JOB_CANCELED : + case IPP_JOB_COMPLETED : + if (newstate == IPP_JOB_CANCELED) + { + /* + * Remove the job from the active list if there are no processes still + * running for it... + */ + + for (i = 0; job->filters[i] < 0; i++); + + if (!job->filters[i] && job->backend <= 0) + cupsArrayRemove(ActiveJobs, job); + } + else + { + /* + * Otherwise just remove the job from the active list immediately... + */ + + cupsArrayRemove(ActiveJobs, job); + } + + /* + * Expire job subscriptions since the job is now "completed"... + */ + + cupsdExpireSubscriptions(NULL, job); + +#ifdef __APPLE__ + /* + * If we are going to sleep and the PrintingJobs count is now 0, allow the + * sleep to happen immediately... + */ + + if (Sleeping && cupsArrayCount(PrintingJobs) == 0) + cupsdAllowSleep(); +#endif /* __APPLE__ */ + + /* + * Remove any authentication data... + */ + + snprintf(filename, sizeof(filename), "%s/a%05d", RequestRoot, job->id); + if (cupsdRemoveFile(filename) && errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to remove authentication cache: %s", + strerror(errno)); + + cupsdClearString(&job->auth_username); + cupsdClearString(&job->auth_domain); + cupsdClearString(&job->auth_password); + +#ifdef HAVE_GSSAPI + /* + * Destroy the credential cache and clear the KRB5CCNAME env var string. + */ + + if (job->ccache) + { + krb5_cc_destroy(KerberosContext, job->ccache); + job->ccache = NULL; + } + + cupsdClearString(&job->ccname); +#endif /* HAVE_GSSAPI */ + + /* + * Remove the print file for good if we aren't preserving jobs or + * files... + */ + + if (!JobHistory || !JobFiles || action == CUPSD_JOB_PURGE) + { + for (i = 1; i <= job->num_files; i ++) + { + snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, + job->id, i); + unlink(filename); + } + + if (job->num_files > 0) + { + free(job->filetypes); + free(job->compressions); + + job->num_files = 0; + job->filetypes = NULL; + job->compressions = NULL; + } + } + + if (JobHistory && action != CUPSD_JOB_PURGE) + { + /* + * Save job state info... + */ + + job->dirty = 1; + cupsdMarkDirty(CUPSD_DIRTY_JOBS); + } + else if (!job->printer) + { + /* + * Delete the job immediately if not actively printing... + */ + + cupsdDeleteJob(job, CUPSD_JOB_PURGE); + job = NULL; + } + break; + } + + /* + * Finalize the job immediately if we forced things... + */ + + if (action >= CUPSD_JOB_FORCE && job && job->printer) + finalize_job(job, 0); + + /* + * Update the server "busy" state... + */ + + cupsdSetBusyState(); +} + + +/* + * 'cupsdStopAllJobs()' - Stop all print jobs. + */ + +void +cupsdStopAllJobs( + cupsd_jobaction_t action, /* I - Action */ + int kill_delay) /* I - Number of seconds before we kill */ +{ + cupsd_job_t *job; /* Current job */ + + + DEBUG_puts("cupsdStopAllJobs()"); + + for (job = (cupsd_job_t *)cupsArrayFirst(PrintingJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(PrintingJobs)) + { + if (kill_delay) + job->kill_time = time(NULL) + kill_delay; + + cupsdSetJobState(job, IPP_JOB_PENDING, action, NULL); + } +} + + +/* + * 'cupsdUnloadCompletedJobs()' - Flush completed job history from memory. + */ + +void +cupsdUnloadCompletedJobs(void) +{ + cupsd_job_t *job; /* Current job */ + time_t expire; /* Expiration time */ + + + expire = time(NULL) - 60; + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + if (job->attrs && job->state_value >= IPP_JOB_STOPPED && !job->printer && + job->access_time < expire) + { + if (job->dirty) + cupsdSaveJob(job); + + unload_job(job); + } +} + + +/* + * 'compare_active_jobs()' - Compare the job IDs and priorities of two jobs. + */ + +static int /* O - Difference */ +compare_active_jobs(void *first, /* I - First job */ + void *second, /* I - Second job */ + void *data) /* I - App data (not used) */ +{ + int diff; /* Difference */ + + + if ((diff = ((cupsd_job_t *)second)->priority - + ((cupsd_job_t *)first)->priority) != 0) + return (diff); + else + return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id); +} + + +/* + * 'compare_jobs()' - Compare the job IDs of two jobs. + */ + +static int /* O - Difference */ +compare_jobs(void *first, /* I - First job */ + void *second, /* I - Second job */ + void *data) /* I - App data (not used) */ +{ + return (((cupsd_job_t *)first)->id - ((cupsd_job_t *)second)->id); +} + + +/* + * 'dump_job_history()' - Dump any debug messages for a job. + */ + +static void +dump_job_history(cupsd_job_t *job) /* I - Job */ +{ + int i, /* Looping var */ + oldsize; /* Current MaxLogSize */ + struct tm *date; /* Date/time value */ + cupsd_joblog_t *message; /* Current message */ + char temp[2048], /* Log message */ + *ptr, /* Pointer into log message */ + start[256], /* Start time */ + end[256]; /* End time */ + cupsd_printer_t *printer; /* Printer for job */ + + + /* + * See if we have anything to dump... + */ + + if (!job->history) + return; + + /* + * Disable log rotation temporarily... + */ + + oldsize = MaxLogSize; + MaxLogSize = 0; + + /* + * Copy the debug messages to the log... + */ + + message = (cupsd_joblog_t *)cupsArrayFirst(job->history); + date = localtime(&(message->time)); + strftime(start, sizeof(start), "%X", date); + + message = (cupsd_joblog_t *)cupsArrayLast(job->history); + date = localtime(&(message->time)); + strftime(end, sizeof(end), "%X", date); + + snprintf(temp, sizeof(temp), + "[Job %d] The following messages were recorded from %s to %s", + job->id, start, end); + cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp); + + for (message = (cupsd_joblog_t *)cupsArrayFirst(job->history); + message; + message = (cupsd_joblog_t *)cupsArrayNext(job->history)) + cupsdWriteErrorLog(CUPSD_LOG_DEBUG, message->message); + + snprintf(temp, sizeof(temp), "[Job %d] End of messages", job->id); + cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp); + + /* + * Log the printer state values... + */ + + if ((printer = job->printer) == NULL) + printer = cupsdFindDest(job->dest); + + if (printer) + { + snprintf(temp, sizeof(temp), "[Job %d] printer-state=%d(%s)", job->id, + printer->state, + printer->state == IPP_PRINTER_IDLE ? "idle" : + printer->state == IPP_PRINTER_PROCESSING ? "processing" : + "stopped"); + cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp); + + snprintf(temp, sizeof(temp), "[Job %d] printer-state-message=\"%s\"", + job->id, printer->state_message); + cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp); + + snprintf(temp, sizeof(temp), "[Job %d] printer-state-reasons=", job->id); + ptr = temp + strlen(temp); + if (printer->num_reasons == 0) + strlcpy(ptr, "none", sizeof(temp) - (ptr - temp)); + else + { + for (i = 0; + i < printer->num_reasons && ptr < (temp + sizeof(temp) - 2); + i ++) + { + if (i) + *ptr++ = ','; + + strlcpy(ptr, printer->reasons[i], sizeof(temp) - (ptr - temp)); + ptr += strlen(ptr); + } + } + cupsdWriteErrorLog(CUPSD_LOG_DEBUG, temp); + } + + /* + * Restore log file rotation... + */ + + MaxLogSize = oldsize; + + /* + * Free all messages... + */ + + free_job_history(job); +} + + +/* + * 'free_job_history()' - Free any log history. + */ + +static void +free_job_history(cupsd_job_t *job) /* I - Job */ +{ + char *message; /* Current message */ + + + if (!job->history) + return; + + for (message = (char *)cupsArrayFirst(job->history); + message; + message = (char *)cupsArrayNext(job->history)) + free(message); + + cupsArrayDelete(job->history); + job->history = NULL; +} + + +/* + * 'finalize_job()' - Cleanup after job filter processes and support data. + */ + +static void +finalize_job(cupsd_job_t *job, /* I - Job */ + int set_job_state) /* I - 1 = set the job state */ +{ + ipp_pstate_t printer_state; /* New printer state value */ + ipp_jstate_t job_state; /* New job state value */ + const char *message; /* Message for job state */ + char buffer[1024]; /* Buffer for formatted messages */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "finalize_job(job=%p(%d))", job, job->id); + + /* + * Clear the "connecting-to-device" and "com.apple.print.recoverable-warning" + * reasons, which are only valid when a printer is processing... + */ + + cupsdSetPrinterReasons(job->printer, "-connecting-to-device"); + cupsdSetPrinterReasons(job->printer, "-com.apple.print.recoverable-warning"); + + /* + * Similarly, clear the "offline-report" reason for non-USB devices since we + * rarely have current information for network devices... + */ + + if (strncmp(job->printer->device_uri, "usb:", 4)) + cupsdSetPrinterReasons(job->printer, "-offline-report"); + + /* + * Free the security profile... + */ + + cupsdDestroyProfile(job->profile); + job->profile = NULL; + + /* + * Clear the unresponsive job watchdog timer... + */ + + job->kill_time = 0; + + /* + * Close pipes and status buffer... + */ + + cupsdClosePipe(job->print_pipes); + cupsdClosePipe(job->back_pipes); + cupsdClosePipe(job->side_pipes); + + cupsdRemoveSelect(job->status_pipes[0]); + cupsdClosePipe(job->status_pipes); + cupsdStatBufDelete(job->status_buffer); + job->status_buffer = NULL; + + /* + * Process the exit status... + */ + + if (job->printer->state == IPP_PRINTER_PROCESSING) + printer_state = IPP_PRINTER_IDLE; + else + printer_state = job->printer->state; + + switch (job_state = job->state_value) + { + case IPP_JOB_PENDING : + message = "Job paused."; + break; + + case IPP_JOB_HELD : + message = "Job held."; + break; + + default : + case IPP_JOB_PROCESSING : + case IPP_JOB_COMPLETED : + job_state = IPP_JOB_COMPLETED; + message = "Job completed."; + break; + + case IPP_JOB_STOPPED : + message = "Job stopped."; + break; + + case IPP_JOB_CANCELED : + message = "Job canceled."; + break; + + case IPP_JOB_ABORTED : + message = "Job aborted."; + break; + } + + if (job->status < 0) + { + /* + * Backend had errors... + */ + + int exit_code; /* Exit code from backend */ + + + /* + * Convert the status to an exit code. Due to the way the W* macros are + * implemented on MacOS X (bug?), we have to store the exit status in a + * variable first and then convert... + */ + + exit_code = -job->status; + if (WIFEXITED(exit_code)) + exit_code = WEXITSTATUS(exit_code); + else + exit_code = job->status; + + cupsdLogJob(job, CUPSD_LOG_INFO, "Backend returned status %d (%s)", + exit_code, + exit_code == CUPS_BACKEND_FAILED ? "failed" : + exit_code == CUPS_BACKEND_AUTH_REQUIRED ? + "authentication required" : + exit_code == CUPS_BACKEND_HOLD ? "hold job" : + exit_code == CUPS_BACKEND_STOP ? "stop printer" : + exit_code == CUPS_BACKEND_CANCEL ? "cancel job" : + exit_code < 0 ? "crashed" : "unknown"); + + /* + * Do what needs to be done... + */ + + switch (exit_code) + { + default : + case CUPS_BACKEND_FAILED : + /* + * Backend failure, use the error-policy to determine how to + * act... + */ + + if (job->dtype & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) + { + /* + * Queued on a class - mark the job as pending and we'll retry on + * another printer... + */ + + if (job_state == IPP_JOB_COMPLETED) + { + job_state = IPP_JOB_PENDING; + message = "Retrying job on another printer."; + } + } + else if (!strcmp(job->printer->error_policy, "retry-current-job")) + { + /* + * The error policy is "retry-current-job" - mark the job as pending + * and we'll retry on the same printer... + */ + + if (job_state == IPP_JOB_COMPLETED) + { + job_state = IPP_JOB_PENDING; + message = "Retrying job on same printer."; + } + } + else if ((job->printer->type & CUPS_PRINTER_FAX) || + !strcmp(job->printer->error_policy, "retry-job")) + { + if (job_state == IPP_JOB_COMPLETED) + { + /* + * The job was queued on a fax or the error policy is "retry-job" - + * hold the job if the number of retries is less than the + * JobRetryLimit, otherwise abort the job. + */ + + job->tries ++; + + if (job->tries > JobRetryLimit && JobRetryLimit > 0) + { + /* + * Too many tries... + */ + + snprintf(buffer, sizeof(buffer), + "Job aborted after %d unsuccessful attempts.", + JobRetryLimit); + job_state = IPP_JOB_ABORTED; + message = buffer; + } + else + { + /* + * Try again in N seconds... + */ + + snprintf(buffer, sizeof(buffer), + "Job held for %d seconds since it could not be sent.", + JobRetryInterval); + + job->hold_until = time(NULL) + JobRetryInterval; + job_state = IPP_JOB_HELD; + message = buffer; + } + } + } + else if (!strcmp(job->printer->error_policy, "abort-job") && + job_state == IPP_JOB_COMPLETED) + { + job_state = IPP_JOB_ABORTED; + message = "Job aborted due to backend errors; please consult " + "the error_log file for details."; + } + else if (job->state_value == IPP_JOB_PROCESSING) + { + job_state = IPP_JOB_PENDING; + printer_state = IPP_PRINTER_STOPPED; + message = "Printer stopped due to backend errors; please " + "consult the error_log file for details."; + } + break; + + case CUPS_BACKEND_CANCEL : + /* + * Abort the job... + */ + + if (job_state == IPP_JOB_COMPLETED) + { + job_state = IPP_JOB_ABORTED; + message = "Job aborted due to backend errors; please consult " + "the error_log file for details."; + } + break; + + case CUPS_BACKEND_HOLD : + if (job_state == IPP_JOB_COMPLETED) + { + /* + * Hold the job... + */ + + cupsdSetJobHoldUntil(job, "indefinite", 1); + + job_state = IPP_JOB_HELD; + message = "Job held indefinitely due to backend errors; please " + "consult the error_log file for details."; + } + break; + + case CUPS_BACKEND_STOP : + /* + * Stop the printer... + */ + + printer_state = IPP_PRINTER_STOPPED; + message = "Printer stopped due to backend errors; please " + "consult the error_log file for details."; + + if (job_state == IPP_JOB_COMPLETED) + job_state = IPP_JOB_PENDING; + break; + + case CUPS_BACKEND_AUTH_REQUIRED : + /* + * Hold the job for authentication... + */ + + if (job_state == IPP_JOB_COMPLETED) + { + cupsdSetJobHoldUntil(job, "auth-info-required", 1); + + job_state = IPP_JOB_HELD; + message = "Job held for authentication."; + } + break; + } + } + else if (job->status > 0) + { + /* + * Filter had errors; stop job... + */ + + if (job_state == IPP_JOB_COMPLETED) + { + job_state = IPP_JOB_STOPPED; + message = "Job stopped due to filter errors; please consult the " + "error_log file for details."; + } + } + + /* + * Update the printer and job state. + */ + + if (job_state != job->state_value) + cupsdSetJobState(job, job_state, CUPSD_JOB_DEFAULT, "%s", message); + + cupsdSetPrinterState(job->printer, printer_state, + printer_state == IPP_PRINTER_STOPPED); + update_job_attrs(job, 0); + + if (job->history) + { + if (job->status) + dump_job_history(job); + else + free_job_history(job); + } + + cupsArrayRemove(PrintingJobs, job); + + /* + * Clear the printer <-> job association... + */ + + job->printer->job = NULL; + job->printer = NULL; + + /* + * Try printing another job... + */ + + if (printer_state != IPP_PRINTER_STOPPED) + cupsdCheckJobs(); +} + + +/* + * 'get_options()' - Get a string containing the job options. + */ + +static char * /* O - Options string */ +get_options(cupsd_job_t *job, /* I - Job */ + int banner_page, /* I - Printing a banner page? */ + char *copies, /* I - Copies buffer */ + size_t copies_size, /* I - Size of copies buffer */ + char *title, /* I - Title buffer */ + size_t title_size) /* I - Size of title buffer */ +{ + int i; /* Looping var */ + size_t newlength; /* New option buffer length */ + char *optptr, /* Pointer to options */ + *valptr; /* Pointer in value string */ + ipp_attribute_t *attr; /* Current attribute */ + _pwg_t *pwg; /* PWG->PPD mapping data */ + int num_pwgppds; /* Number of PWG->PPD options */ + cups_option_t *pwgppds, /* PWG->PPD options */ + *pwgppd, /* Current PWG->PPD option */ + *preset; /* Current preset option */ + int output_mode, /* Output mode (if any) */ + print_quality; /* Print quality (if any) */ + const char *ppd; /* PPD option choice */ + int exact; /* Did we get an exact match? */ + static char *options = NULL;/* Full list of options */ + static size_t optlength = 0; /* Length of option buffer */ + + + /* + * 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... :) + * + * First build an options array for any PWG->PPD mapped option/choice pairs. + */ + + pwg = job->printer->pwg; + num_pwgppds = 0; + pwgppds = NULL; + + if (pwg && + !ippFindAttribute(job->attrs, + "com.apple.print.DocumentTicket.PMSpoolFormat", + IPP_TAG_ZERO) && + !ippFindAttribute(job->attrs, "APPrinterPreset", IPP_TAG_ZERO) && + (ippFindAttribute(job->attrs, "output-mode", IPP_TAG_ZERO) || + ippFindAttribute(job->attrs, "print-quality", IPP_TAG_ZERO))) + { + /* + * Map output-mode and print-quality to a preset... + */ + + if ((attr = ippFindAttribute(job->attrs, "output-mode", + IPP_TAG_KEYWORD)) != NULL && + !strcmp(attr->values[0].string.text, "monochrome")) + output_mode = _PWG_OUTPUT_MODE_MONOCHROME; + else + output_mode = _PWG_OUTPUT_MODE_COLOR; + + if ((attr = ippFindAttribute(job->attrs, "print-quality", + IPP_TAG_ENUM)) != NULL && + attr->values[0].integer >= IPP_QUALITY_DRAFT && + attr->values[0].integer <= IPP_QUALITY_HIGH) + print_quality = attr->values[0].integer - IPP_QUALITY_DRAFT; + else + print_quality = _PWG_PRINT_QUALITY_NORMAL; + + if (pwg->num_presets[output_mode][print_quality] == 0) + { + /* + * Try to find a preset that works so that we maximize the chances of us + * getting a good print using IPP attributes. + */ + + if (pwg->num_presets[output_mode][_PWG_PRINT_QUALITY_NORMAL] > 0) + print_quality = _PWG_PRINT_QUALITY_NORMAL; + else if (pwg->num_presets[_PWG_OUTPUT_MODE_COLOR][print_quality] > 0) + output_mode = _PWG_OUTPUT_MODE_COLOR; + else + { + print_quality = _PWG_PRINT_QUALITY_NORMAL; + output_mode = _PWG_OUTPUT_MODE_COLOR; + } + } + + if (pwg->num_presets[output_mode][print_quality] > 0) + { + /* + * Copy the preset options as long as the corresponding names are not + * already defined in the IPP request... + */ + + for (i = pwg->num_presets[output_mode][print_quality], + preset = pwg->presets[output_mode][print_quality]; + i > 0; + i --, preset ++) + { + if (!ippFindAttribute(job->attrs, preset->name, IPP_TAG_ZERO)) + num_pwgppds = cupsAddOption(preset->name, preset->value, num_pwgppds, + &pwgppds); + } + } + } + + if (pwg) + { + if (!ippFindAttribute(job->attrs, "InputSlot", IPP_TAG_ZERO) && + !ippFindAttribute(job->attrs, "HPPaperSource", IPP_TAG_ZERO)) + { + if ((ppd = _pwgGetInputSlot(pwg, job->attrs, NULL)) != NULL) + num_pwgppds = cupsAddOption(pwg->source_option, ppd, num_pwgppds, + &pwgppds); + else if (!ippFindAttribute(job->attrs, "AP_D_InputSlot", IPP_TAG_ZERO)) + num_pwgppds = cupsAddOption("AP_D_InputSlot", "", num_pwgppds, + &pwgppds); + } + + if (!ippFindAttribute(job->attrs, "MediaType", IPP_TAG_ZERO) && + (ppd = _pwgGetMediaType(pwg, job->attrs, NULL)) != NULL) + num_pwgppds = cupsAddOption("MediaType", ppd, num_pwgppds, &pwgppds); + + if (!ippFindAttribute(job->attrs, "PageRegion", IPP_TAG_ZERO) && + !ippFindAttribute(job->attrs, "PageSize", IPP_TAG_ZERO) && + (ppd = _pwgGetPageSize(pwg, job->attrs, NULL, &exact)) != NULL) + { + num_pwgppds = cupsAddOption("PageSize", ppd, num_pwgppds, &pwgppds); + + if (!ippFindAttribute(job->attrs, "media", IPP_TAG_ZERO)) + num_pwgppds = cupsAddOption("media", ppd, num_pwgppds, &pwgppds); + } + + if (!ippFindAttribute(job->attrs, "OutputBin", IPP_TAG_ZERO) && + (attr = ippFindAttribute(job->attrs, "output-bin", + IPP_TAG_ZERO)) != NULL && + (attr->value_tag == IPP_TAG_KEYWORD || + attr->value_tag == IPP_TAG_NAME) && + (ppd = _pwgGetOutputBin(pwg, attr->values[0].string.text)) != NULL) + { + /* + * Map output-bin to OutputBin option... + */ + + num_pwgppds = cupsAddOption("OutputBin", ppd, num_pwgppds, &pwgppds); + } + + if (pwg->sides_option && + !ippFindAttribute(job->attrs, pwg->sides_option, IPP_TAG_ZERO) && + (attr = ippFindAttribute(job->attrs, "sides", IPP_TAG_KEYWORD)) != NULL) + { + /* + * Map sides to duplex option... + */ + + if (!strcmp(attr->values[0].string.text, "one-sided")) + num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_1sided, + num_pwgppds, &pwgppds); + else if (!strcmp(attr->values[0].string.text, "two-sided-long-edge")) + num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_long, + num_pwgppds, &pwgppds); + else if (!strcmp(attr->values[0].string.text, "two-sided-short-edge")) + num_pwgppds = cupsAddOption(pwg->sides_option, pwg->sides_2sided_short, + num_pwgppds, &pwgppds); + } + } + + /* + * Figure out how much room we need... + */ + + newlength = ipp_length(job->attrs); + + for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++) + newlength += 1 + strlen(pwgppd->name) + 1 + strlen(pwgppd->value); + + /* + * Then allocate/reallocate the option buffer as needed... + */ + + if (newlength > optlength || !options) + { + if (!options) + optptr = malloc(newlength); + else + optptr = realloc(options, newlength); + + if (!optptr) + { + cupsdLogJob(job, CUPSD_LOG_CRIT, + "Unable to allocate " CUPS_LLFMT " bytes for option buffer!", + CUPS_LLCAST newlength); + return (NULL); + } + + options = optptr; + optlength = newlength; + } + + /* + * Now loop through the attributes and convert them to the textual + * representation used by the filters... + */ + + optptr = options; + *optptr = '\0'; + + snprintf(title, title_size, "%s-%d", job->printer->name, job->id); + strlcpy(copies, "1", copies_size); + + for (attr = job->attrs->attrs; attr != NULL; attr = attr->next) + { + if (!strcmp(attr->name, "copies") && + attr->value_tag == IPP_TAG_INTEGER) + { + /* + * Don't use the # copies attribute if we are printing the job sheets... + */ + + if (!banner_page) + snprintf(copies, copies_size, "%d", attr->values[0].integer); + } + else if (!strcmp(attr->name, "job-name") && + (attr->value_tag == IPP_TAG_NAME || + attr->value_tag == IPP_TAG_NAMELANG)) + strlcpy(title, attr->values[0].string.text, title_size); + else if (attr->group_tag == IPP_TAG_JOB) + { + /* + * Filter out other unwanted attributes... + */ + + if (attr->value_tag == IPP_TAG_NOVALUE || + attr->value_tag == IPP_TAG_MIMETYPE || + attr->value_tag == IPP_TAG_NAMELANG || + attr->value_tag == IPP_TAG_TEXTLANG || + (attr->value_tag == IPP_TAG_URI && strcmp(attr->name, "job-uuid")) || + attr->value_tag == IPP_TAG_URISCHEME || + attr->value_tag == IPP_TAG_BEGIN_COLLECTION) /* Not yet supported */ + continue; + + if (!strcmp(attr->name, "job-hold-until")) + continue; + + if (!strncmp(attr->name, "job-", 4) && + strcmp(attr->name, "job-billing") && + strcmp(attr->name, "job-impressions") && + strcmp(attr->name, "job-originating-host-name") && + strcmp(attr->name, "job-uuid") && + !(job->printer->type & CUPS_PRINTER_REMOTE)) + continue; + + if ((!strcmp(attr->name, "job-impressions") || + !strcmp(attr->name, "page-label") || + !strcmp(attr->name, "page-border") || + !strncmp(attr->name, "number-up", 9) || + !strcmp(attr->name, "page-ranges") || + !strcmp(attr->name, "page-set") || + !strcasecmp(attr->name, "AP_FIRSTPAGE_InputSlot") || + !strcasecmp(attr->name, "AP_FIRSTPAGE_ManualFeed") || + !strcasecmp(attr->name, "com.apple.print.PrintSettings." + "PMTotalSidesImaged..n.") || + !strcasecmp(attr->name, "com.apple.print.PrintSettings." + "PMTotalBeginPages..n.")) && + banner_page) + continue; + + /* + * Otherwise add them to the list... + */ + + if (optptr > options) + strlcat(optptr, " ", optlength - (optptr - options)); + + if (attr->value_tag != IPP_TAG_BOOLEAN) + { + strlcat(optptr, attr->name, optlength - (optptr - options)); + strlcat(optptr, "=", optlength - (optptr - options)); + } + + for (i = 0; i < attr->num_values; i ++) + { + if (i) + strlcat(optptr, ",", optlength - (optptr - options)); + + optptr += strlen(optptr); + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + snprintf(optptr, optlength - (optptr - options), + "%d", attr->values[i].integer); + break; + + case IPP_TAG_BOOLEAN : + if (!attr->values[i].boolean) + strlcat(optptr, "no", optlength - (optptr - options)); + + strlcat(optptr, attr->name, + optlength - (optptr - options)); + break; + + case IPP_TAG_RANGE : + if (attr->values[i].range.lower == attr->values[i].range.upper) + snprintf(optptr, optlength - (optptr - options) - 1, + "%d", attr->values[i].range.lower); + else + snprintf(optptr, optlength - (optptr - options) - 1, + "%d-%d", attr->values[i].range.lower, + attr->values[i].range.upper); + break; + + case IPP_TAG_RESOLUTION : + snprintf(optptr, optlength - (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 : + case IPP_TAG_URI : + for (valptr = attr->values[i].string.text; *valptr;) + { + if (strchr(" \t\n\\\'\"", *valptr)) + *optptr++ = '\\'; + *optptr++ = *valptr++; + } + + *optptr = '\0'; + break; + + default : + break; /* anti-compiler-warning-code */ + } + } + + optptr += strlen(optptr); + } + } + + /* + * Finally loop through the PWG->PPD mapped options and add them... + */ + + for (i = num_pwgppds, pwgppd = pwgppds; i > 0; i --, pwgppd ++) + { + *optptr++ = ' '; + strcpy(optptr, pwgppd->name); + optptr += strlen(optptr); + *optptr++ = '='; + strcpy(optptr, pwgppd->value); + optptr += strlen(optptr); + } + + cupsFreeOptions(num_pwgppds, pwgppds); + + /* + * Return the options string... + */ + + return (options); +} + + +/* + * 'ipp_length()' - Compute the size of the buffer needed to hold + * the textual IPP attributes. + */ + +static size_t /* O - Size of attribute buffer */ +ipp_length(ipp_t *ipp) /* I - IPP request */ +{ + size_t bytes; /* Number of bytes */ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Current attribute */ + + + /* + * Loop through all attributes... + */ + + bytes = 0; + + for (attr = ipp->attrs; attr != NULL; attr = attr->next) + { + /* + * Skip attributes that won't be sent to filters... + */ + + if (attr->value_tag == IPP_TAG_NOVALUE || + 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; + + /* + * Add space for a leading space and commas between each value. + * For the first attribute, the leading space isn't used, so the + * extra byte can be used as the nul terminator... + */ + + bytes ++; /* " " separator */ + bytes += attr->num_values; /* "," separators */ + + /* + * Boolean attributes appear as "foo,nofoo,foo,nofoo", while + * other attributes appear as "foo=value1,value2,...,valueN". + */ + + if (attr->value_tag != IPP_TAG_BOOLEAN) + bytes += strlen(attr->name); + else + bytes += attr->num_values * strlen(attr->name); + + /* + * Now add the size required for each value in the attribute... + */ + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + /* + * Minimum value of a signed integer is -2147483647, or 11 digits. + */ + + bytes += attr->num_values * 11; + break; + + case IPP_TAG_BOOLEAN : + /* + * Add two bytes for each false ("no") value... + */ + + for (i = 0; i < attr->num_values; i ++) + if (!attr->values[i].boolean) + bytes += 2; + break; + + case IPP_TAG_RANGE : + /* + * A range is two signed integers separated by a hyphen, or + * 23 characters max. + */ + + bytes += attr->num_values * 23; + break; + + case IPP_TAG_RESOLUTION : + /* + * A resolution is two signed integers separated by an "x" and + * suffixed by the units, or 26 characters max. + */ + + bytes += attr->num_values * 26; + 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 : + case IPP_TAG_URI : + /* + * Strings can contain characters that need quoting. We need + * at least 2 * len + 2 characters to cover the quotes and + * any backslashes in the string. + */ + + for (i = 0; i < attr->num_values; i ++) + bytes += 2 * strlen(attr->values[i].string.text) + 2; + break; + + default : + break; /* anti-compiler-warning-code */ + } + } + + return (bytes); +} + + +/* + * 'load_job_cache()' - Load jobs from the job.cache file. + */ + +static void +load_job_cache(const char *filename) /* I - job.cache filename */ +{ + cups_file_t *fp; /* job.cache file */ + char line[1024], /* Line buffer */ + *value; /* Value on line */ + int linenum; /* Line number in file */ + cupsd_job_t *job; /* Current job */ + int jobid; /* Job ID */ + char jobfile[1024]; /* Job filename */ + + + /* + * Open the job.cache file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open job cache file \"%s\": %s", + filename, strerror(errno)); + + load_request_root(); + + return; + } + + /* + * Read entries from the job cache file and create jobs as needed. + */ + + cupsdLogMessage(CUPSD_LOG_INFO, "Loading job cache file \"%s\"...", + filename); + + linenum = 0; + job = NULL; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!strcasecmp(line, "NextJobId")) + { + if (value) + NextJobId = atoi(value); + } + else if (!strcasecmp(line, " directive on line %d!", + linenum); + continue; + } + + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Missing job ID on line %d!", linenum); + continue; + } + + jobid = atoi(value); + + if (jobid < 1) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad job ID %d on line %d!", jobid, + linenum); + continue; + } + + snprintf(jobfile, sizeof(jobfile), "%s/c%05d", RequestRoot, jobid); + if (access(jobfile, 0)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "[Job %d] Files have gone away!", + jobid); + continue; + } + + job = calloc(1, sizeof(cupsd_job_t)); + if (!job) + { + cupsdLogMessage(CUPSD_LOG_EMERG, + "[Job %d] Unable to allocate memory for job!", jobid); + break; + } + + job->id = jobid; + job->back_pipes[0] = -1; + job->back_pipes[1] = -1; + job->print_pipes[0] = -1; + job->print_pipes[1] = -1; + job->side_pipes[0] = -1; + job->side_pipes[1] = -1; + job->status_pipes[0] = -1; + job->status_pipes[1] = -1; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Loading from cache...", + job->id); + } + else if (!job) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Missing directive on line %d!", linenum); + continue; + } + else if (!strcasecmp(line, "")) + { + cupsArrayAdd(Jobs, job); + + if (job->state_value <= IPP_JOB_STOPPED && cupsdLoadJob(job)) + cupsArrayAdd(ActiveJobs, job); + + job = NULL; + } + else if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value on line %d!", linenum); + continue; + } + else if (!strcasecmp(line, "State")) + { + job->state_value = (ipp_jstate_t)atoi(value); + + if (job->state_value < IPP_JOB_PENDING) + job->state_value = IPP_JOB_PENDING; + else if (job->state_value > IPP_JOB_COMPLETED) + job->state_value = IPP_JOB_COMPLETED; + } + else if (!strcasecmp(line, "HoldUntil")) + { + job->hold_until = atoi(value); + } + else if (!strcasecmp(line, "Priority")) + { + job->priority = atoi(value); + } + else if (!strcasecmp(line, "Username")) + { + cupsdSetString(&job->username, value); + } + else if (!strcasecmp(line, "Destination")) + { + cupsdSetString(&job->dest, value); + } + else if (!strcasecmp(line, "DestType")) + { + job->dtype = (cups_ptype_t)atoi(value); + } + else if (!strcasecmp(line, "NumFiles")) + { + job->num_files = atoi(value); + + if (job->num_files < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad NumFiles value %d on line %d!", + job->num_files, linenum); + job->num_files = 0; + continue; + } + + if (job->num_files > 0) + { + snprintf(jobfile, sizeof(jobfile), "%s/d%05d-001", RequestRoot, + job->id); + if (access(jobfile, 0)) + { + cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Data files have gone away!", + job->id); + job->num_files = 0; + continue; + } + + job->filetypes = calloc(job->num_files, sizeof(mime_type_t *)); + job->compressions = calloc(job->num_files, sizeof(int)); + + if (!job->filetypes || !job->compressions) + { + cupsdLogMessage(CUPSD_LOG_EMERG, + "[Job %d] Unable to allocate memory for %d files!", + job->id, job->num_files); + break; + } + } + } + else if (!strcasecmp(line, "File")) + { + int number, /* File number */ + compression; /* Compression value */ + char super[MIME_MAX_SUPER], /* MIME super type */ + type[MIME_MAX_TYPE]; /* MIME type */ + + + if (sscanf(value, "%d%*[ \t]%15[^/]/%255s%d", &number, super, type, + &compression) != 4) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File on line %d!", linenum); + continue; + } + + if (number < 1 || number > job->num_files) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Bad File number %d on line %d!", + number, linenum); + continue; + } + + number --; + + job->compressions[number] = compression; + job->filetypes[number] = mimeType(MimeDatabase, super, type); + + if (!job->filetypes[number]) + { + /* + * If the original MIME type is unknown, auto-type it! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "[Job %d] Unknown MIME type %s/%s for file %d!", + job->id, super, type, number + 1); + + snprintf(jobfile, sizeof(jobfile), "%s/d%05d-%03d", RequestRoot, + job->id, number + 1); + job->filetypes[number] = mimeFileType(MimeDatabase, jobfile, NULL, + job->compressions + number); + + /* + * If that didn't work, assume it is raw... + */ + + if (!job->filetypes[number]) + job->filetypes[number] = mimeType(MimeDatabase, "application", + "vnd.cups-raw"); + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown %s directive on line %d!", + line, linenum); + } + + cupsFileClose(fp); +} + + +/* + * 'load_next_job_id()' - Load the NextJobId value from the job.cache file. + */ + +static void +load_next_job_id(const char *filename) /* I - job.cache filename */ +{ + cups_file_t *fp; /* job.cache file */ + char line[1024], /* Line buffer */ + *value; /* Value on line */ + int linenum; /* Line number in file */ + int next_job_id; /* NextJobId value from line */ + + + /* + * Read the NextJobId directive from the job.cache file and use + * the value (if any). + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open job cache file \"%s\": %s", + filename, strerror(errno)); + + return; + } + + cupsdLogMessage(CUPSD_LOG_INFO, + "Loading NextJobId from job cache file \"%s\"...", filename); + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!strcasecmp(line, "NextJobId")) + { + if (value) + { + next_job_id = atoi(value); + + if (next_job_id > NextJobId) + NextJobId = next_job_id; + } + break; + } + } + + cupsFileClose(fp); +} + + +/* + * 'load_request_root()' - Load jobs from the RequestRoot directory. + */ + +static void +load_request_root(void) +{ + cups_dir_t *dir; /* Directory */ + cups_dentry_t *dent; /* Directory entry */ + cupsd_job_t *job; /* New job */ + + + /* + * Open the requests directory... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Scanning %s for jobs...", RequestRoot); + + if ((dir = cupsDirOpen(RequestRoot)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open spool directory \"%s\": %s", + RequestRoot, strerror(errno)); + return; + } + + /* + * Read all the c##### files... + */ + + while ((dent = cupsDirRead(dir)) != NULL) + if (strlen(dent->filename) >= 6 && dent->filename[0] == 'c') + { + /* + * Allocate memory for the job... + */ + + if ((job = calloc(sizeof(cupsd_job_t), 1)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Ran out of memory for jobs!"); + cupsDirClose(dir); + return; + } + + /* + * Assign the job ID... + */ + + job->id = atoi(dent->filename + 1); + job->back_pipes[0] = -1; + job->back_pipes[1] = -1; + job->print_pipes[0] = -1; + job->print_pipes[1] = -1; + job->side_pipes[0] = -1; + job->side_pipes[1] = -1; + job->status_pipes[0] = -1; + job->status_pipes[1] = -1; + + if (job->id >= NextJobId) + NextJobId = job->id + 1; + + /* + * Load the job... + */ + + if (cupsdLoadJob(job)) + { + /* + * Insert the job into the array, sorting by job priority and ID... + */ + + cupsArrayAdd(Jobs, job); + + if (job->state_value <= IPP_JOB_STOPPED) + cupsArrayAdd(ActiveJobs, job); + else + unload_job(job); + } + } + + cupsDirClose(dir); +} + + +/* + * 'set_time()' - Set one of the "time-at-xyz" attributes. + */ + +static void +set_time(cupsd_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_job()' - Start a print job. + */ + +static void +start_job(cupsd_job_t *job, /* I - Job ID */ + cupsd_printer_t *printer) /* I - Printer to print job */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "start_job(job=%p(%d), printer=%p(%s))", + job, job->id, printer, printer->name); + + /* + * Make sure we have some files around before we try to print... + */ + + if (job->num_files == 0) + { + cupsdSetJobState(job, IPP_JOB_ABORTED, CUPSD_JOB_DEFAULT, + "Aborting job because it has no files."); + return; + } + + /* + * Update the printer and job state to "processing"... + */ + + if (!cupsdLoadJob(job)) + return; + + cupsdSetJobState(job, IPP_JOB_PROCESSING, CUPSD_JOB_DEFAULT, NULL); + cupsdSetPrinterState(printer, IPP_PRINTER_PROCESSING, 0); + + job->cost = 0; + job->current_file = 0; + job->progress = 0; + job->printer = printer; + printer->job = job; + + /* + * Setup the last exit status and security profiles... + */ + + job->status = 0; + job->profile = cupsdCreateProfile(job->id); + + /* + * Create the status pipes and buffer... + */ + + if (cupsdOpenPipe(job->status_pipes)) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Unable to create job status pipes - %s.", strerror(errno)); + + cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT, + "Job stopped because the scheduler could not create the " + "job status pipes."); + + cupsdDestroyProfile(job->profile); + job->profile = NULL; + return; + } + + job->status_buffer = cupsdStatBufNew(job->status_pipes[0], NULL); + job->status_level = CUPSD_LOG_INFO; + + if (job->printer_message) + cupsdSetString(&(job->printer_message->values[0].string.text), ""); + + /* + * Create the backchannel pipes and make them non-blocking... + */ + + if (cupsdOpenPipe(job->back_pipes)) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Unable to create back-channel pipes - %s.", strerror(errno)); + + cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT, + "Job stopped because the scheduler could not create the " + "back-channel pipes."); + + cupsdClosePipe(job->status_pipes); + cupsdStatBufDelete(job->status_buffer); + job->status_buffer = NULL; + + cupsdDestroyProfile(job->profile); + job->profile = NULL; + return; + } + + fcntl(job->back_pipes[0], F_SETFL, + fcntl(job->back_pipes[0], F_GETFL) | O_NONBLOCK); + fcntl(job->back_pipes[1], F_SETFL, + fcntl(job->back_pipes[1], F_GETFL) | O_NONBLOCK); + + /* + * Create the side-channel pipes and make them non-blocking... + */ + + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, job->side_pipes)) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Unable to create side-channel pipes - %s.", strerror(errno)); + + cupsdSetJobState(job, IPP_JOB_STOPPED, CUPSD_JOB_DEFAULT, + "Job stopped because the scheduler could not create the " + "side-channel pipes."); + + cupsdClosePipe(job->back_pipes); + + cupsdClosePipe(job->status_pipes); + cupsdStatBufDelete(job->status_buffer); + job->status_buffer = NULL; + + cupsdDestroyProfile(job->profile); + job->profile = NULL; + return; + } + + fcntl(job->side_pipes[0], F_SETFL, + fcntl(job->side_pipes[0], F_GETFL) | O_NONBLOCK); + fcntl(job->side_pipes[1], F_SETFL, + fcntl(job->side_pipes[1], F_GETFL) | O_NONBLOCK); + + fcntl(job->side_pipes[0], F_SETFD, + fcntl(job->side_pipes[0], F_GETFD) | FD_CLOEXEC); + fcntl(job->side_pipes[1], F_SETFD, + fcntl(job->side_pipes[1], F_GETFD) | FD_CLOEXEC); + + /* + * Now start the first file in the job... + */ + + cupsdContinueJob(job); +} + + +/* + * 'stop_job()' - Stop a print job. + */ + +static void +stop_job(cupsd_job_t *job, /* I - Job */ + cupsd_jobaction_t action) /* I - Action */ +{ + int i; /* Looping var */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "stop_job(job=%p(%d), action=%d)", job, + job->id, action); + + FilterLevel -= job->cost; + job->cost = 0; + + if (action == CUPSD_JOB_DEFAULT && !job->kill_time) + job->kill_time = time(NULL) + JobKillDelay; + else if (action >= CUPSD_JOB_FORCE) + job->kill_time = 0; + + for (i = 0; job->filters[i]; i ++) + if (job->filters[i] > 0) + { + cupsdEndProcess(job->filters[i], action >= CUPSD_JOB_FORCE); + + if (action >= CUPSD_JOB_FORCE) + job->filters[i] = -job->filters[i]; + } + + if (job->backend > 0) + { + cupsdEndProcess(job->backend, action >= CUPSD_JOB_FORCE); + + if (action >= CUPSD_JOB_FORCE) + job->backend = -job->backend; + } + + if (action >= CUPSD_JOB_FORCE) + { + /* + * Clear job status... + */ + + job->status = 0; + } +} + + +/* + * 'unload_job()' - Unload a job from memory. + */ + +static void +unload_job(cupsd_job_t *job) /* I - Job */ +{ + if (!job->attrs) + return; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "[Job %d] Unloading...", job->id); + + ippDelete(job->attrs); + + job->attrs = NULL; + job->state = NULL; + job->sheets = NULL; + job->job_sheets = NULL; + job->printer_message = NULL; + job->printer_reasons = NULL; +} + + +/* + * 'update_job()' - Read a status update from a job's filters. + */ + +void +update_job(cupsd_job_t *job) /* I - Job to check */ +{ + int i; /* Looping var */ + int copies; /* Number of copies printed */ + char message[CUPSD_SB_BUFFER_SIZE], + /* Message text */ + *ptr; /* Pointer update... */ + int loglevel, /* Log level for message */ + event = 0; /* Events? */ + static const char * const levels[] = /* Log levels */ + { + "NONE", + "EMERG", + "ALERT", + "CRIT", + "ERROR", + "WARN", + "NOTICE", + "INFO", + "DEBUG", + "DEBUG2" + }; + + + /* + * Get the printer associated with this job; if the printer is stopped for + * any reason then job->printer will be reset to NULL, so make sure we have + * a valid pointer... + */ + + while ((ptr = cupsdStatBufUpdate(job->status_buffer, &loglevel, + message, sizeof(message))) != NULL) + { + /* + * Process page and printer state messages as needed... + */ + + if (loglevel == CUPSD_LOG_PAGE) + { + /* + * Page message; send the message to the page_log file and update the + * job sheet count... + */ + + cupsdLogJob(job, CUPSD_LOG_DEBUG, "PAGE: %s", message); + + if (job->sheets) + { + if (!strncasecmp(message, "total ", 6)) + { + /* + * Got a total count of pages from a backend or filter... + */ + + copies = atoi(message + 6); + copies -= job->sheets->values[0].integer; /* Just track the delta */ + } + else if (!sscanf(message, "%*d%d", &copies)) + copies = 1; + + job->sheets->values[0].integer += copies; + + if (job->printer->page_limit) + { + cupsd_quota_t *q = cupsdUpdateQuota(job->printer, job->username, + copies, 0); + +#ifdef __APPLE__ + if (AppleQuotas && q->page_count == -3) + { + /* + * Quota limit exceeded, cancel job in progress immediately... + */ + + cupsdSetJobState(job, IPP_JOB_CANCELED, CUPSD_JOB_DEFAULT, + "Canceled job because pages exceed user %s " + "quota limit on printer %s (%s).", + job->username, job->printer->name, + job->printer->info); + return; + } +#else + (void)q; +#endif /* __APPLE__ */ + } + } + + cupsdLogPage(job, message); + + if (job->sheets) + cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, + "Printed %d page(s).", job->sheets->values[0].integer); + } + else if (loglevel == CUPSD_LOG_STATE) + { + cupsdLogJob(job, CUPSD_LOG_DEBUG, "STATE: %s", message); + + if (!strcmp(message, "paused")) + { + cupsdStopPrinter(job->printer, 1); + return; + } + else if (cupsdSetPrinterReasons(job->printer, message)) + { + cupsdAddPrinterHistory(job->printer); + event |= CUPSD_EVENT_PRINTER_STATE; + } + + update_job_attrs(job, 0); + } + else if (loglevel == CUPSD_LOG_ATTR) + { + /* + * Set attribute(s)... + */ + + int num_attrs; /* Number of attributes */ + cups_option_t *attrs; /* Attributes */ + const char *attr; /* Attribute */ + + + cupsdLogJob(job, CUPSD_LOG_DEBUG, "ATTR: %s", message); + + num_attrs = cupsParseOptions(message, 0, &attrs); + + if ((attr = cupsGetOption("auth-info-required", num_attrs, + attrs)) != NULL) + { + cupsdSetAuthInfoRequired(job->printer, attr, NULL); + cupsdSetPrinterAttrs(job->printer); + + if (job->printer->type & CUPS_PRINTER_DISCOVERED) + cupsdMarkDirty(CUPSD_DIRTY_REMOTE); + else + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("job-media-progress", num_attrs, + attrs)) != NULL) + { + int progress = atoi(attr); + + + if (progress >= 0 && progress <= 100) + { + job->progress = progress; + + if (job->sheets) + cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, + "Printing page %d, %d%%", + job->sheets->values[0].integer, job->progress); + } + } + + if ((attr = cupsGetOption("printer-alert", num_attrs, attrs)) != NULL) + { + cupsdSetString(&job->printer->alert, attr); + event |= CUPSD_EVENT_PRINTER_STATE; + } + + if ((attr = cupsGetOption("printer-alert-description", num_attrs, + attrs)) != NULL) + { + cupsdSetString(&job->printer->alert_description, attr); + event |= CUPSD_EVENT_PRINTER_STATE; + } + + if ((attr = cupsGetOption("marker-colors", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-colors", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-levels", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-levels", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-low-levels", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-low-levels", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-high-levels", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-high-levels", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-message", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-message", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-names", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-names", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + if ((attr = cupsGetOption("marker-types", num_attrs, attrs)) != NULL) + { + cupsdSetPrinterAttr(job->printer, "marker-types", (char *)attr); + job->printer->marker_time = time(NULL); + event |= CUPSD_EVENT_PRINTER_STATE; + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + } + + cupsFreeOptions(num_attrs, attrs); + } + else if (loglevel == CUPSD_LOG_PPD) + { + /* + * Set attribute(s)... + */ + + int num_keywords; /* Number of keywords */ + cups_option_t *keywords; /* Keywords */ + + + cupsdLogJob(job, CUPSD_LOG_DEBUG, "PPD: %s", message); + + num_keywords = cupsParseOptions(message, 0, &keywords); + + if (cupsdUpdatePrinterPPD(job->printer, num_keywords, keywords)) + cupsdSetPrinterAttrs(job->printer); + + cupsFreeOptions(num_keywords, keywords); + } + else if (!strncmp(message, "recoverable:", 12)) + { + ptr = message + 12; + while (isspace(*ptr & 255)) + ptr ++; + + if (*ptr) + { + if (cupsdSetPrinterReasons(job->printer, + "+com.apple.print.recoverable-warning") || + !job->printer->recoverable || + strcmp(job->printer->recoverable, ptr)) + { + cupsdSetString(&(job->printer->recoverable), ptr); + cupsdAddPrinterHistory(job->printer); + event |= CUPSD_EVENT_PRINTER_STATE; + } + } + } + else if (!strncmp(message, "recovered:", 10)) + { + ptr = message + 10; + while (isspace(*ptr & 255)) + ptr ++; + + if (cupsdSetPrinterReasons(job->printer, + "-com.apple.print.recoverable-warning") || + !job->printer->recoverable || strcmp(job->printer->recoverable, ptr)) + { + cupsdSetString(&(job->printer->recoverable), ptr); + cupsdAddPrinterHistory(job->printer); + event |= CUPSD_EVENT_PRINTER_STATE; + } + } + else + { + cupsdLogJob(job, loglevel, "%s", message); + + if (loglevel < CUPSD_LOG_DEBUG && + strcmp(job->printer->state_message, ptr)) + { + strlcpy(job->printer->state_message, message, + sizeof(job->printer->state_message)); + cupsdAddPrinterHistory(job->printer); + + event |= CUPSD_EVENT_PRINTER_STATE | CUPSD_EVENT_JOB_PROGRESS; + + if (loglevel <= job->status_level && job->status_level > CUPSD_LOG_ERROR) + { + /* + * Some messages show in the job-printer-state-message attribute... + */ + + if (loglevel != CUPSD_LOG_NOTICE) + job->status_level = loglevel; + + update_job_attrs(job, 1); + + cupsdLogJob(job, CUPSD_LOG_DEBUG, + "Set job-printer-state-message to \"%s\", " + "current level=%s", + job->printer_message->values[0].string.text, + levels[job->status_level]); + } + } + } + + if (!strchr(job->status_buffer->buffer, '\n')) + break; + } + + if (event & CUPSD_EVENT_JOB_PROGRESS) + cupsdAddEvent(CUPSD_EVENT_JOB_PROGRESS, job->printer, job, + "%s", job->printer->state_message); + if (event & CUPSD_EVENT_PRINTER_STATE) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, + (job->printer->type & CUPS_PRINTER_CLASS) ? + "Class \"%s\" state changed." : + "Printer \"%s\" state changed.", + job->printer->name); + + + if (ptr == NULL && !job->status_buffer->bufused) + { + /* + * See if all of the filters and the backend have returned their + * exit statuses. + */ + + for (i = 0; job->filters[i] < 0; i ++); + + if (job->filters[i]) + { + /* + * EOF but we haven't collected the exit status of all filters... + */ + + cupsdCheckProcess(); + return; + } + + if (job->current_file >= job->num_files && job->backend > 0) + { + /* + * EOF but we haven't collected the exit status of the backend... + */ + + cupsdCheckProcess(); + return; + } + + /* + * Handle the end of job stuff... + */ + + finalize_job(job, 1); + + /* + * Check for new jobs... + */ + + cupsdCheckJobs(); + } +} + + +/* + * 'update_job_attrs()' - Update the job-printer-* attributes. + */ + +void +update_job_attrs(cupsd_job_t *job, /* I - Job to update */ + int do_message)/* I - 1 = copy job-printer-state message */ +{ + int i; /* Looping var */ + int num_reasons; /* Actual number of reasons */ + const char * const *reasons; /* Reasons */ + static const char *none = "none"; /* "none" reason */ + + + /* + * Get/create the job-printer-state-* attributes... + */ + + if (!job->printer_message) + { + if ((job->printer_message = ippFindAttribute(job->attrs, + "job-printer-state-message", + IPP_TAG_TEXT)) == NULL) + job->printer_message = ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_TEXT, + "job-printer-state-message", + NULL, ""); + } + + if (!job->printer_reasons) + job->printer_reasons = ippFindAttribute(job->attrs, + "job-printer-state-reasons", + IPP_TAG_KEYWORD); + + /* + * Copy or clear the printer-state-message value as needed... + */ + + if (job->state_value != IPP_JOB_PROCESSING && + job->status_level == CUPSD_LOG_INFO) + cupsdSetString(&(job->printer_message->values[0].string.text), ""); + else if (job->printer->state_message[0] && do_message) + cupsdSetString(&(job->printer_message->values[0].string.text), + job->printer->state_message); + + /* + * ... and the printer-state-reasons value... + */ + + if (job->printer->num_reasons == 0) + { + num_reasons = 1; + reasons = &none; + } + else + { + num_reasons = job->printer->num_reasons; + reasons = (const char * const *)job->printer->reasons; + } + + if (!job->printer_reasons || job->printer_reasons->num_values != num_reasons) + { + /* + * Replace/create a job-printer-state-reasons attribute... + */ + + ippDeleteAttribute(job->attrs, job->printer_reasons); + + job->printer_reasons = ippAddStrings(job->attrs, + IPP_TAG_JOB, IPP_TAG_KEYWORD, + "job-printer-state-reasons", + num_reasons, NULL, NULL); + } + else + { + /* + * Don't bother clearing the reason strings if they are the same... + */ + + for (i = 0; i < num_reasons; i ++) + if (strcmp(job->printer_reasons->values[i].string.text, reasons[i])) + break; + + if (i >= num_reasons) + return; + + /* + * Not the same, so free the current strings... + */ + + for (i = 0; i < num_reasons; i ++) + _cupsStrFree(job->printer_reasons->values[i].string.text); + } + + /* + * Copy the reasons... + */ + + for (i = 0; i < num_reasons; i ++) + job->printer_reasons->values[i].string.text = _cupsStrAlloc(reasons[i]); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/job.h b/scheduler/job.h new file mode 100644 index 0000000000..fc3d6355b3 --- /dev/null +++ b/scheduler/job.h @@ -0,0 +1,171 @@ +/* + * "$Id$" + * + * Print job definitions for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Constants... + */ + +typedef enum cupsd_jobaction_e /**** Actions for state changes ****/ +{ + CUPSD_JOB_DEFAULT, /* Use default action */ + CUPSD_JOB_FORCE, /* Force the change */ + CUPSD_JOB_PURGE /* Force the change and purge */ +} cupsd_jobaction_t; + + +/* + * Job request structure... + */ + +struct cupsd_job_s /**** Job request ****/ +{ + int id, /* Job ID */ + priority, /* Job priority */ + dirty; /* Do we need to write the "c" file? */ + ipp_jstate_t state_value; /* Cached job-state */ + int pending_timeout;/* Non-zero if the job was created and + * waiting on files */ + char *username; /* Printing user */ + char *dest; /* Destination printer or class */ + cups_ptype_t dtype; /* Destination type */ + int num_files; /* Number of files in job */ + mime_type_t **filetypes; /* File types */ + int *compressions; /* Compression status of each file */ + ipp_attribute_t *sheets; /* job-media-sheets-completed */ + time_t access_time, /* Last access time */ + kill_time, /* When to send SIGKILL */ + hold_until; /* Hold expiration date/time */ + ipp_attribute_t *state; /* Job state */ + ipp_attribute_t *job_sheets; /* Job sheets (NULL if none) */ + ipp_attribute_t *printer_message, + /* job-printer-state-message */ + *printer_reasons; + /* job-printer-state-reasons */ + int current_file; /* Current file in job */ + ipp_t *attrs; /* Job attributes */ + int print_pipes[2], /* Print data pipes */ + back_pipes[2], /* Backchannel pipes */ + side_pipes[2], /* Sidechannel pipes */ + status_pipes[2];/* Status pipes */ + cupsd_statbuf_t *status_buffer; /* Status buffer for this job */ + int status_level; /* Highest log level in a status + * message */ + int cost; /* Filtering cost */ + int pending_cost; /* Waiting for FilterLimit */ + int filters[MAX_FILTERS + 1]; + /* Filter process IDs, 0 terminated */ + int backend; /* Backend process ID */ + int status; /* Status code from filters */ + cupsd_printer_t *printer; /* Printer this job is assigned to */ + int tries; /* Number of tries for this job */ + char *auth_username, /* AUTH_USERNAME environment variable, + * if any */ + *auth_domain, /* AUTH_DOMAIN environment variable, + * if any */ + *auth_password; /* AUTH_PASSWORD environment variable, + * if any */ + void *profile; /* Security profile */ + cups_array_t *history; /* Debug log history */ + int progress; /* Printing progress */ +#ifdef HAVE_GSSAPI + krb5_ccache ccache; /* Kerberos credential cache */ + char *ccname; /* KRB5CCNAME environment variable */ +#endif /* HAVE_GSSAPI */ +}; + +typedef struct cupsd_joblog_s /**** Job log message ****/ +{ + time_t time; /* Time of message */ + char message[1]; /* Message string */ +} cupsd_joblog_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 */ + MaxActiveJobs VALUE(0), + /* Max number of active jobs */ + MaxJobsPerUser VALUE(0), + /* Max jobs per user */ + MaxJobsPerPrinter VALUE(0); + /* Max jobs per printer */ +VAR int JobAutoPurge VALUE(0); + /* Automatically purge jobs */ +VAR cups_array_t *Jobs VALUE(NULL), + /* List of current jobs */ + *ActiveJobs VALUE(NULL), + /* List of active jobs */ + *PrintingJobs VALUE(NULL); + /* List of jobs that are printing */ +VAR int NextJobId VALUE(1); + /* Next job ID to use */ +VAR int JobKillDelay VALUE(DEFAULT_TIMEOUT), + /* Delay before killing jobs */ + JobRetryLimit VALUE(5), + /* Max number of tries */ + JobRetryInterval VALUE(300); + /* Seconds between retries */ + + +/* + * Prototypes... + */ + +extern cupsd_job_t *cupsdAddJob(int priority, const char *dest); +extern void cupsdCancelJobs(const char *dest, const char *username, + int purge); +extern void cupsdCheckJobs(void); +extern void cupsdCleanJobs(void); +extern void cupsdContinueJob(cupsd_job_t *job); +extern void cupsdDeleteJob(cupsd_job_t *job, + cupsd_jobaction_t action); +extern cupsd_job_t *cupsdFindJob(int id); +extern void cupsdFreeAllJobs(void); +extern int cupsdGetPrinterJobCount(const char *dest); +extern int cupsdGetUserJobCount(const char *username); +extern void cupsdLoadAllJobs(void); +extern int cupsdLoadJob(cupsd_job_t *job); +extern void cupsdMoveJob(cupsd_job_t *job, cupsd_printer_t *p); +extern void cupsdReleaseJob(cupsd_job_t *job); +extern void cupsdRestartJob(cupsd_job_t *job); +extern void cupsdSaveAllJobs(void); +extern void cupsdSaveJob(cupsd_job_t *job); +extern void cupsdSetJobHoldUntil(cupsd_job_t *job, + const char *when, int update); +extern void cupsdSetJobPriority(cupsd_job_t *job, int priority); +extern void cupsdSetJobState(cupsd_job_t *job, + ipp_jstate_t newstate, + cupsd_jobaction_t action, + const char *message, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 4, 5))) +#endif /* __GNUC__ */ +; +extern void cupsdStopAllJobs(cupsd_jobaction_t action, + int kill_delay); +extern int cupsdTimeoutJob(cupsd_job_t *job); +extern void cupsdUnloadCompletedJobs(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/libcupsmime.exp b/scheduler/libcupsmime.exp new file mode 100644 index 0000000000..dfe99c290b --- /dev/null +++ b/scheduler/libcupsmime.exp @@ -0,0 +1,19 @@ +_mimeAddFilter +_mimeAddType +_mimeAddTypeRule +_mimeDelete +_mimeDeleteFilter +_mimeDeleteType +_mimeFileType +_mimeFilter +_mimeFilterLookup +_mimeFirstFilter +_mimeFirstType +_mimeLoad +_mimeLoadFilters +_mimeLoadTypes +_mimeNextFilter +_mimeNextType +_mimeNumFilters +_mimeNumTypes +_mimeType diff --git a/scheduler/listen.c b/scheduler/listen.c new file mode 100644 index 0000000000..482a95bbe2 --- /dev/null +++ b/scheduler/listen.c @@ -0,0 +1,443 @@ +/* + * "$Id$" + * + * Server listening routines for the Common UNIX Printing System (CUPS) + * scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdDeleteAllListeners() - Delete all listeners. + * cupsdPauseListening() - Clear input polling on all listening sockets... + * cupsdResumeListening() - Set input polling on all listening sockets... + * cupsdStartListening() - Create all listening sockets... + * cupsdStopListening() - Close all listening sockets... + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + + +/* + * Make sure the IPV6_V6ONLY is defined on Linux - older versions of + * glibc don't define it even if the kernel supports it... + */ + +#if defined(__linux) && !defined(IPV6_V6ONLY) +# define IPV6_V6ONLY 26 +#endif /* __linux && !IPV6_V6ONLY */ + + +/* + * 'cupsdDeleteAllListeners()' - Delete all listeners. + */ + +void +cupsdDeleteAllListeners(void) +{ + cupsd_listener_t *lis; /* Current listening socket */ + + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + free(lis); + + cupsArrayDelete(Listeners); + Listeners = NULL; +} + + +/* + * 'cupsdPauseListening()' - Clear input polling on all listening sockets... + */ + +void +cupsdPauseListening(void) +{ + cupsd_listener_t *lis; /* Current listening socket */ + + + if (cupsArrayCount(Listeners) < 1) + return; + + if (cupsArrayCount(Clients) == MaxClients) + cupsdLogMessage(CUPSD_LOG_WARN, + "Max clients reached, holding new connections..."); + else if (errno == ENFILE || errno == EMFILE) + cupsdLogMessage(CUPSD_LOG_WARN, + "Too many open files, holding new connections for " + "30 seconds..."); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdPauseListening: Clearing input bits..."); + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + cupsdRemoveSelect(lis->fd); + + ListeningPaused = time(NULL) + 30; +} + + +/* + * 'cupsdResumeListening()' - Set input polling on all listening sockets... + */ + +void +cupsdResumeListening(void) +{ + cupsd_listener_t *lis; /* Current listening socket */ + + + if (cupsArrayCount(Listeners) < 1) + return; + + cupsdLogMessage(CUPSD_LOG_INFO, "Resuming new connection processing..."); + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdResumeListening: Setting input bits..."); + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + cupsdAddSelect(lis->fd, (cupsd_selfunc_t)cupsdAcceptClient, NULL, lis); + + ListeningPaused = 0; +} + + +/* + * 'cupsdStartListening()' - Create all listening sockets... + */ + +void +cupsdStartListening(void) +{ + int status; /* Bind result */ + int p, /* Port number */ + val; /* Parameter value */ + cupsd_listener_t *lis; /* Current listening socket */ + char s[256]; /* String addresss */ + const char *have_domain; /* Have a domain socket? */ + static const char * const encryptions[] = + { /* Encryption values */ + "IfRequested", + "Never", + "Required", + "Always" + }; + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartListening: %d Listeners", + cupsArrayCount(Listeners)); + + /* + * Setup socket listeners... + */ + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners), LocalPort = 0, + have_domain = NULL; + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + { + httpAddrString(&(lis->address), s, sizeof(s)); + +#ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + p = ntohs(lis->address.ipv6.sin6_port); + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (lis->address.addr.sa_family == AF_LOCAL) + p = 0; + else +#endif /* AF_LOCAL */ + p = ntohs(lis->address.ipv4.sin_port); + + /* + * If needed, create a socket for listening... + */ + + if (lis->fd == -1) + { + /* + * Create a socket for listening... + */ + + lis->fd = socket(lis->address.addr.sa_family, SOCK_STREAM, 0); + + if (lis->fd == -1) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to open listen socket for address %s:%d - %s.", + s, p, strerror(errno)); + +#ifdef AF_INET6 + /* + * IPv6 is often disabled while DNS returns IPv6 addresses... + */ + + if (lis->address.addr.sa_family != AF_INET6 && + (FatalErrors & CUPSD_FATAL_LISTEN)) + cupsdEndProcess(getpid(), 0); +#else + if (FatalErrors & CUPSD_FATAL_LISTEN) + cupsdEndProcess(getpid(), 0); +#endif /* AF_INET6 */ + + continue; + } + + /* + * 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... + */ + +#ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + { +# ifdef IPV6_V6ONLY + /* + * Accept only IPv6 connections on this socket, to avoid + * potential security issues and to make all platforms behave + * the same. + */ + + val = 1; +# ifdef __sun + setsockopt(lis->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&val, sizeof(val)); +# else + setsockopt(lis->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)); +# endif /* __sun */ +# endif /* IPV6_V6ONLY */ + + status = bind(lis->fd, (struct sockaddr *)&(lis->address), + httpAddrLength(&(lis->address))); + } + else +#endif /* AF_INET6 */ +#ifdef AF_LOCAL + if (lis->address.addr.sa_family == AF_LOCAL) + { + mode_t mask; /* Umask setting */ + + + /* + * Remove any existing domain socket file... + */ + + unlink(lis->address.un.sun_path); + + /* + * Save the current umask and set it to 0 so that all users can access + * the domain socket... + */ + + mask = umask(0); + + /* + * Bind the domain socket... + */ + + status = bind(lis->fd, (struct sockaddr *)&(lis->address), + httpAddrLength(&(lis->address))); + + /* + * Restore the umask... + */ + + umask(mask); + } + else +#endif /* AF_LOCAL */ + status = bind(lis->fd, (struct sockaddr *)&(lis->address), + sizeof(lis->address.ipv4)); + + if (status < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to bind socket for address %s:%d - %s.", + s, p, strerror(errno)); + close(lis->fd); + lis->fd = -1; + + if (FatalErrors & CUPSD_FATAL_LISTEN) + cupsdEndProcess(getpid(), 0); + + continue; + } + + /* + * Listen for new clients. + */ + + if (listen(lis->fd, ListenBackLog) < 0) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to listen for clients on address %s:%d - %s.", + s, p, strerror(errno)); + + close(lis->fd); + lis->fd = -1; + + if (FatalErrors & CUPSD_FATAL_LISTEN) + cupsdEndProcess(getpid(), 0); + + continue; + } + } + + fcntl(lis->fd, F_SETFD, fcntl(lis->fd, F_GETFD) | FD_CLOEXEC); + + if (p) + cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s:%d on fd %d...", + s, p, lis->fd); + else + { + cupsdLogMessage(CUPSD_LOG_INFO, "Listening to %s on fd %d...", + s, lis->fd); + + if (chmod(s, 0140777)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to change permisssions on domain socket " + "\"%s\" - %s", s, strerror(errno)); + } + + /* + * Save the first port that is bound to the local loopback or + * "any" address... + */ + + if ((!LocalPort || LocalEncryption == HTTP_ENCRYPT_ALWAYS) && p > 0 && + (httpAddrLocalhost(&(lis->address)) || + httpAddrAny(&(lis->address)))) + { + LocalPort = p; + LocalEncryption = lis->encryption; + } + +#ifdef AF_LOCAL + if (lis->address.addr.sa_family == AF_LOCAL && !have_domain) + have_domain = lis->address.un.sun_path; +#endif /* AF_LOCAL */ + } + + /* + * Make sure that we are listening on localhost! + */ + + if (!LocalPort && !have_domain) + { + cupsdLogMessage(CUPSD_LOG_EMERG, + "No Listen or Port lines were found to allow access via " + "localhost!"); + + if (FatalErrors & (CUPSD_FATAL_CONFIG | CUPSD_FATAL_LISTEN)) + cupsdEndProcess(getpid(), 0); + } + + /* + * Set the CUPS_SERVER, IPP_PORT, and CUPS_ENCRYPTION variables based on + * the listeners... + */ + + if (have_domain) + { + /* + * Use domain sockets for the local connection... + */ + + cupsdSetEnv("CUPS_SERVER", have_domain); + + LocalEncryption = HTTP_ENCRYPT_IF_REQUESTED; + } + else + { + /* + * Use the default local loopback address for the server... + */ + + cupsdSetEnv("CUPS_SERVER", "localhost"); + } + + cupsdSetEnv("CUPS_ENCRYPTION", encryptions[LocalEncryption]); + + if (LocalPort) + cupsdSetEnvf("IPP_PORT", "%d", LocalPort); + + /* + * Resume listening for connections... + */ + + cupsdResumeListening(); +} + + +/* + * 'cupsdStopListening()' - Close all listening sockets... + */ + +void +cupsdStopListening(void) +{ + cupsd_listener_t *lis; /* Current listening socket */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdStopListening: closing all listen sockets."); + + cupsdPauseListening(); + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + { + if (lis->fd != -1) + { +#ifdef WIN32 + closesocket(lis->fd); +#else + close(lis->fd); +#endif /* WIN32 */ + +#ifdef AF_LOCAL + /* + * Remove domain sockets... + */ + +# ifdef HAVE_LAUNCH_H + if (lis->address.addr.sa_family == AF_LOCAL && !Launchd) +# else + if (lis->address.addr.sa_family == AF_LOCAL) +# endif /* HAVE_LAUNCH_H */ + unlink(lis->address.un.sun_path); +#endif /* AF_LOCAL */ + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/log.c b/scheduler/log.c new file mode 100644 index 0000000000..0c6bb74e85 --- /dev/null +++ b/scheduler/log.c @@ -0,0 +1,1031 @@ +/* + * "$Id$" + * + * Log file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdGetDateTime() - Returns a pointer to a date/time string. + * cupsdLogGSSMessage() - Log a GSSAPI error... + * cupsdLogJob() - Log a job message. + * cupsdLogMessage() - Log a message to the error log file. + * cupsdLogPage() - Log a page to the page log file. + * cupsdLogRequest() - Log an HTTP request in Common Log Format. + * cupsdWriteErrorLog() - Write a line to the ErrorLog. + * check_log_file() - Open/rotate a log file if it needs it. + * format_log_line() - Format a line for a log file. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include +#include + + +/* + * Local globals... + */ + +static int log_linesize = 0; /* Size of line for output file */ +static char *log_line = NULL; /* Line for output file */ + + +/* + * Local functions... + */ + +static int check_log_file(cups_file_t **lf, const char *logname); +static int format_log_line(const char *message, va_list ap); + + +/* + * 'cupsdGetDateTime()' - Returns a pointer to a date/time string. + */ + +char * /* O - Date/time string */ +cupsdGetDateTime(struct timeval *t, /* I - Time value or NULL for current */ + cupsd_time_t format) /* I - Format to use */ +{ + struct timeval curtime; /* Current time value */ + struct tm *date; /* Date/time value */ + static struct timeval last_time = { 0, 0 }; + /* Last time we formatted */ + static char s[1024]; /* Date/time string */ + static const char * const months[12] =/* Months */ + { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + }; + + + /* + * Make sure we have a valid time... + */ + + if (!t) + { + gettimeofday(&curtime, NULL); + t = &curtime; + } + + if (t->tv_sec != last_time.tv_sec || + (LogTimeFormat == CUPSD_TIME_USECS && t->tv_usec != last_time.tv_usec)) + { + last_time = *t; + + /* + * 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->tv_sec)); + + if (format == CUPSD_TIME_STANDARD) + 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 */ + else + snprintf(s, sizeof(s), "[%02d/%s/%04d:%02d:%02d:%02d.%06d %+03ld%02ld]", + date->tm_mday, months[date->tm_mon], 1900 + date->tm_year, + date->tm_hour, date->tm_min, date->tm_sec, (int)t->tv_usec, +#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); +} + + +#ifdef HAVE_GSSAPI +/* + * 'cupsdLogGSSMessage()' - Log a GSSAPI error... + */ + +int /* O - 1 on success, 0 on error */ +cupsdLogGSSMessage( + int level, /* I - Log level */ + int major_status, /* I - Major GSSAPI status */ + int minor_status, /* I - Minor GSSAPI status */ + const char *message, /* I - printf-style message string */ + ...) /* I - Additional args as needed */ +{ + OM_uint32 err_major_status, /* Major status code for display */ + err_minor_status; /* Minor status code for display */ + OM_uint32 msg_ctx; /* Message context */ + gss_buffer_desc major_status_string = GSS_C_EMPTY_BUFFER, + /* Major status message */ + minor_status_string = GSS_C_EMPTY_BUFFER; + /* Minor status message */ + int ret; /* Return value */ + + + msg_ctx = 0; + err_major_status = gss_display_status(&err_minor_status, + major_status, + GSS_C_GSS_CODE, + GSS_C_NO_OID, + &msg_ctx, + &major_status_string); + + if (!GSS_ERROR(err_major_status)) + gss_display_status(&err_minor_status, minor_status, GSS_C_MECH_CODE, + GSS_C_NULL_OID, &msg_ctx, &minor_status_string); + + ret = cupsdLogMessage(level, "%s: %s, %s", message, + (char *)major_status_string.value, + (char *)minor_status_string.value); + gss_release_buffer(&err_minor_status, &major_status_string); + gss_release_buffer(&err_minor_status, &minor_status_string); + + return (ret); +} +#endif /* HAVE_GSSAPI */ + + +/* + * 'cupsdLogJob()' - Log a job message. + */ + +int /* O - 1 on success, 0 on error */ +cupsdLogJob(cupsd_job_t *job, /* I - Job */ + int level, /* I - Log level */ + const char *message, /* I - Printf-style message string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Argument pointer */ + char jobmsg[1024]; /* Format string for job message */ + int status; /* Formatting status */ + + + /* + * See if we want to log this message... + */ + + if (TestConfigFile || !ErrorLog) + return (1); + + if ((level > LogLevel || + (level == CUPSD_LOG_INFO && LogLevel < CUPSD_LOG_DEBUG)) && + LogDebugHistory <= 0) + return (1); + + /* + * Format and write the log message... + */ + + snprintf(jobmsg, sizeof(jobmsg), "[Job %d] %s", job->id, message); + + do + { + va_start(ap, message); + status = format_log_line(jobmsg, ap); + va_end(ap); + } + while (status == 0); + + if (status > 0) + { + if ((level > LogLevel || + (level == CUPSD_LOG_INFO && LogLevel < CUPSD_LOG_DEBUG)) && + LogDebugHistory > 0) + { + /* + * Add message to the job history... + */ + + cupsd_joblog_t *temp; /* Copy of log message */ + + + if ((temp = malloc(sizeof(cupsd_joblog_t) + strlen(log_line))) != NULL) + { + temp->time = time(NULL); + strcpy(temp->message, log_line); + } + + if (!job->history) + job->history = cupsArrayNew(NULL, NULL); + + if (job->history && temp) + { + cupsArrayAdd(job->history, temp); + + if (cupsArrayCount(job->history) > LogDebugHistory) + { + /* + * Remove excess messages... + */ + + temp = cupsArrayFirst(job->history); + cupsArrayRemove(job->history, temp); + free(temp); + } + } + else if (temp) + free(temp); + + return (1); + } + else if (level <= LogLevel && + (level != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG)) + return (cupsdWriteErrorLog(level, log_line)); + else + return (1); + } + else + return (cupsdWriteErrorLog(CUPSD_LOG_ERROR, + "Unable to allocate memory for log line!")); +} + + +/* + * 'cupsdLogMessage()' - Log a message to the error log file. + */ + +int /* O - 1 on success, 0 on error */ +cupsdLogMessage(int level, /* I - Log level */ + const char *message, /* I - printf-style message string */ + ...) /* I - Additional args as needed */ +{ + va_list ap; /* Argument pointer */ + int status; /* Formatting status */ + + + /* + * See if we want to log this message... + */ + + if (TestConfigFile) + { + if (level <= CUPSD_LOG_WARN) + { + va_start(ap, message); + vfprintf(stderr, message, ap); + putc('\n', stderr); + va_end(ap); + } + + return (1); + } + + if (level > LogLevel || !ErrorLog) + return (1); + + /* + * Format and write the log message... + */ + + do + { + va_start(ap, message); + status = format_log_line(message, ap); + va_end(ap); + } + while (status == 0); + + if (status > 0) + return (cupsdWriteErrorLog(level, log_line)); + else + return (cupsdWriteErrorLog(CUPSD_LOG_ERROR, + "Unable to allocate memory for log line!")); +} + + +/* + * 'cupsdLogPage()' - Log a page to the page log file. + */ + +int /* O - 1 on success, 0 on error */ +cupsdLogPage(cupsd_job_t *job, /* I - Job being printed */ + const char *page) /* I - Page being printed */ +{ + int i; /* Looping var */ + char buffer[2048], /* Buffer for page log */ + *bufptr, /* Pointer into buffer */ + name[256]; /* Attribute name */ + const char *format, /* Pointer into PageLogFormat */ + *nameend; /* End of attribute name */ + ipp_attribute_t *attr; /* Current attribute */ + int number; /* Page number */ + char copies[256]; /* Number of copies */ + + + /* + * Format the line going into the page log... + */ + + if (!PageLogFormat) + return (1); + + number = 1; + strcpy(copies, "1"); + sscanf(page, "%d%255s", &number, copies); + + for (format = PageLogFormat, bufptr = buffer; *format; format ++) + { + if (*format == '%') + { + format ++; + + switch (*format) + { + case '%' : /* Literal % */ + if (bufptr < (buffer + sizeof(buffer) - 1)) + *bufptr++ = '%'; + break; + + case 'p' : /* Printer name */ + strlcpy(bufptr, job->printer->name, + sizeof(buffer) - (bufptr - buffer)); + bufptr += strlen(bufptr); + break; + + case 'j' : /* Job ID */ + snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", job->id); + bufptr += strlen(bufptr); + break; + + case 'u' : /* Username */ + strlcpy(bufptr, job->username ? job->username : "-", + sizeof(buffer) - (bufptr - buffer)); + bufptr += strlen(bufptr); + break; + + case 'T' : /* Date and time */ + strlcpy(bufptr, cupsdGetDateTime(NULL, LogTimeFormat), + sizeof(buffer) - (bufptr - buffer)); + bufptr += strlen(bufptr); + break; + + case 'P' : /* Page number */ + snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), "%d", number); + bufptr += strlen(bufptr); + break; + + case 'C' : /* Number of copies */ + strlcpy(bufptr, copies, sizeof(buffer) - (bufptr - buffer)); + bufptr += strlen(bufptr); + break; + + case '{' : /* {attribute} */ + if ((nameend = strchr(format, '}')) != NULL && + (nameend - format - 2) < (sizeof(name) - 1)) + { + /* + * Pull the name from inside the brackets... + */ + + memcpy(name, format + 1, nameend - format - 1); + name[nameend - format - 1] = '\0'; + + format = nameend; + + if ((attr = ippFindAttribute(job->attrs, name, + IPP_TAG_ZERO)) != NULL) + { + /* + * Add the attribute value... + */ + + for (i = 0; + i < attr->num_values && + bufptr < (buffer + sizeof(buffer) - 1); + i ++) + { + if (i) + *bufptr++ = ','; + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), + "%d", attr->values[i].integer); + bufptr += strlen(bufptr); + break; + + case IPP_TAG_BOOLEAN : + snprintf(bufptr, sizeof(buffer) - (bufptr - buffer), + "%d", attr->values[i].boolean); + bufptr += strlen(bufptr); + break; + + 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 : + strlcpy(bufptr, attr->values[i].string.text, + sizeof(buffer) - (bufptr - buffer)); + bufptr += strlen(bufptr); + break; + + default : + strlcpy(bufptr, "???", + sizeof(buffer) - (bufptr - buffer)); + bufptr += strlen(bufptr); + break; + } + } + } + else if (bufptr < (buffer + sizeof(buffer) - 1)) + *bufptr++ = '-'; + break; + } + + default : + if (bufptr < (buffer + sizeof(buffer) - 2)) + { + *bufptr++ = '%'; + *bufptr++ = *format; + } + break; + } + } + else if (bufptr < (buffer + sizeof(buffer) - 1)) + *bufptr++ = *format; + } + + *bufptr = '\0'; + +#ifdef HAVE_VSYSLOG + /* + * See if we are logging pages via syslog... + */ + + if (!strcmp(PageLog, "syslog")) + { + syslog(LOG_INFO, "%s", buffer); + + 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 user job-id [DD/MON/YYYY:HH:MM:SS +TTTT] page num-copies \ + * billing hostname + */ + + cupsFilePrintf(PageFile, "%s\n", buffer); + cupsFileFlush(PageFile); + + return (1); +} + + +/* + * 'cupsdLogRequest()' - Log an HTTP request in Common Log Format. + */ + +int /* O - 1 on success, 0 on error */ +cupsdLogRequest(cupsd_client_t *con, /* I - Request to log */ + http_status_t code) /* I - Response code */ +{ + char temp[2048]; /* Temporary string for URI */ + static const char * const states[] = /* HTTP client states... */ + { + "WAITING", + "OPTIONS", + "GET", + "GET", + "HEAD", + "POST", + "POST", + "POST", + "PUT", + "PUT", + "DELETE", + "TRACE", + "CLOSE", + "STATUS" + }; + + + /* + * Filter requests as needed... + */ + + if (AccessLogLevel < CUPSD_ACCESSLOG_ALL) + { + /* + * Eliminate simple GET, POST, and PUT requests... + */ + + if ((con->operation == HTTP_GET && + strncmp(con->uri, "/admin/conf", 11) && + strncmp(con->uri, "/admin/log", 10)) || + (con->operation == HTTP_POST && !con->request && + strncmp(con->uri, "/admin", 6)) || + (con->operation != HTTP_GET && con->operation != HTTP_POST && + con->operation != HTTP_PUT)) + return (1); + + if (con->request && con->response && + (con->response->request.status.status_code < IPP_REDIRECTION_OTHER_SITE || + con->response->request.status.status_code == IPP_NOT_FOUND)) + { + /* + * Check successful requests... + */ + + ipp_op_t op = con->request->request.op.operation_id; + static cupsd_accesslog_t standard_ops[] = + { + CUPSD_ACCESSLOG_ALL, /* reserved */ + CUPSD_ACCESSLOG_ALL, /* reserved */ + CUPSD_ACCESSLOG_ACTIONS,/* Print-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Print-URI */ + CUPSD_ACCESSLOG_ACTIONS,/* Validate-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Create-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Send-Document */ + CUPSD_ACCESSLOG_ACTIONS,/* Send-URI */ + CUPSD_ACCESSLOG_ACTIONS,/* Cancel-Job */ + CUPSD_ACCESSLOG_ALL, /* Get-Job-Attributes */ + CUPSD_ACCESSLOG_ALL, /* Get-Jobs */ + CUPSD_ACCESSLOG_ALL, /* Get-Printer-Attributes */ + CUPSD_ACCESSLOG_ACTIONS,/* Hold-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Release-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Restart-Job */ + CUPSD_ACCESSLOG_ALL, /* reserved */ + CUPSD_ACCESSLOG_CONFIG, /* Pause-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Resume-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Purge-Jobs */ + CUPSD_ACCESSLOG_CONFIG, /* Set-Printer-Attributes */ + CUPSD_ACCESSLOG_ACTIONS,/* Set-Job-Attributes */ + CUPSD_ACCESSLOG_CONFIG, /* Get-Printer-Supported-Values */ + CUPSD_ACCESSLOG_ACTIONS,/* Create-Printer-Subscription */ + CUPSD_ACCESSLOG_ACTIONS,/* Create-Job-Subscription */ + CUPSD_ACCESSLOG_ALL, /* Get-Subscription-Attributes */ + CUPSD_ACCESSLOG_ALL, /* Get-Subscriptions */ + CUPSD_ACCESSLOG_ACTIONS,/* Renew-Subscription */ + CUPSD_ACCESSLOG_ACTIONS,/* Cancel-Subscription */ + CUPSD_ACCESSLOG_ALL, /* Get-Notifications */ + CUPSD_ACCESSLOG_ACTIONS,/* Send-Notifications */ + CUPSD_ACCESSLOG_ALL, /* reserved */ + CUPSD_ACCESSLOG_ALL, /* reserved */ + CUPSD_ACCESSLOG_ALL, /* reserved */ + CUPSD_ACCESSLOG_ALL, /* Get-Print-Support-Files */ + CUPSD_ACCESSLOG_CONFIG, /* Enable-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Disable-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Pause-Printer-After-Current-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Hold-New-Jobs */ + CUPSD_ACCESSLOG_ACTIONS,/* Release-Held-New-Jobs */ + CUPSD_ACCESSLOG_CONFIG, /* Deactivate-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Activate-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Restart-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Shutdown-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* Startup-Printer */ + CUPSD_ACCESSLOG_ACTIONS,/* Reprocess-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Cancel-Current-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Suspend-Current-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Resume-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* Promote-Job */ + CUPSD_ACCESSLOG_ACTIONS /* Schedule-Job-After */ + }; + static cupsd_accesslog_t cups_ops[] = + { + CUPSD_ACCESSLOG_ALL, /* CUPS-Get-Default */ + CUPSD_ACCESSLOG_ALL, /* CUPS-Get-Printers */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Add-Modify-Printer */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Delete-Printer */ + CUPSD_ACCESSLOG_ALL, /* CUPS-Get-Classes */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Add-Modify-Class */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Delete-Class */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Accept-Jobs */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Reject-Jobs */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Set-Default */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Get-Devices */ + CUPSD_ACCESSLOG_CONFIG, /* CUPS-Get-PPDs */ + CUPSD_ACCESSLOG_ACTIONS,/* CUPS-Move-Job */ + CUPSD_ACCESSLOG_ACTIONS,/* CUPS-Authenticate-Job */ + CUPSD_ACCESSLOG_ALL /* CUPS-Get-PPD */ + }; + + + if ((op <= IPP_SCHEDULE_JOB_AFTER && standard_ops[op] > AccessLogLevel) || + (op >= CUPS_GET_DEFAULT && op <= CUPS_GET_PPD && + cups_ops[op - CUPS_GET_DEFAULT] > AccessLogLevel)) + return (1); + } + } + +#ifdef HAVE_VSYSLOG + /* + * See if we are logging accesses via syslog... + */ + + if (!strcmp(AccessLog, "syslog")) + { + syslog(LOG_INFO, + "REQUEST %s - %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n", + con->http.hostname, con->username[0] != '\0' ? con->username : "-", + states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)), + con->http.version / 100, con->http.version % 100, + code, CUPS_LLCAST con->bytes, + con->request ? + ippOpString(con->request->request.op.operation_id) : "-", + con->response ? + ippErrorString(con->response->request.status.status_code) : "-"); + + 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"... + */ + + cupsFilePrintf(AccessFile, + "%s - %s %s \"%s %s HTTP/%d.%d\" %d " CUPS_LLFMT " %s %s\n", + con->http.hostname, con->username[0] != '\0' ? con->username : "-", + cupsdGetDateTime(&(con->start), LogTimeFormat), + states[con->operation], + _httpEncodeURI(temp, con->uri, sizeof(temp)), + con->http.version / 100, con->http.version % 100, + code, CUPS_LLCAST con->bytes, + con->request ? + ippOpString(con->request->request.op.operation_id) : "-", + con->response ? + ippErrorString(con->response->request.status.status_code) : + "-"); + + cupsFileFlush(AccessFile); + + return (1); +} + + +/* + * 'cupsdWriteErrorLog()' - Write a line to the ErrorLog. + */ + +int /* O - 1 on success, 0 on failure */ +cupsdWriteErrorLog(int level, /* I - Log level */ + const char *message) /* I - Message string */ +{ + static const char levels[] = /* Log levels... */ + { + ' ', + 'X', + 'A', + 'C', + 'E', + 'W', + 'N', + 'I', + 'D', + 'd' + }; +#ifdef HAVE_VSYSLOG + static const 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 */ + + +#ifdef HAVE_VSYSLOG + /* + * See if we are logging errors via syslog... + */ + + if (!strcmp(ErrorLog, "syslog")) + { + syslog(syslevels[level], "%s", message); + return (1); + } +#endif /* HAVE_VSYSLOG */ + + /* + * Not using syslog; check the log file... + */ + + if (!check_log_file(&ErrorFile, ErrorLog)) + return (0); + + /* + * Write the log message... + */ + + cupsFilePrintf(ErrorFile, "%c %s %s\n", levels[level], + cupsdGetDateTime(NULL, LogTimeFormat), message); + cupsFileFlush(ErrorFile); + + 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(cups_file_t **lf, /* IO - Log file */ + const char *logname) /* I - Log filename */ +{ + char backname[1024], /* Backup log filename */ + filename[1024], /* Formatted log filename */ + *ptr; /* Pointer into filename */ + const char *logptr; /* Pointer into log filename */ + + + /* + * See if we have a log file to check... + */ + + if (!lf || !logname || !logname[0]) + return (1); + + /* + * Format the filename as needed... + */ + + if (!*lf || + (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > 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 (logptr = logname, ptr = filename + strlen(filename); + *logptr && ptr < (filename + sizeof(filename) - 1); + logptr ++) + if (*logptr == '%') + { + /* + * Format spec... + */ + + logptr ++; + if (*logptr == 's') + { + /* + * Insert the server name... + */ + + strlcpy(ptr, ServerName, sizeof(filename) - (ptr - filename)); + ptr += strlen(ptr); + } + else + { + /* + * Otherwise just insert the character... + */ + + *ptr++ = *logptr; + } + } + else + *ptr++ = *logptr; + + *ptr = '\0'; + } + + /* + * See if the log file is open... + */ + + if (!*lf) + { + /* + * Nope, open the log file... + */ + + if ((*lf = cupsFileOpen(filename, "a")) == NULL) + { + /* + * If the file is in CUPS_LOGDIR then try to create a missing directory... + */ + + if (!strncmp(filename, CUPS_LOGDIR, strlen(CUPS_LOGDIR))) + { + /* + * Try updating the permissions of the containing log directory, using + * the log file permissions as a basis... + */ + + int log_dir_perm = 0300 | LogFilePerm; + /* LogFilePerm + owner write/search */ + if (log_dir_perm & 0040) + log_dir_perm |= 0010; /* Add group search */ + if (log_dir_perm & 0004) + log_dir_perm |= 0001; /* Add other search */ + + cupsdCheckPermissions(CUPS_LOGDIR, NULL, log_dir_perm, RunUser, Group, + 1, -1); + + *lf = cupsFileOpen(filename, "a"); + } + + if (*lf == NULL) + { + syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, + strerror(errno)); + + if (FatalErrors & CUPSD_FATAL_LOG) + cupsdEndProcess(getpid(), 0); + + return (0); + } + } + + if (strncmp(filename, "/dev/", 5)) + { + /* + * Change ownership and permissions of non-device logs... + */ + + fchown(cupsFileNumber(*lf), RunUser, Group); + fchmod(cupsFileNumber(*lf), LogFilePerm); + } + } + + /* + * Do we need to rotate the log? + */ + + if (strncmp(logname, "/dev/", 5) && cupsFileTell(*lf) > MaxLogSize && + MaxLogSize > 0) + { + /* + * Rotate log file... + */ + + cupsFileClose(*lf); + + strcpy(backname, filename); + strlcat(backname, ".O", sizeof(backname)); + + unlink(backname); + rename(filename, backname); + + if ((*lf = cupsFileOpen(filename, "a")) == NULL) + { + syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, + strerror(errno)); + + if (FatalErrors & CUPSD_FATAL_LOG) + cupsdEndProcess(getpid(), 0); + + return (0); + } + + /* + * Change ownership and permissions of non-device logs... + */ + + fchown(cupsFileNumber(*lf), RunUser, Group); + fchmod(cupsFileNumber(*lf), LogFilePerm); + } + + return (1); +} + + +/* + * 'format_log_line()' - Format a line for a log file. + * + * This function resizes a global string buffer as needed. Each call returns + * a pointer to this buffer, so the contents are only good until the next call + * to format_log_line()... + */ + +static int /* O - -1 for fatal, 0 for retry, 1 for success */ +format_log_line(const char *message, /* I - Printf-style format string */ + va_list ap) /* I - Argument list */ +{ + int len; /* Length of formatted line */ + + + /* + * Allocate the line buffer as needed... + */ + + if (!log_linesize) + { + log_linesize = 8192; + log_line = malloc(log_linesize); + + if (!log_line) + return (-1); + } + + /* + * Format the log message... + */ + + len = vsnprintf(log_line, log_linesize, message, ap); + + /* + * Resize the buffer as needed... + */ + + if (len >= log_linesize && log_linesize < 65536) + { + char *temp; /* Temporary string pointer */ + + + len ++; + + if (len < 8192) + len = 8192; + else if (len > 65536) + len = 65536; + + temp = realloc(log_line, len); + + if (temp) + { + log_line = temp; + log_linesize = len; + + return (0); + } + } + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/main.c b/scheduler/main.c new file mode 100644 index 0000000000..86d4e8034d --- /dev/null +++ b/scheduler/main.c @@ -0,0 +1,2206 @@ +/* + * "$Id$" + * + * Main loop for the CUPS scheduler. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for the CUPS scheduler. + * cupsdCheckProcess() - Tell the main loop to check for dead children. + * cupsdClosePipe() - Close a pipe as necessary. + * cupsdOpenPipe() - Create a pipe which is closed on exec. + * cupsdClearString() - Clear a string. + * cupsdHoldSignals() - Hold child and termination signals. + * cupsdReleaseSignals() - Release signals for delivery. + * cupsdSetString() - Set a string value. + * cupsdSetStringf() - Set a formatted string value. + * cupsd_clean_files() - Clean out old files. + * launchd_checkin() - Check-in with launchd and collect the listening + * fds. + * launchd_checkout() - Update the launchd KeepAlive file as needed. + * parent_handler() - Catch USR1/CHLD signals... + * process_children() - Process all dead children... + * select_timeout() - Calculate the select timeout value. + * 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 +#include +#include +#include +#include + +#ifdef HAVE_LAUNCH_H +# include +# include +# define CUPS_KEEPALIVE CUPS_CACHEDIR "/org.cups.cupsd" + /* Name of the launchd KeepAlive file */ +# ifndef LAUNCH_JOBKEY_KEEPALIVE +# define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" +# endif /* !LAUNCH_JOBKEY_KEEPALIVE */ +# ifndef LAUNCH_JOBKEY_PATHSTATE +# define LAUNCH_JOBKEY_PATHSTATE "PathState" +# endif /* !LAUNCH_JOBKEY_PATHSTATE */ +# ifndef LAUNCH_JOBKEY_SERVICEIPC +# define LAUNCH_JOBKEY_SERVICEIPC "ServiceIPC" +# endif /* !LAUNCH_JOBKEY_SERVICEIPC */ +#endif /* HAVE_LAUNCH_H */ + +#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO) +# include +#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */ +#ifdef HAVE_NOTIFY_H +# include +#endif /* HAVE_NOTIFY_H */ + +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) +# include +#endif /* __APPLE__ && HAVE_DLFCN_H */ + + +/* + * Local functions... + */ + +static void cupsd_clean_files(const char *path, + const char *pattern); +#ifdef HAVE_LAUNCHD +static void launchd_checkin(void); +static void launchd_checkout(void); +#endif /* HAVE_LAUNCHD */ +static void parent_handler(int sig); +static void process_children(void); +static void sigchld_handler(int sig); +static void sighup_handler(int sig); +static void sigterm_handler(int sig); +static long select_timeout(int fds); +static void usage(int status); + + +/* + * Local globals... + */ + +static int parent_signal = 0; + /* Set to signal number from child */ +static int holdcount = 0; /* Number of times "hold" was called */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) +static sigset_t holdmask; /* Old POSIX signal mask */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ +static int dead_children = 0; + /* Dead children? */ +static int stop_scheduler = 0; + /* Should the scheduler stop? */ + +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) +static const char *PSQLibPath = "/usr/lib/libPrintServiceQuota.dylib"; +static const char *PSQLibFuncName = "PSQUpdateQuota"; +static void *PSQLibRef; /* libPrintServiceQuota.dylib */ +#endif /* HAVE_DLFCN_H */ + + +/* + * 'main()' - Main entry for the CUPS scheduler. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + char *opt; /* Option character */ + int fg; /* Run in the foreground */ + int fds; /* Number of ready descriptors */ + cupsd_client_t *con; /* Current client */ + cupsd_job_t *job; /* Current job */ + cupsd_listener_t *lis; /* Current listener */ + time_t current_time, /* Current time */ + activity, /* Client activity timer */ + browse_time, /* Next browse send time */ + senddoc_time, /* Send-Document time */ + expire_time, /* Subscription expire time */ + report_time, /* Malloc/client/job report time */ + event_time; /* Last event notification time */ + long timeout; /* Timeout for cupsdDoSelect() */ + 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 + cups_file_t *fp; /* Fake lpsched lock file */ + struct stat statbuf; /* Needed for checking lpsched FIFO */ +#endif /* __sgi */ + int run_as_child = 0; + /* Needed for background fork/exec */ +#ifdef __APPLE__ + int use_sysman = !getuid(); + /* Use system management functions? */ +#else + time_t netif_time = 0; /* Time since last network update */ +#endif /* __APPLE__ */ +#if HAVE_LAUNCHD + int launchd_idle_exit; + /* Idle exit on select timeout? */ +#endif /* HAVE_LAUNCHD */ + + +#ifdef HAVE_GETEUID + /* + * Check for setuid invocation, which we do not support! + */ + + if (getuid() != geteuid()) + { + fputs("cupsd: Cannot run as a setuid program!\n", stderr); + return (1); + } +#endif /* HAVE_GETEUID */ + + /* + * Check for command-line arguments... + */ + + fg = 0; + +#ifdef HAVE_LAUNCHD + if (getenv("CUPSD_LAUNCHD")) + { + Launchd = 1; + fg = 1; + } +#endif /* HAVE_LAUNCHD */ + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + for (opt = argv[i] + 1; *opt != '\0'; opt ++) + switch (*opt) + { + case 'C' : /* Run as child with config file */ + run_as_child = 1; + fg = -1; + + case 'c' : /* Configuration file */ + i ++; + if (i >= argc) + { + _cupsLangPuts(stderr, _("cupsd: Expected config filename " + "after \"-c\" option!\n")); + usage(1); + } + + if (argv[i][0] == '/') + { + /* + * Absolute directory... + */ + + cupsdSetString(&ConfigurationFile, argv[i]); + } + else + { + /* + * Relative directory... + */ + + char *current; /* Current directory */ + + + /* + * Allocate a buffer for the current working directory to + * reduce run-time stack usage; this approximates the + * behavior of some implementations of getcwd() when they + * are passed a NULL pointer. + */ + + if ((current = malloc(1024)) == NULL) + { + _cupsLangPuts(stderr, + _("cupsd: Unable to get current directory!\n")); + return (1); + } + + if (!getcwd(current, 1024)) + { + _cupsLangPuts(stderr, + _("cupsd: Unable to get current directory!\n")); + free(current); + return (1); + } + + cupsdSetStringf(&ConfigurationFile, "%s/%s", current, argv[i]); + free(current); + } + break; + + case 'f' : /* Run in foreground... */ + fg = 1; + break; + + case 'F' : /* Run in foreground, but disconnect from terminal... */ + fg = -1; + break; + + case 'h' : /* Show usage/help */ + usage(0); + break; + + case 'l' : /* Started by launchd... */ +#ifdef HAVE_LAUNCHD + Launchd = 1; + fg = 1; +#else + _cupsLangPuts(stderr, _("cupsd: launchd(8) support not compiled " + "in, running in normal mode.\n")); + fg = 0; +#endif /* HAVE_LAUNCHD */ + break; + + case 'p' : /* Stop immediately for profiling */ + fputs("cupsd: -p (startup profiling) is for internal testing " + "use only!\n", stderr); + stop_scheduler = 1; + fg = 1; + break; + + case 'P' : /* Disable security profiles */ + fputs("cupsd: -P (disable security profiles) is for internal " + "testing use only!\n", stderr); + UseProfiles = 0; + break; + +#ifdef __APPLE__ + case 'S' : /* Disable system management functions */ + fputs("cupsd: -S (disable system management) for internal " + "testing use only!\n", stderr); + use_sysman = 0; + break; +#endif /* __APPLE__ */ + + case 't' : /* Test the cupsd.conf file... */ + TestConfigFile = 1; + fg = 1; + break; + + default : /* Unknown option */ + _cupsLangPrintf(stderr, _("cupsd: Unknown option \"%c\" - " + "aborting!\n"), *opt); + usage(1); + break; + } + else + { + _cupsLangPrintf(stderr, _("cupsd: Unknown argument \"%s\" - aborting!\n"), + argv[i]); + usage(1); + } + + if (!ConfigurationFile) + cupsdSetString(&ConfigurationFile, CUPS_SERVERROOT "/cupsd.conf"); + + /* + * If the user hasn't specified "-f", run in the background... + */ + + if (!fg) + { + /* + * Setup signal handlers for the parent... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGUSR1, parent_handler); + sigset(SIGCHLD, parent_handler); + + sigset(SIGHUP, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGUSR1); + action.sa_handler = parent_handler; + sigaction(SIGUSR1, &action, NULL); + sigaction(SIGCHLD, &action, NULL); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGHUP, &action, NULL); +#else + signal(SIGUSR1, parent_handler); + signal(SIGCLD, parent_handler); + + signal(SIGHUP, SIG_IGN); +#endif /* HAVE_SIGSET */ + + if (fork() > 0) + { + /* + * OK, wait for the child to startup and send us SIGUSR1 or to crash + * and the OS send us SIGCHLD... We also need to ignore SIGHUP which + * might be sent by the init script to restart the scheduler... + */ + + for (; parent_signal == 0;) + sleep(1); + + if (parent_signal == SIGUSR1) + return (0); + + if (wait(&i) < 0) + { + perror("cupsd"); + return (1); + } + else if (WIFEXITED(i)) + { + fprintf(stderr, "cupsd: Child exited with status %d!\n", + WEXITSTATUS(i)); + return (2); + } + else + { + fprintf(stderr, "cupsd: Child exited on signal %d!\n", WTERMSIG(i)); + return (3); + } + } + +#ifdef __OpenBSD__ + /* + * Call _thread_sys_closefrom() so the child process doesn't reset the + * parent's file descriptors to be blocking. This is a workaround for a + * limitation of userland libpthread on OpenBSD. + */ + + _thread_sys_closefrom(0); +#endif /* __OpenBSD__ */ + + /* + * Since CoreFoundation and DBUS both create fork-unsafe data on execution of + * a program, and since this kind of really unfriendly behavior seems to be + * more common these days in system libraries, we need to re-execute the + * background cupsd with the "-C" option to avoid problems. Unfortunately, + * we also have to assume that argv[0] contains the name of the cupsd + * executable - there is no portable way to get the real pathname... + */ + + execlp(argv[0], argv[0], "-C", ConfigurationFile, (char *)0); + exit(errno); + } + + 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... + */ + + setsid(); + + /* + * Close all open files... + */ + + getrlimit(RLIMIT_NOFILE, &limit); + + for (i = 0; i < limit.rlim_cur && i < 1024; i ++) + close(i); + + /* + * Redirect stdin/out/err to /dev/null... + */ + + if ((i = open("/dev/null", O_RDONLY)) != 0) + { + dup2(i, 0); + close(i); + } + + if ((i = open("/dev/null", O_WRONLY)) != 1) + { + dup2(i, 1); + close(i); + } + + if ((i = open("/dev/null", O_WRONLY)) != 2) + { + dup2(i, 2); + close(i); + } +#endif /* DEBUG */ + } + + /* + * Set the timezone info... + */ + + tzset(); + +#ifdef LC_TIME + setlocale(LC_TIME, ""); +#endif /* LC_TIME */ + + /* + * Set the maximum number of files... + */ + + getrlimit(RLIMIT_NOFILE, &limit); + +#if !defined(HAVE_POLL) && !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE) + if (limit.rlim_max > FD_SETSIZE) + MaxFDs = FD_SETSIZE; + else +#endif /* !HAVE_POLL && !HAVE_EPOLL && !HAVE_KQUEUE */ +#ifdef RLIM_INFINITY + if (limit.rlim_max == RLIM_INFINITY) + MaxFDs = 16384; + else +#endif /* RLIM_INFINITY */ + MaxFDs = limit.rlim_max; + + limit.rlim_cur = MaxFDs; + + setrlimit(RLIMIT_NOFILE, &limit); + + cupsdStartSelect(); + + /* + * Read configuration... + */ + + if (!cupsdReadConfiguration()) + { + if (TestConfigFile) + printf("%s contains errors\n", ConfigurationFile); + else + syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!", + ConfigurationFile); + return (1); + } + else if (TestConfigFile) + { + printf("%s is OK\n", ConfigurationFile); + return (0); + } + + /* + * Clean out old temp files and printer cache data. + */ + + if (!strncmp(TempDir, RequestRoot, strlen(RequestRoot))) + cupsd_clean_files(TempDir, NULL); + + cupsd_clean_files(CacheDir, "*.ipp"); + +#if HAVE_LAUNCHD + if (Launchd) + { + /* + * If we were started by launchd get the listen sockets file descriptors... + */ + + launchd_checkin(); + launchd_checkout(); + } +#endif /* HAVE_LAUNCHD */ + +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) + /* + * Load Print Service quota enforcement library (X Server only) + */ + + PSQLibRef = dlopen(PSQLibPath, RTLD_LAZY); + + if (PSQLibRef) + PSQUpdateQuotaProc = dlsym(PSQLibRef, PSQLibFuncName); +#endif /* __APPLE__ && HAVE_DLFCN_H */ + + /* + * Startup the server... + */ + + httpInitialize(); + + cupsdStartServer(); + + /* + * Catch hangup and child signals and ignore broken pipes... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGCHLD, sigchld_handler); + 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, SIGTERM); + sigaddset(&action.sa_mask, SIGCHLD); + action.sa_handler = sigchld_handler; + sigaction(SIGCHLD, &action, NULL); + + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGHUP); + 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 + signal(SIGCLD, sigchld_handler); /* No, SIGCLD isn't a typo... */ + signal(SIGHUP, sighup_handler); + signal(SIGPIPE, SIG_IGN); + signal(SIGTERM, sigterm_handler); +#endif /* HAVE_SIGSET */ + +#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 = cupsFileOpen("/var/spool/lp/SCHEDLOCK", "w")) == NULL) + { + syslog(LOG_LPR, "Unable to create fake lpsched lock file " + "\"/var/spool/lp/SCHEDLOCK\"\' - %s!", + strerror(errno)); + } + else + { + fchmod(cupsFileNumber(fp), 0644); + fchown(cupsFileNumber(fp), User, Group); + + cupsFileClose(fp); + } +#endif /* __sgi */ + + /* + * Initialize authentication certificates... + */ + + cupsdInitCerts(); + + /* + * If we are running in the background, signal the parent process that + * we are up and running... + */ + + if (!fg || run_as_child) + { + /* + * Send a signal to the parent process, but only if the parent is + * not PID 1 (init). This avoids accidentally shutting down the + * system on OpenBSD if you CTRL-C the server before it is up... + */ + + i = getppid(); /* Save parent PID to avoid race condition */ + + if (i != 1) + kill(i, SIGUSR1); + } + +#ifdef __APPLE__ + /* + * Start power management framework... + */ + + if (use_sysman) + cupsdStartSystemMonitor(); +#endif /* __APPLE__ */ + + /* + * Send server-started event... + */ + +#ifdef HAVE_LAUNCHD + if (Launchd) + cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, + "Scheduler started via launchd."); + else +#endif /* HAVE_LAUNCHD */ + if (fg) + cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, + "Scheduler started in foreground."); + else + cupsdAddEvent(CUPSD_EVENT_SERVER_STARTED, NULL, NULL, + "Scheduler started in background."); + + /* + * Start any pending print jobs... + */ + + cupsdCheckJobs(); + + /* + * Loop forever... + */ + + current_time = time(NULL); + browse_time = current_time; + event_time = current_time; + expire_time = current_time; + fds = 1; + report_time = 0; + senddoc_time = current_time; + + while (!stop_scheduler) + { + /* + * Check if there are dead children to handle... + */ + + if (dead_children) + process_children(); + + /* + * Check if we need to load the server configuration file... + */ + + if (NeedReload) + { + /* + * Close any idle clients... + */ + + if (cupsArrayCount(Clients) > 0) + { + for (con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + con = (cupsd_client_t *)cupsArrayNext(Clients)) + if (con->http.state == HTTP_WAITING) + cupsdCloseClient(con); + else + con->http.keep_alive = HTTP_KEEPALIVE_OFF; + + cupsdPauseListening(); + } + + /* + * Restart if all clients are closed and all jobs finished, or + * if the reload timeout has elapsed... + */ + + if ((cupsArrayCount(Clients) == 0 && + (cupsArrayCount(PrintingJobs) == 0 || NeedReload != RELOAD_ALL)) || + (time(NULL) - ReloadTime) >= ReloadTimeout) + { + /* + * Shutdown the server... + */ + + DoingShutdown = 1; + + cupsdStopServer(); + + /* + * Read configuration... + */ + + if (!cupsdReadConfiguration()) + { + syslog(LOG_LPR, "Unable to read configuration file \'%s\' - exiting!", + ConfigurationFile); + break; + } + +#if HAVE_LAUNCHD + if (Launchd) + { + /* + * If we were started by launchd, get the listen socket file + * descriptors... + */ + + launchd_checkin(); + launchd_checkout(); + } +#endif /* HAVE_LAUNCHD */ + + /* + * Startup the server... + */ + + DoingShutdown = 0; + + cupsdStartServer(); + + /* + * Send a server-restarted event... + */ + + cupsdAddEvent(CUPSD_EVENT_SERVER_RESTARTED, NULL, NULL, + "Scheduler restarted."); + } + } + + /* + * Check for available input or ready output. If cupsdDoSelect() + * 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. + */ + + if ((timeout = select_timeout(fds)) > 1 && LastEvent) + timeout = 1; + +#if HAVE_LAUNCHD + /* + * If no other work is scheduled and we're being controlled by + * launchd then timeout after 'LaunchdTimeout' seconds of + * inactivity... + */ + + if (timeout == 86400 && Launchd && LaunchdTimeout && !NumPolled && + !cupsArrayCount(ActiveJobs) && + (!Browsing || + (!BrowseRemoteProtocols && + (!BrowseLocalProtocols || !cupsArrayCount(Printers))))) + { + timeout = LaunchdTimeout; + launchd_idle_exit = 1; + } + else + launchd_idle_exit = 0; +#endif /* HAVE_LAUNCHD */ + + if ((fds = cupsdDoSelect(timeout)) < 0) + { + /* + * Got an error from select! + */ + +#ifdef HAVE_DNSSD + cupsd_printer_t *p; /* Current printer */ +#endif /* HAVE_DNSSD */ + + + if (errno == EINTR) /* Just interrupted by a signal */ + continue; + + /* + * Log all sorts of debug info to help track down the problem. + */ + + cupsdLogMessage(CUPSD_LOG_EMERG, "cupsdDoSelect() failed - %s!", + strerror(errno)); + + for (i = 0, con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + i ++, con = (cupsd_client_t *)cupsArrayNext(Clients)) + cupsdLogMessage(CUPSD_LOG_EMERG, + "Clients[%d] = %d, file = %d, state = %d", + i, con->http.fd, con->file, con->http.state); + + for (i = 0, lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + i ++, lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + cupsdLogMessage(CUPSD_LOG_EMERG, "Listeners[%d] = %d", i, lis->fd); + + cupsdLogMessage(CUPSD_LOG_EMERG, "BrowseSocket = %d", BrowseSocket); + + cupsdLogMessage(CUPSD_LOG_EMERG, "CGIPipes[0] = %d", CGIPipes[0]); + +#ifdef __APPLE__ + cupsdLogMessage(CUPSD_LOG_EMERG, "SysEventPipes[0] = %d", + SysEventPipes[0]); +#endif /* __APPLE__ */ + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + cupsdLogMessage(CUPSD_LOG_EMERG, "Jobs[%d] = %d < [%d %d] > [%d %d]", + job->id, + job->status_buffer ? job->status_buffer->fd : -1, + job->print_pipes[0], job->print_pipes[1], + job->back_pipes[0], job->back_pipes[1]); + +#ifdef HAVE_DNSSD + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + cupsdLogMessage(CUPSD_LOG_EMERG, "printer[%s] reg_name=\"%s\"", p->name, + p->reg_name ? p->reg_name : "(null)"); +#endif /* HAVE_DNSSD */ + + break; + } + + current_time = time(NULL); + + /* + * Write dirty config/state files... + */ + + if (DirtyCleanTime && current_time >= DirtyCleanTime) + cupsdCleanDirty(); + +#ifdef __APPLE__ + /* + * If we are going to sleep and still have pending jobs, stop them after + * a period of time... + */ + + if (SleepJobs > 0 && current_time >= SleepJobs && + cupsArrayCount(PrintingJobs) > 0) + { + SleepJobs = 0; + cupsdStopAllJobs(CUPSD_JOB_DEFAULT, 10); + } +#endif /* __APPLE__ */ + +#ifndef __APPLE__ + /* + * Update the network interfaces once a minute... + */ + + if ((current_time - netif_time) >= 60) + { + netif_time = current_time; + NetIFUpdate = 1; + } +#endif /* !__APPLE__ */ + +#if HAVE_LAUNCHD + /* + * If no other work was scheduled and we're being controlled by launchd + * then timeout after 'LaunchdTimeout' seconds of inactivity... + */ + + if (!fds && launchd_idle_exit) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "Printer sharing is off and there are no jobs pending, " + "will restart on demand."); + stop_scheduler = 1; + break; + } +#endif /* HAVE_LAUNCHD */ + + /* + * Resume listening for new connections as needed... + */ + + if (ListeningPaused && ListeningPaused <= current_time && + cupsArrayCount(Clients) < MaxClients) + cupsdResumeListening(); + + /* + * Expire subscriptions and unload completed jobs as needed... + */ + + if (current_time > expire_time) + { + if (cupsArrayCount(Subscriptions) > 0) + cupsdExpireSubscriptions(NULL, NULL); + + cupsdUnloadCompletedJobs(); + + expire_time = current_time; + } + + /* + * Update the browse list as needed... + */ + + if (Browsing) + { +#ifdef HAVE_LIBSLP + if ((BrowseRemoteProtocols & BROWSE_SLP) && + BrowseSLPRefresh <= current_time) + cupsdUpdateSLPBrowse(); +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if ((BrowseRemoteProtocols & BROWSE_LDAP) && + BrowseLDAPRefresh <= current_time) + cupsdUpdateLDAPBrowse(); +#endif /* HAVE_LDAP */ + } + + if (Browsing && current_time > browse_time) + { + cupsdSendBrowseList(); + browse_time = current_time; + } + + /* + * Update the root certificate once every 5 minutes if we have client + * connections... + */ + + if ((current_time - RootCertTime) >= RootCertDuration && RootCertDuration && + !RunUser && cupsArrayCount(Clients)) + { + /* + * Update the root certificate... + */ + + cupsdDeleteCert(0); + cupsdAddCert(0, "root", NULL); + } + + /* + * Check for new data on the client sockets... + */ + + for (con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + con = (cupsd_client_t *)cupsArrayNext(Clients)) + { + /* + * Process pending data in the input buffer... + */ + + if (con->http.used) + { + cupsdReadClient(con); + continue; + } + + /* + * Check the activity and close old clients... + */ + + activity = current_time - Timeout; + if (con->http.activity < activity && !con->pipe_pid) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Closing client %d after %d seconds of inactivity...", + con->http.fd, Timeout); + + cupsdCloseClient(con); + continue; + } + } + + /* + * Update any pending multi-file documents... + */ + + if ((current_time - senddoc_time) >= 10) + { + cupsdCheckJobs(); + cupsdCleanJobs(); + senddoc_time = current_time; + } + + /* + * Log statistics at most once a minute when in debug mode... + */ + + if ((current_time - report_time) >= 60 && LogLevel >= CUPSD_LOG_DEBUG) + { + size_t string_count, /* String count */ + alloc_bytes, /* Allocated string bytes */ + total_bytes; /* Total string bytes */ +#ifdef HAVE_MALLINFO + struct mallinfo mem; /* Malloc information */ + + + mem = mallinfo(); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-arena=%lu", mem.arena); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-used=%lu", + mem.usmblks + mem.uordblks); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: malloc-free=%lu", + mem.fsmblks + mem.fordblks); +#endif /* HAVE_MALLINFO */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: clients=%d", + cupsArrayCount(Clients)); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs=%d", + cupsArrayCount(Jobs)); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: jobs-active=%d", + cupsArrayCount(ActiveJobs)); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers=%d", + cupsArrayCount(Printers)); + cupsdLogMessage(CUPSD_LOG_DEBUG, "Report: printers-implicit=%d", + cupsArrayCount(ImplicitPrinters)); + + string_count = _cupsStrStatistics(&alloc_bytes, &total_bytes); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Report: stringpool-string-count=" CUPS_LLFMT, + CUPS_LLCAST string_count); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Report: stringpool-alloc-bytes=" CUPS_LLFMT, + CUPS_LLCAST alloc_bytes); + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Report: stringpool-total-bytes=" CUPS_LLFMT, + CUPS_LLCAST total_bytes); + + report_time = current_time; + } + + /* + * Handle OS-specific event notification for any events that have + * accumulated. Don't send these more than once a second... + */ + + if (LastEvent && (current_time - event_time) >= 1) + { +#ifdef HAVE_NOTIFY_POST + if (LastEvent & (CUPSD_EVENT_PRINTER_ADDED | + CUPSD_EVENT_PRINTER_DELETED | + CUPSD_EVENT_PRINTER_MODIFIED)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "notify_post(\"com.apple.printerListChange\")"); + notify_post("com.apple.printerListChange"); + } + + if (LastEvent & CUPSD_EVENT_PRINTER_STATE_CHANGED) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "notify_post(\"com.apple.printerHistoryChange\")"); + notify_post("com.apple.printerHistoryChange"); + } + + if (LastEvent & (CUPSD_EVENT_JOB_STATE_CHANGED | + CUPSD_EVENT_JOB_CONFIG_CHANGED | + CUPSD_EVENT_JOB_PROGRESS)) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "notify_post(\"com.apple.jobChange\")"); + notify_post("com.apple.jobChange"); + } +#endif /* HAVE_NOTIFY_POST */ + + /* + * Reset the accumulated events... + */ + + LastEvent = CUPSD_EVENT_NONE; + event_time = current_time; + } + } + + /* + * Log a message based on what happened... + */ + + if (stop_scheduler) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Scheduler shutting down normally."); + cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL, + "Scheduler shutting down normally."); + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Scheduler shutting down due to program error."); + cupsdAddEvent(CUPSD_EVENT_SERVER_STOPPED, NULL, NULL, + "Scheduler shutting down due to program error."); + } + + /* + * Close all network clients... + */ + + DoingShutdown = 1; + + cupsdStopServer(); + +#ifdef HAVE_LAUNCHD + /* + * Update the launchd KeepAlive file as needed... + */ + + if (Launchd) + launchd_checkout(); +#endif /* HAVE_LAUNCHD */ + + /* + * Stop all jobs... + */ + + cupsdFreeAllJobs(); + +#ifdef __APPLE__ + /* + * Stop monitoring system event monitoring... + */ + + if (use_sysman) + cupsdStopSystemMonitor(); +#endif /* __APPLE__ */ + +#ifdef HAVE_GSSAPI + /* + * Free the scheduler's Kerberos context... + */ + +# ifdef __APPLE__ + /* + * If the weak-linked GSSAPI/Kerberos library is not present, don't try + * to use it... + */ + + if (krb5_init_context != NULL) +# endif /* __APPLE__ */ + if (KerberosContext) + krb5_free_context(KerberosContext); +#endif /* HAVE_GSSAPI */ + +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) + /* + * Unload Print Service quota enforcement library (X Server only) + */ + + PSQUpdateQuotaProc = NULL; + if (PSQLibRef) + { + dlclose(PSQLibRef); + PSQLibRef = NULL; + } +#endif /* __APPLE__ && HAVE_DLFCN_H */ + +#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 */ + + cupsdStopSelect(); + + return (!stop_scheduler); +} + + +/* + * 'cupsdCheckProcess()' - Tell the main loop to check for dead children. + */ + +void +cupsdCheckProcess(void) +{ + /* + * Flag that we have dead children... + */ + + dead_children = 1; +} + + +/* + * 'cupsdClosePipe()' - Close a pipe as necessary. + */ + +void +cupsdClosePipe(int *fds) /* I - Pipe file descriptors (2) */ +{ + /* + * Close file descriptors as needed... + */ + + if (fds[0] >= 0) + { + close(fds[0]); + fds[0] = -1; + } + + if (fds[1] >= 0) + { + close(fds[1]); + fds[1] = -1; + } +} + + +/* + * 'cupsdOpenPipe()' - Create a pipe which is closed on exec. + */ + +int /* O - 0 on success, -1 on error */ +cupsdOpenPipe(int *fds) /* O - Pipe file descriptors (2) */ +{ + /* + * Create the pipe... + */ + + if (pipe(fds)) + { + fds[0] = -1; + fds[1] = -1; + + return (-1); + } + + /* + * Set the "close on exec" flag on each end of the pipe... + */ + + if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) + { + close(fds[0]); + close(fds[1]); + + fds[0] = -1; + fds[1] = -1; + + return (-1); + } + + if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) + { + close(fds[0]); + close(fds[1]); + + fds[0] = -1; + fds[1] = -1; + + return (-1); + } + + /* + * Return 0 indicating success... + */ + + return (0); +} + + +/* + * 'cupsdClearString()' - Clear a string. + */ + +void +cupsdClearString(char **s) /* O - String value */ +{ + if (s && *s) + { + _cupsStrFree(*s); + *s = NULL; + } +} + + +/* + * 'cupsdHoldSignals()' - Hold child and termination signals. + */ + +void +cupsdHoldSignals(void) +{ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + sigset_t newmask; /* New POSIX signal mask */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + holdcount ++; + if (holdcount > 1) + return; + +#ifdef HAVE_SIGSET + sighold(SIGTERM); + sighold(SIGCHLD); +#elif defined(HAVE_SIGACTION) + sigemptyset(&newmask); + sigaddset(&newmask, SIGTERM); + sigaddset(&newmask, SIGCHLD); + sigprocmask(SIG_BLOCK, &newmask, &holdmask); +#endif /* HAVE_SIGSET */ +} + + +/* + * 'cupsdReleaseSignals()' - Release signals for delivery. + */ + +void +cupsdReleaseSignals(void) +{ + holdcount --; + if (holdcount > 0) + return; + +#ifdef HAVE_SIGSET + sigrelse(SIGTERM); + sigrelse(SIGCHLD); +#elif defined(HAVE_SIGACTION) + sigprocmask(SIG_SETMASK, &holdmask, NULL); +#endif /* HAVE_SIGSET */ +} + + +/* + * 'cupsdSetString()' - Set a string value. + */ + +void +cupsdSetString(char **s, /* O - New string */ + const char *v) /* I - String value */ +{ + if (!s || *s == v) + return; + + if (*s) + _cupsStrFree(*s); + + if (v) + *s = _cupsStrAlloc(v); + else + *s = NULL; +} + + +/* + * 'cupsdSetStringf()' - Set a formatted string value. + */ + +void +cupsdSetStringf(char **s, /* O - New string */ + const char *f, /* I - Printf-style format string */ + ...) /* I - Additional args as needed */ +{ + char v[4096]; /* Formatting string value */ + va_list ap; /* Argument pointer */ + char *olds; /* Old string */ + + + if (!s) + return; + + olds = *s; + + if (f) + { + va_start(ap, f); + vsnprintf(v, sizeof(v), f, ap); + va_end(ap); + + *s = _cupsStrAlloc(v); + } + else + *s = NULL; + + if (olds) + _cupsStrFree(olds); +} + + +/* + * 'cupsd_clean_files()' - Clean out old files. + */ + +static void +cupsd_clean_files(const char *path, /* I - Directory to clean */ + const char *pattern) /* I - Filename pattern or NULL */ +{ + cups_dir_t *dir; /* Directory */ + cups_dentry_t *dent; /* Directory entry */ + char filename[1024]; /* Filename */ + int status; /* Status from unlink/rmdir */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsd_clean_files(path=\"%s\", pattern=\"%s\")", path, + pattern ? pattern : "(null)"); + + if ((dir = cupsDirOpen(path)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open directory \"%s\" - %s", + path, strerror(errno)); + return; + } + + cupsdLogMessage(CUPSD_LOG_INFO, "Cleaning out old files in \"%s\"...", path); + + while ((dent = cupsDirRead(dir)) != NULL) + { + if (pattern && fnmatch(pattern, dent->filename, 0)) + continue; + + snprintf(filename, sizeof(filename), "%s/%s", path, dent->filename); + + if (S_ISDIR(dent->fileinfo.st_mode)) + { + cupsd_clean_files(filename, pattern); + + status = rmdir(filename); + } + else + status = unlink(filename); + + if (status) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove \"%s\" - %s", filename, + strerror(errno)); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "Removed \"%s\"...", filename); + } + + cupsDirClose(dir); +} + + +#ifdef HAVE_LAUNCHD +/* + * 'launchd_checkin()' - Check-in with launchd and collect the listening fds. + */ + +static void +launchd_checkin(void) +{ + size_t i, /* Looping var */ + count; /* Number of listeners */ +# ifdef HAVE_SSL + int portnum; /* Port number */ +# endif /* HAVE_SSL */ + launch_data_t ld_msg, /* Launch data message */ + ld_resp, /* Launch data response */ + ld_array, /* Launch data array */ + ld_sockets, /* Launch data sockets dictionary */ + tmp; /* Launch data */ + cupsd_listener_t *lis; /* Listeners array */ + http_addr_t addr; /* Address variable */ + socklen_t addrlen; /* Length of address */ + int fd; /* File descriptor */ + char s[256]; /* String addresss */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid()); + + /* + * Check-in with launchd... + */ + + ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN); + if ((ld_resp = launch_msg(ld_msg)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN + "\") IPC failure"); + exit(EXIT_FAILURE); + return; /* anti-compiler-warning */ + } + + if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO) + { + errno = launch_data_get_errno(ld_resp); + cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Check-in failed: %s", + strerror(errno)); + exit(EXIT_FAILURE); + return; /* anti-compiler-warning */ + } + + /* + * Get the sockets dictionary... + */ + + if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS)) + == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: No sockets found to answer requests on!"); + exit(EXIT_FAILURE); + return; /* anti-compiler-warning */ + } + + /* + * Get the array of listener sockets... + */ + + if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: No sockets found to answer requests on!"); + exit(EXIT_FAILURE); + return; /* anti-compiler-warning */ + } + + /* + * Add listening fd(s) to the Listener array... + */ + + if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY) + { + count = launch_data_array_get_count(ld_array); + + for (i = 0; i < count; i ++) + { + /* + * Get the launchd file descriptor and address... + */ + + if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL) + { + fd = launch_data_get_fd(tmp); + addrlen = sizeof(addr); + + if (getsockname(fd, (struct sockaddr *)&addr, &addrlen)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: Unable to get local address - %s", + strerror(errno)); + continue; + } + + /* + * Try to match the launchd socket address to one of the listeners... + */ + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + if (httpAddrEqual(&lis->address, &addr)) + break; + + /* + * Add a new listener If there's no match... + */ + + if (lis) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "launchd_checkin: Matched existing listener %s with fd %d...", + httpAddrString(&(lis->address), s, sizeof(s)), fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "launchd_checkin: Adding new listener %s with fd %d...", + httpAddrString(&addr, s, sizeof(s)), fd); + + if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "launchd_checkin: Unable to allocate listener - " + "%s.", strerror(errno)); + exit(EXIT_FAILURE); + } + + cupsArrayAdd(Listeners, lis); + + memcpy(&lis->address, &addr, sizeof(lis->address)); + } + + lis->fd = fd; + +# ifdef HAVE_SSL + portnum = 0; + +# ifdef AF_INET6 + if (lis->address.addr.sa_family == AF_INET6) + portnum = ntohs(lis->address.ipv6.sin6_port); + else +# endif /* AF_INET6 */ + if (lis->address.addr.sa_family == AF_INET) + portnum = ntohs(lis->address.ipv4.sin_port); + + if (portnum == 443) + lis->encryption = HTTP_ENCRYPT_ALWAYS; +# endif /* HAVE_SSL */ + } + } + } + + launch_data_free(ld_msg); + launch_data_free(ld_resp); +} + + +/* + * 'launchd_checkout()' - Update the launchd KeepAlive file as needed. + */ + +static void +launchd_checkout(void) +{ + int fd; /* File descriptor */ + + + /* + * Create or remove the launchd KeepAlive file based on whether + * there are active jobs, polling, browsing for remote printers or + * shared printers to advertise... + */ + + if (cupsArrayCount(ActiveJobs) || NumPolled || + (Browsing && + (BrowseRemoteProtocols || + (BrowseLocalProtocols && cupsArrayCount(Printers))))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Creating launchd keepalive file \"" CUPS_KEEPALIVE + "\"..."); + + if ((fd = open(CUPS_KEEPALIVE, O_RDONLY | O_CREAT | O_EXCL, S_IRUSR)) >= 0) + close(fd); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Removing launchd keepalive file \"" CUPS_KEEPALIVE + "\"..."); + + unlink(CUPS_KEEPALIVE); + } +} +#endif /* HAVE_LAUNCHD */ + + +/* + * 'parent_handler()' - Catch USR1/CHLD signals... + */ + +static void +parent_handler(int sig) /* I - Signal */ +{ + /* + * Store the signal we got from the OS and return... + */ + + parent_signal = sig; +} + + +/* + * 'process_children()' - Process all dead children... + */ + +static void +process_children(void) +{ + int status; /* Exit status of child */ + int pid, /* Process ID of child */ + job_id; /* Job ID of child */ + cupsd_job_t *job; /* Current job */ + int i; /* Looping var */ + char name[1024]; /* Process name */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "process_children()"); + + /* + * Reset the dead_children flag... + */ + + dead_children = 0; + + /* + * Collect the exit status of some children... + */ + +#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 */ + { + /* + * Collect the name of the process that finished... + */ + + cupsdFinishProcess(pid, name, sizeof(name), &job_id); + + /* + * Delete certificates for CGI processes... + */ + + if (pid) + cupsdDeleteCert(pid); + + /* + * Handle completed job filters... + */ + + if (job_id > 0 && (job = cupsdFindJob(job_id)) != NULL) + { + for (i = 0; job->filters[i]; i ++) + if (job->filters[i] == pid) + break; + + if (job->filters[i] || job->backend == pid) + { + /* + * OK, this process has gone away; what's left? + */ + + if (job->filters[i]) + job->filters[i] = -pid; + else + job->backend = -pid; + + if (status && status != SIGTERM && status != SIGKILL && + status != SIGPIPE && 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->filters[i]) + job->status = status; /* Filter failed */ + else + job->status = -status; /* Backend failed */ + + if (job->state_value == IPP_JOB_PROCESSING && + job->status_level > CUPSD_LOG_ERROR) + { + char message[1024]; /* New printer-state-message */ + + + job->status_level = CUPSD_LOG_ERROR; + + snprintf(message, sizeof(message), "%s failed", name); + + if (job->printer) + { + strlcpy(job->printer->state_message, message, + sizeof(job->printer->state_message)); + cupsdAddPrinterHistory(job->printer); + } + + if (!job->attrs) + cupsdLoadJob(job); + + if (!job->printer_message && job->attrs) + { + if ((job->printer_message = + ippFindAttribute(job->attrs, "job-printer-state-message", + IPP_TAG_TEXT)) == NULL) + job->printer_message = ippAddString(job->attrs, IPP_TAG_JOB, + IPP_TAG_TEXT, + "job-printer-state-message", + NULL, NULL); + } + + if (job->printer_message) + cupsdSetString(&(job->printer_message->values[0].string.text), + message); + } + } + + /* + * If this is not the last file in a job, see if all of the + * filters are done, and if so move to the next file. + */ + + if (job->current_file < job->num_files && job->printer) + { + for (i = 0; job->filters[i] < 0; i ++); + + if (!job->filters[i]) + { + /* + * Process the next file... + */ + + cupsdContinueJob(job); + } + } + else if (job->state_value >= IPP_JOB_CANCELED) + { + /* + * Remove the job from the active list if there are no processes still + * running for it... + */ + + for (i = 0; job->filters[i] < 0; i++); + + if (!job->filters[i] && job->backend <= 0) + cupsArrayRemove(ActiveJobs, job); + } + } + } + + /* + * Show the exit status as needed, ignoring SIGTERM and SIGKILL errors + * since they come when we kill/end a process... + */ + + if (status == SIGTERM || status == SIGKILL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "PID %d (%s) was terminated normally with signal %d.", + pid, name, status); + } + else if (status == SIGPIPE) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "PID %d (%s) did not catch or ignore signal %d.", + pid, name, status); + } + else if (status) + { + if (WIFEXITED(status)) + cupsdLogMessage(CUPSD_LOG_DEBUG, "PID %d (%s) stopped with status %d!", + pid, name, WEXITSTATUS(status)); + else + cupsdLogMessage(CUPSD_LOG_ERROR, "PID %d (%s) crashed on signal %d!", + pid, name, WTERMSIG(status)); + + if (LogLevel < CUPSD_LOG_DEBUG) + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Try setting the LogLevel to \"debug\" to find " + "out more."); + } + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "PID %d (%s) exited with no errors.", + pid, name); + } + + /* + * If wait*() is interrupted by a signal, tell main() to call us again... + */ + + if (pid < 0 && errno == EINTR) + dead_children = 1; +} + + +/* + * 'select_timeout()' - Calculate the select timeout value. + * + */ + +static long /* O - Number of seconds */ +select_timeout(int fds) /* I - Number of descriptors returned */ +{ + long timeout; /* Timeout for select */ + time_t now; /* Current time */ + cupsd_client_t *con; /* Client information */ + cupsd_printer_t *p; /* Printer information */ + cupsd_job_t *job; /* Job information */ + cupsd_subscription_t *sub; /* Subscription information */ + const char *why; /* Debugging aid */ + + + /* + * Check to see if any of the clients have pending data to be + * processed; if so, the timeout should be 0... + */ + + for (con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + con = (cupsd_client_t *)cupsArrayNext(Clients)) + if (con->http.used > 0) + return (0); + + /* + * If select has been active in the last second (fds > 0) or we have + * many resources in use then don't bother trying to optimize the + * timeout, just make it 1 second. + */ + + if (fds > 0 || cupsArrayCount(Clients) > 50) + return (1); + + /* + * Otherwise, check all of the possible events that we need to wake for... + */ + + now = time(NULL); + timeout = now + 86400; /* 86400 == 1 day */ + why = "do nothing"; + +#ifdef __APPLE__ + /* + * When going to sleep, wake up to cancel jobs that don't complete in time. + */ + + if (SleepJobs > 0 && SleepJobs < timeout) + { + timeout = SleepJobs; + why = "cancel jobs before sleeping"; + } +#endif /* __APPLE__ */ + + /* + * Check whether we are accepting new connections... + */ + + if (ListeningPaused > 0 && cupsArrayCount(Clients) < MaxClients && + ListeningPaused < timeout) + { + if (ListeningPaused <= now) + timeout = now; + else + timeout = ListeningPaused; + + why = "resume listening"; + } + + /* + * Check the activity and close old clients... + */ + + for (con = (cupsd_client_t *)cupsArrayFirst(Clients); + con; + con = (cupsd_client_t *)cupsArrayNext(Clients)) + if ((con->http.activity + Timeout) < timeout) + { + timeout = con->http.activity + Timeout; + why = "timeout a client connection"; + } + + /* + * Update the browse list as needed... + */ + + if (Browsing && BrowseLocalProtocols) + { +#ifdef HAVE_LIBSLP + if ((BrowseLocalProtocols & BROWSE_SLP) && (BrowseSLPRefresh < timeout)) + { + timeout = BrowseSLPRefresh; + why = "update SLP browsing"; + } +#endif /* HAVE_LIBSLP */ + +#ifdef HAVE_LDAP + if ((BrowseLocalProtocols & BROWSE_LDAP) && (BrowseLDAPRefresh < timeout)) + { + timeout = BrowseLDAPRefresh; + why = "update LDAP browsing"; + } +#endif /* HAVE_LDAP */ + + if ((BrowseLocalProtocols & BROWSE_CUPS) && NumBrowsers) + { + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + if (p->type & CUPS_PRINTER_REMOTE) + { + if ((p->browse_time + BrowseTimeout) < timeout) + { + timeout = p->browse_time + BrowseTimeout; + why = "browse timeout a printer"; + } + } + else if (p->shared && !(p->type & CUPS_PRINTER_IMPLICIT)) + { + if (BrowseInterval && (p->browse_time + BrowseInterval) < timeout) + { + timeout = p->browse_time + BrowseInterval; + why = "send browse update"; + } + } + } + } + } + + /* + * Write out changes to configuration and state files... + */ + + if (DirtyCleanTime && timeout > DirtyCleanTime) + { + timeout = DirtyCleanTime; + why = "write dirty config/state files"; + } + + /* + * Check for any active jobs... + */ + + for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs); + job; + job = (cupsd_job_t *)cupsArrayNext(ActiveJobs)) + { + if (job->kill_time && job->kill_time < timeout) + { + timeout = job->kill_time; + why = "kill unresponsive jobs"; + } + + if (job->state_value == IPP_JOB_HELD && job->hold_until < timeout) + { + timeout = job->hold_until; + why = "release held jobs"; + } + else if (job->state_value == IPP_JOB_PENDING && timeout > (now + 10)) + { + timeout = now + 10; + why = "start pending jobs"; + break; + } + } + +#ifdef HAVE_MALLINFO + /* + * Log memory usage every minute... + */ + + if (LogLevel >= CUPSD_LOG_DEBUG && (mallinfo_time + 60) < timeout) + { + timeout = mallinfo_time + 60; + why = "display memory usage"; + } +#endif /* HAVE_MALLINFO */ + + /* + * Expire subscriptions as needed... + */ + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (!sub->job && sub->expire && sub->expire < timeout) + { + timeout = sub->expire; + why = "expire subscription"; + } + + /* + * Adjust from absolute to relative time. If p->browse_time above + * was 0 then we can end up with a negative value here, so check. + * We add 1 second to the timeout since events occur after the + * timeout expires, and limit the timeout to 86400 seconds (1 day) + * to avoid select() timeout limits present on some operating + * systems... + */ + + timeout = timeout - now + 1; + + if (timeout < 1) + timeout = 1; + else if (timeout > 86400) + timeout = 86400; + + /* + * Log and return the timeout value... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "select_timeout(%d): %ld seconds to %s", + fds, timeout, why); + + return (timeout); +} + + +/* + * 'sigchld_handler()' - Handle 'child' signals from old processes. + */ + +static void +sigchld_handler(int sig) /* I - Signal number */ +{ + (void)sig; + + /* + * Flag that we have dead children... + */ + + dead_children = 1; + + /* + * Reset the signal handler as needed... + */ + +#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) + signal(SIGCLD, sigchld_handler); +#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */ +} + + +/* + * 'sighup_handler()' - Handle 'hangup' signals to reconfigure the scheduler. + */ + +static void +sighup_handler(int sig) /* I - Signal number */ +{ + (void)sig; + + NeedReload = RELOAD_ALL; + ReloadTime = time(NULL); + +#if !defined(HAVE_SIGSET) && !defined(HAVE_SIGACTION) + signal(SIGHUP, sighup_handler); +#endif /* !HAVE_SIGSET && !HAVE_SIGACTION */ +} + + +/* + * 'sigterm_handler()' - Handle 'terminate' signals that stop the scheduler. + */ + +static void +sigterm_handler(int sig) /* I - Signal number */ +{ + (void)sig; /* remove compiler warnings... */ + + /* + * Flag that we should stop and return... + */ + + stop_scheduler = 1; +} + + +/* + * 'usage()' - Show scheduler usage. + */ + +static void +usage(int status) /* O - Exit status */ +{ + _cupsLangPuts(status ? stderr : stdout, + _("Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" + "\n" + "-c config-file Load alternate configuration file\n" + "-f Run in the foreground\n" + "-F Run in the foreground but detach\n" + "-h Show this usage message\n" + "-l Run cupsd from launchd(8)\n")); + exit(status); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/mime.c b/scheduler/mime.c new file mode 100644 index 0000000000..70dc7bf5d5 --- /dev/null +++ b/scheduler/mime.c @@ -0,0 +1,774 @@ +/* + * "$Id$" + * + * MIME database file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * mimeDelete() - Delete (free) a MIME database. + * mimeDeleteFilter() - Delete a filter from the MIME database. + * mimeDeleteType() - Delete a type from the MIME database. + * mimeFirstFilter() - Get the first filter in the MIME database. + * mimeFirstType() - Get the first type in the MIME database. + * mimeLoad() - Create a new MIME database from disk. + * mimeMerge() - Merge a MIME database from disk with the current one. + * mimeNew() - Create a new, empty MIME database. + * mimeNextFilter() - Get the next filter in the MIME database. + * mimeNextType() - Get the next type in the MIME database. + * mimeNumFilters() - Get the number of filters in a MIME database. + * mimeNumTypes() - Get the number of types in a MIME database. + * add_fcache() - Add a filter to the filter cache. + * compare_fcache() - Compare two filter cache entries. + * delete_fcache() - Free all memory used by the filter cache. + * delete_rules() - Free all memory for the given rule tree. + * load_convs() - Load a xyz.convs file... + * load_types() - Load a xyz.types file... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + +#include +#include +#include +#include "mime.h" + + +/* + * Local types... + */ + +typedef struct _mime_fcache_s /**** Filter cache structure ****/ +{ + char *name, /* Filter name */ + *path; /* Full path to filter if available */ +} _mime_fcache_t; + + +/* + * Local functions... + */ + +static const char *add_fcache(cups_array_t *filtercache, const char *name, + const char *filterpath); +static int compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b); +static void delete_fcache(cups_array_t *filtercache); +static void delete_rules(mime_magic_t *rules); +static void load_convs(mime_t *mime, const char *filename, + const char *filterpath, + cups_array_t *filtercache); +static void load_types(mime_t *mime, const char *filename); +static mime_t *mime_new(void); + + +/* + * 'mimeDelete()' - Delete (free) a MIME database. + */ + +void +mimeDelete(mime_t *mime) /* I - MIME database */ +{ + mime_type_t *type; /* Current type */ + mime_filter_t *filter; /* Current filter */ + + + if (!mime) + return; + + /* + * Loop through filters and free them... + */ + + for (filter = (mime_filter_t *)cupsArrayFirst(mime->filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(mime->filters)) + mimeDeleteFilter(mime, filter); + + /* + * Loop through the file types and delete any rules... + */ + + for (type = (mime_type_t *)cupsArrayFirst(mime->types); + type; + type = (mime_type_t *)cupsArrayNext(mime->types)) + mimeDeleteType(mime, type); + + /* + * Free the types and filters arrays, and then the MIME database structure. + */ + + cupsArrayDelete(mime->types); + cupsArrayDelete(mime->filters); + cupsArrayDelete(mime->srcs); + free(mime); +} + + +/* + * 'mimeDeleteFilter()' - Delete a filter from the MIME database. + */ + +void +mimeDeleteFilter(mime_t *mime, /* I - MIME database */ + mime_filter_t *filter) /* I - Filter */ +{ + if (!mime || !filter) + return; + + cupsArrayRemove(mime->filters, filter); + free(filter); + + /* + * Deleting a filter invalidates the source lookup cache used by + * mimeFilter()... + */ + + if (mime->srcs) + { + cupsArrayDelete(mime->srcs); + mime->srcs = NULL; + } +} + + +/* + * 'mimeDeleteType()' - Delete a type from the MIME database. + */ + +void +mimeDeleteType(mime_t *mime, /* I - MIME database */ + mime_type_t *mt) /* I - Type */ +{ + if (!mime || !mt) + return; + + cupsArrayRemove(mime->types, mt); + + delete_rules(mt->rules); + free(mt); +} + + +/* + * 'mimeFirstFilter()' - Get the first filter in the MIME database. + */ + +mime_filter_t * /* O - Filter or NULL */ +mimeFirstFilter(mime_t *mime) /* I - MIME database */ +{ + if (!mime) + return (NULL); + else + return ((mime_filter_t *)cupsArrayFirst(mime->filters)); +} + + +/* + * 'mimeFirstType()' - Get the first type in the MIME database. + */ + +mime_type_t * /* O - Type or NULL */ +mimeFirstType(mime_t *mime) /* I - MIME database */ +{ + if (!mime) + return (NULL); + else + return ((mime_type_t *)cupsArrayFirst(mime->types)); +} + + +/* + * 'mimeLoad()' - Create a new MIME database from disk. + * + * This function uses @link mimeLoadFilters@ and @link mimeLoadTypes@ to + * create a MIME database from a single directory. + */ + +mime_t * /* O - New MIME database */ +mimeLoad(const char *pathname, /* I - Directory to load */ + const char *filterpath) /* I - Directory to load */ +{ + return (mimeLoadFilters(mimeLoadTypes(NULL, pathname), pathname, filterpath)); +} + + +/* + * 'mimeLoadFilters()' - Load filter definitions from disk. + * + * This function loads all of the .convs files from the specified directory. + * Use @link mimeLoadTypes@ to load all types before you load the filters. + */ + +mime_t * /* O - MIME database */ +mimeLoadFilters(mime_t *mime, /* I - MIME database */ + const char *pathname, /* I - Directory to load from */ + const char *filterpath) /* I - Default filter program directory */ +{ + cups_dir_t *dir; /* Directory */ + cups_dentry_t *dent; /* Directory entry */ + char filename[1024]; /* Full filename of .convs file */ + cups_array_t *filtercache; /* Filter cache */ + + + /* + * Range check input... + */ + + if (!mime || !pathname || !filterpath) + return (mime); + + /* + * Then open the directory specified by pathname... + */ + + if ((dir = cupsDirOpen(pathname)) == NULL) + return (mime); + + /* + * Read all the .convs files... + */ + + filtercache = cupsArrayNew((cups_array_func_t)compare_fcache, NULL); + + while ((dent = cupsDirRead(dir)) != NULL) + { + if (strlen(dent->filename) > 6 && + !strcmp(dent->filename + strlen(dent->filename) - 6, ".convs")) + { + /* + * Load a mime.convs file... + */ + + snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); + load_convs(mime, filename, filterpath, filtercache); + } + } + + delete_fcache(filtercache); + + cupsDirClose(dir); + + return (mime); +} + + +/* + * 'mimeLoadTypes()' - Load type definitions from disk. + * + * This function loads all of the .types files from the specified directory. + * Use @link mimeLoadFilters@ to load all filters after you load the types. + */ + +mime_t * /* O - MIME database */ +mimeLoadTypes(mime_t *mime, /* I - MIME database or @code NULL@ to create a new one */ + const char *pathname) /* I - Directory to load from */ +{ + cups_dir_t *dir; /* Directory */ + cups_dentry_t *dent; /* Directory entry */ + char filename[1024]; /* Full filename of .types file */ + + + /* + * First open the directory specified by pathname... + */ + + if ((dir = cupsDirOpen(pathname)) == NULL) + return (mime); + + /* + * If "mime" is NULL, make a new, empty database... + */ + + if (!mime) + mime = mime_new(); + + if (!mime) + { + cupsDirClose(dir); + return (NULL); + } + + /* + * Read all the .types files... + */ + + while ((dent = cupsDirRead(dir)) != NULL) + { + if (strlen(dent->filename) > 6 && + !strcmp(dent->filename + strlen(dent->filename) - 6, ".types")) + { + /* + * Load a mime.types file... + */ + + snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); + load_types(mime, filename); + } + } + + cupsDirClose(dir); + + return (mime); +} + + +/* + * 'mimeNextFilter()' - Get the next filter in the MIME database. + */ + +mime_filter_t * /* O - Filter or NULL */ +mimeNextFilter(mime_t *mime) /* I - MIME database */ +{ + if (!mime) + return (NULL); + else + return ((mime_filter_t *)cupsArrayNext(mime->filters)); +} + + +/* + * 'mimeNextType()' - Get the next type in the MIME database. + */ + +mime_type_t * /* O - Type or NULL */ +mimeNextType(mime_t *mime) /* I - MIME database */ +{ + if (!mime) + return (NULL); + else + return ((mime_type_t *)cupsArrayNext(mime->types)); +} + + +/* + * 'mimeNumFilters()' - Get the number of filters in a MIME database. + */ + +int +mimeNumFilters(mime_t *mime) /* I - MIME database */ +{ + if (!mime) + return (0); + else + return (cupsArrayCount(mime->filters)); +} + + +/* + * 'mimeNumTypes()' - Get the number of types in a MIME database. + */ + +int +mimeNumTypes(mime_t *mime) /* I - MIME database */ +{ + if (!mime) + return (0); + else + return (cupsArrayCount(mime->types)); +} + + +/* + * 'add_fcache()' - Add a filter to the filter cache. + */ + +static const char * /* O - Full path to filter or NULL */ +add_fcache(cups_array_t *filtercache, /* I - Filter cache */ + const char *name, /* I - Filter name */ + const char *filterpath) /* I - Filter path */ +{ + _mime_fcache_t key, /* Search key */ + *temp; /* New filter cache */ + char path[1024]; /* Full path to filter */ + + + key.name = (char *)name; + if ((temp = (_mime_fcache_t *)cupsArrayFind(filtercache, &key)) != NULL) + return (temp->path); + + if ((temp = calloc(1, sizeof(_mime_fcache_t))) == NULL) + return (NULL); + + temp->name = strdup(name); + + if (cupsFileFind(name, filterpath, 1, path, sizeof(path))) + temp->path = strdup(path); + + cupsArrayAdd(filtercache, temp); + + return (temp->path); +} + + +/* + * 'compare_fcache()' - Compare two filter cache entries. + */ + +static int /* O - Result of comparison */ +compare_fcache(_mime_fcache_t *a, /* I - First entry */ + _mime_fcache_t *b) /* I - Second entry */ +{ + return (strcmp(a->name, b->name)); +} + + +/* + * 'delete_fcache()' - Free all memory used by the filter cache. + */ + +static void +delete_fcache(cups_array_t *filtercache)/* I - Filter cache */ +{ + _mime_fcache_t *current; /* Current cache entry */ + + + for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache); + current; + current = (_mime_fcache_t *)cupsArrayNext(filtercache)) + { + free(current->name); + + if (current->path) + free(current->path); + + free(current); + } + + cupsArrayDelete(filtercache); +} + + +/* + * '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; + } +} + + +/* + * '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 - Path for filters */ + cups_array_t *filtercache) /* I - Filter program cache */ +{ + cups_file_t *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 */ + + + DEBUG_printf(("load_convs(mime=%p, filename=\"%s\", filterpath=\"%s\", " + "filtercache=%p)\n", mime, filename, filterpath, filtercache)); + + + /* + * First try to open the file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + return; + + /* + * Then read each line from the file, skipping any comments in the file... + */ + + while (cupsFileGets(fp, line, sizeof(line)) != NULL) + { + /* + * Skip blank lines and lines starting with a #... + */ + + if (!line[0] || line[0] == '#') + continue; + + /* + * Strip trailing whitespace... + */ + + for (lineptr = line + strlen(line) - 1; + lineptr >= line && isspace(*lineptr & 255); + 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++ & 255); + + *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++ & 255); + + *temp = '\0'; + + if (*lineptr == '\0' || *lineptr == '\n') + continue; + + if ((dsttype = mimeType(mime, super, type)) == NULL) + { + DEBUG_printf(("load_convs: Destination type %s/%s not found!\n", + super, type)); + 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; + + if (strcmp(filter, "-")) + { + /* + * Verify that the filter exists and is executable... + */ + + if (!add_fcache(filtercache, filter, filterpath)) + { + DEBUG_printf(("load_convs: Filter %s not found in %s!\n", filter, + filterpath)); + continue; + } + } + + /* + * 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++ & 255); + + *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++ & 255); + + *temp = '\0'; + + if (!strcmp(super, "*") && !strcmp(type, "*")) + { + /* + * 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_type_t *)cupsArrayFirst(mime->types); + temptype; + temptype = (mime_type_t *)cupsArrayNext(mime->types)) + if ((super[0] == '*' || !strcmp(temptype->super, super)) && + (type[0] == '*' || !strcmp(temptype->type, type))) + mimeAddFilter(mime, temptype, dsttype, cost, filter); + } + + cupsFileClose(fp); +} + + +/* + * '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 */ +{ + cups_file_t *fp; /* Types file */ + int linelen; /* Length of line */ + char line[32768], /* 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 */ + + + DEBUG_printf(("load_types(mime=%p, filename=\"%s\")\n", mime, filename)); + + /* + * First try to open the file... + */ + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + return; + + /* + * Then read each line from the file, skipping any comments in the file... + */ + + while (cupsFileGets(fp, line, sizeof(line)) != NULL) + { + /* + * Skip blank lines and lines starting with a #... + */ + + if (!line[0] || line[0] == '#') + continue; + + /* + * While the last character in the line is a backslash, continue on to the + * next line (and the next, etc.) + */ + + linelen = strlen(line); + + while (line[linelen - 1] == '\\') + { + linelen --; + + if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL) + line[linelen] = '\0'; + else + linelen += strlen(line + linelen); + } + + /* + * 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++ & 255); + + *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++ & 255); + + *temp = '\0'; + + /* + * Add the type and rules to the MIME database... + */ + + typeptr = mimeAddType(mime, super, type); + mimeAddTypeRule(typeptr, lineptr); + } + + cupsFileClose(fp); +} + + +/* + * 'mime_new()' - Create a new, empty MIME database. + */ + +static mime_t * /* O - MIME database */ +mime_new(void) +{ + return ((mime_t *)calloc(1, sizeof(mime_t))); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/mime.h b/scheduler/mime.h new file mode 100644 index 0000000000..e8168c11ca --- /dev/null +++ b/scheduler/mime.h @@ -0,0 +1,151 @@ +/* + * "$Id$" + * + * MIME type/conversion database definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_MIME_H_ +# define _CUPS_MIME_H_ + +# include +# include +# include + + +/* + * 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 4096 /* 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_MAGIC_ISTRING /* Case-insensitive string matches */ +} mime_op_t; + +typedef struct _mime_magic_s /**** MIME Magic Data ****/ +{ + struct _mime_magic_s *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 */ + unsigned char charv; /* Byte value */ + unsigned short shortv; /* Short value */ + unsigned intv; /* Integer value */ + } value; +} mime_magic_t; + +typedef struct _mime_type_s /**** MIME Type Data ****/ +{ + mime_magic_t *rules; /* Rules used to detect this type */ + int priority; /* Priority of this type */ + char super[MIME_MAX_SUPER], /* Super-type name ("image", "application", etc.) */ + type[MIME_MAX_TYPE]; /* Type name ("png", "postscript", etc.) */ +} mime_type_t; + +typedef struct _mime_filter_s /**** 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_s /**** MIME Database ****/ +{ + cups_array_t *types; /* File types */ + cups_array_t *filters; /* Type conversion filters */ + cups_array_t *srcs; /* Filters sorted by source type */ +} mime_t; + + +/* + * Functions... + */ + +extern void mimeDelete(mime_t *mime); +extern mime_t *mimeLoad(const char *pathname, const char *filterpath); +extern mime_t *mimeLoadFilters(mime_t *mime, const char *pathname, + const char *filterpath); +extern mime_t *mimeLoadTypes(mime_t *mime, const char *pathname); + +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 void mimeDeleteType(mime_t *mime, mime_type_t *mt); +extern mime_type_t *mimeFileType(mime_t *mime, const char *pathname, + const char *filename, int *compression); +extern mime_type_t *mimeFirstType(mime_t *mime); +extern mime_type_t *mimeNextType(mime_t *mime); +extern int mimeNumTypes(mime_t *mime); +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 void mimeDeleteFilter(mime_t *mime, mime_filter_t *filter); +extern cups_array_t *mimeFilter(mime_t *mime, mime_type_t *src, + mime_type_t *dst, int *cost); +extern mime_filter_t *mimeFilterLookup(mime_t *mime, mime_type_t *src, + mime_type_t *dst); +extern mime_filter_t *mimeFirstFilter(mime_t *mime); +extern mime_filter_t *mimeNextFilter(mime_t *mime); +extern int mimeNumFilters(mime_t *mime); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_MIME_H_ */ + +/* + * End of "$Id$". + */ diff --git a/scheduler/network.c b/scheduler/network.c new file mode 100644 index 0000000000..766e464507 --- /dev/null +++ b/scheduler/network.c @@ -0,0 +1,305 @@ +/* + * "$Id$" + * + * Network interface functions for the CUPS scheduler. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdNetIFFind() - Find a network interface. + * cupsdNetIFFree() - Free the current network interface list. + * cupsdNetIFUpdate() - Update the network interface list as needed... + * compare_netif() - Compare two network interfaces. + */ + +/* + * Include necessary headers. + */ + +#include +#include "cupsd.h" + + +/* + * Local functions... + */ + +static void cupsdNetIFFree(void); +static int compare_netif(cupsd_netif_t *a, cupsd_netif_t *b); + + +/* + * 'cupsdNetIFFind()' - Find a network interface. + */ + +cupsd_netif_t * /* O - Network interface data */ +cupsdNetIFFind(const char *name) /* I - Name of interface */ +{ + cupsd_netif_t key; /* Search key */ + + + /* + * Update the interface list as needed... + */ + + if (NetIFUpdate) + cupsdNetIFUpdate(); + + /* + * Search for the named interface... + */ + + strlcpy(key.name, name, sizeof(key.name)); + + return ((cupsd_netif_t *)cupsArrayFind(NetIFList, &key)); +} + + +/* + * 'cupsdNetIFFree()' - Free the current network interface list. + */ + +static void +cupsdNetIFFree(void) +{ + cupsd_netif_t *current; /* Current interface in array */ + + + /* + * Loop through the interface list and free all the records... + */ + + for (current = (cupsd_netif_t *)cupsArrayFirst(NetIFList); + current; + current = (cupsd_netif_t *)cupsArrayNext(NetIFList)) + { + cupsArrayRemove(NetIFList, current); + free(current); + } +} + + +/* + * 'cupsdNetIFUpdate()' - Update the network interface list as needed... + */ + +void +cupsdNetIFUpdate(void) +{ + int match; /* Matching address? */ + cupsd_listener_t *lis; /* Listen address */ + cupsd_netif_t *temp; /* New interface */ + struct ifaddrs *addrs, /* Interface address list */ + *addr; /* Current interface address */ + char hostname[1024]; /* Hostname for address */ + size_t hostlen; /* Length of hostname */ + + + /* + * Only update the list if we need to... + */ + + if (!NetIFUpdate) + return; + + NetIFUpdate = 0; + + /* + * Free the old interfaces... + */ + + cupsdNetIFFree(); + + /* + * Make sure we have an array... + */ + + if (!NetIFList) + NetIFList = cupsArrayNew((cups_array_func_t)compare_netif, NULL); + + if (!NetIFList) + return; + + /* + * 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 or IPv6... + */ + + if (addr->ifa_addr == NULL || + (addr->ifa_addr->sa_family != AF_INET +#ifdef AF_INET6 + && addr->ifa_addr->sa_family != AF_INET6 +#endif + ) || + addr->ifa_netmask == NULL || addr->ifa_name == NULL) + continue; + + /* + * Try looking up the hostname for the address as needed... + */ + + if (HostNameLookups) + httpAddrLookup((http_addr_t *)(addr->ifa_addr), hostname, + sizeof(hostname)); + else + { + /* + * Map the default server address and localhost to the server name + * and localhost, respectively; for all other addresses, use the + * numeric address... + */ + + if (httpAddrLocalhost((http_addr_t *)(addr->ifa_addr))) + strcpy(hostname, "localhost"); + else + httpAddrString((http_addr_t *)(addr->ifa_addr), hostname, + sizeof(hostname)); + } + + /* + * Create a new address element... + */ + + hostlen = strlen(hostname); + if ((temp = calloc(1, sizeof(cupsd_netif_t) + hostlen)) == NULL) + break; + + /* + * Copy all of the information... + */ + + strlcpy(temp->name, addr->ifa_name, sizeof(temp->name)); + temp->hostlen = hostlen; + strcpy(temp->hostname, hostname); /* Safe because hostname is allocated */ + + if (addr->ifa_addr->sa_family == AF_INET) + { + /* + * Copy IPv4 addresses... + */ + + memcpy(&(temp->address), addr->ifa_addr, sizeof(struct sockaddr_in)); + memcpy(&(temp->mask), addr->ifa_netmask, sizeof(struct sockaddr_in)); + + if (addr->ifa_dstaddr) + memcpy(&(temp->broadcast), addr->ifa_dstaddr, + sizeof(struct sockaddr_in)); + } +#ifdef AF_INET6 + else + { + /* + * Copy IPv6 addresses... + */ + + memcpy(&(temp->address), addr->ifa_addr, sizeof(struct sockaddr_in6)); + memcpy(&(temp->mask), addr->ifa_netmask, sizeof(struct sockaddr_in6)); + + if (addr->ifa_dstaddr) + memcpy(&(temp->broadcast), addr->ifa_dstaddr, + sizeof(struct sockaddr_in6)); + } +#endif /* AF_INET6 */ + + if (!(addr->ifa_flags & IFF_POINTOPOINT) && + !httpAddrLocalhost(&(temp->address))) + temp->is_local = 1; + + /* + * Determine which port to use when advertising printers... + */ + + for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); + lis; + lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) + { + match = 0; + + if (httpAddrAny(&(lis->address))) + match = 1; + else if (addr->ifa_addr->sa_family == AF_INET && + lis->address.addr.sa_family == AF_INET && + (lis->address.ipv4.sin_addr.s_addr & + temp->mask.ipv4.sin_addr.s_addr) == + (temp->address.ipv4.sin_addr.s_addr & + temp->mask.ipv4.sin_addr.s_addr)) + match = 1; +#ifdef AF_INET6 + else if (addr->ifa_addr->sa_family == AF_INET6 && + lis->address.addr.sa_family == AF_INET6 && + (lis->address.ipv6.sin6_addr.s6_addr[0] & + temp->mask.ipv6.sin6_addr.s6_addr[0]) == + (temp->address.ipv6.sin6_addr.s6_addr[0] & + temp->mask.ipv6.sin6_addr.s6_addr[0]) && + (lis->address.ipv6.sin6_addr.s6_addr[1] & + temp->mask.ipv6.sin6_addr.s6_addr[1]) == + (temp->address.ipv6.sin6_addr.s6_addr[1] & + temp->mask.ipv6.sin6_addr.s6_addr[1]) && + (lis->address.ipv6.sin6_addr.s6_addr[2] & + temp->mask.ipv6.sin6_addr.s6_addr[2]) == + (temp->address.ipv6.sin6_addr.s6_addr[2] & + temp->mask.ipv6.sin6_addr.s6_addr[2]) && + (lis->address.ipv6.sin6_addr.s6_addr[3] & + temp->mask.ipv6.sin6_addr.s6_addr[3]) == + (temp->address.ipv6.sin6_addr.s6_addr[3] & + temp->mask.ipv6.sin6_addr.s6_addr[3])) + match = 1; +#endif /* AF_INET6 */ + + if (match) + { + if (lis->address.addr.sa_family == AF_INET) + temp->port = ntohs(lis->address.ipv4.sin_port); +#ifdef AF_INET6 + else if (lis->address.addr.sa_family == AF_INET6) + temp->port = ntohs(lis->address.ipv6.sin6_port); +#endif /* AF_INET6 */ + break; + } + } + + /* + * Add it to the array... + */ + + cupsArrayAdd(NetIFList, temp); + + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdNetIFUpdate: \"%s\" = %s:%d", + temp->name, temp->hostname, temp->port); + } + + freeifaddrs(addrs); +} + + +/* + * 'compare_netif()' - Compare two network interfaces. + */ + +static int /* O - Result of comparison */ +compare_netif(cupsd_netif_t *a, /* I - First network interface */ + cupsd_netif_t *b) /* I - Second network interface */ +{ + return (strcmp(a->name, b->name)); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/network.h b/scheduler/network.h new file mode 100644 index 0000000000..ea63e4bf0b --- /dev/null +++ b/scheduler/network.h @@ -0,0 +1,53 @@ +/* + * "$Id$" + * + * Network interface definitions for the Common UNIX Printing System + * (CUPS) scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Structures... + */ + +typedef struct cupsd_netif_s /**** Network interface data ****/ +{ + int is_local, /* Local (not point-to-point) interface? */ + port; /* Listen port */ + http_addr_t address, /* Network address */ + mask, /* Network mask */ + broadcast; /* Broadcast address */ + size_t hostlen; /* Length of hostname */ + char name[32], /* Network interface name */ + hostname[1]; /* Hostname associated with interface */ +} cupsd_netif_t; + + +/* + * Globals... + */ + +VAR int NetIFUpdate VALUE(1); + /* Network interface list needs updating */ +VAR cups_array_t *NetIFList VALUE(NULL); + /* Array of network interfaces */ + +/* + * Prototypes... + */ + +extern cupsd_netif_t *cupsdNetIFFind(const char *name); +extern void cupsdNetIFUpdate(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/policy.c b/scheduler/policy.c new file mode 100644 index 0000000000..cdb537e4c0 --- /dev/null +++ b/scheduler/policy.c @@ -0,0 +1,366 @@ +/* + * "$Id$" + * + * Policy routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddPolicy() - Add a policy to the system. + * cupsdAddPolicyOp() - Add an operation to a policy. + * cupsdCheckPolicy() - Check the IPP operation and username against + * a policy. + * cupsdDeleteAllPolicies() - Delete all policies in memory. + * cupsdFindPolicy() - Find a named policy. + * cupsdFindPolicyOp() - Find a policy operation. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + + +/* + * Local functions... + */ + +static int compare_ops(cupsd_location_t *a, cupsd_location_t *b); +static int compare_policies(cupsd_policy_t *a, cupsd_policy_t *b); +static int hash_op(cupsd_location_t *op); + + +/* + * 'AddPolicy()' - Add a policy to the system. + */ + +cupsd_policy_t * /* O - Policy */ +cupsdAddPolicy(const char *policy) /* I - Name of policy */ +{ + cupsd_policy_t *temp; /* Pointer to policy */ + + + if (!policy) + return (NULL); + + if (!Policies) + Policies = cupsArrayNew((cups_array_func_t)compare_policies, NULL); + + if (!Policies) + return (NULL); + + if ((temp = calloc(1, sizeof(cupsd_policy_t))) != NULL) + { + cupsdSetString(&temp->name, policy); + cupsArrayAdd(Policies, temp); + } + + return (temp); +} + + +/* + * 'cupsdAddPolicyOp()' - Add an operation to a policy. + */ + +cupsd_location_t * /* O - New policy operation */ +cupsdAddPolicyOp(cupsd_policy_t *p, /* I - Policy */ + cupsd_location_t *po, /* I - Policy operation to copy */ + ipp_op_t op) /* I - IPP operation code */ +{ + int i; /* Looping var */ + cupsd_location_t *temp; /* New policy operation */ + char name[1024]; /* Interface name */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPolicyOp(p=%p, po=%p, op=%x(%s))", + p, po, op, ippOpString(op)); + + if (!p) + return (NULL); + + if (!p->ops) + p->ops = cupsArrayNew2((cups_array_func_t)compare_ops, NULL, + (cups_ahash_func_t)hash_op, 128); + + if (!p->ops) + return (NULL); + + if ((temp = calloc(1, sizeof(cupsd_location_t))) != NULL) + { + temp->op = op; + temp->limit = CUPSD_AUTH_LIMIT_IPP; + + cupsArrayAdd(p->ops, temp); + + if (po) + { + /* + * Copy the specified policy to the new one... + */ + + temp->order_type = po->order_type; + temp->type = po->type; + temp->level = po->level; + temp->satisfy = po->satisfy; + temp->encryption = po->encryption; + + for (i = 0; i < po->num_names; i ++) + cupsdAddName(temp, po->names[i]); + + for (i = 0; i < po->num_allow; i ++) + switch (po->allow[i].type) + { + case CUPSD_AUTH_IP : + cupsdAllowIP(temp, po->allow[i].mask.ip.address, + po->allow[i].mask.ip.netmask); + break; + + case CUPSD_AUTH_INTERFACE : + snprintf(name, sizeof(name), "@IF(%s)", + po->allow[i].mask.name.name); + cupsdAllowHost(temp, name); + break; + + default : + cupsdAllowHost(temp, po->allow[i].mask.name.name); + break; + } + + for (i = 0; i < po->num_deny; i ++) + switch (po->deny[i].type) + { + case CUPSD_AUTH_IP : + cupsdDenyIP(temp, po->deny[i].mask.ip.address, + po->deny[i].mask.ip.netmask); + break; + + case CUPSD_AUTH_INTERFACE : + snprintf(name, sizeof(name), "@IF(%s)", + po->deny[i].mask.name.name); + cupsdDenyHost(temp, name); + break; + + default : + cupsdDenyHost(temp, po->deny[i].mask.name.name); + break; + } + } + } + + return (temp); +} + + +/* + * 'cupsdCheckPolicy()' - Check the IPP operation and username against a policy. + */ + +http_status_t /* I - 1 if OK, 0 otherwise */ +cupsdCheckPolicy(cupsd_policy_t *p, /* I - Policy */ + cupsd_client_t *con, /* I - Client connection */ + const char *owner) /* I - Owner of object */ +{ + cupsd_location_t *po; /* Current policy operation */ + + + /* + * Range check... + */ + + if (!p || !con) + { + cupsdLogMessage(CUPSD_LOG_CRIT, "cupsdCheckPolicy: p=%p, con=%p!", p, con); + + return ((http_status_t)0); + } + + /* + * Find a match for the operation... + */ + + if ((po = cupsdFindPolicyOp(p, con->request->request.op.operation_id)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCheckPolicy: No matching operation, returning 0!"); + return ((http_status_t)0); + } + + con->best = po; + + /* + * Return the status of the check... + */ + + return (cupsdIsAuthorized(con, owner)); +} + + +/* + * 'cupsdDeleteAllPolicies()' - Delete all policies in memory. + */ + +void +cupsdDeleteAllPolicies(void) +{ + cupsd_policy_t *p; /* Current policy */ + cupsd_location_t *po; /* Current policy op */ + cupsd_printer_t *printer; /* Current printer */ + + + if (!Policies) + return; + + /* + * First clear the policy pointers for all printers... + */ + + for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers); + printer; + printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + printer->op_policy_ptr = NULL; + + /* + * Then free all of the policies... + */ + + for (p = (cupsd_policy_t *)cupsArrayFirst(Policies); + p; + p = (cupsd_policy_t *)cupsArrayNext(Policies)) + { + for (po = (cupsd_location_t *)cupsArrayFirst(p->ops); + po; + po = (cupsd_location_t *)cupsArrayNext(p->ops)) + cupsdDeleteLocation(po); + + cupsArrayDelete(p->ops); + cupsdClearString(&p->name); + free(p); + } + + cupsArrayDelete(Policies); + + Policies = NULL; +} + + +/* + * 'cupsdFindPolicy()' - Find a named policy. + */ + +cupsd_policy_t * /* O - Policy */ +cupsdFindPolicy(const char *policy) /* I - Name of policy */ +{ + cupsd_policy_t key; /* Search key */ + + + /* + * Range check... + */ + + if (!policy) + return (NULL); + + /* + * Look it up... + */ + + key.name = (char *)policy; + return ((cupsd_policy_t *)cupsArrayFind(Policies, &key)); +} + + +/* + * 'cupsdFindPolicyOp()' - Find a policy operation. + */ + +cupsd_location_t * /* O - Policy operation */ +cupsdFindPolicyOp(cupsd_policy_t *p, /* I - Policy */ + ipp_op_t op) /* I - IPP operation */ +{ + cupsd_location_t key, /* Search key... */ + *po; /* Current policy operation */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp(p=%p, op=%x(%s))", + p, op, ippOpString(op)); + + /* + * Range check... + */ + + if (!p) + return (NULL); + + /* + * Check the operation against the available policies... + */ + + key.op = op; + if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdFindPolicyOp: Found exact match..."); + return (po); + } + + key.op = IPP_ANY_OPERATION; + if ((po = (cupsd_location_t *)cupsArrayFind(p->ops, &key)) != NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdFindPolicyOp: Found wildcard match..."); + return (po); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindPolicyOp: No match found!"); + + return (NULL); +} + + +/* + * 'compare_ops()' - Compare two operations. + */ + +static int /* O - Result of comparison */ +compare_ops(cupsd_location_t *a, /* I - First operation */ + cupsd_location_t *b) /* I - Second operation */ +{ + return (a->op - b->op); +} + + +/* + * 'compare_policies()' - Compare two policies. + */ + +static int /* O - Result of comparison */ +compare_policies(cupsd_policy_t *a, /* I - First policy */ + cupsd_policy_t *b) /* I - Second policy */ +{ + return (strcasecmp(a->name, b->name)); +} + + +/* + * 'hash_op()' - Generate a lookup hash for the operation. + */ + +static int /* O - Hash value */ +hash_op(cupsd_location_t *op) /* I - Operation */ +{ + return (((op->op >> 6) & 0x40) | (op->op & 0x3f)); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/policy.h b/scheduler/policy.h new file mode 100644 index 0000000000..e79617ec9c --- /dev/null +++ b/scheduler/policy.h @@ -0,0 +1,54 @@ +/* + * "$Id$" + * + * Policy definitions for the Common UNIX Printing System (CUPS) + * scheduler. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + + +/* + * Policy structure... + */ + +typedef struct +{ + char *name; /* Policy name */ + cups_array_t *ops; /* Operations */ +} cupsd_policy_t; + + +/* + * Globals... + */ + +VAR cups_array_t *Policies VALUE(NULL); + /* Policies */ + + +/* + * Prototypes... + */ + +extern cupsd_policy_t *cupsdAddPolicy(const char *policy); +extern cupsd_location_t *cupsdAddPolicyOp(cupsd_policy_t *p, + cupsd_location_t *po, + ipp_op_t op); +extern http_status_t cupsdCheckPolicy(cupsd_policy_t *p, cupsd_client_t *con, + const char *owner); +extern void cupsdDeleteAllPolicies(void); +extern cupsd_policy_t *cupsdFindPolicy(const char *policy); +extern cupsd_location_t *cupsdFindPolicyOp(cupsd_policy_t *p, ipp_op_t op); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/printers.c b/scheduler/printers.c new file mode 100644 index 0000000000..8ef4fe10bf --- /dev/null +++ b/scheduler/printers.c @@ -0,0 +1,5609 @@ +/* + * "$Id$" + * + * Printer routines for the CUPS scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddPrinter() - Add a printer to the system. + * cupsdAddPrinterHistory() - Add the current printer state to the history. + * cupsdAddPrinterUser() - Add a user to the ACL. + * cupsdCreateCommonData() - Create the common printer data. + * cupsdDeleteAllPrinters() - Delete all printers from the system. + * cupsdDeletePrinter() - Delete a printer from the system. + * cupsdFindDest() - Find a destination in the list. + * cupsdFindPrinter() - Find a printer in the list. + * cupsdFreePrinterUsers() - Free allow/deny users. + * cupsdLoadAllPrinters() - Load printers from the printers.conf file. + * cupsdRenamePrinter() - Rename a printer. + * cupsdSaveAllPrinters() - Save all printer definitions to the + * printers.conf file. + * cupsdSetAuthInfoRequired() - Set the required authentication info. + * cupsdSetDeviceURI() - Set the device URI for a printer. + * cupsdSetPrinterAttr() - Set a printer attribute. + * cupsdSetPrinterAttrs() - Set printer attributes based upon the PPD + * file. + * cupsdSetPrinterReasons() - Set/update the reasons strings. + * cupsdSetPrinterState() - Update the current state of a printer. + * cupsdStopPrinter() - Stop a printer from printing any jobs... + * cupsdUpdatePrinterPPD() - Update keywords in a printer's PPD file. + * cupsdUpdatePrinters() - Update printers after a partial reload. + * cupsdValidateDest() - Validate a printer/class destination. + * cupsdWritePrintcap() - Write a pseudo-printcap file for older + * applications that need it... + * add_printer_defaults() - Add name-default attributes to the printer + * attributes. + * add_printer_filter() - Add a MIME filter for a printer. + * add_printer_formats() - Add document-format-supported values for a + * printer. + * add_string_array() - Add a string to an array of CUPS strings. + * compare_printers() - Compare two printers. + * delete_printer_filters() - Delete all MIME filters for a printer. + * delete_string_array() - Delete an array of CUPS strings. + * dirty_printer() - Mark config and state files dirty for the + * specified printer. + * load_ppd() - Load a cached PPD file, updating the cache as + * needed. + * new_media_col() - Create a media-col collection value. + * 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. + * write_xml_string() - Write a string with XML escaping. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include +#ifdef HAVE_APPLICATIONSERVICES_H +# include +#endif /* HAVE_APPLICATIONSERVICES_H */ +#ifdef HAVE_SYS_MOUNT_H +# include +#endif /* HAVE_SYS_MOUNT_H */ +#ifdef HAVE_SYS_STATVFS_H +# include +#elif defined(HAVE_SYS_STATFS_H) +# include +#endif /* HAVE_SYS_STATVFS_H */ +#ifdef HAVE_SYS_VFS_H +# include +#endif /* HAVE_SYS_VFS_H */ + + +/* + * Local functions... + */ + +static void add_printer_defaults(cupsd_printer_t *p); +static void add_printer_filter(cupsd_printer_t *p, mime_type_t *type, + const char *filter); +static void add_printer_formats(cupsd_printer_t *p); +static void add_string_array(cups_array_t **a, const char *s); +static int compare_printers(void *first, void *second, void *data); +static void delete_printer_filters(cupsd_printer_t *p); +static void delete_string_array(cups_array_t **a); +static void dirty_printer(cupsd_printer_t *p); +static void load_ppd(cupsd_printer_t *p); +static ipp_t *new_media_col(_pwg_size_t *size, const char *source, + const char *type); +#ifdef __sgi +static void write_irix_config(cupsd_printer_t *p); +static void write_irix_state(cupsd_printer_t *p); +#endif /* __sgi */ +static void write_xml_string(cups_file_t *fp, const char *s); + + +/* + * 'cupsdAddPrinter()' - Add a printer to the system. + */ + +cupsd_printer_t * /* O - New printer */ +cupsdAddPrinter(const char *name) /* I - Name of printer */ +{ + cupsd_printer_t *p; /* New printer */ + char uri[1024]; /* Printer URI */ + + + /* + * Range check input... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPrinter(\"%s\")", name); + + /* + * Create a new printer entity... + */ + + if ((p = calloc(1, sizeof(cupsd_printer_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_CRIT, "Unable to allocate memory for printer - %s", + strerror(errno)); + return (NULL); + } + + cupsdSetString(&p->name, name); + cupsdSetString(&p->info, name); + cupsdSetString(&p->hostname, ServerName); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + ServerName, RemotePort, "/printers/%s", name); + cupsdSetString(&p->uri, uri); + cupsdSetDeviceURI(p, "file:///dev/null"); + + p->state = IPP_PRINTER_STOPPED; + p->state_time = time(NULL); + p->accepting = 0; + p->shared = DefaultShared; + p->filetype = mimeAddType(MimeDatabase, "printer", name); + + cupsdSetString(&p->job_sheets[0], "none"); + cupsdSetString(&p->job_sheets[1], "none"); + + cupsdSetString(&p->error_policy, ErrorPolicy); + cupsdSetString(&p->op_policy, DefaultPolicy); + + p->op_policy_ptr = DefaultPolicyPtr; + + if (MaxPrinterHistory) + p->history = calloc(MaxPrinterHistory, sizeof(ipp_t *)); + + /* + * Insert the printer in the printer list alphabetically... + */ + + if (!Printers) + Printers = cupsArrayNew(compare_printers, NULL); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddPrinter: Adding %s to Printers", p->name); + cupsArrayAdd(Printers, p); + + if (!ImplicitPrinters) + ImplicitPrinters = cupsArrayNew(compare_printers, NULL); + + /* + * Return the new printer... + */ + + return (p); +} + + +/* + * 'cupsdAddPrinterHistory()' - Add the current printer state to the history. + */ + +void +cupsdAddPrinterHistory( + cupsd_printer_t *p) /* I - Printer */ +{ + ipp_t *history; /* History collection */ + + + /* + * Stop early if we aren't keeping history data... + */ + + if (MaxPrinterHistory <= 0) + return; + + /* + * Retire old history data as needed... + */ + + p->sequence_number ++; + + if (p->num_history >= MaxPrinterHistory) + { + p->num_history --; + ippDelete(p->history[0]); + memmove(p->history, p->history + 1, p->num_history * sizeof(ipp_t *)); + } + + /* + * Create a collection containing the current printer-state, printer-up-time, + * printer-state-message, and printer-state-reasons attributes. + */ + + history = ippNew(); + ippAddInteger(history, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", + p->state); + ippAddBoolean(history, IPP_TAG_PRINTER, "printer-is-accepting-jobs", + p->accepting); + ippAddBoolean(history, IPP_TAG_PRINTER, "printer-is-shared", p->shared); + ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-state-message", + NULL, p->state_message); +#ifdef __APPLE__ + if (p->recoverable) + ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "com.apple.print.recoverable-message", NULL, p->recoverable); +#endif /* __APPLE__ */ + if (p->num_reasons == 0) + ippAddString(history, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-state-reasons", NULL, "none"); + else + ippAddStrings(history, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-state-reasons", p->num_reasons, NULL, + (const char * const *)p->reasons); + ippAddInteger(history, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "printer-state-change-time", p->state_time); + ippAddInteger(history, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "printer-state-sequence-number", p->sequence_number); + + p->history[p->num_history] = history; + p->num_history ++; +} + + +/* + * 'cupsdAddPrinterUser()' - Add a user to the ACL. + */ + +void +cupsdAddPrinterUser( + cupsd_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 ++; +} + + +/* + * 'cupsdCreateCommonData()' - Create the common printer data. + */ + +void +cupsdCreateCommonData(void) +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Attribute data */ + cups_dir_t *dir; /* Notifier directory */ + cups_dentry_t *dent; /* Notifier directory entry */ + cups_array_t *notifiers; /* Notifier array */ + char filename[1024], /* Filename */ + *notifier; /* Current notifier */ + cupsd_policy_t *p; /* Current policy */ + int k_supported; /* Maximum file size supported */ +#ifdef HAVE_STATVFS + struct statvfs spoolinfo; /* FS info for spool directory */ + double spoolsize; /* FS size */ +#elif defined(HAVE_STATFS) + struct statfs spoolinfo; /* FS info for spool directory */ + double spoolsize; /* FS size */ +#endif /* HAVE_STATVFS */ + static const int nups[] = /* number-up-supported values */ + { 1, 2, 4, 6, 9, 16 }; + static const int orients[4] =/* orientation-requested-supported values */ + { + IPP_PORTRAIT, + IPP_LANDSCAPE, + IPP_REVERSE_LANDSCAPE, + IPP_REVERSE_PORTRAIT + }; + static const char * const holds[] = /* job-hold-until-supported values */ + { + "no-hold", + "indefinite", + "day-time", + "evening", + "night", + "second-shift", + "third-shift", + "weekend" + }; + static const char * const versions[] =/* ipp-versions-supported values */ + { + "1.0", + "1.1", + "2.0", + "2.1" + }; + static const int 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_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_ENABLE_PRINTER, + IPP_DISABLE_PRINTER, + IPP_HOLD_NEW_JOBS, + IPP_RELEASE_HELD_NEW_JOBS, + 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_AUTHENTICATE_JOB, + CUPS_GET_PPD, + CUPS_GET_DOCUMENT, + IPP_RESTART_JOB + }; + static const char * const charsets[] =/* charset-supported values */ + { + "us-ascii", + "utf-8" + }; + static const char * const compressions[] = + { /* document-compression-supported values */ + "none" +#ifdef HAVE_LIBZ + ,"gzip" +#endif /* HAVE_LIBZ */ + }; + static const char * const media_col_supported[] = + { /* media-col-supported values */ + "media-bottom-margin", + "media-left-margin", + "media-right-margin", + "media-size", + "media-source", + "media-top-margin", + "media-type" + }; + static const char * const multiple_document_handling[] = + { /* multiple-document-handling-supported values */ + "separate-documents-uncollated-copies", + "separate-documents-collated-copies" + }; + static const char * const notify_attrs[] = + { /* notify-attributes-supported values */ + "printer-state-change-time", + "notify-lease-expiration-time", + "notify-subscriber-user-name" + }; + static const char * const notify_events[] = + { /* notify-events-supported values */ + "job-completed", + "job-config-changed", + "job-created", + "job-progress", + "job-state-changed", + "job-stopped", + "printer-added", + "printer-changed", + "printer-config-changed", + "printer-deleted", + "printer-finishings-changed", + "printer-media-changed", + "printer-modified", + "printer-restarted", + "printer-shutdown", + "printer-state-changed", + "printer-stopped", + "server-audit", + "server-restarted", + "server-started", + "server-stopped" + }; + static const char * const job_creation[] = + { /* job-creation-attributes-supported */ + "copies", + "finishings", + "ipp-attribute-fidelity", + "job-hold-until", + "job-name", + "job-priority", + "job-sheets", + "media", + "media-col", + "multiple-document-handling", + "number-up", + "output-bin", + "output-mode", + "orientation-requested", + "page-ranges", + "print-quality", + "printer-resolution", + "sides" + }; + static const char * const job_settable[] = + { /* job-settable-attributes-supported */ + "copies", + "finishings", + "job-hold-until", + "job-name", + "job-priority", + "media", + "media-col", + "multiple-document-handling", + "number-up", + "output-bin", + "output-mode", + "orientation-requested", + "page-ranges", + "print-quality", + "printer-resolution", + "sides" + }; + static const char * const printer_settable[] = + { /* printer-settable-attributes-supported */ + "printer-info", + "printer-location" + }; + + + if (CommonData) + ippDelete(CommonData); + + CommonData = ippNew(); + + /* + * Get the maximum spool size based on the size of the filesystem used for + * the RequestRoot directory. If the host OS doesn't support the statfs call + * or the filesystem is larger than 2TiB, always report INT_MAX. + */ + +#ifdef HAVE_STATVFS + if (statvfs(RequestRoot, &spoolinfo)) + k_supported = INT_MAX; + else if ((spoolsize = (double)spoolinfo.f_frsize * spoolinfo.f_blocks / 1024) > + INT_MAX) + k_supported = INT_MAX; + else + k_supported = (int)spoolsize; + +#elif defined(HAVE_STATFS) + if (statfs(RequestRoot, &spoolinfo)) + k_supported = INT_MAX; + else if ((spoolsize = (double)spoolinfo.f_bsize * spoolinfo.f_blocks / 1024) > + INT_MAX) + k_supported = INT_MAX; + else + k_supported = (int)spoolsize; + +#else + k_supported = INT_MAX; +#endif /* HAVE_STATVFS */ + + /* + * This list of attributes is sorted to improve performance when the + * client provides a requested-attributes attribute... + */ + + /* charset-configured */ + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY, + "charset-configured", NULL, "utf-8"); + + /* charset-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY, + "charset-supported", sizeof(charsets) / sizeof(charsets[0]), + NULL, charsets); + + /* compression-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "compression-supported", + sizeof(compressions) / sizeof(compressions[0]), + NULL, compressions); + + /* copies-supported */ + ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies); + + /* cups-version */ + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_TEXT | IPP_TAG_COPY, + "cups-version", NULL, CUPS_SVERSION + 6); + + /* generated-natural-language-supported (no IPP_TAG_COPY) */ + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE, + "generated-natural-language-supported", NULL, DefaultLanguage); + + /* ipp-versions-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]), + NULL, versions); + + /* ippget-event-life */ + ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "ippget-event-life", 15); + + /* job-creation-attributes-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "job-creation-attributes-supported", + sizeof(job_creation) / sizeof(job_creation[0]), + NULL, job_creation); + + /* job-hold-until-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "job-hold-until-supported", sizeof(holds) / sizeof(holds[0]), + NULL, holds); + + /* job-priority-supported */ + ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "job-priority-supported", 100); + + /* job-settable-attributes-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "job-settable-attributes-supported", + sizeof(job_settable) / sizeof(job_settable[0]), + NULL, job_settable); + + /* job-sheets-supported */ + if (cupsArrayCount(Banners) > 0) + { + /* + * Setup the job-sheets-supported attribute... + */ + + if (Classification && !ClassifyOverride) + attr = ippAddString(CommonData, IPP_TAG_PRINTER, + IPP_TAG_NAME | IPP_TAG_COPY, + "job-sheets-supported", NULL, Classification); + else + attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, + IPP_TAG_NAME | IPP_TAG_COPY, + "job-sheets-supported", cupsArrayCount(Banners) + 1, + NULL, NULL); + + if (attr == NULL) + cupsdLogMessage(CUPSD_LOG_EMERG, + "Unable to allocate memory for " + "job-sheets-supported attribute: %s!", strerror(errno)); + else if (!Classification || ClassifyOverride) + { + cupsd_banner_t *banner; /* Current banner */ + + + attr->values[0].string.text = _cupsStrAlloc("none"); + + for (i = 1, banner = (cupsd_banner_t *)cupsArrayFirst(Banners); + banner; + i ++, banner = (cupsd_banner_t *)cupsArrayNext(Banners)) + attr->values[i].string.text = banner->name; + } + } + else + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, + "job-sheets-supported", NULL, "none"); + + /* media-col-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "media-col-supported", + sizeof(media_col_supported) / + sizeof(media_col_supported[0]), NULL, + media_col_supported); + + /* multiple-document-handling-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "multiple-document-handling-supported", + sizeof(multiple_document_handling) / + sizeof(multiple_document_handling[0]), NULL, + multiple_document_handling); + + /* multiple-document-jobs-supported */ + ippAddBoolean(CommonData, IPP_TAG_PRINTER, + "multiple-document-jobs-supported", 1); + + /* multiple-operation-time-out */ + ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "multiple-operation-time-out", MultipleOperationTimeout); + + /* natural-language-configured (no IPP_TAG_COPY) */ + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE, + "natural-language-configured", NULL, DefaultLanguage); + + /* notify-attributes-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "notify-attributes-supported", + (int)(sizeof(notify_attrs) / sizeof(notify_attrs[0])), + NULL, notify_attrs); + + /* notify-lease-duration-supported */ + ippAddRange(CommonData, IPP_TAG_PRINTER, + "notify-lease-duration-supported", 0, + MaxLeaseDuration ? MaxLeaseDuration : 2147483647); + + /* notify-max-events-supported */ + ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "notify-max-events-supported", MaxEvents); + + /* notify-events-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "notify-events-supported", + (int)(sizeof(notify_events) / sizeof(notify_events[0])), + NULL, notify_events); + + /* notify-pull-method-supported */ + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "notify-pull-method-supported", NULL, "ippget"); + + /* notify-schemes-supported */ + snprintf(filename, sizeof(filename), "%s/notifier", ServerBin); + if ((dir = cupsDirOpen(filename)) != NULL) + { + notifiers = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + while ((dent = cupsDirRead(dir)) != NULL) + if (S_ISREG(dent->fileinfo.st_mode) && + (dent->fileinfo.st_mode & S_IXOTH) != 0) + cupsArrayAdd(notifiers, _cupsStrAlloc(dent->filename)); + + if (cupsArrayCount(notifiers) > 0) + { + attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "notify-schemes-supported", + cupsArrayCount(notifiers), NULL, NULL); + + for (i = 0, notifier = (char *)cupsArrayFirst(notifiers); + notifier; + i ++, notifier = (char *)cupsArrayNext(notifiers)) + attr->values[i].string.text = notifier; + } + + cupsArrayDelete(notifiers); + cupsDirClose(dir); + } + + /* number-up-supported */ + ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "number-up-supported", sizeof(nups) / sizeof(nups[0]), nups); + + /* operations-supported */ + ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "operations-supported", + sizeof(ops) / sizeof(ops[0]) + JobFiles - 1, ops); + + /* orientation-requested-supported */ + ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "orientation-requested-supported", 4, orients); + + /* page-ranges-supported */ + ippAddBoolean(CommonData, IPP_TAG_PRINTER, "page-ranges-supported", 1); + + /* pdl-override-supported */ + ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "pdl-override-supported", NULL, "attempted"); + + /* printer-op-policy-supported */ + attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY, + "printer-op-policy-supported", cupsArrayCount(Policies), + NULL, NULL); + for (i = 0, p = (cupsd_policy_t *)cupsArrayFirst(Policies); + p; + i ++, p = (cupsd_policy_t *)cupsArrayNext(Policies)) + attr->values[i].string.text = p->name; + + /* printer-settable-attributes-supported */ + ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY, + "printer-settable-attributes-supported", + sizeof(printer_settable) / sizeof(printer_settable[0]), + NULL, printer_settable); + + /* server-is-sharing-printers */ + ippAddBoolean(CommonData, IPP_TAG_PRINTER, "server-is-sharing-printers", + BrowseLocalProtocols != 0 && Browsing); +} + + +/* + * 'cupsdDeleteAllPrinters()' - Delete all printers from the system. + */ + +void +cupsdDeleteAllPrinters(void) +{ + cupsd_printer_t *p; /* Pointer to current printer/class */ + + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + p->op_policy_ptr = DefaultPolicyPtr; + cupsdDeletePrinter(p, 0); + } +} + + +/* + * 'cupsdDeletePrinter()' - Delete a printer from the system. + */ + +int /* O - 1 if classes affected, 0 otherwise */ +cupsdDeletePrinter( + cupsd_printer_t *p, /* I - Printer to delete */ + int update) /* I - Update printers.conf? */ +{ + int i, /* Looping var */ + changed = 0; /* Class changed? */ +#ifdef __sgi + char filename[1024]; /* Interface script filename */ +#endif /* __sgi */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeletePrinter(p=%p(%s), update=%d)", + p, p->name, update); + + /* + * Save the current position in the Printers array... + */ + + cupsArraySave(Printers); + + /* + * Stop printing on this printer... + */ + + cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, update); + + p->state = IPP_PRINTER_STOPPED; /* Force for browsed printers */ + + if (p->job) + cupsdSetJobState(p->job, IPP_JOB_PENDING, CUPSD_JOB_FORCE, + update ? "Job stopped due to printer being deleted." : + "Job stopped."); + + /* + * If this printer is the next for browsing, point to the next one... + */ + + if (p == BrowseNext) + { + cupsArrayFind(Printers, p); + BrowseNext = (cupsd_printer_t *)cupsArrayNext(Printers); + } + + /* + * Remove the printer from the list... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDeletePrinter: Removing %s from Printers", p->name); + cupsArrayRemove(Printers, p); + + if (p->type & CUPS_PRINTER_IMPLICIT) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdDeletePrinter: Removing %s from ImplicitPrinters", + p->name); + cupsArrayRemove(ImplicitPrinters, 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 a different one... + */ + + if (p == DefaultPrinter) + { + DefaultPrinter = NULL; + + if (UseNetworkDefault) + { + /* + * Find the first network default printer and use it... + */ + + cupsd_printer_t *dp; /* New default printer */ + + + for (dp = (cupsd_printer_t *)cupsArrayFirst(Printers); + dp; + dp = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (dp != p && (dp->type & CUPS_PRINTER_DEFAULT)) + { + DefaultPrinter = dp; + break; + } + } + } + + /* + * Remove this printer from any classes... + */ + + if (!(p->type & CUPS_PRINTER_IMPLICIT)) + { + changed = cupsdDeletePrinterFromClasses(p); + + /* + * Deregister from any browse protocols... + */ + + cupsdDeregisterPrinter(p, 1); + } + + /* + * Free all memory used by the printer... + */ + + if (p->printers != NULL) + free(p->printers); + + if (MaxPrinterHistory) + { + for (i = 0; i < p->num_history; i ++) + ippDelete(p->history[i]); + + free(p->history); + } + + delete_printer_filters(p); + + for (i = 0; i < p->num_reasons; i ++) + _cupsStrFree(p->reasons[i]); + + ippDelete(p->attrs); + ippDelete(p->ppd_attrs); + + mimeDeleteType(MimeDatabase, p->filetype); + mimeDeleteType(MimeDatabase, p->prefiltertype); + + delete_string_array(&(p->filters)); + delete_string_array(&(p->pre_filters)); + + cupsdFreePrinterUsers(p); + cupsdFreeQuotas(p); + + cupsdClearString(&p->uri); + cupsdClearString(&p->hostname); + cupsdClearString(&p->name); + cupsdClearString(&p->location); + cupsdClearString(&p->make_model); + cupsdClearString(&p->info); + cupsdClearString(&p->job_sheets[0]); + cupsdClearString(&p->job_sheets[1]); + cupsdClearString(&p->device_uri); + cupsdClearString(&p->sanitized_device_uri); + cupsdClearString(&p->port_monitor); + cupsdClearString(&p->op_policy); + cupsdClearString(&p->error_policy); + + cupsdClearString(&p->alert); + cupsdClearString(&p->alert_description); + +#ifdef HAVE_DNSSD + cupsdClearString(&p->product); + cupsdClearString(&p->pdl); +#endif /* HAVE_DNSSD */ + + cupsArrayDelete(p->filetypes); + + if (p->browse_attrs) + free(p->browse_attrs); + +#ifdef __APPLE__ + cupsdClearString(&p->recoverable); +#endif /* __APPLE__ */ + + cupsFreeOptions(p->num_options, p->options); + + free(p); + + /* + * Restore the previous position in the Printers array... + */ + + cupsArrayRestore(Printers); + + return (changed); +} + + +/* + * 'cupsdFindDest()' - Find a destination in the list. + */ + +cupsd_printer_t * /* O - Destination in list */ +cupsdFindDest(const char *name) /* I - Name of printer or class to find */ +{ + cupsd_printer_t key; /* Search key */ + + + key.name = (char *)name; + return ((cupsd_printer_t *)cupsArrayFind(Printers, &key)); +} + + +/* + * 'cupsdFindPrinter()' - Find a printer in the list. + */ + +cupsd_printer_t * /* O - Printer in list */ +cupsdFindPrinter(const char *name) /* I - Name of printer to find */ +{ + cupsd_printer_t *p; /* Printer in list */ + + + if ((p = cupsdFindDest(name)) != NULL && (p->type & CUPS_PRINTER_CLASS)) + return (NULL); + else + return (p); +} + + +/* + * 'cupsdFreePrinterUsers()' - Free allow/deny users. + */ + +void +cupsdFreePrinterUsers( + cupsd_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; +} + + +/* + * 'cupsdLoadAllPrinters()' - Load printers from the printers.conf file. + */ + +void +cupsdLoadAllPrinters(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* printers.conf file */ + int linenum; /* Current line number */ + char line[4096], /* Line from file */ + *value, /* Pointer to value */ + *valueptr; /* Pointer into value */ + cupsd_printer_t *p; /* Current printer */ + + + /* + * Open the printers.conf file... + */ + + snprintf(line, sizeof(line), "%s/printers.conf", ServerRoot); + if ((fp = cupsFileOpen(line, "r")) == NULL) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", line, + strerror(errno)); + return; + } + + /* + * Read printer configurations until we hit EOF... + */ + + linenum = 0; + p = NULL; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Decode the directive... + */ + + if (!strcasecmp(line, " or + */ + + if (p == NULL && value) + { + /* + * Add the printer and a base file type... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading printer %s...", value); + + p = cupsdAddPrinter(value); + p->accepting = 1; + p->state = IPP_PRINTER_IDLE; + + /* + * Set the default printer as needed... + */ + + if (!strcasecmp(line, "")) + { + if (p != NULL) + { + /* + * Close out the current printer... + */ + + cupsdSetPrinterAttrs(p); + cupsdAddPrinterHistory(p); + + if (strncmp(p->device_uri, "file:", 5) && + p->state != IPP_PRINTER_STOPPED) + { + /* + * See if the backend exists... + */ + + snprintf(line, sizeof(line), "%s/backend/%s", ServerBin, + p->device_uri); + + if ((valueptr = strchr(line + strlen(ServerBin), ':')) != NULL) + *valueptr = '\0'; /* Chop everything but URI scheme */ + + if (access(line, 0)) + { + /* + * Backend does not exist, stop printer... + */ + + p->state = IPP_PRINTER_STOPPED; + snprintf(p->state_message, sizeof(p->state_message), + "Backend %s does not exist!", line); + } + } + + p = NULL; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!p) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "AuthInfoRequired")) + { + if (!cupsdSetAuthInfoRequired(p, value, NULL)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad AuthInfoRequired on line %d of printers.conf.", + linenum); + } + else if (!strcasecmp(line, "Info")) + { + if (value) + cupsdSetString(&p->info, value); + } + else if (!strcasecmp(line, "MakeModel")) + { + if (value) + cupsdSetString(&p->make_model, value); + } + else if (!strcasecmp(line, "Location")) + { + if (value) + cupsdSetString(&p->location, value); + } + else if (!strcasecmp(line, "DeviceURI")) + { + if (value) + cupsdSetDeviceURI(p, value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Option") && value) + { + /* + * Option name value + */ + + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + p->num_options = cupsAddOption(value, valueptr, p->num_options, + &(p->options)); + } + } + else if (!strcasecmp(line, "PortMonitor")) + { + if (value && strcmp(value, "none")) + cupsdSetString(&p->port_monitor, value); + else if (value) + cupsdClearString(&p->port_monitor); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Reason")) + { + if (value && + strcmp(value, "com.apple.print.recoverable-warning") && + strcmp(value, "connecting-to-device") && + strcmp(value, "cups-insecure-filter-warning") && + strcmp(value, "cups-missing-filter-warning")) + { + for (i = 0 ; i < p->num_reasons; i ++) + if (!strcmp(value, p->reasons[i])) + break; + + if (i >= p->num_reasons && + p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) + { + p->reasons[p->num_reasons] = _cupsStrAlloc(value); + p->num_reasons ++; + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "State")) + { + /* + * Set the initial queue state... + */ + + if (value && !strcasecmp(value, "idle")) + p->state = IPP_PRINTER_IDLE; + else if (value && !strcasecmp(value, "stopped")) + { + p->state = IPP_PRINTER_STOPPED; + + for (i = 0 ; i < p->num_reasons; i ++) + if (!strcmp("paused", p->reasons[i])) + break; + + if (i >= p->num_reasons && + p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) + { + p->reasons[p->num_reasons] = _cupsStrAlloc("paused"); + p->num_reasons ++; + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "StateMessage")) + { + /* + * Set the initial queue state message... + */ + + if (value) + strlcpy(p->state_message, value, sizeof(p->state_message)); + } + else if (!strcasecmp(line, "StateTime")) + { + /* + * Set the state time... + */ + + if (value) + p->state_time = atoi(value); + } + else if (!strcasecmp(line, "Accepting")) + { + /* + * Set the initial accepting state... + */ + + if (value && + (!strcasecmp(value, "yes") || + !strcasecmp(value, "on") || + !strcasecmp(value, "true"))) + p->accepting = 1; + else if (value && + (!strcasecmp(value, "no") || + !strcasecmp(value, "off") || + !strcasecmp(value, "false"))) + p->accepting = 0; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Type")) + { + if (value) + p->type = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Product")) + { + if (value) + { +#ifdef HAVE_DNSSD + p->product = _cupsStrAlloc(value); +#endif /* HAVE_DNSSD */ + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Filter")) + { + if (value) + { + if (!p->filters) + p->filters = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(p->filters, _cupsStrAlloc(value)); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "PreFilter")) + { + if (value) + { + if (!p->pre_filters) + p->pre_filters = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(p->pre_filters, _cupsStrAlloc(value)); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Shared")) + { + /* + * Set the initial shared state... + */ + + if (value && + (!strcasecmp(value, "yes") || + !strcasecmp(value, "on") || + !strcasecmp(value, "true"))) + p->shared = 1; + else if (value && + (!strcasecmp(value, "no") || + !strcasecmp(value, "off") || + !strcasecmp(value, "false"))) + p->shared = 0; + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "JobSheets")) + { + /* + * Set the initial job sheets... + */ + + if (value) + { + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (*valueptr) + *valueptr++ = '\0'; + + cupsdSetString(&p->job_sheets[0], value); + + while (isspace(*valueptr & 255)) + valueptr ++; + + if (*valueptr) + { + for (value = valueptr; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (*valueptr) + *valueptr = '\0'; + + cupsdSetString(&p->job_sheets[1], value); + } + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "AllowUser")) + { + if (value) + { + p->deny_users = 0; + cupsdAddPrinterUser(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "DenyUser")) + { + if (value) + { + p->deny_users = 1; + cupsdAddPrinterUser(p, value); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "QuotaPeriod")) + { + if (value) + p->quota_period = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "PageLimit")) + { + if (value) + p->page_limit = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "KLimit")) + { + if (value) + p->k_limit = atoi(value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "OpPolicy")) + { + if (value) + { + cupsd_policy_t *pol; /* Policy */ + + + if ((pol = cupsdFindPolicy(value)) != NULL) + { + cupsdSetString(&p->op_policy, value); + p->op_policy_ptr = pol; + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad policy \"%s\" on line %d of printers.conf", + value, linenum); + } + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "ErrorPolicy")) + { + if (value) + cupsdSetString(&p->error_policy, value); + else + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + } + else if (!strcasecmp(line, "Attribute") && value) + { + for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); + + if (!*valueptr) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of printers.conf.", linenum); + else + { + for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); + + if (!p->attrs) + cupsdSetPrinterAttrs(p); + + if (!strcmp(value, "marker-change-time")) + p->marker_time = atoi(valueptr); + else + cupsdSetPrinterAttr(p, value, valueptr); + } + } + else + { + /* + * Something else we don't understand... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown configuration directive %s on line %d of printers.conf.", + line, linenum); + } + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdRenamePrinter()' - Rename a printer. + */ + +void +cupsdRenamePrinter( + cupsd_printer_t *p, /* I - Printer */ + const char *name) /* I - New name */ +{ + /* + * Remove the printer from the array(s) first... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRenamePrinter: Removing %s from Printers", p->name); + cupsArrayRemove(Printers, p); + + if (p->type & CUPS_PRINTER_IMPLICIT) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRenamePrinter: Removing %s from ImplicitPrinters", + p->name); + cupsArrayRemove(ImplicitPrinters, p); + } + + /* + * Rename the printer type... + */ + + mimeDeleteType(MimeDatabase, p->filetype); + p->filetype = mimeAddType(MimeDatabase, "printer", name); + + mimeDeleteType(MimeDatabase, p->prefiltertype); + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name); + + /* + * Rename the printer... + */ + + cupsdSetString(&p->name, name); + + /* + * Reset printer attributes... + */ + + cupsdSetPrinterAttrs(p); + + /* + * Add the printer back to the printer array(s)... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRenamePrinter: Adding %s to Printers", p->name); + cupsArrayAdd(Printers, p); + + if (p->type & CUPS_PRINTER_IMPLICIT) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdRenamePrinter: Adding %s to ImplicitPrinters", + p->name); + cupsArrayAdd(ImplicitPrinters, p); + } +} + + +/* + * 'cupsdSaveAllPrinters()' - Save all printer definitions to the printers.conf + * file. + */ + +void +cupsdSaveAllPrinters(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* printers.conf file */ + char temp[1024], /* Temporary string */ + backup[1024], /* printers.conf.O file */ + value[2048], /* Value string */ + *ptr; /* Pointer into value */ + cupsd_printer_t *printer; /* Current printer class */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + cups_option_t *option; /* Current option */ + ipp_attribute_t *marker; /* Current marker attribute */ + + + /* + * 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)) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to backup printers.conf - %s", strerror(errno)); + } + + if ((fp = cupsFileOpen(temp, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to save printers.conf - %s", strerror(errno)); + + if (rename(backup, temp)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to restore printers.conf - %s", strerror(errno)); + return; + } + else + cupsdLogMessage(CUPSD_LOG_INFO, "Saving printers.conf..."); + + /* + * Restrict access to the file... + */ + + fchown(cupsFileNumber(fp), getuid(), Group); + fchmod(cupsFileNumber(fp), ConfigFilePerm & 0600); + + /* + * Write a small header to the file... + */ + + curtime = time(NULL); + curdate = localtime(&curtime); + strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate); + + cupsFilePuts(fp, "# Printer configuration file for " CUPS_SVERSION "\n"); + cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp); + cupsFilePuts(fp, "# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING\n"); + + /* + * Write each local printer known to the system... + */ + + for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers); + printer; + printer = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * Skip remote destinations and printer classes... + */ + + if ((printer->type & CUPS_PRINTER_DISCOVERED) || + (printer->type & CUPS_PRINTER_CLASS) || + (printer->type & CUPS_PRINTER_IMPLICIT)) + continue; + + /* + * Write printers as needed... + */ + + if (printer == DefaultPrinter) + cupsFilePrintf(fp, "\n", printer->name); + else + cupsFilePrintf(fp, "\n", printer->name); + + if (printer->num_auth_info_required > 0) + { + switch (printer->num_auth_info_required) + { + case 1 : + strlcpy(value, printer->auth_info_required[0], sizeof(value)); + break; + + case 2 : + snprintf(value, sizeof(value), "%s,%s", + printer->auth_info_required[0], + printer->auth_info_required[1]); + break; + + case 3 : + default : + snprintf(value, sizeof(value), "%s,%s,%s", + printer->auth_info_required[0], + printer->auth_info_required[1], + printer->auth_info_required[2]); + break; + } + + cupsFilePutConf(fp, "AuthInfoRequired", value); + } + + if (printer->info) + cupsFilePutConf(fp, "Info", printer->info); + + if (printer->location) + cupsFilePutConf(fp, "Location", printer->location); + + if (printer->make_model) + cupsFilePutConf(fp, "MakeModel", printer->make_model); + + cupsFilePutConf(fp, "DeviceURI", printer->device_uri); + + if (printer->port_monitor) + cupsFilePutConf(fp, "PortMonitor", printer->port_monitor); + + if (printer->state == IPP_PRINTER_STOPPED) + { + cupsFilePuts(fp, "State Stopped\n"); + + if (printer->state_message) + cupsFilePutConf(fp, "StateMessage", printer->state_message); + } + else + cupsFilePuts(fp, "State Idle\n"); + + cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time); + + for (i = 0; i < printer->num_reasons; i ++) + if (strcmp(printer->reasons[i], "com.apple.print.recoverable-warning") && + strcmp(printer->reasons[i], "connecting-to-device") && + strcmp(printer->reasons[i], "cups-insecure-filter-warning") && + strcmp(printer->reasons[i], "cups-missing-filter-warning")) + cupsFilePutConf(fp, "Reason", printer->reasons[i]); + + cupsFilePrintf(fp, "Type %d\n", printer->type); + +#ifdef HAVE_DNSSD + if (printer->product) + cupsFilePutConf(fp, "Product", printer->product); +#endif /* HAVE_DNSSD */ + + for (ptr = (char *)cupsArrayFirst(printer->filters); + ptr; + ptr = (char *)cupsArrayNext(printer->filters)) + cupsFilePutConf(fp, "Filter", ptr); + + for (ptr = (char *)cupsArrayFirst(printer->pre_filters); + ptr; + ptr = (char *)cupsArrayNext(printer->pre_filters)) + cupsFilePutConf(fp, "PreFilter", ptr); + + if (printer->accepting) + cupsFilePuts(fp, "Accepting Yes\n"); + else + cupsFilePuts(fp, "Accepting No\n"); + + if (printer->shared) + cupsFilePuts(fp, "Shared Yes\n"); + else + cupsFilePuts(fp, "Shared No\n"); + + snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0], + printer->job_sheets[1]); + cupsFilePutConf(fp, "JobSheets", value); + + cupsFilePrintf(fp, "QuotaPeriod %d\n", printer->quota_period); + cupsFilePrintf(fp, "PageLimit %d\n", printer->page_limit); + cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit); + + for (i = 0; i < printer->num_users; i ++) + cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", + printer->users[i]); + + if (printer->op_policy) + cupsFilePutConf(fp, "OpPolicy", printer->op_policy); + if (printer->error_policy) + cupsFilePutConf(fp, "ErrorPolicy", printer->error_policy); + + for (i = printer->num_options, option = printer->options; + i > 0; + i --, option ++) + { + snprintf(value, sizeof(value), "%s %s", option->name, option->value); + cupsFilePutConf(fp, "Option", value); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-colors", + IPP_TAG_NAME)) != NULL) + { + snprintf(value, sizeof(value), "%s ", marker->name); + + for (i = 0, ptr = value + strlen(value); + i < marker->num_values && ptr < (value + sizeof(value) - 1); + i ++) + { + if (i) + *ptr++ = ','; + + strlcpy(ptr, marker->values[i].string.text, + value + sizeof(value) - ptr); + ptr += strlen(ptr); + } + + *ptr = '\0'; + cupsFilePutConf(fp, "Attribute", value); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-levels", + IPP_TAG_INTEGER)) != NULL) + { + cupsFilePrintf(fp, "Attribute %s %d", marker->name, + marker->values[0].integer); + for (i = 1; i < marker->num_values; i ++) + cupsFilePrintf(fp, ",%d", marker->values[i].integer); + cupsFilePuts(fp, "\n"); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-low-levels", + IPP_TAG_INTEGER)) != NULL) + { + cupsFilePrintf(fp, "Attribute %s %d", marker->name, + marker->values[0].integer); + for (i = 1; i < marker->num_values; i ++) + cupsFilePrintf(fp, ",%d", marker->values[i].integer); + cupsFilePuts(fp, "\n"); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-high-levels", + IPP_TAG_INTEGER)) != NULL) + { + cupsFilePrintf(fp, "Attribute %s %d", marker->name, + marker->values[0].integer); + for (i = 1; i < marker->num_values; i ++) + cupsFilePrintf(fp, ",%d", marker->values[i].integer); + cupsFilePuts(fp, "\n"); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-message", + IPP_TAG_TEXT)) != NULL) + { + snprintf(value, sizeof(value), "%s %s", marker->name, + marker->values[0].string.text); + + cupsFilePutConf(fp, "Attribute", value); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-names", + IPP_TAG_NAME)) != NULL) + { + snprintf(value, sizeof(value), "%s ", marker->name); + + for (i = 0, ptr = value + strlen(value); + i < marker->num_values && ptr < (value + sizeof(value) - 1); + i ++) + { + if (i) + *ptr++ = ','; + + strlcpy(ptr, marker->values[i].string.text, + value + sizeof(value) - ptr); + ptr += strlen(ptr); + } + + *ptr = '\0'; + cupsFilePutConf(fp, "Attribute", value); + } + + if ((marker = ippFindAttribute(printer->attrs, "marker-types", + IPP_TAG_KEYWORD)) != NULL) + { + snprintf(value, sizeof(value), "%s ", marker->name); + + for (i = 0, ptr = value + strlen(value); + i < marker->num_values && ptr < (value + sizeof(value) - 1); + i ++) + { + if (i) + *ptr++ = ','; + + strlcpy(ptr, marker->values[i].string.text, + value + sizeof(value) - ptr); + ptr += strlen(ptr); + } + + *ptr = '\0'; + cupsFilePutConf(fp, "Attribute", value); + } + + if (printer->marker_time) + cupsFilePrintf(fp, "Attribute marker-change-time %ld\n", + (long)printer->marker_time); + + cupsFilePuts(fp, "\n"); + +#ifdef __sgi + /* + * Make IRIX desktop & printer status happy + */ + + write_irix_state(printer); +#endif /* __sgi */ + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdSetAuthInfoRequired()' - Set the required authentication info. + */ + +int /* O - 1 if value OK, 0 otherwise */ +cupsdSetAuthInfoRequired( + cupsd_printer_t *p, /* I - Printer */ + const char *values, /* I - Plain text value (or NULL) */ + ipp_attribute_t *attr) /* I - IPP attribute value (or NULL) */ +{ + int i; /* Looping var */ + + + p->num_auth_info_required = 0; + + /* + * Do we have a plain text value? + */ + + if (values) + { + /* + * Yes, grab the keywords... + */ + + const char *end; /* End of current value */ + + + while (*values && p->num_auth_info_required < 4) + { + if ((end = strchr(values, ',')) == NULL) + end = values + strlen(values); + + if ((end - values) == 4 && !strncmp(values, "none", 4)) + { + if (p->num_auth_info_required != 0 || *end) + return (0); + + p->auth_info_required[p->num_auth_info_required] = "none"; + p->num_auth_info_required ++; + + return (1); + } + else if ((end - values) == 9 && !strncmp(values, "negotiate", 9)) + { + if (p->num_auth_info_required != 0 || *end) + return (0); + + p->auth_info_required[p->num_auth_info_required] = "negotiate"; + p->num_auth_info_required ++; + } + else if ((end - values) == 6 && !strncmp(values, "domain", 6)) + { + p->auth_info_required[p->num_auth_info_required] = "domain"; + p->num_auth_info_required ++; + } + else if ((end - values) == 8 && !strncmp(values, "password", 8)) + { + p->auth_info_required[p->num_auth_info_required] = "password"; + p->num_auth_info_required ++; + } + else if ((end - values) == 8 && !strncmp(values, "username", 8)) + { + p->auth_info_required[p->num_auth_info_required] = "username"; + p->num_auth_info_required ++; + } + else + return (0); + + values = (*end) ? end + 1 : end; + } + + if (p->num_auth_info_required == 0) + { + p->auth_info_required[0] = "none"; + p->num_auth_info_required = 1; + } + + /* + * Update the printer-type value as needed... + */ + + if (p->num_auth_info_required > 1 || + strcmp(p->auth_info_required[0], "none")) + p->type |= CUPS_PRINTER_AUTHENTICATED; + else + p->type &= ~CUPS_PRINTER_AUTHENTICATED; + + return (1); + } + + /* + * Grab values from an attribute instead... + */ + + if (!attr || attr->num_values > 4) + return (0); + + /* + * Update the printer-type value as needed... + */ + + if (attr->num_values > 1 || + strcmp(attr->values[0].string.text, "none")) + p->type |= CUPS_PRINTER_AUTHENTICATED; + else + p->type &= ~CUPS_PRINTER_AUTHENTICATED; + + for (i = 0; i < attr->num_values; i ++) + { + if (!strcmp(attr->values[i].string.text, "none")) + { + if (p->num_auth_info_required != 0 || attr->num_values != 1) + return (0); + + p->auth_info_required[p->num_auth_info_required] = "none"; + p->num_auth_info_required ++; + + return (1); + } + else if (!strcmp(attr->values[i].string.text, "negotiate")) + { + if (p->num_auth_info_required != 0 || attr->num_values != 1) + return (0); + + p->auth_info_required[p->num_auth_info_required] = "negotiate"; + p->num_auth_info_required ++; + + return (1); + } + else if (!strcmp(attr->values[i].string.text, "domain")) + { + p->auth_info_required[p->num_auth_info_required] = "domain"; + p->num_auth_info_required ++; + } + else if (!strcmp(attr->values[i].string.text, "password")) + { + p->auth_info_required[p->num_auth_info_required] = "password"; + p->num_auth_info_required ++; + } + else if (!strcmp(attr->values[i].string.text, "username")) + { + p->auth_info_required[p->num_auth_info_required] = "username"; + p->num_auth_info_required ++; + } + else + return (0); + } + + return (1); +} + + +/* + * 'cupsdSetDeviceURI()' - Set the device URI for a printer. + */ + +void +cupsdSetDeviceURI(cupsd_printer_t *p, /* I - Printer */ + const char *uri) /* I - Device URI */ +{ + char buffer[1024], /* URI buffer */ + *start, /* Start of data after scheme */ + *slash, /* First slash after scheme:// */ + *ptr; /* Pointer into user@host:port part */ + + + /* + * Set the full device URI.. + */ + + cupsdSetString(&(p->device_uri), uri); + + /* + * Copy the device URI to a temporary buffer so we can sanitize any auth + * info in it... + */ + + strlcpy(buffer, uri, sizeof(buffer)); + + /* + * Find the end of the scheme:// part... + */ + + if ((ptr = strchr(buffer, ':')) != NULL) + { + for (start = ptr + 1; *start; start ++) + if (*start != '/') + break; + + /* + * Find the next slash (/) in the URI... + */ + + if ((slash = strchr(start, '/')) == NULL) + slash = start + strlen(start); /* No slash, point to the end */ + + /* + * Check for an @ sign before the slash... + */ + + if ((ptr = strchr(start, '@')) != NULL && ptr < slash) + { + /* + * Found an @ sign and it is before the resource part, so we have + * an authentication string. Copy the remaining URI over the + * authentication string... + */ + + _cups_strcpy(start, ptr + 1); + } + } + + /* + * Save the sanitized URI... + */ + + cupsdSetString(&(p->sanitized_device_uri), buffer); +} + + +/* + * 'cupsdSetPrinterAttr()' - Set a printer attribute. + */ + +void +cupsdSetPrinterAttr( + cupsd_printer_t *p, /* I - Printer */ + const char *name, /* I - Attribute name */ + char *value) /* I - Attribute value string */ +{ + ipp_attribute_t *attr; /* Attribute */ + int i, /* Looping var */ + count; /* Number of values */ + char *ptr; /* Pointer into value */ + ipp_tag_t value_tag; /* Value tag for this attribute */ + + + /* + * Don't allow empty values... + */ + + if (!*value && strcmp(name, "marker-message")) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Ignoring empty \"%s\" attribute", name); + return; + } + + /* + * Count the number of values... + */ + + for (count = 1, ptr = value; + (ptr = strchr(ptr, ',')) != NULL; + ptr ++, count ++); + + /* + * Then add or update the attribute as needed... + */ + + if (!strcmp(name, "marker-levels") || !strcmp(name, "marker-low-levels") || + !strcmp(name, "marker-high-levels")) + { + /* + * Integer values... + */ + + if ((attr = ippFindAttribute(p->attrs, name, IPP_TAG_INTEGER)) != NULL && + attr->num_values < count) + { + ippDeleteAttribute(p->attrs, attr); + attr = NULL; + } + + if (attr) + attr->num_values = count; + else + attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, name, + count, NULL); + + if (!attr) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for printer attribute " + "(%d values)", count); + return; + } + + for (i = 0; i < count; i ++) + { + if ((ptr = strchr(value, ',')) != NULL) + *ptr++ = '\0'; + + attr->values[i].integer = strtol(value, NULL, 10); + + if (ptr) + value = ptr; + } + } + else + { + /* + * Name or keyword values... + */ + + if (!strcmp(name, "marker-types")) + value_tag = IPP_TAG_KEYWORD; + else if (!strcmp(name, "marker-message")) + value_tag = IPP_TAG_TEXT; + else + value_tag = IPP_TAG_NAME; + + if ((attr = ippFindAttribute(p->attrs, name, value_tag)) != NULL && + attr->num_values < count) + { + ippDeleteAttribute(p->attrs, attr); + attr = NULL; + } + + if (attr) + { + for (i = 0; i < attr->num_values; i ++) + _cupsStrFree(attr->values[i].string.text); + + attr->num_values = count; + } + else + attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, value_tag, name, + count, NULL, NULL); + + if (!attr) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate memory for printer attribute " + "(%d values)", count); + return; + } + + for (i = 0; i < count; i ++) + { + if ((ptr = strchr(value, ',')) != NULL) + *ptr++ = '\0'; + + attr->values[i].string.text = _cupsStrAlloc(value); + + if (ptr) + value = ptr; + } + } +} + + +/* + * 'cupsdSetPrinterAttrs()' - Set printer attributes based upon the PPD file. + */ + +void +cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */ +{ + int i, /* Looping var */ + length; /* Length of browse attributes */ + char resource[HTTP_MAX_URI]; /* Resource portion of URI */ + int num_air; /* Number of auth-info-required values */ + const char * const *air; /* auth-info-required values */ + cupsd_location_t *auth; /* Pointer to authentication element */ + const char *auth_supported; /* Authentication supported */ + ipp_t *oldattrs; /* Old printer attributes */ + ipp_attribute_t *attr; /* Attribute data */ + cups_option_t *option; /* Current printer option */ + char *filter; /* Current filter */ + static const char * const air_none[] = + { /* No authentication */ + "none" + }; + static const char * const air_userpass[] = + { /* Basic/Digest authentication */ + "username", + "password" + }; + + + DEBUG_printf(("cupsdSetPrinterAttrs: entering name = %s, type = %x\n", p->name, + p->type)); + + /* + * Make sure that we have the common attributes defined... + */ + + if (!CommonData) + cupsdCreateCommonData(); + + /* + * Clear out old filters, if any... + */ + + delete_printer_filters(p); + + /* + * Figure out the authentication that is required for the printer. + */ + + auth_supported = "requesting-user-name"; + num_air = 1; + air = air_none; + + if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none")) + { + num_air = p->num_auth_info_required; + air = p->auth_info_required; + } + else if ((p->type & CUPS_PRINTER_AUTHENTICATED) && + (p->type & CUPS_PRINTER_DISCOVERED)) + { + num_air = 2; + air = air_userpass; + } + + 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 = cupsdFindBest(resource, HTTP_POST)) == NULL || + auth->type == CUPSD_AUTH_NONE) + auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB); + + if (auth) + { + int auth_type; /* Authentication type */ + + + if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT) + auth_type = DefaultAuthType; + + if (auth_type == CUPSD_AUTH_BASIC || auth_type == CUPSD_AUTH_BASICDIGEST) + auth_supported = "basic"; + else if (auth_type == CUPSD_AUTH_DIGEST) + auth_supported = "digest"; +#ifdef HAVE_GSSAPI + else if (auth_type == CUPSD_AUTH_NEGOTIATE) + auth_supported = "negotiate"; +#endif /* HAVE_GSSAPI */ + + if (!(p->type & CUPS_PRINTER_DISCOVERED)) + { + if (auth_type != CUPSD_AUTH_NONE) + p->type |= CUPS_PRINTER_AUTHENTICATED; + else + p->type &= ~CUPS_PRINTER_AUTHENTICATED; + } + } + else if (!(p->type & CUPS_PRINTER_DISCOVERED)) + p->type &= ~CUPS_PRINTER_AUTHENTICATED; + + /* + * Create the required IPP attributes for a printer... + */ + + oldattrs = p->attrs; + p->attrs = ippNew(); + + 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 ? p->location : ""); + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", + NULL, p->info ? p->info : ""); + + 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); + ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "auth-info-required", num_air, NULL, air); + + if (cupsArrayCount(Banners) > 0 && !(p->type & CUPS_PRINTER_DISCOVERED)) + { + /* + * Setup the job-sheets-default attribute... + */ + + attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "job-sheets-default", 2, NULL, NULL); + + if (attr != NULL) + { + attr->values[0].string.text = _cupsStrAlloc(Classification ? + Classification : p->job_sheets[0]); + attr->values[1].string.text = _cupsStrAlloc(Classification ? + Classification : p->job_sheets[1]); + } + } + + p->raw = 0; + p->remote = 0; + + if (p->type & CUPS_PRINTER_DISCOVERED) + { + /* + * Tell the client this is a remote printer of some type... + */ + + if (strchr(p->uri, '?')) + { + /* + * Strip trailing "?options" from URI... + */ + + char *ptr; /* Pointer into URI */ + + strlcpy(resource, p->uri, sizeof(resource)); + if ((ptr = strchr(resource, '?')) != NULL) + *ptr = '\0'; + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-uri-supported", NULL, resource); + } + else + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-uri-supported", NULL, p->uri); + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info", + NULL, p->uri); + + if (p->make_model) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-make-and-model", NULL, p->make_model); + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, + p->uri); + + p->raw = 1; + p->remote = 1; + } + else + { + /* + * Assign additional attributes depending on whether this is a printer + * or class... + */ + + if (p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT)) + { + p->raw = 1; + p->type &= ~CUPS_PRINTER_OPTIONS; + + /* + * Add class-specific attributes... + */ + + if ((p->type & CUPS_PRINTER_IMPLICIT) && p->num_printers > 0 && + p->printers[0]->make_model) + 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"); + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, + "file:///dev/null"); + + if (p->num_printers > 0) + { + /* + * Add a list of member names; URIs are added in copy_printer_attrs... + */ + + attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "member-names", 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 = _cupsStrRetain(p->printers[i]->name); + + p->type &= ~CUPS_PRINTER_OPTIONS | p->printers[i]->type; + } + } + } + else + { + /* + * Add printer-specific attributes... + */ + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL, + p->sanitized_device_uri); + + /* + * Assign additional attributes from the PPD file (if any)... + */ + + load_ppd(p); + + /* + * Add filters for printer... + */ + + cupsdSetPrinterReasons(p, "-cups-missing-filter-warning," + "cups-insecure-filter-warning"); + + for (filter = (char *)cupsArrayFirst(p->filters); + filter; + filter = (char *)cupsArrayNext(p->filters)) + add_printer_filter(p, p->filetype, filter); + + if (p->pre_filters) + { + p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name); + + for (filter = (char *)cupsArrayFirst(p->pre_filters); + filter; + filter = (char *)cupsArrayNext(p->pre_filters)) + add_printer_filter(p, p->prefiltertype, filter); + } + } + } + + /* + * Copy marker attributes as needed... + */ + + if (oldattrs) + { + ipp_attribute_t *oldattr; /* Old attribute */ + + + if ((oldattr = ippFindAttribute(oldattrs, "marker-colors", + IPP_TAG_NAME)) != NULL) + { + if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "marker-colors", oldattr->num_values, NULL, + NULL)) != NULL) + { + for (i = 0; i < oldattr->num_values; i ++) + attr->values[i].string.text = + _cupsStrRetain(oldattr->values[i].string.text); + } + } + + if ((oldattr = ippFindAttribute(oldattrs, "marker-levels", + IPP_TAG_INTEGER)) != NULL) + { + if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "marker-levels", oldattr->num_values, + NULL)) != NULL) + { + for (i = 0; i < oldattr->num_values; i ++) + attr->values[i].integer = oldattr->values[i].integer; + } + } + + if ((oldattr = ippFindAttribute(oldattrs, "marker-message", + IPP_TAG_TEXT)) != NULL) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "marker-message", + NULL, oldattr->values[0].string.text); + + if ((oldattr = ippFindAttribute(oldattrs, "marker-low-levels", + IPP_TAG_INTEGER)) != NULL) + { + if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "marker-low-levels", oldattr->num_values, + NULL)) != NULL) + { + for (i = 0; i < oldattr->num_values; i ++) + attr->values[i].integer = oldattr->values[i].integer; + } + } + + if ((oldattr = ippFindAttribute(oldattrs, "marker-high-levels", + IPP_TAG_INTEGER)) != NULL) + { + if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "marker-high-levels", oldattr->num_values, + NULL)) != NULL) + { + for (i = 0; i < oldattr->num_values; i ++) + attr->values[i].integer = oldattr->values[i].integer; + } + } + + if ((oldattr = ippFindAttribute(oldattrs, "marker-names", + IPP_TAG_NAME)) != NULL) + { + if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "marker-names", oldattr->num_values, NULL, + NULL)) != NULL) + { + for (i = 0; i < oldattr->num_values; i ++) + attr->values[i].string.text = + _cupsStrRetain(oldattr->values[i].string.text); + } + } + + if ((oldattr = ippFindAttribute(oldattrs, "marker-types", + IPP_TAG_KEYWORD)) != NULL) + { + if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "marker-types", oldattr->num_values, NULL, + NULL)) != NULL) + { + for (i = 0; i < oldattr->num_values; i ++) + attr->values[i].string.text = + _cupsStrRetain(oldattr->values[i].string.text); + } + } + + ippDelete(oldattrs); + } + + /* + * Force sharing off for remote queues... + */ + + if (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT)) + p->shared = 0; + else + { + /* + * Copy the printer options into a browse attributes string we can re-use. + */ + + const char *valptr; /* Pointer into value */ + char *attrptr; /* Pointer into attribute string */ + + + /* + * Free the old browse attributes as needed... + */ + + if (p->browse_attrs) + free(p->browse_attrs); + + /* + * Compute the length of all attributes + job-sheets, lease-duration, + * and BrowseLocalOptions. + */ + + for (length = 1, i = p->num_options, option = p->options; + i > 0; + i --, option ++) + { + length += strlen(option->name) + 2; + + if (option->value) + { + for (valptr = option->value; *valptr; valptr ++) + if (strchr(" \"\'\\", *valptr)) + length += 2; + else + length ++; + } + } + + length += 13 + strlen(p->job_sheets[0]) + strlen(p->job_sheets[1]); + length += 32; + if (BrowseLocalOptions) + length += 12 + strlen(BrowseLocalOptions); + + /* + * Allocate the new string... + */ + + if ((p->browse_attrs = calloc(1, length)) == NULL) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to allocate %d bytes for browse data!", + length); + else + { + /* + * Got the allocated string, now copy the options and attributes over... + */ + + sprintf(p->browse_attrs, "job-sheets=%s,%s lease-duration=%d", + p->job_sheets[0], p->job_sheets[1], BrowseTimeout); + attrptr = p->browse_attrs + strlen(p->browse_attrs); + + if (BrowseLocalOptions) + { + sprintf(attrptr, " ipp-options=%s", BrowseLocalOptions); + attrptr += strlen(attrptr); + } + + for (i = p->num_options, option = p->options; + i > 0; + i --, option ++) + { + *attrptr++ = ' '; + strcpy(attrptr, option->name); + attrptr += strlen(attrptr); + + if (option->value) + { + *attrptr++ = '='; + + for (valptr = option->value; *valptr; valptr ++) + { + if (strchr(" \"\'\\", *valptr)) + *attrptr++ = '\\'; + + *attrptr++ = *valptr; + } + } + } + } + } + + /* + * Populate the document-format-supported attribute... + */ + + add_printer_formats(p); + + DEBUG_printf(("cupsdSetPrinterAttrs: leaving name = %s, type = %x\n", p->name, + p->type)); + + /* + * Add name-default attributes... + */ + + add_printer_defaults(p); + +#ifdef __sgi + /* + * Write the IRIX printer config and status files... + */ + + write_irix_config(p); + write_irix_state(p); +#endif /* __sgi */ + + /* + * Let the browse protocols reflect the change + */ + + cupsdRegisterPrinter(p); +} + + +/* + * 'cupsdSetPrinterReasons()' - Set/update the reasons strings. + */ + +int /* O - 1 if something changed, 0 otherwise */ +cupsdSetPrinterReasons( + cupsd_printer_t *p, /* I - Printer */ + const char *s) /* I - Reasons strings */ +{ + int i, /* Looping var */ + changed = 0; /* Did something change? */ + const char *sptr; /* Pointer into reasons */ + char reason[255], /* Reason string */ + *rptr; /* Pointer into reason */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdSetPrinterReasons(p=%p(%s),s=\"%s\"", p, p->name, s); + + if (s[0] == '-' || s[0] == '+') + { + /* + * Add/remove reasons... + */ + + sptr = s + 1; + } + else + { + /* + * Replace reasons... + */ + + sptr = s; + + for (i = 0; i < p->num_reasons; i ++) + _cupsStrFree(p->reasons[i]); + + p->num_reasons = 0; + changed = 1; + + dirty_printer(p); + } + + if (!strcmp(s, "none")) + return (changed); + + /* + * Loop through all of the reasons... + */ + + while (*sptr) + { + /* + * Skip leading whitespace and commas... + */ + + while (isspace(*sptr & 255) || *sptr == ',') + sptr ++; + + for (rptr = reason; *sptr && !isspace(*sptr & 255) && *sptr != ','; sptr ++) + if (rptr < (reason + sizeof(reason) - 1)) + *rptr++ = *sptr; + + if (rptr == reason) + break; + + *rptr = '\0'; + + if (s[0] == '-') + { + /* + * Remove reason... + */ + + for (i = 0; i < p->num_reasons; i ++) + if (!strcmp(reason, p->reasons[i])) + { + /* + * Found a match, so remove it... + */ + + p->num_reasons --; + changed = 1; + _cupsStrFree(p->reasons[i]); + + if (i < p->num_reasons) + memmove(p->reasons + i, p->reasons + i + 1, + (p->num_reasons - i) * sizeof(char *)); + + if (!strcmp(reason, "paused") && p->state == IPP_PRINTER_STOPPED) + cupsdSetPrinterState(p, IPP_PRINTER_IDLE, 1); + + if (strcmp(reason, "connecting-to-device")) + dirty_printer(p); + break; + } + } + else if (p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) + { + /* + * Add reason... + */ + + for (i = 0; i < p->num_reasons; i ++) + if (!strcmp(reason, p->reasons[i])) + break; + + if (i >= p->num_reasons) + { + if (i >= (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) + { + cupsdLogMessage(CUPSD_LOG_ALERT, + "Too many printer-state-reasons values for %s (%d)", + p->name, i + 1); + return (changed); + } + + p->reasons[i] = _cupsStrAlloc(reason); + p->num_reasons ++; + changed = 1; + + if (!strcmp(reason, "paused") && p->state != IPP_PRINTER_STOPPED) + cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, 1); + + if (strcmp(reason, "connecting-to-device")) + dirty_printer(p); + } + } + } + + return (changed); +} + + +/* + * 'cupsdSetPrinterState()' - Update the current state of a printer. + */ + +void +cupsdSetPrinterState( + cupsd_printer_t *p, /* I - Printer to change */ + ipp_pstate_t s, /* I - New state */ + int update) /* I - Update printers.conf? */ +{ + ipp_pstate_t old_state; /* Old printer state */ + static const char * const printer_states[] = + { /* State strings */ + "idle", + "processing", + "stopped" + }; + + + /* + * Can't set status of remote printers... + */ + + if (p->type & CUPS_PRINTER_DISCOVERED) + return; + + /* + * Set the new state... + */ + + old_state = p->state; + p->state = s; + + if (old_state != s) + { + cupsdAddEvent(s == IPP_PRINTER_STOPPED ? CUPSD_EVENT_PRINTER_STOPPED : + CUPSD_EVENT_PRINTER_STATE, p, NULL, + "%s \"%s\" state changed to %s.", + (p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer", + p->name, printer_states[p->state - IPP_PRINTER_IDLE]); + + /* + * Let the browse code know this needs to be updated... + */ + + BrowseNext = p; + p->state_time = time(NULL); + p->browse_time = 0; + +#ifdef __sgi + write_irix_state(p); +#endif /* __sgi */ + } + + /* + * Set/clear the paused reason as needed... + */ + + if (s == IPP_PRINTER_STOPPED) + cupsdSetPrinterReasons(p, "+paused"); + else + cupsdSetPrinterReasons(p, "-paused"); + + /* + * Clear the message for the queue when going to processing... + */ + + if (s == IPP_PRINTER_PROCESSING) + p->state_message[0] = '\0'; + + /* + * Update the printer history... + */ + + cupsdAddPrinterHistory(p); + + /* + * Let the browse protocols reflect the change... + */ + + if (update) + cupsdRegisterPrinter(p); + + /* + * Save the printer configuration if a printer goes from idle or processing + * to stopped (or visa-versa)... + */ + + if (update && + (old_state == IPP_PRINTER_STOPPED) != (s == IPP_PRINTER_STOPPED)) + dirty_printer(p); +} + + +/* + * 'cupsdStopPrinter()' - Stop a printer from printing any jobs... + */ + +void +cupsdStopPrinter(cupsd_printer_t *p, /* I - Printer to stop */ + int update)/* I - Update printers.conf? */ +{ + /* + * Set the printer state... + */ + + cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, update); + + /* + * See if we have a job printing on this printer... + */ + + if (p->job && p->job->state_value == IPP_JOB_PROCESSING) + cupsdSetJobState(p->job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT, + "Job stopped due to printer being paused."); +} + + +/* + * 'cupsdUpdatePrinterPPD()' - Update keywords in a printer's PPD file. + */ + +int /* O - 1 if successful, 0 otherwise */ +cupsdUpdatePrinterPPD( + cupsd_printer_t *p, /* I - Printer */ + int num_keywords, /* I - Number of keywords */ + cups_option_t *keywords) /* I - Keywords */ +{ + int i; /* Looping var */ + cups_file_t *src, /* Original file */ + *dst; /* New file */ + char srcfile[1024], /* Original filename */ + dstfile[1024], /* New filename */ + line[1024], /* Line from file */ + keystring[41]; /* Keyword from line */ + cups_option_t *keyword; /* Current keyword */ + + + cupsdLogMessage(CUPSD_LOG_INFO, "Updating keywords in PPD file for %s...", + p->name); + + /* + * Get the old and new PPD filenames... + */ + + snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd.O", ServerRoot, p->name); + snprintf(dstfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot, p->name); + + /* + * Rename the old file and open the old and new... + */ + + if (rename(dstfile, srcfile)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup PPD file for %s: %s", + p->name, strerror(errno)); + return (0); + } + + if ((src = cupsFileOpen(srcfile, "r")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open PPD file \"%s\": %s", + srcfile, strerror(errno)); + rename(srcfile, dstfile); + return (0); + } + + if ((dst = cupsFileOpen(dstfile, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create PPD file \"%s\": %s", + dstfile, strerror(errno)); + cupsFileClose(src); + rename(srcfile, dstfile); + return (0); + } + + /* + * Copy the first line and then write out all of the keywords... + */ + + if (!cupsFileGets(src, line, sizeof(line))) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to read PPD file \"%s\": %s", + srcfile, strerror(errno)); + cupsFileClose(src); + cupsFileClose(dst); + rename(srcfile, dstfile); + return (0); + } + + cupsFilePrintf(dst, "%s\n", line); + + for (i = num_keywords, keyword = keywords; i > 0; i --, keyword ++) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "*%s: %s", keyword->name, keyword->value); + cupsFilePrintf(dst, "*%s: %s\n", keyword->name, keyword->value); + } + + /* + * Then copy the rest of the PPD file, dropping any keywords we changed. + */ + + while (cupsFileGets(src, line, sizeof(line))) + { + /* + * Skip keywords we've already set... + */ + + if (sscanf(line, "*%40[^:]:", keystring) == 1 && + cupsGetOption(keystring, num_keywords, keywords)) + continue; + + /* + * Otherwise write the line... + */ + + cupsFilePrintf(dst, "%s\n", line); + } + + /* + * Close files and return... + */ + + cupsFileClose(src); + cupsFileClose(dst); + + return (1); +} + + +/* + * 'cupsdUpdatePrinters()' - Update printers after a partial reload. + */ + +void +cupsdUpdatePrinters(void) +{ + cupsd_printer_t *p; /* Current printer */ + + + /* + * Loop through the printers and recreate the printer attributes + * for any local printers since the policy and/or access control + * stuff may have changed. Also, if browsing is disabled, remove + * any remote printers... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + /* + * Remove remote printers if we are no longer browsing... + */ + + if (!Browsing && + (p->type & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_DISCOVERED))) + { + if (p->type & CUPS_PRINTER_IMPLICIT) + cupsArrayRemove(ImplicitPrinters, p); + + cupsArraySave(Printers); + cupsdDeletePrinter(p, 0); + cupsArrayRestore(Printers); + continue; + } + + /* + * Update the operation policy pointer... + */ + + if ((p->op_policy_ptr = cupsdFindPolicy(p->op_policy)) == NULL) + p->op_policy_ptr = DefaultPolicyPtr; + + /* + * Update printer attributes as needed... + */ + + if (!(p->type & CUPS_PRINTER_DISCOVERED)) + cupsdSetPrinterAttrs(p); + } +} + + +/* + * 'cupsdValidateDest()' - Validate a printer/class destination. + */ + +const char * /* O - Printer or class name */ +cupsdValidateDest( + const char *uri, /* I - Printer URI */ + cups_ptype_t *dtype, /* O - Type (printer or class) */ + cupsd_printer_t **printer) /* O - Printer pointer */ +{ + cupsd_printer_t *p; /* Current printer */ + char localname[1024],/* Localized hostname */ + *lptr, /* Pointer into localized hostname */ + *sptr, /* Pointer into server name */ + *rptr, /* Pointer into resource */ + scheme[32], /* Scheme portion of URI */ + username[64], /* Username portion of URI */ + hostname[HTTP_MAX_HOST], + /* Host portion of URI */ + resource[HTTP_MAX_URI]; + /* Resource portion of URI */ + int port; /* Port portion of URI */ + + + DEBUG_printf(("cupsdValidateDest(uri=\"%s\", dtype=%p, printer=%p)\n", uri, + dtype, printer)); + + /* + * Initialize return values... + */ + + if (printer) + *printer = NULL; + + if (dtype) + *dtype = (cups_ptype_t)0; + + /* + * Pull the hostname and resource from the URI... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, sizeof(hostname), + &port, resource, sizeof(resource)); + + /* + * See if the resource is a class or printer... + */ + + if (!strncmp(resource, "/classes/", 9)) + { + /* + * Class... + */ + + rptr = resource + 9; + } + else if (!strncmp(resource, "/printers/", 10)) + { + /* + * Printer... + */ + + rptr = resource + 10; + } + else + { + /* + * Bad resource name... + */ + + return (NULL); + } + + /* + * See if the printer or class name exists... + */ + + p = cupsdFindDest(rptr); + + if (p == NULL && strchr(rptr, '@') == NULL) + return (NULL); + else if (p != NULL) + { + if (printer) + *printer = p; + + if (dtype) + *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED); + + return (p->name); + } + + /* + * Change localhost to the server name... + */ + + if (!strcasecmp(hostname, "localhost")) + strlcpy(hostname, ServerName, sizeof(hostname)); + + strlcpy(localname, hostname, sizeof(localname)); + + if (!strcasecmp(hostname, ServerName)) + { + /* + * 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)) + { + *lptr = '\0'; + break; + } + else + lptr = strchr(lptr + 1, '.'); + } + } + } + + DEBUG_printf(("localized hostname is \"%s\"...\n", localname)); + + /* + * Find a matching printer or class... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (!strcasecmp(p->hostname, localname) && + !strcasecmp(p->name, rptr)) + { + if (printer) + *printer = p; + + if (dtype) + *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_IMPLICIT | + CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED); + + return (p->name); + } + + return (NULL); +} + + +/* + * 'cupsdWritePrintcap()' - Write a pseudo-printcap file for older applications + * that need it... + */ + +void +cupsdWritePrintcap(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* Printcap file */ + cupsd_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 || !*Printcap) + return; + + cupsdLogMessage(CUPSD_LOG_INFO, "Generating printcap %s...", Printcap); + + /* + * Open the printcap file... + */ + + if ((fp = cupsFileOpen(Printcap, "w")) == NULL) + return; + + /* + * Put a comment header at the top so that users will know where the + * data has come from... + */ + + if (PrintcapFormat != PRINTCAP_PLIST) + cupsFilePrintf(fp, "# This file was automatically generated by cupsd(8) " + "from the\n" + "# %s/printers.conf file. All changes to this file\n" + "# will be lost.\n", ServerRoot); + + /* + * 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) + cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", DefaultPrinter->name, + DefaultPrinter->info, ServerName, + DefaultPrinter->name); + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + if (p != DefaultPrinter) + cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", p->name, p->info, + ServerName, p->name); + break; + + case PRINTCAP_PLIST : + /* + * Each printer is written as a dictionary in a plist file. + * Currently the printer-name, printer-info, printer-is-accepting-jobs, + * printer-location, printer-make-and-model, printer-state, + * printer-state-reasons, printer-type, and (sanitized) device-uri. + */ + + cupsFilePuts(fp, "\n" + "\n" + "\n" + "\n"); + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + cupsFilePuts(fp, "\t\n" + "\t\tprinter-name\n" + "\t\t"); + write_xml_string(fp, p->name); + cupsFilePuts(fp, "\n" + "\t\tprinter-info\n" + "\t\t"); + write_xml_string(fp, p->info); + cupsFilePrintf(fp, "\n" + "\t\tprinter-is-accepting-jobs\n" + "\t\t<%s/>\n" + "\t\tprinter-location\n" + "\t\t", p->accepting ? "true" : "false"); + write_xml_string(fp, p->location); + cupsFilePuts(fp, "\n" + "\t\tprinter-make-and-model\n" + "\t\t"); + write_xml_string(fp, p->make_model); + cupsFilePrintf(fp, "\n" + "\t\tprinter-state\n" + "\t\t%d\n" + "\t\tprinter-state-reasons\n" + "\t\t\n", p->state); + for (i = 0; i < p->num_reasons; i ++) + { + cupsFilePuts(fp, "\t\t\t"); + write_xml_string(fp, p->reasons[i]); + cupsFilePuts(fp, "\n"); + } + cupsFilePrintf(fp, "\t\t\n" + "\t\tprinter-type\n" + "\t\t%d\n" + "\t\tdevice-uri\n" + "\t\t", p->type); + write_xml_string(fp, p->sanitized_device_uri); + cupsFilePuts(fp, "\n" + "\t\n"); + } + cupsFilePuts(fp, "\n" + "\n"); + 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: + */ + + cupsFilePuts(fp, "_all:all="); + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayCurrent(Printers)) + cupsFilePrintf(fp, "%s%c", p->name, + cupsArrayNext(Printers) ? ',' : '\n'); + + if (DefaultPrinter) + cupsFilePrintf(fp, "_default:use=%s\n", DefaultPrinter->name); + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + cupsFilePrintf(fp, "%s:\\\n" + "\t:bsdaddr=%s,%s:\\\n" + "\t:description=%s:\n", + p->name, ServerName, p->name, + p->info ? p->info : ""); + break; + } + + /* + * Close the file... + */ + + cupsFileClose(fp); +} + + +/* + * 'add_printer_defaults()' - Add name-default attributes to the printer attributes. + */ + +static void +add_printer_defaults(cupsd_printer_t *p)/* I - Printer */ +{ + int i; /* Looping var */ + int num_options; /* Number of default options */ + cups_option_t *options, /* Default options */ + *option; /* Current option */ + char name[256]; /* name-default */ + + + /* + * Maintain a common array of default attribute names... + */ + + if (!CommonDefaults) + { + CommonDefaults = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("copies-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("document-format-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("finishings-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-hold-until-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-priority-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-sheets-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("media-col-default")); + cupsArrayAdd(CommonDefaults, _cupsStrAlloc("number-up-default")); + cupsArrayAdd(CommonDefaults, + _cupsStrAlloc("orientation-requested-default")); + } + + /* + * Add all of the default options from the .conf files... + */ + + for (num_options = 0, options = NULL, i = p->num_options, option = p->options; + i > 0; + i --, option ++) + { + if (strcmp(option->name, "ipp-options") && + strcmp(option->name, "job-sheets") && + strcmp(option->name, "lease-duration")) + { + snprintf(name, sizeof(name), "%s-default", option->name); + num_options = cupsAddOption(name, option->value, num_options, &options); + + if (!cupsArrayFind(CommonDefaults, name)) + cupsArrayAdd(CommonDefaults, _cupsStrAlloc(name)); + } + } + + /* + * Convert options to IPP attributes... + */ + + cupsEncodeOptions2(p->attrs, num_options, options, IPP_TAG_PRINTER); + cupsFreeOptions(num_options, options); + + /* + * Add standard -default attributes as needed... + */ + + if (!cupsGetOption("copies", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default", + 1); + + if (!cupsGetOption("document-format", p->num_options, p->options)) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, + "document-format-default", NULL, "application/octet-stream"); + + if (!cupsGetOption("job-hold-until", p->num_options, p->options)) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "job-hold-until-default", NULL, "no-hold"); + + if (!cupsGetOption("job-priority", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "job-priority-default", 50); + + if (!cupsGetOption("number-up", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "number-up-default", 1); + + if (!cupsGetOption("notify-lease-duration", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "notify-lease-duration-default", DefaultLeaseDuration); + + if (!cupsGetOption("notify-events", p->num_options, p->options)) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "notify-events-default", NULL, "job-completed"); + + if (!cupsGetOption("orientation-requested", p->num_options, p->options)) + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NOVALUE, + "orientation-requested-default", NULL, NULL); + + if (!cupsGetOption("print-quality", p->num_options, p->options)) + ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "print-quality-default", IPP_QUALITY_NORMAL); +} + + +/* + * 'add_printer_filter()' - Add a MIME filter for a printer. + */ + +static void +add_printer_filter( + cupsd_printer_t *p, /* I - Printer to add to */ + mime_type_t *filtertype, /* I - Filter or prefilter MIME type */ + const char *filter) /* I - Filter to add */ +{ + 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 */ + char filename[1024], /* Full filter filename */ + *dirsep; /* Pointer to directory separator */ + struct stat fileinfo; /* File information */ + + + /* + * Parse the filter string; it should be in the following format: + * + * super/type cost program + */ + + if (sscanf(filter, "%15[^/]/%31s%d%*[ \t]%1023[^\n]", super, type, &cost, + program) != 4) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "%s: invalid filter string \"%s\"!", + p->name, filter); + return; + } + + /* + * See if the filter program exists; if not, stop the printer and flag + * the error! + */ + + if (strcmp(program, "-")) + { + if (program[0] == '/') + strlcpy(filename, program, sizeof(filename)); + else + snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program); + + if (stat(filename, &fileinfo)) + { + memset(&fileinfo, 0, sizeof(fileinfo)); + + snprintf(p->state_message, sizeof(p->state_message), + "Filter \"%s\" for printer \"%s\" not available: %s", + filename, p->name, strerror(errno)); + cupsdSetPrinterReasons(p, "+cups-missing-filter-warning"); + + cupsdLogMessage(CUPSD_LOG_ERROR, "%s", p->state_message); + } + + /* + * When running as root, do additional security checks... + */ + + if (!RunUser) + { + /* + * Only use filters that are owned by root and do not have world write + * permissions. + */ + + if (fileinfo.st_uid || (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0) + { + if (fileinfo.st_uid) + snprintf(p->state_message, sizeof(p->state_message), + "Filter \"%s\" for printer \"%s\" not owned by root", + filename, p->name); + else + snprintf(p->state_message, sizeof(p->state_message), + "Filter \"%s\" for printer \"%s\" has insecure permissions " + "(0%o)", filename, p->name, fileinfo.st_mode); + + cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"); + + cupsdLogMessage(CUPSD_LOG_ERROR, "%s", p->state_message); + } + else if (fileinfo.st_mode) + { + /* + * Similarly, check that the parent directory is also owned by root and + * does not have world write permissions. + */ + + if ((dirsep = strrchr(filename, '/')) != NULL) + *dirsep = '\0'; + + if (!stat(filename, &fileinfo) && + (fileinfo.st_uid || + (fileinfo.st_mode & (S_ISUID | S_IWOTH)) != 0)) + { + if (fileinfo.st_uid) + snprintf(p->state_message, sizeof(p->state_message), + "Filter directory \"%s\" for printer \"%s\" not owned by " + "root", filename, p->name); + else + snprintf(p->state_message, sizeof(p->state_message), + "Filter directory \"%s\" for printer \"%s\" has insecure " + "permissions (0%o)", filename, p->name, fileinfo.st_mode); + + cupsdSetPrinterReasons(p, "+cups-insecure-filter-warning"); + + cupsdLogMessage(CUPSD_LOG_ERROR, "%s", p->state_message); + } + } + } + } + + /* + * Add the filter to the MIME database, supporting wildcards as needed... + */ + + for (temptype = mimeFirstType(MimeDatabase); + temptype; + temptype = mimeNextType(MimeDatabase)) + if (((super[0] == '*' && strcasecmp(temptype->super, "printer")) || + !strcasecmp(temptype->super, super)) && + (type[0] == '*' || !strcasecmp(temptype->type, type))) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_filter: %s: adding filter %s/%s %s/%s %d %s", + p->name, temptype->super, temptype->type, + filtertype->super, filtertype->type, + cost, program); + mimeAddFilter(MimeDatabase, temptype, filtertype, cost, program); + } +} + + +/* + * 'add_printer_formats()' - Add document-format-supported values for a printer. + */ + +static void +add_printer_formats(cupsd_printer_t *p) /* I - Printer */ +{ + int i; /* Looping var */ + mime_type_t *type; /* Current MIME type */ + cups_array_t *filters; /* Filters */ + ipp_attribute_t *attr; /* document-format-supported attribute */ + char mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2]; + /* MIME type name */ + + + /* + * Raw (and remote) queues advertise all of the supported MIME + * types... + */ + + cupsArrayDelete(p->filetypes); + p->filetypes = NULL; + + if (p->raw) + { + ippAddStrings(p->attrs, IPP_TAG_PRINTER, + (ipp_tag_t)(IPP_TAG_MIMETYPE | IPP_TAG_COPY), + "document-format-supported", NumMimeTypes, NULL, MimeTypes); + return; + } + + /* + * Otherwise, loop through the supported MIME types and see if there + * are filters for them... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer_formats: %d types, %d filters", + mimeNumTypes(MimeDatabase), mimeNumFilters(MimeDatabase)); + + p->filetypes = cupsArrayNew(NULL, NULL); + + for (type = mimeFirstType(MimeDatabase); + type; + type = mimeNextType(MimeDatabase)) + { + snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type); + + if ((filters = mimeFilter(MimeDatabase, type, p->filetype, NULL)) != NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_formats: %s: %s needs %d filters", + p->name, mimetype, cupsArrayCount(filters)); + + cupsArrayDelete(filters); + cupsArrayAdd(p->filetypes, type); + } + else + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_formats: %s: %s not supported", + p->name, mimetype); + } + + /* + * Add the file formats that can be filtered... + */ + + if ((type = mimeType(MimeDatabase, "application", "octet-stream")) == NULL || + !cupsArrayFind(p->filetypes, type)) + i = 1; + else + i = 0; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "add_printer_formats: %s: %d supported types", + p->name, cupsArrayCount(p->filetypes) + i); + + attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE, + "document-format-supported", + cupsArrayCount(p->filetypes) + i, NULL, NULL); + + if (i) + attr->values[0].string.text = _cupsStrAlloc("application/octet-stream"); + + for (type = (mime_type_t *)cupsArrayFirst(p->filetypes); + type; + i ++, type = (mime_type_t *)cupsArrayNext(p->filetypes)) + { + snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type); + + attr->values[i].string.text = _cupsStrAlloc(mimetype); + } + +#ifdef HAVE_DNSSD + { + char pdl[1024]; /* Buffer to build pdl list */ + mime_filter_t *filter; /* MIME filter looping var */ + + + /* + * We only support raw printing if this is not a Tioga PrintJobMgr based + * queue and if application/octet-stream is a known type... + */ + + for (filter = (mime_filter_t *)cupsArrayFirst(MimeDatabase->filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(MimeDatabase->filters)) + { + if (filter->dst == p->filetype && filter->filter && + strstr(filter->filter, "PrintJobMgr")) + break; + } + + pdl[0] = '\0'; + + if (!filter && mimeType(MimeDatabase, "application", "octet-stream")) + strlcat(pdl, "application/octet-stream,", sizeof(pdl)); + + /* + * Then list a bunch of formats that are supported by the printer... + */ + + for (type = (mime_type_t *)cupsArrayFirst(p->filetypes); + type; + type = (mime_type_t *)cupsArrayNext(p->filetypes)) + { + if (!strcasecmp(type->super, "application")) + { + if (!strcasecmp(type->type, "pdf")) + strlcat(pdl, "application/pdf,", sizeof(pdl)); + else if (!strcasecmp(type->type, "postscript")) + strlcat(pdl, "application/postscript,", sizeof(pdl)); + } + else if (!strcasecmp(type->super, "image")) + { + if (!strcasecmp(type->type, "jpeg")) + strlcat(pdl, "image/jpeg,", sizeof(pdl)); + else if (!strcasecmp(type->type, "png")) + strlcat(pdl, "image/png,", sizeof(pdl)); + } + } + + if (pdl[0]) + pdl[strlen(pdl) - 1] = '\0'; /* Remove trailing comma */ + + cupsdSetString(&p->pdl, pdl); + } +#endif /* HAVE_DNSSD */ +} + + +/* + * 'add_string_array()' - Add a string to an array of CUPS strings. + */ + +static void +add_string_array(cups_array_t **a, /* I - Array */ + const char *s) /* I - String */ +{ + if (!*a) + *a = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(*a, _cupsStrAlloc(s)); +} + + +/* + * 'compare_printers()' - Compare two printers. + */ + +static int /* O - Result of comparison */ +compare_printers(void *first, /* I - First printer */ + void *second, /* I - Second printer */ + void *data) /* I - App data (not used) */ +{ + return (strcasecmp(((cupsd_printer_t *)first)->name, + ((cupsd_printer_t *)second)->name)); +} + + +/* + * 'delete_printer_filters()' - Delete all MIME filters for a printer. + */ + +static void +delete_printer_filters( + cupsd_printer_t *p) /* I - Printer to remove from */ +{ + 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 = mimeFirstFilter(MimeDatabase); + filter; + filter = mimeNextFilter(MimeDatabase)) + if (filter->dst == p->filetype || filter->dst == p->prefiltertype) + { + /* + * Delete the current filter... + */ + + mimeDeleteFilter(MimeDatabase, filter); + } + + cupsdSetPrinterReasons(p, "-cups-insecure-filter-warning" + ",cups-missing-filter-warning"); +} + + +/* + * 'delete_string_array()' - Delete an array of CUPS strings. + */ + +static void +delete_string_array(cups_array_t **a) /* I - Array */ +{ + char *ptr; /* Current string */ + + + for (ptr = (char *)cupsArrayFirst(*a); + ptr; + ptr = (char *)cupsArrayNext(*a)) + _cupsStrFree(ptr); + + cupsArrayDelete(*a); + *a = NULL; +} + + +/* + * 'dirty_printer()' - Mark config and state files dirty for the specified + * printer. + */ + +static void +dirty_printer(cupsd_printer_t *p) /* I - Printer */ +{ + if (p->type & CUPS_PRINTER_DISCOVERED) + cupsdMarkDirty(CUPSD_DIRTY_REMOTE); + else if (p->type & CUPS_PRINTER_CLASS) + cupsdMarkDirty(CUPSD_DIRTY_CLASSES); + else + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + if (PrintcapFormat == PRINTCAP_PLIST) + cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP); +} + + +/* + * 'load_ppd()' - Load a cached PPD file, updating the cache as needed. + */ + +static void +load_ppd(cupsd_printer_t *p) /* I - Printer */ +{ + int i, j, k; /* Looping vars */ + cups_file_t *cache; /* IPP cache file */ + char cache_name[1024]; /* IPP cache filename */ + struct stat cache_info; /* IPP cache file info */ + char pwg_name[1024]; /* PWG cache filename */ + struct stat pwg_info; /* PWG cache file info */ + ppd_file_t *ppd; /* PPD file */ + char ppd_name[1024]; /* PPD filename */ + struct stat ppd_info; /* PPD file info */ + int num_media; /* Number of media options */ + ppd_size_t *size; /* Current PPD size */ + ppd_option_t *duplex, /* Duplex option */ + *output_bin, /* OutputBin option */ + *output_mode, /* OutputMode option */ + *resolution; /* (Set|JCL|)Resolution option */ + ppd_choice_t *choice, /* Current PPD choice */ + *input_slot, /* Current input slot */ + *media_type; /* Current media type */ + ppd_attr_t *ppd_attr; /* PPD attribute */ + int xdpi, /* Horizontal resolution */ + ydpi; /* Vertical resolution */ + const char *resptr; /* Pointer into resolution keyword */ + _pwg_size_t *pwgsize; /* Current PWG size */ + _pwg_map_t *pwgsource, /* Current PWG source */ + *pwgtype; /* Current PWG type */ + ipp_attribute_t *attr; /* Attribute data */ + ipp_value_t *val; /* Attribute value */ + int num_finishings, /* Number of finishings */ + finishings[5]; /* finishings-supported values */ + int num_qualities, /* Number of print-quality values */ + qualities[3]; /* print-quality values */ + int num_margins, /* Number of media-*-margin-supported values */ + margins[16]; /* media-*-margin-supported values */ + static const char * const sides[3] = /* sides-supported values */ + { + "one-sided", + "two-sided-long-edge", + "two-sided-short-edge" + }; + static const char * const standard_commands[] = + { /* Standard CUPS commands */ + "AutoConfigure", + "Clean", + "PrintSelfTestPage" + }; + + + /* + * Check to see if the cache is up-to-date... + */ + + snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp4", CacheDir, p->name); + if (stat(cache_name, &cache_info)) + cache_info.st_mtime = 0; + + snprintf(pwg_name, sizeof(pwg_name), "%s/%s.pwg3", CacheDir, p->name); + if (stat(pwg_name, &pwg_info)) + pwg_info.st_mtime = 0; + + snprintf(ppd_name, sizeof(ppd_name), "%s/ppd/%s.ppd", ServerRoot, p->name); + if (stat(ppd_name, &ppd_info)) + ppd_info.st_mtime = 1; + + ippDelete(p->ppd_attrs); + p->ppd_attrs = ippNew(); + + _pwgDestroy(p->pwg); + p->pwg = NULL; + + if (pwg_info.st_mtime >= ppd_info.st_mtime) + p->pwg = _pwgCreateWithFile(pwg_name); + + if (cache_info.st_mtime >= ppd_info.st_mtime && p->pwg && + (cache = cupsFileOpen(cache_name, "r")) != NULL) + { + /* + * Load cached information and return... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Loading %s...", cache_name); + + if (ippReadIO(cache, (ipp_iocb_t)cupsFileRead, 1, NULL, + p->ppd_attrs) == IPP_DATA) + { + cupsFileClose(cache); + return; + } + + cupsFileClose(cache); + } + + /* + * Reload PPD attributes from disk... + */ + + cupsdMarkDirty(CUPSD_DIRTY_PRINTERS); + + _pwgDestroy(p->pwg); + p->pwg = NULL; + + cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Loading %s...", ppd_name); + + delete_string_array(&(p->filters)); + delete_string_array(&(p->pre_filters)); + + p->type &= ~CUPS_PRINTER_OPTIONS; + p->type |= CUPS_PRINTER_BW; + + finishings[0] = IPP_FINISHINGS_NONE; + num_finishings = 1; + + if ((ppd = ppdOpenFile(ppd_name)) != NULL) + { + /* + * Add make/model and other various attributes... + */ + + p->pwg = _pwgCreateWithPPD(ppd); + + ppdMarkDefaults(ppd); + + 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; + if ((ppd_attr = ppdFindAttr(ppd, "cupsFax", NULL)) != NULL) + if (ppd_attr->value && !strcasecmp(ppd_attr->value, "true")) + p->type |= CUPS_PRINTER_FAX; + + ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "color-supported", + ppd->color_device); + if (ppd->throughput) + { + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "pages-per-minute", ppd->throughput); + if (ppd->color_device) + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "pages-per-minute-color", ppd->throughput); + } + + num_qualities = 0; + + if ((output_mode = ppdFindOption(ppd, "OutputMode")) != NULL) + { + if (ppdFindChoice(output_mode, "draft") || + ppdFindChoice(output_mode, "fast")) + qualities[num_qualities ++] = IPP_QUALITY_DRAFT; + + qualities[num_qualities ++] = IPP_QUALITY_NORMAL; + + if (ppdFindChoice(output_mode, "best") || + ppdFindChoice(output_mode, "high")) + qualities[num_qualities ++] = IPP_QUALITY_HIGH; + } + else if ((ppd_attr = ppdFindAttr(ppd, "APPrinterPreset", NULL)) != NULL) + { + do + { + if (strstr(ppd_attr->spec, "draft") || + strstr(ppd_attr->spec, "Draft")) + { + qualities[num_qualities ++] = IPP_QUALITY_DRAFT; + break; + } + } + while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset", + NULL)) != NULL); + + qualities[num_qualities ++] = IPP_QUALITY_NORMAL; + qualities[num_qualities ++] = IPP_QUALITY_HIGH; + } + else + qualities[num_qualities ++] = IPP_QUALITY_NORMAL; + + ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "print-quality-supported", num_qualities, qualities); + + if (ppd->nickname) + { + /* + * The NickName can be localized in the character set specified + * by the LanugageEncoding attribute. However, ppdOpen2() has + * already converted the ppd->nickname member to UTF-8 for us + * (the original attribute value is available separately) + */ + + cupsdSetString(&p->make_model, ppd->nickname); + } + else if (ppd->modelname) + { + /* + * Model name can only contain specific characters... + */ + + cupsdSetString(&p->make_model, ppd->modelname); + } + else + cupsdSetString(&p->make_model, "Bad PPD File"); + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-make-and-model", NULL, p->make_model); + + /* + * Add media options from the PPD file... + */ + + if (ppd->num_sizes == 0 || !p->pwg) + { + if (!ppdFindAttr(ppd, "APScannerOnly", NULL)) + cupsdLogMessage(CUPSD_LOG_CRIT, + "The PPD file for printer %s contains no media " + "options and is therefore invalid!", p->name); + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, "unknown"); + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-supported", NULL, "unknown"); + } + else + { + /* + * media-default + */ + + if ((size = ppdPageSize(ppd, NULL)) != NULL) + pwgsize = _pwgGetSize(p->pwg, size->name); + else + pwgsize = NULL; + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-default", NULL, + pwgsize ? pwgsize->map.pwg : "unknown"); + + /* + * media-col-default + */ + + if (pwgsize) + { + ipp_t *col; /* Collection value */ + + input_slot = ppdFindMarkedChoice(ppd, "InputSlot"); + media_type = ppdFindMarkedChoice(ppd, "MediaType"); + col = new_media_col(pwgsize, + input_slot ? + _pwgGetSource(p->pwg, + input_slot->choice) : + NULL, + media_type ? + _pwgGetType(p->pwg, + media_type->choice) : + NULL); + + ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default", + col); + ippDelete(col); + } + + /* + * media-supported + */ + + num_media = p->pwg->num_sizes; + if (p->pwg->custom_min_keyword) + num_media += 2; + + if ((attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-supported", num_media, NULL, + NULL)) != NULL) + { + val = attr->values; + + for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes; + i > 0; + i --, pwgsize ++, val ++) + val->string.text = _cupsStrRetain(pwgsize->map.pwg); + + if (p->pwg->custom_min_keyword) + { + val->string.text = _cupsStrRetain(p->pwg->custom_min_keyword); + val ++; + val->string.text = _cupsStrRetain(p->pwg->custom_max_keyword); + } + } + + /* + * media-source-supported + */ + + if (p->pwg->num_sources > 0 && + (attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-source-supported", p->pwg->num_sources, + NULL, NULL)) != NULL) + { + for (i = p->pwg->num_sources, pwgsource = p->pwg->sources, + val = attr->values; + i > 0; + i --, pwgsource ++, val ++) + val->string.text = _cupsStrRetain(pwgsource->pwg); + } + + /* + * media-type-supported + */ + + if (p->pwg->num_types > 0 && + (attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "media-type-supported", p->pwg->num_types, + NULL, NULL)) != NULL) + { + for (i = p->pwg->num_types, pwgtype = p->pwg->types, + val = attr->values; + i > 0; + i --, pwgtype ++, val ++) + val->string.text = _cupsStrRetain(pwgtype->pwg); + } + + /* + * media-*-margin-supported + */ + + for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0; + i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); + i --, pwgsize ++) + { + for (j = 0; j < num_margins; j ++) + if (pwgsize->bottom == margins[j]) + break; + + if (j >= num_margins) + { + margins[num_margins] = pwgsize->bottom; + num_margins ++; + } + } + + if (num_margins > 0) + ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-bottom-margin-supported", num_margins, margins); + else + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-bottom-margin-supported", 0); + + for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0; + i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); + i --, pwgsize ++) + { + for (j = 0; j < num_margins; j ++) + if (pwgsize->left == margins[j]) + break; + + if (j >= num_margins) + { + margins[num_margins] = pwgsize->left; + num_margins ++; + } + } + + if (num_margins > 0) + ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-left-margin-supported", num_margins, margins); + else + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-left-margin-supported", 0); + + for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0; + i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); + i --, pwgsize ++) + { + for (j = 0; j < num_margins; j ++) + if (pwgsize->right == margins[j]) + break; + + if (j >= num_margins) + { + margins[num_margins] = pwgsize->right; + num_margins ++; + } + } + + if (num_margins > 0) + ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-right-margin-supported", num_margins, margins); + else + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-right-margin-supported", 0); + + for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, num_margins = 0; + i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0])); + i --, pwgsize ++) + { + for (j = 0; j < num_margins; j ++) + if (pwgsize->top == margins[j]) + break; + + if (j >= num_margins) + { + margins[num_margins] = pwgsize->top; + num_margins ++; + } + } + + if (num_margins > 0) + ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-top-margin-supported", num_margins, margins); + else + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-top-margin-supported", 0); + + /* + * media-col-database + */ + + num_media = p->pwg->num_sizes; + if (p->pwg->num_sources) + { + if (p->pwg->num_types > 0) + num_media += p->pwg->num_sizes * p->pwg->num_sources * + p->pwg->num_types; + else + num_media += p->pwg->num_sizes * p->pwg->num_sources; + } + else if (p->pwg->num_types) + num_media += p->pwg->num_sizes * p->pwg->num_types; + + if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, + "media-col-database", num_media, + NULL)) != NULL) + { + for (i = p->pwg->num_sizes, pwgsize = p->pwg->sizes, val = attr->values; + i > 0; + i --, pwgsize ++) + { + /* + * Start by adding the page size without source or type... + */ + + ppdMarkOption(ppd, "PageSize", pwgsize->map.ppd); + + val->collection = new_media_col(pwgsize, NULL, NULL); + val ++; + + /* + * Then add the specific, supported combinations of size, source, and + * type... + */ + + if (p->pwg->num_sources > 0) + { + for (j = p->pwg->num_sources, pwgsource = p->pwg->sources; + j > 0; + j --, pwgsource ++) + { + ppdMarkOption(ppd, "InputSlot", pwgsource->ppd); + + if (p->pwg->num_types > 0) + { + for (k = p->pwg->num_types, pwgtype = p->pwg->types; + k > 0; + k --, pwgtype ++) + { + if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd)) + { + val->collection = new_media_col(pwgsize, pwgsource->pwg, + pwgtype->pwg); + val ++; + } + } + } + else if (!ppdConflicts(ppd)) + { + val->collection = new_media_col(pwgsize, pwgsource->pwg, NULL); + val ++; + } + } + } + else if (p->pwg->num_types > 0) + { + for (j = p->pwg->num_types, pwgtype = p->pwg->types; + j > 0; + j --, pwgtype ++) + { + if (!ppdMarkOption(ppd, "MediaType", pwgtype->ppd)) + { + val->collection = new_media_col(pwgsize, NULL, pwgtype->pwg); + val ++; + } + } + } + } + + /* + * Update the number of media-col-database values... + */ + + attr->num_values = val - attr->values; + } + } + + /* + * Output bin... + */ + + if (p->pwg && p->pwg->num_bins > 0) + { + attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-supported", p->pwg->num_bins, + NULL, NULL); + + if (attr != NULL) + { + for (i = 0, val = attr->values; + i < p->pwg->num_bins; + i ++, val ++) + val->string.text = _cupsStrAlloc(p->pwg->bins[i].pwg); + } + + if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL) + { + for (i = 0; i < p->pwg->num_bins; i ++) + if (!strcmp(p->pwg->bins[i].ppd, output_bin->defchoice)) + break; + + if (i >= p->pwg->num_bins) + i = 0; + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-default", NULL, p->pwg->bins[i].pwg); + } + else + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-default", NULL, p->pwg->bins[0].pwg); + } + else if (((ppd_attr = ppdFindAttr(ppd, "DefaultOutputOrder", + NULL)) != NULL && + !strcasecmp(ppd_attr->value, "Reverse")) || + (!ppd_attr && ppd->manufacturer && /* "Compatibility heuristic" */ + (!strcasecmp(ppd->manufacturer, "epson") || + !strcasecmp(ppd->manufacturer, "lexmark")))) + { + /* + * Report that this printer has a single output bin that leaves pages face + * up. + */ + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-supported", NULL, "face-up"); + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-default", NULL, "face-up"); + } + else + { + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-supported", NULL, "face-down"); + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-bin-default", NULL, "face-down"); + } + + /* + * output-mode... + */ + + if (ppd->color_device) + { + static const char * const output_modes[] = + { + "monochrome", + "color" + }; + + ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-mode-supported", 2, NULL, output_modes); + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-mode-default", NULL, "color"); + } + else + { + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-mode-supported", NULL, "monochrome"); + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "output-mode-default", NULL, "monochrome"); + } + + /* + * Printer resolutions... + */ + + if ((resolution = ppdFindOption(ppd, "Resolution")) == NULL) + if ((resolution = ppdFindOption(ppd, "JCLResolution")) == NULL) + if ((resolution = ppdFindOption(ppd, "SetResolution")) == NULL) + resolution = ppdFindOption(ppd, "CNRes_PGP"); + + if (resolution) + { + /* + * Report all supported resolutions... + */ + + attr = ippAddResolutions(p->ppd_attrs, IPP_TAG_PRINTER, + "printer-resolution-supported", + resolution->num_choices, IPP_RES_PER_INCH, + NULL, NULL); + + for (i = 0, choice = resolution->choices; + i < resolution->num_choices; + i ++, choice ++) + { + xdpi = ydpi = (int)strtol(choice->choice, (char **)&resptr, 10); + if (resptr > choice->choice && xdpi > 0 && *resptr == 'x') + ydpi = (int)strtol(resptr + 1, (char **)&resptr, 10); + + if (xdpi <= 0 || ydpi <= 0) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Bad resolution \"%s\" for printer %s.", + choice->choice, p->name); + xdpi = ydpi = 300; + } + + attr->values[i].resolution.xres = xdpi; + attr->values[i].resolution.yres = ydpi; + attr->values[i].resolution.units = IPP_RES_PER_INCH; + + if (choice->marked) + ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, + "printer-resolution-default", IPP_RES_PER_INCH, + xdpi, ydpi); + } + } + else if ((ppd_attr = ppdFindAttr(ppd, "DefaultResolution", NULL)) != NULL && + ppd_attr->value) + { + /* + * Just the DefaultResolution to report... + */ + + xdpi = ydpi = (int)strtol(ppd_attr->value, (char **)&resptr, 10); + if (resptr > ppd_attr->value && xdpi > 0) + { + if (*resptr == 'x') + ydpi = (int)strtol(resptr + 1, (char **)&resptr, 10); + else + ydpi = xdpi; + } + + if (xdpi <= 0 || ydpi <= 0) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "Bad default resolution \"%s\" for printer %s.", + ppd_attr->value, p->name); + xdpi = ydpi = 300; + } + + ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, + "printer-resolution-default", IPP_RES_PER_INCH, + xdpi, ydpi); + ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, + "printer-resolution-supported", IPP_RES_PER_INCH, + xdpi, ydpi); + } + else + { + /* + * No resolutions in PPD - make one up... + */ + + ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, + "printer-resolution-default", IPP_RES_PER_INCH, + 300, 300); + ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, + "printer-resolution-supported", IPP_RES_PER_INCH, + 300, 300); + } + + /* + * Duplexing, etc... + */ + + ppdMarkDefaults(ppd); + + if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL) + if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL) + if ((duplex = ppdFindOption(ppd, "KD03Duplex")) == NULL) + duplex = ppdFindOption(ppd, "JCLDuplex"); + + if (duplex && duplex->num_choices > 1 && + !ppdInstallableConflict(ppd, duplex->keyword, "DuplexTumble")) + { + p->type |= CUPS_PRINTER_DUPLEX; + + ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-supported", 3, NULL, sides); + + if (!strcasecmp(duplex->defchoice, "DuplexTumble")) + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "two-sided-short-edge"); + else if (!strcasecmp(duplex->defchoice, "DuplexNoTumble")) + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "two-sided-long-edge"); + else + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "one-sided"); + } + else + { + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-supported", NULL, "one-sided"); + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "sides-default", NULL, "one-sided"); + } + + 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; + + if ((ppd_attr = ppdFindAttr(ppd, "APICADriver", NULL)) != NULL && + ppd_attr->value && !strcasecmp(ppd_attr->value, "true")) + { + if ((ppd_attr = ppdFindAttr(ppd, "APScannerOnly", NULL)) != NULL && + ppd_attr->value && !strcasecmp(ppd_attr->value, "true")) + p->type |= CUPS_PRINTER_SCANNER; + else + p->type |= CUPS_PRINTER_MFP; + } + + /* + * Add a filter from application/vnd.cups-raw to printer/name to + * handle "raw" printing by users. + */ + + add_string_array(&(p->filters), "application/vnd.cups-raw 0 -"); + + /* + * Add any pre-filters in the PPD file... + */ + + if ((ppd_attr = ppdFindAttr(ppd, "cupsPreFilter", NULL)) != NULL) + { + for (; ppd_attr; ppd_attr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL)) + if (ppd_attr->value) + add_string_array(&(p->pre_filters), ppd_attr->value); + } + + /* + * 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])); + add_string_array(&(p->filters), ppd->filters[i]); + + if (!strncasecmp(ppd->filters[i], "application/vnd.cups-command", 28) && + isspace(ppd->filters[i][28] & 255)) + p->type |= CUPS_PRINTER_COMMANDS; + } + + if ((ppd_attr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL && + ppd_attr->value && + (!ppd_attr->value[0] || !strcasecmp(ppd_attr->value, "none"))) + { + /* + * Printer does not support CUPS command files (or any commands as far as + * CUPS is concerned... + */ + + p->type &= ~CUPS_PRINTER_COMMANDS; + } + else if (ppd->num_filters == 0) + { + /* + * If there are no filters, add PostScript printing filters. + */ + + add_string_array(&(p->filters), + "application/vnd.cups-command 0 commandtops"); + add_string_array(&(p->filters), + "application/vnd.cups-postscript 0 -"); + + p->type |= CUPS_PRINTER_COMMANDS; + } + else if (!(p->type & CUPS_PRINTER_COMMANDS)) + { + /* + * See if this is a PostScript device without a command filter... + */ + + for (i = 0; i < ppd->num_filters; i ++) + if (!strncasecmp(ppd->filters[i], + "application/vnd.cups-postscript", 31) && + isspace(ppd->filters[i][31] & 255)) + break; + + if (i < ppd->num_filters) + { + /* + * Add the generic PostScript command filter... + */ + + add_string_array(&(p->filters), + "application/vnd.cups-command 0 commandtops"); + p->type |= CUPS_PRINTER_COMMANDS; + } + } + + if (p->type & CUPS_PRINTER_COMMANDS) + { + char *commands, /* Copy of commands */ + *start, /* Start of name */ + *end; /* End of name */ + int count; /* Number of commands */ + + + if (ppd_attr && ppd_attr->value && ppd_attr->value[0]) + { + for (count = 0, start = ppd_attr->value; *start; count ++) + { + while (isspace(*start & 255)) + start ++; + + if (!*start) + break; + + while (*start && !isspace(*start & 255)) + start ++; + } + } + else + count = 0; + + if (count > 0) + { + /* + * Make a copy of the commands string and count how many commands there + * are... + */ + + attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-commands", count, NULL, NULL); + + commands = strdup(ppd_attr->value); + + for (count = 0, start = commands; *start; count ++) + { + while (isspace(*start & 255)) + start ++; + + if (!*start) + break; + + end = start; + while (*end && !isspace(*end & 255)) + end ++; + + if (*end) + *end++ = '\0'; + + attr->values[count].string.text = _cupsStrAlloc(start); + + start = end; + } + + free(commands); + } + else + { + /* + * Add the standard list of commands... + */ + + ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-commands", + (int)(sizeof(standard_commands) / + sizeof(standard_commands[0])), NULL, + standard_commands); + } + } + else + { + /* + * No commands supported... + */ + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, + "printer-commands", NULL, "none"); + } + + /* + * Show current and available port monitors for this printer... + */ + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", + NULL, p->port_monitor ? p->port_monitor : "none"); + + for (i = 1, ppd_attr = ppdFindAttr(ppd, "cupsPortMonitor", NULL); + ppd_attr; + i ++, ppd_attr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL)); + + if (ppd->protocols) + { + if (strstr(ppd->protocols, "TBCP")) + i ++; + else if (strstr(ppd->protocols, "BCP")) + i ++; + } + + attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, + "port-monitor-supported", i, NULL, NULL); + + attr->values[0].string.text = _cupsStrAlloc("none"); + + for (i = 1, ppd_attr = ppdFindAttr(ppd, "cupsPortMonitor", NULL); + ppd_attr; + i ++, ppd_attr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL)) + attr->values[i].string.text = _cupsStrAlloc(ppd_attr->value); + + if (ppd->protocols) + { + if (strstr(ppd->protocols, "TBCP")) + attr->values[i].string.text = _cupsStrAlloc("tbcp"); + else if (strstr(ppd->protocols, "BCP")) + attr->values[i].string.text = _cupsStrAlloc("bcp"); + } + +#ifdef HAVE_DNSSD + cupsdSetString(&p->product, ppd->product); +#endif /* HAVE_DNSSD */ + + if (ppdFindAttr(ppd, "APRemoteQueueID", NULL)) + p->type |= CUPS_PRINTER_REMOTE; + +#ifdef HAVE_APPLICATIONSERVICES_H + /* + * Convert the file referenced in APPrinterIconPath to a 128x128 PNG + * and save it as cacheDir/printername.png + */ + + if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL && + ppd_attr->value) + { + CGImageRef imageRef = NULL;/* Current icon image */ + CGImageRef biggestIconRef = NULL; + /* Biggest icon image */ + CGImageRef closestTo128IconRef = NULL; + /* Icon image closest to and >= 128 */ + CGImageSourceRef sourceRef; /* The file's image source */ + char outPath[HTTP_MAX_URI]; + /* The path to the PNG file */ + CFURLRef outUrl; /* The URL made from the outPath */ + CFURLRef icnsFileUrl; /* The URL of the original ICNS icon file */ + CGImageDestinationRef destRef; /* The image destination to write */ + size_t bytesPerRow; /* The bytes per row used for resizing */ + CGContextRef context; /* The CG context used for resizing */ + + snprintf(outPath, sizeof(outPath), "%s/%s.png", CacheDir, p->name); + outUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + (UInt8 *)outPath, + strlen(outPath), + FALSE); + icnsFileUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + (UInt8 *)ppd_attr->value, + strlen(ppd_attr->value), + FALSE); + if (outUrl && icnsFileUrl) + { + sourceRef = CGImageSourceCreateWithURL(icnsFileUrl, NULL); + if (sourceRef) + { + for (i = 0; i < CGImageSourceGetCount(sourceRef); i ++) + { + imageRef = CGImageSourceCreateImageAtIndex(sourceRef, i, NULL); + if (imageRef && + CGImageGetWidth(imageRef) == CGImageGetHeight(imageRef)) + { + /* + * Loop through remembering the icon closest to 128 but >= 128 + * and then remember the largest icon. + */ + + if (CGImageGetWidth(imageRef) >= 128 && + (!closestTo128IconRef || + CGImageGetWidth(imageRef) < + CGImageGetWidth(closestTo128IconRef))) + { + CGImageRelease(closestTo128IconRef); + CGImageRetain(imageRef); + closestTo128IconRef = imageRef; + } + + if (!biggestIconRef || + CGImageGetWidth(imageRef) > CGImageGetWidth(biggestIconRef)) + { + CGImageRelease(biggestIconRef); + CGImageRetain(imageRef); + biggestIconRef = imageRef; + } + + CGImageRelease(imageRef); + } + } + + if (biggestIconRef) + { + /* + * If biggestIconRef is NULL, we found no icons. Otherwise we first + * want the closest to 128, but if none are larger than 128, we want + * the largest icon available. + */ + + imageRef = closestTo128IconRef ? closestTo128IconRef : + biggestIconRef; + CGImageRetain(imageRef); + CGImageRelease(biggestIconRef); + CGImageRelease(closestTo128IconRef); + destRef = CGImageDestinationCreateWithURL(outUrl, kUTTypePNG, 1, + NULL); + if (destRef) + { + if (CGImageGetWidth(imageRef) != 128) + { + bytesPerRow = CGImageGetBytesPerRow(imageRef) / + CGImageGetWidth(imageRef) * 128; + context = CGBitmapContextCreate(NULL, 128, 128, + CGImageGetBitsPerComponent(imageRef), + bytesPerRow, + CGImageGetColorSpace(imageRef), + kCGImageAlphaPremultipliedFirst); + if (context) + { + CGContextDrawImage(context, CGRectMake(0, 0, 128, 128), + imageRef); + CGImageRelease(imageRef); + imageRef = CGBitmapContextCreateImage(context); + CGContextRelease(context); + } + } + + CGImageDestinationAddImage(destRef, imageRef, NULL); + CGImageDestinationFinalize(destRef); + CFRelease(destRef); + } + } + + if (imageRef) + CGImageRelease(imageRef); + + CFRelease(sourceRef); + } + } + + if (outUrl) + CFRelease(outUrl); + + if (icnsFileUrl) + CFRelease(icnsFileUrl); + } +#endif /* HAVE_APPLICATIONSERVICES_H */ + + /* + * Close the PPD and set the type... + */ + + ppdClose(ppd); + } + else if (!access(ppd_name, 0)) + { + int pline; /* PPD line number */ + ppd_status_t pstatus; /* PPD load status */ + + + pstatus = ppdLastError(&pline); + + cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded!", + p->name); + + if (pstatus <= PPD_ALLOC_ERROR) + cupsdLogMessage(CUPSD_LOG_ERROR, "%s", strerror(errno)); + else + cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d.", + ppdErrorString(pstatus), pline); + + cupsdLogMessage(CUPSD_LOG_INFO, + "Hint: Run \"cupstestppd %s\" and fix any errors.", + ppd_name); + + /* + * Add a filter from application/vnd.cups-raw to printer/name to + * handle "raw" printing by users. + */ + + add_string_array(&(p->filters), "application/vnd.cups-raw 0 -"); + + /* + * Add a PostScript filter, since this is still possibly PS printer. + */ + + add_string_array(&(p->filters), "application/vnd.cups-postscript 0 -"); + } + else + { + /* + * If we have an interface script, add a filter entry for it... + */ + + char interface[1024]; /* Interface script */ + + + snprintf(interface, sizeof(interface), "%s/interfaces/%s", ServerRoot, + p->name); + if (!access(interface, X_OK)) + { + /* + * Yes, we have a System V style interface script; use it! + */ + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-make-and-model", NULL, + "Local System V Printer"); + + snprintf(interface, sizeof(interface), "*/* 0 %s/interfaces/%s", + ServerRoot, p->name); + add_string_array(&(p->filters), interface); + } + else if (!strncmp(p->device_uri, "ipp://", 6) && + (strstr(p->device_uri, "/printers/") != NULL || + strstr(p->device_uri, "/classes/") != NULL || + (strstr(p->device_uri, "._ipp.") != NULL && + !strcmp(p->device_uri + strlen(p->device_uri) - 5, + "/cups")))) + { + /* + * Tell the client this is really a hard-wired remote printer. + */ + + p->type |= CUPS_PRINTER_REMOTE; + + /* + * Point the printer-uri-supported attribute to the + * remote printer... + */ + + if (strchr(p->device_uri, '?')) + { + /* + * Strip trailing "?options" from URI... + */ + + char resource[HTTP_MAX_URI], /* New URI */ + *ptr; /* Pointer into URI */ + + strlcpy(resource, p->device_uri, sizeof(resource)); + if ((ptr = strchr(resource, '?')) != NULL) + *ptr = '\0'; + + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-uri-supported", NULL, resource); + } + else + ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, + "printer-uri-supported", NULL, p->device_uri); + + /* + * Then set the make-and-model accordingly... + */ + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-make-and-model", NULL, "Remote Printer"); + + /* + * Print all files directly... + */ + + p->raw = 1; + p->remote = 1; + } + else + { + /* + * Otherwise we have neither - treat this as a "dumb" printer + * with no PPD file... + */ + + ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, + "printer-make-and-model", NULL, "Local Raw Printer"); + + p->raw = 1; + } + } + + ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "finishings-supported", num_finishings, finishings); + ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, + "finishings-default", IPP_FINISHINGS_NONE); + + if (ppd && (cache = cupsFileOpen(cache_name, "w9")) != NULL) + { + /* + * Save cached PPD attributes to disk... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Saving %s...", cache_name); + + p->ppd_attrs->state = IPP_IDLE; + + if (ippWriteIO(cache, (ipp_iocb_t)cupsFileWrite, 1, NULL, + p->ppd_attrs) != IPP_DATA) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to save PPD cache file \"%s\" - %s", cache_name, + strerror(errno)); + unlink(cache_name); + } + + cupsFileClose(cache); + + _pwgWriteFile(p->pwg, pwg_name); + } + else + { + /* + * Remove cache files... + */ + + if (cache_info.st_mtime) + unlink(cache_name); + + if (pwg_info.st_mtime) + unlink(pwg_name); + } +} + + +/* + * 'new_media_col()' - Create a media-col collection value. + */ + +static ipp_t * /* O - Collection value */ +new_media_col(_pwg_size_t *size, /* I - media-size/margin values */ + const char *source, /* I - media-source value */ + const char *type) /* I - media-type value */ +{ + ipp_t *media_col, /* Collection value */ + *media_size; /* media-size value */ + + + media_col = ippNew(); + + media_size = ippNew(); + ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "x-dimension", size->width); + ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "y-dimension", size->length); + ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size); + ippDelete(media_size); + + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-bottom-margin", size->bottom); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-left-margin", size->left); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-right-margin", size->right); + ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, + "media-top-margin", size->top); + + if (source) + ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-source", + NULL, source); + + if (type) + ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-type", + NULL, type); + + return (media_col); +} + + +#ifdef __sgi +/* + * 'write_irix_config()' - Update the config files used by the IRIX + * desktop tools. + */ + +static void +write_irix_config(cupsd_printer_t *p) /* I - Printer to update */ +{ + char filename[1024]; /* Interface script filename */ + cups_file_t *fp; /* Interface script file */ + ipp_attribute_t *attr; /* Attribute data */ + + + /* + * 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 = cupsFileOpen(filename, "w")) != NULL) + { + cupsFilePuts(fp, "#!/bin/sh\n"); + + if ((attr = ippFindAttribute(p->attrs, "printer-make-and-model", + IPP_TAG_TEXT)) != NULL) + cupsFilePrintf(fp, "NAME=\"%s\"\n", attr->values[0].string.text); + else if (p->type & CUPS_PRINTER_CLASS) + cupsFilePuts(fp, "NAME=\"Printer Class\"\n"); + else + cupsFilePuts(fp, "NAME=\"Remote Destination\"\n"); + + if (p->type & CUPS_PRINTER_COLOR) + cupsFilePuts(fp, "TYPE=ColorPostScript\n"); + else + cupsFilePuts(fp, "TYPE=MonoPostScript\n"); + + cupsFilePrintf(fp, "HOSTNAME=%s\n", ServerName); + cupsFilePrintf(fp, "HOSTPRINTER=%s\n", p->name); + + cupsFileClose(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 = cupsFileOpen(filename, "w")) != NULL) + { + cupsFilePuts(fp, "/dev/null\n"); + + cupsFileClose(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 = cupsFileOpen(filename, "w")) != NULL) + { + cupsFilePuts(fp, "#!/bin/sh\n"); + cupsFilePrintf(fp, "%s -d %s -o \"$3\"\n", PrintcapGUI, p->name); + + cupsFileClose(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 = cupsFileOpen(filename, "w")) != NULL) + { + cupsFilePrintf(fp, "Printer Class | %s\n", + (p->type & CUPS_PRINTER_COLOR) ? "ColorPostScript" : "MonoPostScript"); + cupsFilePrintf(fp, "Printer Model | %s\n", p->make_model ? p->make_model : ""); + cupsFilePrintf(fp, "Location Code | %s\n", p->location ? p->location : ""); + cupsFilePrintf(fp, "Physical Location | %s\n", p->info ? p->info : ""); + cupsFilePrintf(fp, "Port Path | %s\n", p->device_uri); + cupsFilePrintf(fp, "Config Path | /var/spool/lp/pod/%s.config\n", p->name); + cupsFilePrintf(fp, "Active Status Path | /var/spool/lp/pod/%s.status\n", p->name); + cupsFilePuts(fp, "Status Update Wait | 10 seconds\n"); + + cupsFileClose(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(cupsd_printer_t *p) /* I - Printer to update */ +{ + char filename[1024]; /* Interface script filename */ + cups_file_t *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 = cupsFileOpen(filename, "w")) != NULL) + { + cupsFilePrintf(fp, "Operational Status | %s\n", + (p->state == IPP_PRINTER_IDLE) ? "Idle" : + (p->state == IPP_PRINTER_PROCESSING) ? "Busy" : + "Faulted"); + cupsFilePrintf(fp, "Information | 01 00 00 | %s\n", CUPS_SVERSION); + cupsFilePrintf(fp, "Information | 02 00 00 | Device URI: %s\n", + p->device_uri); + cupsFilePrintf(fp, "Information | 03 00 00 | %s jobs\n", + p->accepting ? "Accepting" : "Not accepting"); + cupsFilePrintf(fp, "Information | 04 00 00 | %s\n", p->state_message); + + cupsFileClose(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 = cupsFileOpen(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; + + cupsFilePuts(fp, "#!/bin/sh\n"); + cupsFilePrintf(fp, "#Tag %d\n", tag); + + cupsFileClose(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 = cupsFileOpen(filename, "w")) != NULL) + { + cupsFilePrintf(fp, "%s\n", DefaultPrinter->name); + + cupsFileClose(fp); + + chmod(filename, 0644); + chown(filename, User, Group); + } + } + else + unlink(filename); +} +#endif /* __sgi */ + + +/* + * 'write_xml_string()' - Write a string with XML escaping. + */ + +static void +write_xml_string(cups_file_t *fp, /* I - File to write to */ + const char *s) /* I - String to write */ +{ + const char *start; /* Start of current sequence */ + + + if (!s) + return; + + for (start = s; *s; s ++) + { + if (*s == '&') + { + if (s > start) + cupsFileWrite(fp, start, s - start); + + cupsFilePuts(fp, "&"); + start = s + 1; + } + else if (*s == '<') + { + if (s > start) + cupsFileWrite(fp, start, s - start); + + cupsFilePuts(fp, "<"); + start = s + 1; + } + } + + if (s > start) + cupsFilePuts(fp, start); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/printers.h b/scheduler/printers.h new file mode 100644 index 0000000000..e9bf278b46 --- /dev/null +++ b/scheduler/printers.h @@ -0,0 +1,186 @@ +/* + * "$Id$" + * + * Printer definitions for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifdef HAVE_DNSSD +# include +#endif /* HAVE_DNSSD */ +#include + + +/* + * 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 */ +} cupsd_quota_t; + + +/* + * Printer/class information structure... + */ + +typedef struct cupsd_job_s cupsd_job_t; + +typedef struct cupsd_printer_s +{ + char *uri, /* Printer URI */ + *hostname, /* Host printer resides on */ + *name, /* Printer name */ + *location, /* Location code */ + *make_model, /* Make and model */ + *info, /* Description */ + *op_policy, /* Operation policy name */ + *error_policy; /* Error policy */ + cupsd_policy_t *op_policy_ptr; /* Pointer to operation policy */ + int shared; /* Shared? */ + int accepting; /* Accepting jobs? */ + int holding_new_jobs; /* Holding new jobs for printing? */ + int in_implicit_class; /* In an implicit class? */ + ipp_pstate_t state; /* Printer state */ + char state_message[1024]; /* Printer state message */ + int num_reasons; /* Number of printer-state-reasons */ + char *reasons[64]; /* printer-state-reasons strings */ + time_t state_time; /* Time at this state */ + char *job_sheets[2]; /* Banners/job sheets */ + cups_ptype_t type; /* Printer type (color, small, etc.) */ + char *browse_attrs; /* Attributes sent with browse data */ + time_t browse_expire; /* Expiration time for printer */ + time_t browse_time; /* Last time update was sent/received */ + char *device_uri; /* Device URI */ + char *sanitized_device_uri; /* Sanitized device URI */ + char *port_monitor; /* Port monitor */ + int raw; /* Raw queue? */ + int remote; /* Remote queue? */ + mime_type_t *filetype, /* Pseudo-filetype for printer */ + *prefiltertype; /* Pseudo-filetype for pre-filters */ + cups_array_t *filetypes; /* Supported file types */ + cupsd_job_t *job; /* Current job in queue */ + ipp_t *attrs, /* Attributes supported by this printer */ + *ppd_attrs; /* Attributes based on the PPD */ + int num_printers, /* Number of printers in class */ + last_printer; /* Last printer job was sent to */ + struct cupsd_printer_s **printers; /* Printers in class */ + int quota_period, /* Period for quotas */ + page_limit, /* Maximum number of pages */ + k_limit; /* Maximum number of kilobytes */ + cups_array_t *quotas; /* Quota records */ + int deny_users, /* 1 = deny, 0 = allow */ + num_users; /* Number of allowed/denied users */ + const char **users; /* Allowed/denied users */ + int num_history; /* Number of history collections */ + ipp_t **history; /* History data */ + int sequence_number; /* Increasing sequence number */ + int num_options; /* Number of default options */ + cups_option_t *options; /* Default options */ + int num_auth_info_required; /* Number of required auth fields */ + const char *auth_info_required[4]; /* Required authentication fields */ + char *alert, /* PSX printer-alert value */ + *alert_description; /* PSX printer-alert-description value */ + time_t marker_time; /* Last time marker attributes were updated */ + cups_array_t *filters, /* Filters for queue */ + *pre_filters; /* Pre-filters for queue */ + char *recoverable; /* com.apple.print.recoverable-message */ + _pwg_t *pwg; /* PWG<->PPD mapping data */ + +#ifdef HAVE_DNSSD + char *reg_name, /* Name used for service registration */ + *product, /* PPD Product string */ + *pdl, /* pdl value for TXT record */ + *ipp_txt, /* IPP TXT record contents */ + *printer_txt; /* LPD TXT record contents */ + int ipp_len, /* IPP TXT record length */ + printer_len; /* LPD TXT record length */ + DNSServiceRef ipp_ref, /* Reference for _ipp._tcp,_cups */ + printer_ref; /* Reference for _printer._tcp */ +#endif /* HAVE_DNSSD */ +} cupsd_printer_t; + + +/* + * Globals... + */ + +VAR ipp_t *CommonData VALUE(NULL); + /* Common printer object attrs */ +VAR cups_array_t *CommonDefaults VALUE(NULL); + /* Common -default option names */ +VAR cups_array_t *Printers VALUE(NULL), + /* Printer list */ + *ImplicitPrinters VALUE(NULL); + /* Implicit class printers */ +VAR cupsd_printer_t *DefaultPrinter VALUE(NULL); + /* Default printer */ +VAR char *DefaultPolicy VALUE(NULL); + /* Default policy name */ +VAR cupsd_policy_t *DefaultPolicyPtr + VALUE(NULL); + /* Pointer to default policy */ + + +/* + * Prototypes... + */ + +extern cupsd_printer_t *cupsdAddPrinter(const char *name); +extern void cupsdAddPrinterHistory(cupsd_printer_t *p); +extern void cupsdAddPrinterUser(cupsd_printer_t *p, + const char *username); +extern void cupsdCreateCommonData(void); +extern void cupsdDeleteAllPrinters(void); +extern int cupsdDeletePrinter(cupsd_printer_t *p, int update); +extern cupsd_printer_t *cupsdFindDest(const char *name); +extern cupsd_printer_t *cupsdFindPrinter(const char *name); +extern cupsd_quota_t *cupsdFindQuota(cupsd_printer_t *p, + const char *username); +extern void cupsdFreePrinterUsers(cupsd_printer_t *p); +extern void cupsdFreeQuotas(cupsd_printer_t *p); +extern void cupsdLoadAllPrinters(void); +extern void cupsdRenamePrinter(cupsd_printer_t *p, + const char *name); +extern void cupsdSaveAllPrinters(void); +extern int cupsdSetAuthInfoRequired(cupsd_printer_t *p, + const char *values, + ipp_attribute_t *attr); +extern void cupsdSetDeviceURI(cupsd_printer_t *p, const char *uri); +extern void cupsdSetPrinterAttr(cupsd_printer_t *p, + const char *name, char *value); +extern void cupsdSetPrinterAttrs(cupsd_printer_t *p); +extern int cupsdSetPrinterReasons(cupsd_printer_t *p, + const char *s); +extern void cupsdSetPrinterState(cupsd_printer_t *p, ipp_pstate_t s, + int update); +#define cupsdStartPrinter(p,u) cupsdSetPrinterState((p), IPP_PRINTER_IDLE, (u)) +extern void cupsdStopPrinter(cupsd_printer_t *p, int update); +extern int cupsdUpdatePrinterPPD(cupsd_printer_t *p, + int num_keywords, + cups_option_t *keywords); +extern void cupsdUpdatePrinters(void); +extern cupsd_quota_t *cupsdUpdateQuota(cupsd_printer_t *p, + const char *username, int pages, + int k); +extern const char *cupsdValidateDest(const char *uri, + cups_ptype_t *dtype, + cupsd_printer_t **printer); +extern void cupsdWritePrintcap(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/process.c b/scheduler/process.c new file mode 100644 index 0000000000..5819875324 --- /dev/null +++ b/scheduler/process.c @@ -0,0 +1,634 @@ +/* + * "$Id$" + * + * Process management routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdCreateProfile() - Create an execution profile for a subprocess. + * cupsdDestroyProfile() - Delete an execution profile. + * cupsdEndProcess() - End a process. + * cupsdFinishProcess() - Finish a process and get its name. + * cupsdStartProcess() - Start a process. + * compare_procs() - Compare two processes. + * cupsd_requote() - Make a regular-expression version of a string. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include +#ifdef __APPLE__ +# include +#endif /* __APPLE__ */ +#ifdef HAVE_SANDBOX_H +# define __APPLE_API_PRIVATE +# include +#endif /* HAVE_SANDBOX_H */ + + +/* + * Process structure... + */ + +typedef struct +{ + int pid, /* Process ID */ + job_id; /* Job associated with process */ + char name[1]; /* Name of process */ +} cupsd_proc_t; + + +/* + * Local globals... + */ + +static cups_array_t *process_array = NULL; + + +/* + * Local functions... + */ + +static int compare_procs(cupsd_proc_t *a, cupsd_proc_t *b); +#ifdef HAVE_SANDBOX_H +static char *cupsd_requote(char *dst, const char *src, size_t dstsize); +#endif /* HAVE_SANDBOX_H */ + + +/* + * 'cupsdCreateProfile()' - Create an execution profile for a subprocess. + */ + +void * /* O - Profile or NULL on error */ +cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */ +{ +#ifdef HAVE_SANDBOX_H + cups_file_t *fp; /* File pointer */ + char profile[1024], /* File containing the profile */ + cache[1024], /* Quoted CacheDir */ + request[1024], /* Quoted RequestRoot */ + root[1024], /* Quoted ServerRoot */ + temp[1024]; /* Quoted TempDir */ + + + if (!UseProfiles || RunUser) + { + /* + * Only use sandbox profiles as root... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL", + job_id); + + return (NULL); + } + + if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL", + job_id); + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s", + strerror(errno)); + return (NULL); + } + + cupsd_requote(cache, CacheDir, sizeof(cache)); + cupsd_requote(request, RequestRoot, sizeof(request)); + cupsd_requote(root, ServerRoot, sizeof(root)); + cupsd_requote(temp, TempDir, sizeof(temp)); + + cupsFilePuts(fp, "(version 1)\n"); + cupsFilePuts(fp, "(debug deny)\n"); + cupsFilePuts(fp, "(allow default)\n"); + cupsFilePrintf(fp, + "(deny file-write* file-read-data file-read-metadata\n" + " (regex #\"^%s/\"))\n", request); + cupsFilePrintf(fp, + "(deny file-write*\n" + " (regex #\"^%s\" #\"^/private/etc\" #\"^/usr/local/etc\" " + "#\"^/Library\" #\"^/System\" #\"^/Users\"))\n", root); + cupsFilePrintf(fp, + "(allow file-write* file-read-data file-read-metadata\n" + " (regex #\"^%s$\" #\"^%s/\" #\"^%s$\" #\"^%s/\"" + " #\"^/Library/Application Support/\"" + " #\"^/Library/Caches/\"" + " #\"^/Library/Preferences/\"" + " #\"^/Library/Printers/\"" + "))\n", + temp, temp, cache, cache); + cupsFilePuts(fp, + "(deny file-write*\n" + " (regex #\"^/Library/Printers/PPDs/\"" + " #\"^/Library/Printers/PPD Plugins/\"" + "))\n"); + if (job_id) + cupsFilePrintf(fp, + "(allow file-read-data file-read-metadata\n" + " (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n", + request, job_id, job_id); + + cupsFileClose(fp); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = \"%s\"", + job_id, profile); + return ((void *)strdup(profile)); + +#else + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL", + job_id); + + return (NULL); +#endif /* HAVE_SANDBOX_H */ +} + + +/* + * 'cupsdDestroyProfile()' - Delete an execution profile. + */ + +void +cupsdDestroyProfile(void *profile) /* I - Profile */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeleteProfile(profile=\"%s\")", + profile ? (char *)profile : "(null)"); + +#ifdef HAVE_SANDBOX_H + if (profile) + { + unlink((char *)profile); + free(profile); + } +#endif /* HAVE_SANDBOX_H */ +} + + +/* + * 'cupsdEndProcess()' - End a process. + */ + +int /* O - 0 on success, -1 on failure */ +cupsdEndProcess(int pid, /* I - Process ID */ + int force) /* I - Force child to die */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdEndProcess(pid=%d, force=%d)", pid, + force); + + if (force) + return (kill(pid, SIGKILL)); + else + return (kill(pid, SIGTERM)); +} + + +/* + * 'cupsdFinishProcess()' - Finish a process and get its name. + */ + +const char * /* O - Process name */ +cupsdFinishProcess(int pid, /* I - Process ID */ + char *name, /* I - Name buffer */ + int namelen, /* I - Size of name buffer */ + int *job_id) /* O - Job ID pointer or NULL */ +{ + cupsd_proc_t key, /* Search key */ + *proc; /* Matching process */ + + + key.pid = pid; + + if ((proc = (cupsd_proc_t *)cupsArrayFind(process_array, &key)) != NULL) + { + if (job_id) + *job_id = proc->job_id; + + strlcpy(name, proc->name, namelen); + cupsArrayRemove(process_array, proc); + free(proc); + } + else + { + if (job_id) + *job_id = 0; + + strlcpy(name, "unknown", namelen); + } + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdFinishProcess(pid=%d, name=%p, namelen=%d, " + "job_id=%p(%d)) = \"%s\"", pid, name, namelen, job_id, + job_id ? *job_id : 0, name); + + return (name); +} + + +/* + * 'cupsdStartProcess()' - Start a process. + */ + +int /* O - Process ID or 0 */ +cupsdStartProcess( + 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 backfd, /* I - Backchannel file descriptor */ + int sidefd, /* I - Sidechannel file descriptor */ + int root, /* I - Run as root? */ + void *profile, /* I - Security profile to use */ + cupsd_job_t *job, /* I - Job associated with process */ + int *pid) /* O - Process ID */ +{ + int user; /* Command UID */ + struct stat commandinfo; /* Command file information */ + cupsd_proc_t *proc; /* New process record */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* POSIX signal handler */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ +#if defined(__APPLE__) + char processPath[1024], /* CFProcessPath environment variable */ + linkpath[1024]; /* Link path for symlinks... */ + int linkbytes; /* Bytes for link path */ +#endif /* __APPLE__ */ + + + if (RunUser) + user = RunUser; + else if (root) + user = 0; + else + user = User; + + if (stat(command, &commandinfo)) + { + *pid = 0; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " + "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " + "profile=%p, job=%p(%d), pid=%p) = %d", + command, argv, envp, infd, outfd, errfd, backfd, sidefd, + root, profile, job, job ? job->id : 0, pid, *pid); + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to execute %s: %s", command, + strerror(errno)); + + if (job && job->printer) + { + if (cupsdSetPrinterReasons(job->printer, "+cups-missing-filter-warning")) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, + "Printer driver %s is missing.", command); + } + + return (0); + } + else if ((commandinfo.st_mode & (S_ISUID | S_IWOTH)) || + (!RunUser && commandinfo.st_uid)) + { + *pid = 0; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " + "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " + "profile=%p, job=%p(%d), pid=%p) = %d", + command, argv, envp, infd, outfd, errfd, backfd, sidefd, + root, profile, job, job ? job->id : 0, pid, *pid); + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to execute %s: insecure file permissions (0%o)", + command, commandinfo.st_mode); + + if (job && job->printer) + { + if (cupsdSetPrinterReasons(job->printer, "+cups-insecure-filter-warning")) + cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, job->printer, NULL, + "Printer driver %s has insecure file permissions (0%o).", + command, commandinfo.st_mode); + } + + errno = EPERM; + + return (0); + } + else if ((commandinfo.st_uid != user || !(commandinfo.st_mode & S_IXUSR)) && + (commandinfo.st_gid != Group || !(commandinfo.st_mode & S_IXGRP)) && + !(commandinfo.st_mode & S_IXOTH)) + { + *pid = 0; + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " + "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " + "profile=%p, job=%p(%d), pid=%p) = %d", + command, argv, envp, infd, outfd, errfd, backfd, sidefd, + root, profile, job, job ? job->id : 0, pid, *pid); + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to execute %s: no execute permissions (0%o)", + command, commandinfo.st_mode); + + errno = EPERM; + return (0); + } + +#if defined(__APPLE__) + if (envp) + { + /* + * Add special voodoo magic for MacOS X - this allows MacOS X + * programs to access their bundle resources properly... + */ + + if ((linkbytes = readlink(command, linkpath, sizeof(linkpath) - 1)) > 0) + { + /* + * Yes, this is a symlink to the actual program, nul-terminate and + * use it... + */ + + linkpath[linkbytes] = '\0'; + + if (linkpath[0] == '/') + snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", + linkpath); + else + snprintf(processPath, sizeof(processPath), "CFProcessPath=%s/%s", + dirname((char *)command), linkpath); + } + else + snprintf(processPath, sizeof(processPath), "CFProcessPath=%s", command); + + envp[0] = processPath; /* Replace string */ + } +#endif /* __APPLE__ */ + + /* + * Block signals before forking... + */ + + cupsdHoldSignals(); + + if ((*pid = fork()) == 0) + { + /* + * Child process goes here... + * + * Update stdin/stdout/stderr as needed... + */ + + if (infd != 0) + { + if (infd < 0) + infd = open("/dev/null", O_RDONLY); + + if (infd != 0) + { + dup2(infd, 0); + close(infd); + } + } + + if (outfd != 1) + { + if (outfd < 0) + outfd = open("/dev/null", O_WRONLY); + + if (outfd != 1) + { + dup2(outfd, 1); + close(outfd); + } + } + + if (errfd != 2) + { + if (errfd < 0) + errfd = open("/dev/null", O_WRONLY); + + if (errfd != 2) + { + dup2(errfd, 2); + close(errfd); + } + } + + if (backfd != 3 && backfd >= 0) + { + dup2(backfd, 3); + close(backfd); + fcntl(3, F_SETFL, O_NDELAY); + } + + if (sidefd != 4 && sidefd >= 0) + { + dup2(sidefd, 4); + close(sidefd); + fcntl(4, F_SETFL, O_NDELAY); + } + + /* + * Change the priority of the process based on the FilterNice setting. + * (this is not done for root processes...) + */ + + if (!root) + nice(FilterNice); + +#ifdef HAVE_SANDBOX_H + /* + * Run in a separate security profile... + */ + + if (profile) + { + char *error = NULL; /* Sandbox error, if any */ + + if (sandbox_init((char *)profile, SANDBOX_NAMED_EXTERNAL, &error)) + { + fprintf(stderr, "ERROR: sandbox_init failed: %s (%s)\n", error, + strerror(errno)); + sandbox_free_error(error); + } + } +#endif /* HAVE_SANDBOX_H */ + + /* + * Change user to something "safe"... + */ + + if (!root && !RunUser) + { + /* + * Running as root, so change to non-priviledged user... + */ + + if (setgid(Group)) + exit(errno); + + if (setgroups(1, &Group)) + exit(errno); + + if (setuid(User)) + exit(errno); + } + else + { + /* + * Reset group membership to just the main one we belong to. + */ + + if (setgid(Group) && !RunUser) + exit(errno); + + if (setgroups(1, &Group) && !RunUser) + exit(errno); + } + + /* + * Change umask to restrict permissions on created files... + */ + + umask(077); + + /* + * Unblock signals before doing the exec... + */ + +#ifdef HAVE_SIGSET + sigset(SIGTERM, SIG_DFL); + sigset(SIGCHLD, SIG_DFL); + sigset(SIGPIPE, SIG_DFL); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_DFL; + + sigaction(SIGTERM, &action, NULL); + sigaction(SIGCHLD, &action, NULL); + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGTERM, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + signal(SIGPIPE, SIG_DFL); +#endif /* HAVE_SIGSET */ + + cupsdReleaseSignals(); + + /* + * Execute the command; if for some reason this doesn't work, + * return the error code... + */ + + if (envp) + execve(command, argv, envp); + else + execv(command, argv); + + perror(command); + + exit(errno); + } + else if (*pid < 0) + { + /* + * Error - couldn't fork a new process! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to fork %s - %s.", command, + strerror(errno)); + + *pid = 0; + } + else + { + if (!process_array) + process_array = cupsArrayNew((cups_array_func_t)compare_procs, NULL); + + if (process_array) + { + if ((proc = calloc(1, sizeof(cupsd_proc_t) + strlen(command))) != NULL) + { + proc->pid = *pid; + proc->job_id = job ? job->id : 0; + strcpy(proc->name, command); + + cupsArrayAdd(process_array, proc); + } + } + } + + cupsdReleaseSignals(); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdStartProcess(command=\"%s\", argv=%p, envp=%p, " + "infd=%d, outfd=%d, errfd=%d, backfd=%d, sidefd=%d, root=%d, " + "profile=%p, job=%p(%d), pid=%p) = %d", + command, argv, envp, infd, outfd, errfd, backfd, sidefd, + root, profile, job, job ? job->id : 0, pid, *pid); + + return (*pid); +} + + +/* + * 'compare_procs()' - Compare two processes. + */ + +static int /* O - Result of comparison */ +compare_procs(cupsd_proc_t *a, /* I - First process */ + cupsd_proc_t *b) /* I - Second process */ +{ + return (a->pid - b->pid); +} + + +#ifdef HAVE_SANDBOX_H +/* + * 'cupsd_requote()' - Make a regular-expression version of a string. + */ + +static char * /* O - Quoted string */ +cupsd_requote(char *dst, /* I - Destination buffer */ + const char *src, /* I - Source string */ + size_t dstsize) /* I - Size of destination buffer */ +{ + int ch; /* Current character */ + char *dstptr, /* Current position in buffer */ + *dstend; /* End of destination buffer */ + + + dstptr = dst; + dstend = dst + dstsize - 2; + + while (*src && dstptr < dstend) + { + ch = *src++; + + if (strchr(".?*()[]^$\\", ch)) + *dstptr++ = '\\'; + + *dstptr++ = ch; + } + + *dstptr = '\0'; + + return (dst); +} +#endif /* HAVE_SANDBOX_H */ + + +/* + * End of "$Id$". + */ diff --git a/scheduler/quotas.c b/scheduler/quotas.c new file mode 100644 index 0000000000..58ef907013 --- /dev/null +++ b/scheduler/quotas.c @@ -0,0 +1,257 @@ +/* + * "$Id$" + * + * Quota routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdFindQuota() - Find a quota record. + * cupsdFreeQuotas() - Free quotas for a printer. + * cupsdUpdateQuota() - Update quota data for the specified printer and user. + * add_quota() - Add a quota record for this printer and user. + * compare_quotas() - Compare two quota records... + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + + +/* + * Local functions... + */ + +static cupsd_quota_t *add_quota(cupsd_printer_t *p, const char *username); +static int compare_quotas(const cupsd_quota_t *q1, + const cupsd_quota_t *q2); + + +/* + * 'cupsdFindQuota()' - Find a quota record. + */ + +cupsd_quota_t * /* O - Quota data */ +cupsdFindQuota( + cupsd_printer_t *p, /* I - Printer */ + const char *username) /* I - User */ +{ + cupsd_quota_t *q, /* Quota data pointer */ + match; /* Search data */ + char *ptr; /* Pointer into username */ + + + if (!p || !username) + return (NULL); + + strlcpy(match.username, username, sizeof(match.username)); + if ((ptr = strchr(match.username, '@')) != NULL) + *ptr = '\0'; /* Strip @domain/@KDC */ + + if ((q = (cupsd_quota_t *)cupsArrayFind(p->quotas, &match)) != NULL) + return (q); + else + return (add_quota(p, username)); +} + + +/* + * 'cupsdFreeQuotas()' - Free quotas for a printer. + */ + +void +cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */ +{ + cupsd_quota_t *q; /* Current quota record */ + + + if (!p) + return; + + for (q = (cupsd_quota_t *)cupsArrayFirst(p->quotas); + q; + q = (cupsd_quota_t *)cupsArrayNext(p->quotas)) + free(q); + + cupsArrayDelete(p->quotas); + + p->quotas = NULL; +} + + +/* + * 'cupsdUpdateQuota()' - Update quota data for the specified printer and user. + */ + +cupsd_quota_t * /* O - Quota data */ +cupsdUpdateQuota( + cupsd_printer_t *p, /* I - Printer */ + const char *username, /* I - User */ + int pages, /* I - Number of pages */ + int k) /* I - Number of kilobytes */ +{ + cupsd_quota_t *q; /* Quota data */ + cupsd_job_t *job; /* Current 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 = cupsdFindQuota(p, username)) == NULL) + return (NULL); + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d", + p->name, username, pages, k); + +#if defined(__APPLE__) && defined(HAVE_DLFCN_H) + /* + * Use Apple PrintService quota enforcement if installed (X Server only) + */ + + if (AppleQuotas && PSQUpdateQuotaProc) + { + q->page_count = (*PSQUpdateQuotaProc)(p->name, p->info, username, pages, 0); + + return (q); + } +#endif /* __APPLE__ && HAVE_DLFCN_H */ + + 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 = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + { + /* + * We only care about the current printer/class and user... + */ + + if (strcasecmp(job->dest, p->name) != 0 || + strcasecmp(job->username, q->username) != 0) + continue; + + /* + * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure + * the access_time member is updated so the job isn't unloaded right away... + */ + + if (!cupsdLoadJob(job)) + 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->values[0].integer < curtime) + { + /* + * This job is too old to count towards the quota, ignore it... + */ + + if (JobAutoPurge && !job->printer && job->state_value > IPP_JOB_STOPPED) + cupsdDeleteJob(job, CUPSD_JOB_PURGE); + + 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); +} + + +/* + * 'add_quota()' - Add a quota record for this printer and user. + */ + +static cupsd_quota_t * /* O - Quota data */ +add_quota(cupsd_printer_t *p, /* I - Printer */ + const char *username) /* I - User */ +{ + cupsd_quota_t *q; /* New quota data */ + char *ptr; /* Pointer into username */ + + + if (!p || !username) + return (NULL); + + if (!p->quotas) + p->quotas = cupsArrayNew((cups_array_func_t)compare_quotas, NULL); + + if (!p->quotas) + return (NULL); + + if ((q = calloc(1, sizeof(cupsd_quota_t))) == NULL) + return (NULL); + + strlcpy(q->username, username, sizeof(q->username)); + if ((ptr = strchr(q->username, '@')) != NULL) + *ptr = '\0'; /* Strip @domain/@KDC */ + + cupsArrayAdd(p->quotas, q); + + return (q); +} + + +/* + * 'compare_quotas()' - Compare two quota records... + */ + +static int /* O - Result of comparison */ +compare_quotas(const cupsd_quota_t *q1, /* I - First quota record */ + const cupsd_quota_t *q2) /* I - Second quota record */ +{ + return (strcasecmp(q1->username, q2->username)); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/removefile.c b/scheduler/removefile.c new file mode 100644 index 0000000000..5cf16bfda0 --- /dev/null +++ b/scheduler/removefile.c @@ -0,0 +1,228 @@ +/* + * "$Id$" + * + * "Secure" file removal function for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdRemoveFile() - Remove a file using the 7-pass US DoD method. + * overwrite_data() - Overwrite the data in a file. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#ifdef HAVE_REMOVEFILE +# include +#else +static int overwrite_data(int fd, const char *buffer, int bufsize, + int filesize); +#endif /* HAVE_REMOVEFILE */ + + +/* + * 'cupsdRemoveFile()' - Remove a file using the 7-pass US DoD method. + */ + +int /* O - 0 on success, -1 on error */ +cupsdRemoveFile(const char *filename) /* I - File to remove */ +{ +#ifdef HAVE_REMOVEFILE + int ret; /* Return value */ + removefile_state_t s; /* Remove state variable */ + + + s = removefile_state_alloc(); + ret = removefile(filename, s, REMOVEFILE_SECURE_7_PASS); + + removefile_state_free(s); + + return (ret); + +#else + int fd; /* File descriptor */ + struct stat info; /* File information */ + char buffer[512]; /* Data buffer */ + int i; /* Looping var */ + + + /* + * First open the file for writing in exclusive mode. + */ + + if ((fd = open(filename, O_WRONLY | O_EXCL)) < 0) + return (-1); + + /* + * Delete the file now - it will still be around as long as the file is + * open... + */ + + unlink(filename); + + /* + * Then get the file size... + */ + + if (fstat(fd, &info)) + { + close(fd); + return (-1); + } + + /* + * Overwrite the file 7 times with 0xF6, 0x00, 0xFF, random, 0x00, 0xFF, + * and more random data. + */ + + memset(buffer, 0xF6, sizeof(buffer)); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + memset(buffer, 0x00, sizeof(buffer)); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + memset(buffer, 0xFF, sizeof(buffer)); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + for (i = 0; i < sizeof(buffer); i ++) + buffer[i] = rand(); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + memset(buffer, 0x00, sizeof(buffer)); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + memset(buffer, 0xFF, sizeof(buffer)); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + for (i = 0; i < sizeof(buffer); i ++) + buffer[i] = rand(); + if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) + { + close(fd); + return (-1); + } + + /* + * Whew! Close the file (which will lead to the actual deletion) and + * return success... + */ + + close(fd); + return (0); +#endif /* HAVE_REMOVEFILE */ +} + + +#ifndef HAVE_REMOVEFILE +/* + * 'overwrite_data()' - Overwrite the data in a file. + */ + +static int /* O - 0 on success, -1 on error */ +overwrite_data(int fd, /* I - File descriptor */ + const char *buffer, /* I - Buffer to write */ + int bufsize, /* I - Size of buffer */ + int filesize) /* I - Size of file */ +{ + int bytes; /* Bytes to write/written */ + + + /* + * Start at the beginning of the file... + */ + + if (lseek(fd, 0, SEEK_SET) < 0) + return (-1); + + /* + * Fill the file with the provided data... + */ + + while (filesize > 0) + { + if (filesize > bufsize) + bytes = bufsize; + else + bytes = filesize; + + if ((bytes = write(fd, buffer, bytes)) < 0) + return (-1); + + filesize -= bytes; + } + + /* + * Force the changes to disk... + */ + + return (fsync(fd)); +} +#endif /* HAVE_REMOVEFILE */ + + +#ifdef TEST +# define testmain main +int +testmain(void) +{ + FILE *fp; + + + fp = fopen("testfile.secure", "w"); + fputs("Hello, World!\n", fp); + fputs("Now is the time for all good men to come to the aid of their " + "country.\n", fp); + fclose(fp); + + if (cupsdRemoveFile("testfile.secure")) + { + printf("cupsdRemoveFile: FAIL (%s)\n", strerror(errno)); + return (1); + } + else + { + puts("cupsdRemoveFile: PASS"); + return (0); + } +} +#endif /* TEST */ + + +/* + * End of "$Id$". + */ diff --git a/scheduler/select.c b/scheduler/select.c new file mode 100644 index 0000000000..bb26d1dc15 --- /dev/null +++ b/scheduler/select.c @@ -0,0 +1,951 @@ +/* + * "$Id$" + * + * Select abstraction functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddSelect() - Add a file descriptor to the list. + * cupsdDoSelect() - Do a select-like operation. + * cupsdIsSelecting() - Determine whether we are monitoring a file + * descriptor. + * cupsdRemoveSelect() - Remove a file descriptor from the list. + * cupsdStartSelect() - Initialize the file polling engine. + * cupsdStopSelect() - Shutdown the file polling engine. + * compare_fds() - Compare file descriptors. + * find_fd() - Find an existing file descriptor record. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" + +#ifdef HAVE_EPOLL +# include +# include +#elif defined(HAVE_KQUEUE) +# include +# include +#elif defined(HAVE_POLL) +# include +#elif defined(__hpux) +# include +#else +# include +#endif /* HAVE_EPOLL */ + + +/* + * Design Notes for Poll/Select API in CUPSD + * ----------------------------------------- + * + * SUPPORTED APIS + * + * OS select poll epoll kqueue /dev/poll + * -------------- ------ ------ ------ ------ --------- + * AIX YES YES NO NO NO + * FreeBSD YES YES NO YES NO + * HP-UX YES YES NO NO NO + * IRIX YES YES NO NO NO + * Linux YES YES YES NO NO + * MacOS X YES YES NO YES NO + * NetBSD YES YES NO YES NO + * OpenBSD YES YES NO YES NO + * Solaris YES YES NO NO YES + * Tru64 YES YES NO NO NO + * Windows YES NO NO NO NO + * + * + * HIGH-LEVEL API + * + * typedef void (*cupsd_selfunc_t)(void *data); + * + * void cupsdStartSelect(void); + * void cupsdStopSelect(void); + * void cupsdAddSelect(int fd, cupsd_selfunc_t read_cb, + * cupsd_selfunc_t write_cb, void *data); + * void cupsdRemoveSelect(int fd); + * int cupsdDoSelect(int timeout); + * + * + * IMPLEMENTATION STRATEGY + * + * 0. Common Stuff + * a. CUPS array of file descriptor to callback functions + * and data + temporary array of removed fd's. + * b. cupsdStartSelect() creates the arrays + * c. cupsdStopSelect() destroys the arrays and all elements. + * d. cupsdAddSelect() adds to the array and allocates a + * new callback element. + * e. cupsdRemoveSelect() removes from the active array and + * adds to the inactive array. + * f. _cupsd_fd_t provides a reference-counted structure for + * tracking file descriptors that are monitored. + * g. cupsdDoSelect() frees all inactive FDs. + * + * 1. select() O(n) + * a. Input/Output fd_set variables, copied to working + * copies and then used with select(). + * b. Loop through CUPS array, using FD_ISSET and calling + * the read/write callbacks as needed. + * c. cupsdRemoveSelect() clears fd_set bit from main and + * working sets. + * d. cupsdStopSelect() frees all of the memory used by the + * CUPS array and fd_set's. + * + * 2. poll() - O(n log n) + * a. Regular array of pollfd, sorted the same as the CUPS + * array. + * b. Loop through pollfd array, call the corresponding + * read/write callbacks as needed. + * c. cupsdAddSelect() adds first to CUPS array and flags the + * pollfd array as invalid. + * d. cupsdDoSelect() rebuilds pollfd array as needed, calls + * poll(), then loops through the pollfd array looking up + * as needed. + * e. cupsdRemoveSelect() flags the pollfd array as invalid. + * f. cupsdStopSelect() frees all of the memory used by the + * CUPS array and pollfd array. + * + * 3. epoll() - O(n) + * a. cupsdStartSelect() creates epoll file descriptor using + * epoll_create() with the maximum fd count, and + * allocates an events buffer for the maximum fd count. + * b. cupsdAdd/RemoveSelect() uses epoll_ctl() to add + * (EPOLL_CTL_ADD) or remove (EPOLL_CTL_DEL) a single + * event using the level-triggered semantics. The event + * user data field is a pointer to the new callback array + * element. + * c. cupsdDoSelect() uses epoll_wait() with the global event + * buffer allocated in cupsdStartSelect() and then loops + * through the events, using the user data field to find + * the callback record. + * d. cupsdStopSelect() closes the epoll file descriptor and + * frees all of the memory used by the event buffer. + * + * 4. kqueue() - O(n) + * b. cupsdStartSelect() creates kqueue file descriptor + * using kqueue() function and allocates a global event + * buffer. + * c. cupsdAdd/RemoveSelect() uses EV_SET and kevent() to + * register the changes. The event user data field is a + * pointer to the new callback array element. + * d. cupsdDoSelect() uses kevent() to poll for events and + * loops through the events, using the user data field to + * find the callback record. + * e. cupsdStopSelect() closes the kqueue() file descriptor + * and frees all of the memory used by the event buffer. + * + * 5. /dev/poll - O(n log n) - NOT YET IMPLEMENTED + * a. cupsdStartSelect() opens /dev/poll and allocates an + * array of pollfd structs; on failure to open /dev/poll, + * revert to poll() system call. + * b. cupsdAddSelect() writes a single pollfd struct to + * /dev/poll with the new file descriptor and the + * POLLIN/POLLOUT flags. + * c. cupsdRemoveSelect() writes a single pollfd struct to + * /dev/poll with the file descriptor and the POLLREMOVE + * flag. + * d. cupsdDoSelect() uses the DP_POLL ioctl to retrieve + * events from /dev/poll and then loops through the + * returned pollfd array, looking up the file descriptors + * as needed. + * e. cupsdStopSelect() closes /dev/poll and frees the + * pollfd array. + * + * PERFORMANCE + * + * In tests using the "make test" target with option 0 (keep cupsd + * running) and the "testspeed" program with "-c 50 -r 1000", epoll() + * performed 5.5% slower than select(), followed by kqueue() at 16% + * slower than select() and poll() at 18% slower than select(). Similar + * results were seen with twice the number of client connections. + * + * The epoll() and kqueue() performance is likely limited by the + * number of system calls used to add/modify/remove file + * descriptors dynamically. Further optimizations may be possible + * in the area of limiting use of cupsdAddSelect() and + * cupsdRemoveSelect(), however extreme care will be needed to avoid + * excess CPU usage and deadlock conditions. + * + * We may be able to improve the poll() implementation simply by + * keeping the pollfd array sync'd with the _cupsd_fd_t array, as that + * will eliminate the rebuilding of the array whenever there is a + * change and eliminate the fd array lookups in the inner loop of + * cupsdDoSelect(). + * + * Since /dev/poll will never be able to use a shadow array, it may + * not make sense to implement support for it. ioctl() overhead will + * impact performance as well, so my guess would be that, for CUPS, + * /dev/poll will yield a net performance loss. + */ + +/* + * Local structures... + */ + +typedef struct _cupsd_fd_s +{ + int fd, /* File descriptor */ + use; /* Use count */ + cupsd_selfunc_t read_cb, /* Read callback */ + write_cb; /* Write callback */ + void *data; /* Data pointer for callbacks */ +} _cupsd_fd_t; + + +/* + * Local globals... + */ + +static cups_array_t *cupsd_fds = NULL; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) +static cups_array_t *cupsd_inactive_fds = NULL; +static int cupsd_in_select = 0; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + +#ifdef HAVE_KQUEUE +static int cupsd_kqueue_fd = -1, + cupsd_kqueue_changes = 0; +static struct kevent *cupsd_kqueue_events = NULL; +#elif defined(HAVE_POLL) +static int cupsd_alloc_pollfds = 0, + cupsd_update_pollfds = 0; +static struct pollfd *cupsd_pollfds = NULL; +# ifdef HAVE_EPOLL +static int cupsd_epoll_fd = -1; +static struct epoll_event *cupsd_epoll_events = NULL; +# endif /* HAVE_EPOLL */ +#else /* select() */ +static fd_set cupsd_global_input, + cupsd_global_output, + cupsd_current_input, + cupsd_current_output; +#endif /* HAVE_KQUEUE */ + + +/* + * Local functions... + */ + +static int compare_fds(_cupsd_fd_t *a, _cupsd_fd_t *b); +static _cupsd_fd_t *find_fd(int fd); +#define release_fd(f) { \ + (f)->use --; \ + if (!(f)->use) free((f));\ + } +#define retain_fd(f) (f)->use++ + + +/* + * 'cupsdAddSelect()' - Add a file descriptor to the list. + */ + +int /* O - 1 on success, 0 on error */ +cupsdAddSelect(int fd, /* I - File descriptor */ + cupsd_selfunc_t read_cb, /* I - Read callback */ + cupsd_selfunc_t write_cb,/* I - Write callback */ + void *data) /* I - Data to pass to callback */ +{ + _cupsd_fd_t *fdptr; /* File descriptor record */ +#ifdef HAVE_EPOLL + int added; /* 1 if added, 0 if modified */ +#endif /* HAVE_EPOLL */ + + + /* + * Range check input... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddSelect(fd=%d, read_cb=%p, write_cb=%p, data=%p)", + fd, read_cb, write_cb, data); + + if (fd < 0) + return (0); + + /* + * See if this FD has already been added... + */ + + if ((fdptr = find_fd(fd)) == NULL) + { + /* + * No, add a new entry... + */ + + if ((fdptr = calloc(1, sizeof(_cupsd_fd_t))) == NULL) + return (0); + + fdptr->fd = fd; + fdptr->use = 1; + + if (!cupsArrayAdd(cupsd_fds, fdptr)) + { + cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to add fd %d to array!", fd); + free(fdptr); + return (0); + } + +#ifdef HAVE_EPOLL + added = 1; + } + else + added = 0; +#else + } +#endif /* HAVE_EPOLL */ + +#ifdef HAVE_KQUEUE + { + struct kevent event; /* Event data */ + struct timespec timeout; /* Timeout value */ + + + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + if (fdptr->read_cb != read_cb) + { + if (read_cb) + EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, fdptr); + else + EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_EMERG, "kevent() returned %s", + strerror(errno)); + return (0); + } + } + + if (fdptr->write_cb != write_cb) + { + if (write_cb) + EV_SET(&event, fd, EVFILT_WRITE, EV_ADD, 0, 0, fdptr); + else + EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_EMERG, "kevent() returned %s", + strerror(errno)); + return (0); + } + } + } + +#elif defined(HAVE_POLL) +# ifdef HAVE_EPOLL + if (cupsd_epoll_fd >= 0) + { + struct epoll_event event; /* Event data */ + + + event.events = 0; + + if (read_cb) + event.events |= EPOLLIN; + + if (write_cb) + event.events |= EPOLLOUT; + + event.data.ptr = fdptr; + + if (epoll_ctl(cupsd_epoll_fd, added ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, + &event)) + { + close(cupsd_epoll_fd); + cupsd_epoll_fd = -1; + cupsd_update_pollfds = 1; + } + } + else +# endif /* HAVE_EPOLL */ + + cupsd_update_pollfds = 1; + +#else /* select() */ + /* + * Add or remove the file descriptor in the input and output sets + * for select()... + */ + + if (read_cb) + FD_SET(fd, &cupsd_global_input); + else + { + FD_CLR(fd, &cupsd_global_input); + FD_CLR(fd, &cupsd_current_input); + } + + if (write_cb) + FD_SET(fd, &cupsd_global_output); + else + { + FD_CLR(fd, &cupsd_global_output); + FD_CLR(fd, &cupsd_current_output); + } +#endif /* HAVE_KQUEUE */ + + /* + * Save the (new) read and write callbacks... + */ + + fdptr->read_cb = read_cb; + fdptr->write_cb = write_cb; + fdptr->data = data; + + return (1); +} + + +/* + * 'cupsdDoSelect()' - Do a select-like operation. + */ + +int /* O - Number of files or -1 on error */ +cupsdDoSelect(long timeout) /* I - Timeout in seconds */ +{ + int nfds; /* Number of file descriptors */ + _cupsd_fd_t *fdptr; /* Current file descriptor */ +#ifdef HAVE_KQUEUE + int i; /* Looping var */ + struct kevent *event; /* Current event */ + struct timespec ktimeout; /* kevent() timeout */ + + + cupsd_in_select = 1; + + if (timeout >= 0 && timeout < 86400) + { + ktimeout.tv_sec = timeout; + ktimeout.tv_nsec = 0; + + nfds = kevent(cupsd_kqueue_fd, NULL, 0, cupsd_kqueue_events, MaxFDs, + &ktimeout); + } + else + nfds = kevent(cupsd_kqueue_fd, NULL, 0, cupsd_kqueue_events, MaxFDs, NULL); + + cupsd_kqueue_changes = 0; + + for (i = nfds, event = cupsd_kqueue_events; i > 0; i --, event ++) + { + fdptr = (_cupsd_fd_t *)event->udata; + + if (cupsArrayFind(cupsd_inactive_fds, fdptr)) + continue; + + retain_fd(fdptr); + + if (fdptr->read_cb && event->filter == EVFILT_READ) + (*(fdptr->read_cb))(fdptr->data); + + if (fdptr->use > 1 && fdptr->write_cb && event->filter == EVFILT_WRITE && + !cupsArrayFind(cupsd_inactive_fds, fdptr)) + (*(fdptr->write_cb))(fdptr->data); + + release_fd(fdptr); + } + +#elif defined(HAVE_POLL) + struct pollfd *pfd; /* Current pollfd structure */ + int count; /* Number of file descriptors */ + + +# ifdef HAVE_EPOLL + cupsd_in_select = 1; + + if (cupsd_epoll_fd >= 0) + { + int i; /* Looping var */ + struct epoll_event *event; /* Current event */ + + + if (timeout >= 0 && timeout < 86400) + nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs, + timeout * 1000); + else + nfds = epoll_wait(cupsd_epoll_fd, cupsd_epoll_events, MaxFDs, -1); + + if (nfds < 0 && errno != EINTR) + { + close(cupsd_epoll_fd); + cupsd_epoll_fd = -1; + } + else + { + for (i = nfds, event = cupsd_epoll_events; i > 0; i --, event ++) + { + fdptr = (_cupsd_fd_t *)event->data.ptr; + + if (cupsArrayFind(cupsd_inactive_fds, fdptr)) + continue; + + retain_fd(fdptr); + + if (fdptr->read_cb && (event->events & (EPOLLIN | EPOLLERR | EPOLLHUP))) + (*(fdptr->read_cb))(fdptr->data); + + if (fdptr->use > 1 && fdptr->write_cb && + (event->events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) && + !cupsArrayFind(cupsd_inactive_fds, fdptr)) + (*(fdptr->write_cb))(fdptr->data); + + release_fd(fdptr); + } + + goto release_inactive; + } + } +# endif /* HAVE_EPOLL */ + + count = cupsArrayCount(cupsd_fds); + + if (cupsd_update_pollfds) + { + /* + * Update the cupsd_pollfds array to match the current FD array... + */ + + cupsd_update_pollfds = 0; + + /* + * (Re)allocate memory as needed... + */ + + if (count > cupsd_alloc_pollfds) + { + int allocfds = count + 16; + + + if (cupsd_pollfds) + pfd = realloc(cupsd_pollfds, allocfds * sizeof(struct pollfd)); + else + pfd = malloc(allocfds * sizeof(struct pollfd)); + + if (!pfd) + { + cupsdLogMessage(CUPSD_LOG_EMERG, + "Unable to allocate %d bytes for polling!", + (int)(allocfds * sizeof(struct pollfd))); + + return (-1); + } + + cupsd_pollfds = pfd; + cupsd_alloc_pollfds = allocfds; + } + + /* + * Rebuild the array... + */ + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds), pfd = cupsd_pollfds; + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_fds), pfd ++) + { + pfd->fd = fdptr->fd; + pfd->events = 0; + + if (fdptr->read_cb) + pfd->events |= POLLIN; + + if (fdptr->write_cb) + pfd->events |= POLLOUT; + } + } + + if (timeout >= 0 && timeout < 86400) + nfds = poll(cupsd_pollfds, count, timeout * 1000); + else + nfds = poll(cupsd_pollfds, count, -1); + + if (nfds > 0) + { + /* + * Do callbacks for each file descriptor... + */ + + for (pfd = cupsd_pollfds; count > 0; pfd ++, count --) + { + if (!pfd->revents) + continue; + + if ((fdptr = find_fd(pfd->fd)) == NULL) + continue; + + retain_fd(fdptr); + + if (fdptr->read_cb && (pfd->revents & (POLLIN | POLLERR | POLLHUP))) + (*(fdptr->read_cb))(fdptr->data); + + if (fdptr->use > 1 && fdptr->write_cb && + (pfd->revents & (POLLOUT | POLLERR | POLLHUP))) + (*(fdptr->write_cb))(fdptr->data); + + release_fd(fdptr); + } + } + +#else /* select() */ + struct timeval stimeout; /* Timeout for select() */ + int maxfd; /* Maximum file descriptor */ + + + /* + * Figure out the highest file descriptor number... + */ + + if ((fdptr = (_cupsd_fd_t *)cupsArrayLast(cupsd_fds)) == NULL) + maxfd = 1; + else + maxfd = fdptr->fd + 1; + + /* + * Do the select()... + */ + + cupsd_current_input = cupsd_global_input; + cupsd_current_output = cupsd_global_output; + + if (timeout >= 0 && timeout < 86400) + { + stimeout.tv_sec = timeout; + stimeout.tv_usec = 0; + + nfds = select(maxfd, &cupsd_current_input, &cupsd_current_output, NULL, + &stimeout); + } + else + nfds = select(maxfd, &cupsd_current_input, &cupsd_current_output, NULL, + NULL); + + if (nfds > 0) + { + /* + * Do callbacks for each file descriptor... + */ + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds); + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_fds)) + { + retain_fd(fdptr); + + if (fdptr->read_cb && FD_ISSET(fdptr->fd, &cupsd_current_input)) + (*(fdptr->read_cb))(fdptr->data); + + if (fdptr->use > 1 && fdptr->write_cb && + FD_ISSET(fdptr->fd, &cupsd_current_output)) + (*(fdptr->write_cb))(fdptr->data); + + release_fd(fdptr); + } + } + +#endif /* HAVE_KQUEUE */ + +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + /* + * Release all inactive file descriptors... + */ + +# ifndef HAVE_KQUEUE + release_inactive: +# endif /* !HAVE_KQUEUE */ + + cupsd_in_select = 0; + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_inactive_fds); + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_inactive_fds)) + { + cupsArrayRemove(cupsd_inactive_fds, fdptr); + release_fd(fdptr); + } +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + + /* + * Return the number of file descriptors handled... + */ + + return (nfds); +} + + +#ifdef CUPSD_IS_SELECTING +/* + * 'cupsdIsSelecting()' - Determine whether we are monitoring a file + * descriptor. + */ + +int /* O - 1 if selecting, 0 otherwise */ +cupsdIsSelecting(int fd) /* I - File descriptor */ +{ + return (find_fd(fd) != NULL); +} +#endif /* CUPSD_IS_SELECTING */ + + +/* + * 'cupsdRemoveSelect()' - Remove a file descriptor from the list. + */ + +void +cupsdRemoveSelect(int fd) /* I - File descriptor */ +{ + _cupsd_fd_t *fdptr; /* File descriptor record */ +#ifdef HAVE_EPOLL + struct epoll_event event; /* Event data */ +#elif defined(HAVE_KQUEUE) + struct kevent event; /* Event data */ + struct timespec timeout; /* Timeout value */ +#elif defined(HAVE_POLL) + /* No variables for poll() */ +#endif /* HAVE_EPOLL */ + + + /* + * Range check input... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdRemoveSelect(fd=%d)", fd); + + if (fd < 0) + return; + + /* + * Find the file descriptor... + */ + + if ((fdptr = find_fd(fd)) == NULL) + return; + +#ifdef HAVE_EPOLL + if (epoll_ctl(cupsd_epoll_fd, EPOLL_CTL_DEL, fd, &event)) + { + close(cupsd_epoll_fd); + cupsd_epoll_fd = -1; + cupsd_update_pollfds = 1; + } + +#elif defined(HAVE_KQUEUE) + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + if (fdptr->read_cb) + { + EV_SET(&event, fd, EVFILT_READ, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_EMERG, "kevent() returned %s", + strerror(errno)); + goto cleanup; + } + } + + if (fdptr->write_cb) + { + EV_SET(&event, fd, EVFILT_WRITE, EV_DELETE, 0, 0, fdptr); + + if (kevent(cupsd_kqueue_fd, &event, 1, NULL, 0, &timeout)) + { + cupsdLogMessage(CUPSD_LOG_EMERG, "kevent() returned %s", + strerror(errno)); + goto cleanup; + } + } + +#elif defined(HAVE_POLL) + /* + * Update the pollfds array... + */ + + cupsd_update_pollfds = 1; + +#else /* select() */ + FD_CLR(fd, &cupsd_global_input); + FD_CLR(fd, &cupsd_global_output); + FD_CLR(fd, &cupsd_current_input); + FD_CLR(fd, &cupsd_current_output); +#endif /* HAVE_EPOLL */ + +#ifdef HAVE_KQUEUE + cleanup: +#endif /* HAVE_KQUEUE */ + + /* + * Remove the file descriptor from the active array and add to the + * inactive array (or release, if we don't need the inactive array...) + */ + + cupsArrayRemove(cupsd_fds, fdptr); + +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + if (cupsd_in_select) + cupsArrayAdd(cupsd_inactive_fds, fdptr); + else +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + + release_fd(fdptr); +} + + +/* + * 'cupsdStartSelect()' - Initialize the file polling engine. + */ + +void +cupsdStartSelect(void) +{ + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStartSelect()"); + + cupsd_fds = cupsArrayNew((cups_array_func_t)compare_fds, NULL); + +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + cupsd_inactive_fds = cupsArrayNew((cups_array_func_t)compare_fds, NULL); +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + +#ifdef HAVE_EPOLL + cupsd_epoll_fd = epoll_create(MaxFDs); + cupsd_epoll_events = calloc(MaxFDs, sizeof(struct epoll_event)); + cupsd_update_pollfds = 0; + +#elif defined(HAVE_KQUEUE) + cupsd_kqueue_fd = kqueue(); + cupsd_kqueue_changes = 0; + cupsd_kqueue_events = calloc(MaxFDs, sizeof(struct kevent)); + +#elif defined(HAVE_POLL) + cupsd_update_pollfds = 0; + +#else /* select() */ + FD_ZERO(&cupsd_global_input); + FD_ZERO(&cupsd_global_output); +#endif /* HAVE_EPOLL */ +} + + +/* + * 'cupsdStopSelect()' - Shutdown the file polling engine. + */ + +void +cupsdStopSelect(void) +{ + _cupsd_fd_t *fdptr; /* Current file descriptor */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdStopSelect()"); + + for (fdptr = (_cupsd_fd_t *)cupsArrayFirst(cupsd_fds); + fdptr; + fdptr = (_cupsd_fd_t *)cupsArrayNext(cupsd_fds)) + free(fdptr); + + cupsArrayDelete(cupsd_fds); + cupsd_fds = NULL; + +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + cupsArrayDelete(cupsd_inactive_fds); + cupsd_inactive_fds = NULL; +#endif /* HAVE_EPOLL || HAVE_KQUEUE */ + +#ifdef HAVE_KQUEUE + if (cupsd_kqueue_events) + { + free(cupsd_kqueue_events); + cupsd_kqueue_events = NULL; + } + + if (cupsd_kqueue_fd >= 0) + { + close(cupsd_kqueue_fd); + cupsd_kqueue_fd = -1; + } + + cupsd_kqueue_changes = 0; + +#elif defined(HAVE_POLL) +# ifdef HAVE_EPOLL + if (cupsd_epoll_events) + { + free(cupsd_epoll_events); + cupsd_epoll_events = NULL; + } + + if (cupsd_epoll_fd >= 0) + { + close(cupsd_epoll_fd); + cupsd_epoll_fd = -1; + } +# endif /* HAVE_EPOLL */ + + if (cupsd_pollfds) + { + free(cupsd_pollfds); + cupsd_pollfds = NULL; + cupsd_alloc_pollfds = 0; + } + + cupsd_update_pollfds = 0; + +#else /* select() */ + FD_ZERO(&cupsd_global_input); + FD_ZERO(&cupsd_global_output); +#endif /* HAVE_EPOLL */ +} + + +/* + * 'compare_fds()' - Compare file descriptors. + */ + +static int /* O - Result of comparison */ +compare_fds(_cupsd_fd_t *a, /* I - First file descriptor */ + _cupsd_fd_t *b) /* I - Second file descriptor */ +{ + return (a->fd - b->fd); +} + + +/* + * 'find_fd()' - Find an existing file descriptor record. + */ + +static _cupsd_fd_t * /* O - FD record pointer or NULL */ +find_fd(int fd) /* I - File descriptor */ +{ + _cupsd_fd_t *fdptr, /* Matching record (if any) */ + key; /* Search key */ + + + cupsArraySave(cupsd_fds); + + key.fd = fd; + fdptr = (_cupsd_fd_t *)cupsArrayFind(cupsd_fds, &key); + + cupsArrayRestore(cupsd_fds); + + return (fdptr); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/server.c b/scheduler/server.c new file mode 100644 index 0000000000..75b0247485 --- /dev/null +++ b/scheduler/server.c @@ -0,0 +1,184 @@ +/* + * "$Id$" + * + * Server start/stop routines for the CUPS scheduler. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdStartServer() - Start the server. + * cupsdStopServer() - Stop the server. + */ + +/* + * Include necessary headers... + */ + +#include +#include "cupsd.h" +#include +#ifdef HAVE_NOTIFY_H +# include +#endif /* HAVE_NOTIFY_H */ + + +/* + * Local globals... + */ + +static int started = 0; + + +/* + * 'cupsdStartServer()' - Start the server. + */ + +void +cupsdStartServer(void) +{ + /* + * Create the default security profile... + */ + + DefaultProfile = cupsdCreateProfile(0); + + /* + * Startup all the networking stuff... + */ + + cupsdStartListening(); + cupsdStartBrowsing(); + cupsdStartPolling(); + + /* + * Create a pipe for CGI processes... + */ + + if (cupsdOpenPipe(CGIPipes)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "cupsdStartServer: Unable to create pipes for CGI status!"); + else + { + CGIStatusBuffer = cupsdStatBufNew(CGIPipes[0], "[CGI]"); + + cupsdAddSelect(CGIPipes[0], (cupsd_selfunc_t)cupsdUpdateCGI, NULL, NULL); + } + + /* + * Mark that the server has started and printers and jobs may be changed... + */ + + LastEvent = CUPSD_EVENT_PRINTER_CHANGED | CUPSD_EVENT_JOB_STATE_CHANGED | + CUPSD_EVENT_SERVER_STARTED; + started = 1; + + cupsdSetBusyState(); +} + + +/* + * 'cupsdStopServer()' - Stop the server. + */ + +void +cupsdStopServer(void) +{ + if (!started) + return; + + /* + * Close all network clients and stop all jobs... + */ + + cupsdCloseAllClients(); + cupsdStopListening(); + cupsdStopPolling(); + cupsdStopBrowsing(); + cupsdStopAllNotifiers(); + cupsdDeleteAllCerts(); + + if (Clients) + { + cupsArrayDelete(Clients); + Clients = NULL; + } + + /* + * Close the pipe for CGI processes... + */ + + if (CGIPipes[0] >= 0) + { + cupsdRemoveSelect(CGIPipes[0]); + + cupsdStatBufDelete(CGIStatusBuffer); + close(CGIPipes[1]); + + CGIPipes[0] = -1; + CGIPipes[1] = -1; + } + +#ifdef HAVE_NOTIFY_POST + /* + * Send one last notification as the server shuts down. + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "notify_post(\"com.apple.printerListChange\") last"); + notify_post("com.apple.printerListChange"); +#endif /* HAVE_NOTIFY_POST */ + + /* + * Close all log files... + */ + + if (AccessFile != NULL) + { + cupsFileClose(AccessFile); + + AccessFile = NULL; + } + + if (ErrorFile != NULL) + { + cupsFileClose(ErrorFile); + + ErrorFile = NULL; + } + + if (PageFile != NULL) + { + cupsFileClose(PageFile); + + PageFile = NULL; + } + + /* + * Delete the default security profile... + */ + + cupsdDestroyProfile(DefaultProfile); + DefaultProfile = NULL; + + /* + * Write out any dirty files... + */ + + if (DirtyFiles) + cupsdCleanDirty(); + + started = 0; +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/statbuf.c b/scheduler/statbuf.c new file mode 100644 index 0000000000..71072d975a --- /dev/null +++ b/scheduler/statbuf.c @@ -0,0 +1,331 @@ +/* + * "$Id$" + * + * Status buffer routines for the Common UNIX Printing System (CUPS) + * scheduler. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdStatBufDelete() - Destroy a status buffer. + * cupsdStatBufNew() - Create a new status buffer. + * cupsdStatBufUpdate() - Update the status buffer. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#include + + +/* + * 'cupsdStatBufDelete()' - Destroy a status buffer. + */ + +void +cupsdStatBufDelete(cupsd_statbuf_t *sb) /* I - Status buffer */ +{ + /* + * Range check input... + */ + + if (!sb) + return; + + /* + * Close the status pipe and free memory used... + */ + + close(sb->fd); + + free(sb); +} + + +/* + * 'cupsdStatBufNew()' - Create a new status buffer. + */ + +cupsd_statbuf_t * /* O - New status buffer */ +cupsdStatBufNew(int fd, /* I - File descriptor of pipe */ + const char *prefix, /* I - Printf-style prefix string */ + ...) /* I - Additional args as needed */ +{ + cupsd_statbuf_t *sb; /* New status buffer */ + va_list ap; /* Argument list */ + + + /* + * Range check input... + */ + + if (fd < 0) + return (NULL); + + /* + * Allocate the status buffer... + */ + + if ((sb = calloc(1, sizeof(cupsd_statbuf_t))) != NULL) + { + /* + * Assign the file descriptor... + */ + + sb->fd = fd; + + /* + * Format the prefix string, if any. This is usually "[Job 123]" + * or "[Sub 123]", and so forth. + */ + + if (prefix) + { + /* + * Printf-style prefix string... + */ + + va_start(ap, prefix); + vsnprintf(sb->prefix, sizeof(sb->prefix), prefix, ap); + va_end(ap); + } + else + { + /* + * No prefix string... + */ + + sb->prefix[0] = '\0'; + } + } + + return (sb); +} + + +/* + * 'cupsdStatBufUpdate()' - Update the status buffer. + */ + +char * /* O - Line from buffer, "", or NULL */ +cupsdStatBufUpdate( + cupsd_statbuf_t *sb, /* I - Status buffer */ + int *loglevel, /* O - Log level */ + char *line, /* I - Line buffer */ + int linelen) /* I - Size of line buffer */ +{ + int bytes; /* Number of bytes read */ + char *lineptr, /* Pointer to end of line in buffer */ + *message; /* Pointer to message text */ + + + /* + * Check if the buffer already contains a full line... + */ + + if ((lineptr = strchr(sb->buffer, '\n')) == NULL) + { + /* + * No, read more data... + */ + + if ((bytes = read(sb->fd, sb->buffer + sb->bufused, + CUPSD_SB_BUFFER_SIZE - sb->bufused - 1)) > 0) + { + sb->bufused += bytes; + sb->buffer[sb->bufused] = '\0'; + + /* + * Guard against a line longer than the max buffer size... + */ + + if ((lineptr = strchr(sb->buffer, '\n')) == NULL && + sb->bufused == (CUPSD_SB_BUFFER_SIZE - 1)) + lineptr = sb->buffer + sb->bufused; + } + else if (bytes < 0 && errno == EINTR) + { + /* + * Return an empty line if we are interrupted... + */ + + *loglevel = CUPSD_LOG_NONE; + line[0] = '\0'; + + return (line); + } + else + { + /* + * End-of-file, so use the whole buffer... + */ + + lineptr = sb->buffer + sb->bufused; + *lineptr = '\0'; + } + + /* + * Final check for end-of-file... + */ + + if (sb->bufused == 0 && bytes == 0) + lineptr = NULL; + } + + if (!lineptr) + { + /* + * End of file... + */ + + *loglevel = CUPSD_LOG_NONE; + line[0] = '\0'; + + return (NULL); + } + + /* + * Terminate the line and process it... + */ + + *lineptr++ = '\0'; + + /* + * Figure out the logging level... + */ + + if (!strncmp(sb->buffer, "EMERG:", 6)) + { + *loglevel = CUPSD_LOG_EMERG; + message = sb->buffer + 6; + } + else if (!strncmp(sb->buffer, "ALERT:", 6)) + { + *loglevel = CUPSD_LOG_ALERT; + message = sb->buffer + 6; + } + else if (!strncmp(sb->buffer, "CRIT:", 5)) + { + *loglevel = CUPSD_LOG_CRIT; + message = sb->buffer + 5; + } + else if (!strncmp(sb->buffer, "ERROR:", 6)) + { + *loglevel = CUPSD_LOG_ERROR; + message = sb->buffer + 6; + } + else if (!strncmp(sb->buffer, "WARNING:", 8)) + { + *loglevel = CUPSD_LOG_WARN; + message = sb->buffer + 8; + } + else if (!strncmp(sb->buffer, "NOTICE:", 7)) + { + *loglevel = CUPSD_LOG_NOTICE; + message = sb->buffer + 7; + } + else if (!strncmp(sb->buffer, "INFO:", 5)) + { + *loglevel = CUPSD_LOG_INFO; + message = sb->buffer + 5; + } + else if (!strncmp(sb->buffer, "DEBUG:", 6)) + { + *loglevel = CUPSD_LOG_DEBUG; + message = sb->buffer + 6; + } + else if (!strncmp(sb->buffer, "DEBUG2:", 7)) + { + *loglevel = CUPSD_LOG_DEBUG2; + message = sb->buffer + 7; + } + else if (!strncmp(sb->buffer, "PAGE:", 5)) + { + *loglevel = CUPSD_LOG_PAGE; + message = sb->buffer + 5; + } + else if (!strncmp(sb->buffer, "STATE:", 6)) + { + *loglevel = CUPSD_LOG_STATE; + message = sb->buffer + 6; + } + else if (!strncmp(sb->buffer, "ATTR:", 5)) + { + *loglevel = CUPSD_LOG_ATTR; + message = sb->buffer + 5; + } + else if (!strncmp(sb->buffer, "PPD:", 4)) + { + *loglevel = CUPSD_LOG_PPD; + message = sb->buffer + 4; + } + else + { + *loglevel = CUPSD_LOG_DEBUG; + message = sb->buffer; + } + + /* + * Skip leading whitespace in the message... + */ + + while (isspace(*message & 255)) + message ++; + + /* + * Send it to the log file as needed... + */ + + if (sb->prefix[0]) + { + if (*loglevel > CUPSD_LOG_NONE && + (*loglevel != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG)) + { + /* + * General status message; send it to the error_log file... + */ + + if (message[0] == '[') + cupsdLogMessage(*loglevel, "%s", message); + else + cupsdLogMessage(*loglevel, "%s %s", sb->prefix, message); + } + else if (*loglevel < CUPSD_LOG_NONE && LogLevel >= CUPSD_LOG_DEBUG) + cupsdLogMessage(CUPSD_LOG_DEBUG2, "%s %s", sb->prefix, sb->buffer); + } + + /* + * Copy the message to the line buffer... + */ + + strlcpy(line, message, linelen); + + /* + * Copy over the buffer data we've used up... + */ + + if (lineptr < sb->buffer + sb->bufused) + _cups_strcpy(sb->buffer, lineptr); + + sb->bufused -= lineptr - sb->buffer; + + if (sb->bufused < 0) + sb->bufused = 0; + + return (line); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/statbuf.h b/scheduler/statbuf.h new file mode 100644 index 0000000000..1039259d2f --- /dev/null +++ b/scheduler/statbuf.h @@ -0,0 +1,50 @@ +/* + * "$Id$" + * + * Status buffer definitions for the Common UNIX Printing System (CUPS) + * scheduler. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + + +/* + * Constants... + */ + +#define CUPSD_SB_BUFFER_SIZE 1024 /* Bytes or job status buffer */ + + +/* + * Types and structures... + */ + +typedef struct /**** Status buffer */ +{ + int fd; /* File descriptor to read from */ + char prefix[64]; /* Prefix for log messages */ + int bufused; /* How much is used in buffer */ + char buffer[CUPSD_SB_BUFFER_SIZE]; /* Buffer */ +} cupsd_statbuf_t; + + +/* + * Prototypes... + */ + +extern void cupsdStatBufDelete(cupsd_statbuf_t *sb); +extern cupsd_statbuf_t *cupsdStatBufNew(int fd, const char *prefix, ...); +extern char *cupsdStatBufUpdate(cupsd_statbuf_t *sb, int *loglevel, + char *line, int linelen); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/subscriptions.c b/scheduler/subscriptions.c new file mode 100644 index 0000000000..a34f93fe02 --- /dev/null +++ b/scheduler/subscriptions.c @@ -0,0 +1,1679 @@ +/* + * "$Id$" + * + * Subscription routines for the CUPS scheduler. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdAddEvent() - Add an event to the global event cache. + * cupsdAddSubscription() - Add a new subscription object. + * cupsdDeleteAllSubscriptions() - Delete all subscriptions. + * cupsdDeleteSubscription() - Delete a subscription object. + * cupsdEventName() - Return a single event name. + * cupsdEventValue() - Return the event mask value for a name. + * cupsdExpireSubscriptions() - Expire old subscription objects. + * cupsdFindSubscription() - Find a subscription by ID. + * cupsdLoadAllSubscriptions() - Load all subscriptions from the .conf file. + * cupsdSaveAllSubscriptions() - Save all subscriptions to the .conf file. + * cupsdStopAllNotifiers() - Stop all notifier processes. + * cupsd_compare_subscriptions() - Compare two subscriptions. + * cupsd_delete_event() - Delete a single event... + * cupsd_send_dbus() - Send a DBUS notification... + * cupsd_send_notification() - Send a notification for the specified + * event. + * cupsd_start_notifier() - Start a notifier subprocess... + * cupsd_update_notifier() - Read messages from notifiers. + */ + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#ifdef HAVE_DBUS +# include +# ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND +# define dbus_message_append_iter_init dbus_message_iter_init_append +# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &(v)) +# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, &(v)) +# endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */ +#endif /* HAVE_DBUS */ + + +/* + * Local functions... + */ + +static int cupsd_compare_subscriptions(cupsd_subscription_t *first, + cupsd_subscription_t *second, + void *unused); +static void cupsd_delete_event(cupsd_event_t *event); +#ifdef HAVE_DBUS +static void cupsd_send_dbus(cupsd_eventmask_t event, cupsd_printer_t *dest, + cupsd_job_t *job); +#endif /* HAVE_DBUS */ +static void cupsd_send_notification(cupsd_subscription_t *sub, + cupsd_event_t *event); +static void cupsd_start_notifier(cupsd_subscription_t *sub); +static void cupsd_update_notifier(void); + + +/* + * 'cupsdAddEvent()' - Add an event to the global event cache. + */ + +void +cupsdAddEvent( + cupsd_eventmask_t event, /* I - Event */ + cupsd_printer_t *dest, /* I - Printer associated with event */ + cupsd_job_t *job, /* I - Job associated with event */ + const char *text, /* I - Notification text */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to additional arguments */ + char ftext[1024]; /* Formatted text buffer */ + ipp_attribute_t *attr; /* Printer/job attribute */ + cupsd_event_t *temp; /* New event pointer */ + cupsd_subscription_t *sub; /* Current subscription */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsdAddEvent(event=%s, dest=%p(%s), job=%p(%d), text=\"%s\", ...)", + cupsdEventName(event), dest, dest ? dest->name : "", + job, job ? job->id : 0, text); + + /* + * Keep track of events with any OS-supplied notification mechanisms... + */ + + LastEvent |= event; + +#ifdef HAVE_DBUS + cupsd_send_dbus(event, dest, job); +#endif /* HAVE_DBUS */ + + /* + * Return if we aren't keeping events... + */ + + if (MaxEvents <= 0) + { + cupsdLogMessage(CUPSD_LOG_WARN, + "cupsdAddEvent: Discarding %s event since MaxEvents is %d!", + cupsdEventName(event), MaxEvents); + return; + } + + /* + * Then loop through the subscriptions and add the event to the corresponding + * caches... + */ + + for (temp = NULL, sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + { + /* + * Check if this subscription requires this event... + */ + + if ((sub->mask & event) != 0 && + (sub->dest == dest || !sub->dest) && + (sub->job == job || !sub->job)) + { + /* + * Need this event, so create a new event record... + */ + + if ((temp = (cupsd_event_t *)calloc(1, sizeof(cupsd_event_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_CRIT, + "Unable to allocate memory for event - %s", + strerror(errno)); + return; + } + + temp->event = event; + temp->time = time(NULL); + temp->attrs = ippNew(); + temp->job = job; + temp->dest = dest; + + /* + * Add common event notification attributes... + */ + + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_CHARSET, + "notify-charset", NULL, "utf-8"); + + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_LANGUAGE, + "notify-natural-language", NULL, "en-US"); + + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); + + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "notify-sequence-number", sub->next_event_id); + + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD, + "notify-subscribed-event", NULL, cupsdEventName(event)); + + if (sub->user_data_len > 0) + ippAddOctetString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + "notify-user-data", sub->user_data, + sub->user_data_len); + + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "printer-up-time", time(NULL)); + + va_start(ap, text); + vsnprintf(ftext, sizeof(ftext), text, ap); + va_end(ap); + + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_TEXT, + "notify-text", NULL, ftext); + + if (dest) + { + /* + * Add printer attributes... + */ + + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_URI, + "notify-printer-uri", NULL, dest->uri); + + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, + "printer-name", NULL, dest->name); + + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, + "printer-state", dest->state); + + if (dest->num_reasons == 0) + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "printer-state-reasons", NULL, + dest->state == IPP_PRINTER_STOPPED ? "paused" : "none"); + else + ippAddStrings(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "printer-state-reasons", + dest->num_reasons, NULL, + (const char * const *)dest->reasons); + + ippAddBoolean(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + "printer-is-accepting-jobs", dest->accepting); + } + + if (job) + { + /* + * Add job attributes... + */ + + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "notify-job-id", job->id); + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM, + "job-state", job->state_value); + + if ((attr = ippFindAttribute(job->attrs, "job-name", + IPP_TAG_NAME)) != NULL) + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME, + "job-name", NULL, attr->values[0].string.text); + + switch (job->state_value) + { + case IPP_JOB_PENDING : + if (dest && dest->state == IPP_PRINTER_STOPPED) + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "printer-stopped"); + else + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + 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(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-hold-until-specified"); + else + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-incoming"); + break; + + case IPP_JOB_PROCESSING : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-printing"); + break; + + case IPP_JOB_STOPPED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-stopped"); + break; + + case IPP_JOB_CANCELED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-canceled-by-user"); + break; + + case IPP_JOB_ABORTED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "aborted-by-system"); + break; + + case IPP_JOB_COMPLETED : + ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, + IPP_TAG_KEYWORD, "job-state-reasons", NULL, + "job-completed-successfully"); + break; + } + + ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER, + "job-impressions-completed", + job->sheets ? job->sheets->values[0].integer : 0); + } + + /* + * Send the notification for this subscription... + */ + + cupsd_send_notification(sub, temp); + } + } + + if (temp) + cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); + else + cupsdLogMessage(CUPSD_LOG_DEBUG, "Discarding unused %s event...", + cupsdEventName(event)); +} + + +/* + * 'cupsdAddSubscription()' - Add a new subscription object. + */ + +cupsd_subscription_t * /* O - New subscription object */ +cupsdAddSubscription( + unsigned mask, /* I - Event mask */ + cupsd_printer_t *dest, /* I - Printer, if any */ + cupsd_job_t *job, /* I - Job, if any */ + const char *uri, /* I - notify-recipient-uri, if any */ + int sub_id) /* I - notify-subscription-id or 0 */ +{ + cupsd_subscription_t *temp; /* New subscription object */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription(mask=%x, dest=%p(%s), job=%p(%d), " + "uri=\"%s\")", + mask, dest, dest ? dest->name : "", job, job ? job->id : 0, + uri ? uri : "(null)"); + + if (!Subscriptions) + Subscriptions = cupsArrayNew((cups_array_func_t)cupsd_compare_subscriptions, + NULL); + + if (!Subscriptions) + { + cupsdLogMessage(CUPSD_LOG_CRIT, + "Unable to allocate memory for subscriptions - %s", + strerror(errno)); + return (NULL); + } + + /* + * Limit the number of subscriptions... + */ + + if (MaxSubscriptions > 0 && cupsArrayCount(Subscriptions) >= MaxSubscriptions) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription: Reached MaxSubscriptions %d " + "(count=%d)", MaxSubscriptions, + cupsArrayCount(Subscriptions)); + return (NULL); + } + + if (MaxSubscriptionsPerJob > 0 && job) + { + int count; /* Number of job subscriptions */ + + for (temp = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), + count = 0; + temp; + temp = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (temp->job == job) + count ++; + + if (count >= MaxSubscriptionsPerJob) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription: Reached MaxSubscriptionsPerJob %d " + "for job #%d (count=%d)", MaxSubscriptionsPerJob, + job->id, count); + return (NULL); + } + } + + if (MaxSubscriptionsPerPrinter > 0 && dest) + { + int count; /* Number of printer subscriptions */ + + for (temp = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), + count = 0; + temp; + temp = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (temp->dest == dest) + count ++; + + if (count >= MaxSubscriptionsPerPrinter) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription: Reached " + "MaxSubscriptionsPerPrinter %d for %s (count=%d)", + MaxSubscriptionsPerPrinter, dest->name, count); + return (NULL); + } + } + + /* + * Allocate memory for this subscription... + */ + + if ((temp = calloc(1, sizeof(cupsd_subscription_t))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_CRIT, + "Unable to allocate memory for subscription object - %s", + strerror(errno)); + return (NULL); + } + + /* + * Fill in common data... + */ + + if (sub_id) + { + temp->id = sub_id; + + if (sub_id >= NextSubscriptionId) + NextSubscriptionId = sub_id + 1; + } + else + { + temp->id = NextSubscriptionId; + + NextSubscriptionId ++; + } + + temp->mask = mask; + temp->dest = dest; + temp->job = job; + temp->pipe = -1; + temp->first_event_id = 1; + temp->next_event_id = 1; + + cupsdSetString(&(temp->recipient), uri); + + /* + * Add the subscription to the array... + */ + + cupsArrayAdd(Subscriptions, temp); + + /* + * For RSS subscriptions, run the notifier immediately... + */ + + if (uri && !strncmp(uri, "rss:", 4)) + cupsd_start_notifier(temp); + + return (temp); +} + + +/* + * 'cupsdDeleteAllSubscriptions()' - Delete all subscriptions. + */ + +void +cupsdDeleteAllSubscriptions(void) +{ + cupsd_subscription_t *sub; /* Subscription */ + + + if (!Subscriptions) + return; + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + cupsdDeleteSubscription(sub, 0); + + cupsArrayDelete(Subscriptions); + Subscriptions = NULL; +} + + +/* + * 'cupsdDeleteSubscription()' - Delete a subscription object. + */ + +void +cupsdDeleteSubscription( + cupsd_subscription_t *sub, /* I - Subscription object */ + int update) /* I - 1 = update subscriptions.conf */ +{ + int i; /* Looping var */ + + + /* + * Close the pipe to the notifier as needed... + */ + + if (sub->pipe >= 0) + close(sub->pipe); + + /* + * Remove subscription from array... + */ + + cupsArrayRemove(Subscriptions, sub); + + /* + * Free memory... + */ + + cupsdClearString(&(sub->owner)); + cupsdClearString(&(sub->recipient)); + + if (sub->events) + { + for (i = 0; i < sub->num_events; i ++) + cupsd_delete_event(sub->events[i]); + + free(sub->events); + } + + free(sub); + + /* + * Update the subscriptions as needed... + */ + + if (update) + cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); +} + + +/* + * 'cupsdEventName()' - Return a single event name. + */ + +const char * /* O - Event name */ +cupsdEventName( + cupsd_eventmask_t event) /* I - Event value */ +{ + switch (event) + { + default : + return (NULL); + + case CUPSD_EVENT_PRINTER_RESTARTED : + return ("printer-restarted"); + + case CUPSD_EVENT_PRINTER_SHUTDOWN : + return ("printer-shutdown"); + + case CUPSD_EVENT_PRINTER_STOPPED : + return ("printer-stopped"); + + case CUPSD_EVENT_PRINTER_FINISHINGS_CHANGED : + return ("printer-finishings-changed"); + + case CUPSD_EVENT_PRINTER_MEDIA_CHANGED : + return ("printer-media-changed"); + + case CUPSD_EVENT_PRINTER_ADDED : + return ("printer-added"); + + case CUPSD_EVENT_PRINTER_DELETED : + return ("printer-deleted"); + + case CUPSD_EVENT_PRINTER_MODIFIED : + return ("printer-modified"); + + case CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED : + return ("printer-queue-order-changed"); + + case CUPSD_EVENT_PRINTER_STATE : + case CUPSD_EVENT_PRINTER_STATE_CHANGED : + return ("printer-state-changed"); + + case CUPSD_EVENT_PRINTER_CONFIG : + case CUPSD_EVENT_PRINTER_CONFIG_CHANGED : + return ("printer-config-changed"); + + case CUPSD_EVENT_PRINTER_CHANGED : + return ("printer-changed"); + + case CUPSD_EVENT_JOB_CREATED : + return ("job-created"); + + case CUPSD_EVENT_JOB_COMPLETED : + return ("job-completed"); + + case CUPSD_EVENT_JOB_STOPPED : + return ("job-stopped"); + + case CUPSD_EVENT_JOB_CONFIG_CHANGED : + return ("job-config-changed"); + + case CUPSD_EVENT_JOB_PROGRESS : + return ("job-progress"); + + case CUPSD_EVENT_JOB_STATE : + case CUPSD_EVENT_JOB_STATE_CHANGED : + return ("job-state-changed"); + + case CUPSD_EVENT_SERVER_RESTARTED : + return ("server-restarted"); + + case CUPSD_EVENT_SERVER_STARTED : + return ("server-started"); + + case CUPSD_EVENT_SERVER_STOPPED : + return ("server-stopped"); + + case CUPSD_EVENT_SERVER_AUDIT : + return ("server-audit"); + + case CUPSD_EVENT_ALL : + return ("all"); + } +} + + +/* + * 'cupsdEventValue()' - Return the event mask value for a name. + */ + +cupsd_eventmask_t /* O - Event mask value */ +cupsdEventValue(const char *name) /* I - Name of event */ +{ + if (!strcmp(name, "all")) + return (CUPSD_EVENT_ALL); + else if (!strcmp(name, "printer-restarted")) + return (CUPSD_EVENT_PRINTER_RESTARTED); + else if (!strcmp(name, "printer-shutdown")) + return (CUPSD_EVENT_PRINTER_SHUTDOWN); + else if (!strcmp(name, "printer-stopped")) + return (CUPSD_EVENT_PRINTER_STOPPED); + else if (!strcmp(name, "printer-finishings-changed")) + return (CUPSD_EVENT_PRINTER_FINISHINGS_CHANGED); + else if (!strcmp(name, "printer-media-changed")) + return (CUPSD_EVENT_PRINTER_MEDIA_CHANGED); + else if (!strcmp(name, "printer-added")) + return (CUPSD_EVENT_PRINTER_ADDED); + else if (!strcmp(name, "printer-deleted")) + return (CUPSD_EVENT_PRINTER_DELETED); + else if (!strcmp(name, "printer-modified")) + return (CUPSD_EVENT_PRINTER_MODIFIED); + else if (!strcmp(name, "printer-queue-order-changed")) + return (CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED); + else if (!strcmp(name, "printer-state-changed")) + return (CUPSD_EVENT_PRINTER_STATE_CHANGED); + else if (!strcmp(name, "printer-config-changed")) + return (CUPSD_EVENT_PRINTER_CONFIG_CHANGED); + else if (!strcmp(name, "printer-changed")) + return (CUPSD_EVENT_PRINTER_CHANGED); + else if (!strcmp(name, "job-created")) + return (CUPSD_EVENT_JOB_CREATED); + else if (!strcmp(name, "job-completed")) + return (CUPSD_EVENT_JOB_COMPLETED); + else if (!strcmp(name, "job-stopped")) + return (CUPSD_EVENT_JOB_STOPPED); + else if (!strcmp(name, "job-config-changed")) + return (CUPSD_EVENT_JOB_CONFIG_CHANGED); + else if (!strcmp(name, "job-progress")) + return (CUPSD_EVENT_JOB_PROGRESS); + else if (!strcmp(name, "job-state-changed")) + return (CUPSD_EVENT_JOB_STATE_CHANGED); + else if (!strcmp(name, "server-restarted")) + return (CUPSD_EVENT_SERVER_RESTARTED); + else if (!strcmp(name, "server-started")) + return (CUPSD_EVENT_SERVER_STARTED); + else if (!strcmp(name, "server-stopped")) + return (CUPSD_EVENT_SERVER_STOPPED); + else if (!strcmp(name, "server-audit")) + return (CUPSD_EVENT_SERVER_AUDIT); + else + return (CUPSD_EVENT_NONE); +} + + +/* + * 'cupsdExpireSubscriptions()' - Expire old subscription objects. + */ + +void +cupsdExpireSubscriptions( + cupsd_printer_t *dest, /* I - Printer, if any */ + cupsd_job_t *job) /* I - Job, if any */ +{ + cupsd_subscription_t *sub; /* Current subscription */ + int update; /* Update subscriptions.conf? */ + time_t curtime; /* Current time */ + + + curtime = time(NULL); + update = 0; + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if ((!sub->job && !dest && sub->expire && sub->expire <= curtime) || + (dest && sub->dest == dest) || + (job && sub->job == job)) + { + cupsdLogMessage(CUPSD_LOG_INFO, "Subscription %d has expired...", + sub->id); + + cupsdDeleteSubscription(sub, 0); + + update = 1; + } + + if (update) + cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); +} + + +/* + * 'cupsdFindSubscription()' - Find a subscription by ID. + */ + +cupsd_subscription_t * /* O - Subscription object */ +cupsdFindSubscription(int id) /* I - Subscription ID */ +{ + cupsd_subscription_t sub; /* Subscription template */ + + + sub.id = id; + + return ((cupsd_subscription_t *)cupsArrayFind(Subscriptions, &sub)); +} + + +/* + * 'cupsdLoadAllSubscriptions()' - Load all subscriptions from the .conf file. + */ + +void +cupsdLoadAllSubscriptions(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* subscriptions.conf file */ + int linenum; /* Current line number */ + char line[1024], /* Line from file */ + *value, /* Pointer to value */ + *valueptr; /* Pointer into value */ + cupsd_subscription_t *sub; /* Current subscription */ + int hex; /* Non-zero if reading hex data */ + int delete_sub; /* Delete subscription? */ + + + /* + * Open the subscriptions.conf file... + */ + + snprintf(line, sizeof(line), "%s/subscriptions.conf", ServerRoot); + if ((fp = cupsFileOpen(line, "r")) == NULL) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, + "LoadAllSubscriptions: Unable to open %s - %s", line, + strerror(errno)); + return; + } + + /* + * Read all of the lines from the file... + */ + + linenum = 0; + sub = NULL; + delete_sub = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + if (!strcasecmp(line, "NextSubscriptionId") && value) + { + /* + * NextSubscriptionId NNN + */ + + i = atoi(value); + if (i >= NextSubscriptionId && i > 0) + NextSubscriptionId = i; + } + else if (!strcasecmp(line, " + */ + + if (!sub && value && isdigit(value[0] & 255)) + { + sub = cupsdAddSubscription(CUPSD_EVENT_NONE, NULL, NULL, NULL, + atoi(value)); + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "")) + { + if (!sub) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + + if (delete_sub) + cupsdDeleteSubscription(sub, 0); + + sub = NULL; + delete_sub = 0; + } + else if (!sub) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + } + else if (!strcasecmp(line, "Events")) + { + /* + * Events name + * Events name name name ... + */ + + if (!value) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + + while (*value) + { + /* + * Separate event names... + */ + + for (valueptr = value; !isspace(*valueptr) && *valueptr; valueptr ++); + + while (isspace(*valueptr & 255)) + *valueptr++ = '\0'; + + /* + * See if the name exists... + */ + + if ((sub->mask |= cupsdEventValue(value)) == CUPSD_EVENT_NONE) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown event name \'%s\' on line %d of subscriptions.conf.", + value, linenum); + break; + } + + value = valueptr; + } + } + else if (!strcasecmp(line, "Owner")) + { + /* + * Owner + */ + + if (value) + cupsdSetString(&sub->owner, value); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "Recipient")) + { + /* + * Recipient uri + */ + + if (value) + cupsdSetString(&sub->recipient, value); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "JobId")) + { + /* + * JobId # + */ + + if (value && isdigit(*value & 255)) + { + if ((sub->job = cupsdFindJob(atoi(value))) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Job %s not found on line %d of subscriptions.conf.", + value, linenum); + delete_sub = 1; + } + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "PrinterName")) + { + /* + * PrinterName name + */ + + if (value) + { + if ((sub->dest = cupsdFindDest(value)) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Printer \'%s\' not found on line %d of subscriptions.conf.", + value, linenum); + delete_sub = 1; + } + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "UserData")) + { + /* + * UserData encoded-string + */ + + if (value) + { + for (i = 0, valueptr = value, hex = 0; i < 63 && *valueptr; i ++) + { + if (*valueptr == '<' && !hex) + { + hex = 1; + valueptr ++; + } + + if (hex) + { + if (isxdigit(valueptr[0]) && isxdigit(valueptr[1])) + { + if (isdigit(valueptr[0])) + sub->user_data[i] = (valueptr[0] - '0') << 4; + else + sub->user_data[i] = (tolower(valueptr[0]) - 'a' + 10) << 4; + + if (isdigit(valueptr[1])) + sub->user_data[i] |= valueptr[1] - '0'; + else + sub->user_data[i] |= tolower(valueptr[1]) - 'a' + 10; + + valueptr += 2; + + if (*valueptr == '>') + { + hex = 0; + valueptr ++; + } + } + else + break; + } + else + sub->user_data[i] = *valueptr++; + } + + if (*valueptr) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Bad UserData \'%s\' on line %d of subscriptions.conf.", + value, linenum); + } + else + sub->user_data_len = i; + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "LeaseDuration")) + { + /* + * LeaseDuration # + */ + + if (value && isdigit(*value & 255)) + { + sub->lease = atoi(value); + sub->expire = sub->lease ? time(NULL) + sub->lease : 0; + } + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "Interval")) + { + /* + * Interval # + */ + + if (value && isdigit(*value & 255)) + sub->interval = atoi(value); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "ExpirationTime")) + { + /* + * ExpirationTime # + */ + + if (value && isdigit(*value & 255)) + sub->expire = atoi(value); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else if (!strcasecmp(line, "NextEventId")) + { + /* + * NextEventId # + */ + + if (value && isdigit(*value & 255)) + sub->next_event_id = sub->first_event_id = atoi(value); + else + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Syntax error on line %d of subscriptions.conf.", + linenum); + break; + } + } + else + { + /* + * Something else we don't understand... + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unknown configuration directive %s on line %d of subscriptions.conf.", + line, linenum); + } + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdSaveAllSubscriptions()' - Save all subscriptions to the .conf file. + */ + +void +cupsdSaveAllSubscriptions(void) +{ + int i; /* Looping var */ + cups_file_t *fp; /* subscriptions.conf file */ + char temp[1024]; /* Temporary string */ + char backup[1024]; /* subscriptions.conf.O file */ + cupsd_subscription_t *sub; /* Current subscription */ + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + unsigned mask; /* Current event mask */ + const char *name; /* Current event name */ + int hex; /* Non-zero if we are writing hex data */ + + + /* + * Create the subscriptions.conf file... + */ + + snprintf(temp, sizeof(temp), "%s/subscriptions.conf", ServerRoot); + snprintf(backup, sizeof(backup), "%s/subscriptions.conf.O", ServerRoot); + + if (rename(temp, backup)) + { + if (errno != ENOENT) + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup subscriptions.conf - %s", + strerror(errno)); + } + + if ((fp = cupsFileOpen(temp, "w")) == NULL) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to save subscriptions.conf - %s", + strerror(errno)); + + if (rename(backup, temp)) + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to restore subscriptions.conf - %s", + strerror(errno)); + return; + } + else + cupsdLogMessage(CUPSD_LOG_INFO, "Saving subscriptions.conf..."); + + /* + * Restrict access to the file... + */ + + fchown(cupsFileNumber(fp), getuid(), Group); + fchmod(cupsFileNumber(fp), ConfigFilePerm); + + /* + * Write a small header to the file... + */ + + curtime = time(NULL); + curdate = localtime(&curtime); + strftime(temp, sizeof(temp) - 1, "%Y-%m-%d %H:%M", curdate); + + cupsFilePuts(fp, "# Subscription configuration file for " CUPS_SVERSION "\n"); + cupsFilePrintf(fp, "# Written by cupsd on %s\n", temp); + + cupsFilePrintf(fp, "NextSubscriptionId %d\n", NextSubscriptionId); + + /* + * Write every subscription known to the system... + */ + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + { + cupsFilePrintf(fp, "\n", sub->id); + + if ((name = cupsdEventName((cupsd_eventmask_t)sub->mask)) != NULL) + { + /* + * Simple event list... + */ + + cupsFilePrintf(fp, "Events %s\n", name); + } + else + { + /* + * Complex event list... + */ + + cupsFilePuts(fp, "Events"); + + for (mask = 1; mask < CUPSD_EVENT_ALL; mask <<= 1) + if (sub->mask & mask) + cupsFilePrintf(fp, " %s", cupsdEventName((cupsd_eventmask_t)mask)); + + cupsFilePuts(fp, "\n"); + } + + if (sub->owner) + cupsFilePrintf(fp, "Owner %s\n", sub->owner); + if (sub->recipient) + cupsFilePrintf(fp, "Recipient %s\n", sub->recipient); + if (sub->job) + cupsFilePrintf(fp, "JobId %d\n", sub->job->id); + if (sub->dest) + cupsFilePrintf(fp, "PrinterName %s\n", sub->dest->name); + + if (sub->user_data_len > 0) + { + cupsFilePuts(fp, "UserData "); + + for (i = 0, hex = 0; i < sub->user_data_len; i ++) + { + if (sub->user_data[i] < ' ' || + sub->user_data[i] > 0x7f || + sub->user_data[i] == '<') + { + if (!hex) + { + cupsFilePrintf(fp, "<%02X", sub->user_data[i]); + hex = 1; + } + else + cupsFilePrintf(fp, "%02X", sub->user_data[i]); + } + else + { + if (hex) + { + cupsFilePrintf(fp, ">%c", sub->user_data[i]); + hex = 0; + } + else + cupsFilePutChar(fp, sub->user_data[i]); + } + } + + if (hex) + cupsFilePuts(fp, ">\n"); + else + cupsFilePutChar(fp, '\n'); + } + + cupsFilePrintf(fp, "LeaseDuration %d\n", sub->lease); + cupsFilePrintf(fp, "Interval %d\n", sub->interval); + cupsFilePrintf(fp, "ExpirationTime %ld\n", (long)sub->expire); + cupsFilePrintf(fp, "NextEventId %d\n", sub->next_event_id); + + cupsFilePuts(fp, "\n"); + } + + cupsFileClose(fp); +} + + +/* + * 'cupsdStopAllNotifiers()' - Stop all notifier processes. + */ + +void +cupsdStopAllNotifiers(void) +{ + cupsd_subscription_t *sub; /* Current subscription */ + + + /* + * See if we have started any notifiers... + */ + + if (!NotifierStatusBuffer) + return; + + /* + * Yes, kill any processes that are left... + */ + + for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); + sub; + sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (sub->pid) + { + cupsdEndProcess(sub->pid, 0); + + close(sub->pipe); + sub->pipe = -1; + } + + /* + * Close the status pipes... + */ + + if (NotifierPipes[0] >= 0) + { + cupsdRemoveSelect(NotifierPipes[0]); + + cupsdStatBufDelete(NotifierStatusBuffer); + + close(NotifierPipes[0]); + close(NotifierPipes[1]); + + NotifierPipes[0] = -1; + NotifierPipes[1] = -1; + NotifierStatusBuffer = NULL; + } +} + + +/* + * 'cupsd_compare_subscriptions()' - Compare two subscriptions. + */ + +static int /* O - Result of comparison */ +cupsd_compare_subscriptions( + cupsd_subscription_t *first, /* I - First subscription object */ + cupsd_subscription_t *second, /* I - Second subscription object */ + void *unused) /* I - Unused user data pointer */ +{ + (void)unused; + + return (first->id - second->id); +} + + +/* + * 'cupsd_delete_event()' - Delete a single event... + * + * Oldest events must be deleted first, otherwise the subscription cache + * flushing code will not work properly. + */ + +static void +cupsd_delete_event(cupsd_event_t *event)/* I - Event to delete */ +{ + /* + * Free memory... + */ + + ippDelete(event->attrs); + free(event); +} + + +#ifdef HAVE_DBUS +/* + * 'cupsd_send_dbus()' - Send a DBUS notification... + */ + +static void +cupsd_send_dbus(cupsd_eventmask_t event,/* I - Event to send */ + cupsd_printer_t *dest,/* I - Destination, if any */ + cupsd_job_t *job) /* I - Job, if any */ +{ + DBusError error; /* Error, if any */ + DBusMessage *message; /* Message to send */ + DBusMessageIter iter; /* Iterator for message data */ + const char *what; /* What to send */ + static DBusConnection *con = NULL; /* Connection to DBUS server */ + + + /* + * Figure out what to send, if anything... + */ + + if (event & CUPSD_EVENT_PRINTER_ADDED) + what = "PrinterAdded"; + else if (event & CUPSD_EVENT_PRINTER_DELETED) + what = "PrinterRemoved"; + else if (event & CUPSD_EVENT_PRINTER_CHANGED) + what = "QueueChanged"; + else if (event & CUPSD_EVENT_JOB_CREATED) + what = "JobQueuedLocal"; + else if ((event & CUPSD_EVENT_JOB_STATE) && job && + job->state_value == IPP_JOB_PROCESSING) + what = "JobStartedLocal"; + else + return; + + /* + * Verify connection to DBUS server... + */ + + if (con && !dbus_connection_get_is_connected(con)) + { + dbus_connection_unref(con); + con = NULL; + } + + if (!con) + { + dbus_error_init(&error); + + con = dbus_bus_get(getuid() ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error); + if (!con) + { + dbus_error_free(&error); + return; + } + } + + /* + * Create and send the new message... + */ + + message = dbus_message_new_signal("/com/redhat/PrinterSpooler", + "com.redhat.PrinterSpooler", what); + + dbus_message_append_iter_init(message, &iter); + if (dest) + dbus_message_iter_append_string(&iter, dest->name); + if (job) + { + dbus_message_iter_append_uint32(&iter, job->id); + dbus_message_iter_append_string(&iter, job->username); + } + + dbus_connection_send(con, message, NULL); + dbus_connection_flush(con); + dbus_message_unref(message); +} +#endif /* HAVE_DBUS */ + + +/* + * 'cupsd_send_notification()' - Send a notification for the specified event. + */ + +static void +cupsd_send_notification( + cupsd_subscription_t *sub, /* I - Subscription object */ + cupsd_event_t *event) /* I - Event to send */ +{ + ipp_state_t state; /* IPP event state */ + + + cupsdLogMessage(CUPSD_LOG_DEBUG2, + "cupsd_send_notification(sub=%p(%d), event=%p(%s))", + sub, sub->id, event, cupsdEventName(event->event)); + + /* + * Allocate the events array as needed... + */ + + if (!sub->events) + { + sub->events = calloc(MaxEvents, sizeof(cupsd_event_t *)); + + if (!sub->events) + { + cupsdLogMessage(CUPSD_LOG_CRIT, + "Unable to allocate memory for subscription #%d!", + sub->id); + return; + } + } + + /* + * Purge an old event as needed... + */ + + if (sub->num_events >= MaxEvents) + { + /* + * Purge the oldest event in the cache... + */ + + cupsd_delete_event(sub->events[0]); + + sub->num_events --; + sub->first_event_id ++; + + memmove(sub->events, sub->events + 1, + sub->num_events * sizeof(cupsd_event_t *)); + } + + /* + * Add the event to the subscription. Since the events array is + * always MaxEvents in length, and since we will have already + * removed an event from the subscription cache if we hit the + * event cache limit, we don't need to check for overflow here... + */ + + sub->events[sub->num_events] = event; + sub->num_events ++; + + /* + * Deliver the event... + */ + + if (sub->recipient) + { + for (;;) + { + if (sub->pipe < 0) + cupsd_start_notifier(sub); + + cupsdLogMessage(CUPSD_LOG_DEBUG2, "sub->pipe=%d", sub->pipe); + + if (sub->pipe < 0) + break; + + event->attrs->state = IPP_IDLE; + + while ((state = ippWriteFile(sub->pipe, event->attrs)) != IPP_DATA) + if (state == IPP_ERROR) + break; + + if (state == IPP_ERROR) + { + if (errno == EPIPE) + { + /* + * Notifier died, try restarting it... + */ + + cupsdLogMessage(CUPSD_LOG_WARN, + "Notifier for subscription %d (%s) went away, " + "retrying!", + sub->id, sub->recipient); + cupsdEndProcess(sub->pid, 0); + + close(sub->pipe); + sub->pipe = -1; + continue; + } + + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to send event for subscription %d (%s)!", + sub->id, sub->recipient); + } + + /* + * If we get this far, break out of the loop... + */ + + break; + } + } + + /* + * Bump the event sequence number... + */ + + sub->next_event_id ++; +} + + +/* + * 'cupsd_start_notifier()' - Start a notifier subprocess... + */ + +static void +cupsd_start_notifier( + cupsd_subscription_t *sub) /* I - Subscription object */ +{ + int pid; /* Notifier process ID */ + int fds[2]; /* Pipe file descriptors */ + char *argv[4], /* Command-line arguments */ + *envp[MAX_ENV], /* Environment variables */ + user_data[128], /* Base-64 encoded user data */ + scheme[256], /* notify-recipient-uri scheme */ + *ptr, /* Pointer into scheme */ + command[1024]; /* Notifier command */ + + + /* + * Extract the scheme name from the recipient URI and point to the + * notifier program... + */ + + strlcpy(scheme, sub->recipient, sizeof(scheme)); + if ((ptr = strchr(scheme, ':')) != NULL) + *ptr = '\0'; + + snprintf(command, sizeof(command), "%s/notifier/%s", ServerBin, scheme); + + /* + * Base-64 encode the user data... + */ + + httpEncode64_2(user_data, sizeof(user_data), (char *)sub->user_data, + sub->user_data_len); + + /* + * Setup the argument array... + */ + + argv[0] = command; + argv[1] = sub->recipient; + argv[2] = user_data; + argv[3] = NULL; + + /* + * Setup the environment... + */ + + cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0]))); + + /* + * Create pipes as needed... + */ + + if (!NotifierStatusBuffer) + { + /* + * Create the status pipe... + */ + + if (cupsdOpenPipe(NotifierPipes)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create pipes for notifier status - %s", + strerror(errno)); + return; + } + + NotifierStatusBuffer = cupsdStatBufNew(NotifierPipes[0], "[Notifier]"); + + cupsdAddSelect(NotifierPipes[0], (cupsd_selfunc_t)cupsd_update_notifier, + NULL, NULL); + } + + if (cupsdOpenPipe(fds)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "Unable to create pipes for notifier %s - %s", + scheme, strerror(errno)); + return; + } + + /* + * Make sure the delivery pipe is non-blocking... + */ + + fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL) | O_NONBLOCK); + + /* + * Create the notifier process... + */ + + if (cupsdStartProcess(command, argv, envp, fds[0], -1, NotifierPipes[1], + -1, -1, 0, DefaultProfile, NULL, &pid) < 0) + { + /* + * Error - can't fork! + */ + + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to fork for notifier %s - %s", + scheme, strerror(errno)); + + cupsdClosePipe(fds); + } + else + { + /* + * Fork successful - return the PID... + */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "Notifier %s started - PID = %d", + scheme, pid); + + sub->pid = pid; + sub->pipe = fds[1]; + sub->status = 0; + + close(fds[0]); + } +} + + +/* + * 'cupsd_update_notifier()' - Read messages from notifiers. + */ + +void +cupsd_update_notifier(void) +{ + char message[1024]; /* Pointer to message text */ + int loglevel; /* Log level for message */ + + + while (cupsdStatBufUpdate(NotifierStatusBuffer, &loglevel, + message, sizeof(message))) + { + if (loglevel == CUPSD_LOG_INFO) + cupsdLogMessage(CUPSD_LOG_INFO, "%s", message); + + if (!strchr(NotifierStatusBuffer->buffer, '\n')) + break; + } +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/subscriptions.h b/scheduler/subscriptions.h new file mode 100644 index 0000000000..694e5147fe --- /dev/null +++ b/scheduler/subscriptions.h @@ -0,0 +1,167 @@ +/* + * "$Id$" + * + * Subscription definitions for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Event mask enumeration... + */ + +typedef enum +{ + /* Individual printer events... */ + CUPSD_EVENT_PRINTER_STATE = 0x0001, /* Sent after generic printer state change */ + CUPSD_EVENT_PRINTER_RESTARTED = 0x0002, + /* Sent after printer restarted */ + CUPSD_EVENT_PRINTER_SHUTDOWN = 0x0004,/* Sent after printer shutdown */ + CUPSD_EVENT_PRINTER_STOPPED = 0x0008, /* Sent after printer stopped */ + + CUPSD_EVENT_PRINTER_CONFIG = 0x0010, /* Send after add/modify changes attrs */ + CUPSD_EVENT_PRINTER_FINISHINGS_CHANGED = 0x0020, + /* Sent after finishings-supported changed */ + CUPSD_EVENT_PRINTER_MEDIA_CHANGED = 0x0040, + /* Sent after media-supported changed */ + CUPSD_EVENT_PRINTER_ADDED = 0x0080, /* Sent after printer added */ + CUPSD_EVENT_PRINTER_DELETED = 0x0100, /* Sent after printer deleted */ + CUPSD_EVENT_PRINTER_MODIFIED = 0x0200,/* Sent after printer modified */ + CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED = 0x0400, + /* Sent when the order of jobs is changed */ + + /* Convenience printer event groupings... */ + CUPSD_EVENT_PRINTER_STATE_CHANGED = 0x000f, + /* STATE + RESTARTED + SHUTDOWN + STOPPED */ + CUPSD_EVENT_PRINTER_CONFIG_CHANGED = 0x0070, + /* CONFIG + FINISHINGS_CHANGED + MEDIA_CHANGED */ + CUPSD_EVENT_PRINTER_CHANGED = 0x07ff, /* All of the above */ + + /* Individual job events... */ + CUPSD_EVENT_JOB_STATE = 0x0800, /* Any state change */ + CUPSD_EVENT_JOB_CREATED = 0x1000, /* Send after job is created */ + CUPSD_EVENT_JOB_COMPLETED = 0x2000, /* Sent after job is completed */ + CUPSD_EVENT_JOB_STOPPED = 0x4000, /* Sent after job is stopped */ + CUPSD_EVENT_JOB_CONFIG_CHANGED = 0x8000, + /* Sent after set-job-attributes */ + CUPSD_EVENT_JOB_PROGRESS = 0x10000, /* Sent for each page */ + + /* Convenience job event grouping... */ + CUPSD_EVENT_JOB_STATE_CHANGED = 0x7800, + /* STATE + CREATED + COMPLETED + STOPPED */ + + /* Server events... */ + CUPSD_EVENT_SERVER_RESTARTED = 0x20000,/* Sent after server restarts */ + CUPSD_EVENT_SERVER_STARTED = 0x40000, /* Sent when server first starts */ + CUPSD_EVENT_SERVER_STOPPED = 0x80000, /* Sent when server is stopped */ + CUPSD_EVENT_SERVER_AUDIT = 0x100000, /* Security-related stuff */ + + /* Everything and nothing... */ + CUPSD_EVENT_NONE = 0, /* Nothing */ + CUPSD_EVENT_ALL = 0x1fffff /* Everything */ +} cupsd_eventmask_t; + + +/* + * Notiification support structures... + */ + +typedef struct cupsd_event_s /**** Event structure ****/ +{ + cupsd_eventmask_t event; /* Event */ + time_t time; /* Time of event */ + ipp_t *attrs; /* Notification message */ + cupsd_printer_t *dest; /* Associated printer, if any */ + cupsd_job_t *job; /* Associated job, if any */ +} cupsd_event_t; + +typedef struct cupsd_subscription_s /**** Subscription structure ****/ +{ + int id; /* subscription-id */ + unsigned mask; /* Event mask */ + char *owner; /* notify-subscriber-user-name */ + char *recipient; /* notify-recipient-uri, if applicable */ + unsigned char user_data[64]; /* notify-user-data */ + int user_data_len; /* Length of notify-user-data */ + int lease; /* notify-lease-duration */ + int interval; /* notify-time-interval */ + cupsd_printer_t *dest; /* notify-printer-uri, if any */ + cupsd_job_t *job; /* notify-job-id, if any */ + int pid; /* Process ID of notifier */ + int pipe; /* Pipe to notifier */ + int status; /* Exit status of notifier */ + time_t last; /* Time of last notification */ + time_t expire; /* Lease expiration time */ + int first_event_id, /* First event-id in cache */ + next_event_id, /* Next event-id to use */ + num_events; /* Number of cached events */ + cupsd_event_t **events; /* Cached events */ +} cupsd_subscription_t; + + +/* + * Globals... + */ + +VAR int MaxSubscriptions VALUE(100), + /* Overall subscription limit */ + MaxSubscriptionsPerJob VALUE(0), + /* Per-job subscription limit */ + MaxSubscriptionsPerPrinter VALUE(0), + /* Per-printer subscription limit */ + MaxSubscriptionsPerUser VALUE(0), + /* Per-user subscription limit */ + NextSubscriptionId VALUE(1), + /* Next subscription ID */ + DefaultLeaseDuration VALUE(86400), + /* Default notify-lease-duration */ + MaxLeaseDuration VALUE(0); + /* Maximum notify-lease-duration */ +VAR cups_array_t *Subscriptions VALUE(NULL); + /* Active subscriptions */ + +VAR int MaxEvents VALUE(100); /* Maximum number of events */ + +VAR unsigned LastEvent VALUE(0); /* Last event(s) processed */ +VAR int NotifierPipes[2] VALUE2(-1, -1); + /* Pipes for notifier error/debug output */ +VAR cupsd_statbuf_t *NotifierStatusBuffer VALUE(NULL); + /* Status buffer for pipes */ + + +/* + * Prototypes... + */ + +extern void cupsdAddEvent(cupsd_eventmask_t event, cupsd_printer_t *dest, + cupsd_job_t *job, const char *text, ...); +extern cupsd_subscription_t * + cupsdAddSubscription(unsigned mask, cupsd_printer_t *dest, + cupsd_job_t *job, const char *uri, + int sub_id); +extern void cupsdDeleteAllSubscriptions(void); +extern void cupsdDeleteSubscription(cupsd_subscription_t *sub, int update); +extern const char * + cupsdEventName(cupsd_eventmask_t event); +extern cupsd_eventmask_t + cupsdEventValue(const char *name); + +extern cupsd_subscription_t * + cupsdFindSubscription(int id); +extern void cupsdExpireSubscriptions(cupsd_printer_t *dest, + cupsd_job_t *job); +extern void cupsdLoadAllSubscriptions(void); +extern void cupsdSaveAllSubscriptions(void); +extern void cupsdStopAllNotifiers(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/sysman.c b/scheduler/sysman.c new file mode 100644 index 0000000000..eab30f5d08 --- /dev/null +++ b/scheduler/sysman.c @@ -0,0 +1,921 @@ +/* + * "$Id$" + * + * System management definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdCleanDirty() - Write dirty config and state files. + * cupsdMarkDirty() - Mark config or state files as needing a + * write. + * cupsdSetBusyState() - Let the system know when we are busy + * doing something. + * cupsdAllowSleep() - Tell the OS it is now OK to sleep. + * cupsdStartSystemMonitor() - Start monitoring for system change. + * cupsdStopSystemMonitor() - Stop monitoring for system change. + * sysEventThreadEntry() - A thread to receive power and computer + * name change notifications. + * sysEventPowerNotifier() - Handle power notification events. + * sysEventConfigurationNotifier() - Computer name changed notification + * callback. + * sysEventTimerNotifier() - Handle delayed event notifications. + * sysUpdate() - Update the current system state. + */ + + +/* + * Include necessary headers... + */ + +#include "cupsd.h" +#ifdef HAVE_VPROC_TRANSACTION_BEGIN +# include +#endif /* HAVE_VPROC_TRANSACTION_BEGIN */ + + +/* + * The system management functions cover disk and power management which + * are primarily used on portable computers. + * + * Disk management involves delaying the write of certain configuration + * and state files to minimize the number of times the disk has to spin + * up. + * + * Power management support is currently only implemented on MacOS X, but + * essentially we use four functions to let the OS know when it is OK to + * put the system to idle sleep, typically when we are not in the middle of + * printing a job. + * + * Once put to sleep, we invalidate all remote printers since it is common + * to wake up in a new location/on a new wireless network. + */ + + +/* + * 'cupsdCleanDirty()' - Write dirty config and state files. + */ + +void +cupsdCleanDirty(void) +{ + if (DirtyFiles & CUPSD_DIRTY_PRINTERS) + cupsdSaveAllPrinters(); + + if (DirtyFiles & CUPSD_DIRTY_CLASSES) + cupsdSaveAllClasses(); + + if (DirtyFiles & CUPSD_DIRTY_REMOTE) + cupsdSaveRemoteCache(); + + if (DirtyFiles & CUPSD_DIRTY_PRINTCAP) + cupsdWritePrintcap(); + + if (DirtyFiles & CUPSD_DIRTY_JOBS) + { + cupsd_job_t *job; /* Current job */ + + cupsdSaveAllJobs(); + + for (job = (cupsd_job_t *)cupsArrayFirst(Jobs); + job; + job = (cupsd_job_t *)cupsArrayNext(Jobs)) + if (job->dirty) + cupsdSaveJob(job); + } + + if (DirtyFiles & CUPSD_DIRTY_SUBSCRIPTIONS) + cupsdSaveAllSubscriptions(); + + DirtyFiles = CUPSD_DIRTY_NONE; + DirtyCleanTime = 0; + + cupsdSetBusyState(); +} + + +/* + * 'cupsdMarkDirty()' - Mark config or state files as needing a write. + */ + +void +cupsdMarkDirty(int what) /* I - What file(s) are dirty? */ +{ + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdMarkDirty(%c%c%c%c%c%c)", + (what & CUPSD_DIRTY_PRINTERS) ? 'P' : '-', + (what & CUPSD_DIRTY_CLASSES) ? 'C' : '-', + (what & CUPSD_DIRTY_REMOTE) ? 'R' : '-', + (what & CUPSD_DIRTY_PRINTCAP) ? 'p' : '-', + (what & CUPSD_DIRTY_JOBS) ? 'J' : '-', + (what & CUPSD_DIRTY_SUBSCRIPTIONS) ? 'S' : '-'); + + if (what == CUPSD_DIRTY_PRINTCAP && !Printcap) + return; + + DirtyFiles |= what; + + if (!DirtyCleanTime) + DirtyCleanTime = time(NULL) + DirtyCleanInterval; + + cupsdSetBusyState(); +} + + +/* + * 'cupsdSetBusyState()' - Let the system know when we are busy doing something. + */ + +void +cupsdSetBusyState(void) +{ + int newbusy; /* New busy state */ + static int busy = 0; /* Current busy state */ + static const char * const busy_text[] = + { /* Text for busy states */ + "Not busy", + "Dirty files", + "Printing jobs", + "Printing jobs and dirty files", + "Active clients", + "Active clients and dirty files", + "Active clients and printing jobs", + "Active clients, printing jobs, and dirty files" + }; +#ifdef HAVE_VPROC_TRANSACTION_BEGIN + static vproc_transaction_t vtran = 0; /* Current busy transaction */ +#endif /* HAVE_VPROC_TRANSACTION_BEGIN */ + + + newbusy = (DirtyCleanTime ? 1 : 0) | + (cupsArrayCount(PrintingJobs) ? 2 : 0) | + (cupsArrayCount(ActiveClients) ? 4 : 0); + + if (newbusy != busy) + { + busy = newbusy; + +#ifdef HAVE_VPROC_TRANSACTION_BEGIN + if (busy && !vtran) + vtran = vproc_transaction_begin(NULL); + else if (!busy && vtran) + { + vproc_transaction_end(NULL, vtran); + vtran = 0; + } +#endif /* HAVE_VPROC_TRANSACTION_BEGIN */ + + cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdSetBusyState: %s", busy_text[busy]); + } +} + + +#ifdef __APPLE__ +/* + * This is the Apple-specific system event code. It works by creating + * a worker thread that waits for events from the OS and relays them + * to the main thread via a traditional pipe. + */ + +/* + * Include MacOS-specific headers... + */ + +# include +# include +# include +# include +# include + + +/* + * Constants... + */ + +# define SYSEVENT_CANSLEEP 0x1 /* Decide whether to allow sleep or not */ +# define SYSEVENT_WILLSLEEP 0x2 /* Computer will go to sleep */ +# define SYSEVENT_WOKE 0x4 /* Computer woke from sleep */ +# define SYSEVENT_NETCHANGED 0x8 /* Network changed */ +# define SYSEVENT_NAMECHANGED 0x10 /* Computer name changed */ + + +/* + * Structures... + */ + +typedef struct cupsd_sysevent_s /*** System event data ****/ +{ + unsigned char event; /* Event bit field */ + io_connect_t powerKernelPort; /* Power context data */ + long powerNotificationID; /* Power event data */ +} cupsd_sysevent_t; + + +typedef struct cupsd_thread_data_s /*** Thread context data ****/ +{ + cupsd_sysevent_t sysevent; /* System event */ + CFRunLoopTimerRef timerRef; /* Timer to delay some change * + * notifications */ +} cupsd_thread_data_t; + + +/* + * Local globals... + */ + +static pthread_t SysEventThread = NULL; + /* Thread to host a runloop */ +static pthread_mutex_t SysEventThreadMutex = { 0 }; + /* Coordinates access to shared gloabals */ +static pthread_cond_t SysEventThreadCond = { 0 }; + /* Thread initialization complete condition */ +static CFRunLoopRef SysEventRunloop = NULL; + /* The runloop. Access must be protected! */ +static CFStringRef ComputerNameKey = NULL, + /* Computer name key */ + BTMMKey = NULL, /* Back to My Mac key */ + NetworkGlobalKeyIPv4 = NULL, + /* Network global IPv4 key */ + NetworkGlobalKeyIPv6 = NULL, + /* Network global IPv6 key */ + NetworkGlobalKeyDNS = NULL, + /* Network global DNS key */ + HostNamesKey = NULL, + /* Host name key */ + NetworkInterfaceKeyIPv4 = NULL, + /* Netowrk interface key */ + NetworkInterfaceKeyIPv6 = NULL; + /* Netowrk interface key */ +static cupsd_sysevent_t LastSysEvent; /* Last system event (for delayed sleep) */ + + +/* + * Local functions... + */ + +static void *sysEventThreadEntry(void); +static void sysEventPowerNotifier(void *context, io_service_t service, + natural_t messageType, + void *messageArgument); +static void sysEventConfigurationNotifier(SCDynamicStoreRef store, + CFArrayRef changedKeys, + void *context); +static void sysEventTimerNotifier(CFRunLoopTimerRef timer, void *context); +static void sysUpdate(void); + + +/* + * 'cupsdAllowSleep()' - Tell the OS it is now OK to sleep. + */ + +void +cupsdAllowSleep(void) +{ + cupsdCleanDirty(); + + IOAllowPowerChange(LastSysEvent.powerKernelPort, + LastSysEvent.powerNotificationID); +} + + +/* + * 'cupsdStartSystemMonitor()' - Start monitoring for system change. + */ + +void +cupsdStartSystemMonitor(void) +{ + int flags; /* fcntl flags on pipe */ + + + if (cupsdOpenPipe(SysEventPipes)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "System event monitor pipe() failed - %s!", + strerror(errno)); + return; + } + + cupsdAddSelect(SysEventPipes[0], (cupsd_selfunc_t)sysUpdate, NULL, NULL); + + /* + * Set non-blocking mode on the descriptor we will be receiving notification + * events on. + */ + + flags = fcntl(SysEventPipes[0], F_GETFL, 0); + fcntl(SysEventPipes[0], F_SETFL, flags | O_NONBLOCK); + + /* + * Start the thread that runs the runloop... + */ + + pthread_mutex_init(&SysEventThreadMutex, NULL); + pthread_cond_init(&SysEventThreadCond, NULL); + pthread_create(&SysEventThread, NULL, (void *(*)())sysEventThreadEntry, NULL); +} + + +/* + * 'cupsdStopSystemMonitor()' - Stop monitoring for system change. + */ + +void +cupsdStopSystemMonitor(void) +{ + CFRunLoopRef rl; /* The event handler runloop */ + + + if (SysEventThread) + { + /* + * Make sure the thread has completed it's initialization and + * stored it's runloop reference in the shared global. + */ + + pthread_mutex_lock(&SysEventThreadMutex); + + if (!SysEventRunloop) + pthread_cond_wait(&SysEventThreadCond, &SysEventThreadMutex); + + rl = SysEventRunloop; + SysEventRunloop = NULL; + + pthread_mutex_unlock(&SysEventThreadMutex); + + if (rl) + CFRunLoopStop(rl); + + pthread_join(SysEventThread, NULL); + pthread_mutex_destroy(&SysEventThreadMutex); + pthread_cond_destroy(&SysEventThreadCond); + } + + if (SysEventPipes[0] >= 0) + { + cupsdRemoveSelect(SysEventPipes[0]); + cupsdClosePipe(SysEventPipes); + } +} + + +/* + * 'sysEventThreadEntry()' - A thread to receive power and computer name + * change notifications. + */ + +static void * /* O - Return status/value */ +sysEventThreadEntry(void) +{ + io_object_t powerNotifierObj; + /* Power notifier object */ + IONotificationPortRef powerNotifierPort; + /* Power notifier port */ + SCDynamicStoreRef store = NULL;/* System Config dynamic store */ + CFRunLoopSourceRef powerRLS = NULL,/* Power runloop source */ + storeRLS = NULL;/* System Config runloop source */ + CFStringRef key[6], /* System Config keys */ + pattern[2]; /* System Config patterns */ + CFArrayRef keys = NULL, /* System Config key array*/ + patterns = NULL;/* System Config pattern array */ + SCDynamicStoreContext storeContext; /* Dynamic store context */ + CFRunLoopTimerContext timerContext; /* Timer context */ + cupsd_thread_data_t threadData; /* Thread context data for the * + * runloop notifiers */ + + + /* + * Register for power state change notifications + */ + + bzero(&threadData, sizeof(threadData)); + + threadData.sysevent.powerKernelPort = + IORegisterForSystemPower(&threadData, &powerNotifierPort, + sysEventPowerNotifier, &powerNotifierObj); + + if (threadData.sysevent.powerKernelPort) + { + powerRLS = IONotificationPortGetRunLoopSource(powerNotifierPort); + CFRunLoopAddSource(CFRunLoopGetCurrent(), powerRLS, kCFRunLoopDefaultMode); + } + else + DEBUG_puts("sysEventThreadEntry: error registering for system power " + "notifications"); + + /* + * Register for system configuration change notifications + */ + + bzero(&storeContext, sizeof(storeContext)); + storeContext.info = &threadData; + + store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), + sysEventConfigurationNotifier, &storeContext); + + if (!ComputerNameKey) + ComputerNameKey = SCDynamicStoreKeyCreateComputerName(kCFAllocatorDefault); + + if (!BTMMKey) + BTMMKey = SCDynamicStoreKeyCreate(kCFAllocatorDefault, + CFSTR("Setup:/Network/BackToMyMac")); + + if (!NetworkGlobalKeyIPv4) + NetworkGlobalKeyIPv4 = + SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, + kSCDynamicStoreDomainState, + kSCEntNetIPv4); + + if (!NetworkGlobalKeyIPv6) + NetworkGlobalKeyIPv6 = + SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, + kSCDynamicStoreDomainState, + kSCEntNetIPv6); + + if (!NetworkGlobalKeyDNS) + NetworkGlobalKeyDNS = + SCDynamicStoreKeyCreateNetworkGlobalEntity(kCFAllocatorDefault, + kSCDynamicStoreDomainState, + kSCEntNetDNS); + + if (!HostNamesKey) + HostNamesKey = SCDynamicStoreKeyCreateHostNames(kCFAllocatorDefault); + + if (!NetworkInterfaceKeyIPv4) + NetworkInterfaceKeyIPv4 = + SCDynamicStoreKeyCreateNetworkInterfaceEntity(kCFAllocatorDefault, + kSCDynamicStoreDomainState, + kSCCompAnyRegex, + kSCEntNetIPv4); + + if (!NetworkInterfaceKeyIPv6) + NetworkInterfaceKeyIPv6 = + SCDynamicStoreKeyCreateNetworkInterfaceEntity(kCFAllocatorDefault, + kSCDynamicStoreDomainState, + kSCCompAnyRegex, + kSCEntNetIPv6); + + if (store && ComputerNameKey && HostNamesKey && + NetworkGlobalKeyIPv4 && NetworkGlobalKeyIPv6 && NetworkGlobalKeyDNS && + NetworkInterfaceKeyIPv4 && NetworkInterfaceKeyIPv6) + { + key[0] = ComputerNameKey; + key[1] = BTMMKey; + key[2] = NetworkGlobalKeyIPv4; + key[3] = NetworkGlobalKeyIPv6; + key[4] = NetworkGlobalKeyDNS; + key[5] = HostNamesKey; + + pattern[0] = NetworkInterfaceKeyIPv4; + pattern[1] = NetworkInterfaceKeyIPv6; + + keys = CFArrayCreate(kCFAllocatorDefault, (const void **)key, + sizeof(key) / sizeof(key[0]), + &kCFTypeArrayCallBacks); + + patterns = CFArrayCreate(kCFAllocatorDefault, (const void **)pattern, + sizeof(pattern) / sizeof(pattern[0]), + &kCFTypeArrayCallBacks); + + if (keys && patterns && + SCDynamicStoreSetNotificationKeys(store, keys, patterns)) + { + if ((storeRLS = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, + store, 0)) != NULL) + { + CFRunLoopAddSource(CFRunLoopGetCurrent(), storeRLS, + kCFRunLoopDefaultMode); + } + else + DEBUG_printf(("sysEventThreadEntry: SCDynamicStoreCreateRunLoopSource " + "failed: %s\n", SCErrorString(SCError()))); + } + else + DEBUG_printf(("sysEventThreadEntry: SCDynamicStoreSetNotificationKeys " + "failed: %s\n", SCErrorString(SCError()))); + } + else + DEBUG_printf(("sysEventThreadEntry: SCDynamicStoreCreate failed: %s\n", + SCErrorString(SCError()))); + + if (keys) + CFRelease(keys); + + if (patterns) + CFRelease(patterns); + + /* + * Set up a timer to delay the wake change notifications. + * + * The initial time is set a decade or so into the future, we'll adjust + * this later. + */ + + bzero(&timerContext, sizeof(timerContext)); + timerContext.info = &threadData; + + threadData.timerRef = + CFRunLoopTimerCreate(kCFAllocatorDefault, + CFAbsoluteTimeGetCurrent() + (86400L * 365L * 10L), + 86400L * 365L * 10L, 0, 0, sysEventTimerNotifier, + &timerContext); + CFRunLoopAddTimer(CFRunLoopGetCurrent(), threadData.timerRef, + kCFRunLoopDefaultMode); + + /* + * Store our runloop in a global so the main thread can use it to stop us. + */ + + pthread_mutex_lock(&SysEventThreadMutex); + + SysEventRunloop = CFRunLoopGetCurrent(); + + pthread_cond_signal(&SysEventThreadCond); + pthread_mutex_unlock(&SysEventThreadMutex); + + /* + * Disappear into the runloop until it's stopped by the main thread. + */ + + CFRunLoopRun(); + + /* + * Clean up before exiting. + */ + + if (threadData.timerRef) + { + CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), threadData.timerRef, + kCFRunLoopDefaultMode); + CFRelease(threadData.timerRef); + } + + if (threadData.sysevent.powerKernelPort) + { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), powerRLS, + kCFRunLoopDefaultMode); + IODeregisterForSystemPower(&powerNotifierObj); + IOServiceClose(threadData.sysevent.powerKernelPort); + IONotificationPortDestroy(powerNotifierPort); + } + + if (storeRLS) + { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), storeRLS, + kCFRunLoopDefaultMode); + CFRunLoopSourceInvalidate(storeRLS); + CFRelease(storeRLS); + } + + if (store) + CFRelease(store); + + pthread_exit(NULL); +} + + +/* + * 'sysEventPowerNotifier()' - Handle power notification events. + */ + +static void +sysEventPowerNotifier( + void *context, /* I - Thread context data */ + io_service_t service, /* I - Unused service info */ + natural_t messageType, /* I - Type of message */ + void *messageArgument) /* I - Message data */ +{ + int sendit = 1; /* Send event to main thread? * + * (0 = no, 1 = yes, 2 = delayed */ + cupsd_thread_data_t *threadData; /* Thread context data */ + + + threadData = (cupsd_thread_data_t *)context; + + (void)service; /* anti-compiler-warning-code */ + + switch (messageType) + { + case kIOMessageCanSystemPowerOff: + case kIOMessageCanSystemSleep: + threadData->sysevent.event |= SYSEVENT_CANSLEEP; + break; + + case kIOMessageSystemWillRestart: + case kIOMessageSystemWillPowerOff: + case kIOMessageSystemWillSleep: + threadData->sysevent.event |= SYSEVENT_WILLSLEEP; + break; + + case kIOMessageSystemHasPoweredOn: + /* + * Because powered on is followed by a net-changed event, delay + * before sending it. + */ + + sendit = 2; + threadData->sysevent.event |= SYSEVENT_WOKE; + break; + + case kIOMessageSystemWillNotPowerOff: + case kIOMessageSystemWillNotSleep: +# ifdef kIOMessageSystemWillPowerOn + case kIOMessageSystemWillPowerOn: +# endif /* kIOMessageSystemWillPowerOn */ + default: + sendit = 0; + break; + } + + if (sendit == 0) + IOAllowPowerChange(threadData->sysevent.powerKernelPort, + (long)messageArgument); + else + { + threadData->sysevent.powerNotificationID = (long)messageArgument; + + if (sendit == 1) + { + /* + * Send the event to the main thread now. + */ + + write(SysEventPipes[1], &threadData->sysevent, + sizeof(threadData->sysevent)); + threadData->sysevent.event = 0; + } + else + { + /* + * Send the event to the main thread after 1 to 2 seconds. + */ + + CFRunLoopTimerSetNextFireDate(threadData->timerRef, + CFAbsoluteTimeGetCurrent() + 2); + } + } +} + + +/* + * 'sysEventConfigurationNotifier()' - Network configuration change notification + * callback. + */ + +static void +sysEventConfigurationNotifier( + SCDynamicStoreRef store, /* I - System data (unused) */ + CFArrayRef changedKeys, /* I - Changed data */ + void *context) /* I - Thread context data */ +{ + cupsd_thread_data_t *threadData; /* Thread context data */ + + + threadData = (cupsd_thread_data_t *)context; + + (void)store; /* anti-compiler-warning-code */ + + CFRange range = CFRangeMake(0, CFArrayGetCount(changedKeys)); + + if (CFArrayContainsValue(changedKeys, range, ComputerNameKey) || + CFArrayContainsValue(changedKeys, range, BTMMKey)) + threadData->sysevent.event |= SYSEVENT_NAMECHANGED; + else + { + threadData->sysevent.event |= SYSEVENT_NETCHANGED; + + /* + * Indicate the network interface list needs updating... + */ + + NetIFUpdate = 1; + } + + /* + * Because we registered for several different kinds of change notifications + * this callback usually gets called several times in a row. We use a timer to + * de-bounce these so we only end up generating one event for the main thread. + */ + + CFRunLoopTimerSetNextFireDate(threadData->timerRef, + CFAbsoluteTimeGetCurrent() + 5); +} + + +/* + * 'sysEventTimerNotifier()' - Handle delayed event notifications. + */ + +static void +sysEventTimerNotifier( + CFRunLoopTimerRef timer, /* I - Timer information */ + void *context) /* I - Thread context data */ +{ + cupsd_thread_data_t *threadData; /* Thread context data */ + + + threadData = (cupsd_thread_data_t *)context; + + /* + * If an event is still pending send it to the main thread. + */ + + if (threadData->sysevent.event) + { + write(SysEventPipes[1], &threadData->sysevent, + sizeof(threadData->sysevent)); + threadData->sysevent.event = 0; + } +} + + +/* + * 'sysUpdate()' - Update the current system state. + */ + +static void +sysUpdate(void) +{ + int i; /* Looping var */ + cupsd_sysevent_t sysevent; /* The system event */ + cupsd_printer_t *p; /* Printer information */ + + + /* + * Drain the event pipe... + */ + + while (read((int)SysEventPipes[0], &sysevent, sizeof(sysevent)) + == sizeof(sysevent)) + { + if (sysevent.event & SYSEVENT_CANSLEEP) + { + /* + * If there are active printers that don't have the connecting-to-device + * printer-state-reason then cancel the sleep request (i.e. this reason + * indicates a job that is not yet connected to the printer)... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + if (p->job) + { + for (i = 0; i < p->num_reasons; i ++) + if (!strcmp(p->reasons[i], "connecting-to-device")) + break; + + if (!p->num_reasons || i >= p->num_reasons) + break; + } + } + + if (p) + { + cupsdLogMessage(CUPSD_LOG_INFO, + "System sleep canceled because printer %s is active", + p->name); + IOCancelPowerChange(sysevent.powerKernelPort, + sysevent.powerNotificationID); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "System wants to sleep"); + IOAllowPowerChange(sysevent.powerKernelPort, + sysevent.powerNotificationID); + } + } + + if (sysevent.event & SYSEVENT_WILLSLEEP) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "System going to sleep"); + + Sleeping = 1; + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + if (p->type & CUPS_PRINTER_DISCOVERED) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Deleting remote destination \"%s\"", p->name); + cupsArraySave(Printers); + cupsdDeletePrinter(p, 0); + cupsArrayRestore(Printers); + } + else + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Deregistering local printer \"%s\"", p->name); + cupsdDeregisterPrinter(p, 0); + } + } + + cupsdCleanDirty(); + + /* + * If we have no printing jobs, allow the power change immediately. + * Otherwise set the SleepJobs time to 15 seconds in the future when + * we'll take more drastic measures... + */ + + if (cupsArrayCount(PrintingJobs) == 0) + IOAllowPowerChange(sysevent.powerKernelPort, + sysevent.powerNotificationID); + else + { + LastSysEvent = sysevent; + SleepJobs = time(NULL) + 15; + } + } + + if (sysevent.event & SYSEVENT_WOKE) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, "System woke from sleep"); + IOAllowPowerChange(sysevent.powerKernelPort, + sysevent.powerNotificationID); + Sleeping = 0; + cupsdCheckJobs(); + } + + if (sysevent.event & SYSEVENT_NETCHANGED) + { + if (!Sleeping) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "System network configuration changed"); + + /* + * Resetting browse_time before calling cupsdSendBrowseList causes + * browse packets to be sent for local shared printers. + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + p->browse_time = 0; + + cupsdSendBrowseList(); + cupsdRestartPolling(); + } + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "System network configuration changed; " + "ignored while sleeping"); + } + + if (sysevent.event & SYSEVENT_NAMECHANGED) + { + if (!Sleeping) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Computer name or BTMM domains changed"); + + /* + * De-register the individual printers... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + cupsdDeregisterPrinter(p, 1); + + /* + * Update the computer name and BTMM domain list... + */ + + cupsdUpdateDNSSDName(); + + /* + * Now re-register them... + */ + + for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); + p; + p = (cupsd_printer_t *)cupsArrayNext(Printers)) + { + p->browse_time = 0; + cupsdRegisterPrinter(p); + } + } + else + cupsdLogMessage(CUPSD_LOG_DEBUG, + "Computer name or BTMM domains changed; ignored while " + "sleeping"); + } + } +} +#endif /* __APPLE__ */ + + +/* + * End of "$Id$". + */ diff --git a/scheduler/sysman.h b/scheduler/sysman.h new file mode 100644 index 0000000000..7cda2e8647 --- /dev/null +++ b/scheduler/sysman.h @@ -0,0 +1,64 @@ +/* + * "$Id$" + * + * System management definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Constants... + */ + +#define CUPSD_DIRTY_NONE 0 /* Nothing is dirty */ +#define CUPSD_DIRTY_PRINTERS 1 /* printers.conf is dirty */ +#define CUPSD_DIRTY_CLASSES 2 /* classes.conf is dirty */ +#define CUPSD_DIRTY_REMOTE 4 /* remote.cache is dirty */ +#define CUPSD_DIRTY_PRINTCAP 8 /* printcap is dirty */ +#define CUPSD_DIRTY_JOBS 16 /* jobs.cache or "c" file(s) are dirty */ +#define CUPSD_DIRTY_SUBSCRIPTIONS 32 /* subscriptions.conf is dirty */ + +/* + * Globals... + */ + +VAR int DirtyFiles VALUE(CUPSD_DIRTY_NONE), + /* What files are dirty? */ + DirtyCleanInterval VALUE(DEFAULT_KEEPALIVE); + /* How often do we write dirty files? */ +VAR time_t DirtyCleanTime VALUE(0); + /* When to clean dirty files next */ +VAR int Sleeping VALUE(0); + /* Non-zero if machine is entering or * + * in a sleep state... */ +VAR time_t SleepJobs VALUE(0); + /* Time when all jobs must be * + * canceled for system sleep. */ +#ifdef __APPLE__ +VAR int SysEventPipes[2] VALUE2(-1,-1); + /* System event notification pipes */ +#endif /* __APPLE__ */ + + +/* + * Prototypes... + */ + +extern void cupsdAllowSleep(void); +extern void cupsdCleanDirty(void); +extern void cupsdMarkDirty(int what); +extern void cupsdSetBusyState(void); +extern void cupsdStartSystemMonitor(void); +extern void cupsdStopSystemMonitor(void); + + +/* + * End of "$Id$". + */ diff --git a/scheduler/testdirsvc.c b/scheduler/testdirsvc.c new file mode 100644 index 0000000000..48e4002ff2 --- /dev/null +++ b/scheduler/testdirsvc.c @@ -0,0 +1,326 @@ +/* + * "$Id$" + * + * Browsing test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Simulate one or more remote printers. + * usage() - Show program usage... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void usage(void); + + +/* + * 'main()' - Simulate one or more remote printers. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, /* Looping var */ + printer, /* Current printer */ + num_printers, /* Number of printers */ + pclass, /* Current printer class */ + num_pclasses, /* Number of printer classes */ + server, /* Current server */ + num_servers, /* Number of servers */ + count, /* Number of printers sent this cycle */ + interval, /* Browse Interval */ + lease, /* Browse lease-duration */ + continuous, /* Run continuously? */ + port, /* Browse port */ + sock, /* Browse socket */ + val, /* Socket option value */ + seconds, /* Seconds until next cycle */ + verbose; /* Verbose output? */ + const char *options; /* Options for URIs */ + time_t curtime; /* Current UNIX time */ + struct tm *curdate; /* Current date and time */ + struct sockaddr_in addr; /* Broadcast address */ + char packet[1540]; /* Data packet */ + static const char * const names[26] = /* Printer names */ + { + "alpha", + "bravo", + "charlie", + "delta", + "echo", + "foxtrot", + "golf", + "hotel", + "india", + "juliet", + "kilo", + "lima", + "mike", + "november", + "oscar", + "papa", + "quebec", + "romeo", + "sierra", + "tango", + "uniform", + "victor", + "wiskey", + "x-ray", + "yankee", + "zulu" + }; + + + /* + * Process command-line arguments... + */ + + num_printers = 10; + num_pclasses = 5; + num_servers = 1; + interval = 30; + lease = 60; + port = 0; + verbose = 0; + continuous = 0; + options = NULL; + + for (i = 1; i < argc; i ++) + { + if (!strcmp(argv[i], "-c")) + continuous = 1; + else if (!strcmp(argv[i], "-i")) + { + i ++; + if (i < argc) + interval = atoi(argv[i]); + else + usage(); + + continuous = 1; + } + else if (!strcmp(argv[i], "-l")) + { + i ++; + if (i < argc) + lease = atoi(argv[i]); + else + usage(); + } + else if (!strcmp(argv[i], "-o")) + { + i ++; + if (i < argc) + options = argv[i]; + else + usage(); + } + else if (!strcmp(argv[i], "-C")) + { + i ++; + if (i < argc) + num_pclasses = atoi(argv[i]); + else + usage(); + } + else if (!strcmp(argv[i], "-p")) + { + i ++; + if (i < argc) + num_printers = atoi(argv[i]); + else + usage(); + } + else if (!strcmp(argv[i], "-s")) + { + i ++; + if (i < argc) + num_servers = atoi(argv[i]); + else + usage(); + } + else if (!strcmp(argv[i], "-v")) + verbose = 1; + else if (isdigit(argv[i][0] & 255)) + { + port = atoi(argv[i]); + } + else + usage(); + } + + if ((num_printers <= 0 && num_pclasses <= 0) || num_servers <= 0 || + interval <= 0 || lease < 1 || port <= 0) + usage(); + + /* + * Open a broadcast socket... + */ + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + perror("Unable to open broadcast socket"); + return (1); + } + + /* + * Set the "broadcast" flag... + */ + + val = 1; + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) + { + perror("Unable to put socket in broadcast mode"); + + close(sock); + return (1); + } + + /* + * 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); + + /* + * Send virtual printers continuously until we are stopped. + */ + + for (;;) + { + /* + * Start a new cycle of N printers... + */ + + printf("Sending %d printers from %d servers...\n", num_printers, + num_servers); + + count = num_servers * (num_printers + num_pclasses) / interval + 1; + curtime = time(NULL); + curdate = localtime(&curtime); + seconds = interval; + + for (i = 0, printer = 0; printer < num_printers; printer ++) + { + for (server = 0; server < num_servers; server ++, i ++) + { + if (i == count) + { + seconds --; + i = 0; + sleep(1); + curtime = time(NULL); + curdate = localtime(&curtime); + } + + snprintf(packet, sizeof(packet), + "%x %x ipp://testserver-%d/printers/%s-%d \"Server Room %d\" " + "\"Test Printer %d\" \"Acme Blazer 2000\"%s%s " + "lease-duration=%d\n", + CUPS_PRINTER_REMOTE, IPP_PRINTER_IDLE, server + 1, + names[printer % 26], printer / 26 + 1, server + 1, + printer + 1, options ? " ipp-options=" : "", + options ? options : "", lease); + + if (verbose) + printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min, + curdate->tm_sec, packet); + + if (sendto(sock, packet, strlen(packet), 0, + (struct sockaddr *)&addr, sizeof(addr)) < 0) + perror("Unabled to send packet"); + } + } + + + for (i = 0, pclass = 0; pclass < num_pclasses; pclass ++) + { + for (server = 0; server < num_servers; server ++, i ++) + { + if (i == count) + { + seconds --; + i = 0; + sleep(1); + curtime = time(NULL); + curdate = localtime(&curtime); + } + + snprintf(packet, sizeof(packet), + "%x %x ipp://testserver-%d/classes/class-%s-%d \"Server Room %d\" " + "\"Test Class %d\" \"Acme Blazer 2000\"%s%s " + "lease-duration=%d\n", + CUPS_PRINTER_REMOTE | CUPS_PRINTER_CLASS, IPP_PRINTER_IDLE, + server + 1, names[pclass % 26], pclass / 26 + 1, server + 1, + pclass + 1, options ? " ipp-options=" : "", + options ? options : "", lease); + + if (verbose) + printf("[%02d:%02d:%02d] %s", curdate->tm_hour, curdate->tm_min, + curdate->tm_sec, packet); + + if (sendto(sock, packet, strlen(packet), 0, + (struct sockaddr *)&addr, sizeof(addr)) < 0) + perror("Unabled to send packet"); + } + } + + if (!continuous) + break; + + /* + * Sleep for any remaining time... + */ + + if (seconds > 0) + sleep(seconds); + } + + return (0); +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(void) +{ + puts("Usage: testdirsvc [-c] [-i interval] [-l lease-duration] " + "[-o ipp-options] [-p printers] " + "[-C classes] [-s servers] [-v] port"); + exit(0); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/testlpd.c b/scheduler/testlpd.c new file mode 100644 index 0000000000..5b16921bf6 --- /dev/null +++ b/scheduler/testlpd.c @@ -0,0 +1,552 @@ +/* + * "$Id$" + * + * cups-lpd test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Simulate an LPD client. + * do_command() - Send the LPD command and wait for a response. + * print_job() - Submit a file for printing. + * print_waiting() - Print waiting jobs. + * remove_job() - Cancel a print job. + * status_long() - Show the long printer status. + * status_short() - Show the short printer status. + * usage() - Show program usage... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int do_command(int outfd, int infd, const char *command); +static int print_job(int outfd, int infd, char *dest, char **args); +static int print_waiting(int outfd, int infd, char *dest); +static int remove_job(int outfd, int infd, char *dest, char **args); +static int status_long(int outfd, int infd, char *dest, char **args); +static int status_short(int outfd, int infd, char *dest, char **args); +static void usage(void); + + +/* + * 'main()' - Simulate an LPD client. + */ + +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; /* Test status */ + char *op, /* Operation to test */ + **opargs, /* Remaining arguments */ + *dest; /* Destination */ + int cupslpd_argc; /* Argument count for cups-lpd */ + char *cupslpd_argv[1000]; /* Arguments for cups-lpd */ + int cupslpd_stdin[2], /* Standard input for cups-lpd */ + cupslpd_stdout[2], /* Standard output for cups-lpd */ + cupslpd_pid, /* Process ID for cups-lpd */ + cupslpd_status; /* Status of cups-lpd process */ + + + /* + * Collect command-line arguments... + */ + + op = NULL; + opargs = NULL; + dest = NULL; + cupslpd_argc = 1; + cupslpd_argv[0] = (char *)"cups-lpd"; + + for (i = 1; i < argc; i ++) + if (!strncmp(argv[i], "-o", 2)) + { + cupslpd_argv[cupslpd_argc++] = argv[i]; + + if (!argv[i][2]) + { + i ++; + + if (i >= argc) + usage(); + + cupslpd_argv[cupslpd_argc++] = argv[i]; + } + } + else if (argv[i][0] == '-') + usage(); + else if (!op) + op = argv[i]; + else if (!dest) + dest = argv[i]; + else + { + opargs = argv + i; + break; + } + + if (!op || + (!strcmp(op, "print-job") && (!dest || !opargs)) || + (!strcmp(op, "remove-job") && (!dest || !opargs)) || + (strcmp(op, "print-job") && strcmp(op, "print-waiting") && + strcmp(op, "remove-job") && strcmp(op, "status-long") && + strcmp(op, "status-short"))) + { + printf("op=\"%s\", dest=\"%s\", opargs=%p\n", op, dest, opargs); + usage(); + } + + /* + * Run the cups-lpd program using pipes... + */ + + cupslpd_argv[cupslpd_argc] = NULL; + + pipe(cupslpd_stdin); + pipe(cupslpd_stdout); + + if ((cupslpd_pid = fork()) < 0) + { + /* + * Error! + */ + + perror("testlpd: Unable to fork"); + return (1); + } + else if (cupslpd_pid == 0) + { + /* + * Child goes here... + */ + + dup2(cupslpd_stdin[0], 0); + close(cupslpd_stdin[0]); + close(cupslpd_stdin[1]); + + dup2(cupslpd_stdout[1], 1); + close(cupslpd_stdout[0]); + close(cupslpd_stdout[1]); + + execv("./cups-lpd", cupslpd_argv); + + perror("testlpd: Unable to exec ./cups-lpd"); + exit(errno); + } + else + { + close(cupslpd_stdin[0]); + close(cupslpd_stdout[1]); + } + + /* + * Do the operation test... + */ + + if (!strcmp(op, "print-job")) + status = print_job(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs); + else if (!strcmp(op, "print-waiting")) + status = print_waiting(cupslpd_stdin[1], cupslpd_stdout[0], dest); + else if (!strcmp(op, "remove-job")) + status = remove_job(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs); + else if (!strcmp(op, "status-long")) + status = status_long(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs); + else if (!strcmp(op, "status-short")) + status = status_short(cupslpd_stdin[1], cupslpd_stdout[0], dest, opargs); + else + { + printf("Unknown operation \"%s\"!\n", op); + status = 1; + } + + /* + * Kill the test program... + */ + + close(cupslpd_stdin[1]); + close(cupslpd_stdout[0]); + + while (wait(&cupslpd_status) != cupslpd_pid); + + printf("cups-lpd exit status was %d...\n", cupslpd_status); + + /* + * Return the test status... + */ + + return (status); +} + + +/* + * 'do_command()' - Send the LPD command and wait for a response. + */ + +static int /* O - Status from cups-lpd */ +do_command(int outfd, /* I - Command file descriptor */ + int infd, /* I - Response file descriptor */ + const char *command) /* I - Command line to send */ +{ + int len; /* Length of command line */ + char status; /* Status byte */ + + + printf("COMMAND: %02X %s", command[0], command + 1); + + len = strlen(command); + + if (write(outfd, command, len) < len) + { + puts(" Write failed!"); + return (-1); + } + + if (read(infd, &status, 1) < 1) + puts("STATUS: ERROR"); + else + printf("STATUS: %d\n", status); + + return (status); +} + + +/* + * 'print_job()' - Submit a file for printing. + */ + +static int /* O - Status from cups-lpd */ +print_job(int outfd, /* I - Command file descriptor */ + int infd, /* I - Response file descriptor */ + char *dest, /* I - Destination */ + char **args) /* I - Arguments */ +{ + int fd; /* Print file descriptor */ + char command[1024], /* Command buffer */ + control[1024], /* Control file */ + buffer[8192]; /* Print buffer */ + int status; /* Status of command */ + struct stat fileinfo; /* File information */ + char *jobname; /* Job name */ + int sequence; /* Sequence number */ + int bytes; /* Bytes read/written */ + + + /* + * Check the print file... + */ + + if (stat(args[0], &fileinfo)) + { + perror(args[0]); + return (-1); + } + + if ((fd = open(args[0], O_RDONLY)) < 0) + { + perror(args[0]); + return (-1); + } + + /* + * Send the "receive print job" command... + */ + + snprintf(command, sizeof(command), "\002%s\n", dest); + if ((status = do_command(outfd, infd, command)) != 0) + { + close(fd); + return (status); + } + + /* + * Format a control file string that will be used to submit the job... + */ + + if ((jobname = strrchr(args[0], '/')) != NULL) + jobname ++; + else + jobname = args[0]; + + sequence = (int)getpid() % 1000; + + snprintf(control, sizeof(control), + "Hlocalhost\n" + "P%s\n" + "J%s\n" + "ldfA%03dlocalhost\n" + "UdfA%03dlocalhost\n" + "N%s\n", + cupsUser(), jobname, sequence, sequence, jobname); + + /* + * Send the control file... + */ + + bytes = strlen(control); + + snprintf(command, sizeof(command), "\002%d cfA%03dlocalhost\n", + bytes, sequence); + + if ((status = do_command(outfd, infd, command)) != 0) + { + close(fd); + return (status); + } + + bytes ++; + + if (write(outfd, control, bytes) < bytes) + { + printf("CONTROL: Unable to write %d bytes!\n", bytes); + close(fd); + return (-1); + } + + printf("CONTROL: Wrote %d bytes.\n", bytes); + + if (read(infd, command, 1) < 1) + { + puts("STATUS: ERROR"); + close(fd); + return (-1); + } + else + { + status = command[0]; + + printf("STATUS: %d\n", status); + } + + /* + * Send the data file... + */ + + snprintf(command, sizeof(command), "\003%d dfA%03dlocalhost\n", + (int)fileinfo.st_size, sequence); + + if ((status = do_command(outfd, infd, command)) != 0) + { + close(fd); + return (status); + } + + while ((bytes = read(fd, buffer, sizeof(buffer))) > 0) + { + if (write(outfd, buffer, bytes) < bytes) + { + printf("DATA: Unable to write %d bytes!\n", bytes); + close(fd); + return (-1); + } + } + + write(outfd, "", 1); + + close(fd); + + printf("DATA: Wrote %d bytes.\n", (int)fileinfo.st_size); + + if (read(infd, command, 1) < 1) + { + puts("STATUS: ERROR"); + close(fd); + return (-1); + } + else + { + status = command[0]; + + printf("STATUS: %d\n", status); + } + + return (status); +} + + +/* + * 'print_waiting()' - Print waiting jobs. + */ + +static int /* O - Status from cups-lpd */ +print_waiting(int outfd, /* I - Command file descriptor */ + int infd, /* I - Response file descriptor */ + char *dest) /* I - Destination */ +{ + char command[1024]; /* Command buffer */ + + + /* + * Send the "print waiting jobs" command... + */ + + snprintf(command, sizeof(command), "\001%s\n", dest); + + return (do_command(outfd, infd, command)); +} + + +/* + * 'remove_job()' - Cancel a print job. + */ + +static int /* O - Status from cups-lpd */ +remove_job(int outfd, /* I - Command file descriptor */ + int infd, /* I - Response file descriptor */ + char *dest, /* I - Destination */ + char **args) /* I - Arguments */ +{ + int i; /* Looping var */ + char command[1024]; /* Command buffer */ + + /* + * Send the "remove jobs" command... + */ + + snprintf(command, sizeof(command), "\005%s", dest); + + for (i = 0; args[i]; i ++) + { + strlcat(command, " ", sizeof(command)); + strlcat(command, args[i], sizeof(command)); + } + + strlcat(command, "\n", sizeof(command)); + + return (do_command(outfd, infd, command)); +} + + +/* + * 'status_long()' - Show the long printer status. + */ + +static int /* O - Status from cups-lpd */ +status_long(int outfd, /* I - Command file descriptor */ + int infd, /* I - Response file descriptor */ + char *dest, /* I - Destination */ + char **args) /* I - Arguments */ +{ + char command[1024], /* Command buffer */ + buffer[8192]; /* Status buffer */ + int bytes; /* Bytes read/written */ + + + /* + * Send the "send short status" command... + */ + + if (args) + snprintf(command, sizeof(command), "\004%s %s\n", dest, args[0]); + else + snprintf(command, sizeof(command), "\004%s\n", dest); + + bytes = strlen(command); + + if (write(outfd, command, bytes) < bytes) + return (-1); + + /* + * Read the status back... + */ + + while ((bytes = read(infd, buffer, sizeof(buffer))) > 0) + { + fwrite(buffer, 1, bytes, stdout); + fflush(stdout); + } + + return (0); +} + + +/* + * 'status_short()' - Show the short printer status. + */ + +static int /* O - Status from cups-lpd */ +status_short(int outfd, /* I - Command file descriptor */ + int infd, /* I - Response file descriptor */ + char *dest, /* I - Destination */ + char **args) /* I - Arguments */ +{ + char command[1024], /* Command buffer */ + buffer[8192]; /* Status buffer */ + int bytes; /* Bytes read/written */ + + + /* + * Send the "send short status" command... + */ + + if (args) + snprintf(command, sizeof(command), "\003%s %s\n", dest, args[0]); + else + snprintf(command, sizeof(command), "\003%s\n", dest); + + bytes = strlen(command); + + if (write(outfd, command, bytes) < bytes) + return (-1); + + /* + * Read the status back... + */ + + while ((bytes = read(infd, buffer, sizeof(buffer))) > 0) + { + fwrite(buffer, 1, bytes, stdout); + fflush(stdout); + } + + return (0); +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(void) +{ + puts("Usage: testlpd [options] print-job printer filename [... filename]"); + puts(" testlpd [options] print-waiting [printer or user]"); + puts(" testlpd [options] remove-job printer [user [job-id]]"); + puts(" testlpd [options] status-long [printer or user]"); + puts(" testlpd [options] status-short [printer or user]"); + puts(""); + puts("Options:"); + puts(" -o name=value"); + + exit(0); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/testmime.c b/scheduler/testmime.c new file mode 100644 index 0000000000..7bfd65060a --- /dev/null +++ b/scheduler/testmime.c @@ -0,0 +1,326 @@ +/* + * "$Id$" + * + * MIME test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for the test program. + * print_rules() - Print the rules for a file type... + * type_dir() - Show the MIME types for a given directory. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include "mime.h" +#include + + +/* + * Local functions... + */ + +static void print_rules(mime_magic_t *rules); +static void type_dir(mime_t *mime, const char *dirname); + + +/* + * '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 vars */ + const char *filter_path; /* Filter path */ + char super[MIME_MAX_SUPER], /* Super-type name */ + type[MIME_MAX_TYPE]; /* Type name */ + int compression; /* Compression of file */ + int cost; /* Cost of filters */ + mime_t *mime; /* MIME database */ + mime_type_t *src, /* Source type */ + *dst; /* Destination type */ + cups_array_t *filters; /* Filters for the file */ + mime_filter_t *filter; /* Current filter */ + + + mime = NULL; + src = NULL; + dst = NULL; + filter_path = "../filter:../pdftops:" CUPS_SERVERBIN "/filter"; + + for (i = 1; i < argc; i ++) + if (!strcmp(argv[i], "-d")) + { + i ++; + + if (i < argc) + mime = mimeLoad(argv[i], filter_path); + } + else if (!strcmp(argv[i], "-f")) + { + i ++; + + if (i < argc) + filter_path = argv[i]; + } + else if (!src) + { + if (!mime) + mime = mimeLoad("../conf", filter_path); + + src = mimeFileType(mime, argv[i], NULL, &compression); + + if (src) + printf("%s: %s/%s%s\n", argv[i], src->super, src->type, + compression ? " (gzipped)" : ""); + else if ((src = mimeType(mime, "application", "octet-stream")) != NULL) + printf("%s: application/octet-stream\n", argv[i]); + 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, &cost); + + if (!filters) + { + printf("No filters to convert from %s/%s to %s.\n", src->super, + src->type, argv[i]); + } + else + { + printf("Filter cost = %d\n", cost); + + filter = (mime_filter_t *)cupsArrayFirst(filters); + fputs(filter->filter, stdout); + + for (filter = (mime_filter_t *)cupsArrayNext(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + printf(" | %s", filter->filter); + + putchar('\n'); + + cupsArrayDelete(filters); + } + } + + if (!mime) + mime = mimeLoad("../conf", filter_path); + + if (!src) + { + puts("MIME database types:"); + for (src = mimeFirstType(mime); src; src = mimeNextType(mime)) + { + printf("\t%s/%s (%d):\n", src->super, src->type, src->priority); + print_rules(src->rules); + puts(""); + } + + puts(""); + + puts("MIME database filters:"); + for (filter = mimeFirstFilter(mime); filter; filter = mimeNextFilter(mime)) + printf("\t%s/%s to %s/%s: %s (%d)\n", + filter->src->super, filter->src->type, + filter->dst->super, filter->dst->type, + filter->filter, filter->cost); + + type_dir(mime, "../doc"); + type_dir(mime, "../man"); + } + + 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; + } +} + + +/* + * 'type_dir()' - Show the MIME types for a given directory. + */ + +static void +type_dir(mime_t *mime, /* I - MIME database */ + const char *dirname) /* I - Directory */ +{ + cups_dir_t *dir; /* Directory */ + cups_dentry_t *dent; /* Directory entry */ + char filename[1024]; /* File to type */ + mime_type_t *filetype; /* File type */ + int compression; /* Compressed file? */ + mime_type_t *pstype; /* application/vnd.cups-postscript */ + cups_array_t *filters; /* Filters to pstype */ + mime_filter_t *filter; /* Current filter */ + int cost; /* Filter cost */ + + + dir = cupsDirOpen(dirname); + if (!dir) + return; + + pstype = mimeType(mime, "application", "vnd.cups-postscript"); + + while ((dent = cupsDirRead(dir)) != NULL) + { + if (dent->filename[0] == '.') + continue; + + snprintf(filename, sizeof(filename), "%s/%s", dirname, dent->filename); + + if (S_ISDIR(dent->fileinfo.st_mode)) + type_dir(mime, filename); + + if (!S_ISREG(dent->fileinfo.st_mode)) + continue; + + filetype = mimeFileType(mime, filename, NULL, &compression); + + if (filetype) + { + printf("%s: %s/%s%s\n", filename, filetype->super, filetype->type, + compression ? " (compressed)" : ""); + + filters = mimeFilter(mime, filetype, pstype, &cost); + + if (!filters) + puts(" No filters to convert application/vnd.cups-postscript."); + else + { + printf(" Filter cost = %d\n", cost); + + filter = (mime_filter_t *)cupsArrayFirst(filters); + printf(" %s", filter->filter); + + for (filter = (mime_filter_t *)cupsArrayNext(filters); + filter; + filter = (mime_filter_t *)cupsArrayNext(filters)) + printf(" | %s", filter->filter); + + putchar('\n'); + + cupsArrayDelete(filters); + } + } + else + printf("%s: unknown%s\n", filename, compression ? " (compressed)" : ""); + } + + cupsDirClose(dir); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/testspeed.c b/scheduler/testspeed.c new file mode 100644 index 0000000000..0da9c825f2 --- /dev/null +++ b/scheduler/testspeed.c @@ -0,0 +1,366 @@ +/* + * "$Id$" + * + * Scheduler speed test for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Send multiple IPP requests and report on the average response + * time. + * do_test() - Run a test on a specific host... + * usage() - Show program usage... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int do_test(const char *server, int port, + http_encryption_t encryption, int requests, + int verbose); +static void usage(void); + + +/* + * '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 */ + char *server, /* Server to use */ + *ptr; /* Pointer to port in server */ + int port; /* Port to use */ + http_encryption_t encryption; /* Encryption to use */ + int requests; /* Number of requests to send */ + int children; /* Number of children to fork */ + int good_children; /* Number of children that exited normally */ + int pid; /* Child PID */ + int status; /* Child status */ + time_t start, /* Start time */ + end; /* End time */ + double elapsed; /* Elapsed time */ + int verbose; /* Verbosity */ + + + /* + * Parse command-line options... + */ + + requests = 100; + children = 5; + server = (char *)cupsServer(); + port = ippPort(); + encryption = HTTP_ENCRYPT_IF_REQUESTED; + verbose = 0; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + { + for (ptr = argv[i] + 1; *ptr; ptr ++) + switch (*ptr) + { + case 'c' : /* Number of children */ + i ++; + if (i >= argc) + usage(); + + children = atoi(argv[i]); + break; + + case 'r' : /* Number of requests */ + i ++; + if (i >= argc) + usage(); + + requests = atoi(argv[i]); + break; + + case 'E' : /* Enable encryption */ + encryption = HTTP_ENCRYPT_REQUIRED; + break; + + case 'v' : /* Verbose logging */ + verbose ++; + break; + + default : + usage(); + break; + } + } + else + { + server = argv[i]; + + if (server[0] != '/' && (ptr = strrchr(server, ':')) != NULL) + { + *ptr++ = '\0'; + port = atoi(ptr); + } + } + + /* + * Then create child processes to act as clients... + */ + + if (children > 0) + { + printf("testspeed: Simulating %d clients with %d requests to %s with " + "%sencryption...\n", children, requests, server, + encryption == HTTP_ENCRYPT_IF_REQUESTED ? "no " : ""); + } + + start = time(NULL); + + if (children < 1) + return (do_test(server, port, encryption, requests, verbose)); + else if (children == 1) + good_children = do_test(server, port, encryption, requests, verbose) ? 0 : 1; + else + { + char options[255], /* Command-line options for child */ + reqstr[255], /* Requests string for child */ + serverstr[255]; /* Server:port string for child */ + + + snprintf(reqstr, sizeof(reqstr), "%d", requests); + + if (port == 631 || server[0] == '/') + strlcpy(serverstr, server, sizeof(serverstr)); + else + snprintf(serverstr, sizeof(serverstr), "%s:%d", server, port); + + strlcpy(options, "-cr", sizeof(options)); + + if (encryption == HTTP_ENCRYPT_REQUIRED) + strlcat(options, "E", sizeof(options)); + + if (verbose) + strlcat(options, "v", sizeof(options)); + + for (i = 0; i < children; i ++) + { + fflush(stdout); + + if ((pid = fork()) == 0) + { + /* + * Child goes here... + */ + + execlp(argv[0], argv[0], options, "0", reqstr, serverstr, (char *)NULL); + exit(errno); + } + else if (pid < 0) + { + printf("testspeed: Fork failed: %s\n", strerror(errno)); + break; + } + else + printf("testspeed: Started child %d...\n", pid); + } + + /* + * Wait for children to finish... + */ + + puts("testspeed: Waiting for children to finish..."); + + for (good_children = 0;;) + { + pid = wait(&status); + + if (pid < 0 && errno != EINTR) + break; + + printf("testspeed: Ended child %d (%d)...\n", pid, status / 256); + + if (!status) + good_children ++; + } + } + + /* + * Compute the total run time... + */ + + if (good_children > 0) + { + end = time(NULL); + elapsed = end - start; + i = good_children * requests; + + printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n", + good_children, requests, i, elapsed, elapsed / i, i / elapsed); + } + + /* + * Exit with no errors... + */ + + return (0); +} + + +/* + * 'do_test()' - Run a test on a specific host... + */ + +static int /* O - Exit status */ +do_test(const char *server, /* I - Server to use */ + int port, /* I - Port number to use */ + http_encryption_t encryption, /* I - Encryption to use */ + int requests, /* I - Number of requests to send */ + int verbose) /* I - Verbose output? */ +{ + int i; /* Looping var */ + http_t *http; /* Connection to server */ + ipp_t *request; /* IPP Request */ + struct timeval start, /* Start time */ + end; /* End time */ + double reqtime, /* Time for this request */ + elapsed; /* Elapsed time */ + int op; /* Current operation */ + static ipp_op_t ops[4] = /* Operations to test... */ + { + IPP_PRINT_JOB, + CUPS_GET_PRINTERS, + CUPS_GET_CLASSES, + IPP_GET_JOBS + }; + + + /* + * Connect to the server... + */ + + if ((http = httpConnectEncrypt(server, port, encryption)) == NULL) + { + printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(), + strerror(errno)); + return (1); + } + + /* + * Do multiple requests... + */ + + for (elapsed = 0.0, i = 0; i < requests; i ++) + { + /* + * Build a request which requires the following attributes: + * + * attributes-charset + * attributes-natural-language + * + * In addition, IPP_GET_JOBS needs a printer-uri attribute. + */ + + op = ops[i & 3]; + request = ippNewRequest(op); + + gettimeofday(&start, NULL); + + if (verbose) + printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed, + ippOpString(op)); + + switch (op) + { + case IPP_GET_JOBS : + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers/"); + + default : + ippDelete(cupsDoRequest(http, request, "/")); + break; + + case IPP_PRINT_JOB : + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers/test"); + ippDelete(cupsDoFileRequest(http, request, "/printers/test", + "../data/testprint.ps")); + break; + } + + gettimeofday(&end, NULL); + + reqtime = (end.tv_sec - start.tv_sec) + + 0.000001 * (end.tv_usec - start.tv_usec); + elapsed += reqtime; + + switch (cupsLastError()) + { + case IPP_OK : + case IPP_NOT_FOUND : + if (verbose) + { + printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime); + fflush(stdout); + } + break; + + default : + if (!verbose) + printf("testspeed(%d): %s ", (int)getpid(), + ippOpString(ops[i & 3])); + + printf("failed: %s\n", cupsLastErrorString()); + httpClose(http); + return (1); + } + } + + httpClose(http); + + printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n", + (int)getpid(), i, elapsed, elapsed / i, i / elapsed); + + return (0); +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(void) +{ + puts("Usage: testspeed [-c children] [-h] [-r requests] [-v] [-E] " + "hostname[:port]"); + exit(0); +} + + + +/* + * End of "$Id$". + */ diff --git a/scheduler/testsub.c b/scheduler/testsub.c new file mode 100644 index 0000000000..083bacdc1e --- /dev/null +++ b/scheduler/testsub.c @@ -0,0 +1,522 @@ +/* + * "$Id$" + * + * Scheduler notification tester for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Subscribe to the . + * print_attributes() - Print the attributes in a request... + * sigterm_handler() - Flag when the user hits CTRL-C... + * usage() - Show program usage... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include + + +/* + * Local globals... + */ + +static int terminate = 0; + + +/* + * Local functions... + */ + +static void print_attributes(ipp_t *ipp, int indent); +static void sigterm_handler(int sig); +static void usage(void); + + +/* + * 'main()' - Subscribe to the . + */ + +int +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + const char *uri; /* URI to use */ + int num_events; /* Number of events */ + const char *events[100]; /* Events */ + int subscription_id, /* notify-subscription-id */ + sequence_number, /* notify-sequence-number */ + interval; /* Interval between polls */ + http_t *http; /* HTTP connection */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* Current attribute */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * Parse command-line... + */ + + num_events = 0; + uri = NULL; + + for (i = 1; i < argc; i ++) + if (!strcmp(argv[i], "-E")) + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + else if (!strcmp(argv[i], "-e")) + { + i ++; + if (i >= argc || num_events >= 100) + usage(); + + events[num_events] = argv[i]; + num_events ++; + } + else if (!strcmp(argv[i], "-h")) + { + i ++; + if (i >= argc) + usage(); + + cupsSetServer(argv[i]); + } + else if (uri || strncmp(argv[i], "ipp://", 6)) + usage(); + else + uri = argv[i]; + + if (!uri) + usage(); + + if (num_events == 0) + { + events[0] = "all"; + num_events = 1; + } + + /* + * Connect to the server... + */ + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + perror(cupsServer()); + return (1); + } + + /* + * Catch CTRL-C and SIGTERM... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGINT, sigterm_handler); + sigset(SIGTERM, sigterm_handler); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = sigterm_handler; + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGINT, sigterm_handler); + signal(SIGTERM, sigterm_handler); +#endif /* HAVE_SIGSET */ + + /* + * Create the subscription... + */ + + if (strstr(uri, "/jobs/")) + { + request = ippNewRequest(IPP_CREATE_JOB_SUBSCRIPTION); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + } + else + { + request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION); + 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()); + + ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", + num_events, NULL, events); + ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, + "notify-pull-method", NULL, "ippget"); + + response = cupsDoRequest(http, request, uri); + if (cupsLastError() >= IPP_BAD_REQUEST) + { + fprintf(stderr, "Create-%s-Subscription: %s\n", + strstr(uri, "/jobs") ? "Job" : "Printer", cupsLastErrorString()); + ippDelete(response); + httpClose(http); + return (1); + } + + if ((attr = ippFindAttribute(response, "notify-subscription-id", + IPP_TAG_INTEGER)) == NULL) + { + fputs("ERROR: No notify-subscription-id in response!\n", stderr); + ippDelete(response); + httpClose(http); + return (1); + } + + subscription_id = attr->values[0].integer; + + printf("Create-%s-Subscription: notify-subscription-id=%d\n", + strstr(uri, "/jobs/") ? "Job" : "Printer", subscription_id); + + ippDelete(response); + + /* + * Monitor for events... + */ + + sequence_number = 0; + + while (!terminate) + { + /* + * Get the current events... + */ + + printf("\nGet-Notifications(%d,%d):", subscription_id, sequence_number); + fflush(stdout); + + request = ippNewRequest(IPP_GET_NOTIFICATIONS); + + if (strstr(uri, "/jobs/")) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + else + 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()); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "notify-subscription-ids", subscription_id); + if (sequence_number) + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "notify-sequence-numbers", sequence_number + 1); + + response = cupsDoRequest(http, request, uri); + + printf(" %s\n", ippErrorString(cupsLastError())); + + if (cupsLastError() >= IPP_BAD_REQUEST) + fprintf(stderr, "Get-Notifications: %s\n", cupsLastErrorString()); + else if (response) + { + print_attributes(response, 0); + + for (attr = ippFindAttribute(response, "notify-sequence-number", + IPP_TAG_INTEGER); + attr; + attr = ippFindNextAttribute(response, "notify-sequence-number", + IPP_TAG_INTEGER)) + if (attr->values[0].integer > sequence_number) + sequence_number = attr->values[0].integer; + } + + if ((attr = ippFindAttribute(response, "notify-get-interval", + IPP_TAG_INTEGER)) != NULL && + attr->values[0].integer > 0) + interval = attr->values[0].integer; + else + interval = 5; + + ippDelete(response); + sleep(interval); + } + + /* + * Cancel the subscription... + */ + + printf("\nCancel-Subscription:"); + fflush(stdout); + + request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION); + + if (strstr(uri, "/jobs/")) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + else + 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()); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, + "notify-subscription-id", subscription_id); + + ippDelete(cupsDoRequest(http, request, uri)); + + printf(" %s\n", ippErrorString(cupsLastError())); + + if (cupsLastError() >= IPP_BAD_REQUEST) + fprintf(stderr, "Cancel-Subscription: %s\n", cupsLastErrorString()); + + /* + * Close the connection and return... + */ + + httpClose(http); + + return (0); +} + + +/* + * 'print_attributes()' - Print the attributes in a request... + */ + +static void +print_attributes(ipp_t *ipp, /* I - IPP request */ + int indent) /* I - Indentation */ +{ + int i; /* Looping var */ + ipp_tag_t group; /* Current group */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_value_t *val; /* Current value */ + static const char * const tags[] = /* Value/group tag strings */ + { + "reserved-00", + "operation-attributes-tag", + "job-attributes-tag", + "end-of-attributes-tag", + "printer-attributes-tag", + "unsupported-attributes-tag", + "subscription-attributes-tag", + "event-attributes-tag", + "reserved-08", + "reserved-09", + "reserved-0A", + "reserved-0B", + "reserved-0C", + "reserved-0D", + "reserved-0E", + "reserved-0F", + "unsupported", + "default", + "unknown", + "no-value", + "reserved-14", + "not-settable", + "delete-attr", + "admin-define", + "reserved-18", + "reserved-19", + "reserved-1A", + "reserved-1B", + "reserved-1C", + "reserved-1D", + "reserved-1E", + "reserved-1F", + "reserved-20", + "integer", + "boolean", + "enum", + "reserved-24", + "reserved-25", + "reserved-26", + "reserved-27", + "reserved-28", + "reserved-29", + "reserved-2a", + "reserved-2b", + "reserved-2c", + "reserved-2d", + "reserved-2e", + "reserved-2f", + "octetString", + "dateTime", + "resolution", + "rangeOfInteger", + "begCollection", + "textWithLanguage", + "nameWithLanguage", + "endCollection", + "reserved-38", + "reserved-39", + "reserved-3a", + "reserved-3b", + "reserved-3c", + "reserved-3d", + "reserved-3e", + "reserved-3f", + "reserved-40", + "textWithoutLanguage", + "nameWithoutLanguage", + "reserved-43", + "keyword", + "uri", + "uriScheme", + "charset", + "naturalLanguage", + "mimeMediaType", + "memberName" + }; + + + for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next) + { + if ((attr->group_tag == IPP_TAG_ZERO && indent <= 8) || !attr->name) + { + group = IPP_TAG_ZERO; + putchar('\n'); + continue; + } + + if (group != attr->group_tag) + { + group = attr->group_tag; + + putchar('\n'); + for (i = 4; i < indent; i ++) + putchar(' '); + + printf("%s:\n\n", tags[group]); + } + + for (i = 0; i < indent; i ++) + putchar(' '); + + printf("%s (", attr->name); + if (attr->num_values > 1) + printf("1setOf "); + printf("%s):", tags[attr->value_tag]); + + switch (attr->value_tag) + { + case IPP_TAG_ENUM : + case IPP_TAG_INTEGER : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %d", val->integer); + putchar('\n'); + break; + + case IPP_TAG_BOOLEAN : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %s", val->boolean ? "true" : "false"); + putchar('\n'); + break; + + case IPP_TAG_RANGE : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %d-%d", val->range.lower, val->range.upper); + putchar('\n'); + break; + + case IPP_TAG_DATE : + { + time_t vtime; /* Date/Time value */ + struct tm *vdate; /* Date info */ + char vstring[256]; /* Formatted time */ + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + vtime = ippDateToTime(val->date); + vdate = localtime(&vtime); + strftime(vstring, sizeof(vstring), "%c", vdate); + printf(" (%s)", vstring); + } + } + putchar('\n'); + break; + + case IPP_TAG_RESOLUTION : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" %dx%d%s", val->resolution.xres, val->resolution.yres, + val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc"); + putchar('\n'); + break; + + 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 : + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + printf(" \"%s\"", val->string.text); + putchar('\n'); + break; + + case IPP_TAG_BEGIN_COLLECTION : + putchar('\n'); + + for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++) + { + if (i) + putchar('\n'); + print_attributes(val->collection, indent + 4); + } + break; + + default : + printf("UNKNOWN (%d values)\n", attr->num_values); + break; + } + } +} + + +/* + * 'sigterm_handler()' - Flag when the user hits CTRL-C... + */ + +static void +sigterm_handler(int sig) /* I - Signal number (unused) */ +{ + (void)sig; + + terminate = 1; +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(void) +{ + puts("Usage: testsub [-E] [-e event ... -e eventN] [-h hostname] URI"); + exit(0); +} + + + +/* + * End of "$Id$". + */ diff --git a/scheduler/type.c b/scheduler/type.c new file mode 100644 index 0000000000..58b08ce658 --- /dev/null +++ b/scheduler/type.c @@ -0,0 +1,1178 @@ +/* + * "$Id$" + * + * MIME typing routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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_types() - Compare two MIME super/type names. + * checkrules() - Check each rule in a list. + * patmatch() - Pattern matching... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include + +#include +#include "mime.h" +#include + + +/* + * Local types... + */ + +typedef struct _mime_filebuf_s /**** File buffer for MIME typing ****/ +{ + cups_file_t *fp; /* File pointer */ + int offset, /* Offset in file */ + length; /* Length of buffered data */ + unsigned char buffer[MIME_MAX_BUFFER];/* Buffered data */ +} _mime_filebuf_t; + + +/* + * Local functions... + */ + +static int compare_types(mime_type_t *t0, mime_type_t *t1); +static int checkrules(const char *filename, _mime_filebuf_t *fb, + mime_magic_t *rules); +static int patmatch(const char *s, const char *pat); + + +/* + * Local globals... + */ + +#ifdef DEBUG +static const char * const debug_ops[] = + { /* Test names... */ + "NOP", /* No operation */ + "AND", /* Logical AND of all children */ + "OR", /* Logical OR of all children */ + "MATCH", /* Filename match */ + "ASCII", /* ASCII characters in range */ + "PRINTABLE", /* Printable characters (32-255) */ + "STRING", /* String matches */ + "CHAR", /* Character/byte matches */ + "SHORT", /* Short/16-bit word matches */ + "INT", /* Integer/32-bit word matches */ + "LOCALE", /* Current locale matches string */ + "CONTAINS", /* File contains a string */ + "ISTRING" /* Case-insensitive string matches */ + }; +#endif /* DEBUG */ + + +/* + * '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 */ + + + /* + * Range check input... + */ + + if (!mime || !super || !type) + 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 (!mime->types) + mime->types = cupsArrayNew((cups_array_func_t)compare_types, NULL); + + if (!mime->types) + return (NULL); + + if ((temp = calloc(1, sizeof(mime_type_t) - MIME_MAX_TYPE + + strlen(type) + 1)) == NULL) + return (NULL); + + strlcpy(temp->super, super, sizeof(temp->super)); + strcpy(temp->type, type); /* Safe: temp->type is allocated */ + temp->priority = 100; + + cupsArrayAdd(mime->types, temp); + + 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 || !rule) + return (-1); + + /* + * Find the last rule in the top-level of the rules tree. + */ + + for (current = mt->rules; current; current = current->next) + if (!current->next) + 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(("mimeAddTypeRule: %s/%s: %s", mt->super, mt->type, rule)); + + while (*rule != '\0') + { + while (isspace(*rule & 255)) + rule ++; + + if (*rule == '(') + { + DEBUG_puts("mimeAddTypeRule: New parenthesis group"); + logic = MIME_MAGIC_NOP; + rule ++; + } + else if (*rule == ')') + { + DEBUG_puts("mimeAddTypeRule: 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) + { + /* + * 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(("mimeAddTypeRule: Creating new AND group %p...", temp)); + } + else if (current->parent) + { + DEBUG_printf(("mimeAddTypeRule: Setting group %p op to AND...", + 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(("mimeAddTypeRule: Creating new AND group %p inside OR " + "group", 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("mimeAddTypeRule: Going up one level"); + current = current->parent; + } + } + + logic = MIME_MAGIC_OR; + rule ++; + } + else if (*rule == '!') + { + DEBUG_puts("mimeAddTypeRule: NOT"); + invert = 1; + rule ++; + } + else if (isalnum(*rule & 255)) + { + /* + * Read an extension name or a function... + */ + + ptr = name; + while (isalnum(*rule & 255) && (ptr - name) < (sizeof(name) - 1)) + *ptr++ = *rule++; + + *ptr = '\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 & 255)) + { + /* + * 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] & 255) && isxdigit(rule[1] & 255)) + { + 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 != ',') + { + num_values ++; + break; + } + + rule ++; + } + + if (*rule != ')') + return (-1); + + rule ++; + + /* + * Figure out the function... + */ + + if (!strcmp(name, "match")) + op = MIME_MAGIC_MATCH; + else if (!strcmp(name, "ascii")) + op = MIME_MAGIC_ASCII; + else if (!strcmp(name, "printable")) + op = MIME_MAGIC_PRINTABLE; + else if (!strcmp(name, "string")) + op = MIME_MAGIC_STRING; + else if (!strcmp(name, "istring")) + op = MIME_MAGIC_ISTRING; + else if (!strcmp(name, "char")) + op = MIME_MAGIC_CHAR; + else if (!strcmp(name, "short")) + op = MIME_MAGIC_SHORT; + else if (!strcmp(name, "int")) + op = MIME_MAGIC_INT; + else if (!strcmp(name, "locale")) + op = MIME_MAGIC_LOCALE; + else if (!strcmp(name, "contains")) + op = MIME_MAGIC_CONTAINS; + else if (!strcmp(name, "priority") && num_values == 1) + { + mt->priority = atoi(value[0]); + continue; + } + 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]); + 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(("mimeAddTypeRule: Making new OR group %p for " + "parenthesis...", temp)); + + temp->op = MIME_MAGIC_OR; + + if ((temp->child = calloc(1, sizeof(mime_magic_t))) == NULL) + return (-1); + + temp->child->parent = temp; + temp->child->invert = temp->invert; + temp->invert = 0; + + temp = temp->child; + logic = MIME_MAGIC_OR; + } + + DEBUG_printf(("mimeAddTypeRule: adding %p: %s, op=MIME_MAGIC_%s(%d), " + "logic=MIME_MAGIC_%s, invert=%d", temp, name, debug_ops[op], + op, debug_ops[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 : + case MIME_MAGIC_ISTRING : + 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 = (unsigned char)strtol(value[1], NULL, 0); + + DEBUG_printf(("1mimeAddTypeRule: CHAR(%d,0x%02x)", temp->offset, + temp->value.charv)); + break; + case MIME_MAGIC_SHORT : + temp->offset = strtol(value[0], NULL, 0); + temp->value.shortv = (unsigned short)strtol(value[1], NULL, 0); + break; + case MIME_MAGIC_INT : + temp->offset = strtol(value[0], NULL, 0); + temp->value.intv = (unsigned)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 on disk */ + const char *filename, /* I - Original filename or NULL */ + int *compression) /* O - Is the file compressed? */ +{ + _mime_filebuf_t fb; /* File buffer */ + const char *base; /* Base filename of file */ + mime_type_t *type, /* File type */ + *best; /* Best match */ + + + DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", filename=\"%s\", " + "compression=%p)", mime, pathname, filename, compression)); + + /* + * Range check input parameters... + */ + + if (!mime || !pathname) + return (NULL); + + /* + * Try to open the file... + */ + + if ((fb.fp = cupsFileOpen(pathname, "r")) == NULL) + return (NULL); + + fb.offset = -1; + fb.length = 0; + + /* + * Figure out the base filename (without directory portion)... + */ + + if (filename) + { + if ((base = strrchr(filename, '/')) != NULL) + base ++; + else + base = filename; + } + else if ((base = strrchr(pathname, '/')) != NULL) + base ++; + else + base = pathname; + + /* + * Then check it against all known types... + */ + + for (type = (mime_type_t *)cupsArrayFirst(mime->types), best = NULL; + type; + type = (mime_type_t *)cupsArrayNext(mime->types)) + if (checkrules(base, &fb, type->rules)) + { + if (!best || type->priority > best->priority) + best = type; + } + + /* + * Finally, close the file and return a match (if any)... + */ + + if (compression) + *compression = cupsFileCompression(fb.fp); + + cupsFileClose(fb.fp); + + return (best); +} + + +/* + * '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*/ + + + /* + * Range check input... + */ + + if (!mime || !super || !type) + return (NULL); + + /* + * Lookup the type in the array... + */ + + strlcpy(key.super, super, sizeof(key.super)); + strlcpy(key.type, type, sizeof(key.type)); + + return ((mime_type_t *)cupsArrayFind(mime->types, &key)); +} + + +/* + * 'compare_types()' - Compare two MIME super/type names. + */ + +static int /* O - Result of comparison */ +compare_types(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 */ + _mime_filebuf_t *fb, /* 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 *bufptr; /* Pointer into buffer */ + + + DEBUG_printf(("checkrules(filename=\"%s\", fb=%p, rules=%p)", filename, + fb, rules)); + + if (rules == NULL) + return (0); + + if (rules->parent == NULL) + logic = MIME_MAGIC_OR; + else + logic = rules->parent->op; + + 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 (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + rules->length) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = rules->offset; + } + + /* + * Test for ASCII printable characters plus standard control chars. + */ + + if ((rules->offset + rules->length) > (fb->offset + fb->length)) + n = fb->offset + fb->length - rules->offset; + else + n = rules->length; + + bufptr = fb->buffer + rules->offset - fb->offset; + 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 (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + rules->length) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = rules->offset; + } + + /* + * Test for 8-bit printable characters plus standard control chars. + */ + + if ((rules->offset + rules->length) > (fb->offset + fb->length)) + n = fb->offset + fb->length - rules->offset; + else + n = rules->length; + + bufptr = fb->buffer + rules->offset - fb->offset; + + 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 : + DEBUG_printf(("checkrules: string(%d, \"%s\")", rules->offset, + rules->value.stringv)); + + /* + * Load the buffer if necessary... + */ + + if (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + rules->length) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = rules->offset; + + DEBUG_printf(("checkrules: loaded %d byte fb->buffer at %d, starts " + "with \"%c%c%c%c\"...", + fb->length, fb->offset, fb->buffer[0], fb->buffer[1], + fb->buffer[2], fb->buffer[3])); + } + + /* + * 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) > (fb->offset + fb->length)) + result = 0; + else + result = (memcmp(fb->buffer + rules->offset - fb->offset, + rules->value.stringv, rules->length) == 0); + DEBUG_printf(("checkrules: result=%d", result)); + break; + + case MIME_MAGIC_ISTRING : + /* + * Load the buffer if necessary... + */ + + if (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + rules->length) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = 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) > (fb->offset + fb->length)) + result = 0; + else + result = (strncasecmp((char *)fb->buffer + rules->offset - + fb->offset, + rules->value.stringv, rules->length) == 0); + break; + + case MIME_MAGIC_CHAR : + /* + * Load the buffer if necessary... + */ + + if (fb->offset < 0 || rules->offset < fb->offset) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = rules->offset; + } + + /* + * Compare the character values; if the file is too short, it + * can't match... + */ + + if (fb->length < 1) + result = 0; + else + result = (fb->buffer[rules->offset - fb->offset] == + rules->value.charv); + break; + + case MIME_MAGIC_SHORT : + /* + * Load the buffer if necessary... + */ + + if (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + 2) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = rules->offset; + } + + /* + * Compare the short values; if the file is too short, it + * can't match... + */ + + if (fb->length < 2) + result = 0; + else + { + bufptr = fb->buffer + rules->offset - fb->offset; + shortv = (bufptr[0] << 8) | bufptr[1]; + result = (shortv == rules->value.shortv); + } + break; + + case MIME_MAGIC_INT : + /* + * Load the buffer if necessary... + */ + + if (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + 4) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = rules->offset; + } + + /* + * Compare the int values; if the file is too short, it + * can't match... + */ + + if (fb->length < 4) + result = 0; + else + { + bufptr = fb->buffer + rules->offset - fb->offset; + intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) | + bufptr[2]) << 8) | bufptr[3]; + result = (intv == rules->value.intv); + } + break; + + case MIME_MAGIC_LOCALE : +#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__) + result = (strcmp(rules->value.localev, + setlocale(LC_ALL, "")) == 0); +#else + result = (strcmp(rules->value.localev, + setlocale(LC_MESSAGES, "")) == 0); +#endif /* __APPLE__ */ + break; + + case MIME_MAGIC_CONTAINS : + /* + * Load the buffer if necessary... + */ + + if (fb->offset < 0 || rules->offset < fb->offset || + (rules->offset + rules->region) > (fb->offset + fb->length)) + { + /* + * Reload file buffer... + */ + + cupsFileSeek(fb->fp, rules->offset); + fb->length = cupsFileRead(fb->fp, (char *)fb->buffer, + sizeof(fb->buffer)); + fb->offset = 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) > (fb->offset + fb->length)) + result = 0; + else + { + if (fb->length > rules->region) + region = rules->region - rules->length; + else + region = fb->length - rules->length; + + for (n = 0; n < region; n ++) + if ((result = (memcmp(fb->buffer + rules->offset - fb->offset + n, + rules->value.stringv, + rules->length) == 0)) != 0) + break; + } + break; + + default : + if (rules->child != NULL) + result = checkrules(filename, fb, 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(("checkrules: result of test %p (MIME_MAGIC_%s) is %d", + rules, debug_ops[rules->op], 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... */ + + /* + * 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/scheduler/util.c b/scheduler/util.c new file mode 100644 index 0000000000..49433efe96 --- /dev/null +++ b/scheduler/util.c @@ -0,0 +1,500 @@ +/* + * "$Id$" + * + * Mini-daemon utility functions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsdCompareNames() - Compare two names. + * cupsdCreateStringsArray() - Create a CUPS array of strings. + * cupsdExec() - Run a program with the correct environment. + * cupsdPipeCommand() - Read output from a command. + * cupsdSendIPPGroup() - Send a group tag. + * cupsdSendIPPHeader() - Send the IPP response header. + * cupsdSendIPPInteger() - Send an integer attribute. + * cupsdSendIPPString() - Send a string attribute. + * cupsdSendIPPTrailer() - Send the end-of-message tag. + */ + +/* + * Include necessary headers... + */ + +#include "util.h" +#include +#include +#include +#ifdef __APPLE__ +# include +extern char **environ; +#endif /* __APPLE__ */ + + +/* + * 'cupsdCompareNames()' - Compare two names. + * + * This function basically does a strcasecmp() of the two strings, + * but is also aware of numbers so that "a2" < "a100". + */ + +int /* O - Result of comparison */ +cupsdCompareNames(const char *s, /* I - First string */ + const char *t) /* I - Second string */ +{ + int diff, /* Difference between digits */ + digits; /* Number of digits */ + + + /* + * Loop through both names, returning only when a difference is + * seen. Also, compare whole numbers rather than just characters, too! + */ + + while (*s && *t) + { + if (isdigit(*s & 255) && isdigit(*t & 255)) + { + /* + * Got a number; start by skipping leading 0's... + */ + + while (*s == '0') + s ++; + while (*t == '0') + t ++; + + /* + * Skip equal digits... + */ + + while (isdigit(*s & 255) && *s == *t) + { + s ++; + t ++; + } + + /* + * Bounce out if *s and *t aren't both digits... + */ + + if (isdigit(*s & 255) && !isdigit(*t & 255)) + return (1); + else if (!isdigit(*s & 255) && isdigit(*t & 255)) + return (-1); + else if (!isdigit(*s & 255) || !isdigit(*t & 255)) + continue; + + if (*s < *t) + diff = -1; + else + diff = 1; + + /* + * Figure out how many more digits there are... + */ + + digits = 0; + s ++; + t ++; + + while (isdigit(*s & 255)) + { + digits ++; + s ++; + } + + while (isdigit(*t & 255)) + { + 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 (0); +} + + +/* + * 'cupsdCreateStringsArray()' - Create a CUPS array of strings. + */ + +cups_array_t * /* O - CUPS array */ +cupsdCreateStringsArray(const char *s) /* I - Comma-delimited strings */ +{ + cups_array_t *a; /* CUPS array */ + const char *start, /* Start of string */ + *end; /* End of string */ + char *ptr; /* New string */ + + + if (!s) + return (NULL); + + if ((a = cupsArrayNew((cups_array_func_t)strcmp, NULL)) != NULL) + { + for (start = end = s; *end; start = end + 1) + { + /* + * Find the end of the current delimited string... + */ + + if ((end = strchr(start, ',')) == NULL) + end = start + strlen(start); + + /* + * Duplicate the string and add it to the array... + */ + + if ((ptr = calloc(1, end - start + 1)) == NULL) + break; + + memcpy(ptr, start, end - start); + cupsArrayAdd(a, ptr); + } + } + + return (a); +} + + +/* + * 'cupsdExec()' - Run a program with the correct environment. + * + * On Mac OS X, we need to update the CFProcessPath environment variable that + * is passed in the environment so the child can access its bundled resources. + */ + +int /* O - exec() status */ +cupsdExec(const char *command, /* I - Full path to program */ + char **argv) /* I - Command-line arguments */ +{ +#ifdef __APPLE__ + int i, j; /* Looping vars */ + char *envp[500], /* Array of environment variables */ + cfprocesspath[1024], /* CFProcessPath environment variable */ + linkpath[1024]; /* Link path for symlinks... */ + int linkbytes; /* Bytes for link path */ + + + /* + * Some Mac OS X programs are bundled and need the CFProcessPath environment + * variable defined. If the command is a symlink, resolve the link and point + * to the resolved location, otherwise, use the command path itself. + */ + + if ((linkbytes = readlink(command, linkpath, sizeof(linkpath) - 1)) > 0) + { + /* + * Yes, this is a symlink to the actual program, nul-terminate and + * use it... + */ + + linkpath[linkbytes] = '\0'; + + if (linkpath[0] == '/') + snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s", + linkpath); + else + snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s/%s", + dirname((char *)command), linkpath); + } + else + snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s", command); + + envp[0] = cfprocesspath; + + /* + * Copy the rest of the environment except for any CFProcessPath that may + * already be there... + */ + + for (i = 1, j = 0; + environ[j] && i < (int)(sizeof(envp) / sizeof(envp[0]) - 1); + j ++) + if (strncmp(environ[j], "CFProcessPath=", 14)) + envp[i ++] = environ[j]; + + envp[i] = NULL; + + /* + * Use execve() to run the program... + */ + + return (execve(command, argv, envp)); + +#else + /* + * On other operating systems, just call execv() to use the same environment + * variables as the parent... + */ + + return (execv(command, argv)); +#endif /* __APPLE__ */ +} + + +/* + * 'cupsdPipeCommand()' - Read output from a command. + */ + +cups_file_t * /* O - CUPS file or NULL on error */ +cupsdPipeCommand(int *pid, /* O - Process ID or 0 on error */ + const char *command, /* I - Command to run */ + char **argv, /* I - Arguments to pass to command */ + int user) /* I - User to run as or 0 for current */ +{ + int fd, /* Temporary file descriptor */ + fds[2]; /* Pipe file descriptors */ + + + /* + * First create the pipe... + */ + + if (pipe(fds)) + { + *pid = 0; + return (NULL); + } + + /* + * Set the "close on exec" flag on each end of the pipe... + */ + + if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC)) + { + close(fds[0]); + close(fds[1]); + + *pid = 0; + + return (NULL); + } + + if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC)) + { + close(fds[0]); + close(fds[1]); + + *pid = 0; + + return (NULL); + } + + /* + * Then run the command... + */ + + if ((*pid = fork()) < 0) + { + /* + * Unable to fork! + */ + + *pid = 0; + close(fds[0]); + close(fds[1]); + + return (NULL); + } + else if (!*pid) + { + /* + * Child comes here... + */ + + if (!getuid() && user) + setuid(user); /* Run as restricted user */ + + if ((fd = open("/dev/null", O_RDONLY)) > 0) + { + dup2(fd, 0); /* pipe */ + close(fds[1]); + + cupsdExec(command, argv); + exit(errno); + } + + /* + * Parent comes here, open the input side of the pipe... + */ + + close(fds[1]); + + return (cupsFileOpenFd(fds[0], "r")); +} + + +/* + * 'cupsdSendIPPGroup()' - Send a group tag. + */ + +void +cupsdSendIPPGroup(ipp_tag_t group_tag) /* I - Group tag */ +{ + /* + * Send IPP group tag (1 byte)... + */ + + putchar(group_tag); +} + + +/* + * 'cupsdSendIPPHeader()' - Send the IPP response header. + */ + +void +cupsdSendIPPHeader( + ipp_status_t status_code, /* I - Status code */ + int request_id) /* I - Request ID */ +{ + /* + * Send IPP/1.1 response header: version number (2 bytes), status code + * (2 bytes), and request ID (4 bytes)... + * + * TODO: Add version number (IPP/2.x and IPP/1.0) support. + */ + + putchar(1); + putchar(1); + + putchar(status_code >> 8); + putchar(status_code); + + putchar(request_id >> 24); + putchar(request_id >> 16); + putchar(request_id >> 8); + putchar(request_id); +} + + +/* + * 'cupsdSendIPPInteger()' - Send an integer attribute. + */ + +void +cupsdSendIPPInteger( + ipp_tag_t value_tag, /* I - Value tag */ + const char *name, /* I - Attribute name */ + int value) /* I - Attribute value */ +{ + size_t len; /* Length of attribute name */ + + + /* + * Send IPP integer value: value tag (1 byte), name length (2 bytes), + * name string (without nul), value length (2 bytes), and value (4 bytes)... + */ + + putchar(value_tag); + + len = strlen(name); + putchar(len >> 8); + putchar(len); + + fputs(name, stdout); + + putchar(0); + putchar(4); + + putchar(value >> 24); + putchar(value >> 16); + putchar(value >> 8); + putchar(value); +} + + +/* + * 'cupsdSendIPPString()' - Send a string attribute. + */ + +void +cupsdSendIPPString( + ipp_tag_t value_tag, /* I - Value tag */ + const char *name, /* I - Attribute name */ + const char *value) /* I - Attribute value */ +{ + size_t len; /* Length of attribute name */ + + + /* + * Send IPP string value: value tag (1 byte), name length (2 bytes), + * name string (without nul), value length (2 bytes), and value string + * (without nul)... + */ + + putchar(value_tag); + + len = strlen(name); + putchar(len >> 8); + putchar(len); + + fputs(name, stdout); + + len = strlen(value); + putchar(len >> 8); + putchar(len); + + fputs(value, stdout); +} + + +/* + * 'cupsdSendIPPTrailer()' - Send the end-of-message tag. + */ + +void +cupsdSendIPPTrailer(void) +{ + putchar(IPP_TAG_END); + fflush(stdout); +} + + +/* + * End of "$Id$". + */ diff --git a/scheduler/util.h b/scheduler/util.h new file mode 100644 index 0000000000..a0f6e50b4a --- /dev/null +++ b/scheduler/util.h @@ -0,0 +1,70 @@ +/* + * "$Id$" + * + * Mini-daemon utility definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPSD_UTIL_H_ +# define _CUPSD_UTIL_H_ + +/* + * Include necessary headers... + */ + +# include +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Types... + */ + +typedef int (*cupsd_compare_func_t)(const void *, const void *); + + +/* + * Prototypes... + */ + +extern int cupsdCompareNames(const char *s, const char *t); +extern cups_array_t *cupsdCreateStringsArray(const char *s); +extern int cupsdExec(const char *command, char **argv); +extern cups_file_t *cupsdPipeCommand(int *pid, const char *command, + char **argv, int user); +extern void cupsdSendIPPGroup(ipp_tag_t group_tag); +extern void cupsdSendIPPHeader(ipp_status_t status_code, + int request_id); +extern void cupsdSendIPPInteger(ipp_tag_t value_tag, + const char *name, int value); +extern void cupsdSendIPPString(ipp_tag_t value_tag, + const char *name, const char *value); +extern void cupsdSendIPPTrailer(void); + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPSD_UTIL_H_ */ + +/* + * End of "$Id$". + */ diff --git a/scripting/perl/CUPS.pm b/scripting/perl/CUPS.pm new file mode 100644 index 0000000000..5f2ed5f147 --- /dev/null +++ b/scripting/perl/CUPS.pm @@ -0,0 +1,144 @@ +package CUPS; + +use 5.006; +use strict; +use warnings; +use Carp; + +require Exporter; +require DynaLoader; +use AutoLoader; + +our @ISA = qw(Exporter DynaLoader); + +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. + +# This allows declaration use CUPS ':all'; +# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK +# will save memory. +our %EXPORT_TAGS = ( 'all' => [ qw( + CUPS_DATE_ANY + CUPS_VERSION + HTTP_MAX_BUFFER + HTTP_MAX_HOST + HTTP_MAX_URI + HTTP_MAX_VALUE + IPP_MAX_NAME + IPP_MAX_VALUES + IPP_PORT + PPD_MAX_LINE + PPD_MAX_NAME + PPD_MAX_TEXT + PPD_VERSION +) ] ); + +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +our @EXPORT = qw( + CUPS_DATE_ANY + CUPS_VERSION + HTTP_MAX_BUFFER + HTTP_MAX_HOST + HTTP_MAX_URI + HTTP_MAX_VALUE + IPP_MAX_NAME + IPP_MAX_VALUES + IPP_PORT + PPD_MAX_LINE + PPD_MAX_NAME + PPD_MAX_TEXT + PPD_VERSION +); +our $VERSION = '1.2'; + +sub AUTOLOAD { + # This AUTOLOAD is used to 'autoload' constants from the constant() + # XS function. If a constant is not found then control is passed + # to the AUTOLOAD in AutoLoader. + + my $constname; + our $AUTOLOAD; + ($constname = $AUTOLOAD) =~ s/.*:://; + croak "& not defined" if $constname eq 'constant'; + my $val = constant($constname, @_ ? $_[0] : 0); + if ($! != 0) { + if ($! =~ /Invalid/ || $!{EINVAL}) { + $AutoLoader::AUTOLOAD = $AUTOLOAD; + goto &AutoLoader::AUTOLOAD; + } + else { + croak "Your vendor has not defined CUPS macro $constname"; + } + } + { + no strict 'refs'; + # Fixed between 5.005_53 and 5.005_61 + if ($] >= 5.00561) { + *$AUTOLOAD = sub () { $val }; + } + else { + *$AUTOLOAD = sub { $val }; + } + } + goto &$AUTOLOAD; +} + +bootstrap CUPS $VERSION; + +# Preloaded methods go here. + +# Autoload methods go after =cut, and are processed by the autosplit program. + +1; +__END__ +# Below is stub documentation for your module. You better edit it! + +=head1 NAME + +CUPS - Perl extension for blah blah blah + +=head1 SYNOPSIS + + use CUPS; + blah blah blah + +=head1 DESCRIPTION + +Stub documentation for CUPS, created by h2xs. It looks like the +author of the extension was negligent enough to leave the stub +unedited. + +Blah blah blah. + +=head2 EXPORT + +None by default. + +=head2 Exportable constants + + CUPS_DATE_ANY + CUPS_VERSION + HTTP_MAX_BUFFER + HTTP_MAX_HOST + HTTP_MAX_URI + HTTP_MAX_VALUE + IPP_MAX_NAME + IPP_MAX_VALUES + IPP_PORT + PPD_MAX_LINE + PPD_MAX_NAME + PPD_MAX_TEXT + PPD_VERSION + + +=head1 AUTHOR + +A. U. Thor, Ea.u.thor@a.galaxy.far.far.awayE + +=head1 SEE ALSO + +L. + +=cut diff --git a/scripting/perl/CUPS.xs b/scripting/perl/CUPS.xs new file mode 100644 index 0000000000..efaf6dc7a5 --- /dev/null +++ b/scripting/perl/CUPS.xs @@ -0,0 +1,270 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include +#include +#include +#include +#include + +static int +not_here(char *s) +{ + croak("%s not implemented on this architecture", s); + return -1; +} + +static double +constant_PPD_M(char *name, int len, int arg) +{ + if (5 + 3 >= len ) { + errno = EINVAL; + return 0; + } + switch (name[5 + 3]) { + case 'L': + if (strEQ(name + 5, "AX_LINE")) { /* PPD_M removed */ +#ifdef PPD_MAX_LINE + return PPD_MAX_LINE; +#else + goto not_there; +#endif + } + case 'N': + if (strEQ(name + 5, "AX_NAME")) { /* PPD_M removed */ +#ifdef PPD_MAX_NAME + return PPD_MAX_NAME; +#else + goto not_there; +#endif + } + case 'T': + if (strEQ(name + 5, "AX_TEXT")) { /* PPD_M removed */ +#ifdef PPD_MAX_TEXT + return PPD_MAX_TEXT; +#else + goto not_there; +#endif + } + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + +static double +constant_P(char *name, int len, int arg) +{ + if (1 + 3 >= len ) { + errno = EINVAL; + return 0; + } + switch (name[1 + 3]) { + case 'M': + if (!strnEQ(name + 1,"PD_", 3)) + break; + return constant_PPD_M(name, len, arg); + case 'V': + if (strEQ(name + 1, "PD_VERSION")) { /* P removed */ +#ifdef PPD_VERSION + return PPD_VERSION; +#else + goto not_there; +#endif + } + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + +static double +constant_H(char *name, int len, int arg) +{ + if (1 + 8 >= len ) { + errno = EINVAL; + return 0; + } + switch (name[1 + 8]) { + case 'B': + if (strEQ(name + 1, "TTP_MAX_BUFFER")) { /* H removed */ +#ifdef HTTP_MAX_BUFFER + return HTTP_MAX_BUFFER; +#else + goto not_there; +#endif + } + case 'H': + if (strEQ(name + 1, "TTP_MAX_HOST")) { /* H removed */ +#ifdef HTTP_MAX_HOST + return HTTP_MAX_HOST; +#else + goto not_there; +#endif + } + case 'U': + if (strEQ(name + 1, "TTP_MAX_URI")) { /* H removed */ +#ifdef HTTP_MAX_URI + return HTTP_MAX_URI; +#else + goto not_there; +#endif + } + case 'V': + if (strEQ(name + 1, "TTP_MAX_VALUE")) { /* H removed */ +#ifdef HTTP_MAX_VALUE + return HTTP_MAX_VALUE; +#else + goto not_there; +#endif + } + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + +static double +constant_IPP_M(char *name, int len, int arg) +{ + if (5 + 3 >= len ) { + errno = EINVAL; + return 0; + } + switch (name[5 + 3]) { + case 'N': + if (strEQ(name + 5, "AX_NAME")) { /* IPP_M removed */ +#ifdef IPP_MAX_NAME + return IPP_MAX_NAME; +#else + goto not_there; +#endif + } + case 'V': + if (strEQ(name + 5, "AX_VALUES")) { /* IPP_M removed */ +#ifdef IPP_MAX_VALUES + return IPP_MAX_VALUES; +#else + goto not_there; +#endif + } + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + +static double +constant_I(char *name, int len, int arg) +{ + if (1 + 3 >= len ) { + errno = EINVAL; + return 0; + } + switch (name[1 + 3]) { + case 'M': + if (!strnEQ(name + 1,"PP_", 3)) + break; + return constant_IPP_M(name, len, arg); + case 'P': + if (strEQ(name + 1, "PP_PORT")) { /* I removed */ +#ifdef IPP_PORT + return IPP_PORT; +#else + goto not_there; +#endif + } + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + +static double +constant_C(char *name, int len, int arg) +{ + if (1 + 4 >= len ) { + errno = EINVAL; + return 0; + } + switch (name[1 + 4]) { + case 'D': + if (strEQ(name + 1, "UPS_DATE_ANY")) { /* C removed */ +#ifdef CUPS_DATE_ANY + return CUPS_DATE_ANY; +#else + goto not_there; +#endif + } + case 'V': + if (strEQ(name + 1, "UPS_VERSION")) { /* C removed */ +#ifdef CUPS_VERSION + return CUPS_VERSION; +#else + goto not_there; +#endif + } + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + +static double +constant(char *name, int len, int arg) +{ + errno = 0; + switch (name[0 + 0]) { + case 'C': + return constant_C(name, len, arg); + case 'H': + return constant_H(name, len, arg); + case 'I': + return constant_I(name, len, arg); + case 'P': + return constant_P(name, len, arg); + } + errno = EINVAL; + return 0; + +not_there: + errno = ENOENT; + return 0; +} + + +MODULE = CUPS PACKAGE = CUPS + + +double +constant(sv,arg) + PREINIT: + STRLEN len; + INPUT: + SV * sv + char * s = SvPV(sv, len); + int arg + CODE: + RETVAL = constant(s,len,arg); + OUTPUT: + RETVAL + diff --git a/scripting/perl/Makefile.PL b/scripting/perl/Makefile.PL new file mode 100644 index 0000000000..f5e4bdd27e --- /dev/null +++ b/scripting/perl/Makefile.PL @@ -0,0 +1,17 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'CUPS', + 'VERSION_FROM' => 'CUPS.pm', # finds $VERSION + 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT_FROM => 'CUPS.pm', # retrieve abstract from module + AUTHOR => 'A. U. Thor ') : ()), + 'LIBS' => ['-lcups '], # e.g., '-lm' + 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' + # Insert -I. if you add *.h files later: + 'INC' => '', # e.g., '-I/usr/include/other' + # Un-comment this if you add C files to link with later: + # 'OBJECT' => '$(O_FILES)', # link all the C files too +); diff --git a/scripting/perl/README b/scripting/perl/README new file mode 100644 index 0000000000..1605c77984 --- /dev/null +++ b/scripting/perl/README @@ -0,0 +1,35 @@ +CUPS version 1.2 +================ + +The README is used to introduce the module and provide instructions on +how to install the module, any machine dependencies it may have (for +example C compilers and installed libraries) and any other information +that should be provided before the module is installed. + +A README file is required for CPAN modules since CPAN extracts the +README file from a module distribution so that people browsing the +archive can use it get an idea of the modules uses. It is usually a +good idea to provide version information here so that people can +decide whether fixes for the module are worth downloading. + +INSTALLATION + +To install this module type the following: + + perl Makefile.PL + make + make test + make install + +DEPENDENCIES + +This module requires these other modules and libraries: + + blah blah blah + +COPYRIGHT AND LICENCE + +Put the correct copyright and licence information here. + +Copyright (C) 2002 A. U. Thor blah blah blah + diff --git a/scripting/perl/test.pl b/scripting/perl/test.pl new file mode 100644 index 0000000000..acf31916b1 --- /dev/null +++ b/scripting/perl/test.pl @@ -0,0 +1,17 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use Test; +BEGIN { plan tests => 1 }; +use CUPS; +ok(1); # If we made it this far, we're ok. + +######################### + +# Insert your test code below, the Test module is use()ed here so read +# its man page ( perldoc Test ) for help writing this test script. + diff --git a/scripting/php/Dependencies b/scripting/php/Dependencies new file mode 100644 index 0000000000..50d872b4b4 --- /dev/null +++ b/scripting/php/Dependencies @@ -0,0 +1,6 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +phpcups.o: ../../cups/string.h ../../config.h phpcups.h ../../cups/cups.h +phpcups.o: ../../cups/ipp.h ../../cups/http.h ../../cups/versioning.h +phpcups.o: ../../cups/ppd.h ../../cups/array.h ../../cups/file.h +phpcups.o: ../../cups/language.h ../../cups/language.h ../../cups/debug.h diff --git a/scripting/php/Makefile b/scripting/php/Makefile new file mode 100644 index 0000000000..fa431779ff --- /dev/null +++ b/scripting/php/Makefile @@ -0,0 +1,153 @@ +# +# "$Id$" +# +# PHP Makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../../Makedefs + + +# +# Where to install and how to compile the PHP module... +# + +PHPDIR = $(BUILDROOT)`$(PHPCONFIG) --extension-dir` +OPTIONS = $(PHPOPTIONS) + + +# +# Object files... +# + +OBJS = phpcups.o + + +# +# Targets in this directory... +# + +PHPCUPS = phpcups.so + + +# +# Make all targets... +# + +all: $(PHPCUPS) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Remove object and target files... +# + +clean: + $(RM) $(OBJS) $(PHPCUPS) + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + makedepend -Y -I../.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + echo Installing $(PHPCUPS) in $(PHPDIR) + $(INSTALL_DIR) $(PHPDIR) + $(INSTALL_LIB) $(PHPCUPS) $(PHPDIR) + if test "x$(SYMROOT)" != x; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(PHPCUPS) $(SYMROOT); \ + fi + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall object and target files... +# + +uninstall: + $(RM) $(PHPDIR)/$(PHPCUPS) + -$(RMDIR) $(PHPDIR) + + +# +# phpcups.so +# + +phpcups.so: $(OBJS) ../../Makedefs + echo Linking $@... + if test `uname` = Darwin; then \ + DSOFLAGS="-bundle -flat_namespace -undefined suppress $(RC_CFLAGS)"; \ + else \ + DSOFLAGS="$(DSOFLAGS)"; \ + fi; \ + echo $(DSO) $$DSOFLAGS $(ARCHFLAGS) -o $@ $(OBJS) -L../../cups $(LIBS); \ + $(DSO) $$DSOFLAGS $(ARCHFLAGS) -o $@ $(OBJS) -L../../cups $(LIBS) + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/scripting/php/README b/scripting/php/README new file mode 100644 index 0000000000..e4ab27d840 --- /dev/null +++ b/scripting/php/README @@ -0,0 +1,157 @@ +README - 02/25/2006 +------------------- + +INTRODUCTION + + This directory contains a dynamically loadable CUPS extension + module for PHP 4 and 5. The CUPS 1.2 module has been + substantially updated to provide an API more consistent with + the C API and is NOT compatible with the CUPS 1.1 module. + + +COMPILING AND INSTALLING + + Run "make" to compile the PHP CUPS extension: + + make + + To install it, type: + + make install + + +RESOURCES AND SUPPORT + + Questions should be reported to the CUPS newsgroups/mailing + lists at: + + http://www.cups.org/newsgroups.php + + Bug reports and enhancement requests can be submitted via the + form at: + + http://www.cups.org/str.php + + +QUICK REFERENCE DOCUMENTATION + + In lieu of actual documentation, the following definitions + can be used as a quick reference to the supported functions: + + + CUPS_CANCEL_JOB + + Cancels a job on the named destination: + + bool cups_cancel_job(string dest, int id) + + The return value is TRUE on success and FALSE on failure. + + Example: + + if (!cups_cancel_job("myprinter", 123)) + print("Unable to cancel job: " . cups_last_error_string() . "\n"); + + + CUPS_GET_DESTS + + Gets a list of available destinations: + + array cups_get_dests() + + The return value is an array of objects with the following + properties: + + name The name of the printer or class + instance The instance of the printer or class + is_default TRUE if the printer or class is the default destination + options Associative array of options and their values + + Example: + + $dest = cups_get_dests(); + + + CUPS_GET_JOBS + + Gets a list of jobs: + + array cups_get_jobs(string dest, bool myjobs, int completed) + + The "dest" string can be blank for jobs on all destinations. + Pass TRUE for "myjobs" to only get jobs for the current user. + The "completed" argument can be 0 for pending jobs, 1 for + completed jobs, and -1 for all jobs. + + The return value is an array of objects with the following + properties: + + id The job ID + dest Printer or class name + title Title/job name + user User the submitted the job + format Document format + state Job state + size Size in kilobytes + priority Priority (1-100) + completed_time Time the job was completed + creation_time Time the job was created + processing_time Time the job was processed + + Example: + + $jobs = cups_get_jobs("", FALSE, -1); + + + CUPS_LAST_ERROR + + Returns the IPP status code for the most recent request: + + int cups_last_error() + + Example: + + $error = cups_last_error(); + + + CUPS_LAST_ERROR_STRING + + Returns the IPP status-message string for the most recent request: + + string cups_last_error_string() + + Example: + + $message = cups_last_error_string(); + + + CUPS_PRINT_FILE + + Prints a single file to a printer or class: + + int cups_print_file(string dest, string filename, string title, + array options) + + The return value is the job ID or 0 if there was an error. + + Example: + + $options = array("name" => "value", "name2" => "value2"); + $id = cups_print_file("dest", "filename", "title", $options); + + + CUPS_PRINT_FILES + + Prints one or more files to a printer or class: + + int cups_print_files(string dest, array files, string title, + array options); + + The return value is the job ID or 0 if there was an error. + + Example: + + $files = array("file1", "file2", "file3"); + $options = array("name" => "value", "name2" => "value2"); + $id = cups_print_file("dest", $files, "title", $options); + diff --git a/scripting/php/phpcups.c b/scripting/php/phpcups.c new file mode 100644 index 0000000000..d125a6e872 --- /dev/null +++ b/scripting/php/phpcups.c @@ -0,0 +1,487 @@ +/* + * "$Id$" + * + * Printing utilities for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cups_convert_options() - Convert a PHP options array to a CUPS options array. + * zm_startup_phpcups() - Initialize the CUPS module. + * zif_cups_cancel_job() - Cancel a job. + * zif_cups_get_dests() - Get a list of printers and classes. + * zif_cups_get_jobs() - Get a list of jobs. + * zif_cups_last_error() - Return the last IPP status code. + * zif_cups_last_error_string() - Return the last IPP status + * zif_cups_print_file() - Print a single file. + * zif_cups_print_files() - Print multiple files. + */ + +/* + * Include necessary headers... + */ + +#include +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "phpcups.h" + + +/* + * PHP function list... + */ + +function_entry phpcups_functions[] = +{ + PHP_FE(cups_cancel_job, NULL) + PHP_FE(cups_get_dests, NULL) + PHP_FE(cups_get_jobs, NULL) + PHP_FE(cups_last_error, NULL) + PHP_FE(cups_last_error_string, NULL) + PHP_FE(cups_print_file, NULL) + PHP_FE(cups_print_files, NULL) + {NULL, NULL, NULL} +}; + + +/* + * PHP module info... + */ + +zend_module_entry phpcups_module_entry = +{ + STANDARD_MODULE_HEADER, + "phpcups", + phpcups_functions, + PHP_MINIT(phpcups), + NULL, + NULL, + NULL, + NULL, + CUPS_SVERSION, + STANDARD_MODULE_PROPERTIES +}; + + +ZEND_GET_MODULE(phpcups) + + +/* + * 'cups_convert_options()' - Convert a PHP options array to a CUPS options array. + */ + +static int /* O - Number of options */ +cups_convert_options( + zval *optionsobj, /* I - Options array object */ + cups_option_t **options) /* O - Options */ +{ + int num_options; /* Number of options */ + HashTable *ht; /* Option array hash table */ + Bucket *current; /* Current element in array */ + zval *value; /* Current value in array */ + char temp[255]; /* String value for numbers */ + + + ht = Z_ARRVAL_P(optionsobj); + num_options = 0; + + for (current = ht->pListHead; current; current = current->pListNext) + { + value = (zval *)current->pDataPtr; + + switch (Z_TYPE_P(value)) + { + case IS_LONG : + sprintf(temp, "%ld", Z_LVAL_P(value)); + num_options = cupsAddOption(current->arKey, temp, num_options, + options); + break; + + case IS_DOUBLE : + sprintf(temp, "%g", Z_DVAL_P(value)); + num_options = cupsAddOption(current->arKey, temp, num_options, + options); + break; + + case IS_BOOL : + num_options = cupsAddOption(current->arKey, + Z_BVAL_P(value) ? "true" : "false", + num_options, options); + break; + + case IS_STRING : + num_options = cupsAddOption(current->arKey, Z_STRVAL_P(value), + num_options, options); + break; + } + } + + return (num_options); +} + + +/* + * 'zm_startup_phpcups()' - Initialize the CUPS module. + */ + +PHP_MINIT_FUNCTION(phpcups) +{ + REGISTER_LONG_CONSTANT("CUPS_PRINTER_LOCAL", CUPS_PRINTER_LOCAL, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_CLASS", CUPS_PRINTER_CLASS, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_REMOTE", CUPS_PRINTER_REMOTE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_BW", CUPS_PRINTER_BW, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLOR", CUPS_PRINTER_COLOR, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DUPLEX", CUPS_PRINTER_DUPLEX, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_STAPLE", CUPS_PRINTER_STAPLE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COPIES", CUPS_PRINTER_COPIES, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLLATE", CUPS_PRINTER_COLLATE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_PUNCH", CUPS_PRINTER_PUNCH, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COVER", CUPS_PRINTER_COVER, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_BIND", CUPS_PRINTER_BIND, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_SORT", CUPS_PRINTER_SORT, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_SMALL", CUPS_PRINTER_SMALL, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_MEDIUM", CUPS_PRINTER_MEDIUM, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_LARGE", CUPS_PRINTER_LARGE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_VARIABLE", CUPS_PRINTER_VARIABLE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_IMPLICIT", CUPS_PRINTER_IMPLICIT, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DEFAULT", CUPS_PRINTER_DEFAULT, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_FAX", CUPS_PRINTER_FAX, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_REJECTING", CUPS_PRINTER_REJECTING, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DELETE", CUPS_PRINTER_DELETE, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_NOT_SHARED", CUPS_PRINTER_NOT_SHARED, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_AUTHENTICATED", CUPS_PRINTER_AUTHENTICATED, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_COMMANDS", CUPS_PRINTER_COMMANDS, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_DISCOVERED", CUPS_PRINTER_DISCOVERED, CONST_CS); + REGISTER_LONG_CONSTANT("CUPS_PRINTER_OPTIONS", CUPS_PRINTER_OPTIONS, CONST_CS); + + REGISTER_LONG_CONSTANT("IPP_OK", IPP_OK, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_SUBST", IPP_OK_SUBST, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_CONFLICT", IPP_OK_CONFLICT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_SUBSCRIPTIONS", IPP_OK_IGNORED_SUBSCRIPTIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_NOTIFICATIONS", IPP_OK_IGNORED_NOTIFICATIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_TOO_MANY_EVENTS", IPP_OK_TOO_MANY_EVENTS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_BUT_CANCEL_SUBSCRIPTION", IPP_OK_BUT_CANCEL_SUBSCRIPTION, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OK_EVENTS_COMPLETE", IPP_OK_EVENTS_COMPLETE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_REDIRECTION_OTHER_SITE", IPP_REDIRECTION_OTHER_SITE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_BAD_REQUEST", IPP_BAD_REQUEST, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_FORBIDDEN", IPP_FORBIDDEN, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_AUTHENTICATED", IPP_NOT_AUTHENTICATED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_AUTHORIZED", IPP_NOT_AUTHORIZED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_POSSIBLE", IPP_NOT_POSSIBLE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_TIMEOUT", IPP_TIMEOUT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_FOUND", IPP_NOT_FOUND, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_GONE", IPP_GONE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_REQUEST_ENTITY", IPP_REQUEST_ENTITY, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_REQUEST_VALUE", IPP_REQUEST_VALUE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT", IPP_DOCUMENT_FORMAT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES", IPP_ATTRIBUTES, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_URI_SCHEME", IPP_URI_SCHEME, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_CHARSET", IPP_CHARSET, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_CONFLICT", IPP_CONFLICT, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_COMPRESSION_NOT_SUPPORTED", IPP_COMPRESSION_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_COMPRESSION_ERROR", IPP_COMPRESSION_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT_ERROR", IPP_DOCUMENT_FORMAT_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DOCUMENT_ACCESS_ERROR", IPP_DOCUMENT_ACCESS_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES_NOT_SETTABLE", IPP_ATTRIBUTES_NOT_SETTABLE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_SUBSCRIPTIONS", IPP_IGNORED_ALL_SUBSCRIPTIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_TOO_MANY_SUBSCRIPTIONS", IPP_TOO_MANY_SUBSCRIPTIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_NOTIFICATIONS", IPP_IGNORED_ALL_NOTIFICATIONS, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_PRINT_SUPPORT_FILE_NOT_FOUND", IPP_PRINT_SUPPORT_FILE_NOT_FOUND, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_INTERNAL_ERROR", IPP_INTERNAL_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_OPERATION_NOT_SUPPORTED", IPP_OPERATION_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_SERVICE_UNAVAILABLE", IPP_SERVICE_UNAVAILABLE, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_VERSION_NOT_SUPPORTED", IPP_VERSION_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_DEVICE_ERROR", IPP_DEVICE_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_TEMPORARY_ERROR", IPP_TEMPORARY_ERROR, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_NOT_ACCEPTING", IPP_NOT_ACCEPTING, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_PRINTER_BUSY", IPP_PRINTER_BUSY, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_ERROR_JOB_CANCELLED", IPP_ERROR_JOB_CANCELLED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_MULTIPLE_JOBS_NOT_SUPPORTED", IPP_MULTIPLE_JOBS_NOT_SUPPORTED, CONST_CS); + REGISTER_LONG_CONSTANT("IPP_PRINTER_IS_DEACTIVATED", IPP_PRINTER_IS_DEACTIVATED, CONST_CS); + + return (SUCCESS); +} + +/* + * 'zif_cups_cancel_job()' - Cancel a job. + */ + +PHP_FUNCTION(cups_cancel_job) +{ + char *dest; /* Destination */ + int dest_len, /* Length of destination */ + id; /* Job ID */ + + + if (ZEND_NUM_ARGS() != 2 || + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &dest, &dest_len, &id)) + { + WRONG_PARAM_COUNT; + } + + RETURN_LONG(cupsCancelJob(dest, id)); +} + + +/* + * 'zif_cups_get_dests()' - Get a list of printers and classes. + */ + +PHP_FUNCTION(cups_get_dests) +{ + int i, j, /* Looping vars */ + num_dests; /* Number of destinations */ + cups_dest_t *dests, /* Destinations */ + *dest; /* Current destination */ + cups_option_t *option; /* Current option */ + zval *destobj, /* Destination object */ + *optionsobj; /* Options object */ + + + if (ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + if ((num_dests = cupsGetDests(&dests)) <= 0) + { + RETURN_NULL(); + } + + if (array_init(return_value) == SUCCESS) + { + for (i = 0, dest = dests; i < num_dests; i ++, dest ++) + { + MAKE_STD_ZVAL(destobj); + + if (object_init(destobj) == SUCCESS) + { + /* + * Add properties to the destination for each of the cups_dest_t + * members... + */ + + add_property_string(destobj, "name", dest->name, 1); + add_property_string(destobj, "instance", + dest->instance ? dest->instance : "", 1); + add_property_long(destobj, "is_default", dest->is_default); + + /* + * Create an associative array for the options... + */ + + MAKE_STD_ZVAL(optionsobj); + + if (array_init(optionsobj) == SUCCESS) + { + for (j = 0, option = dest->options; + j < dest->num_options; + j ++, option ++) + add_assoc_string(optionsobj, option->name, option->value, 1); + + add_property_zval(destobj, "options", optionsobj); + } + + add_index_zval(return_value, i, destobj); + } + } + } + + cupsFreeDests(num_dests, dests); +} + + +/* + * 'zif_cups_get_jobs()' - Get a list of jobs. + */ + +PHP_FUNCTION(cups_get_jobs) +{ + char *dest; /* Destination */ + int dest_len, /* Length of destination */ + myjobs, /* Only show my jobs? */ + completed; /* Show completed jobs? */ + int i, /* Looping var */ + num_jobs; /* Number of jobs */ + cups_job_t *jobs, /* Jobs */ + *job; /* Current job */ + zval *jobobj; /* Job object */ + + + + + if (ZEND_NUM_ARGS() != 3 || + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &dest, &dest_len, &myjobs, &completed)) + { + WRONG_PARAM_COUNT; + } + + if (!*dest) + dest = NULL; + + if ((num_jobs = cupsGetJobs(&jobs, dest, myjobs, completed)) <= 0) + { + RETURN_NULL(); + } + + if (array_init(return_value) == SUCCESS) + { + for (i = 0, job = jobs; i < num_jobs; i ++, job ++) + { + MAKE_STD_ZVAL(jobobj); + + if (object_init(jobobj) == SUCCESS) + { + /* + * Add properties to the job for each of the cups_job_t + * members... + */ + + add_property_long(jobobj, "id", job->id); + add_property_string(jobobj, "dest", job->dest, 1); + add_property_string(jobobj, "title", job->title, 1); + add_property_string(jobobj, "user", job->user, 1); + add_property_string(jobobj, "format", job->format, 1); + add_property_long(jobobj, "state", job->state); + add_property_long(jobobj, "size", job->size); + add_property_long(jobobj, "priority", job->priority); + add_property_long(jobobj, "completed_time", job->completed_time); + add_property_long(jobobj, "creation_time", job->creation_time); + add_property_long(jobobj, "processing_time", job->processing_time); + + add_index_zval(return_value, i, jobobj); + } + } + } + + cupsFreeJobs(num_jobs, jobs); +} + + +/* + * 'zif_cups_last_error()' - Return the last IPP status code. + */ + +PHP_FUNCTION(cups_last_error) +{ + if (ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + RETURN_LONG(cupsLastError()); +} + + +/* + * 'zif_cups_last_error_string()' - Return the last IPP status-message. + */ + +PHP_FUNCTION(cups_last_error_string) +{ + if (ZEND_NUM_ARGS() != 0) + { + WRONG_PARAM_COUNT; + } + + RETURN_STRING((char *)cupsLastErrorString(), 1); +} + + +/* + * 'zif_cups_print_file()' - Print a single file. + */ + +PHP_FUNCTION(cups_print_file) +{ + char *dest; /* Destination */ + int dest_len; /* Length of destination */ + char *filename; /* Filename */ + int filename_len; /* Length of filename */ + char *title; /* Title */ + int title_len; /* Length of title */ + zval *optionsobj; /* Array of options */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int id; /* Job ID */ + + + if (ZEND_NUM_ARGS() != 4 || + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssa", &dest, &dest_len, + &filename, &filename_len, + &title, &title_len, &optionsobj)) + { + WRONG_PARAM_COUNT; + } + + num_options = cups_convert_options(optionsobj, &options); + + id = cupsPrintFile(dest, filename, title, num_options, options); + + cupsFreeOptions(num_options, options); + + RETURN_LONG(id); +} + + +/* + * 'zif_cups_print_files()' - Print multiple files. + */ + +PHP_FUNCTION(cups_print_files) +{ + char *dest; /* Destination */ + int dest_len; /* Length of destination */ + zval *filesobj; /* Files array */ + int num_files; /* Number of files */ + const char *files[1000]; /* Files */ + char *title; /* Title */ + int title_len; /* Length of title */ + zval *optionsobj; /* Array of options */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + HashTable *ht2; /* Option array hash table */ + Bucket *current; /* Current element in array */ + int id; /* Job ID */ + + + if (ZEND_NUM_ARGS() != 4 || + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sasa", &dest, &dest_len, &filesobj, + &title, &title_len, &optionsobj)) + { + WRONG_PARAM_COUNT; + } + + ht2 = Z_ARRVAL_P(filesobj); + num_files = 0; + + for (current = ht2->pListHead; current; current = current->pListNext) + { + files[num_files ++] = Z_STRVAL_P(((zval *)current->pDataPtr)); + + if (num_files >= (int)(sizeof(files) / sizeof(files[0]))) + break; + } + + num_options = cups_convert_options(optionsobj, &options); + + id = cupsPrintFiles(dest, num_files, files, title, num_options, options); + + cupsFreeOptions(num_options, options); + + RETURN_LONG(id); +} + + +/* + * End of "$Id$". + */ diff --git a/scripting/php/phpcups.h b/scripting/php/phpcups.h new file mode 100644 index 0000000000..396b18e0cb --- /dev/null +++ b/scripting/php/phpcups.h @@ -0,0 +1,70 @@ +/* + * "$Id$" + * + * PHP module include file for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef PHPCUPS_H +# define PHPCUPS_H + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include +# include +# include +# include +# include +# if defined(WIN32) || defined(__EMX__) +# include +# else +# include +# endif /* WIN32 || __EMX__ */ + + +/* + * Zend definitions... + */ + +extern zend_module_entry phpcups_module_entry; +# define phpext_phpcups_ptr &phpcups_module_entry + +# ifdef PHP_WIN32 +# define PHP_PHPCUPS_API __declspec(dllexport) +# else +# define PHP_PHPCUPS_API +# endif + +# ifdef ZTS +# include "TSRM.h" +# endif + +PHP_MINIT_FUNCTION(phpcups); + +PHP_FUNCTION(cups_cancel_job); +PHP_FUNCTION(cups_get_dests); +PHP_FUNCTION(cups_get_jobs); +PHP_FUNCTION(cups_last_error); +PHP_FUNCTION(cups_last_error_string); +PHP_FUNCTION(cups_print_file); +PHP_FUNCTION(cups_print_files); + +#endif /* !PHPCUPS_H */ + + +/* + * End of "$Id$". + */ diff --git a/scripting/php/phpcups.php b/scripting/php/phpcups.php new file mode 100755 index 0000000000..791c004c01 --- /dev/null +++ b/scripting/php/phpcups.php @@ -0,0 +1,60 @@ +#!/usr/bin/php -f + "100", + "page-label" => "testfile.jpg"))); + +print("cups_print_files(\"test\", array(\"../../test/testfile.jpg\", " + ."\"../../test/testfile.ps\"), \"testfiles\", ...):\n"); +print_r(cups_print_files("test", array("../../test/testfile.jpg", + "../../test/testfile.ps"), + "testfiles", + array("scaling" => "100", + "page-label" => "testfile.jpg"))); + +// +// End of "$Id: phpcups.php 3603 2003-04-11 18:42:52Z mike $". +// +?> diff --git a/standards/Makefile b/standards/Makefile new file mode 100644 index 0000000000..5903f58062 --- /dev/null +++ b/standards/Makefile @@ -0,0 +1,163 @@ +# +# "$Id$" +# +# Standards makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + + +# +# Standards... +# + +RFCS = \ + rfc1155.txt \ + rfc1157.txt \ + rfc1179.txt \ + rfc1213.txt \ + rfc1321.txt \ + rfc2222.txt \ + rfc2246.txt \ + rfc2487.txt \ + rfc2554.txt \ + rfc2567.txt \ + rfc2568.txt \ + rfc2569.txt \ + rfc2578.txt \ + rfc2595.txt \ + rfc2616.txt \ + rfc2617.txt \ + rfc2712.txt \ + rfc2790.txt \ + rfc2817.txt \ + rfc2818.txt \ + rfc2821.txt \ + rfc2822.txt \ + rfc2910.txt \ + rfc2911.txt \ + rfc2965.txt \ + rfc3196.txt \ + rfc3239.txt \ + rfc3380.txt \ + rfc3381.txt \ + rfc3382.txt \ + rfc3391.txt \ + rfc3510.txt \ + rfc3712.txt \ + rfc3805.txt \ + rfc3875.txt \ + rfc3986.txt \ + rfc3995.txt \ + rfc3996.txt \ + rfc3997.txt \ + rfc3998.txt \ + rfc4122.txt \ + rfc4234.txt + +.SUFFIXES: .html .txt +.txt.html: rfctohtml + echo Converting $< to HTML... + ./rfctohtml $< ../doc/help/$@ + + +# +# Make everything... +# + +all: rfctohtml $(RFCS:.txt=.html) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + $(RM) rfctohtml rfctohtml.o + $(RM) $(RFCS:.txt=.html) + + +# +# Dummy depend target... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: + + +# +# rfctohtml - make html versions of RFCs... +# + +rfctohtml: rfctohtml.o ../cups/libcups.a + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ rfctohtml.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# End of "$Id$". +# diff --git a/standards/X.690-0207.pdf b/standards/X.690-0207.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8f88864a3694c4396ded15228beef7619a3b766f GIT binary patch literal 524444 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 S-UvRMB#ev`;*~n0*<( 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

4`p75W{?z-9xR*tq<@aVx>@#-=E{c# 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

dkkBX40z=#lj*anvNsKTDZ870j3 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

hqD{XnGh4tf_ZcI9I;bRdW)V-RsuaW$ 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

cjtAr6$uBe|SjI}-?(~MC+BC!AFCF9Hz z!$5dj{Z{5(#-dDF{`o{yL~oprkNx%Wd`C0@NIMV*`VaJC`>*K5{ttR_{4dk%pS^2Y z+5dZbiLw6cnf?D;hH?A{hOshm{7)EGqrPjmJ@xP5)-*nf3IU@Izv+X6fH?Sn1VpXM z+m^r_oCYOaN`S*vL^&fDUsykSax-^JC8XT0TOq}j45T})aEAg+>L*y>83rW_TtBM zN|+?YHLZ}6%?;emdbJP2-WZI4pG32)$1_(EL|2>PKs0l~Tcwsbv5V#4g{oFC%xWb& z?-j?FrEZG`V7)kI(iC`Fq2Rhw%)5hK=1R0IP*==80<1UaK)71cGMvkCtfS|jiwPPw|0Omd92-kcI<^!TK z6%YXDIK4W6<>?(_0xW#Vgqj=ld|W{Jw{2-00=M#O9?q-bQ}2Y-+9Xtjq2AYHyRjFGS0DBL&)5*4HiljYaz z2mJKZ`+=w6%}(m_fXU~bVpu3Q0o%)|>5~)42@xvuc^@JrK4`^ z)lU}&bI6d&q`6B)Ag49?RbVA&t$U z$#S4j4Lh`eto+8V7QV_<)me@h+!$lwh0=&cQGKC6hZDHZV>BBap{qLER&n|VLvJv< z8{vG|V-+i-4MWZ8T(yAoPhpeRUUi|y%K`A2$8-y4d&XI?1*QOj&trY;FNW=1@g1ax z7ic}$EjEsjkK{c6iodeE>6+iWws!&LuOm3oR3R-3?oeBv$ggRHv(9#Pe1Kon8Nw%> z2&=*z$b#5?uO{HL8fx)OM0(#b-uUA^2s z!)v1KZxD$Um$7t!0*xFmsYz) zm?FXUH17FVZI7nvpQEE?{69Y4ZrUue^Bx?9!>Dxctl!I4jz{MG2bBv1m90StU{AoU zU@p$IgvaZf;%uJyI+$C<2VH14o@JEGm)|DQVJ4v3B_-UJkM?Wz@x!WRG&|_r%7oC$ zf=X441^W$#jmP>gwx549YO&fV*V{*Xbl#N4B1>(t^-xHiQrl52lH^})p#Qehv2Cw@ z-L`Es7$e|f1FCoKqBgdla$!>NnYqIb(&jO-UF9X!9-*NWJa}Mj&5y#0-Eti045f}^ z@riV86h3lQTAe7dQGU%w{j8~;ry}k-crry%g2I#u;|d8dR{{fa_Gid4AOR%*hV1v# z8@7Cm*WwRx!z?n7bVAS~Yg1YmRPLoYV(bb3fztmKZ8fMTOW$KKK-Izc*RD-TtWR$g zs>kBPxXZeO)V7hMaBrL%(<-%6=fgz;RfL$b24>IC2oCQyrJ2aEyFO9T)=q zb`43x``N%iN(q= zZM;l${AHhX%y(_O4=oW2oBUq$MAcRIn=zZJjgu?}^Tt`Nza&qA8CYa4i^D&n1p0B%Gd8|lW41jqHT1;`0dDs4bY3bJ16h=heJ160X)2f82+_w zTVNy40snpR5AmGWl?uAfPOBqS44l|>8X43_OZBwk0i)l{K*&lEgj$+)d$1Mvu1CV@ z)qv|2z_f)lEEr+MMHH~~y6go$fMXI~6g=^V?xGn`$xF!cFibujZ|j9%EO^Bs<^GmV z$d-5qo}-C~;Hmj3t)|zZpVP@CQIFbBwSLc_<<*chrw~{R#5ntpvLY+{pD@FjSu>0GNAHZ?1184 z!gsrKN-VEBT(6E`0^nDK<4539)YJ6WKX77(je6;$VHxJAno;3P!a2tS7>H^woiBxq zM|o^wZaa4mh(s-Nqj>X{-LPN&Dc2%U)3q+Sdc-KMS-nFsPs1NO+q+-qX;1F`036Z_ z;QB9qu!p4F#3zY$_fUGUvtXj7MoIYWP_Y{I-9gsBH`?A&FD)n0dmm-FJW_!>aX_It zK>3}*bHJ>jsil=o4k`&&f_0&Uq+5ifKJo$e4$2hO^?tU>>WWH#Ok0kv>-(V(rW5=? z9m*ds+uf&rPrkR=mzytQX65|*KNR`H8LIO-Zg){}$h{H=U`<+e+bq8AuT)pI$zVeE zKdHZ1NR=xiBr*21vzlTngKG9sS`S(}(O{8y!sE2)9)Ke6Bi1p0N+CoC9Fe_L3<4s` zm!@Ucs;Z0662aZu4exjRGvn$r-RFboxkQwIw`=j`d|qVy0OGm} z1RcQP=K8pXUyjwjJ?NfjXlr?ZXH+~#b`cq$`l2JTbp2k)10EMZ9dUHt4RL%RzOp|Q zpIPCG9DHhB_z5et%eM7Ps^FY#G&Nt-waeN@# zTQ4o2v0Y-Kt~DXWZ?O2tV~}mka&Uq*yL12_OU$x4&5>JGLXOL|N}4AL@aqF_2L-!n zUF~SxGF7M@{TZm&wMz?DEkm*zu`a#9T@%9?<@=mIDy4x5>Q-dU4R>eV8Bk+?h#HAy#r(sYKCG1=m{V#$TflDC7VY&YNqQFSr#|P z9N@8`7mP~JH4mMq?Vg9m5JTk@kZaC>(lD=K4BS+LyGPdbhM#>F0z6=?qDDZ^Oa_Qo zdkPlO&Twh)8W?2SYP3o_21oo&AuC)=g-5O!*9HaWW3`SIUOJv{<^6ix{1+h3)QIyxz?$>_ z9oDS>fHfP#{}a}1jQ`89{%03ZHirM>?=;yM|Kk`Kj{jNTPi_01j(^{261+%4(S((F zB(}-NWz+72gG87|1Igl>z>cdiCV~-jMh1T4zW4I>T(B+8n6ZOG0plr(pWSn}$A{aq zsn@e($5Cuu*HH|H5CZw%N;=Firyxdw5>jsYbb0x1OR2QIUkX=fC>CdCh!f@h?0$c) zGmaB=c|-H_bct$?i3s_dflZH3^nPQ2F9*Y8{@KaCeEd=1{Ovm^}?la+tb&zR@F_8mcRGcGp2=I+r zgyB#Z=2!w`mn|QlWa|LC%P}6qeZo`F+So(4>z`nlWq39FvV(!93WJTD#TjLp&v5_1 zAN|p6rzi`dzHi#}9O(BT=%fwAS!7{WEh32HbXGMg5?@Y4-oC7ursKTK<-6=!QKorn zGLAXak)wgjB+Pis@rn`c)fF7=2>8kqS6$r?r~U&Ht*pbRodJa`8h%yyUZeP_a{YQP zSUjxQ-gS$k(jc0NL7H8mr_b?y3V~K5rdq5aCaTFcZVL#I8wnyrmzqLRn31@1x~*z+ zDwD`k@*us+I~sX4C?b}9G+6t>7}~Y+LW=DhK=1zoDFvj5#%Lp19PGWFrHWVBkS+F6 z?S1*&=q5jk=Su(Mebb`Yh(FnV*__^1;V94jBwUtV$)cLTF1TsNG9lkbb#hP5UIj;JEN`aThEDz&FCv#1mjTreOa7n%F5t zEO5!r7%$X>NqOm#C6g~yz?-LVokF&;LoAnd;ca&3aC928q+qlq+5I_+aZbEQi7nM96+Uy`L@6tGhFZGFT{(aUhW}2vxYCh{S(qeG2dP8H6UQ!&lh77&zpU6CGgbA=Q`r3VHK zDno+|juy&$BzmdgqUe6MtR7Ty#*?-g2X3>_8{$v#VXbdu@=Su3x({eo*kK)cL}4h? zx)87agTi8E`J{TiUg37O``w=X!sqt3K0m<|P#lunM3jvd5`%|OK7ESFSnxdyBVW*T zS0Rbmlr(8$4UUwNt$BWc>dG1^Qwj(w86xt+^b+1$6UTKojc+q%<6;e%N)#&QIzaAf zK#&?Ms{`X}oD@h|%dT0PL1y5PlwYn5ZSQmzUpMh;=m}l*$4=eN zrBF}Q`p3{LXJ^tTt7W{UCQh4fTHbVx!oo-1MY!@Jd{NqRa#JNY21b%qw3+#F!j54@ zh>Dri+s=ngT~@Z4rWsiwwWZt8Di8ftm`Hp|I#X{Aj#6)1GyDgY)g4k|^`u^6oB?fQ zxNmyNSrRNU)~p;I3EMFtb*rCE*Ob|%P@6M93WZ%=JlXbcV}&+H7xMPfj2w^I2D|S! zx3oY*>hNw#0CHX0K$9IsVB(_^Bn@>qlE(ICxe;osYvhqCkv`%}0a~fyvgl#wGc#Z3 zu@@5=^ki~E>%Qn2{|7~SB@V@P2|$iRD?pm7FknndI+TGXC(6Lq93OghMXfXtbe|R= z_5b}odDTG}wx%CA#KVetwp8{1VkZ6Km*RjaHnH`39$HPMy9!TKBK{y6CcLQ`r6YsZ&cU7(qE(nIq5eGP%a4qlmA#UI1qU<|lF^ zy^HC>NtRM;92LM@O^f5XS{G!CuUCT_4OF97T(k#w0QXt+oSWVNL!Bjwj7yb@g;fu3 zE@YNdcgYbrB4R+zbItAh49#K1-%TEi_1eJ9&jLguc<}a}j;X3p$6z810olsr04ggE zEPQV=hSnTZ;NZ=I%GhM$i#UjWDOK!aRi#v1Bzhy5&S&Da?=#q3#i$Nir(`vhj7;$% z`M_b(7Id-+RWt*95EDx!0Z~)bjeB{7A_Z9_Vw+NscO6X>CQGcW>GqCulB(NAz&eg_>4GqaFp!N5exU2v!Y_M6P2qTmn_2_w#6e{trkj9`zD46@rFElZo6h}Ooa^n7 z%Hlmq;d8AfXHrmx_yGWodeQWbGF*}=`XfFrP_1~=GtmPT)6_r8Bjn!deZ|MM)*N4x zzaa8@%L>xXVOL*{;lis;oMF|D_gpM~*NBtDi(Bx%3*G$*lWz$0dCkbvPB+&o$=B`~ zu!yFJFF(9M<@r*+#hxB^a~3vqV4+kq_PzacO%Y>oIt>^W(1#<|?eDDXJH(xm zEu0FR2<->NV+DApN4`MCa-j$J0rdAI6Ep5~Y>4p*9UQgq4~uEE2L0en!OkS*Oxd+d zI?Cr|of|*Z#+SY57RYh$mm01(9`vs6CmykltVqHb|Yu|3GN|Z z0F(1L>esW64OB5s)hG*pg14e@^Z<&9)<}-X0+Cti_fkuQW;WVkqPN?=a5PK!1@w-- z+#EbgF|%MUKe9>zHO5RBGa>SVr32Z3$Q9w{tu%NS>s`S+ZKv!>SQwc9wW2}Vyq+Jd z?Vk0#O7wU!7#GM`-Ctwo7atrP+x&KAf_1*JFiKOFksi0U@vL}pc*xaxK5%%3qX2S+ zk>b0q#K9}fm5*!0gcs$+`k*KN`s2jh0_7~Jl82%-whI7j54_itrSf@0O$TsEDv$Y`R5O!qYr z!+d4c;#z{Z!`LEhswZ~}VU|;v?@?-xx+y0|{wnFS%EoO8Jm={b64z}JN(2O)w5dLU zD|zok$2Nx3g5wNi+xYqFRcrfXV8)NDR!Y%{CH-C8RqB7;B9sr8IRSLN-TE$dF-6Oi z6W)G$KjCJjCrI%nth~7o7<%@c#-0dK;*}1o-lr>bGTskS-AP%dgGNf!}gMR5>;y+~7QJJ<#QH({Q0_u~t(myk9O zMe~NGqi*QDU?&{{xE6vM6v}Jc#^gTZt???_0)$LE8`Fc>R#5Gi2*wTs0<%QkH}X~0 zlO;6#`TUDavmb(+)Qd^+J;R3G6#h+qZKKafK5IFmY4gWiEiIxdQV!h?DAo61?ewER zYfID09bkZ#4CdaRvrcz1VjjT3p&#Y%9lF0XJ;*aMQZEs)j1GaZd6Id_mrWs2AAz00 zv$1HxNs9=*$*;Gs4`xWn^y89avz?jG^-poZ6N0lj%wtj~?~?%<+9~Q^L+4+p*Hr~q z8i-4?l9K^lD|Or}Jjq)UKt@2_=UZ)6xT-y2yTrb85zyH7xTm_4KsvD!sh$krJu<-G zHi2Ct3TuQby+vb%E0)o=&ge#K3lI#W#Q^nmAlBSRLw)y#r^;$L)$oztsc^<-0H+J1 zVo*b_mNS+BtWV4l(K10qmGMQ#vuMb-be~DS6X_gNx_0|_CH7a(WB{)g%}(M7-~1Vd zEC_oon`@9>F0DN5@Dbj{R+tu1u5rEU8{2bH%GAx#!Fb`jsUJl5<|DwJ*`a6LX+DMe zQHYV$z+&46C_8ghuwhzs6vYg5v%DqZE)2*IxIn)q9HyQjTg|py$-5Htn#om#en1p%|^ltI%Vn&QXM?C-#+bo?dk1QySR z?`ZE7s~xQM-U&c}lAocQWrgXQ&tuT?=|chl%&FxnjkQk|129cZQJCbOlaB!iDa5a4KYc4U}G!HX|d)Q`rmB|?%R zpK{TtQ7!%iScve_4ogWkt6P$yi4C5qWc8#ulBTol zO)}Pa5?!bW**l4@Uy-nHZOE2mF<<}F1Cc`+J4V$+n2A{}b52ZYMG+xXmCLP(Fw1)y z`XBLL60`?vUY7B?IFT z;}&mHf26o^=OGC)e&lqgMtDlA;QBzCs~4ui>XN^%!V*qFMrHLf+zl|`3EM3hfDr_q zId4MJj3D+C!KWL`#5eTZx68<`u(x;}2#0d5g-j(^hMM}SQ=@cbty8lhHAa?sVU!9p zkr|SHGUQ^{m;^f003chvV zsmo)innz-&lje_+Rn%v3LnIlZ_dZ)MEQ8|`aM`044_hutQi1~3o6-6!bNQTh6lX7& z_5)GENZ6MsfA&TGH10Ddf-n4V*`CCR&rC%DPTPlTaH4m10PB&Gt@DQVkZqSp9vtv|p^&-{*4opJ+xLr zu}o9Pl$C-saz@1rPc|!;LX3q=rVCJUOw!aRoI*W(w;t-hOmCB1-R59qn=N8ltBm(4 z1#G8#({OEAw@=s%h`BWwtqnaXb9AZ7$!B`{5snjMe&iqy!_e z-G{kSd&uGbs2UrFo!4vs_IUsU0M_%fFiu8Wq*HawQ(KhwNEa2}Z+Y!G3MjkeMA*5d zoX@*sYx}x&6Ay2tqs^I(_haqMnO7mrx98Z2x7wfpnjEXL0O4@R@mj9}Gg$d*yBRj9 z^=aliodCYu&2@9o9u*8WAK?ZPN#vdr4r zb70w|J}$r8;h}ji5osGiJtlkuDqGFA3&)l+4@X)y=s*u$f(V02xp2^2-J*1OoBoWG#VX&pLoP%V+^f`br&%rI`X?JOHJ9V z##1}aJPh9EG%kNI_+rfc$nDA>LoDBCNL`DS_1yv)pD=)iM6yw6GO=7UMN2NsB<-df zAhRfF^}M6}0>h1GjO==T2(ddaXF_g@BH~4sZnoIsAku^+N+A;`G-EPL;kVeg?Lx~1 zf`56Vwy4e2c6M@1-*aNv#&Z&%b4ugigCk{*gd5ikt^vy@t94*akRRt7h zmQGo@G_wZbq0Q2c?jmbCs!|6dxA?KR7XN6VWVnQ%>aGPUctqaAo0|X&Nr94Botj<&3ut{9YBiAg4 zMed8+y$4{R5}<1WzcNL`cilnIG>a)4?DqT>$vUFH) zAG4QQ-*CLR&tb2wPw{Z)F@yt`=ZLtjl`J5d2Z1@U6FNlhz_mW4t%9xr-b@FBi8ex3lrp)(}f z9kYf?Jx;nhhd<|B7TPc410ZFOCURCgO_@&N5>H7}Iy6bO5hJPhFe(D~PR?9ir`Q%q$(BE)w_OvuJflRA0ePRzt(+u6PYwqlAL zP_}5R>7bDyaMbO37W_Jp1$Ne*`u1fO-DG0!R<`5`{CagKRdooTb2SQHi*-Sm5HSAD zn=TzC)}qpTEDb$&z2xr6IXv$6xbUe!<#PWmzC)CE2AOotPR^_g(xpL{?-6#Qkr|<< zMAO4#K%=9u0;4CxWfBaJQSdmbf2~YU^LLvj+E};m|9#T;>r+dYO001M)dP*YE)N#j ze??-D%$58akS4cw5KmSNjN0pYyZHDc)%$Vy@%M5yzP`?1^O zlNcG@)q-EB>0~JJ#*KipOr+J;wIx{bBh(0z+3C!pC1`9~b#qFgULDrs!*2Vbe(>P9 zdH6J)0GVKDBrO5U=$j&UrnQ`|$P1NJXNH7CgXKgzH6aBQ3!;_9n*0FRpwB2W6GJo7 zEb%^S{O#X2KX7a40aVd?aNl`T^q5+_nZPS}h-ihxrGbl>K%s2%^H6eQKTLjpB)}xV zfKF&mBXe?hhLmIZk3!}x4@Srlj5-2zcS9R!+NpH4*Y9ctoSpDo+F3KYJ9DQCS^m>* zXh$dXHt3*W_|<)x(r|)ZBxy&eO|4kPHmu<{-EbwqU}{$Bz}l49Ar`mSK5q$i z%*}jJ=M$B1t3tHT30MO$J?6GCGb;HsnXQ42LA<;7|DY!qKQwP7%(SEwu+cgn%rt7qQZUbzW}(k0hJJ4jc*34maY#*r2Srr1SbW6r z)2=%#RoHxUuBE>0dwoy_j^ z;=pOBOG;1Gg_J2bLgRYR4yMje1>!zR@v$+!RDPoE#WXo_l@)(v9?B-;7Y-+zcDKrG zv@!t|*>*ePUn{w5NPq?ur)1`mOQ0HHR|4i>ErgjW`g0ov3AoCRRZ5{8{lz(mhcGwn@5}eW* zPK`)#EQes7QfqdWjg4}3QqQaet561+3gqv8!JA_70X$woh;i_>yx2H6(o@8pfPVz6sCSyEQEAo6Js)j2+g z0oq74v@ANOV4woxpbc-aU;;MpptCD*KIW%?MqS$em<^%tc}0J)7-l3$;!?1+oaG7# zx@5ZuHVV{@zNvNu3}&+Rgl4J8zqr5ssYqsWu2>YlR|17JaX8c7tdBk#`Tj5Hl`CcG z!26>NbfjxU4Y$=@F2h?y8RQx6^^VlW2KVr&=>l5bI&o z=h1M~I#^u2GrCocLhec*5^y>hJ1;PSE*IyvTi9jMV1)qK-{+P?ayPVD0SvX9xG*14 zL1W3TgTIP?2k!C?p(#ZwmGfyOE{!xnF%bpJQm+}pojfZFvV`HruFTBHPwLoAg@Zm2V=Fi2yhiyAc?q9C#z=-O&4OWIn zi#TTZ@M}@vwDpy@+rR^PC*&<`lD3V0NSHT_Ml~fbjTaiwd@K$3N#nAv1H=K|*~JvY zqz2#9WuTv?MW(KsktaB6h?$e^s-#v+^*l%w4l*`A$LgS^fU)dE2B|e}_t~vPE}H#Q zBxoFM4&(IIzdLQ1EjbcTu*YGqk(GJb^TLE9Se#pxtZq(PR9Jg^C zdPk;lvLIC7S$k|Auu&G`{D#>?7>n#Zbh7ua)LZtrJtd6lhh`Wrfq<`n)3IW9k72%d zUA47*#ovWOhM-<`c1+`BVs-MzVrc&%K zdqBiM_|Y7(CU9hNS+kN>IbV266v@bp-jSl4&S<7kD`7QL>i5bhgwa$X7_j^}9%Ci+ z23wFy<&bcB1{{Hcv0ww*%IO(P5S8bJGBgMU|8%`^egMpNC)a{wjd@pmv?rpX&fElK z-XjY}!20cOBo^LGh!IV)5lkve7mC#@Fy`7~JKPPShjw~+L5=)h%-ut9FYmfO{Mfc_ z+qUzKZQHhO+jdsGV%u5Kifvo}eWvek4|bi}Z`GOfpl4loSNHR|`l+j3fr=}+Ferf- zBSxScY_2u_4(kr548O^E^~*qkD?6THW!y$+|M>)V1hP-NU`5FhA_^Y`~X=A5#{MS$5QK=3;=`_>E~``vq{jze{#-`A#i4BGaCg zyl^Q!;(YFZ(H_>vwz1pN0)Dgh-6o@AeMm%Z9BbUST^IM?3w?VM)blWOjzX?3V#18H zfZ6_FwpSeAeBbLExX&qqn;ba8JRSJ~oocX|xFn}rlD{$DQ{ZUWW{l zx<_p9RDO=`$ctLpg1B45_xSo_0tBf8&^~oT@XtmVSUt1>s(cr<_&7GVn|hZAMS63>#sD04{eML@0;-6wIdJvu6BQoLM!DA zR5)7hCjkR@oU&H!5|+nAd@S8;yRVyqrH%ONiP0FUGF(h1-WS`>dFz!d`0Iz&cNlBD za0=JVDaq?(8;Gk0eKC)dD9 z9ms=$YlSUB?bB&8nj+xB2?!~BZZt0H%bKFKkhmu+;1%GEo98DOR!{gDF=?zSB1#kF z$q~T&rkI%C&pq(&XbPR!i({&Gs1B-ia~)ZQYw*a{Y5*cogDUCvzsZ5v|5rH>$3Jo) z&i`@_^w0J@4vzo(8-h6hP1?iG#_^w|J>43c_J7RG_t1AMN` zJp5Sp9Iy+(5Dt%MD$))SCJ-uoWzkz$6rbiNQEXgE#VWbr>o%T@a|pO<`dCPiYs z{3=Cotx$Jkq^MI|=vI}b&_hy(gmbfu8)B(-o2b!kwzIPa2DDDA`6J4kWT;+V7}1{( z>kUCjHLWZ(@uoPDD-Lf4rzA6&;_BLEsCY>~Z*Ur6+DV7m;YNe^8moc@4aQc%HL||@ zyCS7k95zoO6ngd``8`^0l879oH1S^xJpusYpE0Qrw_KT$qT3B^>?}HO2~;c;8yiR5 ztke;jl+vwQIJw#^VN0gEZw&c;41nkWLsg6f!NSIMFGH0U*C$D5xVQyd9)C zkLt&oPUO-J13VnD(?wpEXUorR!}gLit;rjN2M$Y%RIIv{Ex(guYqI1?rJt;H3ANc;1?l zRSfG}(`i(zh<>5q>{aNPijWr9y11;J>^$R>12OXhtO*ce^Ad zn#E%0VLuB=<(B6`#H_1qFBXXWFb2J=M$W1BrFvdDh7A8o*zTS#v!h@!t!ZTL-harx ztuIEt^#8hjKF^qXS!LXbWbBKoDcJ7m?CO{tnZtZDW2k?4(Qq(`F~OWpiC7sA2$;aK zfh%CkQV-bXaIJj{VEa zRdclE0k1n|!z*CrU7wJg<67ig(gXRJx1(UV2&4k(8t_LAK?3Q9*#cw?ibYzqNhUa; z4nhVF+LDIY;8m;z^y`$AM3rbT2K^PB4NFw!@Fh(aNZT12N!aWJFT3-`LM9*Rb3lQQ zLgf@z7O^6Ly*bYDzTYV=B?h>=Y1 z2W>}t0!qKir$^GgriqP}@l-+3uYCBjgc4Z9tMc1<1VSRGsnsZW!nTHPe`5o?A~zLv z)JI@k@gaZRU!3K;w_t^_cV$)1SwT!U!ZA*PL`|*CccdV0u%1AmoWPP6lb|##sio2| z)v=hFyH`tN)&?1?@fG=sUicuS@24F_r97>_0Vs~gYKuHcJM*XbY}{z=h$}CrXhG~1 z74W+(R?|3Jwfd2uMB>Pz+INMTM(xl9`CV`Lh;22ku#ZH$m@*h#s*uNS`8@}Sr(1-w zWH;nmg@RRqyCnuR7j}Af-E@r$_^ZUjk7+Uy>wpKyZzj=t?53@&B+6eaLSac_W2t0W za*x4t0acsty!`dG=|Ws)1+W$G0Hh@$$fN%g|TVFNLx>@C2Ux^`v7Sua<&F1K^7regsuXeOS zu6ljwBk2*b=WlFdqLNm((Iu)D#-4s!CVq$l^=wn6d;U-j}}gcGc(v z=F2&VDW(7ZDldG{0~zu!B9-;)UvN2UfoEE3Nwr>-mH<+!HP;SedYZm#cCx%1eNI;( zB%ZmR?~};arutsKm04-)9sYoqgdeCc5}5RY+_JI#l|;iYyB1G=8cNr()2fD;5^I!< zET@ZU*d_XV3yt9sWwy$`{3y(Cz##uGyWUBT(#fX#v_n#35)TX>?Lq7zs=F_^K8Sus zdA7blKk-FQdF&G1MPV9vZJ$Fn3q(Eki`bcx;^BsD0ese6xT~dh-#U5r-h}n7lotUu zzGm8WXI%|s9s_ILeh>j>MINb1TrU^yQjZJRO*htT}@kjRc6^C5DIcVy_k)T1Ih zA7vMKwT{!SmpVDu_}apq*3SHU{z0P)Rj=9krmCIaDjKB!Tn|E2^PDgtrqP&rWXJ&Z zlJC_T`@RY<^V49G|CaB@S3Ii&5W>rRx5X35zn<$ntpc$kKTM$d)jgbb_U?$ke>WT| zMbi(Szh0RiOyqDvSgWS7hq_jna}ktZ!?K1C+e~W?jA0$M?qb!UDu1y zz2vX+~XOyk!tYb-%Vexg*92)he5r~+z;YB|5%f4AnJTJUSF*f6HJ$ggQ`TPQ*$no?w zKZ%BO;KPX_$+&2GAG@bpd%R7@19*}sz+V0EYn*olq&E?SV`$i4WeMJFfiMvj&$Ehx z^M{drrWC)*tJX|XyUu~*^e3eRa5}B3eMg71>#vdT-$Pt4&#Pp6`WI@jhF!)M=<>FZ z`t2fM-wMhssgskIP`tz9dRZV~Xgp0|Rh92@a>r&hX=M}i0DkLG%vYC7)VujMhW52v zdx(3yT5}N=1N!4M{PU-XAx4KlEzf?khpzBCRkd>~LOH{LfLN38T`oc<6}Up7nNooz zFD2F^8TxZB{l3%3%ZSay5Q`ZPfZ<+nb|fU8rfU;CQ=oavBFI{4*u;cG5r|W^5*$e) zPUzUiuP+9d7-iEwRu}we+Co*6tQsu+X${jJXVwZ#kV38%7qeHCWXpmPPjb$Q!HCh? zpN>|_S7~3yy~xi2q1EUpVv7=Gu^D{sDK+moVfIk-zE%`XAl;3nlU0ryG0XTOkYjM& z!_xOxi?45^hQIHVM$oT(9SlA_5*3Js+p7%RLD<eMQ z+$h1euPg8pTr1%+=@PFQGnBv5r}ad*hv-tcr?55QC;7LxK`^bC5;k@P<#x6X0k^5W zm+AfAd&8x_=TcXlM_Oye`?it)`Yp011qZ^&+h*pj`mn_#DUD33FIY)&$G zLyk3k>P|8Wh&P~+VlatvG!R#c-dR9wsb)$iBmz<>quT)=&avlGILuapPIX2?w2xt@ zn0NUyc=Zm!F^w02%GNOPyb0s{pG0PNX+M`M%qC2APHRz#gxWrRHMX zJlZAV%?bT6>fLZZY%@A-I9&j}#A);0DMpMTfdXNZ4uW4S9*=RC$YI`Xs%WF!d`t3o zpjJvf5wTkY0)B74K$edond2_?v@j+P!!IPhk>fiop^$=HJaW#;tSw@mnu$4C-=7g6 z?p`O%;#|t|tU=7-{3RDUK#r*e>OtehfA4F{>CI)ar?nZVBeOpNZp%fUp{YhKTG!l> ze}VtI`Z86wO!_{dOnneQ`=xJ9ZbsL+x2_BuXJmahD@NZEUODoC(u!e_uHDV56f=kb zi1DDXzEeV#06lZ=q{G-|UWUo^6Y=~d$l_4WdZ$jv;ef!|S!=m}@67;eEr0bU1fjm3 zn*!SLaJk|jvB~jcFHKbn@h;W9$^NH4AE?M zW-l{lp(sc`QdX_GU+4H3!Z{yh`*LnJ=L_456+f)~J=2RdVz(=r+&06^NlzqWceI7` z1$+n3^l$0UkwQ=p3Hma<{jV-2s_x*5AhOsDahEO0-tx!7bN5i)?t0g)z;D$*zq%vI zUHrt>N|=xDfEjLQ#UKT&MKp-?7&1CL(ZQsVnLa{q z%>zugyr`zsmq4ao7Qu9c>?;C^3>i~A^_4pXy4HSep1%~K z9G)eQXIv?^&xej@jK(J^;4fZnwl0+1b^}#k zo&z5!jQ<)JW;g3y@F2o%um^?ytrBWK$iK#w$|&R2e~CJn^OfYqnitjn-sr`88+;0& za5U5!Oyd;h$Q6R5A;B-->G`>p`6S)0Z|;a)hPl-e|3dzr(v&dvM0rq;d1}-_HyrB| z-Fd@ANO4=nZ31~0zo^4m@%}@~aIjx-YK3*D^iy|>`=PM2yZCig5Y8V?*39ul4x%m| zMqK@+U!&C011J`}BzXGQO`Y*ZzR9{kO$nV@BBRbxY^-miz@LBc{00 zsYEHjzQRk@h4<0ELb}qQ^sz>i4q3Sq>Q(E6Ix6&v+t4q^K1a!qN_nmOaXb4AdtEU0$w?AzaB)Bv zNWn4OX9T>|4w*ZQtfu6?QjUn~f`8_v*~}4L2y-(SfA=`f`~tQ5`J_p7&9Hu)%WnZ! zKxG*VDjrANF*;LCZ0)gsw4=NY7rg*NB3>X2;CzXu_w>HGdQfj0+bnNnq_bRe#ql`N zn#)CRILb7XxaAjYjqV1@d?&+PtrltqNrUXch#&Xv<@BG;8(RLRrC~Aa@i@h>yyH?f zZTpR}S$Ul{Mu3Y8KMS*2t?bzp6}>_+Pr8+EARzZegi9i;08kL^qVFp_$pEc6qu z#jBEJb?c9}WvD*nCCqL=o&2kfYlB}~Oouxd-eEX|@kaG5!=Awc;wuCdAfPGk+b4l> zZ*XHYcy1Pw9Xyo9?hsnE@+jMioZnB=oP2ZyM@^e2-r0lS!PiG z{u2;C0{OH?EG9;A3mu1=s3-9-@oy@@l_Hu4w5`A0}6qi(J(UE9NPqX31 zYarbQD3J(S$$8ye3zBo5nClZsDlHyI*_1E-=p{sGe2A>PhD(q8LqJh^S#!9snG1ul``SQ>mdpJ1rI~DH)d;ObOAxwT1pNt&q!+>)xHp zlYj9|D3`EB;SDGlB3#c7yS|y2BJ@oeZfX65RqtfBe^KnLn8r?r9q=j*ntdoQU>=R6LK&W zL`Y%jBUCcN)B_M5f#gk1x-;-f(s4_{eBSn%Kg1;H{4wwxl;6Sw;x$A{+*$ylK=Z;c zYhIlid|!eZa5dJS^efAB$3=xM`_1$ke1$JqGJ`LtpXYW1gFX15D;W6YpXGH!ln2Hy zL+4E)@#|Q{2EjdwBi?G#@%qu>M+$fyaQLize~Lk@ zS)h;Zm0BQFJ362ow#+PloGpdH$qd5V0z3!Y{B%mS@x7sBIJsLTdQplVCZX5#rARgH z1k$JXqsd0}Cod8w=VKqhMXtsdsRu$qHAS(k1}j0f5Ay>`rAOPTPz4wir6HsfG(@cVM1JqNQCs|}vpPWvM zr04TVfu?a=i6?~!hk!bz6zm?YoyZ7#!e365O;Gqa#-wQ_Wku#qC(B5J0B4nb1P@o9 zST${LB~`&+PY#@kV~1s*T(|lh*(Mbr)x$FO_y;>)Tcla2f(`^Yu`)<^0#g%uJ_JYsTVs2{2>YM>YNw31?HQmCb5gv;RT zG%{R#4S>pf!(2G?Wzc)(a^-O-dwMDU^~u7cDEo=SW5GgsN;P1rR(RGaP-;5cmM8$L zgRtu-Db$DtD7bwk88IC)i4HEO(u@_+rU`6T47b#b4F}n!?jMqM7K|7gb<~84=;g$! zo!=#Oi5BZj3dFYf`a5JmnH2OZ%q6Sknu-PCRTF`ol2?37H?5gTF){l>1mini({5~e z&!Xxe)V8pjO)<%iCE>}6!UqH{Qt#UKdxjXa`H*f9QCtGyllg^2bSETMQWihaNrn!X zG{LwJAn!~Cqb?}U)FSw223*ky_-(`VyiZx)nEEY1sVT7*HYDHIQ>lpnsN{y0M&QF) ziJSh;M%;|zA%~HszoavQFq5Y?wq?wLj zC0X3`FwAu~hna#1I|j%HI_4kng& z-4`6UQWKo7aJJo$!x@R<^XqD<=12P;j=^w!$r${%2KC`o=?Jl(?vl*yqBlJU7qTVr zrcttadrU;_X`)dtB;n(38we%2y9~#KlW$fzl2oS245Aaonoq@pS17g!+VTE3Q^sGM zszpR2e|UJjO3+w(6gXH}UwrU%uu)~It3=LG;$E!CHSlWR#gos)crf!GC+c%Mi8@9VYKGU^1iKND=TiRid^!(M>h?tV@udzD7`xw3uvY}wfmp0RX`87elb($M*K9al8a2}7E_=J9z424{nAHgyH&y`Q7~dMj>t0B7c?~v26K0L% zYh6;(JwyK>(mhWb6KZ{?nK1Xi1^v%yNDLqICS0vc(wG=tI*Pn_G704nE)@&|vR0f8 z7r*QQMj(I#wAjr^XcMWFiJ;L*tsG>hp5K>e{0AZj~Q+P#GT;KG>t!B-rM>(9FN z!RL_N5Tiusob)=29mntRcZQw#MEWXH`+D2DN2fq5tcacyJV3=qSFZuw%r9=qgN|4Q zsJU=vfp+OS<*EYTqGM4Tp4AVf*MG=;(M;Dp+c?vDrsk~|!oD#j@XHEB?aWV@3OuLt zBe^Q3mGvT{_eK@yhn#siGwAzsVNRVe&Wf+C-0S-GT6LiITGuz=PBV#$MA%+D%AHM+ zgRGRtq=OG)Np?cA3t=&l2hp31sa@E(!;}xyrL;a0@FW*pqLXh|*FAbEeWcZ|@ z)L>@a=3aJ8DU@Rgmy8hvFXAw%to|K;_!<4>UD+>MRL3g^E6VCP3C?)M+yiN6DZ!#T*CjYSMR57?e4{|BlraA$8@QxX#HM zZl9mFQfuJkVn*H#9fFXTeae18_sSRU9s%{jzR@bh85u}WL&|=d+E3GjKtkGY%?VDJ zgoW- zyA~t?klb3Erl`dumvtYkmUp!^8&g@vHWXBX>U+cBlo_QF5zLTJL9m&0A-1_?5IeFh zTOw4w>k?X`1eh|wV8{{;kwJQCeE-^lqt;~DvS`aIa6q= zLl}rpSt;mS`8o#yDZtRDN*79;4k)ly*3b+WXAhRkvz=vGG)$+8luQ3|n>7~>yyNUz zJ)c6ks0zYbhKx!vhR-9OHV3#pf3JUe!cwV-o`!{F1#lom@v$?caa{t{WY&7o{MS9v z3u#z;^X}Y=o?w?JR6%h4Pq5)~JIvg-;-(7@H0YW=eSY#pbK3N-M5C0z2EJE6uBmY@ zLdC~cwc9yt>9K?Cr$53@`|raqqTd;BuiRPkF6cMbbofJPf0#!Hy>l~qUbRq(5jk_kmO}L z8Oppb+1*q$s5B6OJZ?3X-{wg8?H^*rQgwC^jY?A?8RWSTu(a#grVzj{W{VV%fPC?? zXVubHY49u+y~WRcNS@Gb@Y4Qhvh8~QJ<^&az);&Ayuo^{lQKH9eDe=ubT((oJKq=d zDOLnXwi9(k+AEP65vF3iqC6qggIs#4NuS>}KiPXUF9FbO=+Z}_;PX3kgLhr|91mIL zspo_r2JY-leSlWevr%g~-uc(&U7wbL^vLxj&g=Udpj!os|F}#HIGy8;Hu4av7W93> zA#7yP6eHA+Ma_M8_`X6miyx=|(}9mIt77p_yJ5e)c4YKr4=|LKJdP} zIe*AxWx8^Bu^Ppq@n+!y9&)nUb80wqJ|GlI87Ly#j` zvm_?M!^dN^Tr_OR*SZHbmR>(ISBwtoQ3@eBFSk;`9+TWD^(8m(=gye7ms{3IeoX`7 z(j>)_enMe0H>mJ`qL!+F!&bG*57-j=ilMQRGwH&X=1cjaob7JeWtRXa12f@lZ*DV+ zPYW5^U$E*p_>kV{*0^hYU~xmS@F1YmTQc-$ip?>+`!U-}92$I!m8&B>9B?xOUh^z4 zq!9)ap?pQ`3OP^$Z~}>_CV87=##$Xb(c{kmNd)%5AwjmfbHw}?KO}hPt`A-D(K9Kt ztfg6I9w{k4rSH`lNRQ2SwVr~4ZZI6Y%7>HULDk2Jd%5~zgP=bHsBd?N4Q9ST4nv_D z@)M~3X1npPdTyV#wBE};EBMi*Jr8{}IoTO#&4=v9ztuw9xAJ@^e!G9(>X0jYwv!MY z49|Rc&_;(-wM6MjuAWD9JsT`fLI_%ig9eXE{GndMIj-_?XE!oeb_c(-n{_+eL@2Zj zDc+{pNgJ7{nf-BkzAYmaO{li_cDq^WeAu)RzlgpsoD^MH%o;tXYjKYT<;BBz&=Oz& zP%jN4L)x}on9ZJF@Y5Ghngw}1|E<4bfxR=7ZyquG;79okA5r9Im5Ugd0Jm4>NmXs) z6!2&*IZo@XoD#np0|jw-Xy1?2&8%fcv8ptPRg5(|jOHz>Lxcf0+5}Jkch-ju{5A@* zo&*xPh9LR?+ZQss#OXx)c%Y>XM7#|%%~VtpO5+RlHNVz3OOn-5#+KnWefLmGxQ-~h z7rC&6-N|w-dq%h(lsSXAL-+>7uJ8_ zLoafJ%$cDf!V^j&;8v~%LaRiAZ!|LwH1tF`^&kLjS){6+sYU2^w_%sGN3h+g$;?S& zp{j0Y!n=b7x?Weu!hDysT_4N9xQ2vc3@eAEeX zl&ikqG_9X|Y8rEYPb*lM5744l*gq|7=$bstnvS6kXP21(O~cavuZsz^J-+Z4W3su8 z?O_$tD6Wlh!xN}*NVKQ^0*}3B7Y}Sc{(PutQ1QkyM~a*~N1l8;rzD4S>B|IR5NOlH@(n))cOB!XzoQS7MS7Vh> zk68vAlkM696qF$=lB{+QO?KrTmigAJ6!Tu7#x&6Z0&+xA(q;$~r)4ceiJx|9`zJ2# zT;?r-C+#e$(^S;<)(eKj-DmFB_=*{J zg!LME390?ucJz|@aE*$%AY?MJ2Ns7(Md^jur7CFlb1B`Z+K7f%tDh=JV`KtV7JZ8~ zd7_&|vw(xI3jiW3C_$@g2JCJX&nuwgAnnqDAQHN^^Q=iT%}Sk@gNMcXUZs{){o@Mc z=I~1VNB81u!=x#a(}$w-zH`jt6)_?IntPe^bEMq_aR3Xg1(KML!AH7K2H=uxppQSq z8w<2J@C5Y71BY6`@_{oQk8#MHhhPLoMd3%xfECcySEh$+U*99a1(l@f7d zcbE|8kP;P1;Y|MSJH!@1zAoZY1_fG^X{a1;5fx}Td`i|Hv}IzpLY+UVFa#!x(#^2ZE}}|X=0*;C=rT3|fdZ7!4!ba8i`{tEltS%R%R{wn#)JpihH0^W zpf>DqKOZRec!#pg_>2|xi-!}{lGhbA^=1!%A%s}$|NPV|SeX`NMTBw6C=haSr*05- zKHTNi9ymgv7v6*-$jK|h{y~Ze5&KYS``URV**a*;u=D&`_=Mh`FyySYU?g+B`D(Oc(Ty|pkCf3wKUHqaOz5vnWH{4=>IQr`ZFbvBNOdK6?}jz1)q>Ya%0 zi$@gvN}yf9mcR&pM9z*)DdCAA2!>&f3WgDX<0Yjj6T;l+ga8~jcV!zDYe~Mu1P=?w z(Tm)u0^Ejdxa9wY8B9CLb8p9ZPlLd`@mfk?HkL&wxxs8bSS9XzYg`ttXP(_es{J#T zWfS|Src0^NGBypum~)i7o)3YK!5T;wOSwVzK|ddhDA5VG%81FC3TjmGFF>da#!gna z2X;B5JMf)-{EK`?zc{aHLbIXVi-V0Gb7GVDWgqPiT5*{JVa-GlVABMiC6|?9r*%Xh zP7jL-M}6FQ^6+t#0PB-ho8c3eV&5R+Fk?1M&TbCsN>(l&{0A^W>Wjo>C+-(-(g;i-8q#S9U z)wNK4r%r!t(#hB@lTItE8i}*fxz^rKFrCOO1YIijjXP9QC4{`e^Z?8H($slv4FZR^ zs%eY|jped;i1x-x2*a2{3?2vwKr+AgsAPSeYIBW;oka66`!nLvOPaeEpa!?%hQZAX zd@}!t6=u(s)uqAugqY-J|#qVa*9S^J_T&$Th-IgLldQoGD#U`-h@T~?)3pg3HVJQdUpnyVUPHB?yd$eI=A%&xkJR0&oF*AU4S5 zPlPGzc3f0R)7V;-a|IDSQ-JU4J1q7ZlLc$34O;i;ZCoL_%c~xwk3@If&3>rl3nw{O zG8|qBZ66PpF0Zi?4Jq>tk_*;Uwf7f>{?FX3Le8gXA~&9**;;EBHHkQBW{Cc*itFH=dUE`}{nhj72 zmcZ@9;vXUkt||KgJPN7mtVJ8=_dRLPiPe>{3&f~w)0a6%6C@ClrF`6w-dic3T%2?L z4phj-n{2|zNku;D1e!rOACPeZZF`DLeL&P^TM0qX2@sb4*{xD(;Y+o%kL*Lt>c{9B zf4G?*u>Y6B-K6FBr!PDqFZ*At(#kj6rTa3E0!LEIpuky9gy30 zav=o=P}rqzT?-oOP4~fW?(Ld$8BN=Rr&HkD4tt# z2-AE!=^6YQ$QhrZ?2=MM?X3rLK0b89gn%BL-xV>no#PKxA@B2@?Nzg97P6MAC2jCW zLBvTvWz5D^^lZNphGGd$`w#P)&&jjv@)eoSlSUvgQ0`SE+rN=0+y6?U?EjD`$A4L( z|7-^3WdHxU5aPeAQjUM8Qm+3D_N zAku>49QZbS>2T5t^C4L~Yd2e6(&>y@V9<2YBsI|^Dryx1^!5S_80y%qYkxDPB-O=l z$4b~1r0eg;PuZf4TVI_X?%G_eR~E9R+-lyB4+ML0o|d=z!^eYDS7z`cl2l?caw2xG zFB%Ak#3}~1Fg?iz>Ly)sW@mQjWqjd0pPAwM7{8;^$x6sOrBUXaUVTxEmZ6ToX>>nd z%msY&EVAO4NXo^t<#e~eD8|H7RIFMka4__kmBSv^x=O_l9|>R208?Sea={VlKWlLk74DySrJutgvd~= zC21BXU*A|Qr=BPvat>#u+s^a%YJVQpEes|x&0vic0{31Y1E7v+%ahr?oQdszn1f$g@Fl;bd zD{C$HZd>vkg|G&{cI!7gXoyKZSOBfM76DJgJ+_V@<^ywQCmk*@&vD-PB=tK43#)Cw zegq<^2xFYilQKM`b*>ujdh_PQZdtWrXeEYmYn{5^|16F%gOR-oWxNauqU;sYz0|IG zvXps+3JL!pp6{L>2|s(9d6FT*&yz>M@+3U9k3+f+O3g!K)90BNfoy?AiU&ARS(bbs zT~zqjh#ZhW0yfyL5O00)x;ep+%9m1=Z}rGb;QNs@KjgtX;zF_s`M*H&nc@;48lhQ_V+;Z<(a~O=7Viy)O4SRG*HhQO zkt!mR{IPDO-*oo0TRCG{o4FB$Y#gDGWmtfalzyf1*_oMLXtlQP^kIR&^#RF#!om+P zHi-odc_)XG>+h?!2a`a8!Ge5`q-?&z14!~spbJ8@qba~mn*vcFX^Y^5a1mc1TVOQS zN@9Fq^ve~ONZWCUayXAfHfZ{R!*CsvltwXEZkAZs66xOQb;v}!ih#ws9n0`53`9)x zpM_nQLP>aM!|<0SD3_?jzk%4WsW}(cuJ%0~?ZW+3CmSW7Paj@4gW={x6F&PGv{@WA z)`m$o_zC{mPoJI+PALPGjLag%lVxeJHp9r21d2dxqRY6yeD)uy;rPU|9P({^hZD-Z z#1;;AnpmhzA=;mp_kgvGUFP>~24(h$RV9&p}X7a>tx`df~;_LZh0PGY4<1ChN2OcCuuK1_a4(Rzap zjCLmj6ioEQt($SmHdB+A=~WFnw9tIOjPbo$n6QQ41TnNK={H&g+rSM!86ghm)2_ur z_;$=+HbBq`;#W+rFdRf!vCY{Som|mRh8%ZOQ~W)tprE^kWI0|rv`RuG&E;R56o?m6 z*lJ=h>!-6R{>GKB`Zwuul_`j|VR|`Z>o2&umk}E%`jE`-$TxtlFf!r6`tax&H_@W8-W4LdH2!u4T%Wo zx|t`l`bA4969tATu)Tn<&Wa|UqJF|~vLx`&m~4e&FOPv zx&e`JxXd>?P43t=BGCZk3OKJnqu8l?Ren$)sK0_zBQaifdZpaGjuJU$+>9AZ#YEc_ zP^d9k)r6&Q8egOv7i54Yp;V`BUL_v*74NW;5d<`H)4Zh)w=gJWq-yzg8Rxj3lYifq zG)R3vQz_9q$w35W<{wsE=)^|oG(5|y{zoIMA8mfs@n!~($a}1gG)HI@FLs=1=+$kMNf$35tinIkao<$87>JTkY zS|}Q=w41dKy+!^J(g#tG*0;(}cw{CNJuDq9Eny@GE{jlzsM(o6n}B_BKs9!ehP5*; zO2QJhQRXEMfjHg8e`r)&56jfm55?ct2@A>u?{i^4#a8 zuE~%M0!ori?k8#TP*p__Y`dwpn3q1pvqvKB3)SL70o;ezlF|=S22ml{nFZI!D8RB> znQ3>38j?gFQ!A8(0R1w%e7nir5JM#60+dlF*kOKNB~rdiTN!q2 z#F^xjUSb7}84frGX%~;FKQnEJyrv5{au>4rk=-3UwiTl(K0gdgT9J_$zh&2Lm;BNc zaec1YfW~mJY~$@68p09bn31Trx~7-LBXgqBUszd~Jn#vXFJjfEpG1R~AWNbimC(p^fUXcNP=2tw%$8)N33Ia+&DrMYD-<3=7+F{0Hvr z?hj?Rw)TIXY1W5Y2pu{Tr~j5(;RPsub{I@wmg`>N{`V7P-{~ z%zTV|5}G)Jg@t*B0;B*cVvBsWI{EltUlTHyhx(^F+&A7Cf)XvY^i95Cj?POpYM}o5 zG&QhVo<#G;8M}%d%T&y54dhiNz1xQ@ABilqa4*&>sHh|7!7k@P;*S0k`OZCYT(;#h zMCoItEzfn)Y9=j+B--`JKIaQ*IO_)eakvcIu_yaP;ViznI_pMEX9*$GA6XhH0+m*4 z%6bN5XZC~(H66~0o~v|F;e(=#iYEpNF}&7M>wV83?id>#yeU(o=m#M;_kk0_^JnPx z$+E~FLhsa&zo|Rw_KqmcW_Q;B%zI5nlR=lMb;b{0=4mO^M7P6xy%7y^+H%@%Z{R*| zC;y){g+%I=uDq={sc%7eK|CnqCtk=cH}OTx9#}o8iuU7;BLoFNctiffTC8Qm-7B=6ut9gOWnXPwLL!*)Sv_wPwU;&>>P0j(s=-D4b(=4)1Zu&n%(}R z2Wkaf6~lyY1)5IN-~%-$9D4FvJ^W@FC!EXJwaM#cAVeC?Z5N+0387(fX%oB7OX`5JVzNJkC{4h#g@B{9k*UyM)F%Qob@+E zkMWbr2Oc`e0)Fdpy`Ml7RG^Gf4g*y8ZA>|W{voWPXJF;cEGY>!6f)$f&rlz`noYN% z)AXXR6RiHVtFbOnhh<4J@C6vWkU4kC?R?);5ftmOW!xWGiZ~5(j=Mp~IeQ_IEdk+I zqQ3cnGh&D=Cr3&7r>oTf5ICS*Db@9VV_VMum2J8HVO#G1vTgracF4)~fB!2h_rLKh z2NUOi;@MPlW54OWB%FHOH4TPj%`!-_sHlb26>Ec_Y?uj?d%(8r@UXO)?q~^lzIt4>VIvK(b^f z2R2^Q=O%V!blhkjtnDcFO<(8NEk%nG&R^YuF^G(6D!HzCLG0xtoBk35(SS$S2oW7x z$%OYnn5lp{HqA8>8F;Gh@dqmDsY6A!pcu`R3L^LhRc$>9h#ar%Q6=oZbkZqvu;0~+ z_UKgs{W7TJ!f2yP7^Y@$IAh!fPz;8>;pbvbIf})IzN-{DUN!IH!isu-e=eLrX$MA&tupbm2Qw+);W!%jE3 z!Ix3@4Mwij7b0MNwM|~qCL8zU9bc~xW|2hB=*C>l`p{uO-__;#9ee0tq$UND6NFa% zqVOKe3#kvnVzeATJ8_?8$%375xIMQ`_GG?94G;k0qP2s+d-`F((B^`#(o%&I8+@(Y z+FZ-c3wm;tlMrf%hD=($n^nJ0W~=`7VjUB`LJZ119$rbJx5$qg>t1orFmTuo=v8ay zT)iRY^ACju{oNOiS$%X2v>+d4F2xaS{sMR@Y^b!Lcq%8yy5ug(ER=68)hKD z_f!acsj##PR_3>maC9m;c*Y-qO2!_KkdxAg?dTR;3crWipeb!)X!A1rQjT|}tt z4&w?zo^xGb8;llbME#KaWVYZ-j$YxUdIoQL5Hu;xtxOvL8wayb;zb{d` zTm>Ga_x#EbP}$dK!`<766oOo?+#%6YHlqC=8c0l1m?w4sH0$__KxzN6teKIw4OoLs7mgh(ySefWD&-pUI)UDY%+WF=SmF#^-VzMT(XdNeSjD2E5j36{;&nI` z%bR+1KqppnvguS*n+{6>5NSyFRPsOP* zRmzwoF7HIyIAfcZq|mX1%6U6P)B&vtRp*6_bOlBVj^w?NTjf?h;~6pY)d#EBuB&J_ zVTsvW7buvTgs5)Qg%u)M-Mo!&nPFY?BF*dsDlcE_9D8vHnmJu>JL@UTkRk6naS)4` z?>i8ktncJa5}n>YMgr!i=F%7@paVIx!oqWi*^`k;4{fEtupF}KiRbJljOWA3KG)X? zn(EAZ{k<5skqfK})L$>#H-s88p*U48#aFUSJTcCMGEfrvy9g}YsalU706WW(im9#C zP~58Bd^_@Kin9TGtTFHs`@7j`NQqFaiS-^XSDWrP>kB3h7S_%3V?z{uY=0l;-ZEeJ zaT0m|mhKXiqTpX@liq^YgW$`!mT#K6M$Bdb(1H-mdcYzTCh&hGW?KiaN>2{Kn-#^C zy5|A-I3s3daGFfgs@6chyH0yXy2gXo#c7AD7!aDGzjmkteI7$w<rbEKECN1N3~jvEcE@Y^f7$I z;f7wfe4`jQE4g4nMYdSB;#I9L7zgG7$Wuevd$-vBjmZWOvM~Bdj-TEXKoEeF>>xcb za*JQ1W{G(X9LN>#hsWw-39V}rQN9KXcg=t$`4wCxHn2Ng^qPFn~fC zHz#6hc2#?v@~CCIVnPHrBsGHu0fmO+#(15{Ea3Qd`ZtaN< zN4`X=myY09>OWS|?0@2Xvr60jcQrcTt`qtmjVE{7Uq+LJ{iHFZggRx^bA98vYSxaV z8q(0@>S&s7G4ex}epJ4&iLI`Q~Y^{oaeiTK-IoCZNL-f8{?qs}$GxgZu^q z(nekTU(~i4<>Y1T70?lF@@LW_*Z^G3aOlZ~WRShqtAZ2H*WWG=avHXgWKq)e%sz_v;^zX>{bg5Q1{q4v2K zdF0hXV=wo;Hm9LQ7otJPR8N?;mWYqXEs_XX+^H&mbOGlgCX)v>o~u@?PppQ_eG1Ss zZ{4S_c~%r^ZnxQYX;r~IcQ&7MLC|#ilvFa~%!wujWdJ|Jl$X3D5pg92S#RKz#UT(e zZHJZmp|r0~OCz8Y9?Jppp}s6(MR+ssrZFeZR+qa%+}YVCqtc22mX6OP9uWyfOb6If zJ%rpRNKV2BBl_px8u7^Z)04^4f0kEYZ-`j1O3)*e&nW#_{i9BY=hyQQ?swX1gD5V- z>ky^4F2O`^zQjC`ViCe+qm+%jAJjU#~@wBrG(4jPqiImpU?z$-?? zM~oxeADKmg!b3(7Rh&AHSdWp<<|DvKoL#4P$_8F1dr$ka>Mha!)u4ny99%(~D4-N< zbRP!Ku~+i!_8% zQdIVS$L;FI0w&PkKWy81(01}%#>=lsw=p{3aq{Qp=m|EXK58V&(})`yDsg@Mu(wm)cD8f5YTll9f+D}1%)Cs_yBj_WTM zf!1k%>P8R&%?*fOk^Nlbsk?U@chJxEY;5djyWZ24G}EHBz-_HGrc33eUGY}_-?3ex ztbt_p0$DiV_m7X3o*!h|{Ip2@*Hx^>S1!RwZ69Y02x|~V((x|NYhkO8jRJ66k!w+F zi9mfrmzk|-itYRrx@8EWugfoJj$%~q#zL8;ar~LuMRA_cqz>Gja&^LMa`8-u_PExo^Zi&%wkOG^* zl1|a1(EC$FTUnpR)c_uiOJx!|6GsIlzUpNt68=ULV!8lOy<|HaFlmocvZCW_0borWZ;Gcd!YN(h@NsEFTrXOnVI5(g>J7Qh7j)IkHGBrj`7#hTS{Qrm@*fwREns z13)AJR4ZJsA&|17=`&6~5%b3_OPs%!F|{||JA=+S1WFb?$%##Xba_h(?SKFk`_;%# zOH7J`OIanPq^qCFZkOh){Rrv`77@V0Av~$GXUB5E3Ar=jjXZQkTGmR!aUI7QC{9Ge zrUc5mL}i_2Y_sd4ix0R-m@~l;1XOQ-5(+Tl!9d`A-P&}e>5fYEOa@9GbaZKT;(ffH105HITq~Q8L^Ew;dzmnJ4=>PY;&c^U> z&g=i2l#Y%5|N6Yn#_-R)&cH;^{$I)KhyQW^`M>9Nrq4wfk<9Ko@ptPH7c{t7Z9Ng- z%WF4Wv$%S;SvffJwF9GvUvGb}{ubL#PbRU4_$++o8B-=pWgN;SJ5waKri?>G8Pp^S zK?3xEKaZ3QdE#mWMi`KJYnKy;SIUNKo%WU>md8tnS1-6ko@OMs0dlnyUJOGy{q<`P zhsZr&w+9=&L5MwF{uz6!RN_iZNhwgSod-;w=pa4Q-vP;~)A2%Bz&okhvLM$KcD&O8 zYbRrk-W*W}a-wA}5dx`2ExoYL=yVJ}Gv5(qf~3Y}kf;&JgYmlqH4;^xzBESZ6o};Hn>)1V z)BJtK3{ptH3Z{IblqD#v6CW*2d@XVYZ-oxv@}6fz*na;ptK65C{tE5=mm73e4pPT@f+TZWeBFVA8-B9B&JDv8?QP=94KT zIWCvZXa;EvQME8VE)-gZV|~^s{SGp#4OCb+lu^GNMBj6;+YN`B3a4_{ng221aBvN* zYp>>4gE)gpU5)@hbaK&7bKIzRR84Cq{d#6qXBRaj{?j1^F+&K@A$%YmLja&9Ap*e^ zvyslFVf#xYdJ(V_^{x`T^{C57&zJVx*>Sjw4Kj)QY#T32cTX3Kq(C|bT+MtG_~FV2 zw!%2Qak!UuKbhIw3=Hs584|-lSz>q;PoQ6{lmmP6hpi(WbUwiPC?$Z$A+=dW@Jqfc zXZ&&1-&UM##Ef5Iyp-09dO{gn*n6E4RAxFEl(PJd;|0W5Z))B#vpVvR7MsFKH`D8o z(9dLz-VBrUKv4}WdXHA8zWTs@e%eaoZujV#890kakzNZU*}!GVEJ?r@8Xvt&7f8zH zwpJha@v7vcQaw9nn)R<Vg)PZ z6+;N8e$A{w%|UHtX^ze!DZ^VhK-=)Q_VHgTxli%vaLTP6Kosu3fX2?oKTp{`?Wb9* zf7N{iJQ=GB!~nr}AZ@hG0oUD3;Q2qEfpCmc-puI&S7M2dAL0CDXA9;7Pxca@Xw5J? z9iTEVH8_hG1W+$G)hwhm!q$;8ktCg3C6a`xBA8tb&G05*I(2nlcT`WHS)mVirD81P z5otGj?axf))1>YU*tP5E>PBMeLfQ8*44CawMfJ{edD?pbO6jzbI%zLBj-;Wuw>+dz zge5K*2BF?SP;RIBMxZtHSVx5Xp8ag+NSvZT5l_Ed4(fgov=^u%3=57$1~aTA_#BLq z_95GI%?N;%M@r7x5uC#fLQT`!nP8`P?2DSGfHB||z67Xj&ez`EOfv5F89{{=}V zFCTE?RrJ*THp`XuW~a6yoS`pywv+GLD;TYltinODnfu;u z+7iM4jE||pZI%L$*mWAS+u^y3_8yIN_=V@v4FHui4KN7~{K*B>$?SK8dmEWNyx-hJ zeV-w^K}c8sPB?&L{y3xQtLY-!|Xr@`H5U-5PRm|KJ(ml41O+v1CKpT~_oR z3jgUQo|#H&d#bpiwP2Qrr`pv6EHJ8kAV{b8L)h!GEZe+sCHa=s6Q3;f^HwM>p81(^ zC83<6X5Gp%d`8eRT@~L7vG;yNB2}#YA@X@Bt|{xK?j>h!_u6#IZ&(Lp0dPbZszgBa z(9vN2RuFqTe=+oCX#d7C(#8lRGgC3&Lx9qOxA!^v4OqPk<�^XS7ueZUBuY!ROBH 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

w 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

brci2O)kf?5t5ckQ{IUHo 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 L^&r4_1N8|b-lqmYnR)2duro9$2i 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

xlSj!<3_hhpNE$|o> zf7b_g>w*Wq&g@d|{D~|GSJ2JiS2tfZjxXvP#cZj$n~Th;iAu4J1i#^}uRZn5>hrx? zi6@`=&88AjC`hYGbLd`pzr>V>M!w8x_P9lz^$G`f7TMyMu5@)wvB-c7>jL9_g^N4Z zSCZ0^)TeBfh*fP6g8|ma*|8U=W*1n~vEZol>0RKRNw^XDI|hdH>7ofp=JZ0*1h1NY zijKwO9dl4YZ*or-1_2wCzOQ^1gMeTshv5y@l;gXRGuORF9N9fa93OrB_V8hu%e|Xt zOs{R%J@@r@k&&ylQOw^OnfmrBwMjjZa_gGE;)~;ig^bp{#;c_+-wT_ZEtbmabd3o6p3Gk(nA^csp`#EL2p2e7P3Vd7*6JY_k+=O#R5+AgEJ& zy8??*5Xvno-%^|G;`_pPMoR3D3QwR2dv(j%*+Hlk4%}mh*RhXc%uWBei zdDfv^H0kL50zdqU87rg-?x*JMa7fL?G(Jy<_J)D#5_z9Nyia#;Mfnw-E2@jCFJ59Q z(l}Cgk;B0)>h)?JlcK#9?=}`S{UBatmF^X^ZM$Pl)ZOW>CdZVQ$L)AS=O=lK73Qi2 z`Pk4Lzyx*aOR=EE=15NJDo!fG_~k9I-tz|@PP#3S2-%}K_dksGuFUOk?t`nz#f)-3 zkL$fHCtO(m<~zlI^XBfk`kTW5+-|JM$!&S6hZh4rOT~<2edX9mD#3`TCZ=;6PHW6F z=6pVJ$ISl8$pdk#raJ>8lisrM14Ek1B&LAjo~lGFHX5Iqw0p@vjr!i&1=rGt4Gnh( zhL+J!^6l{7*55u(AZ_uwiB>mjjM?IL7gUq$wRnzw(_o6vc)`U&{f_fGnI^pCfJJ3S z5TOE(=e#h>>3`+(%*f~b{b>nf&*pDiB``BSho(k`h4yf`i=T0cn2?oOVhXB`q0DZL zBh~$D0Inkd6|mcw)Uw&@rx4nrR8&p2V%6}tIALz0#L9lNhFwT5tW;x(0@YZ!r&32q zgS{5tk7XDeEEVG#oZ=m8goNT5p98GljkzD6rYx}KB-fIh=`iikmeoUki`-7TF1%J# zkItB%R*gmK>9Gzzc{yo8K5xUR^F$@mCf3myDCcVu2NAYq6r|q`+xVggM><=+ zZt4q7gAD@rgC=d`ea*(7V>J_#YRSPWY~l~}r{Cp<=NzS%wQdt)QCc}xsnM3~ah}yk z3mCyVs!v60e=J-R38LlT#8dNbK6AR$w{ z7ML-)*RpoZZ!}0{HIzeVea74M^qWSFr5J58b|?@{mMLARz0FPQ@y_~sT2_?5`+RSw z2j$gy-nC({7u}@+#Sd;JONlL&7{W<|osI5?+yZQ-FwvoYyX;pKRpFBkjSi02+19v? z@O(E4S2=PA>-zor{05OXJ?I|1sT-y91Zdc4n^qTpVbLaQj(9C*<2k`O_GL*aU#ZwbBKQEX;_g&!iWkS zpgeZ_0;c?mye^u@fmxZES(NsTn^x&W(Ha%1HCXmoc2uIQqq8>rlqqv8*Y&iuN2*`M zpo#`2oVUhbD@rotlUK5h`b8>VLEh`DvX;M&Yy=~BuU*?Unk-Ggz_ys}F4vs(^l`Fl0wGBqig&v>ohxJhw}T$+R2 zTf@lHoNbL}BC&M$?Nn)-tfW1KJ>?SP=|om2PO-FSJVJA|ek<1)A(a+ho6J4z>MC2UbIq)l7yIeMlA zx$YVaw-?-zpZ?UsnTk8Jr*d@p7|x?wcSSk-R^-O(<84aK(p_}3{Mt2BXF7U^dIX0p zFPJ73s!TjG*)x)O*VzTwiBgb$%J_ud@{L>r89N{CttXf5PGzIN+`V~iDU(pay{k;7 zI!v=m-l^2LsC?!<6~h(ck+Wr0jMAIY8k$cTgSS03 zd|7(Q2k$kv9J^K5M=9{aTm75~{yP7v-2p7>^3?ci4;SOE$vz9?NHHHgE&^jHAA|rdA!Z(y$l00s6=g zaa@U^S!i6>0LsVB9SK$UiPy!1yx4o-s0=-wbl;u+0#D2U@VaL2`9!DawvFO0oW%oK zcZ8!nQ!Q;PscFoJh*U9Fj`Q_8C6#w)4}5%y{8&)PTN@!0!q6QK#%?8>O8W{FK7?Xj z^xR43Bo=vwM+7OYXONSm<-!U%$>BBq&IRonq-1cfO?mQlEtZdRf2g(_?=m zP(t#KlIvh+BeCp>fDxF#c~2^iOa@@%qCGpaZm{(ES)n?8#C@pmrn+M3;;koVIDuqx zp_Vl(k*s?2&`!)YX47ODFQIJW!FWx}HN0tLJ#Sm=iQ}5j6N&u3qgUNt73uYlTHH|= zPBj-k`|^_X>It$a(4&Da!9`@E15+jfImA{Fq*8k)>r7K4uck`$4avm@Ay`35^s~pf z-jSte?`zI8zhyb!H~EFuEwmz+la(ntpO!W3dg!_G1+m^mq{U|RXDpY6@aTyrTWd!# zg#x8z!vNKJ-P8@16mNG=tAiy4_g$;$tt+M5X@o7Nfs1={jOu5~i{Wa6V6%DTV9J;0 zc0EkI`y2UgA2%jGiEG-j_tqcv+%@{TE;PRNq$RFuRbe$Kcd$!I^F-~=A z@n`}9=*H0Q63x9^=aj=8#myd*IsOFzC5!M(*6;AJytbUl*U%s8LqTR$P~;q7_Z7Ps zmoXTi@cfyuASGqi3A5Z?`53{(4My|Q@RNmGPgO2iUYQfE{WxX1>*+O97AEnLcS{u# z90FM5SgKn!c2Ec%aP=Py&`M8T6BsbN6jP8pASD|UB#|MVJ6vt^Y61T#eM8pctqDhA z-NIeUyZyRLuM8MPyH`VMwywM`LnfH03q$%)$q)K$J(Anxa>?@QhojBdUR(){q#VSW z^$?iU#Jg3khliz4xJgre@;hzz0>iCNmUN(C@7>w9HvQ#*<%aTZ-)-uIC|(7CRXxi9 zReD`dA^%FJQ1J!diLJT*f${L_C9RVlN(-#{_Z(J7ZhUD3lJ(rr8H{OJ} zm}tCF9ltx6c(SaK4*zB4T;dkr{?TXeT2+>#P8z=r%x~V3S_;06Q9w>%Z;7yh(W)XG z0&^NMr?s!2%n>s-ZhCC(0MKeZOR(=*w>A_Oo6^&y36GdYRL7ljj*~QM>FyeWw%1*m zgB_J;HNO(tragCD=8}@2RxY`WHOlz>)B6<+tUSFEJYcGWQ7Zl%vJEPjr$9u7cJ+mk=cr$eG@Bjh_LSAw{D(|WySgOA?R zM)H?WPdJ$!5M|b@1^sVYkkdO;MB`5OXksZ0hA&pKiK&Y~B=74m4<8V1_#PQpIhn6% zjz2FmU0@%79lu>s3BQD@PG-=78CINz3Q5XKdQNMm3c=>6a2k1SDa5&CE`H`R{jxg_ z6tZlRWgr~RCU59gA~N*|L^BUc&N8m~1d3F472Q?%@N}pv@$Iw9k-&q!{k6Sd7n#6Y zZw1ot?}bAi2aYDZOaiGIqqRiUl3>vZ@ddW)Aw%z7KS^E7z%X@YnAsWBKYQK&VVM21 z*PHB1f&oGtjEO-~@8+USE2AEl<^1YxHQ%?=mWZ*w~+oh`N>To*ls@lqS;qjZugY}>nYh}Ui zHkUSlsi3bQ7Q4VA;+IXb%dX2Ub*rU%An^l-+4}c|+vQo|>VSJ`6@kxemt$6Mzt~Kg zymspCiTAEYKWoz7lW?>IC_);XMbA9apKVa_1nM&p!%sR?x$ix~x776y2pMh%CG^X% zH}9ua_LSuD=nk}1vONLa&y?%C-xln9PxkATCvRJCbBtN48{`Gr?UY;- z)1Ke7T&qItn}0*U*m<@mw)`lYvGw^}b=kr6_!yt(4)$1zGSK2{ehdH#IYnRP?ir>NkS z<<;>zLeMv@8!abdg7$jlJ`2>BPxEA->@v&Wx*>m*@IH(Ub`*XqOFX5T`#~f}JyT`` z9ALPJi3b~>&KLY5O?38*lbk-oq`a7AY)HBKD8NAGeeb6-Zes@RW%t=LxiXdymE1zp z$pxX0Xd}bMU-Gq8=y?r@A!^9)gKlf8WKB5>YRSmr;B$IRIgJdrb#tyN_uW4hKNb=Z zWIJ)fDIDLUXuuAfHhM?v$4rrsGo?t!bIklo^pLOEmYP191sIBaeJ7ViO$(s;k!Yxa(&99R~||kHW%_RKu)ZDIwm;b zu3u90q+{%zS76G?e&4fK(K4jXyz6FLcWK;tD=m^%M1#|yFr9_}Iu&~2RDsBq$|~dB zMWy7-8PSf#u$hm+M&1t6G!mV1i$P*(h>NQx*Dh}WgE?%su>jeIgeDtP7#KjWm7%s;?9DU_m7nA!+ z>CLnJQDsHM5nNX#Cvw6R^gg0fw+y57EKe_ue{zF~B9~{pZeO6TPKk{1tqt8C<6I-; zSnhjr{hgC_*PdVa_^8#PLA~!wX?9kcb${Rn4aN2Au(uW8b`*8gN(w5QI|Uv+Z=nRZ zQ84BtV%<_zj+Qo2Fl#9*oyftfYK~f-qq@SZzM@(Dv7$Ee0?UrywjWcA=H&hwe*R4t zX8u#8uE)t2v0@d>?>W>>GVBReV|E>M`R`^QK|Ee+K1+{jdpS3I-qH{DvSfhguHB>h z4ecHAj5+vy{^+kGWDonijL*d99*5ggTKEMz&nUH!hs==5(7b=}G4JJVprN^wm3gsOQ)q>}af#%BcuNGpQ zHR@Mmr}DZ)#wA4~ zrlF-z{gV_*$=V{C9R&GvHA|F-1F;I)-jj~Hk*9|PX@km<%#5ev6w`)XFzZ=&48xVS z3eVIWHMxhVrrEM0%O9{p$T=CTOsfl4Ed^}fD~b7XVKgdO68~ZE3*g1-jFUlcd1-m+ zMgg_zF6}{+PeKn)9zwkg&{rzzPXF3a^)h04R@$!k%@X>e9-HBjatB)j z_@Et@Wj{-Lb#jk^xnCx=`j}*27M>tI)mvl7eRC7$#t*A5JNuNCL zvp$d?iabRdCdbgQouy-f%jg*<90N+6Dz;ll2*I9Rm z=gOQqOhzoXDR40!iY#~J=?}!avpTay;`I!8RX;V1Qb|5OT2JOe*7k(LrYz*#nGT6q zF!hII^3Zr*;>VhXCvnejYu~ofl(snE*C}rB+RLm5^#NgawH-kx*&RVEuGfn+l;~m+ ztF}!y@44#4uXKT4HhTTR;yhA_r`w3pN4QPO((zd&74GaAEQ1Cwqwnx_$5~~L74nLk zST%@6hT@STO96AS{fPz{U^ep9{5kdGpy=R4-i-7^6$Xg^sV^dk60k?0qw= zkGChup4?Vb4mt>sFaJoz&t`c}sVi*XB-9V$oTMQ8j<< z``D=PLcXsw;T;FrO)eo>u)+1<$+WODstItV z7)-t2yHEpS+Y6e!)Erp9*Rr zWuXf|jtVDovMS!HVEqc_^x;QCFGH?g!M`NSOfYDmsk*3la!^HPkl4<*sPu7vYPkVmlAtFH+v#kgF{V$qqxmJf;+yOcxkh zqSBThi!~JMeVl8=55;pzF+{87>5>x)b>3fW?#~3>@P#-l139SK!j)St2SZ z^QK{HusH4Dfz8`$zrCuakr5yNXHBmy%j@v_Y;QBqFYR9%$GuoQ8&iFR{Z<-9;#8nV zFK)77O2%oO%UXqp<;8^H-I`fZzpc%WsRD(?*S7>#Z{4|2z8CMHpJ9+CSDD&_kv3#5 z8GW_0?ix=X5n@t3CFN#p$fP{a*LQZ6y3;ww$9YJayASHlZ}g-#WzvzdUyVLoOzz9o zRnU4Jt?n1-?6W0_H}~B}>u@#vxtjuwNfCkJVRt{XMQSQtr5aZG^xBhK$B5SWgm5jA z)|nxBGLNnrgJKac*OhD9S6Z5S+FLDc*W#Hdr$GGV>oU7;%NwLS7MtEQ+PVa;igQ}H z66E-#y7*!x`!!<^E}eFitGSpu)*Eg%kfhB>9JS1&Hhu22sa}G)75G$M=5#d_v_TJ{ ztlnoAJx^rRxhCcu6Nx~+Oct2$zc#dTt$ zvr@5|%F)~wB}KxIn^BrMIz^n^p;t|8^-VZBo>*-_6M64N)ukY79&JElD}^=r={p!- z#Z63k>>-;@qy-E`dŶ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

    GvB*UCzP`DRIopn|1WWG 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"); + toclevel --; + } + + while (toclevel < level) + { + cupsFilePuts(outfile, "\n"); + toclevel --; + } + + cupsFilePutChar(outfile, '\n'); + intoc = 0; + } + + if (inpre) + { + cupsFilePuts(outfile, "\n"); + inpre = 0; + } + + strlcpy(name, line, sizeof(name)); + for (nameptr = name, level = 1; *nameptr;) + if (isdigit(*nameptr & 255)) + { + while (isdigit(*nameptr & 255)) + nameptr ++; + + level ++; + } + else if (*nameptr == ' ') + { + *nameptr = '\0'; + break; + } + else + nameptr ++; + + cupsFilePrintf(outfile, "\n", level, + name); + put_line(outfile, line); + + intoc = 0; + inheading = level; + } + else + { + if (intoc) + { + while (toclevel > 0) + { + cupsFilePuts(outfile, "\n"); + toclevel --; + } + + cupsFilePutChar(outfile, '\n'); + intoc = 0; + } + + if (!inheading) + { + cupsFilePuts(outfile, "\n

    "); + inheading = -1; + } + + put_line(outfile, line); + + intoc = !strcasecmp(line, "Table of Contents"); + toclevel = 0; + } + } + + if (inpre) + cupsFilePuts(outfile, "\n"); + + if (inheading) + { + if (inheading < 0) + cupsFilePuts(outfile, "

    \n"); + else + cupsFilePrintf(outfile, "
    \n", inheading); + } + + cupsFilePuts(outfile, "\n" + "\n"); + + /* + * Close files... + */ + + cupsFileClose(infile); + cupsFileClose(outfile); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'put_entity()' - Put a single character, using entities as needed. + */ + +void +put_entity(cups_file_t *fp, /* I - File */ + int ch) /* I - Character */ +{ + if (ch == '&') + cupsFilePuts(fp, "&"); + else if (ch == '<') + cupsFilePuts(fp, "<"); + else + cupsFilePutChar(fp, ch); +} + + +/* + * 'put_line()' - Put a whole string for a line. + */ + +void +put_line(cups_file_t *fp, /* I - File */ + const char *s) /* I - String */ +{ + int whitespace, /* Saw whitespace */ + i, /* Looping var */ + len; /* Length of keyword */ + static const char * const keywords[] =/* Special keywords to boldface */ + { + "MAY", + "MUST", + "NEED", + "NOT", + "OPTIONAL", + "OPTIONALLY", + "RECOMMENDED", + "REQUIRED", + "SHALL", + "SHOULD" + }; + + + whitespace = 1; + + while (*s) + { + if (*s == ' ') + whitespace = 1; + + if (whitespace && isupper(*s & 255)) + { + whitespace = 0; + + for (i = 0; i < (int)(sizeof(keywords) / sizeof(sizeof(keywords[0]))); i ++) + { + len = strlen(keywords[i]); + if (!strncmp(s, keywords[i], len) && + (isspace(s[len] & 255) || ispunct(s[len] & 255) || !*s)) + { + cupsFilePrintf(fp, "%s", keywords[i]); + s += len; + break; + } + } + + if (i >= (int)(sizeof(keywords) / sizeof(sizeof(keywords[0])))) + put_entity(fp, *s++); + } + else + { + if (*s != ' ') + whitespace = 0; + + put_entity(fp, *s++); + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/standards/wake-on-lan.pdf b/standards/wake-on-lan.pdf new file mode 100644 index 0000000000000000000000000000000000000000..07d97f44392d52b17c4dae4427fb572cc8f1936e GIT binary patch literal 37276 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/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + echo Installing System V admin printing commands in $(SBINDIR) + $(INSTALL_DIR) -m 755 $(SBINDIR) + $(INSTALL_BIN) cupsaccept $(SBINDIR) + $(INSTALL_BIN) cupsaddsmb $(SBINDIR) + $(INSTALL_BIN) cupsctl $(SBINDIR) + $(INSTALL_BIN) lpadmin $(SBINDIR) + $(INSTALL_BIN) lpinfo $(SBINDIR) + $(INSTALL_BIN) lpmove $(SBINDIR) + $(RM) $(SBINDIR)/accept + $(LN) cupsaccept $(SBINDIR)/accept + $(RM) $(SBINDIR)/cupsdisable + $(LN) cupsaccept $(SBINDIR)/cupsdisable + $(RM) $(SBINDIR)/cupsenable + $(LN) cupsaccept $(SBINDIR)/cupsenable + $(RM) $(SBINDIR)/cupsreject + $(LN) cupsaccept $(SBINDIR)/cupsreject + $(RM) $(SBINDIR)/reject + $(LN) cupsaccept $(SBINDIR)/reject + echo Installing System V user printing commands in $(BINDIR) + $(INSTALL_DIR) -m 755 $(BINDIR) + $(INSTALL_BIN) cancel $(BINDIR) + $(INSTALL_BIN) cupstestdsc $(BINDIR) + $(INSTALL_BIN) cupstestppd $(BINDIR) + $(INSTALL_BIN) lp $(BINDIR) + $(INSTALL_BIN) lpoptions $(BINDIR) + $(INSTALL_BIN) lpstat $(BINDIR) + $(INSTALL_BIN) lppasswd $(BINDIR) + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(TARGETS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall all targets... +# + +uninstall: + $(RM) $(BINDIR)/cancel + $(RM) $(BINDIR)/cupstestdsc + $(RM) $(BINDIR)/cupstestppd + $(RM) $(BINDIR)/lp + $(RM) $(BINDIR)/lpoptions + $(RM) $(BINDIR)/lppasswd + $(RM) $(BINDIR)/lpstat + -$(RMDIR) $(BINDIR) + $(RM) $(SBINDIR)/accept + $(RM) $(SBINDIR)/cupsaccept + $(RM) $(SBINDIR)/cupsaddsmb + $(RM) $(SBINDIR)/cupsaccept + $(RM) $(SBINDIR)/cupsdisable + $(RM) $(SBINDIR)/cupsenable + $(RM) $(SBINDIR)/cupsreject + $(RM) $(SBINDIR)/lpadmin + $(RM) $(SBINDIR)/lpinfo + $(RM) $(SBINDIR)/lpmove + $(RM) $(SBINDIR)/reject + -$(RMDIR) $(SBINDIR) + + +# +# cancel +# + +cancel: cancel.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cancel cancel.o $(LIBS) + + +# +# cupsaccept +# + +cupsaccept: cupsaccept.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsaccept cupsaccept.o $(LIBS) + for file in accept cupsenable cupsdisable cupsreject reject; do \ + $(RM) $$file; \ + $(LN) cupsaccept $$file; \ + done + + +# +# cupsaddsmb +# + +cupsaddsmb: cupsaddsmb.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsaddsmb cupsaddsmb.o $(LIBS) + + +# +# cupsctl +# + +cupsctl: cupsctl.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o cupsctl cupsctl.o $(LIBS) + + +# +# cupstestdsc +# + +cupstestdsc: cupstestdsc.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ cupstestdsc.o $(LIBS) + + +# +# cupstestppd +# + +cupstestppd: cupstestppd.o ../cups/$(LIBCUPS) ../filter/$(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ cupstestppd.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + +cupstestppd-static: cupstestppd.o ../cups/libcups.a ../filter/libcupsimage.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ cupstestppd.o ../filter/libcupsimage.a \ + ../cups/libcups.a $(IMGLIBS) $(LIBGSSAPI) $(LIBS) $(LIBZ) + + +# +# 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/cancel.c b/systemv/cancel.c new file mode 100644 index 0000000000..d9bca76bf4 --- /dev/null +++ b/systemv/cancel.c @@ -0,0 +1,386 @@ +/* + * "$Id$" + * + * "cancel" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and cancel jobs. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include + + +/* + * '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 */ + *user; /* Cancel jobs for a user */ + int purge; /* Purge or cancel jobs? */ + char uri[1024]; /* Printer or job URI */ + ipp_t *request; /* IPP request */ + ipp_t *response; /* IPP response */ + ipp_op_t op; /* Operation */ + + + _cupsSetLocale(argv); + + /* + * Setup to cancel individual print jobs... + */ + + op = IPP_CANCEL_JOB; + purge = 0; + dest = NULL; + user = 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_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + + if (http) + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + return (1); + } + + cupsSetUser(argv[i]); + } + break; + + case 'a' : /* Cancel all jobs */ + purge = 1; + op = IPP_PURGE_JOBS; + break; + + case 'h' : /* Connect to host */ + if (http != NULL) + { + httpClose(http); + http = NULL; + } + + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-h\' option!\n"), + argv[0]); + return (1); + } + else + cupsSetServer(argv[i]); + } + break; + + case 'u' : /* Username */ + op = IPP_PURGE_JOBS; + + if (argv[i][2] != '\0') + user = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-u\' option!\n"), + argv[0]); + return (1); + } + else + user = argv[i]; + } + break; + + default : + _cupsLangPrintf(stderr, + _("%s: Error - unknown option \'%c\'!\n"), + argv[0], argv[i][1]); + return (1); + } + else + { + /* + * Cancel a job or printer... + */ + + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if (!strcmp(argv[i], "-")) + { + /* + * 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] & 255)) + { + /* + * Delete the specified job ID. + */ + + dest = NULL; + op = IPP_CANCEL_JOB; + job_id = atoi(job + 1); + } + else if (isdigit(argv[i][0] & 255)) + { + /* + * Delete the specified job ID. + */ + + dest = NULL; + op = IPP_CANCEL_JOB; + job_id = atoi(argv[i]); + } + else + { + /* + * Bad printer name! + */ + + _cupsLangPrintf(stderr, + _("%s: Error - unknown destination \"%s\"!\n"), + argv[0], argv[i]); + return (1); + } + + /* + * 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) + { + _cupsLangPrintf(stderr, + _("%s: Unable to contact server!\n"), + argv[0]); + 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 = ippNewRequest(op); + + if (dest) + { + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/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); + } + + if (user) + { + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); + } + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, cupsUser()); + + if (op == IPP_PURGE_JOBS) + ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", purge); + + /* + * Do the request and get back a response... + */ + + if (op == IPP_PURGE_JOBS && (!user || strcasecmp(user, cupsUser()))) + response = cupsDoRequest(http, request, "/admin/"); + else + response = cupsDoRequest(http, request, "/jobs/"); + + if (response == NULL || + response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, _("%s: %s failed: %s\n"), argv[0], + op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", + cupsLastErrorString()); + + if (response) + ippDelete(response); + + return (1); + } + + ippDelete(response); + } + + if (num_dests == 0 && op == IPP_PURGE_JOBS) + { + /* + * Open a connection to the server... + */ + + if (http == NULL) + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + _cupsLangPrintf(stderr, _("%s: Unable to contact server!\n"), + argv[0]); + 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 = ippNewRequest(op); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, "ipp://localhost/printers/"); + + if (user) + { + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); + } + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, cupsUser()); + + ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", purge); + + /* + * Do the request and get back a response... + */ + + response = cupsDoRequest(http, request, "/admin/"); + + if (response == NULL || + response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, _("%s: %s failed: %s\n"), argv[0], + op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", + cupsLastErrorString()); + + if (response) + ippDelete(response); + + return (1); + } + + ippDelete(response); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/cupsaccept.c b/systemv/cupsaccept.c new file mode 100644 index 0000000000..d92f184330 --- /dev/null +++ b/systemv/cupsaccept.c @@ -0,0 +1,249 @@ +/* + * "$Id$" + * + * "cupsaccept", "cupsdisable", "cupsenable", and "cupsreject" commands for + * the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and accept/reject jobs or disable/enable printers. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * '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 */ +{ + int i; /* Looping var */ + char *command, /* Command to do */ + uri[1024], /* Printer URI */ + *reason; /* Reason for reject/disable */ + ipp_t *request; /* IPP request */ + ipp_op_t op; /* Operation */ + int cancel; /* Cancel jobs? */ + + + _cupsSetLocale(argv); + + /* + * See what operation we're supposed to do... + */ + + if ((command = strrchr(argv[0], '/')) != NULL) + command ++; + else + command = argv[0]; + + cancel = 0; + + if (!strcmp(command, "cupsaccept") || !strcmp(command, "accept")) + op = CUPS_ACCEPT_JOBS; + else if (!strcmp(command, "cupsreject") || !strcmp(command, "reject")) + op = CUPS_REJECT_JOBS; + else if (!strcmp(command, "cupsdisable") || !strcmp(command, "disable")) + op = IPP_PAUSE_PRINTER; + else if (!strcmp(command, "cupsenable") || !strcmp(command, "enable")) + op = IPP_RESUME_PRINTER; + else + { + _cupsLangPrintf(stderr, _("%s: Don't know what to do!\n"), + command); + return (1); + } + + 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_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + command); +#endif /* HAVE_SSL */ + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + command); + return (1); + } + + cupsSetUser(argv[i]); + } + break; + + case 'c' : /* Cancel jobs */ + cancel = 1; + break; + + case 'h' : /* Connect to host */ + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-h\' option!\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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected reason text after " + "\'-r\' option!\n"), + command); + return (1); + } + + reason = argv[i]; + } + break; + + case '-' : + if (!strcmp(argv[i], "--hold")) + op = IPP_HOLD_NEW_JOBS; + else if (!strcmp(argv[i], "--release")) + op = IPP_RELEASE_HELD_NEW_JOBS; + else + { + _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%s\'!\n"), + command, argv[i]); + return (1); + } + break; + + default : + _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"), + command, argv[i][1]); + return (1); + } + } + else + { + /* + * Accept/disable/enable/reject a destination... + */ + + request = ippNewRequest(op); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", argv[i]); + 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 (reason != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, + "printer-state-message", NULL, reason); + + /* + * Do the request and get back a response... + */ + + ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + _cupsLangPrintf(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 = ippNewRequest(IPP_PURGE_JOBS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, uri); + + ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); + return (1); + } + } + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/cupsaddsmb.c b/systemv/cupsaddsmb.c new file mode 100644 index 0000000000..16f37f3b61 --- /dev/null +++ b/systemv/cupsaddsmb.c @@ -0,0 +1,303 @@ +/* + * "$Id$" + * + * "cupsaddsmb" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 2001-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Export printers on the command-line. + * export_dest() - Export a destination to SAMBA. + * usage() - Show program usage and exit... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local globals... + */ + +int Verbosity = 0; +const char *SAMBAUser, + *SAMBAPassword, + *SAMBAServer; + + +/* + * Local functions... + */ + +int export_dest(http_t *http, const char *dest); +void usage(void); + + +/* + * '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? */ + http_t *http; /* Connection to server */ + int num_dests; /* Number of printers */ + cups_dest_t *dests; /* Printers */ + + + _cupsSetLocale(argv); + + /* + * Parse command-line arguments... + */ + + export_all = 0; + http = NULL; + SAMBAUser = cupsUser(); + SAMBAPassword = NULL; + SAMBAServer = NULL; + + for (i = 1; i < argc; i ++) + if (!strcmp(argv[i], "-E")) + { +#ifdef HAVE_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + } + else if (!strcmp(argv[i], "-H")) + { + i ++; + if (i >= argc) + usage(); + + SAMBAServer = argv[i]; + } + else if (!strcmp(argv[i], "-U")) + { + char *sep; /* Separator for password */ + + + i ++; + if (i >= argc) + usage(); + + SAMBAUser = argv[i]; + + if ((sep = strchr(argv[i], '%')) != NULL) + { + /* + * Nul-terminate the username at the first % and point the + * password at the rest... + */ + + *sep++ = '\0'; + + SAMBAPassword = sep; + } + } + else if (!strcmp(argv[i], "-a")) + export_all = 1; + else if (!strcmp(argv[i], "-h")) + { + i ++; + if (i >= argc) + usage(); + + cupsSetServer(argv[i]); + } + else if (!strcmp(argv[i], "-v")) + Verbosity = 1; + else if (argv[i][0] != '-') + { + if (!http) + { + /* + * Connect to the server... + */ + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + _cupsLangPrintf(stderr, _("%s: Unable to connect to server\n"), argv[0]); + exit(1); + } + } + + if (SAMBAServer == NULL) + { + SAMBAServer = cupsServer(); + + if (SAMBAServer[0] == '/') /* Use localhost instead of domain socket */ + SAMBAServer = "localhost"; + } + + if ((status = export_dest(http, argv[i])) != 0) + return (status); + } + else + usage(); + + /* + * Connect to the server... + */ + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + _cupsLangPrintf(stderr, _("%s: Unable to connect to server\n"), argv[0]); + exit(1); + } + + /* + * See if the user specified "-a"... + */ + + if (export_all) + { + /* + * Export all printers... + */ + + if (SAMBAServer == NULL) + { + SAMBAServer = cupsServer(); + + if (SAMBAServer[0] == '/') /* Use localhost instead of domain socket */ + SAMBAServer = "localhost"; + } + + num_dests = cupsGetDests2(http, &dests); + + for (j = 0, status = 0; j < num_dests; j ++) + if (!dests[j].instance) + { + if ((status = export_dest(http, dests[j].name)) != 0) + break; + } + + cupsFreeDests(num_dests, dests); + + if (status) + return (status); + } + + return (0); +} + + +/* + * 'export_dest()' - Export a destination to SAMBA. + */ + +int /* O - 0 on success, non-zero on error */ +export_dest(http_t *http, /* I - Connection to server */ + const char *dest) /* I - Destination to export */ +{ + int status; /* Status of export */ + char ppdfile[1024], /* PPD file for printer drivers */ + prompt[1024]; /* Password prompt */ + int tries; /* Number of tries */ + + + /* + * Get the Windows PPD file for the printer... + */ + + if (!cupsAdminCreateWindowsPPD(http, dest, ppdfile, sizeof(ppdfile))) + { + _cupsLangPrintf(stderr, + _("cupsaddsmb: No PPD file for printer \"%s\" - " + "%s\n"), + dest, cupsLastErrorString()); + return (1); + } + + /* + * Try to export it... + */ + + for (status = 0, tries = 0; !status && tries < 3; tries ++) + { + /* + * Get the password, as needed... + */ + + if (!SAMBAPassword) + { + snprintf(prompt, sizeof(prompt), + _cupsLangString(cupsLangDefault(), + _("Password for %s required to access %s via " + "SAMBA: ")), + SAMBAUser, SAMBAServer); + + if ((SAMBAPassword = cupsGetPassword(prompt)) == NULL) + break; + } + + status = cupsAdminExportSamba(dest, ppdfile, SAMBAServer, + SAMBAUser, SAMBAPassword, + Verbosity ? stderr : NULL); + + if (!status && cupsLastError() == IPP_NOT_FOUND) + break; + } + + unlink(ppdfile); + + return (!status); +} + + +/* + * 'usage()' - Show program usage and exit... + */ + +void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: cupsaddsmb [options] printer1 ... printerN\n" + " cupsaddsmb [options] -a\n" + "\n" + "Options:\n" + " -E Encrypt the connection to the server\n" + " -H samba-server Use the named SAMBA server\n" + " -U samba-user Authenticate using the named SAMBA user\n" + " -a Export all printers\n" + " -h cups-server Use the named CUPS server\n" + " -v Be verbose (show commands)\n")); + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/cupsctl.c b/systemv/cupsctl.c new file mode 100644 index 0000000000..c41d7cc22a --- /dev/null +++ b/systemv/cupsctl.c @@ -0,0 +1,233 @@ +/* + * "$Id$" + * + * CUPS control program for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 2006-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Get/set server settings. + * usage() - Show program usage. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void usage(const char *opt); + + +/* + * 'main()' - Get/set server settings. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, /* Looping var */ + num_settings; /* Number of settings */ + cups_option_t *settings; /* Settings */ + const char *opt; /* Current option character */ + http_t *http; /* Connection to server */ + + + /* + * Process the command-line... + */ + + _cupsSetLocale(argv); + + num_settings = 0; + settings = NULL; + + for (i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + if (argv[i][1] == '-') + { + if (!strcmp(argv[i], "--debug-logging")) + num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, "1", + num_settings, &settings); + else if (!strcmp(argv[i], "--no-debug-logging")) + num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, "0", + num_settings, &settings); + else if (!strcmp(argv[i], "--remote-admin")) + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, "1", + num_settings, &settings); + else if (!strcmp(argv[i], "--no-remote-admin")) + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, "0", + num_settings, &settings); + else if (!strcmp(argv[i], "--remote-any")) + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, "1", + num_settings, &settings); + else if (!strcmp(argv[i], "--no-remote-any")) + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, "0", + num_settings, &settings); + else if (!strcmp(argv[i], "--remote-printers")) + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, "1", + num_settings, &settings); + else if (!strcmp(argv[i], "--no-remote-printers")) + num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS, "0", + num_settings, &settings); + else if (!strcmp(argv[i], "--share-printers")) + num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, "1", + num_settings, &settings); + else if (!strcmp(argv[i], "--no-share-printers")) + num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, "0", + num_settings, &settings); + else if (!strcmp(argv[i], "--user-cancel-any")) + num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, "1", + num_settings, &settings); + else if (!strcmp(argv[i], "--no-user-cancel-any")) + num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, "0", + num_settings, &settings); + else + usage(argv[i]); + } + else + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'E' : + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + break; + + case 'U' : + i ++; + if (i >= argc) + usage(NULL); + + cupsSetUser(argv[i]); + break; + + case 'h' : + i ++; + if (i >= argc) + usage(NULL); + + cupsSetServer(argv[i]); + break; + + default : + usage(opt); + break; + } + } + } + else if (strchr(argv[i], '=')) + num_settings = cupsParseOptions(argv[i], num_settings, &settings); + else + usage(argv[i]); + } + + if (cupsGetOption("Listen", num_settings, settings) || + cupsGetOption("Port", num_settings, settings)) + { + _cupsLangPuts(stderr, _("cupsctl: Cannot set Listen or Port directly.\n")); + return (1); + } + + /* + * Connect to the server using the defaults... + */ + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) == NULL) + { + _cupsLangPrintf(stderr, _("cupsctl: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + + /* + * Set the current configuration if we have anything on the command-line... + */ + + if (num_settings > 0) + { + if (!cupsAdminSetServerSettings(http, num_settings, settings)) + { + _cupsLangPrintf(stderr, "cupsctl: %s\n", cupsLastErrorString()); + return (1); + } + } + else if (!cupsAdminGetServerSettings(http, &num_settings, &settings)) + { + _cupsLangPrintf(stderr, "cupsctl: %s\n", cupsLastErrorString()); + return (1); + } + else + { + for (i = 0; i < num_settings; i ++) + _cupsLangPrintf(stdout, "%s=%s\n", settings[i].name, settings[i].value); + } + + cupsFreeOptions(num_settings, settings); + return (0); +} + + +/* + * 'usage()' - Show program usage. + */ + +static void +usage(const char *opt) /* I - Option character/string */ +{ + if (opt) + { + if (*opt == '-') + _cupsLangPrintf(stderr, _("cupsctl: Unknown option \"%s\"!\n"), opt); + else + _cupsLangPrintf(stderr, _("cupsctl: Unknown option \"-%c\"!\n"), *opt); + } + + _cupsLangPuts(stdout, + _("Usage: cupsctl [options] [param=value ... paramN=valueN]\n" + "\n" + "Options:\n" + "\n" + " -E Enable encryption\n" + " -U username Specify username\n" + " -h server[:port] Specify server address\n" + "\n" + " --[no-]debug-logging Turn debug logging on/off\n" + " --[no-]remote-admin Turn remote administration " + "on/off\n" + " --[no-]remote-any Allow/prevent access from the " + "Internet\n" + " --[no-]remote-printers Show/hide remote printers\n" + " --[no-]share-printers Turn printer sharing on/off\n" + " --[no-]user-cancel-any Allow/prevent users to cancel " + "any job\n")); + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/cupstestdsc.c b/systemv/cupstestdsc.c new file mode 100644 index 0000000000..dd68ecc9ed --- /dev/null +++ b/systemv/cupstestdsc.c @@ -0,0 +1,446 @@ +/* + * "$Id$" + * + * DSC test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2006 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * check() - Check a file for conformance. + * usage() - Show program usage. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int check_file(const char *filename); +static void usage(void); + + +/* + * 'main()' - Main entry for 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 */ + int status; /* Status of tests */ + int num_files; /* Number of files tested */ + + + _cupsSetLocale(argv); + + /* + * Collect command-line arguments... + */ + + for (i = 1, num_files = 0, status = 0; i < argc; i ++) + if (argv[i][0] == '-') + { + if (argv[i][1]) + { + /* + * Currently the only supported option is "-h" (help)... + */ + + usage(); + } + else + { + num_files ++; + status += check_file("(stdin)"); + } + } + else + { + num_files ++; + status += check_file(argv[i]); + } + + if (!num_files) + usage(); + + return (status); +} + + +/* + * 'check()' - Check a file for conformance. + */ + +static int /* O - 0 on success, 1 on failure */ +check_file(const char *filename) /* I - File to read from */ +{ + int i; /* Looping var */ + cups_file_t *fp; /* File */ + char line[1024]; /* Line from file */ + int ch; /* Current character */ + size_t bytes; /* Length of line */ + int status; /* Status of test */ + int linenum; /* Line number */ + int binary; /* File contains binary data? */ + float version; /* DSC version */ + int lbrt[4]; /* Bounding box */ + char page_label[256]; /* Page label string */ + int page_number; /* Page number */ + int last_page_number; /* Last page number seen */ + int level; /* Embedded document level */ + int saw_bounding_box, /* %%BoundingBox seen? */ + saw_pages, /* %%Pages seen? */ + saw_end_comments, /* %%EndComments seen? */ + saw_begin_prolog, /* %%BeginProlog seen? */ + saw_end_prolog, /* %%EndProlog seen? */ + saw_begin_setup, /* %%BeginSetup seen? */ + saw_end_setup, /* %%EndSetup seen? */ + saw_page, /* %%Page seen? */ + saw_trailer, /* %%Trailer seen? */ + saw_long_line; /* Saw long lines? */ + + + /* + * Open the file... + */ + + if (!strcmp(filename, "(stdin)")) + fp = cupsFileStdin(); + else + fp = cupsFileOpen(filename, "r"); + + if (!fp) + { + perror(filename); + return (1); + } + + /* + * Scan the file... + */ + + binary = 0; + last_page_number = 0; + level = 0; + linenum = 0; + saw_begin_prolog = 0; + saw_begin_setup = 0; + saw_bounding_box = 0; + saw_end_comments = 0; + saw_end_prolog = 0; + saw_end_setup = 0; + saw_long_line = 0; + saw_page = 0; + saw_pages = 0; + saw_trailer = 0; + status = 0; + version = 0.0f; + + _cupsLangPrintf(stdout, "%s: ", filename); + fflush(stdout); + + while ((bytes = cupsFileGetLine(fp, line, sizeof(line))) > 0) + { + linenum ++; + + if (bytes > 255) + { + if (!saw_long_line) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPrintf(stdout, + _(" Line %d is longer than 255 characters (%d)!\n" + " REF: Page 25, Line Length\n"), + linenum, (int)bytes); + } + + saw_long_line ++; + } + + if (linenum == 1) + { + if (strncmp(line, "%!PS-Adobe-", 11)) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + _cupsLangPuts(stdout, + _(" Missing %!PS-Adobe-3.0 on first line!\n" + " REF: Page 17, 3.1 Conforming Documents\n")); + cupsFileClose(fp); + return (1); + } + else + version = atof(line + 11); + } + else if (level > 0) + { + if (!strncmp(line, "%%BeginDocument:", 16)) + level ++; + else if (!strncmp(line, "%%EndDocument", 13)) + level --; + } + else if (saw_trailer) + { + if (!strncmp(line, "%%Pages:", 8)) + { + if (atoi(line + 8) <= 0) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPrintf(stdout, + _(" Bad %%%%Pages: on line %d!\n" + " REF: Page 43, %%%%Pages:\n"), + linenum); + } + else + saw_pages = 1; + } + else if (!strncmp(line, "%%BoundingBox:", 14)) + { + if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2, + lbrt + 3) != 4) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPrintf(stdout, _(" Bad %%%%BoundingBox: on line %d!\n" + " REF: Page 39, %%%%BoundingBox:\n"), + linenum); + } + else + saw_bounding_box = 1; + } + } + else if (!saw_end_comments) + { + if (!strncmp(line, "%%EndComments", 13)) + saw_end_comments = 1; + else if (line[0] != '%') + saw_end_comments = -1; + else if (!strncmp(line, "%%Pages:", 8)) + { + if (strstr(line + 8, "(atend)")) + saw_pages = -1; + else if (atoi(line + 8) <= 0) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPrintf(stdout, _(" Bad %%%%Pages: on line %d!\n" + " REF: Page 43, %%%%Pages:\n"), + linenum); + } + else + saw_pages = 1; + } + else if (!strncmp(line, "%%BoundingBox:", 14)) + { + if (strstr(line, "(atend)")) + saw_bounding_box = -1; + else if (sscanf(line + 14, "%d%d%d%d", lbrt + 0, lbrt + 1, lbrt + 2, + lbrt + 3) != 4) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPrintf(stdout, _(" Bad %%%%BoundingBox: on line %d!\n" + " REF: Page 39, %%%%BoundingBox:\n"), + linenum); + } + else + saw_bounding_box = 1; + } + } + else if (saw_begin_prolog && !saw_end_prolog) + { + if (!strncmp(line, "%%EndProlog", 11)) + saw_end_prolog = 1; + } + else if (saw_begin_setup && !saw_end_setup) + { + if (!strncmp(line, "%%EndSetup", 10)) + saw_end_setup = 1; + } + else if (saw_end_comments) + { + if (!strncmp(line, "%%Page:", 7)) + { + if (sscanf(line + 7, "%255s%d", page_label, &page_number) != 2 || + page_number != (last_page_number + 1) || page_number < 1) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPrintf(stdout, _(" Bad %%%%Page: on line %d!\n" + " REF: Page 53, %%%%Page:\n"), + linenum); + } + else + { + last_page_number = page_number; + saw_page = 1; + } + } + else if (!strncmp(line, "%%BeginProlog", 13)) + saw_begin_prolog = 1; + else if (!strncmp(line, "%%BeginSetup", 12)) + saw_begin_setup = 1; + else if (!strncmp(line, "%%BeginDocument:", 16)) + level ++; + else if (!strncmp(line, "%%EndDocument", 13)) + level --; + else if (!strncmp(line, "%%Trailer", 9)) + saw_trailer = 1; + } + + for (i = 0; !binary && i < bytes; i ++) + { + ch = line[i]; + + if ((ch < ' ' || (ch & 0x80)) && ch != '\n' && ch != '\r' && ch != '\t') + binary = 1; + } + } + + if (saw_bounding_box <= 0) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPuts(stdout, _(" Missing or bad %%BoundingBox: comment!\n" + " REF: Page 39, %%BoundingBox:\n")); + } + + if (saw_pages <= 0) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPuts(stdout, _(" Missing or bad %%Pages: comment!\n" + " REF: Page 43, %%Pages:\n")); + } + + if (!saw_end_comments) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPuts(stdout, _(" Missing %%EndComments comment!\n" + " REF: Page 41, %%EndComments\n")); + } + + if (!saw_page) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPuts(stdout, _(" Missing or bad %%Page: comments!\n" + " REF: Page 53, %%Page:\n")); + } + + if (level < 0) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPuts(stdout, _(" Too many %%EndDocument comments!\n")); + } + else if (level > 0) + { + if (!status) + _cupsLangPuts(stdout, _("FAIL\n")); + + status ++; + _cupsLangPuts(stdout, _(" Too many %%BeginDocument comments!\n")); + } + + if (saw_long_line > 1) + _cupsLangPrintf(stderr, + _(" Saw %d lines that exceeded 255 characters!\n"), + saw_long_line); + + if (!status) + _cupsLangPuts(stdout, _("PASS\n")); + + if (binary) + _cupsLangPuts(stdout, _(" Warning: file contains binary data!\n")); + + if (version < 3.0f) + _cupsLangPrintf(stdout, + _(" Warning: obsolete DSC version %.1f in file!\n"), + version); + + if (saw_end_comments < 0) + _cupsLangPuts(stdout, _(" Warning: no %%EndComments comment in file!\n")); + + cupsFileClose(fp); + + return (status); +} + + +/* + * 'usage()' - Show program usage. + */ + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" + " cupstestdsc [options] -\n" + "\n" + "Options:\n" + "\n" + " -h Show program usage\n" + "\n" + " Note: this program only validates the DSC comments, " + "not the PostScript itself.\n")); + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/cupstestppd.c b/systemv/cupstestppd.c new file mode 100644 index 0000000000..7f29b04d81 --- /dev/null +++ b/systemv/cupstestppd.c @@ -0,0 +1,3658 @@ +/* + * "$Id$" + * + * PPD test program for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * check_basics() - Check for CR LF, mixed line endings, and blank + * lines. + * check_constraints() - Check UIConstraints in the PPD file. + * check_case() - Check that there are no duplicate groups, options, + * or choices that differ only by case. + * check_defaults() - Check default option keywords in the PPD file. + * check_duplex() - Check duplex keywords in the PPD file. + * check_filters() - Check filters in the PPD file. + * check_profiles() - Check ICC color profiles in the PPD file. + * check_sizes() - Check media sizes in the PPD file. + * check_translations() - Check translations in the PPD file. + * show_conflicts() - Show option conflicts in a PPD file. + * test_raster() - Test PostScript commands for raster printers. + * usage() - Show program usage... + * valid_path() - Check whether a path has the correct capitalization. + * valid_utf8() - Check whether a string contains valid UTF-8 text. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WIN32 +# define X_OK 0 +#endif /* WIN32 */ + + +/* + * Error warning overrides... + */ + +enum +{ + WARN_NONE = 0, + WARN_CONSTRAINTS = 1, + WARN_DEFAULTS = 2, + WARN_FILTERS = 4, + WARN_PROFILES = 8, + WARN_TRANSLATIONS = 16, + WARN_DUPLEX = 32, + WARN_SIZES = 64, + WARN_FILENAME = 128, + WARN_ALL = 255 +}; + + +/* + * Error codes... + */ + +enum +{ + ERROR_NONE = 0, + ERROR_USAGE, + ERROR_FILE_OPEN, + ERROR_PPD_FORMAT, + ERROR_CONFORMANCE +}; + + +/* + * Line endings... + */ + +enum +{ + EOL_NONE = 0, + EOL_CR, + EOL_LF, + EOL_CRLF +}; + + +/* + * File permissions... + */ + +#define MODE_WRITE 0022 /* Group/other write */ +#define MODE_MASK 0555 /* Owner/group/other read+exec/search */ +#define MODE_DATAFILE 0444 /* Owner/group/other read */ +#define MODE_DIRECTORY 0555 /* Owner/group/other read+search */ +#define MODE_PROGRAM 0555 /* Owner/group/other read+exec */ + + +/* + * Local functions... + */ + +static void check_basics(const char *filename); +static int check_constraints(ppd_file_t *ppd, int errors, int verbose, + int warn); +static int check_case(ppd_file_t *ppd, int errors, int verbose); +static int check_defaults(ppd_file_t *ppd, int errors, int verbose, + int warn); +static int check_duplex(ppd_file_t *ppd, int errors, int verbose, + int warn); +static int check_filters(ppd_file_t *ppd, const char *root, int errors, + int verbose, int warn); +static int check_profiles(ppd_file_t *ppd, const char *root, int errors, + int verbose, int warn); +static int check_sizes(ppd_file_t *ppd, int errors, int verbose, int warn); +static int check_translations(ppd_file_t *ppd, int errors, int verbose, + int warn); +static void show_conflicts(ppd_file_t *ppd); +static int test_raster(ppd_file_t *ppd, int verbose); +static void usage(void); +static int valid_path(const char *keyword, const char *path, int errors, + int verbose, int warn); +static int valid_utf8(const char *s); + + +/* + * 'main()' - Main entry for test program. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, j, k, m, n; /* Looping vars */ + int len; /* Length of option name */ + char *opt; /* Option character */ + const char *ptr; /* Pointer into string */ + int files; /* Number of files */ + int verbose; /* Want verbose output? */ + int warn; /* Which errors to just warn about */ + int ignore; /* Which errors to ignore */ + int status; /* Exit status */ + int errors; /* Number of conformance errors */ + int ppdversion; /* PPD spec version in PPD file */ + ppd_status_t error; /* Status of ppdOpen*() */ + int line; /* Line number for error */ + char *root; /* Root directory */ + int xdpi, /* X resolution */ + ydpi; /* Y resolution */ + ppd_file_t *ppd; /* PPD file record */ + ppd_attr_t *attr; /* PPD attribute */ + ppd_size_t *size; /* Size record */ + ppd_group_t *group; /* UI group */ + ppd_option_t *option; /* Standard UI option */ + ppd_group_t *group2; /* UI group */ + ppd_option_t *option2; /* Standard UI option */ + ppd_choice_t *choice; /* Standard UI option choice */ + struct lconv *loc; /* Locale data */ + static char *uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" }; + static char *sections[] = { "ANY", "DOCUMENT", "EXIT", + "JCL", "PAGE", "PROLOG" }; + + + _cupsSetLocale(argv); + loc = localeconv(); + + /* + * Display PPD files for each file listed on the command-line... + */ + + ppdSetConformance(PPD_CONFORM_STRICT); + + verbose = 0; + ppd = NULL; + files = 0; + status = ERROR_NONE; + root = ""; + warn = WARN_NONE; + ignore = WARN_NONE; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-' && argv[i][1]) + { + for (opt = argv[i] + 1; *opt; opt ++) + switch (*opt) + { + case 'I' : /* Ignore errors */ + i ++; + + if (i >= argc) + usage(); + + if (!strcmp(argv[i], "none")) + ignore = WARN_NONE; + else if (!strcmp(argv[i], "filename")) + ignore |= WARN_FILENAME; + else if (!strcmp(argv[i], "filters")) + ignore |= WARN_FILTERS; + else if (!strcmp(argv[i], "profiles")) + ignore |= WARN_PROFILES; + else if (!strcmp(argv[i], "all")) + ignore = WARN_FILTERS | WARN_PROFILES; + else + usage(); + break; + + case 'R' : /* Alternate root directory */ + i ++; + + if (i >= argc) + usage(); + + root = argv[i]; + break; + + case 'W' : /* Turn errors into warnings */ + i ++; + + if (i >= argc) + usage(); + + if (!strcmp(argv[i], "none")) + warn = WARN_NONE; + else if (!strcmp(argv[i], "constraints")) + warn |= WARN_CONSTRAINTS; + else if (!strcmp(argv[i], "defaults")) + warn |= WARN_DEFAULTS; + else if (!strcmp(argv[i], "duplex")) + warn |= WARN_DUPLEX; + else if (!strcmp(argv[i], "filters")) + warn |= WARN_FILTERS; + else if (!strcmp(argv[i], "profiles")) + warn |= WARN_PROFILES; + else if (!strcmp(argv[i], "sizes")) + warn |= WARN_SIZES; + else if (!strcmp(argv[i], "translations")) + warn |= WARN_TRANSLATIONS; + else if (!strcmp(argv[i], "all")) + warn = WARN_ALL; + else + usage(); + break; + + case 'q' : /* Quiet mode */ + if (verbose > 0) + { + _cupsLangPuts(stderr, + _("cupstestppd: The -q option is incompatible " + "with the -v option.\n")); + return (1); + } + + verbose --; + break; + + case 'r' : /* Relaxed mode */ + ppdSetConformance(PPD_CONFORM_RELAXED); + break; + + case 'v' : /* Verbose mode */ + if (verbose < 0) + { + _cupsLangPuts(stderr, + _("cupstestppd: The -v option is incompatible " + "with the -q option.\n")); + return (1); + } + + verbose ++; + break; + + default : + usage(); + break; + } + } + else + { + /* + * Open the PPD file... + */ + + if (files && verbose >= 0) + _cupsLangPuts(stdout, "\n"); + + files ++; + + if (argv[i][0] == '-') + { + /* + * Read from stdin... + */ + + ppd = ppdOpen(stdin); + + if (verbose >= 0) + printf("%s:", (ppd && ppd->pcfilename) ? ppd->pcfilename : "(stdin)"); + } + else + { + /* + * Read from a file... + */ + + if (verbose >= 0) + printf("%s:", argv[i]); + + ppd = ppdOpenFile(argv[i]); + } + + if (ppd == NULL) + { + error = ppdLastError(&line); + + if (error <= PPD_ALLOC_ERROR) + { + status = ERROR_FILE_OPEN; + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" FAIL\n" + " **FAIL** Unable to open PPD file - %s\n"), + strerror(errno)); + } + else + { + status = ERROR_PPD_FORMAT; + + if (verbose >= 0) + { + _cupsLangPrintf(stdout, + _(" FAIL\n" + " **FAIL** Unable to open PPD file - " + "%s on line %d.\n"), + ppdErrorString(error), line); + + switch (error) + { + case PPD_MISSING_PPDADOBE4 : + _cupsLangPuts(stdout, + _(" REF: Page 42, section 5.2.\n")); + break; + case PPD_MISSING_VALUE : + _cupsLangPuts(stdout, + _(" REF: Page 20, section 3.4.\n")); + break; + case PPD_BAD_OPEN_GROUP : + case PPD_NESTED_OPEN_GROUP : + _cupsLangPuts(stdout, + _(" REF: Pages 45-46, section 5.2.\n")); + break; + case PPD_BAD_OPEN_UI : + case PPD_NESTED_OPEN_UI : + _cupsLangPuts(stdout, + _(" REF: Pages 42-45, section 5.2.\n")); + break; + case PPD_BAD_ORDER_DEPENDENCY : + _cupsLangPuts(stdout, + _(" REF: Pages 48-49, section 5.2.\n")); + break; + case PPD_BAD_UI_CONSTRAINTS : + _cupsLangPuts(stdout, + _(" REF: Pages 52-54, section 5.2.\n")); + break; + case PPD_MISSING_ASTERISK : + _cupsLangPuts(stdout, + _(" REF: Page 15, section 3.2.\n")); + break; + case PPD_LINE_TOO_LONG : + _cupsLangPuts(stdout, + _(" REF: Page 15, section 3.1.\n")); + break; + case PPD_ILLEGAL_CHARACTER : + _cupsLangPuts(stdout, + _(" REF: Page 15, section 3.1.\n")); + break; + case PPD_ILLEGAL_MAIN_KEYWORD : + _cupsLangPuts(stdout, + _(" REF: Pages 16-17, section 3.2.\n")); + break; + case PPD_ILLEGAL_OPTION_KEYWORD : + _cupsLangPuts(stdout, + _(" REF: Page 19, section 3.3.\n")); + break; + case PPD_ILLEGAL_TRANSLATION : + _cupsLangPuts(stdout, + _(" REF: Page 27, section 3.5.\n")); + break; + default : + break; + } + + check_basics(argv[i]); + } + } + + continue; + } + + /* + * Show the header and then perform basic conformance tests (limited + * only by what the CUPS PPD functions actually load...) + */ + + errors = 0; + ppdversion = 43; + + if (verbose > 0) + _cupsLangPuts(stdout, + _("\n DETAILED CONFORMANCE TEST RESULTS\n")); + + if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL && + attr->value) + ppdversion = (int)(10 * _cupsStrScand(attr->value, NULL, loc) + 0.5); + + for (j = 0; j < ppd->num_filters; j ++) + if (strstr(ppd->filters[j], "application/vnd.cups-raster")) + { + if (!test_raster(ppd, verbose)) + errors ++; + break; + } + + /* + * Look for default keywords with no matching option... + */ + + if (!(warn & WARN_DEFAULTS)) + errors = check_defaults(ppd, errors, verbose, 0); + + if ((attr = ppdFindAttr(ppd, "DefaultImageableArea", NULL)) == NULL) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED DefaultImageableArea\n" + " REF: Page 102, section 5.15.\n")); + } + + errors ++; + } + else if (ppdPageSize(ppd, attr->value) == NULL && + strcmp(attr->value, "Unknown")) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** BAD DefaultImageableArea %s!\n" + " REF: Page 102, section 5.15.\n"), + attr->value); + } + + errors ++; + } + else + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS DefaultImageableArea\n")); + } + + if ((attr = ppdFindAttr(ppd, "DefaultPaperDimension", NULL)) == NULL) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED DefaultPaperDimension\n" + " REF: Page 103, section 5.15.\n")); + } + + errors ++; + } + else if (ppdPageSize(ppd, attr->value) == NULL && + strcmp(attr->value, "Unknown")) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** BAD DefaultPaperDimension %s!\n" + " REF: Page 103, section 5.15.\n"), + attr->value); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS DefaultPaperDimension\n")); + + for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) + for (k = 0, option = group->options; k < group->num_options; k ++, option ++) + { + /* + * Verify that we have a default choice... + */ + + if (option->defchoice[0]) + { + if (ppdFindChoice(option, option->defchoice) == NULL && + strcmp(option->defchoice, "Unknown")) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** BAD Default%s %s\n" + " REF: Page 40, section 4.5.\n"), + option->keyword, option->defchoice); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPrintf(stdout, + _(" PASS Default%s\n"), + option->keyword); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** REQUIRED Default%s\n" + " REF: Page 40, section 4.5.\n"), + option->keyword); + } + + errors ++; + } + } + + if ((attr = ppdFindAttr(ppd, "FileVersion", NULL)) != NULL) + { + for (ptr = attr->value; *ptr; ptr ++) + if (!isdigit(*ptr & 255) && *ptr != '.') + break; + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad FileVersion \"%s\"\n" + " REF: Page 56, section 5.3.\n"), + attr->value); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS FileVersion\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED FileVersion\n" + " REF: Page 56, section 5.3.\n")); + } + + errors ++; + } + + if ((attr = ppdFindAttr(ppd, "FormatVersion", NULL)) != NULL) + { + ptr = attr->value; + if (*ptr == '4' && ptr[1] == '.') + { + + for (ptr += 2; *ptr; ptr ++) + if (!isdigit(*ptr & 255)) + break; + } + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad FormatVersion \"%s\"\n" + " REF: Page 56, section 5.3.\n"), + attr->value); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS FormatVersion\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED FormatVersion\n" + " REF: Page 56, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->lang_encoding != NULL) + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS LanguageEncoding\n")); + } + else if (ppdversion > 40) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED LanguageEncoding\n" + " REF: Pages 56-57, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->lang_version != NULL) + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS LanguageVersion\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED LanguageVersion\n" + " REF: Pages 57-58, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->manufacturer != NULL) + { + if (!strncasecmp(ppd->manufacturer, "Hewlett-Packard", 15) || + !strncasecmp(ppd->manufacturer, "Hewlett Packard", 15)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** BAD Manufacturer (should be " + "\"HP\")\n" + " REF: Page 211, table D.1.\n")); + } + + errors ++; + } + else if (!strncasecmp(ppd->manufacturer, "OkiData", 7) || + !strncasecmp(ppd->manufacturer, "Oki Data", 8)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** BAD Manufacturer (should be " + "\"Oki\")\n" + " REF: Page 211, table D.1.\n")); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS Manufacturer\n")); + } + else if (ppdversion >= 43) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED Manufacturer\n" + " REF: Pages 58-59, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->modelname != NULL) + { + for (ptr = ppd->modelname; *ptr; ptr ++) + if (!isalnum(*ptr & 255) && !strchr(" ./-+", *ptr)) + break; + + if (*ptr) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** BAD ModelName - \"%c\" not " + "allowed in string.\n" + " REF: Pages 59-60, section 5.3.\n"), + *ptr); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS ModelName\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED ModelName\n" + " REF: Pages 59-60, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->nickname != NULL) + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS NickName\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED NickName\n" + " REF: Page 60, section 5.3.\n")); + } + + errors ++; + } + + if (ppdFindOption(ppd, "PageSize") != NULL) + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS PageSize\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED PageSize\n" + " REF: Pages 99-100, section 5.14.\n")); + } + + errors ++; + } + + if (ppdFindOption(ppd, "PageRegion") != NULL) + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS PageRegion\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED PageRegion\n" + " REF: Page 100, section 5.14.\n")); + } + + errors ++; + } + + if (ppd->pcfilename != NULL) + { + if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS PCFileName\n")); + } + else if (!(ignore & WARN_FILENAME)) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED PCFileName\n" + " REF: Pages 61-62, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->product != NULL) + { + if (ppd->product[0] != '(' || + ppd->product[strlen(ppd->product) - 1] != ')') + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** BAD Product - not \"(string)\".\n" + " REF: Page 62, section 5.3.\n")); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS Product\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED Product\n" + " REF: Page 62, section 5.3.\n")); + } + + errors ++; + } + + if ((attr = ppdFindAttr(ppd, "PSVersion", NULL)) != NULL && + attr->value != NULL) + { + char junkstr[255]; /* Temp string */ + int junkint; /* Temp integer */ + + + if (sscanf(attr->value, "(%[^)])%d", junkstr, &junkint) != 2) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** BAD PSVersion - not \"(string) " + "int\".\n" + " REF: Pages 62-64, section 5.3.\n")); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS PSVersion\n")); + } + else + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED PSVersion\n" + " REF: Pages 62-64, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->shortnickname != NULL) + { + if (strlen(ppd->shortnickname) > 31) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** BAD ShortNickName - longer " + "than 31 chars.\n" + " REF: Pages 64-65, section 5.3.\n")); + } + + errors ++; + } + else if (verbose > 0) + _cupsLangPuts(stdout, _(" PASS ShortNickName\n")); + } + else if (ppdversion >= 43) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED ShortNickName\n" + " REF: Page 64-65, section 5.3.\n")); + } + + errors ++; + } + + if (ppd->patches != NULL && strchr(ppd->patches, '\"') && + strstr(ppd->patches, "*End")) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** BAD JobPatchFile attribute in file\n" + " REF: Page 24, section 3.4.\n")); + } + + errors ++; + } + + /* + * Check for page sizes without the corresponding ImageableArea or + * PaperDimension values... + */ + + if (ppd->num_sizes == 0) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPuts(stdout, + _(" **FAIL** REQUIRED PageSize\n" + " REF: Page 41, section 5.\n" + " REF: Page 99, section 5.14.\n")); + } + + errors ++; + } + else + { + for (j = 0, size = ppd->sizes; j < ppd->num_sizes; j ++, size ++) + { + /* + * Don't check custom size... + */ + + if (!strcmp(size->name, "Custom")) + continue; + + /* + * Check for ImageableArea... + */ + + if (size->left == 0.0 && size->bottom == 0.0 && + size->right == 0.0 && size->top == 0.0) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** REQUIRED ImageableArea for " + "PageSize %s\n" + " REF: Page 41, section 5.\n" + " REF: Page 102, section 5.15.\n"), + size->name); + } + + errors ++; + } + + /* + * Check for PaperDimension... + */ + + if (size->width == 0.0 && size->length == 0.0) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** REQUIRED PaperDimension " + "for PageSize %s\n" + " REF: Page 41, section 5.\n" + " REF: Page 103, section 5.15.\n"), + size->name); + } + + errors ++; + } + } + } + + /* + * Check for valid Resolution, JCLResolution, or SetResolution values... + */ + + if ((option = ppdFindOption(ppd, "Resolution")) == NULL) + if ((option = ppdFindOption(ppd, "JCLResolution")) == NULL) + option = ppdFindOption(ppd, "SetResolution"); + + if (option != NULL) + { + for (j = option->num_choices, choice = option->choices; j > 0; j --, choice ++) + { + /* + * Verify that all resolution options are of the form NNNdpi + * or NNNxNNNdpi... + */ + + xdpi = strtol(choice->choice, (char **)&ptr, 10); + if (ptr > choice->choice && xdpi > 0) + { + if (*ptr == 'x') + ydpi = strtol(ptr + 1, (char **)&ptr, 10); + else + ydpi = xdpi; + } + else + ydpi = xdpi; + + if (xdpi <= 0 || xdpi > 99999 || ydpi <= 0 || ydpi > 99999 || + strcmp(ptr, "dpi")) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** Bad %s choice %s!\n" + " REF: Page 84, section 5.9\n"), + option->keyword, choice->choice); + } + + errors ++; + } + } + } + + if ((attr = ppdFindAttr(ppd, "1284DeviceID", NULL)) && + strcmp(attr->name, "1284DeviceID")) + { + if (verbose >= 0) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" **FAIL** %s must be 1284DeviceID!\n" + " REF: Page 72, section 5.5\n"), + attr->name); + } + + errors ++; + } + + errors = check_case(ppd, errors, verbose); + + if (!(warn & WARN_CONSTRAINTS)) + errors = check_constraints(ppd, errors, verbose, 0); + + if (!(warn & WARN_FILTERS) && !(ignore & WARN_FILTERS)) + errors = check_filters(ppd, root, errors, verbose, 0); + + if (!(warn & WARN_PROFILES) && !(ignore & WARN_PROFILES)) + errors = check_profiles(ppd, root, errors, verbose, 0); + + if (!(warn & WARN_SIZES)) + errors = check_sizes(ppd, errors, verbose, 0); + + if (!(warn & WARN_TRANSLATIONS)) + errors = check_translations(ppd, errors, verbose, 0); + + if (!(warn & WARN_DUPLEX)) + errors = check_duplex(ppd, errors, verbose, 0); + + if ((attr = ppdFindAttr(ppd, "cupsLanguages", NULL)) != NULL && + attr->value) + { + /* + * This file contains localizations, check for conformance of the + * base translation... + */ + + if ((attr = ppdFindAttr(ppd, "LanguageEncoding", NULL)) != NULL) + { + if (!attr->value || strcmp(attr->value, "ISOLatin1")) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Bad LanguageEncoding %s - " + "must be ISOLatin1!\n"), + attr->value ? attr->value : "(null)"); + + errors ++; + } + + if (!ppd->lang_version || strcmp(ppd->lang_version, "English")) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Bad LanguageVersion %s - " + "must be English!\n"), + ppd->lang_version ? ppd->lang_version : "(null)"); + + errors ++; + } + + /* + * Loop through all options and choices... + */ + + for (option = ppdFirstOption(ppd); + option; + option = ppdNextOption(ppd)) + { + /* + * Check for special characters outside A0 to BF, F7, or F8 + * that are used for languages other than English. + */ + + for (ptr = option->text; *ptr; ptr ++) + if ((*ptr & 0x80) && (*ptr & 0xe0) != 0xa0 && + (*ptr & 0xff) != 0xf7 && (*ptr & 0xff) != 0xf8) + break; + + if (*ptr) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Default translation " + "string for option %s contains 8-bit " + "characters!\n"), + option->keyword); + + errors ++; + } + + for (j = 0; j < option->num_choices; j ++) + { + /* + * Check for special characters outside A0 to BF, F7, or F8 + * that are used for languages other than English. + */ + + for (ptr = option->choices[j].text; *ptr; ptr ++) + if ((*ptr & 0x80) && (*ptr & 0xe0) != 0xa0 && + (*ptr & 0xff) != 0xf7 && (*ptr & 0xff) != 0xf8) + break; + + if (*ptr) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Default translation " + "string for option %s choice %s contains " + "8-bit characters!\n"), + option->keyword, + option->choices[j].choice); + + errors ++; + } + } + } + } + } + + /* + * Final pass/fail notification... + */ + + if (errors) + status = ERROR_CONFORMANCE; + else if (!verbose) + _cupsLangPuts(stdout, _(" PASS\n")); + + if (verbose >= 0) + { + check_basics(argv[i]); + + if (warn & WARN_DEFAULTS) + errors = check_defaults(ppd, errors, verbose, 1); + + if (warn & WARN_CONSTRAINTS) + errors = check_constraints(ppd, errors, verbose, 1); + + if ((warn & WARN_FILTERS) && !(ignore & WARN_FILTERS)) + errors = check_filters(ppd, root, errors, verbose, 1); + + if ((warn & WARN_PROFILES) && !(ignore & WARN_PROFILES)) + errors = check_profiles(ppd, root, errors, verbose, 1); + + if (warn & WARN_SIZES) + errors = check_sizes(ppd, errors, verbose, 1); + else + errors = check_sizes(ppd, errors, verbose, 2); + + if (warn & WARN_TRANSLATIONS) + errors = check_translations(ppd, errors, verbose, 1); + + if (warn & WARN_DUPLEX) + errors = check_duplex(ppd, errors, verbose, 1); + + /* + * Look for legacy duplex keywords... + */ + + if ((option = ppdFindOption(ppd, "JCLDuplex")) == NULL) + if ((option = ppdFindOption(ppd, "EFDuplex")) == NULL) + option = ppdFindOption(ppd, "KD03Duplex"); + + if (option) + _cupsLangPrintf(stdout, + _(" WARN Duplex option keyword %s may not " + "work as expected and should be named Duplex!\n" + " REF: Page 122, section 5.17\n"), + option->keyword); + + /* + * Look for default keywords with no corresponding option... + */ + + for (j = 0; j < ppd->num_attrs; j ++) + { + attr = ppd->attrs[j]; + + if (!strcmp(attr->name, "DefaultColorSpace") || + !strcmp(attr->name, "DefaultColorSep") || + !strcmp(attr->name, "DefaultFont") || + !strcmp(attr->name, "DefaultHalftoneType") || + !strcmp(attr->name, "DefaultImageableArea") || + !strcmp(attr->name, "DefaultLeadingEdge") || + !strcmp(attr->name, "DefaultOutputOrder") || + !strcmp(attr->name, "DefaultPaperDimension") || + !strcmp(attr->name, "DefaultResolution") || + !strcmp(attr->name, "DefaultScreenProc") || + !strcmp(attr->name, "DefaultTransfer")) + continue; + + if (!strncmp(attr->name, "Default", 7) && + !ppdFindOption(ppd, attr->name + 7)) + _cupsLangPrintf(stdout, + _(" WARN %s has no corresponding " + "options!\n"), + attr->name); + } + + ppdMarkDefaults(ppd); + if (ppdConflicts(ppd)) + { + _cupsLangPuts(stdout, + _(" WARN Default choices conflicting!\n")); + + show_conflicts(ppd); + } + + if (ppdversion < 43) + { + _cupsLangPrintf(stdout, + _(" WARN Obsolete PPD version %.1f!\n" + " REF: Page 42, section 5.2.\n"), + 0.1f * ppdversion); + } + + if (!ppd->lang_encoding && ppdversion < 41) + { + _cupsLangPuts(stdout, + _(" WARN LanguageEncoding required by PPD " + "4.3 spec.\n" + " REF: Pages 56-57, section 5.3.\n")); + } + + if (!ppd->manufacturer && ppdversion < 43) + { + _cupsLangPuts(stdout, + _(" WARN Manufacturer required by PPD " + "4.3 spec.\n" + " REF: Pages 58-59, section 5.3.\n")); + } + + /* + * Treat a PCFileName attribute longer than 12 characters as + * a warning and not a hard error... + */ + + if (!(ignore & WARN_FILENAME) && ppd->pcfilename) + { + if (strlen(ppd->pcfilename) > 12) + { + _cupsLangPuts(stdout, + _(" WARN PCFileName longer than 8.3 in " + "violation of PPD spec.\n" + " REF: Pages 61-62, section " + "5.3.\n")); + } + + if (!strcasecmp(ppd->pcfilename, "unused.ppd")) + _cupsLangPuts(stdout, + _(" WARN PCFileName should contain a " + "unique filename.\n" + " REF: Pages 61-62, section " + "5.3.\n")); + } + + if (!ppd->shortnickname && ppdversion < 43) + { + _cupsLangPuts(stdout, + _(" WARN ShortNickName required by PPD " + "4.3 spec.\n" + " REF: Pages 64-65, section 5.3.\n")); + } + + /* + * Check the Protocols line and flag PJL + BCP since TBCP is + * usually used with PJL... + */ + + if (ppd->protocols) + { + if (strstr(ppd->protocols, "PJL") && + strstr(ppd->protocols, "BCP") && + !strstr(ppd->protocols, "TBCP")) + { + _cupsLangPuts(stdout, + _(" WARN Protocols contains both PJL " + "and BCP; expected TBCP.\n" + " REF: Pages 78-79, section 5.7.\n")); + } + + if (strstr(ppd->protocols, "PJL") && + (!ppd->jcl_begin || !ppd->jcl_end || !ppd->jcl_ps)) + { + _cupsLangPuts(stdout, + _(" WARN Protocols contains PJL but JCL " + "attributes are not set.\n" + " REF: Pages 78-79, section 5.7.\n")); + } + } + + /* + * Check for options with a common prefix, e.g. Duplex and Duplexer, + * which are errors according to the spec but won't cause problems + * with CUPS specifically... + */ + + for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) + for (k = 0, option = group->options; k < group->num_options; k ++, option ++) + { + len = (int)strlen(option->keyword); + + for (m = 0, group2 = ppd->groups; + m < ppd->num_groups; + m ++, group2 ++) + for (n = 0, option2 = group2->options; + n < group2->num_options; + n ++, option2 ++) + if (option != option2 && + len < (int)strlen(option2->keyword) && + !strncmp(option->keyword, option2->keyword, len)) + { + _cupsLangPrintf(stdout, + _(" WARN %s shares a common " + "prefix with %s\n" + " REF: Page 15, section " + "3.2.\n"), + option->keyword, option2->keyword); + } + } + } + + if (verbose > 0) + { + if (errors) + _cupsLangPrintf(stdout, _(" %d ERRORS FOUND\n"), errors); + else + _cupsLangPuts(stdout, _(" NO ERRORS FOUND\n")); + } + + /* + * Then list the options, if "-v" was provided... + */ + + if (verbose > 1) + { + _cupsLangPrintf(stdout, + "\n" + " language_level = %d\n" + " color_device = %s\n" + " variable_sizes = %s\n" + " landscape = %d\n", + ppd->language_level, + ppd->color_device ? "TRUE" : "FALSE", + ppd->variable_sizes ? "TRUE" : "FALSE", + ppd->landscape); + + switch (ppd->colorspace) + { + case PPD_CS_CMYK : + _cupsLangPuts(stdout, " colorspace = PPD_CS_CMYK\n"); + break; + case PPD_CS_CMY : + _cupsLangPuts(stdout, " colorspace = PPD_CS_CMY\n"); + break; + case PPD_CS_GRAY : + _cupsLangPuts(stdout, " colorspace = PPD_CS_GRAY\n"); + break; + case PPD_CS_RGB : + _cupsLangPuts(stdout, " colorspace = PPD_CS_RGB\n"); + break; + default : + _cupsLangPuts(stdout, " colorspace = \n"); + break; + } + + _cupsLangPrintf(stdout, " num_emulations = %d\n", + ppd->num_emulations); + for (j = 0; j < ppd->num_emulations; j ++) + _cupsLangPrintf(stdout, " emulations[%d] = %s\n", + j, ppd->emulations[j].name); + + _cupsLangPrintf(stdout, " lang_encoding = %s\n", + ppd->lang_encoding); + _cupsLangPrintf(stdout, " lang_version = %s\n", + ppd->lang_version); + _cupsLangPrintf(stdout, " modelname = %s\n", ppd->modelname); + _cupsLangPrintf(stdout, " ttrasterizer = %s\n", + ppd->ttrasterizer == NULL ? "None" : ppd->ttrasterizer); + _cupsLangPrintf(stdout, " manufacturer = %s\n", + ppd->manufacturer); + _cupsLangPrintf(stdout, " product = %s\n", ppd->product); + _cupsLangPrintf(stdout, " nickname = %s\n", ppd->nickname); + _cupsLangPrintf(stdout, " shortnickname = %s\n", + ppd->shortnickname); + _cupsLangPrintf(stdout, " patches = %d bytes\n", + ppd->patches == NULL ? 0 : (int)strlen(ppd->patches)); + + _cupsLangPrintf(stdout, " num_groups = %d\n", ppd->num_groups); + for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) + { + _cupsLangPrintf(stdout, " group[%d] = %s\n", + j, group->text); + + for (k = 0, option = group->options; k < group->num_options; k ++, option ++) + { + _cupsLangPrintf(stdout, + " 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") || + !strcmp(option->keyword, "PageRegion")) + { + for (m = option->num_choices, choice = option->choices; + m > 0; + m --, choice ++) + { + size = ppdPageSize(ppd, choice->choice); + + if (size == NULL) + _cupsLangPrintf(stdout, + " %s (%s) = ERROR", + choice->choice, choice->text); + else + _cupsLangPrintf(stdout, + " %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)) + _cupsLangPuts(stdout, " *\n"); + else + _cupsLangPuts(stdout, "\n"); + } + } + else + { + for (m = option->num_choices, choice = option->choices; + m > 0; + m --, choice ++) + { + _cupsLangPrintf(stdout, " %s (%s)", + choice->choice, choice->text); + + if (!strcmp(option->defchoice, choice->choice)) + _cupsLangPuts(stdout, " *\n"); + else + _cupsLangPuts(stdout, "\n"); + } + } + } + } + + _cupsLangPrintf(stdout, " num_consts = %d\n", + ppd->num_consts); + for (j = 0; j < ppd->num_consts; j ++) + _cupsLangPrintf(stdout, + " consts[%d] = *%s %s *%s %s\n", + j, ppd->consts[j].option1, ppd->consts[j].choice1, + ppd->consts[j].option2, ppd->consts[j].choice2); + + _cupsLangPrintf(stdout, " num_profiles = %d\n", + ppd->num_profiles); + for (j = 0; j < ppd->num_profiles; j ++) + _cupsLangPrintf(stdout, + " 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]); + + _cupsLangPrintf(stdout, " num_fonts = %d\n", ppd->num_fonts); + for (j = 0; j < ppd->num_fonts; j ++) + _cupsLangPrintf(stdout, " fonts[%d] = %s\n", + j, ppd->fonts[j]); + + _cupsLangPrintf(stdout, " num_attrs = %d\n", ppd->num_attrs); + for (j = 0; j < ppd->num_attrs; j ++) + _cupsLangPrintf(stdout, + " attrs[%d] = %s %s%s%s: \"%s\"\n", j, + ppd->attrs[j]->name, ppd->attrs[j]->spec, + ppd->attrs[j]->text[0] ? "/" : "", + ppd->attrs[j]->text, + ppd->attrs[j]->value ? + ppd->attrs[j]->value : "(null)"); + } + + ppdClose(ppd); + } + + if (!files) + usage(); + + return (status); +} + + +/* + * 'check_basics()' - Check for CR LF, mixed line endings, and blank lines. + */ + +static void +check_basics(const char *filename) /* I - PPD file to check */ +{ + cups_file_t *fp; /* File pointer */ + int ch; /* Current character */ + int col, /* Current column */ + whitespace; /* Only seen whitespace? */ + int eol; /* Line endings */ + int linenum; /* Line number */ + int mixed; /* Mixed line endings? */ + + + if ((fp = cupsFileOpen(filename, "r")) == NULL) + return; + + linenum = 1; + col = 0; + eol = EOL_NONE; + mixed = 0; + whitespace = 1; + + while ((ch = cupsFileGetChar(fp)) != EOF) + { + if (ch == '\r' || ch == '\n') + { + if (ch == '\n') + { + if (eol == EOL_NONE) + eol = EOL_LF; + else if (eol != EOL_LF) + mixed = 1; + } + else if (ch == '\r') + { + if (cupsFilePeekChar(fp) == '\n') + { + cupsFileGetChar(fp); + + if (eol == EOL_NONE) + eol = EOL_CRLF; + else if (eol != EOL_CRLF) + mixed = 1; + } + else if (eol == EOL_NONE) + eol = EOL_CR; + else if (eol != EOL_CR) + mixed = 1; + } + + if (col > 0 && whitespace) + _cupsLangPrintf(stdout, + _(" WARN Line %d only contains whitespace!\n"), + linenum); + + linenum ++; + col = 0; + whitespace = 1; + } + else + { + if (ch != ' ' && ch != '\t') + whitespace = 0; + + col ++; + } + } + + if (mixed) + _cupsLangPuts(stdout, + _(" WARN File contains a mix of CR, LF, and " + "CR LF line endings!\n")); + + if (eol == EOL_CRLF) + _cupsLangPuts(stdout, + _(" WARN Non-Windows PPD files should use lines " + "ending with only LF, not CR LF!\n")); + + cupsFileClose(fp); +} + + +/* + * 'check_constraints()' - Check UIConstraints in the PPD file. + */ + +static int /* O - Errors found */ +check_constraints(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping var */ + const char *prefix; /* WARN/FAIL prefix */ + ppd_const_t *c; /* Current UIConstraints data */ + ppd_attr_t *constattr; /* Current cupsUIConstraints attribute */ + const char *vptr; /* Pointer into constraint value */ + char option[PPD_MAX_NAME], + /* Option name/MainKeyword */ + choice[PPD_MAX_NAME], + /* Choice/OptionKeyword */ + *ptr; /* Pointer into option or choice */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + ppd_option_t *o; /* PPD option */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + + /* + * See what kind of constraint data we have in the PPD... + */ + + if ((constattr = ppdFindAttr(ppd, "cupsUIConstraints", NULL)) != NULL) + { + /* + * Check new-style cupsUIConstraints data... + */ + + for (; constattr; + constattr = ppdFindNextAttr(ppd, "cupsUIConstraints", NULL)) + { + if (!constattr->value) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Empty cupsUIConstraints %s!\n"), + prefix, constattr->spec); + + if (!warn) + errors ++; + + continue; + } + + for (i = 0, vptr = strchr(constattr->value, '*'); + vptr; + i ++, vptr = strchr(vptr + 1, '*')); + + if (i == 0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Bad cupsUIConstraints %s: \"%s\"!\n"), + prefix, constattr->spec, constattr->value); + + if (!warn) + errors ++; + + continue; + } + + cupsArraySave(ppd->sorted_attrs); + + if (constattr->spec[0] && + !ppdFindAttr(ppd, "cupsUIResolver", constattr->spec)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing cupsUIResolver %s!\n"), + prefix, constattr->spec); + + if (!warn) + errors ++; + } + + cupsArrayRestore(ppd->sorted_attrs); + + num_options = 0; + options = NULL; + + for (vptr = strchr(constattr->value, '*'); + vptr; + vptr = strchr(vptr, '*')) + { + /* + * Extract "*Option Choice" or just "*Option"... + */ + + for (vptr ++, ptr = option; *vptr && !isspace(*vptr & 255); vptr ++) + if (ptr < (option + sizeof(option) - 1)) + *ptr++ = *vptr; + + *ptr = '\0'; + + while (isspace(*vptr & 255)) + vptr ++; + + if (*vptr == '*') + choice[0] = '\0'; + else + { + for (ptr = choice; *vptr && !isspace(*vptr & 255); vptr ++) + if (ptr < (choice + sizeof(choice) - 1)) + *ptr++ = *vptr; + + *ptr = '\0'; + } + + if (!strncasecmp(option, "Custom", 6) && !strcasecmp(choice, "True")) + { + _cups_strcpy(option, option + 6); + strcpy(choice, "Custom"); + } + + if ((o = ppdFindOption(ppd, option)) == NULL) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing option %s in " + "cupsUIConstraints %s: \"%s\"!\n"), + prefix, option, constattr->spec, constattr->value); + + if (!warn) + errors ++; + + continue; + } + + if (choice[0] && !ppdFindChoice(o, choice)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing choice *%s %s in " + "cupsUIConstraints %s: \"%s\"!\n"), + prefix, option, choice, constattr->spec, + constattr->value); + + if (!warn) + errors ++; + + continue; + } + + if (choice[0]) + num_options = cupsAddOption(option, choice, num_options, &options); + else + { + for (i = 0; i < o->num_choices; i ++) + if (strcasecmp(o->choices[i].choice, "None") && + strcasecmp(o->choices[i].choice, "Off") && + strcasecmp(o->choices[i].choice, "False")) + { + num_options = cupsAddOption(option, o->choices[i].choice, + num_options, &options); + break; + } + } + } + + /* + * Resolvers must list at least two options... + */ + + if (num_options < 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s cupsUIResolver %s does not list at least " + "two different options!\n"), + prefix, constattr->spec); + + if (!warn) + errors ++; + } + + /* + * Test the resolver... + */ + + if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s cupsUIResolver %s causes a loop!\n"), + prefix, constattr->spec); + + if (!warn) + errors ++; + } + + cupsFreeOptions(num_options, options); + } + } + else + { + /* + * Check old-style [Non]UIConstraints data... + */ + + for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) + { + if (!strncasecmp(c->option1, "Custom", 6) && + !strcasecmp(c->choice1, "True")) + { + strcpy(option, c->option1 + 6); + strcpy(choice, "Custom"); + } + else + { + strcpy(option, c->option1); + strcpy(choice, c->choice1); + } + + if ((o = ppdFindOption(ppd, option)) == NULL) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing option %s in " + "UIConstraints \"*%s %s *%s %s\"!\n"), + prefix, c->option1, + c->option1, c->choice1, c->option2, c->choice2); + + if (!warn) + errors ++; + } + else if (choice[0] && !ppdFindChoice(o, choice)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing choice *%s %s in " + "UIConstraints \"*%s %s *%s %s\"!\n"), + prefix, c->option1, c->choice1, + c->option1, c->choice1, c->option2, c->choice2); + + if (!warn) + errors ++; + } + + if (!strncasecmp(c->option2, "Custom", 6) && + !strcasecmp(c->choice2, "True")) + { + strcpy(option, c->option2 + 6); + strcpy(choice, "Custom"); + } + else + { + strcpy(option, c->option2); + strcpy(choice, c->choice2); + } + + if ((o = ppdFindOption(ppd, option)) == NULL) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing option %s in " + "UIConstraints \"*%s %s *%s %s\"!\n"), + prefix, c->option2, + c->option1, c->choice1, c->option2, c->choice2); + + if (!warn) + errors ++; + } + else if (choice[0] && !ppdFindChoice(o, choice)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Missing choice *%s %s in " + "UIConstraints \"*%s %s *%s %s\"!\n"), + prefix, c->option2, c->choice2, + c->option1, c->choice1, c->option2, c->choice2); + + if (!warn) + errors ++; + } + } + } + + return (errors); +} + + +/* + * 'check_case()' - Check that there are no duplicate groups, options, + * or choices that differ only by case. + */ + +static int /* O - Errors found */ +check_case(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose) /* I - Verbosity level */ +{ + int i, j; /* Looping vars */ + ppd_group_t *groupa, /* First group */ + *groupb; /* Second group */ + ppd_option_t *optiona, /* First option */ + *optionb; /* Second option */ + ppd_choice_t *choicea, /* First choice */ + *choiceb; /* Second choice */ + + + /* + * Check that the groups do not have any duplicate names... + */ + + for (i = ppd->num_groups, groupa = ppd->groups; i > 1; i --, groupa ++) + for (j = i - 1, groupb = groupa + 1; j > 0; j --, groupb ++) + if (!strcasecmp(groupa->name, groupb->name)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Group names %s and %s differ only " + "by case!\n"), + groupa->name, groupb->name); + + errors ++; + } + + /* + * Check that the options do not have any duplicate names... + */ + + for (optiona = ppdFirstOption(ppd); optiona; optiona = ppdNextOption(ppd)) + { + cupsArraySave(ppd->options); + for (optionb = ppdNextOption(ppd); optionb; optionb = ppdNextOption(ppd)) + if (!strcasecmp(optiona->keyword, optionb->keyword)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Option names %s and %s differ only " + "by case!\n"), + optiona->keyword, optionb->keyword); + + errors ++; + } + cupsArrayRestore(ppd->options); + + /* + * Then the choices... + */ + + for (i = optiona->num_choices, choicea = optiona->choices; + i > 1; + i --, choicea ++) + for (j = i - 1, choiceb = choicea + 1; j > 0; j --, choiceb ++) + if (!strcmp(choicea->choice, choiceb->choice)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Multiple occurrences of %s " + "choice name %s!\n"), + optiona->keyword, choicea->choice); + + errors ++; + + choicea ++; + i --; + break; + } + else if (!strcasecmp(choicea->choice, choiceb->choice)) + { + if (!errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** %s choice names %s and %s " + "differ only by case!\n"), + optiona->keyword, choicea->choice, choiceb->choice); + + errors ++; + } + } + + /* + * Return the number of errors found... + */ + + return (errors); +} + + +/* + * 'check_defaults()' - Check default option keywords in the PPD file. + */ + +static int /* O - Errors found */ +check_defaults(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int j, k; /* Looping vars */ + ppd_attr_t *attr; /* PPD attribute */ + ppd_option_t *option; /* Standard UI option */ + const char *prefix; /* WARN/FAIL prefix */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + for (j = 0; j < ppd->num_attrs; j ++) + { + attr = ppd->attrs[j]; + + if (!strcmp(attr->name, "DefaultColorSpace") || + !strcmp(attr->name, "DefaultFont") || + !strcmp(attr->name, "DefaultHalftoneType") || + !strcmp(attr->name, "DefaultImageableArea") || + !strcmp(attr->name, "DefaultLeadingEdge") || + !strcmp(attr->name, "DefaultOutputOrder") || + !strcmp(attr->name, "DefaultPaperDimension") || + !strcmp(attr->name, "DefaultResolution") || + !strcmp(attr->name, "DefaultTransfer")) + continue; + + if (!strncmp(attr->name, "Default", 7)) + { + if ((option = ppdFindOption(ppd, attr->name + 7)) != NULL && + strcmp(attr->value, "Unknown")) + { + /* + * Check that the default option value matches a choice... + */ + + for (k = 0; k < option->num_choices; k ++) + if (!strcmp(option->choices[k].choice, attr->value)) + break; + + if (k >= option->num_choices) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s %s %s does not exist!\n"), + prefix, attr->name, attr->value); + + if (!warn) + errors ++; + } + } + } + } + + return (errors); +} + + +/* + * 'check_duplex()' - Check duplex keywords in the PPD file. + */ + +static int /* O - Errors found */ +check_duplex(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Error found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping var */ + ppd_option_t *option; /* PPD option */ + ppd_choice_t *choice; /* Current choice */ + const char *prefix; /* Message prefix */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + /* + * Check for a duplex option, and for standard values... + */ + + if ((option = ppdFindOption(ppd, "Duplex")) != NULL) + { + if (!ppdFindChoice(option, "None")) + { + if (verbose >= 0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s REQUIRED %s does not define " + "choice None!\n" + " REF: Page 122, section 5.17\n"), + prefix, option->keyword); + } + + if (!warn) + errors ++; + } + + for (i = option->num_choices, choice = option->choices; + i > 0; + i --, choice ++) + if (strcmp(choice->choice, "None") && + strcmp(choice->choice, "DuplexNoTumble") && + strcmp(choice->choice, "DuplexTumble") && + strcmp(choice->choice, "SimplexTumble")) + { + if (verbose >= 0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + _cupsLangPrintf(stdout, + _(" %s Bad %s choice %s!\n" + " REF: Page 122, section 5.17\n"), + prefix, option->keyword, choice->choice); + } + + if (!warn) + errors ++; + } + } + + return (errors); +} + + +/* + * 'check_filters()' - Check filters in the PPD file. + */ + +static int /* O - Errors found */ +check_filters(ppd_file_t *ppd, /* I - PPD file */ + const char *root, /* I - Root directory */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping var */ + ppd_attr_t *attr; /* PPD attribute */ + const char *ptr; /* Pointer into string */ + char super[16], /* Super-type for filter */ + type[256], /* Type for filter */ + program[1024], /* Program/filter name */ + pathprog[1024]; /* Complete path to program/filter */ + int cost; /* Cost of filter */ + const char *prefix; /* WARN/FAIL prefix */ + struct stat fileinfo; /* File information */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + /* + * cupsFilter + */ + + for (i = 0; i < ppd->num_filters; i ++) + { + if (sscanf(ppd->filters[i], "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, + &cost, program) != 4) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad cupsFilter value \"%s\"!\n"), + prefix, ppd->filters[i]); + + if (!warn) + errors ++; + } + else if (strcmp(program, "-")) + { + if (program[0] == '/') + snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); + else + { + if ((ptr = getenv("CUPS_SERVERBIN")) == NULL) + ptr = CUPS_SERVERBIN; + + if (*ptr == '/' || !*root) + snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr, + program); + else + snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr, + program); + } + + if (stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing cupsFilter " + "file \"%s\"\n"), prefix, pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on cupsFilter " + "file \"%s\"\n"), prefix, pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("cupsFilter", pathprog, errors, verbose, warn); + } + } + + /* + * cupsPreFilter + */ + + for (attr = ppdFindAttr(ppd, "cupsPreFilter", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsPreFilter", NULL)) + { + if (strcmp(attr->name, "cupsPreFilter")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s!\n"), + prefix, attr->name, "cupsPreFilter"); + + if (!warn) + errors ++; + } + + if (!attr->value || + sscanf(attr->value, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, + &cost, program) != 4) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad cupsPreFilter value \"%s\"!\n"), + prefix, attr->value ? attr->value : ""); + + if (!warn) + errors ++; + } + else if (strcmp(program, "-")) + { + if (program[0] == '/') + snprintf(pathprog, sizeof(pathprog), "%s%s", root, program); + else + { + if ((ptr = getenv("CUPS_SERVERBIN")) == NULL) + ptr = CUPS_SERVERBIN; + + if (*ptr == '/' || !*root) + snprintf(pathprog, sizeof(pathprog), "%s%s/filter/%s", root, ptr, + program); + else + snprintf(pathprog, sizeof(pathprog), "%s/%s/filter/%s", root, ptr, + program); + } + + if (stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing cupsPreFilter " + "file \"%s\"\n"), prefix, pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_PROGRAM) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "cupsPreFilter file \"%s\"\n"), prefix, + pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("cupsPreFilter", pathprog, errors, verbose, warn); + } + } + +#ifdef __APPLE__ + /* + * APDialogExtension + */ + + for (attr = ppdFindAttr(ppd, "APDialogExtension", NULL); + attr != NULL; + attr = ppdFindNextAttr(ppd, "APDialogExtension", NULL)) + { + if (strcmp(attr->name, "APDialogExtension")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s!\n"), + prefix, attr->name, "APDialogExtension"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing " + "APDialogExtension file \"%s\"\n"), + prefix, pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "APDialogExtension file \"%s\"\n"), prefix, + pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APDialogExtension", pathprog, errors, verbose, + warn); + } + + /* + * APPrinterIconPath + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL) + { + if (strcmp(attr->name, "APPrinterIconPath")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s!\n"), + prefix, attr->name, "APPrinterIconPath"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing " + "APPrinterIconPath file \"%s\"\n"), + prefix, pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DATAFILE) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "APPrinterIconPath file \"%s\"\n"), prefix, + pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APPrinterIconPath", pathprog, errors, verbose, + warn); + } + + /* + * APPrinterLowInkTool + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterLowInkTool", NULL)) != NULL) + { + if (strcmp(attr->name, "APPrinterLowInkTool")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s!\n"), + prefix, attr->name, "APPrinterLowInkTool"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing " + "APPrinterLowInkTool file \"%s\"\n"), + prefix, pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "APPrinterLowInkTool file \"%s\"\n"), prefix, + pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APPrinterLowInkTool", pathprog, errors, verbose, + warn); + } + + /* + * APPrinterUtilityPath + */ + + if ((attr = ppdFindAttr(ppd, "APPrinterUtilityPath", NULL)) != NULL) + { + if (strcmp(attr->name, "APPrinterUtilityPath")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s!\n"), + prefix, attr->name, "APPrinterUtilityPath"); + + if (!warn) + errors ++; + } + + snprintf(pathprog, sizeof(pathprog), "%s%s", root, + attr->value ? attr->value : "(null)"); + + if (!attr->value || stat(pathprog, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing " + "APPrinterUtilityPath file \"%s\"\n"), + prefix, pathprog); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "APPrinterUtilityPath file \"%s\"\n"), prefix, + pathprog); + + if (!warn) + errors ++; + } + else + errors = valid_path("APPrinterUtilityPath", pathprog, errors, verbose, + warn); + } + + /* + * APScanAppBundleID and APScanAppPath + */ + + if ((attr = ppdFindAttr(ppd, "APScanAppPath", NULL)) != NULL) + { + if (strcmp(attr->name, "APScanAppPath")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad spelling of %s - should be %s!\n"), + prefix, attr->name, "APScanAppPath"); + + if (!warn) + errors ++; + } + + if (!attr->value || stat(attr->value, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing " + "APScanAppPath file \"%s\"\n"), + prefix, attr->value ? attr->value : ""); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DIRECTORY) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "APScanAppPath file \"%s\"\n"), prefix, + attr->value); + + if (!warn) + errors ++; + } + else + errors = valid_path("APScanAppPath", attr->value, errors, verbose, + warn); + + if (ppdFindAttr(ppd, "APScanAppBundleID", NULL)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Cannot provide both " + "APScanAppPath and APScanAppBundleID!\n"), + prefix); + + if (!warn) + errors ++; + } + } +#endif /* __APPLE__ */ + + return (errors); +} + + +/* + * 'check_profiles()' - Check ICC color profiles in the PPD file. + */ + +static int /* O - Errors found */ +check_profiles(ppd_file_t *ppd, /* I - PPD file */ + const char *root, /* I - Root directory */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping var */ + ppd_attr_t *attr; /* PPD attribute */ + const char *ptr; /* Pointer into string */ + const char *prefix; /* WARN/FAIL prefix */ + char filename[1024]; /* Profile filename */ + struct stat fileinfo; /* File information */ + int num_profiles = 0; /* Number of profiles */ + unsigned hash, /* Current hash value */ + hashes[1000]; /* Hash values of profile names */ + const char *specs[1000]; /* Specifiers for profiles */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + for (attr = ppdFindAttr(ppd, "cupsICCProfile", NULL); + attr; + attr = ppdFindNextAttr(ppd, "cupsICCProfile", NULL)) + { + /* + * Check for valid selector... + */ + + for (i = 0, ptr = strchr(attr->spec, '.'); ptr; ptr = strchr(ptr + 1, '.')) + i ++; + + if (!attr->value || i < 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad cupsICCProfile %s!\n"), + prefix, attr->spec); + + if (!warn) + errors ++; + + continue; + } + + /* + * Check for valid profile filename... + */ + + if (attr->value[0] == '/') + snprintf(filename, sizeof(filename), "%s%s", root, attr->value); + else + { + if ((ptr = getenv("CUPS_DATADIR")) == NULL) + ptr = CUPS_DATADIR; + + if (*ptr == '/' || !*root) + snprintf(filename, sizeof(filename), "%s%s/profiles/%s", root, ptr, + attr->value); + else + snprintf(filename, sizeof(filename), "%s/%s/profiles/%s", root, ptr, + attr->value); + } + + if (stat(filename, &fileinfo)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Missing cupsICCProfile " + "file \"%s\"!\n"), prefix, filename); + + if (!warn) + errors ++; + } + else if (fileinfo.st_uid != 0 || + (fileinfo.st_mode & MODE_WRITE) || + (fileinfo.st_mode & MODE_MASK) != MODE_DATAFILE) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, _(" %s Bad permissions on " + "cupsICCProfile file \"%s\"\n"), prefix, + filename); + + if (!warn) + errors ++; + } + else + errors = valid_path("cupsICCProfile", filename, errors, verbose, warn); + + /* + * Check for hash collisions... + */ + + hash = _ppdHashName(attr->spec); + + if (num_profiles > 0) + { + for (i = 0; i < num_profiles; i ++) + if (hashes[i] == hash) + break; + + if (i < num_profiles) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s cupsICCProfile %s hash value " + "collides with %s!\n"), prefix, attr->spec, + specs[i]); + + if (!warn) + errors ++; + } + } + + /* + * Remember up to 1000 profiles... + */ + + if (num_profiles < 1000) + { + hashes[num_profiles] = hash; + specs[num_profiles] = attr->spec; + num_profiles ++; + } + } + + return (errors); +} + + +/* + * 'check_sizes()' - Check media sizes in the PPD file. + */ + +static int /* O - Errors found */ +check_sizes(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int i; /* Looping vars */ + ppd_size_t *size; /* Current size */ + int width, /* Custom width */ + length; /* Custom length */ + const char *prefix; /* WARN/FAIL prefix */ + ppd_option_t *page_size, /* PageSize option */ + *page_region; /* PageRegion option */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + if ((page_size = ppdFindOption(ppd, "PageSize")) == NULL && warn != 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing REQUIRED PageSize option!\n" + " REF: Page 99, section 5.14.\n"), + prefix); + + if (!warn) + errors ++; + } + + if ((page_region = ppdFindOption(ppd, "PageRegion")) == NULL && warn != 2) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing REQUIRED PageRegion option!\n" + " REF: Page 100, section 5.14.\n"), + prefix); + + if (!warn) + errors ++; + } + + for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++) + { + /* + * Check that the size name is standard... + */ + + if (!strcmp(size->name, "Custom")) + { + /* + * Skip custom page size... + */ + + continue; + } + else if (warn != 2 && size->name[0] == 'w' && + sscanf(size->name, "w%dh%d", &width, &length) == 2) + { + /* + * Validate device-specific size wNNNhNNN should have proper width and + * length... + */ + + if (fabs(width - size->width) >= 1.0 || + fabs(length - size->length) >= 1.0) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" has unexpected dimensions " + "(%gx%g)!\n"), + prefix, size->name, size->width, size->length); + + if (!warn) + errors ++; + } + } + + /* + * Verify that the size is defined for both PageSize and PageRegion... + */ + + if (warn != 2 && !ppdFindChoice(page_size, size->name)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" defined for %s but not for " + "%s!\n"), + prefix, size->name, "PageRegion", "PageSize"); + + if (!warn) + errors ++; + } + else if (warn != 2 && !ppdFindChoice(page_region, size->name)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Size \"%s\" defined for %s but not for " + "%s!\n"), + prefix, size->name, "PageSize", "PageRegion"); + + if (!warn) + errors ++; + } + } + + return (errors); +} + + +/* + * 'check_translations()' - Check translations in the PPD file. + */ + +static int /* O - Errors found */ +check_translations(ppd_file_t *ppd, /* I - PPD file */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + int j; /* Looping var */ + ppd_attr_t *attr; /* PPD attribute */ + cups_array_t *languages; /* Array of languages */ + int langlen; /* Length of language */ + char *language, /* Current language */ + keyword[PPD_MAX_NAME], /* Localization keyword (full) */ + llkeyword[PPD_MAX_NAME],/* Localization keyword (base) */ + ckeyword[PPD_MAX_NAME], /* Custom option keyword (full) */ + cllkeyword[PPD_MAX_NAME]; + /* Custom option keyword (base) */ + ppd_option_t *option; /* Standard UI option */ + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + char ll[3]; /* Base language */ + const char *prefix; /* WARN/FAIL prefix */ + const char *text; /* Pointer into UI text */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + if ((languages = _ppdGetLanguages(ppd)) != NULL) + { + /* + * This file contains localizations, check them... + */ + + for (language = (char *)cupsArrayFirst(languages); + language; + language = (char *)cupsArrayNext(languages)) + { + langlen = (int)strlen(language); + if (langlen != 2 && langlen != 5) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad language \"%s\"!\n"), + prefix, language); + + if (!warn) + errors ++; + + continue; + } + + if (!strcmp(language, "en")) + continue; + + strlcpy(ll, language, sizeof(ll)); + + /* + * Loop through all options and choices... + */ + + for (option = ppdFirstOption(ppd); + option; + option = ppdNextOption(ppd)) + { + if (!strcmp(option->keyword, "PageRegion")) + continue; + + snprintf(keyword, sizeof(keyword), "%s.Translation", language); + snprintf(llkeyword, sizeof(llkeyword), "%s.Translation", ll); + + if ((attr = ppdFindAttr(ppd, keyword, option->keyword)) == NULL && + (attr = ppdFindAttr(ppd, llkeyword, option->keyword)) == NULL) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing \"%s\" translation " + "string for option %s!\n"), + prefix, language, option->keyword); + + if (!warn) + errors ++; + } + else if (!valid_utf8(attr->text)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad UTF-8 \"%s\" translation " + "string for option %s!\n"), + prefix, language, option->keyword); + + if (!warn) + errors ++; + } + + snprintf(keyword, sizeof(keyword), "%s.%s", language, + option->keyword); + snprintf(llkeyword, sizeof(llkeyword), "%s.%s", ll, + option->keyword); + + for (j = 0; j < option->num_choices; j ++) + { + /* + * First see if this choice is a number; if so, don't require + * translation... + */ + + for (text = option->choices[j].text; *text; text ++) + if (!strchr("0123456789-+.", *text)) + break; + + if (!*text) + continue; + + /* + * Check custom choices differently... + */ + + if (!strcasecmp(option->choices[j].choice, "Custom") && + (coption = ppdFindCustomOption(ppd, + option->keyword)) != NULL) + { + snprintf(ckeyword, sizeof(ckeyword), "%s.Custom%s", + language, option->keyword); + + if ((attr = ppdFindAttr(ppd, ckeyword, "True")) != NULL && + !valid_utf8(attr->text)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad UTF-8 \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + prefix, language, + ckeyword + 1 + strlen(language), + "True"); + + if (!warn) + errors ++; + } + + if (strcasecmp(option->keyword, "PageSize")) + { + for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + cparam; + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params)) + { + snprintf(ckeyword, sizeof(ckeyword), "%s.ParamCustom%s", + language, option->keyword); + snprintf(cllkeyword, sizeof(cllkeyword), "%s.ParamCustom%s", + ll, option->keyword); + + if ((attr = ppdFindAttr(ppd, ckeyword, + cparam->name)) == NULL && + (attr = ppdFindAttr(ppd, cllkeyword, + cparam->name)) == NULL) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + prefix, language, + ckeyword + 1 + strlen(language), + cparam->name); + + if (!warn) + errors ++; + } + else if (!valid_utf8(attr->text)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad UTF-8 \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + prefix, language, + ckeyword + 1 + strlen(language), + cparam->name); + + if (!warn) + errors ++; + } + } + } + } + else if ((attr = ppdFindAttr(ppd, keyword, + option->choices[j].choice)) == NULL && + (attr = ppdFindAttr(ppd, llkeyword, + option->choices[j].choice)) == NULL) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Missing \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + prefix, language, option->keyword, + option->choices[j].choice); + + if (!warn) + errors ++; + } + else if (!valid_utf8(attr->text)) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s Bad UTF-8 \"%s\" " + "translation string for option %s, " + "choice %s!\n"), + prefix, language, option->keyword, + option->choices[j].choice); + + if (!warn) + errors ++; + } + } + } + } + + /* + * Verify that we have the base language for each localized one... + */ + + for (language = (char *)cupsArrayFirst(languages); + language; + language = (char *)cupsArrayNext(languages)) + if (language[2]) + { + /* + * Lookup the base language... + */ + + cupsArraySave(languages); + + strlcpy(ll, language, sizeof(ll)); + + if (!cupsArrayFind(languages, ll) && + strcmp(ll, "zh") && strcmp(ll, "en")) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s No base translation \"%s\" " + "is included in file!\n"), prefix, ll); + + if (!warn) + errors ++; + } + + cupsArrayRestore(languages); + } + + /* + * Free memory used for the languages... + */ + + _ppdFreeLanguages(languages); + } + + return (errors); +} + + +/* + * 'show_conflicts()' - Show option conflicts in a PPD file. + */ + +static void +show_conflicts(ppd_file_t *ppd) /* I - PPD to check */ +{ + int i, j; /* Looping variables */ + ppd_const_t *c; /* Current constraint */ + ppd_option_t *o1, *o2; /* Options */ + ppd_choice_t *c1, *c2; /* Choices */ + + + /* + * Loop through all of the UI constraints and report 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") || + !strcasecmp(c1->choice, "Off") || + !strcasecmp(c1->choice, "False")) + 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") || + !strcasecmp(c2->choice, "Off") || + !strcasecmp(c2->choice, "False")) + c2 = NULL; + } + + /* + * If both options are marked then there is a conflict... + */ + + if (c1 != NULL && c1->marked && c2 != NULL && c2->marked) + _cupsLangPrintf(stdout, + _(" WARN \"%s %s\" conflicts with \"%s %s\"\n" + " (constraint=\"%s %s %s %s\")\n"), + o1->keyword, c1->choice, o2->keyword, c2->choice, + c->option1, c->choice1, c->option2, c->choice2); + } +} + + +/* + * 'test_raster()' - Test PostScript commands for raster printers. + */ + +static int /* O - 1 on success, 0 on failure */ +test_raster(ppd_file_t *ppd, /* I - PPD file */ + int verbose) /* I - Verbosity */ +{ + cups_page_header2_t header; /* Page header */ + + + ppdMarkDefaults(ppd); + if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, 0)) + { + if (!verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Default option code cannot be " + "interpreted: %s\n"), cupsRasterErrorString()); + + return (0); + } + + /* + * Try a test of custom page size code, if available... + */ + + if (!ppdPageSize(ppd, "Custom.612x792")) + return (1); + + ppdMarkOption(ppd, "PageSize", "Custom.612x792"); + + if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, 0)) + { + if (!verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" **FAIL** Default option code cannot be " + "interpreted: %s\n"), cupsRasterErrorString()); + + return (0); + } + + return (1); +} + + +/* + * 'usage()' - Show program usage... + */ + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: cupstestppd [options] filename1.ppd[.gz] " + "[... filenameN.ppd[.gz]]\n" + " program | cupstestppd [options] -\n" + "\n" + "Options:\n" + "\n" + " -R root-directory Set alternate root\n" + " -W {all,none,constraints,defaults,duplex,filters," + "profiles,sizes,translations}\n" + " Issue warnings instead of errors\n" + " -q Run silently\n" + " -r Use 'relaxed' open mode\n" + " -v Be slightly verbose\n" + " -vv Be very verbose\n")); + + exit(ERROR_USAGE); +} + + +/* + * 'valid_path()' - Check whether a path has the correct capitalization. + */ + +static int /* O - Errors found */ +valid_path(const char *keyword, /* I - Keyword using path */ + const char *path, /* I - Path to check */ + int errors, /* I - Errors found */ + int verbose, /* I - Verbosity level */ + int warn) /* I - Warnings only? */ +{ + cups_dir_t *dir; /* Current directory */ + cups_dentry_t *dentry; /* Current directory entry */ + char temp[1024], /* Temporary path */ + *ptr; /* Pointer into temporary path */ + const char *prefix; /* WARN/FAIL prefix */ + + + prefix = warn ? " WARN " : "**FAIL**"; + + /* + * Loop over the components of the path, checking that the entry exists with + * the same capitalization... + */ + + strlcpy(temp, path, sizeof(temp)); + + while ((ptr = strrchr(temp, '/')) != NULL) + { + /* + * Chop off the trailing component so temp == dirname and ptr == basename. + */ + + *ptr++ = '\0'; + + /* + * Try opening the directory containing the base name... + */ + + if (temp[0]) + dir = cupsDirOpen(temp); + else + dir = cupsDirOpen("/"); + + if (!dir) + dentry = NULL; + else + { + while ((dentry = cupsDirRead(dir)) != NULL) + { + if (!strcmp(dentry->filename, ptr)) + break; + } + + cupsDirClose(dir); + } + + /* + * Display an error if the filename doesn't exist with the same + * capitalization... + */ + + if (!dentry) + { + if (!warn && !errors && !verbose) + _cupsLangPuts(stdout, _(" FAIL\n")); + + if (verbose >= 0) + _cupsLangPrintf(stdout, + _(" %s %s file \"%s\" has the wrong " + "capitalization!\n"), prefix, keyword, path); + + if (!warn) + errors ++; + + break; + } + } + + return (errors); +} + + +/* + * 'valid_utf8()' - Check whether a string contains valid UTF-8 text. + */ + +static int /* O - 1 if valid, 0 if not */ +valid_utf8(const char *s) /* I - String to check */ +{ + while (*s) + { + if (*s & 0x80) + { + /* + * Check for valid UTF-8 sequence... + */ + + if ((*s & 0xc0) == 0x80) + return (0); /* Illegal suffix byte */ + else if ((*s & 0xe0) == 0xc0) + { + /* + * 2-byte sequence... + */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + } + else if ((*s & 0xf0) == 0xe0) + { + /* + * 3-byte sequence... + */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + } + else if ((*s & 0xf8) == 0xf0) + { + /* + * 4-byte sequence... + */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + + s ++; + + if ((*s & 0xc0) != 0x80) + return (0); /* Missing suffix byte */ + } + else + return (0); /* Bad sequence */ + } + + s ++; + } + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/lp.c b/systemv/lp.c new file mode 100644 index 0000000000..718ec669d0 --- /dev/null +++ b/systemv/lp.c @@ -0,0 +1,744 @@ +/* + * "$Id$" + * + * "lp" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and send files for printing. + * restart_job() - Restart a job. + * set_job_attrs() - Set job attributes. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions. + */ + +int restart_job(const char *command, int job_id); +int set_job_attrs(const char *command, int job_id, int num_options, + cups_option_t *options); + + +/* + * '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 */ + cups_dest_t *dest; /* Selected destination */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int end_options; /* No more options? */ + int silent; /* Silent or verbose output? */ + char buffer[8192]; /* Copy buffer */ + + +#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")) + return (0); +#endif /* __sun */ + + _cupsSetLocale(argv); + + silent = 0; + printer = NULL; + dest = NULL; + num_options = 0; + options = NULL; + num_files = 0; + title = NULL; + job_id = 0; + end_options = 0; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-' && argv[i][1] && !end_options) + switch (argv[i][1]) + { + case 'E' : /* Encrypt */ +#ifdef HAVE_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + return (1); + } + + cupsSetUser(argv[i]); + } + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected destination after " + "\'-d\' option!\n"), + argv[0]); + return (1); + } + + printer = argv[i]; + } + + if ((instance = strrchr(printer, '/')) != NULL) + *instance++ = '\0'; + + if ((dest = cupsGetNamedDest(NULL, printer, instance)) != 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected form after \'-f\' " + "option!\n"), + argv[0]); + return (1); + } + } + + _cupsLangPrintf(stderr, _("%s: Warning - form option ignored!\n"), + argv[0]); + break; + + case 'h' : /* Destination host */ + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-h\' option!\n"), + argv[0]); + return (1); + } + + cupsSetServer(argv[i]); + } + break; + + case 'i' : /* Change job */ + if (argv[i][2]) + val = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Expected job ID after \'-i\' option!\n"), + argv[0]); + return (1); + } + + val = argv[i]; + } + + if (num_files > 0) + { + _cupsLangPrintf(stderr, + _("%s: Error - cannot print files and alter " + "jobs simultaneously!\n"), + argv[0]); + return (1); + } + + if (strrchr(val, '-') != NULL) + job_id = atoi(strrchr(val, '-') + 1); + else + job_id = atoi(val); + + if (job_id < 0) + { + _cupsLangPrintf(stderr, _("%s: Error - bad job ID!\n"), argv[0]); + 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 */ + { + char email[1024]; /* EMail address */ + + + snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(), + httpGetHostname(NULL, buffer, sizeof(buffer))); + num_options = cupsAddOption("notify-recipient-uri", email, + num_options, &options); + } + + silent = 1; + break; + + case 'n' : /* Number of copies */ + if (argv[i][2] != '\0') + num_copies = atoi(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected copies after " + "\'-n\' option!\n"), + argv[0]); + return (1); + } + + num_copies = atoi(argv[i]); + } + + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected option string after " + "\'-o\' option!\n"), + argv[0]); + 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 + { + if ((i + 1) >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected priority after " + "\'-%c\' option!\n"), + argv[0], argv[i][1]); + return (1); + } + + i ++; + + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - priority must be between 1 and " + "100.\n"), + argv[0]); + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected title after " + "\'-t\' option!\n"), + argv[0]); + return (1); + } + + title = argv[i]; + } + break; + + case 'y' : /* mode-list */ + if (!argv[i][2]) + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected mode list after " + "\'-y\' option!\n"), + argv[0]); + return (1); + } + } + + _cupsLangPrintf(stderr, + _("%s: Warning - mode option ignored!\n"), + argv[0]); + break; + + case 'H' : /* Hold job */ + if (argv[i][2]) + val = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hold name after " + "\'-H\' option!\n"), + argv[0]); + return (1); + } + + val = argv[i]; + } + + if (!strcmp(val, "hold")) + num_options = cupsAddOption("job-hold-until", "indefinite", + num_options, &options); + else if (!strcmp(val, "resume") || + !strcmp(val, "release")) + num_options = cupsAddOption("job-hold-until", "no-hold", + num_options, &options); + else if (!strcmp(val, "immediate")) + { + num_options = cupsAddOption("job-hold-until", "no-hold", + num_options, &options); + num_options = cupsAddOption("job-priority", "100", + num_options, &options); + } + else if (!strcmp(val, "restart")) + { + if (job_id < 1) + { + _cupsLangPrintf(stderr, + _("%s: Need job ID (\'-i jobid\') before " + "\'-H restart\'!\n"), + argv[0]); + return (1); + } + + if (restart_job(argv[0], job_id)) + return (1); + } + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected page list after " + "\'-P\' option!\n"), + argv[0]); + 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) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected character set after " + "\'-S\' option!\n"), + argv[0]); + return (1); + } + } + + _cupsLangPrintf(stderr, + _("%s: Warning - character set option ignored!\n"), + argv[0]); + break; + + case 'T' : /* Content-Type */ + if (!argv[i][2]) + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected content type after " + "\'-T\' option!\n"), + argv[0]); + return (1); + } + } + + _cupsLangPrintf(stderr, + _("%s: Warning - content type option ignored!\n"), + argv[0]); + break; + + case '-' : /* Stop processing options */ + end_options = 1; + break; + + default : + _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"), + argv[0], argv[i][1]); + return (1); + } + else if (!strcmp(argv[i], "-")) + { + if (num_files || job_id) + { + _cupsLangPrintf(stderr, + _("%s: Error - cannot print from stdin if files or a " + "job ID are provided!\n"), + argv[0]); + return (1); + } + + break; + } + else if (num_files < 1000 && job_id == 0) + { + /* + * Print a file... + */ + + if (access(argv[i], R_OK) != 0) + { + _cupsLangPrintf(stderr, _("%s: Error - unable to access \"%s\" - %s\n"), + argv[0], argv[i], strerror(errno)); + return (1); + } + + files[num_files] = argv[i]; + num_files ++; + + if (title == NULL) + { + if ((title = strrchr(argv[i], '/')) != NULL) + title ++; + else + title = argv[i]; + } + } + else + _cupsLangPrintf(stderr, _("%s: Error - too many files - \"%s\"\n"), + argv[0], argv[i]); + + /* + * See if we are altering an existing job... + */ + + if (job_id) + return (set_job_attrs(argv[0], job_id, num_options, options)); + + /* + * See if we have any files to print; if not, print from stdin... + */ + + if (printer == NULL) + { + if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL) + { + printer = dest->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); + } + } + + if (printer == NULL) + { + val = NULL; + + if ((printer = getenv("LPDEST")) == NULL) + { + if ((printer = getenv("PRINTER")) != NULL) + { + if (!strcmp(printer, "lp")) + printer = NULL; + else + val = "PRINTER"; + } + } + else + val = "LPDEST"; + + if (printer && !cupsGetNamedDest(NULL, printer, NULL)) + _cupsLangPrintf(stderr, + _("%s: Error - %s environment variable names " + "non-existent destination \"%s\"!\n"), + argv[0], val, printer); + else if (cupsLastError() == IPP_NOT_FOUND) + _cupsLangPrintf(stderr, + _("%s: Error - no default destination available.\n"), + argv[0]); + else + _cupsLangPrintf(stderr, + _("%s: Error - scheduler not responding!\n"), + argv[0]); + + return (1); + } + + if (num_files > 0) + job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options); + else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer, + title ? title : "(stdin)", + num_options, options)) > 0) + { + http_status_t status; /* Write status */ + const char *format; /* Document format */ + ssize_t bytes; /* Bytes read */ + + + if (cupsGetOption("raw", num_options, options)) + format = CUPS_FORMAT_RAW; + else if ((format = cupsGetOption("document-format", num_options, + options)) == NULL) + format = CUPS_FORMAT_AUTO; + + status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL, + format, 1); + + while (status == HTTP_CONTINUE && + (bytes = read(0, buffer, sizeof(buffer))) > 0) + status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes); + + if (status != HTTP_CONTINUE) + { + _cupsLangPrintf(stderr, + _("%s: Error - unable to queue from stdin - %s\n"), + argv[0], httpStatus(status)); + return (1); + } + + if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK) + job_id = 0; + } + + if (job_id < 1) + { + _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); + return (1); + } + else if (!silent) + _cupsLangPrintf(stdout, _("request id is %s-%d (%d file(s))\n"), + printer, job_id, num_files); + + return (0); +} + + +/* + * 'restart_job()' - Restart a job. + */ + +int /* O - Exit status */ +restart_job(const char *command, /* I - Command name */ + int job_id) /* I - Job ID */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* URI for job */ + + + request = ippNewRequest(IPP_RESTART_JOB); + + 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()); + + ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/jobs")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'set_job_attrs()' - Set job attributes. + */ + +int /* O - Exit status */ +set_job_attrs(const char *command, /* I - Command name */ + int job_id, /* I - Job ID */ + int num_options,/* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + ipp_t *request; /* IPP request */ + char uri[HTTP_MAX_URI]; /* URI for job */ + + + if (num_options == 0) + return (0); + + request = ippNewRequest(IPP_SET_JOB_ATTRIBUTES); + + 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); + + ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/jobs")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "%s: %s\n", command, cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/lpadmin.c b/systemv/lpadmin.c new file mode 100644 index 0000000000..7fdbbab06e --- /dev/null +++ b/systemv/lpadmin.c @@ -0,0 +1,1394 @@ +/* + * "$Id$" + * + * "lpadmin" command for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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_options() - Set the printer options and/or file. + * validate_name() - Make sure the printer name only contains + * valid chars. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int add_printer_to_class(http_t *http, char *printer, char *pclass); +static int default_printer(http_t *http, char *printer); +static int delete_printer(http_t *http, char *printer); +static int delete_printer_from_class(http_t *http, char *printer, + char *pclass); +static int enable_printer(http_t *http, char *printer); +static int set_printer_options(http_t *http, char *printer, + int num_options, cups_option_t *options, + char *file); +static int validate_name(const char *name); + + +/* + * '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 */ + char *file; /* New PPD file/interface script */ + + + _cupsSetLocale(argv); + + http = NULL; + printer = NULL; + num_options = 0; + options = NULL; + file = 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) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + } + + if (printer == NULL) + { + _cupsLangPuts(stderr, + _("lpadmin: Unable to add a printer to the class:\n" + " You must specify a printer name " + "first!\n")); + return (1); + } + + if (argv[i][2]) + pclass = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected class name after \'-c\' " + "option!\n")); + return (1); + } + + pclass = argv[i]; + } + + if (!validate_name(pclass)) + { + _cupsLangPuts(stderr, + _("lpadmin: Class name can only contain printable " + "characters!\n")); + return (1); + } + + if (add_printer_to_class(http, printer, pclass)) + return (1); + break; + + case 'd' : /* Set as default destination */ + if (!http) + { + http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + } + + if (argv[i][2]) + printer = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected printer name after \'-d\' " + "option!\n")); + return (1); + } + + printer = argv[i]; + } + + if (!validate_name(printer)) + { + _cupsLangPuts(stderr, + _("lpadmin: Printer name can only contain " + "printable characters!\n")); + return (1); + } + + if (default_printer(http, printer)) + return (1); + + 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) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected hostname after \'-h\' " + "option!\n")); + return (1); + } + + cupsSetServer(argv[i]); + } + break; + + case 'i' : /* Use the specified interface script */ + if (argv[i][2]) + file = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected interface after \'-i\' " + "option!\n")); + return (1); + } + + file = argv[i]; + } + break; + + case 'E' : /* Enable the printer */ + if (printer == NULL) + { +#ifdef HAVE_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + + if (http) + httpEncryption(http, HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + } + + if (!http) + { + http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + } + + if (enable_printer(http, printer)) + return (1); + break; + + case 'm' : /* Use the specified standard script/PPD file */ + if (argv[i][2]) + num_options = cupsAddOption("ppd-name", argv[i] + 2, num_options, + &options); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected model after \'-m\' " + "option!\n")); + return (1); + } + + num_options = cupsAddOption("ppd-name", argv[i], num_options, + &options); + } + break; + + case 'o' : /* Set option */ + if (argv[i][2]) + num_options = cupsParseOptions(argv[i] + 2, num_options, &options); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected name=value after \'-o\' " + "option!\n")); + return (1); + } + + num_options = cupsParseOptions(argv[i], num_options, &options); + } + break; + + case 'p' : /* Add/modify a printer */ + if (argv[i][2]) + printer = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected printer after \'-p\' " + "option!\n")); + return (1); + } + + printer = argv[i]; + } + + if (!validate_name(printer)) + { + _cupsLangPuts(stderr, + _("lpadmin: Printer name can only contain " + "printable characters!\n")); + return (1); + } + break; + + case 'r' : /* Remove printer from class */ + if (!http) + { + http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + } + + if (printer == NULL) + { + _cupsLangPuts(stderr, + _("lpadmin: Unable to remove a printer from the " + "class:\n" + " You must specify a printer name " + "first!\n")); + return (1); + } + + if (argv[i][2]) + pclass = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected class after \'-r\' " + "option!\n")); + return (1); + } + + pclass = argv[i]; + } + + if (!validate_name(pclass)) + { + _cupsLangPuts(stderr, + _("lpadmin: Class name can only contain printable " + "characters!\n")); + return (1); + } + + if (delete_printer_from_class(http, printer, pclass)) + return (1); + break; + + case 'U' : /* Username */ + if (argv[i][2] != '\0') + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + return (1); + } + + cupsSetUser(argv[i]); + } + break; + + case 'u' : /* Allow/deny users */ + if (argv[i][2]) + val = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected allow/deny:userlist after " + "\'-u\' option!\n")); + return (1); + } + + val = argv[i]; + } + + if (!strncasecmp(val, "allow:", 6)) + num_options = cupsAddOption("requesting-user-name-allowed", + val + 6, num_options, &options); + else if (!strncasecmp(val, "deny:", 5)) + num_options = cupsAddOption("requesting-user-name-denied", + val + 5, num_options, &options); + else + { + _cupsLangPrintf(stderr, + _("lpadmin: Unknown allow/deny option \"%s\"!\n"), + val); + return (1); + } + break; + + case 'v' : /* Set the device-uri attribute */ + if (argv[i][2]) + num_options = cupsAddOption("device-uri", argv[i] + 2, + num_options, &options); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected device URI after \'-v\' " + "option!\n")); + return (1); + } + + num_options = cupsAddOption("device-uri", argv[i], + num_options, &options); + } + break; + + case 'x' : /* Delete a printer */ + if (!http) + { + http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + } + + if (argv[i][2]) + printer = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected printer or class after " + "\'-x\' option!\n")); + return (1); + } + + printer = argv[i]; + } + + if (!validate_name(printer)) + { + _cupsLangPuts(stderr, + _("lpadmin: Printer name can only contain " + "printable characters!\n")); + return (1); + } + + if (delete_printer(http, printer)) + return (1); + + i = argc; + break; + + case 'D' : /* Set the printer-info attribute */ + if (argv[i][2]) + num_options = cupsAddOption("printer-info", argv[i] + 2, + num_options, &options); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected description after " + "\'-D\' option!\n")); + return (1); + } + + num_options = cupsAddOption("printer-info", argv[i], + num_options, &options); + } + break; + + case 'I' : /* Set the supported file types (ignored) */ + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected file type(s) after \'-I\' " + "option!\n")); + return (1); + } + + _cupsLangPuts(stderr, + _("lpadmin: Warning - content type list ignored!\n")); + break; + + case 'L' : /* Set the printer-location attribute */ + if (argv[i][2]) + num_options = cupsAddOption("printer-location", argv[i] + 2, + num_options, &options); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected location after \'-L\' " + "option!\n")); + return (1); + } + + num_options = cupsAddOption("printer-location", argv[i], + num_options, &options); + } + break; + + case 'P' : /* Use the specified PPD file */ + if (argv[i][2]) + file = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("lpadmin: Expected PPD after \'-P\' option!\n")); + return (1); + } + + file = argv[i]; + } + break; + + default : + _cupsLangPrintf(stderr, + _("lpadmin: Unknown option \'%c\'!\n"), argv[i][1]); + return (1); + } + else + { + _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \'%s\'!\n"), + argv[i]); + return (1); + } + + /* + * Set options as needed... + */ + + if (num_options || file) + { + if (!http) + { + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + } + + if (printer == NULL) + { + _cupsLangPuts(stderr, + _("lpadmin: Unable to set the printer options:\n" + " You must specify a printer name first!\n")); + return (1); + } + + if (set_printer_options(http, printer, num_options, options, file)) + return (1); + } + + if (printer == NULL) + { + _cupsLangPuts(stdout, + _("Usage:\n" + "\n" + " lpadmin [-h server] -d destination\n" + " lpadmin [-h server] -x destination\n" + " lpadmin [-h server] -p printer [-c add-class] " + "[-i interface] [-m model]\n" + " [-r remove-class] [-v device] " + "[-D description]\n" + " [-P ppd-file] [-o name=value]\n" + " [-u allow:user,user] " + "[-u deny:user,user]\n" + "\n")); + } + + if (http) + httpClose(http); + + return (0); +} + + +/* + * 'add_printer_to_class()' - Add a printer to a class. + */ + +static int /* O - 0 on success, 1 on fail */ +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 */ + 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 + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", pclass); + 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 = ippNewRequest(CUPS_ADD_CLASS); + + 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) + { + _cupsLangPrintf(stderr, + _("lpadmin: Printer %s is already a member of class %s.\n"), + printer, pclass); + ippDelete(request); + ippDelete(response); + return (0); + } + + /* + * OK, the printer isn't part of the class, so add it... + */ + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/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 = _cupsStrAlloc(members->values[i].string.text); + + attr->values[i].string.text = _cupsStrAlloc(uri); + } + else + 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) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + return (1); + } + else if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + ippDelete(response); + + return (1); + } + else + { + ippDelete(response); + + return (0); + } +} + + +/* + * 'default_printer()' - Set the default printing destination. + */ + +static int /* O - 0 on success, 1 on fail */ +default_printer(http_t *http, /* I - Server connection */ + char *printer) /* I - Printer name */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + 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 + */ + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + + request = ippNewRequest(CUPS_SET_DEFAULT); + + 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) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + return (1); + } + else if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + ippDelete(response); + + return (1); + } + else + { + ippDelete(response); + + return (0); + } +} + + +/* + * 'delete_printer()' - Delete a printer from the system... + */ + +static int /* O - 0 on success, 1 on fail */ +delete_printer(http_t *http, /* I - Server connection */ + char *printer) /* I - Printer to delete */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + 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 + */ + + request = ippNewRequest(CUPS_DELETE_PRINTER); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", 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, "/admin/")) == NULL) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + return (1); + } + else if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + ippDelete(response); + + return (1); + } + else + { + ippDelete(response); + + return (0); + } +} + + +/* + * 'delete_printer_from_class()' - Delete a printer from a class. + */ + +static int /* O - 0 on success, 1 on fail */ +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 */ + 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 + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", 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, "/classes/")) == NULL || + response->request.status.status_code == IPP_NOT_FOUND) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + ippDelete(response); + + return (1); + } + + /* + * See if the printer is already in the class... + */ + + if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL) + { + _cupsLangPuts(stderr, _("lpadmin: No member names were seen!\n")); + + ippDelete(response); + + return (1); + } + + for (i = 0; i < members->num_values; i ++) + if (!strcasecmp(printer, members->values[i].string.text)) + break; + + if (i >= members->num_values) + { + _cupsLangPrintf(stderr, + _("lpadmin: Printer %s is not a member of class %s.\n"), + printer, pclass); + + ippDelete(response); + + return (1); + } + + if (members->num_values == 1) + { + /* + * Build a CUPS_DELETE_CLASS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNewRequest(CUPS_DELETE_CLASS); + + 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 = ippNewRequest(CUPS_ADD_CLASS); + + 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 = + _cupsStrAlloc(members->values[j].string.text); + } + + /* + * Then send the request... + */ + + ippDelete(response); + + if ((response = cupsDoRequest(http, request, "/admin/")) == NULL) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + return (1); + } + else if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + ippDelete(response); + + return (1); + } + else + { + ippDelete(response); + + return (0); + } +} + + +/* + * 'enable_printer()' - Enable a printer... + */ + +static int /* O - 0 on success, 1 on fail */ +enable_printer(http_t *http, /* I - Server connection */ + char *printer) /* I - Printer to enable */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + 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 + */ + + request = ippNewRequest(CUPS_ADD_PRINTER); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + 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) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + return (1); + } + else if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + ippDelete(response); + + return (1); + } + else + { + ippDelete(response); + + return (0); + } +} + + +/* + * 'set_printer_options()' - Set the printer options. + */ + +static int /* O - 0 on success, 1 on fail */ +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 */ + char *file) /* I - PPD file/interface script */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* IPP attribute */ + ipp_op_t op; /* Operation to perform */ + const char *ppdfile; /* PPD filename */ + int ppdchanged; /* PPD changed? */ + ppd_file_t *ppd; /* PPD file */ + ppd_choice_t *choice; /* Marked choice */ + 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 */ + cups_file_t *in, /* PPD file */ + *out; /* Temporary file */ + const char *protocol, /* Old protocol option */ + *customval; /* Custom option value */ + + + DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, " + "options=%p, file=\"%s\")\n", http, printer, num_options, + options, file)); + + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/printers/%s", printer); + + /* + * Build a GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requested-attributes + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + 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_MODIFY_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_MODIFY_CLASS; + httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, + "localhost", 0, "/classes/%s", printer); + } + } + + ippDelete(response); + } + + /* + * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which + * requires the following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * other options + */ + + request = ippNewRequest(op); + + 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()); + + /* + * Add the options... + */ + + cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER); + + if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL) + { + if (!strcasecmp(protocol, "bcp")) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", + NULL, "bcp"); + else if (!strcasecmp(protocol, "tbcp")) + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor", + NULL, "tbcp"); + } + + if (file) + ppdfile = file; + else if (op == CUPS_ADD_MODIFY_PRINTER) + ppdfile = cupsGetPPD(printer); + else + ppdfile = NULL; + + if (ppdfile != NULL) + { + /* + * Set default options in the PPD file... + */ + + ppd = ppdOpenFile(ppdfile); + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL) + { + _cupsLangPrintError(_("ERROR: Unable to create temporary file")); + ippDelete(request); + if (ppdfile != file) + unlink(ppdfile); + return (1); + } + + if ((in = cupsFileOpen(ppdfile, "r")) == NULL) + { + _cupsLangPrintf(stderr, + _("lpadmin: Unable to open PPD file \"%s\" - %s\n"), + ppdfile, strerror(errno)); + ippDelete(request); + if (ppdfile != file) + unlink(ppdfile); + cupsFileClose(out); + unlink(tempfile); + return (1); + } + + ppdchanged = 0; + + while (cupsFileGets(in, line, sizeof(line))) + { + if (strncmp(line, "*Default", 8)) + cupsFilePrintf(out, "%s\n", line); + else + { + /* + * Get default option name... + */ + + strlcpy(keyword, line + 8, sizeof(keyword)); + + for (keyptr = keyword; *keyptr; keyptr ++) + if (*keyptr == ':' || isspace(*keyptr & 255)) + break; + + *keyptr++ = '\0'; + while (isspace(*keyptr & 255)) + keyptr ++; + + if (!strcmp(keyword, "PageRegion") || + !strcmp(keyword, "PageSize") || + !strcmp(keyword, "PaperDimension") || + !strcmp(keyword, "ImageableArea")) + { + if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL) + choice = ppdFindMarkedChoice(ppd, "PageRegion"); + } + else + choice = ppdFindMarkedChoice(ppd, keyword); + + if (choice && strcmp(choice->choice, keyptr)) + { + if (strcmp(choice->choice, "Custom")) + { + cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice); + ppdchanged = 1; + } + else if ((customval = cupsGetOption(keyword, num_options, + options)) != NULL) + { + cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval); + ppdchanged = 1; + } + else + cupsFilePrintf(out, "%s\n", line); + } + else + cupsFilePrintf(out, "%s\n", line); + } + } + + cupsFileClose(in); + cupsFileClose(out); + ppdClose(ppd); + + /* + * Do the request... + */ + + ippDelete(cupsDoFileRequest(http, request, "/admin/", + ppdchanged ? tempfile : file)); + + /* + * Clean up temp files... (TODO: catch signals in case we CTRL-C during + * lpadmin) + */ + + if (ppdfile != file) + unlink(ppdfile); + unlink(tempfile); + } + else + { + /* + * No PPD file - just set the options... + */ + + ippDelete(cupsDoRequest(http, request, "/admin/")); + } + + /* + * Check the response... + */ + + if (cupsLastError() > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpadmin: %s\n", cupsLastErrorString()); + + return (1); + } + else + return (0); +} + + +/* + * '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 == '/' || + *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 0000000000..93f54eb549 --- /dev/null +++ b/systemv/lpinfo.c @@ -0,0 +1,503 @@ +/* + * "$Id$" + * + * "lpinfo" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and show information. + * device_cb - Device callback. + * show_devices() - Show available devices. + * show_models() - Show available PPDs. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void device_cb(const char *device_clas, const char *device_id, + const char *device_info, + const char *device_make_and_model, + const char *device_uri, const char *device_location, + void *user_data); +static int show_devices(int long_status, int timeout, + const char *include_schemes, + const char *exclude_schemes); +static int show_models(int long_status, + const char *device_id, const char *language, + const char *make_model, const char *product, + const char *include_schemes, + const char *exclude_schemes); + + +/* + * '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 */ + int long_status; /* Long listing? */ + const char *device_id, /* 1284 device ID */ + *language, /* Language */ + *make_model, /* Make and model */ + *product, /* Product */ + *include_schemes, /* Schemes to include */ + *exclude_schemes; /* Schemes to exclude */ + int timeout; /* Device timeout */ + + + _cupsSetLocale(argv); + + long_status = 0; + device_id = NULL; + language = NULL; + make_model = NULL; + product = NULL; + include_schemes = CUPS_INCLUDE_ALL; + exclude_schemes = CUPS_EXCLUDE_NONE; + timeout = CUPS_TIMEOUT_DEFAULT; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + switch (argv[i][1]) + { + case 'E' : /* Encrypt */ +#ifdef HAVE_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'h' : /* Connect to host */ + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("Error: need hostname after \'-h\' option!\n")); + return (1); + } + + cupsSetServer(argv[i]); + } + break; + + case 'l' : /* Show long listing */ + long_status = 1; + break; + + case 'm' : /* Show models */ + if (show_models(long_status, device_id, language, make_model, + product, include_schemes, exclude_schemes)) + return (1); + break; + + case 'v' : /* Show available devices */ + if (show_devices(long_status, timeout, include_schemes, + exclude_schemes)) + return (1); + break; + + case '-' : /* --something */ + if (!strcmp(argv[i], "--device-id")) + { + i ++; + + if (i < argc) + device_id = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected 1284 device ID string " + "after --device-id!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--device-id=", 12) && argv[i][12]) + { + device_id = argv[i] + 12; + } + else if (!strcmp(argv[i], "--exclude-schemes")) + { + i ++; + + if (i < argc) + exclude_schemes = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected scheme list after " + "--exclude-schemes!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--exclude-schemes=", 18) && argv[i][18]) + { + exclude_schemes = argv[i] + 18; + } + else if (!strcmp(argv[i], "--include-schemes")) + { + i ++; + + if (i < argc) + include_schemes = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected scheme list after " + "--include-schemes!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--include-schemes=", 18) && argv[i][18]) + { + include_schemes = argv[i] + 18; + } + else if (!strcmp(argv[i], "--language")) + { + i ++; + if (i < argc) + language = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected language after " + "--language!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--language=", 11) && argv[i][11]) + { + language = argv[i] + 11; + } + else if (!strcmp(argv[i], "--make-and-model")) + { + i ++; + if (i < argc) + make_model= argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected make and model after " + "--make-and-model!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--make-and-model=", 17) && argv[i][17]) + { + make_model = argv[i] + 17; + } + else if (!strcmp(argv[i], "--product")) + { + i ++; + if (i < argc) + product = argv[i]; + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected product string after " + "--product!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--product=", 10) && argv[i][10]) + { + product = argv[i] + 10; + } + else if (!strcmp(argv[i], "--timeout")) + { + i ++; + if (i < argc) + timeout = atoi(argv[i]); + else + { + _cupsLangPuts(stderr, + _("lpinfo: Expected timeout after --timeout!\n")); + return (1); + } + } + else if (!strncmp(argv[i], "--timeout=", 10) && argv[i][10]) + { + timeout = atoi(argv[i] + 10); + } + else + { + _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%s\'!\n"), + argv[i]); + return (1); + } + break; + + default : + _cupsLangPrintf(stderr, _("lpinfo: Unknown option \'%c\'!\n"), + argv[i][1]); + return (1); + } + else + { + _cupsLangPrintf(stderr, _("lpinfo: Unknown argument \'%s\'!\n"), + argv[i]); + return (1); + } + + return (0); +} + + +/* + * 'device_cb()' - Device callback. + */ + +static void +device_cb( + const char *device_class, /* I - device-class string */ + const char *device_id, /* I - device-id string */ + const char *device_info, /* I - device-info string */ + const char *device_make_and_model, /* I - device-make-and-model string */ + const char *device_uri, /* I - device-uri string */ + const char *device_location, /* I - device-location string */ + void *user_data) /* I - User data */ +{ + int *long_status; /* Show verbose info? */ + + + /* + * Display the device... + */ + + long_status = (int *)user_data; + + if (*long_status) + { + _cupsLangPrintf(stdout, + _("Device: uri = %s\n" + " class = %s\n" + " info = %s\n" + " make-and-model = %s\n" + " device-id = %s\n" + " location = %s\n"), + device_uri, device_class, device_info, + device_make_and_model, device_id, device_location); + } + else + _cupsLangPrintf(stdout, "%s %s\n", device_class, device_uri); +} + + +/* + * 'show_devices()' - Show available devices. + */ + +static int /* O - 0 on success, 1 on failure */ +show_devices( + int long_status, /* I - Long status report? */ + int timeout, /* I - Timeout */ + const char *include_schemes, /* I - List of schemes to include */ + const char *exclude_schemes) /* I - List of schemes to exclude */ +{ + if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes, + exclude_schemes, device_cb, &long_status) != IPP_OK) + { + _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'show_models()' - Show available PPDs. + */ + +static int /* O - 0 on success, 1 on failure */ +show_models( + int long_status, /* I - Long status report? */ + const char *device_id, /* I - 1284 device ID */ + const char *language, /* I - Language */ + const char *make_model, /* I - Make and model */ + const char *product, /* I - Product */ + const char *include_schemes, /* I - List of schemes to include */ + const char *exclude_schemes) /* I - List of schemes to exclude */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + const char *ppd_device_id, /* Pointer to ppd-device-id */ + *ppd_language, /* Pointer to ppd-natural-language */ + *ppd_make_model, /* Pointer to ppd-make-and-model */ + *ppd_name; /* Pointer to ppd-name */ + cups_option_t option; /* in/exclude-schemes option */ + + + /* + * Build a CUPS_GET_PPDS request... + */ + + request = ippNewRequest(CUPS_GET_PPDS); + + if (device_id) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-device-id", + NULL, device_id); + if (language) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "ppd-language", + NULL, language); + if (make_model) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-make-and-model", + NULL, make_model); + if (product) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-product", + NULL, product); + + if (include_schemes) + { + option.name = "include-schemes"; + option.value = (char *)include_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + + if (exclude_schemes) + { + option.name = "exclude-schemes"; + option.value = (char *)exclude_schemes; + + cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION); + } + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + /* + * Loop through the device list and display them... + */ + + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); + 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_device_id = "NONE"; + ppd_language = NULL; + ppd_make_model = NULL; + ppd_name = NULL; + + while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) + { + if (!strcmp(attr->name, "ppd-device-id") && + attr->value_tag == IPP_TAG_TEXT) + ppd_device_id = attr->values[0].string.text; + else if (!strcmp(attr->name, "ppd-natural-language") && + attr->value_tag == IPP_TAG_LANGUAGE) + ppd_language = attr->values[0].string.text; + else if (!strcmp(attr->name, "ppd-make-and-model") && + attr->value_tag == IPP_TAG_TEXT) + ppd_make_model = attr->values[0].string.text; + else if (!strcmp(attr->name, "ppd-name") && + 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_model == NULL || ppd_name == NULL) + { + if (attr == NULL) + break; + else + continue; + } + + /* + * Display the device... + */ + + if (long_status) + { + _cupsLangPrintf(stdout, + _("Model: name = %s\n" + " natural_language = %s\n" + " make-and-model = %s\n" + " device-id = %s\n"), + ppd_name, ppd_language, ppd_make_model, ppd_device_id); + } + else + _cupsLangPrintf(stdout, "%s %s\n", ppd_name, ppd_make_model); + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "lpinfo: %s\n", cupsLastErrorString()); + + return (1); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/lpmove.c b/systemv/lpmove.c new file mode 100644 index 0000000000..dc99fc6c63 --- /dev/null +++ b/systemv/lpmove.c @@ -0,0 +1,221 @@ +/* + * "$Id$" + * + * "lpmove" command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and move jobs. + * move_job() - Move a job. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int move_job(http_t *http, const char *src, int jobid, + const char *dest); + + +/* + * '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 jobid; /* Job ID */ + int num_dests; /* Number of destinations */ + cups_dest_t *dests; /* Destinations */ + const char *src, /* Original queue */ + *dest; /* New destination */ + + + _cupsSetLocale(argv); + + dest = NULL; + dests = NULL; + job = NULL; + jobid = 0; + num_dests = 0; + src = NULL; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + switch (argv[i][1]) + { + case 'E' : /* Encrypt */ +#ifdef HAVE_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'h' : /* Connect to host */ + if (argv[i][2] != '\0') + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPuts(stderr, + _("Error: need hostname after \'-h\' option!\n")); + return (1); + } + + cupsSetServer(argv[i]); + } + break; + + default : + _cupsLangPrintf(stderr, _("lpmove: Unknown option \'%c\'!\n"), + argv[i][1]); + return (1); + } + else if (!jobid && !src) + { + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if ((job = strrchr(argv[i], '-')) != NULL && + cupsGetDest(argv[i], NULL, num_dests, dests) == NULL) + jobid = atoi(job + 1); + else if (isdigit(argv[i][0] & 255) && + !cupsGetDest(argv[i], NULL, num_dests, dests)) + jobid = atoi(argv[i]); + else + src = argv[i]; + } + else if (dest == NULL) + dest = argv[i]; + else + { + _cupsLangPrintf(stderr, _("lpmove: Unknown argument \'%s\'!\n"), + argv[i]); + return (1); + } + + if ((!jobid && !src) || !dest) + { + _cupsLangPuts(stdout, _("Usage: lpmove job/src dest\n")); + return (1); + } + + http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); + + if (http == NULL) + { + _cupsLangPrintf(stderr, + _("lpmove: Unable to connect to server: %s\n"), + strerror(errno)); + return (1); + } + + return (move_job(http, src, jobid, dest)); +} + + +/* + * 'move_job()' - Move a job. + */ + +static int /* O - 0 on success, 1 on error */ +move_job(http_t *http, /* I - HTTP connection to server */ + const char *src, /* I - Source queue */ + int jobid, /* I - Job ID */ + const char *dest) /* I - Destination queue */ +{ + ipp_t *request; /* IPP Request */ + char job_uri[HTTP_MAX_URI], /* job-uri */ + printer_uri[HTTP_MAX_URI]; /* job-printer-uri */ + + + if (!http) + return (1); + + /* + * Build a CUPS_MOVE_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * job-uri/printer-uri + * job-printer-uri + * requesting-user-name + */ + + request = ippNewRequest(CUPS_MOVE_JOB); + + if (jobid) + { + snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, + job_uri); + } + else + { + httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL, + "localhost", 0, "/printers/%s", src); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + job_uri); + } + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "ipp", NULL, "localhost", 0, "/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... + */ + + ippDelete(cupsDoRequest(http, request, "/jobs")); + + if (cupsLastError() > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpmove: %s\n", cupsLastErrorString()); + return (1); + } + else + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/lpoptions.c b/systemv/lpoptions.c new file mode 100644 index 0000000000..8c7fec4d89 --- /dev/null +++ b/systemv/lpoptions.c @@ -0,0 +1,552 @@ +/* + * "$Id$" + * + * Printer option program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void list_group(ppd_file_t *ppd, ppd_group_t *group); +static void list_options(cups_dest_t *dest); +static 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 */ + + + _cupsSetLocale(argv); + + /* + * 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 (num_dests == 0 || !dests || + (dest = cupsGetDest(printer, instance, num_dests, + dests)) == NULL) + { + _cupsLangPuts(stderr, + _("lpoptions: Unknown printer or class!\n")); + 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 'E' : /* Encrypt connection */ + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); + break; + + case 'l' : /* -l (list options) */ + if (dest == NULL) + { + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) + dest = dests; + } + + if (dest == NULL) + _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n")); + else + list_options(dest); + + changes = -1; + break; + + case 'o' : /* -o option[=value] */ + if (dest == NULL) + { + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) + dest = dests; + + if (dest == NULL) + { + _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n")); + 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); + } + + 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) + { + _cupsLangPrintf(stderr, + _("lpoptions: Unable to add printer or " + "instance: %s\n"), + strerror(errno)); + 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 (dest == NULL) + { + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) + dest = dests; + + if (dest == NULL) + { + _cupsLangPuts(stderr, _("lpoptions: No printers!?!\n")); + 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); + } + + 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)) + { + /* + * 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) + { + 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; + changes = -1; + break; + + default : + usage(); + } + } + else + usage(); + + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if (dest == NULL) + { + if ((dest = cupsGetDest(NULL, NULL, 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); + } + } + + 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) + _cupsLangPuts(stdout, " "); + + if (!options[i].value[0]) + _cupsLangPrintf(stdout, "%s", options[i].name); + else if (strchr(options[i].value, ' ') != NULL || + strchr(options[i].value, '\t') != NULL) + _cupsLangPrintf(stdout, "%s=\'%s\'", options[i].name, + options[i].value); + else + _cupsLangPrintf(stdout, "%s=%s", options[i].name, + options[i].value); + } + + _cupsLangPuts(stdout, "\n"); + } + + return (0); +} + +/* + * 'list_group()' - List printer-specific options from the PPD group. + */ + +static void +list_group(ppd_file_t *ppd, /* I - PPD file */ + 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 ++) + { + if (!strcasecmp(option->keyword, "PageRegion")) + continue; + + _cupsLangPrintf(stdout, "%s/%s:", option->keyword, option->text); + + for (j = option->num_choices, choice = option->choices; + j > 0; + j --, choice ++) + if (!strcasecmp(choice->choice, "Custom")) + { + ppd_coption_t *coption; /* Custom option */ + ppd_cparam_t *cparam; /* Custom parameter */ + static const char * const types[] = + { /* Parameter types */ + "CURVE", + "INTEGER", + "INVCURVE", + "PASSCODE", + "PASSWORD", + "POINTS", + "REAL", + "STRING" + }; + + + if ((coption = ppdFindCustomOption(ppd, option->keyword)) == NULL || + cupsArrayCount(coption->params) == 0) + _cupsLangPrintf(stdout, " %sCustom", choice->marked ? "*" : ""); + else if (!strcasecmp(option->keyword, "PageSize") || + !strcasecmp(option->keyword, "PageRegion")) + _cupsLangPrintf(stdout, " %sCustom.WIDTHxHEIGHT", + choice->marked ? "*" : ""); + else + { + cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params); + + if (cupsArrayCount(coption->params) == 1) + _cupsLangPrintf(stdout, " %sCustom.%s", choice->marked ? "*" : "", + types[cparam->type]); + else + { + const char *prefix; /* Prefix string */ + + + if (choice->marked) + prefix = " *{"; + else + prefix = " {"; + + while (cparam) + { + _cupsLangPrintf(stdout, "%s%s=%s", prefix, cparam->name, + types[cparam->type]); + cparam = (ppd_cparam_t *)cupsArrayNext(coption->params); + prefix = " "; + } + + _cupsLangPuts(stdout, "}"); + } + } + } + else if (choice->marked) + _cupsLangPrintf(stdout, " *%s", choice->choice); + else + _cupsLangPrintf(stdout, " %s", choice->choice); + + _cupsLangPuts(stdout, "\n"); + } + + for (i = group->num_subgroups, subgroup = group->subgroups; i > 0; i --, subgroup ++) + list_group(ppd, subgroup); +} + + +/* + * 'list_options()' - List printer-specific options from the PPD file. + */ + +static 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) + { + _cupsLangPrintf(stderr, + _("lpoptions: Unable to get PPD file for %s: %s\n"), + dest->name, cupsLastErrorString()); + return; + } + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + unlink(filename); + _cupsLangPrintf(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(ppd, group); + + ppdClose(ppd); + unlink(filename); +} + + +/* + * 'usage()' - Show program usage and exit. + */ + +static void +usage(void) +{ + _cupsLangPuts(stdout, + _("Usage: lpoptions [-h server] [-E] -d printer\n" + " lpoptions [-h server] [-E] [-p printer] -l\n" + " lpoptions [-h server] [-E] -p printer -o " + "option[=value] ...\n" + " lpoptions [-h server] [-E] -x printer\n")); + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/lppasswd.c b/systemv/lppasswd.c new file mode 100644 index 0000000000..ebf4e94a88 --- /dev/null +++ b/systemv/lppasswd.c @@ -0,0 +1,501 @@ +/* + * "$Id$" + * + * MD5 password program for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Add, change, or delete passwords from the MD5 password file. + * usage() - Show program usage. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef WIN32 +# include +# include +#endif /* !WIN32 */ + + +/* + * 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 */ + 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 */ + int error; /* Write error */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + cups_lang_t *lang; /* Language info */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Signal action */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET*/ + + + _cupsSetLocale(argv); + lang = cupsLangDefault(); + + /* + * Check to see if stdin, stdout, and stderr are still open... + */ + + if (fcntl(0, F_GETFD, &i) || + fcntl(1, F_GETFD, &i) || + fcntl(2, F_GETFD, &i)) + { + /* + * No, return exit status 2 and don't try to send any output since + * someone is trying to bypass the security on the server. + */ + + return (2); + } + + /* + * Find the server directory... + */ + + snprintf(passwdmd5, sizeof(passwdmd5), "%s/passwd.md5", cg->cups_serverroot); + snprintf(passwdold, sizeof(passwdold), "%s/passwd.old", cg->cups_serverroot); + snprintf(passwdnew, sizeof(passwdnew), "%s/passwd.new", cg->cups_serverroot); + + /* + * Find the default system group... + */ + + if (getgrnam(CUPS_DEFAULT_GROUP)) + groupname = CUPS_DEFAULT_GROUP; + 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() && getuid() != geteuid() && (op != CHANGE || username)) + { + _cupsLangPuts(stderr, + _("lppasswd: Only root can add or delete passwords!\n")); + 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) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to copy password string: %s\n"), + strerror(errno)); + return (1); + } + } + + /* + * Now get the new password, if necessary... + */ + + if (op != DELETE) + { + if ((passwd = cupsGetPassword( + _cupsLangString(lang, _("Enter password:")))) == NULL) + return (1); + + if ((newpass = strdup(passwd)) == NULL) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to copy password string: %s\n"), + strerror(errno)); + return (1); + } + + if ((passwd = cupsGetPassword( + _cupsLangString(lang, _("Enter password again:")))) == NULL) + return (1); + + if (strcmp(passwd, newpass) != 0) + { + _cupsLangPuts(stderr, + _("lppasswd: Sorry, passwords don't match!\n")); + return (1); + } + + /* + * Check that the password contains at least one letter and number. + */ + + flag = 0; + + for (passwd = newpass; *passwd; passwd ++) + if (isdigit(*passwd & 255)) + flag |= 1; + else if (isalpha(*passwd & 255)) + 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) + { + _cupsLangPuts(stderr, + _("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")); + return (1); + } + } + + /* + * Ignore SIGHUP, SIGINT, SIGTERM, and SIGXFSZ (if defined) for the + * remainder of the time so that we won't end up with bogus password + * files... + */ + +#ifndef WIN32 +# if defined(HAVE_SIGSET) + sigset(SIGHUP, SIG_IGN); + sigset(SIGINT, SIG_IGN); + sigset(SIGTERM, SIG_IGN); +# ifdef SIGXFSZ + sigset(SIGXFSZ, SIG_IGN); +# endif /* SIGXFSZ */ +# elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + + sigaction(SIGHUP, &action, NULL); + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +# ifdef SIGXFSZ + sigaction(SIGXFSZ, &action, NULL); +# endif /* SIGXFSZ */ +# else + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGTERM, SIG_IGN); +# ifdef SIGXFSZ + signal(SIGXFSZ, SIG_IGN); +# endif /* SIGXFSZ */ +# endif +#endif /* !WIN32 */ + + /* + * Open the output file. + */ + + if ((fd = open(passwdnew, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0) + { + if (errno == EEXIST) + _cupsLangPuts(stderr, _("lppasswd: Password file busy!\n")); + else + _cupsLangPrintf(stderr, + _("lppasswd: Unable to open password file: %s\n"), + strerror(errno)); + + return (1); + } + + if ((outfile = fdopen(fd, "w")) == NULL) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to open password file: %s\n"), + strerror(errno)); + + unlink(passwdnew); + + return (1); + } + + setbuf(outfile, NULL); + + /* + * Open the existing password file and create a new one... + */ + + infile = fopen(passwdmd5, "r"); + if (infile == NULL && errno != ENOENT && op != ADD) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to open password file: %s\n"), + strerror(errno)); + + fclose(outfile); + + unlink(passwdnew); + + return (1); + } + + /* + * Read lines from the password file; the format is: + * + * username:group:MD5-sum + */ + + error = 0; + userline[0] = '\0'; + groupline[0] = '\0'; + md5line[0] = '\0'; + + 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; + + if (fputs(line, outfile) == EOF) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to write to password file: %s\n"), + strerror(errno)); + error = 1; + break; + } + } + + if (!error) + { + while (fgets(line, sizeof(line), infile) != NULL) + if (fputs(line, outfile) == EOF) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to write to password file: %s\n"), + strerror(errno)); + error = 1; + break; + } + } + } + + if (op == CHANGE && + (strcmp(username, userline) || strcmp(groupname, groupline))) + { + _cupsLangPrintf(stderr, + _("lppasswd: user \"%s\" and group \"%s\" do not exist.\n"), + username, groupname); + error = 1; + } + else if (op != DELETE) + { + if (oldpass && + strcmp(httpMD5(username, "CUPS", oldpass, md5new), md5line) != 0) + { + _cupsLangPuts(stderr, + _("lppasswd: Sorry, password doesn't match!\n")); + error = 1; + } + else + { + snprintf(line, sizeof(line), "%s:%s:%s\n", username, groupname, + httpMD5(username, "CUPS", newpass, md5new)); + if (fputs(line, outfile) == EOF) + { + _cupsLangPrintf(stderr, + _("lppasswd: Unable to write to password file: %s\n"), + strerror(errno)); + error = 1; + } + } + } + + /* + * Close the files... + */ + + if (infile) + fclose(infile); + + if (fclose(outfile) == EOF) + error = 1; + + /* + * Error out gracefully as needed... + */ + + if (error) + { + _cupsLangPuts(stderr, _("lppasswd: Password file not updated!\n")); + + unlink(passwdnew); + + return (1); + } + + /* + * Save old passwd file + */ + + unlink(passwdold); + if (link(passwdmd5, passwdold) && errno != ENOENT) + { + _cupsLangPrintf(stderr, + _("lppasswd: failed to backup old password file: %s\n"), + strerror(errno)); + unlink(passwdnew); + return (1); + } + + /* + * Install new password file + */ + + if (rename(passwdnew, passwdmd5) < 0) + { + _cupsLangPrintf(stderr, + _("lppasswd: failed to rename password file: %s\n"), + strerror(errno)); + unlink(passwdnew); + return (1); + } + + return (0); +} + + +/* + * 'usage()' - Show program usage. + */ + +static void +usage(FILE *fp) /* I - File to send usage to */ +{ + if (getuid()) + _cupsLangPuts(fp, _("Usage: lppasswd [-g groupname]\n")); + else + _cupsLangPuts(fp, + _("Usage: lppasswd [-g groupname] [username]\n" + " lppasswd [-g groupname] -a [username]\n" + " lppasswd [-g groupname] -x [username]\n")); + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/systemv/lpstat.c b/systemv/lpstat.c new file mode 100644 index 0000000000..5140467601 --- /dev/null +++ b/systemv/lpstat.c @@ -0,0 +1,2011 @@ +/* + * "$Id$" + * + * "lpstat" command for CUPS. + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and show status information. + * check_dest() - Verify that the named destination(s) exists. + * match_list() - Match a name from a list of comma or space-separated + * names. + * 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 +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void check_dest(const char *command, const char *name, + int *num_dests, cups_dest_t **dests); +static int match_list(const char *list, const char *name); +static int show_accepting(const char *printers, int num_dests, + cups_dest_t *dests); +static int show_classes(const char *dests); +static void show_default(cups_dest_t *dest); +static int show_devices(const char *printers, int num_dests, + cups_dest_t *dests); +static int show_jobs(const char *dests, const char *users, int long_status, + int ranking, const char *which); +static int show_printers(const char *printers, int num_dests, + cups_dest_t *dests, int long_status); +static void show_scheduler(void); + + +/* + * '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 */ + status; /* Exit status */ + int num_dests; /* Number of user destinations */ + cups_dest_t *dests; /* User destinations */ + int long_status; /* Long status report? */ + int ranking; /* Show job ranking? */ + const char *which; /* Which jobs to show? */ + char op; /* Last operation on command-line */ + + + _cupsSetLocale(argv); + + /* + * Parse command-line options... + */ + + num_dests = 0; + dests = NULL; + long_status = 0; + ranking = 0; + status = 0; + which = "not-completed"; + op = 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_SSL + cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); +#else + _cupsLangPrintf(stderr, + _("%s: Sorry, no encryption support compiled in!\n"), + argv[0]); +#endif /* HAVE_SSL */ + break; + + case 'H' : /* Show server and port */ + if (cupsServer()[0] == '/') + _cupsLangPrintf(stdout, "%s\n", cupsServer()); + else + _cupsLangPrintf(stdout, "%s:%d\n", cupsServer(), ippPort()); + break; + + case 'P' : /* Show paper types */ + op = 'P'; + break; + + case 'R' : /* Show ranking */ + ranking = 1; + break; + + case 'S' : /* Show charsets */ + op = 'S'; + if (!argv[i][2]) + i ++; + break; + + case 'U' : /* Username */ + if (argv[i][2]) + cupsSetUser(argv[i] + 2); + else + { + i ++; + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected username after " + "\'-U\' option!\n"), + argv[0]); + return (1); + } + + cupsSetUser(argv[i]); + } + break; + + case 'W' : /* Show which jobs? */ + if (argv[i][2]) + which = argv[i] + 2; + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - need \"completed\", " + "\"not-completed\", or \"all\" after " + "\'-W\' option!\n"), + argv[0]); + return (1); + } + + which = argv[i]; + } + + if (strcmp(which, "completed") && strcmp(which, "not-completed") && + strcmp(which, "all")) + { + _cupsLangPrintf(stderr, + _("%s: Error - need \"completed\", " + "\"not-completed\", or \"all\" after " + "\'-W\' option!\n"), + argv[0]); + return (1); + } + break; + + case 'a' : /* Show acceptance status */ + op = 'a'; + + if (argv[i][2]) + { + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + status |= show_accepting(argv[i] + 2, num_dests, dests); + } + else if ((i + 1) < argc && argv[i + 1][0] != '-') + { + i ++; + + check_dest(argv[0], argv[i], &num_dests, &dests); + + status |= show_accepting(argv[i], num_dests, dests); + } + else + { + if (num_dests <= 1) + { + cupsFreeDests(num_dests, dests); + num_dests = cupsGetDests(&dests); + } + + status |= show_accepting(NULL, num_dests, dests); + } + break; + +#ifdef __sgi + case 'b' : /* Show both the local and remote status */ + op = 'b'; + + if (argv[i][2]) + { + /* + * 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... + */ + + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + puts(""); + status |= show_jobs(argv[i] + 2, NULL, 3, ranking, which); + } + else + { + _cupsLangPrintf(stderr, + _("%s: Error - expected destination after " + "\'-b\' option!\n"), + argv[0]); + + return (1); + } + break; +#endif /* __sgi */ + + case 'c' : /* Show classes and members */ + op = 'c'; + + if (argv[i][2]) + { + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + status |= show_classes(argv[i] + 2); + } + else if ((i + 1) < argc && argv[i + 1][0] != '-') + { + i ++; + + check_dest(argv[0], argv[i], &num_dests, &dests); + + status |= show_classes(argv[i]); + } + else + status |= show_classes(NULL); + break; + + case 'd' : /* Show default destination */ + op = 'd'; + + if (num_dests != 1 || !dests[0].is_default) + { + cupsFreeDests(num_dests, dests); + + dests = cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL); + num_dests = dests ? 1 : 0; + } + + show_default(dests); + break; + + case 'f' : /* Show forms */ + op = 'f'; + if (!argv[i][2]) + i ++; + break; + + case 'h' : /* Connect to host */ + if (argv[i][2]) + cupsSetServer(argv[i] + 2); + else + { + i ++; + + if (i >= argc) + { + _cupsLangPrintf(stderr, + _("%s: Error - expected hostname after " + "\'-h\' option!\n"), + argv[0]); + return (1); + } + + cupsSetServer(argv[i]); + } + break; + + case 'l' : /* Long status or long job status */ +#ifdef __sgi + op = 'l'; + + if (argv[i][2]) + { + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + status |= show_jobs(argv[i] + 2, NULL, 3, ranking, which); + } + else +#endif /* __sgi */ + long_status = 2; + break; + + case 'o' : /* Show jobs by destination */ + op = 'o'; + + if (argv[i][2]) + { + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + status |= show_jobs(argv[i] + 2, NULL, long_status, ranking, + which); + } + else if ((i + 1) < argc && argv[i + 1][0] != '-') + { + i ++; + + check_dest(argv[0], argv[i], &num_dests, &dests); + + status |= show_jobs(argv[i], NULL, long_status, ranking, which); + } + else + status |= show_jobs(NULL, NULL, long_status, ranking, which); + break; + + case 'p' : /* Show printers */ + op = 'p'; + + if (argv[i][2]) + { + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + status |= show_printers(argv[i] + 2, num_dests, dests, + long_status); + } + else if ((i + 1) < argc && argv[i + 1][0] != '-') + { + i ++; + + check_dest(argv[0], argv[i], &num_dests, &dests); + + status |= show_printers(argv[i], num_dests, dests, long_status); + } + else + { + if (num_dests <= 1) + { + cupsFreeDests(num_dests, dests); + num_dests = cupsGetDests(&dests); + } + + status |= show_printers(NULL, num_dests, dests, long_status); + } + break; + + case 'r' : /* Show scheduler status */ + op = 'r'; + + show_scheduler(); + break; + + case 's' : /* Show summary */ + op = 's'; + + if (num_dests <= 1) + { + cupsFreeDests(num_dests, dests); + num_dests = cupsGetDests(&dests); + } + + show_default(cupsGetDest(NULL, NULL, num_dests, dests)); + status |= show_classes(NULL); + status |= show_devices(NULL, num_dests, dests); + break; + + case 't' : /* Show all info */ + op = 't'; + + if (num_dests <= 1) + { + cupsFreeDests(num_dests, dests); + num_dests = cupsGetDests(&dests); + } + + show_scheduler(); + show_default(cupsGetDest(NULL, NULL, num_dests, dests)); + status |= show_classes(NULL); + status |= show_devices(NULL, num_dests, dests); + status |= show_accepting(NULL, num_dests, dests); + status |= show_printers(NULL, num_dests, dests, long_status); + status |= show_jobs(NULL, NULL, long_status, ranking, which); + break; + + case 'u' : /* Show jobs by user */ + op = 'u'; + + if (argv[i][2]) + status |= show_jobs(NULL, argv[i] + 2, long_status, ranking, + which); + else if ((i + 1) < argc && argv[i + 1][0] != '-') + { + i ++; + status |= show_jobs(NULL, argv[i], long_status, ranking, which); + } + else + status |= show_jobs(NULL, NULL, long_status, ranking, which); + break; + + case 'v' : /* Show printer devices */ + op = 'v'; + + if (argv[i][2]) + { + check_dest(argv[0], argv[i] + 2, &num_dests, &dests); + + status |= show_devices(argv[i] + 2, num_dests, dests); + } + else if ((i + 1) < argc && argv[i + 1][0] != '-') + { + i ++; + + check_dest(argv[0], argv[i], &num_dests, &dests); + + status |= show_devices(argv[i], num_dests, dests); + } + else + { + if (num_dests <= 1) + { + cupsFreeDests(num_dests, dests); + num_dests = cupsGetDests(&dests); + } + + status |= show_devices(NULL, num_dests, dests); + } + break; + + default : + _cupsLangPrintf(stderr, + _("%s: Error - unknown option \'%c\'!\n"), + argv[0], argv[i][1]); + return (1); + } + else + { + status |= show_jobs(argv[i], NULL, long_status, ranking, which); + op = 'o'; + } + + if (!op) + status |= show_jobs(NULL, cupsUser(), long_status, ranking, which); + + return (status); +} + + +/* + * 'check_dest()' - Verify that the named destination(s) exists. + */ + +static void +check_dest(const char *command, /* I - Command name */ + const char *name, /* I - List of printer/class names */ + int *num_dests, /* IO - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + const char *dptr; /* Pointer into name */ + char *pptr, /* Pointer into printer */ + printer[1024]; /* Current printer/class name */ + + + /* + * Load the destination list as necessary... + */ + + if (*num_dests <= 1) + { + if (*num_dests) + cupsFreeDests(*num_dests, *dests); + + if (strchr(name, ',')) + *num_dests = cupsGetDests(dests); + else + { + strlcpy(printer, name, sizeof(printer)); + if ((pptr = strchr(printer, '/')) != NULL) + *pptr++ = '\0'; + + if ((*dests = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer, pptr)) == NULL) + { + _cupsLangPrintf(stderr, + _("%s: Invalid destination name in list \"%s\"!\n"), + command, name); + exit(1); + } + else + { + *num_dests = 1; + return; + } + } + } + + /* + * Scan the name string for printer/class name(s)... + */ + + for (dptr = name; *dptr;) + { + /* + * Skip leading whitespace and commas... + */ + + while (isspace(*dptr & 255) || *dptr == ',') + dptr ++; + + if (!*dptr) + break; + + /* + * Extract a single destination name from the name string... + */ + + for (pptr = printer; !isspace(*dptr & 255) && *dptr != ',' && *dptr;) + { + if ((pptr - printer) < (sizeof(printer) - 1)) + *pptr++ = *dptr++; + else + { + _cupsLangPrintf(stderr, + _("%s: Invalid destination name in list \"%s\"!\n"), + command, name); + exit(1); + } + } + + *pptr = '\0'; + + /* + * Check the destination... + */ + + if (!cupsGetDest(printer, NULL, *num_dests, *dests)) + { + _cupsLangPrintf(stderr, + _("%s: Unknown destination \"%s\"!\n"), command, printer); + exit(1); + } + } +} + + +/* + * 'match_list()' - Match a name from a list of comma or space-separated names. + */ + +static int /* O - 1 on match, 0 on no match */ +match_list(const char *list, /* I - List of names */ + const char *name) /* I - Name to find */ +{ + const char *nameptr; /* Pointer into name */ + + + /* + * An empty list always matches... + */ + + if (!list || !*list) + return (1); + + while (*list) + { + /* + * Skip leading whitespace and commas... + */ + + while (isspace(*list & 255) || *list == ',') + list ++; + + if (!*list) + break; + + /* + * Compare names... + */ + + for (nameptr = name; + *nameptr && *list && tolower(*nameptr & 255) == tolower(*list & 255); + nameptr ++, list ++); + + if (!*nameptr && (!*list || *list == ',' || isspace(*list & 255))) + return (1); + + while (*list && !isspace(*list & 255) && *list != ',') + list ++; + } + + return (0); +} + + +/* + * 'show_accepting()' - Show acceptance status. + */ + +static int /* O - 0 on success, 1 on fail */ +show_accepting(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 */ + const char *printer, /* Printer name */ + *message; /* Printer device URI */ + int accepting; /* Accepting requests? */ + time_t ptime; /* Printer state time */ + struct tm *pdate; /* Printer state date & time */ + char printer_state_time[255];/* Printer state time */ + static const char *pattrs[] = /* Attributes we need for printers... */ + { + "printer-name", + "printer-state-change-time", + "printer-state-message", + "printer-is-accepting-jobs" + }; + + + DEBUG_printf(("show_accepting(printers=\"%s\")\n", printers)); + + if (printers != NULL && !strcmp(printers, "all")) + printers = NULL; + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requested-attributes + * requesting-user-name + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + DEBUG_puts("show_accepting: request succeeded..."); + + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + ippDelete(response); + return (1); + } + + /* + * 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; + ptime = 0; + + while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) + { + if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) + printer = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-state-change-time") && + attr->value_tag == IPP_TAG_INTEGER) + ptime = (time_t)attr->values[0].integer; + else if (!strcmp(attr->name, "printer-state-message") && + attr->value_tag == IPP_TAG_TEXT) + message = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-is-accepting-jobs") && + 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; + } + + /* + * Display the printer entry if needed... + */ + + if (match_list(printers, printer)) + { + pdate = localtime(&ptime); + strftime(printer_state_time, sizeof(printer_state_time), "%c", pdate); + + if (accepting) + _cupsLangPrintf(stdout, _("%s accepting requests since %s\n"), + printer, printer_state_time); + else + _cupsLangPrintf(stdout, _("%s not accepting requests since %s -\n" + "\t%s\n"), + printer, printer_state_time, + (message == NULL || !*message) ? + "reason unknown" : message); + + for (i = 0; i < num_dests; i ++) + if (!strcasecmp(dests[i].name, printer) && dests[i].instance) + { + if (accepting) + _cupsLangPrintf(stdout, _("%s/%s accepting requests since %s\n"), + printer, dests[i].instance, printer_state_time); + else + _cupsLangPrintf(stdout, _("%s/%s not accepting requests since " + "%s -\n\t%s\n"), + printer, dests[i].instance, printer_state_time, + (message == NULL || !*message) ? + "reason unknown" : message); + } + } + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'show_classes()' - Show printer classes. + */ + +static int /* O - 0 on success, 1 on fail */ +show_classes(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 */ + 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 */ + static const char *cattrs[] = /* Attributes we need for classes... */ + { + "printer-name", + "printer-uri-supported", + "member-names" + }; + + + DEBUG_printf(("show_classes(dests=\"%s\")\n", dests)); + + if (dests != NULL && !strcmp(dests, "all")) + dests = NULL; + + /* + * Build a CUPS_GET_CLASSES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requested-attributes + * requesting-user-name + */ + + request = ippNewRequest(CUPS_GET_CLASSES); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(cattrs) / sizeof(cattrs[0]), + NULL, cattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + DEBUG_puts("show_classes: request succeeded..."); + + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + ippDelete(response); + return (1); + } + + /* + * 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") && + attr->value_tag == IPP_TAG_NAME) + printer = attr->values[0].string.text; + + if (!strcmp(attr->name, "printer-uri-supported") && + attr->value_tag == IPP_TAG_URI) + printer_uri = attr->values[0].string.text; + + if (!strcmp(attr->name, "member-names") && + 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) + { + httpSeparateURI(HTTP_URI_CODING_ALL, printer_uri, method, sizeof(method), + username, sizeof(username), server, sizeof(server), + &port, resource, sizeof(resource)); + + if (!strcasecmp(server, cupsServer())) + http2 = CUPS_HTTP_DEFAULT; + else + http2 = httpConnectEncrypt(server, port, cupsEncryption()); + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requested-attributes + */ + + request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); + + 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); + + if (http2) + httpClose(http2); + } + + /* + * See if we have everything needed... + */ + + if (printer == NULL) + { + if (response2) + ippDelete(response2); + + if (attr == NULL) + break; + else + continue; + } + + /* + * Display the printer entry if needed... + */ + + if (match_list(dests, printer)) + { + _cupsLangPrintf(stdout, _("members of class %s:\n"), printer); + + if (members) + { + for (i = 0; i < members->num_values; i ++) + _cupsLangPrintf(stdout, "\t%s\n", + members->values[i].string.text); + } + else + _cupsLangPuts(stdout, "\tunknown\n"); + } + + if (response2) + ippDelete(response2); + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'show_default()' - Show default destination. + */ + +static void +show_default(cups_dest_t *dest) /* I - Default destination */ +{ + const char *printer, /* Printer name */ + *val; /* Environment variable name */ + + + if (dest) + { + if (dest->instance) + _cupsLangPrintf(stdout, _("system default destination: %s/%s\n"), + dest->name, dest->instance); + else + _cupsLangPrintf(stdout, _("system default destination: %s\n"), + dest->name); + } + else + { + val = NULL; + + if ((printer = getenv("LPDEST")) == NULL) + { + if ((printer = getenv("PRINTER")) != NULL) + { + if (!strcmp(printer, "lp")) + printer = NULL; + else + val = "PRINTER"; + } + } + else + val = "LPDEST"; + + if (printer) + _cupsLangPrintf(stdout, + _("lpstat: error - %s environment variable names " + "non-existent destination \"%s\"!\n"), + val, printer); + else + _cupsLangPuts(stdout, _("no system default destination\n")); + } +} + + +/* + * 'show_devices()' - Show printer devices. + */ + +static int /* O - 0 on success, 1 on fail */ +show_devices(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 */ + const char *printer, /* Printer name */ + *uri, /* Printer URI */ + *device; /* Printer device URI */ + static const char *pattrs[] = /* Attributes we need for printers... */ + { + "printer-name", + "printer-uri-supported", + "device-uri" + }; + + + DEBUG_printf(("show_devices(printers=\"%s\")\n", printers)); + + if (printers != NULL && !strcmp(printers, "all")) + printers = NULL; + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requested-attributes + * requesting-user-name + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + DEBUG_puts("show_devices: request succeeded..."); + + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + ippDelete(response); + return (1); + } + + /* + * 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") && + attr->value_tag == IPP_TAG_NAME) + printer = attr->values[0].string.text; + + if (!strcmp(attr->name, "printer-uri-supported") && + attr->value_tag == IPP_TAG_URI) + uri = attr->values[0].string.text; + + if (!strcmp(attr->name, "device-uri") && + 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; + } + + /* + * Display the printer entry if needed... + */ + + if (match_list(printers, printer)) + { +#ifdef __osf__ /* Compaq/Digital like to do it their own way... */ + char scheme[HTTP_MAX_URI], /* Components of printer URI */ + username[HTTP_MAX_URI], + hostname[HTTP_MAX_URI], + resource[HTTP_MAX_URI]; + int port; + + + if (device == NULL) + { + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + username, sizeof(username), hostname, + sizeof(hostname), &port, resource, sizeof(resource)); + _cupsLangPrintf(stdout, + _("Output for printer %s is sent to remote " + "printer %s on %s\n"), + printer, strrchr(resource, '/') + 1, hostname); + } + else if (!strncmp(device, "file:", 5)) + _cupsLangPrintf(stdout, + _("Output for printer %s is sent to %s\n"), + printer, device + 5); + else + _cupsLangPrintf(stdout, + _("Output for printer %s is sent to %s\n"), + printer, device); + + for (i = 0; i < num_dests; i ++) + if (!strcasecmp(printer, dests[i].name) && dests[i].instance) + { + if (device == NULL) + _cupsLangPrintf(stdout, + _("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)) + _cupsLangPrintf(stdout, + _("Output for printer %s/%s is sent to %s\n"), + printer, dests[i].instance, device + 5); + else + _cupsLangPrintf(stdout, + _("Output for printer %s/%s is sent to %s\n"), + printer, dests[i].instance, device); + } +#else + if (device == NULL) + _cupsLangPrintf(stdout, _("device for %s: %s\n"), + printer, uri); + else if (!strncmp(device, "file:", 5)) + _cupsLangPrintf(stdout, _("device for %s: %s\n"), + printer, device + 5); + else + _cupsLangPrintf(stdout, _("device for %s: %s\n"), + printer, device); + + for (i = 0; i < num_dests; i ++) + if (!strcasecmp(printer, dests[i].name) && dests[i].instance) + { + if (device == NULL) + _cupsLangPrintf(stdout, _("device for %s/%s: %s\n"), + printer, dests[i].instance, uri); + else if (!strncmp(device, "file:", 5)) + _cupsLangPrintf(stdout, _("device for %s/%s: %s\n"), + printer, dests[i].instance, device + 5); + else + _cupsLangPrintf(stdout, _("device for %s/%s: %s\n"), + printer, dests[i].instance, device); + } +#endif /* __osf__ */ + } + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'show_jobs()' - Show active print jobs. + */ + +static int /* O - 0 on success, 1 on fail */ +show_jobs(const char *dests, /* I - Destinations */ + const char *users, /* I - Users */ + int long_status, /* I - Show long status? */ + int ranking, /* I - Show job ranking? */ + const char *which) /* I - Show which jobs? */ +{ + int i; /* Looping var */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr, /* Current attribute */ + *reasons; /* Job state reasons attribute */ + 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 */ + char temp[255], /* Temporary buffer */ + date[255]; /* Date buffer */ + static const char *jattrs[] = /* Attributes we need for jobs... */ + { + "job-id", + "job-k-octets", + "job-name", + "job-originating-user-name", + "job-printer-uri", + "job-state-reasons", + "time-at-creation" + }; + + + DEBUG_printf(("show_jobs(dests=\"%s\", users=\"%s\", long_status=%d, " + "ranking=%d, which=\"%s\")\n", dests, users, long_status, + ranking, which)); + + if (dests != NULL && !strcmp(dests, "all")) + dests = NULL; + + /* + * Build a IPP_GET_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requested-attributes + * requesting-user-name + * which-jobs + */ + + request = ippNewRequest(IPP_GET_JOBS); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/"); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(jattrs) / sizeof(jattrs[0]), + NULL, jattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", + NULL, which); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + /* + * Loop through the job list and display them... + */ + + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + ippDelete(response); + return (1); + } + + 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"; + reasons = NULL; + + while (attr != NULL && attr->group_tag == IPP_TAG_JOB) + { + if (!strcmp(attr->name, "job-id") && + attr->value_tag == IPP_TAG_INTEGER) + jobid = attr->values[0].integer; + + if (!strcmp(attr->name, "job-k-octets") && + attr->value_tag == IPP_TAG_INTEGER) + size = attr->values[0].integer; + + if (!strcmp(attr->name, "time-at-creation") && + attr->value_tag == IPP_TAG_INTEGER) + jobtime = attr->values[0].integer; + + if (!strcmp(attr->name, "job-printer-uri") && + attr->value_tag == IPP_TAG_URI) + if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL) + dest ++; + + if (!strcmp(attr->name, "job-originating-user-name") && + attr->value_tag == IPP_TAG_NAME) + username = attr->values[0].string.text; + + if (!strcmp(attr->name, "job-name") && + attr->value_tag == IPP_TAG_NAME) + title = attr->values[0].string.text; + + if (!strcmp(attr->name, "job-state-reasons") && + attr->value_tag == IPP_TAG_KEYWORD) + reasons = attr; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (dest == NULL || jobid == 0) + { + if (attr == NULL) + break; + else + continue; + } + + /* + * Display the job... + */ + + rank ++; + + if (match_list(dests, dest) && match_list(users, username)) + { + jobdate = localtime(&jobtime); + snprintf(temp, sizeof(temp), "%s-%d", dest, jobid); + + if (long_status == 3) + { + /* + * Show the consolidated output format for the SGI tools... + */ + + if (!strftime(date, sizeof(date), "%b %d %H:%M", jobdate)) + strcpy(date, "Unknown"); + + _cupsLangPrintf(stdout, "%s;%s;%d;%s;%s\n", + temp, username ? username : "unknown", + size, title ? title : "unknown", date); + } + else + { + if (!strftime(date, sizeof(date), "%c", jobdate)) + strcpy(date, "Unknown"); + + if (ranking) + _cupsLangPrintf(stdout, "%3d %-21s %-13s %8.0f %s\n", + rank, temp, username ? username : "unknown", + 1024.0 * size, date); + else + _cupsLangPrintf(stdout, "%-23s %-13s %8.0f %s\n", + temp, username ? username : "unknown", + 1024.0 * size, date); + if (long_status) + { + if (reasons) + { + _cupsLangPuts(stdout, _("\tAlerts:")); + for (i = 0; i < reasons->num_values; i ++) + _cupsLangPrintf(stdout, " %s", + reasons->values[i].string.text); + _cupsLangPuts(stdout, "\n"); + } + _cupsLangPrintf(stdout, _("\tqueued for %s\n"), dest); + } + } + } + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'show_printers()' - Show printers. + */ + +static int /* O - 0 on success, 1 on fail */ +show_printers(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, j; /* Looping vars */ + ipp_t *request, /* IPP Request */ + *response, /* IPP Response */ + *jobs; /* IPP Get Jobs response */ + ipp_attribute_t *attr, /* Current attribute */ + *jobattr, /* Job ID attribute */ + *reasons; /* Job state reasons attribute */ + const char *printer, /* Printer name */ + *message, /* Printer state message */ + *description, /* Description of printer */ + *location, /* Location of printer */ + *make_model, /* Make and model of printer */ + *uri; /* URI of printer */ + ipp_attribute_t *allowed, /* requesting-user-name-allowed */ + *denied; /* requestint-user-name-denied */ + ipp_pstate_t pstate; /* Printer state */ + cups_ptype_t ptype; /* Printer type */ + time_t ptime; /* Printer state time */ + struct tm *pdate; /* Printer state date & time */ + int jobid; /* Job ID of current job */ + char printer_uri[HTTP_MAX_URI], + /* Printer URI */ + printer_state_time[255];/* Printer state time */ + _cups_globals_t *cg = _cupsGlobals(); /* Global data */ + static const char *pattrs[] = /* Attributes we need for printers... */ + { + "printer-name", + "printer-state", + "printer-state-message", + "printer-state-reasons", + "printer-state-change-time", + "printer-type", + "printer-info", + "printer-location", + "printer-make-and-model", + "printer-uri-supported", + "requesting-user-name-allowed", + "requesting-user-name-denied" + }; + static const char *jattrs[] = /* Attributes we need for jobs... */ + { + "job-id", + "job-state" + }; + + + DEBUG_printf(("show_printers(printers=\"%s\", num_dests=%d, dests=%p, " + "long_status=%d)\n", printers, num_dests, dests, long_status)); + + if (printers != NULL && !strcmp(printers, "all")) + printers = NULL; + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * requested-attributes + * requesting-user-name + */ + + request = ippNewRequest(CUPS_GET_PRINTERS); + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", sizeof(pattrs) / sizeof(pattrs[0]), + NULL, pattrs); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + DEBUG_puts("show_printers: request succeeded..."); + + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + ippDelete(response); + return (1); + } + + /* + * 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; + ptime = 0; + ptype = CUPS_PRINTER_LOCAL; + pstate = IPP_PRINTER_IDLE; + message = NULL; + description = NULL; + location = NULL; + make_model = NULL; + reasons = NULL; + uri = NULL; + jobid = 0; + allowed = NULL; + denied = NULL; + + while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) + { + if (!strcmp(attr->name, "printer-name") && + attr->value_tag == IPP_TAG_NAME) + printer = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-state") && + attr->value_tag == IPP_TAG_ENUM) + pstate = (ipp_pstate_t)attr->values[0].integer; + else if (!strcmp(attr->name, "printer-type") && + attr->value_tag == IPP_TAG_ENUM) + ptype = (cups_ptype_t)attr->values[0].integer; + else if (!strcmp(attr->name, "printer-state-message") && + attr->value_tag == IPP_TAG_TEXT) + message = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-state-change-time") && + attr->value_tag == IPP_TAG_INTEGER) + ptime = (time_t)attr->values[0].integer; + else if (!strcmp(attr->name, "printer-info") && + attr->value_tag == IPP_TAG_TEXT) + description = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-location") && + attr->value_tag == IPP_TAG_TEXT) + location = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-make-and-model") && + attr->value_tag == IPP_TAG_TEXT) + make_model = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-uri-supported") && + attr->value_tag == IPP_TAG_URI) + uri = attr->values[0].string.text; + else if (!strcmp(attr->name, "printer-state-reasons") && + attr->value_tag == IPP_TAG_KEYWORD) + reasons = attr; + else if (!strcmp(attr->name, "requesting-user-name-allowed") && + attr->value_tag == IPP_TAG_NAME) + allowed = attr; + else if (!strcmp(attr->name, "requesting-user-name-denied") && + attr->value_tag == IPP_TAG_NAME) + denied = attr; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (printer == NULL) + { + if (attr == NULL) + break; + else + continue; + } + + /* + * Display the printer entry if needed... + */ + + if (match_list(printers, printer)) + { + /* + * 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 = ippNewRequest(IPP_GET_JOBS); + + request->request.op.operation_id = IPP_GET_JOBS; + request->request.op.request_id = 1; + + ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, + "requested-attributes", + sizeof(jattrs) / sizeof(jattrs[0]), NULL, jattrs); + + httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), + "ipp", NULL, "localhost", 0, "/printers/%s", printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, printer_uri); + + if ((jobs = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL) + { + /* + * Get the current active job on this queue... + */ + + ipp_jstate_t jobstate = IPP_JOB_PENDING; + jobid = 0; + + for (jobattr = jobs->attrs; jobattr; jobattr = jobattr->next) + { + if (!jobattr->name) + { + if (jobstate == IPP_JOB_PROCESSING) + break; + else + continue; + } + + if (!strcmp(jobattr->name, "job-id") && + jobattr->value_tag == IPP_TAG_INTEGER) + jobid = jobattr->values[0].integer; + else if (!strcmp(jobattr->name, "job-state") && + jobattr->value_tag == IPP_TAG_ENUM) + jobstate = jobattr->values[0].integer; + } + + if (jobstate != IPP_JOB_PROCESSING) + jobid = 0; + + ippDelete(jobs); + } + } + + /* + * Display it... + */ + + pdate = localtime(&ptime); + strftime(printer_state_time, sizeof(printer_state_time), "%c", pdate); + + switch (pstate) + { + case IPP_PRINTER_IDLE : + _cupsLangPrintf(stdout, + _("printer %s is idle. enabled since %s\n"), + printer, printer_state_time); + break; + case IPP_PRINTER_PROCESSING : + _cupsLangPrintf(stdout, + _("printer %s now printing %s-%d. " + "enabled since %s\n"), + printer, printer, jobid, printer_state_time); + break; + case IPP_PRINTER_STOPPED : + _cupsLangPrintf(stdout, + _("printer %s disabled since %s -\n"), + printer, printer_state_time); + break; + } + + if ((message && *message) || pstate == IPP_PRINTER_STOPPED) + { + if (!message || !*message) + _cupsLangPuts(stdout, _("\treason unknown\n")); + else + _cupsLangPrintf(stdout, "\t%s\n", message); + } + + if (long_status > 1) + _cupsLangPuts(stdout, + _("\tForm mounted:\n" + "\tContent types: any\n" + "\tPrinter types: unknown\n")); + + if (long_status) + { + _cupsLangPrintf(stdout, _("\tDescription: %s\n"), + description ? description : ""); + + if (reasons) + { + _cupsLangPuts(stdout, _("\tAlerts:")); + for (j = 0; j < reasons->num_values; j ++) + _cupsLangPrintf(stdout, " %s", + reasons->values[j].string.text); + _cupsLangPuts(stdout, "\n"); + } + } + if (long_status > 1) + { + _cupsLangPrintf(stdout, _("\tLocation: %s\n"), + location ? location : ""); + + if (ptype & CUPS_PRINTER_REMOTE) + { + _cupsLangPuts(stdout, _("\tConnection: remote\n")); + + if (make_model && !strstr(make_model, "System V Printer") && + !strstr(make_model, "Raw Printer") && uri) + _cupsLangPrintf(stdout, _("\tInterface: %s.ppd\n"), + uri); + } + else + { + _cupsLangPuts(stdout, _("\tConnection: direct\n")); + + if (make_model && strstr(make_model, "System V Printer")) + _cupsLangPrintf(stdout, + _("\tInterface: %s/interfaces/%s\n"), + cg->cups_serverroot, printer); + else if (make_model && !strstr(make_model, "Raw Printer")) + _cupsLangPrintf(stdout, + _("\tInterface: %s/ppd/%s.ppd\n"), + cg->cups_serverroot, printer); + } + _cupsLangPuts(stdout, _("\tOn fault: no alert\n")); + _cupsLangPuts(stdout, _("\tAfter fault: continue\n")); + /* TODO update to use printer-error-policy */ + if (allowed) + { + _cupsLangPuts(stdout, _("\tUsers allowed:\n")); + for (j = 0; j < allowed->num_values; j ++) + _cupsLangPrintf(stdout, "\t\t%s\n", + allowed->values[j].string.text); + } + else if (denied) + { + _cupsLangPuts(stdout, _("\tUsers denied:\n")); + for (j = 0; j < denied->num_values; j ++) + _cupsLangPrintf(stdout, "\t\t%s\n", + denied->values[j].string.text); + } + else + { + _cupsLangPuts(stdout, _("\tUsers allowed:\n")); + _cupsLangPuts(stdout, _("\t\t(all)\n")); + } + _cupsLangPuts(stdout, _("\tForms allowed:\n")); + _cupsLangPuts(stdout, _("\t\t(none)\n")); + _cupsLangPuts(stdout, _("\tBanner required\n")); + _cupsLangPuts(stdout, _("\tCharset sets:\n")); + _cupsLangPuts(stdout, _("\t\t(none)\n")); + _cupsLangPuts(stdout, _("\tDefault pitch:\n")); + _cupsLangPuts(stdout, _("\tDefault page size:\n")); + _cupsLangPuts(stdout, _("\tDefault port settings:\n")); + } + + for (i = 0; i < num_dests; i ++) + if (!strcasecmp(printer, dests[i].name) && dests[i].instance) + { + switch (pstate) + { + case IPP_PRINTER_IDLE : + _cupsLangPrintf(stdout, + _("printer %s/%s is idle. " + "enabled since %s\n"), + printer, dests[i].instance, + printer_state_time); + break; + case IPP_PRINTER_PROCESSING : + _cupsLangPrintf(stdout, + _("printer %s/%s now printing %s-%d. " + "enabled since %s\n"), + printer, dests[i].instance, printer, jobid, + printer_state_time); + break; + case IPP_PRINTER_STOPPED : + _cupsLangPrintf(stdout, + _("printer %s/%s disabled since %s -\n"), + printer, dests[i].instance, + printer_state_time); + break; + } + + if ((message && *message) || pstate == IPP_PRINTER_STOPPED) + { + if (!message || !*message) + _cupsLangPuts(stdout, _("\treason unknown\n")); + else + _cupsLangPrintf(stdout, "\t%s\n", message); + } + + if (long_status > 1) + _cupsLangPuts(stdout, + _("\tForm mounted:\n" + "\tContent types: any\n" + "\tPrinter types: unknown\n")); + + if (long_status) + { + _cupsLangPrintf(stdout, _("\tDescription: %s\n"), + description ? description : ""); + + if (reasons) + { + _cupsLangPuts(stdout, _("\tAlerts:")); + for (j = 0; j < reasons->num_values; j ++) + _cupsLangPrintf(stdout, " %s", + reasons->values[j].string.text); + _cupsLangPuts(stdout, "\n"); + } + } + if (long_status > 1) + { + _cupsLangPrintf(stdout, _("\tLocation: %s\n"), + location ? location : ""); + + if (ptype & CUPS_PRINTER_REMOTE) + { + _cupsLangPuts(stdout, _("\tConnection: remote\n")); + + if (make_model && !strstr(make_model, "System V Printer") && + !strstr(make_model, "Raw Printer") && uri) + _cupsLangPrintf(stdout, _("\tInterface: %s.ppd\n"), + uri); + } + else + { + _cupsLangPuts(stdout, _("\tConnection: direct\n")); + + if (make_model && strstr(make_model, "System V Printer")) + _cupsLangPrintf(stdout, + _("\tInterface: %s/interfaces/%s\n"), + cg->cups_serverroot, printer); + else if (make_model && !strstr(make_model, "Raw Printer")) + _cupsLangPrintf(stdout, + _("\tInterface: %s/ppd/%s.ppd\n"), + cg->cups_serverroot, printer); + } + _cupsLangPuts(stdout, _("\tOn fault: no alert\n")); + _cupsLangPuts(stdout, _("\tAfter fault: continue\n")); + /* TODO update to use printer-error-policy */ + if (allowed) + { + _cupsLangPuts(stdout, _("\tUsers allowed:\n")); + for (j = 0; j < allowed->num_values; j ++) + _cupsLangPrintf(stdout, "\t\t%s\n", + allowed->values[j].string.text); + } + else if (denied) + { + _cupsLangPuts(stdout, _("\tUsers denied:\n")); + for (j = 0; j < denied->num_values; j ++) + _cupsLangPrintf(stdout, "\t\t%s\n", + denied->values[j].string.text); + } + else + { + _cupsLangPuts(stdout, _("\tUsers allowed:\n")); + _cupsLangPuts(stdout, _("\t\t(all)\n")); + } + _cupsLangPuts(stdout, _("\tForms allowed:\n")); + _cupsLangPuts(stdout, _("\t\t(none)\n")); + _cupsLangPuts(stdout, _("\tBanner required\n")); + _cupsLangPuts(stdout, _("\tCharset sets:\n")); + _cupsLangPuts(stdout, _("\t\t(none)\n")); + _cupsLangPuts(stdout, _("\tDefault pitch:\n")); + _cupsLangPuts(stdout, _("\tDefault page size:\n")); + _cupsLangPuts(stdout, _("\tDefault port settings:\n")); + } + } + } + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + _cupsLangPrintf(stderr, "lpstat: %s\n", cupsLastErrorString()); + return (1); + } + + return (0); +} + + +/* + * 'show_scheduler()' - Show scheduler status. + */ + +static void +show_scheduler(void) +{ + http_t *http; /* Connection to server */ + + + if ((http = httpConnectEncrypt(cupsServer(), ippPort(), + cupsEncryption())) != NULL) + { + _cupsLangPuts(stdout, _("scheduler is running\n")); + httpClose(http); + } + else + _cupsLangPuts(stdout, _("scheduler is not running\n")); +} + + +/* + * End of "$Id$". + */ diff --git a/templates/Makefile b/templates/Makefile new file mode 100644 index 0000000000..9d2cf71d29 --- /dev/null +++ b/templates/Makefile @@ -0,0 +1,201 @@ +# +# "$Id$" +# +# Template makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1993-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +# +# Template files... +# + +FILES = \ + add-class.tmpl \ + add-printer.tmpl \ + add-rss-subscription.tmpl \ + admin.tmpl \ + choose-device.tmpl \ + choose-make.tmpl \ + choose-model.tmpl \ + choose-serial.tmpl \ + choose-uri.tmpl \ + class.tmpl \ + class-added.tmpl \ + class-confirm.tmpl \ + class-deleted.tmpl \ + class-jobs-header.tmpl \ + class-modified.tmpl \ + classes.tmpl \ + classes-header.tmpl \ + command.tmpl \ + edit-config.tmpl \ + error.tmpl \ + error-op.tmpl \ + header.tmpl \ + help-header.tmpl \ + help-trailer.tmpl \ + help-printable.tmpl \ + job-cancel.tmpl \ + job-hold.tmpl \ + job-move.tmpl \ + job-moved.tmpl \ + job-release.tmpl \ + job-restart.tmpl \ + jobs.tmpl \ + jobs-header.tmpl \ + list-available-printers.tmpl \ + modify-class.tmpl \ + modify-printer.tmpl \ + norestart.tmpl \ + option-boolean.tmpl \ + option-conflict.tmpl \ + option-header.tmpl \ + option-pickmany.tmpl \ + option-pickone.tmpl \ + option-trailer.tmpl \ + pager.tmpl \ + printer.tmpl \ + printer-accept.tmpl \ + printer-added.tmpl \ + printer-configured.tmpl \ + printer-confirm.tmpl \ + printer-default.tmpl \ + printer-deleted.tmpl \ + printer-jobs-header.tmpl \ + printer-modified.tmpl \ + printer-purge.tmpl \ + printer-reject.tmpl \ + printer-start.tmpl \ + printer-stop.tmpl \ + printers.tmpl \ + printers-header.tmpl \ + restart.tmpl \ + samba-export.tmpl \ + samba-exported.tmpl \ + search.tmpl \ + set-printer-options-header.tmpl \ + set-printer-options-trailer.tmpl \ + subscription-added.tmpl \ + subscription-canceled.tmpl \ + test-page.tmpl \ + trailer.tmpl \ + users.tmpl + + +# +# Make everything... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Dummy depend... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: $(INSTALL_LANGUAGES) + $(INSTALL_DIR) -m 755 $(DATADIR)/templates + for file in $(FILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/templates; \ + done + +install-languages: + for lang in $(LANGUAGES); do \ + if test -d $$lang; then \ + $(INSTALL_DIR) -m 755 $(DATADIR)/templates/$$lang; \ + for file in $(FILES); do \ + $(INSTALL_DATA) $$lang/$$file $(DATADIR)/templates/$$lang >/dev/null 2>&1 || true; \ + done \ + fi \ + done + + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: $(UNINSTALL_LANGUAGES) + for file in $(FILES); do \ + $(RM) $(DATADIR)/templates/$$file; \ + done + -$(RMDIR) $(DATADIR)/templates + +uninstall-languages: + for lang in $(LANGUAGES); do \ + for file in $(FILES); do \ + $(RM) $(DATADIR)/templates/$$lang/$$file; \ + done \ + $(RMDIR) $(DATADIR)/templates/$$lang; \ + done + + +# +# End of "$Id$". +# diff --git a/templates/add-class.tmpl b/templates/add-class.tmpl new file mode 100644 index 0000000000..eaf52d73dc --- /dev/null +++ b/templates/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Add Class

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(May contain any printable characters except "/", "#", and space)
    Description:
    +(Human-readable description such as "HP LaserJet with Duplexer")
    Location:
    +(Human-readable location such as "Lab 1")
    Members: + +
    + +
    +
    \ No newline at end of file diff --git a/templates/add-printer.tmpl b/templates/add-printer.tmpl new file mode 100644 index 0000000000..361958b674 --- /dev/null +++ b/templates/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    Add Printer

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(May contain any printable characters except "/", "#", and space)
    Description:
    +(Human-readable description such as "HP LaserJet with Duplexer")
    Location:
    +(Human-readable location such as "Lab 1")
    Connection:{device_uri}
    Sharing: +Share This Printer
    + +
    +
    \ No newline at end of file diff --git a/templates/add-rss-subscription.tmpl b/templates/add-rss-subscription.tmpl new file mode 100644 index 0000000000..17e3fa0d37 --- /dev/null +++ b/templates/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Add RSS Subscription

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(May contain any printable characters except space, "/", "?", and "#")
    Queue:
    Events:Job Created
    +Job Completed
    +Job Stopped
    +Job Options Changed
        Queue Stopped
    +Queue Added
    +Queue Modified
    +Queue Deleted
        Server Started
    +Server Stopped
    +Server Restarted
    +Server Security Auditing
    Maximum Events in Feed:
    + +
    diff --git a/templates/admin.tmpl b/templates/admin.tmpl new file mode 100644 index 0000000000..477da139ed --- /dev/null +++ b/templates/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Printers

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Classes

    + +

    +

    +
    +

    + +

    Jobs

    + +

    +

    +

    + +
              + +

    Server

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Server Settings\:

    + +

    Advanced
    + + + Show printers shared by other systems
    +        Protocols\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Share printers connected to this system
    +        Max clients\: +
    +        Protocols\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Allow printing from the Internet
    +         Advertise web interface
    + Allow remote administration
    +{have_gssapi? Use Kerberos authentication (FAQ)
    :} + Allow users to cancel any job (not just their own)
    + Preserve job history
    +        Number of jobs\: +
    +         Preserve job print files
    + Save debugging information for troubleshooting
    +        Max log file size\: +

    + +:

    Server Settings:

    + +

    Advanced
    + + Show printers shared by other systems
    + Share printers connected to this system
    +         Allow printing from the Internet
    + Allow remote administration
    +{have_gssapi? Use Kerberos authentication (FAQ)
    :} + Allow users to cancel any job (not just their own)
    + Save debugging information for troubleshooting

    + +} +

    + +
    } + +
    + +
    + +

    RSS Subscriptions

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    NameEventsQueue Name
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:All Queues}
    :} diff --git a/templates/choose-device.tmpl b/templates/choose-device.tmpl new file mode 100644 index 0000000000..c5ab251b54 --- /dev/null +++ b/templates/choose-device.tmpl @@ -0,0 +1,53 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Add Printer}

    + +{CUPS_GET_DEVICES_DONE?
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Current Connection\: +{current_device_uri}
    Local Printers\: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Discovered Network Printers\: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Other Network Printers\: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    :

    Looking for printers...

    } + +
    diff --git a/templates/choose-make.tmpl b/templates/choose-make.tmpl new file mode 100644 index 0000000000..65096ad9a6 --- /dev/null +++ b/templates/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Add Printer}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:{printer_name}
    Description:{printer_info}
    Location:{printer_location}
    Connection:{device_uri}
    Sharing: +{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Share This Printer
    Make: + +
     
    Or Provide a PPD File:
    + +
    +
    \ No newline at end of file diff --git a/templates/choose-model.tmpl b/templates/choose-model.tmpl new file mode 100644 index 0000000000..992cd01fd6 --- /dev/null +++ b/templates/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Add Printer}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:{printer_name}
    Description:{printer_info}
    Location:{printer_location}
    Connection:{device_uri}
    Sharing: +{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Share This Printer
    Make:{PPD_MAKE}
    Model: + +
    Or Provide a PPD File:
    + +
    +
    \ No newline at end of file diff --git a/templates/choose-serial.tmpl b/templates/choose-serial.tmpl new file mode 100644 index 0000000000..56a14a4cbf --- /dev/null +++ b/templates/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Add Printer}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Connection:{device_uri}
    Baud Rate:
    Parity:
    Data Bits:
    Flow Control:
    + +
    +
    \ No newline at end of file diff --git a/templates/choose-uri.tmpl b/templates/choose-uri.tmpl new file mode 100644 index 0000000000..45d84de194 --- /dev/null +++ b/templates/choose-uri.tmpl @@ -0,0 +1,44 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Add Printer}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Connection:
    Examples: +
    +    http://hostname:631/ipp/
    +    http://hostname:631/ipp/port1
    +
    +    ipp://hostname/ipp/
    +    ipp://hostname/ipp/port1
    +
    +    lpd://hostname/queue
    +
    +    socket://hostname
    +    socket://hostname:9100
    +
    + +

    See "Network +Printers" for the correct URI to use with your printer.

    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/class-added.tmpl b/templates/class-added.tmpl new file mode 100644 index 0000000000..c062a16d5a --- /dev/null +++ b/templates/class-added.tmpl @@ -0,0 +1,8 @@ +
    diff --git a/templates/class-confirm.tmpl b/templates/class-confirm.tmpl new file mode 100644 index 0000000000..5f0277cb51 --- /dev/null +++ b/templates/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Delete Class {printer_name}

    + +

    Warning: Are you sure you want to delete class +{printer_name}?

    + +

    + +
    diff --git a/templates/class-deleted.tmpl b/templates/class-deleted.tmpl new file mode 100644 index 0000000000..a4ad46a0ad --- /dev/null +++ b/templates/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Delete Class {printer_name}

    + +

    Class {printer_name} has been deleted successfully. + +

    \ No newline at end of file diff --git a/templates/class-jobs-header.tmpl b/templates/class-jobs-header.tmpl new file mode 100644 index 0000000000..ba46f10260 --- /dev/null +++ b/templates/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Jobs

    +
    diff --git a/templates/class-modified.tmpl b/templates/class-modified.tmpl new file mode 100644 index 0000000000..fe42c907bb --- /dev/null +++ b/templates/class-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Modify Class {printer_name}

    + +

    Class {printer_name} has been +modified successfully. + +

    \ No newline at end of file diff --git a/templates/class.tmpl b/templates/class.tmpl new file mode 100644 index 0000000000..477e0e8edb --- /dev/null +++ b/templates/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?Idle:{printer_state=4?Processing:Paused}}, +{printer_is_accepting_jobs=0?Rejecting Jobs:Accepting Jobs}, +{server_is_sharing_printers=0?Not:{printer_is_shared=0?Not:}} Shared{default_name={printer_name}?, Server Default:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Description:{printer_info}
    Location:{printer_location}
    Members:{?member_uris=?None:{member_uris}}
    Defaults:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/classes-header.tmpl b/templates/classes-header.tmpl new file mode 100644 index 0000000000..7ac98fbddc --- /dev/null +++ b/templates/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?No classes:Showing {#printer_name} of {total} class{total=1?:es}}.

    diff --git a/templates/classes.tmpl b/templates/classes.tmpl new file mode 100644 index 0000000000..51e454fb1c --- /dev/null +++ b/templates/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Queue Name : Queue Name }DescriptionLocationMembersStatus
    {printer_name}{printer_info}{printer_location}{?member_uris=?None:{member_uris}}{printer_state=3?Idle:{printer_state=4?Processing:Paused}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/command.tmpl b/templates/command.tmpl new file mode 100644 index 0000000000..9a87439ca5 --- /dev/null +++ b/templates/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} On {printer_name}

    + +

    {job_state>5?:Busy Indicator }Printer command job +{job_state=3?pending:{job_state=4?held: +{job_state=5?processing:{job_state=6?stopped: +{job_state=7?canceled:{job_state=8?aborted:completed}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/de/add-class.tmpl b/templates/de/add-class.tmpl new file mode 100644 index 0000000000..2753bb919b --- /dev/null +++ b/templates/de/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Klasse hinzufügen

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(Darf alle druckbaren Zeichen außer "/", "#", und Leerzeichen enthalten)
    Beschreibung:
    +(Für Menschen lesbare Beschreibung wie "HP LaserJet with Duplexer")
    Ort:
    +(Für Menschen lesbarer Ort wie "Lab 1")
    Mitglieder: + +
    + +
    +
    diff --git a/templates/de/add-printer.tmpl b/templates/de/add-printer.tmpl new file mode 100644 index 0000000000..15380b97bc --- /dev/null +++ b/templates/de/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    Drucker hinzufügen

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(Darf alle druckbaren Zeichen außer "/", "#", und Leerzeichen enthalten)
    Beschreibung:
    +(Für Menschen lesbare Beschreibung wie "HP LaserJet with Duplexer")
    Ort:
    +(Für Menschen lesbarer Ort wie "Lab 1")
    Verbindung:{device_uri}
    Freigabe: +Diesen Drucker freigeben
    + +
    +
    diff --git a/templates/de/add-rss-subscription.tmpl b/templates/de/add-rss-subscription.tmpl new file mode 100644 index 0000000000..6b92facb29 --- /dev/null +++ b/templates/de/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    RSS Subskription hinzufügen

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:
    +(Darf alle druckbaren Zeichen außer Leerzeichen, "/", "?", und "#" enthalten)
    Warteschlange:
    Ereignisse:Auftrag Erstellt
    +Auftrag Abgeschlossen
    +Auftrag Gestoppt
    +Auftrags Parameter Geändert
        Warteschlange Gestoppt
    +Warteschlange Hinzugefügt
    +Warteschlange Geändert
    +Warteschlange Gelöscht
        Server Gestartet
    +Server Gestoppt
    +Server Neu Gestartet
    +Server Sicherheits Prüfung
    Maximale Ereignisse in Durchführung:
    + +
    diff --git a/templates/de/admin.tmpl b/templates/de/admin.tmpl new file mode 100644 index 0000000000..1ad1326918 --- /dev/null +++ b/templates/de/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Drucker

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Klassen

    + +

    +

    +
    +

    + +

    Druckaufträge

    + +

    +

    +

    + +
              + +

    Server

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Erweiterte Servereinstellungen\:

    + +

    Erweitert
    + + + Zeige freigegebene Drucker von anderen Systemen
    +        Protokolle\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Freigeben von Druckern welche mit diesem System verbunden sind
    +        Klienten maximal\: +
    +        Protokolle\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Erlaube Drucken vom Internet aus
    +         Veröffentliche Webinterface
    + Erlaube entfernte Verwaltung
    +{have_gssapi? Benutze Kerberos Authentifizierung (FAQ)
    :} + Erlaube Benutzern jeden Auftrag abzubrechen (nicht nur die Eigenen)
    + Auftragsverlauf aufbewahren
    +        Anzahl der Aufträge\: +
    +         Dateien von Druckaufträgen aufbewahren
    + Speichere Fehlerinformationen für Fehlersuche
    +        Maximale Größe der Protokolldatei\: +

    + +:

    Grundlegende Servereinstellungen:

    + +

    Erweitert
    + + Zeige freigegebene Drucker von anderen Systemen
    + Freigeben von Druckern welche mit diesem System verbunden sind
    +         Erlaube Drucken vom Internet aus
    + Erlaube entfernte Verwaltung
    +{have_gssapi? Benutze Kerberos Authentifizierung (FAQ)
    :} + Erlaube Benutzern jeden Auftrag abzubrechen (nicht nur die Eigenen)
    + Speichere Fehlerinformationen für Fehlersuche

    + +} +

    + +
    } + +
    + +
    + +

    RSS Subskriptionen

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    NameEreignisWarteschlange
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Alle Warteschlangen}
    :} diff --git a/templates/de/choose-device.tmpl b/templates/de/choose-device.tmpl new file mode 100644 index 0000000000..3be8a350c1 --- /dev/null +++ b/templates/de/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?{printer_name} ändern:Drucker hinzufügen}

    + +{CUPS_GET_DEVICES_DONE?:

    Suche nach Druckern...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Aktuelle Verbindung: +{current_device_uri}
    Lokale Drucker: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unbekannt?({device_make_and_model}):}
    +:}} +
    Entdeckte Netzwerkdrucker: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unbekannt?({device_make_and_model}):}
    +:}:}} +
    Andere Netzwerkdrucker: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unbekannt?({device_make_and_model}):}
    +}:}} +
    + +
    +
    diff --git a/templates/de/choose-make.tmpl b/templates/de/choose-make.tmpl new file mode 100644 index 0000000000..6d572a6b26 --- /dev/null +++ b/templates/de/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?{printer_name} ändern:Drucker hinzufügen}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:{printer_name}
    Beschreibung:{printer_info}
    Ort:{printer_location}
    Verbindung:{device_uri}
    Freigabe: +Diesen Drucker {?printer_is_shared=?nicht:{?printer_is_shared=0?nicht:}} freigeben
    Marke: + +
     
    Oder stellen Sie eine PPD Datei bereit:
    + +
    +
    diff --git a/templates/de/choose-model.tmpl b/templates/de/choose-model.tmpl new file mode 100644 index 0000000000..2f5bb18d88 --- /dev/null +++ b/templates/de/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?{printer_name} ändern:Drucker hinzufügen}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name:{printer_name}
    Beschreibung:{printer_info}
    Ort:{printer_location}
    Verbindung:{device_uri}
    Freigabe: +Diesen Drucker {?printer_is_shared=?nicht:{?printer_is_shared=0?nicht:}} freigeben
    Marke:{PPD_MAKE}
    Modell: + +
    Oder stellen Sie eine PPD Datei bereit:
    + +
    +
    diff --git a/templates/de/choose-serial.tmpl b/templates/de/choose-serial.tmpl new file mode 100644 index 0000000000..a6f0044b55 --- /dev/null +++ b/templates/de/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?{printer_name} ändern:Drucker hinzufügen}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Verbindung:{device_uri}
    Baud Rate:
    Parität:
    Daten Bits:
    Flußkontrolle:
    + +
    +
    diff --git a/templates/de/choose-uri.tmpl b/templates/de/choose-uri.tmpl new file mode 100644 index 0000000000..0633fd6cd4 --- /dev/null +++ b/templates/de/choose-uri.tmpl @@ -0,0 +1,44 @@ +
    + +

    {op=modify-printer?{printer_name} ändern:Drucker hinzufügen}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Verbindung:
    Beispiele: +
    +    http://Hostname:631/ipp/
    +    http://Hostname:631/ipp/Anschluss1
    +
    +    ipp://Hostname/ipp/
    +    ipp://Hostname/ipp/Anschluss1
    +
    +    lpd://Hostname/Warteschlange
    +
    +    socket://Hostname
    +    socket://Hostname:9100
    +
    + +

    Bitte lesen Sie "Netzwerk +Drucker" um die korrekte URI für Ihren Drucker zu benutzen.

    + +
    + +
    +
    diff --git a/templates/de/class-added.tmpl b/templates/de/class-added.tmpl new file mode 100644 index 0000000000..3b05769a30 --- /dev/null +++ b/templates/de/class-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Klasse hinzufügen

    + +

    Die Klasse {printer_name} wurde erfolgreich +hinzugefügt. + +

    diff --git a/templates/de/class-confirm.tmpl b/templates/de/class-confirm.tmpl new file mode 100644 index 0000000000..5e0223cffd --- /dev/null +++ b/templates/de/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Klasse {printer_name} löschen

    + +

    Warnung: Sind Sie sicher, dass Sie die Klasse +{printer_name} löschen wollen?

    + +

    + +
    diff --git a/templates/de/class-deleted.tmpl b/templates/de/class-deleted.tmpl new file mode 100644 index 0000000000..9357924c11 --- /dev/null +++ b/templates/de/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Klasse {printer_name} löschen

    + +

    Die Klasse {printer_name} wurde erfolgreich gelöscht. + +

    diff --git a/templates/de/class-jobs-header.tmpl b/templates/de/class-jobs-header.tmpl new file mode 100644 index 0000000000..4f3de9340f --- /dev/null +++ b/templates/de/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Aufträge

    +
    diff --git a/templates/de/class-modified.tmpl b/templates/de/class-modified.tmpl new file mode 100644 index 0000000000..b5ad0daec5 --- /dev/null +++ b/templates/de/class-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Klasse {printer_name} ändern

    + +

    Die Klasse {printer_name} wurde +erfolgreich geändert. + +

    diff --git a/templates/de/class.tmpl b/templates/de/class.tmpl new file mode 100644 index 0000000000..61a89dc7e4 --- /dev/null +++ b/templates/de/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?Frei:{printer_state=4?Beschäftigt:Angehalten}}, +{printer_is_accepting_jobs=0?Aufträge werden ablehnt:Aufträge werden akzeptiert}, +{server_is_sharing_printers=0?Nicht:{printer_is_shared=0?Nicht:}} Freigegeben{default_name={printer_name}?, Standarddrucker:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Beschreibung:{printer_info}
    Ort:{printer_location}
    Mitglieder:{?member_uris=?None:{member_uris}}
    Standardeinstellungen:job-sheets={job_sheets_default} +media={media_default?{media_default}:unbekannt} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/de/classes-header.tmpl b/templates/de/classes-header.tmpl new file mode 100644 index 0000000000..5fa4d4ae33 --- /dev/null +++ b/templates/de/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Keine Klassen:Zeige {#printer_name} von {total} Klasse{total=1?:n}}.

    diff --git a/templates/de/classes.tmpl b/templates/de/classes.tmpl new file mode 100644 index 0000000000..1a919a80ef --- /dev/null +++ b/templates/de/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Wartweschlange : Warteschlange }BeschreibungOrtMitgliederStatus
    {printer_name}{printer_info}{printer_location}{?member_uris=?Keine:{member_uris}}{printer_state=3?Frei:{printer_state=4?Beschäftigt:Angehalten}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/de/command.tmpl b/templates/de/command.tmpl new file mode 100644 index 0000000000..45e8dce563 --- /dev/null +++ b/templates/de/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} auf {printer_name}

    + +

    {job_state>5?:Busy Indicator }Drucker Befehlsauftrag +{job_state=3?unerledigt:{job_state=4?gehalten: +{job_state=5?verarbeite:{job_state=6?gestoppt: +{job_state=7?gelöscht:{job_state=8?abgebrochen:beendet}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/de/edit-config.tmpl b/templates/de/edit-config.tmpl new file mode 100644 index 0000000000..f2913138b9 --- /dev/null +++ b/templates/de/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Konfigurationsdatei ändern

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/de/error-op.tmpl b/templates/de/error-op.tmpl new file mode 100644 index 0000000000..d47e73089a --- /dev/null +++ b/templates/de/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Error

    + +

    Fehler:

    + +
    Unbekannte Operation "{op}"!
    + +
    diff --git a/templates/de/error.tmpl b/templates/de/error.tmpl new file mode 100644 index 0000000000..1a7f6503c1 --- /dev/null +++ b/templates/de/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Error

    + +

    {?message?{message}:Fehler:}

    + +
    {error}
    + +
    diff --git a/templates/de/header.tmpl.in b/templates/de/header.tmpl.in new file mode 100644 index 0000000000..09a48164f0 --- /dev/null +++ b/templates/de/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/de/option-conflict.tmpl b/templates/de/option-conflict.tmpl new file mode 100644 index 0000000000..eac3c0de07 --- /dev/null +++ b/templates/de/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Error: The following options are conflicting:

    + + + +

    Bitte ändern sie eine oder mehrere Einstellungen um die Konflikte zu lösen.

    diff --git a/templates/de/option-header.tmpl b/templates/de/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/de/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      Startseite    Verwaltung    Klassen    Online-Hilfe    Aufträge    Drucker  
     
    diff --git a/templates/de/help-header.tmpl b/templates/de/help-header.tmpl new file mode 100644 index 0000000000..a2d68a58a7 --- /dev/null +++ b/templates/de/help-header.tmpl @@ -0,0 +1,51 @@ +
    +
    +{TOPIC?:} + +

    Suche in +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:allen Dokumenten}}: + +

    + +
    + + + + +{QUERY?

    Suchergebnisse in {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:allen Dokumenten}}\:

    +{QTEXT?:} +:

    Keine Übereinstimmung gefunden.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    CUPS Hilfeseiten

    + +

    Dies ist das CUPS online Hilfesystem. Geben Sie Ihren Suchbegriff +oben ein oder klicken Sie auf einen der Dokumentationslinks +um sich die Online Hilfe Informationen anzeigen zu lassen.

    + +

    Wenn Sie noch unerfahren im Umgang mit CUPS sind, lesen Sie die "CUPS Übersicht". +Erfahrene Benutzer sollten "Was ist neu in CUPS +1.4" lesen.

    + +

    Die CUPS Webseite bietet +ebenfalls viele Angebote inklusive Diskussionsforen fü Benutzer, +Antworten auf häufig gestellte Fragen, und ein Formular für +Fehlerberichte und Wünsche.

    } diff --git a/templates/de/help-printable.tmpl b/templates/de/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/de/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/de/help-trailer.tmpl b/templates/de/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/de/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/de/job-cancel.tmpl b/templates/de/job-cancel.tmpl new file mode 100644 index 0000000000..9bf6f38830 --- /dev/null +++ b/templates/de/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Auftrag {job_id} löschen

    + +

    Auftrag {job_id} wurde gelöscht. + +

    diff --git a/templates/de/job-hold.tmpl b/templates/de/job-hold.tmpl new file mode 100644 index 0000000000..aaddb20b68 --- /dev/null +++ b/templates/de/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Auftrag {job_id} anhalten

    + +

    Auftrag {job_id} wurde vom Drucken abgehalten. + +

    diff --git a/templates/de/job-move.tmpl b/templates/de/job-move.tmpl new file mode 100644 index 0000000000..67c57dd31b --- /dev/null +++ b/templates/de/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Auftrag {job_id} verschieben:Alle Aufträge verschieben}

    + + + + + + + + + + +
    Neues Ziel: + +
    + +
    + +
    diff --git a/templates/de/job-moved.tmpl b/templates/de/job-moved.tmpl new file mode 100644 index 0000000000..ad9624ea6f --- /dev/null +++ b/templates/de/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Auftrag {job_id} verschieben:Alle Aufträge verschieben}

    + +

    {job_id?Auftrag {job_id}:Alle Aufträge} nach +{job_printer_name} verschoben.

    + +
    diff --git a/templates/de/job-release.tmpl b/templates/de/job-release.tmpl new file mode 100644 index 0000000000..e1d4227fe6 --- /dev/null +++ b/templates/de/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Auftrag {job_id} freigeben

    + +

    Auftrag {job_id} wurde zum Drucken freigegeben. + +

    diff --git a/templates/de/job-restart.tmpl b/templates/de/job-restart.tmpl new file mode 100644 index 0000000000..b4876978f3 --- /dev/null +++ b/templates/de/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Auftrag {job_id} neu starten

    + +

    Auftrag {job_id} wurde neu gestartet. + +

    diff --git a/templates/de/jobs-header.tmpl b/templates/de/jobs-header.tmpl new file mode 100644 index 0000000000..6565af41e1 --- /dev/null +++ b/templates/de/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?Keine Aufträge:Zeige {#job_id} von {total} {?which_jobs=?aktiven:{which_jobs=all?:beendeten}} {total=1?Auftrag:Aufträgen}}.

    diff --git a/templates/de/jobs.tmpl b/templates/de/jobs.tmpl new file mode 100644 index 0000000000..94a60b0aa7 --- /dev/null +++ b/templates/de/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }NameBenutzerGrößeSeitenStatusKontrolle
    {job_printer_name}-{job_id} {?job_name=?Unbekannt:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Unbekannt:{?job_media_sheets_completed}} {job_state=3?unerledigt seit
    {time_at_creation}:{job_state=4?angehalten seit
    {time_at_creation}: +{job_state=5?verarbeitet seit
    {time_at_processing}:{job_state=6?gestoppt: +{job_state=7?gelöscht am
    {time_at_completed}:{job_state=8?abgebrochen:beendet am
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/de/list-available-printers.tmpl b/templates/de/list-available-printers.tmpl new file mode 100644 index 0000000000..08a04522a8 --- /dev/null +++ b/templates/de/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Verfügbare Drucker

    + +{#device_uri=0?

    Keine Drucker gefunden.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/de/modify-class.tmpl b/templates/de/modify-class.tmpl new file mode 100644 index 0000000000..2e0bae80dc --- /dev/null +++ b/templates/de/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Klasse {printer_name} ändern

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Beschreibung:
    Ort:
    Mitglieder: + +
    + +
    +
    diff --git a/templates/de/modify-printer.tmpl b/templates/de/modify-printer.tmpl new file mode 100644 index 0000000000..d128471d73 --- /dev/null +++ b/templates/de/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    {printer_name} ändern

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Beschreibung:
    +(Für Menschen lesbare Beschreibung wie "HP LaserJet with Duplexer")
    Ort:
    +(Für Menschen lesbarer Ort wie "Lab 1")
    Verbindung:{device_uri}
    Freigabe: +Diesen Drucker freigeben
    + +
    +
    diff --git a/templates/de/norestart.tmpl b/templates/de/norestart.tmpl new file mode 100644 index 0000000000..fb22b154ec --- /dev/null +++ b/templates/de/norestart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Change Settings

    + +

    Der Server wurde nicht neu gestartet, da die Konfiguration +nicht geändert wurde...

    + +
    diff --git a/templates/de/option-boolean.tmpl b/templates/de/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/de/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/de/option-pickmany.tmpl b/templates/de/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/de/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/de/option-pickone.tmpl b/templates/de/option-pickone.tmpl new file mode 100644 index 0000000000..111397ce9d --- /dev/null +++ b/templates/de/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/de/option-trailer.tmpl b/templates/de/option-trailer.tmpl new file mode 100644 index 0000000000..87adedb443 --- /dev/null +++ b/templates/de/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + diff --git a/templates/de/pager.tmpl b/templates/de/pager.tmpl new file mode 100644 index 0000000000..6bc63d673f --- /dev/null +++ b/templates/de/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/de/printer-accept.tmpl b/templates/de/printer-accept.tmpl new file mode 100644 index 0000000000..25045fa03a --- /dev/null +++ b/templates/de/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Aufträge von {is_class?Klasse:Drucker} {printer_name} akzeptieren

    + +

    {is_class?Klasse:Drucker} {printer_name} +aktzeptiert jetzt Aufträge.

    + +
    diff --git a/templates/de/printer-added.tmpl b/templates/de/printer-added.tmpl new file mode 100644 index 0000000000..fe712beaa0 --- /dev/null +++ b/templates/de/printer-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Drucker hinzufügen

    + +

    Drucker {printer_name} wurde erfolgreich +hinzufügt. + +

    diff --git a/templates/de/printer-configured.tmpl b/templates/de/printer-configured.tmpl new file mode 100644 index 0000000000..60e27c2a53 --- /dev/null +++ b/templates/de/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Standardeinstellungen für {printer_name} festlegen

    + +

    Standardeinstellungen für {OP=set-class-options?Klasse :Drucker }{printer_name} +wurden erfolgreich gesetzt. + +

    diff --git a/templates/de/printer-confirm.tmpl b/templates/de/printer-confirm.tmpl new file mode 100644 index 0000000000..030f6524ac --- /dev/null +++ b/templates/de/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Drucker {printer_name} löschen

    + +

    Warnung: Sind Sie sicher, dass Sie den Drucker +{printer_name} löschen wollen?

    + +

    + +
    diff --git a/templates/de/printer-default.tmpl b/templates/de/printer-default.tmpl new file mode 100644 index 0000000000..ac2221f625 --- /dev/null +++ b/templates/de/printer-default.tmpl @@ -0,0 +1,13 @@ +
    + +

    {is_class?Klasse:Drucker} {printer_name} als Standard festlegen

    + +

    {is_class?Klasse:Drucker} {printer_name} +wurde zum Standarddrucker für diesen Server gemacht.

    + +
    Notiz: Die Einstellungen des Standarddruckers +welche von Benutzern mittels dem lpoptions Befehl gesetzt wurden, +überschreiben diese Einstellung.
    + +
    diff --git a/templates/de/printer-deleted.tmpl b/templates/de/printer-deleted.tmpl new file mode 100644 index 0000000000..6046113039 --- /dev/null +++ b/templates/de/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Drucker {printer_name} löschen

    + +

    Drucker {printer_name} wurde erfolgreich gelöscht. + +

    diff --git a/templates/de/printer-jobs-header.tmpl b/templates/de/printer-jobs-header.tmpl new file mode 100644 index 0000000000..4f3de9340f --- /dev/null +++ b/templates/de/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Aufträge

    +
    diff --git a/templates/de/printer-modified.tmpl b/templates/de/printer-modified.tmpl new file mode 100644 index 0000000000..b6e10bd4ea --- /dev/null +++ b/templates/de/printer-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Drucker {printer_name} ändern

    + +

    Drucker {printer_name} wurde +erfolgreich geändert. + +

    diff --git a/templates/de/printer-purge.tmpl b/templates/de/printer-purge.tmpl new file mode 100644 index 0000000000..1ff63ac0f7 --- /dev/null +++ b/templates/de/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    Aufträge für {is_class?die Klasse:den Drucker} {printer_name} verwerfen

    + +

    Aufträge für {is_class?die Klasse:den Drucker} {printer_name} +wurden verworfen.

    + +
    diff --git a/templates/de/printer-reject.tmpl b/templates/de/printer-reject.tmpl new file mode 100644 index 0000000000..1a5de730f2 --- /dev/null +++ b/templates/de/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Aufträge für {is_class?die Klasse:den Drucker} {printer_name} ablehnen

    + +

    {is_class?Die Klasse:Der Drucker} {printer_name} +akzeptiert keine weiteren Aufträge.

    + +
    diff --git a/templates/de/printer-start.tmpl b/templates/de/printer-start.tmpl new file mode 100644 index 0000000000..7a78568e67 --- /dev/null +++ b/templates/de/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    {is_class?Die Klasse:Den Drucker} {printer_name} fortfahren

    + +

    {is_class?Die Klassen:Der Drucker} {printer_name} +wird fortgesetzt.

    + +
    diff --git a/templates/de/printer-stop.tmpl b/templates/de/printer-stop.tmpl new file mode 100644 index 0000000000..b304bd9291 --- /dev/null +++ b/templates/de/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    {is_class?Die Klasse:Den Drucker} {printer_name} anhalten

    + +

    {is_class?Die Klasse:Der Drucker} {printer_name} +wurde angehalten.

    + +
    diff --git a/templates/de/printer.tmpl b/templates/de/printer.tmpl new file mode 100644 index 0000000000..ffc58e9194 --- /dev/null +++ b/templates/de/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?Frei:{printer_state=4?Beschäftigt:Angehalten}}, +{printer_is_accepting_jobs=0?Aufträge werden ablehnt:Aufträge werden akzeptiert}, +{server_is_sharing_printers=0?Nicht:{printer_is_shared=0?Nicht:}} freigegeben{default_name={printer_name}?, Standarddrucker:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Beschreibung:{printer_info}
    Ort:{printer_location}
    Treiber:{printer_make_and_model} ({color_supported=1?color:grayscale}{sides_supported?, 2-sided printing:})
    +
    Verbindung:{device_uri}
    Einstellungen:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/de/printers-header.tmpl b/templates/de/printers-header.tmpl new file mode 100644 index 0000000000..d07f783f95 --- /dev/null +++ b/templates/de/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Keine Drucker:Zeige {#printer_name} von {total} Drucker}.

    diff --git a/templates/de/printers.tmpl b/templates/de/printers.tmpl new file mode 100644 index 0000000000..2180a08183 --- /dev/null +++ b/templates/de/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Queue Name : Queue Name }BeschreibungOrtMarke und ModellStatus
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Frei:{printer_state=4?Beschäftigt:Angehalten}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/de/restart.tmpl b/templates/de/restart.tmpl new file mode 100644 index 0000000000..245300f9c8 --- /dev/null +++ b/templates/de/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Einstellungen ändern

    + +

    Bitte warten Sie während der Server neu startet...

    + +
    diff --git a/templates/de/samba-export.tmpl b/templates/de/samba-export.tmpl new file mode 100644 index 0000000000..ab2b0c60cb --- /dev/null +++ b/templates/de/samba-export.tmpl @@ -0,0 +1,55 @@ + + +
    + + + +

    Drucker für Samba freigeben

    + +{error?

    Kann Drucker nicht für Samba freigeben\:

    +
    {error}
    +

    Consult the Fehlerprotokoll Datei um mehr Informationen zu erhalten.

    : +

    Diese Seite erlaubt es Ihnen Drucker für Samba bereitzustellen +damit auf diese mittels Windows Clients über die Desktopsymbole +Netzwerk Nachbarn oder Netzwerkumgebung +zugegriffen werden kann. Sie müssen zuerst einen +Windows PostScript Druckerteiber installieren wie diese in der Hilfe für cupsaddsmb(8) beschrieben ist.

    } + + + + + + + + + + + + + + + + + + +
    Drucker: +
    + Alle Drucker freigeben +
    Samba Benutzername: (benötigt)
    Samba Passwort: (benötigt)
    + +
    diff --git a/templates/de/samba-exported.tmpl b/templates/de/samba-exported.tmpl new file mode 100644 index 0000000000..cf5db88945 --- /dev/null +++ b/templates/de/samba-exported.tmpl @@ -0,0 +1 @@ +

    Drucker wurden erfolgreich für Samba freigegeben.

    diff --git a/templates/de/search.tmpl b/templates/de/search.tmpl new file mode 100644 index 0000000000..a462ae0b08 --- /dev/null +++ b/templates/de/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Suche in +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?Klassen:{SECTION=jobs?Aufträgen:Drucker}}}: +

    + +
    diff --git a/templates/de/set-printer-options-header.tmpl b/templates/de/set-printer-options-header.tmpl new file mode 100644 index 0000000000..75f9f4ff2c --- /dev/null +++ b/templates/de/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Standardeinstellungen für {printer_name} festlegen

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/de/set-printer-options-trailer.tmpl b/templates/de/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/de/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/de/subscription-added.tmpl b/templates/de/subscription-added.tmpl new file mode 100644 index 0000000000..fe4f1cd42b --- /dev/null +++ b/templates/de/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subskription {subscription_name} wurde erfolgreich hinzugefügt.

    + +
    diff --git a/templates/de/subscription-canceled.tmpl b/templates/de/subscription-canceled.tmpl new file mode 100644 index 0000000000..56f7a977e5 --- /dev/null +++ b/templates/de/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subskription #{notify_subscription_id} wurde gekündigt.

    + +
    diff --git a/templates/de/test-page.tmpl b/templates/de/test-page.tmpl new file mode 100644 index 0000000000..82ce971662 --- /dev/null +++ b/templates/de/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Print Test Page On {printer_name}

    + +

    Testseite gesendet; Auftrags ID ist +{printer_name}-{job_id}.

    + +
    diff --git a/templates/de/trailer.tmpl b/templates/de/trailer.tmpl new file mode 100644 index 0000000000..74f62ad7e4 --- /dev/null +++ b/templates/de/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS und das CUPS Logo sind +eingetragene Warenzeichen der Apple Inc. CUPS +ist urheberrechtlich geschützt 2007-2011 von Apple Inc, alle Rechte vorbehalten. + + + diff --git a/templates/de/users.tmpl b/templates/de/users.tmpl new file mode 100644 index 0000000000..0704e87540 --- /dev/null +++ b/templates/de/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Erlaubte Benutzer für {printer_name}

    + + + + + + + + + + +
    Benutzer: + +
    +Erlaube diesen Benutzern zu drucken +Verweigere diesen Benutzern zu drucken +
    + +
    + +
    +
    diff --git a/templates/edit-config.tmpl b/templates/edit-config.tmpl new file mode 100644 index 0000000000..8947382b19 --- /dev/null +++ b/templates/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Edit Configuration File

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/error-op.tmpl b/templates/error-op.tmpl new file mode 100644 index 0000000000..feaed0f904 --- /dev/null +++ b/templates/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Error

    + +

    Error:

    + +
    Unknown operation "{op}"!
    + +
    diff --git a/templates/error.tmpl b/templates/error.tmpl new file mode 100644 index 0000000000..ff30a4c6c3 --- /dev/null +++ b/templates/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Error

    + +

    {?message?{message}:Error:}

    + +
    {error}
    + +
    diff --git a/templates/es/add-class.tmpl b/templates/es/add-class.tmpl new file mode 100755 index 0000000000..f7e79fa898 --- /dev/null +++ b/templates/es/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Añadir clase

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Nombre:
    +(Puede contener cualquier carácter imprimible excepto "/", "#", y espacio)
    Descripción:
    +(Descripción fácilmente leíble tal como "HP LaserJet de doble cara")
    Ubicación:
    +(Ubicación fácilmente leíble tal como "Lab 1")
    Miembros: + +
    + +
    +
    diff --git a/templates/es/add-printer.tmpl b/templates/es/add-printer.tmpl new file mode 100755 index 0000000000..eedc3db40f --- /dev/null +++ b/templates/es/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    Añadir impresora

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nombre:
    +(Puede contener cualquier carácter imprimible excepto "/", "#", y espacio)
    Descripción:
    +(Descripción fácilmente leíble tal como "HP LaserJet de doble cara")
    Ubicación:
    +(Ubicación fácilmente leíble tal como "Lab 1")
    Conexión:{device_uri}
    Compartición: +Compartir esta impresora
    + +
    +
    diff --git a/templates/es/add-rss-subscription.tmpl b/templates/es/add-rss-subscription.tmpl new file mode 100755 index 0000000000..d17c86eef1 --- /dev/null +++ b/templates/es/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Añadir subscripción RSS

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nombre:
    +(Puede contener cualquier carácter imprimible excepto espacio, "/", "?", y "#"))
    Cola:
    Eventos:Trabajo creado
    +Trabajo completado
    +Trabajo parado
    +Opciones de trabajo cambiadas
        Cola parada
    +Cola añadida
    +Cola modificada
    +Cola borrada
        Servidor iniciado
    +Servidor parado
    +Servidor reiniciado
    +Auditoría de seguridad del servidor
    Número máximo de eventos del canal:
    + +
    diff --git a/templates/es/admin.tmpl b/templates/es/admin.tmpl new file mode 100755 index 0000000000..53e5d34d8b --- /dev/null +++ b/templates/es/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Impresoras

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Clases

    + +

    +

    +
    +

    + +

    Trabajos

    + +

    +

    +

    + +
              + +

    Servidor

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Configuración del servidor\:

    + +

    Avanzada
    + + + Mostrar impresoras compartidas por otros sistemas
    +        Protocolos\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Compartir impresoras conectadas a este sistema
    +        Número máximo de clientes\: +
    +        Protocolos\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Permitir la impresión desde Internet
    +         Anunciar la interfaz web
    + Permitir administración remota
    +{have_gssapi? Usar autentificación Kerberos (FAQ)
    :} + Permitir a los usuarios cancelar cualquier trabajo (no sólo los suyos propios)
    + Preservar el historial de trabajos
    +        Número de trabajos\: +
    +         Preservar los archivos de impresión de trabajos
    + Guardar información de depuración para búsqueda de problemas
    +        Tamaño máximo del archivo de registro\: +

    + +:

    Configuración del servidor:

    + +

    Avanzada
    + + Mostrar impresoras compartidas por otros sistemas
    + Compartir impresoras conectadas a este sistema
    +         Permitir la impresión desde Internet
    + Permitir administración remota
    +{have_gssapi? Usar autentificación Kerberos (FAQ)
    :} + Permitir a los usuarios cancelar cualquier trabajo (no sólo los suyos propios)
    + Guardar información de depuración para búsqueda de problemas

    + +} +

    + +
    } + +
    + +
    + +

    Subscripciones RSS

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    NombreEventosNombre de la cola
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Todas las colas}
    :} diff --git a/templates/es/choose-device.tmpl b/templates/es/choose-device.tmpl new file mode 100755 index 0000000000..9f314fdf66 --- /dev/null +++ b/templates/es/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?Modificar {printer_name}:Añadir impresora}

    + +{CUPS_GET_DEVICES_DONE?:

    Buscando impresoras...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Conexión actual: +{current_device_uri}
    Impresoras locales: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Impresoras en red descubiertas: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Otras impresoras en red: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    diff --git a/templates/es/choose-make.tmpl b/templates/es/choose-make.tmpl new file mode 100755 index 0000000000..c846de4df5 --- /dev/null +++ b/templates/es/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Modificar {printer_name}:Añadir impresora}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nombre:{printer_name}
    Descripción:{printer_info}
    Ubicación:{printer_location}
    Conexión:{device_uri}
    Compartición: +{?printer_is_shared=?No:{?printer_is_shared=0?No:}} compartir esta impresora
    Marca: + +
     
    O proporcione un archivo PPD:
    + +
    +
    diff --git a/templates/es/choose-model.tmpl b/templates/es/choose-model.tmpl new file mode 100755 index 0000000000..497d4b1d1c --- /dev/null +++ b/templates/es/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?Modificar {printer_name}:Añadir impresora}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nombre:{printer_name}
    Descripción:{printer_info}
    Ubicación:{printer_location}
    Conexión:{device_uri}
    Compartición: +{?printer_is_shared=?No:{?printer_is_shared=0?No:}} compartir esta impresora
    Marca:{PPD_MAKE}
    Modelo: + +
    O proporcione un archivo PPD:
    + +
    +
    diff --git a/templates/es/choose-serial.tmpl b/templates/es/choose-serial.tmpl new file mode 100755 index 0000000000..e296fb95f4 --- /dev/null +++ b/templates/es/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Modificar {printer_name}:Añadir impresora}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Conexi&ocaute;n:{device_uri}
    Baudios:
    Paridad:
    Bits de datos:
    Control de flujo:
    + +
    +
    \ No newline at end of file diff --git a/templates/es/choose-uri.tmpl b/templates/es/choose-uri.tmpl new file mode 100755 index 0000000000..46ea17b132 --- /dev/null +++ b/templates/es/choose-uri.tmpl @@ -0,0 +1,44 @@ +
    + +

    {op=modify-printer?Modificar {printer_name}:Añadir impresora}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Conexión:
    Ejemplos: +
    +    http://nombre_ordenador:631/ipp/
    +    http://nombre_ordenador:631/ipp/puerto1
    +
    +    ipp://nombre_ordenador/ipp/
    +    ipp://nombre_ordenador/ipp/puerto1
    +
    +    lpd://nombre_ordenador/cola
    +
    +    socket://nombre_ordenador
    +    socket://nombre_ordenador:9100
    +
    + +

    Vea "Impresoras +en red" para escoger el URI adecuado a usar con su impresora.

    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/es/class-added.tmpl b/templates/es/class-added.tmpl new file mode 100755 index 0000000000..867c8d9287 --- /dev/null +++ b/templates/es/class-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Añadir clase

    + +

    Se ha añadido con éxito la clase {printer_name}. + +

    diff --git a/templates/es/class-confirm.tmpl b/templates/es/class-confirm.tmpl new file mode 100755 index 0000000000..a30ff726f1 --- /dev/null +++ b/templates/es/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Borrar clase {printer_name}

    + +

    Advertencia: ¿Está seguro de querer borrar la clase +{printer_name}?

    + +

    + +
    diff --git a/templates/es/class-deleted.tmpl b/templates/es/class-deleted.tmpl new file mode 100755 index 0000000000..ced78ad70e --- /dev/null +++ b/templates/es/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Borrar clase {printer_name}

    + +

    Se ha borrado con éxito la clase {printer_name}. + +

    \ No newline at end of file diff --git a/templates/es/class-jobs-header.tmpl b/templates/es/class-jobs-header.tmpl new file mode 100755 index 0000000000..f25951b7a5 --- /dev/null +++ b/templates/es/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Trabajos

    +
    diff --git a/templates/es/class-modified.tmpl b/templates/es/class-modified.tmpl new file mode 100755 index 0000000000..d5ae2a72cb --- /dev/null +++ b/templates/es/class-modified.tmpl @@ -0,0 +1,6 @@ +
    + +

    Modificar clase {printer_name}

    + +

    Se ha modificado con éxito la clase {printer_name}. +

    \ No newline at end of file diff --git a/templates/es/class.tmpl b/templates/es/class.tmpl new file mode 100755 index 0000000000..5eea4f195e --- /dev/null +++ b/templates/es/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?inactiva:{printer_state=4?procesando:en pausa}}, +{printer_is_accepting_jobs=0?rechazando trabajos:aceptando trabajos}, +{server_is_sharing_printers=0?no:{printer_is_shared=0?no:}} compartida{default_name={printer_name}?, predeterminada del servidor:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Descripción:{printer_info}
    Ubicación:{printer_location}
    Miembros:{?member_uris=?Ninguno:{member_uris}}
    Opciones predeterminadas:job-sheets={job_sheets_default} +media={media_default?{media_default}:desconocido} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/es/classes-header.tmpl b/templates/es/classes-header.tmpl new file mode 100755 index 0000000000..714ab89c4e --- /dev/null +++ b/templates/es/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?No hay clases:Mostrando {#printer_name} de {total} clase{total=1?:s}}.

    diff --git a/templates/es/classes.tmpl b/templates/es/classes.tmpl new file mode 100755 index 0000000000..6fde7bf621 --- /dev/null +++ b/templates/es/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nombre de la cola : Nombre de la cola }DescripciónUbicaciónMiembrosEstado
    {printer_name}{printer_info}{printer_location}{?member_uris=?Ninguna:{member_uris}}{printer_state=3?Inactiva:{printer_state=4?Procesando:En pausa}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/es/command.tmpl b/templates/es/command.tmpl new file mode 100755 index 0000000000..ba50560faa --- /dev/null +++ b/templates/es/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} en {printer_name}

    + +

    {job_state>5?:Indicador de ocupado }Trabajo de comando de impresora +{job_state=3?pendiente:{job_state=4?retenido: +{job_state=5?procesando:{job_state=6?parado: +{job_state=7?cancelado:{job_state=8?anulado:completado}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/es/edit-config.tmpl b/templates/es/edit-config.tmpl new file mode 100755 index 0000000000..a0c663436a --- /dev/null +++ b/templates/es/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Editar archivo de configuración

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/es/error-op.tmpl b/templates/es/error-op.tmpl new file mode 100755 index 0000000000..d584108e83 --- /dev/null +++ b/templates/es/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    Error en {?printer_name}: {?title}

    + +

    Error:

    + +
    Operación desconocida "{op}".
    + +
    diff --git a/templates/es/error.tmpl b/templates/es/error.tmpl new file mode 100755 index 0000000000..650bc32608 --- /dev/null +++ b/templates/es/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    Error en {?printer_name}: {?title}

    + +

    {?message?{message}:Error:}

    + +
    {error}
    + +
    diff --git a/templates/es/header.tmpl.in b/templates/es/header.tmpl.in new file mode 100755 index 0000000000..b6c63b4315 --- /dev/null +++ b/templates/es/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/es/option-conflict.tmpl b/templates/es/option-conflict.tmpl new file mode 100755 index 0000000000..adeb4363e6 --- /dev/null +++ b/templates/es/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Error: Las siguientes opciones están en conflicto:

    + + + +

    Cambie una o más de las opciones para resolver el problema.

    diff --git a/templates/es/option-header.tmpl b/templates/es/option-header.tmpl new file mode 100755 index 0000000000..464726a50b --- /dev/null +++ b/templates/es/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      Inicio    Administración    Clases    Ayuda en línea    Trabajos    Impresoras  
     
    diff --git a/templates/es/help-header.tmpl b/templates/es/help-header.tmpl new file mode 100755 index 0000000000..d513ca319f --- /dev/null +++ b/templates/es/help-header.tmpl @@ -0,0 +1,51 @@ +
    +
    +{TOPIC?:} + +

    Buscar en +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:todos los documentos}}: + +

    + +
    + + + + +{QUERY?

    Buscar resultados en {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:todos los documentos}}\:

    +{QTEXT?:} +:

    No hay coincidencias.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Ayuda en línea

    + +

    Esta es la interfaz de ayuda en línea de CUPS. Introduzca las palabras +a buscar aquí encima o haga clic en cualquiera de los enlaces de la +documentación para visualizar la información de ayuda en línea.

    + +

    Si es nuevo en CUPS, lea la página "Información general de CUPS". Los usuarios veteranos +deberían leer la página "Qué hay de nuevo en CUPS +1.4".

    + +

    La página de inicio de CUPS también +proporciona muchos recursos, incluyendo foros de discusión de usuarios, respuestas +a preguntas frecuentes, y un formulario para el envío de informes de errores y +peticiones de mejoras.

    } diff --git a/templates/es/help-printable.tmpl b/templates/es/help-printable.tmpl new file mode 100755 index 0000000000..2463c1630c --- /dev/null +++ b/templates/es/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/es/help-trailer.tmpl b/templates/es/help-trailer.tmpl new file mode 100755 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/es/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/es/job-cancel.tmpl b/templates/es/job-cancel.tmpl new file mode 100755 index 0000000000..6a414274cc --- /dev/null +++ b/templates/es/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Cancelar trabajo {job_id}

    + +

    Se ha cancelado el Trabajo {job_id}. + +

    diff --git a/templates/es/job-hold.tmpl b/templates/es/job-hold.tmpl new file mode 100755 index 0000000000..3136f9d8c4 --- /dev/null +++ b/templates/es/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Retener trabajo {job_id}

    + +

    Se ha retenido el Trabajo {job_id}. + +

    diff --git a/templates/es/job-move.tmpl b/templates/es/job-move.tmpl new file mode 100755 index 0000000000..e6aac39a59 --- /dev/null +++ b/templates/es/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Mover trabajo {job_id}:Mover todos los trabajos}

    + + + + + + + + + + +
    Nuevo destino: + +
    + +
    + +
    diff --git a/templates/es/job-moved.tmpl b/templates/es/job-moved.tmpl new file mode 100755 index 0000000000..8eb7a98165 --- /dev/null +++ b/templates/es/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Mover trabajo {job_id}:Mover todos los trabajos}

    + +

    Se {job_id?ha movido el Trabajo {job_id}:han movido todos los trabajos} a +{job_printer_name}.

    + +
    diff --git a/templates/es/job-release.tmpl b/templates/es/job-release.tmpl new file mode 100755 index 0000000000..d925e5fe55 --- /dev/null +++ b/templates/es/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Liberar trabajo {job_id}

    + +

    Se ha liberado el Trabajo {job_id}. + +

    diff --git a/templates/es/job-restart.tmpl b/templates/es/job-restart.tmpl new file mode 100755 index 0000000000..ee6c8e5983 --- /dev/null +++ b/templates/es/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Reimprimir trabajo {job_id}

    + +

    Se ha reiniciado el Trabajo {job_id}. + +

    diff --git a/templates/es/jobs-header.tmpl b/templates/es/jobs-header.tmpl new file mode 100755 index 0000000000..fe8b51fa80 --- /dev/null +++ b/templates/es/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?No hay trabajos:Mostrando {#job_id} de {total} trabajo{total=1?:s}{?which_jobs=? activo{total=1?:s}:{which_jobs=all?: completado{total=1?:s}}}}.

    diff --git a/templates/es/jobs.tmpl b/templates/es/jobs.tmpl new file mode 100755 index 0000000000..e1bc195b56 --- /dev/null +++ b/templates/es/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }NombreUsuarioTamañoPáginasEstadoControl
    {job_printer_name}-{job_id} {?job_name=?Desconocido:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Desconocido:{?job_media_sheets_completed}} {job_state=3?pendiente desde
    {time_at_creation}:{job_state=4?retenido desde
    {time_at_creation}: +{job_state=5?en proceso desde
    {time_at_processing}:{job_state=6?parado: +{job_state=7?cancelado el
    {time_at_completed}:{job_state=8?anulado:completado el
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/es/list-available-printers.tmpl b/templates/es/list-available-printers.tmpl new file mode 100755 index 0000000000..51e0eb9820 --- /dev/null +++ b/templates/es/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Impresoras disponibles

    + +{#device_uri=0?

    No se encuentran impresoras.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/es/modify-class.tmpl b/templates/es/modify-class.tmpl new file mode 100755 index 0000000000..a50b2bb727 --- /dev/null +++ b/templates/es/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Modificar clase {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Descripción:
    Ubicación:
    Miembros: + +
    + +
    +
    \ No newline at end of file diff --git a/templates/es/modify-printer.tmpl b/templates/es/modify-printer.tmpl new file mode 100755 index 0000000000..3c09da09e2 --- /dev/null +++ b/templates/es/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    Modificar {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Descripción:
    +(Descripción fácilmente leíble tal como "HP LaserJet de doble cara")
    Ubicación:
    +(Ubicación fácilmente leíble tal como "Lab 1")
    Conexión:{device_uri}
    Compartida: +Compartir esta impresora
    + +
    +
    diff --git a/templates/es/norestart.tmpl b/templates/es/norestart.tmpl new file mode 100755 index 0000000000..ac0f96baba --- /dev/null +++ b/templates/es/norestart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Cambiar especificaciones

    + +

    No se ha reiniciado el servidor debido a que no se han hecho +cambios en la configuración...

    + +
    diff --git a/templates/es/option-boolean.tmpl b/templates/es/option-boolean.tmpl new file mode 100755 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/es/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/es/option-pickmany.tmpl b/templates/es/option-pickmany.tmpl new file mode 100755 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/es/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/es/option-pickone.tmpl b/templates/es/option-pickone.tmpl new file mode 100755 index 0000000000..40fd124c4e --- /dev/null +++ b/templates/es/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/es/option-trailer.tmpl b/templates/es/option-trailer.tmpl new file mode 100755 index 0000000000..ff8f2b2396 --- /dev/null +++ b/templates/es/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + \ No newline at end of file diff --git a/templates/es/pager.tmpl b/templates/es/pager.tmpl new file mode 100755 index 0000000000..5f27c10605 --- /dev/null +++ b/templates/es/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/es/printer-accept.tmpl b/templates/es/printer-accept.tmpl new file mode 100755 index 0000000000..63fab1b4cd --- /dev/null +++ b/templates/es/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Aceptar trabajos de la {is_class?clase:impresora} {printer_name}

    + +

    La {is_class?clase:impresora} {printer_name} +ahora acepta trabajos.

    + +
    diff --git a/templates/es/printer-added.tmpl b/templates/es/printer-added.tmpl new file mode 100755 index 0000000000..88c565bcf8 --- /dev/null +++ b/templates/es/printer-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Añadir impresora

    + +

    Se ha añadido con éxito la impresora {printer_name}. + +

    diff --git a/templates/es/printer-configured.tmpl b/templates/es/printer-configured.tmpl new file mode 100755 index 0000000000..d382264f9b --- /dev/null +++ b/templates/es/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Cambiar opciones predeterminadas de {printer_name}

    + +

    Se han establecido con éxito las opciones predeterminadas de la +{OP=set-class-options?clase :impresora }{printer_name}. + +

    diff --git a/templates/es/printer-confirm.tmpl b/templates/es/printer-confirm.tmpl new file mode 100755 index 0000000000..1de104a638 --- /dev/null +++ b/templates/es/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Borrar impresora {printer_name}

    + +

    Advertencia: ¿Está seguro de querer borrar la impresora +{printer_name}?

    + +

    + +
    diff --git a/templates/es/printer-default.tmpl b/templates/es/printer-default.tmpl new file mode 100755 index 0000000000..68b61f2674 --- /dev/null +++ b/templates/es/printer-default.tmpl @@ -0,0 +1,13 @@ +
    + +

    Poner la {is_class?clase:impresora} {printer_name} como predeterminada

    + +

    Se ha puesto como predeterminada en el servidor la {is_class?clase:impresora} {printer_name}.

    + +
    Nota: cualquier opción de usuario +que haya sido activada por mediación del comando +lpoptions tiene mayor preferencia que este ajuste +predeterminado.
    + +
    diff --git a/templates/es/printer-deleted.tmpl b/templates/es/printer-deleted.tmpl new file mode 100755 index 0000000000..8bf7db61e8 --- /dev/null +++ b/templates/es/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Borrar impresora {printer_name}

    + +

    Se ha borrado con éxito la impresora {printer_name}. + +

    diff --git a/templates/es/printer-jobs-header.tmpl b/templates/es/printer-jobs-header.tmpl new file mode 100755 index 0000000000..f25951b7a5 --- /dev/null +++ b/templates/es/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Trabajos

    +
    diff --git a/templates/es/printer-modified.tmpl b/templates/es/printer-modified.tmpl new file mode 100755 index 0000000000..9035dce4f6 --- /dev/null +++ b/templates/es/printer-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    Modificar impresora {printer_name}

    + +

    Se ha modificado con éxito la impresora {printer_name}. + +

    \ No newline at end of file diff --git a/templates/es/printer-purge.tmpl b/templates/es/printer-purge.tmpl new file mode 100755 index 0000000000..b26bb46104 --- /dev/null +++ b/templates/es/printer-purge.tmpl @@ -0,0 +1,8 @@ +
    + +

    Purgar trabajos de la {is_class?clase:impresora} {printer_name}

    + +

    Se han purgado todos los trabajos de la {is_class?clase:impresora} {printer_name}.

    + +
    \ No newline at end of file diff --git a/templates/es/printer-reject.tmpl b/templates/es/printer-reject.tmpl new file mode 100755 index 0000000000..637e13e00f --- /dev/null +++ b/templates/es/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Rechazar trabajos de la {is_class?clase:impresora} {printer_name}

    + +

    La {is_class?clase:impresora} {printer_name} +ya no acepta trabajos.

    + +
    diff --git a/templates/es/printer-start.tmpl b/templates/es/printer-start.tmpl new file mode 100755 index 0000000000..117afcdb0c --- /dev/null +++ b/templates/es/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    Reanudar la {is_class?clase:impresora} {printer_name}

    + +

    La {is_class?clase:impresora} {printer_name} +ha sido reanudada.

    + +
    \ No newline at end of file diff --git a/templates/es/printer-stop.tmpl b/templates/es/printer-stop.tmpl new file mode 100755 index 0000000000..af374941e3 --- /dev/null +++ b/templates/es/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    Pausar la {is_class?clase:impresora} {printer_name}

    + +

    La {is_class?clase:impresora} {printer_name} +ha sido puesta en pausa.

    + +
    \ No newline at end of file diff --git a/templates/es/printer.tmpl b/templates/es/printer.tmpl new file mode 100755 index 0000000000..f7642ac0cd --- /dev/null +++ b/templates/es/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?inactiva:{printer_state=4?procesando:en pausa}}, +{printer_is_accepting_jobs=0?rechazando trabajos:aceptando trabajos}, +{server_is_sharing_printers=0?no:{printer_is_shared=0?no:}} compartida{default_name={printer_name}?, predeterminada del servidor:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Descripción:{printer_info}
    Ubicación:{printer_location}
    Controlador:{printer_make_and_model} ({color_supported=1?color:escala de grises}{sides_supported?, dúplex:})
    +
    Conexión:{device_uri}
    Opciones predeterminadas:job-sheets={job_sheets_default} +media={media_default?{media_default}:desconocido} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/es/printers-header.tmpl b/templates/es/printers-header.tmpl new file mode 100755 index 0000000000..7280687bcf --- /dev/null +++ b/templates/es/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?No hay impresoras:Mostrando {#printer_name} de {total} impresora{total=1?:s}}.

    diff --git a/templates/es/printers.tmpl b/templates/es/printers.tmpl new file mode 100755 index 0000000000..6b97fd9e6c --- /dev/null +++ b/templates/es/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nombre de la cola : Nombre de la cola }DescripciónUbicaciónMarca y modeloEstado
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Inactiva:{printer_state=4?Procesando:En pausa}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/es/restart.tmpl b/templates/es/restart.tmpl new file mode 100755 index 0000000000..607351d2b4 --- /dev/null +++ b/templates/es/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Cambiar especificaciones

    + +

    Por favor espere mientras se reinicia el servidor...

    + +
    diff --git a/templates/es/samba-export.tmpl b/templates/es/samba-export.tmpl new file mode 100755 index 0000000000..0036372ede --- /dev/null +++ b/templates/es/samba-export.tmpl @@ -0,0 +1,55 @@ + + +
    + + + +

    Exportar impresoras a Samba

    + +{error?

    No se han podido exportar las impresoras a Samba\:

    +
    {error}
    +

    Consulte el archivo error_log para más información.

    : +

    Esta página le permite exportar las impresoras a Samba para que +los clientes Windows puedan acceder a ellas por los iconos de su +escritorio Entorno de red o Sitios de red. Debe haber instalado +previamente el controlador de impresora PostScript de Windows +como se describe en la página del manual +cupsaddsmb(8).

    } + + + + + + + + + + + + + + + + + + +
    Impresoras: +
    + Exportar todas las impresoras +
    Nombre de usuario Samba: (necesario)
    Contraseña Samba: (necesaria)
    + +
    diff --git a/templates/es/samba-exported.tmpl b/templates/es/samba-exported.tmpl new file mode 100755 index 0000000000..a54925d3c6 --- /dev/null +++ b/templates/es/samba-exported.tmpl @@ -0,0 +1 @@ +

    Se han exportado las impresoras a samba con éxito.

    diff --git a/templates/es/search.tmpl b/templates/es/search.tmpl new file mode 100755 index 0000000000..3f430689c3 --- /dev/null +++ b/templates/es/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Buscar en +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?clases:{SECTION=jobs?trabajos:impresoras}}}: +

    + +
    diff --git a/templates/es/set-printer-options-header.tmpl b/templates/es/set-printer-options-header.tmpl new file mode 100755 index 0000000000..8a2740b3be --- /dev/null +++ b/templates/es/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Establecer opciones predeterminadas de {printer_name}

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/es/set-printer-options-trailer.tmpl b/templates/es/set-printer-options-trailer.tmpl new file mode 100755 index 0000000000..11adc70125 --- /dev/null +++ b/templates/es/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/es/subscription-added.tmpl b/templates/es/subscription-added.tmpl new file mode 100755 index 0000000000..87ce96ae00 --- /dev/null +++ b/templates/es/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    Se ha añadido con éxito la subscripción {subscription_name}.

    + +
    diff --git a/templates/es/subscription-canceled.tmpl b/templates/es/subscription-canceled.tmpl new file mode 100755 index 0000000000..d6ac1711bb --- /dev/null +++ b/templates/es/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    La subscripción #{notify_subscription_id} ha sido cancelada.

    + +
    diff --git a/templates/es/test-page.tmpl b/templates/es/test-page.tmpl new file mode 100755 index 0000000000..763dab5560 --- /dev/null +++ b/templates/es/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Imprimir página de prueba en {printer_name}

    + +

    Página de prueba enviada; el número del trabajo es el +{printer_name}-{job_id}.

    + +
    diff --git a/templates/es/trailer.tmpl b/templates/es/trailer.tmpl new file mode 100755 index 0000000000..3bd550b06c --- /dev/null +++ b/templates/es/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS y el logo de CUPS son marcas registradas de +Apple, Inc. Los derechos de copia de CUPS +2007-2011 son de Apple Inc. Todos los derechos reservados. + + + diff --git a/templates/es/users.tmpl b/templates/es/users.tmpl new file mode 100755 index 0000000000..a8a645e6f6 --- /dev/null +++ b/templates/es/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Usuarios permitidos para {printer_name}

    + + + + + + + + + + +
    Usuarios: + +
    +Permitir a estos usuarios imprimir +Evitar que estos usuarios impriman +
    + +
    + +
    +
    diff --git a/templates/eu/add-class.tmpl b/templates/eu/add-class.tmpl new file mode 100644 index 0000000000..bd7436ae27 --- /dev/null +++ b/templates/eu/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Gehitu klasea

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Izena:
    +(Inprimatu daitekeen edozein karaktere eduki dezake, "/", "#" eta zuriunea izan ezik)
    Deskripzioa:
    +(Gizakiek irakurtzeko deskripzioa, adibidez "HP LaserJet Duplexatzailearekin")
    Kokalekua:
    +(Gizakiek irakurtzeko kokalekua, adibidez "Lab 1")
    Kideak: + +
    + +
    +
    diff --git a/templates/eu/add-printer.tmpl b/templates/eu/add-printer.tmpl new file mode 100644 index 0000000000..312da1e6ea --- /dev/null +++ b/templates/eu/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    Gehitu inprimagailua

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Izena:
    +(Inprimatu daitekeen edozein karaktere eduki dezake, "/", "#" eta zuriunea izan ezik)
    Deskripzioa:
    +(izakiek irakurtzeko deskripzioa, adibidez "HP LaserJet Duplexatzailearekin")
    Kokalekua:
    +(izakiek irakurtzeko kokalekua, adibidez "Lab 1")
    Konexioa:{device_uri}
    Partekatzea: +Partekatu inprimagailu hau
    + +
    +
    diff --git a/templates/eu/add-rss-subscription.tmpl b/templates/eu/add-rss-subscription.tmpl new file mode 100644 index 0000000000..86025a2dce --- /dev/null +++ b/templates/eu/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Gehitu RSS harpidetza

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Izena:
    +(Inprimatu daitekeen edozein karaktere eduki dezake, "/", "#" eta zuriunea izan ezik)
    Ilara:
    Gertaerak:Lana sortuta
    +Lana burututa
    +Lana geldituta
    +Lanaren aukerak aldatuta
        Ilara geldituta
    +Ilara gehituta
    +Ilara aldatuta
    +Ilara ezabatuta
        Zerbitzaria abiarazita
    +Zerbitzaria geldituta
    +Zerbitzaria berrabiarazita
    +Zerbitzariko segurtasun auditoretza
    Gehienezko gertaerak iturrian:
    + +
    diff --git a/templates/eu/admin.tmpl b/templates/eu/admin.tmpl new file mode 100644 index 0000000000..8b5ecddcbe --- /dev/null +++ b/templates/eu/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Inprimagailuak

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Klaseak

    + +

    +

    +
    +

    + +

    Lanak

    + +

    +

    +

    + +
              + +

    Zerbitzaria

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Zerbitzariaren ezarpenak\:

    + +

    Aurreratua
    + + + Erakutsi beste sistemekin partekatutako inprimagailuak
    +        Protokoloak\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Partekatu sistema honekin konektatutako inprimagailuak
    +        Gehienezko bezeroak\: +
    +        Protokoloak\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Baimendu Internetetik inprimatzea
    +         Jakinarazi web interfazea
    + Baimendu urruneko administrazioa
    +{have_gssapi? Erabili Kerberos autentifikazioa (MEG)
    :} + Baimendu erabiltzaileek edozein lan bertan uztea (beraien lanetaz gain)
    + Mantendu lanen historia
    +        Lan kopurua\: +
    +         Mantendu lanen inprimatzeko fitxategiak
    + Gorde arazketako informazioa arazoak konpontzeko
    +        Egunkari fitxategiaren gehienezko tamaina\: +

    + +:

    Zerbitzariaren ezarpenak:

    + +

    Aurreratua
    + + Erakutsi beste sistemekin partekatutako inprimagailuak
    + Partekatu sistema honekin konektatutako inprimagailuak
    +         Baimendu Internetetik inprimatzea
    + Baimendu urruneko administrazioa
    +{have_gssapi? Erabili Kerberos autentifikazioa (MEG)
    :} + Baimendu erabiltzaileek edozein lan bertan uztea (beraien lanetaz gain)
    + Gorde arazketako informazioa arazoak konpontzeko

    + +} +

    + +
    } + +
    + +
    + +

    RSS harpidetzak

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    IzenaGertaerakIlararen izena
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Ilara guztiak}
    :} diff --git a/templates/eu/choose-device.tmpl b/templates/eu/choose-device.tmpl new file mode 100644 index 0000000000..36b7b86b7c --- /dev/null +++ b/templates/eu/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?Aldatu {printer_name}:Gehitu inprimagailua}

    + +{CUPS_GET_DEVICES_DONE?:

    Inprimagailuak bilatzen...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Uneko konexioa: +{current_device_uri}
    Inprimagailu lokalak: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Aurkitutako sareko inprimagailuak: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Beste sareko inprimagailuak: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    diff --git a/templates/eu/choose-make.tmpl b/templates/eu/choose-make.tmpl new file mode 100644 index 0000000000..9fb3897644 --- /dev/null +++ b/templates/eu/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Aldatu {printer_name}:Gehitu inprimagailua}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Izena:{printer_name}
    Deskripzioa:{printer_info}
    Kokalekua:{printer_location}
    Konexioa:{device_uri}
    Partekatzea: +{?printer_is_shared=?Ez:{?printer_is_shared=0?Ez:}} partekatu inprimagailu hau
    Marka: + +
     
    edo eman PPD fitxategia:
    + +
    +
    diff --git a/templates/eu/choose-model.tmpl b/templates/eu/choose-model.tmpl new file mode 100644 index 0000000000..5824932b7f --- /dev/null +++ b/templates/eu/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?Aldatu {printer_name}:Gehitu inprimagailua}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Izena:{printer_name}
    Deskripzioa:{printer_info}
    Kokalekua:{printer_location}
    Konexioa:{device_uri}
    Partekatzea: +{?printer_is_shared=?Ez:{?printer_is_shared=0?Ez:}} partekatu inprimagailu hau
    Marka:{PPD_MAKE}
    Modeloa: + +
    edo eman PPD fitxategia:
    + +
    +
    diff --git a/templates/eu/choose-serial.tmpl b/templates/eu/choose-serial.tmpl new file mode 100644 index 0000000000..a4dbba2e53 --- /dev/null +++ b/templates/eu/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Aldatu {printer_name}:Gehitu inprimagailua}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Konexioa:{device_uri}
    Baudio-emaria:
    Paritatea:
    Datuen bit-ak:
    Fluxu-kontrola:
    + +
    +
    diff --git a/templates/eu/choose-uri.tmpl b/templates/eu/choose-uri.tmpl new file mode 100644 index 0000000000..4b1fd677b1 --- /dev/null +++ b/templates/eu/choose-uri.tmpl @@ -0,0 +1,43 @@ +
    + +

    {op=modify-printer?Aldatu {printer_name}:Gehitu inprimagailua}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Konexioa:
    Adibideak: +
    +    http://ostalari_izena:631/ipp/
    +    http://ostalari_izena:631/ipp/ataka1
    +
    +    ipp://ostalari_izena/ipp/
    +    ipp://ostalari_izena/ipp/ataka1
    +
    +    lpd://ostalari_izena/ilara
    +
    +    socket://ostalari_izena
    +    socket://ostalari_izena:9100
    +
    + +

    Ikusi "Sareko inprimagailuak" URI zuzena erabiltzeko inprimagailuarekin.

    + +
    + +
    +
    diff --git a/templates/eu/class-added.tmpl b/templates/eu/class-added.tmpl new file mode 100644 index 0000000000..e0dfa891be --- /dev/null +++ b/templates/eu/class-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Gehitu klasea

    + +

    {printer_name} klasea ongi gehitu da. + +

    diff --git a/templates/eu/class-confirm.tmpl b/templates/eu/class-confirm.tmpl new file mode 100644 index 0000000000..f4a1a6f400 --- /dev/null +++ b/templates/eu/class-confirm.tmpl @@ -0,0 +1,9 @@ +
    + +

    Ezabatu {printer_name} klasea

    + +

    Abisua: ziur zaude {printer_name} klasea ezabatu nahi duzula?

    + +

    + +
    diff --git a/templates/eu/class-deleted.tmpl b/templates/eu/class-deleted.tmpl new file mode 100644 index 0000000000..5e39282a78 --- /dev/null +++ b/templates/eu/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ezabatu {printer_name} klasea

    + +

    {printer_name} klasea ongi ezabatu da. + +

    diff --git a/templates/eu/class-jobs-header.tmpl b/templates/eu/class-jobs-header.tmpl new file mode 100644 index 0000000000..89144751fc --- /dev/null +++ b/templates/eu/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Lanak

    +
    diff --git a/templates/eu/class-modified.tmpl b/templates/eu/class-modified.tmpl new file mode 100644 index 0000000000..9397bcc8a9 --- /dev/null +++ b/templates/eu/class-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    Aldatu {printer_name} klasea

    + +

    {printer_name} klasea ongi aldatu da. + +

    diff --git a/templates/eu/class.tmpl b/templates/eu/class.tmpl new file mode 100644 index 0000000000..b3c68ca843 --- /dev/null +++ b/templates/eu/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?Inaktiboa:{printer_state=4?Prozesatzen:Pausatuta}}, +{printer_is_accepting_jobs=0?Lanak ukatzen:Lanak onartzen}, +{default_name={printer_name}?, zerbitzariaren lehenetsiak:} partekatuta {server_is_sharing_printers=0?ez:{printer_is_shared=0?ez:}} daude)

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Deskripzioa:{printer_info}
    Kokalekua:{printer_location}
    Kideak:{?member_uris=?Bat ere ez:{member_uris}}
    Aukera lehenetsiak:job-sheets={job_sheets_default} +papera={media_default?{media_default}:ezezaguna} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/eu/classes-header.tmpl b/templates/eu/classes-header.tmpl new file mode 100644 index 0000000000..a8e24b4bc1 --- /dev/null +++ b/templates/eu/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Klaserik ez:{#printer_name}/{total} klase erakusten}.

    diff --git a/templates/eu/classes.tmpl b/templates/eu/classes.tmpl new file mode 100644 index 0000000000..4cab599266 --- /dev/null +++ b/templates/eu/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Ilararen izena : Ilararen izena }DeskripzioaKokalekuaKideakEgoera
    {printer_name}{printer_info}{printer_location}{?member_uris=?Bat ere ez:{member_uris}}{printer_state=3?Inaktibo:{printer_state=4?Prozesatzen:Pausatuta}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/eu/command.tmpl b/templates/eu/command.tmpl new file mode 100644 index 0000000000..0157b34bc2 --- /dev/null +++ b/templates/eu/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} {printer_name} inprimagailuan

    + +

    {job_state>5?:Lanpetuta egoeraren adierazlea }Inprimagailuaren lanaren komandoa +{job_state=3?zain:{job_state=4?eutsita: +{job_state=5?processing:{job_state=6?geldituta: +{job_state=7?bertan behera utzita:{job_state=8?abortatuta:burututa}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/eu/edit-config.tmpl b/templates/eu/edit-config.tmpl new file mode 100644 index 0000000000..4b2ba7bca4 --- /dev/null +++ b/templates/eu/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Editatu konfigurazioko fitxategia

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/eu/error-op.tmpl b/templates/eu/error-op.tmpl new file mode 100644 index 0000000000..605cc63f97 --- /dev/null +++ b/templates/eu/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?printer_name} errorea: {?title}

    + +

    Errorea:

    + +
    "{op}" eragiketa ezezaguna.
    + +
    diff --git a/templates/eu/error.tmpl b/templates/eu/error.tmpl new file mode 100644 index 0000000000..76dc6a0a8b --- /dev/null +++ b/templates/eu/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?printer_name} errorea: {?title}

    + +

    {?message?{message}:Errorea:}

    + +
    {error}
    + +
    diff --git a/templates/eu/header.tmpl.in b/templates/eu/header.tmpl.in new file mode 100644 index 0000000000..19a04e0489 --- /dev/null +++ b/templates/eu/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/eu/option-conflict.tmpl b/templates/eu/option-conflict.tmpl new file mode 100644 index 0000000000..617858ccbb --- /dev/null +++ b/templates/eu/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Errorea: honako aukerak gatazkan daude:

    + + + +

    Aldatu aukera bat edo gehiago gatazkak ebazteko.

    diff --git a/templates/eu/option-header.tmpl b/templates/eu/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/eu/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      Hasiera    Administrazioa    Klaseak    Lineako laguntza    Lanak    Inprimagailuak  
     
    diff --git a/templates/eu/help-header.tmpl b/templates/eu/help-header.tmpl new file mode 100644 index 0000000000..c87c767422 --- /dev/null +++ b/templates/eu/help-header.tmpl @@ -0,0 +1,49 @@ +
    +
    +{TOPIC?:} + +

    Bilatu +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:dokumentu guztietan}}: + +

    + +
    + + + + +{QUERY?

    Bilaketaren emaitzak {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:dokumentu guztietan}}\:

    +{QTEXT?:} +:

    Ez da bat datorrenik aurkitu.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Lineako laguntza

    + +

    Hau CUPSen lineako laguntzaren interfazea da. Sartu bilatzeko hitzak gainean +edo klik egin dokumentazioaren edozein esteketan lineako laguntzaren informazioa bistaratzeko.

    + +

    CUPSekin hasiberria bazara, irakurri "CUPSen gainbegiraketa" orrialdea. Erabiltzaile adituek + "CUPS 1.4 bertsioko berrikuntzak" orrialdea irakurri beharko lukete.

    + +

    CUPSen webgune nagusiak +hainbat baliabide eskaintzen ditu: erabiltzaileek eztabaidatzeko foruak, maiz egindako +galderei (MEG edo FAQ) erantzunak, eta akatsei buruz berri emateko edo eginbideak eskatzeko +inprimakia.

    } diff --git a/templates/eu/help-printable.tmpl b/templates/eu/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/eu/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/eu/help-trailer.tmpl b/templates/eu/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/eu/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/eu/job-cancel.tmpl b/templates/eu/job-cancel.tmpl new file mode 100644 index 0000000000..ec432ebb4c --- /dev/null +++ b/templates/eu/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Utzi {job_id} lana

    + +

    {job_id} lana bertan behera utzi da. + +

    diff --git a/templates/eu/job-hold.tmpl b/templates/eu/job-hold.tmpl new file mode 100644 index 0000000000..177ac160fc --- /dev/null +++ b/templates/eu/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Eutsi {job_id} lana

    + +

    {job_id} lana inprimatzetik eutsi da. + +

    diff --git a/templates/eu/job-move.tmpl b/templates/eu/job-move.tmpl new file mode 100644 index 0000000000..f337353b28 --- /dev/null +++ b/templates/eu/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Aldatu {job_id} lana lekuz:Aldatu lan guztiak lekuz}

    + + + + + + + + + + +
    Helburu berria: + +
    + +
    + +
    diff --git a/templates/eu/job-moved.tmpl b/templates/eu/job-moved.tmpl new file mode 100644 index 0000000000..47f31caf99 --- /dev/null +++ b/templates/eu/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Aldatu {job_id} lana lekuz:Aldatu lan guztiak lekuz}

    + +

    {job_id?{job_id} lana hona eraman da:Lan guztiak hona eraman dira}: +{job_printer_name}.

    + +
    diff --git a/templates/eu/job-release.tmpl b/templates/eu/job-release.tmpl new file mode 100644 index 0000000000..40f7f2b373 --- /dev/null +++ b/templates/eu/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Askatu {job_id} lana

    + +

    {job_id} lana inprimatzetik askatu egin da. + +

    diff --git a/templates/eu/job-restart.tmpl b/templates/eu/job-restart.tmpl new file mode 100644 index 0000000000..5868c50d25 --- /dev/null +++ b/templates/eu/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Inprimatu berriro {job_id} lana

    + +

    {job_id} lana berriro hasi da. + +

    diff --git a/templates/eu/jobs-header.tmpl b/templates/eu/jobs-header.tmpl new file mode 100644 index 0000000000..664f0ebf73 --- /dev/null +++ b/templates/eu/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?Lanik ez: {#job_id}/{total} lan {?which_jobs=?aktiboak:{which_jobs=all?:burututakoak}} erakusten}.

    diff --git a/templates/eu/jobs.tmpl b/templates/eu/jobs.tmpl new file mode 100644 index 0000000000..3071f6d40b --- /dev/null +++ b/templates/eu/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }IzenaErabiltzaileaTamainaOrrialdeakEgoeraKontrola
    {job_printer_name}-{job_id} {?job_name=?Ezezaguna:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Ezezaguna:{?job_media_sheets_completed}} {job_state=3?noiztik zain
    {time_at_creation}:{job_state=4?noiztik eutsita
    {time_at_creation}: +{job_state=5?noiztik prozesatzen
    {time_at_processing}:{job_state=6?geldituta: +{job_state=7?bertan behera utzita
    {time_at_completed}:{job_state=8?abortatuta:burututa
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/eu/list-available-printers.tmpl b/templates/eu/list-available-printers.tmpl new file mode 100644 index 0000000000..c8a397f3e6 --- /dev/null +++ b/templates/eu/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Inprimagailu erabilgarriak

    + +{#device_uri=0?

    Ez da inprimagailurik aurkitu.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/eu/modify-class.tmpl b/templates/eu/modify-class.tmpl new file mode 100644 index 0000000000..bce650341e --- /dev/null +++ b/templates/eu/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Aldatu {printer_name} klasea

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Deskripzioa:
    Kokalekua:
    Kideak: + +
    + +
    +
    diff --git a/templates/eu/modify-printer.tmpl b/templates/eu/modify-printer.tmpl new file mode 100644 index 0000000000..9b0417a549 --- /dev/null +++ b/templates/eu/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    Aldatu {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Deskripzioa:
    +(Gizakiek irakurtzeko deskripzioa, adibidez "HP LaserJet duplexatzailearekin")
    Kokalekua:
    +(Gizakiek irakurtzeko kokalekua, adibidez "Lab 1")
    Konexioa:{device_uri}
    Partekatzea: +Partekatu inprimagailu hau
    + +
    +
    diff --git a/templates/eu/norestart.tmpl b/templates/eu/norestart.tmpl new file mode 100644 index 0000000000..5ed12b6be9 --- /dev/null +++ b/templates/eu/norestart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Aldatu ezarpenak

    + +

    Zerbitzaria ez da berrabiarazi konfigurazioaren aldaketarik ez delako egin...

    + +
    diff --git a/templates/eu/option-boolean.tmpl b/templates/eu/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/eu/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/eu/option-pickmany.tmpl b/templates/eu/option-pickmany.tmpl new file mode 100644 index 0000000000..067075aec0 --- /dev/null +++ b/templates/eu/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/eu/option-pickone.tmpl b/templates/eu/option-pickone.tmpl new file mode 100644 index 0000000000..70866dfb51 --- /dev/null +++ b/templates/eu/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/eu/option-trailer.tmpl b/templates/eu/option-trailer.tmpl new file mode 100644 index 0000000000..d80296a5fe --- /dev/null +++ b/templates/eu/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + diff --git a/templates/eu/pager.tmpl b/templates/eu/pager.tmpl new file mode 100644 index 0000000000..901b0ff0e9 --- /dev/null +++ b/templates/eu/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/eu/printer-accept.tmpl b/templates/eu/printer-accept.tmpl new file mode 100644 index 0000000000..5bc9da6894 --- /dev/null +++ b/templates/eu/printer-accept.tmpl @@ -0,0 +1,8 @@ +
    + +

    Onartu lanak {printer_name} {is_class?klasean:inprimagailuan}

    + +

    {printer_name} {is_class?klasea:inprimagailua} +lanak onartzen ari da orain.

    + +
    diff --git a/templates/eu/printer-added.tmpl b/templates/eu/printer-added.tmpl new file mode 100644 index 0000000000..17e9c02bba --- /dev/null +++ b/templates/eu/printer-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Gehitu inprimagailua

    + +

    {printer_name} inprimagailua ongi gehitu da. + +

    diff --git a/templates/eu/printer-configured.tmpl b/templates/eu/printer-configured.tmpl new file mode 100644 index 0000000000..66e6f41d14 --- /dev/null +++ b/templates/eu/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Ezarri {printer_name}(r)en aukera lehenetsiak

    + +

    {OP=set-class-options?{printer_name} klasea:{printer_name} inprimagailua}ren +aukera lehenetsiak ongi ezarri dira. + +

    diff --git a/templates/eu/printer-confirm.tmpl b/templates/eu/printer-confirm.tmpl new file mode 100644 index 0000000000..d72d24010a --- /dev/null +++ b/templates/eu/printer-confirm.tmpl @@ -0,0 +1,9 @@ +
    + +

    Ezabatu {printer_name} inprimagailua

    + +

    Abisua: ziur zaude {printer_name} inprimagailua ezabatzea nahi duzula?

    + +

    + +
    diff --git a/templates/eu/printer-default.tmpl b/templates/eu/printer-default.tmpl new file mode 100644 index 0000000000..0834a3ab4a --- /dev/null +++ b/templates/eu/printer-default.tmpl @@ -0,0 +1,11 @@ +
    + +

    Ezarri {printer_name} {is_class?klasea:inprimagailua} lehenetsi gisa

    + +

    {printer_name} +{is_class?klasea:inprimagailua} zerbitzarian inprimagailu lehenetsi gisa ezarri da.

    + +
    Oharra: lpoptions komandoaren bidez ezarritako edozein +erabiltzailek ezarpen lehenetsi hau gainidatz dezake.
    + +
    diff --git a/templates/eu/printer-deleted.tmpl b/templates/eu/printer-deleted.tmpl new file mode 100644 index 0000000000..b2b72075f3 --- /dev/null +++ b/templates/eu/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ezabatu {printer_name} inprimagailua

    + +

    {printer_name} inprimagailua ongi ezabatu da. + +

    diff --git a/templates/eu/printer-jobs-header.tmpl b/templates/eu/printer-jobs-header.tmpl new file mode 100644 index 0000000000..89144751fc --- /dev/null +++ b/templates/eu/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Lanak

    +
    diff --git a/templates/eu/printer-modified.tmpl b/templates/eu/printer-modified.tmpl new file mode 100644 index 0000000000..80aa65be32 --- /dev/null +++ b/templates/eu/printer-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Aldatu {printer_name} inprimagailua

    + +

    {printer_name} inprimagailua +ongi aldatu da. + +

    diff --git a/templates/eu/printer-purge.tmpl b/templates/eu/printer-purge.tmpl new file mode 100644 index 0000000000..0977c8b04b --- /dev/null +++ b/templates/eu/printer-purge.tmpl @@ -0,0 +1,8 @@ +
    + +

    Kendu lanak {printer_name} {is_class?klasetik:inprimagailutik}

    + +

    {printer_name} +{is_class?klaseko:inprimagailuko} lan guztiak kendu dira.

    + +
    diff --git a/templates/eu/printer-reject.tmpl b/templates/eu/printer-reject.tmpl new file mode 100644 index 0000000000..178ef8b8e8 --- /dev/null +++ b/templates/eu/printer-reject.tmpl @@ -0,0 +1,8 @@ +
    + +

    Ukatu lanak {printer_name} {is_class?klasean:inprimagailuan}

    + +

    {printer_name} +{is_class?klaseak:inprimagailuak} ez du lan gehiago onartuko.

    + +
    diff --git a/templates/eu/printer-start.tmpl b/templates/eu/printer-start.tmpl new file mode 100644 index 0000000000..4403344e39 --- /dev/null +++ b/templates/eu/printer-start.tmpl @@ -0,0 +1,8 @@ +
    + +

    Jarraitu {printer_name} {is_class?klasea:inprimagailua}

    + +

    {printer_name} +{is_class?klaseak:inprimagailuak} jarraitu egin du.

    + +
    diff --git a/templates/eu/printer-stop.tmpl b/templates/eu/printer-stop.tmpl new file mode 100644 index 0000000000..2338e87bf8 --- /dev/null +++ b/templates/eu/printer-stop.tmpl @@ -0,0 +1,8 @@ +
    + +

    Pausatu {printer_name} {is_class?klasea:inprimagailua}

    + +

    {printer_name} +{is_class?klasea:inprimagailua} pausatu egin da.

    + +
    diff --git a/templates/eu/printer.tmpl b/templates/eu/printer.tmpl new file mode 100644 index 0000000000..ac984ebd04 --- /dev/null +++ b/templates/eu/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?inaktibo:{printer_state=4?prozesatzen:pausatuta}}, +{printer_is_accepting_jobs=0?lanak ukatzen:lanak onartzen}, +{default_name={printer_name}?, Zerbitzariaren lehenetsia:} partekatuta {server_is_sharing_printers=0?ez:{printer_is_shared=0?ez:}} dago)

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Deskripzioa:{printer_info}
    Kokalekua:{printer_location}
    Kontrolatzailea:{printer_make_and_model} ({color_supported=1?kolorea:gris-eskala}{sides_supported?, 2 aldeetan inprimatzea:})
    +
    Konexioa:{device_uri}
    Lehenetsiak:lanen orriak={job_sheets_default} +euskarria={media_default?{media_default}:ezezaguna} +{sides_default?aldeak={sides_default}:}
    + +
    diff --git a/templates/eu/printers-header.tmpl b/templates/eu/printers-header.tmpl new file mode 100644 index 0000000000..ba6d22fca7 --- /dev/null +++ b/templates/eu/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Inprimagailurik ez:{#printer_name}/{total} inprimagailu erakusten}.

    diff --git a/templates/eu/printers.tmpl b/templates/eu/printers.tmpl new file mode 100644 index 0000000000..541589102e --- /dev/null +++ b/templates/eu/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Ilararen izena : Ilararen izena }DeskripzioaKokalekuaMarka eta modeloaEgoera
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Inaktibo:{printer_state=4?Prozesatzen:Pausatuta}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/eu/restart.tmpl b/templates/eu/restart.tmpl new file mode 100644 index 0000000000..d599c228fe --- /dev/null +++ b/templates/eu/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Aldatu ezarpenak

    + +

    Itxaron zerbitzaria berrabiatzen den bitartean...

    + +
    diff --git a/templates/eu/samba-export.tmpl b/templates/eu/samba-export.tmpl new file mode 100644 index 0000000000..b6851f86b1 --- /dev/null +++ b/templates/eu/samba-export.tmpl @@ -0,0 +1,54 @@ + + +
    + + + +

    Esportatu inprimagailuak Samba-ra

    + +{error?

    Ezin dira inprimagailuak Samba-ra esportatu\:

    +
    {error}
    +

    Begiratu error_log fitxategia informazio gehiagorako.

    : +

    +Orrialde honek inprimagailuak Samba-ra esportatzea baimentzen du, horrela +Windows sistemako bezeroek inprimagailu horiek atzi daitezke haien +mahaigaineko Auzoko sareak edo Sareko lekuak ikonoen bidez. +Aurrenik Windows-eko inprimagailuen PostScript kontrolatzaileak instalatu +behar dira, cupsaddsmb(8) eskuliburuko orrialdean +azaltzen den bezala.

    } + + + + + + + + + + + + + + + + + +
    Inprimagailuak: +
    + Esportatu inprimagailu guztiak +
    Samba-ko erabiltzaile-izena: (beharrezkoa)
    Samba-ko pasahitza: (beharrezkoa)
    + +
    diff --git a/templates/eu/samba-exported.tmpl b/templates/eu/samba-exported.tmpl new file mode 100644 index 0000000000..3a8f6584be --- /dev/null +++ b/templates/eu/samba-exported.tmpl @@ -0,0 +1 @@ +

    Inprimagailuak ongi esportatu dira Samba-ra.

    diff --git a/templates/eu/search.tmpl b/templates/eu/search.tmpl new file mode 100644 index 0000000000..4211735604 --- /dev/null +++ b/templates/eu/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Bilatu +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?klasetan:{SECTION=jobs?lanetan:inprimgailuetan}}}: +

    + +
    diff --git a/templates/eu/set-printer-options-header.tmpl b/templates/eu/set-printer-options-header.tmpl new file mode 100644 index 0000000000..89b548b2f1 --- /dev/null +++ b/templates/eu/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Ezarri {printer_name}(r)en aukera lehenetsiak

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/eu/set-printer-options-trailer.tmpl b/templates/eu/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/eu/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/eu/subscription-added.tmpl b/templates/eu/subscription-added.tmpl new file mode 100644 index 0000000000..43ee5fcbd7 --- /dev/null +++ b/templates/eu/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    {subscription_name} harpidetza ongi landu da.

    + +
    diff --git a/templates/eu/subscription-canceled.tmpl b/templates/eu/subscription-canceled.tmpl new file mode 100644 index 0000000000..71b0dbd0db --- /dev/null +++ b/templates/eu/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    {notify_subscription_id}. harpidetza bertan behera utzi da.

    + +
    diff --git a/templates/eu/test-page.tmpl b/templates/eu/test-page.tmpl new file mode 100644 index 0000000000..bf5c77a69c --- /dev/null +++ b/templates/eu/test-page.tmpl @@ -0,0 +1,7 @@ +
    + +

    Inprimatu probako orrialdea hemen: {printer_name}

    + +

    Probako orrialdea bidalita; lanaren IDa {printer_name}-{job_id} da.

    + +
    diff --git a/templates/eu/trailer.tmpl b/templates/eu/trailer.tmpl new file mode 100644 index 0000000000..92df005234 --- /dev/null +++ b/templates/eu/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS eta CUPSen logotipoa Apple Inc.en +marka errejistratuak dira. CUPSen copyright-a: 2007-2011 Apple +Inc. eskubide guztiak gordeta. + + + diff --git a/templates/eu/users.tmpl b/templates/eu/users.tmpl new file mode 100644 index 0000000000..ba0ee968b7 --- /dev/null +++ b/templates/eu/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    {printer_name}(e)n baimendutako erabiltzaile guztiak

    + + + + + + + + + + +
    Erabiltzaileak: + +
    +Baimendu erabiltzaileak inprimatzea +Saihestu erabiltzaile hauek inprimatzetik +
    + +
    + +
    +
    diff --git a/templates/header.tmpl.in b/templates/header.tmpl.in new file mode 100644 index 0000000000..a383725c51 --- /dev/null +++ b/templates/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + +
    + + + + + + + + + + + + + +
      Home    Administration    Classes    Online Help    Jobs    Printers  
     
    diff --git a/templates/help-header.tmpl b/templates/help-header.tmpl new file mode 100644 index 0000000000..17afce7388 --- /dev/null +++ b/templates/help-header.tmpl @@ -0,0 +1,51 @@ +
    +
    +{TOPIC?:} + +

    Search in +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:All Documents}}: + +

    + +
    + + + + +{QUERY?

    Search Results in {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:All Documents}}\:

    +{QTEXT?:} +:

    No matches found.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Online Help

    + +

    This is the CUPS online help interface. Enter search words +above or click on any of the documentation links to display +online help information.

    + +

    If you are new to CUPS, read the "Overview of CUPS" page. Veteran users +should read the "What's New in CUPS +1.4" page.

    + +

    The CUPS home page also +provides many resources including user discussion forums, answers +to frequently-asked questions, and a form for submitting bug +reports and feature requests.

    } diff --git a/templates/help-printable.tmpl b/templates/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/help-trailer.tmpl b/templates/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/id/add-class.tmpl b/templates/id/add-class.tmpl new file mode 100644 index 0000000000..55f90ad2ea --- /dev/null +++ b/templates/id/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Tambah Kelas

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Nama:
    +(Karakter apa saja yang dapat dicetak, kecuali "/", "#", dan spasi)
    Deskripsi:
    +(Deskripsi yang mudah dibaca, seperti "HP LaserJet dengan Duplexer")
    Lokasi:
    +(Lokasi yang mudah dibaca, seperti "Lab 1")
    Anggota: + +
    + +
    +
    diff --git a/templates/id/add-printer.tmpl b/templates/id/add-printer.tmpl new file mode 100644 index 0000000000..5c7c7ccdd9 --- /dev/null +++ b/templates/id/add-printer.tmpl @@ -0,0 +1,43 @@ +
    + +

    Add Printer

    + +
    + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nama:
    +(Karakter apa saja yang dapat dicetak, kecuali "/", "#", dan spasi)
    Deskripsi:
    +(Deskripsi yang mudah dibaca, seperti "HP LaserJet dengan Duplexer")
    Location:
    +(Lokasi yang mudah dibaca, seperti "Lab 1")
    Koneksi:{device_uri}
    Berbagi: +Berbagi Pencetak Ini
    + +
    +
    diff --git a/templates/id/add-rss-subscription.tmpl b/templates/id/add-rss-subscription.tmpl new file mode 100644 index 0000000000..bf8f9644b8 --- /dev/null +++ b/templates/id/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Tambah Subskripsi RSS

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nama:
    +(Karakter apa saja yang dapat dicetak, kecuali "/", "#", dan spasi)
    Antrian:
    Kejadian:Tugas Dibuat
    +Tugas Selesai
    +Tugas Berhenti
    +Opsi Tugas Berubah
        Antrian Berhenti
    +Antrian Ditambah
    +Antrian Berubah
    +Antrian Dihapus
        Server Dimulai
    +Server Berhenti
    +Server Dijalankan Ulang
    +Audit Keamanan Server
    Maksimal Kejadian dalam Berita:
    + +
    diff --git a/templates/id/admin.tmpl b/templates/id/admin.tmpl new file mode 100644 index 0000000000..9106d6518a --- /dev/null +++ b/templates/id/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Pencetak

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Kelas

    + +

    +

    +
    +

    + +

    Tugas

    + +

    +

    +

    + +
              + +

    Server

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Pengaturan Server\:

    + +

    Lanjutan
    + + + Lihat pencetak yang dibagikan oleh sistem lain
    +        Protokol\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Bagikan pencetak yang terhubung ke sistem ini
    +        Klien maks.\: +
    +        Protokol\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Perbolehkan mencetak dari Internet
    +         Advertise web interface
    + Perbolehkan administrasi dari jarak jauh
    +{have_gssapi? Gunakan otentikasi Kerberos (FAQ)
    :} + Perbolehkan pengguna biasa untuk membatalkan semua tugas (termasuk tugas orang lain)
    + Catat histori tugas
    +        Banyaknya tugas\: +
    +         Catat berkas tugas cetak
    + Simpan informasi kesalahan untuk mencari dan memecahkan masalah
    +        Ukuran maks. berkas log\: +

    + +:

    Pengaturan Server:

    + +

    Lanjutan
    + + Lihat pencetak yang dibagikan oleh sistem lain
    + Bagikan pencetak yang terhubung ke sistem ini
    +         Perbolehkan mencetak dari Internet
    + Perbolehkan administrasi dari jarak jauh
    +{have_gssapi? Gunakan otentikasi Kerberos (FAQ)
    :} + Perbolehkan pengguna biasa untuk membatalkan semua tugas (termasuk tugas orang lain)
    + Save debugging information for troubleshooting

    + +} +

    + +
    } + +
    + +
    + +

    Subskripsi RSS

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    NamaKejadianNama Antrian
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Semua Antrian}
    :} diff --git a/templates/id/choose-device.tmpl b/templates/id/choose-device.tmpl new file mode 100644 index 0000000000..8f812a5e41 --- /dev/null +++ b/templates/id/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?Ubah {printer_name}:Tambah Pencetak}

    + +{CUPS_GET_DEVICES_DONE?:

    Mencari pencetak...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Koneksi yang Ada: +{current_device_uri}
    Pencetak Lokal: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Pencetak Jaringan yang Ditemukan: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Pencetak Jaringan Lainnya: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    diff --git a/templates/id/choose-make.tmpl b/templates/id/choose-make.tmpl new file mode 100644 index 0000000000..d04338fcc6 --- /dev/null +++ b/templates/id/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Ubah {printer_name}:Tambah Pencetak}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nama:{printer_name}
    Deskripsi:{printer_info}
    Lokasi:{printer_location}
    Koneksi:{device_uri}
    Berbagi: +{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Share This Printer
    Buatan: + +
     
    Atau, Sediakan Berkas PPD:
    + +
    +
    diff --git a/templates/id/choose-model.tmpl b/templates/id/choose-model.tmpl new file mode 100644 index 0000000000..c4cfdb9d0e --- /dev/null +++ b/templates/id/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Tambah Pencetak}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nama:{printer_name}
    Deskripsi:{printer_info}
    Lokasi:{printer_location}
    Koneksi:{device_uri}
    Berbagi: +{?printer_is_shared=?Jangan:{?printer_is_shared=0?Jangan:}} Berbagi Pencetak Ini
    Pembuat:{PPD_MAKE}
    Model: + +
    Atau Sediakan Berkas PPD:
    + +
    +
    diff --git a/templates/id/choose-serial.tmpl b/templates/id/choose-serial.tmpl new file mode 100644 index 0000000000..19de16c4fd --- /dev/null +++ b/templates/id/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Tambah Pencetak}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Koneksi:{device_uri}
    Kecepatan Data:
    Paritas:
    Bit Data:
    Kendali Aliran Data:
    + +
    +
    diff --git a/templates/id/choose-uri.tmpl b/templates/id/choose-uri.tmpl new file mode 100644 index 0000000000..4391b9114d --- /dev/null +++ b/templates/id/choose-uri.tmpl @@ -0,0 +1,43 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Tambah Pencetak}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Koneksi:
    Contoh: +
    +    http://hostname:631/ipp/
    +    http://hostname:631/ipp/port1
    +
    +    ipp://hostname/ipp/
    +    ipp://hostname/ipp/port1
    +
    +    lpd://hostname/queue
    +
    +    socket://hostname
    +    socket://hostname:9100
    +
    + +

    Lihat "Pencetak Jaringan" untuk URI yang tepat bagi pencetak Anda.

    + +
    + +
    +
    diff --git a/templates/id/class-added.tmpl b/templates/id/class-added.tmpl new file mode 100644 index 0000000000..12c408f843 --- /dev/null +++ b/templates/id/class-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Tambah Kelas

    + +

    Kelas {printer_name} telah berhasil ditambahkan. + +

    diff --git a/templates/id/class-confirm.tmpl b/templates/id/class-confirm.tmpl new file mode 100644 index 0000000000..3805b91771 --- /dev/null +++ b/templates/id/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Hapus Kelas {printer_name}

    + +

    Peringatan: Anda yakin untuk menghapus kelas +{printer_name}?

    + +

    + +
    diff --git a/templates/id/class-deleted.tmpl b/templates/id/class-deleted.tmpl new file mode 100644 index 0000000000..30320cbe3e --- /dev/null +++ b/templates/id/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Hapus Kelas {printer_name}

    + +

    Kelas {printer_name} telah berhasil dihapus. + +

    diff --git a/templates/id/class-jobs-header.tmpl b/templates/id/class-jobs-header.tmpl new file mode 100644 index 0000000000..e6ca44714f --- /dev/null +++ b/templates/id/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Tugas

    +
    diff --git a/templates/id/class-modified.tmpl b/templates/id/class-modified.tmpl new file mode 100644 index 0000000000..d2fdded391 --- /dev/null +++ b/templates/id/class-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ubah Kelas {printer_name}

    + +

    Kelas {printer_name} telah berhasil diubah. + +

    diff --git a/templates/id/class.tmpl b/templates/id/class.tmpl new file mode 100644 index 0000000000..af2178736c --- /dev/null +++ b/templates/id/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?Idle:{printer_state=4?Memproses:Ditahan}}, +{printer_is_accepting_jobs=0?Menolak Tugas:Menerima Tugas}, +{server_is_sharing_printers=0?Jangan:{printer_is_shared=0?Jangan:}} Berbagi{default_name={printer_name}?, Server Baku:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Deskripsi:{printer_info}
    Lokasi:{printer_location}
    Anggota:{?member_uris=?None:{member_uris}}
    Baku:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/id/classes-header.tmpl b/templates/id/classes-header.tmpl new file mode 100644 index 0000000000..da891a3c77 --- /dev/null +++ b/templates/id/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Tidak ada kelas:Menampilkan {#printer_name} dari {total} kelas{total=1?:}}.

    diff --git a/templates/id/classes.tmpl b/templates/id/classes.tmpl new file mode 100644 index 0000000000..c8e9b5f285 --- /dev/null +++ b/templates/id/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nama Antrian : Nama Antrian }DeskripsiLokasiAnggotaStatus
    {printer_name}{printer_info}{printer_location}{?member_uris=?Nihil:{member_uris}}{printer_state=3?Idle:{printer_state=4?Memproses:Ditahan}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/id/command.tmpl b/templates/id/command.tmpl new file mode 100644 index 0000000000..b38d2c985b --- /dev/null +++ b/templates/id/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} Pada {printer_name}

    + +

    {job_state>5?:Indikator Kesibukan }Perintah tugas pencetak +{job_state=3?pending:{job_state=4?held: +{job_state=5?processing:{job_state=6?stopped: +{job_state=7?canceled:{job_state=8?aborted:completed}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/id/edit-config.tmpl b/templates/id/edit-config.tmpl new file mode 100644 index 0000000000..6701f84ac4 --- /dev/null +++ b/templates/id/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Sunting Berkas Konfigurasi

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/id/error-op.tmpl b/templates/id/error-op.tmpl new file mode 100644 index 0000000000..2611c5deed --- /dev/null +++ b/templates/id/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    Kesalahan {?title} {?printer_name}

    + +

    Kesalahan:

    + +
    Operasi tak dikenal "{op}"!
    + +
    diff --git a/templates/id/error.tmpl b/templates/id/error.tmpl new file mode 100644 index 0000000000..c74bd70967 --- /dev/null +++ b/templates/id/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    Kesalahan {?title} {?printer_name}

    + +

    {?message?{message}:Kesalahan:}

    + +
    {error}
    + +
    diff --git a/templates/id/header.tmpl.in b/templates/id/header.tmpl.in new file mode 100644 index 0000000000..b45d870cb0 --- /dev/null +++ b/templates/id/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/id/option-conflict.tmpl b/templates/id/option-conflict.tmpl new file mode 100644 index 0000000000..71e2bcca83 --- /dev/null +++ b/templates/id/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Kesalahan: Opsi berikut ini konflik:

    + + + +

    Silakan ubah satu atau lebih opsi yang ada untuk memperbaiki masalah ini.

    diff --git a/templates/id/option-header.tmpl b/templates/id/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/id/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      Home    Administrasi    Kelas    Bantuan Langsung    Tugas    Pencetak  
     
    diff --git a/templates/id/help-header.tmpl b/templates/id/help-header.tmpl new file mode 100644 index 0000000000..e28b527813 --- /dev/null +++ b/templates/id/help-header.tmpl @@ -0,0 +1,47 @@ +
    +
    +{TOPIC?:} + +

    Mencari di +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:Semua Dokumen}}: + +

    + +
    + + + + +{QUERY?

    Hasil Pencarian di {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:Semua Dokumen}}\:

    +{QTEXT?:} +:

    Tidak ada yang cocok.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Bantuan Langsung

    + +

    Ini adalah antarmuka bantuan langsung milik CUPS. Masukkan kata yang hendak dicari pada kotak +di atas atau klik salah satu taut dokumen untuk melihat informasi bantuan langsung tersebut.

    + +

    Apabila Anda adalah pengguna baru CUPS, bacalah halaman "Ikhtisar CUPS". Bagi yang sudah berpengalaman, dapat +membaca halaman "Apa yang Baru di CUPS +1.4".

    + +

    Laman CUPS juga menyediakan berbagai sumber termasuk forum, jawaban untuk pertanyaan-pertanyaan yang sering diajukan, serta formulir untuk mengirim laporan kode hama dan permintaan fitur baru.

    } diff --git a/templates/id/help-printable.tmpl b/templates/id/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/id/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/id/help-trailer.tmpl b/templates/id/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/id/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/id/job-cancel.tmpl b/templates/id/job-cancel.tmpl new file mode 100644 index 0000000000..d3d6047192 --- /dev/null +++ b/templates/id/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Batalkan Tugas {job_id}

    + +

    Tugas {job_id} telah dibatalkan. + +

    diff --git a/templates/id/job-hold.tmpl b/templates/id/job-hold.tmpl new file mode 100644 index 0000000000..ab2dd5937d --- /dev/null +++ b/templates/id/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Tahan Tugas {job_id}

    + +

    Tugas {job_id} telah ditahan untuk dicetak. + +

    diff --git a/templates/id/job-move.tmpl b/templates/id/job-move.tmpl new file mode 100644 index 0000000000..9ec881a04a --- /dev/null +++ b/templates/id/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Pindahkan Tugas {job_id}:Pindahkan Semua Tugas}

    + + + + + + + + + + +
    Tujuan Baru: + +
    + +
    + +
    diff --git a/templates/id/job-moved.tmpl b/templates/id/job-moved.tmpl new file mode 100644 index 0000000000..c52c312967 --- /dev/null +++ b/templates/id/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Pindahkan Tugas {job_id}:Pindahkan Semua Tugas}

    + +

    {job_id?Tugas {job_id}:Semua tugas} dipindahkan ke +{job_printer_name}.

    + +
    diff --git a/templates/id/job-release.tmpl b/templates/id/job-release.tmpl new file mode 100644 index 0000000000..a447ae19ba --- /dev/null +++ b/templates/id/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Lepaskan Tugas {job_id}

    + +

    Tugas {job_id} telah dilepas untuk dicetak. + +

    diff --git a/templates/id/job-restart.tmpl b/templates/id/job-restart.tmpl new file mode 100644 index 0000000000..c54601c87b --- /dev/null +++ b/templates/id/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Cetak Ulang Tugas {job_id}

    + +

    Tugas {job_id} telah dilaksanakan ulang. + +

    diff --git a/templates/id/jobs-header.tmpl b/templates/id/jobs-header.tmpl new file mode 100644 index 0000000000..3cba80c589 --- /dev/null +++ b/templates/id/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?Tidak ada tugas:Menampilkan {#job_id} dari {total} tugas {?which_jobs=?yang aktif:{which_jobs=all?:yang diselesaikan}} {total=1?:}}.

    diff --git a/templates/id/jobs.tmpl b/templates/id/jobs.tmpl new file mode 100644 index 0000000000..1cd13a0ec2 --- /dev/null +++ b/templates/id/jobs.tmpl @@ -0,0 +1,36 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }NamaPenggunaUkuranHalamanStatusKontrol
    {job_printer_name}-{job_id} {?job_name=?Tak Dikenal:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Tak Dikenal:{?job_media_sheets_completed}} {job_state=3?ditunda sejak
    {time_at_creation}:{job_state=4?ditahan sejak
    {time_at_creation}: +{job_state=5?diproses sejak
    {time_at_processing}:{job_state=6?dihentikan: +{job_state=7?dibatalkan pada
    {time_at_completed}:{job_state=8?dibatalkan:diselesaikan pada
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/id/list-available-printers.tmpl b/templates/id/list-available-printers.tmpl new file mode 100644 index 0000000000..f3ca39fd98 --- /dev/null +++ b/templates/id/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Pencetak yang Ada

    + +{#device_uri=0?

    Tidak ada pencetak.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/id/modify-class.tmpl b/templates/id/modify-class.tmpl new file mode 100644 index 0000000000..db2d65e26d --- /dev/null +++ b/templates/id/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Ubah Kelas {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Deskripsi:
    Lokasi:
    Anggota: + +
    + +
    +
    diff --git a/templates/id/modify-printer.tmpl b/templates/id/modify-printer.tmpl new file mode 100644 index 0000000000..9bdb0c4f14 --- /dev/null +++ b/templates/id/modify-printer.tmpl @@ -0,0 +1,38 @@ +
    + +

    Ubah {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Deskripsi:
    +(Deskripsi yang mudah dibaca, seperti "HP LaserJet dengan Pendupleks")
    Lokasi:
    +(Deskripsi yang mudah dibaca, seperti "Lab 1")
    Koneksi:{device_uri}
    Berbagi: +Berbagi Pencetak Ini
    + +
    +
    diff --git a/templates/id/norestart.tmpl b/templates/id/norestart.tmpl new file mode 100644 index 0000000000..f39d9f2591 --- /dev/null +++ b/templates/id/norestart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ubah Pengaturan

    + +

    Server tidak dijalankan ulang karena tidak ada perubahan yang terjadi...

    + +
    diff --git a/templates/id/option-boolean.tmpl b/templates/id/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/id/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/id/option-pickmany.tmpl b/templates/id/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/id/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/id/option-pickone.tmpl b/templates/id/option-pickone.tmpl new file mode 100644 index 0000000000..8ee71b3160 --- /dev/null +++ b/templates/id/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/id/option-trailer.tmpl b/templates/id/option-trailer.tmpl new file mode 100644 index 0000000000..a403a981ff --- /dev/null +++ b/templates/id/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + diff --git a/templates/id/pager.tmpl b/templates/id/pager.tmpl new file mode 100644 index 0000000000..00b6340c38 --- /dev/null +++ b/templates/id/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/id/printer-accept.tmpl b/templates/id/printer-accept.tmpl new file mode 100644 index 0000000000..bba229a819 --- /dev/null +++ b/templates/id/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Terima Tugas dari {is_class?Kelas:Pencetak} {printer_name}

    + +

    {is_class?Kelas:Pencetak} {printer_name} +kini menerima tugas.

    + +
    diff --git a/templates/id/printer-added.tmpl b/templates/id/printer-added.tmpl new file mode 100644 index 0000000000..636496a9a2 --- /dev/null +++ b/templates/id/printer-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Tambah Pencetak

    + +

    Pencetak {printer_name} telah berhasil ditambahkan. + +

    diff --git a/templates/id/printer-configured.tmpl b/templates/id/printer-configured.tmpl new file mode 100644 index 0000000000..c2c8179283 --- /dev/null +++ b/templates/id/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Atur Opsi Baku untuk {printer_name}

    + +

    Opsi baku {OP=set-class-options?kelas :pencetak }{printer_name} +telah berhasil ditetapkan. + +

    diff --git a/templates/id/printer-confirm.tmpl b/templates/id/printer-confirm.tmpl new file mode 100644 index 0000000000..e6d89d616b --- /dev/null +++ b/templates/id/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Hapus Pencetak {printer_name}

    + +

    Peringatan: Anda yakin untuk menghapus +{printer_name}?

    + +

    + +
    diff --git a/templates/id/printer-default.tmpl b/templates/id/printer-default.tmpl new file mode 100644 index 0000000000..2bbedae09f --- /dev/null +++ b/templates/id/printer-default.tmpl @@ -0,0 +1,11 @@ +
    + +

    Atur {is_class?Kelas:Pencetak} {printer_name} sebagai Baku

    + +

    {is_class?Kelas:Pencetak} {printer_name} +telah dijadikan pencetak utama pada server.

    + +
    Catatan: Semua pengguna yang diatur melalui perintah lpoptions akan ditimpa oleh pengaturan ini.
    + +
    diff --git a/templates/id/printer-deleted.tmpl b/templates/id/printer-deleted.tmpl new file mode 100644 index 0000000000..e4492ea24d --- /dev/null +++ b/templates/id/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Hapus Pencetak {printer_name}

    + +

    Pencetak {printer_name} telah berhasil dihapus. + +

    diff --git a/templates/id/printer-jobs-header.tmpl b/templates/id/printer-jobs-header.tmpl new file mode 100644 index 0000000000..e6ca44714f --- /dev/null +++ b/templates/id/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Tugas

    +
    diff --git a/templates/id/printer-modified.tmpl b/templates/id/printer-modified.tmpl new file mode 100644 index 0000000000..16a7ad349a --- /dev/null +++ b/templates/id/printer-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ubah Pencetak {printer_name}

    + +

    Pencetak {printer_name} telah berhasil diubah. + +

    diff --git a/templates/id/printer-purge.tmpl b/templates/id/printer-purge.tmpl new file mode 100644 index 0000000000..5dff3ef146 --- /dev/null +++ b/templates/id/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    Bersihkan Tugas untuk {is_class?Kelas:Pencetak} {printer_name}

    + +

    {is_class?Kelas:Pencetak} {printer_name} +telah dibersihkan dari semua tugas.

    + +
    diff --git a/templates/id/printer-reject.tmpl b/templates/id/printer-reject.tmpl new file mode 100644 index 0000000000..616dbf009c --- /dev/null +++ b/templates/id/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Tolak Tugas untuk {is_class?Kelas:Pencetak} {printer_name}

    + +

    {is_class?Kelas:Pencetak} {printer_name} +tidak lagi menerima tugas.

    + +
    diff --git a/templates/id/printer-start.tmpl b/templates/id/printer-start.tmpl new file mode 100644 index 0000000000..ca3d95a5fa --- /dev/null +++ b/templates/id/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    Menjalankan Ulang {is_class?Kelas:Pencetak} {printer_name}

    + +

    {is_class?Kelas:Pencetak} {printer_name} +telah dijalankan lagi.

    + +
    diff --git a/templates/id/printer-stop.tmpl b/templates/id/printer-stop.tmpl new file mode 100644 index 0000000000..ca022e0028 --- /dev/null +++ b/templates/id/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    Menghentikan {is_class?Kelas:Pencetak} {printer_name}

    + +

    {is_class?Kelas:Pencetak} {printer_name} +telah dihentikan.

    + +
    diff --git a/templates/id/printer.tmpl b/templates/id/printer.tmpl new file mode 100644 index 0000000000..4c56b67611 --- /dev/null +++ b/templates/id/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?Menganggur:{printer_state=4?Memproses:Berhenti}}, +{printer_is_accepting_jobs=0?Menolak Tugas:Menerima Tugas}, +{server_is_sharing_printers=0?Tidak:{printer_is_shared=0?Tidak:}} Berbagi{default_name={printer_name}?, Server Baku:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Deskripsi:{printer_info}
    Lokasi:{printer_location}
    Penggerak:{printer_make_and_model} ({color_supported=1?warna:skala abu-abu}{sides_supported?, cetak 2-sisi:})
    +
    Koneksi:{device_uri}
    Baku:job-sheets={job_sheets_default} +media={media_default?{media_default}:tak dikenal} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/id/printers-header.tmpl b/templates/id/printers-header.tmpl new file mode 100644 index 0000000000..b1a00fcd42 --- /dev/null +++ b/templates/id/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Tidak ada pencetak:Menampilkan {#printer_name} dari {total} pencetak{total=1?:}}.

    diff --git a/templates/id/printers.tmpl b/templates/id/printers.tmpl new file mode 100644 index 0000000000..3aa4d0da64 --- /dev/null +++ b/templates/id/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nama Antrian : Nama Antrian }DeskripsiLokasiPembuat dan ModelStatus
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Menganggur:{printer_state=4?Memproses:Berhenti}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/id/restart.tmpl b/templates/id/restart.tmpl new file mode 100644 index 0000000000..fde1b06bab --- /dev/null +++ b/templates/id/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Ubah Pengaturan

    + +

    Silakan tunggu selagi server dijalankan ulang...

    + +
    diff --git a/templates/id/samba-export.tmpl b/templates/id/samba-export.tmpl new file mode 100644 index 0000000000..4d9e17519d --- /dev/null +++ b/templates/id/samba-export.tmpl @@ -0,0 +1,55 @@ + + +
    + + + +

    Ekspor Pencetak ke Samba

    + +{error?

    Tak dapat mengekspor pencetak ke Samba\:

    +
    {error}
    +

    Rujuklah berkas error_log untuk informasi lebih lanjut.

    : +

    Di halaman ini, Anda dapat mengekspor pencetak untuk Samba, sehingga +klien Windows dapat mengakses pencetak-pencetak tersebut melalui ikon +Network Neighborhood atau Network Places yang ada +di desktop mereka. Namun, sebelumnya Anda harus memasang penggerak +pencetak PostScript Windows seperti yang dijelaskan pada halaman +manual cupsaddsmb(8).

    } + + + + + + + + + + + + + + + + + + +
    Pencetak: +
    + Ekspor Semua Pencetak +
    Nama Pengguna Samba: (diperlukan)
    Sandi Samba: (diperlukan)
    + +
    diff --git a/templates/id/samba-exported.tmpl b/templates/id/samba-exported.tmpl new file mode 100644 index 0000000000..8fa811100e --- /dev/null +++ b/templates/id/samba-exported.tmpl @@ -0,0 +1 @@ +

    Pencetak berhasil diekspor ke Samba.

    diff --git a/templates/id/search.tmpl b/templates/id/search.tmpl new file mode 100644 index 0000000000..9dc2e5d54c --- /dev/null +++ b/templates/id/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Cari di +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?Kelas:{SECTION=jobs?Tugas:Pencetak}}}: +

    + +
    diff --git a/templates/id/set-printer-options-header.tmpl b/templates/id/set-printer-options-header.tmpl new file mode 100644 index 0000000000..017e2c4757 --- /dev/null +++ b/templates/id/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Atur Opsi Baku untuk {printer_name}

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/id/set-printer-options-trailer.tmpl b/templates/id/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/id/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/id/subscription-added.tmpl b/templates/id/subscription-added.tmpl new file mode 100644 index 0000000000..70abc79f85 --- /dev/null +++ b/templates/id/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subskripsi {subscription_name} telah berhasil ditambahkan.

    + +
    diff --git a/templates/id/subscription-canceled.tmpl b/templates/id/subscription-canceled.tmpl new file mode 100644 index 0000000000..ba7b0e15e0 --- /dev/null +++ b/templates/id/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subskripsi #{notify_subscription_id} telah dibatalkan.

    + +
    diff --git a/templates/id/test-page.tmpl b/templates/id/test-page.tmpl new file mode 100644 index 0000000000..5b1492ea1b --- /dev/null +++ b/templates/id/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Cetak Halaman Uji pada {printer_name}

    + +

    Halaman uji telah dikirim; ID tugas adalah +{printer_name}-{job_id}.

    + +
    diff --git a/templates/id/trailer.tmpl b/templates/id/trailer.tmpl new file mode 100644 index 0000000000..eb53dddb94 --- /dev/null +++ b/templates/id/trailer.tmpl @@ -0,0 +1,8 @@ +
     
    CUPS dan logo CUPS adalah merek dagang dari +Apple Inc. Hak Cipta CUPS adalah 2007-2011 Apple +Inc. Semua hak terpelihara.
    + + diff --git a/templates/id/users.tmpl b/templates/id/users.tmpl new file mode 100644 index 0000000000..fe9107050e --- /dev/null +++ b/templates/id/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Pengguna yang Diperbolehkan Bagi {printer_name}

    + + + + + + + + + + +
    Pengguna: + +
    +Perbolehkan pengguna ini untuk mencetak +Larang pengguna ini untuk mencetak +
    + +
    + +
    +
    diff --git a/templates/it/add-class.tmpl b/templates/it/add-class.tmpl new file mode 100644 index 0000000000..cff0d45bc5 --- /dev/null +++ b/templates/it/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Aggiungi classe

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Nome:
    +(Può contenere qualsiasi carattere stampabile eccetto "/", "#", e spazio)
    Descrizione:
    +(Descrizione esplicativa del tipo "HP LaserJet con Duplexer")
    Posizione:
    +(Posizione esplicativa del tipo "Laboratorio 1")
    Membri: + +
    + +
    +
    diff --git a/templates/it/add-printer.tmpl b/templates/it/add-printer.tmpl new file mode 100644 index 0000000000..3bf0906fa5 --- /dev/null +++ b/templates/it/add-printer.tmpl @@ -0,0 +1,43 @@ +
    + +

    Aggiungi stampante

    + +
    + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nome:
    +(Può contenere qualsiasi carattere stampabile eccetto "/", "#", e spazio)
    Descrizione:
    +(Descrizione esplicativa del tipo "HP LaserJet con Duplexer")
    Posizione:
    +(Posizione esplicativa del tipo "Laboratorio 1")
    Connessione:{device_uri}
    Condivisione: +Condividi la stampante
    + +
    +
    diff --git a/templates/it/add-rss-subscription.tmpl b/templates/it/add-rss-subscription.tmpl new file mode 100644 index 0000000000..c85e45f0f0 --- /dev/null +++ b/templates/it/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Aggiungi iscrizione RSS

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nome:
    +(Può contenere qualsiasi carattere eccetto spazio, "/", "?", e "#")
    Coda:
    Eventi:Stampa creata
    +Stampa completata
    +Stampa fermata
    +Opzioni di stampa modificate
        Coda fermata
    +Coda aggiunta
    +Coda modificata
    +Coda eliminata
        Server avviato
    +Server fermato
    +Server riavviato
    +Controllo di sicurezza del server
    N. massimo di eventi nella fonte:
    + +
    diff --git a/templates/it/admin.tmpl b/templates/it/admin.tmpl new file mode 100644 index 0000000000..355c51fcc6 --- /dev/null +++ b/templates/it/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Stampanti

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Classi

    + +

    +

    +
    +

    + +

    Stampe

    + +

    +

    +

    + +
              + +

    Server

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Impostazioni del server\:

    + +

    Avanzate
    + + + Mostra stampanti condivise da altri sistemi
    +        Protocolli\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Condividi le stampanti connesse al sistema
    +        N. massimo di client\: +
    +        Protocolli\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Consenti stampa da Internet
    +         Pubblica l'interfaccia web
    + Consenti amministrazione remota
    +{have_gssapi? Usa autenticazione Kerberos (FAQ)
    :} + Consenti agli utenti di annullare ogni stampa (non solo le proprie)
    + Mantieni lo storico delle stampe
    +        Numero di stampe\: +
    +         Conserva i file di stampa
    + Salva informazioni di debug per la risoluzione di problemi
    +        Dim. massima file di registro\: +

    + +:

    Impostazioni server:

    + +

    Avanzate
    + + Mostra stampanti condivise da altri sistemi
    + Condividi stampanti connesse al sistema
    +         Consenti la stampa da Internet
    + Consenti amministrazione remota
    +{have_gssapi? Utilizza autenticazione Kerberos (FAQ)
    :} + Consenti agli utenti di annullare ogni stampa (non solo le proprie)
    + Salva le informazioni di debug per la risoluzione di problemi

    + +} +

    + +
    } + +
    + +
    + +

    Iscrizioni RSS

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    NomeEventiNome coda
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Tutte le code}
    :} diff --git a/templates/it/choose-device.tmpl b/templates/it/choose-device.tmpl new file mode 100644 index 0000000000..3420fdfe1a --- /dev/null +++ b/templates/it/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?Modifica {printer_name}:Aggiungi stampante}

    + +{CUPS_GET_DEVICES_DONE?:

    Ricerca stampanti...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Connessione attuale: +{current_device_uri}
    Stampanti locali: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Stampanti di rete rilevate: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Altre stampante di reti: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    diff --git a/templates/it/choose-make.tmpl b/templates/it/choose-make.tmpl new file mode 100644 index 0000000000..3bb4c78c44 --- /dev/null +++ b/templates/it/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Aggiungi stampante}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nome:{printer_name}
    Descrizione:{printer_info}
    Posizione:{printer_location}
    Connessione:{device_uri}
    Condivisione: +{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Condividi questa stampante
    Crea: + +
     
    Or Provide a PPD File:
    + +
    +
    diff --git a/templates/it/choose-model.tmpl b/templates/it/choose-model.tmpl new file mode 100644 index 0000000000..d7e9357699 --- /dev/null +++ b/templates/it/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Aggiungi stampante}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nome:{printer_name}
    Descrizione:{printer_info}
    Posizione:{printer_location}
    Connessione:{device_uri}
    Condivisione: +{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Condividi stampante
    Crea:{PPD_MAKE}
    Modello: + +
    O fornisci un file PPD:
    + +
    +
    diff --git a/templates/it/choose-serial.tmpl b/templates/it/choose-serial.tmpl new file mode 100644 index 0000000000..106393adb6 --- /dev/null +++ b/templates/it/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Modifica {printer_name}:Aggiungi stampante}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Connessione:{device_uri}
    Velocità:
    Parità:
    Data Bits:
    Flow Control:
    + +
    +
    diff --git a/templates/it/choose-uri.tmpl b/templates/it/choose-uri.tmpl new file mode 100644 index 0000000000..81b153a0a5 --- /dev/null +++ b/templates/it/choose-uri.tmpl @@ -0,0 +1,44 @@ +
    + +

    {op=modify-printer?Modifica {printer_name}:Aggiungi stampante}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Connection:
    Esempi: +
    +    http://hostname:631/ipp/
    +    http://hostname:631/ipp/port1
    +
    +    ipp://hostname/ipp/
    +    ipp://hostname/ipp/port1
    +
    +    lpd://hostname/queue
    +
    +    socket://hostname
    +    socket://hostname:9100
    +
    + +

    Vedere "Stampanti di +rete" per l'URI corretto da utilizzare la stampante.

    + +
    + +
    +
    diff --git a/templates/it/class-added.tmpl b/templates/it/class-added.tmpl new file mode 100644 index 0000000000..fcccaa3200 --- /dev/null +++ b/templates/it/class-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Aggiungi classe

    + +

    Class {printer_name} è stata aggiunta +correttamente. + +

    diff --git a/templates/it/class-confirm.tmpl b/templates/it/class-confirm.tmpl new file mode 100644 index 0000000000..4e99f45742 --- /dev/null +++ b/templates/it/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Elimina classe {printer_name}

    + +

    Warning: Sei sicuro di voler eliminare la classe +{printer_name}?

    + +

    + +
    diff --git a/templates/it/class-deleted.tmpl b/templates/it/class-deleted.tmpl new file mode 100644 index 0000000000..ce2365436f --- /dev/null +++ b/templates/it/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Elimina classe {printer_name}

    + +

    La classe {printer_name} è stata eliminata correttamente. + +

    diff --git a/templates/it/class-jobs-header.tmpl b/templates/it/class-jobs-header.tmpl new file mode 100644 index 0000000000..12a936ea92 --- /dev/null +++ b/templates/it/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Stampe

    +
    diff --git a/templates/it/class-modified.tmpl b/templates/it/class-modified.tmpl new file mode 100644 index 0000000000..04d4c8490f --- /dev/null +++ b/templates/it/class-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Modifica classe {printer_name}

    + +

    La classe {printer_name} è stata +modificata correttamente. + +

    diff --git a/templates/it/class.tmpl b/templates/it/class.tmpl new file mode 100644 index 0000000000..0089c93469 --- /dev/null +++ b/templates/it/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?Idle:{printer_state=4?Processing:Paused}}, +{printer_is_accepting_jobs=0?Rejecting Jobs:Accepting Jobs}, +{server_is_sharing_printers=0?Not:{printer_is_shared=0?Not:}} Shared{default_name={printer_name}?, Server Default:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Descrizione:{printer_info}
    Posizione:{printer_location}
    Membri:{?member_uris=?None:{member_uris}}
    Predefiniti:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/it/classes-header.tmpl b/templates/it/classes-header.tmpl new file mode 100644 index 0000000000..943537f894 --- /dev/null +++ b/templates/it/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Nessuna classe:Mostrat{total=1?a:e} {#printer_name} di {total} class{total=1?e:i}}.

    \ No newline at end of file diff --git a/templates/it/classes.tmpl b/templates/it/classes.tmpl new file mode 100644 index 0000000000..bfa5bdf27a --- /dev/null +++ b/templates/it/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nome coda : Nome coda }DescrizionePosizioneMembriStato
    {printer_name}{printer_info}{printer_location}{?member_uris=?None:{member_uris}}{printer_state=3?In attesa:{printer_state=4?Elaborazion in corso:Sospesa}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/it/command.tmpl b/templates/it/command.tmpl new file mode 100644 index 0000000000..80d44f6343 --- /dev/null +++ b/templates/it/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} su {printer_name}

    + +

    {job_state>5?:Indicatore di occupato }Printer command job +{job_state=3?pendente:{job_state=4?held: +{job_state=5?elaborazione in corso:{job_state=6?fermata: +{job_state=7?annullata:{job_state=8?aborted:completed}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/it/edit-config.tmpl b/templates/it/edit-config.tmpl new file mode 100644 index 0000000000..c8d8ea8a96 --- /dev/null +++ b/templates/it/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Modifica file di configurazione

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/it/error-op.tmpl b/templates/it/error-op.tmpl new file mode 100644 index 0000000000..c6cdfa80e7 --- /dev/null +++ b/templates/it/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Errore

    + +

    Errore:

    + +
    Operazione sconosciuta "{op}"!
    + +
    diff --git a/templates/it/error.tmpl b/templates/it/error.tmpl new file mode 100644 index 0000000000..b0e7a4b37f --- /dev/null +++ b/templates/it/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Errore

    + +

    {?message?{message}:Error:}

    + +
    {error}
    + +
    diff --git a/templates/it/help-header.tmpl b/templates/it/help-header.tmpl new file mode 100644 index 0000000000..39c39e5329 --- /dev/null +++ b/templates/it/help-header.tmpl @@ -0,0 +1,50 @@ +
    +
    +{TOPIC?:} + +

    Cerca in +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:Tutti i documenti}}: + +

    + +
    + + + + +{QUERY?

    Cerca risultati in {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:Tutti i documenti}}\:

    +{QTEXT?:} +:

    Nessuna corrispondenza trovata.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Guida in linea

    + +

    Questa è l'interfaccia di guida in linea di CUPS. Inserisci in alto i termini da ricercare +o fai clic su qualsiasi collegamento della documentazione per visualizzare +informazioni della guida in linea.

    + +

    Se sei nuovo di CUPS, leggi la pagina "Panoramica di CUPS". Gli utenti esperti +dovrebbero leggere la pagina "Cosa c'è di nuovo in CUPS +1.4".

    + +

    La pagina principale di CUPS fornisce +inoltre molte risorse tra le quali forum di discussione per gli utenti, risposte +alle domande frequenti, e un modulo per segnalare bug e richiede nuove funzionalità.

    } diff --git a/templates/it/help-printable.tmpl b/templates/it/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/it/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/it/help-trailer.tmpl b/templates/it/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/it/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/it/job-cancel.tmpl b/templates/it/job-cancel.tmpl new file mode 100644 index 0000000000..766881ea7c --- /dev/null +++ b/templates/it/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Annulla la stampa {job_id}

    + +

    La stampa {job_id} è stata annullata. + +

    diff --git a/templates/it/job-hold.tmpl b/templates/it/job-hold.tmpl new file mode 100644 index 0000000000..ac2d8199c3 --- /dev/null +++ b/templates/it/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Blocca la stampa {job_id}

    + +

    La stampa {job_id} è stata bloccata. + +

    diff --git a/templates/it/job-move.tmpl b/templates/it/job-move.tmpl new file mode 100644 index 0000000000..0a52ba2f23 --- /dev/null +++ b/templates/it/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Sposta la stampa {job_id}:Sposta tutte le stampe}

    + + + + + + + + + + +
    Nuova destinazione: + +
    + +
    + +
    diff --git a/templates/it/job-moved.tmpl b/templates/it/job-moved.tmpl new file mode 100644 index 0000000000..98be4fe7d6 --- /dev/null +++ b/templates/it/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Sposta stampa {job_id}:Sposta tutte le stampe}

    + +

    {job_id?La stampa {job_id}:Tutte le stampe} {job_id?è stata:sono state} spostat{job_id?a:e} su +{job_printer_name}.

    + +
    diff --git a/templates/it/job-release.tmpl b/templates/it/job-release.tmpl new file mode 100644 index 0000000000..c6520fdd53 --- /dev/null +++ b/templates/it/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Rilascia la stampa {job_id}

    + +

    La stampa {job_id} è stata rilasciata. + +

    diff --git a/templates/it/job-restart.tmpl b/templates/it/job-restart.tmpl new file mode 100644 index 0000000000..59d9aa6b56 --- /dev/null +++ b/templates/it/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ripeti la stampa {job_id}

    + +

    La stampa {job_id} è stata riavviata. + +

    diff --git a/templates/it/jobs-header.tmpl b/templates/it/jobs-header.tmpl new file mode 100644 index 0000000000..38538d12f5 --- /dev/null +++ b/templates/it/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?Nessuna stampa:Mostrat{total=1?a:e} {#job_id} di {total} stamp{total=1?a:e} {?which_jobs=?attiva:{which_jobs=all?:completata}} }.

    diff --git a/templates/it/jobs.tmpl b/templates/it/jobs.tmpl new file mode 100644 index 0000000000..494c1eebd3 --- /dev/null +++ b/templates/it/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }NomeUtenteDimensionePagineStatoControllo
    {job_printer_name}-{job_id} {?job_name=?Unknown:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Unknown:{?job_media_sheets_completed}} {job_state=3?pending since
    {time_at_creation}:{job_state=4?held since
    {time_at_creation}: +{job_state=5?processing since
    {time_at_processing}:{job_state=6?stopped: +{job_state=7?canceled at
    {time_at_completed}:{job_state=8?aborted:completed at
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/it/list-available-printers.tmpl b/templates/it/list-available-printers.tmpl new file mode 100644 index 0000000000..147d6103cf --- /dev/null +++ b/templates/it/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Stampanti disponibili

    + +{#device_uri=0?

    Nessuna stampante trovata.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/it/modify-class.tmpl b/templates/it/modify-class.tmpl new file mode 100644 index 0000000000..065f2b91ab --- /dev/null +++ b/templates/it/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Modifica classe {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Descrizione:
    Posizione:
    Membri: + +
    + +
    +
    \ No newline at end of file diff --git a/templates/it/modify-printer.tmpl b/templates/it/modify-printer.tmpl new file mode 100644 index 0000000000..a6303f2983 --- /dev/null +++ b/templates/it/modify-printer.tmpl @@ -0,0 +1,38 @@ +
    + +

    Modifica {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Descrizione:
    +(Descrizione esplicativa del tipo "HP LaserJet con Duplexer")
    Posizione:
    +(Posizione esplicativa del tipo "Laboratorio 1")
    Connessione:{device_uri}
    Condivisione: +Condividi stampante
    + +
    +
    diff --git a/templates/it/norestart.tmpl b/templates/it/norestart.tmpl new file mode 100644 index 0000000000..924d533f25 --- /dev/null +++ b/templates/it/norestart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Cambia impostazioni

    + +

    Il server non è stato riavviato poiché nessuna modifica è stata apportata alla configurazione...

    + +
    diff --git a/templates/it/option-boolean.tmpl b/templates/it/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/it/option-boolean.tmpl @@ -0,0 +1,6 @@ + +{keytext}: + +{[choices]{text}} + + diff --git a/templates/it/option-conflict.tmpl b/templates/it/option-conflict.tmpl new file mode 100644 index 0000000000..6d3b97538a --- /dev/null +++ b/templates/it/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Errore: Le seguenti opzioni sono in conflitto:

    + + + +

    Cambia una o più opzioni per risolvere i conflitti.

    diff --git a/templates/it/option-header.tmpl b/templates/it/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/it/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + + diff --git a/templates/it/option-pickmany.tmpl b/templates/it/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/it/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/it/option-pickone.tmpl b/templates/it/option-pickone.tmpl new file mode 100644 index 0000000000..c21fc71ba2 --- /dev/null +++ b/templates/it/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/it/option-trailer.tmpl b/templates/it/option-trailer.tmpl new file mode 100644 index 0000000000..ddbde0bc9a --- /dev/null +++ b/templates/it/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + +
    \ No newline at end of file diff --git a/templates/it/pager.tmpl b/templates/it/pager.tmpl new file mode 100644 index 0000000000..019646f95d --- /dev/null +++ b/templates/it/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/it/printer-accept.tmpl b/templates/it/printer-accept.tmpl new file mode 100644 index 0000000000..bbf718ae5b --- /dev/null +++ b/templates/it/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Accetta stampe su {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +accetta stampe.

    + +
    diff --git a/templates/it/printer-added.tmpl b/templates/it/printer-added.tmpl new file mode 100644 index 0000000000..682dfa7e9b --- /dev/null +++ b/templates/it/printer-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Aggiungi stampante

    + +

    Printer {printer_name} è stata aggiunta correttamente. + +

    diff --git a/templates/it/printer-configured.tmpl b/templates/it/printer-configured.tmpl new file mode 100644 index 0000000000..cfcbf65063 --- /dev/null +++ b/templates/it/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Imposta le opzioni predefinite per {printer_name}

    + +

    {OP=set-class-options?Class :Printer }{printer_name} +default options have been set successfully. + +

    diff --git a/templates/it/printer-confirm.tmpl b/templates/it/printer-confirm.tmpl new file mode 100644 index 0000000000..e23071c9f2 --- /dev/null +++ b/templates/it/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Elimina stampante {printer_name}

    + +

    Avviso: Sei sicuro di voler eliminare la stampante +{printer_name}?

    + +

    + +
    diff --git a/templates/it/printer-default.tmpl b/templates/it/printer-default.tmpl new file mode 100644 index 0000000000..fe44138fbf --- /dev/null +++ b/templates/it/printer-default.tmpl @@ -0,0 +1,12 @@ +
    + +

    Imposta {is_class?Class:Printer} {printer_name} come predefinita

    + +

    {is_class?Class:Printer} {printer_name} +è la stampante predefinita su questo server.

    + +
    Note: Qualsiasi utente predefinito impostato attraverso +il comando lpoptions scavalcherà questa impostazione predefinita.
    + +
    diff --git a/templates/it/printer-deleted.tmpl b/templates/it/printer-deleted.tmpl new file mode 100644 index 0000000000..4698805d89 --- /dev/null +++ b/templates/it/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Elimina la stampante {printer_name}

    + +

    La stampante {printer_name} è stata eliminata correttamente. + +

    diff --git a/templates/it/printer-jobs-header.tmpl b/templates/it/printer-jobs-header.tmpl new file mode 100644 index 0000000000..12a936ea92 --- /dev/null +++ b/templates/it/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Stampe

    +
    diff --git a/templates/it/printer-modified.tmpl b/templates/it/printer-modified.tmpl new file mode 100644 index 0000000000..2a34e89d87 --- /dev/null +++ b/templates/it/printer-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Modifica la stampante {printer_name}

    + +

    La stampante {printer_name} è stata +modificata correttamente. + +

    \ No newline at end of file diff --git a/templates/it/printer-purge.tmpl b/templates/it/printer-purge.tmpl new file mode 100644 index 0000000000..8cf7c14617 --- /dev/null +++ b/templates/it/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    Purge Jobs On {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +has been purged of all jobs.

    + +
    \ No newline at end of file diff --git a/templates/it/printer-reject.tmpl b/templates/it/printer-reject.tmpl new file mode 100644 index 0000000000..02f4ce9505 --- /dev/null +++ b/templates/it/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Rifiuta stampe su {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +non accetta alcuna stampa.

    + +
    diff --git a/templates/it/printer-start.tmpl b/templates/it/printer-start.tmpl new file mode 100644 index 0000000000..b7f2edc5f0 --- /dev/null +++ b/templates/it/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    Ripristina {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +è stata ripristinata.

    + +
    \ No newline at end of file diff --git a/templates/it/printer-stop.tmpl b/templates/it/printer-stop.tmpl new file mode 100644 index 0000000000..ef091180cd --- /dev/null +++ b/templates/it/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    Sospendi {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +è stata sospesa.

    + +
    \ No newline at end of file diff --git a/templates/it/printer.tmpl b/templates/it/printer.tmpl new file mode 100644 index 0000000000..78fc08beae --- /dev/null +++ b/templates/it/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?Idle:{printer_state=4?Processing:Paused}}, +{printer_is_accepting_jobs=0?Rejecting Jobs:Accepting Jobs}, +{server_is_sharing_printers=0?Not:{printer_is_shared=0?Not:}} Shared{default_name={printer_name}?, Server Default:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Description:{printer_info}
    Location:{printer_location}
    Driver:{printer_make_and_model} ({color_supported=1?color:grayscale}{sides_supported?, 2-sided printing:})
    +
    Connection:{device_uri}
    Defaults:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    \ No newline at end of file diff --git a/templates/it/printers-header.tmpl b/templates/it/printers-header.tmpl new file mode 100644 index 0000000000..e10112df7a --- /dev/null +++ b/templates/it/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Nessuna stampante:Mostrat{total=1?a:e} {#printer_name} di {total} stampant{total=1?e:i}}.

    diff --git a/templates/it/printers.tmpl b/templates/it/printers.tmpl new file mode 100644 index 0000000000..87efb6d967 --- /dev/null +++ b/templates/it/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nome coda : Nome coda }DescrizionePosizioneMarca e modelloStato
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Idle:{printer_state=4?Processing:Paused}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/it/restart.tmpl b/templates/it/restart.tmpl new file mode 100644 index 0000000000..3d6424867e --- /dev/null +++ b/templates/it/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Cambia impostazioni

    + +

    Attendi il riavvio del server...

    + +
    diff --git a/templates/it/samba-export.tmpl b/templates/it/samba-export.tmpl new file mode 100644 index 0000000000..bce7469d0d --- /dev/null +++ b/templates/it/samba-export.tmpl @@ -0,0 +1,54 @@ + + +
    + + + +

    Esporta stampanti a Samba

    + +{error?

    Impossibile esportare stampanti a Samba\:

    +
    {error}
    +

    Consulta il file error_log per ulteriori informazioni.

    : +

    Questa pagina ti consente di esportare stampanti a Samba in modo che +i client Windows possano accedervi dalle icone Risorse di rete +sui loro desktop. Devi installare preventivamente i driver per stampanti +Windows PostScript come descritto nella pagina di manuale cupsaddsmb(8).

    } + + + + + + + + + + + + + + + + + + +
    Stampanti: +
    + Esporta tutte le stampanti +
    Nome utente Samba: (richiesto)
    Password Samba: (richiesto)
    + +
    diff --git a/templates/it/samba-exported.tmpl b/templates/it/samba-exported.tmpl new file mode 100644 index 0000000000..d75f2d821b --- /dev/null +++ b/templates/it/samba-exported.tmpl @@ -0,0 +1 @@ +

    Stampanti esportate a samba correttamente.

    diff --git a/templates/it/search.tmpl b/templates/it/search.tmpl new file mode 100644 index 0000000000..c71a9dd731 --- /dev/null +++ b/templates/it/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Cerca in +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?Classi:{SECTION=jobs?Stampe:Stampanti}}}: +

    + +
    diff --git a/templates/it/set-printer-options-header.tmpl b/templates/it/set-printer-options-header.tmpl new file mode 100644 index 0000000000..b0867cedbc --- /dev/null +++ b/templates/it/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Imposta opzioni predefinite per {printer_name}

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/it/set-printer-options-trailer.tmpl b/templates/it/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/it/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/it/subscription-added.tmpl b/templates/it/subscription-added.tmpl new file mode 100644 index 0000000000..baec73decd --- /dev/null +++ b/templates/it/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    L'iscrizione {subscription_name} è stata aggiunta correttamente.

    + +
    diff --git a/templates/it/subscription-canceled.tmpl b/templates/it/subscription-canceled.tmpl new file mode 100644 index 0000000000..b8a94aa137 --- /dev/null +++ b/templates/it/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    L'iscrizione #{notify_subscription_id} è stata annullata.

    + +
    diff --git a/templates/it/test-page.tmpl b/templates/it/test-page.tmpl new file mode 100644 index 0000000000..409ebf617d --- /dev/null +++ b/templates/it/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Stampa pagina di prova su {printer_name}

    + +

    Pagina di prova inviata; l'ID della stampa è +{printer_name}-{job_id}.

    + +
    diff --git a/templates/it/trailer.tmpl b/templates/it/trailer.tmpl new file mode 100644 index 0000000000..303b5b86bc --- /dev/null +++ b/templates/it/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS e il logo CUPS sono marchi di +Apple Inc. CUPS è un copyright 2007-2011 Apple +Inc. Tutti i diritti sono riservati. + + + diff --git a/templates/it/users.tmpl b/templates/it/users.tmpl new file mode 100644 index 0000000000..34d8adb10f --- /dev/null +++ b/templates/it/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Utenti autorizzati per {printer_name}

    + + + + + + + + + + +
    Utenti: + +
    +Consenti a questi utenti di stampare +Vieta a questi utenti di stampare +
    + +
    + +
    +
    diff --git a/templates/ja/add-class.tmpl b/templates/ja/add-class.tmpl new file mode 100644 index 0000000000..11108ccfe4 --- /dev/null +++ b/templates/ja/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    クラスの追加

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    名前:
    +("/"、"#"、スペースを除く文字を含めることができます)
    説明:
    +("HP LaserJet with Duplexer" のように人が読みやすい説明)
    場所:
    +("Lab 1" のように人が読みやすい場所)
    メンバー: + +
    + +
    +
    diff --git a/templates/ja/add-printer.tmpl b/templates/ja/add-printer.tmpl new file mode 100644 index 0000000000..f054254aa4 --- /dev/null +++ b/templates/ja/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    新しいプリンターの追加

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    名前:
    +("/"、"#"、スペースを除く文字を含めることができます)
    説明:
    +("HP LaserJet with Duplexer" のように人が読みやすい説明)
    場所:
    +("Lab 1" のように人が読みやすい場所)
    接続:{device_uri}
    共有: +このプリンターを共有する
    + +
    +
    diff --git a/templates/ja/add-rss-subscription.tmpl b/templates/ja/add-rss-subscription.tmpl new file mode 100644 index 0000000000..c5afeb0689 --- /dev/null +++ b/templates/ja/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    RSS 購読を追加

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    名前:
    +("/"、"?"、"#"、スペースを除く文字を含めることができます)
    キュー:
    イベント:ジョブが作成された
    +ジョブが完了した
    +ジョブが停止した
    +ジョブオプションが変更された
        ã‚­ãƒ¥ãƒ¼ãŒåœæ­¢ã—た
    +キューが追加された
    +キューが変更された
    +キューが削除された
        ã‚µãƒ¼ãƒãƒ¼ãŒé–‹å§‹ã—た
    +サーバーが停止した
    +サーバーが再起動した
    +サーバーのセキュリティを監査中
    フィード内の最大イベント数:
    + +
    diff --git a/templates/ja/admin.tmpl b/templates/ja/admin.tmpl new file mode 100644 index 0000000000..e1e0229518 --- /dev/null +++ b/templates/ja/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    プリンター

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    クラス

    + +

    +

    +
    +

    + +

    ジョブ

    + +

    +

    +

    + +
              + +

    サーバー

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    サーバー設定\:

    + +

    詳細
    + + + ほかのシステムで共有されているプリンターを表示
    +        ãƒ—ロトコル\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + このシステムに接続されているプリンターを共有
    +        æœ€å¤§ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæ•°\: +
    +        ãƒ—ロトコル\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         インターネットからの印刷を許可
    +         ウェブインターフェイスを公開
    + リモート管理を許可
    +{have_gssapi? Kerberos 認証を使用 (FAQ)
    :} + 所有者以外のユーザーにもジョブのキャンセルを許可
    + ジョブの履歴を保存
    +        æœ€å¤§ã‚¸ãƒ§ãƒ–æ•°\: +
    +         ジョブの印刷ファイルを保存
    + トラブルシューティングのためにデバッグ情報を保存
    +        æœ€å¤§ãƒ­ã‚°ãƒ•ァイルサイズ\: +

    + +:

    サーバー設定\:

    + +

    詳細
    + + ほかのシステムで共有されているプリンターを表示
    + このシステムに接続されているプリンターを共有
    +         インターネットからの印刷を許可
    + リモート管理を許可
    +{have_gssapi? Kerberos 認証を使用 (FAQ)
    :} + 所有者以外のユーザーにもジョブのキャンセルを許可
    + トラブルシューティングのためにデバッグ情報を保存

    + +} +

    + +
    } + +
    + +
    + +

    RSS 購読

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    名前イベントキュー名
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:すべてのキュー}
    :} diff --git a/templates/ja/choose-device.tmpl b/templates/ja/choose-device.tmpl new file mode 100644 index 0000000000..05700c3c7c --- /dev/null +++ b/templates/ja/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?{printer_name}の変更:プリンターの追加}

    + +{CUPS_GET_DEVICES_DONE?:

    プリンターを探しています...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    現在の接続: +{current_device_uri}
    ローカルプリンター: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    発見されたネットワークプリンター: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    その他のネットワークプリンター: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    \ No newline at end of file diff --git a/templates/ja/choose-make.tmpl b/templates/ja/choose-make.tmpl new file mode 100644 index 0000000000..c800d9818b --- /dev/null +++ b/templates/ja/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?{printer_name}の変更:プリンターの追加}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    名前:{printer_name}
    説明:{printer_info}
    場所:{printer_location}
    接続:{device_uri}
    共有: +このプリンターを共有{?printer_is_shared=?しない:{?printer_is_shared=0?しない:する}}
    メーカー: + +
     
    または PPD ファイルを提供:
    + +
    +
    diff --git a/templates/ja/choose-model.tmpl b/templates/ja/choose-model.tmpl new file mode 100644 index 0000000000..20011b4d51 --- /dev/null +++ b/templates/ja/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?{printer_name}の追加:プリンターの追加}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    名前:{printer_name}
    説明:{printer_info}
    場所:{printer_location}
    接続:{device_uri}
    共有: +このプリンターを共有{?printer_is_shared=?しない:{?printer_is_shared=0?しない:する}}
    メーカー:{PPD_MAKE}
    モデル: + +
    または PPD ファイルを提供:
    + +
    +
    diff --git a/templates/ja/choose-serial.tmpl b/templates/ja/choose-serial.tmpl new file mode 100644 index 0000000000..924b84a74a --- /dev/null +++ b/templates/ja/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?{printer_name}の変更:プリンターの追加}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    接続:{device_uri}
    ボーレート:
    パリティ:
    データビット:
    フロー制御:
    + +
    +
    \ No newline at end of file diff --git a/templates/ja/choose-uri.tmpl b/templates/ja/choose-uri.tmpl new file mode 100644 index 0000000000..48978edf64 --- /dev/null +++ b/templates/ja/choose-uri.tmpl @@ -0,0 +1,43 @@ +
    + +

    {op=modify-printer?{printer_name}の変更:プリンターの追加}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    接続:
    例: +
    +    http://hostname:631/ipp/
    +    http://hostname:631/ipp/port1
    +
    +    ipp://hostname/ipp/
    +    ipp://hostname/ipp/port1
    +
    +    lpd://hostname/queue
    +
    +    socket://hostname
    +    socket://hostname:9100
    +
    + +

    あなたのプリンターにふさわしい URI については、"ネットワークプリンター"を参照してください。

    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/ja/class-added.tmpl b/templates/ja/class-added.tmpl new file mode 100644 index 0000000000..284aa9fb85 --- /dev/null +++ b/templates/ja/class-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    クラスの追加

    + +

    クラス {printer_name} は正しく追加されました。 + +

    diff --git a/templates/ja/class-confirm.tmpl b/templates/ja/class-confirm.tmpl new file mode 100644 index 0000000000..e50b6a90ae --- /dev/null +++ b/templates/ja/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    クラス {printer_name} の削除

    + +

    警告: 本当にクラス +{printer_name} を削除しても良いですか?

    + +

    + +
    diff --git a/templates/ja/class-deleted.tmpl b/templates/ja/class-deleted.tmpl new file mode 100644 index 0000000000..415693791b --- /dev/null +++ b/templates/ja/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    クラス {printer_name} の削除

    + +

    クラス {printer_name} は正しく削除されました。 + +

    diff --git a/templates/ja/class-jobs-header.tmpl b/templates/ja/class-jobs-header.tmpl new file mode 100644 index 0000000000..1d5d887cd8 --- /dev/null +++ b/templates/ja/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    ジョブ

    +
    diff --git a/templates/ja/class-modified.tmpl b/templates/ja/class-modified.tmpl new file mode 100644 index 0000000000..ef14ee4eb0 --- /dev/null +++ b/templates/ja/class-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    クラス {printer_name} の変更

    + +

    Class {printer_name} は正しく変更されました。 + +

    diff --git a/templates/ja/class.tmpl b/templates/ja/class.tmpl new file mode 100644 index 0000000000..c28407642b --- /dev/null +++ b/templates/ja/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?待機中:{printer_state=4?処理中:停止}}, +{printer_is_accepting_jobs=0?ジョブを拒否中:ジョブを受け付け中}, +{server_is_sharing_printers=0?非:{printer_is_shared=0?非:}}共有{default_name={printer_name}?, デフォルトプリンター:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    説明:{printer_info}
    場所:{printer_location}
    メンバー:{?member_uris=?None:{member_uris}}
    デフォルト:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/ja/classes-header.tmpl b/templates/ja/classes-header.tmpl new file mode 100644 index 0000000000..506603cd5a --- /dev/null +++ b/templates/ja/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?クラスはありません:{total} 個のクラスのうち {#printer_name} 個を表示中}。

    diff --git a/templates/ja/classes.tmpl b/templates/ja/classes.tmpl new file mode 100644 index 0000000000..82d13d6612 --- /dev/null +++ b/templates/ja/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? キュー名 : キュー名 }説明場所メンバー状態
    {printer_name}{printer_info}{printer_location}{?member_uris=?None:{member_uris}}{printer_state=3?待機中:{printer_state=4?処理中:停止}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/ja/command.tmpl b/templates/ja/command.tmpl new file mode 100644 index 0000000000..3b8afbf23d --- /dev/null +++ b/templates/ja/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {printer_name} の {title}

    + +

    {job_state>5?:Busy Indicator }プリンタージョブ +{job_state=3?ペンディング中:{job_state=4?ホールド中: +{job_state=5?処理中:{job_state=6?停止中: +{job_state=7?キャンセル:{job_state=8?破棄:完了}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/ja/edit-config.tmpl b/templates/ja/edit-config.tmpl new file mode 100644 index 0000000000..a05a55479a --- /dev/null +++ b/templates/ja/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    設定ファイルの設定

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/ja/error-op.tmpl b/templates/ja/error-op.tmpl new file mode 100644 index 0000000000..81c8fbbdf3 --- /dev/null +++ b/templates/ja/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} エラー

    + +

    エラー:

    + +
    "{op}" は未知の操作です!
    + +
    diff --git a/templates/ja/error.tmpl b/templates/ja/error.tmpl new file mode 100644 index 0000000000..f10c38870d --- /dev/null +++ b/templates/ja/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} エラー

    + +

    {?message?{message}:エラー:}

    + +
    {error}
    + +
    diff --git a/templates/ja/header.tmpl.in b/templates/ja/header.tmpl.in new file mode 100644 index 0000000000..ec64a744d3 --- /dev/null +++ b/templates/ja/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/ja/option-conflict.tmpl b/templates/ja/option-conflict.tmpl new file mode 100644 index 0000000000..4f782ac803 --- /dev/null +++ b/templates/ja/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    エラー: 以下のオプションは競合します:

    + + + +

    競合を解決するために、1 つ以上のオプションを変更してください。

    diff --git a/templates/ja/option-header.tmpl b/templates/ja/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/ja/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      ãƒ›ãƒ¼ãƒ     ç®¡ç†    ã‚¯ãƒ©ã‚¹    ãƒ˜ãƒ«ãƒ—    ã‚¸ãƒ§ãƒ–   ãƒ—リンター 
     
    diff --git a/templates/ja/help-header.tmpl b/templates/ja/help-header.tmpl new file mode 100644 index 0000000000..ee0e5f018c --- /dev/null +++ b/templates/ja/help-header.tmpl @@ -0,0 +1,51 @@ +
    +
    +{TOPIC?:} + +

    +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:すべてのドキュメント}内を検索: + +

    + +
    + + + + +{QUERY?

    {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:すべてのドキュメントの検索結果}}\:

    +{QTEXT?:} +:

    マッチするものは見つかりませんでした。

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    オンラインヘルプ

    + +

    これは、CUPS のオンラインヘルプインターフェイスです。 +オンラインヘルプ情報を表示するには、検索語句を上に入力するか、 +ドキュメントリンクのいずれかをクリックしてください。

    + +

    あなたが CUPS について初心者なら、 "CUPS の概要" を読んでください。 +上級ユーザーは、 "CUPS 1.4 の新機能" +を読むべきです。

    + +

    CUPS ホームページ でも、ユーザー +ディスカッションフォーラム、FAQ、バグ報告や機能リクエストを申請する +フォームといった、多くのリソースを提供しています。

    } + diff --git a/templates/ja/help-printable.tmpl b/templates/ja/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/ja/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/ja/help-trailer.tmpl b/templates/ja/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/ja/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/ja/job-cancel.tmpl b/templates/ja/job-cancel.tmpl new file mode 100644 index 0000000000..16e44d82f3 --- /dev/null +++ b/templates/ja/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    ジョブ {job_id}のキャンセル

    + +

    ジョブ {job_id} はキャンセルされました。 + +

    diff --git a/templates/ja/job-hold.tmpl b/templates/ja/job-hold.tmpl new file mode 100644 index 0000000000..4aec1b2266 --- /dev/null +++ b/templates/ja/job-hold.tmpl @@ -0,0 +1,6 @@ +
    + +

    ジョブ {job_id} の保留

    + +

    ジョブ {job_id} は印刷を保留されました。 +

    diff --git a/templates/ja/job-move.tmpl b/templates/ja/job-move.tmpl new file mode 100644 index 0000000000..54da7e0387 --- /dev/null +++ b/templates/ja/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?ジョブ {job_id} の移動:すべてのジョブの移動}

    + + + + + + + + + + +
    新しい宛先: + +
    + +
    + +
    diff --git a/templates/ja/job-moved.tmpl b/templates/ja/job-moved.tmpl new file mode 100644 index 0000000000..d6b3445c19 --- /dev/null +++ b/templates/ja/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?ジョブ {job_id} の移動:すべてのジョブの移動}

    + +

    {job_id?ジョブ {job_id}:すべてのジョブ} は +{job_printer_name}に移動しました。

    + +
    diff --git a/templates/ja/job-release.tmpl b/templates/ja/job-release.tmpl new file mode 100644 index 0000000000..fd9f89dd24 --- /dev/null +++ b/templates/ja/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    ジョブ {job_id} の解放

    + +

    ジョブ {job_id} は印刷から解放されました。 + +

    diff --git a/templates/ja/job-restart.tmpl b/templates/ja/job-restart.tmpl new file mode 100644 index 0000000000..493a4ace74 --- /dev/null +++ b/templates/ja/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    ジョブ {job_id} の再印刷

    + +

    ジョブ {job_id} は再印刷されました。 + +

    diff --git a/templates/ja/jobs-header.tmpl b/templates/ja/jobs-header.tmpl new file mode 100644 index 0000000000..76095b4e67 --- /dev/null +++ b/templates/ja/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?ジョブはありません:{total} 個の{?which_jobs=?アクティブな:{which_jobs=all?:完了した}}ジョブのうち {#job_id} 個を表示中}。

    diff --git a/templates/ja/jobs.tmpl b/templates/ja/jobs.tmpl new file mode 100644 index 0000000000..bff543aea2 --- /dev/null +++ b/templates/ja/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }名前ユーザーサイズページ状態制御
    {job_printer_name}-{job_id} {?job_name=?未知:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?不明:{?job_media_sheets_completed}} {job_state=3?{time_at_creation}
    から保留中:{job_state=4?held since
    {time_at_creation}: +{job_state=5?{time_at_processing}
    から処理中:{job_state=6?stopped: +{job_state=7?{time_at_completed}
    にキャンセル:{job_state=8?{time_at_completed}に中断:に完了}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/ja/list-available-printers.tmpl b/templates/ja/list-available-printers.tmpl new file mode 100644 index 0000000000..f70b5aac0d --- /dev/null +++ b/templates/ja/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    利用可能なプリンター

    + +{#device_uri=0?

    プリンターが見つかりません。

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/ja/modify-class.tmpl b/templates/ja/modify-class.tmpl new file mode 100644 index 0000000000..a41010f3f3 --- /dev/null +++ b/templates/ja/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    クラス {printer_name} の変更

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    説明:
    場所:
    メンバー: + +
    + +
    +
    \ No newline at end of file diff --git a/templates/ja/modify-printer.tmpl b/templates/ja/modify-printer.tmpl new file mode 100644 index 0000000000..d8ef5f04b5 --- /dev/null +++ b/templates/ja/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    プリンター {printer_name} の変更

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    説明:
    +("HP LaserJet with Duplexer" のように人が読みやすい説明)
    場所:
    +("Lab 1" のように人が読みやすい場所)
    接続:{device_uri}
    共有: +このプリンターを共有する
    + +
    +
    diff --git a/templates/ja/norestart.tmpl b/templates/ja/norestart.tmpl new file mode 100644 index 0000000000..4740433184 --- /dev/null +++ b/templates/ja/norestart.tmpl @@ -0,0 +1,7 @@ +
    + +

    設定変更

    + +

    設定に何も変更が行われなかったため、サーバーは再起動されませんでした...

    + +
    diff --git a/templates/ja/option-boolean.tmpl b/templates/ja/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/ja/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/ja/option-pickmany.tmpl b/templates/ja/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/ja/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/ja/option-pickone.tmpl b/templates/ja/option-pickone.tmpl new file mode 100644 index 0000000000..514e2abc20 --- /dev/null +++ b/templates/ja/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/ja/option-trailer.tmpl b/templates/ja/option-trailer.tmpl new file mode 100644 index 0000000000..da2db1e093 --- /dev/null +++ b/templates/ja/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + \ No newline at end of file diff --git a/templates/ja/pager.tmpl b/templates/ja/pager.tmpl new file mode 100644 index 0000000000..ebba3a0040 --- /dev/null +++ b/templates/ja/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/ja/printer-accept.tmpl b/templates/ja/printer-accept.tmpl new file mode 100644 index 0000000000..f13c66267c --- /dev/null +++ b/templates/ja/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    {is_class?クラス:プリンター} {printer_name} のジョブの受け付け

    + +

    {is_class?クラス:プリンター} {printer_name} +はジョブを受け付けるようになりました。

    + +
    diff --git a/templates/ja/printer-added.tmpl b/templates/ja/printer-added.tmpl new file mode 100644 index 0000000000..c07a832b8d --- /dev/null +++ b/templates/ja/printer-added.tmpl @@ -0,0 +1,6 @@ +
    + +

    プリンターの追加

    + +

    プリンター {printer_name} は正しく追加されました。 +

    diff --git a/templates/ja/printer-configured.tmpl b/templates/ja/printer-configured.tmpl new file mode 100644 index 0000000000..d6b2bf1a4f --- /dev/null +++ b/templates/ja/printer-configured.tmpl @@ -0,0 +1,7 @@ +
    + +

    {printer_name} のデフォルトオプションの設定

    + +

    {OP=set-class-options?クラス :プリンター }{printer_name} のデフォルトオプションは正しく設定されました。 + +

    diff --git a/templates/ja/printer-confirm.tmpl b/templates/ja/printer-confirm.tmpl new file mode 100644 index 0000000000..6fdb52cabc --- /dev/null +++ b/templates/ja/printer-confirm.tmpl @@ -0,0 +1,9 @@ +
    + +

    プリンター {printer_name} の削除

    + +

    警告: 本当にプリンター {printer_name} を削除してよいですか?

    + +

    + +
    diff --git a/templates/ja/printer-default.tmpl b/templates/ja/printer-default.tmpl new file mode 100644 index 0000000000..aa04c2ee94 --- /dev/null +++ b/templates/ja/printer-default.tmpl @@ -0,0 +1,12 @@ +
    + +

    {is_class?クラス:プリンター} {printer_name} をデフォルトに設定

    + +

    {is_class?クラス:プリンター} {printer_name} +をサーバーのデフォルトプリンターに設定しました。

    + +
    注意: lpoptions コマンドで設定されたユーザーのデフォルトは、このサーバーのデフォルト設定を上書きします。 +
    + +
    diff --git a/templates/ja/printer-deleted.tmpl b/templates/ja/printer-deleted.tmpl new file mode 100644 index 0000000000..17cf44c15b --- /dev/null +++ b/templates/ja/printer-deleted.tmpl @@ -0,0 +1,6 @@ +
    + +

    プリンター {printer_name} の削除

    + +

    プリンター {printer_name} は正しく削除されました。 +

    diff --git a/templates/ja/printer-jobs-header.tmpl b/templates/ja/printer-jobs-header.tmpl new file mode 100644 index 0000000000..1d5d887cd8 --- /dev/null +++ b/templates/ja/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    ジョブ

    +
    diff --git a/templates/ja/printer-modified.tmpl b/templates/ja/printer-modified.tmpl new file mode 100644 index 0000000000..63997bb4c2 --- /dev/null +++ b/templates/ja/printer-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    プリンター {printer_name} の変更

    + +

    プリンター {printer_name} は正しく変更されました。 + +

    diff --git a/templates/ja/printer-purge.tmpl b/templates/ja/printer-purge.tmpl new file mode 100644 index 0000000000..0546412a80 --- /dev/null +++ b/templates/ja/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    {is_class?クラス:プリンター} {printer_name} ジョブの全削除

    + +

    {is_class?クラス:プリンター} {printer_name} +はすべてのジョブを削除しました。

    + +
    diff --git a/templates/ja/printer-reject.tmpl b/templates/ja/printer-reject.tmpl new file mode 100644 index 0000000000..ba7cc524c7 --- /dev/null +++ b/templates/ja/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    {is_class?クラス:プリンター} {printer_name} のジョブの拒否

    + +

    {is_class?クラス:プリンター} {printer_name} +はジョブを受け付けなくなりました。

    + +
    diff --git a/templates/ja/printer-start.tmpl b/templates/ja/printer-start.tmpl new file mode 100644 index 0000000000..5c0eea19fc --- /dev/null +++ b/templates/ja/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    {is_class?クラス:プリンター} {printer_name} の再開

    + +

    {is_class?クラス:プリンター} {printer_name} +は再開しました。

    + +
    diff --git a/templates/ja/printer-stop.tmpl b/templates/ja/printer-stop.tmpl new file mode 100644 index 0000000000..8499b2ea75 --- /dev/null +++ b/templates/ja/printer-stop.tmpl @@ -0,0 +1,8 @@ +
    + +

    {is_class?クラス:プリンター} {printer_name} の停止

    + +

    {is_class?クラス:プリンター} {printer_name} +は停止しました。

    +
    diff --git a/templates/ja/printer.tmpl b/templates/ja/printer.tmpl new file mode 100644 index 0000000000..fbd9c5ad0c --- /dev/null +++ b/templates/ja/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?待機中:{printer_state=4?処理中:一時停止中}}, +{printer_is_accepting_jobs=0?ジョブを拒否中:ジョブを受け付け中}, +{server_is_sharing_printers=0?非:{printer_is_shared=0?非:}}共有{default_name={printer_name}?, デフォルトプリンター:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    説明:{printer_info}
    場所:{printer_location}
    プリンタードライバー:{printer_make_and_model} ({color_supported=1?カラー:白黒}{sides_supported?, 両面可:})
    +
    接続先:{device_uri}
    デフォルト設定:バナー={job_sheets_default} +用紙サイズ={media_default?{media_default}:unknown} +{sides_default?両面指定={sides_default}:}
    + +
    diff --git a/templates/ja/printers-header.tmpl b/templates/ja/printers-header.tmpl new file mode 100644 index 0000000000..1342eff42d --- /dev/null +++ b/templates/ja/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?プリンターはありません:{total} 台のプリンターのうち {#printer_name} 台を表示中}。

    diff --git a/templates/ja/printers.tmpl b/templates/ja/printers.tmpl new file mode 100644 index 0000000000..3fb9a37e8a --- /dev/null +++ b/templates/ja/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? キュー名:キュー名}説明場所メーカーとモデル状態
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?待機:{printer_state=4?Processing:停止中}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/ja/restart.tmpl b/templates/ja/restart.tmpl new file mode 100644 index 0000000000..ec74fac837 --- /dev/null +++ b/templates/ja/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    設定の変更

    + +

    サーバーが再起動するあいだ、しばらくお待ちください...

    + +
    diff --git a/templates/ja/samba-export.tmpl b/templates/ja/samba-export.tmpl new file mode 100644 index 0000000000..74b7991e36 --- /dev/null +++ b/templates/ja/samba-export.tmpl @@ -0,0 +1,56 @@ + + +
    + + + +

    プリンターを Samba にエクスポート

    + +{error?

    プリンターを Samba にエクスポートできません\:

    +
    {error}
    +

    より詳細な情報については error_log ファイルを参照してください。

    : +

    このページは、Windows クライアントがデスクトップ上の +マイネットワーク や ネットワークの場所 +アイコン経由でアクセスできるよう、プリンターの Samba +へのエクスポートを許可します。cupsaddsmb(8) man ページに書かれているように、 +事前に Windows PostScript ドライバーをインストールしておく必要があります。 +

    } + + + + + + + + + + + + + + + + + + +
    プリンター: +
    + すべてのプリンターをエクスポート +
    Samba のユーザー名: (required)
    Samba のパスワード: (required)
    + +
    diff --git a/templates/ja/samba-exported.tmpl b/templates/ja/samba-exported.tmpl new file mode 100644 index 0000000000..f67ddd9285 --- /dev/null +++ b/templates/ja/samba-exported.tmpl @@ -0,0 +1 @@ +

    プリンターは Samba に正しくエクスポートされました。

    diff --git a/templates/ja/search.tmpl b/templates/ja/search.tmpl new file mode 100644 index 0000000000..3e819952cd --- /dev/null +++ b/templates/ja/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?クラス:{SECTION=jobs?ジョブ:プリンター}}} 内を検索: +

    + +
    diff --git a/templates/ja/set-printer-options-header.tmpl b/templates/ja/set-printer-options-header.tmpl new file mode 100644 index 0000000000..b5896f071e --- /dev/null +++ b/templates/ja/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    {printer_name} のデフォルトオプション変更

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/ja/set-printer-options-trailer.tmpl b/templates/ja/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/ja/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/ja/subscription-added.tmpl b/templates/ja/subscription-added.tmpl new file mode 100644 index 0000000000..e4ab98cf9e --- /dev/null +++ b/templates/ja/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    {subscription_name} の購読は正しく追加されました。

    + +
    diff --git a/templates/ja/subscription-canceled.tmpl b/templates/ja/subscription-canceled.tmpl new file mode 100644 index 0000000000..8787dad2bd --- /dev/null +++ b/templates/ja/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    購読 #{notify_subscription_id} はキャンセルされました。

    + +
    diff --git a/templates/ja/test-page.tmpl b/templates/ja/test-page.tmpl new file mode 100644 index 0000000000..6cdaa87517 --- /dev/null +++ b/templates/ja/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    {printer_name} のテストページ印刷

    + +

    テストページを送信しました; ジョブ ID は +{printer_name}-{job_id} です。

    + +
    diff --git a/templates/ja/trailer.tmpl b/templates/ja/trailer.tmpl new file mode 100644 index 0000000000..100d9f7adc --- /dev/null +++ b/templates/ja/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS and the CUPS logo are trademarks of +Apple Inc. CUPS is copyright 2007-2011 Apple +Inc. All rights reserved. + + + diff --git a/templates/ja/users.tmpl b/templates/ja/users.tmpl new file mode 100644 index 0000000000..b998c6b2b9 --- /dev/null +++ b/templates/ja/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    {printer_name} に許可するユーザー

    + + + + + + + + + + +
    ユーザー: + +
    +これらのユーザーの印刷を許可 +これらのユーザーの印刷を禁止 +
    + +
    + +
    +
    diff --git a/templates/job-cancel.tmpl b/templates/job-cancel.tmpl new file mode 100644 index 0000000000..3e8fd4dadf --- /dev/null +++ b/templates/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Cancel Job {job_id}

    + +

    Job {job_id} has been canceled. + +

    diff --git a/templates/job-hold.tmpl b/templates/job-hold.tmpl new file mode 100644 index 0000000000..58ce97fc91 --- /dev/null +++ b/templates/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Hold Job {job_id}

    + +

    Job {job_id} has been held from printing. + +

    diff --git a/templates/job-move.tmpl b/templates/job-move.tmpl new file mode 100644 index 0000000000..6ef0ff12e1 --- /dev/null +++ b/templates/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Move Job {job_id}:Move All Jobs}

    + + + + + + + + + + +
    New Destination: + +
    + +
    + +
    diff --git a/templates/job-moved.tmpl b/templates/job-moved.tmpl new file mode 100644 index 0000000000..c4db096968 --- /dev/null +++ b/templates/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Move Job {job_id}:Move All Jobs}

    + +

    {job_id?Job {job_id}:All jobs} moved to +{job_printer_name}.

    + +
    diff --git a/templates/job-release.tmpl b/templates/job-release.tmpl new file mode 100644 index 0000000000..8eb9a96675 --- /dev/null +++ b/templates/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Release Job {job_id}

    + +

    Job {job_id} has been released for printing. + +

    diff --git a/templates/job-restart.tmpl b/templates/job-restart.tmpl new file mode 100644 index 0000000000..b91ced9263 --- /dev/null +++ b/templates/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Reprint Job {job_id}

    + +

    Job {job_id} has been restarted. + +

    diff --git a/templates/jobs-header.tmpl b/templates/jobs-header.tmpl new file mode 100644 index 0000000000..e7547ba7bb --- /dev/null +++ b/templates/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?No jobs:Showing {#job_id} of {total} {?which_jobs=?active:{which_jobs=all?:completed}} job{total=1?:s}}.

    diff --git a/templates/jobs.tmpl b/templates/jobs.tmpl new file mode 100644 index 0000000000..9c56b3f94d --- /dev/null +++ b/templates/jobs.tmpl @@ -0,0 +1,36 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? ID : ID }NameUserSizePagesStateControl
    {job_printer_name}-{job_id} {?job_name=?Unknown:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Unknown:{?job_media_sheets_completed}} {job_state=3?pending since
    {time_at_creation}:{job_state=4?held since
    {time_at_creation}: +{job_state=5?processing since
    {time_at_processing}:{job_state=6?stopped: +{job_state=7?canceled at
    {time_at_completed}:{job_state=8?aborted:completed at
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/list-available-printers.tmpl b/templates/list-available-printers.tmpl new file mode 100644 index 0000000000..a594439ee3 --- /dev/null +++ b/templates/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Available Printers

    + +{#device_uri=0?

    No printers found.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/modify-class.tmpl b/templates/modify-class.tmpl new file mode 100644 index 0000000000..31f7b9ce3c --- /dev/null +++ b/templates/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Modify Class {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Description:
    Location:
    Members: + +
    + +
    +
    \ No newline at end of file diff --git a/templates/modify-printer.tmpl b/templates/modify-printer.tmpl new file mode 100644 index 0000000000..bdf3df6042 --- /dev/null +++ b/templates/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    Modify {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Description:
    +(Human-readable description such as "HP LaserJet with Duplexer")
    Location:
    +(Human-readable location such as "Lab 1")
    Connection:{device_uri}
    Sharing: +Share This Printer
    + +
    +
    diff --git a/templates/norestart.tmpl b/templates/norestart.tmpl new file mode 100644 index 0000000000..6b3120337c --- /dev/null +++ b/templates/norestart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Change Settings

    + +

    The server was not restarted because no changes were made to +the configuration...

    + +
    diff --git a/templates/option-boolean.tmpl b/templates/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/option-boolean.tmpl @@ -0,0 +1,6 @@ + +{keytext}: + +{[choices]{text}} + + diff --git a/templates/option-conflict.tmpl b/templates/option-conflict.tmpl new file mode 100644 index 0000000000..3772295a83 --- /dev/null +++ b/templates/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Error: The following options are conflicting:

    + + + +

    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 0000000000..464726a50b --- /dev/null +++ b/templates/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + + diff --git a/templates/option-pickmany.tmpl b/templates/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/option-pickone.tmpl b/templates/option-pickone.tmpl new file mode 100644 index 0000000000..890ef4e7d3 --- /dev/null +++ b/templates/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/option-trailer.tmpl b/templates/option-trailer.tmpl new file mode 100644 index 0000000000..17c928109e --- /dev/null +++ b/templates/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + +
    \ No newline at end of file diff --git a/templates/pager.tmpl b/templates/pager.tmpl new file mode 100644 index 0000000000..ebd688d51b --- /dev/null +++ b/templates/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/pl/add-class.tmpl b/templates/pl/add-class.tmpl new file mode 100644 index 0000000000..d1f4b66bf6 --- /dev/null +++ b/templates/pl/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Dodawanie klasy

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Nazwa:
    +(Może zawierać wszystkie drukowalne znaki, oprócz "/", "#" i spacji)
    Opis:
    +(Opis czytelny dla człowieka, taki jak "HP LaserJet z dupleksem")
    Położenie:
    +(Położenie czytelne dla człowieka, takie jak "Laboratorium 1")
    Członkowie: + +
    + +
    +
    diff --git a/templates/pl/add-printer.tmpl b/templates/pl/add-printer.tmpl new file mode 100644 index 0000000000..45b50a0d4c --- /dev/null +++ b/templates/pl/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    Dodawanie drukarki

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nazwa:
    +(Może zawierać wszystkie drukowalne znaki, oprócz "/", "#" i spacji)
    Opis:
    +(Opis czytelny dla człowieka, taki jak "HP LaserJet z dupleksem")
    Położenie:
    +(Położenie czytelne dla człowieka, takie jak "Laboratorium 1")
    Połączenie:{device_uri}
    Współdzielenie: +Współdzielenie tej drukarki
    + +
    +
    diff --git a/templates/pl/add-rss-subscription.tmpl b/templates/pl/add-rss-subscription.tmpl new file mode 100644 index 0000000000..f11ba610a5 --- /dev/null +++ b/templates/pl/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Dodawanie subskrypcji RSS

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nazwa:
    +(Może zawierać wszystkie drukowalne znaki, oprócz spacji, "/", "?" i "#")
    Kolejka:
    Zdarzenia:Utworzono zadanie
    +Ukończono zadanie
    +Zatrzymano zadanie
    +Zmieniono opcje zadania
        Zatrzymano kolejkę
    +Dodano kolejkę
    +Zmodyfikowano kolejkę
    +Usunięto kolejkę
        Uruchomiono serwer
    +Zatrzymano serwer
    +Ponownie uruchomiono serwer
    +Audytowanie bezpieczeństwa serwera
    Maksymalna liczba zdarzeń w kanale:
    + +
    diff --git a/templates/pl/admin.tmpl b/templates/pl/admin.tmpl new file mode 100644 index 0000000000..16840361fd --- /dev/null +++ b/templates/pl/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Drukarki

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Klasy

    + +

    +

    +
    +

    + +

    Zadania

    + +

    +

    +

    + +
              + +

    Serwery

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Ustawienia serwera\:

    + +

    Zaawansowane
    + + + Wyświetlanie drukarek współdzielonych przez inne systemy
    +        Protokoły\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Współdzielenie drukarek podłączonych do tego systemu
    +        Maksymalna liczba klientów\: +
    +        Protokoły\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Zezwolenie na drukowanie z Internetu"
    +         Rozgłaszanie interfejsu WWW
    + Zezwolenie na zdalną administrację
    +{have_gssapi? Używanie uwierzytelniania Kerberosa (FAQ)
    :} + Zezwolenie użytkownikom na anulowanie każdego zadania (nie tylko ich własnego)
    + Przechowywanie plików zadań
    +        Liczba zadań\: +
    +         Przechowywanie plików wydruków zadań
    + Zapisywanie informacji debugowania do naprawiania problemów
    +        Maksymalny rozmiar pliku dziennika\: +

    + +:

    Ustawienia serwera:

    + +

    Zaawansowane
    + + Wyświetlanie drukarek współdzielonych przez inne systemy
    + Współdzielenie drukarek połączonych do tego systemu
    +         Zezwolenie na drukowanie z Internetu
    + Zezwolenie na zdalną administrację
    +{have_gssapi? Używanie uwierzytelniania Kerberosa (FAQ)
    :} + Zezwolenie użytkownikom na anulowanie każdego zadania (nie tylko ich własnego)
    + Zapisywanie informacji debugowania do naprawiania problemów

    + +} +

    + +
    } + +
    + +
    + +

    Subskrypcje RSS

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    NameZdarzeniaNazwa kolejki
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Wszystkie kolejki}
    :} diff --git a/templates/pl/choose-device.tmpl b/templates/pl/choose-device.tmpl new file mode 100644 index 0000000000..4457456244 --- /dev/null +++ b/templates/pl/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?Modyfikowanie {printer_name}:Dodawanie drukarki}

    + +{CUPS_GET_DEVICES_DONE?:

    Wyszukiwanie drukarek...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Bieżące połączenie: +{current_device_uri}
    Lokalne drukarki: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Wykryte drukarki sieciowe: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Inne drukarki sieciowe: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    diff --git a/templates/pl/choose-make.tmpl b/templates/pl/choose-make.tmpl new file mode 100644 index 0000000000..c0ec622a7a --- /dev/null +++ b/templates/pl/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Modify {printer_name}:Dodawanie drukarki}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nazwa:{printer_name}
    Opis:{printer_info}
    Położenie:{printer_location}
    Połączenie:{device_uri}
    Współdzielenie: +{?printer_is_shared=?Do Not:{?printer_is_shared=0?Do Not:}} Współdzielenie tej drukarki
    Producent: + +
     
    Lub podaj plik PPD:
    + +
    +
    diff --git a/templates/pl/choose-model.tmpl b/templates/pl/choose-model.tmpl new file mode 100644 index 0000000000..9438cee567 --- /dev/null +++ b/templates/pl/choose-model.tmpl @@ -0,0 +1,60 @@ +
    + +

    {op=modify-printer?Modyfikowanie {printer_name}:Dodawanie drukarki}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nazwa:{printer_name}
    Opis:{printer_info}
    Położenie:{printer_location}
    Połączenie:{device_uri}
    Współdzielenie: +{?printer_is_shared=?Nie:{?printer_is_shared=0?Nie:}} współdziel tej drukarki
    Producent:{PPD_MAKE}
    Model: + +
    Lub podaj plik PPD:
    + +
    +
    diff --git a/templates/pl/choose-serial.tmpl b/templates/pl/choose-serial.tmpl new file mode 100644 index 0000000000..8bbf8c8c2f --- /dev/null +++ b/templates/pl/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Modyfikowanie {printer_name}:Dodawanie drukarki}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Połączenie:{device_uri}
    Prędkość w baudach:
    Równorzędność:
    Bity danych:
    Kontrola przepływu:
    + +
    +
    diff --git a/templates/pl/choose-uri.tmpl b/templates/pl/choose-uri.tmpl new file mode 100644 index 0000000000..88201b925d --- /dev/null +++ b/templates/pl/choose-uri.tmpl @@ -0,0 +1,44 @@ +
    + +

    {op=modify-printer?Modyfikowanie {printer_name}:Dodawanie drukarki}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Połączenie:
    Przykłady: +
    +    http://nazwakomputera:631/ipp/
    +    http://nazwakomputera:631/ipp/port1
    +
    +    ipp://nazwakomputera/ipp/
    +    ipp://nazwakomputera/ipp/port1
    +
    +    lpd://nazwakomputera/kolejka
    +
    +    socket://nazwakomputera
    +    socket://nazwakomputera:9100
    +
    + +

    Proszę zobaczyć "Drukarki +sieciowe", aby uzyskać poprawne URI dla drukarki.

    + +
    + +
    +
    diff --git a/templates/pl/class-added.tmpl b/templates/pl/class-added.tmpl new file mode 100644 index 0000000000..2bee7d8ca3 --- /dev/null +++ b/templates/pl/class-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Dodawanie klasy

    + +

    Klasa {printer_name} została pomyślnie +dodana. + +

    diff --git a/templates/pl/class-confirm.tmpl b/templates/pl/class-confirm.tmpl new file mode 100644 index 0000000000..55cb5ed4e8 --- /dev/null +++ b/templates/pl/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Usuwanie klasy {printer_name}

    + +

    Ostrzeżenie: Usunąć klasę +{printer_name}?

    + +

    + +
    diff --git a/templates/pl/class-deleted.tmpl b/templates/pl/class-deleted.tmpl new file mode 100644 index 0000000000..1a78c903e3 --- /dev/null +++ b/templates/pl/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Usuwanie klasy {printer_name}

    + +

    Klasa {printer_name} została pomyślnie usunięta. + +

    diff --git a/templates/pl/class-jobs-header.tmpl b/templates/pl/class-jobs-header.tmpl new file mode 100644 index 0000000000..83dcfbcd5b --- /dev/null +++ b/templates/pl/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Zadania

    +
    diff --git a/templates/pl/class-modified.tmpl b/templates/pl/class-modified.tmpl new file mode 100644 index 0000000000..be91caaed4 --- /dev/null +++ b/templates/pl/class-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Modyfikowanie klasy {printer_name}

    + +

    Klasa {printer_name} została +pomyślnie zmodyfikowana. + +

    diff --git a/templates/pl/class.tmpl b/templates/pl/class.tmpl new file mode 100644 index 0000000000..5c015ac5ca --- /dev/null +++ b/templates/pl/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?Bezczynna:{printer_state=4?Przetwarzanie:Wstrzymane}}, +{printer_is_accepting_jobs=0?Odrzucanie zadań:Akceptowanie zadań}, +{server_is_sharing_printers=0?Nie:{printer_is_shared=0?Nie:}} Współdzielona{default_name={printer_name}?, Domyślne serwera:})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Opis:{printer_info}
    Położenie:{printer_location}
    Członkowie:{?member_uris=?None:{member_uris}}
    Domyślne:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/pl/classes-header.tmpl b/templates/pl/classes-header.tmpl new file mode 100644 index 0000000000..8482fd19ca --- /dev/null +++ b/templates/pl/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Brak klas:Wyświetlanie {#printer_name} z {total} klas{total=1?:es}}.

    diff --git a/templates/pl/classes.tmpl b/templates/pl/classes.tmpl new file mode 100644 index 0000000000..1d8c766da7 --- /dev/null +++ b/templates/pl/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nazwa kolejki : Nazwa kolejki }OpisPołożenieMembersStan
    {printer_name}{printer_info}{printer_location}{?member_uris=?Brak:{member_uris}}{printer_state=3?Idle:{printer_state=4?Przetwarzanie:Wstrzymane}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/pl/command.tmpl b/templates/pl/command.tmpl new file mode 100644 index 0000000000..9a87439ca5 --- /dev/null +++ b/templates/pl/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} On {printer_name}

    + +

    {job_state>5?:Busy Indicator }Printer command job +{job_state=3?pending:{job_state=4?held: +{job_state=5?processing:{job_state=6?stopped: +{job_state=7?canceled:{job_state=8?aborted:completed}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/pl/edit-config.tmpl b/templates/pl/edit-config.tmpl new file mode 100644 index 0000000000..3688ee24c0 --- /dev/null +++ b/templates/pl/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Modyfikowanie pliku konfiguracji

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/pl/error-op.tmpl b/templates/pl/error-op.tmpl new file mode 100644 index 0000000000..b9e5f7194d --- /dev/null +++ b/templates/pl/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Błąd

    + +

    Błąd:

    + +
    Nieznana operacja "{op}"!
    + +
    diff --git a/templates/pl/error.tmpl b/templates/pl/error.tmpl new file mode 100644 index 0000000000..f9992930bc --- /dev/null +++ b/templates/pl/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} Błąd

    + +

    {?message?{message}:Błąd:}

    + +
    {error}
    + +
    diff --git a/templates/pl/header.tmpl.in b/templates/pl/header.tmpl.in new file mode 100644 index 0000000000..ca1774b89e --- /dev/null +++ b/templates/pl/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} - CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/pl/option-conflict.tmpl b/templates/pl/option-conflict.tmpl new file mode 100644 index 0000000000..708ba4c2f2 --- /dev/null +++ b/templates/pl/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Błąd: następujące opcje są w konflikcie ze sobą:

    + + + +

    Proszę zmienić jedną lub więcej opcji, aby rozwiązać konflikt.

    diff --git a/templates/pl/option-header.tmpl b/templates/pl/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/pl/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      Strona domowa    Administracja    Klasy    Pomoc online    Zadania    Drukarki  
     
    diff --git a/templates/pl/help-header.tmpl b/templates/pl/help-header.tmpl new file mode 100644 index 0000000000..88f5524215 --- /dev/null +++ b/templates/pl/help-header.tmpl @@ -0,0 +1,51 @@ +
    +
    +{TOPIC?:} + +

    Wyszukaj w +{HELPTITLE?{HELPTITLE}:{TOPIC?{TOPIC}:Wszystkie dokumenty}}: + +

    + +
    + + + + +{QUERY?

    Wyniki wyszukiwania w {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:Wszystkie dokumenty}}\:

    +{QTEXT?:} +:

    Nie znaleziono.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Pomoc online

    + +

    To jest interfejs pomocy online CUPS. Należy podać wyszukiwane słowa +powyżej lub nacisnąć na jeden z odnośników do dokumentacji, aby wyświetlić +informacje o pomocy online.

    + +

    Nowi użytkownicy CUPS powinni przeczytać stronę "Przegląd CUPS". Zaawansowani użytkownicy +powinni przeczytać stronę "Co nowego w CUPS +1.4".

    + +

    Strona domowa CUPS także +dostarcza wiele zasobów, w tym fora dyskusyjne użytkowników, odpowiedzi +na najczęściej zadawane pytania oraz formularz do wysyłania raportów +błędów i próśb o nowe funkcje.

    } diff --git a/templates/pl/help-printable.tmpl b/templates/pl/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/pl/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/pl/help-trailer.tmpl b/templates/pl/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/pl/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/pl/job-cancel.tmpl b/templates/pl/job-cancel.tmpl new file mode 100644 index 0000000000..bcfffcf0df --- /dev/null +++ b/templates/pl/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Anulowanie zadania {job_id}

    + +

    Zadanie {job_id} zostało anulowane. + +

    diff --git a/templates/pl/job-hold.tmpl b/templates/pl/job-hold.tmpl new file mode 100644 index 0000000000..8827d9e28a --- /dev/null +++ b/templates/pl/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Wstrzymywanie zadania {job_id}

    + +

    Drukowanie zadania {job_id} zostało wstrzymane. + +

    diff --git a/templates/pl/job-move.tmpl b/templates/pl/job-move.tmpl new file mode 100644 index 0000000000..bd77beeb2d --- /dev/null +++ b/templates/pl/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Przenoszenie zadanie {job_id}:Przenoszenie wszystkich zadań}

    + + + + + + + + + + +
    Nowe miejsce docelowe: + +
    + +
    + +
    diff --git a/templates/pl/job-moved.tmpl b/templates/pl/job-moved.tmpl new file mode 100644 index 0000000000..bd3db7686e --- /dev/null +++ b/templates/pl/job-moved.tmpl @@ -0,0 +1,8 @@ +
    + +

    {job_id?Przenoszenie zadania {job_id}:Przenoszenie wszystkich zadań}

    + +

    {job_id?Zadanie {job_id}:Wszystkie zadania} zostało przeniesione do +{job_printer_name}.

    + +
    diff --git a/templates/pl/job-release.tmpl b/templates/pl/job-release.tmpl new file mode 100644 index 0000000000..09bffda038 --- /dev/null +++ b/templates/pl/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Zwalnianie zadania {job_id}

    + +

    Drukowanie zadania {job_id} zostało zwolnione. + +

    diff --git a/templates/pl/job-restart.tmpl b/templates/pl/job-restart.tmpl new file mode 100644 index 0000000000..6edf8b2472 --- /dev/null +++ b/templates/pl/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Ponowne drukowanie zadania {job_id}

    + +

    Zadanie {job_id} zostało ponownie uruchomione. + +

    diff --git a/templates/pl/jobs-header.tmpl b/templates/pl/jobs-header.tmpl new file mode 100644 index 0000000000..ea8718d12b --- /dev/null +++ b/templates/pl/jobs-header.tmpl @@ -0,0 +1,5 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?Brak zadań:Wyświetlanie {#job_id} z {total} {?which_jobs=?aktywnych:{which_jobs=all?:zakończonych}} zadań{total=1?:s}}.

    diff --git a/templates/pl/jobs.tmpl b/templates/pl/jobs.tmpl new file mode 100644 index 0000000000..665bdffbdb --- /dev/null +++ b/templates/pl/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? Identyfikator : Identyfikator }NazwaUżytkownikRozmiarStronyStanKontrola
    {job_printer_name}-{job_id} {?job_name=?Unknown:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Unknown:{?job_media_sheets_completed}} {job_state=3?oczekiwanie od
    {time_at_creation}:{job_state=4?wstrzymane od
    {time_at_creation}: +{job_state=5?przetwarzanie od
    {time_at_processing}:{job_state=6?zatrzymano: +{job_state=7?anulowano o
    {time_at_completed}:{job_state=8?przerwano:zakończono o
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/pl/list-available-printers.tmpl b/templates/pl/list-available-printers.tmpl new file mode 100644 index 0000000000..aad6a49fa5 --- /dev/null +++ b/templates/pl/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Dostępne drukarki

    + +{#device_uri=0?

    Nie znaleziono drukarek.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/pl/modify-class.tmpl b/templates/pl/modify-class.tmpl new file mode 100644 index 0000000000..b8a2130763 --- /dev/null +++ b/templates/pl/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Modyfikowanie klasy {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Opis:
    Położenie:
    Członkowie: + +
    + +
    +
    diff --git a/templates/pl/modify-printer.tmpl b/templates/pl/modify-printer.tmpl new file mode 100644 index 0000000000..a63f4781c9 --- /dev/null +++ b/templates/pl/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    Modyfikowanie {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Opis:
    +(Opis czytelny dla człowieka, taki jak "HP LaserJet z dupleksem")
    Położenie:
    +(Położenie czytelne dla człowieka, takie jak "Laboratorium 1")
    Połączenie:{device_uri}
    Współdzielenie: +Share This Printer
    + +
    +
    diff --git a/templates/pl/norestart.tmpl b/templates/pl/norestart.tmpl new file mode 100644 index 0000000000..d29b0f4c77 --- /dev/null +++ b/templates/pl/norestart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Zmienianie ustawień

    + +

    Serwer nie został ponownie uruchomiony, ponieważ nie wprowadzono żadnych zmian do +konfiguracji...

    + +
    diff --git a/templates/pl/option-boolean.tmpl b/templates/pl/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/pl/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/pl/option-pickmany.tmpl b/templates/pl/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/pl/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/pl/option-pickone.tmpl b/templates/pl/option-pickone.tmpl new file mode 100644 index 0000000000..598fe1007f --- /dev/null +++ b/templates/pl/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/pl/option-trailer.tmpl b/templates/pl/option-trailer.tmpl new file mode 100644 index 0000000000..21eec5678c --- /dev/null +++ b/templates/pl/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + diff --git a/templates/pl/pager.tmpl b/templates/pl/pager.tmpl new file mode 100644 index 0000000000..ce3515e575 --- /dev/null +++ b/templates/pl/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/pl/printer-accept.tmpl b/templates/pl/printer-accept.tmpl new file mode 100644 index 0000000000..6589b60f38 --- /dev/null +++ b/templates/pl/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Akceptowanie zadań na {is_class?klasie:drukarce} {printer_name}

    + +

    {is_class?Klasa:Drukarka} {printer_name} +akceptują zadania.

    + +
    diff --git a/templates/pl/printer-added.tmpl b/templates/pl/printer-added.tmpl new file mode 100644 index 0000000000..e217ee4f0e --- /dev/null +++ b/templates/pl/printer-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Dodawanie drukarki

    + +

    Drukarka {printer_name} została +pomyślnie dodana. + +

    diff --git a/templates/pl/printer-configured.tmpl b/templates/pl/printer-configured.tmpl new file mode 100644 index 0000000000..994ed3461e --- /dev/null +++ b/templates/pl/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Ustawianie domyślnych opcji dla {printer_name}

    + +

    Domyślne opcje {OP=set-class-options?klasy :drukarki }{printer_name} +zostały pomyślnie ustawione. + +

    diff --git a/templates/pl/printer-confirm.tmpl b/templates/pl/printer-confirm.tmpl new file mode 100644 index 0000000000..73f8601285 --- /dev/null +++ b/templates/pl/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Usuwanie drukarki {printer_name}

    + +

    Ostrzeżenie: usunąć drukarkę +{printer_name}?

    + +

    + +
    diff --git a/templates/pl/printer-default.tmpl b/templates/pl/printer-default.tmpl new file mode 100644 index 0000000000..541de9d99e --- /dev/null +++ b/templates/pl/printer-default.tmpl @@ -0,0 +1,13 @@ +
    + +

    Ustawianie {is_class?klasy:drukarki} {printer_name} jako domyślnej

    + +

    {is_class?Klasa:Drukarka} {printer_name} +została ustawiona jako domyślna drukarka serwera.

    + +
    Uwaga: każda domyśla opcja użytkownika ustawiona przez +polecenie lpoptions zostanie zastąpiona tym domyślnym +ustawieniem.
    + +
    diff --git a/templates/pl/printer-deleted.tmpl b/templates/pl/printer-deleted.tmpl new file mode 100644 index 0000000000..26e170b13e --- /dev/null +++ b/templates/pl/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Usuwanie drukarki {printer_name}

    + +

    Drukarka {printer_name} została pomyślnie usunięta. + +

    diff --git a/templates/pl/printer-jobs-header.tmpl b/templates/pl/printer-jobs-header.tmpl new file mode 100644 index 0000000000..83dcfbcd5b --- /dev/null +++ b/templates/pl/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Zadania

    +
    diff --git a/templates/pl/printer-modified.tmpl b/templates/pl/printer-modified.tmpl new file mode 100644 index 0000000000..9bf074dbc8 --- /dev/null +++ b/templates/pl/printer-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Modyfikowanie drukarki {printer_name}

    + +

    Drukarka {printer_name} została +pomyślnie zmodyfikowana. + +

    diff --git a/templates/pl/printer-purge.tmpl b/templates/pl/printer-purge.tmpl new file mode 100644 index 0000000000..065217511a --- /dev/null +++ b/templates/pl/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    Czyszczenie zadań na {is_class?klasie:drukarce} {printer_name}

    + +

    {is_class?Klasa:Drukarka} {printer_name} +została wyczyszczona ze wszystkich zadań.

    + +
    diff --git a/templates/pl/printer-reject.tmpl b/templates/pl/printer-reject.tmpl new file mode 100644 index 0000000000..038f8bab25 --- /dev/null +++ b/templates/pl/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Odrzucanie zadań na {is_class?klasie:drukarce} {printer_name}

    + +

    {is_class?Klasa:Drukarka} {printer_name} +nie akceptuje zadań.

    + +
    diff --git a/templates/pl/printer-start.tmpl b/templates/pl/printer-start.tmpl new file mode 100644 index 0000000000..e291f49d9e --- /dev/null +++ b/templates/pl/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    Wznawianie {is_class?klasy:drukarki} {printer_name}

    + +

    {is_class?Klasa:Drukarka} {printer_name} +została wznowiona.

    + +
    diff --git a/templates/pl/printer-stop.tmpl b/templates/pl/printer-stop.tmpl new file mode 100644 index 0000000000..06f94f699c --- /dev/null +++ b/templates/pl/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    Wstrzymywanie {is_class?klasy:drukarki} {printer_name}

    + +

    {is_class?Klasa:Drukarka} {printer_name} +została wstrzymana.

    + +
    diff --git a/templates/pl/printer.tmpl b/templates/pl/printer.tmpl new file mode 100644 index 0000000000..c62b857a0b --- /dev/null +++ b/templates/pl/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?Bezczynna:{printer_state=4?Przetwarzanie:Wstrzymana}}, +{printer_is_accepting_jobs=0?Odrzucanie zadań:Akceptowanie zadań}, +{server_is_sharing_printers=0?Nie:{printer_is_shared=0?Nie:}} Współdzielona{default_name={printer_name}?, Domyślne serwera:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Opis:{printer_info}
    Położenie:{printer_location}
    Sterownik:{printer_make_and_model} ({color_supported=1?color:grayscale}{sides_supported?, 2-sided printing:})
    +
    Połączenie:{device_uri}
    Domyślne:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/pl/printers-header.tmpl b/templates/pl/printers-header.tmpl new file mode 100644 index 0000000000..6a06c7f590 --- /dev/null +++ b/templates/pl/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Brak drukarek:Wyświetlanie {#printer_name} z {total} drukarek{total=1?:s}}.

    diff --git a/templates/pl/printers.tmpl b/templates/pl/printers.tmpl new file mode 100644 index 0000000000..810ecb4a53 --- /dev/null +++ b/templates/pl/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Nazwa kolejki : Nazwa kolejki }OpisPołożenieProducent i modelStan
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Bezczynna:{printer_state=4?Przetwarzanie:Wstrzymana}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/pl/restart.tmpl b/templates/pl/restart.tmpl new file mode 100644 index 0000000000..6965e6b501 --- /dev/null +++ b/templates/pl/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Zmienianie ustawień

    + +

    Proszę czekać, trwa ponowne uruchamianie serwera...

    + +
    diff --git a/templates/pl/samba-export.tmpl b/templates/pl/samba-export.tmpl new file mode 100644 index 0000000000..691a30bb03 --- /dev/null +++ b/templates/pl/samba-export.tmpl @@ -0,0 +1,55 @@ + + +
    + + + +

    Eksportowanie drukarek do Samby

    + +{error?

    Nie można wyeksportować drukarek do Samby\:

    +
    {error}
    +

    Proszę zobaczyć plik error_log, aby uzyskać więcej informacji.

    : +

    Ta strona umożliwia wyeksportowanie drukarek do Samby, aby +klienci Windows mogli mieć do nich dostęp przez ikonę Otoczenie +sieciowe lub Miejsca sieciowe na pulpitach. +Należy wcześniej zainstalować sterowniki drukarki Windows PostScript, +tak jak opisano na stronie podręcznika cupsaddsmb(8).

    } + + + + + + + + + + + + + + + + + + +
    Drukarki: +
    + Wyeksportuj wszystkie drukarki +
    Nazwa użytkownika Samby: (wymagana)
    Hasło Samby: (wymagane)
    + +
    diff --git a/templates/pl/samba-exported.tmpl b/templates/pl/samba-exported.tmpl new file mode 100644 index 0000000000..55ba028662 --- /dev/null +++ b/templates/pl/samba-exported.tmpl @@ -0,0 +1 @@ +

    Pomyślnie wyeksportowano drukarki do Samby.

    diff --git a/templates/pl/search.tmpl b/templates/pl/search.tmpl new file mode 100644 index 0000000000..0851d85166 --- /dev/null +++ b/templates/pl/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Znajdź w +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?klasach:{SECTION=jobs?zadaniach:drukarkach}}}: +

    + +
    diff --git a/templates/pl/set-printer-options-header.tmpl b/templates/pl/set-printer-options-header.tmpl new file mode 100644 index 0000000000..58e5b85d13 --- /dev/null +++ b/templates/pl/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Ustawianie domyślnych opcji dla {printer_name}

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/pl/set-printer-options-trailer.tmpl b/templates/pl/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..c1183e18e3 --- /dev/null +++ b/templates/pl/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/pl/subscription-added.tmpl b/templates/pl/subscription-added.tmpl new file mode 100644 index 0000000000..af87082b16 --- /dev/null +++ b/templates/pl/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subskrypcja {subscription_name} została pomyślnie dodana.

    + +
    diff --git a/templates/pl/subscription-canceled.tmpl b/templates/pl/subscription-canceled.tmpl new file mode 100644 index 0000000000..58ce44c7ab --- /dev/null +++ b/templates/pl/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subskrypcja #{notify_subscription_id} została usunięta.

    + +
    diff --git a/templates/pl/test-page.tmpl b/templates/pl/test-page.tmpl new file mode 100644 index 0000000000..346a6d2fc7 --- /dev/null +++ b/templates/pl/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Drukowanie strony próbnej na {printer_name}

    + +

    Wysłano stronę próbną; identyfikator zadania to +{printer_name}-{job_id}.

    + +
    diff --git a/templates/pl/trailer.tmpl b/templates/pl/trailer.tmpl new file mode 100644 index 0000000000..5f2602b23c --- /dev/null +++ b/templates/pl/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS i logo CUPS +są znakami handlowymi Apple Inc. CUPS +copyright 2007-2011 Apple Inc. Wszystkie prawa zastrzeżone. + + + diff --git a/templates/pl/users.tmpl b/templates/pl/users.tmpl new file mode 100644 index 0000000000..5cb7549521 --- /dev/null +++ b/templates/pl/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Zezwoleni użytkownicy dla {printer_name}

    + + + + + + + + + + +
    Użytkownicy: + +
    +Pozwól tym użytkownikom drukować +Nie pozwalaj tym użytkownikom drukować +
    + +
    + +
    +
    diff --git a/templates/printer-accept.tmpl b/templates/printer-accept.tmpl new file mode 100644 index 0000000000..3e987ce64f --- /dev/null +++ b/templates/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Accept Jobs On {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +is now accepting jobs.

    + +
    diff --git a/templates/printer-added.tmpl b/templates/printer-added.tmpl new file mode 100644 index 0000000000..9a6e798e9a --- /dev/null +++ b/templates/printer-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Add Printer

    + +

    Printer {printer_name} has been added +successfully. + +

    diff --git a/templates/printer-configured.tmpl b/templates/printer-configured.tmpl new file mode 100644 index 0000000000..6f8104e231 --- /dev/null +++ b/templates/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Set Default Options for {printer_name}

    + +

    {OP=set-class-options?Class :Printer }{printer_name} +default options have been set successfully. + +

    diff --git a/templates/printer-confirm.tmpl b/templates/printer-confirm.tmpl new file mode 100644 index 0000000000..fce9e3494b --- /dev/null +++ b/templates/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Delete Printer {printer_name}

    + +

    Warning: Are you sure you want to delete printer +{printer_name}?

    + +

    + +
    diff --git a/templates/printer-default.tmpl b/templates/printer-default.tmpl new file mode 100644 index 0000000000..72a7b5ea8c --- /dev/null +++ b/templates/printer-default.tmpl @@ -0,0 +1,13 @@ +
    + +

    Set {is_class?Class:Printer} {printer_name} As Default

    + +

    {is_class?Class:Printer} {printer_name} +has been made the default printer on the server.

    + +
    Note: Any user default that has been set via +the lpoptions command will override this default +setting.
    + +
    diff --git a/templates/printer-deleted.tmpl b/templates/printer-deleted.tmpl new file mode 100644 index 0000000000..d8a31ae615 --- /dev/null +++ b/templates/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Delete Printer {printer_name}

    + +

    Printer {printer_name} has been deleted successfully. + +

    diff --git a/templates/printer-jobs-header.tmpl b/templates/printer-jobs-header.tmpl new file mode 100644 index 0000000000..ba46f10260 --- /dev/null +++ b/templates/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Jobs

    +
    diff --git a/templates/printer-modified.tmpl b/templates/printer-modified.tmpl new file mode 100644 index 0000000000..b61e8e34a2 --- /dev/null +++ b/templates/printer-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Modify Printer {printer_name}

    + +

    Printer {printer_name} has been +modified successfully. + +

    \ No newline at end of file diff --git a/templates/printer-purge.tmpl b/templates/printer-purge.tmpl new file mode 100644 index 0000000000..8cf7c14617 --- /dev/null +++ b/templates/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    Purge Jobs On {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +has been purged of all jobs.

    + +
    \ No newline at end of file diff --git a/templates/printer-reject.tmpl b/templates/printer-reject.tmpl new file mode 100644 index 0000000000..5f1c79195b --- /dev/null +++ b/templates/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Reject Jobs On {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +is no longer accepting jobs.

    + +
    diff --git a/templates/printer-start.tmpl b/templates/printer-start.tmpl new file mode 100644 index 0000000000..3eaed13d17 --- /dev/null +++ b/templates/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    Resume {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +has been resumed.

    + +
    \ No newline at end of file diff --git a/templates/printer-stop.tmpl b/templates/printer-stop.tmpl new file mode 100644 index 0000000000..b74e87135d --- /dev/null +++ b/templates/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    Pause {is_class?Class:Printer} {printer_name}

    + +

    {is_class?Class:Printer} {printer_name} +has been paused.

    + +
    \ No newline at end of file diff --git a/templates/printer.tmpl b/templates/printer.tmpl new file mode 100644 index 0000000000..78fc08beae --- /dev/null +++ b/templates/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?Idle:{printer_state=4?Processing:Paused}}, +{printer_is_accepting_jobs=0?Rejecting Jobs:Accepting Jobs}, +{server_is_sharing_printers=0?Not:{printer_is_shared=0?Not:}} Shared{default_name={printer_name}?, Server Default:})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Description:{printer_info}
    Location:{printer_location}
    Driver:{printer_make_and_model} ({color_supported=1?color:grayscale}{sides_supported?, 2-sided printing:})
    +
    Connection:{device_uri}
    Defaults:job-sheets={job_sheets_default} +media={media_default?{media_default}:unknown} +{sides_default?sides={sides_default}:}
    + +
    \ No newline at end of file diff --git a/templates/printers-header.tmpl b/templates/printers-header.tmpl new file mode 100644 index 0000000000..5196be1d87 --- /dev/null +++ b/templates/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?No printers:Showing {#printer_name} of {total} printer{total=1?:s}}.

    diff --git a/templates/printers.tmpl b/templates/printers.tmpl new file mode 100644 index 0000000000..e0a3228d04 --- /dev/null +++ b/templates/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Queue Name : Queue Name }DescriptionLocationMake and ModelStatus
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?Idle:{printer_state=4?Processing:Paused}}{printer_state_message? - "{printer_state_message}":}
    } diff --git a/templates/restart.tmpl b/templates/restart.tmpl new file mode 100644 index 0000000000..bdfca876fb --- /dev/null +++ b/templates/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Change Settings

    + +

    Please stand by while the server restarts...

    + +
    diff --git a/templates/ru/Makefile b/templates/ru/Makefile new file mode 100644 index 0000000000..ca4c6e120b --- /dev/null +++ b/templates/ru/Makefile @@ -0,0 +1,201 @@ +# +# "$Id$" +# +# Template makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1993-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +# +# Template files... +# + +FILES = \ + add-class.tmpl \ + add-printer.tmpl \ + add-rss-subscription.tmpl \ + admin.tmpl \ + choose-device.tmpl \ + choose-make.tmpl \ + choose-model.tmpl \ + choose-serial.tmpl \ + choose-uri.tmpl \ + class.tmpl \ + class-added.tmpl \ + class-confirm.tmpl \ + class-deleted.tmpl \ + class-jobs-header.tmpl \ + class-modified.tmpl \ + classes.tmpl \ + classes-header.tmpl \ + command.tmpl \ + edit-config.tmpl \ + error.tmpl \ + error-op.tmpl \ + header.tmpl \ + help-header.tmpl \ + help-trailer.tmpl \ + help-printable.tmpl \ + job-cancel.tmpl \ + job-hold.tmpl \ + job-move.tmpl \ + job-moved.tmpl \ + job-release.tmpl \ + job-restart.tmpl \ + jobs.tmpl \ + jobs-header.tmpl \ + list-available-printers.tmpl \ + modify-class.tmpl \ + modify-printer.tmpl \ + norestart.tmpl \ + option-boolean.tmpl \ + option-conflict.tmpl \ + option-header.tmpl \ + option-pickmany.tmpl \ + option-pickone.tmpl \ + option-trailer.tmpl \ + pager.tmpl \ + printer.tmpl \ + printer-accept.tmpl \ + printer-added.tmpl \ + printer-configured.tmpl \ + printer-confirm.tmpl \ + printer-default.tmpl \ + printer-deleted.tmpl \ + printer-jobs-header.tmpl \ + printer-modified.tmpl \ + printer-purge.tmpl \ + printer-reject.tmpl \ + printer-start.tmpl \ + printer-stop.tmpl \ + printers.tmpl \ + printers-header.tmpl \ + restart.tmpl \ + samba-export.tmpl \ + samba-exported.tmpl \ + search.tmpl \ + set-printer-options-header.tmpl \ + set-printer-options-trailer.tmpl \ + subscription-added.tmpl \ + subscription-canceled.tmpl \ + test-page.tmpl \ + trailer.tmpl \ + users.tmpl + + +# +# Make everything... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Dummy depend... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: $(INSTALL_LANGUAGES) + $(INSTALL_DIR) -m 755 $(DATADIR)/templates + for file in $(FILES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/templates; \ + done + +install-languages: + for lang in $(LANGUAGES); do \ + if test -d $$lang; then \ + $(INSTALL_DIR) -m 755 $(DATADIR)/templates/$$lang; \ + for file in $(FILES); do \ + $(INSTALL_DATA) $$lang/$$file $(DATADIR)/templates/$$lang 2>/dev/null || true; \ + done \ + fi \ + done + + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: $(UNINSTALL_LANGUAGES) + for file in $(FILES); do \ + $(RM) $(DATADIR)/templates/$$file; \ + done + -$(RMDIR) $(DATADIR)/templates + +uninstall-languages: + for lang in $(LANGUAGES); do \ + for file in $(FILES); do \ + $(RM) $(DATADIR)/templates/$$lang/$$file; \ + done \ + $(RMDIR) $(DATADIR)/templates/$$lang; \ + done + + +# +# End of "$Id$". +# diff --git a/templates/ru/add-class.tmpl b/templates/ru/add-class.tmpl new file mode 100644 index 0000000000..41a7f9868c --- /dev/null +++ b/templates/ru/add-class.tmpl @@ -0,0 +1,40 @@ +
    + +

    Новая группа

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    Название:
    +(может содержать любые символы кроме «/», «#» и пробела)
    Описание:
    +(расширенное описание группы, например, «Дуплексный принтер»)
    Расположение:
    +(местоположение группы, например, «Кабинет 55»)
    Состав группы: + +
    + +
    +
    diff --git a/templates/ru/add-printer.tmpl b/templates/ru/add-printer.tmpl new file mode 100644 index 0000000000..2d040189ca --- /dev/null +++ b/templates/ru/add-printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    Добавление принтера

    + +
    + + + + + + +{?current_make!?:} +{?current_make_and_model!?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Название:
    +(может содержать любые символы кроме «/», «#» и пробела)
    Описание:
    +(расширенное описание принтера, например, «HP LaserJet с дуплексной печатью»)
    Расположение:
    +(местоположение принтера, например, «Кабинет 55»)
    Подключение:{device_uri}
    Совместный доступ: +Разрешить совместный доступ к этому принтеру
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/add-rss-subscription.tmpl b/templates/ru/add-rss-subscription.tmpl new file mode 100644 index 0000000000..6ff4ff2cdb --- /dev/null +++ b/templates/ru/add-rss-subscription.tmpl @@ -0,0 +1,44 @@ +
    + + + +

    Добавление подписки по RSS

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Название:
    +(может содержать любые символы кроме «/», «#» и пробела)
    Очередь:
    События:Новое задание
    +Задание напечатано
    +Задание остановлено
    +Изменены параметров задания
        ÐžÑ‡ÐµÑ€ÐµÐ´ÑŒ остановлена
    +Очередь добавлена
    +Очередь изменена
    +Очередь удалена
        Ð¡ÐµÑ€Ð²ÐµÑ€ запущен
    +Сервер остановлен
    +Сервер перезапущен
    +Проверка безопасности сервера
    Количество событий в ленте:
    + +
    diff --git a/templates/ru/admin.tmpl b/templates/ru/admin.tmpl new file mode 100644 index 0000000000..22d9de0649 --- /dev/null +++ b/templates/ru/admin.tmpl @@ -0,0 +1,110 @@ + + +
    + +

    Принтеры

    + +

    +

    +
    +
    +{have_samba?
    :} +

    + +

    Группы

    + +

    +

    +
    +

    + +

    Задания

    + +

    +

    +

    + +
              + +

    Сервер

    + +

    +

    +
    +
    +
    +

    + +{SETTINGS_ERROR?

    {SETTINGS_MESSAGE}

    +
    {SETTINGS_ERROR}
    : + +
    + + +{ADVANCEDSETTINGS?

    Параметры сервера\:

    + +

    Дополнительные параметры
    + + + Показать принтеры, использующиеся в других системах
    +        ÐŸÑ€Ð¾Ñ‚околы\: + CUPS +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    + Разрешить совместный доступ к принтерам, подключенным к этой системе
    +        ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð¾Ðµ количество клиентов\: +
    +        ÐŸÑ€Ð¾Ñ‚околы\: + CUPS +{HAVE_DNSSD? DNS-SD:} +{HAVE_LDAP? LDAP:} +{HAVE_LIBSLP? SLP:}
    +         Разрешить печать из Интернета
    +         Анонсировать веб-интерфейс
    + Разрешить удаленное администрирование
    +{have_gssapi? Разрешить аунтентификацию Kerberos (FAQ)
    :} + Разрешить пользователям отменять любое задание (не только их собственное)
    + Вести журнал заданий
    +        ÐšÐ¾Ð»Ð¸Ñ‡ÐµÑÑ‚во заданий\: +
    +         Сохранять содержимое заданий
    +Сохранять отладочную информацию в журнале
    +        ÐœÐ°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¹ размер журнала ошибок\: +

    + +:

    Параметры сервера:

    + +

    Дополнительные параметры
    + + Показать принтеры, использующиеся в других системах
    + Разрешить совместный доступ к принтерам, подключенным к этой системе
    +         Разрешить печать из Интернета
    + Разрешить удаленное администрирование
    +{have_gssapi? Разрешить аунтентификацию Kerberos (FAQ)
    :} + Разрешить пользователям отменять любое задание (не только их собственное)
    + Сохранять отладочную информацию в журнале

    + +} +

    + +
    } + +
    + +
    + +

    Подписка по RSS

    + +

    +

    +

    + +
    + +{notify_subscription_id? + +{[notify_subscription_id] +} + +
    НазваниеСобытияОчередь
    {notify_recipient_name}
    +
     
    {notify_events} {notify_printer_name?{notify_printer_name}:Все очереди}
    :} diff --git a/templates/ru/choose-device.tmpl b/templates/ru/choose-device.tmpl new file mode 100644 index 0000000000..3df36db86a --- /dev/null +++ b/templates/ru/choose-device.tmpl @@ -0,0 +1,54 @@ +
    + +

    {op=modify-printer?Изменение {printer_name}:Добавление принтера}

    + +{CUPS_GET_DEVICES_DONE?:

    Поиск принтеров...

    } + +
    + + +{printer_name?:} + + +{op=add-printer?: + + +} + + + + + + + + + + + + + + + + + +
    Текущее подключение: +{current_device_uri}
    Локальные принтеры: +{[device_uri]{device_class!network? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}} +
    Обнаруженные сетевые принтеры: +{[device_uri]{device_class=network?{device_uri~[a-z]+://? +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +:}:}} +
    Другие сетевые принтеры: +{[device_uri]{device_class=network?{device_uri~[a-z]+://?: +{device_info} {?device_make_and_model!Unknown?({device_make_and_model}):}
    +}:}} +
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/choose-make.tmpl b/templates/ru/choose-make.tmpl new file mode 100644 index 0000000000..a87d6bf276 --- /dev/null +++ b/templates/ru/choose-make.tmpl @@ -0,0 +1,64 @@ +
    + +

    {op=modify-printer?Изменение {printer_name}:Добавление принтера}

    + +
    + + +{printer_name?:} + + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Название:{printer_name}
    Описание:{printer_info}
    Расположение:{printer_location}
    Подключение:{device_uri}
    Совместный доступ: +{?printer_is_shared=?Нет совместного доступа:{?printer_is_shared=0?Нет совместного доступа:Разрешен совместный доступ}} к этому принтеру
    Создать: + +
     
    или использовать файл PPD:
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/choose-model.tmpl b/templates/ru/choose-model.tmpl new file mode 100644 index 0000000000..9d434f1c37 --- /dev/null +++ b/templates/ru/choose-model.tmpl @@ -0,0 +1,59 @@ +
    + +

    {op=modify-printer?Изменение {printer_name}:Добавление принтера}

    + +
    + + +{printer_name?:} + + + + + +{op=modify-printer?: + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Название:{printer_name}
    Описание:{printer_info}
    Расположение:{printer_location}
    Подключение:{device_uri}
    Совместный доступ: +{?printer_is_shared=?Нет совместного доступа:{?printer_is_shared=0?Нет совместного доступа:Разрешен совместный доступ}} к этому принтеру
    Создать:{PPD_MAKE}
    Модель: + +
    или использовать файл PPD:
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/choose-serial.tmpl b/templates/ru/choose-serial.tmpl new file mode 100644 index 0000000000..21e4bf87fa --- /dev/null +++ b/templates/ru/choose-serial.tmpl @@ -0,0 +1,52 @@ +
    + +

    {op=modify-printer?Изменение {printer_name}:Добавление принтера}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Подключение:{device_uri}
    Скорость передачи:
    Печать страниц:
    Биты данных:
    Управление:
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/choose-uri.tmpl b/templates/ru/choose-uri.tmpl new file mode 100644 index 0000000000..17e5e94f65 --- /dev/null +++ b/templates/ru/choose-uri.tmpl @@ -0,0 +1,43 @@ +
    + +

    {op=modify-printer?Изменение {printer_name}:Добавление принтера}

    + +
    + + +{printer_name?:} + + + + + + + + + + + + + + + +
    Подключение:
    Примеры: +
    +    http://hostname:631/ipp/
    +    http://hostname:631/ipp/port1
    +
    +    ipp://hostname/ipp/
    +    ipp://hostname/ipp/port1
    +
    +    lpd://hostname/queue
    +
    +    socket://hostname
    +    socket://hostname:9100
    +
    + +

    Смотрите раздел «Сетевые принтеры» для выяснения правильного адреса вашего принтера.

    + +
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/class-added.tmpl b/templates/ru/class-added.tmpl new file mode 100644 index 0000000000..298dfb9286 --- /dev/null +++ b/templates/ru/class-added.tmpl @@ -0,0 +1,7 @@ +
    + +

    Новая группа

    + +

    Группа «{printer_name}» успешно добавлена. + +

    diff --git a/templates/ru/class-confirm.tmpl b/templates/ru/class-confirm.tmpl new file mode 100644 index 0000000000..5bef5bf07c --- /dev/null +++ b/templates/ru/class-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Удаление группы {printer_name}

    + +

    Предупреждение: вы действительно хотите удалить группу +«{printer_name}»?

    + +

    + +
    diff --git a/templates/ru/class-deleted.tmpl b/templates/ru/class-deleted.tmpl new file mode 100644 index 0000000000..0ddd4d5414 --- /dev/null +++ b/templates/ru/class-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Удаление группы {printer_name}

    + +

    Группа «{printer_name}» успешно удалена. + +

    \ No newline at end of file diff --git a/templates/ru/class-jobs-header.tmpl b/templates/ru/class-jobs-header.tmpl new file mode 100644 index 0000000000..8487cbbda5 --- /dev/null +++ b/templates/ru/class-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Задания

    +
    diff --git a/templates/ru/class-modified.tmpl b/templates/ru/class-modified.tmpl new file mode 100644 index 0000000000..94df570f46 --- /dev/null +++ b/templates/ru/class-modified.tmpl @@ -0,0 +1,7 @@ +
    + +

    Изменение группы {printer_name}

    + +

    Группа «{printer_name}» успешно изменена. + +

    \ No newline at end of file diff --git a/templates/ru/class.tmpl b/templates/ru/class.tmpl new file mode 100644 index 0000000000..70dd90a79e --- /dev/null +++ b/templates/ru/class.tmpl @@ -0,0 +1,44 @@ +
    +

    {printer_name} +({printer_state=3?в ожидании:{printer_state=4?печать:приостановлен}}, +{printer_is_accepting_jobs=0?не принимает задания:принимает задания}, +{server_is_sharing_printers=0?нет совместного доступа:{printer_is_shared=0?нет совместного доступа:разрешен совместный доступ}})

    + +
    + + + +
    + +
    + + + + + +
    + + + + + + +
    Описание:{printer_info}
    Расположение:{printer_location}
    Состав:{?member_uris=?Нет принтеров:{member_uris}}
    По умолчанию:job-sheets={job_sheets_default} +media={media_default?{media_default}:неизвестный} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/ru/classes-header.tmpl b/templates/ru/classes-header.tmpl new file mode 100644 index 0000000000..53b3db3288 --- /dev/null +++ b/templates/ru/classes-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Нет групп:Группа {#printer_name} из {total}.

    diff --git a/templates/ru/classes.tmpl b/templates/ru/classes.tmpl new file mode 100644 index 0000000000..151ccad791 --- /dev/null +++ b/templates/ru/classes.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Очередь : Очередь }ОписаниеРасположениеСоставСтатус
    {printer_name}{printer_info}{printer_location}{?member_uris=?Нет принтеров:{member_uris}}{printer_state=3?В ожидании:{printer_state=4?Печатает:Приостановлена}}{printer_state_message?: {printer_state_message}:}
    } diff --git a/templates/ru/command.tmpl b/templates/ru/command.tmpl new file mode 100644 index 0000000000..4dc7b4e6ec --- /dev/null +++ b/templates/ru/command.tmpl @@ -0,0 +1,12 @@ +
    + +

    {title} для {printer_name}

    + +

    {job_state>5?:Индикатор занятости }Обработка задания +{job_state=3?в очереди:{job_state=4?удерживается: +{job_state=5?обрабатывается:{job_state=6?остановлено: +{job_state=7?отменено:{job_state=8?прервано:завершено}}}}}}{job_state=9?:{job_printer_state_message?, +"{job_printer_state_message}":}}

    + +
    diff --git a/templates/ru/edit-config.tmpl b/templates/ru/edit-config.tmpl new file mode 100644 index 0000000000..d194059d88 --- /dev/null +++ b/templates/ru/edit-config.tmpl @@ -0,0 +1,24 @@ + + +
    + +

    Редактирование конфигурационного файла

    + +
    + + + + + +

    +

    + +
    + +
    diff --git a/templates/ru/error-op.tmpl b/templates/ru/error-op.tmpl new file mode 100644 index 0000000000..29fce86b74 --- /dev/null +++ b/templates/ru/error-op.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} — ошибка

    + +

    Ошибка:

    + +
    Неизвестная операция «{op}»!
    + +
    diff --git a/templates/ru/error.tmpl b/templates/ru/error.tmpl new file mode 100644 index 0000000000..9a780b19ec --- /dev/null +++ b/templates/ru/error.tmpl @@ -0,0 +1,9 @@ +
    + +

    {?title} {?printer_name} — ошибка

    + +

    {?message?{message}:Ошибка:}

    + +
    {error}
    + +
    diff --git a/templates/ru/header.tmpl.in b/templates/ru/header.tmpl.in new file mode 100644 index 0000000000..4fbdbe0335 --- /dev/null +++ b/templates/ru/header.tmpl.in @@ -0,0 +1,29 @@ + + + + + {title} — CUPS @CUPS_VERSION@@CUPS_REVISION@ + + + {refresh_page?:} + + + + + + + diff --git a/templates/ru/option-conflict.tmpl b/templates/ru/option-conflict.tmpl new file mode 100644 index 0000000000..9497fb777c --- /dev/null +++ b/templates/ru/option-conflict.tmpl @@ -0,0 +1,7 @@ +

    Ошибка: следующие параметры конфликтуют:

    + + + +

    Измените один или несколько параметров для того, чтобы избежать конфликта.

    diff --git a/templates/ru/option-header.tmpl b/templates/ru/option-header.tmpl new file mode 100644 index 0000000000..464726a50b --- /dev/null +++ b/templates/ru/option-header.tmpl @@ -0,0 +1,5 @@ +
    + +

    {group}

    + +
    + + + + + + + + + + + + + +
      ÐÐ°Ñ‡Ð°Ð»Ð¾    ÐÐ´Ð¼Ð¸Ð½Ð¸ÑÑ‚рирование    Ð“руппы    Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ°    Ð—адания    ÐŸÑ€Ð¸Ð½Ñ‚еры  
     
    diff --git a/templates/ru/help-header.tmpl b/templates/ru/help-header.tmpl new file mode 100644 index 0000000000..6adbae3804 --- /dev/null +++ b/templates/ru/help-header.tmpl @@ -0,0 +1,46 @@ +
    +
    +{TOPIC?:} + +

    Поиск +{HELPTITLE?в {HELPTITLE}:{TOPIC?в {TOPIC}:по справке}}: + +

    + +
    + + + + +{QUERY?

    Результаты поиска в {HELPFILE?{HELPTITLE}:{TOPIC?{TOPIC}:всей справке}}\:

    +{QTEXT?:} +:

    Не найдено совпадений.

    } +
    :} +{HELPTITLE?

    {HELPTITLE}

    +
    : + +

    Справка

    + +

    Это справка CUPS. Введите выше слова для поиска в справке и нажмите «Поиск», чтобы показать результаты поиска.

    + +

    Если вы пока мало знакомы с CUPS, прочтите раздел «Введение в CUPS». Опытные пользователи +могут обратиться к разделу «Что нового в CUPS 1.4».

    + +

    Веб-сайт CUPS содержит большое количество ресурсов для пользователей, включая форум, ответы +на часто задаваемые вопросы и форму для регистрации ошибок и пожеланий.

    } diff --git a/templates/ru/help-printable.tmpl b/templates/ru/help-printable.tmpl new file mode 100644 index 0000000000..2463c1630c --- /dev/null +++ b/templates/ru/help-printable.tmpl @@ -0,0 +1,9 @@ + + + + + {HELPTITLE} + + + + diff --git a/templates/ru/help-trailer.tmpl b/templates/ru/help-trailer.tmpl new file mode 100644 index 0000000000..4c1ebed851 --- /dev/null +++ b/templates/ru/help-trailer.tmpl @@ -0,0 +1 @@ +
    diff --git a/templates/ru/job-cancel.tmpl b/templates/ru/job-cancel.tmpl new file mode 100644 index 0000000000..cba5644692 --- /dev/null +++ b/templates/ru/job-cancel.tmpl @@ -0,0 +1,7 @@ +
    + +

    Отмена задания {job_id}

    + +

    Задание {job_id} отменено. + +

    diff --git a/templates/ru/job-hold.tmpl b/templates/ru/job-hold.tmpl new file mode 100644 index 0000000000..162e4a46ea --- /dev/null +++ b/templates/ru/job-hold.tmpl @@ -0,0 +1,7 @@ +
    + +

    Приостановка задания {job_id}

    + +

    Задание {job_id} приостановлено. + +

    diff --git a/templates/ru/job-move.tmpl b/templates/ru/job-move.tmpl new file mode 100644 index 0000000000..598e4db746 --- /dev/null +++ b/templates/ru/job-move.tmpl @@ -0,0 +1,27 @@ +
    + +
    + + +{job_id?:} + +

    {job_id?Перемещение задания {job_id}:Перемещение всех заданий}

    + + + + + + + + + + +
    Переместить на принтер: + +
    + +
    + +
    diff --git a/templates/ru/job-moved.tmpl b/templates/ru/job-moved.tmpl new file mode 100644 index 0000000000..1755491dd5 --- /dev/null +++ b/templates/ru/job-moved.tmpl @@ -0,0 +1,7 @@ +
    + +

    {job_id?Перемещение задания {job_id}:Перемещение всех заданий}

    + +

    {job_id?Задание {job_id}:Все задания} перемещены на принтер «{job_printer_name}».

    + +
    diff --git a/templates/ru/job-release.tmpl b/templates/ru/job-release.tmpl new file mode 100644 index 0000000000..876c85ba17 --- /dev/null +++ b/templates/ru/job-release.tmpl @@ -0,0 +1,7 @@ +
    + +

    Разблокирование задания {job_id}

    + +

    Задания {job_id} разблокировано. + +

    diff --git a/templates/ru/job-restart.tmpl b/templates/ru/job-restart.tmpl new file mode 100644 index 0000000000..490fc3a37e --- /dev/null +++ b/templates/ru/job-restart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Перезапуск задания {job_id}

    + +

    Задание {job_id} запущено заново. + +

    diff --git a/templates/ru/jobs-header.tmpl b/templates/ru/jobs-header.tmpl new file mode 100644 index 0000000000..d9ee960432 --- /dev/null +++ b/templates/ru/jobs-header.tmpl @@ -0,0 +1,6 @@ +
    {?which_jobs=?:
    } +{?which_jobs=completed?:
    } +{?which_jobs=all?:
    }
    + +

    {total=0?Нет заданий:Задание {#job_id} из {total} {?which_jobs=?активных:{which_jobs=all?:завершенных}}.

    + diff --git a/templates/ru/jobs.tmpl b/templates/ru/jobs.tmpl new file mode 100644 index 0000000000..c2226f67e0 --- /dev/null +++ b/templates/ru/jobs.tmpl @@ -0,0 +1,37 @@ +{#job_id=0?: + + + + + +{[job_id] + + + + + + + + + +} + +
    {ORDER=dec? Номер : ID }НазваниеПользовательРазмерСтраницСтатусУправление
    {job_printer_name}-{job_id} {?job_name=?Неизвестное:{job_name}} {job_originating_user_name} {job_k_octets}k {job_media_sheets_completed=0?Неизвестно:{?job_media_sheets_completed}} {job_state=3?В очереди
    {time_at_creation}:{job_state=4?Приостановлено с
    {time_at_creation}: +{job_state=5?Создано
    {time_at_processing}:{job_state=6?Остановлено: +{job_state=7?Отменено
    {time_at_completed}:{job_state=8?Прервано:Завершено
    {time_at_completed}}}}}}} {job_printer_state_message?
    +"{job_printer_state_message}":}
    +{job_preserved>0?{job_state>5? +
    +
    :}:} +{job_state=4? +
    +
    :} +{job_state=3? +
    +
    :} +{job_state<7? +
    +
    +
    :} + 
    +} diff --git a/templates/ru/list-available-printers.tmpl b/templates/ru/list-available-printers.tmpl new file mode 100644 index 0000000000..1615628457 --- /dev/null +++ b/templates/ru/list-available-printers.tmpl @@ -0,0 +1,11 @@ +
    + +

    Доступные принтеры

    + +{#device_uri=0?

    Не обнаружено ни одного принтера.

    +:
      {[device_uri] +
    • +{device_make_and_model} ({device_info})
    • +}
    } + +
    diff --git a/templates/ru/modify-class.tmpl b/templates/ru/modify-class.tmpl new file mode 100644 index 0000000000..a85698a52c --- /dev/null +++ b/templates/ru/modify-class.tmpl @@ -0,0 +1,34 @@ +
    + +

    Изменение группы {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + +
    Описание:
    Расположение:
    Состав группы: + +
    + +
    +
    \ No newline at end of file diff --git a/templates/ru/modify-printer.tmpl b/templates/ru/modify-printer.tmpl new file mode 100644 index 0000000000..6277b5d6f2 --- /dev/null +++ b/templates/ru/modify-printer.tmpl @@ -0,0 +1,42 @@ +
    + +

    Изменение принтера {printer_name}

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Описание:
    +(расширенное описание принтера, например, «HP LaserJet с дуплексной печатью»)
    Расположение:
    +(местоположение принтера, например, «Кабинет 55»)
    Подключение:{device_uri}
    Совместный доступ: +Разрешить совместный доступ к этому принтеру
    + +
    +
    diff --git a/templates/ru/norestart.tmpl b/templates/ru/norestart.tmpl new file mode 100644 index 0000000000..0b74c036b1 --- /dev/null +++ b/templates/ru/norestart.tmpl @@ -0,0 +1,7 @@ +
    + +

    Применение изменений

    + +

    Сервер не был перезапущен, поскольку не произошло изменений в конфигурации...

    + +
    diff --git a/templates/ru/option-boolean.tmpl b/templates/ru/option-boolean.tmpl new file mode 100644 index 0000000000..e832ee1022 --- /dev/null +++ b/templates/ru/option-boolean.tmpl @@ -0,0 +1,6 @@ +
    {keytext}: +{[choices]{text}} +
    diff --git a/templates/ru/option-pickmany.tmpl b/templates/ru/option-pickmany.tmpl new file mode 100644 index 0000000000..0da75e5d2c --- /dev/null +++ b/templates/ru/option-pickmany.tmpl @@ -0,0 +1,6 @@ + + + + diff --git a/templates/ru/option-pickone.tmpl b/templates/ru/option-pickone.tmpl new file mode 100644 index 0000000000..49a9929ae7 --- /dev/null +++ b/templates/ru/option-pickone.tmpl @@ -0,0 +1,18 @@ + + +:} + diff --git a/templates/ru/option-trailer.tmpl b/templates/ru/option-trailer.tmpl new file mode 100644 index 0000000000..15a3142760 --- /dev/null +++ b/templates/ru/option-trailer.tmpl @@ -0,0 +1,5 @@ +
    {keytext}:
    {keytext}: +{iscustom=1?{[params] + + +}
    {paramtext}:{params=Units?:}
    +
    + +

    + + diff --git a/templates/ru/pager.tmpl b/templates/ru/pager.tmpl new file mode 100644 index 0000000000..fb1d2fae42 --- /dev/null +++ b/templates/ru/pager.tmpl @@ -0,0 +1,6 @@ + + + + + +
    {PREV?
    : }
    {NEXT?
    : }
    diff --git a/templates/ru/printer-accept.tmpl b/templates/ru/printer-accept.tmpl new file mode 100644 index 0000000000..24d100d48b --- /dev/null +++ b/templates/ru/printer-accept.tmpl @@ -0,0 +1,9 @@ +
    + +

    Прием заданий {is_class?в группу:на принтер} {printer_name}

    + +

    {is_class?Группа:Принтер} {printer_name} +теперь принимает задания.

    + +
    diff --git a/templates/ru/printer-added.tmpl b/templates/ru/printer-added.tmpl new file mode 100644 index 0000000000..eda0748c09 --- /dev/null +++ b/templates/ru/printer-added.tmpl @@ -0,0 +1,8 @@ +
    + +

    Добавление принтера

    + +

    Принтер «{printer_name}» успешно +добавлен. + +

    diff --git a/templates/ru/printer-configured.tmpl b/templates/ru/printer-configured.tmpl new file mode 100644 index 0000000000..33c4c143f2 --- /dev/null +++ b/templates/ru/printer-configured.tmpl @@ -0,0 +1,8 @@ +
    + +

    Настройки по умолчанию для {printer_name}

    + +

    {OP=set-class-options?Группа :Принтер }{printer_name} +теперь используют параметры по умолчанию. + +

    diff --git a/templates/ru/printer-confirm.tmpl b/templates/ru/printer-confirm.tmpl new file mode 100644 index 0000000000..c57356d075 --- /dev/null +++ b/templates/ru/printer-confirm.tmpl @@ -0,0 +1,10 @@ +
    + +

    Удаление принтера {printer_name}

    + +

    Предупреждение: вы действительно хотите удалить принтер +«{printer_name}»?

    + +

    + +
    diff --git a/templates/ru/printer-default.tmpl b/templates/ru/printer-default.tmpl new file mode 100644 index 0000000000..6297d79ed0 --- /dev/null +++ b/templates/ru/printer-default.tmpl @@ -0,0 +1,12 @@ +
    + +

    Установка {is_class?группы:принтера} {printer_name} по умолчанию

    + +

    {is_class?Группа:Принтер} {printer_name} +установлены на сервере по умолчанию для новых заданий.

    + +
    Примечание: вы можете переопределить это поведение с помощью команды + lpoptions.
    + +
    diff --git a/templates/ru/printer-deleted.tmpl b/templates/ru/printer-deleted.tmpl new file mode 100644 index 0000000000..97fd8bd8c4 --- /dev/null +++ b/templates/ru/printer-deleted.tmpl @@ -0,0 +1,7 @@ +
    + +

    Удаление принтера {printer_name}

    + +

    Принтер «{printer_name}» успешно удален. + +

    diff --git a/templates/ru/printer-jobs-header.tmpl b/templates/ru/printer-jobs-header.tmpl new file mode 100644 index 0000000000..8487cbbda5 --- /dev/null +++ b/templates/ru/printer-jobs-header.tmpl @@ -0,0 +1,3 @@ +
    +

    Задания

    +
    diff --git a/templates/ru/printer-modified.tmpl b/templates/ru/printer-modified.tmpl new file mode 100644 index 0000000000..be27e5e7f3 --- /dev/null +++ b/templates/ru/printer-modified.tmpl @@ -0,0 +1,8 @@ +
    + +

    Изменение принтера {printer_name}

    + +

    Параметры принтера «{printer_name}» успешно +изменены. + +

    \ No newline at end of file diff --git a/templates/ru/printer-purge.tmpl b/templates/ru/printer-purge.tmpl new file mode 100644 index 0000000000..44fda0d1f1 --- /dev/null +++ b/templates/ru/printer-purge.tmpl @@ -0,0 +1,9 @@ +
    + +

    Очистка всех заданий для {is_class?группы:принтера} {printer_name}

    + +

    Все задания для {is_class?группы:принтера} «{printer_name}» +очищены.

    + +
    diff --git a/templates/ru/printer-reject.tmpl b/templates/ru/printer-reject.tmpl new file mode 100644 index 0000000000..488203c929 --- /dev/null +++ b/templates/ru/printer-reject.tmpl @@ -0,0 +1,9 @@ +
    + +

    Отмена заданий для {is_class?группы:принтера} {printer_name}

    + +

    {is_class?Группа:Принтер} «{printer_name}» +больше не принимает задания.

    + +
    diff --git a/templates/ru/printer-start.tmpl b/templates/ru/printer-start.tmpl new file mode 100644 index 0000000000..69ffa7ef53 --- /dev/null +++ b/templates/ru/printer-start.tmpl @@ -0,0 +1,9 @@ +
    + +

    Возобновить работу {is_class?группы:принтера} {printer_name}

    + +

    {is_class?Группа:Принтер} «{printer_name}» +теперь принимают задания.

    + +
    diff --git a/templates/ru/printer-stop.tmpl b/templates/ru/printer-stop.tmpl new file mode 100644 index 0000000000..3fecd1e73e --- /dev/null +++ b/templates/ru/printer-stop.tmpl @@ -0,0 +1,9 @@ +
    + +

    Приостановить {is_class?группу:принтер} {printer_name}

    + +

    {is_class?Группа:Принтер} «{printer_name}» +{is_class?была приостановлена:был приостановлен}.

    + +
    diff --git a/templates/ru/printer.tmpl b/templates/ru/printer.tmpl new file mode 100644 index 0000000000..5128d004c2 --- /dev/null +++ b/templates/ru/printer.tmpl @@ -0,0 +1,47 @@ +
    + +

    {printer_name} +({printer_state=3?в ожидании:{printer_state=4?печать:приостановлен}}, +{printer_is_accepting_jobs=0?не принимает задания:принимает задания}, +{server_is_sharing_printers=0?нет совместного доступа:{printer_is_shared=0?нет совместного доступа:разрешен совместный доступ}})

    + +
    + + + +
    + +
    + + + + +
    + + + + + + +
    Описание:{printer_info}
    Расположение:{printer_location}
    Драйвер:{printer_make_and_model} ({color_supported=1?цветной:черно-белый}{sides_supported?, дуплексная печать:})
    +
    Подключение:{device_uri}
    По умолчанию:job-sheets={job_sheets_default} +media={media_default?{media_default}:неизвестный} +{sides_default?sides={sides_default}:}
    + +
    diff --git a/templates/ru/printers-header.tmpl b/templates/ru/printers-header.tmpl new file mode 100644 index 0000000000..8662459130 --- /dev/null +++ b/templates/ru/printers-header.tmpl @@ -0,0 +1 @@ +

    {total=0?Нет принтеров:Принтер {#printer_name} из {total}.

    diff --git a/templates/ru/printers.tmpl b/templates/ru/printers.tmpl new file mode 100644 index 0000000000..694658677b --- /dev/null +++ b/templates/ru/printers.tmpl @@ -0,0 +1,11 @@ +{#printer_name=0?: + + + + + +{[printer_name] + +} + +
    {ORDER=dec? Очередь : Очередь }ОписаниеРасположениеДрайверСтатус
    {printer_name}{printer_info}{printer_location}{printer_make_and_model}{printer_state=3?В ожидании:{printer_state=4?Печатает:Приостановлен}}{printer_state_message?: {printer_state_message}:}
    } diff --git a/templates/ru/restart.tmpl b/templates/ru/restart.tmpl new file mode 100644 index 0000000000..1b8132dd35 --- /dev/null +++ b/templates/ru/restart.tmpl @@ -0,0 +1,8 @@ +
    + +

    Применение изменений параметров

    + +

    Дождитесь перезагрузки сервера...

    + +
    diff --git a/templates/ru/samba-export.tmpl b/templates/ru/samba-export.tmpl new file mode 100644 index 0000000000..22a3acb151 --- /dev/null +++ b/templates/ru/samba-export.tmpl @@ -0,0 +1,54 @@ + + +
    + + + +

    Экспорт принтеров в Samba

    + +{error?

    Невозможно экспортировать принтеры в Samba\:

    +
    {error}
    +

    Посмотрите файл «error_log».

    : +

    Эта страница позволяет добавить принтеры в Samba так, чтобы +клиенты Windows могли получить доступ к ним через значок Сетевое окружение на их +рабочем столе. Вы должны установить на Windows драйвер принтера PostScript +как описано на странице руководства cupsaddsmb(8).

    } + + + + + + + + + + + + + + + + + + +
    Принтеры: +
    + Экспортировать все принтеры +
    Имя пользователя Samba: (обязательный параметр)
    Пароль Samba: (обязательный параметр)
    + +
    diff --git a/templates/ru/samba-exported.tmpl b/templates/ru/samba-exported.tmpl new file mode 100644 index 0000000000..179b2ad8aa --- /dev/null +++ b/templates/ru/samba-exported.tmpl @@ -0,0 +1 @@ +

    Принтеры успешно экспортированы в Samba.

    diff --git a/templates/ru/search.tmpl b/templates/ru/search.tmpl new file mode 100644 index 0000000000..64266599db --- /dev/null +++ b/templates/ru/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Поиск +{SEARCH_DEST?на {SEARCH_DEST}:{SECTION=classes?группы:{SECTION=jobs?задания:принтера}}}: +

    + +
    diff --git a/templates/ru/set-printer-options-header.tmpl b/templates/ru/set-printer-options-header.tmpl new file mode 100644 index 0000000000..e5c79dd44a --- /dev/null +++ b/templates/ru/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Установить параметры по умолчанию для {printer_name}

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/ru/set-printer-options-trailer.tmpl b/templates/ru/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/ru/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/ru/subscription-added.tmpl b/templates/ru/subscription-added.tmpl new file mode 100644 index 0000000000..6727217b6f --- /dev/null +++ b/templates/ru/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    Подписка «{subscription_name}» была успешно добавлена.

    + +
    diff --git a/templates/ru/subscription-canceled.tmpl b/templates/ru/subscription-canceled.tmpl new file mode 100644 index 0000000000..205f993e91 --- /dev/null +++ b/templates/ru/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    Подписка «#{notify_subscription_id}» была отменена.

    + +
    diff --git a/templates/ru/test-page.tmpl b/templates/ru/test-page.tmpl new file mode 100644 index 0000000000..7330b80fbd --- /dev/null +++ b/templates/ru/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Печать пробной страницы на {printer_name}

    + +

    Пробная страница отправлена на печать. Номер задания « +{printer_name}-{job_id}».

    + +
    diff --git a/templates/ru/trailer.tmpl b/templates/ru/trailer.tmpl new file mode 100644 index 0000000000..fa4ad012d9 --- /dev/null +++ b/templates/ru/trailer.tmpl @@ -0,0 +1,6 @@ + +  +CUPS а также логотип CUPS являются зарегистрированными торговыми марками Apple Inc. Авторские права на CUPS принадлежат (2007-2011) компании Apple Inc. Все права защищены. + + + diff --git a/templates/ru/users.tmpl b/templates/ru/users.tmpl new file mode 100644 index 0000000000..c5b357501f --- /dev/null +++ b/templates/ru/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Доступ пользователей на {printer_name}

    + + + + + + + + + + +
    Пользователи: + +
    +Разрешить этим пользователям печать +Запретить этим пользователям печать +
    + +
    + +
    +
    diff --git a/templates/samba-export.tmpl b/templates/samba-export.tmpl new file mode 100644 index 0000000000..6515a4d3ae --- /dev/null +++ b/templates/samba-export.tmpl @@ -0,0 +1,55 @@ + + +
    + + + +

    Export Printers to Samba

    + +{error?

    Unable to export printers to Samba\:

    +
    {error}
    +

    Consult the error_log file for more information.

    : +

    This page allows you to export printers to Samba so that +Windows clients can access them through the Network +Neighborhood or Network Places icons on their +desktop. You must previously install the Windows PostScript +printer drivers as described in the cupsaddsmb(8) man page.

    } + + + + + + + + + + + + + + + + + + +
    Printers: +
    + Export All Printers +
    Samba Username: (required)
    Samba Password: (required)
    + +
    diff --git a/templates/samba-exported.tmpl b/templates/samba-exported.tmpl new file mode 100644 index 0000000000..6fa8eb4a69 --- /dev/null +++ b/templates/samba-exported.tmpl @@ -0,0 +1 @@ +

    Printers exported to samba successfully.

    diff --git a/templates/search.tmpl b/templates/search.tmpl new file mode 100644 index 0000000000..755269ea37 --- /dev/null +++ b/templates/search.tmpl @@ -0,0 +1,10 @@ +
    +{WHICH_JOBS?:} +{ORDER?:} + +

    Search in +{SEARCH_DEST?{SEARCH_DEST}:{SECTION=classes?Classes:{SECTION=jobs?Jobs:Printers}}}: +

    + +
    diff --git a/templates/set-printer-options-header.tmpl b/templates/set-printer-options-header.tmpl new file mode 100644 index 0000000000..3e7db4669c --- /dev/null +++ b/templates/set-printer-options-header.tmpl @@ -0,0 +1,26 @@ +
    + +

    Set Default Options for {printer_name}

    + +
    + + + +{HAVE_AUTOCONFIGURE?:} + + + +

    {[group_id] +{group}     }

    + +
    diff --git a/templates/set-printer-options-trailer.tmpl b/templates/set-printer-options-trailer.tmpl new file mode 100644 index 0000000000..11adc70125 --- /dev/null +++ b/templates/set-printer-options-trailer.tmpl @@ -0,0 +1,16 @@ +
    + + +
    + +
    diff --git a/templates/subscription-added.tmpl b/templates/subscription-added.tmpl new file mode 100644 index 0000000000..c288b3649b --- /dev/null +++ b/templates/subscription-added.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subscription {subscription_name} has been added successfully.

    + +
    diff --git a/templates/subscription-canceled.tmpl b/templates/subscription-canceled.tmpl new file mode 100644 index 0000000000..86f2c10691 --- /dev/null +++ b/templates/subscription-canceled.tmpl @@ -0,0 +1,5 @@ +
    + +

    Subscription #{notify_subscription_id} has been canceled.

    + +
    diff --git a/templates/test-page.tmpl b/templates/test-page.tmpl new file mode 100644 index 0000000000..59e314a8d4 --- /dev/null +++ b/templates/test-page.tmpl @@ -0,0 +1,8 @@ +
    + +

    Print Test Page On {printer_name}

    + +

    Test page sent; job ID is +{printer_name}-{job_id}.

    + +
    diff --git a/templates/trailer.tmpl b/templates/trailer.tmpl new file mode 100644 index 0000000000..100d9f7adc --- /dev/null +++ b/templates/trailer.tmpl @@ -0,0 +1,8 @@ + +  +CUPS and the CUPS logo are trademarks of +Apple Inc. CUPS is copyright 2007-2011 Apple +Inc. All rights reserved. + + + diff --git a/templates/users.tmpl b/templates/users.tmpl new file mode 100644 index 0000000000..0889f3f31e --- /dev/null +++ b/templates/users.tmpl @@ -0,0 +1,30 @@ +
    + +
    + + + +{IS_CLASS?:} + +

    Allowed Users For {printer_name}

    + + + + + + + + + + +
    Users: + +
    +Allow these users to print +Prevent these users from printing +
    + +
    + +
    +
    diff --git a/test/4.1-requests.test b/test/4.1-requests.test new file mode 100644 index 0000000000..860d43c078 --- /dev/null +++ b/test/4.1-requests.test @@ -0,0 +1,159 @@ +# +# "$Id: 4.1-requests.test 8235 2009-01-13 00:55:16Z 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 $scheme://$hostname:$port/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 "Bad IPP Version" + + # The operation to use + OPERATION get-jobs + + # The version number to use + VERSION 0.0 + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri ipp://localhost/printers + + # What statuses are OK? + STATUS server-error-version-not-supported +} +# +# End of "$Id: 4.1-requests.test 8235 2009-01-13 00:55:16Z mike $" +# diff --git a/test/4.2-cups-printer-ops.test b/test/4.2-cups-printer-ops.test new file mode 100644 index 0000000000..c858a8db2d --- /dev/null +++ b/test/4.2-cups-printer-ops.test @@ -0,0 +1,327 @@ +# +# "$Id: 4.2-cups-printer-ops.test 8536 2009-04-21 23:02:10Z 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 "Subscribe to Printer Events" + + # The operation to use + OPERATION Create-Printer-Subscription + 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/ + ATTR name requesting-user-name $user + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:// + ATTR keyword notify-events printer-added,printer-modified,printer-deleted + + # What statuses are OK? + STATUS successful-ok + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language + EXPECT notify-subscription-id +} +{ + # 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 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 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 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 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 +} +{ + # The name of the test... + NAME "Get Default Printer with no default set" + + # The operation to use + OPERATION cups-get-default + RESOURCE / + + # 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-not-found + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language +} +{ + # The name of the test... + NAME "Set Default Printer to Test1" + + # The operation to use + OPERATION cups-set-default + 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 "Get Default Printer" + + # The operation to use + OPERATION cups-get-default + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + + # What statuses are OK? + STATUS successful-ok + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language + EXPECT printer-name + EXPECT printer-uri-supported +} +{ + # The name of the test... + NAME "Get IPP/2.x Attributes for Printer Test1" + + # The operation to use + OPERATION get-printer-attributes + RESOURCE / + + # The IPP version to use + VERSION 2.0 + + # 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 media-col-default +} + +# +# End of "$Id: 4.2-cups-printer-ops.test 8536 2009-04-21 23:02:10Z mike $" +# diff --git a/test/4.3-job-ops.test b/test/4.3-job-ops.test new file mode 100644 index 0000000000..b3d8b75ad6 --- /dev/null +++ b/test/4.3-job-ops.test @@ -0,0 +1,330 @@ +# +# "$Id: 4.3-job-ops.test 8929 2009-12-15 22:40:37Z mike $" +# +# Verify that the IPP job operations work. +# +{ + # The name of the test... + NAME "Print PostScript Job with bad job-sheets value 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 + ATTR name job-sheets "none\,none" + + FILE testfile.ps + + # What statuses are OK? + STATUS client-error-bad-request +} +{ + # 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 JPEG 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 + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:/// + + 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 + EXPECT notify-subscription-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 + + GROUP job + ATTR keyword job-hold-until weekend + + 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 "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 "Print Held 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 + GROUP job + ATTR keyword job-hold-until indefinite + + 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 "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 +} +{ + # 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 + EXPECT !job-printer-uri +} +{ + # 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 printer-uri $scheme://$hostname:$port/ + ATTR keyword requested-attributes all + + # 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 + EXPECT job-printer-uri +} + +# +# End of "$Id: 4.3-job-ops.test 8929 2009-12-15 22:40:37Z mike $" +# diff --git a/test/4.4-subscription-ops.test b/test/4.4-subscription-ops.test new file mode 100644 index 0000000000..7ea3367ee0 --- /dev/null +++ b/test/4.4-subscription-ops.test @@ -0,0 +1,148 @@ +# +# "$Id: 4.4-subscription-ops.test 8145 2008-11-19 19:45:40Z mike $" +# +# Verify that the CUPS subscription operations work. +# +{ + # The name of the test... + NAME "Add Printer Subscription w/Lease" + + # The operation to use + OPERATION Create-Printer-Subscription + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:// + ATTR keyword notify-events printer-state-changed + ATTR integer notify-lease-duration 5 + + # What statuses are OK? + STATUS successful-ok + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language + EXPECT notify-subscription-id + DISPLAY notify-subscription-id +} +{ + # The name of the test... + NAME "Verify Subscription Expiration" + + # Delay test for 7 seconds to allow lease to expire... + DELAY 7 + + # The operation to use + OPERATION Get-Subscription-Attributes + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + ATTR integer notify-subscription-id $notify-subscription-id + + # 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 2 Printer Subscriptions w/Lease" + + # The operation to use + OPERATION Create-Printer-Subscription + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:// + ATTR keyword notify-events printer-state-changed + ATTR integer notify-lease-duration 5 + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:// + ATTR keyword notify-events printer-config-changed + ATTR integer notify-lease-duration 5 + + # What statuses are OK? + STATUS successful-ok + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language + EXPECT notify-subscription-id + DISPLAY notify-subscription-id +} +{ + # The name of the test... + NAME "List Printer Subscriptions" + + # The operation to use + OPERATION Get-Subscriptions + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + + # What statuses are OK? + STATUS successful-ok + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language + EXPECT notify-subscription-id + DISPLAY notify-subscription-id + EXPECT notify-printer-uri + DISPLAY notify-printer-uri + EXPECT notify-events + DISPLAY notify-events +} +{ + # The name of the test... + NAME "Check MaxSubscriptions limits" + + # The operation to use + OPERATION Create-Printer-Subscription + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $scheme://$hostname:$port/printers/Test1 + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:// + ATTR keyword notify-events printer-state-changed + ATTR integer notify-lease-duration 5 + + # What statuses are OK? + STATUS client-error-too-many-subscriptions + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language +} + +# +# End of "$Id: 4.4-subscription-ops.test 8145 2008-11-19 19:45:40Z mike $" +# diff --git a/test/5.1-lpadmin.sh b/test/5.1-lpadmin.sh new file mode 100755 index 0000000000..c96ccfcf6f --- /dev/null +++ b/test/5.1-lpadmin.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lpadmin command. +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +echo "Add Printer Test" +echo "" +echo " lpadmin -p Test3 -v file:/dev/null -E -m drv:///sample.drv/deskjet.ppd" +../systemv/lpadmin -p Test3 -v file:/dev/null -E -m drv:///sample.drv/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 0000000000..c1a3f6ce2d --- /dev/null +++ b/test/5.2-lpc.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lpc command. +# +# Copyright 2007 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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 0000000000..ef895ebc30 --- /dev/null +++ b/test/5.3-lpq.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lpq command. +# +# Copyright 2007 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +echo "LPQ Test" +echo "" +echo " lpq -P Test1" +../berkeley/lpq -P Test1 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 0000000000..83c8585bb8 --- /dev/null +++ b/test/5.4-lpstat.sh @@ -0,0 +1,43 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lpstat command. +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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 "" + +echo "LPSTAT Test" +echo "" +echo " lpstat -H" +server="`../systemv/lpstat -H 2>&1`" +if test $? != 0 -o "x$server" != xlocalhost:8631; then + echo " FAILED ($server)" + exit 1 +else + echo " PASSED ($server)" +fi +echo "" + +# +# End of "$Id$". +# diff --git a/test/5.5-lp.sh b/test/5.5-lp.sh new file mode 100755 index 0000000000..53b7bcbdda --- /dev/null +++ b/test/5.5-lp.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lp command. +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +echo "LP Default Test" +echo "" +echo " lp testfile.pdf" +../systemv/lp testfile.pdf 2>&1 +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +echo "LP Destination Test" +echo "" +echo " lp -d Test2 testfile.jpg" +../systemv/lp -d Test2 testfile.jpg 2>&1 +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +echo "LP Options Test" +echo "" +echo " lp -d Test1 -P 1-4 -o job-sheets=classified,classified testfile.pdf" +../systemv/lp -d Test1 -P 1-4 -o job-sheets=classified,classified testfile.pdf 2>&1 +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +echo "LP Flood Test ($1 times in parallel)" +echo "" +echo " lp -d Test1 testfile.jpg" +echo " lp -d Test2 testfile.jpg" +i=0 +while test $i -lt $1; do + echo " flood copy $i..." 1>&2 + + j=1 + while test $j -le $2; do + ../systemv/lp -d test-$j testfile.jpg 2>&1 + j=`expr $j + 1` + done + + ../systemv/lp -d Test1 testfile.jpg 2>&1 & + ../systemv/lp -d Test2 testfile.jpg 2>&1 & + lppid=$! + + i=`expr $i + 1` +done +wait $lppid +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +./waitjobs.sh + +# +# End of "$Id$". +# diff --git a/test/5.6-lpr.sh b/test/5.6-lpr.sh new file mode 100755 index 0000000000..b92a27d095 --- /dev/null +++ b/test/5.6-lpr.sh @@ -0,0 +1,86 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lpr command. +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +echo "LPR Default Test" +echo "" +echo " lpr testfile.pdf" +../berkeley/lpr testfile.pdf 2>&1 +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +echo "LPR Destination Test" +echo "" +echo " lpr -P Test2 testfile.jpg" +../berkeley/lpr -P Test2 testfile.jpg 2>&1 +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +echo "LPR Options Test" +echo "" +echo " lpr -P Test1 -o number-up=4 -o job-sheets=standard,none testfile.pdf" +../berkeley/lpr -P Test1 -o number-up=4 -o job-sheets=standard,none testfile.pdf 2>&1 +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +echo "LPR Flood Test ($1 times in parallel)" +echo "" +echo " lpr -P Test1 testfile.jpg" +echo " lpr -P Test2 testfile.jpg" +i=0 +while test $i -lt $1; do + echo " flood copy $i..." 1>&2 + + j=1 + while test $j -le $2; do + ../berkeley/lpr -P test-$j testfile.jpg 2>&1 + j=`expr $j + 1` + done + + ../berkeley/lpr -P Test1 testfile.jpg 2>&1 & + ../berkeley/lpr -P Test2 testfile.jpg 2>&1 & + lprpid=$! + + i=`expr $i + 1` +done +wait $lppid +if test $? != 0; then + echo " FAILED" + exit 1 +else + echo " PASSED" +fi +echo "" + +./waitjobs.sh + +# +# End of "$Id$". +# diff --git a/test/5.7-lprm.sh b/test/5.7-lprm.sh new file mode 100755 index 0000000000..e1ba395dfa --- /dev/null +++ b/test/5.7-lprm.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lprm command. +# +# Copyright 2007 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +echo "LPRM Current Test" +echo "" +echo " lpr -o job-hold-until=indefinite testfile.jpg" +../berkeley/lpr -o job-hold-until=indefinite testfile.jpg 2>&1 +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 " lpr -P Test1 -o job-hold-until=indefinite testfile.jpg" +../berkeley/lpr -P Test1 -o job-hold-until=indefinite testfile.jpg 2>&1 +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 0000000000..ddc346040a --- /dev/null +++ b/test/5.8-cancel.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the cancel command. +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +echo "Cancel Destination Test" +echo "" +echo " lp -d Test1 -o job-hold-until=indefinite testfile.jpg" +../systemv/lp -d Test1 -o job-hold-until=indefinite testfile.jpg 2>&1 +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 0000000000..d9bff8308b --- /dev/null +++ b/test/5.9-lpinfo.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# "$Id$" +# +# Test the lpinfo command. +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1997-2005 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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 "" + +echo "LPINFO Drivers Test" +echo "" +echo " lpinfo -m | grep -q sample.drv" +../systemv/lpinfo -m | grep -q sample.drv 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 0000000000..43ea400746 --- /dev/null +++ b/test/Dependencies @@ -0,0 +1,5 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +ipptest.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h +ipptest.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h ../cups/array.h +ipptest.o: ../cups/file.h ../cups/language.h ../cups/language.h diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000000..5724cd6c4e --- /dev/null +++ b/test/Makefile @@ -0,0 +1,117 @@ +# +# "$Id$" +# +# IPP test makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 1997-2006 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + + +# +# Make all targets... +# + +all: ipptest + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# 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: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Unnstall all targets... +# + +uninstall: + + +# +# ipptest +# + +ipptest: ipptest.o ../cups/libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o ipptest ipptest.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# 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 0000000000..87d94a5b65 --- /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 0000000000..d15bb7d4b6 --- /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 0000000000..514924d423 --- /dev/null +++ b/test/create-job-timeout.test @@ -0,0 +1,54 @@ +# 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 + ATTR name job-sheets unclassified,unclassified + + # What statuses are OK? + STATUS successful-ok + + # 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 successful-ok +} diff --git a/test/create-job.test b/test/create-job.test new file mode 100644 index 0000000000..61336c63bf --- /dev/null +++ b/test/create-job.test @@ -0,0 +1,52 @@ +# 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 successful-ok + + # 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 successful-ok +} diff --git a/test/create-printer-subscription.test b/test/create-printer-subscription.test new file mode 100644 index 0000000000..c6427ef76e --- /dev/null +++ b/test/create-printer-subscription.test @@ -0,0 +1,36 @@ +# +# "$Id: 4.4-subscription-ops.test 4840 2005-11-14 21:53:30Z mike $" +# +# Verify that the CUPS subscription operations work. +# +{ + # The name of the test... + NAME "Add Printer Subscription w/Lease" + + # The operation to use + OPERATION Create-Printer-Subscription + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $uri + + GROUP subscription + ATTR uri notify-recipient testnotify://nowait + ATTR keyword notify-events printer-state-changed + + # What statuses are OK? + STATUS successful-ok + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language + EXPECT notify-subscription-id + DISPLAY notify-subscription-id +} + +# +# End of "$Id: 4.4-subscription-ops.test 4840 2005-11-14 21:53:30Z mike $" +# diff --git a/test/get-devices.test b/test/get-devices.test new file mode 100644 index 0000000000..76bb5ec762 --- /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 0000000000..ba62bd7f3d --- /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 +# ATTR keyword requested-attributes job-media-sheets-completed,job-state + + # What statuses are OK? + #STATUS ok + #STATUS ok-subst + + # What attributes do we expect? + EXPECT job-uri + EXPECT job-state +} diff --git a/test/get-job-attributes2.test b/test/get-job-attributes2.test new file mode 100644 index 0000000000..6a8673f88d --- /dev/null +++ b/test/get-job-attributes2.test @@ -0,0 +1,28 @@ +# 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 job-uri $uri + + # 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-jobs.test b/test/get-jobs.test new file mode 100644 index 0000000000..1b4ed20104 --- /dev/null +++ b/test/get-jobs.test @@ -0,0 +1,21 @@ +# Get list of jobs +{ + # The name of the test... + NAME "Get-Jobs" + + # The resource to use for the POST + # RESOURCE /admin + + # The operation to use + OPERATION Get-Jobs + + # 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 keyword which-jobs completed + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppd-printer.test b/test/get-ppd-printer.test new file mode 100644 index 0000000000..4f723f88bb --- /dev/null +++ b/test/get-ppd-printer.test @@ -0,0 +1,20 @@ +# Get printer PPD file using CUPS-Get-PPD +{ + # The name of the test... + NAME "Get printer PPD file using CUPS-Get-PPD" + + # The resource to use for the POST + # RESOURCE /admin + + # The operation to use + OPERATION CUPS-Get-PPD + + # 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 +} diff --git a/test/get-ppd.test b/test/get-ppd.test new file mode 100644 index 0000000000..24a935e4d9 --- /dev/null +++ b/test/get-ppd.test @@ -0,0 +1,20 @@ +# Get PPD file using CUPS-get-ppd +{ + # The name of the test... + NAME "Get PPD file using CUPS-get-ppd" + + # The resource to use for the POST + # RESOURCE /admin + + # The operation to use + OPERATION CUPS-get-ppd + + # Attributes, starting in the operation group... + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR name ppd-name $ENV[ppd-name] + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppds-drv-only.test b/test/get-ppds-drv-only.test new file mode 100644 index 0000000000..ccb1828d00 --- /dev/null +++ b/test/get-ppds-drv-only.test @@ -0,0 +1,24 @@ +# Get drv-based PPD files using CUPS-Get-PPDs +{ + # The name of the test... + NAME "Get drv-based 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 + ATTR name include-schemes drv + + # What statuses are OK? + STATUS ok + STATUS ok-subst + + EXPECT ppd-name +} diff --git a/test/get-ppds-language.test b/test/get-ppds-language.test new file mode 100644 index 0000000000..2ed011866e --- /dev/null +++ b/test/get-ppds-language.test @@ -0,0 +1,21 @@ +# Get PPD files using CUPS-Get-PPDs and language +{ + # The name of the test... + NAME "Get PPD files using CUPS-Get-PPDs and language" + + # 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 + ATTR language ppd-natural-language $ENV[language] + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppds-make-and-model.test b/test/get-ppds-make-and-model.test new file mode 100644 index 0000000000..c57b14736b --- /dev/null +++ b/test/get-ppds-make-and-model.test @@ -0,0 +1,21 @@ +# Get PPD files using CUPS-Get-PPDs and model +{ + # The name of the test... + NAME "Get PPD files using CUPS-Get-PPDs and model" + + # 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 + ATTR text ppd-make-and-model $ENV[model] + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppds-make.test b/test/get-ppds-make.test new file mode 100644 index 0000000000..ac3f736e41 --- /dev/null +++ b/test/get-ppds-make.test @@ -0,0 +1,21 @@ +# Get PPD files using CUPS-Get-PPDs and make +{ + # The name of the test... + NAME "Get PPD files using CUPS-Get-PPDs and make" + + # 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 + ATTR text ppd-make $ENV[make] + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppds-product.test b/test/get-ppds-product.test new file mode 100644 index 0000000000..b0535f7e1a --- /dev/null +++ b/test/get-ppds-product.test @@ -0,0 +1,21 @@ +# Get PPD files using CUPS-Get-PPDs and Product +{ + # The name of the test... + NAME "Get PPD files using CUPS-Get-PPDs and Product" + + # 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 + ATTR text ppd-product $ENV[product] + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppds-psversion.test b/test/get-ppds-psversion.test new file mode 100644 index 0000000000..b7f93b670b --- /dev/null +++ b/test/get-ppds-psversion.test @@ -0,0 +1,21 @@ +# Get PPD files using CUPS-Get-PPDs and PSVersion +{ + # The name of the test... + NAME "Get PPD files using CUPS-Get-PPDs and PSVersion" + + # 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 + ATTR text ppd-psversion $ENV[psversion] + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-ppds.test b/test/get-ppds.test new file mode 100644 index 0000000000..90f59eb6e2 --- /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-2.0.test b/test/get-printer-attributes-2.0.test new file mode 100644 index 0000000000..c123c3e102 --- /dev/null +++ b/test/get-printer-attributes-2.0.test @@ -0,0 +1,48 @@ +# 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 + + # The version to use + VERSION 2.0 + + # 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 keyword requested-attributes printer-defaults,printer-description,media-col-database + + # 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 media-col-default + 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 +} diff --git a/test/get-printer-attributes.test b/test/get-printer-attributes.test new file mode 100644 index 0000000000..54ce778b29 --- /dev/null +++ b/test/get-printer-attributes.test @@ -0,0 +1,41 @@ +# 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 pdl-override-supported + EXPECT printer-is-accepting-jobs + EXPECT printer-name + EXPECT printer-state + EXPECT printer-state-reasons + EXPECT printer-up-time + EXPECT printer-uri-supported + EXPECT queued-job-count + EXPECT uri-authentication-supported + EXPECT uri-security-supported +} diff --git a/test/get-printers.test b/test/get-printers.test new file mode 100644 index 0000000000..54f8df4c8f --- /dev/null +++ b/test/get-printers.test @@ -0,0 +1,19 @@ +# Get printer attributes using get-printer-attributes +{ + # The name of the test... + NAME "CUPS-Get-Printers" + + # The resource to use for the POST + # RESOURCE /admin + + # The operation to use + OPERATION CUPS-Get-Printers + + # Attributes, starting in the operation group... + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + + # What statuses are OK? + STATUS successful-ok +} diff --git a/test/get-subscriptions.test b/test/get-subscriptions.test new file mode 100644 index 0000000000..686059dfa2 --- /dev/null +++ b/test/get-subscriptions.test @@ -0,0 +1,21 @@ +# Get subscriptions using Get-Subscriptions +{ + # The name of the test... + NAME "Get subscriptions using Get-Subscriptions" + + # The resource to use for the POST + # RESOURCE /admin + + # The operation to use + OPERATION Get-Subscriptions + + # 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/ipp-backend.test b/test/ipp-backend.test new file mode 100644 index 0000000000..c2642d3756 --- /dev/null +++ b/test/ipp-backend.test @@ -0,0 +1,22 @@ +# 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 + ATTR keyword requested-attributes com.apple.print.recoverable-message,copies-supported,document-format-supported,marker-colors,marker-levels,marker-message,marker-names,marker-types,printer-is-accepting-jobs,printer-state,printer-state-message,printer-state-reasons + + # What statuses are OK? + STATUS successful-ok + STATUS successful-ok-ignored-or-substituted-attributes +} diff --git a/test/ipptest.c b/test/ipptest.c new file mode 100644 index 0000000000..25610a56a4 --- /dev/null +++ b/test/ipptest.c @@ -0,0 +1,1278 @@ +/* + * "$Id$" + * + * IPP test command for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Parse options and do tests. + * do_tests() - Do tests as specified in the test file. + * expect_matches() - Return true if the tag matches the specification. + * get_token() - Get a token from a file. + * print_attr() - Print an attribute on the screen. + * print_col() - Print a collection attribute on the screen. + * usage() - Show program usage. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifndef O_BINARY +# define O_BINARY 0 +#endif /* !O_BINARY */ + + +/* + * Types... + */ + +typedef struct _cups_expect_s /**** Expected attribute info ****/ +{ + int not_expect; /* Don't expect attribute? */ + char *name, /* Attribute name */ + *of_type, /* Type name */ + *same_count_as, /* Parallel attribute name */ + *if_defined; /* Only required if variable defined */ +} _cups_expect_t; + + +/* + * Globals... + */ + +int Chunking = 0; /* Use chunked requests */ +int Verbosity = 0; /* Show all attributes? */ + + +/* + * Local functions... + */ + +static int do_tests(const char *uri, const char *testfile); +static int expect_matches(_cups_expect_t *expect, ipp_tag_t value_tag); +static char *get_token(FILE *fp, char *buf, int buflen, + int *linenum); +static void print_attr(ipp_attribute_t *attr); +static void print_col(ipp_t *col); +static void usage(void); + + +/* + * 'main()' - Parse options and do tests. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int status; /* Status of tests... */ + char *opt; /* Current option */ + const char *uri, /* URI to use */ + *testfile; /* Test file to use */ + int interval; /* Test interval */ + + + /* + * We need at least: + * + * testipp URL testfile + */ + + uri = NULL; + testfile = NULL; + status = 0; + interval = 0; + + for (i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + for (opt = argv[i] + 1; *opt; opt ++) + { + switch (*opt) + { + case 'c' : /* Enable HTTP chunking */ + Chunking = 1; + break; + + case 'd' : /* Define a variable */ + i ++; + + if (i >= argc) + { + fputs("ipptest: Missing name=value for \"-d\"!\n", stderr); + usage(); + } + else + putenv(argv[i]); + break; + + case 'i' : /* Test every N seconds */ + i++; + + if (i >= argc) + { + fputs("ipptest: Missing seconds for \"-i\"!\n", stderr); + usage(); + } + else + interval = atoi(argv[i]); + break; + + case 'v' : /* Be verbose */ + Verbosity ++; + break; + + default : + fprintf(stderr, "ipptest: Unknown option \"-%c\"!\n", *opt); + usage(); + break; + } + } + } + else if (!strncmp(argv[i], "ipp://", 6) || + !strncmp(argv[i], "http://", 7) || + !strncmp(argv[i], "https://", 8)) + { + /* + * Set URI... + */ + + if (!testfile && uri) + { + fputs("ipptest: May only specify a single URI before a test!\n", + stderr); + usage(); + } + + uri = argv[i]; + testfile = NULL; + } + else + { + /* + * Run test... + */ + + testfile = argv[i]; + + if (!do_tests(uri, testfile)) + status ++; + } + } + + if (!uri || !testfile) + usage(); + + /* + * Loop if the interval is set... + */ + + if (interval) + { + for (;;) + { + sleep(interval); + do_tests(uri, testfile); + } + } + + /* + * Exit... + */ + + return (status); +} + + +/* + * 'do_tests()' - Do tests as specified in the test file. + */ + +static 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 linenum; /* Current line number */ + int version; /* IPP version number to use */ + http_t *http; /* HTTP connection to server */ + char scheme[HTTP_MAX_URI], /* URI scheme */ + 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 */ + *found; /* Found attribute */ + 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 */ + _cups_expect_t expects[100], /* Expected attributes */ + *expect, /* Current expected attribute */ + *last_expect; /* Last EXPECT (for predicates) */ + int num_displayed; /* Number of displayed attributes */ + char *displayed[100]; /* Displayed 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 */ + int subscription_id; /* Subscription 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... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, + sizeof(userpass), server, sizeof(server), &port, resource, + sizeof(resource)); + if ((http = httpConnect(server, port)) == NULL) + { + printf("Unable to connect to %s on port %d - %s\n", server, port, + strerror(errno)); + fclose(fp); + return (0); + } + + /* + * Loop on tests... + */ + + printf("\"%s\":\n", testfile); + pass = 1; + job_id = 0; + subscription_id = 0; + version = 11; + linenum = 1; + + while (get_token(fp, token, sizeof(token), &linenum) != NULL) + { + /* + * Expect an open brace... + */ + + if (strcmp(token, "{")) + { + printf("Unexpected token %s seen on line %d - aborting test!\n", token, + linenum); + httpClose(http); + return (0); + } + + /* + * Initialize things... + */ + + httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, + sizeof(userpass), server, sizeof(server), &port, resource, + sizeof(resource)); + + request = ippNew(); + op = (ipp_op_t)0; + group = IPP_TAG_ZERO; + num_statuses = 0; + num_expects = 0; + num_displayed = 0; + last_expect = NULL; + 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), &linenum) != NULL) + { + if (strcasecmp(token, "EXPECT") && + strcasecmp(token, "IF-DEFINED") && + strcasecmp(token, "OF-TYPE") && + strcasecmp(token, "SAME-COUNT-AS")) + last_expect = NULL; + + if (!strcmp(token, "}")) + break; + else if (!strcasecmp(token, "NAME")) + { + /* + * Name of test... + */ + + get_token(fp, name, sizeof(name), &linenum); + } + else if (!strcasecmp(token, "VERSION")) + { + /* + * IPP version number for test... + */ + + int major, minor; /* Major/minor IPP version */ + + + get_token(fp, temp, sizeof(temp), &linenum); + if (sscanf(temp, "%d.%d", &major, &minor) == 2 && + major >= 0 && minor >= 0 && minor < 10) + version = major * 10 + minor; + else + { + printf("Bad version %s seen on line %d - aborting test!\n", token, + linenum); + httpClose(http); + ippDelete(request); + return (0); + } + } + else if (!strcasecmp(token, "RESOURCE")) + { + /* + * Resource name... + */ + + get_token(fp, resource, sizeof(resource), &linenum); + } + else if (!strcasecmp(token, "OPERATION")) + { + /* + * Operation... + */ + + get_token(fp, token, sizeof(token), &linenum); + op = ippOpValue(token); + } + else if (!strcasecmp(token, "GROUP")) + { + /* + * Attribute group... + */ + + get_token(fp, token, sizeof(token), &linenum); + value = ippTagValue(token); + + if (value == group) + ippAddSeparator(request); + + group = value; + } + else if (!strcasecmp(token, "DELAY")) + { + /* + * Delay before operation... + */ + + int delay; + + get_token(fp, token, sizeof(token), &linenum); + if ((delay = atoi(token)) > 0) + sleep(delay); + } + else if (!strcasecmp(token, "ATTR")) + { + /* + * Attribute... + */ + + get_token(fp, token, sizeof(token), &linenum); + value = ippTagValue(token); + get_token(fp, attr, sizeof(attr), &linenum); + get_token(fp, temp, sizeof(temp), &linenum); + + 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)) + { + strlcpy(tokenptr, uri, sizeof(token) - (tokenptr - token)); + tempptr += 4; + } + else if (!strncasecmp(tempptr + 1, "scheme", 6) || + !strncasecmp(tempptr + 1, "method", 6)) + { + strlcpy(tokenptr, scheme, sizeof(token) - (tokenptr - token)); + tempptr += 7; + } + else if (!strncasecmp(tempptr + 1, "username", 8)) + { + strlcpy(tokenptr, userpass, sizeof(token) - (tokenptr - token)); + tempptr += 9; + } + else if (!strncasecmp(tempptr + 1, "hostname", 8)) + { + strlcpy(tokenptr, server, sizeof(token) - (tokenptr - token)); + tempptr += 9; + } + else if (!strncasecmp(tempptr + 1, "port", 4)) + { + snprintf(tokenptr, sizeof(token) - (tokenptr - token), + "%d", port); + tempptr += 5; + } + else if (!strncasecmp(tempptr + 1, "resource", 8)) + { + strlcpy(tokenptr, resource, sizeof(token) - (tokenptr - token)); + tempptr += 9; + } + else if (!strncasecmp(tempptr + 1, "job-id", 6)) + { + snprintf(tokenptr, sizeof(token) - (tokenptr - token), + "%d", job_id); + tempptr += 7; + } + else if (!strncasecmp(tempptr + 1, "notify-subscription-id", 22)) + { + snprintf(tokenptr, sizeof(token) - (tokenptr - token), + "%d", subscription_id); + tempptr += 23; + } + else if (!strncasecmp(tempptr + 1, "user", 4)) + { + strlcpy(tokenptr, cupsUser(), sizeof(token) - (tokenptr - token)); + tempptr += 5; + } + else if (!strncasecmp(tempptr + 1, "ENV[", 4)) + { + char *end; /* End of $ENV[name] */ + + + if ((end = strchr(tempptr + 5, ']')) != NULL) + { + *end++ = '\0'; + strlcpy(tokenptr, + getenv(tempptr + 5) ? getenv(tempptr + 5) : tempptr + 5, + sizeof(token) - (tokenptr - token)); + tempptr = end; + } + else + { + *tokenptr++ = *tempptr++; + *tokenptr = '\0'; + } + } + else + { + *tokenptr++ = *tempptr++; + *tokenptr = '\0'; + } + + tokenptr += strlen(tokenptr); + } + else + { + *tokenptr++ = *tempptr++; + *tokenptr = '\0'; + } + + switch (value) + { + case IPP_TAG_BOOLEAN : + if (!strcasecmp(token, "true")) + 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 : + if (!strchr(token, ',')) + ippAddString(request, group, value, attr, NULL, token); + else + { + /* + * Multiple string values... + */ + + int num_values; /* Number of values */ + char *values[100], /* Values */ + *ptr; /* Pointer to next value */ + + + values[0] = token; + num_values = 1; + + for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ',')) + { + *ptr++ = '\0'; + values[num_values] = ptr; + num_values ++; + } + + ippAddStrings(request, group, value, attr, num_values, + NULL, (const char **)values); + } + break; + } + } + else if (!strcasecmp(token, "FILE")) + { + /* + * File... + */ + + get_token(fp, filename, sizeof(filename), &linenum); + } + else if (!strcasecmp(token, "STATUS") && + num_statuses < (int)(sizeof(statuses) / sizeof(statuses[0]))) + { + /* + * Status... + */ + + get_token(fp, token, sizeof(token), &linenum); + statuses[num_statuses] = ippErrorValue(token); + num_statuses ++; + } + else if (!strcasecmp(token, "EXPECT")) + { + /* + * Expected attributes... + */ + + if (num_expects >= (int)(sizeof(expects) / sizeof(expects[0]))) + { + fprintf(stderr, "ipptest: Too many EXPECT's on line %d\n", linenum); + httpClose(http); + ippDelete(request); + return (0); + } + + get_token(fp, token, sizeof(token), &linenum); + + last_expect = expects + num_expects; + num_expects ++; + + if (token[0] == '!') + { + last_expect->not_expect = 1; + last_expect->name = strdup(token + 1); + } + else + { + last_expect->not_expect = 0; + last_expect->name = strdup(token); + } + + last_expect->of_type = NULL; + last_expect->same_count_as = NULL; + last_expect->if_defined = NULL; + } + else if (!strcasecmp(token, "OF-TYPE")) + { + get_token(fp, token, sizeof(token), &linenum); + + if (last_expect) + last_expect->of_type = strdup(token); + else + { + fprintf(stderr, + "ipptest: OF-TYPE without a preceding EXPECT on line %d\n", + linenum); + httpClose(http); + ippDelete(request); + return (0); + } + } + else if (!strcasecmp(token, "SAME-COUNT-AS")) + { + get_token(fp, token, sizeof(token), &linenum); + + if (last_expect) + last_expect->same_count_as = strdup(token); + else + { + fprintf(stderr, + "ipptest: SAME-COUNT-AS without a preceding EXPECT on line " + "%d\n", linenum); + httpClose(http); + ippDelete(request); + return (0); + } + } + else if (!strcasecmp(token, "IF-DEFINED")) + { + get_token(fp, token, sizeof(token), &linenum); + + if (last_expect) + last_expect->if_defined = strdup(token); + else + { + fprintf(stderr, + "ipptest: IF-DEFINED without a preceding EXPECT on line %d\n", + linenum); + httpClose(http); + ippDelete(request); + return (0); + } + } + else if (!strcasecmp(token, "DISPLAY") && + num_displayed < (int)(sizeof(displayed) / sizeof(displayed[0]))) + { + /* + * Display attributes... + */ + + get_token(fp, token, sizeof(token), &linenum); + displayed[num_displayed] = strdup(token); + num_displayed ++; + } + else + { + fprintf(stderr, + "ipptest: Unexpected token %s seen on line %d - aborting " + "test!\n", token, linenum); + httpClose(http); + ippDelete(request); + return (0); + } + } + + /* + * Submit the IPP request... + */ + + request->request.op.version[0] = version / 10; + request->request.op.version[1] = version % 10; + request->request.op.operation_id = op; + request->request.op.request_id = 1; + + if (Verbosity) + { + printf(" %s:\n", ippOpString(op)); + + for (attrptr = request->attrs; attrptr; attrptr = attrptr->next) + print_attr(attrptr); + } + + printf(" %-60.60s [", name); + fflush(stdout); + + if (Chunking) + { + http_status_t status = cupsSendRequest(http, request, resource, 0); + + if (status == HTTP_CONTINUE && filename[0]) + { + int fd; /* File to send */ + char buffer[8192]; /* Copy buffer */ + ssize_t bytes; /* Bytes read/written */ + + + if ((fd = open(filename, O_RDONLY | O_BINARY)) >= 0) + { + while ((bytes = read(fd, buffer, sizeof(buffer))) > 0) + if ((status = cupsWriteRequestData(http, buffer, + bytes)) != HTTP_CONTINUE) + break; + } + else + status = HTTP_ERROR; + } + + ippDelete(request); + + if (status == HTTP_CONTINUE) + response = cupsGetResponse(http, resource); + else + response = NULL; + } + else if (filename[0]) + response = cupsDoFileRequest(http, request, resource, filename); + else + response = cupsDoIORequest(http, request, resource, -1, + Verbosity ? 1 : -1); + + if (response == NULL) + { + time_t curtime; + + curtime = time(NULL); + + puts("FAIL]"); + printf(" ERROR %04x (%s) @ %s\n", cupsLastError(), + cupsLastErrorString(), ctime(&curtime)); + pass = 0; + } + else + { + if (http->version != HTTP_1_1) + pass = 0; + + if ((attrptr = ippFindAttribute(response, "job-id", + IPP_TAG_INTEGER)) != NULL) + job_id = attrptr->values[0].integer; + + if ((attrptr = ippFindAttribute(response, "notify-subscription-id", + IPP_TAG_INTEGER)) != NULL) + subscription_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) + pass = 0; + else + { + for (i = num_expects, expect = expects; i > 0; i --, expect ++) + { + if (expect->if_defined && !getenv(expect->if_defined)) + continue; + + found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO); + + if ((found == NULL) != expect->not_expect || + (found && !expect_matches(expect, found->value_tag))) + { + pass = 0; + break; + } + + if (found && expect->same_count_as) + { + attrptr = ippFindAttribute(response, expect->same_count_as, + IPP_TAG_ZERO); + + if (!attrptr || attrptr->num_values != found->num_values) + { + pass = 0; + break; + } + } + } + } + + if (pass) + { + puts("PASS]"); + printf(" RECEIVED: %lu bytes in response\n", + (unsigned long)ippLength(response)); + + if (Verbosity) + { + for (attrptr = response->attrs; + attrptr != NULL; + attrptr = attrptr->next) + { + print_attr(attrptr); + } + } + else if (num_displayed > 0) + { + for (attrptr = response->attrs; + attrptr != NULL; + attrptr = attrptr->next) + { + if (attrptr->name) + { + for (i = 0; i < num_displayed; i ++) + { + if (!strcmp(displayed[i], attrptr->name)) + { + print_attr(attrptr); + break; + } + } + } + } + } + } + else + { + puts("FAIL]"); + printf(" RECEIVED: %lu bytes in response\n", + (unsigned long)ippLength(response)); + + if (http->version != HTTP_1_1) + printf(" BAD HTTP VERSION (%d.%d)\n", http->version / 100, + http->version % 100); + + for (i = 0; i < num_statuses; i ++) + if (response->request.status.status_code == statuses[i]) + break; + + if (i == num_statuses && num_statuses > 0) + puts(" BAD STATUS"); + + printf(" status-code = %04x (%s)\n", + cupsLastError(), ippErrorString(cupsLastError())); + + for (i = num_expects, expect = expects; i > 0; i --, expect ++) + { + if (expect->if_defined && !getenv(expect->if_defined)) + continue; + + found = ippFindAttribute(response, expect->name, IPP_TAG_ZERO); + + if ((found == NULL) != expect->not_expect) + { + if (expect->not_expect) + printf(" NOT EXPECTED: %s\n", expect->name); + else + printf(" EXPECTED: %s\n", expect->name); + } + else if (found) + { + if (!expect_matches(expect, found->value_tag)) + printf(" EXPECTED: %s of type %s but got %s\n", + expect->name, expect->of_type, + ippTagString(found->value_tag)); + else if (expect->same_count_as) + { + attrptr = ippFindAttribute(response, expect->same_count_as, + IPP_TAG_ZERO); + + if (!attrptr) + printf(" EXPECTED: %s (%d values) same count as %s " + "(not returned)\n", + expect->name, found->num_values, expect->same_count_as); + else if (attrptr->num_values != found->num_values) + printf(" EXPECTED: %s (%d values) same count as %s " + "(%d values)\n", + expect->name, found->num_values, expect->same_count_as, + attrptr->num_values); + } + } + } + + for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next) + print_attr(attrptr); + } + + ippDelete(response); + } + + for (i = num_expects, expect = expects; i > 0; i --, expect ++) + { + free(expect->name); + if (expect->of_type) + free(expect->of_type); + if (expect->same_count_as) + free(expect->same_count_as); + if (expect->if_defined) + free(expect->if_defined); + } + if (!pass) + break; + } + + fclose(fp); + httpClose(http); + + return (pass); +} + + +/* + * 'expect_matches()' - Return true if the tag matches the specification. + */ + +static int /* O - 1 if matches, 0 otherwise */ +expect_matches( + _cups_expect_t *expect, /* I - Expected attribute */ + ipp_tag_t value_tag) /* I - Value tag for attribute */ +{ + int match; /* Match? */ + char *of_type, /* Type name to match */ + *next; /* Next name to match */ + + + /* + * If we don't expect a particular type, return immediately... + */ + + if (!expect->of_type) + return (1); + + /* + * Parse the "of_type" value since the string can contain multiple attribute + * types separated by "|"... + */ + + for (of_type = expect->of_type, match = 0; !match && of_type; of_type = next) + { + /* + * Find the next separator, and set it (temporarily) to nul if present. + */ + + if ((next = strchr(of_type, '|')) != NULL) + *next = '\0'; + + /* + * Support some meta-types to make it easier to write the test file. + */ + + if (!strcmp(of_type, "text")) + match = value_tag == IPP_TAG_TEXTLANG || value_tag == IPP_TAG_TEXT; + else if (!strcmp(of_type, "name")) + match = value_tag == IPP_TAG_NAMELANG || value_tag == IPP_TAG_NAME; + else if (!strcmp(of_type, "collection")) + match = value_tag == IPP_TAG_BEGIN_COLLECTION; + else + match = value_tag == ippTagValue(of_type); + + /* + * Restore the separator if we have one... + */ + + if (next) + *next++ = '|'; + } + + return (match); +} + + +/* + * 'get_token()' - Get a token from a file. + */ + +static 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 *linenum) /* IO - Current line number */ +{ + 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))) + { + if (ch == '\n') + (*linenum) ++; + } + + /* + * 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; + + (*linenum) ++; + } + 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. + */ + +static void +print_attr(ipp_attribute_t *attr) /* I - Attribute to print */ +{ + int i; /* Looping var */ + + + if (attr->name == NULL) + { + puts(" -- separator --"); + return; + } + + printf(" %s (%s%s) = ", attr->name, + attr->num_values > 1 ? "1setOf " : "", + ippTagString(attr->value_tag)); + + 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; + + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + putchar(' '); + + print_col(attr->values[i].collection); + } + break; + + default : + break; /* anti-compiler-warning-code */ + } + + putchar('\n'); +} + + +/* + * 'print_col()' - Print a collection attribute on the screen. + */ + +static void +print_col(ipp_t *col) /* I - Collection attribute to print */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* Current attribute in collection */ + + + putchar('{'); + for (attr = col->attrs; attr; attr = attr->next) + { + printf("%s(%s%s)=", attr->name, attr->num_values > 1 ? "1setOf " : "", + ippTagString(attr->value_tag)); + + 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; + + case IPP_TAG_BEGIN_COLLECTION : + for (i = 0; i < attr->num_values; i ++) + { + print_col(attr->values[i].collection); + putchar(' '); + } + break; + + default : + break; /* anti-compiler-warning-code */ + } + } + + putchar('}'); +} + + +/* + * 'usage()' - Show program usage. + */ + +static void +usage(void) +{ + fputs("Usage: ipptest [options] URL testfile [ ... testfileN ]\n", stderr); + fputs("Options:\n", stderr); + fputs("\n", stderr); + fputs("-c Send requests using chunking.\n", stderr); + fputs("-d name=value Define variable.\n", stderr); + fputs("-i seconds Repeat the last test file with the given interval.\n", + stderr); + fputs("-v Show all attributes in response, even on success.\n", + stderr); + + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/test/print-job-hold.test b/test/print-job-hold.test new file mode 100644 index 0000000000..6bdaa83815 --- /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-media-col.test b/test/print-job-media-col.test new file mode 100644 index 0000000000..373825ab3c --- /dev/null +++ b/test/print-job-media-col.test @@ -0,0 +1,39 @@ +# Print a test page using Print-Job + media-col +# +# Usage: +# +# ./ipptest -f filename ipp://... print-job-media-col.test +{ + # The name of the test... + NAME "Print test page using Print-Job + media-col" + + # The operation to use + OPERATION Print-Job + + # Attributes, starting in the operation group... + GROUP operation-attributes-tag + 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/octet-stream + + GROUP job-attributes-tag + ATTR collection media-col { + MEMBER collection media-size { + # 4x6 + MEMBER integer x-dimension 10160 + MEMBER integer y-dimension 15240 + } + } + + FILE $filename + + # What statuses are OK? + STATUS successful-ok + STATUS successful-ok-ignored-or-substituted-attributes + + # What attributes do we expect? + EXPECT job-id OF-TYPE integer WITH-VALUE >0 + EXPECT job-uri OF-TYPE uri +} diff --git a/test/print-job.test b/test/print-job.test new file mode 100644 index 0000000000..a0c814e534 --- /dev/null +++ b/test/print-job.test @@ -0,0 +1,32 @@ +# 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 testfile.ps + + # What statuses are OK? + STATUS successful-ok + STATUS successful-ok-ignored-or-substituted-attributes + + # What attributes do we expect? + EXPECT job-id + EXPECT job-uri +} diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh new file mode 100755 index 0000000000..79a4cfe1ae --- /dev/null +++ b/test/run-stp-tests.sh @@ -0,0 +1,869 @@ +#!/bin/sh +# +# "$Id$" +# +# Perform the complete set of IPP compliance tests specified in the +# CUPS Software Test Plan. +# +# Copyright 2007-2011 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +argcount=$# + +# +# Make the IPP test program... +# + +make + +# +# Solaris has a non-POSIX grep in /bin... +# + +if test -x /usr/xpg4/bin/grep; then + GREP=/usr/xpg4/bin/grep +else + GREP=grep +fi + +# +# Figure out the proper echo options... +# + +if (echo "testing\c"; echo 1,2,3) | $GREP c >/dev/null; then + ac_n=-n + ac_c= +else + ac_n= + ac_c='\c' +fi + +# +# Greet the tester... +# + +echo "Welcome to the CUPS Automated Test Script." +echo "" +echo "Before we begin, it is important that you understand that the larger" +echo "tests require significant amounts of RAM and disk space. If you" +echo "attempt to run one of the big tests on a system that lacks sufficient" +echo "disk and virtual memory, the UNIX kernel might decide to kill one or" +echo "more system processes that you've grown attached to, like the X" +echo "server. The question you may want to ask yourself before running a" +echo "large test is: Do you feel lucky?" +echo "" +echo "OK, now that we have the Dirty Harry quote out of the way, please" +echo "choose the type of test you wish to perform:" +echo "" +echo "0 - No testing, keep the scheduler running for me (all systems)" +echo "1 - Basic conformance test, no load testing (all systems)" +echo "2 - Basic conformance test, some load testing (minimum 256MB VM, 50MB disk)" +echo "3 - Basic conformance test, extreme load testing (minimum 1GB VM, 500MB disk)" +echo "4 - Basic conformance test, torture load testing (minimum 2GB VM, 1GB disk)" +echo "" +echo $ac_n "Enter the number of the test you wish to perform: [1] $ac_c" + +if test $# -gt 0; then + testtype=$1 + shift +else + read testtype +fi +echo "" + +case "$testtype" in + 0) + echo "Running in test mode (0)" + nprinters1=0 + nprinters2=0 + pjobs=0 + pprinters=0 + ;; + 2) + echo "Running the medium tests (2)" + nprinters1=10 + nprinters2=20 + pjobs=20 + pprinters=10 + ;; + 3) + echo "Running the extreme tests (3)" + nprinters1=500 + nprinters2=1000 + pjobs=100 + pprinters=50 + ;; + 4) + echo "Running the torture tests (4)" + nprinters1=10000 + nprinters2=20000 + pjobs=200 + pprinters=100 + ;; + *) + echo "Running the timid tests (1)" + nprinters1=0 + nprinters2=0 + pjobs=10 + pprinters=0 + ;; +esac + +# +# See if we want to do SSL testing... +# + +echo "" +echo "Now you can choose whether to create a SSL/TLS encryption key and" +echo "certificate for testing; these tests currently require the OpenSSL" +echo "tools:" +echo "" +echo "0 - Do not do SSL/TLS encryption tests" +echo "1 - Test but do not require encryption" +echo "2 - Test and require encryption" +echo "" +echo $ac_n "Enter the number of the SSL/TLS tests to perform: [0] $ac_c" + +if test $# -gt 0; then + ssltype=$1 + shift +else + read ssltype +fi +echo "" + +case "$ssltype" in + 1) + echo "Will test but not require encryption (1)" + ;; + 2) + echo "Will test and require encryption (2)" + ;; + *) + echo "Not using SSL/TLS (0)" + ssltype=0 + ;; +esac + +# +# Information for the server/tests... +# + +user="$USER" +if test -z "$user"; then + if test -x /usr/ucb/whoami; then + user=`/usr/ucb/whoami` + else + user=`whoami` + fi + + if test -z "$user"; then + user="unknown" + fi +fi + +port=8631 +cwd=`pwd` +root=`dirname $cwd` + +# +# Make sure that the LPDEST and PRINTER environment variables are +# not included in the environment that is passed to the tests. These +# will usually cause tests to fail erroneously... +# + +unset LPDEST +unset PRINTER + +# +# See if we want to use valgrind... +# + +echo "" +echo "This test script can use the Valgrind software from:" +echo "" +echo " http://developer.kde.org/~sewardj/" +echo "" +echo $ac_n "Enter Y to use Valgrind or N to not use Valgrind: [N] $ac_c" + +if test $# -gt 0; then + usevalgrind=$1 + shift +else + read usevalgrind +fi +echo "" + +case "$usevalgrind" in + Y* | y*) + valgrind="valgrind --tool=memcheck --log-file=/tmp/cups-$user/log/valgrind.%p --error-limit=no --leak-check=yes --trace-children=yes --read-var-info=yes" + echo "Using Valgrind; log files can be found in /tmp/cups-$user/log..." + ;; + + *) + valgrind="" + ;; +esac + +# +# Start by creating temporary directories for the tests... +# + +echo "Creating directories for test..." + +rm -rf /tmp/cups-$user +mkdir /tmp/cups-$user +mkdir /tmp/cups-$user/bin +mkdir /tmp/cups-$user/bin/backend +mkdir /tmp/cups-$user/bin/driver +mkdir /tmp/cups-$user/bin/filter +mkdir /tmp/cups-$user/certs +mkdir /tmp/cups-$user/share +mkdir /tmp/cups-$user/share/banners +mkdir /tmp/cups-$user/share/drv +mkdir /tmp/cups-$user/share/locale +for file in ../locale/cups_*.po; do + loc=`basename $file .po | cut -c 6-` + mkdir /tmp/cups-$user/share/locale/$loc + ln -s $root/locale/cups_$loc.po /tmp/cups-$user/share/locale/$loc + ln -s $root/locale/ppdc_$loc.po /tmp/cups-$user/share/locale/$loc +done +mkdir /tmp/cups-$user/share/mime +mkdir /tmp/cups-$user/share/model +mkdir /tmp/cups-$user/share/ppdc +mkdir /tmp/cups-$user/interfaces +mkdir /tmp/cups-$user/log +mkdir /tmp/cups-$user/ppd +mkdir /tmp/cups-$user/spool +mkdir /tmp/cups-$user/spool/temp +mkdir /tmp/cups-$user/ssl + +ln -s $root/backend/dnssd /tmp/cups-$user/bin/backend +ln -s $root/backend/http /tmp/cups-$user/bin/backend +ln -s $root/backend/ipp /tmp/cups-$user/bin/backend +ln -s $root/backend/lpd /tmp/cups-$user/bin/backend +ln -s $root/backend/mdns /tmp/cups-$user/bin/backend +ln -s $root/backend/parallel /tmp/cups-$user/bin/backend +ln -s $root/backend/serial /tmp/cups-$user/bin/backend +ln -s $root/backend/snmp /tmp/cups-$user/bin/backend +ln -s $root/backend/socket /tmp/cups-$user/bin/backend +ln -s $root/backend/usb /tmp/cups-$user/bin/backend +ln -s $root/cgi-bin /tmp/cups-$user/bin +ln -s $root/monitor /tmp/cups-$user/bin +ln -s $root/notifier /tmp/cups-$user/bin +ln -s $root/scheduler /tmp/cups-$user/bin/daemon +ln -s $root/filter/bannertops /tmp/cups-$user/bin/filter +ln -s $root/filter/commandtops /tmp/cups-$user/bin/filter +ln -s $root/filter/gziptoany /tmp/cups-$user/bin/filter +ln -s $root/filter/hpgltops /tmp/cups-$user/bin/filter +ln -s $root/filter/pstops /tmp/cups-$user/bin/filter +ln -s $root/filter/rastertoepson /tmp/cups-$user/bin/filter +ln -s $root/filter/rastertohp /tmp/cups-$user/bin/filter +ln -s $root/filter/texttops /tmp/cups-$user/bin/filter + +ln -s $root/data/classified /tmp/cups-$user/share/banners +ln -s $root/data/confidential /tmp/cups-$user/share/banners +ln -s $root/data/secret /tmp/cups-$user/share/banners +ln -s $root/data/standard /tmp/cups-$user/share/banners +ln -s $root/data/topsecret /tmp/cups-$user/share/banners +ln -s $root/data/unclassified /tmp/cups-$user/share/banners +ln -s $root/data /tmp/cups-$user/share/charmaps +ln -s $root/data /tmp/cups-$user/share/charsets +ln -s $root/data /tmp/cups-$user/share +ln -s $root/fonts /tmp/cups-$user/share +ln -s $root/ppdc/sample.drv /tmp/cups-$user/share/drv +ln -s $root/conf/mime.types /tmp/cups-$user/share/mime +ln -s $root/conf/mime.convs /tmp/cups-$user/share/mime +ln -s $root/data/*.h /tmp/cups-$user/share/ppdc +ln -s $root/data/*.defs /tmp/cups-$user/share/ppdc +ln -s $root/templates /tmp/cups-$user/share + +# +# Mac OS X filters and configuration files... +# + +if test `uname` = Darwin; then + ln -s /usr/libexec/cups/filter/cgpdfto* /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/cgbannertopdf /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/cgimagetopdf /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/cgtexttopdf /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/nsimagetopdf /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/nstexttopdf /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/pictwpstops /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/pstoappleps /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/pstocupsraster /tmp/cups-$user/bin/filter + ln -s /usr/libexec/cups/filter/pstopdffilter /tmp/cups-$user/bin/filter + + if test -f /private/etc/cups/apple.types; then + ln -s /private/etc/cups/apple.* /tmp/cups-$user/share/mime + elif test -f /usr/share/cups/mime/apple.types; then + ln -s /usr/share/cups/mime/apple.* /tmp/cups-$user/share/mime + fi +else + ln -s $root/filter/imagetops /tmp/cups-$user/bin/filter + ln -s $root/filter/imagetoraster /tmp/cups-$user/bin/filter + ln -s $root/filter/pdftops /tmp/cups-$user/bin/filter +fi + +# +# Then create the necessary config files... +# + +echo "Creating cupsd.conf for test..." + +if test $ssltype = 2; then + encryption="Encryption Required" +else + encryption="" +fi + +cat >/tmp/cups-$user/cupsd.conf < + +Order Deny,Allow +Deny from all +Allow from 127.0.0.1 +$encryption + + +EOF + +# +# Setup lots of test queues - half with PPD files, half without... +# + +echo "Creating printers.conf for test..." + +i=1 +while test $i -le $nprinters1; do + cat >>/tmp/cups-$user/printers.conf < +Accepting Yes +DeviceURI file:/dev/null +Info Test PS printer $i +JobSheets none none +Location CUPS test suite +State Idle +StateMessage Printer $1 is idle. + +EOF + + cp testps.ppd /tmp/cups-$user/ppd/test-$i.ppd + + i=`expr $i + 1` +done + +while test $i -le $nprinters2; do + cat >>/tmp/cups-$user/printers.conf < +Accepting Yes +DeviceURI file:/dev/null +Info Test raw printer $i +JobSheets none none +Location CUPS test suite +State Idle +StateMessage Printer $1 is idle. + +EOF + + i=`expr $i + 1` +done + +if test -f /tmp/cups-$user/printers.conf; then + cp /tmp/cups-$user/printers.conf /tmp/cups-$user/printers.conf.orig +else + touch /tmp/cups-$user/printers.conf.orig +fi + +# +# Setup the paths... +# + +echo "Setting up environment variables for test..." + +if test "x$LD_LIBRARY_PATH" = x; then + LD_LIBRARY_PATH="$root/cups:$root/filter:$root/cgi-bin:$root/scheduler:$root/driver:$root/ppdc" +else + LD_LIBRARY_PATH="$root/cups:$root/filter:$root/cgi-bin:$root/scheduler:$root/driver:$root/ppdc:$LD_LIBRARY_PATH" +fi + +export LD_LIBRARY_PATH + +LD_PRELOAD="$root/cups/libcups.so.2:$root/filter/libcupsimage.so.2:$root/cgi-bin/libcupscgi.so.1:$root/scheduler/libcupsmime.so.1:$root/driver/libcupsdriver.so.1:$root/ppdc/libcupsppdc.so.1" +if test `uname` = SunOS -a -r /usr/lib/libCrun.so.1; then + LD_PRELOAD="/usr/lib/libCrun.so.1:$LD_PRELOAD" +fi +export LD_PRELOAD + +if test "x$DYLD_LIBRARY_PATH" = x; then + DYLD_LIBRARY_PATH="$root/cups:$root/filter:$root/cgi-bin:$root/scheduler:$root/driver:$root/ppdc" +else + DYLD_LIBRARY_PATH="$root/cups:$root/filter:$root/cgi-bin:$root/scheduler:$root/driver:$root/ppdc:$DYLD_LIBRARY_PATH" +fi + +export DYLD_LIBRARY_PATH + +if test "x$SHLIB_PATH" = x; then + SHLIB_PATH="$root/cups:$root/filter:$root/cgi-bin:$root/scheduler:$root/driver:$root/ppdc" +else + SHLIB_PATH="$root/cups:$root/filter:$root/cgi-bin:$root/scheduler:$root/driver:$root/ppdc:$SHLIB_PATH" +fi + +export SHLIB_PATH + +CUPS_DISABLE_APPLE_DEFAULT=yes; export CUPS_DISABLE_APPLE_DEFAULT +CUPS_SERVER=localhost:8631; export CUPS_SERVER +CUPS_SERVERROOT=/tmp/cups-$user; export CUPS_SERVERROOT +CUPS_STATEDIR=/tmp/cups-$user; export CUPS_STATEDIR +CUPS_DATADIR=/tmp/cups-$user/share; export CUPS_DATADIR +LOCALEDIR=/tmp/cups-$user/share/locale; export LOCALEDIR + +# +# Set a new home directory to avoid getting user options mixed in... +# + +HOME=/tmp/cups-$user +export HOME + +# +# Force POSIX locale for tests... +# + +LANG=C +export LANG + +LC_MESSAGES=C +export LC_MESSAGES + +# +# Start the server; run as foreground daemon in the background... +# + +echo "Starting scheduler:" +echo " $valgrind ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 &" +echo "" + +if test `uname` = Darwin -a "x$valgrind" = x; then + DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib \ + $valgrind ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 & +else + $valgrind ../scheduler/cupsd -c /tmp/cups-$user/cupsd.conf -f >/tmp/cups-$user/log/debug_log 2>&1 & +fi + +cupsd=$! + +if test "x$testtype" = x0; then + # Not running tests... + echo "Scheduler is PID $cupsd and is listening on port 8631." + echo "" + + # Create a helper script to run programs with... + runcups="/tmp/cups-$user/runcups" + + echo "#!/bin/sh" >$runcups + echo "# Helper script for running CUPS test instance." >>$runcups + echo "" >>$runcups + echo "# Set required environment variables..." >>$runcups + echo "CUPS_DATADIR=\"$CUPS_DATADIR\"; export CUPS_DATADIR" >>$runcups + echo "CUPS_SERVER=\"$CUPS_SERVER\"; export CUPS_SERVER" >>$runcups + echo "CUPS_SERVERROOT=\"$CUPS_SERVERROOT\"; export CUPS_SERVERROOT" >>$runcups + echo "CUPS_STATEDIR=\"$CUPS_STATEDIR\"; export CUPS_STATEDIR" >>$runcups + echo "DYLD_LIBRARY_PATH=\"$DYLD_LIBRARY_PATH\"; export DYLD_LIBRARY_PATH" >>$runcups + echo "LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH\"; export LD_LIBRARY_PATH" >>$runcups + echo "LD_PRELOAD=\"$LD_PRELOAD\"; export LD_PRELOAD" >>$runcups + echo "LOCALEDIR=\"$LOCALEDIR\"; export LOCALEDIR" >>$runcups + echo "SHLIB_PATH=\"$SHLIB_PATH\"; export SHLIB_PATH" >>$runcups + echo "" >>$runcups + echo "# Run command..." >>$runcups + echo "exec \"\$@\"" >>$runcups + + chmod +x $runcups + + echo "The $runcups helper script can be used to test programs" + echo "with the server." + exit 0 +fi + +if test $argcount -eq 0; then + echo "Scheduler is PID $cupsd; run debugger now if you need to." + echo "" + echo $ac_n "Press ENTER to continue... $ac_c" + read junk +else + echo "Scheduler is PID $cupsd." + sleep 2 +fi + +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... +# + +date=`date "+%Y-%m-%d"` +strfile=/tmp/cups-$user/cups-str-1.4-$date-$user.html + +rm -f $strfile +cat str-header.html >$strfile + +# +# Run the IPP tests... +# + +echo "" +echo "Running IPP compliance tests..." + +echo "

    1 - IPP Compliance Tests

    " >>$strfile +echo "

    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 $user on `hostname`. >>$strfile +echo "

    " >>$strfile
    +
    +fail=0
    +for file in 4*.test; do
    +	echo "Performing $file..."
    +	echo "" >>$strfile
    +
    +	./ipptest ipp://localhost:$port/printers $file | tee -a $strfile
    +	status=$?
    +
    +	if test $status != 0; then
    +		echo Test failed.
    +		fail=`expr $fail + 1`
    +	fi
    +done
    +
    +echo "
    " >>$strfile + +# +# Run the command tests... +# + +echo "" +echo "Running command tests..." + +echo "

    2 - Command Tests

    " >>$strfile +echo "

    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 by $user on `hostname`. >>$strfile +echo "

    " >>$strfile
    +
    +for file in 5*.sh; do
    +	echo "Performing $file..."
    +	echo "" >>$strfile
    +	echo "\"$file\":" >>$strfile
    +
    +	sh $file $pjobs $pprinters | tee -a $strfile
    +	status=$?
    +
    +	if test $status != 0; then
    +		echo Test failed.
    +		fail=`expr $fail + 1`
    +	fi
    +done
    +
    +echo "
    " >>$strfile + +# +# Stop the server... +# + +kill $cupsd + +# +# Append the log files for post-mortim... +# + +echo "

    3 - Log Files

    " >>$strfile + +# +# Verify counts... +# + +echo "Test Summary" +echo "" +echo "

    Summary

    " >>$strfile + +# Job control files +count=`ls -1 /tmp/cups-$user/spool | wc -l` +count=`expr $count - 1` +if test $count != 0; then + echo "FAIL: $count job control files were not purged." + echo "

    FAIL: $count job control files were not purged.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: All job control files purged." + echo "

    PASS: All job control files purged.

    " >>$strfile +fi + +# Pages printed on Test1 (within 1 page for timing-dependent cancel issues) +count=`$GREP '^Test1 ' /tmp/cups-$user/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'` +expected=`expr $pjobs \* 2 + 34` +expected2=`expr $expected + 2` +if test $count -lt $expected -a $count -gt $expected2; then + echo "FAIL: Printer 'Test1' produced $count page(s), expected $expected." + echo "

    FAIL: Printer 'Test1' produced $count page(s), expected $expected.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: Printer 'Test1' correctly produced $count page(s)." + echo "

    PASS: Printer 'Test1' correctly produced $count page(s).

    " >>$strfile +fi + +# Paged printed on Test2 +count=`$GREP '^Test2 ' /tmp/cups-$user/log/page_log | awk 'BEGIN{count=0}{count=count+$7}END{print count}'` +expected=`expr $pjobs \* 2 + 3` +if test $count != $expected; then + echo "FAIL: Printer 'Test2' produced $count page(s), expected $expected." + echo "

    FAIL: Printer 'Test2' produced $count page(s), expected $expected.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: Printer 'Test2' correctly produced $count page(s)." + echo "

    PASS: Printer 'Test2' correctly produced $count page(s).

    " >>$strfile +fi + +# Requests logged +count=`wc -l /tmp/cups-$user/log/access_log | awk '{print $1}'` +expected=`expr 37 + 18 + $pjobs \* 8 + $pprinters \* $pjobs \* 4` +if test $count != $expected; then + echo "FAIL: $count requests logged, expected $expected." + echo "

    FAIL: $count requests logged, expected $expected.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count requests logged." + echo "

    PASS: $count requests logged.

    " >>$strfile +fi + +# Did CUPS-Get-Default get logged? +if $GREP -q CUPS-Get-Default /tmp/cups-$user/log/access_log; then + echo "FAIL: CUPS-Get-Default logged with 'AccessLogLevel actions'" + echo "

    FAIL: CUPS-Get-Default logged with 'AccessLogLevel actions'

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP CUPS-Get-Default /tmp/cups-$user/log/access_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: CUPS-Get-Default not logged." + echo "

    PASS: CUPS-Get-Default not logged.

    " >>$strfile +fi + +# Emergency log messages +count=`$GREP '^X ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count != 0; then + echo "FAIL: $count emergency messages, expected 0." + $GREP '^X ' /tmp/cups-$user/log/error_log + echo "

    FAIL: $count emergency messages, expected 0.

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP '^X ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count emergency messages." + echo "

    PASS: $count emergency messages.

    " >>$strfile +fi + +# Alert log messages +count=`$GREP '^A ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count != 0; then + echo "FAIL: $count alert messages, expected 0." + $GREP '^A ' /tmp/cups-$user/log/error_log + echo "

    FAIL: $count alert messages, expected 0.

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP '^A ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count alert messages." + echo "

    PASS: $count alert messages.

    " >>$strfile +fi + +# Critical log messages +count=`$GREP '^C ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count != 0; then + echo "FAIL: $count critical messages, expected 0." + $GREP '^C ' /tmp/cups-$user/log/error_log + echo "

    FAIL: $count critical messages, expected 0.

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP '^C ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count critical messages." + echo "

    PASS: $count critical messages.

    " >>$strfile +fi + +# Error log messages +count=`$GREP '^E ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count != 18; then + echo "FAIL: $count error messages, expected 18." + $GREP '^E ' /tmp/cups-$user/log/error_log + echo "

    FAIL: $count error messages, expected 18.

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP '^E ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count error messages." + echo "

    PASS: $count error messages.

    " >>$strfile +fi + +# Warning log messages +count=`$GREP '^W ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count != 0; then + echo "FAIL: $count warning messages, expected 0." + $GREP '^W ' /tmp/cups-$user/log/error_log + echo "

    FAIL: $count warning messages, expected 0.

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP '^W ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count warning messages." + echo "

    PASS: $count warning messages.

    " >>$strfile +fi + +# Notice log messages +count=`$GREP '^N ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count != 0; then + echo "FAIL: $count notice messages, expected 0." + $GREP '^N ' /tmp/cups-$user/log/error_log + echo "

    FAIL: $count notice messages, expected 0.

    " >>$strfile + echo "
    " >>$strfile
    +	$GREP '^N ' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +	echo "
    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count notice messages." + echo "

    PASS: $count notice messages.

    " >>$strfile +fi + +# Info log messages +count=`$GREP '^I ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count = 0; then + echo "FAIL: $count info messages, expected more than 0." + echo "

    FAIL: $count info messages, expected more than 0.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count info messages." + echo "

    PASS: $count info messages.

    " >>$strfile +fi + +# Debug log messages +count=`$GREP '^D ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count = 0; then + echo "FAIL: $count debug messages, expected more than 0." + echo "

    FAIL: $count debug messages, expected more than 0.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count debug messages." + echo "

    PASS: $count debug messages.

    " >>$strfile +fi + +# Debug2 log messages +count=`$GREP '^d ' /tmp/cups-$user/log/error_log | wc -l | awk '{print $1}'` +if test $count = 0; then + echo "FAIL: $count debug2 messages, expected more than 0." + echo "

    FAIL: $count debug2 messages, expected more than 0.

    " >>$strfile + fail=`expr $fail + 1` +else + echo "PASS: $count debug2 messages." + echo "

    PASS: $count debug2 messages.

    " >>$strfile +fi + +# Page log file... +if $GREP -iq 'testfile.pdf na_letter_8.5x11in' /tmp/cups-$user/log/page_log; then + echo "PASS: page_log formatted correctly." + echo "

    PASS: page_log formatted correctly.

    " >>$strfile +else + echo "WARN: page_log formatted incorrectly." + echo "

    WARN: page_log formatted incorrectly.

    " >>$strfile +# fail=`expr $fail + 1` +fi + +# Log files... +echo "

    access_log

    " >>$strfile +echo "
    " >>$strfile
    +sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +echo "
    " >>$strfile + +echo "

    error_log

    " >>$strfile +echo "
    " >>$strfile
    +$GREP -v '^d' /tmp/cups-$user/log/error_log | sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +echo "
    " >>$strfile + +echo "

    page_log

    " >>$strfile +echo "
    " >>$strfile
    +sed -e '1,$s/&/&/g' -e '1,$s/>$strfile
    +echo "
    " >>$strfile + +# +# Format the reports and tell the user where to find them... +# + +cat str-trailer.html >>$strfile + +echo "" + +if test $fail != 0; then + echo "$fail tests failed." + cp /tmp/cups-$user/log/error_log error_log-$date-$user + cp $strfile . +else + echo "All tests were successful." +fi + +echo "Log files can be found in /tmp/cups-$user/log." +echo "A HTML report was created in $strfile." +echo "" + +if test $fail != 0; then + echo "Copies of the error_log and `basename $strfile` files are in" + echo "`pwd`." + echo "" + + exit 1 +fi + +# +# End of "$Id$" +# diff --git a/test/set-attrs-hold.test b/test/set-attrs-hold.test new file mode 100644 index 0000000000..377819ae47 --- /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 0000000000..ff53adb82b --- /dev/null +++ b/test/str-header.html @@ -0,0 +1,31 @@ + + + + + + + CUPS 1.4 Software Test Report + + + + +

    CUPS 1.4 Software Test Report

    + +

    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.4. + +

    Document Overview

    + +

    This software test plan is organized into the following sections: + +

      +
    • 1 - IPP Compliance Tests
    • +
    • 2 - Command Tests
    • +
    • 3 - Log Files
    • +
    diff --git a/test/str-trailer.html b/test/str-trailer.html new file mode 100644 index 0000000000..e04310fdd2 --- /dev/null +++ b/test/str-trailer.html @@ -0,0 +1,2 @@ + + diff --git a/test/testfile.jpg b/test/testfile.jpg new file mode 100644 index 0000000000000000000000000000000000000000..418cb93597c7a3cb5a425fffaf2250373663b3ae GIT binary patch literal 204156 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 bL+t^$8>%2v=^7IZo85up{}w6_LQeiachriZ literal 0 Hc-jL100001 diff --git a/test/testfile.pdf b/test/testfile.pdf new file mode 100644 index 0000000000000000000000000000000000000000..433577179840d3d626229e113e7471fd44b7e638 GIT binary patch literal 279746 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°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 literal 0 Hc-jL100001 diff --git a/test/testfile.ps b/test/testfile.ps new file mode 100644 index 0000000000..bce9c91757 --- /dev/null +++ b/test/testfile.ps @@ -0,0 +1,598 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset testprint/1.3 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Apple Inc. +%%CreationDate: D:20070606214000+0500 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset testprint 1.3 0 +% +% PostScript test page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 2007 Apple Inc. +% Copyright 1993-2007 Easy Software Products +% +% These coded instructions, statements, and computer programs are the +% property of Apple Inc. and are protected by Federal copyright law. +% Distribution and use rights are outlined in the file "LICENSE.txt" +% which is included with the CUPS source distribution. +% +/SEXTANT { % Draw a color wheel sextant... + % (name) white radius r g b SEXTANT - + % Loop through 100 shades... + 0 0.010101 0.98 { + % Set the color... + dup 0.75 le { % Get "white" value + % Start from black + dup 0.75 div % val2 = val / 0.75 + + 0 index 5 index mul % R = R * val2 + 1 index 5 index mul % G = G * val2 + 2 index 5 index mul % B = B * val2 + + 4 -1 roll pop % Discard val2 + } { + % Fade to white + dup neg 1 add 4 mul % val2 = (1 - val) * 4 + + 0 index 5 index mul % R = R * val2 + 1 index neg 1 add add % + (1 - val2) + 1 index 5 index mul % G = G * val2 + 2 index neg 1 add add % + (1 - val2) + 2 index 5 index mul % B = B * val2 + 3 index neg 1 add add % + (1 - val2) + + 4 -1 roll pop % Discard val2 + } ifelse + setrgbcolor % Set the color... + + % Draw the polygon... + newpath % Start a new path... + dup 5 index mul % r1 = radius * val + 0 0 3 -1 roll 0 60 arc % Draw the inner arc + + dup 0.010101 add 5 index mul% r2 = (radius + 0.010101) * val + 0 0 3 -1 roll 60 0 arcn % Draw the outer arc + + closepath % Close the path + fill % Fill it... + + pop % Pop value... + } for + + % Draw a line around the polygons... + pop pop pop dup % Pop R, G, B, start + 0 setgray % Black + newpath + 0 0 moveto % Center + 0 0 3 -1 roll 0 60 arc % Arc around octant + closepath % Back to center + stroke % Stroke it... + + % Draw the label... + dup % Save radius + dup 30 cos mul % X = radius * cos(30) + exch 30 sin mul % Y = radius * sin(30) + moveto % Position label + + gsave + 30 rotate % Rotate label + dup 0.05 mul % Offset to the right + exch -0.05 mul % and down... + 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 +%%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 + + /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) + + % Draw rulers along the edges... + /CENTIMETER 72 2.54 div def + /MILLIMETER 72 25.4 div def + + /Times-Roman findfont % Font for ruler numbers + 11 scalefont setfont % 11 points + + gsave % Left side inches + pageLeft 72 mul 0 translate % Offset left edge + + 1 setlinewidth % Draw normal lines + 72 72 pageTop 72 mul { % Height inches + dup dup + 0 exch moveto 24 0 rlineto stroke % Draw tic mark + 24 exch pageHeight sub moveto % Draw number + 72 div cvi 10 string cvs RIGHT + } for + + 0.5 setlinewidth % Draw thin lines + 18 18 pageTop 72 mul { % 1/4 inches + 0 exch moveto 15 0 rlineto stroke % Draw tic mark + } for + + 9 9 pageTop 72 mul { % 1/8 inches + 0 exch moveto 6 0 rlineto stroke % Draw tic mark + } for + grestore + + gsave % Bottom inches + 0 pageBottom 72 mul translate % Offset bottom edge + + 1 setlinewidth % Draw normal lines + 72 72 pageRight 72 mul { % Width inches + dup dup + 0 moveto 0 24 rlineto stroke % Draw tic mark + 3 add 27 pageHeight sub moveto % Draw number + 72 div cvi 10 string cvs show + } for + + 0.5 setlinewidth % Draw thin lines + 18 18 pageRight 72 mul { % 1/4 inches + 0 moveto 0 15 rlineto stroke % Draw tic mark + } for + + 9 9 pageRight 72 mul { % 1/8 inches + 0 moveto 0 6 rlineto stroke % Draw tic mark + } for + grestore + + gsave % Right side centimeters + pageRight 72 mul 0 translate % Offset right edge + + 1 setlinewidth % Draw normal lines + CENTIMETER CENTIMETER + pageTop 72 mul { % Height centimeters + 0 exch moveto -24 0 rlineto stroke% Draw tic mark + } for + 1 1 pageTop 2.54 mul { % Height labels + dup + -24 exch CENTIMETER mul + pageHeight sub moveto % Draw number + cvi 10 string cvs show + } for + + 0.5 setlinewidth % Draw thin lines + 0 0.5 CENTIMETER mul + pageTop 72 mul { % 1/2 centimeters + 0 exch moveto -15 0 rlineto stroke% Draw tic mark + } for + 0 MILLIMETER pageTop 72 mul { % Millimeters + 0 exch moveto -6 0 rlineto stroke % Draw tic mark + } for + grestore + + gsave % Top centimeters + 0 pageTop 72 mul translate % Offset top edge + + 1 setlinewidth % Draw normal lines + CENTIMETER CENTIMETER + pageRight 72 mul { % Width centimeters + 0 moveto 0 -24 rlineto stroke % Draw tic mark + } for + 1 1 pageRight 2.54 mul { % Width labels + dup + CENTIMETER mul 3 add -24 moveto % Draw number + cvi 10 string cvs show + } for + + 0.5 setlinewidth % Draw thin lines + 0 0.5 CENTIMETER mul + pageRight 72 mul { % 1/2 centimeters + 0 moveto 0 -15 rlineto stroke % Draw tic mark + } for + 0 MILLIMETER pageRight 72 mul { % Millimeters + 0 moveto 0 -6 rlineto stroke % Draw tic mark + } for + grestore + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Set text font and color... + mediumFont setfont % Font + 0 setgray % Color + 1 setlinewidth % Draw normal lines + + % Draw the color wheel... + 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) 3 -1 roll 0 1 1 SEXTANT 60 rotate + dup (M) 3 -1 roll 1 0 1 SEXTANT 60 rotate + dup (Y) 3 -1 roll 1 1 0 SEXTANT 60 rotate + dup (R) 3 -1 roll 1 0 0 SEXTANT 60 rotate + dup (G) 3 -1 roll 0 1 0 SEXTANT 60 rotate + dup (B) 3 -1 roll 0 0 1 SEXTANT 60 rotate + + pop + grestore + + % Label the color wheel... + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 43 mul % y = pageHeight * 19/32 * 72 + moveto % Position the text + (Color Wheel) CENTER % Show the text centered + + % Draw the gray ramp... + gsave + % Position the gray ramp in the center... + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 54 mul % y = pageHeight * 3/4 * 72 + wheelSize sub % - wheelSize + translate + + % Loop through 100 shades... + 0 0.010101 0.98 { + % Set the color... + dup setgray % Set the grayscale... + + % Draw the polygon... + newpath % Start a new path... + + wheelSize -0.2 mul % X = -wheelSize / 5 + 1 index 2 mul wheelSize mul % Y = val * 2 * wheelSize + moveto % Move there... + + wheelSize 0.4 mul 0 rlineto % Right side... + + wheelSize 0.2 mul % X = wheelSize / 5 + 1 index 0.010101 add 2 mul wheelSize mul + % Y = (val + 0.010101) * 2 * wheelSize + lineto % Move there... + + wheelSize -0.4 mul 0 rlineto % Left side... + + closepath % Close the path + fill % Fill it... + + pop % Pop value... + } for + + 0 setgray % Black + + newpath % Start a new path + wheelSize -0.2 mul 0 moveto % Bottom left + wheelSize 0.4 mul 0 rlineto % Bottom right + 0 wheelSize 2 mul rlineto % Upper right + wheelSize -0.4 mul 0 rlineto % Upper left + closepath % Close the path + stroke % Stroke it... + + 0 wheelSize -0.2 mul moveto % Center bottom for label + (K) CENTER % Center K at bottom + + 0 wheelSize 2.05 mul moveto % Center top for label + (W) CENTER % Center W at top + grestore + + % Label the gray ramp... + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 43 mul % y = pageHeight * 19/32 * 72 + moveto % Position the text + (Gray Ramp) 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 43 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... + 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 66 mul % Top of page (11/12ths) + moveto % Position text + bigFont setfont % Font + (Printer Test Page) CENTER % Show text centered + + % Draw the copyright notice at the bottom... + pageWidth 17 mul % Center of page + pageHeight 10 mul % Bottom of page + moveto % Position text + (Printed Using CUPS v1.3.x) show + + pageWidth 17 mul % Left side of page + pageHeight 8 mul % Move down... + 2 copy moveto % Position text + smallFont setfont % Font + (Copyright 2007 Apple Inc., All Rights Reserved. CUPS and the CUPS logo are the trademark) show + pageHeight 2 add sub % Move down... + 2 copy moveto % Position text + (property of Apple Inc., 1 Infinite Loop, Cupertino, CA 95014, USA.) show + pageHeight 2 mul 4 add sub % Move down... + moveto % Position text + (Need help? Contact your operating system vendor or visit "http://www.cups.org/".) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageHeight 4 mul + translate + pageWidth 15 mul CUPSLOGO + grestore + +% Show the page... +grestore +showpage +% +% End of "$Id: testfile.ps 6649 2007-07-11 21:46:42Z mike $". +% +%%EOF diff --git a/test/testfile.txt b/test/testfile.txt new file mode 100644 index 0000000000..46bbf08483 --- /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 0000000000..f7c8b9cfff --- /dev/null +++ b/test/testhp.ppd @@ -0,0 +1,186 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Test HP PPD file for the Common UNIX Printing System (CUPS). +*% +*% Copyright 2007 by Apple Inc. +*% Copyright 1997-2005 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Apple Inc. 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 +*% file is missing or damaged, see the license at "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: "<>setpagedevice" +*PageSize Legal/US Legal: "<>setpagedevice" +*PageSize Executive/US Executive: "<>setpagedevice" +*PageSize Tabloid/US Tabloid: "<>setpagedevice" +*PageSize A3/A3: "<>setpagedevice" +*PageSize A4/A4: "<>setpagedevice" +*PageSize A5/A5: "<>setpagedevice" +*PageSize B5/B5 (JIS): "<>setpagedevice" +*PageSize EnvISOB5/Envelope B5: "<>setpagedevice" +*PageSize Env10/Envelope #10: "<>setpagedevice" +*PageSize EnvC5/Envelope C5: "<>setpagedevice" +*PageSize EnvDL/Envelope DL: "<>setpagedevice" +*PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/US Letter: "<>setpagedevice" +*PageRegion Legal/US Legal: "<>setpagedevice" +*PageRegion Executive/US Executive: "<>setpagedevice" +*PageRegion Tabloid/US Tabloid: "<>setpagedevice" +*PageRegion A3/A3: "<>setpagedevice" +*PageRegion A4/A4: "<>setpagedevice" +*PageRegion A5/A5: "<>setpagedevice" +*PageRegion B5/B5 (JIS): "<>setpagedevice" +*PageRegion EnvISOB5/Envelope B5: "<>setpagedevice" +*PageRegion Env10/Envelope #10: "<>setpagedevice" +*PageRegion EnvC5/Envelope C5: "<>setpagedevice" +*PageRegion EnvDL/Envelope DL: "<>setpagedevice" +*PageRegion EnvMonarch/Envelope Monarch: "<>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: "<>setpagedevice" +*MediaType Bond/Bond Paper: "<>setpagedevice" +*MediaType Special/Special Paper: "<>setpagedevice" +*MediaType Transparency/Transparency: "<>setpagedevice" +*MediaType Glossy/Glossy Paper: "<>setpagedevice" +*CloseUI: *MediaType + +*OpenUI *InputSlot/Media Source: PickOne +*OrderDependency: 10 AnySetup *InputSlot +*DefaultInputSlot: Tray +*InputSlot Tray/Tray: "<>setpagedevice" +*InputSlot Manual/Manual Feed: "<>setpagedevice" +*InputSlot Envelope/Envelope Feed: "<>setpagedevice" +*CloseUI: *InputSlot + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 100dpi +*Resolution 75dpi/75 DPI: "<>setpagedevice" +*Resolution 100dpi/100 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*OpenUI *ColorModel/Output Mode: PickOne +*OrderDependency: 10 AnySetup *ColorModel +*DefaultColorModel: CMYK +*ColorModel CMYK/CMYK Color: "<>setpagedevice" +*ColorModel RGB/CMY Color: "<>setpagedevice" +*ColorModel Gray/Grayscale: "<>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 0000000000..6bc5907d7e --- /dev/null +++ b/test/testps.ppd @@ -0,0 +1,183 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Test PS PPD file for the Common UNIX Printing System (CUPS). +*% +*% Copyright 2007 by Apple Inc. +*% Copyright 1997-2005 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Apple Inc. 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 +*% file is missing or damaged, see the license at "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: "<>setpagedevice" +*PageSize Legal/US Legal: "<>setpagedevice" +*PageSize Executive/US Executive: "<>setpagedevice" +*PageSize Tabloid/US Tabloid: "<>setpagedevice" +*PageSize A3/A3: "<>setpagedevice" +*PageSize A4/A4: "<>setpagedevice" +*PageSize A5/A5: "<>setpagedevice" +*PageSize B5/B5 (JIS): "<>setpagedevice" +*PageSize EnvISOB5/Envelope B5: "<>setpagedevice" +*PageSize Env10/Envelope #10: "<>setpagedevice" +*PageSize EnvC5/Envelope C5: "<>setpagedevice" +*PageSize EnvDL/Envelope DL: "<>setpagedevice" +*PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/US Letter: "<>setpagedevice" +*PageRegion Legal/US Legal: "<>setpagedevice" +*PageRegion Executive/US Executive: "<>setpagedevice" +*PageRegion Tabloid/US Tabloid: "<>setpagedevice" +*PageRegion A3/A3: "<>setpagedevice" +*PageRegion A4/A4: "<>setpagedevice" +*PageRegion A5/A5: "<>setpagedevice" +*PageRegion B5/B5 (JIS): "<>setpagedevice" +*PageRegion EnvISOB5/Envelope B5: "<>setpagedevice" +*PageRegion Env10/Envelope #10: "<>setpagedevice" +*PageRegion EnvC5/Envelope C5: "<>setpagedevice" +*PageRegion EnvDL/Envelope DL: "<>setpagedevice" +*PageRegion EnvMonarch/Envelope Monarch: "<>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: "<>setpagedevice" +*MediaType Bond/Bond Paper: "<>setpagedevice" +*MediaType Special/Special Paper: "<>setpagedevice" +*MediaType Transparency/Transparency: "<>setpagedevice" +*MediaType Glossy/Glossy Paper: "<>setpagedevice" +*CloseUI: *MediaType + +*OpenUI *InputSlot/Media Source: PickOne +*OrderDependency: 10 AnySetup *InputSlot +*DefaultInputSlot: Tray +*InputSlot Tray/Tray: "<>setpagedevice" +*InputSlot Manual/Manual Feed: "<>setpagedevice" +*InputSlot Envelope/Envelope Feed: "<>setpagedevice" +*CloseUI: *InputSlot + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 100dpi +*Resolution 75dpi/75 DPI: "<>setpagedevice" +*Resolution 100dpi/100 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*OpenUI *ColorModel/Output Mode: PickOne +*OrderDependency: 10 AnySetup *ColorModel +*DefaultColorModel: CMYK +*ColorModel CMYK/CMYK Color: "<>setpagedevice" +*ColorModel RGB/CMY Color: "<>setpagedevice" +*ColorModel Gray/Grayscale: "<>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/waitjobs.sh b/test/waitjobs.sh new file mode 100755 index 0000000000..7a79fb69be --- /dev/null +++ b/test/waitjobs.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# "$Id$" +# +# Script to wait for jobs to complete. +# +# Copyright 2008-2009 by Apple Inc. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Get timeout from command-line +# + +if test $# = 1; then + timeout=$1 +else + timeout=360 +fi + +# +# Figure out the proper echo options... +# + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + ac_n=-n + ac_c= +else + ac_n= + ac_c='\c' +fi + +echo $ac_n "Waiting for jobs to complete...$ac_c" +oldjobs=0 + +while test $timeout -gt 0; do + jobs=`../systemv/lpstat 2>/dev/null | wc -l | tr -d ' '` + if test $jobs = 0; then + break + fi + + if test $jobs != $oldjobs; then + echo $ac_n "$jobs...$ac_c" + oldjobs=$jobs + fi + + sleep 5 + timeout=`expr $timeout - 5` +done + +echo "" + +# +# End of "$Id$". +# diff --git a/tools/checkglobals b/tools/checkglobals new file mode 100755 index 0000000000..4d15387eaf --- /dev/null +++ b/tools/checkglobals @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Check for global symbols that don't need to be made global... +# + +for file in *.o; do + functions="" + + for function in `nm -g $file | grep "T " | awk '{print $3}'`; do + found="" + for file2 in *.o; do + if test "$file" = "$file2"; then + continue; + fi + + found=`nm -g $file2 | grep $function` + if test "$found" != ""; then + break; + fi + done + + if test -z "$found"; then + functions="$functions $function" + fi + done + + if test -z "$functions"; then + echo "$file: OK" + else + echo "$file: $functions" + fi +done diff --git a/tools/listpublic b/tools/listpublic new file mode 100755 index 0000000000..d864e7ee63 --- /dev/null +++ b/tools/listpublic @@ -0,0 +1,12 @@ +#!/bin/sh +# +# List public API symbols... +# + +for function in `nm -g *.so | grep "T " | awk '{print $3}' | grep -v '^_' | sort`; do + found=`grep $function\( *.h | grep -v DEPRECATED` + + if test "x$found" != x; then + echo $function + fi +done diff --git a/tools/makesrcdist b/tools/makesrcdist new file mode 100755 index 0000000000..cf4bc57fb0 --- /dev/null +++ b/tools/makesrcdist @@ -0,0 +1,91 @@ +#!/bin/sh +# +# "$Id: makesrcdist 9120 2010-04-23 18:56:34Z mike $" +# +# makesrcdist - make a source distribution of CUPS. +# + +# Make sure we are running in the right directory... +if test ! -f tools/makesrcdist; then + echo "Run this script from the top-level CUPS source directory, e.g.:" + echo "" + echo " tools/makesrcdist $*" + echo "" + exit 1 +fi + +if test $# = 0; then + echo Updating for snapshot... + svn up + rev=`svnversion . | sed -e '1,$s/[a-zA-Z]//g'` + version="1.4svn" + revision="-r$rev" + fileversion="1.4svn-r$rev" + fileurl="http://ftp.easysw.com/pub/cups/test/cups-$fileversion-source.tar." + url="." +else + echo Creating tag for release... + rev="1" + version=$1 + revision="" + fileversion=$1 + fileurl="http://ftp.easysw.com/pub/cups/$version/cups-$fileversion-source.tar." + url="https://svn.easysw.com/public/cups/tags/release-$version" + + svn copy https://svn.easysw.com/public/cups/branches/branch-1.4 "$url" \ + -m "Tag $version" || exit 1 +fi + +fileurl=`echo $fileurl | sed -e '1,$s/\\//\\\\\\//g'` + +echo Exporting $fileversion... +rm -rf /tmp/cups-$version +svn export $url /tmp/cups-$version + +echo Updating version information... +cd /tmp/cups-$version/config-scripts + +sed -e '1,$s/^CUPS_VERSION=.*/CUPS_VERSION='$version'/' \ + -e '1,$s/^CUPS_REVISION=.*/CUPS_REVISION='$revision'/' \ + cups-common.m4.new +mv cups-common.m4.new cups-common.m4 +cd .. + +echo Configuring... +autoconf -f +rm -rf autom4te*.cache +rm -rf standards +rm -rf tools +cd .. + +echo -n Archiving...gz +sed -e '1,$s/@CUPS_VERSION@/'$version'/' \ + -e '1,$s/^Release:.*/Release: '$rev'/' \ + -e '1,$s/^Source:.*/Source: '$fileurl'gz/' \ + cups-$version/packaging/cups.spec +tar czf cups-$fileversion-source.tar.gz cups-$version + +echo -n ...bz2 +sed -e '1,$s/@CUPS_VERSION@/'$version'/' \ + -e '1,$s/^Release:.*/Release: '$rev'/' \ + -e '1,$s/^Source:.*/Source: '$fileurl'bz2/' \ + cups-$version/packaging/cups.spec +tar cjf cups-$fileversion-source.tar.bz2 cups-$version +echo "..." + +if test -x /usr/bin/md5sum; then + (cd /tmp; md5sum cups-$fileversion-source.tar.* | awk '{print $1, "'$fileversion' cups/'$fileversion'/" $2}') +elif test -x /sbin/md5; then + (cd /tmp; md5 cups-$fileversion-source.tar.* | awk '{print $4, "'$fileversion' cups/'$fileversion'/" substr($2, 2, length($2) - 2)}') +fi + +echo Removing temporary files... +rm -rf cups-$version + +echo "Done!" + +# +# End of "$Id: makesrcdist 9120 2010-04-23 18:56:34Z mike $". +# diff --git a/tools/products.php b/tools/products.php new file mode 100755 index 0000000000..9c2e7430ea --- /dev/null +++ b/tools/products.php @@ -0,0 +1,50 @@ +#!/usr/bin/php -f + $maxlen) + $maxlen = strlen($data[1]); +} + +pclose($fp); + +arsort($files); + +$current_count = 0; +$current_files = 0; + +foreach ($files as $file => $count) +{ + if ($current_count == 0) + print(basename($file) . " => $count products\n"); + + if ($count != $current_count) + { + if ($current_count != 0) + print("$current_files PPDs with $current_count products.\n"); + + $current_count = $count; + $current_files = 1; + } + else + $current_files ++; +} + +if ($current_count != 0) + print("$current_files PPDs with $current_count products.\n"); + +print("Maximum length of Product string: $maxlen\n"); + +?> diff --git a/tools/testosx b/tools/testosx new file mode 100755 index 0000000000..918e7a41cc --- /dev/null +++ b/tools/testosx @@ -0,0 +1,137 @@ +#!/bin/sh +# Make sure we are running in the right directory... +if test ! -f tools/testosx; then + echo "Run this script from the top-level CUPS source directory, e.g.:" + echo "" + echo " sudo tools/testosx [version]" + echo "" + exit 1 +fi + +if test `whoami` != root; then + echo "Run this script with sudo, e.g.:" + echo "" + echo " sudo tools/testosx [version]" + echo "" + exit 1 +fi + +# Get the current working copy version... +rev=`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[a-zA-Z]*//g'` + +if test $# = 0; then + version="1.4svn-r$rev" +else + version=$1 +fi + +# Setup an install directory... +user=`whoami` +topdir=`pwd` +pkgdir="/tmp/cups.pkg-$user" + +echo Building package using temp directory $pkgdir... +rm -rf $pkgdir +mkdir -p $pkgdir/Package +mkdir -p $pkgdir/Resources + +# Install resource files into the Resources directory... +echo Installing resource files... +cp packaging/LICENSE.rtf $pkgdir/Resources/ReadMe.rtf +sed -e '1,$s/@CUPS_VERSION@/'$version'/g' \ + $pkgdir/Resources/Welcome.rtf +cp packaging/installer.tif $pkgdir/Resources/background.tif + +if test -x /bin/launchctl; then + cat >$pkgdir/Resources/preflight <$pkgdir/Resources/preflight <$pkgdir/Resources/postflight <$pkgdir/Resources/postflight <$file +done + +# Install CUPS into the Package directory... +#make INSTALL=$topdir/install-sh BUILDROOT=$pkgdir/Package install +make BUILDROOT=$pkgdir/Package install || exit 1 + +# Figure out where PackageMaker is installled... +if test -d /Developer/Applications/Utilities/PackageMaker.app; then + PackageMaker=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker +else + PackageMaker=/Developer/Applications/PackageMaker.app/Contents/MacOS/PackageMaker +fi + +# Create the package... +echo Creating MacOS X package... +rm -rf cups.pkg +echo $PackageMaker -build -v -p cups.pkg \ + -f $pkgdir/Package \ + -r $pkgdir/Resources \ + -d packaging/cups-desc.plist \ + -i packaging/cups-info.plist +$PackageMaker -build -v -p cups.pkg \ + -f $pkgdir/Package \ + -r $pkgdir/Resources \ + -d packaging/cups-desc.plist \ + -i packaging/cups-info.plist + +# Create a disk image... +echo Creating MacOS X disk image... +hdiutil create -ov -srcfolder cups.pkg cups-$version.dmg + +# Cleanup temp files... +echo Removing temporary files... +#rm -rf $pkgdir diff --git a/tools/testrpm b/tools/testrpm new file mode 100755 index 0000000000..7d4e9e4a3c --- /dev/null +++ b/tools/testrpm @@ -0,0 +1,32 @@ +#!/bin/sh +# +# "$Id: testrpm 5304 2006-03-18 01:21:37Z mike $" +# +# Test script for making RPMs... +# + +# Make sure we are running in the right directory... +if test ! -f tools/testrpm; then + echo "Run this script from the top-level CUPS source directory, e.g.:" + echo "" + echo " tools/testrpm [rpmbuild options]" + echo "" + exit 1 +fi + +# Strip command-line arguments so we don't create a release tag... +args="$*" +shift $# + +# Get a snapshot of the current source... +. tools/makesrcdist + +# Build the RPM... +echo Building rpm... +rm -f /usr/src/redhat/RPMS/i386/cups*.rpm +rm -f /usr/src/redhat/SRPMS/cups*.rpm +rpmbuild -ta $args cups-$fileversion-source.tar.bz2 + +# +# End of "$Id: testrpm 5304 2006-03-18 01:21:37Z mike $". +# diff --git a/vc2005/cups.sln b/vc2005/cups.sln new file mode 100644 index 0000000000..cfec29e77a --- /dev/null +++ b/vc2005/cups.sln @@ -0,0 +1,78 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcups2", "libcups2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "testfile.vcproj", "{CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testhttp", "testhttp.vcproj", "{90B0058C-8393-411F-BD3B-E2C831D4E883}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cupstestppd", "cupstestppd.vcproj", "{6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E1234} = {CB4AA6F2-3E84-45BE-B505-95CD375E1234} + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcupsimage2", "libcupsimage2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E1234}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.Build.0 = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.Build.0 = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|x64.ActiveCfg = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|x64.Build.0 = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|Win32.ActiveCfg = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|Win32.Build.0 = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|x64.ActiveCfg = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|x64.Build.0 = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|Win32.ActiveCfg = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|Win32.Build.0 = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|x64.ActiveCfg = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|x64.Build.0 = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|Win32.ActiveCfg = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|Win32.Build.0 = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|x64.ActiveCfg = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|x64.Build.0 = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.ActiveCfg = Debug|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.Build.0 = Debug|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.ActiveCfg = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.Build.0 = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.ActiveCfg = Release|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.Build.0 = Release|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.ActiveCfg = Release|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.Build.0 = Release|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.ActiveCfg = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.Build.0 = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.ActiveCfg = Release|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vc2005/cupstestppd.vcproj b/vc2005/cupstestppd.vcproj new file mode 100644 index 0000000000..479afcc1dd --- /dev/null +++ b/vc2005/cupstestppd.vcproj @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vc2005/libcups2.vcproj b/vc2005/libcups2.vcproj new file mode 100644 index 0000000000..a7b06c6d01 --- /dev/null +++ b/vc2005/libcups2.vcproj @@ -0,0 +1,1587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vc2005/libcupsimage2.vcproj b/vc2005/libcupsimage2.vcproj new file mode 100644 index 0000000000..bb1f9efb4d --- /dev/null +++ b/vc2005/libcupsimage2.vcproj @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vc2005/testfile.vcproj b/vc2005/testfile.vcproj new file mode 100644 index 0000000000..edebe6333d --- /dev/null +++ b/vc2005/testfile.vcproj @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vc2005/testhttp.vcproj b/vc2005/testhttp.vcproj new file mode 100644 index 0000000000..77501a2d74 --- /dev/null +++ b/vc2005/testhttp.vcproj @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/config.h b/vcnet/config.h new file mode 100644 index 0000000000..cebe0cbfe6 --- /dev/null +++ b/vcnet/config.h @@ -0,0 +1,705 @@ +/* + * "$Id$" + * + * Configuration file for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +#ifndef _CUPS_CONFIG_H_ +#define _CUPS_CONFIG_H_ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include + + +/* + * Microsoft renames the POSIX functions to _name, and introduces + * a broken compatibility layer using the original names. As a result, + * random crashes can occur when, for example, strdup() allocates memory + * from a different heap than used by malloc() and free(). + * + * To avoid moronic problems like this, we #define the POSIX function + * names to the corresponding non-standard Microsoft names. + */ + +#define access _access +#define close _close +#define fileno _fileno +#define lseek _lseek +#define open _open +#define read _read +#define snprintf _snprintf +#define strdup _strdup +#define unlink _unlink +#define vsnprintf _vsnprintf +#define write _write + + +/* + * Map the POSIX sleep() and usleep() functions to the Win32 Sleep() function... + */ + +#define sleep(X) Sleep(1000 * (X)) +#define usleep(X) Sleep((X)/1000) + + +/* + * Map various parameters to Posix style system calls + */ + +# define F_OK 00 +# define W_OK 02 +# define R_OK 04 +# define O_RDONLY _O_RDONLY +# define O_WRONLY _O_WRONLY +# define O_CREATE _O_CREAT +# define O_TRUNC _O_TRUNC + + +/* + * Compiler stuff... + */ + +#undef const +#undef __CHAR_UNSIGNED__ + + +/* + * Version of software... + */ + +#define CUPS_SVERSION "CUPS v1.4.7" +#define CUPS_MINIMAL "CUPS/1.4.7" + + +/* + * Default user and groups... + */ + +#define CUPS_DEFAULT_USER "" +#define CUPS_DEFAULT_GROUP "" +#define CUPS_DEFAULT_SYSTEM_GROUPS "" +#define CUPS_DEFAULT_PRINTOPERATOR_AUTH "" + + +/* + * Default file permissions... + */ + +#define CUPS_DEFAULT_CONFIG_FILE_PERM 0644 +#define CUPS_DEFAULT_LOG_FILE_PERM 0644 + + +/* + * Default logging settings... + */ + +#define CUPS_DEFAULT_LOG_LEVEL "warn" +#define CUPS_DEFAULT_ACCESS_LOG_LEVEL "actions" + + +/* + * Default fatal error settings... + */ + +#define CUPS_DEFAULT_FATAL_ERRORS "config" + + +/* + * Default browsing settings... + */ + +#define CUPS_DEFAULT_BROWSING 1 +#define CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS "CUPS dnssd" +#define CUPS_DEFAULT_BROWSE_REMOTE_PROTOCOLS "" +#define CUPS_DEFAULT_BROWSE_SHORT_NAMES 1 +#define CUPS_DEFAULT_DEFAULT_SHARED 1 +#define CUPS_DEFAULT_IMPLICIT_CLASSES 1 +#define CUPS_DEFAULT_USE_NETWORK_DEFAULT 0 + + +/* + * Default IPP port... + */ + +#define CUPS_DEFAULT_IPP_PORT 631 + + +/* + * Default printcap file... + */ + +#define CUPS_DEFAULT_PRINTCAP "" + + +/* + * Default Samba and LPD config files... + */ + +#define CUPS_DEFAULT_SMB_CONFIG_FILE "" +#define CUPS_DEFAULT_LPD_CONFIG_FILE "" + + +/* + * Default MaxCopies value... + */ + +#define CUPS_DEFAULT_MAX_COPIES 9999 + + +/* + * Do we have domain socket support? + */ + +#undef CUPS_DEFAULT_DOMAINSOCKET + + +/* + * Where are files stored? + * + * Note: These are defaults, which can be overridden by environment + * variables at run-time... + */ + +#define CUPS_BINDIR "C:/CUPS/bin" +#define CUPS_CACHEDIR "C:/CUPS/cache" +#define CUPS_DATADIR "C:/CUPS/share" +#define CUPS_DOCROOT "C:/CUPS/share/doc" +#define CUPS_FONTPATH "C:/CUPS/share/fonts" +#define CUPS_LOCALEDIR "C:/CUPS/locale" +#define CUPS_LOGDIR "C:/CUPS/logs" +#define CUPS_REQUESTS "C:/CUPS/spool" +#define CUPS_SBINDIR "C:/CUPS/sbin" +#define CUPS_SERVERBIN "C:/CUPS/lib" +#define CUPS_SERVERROOT "C:/CUPS/etc" +#define CUPS_STATEDIR "C:/CUPS/run" + + +/* + * Do we have various image libraries? + */ + +/* #undef HAVE_LIBPNG */ +/* #undef HAVE_LIBZ */ +/* #undef HAVE_LIBJPEG */ +/* #undef HAVE_LIBTIFF */ + + +/* + * Do we have PAM stuff? + */ + +#ifndef HAVE_LIBPAM +#define HAVE_LIBPAM 0 +#endif /* !HAVE_LIBPAM */ + +/* #undef HAVE_PAM_PAM_APPL_H */ +/* #undef HAVE_PAM_SET_ITEM */ +/* #undef HAVE_PAM_SETCRED */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_SHADOW_H */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_CRYPT_H */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_SCSI_SG_H */ + + +/* + * Use , , and/or ? + */ + +#define HAVE_STRING_H 1 +/* #undef HAVE_STRINGS_H */ +/* #undef HAVE_BSTRING_H */ + + +/* + * Do we have the long long type? + */ + +/* #undef HAVE_LONG_LONG */ + +#ifdef HAVE_LONG_LONG +# define CUPS_LLFMT "%lld" +# define CUPS_LLCAST (long long) +#else +# define CUPS_LLFMT "%ld" +# define CUPS_LLCAST (long) +#endif /* HAVE_LONG_LONG */ + + +/* + * Do we have the strtoll() function? + */ + +/* #undef HAVE_STRTOLL */ + +#ifndef HAVE_STRTOLL +# define strtoll(nptr,endptr,base) strtol((nptr), (endptr), (base)) +#endif /* !HAVE_STRTOLL */ + + +/* + * Do we have the strXXX() functions? + */ + +#define HAVE_STRDUP 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +/* #undef HAVE_STRLCAT */ +/* #undef HAVE_STRLCPY */ + + +/* + * Do we have the geteuid() function? + */ + +/* #undef HAVE_GETEUID */ + + +/* + * Do we have the vsyslog() function? + */ + +/* #undef HAVE_VSYSLOG */ + + +/* + * Do we have the (v)snprintf() functions? + */ + +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 + + +/* + * 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 POSIX ACL functions? + */ + +/* #undef HAVE_ACL_INIT */ + + +/* + * Do we have the langinfo.h header file? + */ + +/* #undef HAVE_LANGINFO_H */ + + +/* + * Which encryption libraries do we have? + */ + +/* #undef HAVE_CDSASSL */ +/* #undef HAVE_GNUTLS */ +/* #undef HAVE_LIBSSL */ +/* #undef HAVE_SSL */ + + +/* + * What Security framework headers do we have? + */ + +/* #undef HAVE_AUTHORIZATION_H */ +/* #undef HAVE_SECPOLICY_H */ +/* #undef HAVE_SECPOLICYPRIV_H */ +/* #undef HAVE_SECBASEPRIV_H */ +/* #undef HAVE_SECIDENTITYSEARCHPRIV_H */ + + +/* + * Do we have the SecIdentitySearchCreateWithPolicy function? + */ + +/* #undef HAVE_SECIDENTITYSEARCHCREATEWITHPOLICY */ + + +/* + * Do we have the SLP library? + */ + +/* #undef HAVE_LIBSLP */ + + +/* + * Do we have an LDAP library? + */ + +/* #undef HAVE_LDAP */ +/* #undef HAVE_OPENLDAP */ +/* #undef HAVE_MOZILLA_LDAP */ +/* #undef HAVE_LDAP_SSL_H */ +/* #undef HAVE_LDAP_SSL */ +/* #undef HAVE_LDAP_REBIND_PROC */ + + +/* + * Do we have libpaper? + */ + +/* #undef HAVE_LIBPAPER */ + + +/* + * Do we have DNS Service Discovery (aka Bonjour)? + */ + +/* #undef HAVE_DNSSD */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_SYS_IOCTL_H */ + + +/* + * Does the "tm" structure contain the "tm_gmtoff" member? + */ + +/* #undef HAVE_TM_GMTOFF */ + + +/* + * Do we have rresvport_af()? + */ + +/* #undef HAVE_RRESVPORT_AF */ + + +/* + * Do we have getaddrinfo()? + */ + +#define HAVE_GETADDRINFO 1 + + +/* + * Do we have getnameinfo()? + */ + +#define HAVE_GETNAMEINFO 1 + + +/* + * Do we have getifaddrs()? + */ + +/* #undef HAVE_GETIFADDRS */ + + +/* + * Do we have hstrerror()? + */ + +/* #undef HAVE_HSTRERROR */ + + +/* + * Do we have res_init()? + */ + +/* #undef HAVE_RES_INIT */ + + +/* + * Do we have + */ + +/* #undef HAVE_RESOLV_H */ + + +/* + * Do we have the header file? + */ + +/* #undef HAVE_SYS_SOCKIO_H */ + + +/* + * Does the sockaddr structure contain an sa_len parameter? + */ + +/* #undef HAVE_STRUCT_SOCKADDR_SA_LEN */ + + +/* + * Do we have the AIX usersec.h header file? + */ + +/* #undef HAVE_USERSEC_H */ + + +/* + * Do we have pthread support? + */ + +/* #undef HAVE_PTHREAD_H */ + + +/* + * Do we have launchd support? + */ + +/* #undef HAVE_LAUNCH_H */ +/* #undef HAVE_LAUNCHD */ + + +/* + * Various scripting languages... + */ + +/* #undef HAVE_JAVA */ +#define CUPS_JAVA "" +/* #undef HAVE_PERL */ +#define CUPS_PERL "" +/* #undef HAVE_PHP */ +#define CUPS_PHP "" +/* #undef HAVE_PYTHON */ +#define CUPS_PYTHON "" + + +/* + * Location of the poppler/Xpdf pdftops program... + */ + +/* #undef HAVE_PDFTOPS */ +#define CUPS_PDFTOPS "" + + +/* + * Location of the Ghostscript gs program... + */ + +/* #undef HAVE_GHOSTSCRIPT */ +#define CUPS_GHOSTSCRIPT "" + + +/* + * Do we have Darwin's CoreFoundation and SystemConfiguration frameworks? + */ + +/* #undef HAVE_COREFOUNDATION */ +/* #undef HAVE_SYSTEMCONFIGURATION */ + + +/* + * Do we have CoreFoundation public and private headers? + */ + +/* #undef HAVE_COREFOUNDATION_H */ +/* #undef HAVE_CFPRIV_H */ +/* #undef HAVE_CFBUNDLEPRIV_H */ + + +/* + * Do we have the SCDynamicStoreCopyComputerName function? + */ + +/* #undef HAVE_SCDYNAMICSTORECOPYCOMPUTERNAME */ + + +/* + * Do we have MacOSX 10.4's mbr_XXX functions()? + */ + +/* #undef HAVE_MEMBERSHIP_H */ +/* #undef HAVE_MEMBERSHIPPRIV_H */ +/* #undef HAVE_MBR_UID_TO_UUID */ + + +/* + * Do we have Darwin's notify_post() header and function? + */ + +/* #undef HAVE_NOTIFY_H */ +/* #undef HAVE_NOTIFY_POST */ + + +/* + * Do we have DBUS? + */ + +/* #undef HAVE_DBUS */ +/* #undef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */ + + +/* + * Do we have the AppleTalk/at_proto.h header? + */ + +/* #undef HAVE_APPLETALK_AT_PROTO_H */ + + +/* + * Do we have the GSSAPI support library (for Kerberos support)? + */ + +/* #undef HAVE_GSSAPI */ +/* #undef HAVE_GSSAPI_H */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ +/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ +/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ +/* #undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */ +/* #undef HAVE_GSS_C_NT_HOSTBASED_SERVICE */ +/* #undef HAVE_KRB5_CC_NEW_UNIQUE */ +/* #undef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */ +/* #undef HAVE_KRB5_H */ +/* #undef HAVE_HEIMDAL */ + + +/* + * Default GSS service name... + */ + +#define CUPS_DEFAULT_GSSSERVICENAME "host" + + +/* + * Select/poll interfaces... + */ + +/* #undef HAVE_POLL */ +/* #undef HAVE_EPOLL */ +/* #undef HAVE_KQUEUE */ + + +/* + * Do we have the header? + */ + +/* #undef HAVE_DLFCN_H */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_SYS_PARAM_H */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_SYS_UCRED_H */ + + +/* + * Do we have removefile()? + */ + +/* #undef HAVE_REMOVEFILE */ + + +/* + * Do we have ? + */ + +/* #undef HAVE_SANDBOX_H */ + + +/* + * Which random number generator function to use... + */ + +/* #undef HAVE_ARC4RANDOM */ +/* #undef HAVE_RANDOM */ +/* #undef HAVE_LRAND48 */ + +#ifdef HAVE_ARC4RANDOM +# define CUPS_RAND() arc4random() +# define CUPS_SRAND(v) arc4random_stir() +#elif defined(HAVE_RANDOM) +# define CUPS_RAND() random() +# define CUPS_SRAND(v) srandom(v) +#elif defined(HAVE_LRAND48) +# define CUPS_RAND() lrand48() +# define CUPS_SRAND(v) srand48(v) +#else +# define CUPS_RAND() rand() +# define CUPS_SRAND(v) srand(v) +#endif /* HAVE_ARC4RANDOM */ + + +/* + * Do we have vproc_transaction_begin/end? + */ + +/* #undef HAVE_VPROC_TRANSACTION_BEGIN */ + + +/* + * Do we have libusb? + */ + +/* #undef HAVE_USB_H */ + + +/* + * Do we have libwrap and tcpd.h? + */ + +/* #undef HAVE_TCPD_H */ + + +#endif /* !_CUPS_CONFIG_H_ */ + +/* + * End of "$Id$". + */ diff --git a/vcnet/cups.sln b/vcnet/cups.sln new file mode 100644 index 0000000000..96c46af18d --- /dev/null +++ b/vcnet/cups.sln @@ -0,0 +1,78 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcups2", "libcups2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "testfile.vcproj", "{CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testhttp", "testhttp.vcproj", "{90B0058C-8393-411F-BD3B-E2C831D4E883}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cupstestppd", "cupstestppd.vcproj", "{6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E1234} = {CB4AA6F2-3E84-45BE-B505-95CD375E1234} + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcupsimage2", "libcupsimage2.vcproj", "{CB4AA6F2-3E84-45BE-B505-95CD375E1234}" + ProjectSection(ProjectDependencies) = postProject + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} = {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Debug|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E8BE3}.Release|x64.Build.0 = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.ActiveCfg = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|Win32.Build.0 = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|x64.ActiveCfg = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Debug|x64.Build.0 = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|Win32.ActiveCfg = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|Win32.Build.0 = Debug|Win32 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|x64.ActiveCfg = Debug|x64 + {CE75FC5F-E0CF-45DC-AD27-84666D3FBA30}.Release|x64.Build.0 = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|Win32.ActiveCfg = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|Win32.Build.0 = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|x64.ActiveCfg = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Debug|x64.Build.0 = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|Win32.ActiveCfg = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|Win32.Build.0 = Debug|Win32 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|x64.ActiveCfg = Debug|x64 + {90B0058C-8393-411F-BD3B-E2C831D4E883}.Release|x64.Build.0 = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.ActiveCfg = Debug|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|Win32.Build.0 = Debug|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.ActiveCfg = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Debug|x64.Build.0 = Debug|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.ActiveCfg = Release|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|Win32.Build.0 = Release|Win32 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.ActiveCfg = Release|x64 + {6BE0CDD3-4ED7-409C-A80F-19DF73664B1F}.Release|x64.Build.0 = Release|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|Win32.Build.0 = Debug|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.ActiveCfg = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Debug|x64.Build.0 = Debug|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.ActiveCfg = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|Win32.Build.0 = Release|Win32 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.ActiveCfg = Release|x64 + {CB4AA6F2-3E84-45BE-B505-95CD375E1234}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vcnet/cupstestppd.vcproj b/vcnet/cupstestppd.vcproj new file mode 100644 index 0000000000..8c34169630 --- /dev/null +++ b/vcnet/cupstestppd.vcproj @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/libcups2.vcproj b/vcnet/libcups2.vcproj new file mode 100644 index 0000000000..d70c235e98 --- /dev/null +++ b/vcnet/libcups2.vcproj @@ -0,0 +1,1588 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/libcupsimage2.vcproj b/vcnet/libcupsimage2.vcproj new file mode 100644 index 0000000000..23f3f5b919 --- /dev/null +++ b/vcnet/libcupsimage2.vcproj @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/testfile.vcproj b/vcnet/testfile.vcproj new file mode 100644 index 0000000000..070dd6b1c5 --- /dev/null +++ b/vcnet/testfile.vcproj @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vcnet/testhttp.vcproj b/vcnet/testhttp.vcproj new file mode 100755 index 0000000000..c041ebb753 --- /dev/null +++ b/vcnet/testhttp.vcproj @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.47.3

    + +

    Add Class

    + +

    Class {printer_name} has been added +successfully. + +

)9WL+RtR3G!SiflO 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 t + + +/* + * 'cupsLutDelete()' - Free the memory used by a lookup table. + */ + +void +cupsLutDelete(cups_lut_t *lut) /* I - Lookup table to free */ +{ + if (lut != NULL) + free(lut); +} + + +/* + * 'cupsLutLoad()' - Load a LUT from a PPD file. + */ + +cups_lut_t * /* O - New lookup table */ +cupsLutLoad(ppd_file_t *ppd, /* I - PPD file */ + const char *colormodel, /* I - Color model */ + const char *media, /* I - Media type */ + const char *resolution, /* I - Resolution */ + const char *ink) /* I - Ink name */ +{ + char name[PPD_MAX_NAME], /* Attribute name */ + spec[PPD_MAX_NAME]; /* Attribute spec */ + ppd_attr_t *attr; /* Attribute */ + int nvals; /* Number of values */ + float vals[4]; /* Values */ + + + /* + * Range check input... + */ + + if (!ppd || !colormodel || !media || !resolution || !ink) + return (NULL); + + /* + * Try to find the LUT values... + */ + + snprintf(name, sizeof(name), "cups%sDither", ink); + + if ((attr = cupsFindAttr(ppd, name, colormodel, media, resolution, spec, + sizeof(spec))) == NULL) + attr = cupsFindAttr(ppd, "cupsAllDither", colormodel, media, + resolution, spec, sizeof(spec)); + + if (!attr) + return (NULL); + + vals[0] = 0.0; + vals[1] = 0.0; + vals[2] = 0.0; + vals[3] = 0.0; + nvals = sscanf(attr->value, "%f%f%f", vals + 1, vals + 2, vals + 3) + 1; + + fprintf(stderr, "DEBUG: Loaded LUT %s from PPD with values [%.3f %.3f %.3f %.3f]\n", + name, vals[0], vals[1], vals[2], vals[3]); + + return (cupsLutNew(nvals, vals)); +} + + +/* + * 'cupsLutNew()' - Make a lookup table from a list of pixel values. + * + * Returns a pointer to the lookup table on success, NULL on failure. + */ + +cups_lut_t * /* O - New lookup table */ +cupsLutNew(int num_values, /* I - Number of values */ + const float *values) /* I - Lookup table values */ +{ + int pixel; /* Pixel value */ + cups_lut_t *lut; /* Lookup table */ + int start, /* Start value */ + end, /* End value */ + maxval; /* Maximum value */ + + + /* + * Range check... + */ + + if (!num_values || !values) + return (NULL); + + /* + * Allocate memory for the lookup table... + */ + + if ((lut = (cups_lut_t *)calloc((CUPS_MAX_LUT + 1), + sizeof(cups_lut_t))) == NULL) + return (NULL); + + /* + * Generate the dither lookup table. The pixel values are roughly + * defined by a piecewise linear curve that has an intensity value + * at each output pixel. This isn't perfectly accurate, but it's + * close enough for jazz. + */ + + maxval = CUPS_MAX_LUT / values[num_values - 1]; + + for (start = 0; start <= CUPS_MAX_LUT; start ++) + lut[start].intensity = start * maxval / CUPS_MAX_LUT; + + for (pixel = 0; pixel < num_values; pixel ++) + { + /* + * Select start and end values for this pixel... + */ + + if (pixel == 0) + start = 0; + else + start = (int)(0.5 * maxval * (values[pixel - 1] + + values[pixel])) + 1; + + if (start < 0) + start = 0; + else if (start > CUPS_MAX_LUT) + start = CUPS_MAX_LUT; + + if (pixel == (num_values - 1)) + end = CUPS_MAX_LUT; + else + end = (int)(0.5 * maxval * (values[pixel] + values[pixel + 1])); + + if (end < 0) + end = 0; + else if (end > CUPS_MAX_LUT) + end = CUPS_MAX_LUT; + + if (start == end) + break; + + /* + * Generate lookup values and errors for each pixel. + */ + + while (start <= end) + { + lut[start].pixel = pixel; + if (start == 0) + lut[0].error = 0; + else + lut[start].error = start - maxval * values[pixel]; + + start ++; + } + } + + /* + * Show the lookup table... + */ + + for (start = 0; start <= CUPS_MAX_LUT; start += CUPS_MAX_LUT / 15) + fprintf(stderr, "DEBUG: %d = %d/%d/%d\n", start, lut[start].intensity, + lut[start].pixel, lut[start].error); + + /* + * Return the lookup table... + */ + + return (lut); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/pack.c b/driver/pack.c new file mode 100644 index 0000000000..d9d01d16bb --- /dev/null +++ b/driver/pack.c @@ -0,0 +1,307 @@ +/* + * "$Id$" + * + * Bit packing routines for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsPackHorizontal() - Pack pixels horizontally... + * cupsPackHorizontal2() - Pack 2-bit pixels horizontally... + * cupsPackHorizontalBit() - Pack pixels horizontally by bit... + * cupsPackVertical() - Pack pixels vertically... + */ + +/* + * Include necessary headers... + */ + +#include "driver.h" + + +/* + * 'cupsPackHorizontal()' - Pack pixels horizontally... + */ + +void +cupsPackHorizontal(const unsigned char *ipixels,/* I - Input pixels */ + unsigned char *obytes, /* O - Output bytes */ + int width, /* I - Number of pixels */ + const unsigned char clearto, /* I - Initial value of bytes */ + const int step) /* I - Step value between pixels */ +{ + register unsigned char b; /* Current byte */ + + + /* + * Do whole bytes first... + */ + + while (width > 7) + { + b = clearto; + + if (*ipixels) + b ^= 0x80; + ipixels += step; + if (*ipixels) + b ^= 0x40; + ipixels += step; + if (*ipixels) + b ^= 0x20; + ipixels += step; + if (*ipixels) + b ^= 0x10; + ipixels += step; + if (*ipixels) + b ^= 0x08; + ipixels += step; + if (*ipixels) + b ^= 0x04; + ipixels += step; + if (*ipixels) + b ^= 0x02; + ipixels += step; + if (*ipixels) + b ^= 0x01; + ipixels += step; + + *obytes++ = b; + + width -= 8; + } + + /* + * Then do the last N bytes (N < 8)... + */ + + b = clearto; + + switch (width) + { + case 7 : + if (ipixels[6 * step]) + b ^= 0x02; + case 6 : + if (ipixels[5 * step]) + b ^= 0x04; + case 5 : + if (ipixels[4 * step]) + b ^= 0x08; + case 4 : + if (ipixels[3 * step]) + b ^= 0x10; + case 3 : + if (ipixels[2 * step]) + b ^= 0x20; + case 2 : + if (ipixels[1 * step]) + b ^= 0x40; + case 1 : + if (ipixels[0]) + b ^= 0x80; + *obytes = b; + break; + } +} + + +/* + * 'cupsPackHorizontal2()' - Pack 2-bit pixels horizontally... + */ + +void +cupsPackHorizontal2(const unsigned char *ipixels, /* I - Input pixels */ + unsigned char *obytes, /* O - Output bytes */ + int width, /* I - Number of pixels */ + const int step) /* I - Stepping value */ +{ + register unsigned char b; /* Current byte */ + + + /* + * Do whole bytes first... + */ + + while (width > 3) + { + b = *ipixels; + ipixels += step; + b = (b << 2) | *ipixels; + ipixels += step; + b = (b << 2) | *ipixels; + ipixels += step; + b = (b << 2) | *ipixels; + ipixels += step; + + *obytes++ = b; + + width -= 4; + } + + /* + * Then do the last N bytes (N < 4)... + */ + + b = 0; + + switch (width) + { + case 3 : + b = ipixels[2 * step]; + case 2 : + b = (b << 2) | ipixels[step]; + case 1 : + b = (b << 2) | ipixels[0]; + *obytes = b << (8 - 2 * width); + break; + } +} + + +/* + * 'cupsPackHorizontalBit()' - Pack pixels horizontally by bit... + */ + +void +cupsPackHorizontalBit(const unsigned char *ipixels, /* I - Input pixels */ + unsigned char *obytes, /* O - Output bytes */ + int width, /* I - Number of pixels */ + const unsigned char clearto, /* I - Initial value of bytes */ + const unsigned char bit) /* I - Bit to check */ +{ + register unsigned char b; /* Current byte */ + + + /* + * Do whole bytes first... + */ + + while (width > 7) + { + b = clearto; + + if (*ipixels++ & bit) + b ^= 0x80; + if (*ipixels++ & bit) + b ^= 0x40; + if (*ipixels++ & bit) + b ^= 0x20; + if (*ipixels++ & bit) + b ^= 0x10; + if (*ipixels++ & bit) + b ^= 0x08; + if (*ipixels++ & bit) + b ^= 0x04; + if (*ipixels++ & bit) + b ^= 0x02; + if (*ipixels++ & bit) + b ^= 0x01; + + *obytes++ = b; + + width -= 8; + } + + /* + * Then do the last N bytes (N < 8)... + */ + + b = clearto; + + switch (width) + { + case 7 : + if (ipixels[6] & bit) + b ^= 0x02; + case 6 : + if (ipixels[5] & bit) + b ^= 0x04; + case 5 : + if (ipixels[4] & bit) + b ^= 0x08; + case 4 : + if (ipixels[3] & bit) + b ^= 0x10; + case 3 : + if (ipixels[2] & bit) + b ^= 0x20; + case 2 : + if (ipixels[1] & bit) + b ^= 0x40; + case 1 : + if (ipixels[0] & bit) + b ^= 0x80; + *obytes = b; + break; + } +} + + +/* + * 'cupsPackVertical()' - Pack pixels vertically... + */ + +void +cupsPackVertical(const unsigned char *ipixels, /* I - Input pixels */ + unsigned char *obytes, /* O - Output bytes */ + int width, /* I - Number of input pixels */ + const unsigned char bit, /* I - Output bit */ + const int step) /* I - Number of bytes between columns */ +{ + /* + * Loop through the entire array... + */ + + while (width > 7) + { + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + if (*ipixels++) + *obytes ^= bit; + obytes += step; + + width -= 8; + } + + while (width > 0) + { + if (*ipixels++) + *obytes ^= bit; + + obytes += step; + width --; + } +} + + +/* + * End of "$Id$". + */ diff --git a/driver/pcl-common.c b/driver/pcl-common.c new file mode 100644 index 0000000000..427879338d --- /dev/null +++ b/driver/pcl-common.c @@ -0,0 +1,272 @@ +/* + * "$Id$" + * + * Common PCL functions for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * pcl_set_media_size() - Set media size using the page size command. + * pjl_write() - Write a PJL command string, performing + * substitutions as needed. + */ + +/* + * Include necessary headers... + */ + +#include "driver.h" +#include "pcl-common.h" +#include + + +/* + * 'pcl_set_media_size()' - Set media size using the page size command. + */ + +void +pcl_set_media_size(ppd_file_t *ppd, /* I - PPD file */ + float width, /* I - Width of page */ + float length) /* I - Length of page */ +{ + (void)width; + + printf("\033&l0O"); /* Set portrait orientation */ + + if (ppd->model_number & PCL_PAPER_SIZE) + switch ((int)(length + 0.5f)) + { + case 419 : /* Postcard */ + printf("\033&l71A"); /* Set page size */ + break; + + case 540 : /* Monarch Envelope */ + printf("\033&l80A"); /* Set page size */ + break; + + case 567 : /* Double Postcard */ + printf("\033&l72A"); /* Set page size */ + break; + + case 595 : /* A5 */ + printf("\033&l25A"); /* Set page size */ + break; + + case 612 : /* Statement */ + printf("\033&l5A"); /* 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 729 : /* B5 */ + printf("\033&l45A"); /* 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 936 : /* Foolscap */ + printf("\033&l23A"); /* Set page size */ + break; + + case 1008 : /* Legal */ + printf("\033&l3A"); /* Set page size */ + break; + + case 1032 : /* B4 */ + printf("\033&l46A"); /* Set page size */ + break; + + case 1191 : /* A3 */ + printf("\033&l27A"); /* Set page size */ + break; + + case 1224 : /* Tabloid */ + printf("\033&l6A"); /* Set page size */ + break; + + default : + printf("\033&l101A"); /* Set page size */ + printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */ + printf("\033&l%.2fP", length / 12.0); + /* Set page length */ + printf("\033&l%.0fF", length / 12.0); + /* Set text length to page */ + break; + } + else + { + printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */ + printf("\033&l%.2fP", length / 12.0); + /* Set page length */ + printf("\033&l%.0fF", length / 12.0); + /* Set text length to page */ + } + + printf("\033&l0L"); /* Turn off perforation skip */ + printf("\033&l0E"); /* Reset top margin to 0 */ +} + + +/* + * 'pjl_write()' - Write a PJL command string, performing substitutions as needed. + */ + +void +pjl_write(ppd_file_t *ppd, /* I - PPD file */ + const char *format, /* I - Format string */ + const char *value, /* I - Value for %s */ + int job_id, /* I - Job ID */ + const char *user, /* I - Username */ + const char *title, /* I - Title */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + const char *optval; /* Option value */ + char match[255], /* Match string */ + *mptr; /* Pointer into match string */ + + + if (!format) + return; + + while (*format) + { + if (*format == '%') + { + /* + * Perform substitution... + */ + + format ++; + switch (*format) + { + case 'b' : /* job-billing */ + if ((optval = cupsGetOption("job-billing", num_options, + options)) != NULL) + fputs(optval, stdout); + break; + + case 'h' : /* job-originating-host-name */ + if ((optval = cupsGetOption("job-originating-host-name", + num_options, options)) != NULL) + fputs(optval, stdout); + break; + + case 'j' : /* job-id */ + printf("%d", job_id); + break; + + case 'n' : /* CR + LF */ + putchar('\r'); + putchar('\n'); + break; + + case 'q' : /* double quote (") */ + putchar('\"'); + break; + + case 's' : /* "value" */ + if (value) + fputs(value, stdout); + break; + + case 't' : /* job-name */ + fputs(title, stdout); + break; + + case 'u' : /* job-originating-user-name */ + fputs(user, stdout); + break; + + case '?' : /* ?value:string; */ + /* + * Get the match value... + */ + + for (format ++, mptr = match; *format && *format != ':'; format ++) + if (mptr < (match + sizeof(match) - 1)) + *mptr++ = *format; + + if (!*format) + return; + + /* + * See if we have a match... + */ + + format ++; + *mptr = '\0'; + + if (!value || strcmp(match, value)) + { + /* + * Value doesn't match; skip the string that follows... + */ + + while (*format && *format != ';') + format ++; + } + else + { + /* + * Value matches; copy the string that follows... + */ + + while (*format && *format != ';') + putchar(*format++); + } + + if (!*format) + return; + break; + + default : /* Anything else */ + putchar('%'); + case '%' : /* %% = single % */ + putchar(*format); + break; + } + } + else + putchar(*format); + + format ++; + } +} + + +/* + * End of "$Id$". + */ diff --git a/driver/pcl-common.h b/driver/pcl-common.h new file mode 100644 index 0000000000..17819ab01d --- /dev/null +++ b/driver/pcl-common.h @@ -0,0 +1,71 @@ +/* + * "$Id$" + * + * Common HP-PCL definitions for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products, All Rights Reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Include necessary headers... + */ + +#include +#include "data/pcl.h" + + +/* + * Functions/macros... + */ + +#define pcl_reset()\ + printf("\033E") +#define pcl_set_copies(copies)\ + printf("\033&l%dX", (copies)) +#define pcl_set_pcl_mode(m)\ + printf("\033%%%dA", (m)) +#define pcl_set_hpgl_mode(m)\ + printf("\033%%%dB", (m)) +#define pcl_set_negative_motion()\ + printf("\033&a1N") +#define pcl_set_media_source(source)\ + printf("\033&l%dH", source) +#define pcl_set_media_type(type)\ + printf("\033&l%dM", type) +#define pcl_set_duplex(duplex,landscape)\ + if (duplex) printf("\033&l%dS", (duplex) + (landscape)) +#define pcl_set_simple_black()\ + printf("\033*r-1U") +#define pcl_set_simple_color()\ + printf("\033*r3U") +#define pcl_set_simple_cmy()\ + printf("\033*r-3U") +#define pcl_set_simple_kcmy()\ + printf("\033*r-4U") +#define pcl_set_simple_resolution(r)\ + printf("\033*t%dR", (r)) + +#define pjl_escape()\ + printf("\033%%-12345X@PJL\r\n") +#define pjl_set_job(job_id,user,title)\ + printf("@PJL JOB NAME = \"%s\" DISPLAY = \"%d %s %s\"\r\n", \ + (title), (job_id), (user), (title)) +#define pjl_enter_language(lang)\ + printf("@PJL ENTER LANGUAGE=%s\r\n", (lang)) + +extern void pcl_set_media_size(ppd_file_t *ppd, float width, float length); +extern void pjl_write(ppd_file_t *ppd, const char *format, + const char *value, int job_id, + const char *user, const char *title, + int num_options, cups_option_t *options); + +/* + * End of "$Id$". + */ diff --git a/driver/rastertoescpx.c b/driver/rastertoescpx.c new file mode 100644 index 0000000000..6f08f71416 --- /dev/null +++ b/driver/rastertoescpx.c @@ -0,0 +1,1919 @@ +/* + * "$Id$" + * + * Advanced EPSON ESC/P raster driver for CUPS. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * Setup() - Prepare the printer for graphics output. + * StartPage() - Start a page of graphics. + * EndPage() - Finish a page of graphics. + * Shutdown() - Shutdown a printer. + * CancelJob() - Cancel the current job... + * CompressData() - Compress a line of graphics. + * OutputBand() - Output a band of graphics. + * ProcessLine() - Read graphics from the page stream and output + * as needed. + * main() - Main entry and processing of driver. + */ + +/* + * Include necessary headers... + */ + +#include "driver.h" +#include +#include +#include "data/escp.h" +#include +#include + + +/* + * Softweave data... + */ + +typedef struct cups_weave_str +{ + struct cups_weave_str *prev, /* Previous band */ + *next; /* Next band */ + int x, y, /* Column/Line on the page */ + plane, /* Color plane */ + dirty, /* Is this buffer dirty? */ + row, /* Row in the buffer */ + count; /* Max rows this pass */ + unsigned char *buffer; /* Data buffer */ +} cups_weave_t; + + +/* + * Globals... + */ + +cups_rgb_t *RGB; /* RGB color separation data */ +cups_cmyk_t *CMYK; /* CMYK color separation data */ +unsigned char *PixelBuffer, /* Pixel buffer */ + *CMYKBuffer, /* CMYK buffer */ + *OutputBuffers[7], /* Output buffers */ + *DotBuffers[7], /* Dot buffers */ + *CompBuffer; /* Compression buffer */ +short *InputBuffer; /* Color separation buffer */ +cups_weave_t *DotAvailList, /* Available buffers */ + *DotUsedList, /* Used buffers */ + *DotBands[128][7]; /* Buffers in use */ +int DotBufferSize, /* Size of dot buffers */ + DotRowMax, /* Maximum row number in buffer */ + DotColStep, /* Step for each output column */ + DotRowStep, /* Step for each output line */ + DotRowFeed, /* Amount to feed for interleave */ + DotRowCount, /* Number of rows to output */ + DotRowOffset[7], /* Offset for each color on print head */ + DotRowCurrent, /* Current row */ + DotSize; /* Dot size (Pro 5000 only) */ +int PrinterPlanes, /* # of color planes */ + BitPlanes, /* # of bit planes per color */ + PrinterTop, /* Top of page */ + PrinterLength; /* Length of page */ +cups_lut_t *DitherLuts[7]; /* Lookup tables for dithering */ +cups_dither_t *DitherStates[7]; /* Dither state tables */ +int OutputFeed; /* Number of lines to skip */ +int Canceled; /* Is the job canceled? */ + + +/* + * Prototypes... + */ + +void Setup(ppd_file_t *); +void StartPage(ppd_file_t *, cups_page_header2_t *); +void EndPage(ppd_file_t *, cups_page_header2_t *); +void Shutdown(ppd_file_t *); + +void AddBand(cups_weave_t *band); +void CancelJob(int sig); +void CompressData(ppd_file_t *, const unsigned char *, const int, + int, int, const int, const int, const int, + const int); +void OutputBand(ppd_file_t *, cups_page_header2_t *, + cups_weave_t *band); +void ProcessLine(ppd_file_t *, cups_raster_t *, + cups_page_header2_t *, const int y); + + +/* + * 'Setup()' - Prepare a printer for graphics output. + */ + +void +Setup(ppd_file_t *ppd) /* I - PPD file */ +{ + /* + * Some EPSON printers need an additional command issued at the + * beginning of each job to exit from USB "packet" mode... + */ + + if (ppd->model_number & ESCP_USB) + cupsWritePrintData("\000\000\000\033\001@EJL 1284.4\n@EJL \n\033@", 29); +} + + +/* + * 'StartPage()' - Start a page of graphics. + */ + +void +StartPage(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header) /* I - Page header */ +{ + int i, y; /* Looping vars */ + int subrow, /* Current subrow */ + modrow, /* Subrow modulus */ + plane; /* Current color plane */ + unsigned char *ptr; /* Pointer into dot buffer */ + int bands; /* Number of bands to allocate */ + int units; /* Units for resolution */ + cups_weave_t *band; /* Current band */ + const char *colormodel; /* Color model string */ + char resolution[PPD_MAX_NAME], + /* Resolution string */ + spec[PPD_MAX_NAME]; /* PPD attribute name */ + ppd_attr_t *attr; /* Attribute from PPD file */ + const float default_lut[2] = /* Default dithering lookup table */ + { + 0.0, + 1.0 + }; + + + fprintf(stderr, "DEBUG: StartPage...\n"); + fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass); + fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor); + fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType); + fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType); + + fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance); + fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia); + fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate); + fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia); + fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex); + fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0], + header->HWResolution[1]); + fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", + header->ImagingBoundingBox[0], header->ImagingBoundingBox[1], + header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]); + fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet); + fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog); + fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge); + fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0], + header->Margins[1]); + fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed); + fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition); + fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight); + fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint); + fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint); + fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies); + fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation); + fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp); + fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0], + header->PageSize[1]); + fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations); + fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch); + fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble); + fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth); + fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight); + fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType); + 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: cupsCompression = %d\n", header->cupsCompression); + fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount); + fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed); + fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep); + + /* + * Figure out the color model and spec strings... + */ + + switch (header->cupsColorSpace) + { + case CUPS_CSPACE_K : + colormodel = "Black"; + break; + case CUPS_CSPACE_W : + colormodel = "Gray"; + break; + default : + case CUPS_CSPACE_RGB : + colormodel = "RGB"; + break; + case CUPS_CSPACE_CMYK : + colormodel = "CMYK"; + break; + } + + if (header->HWResolution[0] != header->HWResolution[1]) + snprintf(resolution, sizeof(resolution), "%dx%ddpi", + header->HWResolution[0], header->HWResolution[1]); + else + snprintf(resolution, sizeof(resolution), "%ddpi", + header->HWResolution[0]); + + if (!header->MediaType[0]) + strcpy(header->MediaType, "Plain"); + + /* + * Load the appropriate color profiles... + */ + + RGB = NULL; + CMYK = NULL; + + fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr); + fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel); + fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType); + fprintf(stderr, "DEBUG: Resolution = %s\n", resolution); + + if (header->cupsColorSpace == CUPS_CSPACE_RGB || + header->cupsColorSpace == CUPS_CSPACE_W) + RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution); + else + RGB = NULL; + + CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution); + + if (RGB) + fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr); + + if (CMYK) + fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr); + else + { + fputs("DEBUG: Loading default CMYK separation.\n", stderr); + CMYK = cupsCMYKNew(4); + } + + PrinterPlanes = CMYK->num_channels; + + fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes); + + /* + * Get the dithering parameters... + */ + + switch (PrinterPlanes) + { + case 1 : /* K */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + break; + + case 2 : /* Kk */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightBlack"); + break; + + case 3 : /* CMY */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + break; + + case 4 : /* CMYK */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + break; + + case 6 : /* CcMmYK */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightCyan"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightMagenta"); + DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + break; + + case 7 : /* CcMmYKk */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightCyan"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightMagenta"); + DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + DitherLuts[6] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightBlack"); + break; + } + + for (plane = 0; plane < PrinterPlanes; plane ++) + { + DitherStates[plane] = cupsDitherNew(header->cupsWidth); + + if (!DitherLuts[plane]) + DitherLuts[plane] = cupsLutNew(2, default_lut); + } + + if (DitherLuts[0][4095].pixel > 1) + BitPlanes = 2; + else + BitPlanes = 1; + + /* + * Initialize the printer... + */ + + printf("\033@"); + + if (ppd->model_number & ESCP_REMOTE) + { + /* + * Go into remote mode... + */ + + cupsWritePrintData("\033(R\010\000\000REMOTE1", 13); + + /* + * Disable status reporting... + */ + + cupsWritePrintData("ST\002\000\000\000", 6); + + /* + * Enable borderless printing... + */ + + if ((attr = ppdFindAttr(ppd, "cupsESCPFP", NULL)) != NULL && attr->value) + { + /* + * Set horizontal offset... + */ + + i = atoi(attr->value); + + cupsWritePrintData("FP\003\000\000", 5); + putchar(i & 255); + putchar(i >> 8); + } + + /* + * Set media type... + */ + + if (header->cupsMediaType) + { + sprintf(spec, "%d", header->cupsMediaType); + + if ((attr = ppdFindAttr(ppd, "cupsESCPSN0", spec)) != NULL && attr->value) + { + /* + * Set feed sequence... + */ + + cupsWritePrintData("SN\003\000\000\000", 6); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPSN1", spec)) != NULL && attr->value) + { + /* + * Set platten gap... + */ + + cupsWritePrintData("SN\003\000\000\001", 6); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPSN2", spec)) != NULL && attr->value) + { + /* + * Paper feeding/ejecting sequence... + */ + + cupsWritePrintData("SN\003\000\000\002", 6); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPSN6", spec)) != NULL && attr->value) + { + /* + * Eject delay... + */ + + cupsWritePrintData("SN\003\000\000\006", 6); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPMT", spec)) != NULL && attr->value) + { + /* + * Set media type. + */ + + cupsWritePrintData("MT\003\000\000\000", 6); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPPH", spec)) != NULL && attr->value) + { + /* + * Set paper thickness. + */ + + cupsWritePrintData("PH\002\000\000", 5); + putchar(atoi(attr->value)); + } + } + + sprintf(spec, "%d", header->MediaPosition); + + if (header->MediaPosition) + { + if ((attr = ppdFindAttr(ppd, "cupsESCPPC", spec)) != NULL && attr->value) + { + /* + * Paper check. + */ + + cupsWritePrintData("PC\002\000\000", 5); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPPP", spec)) != NULL && attr->value) + { + /* + * Paper path. + */ + + int a, b; + + a = b = 0; + sscanf(attr->value, "%d%d", &a, &b); + + cupsWritePrintData("PP\003\000\000", 5); + putchar(a); + putchar(b); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPEX", spec)) != NULL && attr->value) + { + /* + * Set media position. + */ + + cupsWritePrintData("EX\006\000\000\000\000\000\005", 9); + putchar(atoi(attr->value)); + } + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPMS", spec)) != NULL && attr->value) + { + /* + * Set media size... + */ + + cupsWritePrintData("MS\010\000\000", 5); + putchar(atoi(attr->value)); + + switch (header->PageSize[1]) + { + case 1191 : /* A3 */ + putchar(0x01); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 1032 : /* B4 */ + putchar(0x02); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 842 : /* A4 */ + putchar(0x03); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 595 : /* A4.Transverse */ + putchar(0x03); + putchar(0x01); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 729 : /* B5 */ + putchar(0x04); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 516 : /* B5.Transverse */ + putchar(0x04); + putchar(0x01); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 1369 : /* Super A3/B */ + putchar(0x20); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 792 : /* Letter */ + putchar(0x08); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 612 : /* Letter.Transverse */ + putchar(0x08); + putchar(0x01); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 1004 : /* Legal */ + putchar(0x0a); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + case 1224 : /* Tabloid */ + putchar(0x2d); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + putchar(0x00); + break; + default : /* Custom size */ + putchar(0xff); + putchar(0xff); + i = 360 * header->PageSize[0] / 72; + putchar(i); + putchar(i >> 8); + i = 360 * header->PageSize[1] / 72; + putchar(i); + putchar(i >> 8); + break; + } + } + + sprintf(spec, "%d", header->CutMedia); + + if ((attr = ppdFindAttr(ppd, "cupsESCPAC", spec)) != NULL && attr->value) + { + /* + * Enable/disable cutter. + */ + + cupsWritePrintData("AC\002\000\000", 5); + putchar(atoi(attr->value)); + + if ((attr = ppdFindAttr(ppd, "cupsESCPSN80", header->MediaType)) != NULL && attr->value) + { + /* + * Cutting method... + */ + + cupsWritePrintData("SN\003\000\000\200", 6); + putchar(atoi(attr->value)); + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPSN81", header->MediaType)) != NULL && attr->value) + { + /* + * Cutting pressure... + */ + + cupsWritePrintData("SN\003\000\000\201", 6); + putchar(atoi(attr->value)); + } + } + + if ((attr = ppdFindAttr(ppd, "cupsESCPCO", spec)) != NULL && attr->value) + { + /* + * Enable/disable cutter. + */ + + cupsWritePrintData("CO\010\000\000\000", 6); + putchar(atoi(attr->value)); + cupsWritePrintData("\000\000\000\000\000", 5); + } + + /* + * Exit remote mode... + */ + + cupsWritePrintData("\033\000\000\000", 4); + } + + /* + * Enter graphics mode... + */ + + cupsWritePrintData("\033(G\001\000\001", 6); + + /* + * Set the line feed increment... + */ + + /* TODO: get this from the PPD file... */ + for (units = 1440; units < header->HWResolution[0]; units *= 2); + + if (ppd->model_number & ESCP_EXT_UNITS) + { + cupsWritePrintData("\033(U\005\000", 5); + putchar(units / header->HWResolution[1]); + putchar(units / header->HWResolution[1]); + putchar(units / header->HWResolution[0]); + putchar(units); + putchar(units >> 8); + } + else + { + cupsWritePrintData("\033(U\001\000", 5); + putchar(3600 / header->HWResolution[1]); + } + + /* + * Set the page length... + */ + + PrinterLength = header->PageSize[1] * header->HWResolution[1] / 72; + + if (ppd->model_number & ESCP_PAGE_SIZE) + { + /* + * Set page size (expands bottom margin)... + */ + + cupsWritePrintData("\033(S\010\000", 5); + + i = header->PageSize[0] * header->HWResolution[1] / 72; + putchar(i); + putchar(i >> 8); + putchar(i >> 16); + putchar(i >> 24); + + i = header->PageSize[1] * header->HWResolution[1] / 72; + putchar(i); + putchar(i >> 8); + putchar(i >> 16); + putchar(i >> 24); + } + else + { + cupsWritePrintData("\033(C\002\000", 5); + putchar(PrinterLength & 255); + putchar(PrinterLength >> 8); + } + + /* + * Set the top and bottom margins... + */ + + PrinterTop = (int)((ppd->sizes[1].length - ppd->sizes[1].top) * + header->HWResolution[1] / 72.0); + + if (ppd->model_number & ESCP_EXT_MARGINS) + { + cupsWritePrintData("\033(c\010\000", 5); + + putchar(PrinterTop); + putchar(PrinterTop >> 8); + putchar(PrinterTop >> 16); + putchar(PrinterTop >> 24); + + putchar(PrinterLength); + putchar(PrinterLength >> 8); + putchar(PrinterLength >> 16); + putchar(PrinterLength >> 24); + } + else + { + cupsWritePrintData("\033(c\004\000", 5); + + putchar(PrinterTop & 255); + putchar(PrinterTop >> 8); + + putchar(PrinterLength & 255); + putchar(PrinterLength >> 8); + } + + /* + * Set the top position... + */ + + cupsWritePrintData("\033(V\002\000\000\000", 7); + + /* + * Enable unidirectional printing depending on the mode... + */ + + if ((attr = cupsFindAttr(ppd, "cupsESCPDirection", colormodel, + header->MediaType, resolution, spec, + sizeof(spec))) != NULL) + printf("\033U%c", atoi(attr->value)); + + /* + * Enable/disable microweaving as needed... + */ + + if ((attr = cupsFindAttr(ppd, "cupsESCPMicroWeave", colormodel, + header->MediaType, resolution, spec, + sizeof(spec))) != NULL) + printf("\033(i\001%c%c", 0, atoi(attr->value)); + + /* + * Set the dot size and print speed as needed... + */ + + if ((attr = cupsFindAttr(ppd, "cupsESCPDotSize", colormodel, + header->MediaType, resolution, spec, + sizeof(spec))) != NULL) + printf("\033(e\002%c%c%c", 0, 0, atoi(attr->value)); + + if (ppd->model_number & ESCP_ESCK) + { + /* + * Set the print mode... + */ + + if (PrinterPlanes == 1) + { + /* + * Fast black printing. + */ + + cupsWritePrintData("\033(K\002\000\000\001", 7); + } + else + { + /* + * Color printing. + */ + + cupsWritePrintData("\033(K\002\000\000\002", 7); + } + } + + /* + * Get softweave settings from header... + */ + + if (header->cupsRowCount <= 1) + { + DotRowCount = 1; + DotColStep = 1; + DotRowStep = 1; + DotRowFeed = 1; + } + else + { + DotRowCount = header->cupsRowCount; + DotRowFeed = header->cupsRowFeed; + DotRowStep = header->cupsRowStep % 100; + DotColStep = header->cupsRowStep / 100; + + if (DotColStep == 0) + DotColStep ++; + } + + /* + * Setup softweave parameters... + */ + + DotRowCurrent = 0; + DotRowMax = DotRowCount * DotRowStep; + DotBufferSize = (header->cupsWidth / DotColStep * BitPlanes + 7) / 8; + + fprintf(stderr, "DEBUG: DotBufferSize = %d\n", DotBufferSize); + fprintf(stderr, "DEBUG: DotColStep = %d\n", DotColStep); + fprintf(stderr, "DEBUG: DotRowMax = %d\n", DotRowMax); + fprintf(stderr, "DEBUG: DotRowStep = %d\n", DotRowStep); + fprintf(stderr, "DEBUG: DotRowFeed = %d\n", DotRowFeed); + fprintf(stderr, "DEBUG: DotRowCount = %d\n", DotRowCount); + + DotAvailList = NULL; + DotUsedList = NULL; + DotBuffers[0] = NULL; + + fprintf(stderr, "DEBUG: model_number = %x\n", ppd->model_number); + + if (DotRowMax > 1) + { + /* + * Compute offsets for the color jets on the print head... + */ + + bands = DotRowStep * DotColStep * PrinterPlanes * 4; + + memset(DotRowOffset, 0, sizeof(DotRowOffset)); + + if (PrinterPlanes == 1) + { + /* + * Use full height of print head... + */ + + if ((attr = ppdFindAttr(ppd, "cupsESCPBlack", resolution)) != NULL && + attr->value) + { + /* + * Use custom black head data... + */ + + sscanf(attr->value, "%d%d", &DotRowCount, &DotRowStep); + } + } + else if (ppd->model_number & ESCP_STAGGER) + { + /* + * Use staggered print head... + */ + + fputs("DEBUG: Offset head detected...\n", stderr); + + if ((attr = ppdFindAttr(ppd, "cupsESCPOffsets", resolution)) != NULL && + attr->value) + { + /* + * Use only 1/3 of the print head when printing color... + */ + + sscanf(attr->value, "%d%d%d%d", DotRowOffset + 0, + DotRowOffset + 1, DotRowOffset + 2, DotRowOffset + 3); + } + } + + for (i = 0; i < PrinterPlanes; i ++) + fprintf(stderr, "DEBUG: DotRowOffset[%d] = %d\n", i, DotRowOffset[i]); + + /* + * Allocate bands... + */ + + for (i = 0; i < bands; i ++) + { + band = (cups_weave_t *)calloc(1, sizeof(cups_weave_t)); + band->next = DotAvailList; + DotAvailList = band; + + band->buffer = calloc(DotRowCount, DotBufferSize); + } + + if (!DotAvailList) + { + fputs("ERROR: Unable to allocate band list!\n", stderr); + exit(1); + } + + fputs("DEBUG: Pointer list at start of page...\n", stderr); + + for (band = DotAvailList; band != NULL; band = band->next) + fprintf(stderr, "DEBUG: %p\n", band); + + fputs("DEBUG: ----END----\n", stderr); + + /* + * Fill the initial bands... + */ + + modrow = DotColStep * DotRowStep; + + if (DotRowFeed == 0) + { + /* + * Automatically compute the optimal feed value... + */ + + DotRowFeed = DotRowCount / DotColStep - DotRowStep; + + while ((((DotRowFeed % 2) == 0) == ((DotRowCount % 2) == 0) || + ((DotRowFeed % 3) == 0) == ((DotRowCount % 3) == 0) || + ((DotRowFeed % 5) == 0) == ((DotRowCount % 5) == 0)) && + DotRowFeed > 1) + DotRowFeed --; + + if (DotRowFeed < 1) + DotRowFeed = 1; + + fprintf(stderr, "DEBUG: Auto DotRowFeed = %d, modrow=%d...\n", + DotRowFeed, modrow); + } + + memset(DotBands, 0, sizeof(DotBands)); + + for (i = modrow, subrow = modrow - 1, y = DotRowFeed; + i > 0; + i --, y += DotRowFeed) + { + while (DotBands[subrow][0]) + { + /* + * This subrow is already used, move to another one... + */ + + subrow = (subrow + 1) % modrow; + } + + for (plane = 0; plane < PrinterPlanes; plane ++) + { + /* + * Pull the next available band from the list... + */ + + band = DotAvailList; + DotAvailList = DotAvailList->next; + DotBands[subrow][plane] = band; + + /* + * Start the band in the first few passes, with the number of rows + * varying to allow for a nice interleaved pattern... + */ + + band->x = subrow / DotRowStep; + band->y = (subrow % DotRowStep) + DotRowOffset[plane]; + band->plane = plane; + band->row = 0; + band->count = DotRowCount - y / DotRowStep; + + if (band->count < 1) + band->count = 1; + else if (band->count > DotRowCount) + band->count = DotRowCount; + + fprintf(stderr, "DEBUG: DotBands[%d][%d] = %p, x = %d, y = %d, plane = %d, count = %d\n", + subrow, plane, band, band->x, band->y, band->plane, band->count); + } + + subrow = (subrow + DotRowFeed) % modrow; + } + } + else + { + /* + * Allocate memory for a single line of graphics... + */ + + ptr = calloc(PrinterPlanes, DotBufferSize); + + for (plane = 0; plane < PrinterPlanes; plane ++, ptr += DotBufferSize) + DotBuffers[plane] = ptr; + } + + /* + * Set the output resolution... + */ + + cupsWritePrintData("\033(D\004\000", 5); + putchar(units); + putchar(units >> 8); + putchar(units * DotRowStep / header->HWResolution[1]); + putchar(units * DotColStep / header->HWResolution[0]); + + /* + * Set the top of form... + */ + + OutputFeed = 0; + + /* + * Allocate buffers as needed... + */ + + PixelBuffer = malloc(header->cupsBytesPerLine); + InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2); + OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth); + + for (i = 1; i < PrinterPlanes; i ++) + OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth; + + if (RGB) + CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes); + + CompBuffer = malloc(10 * DotBufferSize * DotRowMax); +} + + +/* + * 'EndPage()' - Finish a page of graphics. + */ + +void +EndPage(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header) /* I - Page header */ +{ + int i; /* Looping var */ + cups_weave_t *band, /* Current band */ + *next; /* Next band in list */ + int plane; /* Current plane */ + int subrow; /* Current subrow */ + int subrows; /* Number of subrows */ + + + /* + * Output the last bands of print data as necessary... + */ + + if (DotRowMax > 1) + { + /* + * Move the remaining bands to the used or avail lists... + */ + + subrows = DotRowStep * DotColStep; + + for (subrow = 0; subrow < subrows; subrow ++) + for (plane = 0; plane < PrinterPlanes; plane ++) + { + if (DotBands[subrow][plane]->dirty) + { + /* + * Insert into the used list... + */ + + DotBands[subrow][plane]->count = DotBands[subrow][plane]->row; + + AddBand(DotBands[subrow][plane]); + } + else + { + /* + * Nothing here, so move it to the available list... + */ + + DotBands[subrow][plane]->next = DotAvailList; + DotAvailList = DotBands[subrow][plane]; + } + + DotBands[subrow][plane] = NULL; + } + + /* + * Loop until all bands are written... + */ + + fputs("DEBUG: Pointer list at end of page...\n", stderr); + + for (band = DotUsedList; band != NULL; band = band->next) + fprintf(stderr, "DEBUG: %p (used)\n", band); + for (band = DotAvailList; band != NULL; band = band->next) + fprintf(stderr, "DEBUG: %p (avail)\n", band); + + fputs("DEBUG: ----END----\n", stderr); + + for (band = DotUsedList; band != NULL; band = next) + { + next = band->next; + + OutputBand(ppd, header, band); + + fprintf(stderr, "DEBUG: freeing used band %p, prev = %p, next = %p\n", + band, band->prev, band->next); + + free(band->buffer); + free(band); + } + + /* + * Free memory for the available bands, if any... + */ + + for (band = DotAvailList; band != NULL; band = next) + { + next = band->next; + + fprintf(stderr, "DEBUG: freeing avail band %p, prev = %p, next = %p\n", + band, band->prev, band->next); + + free(band->buffer); + free(band); + } + } + else + free(DotBuffers[0]); + + /* + * Output a page eject sequence... + */ + + putchar(12); + + /* + * Free memory for the page... + */ + + for (i = 0; i < PrinterPlanes; i ++) + { + cupsDitherDelete(DitherStates[i]); + cupsLutDelete(DitherLuts[i]); + } + + free(OutputBuffers[0]); + + free(PixelBuffer); + free(InputBuffer); + free(CompBuffer); + + cupsCMYKDelete(CMYK); + + if (RGB) + { + cupsRGBDelete(RGB); + free(CMYKBuffer); + } +} + + +/* + * 'Shutdown()' - Shutdown a printer. + */ + +void +Shutdown(ppd_file_t *ppd) /* I - PPD file */ +{ + /* + * Reset the printer... + */ + + printf("\033@"); + + if (ppd->model_number & ESCP_REMOTE) + { + /* + * Go into remote mode... + */ + + cupsWritePrintData("\033(R\010\000\000REMOTE1", 13); + + /* + * Load defaults... + */ + + cupsWritePrintData("LD\000\000", 4); + + /* + * Exit remote mode... + */ + + cupsWritePrintData("\033\000\000\000", 4); + } +} + + +/* + * 'AddBand()' - Add a band of data to the used list. + */ + +void +AddBand(cups_weave_t *band) /* I - Band to add */ +{ + cups_weave_t *current, /* Current band */ + *prev; /* Previous band */ + + + if (band->count < 1) + return; + + for (current = DotUsedList, prev = NULL; + current != NULL; + prev = current, current = current->next) + if (band->y < current->y || + (band->y == current->y && band->x < current->x) || + (band->y == current->y && band->x == current->x && + band->plane < current->plane)) + break; + + if (current != NULL) + { + /* + * Insert the band... + */ + + band->next = current; + band->prev = prev; + current->prev = band; + + if (prev != NULL) + prev->next = band; + else + DotUsedList = band; + } + else if (prev != NULL) + { + /* + * Append the band to the end... + */ + + band->prev = prev; + prev->next = band; + band->next = NULL; + } + else + { + /* + * First band in list... + */ + + DotUsedList = band; + band->prev = NULL; + band->next = NULL; + } +} + + +/* + * 'CancelJob()' - Cancel the current job... + */ + +void +CancelJob(int sig) /* I - Signal */ +{ + (void)sig; + + Canceled = 1; +} + + +/* + * 'CompressData()' - Compress a line of graphics. + */ + +void +CompressData(ppd_file_t *ppd, /* I - PPD file information */ + const unsigned char *line, /* I - Data to compress */ + const int length,/* I - Number of bytes */ + int plane, /* I - Color plane */ + int type, /* I - Type of compression */ + const int rows, /* I - Number of lines to write */ + const int xstep, /* I - Spacing between columns */ + const int ystep, /* I - Spacing between lines */ + const int offset)/* I - Head offset */ +{ + register const unsigned char *line_ptr, + /* Current byte pointer */ + *line_end, /* End-of-line byte pointer */ + *start; /* Start of compression sequence */ + register unsigned char *comp_ptr; /* Pointer into compression buffer */ + register int count; /* Count of bytes for output */ + register int bytes; /* Number of bytes per row */ + static int ctable[7][7] = /* Colors */ + { + { 0, 0, 0, 0, 0, 0, 0 }, /* K */ + { 0, 16, 0, 0, 0, 0, 0 }, /* Kk */ + { 2, 1, 4, 0, 0, 0, 0 }, /* CMY */ + { 2, 1, 4, 0, 0, 0, 0 }, /* CMYK */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 2, 18, 1, 17, 4, 0, 0 }, /* CcMmYK */ + { 2, 18, 1, 17, 4, 0, 16 }, /* CcMmYKk */ + }; + + + switch (type) + { + case 0 : + /* + * Do no compression... + */ + + line_ptr = (const unsigned char *)line; + line_end = (const unsigned char *)line + length; + break; + + default : + /* + * Do TIFF pack-bits encoding... + */ + + line_ptr = (const unsigned char *)line; + line_end = (const unsigned char *)line + length; + comp_ptr = CompBuffer; + + while (line_ptr < line_end && (comp_ptr - CompBuffer) < length) + { + 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; + } + } + + if ((comp_ptr - CompBuffer) < length) + { + line_ptr = (const unsigned char *)CompBuffer; + line_end = (const unsigned char *)comp_ptr; + } + else + { + type = 0; + line_ptr = (const unsigned char *)line; + line_end = (const unsigned char *)line + length; + } + break; + } + + /* + * Position the print head... + */ + + putchar(0x0d); + + if (offset) + { + if (BitPlanes == 1) + cupsWritePrintData("\033(\\\004\000\240\005", 7); + else + printf("\033\\"); + + putchar(offset); + putchar(offset >> 8); + } + + /* + * Send the graphics... + */ + + bytes = length / rows; + + if (ppd->model_number & ESCP_RASTER_ESCI) + { + /* + * Send graphics with ESC i command. + */ + + printf("\033i"); + putchar(ctable[PrinterPlanes - 1][plane]); + putchar(type != 0); + putchar(BitPlanes); + putchar(bytes & 255); + putchar(bytes >> 8); + putchar(rows & 255); + putchar(rows >> 8); + } + else + { + /* + * Set the color if necessary... + */ + + if (PrinterPlanes > 1) + { + plane = ctable[PrinterPlanes - 1][plane]; + + if (plane & 0x10) + printf("\033(r%c%c%c%c", 2, 0, 1, plane & 0x0f); + else + printf("\033r%c", plane); + } + + /* + * Send graphics with ESC . command. + */ + + bytes *= 8; + + printf("\033."); + putchar(type != 0); + putchar(ystep); + putchar(xstep); + putchar(rows); + putchar(bytes & 255); + putchar(bytes >> 8); + } + + cupsWritePrintData(line_ptr, line_end - line_ptr); +} + + +/* + * 'OutputBand()' - Output a band of graphics. + */ + +void +OutputBand(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header, /* I - Page header */ + cups_weave_t *band) /* I - Current band */ +{ + int xstep, /* Spacing between columns */ + ystep; /* Spacing between rows */ + + + /* + * Interleaved ESC/P2 graphics... + */ + + OutputFeed = band->y - DotRowCurrent; + DotRowCurrent = band->y; + + fprintf(stderr, "DEBUG: Printing band %p, x = %d, y = %d, plane = %d, count = %d, OutputFeed = %d\n", + band, band->x, band->y, band->plane, band->count, OutputFeed); + + /* + * Compute step values... + */ + + xstep = 3600 * DotColStep / header->HWResolution[0]; + ystep = 3600 * DotRowStep / header->HWResolution[1]; + + /* + * Output the band... + */ + + if (OutputFeed > 0) + { + cupsWritePrintData("\033(v\002\000", 5); + putchar(OutputFeed & 255); + putchar(OutputFeed >> 8); + + OutputFeed = 0; + } + + CompressData(ppd, band->buffer, band->count * DotBufferSize, band->plane, + header->cupsCompression, band->count, xstep, ystep, band->x); + + /* + * Clear the band... + */ + + memset(band->buffer, 0, band->count * DotBufferSize); + band->dirty = 0; + + /* + * Flush the output buffers... + */ + + fflush(stdout); +} + + +/* + * 'ProcessLine()' - Read graphics from the page stream and output as needed. + */ + +void +ProcessLine(ppd_file_t *ppd, /* I - PPD file */ + cups_raster_t *ras, /* I - Raster stream */ + cups_page_header2_t *header, /* I - Page header */ + const int y) /* I - Current scanline */ +{ + int plane, /* Current color plane */ + width, /* Width of line */ + subwidth, /* Width of interleaved row */ + subrow, /* Subrow for interleaved output */ + offset, /* Offset to current line */ + pass, /* Pass number */ + xstep, /* X step value */ + ystep; /* Y step value */ + cups_weave_t *band; /* Current band */ + + + /* + * Read a row of graphics... + */ + + if (!cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine)) + return; + + /* + * Perform the color separation... + */ + + width = header->cupsWidth; + subwidth = header->cupsWidth / DotColStep; + xstep = 3600 / header->HWResolution[0]; + ystep = 3600 / header->HWResolution[1]; + + switch (header->cupsColorSpace) + { + case CUPS_CSPACE_W : + if (RGB) + { + cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width); + cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); + } + else + cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width); + break; + + case CUPS_CSPACE_K : + cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width); + break; + + default : + case CUPS_CSPACE_RGB : + if (RGB) + { + cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width); + cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); + } + else + cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width); + break; + + case CUPS_CSPACE_CMYK : + cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width); + break; + } + + /* + * Dither the pixels... + */ + + for (plane = 0; plane < PrinterPlanes; plane ++) + { + cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane, + PrinterPlanes, OutputBuffers[plane]); + + if (DotRowMax == 1) + { + /* + * Handle microweaved output... + */ + + if (cupsCheckBytes(OutputBuffers[plane], width)) + continue; + + if (BitPlanes == 1) + cupsPackHorizontal(OutputBuffers[plane], DotBuffers[plane], + width, 0, 1); + else + cupsPackHorizontal2(OutputBuffers[plane], DotBuffers[plane], + width, 1); + + if (OutputFeed > 0) + { + cupsWritePrintData("\033(v\002\000", 5); + putchar(OutputFeed & 255); + putchar(OutputFeed >> 8); + OutputFeed = 0; + } + + CompressData(ppd, DotBuffers[plane], DotBufferSize, plane, 1, 1, + xstep, ystep, 0); + fflush(stdout); + } + else + { + /* + * Handle softweaved output... + */ + + for (pass = 0, subrow = y % DotRowStep; + pass < DotColStep; + pass ++, subrow += DotRowStep) + { + /* + * See if we need to output the band... + */ + + band = DotBands[subrow][plane]; + offset = band->row * DotBufferSize; + + if (BitPlanes == 1) + cupsPackHorizontal(OutputBuffers[plane] + pass, + band->buffer + offset, subwidth, 0, DotColStep); + else + cupsPackHorizontal2(OutputBuffers[plane] + pass, + band->buffer + offset, subwidth, DotColStep); + + band->row ++; + band->dirty |= !cupsCheckBytes(band->buffer + offset, DotBufferSize); + if (band->row >= band->count) + { + if (band->dirty) + { + /* + * Dirty band needs to be added to the used list... + */ + + AddBand(band); + + /* + * Then find a new band... + */ + + if (DotAvailList == NULL) + { + OutputBand(ppd, header, DotUsedList); + + DotBands[subrow][plane] = DotUsedList; + DotUsedList->x = band->x; + DotUsedList->y = band->y + band->count * DotRowStep; + DotUsedList->plane = band->plane; + DotUsedList->row = 0; + DotUsedList->count = DotRowCount; + DotUsedList = DotUsedList->next; + } + else + { + DotBands[subrow][plane] = DotAvailList; + DotAvailList->x = band->x; + DotAvailList->y = band->y + band->count * DotRowStep; + DotAvailList->plane = band->plane; + DotAvailList->row = 0; + DotAvailList->count = DotRowCount; + DotAvailList = DotAvailList->next; + } + } + else + { + /* + * This band isn't dirty, so reuse it... + */ + + fprintf(stderr, "DEBUG: Blank band %p, x = %d, y = %d, plane = %d, count = %d\n", + band, band->x, band->y, band->plane, band->count); + + band->y += band->count * DotRowStep; + band->row = 0; + band->count = DotRowCount; + } + } + } + } + } + + if (DotRowMax == 1) + OutputFeed ++; +} + + +/* + * '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_header2_t header; /* Page header from file */ + int page; /* Current page */ + int y; /* Current line */ + ppd_file_t *ppd; /* PPD file */ + int num_options; /* Number of options */ + cups_option_t *options; /* 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 < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("ERROR: %s job-id user title copies options [file]\n"), + "rastertoescpx"); + return (1); + } + + num_options = cupsParseOptions(argv[5], 0, &options); + + /* + * Open the PPD file... + */ + + ppd = ppdOpenFile(getenv("PPD")); + + if (!ppd) + { + _cupsLangPuts(stderr, _("ERROR: Unable to open PPD file!\n")); + return (1); + } + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"), + strerror(errno)); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Register a signal handler to eject the current page if the + * job is cancelled. + */ + + Canceled = 0; + +#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 */ + + /* + * Initialize the print device... + */ + + Setup(ppd); + + /* + * Process pages as needed... + */ + + page = 0; + + while (cupsRasterReadHeader2(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + if (Canceled) + break; + + page ++; + + fprintf(stderr, "PAGE: %d 1\n", page); + _cupsLangPrintf(stderr, _("INFO: Starting page %d...\n"), page); + + StartPage(ppd, &header); + + for (y = 0; y < header.cupsHeight; y ++) + { + /* + * Let the user know how far we have progressed... + */ + + if (Canceled) + break; + + if ((y & 127) == 0) + _cupsLangPrintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"), + page, 100 * y / header.cupsHeight); + + /* + * Read and write a line of graphics or whitespace... + */ + + ProcessLine(ppd, ras, &header, y); + } + + /* + * Eject the page... + */ + + _cupsLangPrintf(stderr, _("INFO: Finished page %d...\n"), page); + + EndPage(ppd, &header); + + if (Canceled) + break; + } + + Shutdown(ppd); + + cupsFreeOptions(num_options, options); + + cupsRasterClose(ras); + + if (fd != 0) + close(fd); + + if (page == 0) + { + _cupsLangPuts(stderr, _("ERROR: No pages found!\n")); + return (1); + } + else + { + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + return (0); + } +} + + +/* + * End of "$Id$". + */ diff --git a/driver/rastertopclx.c b/driver/rastertopclx.c new file mode 100644 index 0000000000..8c9f93951b --- /dev/null +++ b/driver/rastertopclx.c @@ -0,0 +1,1944 @@ +/* + * "$Id$" + * + * Advanced HP Page Control Language and Raster Transfer Language + * filter for CUPS. + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * StartPage() - Start a page of graphics. + * EndPage() - Finish a page of graphics. + * Shutdown() - Shutdown a printer. + * CancelJob() - Cancel the current job... + * CompressData() - Compress a line of graphics. + * OutputLine() - Output the specified number of lines of graphics. + * ReadLine() - Read graphics from the page stream. + * main() - Main entry and processing of driver. + */ + +/* + * Include necessary headers... + */ + +#include "driver.h" +#include +#include +#include "pcl-common.h" +#include +#include + + +/* + * Output modes... + */ + +typedef enum +{ + OUTPUT_BITMAP, /* Output bitmap data from RIP */ + OUTPUT_INVERBIT, /* Output inverted bitmap data */ + OUTPUT_RGB, /* Output 24-bit RGB data from RIP */ + OUTPUT_DITHERED /* Output dithered data */ +} pcl_output_t; + + +/* + * Globals... + */ + +cups_rgb_t *RGB; /* RGB color separation data */ +cups_cmyk_t *CMYK; /* CMYK color separation data */ +unsigned char *PixelBuffer, /* Pixel buffer */ + *CMYKBuffer, /* CMYK buffer */ + *OutputBuffers[6], /* Output buffers */ + *DotBuffers[6], /* Bit buffers */ + *CompBuffer, /* Compression buffer */ + *SeedBuffer, /* Mode 3 seed buffers */ + BlankValue; /* The blank value */ +short *InputBuffer; /* Color separation buffer */ +cups_lut_t *DitherLuts[6]; /* Lookup tables for dithering */ +cups_dither_t *DitherStates[6]; /* Dither state tables */ +int PrinterPlanes, /* Number of color planes */ + SeedInvalid, /* Contents of seed buffer invalid? */ + DotBits[6], /* Number of bits per color */ + DotBufferSizes[6], /* Size of one row of color dots */ + DotBufferSize, /* Size of complete line */ + OutputFeed, /* Number of lines to skip */ + Page; /* Current page number */ +pcl_output_t OutputMode; /* Output mode - see OUTPUT_ consts */ +const int ColorOrders[7][7] = /* Order of color planes */ + { + { 0, 0, 0, 0, 0, 0, 0 }, /* Black */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 0, 0, 0, 0 }, /* CMY */ + { 3, 0, 1, 2, 0, 0, 0 }, /* KCMY */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 5, 0, 1, 2, 3, 4, 0 }, /* KCMYcm */ + { 5, 0, 1, 2, 3, 4, 6 } /* KCMYcmk */ + }; +int Canceled; /* Is the job canceled? */ + + +/* + * Prototypes... + */ + +void StartPage(ppd_file_t *ppd, cups_page_header2_t *header, int job_id, + const char *user, const char *title, int num_options, + cups_option_t *options); +void EndPage(ppd_file_t *ppd, cups_page_header2_t *header); +void Shutdown(ppd_file_t *ppd, int job_id, const char *user, + const char *title, int num_options, cups_option_t *options); + +void CancelJob(int sig); +void CompressData(unsigned char *line, int length, int plane, int pend, + int type); +void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header); +int ReadLine(cups_raster_t *ras, cups_page_header2_t *header); + + +/* + * 'StartPage()' - Start a page of graphics. + */ + +void +StartPage(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header, /* I - Page header */ + int job_id, /* I - Job ID */ + const char *user, /* I - User printing job */ + const char *title, /* I - Title of job */ + int num_options, + /* I - Number of command-line options */ + cups_option_t *options) /* I - Command-line options */ +{ + int i; /* Temporary/looping var */ + int plane; /* Current plane */ + char s[255]; /* Temporary value */ + const char *colormodel; /* Color model string */ + char resolution[PPD_MAX_NAME], + /* Resolution string */ + spec[PPD_MAX_NAME]; /* PPD attribute name */ + ppd_attr_t *attr; /* Attribute from PPD file */ + ppd_choice_t *choice; /* Selected option */ + const int *order; /* Order to use */ + int xorigin, /* X origin of page */ + yorigin; /* Y origin of page */ + static const float default_lut[2] = /* Default dithering lookup table */ + { + 0.0, + 1.0 + }; + + + /* + * Debug info... + */ + + fprintf(stderr, "DEBUG: StartPage...\n"); + fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass); + fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor); + fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType); + fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType); + + fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance); + fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia); + fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate); + fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia); + fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex); + fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0], + header->HWResolution[1]); + fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", + header->ImagingBoundingBox[0], header->ImagingBoundingBox[1], + header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]); + fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet); + fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog); + fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge); + fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0], + header->Margins[1]); + fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed); + fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition); + fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight); + fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint); + fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint); + fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies); + fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation); + fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp); + fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0], + header->PageSize[1]); + fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations); + fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch); + fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble); + fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth); + fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight); + fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType); + 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: cupsCompression = %d\n", header->cupsCompression); + +#ifdef __APPLE__ + /* + * MacOS X 10.2.x doesn't set most of the page device attributes, so check + * the options and set them accordingly... + */ + + if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble")) + { + header->Duplex = CUPS_TRUE; + header->Tumble = CUPS_FALSE; + } + else if (ppdIsMarked(ppd, "Duplex", "DuplexTumble")) + { + header->Duplex = CUPS_TRUE; + header->Tumble = CUPS_TRUE; + } + + fprintf(stderr, "DEBUG: num_options=%d\n", num_options); + + for (i = 0; i < num_options; i ++) + fprintf(stderr, "DEBUG: options[%d]=[\"%s\" \"%s\"]\n", i, + options[i].name, options[i].value); +#endif /* __APPLE__ */ + + /* + * Figure out the color model and spec strings... + */ + + switch (header->cupsColorSpace) + { + case CUPS_CSPACE_K : + colormodel = "Black"; + break; + case CUPS_CSPACE_W : + colormodel = "Gray"; + break; + default : + case CUPS_CSPACE_RGB : + colormodel = "RGB"; + break; + case CUPS_CSPACE_CMY : + colormodel = "CMY"; + break; + case CUPS_CSPACE_CMYK : + colormodel = "CMYK"; + break; + } + + if (header->HWResolution[0] != header->HWResolution[1]) + snprintf(resolution, sizeof(resolution), "%dx%ddpi", + header->HWResolution[0], header->HWResolution[1]); + else + snprintf(resolution, sizeof(resolution), "%ddpi", + header->HWResolution[0]); + + if (!header->MediaType[0]) + strcpy(header->MediaType, "PLAIN"); + + /* + * Get the dithering parameters... + */ + + BlankValue = 0x00; + + if (header->cupsBitsPerColor == 1) + { + /* + * Use raw bitmap mode... + */ + + switch (header->cupsColorSpace) + { + case CUPS_CSPACE_K : + OutputMode = OUTPUT_BITMAP; + PrinterPlanes = 1; + break; + case CUPS_CSPACE_W : + OutputMode = OUTPUT_INVERBIT; + PrinterPlanes = 1; + break; + default : + case CUPS_CSPACE_RGB : + OutputMode = OUTPUT_INVERBIT; + PrinterPlanes = 3; + break; + case CUPS_CSPACE_CMY : + OutputMode = OUTPUT_BITMAP; + PrinterPlanes = 3; + break; + case CUPS_CSPACE_CMYK : + OutputMode = OUTPUT_BITMAP; + PrinterPlanes = 4; + break; + } + + if (OutputMode == OUTPUT_INVERBIT) + BlankValue = 0xff; + + DotBufferSize = header->cupsBytesPerLine; + + memset(DitherLuts, 0, sizeof(DitherLuts)); + memset(DitherStates, 0, sizeof(DitherStates)); + } + else if (header->cupsColorSpace == CUPS_CSPACE_RGB && + (ppd->model_number & PCL_RASTER_RGB24)) + { + /* + * Use 24-bit RGB output mode... + */ + + OutputMode = OUTPUT_RGB; + PrinterPlanes = 3; + DotBufferSize = header->cupsBytesPerLine; + + if (header->cupsCompression == 10) + BlankValue = 0xff; + + memset(DitherLuts, 0, sizeof(DitherLuts)); + memset(DitherStates, 0, sizeof(DitherStates)); + } + else if ((header->cupsColorSpace == CUPS_CSPACE_K || + header->cupsColorSpace == CUPS_CSPACE_W) && + (ppd->model_number & PCL_RASTER_RGB24) && + header->cupsCompression == 10) + { + /* + * Use 24-bit RGB output mode for grayscale/black output... + */ + + OutputMode = OUTPUT_RGB; + PrinterPlanes = 1; + DotBufferSize = header->cupsBytesPerLine; + + if (header->cupsColorSpace == CUPS_CSPACE_W) + BlankValue = 0xff; + + memset(DitherLuts, 0, sizeof(DitherLuts)); + memset(DitherStates, 0, sizeof(DitherStates)); + } + else + { + /* + * Use dithered output mode... + */ + + OutputMode = OUTPUT_DITHERED; + + /* + * Load the appropriate color profiles... + */ + + RGB = NULL; + CMYK = NULL; + + fputs("DEBUG: Attempting to load color profiles using the following values:\n", stderr); + fprintf(stderr, "DEBUG: ColorModel = %s\n", colormodel); + fprintf(stderr, "DEBUG: MediaType = %s\n", header->MediaType); + fprintf(stderr, "DEBUG: Resolution = %s\n", resolution); + + if (header->cupsColorSpace == CUPS_CSPACE_RGB || + header->cupsColorSpace == CUPS_CSPACE_W) + RGB = cupsRGBLoad(ppd, colormodel, header->MediaType, resolution); + + CMYK = cupsCMYKLoad(ppd, colormodel, header->MediaType, resolution); + + if (RGB) + fputs("DEBUG: Loaded RGB separation from PPD.\n", stderr); + + if (CMYK) + fputs("DEBUG: Loaded CMYK separation from PPD.\n", stderr); + else + { + fputs("DEBUG: Loading default K separation.\n", stderr); + CMYK = cupsCMYKNew(1); + } + + PrinterPlanes = CMYK->num_channels; + + /* + * Use dithered mode... + */ + + switch (PrinterPlanes) + { + case 1 : /* K */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + break; + + case 3 : /* CMY */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + break; + + case 4 : /* CMYK */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + break; + + case 6 : /* CcMmYK */ + DitherLuts[0] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Cyan"); + DitherLuts[1] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightCyan"); + DitherLuts[2] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Magenta"); + DitherLuts[3] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "LightMagenta"); + DitherLuts[4] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Yellow"); + DitherLuts[5] = cupsLutLoad(ppd, colormodel, header->MediaType, + resolution, "Black"); + break; + } + + for (plane = 0; plane < PrinterPlanes; plane ++) + { + if (!DitherLuts[plane]) + DitherLuts[plane] = cupsLutNew(2, default_lut); + + if (DitherLuts[plane][4095].pixel > 1) + DotBits[plane] = 2; + else + DotBits[plane] = 1; + + DitherStates[plane] = cupsDitherNew(header->cupsWidth); + + if (!DitherLuts[plane]) + DitherLuts[plane] = cupsLutNew(2, default_lut); + } + } + + fprintf(stderr, "DEBUG: PrinterPlanes = %d\n", PrinterPlanes); + + /* + * Initialize the printer... + */ + + if ((attr = ppdFindAttr(ppd, "cupsInitialNulls", NULL)) != NULL) + for (i = atoi(attr->value); i > 0; i --) + putchar(0); + + if (Page == 1 && (ppd->model_number & PCL_PJL)) + { + pjl_escape(); + + /* + * PJL job setup... + */ + + pjl_set_job(job_id, user, title); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "StartJob")) != NULL) + pjl_write(ppd, attr->value, NULL, job_id, user, title, num_options, + options); + + snprintf(spec, sizeof(spec), "RENDERMODE.%s", colormodel); + if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL) + printf("@PJL SET RENDERMODE=%s\r\n", attr->value); + + snprintf(spec, sizeof(spec), "COLORSPACE.%s", colormodel); + if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL) + printf("@PJL SET COLORSPACE=%s\r\n", attr->value); + + snprintf(spec, sizeof(spec), "RENDERINTENT.%s", colormodel); + if ((attr = ppdFindAttr(ppd, "cupsPJL", spec)) != NULL) + printf("@PJL SET RENDERINTENT=%s\r\n", attr->value); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "Duplex")) != NULL) + { + sprintf(s, "%d", header->Duplex); + pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options); + } + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "Tumble")) != NULL) + { + sprintf(s, "%d", header->Tumble); + pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options); + } + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaClass")) != NULL) + pjl_write(ppd, attr->value, header->MediaClass, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaColor")) != NULL) + pjl_write(ppd, attr->value, header->MediaColor, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "MediaType")) != NULL) + pjl_write(ppd, attr->value, header->MediaType, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "OutputType")) != NULL) + pjl_write(ppd, attr->value, header->OutputType, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsBooklet")) != NULL && + (choice = ppdFindMarkedChoice(ppd, "cupsBooklet")) != NULL) + pjl_write(ppd, attr->value, choice->choice, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "Jog")) != NULL) + { + sprintf(s, "%d", header->Jog); + pjl_write(ppd, attr->value, s, job_id, user, title, num_options, options); + } + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsPunch")) != NULL && + (choice = ppdFindMarkedChoice(ppd, "cupsPunch")) != NULL) + pjl_write(ppd, attr->value, choice->choice, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsStaple")) != NULL && + (choice = ppdFindMarkedChoice(ppd, "cupsStaple")) != NULL) + pjl_write(ppd, attr->value, choice->choice, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsRET")) != NULL && + (choice = ppdFindMarkedChoice(ppd, "cupsRET")) != NULL) + pjl_write(ppd, attr->value, choice->choice, job_id, user, title, + num_options, options); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "cupsTonerSave")) != NULL && + (choice = ppdFindMarkedChoice(ppd, "cupsTonerSave")) != NULL) + pjl_write(ppd, attr->value, choice->choice, job_id, user, title, + num_options, options); + + if (ppd->model_number & PCL_PJL_PAPERWIDTH) + { + printf("@PJL SET PAPERLENGTH=%d\r\n", header->PageSize[1] * 10); + printf("@PJL SET PAPERWIDTH=%d\r\n", header->PageSize[0] * 10); + } + + if (ppd->model_number & PCL_PJL_RESOLUTION) + printf("@PJL SET RESOLUTION=%d\r\n", header->HWResolution[0]); + + if (ppd->model_number & PCL_PJL_HPGL2) + pjl_enter_language("HPGL2"); + else if (ppd->model_number & PCL_PJL_PCL3GUI) + pjl_enter_language("PCL3GUI"); + else + pjl_enter_language("PCL"); + } + + if (Page == 1) + { + pcl_reset(); + } + + if (ppd->model_number & PCL_PJL_HPGL2) + { + if (Page == 1) + { + /* + * HP-GL/2 initialization... + */ + + printf("IN;"); + printf("MG\"%d %s %s\";", job_id, user, title); + } + + /* + * Set media size, position, type, etc... + */ + + printf("BP5,0;"); + printf("PS%.0f,%.0f;", + header->cupsHeight * 1016.0 / header->HWResolution[1], + header->cupsWidth * 1016.0 / header->HWResolution[0]); + printf("PU;"); + printf("PA0,0"); + + printf("MT%d;", header->cupsMediaType); + + if (header->CutMedia == CUPS_CUT_PAGE) + printf("EC;"); + else + printf("EC0;"); + + /* + * Set graphics mode... + */ + + pcl_set_pcl_mode(0); + pcl_set_negative_motion(); + } + else + { + /* + * Set media size, position, type, etc... + */ + + if (!header->Duplex || (Page & 1)) + { + pcl_set_media_size(ppd, header->PageSize[0], header->PageSize[1]); + + if (header->MediaPosition) + pcl_set_media_source(header->MediaPosition); + + pcl_set_media_type(header->cupsMediaType); + + if (ppdFindAttr(ppd, "cupsPJL", "Duplex") == NULL) + pcl_set_duplex(header->Duplex, header->Tumble); + + /* + * Set the number of copies... + */ + + if (!ppd->manual_copies) + pcl_set_copies(header->NumCopies); + + /* + * Set the output order/bin... + */ + + if (ppdFindAttr(ppd, "cupsPJL", "Jog") == NULL && header->Jog) + printf("\033&l%dG", header->Jog); + } + else + { + /* + * Print on the back side... + */ + + printf("\033&a2G"); + } + + if (header->Duplex && (ppd->model_number & PCL_RASTER_CRD)) + { + /* + * Reload the media... + */ + + pcl_set_media_source(-2); + } + + /* + * Set the units for cursor positioning and go to the top of the form. + */ + + printf("\033&u%dD", header->HWResolution[0]); + printf("\033*p0Y\033*p0X"); + } + + if ((attr = cupsFindAttr(ppd, "cupsPCLQuality", colormodel, + header->MediaType, resolution, spec, + sizeof(spec))) != NULL) + { + /* + * Set the print quality... + */ + + if (ppd->model_number & PCL_PJL_HPGL2) + printf("QM%d", atoi(attr->value)); + else + printf("\033*o%dM", atoi(attr->value)); + } + + /* + * Enter graphics mode... + */ + + if (ppd->model_number & PCL_RASTER_CRD) + { + /* + * Use configure raster data command... + */ + + if (OutputMode == OUTPUT_RGB) + { + /* + * Send 12-byte configure raster data command with horizontal and + * vertical resolutions as well as a color count... + */ + + if ((attr = cupsFindAttr(ppd, "cupsPCLCRDMode", colormodel, + header->MediaType, resolution, spec, + sizeof(spec))) != NULL) + i = atoi(attr->value); + else + i = 31; + + printf("\033*g12W"); + putchar(6); /* Format 6 */ + putchar(i); /* Set pen mode */ + putchar(0x00); /* Number components */ + putchar(0x01); /* (1 for RGB) */ + + putchar(header->HWResolution[0] >> 8); + putchar(header->HWResolution[0]); + putchar(header->HWResolution[1] >> 8); + putchar(header->HWResolution[1]); + + putchar(header->cupsCompression); /* Compression mode 3 or 10 */ + putchar(0x01); /* Portrait orientation */ + putchar(0x20); /* Bits per pixel (32 = RGB) */ + putchar(0x01); /* Planes per pixel (1 = chunky RGB) */ + } + else + { + /* + * Send the configure raster data command with horizontal and + * vertical resolutions as well as a color count... + */ + + printf("\033*g%dW", PrinterPlanes * 6 + 2); + putchar(2); /* Format 2 */ + putchar(PrinterPlanes); /* Output planes */ + + order = ColorOrders[PrinterPlanes - 1]; + + for (i = 0; i < PrinterPlanes; i ++) + { + plane = order[i]; + + putchar(header->HWResolution[0] >> 8); + putchar(header->HWResolution[0]); + putchar(header->HWResolution[1] >> 8); + putchar(header->HWResolution[1]); + putchar(0); + putchar(1 << DotBits[plane]); + } + } + } + else if ((ppd->model_number & PCL_RASTER_CID) && OutputMode == OUTPUT_RGB) + { + /* + * Use configure image data command... + */ + + pcl_set_simple_resolution(header->HWResolution[0]); + /* Set output resolution */ + + cupsWritePrintData("\033*v6W\0\3\0\10\10\10", 11); + /* 24-bit RGB */ + } + else + { + /* + * Use simple raster commands... + */ + + pcl_set_simple_resolution(header->HWResolution[0]); + /* Set output resolution */ + + if (PrinterPlanes == 3) + pcl_set_simple_cmy(); + else if (PrinterPlanes == 4) + pcl_set_simple_kcmy(); + } + + if ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "X")) != NULL) + xorigin = atoi(attr->value); + else + xorigin = 0; + + if ((attr = ppdFindAttr(ppd, "cupsPCLOrigin", "Y")) != NULL) + yorigin = atoi(attr->value); + else + yorigin = 120; + + printf("\033&a%dH\033&a%dV", xorigin, yorigin); + printf("\033*r%dS", header->cupsWidth); + printf("\033*r%dT", header->cupsHeight); + printf("\033*r1A"); + + if (header->cupsCompression && header->cupsCompression != 10) + printf("\033*b%dM", header->cupsCompression); + + OutputFeed = 0; + + /* + * Allocate memory for the page... + */ + + PixelBuffer = malloc(header->cupsBytesPerLine); + + if (OutputMode == OUTPUT_DITHERED) + { + InputBuffer = malloc(header->cupsWidth * PrinterPlanes * 2); + OutputBuffers[0] = malloc(PrinterPlanes * header->cupsWidth); + + for (i = 1; i < PrinterPlanes; i ++) + OutputBuffers[i] = OutputBuffers[0] + i * header->cupsWidth; + + if (RGB) + CMYKBuffer = malloc(header->cupsWidth * PrinterPlanes); + + for (plane = 0, DotBufferSize = 0; plane < PrinterPlanes; plane ++) + { + DotBufferSizes[plane] = (header->cupsWidth + 7) / 8 * DotBits[plane]; + DotBufferSize += DotBufferSizes[plane]; + } + + DotBuffers[0] = malloc(DotBufferSize); + for (plane = 1; plane < PrinterPlanes; plane ++) + DotBuffers[plane] = DotBuffers[plane - 1] + DotBufferSizes[plane - 1]; + } + + if (header->cupsCompression) + CompBuffer = malloc(DotBufferSize * 4); + + if (header->cupsCompression >= 3) + SeedBuffer = malloc(DotBufferSize); + + SeedInvalid = 1; + + fprintf(stderr, "BlankValue=%d\n", BlankValue); +} + + +/* + * 'EndPage()' - Finish a page of graphics. + */ + +void +EndPage(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header) /* I - Page header */ +{ + int plane; /* Current plane */ + + + /* + * End graphics mode... + */ + + if (ppd->model_number & PCL_RASTER_END_COLOR) + printf("\033*rC"); /* End color GFX */ + else + printf("\033*r0B"); /* End B&W GFX */ + + /* + * Output a page eject sequence... + */ + + if (ppd->model_number & PCL_PJL_HPGL2) + { + pcl_set_hpgl_mode(0); /* Back to HP-GL/2 mode */ + printf("PG;"); /* Eject the current page */ + } + else if (!(header->Duplex && (Page & 1))) + printf("\014"); /* Eject current page */ + + /* + * Free memory for the page... + */ + + free(PixelBuffer); + + if (OutputMode == OUTPUT_DITHERED) + { + for (plane = 0; plane < PrinterPlanes; plane ++) + { + cupsDitherDelete(DitherStates[plane]); + cupsLutDelete(DitherLuts[plane]); + } + + free(DotBuffers[0]); + free(InputBuffer); + free(OutputBuffers[0]); + + cupsCMYKDelete(CMYK); + + if (RGB) + { + cupsRGBDelete(RGB); + free(CMYKBuffer); + } + } + + if (header->cupsCompression) + free(CompBuffer); + + if (header->cupsCompression >= 3) + free(SeedBuffer); +} + + +/* + * 'Shutdown()' - Shutdown a printer. + */ + +void +Shutdown(ppd_file_t *ppd, /* I - PPD file */ + int job_id, /* I - Job ID */ + const char *user, /* I - User printing job */ + const char *title, /* I - Title of job */ + int num_options,/* I - Number of command-line options */ + cups_option_t *options) /* I - Command-line options */ +{ + ppd_attr_t *attr; /* Attribute from PPD file */ + + + if ((attr = ppdFindAttr(ppd, "cupsPCL", "EndJob")) != NULL) + { + /* + * Tell the printer how many pages were in the job... + */ + + putchar(0x1b); + printf(attr->value, Page); + } + else + { + /* + * Return the printer to the default state... + */ + + pcl_reset(); + } + + if (ppd->model_number & PCL_PJL) + { + pjl_escape(); + + if ((attr = ppdFindAttr(ppd, "cupsPJL", "EndJob")) != NULL) + pjl_write(ppd, attr->value, NULL, job_id, user, title, num_options, + options); + else + printf("@PJL EOJ\r\n"); + + pjl_escape(); + } +} + + +/* + * 'CancelJob()' - Cancel the current job... + */ + +void +CancelJob(int sig) /* I - Signal */ +{ + (void)sig; + + Canceled = 1; +} + + +/* + * '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 pend, /* I - End character for data */ + 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 */ + *seed; /* Seed buffer pointer */ + int count, /* Count of bytes for output */ + offset, /* Offset of bytes for output */ + temp; /* Temporary count */ + int r, g, b; /* RGB deltas for mode 10 compression */ + + + switch (type) + { + default : + /* + * Do no compression; with a mode-0 only printer, we can compress blank + * lines... + */ + + line_ptr = line; + + if (cupsCheckBytes(line, length)) + line_end = line; /* Blank line */ + else + line_end = line + length; /* Non-blank line */ + 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; + + case 3 : + /* + * Do delta-row compression... + */ + + line_ptr = line; + line_end = line + length; + + comp_ptr = CompBuffer; + seed = SeedBuffer + plane * length; + + while (line_ptr < line_end) + { + /* + * Find the next non-matching sequence... + */ + + start = line_ptr; + + if (SeedInvalid) + { + /* + * The seed buffer is invalid, so do the next 8 bytes, max... + */ + + offset = 0; + + if ((count = line_end - line_ptr) > 8) + count = 8; + + line_ptr += count; + } + else + { + /* + * The seed buffer is valid, so compare against it... + */ + + while (*line_ptr == *seed && + line_ptr < line_end) + { + line_ptr ++; + seed ++; + } + + if (line_ptr == line_end) + break; + + offset = line_ptr - start; + + /* + * Find up to 8 non-matching bytes... + */ + + start = line_ptr; + count = 0; + while (*line_ptr != *seed && + line_ptr < line_end && + count < 8) + { + line_ptr ++; + seed ++; + count ++; + } + } + + /* + * Place mode 3 compression data in the buffer; see HP manuals + * for details... + */ + + if (offset >= 31) + { + /* + * Output multi-byte offset... + */ + + *comp_ptr++ = ((count - 1) << 5) | 31; + + offset -= 31; + while (offset >= 255) + { + *comp_ptr++ = 255; + offset -= 255; + } + + *comp_ptr++ = offset; + } + else + { + /* + * Output single-byte offset... + */ + + *comp_ptr++ = ((count - 1) << 5) | offset; + } + + memcpy(comp_ptr, start, count); + comp_ptr += count; + } + + line_ptr = CompBuffer; + line_end = comp_ptr; + + memcpy(SeedBuffer + plane * length, line, length); + break; + + case 10 : + /* + * Mode 10 "near lossless" RGB compression... + */ + + line_ptr = line; + line_end = line + length; + + comp_ptr = CompBuffer; + seed = SeedBuffer; + + if (PrinterPlanes == 1) + { + /* + * Do grayscale compression to RGB... + */ + + while (line_ptr < line_end) + { + /* + * Find the next non-matching sequence... + */ + + start = line_ptr; + while (line_ptr < line_end && + *line_ptr == *seed) + { + line_ptr ++; + seed ++; + } + + if (line_ptr == line_end) + break; + + offset = line_ptr - start; + + /* + * Find non-matching grayscale pixels... + */ + + start = line_ptr; + while (line_ptr < line_end && + *line_ptr != *seed) + { + line_ptr ++; + seed ++; + } + + count = line_ptr - start; + +#if 0 + fprintf(stderr, "DEBUG: offset=%d, count=%d, comp_ptr=%p(%d of %d)...\n", + offset, count, comp_ptr, comp_ptr - CompBuffer, + BytesPerLine * 5); +#endif /* 0 */ + + /* + * Place mode 10 compression data in the buffer; each sequence + * starts with a command byte that looks like: + * + * CMD SRC SRC OFF OFF CNT CNT CNT + * + * For the purpose of this driver, CMD and SRC are always 0. + * + * If the offset >= 3 then additional offset bytes follow the + * first command byte, each byte == 255 until the last one. + * + * If the count >= 7, then additional count bytes follow each + * group of pixels, each byte == 255 until the last one. + * + * The offset and count are in RGB tuples (not bytes, as for + * Mode 3 and 9)... + */ + + if (offset >= 3) + { + /* + * Output multi-byte offset... + */ + + if (count > 7) + *comp_ptr++ = 0x1f; + else + *comp_ptr++ = 0x18 | (count - 1); + + offset -= 3; + while (offset >= 255) + { + *comp_ptr++ = 255; + offset -= 255; + } + + *comp_ptr++ = offset; + } + else + { + /* + * Output single-byte offset... + */ + + if (count > 7) + *comp_ptr++ = (offset << 3) | 0x07; + else + *comp_ptr++ = (offset << 3) | (count - 1); + } + + temp = count - 8; + seed -= count; + + while (count > 0) + { + if (count <= temp) + { + /* + * This is exceedingly lame... The replacement counts + * are intermingled with the data... + */ + + if (temp >= 255) + *comp_ptr++ = 255; + else + *comp_ptr++ = temp; + + temp -= 255; + } + + /* + * Get difference between current and see pixels... + */ + + r = *start - *seed; + g = r; + b = ((*start & 0xfe) - (*seed & 0xfe)) / 2; + + if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15) + { + /* + * Pack 24-bit RGB into 23 bits... Lame... + */ + + g = *start; + + *comp_ptr++ = g >> 1; + + if (g & 1) + *comp_ptr++ = 0x80 | (g >> 1); + else + *comp_ptr++ = g >> 1; + + if (g & 1) + *comp_ptr++ = 0x80 | (g >> 1); + else + *comp_ptr++ = g >> 1; + } + else + { + /* + * Pack 15-bit RGB difference... + */ + + *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03); + *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f); + } + + count --; + start ++; + seed ++; + } + + /* + * Make sure we have the ending count if the replacement count + * was exactly 8 + 255n... + */ + + if (temp == 0) + *comp_ptr++ = 0; + } + } + else + { + /* + * Do RGB compression... + */ + + while (line_ptr < line_end) + { + /* + * Find the next non-matching sequence... + */ + + start = line_ptr; + while (line_ptr[0] == seed[0] && + line_ptr[1] == seed[1] && + line_ptr[2] == seed[2] && + (line_ptr + 2) < line_end) + { + line_ptr += 3; + seed += 3; + } + + if (line_ptr == line_end) + break; + + offset = (line_ptr - start) / 3; + + /* + * Find non-matching RGB tuples... + */ + + start = line_ptr; + while ((line_ptr[0] != seed[0] || + line_ptr[1] != seed[1] || + line_ptr[2] != seed[2]) && + (line_ptr + 2) < line_end) + { + line_ptr += 3; + seed += 3; + } + + count = (line_ptr - start) / 3; + + /* + * Place mode 10 compression data in the buffer; each sequence + * starts with a command byte that looks like: + * + * CMD SRC SRC OFF OFF CNT CNT CNT + * + * For the purpose of this driver, CMD and SRC are always 0. + * + * If the offset >= 3 then additional offset bytes follow the + * first command byte, each byte == 255 until the last one. + * + * If the count >= 7, then additional count bytes follow each + * group of pixels, each byte == 255 until the last one. + * + * The offset and count are in RGB tuples (not bytes, as for + * Mode 3 and 9)... + */ + + if (offset >= 3) + { + /* + * Output multi-byte offset... + */ + + if (count > 7) + *comp_ptr++ = 0x1f; + else + *comp_ptr++ = 0x18 | (count - 1); + + offset -= 3; + while (offset >= 255) + { + *comp_ptr++ = 255; + offset -= 255; + } + + *comp_ptr++ = offset; + } + else + { + /* + * Output single-byte offset... + */ + + if (count > 7) + *comp_ptr++ = (offset << 3) | 0x07; + else + *comp_ptr++ = (offset << 3) | (count - 1); + } + + temp = count - 8; + seed -= count * 3; + + while (count > 0) + { + if (count <= temp) + { + /* + * This is exceedingly lame... The replacement counts + * are intermingled with the data... + */ + + if (temp >= 255) + *comp_ptr++ = 255; + else + *comp_ptr++ = temp; + + temp -= 255; + } + + /* + * Get difference between current and see pixels... + */ + + r = start[0] - seed[0]; + g = start[1] - seed[1]; + b = ((start[2] & 0xfe) - (seed[2] & 0xfe)) / 2; + + if (r < -16 || r > 15 || g < -16 || g > 15 || b < -16 || b > 15) + { + /* + * Pack 24-bit RGB into 23 bits... Lame... + */ + + *comp_ptr++ = start[0] >> 1; + + if (start[0] & 1) + *comp_ptr++ = 0x80 | (start[1] >> 1); + else + *comp_ptr++ = start[1] >> 1; + + if (start[1] & 1) + *comp_ptr++ = 0x80 | (start[2] >> 1); + else + *comp_ptr++ = start[2] >> 1; + } + else + { + /* + * Pack 15-bit RGB difference... + */ + + *comp_ptr++ = 0x80 | ((r << 2) & 0x7c) | ((g >> 3) & 0x03); + *comp_ptr++ = ((g << 5) & 0xe0) | (b & 0x1f); + } + + count --; + start += 3; + seed += 3; + } + + /* + * Make sure we have the ending count if the replacement count + * was exactly 8 + 255n... + */ + + if (temp == 0) + *comp_ptr++ = 0; + } + } + + line_ptr = CompBuffer; + line_end = comp_ptr; + + memcpy(SeedBuffer, line, length); + break; + } + + /* + * Set the length of the data and write a raster plane... + */ + + printf("\033*b%d%c", (int)(line_end - line_ptr), pend); + cupsWritePrintData(line_ptr, line_end - line_ptr); +} + + +/* + * 'OutputLine()' - Output the specified number of lines of graphics. + */ + +void +OutputLine(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header) /* I - Page header */ +{ + int i, j; /* Looping vars */ + int plane; /* Current plane */ + unsigned char bit; /* Current bit */ + int bytes; /* Number of bytes/plane */ + int width; /* Width of line in pixels */ + const int *order; /* Order to use */ + unsigned char *ptr; /* Pointer into buffer */ + + + /* + * Output whitespace as needed... + */ + + if (OutputFeed > 0) + { + if (header->cupsCompression < 3) + { + /* + * Send blank raster lines... + */ + + while (OutputFeed > 0) + { + printf("\033*b0W"); + OutputFeed --; + } + } + else + { + /* + * Send Y offset command and invalidate the seed buffer... + */ + + printf("\033*b%dY", OutputFeed); + OutputFeed = 0; + SeedInvalid = 1; + } + } + + /* + * Write bitmap data as needed... + */ + + switch (OutputMode) + { + case OUTPUT_BITMAP : /* Send 1-bit bitmap data... */ + order = ColorOrders[PrinterPlanes - 1]; + bytes = header->cupsBytesPerLine / PrinterPlanes; + + for (i = 0; i < PrinterPlanes; i ++) + { + plane = order[i]; + + CompressData(PixelBuffer + i * bytes, bytes, plane, + (i < (PrinterPlanes - 1)) ? 'V' : 'W', + header->cupsCompression); + } + break; + + case OUTPUT_INVERBIT : /* Send inverted 1-bit bitmap data... */ + order = ColorOrders[PrinterPlanes - 1]; + bytes = header->cupsBytesPerLine / PrinterPlanes; + + for (i = header->cupsBytesPerLine, ptr = PixelBuffer; + i > 0; + i --, ptr ++) + *ptr = ~*ptr; + + for (i = 0; i < PrinterPlanes; i ++) + { + plane = order[i]; + + CompressData(PixelBuffer + i * bytes, bytes, plane, + (i < (PrinterPlanes - 1)) ? 'V' : 'W', + header->cupsCompression); + } + break; + + case OUTPUT_RGB : /* Send 24-bit RGB data... */ + if (PrinterPlanes == 1 && !BlankValue) + { + /* + * Invert black to grayscale... + */ + + for (i = header->cupsBytesPerLine, ptr = PixelBuffer; + i > 0; + i --, ptr ++) + *ptr = ~*ptr; + } + + /* + * Compress the output... + */ + + CompressData(PixelBuffer, header->cupsBytesPerLine, 0, 'W', + header->cupsCompression); + break; + + default : + order = ColorOrders[PrinterPlanes - 1]; + width = header->cupsWidth; + + for (i = 0, j = 0; i < PrinterPlanes; i ++) + { + plane = order[i]; + bytes = DotBufferSizes[plane] / DotBits[plane]; + + for (bit = 1, ptr = DotBuffers[plane]; + bit <= DotBits[plane]; + bit <<= 1, ptr += bytes, j ++) + { + cupsPackHorizontalBit(OutputBuffers[plane], DotBuffers[plane], + width, 0, bit); + CompressData(ptr, bytes, j, + i == (PrinterPlanes - 1) && + bit == DotBits[plane] ? 'W' : 'V', + header->cupsCompression); + } + } + break; + } + + /* + * The seed buffer, if any, now should contain valid data... + */ + + SeedInvalid = 0; +} + + +/* + * 'ReadLine()' - Read graphics from the page stream. + */ + +int /* O - Number of lines (0 if blank) */ +ReadLine(cups_raster_t *ras, /* I - Raster stream */ + cups_page_header2_t *header) /* I - Page header */ +{ + int plane, /* Current color plane */ + width; /* Width of line */ + + + /* + * Read raster data... + */ + + cupsRasterReadPixels(ras, PixelBuffer, header->cupsBytesPerLine); + + /* + * See if it is blank; if so, return right away... + */ + + if (cupsCheckValue(PixelBuffer, header->cupsBytesPerLine, BlankValue)) + return (0); + + /* + * If we aren't dithering, return immediately... + */ + + if (OutputMode != OUTPUT_DITHERED) + return (1); + + /* + * Perform the color separation... + */ + + width = header->cupsWidth; + + switch (header->cupsColorSpace) + { + case CUPS_CSPACE_W : + if (RGB) + { + cupsRGBDoGray(RGB, PixelBuffer, CMYKBuffer, width); + + if (RGB->num_channels == 1) + cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width); + else + cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); + } + else + cupsCMYKDoGray(CMYK, PixelBuffer, InputBuffer, width); + break; + + case CUPS_CSPACE_K : + cupsCMYKDoBlack(CMYK, PixelBuffer, InputBuffer, width); + break; + + default : + case CUPS_CSPACE_RGB : + if (RGB) + { + cupsRGBDoRGB(RGB, PixelBuffer, CMYKBuffer, width); + + if (RGB->num_channels == 1) + cupsCMYKDoBlack(CMYK, CMYKBuffer, InputBuffer, width); + else + cupsCMYKDoCMYK(CMYK, CMYKBuffer, InputBuffer, width); + } + else + cupsCMYKDoRGB(CMYK, PixelBuffer, InputBuffer, width); + break; + + case CUPS_CSPACE_CMYK : + cupsCMYKDoCMYK(CMYK, PixelBuffer, InputBuffer, width); + break; + } + + /* + * Dither the pixels... + */ + + for (plane = 0; plane < PrinterPlanes; plane ++) + cupsDitherLine(DitherStates[plane], DitherLuts[plane], InputBuffer + plane, + PrinterPlanes, OutputBuffers[plane]); + + /* + * Return 1 to indicate that we have non-blank output... + */ + + return (1); +} + + +/* + * '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_header2_t header; /* Page header from file */ + int y; /* Current line */ + ppd_file_t *ppd; /* PPD file */ + int job_id; /* Job ID */ + int num_options; /* Number of options */ + cups_option_t *options; /* 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 < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("ERROR: %s job-id user title copies options [file]\n"), + "rastertopclx"); + return (1); + } + + num_options = cupsParseOptions(argv[5], 0, &options); + + /* + * Open the PPD file... + */ + + ppd = ppdOpenFile(getenv("PPD")); + + if (!ppd) + { + _cupsLangPuts(stderr, _("ERROR: Unable to open PPD file!\n")); + return (1); + } + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"), + strerror(errno)); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Register a signal handler to eject the current page if the + * job is cancelled. + */ + + Canceled = 0; + +#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 */ + + /* + * Process pages as needed... + */ + + job_id = atoi(argv[1]); + + Page = 0; + + while (cupsRasterReadHeader2(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + if (Canceled) + break; + + Page ++; + + fprintf(stderr, "PAGE: %d %d\n", Page, header.NumCopies); + _cupsLangPrintf(stderr, _("INFO: Starting page %d...\n"), Page); + + StartPage(ppd, &header, atoi(argv[1]), argv[2], argv[3], + num_options, options); + + for (y = 0; y < (int)header.cupsHeight; y ++) + { + /* + * Let the user know how far we have progressed... + */ + + if (Canceled) + break; + + if ((y & 127) == 0) + _cupsLangPrintf(stderr, _("INFO: Printing page %d, %d%% complete...\n"), + Page, 100 * y / header.cupsHeight); + + /* + * Read and write a line of graphics or whitespace... + */ + + if (ReadLine(ras, &header)) + OutputLine(ppd, &header); + else + OutputFeed ++; + } + + /* + * Eject the page... + */ + + _cupsLangPrintf(stderr, _("INFO: Finished page %d...\n"), Page); + + EndPage(ppd, &header); + + if (Canceled) + break; + } + + Shutdown(ppd, job_id, argv[2], argv[3], num_options, options); + + cupsFreeOptions(num_options, options); + + cupsRasterClose(ras); + + if (fd != 0) + close(fd); + + if (Page == 0) + { + _cupsLangPuts(stderr, _("ERROR: No pages found!\n")); + return (1); + } + else + { + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + return (0); + } +} + + +/* + * End of "$Id$". + */ diff --git a/driver/rgb.c b/driver/rgb.c new file mode 100644 index 0000000000..fd0b117a59 --- /dev/null +++ b/driver/rgb.c @@ -0,0 +1,558 @@ +/* + * "$Id$" + * + * RGB color separation code for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * cupsRGBDelete() - Delete a color separation. + * cupsRGBDoGray() - Do a grayscale separation... + * cupsRGBDoRGB() - Do a RGB separation... + * cupsRGBLoad() - Load a RGB color profile from a PPD file. + * cupsRGBNew() - Create a new RGB color separation. + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" + + +/* + * 'cupsRGBDelete()' - Delete a color separation. + */ + +void +cupsRGBDelete(cups_rgb_t *rgbptr) /* I - Color separation */ +{ + if (rgbptr == NULL) + return; + + free(rgbptr->colors[0][0][0]); + free(rgbptr->colors[0][0]); + free(rgbptr->colors[0]); + free(rgbptr->colors); + free(rgbptr); +} + + +/* + * 'cupsRGBDoGray()' - Do a grayscale separation... + */ + +void +cupsRGBDoGray(cups_rgb_t *rgbptr, + /* I - Color separation */ + const unsigned char *input, + /* I - Input grayscale pixels */ + unsigned char *output, + /* O - Output Device-N pixels */ + int num_pixels) + /* I - Number of pixels */ +{ + int i; /* Looping var */ + int lastgray; /* Previous grayscale */ + int xs, ys, zs, /* Current RGB row offsets */ + g, gi, gm0, gm1;/* Current gray index and multipliers ... */ + const unsigned char *color; /* Current color data */ + int tempg; /* Current separation color */ + int rgbsize; /* Separation data size */ + + + /* + * Range check input... + */ + + if (!rgbptr || !input || !output || num_pixels <= 0) + return; + + /* + * Initialize variables used for the duration of the separation... + */ + + lastgray = -1; + rgbsize = rgbptr->num_channels; + xs = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels; + ys = rgbptr->cube_size * rgbptr->num_channels; + zs = rgbptr->num_channels; + + /* + * Loop through it all... + */ + + while (num_pixels > 0) + { + /* + * See if the next pixel is a cached value... + */ + + num_pixels --; + + g = cups_srgb_lut[*input++]; + + if (g == lastgray) + { + /* + * Copy previous color and continue... + */ + + memcpy(output, output - rgbptr->num_channels, rgbsize); + + output += rgbptr->num_channels; + continue; + } + else if (g == 0x00 && rgbptr->cache_init) + { + /* + * Copy black color and continue... + */ + + memcpy(output, rgbptr->black, rgbsize); + + output += rgbptr->num_channels; + continue; + } + else if (g == 0xff && rgbptr->cache_init) + { + /* + * Copy white color and continue... + */ + + memcpy(output, rgbptr->white, rgbsize); + + output += rgbptr->num_channels; + continue; + } + + /* + * Nope, figure this one out on our own... + */ + + gi = rgbptr->cube_index[g]; + gm0 = rgbptr->cube_mult[g]; + gm1 = 256 - gm0; + + color = rgbptr->colors[gi][gi][gi]; + + for (i = 0; i < rgbptr->num_channels; i ++, color ++) + { + tempg = (color[0] * gm0 + color[xs + ys + zs] * gm1) / 256; + + if (tempg > 255) + *output++ = 255; + else if (tempg < 0) + *output++ = 0; + else + *output++ = tempg; + } + } +} + + +/* + * 'cupsRGBDoRGB()' - Do a RGB separation... + */ + +void +cupsRGBDoRGB(cups_rgb_t *rgbptr, + /* I - Color separation */ + const unsigned char *input, + /* I - Input RGB pixels */ + unsigned char *output, + /* O - Output Device-N pixels */ + int num_pixels) + /* I - Number of pixels */ +{ + int i; /* Looping var */ + int rgb, /* Current RGB color */ + lastrgb; /* Previous RGB color */ + int r, ri, rm0, rm1, rs, + /* Current red index, multipliexs, and row offset */ + g, gi, gm0, gm1, gs, + /* Current green ... */ + b, bi, bm0, bm1, bs; + /* Current blue ... */ + const unsigned char *color; /* Current color data */ + int tempr, /* Current separation colors */ + tempg, /* ... */ + tempb ; /* ... */ + int rgbsize; /* Separation data size */ + + + /* + * Range check input... + */ + + if (!rgbptr || !input || !output || num_pixels <= 0) + return; + + /* + * Initialize variables used for the duration of the separation... + */ + + lastrgb = -1; + rgbsize = rgbptr->num_channels; + rs = rgbptr->cube_size * rgbptr->cube_size * rgbptr->num_channels; + gs = rgbptr->cube_size * rgbptr->num_channels; + bs = rgbptr->num_channels; + + /* + * Loop through it all... + */ + + while (num_pixels > 0) + { + /* + * See if the next pixel is a cached value... + */ + + num_pixels --; + + r = cups_srgb_lut[*input++]; + g = cups_srgb_lut[*input++]; + b = cups_srgb_lut[*input++]; + rgb = (((r << 8) | g) << 8) | b; + + if (rgb == lastrgb) + { + /* + * Copy previous color and continue... + */ + + memcpy(output, output - rgbptr->num_channels, rgbsize); + + output += rgbptr->num_channels; + continue; + } + else if (rgb == 0x000000 && rgbptr->cache_init) + { + /* + * Copy black color and continue... + */ + + memcpy(output, rgbptr->black, rgbsize); + + output += rgbptr->num_channels; + continue; + } + else if (rgb == 0xffffff && rgbptr->cache_init) + { + /* + * Copy white color and continue... + */ + + memcpy(output, rgbptr->white, rgbsize); + + output += rgbptr->num_channels; + continue; + } + + /* + * Nope, figure this one out on our own... + */ + + ri = rgbptr->cube_index[r]; + rm0 = rgbptr->cube_mult[r]; + rm1 = 256 - rm0; + + gi = rgbptr->cube_index[g]; + gm0 = rgbptr->cube_mult[g]; + gm1 = 256 - gm0; + + bi = rgbptr->cube_index[b]; + bm0 = rgbptr->cube_mult[b]; + bm1 = 256 - bm0; + + color = rgbptr->colors[ri][gi][bi]; + + for (i = rgbptr->num_channels; i > 0; i --, color ++) + { + tempb = (color[0] * bm0 + color[bs] * bm1) / 256; + tempg = tempb * gm0; + tempb = (color[gs] * gm0 + color[gs + bs] * bm1) / 256; + tempg = (tempg + tempb * gm1) / 256; + + tempr = tempg * rm0; + + tempb = (color[rs] * bm0 + color[rs + bs] * bm1) / 256; + tempg = tempb * gm0; + tempb = (color[rs + gs] * bm0 + color[rs + gs + bs] * bm1) / 256; + tempg = (tempg + tempb * gm1) / 256; + + tempr = (tempr + tempg * rm1) / 256; + + if (tempr > 255) + *output++ = 255; + else if (tempr < 0) + *output++ = 0; + else + *output++ = tempr; + } + } +} + + +/* + * 'cupsRGBLoad()' - Load a RGB color profile from a PPD file. + */ + +cups_rgb_t * /* O - New color profile */ +cupsRGBLoad(ppd_file_t *ppd, /* I - PPD file */ + const char *colormodel, /* I - Color model */ + const char *media, /* I - Media type */ + const char *resolution) /* I - Resolution */ +{ + int i, /* Looping var */ + cube_size, /* Size of color lookup cube */ + num_channels, /* Number of color channels */ + num_samples; /* Number of color samples */ + cups_sample_t *samples; /* Color samples */ + float values[7]; /* Color sample values */ + char spec[PPD_MAX_NAME]; /* Profile name */ + ppd_attr_t *attr; /* Attribute from PPD file */ + cups_rgb_t *rgbptr; /* RGB color profile */ + + + /* + * Find the following attributes: + * + * cupsRGBProfile - Specifies the cube size, number of channels, and + * number of samples + * cupsRGBSample - Specifies an RGB to CMYK color sample + */ + + if ((attr = cupsFindAttr(ppd, "cupsRGBProfile", colormodel, media, + resolution, spec, sizeof(spec))) == NULL) + { + fputs("DEBUG2: No cupsRGBProfile attribute found for the current settings!\n", stderr); + return (NULL); + } + + if (!attr->value || sscanf(attr->value, "%d%d%d", &cube_size, &num_channels, + &num_samples) != 3) + { + fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n", + attr->value ? attr->value : "(null)"); + return (NULL); + } + + if (cube_size < 2 || cube_size > 16 || + num_channels < 1 || num_channels > CUPS_MAX_RGB || + num_samples != (cube_size * cube_size * cube_size)) + { + fprintf(stderr, "ERROR: Bad cupsRGBProfile attribute \'%s\'!\n", + attr->value); + return (NULL); + } + + /* + * Allocate memory for the samples and read them... + */ + + if ((samples = calloc(num_samples, sizeof(cups_sample_t))) == NULL) + { + fputs("ERROR: Unable to allocate memory for RGB profile!\n", stderr); + return (NULL); + } + + /* + * Read all of the samples... + */ + + for (i = 0; i < num_samples; i ++) + if ((attr = ppdFindNextAttr(ppd, "cupsRGBSample", spec)) == NULL) + break; + else if (!attr->value) + { + fputs("ERROR: Bad cupsRGBSample value!\n", stderr); + break; + } + else if (sscanf(attr->value, "%f%f%f%f%f%f%f", values + 0, + values + 1, values + 2, values + 3, values + 4, values + 5, + values + 6) != (3 + num_channels)) + { + fputs("ERROR: Bad cupsRGBSample value!\n", stderr); + break; + } + else + { + samples[i].rgb[0] = (int)(255.0 * values[0] + 0.5); + samples[i].rgb[1] = (int)(255.0 * values[1] + 0.5); + samples[i].rgb[2] = (int)(255.0 * values[2] + 0.5); + samples[i].colors[0] = (int)(255.0 * values[3] + 0.5); + if (num_channels > 1) + samples[i].colors[1] = (int)(255.0 * values[4] + 0.5); + if (num_channels > 2) + samples[i].colors[2] = (int)(255.0 * values[5] + 0.5); + if (num_channels > 3) + samples[i].colors[3] = (int)(255.0 * values[6] + 0.5); + } + + /* + * If everything went OK, create the color profile... + */ + + if (i == num_samples) + rgbptr = cupsRGBNew(num_samples, samples, cube_size, num_channels); + else + rgbptr = NULL; + + /* + * Free the temporary sample array and return... + */ + + free(samples); + + return (rgbptr); +} + + +/* + * 'cupsRGBNew()' - Create a new RGB color separation. + */ + +cups_rgb_t * /* O - New color separation or NULL */ +cupsRGBNew(int num_samples, /* I - Number of samples */ + cups_sample_t *samples, /* I - Samples */ + int cube_size, /* I - Size of LUT cube */ + int num_channels) /* I - Number of color components */ +{ + cups_rgb_t *rgbptr; /* New color separation */ + int i; /* Looping var */ + int r, g, b; /* Current RGB */ + int tempsize; /* Sibe of main arrays */ + unsigned char *tempc; /* Pointer for C arrays */ + unsigned char **tempb ; /* Pointer for Z arrays */ + unsigned char ***tempg; /* Pointer for Y arrays */ + unsigned char ****tempr; /* Pointer for X array */ + unsigned char rgb[3]; /* Temporary RGB value */ + + + /* + * Range-check the input... + */ + + if (!samples || num_samples != (cube_size * cube_size * cube_size) || + num_channels <= 0 || num_channels > CUPS_MAX_RGB) + return (NULL); + + /* + * Allocate memory for the separation... + */ + + if ((rgbptr = calloc(1, sizeof(cups_rgb_t))) == NULL) + return (NULL); + + /* + * Allocate memory for the samples and the LUT cube... + */ + + tempsize = cube_size * cube_size * cube_size; /* FUTURE: num_samples < cs^3 */ + + tempc = calloc(tempsize, num_channels); + tempb = calloc(tempsize, sizeof(unsigned char *)); + tempg = calloc(cube_size * cube_size, sizeof(unsigned char **)); + tempr = calloc(cube_size, sizeof(unsigned char ***)); + + if (tempc == NULL || tempb == NULL || tempg == NULL || tempr == NULL) + { + free(rgbptr); + + if (tempc) + free(tempc); + + if (tempb) + free(tempb); + + if (tempg) + free(tempg); + + if (tempr) + free(tempr); + + return (NULL); + } + + /* + * Fill in the arrays... + */ + + for (i = 0, r = 0; r < cube_size; r ++) + { + tempr[r] = tempg + r * cube_size; + + for (g = 0; g < cube_size; g ++) + { + tempr[r][g] = tempb + i; + + for (b = 0; b < cube_size; b ++, i ++) + tempr[r][g][b] = tempc + i * num_channels; + } + } + + for (i = 0; i < num_samples; i ++) + { + r = samples[i].rgb[0] * (cube_size - 1) / 255; + g = samples[i].rgb[1] * (cube_size - 1) / 255; + b = samples[i].rgb[2] * (cube_size - 1) / 255; + + memcpy(tempr[r][g][b], samples[i].colors, num_channels); + } + + rgbptr->cube_size = cube_size; + rgbptr->num_channels = num_channels; + rgbptr->colors = tempr; + + /* + * Generate the lookup tables for the cube indices and multipliers... + */ + + for (i = 0; i < 256; i ++) + { + rgbptr->cube_index[i] = i * (cube_size - 1) / 256; + + if (i == 0) + rgbptr->cube_mult[i] = 256; + else + rgbptr->cube_mult[i] = 255 - ((i * (cube_size - 1)) & 255); + } + + /* + * Generate the black and white cache values for the separation... + */ + + rgb[0] = 0; + rgb[1] = 0; + rgb[2] = 0; + + cupsRGBDoRGB(rgbptr, rgb, rgbptr->black, 1); + + rgb[0] = 255; + rgb[1] = 255; + rgb[2] = 255; + + cupsRGBDoRGB(rgbptr, rgb, rgbptr->white, 1); + + rgbptr->cache_init = 1; + + /* + * Return the separation... + */ + + return (rgbptr); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/srgb.c b/driver/srgb.c new file mode 100644 index 0000000000..0354f23e51 --- /dev/null +++ b/driver/srgb.c @@ -0,0 +1,79 @@ +/* + * "$Id$" + * + * sRGB lookup tables for CUPS. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" + + +/* + * sRGB gamma lookup table. + */ + +const unsigned char cups_srgb_lut[256] = +{ + 0, 20, 28, 33, 38, 42, 46, 49, 52, 55, 58, 61, 63, 65, 68, + 70, 72, 74, 76, 78, 80, 81, 83, 85, 87, 88, 90, 91, 93, 94, + 96, 97, 99, 100, 102, 103, 104, 106, 107, 108, 109, 111, 112, 113, 114, + 115, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 147, 148, 149, 150, 151, 152, 153, 153, 154, 155, 156, 157, 158, + 158, 159, 160, 161, 162, 162, 163, 164, 165, 165, 166, 167, 168, 168, 169, + 170, 171, 171, 172, 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 180, + 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, + 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197, 198, 199, 199, + 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207, 208, 208, + 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217, + 217, 218, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 224, 224, 225, + 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, + 233, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, 239, 240, + 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, + 248, 248, 249, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, + 255 +}; + + +/* + * sRGB gamma lookup table (inverted output to map to CMYK...) + */ + +const unsigned char cups_scmy_lut[256] = +{ + 255, 235, 227, 222, 217, 213, 209, 206, 203, 200, 197, 194, 192, 190, 187, + 185, 183, 181, 179, 177, 175, 174, 172, 170, 168, 167, 165, 164, 162, 161, + 159, 158, 156, 155, 153, 152, 151, 149, 148, 147, 146, 144, 143, 142, 141, + 140, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 127, 126, 125, 124, + 123, 122, 121, 120, 119, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, + 109, 108, 108, 107, 106, 105, 104, 103, 102, 102, 101, 100, 99, 98, 97, + 97, 96, 95, 94, 93, 93, 92, 91, 90, 90, 89, 88, 87, 87, 86, + 85, 84, 84, 83, 82, 81, 81, 80, 79, 79, 78, 77, 77, 76, 75, + 74, 74, 73, 72, 72, 71, 70, 70, 69, 68, 68, 67, 66, 66, 65, + 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 58, 57, 56, 56, + 55, 55, 54, 53, 53, 52, 52, 51, 50, 50, 49, 49, 48, 47, 47, + 46, 46, 45, 45, 44, 43, 43, 42, 42, 41, 41, 40, 39, 39, 38, + 38, 37, 37, 36, 36, 35, 35, 34, 33, 33, 32, 32, 31, 31, 30, + 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, 24, 23, 23, + 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, + 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, + 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, + 0 +}; + + +/* + * End of "$Id$". + */ diff --git a/driver/testcmyk.c b/driver/testcmyk.c new file mode 100644 index 0000000000..a89353cd95 --- /dev/null +++ b/driver/testcmyk.c @@ -0,0 +1,437 @@ +/* + * "$Id$" + * + * Test the CMYK color separation code for ESP Print Pro. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products, All Rights Reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * test_gray() - Test grayscale separations... + * test_rgb() - Test color separations... + * main() - Do color separation tests. + */ + +/* + * Include necessary headers. + */ + +#include +#include "driver.h" +#include + + +void test_gray(int num_comps, const char *basename); +void test_rgb(int num_comps, const char *basename); + + +/* + * 'main()' - Do color separation tests. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + /* + * Make the test directory... + */ + + mkdir("test", 0755); + + /* + * Run tests for K, Kk, CMY, CMYK, CcMmYK, and CcMmYKk separations... + */ + + test_rgb(1, "test/K-rgb"); + test_rgb(2, "test/Kk-rgb"); + test_rgb(3, "test/CMY-rgb"); + test_rgb(4, "test/CMYK-rgb"); + test_rgb(6, "test/CcMmYK-rgb"); + test_rgb(7, "test/CcMmYKk-rgb"); + + test_gray(1, "test/K-gray"); + test_gray(2, "test/Kk-gray"); + test_gray(3, "test/CMY-gray"); + test_gray(4, "test/CMYK-gray"); + test_gray(6, "test/CcMmYK-gray"); + test_gray(7, "test/CcMmYKk-gray"); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'test_gray()' - Test grayscale separations... + */ + +void +test_gray(int num_comps, /* I - Number of components */ + const char *basename) /* I - Base filename of output */ +{ + int i; /* Looping var */ + char filename[255]; /* Output filename */ + char line[255]; /* Line from PGM file */ + int width, height; /* Width and height of test image */ + int x, y; /* Current coordinate in image */ + int r, g, b; /* Current RGB color */ + unsigned char input[7000]; /* Line to separate */ + short output[48000], /* Output separation data */ + *outptr; /* Pointer in output */ + FILE *in; /* Input PPM file */ + FILE *out[CUPS_MAX_CHAN]; + /* Output PGM files */ + FILE *comp; /* Composite output */ + cups_cmyk_t *cmyk; /* Color separation */ + + + /* + * Open the test image... + */ + + in = fopen("image.pgm", "rb"); + while (fgets(line, sizeof(line), in) != NULL) + if (isdigit(line[0])) + break; + + sscanf(line, "%d%d", &width, &height); + + fgets(line, sizeof(line), in); + + /* + * Create the color separation... + */ + + cmyk = cupsCMYKNew(num_comps); + + switch (num_comps) + { + case 2 : /* Kk */ + cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); + break; + + case 4 : + cupsCMYKSetGamma(cmyk, 2, 1.0, 0.9); + cupsCMYKSetBlack(cmyk, 0.5, 1.0); + break; + + case 6 : /* CcMmYK */ + cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); + cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); + cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9); + cupsCMYKSetBlack(cmyk, 0.5, 1.0); + break; + + case 7 : /* CcMmYKk */ + cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); + cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); + cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9); + cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0); + break; + } + + /* + * Open the color separation files... + */ + + for (i = 0; i < num_comps; i ++) + { + sprintf(filename, "%s%d.pgm", basename, i); + out[i] = fopen(filename, "wb"); + + fprintf(out[i], "P5\n%d %d 255\n", width, height); + } + + sprintf(filename, "%s.ppm", basename); + comp = fopen(filename, "wb"); + + fprintf(comp, "P6\n%d %d 255\n", width, height); + + /* + * Read the image and do the separations... + */ + + for (y = 0; y < height; y ++) + { + fread(input, width, 1, in); + + cupsCMYKDoGray(cmyk, input, output, width); + + for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) + { + for (i = 0; i < num_comps; i ++) + putc(255 - 255 * outptr[i] / 4095, out[i]); + + r = 4095; + g = 4095; + b = 4095; + + switch (num_comps) + { + case 1 : + r -= outptr[0]; + g -= outptr[0]; + b -= outptr[0]; + break; + case 2 : + r -= outptr[0]; + g -= outptr[0]; + b -= outptr[0]; + + r -= outptr[1] / 2; + g -= outptr[1] / 2; + b -= outptr[1] / 2; + break; + case 3 : + r -= outptr[0]; + g -= outptr[1]; + b -= outptr[2]; + break; + case 4 : + r -= outptr[0]; + g -= outptr[1]; + b -= outptr[2]; + + r -= outptr[3]; + g -= outptr[3]; + b -= outptr[3]; + break; + case 6 : + r -= outptr[0] + outptr[1] / 2; + g -= outptr[2] + outptr[3] / 3; + b -= outptr[4]; + + r -= outptr[5]; + g -= outptr[5]; + b -= outptr[5]; + break; + case 7 : + r -= outptr[0] + outptr[1] / 2; + g -= outptr[2] + outptr[3] / 3; + b -= outptr[4]; + + r -= outptr[5] + outptr[6] / 2; + g -= outptr[5] + outptr[6] / 2; + b -= outptr[5] + outptr[6] / 2; + break; + } + + if (r < 0) + putc(0, comp); + else + putc(255 * r / 4095, comp); + + if (g < 0) + putc(0, comp); + else + putc(255 * g / 4095, comp); + + if (b < 0) + putc(0, comp); + else + putc(255 * b / 4095, comp); + } + } + + for (i = 0; i < num_comps; i ++) + fclose(out[i]); + + fclose(comp); + fclose(in); + + cupsCMYKDelete(cmyk); +} + + +/* + * 'test_rgb()' - Test color separations... + */ + +void +test_rgb(int num_comps, /* I - Number of components */ + const char *basename) /* I - Base filename of output */ +{ + int i; /* Looping var */ + char filename[255]; /* Output filename */ + char line[255]; /* Line from PPM file */ + int width, height; /* Width and height of test image */ + int x, y; /* Current coordinate in image */ + int r, g, b; /* Current RGB color */ + unsigned char input[7000]; /* Line to separate */ + short output[48000], /* Output separation data */ + *outptr; /* Pointer in output */ + FILE *in; /* Input PPM file */ + FILE *out[CUPS_MAX_CHAN]; + /* Output PGM files */ + FILE *comp; /* Composite output */ + cups_cmyk_t *cmyk; /* Color separation */ + + + /* + * Open the test image... + */ + + in = fopen("image.ppm", "rb"); + while (fgets(line, sizeof(line), in) != NULL) + if (isdigit(line[0])) + break; + + sscanf(line, "%d%d", &width, &height); + + fgets(line, sizeof(line), in); + + /* + * Create the color separation... + */ + + cmyk = cupsCMYKNew(num_comps); + + cupsCMYKSetBlack(cmyk, 0.5, 1.0); + + switch (num_comps) + { + case 2 : /* Kk */ + cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); + break; + case 6 : /* CcMmYK */ + cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8); + cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); + cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8); + cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); + break; + case 7 : /* CcMmYKk */ + cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8); + cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0); + cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8); + cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0); + cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0); + break; + } + + /* + * Open the color separation files... + */ + + for (i = 0; i < num_comps; i ++) + { + sprintf(filename, "%s%d.pgm", basename, i); + out[i] = fopen(filename, "wb"); + + fprintf(out[i], "P5\n%d %d 255\n", width, height); + } + + sprintf(filename, "%s.ppm", basename); + comp = fopen(filename, "wb"); + + fprintf(comp, "P6\n%d %d 255\n", width, height); + + /* + * Read the image and do the separations... + */ + + for (y = 0; y < height; y ++) + { + fread(input, width, 3, in); + + cupsCMYKDoRGB(cmyk, input, output, width); + + for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) + { + for (i = 0; i < num_comps; i ++) + putc(255 - 255 * outptr[i] / 4095, out[i]); + + r = 4095; + g = 4095; + b = 4095; + + switch (num_comps) + { + case 1 : + r -= outptr[0]; + g -= outptr[0]; + b -= outptr[0]; + break; + case 2 : + r -= outptr[0]; + g -= outptr[0]; + b -= outptr[0]; + + r -= outptr[1] / 2; + g -= outptr[1] / 2; + b -= outptr[1] / 2; + break; + case 3 : + r -= outptr[0]; + g -= outptr[1]; + b -= outptr[2]; + break; + case 4 : + r -= outptr[0]; + g -= outptr[1]; + b -= outptr[2]; + + r -= outptr[3]; + g -= outptr[3]; + b -= outptr[3]; + break; + case 6 : + r -= outptr[0] + outptr[1] / 2; + g -= outptr[2] + outptr[3] / 3; + b -= outptr[4]; + + r -= outptr[5]; + g -= outptr[5]; + b -= outptr[5]; + break; + case 7 : + r -= outptr[0] + outptr[1] / 2; + g -= outptr[2] + outptr[3] / 3; + b -= outptr[4]; + + r -= outptr[5] + outptr[6] / 2; + g -= outptr[5] + outptr[6] / 2; + b -= outptr[5] + outptr[6] / 2; + break; + } + + if (r < 0) + putc(0, comp); + else + putc(255 * r / 4095, comp); + + if (g < 0) + putc(0, comp); + else + putc(255 * g / 4095, comp); + + if (b < 0) + putc(0, comp); + else + putc(255 * b / 4095, comp); + } + } + + for (i = 0; i < num_comps; i ++) + fclose(out[i]); + + fclose(comp); + fclose(in); + + cupsCMYKDelete(cmyk); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/testdither.c b/driver/testdither.c new file mode 100644 index 0000000000..29f5e337ed --- /dev/null +++ b/driver/testdither.c @@ -0,0 +1,191 @@ +/* + * "$Id$" + * + * Dither test program for ESP Print Pro. + * + * Try the following: + * + * testdither 0 255 > filename.ppm + * testdither 0 127 255 > filename.ppm + * testdither 0 85 170 255 > filename.ppm + * testdither 0 63 127 170 198 227 255 > filename.ppm + * testdither 0 210 383 > filename.ppm + * testdither 0 82 255 > filename.ppm + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Test dithering and output a PPM file. + * usage() - Show program usage... + */ + +/* + * Include necessary headers. + */ + +#include "driver.h" +#include + + +/* + * Local functions... + */ + +void usage(void); + + +/* + * 'main()' - Test dithering and output a PPM file. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int x, y; /* Current coordinate in image */ + short line[512]; /* Line to dither */ + unsigned char pixels[512], /* Dither pixels */ + *pixptr; /* Pointer in line */ + int output; /* Output pixel */ + cups_lut_t *lut; /* Dither lookup table */ + cups_dither_t *dither; /* Dither state */ + int nlutvals; /* Number of lookup values */ + float lutvals[16]; /* Lookup values */ + int pixvals[16]; /* Pixel values */ + + + /* + * See if we have lookup table values on the command-line... + */ + + if (argc > 1) + { + /* + * Yes, collect them... + */ + + nlutvals = 0; + + for (x = 1; x < argc; x ++) + if (isdigit(argv[x][0]) && nlutvals < 16) + { + pixvals[nlutvals] = atoi(argv[x]); + lutvals[nlutvals] = atof(argv[x]) / 255.0; + nlutvals ++; + } + else + usage(); + + /* + * See if we have at least 2 values... + */ + + if (nlutvals < 2) + usage(); + } + else + { + /* + * Otherwise use the default 2-entry LUT with values of 0 and 255... + */ + + nlutvals = 2; + lutvals[0] = 0.0; + lutvals[1] = 1.0; + pixvals[0] = 0; + pixvals[1] = 255; + } + + /* + * Create the lookup table and dither state... + */ + + lut = cupsLutNew(nlutvals, lutvals); + dither = cupsDitherNew(512); + + /* + * Put out the PGM header for a raw 256x256x8-bit grayscale file... + */ + + puts("P5\n512\n512\n255"); + + /* + * Dither 512 lines, which are written out in 256 image lines... + */ + + for (y = 0; y < 512; y ++) + { + /* + * Create the grayscale data for the current line... + */ + + for (x = 0; x < 512; x ++) + line[x] = 4095 * ((y / 32) * 16 + x / 32) / 255; + + /* + * Dither the line... + */ + + cupsDitherLine(dither, lut, line, 1, pixels); + + if (y == 0) + { + fputs("DEBUG: pixels =", stderr); + for (x = 0; x < 512; x ++) + fprintf(stderr, " %d", pixels[x]); + fputs("\n", stderr); + } + + /* + * Add or set the output pixel values... + */ + + for (x = 0, pixptr = pixels; x < 512; x ++, pixptr ++) + { + output = 255 - pixvals[*pixptr]; + + if (output < 0) + putchar(0); + else + putchar(output); + } + } + + /* + * Free the dither state and lookup table... + */ + + cupsDitherDelete(dither); + cupsLutDelete(lut); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'usage()' - Show program usage... + */ + +void +usage(void) +{ + puts("Usage: testdither [val1 val2 [... val16]] >filename.ppm"); + exit(1); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/testdriver.c b/driver/testdriver.c new file mode 100644 index 0000000000..41059cfd38 --- /dev/null +++ b/driver/testdriver.c @@ -0,0 +1,178 @@ +/* + * "$Id$" + * + * Sample/test driver interface program for the Common UNIX Printing + * System (CUPS). + * + * This program handles listing and installing both static PPD files + * in CUPS_DATADIR/model and dynamically generated PPD files using + * the driver helper programs in CUPS_SERVERBIN/driver. + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Enumerate or display PPD files. + * cat_ppd() - Display a PPD file. + * list_ppds() - List PPDs. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + + +/* + * Local functions... + */ + +static int cat_ppd(const char *uri); +static int list_ppds(const char *name); + + +/* + * Sample data... + */ + +static const char *models[][2] = + { + { "foojet.ppd", "Foo Printer" }, + { "barjet.ppd", "Bar Printer" }, + { "foobar.ppd", "Foo/Bar Multifunction Printer" } + }; + + +/* + * 'main()' - Enumerate or display PPD files. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + if (argc == 2 && !strcmp(argv[1], "list")) + return (list_ppds(argv[0])); + else if (argc == 3 && !strcmp(argv[1], "cat")) + return (cat_ppd(argv[2])); + + fprintf(stderr, "ERROR: Usage: %s cat URI\n", argv[0]); + fprintf(stderr, "ERROR: Usage: %s list\n", argv[0]); + return (1); +} + + +/* + * 'cat_ppd()' - Display a PPD file. + */ + +static int /* O - Exit status */ +cat_ppd(const char *uri) /* I - PPD URI */ +{ + int i; /* Looping var */ + char scheme[255], /* URI scheme */ + userpass[255], /* Username/password (unused) */ + hostname[255], /* Hostname (unused) */ + resource[1024]; /* Resource name */ + int port; /* Port (unused) */ + const char *name; /* Pointer to name in URI */ + + + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + userpass, sizeof(userpass), hostname, sizeof(hostname), + &port, resource, sizeof(resource)) < HTTP_URI_OK) + { + fprintf(stderr, "ERROR: Bad URI \"%s\"!\n", uri); + return (1); + } + + name = resource + 1; + + for (i = 0 ; i < (int)(sizeof(models) / sizeof(models[0])); i ++) + if (!strcmp(name, models[i][0])) + { + /* + * Actually display the PPD file... + */ + puts("*PPD-Adobe: \"4.3\""); + + puts("*LanguageEncoding: ISOLatin1"); + puts("*LanguageVersion: English"); + puts("*Manufacturer: \"Test\""); + puts("*FileVersion: \"1.0\""); + puts("*FormatVersion: \"4.3\""); + puts("*PSVersion: \"(3010) 1\""); + printf("*PCFileName: \"%s\"\n", models[i][0]); + + printf("*Product: \"(%s)\"\n", models[i][1]); + printf("*ModelName: \"Test %s\"\n", models[i][1]); + printf("*NickName: \"Test %s\"\n", models[i][1]); + printf("*ShortNickName: \"Test %s\"\n", models[i][1]); + + puts("*OpenUI PageSize: PickOne"); + puts("*OrderDependency: 10 AnySetup *PageSetup"); + puts("*DefaultPageSize: Letter"); + puts("*PageSize Letter: \"<>setpagedevice\""); + puts("*PageSize A4: \"<>setpagedevice\""); + puts("*CloseUI: *PageSize"); + + puts("*OpenUI PageRegion: PickOne"); + puts("*OrderDependency: 10 AnySetup *PageRegion"); + puts("*DefaultPageRegion: Letter"); + puts("*PageRegion Letter: \"<>setpagedevice\""); + puts("*PageRegion A4: \"<>setpagedevice\""); + puts("*CloseUI: *PageRegion"); + + puts("*DefaultImageableArea: Letter"); + puts("*ImageableArea Letter: \"0 0 612 792\""); + puts("*ImageableArea A4: \"0 0 595 842\""); + + puts("*DefaultPaperDimension: Letter"); + puts("*PaperDimension Letter: \"612 792\""); + puts("*PaperDimension A4: \"595 842\""); + + return (0); + } + + fprintf(stderr, "ERROR: Unknown URI \"%s\"!\n", uri); + return (1); +} + + +/* + * 'list_ppds()' - List PPDs. + */ + +static int /* O - Exit status */ +list_ppds(const char *name) /* I - Program name */ +{ + int i; /* Looping var */ + const char *base; /* Base name of program */ + + + if ((base = strrchr(name, '/')) != NULL) + base ++; + else + base = name; + + for (i = 0; i < (int)(sizeof(models) / sizeof(models[0])); i ++) + printf("\"%s:///%s\" en \"Test\" \"Test %s\" \"1284 device id\"\n", + base, models[i][0], models[i][1]); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/driver/testrgb.c b/driver/testrgb.c new file mode 100644 index 0000000000..3fb0ae41a9 --- /dev/null +++ b/driver/testrgb.c @@ -0,0 +1,348 @@ +/* + * "$Id$" + * + * Test the new RGB color separation code for ESP Print Pro. + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products, All Rights Reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Do color rgb tests. + * test_gray() - Test grayscale rgbs... + * test_rgb() - Test color rgbs... + */ + +/* + * Include necessary headers. + */ + +#include +#include "driver.h" +#include + +#ifdef HAVE_LIBLCMS +# include +#endif /* HAVE_LIBLCMS */ + + +void test_gray(cups_sample_t *samples, int num_samples, + int cube_size, int num_comps, const char *basename); +void test_rgb(cups_sample_t *samples, int num_samples, + int cube_size, int num_comps, + const char *basename); + + +/* + * 'main()' - Do color rgb tests. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + static cups_sample_t CMYK[] = /* Basic 4-color sep */ + { + /*{ r, g, b }, { C, M, Y, K }*/ + { { 0, 0, 0 }, { 0, 0, 0, 255 } }, + { { 255, 0, 0 }, { 0, 255, 240, 0 } }, + { { 0, 255, 0 }, { 200, 0, 200, 0 } }, + { { 255, 255, 0 }, { 0, 0, 240, 0 } }, + { { 0, 0, 255 }, { 200, 200, 0, 0 } }, + { { 255, 0, 255 }, { 0, 200, 0, 0 } }, + { { 0, 255, 255 }, { 200, 0, 0, 0 } }, + { { 255, 255, 255 }, { 0, 0, 0, 0 } } + }; + + + /* + * Make the test directory... + */ + + mkdir("test", 0755); + + /* + * Run tests for CMYK and CMYK separations... + */ + + test_rgb(CMYK, 8, 2, 4, "test/rgb-cmyk"); + + test_gray(CMYK, 8, 2, 4, "test/gray-cmyk"); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'test_gray()' - Test grayscale rgbs... + */ + +void +test_gray(cups_sample_t *samples, /* I - Sample values */ + int num_samples, /* I - Number of samples */ + int cube_size, /* I - Cube size */ + int num_comps, /* I - Number of components */ + const char *basename) /* I - Base filename of output */ +{ + int i; /* Looping var */ + char filename[255]; /* Output filename */ + char line[255]; /* Line from PPM file */ + int width, height; /* Width and height of test image */ + int x, y; /* Current coordinate in image */ + int r, g, b; /* Current RGB color */ + unsigned char input[7000]; /* Line to rgbarate */ + unsigned char output[48000], /* Output rgb data */ + *outptr; /* Pointer in output */ + FILE *in; /* Input PPM file */ + FILE *out[CUPS_MAX_CHAN]; + /* Output PGM files */ + FILE *comp; /* Composite output */ + cups_rgb_t *rgb; /* Color separation */ + + + /* + * Open the test image... + */ + + in = fopen("image.pgm", "rb"); + while (fgets(line, sizeof(line), in) != NULL) + if (isdigit(line[0])) + break; + + sscanf(line, "%d%d", &width, &height); + + fgets(line, sizeof(line), in); + + /* + * Create the color rgb... + */ + + rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps); + + /* + * Open the color rgb files... + */ + + for (i = 0; i < num_comps; i ++) + { + sprintf(filename, "%s%d.pgm", basename, i); + out[i] = fopen(filename, "wb"); + + fprintf(out[i], "P5\n%d %d 255\n", width, height); + } + + sprintf(filename, "%s.ppm", basename); + comp = fopen(filename, "wb"); + + fprintf(comp, "P6\n%d %d 255\n", width, height); + + /* + * Read the image and do the rgbs... + */ + + for (y = 0; y < height; y ++) + { + fread(input, width, 1, in); + + cupsRGBDoGray(rgb, input, output, width); + + for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) + { + for (i = 0; i < num_comps; i ++) + putc(255 - outptr[i], out[i]); + + r = 255; + g = 255; + b = 255; + + r -= outptr[0]; + g -= outptr[1]; + b -= outptr[2]; + + r -= outptr[3]; + g -= outptr[3]; + b -= outptr[3]; + + if (num_comps > 4) + { + r -= outptr[4] / 2; + g -= outptr[5] / 2; + } + + if (num_comps > 6) + { + r -= outptr[6] / 2; + g -= outptr[6] / 2; + b -= outptr[6] / 2; + } + + if (r < 0) + putc(0, comp); + else + putc(r, comp); + + if (g < 0) + putc(0, comp); + else + putc(g, comp); + + if (b < 0) + putc(0, comp); + else + putc(b, comp); + } + } + + for (i = 0; i < num_comps; i ++) + fclose(out[i]); + + fclose(comp); + fclose(in); + + cupsRGBDelete(rgb); +} + + +/* + * 'test_rgb()' - Test color rgbs... + */ + +void +test_rgb(cups_sample_t *samples, /* I - Sample values */ + int num_samples, /* I - Number of samples */ + int cube_size, /* I - Cube size */ + int num_comps, /* I - Number of components */ + const char *basename) /* I - Base filename of output */ +{ + int i; /* Looping var */ + char filename[255]; /* Output filename */ + char line[255]; /* Line from PPM file */ + int width, height; /* Width and height of test image */ + int x, y; /* Current coordinate in image */ + int r, g, b; /* Current RGB color */ + unsigned char input[7000]; /* Line to rgbarate */ + unsigned char output[48000], /* Output rgb data */ + *outptr; /* Pointer in output */ + FILE *in; /* Input PPM file */ + FILE *out[CUPS_MAX_CHAN]; + /* Output PGM files */ + FILE *comp; /* Composite output */ + cups_rgb_t *rgb; /* Color separation */ + + + /* + * Open the test image... + */ + + in = fopen("image.ppm", "rb"); + while (fgets(line, sizeof(line), in) != NULL) + if (isdigit(line[0])) + break; + + sscanf(line, "%d%d", &width, &height); + + fgets(line, sizeof(line), in); + + /* + * Create the color rgb... + */ + + rgb = cupsRGBNew(num_samples, samples, cube_size, num_comps); + + /* + * Open the color rgb files... + */ + + for (i = 0; i < num_comps; i ++) + { + sprintf(filename, "%s%d.pgm", basename, i); + out[i] = fopen(filename, "wb"); + + fprintf(out[i], "P5\n%d %d 255\n", width, height); + } + + sprintf(filename, "%s.ppm", basename); + comp = fopen(filename, "wb"); + + fprintf(comp, "P6\n%d %d 255\n", width, height); + + /* + * Read the image and do the rgbs... + */ + + for (y = 0; y < height; y ++) + { + fread(input, width, 3, in); + + cupsRGBDoRGB(rgb, input, output, width); + + for (x = 0, outptr = output; x < width; x ++, outptr += num_comps) + { + for (i = 0; i < num_comps; i ++) + putc(255 - outptr[i], out[i]); + + r = 255; + g = 255; + b = 255; + + r -= outptr[0]; + g -= outptr[1]; + b -= outptr[2]; + + r -= outptr[3]; + g -= outptr[3]; + b -= outptr[3]; + + if (num_comps > 4) + { + r -= outptr[4] / 2; + g -= outptr[5] / 2; + } + + if (num_comps > 6) + { + r -= outptr[6] / 2; + g -= outptr[6] / 2; + b -= outptr[6] / 2; + } + + if (r < 0) + putc(0, comp); + else + putc(r, comp); + + if (g < 0) + putc(0, comp); + else + putc(g, comp); + + if (b < 0) + putc(0, comp); + else + putc(b, comp); + } + } + + for (i = 0; i < num_comps; i ++) + fclose(out[i]); + + fclose(comp); + fclose(in); + + cupsRGBDelete(rgb); +} + + +/* + * End of "$Id$". + */ diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000000..928d71c155 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,128 @@ +# +# "$Id$" +# +# PPD compiler example makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 2002-2005 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Include standard definitions... +# + +include ../Makedefs + + +# +# Examples... +# + +EXAMPLES = \ + color.drv \ + constraint.drv \ + custom.drv \ + grouping.drv \ + laserjet-basic.drv \ + laserjet-pjl.drv \ + minimum.drv \ + postscript.drv \ + r300-basic.drv \ + r300-colorman.drv \ + r300-remote.drv + + +# +# Make everything... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean everything... +# + +clean: + + +# +# Dummy depend... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + $(INSTALL_DIR) $(DATADIR)/examples + for file in $(EXAMPLES); do \ + $(INSTALL_DATA) $$file $(DATADIR)/examples; \ + done + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: + for file in $(EXAMPLES); do \ + $(RM) $(DATADIR)/examples/$$file; \ + done + -$(RMDIR) $(DATADIR)/examples + + +# +# End of "$Id$". +# diff --git a/examples/color.drv b/examples/color.drv new file mode 100644 index 0000000000..69984c4b9c --- /dev/null +++ b/examples/color.drv @@ -0,0 +1,44 @@ +// Include standard font and media definitions +#include +#include + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and version +Manufacturer "Foo" +Version 1.0 + +// Each filter provided by the driver... +Filter application/vnd.cups-raster 100 rastertofoo + +// Supported page sizes +*MediaSize Letter +MediaSize A4 + +{ + // Supported resolutions + *Resolution k 8 0 0 0 "600dpi/600 DPI" + + // Specify the model name and filename... + ModelName "FooJet 2000" + PCFileName "foojet2k.ppd" +} + +{ + // Supports color printing + ColorDevice true + + // Supported colorspaces + ColorModel Gray/Grayscale w chunky 0 + *ColorModel RGB/Color rgb chunky 0 + + // Supported resolutions + *Resolution - 8 0 0 0 "300dpi/300 DPI" + Resolution - 8 0 0 0 "600dpi/600 DPI" + + // Specify the model name and filename... + ModelName "FooJet Color" + PCFileName "foojetco.ppd" +} diff --git a/examples/constraint.drv b/examples/constraint.drv new file mode 100644 index 0000000000..6acb7f106d --- /dev/null +++ b/examples/constraint.drv @@ -0,0 +1,48 @@ +// Include standard font and media definitions +#include +#include + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer, model name, and version +Manufacturer "Foo" +ModelName "FooJet 2000" +Version 1.0 + +// Each filter provided by the driver... +Filter application/vnd.cups-raster 100 rastertofoo + +// Supported page sizes +*MediaSize Letter +MediaSize A4 + +// Supported resolutions +*Resolution k 8 0 0 0 "600dpi/600 DPI" + +// Installable Option Group +Group "InstallableOptions/Options Installed" + + // Duplexing unit option + Option "Option1/Duplexing Unit" Boolean AnySetup 10 + Choice True/Installed "" + *Choice "False/Not Installed" "" + +// General Option Group +Group General + + // Duplexing option + Option "Duplex/Two-Sided Printing" PickOne AnySetup 10 + *Choice "None/No" "<>setpagedevice" + Choice "DuplexNoTumble/Long Edge Binding" + "<>setpagedevice" + Choice "DuplexTumble/Short Edge Binding" + "<>setpagedevice" + +// Only allow duplexing if the duplexer is installed +UIConstraints "*Duplex *Option1 False" + +// Specify the name of the PPD file we want to generate... +PCFileName "foojet2k.ppd" + diff --git a/examples/custom.drv b/examples/custom.drv new file mode 100644 index 0000000000..1001c4fc19 --- /dev/null +++ b/examples/custom.drv @@ -0,0 +1,41 @@ +// Include standard font and media definitions +#include +#include + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer, model name, and version +Manufacturer "Foo" +ModelName "FooJet 2000" +Version 1.0 + +// Each filter provided by the driver... +Filter application/vnd.cups-raster 100 rastertofoo + +// Supported page sizes +*MediaSize Letter +MediaSize A4 + +// Supported resolutions +*Resolution k 8 0 0 0 "600dpi/600 DPI" + +// Option Group +Group "Footasm" + + // Boolean option + Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10 + *Choice True/Yes "<>setpagedevice" + Choice False/No "<>setpagedevice" + + // Multiple choice option + Option "fooOutputType/Output Quality" PickOne AnySetup 10 + *Choice "Auto/Automatic Selection" "<>setpagedevice" + Choice "Text/Optimize for Text" "<>setpagedevice" + Choice "Graph/Optimize for Graphics" "<>setpagedevice" + Choice "Photo/Optimize for Photos" "<>setpagedevice" + +// Specify the name of the PPD file we want to generate... +PCFileName "foojet2k.ppd" + diff --git a/examples/grouping.drv b/examples/grouping.drv new file mode 100644 index 0000000000..da66d74fc9 --- /dev/null +++ b/examples/grouping.drv @@ -0,0 +1,36 @@ +// Include standard font and media definitions +#include +#include + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and version +Manufacturer "Foo" +Version 1.0 + +// Each filter provided by the driver... +Filter application/vnd.cups-raster 100 rastertofoo + +// Supported page sizes +*MediaSize Letter +MediaSize A4 + +{ + // Supported resolutions + *Resolution k 8 0 0 0 "600dpi/600 DPI" + + // Specify the model name and filename... + ModelName "FooJet 2000" + PCFileName "foojet2k.ppd" +} + +{ + // Supported resolutions + *Resolution k 8 0 0 0 "1200dpi/1200 DPI" + + // Specify the model name and filename... + ModelName "FooJet 2001" + PCFileName "foojt2k1.ppd" +} diff --git a/examples/laserjet-basic.drv b/examples/laserjet-basic.drv new file mode 100644 index 0000000000..6924ed7b89 --- /dev/null +++ b/examples/laserjet-basic.drv @@ -0,0 +1,88 @@ +// Include standard font and media definitions +#include +#include + +// Include HP-PCL driver definitions +#include + +// Specify that this driver uses the HP-PCL driver... +DriverType pcl + +// Specify the driver options via the model number... +ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION) + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and driver version +Manufacturer "HP" +Version 1.0 + +// Supported page sizes and their margins +HWMargins 18 12 18 12 +*MediaSize Letter +MediaSize Legal +MediaSize Executive +MediaSize Monarch +MediaSize Statement +MediaSize FanFoldGermanLegal + +HWMargins 18 12.72 18 12.72 +MediaSize Env10 + +HWMargins 9.72 12 9.72 12 +MediaSize A4 +MediaSize A5 +MediaSize B5 +MediaSize EnvC5 +MediaSize EnvDL +MediaSize EnvISOB5 +MediaSize Postcard +MediaSize DoublePostcard + +// Only black-and-white output with mode 3 compression... +ColorModel Gray k chunky 3 + +// Supported resolutions +Resolution - 1 0 0 0 "300dpi/300 DPI" +*Resolution - 8 0 0 0 "600dpi/600 DPI" + +// Supported input slots +*InputSlot 7 "Auto/Automatic Selection" +InputSlot 2 "Manual/Tray 1 - Manual Feed" +InputSlot 4 "Upper/Tray 1" +InputSlot 1 "Lower/Tray 2" +InputSlot 5 "LargeCapacity/Tray 3" + +// Tray 3 is an option... +Installable "OptionLargeCapacity/Tray 3 Installed" +UIConstraints "*OptionLargeCapacity False *InputSlot LargeCapacity" + +{ + // HP LaserJet 2100 Series + Throughput 10 + ModelName "LaserJet 2100 Series" + PCFileName "hpljt211.ppd" +} + +{ + // LaserJet 2200 and 2300 series have duplexer option... + Duplex normal + Installable "OptionDuplex/Duplexer Installed" + UIConstraints "*OptionDuplex False *Duplex" + + { + // HP LaserJet 2200 Series + Throughput 19 + ModelName "LaserJet 2200 Series" + PCFileName "hpljt221.ppd" + } + + { + // HP LaserJet 2300 Series + Throughput 25 + ModelName "LaserJet 2300 Series" + PCFileName "hpljt231.ppd" + } +} diff --git a/examples/laserjet-pjl.drv b/examples/laserjet-pjl.drv new file mode 100644 index 0000000000..32a0bc4f02 --- /dev/null +++ b/examples/laserjet-pjl.drv @@ -0,0 +1,101 @@ +// Include standard font and media definitions +#include +#include + +// Include HP-PCL driver definitions +#include + +// Specify that this driver uses the HP-PCL driver... +DriverType pcl + +// Specify the driver options via the model number... +ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION) + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and driver version +Manufacturer "HP" +Version 2.0 + +// Supported page sizes and their margins +HWMargins 18 12 18 12 +*MediaSize Letter +MediaSize Legal +MediaSize Executive +MediaSize Monarch +MediaSize Statement +MediaSize FanFoldGermanLegal + +HWMargins 18 12.72 18 12.72 +MediaSize Env10 + +HWMargins 9.72 12 9.72 12 +MediaSize A4 +MediaSize A5 +MediaSize B5 +MediaSize EnvC5 +MediaSize EnvDL +MediaSize EnvISOB5 +MediaSize Postcard +MediaSize DoublePostcard + +// Only black-and-white output with mode 3 compression... +ColorModel Gray k chunky 3 + +// Supported resolutions +Resolution - 1 0 0 0 "300dpi/300 DPI" +*Resolution - 8 0 0 0 "600dpi/600 DPI" + +// Supported input slots +*InputSlot 7 "Auto/Automatic Selection" +InputSlot 2 "Manual/Tray 1 - Manual Feed" +InputSlot 4 "Upper/Tray 1" +InputSlot 1 "Lower/Tray 2" +InputSlot 5 "LargeCapacity/Tray 3" + +// Tray 3 is an option... +Installable "OptionLargeCapacity/Tray 3 Installed" +UIConstraints "*OptionLargeCapacity False *InputSlot LargeCapacity" + +// PJL options +Attribute cupsPJL cupsRET "@PJL SET SMOOTHING=%?False:OFF;%?True:ON;%n" + +Option "cupsRET/Smoothing" Boolean DocumentSetup 10 + Choice "False/Off" "" + *Choice "True/On" "" + +Attribute cupsPJL cupsTonerSave "@PJL SET ECONOMODE=%?False:OFF;%?True:ON;%n" + +Option "cupsTonerSave/Save Toner" Boolean DocumentSetup 10 + *Choice "False/No" "" + Choice "True/Yes" "" + +{ + // HP LaserJet 2100 Series + Throughput 10 + ModelName "LaserJet 2100 Series PJL" + PCFileName "hpljt212.ppd" +} + +{ + // LaserJet 2200 and 2300 series have duplexer option... + Duplex normal + Installable "OptionDuplex/Duplexer Installed" + UIConstraints "*OptionDuplex False *Duplex" + + { + // HP LaserJet 2200 Series + Throughput 19 + ModelName "LaserJet 2200 Series PJL" + PCFileName "hpljt222.ppd" + } + + { + // HP LaserJet 2300 Series + Throughput 25 + ModelName "LaserJet 2300 Series PJL" + PCFileName "hpljt232.ppd" + } +} diff --git a/examples/minimum.drv b/examples/minimum.drv new file mode 100644 index 0000000000..ac6e38db08 --- /dev/null +++ b/examples/minimum.drv @@ -0,0 +1,26 @@ +// Include standard font and media definitions +#include +#include + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer, model name, and version +Manufacturer "Foo" +ModelName "FooJet 2000" +Version 1.0 + +// Each filter provided by the driver... +Filter application/vnd.cups-raster 100 rastertofoo + +// Supported page sizes +*MediaSize Letter +MediaSize A4 + +// Supported resolutions +*Resolution k 8 0 0 0 "600dpi/600 DPI" + +// Specify the name of the PPD file we want to generate... +PCFileName "foojet2k.ppd" + diff --git a/examples/postscript.drv b/examples/postscript.drv new file mode 100644 index 0000000000..ebb02f8a09 --- /dev/null +++ b/examples/postscript.drv @@ -0,0 +1,46 @@ +// Include standard font and media definitions +#include +#include + +// Specify this is a PostScript printer driver +DriverType ps + +// List the fonts that are supported, in this case all standard fonts +Font * + +// Manufacturer, model name, and version +Manufacturer "Foo" +ModelName "Foo LaserProofer 2000" +Version 1.0 + +// PostScript printer attributes +Attribute DefaultColorSpace "" Gray +Attribute LandscapeOrientation "" Minus90 +Attribute LanguageLevel "" "3" +Attribute Product "" "(Foo LaserProofer 2000)" +Attribute PSVersion "" "(3010) 0" +Attribute TTRasterizer "" Type42 + +// Supported page sizes +*MediaSize Letter +MediaSize Legal +MediaSize A4 + +// Query command for page size +Attribute "?PageSize" "" " + save + currentpagedevice /PageSize get aload pop + 2 copy gt {exch} if (Unknown) + 23 dict + dup [612 792] (Letter) put + dup [612 1008] (Legal) put + dup [595 842] (A4) put + {exch aload pop 4 index sub abs 5 le exch + 5 index sub abs 5 le and + {exch pop exit} {pop} ifelse + } bind forall = flush pop pop + restore" + +// Specify the name of the PPD file we want to generate +PCFileName "fooproof.ppd" + diff --git a/examples/r300-basic.drv b/examples/r300-basic.drv new file mode 100644 index 0000000000..e203d511d8 --- /dev/null +++ b/examples/r300-basic.drv @@ -0,0 +1,75 @@ +// Include standard font and media definitions +#include +#include + +// Include ESC/P driver definitions +#include + +// Specify that this driver uses the ESC/P driver... +DriverType escp + +// Specify the driver options via the model number... +ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB + $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI) + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and driver version +Manufacturer "Epson" +Version 1.0 + +// Supported page sizes and their margins +HWMargins 8.4 0 8.4 0 +*MediaSize Letter +MediaSize Legal +MediaSize Executive +MediaSize Statement +MediaSize A4 +MediaSize A5 +MediaSize A6 +MediaSize B5 +MediaSize Env10 +MediaSize EnvC5 +MediaSize EnvDL +MediaSize EnvISOB5 +MediaSize Postcard +MediaSize DoublePostcard + +VariablePaperSize Yes +MinSize 1in 4in +MaxSize 8.5in 44in + +// Four color modes are supported... +ColorModel Gray/Grayscale w chunky 1 +ColorModel Black k chunky 1 +*ColorModel RGB/Color rgb chunky 1 +ColorModel CMYK cmyk chunky 1 + +// Supported resolutions +Resolution - 8 90 0 103 "360dpi/360 DPI" +*Resolution - 8 90 0 206 "720dpi/720 DPI" +Resolution - 8 90 0 412 "1440dpi/1440 DPI" + +// Very basic dithering settings +Attribute cupsInkChannels "" 6 +Attribute cupsInkLimit "" 2.0 + +Attribute cupsCyanLtDk "" "0.5 1.0" +Attribute cupsMagentaLtDk "" "0.5 1.0" + +Attribute cupsAllDither 360dpi "0.5 0.75 1.0" +Attribute cupsAllDither 720dpi "0.6 0.9 1.2" +Attribute cupsAllDither 1440dpi "0.9 1.35" + +Attribute cupsESCPDotSize 360dpi 16 +Attribute cupsESCPDotSize 720dpi 17 +Attribute cupsESCPDotSize 1440dpi 18 + +{ + // EPSON Stylus Photo R300 Series + Throughput 1 + ModelName "Stylus Photo R300" + PCFileName "epspr301.ppd" +} diff --git a/examples/r300-colorman.drv b/examples/r300-colorman.drv new file mode 100644 index 0000000000..ddaf58ec70 --- /dev/null +++ b/examples/r300-colorman.drv @@ -0,0 +1,85 @@ +// Include standard font and media definitions +#include +#include + +// Include ESC/P driver definitions +#include + +// Specify that this driver uses the ESC/P driver... +DriverType escp + +// Specify the driver options via the model number... +ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB + $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI $ESCP_REMOTE) + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and driver version +Manufacturer "Epson" +Version 3.0 + +// Supported page sizes and their margins +HWMargins 0 0 0 0 +*MediaSize Letter +MediaSize Legal +MediaSize Executive +MediaSize Statement +MediaSize A4 +MediaSize A5 +MediaSize A6 +MediaSize B5 +MediaSize Env10 +MediaSize EnvC5 +MediaSize EnvDL +MediaSize EnvISOB5 +MediaSize Postcard +MediaSize DoublePostcard + +VariablePaperSize Yes +MinSize 1in 4in +MaxSize 8.5in 44in + +// Borderless printing offset... +Attribute cupsESCPFP "" 0 + +// Four color modes are supported... +ColorModel Gray/Grayscale w chunky 1 +ColorModel Black k chunky 1 +*ColorModel RGB/Color rgb chunky 1 +ColorModel CMYK cmyk chunky 1 + +// Supported resolutions +Resolution - 8 90 0 103 "360dpi/360 DPI" +*Resolution - 8 90 0 206 "720dpi/720 DPI" +Resolution - 8 90 0 412 "1440dpi/1440 DPI" + +// Paper trays... +*InputSlot 0 "Auto/Auto Select" +InputSlot 1 "Manual/Manual Feed" + +Attribute cupsESCPPP 0 "1 255" +Attribute cupsESCPPP 1 "2 1" + +// Very basic dithering settings +Attribute cupsInkChannels "" 6 +Attribute cupsInkLimit "" 3.0 + +Attribute cupsCyanLtDk "" "0.5 1.0" +Attribute cupsMagentaLtDk "" "0.5 1.0" + +Attribute cupsAllDither 360dpi "0.5 0.75 1.0" +Attribute cupsAllDither 720dpi "0.6 0.9 1.2" +Attribute cupsAllDither 1440dpi "0.9 1.35" + +Attribute cupsESCPDotSize 360dpi 16 +Attribute cupsESCPDotSize 720dpi 17 +Attribute cupsESCPDotSize 1440dpi 18 + +{ + // EPSON Stylus Photo R300 Series + Throughput 1 + ModelName "Epson Stylus Photo R300" + PCFileName "epspr303.ppd" +} diff --git a/examples/r300-remote.drv b/examples/r300-remote.drv new file mode 100644 index 0000000000..c3065d00c1 --- /dev/null +++ b/examples/r300-remote.drv @@ -0,0 +1,85 @@ +// Include standard font and media definitions +#include +#include + +// Include ESC/P driver definitions +#include + +// Specify that this driver uses the ESC/P driver... +DriverType escp + +// Specify the driver options via the model number... +ModelNumber ($ESCP_ESCK $ESCP_EXT_UNITS $ESCP_EXT_MARGINS $ESCP_USB + $ESCP_PAGE_SIZE $ESCP_RASTER_ESCI $ESCP_REMOTE) + +// List the fonts that are supported, in this case all standard +// fonts... +Font * + +// Manufacturer and driver version +Manufacturer "Epson" +Version 2.0 + +// Supported page sizes and their margins +HWMargins 0 0 0 0 +*MediaSize Letter +MediaSize Legal +MediaSize Executive +MediaSize Statement +MediaSize A4 +MediaSize A5 +MediaSize A6 +MediaSize B5 +MediaSize Env10 +MediaSize EnvC5 +MediaSize EnvDL +MediaSize EnvISOB5 +MediaSize Postcard +MediaSize DoublePostcard + +VariablePaperSize Yes +MinSize 1in 4in +MaxSize 8.5in 44in + +// Borderless printing offset... +Attribute cupsESCPFP "" -80 + +// Four color modes are supported... +ColorModel Gray/Grayscale w chunky 1 +ColorModel Black k chunky 1 +*ColorModel RGB/Color rgb chunky 1 +ColorModel CMYK cmyk chunky 1 + +// Supported resolutions +Resolution - 8 90 0 103 "360dpi/360 DPI" +*Resolution - 8 90 0 206 "720dpi/720 DPI" +Resolution - 8 90 0 412 "1440dpi/1440 DPI" + +// Paper trays... +*InputSlot 0 "Auto/Auto Select" +InputSlot 1 "Manual/Manual Feed" + +Attribute cupsESCPPP 0 "1 255" +Attribute cupsESCPPP 1 "2 1" + +// Very basic dithering settings +Attribute cupsInkChannels "" 6 +Attribute cupsInkLimit "" 2.0 + +Attribute cupsCyanLtDk "" "0.5 1.0" +Attribute cupsMagentaLtDk "" "0.5 1.0" + +Attribute cupsAllDither 360dpi "0.5 0.75 1.0" +Attribute cupsAllDither 720dpi "0.6 0.9 1.2" +Attribute cupsAllDither 1440dpi "0.9 1.35" + +Attribute cupsESCPDotSize 360dpi 16 +Attribute cupsESCPDotSize 720dpi 17 +Attribute cupsESCPDotSize 1440dpi 18 + +{ + // EPSON Stylus Photo R300 Series + Throughput 1 + ModelName "Epson Stylus Photo R300" + PCFileName "epspr302.ppd" +} diff --git a/filter/Dependencies b/filter/Dependencies new file mode 100644 index 0000000000..a50962a1a1 --- /dev/null +++ b/filter/Dependencies @@ -0,0 +1,546 @@ +# DO NOT DELETE + +hpgl-attr.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-attr.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-attr.o: ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-attr.o: ../cups/string.h ../config.h +hpgl-config.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-config.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-config.o: ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-config.o: ../cups/language.h ../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/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-main.o: ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-main.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +hpgl-prolog.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-prolog.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-prolog.o: ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-prolog.o: ../cups/language.h ../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/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-char.o: ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-char.o: ../cups/string.h ../config.h +hpgl-input.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-input.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-input.o: ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-input.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +hpgl-polygon.o: hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-polygon.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-polygon.o: ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-polygon.o: ../cups/language.h ../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/versioning.h ../cups/ppd.h +hpgl-vector.o: ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-vector.o: ../cups/language.h ../cups/string.h ../config.h +image-bmp.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-bmp.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-bmp.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-bmp.o: ../cups/debug.h ../cups/string.h ../config.h +image-colorspace.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-colorspace.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h +image-colorspace.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +image-colorspace.o: ../cups/language.h ../cups/debug.h ../cups/string.h +image-colorspace.o: ../config.h +image-gif.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-gif.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-gif.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-gif.o: ../cups/debug.h ../cups/string.h ../config.h +image-jpeg.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-jpeg.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-jpeg.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-jpeg.o: ../cups/debug.h ../cups/string.h ../config.h +image-photocd.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-photocd.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h +image-photocd.o: ../cups/ppd.h ../cups/array.h ../cups/file.h +image-photocd.o: ../cups/language.h ../cups/debug.h ../cups/string.h +image-photocd.o: ../config.h +image-pix.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-pix.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-pix.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-pix.o: ../cups/debug.h ../cups/string.h ../config.h +image-png.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-png.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-png.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-png.o: ../cups/debug.h ../cups/string.h ../config.h +image-pnm.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-pnm.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-pnm.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-pnm.o: ../cups/debug.h ../cups/string.h ../config.h +image-sgi.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-sgi.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-sgi.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-sgi.o: ../cups/debug.h ../cups/string.h ../config.h image-sgi.h +image-sgilib.o: image-sgi.h +image-sun.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-sun.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-sun.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-sun.o: ../cups/debug.h ../cups/string.h ../config.h +image-tiff.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-tiff.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-tiff.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-tiff.o: ../cups/debug.h ../cups/string.h ../config.h +image-zoom.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image-zoom.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-zoom.o: ../cups/array.h ../cups/file.h ../cups/language.h +image-zoom.o: ../cups/debug.h ../cups/string.h ../config.h +image.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +image.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +image.o: ../cups/string.h ../config.h +error.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +error.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +error.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +error.o: ../cups/string.h ../config.h +interpret.o: ../cups/string.h ../config.h image-private.h image.h +interpret.o: ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +interpret.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +interpret.o: ../cups/file.h ../cups/language.h ../cups/debug.h +raster.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +raster.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +raster.o: ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +raster.o: ../cups/string.h ../config.h +form-main.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-main.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +form-main.o: ../cups/file.h ../cups/language.h ../cups/language.h +form-main.o: ../cups/string.h ../config.h +form-ps.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-ps.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +form-ps.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +form-tree.o: form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-tree.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +form-tree.o: ../cups/file.h ../cups/language.h ../cups/language.h +form-tree.o: ../cups/string.h ../config.h +bannertops.o: pstext.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +bannertops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +bannertops.o: ../cups/file.h ../cups/language.h ../cups/language.h +bannertops.o: ../cups/string.h ../config.h ../cups/transcode.h image.h +bannertops.o: ../cups/raster.h ../cups/i18n.h ../cups/transcode.h +commandtops.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +commandtops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +commandtops.o: ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +commandtops.o: ../cups/sidechannel.h +gziptoany.o: ../cups/file.h ../cups/versioning.h ../cups/string.h ../config.h +gziptoany.o: ../cups/i18n.h ../cups/transcode.h ../cups/language.h +gziptoany.o: ../cups/array.h +imagetops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +imagetops.o: ../cups/file.h ../cups/language.h ../cups/language.h +imagetops.o: ../cups/string.h ../config.h image.h ../cups/raster.h +imagetops.o: ../cups/i18n.h ../cups/transcode.h +imagetoraster.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetoraster.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +imagetoraster.o: ../cups/file.h ../cups/language.h ../cups/language.h +imagetoraster.o: ../cups/string.h ../config.h image-private.h image.h +imagetoraster.o: ../cups/raster.h ../cups/debug.h ../cups/i18n.h +imagetoraster.o: ../cups/transcode.h +common.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +common.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +common.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pdftops.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +pdftops.o: ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +pdftops.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +pstext.o: pstext.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pstext.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pstext.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pstext.o: ../cups/transcode.h ../cups/i18n.h ../cups/transcode.h +pstops.o: common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pstops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pstops.o: ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pstops.o: ../cups/file.h ../cups/array.h ../cups/i18n.h ../cups/transcode.h +rasterbench.o: ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rasterbench.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rasterbench.o: ../cups/file.h ../cups/language.h +rastertoepson.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertoepson.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertoepson.o: ../cups/file.h ../cups/language.h ../cups/ppd.h +rastertoepson.o: ../cups/string.h ../config.h ../cups/i18n.h +rastertoepson.o: ../cups/transcode.h ../cups/raster.h +rastertohp.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertohp.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertohp.o: ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +rastertohp.o: ../cups/i18n.h ../cups/transcode.h ../cups/raster.h +rastertolabel.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertolabel.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertolabel.o: ../cups/file.h ../cups/language.h ../cups/string.h +rastertolabel.o: ../config.h ../cups/i18n.h ../cups/transcode.h +rastertolabel.o: ../cups/raster.h +testimage.o: image.h ../cups/raster.h ../cups/cups.h ../cups/ipp.h +testimage.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testimage.o: ../cups/array.h ../cups/file.h ../cups/language.h +testraster.o: image-private.h image.h ../cups/raster.h ../cups/cups.h +testraster.o: ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testraster.o: ../cups/array.h ../cups/file.h ../cups/language.h +testraster.o: ../cups/debug.h ../cups/string.h ../config.h +textcommon.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h +textcommon.o: ../cups/http.h ../cups/versioning.h ../cups/ppd.h +textcommon.o: ../cups/array.h ../cups/file.h ../cups/language.h +textcommon.o: ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h +textcommon.o: ../cups/transcode.h +texttops.o: textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +texttops.o: ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +texttops.o: ../cups/language.h ../cups/language.h ../cups/string.h +texttops.o: ../config.h ../cups/i18n.h ../cups/transcode.h +# DO NOT DELETE + +hpgl-attr.32.o: hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-attr.32.o: hpgl-attr.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-attr.32.o: hpgl-attr.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-attr.32.o: hpgl-attr.c ../cups/string.h ../config.h +hpgl-config.32.o: hpgl-config.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-config.32.o: hpgl-config.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-config.32.o: hpgl-config.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-config.32.o: hpgl-config.c ../cups/language.h ../cups/string.h ../config.h +hpgl-main.32.o: hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-main.32.o: hpgl-main.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-main.32.o: hpgl-main.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-main.32.o: hpgl-main.c ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +hpgl-prolog.32.o: hpgl-prolog.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-prolog.32.o: hpgl-prolog.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-prolog.32.o: hpgl-prolog.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-prolog.32.o: hpgl-prolog.c ../cups/language.h ../cups/string.h ../config.h +hpgl-char.32.o: hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-char.32.o: hpgl-char.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-char.32.o: hpgl-char.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-char.32.o: hpgl-char.c ../cups/string.h ../config.h +hpgl-input.32.o: hpgl-input.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-input.32.o: hpgl-input.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-input.32.o: hpgl-input.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-input.32.o: hpgl-input.c ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +hpgl-polygon.32.o: hpgl-polygon.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-polygon.32.o: hpgl-polygon.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-polygon.32.o: hpgl-polygon.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-polygon.32.o: hpgl-polygon.c ../cups/language.h ../cups/string.h ../config.h +hpgl-vector.32.o: hpgl-vector.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-vector.32.o: hpgl-vector.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-vector.32.o: hpgl-vector.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-vector.32.o: hpgl-vector.c ../cups/language.h ../cups/string.h ../config.h +image-bmp.32.o: image-bmp.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-bmp.32.o: image-bmp.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-bmp.32.o: image-bmp.c ../cups/array.h ../cups/file.h ../cups/language.h +image-bmp.32.o: image-bmp.c ../cups/debug.h ../cups/string.h ../config.h +image-colorspace.32.o: image-colorspace.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-colorspace.32.o: image-colorspace.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h +image-colorspace.32.o: image-colorspace.c ../cups/ppd.h ../cups/array.h ../cups/file.h +image-colorspace.32.o: image-colorspace.c ../cups/language.h ../cups/debug.h ../cups/string.h +image-colorspace.32.o: image-colorspace.c ../config.h +image-gif.32.o: image-gif.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-gif.32.o: image-gif.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-gif.32.o: image-gif.c ../cups/array.h ../cups/file.h ../cups/language.h +image-gif.32.o: image-gif.c ../cups/debug.h ../cups/string.h ../config.h +image-jpeg.32.o: image-jpeg.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-jpeg.32.o: image-jpeg.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-jpeg.32.o: image-jpeg.c ../cups/array.h ../cups/file.h ../cups/language.h +image-jpeg.32.o: image-jpeg.c ../cups/debug.h ../cups/string.h ../config.h +image-photocd.32.o: image-photocd.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-photocd.32.o: image-photocd.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h +image-photocd.32.o: image-photocd.c ../cups/ppd.h ../cups/array.h ../cups/file.h +image-photocd.32.o: image-photocd.c ../cups/language.h ../cups/debug.h ../cups/string.h +image-photocd.32.o: image-photocd.c ../config.h +image-pix.32.o: image-pix.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-pix.32.o: image-pix.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-pix.32.o: image-pix.c ../cups/array.h ../cups/file.h ../cups/language.h +image-pix.32.o: image-pix.c ../cups/debug.h ../cups/string.h ../config.h +image-png.32.o: image-png.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-png.32.o: image-png.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-png.32.o: image-png.c ../cups/array.h ../cups/file.h ../cups/language.h +image-png.32.o: image-png.c ../cups/debug.h ../cups/string.h ../config.h +image-pnm.32.o: image-pnm.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-pnm.32.o: image-pnm.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-pnm.32.o: image-pnm.c ../cups/array.h ../cups/file.h ../cups/language.h +image-pnm.32.o: image-pnm.c ../cups/debug.h ../cups/string.h ../config.h +image-sgi.32.o: image-sgi.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-sgi.32.o: image-sgi.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-sgi.32.o: image-sgi.c ../cups/array.h ../cups/file.h ../cups/language.h +image-sgi.32.o: image-sgi.c ../cups/debug.h ../cups/string.h ../config.h image-sgi.h +image-sgilib.32.o: image-sgilib.c image-sgi.h +image-sun.32.o: image-sun.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-sun.32.o: image-sun.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-sun.32.o: image-sun.c ../cups/array.h ../cups/file.h ../cups/language.h +image-sun.32.o: image-sun.c ../cups/debug.h ../cups/string.h ../config.h +image-tiff.32.o: image-tiff.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-tiff.32.o: image-tiff.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-tiff.32.o: image-tiff.c ../cups/array.h ../cups/file.h ../cups/language.h +image-tiff.32.o: image-tiff.c ../cups/debug.h ../cups/string.h ../config.h +image-zoom.32.o: image-zoom.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-zoom.32.o: image-zoom.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-zoom.32.o: image-zoom.c ../cups/array.h ../cups/file.h ../cups/language.h +image-zoom.32.o: image-zoom.c ../cups/debug.h ../cups/string.h ../config.h +image.32.o: image.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image.32.o: image.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image.32.o: image.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +image.32.o: image.c ../cups/string.h ../config.h +error.32.o: error.c image-private.h image.h ../cups/raster.h ../cups/cups.h +error.32.o: error.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +error.32.o: error.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +error.32.o: error.c ../cups/string.h ../config.h +interpret.32.o: interpret.c ../cups/string.h ../config.h image-private.h image.h +interpret.32.o: interpret.c ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +interpret.32.o: interpret.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +interpret.32.o: interpret.c ../cups/file.h ../cups/language.h ../cups/debug.h +raster.32.o: raster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +raster.32.o: raster.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +raster.32.o: raster.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +raster.32.o: raster.c ../cups/string.h ../config.h +form-main.32.o: form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-main.32.o: form-main.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +form-main.32.o: form-main.c ../cups/file.h ../cups/language.h ../cups/language.h +form-main.32.o: form-main.c ../cups/string.h ../config.h +form-ps.32.o: form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-ps.32.o: form-ps.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +form-ps.32.o: form-ps.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +form-tree.32.o: form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-tree.32.o: form-tree.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +form-tree.32.o: form-tree.c ../cups/file.h ../cups/language.h ../cups/language.h +form-tree.32.o: form-tree.c ../cups/string.h ../config.h +bannertops.32.o: bannertops.c pstext.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +bannertops.32.o: bannertops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +bannertops.32.o: bannertops.c ../cups/file.h ../cups/language.h ../cups/language.h +bannertops.32.o: bannertops.c ../cups/string.h ../config.h ../cups/transcode.h image.h +bannertops.32.o: bannertops.c ../cups/raster.h ../cups/i18n.h ../cups/transcode.h +commandtops.32.o: commandtops.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +commandtops.32.o: commandtops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +commandtops.32.o: commandtops.c ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +commandtops.32.o: commandtops.c ../cups/sidechannel.h +gziptoany.32.o: gziptoany.c ../cups/file.h ../cups/versioning.h ../cups/string.h ../config.h +gziptoany.32.o: gziptoany.c ../cups/i18n.h ../cups/transcode.h ../cups/language.h +gziptoany.32.o: gziptoany.c ../cups/array.h +imagetops.32.o: imagetops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetops.32.o: imagetops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +imagetops.32.o: imagetops.c ../cups/file.h ../cups/language.h ../cups/language.h +imagetops.32.o: imagetops.c ../cups/string.h ../config.h image.h ../cups/raster.h +imagetops.32.o: imagetops.c ../cups/i18n.h ../cups/transcode.h +imagetoraster.32.o: imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetoraster.32.o: imagetoraster.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +imagetoraster.32.o: imagetoraster.c ../cups/file.h ../cups/language.h ../cups/language.h +imagetoraster.32.o: imagetoraster.c ../cups/string.h ../config.h image-private.h image.h +imagetoraster.32.o: imagetoraster.c ../cups/raster.h ../cups/debug.h ../cups/i18n.h +imagetoraster.32.o: imagetoraster.c ../cups/transcode.h +common.32.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +common.32.o: common.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +common.32.o: common.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pdftops.32.o: pdftops.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +pdftops.32.o: pdftops.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +pdftops.32.o: pdftops.c ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +pstext.32.o: pstext.c pstext.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pstext.32.o: pstext.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pstext.32.o: pstext.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pstext.32.o: pstext.c ../cups/transcode.h ../cups/i18n.h ../cups/transcode.h +pstops.32.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pstops.32.o: pstops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pstops.32.o: pstops.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pstops.32.o: pstops.c ../cups/file.h ../cups/array.h ../cups/i18n.h ../cups/transcode.h +rasterbench.32.o: rasterbench.c ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rasterbench.32.o: rasterbench.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rasterbench.32.o: rasterbench.c ../cups/file.h ../cups/language.h +rastertoepson.32.o: rastertoepson.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertoepson.32.o: rastertoepson.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertoepson.32.o: rastertoepson.c ../cups/file.h ../cups/language.h ../cups/ppd.h +rastertoepson.32.o: rastertoepson.c ../cups/string.h ../config.h ../cups/i18n.h +rastertoepson.32.o: rastertoepson.c ../cups/transcode.h ../cups/raster.h +rastertohp.32.o: rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertohp.32.o: rastertohp.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertohp.32.o: rastertohp.c ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +rastertohp.32.o: rastertohp.c ../cups/i18n.h ../cups/transcode.h ../cups/raster.h +rastertolabel.32.o: rastertolabel.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertolabel.32.o: rastertolabel.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertolabel.32.o: rastertolabel.c ../cups/file.h ../cups/language.h ../cups/string.h +rastertolabel.32.o: rastertolabel.c ../config.h ../cups/i18n.h ../cups/transcode.h +rastertolabel.32.o: rastertolabel.c ../cups/raster.h +testimage.32.o: testimage.c image.h ../cups/raster.h ../cups/cups.h ../cups/ipp.h +testimage.32.o: testimage.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testimage.32.o: testimage.c ../cups/array.h ../cups/file.h ../cups/language.h +testraster.32.o: testraster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +testraster.32.o: testraster.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testraster.32.o: testraster.c ../cups/array.h ../cups/file.h ../cups/language.h +testraster.32.o: testraster.c ../cups/debug.h ../cups/string.h ../config.h +textcommon.32.o: textcommon.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h +textcommon.32.o: textcommon.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +textcommon.32.o: textcommon.c ../cups/array.h ../cups/file.h ../cups/language.h +textcommon.32.o: textcommon.c ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h +textcommon.32.o: textcommon.c ../cups/transcode.h +texttops.32.o: texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +texttops.32.o: texttops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +texttops.32.o: texttops.c ../cups/language.h ../cups/language.h ../cups/string.h +texttops.32.o: texttops.c ../config.h ../cups/i18n.h ../cups/transcode.h +# DO NOT DELETE + +hpgl-attr.64.o: hpgl-attr.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-attr.64.o: hpgl-attr.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-attr.64.o: hpgl-attr.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-attr.64.o: hpgl-attr.c ../cups/string.h ../config.h +hpgl-config.64.o: hpgl-config.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-config.64.o: hpgl-config.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-config.64.o: hpgl-config.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-config.64.o: hpgl-config.c ../cups/language.h ../cups/string.h ../config.h +hpgl-main.64.o: hpgl-main.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-main.64.o: hpgl-main.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-main.64.o: hpgl-main.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-main.64.o: hpgl-main.c ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +hpgl-prolog.64.o: hpgl-prolog.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-prolog.64.o: hpgl-prolog.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-prolog.64.o: hpgl-prolog.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-prolog.64.o: hpgl-prolog.c ../cups/language.h ../cups/string.h ../config.h +hpgl-char.64.o: hpgl-char.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-char.64.o: hpgl-char.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-char.64.o: hpgl-char.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-char.64.o: hpgl-char.c ../cups/string.h ../config.h +hpgl-input.64.o: hpgl-input.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +hpgl-input.64.o: hpgl-input.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +hpgl-input.64.o: hpgl-input.c ../cups/file.h ../cups/language.h ../cups/language.h +hpgl-input.64.o: hpgl-input.c ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +hpgl-polygon.64.o: hpgl-polygon.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-polygon.64.o: hpgl-polygon.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-polygon.64.o: hpgl-polygon.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-polygon.64.o: hpgl-polygon.c ../cups/language.h ../cups/string.h ../config.h +hpgl-vector.64.o: hpgl-vector.c hpgltops.h common.h ../cups/cups.h ../cups/ipp.h +hpgl-vector.64.o: hpgl-vector.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +hpgl-vector.64.o: hpgl-vector.c ../cups/array.h ../cups/file.h ../cups/language.h +hpgl-vector.64.o: hpgl-vector.c ../cups/language.h ../cups/string.h ../config.h +image-bmp.64.o: image-bmp.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-bmp.64.o: image-bmp.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-bmp.64.o: image-bmp.c ../cups/array.h ../cups/file.h ../cups/language.h +image-bmp.64.o: image-bmp.c ../cups/debug.h ../cups/string.h ../config.h +image-colorspace.64.o: image-colorspace.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-colorspace.64.o: image-colorspace.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h +image-colorspace.64.o: image-colorspace.c ../cups/ppd.h ../cups/array.h ../cups/file.h +image-colorspace.64.o: image-colorspace.c ../cups/language.h ../cups/debug.h ../cups/string.h +image-colorspace.64.o: image-colorspace.c ../config.h +image-gif.64.o: image-gif.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-gif.64.o: image-gif.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-gif.64.o: image-gif.c ../cups/array.h ../cups/file.h ../cups/language.h +image-gif.64.o: image-gif.c ../cups/debug.h ../cups/string.h ../config.h +image-jpeg.64.o: image-jpeg.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-jpeg.64.o: image-jpeg.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-jpeg.64.o: image-jpeg.c ../cups/array.h ../cups/file.h ../cups/language.h +image-jpeg.64.o: image-jpeg.c ../cups/debug.h ../cups/string.h ../config.h +image-photocd.64.o: image-photocd.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-photocd.64.o: image-photocd.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h +image-photocd.64.o: image-photocd.c ../cups/ppd.h ../cups/array.h ../cups/file.h +image-photocd.64.o: image-photocd.c ../cups/language.h ../cups/debug.h ../cups/string.h +image-photocd.64.o: image-photocd.c ../config.h +image-pix.64.o: image-pix.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-pix.64.o: image-pix.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-pix.64.o: image-pix.c ../cups/array.h ../cups/file.h ../cups/language.h +image-pix.64.o: image-pix.c ../cups/debug.h ../cups/string.h ../config.h +image-png.64.o: image-png.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-png.64.o: image-png.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-png.64.o: image-png.c ../cups/array.h ../cups/file.h ../cups/language.h +image-png.64.o: image-png.c ../cups/debug.h ../cups/string.h ../config.h +image-pnm.64.o: image-pnm.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-pnm.64.o: image-pnm.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-pnm.64.o: image-pnm.c ../cups/array.h ../cups/file.h ../cups/language.h +image-pnm.64.o: image-pnm.c ../cups/debug.h ../cups/string.h ../config.h +image-sgi.64.o: image-sgi.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-sgi.64.o: image-sgi.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-sgi.64.o: image-sgi.c ../cups/array.h ../cups/file.h ../cups/language.h +image-sgi.64.o: image-sgi.c ../cups/debug.h ../cups/string.h ../config.h image-sgi.h +image-sgilib.64.o: image-sgilib.c image-sgi.h +image-sun.64.o: image-sun.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-sun.64.o: image-sun.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-sun.64.o: image-sun.c ../cups/array.h ../cups/file.h ../cups/language.h +image-sun.64.o: image-sun.c ../cups/debug.h ../cups/string.h ../config.h +image-tiff.64.o: image-tiff.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-tiff.64.o: image-tiff.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-tiff.64.o: image-tiff.c ../cups/array.h ../cups/file.h ../cups/language.h +image-tiff.64.o: image-tiff.c ../cups/debug.h ../cups/string.h ../config.h +image-zoom.64.o: image-zoom.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image-zoom.64.o: image-zoom.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image-zoom.64.o: image-zoom.c ../cups/array.h ../cups/file.h ../cups/language.h +image-zoom.64.o: image-zoom.c ../cups/debug.h ../cups/string.h ../config.h +image.64.o: image.c image-private.h image.h ../cups/raster.h ../cups/cups.h +image.64.o: image.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +image.64.o: image.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +image.64.o: image.c ../cups/string.h ../config.h +error.64.o: error.c image-private.h image.h ../cups/raster.h ../cups/cups.h +error.64.o: error.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +error.64.o: error.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +error.64.o: error.c ../cups/string.h ../config.h +interpret.64.o: interpret.c ../cups/string.h ../config.h image-private.h image.h +interpret.64.o: interpret.c ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +interpret.64.o: interpret.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +interpret.64.o: interpret.c ../cups/file.h ../cups/language.h ../cups/debug.h +raster.64.o: raster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +raster.64.o: raster.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +raster.64.o: raster.c ../cups/array.h ../cups/file.h ../cups/language.h ../cups/debug.h +raster.64.o: raster.c ../cups/string.h ../config.h +form-main.64.o: form-main.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-main.64.o: form-main.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +form-main.64.o: form-main.c ../cups/file.h ../cups/language.h ../cups/language.h +form-main.64.o: form-main.c ../cups/string.h ../config.h +form-ps.64.o: form-ps.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-ps.64.o: form-ps.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +form-ps.64.o: form-ps.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +form-tree.64.o: form-tree.c form.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +form-tree.64.o: form-tree.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +form-tree.64.o: form-tree.c ../cups/file.h ../cups/language.h ../cups/language.h +form-tree.64.o: form-tree.c ../cups/string.h ../config.h +bannertops.64.o: bannertops.c pstext.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +bannertops.64.o: bannertops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +bannertops.64.o: bannertops.c ../cups/file.h ../cups/language.h ../cups/language.h +bannertops.64.o: bannertops.c ../cups/string.h ../config.h ../cups/transcode.h image.h +bannertops.64.o: bannertops.c ../cups/raster.h ../cups/i18n.h ../cups/transcode.h +commandtops.64.o: commandtops.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +commandtops.64.o: commandtops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +commandtops.64.o: commandtops.c ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +commandtops.64.o: commandtops.c ../cups/sidechannel.h +gziptoany.64.o: gziptoany.c ../cups/file.h ../cups/versioning.h ../cups/string.h ../config.h +gziptoany.64.o: gziptoany.c ../cups/i18n.h ../cups/transcode.h ../cups/language.h +gziptoany.64.o: gziptoany.c ../cups/array.h +imagetops.64.o: imagetops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetops.64.o: imagetops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +imagetops.64.o: imagetops.c ../cups/file.h ../cups/language.h ../cups/language.h +imagetops.64.o: imagetops.c ../cups/string.h ../config.h image.h ../cups/raster.h +imagetops.64.o: imagetops.c ../cups/i18n.h ../cups/transcode.h +imagetoraster.64.o: imagetoraster.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +imagetoraster.64.o: imagetoraster.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +imagetoraster.64.o: imagetoraster.c ../cups/file.h ../cups/language.h ../cups/language.h +imagetoraster.64.o: imagetoraster.c ../cups/string.h ../config.h image-private.h image.h +imagetoraster.64.o: imagetoraster.c ../cups/raster.h ../cups/debug.h ../cups/i18n.h +imagetoraster.64.o: imagetoraster.c ../cups/transcode.h +common.64.o: common.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +common.64.o: common.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +common.64.o: common.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pdftops.64.o: pdftops.c ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/versioning.h +pdftops.64.o: pdftops.c ../cups/ppd.h ../cups/array.h ../cups/file.h ../cups/language.h +pdftops.64.o: pdftops.c ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +pstext.64.o: pstext.c pstext.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pstext.64.o: pstext.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pstext.64.o: pstext.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pstext.64.o: pstext.c ../cups/transcode.h ../cups/i18n.h ../cups/transcode.h +pstops.64.o: pstops.c common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +pstops.64.o: pstops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +pstops.64.o: pstops.c ../cups/language.h ../cups/language.h ../cups/string.h ../config.h +pstops.64.o: pstops.c ../cups/file.h ../cups/array.h ../cups/i18n.h ../cups/transcode.h +rasterbench.64.o: rasterbench.c ../cups/raster.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +rasterbench.64.o: rasterbench.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rasterbench.64.o: rasterbench.c ../cups/file.h ../cups/language.h +rastertoepson.64.o: rastertoepson.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertoepson.64.o: rastertoepson.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertoepson.64.o: rastertoepson.c ../cups/file.h ../cups/language.h ../cups/ppd.h +rastertoepson.64.o: rastertoepson.c ../cups/string.h ../config.h ../cups/i18n.h +rastertoepson.64.o: rastertoepson.c ../cups/transcode.h ../cups/raster.h +rastertohp.64.o: rastertohp.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertohp.64.o: rastertohp.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertohp.64.o: rastertohp.c ../cups/file.h ../cups/language.h ../cups/string.h ../config.h +rastertohp.64.o: rastertohp.c ../cups/i18n.h ../cups/transcode.h ../cups/raster.h +rastertolabel.64.o: rastertolabel.c ../cups/cups.h ../cups/ipp.h ../cups/http.h +rastertolabel.64.o: rastertolabel.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h +rastertolabel.64.o: rastertolabel.c ../cups/file.h ../cups/language.h ../cups/string.h +rastertolabel.64.o: rastertolabel.c ../config.h ../cups/i18n.h ../cups/transcode.h +rastertolabel.64.o: rastertolabel.c ../cups/raster.h +testimage.64.o: testimage.c image.h ../cups/raster.h ../cups/cups.h ../cups/ipp.h +testimage.64.o: testimage.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testimage.64.o: testimage.c ../cups/array.h ../cups/file.h ../cups/language.h +testraster.64.o: testraster.c image-private.h image.h ../cups/raster.h ../cups/cups.h +testraster.64.o: testraster.c ../cups/ipp.h ../cups/http.h ../cups/versioning.h ../cups/ppd.h +testraster.64.o: testraster.c ../cups/array.h ../cups/file.h ../cups/language.h +testraster.64.o: testraster.c ../cups/debug.h ../cups/string.h ../config.h +textcommon.64.o: textcommon.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h +textcommon.64.o: textcommon.c ../cups/http.h ../cups/versioning.h ../cups/ppd.h +textcommon.64.o: textcommon.c ../cups/array.h ../cups/file.h ../cups/language.h +textcommon.64.o: textcommon.c ../cups/language.h ../cups/string.h ../config.h ../cups/i18n.h +textcommon.64.o: textcommon.c ../cups/transcode.h +texttops.64.o: texttops.c textcommon.h common.h ../cups/cups.h ../cups/ipp.h ../cups/http.h +texttops.64.o: texttops.c ../cups/versioning.h ../cups/ppd.h ../cups/array.h ../cups/file.h +texttops.64.o: texttops.c ../cups/language.h ../cups/language.h ../cups/string.h +texttops.64.o: texttops.c ../config.h ../cups/i18n.h ../cups/transcode.h diff --git a/filter/Makefile b/filter/Makefile new file mode 100644 index 0000000000..9d3bd8f43d --- /dev/null +++ b/filter/Makefile @@ -0,0 +1,528 @@ +# +# "$Id$" +# +# Filter makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2010 by Apple Inc. +# Copyright 1997-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +# This file is subject to the Apple OS-Developed Software exception. +# + +include ../Makedefs + + +FILTERS = \ + $(BANNERTOPS) \ + commandtops \ + gziptoany \ + hpgltops \ + $(TEXTTOPS) \ + pstops \ + $(IMGFILTERS) \ + $(PDFTOPS) \ + rastertolabel \ + rastertoepson \ + rastertohp +LIBTARGETS = \ + $(LIBCUPSIMAGE) \ + libcupsimage.a \ + $(LIB32CUPSIMAGE) \ + $(LIB64CUPSIMAGE) +UNITTARGETS = \ + rasterbench \ + testimage \ + testraster +TARGETS = \ + $(LIBTARGETS) \ + $(FILTERS) + +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 error.o interpret.o raster.o +IMAGE32OBJS = $(IMAGEOBJS:.o=.32.o) +IMAGE64OBJS = $(IMAGEOBJS:.o=.64.o) +FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o +OBJS = $(HPGLOBJS) $(IMAGEOBJS) $(FORMOBJS) \ + bannertops.o commandtops.o gziptoany.o imagetops.o \ + imagetoraster.o common.o pdftops.o pstext.o pstops.o \ + rasterbench.o rastertoepson.o rastertohp.o rastertolabel.o \ + testimage.o testraster.o textcommon.o texttops.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: $(LIBTARGETS) + + +# +# Make unit tests... +# + +unittests: $(UNITTARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) $(UNITTARGETS) + $(RM) libcupsimage.so libcupsimage.sl libcupsimage.dylib + $(RM) -r 32bit 64bit + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + touch Dependencies.tmp + makedepend -Y -I.. -fDependencies.tmp $(OBJS:.o=.c) >/dev/null 2>&1 + $(RM) Dependencies + cp Dependencies.tmp Dependencies + sed -E -e '1,$$s/^([^.]+)\.o:/\1\.32.o: \1\.c /' Dependencies.tmp >>Dependencies + sed -E -e '1,$$s/^([^.]+)\.o:/\1\.64.o: \1\.c /' Dependencies.tmp >>Dependencies + $(RM) Dependencies.tmp + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + + +# +# Install programs... +# + +install-exec: + $(INSTALL_DIR) -m 755 $(SERVERBIN)/filter + for file in $(FILTERS); do \ + $(INSTALL_BIN) $$file $(SERVERBIN)/filter; \ + done + $(RM) $(SERVERBIN)/filter/rastertodymo + $(LN) rastertolabel $(SERVERBIN)/filter/rastertodymo + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + for file in $(FILTERS); do \ + cp $$file $(SYMROOT); \ + done \ + fi + + +# +# Install headers... +# + +install-headers: + $(INSTALL_DIR) -m 755 $(INCLUDEDIR)/cups + $(INSTALL_DATA) image.h $(INCLUDEDIR)/cups + + +# +# Install libraries... +# + +install-libs: $(INSTALLSTATIC) $(INSTALL32) $(INSTALL64) + $(INSTALL_DIR) -m 755 $(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 \ + $(RM) $(LIBDIR)/libcupsimage.dylib; \ + $(LN) $(LIBCUPSIMAGE) $(LIBDIR)/libcupsimage.dylib; \ + fi + if test "x$(SYMROOT)" != "x"; then \ + $(INSTALL_DIR) $(SYMROOT); \ + cp $(LIBCUPSIMAGE) $(SYMROOT); \ + fi + +installstatic: + $(INSTALL_DIR) -m 755 $(LIBDIR) + $(INSTALL_LIB) -m 755 libcupsimage.a $(LIBDIR) + $(RANLIB) $(LIBDIR)/libcupsimage.a + $(CHMOD) 555 $(LIBDIR)/libcupsimage.a + +install32bit: + $(INSTALL_DIR) -m 755 $(LIB32DIR) + $(INSTALL_LIB) 32bit/libcupsimage.so.2 $(LIB32DIR)/libcupsimage.so.2 + $(LN) libcupsimage.so.2 $(LIB32DIR)/libcupsimage.so + +install64bit: + $(INSTALL_DIR) -m 755 $(LIB64DIR) + $(INSTALL_LIB) 64bit/libcupsimage.so.2 $(LIB64DIR)/libcupsimage.so.2 + $(LN) libcupsimage.so.2 $(LIB64DIR)/libcupsimage.so + + +# +# Uninstall all targets... +# + +uninstall: $(UNINSTALL32) $(UNINSTALL64) + for file in $(FILTERS); do \ + $(RM) $(SERVERBIN)/filter/$$file; \ + done + $(RM) $(SERVERBIN)/filter/rastertodymo + -$(RMDIR) $(SERVERBIN)/filter + -$(RMDIR) $(SERVERBIN) + $(RM) $(LIBDIR)/libcupsimage.2.dylib + $(RM) $(LIBDIR)/libcupsimage.a + $(RM) $(LIBDIR)/libcupsimage.dylib + $(RM) $(LIBDIR)/libcupsimage_s.a + $(RM) $(LIBDIR)/libcupsimage.sl + $(RM) $(LIBDIR)/libcupsimage.sl.2 + $(RM) $(LIBDIR)/libcupsimage.so + $(RM) $(LIBDIR)/libcupsimage.so.2 + -$(RMDIR) $(LIBDIR) + $(RM) $(INCLUDEDIR)/cups/image.h + -$(RMDIR) $(INCLUDEDIR)/cups + +uninstall32bit: + $(RM) $(LIB32DIR)/libcupsimage.so + $(RM) $(LIB32DIR)/libcupsimage.so.2 + -$(RMDIR) $(LIB32DIR) + +uninstall64bit: + $(RM) $(LIB64DIR)/libcupsimage.so + $(RM) $(LIB64DIR)/libcupsimage.so.2 + -$(RMDIR) $(LIB64DIR) + + +# +# Automatic API help files... +# + +apihelp: + echo Generating CUPS API help files... + mxmldoc --section "Programming" --title "Raster API" \ + --css ../doc/cups-printable.css \ + --header api-raster.header --intro api-raster.shtml \ + api-raster.xml \ + ../cups/raster.h interpret.c raster.c \ + >../doc/help/api-raster.html + mxmldoc --tokens help/api-raster.html api-raster.xml >../doc/help/api-raster.tokens + $(RM) api-raster.xml + mxmldoc --section "Programming" \ + --title "Developing PostScript Printer Drivers" \ + --css ../doc/cups-printable.css \ + --header postscript-driver.header \ + --intro postscript-driver.shtml \ + >../doc/help/postscript-driver.html + mxmldoc --section "Programming" \ + --title "Introduction to the PPD Compiler" \ + --css ../doc/cups-printable.css \ + --header ppd-compiler.header \ + --intro ppd-compiler.shtml \ + >../doc/help/ppd-compiler.html + mxmldoc --section "Programming" \ + --title "Developing Raster Printer Drivers" \ + --css ../doc/cups-printable.css \ + --header raster-driver.header \ + --intro raster-driver.shtml \ + >../doc/help/raster-driver.html + +framedhelp: + echo Generating CUPS API help files... + mxmldoc --section "Programming" --title "Raster API" \ + --framed ../cups/api-raster \ + --css ../doc/cups-printable.css \ + --header api-raster.header --intro api-raster.shtml \ + ../cups/raster.h interpret.c raster.c + mxmldoc --section "Programming" \ + --title "Developing PostScript Printer Drivers" \ + --framed ../cups/postscript-driver \ + --css ../doc/cups-printable.css \ + --header postscript-driver.header \ + --intro postscript-driver.shtml + mxmldoc --section "Programming" \ + --title "Introduction to the PPD Compiler" \ + --framed ../cups/ppd-compiler \ + --css ../doc/cups-printable.css \ + --header ppd-compiler.header \ + --intro ppd-compiler.shtml + mxmldoc --section "Programming" \ + --title "Developing Raster Printer Drivers" \ + --framed ../cups/raster-driver \ + --css ../doc/cups-printable.css \ + --header raster-driver.header \ + --intro raster-driver.shtml + + +# +# bannertops +# + +bannertops: bannertops.o pstext.o common.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ bannertops.o pstext.o common.o $(LINKCUPSIMAGE) \ + $(IMGLIBS) $(LIBS) + + +# +# commandtops +# + +commandtops: commandtops.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ commandtops.o $(LIBS) + + +# +# formtops +# + +formtops: $(FORMOBJS) common.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ $(FORMOBJS) common.o $(LIBS) -lm + + +# +# gziptoany +# + +gziptoany: gziptoany.o ../Makedefs ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ gziptoany.o $(LIBZ) $(LIBS) + + +# +# hpgltops +# + +hpgltops: $(HPGLOBJS) common.o ../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) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS) $(DSOLIBS) \ + -L../cups $(LINKCUPS) -lm + $(RM) `basename $@ .2` + $(LN) $@ `basename $@ .2` + + +# +# 32bit/libcupsimage.so.2 +# + +32bit/libcupsimage.so.2: $(IMAGE32OBJS) + echo Linking 32-bit $@... + -mkdir 32bit + $(DSO) $(ARCH32FLAGS) $(DSO32FLAGS) -o $@ $(IMAGE32OBJS) $(DSOLIBS) \ + -L../cups/32bit $(LINKCUPS) -lm + + +# +# 64bit/libcupsimage.so.2 +# + +64bit/libcupsimage.so.2: $(IMAGE64OBJS) + echo Linking 64-bit $@... + -mkdir 64bit + $(DSO) $(ARCH64FLAGS) $(DSO64FLAGS) -o $@ $(IMAGE64OBJS) $(DSOLIBS) \ + -L../cups/64bit $(LINKCUPS) -lm + + +# +# libcupsimage.2.dylib +# + +libcupsimage.2.dylib: $(IMAGEOBJS) $(LIBCUPSIMAGEORDER) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ \ + -install_name $(libdir)/$@ \ + -current_version 2.3.0 \ + -compatibility_version 2.0.0 \ + -sectorder __TEXT __text $(LIBCUPSIMAGEORDER) \ + $(IMAGEOBJS) $(DSOLIBS) -L../cups $(LINKCUPS) -lm + $(RM) libcupsimage.dylib + $(LN) $@ libcupsimage.dylib + + +# +# libcupsimage_s.a +# + +libcupsimage_s.a: $(IMAGEOBJS) libcupsimage_s.exp + echo Linking $@... + $(DSO) $(DSOFLAGS) -Wl,-berok,-bexport:libcupsimage_s.exp \ + -o libcupsimage_s.o $(IMAGEOBJS) $(DSOLIBS) -lm + $(RM) $@ + $(AR) $(ARFLAGS) $@ libcupsimage_s.o + + +# +# libcupsimage.la +# + +libcupsimage.la: $(IMAGEOBJS) + echo Linking $@... + $(DSO) $(ARCHFLAGS) $(DSOFLAGS) -o $@ $(IMAGEOBJS:.o=.lo) $(DSOLIBS) \ + -L../cups $(LINKCUPS) \ + -rpath $(LIBDIR) -version-info 2:3 + + +# +# libcupsimage.a +# + +libcupsimage.a: $(IMAGEOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(IMAGEOBJS) + $(RANLIB) $@ + + +# +# testimage +# + +testimage: testimage.o libcupsimage.a ../Makedefs + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testimage.o libcupsimage.a \ + $(IMGLIBS) $(DSOLIBS) $(LIBS) + + +# +# imagetops +# + +imagetops: imagetops.o common.o $(LIBCUPSIMAGE) \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ imagetops.o common.o $(LINKCUPSIMAGE) \ + $(IMGLIBS) $(LIBS) + + +# +# imagetoraster +# + +imagetoraster: imagetoraster.o common.o $(LIBCUPSIMAGE) \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ imagetoraster.o common.o $(LINKCUPSIMAGE) \ + $(IMGLIBS) $(LIBS) + + +# +# pstops +# + +pstops: pstops.o common.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS) -lm + + +# +# pdftops +# + +pdftops: pdftops.o common.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ pdftops.o common.o $(LIBS) + + +# +# rastertolabel +# + +rastertolabel: rastertolabel.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertolabel.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + + +# +# rastertoepson +# + +rastertoepson: rastertoepson.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertoepson.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + + +# +# rastertohp +# + +rastertohp: rastertohp.o ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) + + +# +# testraster +# + +testraster: testraster.o ../cups/libcups.a libcupsimage.a + echo Linking $@... + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ testraster.o libcupsimage.a \ + ../cups/libcups.a $(IMGLIBS) $(DSOLIBS) $(COMMONLIBS) \ + $(SSLLIBS) $(DNSSDLIBS) $(LIBGSSAPI) + echo Running raster API tests... + ./testraster + + +# +# rasterbench +# + +rasterbench: rasterbench.o libcupsimage.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rasterbench.o libcupsimage.a $(LIBS) + + +# +# texttops +# + +texttops: texttops.o textcommon.o common.o \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ texttops.o textcommon.o common.o $(LIBS) + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/filter/api-raster.header b/filter/api-raster.header new file mode 100644 index 0000000000..8e26fbf3e0 --- /dev/null +++ b/filter/api-raster.header @@ -0,0 +1,37 @@ + + +

Raster API

+ +
+ + + + + + + + + + + + + + + + +
Headercups/raster.h
Library-lcupsimage
See AlsoProgramming: Introduction to CUPS Programming
+ Programming: CUPS API
+ Programming: PPD API
+ References: CUPS PPD Specification
diff --git a/filter/api-raster.shtml b/filter/api-raster.shtml new file mode 100644 index 0000000000..a309022eae --- /dev/null +++ b/filter/api-raster.shtml @@ -0,0 +1,160 @@ + + +
+ +

The CUPS raster API provides a standard interface for reading and writing +CUPS raster streams which are used for printing to raster printers. Because the +raster format is updated from time to time, it is important to use this API to +avoid incompatibilities with newer versions of CUPS.

+ +

Two kinds of CUPS filters use the CUPS raster API - raster image processor +(RIP) filters such as pstoraster and cgpdftoraster +(Mac OS X) that produce CUPS raster files and printer driver filters that +convert CUPS raster files into a format usable by the printer. Printer +driver filters are by far the most common.

+ +

CUPS raster files (application/vnd.cups-raster) consists of +a stream of raster page descriptions produced by one of the RIP filters such as +pstoraster, imagetoraster, or +cgpdftoraster. CUPS raster files are referred to using the +cups_raster_t type and are +opened using the cupsRasterOpen +function. For example, to read raster data from the standard input, open +file descriptor 0:

+ +
+#include <cups/raster.h>>
+
+cups_raster_t *ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+
+ +

Each page of data begins with a page dictionary structure called +cups_page_header2_t. This +structure contains the colorspace, bits per color, media size, media type, +hardware resolution, and so forth used for the page.

+ +
Note: + +

Do not confuse the colorspace in the page header with the PPD + ColorModel keyword. ColorModel refers to the general type of + color used for a device (Gray, RGB, CMYK, DeviceN) and is often used to + select a particular colorspace for the page header along with the associate + color profile. The page header colorspace (cupsColorSpace) describes + both the type and organization of the color data, for example KCMY (black + first) instead of CMYK and RGBA (RGB + alpha) instead of RGB.

+ +
+ +

You read the page header using the +cupsRasterReadHeader2 +function:

+ +
+#include <cups/raster.h>>
+
+cups_raster_t *ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+cups_page_header2_t header;
+
+while (cupsRasterReadHeader2(ras, &header))
+{
+  /* setup this page */
+
+  /* read raster data */
+
+  /* finish this page */
+}
+
+ +

After the page dictionary comes the page data which is a full-resolution, +possibly compressed bitmap representing the page in the printer's output +colorspace. You read uncompressed raster data using the +cupsRasterReadPixels +function. A for loop is normally used to read the page one line +at a time:

+ +
+#include <cups/raster.h>>
+
+cups_raster_t *ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+cups_page_header2_t header;
+int page = 0;
+int y;
+char *buffer;
+
+while (cupsRasterReadHeader2(ras, &header))
+{
+  /* setup this page */
+  page ++;
+  fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies);
+
+  /* allocate memory for 1 line */
+  buffer = malloc(header.cupsBytesPerLine);
+
+  /* read raster data */
+  for (y = 0; y < header.cupsHeight; y ++)
+  {
+    if (cupsRasterReadPixels(ras, buffer, header.cupsBytesPerLine) == 0)
+      break;
+
+    /* write raster data to printer on stdout */
+  }
+
+  /* finish this page */
+}
+
+ +

When you are done reading the raster data, call the +cupsRasterClose function to free +the memory used to read the raster file:

+ +
+cups_raster_t *ras;
+
+cupsRasterClose(ras);
+
+ + +

Functions by Task

+ +

Opening and Closing Raster Streams

+ + + +

Reading Raster Streams

+ + + +

Writing Raster Streams

+ + diff --git a/filter/bannertops.c b/filter/bannertops.c new file mode 100644 index 0000000000..e18c07e09c --- /dev/null +++ b/filter/bannertops.c @@ -0,0 +1,1092 @@ +/* + * "$Id$" + * + * Banner to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2008 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Generate PostScript cover pages. + * load_banner() - Load the banner file. + * ps_ascii85() - Print binary data as a series of base-85 numbers. + * write_banner() - Write a banner page... + * write_epilogue() - Write the PostScript file epilogue. + * write_prolog() - Write the PostScript file prolog with options. + */ + +/* + * Include necessary headers... + */ + +#include "pstext.h" +#include "image.h" +#include + + +/* + * Constants... + */ + +#define SHOW_IMAGEABLE_AREA 1 /* Show imageable area */ +#define SHOW_JOB_BILLING 2 /* Show billing string */ +#define SHOW_JOB_ID 4 /* Show job ID */ +#define SHOW_JOB_NAME 8 /* Show job title */ +#define SHOW_JOB_ORIGINATING_USER_NAME 16 /* Show owner of job */ +#define SHOW_JOB_ORIGINATING_HOST_NAME 32 /* Show submitting system */ +#define SHOW_JOB_UUID 64 /* Show job UUID */ +#define SHOW_OPTIONS 128 /* Show print options */ +#define SHOW_PAPER_NAME 256 /* Show paper size name */ +#define SHOW_PAPER_SIZE 512 /* Show paper dimensions */ +#define SHOW_PRINTER_DRIVER_NAME 1024 /* Show printer driver name */ +#define SHOW_PRINTER_DRIVER_VERSION 2048 /* Show printer driver version */ +#define SHOW_PRINTER_INFO 4096 /* Show printer description */ +#define SHOW_PRINTER_LOCATION 8192 /* Show printer location */ +#define SHOW_PRINTER_MAKE_AND_MODEL 16384 /* Show printer make and model */ +#define SHOW_PRINTER_NAME 32768 /* Show printer queue ID */ +#define SHOW_TIME_AT_CREATION 65536 /* Show date/time when submitted */ +#define SHOW_TIME_AT_PROCESSING 131072 /* Show date/time when printed */ + + +/* + * Structures... + */ + +typedef struct banner_file_s /**** Banner file data ****/ +{ + int show; /* What to show */ + char *header, /* Header text */ + *footer; /* Footer text */ + cups_array_t *notices, /* Notices to show */ + *images; /* Images to show */ +} banner_file_t; + + +/* + * Local functions... + */ + +static banner_file_t *load_banner(const char *filename); +static int write_banner(banner_file_t *banner, ppd_file_t *ppd, + ps_text_t *fonts, int job_id, + const char *title, const char *username, + int num_options, cups_option_t *options); +static void write_epilogue(int num_pages); +static ps_text_t *write_prolog(const char *title, const char *user); + + +/* + * 'main()' - Generate PostScript cover pages. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + banner_file_t *banner; /* Banner file data */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + ppd_file_t *ppd; /* PPD file */ + ps_text_t *fonts; /* Fonts for output */ + int job_id; /* Job ID from command-line */ + const char *title, /* Title from command-line */ + *username; /* Username from command-line */ + int num_pages; /* Number of pages printed */ + + + /* + * Make sure status messages are not buffered... + */ + + setbuf(stderr, NULL); + + /* + * Check command-line... + */ + + if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + "bannertops"); + return (1); + } + + /* + * Get stuff from command-line... + */ + + job_id = atoi(argv[1]); + username = argv[2]; + title = argv[3]; + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + banner = load_banner(argv[6]); + + /* + * Set standard options and get the PPD file for this printer... + */ + + ppd = SetCommonOptions(num_options, options, 1); + + /* + * Write a PostScript banner document and return... + */ + + fonts = write_prolog(title, username); + num_pages = write_banner(banner, ppd, fonts, job_id, title, username, + num_options, options); + + write_epilogue(num_pages); + + return (0); +} + + +/* + * 'load_banner()' - Load the banner file. + */ + +static banner_file_t * /* O - Banner file data */ +load_banner(const char *filename) /* I - Filename or NULL for stdin */ +{ + cups_file_t *fp; /* File */ + char line[2048], /* Line buffer */ + *ptr; /* Pointer into line */ + int linenum; /* Current line number */ + banner_file_t *banner; /* Banner file data */ + const char *cups_docroot; /* CUPS_DOCROOT environment variable */ + + + fprintf(stderr, "DEBUG: load_banner(filename=\"%s\")\n", + filename ? filename : "(stdin)"); + + /* + * Open the banner file... + */ + + if (filename) + fp = cupsFileOpen(filename, "r"); + else + fp = cupsFileStdin(); + + if (!fp) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to open banner file \"%s\" - %s\n"), + filename ? filename : "(stdin)", strerror(errno)); + exit(1); + } + + /* + * Read the banner file... + */ + + if ((cups_docroot = getenv("CUPS_DOCROOT")) == NULL) + cups_docroot = CUPS_DOCROOT; + + banner = calloc(1, sizeof(banner_file_t)); + linenum = 0; + + while (cupsFileGets(fp, line, sizeof(line))) + { + /* + * Skip blank and comment lines... + */ + + linenum ++; + + if (line[0] == '#' || !line[0]) + continue; + + /* + * Break the line into keyword and value parts... + */ + + for (ptr = line; *ptr && !isspace(*ptr & 255); ptr ++); + + while (isspace(*ptr & 255)) + *ptr++ = '\0'; + + if (!*ptr) + { + _cupsLangPrintf(stderr, + _("ERROR: Missing value on line %d of banner file!\n"), + linenum); + continue; + } + + /* + * Save keyword values in the appropriate places... + */ + + if (!strcasecmp(line, "Footer")) + { + if (banner->footer) + fprintf(stderr, "DEBUG: Extra \"Footer\" on line %d of banner file!\n", + linenum); + else + banner->footer = strdup(ptr); + } + else if (!strcasecmp(line, "Header")) + { + if (banner->header) + fprintf(stderr, "DEBUG: Extra \"Header\" on line %d of banner file!\n", + linenum); + else + banner->header = strdup(ptr); + } + else if (!strcasecmp(line, "Image")) + { + char imagefile[1024]; /* Image filename */ + + + if (ptr[0] == '/') + strlcpy(imagefile, ptr, sizeof(imagefile)); + else + snprintf(imagefile, sizeof(imagefile), "%s/%s", cups_docroot, ptr); + + if (access(imagefile, R_OK)) + { + fprintf(stderr, "DEBUG: Image \"%s\" on line %d of banner file: %s\n", + ptr, linenum, strerror(errno)); + } + else + { + if (!banner->images) + banner->images = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(banner->images, strdup(imagefile)); + } + } + else if (!strcasecmp(line, "Notice")) + { + if (!banner->notices) + banner->notices = cupsArrayNew(NULL, NULL); + + cupsArrayAdd(banner->notices, strdup(ptr)); + } + else if (!strcasecmp(line, "Show")) + { + char *value; /* Current value */ + + + for (value = ptr; *value; value = ptr) + { + /* + * Find the end of the current value + */ + + while (*ptr && !isspace(*ptr & 255)) + ptr ++; + + while (*ptr && isspace(*ptr & 255)) + *ptr++ = '\0'; + + /* + * Add the value to the show flags... + */ + if (!strcasecmp(value, "imageable-area")) + banner->show |= SHOW_IMAGEABLE_AREA; + else if (!strcasecmp(value, "job-billing")) + banner->show |= SHOW_JOB_BILLING; + else if (!strcasecmp(value, "job-id")) + banner->show |= SHOW_JOB_ID; + else if (!strcasecmp(value, "job-name")) + banner->show |= SHOW_JOB_NAME; + else if (!strcasecmp(value, "job-originating-host-name")) + banner->show |= SHOW_JOB_ORIGINATING_HOST_NAME; + else if (!strcasecmp(value, "job-originating-user-name")) + banner->show |= SHOW_JOB_ORIGINATING_USER_NAME; + else if (!strcasecmp(value, "job-uuid")) + banner->show |= SHOW_JOB_UUID; + else if (!strcasecmp(value, "options")) + banner->show |= SHOW_OPTIONS; + else if (!strcasecmp(value, "paper-name")) + banner->show |= SHOW_PAPER_NAME; + else if (!strcasecmp(value, "paper-size")) + banner->show |= SHOW_PAPER_SIZE; + else if (!strcasecmp(value, "printer-driver-name")) + banner->show |= SHOW_PRINTER_DRIVER_NAME; + else if (!strcasecmp(value, "printer-driver-version")) + banner->show |= SHOW_PRINTER_DRIVER_VERSION; + else if (!strcasecmp(value, "printer-info")) + banner->show |= SHOW_PRINTER_INFO; + else if (!strcasecmp(value, "printer-location")) + banner->show |= SHOW_PRINTER_LOCATION; + else if (!strcasecmp(value, "printer-make-and-model")) + banner->show |= SHOW_PRINTER_MAKE_AND_MODEL; + else if (!strcasecmp(value, "printer-name")) + banner->show |= SHOW_PRINTER_NAME; + else if (!strcasecmp(value, "time-at-creation")) + banner->show |= SHOW_TIME_AT_CREATION; + else if (!strcasecmp(value, "time-at-processing")) + banner->show |= SHOW_TIME_AT_PROCESSING; + else + { + fprintf(stderr, + "DEBUG: Unknown \"Show\" value \"%s\" on line %d of banner " + "file!\n", value, linenum); + } + } + } + else + fprintf(stderr, "DEBUG: Unknown key \"%s\" on line %d of banner file!\n", + line, linenum); + } + + if (filename) + cupsFileClose(fp); + + return (banner); +} + + +/* + * 'ps_ascii85()' - Print binary data as a series of base-85 numbers. + */ + +static void +ps_ascii85(cups_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; + } +} + + +/* + * 'write_banner()' - Write a banner page... + */ + +static int /* O - Number of pages */ +write_banner(banner_file_t *banner, /* I - Banner file */ + ppd_file_t *ppd, /* I - PPD file */ + ps_text_t *fonts, /* I - Fonts */ + int job_id, /* I - Job ID */ + const char *title, /* I - Title of job */ + const char *username, /* I - Owner of job */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + char *notice; /* Current notice */ + char *imagefile; /* Current image file */ + cups_array_t *images; /* Images */ + cups_image_t *image; /* Current image */ + const char *option; /* Option value */ + int i, j; /* Looping vars */ + float x, /* Current X position */ + y; /* Current Y position */ + cups_lang_t *language; /* Default language */ + int showlines; /* Number of lines to show */ + float fontsize; /* Font size to use */ + int num_pages; /* Number of pages */ + float print_width, /* Printable width of page */ + print_height, /* Printable height of page */ + info_top, /* Top of info fields */ + info_height, /* Height of info fields */ + line_height, /* Height of info lines */ + notices_height, /* Height of all notices */ + images_width, /* Width of all images */ + images_height, /* Height of all images */ + total_height; /* Height of all content */ + char text[1024]; /* Formatted field text */ + + + /* + * Figure out how many lines of text will be shown... + */ + + showlines = 0; + if (banner->show & SHOW_IMAGEABLE_AREA) + showlines += 2; + if (banner->show & SHOW_JOB_BILLING) + showlines ++; + if (banner->show & SHOW_JOB_ID) + showlines ++; + if (banner->show & SHOW_JOB_NAME) + showlines ++; + if (banner->show & SHOW_JOB_ORIGINATING_USER_NAME) + showlines ++; + if (banner->show & SHOW_JOB_ORIGINATING_HOST_NAME) + showlines ++; + if (banner->show & SHOW_JOB_UUID) + showlines ++; + if (banner->show & SHOW_OPTIONS) + { + for (j = 0; j < num_options; j ++) + { + if (strcasecmp("media", options[j].name) && + strcasecmp("PageSize", options[j].name) && + strcasecmp("PageRegion", options[j].name) && + strcasecmp("InputSlot", options[j].name) && + strcasecmp("MediaType", options[j].name) && + strcasecmp("finishings", options[j].name) && + strcasecmp("sides", options[j].name) && + strcasecmp("Duplex", options[j].name) && + strcasecmp("orientation-requested", options[j].name) && + strcasecmp("landscape", options[j].name) && + strcasecmp("number-up", options[j].name) && + strcasecmp("OutputOrder", options[j].name)) + continue; + + showlines ++; + } + } + if (banner->show & SHOW_PAPER_NAME) + showlines ++; + if (banner->show & SHOW_PAPER_SIZE) + showlines += 2; + if (banner->show & SHOW_PRINTER_DRIVER_NAME) + showlines ++; + if (banner->show & SHOW_PRINTER_DRIVER_VERSION) + showlines ++; + if (banner->show & SHOW_PRINTER_INFO) + showlines ++; + if (banner->show & SHOW_PRINTER_LOCATION) + showlines ++; + if (banner->show & SHOW_PRINTER_MAKE_AND_MODEL) + showlines ++; + if (banner->show & SHOW_PRINTER_NAME) + showlines ++; + if (banner->show & SHOW_TIME_AT_CREATION) + showlines ++; + if (banner->show & SHOW_TIME_AT_PROCESSING) + showlines ++; + + /* + * Figure out the dimensions and positions of everything... + */ + + print_width = PageRight - PageLeft; + print_height = PageTop - PageBottom; + fontsize = print_height / 60; /* Nominally 12pts */ + line_height = 1.2 * fontsize; + info_height = showlines * line_height; + notices_height = cupsArrayCount(banner->notices) * line_height; + + if (cupsArrayCount(banner->images)) + { + images = cupsArrayNew(NULL, NULL); + images_height = print_height / 10; /* Nominally 1" */ + + for (imagefile = (char *)cupsArrayFirst(banner->images), images_width = 0.0; + imagefile; + imagefile = (char *)cupsArrayNext(banner->images)) + { + if ((image = cupsImageOpen(imagefile, ColorDevice ? CUPS_IMAGE_RGB_CMYK : + CUPS_IMAGE_WHITE, + CUPS_IMAGE_WHITE, 100, 0, NULL)) == NULL) + { + fprintf(stderr, "DEBUG: Unable to open image file \"%s\"!\n", + imagefile); + continue; + } + + images_width += cupsImageGetWidth(image) * images_height / + cupsImageGetHeight(image); + cupsArrayAdd(images, image); + } + } + else + { + images = NULL; + images_height = 0; + images_width = 0; + } + + total_height = info_height + notices_height + images_height; + if (cupsArrayCount(banner->notices) && showlines) + total_height += 2 * line_height; + if (cupsArrayCount(banner->images) && + (showlines || cupsArrayCount(banner->notices))) + total_height += 2 * line_height; + + info_top = 0.5 * (print_height + total_height); + + /* + * Write the page(s)... + */ + + language = cupsLangDefault(); + num_pages = Duplex ? 2 : 1; + + for (i = 1; i <= num_pages; i ++) + { + /* + * Start the page... + */ + + printf("%%%%Page: %s %d\n", i == 1 ? "coverpage" : "coverback", i); + puts("gsave"); + if (i == 1) + printf("%.1f %.1f translate\n", PageLeft, PageBottom); + else + printf("%.1f %.1f translate\n", PageWidth - PageRight, + PageLength - PageTop); + puts("0 setgray"); + + y = info_top; + + /* + * Information... + */ + + if (banner->show) + { + x = 0.33 * print_width; + + if (banner->show & SHOW_PRINTER_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printer Name: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, getenv("PRINTER")); + } + if (banner->show & SHOW_JOB_ID) + { + snprintf(text, sizeof(text), "%s-%d", getenv("PRINTER"), job_id); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Job ID: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + if (banner->show & SHOW_JOB_UUID) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Job UUID: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + cupsGetOption("job-uuid", num_options, options)); + } + if (banner->show & SHOW_JOB_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Title: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, title); + } + if (banner->show & SHOW_JOB_ORIGINATING_USER_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printed For: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, username); + } + if (banner->show & SHOW_JOB_ORIGINATING_HOST_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printed From: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + cupsGetOption("job-originating-host-name", num_options, + options)); + } + if (banner->show & SHOW_JOB_BILLING) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Billing Information: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + cupsGetOption("job-billing", num_options, options)); + } + if (banner->show & SHOW_OPTIONS) + { + printf("%.1f %.1f moveto", x, y); + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Options: "))); + + for (j = 0; j < num_options; j ++) + { + if (strcasecmp("media", options[j].name) && + strcasecmp("PageSize", options[j].name) && + strcasecmp("PageRegion", options[j].name) && + strcasecmp("InputSlot", options[j].name) && + strcasecmp("MediaType", options[j].name) && + strcasecmp("finishings", options[j].name) && + strcasecmp("sides", options[j].name) && + strcasecmp("Duplex", options[j].name) && + strcasecmp("orientation-requested", options[j].name) && + strcasecmp("landscape", options[j].name) && + strcasecmp("number-up", options[j].name) && + strcasecmp("OutputOrder", options[j].name)) + continue; + + if (!strcasecmp("landscape", options[j].name)) + strlcpy(text, "orientation-requested=landscape", sizeof(text)); + else if (!strcasecmp("orientation-requested", options[j].name)) + { + switch (atoi(options[j].value)) + { + default : + case IPP_PORTRAIT : + strlcpy(text, "orientation-requested=portrait", + sizeof(text)); + break; + + case IPP_LANDSCAPE : + strlcpy(text, "orientation-requested=landscape", + sizeof(text)); + break; + + case IPP_REVERSE_PORTRAIT : + strlcpy(text, "orientation-requested=reverse-portrait", + sizeof(text)); + break; + + case IPP_REVERSE_LANDSCAPE : + strlcpy(text, "orientation-requested=reverse-landscape", + sizeof(text)); + break; + } + } + else + snprintf(text, sizeof(text), "%s=%s", options[j].name, + options[j].value); + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + } + + if (banner->show & SHOW_PRINTER_INFO) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Description: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + getenv("PRINTER_INFO")); + } + if (banner->show & SHOW_PRINTER_LOCATION) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Location: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + getenv("PRINTER_LOCATION")); + } + if (banner->show & SHOW_PRINTER_MAKE_AND_MODEL) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Make and Model: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + ppd ? ppd->nickname : NULL); + } + + if (banner->show & SHOW_PAPER_NAME) + { + if ((option = cupsGetOption("media", num_options, options)) == NULL) + if ((option = cupsGetOption("PageSize", num_options, options)) == NULL) + if ((option = cupsGetOption("PageRegion", num_options, + options)) == NULL) + option = "Default"; + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Media Name: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, option); + } + if (banner->show & SHOW_PAPER_SIZE) + { + snprintf(text, sizeof(text), + _cupsLangString(language, _("%.2f x %.2f inches")), + PageWidth / 72.0, PageLength / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Media Dimensions: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + + snprintf(text, sizeof(text), + _cupsLangString(language, _("%.0f x %.0f millimeters")), + PageWidth * 25.4 / 72.0, PageLength * 25.4 / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + if (banner->show & SHOW_IMAGEABLE_AREA) + { + snprintf(text, sizeof(text), + _cupsLangString(language, + _("%.2f x %.2f to %.2f x %.2f inches")), + PageLeft / 72.0, PageBottom / 72.0, + PageRight / 72.0, PageTop / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Media Limits: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + + snprintf(text, sizeof(text), + _cupsLangString(language, + _("%.0f x %.0f to %.0f x %.0f millimeters")), + PageLeft * 25.4 / 72.0, PageBottom * 25.4 / 72.0, + PageRight * 25.4 / 72.0, PageTop * 25.4 / 72.0); + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + + printf("gsave 2 setlinewidth 1 1 %.1f %.1f rectstroke grestore\n", + print_width - 2.0, print_height - 2.0); + } + if (banner->show & SHOW_PRINTER_DRIVER_NAME) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Driver Name: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + ppd ? ppd->pcfilename : NULL); + } + if (banner->show & SHOW_PRINTER_DRIVER_VERSION) + { + ppd_attr_t *file_version = ppdFindAttr(ppd, "FileVersion", NULL); + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Driver Version: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, + file_version ? file_version->value : NULL); + } + if (banner->show & SHOW_TIME_AT_CREATION) + { + if ((option = cupsGetOption("time-at-creation", num_options, + options)) != NULL) + { + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + + curtime = (time_t)atoi(option); + curdate = localtime(&curtime); + + strftime(text, sizeof(text), "%c", curdate); + } + else + strlcpy(text, "?", sizeof(text)); + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Created On: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + if (banner->show & SHOW_TIME_AT_PROCESSING) + { + if ((option = cupsGetOption("time-at-processing", num_options, + options)) != NULL) + { + time_t curtime; /* Current time */ + struct tm *curdate; /* Current date */ + + curtime = (time_t)atoi(option); + curdate = localtime(&curtime); + + strftime(text, sizeof(text), "%c", curdate); + } + else + strlcpy(text, "?", sizeof(text)); + + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_BOLD, PS_RIGHT, + _cupsLangString(language, _("Printed On: "))); + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_LEFT, text); + } + } + + /* + * Notices... + */ + + if (cupsArrayCount(banner->notices)) + { + if (banner->show) + y -= 2 * line_height; + + x = 0.5 * print_width; + + for (notice = (char *)cupsArrayFirst(banner->notices); + notice; + notice = (char *)cupsArrayNext(banner->notices)) + { + printf("%.1f %.1f moveto", x, y); + y -= line_height; + psTextUTF8(fonts, fontsize, PS_NORMAL, PS_CENTER, notice); + } + } + + /* + * Images... + */ + + if (cupsArrayCount(images)) + { + if (banner->show || cupsArrayCount(banner->notices)) + y -= 2 * line_height; + + x = 0.5 * (print_width - images_width); + + for (image = (cups_image_t *)cupsArrayFirst(images); + image; + image = (cups_image_t *)cupsArrayNext(images)) + { + float temp_width; /* Width of this image */ + int depth, /* Bytes per pixel */ + num_cols, /* Number of columns */ + row, /* Current row */ + num_rows, /* Number of rows */ + out_length, /* Length of data to write */ + out_offset; /* Offset in line buffer */ + unsigned char *line; /* Data for current row */ + + + depth = cupsImageGetDepth(image); + num_cols = cupsImageGetWidth(image); + num_rows = cupsImageGetHeight(image); + line = malloc(depth * num_cols + 3); + temp_width = num_cols * images_height / num_rows; + + printf("gsave %.1f %.1f translate %.3f %.3f scale\n", x, y, + temp_width / num_cols, images_height / num_rows); + x += temp_width; + + switch (cupsImageGetColorSpace(image)) + { + default : + case CUPS_IMAGE_WHITE : + printf("/DeviceGray setcolorspace" + "<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8" + "/Decode[0 1]\n", + num_cols, num_rows); + break; + + case CUPS_IMAGE_RGB : + printf("/DeviceRGB setcolorspace" + "<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8" + "/Decode[0 1 0 1 0 1]\n", + num_cols, num_rows); + break; + + case CUPS_IMAGE_CMYK : + printf("/DeviceCMYK setcolorspace" + "<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8" + "/Decode[0 1 0 1 0 1 0 1]\n", + num_cols, num_rows); + break; + } + + puts("/DataSource currentfile" + "/ASCII85Decode filter" + "/ImageMatrix[1 0 0 -1 0 1]>>image"); + + for (row = 0, out_offset = 0; row < num_rows; row ++) + { + cupsImageGetRow(image, 0, row, num_cols, line + out_offset); + + out_length = num_cols * depth + out_offset; + out_offset = out_length & 3; + + ps_ascii85(line, out_length, row == (num_rows - 1)); + + if (out_offset > 0) + memcpy(line, line + out_length - out_offset, out_offset); + } + + puts("grestore"); + + if (i == num_pages) + cupsImageClose(image); + } + } + + /* + * Header and footer... + */ + + x = 0.5 * print_width; + + if (banner->header) + { + printf("%.1f %.1f moveto", x, print_height - 2 * fontsize); + psTextUTF8(fonts, 2 * fontsize, PS_BOLD, PS_CENTER, banner->header); + } + + if (banner->footer) + { + printf("%.1f %.1f moveto", x, fontsize); + psTextUTF8(fonts, 2 * fontsize, PS_BOLD, PS_CENTER, banner->footer); + } + + /* + * Show the page... + */ + + puts("grestore"); + puts("showpage"); + } + + return (num_pages); +} + + +/* + * 'write_epilogue()' - Write the PostScript file epilogue. + */ + +static void +write_epilogue(int num_pages) /* I - Number of pages */ +{ + puts("%%Trailer"); + printf("%%%%Pages: %d\n", num_pages); + puts("%%EOF"); +} + + +/* + * 'write_prolog()' - Write the PostScript file prolog with options. + */ + +ps_text_t * /* O - Fonts */ +write_prolog(const char *title, /* I - Title of job */ + const char *username) /* I - Username */ +{ + time_t curtime; /* Current time */ + struct tm *curtm; /* Current date */ + char curdate[255]; /* Current date (text format) */ + ps_text_t *fonts; /* Fonts */ + + + /* + * Get the fonts we'll need... + */ + + fonts = psTextInitialize(); + + /* + * Output the DSC header... + */ + + curtime = time(NULL); + curtm = localtime(&curtime); + strftime(curdate, sizeof(curdate), "%c", 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: bannertops/" CUPS_SVERSION); + printf("%%%%CreationDate: %s\n", curdate); + puts("%%LanguageLevel: 2"); + puts("%%DocumentData: Clean7Bit"); + WriteTextComment("Title", title); + WriteTextComment("For", username); + printf("%%%%Pages: %d\n", Duplex ? 2 : 1); + psTextListFonts(fonts); + puts("%%EndComments"); + puts("%%BeginProlog"); + psTextEmbedFonts(fonts); + puts("%%EndProlog"); + + return (fonts); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/commandtops.c b/filter/commandtops.c new file mode 100644 index 0000000000..945409fe08 --- /dev/null +++ b/filter/commandtops.c @@ -0,0 +1,356 @@ +/* + * "$Id$" + * + * PostScript command filter for CUPS. + * + * Copyright 2008-2011 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * + * Contents: + * + * main() - Process a CUPS command file. + * auto_configure() - Automatically configure the printer using + * PostScript query commands and/or SNMP lookups. + * begin_ps() - Send the standard PostScript prolog. + * end_ps() - Send the standard PostScript trailer. + * print_self_test_page() - Print a self-test page. + * report_levels() - Report supply levels. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + + +/* + * Local functions... + */ + +static void auto_configure(ppd_file_t *ppd, const char *user); +static void begin_ps(ppd_file_t *ppd, const char *user); +static void end_ps(ppd_file_t *ppd); +static void print_self_test_page(ppd_file_t *ppd, const char *user); +static void report_levels(ppd_file_t *ppd, const char *user); + + +/* + * 'main()' - Process a CUPS command file. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_file_t *fp; /* Command file */ + char line[1024], /* Line from file */ + *value; /* Value on line */ + int linenum; /* Line number in file */ + ppd_file_t *ppd; /* PPD file */ + + + /* + * Check for valid arguments... + */ + + if (argc < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + fputs("ERROR: commandtops job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * Open the PPD file... + */ + + if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL) + { + fputs("ERROR: Unable to open PPD file!\n", stderr); + return (1); + } + + /* + * Open the command file as needed... + */ + + if (argc == 7) + { + if ((fp = cupsFileOpen(argv[6], "r")) == NULL) + { + perror("ERROR: Unable to open command file - "); + return (1); + } + } + else + fp = cupsFileStdin(); + + /* + * Read the commands from the file and send the appropriate commands... + */ + + linenum = 0; + + while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) + { + /* + * Parse the command... + */ + + if (!strcasecmp(line, "AutoConfigure")) + auto_configure(ppd, argv[2]); + else if (!strcasecmp(line, "PrintSelfTestPage")) + print_self_test_page(ppd, argv[2]); + else if (!strcasecmp(line, "ReportLevels")) + report_levels(ppd, argv[2]); + else + fprintf(stderr, "ERROR: Invalid printer command \"%s\"!\n", line); + } + + return (0); +} + + +/* + * 'auto_configure()' - Automatically configure the printer using PostScript + * query commands and/or SNMP lookups. + */ + +static void +auto_configure(ppd_file_t *ppd, /* I - PPD file */ + const char *user) /* I - Printing user */ +{ + ppd_option_t *option; /* Current option in PPD */ + ppd_attr_t *attr; /* Query command attribute */ + char buffer[1024], /* String buffer */ + *bufptr; /* Pointer into buffer */ + ssize_t bytes; /* Number of bytes read */ + int datalen; /* Side-channel data length */ + + + /* + * See if the backend supports bidirectional I/O... + */ + + datalen = 1; + if (cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer, &datalen, + 30.0) != CUPS_SC_STATUS_OK || + buffer[0] != CUPS_SC_BIDI_SUPPORTED) + { + fputs("DEBUG: Unable to auto-configure PostScript Printer - no " + "bidirectional I/O available!\n", stderr); + return; + } + + /* + * Put the printer in PostScript mode... + */ + + begin_ps(ppd, user); + + /* + * Then loop through every option in the PPD file and ask for the current + * value... + */ + + fputs("DEBUG: Auto-configuring PostScript printer...\n", stderr); + + for (option = ppdFirstOption(ppd); option; option = ppdNextOption(ppd)) + { + /* + * See if we have a query command for this option... + */ + + snprintf(buffer, sizeof(buffer), "?%s", option->keyword); + + if ((attr = ppdFindAttr(ppd, buffer, NULL)) == NULL || !attr->value) + { + fprintf(stderr, "DEBUG: Skipping %s option...\n", option->keyword); + continue; + } + + /* + * Send the query code to the printer... + */ + + fprintf(stderr, "DEBUG: Querying %s...\n", option->keyword); + fputs(attr->value, stdout); + fflush(stdout); + + datalen = 0; + cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer, &datalen, 5.0); + + /* + * Read the response data... + */ + + while ((bytes = cupsBackChannelRead(buffer, sizeof(buffer) - 1, 90.0)) > 0) + { + /* + * Trim whitespace from both ends... + */ + + buffer[bytes] = '\0'; + + for (bufptr = buffer + bytes - 1; bufptr >= buffer; bufptr --) + if (isspace(*bufptr & 255)) + *bufptr = '\0'; + else + break; + + for (bufptr = buffer; isspace(*bufptr & 255); bufptr ++); + + fprintf(stderr, "DEBUG: Got \"%s\" (%d bytes)\n", bufptr, (int)bytes); + + /* + * Skip blank lines... + */ + + if (!*bufptr) + continue; + + /* + * Verify the result is a valid option choice... + */ + + if (!ppdFindChoice(option, bufptr)) + continue; + + /* + * Write out the result and move on to the next option... + */ + + fprintf(stderr, "DEBUG: Default%s=%s\n", option->keyword, bufptr); + fprintf(stderr, "PPD: Default%s=%s\n", option->keyword, bufptr); + break; + } + } + + /* + * Finish the job... + */ + + end_ps(ppd); +} + + +/* + * 'begin_ps()' - Send the standard PostScript prolog. + */ + +static void +begin_ps(ppd_file_t *ppd, /* I - PPD file */ + const char *user) /* I - Username */ +{ + (void)user; + + if (ppd->jcl_begin) + { + fputs(ppd->jcl_begin, stdout); + fputs(ppd->jcl_ps, stdout); + } + + puts("%!"); + puts("userdict dup(\\004)cvn{}put (\\004\\004)cvn{}put\n"); + fflush(stdout); +} + + +/* + * 'end_ps()' - Send the standard PostScript trailer. + */ + +static void +end_ps(ppd_file_t *ppd) /* I - PPD file */ +{ + if (ppd->jcl_end) + fputs(ppd->jcl_end, stdout); + else + putchar(0x04); + + fflush(stdout); +} + + +/* + * 'print_self_test_page()' - Print a self-test page. + */ + +static void +print_self_test_page(ppd_file_t *ppd, /* I - PPD file */ + const char *user) /* I - Printing user */ +{ + /* + * Put the printer in PostScript mode... + */ + + begin_ps(ppd, user); + + /* + * Send a simple file the draws a box around the imageable area and shows + * the product/interpreter information... + */ + + puts("% You are using the wrong driver for your printer!\n" + "0 setgray\n" + "2 setlinewidth\n" + "initclip newpath clippath gsave stroke grestore pathbbox\n" + "exch pop exch pop exch 9 add exch 9 sub moveto\n" + "/Courier findfont 12 scalefont setfont\n" + "0 -12 rmoveto gsave product show grestore\n" + "0 -12 rmoveto gsave version show ( ) show revision 20 string cvs show " + "grestore\n" + "0 -12 rmoveto gsave serialnumber 20 string cvs show grestore\n" + "showpage"); + + /* + * Finish the job... + */ + + end_ps(ppd); +} + + +/* + * 'report_levels()' - Report supply levels. + */ + +static void +report_levels(ppd_file_t *ppd, /* I - PPD file */ + const char *user) /* I - Printing user */ +{ + /* + * Put the printer in PostScript mode... + */ + + begin_ps(ppd, user); + + /* + * Don't bother sending any additional PostScript commands, since we just + * want the backend to have enough time to collect the supply info. + */ + + /* + * Finish the job... + */ + + end_ps(ppd); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/common.c b/filter/common.c new file mode 100644 index 0000000000..452cc45229 --- /dev/null +++ b/filter/common.c @@ -0,0 +1,535 @@ +/* + * "$Id$" + * + * Common filter routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * WriteComment() - Write a DSC comment. + * 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" +#include + + +/* + * 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 */ + + +#ifdef LC_TIME + setlocale(LC_TIME, ""); +#endif /* LC_TIME */ + + 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) + { + if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 && + strcasecmp(val, "false") != 0) + { + if (ppd && ppd->landscape > 0) + Orientation = 1; + else + Orientation = 3; + } + } + else 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 (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"); + 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"); +} + + +/* + * '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 */ + const char *ptr; /* Temporary string pointer */ + + + /* + * 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("); + + for (ptr = classification; *ptr; ptr ++) + if (*ptr < 32 || *ptr > 126) + printf("\\%03o", *ptr); + else if (*ptr == '_') + putchar(' '); + else + { + if (*ptr == '(' || *ptr == ')' || *ptr == '\\') + putchar('\\'); + + putchar(*ptr); + } + } + + if (label) + { + if (classification[0]) + printf(" - "); + + /* + * Quote the label string as needed... + */ + + for (ptr = label; *ptr; ptr ++) + if (*ptr < 32 || *ptr > 126) + printf("\\%03o", *ptr); + else + { + if (*ptr == '(' || *ptr == ')' || *ptr == '\\') + putchar('\\'); + + putchar(*ptr); + } + } + + 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"); +} + + +/* + * 'WriteTextComment()' - Write a DSC text comment. + */ + +void +WriteTextComment(const char *name, /* I - Comment name ("Title", etc.) */ + const char *value) /* I - Comment value */ +{ + int len; /* Current line length */ + + + /* + * DSC comments are of the form: + * + * %%name: value + * + * The name and value must be limited to 7-bit ASCII for most printers, + * so we escape all non-ASCII and ASCII control characters as described + * in the Adobe Document Structuring Conventions specification. + */ + + printf("%%%%%s: (", name); + len = 5 + strlen(name); + + while (*value) + { + if (*value < ' ' || *value >= 127) + { + /* + * Escape this character value... + */ + + if (len >= 251) /* Keep line < 254 chars */ + break; + + printf("\\%03o", *value & 255); + len += 4; + } + else if (*value == '\\') + { + /* + * Escape the backslash... + */ + + if (len >= 253) /* Keep line < 254 chars */ + break; + + putchar('\\'); + putchar('\\'); + len += 2; + } + else + { + /* + * Put this character literally... + */ + + if (len >= 254) /* Keep line < 254 chars */ + break; + + putchar(*value); + len ++; + } + + value ++; + } + + puts(")"); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/common.h b/filter/common.h new file mode 100644 index 0000000000..303d1dad6b --- /dev/null +++ b/filter/common.h @@ -0,0 +1,84 @@ +/* + * "$Id$" + * + * Common filter definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * 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); +extern void WriteTextComment(const char *name, const char *value); + + +/* + * C++ magic... + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +/* + * End of "$Id$". + */ diff --git a/filter/error.c b/filter/error.c new file mode 100644 index 0000000000..de2c7834fb --- /dev/null +++ b/filter/error.c @@ -0,0 +1,287 @@ +/* + * "$Id$" + * + * Raster error handling for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsRasterAddError() - Add an error message to the error buffer. + * _cupsRasterClearError() - Clear the error buffer. + * cupsRasterErrorString() - Return the last error from a raster function. + * get_error_buffer() - Return a pointer to thread local storage. + * raster_init() - Initialize error buffer once. + * raster_destructor() - Free memory allocated by get_error_buffer(). + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" +#include + + +/* + * Local structures... + */ + +typedef struct _cups_raster_error_s /**** Error buffer structure ****/ +{ + char *start, /* Start of buffer */ + *current, /* Current position in buffer */ + *end; /* End of buffer */ +} _cups_raster_error_t; + + +/* + * Local functions... + */ + +static _cups_raster_error_t *get_error_buffer(void); + + +/* + * '_cupsRasterAddError()' - Add an error message to the error buffer. + */ + +void +_cupsRasterAddError(const char *f, /* I - Printf-style error message */ + ...) /* I - Additional arguments as needed */ +{ + _cups_raster_error_t *buf = get_error_buffer(); + /* Error buffer */ + va_list ap; /* Pointer to additional arguments */ + char s[2048]; /* Message string */ + size_t bytes; /* Bytes in message string */ + + + va_start(ap, f); + bytes = vsnprintf(s, sizeof(s), f, ap); + va_end(ap); + + if (bytes <= 0) + return; + + bytes ++; + + if (bytes >= sizeof(s)) + return; + + if (bytes > (buf->end - buf->current)) + { + /* + * Allocate more memory... + */ + + char *temp; /* New buffer */ + size_t size; /* Size of buffer */ + + + size = buf->end - buf->start + 2 * bytes + 1024; + + if (buf->start) + temp = realloc(buf->start, size); + else + temp = malloc(size); + + if (!temp) + return; + + /* + * Update pointers... + */ + + buf->end = temp + size; + buf->current = temp + (buf->current - buf->start); + buf->start = temp; + } + + /* + * Append the message to the end of the current string... + */ + + memcpy(buf->current, s, bytes); + buf->current += bytes - 1; +} + + +/* + * '_cupsRasterClearError()' - Clear the error buffer. + */ + +void +_cupsRasterClearError(void) +{ + _cups_raster_error_t *buf = get_error_buffer(); + /* Error buffer */ + + + buf->current = buf->start; + + if (buf->start) + *(buf->start) = '\0'; +} + + +/* + * 'cupsRasterErrorString()' - Return the last error from a raster function. + * + * If there are no recent errors, NULL is returned. + * + * @since CUPS 1.3/Mac OS X 10.5@ + */ + +const char * /* O - Last error */ +cupsRasterErrorString(void) +{ + _cups_raster_error_t *buf = get_error_buffer(); + /* Error buffer */ + + + if (buf->current == buf->start) + return (NULL); + else + return (buf->start); +} + + +#ifdef HAVE_PTHREAD_H +/* + * Implement per-thread globals... + */ + +# include + + +/* + * Local globals... + */ + +static pthread_key_t raster_key = -1; + /* Thread local storage key */ +static pthread_once_t raster_key_once = PTHREAD_ONCE_INIT; + /* One-time initialization object */ + + +/* + * Local functions... + */ + +static void raster_init(void); +static void raster_destructor(void *value); + + +/* + * 'get_error_buffer()' - Return a pointer to thread local storage. + */ + +_cups_raster_error_t * /* O - Pointer to error buffer */ +get_error_buffer(void) +{ + _cups_raster_error_t *buf; /* Pointer to error buffer */ + + + /* + * Initialize the global data exactly once... + */ + + DEBUG_puts("get_error_buffer()"); + + pthread_once(&raster_key_once, raster_init); + + /* + * See if we have allocated the data yet... + */ + + if ((buf = (_cups_raster_error_t *)pthread_getspecific(raster_key)) + == NULL) + { + DEBUG_puts("get_error_buffer: allocating memory for thread..."); + + /* + * No, allocate memory as set the pointer for the key... + */ + + buf = calloc(1, sizeof(_cups_raster_error_t)); + pthread_setspecific(raster_key, buf); + + DEBUG_printf((" buf=%p\n", buf)); + } + + /* + * Return the pointer to the data... + */ + + return (buf); +} + + +/* + * 'raster_init()' - Initialize error buffer once. + */ + +static void +raster_init(void) +{ + pthread_key_create(&raster_key, raster_destructor); + + DEBUG_printf(("raster_init(): raster_key=%x(%u)\n", (unsigned)raster_key, + (unsigned)raster_key)); +} + + +/* + * 'raster_destructor()' - Free memory allocated by get_error_buffer(). + */ + +static void +raster_destructor(void *value) /* I - Data to free */ +{ + _cups_raster_error_t *buf = (_cups_raster_error_t *)value; + /* Error buffer */ + + + DEBUG_printf(("raster_destructor(value=%p)\n", value)); + + if (buf->start) + free(buf->start); + + free(value); +} + + +#else +/* + * Implement static globals... + */ + +/* + * 'get_error_buffer()' - Return a pointer to thread local storage. + */ + +_cups_raster_error_t * /* O - Pointer to error buffer */ +get_error_buffer(void) +{ + static _cups_raster_error_t buf = { 0, 0, 0 }; + /* Error buffer */ + + + return (&buf); +} +#endif /* HAVE_PTHREAD_H */ + + +/* + * End of "$Id$". + */ diff --git a/filter/form-main.c b/filter/form-main.c new file mode 100644 index 0000000000..b104b08005 --- /dev/null +++ b/filter/form-main.c @@ -0,0 +1,53 @@ +/* + * "$Id$" + * + * CUPS form main entry for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 0000000000..1d9630db68 --- /dev/null +++ b/filter/form-ps.c @@ -0,0 +1,40 @@ +/* + * "$Id$" + * + * CUPS form PostScript routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 0000000000..dd3c6078e8 --- /dev/null +++ b/filter/form-tree.c @@ -0,0 +1,615 @@ +/* + * "$Id$" + * + * CUPS form document tree routines for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 & 255)) + { + 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 & 255)) + 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 & 255) && ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1)) + { + if (ch == '&') + { + for (glyphptr = glyph; + (ch = getc(fp)) != EOF && (glyphptr - glyph) < 15; + glyphptr ++) + if (!isalnum(ch & 255)) + 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 & 255)) + *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 & 255)) + { + if (ptr < (name + sizeof(name) - 1)) + *ptr++ = ch; + } + else + break; + + *ptr = '\0'; + + while (isspace(ch & 255) || 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 & 255) || 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 & 255) || 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 & 255)) + 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 & 255)) + { + 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 0000000000..da91a160c4 --- /dev/null +++ b/filter/form.h @@ -0,0 +1,168 @@ +/* + * "$Id$" + * + * CUPS form header file for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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/gziptoany.c b/filter/gziptoany.c new file mode 100644 index 0000000000..f5cbe29e63 --- /dev/null +++ b/filter/gziptoany.c @@ -0,0 +1,118 @@ +/* + * "$Id$" + * + * GZIP/raw pre-filter for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Copy (and uncompress) files to stdout. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * 'main()' - Copy (and uncompress) files to stdout. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_file_t *fp; /* File */ + char buffer[8192]; /* Data buffer */ + int bytes; /* Number of bytes read/written */ + int copies; /* Number of copies */ + + + /* + * Check command-line... + */ + + if (argc != 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options file\n"), + argv[0]); + return (1); + } + + /* + * Get the copy count; if we have no final content type, this is a + * raw queue or raw print file, so we need to make copies... + */ + + if (!getenv("FINAL_CONTENT_TYPE")) + copies = atoi(argv[4]); + else + copies = 1; + + /* + * Open the file... + */ + + if ((fp = cupsFileOpen(argv[6], "r")) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open file \"%s\": %s\n"), + argv[6], strerror(errno)); + return (1); + } + + /* + * Copy the file to stdout... + */ + + while (copies > 0) + { + if (!getenv("FINAL_CONTENT_TYPE")) + fputs("PAGE: 1 1\n", stderr); + + cupsFileRewind(fp); + + while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) + if (write(1, buffer, bytes) < bytes) + { + _cupsLangPrintf(stderr, + _("ERROR: Unable to write uncompressed document data: " + "%s\n"), strerror(errno)); + cupsFileClose(fp); + + return (1); + } + + copies --; + } + + /* + * Close the file and return... + */ + + cupsFileClose(fp); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-attr.c b/filter/hpgl-attr.c new file mode 100644 index 0000000000..787fbbd120 --- /dev/null +++ b/filter/hpgl-attr.c @@ -0,0 +1,479 @@ +/* + * "$Id$" + * + * HP-GL/2 attribute processing for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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, + "DEBUG: 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) + { + if (params[0].value.number < 1 || params[0].value.number > MAX_PENS) + { + fprintf(stderr, + "DEBUG: HP-GL/2 \'NP\' command with invalid number of " + "pens (%d)!\n", (int)params[0].value.number); + PenCount = 8; + } + else + PenCount = (int)params[0].value.number; + } + else + fprintf(stderr, + "DEBUG: 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 */ + { + { 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 */ + { 1.0, 1.0, 1.0 } /* White */ + }; + + + 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 - 1; + + if (i < 0 || i >= PenCount) + { + fprintf(stderr, + "DEBUG: HP-GL/2 \'PC\' command with invalid pen (%d)!\n", i + 1); + return; + } + + 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, + "DEBUG: 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 - 1; + + if (pen < 0 || pen >= PenCount) + { + fprintf(stderr, + "DEBUG: HP-GL/2 \'PW\' command with invalid pen (%d)!\n", + pen + 1); + return; + } + + 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, + "DEBUG: 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 = 0; + else if (num_params > 1) + fprintf(stderr, + "DEBUG: HP-GL/2 \'SP\' command with invalid number of parameters " + "(%d)!\n", num_params); + else if (params[0].value.number <= 0 || params[0].value.number >= PenCount) + fprintf(stderr, "DEBUG: HP-GL/2 \'SP\' command with invalid pen (%d)!\n", + (int)params[0].value.number); + else + PenNumber = (int)params[0].value.number - 1; + + 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, + "DEBUG: 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 0000000000..a6f9f41e74 --- /dev/null +++ b/filter/hpgl-char.c @@ -0,0 +1,631 @@ +/* + * "$Id$" + * + * HP-GL/2 character processing for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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" + + +/* + * 'define_font()' - Define the specified font... + */ + +void +define_font(int f) /* I - Font number */ +{ + font_t *font; /* Font */ + const char *fstring; /* Font string - SA or SS */ + float xform[2][2]; /* Transform matrix */ + + + /* + * Get the correct font data... + */ + + if (f) + { + font = &AlternateFont; + fstring = "SA"; + } + else + { + font = &StandardFont; + fstring = "SS"; + } + + /* + * Compute the font matrix, accounting for any rotation... + */ + + switch (Rotation) + { + default : + case 0 : + xform[0][0] = font->xpitch * font->x * font->height; + xform[0][1] = font->xpitch * font->y * font->height; + xform[1][0] = -font->y * font->height; + xform[1][1] = font->x * font->height; + break; + + case 90 : + xform[0][0] = -font->xpitch * font->y * font->height; + xform[0][1] = font->xpitch * font->x * font->height; + xform[1][0] = -font->x * font->height; + xform[1][1] = -font->y * font->height; + break; + + case 180 : + xform[0][0] = -font->xpitch * font->x * font->height; + xform[0][1] = -font->xpitch * font->y * font->height; + xform[1][0] = font->y * font->height; + xform[1][1] = -font->x * font->height; + break; + + case 270 : + xform[0][0] = font->xpitch * font->y * font->height; + xform[0][1] = -font->xpitch * font->x * font->height; + xform[1][0] = font->x * font->height; + xform[1][1] = font->y * font->height; + break; + } + + /* + * Send the font definition... + */ + + printf("/%s {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + fstring, font->spacing ? "Helvetica" : "Courier", + (font->weight > 0 || font->posture) ? "-" : "", + font->weight > 0 ? "Bold" : "", + font->posture ? "Oblique" : "", + xform[0][0], xform[0][1], xform[1][0], xform[1][1]); + + if (f == CharFont) + printf("%s\n", fstring); +} + + +/* + * '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.symbol_set = 277; + AlternateFont.spacing = 0; + AlternateFont.pitch = 9; + AlternateFont.height = 11.5; + AlternateFont.posture = 0; + AlternateFont.weight = 0; + AlternateFont.typeface = 48; + AlternateFont.x = 1.0; + AlternateFont.y = 0.0; + + /* + * Loop through parameter value pairs... + */ + + for (i = 0; i < (num_params - 1); i += 2) + switch ((int)params[i].value.number) + { + case 1 : /* Symbol Set */ + AlternateFont.symbol_set = (int)params[i + 1].value.number; + break; + case 2 : /* Font Spacing */ + AlternateFont.spacing = (int)params[i + 1].value.number; + break; + case 3 : /* Pitch */ + AlternateFont.pitch = params[i + 1].value.number; + break; + case 4 : /* Height */ + AlternateFont.height = params[i + 1].value.number; + break; + case 5 : /* Posture */ + AlternateFont.posture = (int)params[i + 1].value.number; + break; + case 6 : /* Stroke Weight */ + AlternateFont.weight = (int)params[i + 1].value.number; + break; + case 7 : /* Typeface */ + AlternateFont.typeface = (int)params[i + 1].value.number; + break; + } + + if (AlternateFont.spacing) + { + /* + * Set proportional spacing font... + */ + + AlternateFont.xpitch = 1.0f; + } + else + { + /* + * Set fixed-spaced font... + */ + + AlternateFont.xpitch = 0.6f * AlternateFont.height / AlternateFont.pitch; + } + + /* + * Define the font... + */ + + if (PageDirty) + { + printf("%% AD"); + for (i = 0; i < num_params; i ++) + if (i) + printf(",%g", params[i].value.number); + else + printf("%g", params[i].value.number); + puts(";"); + + define_font(1); + } + + 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 (num_params != 2) + return; + + if (CharFont) + { + AlternateFont.x = params[0].value.number; + AlternateFont.y = params[1].value.number; + } + else + { + StandardFont.x = params[0].value.number; + StandardFont.y = params[1].value.number; + } + + if (PageDirty) + { + printf("%% DI%g,%g\n", params[0].value.number, params[1].value.number); + + define_font(CharFont); + } +} + + +/* + * '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 setmiterlimit\n"); + Outputf("MP\n"); + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + PenValid = 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.symbol_set = 277; + StandardFont.spacing = 0; + StandardFont.pitch = 9; + StandardFont.height = 11.5; + StandardFont.posture = 0; + StandardFont.weight = 0; + StandardFont.typeface = 48; + 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 1 : /* Symbol Set */ + StandardFont.symbol_set = (int)params[i + 1].value.number; + break; + case 2 : /* Font Spacing */ + StandardFont.spacing = (int)params[i + 1].value.number; + break; + case 3 : /* Pitch */ + StandardFont.pitch = params[i + 1].value.number; + break; + case 4 : /* Height */ + StandardFont.height = params[i + 1].value.number; + break; + case 5 : /* Posture */ + StandardFont.posture = (int)params[i + 1].value.number; + break; + case 6 : /* Stroke Weight */ + StandardFont.weight = (int)params[i + 1].value.number; + break; + case 7 : /* Typeface */ + StandardFont.typeface = (int)params[i + 1].value.number; + break; + } + + if (StandardFont.spacing || StandardFont.pitch <= 0.0) + { + /* + * Set proportional spacing font... + */ + + StandardFont.xpitch = 1.0f; + } + else + { + /* + * Set fixed-spaced font... + */ + + StandardFont.xpitch = 0.6f * StandardFont.height / StandardFont.pitch; + } + + /* + * Define the font... + */ + + if (PageDirty) + { + printf("%% SD"); + for (i = 0; i < num_params; i ++) + if (i) + printf(",%g", params[i].value.number); + else + printf("%g", params[i].value.number); + puts(";"); + + define_font(0); + } + + 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 */ +{ + float xsize, ysize; /* Font size... */ + + + if (num_params != 2) + return; + + /* + * The "SI" values are supposed to be cm, but they appear to be inches + * when tested on real HP devices... + */ + + xsize = params[0].value.number * 72.0f; + ysize = params[1].value.number * 72.0f * 0.6f; + + if (CharFont) + { + AlternateFont.xpitch = xsize / ysize; + AlternateFont.height = ysize; + } + else + { + StandardFont.xpitch = xsize / ysize; + StandardFont.height = ysize; + } + + if (PageDirty) + { + printf("%% SI%g,%g\n", params[0].value.number, params[1].value.number); + + define_font(CharFont); + } +} + + +/* + * '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 0000000000..3db05ad9ea --- /dev/null +++ b/filter/hpgl-config.c @@ -0,0 +1,636 @@ +/* + * "$Id$" + * + * HP-GL/2 configuration routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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) + { + default : + 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; + + NP_number_pens(0, NULL); + 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 0000000000..1b1c4be089 --- /dev/null +++ b/filter/hpgl-input.c @@ -0,0 +1,272 @@ +/* + * "$Id$" + * + * HP-GL/2 input processing for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include + +#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 */ + *bufptr; /* Pointer into buffer */ + float temp; /* Temporary parameter value */ + 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; + + case '%' : /* PJL command? */ + if ((i = getc(fp)) == '-') + if ((i = getc(fp)) == '1') + if ((i = getc(fp)) == '2') + { + /* + * Yes, dump everything up to the "ENTER LANGUAGE" line... + */ + + while (fgets(buf, sizeof(buf), fp) != NULL) + if (strstr(buf, "ENTER") && strstr(buf, "LANGUAGE")) + break; + break; + } + + ungetc(i, fp); + + default : /* HP RTL/PCL control */ + while ((i = getc(fp)) != EOF && !isupper(i & 255)); + + if (i == EOF) + return (-1); + break; + } + } while (ch < ' '); + + name[0] = ch; + name[1] = getc(fp); + name[2] = '\0'; + + if (name[1] < ' ') + { + /* + * If we get here, then more than likely we are faced with a raw PCL + * file which we can't handle - abort! + */ + + fputs(_("ERROR: Invalid HP-GL/2 command seen, unable to print file!\n"), + stderr); + return (-1); + } + + if (!strcasecmp(name, "LB")) + { + bufptr = buf; + while ((ch = getc(fp)) != StringTerminator && ch != EOF) + if (bufptr < (buf + sizeof(buf) - 1)) + *bufptr++ = ch; + *bufptr = '\0'; + + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + } + else if (!strcasecmp(name, "SM")) + { + 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")) + { + 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")) + { + bufptr = buf; + while ((ch = getc(fp)) != ';') + if (ch == EOF) + break; + else if (bufptr < (buf + sizeof(buf) - 1)) + *bufptr++ = ch; + *bufptr = '\0'; + + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + } + + while (!done) + switch (ch = getc(fp)) + { + case EOF : + done = 1; + break; + + 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); + if (fscanf(fp, "%f", &temp) == 1 && num_params < MAX_PARAMS) + { + p[num_params].type = PARAM_RELATIVE; + p[num_params].value.number = temp; + 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); + if (fscanf(fp, "%f", &temp) == 1 && num_params < MAX_PARAMS) + { + p[num_params].type = PARAM_ABSOLUTE; + p[num_params].value.number = temp; + 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 0000000000..7750c4df43 --- /dev/null +++ b/filter/hpgl-main.c @@ -0,0 +1,269 @@ +/* + * "$Id$" + * + * HP-GL/2 filter main entry for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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" +#include + + +/* + * 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(stdout, NULL); + setbuf(stderr, NULL); + + /* + * Check command-line... + */ + + 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 = stdin; + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("DEBUG: 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 && + strcasecmp(val, "no") && strcasecmp(val, "off") && + strcasecmp(val, "false")) + shading = 0; + + if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + !strcasecmp(val, "true")) + FitPlot = 1; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) + 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, ¶ms)) >= 0) + { + Outputf("%% %s(%d)\n", name.name, num_params); + +#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 0000000000..8bcd470817 --- /dev/null +++ b/filter/hpgl-polygon.c @@ -0,0 +1,385 @@ +/* + * "$Id$" + * + * HP-GL/2 polygon routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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"); + PenValid = 0; + 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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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 0000000000..dd6edf8bae --- /dev/null +++ b/filter/hpgl-prolog.c @@ -0,0 +1,369 @@ +/* + * "$Id$" + * + * HP-GL/2 prolog routines for for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 + + +/* + * '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), "%c", curtm); + printf("%%%%CreationDate: %s\n", line); + WriteTextComment("Title", title); + WriteTextComment("For", user); + printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); + puts("%%EndComments"); + puts("%%BeginProlog"); + printf("/DefaultPenWidth %.2f def\n", PenWidth * 72.0 / 25.4); + 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, + "DEBUG: 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("<>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("<>setpagedevice\n", + width, length); + puts("%%EndFeature"); + puts("%%EndPageSetup"); + + PageLeft = 0.0; + PageRight = width; + PageWidth = width; + PageBottom = 0.0; + PageTop = length; + PageLength = length; + } + } + + define_font(0); + define_font(1); + + 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 0000000000..f5d1bc07dd --- /dev/null +++ b/filter/hpgl-vector.c @@ -0,0 +1,773 @@ +/* + * "$Id$" + * + * HP-GL/2 vector routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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"); + + PenValid = 1; + + 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 = PenDown; + abscoords = 0; + + if (num_params == 0) + return; + + if (!PolygonMode) + { + Outputf("MP\n"); + PenValid = 0; + } + + if (!PenValid) + { + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + PenValid = 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 */ + + Outputf("%% PE: 7-bit\n"); + break; + case ':' : /* Select pen */ + s ++; + temp = (int)decode_number(&s, base_bits, 1.0) - 1; + if (temp < 0 || temp >= PenCount) + { + fprintf(stderr, "DEBUG: Bad pen number %d in PE\n", temp + 1); + return; + } + + PenNumber = temp; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: set pen #%d\n", PenNumber + 1); +#endif /* DEBUG */ + + Outputf("%% PE: set pen #%d\n", PenNumber + 1); + + 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); + break; + case '<' : /* Next coords are a move-to */ + draw = 0; + s ++; + +#ifdef DEBUG + fputs("DEBUG: moveto\n", stderr); +#endif /* DEBUG */ + + Outputf("%% PE: moveto\n"); + 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 */ + + Outputf("%% PE: set fractional bits %d\n", temp); + break; + case '=' : /* Next coords are absolute */ + s ++; + abscoords = 1; + +#ifdef DEBUG + fputs("DEBUG: absolute\n", stderr); +#endif /* DEBUG */ + + Outputf("%% PE: absolute\n"); + 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 */ + + Outputf("%% PE: coords %.3f %.3f\n", x, y); + + 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) + { + if (fabs(PenPosition[0] - tx) > 0.001 || + fabs(PenPosition[1] - ty) > 0.001) + 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"); + + PenValid = 1; + + 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, "DEBUG: Bad PE character 0x%02X!\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, "DEBUG: Bad PE character 0x%02X!\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]); + + PenValid = 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) + { + if (PolygonMode && i == 0) + Outputf("%.3f %.3f MO\n", x, y); + else if (fabs(PenPosition[0] - x) > 0.001 || + fabs(PenPosition[1] - y) > 0.001) + 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.h b/filter/hpgltops.h new file mode 100644 index 0000000000..e262975dc3 --- /dev/null +++ b/filter/hpgltops.h @@ -0,0 +1,240 @@ +/* + * "$Id$" + * + * HP-GL/2 to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif /* M_PI */ + + +/* + * Maximum number of pens we emulate... + */ + +#define MAX_PENS 1024 + + +/* + * 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 symbol_set, /* Symbol set */ + spacing, /* Spacing (0 = fixed, 1 = proportional) */ + posture, /* Posture number */ + weight, /* Weight number */ + typeface; /* Typeface number */ + float pitch, /* Characters per inch */ + height, /* Height/size of font */ + xpitch; /* X pitch scaling value */ + 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[MAX_PENS]; /* State of each pen */ +VAR int PenMotion VALUE(0), /* 0 = absolute, 1 = relative */ + PenValid VALUE(0), /* 1 = valid position, 0 = undefined */ + PenNumber VALUE(0), /* 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 define_font(int f); +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 0000000000..0c124b6ec5 --- /dev/null +++ b/filter/image-bmp.c @@ -0,0 +1,545 @@ +/* + * "$Id$" + * + * BMP image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadBMP() - 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-private.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); + + +/* + * '_cupsImageReadBMP()' - Read a BMP image file. + */ + +int /* O - Read status */ +_cupsImageReadBMP( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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 */ + cups_ib_t bit, /* Bit in image */ + byte; /* Byte in image */ + cups_ib_t *in, /* Input pixels */ + *out, /* Output pixels */ + *ptr; /* Pointer into pixels */ + cups_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, "DEBUG: offset = %d\n", offset); + + if (offset < 0) + { + fprintf(stderr, "DEBUG: Bad BMP offset %d\n", offset); + fclose(fp); + return (1); + } + + /* + * 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); + + if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH || + img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT || + (depth != 1 && depth != 4 && depth != 8 && depth != 24)) + { + fprintf(stderr, "DEBUG: Bad BMP dimensions %ux%ux%d\n", + img->xsize, img->ysize, depth); + fclose(fp); + return (1); + } + + if (colors_used < 0 || colors_used > 256) + { + fprintf(stderr, "DEBUG: Bad BMP colormap size %d\n", colors_used); + fclose(fp); + return (1); + } + + if (img->xppi == 0 || img->yppi == 0) + { + fprintf(stderr, "DEBUG: Bad BMP resolution %dx%d PPI.\n", + img->xppi, img->yppi); + img->xppi = img->yppi = 128; + } + + /* + * Make sure the resolution info is valid... + */ + + 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; + + if (colors_used > 0) + fread(colormap, colors_used, 4, fp); + else + memset(colormap, 0, sizeof(colormap)); + + /* + * Setup image and buffers... + */ + + img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + + cupsImageSetMaxTiles(img, 0); + + bpp = cupsImageGetDepth(img); + + if ((in = malloc(img->xsize * 3)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + return (1); + } + + if ((out = malloc(img->xsize * bpp)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + free(in); + fclose(fp); + return (1); + } + + /* + * Read the image data... + */ + + color = 0; + count = 0; + align = 0; + + for (y = img->ysize - 1; y >= 0; y --) + { + 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 (saturation != 100 || hue != 0) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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 0000000000..13fc82ab10 --- /dev/null +++ b/filter/image-colorspace.c @@ -0,0 +1,1567 @@ +/* + * "$Id$" + * + * Colorspace conversions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * The color saturation/hue matrix stuff is provided thanks to Mr. Paul + * Haeberli at "http://www.sgi.com/grafica/matrix/index.html". + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsImageCMYKToBlack() - Convert CMYK data to black. + * cupsImageCMYKToCMY() - Convert CMYK colors to CMY. + * cupsImageCMYKToCMYK() - Convert CMYK colors to CMYK. + * cupsImageCMYKToRGB() - Convert CMYK colors to device-dependent + * RGB. + * cupsImageCMYKToWhite() - Convert CMYK colors to luminance. + * cupsImageLut() - Adjust all pixel values with the given + * LUT. + * cupsImageRGBAdjust() - Adjust the hue and saturation of the + * given RGB colors. + * cupsImageRGBToBlack() - Convert RGB data to black. + * cupsImageRGBToCMY() - Convert RGB colors to CMY. + * cupsImageRGBToCMYK() - Convert RGB colors to CMYK. + * cupsImageRGBToRGB() - Convert RGB colors to device-dependent + * RGB. + * cupsImageRGBToWhite() - Convert RGB colors to luminance. + * cupsImageSetProfile() - Set the device color profile. + * cupsImageSetRasterColorSpace() - Set the destination colorspace. + * cupsImageWhiteToBlack() - Convert luminance colors to black. + * cupsImageWhiteToCMY() - Convert luminance colors to CMY. + * cupsImageWhiteToCMYK() - Convert luminance colors to CMYK. + * cupsImageWhiteToRGB() - Convert luminance data to RGB. + * cupsImageWhiteToWhite() - Convert luminance colors to device- + * dependent luminance. + * cielab() - Map CIE Lab transformation... + * huerotate() - Rotate the hue, maintaining luminance. + * ident() - Make an identity matrix. + * mult() - Multiply two matrices. + * rgb_to_lab() - Convert an RGB color to CIE Lab. + * rgb_to_xyz() - Convert an RGB color to CIE XYZ. + * 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-private.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 */ + +/* + * CIE XYZ whitepoint... + */ + +#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) + + +/* + * Lookup table structure... + */ + +typedef int cups_clut_t[3][256]; + + +/* + * Local globals... + */ + +static int cupsImageHaveProfile = 0; + /* Do we have a color profile? */ +static int *cupsImageDensity; + /* Ink/marker density LUT */ +static cups_clut_t *cupsImageMatrix; + /* Color transform matrix LUT */ +static cups_cspace_t cupsImageColorSpace = CUPS_CSPACE_RGB; + /* Destination colorspace */ + + +/* + * Local functions... + */ + +static float cielab(float x, float xn); +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 rgb_to_lab(cups_ib_t *val); +static void rgb_to_xyz(cups_ib_t *val); +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); + + +/* + * 'cupsImageCMYKToBlack()' - Convert CMYK data to black. + */ + +void +cupsImageCMYKToBlack( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + int k; /* Black value */ + + + if (cupsImageHaveProfile) + while (count > 0) + { + k = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 + in[3]; + + if (k < 255) + *out++ = cupsImageDensity[k]; + else + *out++ = cupsImageDensity[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 --; + } +} + + +/* + * 'cupsImageCMYKToCMY()' - Convert CMYK colors to CMY. + */ + +void +cupsImageCMYKToCMY( + const cups_ib_t *in, /* I - Input pixels */ + cups_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 (cupsImageHaveProfile) + while (count > 0) + { + c = *in++; + m = *in++; + y = *in++; + k = *in++; + + cc = cupsImageMatrix[0][0][c] + + cupsImageMatrix[0][1][m] + + cupsImageMatrix[0][2][y] + k; + cm = cupsImageMatrix[1][0][c] + + cupsImageMatrix[1][1][m] + + cupsImageMatrix[1][2][y] + k; + cy = cupsImageMatrix[2][0][c] + + cupsImageMatrix[2][1][m] + + cupsImageMatrix[2][2][y] + k; + + if (cc < 0) + *out++ = 0; + else if (cc > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cc]; + + if (cm < 0) + *out++ = 0; + else if (cm > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cm]; + + if (cy < 0) + *out++ = 0; + else if (cy > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[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 --; + } +} + + +/* + * 'cupsImageCMYKToCMYK()' - Convert CMYK colors to CMYK. + */ + +void +cupsImageCMYKToCMYK( + const cups_ib_t *in, /* I - Input pixels */ + cups_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 (cupsImageHaveProfile) + while (count > 0) + { + c = *in++; + m = *in++; + y = *in++; + k = *in++; + + cc = (cupsImageMatrix[0][0][c] + + cupsImageMatrix[0][1][m] + + cupsImageMatrix[0][2][y]); + cm = (cupsImageMatrix[1][0][c] + + cupsImageMatrix[1][1][m] + + cupsImageMatrix[1][2][y]); + cy = (cupsImageMatrix[2][0][c] + + cupsImageMatrix[2][1][m] + + cupsImageMatrix[2][2][y]); + + if (cc < 0) + *out++ = 0; + else if (cc > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cc]; + + if (cm < 0) + *out++ = 0; + else if (cm > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cm]; + + if (cy < 0) + *out++ = 0; + else if (cy > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cy]; + + *out++ = cupsImageDensity[k]; + + count --; + } + else if (in != out) + { + while (count > 0) + { + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + *out++ = *in++; + + count --; + } + } +} + + +/* + * 'cupsImageCMYKToRGB()' - Convert CMYK colors to device-dependent RGB. + */ + +void +cupsImageCMYKToRGB( + const cups_ib_t *in, /* I - Input pixels */ + cups_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 (cupsImageHaveProfile) + { + while (count > 0) + { + c = *in++; + m = *in++; + y = *in++; + k = *in++; + + cr = cupsImageMatrix[0][0][c] + + cupsImageMatrix[0][1][m] + + cupsImageMatrix[0][2][y] + k; + cg = cupsImageMatrix[1][0][c] + + cupsImageMatrix[1][1][m] + + cupsImageMatrix[1][2][y] + k; + cb = cupsImageMatrix[2][0][c] + + cupsImageMatrix[2][1][m] + + cupsImageMatrix[2][2][y] + k; + + if (cr < 0) + *out++ = 255; + else if (cr > 255) + *out++ = 255 - cupsImageDensity[255]; + else + *out++ = 255 - cupsImageDensity[cr]; + + if (cg < 0) + *out++ = 255; + else if (cg > 255) + *out++ = 255 - cupsImageDensity[255]; + else + *out++ = 255 - cupsImageDensity[cg]; + + if (cb < 0) + *out++ = 255; + else if (cb > 255) + *out++ = 255 - cupsImageDensity[255]; + else + *out++ = 255 - cupsImageDensity[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 (cupsImageColorSpace == CUPS_CSPACE_CIELab || + cupsImageColorSpace >= CUPS_CSPACE_ICC1) + rgb_to_lab(out - 3); + else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ) + rgb_to_xyz(out - 3); + + count --; + } + } +} + + +/* + * 'cupsImageCMYKToWhite()' - Convert CMYK colors to luminance. + */ + +void +cupsImageCMYKToWhite( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + int w; /* White value */ + + + if (cupsImageHaveProfile) + { + while (count > 0) + { + w = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100 - in[3]; + + if (w > 0) + *out++ = cupsImageDensity[w]; + else + *out++ = cupsImageDensity[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 --; + } + } +} + + +/* + * 'cupsImageLut()' - Adjust all pixel values with the given LUT. + */ + +void +cupsImageLut(cups_ib_t *pixels, /* IO - Input/output pixels */ + int count, /* I - Number of pixels/bytes to adjust */ + const cups_ib_t *lut) /* I - Lookup table */ +{ + while (count > 0) + { + *pixels = lut[*pixels]; + pixels ++; + count --; + } +} + + +/* + * 'cupsImageRGBAdjust()' - Adjust the hue and saturation of the given RGB colors. + */ + +void +cupsImageRGBAdjust(cups_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 cups_clut_t *lut = NULL; /* Lookup table for matrix */ + + + if (saturation != last_sat || hue != last_hue || !lut) + { + /* + * Build the color adjustment matrix... + */ + + ident(mat); + saturate(mat, saturation * 0.01); + huerotate(mat, (float)hue); + + /* + * Allocate memory for the lookup table... + */ + + if (lut == NULL) + lut = calloc(3, sizeof(cups_clut_t)); + + if (lut == NULL) + return; + + /* + * 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; + } +} + + +/* + * 'cupsImageRGBToBlack()' - Convert RGB data to black. + */ + +void +cupsImageRGBToBlack( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + while (count > 0) + { + *out++ = cupsImageDensity[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 --; + } +} + + +/* + * 'cupsImageRGBToCMY()' - Convert RGB colors to CMY. + */ + +void +cupsImageRGBToCMY( + const cups_ib_t *in, /* I - Input pixels */ + cups_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 (cupsImageHaveProfile) + 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 = cupsImageMatrix[0][0][c] + + cupsImageMatrix[0][1][m] + + cupsImageMatrix[0][2][y] + k; + cm = cupsImageMatrix[1][0][c] + + cupsImageMatrix[1][1][m] + + cupsImageMatrix[1][2][y] + k; + cy = cupsImageMatrix[2][0][c] + + cupsImageMatrix[2][1][m] + + cupsImageMatrix[2][2][y] + k; + + if (cc < 0) + *out++ = 0; + else if (cc > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cc]; + + if (cm < 0) + *out++ = 0; + else if (cm > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cm]; + + if (cy < 0) + *out++ = 0; + else if (cy > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[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 --; + } +} + + +/* + * 'cupsImageRGBToCMYK()' - Convert RGB colors to CMYK. + */ + +void +cupsImageRGBToCMYK( + const cups_ib_t *in, /* I - Input pixels */ + cups_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 (cupsImageHaveProfile) + 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 = (cupsImageMatrix[0][0][c] + + cupsImageMatrix[0][1][m] + + cupsImageMatrix[0][2][y]); + cm = (cupsImageMatrix[1][0][c] + + cupsImageMatrix[1][1][m] + + cupsImageMatrix[1][2][y]); + cy = (cupsImageMatrix[2][0][c] + + cupsImageMatrix[2][1][m] + + cupsImageMatrix[2][2][y]); + + if (cc < 0) + *out++ = 0; + else if (cc > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cc]; + + if (cm < 0) + *out++ = 0; + else if (cm > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cm]; + + if (cy < 0) + *out++ = 0; + else if (cy > 255) + *out++ = cupsImageDensity[255]; + else + *out++ = cupsImageDensity[cy]; + + *out++ = cupsImageDensity[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 --; + } +} + + +/* + * 'cupsImageRGBToRGB()' - Convert RGB colors to device-dependent RGB. + */ + +void +cupsImageRGBToRGB( + const cups_ib_t *in, /* I - Input pixels */ + cups_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 (cupsImageHaveProfile) + { + 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 = cupsImageMatrix[0][0][c] + + cupsImageMatrix[0][1][m] + + cupsImageMatrix[0][2][y] + k; + cg = cupsImageMatrix[1][0][c] + + cupsImageMatrix[1][1][m] + + cupsImageMatrix[1][2][y] + k; + cb = cupsImageMatrix[2][0][c] + + cupsImageMatrix[2][1][m] + + cupsImageMatrix[2][2][y] + k; + + if (cr < 0) + *out++ = 255; + else if (cr > 255) + *out++ = 255 - cupsImageDensity[255]; + else + *out++ = 255 - cupsImageDensity[cr]; + + if (cg < 0) + *out++ = 255; + else if (cg > 255) + *out++ = 255 - cupsImageDensity[255]; + else + *out++ = 255 - cupsImageDensity[cg]; + + if (cb < 0) + *out++ = 255; + else if (cb > 255) + *out++ = 255 - cupsImageDensity[255]; + else + *out++ = 255 - cupsImageDensity[cb]; + + count --; + } + } + else + { + if (in != out) + memcpy(out, in, count * 3); + + if (cupsImageColorSpace == CUPS_CSPACE_CIELab || + cupsImageColorSpace >= CUPS_CSPACE_ICC1) + { + while (count > 0) + { + rgb_to_lab(out); + + out += 3; + count --; + } + } + else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ) + { + while (count > 0) + { + rgb_to_xyz(out); + + out += 3; + count --; + } + } + } +} + + +/* + * 'cupsImageRGBToWhite()' - Convert RGB colors to luminance. + */ + +void +cupsImageRGBToWhite( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + { + while (count > 0) + { + *out++ = 255 - cupsImageDensity[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 --; + } + } +} + + +/* + * 'cupsImageSetProfile()' - Set the device color profile. + */ + +void +cupsImageSetProfile(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 cupsImageMatrix */ + + + /* + * Allocate memory for the profile data... + */ + + if (cupsImageMatrix == NULL) + cupsImageMatrix = calloc(3, sizeof(cups_clut_t)); + + if (cupsImageMatrix == NULL) + return; + + if (cupsImageDensity == NULL) + cupsImageDensity = calloc(256, sizeof(int)); + + if (cupsImageDensity == NULL) + return; + + /* + * Populate the profile lookup tables... + */ + + cupsImageHaveProfile = 1; + + for (i = 0, im = cupsImageMatrix[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 = cupsImageDensity; k < 256; k ++) + *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5; +} + + +/* + * 'cupsImageSetRasterColorSpace()' - Set the destination colorspace. + */ + +void +cupsImageSetRasterColorSpace( + cups_cspace_t cs) /* I - Destination colorspace */ +{ + /* + * Set the destination colorspace... + */ + + cupsImageColorSpace = cs; + + /* + * Don't use color profiles in colorimetric colorspaces... + */ + + if (cs == CUPS_CSPACE_CIEXYZ || + cs == CUPS_CSPACE_CIELab || + cs >= CUPS_CSPACE_ICC1) + cupsImageHaveProfile = 0; +} + + +/* + * 'cupsImageWhiteToBlack()' - Convert luminance colors to black. + */ + +void +cupsImageWhiteToBlack( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + while (count > 0) + { + *out++ = cupsImageDensity[255 - *in++]; + count --; + } + else + while (count > 0) + { + *out++ = 255 - *in++; + count --; + } +} + + +/* + * 'cupsImageWhiteToCMY()' - Convert luminance colors to CMY. + */ + +void +cupsImageWhiteToCMY( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + while (count > 0) + { + out[0] = cupsImageDensity[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 --; + } +} + + +/* + * 'cupsImageWhiteToCMYK()' - Convert luminance colors to CMYK. + */ + +void +cupsImageWhiteToCMYK( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + while (count > 0) + { + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = cupsImageDensity[255 - *in++]; + count --; + } + else + while (count > 0) + { + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = 255 - *in++; + count --; + } +} + + +/* + * 'cupsImageWhiteToRGB()' - Convert luminance data to RGB. + */ + +void +cupsImageWhiteToRGB( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + { + while (count > 0) + { + out[0] = 255 - cupsImageDensity[255 - *in++]; + out[1] = out[0]; + out[2] = out[0]; + out += 3; + count --; + } + } + else + { + while (count > 0) + { + *out++ = *in; + *out++ = *in; + *out++ = *in++; + + if (cupsImageColorSpace == CUPS_CSPACE_CIELab || + cupsImageColorSpace >= CUPS_CSPACE_ICC1) + rgb_to_lab(out - 3); + else if (cupsImageColorSpace == CUPS_CSPACE_CIEXYZ) + rgb_to_xyz(out - 3); + + count --; + } + } +} + + +/* + * 'cupsImageWhiteToWhite()' - Convert luminance colors to device-dependent + * luminance. + */ + +void +cupsImageWhiteToWhite( + const cups_ib_t *in, /* I - Input pixels */ + cups_ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (cupsImageHaveProfile) + while (count > 0) + { + *out++ = 255 - cupsImageDensity[255 - *in++]; + count --; + } + else if (in != out) + memcpy(out, in, count); +} + + +/* + * '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); +} + + +/* + * '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)); +} + + +/* + * 'rgb_to_lab()' - Convert an RGB color to CIE Lab. + */ + +static void +rgb_to_lab(cups_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.055) / 1.055, 2.4); + g = pow((val[1] / 255.0 + 0.055) / 1.055, 2.4); + b = pow((val[2] / 255.0 + 0.055) / 1.055, 2.4); + + /* + * 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; + + ciel = ciel; + ciea = 500 * (cielab(ciex, D65_X) - cielab(ciey, D65_Y)); + cieb = 200 * (cielab(ciey, D65_Y) - cielab(ciez, D65_Z)); + + /* + * Scale the L value and bias the a and b values by 128 so that all + * numbers are from 0 to 255. + */ + + ciel = ciel * 2.55 + 0.5; + ciea += 128.5; + cieb += 128.5; + + /* + * Output 8-bit values... + */ + + if (ciel < 0.0) + val[0] = 0; + else if (ciel < 255.0) + val[0] = (int)ciel; + else + val[0] = 255; + + if (ciea < 0.0) + val[1] = 0; + else if (ciea < 255.0) + val[1] = (int)ciea; + else + val[1] = 255; + + if (cieb < 0.0) + val[2] = 0; + else if (cieb < 255.0) + val[2] = (int)cieb; + else + val[2] = 255; +} + + +/* + * 'rgb_to_xyz()' - Convert an RGB color to CIE XYZ. + */ + +static void +rgb_to_xyz(cups_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.055) / 1.055, 2.4); + g = pow((val[1] / 255.0 + 0.055) / 1.055, 2.4); + b = pow((val[2] / 255.0 + 0.055) / 1.055, 2.4); + + /* + * 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; + + /* + * Encode as 8-bit XYZ... + */ + + if (ciex < 0.0f) + val[0] = 0; + else if (ciex < 1.1f) + val[0] = (int)(231.8181f * ciex + 0.5); + else + val[0] = 255; + + if (ciey < 0.0f) + val[1] = 0; + else if (ciey < 1.1f) + val[1] = (int)(231.8181f * ciey + 0.5); + else + val[1] = 255; + + if (ciez < 0.0f) + val[2] = 0; + else if (ciez < 1.1f) + val[2] = (int)(231.8181f * ciez + 0.5); + else + val[2] = 255; +} + + +/* + * '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 0000000000..461ebe5bcb --- /dev/null +++ b/filter/image-gif.c @@ -0,0 +1,692 @@ +/* + * "$Id$" + * + * GIF image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadGIF() - Read a GIF image file. + * gif_get_block() - Read a GIF data block... + * gif_get_code() - Get a LZW code from the file... + * gif_read_cmap() - Read the colormap from a GIF file... + * gif_read_image() - Read a GIF image stream... + * gif_read_lzw() - Read a byte from the LZW stream... + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + + +/* + * GIF definitions... + */ + +#define GIF_INTERLACE 0x40 +#define GIF_COLORMAP 0x80 +#define GIF_MAX_BITS 12 + +typedef cups_ib_t gif_cmap_t[256][4]; +typedef short gif_table_t[4096]; + + +/* + * Local globals... + */ + +static int gif_eof = 0; /* Did we hit EOF? */ + + +/* + * Local functions... + */ + +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_cmap(FILE *fp, int ncolors, gif_cmap_t cmap, + int *gray); +static int gif_read_image(FILE *fp, cups_image_t *img, gif_cmap_t cmap, + int interlace); +static int gif_read_lzw(FILE *fp, int first_time, int input_code_size); + + +/* + * '_cupsImageReadGIF()' - Read a GIF image file. + */ + +int /* O - Read status */ +_cupsImageReadGIF( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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 == CUPS_IMAGE_RGB_CMYK) + primary = CUPS_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 == CUPS_IMAGE_BLACK || primary == CUPS_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 ',' : /* cupsImage data */ + fread(buf, 9, 1, fp); + + if (buf[8] & GIF_COLORMAP) + { + ncolors = 2 << (buf[8] & 0x07); + gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_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 CUPS_IMAGE_CMYK : + for (i = ncolors - 1; i >= 0; i --) + cupsImageWhiteToCMYK(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_CMY : + for (i = ncolors - 1; i >= 0; i --) + cupsImageWhiteToCMY(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_BLACK : + for (i = ncolors - 1; i >= 0; i --) + cupsImageWhiteToBlack(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_WHITE : + break; + case CUPS_IMAGE_RGB : + case CUPS_IMAGE_RGB_CMYK : + for (i = ncolors - 1; i >= 0; i --) + cupsImageWhiteToRGB(cmap[i], cmap[i], 1); + break; + } + + img->colorspace = secondary; + } + else + { + if (hue != 0 || saturation != 100) + for (i = ncolors - 1; i >= 0; i --) + cupsImageRGBAdjust(cmap[i], 1, saturation, hue); + + switch (primary) + { + case CUPS_IMAGE_CMYK : + for (i = ncolors - 1; i >= 0; i --) + cupsImageRGBToCMYK(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_CMY : + for (i = ncolors - 1; i >= 0; i --) + cupsImageRGBToCMY(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_BLACK : + for (i = ncolors - 1; i >= 0; i --) + cupsImageRGBToBlack(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_WHITE : + for (i = ncolors - 1; i >= 0; i --) + cupsImageRGBToWhite(cmap[i], cmap[i], 1); + break; + case CUPS_IMAGE_RGB : + case CUPS_IMAGE_RGB_CMYK : + for (i = ncolors - 1; i >= 0; i --) + cupsImageRGBToRGB(cmap[i], cmap[i], 1); + break; + } + + img->colorspace = primary; + } + + if (lut) + { + bpp = cupsImageGetDepth(img); + + for (i = ncolors - 1; i >= 0; i --) + cupsImageLut(cmap[i], bpp, lut); + } + + img->xsize = (buf[5] << 8) | buf[4]; + img->ysize = (buf[7] << 8) | buf[6]; + + /* + * Check the dimensions of the image; since the dimensions are + * a 16-bit integer we just need to check for 0... + */ + + if (img->xsize == 0 || img->ysize == 0) + { + fprintf(stderr, "DEBUG: Bad GIF image dimensions: %dx%d\n", + img->xsize, img->ysize); + fclose(fp); + return (1); + } + + i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE); + fclose(fp); + return (i); + } + } +} + + +/* + * '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 const 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; + last_byte = 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; + } + else if (last_byte == 1) + { + buf[0] = buf[last_byte - 1]; + last_byte = 1; + } + + /* + * 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... + */ + + curbit = (curbit - lastbit) + 8 * last_byte; + last_byte += count; + lastbit = last_byte * 8; + } + + 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_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_read_image()' - Read a GIF image stream... + */ + +static int /* I - 0 = success, -1 = failure */ +gif_read_image(FILE *fp, /* I - Input file */ + cups_image_t *img, /* I - cupsImage pointer */ + gif_cmap_t cmap, /* I - Colormap */ + int interlace) /* I - Non-zero = interlaced image */ +{ + unsigned char code_size; /* Code size */ + cups_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 const int xpasses[4] = /* X interleaving */ + { 8, 8, 4, 2 }, + ypasses[5] = /* Y interleaving */ + { 0, 4, 2, 1, 999999 }; + + + bpp = cupsImageGetDepth(img); + pixels = calloc(bpp, img->xsize); + xpos = 0; + ypos = 0; + pass = 0; + code_size = getc(fp); + + if (code_size > GIF_MAX_BITS || !pixels) + return (-1); + + if (gif_read_lzw(fp, 1, code_size) < 0) + { + free(pixels); + 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) + { + _cupsImagePutRow(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); +} + + +/* + * '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 */ + *stack = NULL, /* Output stack */ + *sp; /* Current stack pointer */ + static gif_table_t *table = NULL; /* String table */ + + + 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; + + /* + * Allocate memory for buffers... + */ + + if (table == NULL) + table = calloc(2, sizeof(gif_table_t)); + + if (table == NULL) + return (-1); + + if (stack == NULL) + stack = calloc(8192, sizeof(short)); + + if (stack == NULL) + return (-1); + + /* + * Initialize input buffers... + */ + + gif_get_code(fp, 0, 1); + + /* + * Wipe the decompressor table (already mostly 0 due to the calloc above...) + */ + + fresh = 1; + + for (i = 1; i < clear_code; i ++) + table[1][i] = i; + + 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 & 255); + } + else if (!table) + return (0); + + if (sp > stack) + return ((*--sp) & 255); + + while ((code = gif_get_code(fp, code_size, 0)) >= 0) + { + if (code == clear_code) + { + /* + * Clear/reset the compression table... + */ + + memset(table, 0, 2 * sizeof(gif_table_t)); + for (i = 1; i < clear_code; i ++) + table[1][i] = i; + + 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 & 255); + } + else if (code == end_code || code > max_code) + { + unsigned char buf[260]; /* Block buffer */ + + 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) & 255); + } + + return (code & 255); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-jpeg.c b/filter/image-jpeg.c new file mode 100644 index 0000000000..013ae8d499 --- /dev/null +++ b/filter/image-jpeg.c @@ -0,0 +1,322 @@ +/* + * "$Id$" + * + * JPEG image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadJPEG() - Read a JPEG image file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + +#ifdef HAVE_LIBJPEG +# include /* JPEG/JFIF image definitions */ + + +/* + * '_cupsImageReadJPEG()' - Read a JPEG image file. + */ + +int /* O - Read status */ +_cupsImageReadJPEG( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + struct jpeg_decompress_struct cinfo; /* Decompressor info */ + struct jpeg_error_mgr jerr; /* Error handler info */ + cups_ib_t *in, /* Input pixels */ + *out; /* Output pixels */ + jpeg_saved_marker_ptr marker; /* Pointer to marker data */ + int psjpeg = 0; /* Non-zero if Photoshop CMYK JPEG */ + static const char *cspaces[] = + { /* JPEG colorspaces... */ + "JCS_UNKNOWN", + "JCS_GRAYSCALE", + "JCS_RGB", + "JCS_YCbCr", + "JCS_CMYK", + "JCS_YCCK" + }; + + + /* + * Read the JPEG header... + */ + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 0xffff); /* Adobe JPEG */ + jpeg_stdio_src(&cinfo, fp); + jpeg_read_header(&cinfo, 1); + + /* + * Parse any Adobe APPE data embedded in the JPEG file. Since Adobe doesn't + * bother following standards, we have to invert the CMYK JPEG data written by + * Adobe apps... + */ + + for (marker = cinfo.marker_list; marker; marker = marker->next) + if (marker->marker == (JPEG_APP0 + 14) && marker->data_length >= 12 && + !memcmp(marker->data, "Adobe", 5) && marker->data[11] == 2) + { + fputs("DEBUG: Adobe CMYK JPEG detected (inverting color values)\n", + stderr); + psjpeg = 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 == CUPS_IMAGE_RGB_CMYK) ? CUPS_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 == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + } + + jpeg_calc_output_dimensions(&cinfo); + + if (cinfo.output_width <= 0 || cinfo.output_width > CUPS_IMAGE_MAX_WIDTH || + cinfo.output_height <= 0 || cinfo.output_height > CUPS_IMAGE_MAX_HEIGHT) + { + fprintf(stderr, "DEBUG: Bad JPEG dimensions %dx%d!\n", + cinfo.output_width, cinfo.output_height); + + jpeg_destroy_decompress(&cinfo); + + fclose(fp); + return (1); + } + + 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); + } + + if (img->xppi == 0 || img->yppi == 0) + { + fprintf(stderr, "DEBUG: Bad JPEG image resolution %dx%d PPI.\n", + img->xppi, img->yppi); + img->xppi = img->yppi = 128; + } + } + + fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n", + img->xsize, img->ysize, cinfo.output_components, + img->xppi, img->yppi); + + cupsImageSetMaxTiles(img, 0); + + in = malloc(img->xsize * cinfo.output_components); + out = malloc(img->xsize * cupsImageGetDepth(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... + */ + + cups_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) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + if ((img->colorspace == CUPS_IMAGE_WHITE && cinfo.out_color_space == JCS_GRAYSCALE) || + (img->colorspace == CUPS_IMAGE_CMYK && cinfo.out_color_space == JCS_CMYK)) + { +#ifdef DEBUG + int i, j; + cups_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) + cupsImageLut(in, img->xsize * cupsImageGetDepth(img), lut); + + _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, in); + } + else if (cinfo.out_color_space == JCS_GRAYSCALE) + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageWhiteToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut); + + _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); + } + else if (cinfo.out_color_space == JCS_RGB) + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut); + + _cupsImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); + } + else /* JCS_CMYK */ + { + fputs("DEBUG: JCS_CMYK\n", stderr); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageCMYKToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageCMYKToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageCMYKToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageCMYKToRGB(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * cupsImageGetDepth(img), lut); + + _cupsImagePutRow(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 0000000000..1c2d0a2eb9 --- /dev/null +++ b/filter/image-photocd.c @@ -0,0 +1,333 @@ +/* + * "$Id$" + * + * PhotoCD routines for the Common UNIX Printing System (CUPS). + * + * 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... + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadPhotoCD() - Read a PhotoCD image file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + + +/* + * '_cupsImageReadPhotoCD()' - Read a PhotoCD image file. + */ + +int /* O - Read status */ +_cupsImageReadPhotoCD( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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 */ + cups_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 == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + img->xppi = 128; + img->yppi = 128; + + if (rotation) + { + img->xsize = 512; + img->ysize = 768; + } + else + { + img->xsize = 768; + img->ysize = 512; + } + + cupsImageSetMaxTiles(img, 0); + + bpp = cupsImageGetDepth(img); + + if ((in = malloc(768 * 3)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + return (1); + } + + if ((out = malloc(768 * bpp)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + free(in); + return (1); + } + + if (bpp > 1) + { + if ((rgb = malloc(768 * 3)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + free(in); + free(out); + return (1); + } + } + 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); + + if (bpp > 1) + free(rgb); + + 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 == CUPS_IMAGE_BLACK) + { + if (rotation) + { + for (rgbptr = out + xstart, x = 0; x < 768; x ++) + *rgbptr-- = 255 - *iy++; + + if (lut) + cupsImageLut(out, 768, lut); + + _cupsImagePutCol(img, 511 - y - pass, 0, 768, out); + } + else + { + cupsImageWhiteToBlack(iy, out, 768); + + if (lut) + cupsImageLut(out, 768, lut); + + _cupsImagePutRow(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) + cupsImageLut(out, 768, lut); + + _cupsImagePutCol(img, 511 - y - pass, 0, 768, out); + } + else + { + if (lut) + cupsImageLut(iy, 768, lut); + + _cupsImagePutRow(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) + cupsImageRGBAdjust(rgb, 768, saturation, hue); + + /* + * Then convert the RGB data to the appropriate colorspace and + * put it in the image... + */ + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(rgb, out, 768); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(rgb, out, 768); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(rgb, out, 768); + break; + } + + if (lut) + cupsImageLut(out, 768 * bpp, lut); + + if (rotation) + _cupsImagePutCol(img, 511 - y - pass, 0, 768, out); + else + _cupsImagePutRow(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 0000000000..f1cd9b40aa --- /dev/null +++ b/filter/image-pix.c @@ -0,0 +1,240 @@ +/* + * "$Id$" + * + * Alias PIX image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadPIX() - Read a PIX image file. + * read_short() - Read a 16-bit integer. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + + +/* + * Local functions... + */ + +static short read_short(FILE *fp); + + +/* + * '_cupsImageReadPIX()' - Read a PIX image file. + */ + +int /* O - Read status */ +_cupsImageReadPIX( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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 */ + cups_ib_t r, g, b; /* Red, green/gray, blue values */ + cups_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); + + /* + * Check the dimensions of the image. Since the short values used for the + * width and height cannot exceed CUPS_IMAGE_MAX_WIDTH or + * CUPS_IMAGE_MAX_HEIGHT, we just need to verify they are positive integers. + */ + + if (width <= 0 || height <= 0 || + (depth != 8 && depth != 24)) + { + fprintf(stderr, "DEBUG: Bad PIX image dimensions %dx%dx%d\n", + width, height, depth); + fclose(fp); + return (1); + } + + if (depth == 8) + img->colorspace = secondary; + else + img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + + img->xsize = width; + img->ysize = height; + + cupsImageSetMaxTiles(img, 0); + + bpp = cupsImageGetDepth(img); + + if ((in = malloc(img->xsize * (depth / 8))) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + return (1); + } + + if ((out = malloc(img->xsize * bpp)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + free(in); + return (1); + } + + /* + * Read the image data... + */ + + if (depth == 8) + { + for (count = 0, y = 0, g = 0; y < img->ysize; y ++) + { + if (img->colorspace == CUPS_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 != CUPS_IMAGE_WHITE) + switch (img->colorspace) + { + default : + cupsImageWhiteToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, out); + } + } + else + { + for (count = 0, y = 0, r = 0, g = 0, b = 0; y < img->ysize; y ++) + { + 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 (saturation != 100 || hue != 0) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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 0000000000..7efa3882ec --- /dev/null +++ b/filter/image-png.c @@ -0,0 +1,315 @@ +/* + * "$Id$" + * + * PNG image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadPNG() - Read a PNG image file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) +# include /* Portable Network Graphics (PNG) definitions */ + + +/* + * '_cupsImageReadPNG()' - Read a PNG image file. + */ + +int /* O - Read status */ +_cupsImageReadPNG( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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 */ + png_uint_32 width, /* Width of image */ + height; /* Height of image */ + int bit_depth, /* Bit depth */ + color_type, /* Color type */ + interlace_type, /* Interlace type */ + compression_type, /* Compression type */ + filter_type; /* Filter type */ + png_uint_32 xppm, /* X pixels per meter */ + yppm; /* Y pixels per meter */ + int bpp; /* Bytes per pixel */ + int pass, /* Current pass */ + passes; /* Number of passes required */ + cups_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); + + png_get_IHDR(pp, info, &width, &height, &bit_depth, &color_type, + &interlace_type, &compression_type, &filter_type); + + fprintf(stderr, "DEBUG: PNG image: %dx%dx%d, color_type=%x (%s%s%s)\n", + (int)width, (int)height, bit_depth, color_type, + (color_type & PNG_COLOR_MASK_COLOR) ? "RGB" : "GRAYSCALE", + (color_type & PNG_COLOR_MASK_ALPHA) ? "+ALPHA" : "", + (color_type & PNG_COLOR_MASK_PALETTE) ? "+PALETTE" : ""); + + if (color_type & PNG_COLOR_MASK_PALETTE) + png_set_expand(pp); + else if (bit_depth < 8) + { + png_set_packing(pp); + png_set_expand(pp); + } + else if (bit_depth == 16) + png_set_strip_16(pp); + + if (color_type & PNG_COLOR_MASK_COLOR) + img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : + primary; + else + img->colorspace = secondary; + + if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH || + height == 0 || height > CUPS_IMAGE_MAX_HEIGHT) + { + fprintf(stderr, "DEBUG: PNG image has invalid dimensions %ux%u!\n", + (unsigned)width, (unsigned)height); + fclose(fp); + return (1); + } + + img->xsize = width; + img->ysize = height; + + if ((xppm = png_get_x_pixels_per_meter(pp, info)) != 0 && + (yppm = png_get_y_pixels_per_meter(pp, info)) != 0) + { + img->xppi = (int)((float)xppm * 0.0254); + img->yppi = (int)((float)yppm * 0.0254); + + if (img->xppi == 0 || img->yppi == 0) + { + fprintf(stderr, "DEBUG: PNG image has invalid resolution %dx%d PPI\n", + img->xppi, img->yppi); + + img->xppi = img->yppi = 128; + } + } + + cupsImageSetMaxTiles(img, 0); + + 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 (color_type == PNG_COLOR_TYPE_GRAY || + 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... + */ + + size_t bufsize; /* Size of buffer */ + + + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + bufsize = img->xsize * img->ysize; + + if ((bufsize / img->xsize) != img->ysize) + { + fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n", + (unsigned)width, (unsigned)height); + fclose(fp); + return (1); + } + } + else + { + bufsize = img->xsize * img->ysize * 3; + + if ((bufsize / (img->xsize * 3)) != img->ysize) + { + fprintf(stderr, "DEBUG: PNG image dimensions (%ux%u) too large!\n", + (unsigned)width, (unsigned)height); + fclose(fp); + return (1); + } + } + + in = malloc(bufsize); + } + + bpp = cupsImageGetDepth(img); + out = malloc(img->xsize * bpp); + + if (!in || !out) + { + fputs("DEBUG: Unable to allocate memory for PNG image!\n", stderr); + + if (in) + free(in); + + if (out) + free(out); + + fclose(fp); + + return (1); + } + + /* + * 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 (color_type & PNG_COLOR_MASK_COLOR) + { + if ((saturation != 100 || hue != 0) && bpp > 1) + cupsImageRGBAdjust(inptr, img->xsize, saturation, hue); + + switch (img->colorspace) + { + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(inptr, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + case CUPS_IMAGE_RGB_CMYK : + cupsImageRGBToRGB(inptr, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(inptr, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(inptr, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(inptr, out, img->xsize); + break; + } + } + else + { + switch (img->colorspace) + { + case CUPS_IMAGE_WHITE : + memcpy(out, inptr, img->xsize); + break; + case CUPS_IMAGE_RGB : + case CUPS_IMAGE_RGB_CMYK : + cupsImageWhiteToRGB(inptr, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(inptr, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(inptr, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(inptr, out, img->xsize); + break; + } + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, out); + } + + if (passes > 1) + { + if (color_type & PNG_COLOR_MASK_COLOR) + inptr += img->xsize * 3; + else + inptr += img->xsize; + } + } + + png_read_end(pp, info); + png_destroy_read_struct(&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 0000000000..9d84b645f8 --- /dev/null +++ b/filter/image-pnm.c @@ -0,0 +1,320 @@ +/* + * "$Id$" + * + * Portable Any Map file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadPNM() - Read a PNM image file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + + +/* + * '_cupsImageReadPNM()' - Read a PNM image file. + */ + +int /* O - Read status */ +_cupsImageReadPNM( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int x, y; /* Looping vars */ + int bpp; /* Bytes per pixel */ + cups_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 + */ + + if ((lineptr = fgets(line, sizeof(line), fp)) == NULL) + { + fputs("DEBUG: Bad PNM header!\n", stderr); + fclose(fp); + return (1); + } + + lineptr ++; + + format = atoi(lineptr); + while (isdigit(*lineptr & 255)) + lineptr ++; + + while (lineptr != NULL && img->xsize == 0) + { + if (*lineptr == '\0' || *lineptr == '#') + lineptr = fgets(line, sizeof(line), fp); + else if (isdigit(*lineptr & 255)) + { + img->xsize = atoi(lineptr); + while (isdigit(*lineptr & 255)) + lineptr ++; + } + else + lineptr ++; + } + + while (lineptr != NULL && img->ysize == 0) + { + if (*lineptr == '\0' || *lineptr == '#') + lineptr = fgets(line, sizeof(line), fp); + else if (isdigit(*lineptr & 255)) + { + img->ysize = atoi(lineptr); + while (isdigit(*lineptr & 255)) + 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 & 255)) + { + maxval = atoi(lineptr); + while (isdigit(*lineptr & 255)) + lineptr ++; + } + else + lineptr ++; + } + } + else + maxval = 1; + + if (img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH || + img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT) + { + fprintf(stderr, "DEBUG: Bad PNM dimensions %dx%d!\n", + img->xsize, img->ysize); + fclose(fp); + return (1); + } + + if (maxval == 0) + { + fprintf(stderr, "DEBUG: Bad PNM max value %d!\n", maxval); + fclose(fp); + return (1); + } + + if (format == 1 || format == 2 || format == 4 || format == 5) + img->colorspace = secondary; + else + img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + + cupsImageSetMaxTiles(img, 0); + + bpp = cupsImageGetDepth(img); + + if ((in = malloc(img->xsize * 3)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + return (1); + } + + if ((out = malloc(img->xsize * bpp)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + free(in); + return (1); + } + + /* + * Read the image file... + */ + + for (y = 0; y < img->ysize; y ++) + { + switch (format) + { + case 1 : + for (x = img->xsize, inptr = in; x > 0; x --, inptr ++) + if (fscanf(fp, "%d", &val) == 1) + *inptr = val ? 0 : 255; + break; + + 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 = 0; + else + *inptr = 255; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + outptr ++; + } + } + 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 == CUPS_IMAGE_WHITE) + { + if (lut) + cupsImageLut(in, img->xsize, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + cupsImageWhiteToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, out); + } + break; + + default : + if ((saturation != 100 || hue != 0) && bpp > 1) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, out); + break; + } + } + + free(in); + free(out); + + fclose(fp); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-private.h b/filter/image-private.h new file mode 100644 index 0000000000..56acaef869 --- /dev/null +++ b/filter/image-private.h @@ -0,0 +1,221 @@ +/* + * "$Id$" + * + * Private image library definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_IMAGE_PRIVATE_H_ +# define _CUPS_IMAGE_PRIVATE_H_ + +/* + * Include necessary headers... + */ + +# include "image.h" +# include +# include +# include +# include +# include +# ifdef WIN32 +# include +# else +# include +# endif /* WIN32 */ +# include +# include + + +/* + * Constants... + */ + +# define CUPS_IMAGE_MAX_WIDTH 0x07ffffff + /* 2^27-1 to allow for 15-channel data */ +# define CUPS_IMAGE_MAX_HEIGHT 0x3fffffff + /* 2^30-1 */ + +# define CUPS_TILE_SIZE 256 /* 256x256 pixel tiles */ +# define CUPS_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 */ + + +/* + * Types and structures... + */ + +typedef enum cups_iztype_e /**** Image zoom type ****/ +{ + CUPS_IZOOM_FAST, /* Use nearest-neighbor sampling */ + CUPS_IZOOM_NORMAL, /* Use bilinear interpolation */ + CUPS_IZOOM_BEST /* Use bicubic interpolation */ +} cups_iztype_t; + +struct cups_ic_s; + +typedef struct cups_itile_s /**** Image tile ****/ +{ + int dirty; /* True if tile is dirty */ + off_t pos; /* Position of tile on disk (-1 if not written) */ + struct cups_ic_s *ic; /* Pixel data */ +} cups_itile_t; + +typedef struct cups_ic_s /**** Image tile cache ****/ +{ + struct cups_ic_s *prev, /* Previous tile in cache */ + *next; /* Next tile in cache */ + cups_itile_t *tile; /* Tile this is attached to */ + cups_ib_t *pixels; /* Pixel data */ +} cups_ic_t; + +struct cups_image_s /**** Image file data ****/ +{ + cups_icspace_t 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 */ + cups_itile_t **tiles; /* Tiles in image */ + cups_ic_t *first, /* First cached tile in image */ + *last; /* Last cached tile in image */ + int cachefile; /* Tile cache file */ + char cachename[256]; /* Tile cache filename */ +}; + +struct cups_izoom_s /**** Image zoom data ****/ +{ + cups_image_t *img; /* Image to zoom */ + cups_iztype_t type; /* Type of zooming */ + unsigned xorig, /* X origin */ + yorig, /* Y origin */ + 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 */ + cups_ib_t *rows[2], /* Horizontally scaled pixel data */ + *in; /* Unscaled input pixel data */ +}; + + +/* + * Prototypes... + */ + +extern int _cupsImagePutCol(cups_image_t *img, int x, int y, + int height, const cups_ib_t *pixels); +extern int _cupsImagePutRow(cups_image_t *img, int x, int y, + int width, const cups_ib_t *pixels); +extern int _cupsImageReadBMP(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadFPX(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadGIF(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadJPEG(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadPIX(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadPNG(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadPNM(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadPhotoCD(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadSGI(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadSunRaster(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern int _cupsImageReadTIFF(cups_image_t *img, FILE *fp, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut); +extern void _cupsImageZoomDelete(cups_izoom_t *z); +extern void _cupsImageZoomFill(cups_izoom_t *z, int iy); +extern cups_izoom_t *_cupsImageZoomNew(cups_image_t *img, int xc0, int yc0, + int xc1, int yc1, int xsize, + int ysize, int rotated, + cups_iztype_t type); + +extern int _cupsRasterExecPS(cups_page_header2_t *h, + int *preferred_bits, + const char *code); +extern void _cupsRasterAddError(const char *f, ...); +extern void _cupsRasterClearError(void); + +#endif /* !_CUPS_IMAGE_PRIVATE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/filter/image-sgi.c b/filter/image-sgi.c new file mode 100644 index 0000000000..3c100e5e1a --- /dev/null +++ b/filter/image-sgi.c @@ -0,0 +1,295 @@ +/* + * "$Id$" + * + * SGI image file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadSGI() - Read a SGI image file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" +#include "image-sgi.h" + + +/* + * '_cupsImageReadSGI()' - Read a SGI image file. + */ + +int /* O - Read status */ +_cupsImageReadSGI( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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 */ + cups_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... + */ + + /* + * Check the image dimensions; since xsize and ysize are unsigned shorts, + * just check if they are 0 since they can't exceed CUPS_IMAGE_MAX_WIDTH or + * CUPS_IMAGE_MAX_HEIGHT... + */ + + if (sgip->xsize == 0 || sgip->ysize == 0 || + sgip->zsize == 0 || sgip->zsize > 4) + { + fprintf(stderr, "DEBUG: Bad SGI image dimensions %ux%ux%u!\n", + sgip->xsize, sgip->ysize, sgip->zsize); + sgiClose(sgip); + return (1); + } + + if (sgip->zsize < 3) + img->colorspace = secondary; + else + img->colorspace = (primary == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + + img->xsize = sgip->xsize; + img->ysize = sgip->ysize; + + cupsImageSetMaxTiles(img, 0); + + bpp = cupsImageGetDepth(img); + + if ((in = malloc(img->xsize * sgip->zsize)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + sgiClose(sgip); + return (1); + } + + if ((out = malloc(img->xsize * bpp)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + sgiClose(sgip); + free(in); + return (1); + } + + if ((rows[0] = calloc(img->xsize * sgip->zsize, + sizeof(unsigned short))) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + sgiClose(sgip); + free(in); + free(out); + return (1); + } + + 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 == CUPS_IMAGE_WHITE) + { + if (lut) + cupsImageLut(in, img->xsize, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + case CUPS_IMAGE_RGB_CMYK : + cupsImageWhiteToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, out); + } + } + else + { + if ((saturation != 100 || hue != 0) && bpp > 1) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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 0000000000..72a6d97cad --- /dev/null +++ b/filter/image-sgi.h @@ -0,0 +1,87 @@ +/* + * "$Id$" + * + * SGI image file format library definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _SGI_H_ +# define _SGI_H_ + +# include +# include +# include + +# 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(const 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 0000000000..afa132e3a8 --- /dev/null +++ b/filter/image-sgilib.c @@ -0,0 +1,891 @@ +/* + * "$Id$" + * + * SGI image file format library routines for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 /* O - 0 on success, -1 on error */ +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 /* O - 0 on success, -1 on error */ +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 * /* O - New image */ +sgiOpen(const 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 * /* O - New image */ +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); + + if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL) + { + free(sgip); + return (NULL); + } + + if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize, + sizeof(long))) == NULL) + { + free(sgip->table); + free(sgip); + return (NULL); + } + + 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); + if ((sgip->table = calloc(sgip->zsize, sizeof(long *))) == NULL) + { + free(sgip); + return (NULL); + } + + if ((sgip->table[0] = calloc(sgip->ysize * sgip->zsize, + sizeof(long))) == NULL) + { + free(sgip->table); + free(sgip); + return (NULL); + } + + for (i = 1; i < sgip->zsize; i ++) + sgip->table[i] = sgip->table[0] + i * sgip->ysize; + + if ((sgip->length = calloc(sgip->zsize, sizeof(long *))) == NULL) + { + free(sgip->table); + free(sgip); + return (NULL); + } + + if ((sgip->length[0] = calloc(sgip->ysize * sgip->zsize, + sizeof(long))) == NULL) + { + free(sgip->length); + free(sgip->table); + free(sgip); + return (NULL); + } + + 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 /* O - 0 on success, -1 on error */ +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 /* O - Long value */ +getlong(FILE *fp) /* I - File to read from */ +{ + unsigned char b[4]; /* Bytes from file */ + + + 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 /* O - Short value */ +getshort(FILE *fp) /* I - File to read from */ +{ + unsigned char b[2]; /* Bytes from file */ + + + fread(b, 2, 1, fp); + return ((b[0] << 8) | b[1]); +} + + +/* + * 'putlong()' - Put a 32-bit big-endian integer. + */ + +static int /* O - 0 on success, -1 on error */ +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 /* O - 0 on success, -1 on error */ +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 /* O - Value on success, -1 on error */ +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 ++) + if (xsize > 0) + *row = getc(fp); + } + else + { + ch = getc(fp); + length ++; + for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) + *row = ch; + } + } + + return (xsize > 0 ? -1 : length); +} + + +/* + * 'read_rle16()' - Read 16-bit RLE data. + */ + +static int /* O - Value on success, -1 on error */ +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 ++) + if (xsize > 0) + *row = getshort(fp); + } + else + { + ch = getshort(fp); + length ++; + for (i = 0; i < count && xsize > 0; i ++, row ++, xsize --) + *row = ch; + } + } + + return (xsize > 0 ? -1 : length * 2); +} + + +/* + * 'write_rle8()' - Write 8-bit RLE data. + */ + +static int /* O - Length on success, -1 on error */ +write_rle8(FILE *fp, /* I - File to write to */ + unsigned short *row, /* I - Data */ + int xsize) /* I - Width of data in pixels */ +{ + int length, /* Length in bytes */ + count, /* Number of repeating pixels */ + i, /* Looping var */ + x; /* Current column */ + unsigned short *start, /* Start of current sequence */ + repeat; /* Repeated pixel */ + + + 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 /* O - Length in words */ +write_rle16(FILE *fp, /* I - File to write to */ + unsigned short *row, /* I - Data */ + int xsize) /* I - Width of data in pixels */ +{ + int length, /* Length in words */ + count, /* Number of repeating pixels */ + i, /* Looping var */ + x; /* Current column */ + unsigned short *start, /* Start of current sequence */ + repeat; /* Repeated pixel */ + + + 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 0000000000..887880b210 --- /dev/null +++ b/filter/image-sun.c @@ -0,0 +1,407 @@ +/* + * "$Id$" + * + * Sun Raster image file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadSunRaster() - Read a SunRaster image file. + * read_unsigned() - Read a 32-bit unsigned integer. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.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); + + +/* + * '_cupsImageReadSunRaster()' - Read a SunRaster image file. + */ + +int /* O - Read status */ +_cupsImageReadSunRaster( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int i, x, y, + bpp, /* Bytes per pixel */ + scanwidth, + run_count, + run_value; + cups_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 (cupsImageOpen + * checks this) so we don't need to check the magic number again. + */ + + fputs("DEBUG: Reading Sun Raster image...\n", stderr); + + 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); + + fprintf(stderr, "DEBUG: ras_width=%d, ras_height=%d, ras_depth=%d, ras_type=%d, ras_maplength=%d\n", + img->xsize, img->ysize, ras_depth, ras_type, ras_maplength); + + if (ras_maplength > 768 || + img->xsize == 0 || img->xsize > CUPS_IMAGE_MAX_WIDTH || + img->ysize == 0 || img->ysize > CUPS_IMAGE_MAX_HEIGHT || + ras_depth == 0 || ras_depth > 32) + { + fputs("DEBUG: Raster image cannot be loaded!\n", stderr); + return (1); + } + + if (ras_maplength > 0) + { + memset(cmap[0], 255, sizeof(cmap[0])); + memset(cmap[1], 0, sizeof(cmap[1])); + memset(cmap[2], 0, sizeof(cmap[2])); + + 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 == CUPS_IMAGE_RGB_CMYK) ? CUPS_IMAGE_RGB : primary; + in = malloc(img->xsize * 3 + 1); + } + + if (!in) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + return (1); + } + + bpp = cupsImageGetDepth(img); + + if ((out = malloc(img->xsize * bpp)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + free(in); + return (1); + } + + if ((scanline = malloc(scanwidth)) == NULL) + { + fputs("DEBUG: Unable to allocate memory!\n", stderr); + fclose(fp); + free(in); + free(out); + return (1); + } + + run_count = 0; + run_value = 0; + + fprintf(stderr, "DEBUG: bpp=%d, scanwidth=%d\n", bpp, scanwidth); + + for (y = 0; y < img->ysize; y ++) + { + if ((ras_depth != 8 && ras_depth != 24) || 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 >>= 1; + else + { + bit = 128; + scanptr ++; + } + } + } + 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 >>= 1; + else + { + bit = 128; + scanptr ++; + } + } + } + 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 (ras_depth <= 8 && ras_maplength == 0) + { + if (img->colorspace == CUPS_IMAGE_WHITE) + { + if (lut) + cupsImageLut(in, img->xsize, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + cupsImageWhiteToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, out); + } + } + else + { + if ((saturation != 100 || hue != 0) && bpp > 1) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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 0000000000..2bc0ae3c4f --- /dev/null +++ b/filter/image-tiff.c @@ -0,0 +1,1715 @@ +/* + * "$Id$" + * + * TIFF file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageReadTIFF() - Read a TIFF image file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + +#ifdef HAVE_LIBTIFF +# include /* TIFF image definitions */ +# include +# include + + +/* + * '_cupsImageReadTIFF()' - Read a TIFF image file. + */ + +int /* O - Read status */ +_cupsImageReadTIFF( + cups_image_t *img, /* IO - cupsImage */ + FILE *fp, /* I - cupsImage file */ + cups_icspace_t primary, /* I - Primary choice for colorspace */ + cups_icspace_t secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const cups_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; /* cupsImage includes alpha? */ + cups_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("DEBUG: TIFFFdOpen() failed!\n", stderr); + fclose(fp); + return (-1); + } + + if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width)) + { + fputs("DEBUG: No image width tag in the file!\n", stderr); + TIFFClose(tif); + fclose(fp); + return (-1); + } + + if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height)) + { + fputs("DEBUG: No image height tag in the file!\n", stderr); + TIFFClose(tif); + fclose(fp); + return (-1); + } + + if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) + { + fputs("DEBUG: No photometric tag in the file!\n", stderr); + TIFFClose(tif); + fclose(fp); + return (-1); + } + + if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)) + { + fputs("DEBUG: 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; + } + + if (img->xppi == 0 || img->yppi == 0) + { + fputs("DEBUG: Bad TIFF resolution.\n", stderr); + img->xppi = 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; + + /* + * Check the size of the image... + */ + + if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH || + height == 0 || height > CUPS_IMAGE_MAX_HEIGHT || + (bits != 1 && bits != 2 && bits != 4 && bits != 8) || + samples < 1 || samples > 4) + { + fprintf(stderr, "DEBUG: Bad TIFF dimensions %ux%ux%ux%u!\n", + (unsigned)width, (unsigned)height, (unsigned)bits, + (unsigned)samples); + TIFFClose(tif); + fclose(fp); + return (1); + } + + /* + * 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 == CUPS_IMAGE_RGB_CMYK) + img->colorspace = CUPS_IMAGE_CMYK; + else if (primary == CUPS_IMAGE_RGB_CMYK) + img->colorspace = CUPS_IMAGE_RGB; + else + img->colorspace = primary; + + fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace); + + bpp = cupsImageGetDepth(img); + + cupsImageSetMaxTiles(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 == CUPS_IMAGE_WHITE) + { + if (lut) + cupsImageLut(in, img->xsize, lut); + + _cupsImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + cupsImageWhiteToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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 == CUPS_IMAGE_WHITE) + { + if (lut) + cupsImageLut(in, img->ysize, lut); + + _cupsImagePutCol(img, x, 0, img->ysize, in); + } + else + { + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_RGB : + cupsImageWhiteToRGB(in, out, img->ysize); + break; + case CUPS_IMAGE_BLACK : + cupsImageWhiteToBlack(in, out, img->ysize); + break; + case CUPS_IMAGE_CMY : + cupsImageWhiteToCMY(in, out, img->ysize); + break; + case CUPS_IMAGE_CMYK : + cupsImageWhiteToCMYK(in, out, img->ysize); + break; + } + + if (lut) + cupsImageLut(out, img->ysize * bpp, lut); + + _cupsImagePutCol(img, x, 0, img->ysize, out); + } + } + } + break; + + case PHOTOMETRIC_PALETTE : + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap)) + { + fputs("DEBUG: 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++]; + } + } + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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++]; + } + } + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->ysize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->ysize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->ysize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->ysize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->ysize); + break; + } + + if (lut) + cupsImageLut(out, img->ysize * bpp, lut); + + _cupsImagePutCol(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) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * bpp, lut); + + _cupsImagePutRow(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) + cupsImageRGBAdjust(in, img->ysize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->ysize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->ysize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->ysize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->ysize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->ysize); + break; + } + + if (lut) + cupsImageLut(out, img->ysize * bpp, lut); + + _cupsImagePutCol(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 == CUPS_IMAGE_CMYK) + { + TIFFReadScanline(tif, scanline, row, 0); + _cupsImagePutRow(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) + cupsImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->xsize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->xsize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->xsize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->xsize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + cupsImageLut(out, img->xsize * 3, lut); + + _cupsImagePutRow(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 == CUPS_IMAGE_CMYK) + { + TIFFReadScanline(tif, scanline, row, 0); + _cupsImagePutCol(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) + cupsImageRGBAdjust(in, img->ysize, saturation, hue); + + switch (img->colorspace) + { + default : + break; + + case CUPS_IMAGE_WHITE : + cupsImageRGBToWhite(in, out, img->ysize); + break; + case CUPS_IMAGE_RGB : + cupsImageRGBToRGB(in, out, img->ysize); + break; + case CUPS_IMAGE_BLACK : + cupsImageRGBToBlack(in, out, img->ysize); + break; + case CUPS_IMAGE_CMY : + cupsImageRGBToCMY(in, out, img->ysize); + break; + case CUPS_IMAGE_CMYK : + cupsImageRGBToCMYK(in, out, img->ysize); + break; + } + + if (lut) + cupsImageLut(out, img->ysize * bpp, lut); + + _cupsImagePutCol(img, x, 0, img->ysize, out); + } + } + + break; + } + + default : + _TIFFfree(scanline); + free(in); + free(out); + + TIFFClose(tif); + fputs("DEBUG: 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 0000000000..154ea34c2f --- /dev/null +++ b/filter/image-zoom.c @@ -0,0 +1,361 @@ +/* + * "$Id$" + * + * cupsImage zoom routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * _cupsImageZoomDelete() - Free a zoom record... + * _cupsImageZoomFill() - Fill a zoom record... + * _cupsImageZoomNew() - Allocate a pixel zoom record... + * zoom_bilinear() - Fill a zoom record with image data utilizing + * bilinear interpolation. + * zoom_nearest() - Fill a zoom record quickly using nearest-neighbor + * sampling. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + + +/* + * Local functions... + */ + +static void zoom_bilinear(cups_izoom_t *z, int iy); +static void zoom_nearest(cups_izoom_t *z, int iy); + + +/* + * '_cupsImageZoomDelete()' - Free a zoom record... + */ + +void +_cupsImageZoomDelete(cups_izoom_t *z) /* I - Zoom record to free */ +{ + free(z->rows[0]); + free(z->rows[1]); + free(z->in); + free(z); +} + + +/* + * '_cupsImageZoomFill()' - Fill a zoom record with image data utilizing bilinear + * interpolation. + */ + +void +_cupsImageZoomFill(cups_izoom_t *z, /* I - Zoom record to fill */ + int iy) /* I - Zoom image row */ +{ + switch (z->type) + { + case CUPS_IZOOM_FAST : + zoom_nearest(z, iy); + break; + + default : + zoom_bilinear(z, iy); + break; + } +} + + +/* + * '_cupsImageZoomNew()' - Allocate a pixel zoom record... + */ + +cups_izoom_t * +_cupsImageZoomNew( + cups_image_t *img, /* I - cupsImage to zoom */ + int xc0, /* I - Upper-lefthand corner */ + int yc0, /* I - ... */ + int xc1, /* I - Lower-righthand corner */ + int yc1, /* 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 */ + cups_iztype_t type) /* I - Zoom type */ +{ + cups_izoom_t *z; /* New zoom record */ + int flip; /* Flip on X axis? */ + + + if (xsize > CUPS_IMAGE_MAX_WIDTH || + ysize > CUPS_IMAGE_MAX_HEIGHT || + (xc1 - xc0) > CUPS_IMAGE_MAX_WIDTH || + (yc1 - yc0) > CUPS_IMAGE_MAX_HEIGHT) + return (NULL); /* Protect against integer overflow */ + + if ((z = (cups_izoom_t *)calloc(1, sizeof(cups_izoom_t))) == NULL) + return (NULL); + + z->img = img; + z->row = 0; + z->depth = cupsImageGetDepth(img); + z->rotated = rotated; + z->type = type; + + if (xsize < 0) + { + flip = 1; + xsize = -xsize; + } + else + { + flip = 0; + } + + if (rotated) + { + z->xorig = xc1; + z->yorig = yc0; + z->width = yc1 - yc0 + 1; + z->height = xc1 - xc0 + 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; /* z->xincr is always 1 */ + + 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 = xc0; + z->yorig = yc0; + z->width = xc1 - xc0 + 1; + z->height = yc1 - yc0 + 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; /* z->xincr is always 1 */ + + 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] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL) + { + free(z); + return (NULL); + } + + if ((z->rows[1] = (cups_ib_t *)malloc(z->xsize * z->depth)) == NULL) + { + free(z->rows[0]); + free(z); + return (NULL); + } + + if ((z->in = (cups_ib_t *)malloc(z->width * z->depth)) == NULL) + { + free(z->rows[0]); + free(z->rows[1]); + free(z); + return (NULL); + } + + return (z); +} + + +/* + * 'zoom_bilinear()' - Fill a zoom record with image data utilizing bilinear + * interpolation. + */ + +static void +zoom_bilinear(cups_izoom_t *z, /* I - Zoom record to fill */ + int iy) /* I - Zoom image row */ +{ + cups_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) + cupsImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in); + else + cupsImageGetRow(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; + } + } +} + + +/* + * 'zoom_nearest()' - Fill a zoom record quickly using nearest-neighbor + * sampling. + */ + +static void +zoom_nearest(cups_izoom_t *z, /* I - Zoom record to fill */ + int iy) /* I - Zoom image row */ +{ + cups_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) + cupsImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in); + else + cupsImageGetRow(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; + } + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image.c b/filter/image.c new file mode 100644 index 0000000000..d5a747cc69 --- /dev/null +++ b/filter/image.c @@ -0,0 +1,812 @@ +/* + * "$Id$" + * + * Base image support for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsImageClose() - Close an image file. + * cupsImageGetCol() - Get a column of pixels from an image. + * cupsImageGetColorSpace() - Get the image colorspace. + * cupsImageGetDepth() - Get the number of bytes per pixel. + * cupsImageGetHeight() - Get the height of an image. + * cupsImageGetRow() - Get a row of pixels from an image. + * cupsImageGetWidth() - Get the width of an image. + * cupsImageGetXPPI() - Get the horizontal resolution of an image. + * cupsImageGetYPPI() - Get the vertical resolution of an image. + * cupsImageOpen() - Open an image file and read it into memory. + * _cupsImagePutCol() - Put a column of pixels to an image. + * _cupsImagePutRow() - Put a row of pixels to an image. + * cupsImageSetMaxTiles() - Set the maximum number of tiles to cache. + * flush_tile() - Flush the least-recently-used tile in the cache. + * get_tile() - Get a cached tile. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" + + +/* + * Local functions... + */ + +static void flush_tile(cups_image_t *img); +static cups_ib_t *get_tile(cups_image_t *img, int x, int y); + + +/* + * 'cupsImageClose()' - Close an image file. + */ + +void +cupsImageClose(cups_image_t *img) /* I - Image to close */ +{ + cups_ic_t *current, /* Current cached tile */ + *next; /* Next cached tile */ + + + /* + * Wipe the tile cache file (if any)... + */ + + if (img->cachefile >= 0) + { + DEBUG_printf(("Closing/removing swap file \"%s\"...\n", img->cachename)); + + close(img->cachefile); + unlink(img->cachename); + } + + /* + * Free the image cache... + */ + + DEBUG_puts("Freeing memory..."); + + for (current = img->first, next = NULL; current != NULL; current = next) + { + DEBUG_printf(("Freeing cache (%p, next = %p)...\n", current, next)); + + next = current->next; + free(current); + } + + /* + * Free the rest of memory... + */ + + if (img->tiles != NULL) + { + DEBUG_printf(("Freeing tiles (%p)...\n", img->tiles[0])); + + free(img->tiles[0]); + + DEBUG_printf(("Freeing tile pointers (%p)...\n", img->tiles)); + + free(img->tiles); + } + + free(img); +} + + +/* + * 'cupsImageGetCol()' - Get a column of pixels from an image. + */ + +int /* O - -1 on error, 0 on success */ +cupsImageGetCol(cups_image_t *img, /* I - Image */ + int x, /* I - Column */ + int y, /* I - Start row */ + int height, /* I - Column height */ + cups_ib_t *pixels) /* O - Pixel data */ +{ + int bpp, /* Bytes per pixel */ + twidth, /* Tile width */ + count; /* Number of pixels to get */ + const cups_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 = cupsImageGetDepth(img); + twidth = bpp * (CUPS_TILE_SIZE - 1); + + while (height > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + count = CUPS_TILE_SIZE - (y & (CUPS_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); +} + + +/* + * 'cupsImageGetColorSpace()' - Get the image colorspace. + */ + +cups_icspace_t /* O - Colorspace */ +cupsImageGetColorSpace( + cups_image_t *img) /* I - Image */ +{ + return (img->colorspace); +} + + +/* + * 'cupsImageGetDepth()' - Get the number of bytes per pixel. + */ + +int /* O - Bytes per pixel */ +cupsImageGetDepth(cups_image_t *img) /* I - Image */ +{ + return (abs(img->colorspace)); +} + + +/* + * 'cupsImageGetHeight()' - Get the height of an image. + */ + +unsigned /* O - Height in pixels */ +cupsImageGetHeight(cups_image_t *img) /* I - Image */ +{ + return (img->ysize); +} + + +/* + * 'cupsImageGetRow()' - Get a row of pixels from an image. + */ + +int /* O - -1 on error, 0 on success */ +cupsImageGetRow(cups_image_t *img, /* I - Image */ + int x, /* I - Start column */ + int y, /* I - Row */ + int width, /* I - Width of row */ + cups_ib_t *pixels) /* O - Pixel data */ +{ + int bpp, /* Bytes per pixel */ + count; /* Number of pixels to get */ + const cups_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 = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1)); + if (count > width) + count = width; + memcpy(pixels, ib, count * bpp); + pixels += count * bpp; + x += count; + width -= count; + } + + return (0); +} + + +/* + * 'cupsImageGetWidth()' - Get the width of an image. + */ + +unsigned /* O - Width in pixels */ +cupsImageGetWidth(cups_image_t *img) /* I - Image */ +{ + return (img->xsize); +} + + +/* + * 'cupsImageGetXPPI()' - Get the horizontal resolution of an image. + */ + +unsigned /* O - Horizontal PPI */ +cupsImageGetXPPI(cups_image_t *img) /* I - Image */ +{ + return (img->xppi); +} + + +/* + * 'cupsImageGetYPPI()' - Get the vertical resolution of an image. + */ + +unsigned /* O - Vertical PPI */ +cupsImageGetYPPI(cups_image_t *img) /* I - Image */ +{ + return (img->yppi); +} + + +/* + * 'cupsImageOpen()' - Open an image file and read it into memory. + */ + +cups_image_t * /* O - New image */ +cupsImageOpen( + const char *filename, /* I - Filename of image */ + cups_icspace_t primary, /* I - Primary colorspace needed */ + cups_icspace_t secondary, /* I - Secondary colorspace if primary no good */ + int saturation, /* I - Color saturation level */ + int hue, /* I - Color hue adjustment */ + const cups_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) */ + cups_image_t *img; /* New image buffer */ + int status; /* Status of load... */ + + + DEBUG_printf(("cupsImageOpen(\"%s\", %d, %d, %d, %d, %p)\n", + filename ? filename : "(null)", primary, secondary, + saturation, hue, lut)); + + /* + * Figure out the file type... + */ + + if ((fp = fopen(filename, "r")) == NULL) + return (NULL); + + if (fread(header, 1, sizeof(header), fp) == 0) + { + 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(cups_image_t), 1); + + if (img == NULL) + { + fclose(fp); + return (NULL); + } + + /* + * Load the image as appropriate... + */ + + img->max_ics = CUPS_TILE_MINIMUM; + img->xppi = 128; + img->yppi = 128; + + if (!memcmp(header, "GIF87a", 6) || !memcmp(header, "GIF89a", 6)) + status = _cupsImageReadGIF(img, fp, primary, secondary, saturation, hue, + lut); + else if (!memcmp(header, "BM", 2)) + status = _cupsImageReadBMP(img, fp, primary, secondary, saturation, hue, + lut); + else if (header[0] == 0x01 && header[1] == 0xda) + status = _cupsImageReadSGI(img, fp, primary, secondary, saturation, hue, + lut); + else if (header[0] == 0x59 && header[1] == 0xa6 && + header[2] == 0x6a && header[3] == 0x95) + status = _cupsImageReadSunRaster(img, fp, primary, secondary, saturation, + hue, lut); + else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6') + status = _cupsImageReadPNM(img, fp, primary, secondary, saturation, hue, + lut); + else if (!memcmp(header2, "PCD_IPI", 7)) + status = _cupsImageReadPhotoCD(img, fp, primary, secondary, saturation, + hue, lut); + else if (!memcmp(header + 8, "\000\010", 2) || + !memcmp(header + 8, "\000\030", 2)) + status = _cupsImageReadPIX(img, fp, primary, secondary, saturation, hue, + lut); +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) + else if (!memcmp(header, "\211PNG", 4)) + status = _cupsImageReadPNG(img, fp, primary, secondary, saturation, hue, + lut); +#endif /* HAVE_LIBPNG && HAVE_LIBZ */ +#ifdef HAVE_LIBJPEG + else if (!memcmp(header, "\377\330\377", 3) && /* Start-of-Image */ + header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */ + status = _cupsImageReadJPEG(img, fp, primary, secondary, saturation, hue, + lut); +#endif /* HAVE_LIBJPEG */ +#ifdef HAVE_LIBTIFF + else if (!memcmp(header, "MM\000\052", 4) || + !memcmp(header, "II\052\000", 4)) + status = _cupsImageReadTIFF(img, fp, primary, secondary, saturation, hue, + lut); +#endif /* HAVE_LIBTIFF */ + else + { + fclose(fp); + status = -1; + } + + if (status) + { + free(img); + return (NULL); + } + else + return (img); +} + + +/* + * '_cupsImagePutCol()' - Put a column of pixels to an image. + */ + +int /* O - -1 on error, 0 on success */ +_cupsImagePutCol( + cups_image_t *img, /* I - Image */ + int x, /* I - Column */ + int y, /* I - Start row */ + int height, /* I - Column height */ + const cups_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 */ + cups_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 = cupsImageGetDepth(img); + twidth = bpp * (CUPS_TILE_SIZE - 1); + tilex = x / CUPS_TILE_SIZE; + tiley = y / CUPS_TILE_SIZE; + + while (height > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + img->tiles[tiley][tilex].dirty = 1; + tiley ++; + + count = CUPS_TILE_SIZE - (y & (CUPS_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); +} + + +/* + * '_cupsImagePutRow()' - Put a row of pixels to an image. + */ + +int /* O - -1 on error, 0 on success */ +_cupsImagePutRow( + cups_image_t *img, /* I - Image */ + int x, /* I - Start column */ + int y, /* I - Row */ + int width, /* I - Row width */ + const cups_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 */ + cups_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 / CUPS_TILE_SIZE; + tiley = y / CUPS_TILE_SIZE; + + while (width > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + img->tiles[tiley][tilex].dirty = 1; + + count = CUPS_TILE_SIZE - (x & (CUPS_TILE_SIZE - 1)); + if (count > width) + count = width; + memcpy(ib, pixels, count * bpp); + pixels += count * bpp; + x += count; + width -= count; + tilex ++; + } + + return (0); +} + + +/* + * 'cupsImageSetMaxTiles()' - 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 +cupsImageSetMaxTiles( + cups_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(CUPS_TILE_MINIMUM, + 1 + max((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE, + (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE)); + + if (max_tiles == 0) + max_tiles = ((img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE) * + ((img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE); + + cache_size = max_tiles * CUPS_TILE_SIZE * CUPS_TILE_SIZE * + cupsImageGetDepth(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 * CUPS_TILE_SIZE * CUPS_TILE_SIZE; + break; + case 2 : + if (tolower(cache_units[0] & 255) == 'g') + max_size *= 1024 * 1024 * 1024; + else if (tolower(cache_units[0] & 255) == 'm') + max_size *= 1024 * 1024; + else if (tolower(cache_units[0] & 255) == 'k') + max_size *= 1024; + else if (tolower(cache_units[0] & 255) == 't') + max_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE; + break; + } + } + else + max_size = 32 * 1024 * 1024; + + if (cache_size > max_size) + max_tiles = max_size / CUPS_TILE_SIZE / CUPS_TILE_SIZE / + cupsImageGetDepth(img); + + if (max_tiles < min_tiles) + max_tiles = min_tiles; + + img->max_ics = max_tiles; + + DEBUG_printf(("max_ics=%d...\n", img->max_ics)); +} + + +/* + * 'flush_tile()' - Flush the least-recently-used tile in the cache. + */ + +static void +flush_tile(cups_image_t *img) /* I - Image */ +{ + int bpp; /* Bytes per pixel */ + cups_itile_t *tile; /* Pointer to tile */ + + + bpp = cupsImageGetDepth(img); + tile = img->first->tile; + + if (!tile->dirty) + { + tile->ic = NULL; + return; + } + + if (img->cachefile < 0) + { + if ((img->cachefile = cupsTempFd(img->cachename, + sizeof(img->cachename))) < 0) + { + tile->ic = NULL; + tile->dirty = 0; + return; + } + + DEBUG_printf(("Created swap file \"%s\"...\n", img->cachename)); + } + + if (tile->pos >= 0) + { + if (lseek(img->cachefile, tile->pos, SEEK_SET) != tile->pos) + { + tile->ic = NULL; + tile->dirty = 0; + return; + } + } + else + { + if ((tile->pos = lseek(img->cachefile, 0, SEEK_END)) < 0) + { + tile->ic = NULL; + tile->dirty = 0; + return; + } + } + + write(img->cachefile, tile->ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE); + + tile->ic = NULL; + tile->dirty = 0; +} + + +/* + * 'get_tile()' - Get a cached tile. + */ + +static cups_ib_t * /* O - Pointer to tile or NULL */ +get_tile(cups_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 */ + cups_ic_t *ic; /* Cache pointer */ + cups_itile_t *tile; /* Tile pointer */ + + + if (img->tiles == NULL) + { + xtiles = (img->xsize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE; + ytiles = (img->ysize + CUPS_TILE_SIZE - 1) / CUPS_TILE_SIZE; + + DEBUG_printf(("Creating tile array (%dx%d)\n", xtiles, ytiles)); + + if ((img->tiles = calloc(sizeof(cups_itile_t *), ytiles)) == NULL) + return (NULL); + + if ((tile = calloc(xtiles * sizeof(cups_itile_t), ytiles)) == NULL) + return (NULL); + + for (tiley = 0; tiley < ytiles; tiley ++) + { + img->tiles[tiley] = tile; + for (tilex = xtiles; tilex > 0; tilex --, tile ++) + tile->pos = -1; + } + } + + bpp = cupsImageGetDepth(img); + tilex = x / CUPS_TILE_SIZE; + tiley = y / CUPS_TILE_SIZE; + tile = img->tiles[tiley] + tilex; + x &= (CUPS_TILE_SIZE - 1); + y &= (CUPS_TILE_SIZE - 1); + + if ((ic = tile->ic) == NULL) + { + if (img->num_ics < img->max_ics) + { + if ((ic = calloc(sizeof(cups_ic_t) + + bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE, 1)) == NULL) + { + if (img->num_ics == 0) + return (NULL); + + flush_tile(img); + ic = img->first; + } + else + { + ic->pixels = ((cups_ib_t *)ic) + sizeof(cups_ic_t); + + img->num_ics ++; + + DEBUG_printf(("Allocated cache tile %d (%p)...\n", img->num_ics, ic)); + } + } + else + { + DEBUG_printf(("Flushing old cache tile (%p)...\n", img->first)); + + flush_tile(img); + ic = img->first; + } + + ic->tile = tile; + tile->ic = ic; + + if (tile->pos >= 0) + { + DEBUG_printf(("Loading cache tile from file position " CUPS_LLFMT "...\n", + CUPS_LLCAST tile->pos)); + + lseek(img->cachefile, tile->pos, SEEK_SET); + read(img->cachefile, ic->pixels, bpp * CUPS_TILE_SIZE * CUPS_TILE_SIZE); + } + else + { + DEBUG_puts("Clearing cache tile..."); + + memset(ic->pixels, 0, bpp * CUPS_TILE_SIZE * CUPS_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 * CUPS_TILE_SIZE + x)); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image.h b/filter/image.h new file mode 100644 index 0000000000..c42dcde211 --- /dev/null +++ b/filter/image.h @@ -0,0 +1,130 @@ +/* + * "$Id$" + * + * Image library definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +#ifndef _CUPS_IMAGE_H_ +# define _CUPS_IMAGE_H_ + +/* + * Include necessary headers... + */ + +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Constants... + */ + +typedef enum cups_icspace_e /**** Image colorspaces ****/ +{ + CUPS_IMAGE_CMYK = -4, /* Cyan, magenta, yellow, and black */ + CUPS_IMAGE_CMY = -3, /* Cyan, magenta, and yellow */ + CUPS_IMAGE_BLACK = -1, /* Black */ + CUPS_IMAGE_WHITE = 1, /* White (luminance) */ + CUPS_IMAGE_RGB = 3, /* Red, green, and blue */ + CUPS_IMAGE_RGB_CMYK = 4 /* Use RGB or CMYK */ +} cups_icspace_t; + + +/* + * Types and structures... + */ + +typedef unsigned char cups_ib_t; /**** Image byte ****/ + +struct cups_image_s; +typedef struct cups_image_s cups_image_t; + /**** Image file data ****/ + +struct cups_izoom_s; +typedef struct cups_izoom_s cups_izoom_t; + /**** Image zoom data ****/ + + +/* + * Prototypes... + */ + +extern void cupsImageClose(cups_image_t *img) _CUPS_API_1_2; +extern void cupsImageCMYKToBlack(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageCMYKToCMY(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageCMYKToCMYK(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageCMYKToRGB(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageCMYKToWhite(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern int cupsImageGetCol(cups_image_t *img, int x, int y, + int height, cups_ib_t *pixels) _CUPS_API_1_2; +extern cups_icspace_t cupsImageGetColorSpace(cups_image_t *img) _CUPS_API_1_2; +extern int cupsImageGetDepth(cups_image_t *img) _CUPS_API_1_2; +extern unsigned cupsImageGetHeight(cups_image_t *img) _CUPS_API_1_2; +extern int cupsImageGetRow(cups_image_t *img, int x, int y, + int width, cups_ib_t *pixels) _CUPS_API_1_2; +extern unsigned cupsImageGetWidth(cups_image_t *img) _CUPS_API_1_2; +extern unsigned cupsImageGetXPPI(cups_image_t *img) _CUPS_API_1_2; +extern unsigned cupsImageGetYPPI(cups_image_t *img) _CUPS_API_1_2; +extern void cupsImageLut(cups_ib_t *pixels, int count, + const cups_ib_t *lut) _CUPS_API_1_2; +extern cups_image_t *cupsImageOpen(const char *filename, + cups_icspace_t primary, + cups_icspace_t secondary, + int saturation, int hue, + const cups_ib_t *lut) _CUPS_API_1_2; +extern void cupsImageRGBAdjust(cups_ib_t *pixels, int count, + int saturation, int hue) _CUPS_API_1_2; +extern void cupsImageRGBToBlack(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageRGBToCMY(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageRGBToCMYK(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageRGBToRGB(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageRGBToWhite(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageSetMaxTiles(cups_image_t *img, int max_tiles) _CUPS_API_1_2; +extern void cupsImageSetProfile(float d, float g, + float matrix[3][3]) _CUPS_API_1_2; +extern void cupsImageSetRasterColorSpace(cups_cspace_t cs) _CUPS_API_1_2; +extern void cupsImageWhiteToBlack(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageWhiteToCMY(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageWhiteToCMYK(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageWhiteToRGB(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; +extern void cupsImageWhiteToWhite(const cups_ib_t *in, + cups_ib_t *out, int count) _CUPS_API_1_2; + + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_IMAGE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/filter/imagetops.c b/filter/imagetops.c new file mode 100644 index 0000000000..91b9eb8155 --- /dev/null +++ b/filter/imagetops.c @@ -0,0 +1,1069 @@ +/* + * "$Id$" + * + * Image file to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include + + +/* + * 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(cups_ib_t *, int, int); +static void ps_ascii85(cups_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 */ +{ + cups_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 xc0, yc0, /* Corners of the page in image coords */ + xc1, yc1; + cups_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 */ + emit_jcl; /* Emit JCL? */ + 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) + { + fprintf(stderr, _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (1); + } + + /* + * 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, 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-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) + { + /* + * Get gamma value from 1 to 10000... + */ + + g = atoi(val) * 0.001f; + + if (g < 0.001f) + g = 0.001f; + else if (g > 10.0f) + g = 10.0f; + } + + if ((val = cupsGetOption("brightness", num_options, options)) != NULL) + { + /* + * Get brightness value from 10 to 1000. + */ + + b = atoi(val) * 0.01f; + + if (b < 0.1f) + b = 0.1f; + else if (b > 10.0f) + b = 10.0f; + } + + if ((val = cupsGetOption("scaling", num_options, options)) != NULL) + zoom = atoi(val) * 0.01; + else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + !strcasecmp(val, "true")) + zoom = 1.0; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) + zoom = 1.0; + + 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 ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) + { + val = choice->choice; + choice->marked = 0; + } + else + val = cupsGetOption("mirror", num_options, options); + + if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") || + !strcasecmp(val, "yes"))) + Flip = 1; + + if ((val = cupsGetOption("emit-jcl", num_options, options)) != NULL && + (!strcasecmp(val, "false") || !strcasecmp(val, "off") || + !strcasecmp(val, "no") || !strcmp(val, "0"))) + emit_jcl = 0; + else + emit_jcl = 1; + + /* + * Open the input image to print... + */ + + colorspace = ColorDevice ? CUPS_IMAGE_RGB_CMYK : CUPS_IMAGE_WHITE; + + img = cupsImageOpen(filename, colorspace, CUPS_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 = cupsImageGetColorSpace(img); + + /* + * Scale as necessary... + */ + + if (zoom == 0.0 && xppi == 0) + { + xppi = cupsImageGetXPPI(img); + yppi = cupsImageGetYPPI(img); + } + + if (yppi == 0) + yppi = xppi; + + fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n", + xppi, yppi, zoom); + + 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; + } + + fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", + xprint, yprint); + + xinches = (float)cupsImageGetWidth(img) / (float)xppi; + yinches = (float)cupsImageGetHeight(img) / (float)yppi; + + fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n", + xinches, yinches); + + 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... + */ + + fputs("DEBUG: Auto orientation...\n", stderr); + + if ((xinches > xprint || yinches > yprint) && + xinches <= yprint && yinches <= xprint) + { + /* + * Rotate the image as needed... + */ + + fputs("DEBUG: Using landscape orientation...\n", stderr); + + 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)cupsImageGetYPPI(img) / (float)cupsImageGetXPPI(img); + + fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", + xprint, yprint); + + fprintf(stderr, "DEBUG: cupsImageGetXPPI(img) = %d, cupsImageGetYPPI(img) = %d, aspect = %f\n", + cupsImageGetXPPI(img), cupsImageGetYPPI(img), aspect); + + xsize = xprint * zoom; + ysize = xsize * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect; + + if (ysize > (yprint * zoom)) + { + ysize = yprint * zoom; + xsize = ysize * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img); + } + + xsize2 = yprint * zoom; + ysize2 = xsize2 * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect; + + if (ysize2 > (xprint * zoom)) + { + ysize2 = xprint * zoom; + xsize2 = ysize2 * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img); + } + + fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize); + fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\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... + */ + + fputs("DEBUG: Auto orientation...\n", stderr); + + if ((xsize * ysize) < (xsize2 * xsize2)) + { + /* + * Do landscape orientation... + */ + + fputs("DEBUG: Using landscape orientation...\n", stderr); + + Orientation = 1; + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + } + else + { + /* + * Do portrait orientation... + */ + + fputs("DEBUG: Using portrait orientation...\n", stderr); + + Orientation = 0; + xinches = xsize; + yinches = ysize; + } + } + else if (Orientation & 1) + { + fputs("DEBUG: Using landscape orientation...\n", stderr); + + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + } + else + { + fputs("DEBUG: Using portrait orientation...\n", stderr); + + 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; + + fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n", + xpages, xprint, ypages, yprint); + + /* + * 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... */ + + + /* + * Use the correct width and length for the current orientation... + */ + + 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]; + + fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n", + width / 72.0, length / 72.0); + + /* + * 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]; + } + + /* + * 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... + */ + + if (emit_jcl) + 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), "%c", curtm); + printf("%%%%CreationDate: %s\n", curdate); + WriteTextComment("Title", argv[3]); + WriteTextComment("For", 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); + + WriteCommon(); + switch (Orientation) + { + case 0 : + WriteLabelProlog(cupsGetOption("page-label", num_options, options), + PageBottom, PageTop, PageWidth); + break; + + case 1 : + WriteLabelProlog(cupsGetOption("page-label", num_options, options), + PageLeft, PageRight, PageLength); + break; + + case 2 : + WriteLabelProlog(cupsGetOption("page-label", num_options, options), + PageLength - PageTop, PageLength - PageBottom, + PageWidth); + break; + + case 3 : + WriteLabelProlog(cupsGetOption("page-label", num_options, options), + PageWidth - PageRight, PageWidth - PageLeft, + PageLength); + break; + } + + if (realcopies > 1) + { + if (ppd == NULL || ppd->language_level == 1) + printf("/#copies %d def\n", realcopies); + else + printf("<>setpagedevice\n", realcopies); + } + + puts("%%EndProlog"); + + /* + * Output the pages... + */ + + row = malloc(cupsImageGetWidth(img) * abs(colorspace) + 3); + + fprintf(stderr, "DEBUG: XPosition=%d, YPosition=%d, Orientation=%d\n", + XPosition, YPosition, Orientation); + fprintf(stderr, "DEBUG: xprint=%.0f, yprint=%.0f\n", xprint, yprint); + fprintf(stderr, "DEBUG: PageLeft=%.0f, PageRight=%.0f, PageWidth=%.0f\n", + PageLeft, PageRight, PageWidth); + fprintf(stderr, "DEBUG: PageBottom=%.0f, PageTop=%.0f, PageLength=%.0f\n", + PageBottom, PageTop, PageLength); + + switch (Orientation) + { + default : + switch (XPosition) + { + case -1 : + left = PageLeft; + break; + default : + left = (PageRight + PageLeft - xprint * 72) / 2; + break; + case 1 : + left = PageRight - xprint * 72; + break; + } + + switch (YPosition) + { + case -1 : + top = PageBottom + yprint * 72; + break; + default : + top = (PageTop + PageBottom + yprint * 72) / 2; + break; + case 1 : + top = PageTop; + break; + } + break; + + case 1 : + switch (XPosition) + { + case -1 : + left = PageBottom; + break; + default : + left = (PageTop + PageBottom - xprint * 72) / 2; + break; + case 1 : + left = PageTop - xprint * 72; + break; + } + + switch (YPosition) + { + case -1 : + top = PageLeft + yprint * 72; + break; + default : + top = (PageRight + PageLeft + yprint * 72) / 2; + break; + case 1 : + top = PageRight; + break; + } + break; + + case 2 : + switch (XPosition) + { + case 1 : + left = PageLeft; + break; + default : + left = (PageRight + PageLeft - xprint * 72) / 2; + break; + case -1 : + left = PageRight - xprint * 72; + break; + } + + switch (YPosition) + { + case 1 : + top = PageBottom + yprint * 72; + break; + default : + top = (PageTop + PageBottom + yprint * 72) / 2; + break; + case -1 : + top = PageTop; + break; + } + break; + + case 3 : + switch (XPosition) + { + case 1 : + left = PageBottom; + break; + default : + left = (PageTop + PageBottom - xprint * 72) / 2; + break; + case -1 : + left = PageTop - xprint * 72; + break; + } + + switch (YPosition) + { + case 1 : + top = PageLeft + yprint * 72; + break; + default : + top = (PageRight + PageLeft + yprint * 72) / 2; + break; + case -1 : + top = PageRight; + break; + } + break; + } + + fprintf(stderr, "DEBUG: left=%.2f, top=%.2f\n", left, top); + + 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", PageWidth); + 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", PageLength); + break; + } + + puts("gsave"); + + xc0 = cupsImageGetWidth(img) * xpage / xpages; + xc1 = cupsImageGetWidth(img) * (xpage + 1) / xpages - 1; + yc0 = cupsImageGetHeight(img) * ypage / ypages; + yc1 = cupsImageGetHeight(img) * (ypage + 1) / ypages - 1; + + printf("%.1f %.1f translate\n", left, top); + + printf("%.3f %.3f scale\n\n", + xprint * 72.0 / (xc1 - xc0 + 1), + yprint * 72.0 / (yc1 - yc0 + 1)); + + if (LanguageLevel == 1) + { + printf("/picture %d string def\n", (xc1 - xc0 + 1) * abs(colorspace)); + printf("%d %d 8[1 0 0 -1 0 1]", (xc1 - xc0 + 1), (yc1 - yc0 + 1)); + + if (colorspace == CUPS_IMAGE_WHITE) + puts("{currentfile picture readhexstring pop} image"); + else + printf("{currentfile picture readhexstring pop} false %d colorimage\n", + abs(colorspace)); + + for (y = yc0; y <= yc1; y ++) + { + cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row); + ps_hex(row, (xc1 - xc0 + 1) * abs(colorspace), y == yc1); + } + } + else + { + switch (colorspace) + { + case CUPS_IMAGE_WHITE : + puts("/DeviceGray setcolorspace"); + break; + case CUPS_IMAGE_RGB : + puts("/DeviceRGB setcolorspace"); + break; + case CUPS_IMAGE_CMYK : + puts("/DeviceCMYK setcolorspace"); + break; + } + + printf("<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8", + xc1 - xc0 + 1, yc1 - yc0 + 1); + + switch (colorspace) + { + case CUPS_IMAGE_WHITE : + fputs("/Decode[0 1]", stdout); + break; + case CUPS_IMAGE_RGB : + fputs("/Decode[0 1 0 1 0 1]", stdout); + break; + case CUPS_IMAGE_CMYK : + fputs("/Decode[0 1 0 1 0 1 0 1]", stdout); + break; + } + + fputs("\n/DataSource currentfile/ASCII85Decode filter", stdout); + + if (((xc1 - xc0 + 1) / xprint) < 100.0) + fputs("/Interpolate true", stdout); + + puts("/ImageMatrix[1 0 0 -1 0 1]>>image"); + + for (y = yc0, out_offset = 0; y <= yc1; y ++) + { + cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row + out_offset); + + out_length = (xc1 - xc0 + 1) * abs(colorspace) + out_offset; + out_offset = out_length & 3; + + ps_ascii85(row, out_length, y == yc1); + + if (out_offset > 0) + memcpy(row, row + out_length - out_offset, out_offset); + } + } + + puts("grestore"); + WriteLabels(0); + puts("grestore"); + puts("showpage"); + } + + puts("%%EOF"); + + /* + * End the job with the appropriate JCL command or CTRL-D otherwise. + */ + + if (emit_jcl) + { + if (ppd && ppd->jcl_end) + ppdEmitJCLEnd(ppd, stdout); + else + putchar(0x04); + } + + /* + * Close files... + */ + + cupsImageClose(img); + ppdClose(ppd); + + return (0); +} + + +/* + * 'ps_hex()' - Print binary data as a series of hexadecimal numbers. + */ + +static void +ps_hex(cups_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(cups_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 0000000000..2a7da8aa33 --- /dev/null +++ b/filter/imagetoraster.c @@ -0,0 +1,4355 @@ +/* + * "$Id$" + * + * Image file to raster filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry... + * blank_line() - Clear a line buffer to the blank value... + * 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/RGBW. + * 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. + * raster_cb() - Validate the page header. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include "image-private.h" +#include +#include +#include + + +/* + * 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 } + }; + +cups_ib_t OnPixels[256], /* On-pixel LUT */ + OffPixels[256]; /* Off-pixel LUT */ + + +/* + * Local functions... + */ + +static void blank_line(cups_page_header2_t *header, unsigned char *row); +static void format_CMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_CMYK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_K(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_KCMYcm(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_KCMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +#define format_RGB format_CMY +static void format_RGBA(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_W(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_YMC(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void format_YMCK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1); +static void make_lut(cups_ib_t *, int, float, float); +static int raster_cb(cups_page_header2_t *header, int preferred_bits); + + +/* + * '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 */ + cups_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 xc0, yc0, /* Corners of the page in image coords */ + xc1, yc1; + ppd_file_t *ppd; /* PPD file */ + ppd_choice_t *choice; /* PPD option choice */ + 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_header2_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 */ + cups_izoom_t *z; /* Image zoom buffer */ + cups_iztype_t zoom_type; /* Image zoom type */ + int primary, /* Primary image colorspace */ + secondary; /* Secondary image colorspace */ + cups_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 */ + cups_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) + { + fprintf(stderr, _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (1); + } + + /* + * 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... + */ + + dup2(mypipes[0], 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... + */ + + dup2(mypipes[1], 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) + { + /* + * Get gamma value from 1 to 10000... + */ + + g = atoi(val) * 0.001f; + + if (g < 0.001f) + g = 0.001f; + else if (g > 10.0f) + g = 10.0f; + } + + if ((val = cupsGetOption("brightness", num_options, options)) != NULL) + { + /* + * Get brightness value from 10 to 1000. + */ + + b = atoi(val) * 0.01f; + + if (b < 0.1f) + b = 0.1f; + else if (b > 10.0f) + b = 10.0f; + } + + if ((val = cupsGetOption("scaling", num_options, options)) != NULL) + zoom = atoi(val) * 0.01; + else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + !strcasecmp(val, "true")) + zoom = 1.0; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) + zoom = 1.0; + + 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 ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) + { + val = choice->choice; + choice->marked = 0; + } + else + val = cupsGetOption("mirror", num_options, options); + + if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") || + !strcasecmp(val, "yes"))) + Flip = 1; + + /* + * Set the needed options in the page header... + */ + + if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb)) + { + fputs(_("ERROR: Bad page setup!\n"), stderr); + fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString()); + return (1); + } + + /* + * 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 : + case CUPS_CSPACE_SW : + if (header.cupsBitsPerColor >= 8) + { + primary = CUPS_IMAGE_WHITE; + secondary = CUPS_IMAGE_WHITE; + } + else + { + primary = CUPS_IMAGE_BLACK; + secondary = CUPS_IMAGE_BLACK; + } + break; + + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_RGBA : + case CUPS_CSPACE_RGBW : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : + if (header.cupsBitsPerColor >= 8) + { + primary = CUPS_IMAGE_RGB; + secondary = CUPS_IMAGE_RGB; + } + else + { + primary = CUPS_IMAGE_CMY; + secondary = CUPS_IMAGE_CMY; + } + break; + + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + primary = CUPS_IMAGE_BLACK; + secondary = CUPS_IMAGE_BLACK; + break; + + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_KCMYcm : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + if (header.cupsBitsPerColor == 1) + { + primary = CUPS_IMAGE_CMY; + secondary = CUPS_IMAGE_CMY; + } + else + { + primary = CUPS_IMAGE_CMYK; + secondary = CUPS_IMAGE_CMYK; + } + break; + + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + primary = CUPS_IMAGE_CMY; + secondary = CUPS_IMAGE_CMY; + break; + + 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 : + case CUPS_CSPACE_DEVICE1 : + case CUPS_CSPACE_DEVICE2 : + case CUPS_CSPACE_DEVICE3 : + case CUPS_CSPACE_DEVICE4 : + case CUPS_CSPACE_DEVICE5 : + case CUPS_CSPACE_DEVICE6 : + case CUPS_CSPACE_DEVICE7 : + case CUPS_CSPACE_DEVICE8 : + case CUPS_CSPACE_DEVICE9 : + case CUPS_CSPACE_DEVICEA : + case CUPS_CSPACE_DEVICEB : + case CUPS_CSPACE_DEVICEC : + case CUPS_CSPACE_DEVICED : + case CUPS_CSPACE_DEVICEE : + case CUPS_CSPACE_DEVICEF : + fprintf(stderr, "ERROR: Colorspace %d not supported.\n", + header.cupsColorSpace); + exit(1); + 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) + cupsImageSetProfile(profile->density, profile->gamma, profile->matrix); + + cupsImageSetRasterColorSpace(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); + + if (header.cupsColorSpace == CUPS_CSPACE_CIEXYZ || + header.cupsColorSpace == CUPS_CSPACE_CIELab || + header.cupsColorSpace >= CUPS_CSPACE_ICC1) + img = cupsImageOpen(filename, primary, secondary, sat, hue, NULL); + else + img = cupsImageOpen(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; + + fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n", + xppi, yppi, zoom); + + 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; + } + + fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", + xprint, yprint); + + xinches = (float)img->xsize / (float)xppi; + yinches = (float)img->ysize / (float)yppi; + + fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n", + xinches, yinches); + + 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... + */ + + fputs("DEBUG: Auto orientation...\n", stderr); + + if ((xinches > xprint || yinches > yprint) && + xinches <= yprint && yinches <= xprint) + { + /* + * Rotate the image as needed... + */ + + fputs("DEBUG: Using landscape orientation...\n", stderr); + + 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: Before scaling: xprint=%.1f, yprint=%.1f\n", + xprint, yprint); + + 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: Portrait size is %.2f x %.2f inches\n", xsize, ysize); + fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\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... + */ + + fputs("DEBUG: Auto orientation...\n", stderr); + + if ((xsize * ysize) < (xsize2 * xsize2)) + { + /* + * Do landscape orientation... + */ + + fputs("DEBUG: Using landscape orientation...\n", stderr); + + Orientation = 1; + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + } + else + { + /* + * Do portrait orientation... + */ + + fputs("DEBUG: Using portrait orientation...\n", stderr); + + Orientation = 0; + xinches = xsize; + yinches = ysize; + } + } + else if (Orientation & 1) + { + fputs("DEBUG: Using landscape orientation...\n", stderr); + + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + } + else + { + fputs("DEBUG: Using portrait orientation...\n", stderr); + + 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; + + fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n", + xpages, xprint, ypages, yprint); + + /* + * Compute the bitmap size... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL && + strcasecmp(choice->choice, "Custom") == 0) + { + float width, /* New width in points */ + length; /* New length in points */ + + + /* + * Use the correct width and length for the current orientation... + */ + + 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]; + + fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n", + width / 72.0, length / 72.0); + + /* + * Set the new custom size... + */ + + strcpy(header.cupsPageSizeName, "Custom"); + + header.cupsPageSize[0] = width + 0.5; + header.cupsPageSize[1] = length + 0.5; + 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; + + header.cupsBytesPerLine = (header.cupsBitsPerPixel * + header.cupsWidth + 7) / 8; + + if (header.cupsColorOrder == CUPS_ORDER_BANDED) + header.cupsBytesPerLine *= header.cupsNumColors; + } + + header.Margins[0] = PageLeft; + header.Margins[1] = PageBottom; + + fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0], + header.PageSize[1]); + + switch (Orientation) + { + default : + switch (XPosition) + { + case -1 : + header.cupsImagingBBox[0] = PageLeft; + header.cupsImagingBBox[2] = PageLeft + xprint * 72; + break; + default : + header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2; + header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case 1 : + header.cupsImagingBBox[0] = PageRight - xprint * 72; + header.cupsImagingBBox[2] = PageRight; + break; + } + + switch (YPosition) + { + case -1 : + header.cupsImagingBBox[1] = PageBottom; + header.cupsImagingBBox[3] = PageBottom + yprint * 72; + break; + default : + header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2; + header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case 1 : + header.cupsImagingBBox[1] = PageTop - yprint * 72; + header.cupsImagingBBox[3] = PageTop; + break; + } + break; + + case 1 : + switch (XPosition) + { + case -1 : + header.cupsImagingBBox[0] = PageBottom; + header.cupsImagingBBox[2] = PageBottom + yprint * 72; + break; + default : + header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2; + header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case 1 : + header.cupsImagingBBox[0] = PageTop - yprint * 72; + header.cupsImagingBBox[2] = PageTop; + break; + } + + switch (YPosition) + { + case -1 : + header.cupsImagingBBox[1] = PageLeft; + header.cupsImagingBBox[3] = PageLeft + xprint * 72; + break; + default : + header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2; + header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case 1 : + header.cupsImagingBBox[1] = PageRight - xprint * 72; + header.cupsImagingBBox[3] = PageRight; + break; + } + break; + + case 2 : + switch (XPosition) + { + case 1 : + header.cupsImagingBBox[0] = PageLeft; + header.cupsImagingBBox[2] = PageLeft + xprint * 72; + break; + default : + header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2; + header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case -1 : + header.cupsImagingBBox[0] = PageRight - xprint * 72; + header.cupsImagingBBox[2] = PageRight; + break; + } + + switch (YPosition) + { + case 1 : + header.cupsImagingBBox[1] = PageBottom; + header.cupsImagingBBox[3] = PageBottom + yprint * 72; + break; + default : + header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2; + header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case -1 : + header.cupsImagingBBox[1] = PageTop - yprint * 72; + header.cupsImagingBBox[3] = PageTop; + break; + } + break; + + case 3 : + switch (XPosition) + { + case 1 : + header.cupsImagingBBox[0] = PageBottom; + header.cupsImagingBBox[2] = PageBottom + yprint * 72; + break; + default : + header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2; + header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case -1 : + header.cupsImagingBBox[0] = PageTop - yprint * 72; + header.cupsImagingBBox[2] = PageTop; + break; + } + + switch (YPosition) + { + case 1 : + header.cupsImagingBBox[1] = PageLeft; + header.cupsImagingBBox[3] = PageLeft + xprint * 72; + break; + default : + header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2; + header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case -1 : + header.cupsImagingBBox[1] = PageRight - xprint * 72; + header.cupsImagingBBox[3] = PageRight; + break; + } + break; + } + + header.ImagingBoundingBox[0] = header.cupsImagingBBox[0]; + header.ImagingBoundingBox[1] = header.cupsImagingBBox[1]; + header.ImagingBoundingBox[2] = header.cupsImagingBBox[2]; + header.ImagingBoundingBox[3] = header.cupsImagingBBox[3]; + + if (header.cupsColorOrder == CUPS_ORDER_PLANAR) + num_planes = header.cupsNumColors; + else + num_planes = 1; + + if (header.cupsBitsPerColor >= 8) + zoom_type = CUPS_IZOOM_NORMAL; + else + zoom_type = CUPS_IZOOM_FAST; + + /* + * 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); + } + 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); + + 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) + { + xc0 = img->xsize * ypage / ypages; + xc1 = img->xsize * (ypage + 1) / ypages - 1; + yc0 = img->ysize * xpage / xpages; + yc1 = img->ysize * (xpage + 1) / xpages - 1; + + xtemp = header.HWResolution[0] * yprint; + ytemp = header.HWResolution[1] * xprint; + } + else + { + xc0 = img->xsize * xpage / xpages; + xc1 = img->xsize * (xpage + 1) / xpages - 1; + yc0 = img->ysize * ypage / ypages; + yc1 = img->ysize * (ypage + 1) / ypages - 1; + + xtemp = header.HWResolution[0] * xprint; + ytemp = header.HWResolution[1] * yprint; + } + + cupsRasterWriteHeader2(ras, &header); + + for (plane = 0; plane < num_planes; plane ++) + { + /* + * Initialize the image "zoom" engine... + */ + + if (Flip) + z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp, + Orientation & 1, zoom_type); + else + z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp, + Orientation & 1, zoom_type); + + /* + * Write leading blank space as needed... + */ + + if (header.cupsHeight > z->ysize && YPosition <= 0) + { + blank_line(&header, row); + + y = header.cupsHeight - z->ysize; + if (YPosition == 0) + y /= 2; + + fprintf(stderr, "DEBUG: Writing %d leading blank lines...\n", y); + + for (; y > 0; y --) + { + if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < + header.cupsBytesPerLine) + { + fputs(_("ERROR: Unable to write raster data to driver!\n"), + stderr); + cupsImageClose(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 (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1) + _cupsImageZoomFill(z, iy); + + _cupsImageZoomFill(z, iy + z->yincr); + + last_iy = iy; + } + + /* + * Format this line of raster data for the printer... + */ + + blank_line(&header, row); + + 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 : + case CUPS_CSPACE_RGBW : + 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_KCMYcm : + if (header.cupsBitsPerColor == 1) + { + format_KCMYcm(&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; + } + + /* + * 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); + cupsImageClose(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) + { + blank_line(&header, row); + + y = header.cupsHeight - z->ysize; + if (YPosition == 0) + y = y - y / 2; + + fprintf(stderr, "DEBUG: Writing %d trailing blank lines...\n", y); + + for (; y > 0; y --) + { + if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < + header.cupsBytesPerLine) + { + fputs(_("ERROR: Unable to write raster data to driver!\n"), + stderr); + cupsImageClose(img); + exit(1); + } + } + } + + /* + * Free memory used for the "zoom" engine... + */ + + _cupsImageZoomDelete(z); + } + } + + /* + * Close files... + */ + + free(row); + cupsRasterClose(ras); + cupsImageClose(img); + ppdClose(ppd); + + return (0); +} + + +/* + * 'blank_line()' - Clear a line buffer to the blank value... + */ + +static void +blank_line(cups_page_header2_t *header, /* I - Page header */ + unsigned char *row) /* I - Row buffer */ +{ + int count; /* Remaining bytes */ + + + count = header->cupsBytesPerLine; + + switch (header->cupsColorSpace) + { + case CUPS_CSPACE_CIEXYZ : + while (count > 2) + { + *row++ = 242; + *row++ = 255; + *row++ = 255; + count -= 3; + } + break; + + 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 : + while (count > 2) + { + *row++ = 255; + *row++ = 128; + *row++ = 128; + count -= 3; + } + break; + + case CUPS_CSPACE_K : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMC : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_KCMYcm : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + memset(row, 0, count); + break; + + default : + memset(row, 255, count); + break; + } +} + + +/* + * 'format_CMY()' - Convert image data to CMY. + */ + +static void +format_CMY(cups_page_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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 */ + int pc, pm, py; /* CMY pixels */ + + + 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 --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if (pc && pm && py) + { + bitmask >>= 3; + *ptr ^= bitmask; + } + else + { + if (pc) + *ptr ^= bitmask; + bitmask >>= 1; + + if (pm) + *ptr ^= bitmask; + bitmask >>= 1; + + if (py) + *ptr ^= bitmask; + bitmask >>= 1; + } + + 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 --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if (pc && pm && py) + *kptr ^= bitmask; + else + { + if (pc) + *cptr ^= bitmask; + if (pm) + *mptr ^= bitmask; + if (py) + *yptr ^= 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]; + + for (x = xsize; x > 0; x --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if ((pc && pm && py && z == 3) || + (pc && z == 0) || (pm && z == 1) || (py && z == 2)) + *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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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 */ + int pc, pm, py; /* CMY pixels */ + + + 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 --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if (pc && pm && py) + { + *ptr ^= bitmask; + bitmask >>= 3; + } + else + { + bitmask >>= 1; + if (pc) + *ptr ^= bitmask; + + bitmask >>= 1; + if (pm) + *ptr ^= bitmask; + + bitmask >>= 1; + if (py) + *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 --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if (pc && pm && py) + *kptr ^= bitmask; + else + { + if (pc) + *cptr ^= bitmask; + if (pm) + *mptr ^= bitmask; + if (py) + *yptr ^= 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]; + + for (x = xsize; x > 0; x --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if ((pc && pm && py && z == 0) || + (pc && z == 1) || (pm && z == 2) || (py && z == 3)) + *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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */ + cups_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; + bandwidth = header->cupsBytesPerLine / 6; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + 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 = pc && pm && py; + + 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; + else + ptr ++; + } + 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; + + 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 = pc && pm && py; + + 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 CUPS_ORDER_PLANAR : + 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 = pc && pm && py; + + if (pk && z == 0) + *ptr ^= bitmask; + else if (pc && pm && (z == 1 || z == 5)) + *ptr ^= bitmask; /* Blue (cyan + light magenta) */ + else if (pc && py && (z == 3 || z == 4)) + *ptr ^= bitmask; /* Green (light cyan + yellow) */ + else if (pm && py && (z == 2 || z == 3)) + *ptr ^= bitmask; /* Red (magenta + yellow) */ + else if (pc && z == 1) + *ptr ^= bitmask; + else if (pm && z == 2) + *ptr ^= bitmask; + else if (py && z == 3) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + } +} + + +/* + * 'format_RGBA()' - Convert image data to RGBA/RGBW. + */ + +static void +format_RGBA(cups_page_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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) + bitmask >>= 2; + else + { + bitmask = 128; + ptr ++; + } + } + 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 ++; + } + 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 ++; + } + 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 ++; + } + 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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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_header2_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 */ + cups_ib_t *r0, /* I - Primary image data */ + cups_ib_t *r1) /* I - Image data for interpolation */ +{ + cups_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 */ + int pc, pm, py; /* CMY pixels */ + + + 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 --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if (pc && pm && py) + { + bitmask >>= 3; + *ptr ^= bitmask; + } + else + { + if (py) + *ptr ^= bitmask; + bitmask >>= 1; + + if (pm) + *ptr ^= bitmask; + bitmask >>= 1; + + if (pc) + *ptr ^= bitmask; + bitmask >>= 1; + } + + 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 --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if (pc && pm && py) + *kptr ^= bitmask; + else + { + if (pc) + *cptr ^= bitmask; + if (pm) + *mptr ^= bitmask; + if (py) + *yptr ^= 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]; + + for (x = xsize; x > 0; x --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + + if ((pc && pm && py && z == 3) || + (pc && z == 2) || (pm && z == 1) || (py && z == 0)) + *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(cups_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; + } +} + + +/* + * 'raster_cb()' - Validate the page header. + */ + +static int /* O - 0 if OK, -1 if not */ +raster_cb( + cups_page_header2_t *header, /* IO - Raster header */ + int preferred_bits) /* I - Preferred bits per color */ +{ + /* + * Ensure that colorimetric colorspaces use at least 8 bits per + * component... + */ + + if ((header->cupsColorSpace == CUPS_CSPACE_CIEXYZ || + header->cupsColorSpace == CUPS_CSPACE_CIELab || + header->cupsColorSpace >= CUPS_CSPACE_ICC1) && + header->cupsBitsPerColor < 8) + header->cupsBitsPerColor = 8; + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/interpret.c b/filter/interpret.c new file mode 100644 index 0000000000..dc1ec11284 --- /dev/null +++ b/filter/interpret.c @@ -0,0 +1,1660 @@ +/* + * "$Id$" + * + * PPD command interpreter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsRasterInterpretPPD() - Interpret PPD commands to create a page header. + * _cupsRasterExecPS() - Execute PostScript code to initialize a page + * header. + * cleartomark_stack() - Clear to the last mark ([) on the stack. + * copy_stack() - Copy the top N stack objects. + * delete_stack() - Free memory used by a stack. + * error_object() - Add an object's value to the current error + * message. + * error_stack() - Add a stack to the current error message. + * index_stack() - Copy the Nth value on the stack. + * new_stack() - Create a new stack. + * pop_stock() - Pop the top object off the stack. + * push_stack() - Push an object on the stack. + * roll_stack() - Rotate stack objects. + * scan_ps() - Scan a string for the next PS object. + * setpagedevice() - Simulate the PostScript setpagedevice operator. + * DEBUG_object() - Print an object value. + * DEBUG_stack() - Print a stack. + */ + +/* + * Include necessary headers... + */ + +#include +#include "image-private.h" +#include + + +/* + * Stack values for the PostScript mini-interpreter... + */ + +typedef enum +{ + CUPS_PS_NAME, + CUPS_PS_NUMBER, + CUPS_PS_STRING, + CUPS_PS_BOOLEAN, + CUPS_PS_NULL, + CUPS_PS_START_ARRAY, + CUPS_PS_END_ARRAY, + CUPS_PS_START_DICT, + CUPS_PS_END_DICT, + CUPS_PS_START_PROC, + CUPS_PS_END_PROC, + CUPS_PS_CLEARTOMARK, + CUPS_PS_COPY, + CUPS_PS_DUP, + CUPS_PS_INDEX, + CUPS_PS_POP, + CUPS_PS_ROLL, + CUPS_PS_SETPAGEDEVICE, + CUPS_PS_STOPPED, + CUPS_PS_OTHER +} _cups_ps_type_t; + +typedef struct +{ + _cups_ps_type_t type; /* Object type */ + union + { + int boolean; /* Boolean value */ + char name[64]; /* Name value */ + double number; /* Number value */ + char other[64]; /* Other operator */ + char string[64]; /* Sring value */ + } value; /* Value */ +} _cups_ps_obj_t; + +typedef struct +{ + int num_objs, /* Number of objects on stack */ + alloc_objs; /* Number of allocated objects */ + _cups_ps_obj_t *objs; /* Objects in stack */ +} _cups_ps_stack_t; + + +/* + * Local functions... + */ + +static int cleartomark_stack(_cups_ps_stack_t *st); +static int copy_stack(_cups_ps_stack_t *st, int count); +static void delete_stack(_cups_ps_stack_t *st); +static void error_object(_cups_ps_obj_t *obj); +static void error_stack(_cups_ps_stack_t *st, const char *title); +static _cups_ps_obj_t *index_stack(_cups_ps_stack_t *st, int n); +static _cups_ps_stack_t *new_stack(void); +static _cups_ps_obj_t *pop_stack(_cups_ps_stack_t *st); +static _cups_ps_obj_t *push_stack(_cups_ps_stack_t *st, + _cups_ps_obj_t *obj); +static int roll_stack(_cups_ps_stack_t *st, int c, int s); +static _cups_ps_obj_t *scan_ps(_cups_ps_stack_t *st, char **ptr); +static int setpagedevice(_cups_ps_stack_t *st, + cups_page_header2_t *h, + int *preferred_bits); +#ifdef DEBUG +static void DEBUG_object(_cups_ps_obj_t *obj); +static void DEBUG_stack(_cups_ps_stack_t *st); +#endif /* DEBUG */ + + +/* + * 'cupsRasterInterpretPPD()' - Interpret PPD commands to create a page header. + * + * This function is used by raster image processing (RIP) filters like + * cgpdftoraster and imagetoraster when writing CUPS raster data for a page. + * It is not used by raster printer driver filters which only read CUPS + * raster data. + * + * + * @code cupsRasterInterpretPPD@ does not mark the options in the PPD using + * the "num_options" and "options" arguments. Instead, mark the options with + * @code cupsMarkOptions@ and @code ppdMarkOption@ prior to calling it - + * this allows for per-page options without manipulating the options array. + * + * The "func" argument specifies an optional callback function that is + * called prior to the computation of the final raster data. The function + * can make changes to the @link cups_page_header2_t@ data as needed to use a + * supported raster format and then returns 0 on success and -1 if the + * requested attributes cannot be supported. + * + * + * @code cupsRasterInterpretPPD@ supports a subset of the PostScript language. + * Currently only the @code [@, @code ]@, @code <<@, @code >>@, @code {@, + * @code }@, @code cleartomark@, @code copy@, @code dup@, @code index@, + * @code pop@, @code roll@, @code setpagedevice@, and @code stopped@ operators + * are supported. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +int /* O - 0 on success, -1 on failure */ +cupsRasterInterpretPPD( + cups_page_header2_t *h, /* O - Page header to create */ + ppd_file_t *ppd, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options, /* I - Options */ + cups_interpret_cb_t func) /* I - Optional page header callback (@code NULL@ for none) */ +{ + int status; /* Cummulative status */ + char *code; /* Code to run */ + const char *val; /* Option value */ + ppd_size_t *size; /* Current size */ + float left, /* Left position */ + bottom, /* Bottom position */ + right, /* Right position */ + top; /* Top position */ + int preferred_bits; /* Preferred bits per color */ + + + /* + * Range check input... + */ + + _cupsRasterClearError(); + + if (!h) + { + _cupsRasterAddError("Page header cannot be NULL!\n"); + return (-1); + } + + /* + * Reset the page header to the defaults... + */ + + memset(h, 0, sizeof(cups_page_header2_t)); + + h->NumCopies = 1; + h->PageSize[0] = 612; + h->PageSize[1] = 792; + h->HWResolution[0] = 100; + h->HWResolution[1] = 100; + h->cupsBitsPerColor = 1; + h->cupsColorOrder = CUPS_ORDER_CHUNKED; + h->cupsColorSpace = CUPS_CSPACE_K; + h->cupsBorderlessScalingFactor = 1.0f; + h->cupsPageSize[0] = 612.0f; + h->cupsPageSize[1] = 792.0f; + h->cupsImagingBBox[0] = 0.0f; + h->cupsImagingBBox[1] = 0.0f; + h->cupsImagingBBox[2] = 612.0f; + h->cupsImagingBBox[3] = 792.0f; + + strcpy(h->cupsPageSizeName, "Letter"); + +#ifdef __APPLE__ + /* + * cupsInteger0 is also used for the total page count on Mac OS X; set an + * uncommon default value so we can tell if the driver is using cupsInteger0. + */ + + h->cupsInteger[0] = 0x80000000; +#endif /* __APPLE__ */ + + /* + * Apply patches and options to the page header... + */ + + status = 0; + preferred_bits = 0; + + if (ppd) + { + /* + * Apply any patch code (used to override the defaults...) + */ + + if (ppd->patches) + status |= _cupsRasterExecPS(h, &preferred_bits, ppd->patches); + + /* + * Then apply printer options in the proper order... + */ + + if ((code = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, 0.0)) != NULL) + { + status |= _cupsRasterExecPS(h, &preferred_bits, code); + free(code); + } + + if ((code = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL) + { + status |= _cupsRasterExecPS(h, &preferred_bits, code); + free(code); + } + + if ((code = ppdEmitString(ppd, PPD_ORDER_PROLOG, 0.0)) != NULL) + { + status |= _cupsRasterExecPS(h, &preferred_bits, code); + free(code); + } + + if ((code = ppdEmitString(ppd, PPD_ORDER_PAGE, 0.0)) != NULL) + { + status |= _cupsRasterExecPS(h, &preferred_bits, code); + free(code); + } + } + + /* + * Allow option override for page scaling... + */ + + if ((val = cupsGetOption("cupsBorderlessScalingFactor", num_options, + options)) != NULL) + { + float sc = atof(val); + + if (sc >= 0.1 && sc <= 2.0) + h->cupsBorderlessScalingFactor = sc; + } + + /* + * Get the margins for the current size... + */ + + if ((size = ppdPageSize(ppd, NULL)) != NULL) + { + /* + * Use the margins from the PPD file... + */ + + left = size->left; + bottom = size->bottom; + right = size->right; + top = size->top; + + strlcpy(h->cupsPageSizeName, size->name, sizeof(h->cupsPageSizeName)); + + h->cupsPageSize[0] = size->width; + h->cupsPageSize[1] = size->length; + } + else + { + /* + * Use the default margins... + */ + + left = 0.0f; + bottom = 0.0f; + right = 612.0f; + top = 792.0f; + } + + h->PageSize[0] = h->cupsPageSize[0] * + h->cupsBorderlessScalingFactor; + h->PageSize[1] = h->cupsPageSize[1] * + h->cupsBorderlessScalingFactor; + h->Margins[0] = left * h->cupsBorderlessScalingFactor; + h->Margins[1] = bottom * h->cupsBorderlessScalingFactor; + h->ImagingBoundingBox[0] = left * h->cupsBorderlessScalingFactor; + h->ImagingBoundingBox[1] = bottom * h->cupsBorderlessScalingFactor; + h->ImagingBoundingBox[2] = right * h->cupsBorderlessScalingFactor; + h->ImagingBoundingBox[3] = top * h->cupsBorderlessScalingFactor; + h->cupsImagingBBox[0] = left; + h->cupsImagingBBox[1] = bottom; + h->cupsImagingBBox[2] = right; + h->cupsImagingBBox[3] = top; + + /* + * Use the callback to validate the page header... + */ + + if (func && (*func)(h, preferred_bits)) + { + _cupsRasterAddError("Page header callback returned error.\n"); + return (-1); + } + + /* + * Check parameters... + */ + + if (!h->HWResolution[0] || !h->HWResolution[1] || + !h->PageSize[0] || !h->PageSize[1] || + (h->cupsBitsPerColor != 1 && h->cupsBitsPerColor != 2 && + h->cupsBitsPerColor != 4 && h->cupsBitsPerColor != 8 && + h->cupsBitsPerColor != 16) || + h->cupsBorderlessScalingFactor < 0.1 || + h->cupsBorderlessScalingFactor > 2.0) + { + _cupsRasterAddError("Page header uses unsupported values.\n"); + return (-1); + } + + /* + * Compute the bitmap parameters... + */ + + h->cupsWidth = (int)((right - left) * h->cupsBorderlessScalingFactor * + h->HWResolution[0] / 72.0f + 0.5f); + h->cupsHeight = (int)((top - bottom) * h->cupsBorderlessScalingFactor * + h->HWResolution[1] / 72.0f + 0.5f); + + switch (h->cupsColorSpace) + { + case CUPS_CSPACE_W : + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + h->cupsNumColors = 1; + h->cupsBitsPerPixel = h->cupsBitsPerColor; + break; + + default : + /* + * Ensure that colorimetric colorspaces use at least 8 bits per + * component... + */ + + if (h->cupsColorSpace >= CUPS_CSPACE_CIEXYZ && + h->cupsBitsPerColor < 8) + h->cupsBitsPerColor = 8; + + /* + * Figure out the number of bits per pixel... + */ + + if (h->cupsColorOrder == CUPS_ORDER_CHUNKED) + { + if (h->cupsBitsPerColor >= 8) + h->cupsBitsPerPixel = h->cupsBitsPerColor * 3; + else + h->cupsBitsPerPixel = h->cupsBitsPerColor * 4; + } + else + h->cupsBitsPerPixel = h->cupsBitsPerColor; + + h->cupsNumColors = 3; + break; + + case CUPS_CSPACE_KCMYcm : + if (h->cupsBitsPerColor == 1) + { + if (h->cupsColorOrder == CUPS_ORDER_CHUNKED) + h->cupsBitsPerPixel = 8; + else + h->cupsBitsPerPixel = 1; + + h->cupsNumColors = 6; + break; + } + + /* + * Fall through to CMYK code... + */ + + case CUPS_CSPACE_RGBA : + case CUPS_CSPACE_RGBW : + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + if (h->cupsColorOrder == CUPS_ORDER_CHUNKED) + h->cupsBitsPerPixel = h->cupsBitsPerColor * 4; + else + h->cupsBitsPerPixel = h->cupsBitsPerColor; + + h->cupsNumColors = 4; + break; + } + + h->cupsBytesPerLine = (h->cupsBitsPerPixel * h->cupsWidth + 7) / 8; + + if (h->cupsColorOrder == CUPS_ORDER_BANDED) + h->cupsBytesPerLine *= h->cupsNumColors; + + return (status); +} + + +/* + * '_cupsRasterExecPS()' - Execute PostScript code to initialize a page header. + */ + +int /* O - 0 on success, -1 on error */ +_cupsRasterExecPS( + cups_page_header2_t *h, /* O - Page header */ + int *preferred_bits,/* O - Preferred bits per color */ + const char *code) /* I - PS code to execute */ +{ + _cups_ps_stack_t *st; /* PostScript value stack */ + _cups_ps_obj_t *obj; /* Object from top of stack */ + char *codecopy, /* Copy of code */ + *codeptr; /* Pointer into copy of code */ + + + DEBUG_printf(("_cupsRasterExecPS(h=%p, preferred_bits=%p, code=\"%s\")\n", + h, preferred_bits, code ? code : "(null)")); + + /* + * Copy the PostScript code and create a stack... + */ + + if ((codecopy = strdup(code)) == NULL) + { + _cupsRasterAddError("Unable to duplicate code string.\n"); + return (-1); + } + + if ((st = new_stack()) == NULL) + { + _cupsRasterAddError("Unable to create stack.\n"); + free(codecopy); + return (-1); + } + + /* + * Parse the PS string until we run out of data... + */ + + codeptr = codecopy; + + while ((obj = scan_ps(st, &codeptr)) != NULL) + { +#ifdef DEBUG + DEBUG_printf(("_cupsRasterExecPS: Stack (%d objects)\n", st->num_objs)); + DEBUG_object(obj); +#endif /* DEBUG */ + + switch (obj->type) + { + default : + /* Do nothing for regular values */ + break; + + case CUPS_PS_CLEARTOMARK : + pop_stack(st); + + if (cleartomark_stack(st)) + _cupsRasterAddError("cleartomark: Stack underflow!\n"); + +#ifdef DEBUG + DEBUG_puts(" dup: "); + DEBUG_stack(st); +#endif /* DEBUG */ + break; + + case CUPS_PS_COPY : + pop_stack(st); + if ((obj = pop_stack(st)) != NULL) + { + copy_stack(st, (int)obj->value.number); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: copy"); + DEBUG_stack(st); +#endif /* DEBUG */ + } + break; + + case CUPS_PS_DUP : + pop_stack(st); + copy_stack(st, 1); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: dup"); + DEBUG_stack(st); +#endif /* DEBUG */ + break; + + case CUPS_PS_INDEX : + pop_stack(st); + if ((obj = pop_stack(st)) != NULL) + { + index_stack(st, (int)obj->value.number); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: index"); + DEBUG_stack(st); +#endif /* DEBUG */ + } + break; + + case CUPS_PS_POP : + pop_stack(st); + pop_stack(st); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: pop"); + DEBUG_stack(st); +#endif /* DEBUG */ + break; + + case CUPS_PS_ROLL : + pop_stack(st); + if ((obj = pop_stack(st)) != NULL) + { + int c; /* Count */ + + + c = (int)obj->value.number; + + if ((obj = pop_stack(st)) != NULL) + { + roll_stack(st, (int)obj->value.number, c); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: roll"); + DEBUG_stack(st); +#endif /* DEBUG */ + } + } + break; + + case CUPS_PS_SETPAGEDEVICE : + pop_stack(st); + setpagedevice(st, h, preferred_bits); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: setpagedevice"); + DEBUG_stack(st); +#endif /* DEBUG */ + break; + + case CUPS_PS_START_PROC : + case CUPS_PS_END_PROC : + case CUPS_PS_STOPPED : + pop_stack(st); + break; + + case CUPS_PS_OTHER : + _cupsRasterAddError("Unknown operator \"%s\"!\n", obj->value.other); + DEBUG_printf(("_cupsRasterExecPS: Unknown operator \"%s\"!\n", + obj->value.other)); + break; + } + + if (obj && obj->type == CUPS_PS_OTHER) + break; + } + + /* + * Cleanup... + */ + + free(codecopy); + + if (st->num_objs > 0) + { + error_stack(st, "Stack not empty:"); + +#ifdef DEBUG + DEBUG_puts("_cupsRasterExecPS: Stack not empty:"); + DEBUG_stack(st); +#endif /* DEBUG */ + + delete_stack(st); + + return (-1); + } + + delete_stack(st); + + /* + * Return success... + */ + + return (0); +} + + +/* + * 'cleartomark_stack()' - Clear to the last mark ([) on the stack. + */ + +static int /* O - 0 on success, -1 on error */ +cleartomark_stack(_cups_ps_stack_t *st) /* I - Stack */ +{ + _cups_ps_obj_t *obj; /* Current object on stack */ + + + while ((obj = pop_stack(st)) != NULL) + if (obj->type == CUPS_PS_START_ARRAY) + break; + + return (obj ? 0 : -1); +} + + +/* + * 'copy_stack()' - Copy the top N stack objects. + */ + +static int /* O - 0 on success, -1 on error */ +copy_stack(_cups_ps_stack_t *st, /* I - Stack */ + int c) /* I - Number of objects to copy */ +{ + int n; /* Index */ + + + if (c < 0) + return (-1); + else if (c == 0) + return (0); + + if ((n = st->num_objs - c) < 0) + return (-1); + + while (c > 0) + { + if (!push_stack(st, st->objs + n)) + return (-1); + + n ++; + c --; + } + + return (0); +} + + +/* + * 'delete_stack()' - Free memory used by a stack. + */ + +static void +delete_stack(_cups_ps_stack_t *st) /* I - Stack */ +{ + free(st->objs); + free(st); +} + + +/* + * 'error_object()' - Add an object's value to the current error message. + */ + +static void +error_object(_cups_ps_obj_t *obj) /* I - Object to add */ +{ + switch (obj->type) + { + case CUPS_PS_NAME : + _cupsRasterAddError(" /%s", obj->value.name); + break; + + case CUPS_PS_NUMBER : + _cupsRasterAddError(" %g", obj->value.number); + break; + + case CUPS_PS_STRING : + _cupsRasterAddError(" (%s)", obj->value.string); + break; + + case CUPS_PS_BOOLEAN : + if (obj->value.boolean) + _cupsRasterAddError(" true"); + else + _cupsRasterAddError(" false"); + break; + + case CUPS_PS_NULL : + _cupsRasterAddError(" null"); + break; + + case CUPS_PS_START_ARRAY : + _cupsRasterAddError(" ["); + break; + + case CUPS_PS_END_ARRAY : + _cupsRasterAddError(" ]"); + break; + + case CUPS_PS_START_DICT : + _cupsRasterAddError(" <<"); + break; + + case CUPS_PS_END_DICT : + _cupsRasterAddError(" >>"); + break; + + case CUPS_PS_START_PROC : + _cupsRasterAddError(" {"); + break; + + case CUPS_PS_END_PROC : + _cupsRasterAddError(" }"); + break; + + case CUPS_PS_COPY : + _cupsRasterAddError(" --copy--"); + break; + + case CUPS_PS_CLEARTOMARK : + _cupsRasterAddError(" --cleartomark--"); + break; + + case CUPS_PS_DUP : + _cupsRasterAddError(" --dup--"); + break; + + case CUPS_PS_INDEX : + _cupsRasterAddError(" --index--"); + break; + + case CUPS_PS_POP : + _cupsRasterAddError(" --pop--"); + break; + + case CUPS_PS_ROLL : + _cupsRasterAddError(" --roll--"); + break; + + case CUPS_PS_SETPAGEDEVICE : + _cupsRasterAddError(" --setpagedevice--"); + break; + + case CUPS_PS_STOPPED : + _cupsRasterAddError(" --stopped--"); + break; + + case CUPS_PS_OTHER : + _cupsRasterAddError(" --%s--", obj->value.other); + break; + } +} + + +/* + * 'error_stack()' - Add a stack to the current error message... + */ + +static void +error_stack(_cups_ps_stack_t *st, /* I - Stack */ + const char *title) /* I - Title string */ +{ + int c; /* Looping var */ + _cups_ps_obj_t *obj; /* Current object on stack */ + + + _cupsRasterAddError(title); + + for (obj = st->objs, c = st->num_objs; c > 0; c --, obj ++) + error_object(obj); + + _cupsRasterAddError("\n"); +} + + +/* + * 'index_stack()' - Copy the Nth value on the stack. + */ + +static _cups_ps_obj_t * /* O - New object */ +index_stack(_cups_ps_stack_t *st, /* I - Stack */ + int n) /* I - Object index */ +{ + if (n < 0 || (n = st->num_objs - n - 1) < 0) + return (NULL); + + return (push_stack(st, st->objs + n)); +} + + +/* + * 'new_stack()' - Create a new stack. + */ + +static _cups_ps_stack_t * /* O - New stack */ +new_stack(void) +{ + _cups_ps_stack_t *st; /* New stack */ + + + if ((st = calloc(1, sizeof(_cups_ps_stack_t))) == NULL) + return (NULL); + + st->alloc_objs = 32; + + if ((st->objs = calloc(32, sizeof(_cups_ps_obj_t))) == NULL) + { + free(st); + return (NULL); + } + else + return (st); +} + + +/* + * 'pop_stock()' - Pop the top object off the stack. + */ + +static _cups_ps_obj_t * /* O - Object */ +pop_stack(_cups_ps_stack_t *st) /* I - Stack */ +{ + if (st->num_objs > 0) + { + st->num_objs --; + + return (st->objs + st->num_objs); + } + else + return (NULL); +} + + +/* + * 'push_stack()' - Push an object on the stack. + */ + +static _cups_ps_obj_t * /* O - New object */ +push_stack(_cups_ps_stack_t *st, /* I - Stack */ + _cups_ps_obj_t *obj) /* I - Object */ +{ + _cups_ps_obj_t *temp; /* New object */ + + + if (st->num_objs >= st->alloc_objs) + { + + + st->alloc_objs += 32; + + if ((temp = realloc(st->objs, st->alloc_objs * + sizeof(_cups_ps_obj_t))) == NULL) + return (NULL); + + st->objs = temp; + memset(temp + st->num_objs, 0, 32 * sizeof(_cups_ps_obj_t)); + } + + temp = st->objs + st->num_objs; + st->num_objs ++; + + memcpy(temp, obj, sizeof(_cups_ps_obj_t)); + + return (temp); +} + + +/* + * 'roll_stack()' - Rotate stack objects. + */ + +static int /* O - 0 on success, -1 on error */ +roll_stack(_cups_ps_stack_t *st, /* I - Stack */ + int c, /* I - Number of objects */ + int s) /* I - Amount to shift */ +{ + _cups_ps_obj_t *temp; /* Temporary array of objects */ + int n; /* Index into array */ + + + DEBUG_printf((" roll_stack(st=%p, s=%d, c=%d)\n", st, s, c)); + + /* + * Range check input... + */ + + if (c < 0) + return (-1); + else if (c == 0) + return (0); + + if ((n = st->num_objs - c) < 0) + return (-1); + + s %= c; + + if (s == 0) + return (0); + + /* + * Copy N objects and move things around... + */ + + if (s < 0) + { + /* + * Shift down... + */ + + s = -s; + + if ((temp = calloc(s, sizeof(_cups_ps_obj_t))) == NULL) + return (-1); + + memcpy(temp, st->objs + n, s * sizeof(_cups_ps_obj_t)); + memmove(st->objs + n, st->objs + n + s, (c - s) * sizeof(_cups_ps_obj_t)); + memcpy(st->objs + n + c - s, temp, s * sizeof(_cups_ps_obj_t)); + } + else + { + /* + * Shift up... + */ + + if ((temp = calloc(s, sizeof(_cups_ps_obj_t))) == NULL) + return (-1); + + memcpy(temp, st->objs + n + c - s, s * sizeof(_cups_ps_obj_t)); + memmove(st->objs + n + s, st->objs + n, + (c - s) * sizeof(_cups_ps_obj_t)); + memcpy(st->objs + n, temp, s * sizeof(_cups_ps_obj_t)); + } + + free(temp); + + return (0); +} + + +/* + * 'scan_ps()' - Scan a string for the next PS object. + */ + +static _cups_ps_obj_t * /* O - New object or NULL on EOF */ +scan_ps(_cups_ps_stack_t *st, /* I - Stack */ + char **ptr) /* IO - String pointer */ +{ + _cups_ps_obj_t obj; /* Current object */ + char *start, /* Start of object */ + *cur, /* Current position */ + *valptr, /* Pointer into value string */ + *valend; /* End of value string */ + int parens; /* Parenthesis nesting level */ + + + /* + * Skip leading whitespace... + */ + + for (cur = *ptr; *cur; cur ++) + { + if (*cur == '%') + { + /* + * Comment, skip to end of line... + */ + + for (cur ++; *cur && *cur != '\n' && *cur != '\r'; cur ++); + + if (!*cur) + cur --; + } + else if (!isspace(*cur & 255)) + break; + } + + if (!*cur) + { + *ptr = NULL; + + return (NULL); + } + + /* + * See what we have... + */ + + memset(&obj, 0, sizeof(obj)); + + switch (*cur) + { + case '(' : /* (string) */ + obj.type = CUPS_PS_STRING; + start = cur; + + for (cur ++, parens = 1, valptr = obj.value.string, + valend = obj.value.string + sizeof(obj.value.string) - 1; + *cur; + cur ++) + { + if (*cur == ')' && parens == 1) + break; + + if (*cur == '(') + parens ++; + else if (*cur == ')') + parens --; + + if (valptr >= valend) + { + *ptr = start; + + return (NULL); + } + + if (*cur == '\\') + { + /* + * Decode escaped character... + */ + + cur ++; + + if (*cur == 'b') + *valptr++ = '\b'; + else if (*cur == 'f') + *valptr++ = '\f'; + else if (*cur == 'n') + *valptr++ = '\n'; + else if (*cur == 'r') + *valptr++ = '\r'; + else if (*cur == 't') + *valptr++ = '\t'; + else if (*cur >= '0' && *cur <= '7') + { + int ch = *cur - '0'; + + if (cur[1] >= '0' && cur[1] <= '7') + { + cur ++; + ch = (ch << 3) + *cur - '0'; + } + + if (cur[1] >= '0' && cur[1] <= '7') + { + cur ++; + ch = (ch << 3) + *cur - '0'; + } + + *valptr++ = ch; + } + else if (*cur == '\r') + { + if (cur[1] == '\n') + cur ++; + } + else if (*cur != '\n') + *valptr++ = *cur; + } + else + *valptr++ = *cur; + } + + if (*cur != ')') + { + *ptr = start; + + return (NULL); + } + + cur ++; + break; + + case '[' : /* Start array */ + obj.type = CUPS_PS_START_ARRAY; + cur ++; + break; + + case ']' : /* End array */ + obj.type = CUPS_PS_END_ARRAY; + cur ++; + break; + + case '<' : /* Start dictionary or hex string */ + if (cur[1] == '<') + { + obj.type = CUPS_PS_START_DICT; + cur += 2; + } + else + { + obj.type = CUPS_PS_STRING; + start = cur; + + for (cur ++, valptr = obj.value.string, + valend = obj.value.string + sizeof(obj.value.string) - 1; + *cur; + cur ++) + { + int ch; /* Current character */ + + + + if (*cur == '>') + break; + else if (valptr >= valend || !isxdigit(*cur & 255)) + { + *ptr = start; + return (NULL); + } + + if (*cur >= '0' && *cur <= '9') + ch = (*cur - '0') << 4; + else + ch = (tolower(*cur) - 'a' + 10) << 4; + + if (isxdigit(cur[1] & 255)) + { + cur ++; + + if (*cur >= '0' && *cur <= '9') + ch |= *cur - '0'; + else + ch |= tolower(*cur) - 'a' + 10; + } + + *valptr++ = ch; + } + + if (*cur != '>') + { + *ptr = start; + return (NULL); + } + + cur ++; + } + break; + + case '>' : /* End dictionary? */ + if (cur[1] == '>') + { + obj.type = CUPS_PS_END_DICT; + cur += 2; + } + else + { + obj.type = CUPS_PS_OTHER; + obj.value.other[0] = *cur; + + cur ++; + } + break; + + case '{' : /* Start procedure */ + obj.type = CUPS_PS_START_PROC; + cur ++; + break; + + case '}' : /* End procedure */ + obj.type = CUPS_PS_END_PROC; + cur ++; + break; + + case '-' : /* Possible number */ + case '+' : + if (!isdigit(cur[1] & 255) && cur[1] != '.') + { + obj.type = CUPS_PS_OTHER; + obj.value.other[0] = *cur; + + cur ++; + break; + } + + case '0' : /* Number */ + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + case '8' : + case '9' : + case '.' : + obj.type = CUPS_PS_NUMBER; + + start = cur; + for (cur ++; *cur; cur ++) + if (!isdigit(*cur & 255)) + break; + + if (*cur == '#') + { + /* + * Integer with radix... + */ + + obj.value.number = strtol(cur + 1, &cur, atoi(start)); + break; + } + else if (strchr(".Ee()<>[]{}/%", *cur) || isspace(*cur & 255)) + { + /* + * Integer or real number... + */ + + obj.value.number = _cupsStrScand(start, &cur, localeconv()); + break; + } + else + cur = start; + + default : /* Operator/variable name */ + start = cur; + + if (*cur == '/') + { + obj.type = CUPS_PS_NAME; + valptr = obj.value.name; + valend = obj.value.name + sizeof(obj.value.name) - 1; + cur ++; + } + else + { + obj.type = CUPS_PS_OTHER; + valptr = obj.value.other; + valend = obj.value.other + sizeof(obj.value.other) - 1; + } + + while (*cur) + { + if (strchr("()<>[]{}/%", *cur) || isspace(*cur & 255)) + break; + else if (valptr < valend) + *valptr++ = *cur++; + else + { + *ptr = start; + return (NULL); + } + } + + if (obj.type == CUPS_PS_OTHER) + { + if (!strcmp(obj.value.other, "true")) + { + obj.type = CUPS_PS_BOOLEAN; + obj.value.boolean = 1; + } + else if (!strcmp(obj.value.other, "false")) + { + obj.type = CUPS_PS_BOOLEAN; + obj.value.boolean = 0; + } + else if (!strcmp(obj.value.other, "null")) + obj.type = CUPS_PS_NULL; + else if (!strcmp(obj.value.other, "cleartomark")) + obj.type = CUPS_PS_CLEARTOMARK; + else if (!strcmp(obj.value.other, "copy")) + obj.type = CUPS_PS_COPY; + else if (!strcmp(obj.value.other, "dup")) + obj.type = CUPS_PS_DUP; + else if (!strcmp(obj.value.other, "index")) + obj.type = CUPS_PS_INDEX; + else if (!strcmp(obj.value.other, "pop")) + obj.type = CUPS_PS_POP; + else if (!strcmp(obj.value.other, "roll")) + obj.type = CUPS_PS_ROLL; + else if (!strcmp(obj.value.other, "setpagedevice")) + obj.type = CUPS_PS_SETPAGEDEVICE; + else if (!strcmp(obj.value.other, "stopped")) + obj.type = CUPS_PS_STOPPED; + } + break; + } + + /* + * Save the current position in the string and return the new object... + */ + + *ptr = cur; + + return (push_stack(st, &obj)); +} + + +/* + * 'setpagedevice()' - Simulate the PostScript setpagedevice operator. + */ + +static int /* O - 0 on success, -1 on error */ +setpagedevice( + _cups_ps_stack_t *st, /* I - Stack */ + cups_page_header2_t *h, /* O - Page header */ + int *preferred_bits)/* O - Preferred bits per color */ +{ + int i; /* Index into array */ + _cups_ps_obj_t *obj, /* Current object */ + *end; /* End of dictionary */ + const char *name; /* Attribute name */ + + + /* + * Make sure we have a dictionary on the stack... + */ + + if (st->num_objs == 0) + return (-1); + + obj = end = st->objs + st->num_objs - 1; + + if (obj->type != CUPS_PS_END_DICT) + return (-1); + + obj --; + + while (obj > st->objs) + { + if (obj->type == CUPS_PS_START_DICT) + break; + + obj --; + } + + if (obj < st->objs) + return (-1); + + /* + * Found the start of the dictionary, empty the stack to this point... + */ + + st->num_objs = obj - st->objs; + + /* + * Now pull /name and value pairs from the dictionary... + */ + + DEBUG_puts("setpagedevice: Dictionary:"); + + for (obj ++; obj < end; obj ++) + { + /* + * Grab the name... + */ + + if (obj->type != CUPS_PS_NAME) + return (-1); + + name = obj->value.name; + obj ++; + +#ifdef DEBUG + DEBUG_printf(("setpagedevice: /%s ", name)); + DEBUG_object(obj); +#endif /* DEBUG */ + + /* + * Then grab the value... + */ + + if (!strcmp(name, "MediaClass") && obj->type == CUPS_PS_STRING) + strlcpy(h->MediaClass, obj->value.string, sizeof(h->MediaClass)); + else if (!strcmp(name, "MediaColor") && obj->type == CUPS_PS_STRING) + strlcpy(h->MediaColor, obj->value.string, sizeof(h->MediaColor)); + else if (!strcmp(name, "MediaType") && obj->type == CUPS_PS_STRING) + strlcpy(h->MediaType, obj->value.string, sizeof(h->MediaType)); + else if (!strcmp(name, "OutputType") && obj->type == CUPS_PS_STRING) + strlcpy(h->OutputType, obj->value.string, sizeof(h->OutputType)); + else if (!strcmp(name, "AdvanceDistance") && obj->type == CUPS_PS_NUMBER) + h->AdvanceDistance = (unsigned)obj->value.number; + else if (!strcmp(name, "AdvanceMedia") && obj->type == CUPS_PS_NUMBER) + h->AdvanceMedia = (unsigned)obj->value.number; + else if (!strcmp(name, "Collate") && obj->type == CUPS_PS_BOOLEAN) + h->Collate = (unsigned)obj->value.boolean; + else if (!strcmp(name, "CutMedia") && obj->type == CUPS_PS_NUMBER) + h->CutMedia = (cups_cut_t)(unsigned)obj->value.number; + else if (!strcmp(name, "Duplex") && obj->type == CUPS_PS_BOOLEAN) + h->Duplex = (unsigned)obj->value.boolean; + else if (!strcmp(name, "HWResolution") && obj->type == CUPS_PS_START_ARRAY) + { + if (obj[1].type == CUPS_PS_NUMBER && obj[2].type == CUPS_PS_NUMBER && + obj[3].type == CUPS_PS_END_ARRAY) + { + h->HWResolution[0] = (unsigned)obj[1].value.number; + h->HWResolution[1] = (unsigned)obj[2].value.number; + obj += 3; + } + else + return (-1); + } + else if (!strcmp(name, "InsertSheet") && obj->type == CUPS_PS_BOOLEAN) + h->InsertSheet = (unsigned)obj->value.boolean; + else if (!strcmp(name, "Jog") && obj->type == CUPS_PS_NUMBER) + h->Jog = (unsigned)obj->value.number; + else if (!strcmp(name, "LeadingEdge") && obj->type == CUPS_PS_NUMBER) + h->LeadingEdge = (unsigned)obj->value.number; + else if (!strcmp(name, "ManualFeed") && obj->type == CUPS_PS_BOOLEAN) + h->ManualFeed = (unsigned)obj->value.boolean; + else if ((!strcmp(name, "cupsMediaPosition") || + !strcmp(name, "MediaPosition")) && obj->type == CUPS_PS_NUMBER) + { + /* + * cupsMediaPosition is supported for backwards compatibility only. + * We added it back in the Ghostscript 5.50 days to work around a + * bug in Ghostscript WRT handling of MediaPosition and setpagedevice. + * + * All new development should set MediaPosition... + */ + + h->MediaPosition = (unsigned)obj->value.number; + } + else if (!strcmp(name, "MediaWeight") && obj->type == CUPS_PS_NUMBER) + h->MediaWeight = (unsigned)obj->value.number; + else if (!strcmp(name, "MirrorPrint") && obj->type == CUPS_PS_BOOLEAN) + h->MirrorPrint = (unsigned)obj->value.boolean; + else if (!strcmp(name, "NegativePrint") && obj->type == CUPS_PS_BOOLEAN) + h->NegativePrint = (unsigned)obj->value.boolean; + else if (!strcmp(name, "NumCopies") && obj->type == CUPS_PS_NUMBER) + h->NumCopies = (unsigned)obj->value.number; + else if (!strcmp(name, "Orientation") && obj->type == CUPS_PS_NUMBER) + h->Orientation = (unsigned)obj->value.number; + else if (!strcmp(name, "OutputFaceUp") && obj->type == CUPS_PS_BOOLEAN) + h->OutputFaceUp = (unsigned)obj->value.boolean; + else if (!strcmp(name, "PageSize") && obj->type == CUPS_PS_START_ARRAY) + { + if (obj[1].type == CUPS_PS_NUMBER && obj[2].type == CUPS_PS_NUMBER && + obj[3].type == CUPS_PS_END_ARRAY) + { + h->cupsPageSize[0] = obj[1].value.number; + h->cupsPageSize[1] = obj[2].value.number; + + h->PageSize[0] = (unsigned)obj[1].value.number; + h->PageSize[1] = (unsigned)obj[2].value.number; + + obj += 3; + } + else + return (-1); + } + else if (!strcmp(name, "Separations") && obj->type == CUPS_PS_BOOLEAN) + h->Separations = (unsigned)obj->value.boolean; + else if (!strcmp(name, "TraySwitch") && obj->type == CUPS_PS_BOOLEAN) + h->TraySwitch = (unsigned)obj->value.boolean; + else if (!strcmp(name, "Tumble") && obj->type == CUPS_PS_BOOLEAN) + h->Tumble = (unsigned)obj->value.boolean; + else if (!strcmp(name, "cupsMediaType") && obj->type == CUPS_PS_NUMBER) + h->cupsMediaType = (unsigned)obj->value.number; + else if (!strcmp(name, "cupsBitsPerColor") && obj->type == CUPS_PS_NUMBER) + h->cupsBitsPerColor = (unsigned)obj->value.number; + else if (!strcmp(name, "cupsPreferredBitsPerColor") && + obj->type == CUPS_PS_NUMBER) + *preferred_bits = (int)obj->value.number; + else if (!strcmp(name, "cupsColorOrder") && obj->type == CUPS_PS_NUMBER) + h->cupsColorOrder = (cups_order_t)(unsigned)obj->value.number; + else if (!strcmp(name, "cupsColorSpace") && obj->type == CUPS_PS_NUMBER) + h->cupsColorSpace = (cups_cspace_t)(unsigned)obj->value.number; + else if (!strcmp(name, "cupsCompression") && obj->type == CUPS_PS_NUMBER) + h->cupsCompression = (unsigned)obj->value.number; + else if (!strcmp(name, "cupsRowCount") && obj->type == CUPS_PS_NUMBER) + h->cupsRowCount = (unsigned)obj->value.number; + else if (!strcmp(name, "cupsRowFeed") && obj->type == CUPS_PS_NUMBER) + h->cupsRowFeed = (unsigned)obj->value.number; + else if (!strcmp(name, "cupsRowStep") && obj->type == CUPS_PS_NUMBER) + h->cupsRowStep = (unsigned)obj->value.number; + else if (!strcmp(name, "cupsBorderlessScalingFactor") && + obj->type == CUPS_PS_NUMBER) + h->cupsBorderlessScalingFactor = obj->value.number; + else if (!strncmp(name, "cupsInteger", 11) && obj->type == CUPS_PS_NUMBER) + { + if ((i = atoi(name + 11)) < 0 || i > 15) + return (-1); + + h->cupsInteger[i] = (unsigned)obj->value.number; + } + else if (!strncmp(name, "cupsReal", 8) && obj->type == CUPS_PS_NUMBER) + { + if ((i = atoi(name + 8)) < 0 || i > 15) + return (-1); + + h->cupsReal[i] = obj->value.number; + } + else if (!strncmp(name, "cupsString", 10) && obj->type == CUPS_PS_STRING) + { + if ((i = atoi(name + 10)) < 0 || i > 15) + return (-1); + + strlcpy(h->cupsString[i], obj->value.string, sizeof(h->cupsString[i])); + } + else if (!strcmp(name, "cupsMarkerType") && obj->type == CUPS_PS_STRING) + strlcpy(h->cupsMarkerType, obj->value.string, sizeof(h->cupsMarkerType)); + else if (!strcmp(name, "cupsPageSizeName") && obj->type == CUPS_PS_STRING) + strlcpy(h->cupsPageSizeName, obj->value.string, + sizeof(h->cupsPageSizeName)); + else if (!strcmp(name, "cupsRenderingIntent") && + obj->type == CUPS_PS_STRING) + strlcpy(h->cupsRenderingIntent, obj->value.string, + sizeof(h->cupsRenderingIntent)); + else + { + /* + * Ignore unknown name+value... + */ + + DEBUG_printf((" Unknown name (\"%s\") or value...\n", name)); + + while (obj[1].type != CUPS_PS_NAME && obj < end) + obj ++; + } + } + + return (0); +} + + +#ifdef DEBUG +/* + * 'DEBUG_object()' - Print an object's value... + */ + +static void +DEBUG_object(_cups_ps_obj_t *obj) /* I - Object to print */ +{ + switch (obj->type) + { + case CUPS_PS_NAME : + DEBUG_printf(("/%s\n", obj->value.name)); + break; + + case CUPS_PS_NUMBER : + DEBUG_printf(("%g\n", obj->value.number)); + break; + + case CUPS_PS_STRING : + DEBUG_printf(("(%s)\n", obj->value.string)); + break; + + case CUPS_PS_BOOLEAN : + if (obj->value.boolean) + DEBUG_puts("true"); + else + DEBUG_puts("false"); + break; + + case CUPS_PS_NULL : + DEBUG_puts("null"); + break; + + case CUPS_PS_START_ARRAY : + DEBUG_puts("["); + break; + + case CUPS_PS_END_ARRAY : + DEBUG_puts("]"); + break; + + case CUPS_PS_START_DICT : + DEBUG_puts("<<"); + break; + + case CUPS_PS_END_DICT : + DEBUG_puts(">>"); + break; + + case CUPS_PS_START_PROC : + DEBUG_puts("{"); + break; + + case CUPS_PS_END_PROC : + DEBUG_puts("}"); + break; + + case CUPS_PS_CLEARTOMARK : + DEBUG_puts("--cleartomark--"); + break; + + case CUPS_PS_COPY : + DEBUG_puts("--copy--"); + break; + + case CUPS_PS_DUP : + DEBUG_puts("--dup--"); + break; + + case CUPS_PS_INDEX : + DEBUG_puts("--index--"); + break; + + case CUPS_PS_POP : + DEBUG_puts("--pop--"); + break; + + case CUPS_PS_ROLL : + DEBUG_puts("--roll--"); + break; + + case CUPS_PS_SETPAGEDEVICE : + DEBUG_puts("--setpagedevice--"); + break; + + case CUPS_PS_STOPPED : + DEBUG_puts("--stopped--"); + break; + + case CUPS_PS_OTHER : + DEBUG_printf(("--%s--\n", obj->value.other)); + break; + } +} + + +/* + * 'DEBUG_stack()' - Print a stack... + */ + +static void +DEBUG_stack(_cups_ps_stack_t *st) /* I - Stack */ +{ + int c; /* Looping var */ + _cups_ps_obj_t *obj; /* Current object on stack */ + + + for (obj = st->objs, c = st->num_objs; c > 0; c --, obj ++) + DEBUG_object(obj); +} +#endif /* DEBUG */ + + +/* + * End of "$Id$". + */ diff --git a/filter/libcupsimage.order b/filter/libcupsimage.order new file mode 100755 index 0000000000..92820f7c2b --- /dev/null +++ b/filter/libcupsimage.order @@ -0,0 +1 @@ +single module:dyld_stub_binding_helper diff --git a/filter/libcupsimage2.def b/filter/libcupsimage2.def new file mode 100644 index 0000000000..001c7b52c9 --- /dev/null +++ b/filter/libcupsimage2.def @@ -0,0 +1,13 @@ +LIBRARY libcupsimage2 +VERSION 2.2 +EXPORTS +cupsRasterClose +cupsRasterErrorString +cupsRasterInterpretPPD +cupsRasterOpen +cupsRasterReadHeader +cupsRasterReadHeader2 +cupsRasterReadPixels +cupsRasterWriteHeader +cupsRasterWriteHeader2 +cupsRasterWritePixels diff --git a/filter/libcupsimage_s.exp b/filter/libcupsimage_s.exp new file mode 100644 index 0000000000..57f4259f99 --- /dev/null +++ b/filter/libcupsimage_s.exp @@ -0,0 +1,16 @@ +_cupsImagePutCol +_cupsImagePutRow +_cupsImageReadBMP +_cupsImageReadGIF +_cupsImageReadJPEG +_cupsImageReadPIX +_cupsImageReadPNG +_cupsImageReadPNM +_cupsImageReadPhotoCD +_cupsImageReadSGI +_cupsImageReadSunRaster +_cupsImageReadTIFF +_cupsImageZoomDelete +_cupsImageZoomFill +_cupsImageZoomNew +_cupsRasterExecPS diff --git a/filter/pdftops.c b/filter/pdftops.c new file mode 100644 index 0000000000..221aeb760b --- /dev/null +++ b/filter/pdftops.c @@ -0,0 +1,599 @@ +/* + * "$Id$" + * + * PDF to PostScript filter front-end for the Common UNIX Printing + * System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry for filter... + * cancel_job() - Flag the job as canceled. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static void cancel_job(int sig); + + +/* + * Local globals... + */ + +static int job_canceled = 0; + + +/* + * 'main()' - Main entry for filter... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int fd; /* Copy file descriptor */ + char *filename, /* PDF file to convert */ + tempfile[1024]; /* Temporary file */ + char buffer[8192]; /* Copy buffer */ + int bytes; /* Bytes copied */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + const char *val; /* Option value */ + int orientation, /* Output orientation */ + fit; /* Fit output to default page size? */ + ppd_file_t *ppd; /* PPD file */ + ppd_size_t *size; /* Current page size */ + int pdf_pid, /* Process ID for pdftops */ + pdf_argc, /* Number of args for pdftops */ + pstops_pid, /* Process ID of pstops filter */ + pstops_pipe[2], /* Pipe to pstops filter */ + wait_children, /* Number of child processes left */ + wait_pid, /* Process ID from wait() */ + wait_status, /* Status from child */ + exit_status = 0; /* Exit status */ + char *pdf_argv[100], /* Arguments for pdftops/gs */ + pdf_width[255], /* Paper width */ + pdf_height[255], /* Paper height */ + pstops_path[1024], /* Path to pstops program */ + *pstops_argv[7], /* Arguments for pstops filter */ + *pstops_options, /* Options for pstops filter */ + *pstops_start, /* Start of pstops filter option */ + *pstops_end; /* End of pstops filter option */ + const char *cups_serverbin; /* CUPS_SERVERBIN environment variable */ +#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); + + /* + * Make sure we have the right number of arguments for CUPS! + */ + + if (argc < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job user title copies options [filename]\n"), + argv[0]); + return (1); + } + + /* + * Register a signal handler to cleanly cancel a job. + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, cancel_job); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = cancel_job; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, cancel_job); +#endif /* HAVE_SIGSET */ + + /* + * Copy stdin if needed... + */ + + if (argc == 6) + { + /* + * Copy stdin to a temp file... + */ + + if ((fd = cupsTempFd(tempfile, sizeof(tempfile))) < 0) + { + _cupsLangPrintError(_("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) + write(fd, buffer, bytes); + + close(fd); + + filename = tempfile; + } + else + { + /* + * Use the filename on the command-line... + */ + + filename = argv[6]; + tempfile[0] = '\0'; + } + + /* + * Load the PPD file and mark options... + */ + + ppd = ppdOpenFile(getenv("PPD")); + num_options = cupsParseOptions(argv[5], 0, &options); + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + /* + * Build the pstops command-line... + */ + + if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL) + cups_serverbin = CUPS_SERVERBIN; + + snprintf(pstops_path, sizeof(pstops_path), "%s/filter/pstops", + cups_serverbin); + + pstops_options = strdup(argv[5]); + + if ((pstops_start = strstr(pstops_options, "fitplot")) != NULL && + (!pstops_start[7] || isspace(pstops_start[7] & 255))) + { + /* + * Strip [no]fitplot option... + */ + + pstops_end = pstops_start + 7; + + if ((pstops_start - pstops_options) >= 2 && + !strncmp(pstops_start - 2, "no", 2)) + pstops_start -= 2; + + while (*pstops_end && isspace(*pstops_end & 255)) + pstops_end ++; + + _cups_strcpy(pstops_start, pstops_end); + } + + if ((pstops_start = strstr(pstops_options, "fit-to-page")) != NULL && + (!pstops_start[11] || isspace(pstops_start[11] & 255))) + { + /* + * Strip [no]fit-to-page option... + */ + + pstops_end = pstops_start + 11; + + if ((pstops_start - pstops_options) >= 2 && + !strncmp(pstops_start - 2, "no", 2)) + pstops_start -= 2; + + while (*pstops_end && isspace(*pstops_end & 255)) + pstops_end ++; + + _cups_strcpy(pstops_start, pstops_end); + } + + if ((pstops_start = strstr(pstops_options, "landscape")) != NULL && + (!pstops_start[9] || isspace(pstops_start[9] & 255))) + { + /* + * Strip [no]landscape option... + */ + + pstops_end = pstops_start + 9; + + if ((pstops_start - pstops_options) >= 2 && + !strncmp(pstops_start - 2, "no", 2)) + pstops_start -= 2; + + while (*pstops_end && isspace(*pstops_end & 255)) + pstops_end ++; + + _cups_strcpy(pstops_start, pstops_end); + } + + if ((pstops_start = strstr(pstops_options, "orientation-requested=")) != NULL) + { + /* + * Strip [no]fitplot option... + */ + + pstops_end = pstops_start + 22; + while (*pstops_end && !isspace(*pstops_end & 255)) + pstops_end ++; + + _cups_strcpy(pstops_start, pstops_end); + } + + pstops_argv[0] = argv[0]; /* Printer */ + pstops_argv[1] = argv[1]; /* Job */ + pstops_argv[2] = argv[2]; /* User */ + pstops_argv[3] = argv[3]; /* Title */ + pstops_argv[4] = argv[4]; /* Copies */ + pstops_argv[5] = pstops_options; /* Options */ + pstops_argv[6] = NULL; + + /* + * Build the command-line for the pdftops or gs filter... + */ + +#ifdef HAVE_PDFTOPS + pdf_argv[0] = (char *)"pdftops"; + pdf_argc = 1; +#else + pdf_argv[0] = (char *)"gs"; + pdf_argv[1] = (char *)"-q"; + pdf_argv[2] = (char *)"-dNOPAUSE"; + pdf_argv[3] = (char *)"-dBATCH"; + pdf_argv[4] = (char *)"-dSAFER"; + pdf_argv[5] = (char *)"-sDEVICE=pswrite"; + pdf_argv[6] = (char *)"-sOUTPUTFILE=%stdout"; + pdf_argc = 7; +#endif /* HAVE_PDFTOPS */ + + if (ppd) + { + /* + * Set language level and TrueType font handling... + */ + + if (ppd->language_level == 1) + { +#ifdef HAVE_PDFTOPS + pdf_argv[pdf_argc++] = (char *)"-level1"; + pdf_argv[pdf_argc++] = (char *)"-noembtt"; +#else + pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=1"; +#endif /* HAVE_PDFTOPS */ + } + else if (ppd->language_level == 2) + { +#ifdef HAVE_PDFTOPS + pdf_argv[pdf_argc++] = (char *)"-level2"; + if (!ppd->ttrasterizer) + pdf_argv[pdf_argc++] = (char *)"-noembtt"; +#else + pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=2"; +#endif /* HAVE_PDFTOPS */ + } + else +#ifdef HAVE_PDFTOPS + pdf_argv[pdf_argc++] = (char *)"-level3"; +#else + pdf_argv[pdf_argc++] = (char *)"-dLanguageLevel=3"; +#endif /* HAVE_PDFTOPS */ + + if ((val = cupsGetOption("fitplot", num_options, options)) == NULL) + val = cupsGetOption("fit-to-page", num_options, options); + + if (val && strcasecmp(val, "no") && strcasecmp(val, "off") && + strcasecmp(val, "false")) + fit = 1; + else + fit = 0; + + /* + * Set output page size... + */ + + size = ppdPageSize(ppd, NULL); + if (size && fit) + { + /* + * Got the size, now get the orientation... + */ + + orientation = 0; + + if ((val = cupsGetOption("landscape", num_options, options)) != NULL) + { + if (strcasecmp(val, "no") != 0 && strcasecmp(val, "off") != 0 && + strcasecmp(val, "false") != 0) + orientation = 1; + } + else 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; + } + +#ifdef HAVE_PDFTOPS + if (orientation & 1) + { + snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->length); + snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->width); + } + else + { + snprintf(pdf_width, sizeof(pdf_width), "%.0f", size->width); + snprintf(pdf_height, sizeof(pdf_height), "%.0f", size->length); + } + + pdf_argv[pdf_argc++] = (char *)"-paperw"; + pdf_argv[pdf_argc++] = pdf_width; + pdf_argv[pdf_argc++] = (char *)"-paperh"; + pdf_argv[pdf_argc++] = pdf_height; + pdf_argv[pdf_argc++] = (char *)"-expand"; + +#else + if (orientation & 1) + { + snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f", + size->length); + snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f", + size->width); + } + else + { + snprintf(pdf_width, sizeof(pdf_width), "-dDEVICEWIDTHPOINTS=%.0f", + size->width); + snprintf(pdf_height, sizeof(pdf_height), "-dDEVICEHEIGHTPOINTS=%.0f", + size->length); + } + + pdf_argv[pdf_argc++] = pdf_width; + pdf_argv[pdf_argc++] = pdf_height; +#endif /* HAVE_PDFTOPS */ + } + } + +#ifdef HAVE_PDFTOPS + pdf_argv[pdf_argc++] = filename; + pdf_argv[pdf_argc++] = (char *)"-"; +#else + pdf_argv[pdf_argc++] = (char *)"-c"; + pdf_argv[pdf_argc++] = (char *)"save pop"; + pdf_argv[pdf_argc++] = (char *)"-f"; + pdf_argv[pdf_argc++] = filename; +#endif /* HAVE_PDFTOPS */ + + pdf_argv[pdf_argc] = NULL; + + /* + * Execute "pdftops/gs | pstops"... + */ + + if (pipe(pstops_pipe)) + { + _cupsLangPrintError(_("ERROR: Unable to create pipe")); + + exit_status = 1; + goto error; + } + + if ((pdf_pid = fork()) == 0) + { + /* + * Child comes here... + */ + + dup2(pstops_pipe[1], 1); + close(pstops_pipe[0]); + close(pstops_pipe[1]); + +#ifdef HAVE_PDFTOPS + execv(CUPS_PDFTOPS, pdf_argv); + _cupsLangPrintError(_("ERROR: Unable to execute pdftops program")); +#else + execv(CUPS_GHOSTSCRIPT, pdf_argv); + _cupsLangPrintError(_("ERROR: Unable to execute gs program")); +#endif /* HAVE_PDFTOPS */ + + exit(1); + } + else if (pdf_pid < 0) + { + /* + * Unable to fork! + */ + +#ifdef HAVE_PDFTOPS + _cupsLangPrintError(_("ERROR: Unable to execute pdftops program")); +#else + _cupsLangPrintError(_("ERROR: Unable to execute gs program")); +#endif /* HAVE_PDFTOPS */ + + exit_status = 1; + goto error; + } + + fprintf(stderr, "DEBUG: Started filter %s (PID %d)\n", pdf_argv[0], pdf_pid); + + if ((pstops_pid = fork()) == 0) + { + /* + * Child comes here... + */ + + dup2(pstops_pipe[0], 0); + close(pstops_pipe[0]); + close(pstops_pipe[1]); + + execv(pstops_path, pstops_argv); + _cupsLangPrintError(_("ERROR: Unable to execute pstops program")); + + exit(1); + } + else if (pstops_pid < 0) + { + /* + * Unable to fork! + */ + + _cupsLangPrintError(_("ERROR: Unable to execute pstops program")); + + exit_status = 1; + goto error; + } + + fprintf(stderr, "DEBUG: Started filter pstops (PID %d)\n", pstops_pid); + + close(pstops_pipe[0]); + close(pstops_pipe[1]); + + /* + * Wait for the child processes to exit... + */ + + wait_children = 2; + + while (wait_children > 0) + { + /* + * Wait until we get a valid process ID or the job is canceled... + */ + + while ((wait_pid = wait(&wait_status)) < 0 && errno == EINTR) + { + if (job_canceled) + { + kill(pdf_pid, SIGTERM); + kill(pstops_pid, SIGTERM); + + job_canceled = 0; + } + } + + if (wait_pid < 0) + break; + + wait_children --; + + /* + * Report child status... + */ + + if (wait_status) + { + if (WIFEXITED(wait_status)) + { + exit_status = WEXITSTATUS(wait_status); + + fprintf(stderr, "DEBUG: PID %d (%s) stopped with status %d!\n", + wait_pid, +#ifdef HAVE_PDFTOPS + wait_pid == pdf_pid ? "pdftops" : "pstops", +#else + wait_pid == pdf_pid ? "gs" : "pstops", +#endif /* HAVE_PDFTOPS */ + exit_status); + } + else if (WTERMSIG(wait_status) == SIGTERM) + { + fprintf(stderr, + "DEBUG: PID %d (%s) was terminated normally with signal %d!\n", + wait_pid, +#ifdef HAVE_PDFTOPS + wait_pid == pdf_pid ? "pdftops" : "pstops", +#else + wait_pid == pdf_pid ? "gs" : "pstops", +#endif /* HAVE_PDFTOPS */ + exit_status); + } + else + { + exit_status = WTERMSIG(wait_status); + + fprintf(stderr, "DEBUG: PID %d (%s) crashed on signal %d!\n", wait_pid, +#ifdef HAVE_PDFTOPS + wait_pid == pdf_pid ? "pdftops" : "pstops", +#else + wait_pid == pdf_pid ? "gs" : "pstops", +#endif /* HAVE_PDFTOPS */ + exit_status); + } + } + else + { + fprintf(stderr, "DEBUG: PID %d (%s) exited with no errors.\n", wait_pid, +#ifdef HAVE_PDFTOPS + wait_pid == pdf_pid ? "pdftops" : "pstops"); +#else + wait_pid == pdf_pid ? "gs" : "pstops"); +#endif /* HAVE_PDFTOPS */ + } + } + + /* + * Cleanup and exit... + */ + + error: + + if (tempfile[0]) + unlink(tempfile); + + return (exit_status); +} + + +/* + * 'cancel_job()' - Flag the job as canceled. + */ + +static void +cancel_job(int sig) /* I - Signal number (unused) */ +{ + (void)sig; + + job_canceled = 1; +} + + +/* + * End of "$Id$". + */ diff --git a/filter/postscript-driver.header b/filter/postscript-driver.header new file mode 100644 index 0000000000..1f717ba098 --- /dev/null +++ b/filter/postscript-driver.header @@ -0,0 +1,17 @@ +

Developing PostScript Printer Drivers

+ +

This document describes how to develop printer drivers for PostScript printers. Topics include: printer driver basics, creating new PPD files, importing existing PPD files, using custom filters, implementing color management, and adding Mac OS X features.

+ +
+ + + + + + +
See AlsoProgramming: Developing Raster Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Introduction to the PPD Compiler
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
diff --git a/filter/postscript-driver.shtml b/filter/postscript-driver.shtml new file mode 100644 index 0000000000..439744f0fa --- /dev/null +++ b/filter/postscript-driver.shtml @@ -0,0 +1,276 @@ +

Printer Driver Basics

+ +

A CUPS PostScript printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, zero or more filter programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.

+ +

Every time a user prints something the scheduler program, cupsd(8), determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into device-independent PostScript, and then from device-independent PostScript to device-dependent PostScript. Figure 1 shows the data flow of a typical print job.

+ +
+ + +
Figure 1: PostScript Filter Chain
PostScript Filter Chain
+ +

The optional PostScript filter can be provided to add printer-specific commands to the PostScript output that cannot be represented in the PPD file or to reorganize the output for special printer features. Typically this is used to support advanced job management or finishing functions on the printer. CUPS includes a generic PostScript filter that handles all PPD-defined commands.

+ +

The optional port monitor handles interface-specific protocol or encoding issues. For example, many PostScript printers support the Binary Communications Protocol (BCP) and Tagged Binary Communications Protocol (TBCP) to allow applications to print 8-bit ("binary") PostScript jobs. CUPS includes port monitors for BCP and TBCP, and you can supply your own port monitors as needed.

+ +

The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.

+ +

The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. Figure 2 shows the data flow of a typical command job.

+ +
+ + +
Figure 2: Command Filter Chain
Command Filter Chain
+ +

PostScript printer drivers typically do not require their own command filter since CUPS includes a generic PostScript command filter that supports all of the standard functions using PPD-defined commands.

+ + +

Creating New PPD Files

+ +

We recommend using the CUPS PPD compiler, ppdc(1), to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "Introduction to the PPD Compiler" document. Listing 1 shows a driver information file for a black-and-white PostScript printer.

+ +

Listing 1: "examples/postscript.drv"

+ +
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// Specify this is a PostScript printer driver
+DriverType ps
+
+// List the fonts that are supported, in this case all standard fonts
+Font *
+
+// Manufacturer, model name, and version
+Manufacturer "Foo"
+ModelName "Foo LaserProofer 2000"
+Version 1.0
+
+// PostScript printer attributes
+Attribute DefaultColorSpace "" Gray
+Attribute LandscapeOrientation "" Minus90
+Attribute LanguageLevel "" "3"
+Attribute Product "" "(Foo LaserProofer 2000)"
+Attribute PSVersion "" "(3010) 0"
+Attribute TTRasterizer "" Type42
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize Legal
+MediaSize A4
+
+// Query command for page size
+Attribute "?PageSize" "" "
+      save
+      currentpagedevice /PageSize get aload pop
+      2 copy gt {exch} if (Unknown)
+      23 dict
+              dup [612 792] (Letter) put
+              dup [612 1008] (Legal) put
+              dup [595 842] (A4) put
+              {exch aload pop 4 index sub abs 5 le exch 
+               5 index sub abs 5 le and
+              {exch pop exit} {pop} ifelse
+      } bind forall = flush pop pop
+      restore"
+
+// Specify the name of the PPD file we want to generate
+PCFileName "fooproof.ppd"
+
+ +

Required Attributes

+ +

PostScript drivers require the attributes listed in Table 1. If not specified, the defaults for CUPS drivers are used. A typical PostScript driver information file would include the following attributes:

+ +
+Attribute DefaultColorSpace "" Gray
+Attribute LandscapeOrientation "" Minus90
+Attribute LanguageLevel "" "3"
+Attribute Product "" "(Foo LaserProofer 2000)"
+Attribute PSVersion "" "(3010) 0"
+Attribute TTRasterizer "" Type42
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Required PostScript Printer Driver Attributes
AttributeDescription
DefaultColorSpaceThe default colorspace: + Gray, RGB, CMY, or + CMYK. If not specified, then RGB is + assumed.
LandscapeOrientationThe preferred landscape + orientation: Plus90, Minus90, or + Any. If not specified, Plus90 is + assumed.
LanguageLevelThe PostScript language + level supported by the device: 1, 2, or 3. If not + specified, 2 is assumed.
ProductThe string returned by + the PostScript product operator, which + must include parenthesis to conform with + PostScript syntax rules for strings. Multiple + Product attributes may be specified to support + multiple products with the same PPD file. If not + specified, "(ESP Ghostscript)" and "(GNU Ghostscript)" + are assumed.
PSVersionThe PostScript + interpreter version numbers as returned by the + version and revision operators. The + required format is "(version) revision". Multiple + PSVersion attributes may be specified to + support multiple interpreter version numbers. If not + specified, "(3010) 705" and "(3010) 707" are + assumed.
TTRasterizerThe type of TrueType + font rasterizer supported by the device, if any. The + supported values are None, Accept68k, + Type42, and TrueImage. If not + specified, None is assumed.
+ +

Query Commands

+ +

Most PostScript printer PPD files include query commands (?PageSize, etc.) that allow applications to query the printer for its current settings and configuration. Query commands are included in driver information files as attributes. For example, the example in Listing 1 uses the following definition for the PageSize query command:

+ +
+Attribute "?PageSize" "" "
+      save
+      currentpagedevice /PageSize get aload pop
+      2 copy gt {exch} if (Unknown)
+      23 dict
+              dup [612 792] (Letter) put
+              dup [612 1008] (Legal) put
+              dup [595 842] (A4) put
+              {exch aload pop 4 index sub abs 5 le exch 
+               5 index sub abs 5 le and
+              {exch pop exit} {pop} ifelse
+      } bind forall = flush pop pop
+      restore"
+
+ +

Query commands can span multiple lines, however no single line may contain more than 255 characters.

+ +

Importing Existing PPD Files

+ +

CUPS includes a utility called ppdi(1) +which allows you to import existing PPD files into the driver information file +format used by the PPD compiler ppdc(1). Once +imported, you can modify, localize, and regenerate the PPD files easily. Type +the following command to import the PPD file mydevice.ppd into the +driver information file mydevice.drv:

+ +
+ppdi -o mydevice.drv mydevice.ppd
+
+ +

If you have a whole directory of PPD files that you would like to import, +you can list multiple filenames or use shell wildcards to import more than one +PPD file on the command-line:

+ +
+ppdi -o mydevice.drv mydevice1.ppd mydevice2.ppd
+ppdi -o mydevice.drv *.ppd
+
+ +

If the driver information file already exists, the new PPD +file entries are appended to the end of the file. Each PPD file +is placed in its own group of curly braces within the driver +information file.

+ + +

Using Custom Filters

+ +

Normally a PostScript printer driver will not utilize any additional print filters. For drivers that provide additional filters such as a CUPS command file filter for doing printer maintenance, you must also list the following Filter directive to handle printing PostScript files:

+ +
+Filter application/vnd.cups-postscript 0 -
+
+ +

Custom Command Filters

+ +

The application/vnd.cups-command file type is used for CUPS command files. Use the following Filter directive to handle CUPS command files:

+ +
+Filter application/vnd.cups-command 100 /path/to/command/filter
+
+ +

To use the standard PostScript command filter, specify commandtops as the path to the command filter.

+ +

Custom PDF Filters

+ +

The application/pdf file type is used for unfiltered PDF files while the application/vnd.cups-pdf file type is used for filtered PDF files. Use the following Filter directive to handle filtered PDF files:

+ +
+Filter application/vnd.cups-pdf 100 /path/to/pdf/filter
+
+ +

For unfiltered PDF files, use:

+ +
+Filter application/pdf 100 /path/to/pdf/filter
+
+ +

Custom PDF filters that accept filtered data do not need to perform number-up processing and other types of page imposition, while those that accept unfiltered data MUST do the number-up processing themselves.

+ +

Custom PostScript Filters

+ +

The application/vnd.cups-postscript file type is used for filtered PostScript files. Use the following Filter directive to handle PostScript files:

+ +
+Filter application/vnd.cups-postscript 100 /path/to/postscript/filter
+
+ + +

Implementing Color Management

+ +

CUPS uses ICC color profiles to provide more accurate color reproduction. The cupsICCProfile attribute defines the color profiles that are available for a given printer, for example:

+ +
+Attribute cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
+
+ +

where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:

+ +
+Attribute cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
+Attribute cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
+
+ +

The options used for profile selection can be customized using the cupsICCQualifier2 and cupsICCQualifier3 attributes.

+ + +

Adding Mac OS X Features

+ +

Mac OS X printer drivers can provide additional attributes to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:

+ +
+Attribute APDialogExtension "" /Library/Printers/Vendor/filename.plugin
+Attribute APHelpBook "" /Library/Printers/Vendor/filename.bundle
+Attribute APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
+Attribute APPrinterPreset "name/text" "*option choice ..."
+
diff --git a/filter/ppd-compiler.header b/filter/ppd-compiler.header new file mode 100644 index 0000000000..6afe1b4f04 --- /dev/null +++ b/filter/ppd-compiler.header @@ -0,0 +1,19 @@ +

Introduction to the PPD Compiler

+ +

This document describes how to use the CUPS PostScript Printer Description +(PPD) file compiler. The PPD compiler generates PPD files from simple text files +that describe the features and capabilities of one or more printers.

+ +
+ + + + + + +
See AlsoProgramming: Developing Raster Printer Drivers
+ Programming: Developing PostScript Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
diff --git a/filter/ppd-compiler.shtml b/filter/ppd-compiler.shtml new file mode 100644 index 0000000000..c98b95cee6 --- /dev/null +++ b/filter/ppd-compiler.shtml @@ -0,0 +1,883 @@ +

The Basics

+ +

The PPD compiler, ppdc(1), is a +simple command-line tool that takes a single driver information file, +which by convention uses the extension .drv, and produces one or more +PPD files that may be distributed with your printer drivers for use with CUPS. +For example, you would run the following command to create the English language +PPD files defined by the driver information file mydrivers.drv:

+ +
+ppdc mydrivers.drv
+
+ +

The PPD files are placed in a subdirectory called +ppd. The -d option is used to put the PPD +files in a different location, for example:

+ +
+ppdc -d myppds mydrivers.drv
+
+ +

places the PPD files in a subdirectory named +myppds. Finally, use the -l option to +specify the language localization for the PPD files that are +created, for example:

+ +
+ppdc -d myppds/de -l de mydrivers.drv
+ppdc -d myppds/en -l en mydrivers.drv
+ppdc -d myppds/es -l es mydrivers.drv
+ppdc -d myppds/fr -l fr mydrivers.drv
+ppdc -d myppds/it -l it mydrivers.drv
+
+ +

creates PPD files in German (de), English (en), Spanish (es), +French (fr), and Italian (it) in the corresponding +subdirectories. Specify multiple languages (separated by commas) to produce +"globalized" PPD files:

+ +
+ppdc -d myppds -l de,en,es,fr,it mydrivers.drv
+
+ + +

Driver Information Files

+ +

The driver information files accepted by the PPD compiler are +plain text files that define the various attributes and options +that are included in the PPD files that are generated. A driver +information file can define the information for one or more printers and +their corresponding PPD files.

+ +

Listing 1: "examples/minimum.drv"

+ +
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// List the fonts that are supported, in this case all standard fonts...
+Font *
+
+// Manufacturer, model name, and version
+Manufacturer "Foo"
+ModelName "FooJet 2000"
+Version 1.0
+
+// Each filter provided by the driver...
+Filter application/vnd.cups-raster 100 rastertofoo
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize A4
+
+// Supported resolutions
+*Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+// Specify the name of the PPD file we want to generate...
+PCFileName "foojet2k.ppd"
+
+ + +

A Simple Example

+ +

The example in Listing 1 shows a driver information +file which defines the minimum required attributes to provide a valid PPD file. +The first part of the file includes standard definition files for fonts and +media sizes:

+ +
+#include <font.defs>
+#include <media.defs>
+
+ +

The #include directive works just like the C/C++ include directive; +files included using the angle brackets (<filename>) are found +in any of the standard include directories and files included using quotes +("filename") are found in the same directory as the source or include +file. The <font.defs> include file defines the standard fonts +which are included with GPL Ghostscript and the Apple PDF RIP, while the +<media.defs> include file defines the standard media sizes +listed in Appendix B of the Adobe PostScript Printer Description File Format +Specification.

+ +

CUPS provides several other standard include files:

+ +
    + +
  • <epson.h> - Defines all of the rastertoepson driver + constants.
  • + +
  • <escp.h> - Defines all of the rastertoescpx driver + constants.
  • + +
  • <hp.h> - Defines all of the rastertohp driver + constants.
  • + +
  • <label.h> - Defines all of the rastertolabel driver + constants.
  • + +
  • <pcl.h> - Defines all of the rastertopclx driver + constants.
  • + +
  • <raster.defs> - Defines all of the CUPS raster format + constants.
  • + +
+ +

Next we list all of the fonts that are available in the driver; for CUPS +raster drivers, the following line is all that is usually supplied:

+ +
+Font *
+
+ +

The Font directive specifies the name of a single font or the +asterisk to specify all fonts. For example, you would use the following line to +define an additional bar code font that you are supplying with your printer +driver:

+ +
+//   name         encoding  version  charset  status
+Font Barcode-Foo  Special   "(1.0)"  Special  ROM
+
+ +

The name of the font is Barcode-Foo. Since it is not a standard +text font, the encoding and charset name Special is used. The version +number is 1.0 and the status (where the font is located) is +ROM to indicate that the font does not need to be embedded in +documents that use the font for this printer.

+ +

Third comes the manufacturer, model name, and version number information +strings:

+ +
+Manufacturer "Foo"
+ModelName "FooJet 2000"
+Version 1.0
+
+ +

These strings are used when the user (or auto-configuration program) selects +the printer driver for a newly connected device.

+ +

The list of filters comes after the information strings; for the example in +Listing 1, we have a single filter that takes CUPS +raster data:

+ +
+Filter application/vnd.cups-raster 100 rastertofoo
+
+ +

Each filter specified in the driver information file is the equivalent of a +printer driver for that format; if a user submits a print job in a different +format, CUPS figures out the sequence of commands that will produce a supported +format for the least relative cost.

+ +

Once we have defined the driver information we specify the supported options. +For the example driver we support a single resolution of 600 dots per inch and +two media sizes, A4 and Letter:

+ +
+*MediaSize Letter
+MediaSize A4
+
+*Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+ +

The asterisk in front of the MediaSize and Resolution +directives specify that those option choices are the default. The +MediaSize directive is followed by a media size name which is normally +defined in the <media.defs> file and corresponds to a standard +Adobe media size name. If the default media size is Letter, the PPD +compiler will override it to be A4 for non-English localizations for +you automatically.

+ +

The Resolution directive accepts several values after it as +follows:

+ +
    + +
  1. Colorspace for this resolution, if any. In the example file, the + colorspace k is used which corresponds to black. For printer + drivers that support color printing, this field is usually specified as + "-" for "no change".
  2. + +
  3. Bits per color. In the example file, we define 8 bits per color, for + a continuous-tone grayscale output. All versions of CUPS support 1 and + 8 bits per color. CUPS 1.2 and higher (Mac OS X 10.5 and higher) also + supports 16 bits per color.
  4. + +
  5. Rows per band. In the example file, we define 0 rows per band to + indicate that our printer driver does not process the page in + bands.
  6. + +
  7. Row feed. In the example, we define the feed value to be 0 to + indicate that our printer driver does not interleave the output.
  8. + +
  9. Row step. In the example, we define the step value to be 0 to + indicate that our printer driver does not interleave the output. This + value normally indicates the spacing between the nozzles of an inkjet + printer - when combined with the previous two values, it informs the + driver how to stagger the output on the page to produce interleaved + lines on the page for higher-resolution output.
  10. + +
  11. Choice name and text. In the example, we define the choice name and + text to be "600dpi/600 DPI". The name and text are separated by + slash (/) character; if no text is specified, then the name is + used as the text. The PPD compiler parses the name to determine the + actual resolution; the name can be of the form + RESOLUTIONdpi for resolutions that are equal + horizontally and vertically or HRESxVRESdpi for + isometric resolutions. Only integer resolution values are supported, so + a resolution name of 300dpi is valid while 300.1dpi is + not.
  12. + +
+ +

Finally, the PCFileName directive specifies that the named PPD file +should be written for the current driver definitions:

+ +
+PCFileName "foojet2k.ppd"
+
+ +

The filename follows the directive and must conform to the Adobe +filename requirements in the Adobe Postscript Printer Description File Format +Specification. Specifically, the filename may not exceed 8 characters followed +by the extension .ppd. The FileName directive can be used to +specify longer filenames:

+ +
+FileName "FooJet 2000"
+
+ + +

Grouping and Inheritance

+ +

The previous example created a single PPD file. Driver information files can +also define multiple printers by using the PPD compiler grouping functionality. +Directives are grouped using the curly braces ({ and }) and +every group that uses the PCFileName or FileName directives +produces a PPD file with that name. Listing 2 shows a +variation of the original example that uses two groups to define two printers +that share the same printer driver filter but provide two different resolution +options.

+ +

Listing 2: "examples/grouping.drv"

+ +
+
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// List the fonts that are supported, in this case all standard fonts...
+Font *
+
+// Manufacturer and version
+Manufacturer "Foo"
+Version 1.0
+
+// Each filter provided by the driver...
+Filter application/vnd.cups-raster 100 rastertofoo
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize A4
+
+{
+  // Supported resolutions
+  *Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+  // Specify the model name and filename...
+  ModelName "FooJet 2000"
+  PCFileName "foojet2k.ppd"
+}
+
+{
+  // Supported resolutions
+  *Resolution k 8 0 0 0 "1200dpi/1200 DPI"
+
+  // Specify the model name and filename...
+  ModelName "FooJet 2001"
+  PCFileName "foojt2k1.ppd"
+}
+
+ +

The second example is essentially the same as the first, except that each +printer model is defined inside of a pair of curly braces. For example, the +first printer is defined using:

+ +
+{
+  // Supported resolutions
+  *Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+  // Specify the model name and filename...
+  ModelName "FooJet 2000"
+  PCFileName "foojet2k.ppd"
+}
+
+ +

The printer inherits all of the definitions from the parent group (the +top part of the file) and adds the additional definitions inside the curly +braces for that printer driver. When we define the second group, it also +inherits the same definitions from the parent group but none of the +definitions from the first driver. Groups can be nested to any number of levels +to support variations of similar models without duplication of information.

+ + +

Color Support

+ +

For printer drivers that support color printing, the +ColorDevice and ColorModel directives should be +used to tell the printing system that color output is desired +and in what formats. Listing 3 shows a +variation of the previous example which includes a color printer +that supports printing at 300 and 600 DPI.

+ +

The key changes are the addition of the ColorDevice +directive:

+ +
+ColorDevice true
+
+ +

which tells the printing system that the printer supports +color printing, and the ColorModel directives:

+ +
+ColorModel Gray/Grayscale w chunky 0
+*ColorModel RGB/Color rgb chunky 0
+
+ +

which tell the printing system which colorspaces are supported by the printer +driver for color printing. Each of the ColorModel directives is +followed by the option name and text (Gray/Grayscale and +RGB/Color), the colorspace name (w and rgb), the +color organization (chunky), and the compression mode number +(0) to be passed to the driver. The option name can be any of the +standard Adobe ColorModel names:

+ +
    + +
  • Gray - Grayscale output. + +
  • RGB - Color output, typically using the RGB + colorspace, but without a separate black channel. + +
  • CMYK - Color output with a separate black + channel. + +
+ +

Custom names can be used, however it is recommended that you use your vendor +prefix for any custom names, for example "fooName".

+ +

The colorspace name can be any of the following universally supported +colorspaces:

+ +
    +
  • w - Luminance
  • + +
  • rgb - Red, green, blue
  • + +
  • k - Black
  • + +
  • cmy - Cyan, magenta, yellow
  • + +
  • cmyk - Cyan, magenta, yellow, black
  • + +
+ +

The color organization can be any of the following values:

+ +
    + +
  • chunky - Color values are passed together on a line + as RGB RGB RGB RGB
  • + +
  • banded - Color values are passed separately + on a line as RRRR GGGG BBBB; not supported by the Apple + RIP filters
  • + +
  • planar - Color values are passed separately + on a page as RRRR RRRR RRRR ... GGGG GGGG GGGG ... BBBB + BBBB BBBB; not supported by the Apple RIP filters
  • + +
+ +

The compression mode value is passed to the driver in the +cupsCompression attribute. It is traditionally used to select an +appropriate compression mode for the color model but can be used for any +purpose, such as specifying a photo mode vs. standard mode.

+ +

Listing 3: "examples/color.drv"

+ +
+
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// List the fonts that are supported, in this case all standard fonts...
+Font *
+
+// Manufacturer and version
+Manufacturer "Foo"
+Version 1.0
+
+// Each filter provided by the driver...
+Filter application/vnd.cups-raster 100 rastertofoo
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize A4
+
+{
+  // Supported resolutions
+  *Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+  // Specify the model name and filename...
+  ModelName "FooJet 2000"
+  PCFileName "foojet2k.ppd"
+}
+
+{
+  // Supports color printing
+  ColorDevice true
+
+  // Supported colorspaces
+  ColorModel Gray/Grayscale w chunky 0
+  *ColorModel RGB/Color rgb chunky 0
+
+  // Supported resolutions
+  *Resolution - 8 0 0 0 "300dpi/300 DPI"
+  Resolution - 8 0 0 0 "600dpi/600 DPI"
+
+  // Specify the model name and filename...
+  ModelName "FooJet Color"
+  PCFileName "foojetco.ppd"
+}
+
+ + +

Defining Custom Options and Option Groups

+ +

The Group, Option, and Choice +directives are used to define or select a group, option, or +choice. Listing 4 shows a variation of +the first example that provides two custom options in a group +named "Footasm".

+ +

Listing 4: "examples/custom.drv"

+ +
+
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// List the fonts that are supported, in this case all standard fonts...
+Font *
+
+// Manufacturer, model name, and version
+Manufacturer "Foo"
+ModelName "FooJet 2000"
+Version 1.0
+
+// Each filter provided by the driver...
+Filter application/vnd.cups-raster 100 rastertofoo
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize A4
+
+// Supported resolutions
+*Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+// Option Group
+Group "Footasm"
+
+  // Boolean option
+  Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
+    *Choice True/Yes "<</cupsCompression 1>>setpagedevice"
+    Choice False/No "<</cupsCompression 0>>setpagedevice"
+
+  // Multiple choice option
+  Option "fooOutputType/Output Quality" PickOne AnySetup 10
+    *Choice "Auto/Automatic Selection"
+            "<</OutputType(Auto)>>setpagedevice""
+    Choice "Text/Optimize for Text"
+            "<</OutputType(Text)>>setpagedevice""
+    Choice "Graph/Optimize for Graphics"
+            "<</OutputType(Graph)>>setpagedevice""
+    Choice "Photo/Optimize for Photos"
+            "<</OutputType(Photo)>>setpagedevice""
+
+// Specify the name of the PPD file we want to generate...
+PCFileName "foojet2k.ppd"
+
+ +

The custom group is introduced by the Group +directive which is followed by the name and optionally text for +the user:

+ +
+Group "Footasm/Footastic Options"
+
+ +

The group name must conform to the PPD specification and +cannot exceed 40 characters in length. If you specify user text, +it cannot exceed 80 characters in length. The groups +General, Extra, and +InstallableOptions are predefined by CUPS; the general +and extra groups are filled by the UI options defined by the PPD +specification. The InstallableOptions group is reserved +for options that define whether accessories for the printer +(duplexer unit, finisher, stapler, etc.) are installed.

+ +

Once the group is specified, the Option directive is +used to introduce a new option:

+ +
+Option "fooEnhance/Resolution Enhancement" Boolean AnySetup 10
+
+ +

The directive is followed by the name of the option and any +optional user text, the option type, the PostScript document group, and +the sort order number. The option name must conform to the PPD specification +and cannot exceed 40 characters in length. If you specify user text, it +cannot exceed 80 characters in length.

+ +

The option type can be Boolean for true/false +selections, PickOne for picking one of many choices, or +PickMany for picking zero or more choices. Boolean +options can have at most two choices with the names +False and True. Pick options can have any +number of choices, although for Windows compatibility reasons +the number of choices should not exceed 255.

+ +

The PostScript document group is typically AnySetup, +meaning that the option can be introduced at any point in the +PostScript document. Other values include PageSetup to +include the option before each page and DocumentSetup +to include the option once at the beginning of the document.

+ +

The sort order number is used to sort the printer commands +associated with each option choice within the PostScript +document. This allows you to setup certain options before others +as required by the printer. For most CUPS raster printer +drivers, the value 10 can be used for all options.

+ +

Once the option is specified, each option choice can be +listed using the Choice directive:

+ +
+*Choice True/Yes "<</cupsCompression 1>>setpagedevice"
+Choice False/No "<</cupsCompression 0>>setpagedevice"
+
+ +

The directive is followed by the choice name and optionally +user text, and the PostScript commands that should be inserted +when printing a file to this printer. The option name must +conform to the PPD specification and cannot exceed 40 characters +in length. If you specify user text, it cannot exceed 80 +characters in length.

+ +

The PostScript commands are also interpreted by any RIP +filters, so these commands typically must be present for all +option choices. Most commands take the form:

+ +
+<</name value>>setpagedevice
+
+ +

where name is the name of the PostScript page device +attribute and value is the numeric or string value for +that attribute.

+ + +

Defining Constants

+ +

Sometimes you will want to define constants for your drivers +so that you can share values in different groups within the same +driver information file, or to share values between different +driver information files using the #include directive. +The #define directive is used to define constants for +use in your printer definitions:

+ +
+#define NAME value
+
+ +

The NAME is any sequence of letters, numbers, and +the underscore. The value is a number or string; if the +value contains spaces you must put double quotes around it, for +example:

+ +
+#define FOO "My String Value"
+
+ +

Constants can also be defined on the command-line using the -D +option:

+ +
+ppdc -DNAME="value" filename.drv
+
+ +

Once defined, you use the notation $NAME to substitute the value of +the constant in the file, for example:

+ +
+#define MANUFACTURER "Foo"
+#define FOO_600      0
+#define FOO_1200     1
+
+{
+  Manufacturer "$MANUFACTURER"
+  ModelNumber $FOO_600
+  ModelName "FooJet 2000"
+  ...
+}
+
+{
+  Manufacturer "$MANUFACTURER"
+  ModelNumber $FOO_1200
+  ModelName "FooJet 2001"
+  ...
+}
+
+ +

Numeric constants can be bitwise OR'd together by placing the constants +inside parenthesis, for example:

+ +
+// ModelNumber capability bits
+#define DUPLEX 1
+#define COLOR  2
+
+...
+
+{
+  // Define a model number specifying the capabilities of the printer...
+  ModelNumber ($DUPLEX $COLOR)
+  ...
+}
+
+ + +

Conditional Statements

+ +

The PPD compiler supports conditional compilation using the #if, +#elif, #else, and #endif directives. The #if +and #elif directives are followed by a constant name or an expression. +For example, to include a group of options when "ADVANCED" is defined:

+ +
+#if ADVANCED
+Group "Advanced/Advanced Options"
+  Option "fooCyanAdjust/Cyan Adjustment"
+    Choice "plus10/+10%" ""
+    Choice "plus5/+5%" ""
+    *Choice "none/No Adjustment" ""
+    Choice "minus5/-5%" ""
+    Choice "minus10/-10%" ""
+  Option "fooMagentaAdjust/Magenta Adjustment"
+    Choice "plus10/+10%" ""
+    Choice "plus5/+5%" ""
+    *Choice "none/No Adjustment" ""
+    Choice "minus5/-5%" ""
+    Choice "minus10/-10%" ""
+  Option "fooYellowAdjust/Yellow Adjustment"
+    Choice "plus10/+10%" ""
+    Choice "plus5/+5%" ""
+    *Choice "none/No Adjustment" ""
+    Choice "minus5/-5%" ""
+    Choice "minus10/-10%" ""
+  Option "fooBlackAdjust/Black Adjustment"
+    Choice "plus10/+10%" ""
+    Choice "plus5/+5%" ""
+    *Choice "none/No Adjustment" ""
+    Choice "minus5/-5%" ""
+    Choice "minus10/-10%" ""
+#endif
+
+ + +

Defining Constraints

+ +

Constraints are strings that are used to specify that one or more option +choices are incompatible, for example two-sided printing on transparency media. +Constraints are also used to prevent the use of uninstalled features such as the +duplexer unit, additional media trays, and so forth.

+ +

The UIConstraints directive is used to specify a constraint that is +placed in the PPD file. The directive is followed by a string using one of the +following formats:

+ +
+UIConstraints "*Option1 *Option2"
+UIConstraints "*Option1 Choice1 *Option2"
+UIConstraints "*Option1 *Option2 Choice2"
+UIConstraints "*Option1 Choice1 *Option2 Choice2"
+
+ +

Each option name is preceded by the asterisk (*). If no choice is +given for an option, then all choices except False and +None will conflict with the other option and choice(s). Since the PPD +compiler automatically adds reciprocal constraints (option A conflicts with +option B, so therefore option B conflicts with option A), you need only specify +the constraint once.

+ +

Listing 5: "examples/constraint.drv"

+ +
+
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// List the fonts that are supported, in this case all standard fonts...
+Font *
+
+// Manufacturer, model name, and version
+Manufacturer "Foo"
+ModelName "FooJet 2000"
+Version 1.0
+
+// Each filter provided by the driver...
+Filter application/vnd.cups-raster 100 rastertofoo
+
+// Supported page sizes
+*MediaSize Letter
+MediaSize A4
+
+// Supported resolutions
+*Resolution k 8 0 0 0 "600dpi/600 DPI"
+
+// Installable Option Group
+Group "InstallableOptions/Options Installed"
+
+  // Duplexing unit option
+  Option "OptionDuplexer/Duplexing Unit" Boolean AnySetup 10
+    Choice True/Installed ""
+    *Choice "False/Not Installed" ""
+
+// General Option Group
+Group General
+
+  // Duplexing option
+  Option "Duplex/Two-Sided Printing" PickOne AnySetup 10
+    *Choice "None/No" "<</Duplex false>>setpagedevice""
+    Choice "DuplexNoTumble/Long Edge Binding"
+           "<</Duplex true/Tumble false>>setpagedevice""
+    Choice "DuplexTumble/Short Edge Binding"
+           "<</Duplex true/Tumble true>>setpagedevice""
+
+// Only allow duplexing if the duplexer is installed
+UIConstraints "*Duplex *OptionDuplexer False"
+
+// Specify the name of the PPD file we want to generate...
+PCFileName "foojet2k.ppd"
+
+ +

Listing 5 shows a variation of the first example with +an added Duplex option and installable option for the duplexer, +OptionDuplex. A constraint is added at the end to specify that any +choice of the Duplex option that is not None is incompatible +with the "Duplexer Installed" option set to "Not Installed" +(False):

+ +
+UIConstraints "*Duplex *OptionDuplexer False"
+
+ +

Enhanced Constraints

+ +

CUPS 1.4 supports constraints between 2 or more options using the +Attribute directive. cupsUIConstraints attributes define +the constraints, while cupsUIResolver attributes define option changes +to resolve constraints. For example, we can specify the previous duplex +constraint with a resolver that turns off duplexing with the following two +lines:

+ +
+Attribute cupsUIConstraints DuplexOff "*Duplex *OptionDuplexer False"
+Attribute cupsUIResolver DuplexOff "*Duplex None"
+
+ +

Localization

+ +

The PPD compiler provides localization of PPD files in different languages +through message catalog files in the GNU gettext or Apple .strings +formats. Each user text string and several key PPD attribute values such as +LanguageVersion and LanguageEncoding are looked up in the +corresponding message catalog and the translated text is substituted in the +generated PPD files. One message catalog file can be used by multiple driver +information files, and each file contains a single language translation.

+ +

The ppdpo Utility

+ +

While CUPS includes localizations of all standard media sizes and options in +several languages, your driver information files may provide their own media +sizes and options that need to be localized. CUPS provides a utility program to +aid in the localization of drivers called ppdpo(1). The ppdpo program creates +or updates a message catalog file based upon one or more driver information +files. New messages are added with the word "TRANSLATE" added to the front of +the translation string to make locating new strings for translation easier. The +program accepts the message catalog filename and one or more driver information +files.

+ +

For example, run the following command to create a new German message catalog +called de.po for all of the driver information files in the current +directory:

+ +
+ppdpo -o de.po *.drv
+
+ +

If the file de.po already exists, ppdpo will update the +contents of the file with any new messages that need to be translated. To create +an Apple .strings file instead, specify the output filename with a .strings +extension, for example:

+ +
+ppdpo -o de.strings *.drv
+
+ +

Using Message Catalogs with the PPD Compiler

+ +

Once you have created a message catalog, use the #po directive to declare it in each +driver information file. For example, to declare the German message catalog for +a driver use:

+ +
+#po de "de.po"  // German
+
+ +

In fact, you can use the #po directive as many times as needed:

+ +
+#po de "de.po"  // German
+#po es "es.po"  // Spanish
+#po fr "fr.po"  // French
+#po it "it.po"  // Italian
+#po ja "ja.po"  // Japanese
+
+ +

The filename ("de.po", etc.) can be relative to the location of the driver +information file or an absolute path. Once defined, the PPD compiler will +automatically generate a globalized PPD for every language declared in your +driver information file. To generate a single-language PPD file, simply use the +-l option to list the corresponding locale, for example:

+ +
+ppdc -l de -d ppd/de mydrivers.drv
+
+ +

to generate German PPD files.

diff --git a/filter/pstext.c b/filter/pstext.c new file mode 100644 index 0000000000..1517a608bb --- /dev/null +++ b/filter/pstext.c @@ -0,0 +1,506 @@ +/* + * "$Id$" + * + * Common PostScript text code for the Common UNIX Printing System (CUPS). + * + * Copyright 2008 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * psTextEmbedFonts() - Embed PostScript fonts. + * psTextListFonts() - List PostScript fonts. + * psTextInitialize() - Load and embed font data for UTF-8 text. + * psTextUTF8() - Output UTF-8 text at the current position. + * psTextUTF32() - Output UTF-32 text at the current position. + */ + +/* + * Include necessary headers... + */ + +#include "pstext.h" +#include + + +/* + * Composite font names... + */ + +static const char * const ps_font_names[] = +{ + "cupsNormal", + "cupsBold", + "cupsItalic", + "cupsBoldItalic" +}; + + +/* + * 'psTextEmbedFonts()'- Embed PostScript fonts. + */ + +void +psTextEmbedFonts(ps_text_t *fonts) /* I - Font data */ +{ + int i, j; /* Looping vars */ + const char *cups_datadir; /* CUPS_DATADIR environment variable */ + char *font; /* Current font */ + char filename[1024]; /* Current filename */ + FILE *fp; /* Current file */ + char line[1024]; /* Line from file */ + int ch; /* Character value */ + + + /* + * Get the data directory... + */ + + if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) + cups_datadir = CUPS_DATADIR; + + /* + * Embed each font... + */ + + for (font = (char *)cupsArrayFirst(fonts->unique); + font; + font = (char *)cupsArrayNext(fonts->unique)) + { + printf("%%%%BeginResource: font %s\n", font); + + snprintf(filename, sizeof(filename), "%s/fonts/%s", cups_datadir, font); + if ((fp = fopen(filename, "rb")) != NULL) + { + while ((j = fread(line, 1, sizeof(line), fp)) > 0) + fwrite(line, 1, j, stdout); + + fclose(fp); + } + else + fprintf(stderr, "DEBUG: Unable to open font file \"%s\" - %s\n", + filename, strerror(errno)); + + puts("\n%%EndResource"); + } + + /* + * Write the encoding arrays... + */ + + puts("% Character encodings"); + + for (i = 0; i < fonts->num_fonts; i ++) + { + printf("/cupsEncoding%02x [\n", i); + + for (ch = 0; ch < 256; ch ++) + { + if (fonts->glyphs[fonts->codes[i * 256 + ch]]) + printf("/%s", fonts->glyphs[fonts->codes[i * 256 + ch]]); + else if (fonts->codes[i * 256 + ch] > 255) + printf("/uni%04X", fonts->codes[i * 256 + ch]); + else + printf("/.notdef"); + + if ((ch & 7) == 7) + putchar('\n'); + } + + puts("] def"); + } + + /* + * Construct composite fonts... Start by reencoding the base fonts... + */ + + puts("% Reencode base fonts"); + + for (i = 0; i < 4; i ++) + for (j = 0; j < fonts->num_fonts; j ++) + { + printf("/%s findfont\n", fonts->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", ps_font_names[i], j, + ps_font_names[i], j); + } + + /* + * Then merge them into composite fonts... + */ + + puts("% Create composite fonts"); + + for (i = 0; i < 4; 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 < fonts->num_fonts; j ++) + if (j == (fonts->num_fonts - 1)) + printf("%d", j); + else if ((j & 15) == 15) + printf("%d\n", j); + else + printf("%d ", j); + puts("]def/FDepVector["); + for (j = 0; j < fonts->num_fonts; j ++) + if (j == (fonts->num_fonts - 1)) + printf("%s%02x", ps_font_names[i], j); + else if ((j & 3) == 3) + printf("%s%02x\n", ps_font_names[i], j); + else + printf("%s%02x ", ps_font_names[i], j); + puts("]def currentdict end"); + printf("/%s exch definefont pop\n", ps_font_names[i]); + } + + /* + * Procedures... + */ + + puts("% Procedures to justify text...\n" + "/showcenter{dup stringwidth pop -0.5 mul 0 rmoveto show}bind def\n" + "/showleft{show}bind def\n" + "/showright{dup stringwidth pop neg 0 rmoveto show}bind def"); +} + + +/* + * 'psTextListFonts()' - List PostScript fonts. + */ + +void +psTextListFonts(ps_text_t *fonts) /* I - Font data */ +{ + char *font; /* Current font */ + + + font = (char *)cupsArrayFirst(fonts->unique); + printf("%%%%DocumentSuppliedResources: font %s\n", font); + while ((font = (char *)cupsArrayNext(fonts->unique)) != NULL) + printf("%%%%+ font %s\n", font); +} + + +/* + * 'psTextInitialize()' - Load and embed font data for UTF-8 text. + */ + +ps_text_t * /* O - Font data */ +psTextInitialize(void) +{ + ps_text_t *fonts; /* Font data */ + int i, j; /* Looping vars */ + char filename[1024]; /* Current filename */ + FILE *fp; /* Current file */ + const char *cups_datadir; /* CUPS_DATADIR environment variable */ + char line[1024], /* Line from file */ + *lineptr, /* Pointer into line */ + *valptr; /* Pointer to value in line */ + int unicode; /* Character value */ + int start, end; /* Start and end values for range */ + char glyph[64]; /* Glyph name */ + + + /* + * Get the data directory... + */ + + if ((cups_datadir = getenv("CUPS_DATADIR")) == NULL) + cups_datadir = CUPS_DATADIR; + + /* + * Initialize the PostScript text data... + */ + + fonts = (ps_text_t *)calloc(1, sizeof(ps_text_t)); + fonts->size = -1.0; + fonts->style = -1; + + /* + * Load the PostScript glyph names... + */ + + snprintf(filename, sizeof(filename), "%s/data/psglyphs", cups_datadir); + + if ((fp = fopen(filename, "r")) != NULL) + { + while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) + fonts->glyphs[unicode] = _cupsStrAlloc(glyph); + + fclose(fp); + } + else + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open \"%s\" - %s\n"), filename, + strerror(errno)); + exit(1); + } + + /* + * Open the UTF-8 character set definition... + */ + + snprintf(filename, sizeof(filename), "%s/charsets/utf-8", cups_datadir); + + if ((fp = fopen(filename, "r")) == NULL) + { + /* + * Can't open charset file! + */ + + _cupsLangPrintf(stderr, _("ERROR: Unable to open %s: %s\n"), filename, + strerror(errno)); + exit(1); + } + + if (!fgets(line, sizeof(line), fp) || strncmp(line, "charset utf8", 12)) + { + /* + * Bad/empty charset file! + */ + + fclose(fp); + _cupsLangPrintf(stderr, _("ERROR: Bad charset file %s\n"), filename); + exit(1); + } + + /* + * Read the font descriptions... + */ + + fonts->unique = cupsArrayNew((cups_array_func_t)strcmp, NULL); + + 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 & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + _cupsLangPrintf(stderr, _("ERROR: Bad font description line: %s\n"), + valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (!strcmp(valptr, "ltor")) + fonts->directions[fonts->num_fonts] = 1; + else if (!strcmp(valptr, "rtol")) + fonts->directions[fonts->num_fonts] = -1; + else + { + _cupsLangPrintf(stderr, _("ERROR: Bad text direction %s\n"), valptr); + fclose(fp); + exit(1); + } + + /* + * Got the direction, now get the width... + */ + + while (isspace(*lineptr & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + _cupsLangPrintf(stderr, _("ERROR: Bad font description line: %s\n"), + valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (!strcmp(valptr, "single")) + fonts->widths[fonts->num_fonts] = 1; + else if (!strcmp(valptr, "double")) + fonts->widths[fonts->num_fonts] = 2; + else + { + _cupsLangPrintf(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 & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *lineptr) + lineptr ++; + + if (*lineptr) + *lineptr++ = '\0'; + + if (lineptr > valptr) + { + if (!cupsArrayFind(fonts->unique, valptr)) + cupsArrayAdd(fonts->unique, _cupsStrAlloc(valptr)); + + fonts->fonts[fonts->num_fonts][i] = _cupsStrAlloc(valptr); + } + } + + /* + * Fill in remaining fonts as needed... + */ + + for (j = i; j < 4; j ++) + fonts->fonts[fonts->num_fonts][j] = + _cupsStrAlloc(fonts->fonts[fonts->num_fonts][0]); + + /* + * Define the character mappings... + */ + + for (i = start, j = fonts->num_fonts * 256; i <= end; i ++, j ++) + { + fonts->chars[i] = j; + fonts->codes[j] = i; + } + + /* + * Move to the next font, stopping if needed... + */ + + fonts->num_fonts ++; + if (fonts->num_fonts >= 256) + break; + } + + fclose(fp); + + if (cupsArrayCount(fonts->unique) == 0) + { + _cupsLangPrintf(stderr, _("ERROR: No fonts in charset file %s\n"), filename); + exit(1); + } + + return (fonts); +} + + +/* + * 'psTextUTF8()' - Output UTF-8 text at the current position. + */ + +void +psTextUTF8(ps_text_t *fonts, /* I - Font data */ + float size, /* I - Size in points */ + int style, /* I - Style */ + int align, /* I - Alignment */ + const char *text) /* I - UTF-8 text */ +{ + cups_utf32_t utf32[2048]; /* Temporary buffer */ + int utf32len; /* Number of characters */ + + + if (!text) + { + puts(""); + return; + } + + if ((utf32len = cupsUTF8ToUTF32(utf32, (cups_utf8_t *)text, + (int)(sizeof(utf32) / sizeof(utf32[0])))) > 0) + psTextUTF32(fonts, size, style, align, utf32, utf32len); +} + + +/* + * 'psTextUTF32()' - Output UTF-32 text at the current position. + */ + +void +psTextUTF32(ps_text_t *fonts, /* I - Font data */ + float size, /* I - Size in points */ + int style, /* I - Font style */ + int align, /* I - Alignment */ + const cups_utf32_t *text, /* I - UTF-32 text */ + int textlen) /* I - Length of text */ +{ + if (size != fonts->size || style != fonts->style) + { + printf("/%s findfont %g scalefont setfont\n", ps_font_names[style], size); + fonts->size = size; + fonts->style = style; + } + + putchar('<'); + while (textlen > 0) + { + printf("%04x", fonts->chars[*text]); + text ++; + textlen --; + } + + if (align == PS_CENTER) + puts(">showcenter"); + else if (align == PS_RIGHT) + puts(">showright"); + else + puts(">showleft"); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/pstext.h b/filter/pstext.h new file mode 100644 index 0000000000..fea5b0a753 --- /dev/null +++ b/filter/pstext.h @@ -0,0 +1,75 @@ +/* + * "$Id$" + * + * Common PostScript text definitions for the Common UNIX Printing System + * (CUPS). + * + * Copyright 2008 by Apple Inc. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include + + +/* + * Constants... + */ + +#define PS_NORMAL 0 /* Normal text */ +#define PS_BOLD 1 /* Bold text */ +#define PS_ITALIC 2 /* Italic text */ +#define PS_BOLDITALIC 3 /* Bold italic text */ + +#define PS_LEFT 1 /* Left-justified text */ +#define PS_CENTER 0 /* Center-justified text */ +#define PS_RIGHT -1 /* Right-justified text */ + + +/* + * Structures... + */ + +typedef struct ps_text_s /**** PostScript font data ****/ +{ + char *glyphs[65536]; /* PostScript glyphs for Unicode */ + int num_fonts; /* Number of fonts to use */ + char *fonts[256][4]; /* Fonts to use */ + cups_array_t *unique; /* Unique fonts */ + unsigned short chars[65536], /* 0xffcc (ff = font, cc = char) */ + codes[65536]; /* Unicode glyph mapping to fonts */ + int widths[256], /* Widths of each font */ + directions[256];/* Text directions for each font */ + float size; /* Current text size */ + int style; /* Current text style */ +} ps_text_t; + + +/* + * Functions... + */ + +extern void psTextEmbedFonts(ps_text_t *fonts); +extern void psTextListFonts(ps_text_t *fonts); +extern ps_text_t *psTextInitialize(void); +extern void psTextUTF8(ps_text_t *fonts, float size, int style, + int align, const char *text); +extern void psTextUTF32(ps_text_t *fonts, float size, int style, + int align, const cups_utf32_t *text, + int textlen); + + +/* + * End of "$Id$". + */ diff --git a/filter/pstops.c b/filter/pstops.c new file mode 100644 index 0000000000..fdf2883d30 --- /dev/null +++ b/filter/pstops.c @@ -0,0 +1,3531 @@ +/* + * "$Id$" + * + * PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry. + * add_page() - Add a page to the pages array. + * cancel_job() - Flag the job as canceled. + * check_range() - Check to see if the current page is selected for + * printing. + * copy_bytes() - Copy bytes from the input file to stdout. + * copy_comments() - Copy all of the comments section. + * copy_dsc() - Copy a DSC-conforming document. + * copy_non_dsc() - Copy a document that does not conform to the DSC. + * copy_page() - Copy a page description. + * copy_prolog() - Copy the document prolog section. + * copy_setup() - Copy the document setup section. + * copy_trailer() - Copy the document trailer. + * do_prolog() - Send the necessary document prolog commands. + * do_setup() - Send the necessary document setup commands. + * doc_printf() - Send a formatted string to stdout and/or the temp + * file. + * doc_puts() - Send a nul-terminated string to stdout and/or the + * temp file. + * doc_write() - Send data to stdout and/or the temp file. + * end_nup() - End processing for N-up printing. + * include_feature() - Include a printer option/feature command. + * parse_text() - Parse a text value in a comment. + * set_pstops_options() - Set pstops options. + * skip_page() - Skip past a page that won't be printed. + * start_nup() - Start processing for N-up printing. + * write_label_prolog() - Write the prolog with the classification and page + * label. + * write_labels() - Write the actual page labels. + * write_options() - Write options provided via %%IncludeFeature. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include +#include +#include +#include +#include +#include + + +/* + * Constants... + */ + +#define PSTOPS_BORDERNONE 0 /* No border or hairline border */ +#define PSTOPS_BORDERTHICK 1 /* Think border */ +#define PSTOPS_BORDERSINGLE 2 /* Single-line hairline border */ +#define PSTOPS_BORDERSINGLE2 3 /* Single-line thick border */ +#define PSTOPS_BORDERDOUBLE 4 /* Double-line hairline border */ +#define PSTOPS_BORDERDOUBLE2 5 /* Double-line thick border */ + +#define PSTOPS_LAYOUT_LRBT 0 /* Left to right, bottom to top */ +#define PSTOPS_LAYOUT_LRTB 1 /* Left to right, top to bottom */ +#define PSTOPS_LAYOUT_RLBT 2 /* Right to left, bottom to top */ +#define PSTOPS_LAYOUT_RLTB 3 /* Right to left, top to bottom */ +#define PSTOPS_LAYOUT_BTLR 4 /* Bottom to top, left to right */ +#define PSTOPS_LAYOUT_TBLR 5 /* Top to bottom, left to right */ +#define PSTOPS_LAYOUT_BTRL 6 /* Bottom to top, right to left */ +#define PSTOPS_LAYOUT_TBRL 7 /* Top to bottom, right to left */ + +#define PSTOPS_LAYOUT_NEGATEY 1 /* The bits for the layout */ +#define PSTOPS_LAYOUT_NEGATEX 2 /* definitions above... */ +#define PSTOPS_LAYOUT_VERTICAL 4 + + +/* + * Types... + */ + +typedef struct /**** Page information ****/ +{ + char *label; /* Page label */ + int bounding_box[4]; /* PageBoundingBox */ + off_t offset; /* Offset to start of page */ + ssize_t length; /* Number of bytes for page */ + int num_options; /* Number of options for this page */ + cups_option_t *options; /* Options for this page */ +} pstops_page_t; + +typedef struct /**** Document information ****/ +{ + int page; /* Current page */ + int bounding_box[4]; /* BoundingBox from header */ + int new_bounding_box[4]; /* New composite bounding box */ + int num_options; /* Number of document-wide options */ + cups_option_t *options; /* Document-wide options */ + int normal_landscape, /* Normal rotation for landscape? */ + saw_eof, /* Saw the %%EOF comment? */ + slow_collate, /* Collate copies by hand? */ + slow_duplex, /* Duplex pages slowly? */ + slow_order, /* Reverse pages slowly? */ + use_ESPshowpage; /* Use ESPshowpage? */ + cups_array_t *pages; /* Pages in document */ + cups_file_t *temp; /* Temporary file, if any */ + char tempfile[1024]; /* Temporary filename */ + int job_id; /* Job ID */ + const char *user, /* User name */ + *title; /* Job name */ + int copies; /* Number of copies */ + const char *ap_input_slot, /* AP_FIRSTPAGE_InputSlot value */ + *ap_manual_feed, /* AP_FIRSTPAGE_ManualFeed value */ + *ap_media_color, /* AP_FIRSTPAGE_MediaColor value */ + *ap_media_type, /* AP_FIRSTPAGE_MediaType value */ + *ap_page_region, /* AP_FIRSTPAGE_PageRegion value */ + *ap_page_size; /* AP_FIRSTPAGE_PageSize value */ + float brightness; /* brightness value */ + int collate, /* Collate copies? */ + emit_jcl, /* Emit JCL commands? */ + fitplot; /* Fit pages to media */ + float gamma; /* gamma value */ + const char *input_slot, /* InputSlot value */ + *manual_feed, /* ManualFeed value */ + *media_color, /* MediaColor value */ + *media_type, /* MediaType value */ + *page_region, /* PageRegion value */ + *page_size; /* PageSize value */ + int mirror, /* doc->mirror/mirror pages */ + number_up, /* Number of pages on each sheet */ + number_up_layout, /* doc->number_up_layout of N-up pages */ + output_order, /* Requested reverse output order? */ + page_border; /* doc->page_border around pages */ + const char *page_label, /* page-label option, if any */ + *page_ranges, /* page-ranges option, if any */ + *page_set; /* page-set option, if any */ +} pstops_doc_t; + + +/* + * Convenience macros... + */ + +#define is_first_page(p) (doc->number_up == 1 || \ + ((p) % doc->number_up) == 1) +#define is_last_page(p) (doc->number_up == 1 || \ + ((p) % doc->number_up) == 0) +#define is_not_last_page(p) (doc->number_up > 1 && \ + ((p) % doc->number_up) != 0) + + +/* + * Local globals... + */ + +static int JobCanceled = 0;/* Set to 1 on SIGTERM */ + + +/* + * Local functions... + */ + +static pstops_page_t *add_page(pstops_doc_t *doc, const char *label); +static void cancel_job(int sig); +static int check_range(pstops_doc_t *doc, int page); +static void copy_bytes(cups_file_t *fp, off_t offset, + size_t length); +static ssize_t copy_comments(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, char *line, + ssize_t linelen, size_t linesize); +static void copy_dsc(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, char *line, ssize_t linelen, + size_t linesize); +static void copy_non_dsc(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, char *line, + ssize_t linelen, size_t linesize); +static ssize_t copy_page(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, int number, char *line, + ssize_t linelen, size_t linesize); +static ssize_t copy_prolog(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, char *line, + ssize_t linelen, size_t linesize); +static ssize_t copy_setup(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, char *line, + ssize_t linelen, size_t linesize); +static ssize_t copy_trailer(cups_file_t *fp, pstops_doc_t *doc, + ppd_file_t *ppd, int number, char *line, + ssize_t linelen, size_t linesize); +static void do_prolog(pstops_doc_t *doc, ppd_file_t *ppd); +static void do_setup(pstops_doc_t *doc, ppd_file_t *ppd); +static void doc_printf(pstops_doc_t *doc, const char *format, ...) +#ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 2, 3))) +#endif /* __GNUC__ */ +; +static void doc_puts(pstops_doc_t *doc, const char *s); +static void doc_write(pstops_doc_t *doc, const char *s, size_t len); +static void end_nup(pstops_doc_t *doc, int number); +static int include_feature(ppd_file_t *ppd, const char *line, + int num_options, + cups_option_t **options); +static char *parse_text(const char *start, char **end, char *buffer, + size_t bufsize); +static void set_pstops_options(pstops_doc_t *doc, ppd_file_t *ppd, + char *argv[], int num_options, + cups_option_t *options); +static ssize_t skip_page(cups_file_t *fp, char *line, ssize_t linelen, + size_t linesize); +static void start_nup(pstops_doc_t *doc, int number, + int show_border, const int *bounding_box); +static void write_label_prolog(pstops_doc_t *doc, const char *label, + float bottom, float top, + float width); +static void write_labels(pstops_doc_t *doc, int orient); +static void write_options(pstops_doc_t *doc, ppd_file_t *ppd, + int num_options, cups_option_t *options); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + pstops_doc_t doc; /* Document information */ + cups_file_t *fp; /* Print file */ + ppd_file_t *ppd; /* PPD file */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + char line[8192]; /* Line buffer */ + size_t len; /* Length of line buffer */ +#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 < 6 || argc > 7) + { + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + argv[0]); + return (1); + } + + /* + * Register a signal handler to cleanly cancel a job. + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, cancel_job); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = cancel_job; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, cancel_job); +#endif /* HAVE_SIGSET */ + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + fp = cupsFileStdin(); + else + { + /* + * Try to open the print file... + */ + + if ((fp = cupsFileOpen(argv[6], "r")) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open file \"%s\" - %s\n"), + argv[6], strerror(errno)); + return (1); + } + } + + /* + * Read the first line to see if we have DSC comments... + */ + + if ((len = cupsFileGetLine(fp, line, sizeof(line))) == 0) + { + _cupsLangPuts(stderr, _("ERROR: Empty print file!\n")); + return (1); + } + + /* + * Process command-line options... + */ + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + ppd = SetCommonOptions(num_options, options, 1); + + set_pstops_options(&doc, ppd, argv, num_options, options); + + /* + * 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... + */ + + if (doc.emit_jcl) + ppdEmitJCL(ppd, stdout, doc.job_id, doc.user, doc.title); + + /* + * Start with a DSC header... + */ + + puts("%!PS-Adobe-3.0"); + + /* + * Skip leading PJL in the document... + */ + + while (!strncmp(line, "\033%-12345X", 9) || !strncmp(line, "@PJL ", 5)) + { + /* + * Yup, we have leading PJL fun, so skip it until we hit the line + * with "ENTER LANGUAGE"... + */ + + fputs("DEBUG: Skipping PJL header...\n", stderr); + + while (strstr(line, "ENTER LANGUAGE") == NULL && strncmp(line, "%!", 2)) + if ((len = cupsFileGetLine(fp, line, sizeof(line))) == 0) + break; + + if (!strncmp(line, "%!", 2)) + break; + + if ((len = cupsFileGetLine(fp, line, sizeof(line))) == 0) + break; + } + + /* + * Now see if the document conforms to the Adobe Document Structuring + * Conventions... + */ + + if (!strncmp(line, "%!PS-Adobe-", 11)) + { + /* + * Yes, filter the document... + */ + + copy_dsc(fp, &doc, ppd, line, len, sizeof(line)); + } + else + { + /* + * No, display an error message and treat the file as if it contains + * a single page... + */ + + copy_non_dsc(fp, &doc, ppd, line, len, sizeof(line)); + } + + /* + * Send %%EOF as needed... + */ + + if (!doc.saw_eof) + puts("%%EOF"); + + /* + * End the job with the appropriate JCL command or CTRL-D... + */ + + if (doc.emit_jcl) + { + if (ppd && ppd->jcl_end) + ppdEmitJCLEnd(ppd, stdout); + else + putchar(0x04); + } + + /* + * Close files and remove the temporary file if needed... + */ + + if (doc.temp) + { + cupsFileClose(doc.temp); + unlink(doc.tempfile); + } + + ppdClose(ppd); + cupsFreeOptions(num_options, options); + + cupsFileClose(fp); + + return (0); +} + + +/* + * 'add_page()' - Add a page to the pages array. + */ + +static pstops_page_t * /* O - New page info object */ +add_page(pstops_doc_t *doc, /* I - Document information */ + const char *label) /* I - Page label */ +{ + pstops_page_t *pageinfo; /* New page info object */ + + + if (!doc->pages) + doc->pages = cupsArrayNew(NULL, NULL); + + if (!doc->pages) + { + _cupsLangPrintf(stderr, + _("EMERG: Unable to allocate memory for pages array: %s\n"), + strerror(errno)); + exit(1); + } + + if ((pageinfo = calloc(1, sizeof(pstops_page_t))) == NULL) + { + _cupsLangPrintf(stderr, + _("EMERG: Unable to allocate memory for page info: %s\n"), + strerror(errno)); + exit(1); + } + + pageinfo->label = strdup(label); + pageinfo->offset = cupsFileTell(doc->temp); + + cupsArrayAdd(doc->pages, pageinfo); + + doc->page ++; + + return (pageinfo); +} + + +/* + * 'cancel_job()' - Flag the job as canceled. + */ + +static void +cancel_job(int sig) /* I - Signal number (unused) */ +{ + (void)sig; + + JobCanceled = 1; +} + + +/* + * 'check_range()' - Check to see if the current page is selected for + * printing. + */ + +static int /* O - 1 if selected, 0 otherwise */ +check_range(pstops_doc_t *doc, /* I - Document information */ + int page) /* I - Page number */ +{ + const char *range; /* Pointer into range string */ + int lower, upper; /* Lower and upper page numbers */ + + + if (doc->page_set) + { + /* + * See if we only print even or odd pages... + */ + + if (!strcasecmp(doc->page_set, "even") && (page & 1)) + return (0); + + if (!strcasecmp(doc->page_set, "odd") && !(page & 1)) + return (0); + } + + if (!doc->page_ranges) + return (1); /* No range, print all pages... */ + + for (range = doc->page_ranges; *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 & 255)) + 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(cups_file_t *fp, /* I - File to read from */ + off_t offset, /* I - Offset to page data */ + size_t length) /* I - Length of page data */ +{ + char buffer[8192]; /* Data buffer */ + ssize_t nbytes; /* Number of bytes read */ + size_t nleft; /* Number of bytes left/remaining */ + + + nleft = length; + + if (cupsFileSeek(fp, offset) < 0) + { + _cupsLangPrintf(stderr, +#ifdef HAVE_LONG_LONG + _("ERROR: Unable to seek to offset %lld in file - %s\n"), +#else + _("ERROR: Unable to seek to offset %ld in file - %s\n"), +#endif /* HAVE_LONG_LONG */ + CUPS_LLCAST offset, strerror(errno)); + return; + } + + while (nleft > 0 || length == 0) + { + if (nleft > sizeof(buffer) || length == 0) + nbytes = sizeof(buffer); + else + nbytes = nleft; + + if ((nbytes = cupsFileRead(fp, buffer, nbytes)) < 1) + return; + + nleft -= nbytes; + + fwrite(buffer, 1, nbytes, stdout); + } +} + + +/* + * 'copy_comments()' - Copy all of the comments section. + * + * This function expects "line" to be filled with a comment line. + * On return, "line" will contain the next line in the file, if any. + */ + +static ssize_t /* O - Length of next line */ +copy_comments(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + int saw_bounding_box, /* Saw %%BoundingBox: comment? */ + saw_for, /* Saw %%For: comment? */ + saw_pages, /* Saw %%Pages: comment? */ + saw_title; /* Saw %%Title: comment? */ + + + /* + * Loop until we see %%EndComments or a non-comment line... + */ + + saw_bounding_box = 0; + saw_for = 0; + saw_pages = 0; + saw_title = 0; + + while (line[0] == '%') + { + /* + * Strip trailing whitespace... + */ + + while (linelen > 0) + { + linelen --; + + if (!isspace(line[linelen] & 255)) + break; + else + line[linelen] = '\0'; + } + + /* + * Log the header... + */ + + fprintf(stderr, "DEBUG: %s\n", line); + + /* + * Pull the headers out... + */ + + if (!strncmp(line, "%%Pages:", 8)) + { + int pages; /* Number of pages */ + + + if (saw_pages) + _cupsLangPuts(stderr, _("ERROR: Duplicate %%Pages: comment seen!\n")); + + saw_pages = 1; + + if (Duplex && (pages = atoi(line + 8)) > 0 && pages <= doc->number_up) + { + /* + * Since we will only be printing on a single page, disable duplexing. + */ + + Duplex = 0; + doc->slow_duplex = 0; + + if (cupsGetOption("sides", doc->num_options, doc->options)) + doc->num_options = cupsAddOption("sides", "one-sided", + doc->num_options, &(doc->options)); + + if (cupsGetOption("Duplex", doc->num_options, doc->options)) + doc->num_options = cupsAddOption("Duplex", "None", + doc->num_options, &(doc->options)); + + if (cupsGetOption("EFDuplex", doc->num_options, doc->options)) + doc->num_options = cupsAddOption("EFDuplex", "None", + doc->num_options, &(doc->options)); + + if (cupsGetOption("EFDuplexing", doc->num_options, doc->options)) + doc->num_options = cupsAddOption("EFDuplexing", "False", + doc->num_options, &(doc->options)); + + if (cupsGetOption("KD03Duplex", doc->num_options, doc->options)) + doc->num_options = cupsAddOption("KD03Duplex", "None", + doc->num_options, &(doc->options)); + + if (cupsGetOption("JCLDuplex", doc->num_options, doc->options)) + doc->num_options = cupsAddOption("JCLDuplex", "None", + doc->num_options, &(doc->options)); + + ppdMarkOption(ppd, "Duplex", "None"); + ppdMarkOption(ppd, "EFDuplex", "None"); + ppdMarkOption(ppd, "EFDuplexing", "False"); + ppdMarkOption(ppd, "KD03Duplex", "None"); + ppdMarkOption(ppd, "JCLDuplex", "None"); + } + } + else if (!strncmp(line, "%%BoundingBox:", 14)) + { + if (saw_bounding_box) + _cupsLangPuts(stderr, + _("ERROR: Duplicate %%BoundingBox: comment seen!\n")); + else if (strstr(line + 14, "(atend)")) + { + /* + * Do nothing for now but use the default imageable area... + */ + } + else if (sscanf(line + 14, "%d%d%d%d", doc->bounding_box + 0, + doc->bounding_box + 1, doc->bounding_box + 2, + doc->bounding_box + 3) != 4) + { + _cupsLangPuts(stderr, _("ERROR: Bad %%BoundingBox: comment seen!\n")); + + doc->bounding_box[0] = (int)PageLeft; + doc->bounding_box[1] = (int)PageBottom; + doc->bounding_box[2] = (int)PageRight; + doc->bounding_box[3] = (int)PageTop; + } + + saw_bounding_box = 1; + } + else if (!strncmp(line, "%%For:", 6)) + { + saw_for = 1; + doc_printf(doc, "%s\n", line); + } + else if (!strncmp(line, "%%Title:", 8)) + { + saw_title = 1; + doc_printf(doc, "%s\n", line); + } + else if (!strncmp(line, "%cupsRotation:", 14)) + { + /* + * Reset orientation of document? + */ + + int orient = (atoi(line + 14) / 90) & 3; + + if (orient != Orientation) + { + /* + * Yes, update things so that the pages come out right... + */ + + Orientation = (4 - Orientation + orient) & 3; + UpdatePageVars(); + Orientation = orient; + } + } + else if (!strcmp(line, "%%EndComments")) + { + linelen = cupsFileGetLine(fp, line, linesize); + break; + } + else if (strncmp(line, "%!", 2) && strncmp(line, "%cups", 5)) + doc_printf(doc, "%s\n", line); + + if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0) + break; + } + + if (!saw_bounding_box) + _cupsLangPuts(stderr, _("ERROR: No %%BoundingBox: comment in header!\n")); + + if (!saw_pages) + _cupsLangPuts(stderr, _("ERROR: No %%Pages: comment in header!\n")); + + if (!saw_for) + WriteTextComment("For", doc->user); + + if (!saw_title) + WriteTextComment("Title", doc->title); + + if (doc->copies != 1 && (!doc->collate || !doc->slow_collate)) + { + /* + * Tell the document processor the copy and duplex options + * that are required... + */ + + doc_printf(doc, "%%%%Requirements: numcopies(%d)%s%s\n", doc->copies, + doc->collate ? " collate" : "", + Duplex ? " duplex" : ""); + + /* + * Apple uses RBI comments for various non-PPD options... + */ + + doc_printf(doc, "%%RBINumCopies: %d\n", doc->copies); + } + else + { + /* + * Tell the document processor the duplex option that is required... + */ + + if (Duplex) + doc_puts(doc, "%%Requirements: duplex\n"); + + /* + * Apple uses RBI comments for various non-PPD options... + */ + + doc_puts(doc, "%RBINumCopies: 1\n"); + } + + doc_puts(doc, "%%Pages: (atend)\n"); + doc_puts(doc, "%%BoundingBox: (atend)\n"); + doc_puts(doc, "%%EndComments\n"); + + return (linelen); +} + + +/* + * 'copy_dsc()' - Copy a DSC-conforming document. + * + * This function expects "line" to be filled with the %!PS-Adobe comment line. + */ + +static void +copy_dsc(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + int number; /* Page number */ + pstops_page_t *pageinfo; /* Page information */ + + + /* + * Make sure we use ESPshowpage for EPS files... + */ + + if (strstr(line, "EPSF")) + { + doc->use_ESPshowpage = 1; + doc->number_up = 1; + } + + /* + * Start sending the document with any commands needed... + */ + + fprintf(stderr, "DEBUG: Before copy_comments - %s", line); + linelen = copy_comments(fp, doc, ppd, line, linelen, linesize); + + /* + * Now find the prolog section, if any... + */ + + fprintf(stderr, "DEBUG: Before copy_prolog - %s", line); + linelen = copy_prolog(fp, doc, ppd, line, linelen, linesize); + + /* + * Then the document setup section... + */ + + fprintf(stderr, "DEBUG: Before copy_setup - %s", line); + linelen = copy_setup(fp, doc, ppd, line, linelen, linesize); + + /* + * Copy until we see %%Page:... + */ + + while (strncmp(line, "%%Page:", 7) && strncmp(line, "%%Trailer", 9)) + { + doc_write(doc, line, linelen); + + if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0) + break; + } + + /* + * Then process pages until we have no more... + */ + + number = 0; + + fprintf(stderr, "DEBUG: Before page loop - %s", line); + while (!strncmp(line, "%%Page:", 7)) + { + if (JobCanceled) + break; + + number ++; + + if (check_range(doc, (number - 1) / doc->number_up + 1)) + { + fprintf(stderr, "DEBUG: Copying page %d...\n", number); + linelen = copy_page(fp, doc, ppd, number, line, linelen, linesize); + } + else + { + fprintf(stderr, "DEBUG: Skipping page %d...\n", number); + linelen = skip_page(fp, line, linelen, linesize); + } + } + + /* + * Finish up the last page(s)... + */ + + if (number && is_not_last_page(number) && cupsArrayLast(doc->pages) && + check_range(doc, (number - 1) / doc->number_up + 1)) + { + pageinfo = (pstops_page_t *)cupsArrayLast(doc->pages); + + start_nup(doc, doc->number_up, 0, doc->bounding_box); + doc_puts(doc, "showpage\n"); + end_nup(doc, doc->number_up); + + pageinfo->length = cupsFileTell(doc->temp) - pageinfo->offset; + } + + if (doc->slow_duplex && (doc->page & 1)) + { + /* + * Make sure we have an even number of pages... + */ + + pageinfo = add_page(doc, "(filler)"); + + if (!doc->slow_order) + { + if (!ppd || !ppd->num_filters) + fprintf(stderr, "PAGE: %d %d\n", doc->page, + doc->slow_collate ? 1 : doc->copies); + + printf("%%%%Page: (filler) %d\n", doc->page); + } + + start_nup(doc, doc->number_up, 0, doc->bounding_box); + doc_puts(doc, "showpage\n"); + end_nup(doc, doc->number_up); + + pageinfo->length = cupsFileTell(doc->temp) - pageinfo->offset; + } + + /* + * Make additional copies as necessary... + */ + + number = doc->slow_order ? 0 : doc->page; + + if (doc->temp && !JobCanceled && cupsArrayCount(doc->pages) > 0) + { + int copy; /* Current copy */ + + + /* + * Reopen the temporary file for reading... + */ + + cupsFileClose(doc->temp); + + doc->temp = cupsFileOpen(doc->tempfile, "r"); + + /* + * Make the copies... + */ + + if (doc->slow_collate) + copy = !doc->slow_order; + else + copy = doc->copies - 1; + + for (; copy < doc->copies; copy ++) + { + if (JobCanceled) + break; + + /* + * Send end-of-job stuff followed by any start-of-job stuff required + * for the JCL options... + */ + + if (number && doc->emit_jcl && ppd && ppd->jcl_end) + { + /* + * Send the trailer... + */ + + puts("%%Trailer"); + printf("%%%%Pages: %d\n", cupsArrayCount(doc->pages)); + if (doc->number_up > 1 || doc->fitplot) + printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", + PageLeft, PageBottom, PageRight, PageTop); + else + printf("%%%%BoundingBox: %d %d %d %d\n", + doc->new_bounding_box[0], doc->new_bounding_box[1], + doc->new_bounding_box[2], doc->new_bounding_box[3]); + puts("%%EOF"); + + /* + * Start a new document... + */ + + ppdEmitJCLEnd(ppd, stdout); + ppdEmitJCL(ppd, stdout, doc->job_id, doc->user, doc->title); + + puts("%!PS-Adobe-3.0"); + + number = 0; + } + + /* + * Copy the prolog as needed... + */ + + if (!number) + { + pageinfo = (pstops_page_t *)cupsArrayFirst(doc->pages); + copy_bytes(doc->temp, 0, pageinfo->offset); + } + + /* + * Then copy all of the pages... + */ + + pageinfo = doc->slow_order ? (pstops_page_t *)cupsArrayLast(doc->pages) : + (pstops_page_t *)cupsArrayFirst(doc->pages); + + while (pageinfo) + { + if (JobCanceled) + break; + + number ++; + + if (!ppd || !ppd->num_filters) + fprintf(stderr, "PAGE: %d %d\n", number, + doc->slow_collate ? 1 : doc->copies); + + if (doc->number_up > 1) + { + printf("%%%%Page: (%d) %d\n", number, number); + printf("%%%%PageBoundingBox: %.0f %.0f %.0f %.0f\n", + PageLeft, PageBottom, PageRight, PageTop); + } + else + { + printf("%%%%Page: %s %d\n", pageinfo->label, number); + printf("%%%%PageBoundingBox: %d %d %d %d\n", + pageinfo->bounding_box[0], pageinfo->bounding_box[1], + pageinfo->bounding_box[2], pageinfo->bounding_box[3]); + } + + copy_bytes(doc->temp, pageinfo->offset, pageinfo->length); + + pageinfo = doc->slow_order ? (pstops_page_t *)cupsArrayPrev(doc->pages) : + (pstops_page_t *)cupsArrayNext(doc->pages); + } + } + } + + /* + * Restore the old showpage operator as needed... + */ + + if (doc->use_ESPshowpage) + puts("userdict/showpage/ESPshowpage load put\n"); + + /* + * Write/copy the trailer... + */ + + if (!JobCanceled) + copy_trailer(fp, doc, ppd, number, line, linelen, linesize); +} + + +/* + * 'copy_non_dsc()' - Copy a document that does not conform to the DSC. + * + * This function expects "line" to be filled with the %! comment line. + */ + +static void +copy_non_dsc(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + int copy; /* Current copy */ + char buffer[8192]; /* Copy buffer */ + int bytes; /* Number of bytes copied */ + + + /* + * First let the user know that they are attempting to print a file + * that may not print correctly... + */ + + _cupsLangPuts(stderr, + _("WARNING: This document does not conform to the Adobe " + "Document Structuring Conventions and may not print " + "correctly!\n")); + + /* + * Then write a standard DSC comment section... + */ + + printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, + PageRight, PageTop); + + if (doc->slow_collate && doc->copies > 1) + printf("%%%%Pages: %d\n", doc->copies); + else + puts("%%Pages: 1"); + + WriteTextComment("For", doc->user); + WriteTextComment("Title", doc->title); + + if (doc->copies != 1 && (!doc->collate || !doc->slow_collate)) + { + /* + * Tell the document processor the copy and duplex options + * that are required... + */ + + printf("%%%%Requirements: numcopies(%d)%s%s\n", doc->copies, + doc->collate ? " collate" : "", + Duplex ? " duplex" : ""); + + /* + * Apple uses RBI comments for various non-PPD options... + */ + + printf("%%RBINumCopies: %d\n", doc->copies); + } + else + { + /* + * Tell the document processor the duplex option that is required... + */ + + if (Duplex) + puts("%%Requirements: duplex"); + + /* + * Apple uses RBI comments for various non-PPD options... + */ + + puts("%RBINumCopies: 1"); + } + + puts("%%EndComments"); + + /* + * Then the prolog... + */ + + puts("%%BeginProlog"); + + do_prolog(doc, ppd); + + puts("%%EndProlog"); + + /* + * Then the setup section... + */ + + puts("%%BeginSetup"); + + do_setup(doc, ppd); + + puts("%%EndSetup"); + + /* + * Finally, embed a copy of the file inside a %%Page... + */ + + if (!ppd || !ppd->num_filters) + fprintf(stderr, "PAGE: 1 %d\n", doc->temp ? 1 : doc->copies); + + puts("%%Page: 1 1"); + puts("%%BeginPageSetup"); + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + puts("%%EndPageSetup"); + puts("%%BeginDocument: nondsc"); + + fwrite(line, linelen, 1, stdout); + + if (doc->temp) + cupsFileWrite(doc->temp, line, linelen); + + while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) + { + fwrite(buffer, 1, bytes, stdout); + + if (doc->temp) + cupsFileWrite(doc->temp, buffer, bytes); + } + + puts("%%EndDocument"); + + if (doc->use_ESPshowpage) + { + WriteLabels(Orientation); + puts("ESPshowpage"); + } + + if (doc->temp && !JobCanceled) + { + /* + * Reopen the temporary file for reading... + */ + + cupsFileClose(doc->temp); + + doc->temp = cupsFileOpen(doc->tempfile, "r"); + + /* + * Make the additional copies as needed... + */ + + for (copy = 1; copy < doc->copies; copy ++) + { + if (JobCanceled) + break; + + if (!ppd || !ppd->num_filters) + fputs("PAGE: 1 1\n", stderr); + + printf("%%%%Page: %d %d\n", copy + 1, copy + 1); + puts("%%BeginPageSetup"); + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + puts("%%EndPageSetup"); + puts("%%BeginDocument: nondsc"); + + copy_bytes(doc->temp, 0, 0); + + puts("%%EndDocument"); + + if (doc->use_ESPshowpage) + { + WriteLabels(Orientation); + puts("ESPshowpage"); + } + } + } + + /* + * Restore the old showpage operator as needed... + */ + + if (doc->use_ESPshowpage) + puts("userdict/showpage/ESPshowpage load put\n"); +} + + +/* + * 'copy_page()' - Copy a page description. + * + * This function expects "line" to be filled with a %%Page comment line. + * On return, "line" will contain the next line in the file, if any. + */ + +static ssize_t /* O - Length of next line */ +copy_page(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + int number, /* I - Current page number */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + char label[256], /* Page label string */ + *ptr; /* Pointer into line */ + int level; /* Embedded document level */ + pstops_page_t *pageinfo; /* Page information */ + int first_page; /* First page on N-up output? */ + int has_page_setup; /* Does the page have %%Begin/EndPageSetup? */ + int bounding_box[4]; /* PageBoundingBox */ + + + /* + * Get the page label for this page... + */ + + first_page = is_first_page(number); + + if (!parse_text(line + 7, &ptr, label, sizeof(label))) + { + _cupsLangPuts(stderr, _("ERROR: Bad %%Page: comment in file!\n")); + label[0] = '\0'; + number = doc->page; + } + else if (strtol(ptr, &ptr, 10) == LONG_MAX || !isspace(*ptr & 255)) + { + _cupsLangPuts(stderr, _("ERROR: Bad %%Page: comment in file!\n")); + number = doc->page; + } + + /* + * Create or update the current output page... + */ + + if (first_page) + pageinfo = add_page(doc, label); + else + pageinfo = (pstops_page_t *)cupsArrayLast(doc->pages); + + /* + * Handle first page override... + */ + + if (doc->ap_input_slot || doc->ap_manual_feed) + { + if (doc->page == 1) + { + /* + * First page/sheet gets AP_FIRSTPAGE_* options... + */ + + pageinfo->num_options = cupsAddOption("InputSlot", doc->ap_input_slot, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("ManualFeed", + doc->ap_input_slot ? "False" : + doc->ap_manual_feed, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("MediaColor", doc->ap_media_color, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("MediaType", doc->ap_media_type, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("PageRegion", doc->ap_page_region, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("PageSize", doc->ap_page_size, + pageinfo->num_options, + &(pageinfo->options)); + } + else if (doc->page == (Duplex + 2)) + { + /* + * Second page/sheet gets default options... + */ + + pageinfo->num_options = cupsAddOption("InputSlot", doc->input_slot, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("ManualFeed", + doc->input_slot ? "False" : + doc->manual_feed, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("MediaColor", doc->media_color, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("MediaType", doc->media_type, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("PageRegion", doc->page_region, + pageinfo->num_options, + &(pageinfo->options)); + pageinfo->num_options = cupsAddOption("PageSize", doc->page_size, + pageinfo->num_options, + &(pageinfo->options)); + } + } + + /* + * Scan comments until we see something other than %%Page*: or + * %%Include*... + */ + + memcpy(bounding_box, doc->bounding_box, sizeof(bounding_box)); + + while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0) + { + if (!strncmp(line, "%%PageBoundingBox:", 18)) + { + /* + * %%PageBoundingBox: llx lly urx ury + */ + + if (sscanf(line + 18, "%d%d%d%d", bounding_box + 0, + bounding_box + 1, bounding_box + 2, + bounding_box + 3) != 4) + { + _cupsLangPuts(stderr, + _("ERROR: Bad %%PageBoundingBox: comment in file!\n")); + memcpy(bounding_box, doc->bounding_box, + sizeof(bounding_box)); + } + else if (doc->number_up == 1 && !doc->fitplot && Orientation) + { + int temp_bbox[4]; /* Temporary bounding box */ + + + memcpy(temp_bbox, bounding_box, sizeof(temp_bbox)); + + fprintf(stderr, "DEBUG: Orientation = %d\n", Orientation); + fprintf(stderr, "DEBUG: original bounding_box = [ %d %d %d %d ]\n", + bounding_box[0], bounding_box[1], + bounding_box[2], bounding_box[3]); + fprintf(stderr, "DEBUG: PageWidth = %.1f, PageLength = %.1f\n", + PageWidth, PageLength); + + switch (Orientation) + { + case 1 : /* Landscape */ + bounding_box[0] = PageLength - temp_bbox[3]; + bounding_box[1] = temp_bbox[0]; + bounding_box[2] = PageLength - temp_bbox[1]; + bounding_box[3] = temp_bbox[2]; + break; + + case 2 : /* Reverse Portrait */ + bounding_box[0] = PageWidth - temp_bbox[2]; + bounding_box[1] = PageLength - temp_bbox[3]; + bounding_box[2] = PageWidth - temp_bbox[0]; + bounding_box[3] = PageLength - temp_bbox[1]; + break; + + case 3 : /* Reverse Landscape */ + bounding_box[0] = temp_bbox[1]; + bounding_box[1] = PageWidth - temp_bbox[2]; + bounding_box[2] = temp_bbox[3]; + bounding_box[3] = PageWidth - temp_bbox[0]; + break; + } + + fprintf(stderr, "DEBUG: updated bounding_box = [ %d %d %d %d ]\n", + bounding_box[0], bounding_box[1], + bounding_box[2], bounding_box[3]); + } + } +#if 0 + else if (!strncmp(line, "%%PageCustomColors:", 19) || + !strncmp(line, "%%PageMedia:", 12) || + !strncmp(line, "%%PageOrientation:", 18) || + !strncmp(line, "%%PageProcessColors:", 20) || + !strncmp(line, "%%PageRequirements:", 18) || + !strncmp(line, "%%PageResources:", 16)) + { + /* + * Copy literal... + */ + } +#endif /* 0 */ + else if (!strncmp(line, "%%PageCustomColors:", 19)) + { + /* + * %%PageCustomColors: ... + */ + } + else if (!strncmp(line, "%%PageMedia:", 12)) + { + /* + * %%PageMedia: ... + */ + } + else if (!strncmp(line, "%%PageOrientation:", 18)) + { + /* + * %%PageOrientation: ... + */ + } + else if (!strncmp(line, "%%PageProcessColors:", 20)) + { + /* + * %%PageProcessColors: ... + */ + } + else if (!strncmp(line, "%%PageRequirements:", 18)) + { + /* + * %%PageRequirements: ... + */ + } + else if (!strncmp(line, "%%PageResources:", 16)) + { + /* + * %%PageResources: ... + */ + } + else if (!strncmp(line, "%%IncludeFeature:", 17)) + { + /* + * %%IncludeFeature: *MainKeyword OptionKeyword + */ + + if (doc->number_up == 1 &&!doc->fitplot) + pageinfo->num_options = include_feature(ppd, line, + pageinfo->num_options, + &(pageinfo->options)); + } + else if (strncmp(line, "%%Include", 9)) + break; + } + + if (doc->number_up == 1) + { + /* + * Update the document's composite and page bounding box... + */ + + memcpy(pageinfo->bounding_box, bounding_box, + sizeof(pageinfo->bounding_box)); + + if (bounding_box[0] < doc->new_bounding_box[0]) + doc->new_bounding_box[0] = bounding_box[0]; + if (bounding_box[1] < doc->new_bounding_box[1]) + doc->new_bounding_box[1] = bounding_box[1]; + if (bounding_box[2] > doc->new_bounding_box[2]) + doc->new_bounding_box[2] = bounding_box[2]; + if (bounding_box[3] > doc->new_bounding_box[3]) + doc->new_bounding_box[3] = bounding_box[3]; + } + + /* + * Output the page header as needed... + */ + + if (!doc->slow_order && first_page) + { + if (!ppd || !ppd->num_filters) + fprintf(stderr, "PAGE: %d %d\n", doc->page, + doc->slow_collate ? 1 : doc->copies); + + if (doc->number_up > 1) + { + printf("%%%%Page: (%d) %d\n", doc->page, doc->page); + printf("%%%%PageBoundingBox: %.0f %.0f %.0f %.0f\n", + PageLeft, PageBottom, PageRight, PageTop); + } + else + { + printf("%%%%Page: %s %d\n", pageinfo->label, doc->page); + printf("%%%%PageBoundingBox: %d %d %d %d\n", + pageinfo->bounding_box[0], pageinfo->bounding_box[1], + pageinfo->bounding_box[2], pageinfo->bounding_box[3]); + } + } + + /* + * Copy any page setup commands... + */ + + if (first_page) + doc_puts(doc, "%%BeginPageSetup\n"); + + if ((has_page_setup = !strncmp(line, "%%BeginPageSetup", 16)) != 0) + { + int feature = 0; /* In a Begin/EndFeature block? */ + + while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0) + { + if (!strncmp(line, "%%EndPageSetup", 14)) + break; + else if (!strncmp(line, "%%BeginFeature:", 15)) + { + feature = 1; + + if (doc->number_up > 1 || doc->fitplot) + continue; + } + else if (!strncmp(line, "%%EndFeature", 12)) + { + feature = 0; + + if (doc->number_up > 1 || doc->fitplot) + continue; + } + else if (!strncmp(line, "%%IncludeFeature:", 17)) + { + pageinfo->num_options = include_feature(ppd, line, + pageinfo->num_options, + &(pageinfo->options)); + continue; + } + else if (!strncmp(line, "%%Include", 9)) + continue; + + if (line[0] != '%' && !feature) + break; + + if (!feature || (doc->number_up == 1 && !doc->fitplot)) + doc_write(doc, line, linelen); + } + + /* + * Skip %%EndPageSetup... + */ + + if (linelen > 0 && !strncmp(line, "%%EndPageSetup", 14)) + { + linelen = cupsFileGetLine(fp, line, linesize); + has_page_setup = 0; + } + } + + if (first_page) + { + char *page_setup; /* PageSetup commands to send */ + + + if (pageinfo->num_options > 0) + write_options(doc, ppd, pageinfo->num_options, pageinfo->options); + + /* + * Output commands for the current page... + */ + + page_setup = ppdEmitString(ppd, PPD_ORDER_PAGE, 0); + + if (page_setup) + { + doc_puts(doc, page_setup); + free(page_setup); + } + } + + /* + * Prep for the start of the page description... + */ + + start_nup(doc, number, 1, bounding_box); + + /* + * Finish the PageSetup section as needed... + */ + + if (has_page_setup) + { + int feature = 0; /* In a Begin/EndFeature block? */ + + doc_write(doc, line, linelen); + + while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0) + { + if (!strncmp(line, "%%EndPageSetup", 14)) + break; + else if (!strncmp(line, "%%BeginFeature:", 15)) + { + feature = 1; + + if (doc->number_up > 1 || doc->fitplot) + continue; + } + else if (!strncmp(line, "%%EndFeature", 12)) + { + feature = 0; + + if (doc->number_up > 1 || doc->fitplot) + continue; + } + else if (!strncmp(line, "%%Include", 9)) + continue; + + if (!feature || (doc->number_up == 1 && !doc->fitplot)) + doc_write(doc, line, linelen); + } + + /* + * Skip %%EndPageSetup... + */ + + if (linelen > 0 && !strncmp(line, "%%EndPageSetup", 14)) + linelen = cupsFileGetLine(fp, line, linesize); + } + + if (first_page) + doc_puts(doc, "%%EndPageSetup\n"); + + /* + * Read the rest of the page description... + */ + + level = 0; + + do + { + if (level == 0 && + (!strncmp(line, "%%Page:", 7) || + !strncmp(line, "%%Trailer", 9) || + !strncmp(line, "%%EOF", 5))) + break; + else if (!strncmp(line, "%%BeginDocument", 15) || + !strncmp(line, "%ADO_BeginApplication", 21)) + { + doc_write(doc, line, linelen); + + level ++; + } + else if ((!strncmp(line, "%%EndDocument", 13) || + !strncmp(line, "%ADO_EndApplication", 19)) && level > 0) + { + doc_write(doc, line, linelen); + + level --; + } + else if (!strncmp(line, "%%BeginBinary:", 14) || + (!strncmp(line, "%%BeginData:", 12) && + !strstr(line, "ASCII") && !strstr(line, "Hex"))) + { + /* + * Copy binary data... + */ + + int bytes; /* Bytes of data */ + + + doc_write(doc, line, linelen); + + bytes = atoi(strchr(line, ':') + 1); + + while (bytes > 0) + { + if (bytes > linesize) + linelen = cupsFileRead(fp, line, linesize); + else + linelen = cupsFileRead(fp, line, bytes); + + if (linelen < 1) + { + line[0] = '\0'; + perror("ERROR: Early end-of-file while reading binary data"); + return (0); + } + + doc_write(doc, line, linelen); + + bytes -= linelen; + } + } + else + doc_write(doc, line, linelen); + } + while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0); + + /* + * Finish up this page and return... + */ + + end_nup(doc, number); + + pageinfo->length = cupsFileTell(doc->temp) - pageinfo->offset; + + return (linelen); +} + + +/* + * 'copy_prolog()' - Copy the document prolog section. + * + * This function expects "line" to be filled with a %%BeginProlog comment line. + * On return, "line" will contain the next line in the file, if any. + */ + +static ssize_t /* O - Length of next line */ +copy_prolog(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + while (strncmp(line, "%%BeginProlog", 13)) + { + if (!strncmp(line, "%%BeginSetup", 12) || !strncmp(line, "%%Page:", 7)) + break; + + doc_write(doc, line, linelen); + + if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0) + break; + } + + doc_puts(doc, "%%BeginProlog\n"); + + do_prolog(doc, ppd); + + if (!strncmp(line, "%%BeginProlog", 13)) + { + while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0) + { + if (!strncmp(line, "%%EndProlog", 11) || + !strncmp(line, "%%BeginSetup", 12) || + !strncmp(line, "%%Page:", 7)) + break; + + doc_write(doc, line, linelen); + } + + if (!strncmp(line, "%%EndProlog", 11)) + linelen = cupsFileGetLine(fp, line, linesize); + else + _cupsLangPuts(stderr, _("ERROR: Missing %%EndProlog!\n")); + } + + doc_puts(doc, "%%EndProlog\n"); + + return (linelen); +} + + +/* + * 'copy_setup()' - Copy the document setup section. + * + * This function expects "line" to be filled with a %%BeginSetup comment line. + * On return, "line" will contain the next line in the file, if any. + */ + +static ssize_t /* O - Length of next line */ +copy_setup(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + + + while (strncmp(line, "%%BeginSetup", 12)) + { + if (!strncmp(line, "%%Page:", 7)) + break; + + doc_write(doc, line, linelen); + + if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0) + break; + } + + doc_puts(doc, "%%BeginSetup\n"); + + do_setup(doc, ppd); + + num_options = 0; + options = NULL; + + if (!strncmp(line, "%%BeginSetup", 12)) + { + while (strncmp(line, "%%EndSetup", 10)) + { + if (!strncmp(line, "%%Page:", 7)) + break; + else if (!strncmp(line, "%%IncludeFeature:", 17)) + { + /* + * %%IncludeFeature: *MainKeyword OptionKeyword + */ + + if (doc->number_up == 1 && !doc->fitplot) + num_options = include_feature(ppd, line, num_options, &options); + } + else if (strncmp(line, "%%BeginSetup", 12)) + doc_write(doc, line, linelen); + + if ((linelen = cupsFileGetLine(fp, line, linesize)) == 0) + break; + } + + if (!strncmp(line, "%%EndSetup", 10)) + linelen = cupsFileGetLine(fp, line, linesize); + else + _cupsLangPuts(stderr, _("ERROR: Missing %%EndSetup!\n")); + } + + if (num_options > 0) + { + write_options(doc, ppd, num_options, options); + cupsFreeOptions(num_options, options); + } + + doc_puts(doc, "%%EndSetup\n"); + + return (linelen); +} + + +/* + * 'copy_trailer()' - Copy the document trailer. + * + * This function expects "line" to be filled with a %%Trailer comment line. + * On return, "line" will contain the next line in the file, if any. + */ + +static ssize_t /* O - Length of next line */ +copy_trailer(cups_file_t *fp, /* I - File to read from */ + pstops_doc_t *doc, /* I - Document info */ + ppd_file_t *ppd, /* I - PPD file */ + int number, /* I - Number of pages */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + /* + * Write the trailer comments... + */ + + puts("%%Trailer"); + + while (linelen > 0) + { + if (!strncmp(line, "%%EOF", 5)) + break; + else if (strncmp(line, "%%Trailer", 9) && + strncmp(line, "%%Pages:", 8) && + strncmp(line, "%%BoundingBox:", 14)) + fwrite(line, 1, linelen, stdout); + + linelen = cupsFileGetLine(fp, line, linesize); + } + + fprintf(stderr, "DEBUG: Wrote %d pages...\n", number); + + printf("%%%%Pages: %d\n", number); + if (doc->number_up > 1 || doc->fitplot) + printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", + PageLeft, PageBottom, PageRight, PageTop); + else + printf("%%%%BoundingBox: %d %d %d %d\n", + doc->new_bounding_box[0], doc->new_bounding_box[1], + doc->new_bounding_box[2], doc->new_bounding_box[3]); + + return (linelen); +} + + +/* + * 'do_prolog()' - Send the necessary document prolog commands. + */ + +static void +do_prolog(pstops_doc_t *doc, /* I - Document information */ + ppd_file_t *ppd) /* I - PPD file */ +{ + char *ps; /* PS commands */ + + + /* + * Send the document prolog commands... + */ + + if (ppd && ppd->patches) + { + doc_puts(doc, "%%BeginFeature: *JobPatchFile 1\n"); + doc_puts(doc, ppd->patches); + doc_puts(doc, "\n%%EndFeature\n"); + } + + if ((ps = ppdEmitString(ppd, PPD_ORDER_PROLOG, 0.0)) != NULL) + { + doc_puts(doc, ps); + free(ps); + } + + /* + * Define ESPshowpage here so that applications that define their + * own procedure to do a showpage pick it up... + */ + + if (doc->use_ESPshowpage) + doc_puts(doc, "userdict/ESPshowpage/showpage load put\n" + "userdict/showpage{}put\n"); +} + + +/* + * 'do_setup()' - Send the necessary document setup commands. + */ + +static void +do_setup(pstops_doc_t *doc, /* I - Document information */ + ppd_file_t *ppd) /* I - PPD file */ +{ + char *ps; /* PS commands */ + + + /* + * Disable CTRL-D so that embedded files don't cause printing + * errors... + */ + + doc_puts(doc, "% Disable CTRL-D as an end-of-file marker...\n"); + doc_puts(doc, "userdict dup(\\004)cvn{}put (\\004\\004)cvn{}put\n"); + + /* + * Mark job options... + */ + + cupsMarkOptions(ppd, doc->num_options, doc->options); + + /* + * Send all the printer-specific setup commands... + */ + + if ((ps = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, 0.0)) != NULL) + { + doc_puts(doc, ps); + free(ps); + } + + if ((ps = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL) + { + doc_puts(doc, ps); + free(ps); + } + + /* + * Set the number of copies for the job... + */ + + if (doc->copies != 1 && (!doc->collate || !doc->slow_collate)) + { + doc_printf(doc, "%%RBIBeginNonPPDFeature: *NumCopies %d\n", doc->copies); + doc_printf(doc, + "%d/languagelevel where{pop languagelevel 2 ge}{false}ifelse\n" + "{1 dict begin/NumCopies exch def currentdict end " + "setpagedevice}\n" + "{userdict/#copies 3 -1 roll put}ifelse\n", doc->copies); + doc_puts(doc, "%RBIEndNonPPDFeature\n"); + } + + /* + * If we are doing N-up printing, disable setpagedevice... + */ + + if (doc->number_up > 1) + { + doc_puts(doc, "userdict/CUPSsetpagedevice/setpagedevice load put\n"); + doc_puts(doc, "userdict/setpagedevice{pop}bind put\n"); + } + + /* + * Changes to the transfer function must be made AFTER any + * setpagedevice code... + */ + + if (doc->gamma != 1.0f || doc->brightness != 1.0f) + doc_printf(doc, "{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } " + "ifelse %.3f mul } bind settransfer\n", + doc->gamma, doc->brightness); + + /* + * Make sure we have rectclip and rectstroke procedures of some sort... + */ + + doc_puts(doc, + "% 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\n"); + + doc_puts(doc, + "% 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"); + + doc_puts(doc, + "% 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"); + + /* + * Write the page and label prologs... + */ + + if (doc->number_up == 2 || doc->number_up == 6) + { + /* + * For 2- and 6-up output, rotate the labels to match the orientation + * of the pages... + */ + + if (Orientation & 1) + write_label_prolog(doc, doc->page_label, PageBottom, + PageWidth - PageLength + PageTop, PageLength); + else + write_label_prolog(doc, doc->page_label, PageLeft, PageRight, + PageLength); + } + else + write_label_prolog(doc, doc->page_label, PageBottom, PageTop, PageWidth); +} + + +/* + * 'doc_printf()' - Send a formatted string to stdout and/or the temp file. + * + * This function should be used for all page-level output that is affected + * by ordering, collation, etc. + */ + +static void +doc_printf(pstops_doc_t *doc, /* I - Document information */ + const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to arguments */ + char buffer[1024]; /* Output buffer */ + size_t bytes; /* Number of bytes to write */ + + + va_start(ap, format); + bytes = vsnprintf(buffer, sizeof(buffer), format, ap); + va_end(ap); + + if (bytes > sizeof(buffer)) + { + _cupsLangPrintf(stderr, + _("ERROR: doc_printf overflow (%d bytes) detected, " + "aborting!\n"), (int)bytes); + exit(1); + } + + doc_write(doc, buffer, bytes); +} + + +/* + * 'doc_puts()' - Send a nul-terminated string to stdout and/or the temp file. + * + * This function should be used for all page-level output that is affected + * by ordering, collation, etc. + */ + +static void +doc_puts(pstops_doc_t *doc, /* I - Document information */ + const char *s) /* I - String to send */ +{ + doc_write(doc, s, strlen(s)); +} + + +/* + * 'doc_write()' - Send data to stdout and/or the temp file. + */ + +static void +doc_write(pstops_doc_t *doc, /* I - Document information */ + const char *s, /* I - Data to send */ + size_t len) /* I - Number of bytes to send */ +{ + if (!doc->slow_order) + fwrite(s, 1, len, stdout); + + if (doc->temp) + cupsFileWrite(doc->temp, s, len); +} + + +/* + * 'end_nup()' - End processing for N-up printing. + */ + +static void +end_nup(pstops_doc_t *doc, /* I - Document information */ + int number) /* I - Page number */ +{ + if (doc->number_up > 1) + doc_puts(doc, "userdict/ESPsave get restore\n"); + + switch (doc->number_up) + { + case 1 : + if (doc->use_ESPshowpage) + { + write_labels(doc, Orientation); + doc_puts(doc, "ESPshowpage\n"); + } + break; + + case 2 : + case 6 : + if (is_last_page(number) && doc->use_ESPshowpage) + { + if (Orientation & 1) + { + /* + * Rotate the labels back to portrait... + */ + + write_labels(doc, Orientation - 1); + } + else if (Orientation == 0) + { + /* + * Rotate the labels to landscape... + */ + + write_labels(doc, doc->normal_landscape ? 1 : 3); + } + else + { + /* + * Rotate the labels to landscape... + */ + + write_labels(doc, doc->normal_landscape ? 3 : 1); + } + + doc_puts(doc, "ESPshowpage\n"); + } + break; + + default : + if (is_last_page(number) && doc->use_ESPshowpage) + { + write_labels(doc, Orientation); + doc_puts(doc, "ESPshowpage\n"); + } + break; + } + + fflush(stdout); +} + + +/* + * 'include_feature()' - Include a printer option/feature command. + */ + +static int /* O - New number of options */ +include_feature( + ppd_file_t *ppd, /* I - PPD file */ + const char *line, /* I - DSC line */ + int num_options, /* I - Number of options */ + cups_option_t **options) /* IO - Options */ +{ + char name[255], /* Option name */ + value[255]; /* Option value */ + ppd_option_t *option; /* Option in file */ + + + /* + * Get the "%%IncludeFeature: *Keyword OptionKeyword" values... + */ + + if (sscanf(line + 17, "%254s%254s", name, value) != 2) + { + _cupsLangPuts(stderr, _("ERROR: Bad %%IncludeFeature: comment!\n")); + return (num_options); + } + + /* + * Find the option and choice... + */ + + if ((option = ppdFindOption(ppd, name + 1)) == NULL) + { + _cupsLangPrintf(stderr, _("WARNING: Unknown option \"%s\"!\n"), name + 1); + return (num_options); + } + + if (option->section == PPD_ORDER_EXIT || + option->section == PPD_ORDER_JCL) + { + _cupsLangPrintf(stderr, _("WARNING: Option \"%s\" cannot be included via " + "IncludeFeature!\n"), name + 1); + return (num_options); + } + + if (!ppdFindChoice(option, value)) + { + _cupsLangPrintf(stderr, + _("WARNING: Unknown choice \"%s\" for option \"%s\"!\n"), + value, name + 1); + return (num_options); + } + + /* + * Add the option to the option array and return... + */ + + return (cupsAddOption(name + 1, value, num_options, options)); +} + + +/* + * 'parse_text()' - Parse a text value in a comment. + * + * This function parses a DSC text value as defined on page 36 of the + * DSC specification. Text values are either surrounded by parenthesis + * or whitespace-delimited. + * + * The value returned is the literal characters for the entire text + * string, including any parenthesis and escape characters. + */ + +static char * /* O - Value or NULL on error */ +parse_text(const char *start, /* I - Start of text value */ + char **end, /* O - End of text value */ + char *buffer, /* I - Buffer */ + size_t bufsize) /* I - Size of buffer */ +{ + char *bufptr, /* Pointer in buffer */ + *bufend; /* End of buffer */ + int level; /* Parenthesis level */ + + + /* + * Skip leading whitespace... + */ + + while (isspace(*start & 255)) + start ++; + + /* + * Then copy the value... + */ + + level = 0; + bufptr = buffer; + bufend = buffer + bufsize - 1; + + while (bufptr < bufend) + { + if (isspace(*start & 255) && !level) + break; + + *bufptr++ = *start; + + if (*start == '(') + level ++; + else if (*start == ')') + { + if (!level) + { + start ++; + break; + } + else + level --; + } + else if (*start == '\\') + { + /* + * Copy escaped character... + */ + + int i; /* Looping var */ + + + for (i = 1; + i <= 3 && isdigit(start[i] & 255) && bufptr < bufend; + *bufptr++ = start[i], i ++); + } + + start ++; + } + + *bufptr = '\0'; + + /* + * Return the value and new pointer into the line... + */ + + if (end) + *end = (char *)start; + + if (bufptr == bufend) + return (NULL); + else + return (buffer); +} + + +/* + * 'set_pstops_options()' - Set pstops options. + */ + +static void +set_pstops_options( + pstops_doc_t *doc, /* I - Document information */ + ppd_file_t *ppd, /* I - PPD file */ + char *argv[], /* I - Command-line arguments */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + const char *val; /* Option value */ + int intval; /* Integer option value */ + ppd_attr_t *attr; /* PPD attribute */ + ppd_option_t *option; /* PPD option */ + ppd_choice_t *choice; /* PPD choice */ + const char *content_type; /* Original content type */ + + + /* + * Initialize document information structure... + */ + + memset(doc, 0, sizeof(pstops_doc_t)); + + doc->job_id = atoi(argv[1]); + doc->user = argv[2]; + doc->title = argv[3]; + doc->copies = atoi(argv[4]); + + if (ppd && ppd->landscape > 0) + doc->normal_landscape = 1; + + doc->bounding_box[0] = (int)PageLeft; + doc->bounding_box[1] = (int)PageBottom; + doc->bounding_box[2] = (int)PageRight; + doc->bounding_box[3] = (int)PageTop; + + doc->new_bounding_box[0] = INT_MAX; + doc->new_bounding_box[1] = INT_MAX; + doc->new_bounding_box[2] = INT_MIN; + doc->new_bounding_box[3] = INT_MIN; + + /* + * AP_FIRSTPAGE_* and the corresponding non-first-page options. + */ + + doc->ap_input_slot = cupsGetOption("AP_FIRSTPAGE_InputSlot", num_options, + options); + doc->ap_manual_feed = cupsGetOption("AP_FIRSTPAGE_ManualFeed", num_options, + options); + doc->ap_media_color = cupsGetOption("AP_FIRSTPAGE_MediaColor", num_options, + options); + doc->ap_media_type = cupsGetOption("AP_FIRSTPAGE_MediaType", num_options, + options); + doc->ap_page_region = cupsGetOption("AP_FIRSTPAGE_PageRegion", num_options, + options); + doc->ap_page_size = cupsGetOption("AP_FIRSTPAGE_PageSize", num_options, + options); + + if ((choice = ppdFindMarkedChoice(ppd, "InputSlot")) != NULL) + doc->input_slot = choice->choice; + if ((choice = ppdFindMarkedChoice(ppd, "ManualFeed")) != NULL) + doc->manual_feed = choice->choice; + if ((choice = ppdFindMarkedChoice(ppd, "MediaColor")) != NULL) + doc->media_color = choice->choice; + if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL) + doc->media_type = choice->choice; + if ((choice = ppdFindMarkedChoice(ppd, "PageRegion")) != NULL) + doc->page_region = choice->choice; + if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL) + doc->page_size = choice->choice; + + /* + * brightness + */ + + if ((val = cupsGetOption("brightness", num_options, options)) != NULL) + { + /* + * Get brightness value from 10 to 1000. + */ + + intval = atoi(val); + + if (intval < 10 || intval > 1000) + { + _cupsLangPrintf(stderr, _("ERROR: Unsupported brightness value %s, using " + "brightness=100!\n"), val); + doc->brightness = 1.0f; + } + else + doc->brightness = intval * 0.01f; + } + else + doc->brightness = 1.0f; + + /* + * collate, multiple-document-handling + */ + + 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. + */ + + doc->collate = strcasecmp(val, "separate-documents-uncollated-copies") != 0; + } + + if ((val = cupsGetOption("Collate", num_options, options)) != NULL && + (!strcasecmp(val, "true") ||!strcasecmp(val, "on") || + !strcasecmp(val, "yes"))) + doc->collate = 1; + + /* + * emit-jcl + */ + + if ((val = cupsGetOption("emit-jcl", num_options, options)) != NULL && + (!strcasecmp(val, "false") || !strcasecmp(val, "off") || + !strcasecmp(val, "no") || !strcmp(val, "0"))) + doc->emit_jcl = 0; + else + doc->emit_jcl = 1; + + /* + * fitplot/fit-to-page/ipp-attribute-fidelity + * + * (Only for original PostScript content) + */ + + if ((content_type = getenv("CONTENT_TYPE")) == NULL) + content_type = "application/postscript"; + + if (!strcasecmp(content_type, "application/postscript")) + { + if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && + !strcasecmp(val, "true")) + doc->fitplot = 1; + else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && + !strcasecmp(val, "true")) + doc->fitplot = 1; + else if ((val = cupsGetOption("ipp-attribute-fidelity", num_options, + options)) != NULL && + !strcasecmp(val, "true")) + doc->fitplot = 1; + } + + /* + * gamma + */ + + if ((val = cupsGetOption("gamma", num_options, options)) != NULL) + { + /* + * Get gamma value from 1 to 10000... + */ + + intval = atoi(val); + + if (intval < 1 || intval > 10000) + { + _cupsLangPrintf(stderr, _("ERROR: Unsupported gamma value %s, using " + "gamma=1000!\n"), val); + doc->gamma = 1.0f; + } + else + doc->gamma = intval * 0.001f; + } + else + doc->gamma = 1.0f; + + /* + * mirror/MirrorPrint + */ + + if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) + { + val = choice->choice; + choice->marked = 0; + } + else + val = cupsGetOption("mirror", num_options, options); + + if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") || + !strcasecmp(val, "yes"))) + doc->mirror = 1; + + /* + * number-up + */ + + if ((val = cupsGetOption("number-up", num_options, options)) != NULL) + { + switch (intval = atoi(val)) + { + case 1 : + case 2 : + case 4 : + case 6 : + case 9 : + case 16 : + doc->number_up = intval; + break; + default : + _cupsLangPrintf(stderr, + _("ERROR: Unsupported number-up value %d, using " + "number-up=1!\n"), intval); + doc->number_up = 1; + break; + } + } + else + doc->number_up = 1; + + /* + * number-up-layout + */ + + if ((val = cupsGetOption("number-up-layout", num_options, options)) != NULL) + { + if (!strcasecmp(val, "lrtb")) + doc->number_up_layout = PSTOPS_LAYOUT_LRTB; + else if (!strcasecmp(val, "lrbt")) + doc->number_up_layout = PSTOPS_LAYOUT_LRBT; + else if (!strcasecmp(val, "rltb")) + doc->number_up_layout = PSTOPS_LAYOUT_RLTB; + else if (!strcasecmp(val, "rlbt")) + doc->number_up_layout = PSTOPS_LAYOUT_RLBT; + else if (!strcasecmp(val, "tblr")) + doc->number_up_layout = PSTOPS_LAYOUT_TBLR; + else if (!strcasecmp(val, "tbrl")) + doc->number_up_layout = PSTOPS_LAYOUT_TBRL; + else if (!strcasecmp(val, "btlr")) + doc->number_up_layout = PSTOPS_LAYOUT_BTLR; + else if (!strcasecmp(val, "btrl")) + doc->number_up_layout = PSTOPS_LAYOUT_BTRL; + else + { + _cupsLangPrintf(stderr, _("ERROR: Unsupported number-up-layout value %s, " + "using number-up-layout=lrtb!\n"), val); + doc->number_up_layout = PSTOPS_LAYOUT_LRTB; + } + } + else + doc->number_up_layout = PSTOPS_LAYOUT_LRTB; + + /* + * OutputOrder + */ + + if ((val = cupsGetOption("OutputOrder", num_options, options)) != NULL) + { + if (!strcasecmp(val, "Reverse")) + doc->output_order = 1; + } + else if (ppd) + { + /* + * Figure out the right default output order from the PPD file... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "OutputBin")) != NULL && + (attr = ppdFindAttr(ppd, "PageStackOrder", choice->choice)) != NULL && + attr->value) + doc->output_order = !strcasecmp(attr->value, "Reverse"); + else if ((attr = ppdFindAttr(ppd, "DefaultOutputOrder", NULL)) != NULL && + attr->value) + doc->output_order = !strcasecmp(attr->value, "Reverse"); + } + + /* + * page-border + */ + + if ((val = cupsGetOption("page-border", num_options, options)) != NULL) + { + if (!strcasecmp(val, "none")) + doc->page_border = PSTOPS_BORDERNONE; + else if (!strcasecmp(val, "single")) + doc->page_border = PSTOPS_BORDERSINGLE; + else if (!strcasecmp(val, "single-thick")) + doc->page_border = PSTOPS_BORDERSINGLE2; + else if (!strcasecmp(val, "double")) + doc->page_border = PSTOPS_BORDERDOUBLE; + else if (!strcasecmp(val, "double-thick")) + doc->page_border = PSTOPS_BORDERDOUBLE2; + else + { + _cupsLangPrintf(stderr, _("ERROR: Unsupported page-border value %s, " + "using page-border=none!\n"), val); + doc->page_border = PSTOPS_BORDERNONE; + } + } + else + doc->page_border = PSTOPS_BORDERNONE; + + /* + * page-label + */ + + doc->page_label = cupsGetOption("page-label", num_options, options); + + /* + * page-ranges + */ + + doc->page_ranges = cupsGetOption("page-ranges", num_options, options); + + /* + * page-set + */ + + doc->page_set = cupsGetOption("page-set", num_options, options); + + /* + * Now figure out if we have to force collated copies, etc. + */ + + if (ppd && ppd->manual_copies && Duplex && doc->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. + */ + + doc->collate = 1; + } + + /* + * See if we have to filter the fast or slow way... + */ + + if (doc->collate && doc->copies > 1) + { + /* + * See if we need to manually collate the pages... + */ + + doc->slow_collate = 1; + + if ((choice = ppdFindMarkedChoice(ppd, "Collate")) != NULL && + !strcasecmp(choice->choice, "True")) + { + /* + * Hardware collate option is selected, see if the option is + * conflicting - if not, collate in hardware. Otherwise, + * turn the hardware collate option off... + */ + + if ((option = ppdFindOption(ppd, "Collate")) != NULL && + !option->conflicted) + doc->slow_collate = 0; + else + ppdMarkOption(ppd, "Collate", "False"); + } + } + else + doc->slow_collate = 0; + + if (!ppdFindOption(ppd, "OutputOrder") && doc->output_order) + doc->slow_order = 1; + else + doc->slow_order = 0; + + if (Duplex && + (doc->slow_collate || doc->slow_order || + ((attr = ppdFindAttr(ppd, "cupsEvenDuplex", NULL)) != NULL && + attr->value && !strcasecmp(attr->value, "true")))) + doc->slow_duplex = 1; + else + doc->slow_duplex = 0; + + /* + * Create a temporary file for page data if we need to filter slowly... + */ + + if (doc->slow_order || doc->slow_collate) + { + if ((doc->temp = cupsTempFile2(doc->tempfile, + sizeof(doc->tempfile))) == NULL) + { + _cupsLangPrintError(_("ERROR: Unable to create temporary file")); + exit(1); + } + } + + /* + * Figure out if we should use ESPshowpage or not... + */ + + if (doc->page_label || getenv("CLASSIFICATION") || doc->number_up > 1 || + doc->page_border) + { + /* + * Yes, use ESPshowpage... + */ + + doc->use_ESPshowpage = 1; + } + + fprintf(stderr, "DEBUG: slow_collate=%d, slow_duplex=%d, slow_order=%d\n", + doc->slow_collate, doc->slow_duplex, doc->slow_order); +} + + +/* + * 'skip_page()' - Skip past a page that won't be printed. + */ + +static ssize_t /* O - Length of next line */ +skip_page(cups_file_t *fp, /* I - File to read from */ + char *line, /* I - Line buffer */ + ssize_t linelen, /* I - Length of initial line */ + size_t linesize) /* I - Size of line buffer */ +{ + int level; /* Embedded document level */ + + + level = 0; + + while ((linelen = cupsFileGetLine(fp, line, linesize)) > 0) + { + if (level == 0 && + (!strncmp(line, "%%Page:", 7) || !strncmp(line, "%%Trailer", 9))) + break; + else if (!strncmp(line, "%%BeginDocument", 15) || + !strncmp(line, "%ADO_BeginApplication", 21)) + level ++; + else if ((!strncmp(line, "%%EndDocument", 13) || + !strncmp(line, "%ADO_EndApplication", 19)) && level > 0) + level --; + else if (!strncmp(line, "%%BeginBinary:", 14) || + (!strncmp(line, "%%BeginData:", 12) && + !strstr(line, "ASCII") && !strstr(line, "Hex"))) + { + /* + * Skip binary data... + */ + + int bytes; /* Bytes of data */ + + + bytes = atoi(strchr(line, ':') + 1); + + while (bytes > 0) + { + if (bytes > linesize) + linelen = cupsFileRead(fp, line, linesize); + else + linelen = cupsFileRead(fp, line, bytes); + + if (linelen < 1) + { + line[0] = '\0'; + perror("ERROR: Early end-of-file while reading binary data"); + return (0); + } + + bytes -= linelen; + } + } + } + + return (linelen); +} + + +/* + * 'start_nup()' - Start processing for N-up printing. + */ + +static void +start_nup(pstops_doc_t *doc, /* I - Document information */ + int number, /* I - Page number */ + int show_border, /* I - Show the border? */ + const int *bounding_box) /* I - BoundingBox value */ +{ + 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 pagew, /* Printable width of page */ + pagel; /* Printable height of page */ + int bboxx, /* BoundingBox X origin */ + bboxy, /* BoundingBox Y origin */ + bboxw, /* BoundingBox width */ + bboxl; /* BoundingBox height */ + float margin = 0; /* Current margin for border */ + + + if (doc->number_up > 1) + doc_puts(doc, "userdict/ESPsave save put\n"); + + pos = (number - 1) % doc->number_up; + pagew = PageRight - PageLeft; + pagel = PageTop - PageBottom; + + if (doc->fitplot) + { + bboxx = bounding_box[0]; + bboxy = bounding_box[1]; + bboxw = bounding_box[2] - bounding_box[0]; + bboxl = bounding_box[3] - bounding_box[1]; + } + else + { + bboxx = 0; + bboxy = 0; + bboxw = PageWidth; + bboxl = PageLength; + } + + fprintf(stderr, "DEBUG: pagew = %.1f, pagel = %.1f\n", pagew, pagel); + fprintf(stderr, "DEBUG: bboxx = %d, bboxy = %d, bboxw = %d, bboxl = %d\n", + bboxx, bboxy, bboxw, bboxl); + 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 */ + doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", PageLength); + break; + case 2 : /* Reverse Portrait */ + doc_printf(doc, "%.1f %.1f translate 180 rotate\n", PageWidth, + PageLength); + break; + case 3 : /* Reverse Landscape */ + doc_printf(doc, "0.0 %.1f translate -90 rotate\n", PageWidth); + break; + } + + if (Duplex && doc->number_up > 1 && ((number / doc->number_up) & 1)) + doc_printf(doc, "%.1f %.1f translate\n", PageWidth - PageRight, PageBottom); + else if (doc->number_up > 1 || doc->fitplot) + doc_printf(doc, "%.1f %.1f translate\n", PageLeft, PageBottom); + + switch (doc->number_up) + { + default : + if (doc->fitplot) + { + w = pagew; + l = w * bboxl / bboxw; + + if (l > pagel) + { + l = pagel; + w = l * bboxw / bboxl; + } + + tx = 0.5 * (pagew - w); + ty = 0.5 * (pagel - l); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", tx, ty, + w / bboxw, l / bboxl); + } + else + w = PageWidth; + break; + + case 2 : + if (Orientation & 1) + { + x = pos & 1; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + x = 1 - x; + + w = pagel; + l = w * bboxl / bboxw; + + if (l > (pagew * 0.5)) + { + l = pagew * 0.5; + w = l * bboxw / bboxl; + } + + tx = 0.5 * (pagew * 0.5 - l); + ty = 0.5 * (pagel - w); + + if (doc->normal_landscape) + doc_printf(doc, "0.0 %.1f translate -90 rotate\n", pagel); + else + doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", pagew); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + ty, tx + pagew * 0.5 * x, w / bboxw, l / bboxl); + } + else + { + x = pos & 1; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 1 - x; + + l = pagew; + w = l * bboxw / bboxl; + + if (w > (pagel * 0.5)) + { + w = pagel * 0.5; + l = w * bboxl / bboxw; + } + + tx = 0.5 * (pagel * 0.5 - w); + ty = 0.5 * (pagew - l); + + if (doc->normal_landscape) + doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", pagew); + else + doc_printf(doc, "0.0 %.1f translate -90 rotate\n", pagel); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + tx + pagel * 0.5 * x, ty, w / bboxw, l / bboxl); + } + break; + + case 4 : + if (doc->number_up_layout & PSTOPS_LAYOUT_VERTICAL) + { + x = (pos / 2) & 1; + y = pos & 1; + } + else + { + x = pos & 1; + y = (pos / 2) & 1; + } + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 1 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 1 - y; + + w = pagew * 0.5; + l = w * bboxl / bboxw; + + if (l > (pagel * 0.5)) + { + l = pagel * 0.5; + w = l * bboxw / bboxl; + } + + tx = 0.5 * (pagew * 0.5 - w); + ty = 0.5 * (pagel * 0.5 - l); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + tx + x * pagew * 0.5, ty + y * pagel * 0.5, + w / bboxw, l / bboxl); + break; + + case 6 : + if (Orientation & 1) + { + if (doc->number_up_layout & PSTOPS_LAYOUT_VERTICAL) + { + x = pos / 3; + y = pos % 3; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 1 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 2 - y; + } + else + { + x = pos & 1; + y = pos / 2; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 1 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 2 - y; + } + + w = pagel * 0.5; + l = w * bboxl / bboxw; + + if (l > (pagew * 0.333)) + { + l = pagew * 0.333; + w = l * bboxw / bboxl; + } + + tx = 0.5 * (pagel - 2 * w); + ty = 0.5 * (pagew - 3 * l); + + if (doc->normal_landscape) + doc_printf(doc, "0 %.1f translate -90 rotate\n", pagel); + else + doc_printf(doc, "%.1f 0 translate 90 rotate\n", pagew); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + tx + x * w, ty + y * l, l / bboxl, w / bboxw); + } + else + { + if (doc->number_up_layout & PSTOPS_LAYOUT_VERTICAL) + { + x = pos / 2; + y = pos & 1; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 2 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 1 - y; + } + else + { + x = pos % 3; + y = pos / 3; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 2 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 1 - y; + } + + l = pagew * 0.5; + w = l * bboxw / bboxl; + + if (w > (pagel * 0.333)) + { + w = pagel * 0.333; + l = w * bboxl / bboxw; + } + + tx = 0.5 * (pagel - 3 * w); + ty = 0.5 * (pagew - 2 * l); + + if (doc->normal_landscape) + doc_printf(doc, "%.1f 0 translate 90 rotate\n", pagew); + else + doc_printf(doc, "0 %.1f translate -90 rotate\n", pagel); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + tx + w * x, ty + l * y, w / bboxw, l / bboxl); + + } + break; + + case 9 : + if (doc->number_up_layout & PSTOPS_LAYOUT_VERTICAL) + { + x = (pos / 3) % 3; + y = pos % 3; + } + else + { + x = pos % 3; + y = (pos / 3) % 3; + } + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 2 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 2 - y; + + w = pagew * 0.333; + l = w * bboxl / bboxw; + + if (l > (pagel * 0.333)) + { + l = pagel * 0.333; + w = l * bboxw / bboxl; + } + + tx = 0.5 * (pagew * 0.333 - w); + ty = 0.5 * (pagel * 0.333 - l); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + tx + x * pagew * 0.333, ty + y * pagel * 0.333, + w / bboxw, l / bboxl); + break; + + case 16 : + if (doc->number_up_layout & PSTOPS_LAYOUT_VERTICAL) + { + x = (pos / 4) & 3; + y = pos & 3; + } + else + { + x = pos & 3; + y = (pos / 4) & 3; + } + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEX) + x = 3 - x; + + if (doc->number_up_layout & PSTOPS_LAYOUT_NEGATEY) + y = 3 - y; + + w = pagew * 0.25; + l = w * bboxl / bboxw; + + if (l > (pagel * 0.25)) + { + l = pagel * 0.25; + w = l * bboxw / bboxl; + } + + tx = 0.5 * (pagew * 0.25 - w); + ty = 0.5 * (pagel * 0.25 - l); + + doc_printf(doc, "%.1f %.1f translate %.3f %.3f scale\n", + tx + x * pagew * 0.25, ty + y * pagel * 0.25, + w / bboxw, l / bboxl); + break; + } + + /* + * Draw borders as necessary... + */ + + if (doc->page_border && show_border) + { + int rects; /* Number of border rectangles */ + float fscale; /* Scaling value for points */ + + + rects = (doc->page_border & PSTOPS_BORDERDOUBLE) ? 2 : 1; + fscale = PageWidth / w; + margin = 2.25 * fscale; + + /* + * Set the line width and color... + */ + + doc_puts(doc, "gsave\n"); + doc_printf(doc, "%.3f setlinewidth 0 setgray newpath\n", + (doc->page_border & PSTOPS_BORDERTHICK) ? 0.5 * fscale : + 0.24 * fscale); + + /* + * Draw border boxes... + */ + + for (; rects > 0; rects --, margin += 2 * fscale) + if (doc->number_up > 1) + doc_printf(doc, "%.1f %.1f %.1f %.1f ESPrs\n", + margin, + margin, + bboxw - 2 * margin, + bboxl - 2 * margin); + else + doc_printf(doc, "%.1f %.1f %.1f %.1f ESPrs\n", + PageLeft + margin, + PageBottom + margin, + PageRight - PageLeft - 2 * margin, + PageTop - PageBottom - 2 * margin); + + /* + * Restore pen settings... + */ + + doc_puts(doc, "grestore\n"); + } + + if (doc->fitplot) + { + /* + * Offset the page by its bounding box... + */ + + doc_printf(doc, "%d %d translate\n", -bounding_box[0], + -bounding_box[1]); + } + + if (doc->fitplot || doc->number_up > 1) + { + /* + * Clip the page to the page's bounding box... + */ + + doc_printf(doc, "%.1f %.1f %.1f %.1f ESPrc\n", + bboxx + margin, bboxy + margin, + bboxw - 2 * margin, bboxl - 2 * margin); + } + + /* + * Mirror the page as needed... + */ + + if (doc->mirror) + doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth); +} + + +/* + * 'write_label_prolog()' - Write the prolog with the classification + * and page label. + */ + +static void +write_label_prolog(pstops_doc_t *doc, /* I - Document info */ + 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 */ + const char *ptr; /* Temporary string pointer */ + + + /* + * 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])) + { + doc_puts(doc, "userdict/ESPwl{}bind put\n"); + return; + } + + /* + * Set the classification + page label string... + */ + + doc_puts(doc, "userdict"); + if (!strcmp(classification, "confidential")) + doc_puts(doc, "/ESPpl(CONFIDENTIAL"); + else if (!strcmp(classification, "classified")) + doc_puts(doc, "/ESPpl(CLASSIFIED"); + else if (!strcmp(classification, "secret")) + doc_puts(doc, "/ESPpl(SECRET"); + else if (!strcmp(classification, "topsecret")) + doc_puts(doc, "/ESPpl(TOP SECRET"); + else if (!strcmp(classification, "unclassified")) + doc_puts(doc, "/ESPpl(UNCLASSIFIED"); + else + { + doc_puts(doc, "/ESPpl("); + + for (ptr = classification; *ptr; ptr ++) + { + if (*ptr < 32 || *ptr > 126) + doc_printf(doc, "\\%03o", *ptr); + else if (*ptr == '_') + doc_puts(doc, " "); + else if (*ptr == '(' || *ptr == ')' || *ptr == '\\') + doc_printf(doc, "\\%c", *ptr); + else + doc_printf(doc, "%c", *ptr); + } + } + + if (label) + { + if (classification[0]) + doc_puts(doc, " - "); + + /* + * Quote the label string as needed... + */ + + for (ptr = label; *ptr; ptr ++) + { + if (*ptr < 32 || *ptr > 126) + doc_printf(doc, "\\%03o", *ptr); + else if (*ptr == '(' || *ptr == ')' || *ptr == '\\') + doc_printf(doc, "\\%c", *ptr); + else + doc_printf(doc, "%c", *ptr); + } + } + + doc_puts(doc, ")put\n"); + + /* + * Then get a 14 point Helvetica-Bold font... + */ + + doc_puts(doc, "userdict/ESPpf /Helvetica-Bold findfont 14 scalefont put\n"); + + /* + * Finally, the procedure to write the labels on the page... + */ + + doc_puts(doc, "userdict/ESPwl{\n"); + doc_puts(doc, " ESPpf setfont\n"); + doc_printf(doc, " ESPpl stringwidth pop dup 12 add exch -0.5 mul %.0f add\n", + width * 0.5f); + doc_puts(doc, " 1 setgray\n"); + doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrf\n", bottom - 2.0); + doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrf\n", top - 18.0); + doc_puts(doc, " 0 setgray\n"); + doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrs\n", bottom - 2.0); + doc_printf(doc, " dup 6 sub %.0f 3 index 20 ESPrs\n", top - 18.0); + doc_printf(doc, " dup %.0f moveto ESPpl show\n", bottom + 2.0); + doc_printf(doc, " %.0f moveto ESPpl show\n", top - 14.0); + doc_puts(doc, "pop\n"); + doc_puts(doc, "}bind put\n"); +} + + +/* + * 'write_labels()' - Write the actual page labels. + * + * This function is a copy of the one in common.c since we need to + * use doc_puts/doc_printf instead of puts/printf... + */ + +static void +write_labels(pstops_doc_t *doc, /* I - Document information */ + int orient) /* I - Orientation of the page */ +{ + float width, /* Width of page */ + length; /* Length of page */ + + + doc_puts(doc, "gsave\n"); + + if ((orient ^ Orientation) & 1) + { + width = PageLength; + length = PageWidth; + } + else + { + width = PageWidth; + length = PageLength; + } + + switch (orient & 3) + { + case 1 : /* Landscape */ + doc_printf(doc, "%.1f 0.0 translate 90 rotate\n", length); + break; + case 2 : /* Reverse Portrait */ + doc_printf(doc, "%.1f %.1f translate 180 rotate\n", width, length); + break; + case 3 : /* Reverse Landscape */ + doc_printf(doc, "0.0 %.1f translate -90 rotate\n", width); + break; + } + + doc_puts(doc, "ESPwl\n"); + doc_puts(doc, "grestore\n"); +} + + +/* + * 'write_options()' - Write options provided via %%IncludeFeature. + */ + +static void +write_options( + pstops_doc_t *doc, /* I - Document */ + ppd_file_t *ppd, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int i; /* Looping var */ + ppd_option_t *option; /* PPD option */ + int min_order; /* Minimum OrderDependency value */ + char *doc_setup, /* DocumentSetup commands to send */ + *any_setup; /* AnySetup commands to send */ + + + /* + * Figure out the minimum OrderDependency value... + */ + + if ((option = ppdFindOption(ppd, "PageRegion")) != NULL) + min_order = option->order; + else + min_order = 999.0f; + + for (i = 0; i < num_options; i ++) + if ((option = ppdFindOption(ppd, options[i].name)) != NULL && + option->order < min_order) + min_order = option->order; + + /* + * Mark and extract them... + */ + + cupsMarkOptions(ppd, num_options, options); + + doc_setup = ppdEmitString(ppd, PPD_ORDER_DOCUMENT, min_order); + any_setup = ppdEmitString(ppd, PPD_ORDER_ANY, min_order); + + /* + * Then send them out... + */ + + if (doc->number_up > 1) + { + /* + * Temporarily restore setpagedevice so we can set the options... + */ + + doc_puts(doc, "userdict/setpagedevice/CUPSsetpagedevice load put\n"); + } + + if (doc_setup) + { + doc_puts(doc, doc_setup); + free(doc_setup); + } + + if (any_setup) + { + doc_puts(doc, any_setup); + free(any_setup); + } + + if (doc->number_up > 1) + { + /* + * Disable setpagedevice again... + */ + + doc_puts(doc, "userdict/setpagedevice{pop}bind put\n"); + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/raster-driver.header b/filter/raster-driver.header new file mode 100644 index 0000000000..5ba1fb6149 --- /dev/null +++ b/filter/raster-driver.header @@ -0,0 +1,17 @@ +

Developing Raster Printer Drivers

+ +

This document describes how to develop printer drivers for raster printers. Topics include: printer driver basics, creating new PPD files, using filters, implementing color management, and adding Mac OS X features.

+ +
+ + + + + + +
See AlsoProgramming: Developing PostScript Printer Drivers
+ Programming: Filter and Backend Programming
+ Programming: Introduction to the PPD Compiler
+ Programming: Raster API
+ References: PPD Compiler Driver Information File Reference
+ Specifications: CUPS PPD Extensions
diff --git a/filter/raster-driver.shtml b/filter/raster-driver.shtml new file mode 100644 index 0000000000..1c0c32a9d0 --- /dev/null +++ b/filter/raster-driver.shtml @@ -0,0 +1,194 @@ +

Printer Driver Basics

+ +

A CUPS raster printer driver consists of a PostScript Printer Description (PPD) file that describes the features and capabilities of the device, one or more filter programs that prepare print data for the device, and zero or more support files for color management, online help, and so forth. The PPD file includes references to all of the filters and support files used by the driver.

+ +

Every time a user prints something the scheduler program, cupsd(8), determines the format of the print job and the programs required to convert that job into something the printer understands. CUPS includes filter programs for many common formats, for example to convert Portable Document Format (PDF) files into CUPS raster data. Figure 1 shows the data flow of a typical print job.

+ +
+ + +
Figure 1: Raster Filter Chain
Raster Filter Chain
+ +

The raster filter converts CUPS raster data into a format the printer understands, for example HP-PCL. CUPS includes several sample raster filters supporting standard page description languages (PDLs). Table 1 shows the raster filters that are bundled with CUPS and the languages they support.

+ +
+ + + + + + + + + + + +
Table 1: Standard CUPS Raster Filters
FilterPDLsppdc DriverTypeppdc #include file
rastertoepsonESC/P, ESC/P2epsonepson.h
rastertoescpxESC/P, ESC/P2, EPSON Remote Modeescpescp.h
rastertohpHP-PCL3, HP-PCL5hphp.h
rastertolabelCPCL, Dymo, EPL1, EPL2, Intellitech PCL, ZPLlabellabel.h
rastertopclxHP-RTL, HP-PCL3, HP-PCL3GUI, HP-PCL5, HP-PCL5c, HP-PCL5epclpcl.h
+ +

The optional port monitor handles interface-specific protocol or encoding issues. For example, some raster printers use the 1284.4 communications protocol.

+ +

The backend handles communications with the printer, sending print data from the last filter to the printer and relaying back-channel data from the printer to the upstream filters. CUPS includes backend programs for common direct-connect interfaces and network protocols, and you can provide your own backend to support custom interfaces and protocols.

+ +

The scheduler also supports a special "command" file format for sending maintenance commands and status queries to a printer or printer driver. Command print jobs typically use a single command filter program defined in the PPD file to generate the appropriate printer commands and handle any responses from the printer. Figure 2 shows the data flow of a typical command job.

+ +
+ + +
Figure 2: Command Filter Chain
Command Filter Chain
+ +

Raster printer drivers must provide their own command filter.

+ + +

Creating New PPD Files

+ +

We recommend using the CUPS PPD compiler, ppdc(1), to create new PPD files since it manages many of the tedious (and error-prone!) details of paper sizes and localization for you. It also allows you to easily support multiple devices from a single source file. For more information see the "Introduction to the PPD Compiler" document. Listing 1 shows a driver information file for several similar black-and-white HP-PCL5 laser printers.

+ +

Listing 1: "examples/laserjet-basic.drv"

+ +
+// Include standard font and media definitions
+#include <font.defs>
+#include <media.defs>
+
+// Include HP-PCL driver definitions
+#include <pcl.h>
+
+// Specify that this driver uses the HP-PCL driver...
+DriverType pcl
+
+// Specify the driver options via the model number...
+ModelNumber ($PCL_PAPER_SIZE $PCL_PJL $PCL_PJL_RESOLUTION)
+
+// List the fonts that are supported, in this case all standard fonts...
+Font *
+
+// Manufacturer and driver version
+Manufacturer "HP"
+Version 1.0
+
+// Supported page sizes and their margins
+HWMargins 18 12 18 12
+*MediaSize Letter
+MediaSize Legal
+MediaSize Executive
+MediaSize Monarch
+MediaSize Statement
+MediaSize FanFoldGermanLegal
+
+HWMargins 18 12.72 18 12.72
+MediaSize Env10
+
+HWMargins 9.72 12 9.72 12
+MediaSize A4
+MediaSize A5
+MediaSize B5
+MediaSize EnvC5
+MediaSize EnvDL
+MediaSize EnvISOB5
+MediaSize Postcard
+MediaSize DoublePostcard
+
+// Only black-and-white output with mode 3 compression...
+ColorModel Gray k chunky 3
+
+// Supported resolutions
+Resolution - 1 0 0 0 "300dpi/300 DPI"
+*Resolution - 8 0 0 0 "600dpi/600 DPI"
+
+// Supported input slots
+*InputSlot 7 "Auto/Automatic Selection"
+InputSlot 2 "Manual/Tray 1 - Manual Feed"
+InputSlot 4 "Upper/Tray 1"
+InputSlot 1 "Lower/Tray 2"
+InputSlot 5 "LargeCapacity/Tray 3"
+
+// Tray 3 is an option...
+Installable "OptionLargeCapacity/Tray 3 Installed"
+UIConstraints "*OptionLargeCapacity False *InputSlot LargeCapacity"
+
+{
+  // HP LaserJet 2100 Series
+  Throughput 10
+  ModelName "LaserJet 2100 Series"
+  PCFileName "hpljt211.ppd"
+}
+
+{
+  // LaserJet 2200 and 2300 series have duplexer option...
+  Duplex normal
+  Installable "OptionDuplex/Duplexer Installed"
+  UIConstraints "*OptionDuplex False *Duplex"
+
+  {
+    // HP LaserJet 2200 Series
+    Throughput 19
+    ModelName "LaserJet 2200 Series"
+    PCFileName "hpljt221.ppd"
+  }
+
+  {
+    // HP LaserJet 2300 Series
+    Throughput 25
+    ModelName "LaserJet 2300 Series"
+    PCFileName "hpljt231.ppd"
+  }
+}
+
+ + +

Using Filters

+ +

The standard CUPS raster filters can be specified using the +DriverType directive, for example:

+ +
+// Specify that this driver uses the HP-PCL driver...
+DriverType pcl
+
+ +

Table 1 shows the driver types for each of the standard CUPS raster filters. For drivers that do not use the standard raster filters, the "custom" type is used with Filter directives:

+ +
+DriverType custom
+Filter application/vnd.cups-raster 100 /path/to/raster/filter
+Filter application/vnd.cups-command 100 /path/to/command/filter
+
+ + +

Implementing Color Management

+ +

CUPS uses ICC color profiles to provide more accurate color reproduction. The cupsICCProfile attribute defines the color profiles that are available for a given printer, for example:

+ +
+Attribute cupsICCProfile "ColorModel.MediaType.Resolution/Description" /path/to/ICC/profile
+
+ +

where "ColorModel.MediaType.Resolution" defines a selector based on the corresponding option selections. A simple driver might only define profiles for the color models that are supported, for example a printer supporting Gray and RGB might use:

+ +
+Attribute cupsICCProfile "Gray../Grayscale Profile" /path/to/ICC/gray-profile
+Attribute cupsICCProfile "RGB../Full Color Profile" /path/to/ICC/rgb-profile
+
+ +

The options used for profile selection can be customized using the cupsICCQualifier2 and cupsICCQualifier3 attributes.

+ +

Since Mac OS X 10.5Custom Color Matching Support

+ +

Mac OS X printer drivers that are based on an existing standard RGB colorspace can tell the system to use the corresponding colorspace instead of an arbitrary ICC color profile when doing color management. The APSupportsCustomColorMatching and APDefaultCustomColorMatchingProfile attributes can be used to enable this mode:

+ +
+Attribute APSupportsCustomColorMatching "" true
+Attribute APDefaultCustomColorMatchingProfile "" sRGB
+
+ + +

Adding Mac OS X Features

+ +

Mac OS X printer drivers can provide additional attributes to specify additional option panes in the print dialog, an image of the printer, a help book, and option presets for the driver software:

+ +
+Attribute APDialogExtension "" /Library/Printers/Vendor/filename.plugin
+Attribute APHelpBook "" /Library/Printers/Vendor/filename.bundle
+Attribute APPrinterIconPath "" /Library/Printers/Vendor/filename.icns
+Attribute APPrinterPreset "name/text" "*option choice ..."
+
diff --git a/filter/raster.c b/filter/raster.c new file mode 100644 index 0000000000..4aad1ed7cc --- /dev/null +++ b/filter/raster.c @@ -0,0 +1,1295 @@ +/* + * "$Id$" + * + * Raster file routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * This file is part of the CUPS Imaging library. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * cupsRasterClose() - Close a raster stream. + * cupsRasterOpen() - Open a raster stream using a file descriptor. + * cupsRasterReadHeader() - Read a raster page header and store it in a + * version 1 page header structure. + * cupsRasterReadHeader2() - Read a raster page header and store it in a + * version 2 page header structure. + * cupsRasterReadPixels() - Read raster pixels. + * cupsRasterWriteHeader() - Write a raster page header from a version 1 + * page header structure. + * cupsRasterWriteHeader2() - Write a raster page header from a version 2 + * page header structure. + * cupsRasterWritePixels() - Write raster pixels. + * cups_raster_read_header() - Read a raster page header. + * cups_raster_read() - Read through the raster buffer. + * cups_raster_update() - Update the raster header and row count for the + * current page. + * cups_raster_write() - Write a row of compressed raster data... + * cups_read_fd() - Read bytes from a file. + * cups_swap() - Swap bytes in raster data... + * cups_write_fd() - Write bytes to a file. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" +#if defined(WIN32) || defined(__EMX__) +# include +# include /* for htonl() definition */ +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * Private structures... + */ + +typedef ssize_t (*_cups_raster_iocb_t)(void *ctx, unsigned char *buffer, size_t length); + +struct _cups_raster_s /**** Raster stream data ****/ +{ + unsigned sync; /* Sync word from start of stream */ + void *ctx; /* File descriptor */ + _cups_raster_iocb_t iocb; /* IO callback */ + cups_mode_t mode; /* Read/write mode */ + cups_page_header2_t header; /* Raster header for current page */ + int count, /* Current row run-length count */ + remaining, /* Remaining rows in page image */ + bpp; /* Bytes per pixel/color */ + unsigned char *pixels, /* Pixels for current row */ + *pend, /* End of pixel buffer */ + *pcurrent; /* Current byte in pixel buffer */ + int compressed, /* Non-zero if data is compressed */ + swapped; /* Non-zero if data is byte-swapped */ + unsigned char *buffer, /* Read/write buffer */ + *bufptr, /* Current (read) position in buffer */ + *bufend; /* End of current (read) buffer */ + size_t bufsize; /* Buffer size */ +}; + + +/* + * Local functions... + */ + +static int cups_raster_io(cups_raster_t *r, unsigned char *buf, int bytes); +static unsigned cups_raster_read_header(cups_raster_t *r); +static int cups_raster_read(cups_raster_t *r, unsigned char *buf, + int bytes); +static void cups_raster_update(cups_raster_t *r); +static int cups_raster_write(cups_raster_t *r, + const unsigned char *pixels); +static ssize_t cups_read_fd(void *ctx, unsigned char *buf, size_t bytes); +static void cups_swap(unsigned char *buf, int bytes); +static ssize_t cups_write_fd(void *ctx, unsigned char *buf, size_t bytes); + + +/* + * 'cupsRasterClose()' - Close a raster stream. + * + * The file descriptor associated with the raster stream must be closed + * separately as needed. + */ + +void +cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ +{ + if (r != NULL) + { + if (r->buffer) + free(r->buffer); + + if (r->pixels) + free(r->pixels); + + free(r); + } +} + + +/* + * 'cupsRasterOpen()' - Open a raster stream using a file descriptor. + * + * This function associates a raster stream with the given file descriptor. + * For most printer driver filters, "fd" will be 0 (stdin). For most raster + * image processor (RIP) filters that generate raster data, "fd" will be 1 + * (stdout). + * + * When writing raster data, the @code CUPS_RASTER_WRITE@ or + * @code CUPS_RASTER_WRITE_COMPRESS@ mode can be used - compressed output is + * generally 25-50% smaller but adds a 100-300% execution time overhead. + */ + +cups_raster_t * /* O - New stream */ +cupsRasterOpen(int fd, /* I - File descriptor */ + cups_mode_t mode) /* I - Mode - @code CUPS_RASTER_READ@, + @code CUPS_RASTER_WRITE@, or + @code CUPS_RASTER_WRITE_COMPRESSED@ */ +{ + cups_raster_t *r; /* New stream */ + + + _cupsRasterClearError(); + + if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL) + { + _cupsRasterAddError("Unable to allocate memory for raster stream: %s\n", + strerror(errno)); + return (NULL); + } + + r->ctx = (void *)((intptr_t)fd); + r->iocb = mode == CUPS_RASTER_READ ? cups_read_fd : cups_write_fd; + r->mode = mode; + + if (mode == CUPS_RASTER_READ) + { + /* + * Open for read - get sync word... + */ + + if (cups_raster_io(r, (unsigned char *)&(r->sync), sizeof(r->sync)) != + sizeof(r->sync)) + { + _cupsRasterAddError("Unable to read header from raster stream: %s\n", + strerror(errno)); + free(r); + return (NULL); + } + + if (r->sync != CUPS_RASTER_SYNC && + r->sync != CUPS_RASTER_REVSYNC && + r->sync != CUPS_RASTER_SYNCv1 && + r->sync != CUPS_RASTER_REVSYNCv1 && + r->sync != CUPS_RASTER_SYNCv2 && + r->sync != CUPS_RASTER_REVSYNCv2) + { + _cupsRasterAddError("Unknown raster format %08x!\n", r->sync); + free(r); + return (NULL); + } + + if (r->sync == CUPS_RASTER_SYNCv2 || + r->sync == CUPS_RASTER_REVSYNCv2) + r->compressed = 1; + + if (r->sync == CUPS_RASTER_REVSYNC || + r->sync == CUPS_RASTER_REVSYNCv1 || + r->sync == CUPS_RASTER_REVSYNCv2) + r->swapped = 1; + + DEBUG_printf(("r->swapped=%d, r->sync=%08x\n", r->swapped, r->sync)); + } + else + { + /* + * Open for write - put sync word... + */ + + switch (mode) + { + default : + case CUPS_RASTER_WRITE : + r->sync = CUPS_RASTER_SYNC; + break; + + case CUPS_RASTER_WRITE_COMPRESSED : + r->compressed = 1; + r->sync = CUPS_RASTER_SYNCv2; + break; + } + + if (cups_raster_io(r, (unsigned char *)&(r->sync), sizeof(r->sync)) + < sizeof(r->sync)) + { + _cupsRasterAddError("Unable to write raster stream header: %s\n", + strerror(errno)); + free(r); + return (NULL); + } + } + + return (r); +} + + +/* + * 'cupsRasterReadHeader()' - Read a raster page header and store it in a + * version 1 page header structure. + * + * This function is deprecated. Use @link cupsRasterReadHeader2@ instead. + * + * Version 1 page headers were used in CUPS 1.0 and 1.1 and contain a subset + * of the version 2 page header data. This function handles reading version 2 + * page headers and copying only the version 1 data into the provided buffer. + * + * @deprecated@ + */ + +unsigned /* O - 1 on success, 0 on failure/end-of-file */ +cupsRasterReadHeader( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header_t *h) /* I - Pointer to header data */ +{ + /* + * Get the raster header... + */ + + if (!cups_raster_read_header(r)) + return (0); + + /* + * Copy the header to the user-supplied buffer... + */ + + memcpy(h, &(r->header), sizeof(cups_page_header_t)); + + return (1); +} + + +/* + * 'cupsRasterReadHeader2()' - Read a raster page header and store it in a + * version 2 page header structure. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +unsigned /* O - 1 on success, 0 on failure/end-of-file */ +cupsRasterReadHeader2( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header2_t *h) /* I - Pointer to header data */ +{ + /* + * Get the raster header... + */ + + if (!cups_raster_read_header(r)) + return (0); + + /* + * Copy the header to the user-supplied buffer... + */ + + memcpy(h, &(r->header), sizeof(cups_page_header2_t)); + + return (1); +} + + +/* + * 'cupsRasterReadPixels()' - Read raster pixels. + * + * For best performance, filters should read one or more whole lines. + * The "cupsBytesPerLine" value from the page header can be used to allocate + * the line buffer and as the number of bytes to read. + */ + +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 cupsBytesPerLine; /* cupsBytesPerLine value */ + unsigned remaining; /* Bytes remaining */ + unsigned char *ptr, /* Pointer to read buffer */ + byte, /* Byte from file */ + *temp; /* Pointer into buffer */ + int count; /* Repetition count */ + + + if (r == NULL || r->mode != CUPS_RASTER_READ || r->remaining == 0) + return (0); + + if (!r->compressed) + { + /* + * Read without compression... + */ + + r->remaining -= len / r->header.cupsBytesPerLine; + + if (cups_raster_io(r, p, len) < (ssize_t)len) + return (0); + + /* + * Swap bytes as needed... + */ + + if (r->swapped && + (r->header.cupsBitsPerColor == 16 || + r->header.cupsBitsPerPixel == 12 || + r->header.cupsBitsPerPixel == 16)) + cups_swap(p, len); + + /* + * Return... + */ + + return (len); + } + + /* + * Read compressed data... + */ + + remaining = len; + cupsBytesPerLine = r->header.cupsBytesPerLine; + + while (remaining > 0 && r->remaining > 0) + { + if (r->count == 0) + { + /* + * Need to read a new row... + */ + + if (remaining == cupsBytesPerLine) + ptr = p; + else + ptr = r->pixels; + + /* + * Read using a modified PackBits compression... + */ + + if (!cups_raster_read(r, &byte, 1)) + return (0); + + r->count = byte + 1; + + if (r->count > 1) + ptr = r->pixels; + + temp = ptr; + bytes = cupsBytesPerLine; + + while (bytes > 0) + { + /* + * Get a new repeat count... + */ + + if (!cups_raster_read(r, &byte, 1)) + return (0); + + if (byte & 128) + { + /* + * Copy N literal pixels... + */ + + count = (257 - byte) * r->bpp; + + if (count > bytes) + count = bytes; + + if (!cups_raster_read(r, temp, count)) + return (0); + + temp += count; + bytes -= count; + } + else + { + /* + * Repeat the next N bytes... + */ + + count = (byte + 1) * r->bpp; + if (count > bytes) + count = bytes; + + if (count < r->bpp) + break; + + bytes -= count; + + if (!cups_raster_read(r, temp, r->bpp)) + return (0); + + temp += r->bpp; + count -= r->bpp; + + while (count > 0) + { + memcpy(temp, temp - r->bpp, r->bpp); + temp += r->bpp; + count -= r->bpp; + } + } + } + + /* + * Swap bytes as needed... + */ + + if ((r->header.cupsBitsPerColor == 16 || + r->header.cupsBitsPerPixel == 12 || + r->header.cupsBitsPerPixel == 16) && + r->swapped) + cups_swap(ptr, bytes); + + /* + * Update pointers... + */ + + if (remaining >= cupsBytesPerLine) + { + bytes = cupsBytesPerLine; + r->pcurrent = r->pixels; + r->count --; + r->remaining --; + } + else + { + bytes = remaining; + r->pcurrent = r->pixels + bytes; + } + + /* + * Copy data as needed... + */ + + if (ptr != p) + memcpy(p, ptr, bytes); + } + else + { + /* + * Copy fragment from buffer... + */ + + if ((unsigned)(bytes = r->pend - r->pcurrent) > remaining) + bytes = remaining; + + memcpy(p, r->pcurrent, bytes); + r->pcurrent += bytes; + + if (r->pcurrent >= r->pend) + { + r->pcurrent = r->pixels; + r->count --; + r->remaining --; + } + } + + remaining -= bytes; + p += bytes; + } + + return (len); +} + + +/* + * 'cupsRasterWriteHeader()' - Write a raster page header from a version 1 page + * header structure. + * + * This function is deprecated. Use @link cupsRasterWriteHeader2@ instead. + * + * @deprecated@ + */ + +unsigned /* O - 1 on success, 0 on failure */ +cupsRasterWriteHeader( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header_t *h) /* I - Raster page header */ +{ + if (r == NULL || r->mode == CUPS_RASTER_READ) + return (0); + + /* + * Make a copy of the header, and compute the number of raster + * lines in the page image... + */ + + memset(&(r->header), 0, sizeof(r->header)); + memcpy(&(r->header), h, sizeof(cups_page_header_t)); + + cups_raster_update(r); + + /* + * Write the raster header... + */ + + return (cups_raster_io(r, (unsigned char *)&(r->header), sizeof(r->header)) + == sizeof(r->header)); +} + + +/* + * 'cupsRasterWriteHeader2()' - Write a raster page header from a version 2 + * page header structure. + * + * The page header can be initialized using @link cupsRasterInterpretPPD@. + * + * @since CUPS 1.2/Mac OS X 10.5@ + */ + +unsigned /* O - 1 on success, 0 on failure */ +cupsRasterWriteHeader2( + cups_raster_t *r, /* I - Raster stream */ + cups_page_header2_t *h) /* I - Raster page header */ +{ + if (r == NULL || r->mode == CUPS_RASTER_READ) + return (0); + + /* + * Make a copy of the header, and compute the number of raster + * lines in the page image... + */ + + memcpy(&(r->header), h, sizeof(cups_page_header2_t)); + + cups_raster_update(r); + + /* + * Write the raster header... + */ + + return (cups_raster_io(r, (unsigned char *)&(r->header), sizeof(r->header)) + == sizeof(r->header)); +} + + +/* + * 'cupsRasterWritePixels()' - Write raster pixels. + * + * For best performance, filters should write one or more whole lines. + * The "cupsBytesPerLine" value from the page header can be used to allocate + * the line buffer and as the number of bytes to write. + */ + +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 */ + + + DEBUG_printf(("cupsRasterWritePixels(r=%p, p=%p, len=%u), remaining=%u\n", + r, p, len, r->remaining)); + + if (r == NULL || r->mode == CUPS_RASTER_READ || r->remaining == 0) + return (0); + + if (!r->compressed) + { + /* + * Without compression, just write the raster data raw unless the data needs + * to be swapped... + */ + + r->remaining -= len / r->header.cupsBytesPerLine; + + if (r->swapped && + (r->header.cupsBitsPerColor == 16 || + r->header.cupsBitsPerPixel == 12 || + r->header.cupsBitsPerPixel == 16)) + { + unsigned char *bufptr; /* Pointer into write buffer */ + unsigned count; /* Remaining count */ + + /* + * Allocate a write buffer as needed... + */ + + if ((size_t)len > r->bufsize) + { + if (r->buffer) + bufptr = realloc(r->buffer, len); + else + bufptr = malloc(len); + + if (!bufptr) + return (0); + + r->buffer = bufptr; + r->bufsize = len; + } + + /* + * Byte swap the pixels... + */ + + for (bufptr = r->buffer, count = len; count > 1; count -= 2, bufptr += 2) + { + bufptr[1] = *p++; + bufptr[0] = *p++; + } + + if (count) /* This should never happen... */ + *bufptr = *p; + + /* + * Write the byte-swapped buffer... + */ + + return (cups_raster_io(r, r->buffer, len)); + } + else + return (cups_raster_io(r, p, len)); + } + + /* + * Otherwise, compress each line... + */ + + for (remaining = len; remaining > 0; remaining -= bytes, p += bytes) + { + /* + * Figure out the number of remaining bytes on the current line... + */ + + if ((bytes = remaining) > (r->pend - r->pcurrent)) + bytes = r->pend - r->pcurrent; + + if (r->count > 0) + { + /* + * Check to see if this line is the same as the previous line... + */ + + if (memcmp(p, r->pcurrent, bytes)) + { + if (!cups_raster_write(r, r->pixels)) + return (0); + + r->count = 0; + } + else + { + /* + * Mark more bytes as the same... + */ + + r->pcurrent += bytes; + + if (r->pcurrent >= r->pend) + { + /* + * Increase the repeat count... + */ + + r->count ++; + r->pcurrent = r->pixels; + + /* + * Flush out this line if it is the last one... + */ + + r->remaining --; + + if (r->remaining == 0) + return (cups_raster_write(r, r->pixels)); + else if (r->count == 256) + { + if (cups_raster_write(r, r->pixels) == 0) + return (0); + + r->count = 0; + } + } + + continue; + } + } + + if (r->count == 0) + { + /* + * Copy the raster data to the buffer... + */ + + memcpy(r->pcurrent, p, bytes); + + r->pcurrent += bytes; + + if (r->pcurrent >= r->pend) + { + /* + * Increase the repeat count... + */ + + r->count ++; + r->pcurrent = r->pixels; + + /* + * Flush out this line if it is the last one... + */ + + r->remaining --; + + if (r->remaining == 0) + return (cups_raster_write(r, r->pixels)); + } + } + } + + return (len); +} + + +/* + * 'cups_raster_read_header()' - Read a raster page header. + */ + +static unsigned /* O - 1 on success, 0 on fail */ +cups_raster_read_header( + cups_raster_t *r) /* I - Raster stream */ +{ + int len; /* Length for read/swap */ + + + if (r == NULL || r->mode != CUPS_RASTER_READ) + return (0); + + /* + * Get the length of the raster header... + */ + + if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1) + len = sizeof(cups_page_header_t); + else + len = sizeof(cups_page_header2_t); + + /* + * Read the header... + */ + + memset(&(r->header), 0, sizeof(r->header)); + + if (cups_raster_read(r, (unsigned char *)&(r->header), len) < len) + return (0); + + /* + * Swap bytes as needed... + */ + + if (r->swapped) + { + unsigned *s, /* Current word */ + temp; /* Temporary copy */ + + + DEBUG_puts("Swapping header bytes..."); + + for (len = 81, s = &(r->header.AdvanceDistance); + len > 0; + len --, s ++) + { + DEBUG_printf(("%08x =>", *s)); + + temp = *s; + *s = ((temp & 0xff) << 24) | + ((temp & 0xff00) << 8) | + ((temp & 0xff0000) >> 8) | + ((temp & 0xff000000) >> 24); + + DEBUG_printf((" %08x\n", *s)); + } + } + + /* + * Update the header and row count... + */ + + cups_raster_update(r); + + return (1); +} + + +/* + * 'cups_raster_io()' - Read/write bytes from a context, handling interruptions. + */ + +static int /* O - Bytes read or -1 */ +cups_raster_io(cups_raster_t *r, /* I - Raster stream */ + unsigned char *buf, /* I - Buffer for read/write */ + int bytes) /* I - Number of bytes to read/write */ +{ + ssize_t count; /* Number of bytes read/written */ + size_t total; /* Total bytes read/written */ + + + DEBUG_printf(("4cups_raster_io(r=%p, buf=%p, bytes=%d)", r, buf, bytes)); + + for (total = 0; total < bytes; total += count, buf += count) + { + count = (*r->iocb)(r->ctx, buf, bytes - total); + + DEBUG_printf(("5cups_raster_io: count=%d, total=%d", (int)count, + (int)total)); + if (count == 0) + return (0); + else if (count < 0) + return (-1); + } + + return ((int)total); +} + + +/* + * 'cups_raster_read()' - Read through the raster buffer. + */ + +static int /* O - Number of bytes read */ +cups_raster_read(cups_raster_t *r, /* I - Raster stream */ + unsigned char *buf, /* I - Buffer */ + int bytes) /* I - Number of bytes to read */ +{ + int count, /* Number of bytes read */ + remaining, /* Remaining bytes in buffer */ + total; /* Total bytes read */ + + + DEBUG_printf(("cups_raster_read(r=%p, buf=%p, bytes=%d)\n", r, buf, bytes)); + + if (!r->compressed) + return (cups_raster_io(r, buf, bytes)); + + /* + * Allocate a read buffer as needed... + */ + + count = 2 * r->header.cupsBytesPerLine; + + if ((size_t)count > r->bufsize) + { + int offset = r->bufptr - r->buffer; /* Offset to current start of buffer */ + int end = r->bufend - r->buffer; /* Offset to current end of buffer */ + unsigned char *rptr; /* Pointer in read buffer */ + + if (r->buffer) + rptr = realloc(r->buffer, count); + else + rptr = malloc(count); + + if (!rptr) + return (0); + + r->buffer = rptr; + r->bufptr = rptr + offset; + r->bufend = rptr + end; + r->bufsize = count; + } + + /* + * Loop until we have read everything... + */ + + for (total = 0, remaining = r->bufend - r->bufptr; + total < bytes; + total += count, buf += count) + { + count = bytes - total; + + DEBUG_printf(("count=%d, remaining=%d, buf=%p, bufptr=%p, bufend=%p...\n", + count, remaining, buf, r->bufptr, r->bufend)); + + if (remaining == 0) + { + if (count < 16) + { + /* + * Read into the raster buffer and then copy... + */ + + remaining = (*r->iocb)(r->ctx, r->buffer, r->bufsize); + if (remaining <= 0) + return (0); + + r->bufptr = r->buffer; + r->bufend = r->buffer + remaining; + } + else + { + /* + * Read directly into "buf"... + */ + + count = (*r->iocb)(r->ctx, buf, count); + + if (count <= 0) + return (0); + + continue; + } + } + + /* + * Copy bytes from raster buffer to "buf"... + */ + + if (count > remaining) + count = remaining; + + if (count == 1) + { + /* + * Copy 1 byte... + */ + + *buf = *(r->bufptr)++; + remaining --; + } + else if (count < 128) + { + /* + * Copy up to 127 bytes without using memcpy(); this is + * faster because it avoids an extra function call and is + * often further optimized by the compiler... + */ + + unsigned char *bufptr; /* Temporary buffer pointer */ + + + remaining -= count; + + for (bufptr = r->bufptr; count > 0; count --, total ++) + *buf++ = *bufptr++; + + r->bufptr = bufptr; + } + else + { + /* + * Use memcpy() for a large read... + */ + + memcpy(buf, r->bufptr, count); + r->bufptr += count; + remaining -= count; + } + } + + return (total); +} + + +/* + * 'cups_raster_update()' - Update the raster header and row count for the + * current page. + */ + +static void +cups_raster_update(cups_raster_t *r) /* I - Raster stream */ +{ + if (r->sync == CUPS_RASTER_SYNCv1 || r->sync == CUPS_RASTER_REVSYNCv1 || + r->header.cupsNumColors == 0) + { + /* + * Set the "cupsNumColors" field according to the colorspace... + */ + + switch (r->header.cupsColorSpace) + { + case CUPS_CSPACE_W : + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + case CUPS_CSPACE_SW : + r->header.cupsNumColors = 1; + break; + + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + case CUPS_CSPACE_CIEXYZ : + case CUPS_CSPACE_CIELab : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : + 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 : + r->header.cupsNumColors = 3; + break; + + case CUPS_CSPACE_RGBA : + case CUPS_CSPACE_RGBW : + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + r->header.cupsNumColors = 4; + break; + + case CUPS_CSPACE_KCMYcm : + if (r->header.cupsBitsPerPixel < 8) + r->header.cupsNumColors = 6; + else + r->header.cupsNumColors = 4; + break; + + case CUPS_CSPACE_DEVICE1 : + case CUPS_CSPACE_DEVICE2 : + case CUPS_CSPACE_DEVICE3 : + case CUPS_CSPACE_DEVICE4 : + case CUPS_CSPACE_DEVICE5 : + case CUPS_CSPACE_DEVICE6 : + case CUPS_CSPACE_DEVICE7 : + case CUPS_CSPACE_DEVICE8 : + case CUPS_CSPACE_DEVICE9 : + case CUPS_CSPACE_DEVICEA : + case CUPS_CSPACE_DEVICEB : + case CUPS_CSPACE_DEVICEC : + case CUPS_CSPACE_DEVICED : + case CUPS_CSPACE_DEVICEE : + case CUPS_CSPACE_DEVICEF : + r->header.cupsNumColors = r->header.cupsColorSpace - + CUPS_CSPACE_DEVICE1 + 1; + break; + } + } + + /* + * Set the number of bytes per pixel/color... + */ + + if (r->header.cupsColorOrder == CUPS_ORDER_CHUNKED) + r->bpp = (r->header.cupsBitsPerPixel + 7) / 8; + else + r->bpp = (r->header.cupsBitsPerColor + 7) / 8; + + /* + * Set the number of remaining rows... + */ + + if (r->header.cupsColorOrder == CUPS_ORDER_PLANAR) + r->remaining = r->header.cupsHeight * r->header.cupsNumColors; + else + r->remaining = r->header.cupsHeight; + + /* + * Allocate the compression buffer... + */ + + if (r->compressed) + { + if (r->pixels != NULL) + free(r->pixels); + + r->pixels = calloc(r->header.cupsBytesPerLine, 1); + r->pcurrent = r->pixels; + r->pend = r->pixels + r->header.cupsBytesPerLine; + r->count = 0; + } +} + + +/* + * 'cups_raster_write()' - Write a row of compressed raster data... + */ + +static int /* O - Number of bytes written */ +cups_raster_write( + cups_raster_t *r, /* I - Raster stream */ + const unsigned char *pixels) /* I - Pixel data to write */ +{ + const unsigned char *start, /* Start of sequence */ + *ptr, /* Current pointer in sequence */ + *pend, /* End of raster buffer */ + *plast; /* Pointer to last pixel */ + unsigned char *wptr; /* Pointer into write buffer */ + int bpp, /* Bytes per pixel */ + count; /* Count */ + + + DEBUG_printf(("cups_raster_write(r=%p, pixels=%p)\n", r, pixels)); + + /* + * Allocate a write buffer as needed... + */ + + count = r->header.cupsBytesPerLine * 2; + if ((size_t)count > r->bufsize) + { + if (r->buffer) + wptr = realloc(r->buffer, count); + else + wptr = malloc(count); + + if (!wptr) + return (-1); + + r->buffer = wptr; + r->bufsize = count; + } + + /* + * Write the row repeat count... + */ + + bpp = r->bpp; + pend = pixels + r->header.cupsBytesPerLine; + plast = pend - bpp; + wptr = r->buffer; + *wptr++ = r->count - 1; + + /* + * Write using a modified TIFF "packbits" compression... + */ + + for (ptr = pixels; ptr < pend;) + { + start = ptr; + ptr += bpp; + + if (ptr == pend) + { + /* + * Encode a single pixel at the end... + */ + + *wptr++ = 0; + for (count = bpp; count > 0; count --) + *wptr++ = *start++; + } + else if (!memcmp(start, ptr, bpp)) + { + /* + * Encode a sequence of repeating pixels... + */ + + for (count = 2; count < 128 && ptr < plast; count ++, ptr += bpp) + if (memcmp(ptr, ptr + bpp, bpp)) + break; + + *wptr++ = count - 1; + for (count = bpp; count > 0; count --) + *wptr++ = *ptr++; + } + else + { + /* + * Encode a sequence of non-repeating pixels... + */ + + for (count = 1; count < 127 && ptr < plast; count ++, ptr += bpp) + if (!memcmp(ptr, ptr + bpp, bpp)) + break; + + if (ptr >= plast && count < 128) + { + count ++; + ptr += bpp; + } + + *wptr++ = 257 - count; + + count *= bpp; + memcpy(wptr, start, count); + wptr += count; + } + } + + return (cups_raster_io(r, r->buffer, wptr - r->buffer)); +} + + +/* + * 'cups_read_fd()' - Read bytes from a file. + */ + +static ssize_t /* O - Bytes read or -1 */ +cups_read_fd(void *ctx, /* I - File descriptor as pointer */ + unsigned char *buf, /* I - Buffer for read */ + size_t bytes) /* I - Maximum number of bytes to read */ +{ + int fd = (int)((intptr_t)ctx); + /* File descriptor */ + ssize_t count; /* Number of bytes read */ + + + while ((count = read(fd, buf, bytes)) < 0) + if (errno != EINTR && errno != EAGAIN) + return (-1); + + return (count); +} + + +/* + * 'cups_swap()' - Swap bytes in raster data... + */ + +static void +cups_swap(unsigned char *buf, /* I - Buffer to swap */ + int bytes) /* I - Number of bytes to swap */ +{ + unsigned char even, odd; /* Temporary variables */ + + + bytes /= 2; + + while (bytes > 0) + { + even = buf[0]; + odd = buf[1]; + buf[0] = odd; + buf[1] = even; + + buf += 2; + bytes --; + } +} + + +/* + * 'cups_write_fd()' - Write bytes to a file. + */ + +static ssize_t /* O - Bytes written or -1 */ +cups_write_fd(void *ctx, /* I - File descriptor pointer */ + unsigned char *buf, /* I - Bytes to write */ + size_t bytes) /* I - Number of bytes to write */ +{ + int fd = (int)((intptr_t)ctx); + /* File descriptor */ + ssize_t count; /* Number of bytes written */ + + + while ((count = write(fd, buf, bytes)) < 0) + if (errno != EINTR && errno != EAGAIN) + return (-1); + + return (count); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/rasterbench.c b/filter/rasterbench.c new file mode 100644 index 0000000000..5d30c84559 --- /dev/null +++ b/filter/rasterbench.c @@ -0,0 +1,355 @@ +/* + * "$Id$" + * + * Raster benchmark program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Benchmark the raster read/write functions. + * compute_median() - Compute the median time for a test. + * read_test() - Benchmark the raster read functions. + * write_test() - Benchmark the raster write functions. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include + + +/* + * Constants... + */ + +#define TEST_WIDTH 1024 +#define TEST_HEIGHT 1024 +#define TEST_PAGES 16 +#define TEST_PASSES 20 + + +/* + * Local functions... + */ + +static double compute_median(double *secs); +static double get_time(void); +static void read_test(int fd); +static int run_read_test(void); +static void write_test(int fd, cups_mode_t mode); + + +/* + * 'main()' - Benchmark the raster read/write functions. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int ras_fd, /* File descriptor for read process */ + status; /* Exit status of read process */ + double start_secs, /* Start time */ + write_secs, /* Write time */ + read_secs, /* Read time */ + pass_secs[TEST_PASSES]; /* Total test times */ + cups_mode_t mode; /* Write mode */ + + + /* + * See if we have anything on the command-line... + */ + + if (argc > 2 || (argc == 2 && strcmp(argv[1], "-z"))) + { + puts("Usage: rasterbench [-z]"); + return (1); + } + + mode = argc > 1 ? CUPS_RASTER_WRITE_COMPRESSED : CUPS_RASTER_WRITE; + + /* + * Ignore SIGPIPE... + */ + + signal(SIGPIPE, SIG_IGN); + + /* + * Run the tests several times to get a good average... + */ + + printf("Test read/write speed of %d pages, %dx%d pixels...\n\n", + TEST_PAGES, TEST_WIDTH, TEST_HEIGHT); + for (i = 0; i < TEST_PASSES; i ++) + { + printf("PASS %2d: ", i + 1); + fflush(stdout); + + ras_fd = run_read_test(); + start_secs = get_time(); + + write_test(ras_fd, mode); + + write_secs = get_time(); + printf(" %.3f write,", write_secs - start_secs); + fflush(stdout); + + close(ras_fd); + wait(&status); + + read_secs = get_time(); + pass_secs[i] = read_secs - start_secs; + printf(" %.3f read, %.3f total\n", read_secs - write_secs, pass_secs[i]); + } + + printf("\nMedian Total Time: %.3f seconds per document\n", + compute_median(pass_secs)); + + return (0); +} + + +/* + * 'compute_median()' - Compute the median time for a test. + */ + +static double /* O - Median time in seconds */ +compute_median(double *secs) /* I - Array of time samples */ +{ + int i, j; /* Looping vars */ + double temp; /* Swap variable */ + + + /* + * Sort the array into ascending order using a quicky bubble sort... + */ + + for (i = 0; i < (TEST_PASSES - 1); i ++) + for (j = i + 1; j < TEST_PASSES; j ++) + if (secs[i] > secs[j]) + { + temp = secs[i]; + secs[i] = secs[j]; + secs[j] = temp; + } + + /* + * Return the average of the middle two samples... + */ + + return (0.5 * (secs[TEST_PASSES / 2 - 1] + secs[TEST_PASSES / 2])); +} + + +/* + * 'get_time()' - Get the current time in seconds. + */ + +static double /* O - Time in seconds */ +get_time(void) +{ + struct timeval curtime; /* Current time */ + + + gettimeofday(&curtime, NULL); + return (curtime.tv_sec + 0.000001 * curtime.tv_usec); +} + + +/* + * 'read_test()' - Benchmark the raster read functions. + */ + +static void +read_test(int fd) /* I - File descriptor to read from */ +{ + int y; /* Looping var */ + cups_raster_t *r; /* Raster stream */ + cups_page_header2_t header; /* Page header */ + unsigned char buffer[8 * TEST_WIDTH]; + /* Read buffer */ + + + /* + * Test read speed... + */ + + if ((r = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL) + { + perror("Unable to create raster input stream"); + return; + } + + while (cupsRasterReadHeader2(r, &header)) + { + for (y = 0; y < header.cupsHeight; y ++) + cupsRasterReadPixels(r, buffer, header.cupsBytesPerLine); + } + + cupsRasterClose(r); +} + + +/* + * 'run_read_test()' - Run the read test as a child process via pipes. + */ + +static int /* O - Standard input of child */ +run_read_test(void) +{ + int ras_pipes[2]; /* Raster data pipes */ + int pid; /* Child process ID */ + + + if (pipe(ras_pipes)) + return (-1); + + if ((pid = fork()) < 0) + { + /* + * Fork error - return -1 on error... + */ + + close(ras_pipes[0]); + close(ras_pipes[1]); + + return (-1); + } + else if (pid == 0) + { + /* + * Child comes here - read data from the input pipe... + */ + + close(ras_pipes[1]); + read_test(ras_pipes[0]); + exit(0); + } + else + { + /* + * Parent comes here - return the output pipe... + */ + + close(ras_pipes[0]); + return (ras_pipes[1]); + } +} + + +/* + * 'write_test()' - Benchmark the raster write functions. + */ + +static void +write_test(int fd, /* I - File descriptor to write to */ + cups_mode_t mode) /* I - Write mode */ +{ + int page, x, y; /* Looping vars */ + int count; /* Number of bytes to set */ + cups_raster_t *r; /* Raster stream */ + cups_page_header2_t header; /* Page header */ + unsigned char data[32][8 * TEST_WIDTH]; + /* Raster data to write */ + + + /* + * Create a combination of random data and repeated data to simulate + * text with some whitespace. + */ + + CUPS_SRAND(time(NULL)); + + memset(data, 0, sizeof(data)); + + for (y = 0; y < 28; y ++) + { + for (x = CUPS_RAND() & 127, count = (CUPS_RAND() & 15) + 1; + x < sizeof(data[0]); + x ++, count --) + { + if (count <= 0) + { + x += (CUPS_RAND() & 15) + 1; + count = (CUPS_RAND() & 15) + 1; + + if (x >= sizeof(data[0])) + break; + } + + data[y][x] = CUPS_RAND(); + } + } + + /* + * Test write speed... + */ + + if ((r = cupsRasterOpen(fd, mode)) == NULL) + { + perror("Unable to create raster output stream"); + return; + } + + for (page = 0; page < TEST_PAGES; page ++) + { + memset(&header, 0, sizeof(header)); + header.cupsWidth = TEST_WIDTH; + header.cupsHeight = TEST_HEIGHT; + header.cupsBytesPerLine = TEST_WIDTH; + + if (page & 1) + { + header.cupsBytesPerLine *= 4; + header.cupsColorSpace = CUPS_CSPACE_CMYK; + header.cupsColorOrder = CUPS_ORDER_CHUNKED; + } + else + { + header.cupsColorSpace = CUPS_CSPACE_K; + header.cupsColorOrder = CUPS_ORDER_BANDED; + } + + if (page & 2) + { + header.cupsBytesPerLine *= 2; + header.cupsBitsPerColor = 16; + header.cupsBitsPerPixel = (page & 1) ? 64 : 16; + } + else + { + header.cupsBitsPerColor = 8; + header.cupsBitsPerPixel = (page & 1) ? 32 : 8; + } + + cupsRasterWriteHeader2(r, &header); + + for (y = 0; y < TEST_HEIGHT; y ++) + cupsRasterWritePixels(r, data[y & 31], header.cupsBytesPerLine); + } + + cupsRasterClose(r); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c new file mode 100644 index 0000000000..d28e77467b --- /dev/null +++ b/filter/rastertoepson.c @@ -0,0 +1,1142 @@ +/* + * "$Id$" + * + * EPSON ESC/P and ESC/P2 filter for the Common UNIX Printing System + * (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * 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 */ + EjectPage; /* Eject the page when done? */ +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? */ + Canceled; /* Has the current job been canceled? */ + + +/* + * Prototypes... + */ + +void Setup(void); +void StartPage(const ppd_file_t *ppd, const cups_page_header2_t *header); +void EndPage(const cups_page_header2_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_header2_t *header); +void OutputRows(const cups_page_header2_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 && Model >= EPSON_ICOLOR) + 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_header2_t *header) /* I - Page header */ +{ + int n, t; /* Numbers */ + int plane; /* Looping var */ + + + /* + * Send a reset sequence. + */ + + if (ppd && ppd->nickname && strstr(ppd->nickname, "OKIDATA") != NULL) + printf("\033{A"); /* Set EPSON emulation mode */ + + printf("\033@"); + + /* + * See which type of printer we are using... + */ + + switch (Model) + { + case EPSON_9PIN : + case EPSON_24PIN : + printf("\033P\022"); /* 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("\033\062\033C%c", /* Page length in 1/6th inches */ + (int)(header->PageSize[1] / 12.0 + 0.5)); + printf("\033N%c", 0); /* Bottom margin */ + printf("\033O"); /* No perforation skip */ + + /* + * Setup various buffer limits... + */ + + DotBytes = header->cupsRowCount / 8; + DotColumns = header->HWResolution[0] / 60; + Shingling = 0; + + if (Model == EPSON_9PIN) + printf("\033\063\030"); /* Set line feed */ + else + switch (header->HWResolution[0]) + { + case 60: + case 120 : + case 240 : + 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); + + if (ppd) + t = (ppd->sizes[1].length - ppd->sizes[1].top) * + header->HWResolution[1] / 72.0; + else + t = 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... + */ + + if ((Planes[0] = malloc(header->cupsBytesPerLine)) == NULL) + { + fputs("ERROR: Unable to allocate memory!\n", stderr); + exit(1); + } + + for (plane = 1; plane < NumPlanes; plane ++) + Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes; + + if (header->cupsCompression || DotBytes) + { + if ((CompBuffer = calloc(2, header->cupsWidth)) == NULL) + { + fputs("ERROR: Unable to allocate memory!\n", stderr); + exit(1); + } + } + else + CompBuffer = NULL; + + if (DotBytes) + { + if ((LineBuffers[0] = calloc(DotBytes, + header->cupsWidth * (Shingling + 1))) == NULL) + { + fputs("ERROR: Unable to allocate memory!\n", stderr); + exit(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_header2_t *header) /* I - Page header */ +{ + if (DotBytes && header) + { + /* + * Flush remaining graphics as needed... + */ + + if (!Shingling) + { + if (DotBit < 128 || EvenOffset) + 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); + + /* + * 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 */ +{ + (void)sig; + + Canceled = 1; +} + + +/* + * '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_header2_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_header2_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... + */ + + if (i == 0) + putchar('\r'); + else + { + 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... + */ + + if (i == 0) + putchar('\r'); + else + { + 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_header2_t header; /* Page header from file */ + ppd_file_t *ppd; /* PPD file */ + int page; /* Current page */ + int y; /* Current line */ +#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 < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + "rastertoepson"); + return (1); + } + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"), + strerror(errno)); + sleep(1); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Register a signal handler to eject the current page if the + * job is cancelled. + */ + + Canceled = 0; + +#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 */ + + /* + * Initialize the print device... + */ + + ppd = ppdOpenFile(getenv("PPD")); + if (ppd) + Model = ppd->model_number; + + Setup(); + + /* + * Process pages as needed... + */ + + page = 0; + + while (cupsRasterReadHeader2(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + if (Canceled) + break; + + 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 (Canceled) + break; + + if ((y & 127) == 0) + _cupsLangPrintf(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); + + if (Canceled) + break; + } + + /* + * 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) + { + _cupsLangPuts(stderr, _("ERROR: No pages found!\n")); + return (1); + } + else + { + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + return (0); + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/rastertohp.c b/filter/rastertohp.c new file mode 100644 index 0000000000..9c5ffe4798 --- /dev/null +++ b/filter/rastertohp.c @@ -0,0 +1,870 @@ +/* + * "$Id$" + * + * Hewlett-Packard Page Control Language filter for the Common UNIX + * Printing System (CUPS). + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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 +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * 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 */ + Canceled; /* Has the current job been canceled? */ + + +/* + * Prototypes... + */ + +void Setup(void); +void StartPage(ppd_file_t *ppd, cups_page_header2_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_header2_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_header2_t *header) /* I - Page header */ +{ + int plane; /* Looping var */ + + + /* + * Show page device dictionary... + */ + + fprintf(stderr, "DEBUG: StartPage...\n"); + fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass); + fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor); + fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType); + fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType); + + fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance); + fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia); + fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate); + fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia); + fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex); + fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0], + header->HWResolution[1]); + fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", + header->ImagingBoundingBox[0], header->ImagingBoundingBox[1], + header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]); + fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet); + fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog); + fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge); + fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0], + header->Margins[1]); + fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed); + fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition); + fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight); + fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint); + fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint); + fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies); + fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation); + fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp); + fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0], + header->PageSize[1]); + fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations); + fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch); + fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble); + fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth); + fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight); + fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType); + 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: cupsCompression = %d\n", header->cupsCompression); + + /* + * Setup printer/job attributes... + */ + + Duplex = header->Duplex; + ColorBits = header->cupsBitsPerColor; + + if ((!Duplex || (Page & 1)) && header->MediaPosition) + printf("\033&l%dH", /* Set media position */ + header->MediaPosition); + + if (Duplex && ppd && ppd->model_number == 2) + { + /* + * Handle duplexing on new DeskJet printers... + */ + + printf("\033&l-2H"); /* Load media */ + + if (Page & 1) + printf("\033&l2S"); /* Set duplex mode */ + } + + if (!Duplex || (Page & 1) || (ppd && ppd->model_number == 2)) + { + /* + * Set the media 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 595 : /* A5 */ + printf("\033&l25A"); /* 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 */ + } + + if (!Duplex || (Page & 1)) + { + /* + * Set other job options... + */ + + printf("\033&l%dX", header->NumCopies); /* Set number copies */ + + if (header->cupsMediaType && + (!ppd || ppd->model_number != 2 || header->HWResolution[0] == 600)) + printf("\033&l%dM", /* Set media type */ + header->cupsMediaType); + + if (!ppd || ppd->model_number != 2) + { + int mode = Duplex ? 1 + header->Tumble != 0 : 0; + + printf("\033&l%dS", mode); /* Set duplex mode */ + printf("\033&l0L"); /* Turn off perforation skip */ + } + } + else if (!ppd || ppd->model_number != 2) + printf("\033&a2G"); /* Set back side */ + + /* + * Set graphics mode... + */ + + if (ppd && ppd->model_number == 2) + { + /* + * Figure out the number of color planes... + */ + + if (header->cupsColorSpace == CUPS_CSPACE_KCMY) + NumPlanes = 4; + else + NumPlanes = 1; + + /* + * Set the resolution and top-of-form... + */ + + printf("\033&u%dD", header->HWResolution[0]); + /* Resolution */ + printf("\033&l0e0L"); /* Reset top and don't skip */ + printf("\033*p0Y\033*p0X"); /* Set top of form */ + + /* + * 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 */ + + printf("\033&l0H"); /* Set media position */ + } + else + { + printf("\033*t%dR", header->HWResolution[0]); + /* Set resolution */ + + 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... + */ + + if ((Planes[0] = malloc(header->cupsBytesPerLine)) == NULL) + { + fputs("ERROR: Unable to allocate memory!\n", stderr); + exit(1); + } + + 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) +{ + /* + * 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); + + /* + * 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 */ +{ + (void)sig; + + Canceled = 1; +} + + +/* + * '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", (int)(line_end - line_ptr), plane); + fwrite(line_ptr, line_end - line_ptr, 1, stdout); +} + + +/* + * 'OutputLine()' - Output a line of graphics. + */ + +void +OutputLine(cups_page_header2_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_header2_t header; /* Page header from file */ + int y; /* Current line */ + ppd_file_t *ppd; /* PPD file */ +#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 < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + "rastertohp"); + return (1); + } + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"), + strerror(errno)); + sleep(1); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Register a signal handler to eject the current page if the + * job is cancelled. + */ + + Canceled = 0; + +#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 */ + + /* + * Initialize the print device... + */ + + ppd = ppdOpenFile(getenv("PPD")); + + Setup(); + + /* + * Process pages as needed... + */ + + Page = 0; + + while (cupsRasterReadHeader2(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + if (Canceled) + break; + + 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 (Canceled) + break; + + if ((y & 127) == 0) + _cupsLangPrintf(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(); + + if (Canceled) + break; + } + + /* + * 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) + { + _cupsLangPuts(stderr, _("ERROR: No pages found!\n")); + return (1); + } + else + { + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + return (0); + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/rastertolabel.c b/filter/rastertolabel.c new file mode 100644 index 0000000000..0ca1b08bdc --- /dev/null +++ b/filter/rastertolabel.c @@ -0,0 +1,1298 @@ +/* + * "$Id$" + * + * Label printer filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 2001-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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. + * CancelJob() - Cancel the current job... + * OutputLine() - Output a line of graphics. + * PCLCompress() - Output a PCL (mode 3) compressed line. + * ZPLCompress() - Output a run-length compression sequence. + * main() - Main entry and processing of driver. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * This driver filter currently supports Dymo, Intellitech, and Zebra + * label printers. + * + * The Dymo portion of the driver has been tested with the 300, 330, + * and 330 Turbo label printers; it may also work with other models. + * The Dymo printers support printing at 136, 203, and 300 DPI. + * + * The Intellitech portion of the driver has been tested with the + * Intellibar 408, 412, and 808 and supports their PCL variant. + * + * The Zebra portion of the driver has been tested with the LP-2844, + * LP-2844Z, QL-320, and QL-420 label printers; it may also work with + * other models. The driver supports EPL line mode, EPL page mode, + * ZPL, and CPCL as defined in Zebra's online developer documentation. + */ + +/* + * Model number constants... + */ + +#define DYMO_3x0 0 /* Dymo Labelwriter 300/330/330 Turbo */ + +#define ZEBRA_EPL_LINE 0x10 /* Zebra EPL line mode printers */ +#define ZEBRA_EPL_PAGE 0x11 /* Zebra EPL page mode printers */ +#define ZEBRA_ZPL 0x12 /* Zebra ZPL-based printers */ +#define ZEBRA_CPCL 0x13 /* Zebra CPCL-based printers */ + +#define INTELLITECH_PCL 0x20 /* Intellitech PCL-based printers */ + + +/* + * Globals... + */ + +unsigned char *Buffer; /* Output buffer */ +unsigned char *CompBuffer; /* Compression buffer */ +unsigned char *LastBuffer; /* Last buffer */ +int LastSet; /* Number of repeat characters */ +int ModelNumber, /* cupsModelNumber attribute */ + Page, /* Current page */ + Feed, /* Number of lines to skip */ + Canceled; /* Non-zero if job is canceled */ + + +/* + * Prototypes... + */ + +void Setup(ppd_file_t *ppd); +void StartPage(ppd_file_t *ppd, cups_page_header2_t *header); +void EndPage(ppd_file_t *ppd, cups_page_header2_t *header); +void CancelJob(int sig); +void OutputLine(ppd_file_t *ppd, cups_page_header2_t *header, int y); +void PCLCompress(unsigned char *line, int length); +void ZPLCompress(char repeat_char, int repeat_count); + + +/* + * 'Setup()' - Prepare the printer for printing. + */ + +void +Setup(ppd_file_t *ppd) /* I - PPD file */ +{ + int i; /* Looping var */ + + + /* + * Get the model number from the PPD file... + */ + + if (ppd) + ModelNumber = ppd->model_number; + + /* + * Initialize based on the model number... + */ + + switch (ModelNumber) + { + case DYMO_3x0 : + /* + * Clear any remaining data... + */ + + for (i = 0; i < 100; i ++) + putchar(0x1b); + + /* + * Reset the printer... + */ + + fputs("\033@", stdout); + break; + + case ZEBRA_EPL_LINE : + break; + + case ZEBRA_EPL_PAGE : + break; + + case ZEBRA_ZPL : + break; + + case ZEBRA_CPCL : + break; + + case INTELLITECH_PCL : + /* + * Send a PCL reset sequence. + */ + + putchar(0x1b); + putchar('E'); + break; + } +} + + +/* + * 'StartPage()' - Start a page of graphics. + */ + +void +StartPage(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header) /* I - Page header */ +{ + ppd_choice_t *choice; /* Marked choice */ + int length; /* Actual label length */ + + + /* + * Show page device dictionary... + */ + + fprintf(stderr, "DEBUG: StartPage...\n"); + fprintf(stderr, "DEBUG: MediaClass = \"%s\"\n", header->MediaClass); + fprintf(stderr, "DEBUG: MediaColor = \"%s\"\n", header->MediaColor); + fprintf(stderr, "DEBUG: MediaType = \"%s\"\n", header->MediaType); + fprintf(stderr, "DEBUG: OutputType = \"%s\"\n", header->OutputType); + + fprintf(stderr, "DEBUG: AdvanceDistance = %d\n", header->AdvanceDistance); + fprintf(stderr, "DEBUG: AdvanceMedia = %d\n", header->AdvanceMedia); + fprintf(stderr, "DEBUG: Collate = %d\n", header->Collate); + fprintf(stderr, "DEBUG: CutMedia = %d\n", header->CutMedia); + fprintf(stderr, "DEBUG: Duplex = %d\n", header->Duplex); + fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", header->HWResolution[0], + header->HWResolution[1]); + fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", + header->ImagingBoundingBox[0], header->ImagingBoundingBox[1], + header->ImagingBoundingBox[2], header->ImagingBoundingBox[3]); + fprintf(stderr, "DEBUG: InsertSheet = %d\n", header->InsertSheet); + fprintf(stderr, "DEBUG: Jog = %d\n", header->Jog); + fprintf(stderr, "DEBUG: LeadingEdge = %d\n", header->LeadingEdge); + fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", header->Margins[0], + header->Margins[1]); + fprintf(stderr, "DEBUG: ManualFeed = %d\n", header->ManualFeed); + fprintf(stderr, "DEBUG: MediaPosition = %d\n", header->MediaPosition); + fprintf(stderr, "DEBUG: MediaWeight = %d\n", header->MediaWeight); + fprintf(stderr, "DEBUG: MirrorPrint = %d\n", header->MirrorPrint); + fprintf(stderr, "DEBUG: NegativePrint = %d\n", header->NegativePrint); + fprintf(stderr, "DEBUG: NumCopies = %d\n", header->NumCopies); + fprintf(stderr, "DEBUG: Orientation = %d\n", header->Orientation); + fprintf(stderr, "DEBUG: OutputFaceUp = %d\n", header->OutputFaceUp); + fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", header->PageSize[0], + header->PageSize[1]); + fprintf(stderr, "DEBUG: Separations = %d\n", header->Separations); + fprintf(stderr, "DEBUG: TraySwitch = %d\n", header->TraySwitch); + fprintf(stderr, "DEBUG: Tumble = %d\n", header->Tumble); + fprintf(stderr, "DEBUG: cupsWidth = %d\n", header->cupsWidth); + fprintf(stderr, "DEBUG: cupsHeight = %d\n", header->cupsHeight); + fprintf(stderr, "DEBUG: cupsMediaType = %d\n", header->cupsMediaType); + 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: cupsCompression = %d\n", header->cupsCompression); + fprintf(stderr, "DEBUG: cupsRowCount = %d\n", header->cupsRowCount); + fprintf(stderr, "DEBUG: cupsRowFeed = %d\n", header->cupsRowFeed); + fprintf(stderr, "DEBUG: cupsRowStep = %d\n", header->cupsRowStep); + + switch (ModelNumber) + { + case DYMO_3x0 : + /* + * Setup printer/job attributes... + */ + + length = header->PageSize[1] * header->HWResolution[1] / 72; + + printf("\033L%c%c", length >> 8, length); + printf("\033D%c", header->cupsBytesPerLine); + + printf("\033%c", header->cupsCompression + 'c'); /* Darkness */ + break; + + case ZEBRA_EPL_LINE : + /* + * Set print rate... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "zePrintRate")) != NULL && + strcmp(choice->choice, "Default")) + printf("\033S%.0f", atof(choice->choice) * 2.0 - 2.0); + + /* + * Set darkness... + */ + + if (header->cupsCompression > 0 && header->cupsCompression <= 100) + printf("\033D%d", 7 * header->cupsCompression / 100); + + /* + * Set left margin to 0... + */ + + fputs("\033M01", stdout); + + /* + * Start buffered output... + */ + + fputs("\033B", stdout); + break; + + case ZEBRA_EPL_PAGE : + /* + * Start a new label... + */ + + puts(""); + puts("N"); + + /* + * Set hardware options... + */ + + if (!strcmp(header->MediaType, "Direct")) + puts("OD"); + + /* + * Set print rate... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "zePrintRate")) != NULL && + strcmp(choice->choice, "Default")) + { + float val = atof(choice->choice); + + if (val >= 3.0) + printf("S%.0f\n", val); + else + printf("S%.0f\n", val * 2.0 - 2.0); + } + + /* + * Set darkness... + */ + + if (header->cupsCompression > 0 && header->cupsCompression <= 100) + printf("D%d\n", 15 * header->cupsCompression / 100); + + /* + * Set label size... + */ + + printf("q%d\n", (header->cupsWidth + 7) & ~7); + break; + + case ZEBRA_ZPL : + /* + * Set darkness... + */ + + if (header->cupsCompression > 0 && header->cupsCompression <= 100) + printf("~SD%02d\n", 30 * header->cupsCompression / 100); + + /* + * Start bitmap graphics... + */ + + printf("~DGR:CUPS.GRF,%d,%d,\n", + header->cupsHeight * header->cupsBytesPerLine, + header->cupsBytesPerLine); + + /* + * Allocate compression buffers... + */ + + CompBuffer = malloc(2 * header->cupsBytesPerLine + 1); + LastBuffer = malloc(header->cupsBytesPerLine); + LastSet = 0; + break; + + case ZEBRA_CPCL : + /* + * Start label... + */ + + printf("! 0 %u %u %u %u\r\n", header->HWResolution[0], + header->HWResolution[1], header->cupsHeight, + header->NumCopies); + printf("PAGE-WIDTH %d\r\n", header->cupsWidth); + printf("PAGE-HEIGHT %d\r\n", header->cupsWidth); + break; + + case INTELLITECH_PCL : + /* + * Set the media 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 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; + + default : /* Custom size */ + printf("\033!f%dZ", header->PageSize[1] * 300 / 72); + 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 */ + printf("\033&l0L"); /* Turn off perforation skip */ + + /* + * Print settings... + */ + + if (Page == 1) + { + if (header->cupsRowFeed) /* inPrintRate */ + printf("\033!p%dS", header->cupsRowFeed); + + if (header->cupsCompression != ~0) + /* inPrintDensity */ + printf("\033&d%dA", 30 * header->cupsCompression / 100 - 15); + + if ((choice = ppdFindMarkedChoice(ppd, "inPrintMode")) != NULL) + { + if (!strcmp(choice->choice, "Standard")) + fputs("\033!p0M", stdout); + else if (!strcmp(choice->choice, "Tear")) + { + fputs("\033!p1M", stdout); + + if (header->cupsRowCount) /* inTearInterval */ + printf("\033!n%dT", header->cupsRowCount); + } + else + { + fputs("\033!p2M", stdout); + + if (header->cupsRowStep) /* inCutInterval */ + printf("\033!n%dC", header->cupsRowStep); + } + } + } + + /* + * Setup graphics... + */ + + printf("\033*t%dR", header->HWResolution[0]); + /* Set resolution */ + + printf("\033*r%dS", header->cupsWidth); + /* Set width */ + printf("\033*r%dT", header->cupsHeight); + /* Set height */ + + printf("\033&a0H"); /* Set horizontal position */ + printf("\033&a0V"); /* Set vertical position */ + printf("\033*r1A"); /* Start graphics */ + printf("\033*b3M"); /* Set compression */ + + /* + * Allocate compression buffers... + */ + + CompBuffer = malloc(2 * header->cupsBytesPerLine + 1); + LastBuffer = malloc(header->cupsBytesPerLine); + LastSet = 0; + break; + } + + /* + * Allocate memory for a line of graphics... + */ + + Buffer = malloc(header->cupsBytesPerLine); + Feed = 0; +} + + +/* + * 'EndPage()' - Finish a page of graphics. + */ + +void +EndPage(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header) /* I - Page header */ +{ + int val; /* Option value */ + ppd_choice_t *choice; /* Marked choice */ + + + switch (ModelNumber) + { + case DYMO_3x0 : + /* + * Eject the current page... + */ + + fputs("\033E", stdout); + break; + + case ZEBRA_EPL_LINE : + /* + * End buffered output, eject the label... + */ + + fputs("\033E\014", stdout); + break; + + case ZEBRA_EPL_PAGE : + /* + * Print the label... + */ + + puts("P1"); + break; + + case ZEBRA_ZPL : + if (Canceled) + { + /* + * Cancel bitmap download... + */ + + puts("~DN"); + break; + } + + /* + * Start label... + */ + + puts("^XA"); + + /* + * Set print rate... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "zePrintRate")) != NULL && + strcmp(choice->choice, "Default")) + { + val = atoi(choice->choice); + printf("^PR%d,%d,%d\n", val, val, val); + } + + /* + * Put label home in default position (0,0)... + */ + + printf("^LH0,0\n"); + + /* + * Set media tracking... + */ + + if (ppdIsMarked(ppd, "zeMediaTracking", "Continuous")) + { + /* + * Add label length command for continuous... + */ + + printf("^LL%d\n", header->cupsHeight); + printf("^MNN\n"); + } + else if (ppdIsMarked(ppd, "zeMediaTracking", "Web")) + printf("^MNY\n"); + else if (ppdIsMarked(ppd, "zeMediaTracking", "Mark")) + printf("^MNM\n"); + + /* + * Set label top + */ + + if (header->cupsRowStep != 200) + printf("^LT%u\n", header->cupsRowStep); + + /* + * Set media type... + */ + + if (!strcmp(header->MediaType, "Thermal")) + printf("^MTT\n"); + else if (!strcmp(header->MediaType, "Direct")) + printf("^MTD\n"); + + /* + * Set print mode... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "zePrintMode")) != NULL && + strcmp(choice->choice, "Saved")) + { + printf("^MM"); + + if (!strcmp(choice->choice, "Tear")) + printf("T,Y\n"); + else if (!strcmp(choice->choice, "Peel")) + printf("P,Y\n"); + else if (!strcmp(choice->choice, "Rewind")) + printf("R,Y\n"); + else if (!strcmp(choice->choice, "Applicator")) + printf("A,Y\n"); + else + printf("C,Y\n"); + } + + /* + * Set tear-off adjust position... + */ + + if (header->AdvanceDistance != 1000) + { + if ((int)header->AdvanceDistance < 0) + printf("~TA%04d\n", (int)header->AdvanceDistance); + else + printf("~TA%03d\n", (int)header->AdvanceDistance); + } + + /* + * Allow for reprinting after an error... + */ + + if (ppdIsMarked(ppd, "zeErrorReprint", "Always")) + printf("^JZY\n"); + else if (ppdIsMarked(ppd, "zeErrorReprint", "Never")) + printf("^JZN\n"); + + /* + * Print multiple copies + */ + + if (header->NumCopies > 1) + printf("^PQ%d, 0, 0, N\n", header->NumCopies); + + /* + * Display the label image... + */ + + puts("^FO0,0^XGR:CUPS.GRF,1,1^FS"); + + /* + * End the label and eject... + */ + + puts("^IDR:CUPS.GRF^FS"); + puts("^XZ"); + + /* + * Free compression buffers... + */ + + free(CompBuffer); + free(LastBuffer); + break; + + case ZEBRA_CPCL : + /* + * Set tear-off adjust position... + */ + + if (header->AdvanceDistance != 1000) + printf("PRESENT-AT %d 1\r\n", (int)header->AdvanceDistance); + + /* + * Allow for reprinting after an error... + */ + + if (ppdIsMarked(ppd, "zeErrorReprint", "Always")) + puts("ON-OUT-OF-PAPER WAIT\r"); + else if (ppdIsMarked(ppd, "zeErrorReprint", "Never")) + puts("ON-OUT-OF-PAPER PURGE\r"); + + /* + * Cut label? + */ + + if (header->CutMedia) + puts("CUT\r"); + + /* + * Set darkness... + */ + + if (header->cupsCompression > 0) + printf("TONE %u\r\n", 2 * header->cupsCompression); + + /* + * Set print rate... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "zePrintRate")) != NULL && + strcmp(choice->choice, "Default")) + { + val = atoi(choice->choice); + printf("SPEED %d\r\n", val); + } + + /* + * Print the label... + */ + + if ((choice = ppdFindMarkedChoice(ppd, "zeMediaTracking")) == NULL || + strcmp(choice->choice, "Continuous")) + puts("FORM\r"); + + puts("PRINT\r"); + break; + + case INTELLITECH_PCL : + printf("\033*rB"); /* End GFX */ + printf("\014"); /* Eject current page */ + break; + } + + fflush(stdout); + + /* + * Free memory... + */ + + free(Buffer); +} + + +/* + * 'CancelJob()' - Cancel the current job... + */ + +void +CancelJob(int sig) /* I - Signal */ +{ + /* + * Tell the main loop to stop... + */ + + (void)sig; + + Canceled = 1; +} + + +/* + * 'OutputLine()' - Output a line of graphics... + */ + +void +OutputLine(ppd_file_t *ppd, /* I - PPD file */ + cups_page_header2_t *header, /* I - Page header */ + int y) /* I - Line number */ +{ + int i; /* Looping var */ + unsigned char *ptr; /* Pointer into buffer */ + unsigned char *compptr; /* Pointer into compression buffer */ + char repeat_char; /* Repeated character */ + int repeat_count; /* Number of repeated characters */ + static const char *hex = "0123456789ABCDEF"; + /* Hex digits */ + + + switch (ModelNumber) + { + case DYMO_3x0 : + /* + * 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) + { + while (Feed > 255) + { + printf("\033f\001%c", 255); + Feed -= 255; + } + + printf("\033f\001%c", Feed); + Feed = 0; + } + + putchar(0x16); + fwrite(Buffer, header->cupsBytesPerLine, 1, stdout); + fflush(stdout); + +#ifdef __sgi + /* + * This hack works around a bug in the IRIX serial port driver when + * run at high baud rates (e.g. 115200 baud)... This results in + * slightly slower label printing, but at least the labels come + * out properly. + */ + + sginap(1); +#endif /* __sgi */ + } + else + Feed ++; + break; + + case ZEBRA_EPL_LINE : + printf("\033g%03d", header->cupsBytesPerLine); + fwrite(Buffer, 1, header->cupsBytesPerLine, stdout); + fflush(stdout); + break; + + case ZEBRA_EPL_PAGE : + if (Buffer[0] || memcmp(Buffer, Buffer + 1, header->cupsBytesPerLine)) + { + printf("GW0,%d,%d,1\n", y, header->cupsBytesPerLine); + for (i = header->cupsBytesPerLine, ptr = Buffer; i > 0; i --, ptr ++) + putchar(~*ptr); + putchar('\n'); + fflush(stdout); + } + break; + + case ZEBRA_ZPL : + /* + * Determine if this row is the same as the previous line. + * If so, output a ':' and return... + */ + + if (LastSet) + { + if (!memcmp(Buffer, LastBuffer, header->cupsBytesPerLine)) + { + putchar(':'); + return; + } + } + + /* + * Convert the line to hex digits... + */ + + for (ptr = Buffer, compptr = CompBuffer, i = header->cupsBytesPerLine; + i > 0; + i --, ptr ++) + { + *compptr++ = hex[*ptr >> 4]; + *compptr++ = hex[*ptr & 15]; + } + + *compptr = '\0'; + + /* + * Run-length compress the graphics... + */ + + for (compptr = CompBuffer + 1, repeat_char = CompBuffer[0], repeat_count = 1; + *compptr; + compptr ++) + if (*compptr == repeat_char) + repeat_count ++; + else + { + ZPLCompress(repeat_char, repeat_count); + repeat_char = *compptr; + repeat_count = 1; + } + + if (repeat_char == '0') + { + /* + * Handle 0's on the end of the line... + */ + + if (repeat_count & 1) + { + repeat_count --; + putchar('0'); + } + + if (repeat_count > 0) + putchar(','); + } + else + ZPLCompress(repeat_char, repeat_count); + + fflush(stdout); + + /* + * Save this line for the next round... + */ + + memcpy(LastBuffer, Buffer, header->cupsBytesPerLine); + LastSet = 1; + break; + + case ZEBRA_CPCL : + if (Buffer[0] || memcmp(Buffer, Buffer + 1, header->cupsBytesPerLine)) + { + printf("CG %u 1 0 %d ", header->cupsBytesPerLine, y); + fwrite(Buffer, 1, header->cupsBytesPerLine, stdout); + puts("\r"); + fflush(stdout); + } + break; + + case INTELLITECH_PCL : + if (Buffer[0] || + memcmp(Buffer, Buffer + 1, header->cupsBytesPerLine - 1)) + { + if (Feed) + { + printf("\033*b%dY", Feed); + Feed = 0; + LastSet = 0; + } + + PCLCompress(Buffer, header->cupsBytesPerLine); + } + else + Feed ++; + break; + } +} + + +/* + * 'PCLCompress()' - Output a PCL (mode 3) compressed line. + */ + +void +PCLCompress(unsigned char *line, /* I - Line to compress */ + int length) /* I - Length of line */ +{ + 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 */ + *seed; /* Seed buffer pointer */ + int count, /* Count of bytes for output */ + offset; /* Offset of bytes for output */ + + + /* + * Do delta-row compression... + */ + + line_ptr = line; + line_end = line + length; + + comp_ptr = CompBuffer; + seed = LastBuffer; + + while (line_ptr < line_end) + { + /* + * Find the next non-matching sequence... + */ + + start = line_ptr; + + if (!LastSet) + { + /* + * The seed buffer is invalid, so do the next 8 bytes, max... + */ + + offset = 0; + + if ((count = line_end - line_ptr) > 8) + count = 8; + + line_ptr += count; + } + else + { + /* + * The seed buffer is valid, so compare against it... + */ + + while (*line_ptr == *seed && + line_ptr < line_end) + { + line_ptr ++; + seed ++; + } + + if (line_ptr == line_end) + break; + + offset = line_ptr - start; + + /* + * Find up to 8 non-matching bytes... + */ + + start = line_ptr; + count = 0; + while (*line_ptr != *seed && + line_ptr < line_end && + count < 8) + { + line_ptr ++; + seed ++; + count ++; + } + } + + /* + * Place mode 3 compression data in the buffer; see HP manuals + * for details... + */ + + if (offset >= 31) + { + /* + * Output multi-byte offset... + */ + + *comp_ptr++ = ((count - 1) << 5) | 31; + + offset -= 31; + while (offset >= 255) + { + *comp_ptr++ = 255; + offset -= 255; + } + + *comp_ptr++ = offset; + } + else + { + /* + * Output single-byte offset... + */ + + *comp_ptr++ = ((count - 1) << 5) | offset; + } + + memcpy(comp_ptr, start, count); + comp_ptr += count; + } + + /* + * Set the length of the data and write it... + */ + + printf("\033*b%dW", (int)(comp_ptr - CompBuffer)); + fwrite(CompBuffer, comp_ptr - CompBuffer, 1, stdout); + + /* + * Save this line as a "seed" buffer for the next... + */ + + memcpy(LastBuffer, line, length); + LastSet = 1; +} + + +/* + * 'ZPLCompress()' - Output a run-length compression sequence. + */ + +void +ZPLCompress(char repeat_char, /* I - Character to repeat */ + int repeat_count) /* I - Number of repeated characters */ +{ + if (repeat_count > 1) + { + /* + * Print as many z's as possible - they are the largest denomination + * representing 400 characters (zC stands for 400 adjacent C's) + */ + + while (repeat_count >= 400) + { + putchar('z'); + repeat_count -= 400; + } + + /* + * Then print 'g' through 'y' as multiples of 20 characters... + */ + + if (repeat_count >= 20) + { + putchar('f' + repeat_count / 20); + repeat_count %= 20; + } + + /* + * Finally, print 'G' through 'Y' as 1 through 19 characters... + */ + + if (repeat_count > 0) + putchar('F' + repeat_count); + } + + /* + * Then the character to be repeated... + */ + + putchar(repeat_char); +} + + +/* + * '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_header2_t header; /* Page header from file */ + int y; /* Current line */ + ppd_file_t *ppd; /* PPD file */ + int num_options; /* Number of options */ + cups_option_t *options; /* 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 < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + _cupsLangPrintf(stderr, + _("Usage: %s job-id user title copies options [file]\n"), + "rastertolabel"); + return (1); + } + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to open raster file - %s\n"), + strerror(errno)); + sleep(1); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Register a signal handler to eject the current page if the + * job is cancelled. + */ + + Canceled = 0; + +#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 */ + + /* + * Open the PPD file and apply options... + */ + + num_options = cupsParseOptions(argv[5], 0, &options); + + if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL) + { + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + } + + /* + * Initialize the print device... + */ + + Setup(ppd); + + /* + * Process pages as needed... + */ + + Page = 0; + + while (cupsRasterReadHeader2(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + if (Canceled) + break; + + Page ++; + + fprintf(stderr, "PAGE: %d 1\n", Page); + + /* + * Start the page... + */ + + StartPage(ppd, &header); + + /* + * Loop for each line on the page... + */ + + for (y = 0; y < header.cupsHeight && !Canceled; y ++) + { + /* + * Let the user know how far we have progressed... + */ + + if (Canceled) + break; + + if ((y & 15) == 0) + _cupsLangPrintf(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; + + /* + * Write it to the printer... + */ + + OutputLine(ppd, &header, y); + } + + /* + * Eject the page... + */ + + EndPage(ppd, &header); + + if (Canceled) + break; + } + + /* + * Close the raster stream... + */ + + cupsRasterClose(ras); + if (fd != 0) + close(fd); + + /* + * Close the PPD file and free the options... + */ + + ppdClose(ppd); + cupsFreeOptions(num_options, options); + + /* + * If no pages were printed, send an error message... + */ + + if (Page == 0) + { + _cupsLangPuts(stderr, _("ERROR: No pages found!\n")); + return (1); + } + else + { + _cupsLangPuts(stderr, _("INFO: Ready to print.\n")); + return (0); + } + + return (Page == 0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/testimage.c b/filter/testimage.c new file mode 100644 index 0000000000..0c57279712 --- /dev/null +++ b/filter/testimage.c @@ -0,0 +1,99 @@ +/* + * "$Id$" + * + * Image library test program for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1993-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Main entry... + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +/* + * 'main()' - Main entry... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_image_t *img; /* Image to print */ + cups_icspace_t primary; /* Primary image colorspace */ + FILE *out; /* Output PPM/PGM file */ + cups_ib_t *line; /* Line from file */ + int y, /* Current line */ + width, /* Width of image */ + height, /* Height of image */ + depth; /* Depth of image */ + + + if (argc != 3) + { + puts("Usage: testimage filename.ext filename.[ppm|pgm]"); + return (1); + } + + if (strstr(argv[2], ".ppm") != NULL) + primary = CUPS_IMAGE_RGB; + else + primary = CUPS_IMAGE_WHITE; + + img = cupsImageOpen(argv[1], primary, CUPS_IMAGE_WHITE, 100, 0, NULL); + + if (!img) + { + perror(argv[1]); + return (1); + } + + out = fopen(argv[2], "wb"); + + if (!out) + { + perror(argv[2]); + cupsImageClose(img); + return (1); + } + + width = cupsImageGetWidth(img); + height = cupsImageGetHeight(img); + depth = cupsImageGetDepth(img); + line = calloc(width, depth); + + fprintf(out, "P%d\n%d\n%d\n255\n", + cupsImageGetColorSpace(img) == CUPS_IMAGE_WHITE ? 5 : 6, + width, height); + + for (y = 0; y < height; y ++) + { + cupsImageGetRow(img, 0, y, width, line); + fwrite(line, width, depth, out); + } + + cupsImageClose(img); + fclose(out); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/testraster.c b/filter/testraster.c new file mode 100644 index 0000000000..9c74952fff --- /dev/null +++ b/filter/testraster.c @@ -0,0 +1,1076 @@ +/* + * "$Id$" + * + * Raster test program routines for CUPS. + * + * Copyright 2007-2011 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + * + * Contents: + * + * main() - Test the raster functions. + * do_ppd_tests() - Test the default option commands in a PPD file. + * do_ps_tests() - Test standard PostScript commands. + * do_ras_file() - Test reading of a raster file. + * do_raster_tests() - Test reading and writing of raster data. + * print_changes() - Print differences in the page header. + */ + +/* + * Include necessary headers... + */ + +#include "image-private.h" +#ifdef WIN32 +# include +#else +# include +# include +#endif /* WIN32 */ + + +/* + * Test PS commands and header... + */ + +static const char *dsc_code = +"[{\n" +"%%BeginFeature: *PageSize Tabloid\n" +"<>setpagedevice\n" +"%%EndFeature\n" +"} stopped cleartomark\n"; +static const char *setpagedevice_code = +"<<" +"/MediaClass(Media Class)" +"/MediaColor((Media Color))" +"/MediaType(Media\\\\Type)" +"/OutputType<416263>" +"/AdvanceDistance 1000" +"/AdvanceMedia 1" +"/Collate false" +"/CutMedia 2" +"/Duplex true" +"/HWResolution[100 200]" +"/InsertSheet true" +"/Jog 3" +"/LeadingEdge 1" +"/ManualFeed true" +"/MediaPosition 8#777" +"/MediaWeight 16#fe01" +"/MirrorPrint true" +"/NegativePrint true" +"/NumCopies 1" +"/Orientation 1" +"/OutputFaceUp true" +"/PageSize[612 792.1]" +"/Separations true" +"/TraySwitch true" +"/Tumble true" +"/cupsMediaType 2" +"/cupsColorOrder 1" +"/cupsColorSpace 1" +"/cupsCompression 1" +"/cupsRowCount 1" +"/cupsRowFeed 1" +"/cupsRowStep 1" +"/cupsBorderlessScalingFactor 1.001" +"/cupsInteger0 1" +"/cupsInteger1 2" +"/cupsInteger2 3" +"/cupsInteger3 4" +"/cupsInteger4 5" +"/cupsInteger5 6" +"/cupsInteger6 7" +"/cupsInteger7 8" +"/cupsInteger8 9" +"/cupsInteger9 10" +"/cupsInteger10 11" +"/cupsInteger11 12" +"/cupsInteger12 13" +"/cupsInteger13 14" +"/cupsInteger14 15" +"/cupsInteger15 16" +"/cupsReal0 1.1" +"/cupsReal1 2.1" +"/cupsReal2 3.1" +"/cupsReal3 4.1" +"/cupsReal4 5.1" +"/cupsReal5 6.1" +"/cupsReal6 7.1" +"/cupsReal7 8.1" +"/cupsReal8 9.1" +"/cupsReal9 10.1" +"/cupsReal10 11.1" +"/cupsReal11 12.1" +"/cupsReal12 13.1" +"/cupsReal13 14.1" +"/cupsReal14 15.1" +"/cupsReal15 16.1" +"/cupsString0(1)" +"/cupsString1(2)" +"/cupsString2(3)" +"/cupsString3(4)" +"/cupsString4(5)" +"/cupsString5(6)" +"/cupsString6(7)" +"/cupsString7(8)" +"/cupsString8(9)" +"/cupsString9(10)" +"/cupsString10(11)" +"/cupsString11(12)" +"/cupsString12(13)" +"/cupsString13(14)" +"/cupsString14(15)" +"/cupsString15(16)" +"/cupsMarkerType(Marker Type)" +"/cupsRenderingIntent(Rendering Intent)" +"/cupsPageSizeName(Letter)" +"/cupsPreferredBitsPerColor 17" +">> setpagedevice"; + +static cups_page_header2_t setpagedevice_header = +{ + "Media Class", /* MediaClass */ + "(Media Color)", /* MediaColor */ + "Media\\Type", /* MediaType */ + "Abc", /* OutputType */ + 1000, /* AdvanceDistance */ + CUPS_ADVANCE_FILE, /* AdvanceMedia */ + CUPS_FALSE, /* Collate */ + CUPS_CUT_JOB, /* CutMedia */ + CUPS_TRUE, /* Duplex */ + { 100, 200 }, /* HWResolution */ + { 0, 0, 0, 0 }, /* ImagingBoundingBox */ + CUPS_TRUE, /* InsertSheet */ + CUPS_JOG_SET, /* Jog */ + CUPS_EDGE_RIGHT, /* LeadingEdge */ + { 0, 0 }, /* Margins */ + CUPS_TRUE, /* ManualFeed */ + 0777, /* MediaPosition */ + 0xfe01, /* MediaWeight */ + CUPS_TRUE, /* MirrorPrint */ + CUPS_TRUE, /* NegativePrint */ + 1, /* NumCopies */ + CUPS_ORIENT_90, /* Orientation */ + CUPS_TRUE, /* OutputFaceUp */ + { 612, 792 }, /* PageSize */ + CUPS_TRUE, /* Separations */ + CUPS_TRUE, /* TraySwitch */ + CUPS_TRUE, /* Tumble */ + 0, /* cupsWidth */ + 0, /* cupsHeight */ + 2, /* cupsMediaType */ + 0, /* cupsBitsPerColor */ + 0, /* cupsBitsPerPixel */ + 0, /* cupsBytesPerLine */ + CUPS_ORDER_BANDED, /* cupsColorOrder */ + CUPS_CSPACE_RGB, /* cupsColorSpace */ + 1, /* cupsCompression */ + 1, /* cupsRowCount */ + 1, /* cupsRowFeed */ + 1, /* cupsRowStep */ + 0, /* cupsNumColors */ + 1.001, /* cupsBorderlessScalingFactor */ + { 612.0, 792.1 }, /* cupsPageSize */ + { 0.0, 0.0, 0.0, 0.0 }, /* cupsImagingBBox */ + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, + /* cupsInteger[16] */ + { 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1, 9.1, 10.1, 11.1, 12.1, 13.1, + 14.1, 15.1, 16.1 }, /* cupsReal[16] */ + { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", + "14", "15", "16" }, /* cupsString[16] */ + "Marker Type", /* cupsMarkerType */ + "Rendering Intent", /* cupsRenderingIntent */ + "Letter" /* cupsPageSizeName */ +}; + + +/* + * Local functions... + */ + +static int do_ppd_tests(const char *filename, int num_options, + cups_option_t *options); +static int do_ps_tests(void); +static int do_ras_file(const char *filename); +static int do_raster_tests(cups_mode_t mode); +static void print_changes(cups_page_header2_t *header, + cups_page_header2_t *expected); + + +/* + * 'main()' - Test the raster functions. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int errors; /* Number of errors */ + const char *ext; /* Filename extension */ + + + if (argc == 1) + { + errors = do_ps_tests(); + errors += do_raster_tests(CUPS_RASTER_WRITE); + errors += do_raster_tests(CUPS_RASTER_WRITE_COMPRESSED); + } + else + { + int i; /* Looping var */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + + + for (errors = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++) + { + if (argv[i][0] == '-') + { + if (argv[i][1] == 'o') + { + if (argv[i][2]) + num_options = cupsParseOptions(argv[i] + 2, num_options, &options); + else + { + i ++; + if (i < argc) + num_options = cupsParseOptions(argv[i], num_options, &options); + else + { + puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); + puts(" testraster [filename.ras ...]"); + return (1); + } + } + } + else + { + puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); + puts(" testraster [filename.ras ...]"); + return (1); + } + } + else if ((ext = strrchr(argv[i], '.')) != NULL) + { + if (!strcmp(ext, ".ppd")) + errors += do_ppd_tests(argv[i], num_options, options); + else + errors += do_ras_file(argv[i]); + } + else + { + puts("Usage: testraster [-o name=value ...] [filename.ppd ...]"); + puts(" testraster [filename.ras ...]"); + return (1); + } + } + + cupsFreeOptions(num_options, options); + } + + return (errors); +} + + +/* + * 'do_ppd_tests()' - Test the default option commands in a PPD file. + */ + +static int /* O - Number of errors */ +do_ppd_tests(const char *filename, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + ppd_file_t *ppd; /* PPD file data */ + cups_page_header2_t header; /* Page header */ + + + printf("\"%s\": ", filename); + fflush(stdout); + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + ppd_status_t status; /* Status from PPD loader */ + int line; /* Line number containing error */ + + + status = ppdLastError(&line); + + puts("FAIL (bad PPD file)"); + printf(" %s on line %d\n", ppdErrorString(status), line); + + return (1); + } + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + + return (1); + } + else + { + puts("PASS"); + + return (0); + } +} + + +/* + * 'do_ps_tests()' - Test standard PostScript commands. + */ + +static int +do_ps_tests(void) +{ + cups_page_header2_t header; /* Page header */ + int preferred_bits; /* Preferred bits */ + int errors = 0; /* Number of errors */ + + + /* + * Test PS exec code... + */ + + fputs("_cupsRasterExecPS(\"setpagedevice\"): ", stdout); + fflush(stdout); + + memset(&header, 0, sizeof(header)); + header.Collate = CUPS_TRUE; + preferred_bits = 0; + + if (_cupsRasterExecPS(&header, &preferred_bits, setpagedevice_code)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (preferred_bits != 17 || + memcmp(&header, &setpagedevice_header, sizeof(header))) + { + puts("FAIL (bad header)"); + + if (preferred_bits != 17) + printf(" cupsPreferredBitsPerColor %d, expected 17\n", + preferred_bits); + + print_changes(&setpagedevice_header, &header); + errors ++; + } + else + puts("PASS"); + + fputs("_cupsRasterExecPS(\"roll\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, + "792 612 0 0 0\n" + "pop pop pop\n" + "<>" + "setpagedevice\n")) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (header.PageSize[0] != 792 || header.PageSize[1] != 612) + { + printf("FAIL (PageSize [%d %d], expected [792 612])\n", header.PageSize[0], + header.PageSize[1]); + errors ++; + } + else + puts("PASS"); + + fputs("_cupsRasterExecPS(\"dup index\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, + "true false dup\n" + "<>setpagedevice\n" + "pop pop pop")) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else + { + if (!header.Collate) + { + printf("FAIL (Collate false, expected true)\n"); + errors ++; + } + + if (header.Duplex) + { + printf("FAIL (Duplex true, expected false)\n"); + errors ++; + } + + if (header.Tumble) + { + printf("FAIL (Tumble true, expected false)\n"); + errors ++; + } + + if(header.Collate && !header.Duplex && !header.Tumble) + puts("PASS"); + } + + fputs("_cupsRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout); + fflush(stdout); + + if (_cupsRasterExecPS(&header, &preferred_bits, dsc_code)) + { + puts("FAIL (error from function)"); + puts(cupsRasterErrorString()); + errors ++; + } + else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224) + { + printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n", + header.PageSize[0], header.PageSize[1]); + errors ++; + } + else + puts("PASS"); + + return (errors); +} + + +/* + * 'do_ras_file()' - Test reading of a raster file. + */ + +static int /* O - Number of errors */ +do_ras_file(const char *filename) /* I - Filename */ +{ + unsigned y; /* Looping vars */ + int fd; /* File descriptor */ + cups_raster_t *ras; /* Raster stream */ + cups_page_header2_t header; /* Page header */ + unsigned char *data; /* Raster data */ + int errors = 0; /* Number of errors */ + unsigned pages = 0; /* Number of pages */ + + + if ((fd = open(filename, O_RDONLY)) < 0) + { + printf("%s: %s\n", filename, strerror(errno)); + return (1); + } + + if ((ras = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL) + { + printf("%s: cupsRasterOpen failed.\n", filename); + close(fd); + return (1); + } + + printf("%s:\n", filename); + + while (cupsRasterReadHeader2(ras, &header)) + { + pages ++; + data = malloc(header.cupsBytesPerLine); + + printf(" Page %u: %ux%ux%u@%ux%udpi", pages, + header.cupsWidth, header.cupsHeight, header.cupsBitsPerPixel, + header.HWResolution[0], header.HWResolution[1]); + fflush(stdout); + + for (y = 0; y < header.cupsHeight; y ++) + if (cupsRasterReadPixels(ras, data, header.cupsBytesPerLine) < + header.cupsBytesPerLine) + break; + + if (y < header.cupsHeight) + printf(" ERROR AT LINE %d\n", y); + else + putchar('\n'); + + free(data); + } + + cupsRasterClose(ras); + close(fd); + + return (errors); +} + + +/* + * 'do_raster_tests()' - Test reading and writing of raster data. + */ + +static int /* O - Number of errors */ +do_raster_tests(cups_mode_t mode) /* O - Write mode */ +{ + int page, x, y; /* Looping vars */ + FILE *fp; /* Raster file */ + cups_raster_t *r; /* Raster stream */ + cups_page_header2_t header, /* Page header */ + expected; /* Expected page header */ + unsigned char data[2048]; /* Raster data */ + int errors = 0; /* Number of errors */ + + + /* + * Test writing... + */ + + printf("cupsRasterOpen(%s): ", + mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE" : + "CUPS_RASTER_WRITE_COMPRESSED"); + fflush(stdout); + + if ((fp = fopen("test.raster", "wb")) == NULL) + { + printf("FAIL (%s)\n", strerror(errno)); + return (1); + } + + if ((r = cupsRasterOpen(fileno(fp), mode)) == NULL) + { + printf("FAIL (%s)\n", strerror(errno)); + fclose(fp); + return (1); + } + + puts("PASS"); + + for (page = 0; page < 4; page ++) + { + memset(&header, 0, sizeof(header)); + header.cupsWidth = 256; + header.cupsHeight = 256; + header.cupsBytesPerLine = 256; + + if (page & 1) + { + header.cupsBytesPerLine *= 2; + header.cupsColorSpace = CUPS_CSPACE_CMYK; + header.cupsColorOrder = CUPS_ORDER_CHUNKED; + header.cupsNumColors = 4; + } + else + { + header.cupsColorSpace = CUPS_CSPACE_K; + header.cupsColorOrder = CUPS_ORDER_BANDED; + header.cupsNumColors = 1; + } + + if (page & 2) + { + header.cupsBytesPerLine *= 2; + header.cupsBitsPerColor = 16; + header.cupsBitsPerPixel = (page & 1) ? 64 : 16; + } + else + { + header.cupsBitsPerColor = 8; + header.cupsBitsPerPixel = (page & 1) ? 32 : 8; + } + + if (cupsRasterWriteHeader2(r, &header)) + puts("cupsRasterWriteHeader2: PASS"); + else + { + puts("cupsRasterWriteHeader2: FAIL"); + errors ++; + } + + fputs("cupsRasterWritePixels: ", stdout); + fflush(stdout); + + memset(data, 0, header.cupsBytesPerLine); + for (y = 0; y < 64; y ++) + if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) + break; + + if (y < 64) + { + puts("FAIL"); + errors ++; + } + else + { + for (x = 0; x < header.cupsBytesPerLine; x ++) + data[x] = x; + + for (y = 0; y < 64; y ++) + if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) + break; + + if (y < 64) + { + puts("FAIL"); + errors ++; + } + else + { + memset(data, 255, header.cupsBytesPerLine); + for (y = 0; y < 64; y ++) + if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) + break; + + if (y < 64) + { + puts("FAIL"); + errors ++; + } + else + { + for (x = 0; x < header.cupsBytesPerLine; x ++) + data[x] = x / 4; + + for (y = 0; y < 64; y ++) + if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine)) + break; + + if (y < 64) + { + puts("FAIL"); + errors ++; + } + else + puts("PASS"); + } + } + } + } + + cupsRasterClose(r); + fclose(fp); + + /* + * Test reading... + */ + + fputs("cupsRasterOpen(CUPS_RASTER_READ): ", stdout); + fflush(stdout); + + if ((fp = fopen("test.raster", "rb")) == NULL) + { + printf("FAIL (%s)\n", strerror(errno)); + return (1); + } + + if ((r = cupsRasterOpen(fileno(fp), CUPS_RASTER_READ)) == NULL) + { + printf("FAIL (%s)\n", strerror(errno)); + fclose(fp); + return (1); + } + + puts("PASS"); + + for (page = 0; page < 4; page ++) + { + memset(&expected, 0, sizeof(expected)); + expected.cupsWidth = 256; + expected.cupsHeight = 256; + expected.cupsBytesPerLine = 256; + + if (page & 1) + { + expected.cupsBytesPerLine *= 2; + expected.cupsColorSpace = CUPS_CSPACE_CMYK; + expected.cupsColorOrder = CUPS_ORDER_CHUNKED; + expected.cupsNumColors = 4; + } + else + { + expected.cupsColorSpace = CUPS_CSPACE_K; + expected.cupsColorOrder = CUPS_ORDER_BANDED; + expected.cupsNumColors = 1; + } + + if (page & 2) + { + expected.cupsBytesPerLine *= 2; + expected.cupsBitsPerColor = 16; + expected.cupsBitsPerPixel = (page & 1) ? 64 : 16; + } + else + { + expected.cupsBitsPerColor = 8; + expected.cupsBitsPerPixel = (page & 1) ? 32 : 8; + } + + fputs("cupsRasterReadHeader2: ", stdout); + fflush(stdout); + + if (!cupsRasterReadHeader2(r, &header)) + { + puts("FAIL (read error)"); + errors ++; + break; + } + + if (memcmp(&header, &expected, sizeof(header))) + { + puts("FAIL (bad page header)"); + errors ++; + print_changes(&header, &expected); + } + + fputs("cupsRasterReadPixels: ", stdout); + fflush(stdout); + + for (y = 0; y < 64; y ++) + { + if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) + { + puts("FAIL (read error)"); + errors ++; + break; + } + + if (data[0] != 0 || memcmp(data, data + 1, header.cupsBytesPerLine - 1)) + { + printf("FAIL (raster line %d corrupt)\n", y); + errors ++; + break; + } + } + + if (y == 64) + { + for (y = 0; y < 64; y ++) + { + if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) + { + puts("FAIL (read error)"); + errors ++; + break; + } + + for (x = 0; x < header.cupsBytesPerLine; x ++) + if (data[x] != (x & 255)) + break; + + if (x < header.cupsBytesPerLine) + { + printf("FAIL (raster line %d corrupt)\n", y + 64); + errors ++; + break; + } + } + + if (y == 64) + { + for (y = 0; y < 64; y ++) + { + if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) + { + puts("FAIL (read error)"); + errors ++; + break; + } + + if (data[0] != 255 || memcmp(data, data + 1, header.cupsBytesPerLine - 1)) + { + printf("fail (raster line %d corrupt)\n", y + 128); + errors ++; + break; + } + } + + if (y == 64) + { + for (y = 0; y < 64; y ++) + { + if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine)) + { + puts("FAIL (read error)"); + errors ++; + break; + } + + for (x = 0; x < header.cupsBytesPerLine; x ++) + if (data[x] != ((x / 4) & 255)) + break; + + if (x < header.cupsBytesPerLine) + { + printf("FAIL (raster line %d corrupt)\n", y + 192); + errors ++; + break; + } + } + + if (y == 64) + puts("PASS"); + } + } + } + } + + cupsRasterClose(r); + fclose(fp); + + return (errors); +} + + +/* + * 'print_changes()' - Print differences in the page header. + */ + +static void +print_changes( + cups_page_header2_t *header, /* I - Actual page header */ + cups_page_header2_t *expected) /* I - Expected page header */ +{ + int i; /* Looping var */ + + + if (strcmp(header->MediaClass, expected->MediaClass)) + printf(" MediaClass (%s), expected (%s)\n", header->MediaClass, + expected->MediaClass); + + if (strcmp(header->MediaColor, expected->MediaColor)) + printf(" MediaColor (%s), expected (%s)\n", header->MediaColor, + expected->MediaColor); + + if (strcmp(header->MediaType, expected->MediaType)) + printf(" MediaType (%s), expected (%s)\n", header->MediaType, + expected->MediaType); + + if (strcmp(header->OutputType, expected->OutputType)) + printf(" OutputType (%s), expected (%s)\n", header->OutputType, + expected->OutputType); + + if (header->AdvanceDistance != expected->AdvanceDistance) + printf(" AdvanceDistance %d, expected %d\n", header->AdvanceDistance, + expected->AdvanceDistance); + + if (header->AdvanceMedia != expected->AdvanceMedia) + printf(" AdvanceMedia %d, expected %d\n", header->AdvanceMedia, + expected->AdvanceMedia); + + if (header->Collate != expected->Collate) + printf(" Collate %d, expected %d\n", header->Collate, + expected->Collate); + + if (header->CutMedia != expected->CutMedia) + printf(" CutMedia %d, expected %d\n", header->CutMedia, + expected->CutMedia); + + if (header->Duplex != expected->Duplex) + printf(" Duplex %d, expected %d\n", header->Duplex, + expected->Duplex); + + if (header->HWResolution[0] != expected->HWResolution[0] || + header->HWResolution[1] != expected->HWResolution[1]) + printf(" HWResolution [%d %d], expected [%d %d]\n", + header->HWResolution[0], header->HWResolution[1], + expected->HWResolution[0], expected->HWResolution[1]); + + if (memcmp(header->ImagingBoundingBox, expected->ImagingBoundingBox, + sizeof(header->ImagingBoundingBox))) + printf(" ImagingBoundingBox [%d %d %d %d], expected [%d %d %d %d]\n", + header->ImagingBoundingBox[0], + header->ImagingBoundingBox[1], + header->ImagingBoundingBox[2], + header->ImagingBoundingBox[3], + expected->ImagingBoundingBox[0], + expected->ImagingBoundingBox[1], + expected->ImagingBoundingBox[2], + expected->ImagingBoundingBox[3]); + + if (header->InsertSheet != expected->InsertSheet) + printf(" InsertSheet %d, expected %d\n", header->InsertSheet, + expected->InsertSheet); + + if (header->Jog != expected->Jog) + printf(" Jog %d, expected %d\n", header->Jog, + expected->Jog); + + if (header->LeadingEdge != expected->LeadingEdge) + printf(" LeadingEdge %d, expected %d\n", header->LeadingEdge, + expected->LeadingEdge); + + if (header->Margins[0] != expected->Margins[0] || + header->Margins[1] != expected->Margins[1]) + printf(" Margins [%d %d], expected [%d %d]\n", + header->Margins[0], header->Margins[1], + expected->Margins[0], expected->Margins[1]); + + if (header->ManualFeed != expected->ManualFeed) + printf(" ManualFeed %d, expected %d\n", header->ManualFeed, + expected->ManualFeed); + + if (header->MediaPosition != expected->MediaPosition) + printf(" MediaPosition %d, expected %d\n", header->MediaPosition, + expected->MediaPosition); + + if (header->MediaWeight != expected->MediaWeight) + printf(" MediaWeight %d, expected %d\n", header->MediaWeight, + expected->MediaWeight); + + if (header->MirrorPrint != expected->MirrorPrint) + printf(" MirrorPrint %d, expected %d\n", header->MirrorPrint, + expected->MirrorPrint); + + if (header->NegativePrint != expected->NegativePrint) + printf(" NegativePrint %d, expected %d\n", header->NegativePrint, + expected->NegativePrint); + + if (header->NumCopies != expected->NumCopies) + printf(" NumCopies %d, expected %d\n", header->NumCopies, + expected->NumCopies); + + if (header->Orientation != expected->Orientation) + printf(" Orientation %d, expected %d\n", header->Orientation, + expected->Orientation); + + if (header->OutputFaceUp != expected->OutputFaceUp) + printf(" OutputFaceUp %d, expected %d\n", header->OutputFaceUp, + expected->OutputFaceUp); + + if (header->PageSize[0] != expected->PageSize[0] || + header->PageSize[1] != expected->PageSize[1]) + printf(" PageSize [%d %d], expected [%d %d]\n", + header->PageSize[0], header->PageSize[1], + expected->PageSize[0], expected->PageSize[1]); + + if (header->Separations != expected->Separations) + printf(" Separations %d, expected %d\n", header->Separations, + expected->Separations); + + if (header->TraySwitch != expected->TraySwitch) + printf(" TraySwitch %d, expected %d\n", header->TraySwitch, + expected->TraySwitch); + + if (header->Tumble != expected->Tumble) + printf(" Tumble %d, expected %d\n", header->Tumble, + expected->Tumble); + + if (header->cupsWidth != expected->cupsWidth) + printf(" cupsWidth %d, expected %d\n", header->cupsWidth, + expected->cupsWidth); + + if (header->cupsHeight != expected->cupsHeight) + printf(" cupsHeight %d, expected %d\n", header->cupsHeight, + expected->cupsHeight); + + if (header->cupsMediaType != expected->cupsMediaType) + printf(" cupsMediaType %d, expected %d\n", header->cupsMediaType, + expected->cupsMediaType); + + if (header->cupsBitsPerColor != expected->cupsBitsPerColor) + printf(" cupsBitsPerColor %d, expected %d\n", header->cupsBitsPerColor, + expected->cupsBitsPerColor); + + if (header->cupsBitsPerPixel != expected->cupsBitsPerPixel) + printf(" cupsBitsPerPixel %d, expected %d\n", header->cupsBitsPerPixel, + expected->cupsBitsPerPixel); + + if (header->cupsBytesPerLine != expected->cupsBytesPerLine) + printf(" cupsBytesPerLine %d, expected %d\n", header->cupsBytesPerLine, + expected->cupsBytesPerLine); + + if (header->cupsColorOrder != expected->cupsColorOrder) + printf(" cupsColorOrder %d, expected %d\n", header->cupsColorOrder, + expected->cupsColorOrder); + + if (header->cupsColorSpace != expected->cupsColorSpace) + printf(" cupsColorSpace %d, expected %d\n", header->cupsColorSpace, + expected->cupsColorSpace); + + if (header->cupsCompression != expected->cupsCompression) + printf(" cupsCompression %d, expected %d\n", header->cupsCompression, + expected->cupsCompression); + + if (header->cupsRowCount != expected->cupsRowCount) + printf(" cupsRowCount %d, expected %d\n", header->cupsRowCount, + expected->cupsRowCount); + + if (header->cupsRowFeed != expected->cupsRowFeed) + printf(" cupsRowFeed %d, expected %d\n", header->cupsRowFeed, + expected->cupsRowFeed); + + if (header->cupsRowStep != expected->cupsRowStep) + printf(" cupsRowStep %d, expected %d\n", header->cupsRowStep, + expected->cupsRowStep); + + if (header->cupsNumColors != expected->cupsNumColors) + printf(" cupsNumColors %d, expected %d\n", header->cupsNumColors, + expected->cupsNumColors); + + if (header->cupsBorderlessScalingFactor != + expected->cupsBorderlessScalingFactor) + printf(" cupsBorderlessScalingFactor %g, expected %g\n", + header->cupsBorderlessScalingFactor, + expected->cupsBorderlessScalingFactor); + + if (header->cupsPageSize[0] != expected->cupsPageSize[0] || + header->cupsPageSize[1] != expected->cupsPageSize[1]) + printf(" cupsPageSize [%g %g], expected [%g %g]\n", + header->cupsPageSize[0], header->cupsPageSize[1], + expected->cupsPageSize[0], expected->cupsPageSize[1]); + + if (header->cupsImagingBBox[0] != expected->cupsImagingBBox[0] || + header->cupsImagingBBox[1] != expected->cupsImagingBBox[1] || + header->cupsImagingBBox[2] != expected->cupsImagingBBox[2] || + header->cupsImagingBBox[3] != expected->cupsImagingBBox[3]) + printf(" cupsImagingBBox [%g %g %g %g], expected [%g %g %g %g]\n", + header->cupsImagingBBox[0], header->cupsImagingBBox[1], + header->cupsImagingBBox[2], header->cupsImagingBBox[3], + expected->cupsImagingBBox[0], expected->cupsImagingBBox[1], + expected->cupsImagingBBox[2], expected->cupsImagingBBox[3]); + + for (i = 0; i < 16; i ++) + if (header->cupsInteger[i] != expected->cupsInteger[i]) + printf(" cupsInteger%d %d, expected %d\n", i, header->cupsInteger[i], + expected->cupsInteger[i]); + + for (i = 0; i < 16; i ++) + if (header->cupsReal[i] != expected->cupsReal[i]) + printf(" cupsReal%d %g, expected %g\n", i, header->cupsReal[i], + expected->cupsReal[i]); + + for (i = 0; i < 16; i ++) + if (strcmp(header->cupsString[i], expected->cupsString[i])) + printf(" cupsString%d (%s), expected (%s)\n", i, + header->cupsString[i], expected->cupsString[i]); + + if (strcmp(header->cupsMarkerType, expected->cupsMarkerType)) + printf(" cupsMarkerType (%s), expected (%s)\n", header->cupsMarkerType, + expected->cupsMarkerType); + + if (strcmp(header->cupsRenderingIntent, expected->cupsRenderingIntent)) + printf(" cupsRenderingIntent (%s), expected (%s)\n", + header->cupsRenderingIntent, + expected->cupsRenderingIntent); + + if (strcmp(header->cupsPageSizeName, expected->cupsPageSizeName)) + printf(" cupsPageSizeName (%s), expected (%s)\n", + header->cupsPageSizeName, + expected->cupsPageSizeName); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/textcommon.c b/filter/textcommon.c new file mode 100644 index 0000000000..bab3bbc52e --- /dev/null +++ b/filter/textcommon.c @@ -0,0 +1,1211 @@ +/* + * "$Id$" + * + * Common text filter routines for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2008 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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" +#include + + +/* + * 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 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", + "reinterpret_cast", + "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) + { + _cupsLangPrintf(stderr, + _("Usage: %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("DEBUG: 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") && strcasecmp(val, "off") && + strcasecmp(val, "false")) + { + 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_PLAIN; + NumKeywords = 0; + Keywords = NULL; + } + 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-csource") == 0) + { + PrettyPrint = PRETTY_CODE; + NumKeywords = sizeof(code_keywords) / sizeof(code_keywords[0]); + Keywords = code_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_PLAIN; + NumKeywords = 0; + Keywords = NULL; + } + } + + ppd = SetCommonOptions(num_options, options, 1); + + if ((val = cupsGetOption("wrap", num_options, options)) == NULL) + WrapLines = 1; + else + WrapLines = !strcasecmp(val, "true") || !strcasecmp(val, "on") || + !strcasecmp(val, "yes"); + + if ((val = cupsGetOption("columns", num_options, options)) != NULL) + { + PageColumns = atoi(val); + + if (PageColumns < 1) + { + _cupsLangPrintf(stderr, _("ERROR: Bad columns value %d!\n"), PageColumns); + return (1); + } + } + + if ((val = cupsGetOption("cpi", num_options, options)) != NULL) + { + CharsPerInch = atof(val); + + if (CharsPerInch <= 0.0) + { + _cupsLangPrintf(stderr, _("ERROR: Bad cpi value %f!\n"), CharsPerInch); + return (1); + } + } + + if ((val = cupsGetOption("lpi", num_options, options)) != NULL) + { + LinesPerInch = atof(val); + + if (LinesPerInch <= 0.0) + { + _cupsLangPrintf(stderr, _("ERROR: Bad lpi value %f!\n"), LinesPerInch); + return (1); + } + } + + 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; + + attr &= ~ATTR_BOLD; + 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 > PRETTY_PLAIN) + { + /* + * Do highlighting of C/C++ keywords, preprocessor commands, + * and comments... + */ + + if (ch == ' ' && (attr & ATTR_BOLD)) + { + /* + * Stop bolding preprocessor command... + */ + + attr &= ~ATTR_BOLD; + } + else if (!(isalnum(ch & 255) || 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 & 255) || 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) /* 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 0000000000..1c27af32f2 --- /dev/null +++ b/filter/textcommon.h @@ -0,0 +1,114 @@ +/* + * "$Id$" + * + * Common text filter definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 2007 by Apple Inc. + * Copyright 1997-2005 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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_PLAIN 1 +#define PRETTY_CODE 2 +#define PRETTY_SHELL 3 +#define PRETTY_PERL 4 +#define PRETTY_HTML 5 + + +/* + * 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 0000000000..5b27e81a60 --- /dev/null +++ b/filter/texttops.c @@ -0,0 +1,1158 @@ +/* + * "$Id$" + * + * Text to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 2007-2010 by Apple Inc. + * Copyright 1993-2007 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "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" +#include + + +/* + * 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; + + if (SizeColumns <= 0 || SizeColumns > 32767 || + SizeLines <= 0 || SizeLines > 32767) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page!\n"), + SizeColumns, SizeLines); + exit(1); + } + + if ((Page = calloc(sizeof(lchar_t *), SizeLines)) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page!\n"), + SizeColumns, SizeLines); + exit(1); + } + + if ((Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines)) == NULL) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to print %dx%d text page!\n"), + SizeColumns, SizeLines); + exit(1); + } + + 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; + + if (ColumnWidth <= 0) + { + _cupsLangPrintf(stderr, _("ERROR: Unable to print %d text columns!\n"), + PageColumns); + exit(1); + } + + /* + * Output the DSC header... + */ + + curtime = time(NULL); + curtm = localtime(&curtime); + strftime(curdate, sizeof(curdate), "%c", curtm); + + puts("%!PS-Adobe-3.0"); + printf("%%%%BoundingBox: 0 0 %.0f %.0f\n", PageWidth, PageLength); + printf("%%cupsRotation: %d\n", (Orientation & 3) * 90); + puts("%%Creator: texttops/" CUPS_SVERSION); + printf("%%%%CreationDate: %s\n", curdate); + WriteTextComment("Title", title); + WriteTextComment("For", 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 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 & 255); lineptr ++); /* Skip whitespace */ + + if (strcmp(lineptr, "utf8") == 0) + { + /* + * UTF-8 (Unicode) text... + */ + + 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 & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *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 & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *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 & 255)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr & 255) && *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 = PrettyPrint ? 2 : 1; 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 = PrettyPrint ? 2 : 1; 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"); + if (NumFonts > 1) + { + /* + * Convert a number to double-byte chars... + */ + + 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("\tgsave"); + 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; 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 & 255) && !isspace(line->ch & 255)) + break; + + col ++; + line ++; + } + + for (i = 1; start < line; i ++, start ++) + if (!isspace(start->ch & 255)) + 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) + 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/fonts/Makefile b/fonts/Makefile new file mode 100644 index 0000000000..6820d17715 --- /dev/null +++ b/fonts/Makefile @@ -0,0 +1,118 @@ +# +# "$Id$" +# +# Fonts makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1993-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + +# +# Font files... +# + +FONTS = \ + Monospace \ + Monospace-Bold \ + Monospace-BoldOblique \ + Monospace-Oblique + + +# +# Make everything... +# + +all: + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Dummy depend target... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: + $(INSTALL_DIR) -m 755 $(DATADIR)/fonts + if test "x$(BANNERTOPS)" != x -o "x$(TEXTTOPS)" != x; then \ + for file in $(FONTS); do \ + $(INSTALL_DATA) $$file $(DATADIR)/fonts; \ + done \ + fi + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: + for file in $(FONTS); do \ + $(RM) $(DATADIR)/fonts/$$file; \ + done + $(RMDIR) $(DATADIR)/fonts + + +# +# End of "$Id$". +# diff --git a/fonts/Monospace b/fonts/Monospace new file mode 100644 index 0000000000..2512b85fac --- /dev/null +++ b/fonts/Monospace @@ -0,0 +1,2744 @@ +%!PS-AdobeFont-1.0: Monospace 1.15 +%%DocumentSuppliedResources: font Monospace +%%Title: Monospace +%Version: 1.15 +%%CreationDate: Thu Oct 27 10:50:21 2005 +%%Creator: mike +%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +%Copyright: DejaVu changes are in public domain + +% Generated by FontForge 20051018 (http://fontforge.sf.net/) +%%EndComments + +FontDirectory/Monospace known{/Monospace findfont dup/UniqueID known{dup +/UniqueID get 4166841 eq exch/FontType get 1 eq and}{pop false}ifelse +{save true}{false}ifelse}{false}ifelse +11 dict begin +/FontType 1 def +/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def +/FontName /Monospace def +/FontBBox {-109 -1034 1342 2133 }readonly def +/UniqueID 4166841 def +/PaintType 0 def +/FontInfo 11 dict dup begin + /version (1.15) readonly def + /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def +% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +% DejaVu changes are in public domain + /FullName (Monospace) readonly def + /FamilyName (Monospace) readonly def + /Weight (Book) readonly def + /FSType 0 def + /ItalicAngle 0 def + /isFixedPitch true def + /UnderlinePosition -213 def + /UnderlineThickness 141 def + /ascent 1556 def +end readonly def +/Encoding 256 array + 0 1 255 { 1 index exch /.notdef put} for +dup 32/space put +dup 33/exclam put +dup 34/quotedbl put +dup 35/numbersign put +dup 36/dollar put +dup 37/percent put +dup 38/ampersand put +dup 39/quotesingle put +dup 40/parenleft put +dup 41/parenright put +dup 42/asterisk put +dup 43/plus put +dup 44/comma put +dup 45/hyphen 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/at put +dup 65/A put +dup 66/B put +dup 67/C put +dup 68/D put +dup 69/E put +dup 70/F put +dup 71/G put +dup 72/H put +dup 73/I put +dup 74/J put +dup 75/K put +dup 76/L put +dup 77/M put +dup 78/N put +dup 79/O put +dup 80/P put +dup 81/Q put +dup 82/R put +dup 83/S put +dup 84/T put +dup 85/U put +dup 86/V put +dup 87/W put +dup 88/X put +dup 89/Y put +dup 90/Z put +dup 91/bracketleft put +dup 92/backslash put +dup 93/bracketright put +dup 94/asciicircum put +dup 95/underscore put +dup 96/grave put +dup 97/a put +dup 98/b put +dup 99/c put +dup 100/d put +dup 101/e put +dup 102/f put +dup 103/g put +dup 104/h put +dup 105/i put +dup 106/j put +dup 107/k put +dup 108/l put +dup 109/m put +dup 110/n put +dup 111/o put +dup 112/p put +dup 113/q put +dup 114/r put +dup 115/s put +dup 116/t put +dup 117/u put +dup 118/v put +dup 119/w put +dup 120/x put +dup 121/y put +dup 122/z put +dup 123/braceleft put +dup 124/bar put +dup 125/braceright put +dup 126/asciitilde put +dup 160/nonbreakingspace put +dup 161/exclamdown put +dup 162/cent put +dup 163/sterling put +dup 164/currency put +dup 165/yen put +dup 166/brokenbar put +dup 167/section put +dup 168/dieresis put +dup 169/copyright put +dup 170/ordfeminine put +dup 171/guillemotleft put +dup 172/logicalnot put +dup 173/sfthyphen put +dup 174/registered put +dup 175/macron put +dup 176/degree put +dup 177/plusminus put +dup 178/twosuperior put +dup 179/threesuperior put +dup 180/acute put +dup 181/mu put +dup 182/paragraph put +dup 183/periodcentered put +dup 184/cedilla put +dup 185/onesuperior put +dup 186/ordmasculine put +dup 187/guillemotright put +dup 188/onequarter put +dup 189/onehalf put +dup 190/threequarters put +dup 191/questiondown put +dup 192/Agrave put +dup 193/Aacute put +dup 194/Acircumflex put +dup 195/Atilde put +dup 196/Adieresis put +dup 197/Aring put +dup 198/AE put +dup 199/Ccedilla put +dup 200/Egrave put +dup 201/Eacute put +dup 202/Ecircumflex put +dup 203/Edieresis put +dup 204/Igrave put +dup 205/Iacute put +dup 206/Icircumflex put +dup 207/Idieresis put +dup 208/Eth put +dup 209/Ntilde put +dup 210/Ograve put +dup 211/Oacute put +dup 212/Ocircumflex put +dup 213/Otilde put +dup 214/Odieresis put +dup 215/multiply put +dup 216/Oslash put +dup 217/Ugrave put +dup 218/Uacute put +dup 219/Ucircumflex put +dup 220/Udieresis put +dup 221/Yacute put +dup 222/Thorn put +dup 223/germandbls put +dup 224/agrave put +dup 225/aacute put +dup 226/acircumflex put +dup 227/atilde put +dup 228/adieresis put +dup 229/aring put +dup 230/ae put +dup 231/ccedilla put +dup 232/egrave put +dup 233/eacute put +dup 234/ecircumflex put +dup 235/edieresis put +dup 236/igrave put +dup 237/iacute put +dup 238/icircumflex put +dup 239/idieresis put +dup 240/eth put +dup 241/ntilde put +dup 242/ograve put +dup 243/oacute put +dup 244/ocircumflex put +dup 245/otilde put +dup 246/odieresis put +dup 247/divide put +dup 248/oslash put +dup 249/ugrave put +dup 250/uacute put +dup 251/ucircumflex put +dup 252/udieresis put +dup 253/yacute put +dup 254/thorn put +dup 255/ydieresis put +readonly def +currentdict end +currentfile eexec +17F6ABC0BD4E5B049FA8ED1415B73797205424D2E47FC5DF8590627DC99082760E8B3E17 +0C18AF49528FA9DB386CE480B471EC8797784FB466233A879056FB46290A8F49442020C3 +E00AF7FDB602BAC1C4F8636E32FDDB936FC70C567B075E18878EA286E1D24CC1E14B50B7 +DCDD17FD5295A3F44E0DA80366E61263EA00234FA095739BDE371FED9A24338A8CAB0F53 +5964F1515D62E477A2F1C2BEEA2DF171E3962F0DE53E2763D7DE117F6B5328691D69C4D8 +D071D89F6AB4731DFE0A1FCC4F32351620B2B48E12AEAD940270EF4990B511E7D052C3A4 +2AAEF583BD41B85778646ED2E9A86A73A1089F502672860E7A7A9CFC2F7B2E221C6C9080 +7B7E7B4218C9B10B574C73E195D6C97D1EDC5FA365221BD82148D1ADEA7F235FFC14AD5A +47E11207058A7A9059FF373F66FEA5A9113CE0BCAF084AAE135556FE84AA4C5A9070BD77 +E7D39A94BA711FDFE442366E9F27F14EF80FFF2C342189C2E28D9FC541F049944C1CF913 +2A014935BF47B42C4E0847A335B4E6CE5016C1B8FC0C3E153C07ADF3C0B00CE001DDF36F +DE0CC04A25FA1635707299ACB277BFF663DE9558664D1DE90465FBC67BAEA7B1851FCC85 +7364E4BB97470017B40C4D54096C4AE2469A5D037963C7F009DD25A32C20487FF1F1F0A0 +124BF0B10891BC1FBDC65F9192B7236A694E1CFD1388CD27288222AE80032683C803533D +E6C39DF03BFA02DB5F35C1B99531836F38F6F04192AE3228C0F19841842F5C907529175B +6BF7B4A8D7B3F27FB39A58B7D3CF11A306701B548C3DC231102A45496B5535C96FBF0412 +004ED0658F28F845F4B0C5F02A680737A738A559E8E6BFCA7584C0A9FAB1B5D3C8995508 +856337933B9A49D0624F25CC06C8243C2A8816426753B631100403B630D81FCA4D08527F +3AE881DA5332F16C4D8B15F3CBD4DF36430C2199BE5CD27CCF4BE86F5519C046E73442E3 +AEC3F3DAD10948A6AF7740BE87874A288FB27851EF698B571A027E5787BB45BA566A2822 +69423D624D118CA8D14B389A93193F1C8CF64CDC3F0153D4B8CA8AA843C2C26AAC2971DA +7F52B17B21ACE56A7021C6255A2707BFF033A1477C42C0B5D2001820FC9A8BFFB4E9DBAB +B595E925C78C9CF87420160DC0B549CBD8A3D12352AFE06CFEF38A2D3715AECCF86E0919 +790BA8FEAE050576C4DFCB416E2DF5FA3B25192F16A935C9CA82C87CC997CA5909B956FA +1622B10EAD7465B8FE6B347675D7C363581C9B52C9D020AD5CF983284D9359F4C8F9E91B +C073DAFC702EA788540E72A08668BEA885605C8D42E5F6BAE086F3591C614D438FAB01E1 +3D69768ED2249FF1079E2EE704F9672DF9DF9C8A41CADAE9013809F1DA83673A8398B477 +A13B4B0093E151F6489A2D9BC119A66232A1AB85F31979FBA9EE7F163FD59FE14C72FAFF +A1CFCC482619E13021FEC7F10C6730E5A7FCAEE84EB5011F13E407591BCE6353D5AD0634 +D4414B008C95F31170FD8F33F83C6B02DDDF05401012E7260A3DD0213857AF9072EF5DA7 +389AE027997C2D7130443A4B2E505A9F17B00E84E142E4ECBFF3AEF2C2C4E84F162E2F7E +436222EBA20B0DB87346084A2BF64B70B1796729F845D456702C7625AD2CA3D232345C9C +12B9DCBDFAB9B8F697E5E4EF2D473D119F81A46F6FD8A03AAC73211F36FF824DE6E03788 +BD669A0E7F2813A4AA830C8EF8BE445CABE6019318806D10C5952157FF8F8286C1EE7015 +45C8F60EFA854EAE66835A2046A6915D395F1E0366A459E43236162A929ABE6ECDB26B57 +EAE7CE3731E0DB75ED207292FD83B6B288231E4F3F8170DCB831DF571EC07CE2D698CB6B +88C63F342E89FA1BE8879269D9F818C4F740C38EB419A8A814E52AC7CA90187730F43520 +115D7388390F20A8119771ED45AE1E58C1DD30B171E7B5B2E75DC63EDF55BCB9D7BF3119 +5E4BC6D91227A24B996F83BF8AA17D3A1DFD34B32E91C4F51C229796662763D1668E884B +E9BE85D60132A4C45ECFA6FEBEFFD3E34AF21DA897B24A5B836D4DF2E81D1B51FE682095 +63128FFE15E36687F7720F3C980EDED7A794EB420F3E0465B1E93755F64A9C54A24058FE +E496317919512048C2B01062574EAA66A2F86D01F58D9D252F2A84E7B44A057D8DE0EF2F +EF7B752B46B1643D7E57D2871CC15D0DAC4852901205AEB7C996A957C4A0605AAC287AA6 +581DD2C8ED591B89BA7126687F970D7D49E84AD96BCE16AFE6508B25E85D530D9A9F7A11 +E788CBC50E80F8A4ECD26C241C37078EDC447DFF2A43ED7BF1E00B6F227926A9913ACEB0 +98B833E54B3FD10F9D0CE4B8ED76549239A7F4FE846B9D57F26B53229856681CA7D3EFB0 +22CCF57311C872CD0D0342A2FFC59E2F13B32D530B0268A4D01A14193D1B17001E205355 +1E42338F7BAE7D9B02780A3D972AE4E904DD34761AA66159CEF52B226277596A2A9433D6 +4B5AA165D9595B99829EEA6E26F4E10DE1B6E0F33BDBB010A036D221B7F4191F4420B6EF +621566F238B0ACC9A7C41B90823D9DA08E327896CAE4AEE60F860240EC8A89C03E44E2CD +D4E767F4D457275E3F7AD41D4983D7C6BCEE26E6A7EBAD234DADE81B2C98C1F3F396979C +04A4E00E6F4AFDDDBE9D9EB775D1A1EE76399AEC7D30D3CD09AFD73601ADF5593B56D0B1 +4471810AF628AF86D1237E3690509FBAB8FB2F4D041CDA612467B254CBBF83780C60C1C7 +AED265168AFC379F832EBA6D6DFA2CE6FBE127690B37309F6A613608BA98A5B77E9ED5E4 +E7C373750542C245C20D10035D1163AE93970F3A8CCA7B5A57DD0503060637DEA1CDC404 +713E1DE9E328DD8D902D24E0C70B17620EA2217B7E51589626FF6923A0D76DE1B480DFC9 +CE2B7BE62919C80623B7E39BBBE748E8E70242233CCCC5899AE70F1A3B380418564AAB15 +E4CCB6BE3A9329C58D8843AA7D287D851168FB531FA694CAE2B9D77C13720A9499C13D50 +B4D6AB2A5BCAE592D465FBADE34CF7316886A7287918889EEB7FE26AB47B5319F833422D +803421C29FBCCF0D64657D945676C968938B633371EA7B3114BE2C23FD20581CDE846A7F +C5C57C4A4BFBE5A649B20E3756BA94FA8C45D0542134790D6105890BB01C961ACB87C761 +743FBA8F2549015D6B171EFD0390ECDB7744E185BB9D88BA42C4CCD61CF9AAC20B6E4C0D +A70F20091A75C9250C9F9287CDDD78D39400A85D28C70E38B38D33903E7496D3EE1FE98D +B047C84C59A60A58DA8DAC47A058A825544C1B4F4CBDFDD99A04BB691854A20A773544DA +A39EC11B14C864220F74CC2307075EBB4847AFF216614A471B1B169DCFF4F89FE390CB97 +46089C958316DEFEDDDF9F3BE4A6BCD0423836A7AC3F7A29CC863418B703668188C962D3 +6803BCEF438B47363A40762165AB9671A46F9253DDE8AFC38DAE53F7E34230ADE2830956 +F5B7EB9BE9E0086B7FB715173272B381B494085744ED8F2EDFAA567E2DFEC2861A231157 +818D7DC0898DCB8B8AE30BC0F1A65F018BBDFF3ACBA4436B5E824B6B4CC0F4402856E259 +F1D5F1C770A1589A621F9747B5F7E81908016DD977ADED8019C39BF5CB9AB35CA82CC83E +AEC842F6913929F8339EC1DCB27A53E3E1006174E2C8CBE4756F6762395DFB5AD85947BC +63137E05269807A5958D5A346528162B4C1B485E858DDB2ED3AF35A0485CBDECE9A2893D +C28B94DABA77498C26861FEF72571B5B66477862642465030FA5633E47B24BB8697E5A20 +73945D8E2338E554D66EAF307D9035AC9678414E799EC56AD03EB72A72B227DC18C3B27E +8AA1679D14FFBABF22FD2EE80C94AD06C34FE7F7597A82E1EFF272F2FCD72AECE10D5102 +BA8682441BAB1E8DD83EFAD74757A96051DE07782FE7B7D7BDF36DF39A434E59F1D2630D +93B66D1AD1A9565211B13427A036019C538D4C4314905257E8FEB31FC5DD316F606D7BFB +9CC3829EBCEAAF3722E465C60AB1D7CBA1D2D229CC28D11DF8FAFD2169339C0B61AEC73B +6FC855B5567FBF05D9088734DDD8755700C80A5C942915811567F103D0CB70611DE63F61 +9B2908AEED0B33A1CD43A84785FF49EE977D5C45E1ADE13672FBB01DB79096DFF6036904 +30B27DD8C0609AB745C238EC6F73B1CB8234794DDD9E1A41681CC004362DB2A97B8A96E9 +C981F7848C4BA5ECCE7CB87713B6B7C7CDB7450AFA5FA6719A8EF035D672A136AD494139 +8E777EBDBCA5DC8A9DFD54654883221071167CB4756FCD042891D85E4B2F5F306F39CD0F +B2E267665EC0A394A150D73A9AFE7C1098609BB6247A6DD24B01BD3B78DA1E49AAAFF696 +D27A53696FC27DA3B017224587D43372CD3406CCE3AC952D73C9AF01058C8EFFBD0C177B +204C6DF2CFC597FF177ADCAB6FCBD5F0267B00CA18311A4250FD04DF3809D4DB2C0E4778 +3D905D787362901E1171745B2A66848A3B617F29FE183DF6F746F9011AB14925AAFA1C4C +159C27D3BF8537D6FAA40A20B47745BD7148C698C450F18D0ADEBA3095F0379B7D0B4354 +E1BFFF0C63C7D745F0085D7239612CB0E5EF4B8FAEF7C19A7300881206500AC612D0C42C +66F4B99C32AF8CFFB05749260B56B7B425B550C427368E45AB7BB682C9D3E07FAF35DC89 +0AC6191384133DA9DCA3F3977243D277E0A1B833E37C4399B67DC083168310ED294ABA2B +6A96F5F1F7E8A18E5C8A95CE1E224DBBFFCBE5E54BCD199625EBB5E5DDF1F2795DD53D81 +86A5EEE389B4EA7402B14D2BA4B3D9A1F50079AE9809A0B0A5061764A3320D9AB4B5CF1C +4BCAAA4CB0F2926A46397B9D8F3B3956E647FCF3034A34B6BAB88BD4C53FB84638DA56D2 +2C65DB9BDEB68FCAD5CAB7B184EAEC585677704583CE9372F90471EA5B68FC5D1DD702A0 +A7668E6C7416E4A5CD646EFD2359DBB7367492BC0B4E6BAFA13D3D3975604E1A187A6E61 +EF6087394EAC2F8FA9FB4C040A994545480329FF5FF9B4727A39356F8A4043A74A9A7E2D +250826ADD481F91B9DB916A9FD5FE4469A9861A96BDF6BD3DAE13293B9DC2A318A35D7FF +DBCD241F2FB394644895A3F53C457C752A72E8167E6B7D4495B3C1DF0EC53127509988F1 +49D6C49CDA35B00652F148D3CAEFA3EFD8954E80766AEFCB85953366389FD4DF6D70E36E +B321BDB176FE7B75CC31A73F4DB7BDF5E0B45C23FFAD7B7EE35B9B6E9EA4141F4F98430B +D93BE0FCF80D63D7860E9B43D161DA7A68C2BD51E2E95ED7B54A91466D0716603CC41E83 +7004D94DABC5D971330DF98672136E372129A77CB496C7200FE3E287F7936E8002B54C51 +25B364B6E07943A078E2C018678B7E159C1DFDE7633CC3633B38D50C54B98B45DF4A972B +93B4B4013F8F1EC0083B09F3FAFD2CE2B2ED5791DDC0945679A122F21B4C5D67DA6E5A5F +2A5893AD3AA7AFD891ABC6860F14EE16DDE548520DC88C2CE6099861B038EB25A01589D3 +2F4AE37FAA4D171416651CCE37FA4EB8D063A0977988E50F9036C0A9C8E99E6D586EED28 +E0FEFBE7406386EB9FBDCBD8DF820F6371C99C6F7A4F2E3F43FD2792A9A2D3F81BD3DC6E +DEB59B1B4DACC2F278A0C6C1D3B841A73525F311504CEFC8538CD53C487F612D9045AB40 +8B8A76195907E3B679CE68322703C2F80A50401BD44BB5D14080A46F859075C9B51BF0A2 +C42321EDE4254F558FE33357746631F407C16675320B8DF3E24E0FBE2E93BF718CBCCF5F +F21F013313BAF474F239CD0FE72EB03279791A95BB322DF5C4725763052185CD5CDEDC76 +071B4B2337B406337237A2A6490D75598CF6010D22582B8A12871C17003839A8A8C42E92 +EFC92B7EF0763D7B6481965F890802C7AD345F2FFB5A444DE404C833D1D9DB1CEE2DABB6 +42DB540CB398BD2C16A7383E649A0714154E72D94438FF904755399C1674F5E01CD45590 +CD04C4FE3292356650A3D431D7600426A1475B5919722726468C247BCD565965DA6E4A83 +28644CB1FD2A23B1B45F74E6B4BA9AE065BE873BBB80505D16D54D9DE69026CF1DE8DEBD +E472F067C70CB4104D23ED0CC9BF68055283A6CC2AAF48FC59A580DA8597F95EBB8F61FB +C4F6B12FEE888AD60897383AB17D227C0CEF95E86F149ED6B71C2FD67F5A996E8B34C5EE +23DFFEE49200A250611E32FE3300AEE9BF13790703B6AC983C965F1C52D2BE0BE876D4A8 +85FCE072D5D584B12CF2CF91BD7D7F9EDA1D6FD62F40AB5682312D6138030FA1EBE9B194 +1DA4ABAE5A781EA979F608C6F0D5481CF48AACE9F79031574204447596555188C3D6048D +B9D7D8D1F0B67DD5F3468E7C7B647DCD1AC3B3C95E1DA6DA05816B49DC8BB86E85C0094C +6C9A703B88F020363930195842A753EE42B4BEC13B668101203BBB7D5CF7E9C3E39716B9 +85F4BA374147BC7B13BC2515C8A500596D35152A102FA248B9E30D6050C11045B9A81213 +7C228594EE2725F43CCE59D3F1669F0B4722B2171811C2A12B1905C0B40EF1B1957731A3 +A20D29302DB48D061351430549F57084C31D008391BC9D20534EA98CA6F951E00FDE49F6 +22913C19F44E489CF9A80274B43CA60CA5C517C821426D5BFA185649ADC0F1AFFE8ABFBC +A0A03CF0DB690CAF902219A5580EEB11DD3ED650979550454929EFDCC32C7E8418B80F54 +F0CAD6049E2EB23D5DBC2D680772F03E8F3D19913E6F771AC65C1575AA6968CC6857633A +C2520C09AE900BA1CED6C5C21C2CF8BCA8D676A539F22DFE03B4134AA8181CB38BB0F69F +C83517AB3AAB165F2A1FA474E067627199406D26881E8066E509D3C39A1A8C4BF99D4D46 +922EEA6D05F7EBDD33A33774F24A650B9170D2CBC9A69317CF90010F9688EC72B3DFD2B7 +0EAE5DE97C03A5CBC355E8A57F7C36D9AF8DA95B4A307965074244B72B5689F6DA0FD360 +DD95C184A7037397C0598153F96AEBF3E059B042A3251AEBAFDB90631C7A7E52C89E7623 +07487D51B8A019BE505E4078DF87A79565DAEAFCBDCF4D99E658A3A6F33C252CC8FDEA27 +CC974B91269FB2FD905A619159300A0274E79C1F52ACACBF68E03CBA15523A0B2081C739 +3D397D3D4BDF3094FBC5D20852EF7766A4C83B708E2F75008756044AB2B55C57559CF7A4 +636F74B49D18E81057BE38166F87DF24C73B337533DCAFC8F7D4EF0A3C4C6B82E9BFA3E4 +F3116E011FFC4A89B7FB72CFF1B0229D6D578AC85DC6E6C3CB956193689607D6D7A48367 +0D7C529E5C5C223E081E3C6F1F3A2B8BA8EB5C4DBD19F9A5566694EDDAB69837B65C8299 +63A95E321181E4BA0B097FBDF72647838C8B49DE3AA88B6F755317FB1785E12DDA71F944 +49D3D1DBC0C167B3793747D9D6EBF6FA13A74FE1FFB6A2EBBDDE14A21040380DA4BC9088 +C60ED587EDF6E2A00BC041990F00C7568373598310FBB5FE87A1656E381A2C449C63B236 +5BDA6D3C51D1E5A1A0ED408221B2FA8397FE2FC992F990DB3E772F3EA54CB468AD471FB8 +0FB1E1A9CC6444B98D2993F5DAAC9B5CDE3ED8AD6FD8DE80001DC7D67A09B39BA8D0B35A +CEFD510CF34838F06C72047309CFA29787631CD33E0E4457DF26244706966FCAD9A90668 +A155F9BC4214693A80C3440F56C2A01D87AD998493130C344E9560A88F9969585B6D2D4C +AEDCA0D1954D6C84E0F717C48548C60B39D0013FC95E3DA0C13796130F3E0D8A240F8ACC +4BFD93D26A7185DE5AA0C493EF230D0A5EB0DDFBD49A66A61D814D2D03EE94B40A25F8C6 +5F615B8C4402B4FFF0A882316E9123C0267E0773E048658ECF5C0008EC18976EE2F8CB4C +E5B4C17F857B83E16622180B70F0433488E58826B39221566EAE2A9C350177F10D9737CA +6ED009C263E3198F02D7A3514B3AA1AE7B0BDBE901D84DC256855A3DFCC83BF51C9B3CCA +1FD2756DC6D54280E164E942530CC560BDD8FA6AEAD30EF5BD8A4A30EE5755C7A4D7C550 +F0399CCEB87FB781EF298DBA53BF7FC3373388DDE9AE21AFE51A7EADFE83767E8A112DBF +C595A9B0E833CE7F8ECE227028F10E36B8147340F6C0152DADF434AB60CC64BD9158E0E8 +C30F38FD0D5D7573D43FC3AA9403BE945DF46D040AAD91FF69D0B0FDDAF19EDE36F089AB +D8E00D8417C463C1CB3292E6AC20CAF026C74FE0F97CF8D7956678D1A104002A68D53664 +A82EAA93112A3BD2B55113F37E8588E78C0429E482259A2A0C11F745A74429FBABB8A53C +D40101CE27011FE51335D3417E41ED1A8D260EAAB7C3F118B426DF541FFBDA96C4FA9859 +66B99AAB27B4DBFD28304F386879C6DF62242B689DE14BEAA08BF07AE4A38B203B024F88 +808C5E227B6AE750142874E5E59B23AB9B36025B6D67EAE9B8DB60B9A04A388525D1F50D +C46F8172AD8DACEB870ABB56944F916B492DD6E9D296049973D661689E8A416014D4D2C2 +782EAB49362E9FBFD5BD6F0C95F243BE717535005F99A22FF28A7A02A5F4BA4B1F505449 +61ED383753ADD0D2952FA9313CAA827F3D8F8977C98D760E4BBDC134DFBC0A008230D337 +35A048B81A94A8CB7034DE777595158CBABDB648F1A2325655EB64B42C24D190C2979F9F +AB4C9DA55299AEADE3801F9956E3C62A77A16746073EBBD364AC634B37671C8F153B8EF7 +D9F110CEE184CE3394349EBFD88E43D15B309DAFF263F4BECF1C581FC4CE876B68D3F1C5 +EB2F001FBA2809FDC3F834833F39B74C9E5018C8A7CBEECDFCB121EDCE0282988BC5BF4D +156D91F53B4EF6B9FF7D95CF1B39B679F06190A10C3FFF40D461000E3F8E422AC042148F +E12B5A776BB1F15D44D41CED498A9AEFD2CAF59CDCDE5C4158B8CA1CBDF4FB5AE83D99B1 +A39770AA15397D85F77F42846B0893AE39A0F4612A62A7D963B767DFB1E92A0B73FC65CC +EDBAD8D74D2C24E08B2D551538DD954D94A80B92E897E8C10D1725988EAF003E9BABE962 +2C9C8D278A6BF1935574C80C6815BDF0BB7011FBEA53A59C0C45D1978A1D3E6A7BCC87F4 +2C5FDC7886044CE5798F06096AB7FB360316E1BFCE3E719A1EA906E0C5949E00DE7AED0D +E6C25832D30CE1867387C8254F51171A9037C8CBC6D339B4647E9077D605C13E30324180 +A433FF9F3A7BBC3B0B775A860F7BAB63D7538E2092F902F019D29FE8DD198EBD85DF0564 +D39C10DC176F698641996117778D7F899153CB26D568C057DA39FBE2D21ACF39E0756E16 +7FB5AF562F190A7B940A8F4BFF98AE156D74CE4C8CEAAB103FE6F06B7D578E5D7675DBA7 +27FCC0B96031ADF2D3F204EF9DF63D8A4263EBE46B74F1A2CB67D620FF5B2585A53C7CB0 +DA53F6F219B277BE9F8735014BDF61936C3377A6D1348D3C670A65CD057B32DBBFFFF5E4 +D830E9CA83BABE9298431F93884E2083D6ED6DA68A30C7372539DE05E8CC9DD8A748C810 +462687C6B9B75B305C3A31BC32A122365DEB55AF6F6D2BA9468247BC0853E7144E46AAE7 +E0D7C76E8BA15289ED307E0943F5E3A05F051AD2C2EBDC7E2BA46F91B4CA94308D1D2FF3 +FCAB4EDDF761FFCF83C23C979E4D318A51A26424D78E5B215EA33F04E1BE296A9693F065 +9309FF404423775875D73F230FCD5CFB1AEF0F6CE5674F865C300105791111C1AAFC98A1 +557123E1C34749937C8BDE11E41C21B1B0FC53E8C5D199D3289DE09C7D7A95EB23D5192B +AAA67A13DABCDDF6C48115036065984276B126F294D6BDDFB90BE9319F3A3D031A22BBC6 +05766A7BC934472D23812B37720AC3403189F34F2CAC2B674B04D3B3B46B6662B1C2489A +2964D8EE5EAAC87A8AC7208E5E87358DDBEF9EBB52B96102CDB82D8BCC5D8A404DA247FC +C304D7153187BB579C75F71DA411E4B0FA80D2131D11C6BD693F3AA001FB349FA11B5FB4 +9DDC4B2A6443A8932AC4813795934D61D38BAEB1847EE5D3A7D01708524B3933B442709E +CBF2D39460259D44CE01645BCBCDC2BB9588C855936C6100009D867FBDC902475BB43DA2 +F7A309AE56082F18E670A25BA12213EB7D9BF6679452CD4814353BC62C1ECD5E1A7C50EE +43277A1D5D124BA9F596E19A29C24C234B1102893D2BEEA07F22450E26BE882D0FDC2AEA +5457AFEAD360063AF6A079958A343F444DC6EE7126AB88ED079C0165CF95765CC52DBBB7 +3CBECD85BB4F1176C4608201A6E2D3FA69C439B4AB2A9D5441F519DDC85C35C2DEE504DF +5ED9E958F768E9FED68D18748C8521FD6163FFE0DECF1BA44B11A261A4997D13E045C255 +0CD95881B9BC5D65A7C4AF0DA73A637F4979A3B54B9857402738B1E9FF94CDC075F51817 +CDFE1DC677E938F4ADB9E4CE4DDF4F12EE6C72352175B8389F39F84181C189F1BA529E9D +8D84B7E36790C1F57CE2117811E986D00B58EEFF6C8121934AF2FC54D09C486A5D9CA8F7 +6887CF4D7FE4841F3222F0C4E4F7D92C014FB4D48DB83FA87C243D453915BD6BDF5278BF +1C16090730765D68AD17160744DFD19AC8A754915E669074D4F3A9A1F37F7D720B38D5E1 +5D734093944BA853010ED6C6CC7D5D885D6A1366B2FEE42E54718A2DC1BBD437830EF66E +A0F540524597090FC7C762F19C3946274500428C3C3AAD98D9611484C8CD302D64991438 +1F7E531BEC859E6D6624ADE92B17C4D88AE651E49658CD23840C404E1E2EEA4F56D6725F +E514D3AE47AB1127EA69CE677705C603CAEB0DA31233E15ACC5D78ECBB90DBA3878F19FF +F2A62395FE3B8EEDCCBA872A42334251BB515C34F513D2FB745033E903863C24A7F8A47F +0DE02964F1D3AA92E60BEC967BE17A207ACCC4512B8E8D62E767608FEC0D4F0C6D339364 +0332BFDAA278713788075972FE7B5799FCCA94BDE4C881CE667C4B7D10F1A4CE65766CC1 +F3486E0F23DC940A93B3D88EA329FAB54F531034113FC7970DC304A20FA97FFE7116C6D7 +1504BC0FED9A1C8E617AFED697DD3FA441CB5894D783512E1FFB859EA5686F64381EE1A3 +471572DA94B4D7AAC35E3E77EC8ABBB310D46A70C5AB691B050019B1408DB7D155AD3F75 +27E8FEF1F1492E8C96C96A0EAA70AEE119B244995F1DDAC5F9E1B4EDD07AA389382345EE +2873FF17B725037B66F7B5B3CB74237808E8A1E8FA6B597F418D62D174E716C0A857219C +DD489083E9086E5A3564A8D0925003BB0935792B38A458F451CD15D8824E457132B50F8F +1A486AE2AFAAB124EB8D387A4AD23B552803298F23AB33D96547E1A028FDEE361836B59B +879F544757214D635D0AD01C8B8D8FD61B852E3F6BFC9281C99D1F360032349FB484BF27 +256B591CAF48AE5A6A1117BFB824F3850E95E75AB6FF948233763934CB18CD290BAE9E53 +747FA478BDB6E343336F58D89E05BAE9B912D484171ED576DE30D6516D68FF80CC6BC36B +62CCBF407447126E8B3D6D07DF3C187AAB240B84B5D07CEF0CEE8AAD28DEE446F321C622 +0A7E0026C64802A9A006887A170FBCB19B4C29CE1D4E089F5193171CA3D3EBDC1A1286A0 +60C648D24BBBB8791BC400BFCAC653A673F4C3A59C44D364D408B72437C06DAD89512F6B +9526FF964C3B2646DA7E34E3DC95D2408ED3816C6177133287B88C896EA7D575D1389971 +2A9D3A2E689C003CE2D5DC4073ED052F37A3183BDCE5EB3B509385AC8268DDC54A33F8B6 +865FD8D63ED1C51B89B07DFCA39914F10AE7233C7A62EC9B83A8C6E3CFDA24528B1D1F80 +3C74A108E7239456B412EDCDDD5995A6E56535CC9D47E871B0CF8B36BED4818FDD112A70 +2704D417B79347BA3CF24A1B116937BDCCACF86D8D4C544AE863DA44A29C308F740F5DD2 +3FABD1DC281D722590624DAE38EB4A119F5F271C42169287D8E37D34EDAD684EA20CF29E +EF4B6BA4D65E41E9E8BD9EF2321C2453DD84C5AA056017E7F5321A3C11614D810D0095E0 +5DA9C4ED65463C672FF360E0104F58A79D7C399F058A9C6BC6298AE226E06F294787A1BB +0EF6E1AEF499BEE46F2AD81296667E2896098DC7535E1415E7BC0C3844E308807AD7E5ED +59EFB26E2E6E5FA00B7CB6B1A160DB111AA0072ECB249F30A29643BE8F51276A0DA7ECA6 +03136C0147C73658D218BAD2A6DD880C62186178E527901CA62511326630815850E0F4B3 +7D3EF6B96BACDC9EAE70FDCE411297A167780F749BF79652EC2BDD4E620CFB45B8AA9AC7 +9BFDDF782E3B3A6FA9A0B20F8CD7362AE18479685828245B6069F437171A4678C6C1547B +5E4E998C8835104327C75298AB50A6A0D2ECFCA02D466C08669A93BDCD3BB186F04770DC +6AB7C774D2258C4E8C54D56C4EC2FE59EB24697C8BACB485E4DC203630B052FE09D83C97 +781AAA7CDDDD22804591A689B563D318FF5D269ABFD3278C345F6028127C672C3D3D8168 +5739CD11FF84E88C3BF219A41AC1C1272BE1D130A8D01EC18A83906CBC0E02FB4F430026 +5FC5E19B6A5BF67379EA2AD989A1BE64B8BC230CCE5E6782514D465C736B904F42D18417 +EF0A985121A8B155C06E1D0ED8BB3EE89226D931C9A8A0F5E80882DA98C72E346DEA25CA +C3962B6C5879B6AEA1F91DE7FFF9453F98FF1FB2805B21994C0DB8DCCB8872273BD7D964 +EBA87F2FFBC46DB4FB8FDDB5840A162CD6F6BAF0377B43E5DC9DF9054B1AF843D5A4A38A +481EB2DCF93C088FB019F8209BDD37502B8190281BA5F0A91171AE14E313617E74B751AC +AB74070193E0F231497C20484851F0182889D77581BBE0B1539663F844854D59F93CB6EB +A5CC3D2B3FCCF8D6C3758F5F333033513DB561A9E318F599797BCF0FC43391DD600A91F0 +B478A983687DADDCF974419A58F98338D9FEF2036373B5CAE2CCBC0169413BEE50EA39E0 +AA6E922F751B981FCBAA8702428C7FEEC0BAA712989D5F1CB3692F5EE3A014F716D42CB1 +42FA136A7ED845F781C18C1ECA0B6B10699AFDE08BA05393E413BFCA01C7A097933F87CE +45D7A7339F2793483DFB43A26B277C5B5D5A3A51CDDD80D0D6C1FA7D16E03DA0F7D86E50 +85D4516BEB44D0AA911A7945B244CD4A83FEC04985877D15CAB67EC734B1749D837AAE24 +1832A1B555172307301CF5D25EF9DB48B9BB1979893FF637A3C3A86A6D1688F0B45A411E +C8C02AEFA1764F5BB2423707FAE1439295E75E365785FE9B9E5C485779D124604AA59F95 +B8A4025E3D8246CE7AEB3F659B0309C77B6D10FDB120F6A4DF76EE00EF3607EF9D22EBAD +0DBA789B86339482B98F91CB29598365A5E735EA4B7AB18AE1AA8AB8BFCB207C558BDEE6 +F6865D10C8B3487D342C1F6E74CC0B13B522BC054AD4EA9EDAEA215359465BB97CEB6F7C +657ABE5577BCDBA7DD3A61B2C99F552BB70479328AD21F95C8A1F98D019CB23B6EED8808 +658742B1AF408ECF70B36ACCD4F06E4D160EA52DEF62E9CED463FB758C6121724B6E31A3 +A097A7D21B0D5A021B28FC000C68F6A4126A5418EB129AA699D04482EEBE82AFE18A7D3D +0608E71F5899272A4E614E34005578746F6A9D082E29E2F03EF54E9F55D393AD28477E27 +C780AC02449FDFE3314490520FEBA7B38A16E94A302569CFF6958FCDC79561F3F93FC71E +14E780E4F1E9DA30A9B1CFF569368069B140F5B8E67EDA15D0F25404A32362327A0FEE9F +9AE430D517AA8465C72E9490C31153E3528F08843A100BEC4D4BFB6C5E87CA088D4D4C18 +2E398D02AD5D8007CA369A83881AC0C886E72D91A48EC085002017066262AD81925B365B +7E594F3DF58C55A9DD737F2069BF951DB68720AA4043BD6F039AB927F7149DDB7830AC67 +293A70B6906135DFF159B352BE8AE55F1D03AB3BF5642CE1B1A49F773FFA1FBFCFFF851B +3DA54CC2A5BCC6C2EB2BC5CD41676EB08B727526CBC01FC9C7A076A5342BAABD5341B6B7 +3ED8A27013ECA0861430BE51B07CED3522A6031EE04E74F985F10D3776A206BBA86FD199 +64B37F1A8998F4BCD2599A891C5A61C131B23D29788719C15728644886443D12492C87ED +8EDFEC9C5620F7AE2C5CAA568333C26C8866A2E2651408D2BA3B40B68875FE271283A331 +F8EACD13FAED2342A5A3A74A1E76B74283898D8B265E0FC9CD3597CFE85FB55B56AC02A7 +55298DAC4A7471FE68872B311B690E5BC0AFCAFC4CD7EBB5326E453BB07A94843935CB49 +095EE8C7AB1BDFB71011CE6A8AB7F51363DCB97AF77C5C1CF0996F7F1A33BA929E9D32F3 +FABF10FF45E9E53A4A80B808548BF1D70383418B57C986341796FC5E1309EED60AD85476 +A7FE1AB5AE38258D917F267ADA978D02FA7F44200954F8230FEAABC0D7ED444864C91AE4 +4D6BFCB7E09DB0014B6E11FE753C6CF12592156B7946465D1D51C8FDFF1671B9DF64FD18 +0680EBDFE37D5B19B60BAF8A1081C8107C0C207941025CCBADF11423B7F09356B7D2B25E +3C8386FA4F41617DE67D7BE0C3790F853CDCDF996CAE79A0D0113AE8293426662D18E2F2 +92452A9F2D9B3845FC5B9ED4088DB9CC86886D82FE7310F2A158BD57739A0A1C36A7EF21 +6167ADE2542E5124FDD3143D353122182A9AA36A530C96AEFA8ADACF50A5B0266B59E396 +AEA8DF4FBB2AD02EBF24B49D4BEBEA6F1555B5515FE3052CCE0C540D20A82D6EAEA1196D +5A2C029DFC79E48CE0448F7A9FD83C7F107B40E55383E9656321497CB2742756FBDC2646 +A850AFBB90C1573979B32A29CD3E1C7A3350C9E1727E884CA842E9C60601092595D44011 +BB4F24E8A505EEB5397445011750A059265CF4212B4A5EACF7CEF1E922722B365987886E +481215C980DAA2114E03DCC02D1BF8B29098F54733B3090E4DCFF294E01915AF5AA3889A +99F6656F8BB7DBB5844EE7A9FA0FDB8AE67A2634BCFF57B248772F9B5F2E9CF95410060E +22C51E6437EE48FECCF819B1655F052CE6C6EF2175A54652EBC6C38F7BF60799733741CB +D7E030198D32B9956AE908436200C6EFF6611568EF351402A3EF854B0736390F7A16B7A1 +50EDD6E39B2E0D42439FD75C1D0311C8C45138AEE49A7DA2F742AE3C21E19F6ABD62198B +6DC17A3A315AA746961425A18051A0C0C5653D40F9A6D3A542F430DFE71ADAA74586FA56 +9EB935247FBF47098C4D85417C0A3C6E567F7A65B7C23C1060AFD086186E394896D1DE26 +9244085D469240E8391ECD7B219A887F01853AEF9A3191AE70D8D11FB13C7578348599D1 +95186180E4AA0C3419322A318487A712CCC0EE9954C87A6FF2FB447278EA942C101E925C +95DF648D275C836F03A4D1FA85144C7D57622FAD6BEFDDDD7AE2E931D430E29885E83E81 +4C7DF4DFE157A423A163E1372999E34A0689EF8F66EAFA66BCE76DC6CD5F3317BC7801E7 +F090410D2AB40B640777C30476CF9BD7446A9860594FEA131D308D9AEF8F96B7B8731ADB +CAAA0FB8585DBBE770852E8A76A43FDF93FE9566F81A02C2AAB4014CD74CFC1682F33686 +418EE5FB80C2DC2A155F16292FB6B5C35B230038A91814B625EBEC0089B75E7F3019490C +32BE5B78620FEC427B756A3A8085E42ED93304D80108A5D957E479933173EDF77913E5AB +C5B84133CF6B09FEAAC3A41068883696A3E2FAA73FD401E4A5E58F3F7258207159970234 +FD586D1C34EAE89F2213B28F3597EEE1C0D11CA93310C8A294C88119600944A539795B41 +E332CFAC0E578B7E9E9CDB291FAC7B0CA3C125FD3D783E4D955DA04AF2EA8B5C97869104 +84FB27D05B95C8C8FA91C84AD9BE171106D0AF6AF582343250BA953452E1237EFB0142AE +5837EBB076D5C7B6F25AF4625465CC89B27977E6CB71AD1D4058AA871CF3FC749BC4B87D +D7F75D3D18E455C67705EBD876D9073D828D4D083ECD7925822732C07E1581B1FCE4A337 +EC7644EAFEE206C62C1A64E10F0F1603CFC09C98FC36E61A59E9DF4C1D410BA2B775C44E +91001A452798FFD0954AD15D9D20823B52740716F40354E503816CDF0EDD7B6B97879260 +1204972E0B4F8E783317388D31B2DAD3132653A0585F9EF80BA68093A79B773836CD6E62 +CEF409A9A4007D3D7760167F0719F5A12DACD27BF8E0903C75A2BF680048538EF924B616 +FADD681B2E850B2C6AF69E86C491CCB41F8F9FB000F76155B651133D09135EDE439B6A99 +D4B35A49E2AF4F82A369ADAA500C873732664D50879258A9C663196BC29FBBAF20A7FC9E +7DC8904DB9536C92E45F958AD46C067DEFC27FDCB71A7A1E2391FA6B6306B71ADBF3D6EB +1544F077E38D93C9ED11B2CE62D3E94064FE75DBA762BADF76E071BCC5507244670FAF79 +F5B0E11CD72FDF68DDD6C03E6D42E4D505F88554662BCD0CB4F5A0A33CAE7BF80854E715 +8B4E020F2D7517F8B5AAE67675E7518C6A14F00938F36E23DA2172719B351F0A19CE3691 +12DB35771C4EC37F61669D570932E14B82E3B419ADBF6D0E201587E0DC75A1DEE6262DC2 +6EFB9A02174CE7C7BA8E626ED0BB8732AA3618909F69F2D4147F3018494E22ABDC63C89E +DFEE86E6B21DA05163A32415E6142528918A6936F05948C14B2E34FB4694D5F664AA766C +5FEFBBA0F344FFA065F5394F621DB9E6427EA543BBAAF77515D7EEFC5186ED5F9EC74A97 +FD1663195D941CD67C91A5217C8D5C7F1BB848C6A3BD03A2BE6A48C1B2E8BE247D02C01D +B04A994F207D25D5FC46939095986DDDE77FCBF9698D3748D12888D33A7E429AE13C8194 +D624AE196D2F1F384F2B31801B2C3FF3217046A5E11890FE1D63DB4159CFAC405D657BA4 +E47734669D01E953B6702B972981C08A0B028F5655F7C8BD1DDFE145BA1D57129CB9D5E1 +8996C0A0E01285E799F4753CA5879F862A765B6927D7AE8FB474E8169708E1D30E2780A4 +F6893E46DA3F20CBA50BC6B8A310A9BB06713EB126961C97A9F2A4393D663E078026657C +AAC7E6C723215F0FBE58AF074418AE70EC0E710C97A1CF4A0FF853A8051F18BF4AA7DA5D +5B52CE39EB779B75843F14E7736363EB213F3DA581741C7D21D8DC268063C46E97FB0B2F +B525AEC2C6F2D25E0EC43F91225719B4087A92D3A44DF7B5333C64B92862755D5D9566C7 +FFAA3554AB50821AF913213B8738D8FBEB7CF5BDC7E8F191EB3B66A8AC1DD9EF0D5FB967 +B9B1833D8C67F0B6AB2A32F00D20FA51E841BFA6ED035779536EB6EEB30CB751C81D7270 +FF877E2A0EB624FC8CB8D40830B9FE2762FDA8F5A861A0006CE1397598A712DEB751647A +2E5AA196BD31465961D4CFB2F9E8C5C20BE1C92592B3E457CDD05B11DCEF03127B494B8E +4AAE645ED3D891973EE5D633A24B19B06B0F2389FD5ECE0FC1C5091B8334209AC3DE128F +8772D373142113CD296AE0DE58B844496A70FBBC89C09629E095EB1E36DB8E73155735C6 +A4029C1CB8D935F3B563F68AFB6D1DE6D40A59A1F7092466355C7C1A5C3792353FC4A598 +73E5DB876C029895CC933DA80DC11368BB19DEA413FAF2F7652AC6A18ADD92A7D647883A +4201773313B677A7A1D0F4985FC8714CD9632C8266BF7317E557E79CE1EAFF26C5E19F95 +698799264FC251C8382158ED39E613F3BE87660A5F1F2C6F7D9EC08A901E4800463E6498 +65F2FCFAB56F971730824AED3970830FDF3E57802A4CE2DF1EC509522D0FF75EE464A502 +D77A0E9095DEAA555B6EAB3506F2B13B817B60AA418891969AB75873FB0553874048C1F0 +0A9C61105A9215572B1343571CD14FF0AFA30B040AA95AF309F412692288FF9D941CB245 +5B8FE672B4E78D6FDD3AD9EFBE0EAC354C7AD246456CE0C8166441D72762B6518B6EA8F3 +15898649D17F406FC07C50F87F04C9DC12284D655F3A4A14A3D55E80E2D3D054828CE8A4 +2E33D9963903C2BD11AC757687014D2DED8D1238BEBB7260A96D973B062ECE3D429BEF7B +63B4394A2B1DE4F56D0729A7956030F8757762F13A90E211B7B245F3E968446F5AB19621 +5C0A0F6F13957C0584357FB760C68D41A89049B5FFC42A021B1AE9217BCFFFF0063877C9 +4E884FF624D80BFE56F79CA93EBD70844BD30D51D57E19634287881CEFF135EC18ED3873 +596C7C9656B31BE31655F2630934492EE1FC3E44B9607F1AD8F4E162C356A1383AE4E797 +0D2FD92A69282CD16663B2B9D199702FD3CA9B6CC7FB12A7A0C2713B3F5E81F844BEEB2D +F3EE1F31BB05BF57377B9356B776D84711164A49AD69C338D8AA3EAC2F616E735E5677FB +D54A8140DBA442BFC8CE397B2F7F200E9B8AE8417733F90B2ABD1C70F81259D944090B92 +845767E935B2BB7D5181EF5B3D50FC31585BAC37CFA267B966DE999D3B40B2023F132ED9 +C72F827C28D41751D67B98ED61FE3E611A4AD1AB2C45F303677C79A49F774F710004E604 +0AE91BEFC6C8DB58218637DE4923CDB315E941E5E124AFED06CBD0B75484B7B9DB3179FC +5759BCE19BE50D07541DDEDF00C0BFCB084FD3BDD10C4EEC22DB607D65C29A6D78178AC5 +AEF0CB466EAE31EEBFC7B25B2AE157C69BC0747EA3222297F4DD937E1523B9864B62A666 +A4ABB9B4B3A908DA0C37059E847AC1405D2E4246A3CB9AD3B39BF3BEF16D48F769B69422 +7D6743C49F6DBCBA1113DF16B64272848F092C34103B40DC3118AF1CAB1E743BE858404C +3A9831ACE27D3DE50EC75F982D9DC1B6E34BC678A07D214B0A22AA146AB298647927FA54 +222DA2AE878C8A0FCFDCBF90A76CCE2D6CD623818121598C31D0485C900827C91AB17ED8 +3DEE367788418FA250F9841DEBBC95114D82CFF93E8C6164C65CED77D5DDAB4F65FDF19A +26FDF57FC3AFB4F4D155B1AF747A668724F1E2FBCAB941987A17D4B455A74F4E5DB5BD62 +496B197DF439701DD993EB50F92D161ED2E37170EE2D1DFA169C2AA43752C765FAA87107 +3DE44D8BAA93E6511DC365B68157C81C8F3DAC8C624E58EB22CEEB668A058E23F3DAA93A +D05C5B1DF3DB0C88D6FD40113A851F1387E9E2EBD2460EB7FB642BDF4CEDF1B22DBC51B4 +2DD058AEF2CB32B20A30F1948A363458FE07B146012FC3842DE485E687408187A89B93E5 +FFBE019CEE53E8A46C3BD54D12D35DD09D638B7033F0E8B48CC29FC898128F2359AEF423 +192C75DFE9EFD8FB5CD2ACD71811F5B8BA259E9F4179CB1385F85C9B1CEDE79C47ABE400 +0ED992A100198FFBFA4ED40B9B55FD2053DC49A2ADCFF0D18FBF9964BB2976D676FE54E5 +5051BF7FE08C5C70E8AB9A363F98DF09D22AFCFC8290E828CFA5E965574043B310D9A570 +98EC92E2876DDADC2AB52B05564EEF2A64AE2327DBD80795618500D96F296E178CEB3042 +F1BC49CD8112A5A373D6A72A8248DF6D682245A134FCB990F9FAB1CFEE41DCCAB9CCA831 +2B833D6D21BDE04BB26F445093A8C7334F58F3B0FE626C0832DB7BE2EE788357695F3B49 +FDF2B8225E7ABB6FF7A51EA4F03F3F4CA1BE00F70D74416FFAC47C4A8480D12FDBDF2450 +5D53A882988C5747FD8729FFD263C88749AAD3FB70B064AF33BD21630FD5853FC8EEBC7D +91CF02EAD8C57CE136A4B223AF4BAF7D7C08BF31F1718318BBFA9D416594EBC59E8D0BF1 +A2AC0249835FC1C274065D9A28D0B8D751B9677FBE7D970771A8FD96700F00A13AF76158 +AB7437F5EC667D32D8287ECB8A1794383896EA4BD9AE047EBE471A9500E94C3B9EDD0AD8 +24C9D9DAFD1F058929D21244D81A276712454324322A3CFE36FE1CD8172F502F427322F8 +FC8ABF150BF749B132A9E93FCD99AE015F1D75D923F9743C23F0F2264ADE0BD0AA7C1C8A +4BDDEDE18EBA55BBC33B3C9E9204B1418D7B1CF592A5707805C13D62C284B991C817B643 +00FAB2E0457E59E07CAEBDEA55F1D8FC9F6938509E1A11168539B92705BCC03115D29137 +45D24D1533D6988DBDC21795FB59E25850B74A265C47FF6F7A548066FA6203C503BE4E7E +1590689F1A4F73B7B39AD4ED10D89ADA19673655EBE215CADBA0FBD85DF65326ADDA0305 +FFF9BE785E52F0797A345F8A49A58A704106EB220F88F27180B3630AA358BBEE6E27908D +512882ED69166A628B32F06FF47D9D05214A4C8728305DF287A48150F2652EFCB1B7CB95 +AD2746D2F4C10847800E9EBEF69188B770D583A079C79DA8D7FD9349E925E9A9A30F2D8B +35EE7115158B3B353AD7E4E4E740D93289F2CDBE6A75E6BCC8A0A3221CCE578D3A974521 +9C418768B4E332783174173ACAAC86FB61F81DCABA0F46FD3B90D46BBD8F6469C30DA380 +A5A356499394FD428F7DA46DABF232202A8A293B2DA79B4933D0790630A57DDB232E9E25 +4DA8C370F1B3EBBF9182C71EA3BB243DA9685B9B8C1DC22D73B3BE40AE56B08716D1F035 +586556DC0DFC07AAA66F5B3084B7BF87D0AF89BC6AF8CE1CB73B56A39515D44DFADEF15C +E018E31E7B4C61B109A6E105505AB97FB8CD2E53D37BAA3B1C2EC25DB055D87245A8BE47 +94A6E03B71A5F1D13B6E5A7E6C5594CAFC6E303CCC61E01516262F9BCAC1B745EE5B2AA8 +C0E8209C20A1EF19E93222C31B95E4B4FCD0F78F7821FE995494A98BD756FE546700A590 +FFB496FF6852E53470E1A5AB253464BDC12CFF3B5DACF8EBB0B99E822322F21999337A6E +5E849866939D87B2F16DA93B9F8CA7C83BDC49A4F8C5EA64E8F8A1C00E0BEA534C499C84 +4F39E38A06EAA1102A1DFC0E25643EF8A6245427D8E77EA2AC7B352463671EB6DE8571A3 +84D98E1B35C3213F13132FE76D03AA87E5918FE48CBCB8A2F3EA9B1886BB540095D97BD6 +188DA701888410081B8BF49C7043BD8C48E18A51042E92B542176964E292BEAA06E310C7 +FDBFB496D6B7BA5B07A1D36D516EC19C37E1DD06B9F6F85BF740D26FD0DFC09ABC3D4A11 +CEEC922B651C147BDC3124DECBABCC8986F5D48556CCC5AF38F7EAAED9D719B983DE7742 +67F8CEB3302B8CCA7DB832794C3C4F0156E72BED47BFA0F7E4B25E13C0222584601BA304 +FE38C5E96D3B5E709B6F5FBC623FC9BC36A4C4E8D82452D260F13186EBA95EE4DB5D4ACC +945D0A3C5C1800C1D3198D509F7B8ED0A0E33612E25B9344F1D53CD949CF9F65463B7C58 +4E12D78D3E6CF003F9A4185A37ABC6D5BD7F331CCC01540452A36524DBB34EC2FA260C07 +824D76439B0059A8127F940EFC1FF165005123C6B43C9700034D5AB9C7FA1AB62E9FD91D +ABDE5F3D5C03A771B0554ABE655545E133AB8C230517D51830492F29E86963AA55E9B79D +79013BB52D623E660A4D356C293233B79E7263ECE8F8B6EB3E56C82C2051111F49D45D12 +5148AB7554D601BEAA3037CDC84ABA8825658A09C008D19163FE5FD06D56D1A687EBB6CB +1C9812EE0E765F14077116182F67D3006048F8BE549CC71A354048520E66860A0D9350A8 +864ACEF55EF91E17EFEAB4D6266C9BAA1D6D3D309073C9DE287BC0619D7E37EAAC4B7CDA +D320D993B7B8F387FB039AA7E1F84AEF034E7845A1B1B5306AD8FDA2834B59F18E6F1A09 +66221CD9531258458E428EA237FCC45BCBB9C5DDE72061FEF2FDE731706A4C92E5B0B255 +49F60FD845C45D940B4C5A4F38740A40DA356A56B8D155477C04A26B747941180F6EEC05 +A5BA892A0D8E4638A812BC405E2775EC3A2D0E3C288D0DEBFF53582FCEAC6936C152B8F7 +6F9D556F2474BF5ACE2B63550FB94C36E29A8501CAA4C22FDCF908C62012639ACAA7619F +01BF96A552A662DB5664E1DB1A4FDC4E5E9050088D730C8E1F387CBF93619952DD8E23B1 +4A385AC6C222AEB44127DA14539A079EB16991F0CA2D851467828C23A4D524CD5AD92FF8 +0439F6F47D703E9BBAE227628420C2DE818A9D2A6BF085B5262E026C7A04ABE831065F31 +68772805AAA986AD811CB78F3FF8A0FA7A211127BDDA087C1459520F9420CB06AA4518BA +A8935A97BB88A62EC76AB2990D8D414392E31C68A91E9DA122ADC8AF3BF4CE550CB1D22E +B2DC916E735D19215C489BD7B62B842970214B0D809639706303AE7CA8E270ECE748D283 +A8370B4F6A37092EC768426FDAEADFADF8598591AFE55984ECAAD3177973A78EAD02CBC3 +F7DB13A7864EC1E7A68ECC54EDE88E7A62A4AEFA9DB238BAF1A22079F23930CBF7CBE82C +2B98E37F28A47054BD47B48637179F4C57164B26F4EE0B484FC8692AADB29EA0C770C789 +8FDC78DD58B009B4901A678305A0DA4E89B2152A596E13FAAA822DDEFCAA30BD2FFBB1A3 +5DC54BEB87BF96E4C3D25334D86761D7D78C50D71DD13BEC2830A96761CBDDBFADED0A3B +6A0EFC34F96CF540E238410D22EE85AFD0AF104A624D3F9EE5F04D9D8805D7BB502E0223 +AFD0CE95C2B32B30030AC7385BC898C282A5EA204957853640D4BF963C97540744F4D888 +72006B2239C9EB3390FE16B4C3415F6EC97827597FF791B3D1B3BEE6D0329604ADD0C131 +6B24B8544ABAD72B337F00B8FE300BB4EC7372EFE3AC8156328238B94E66E1EC7CAEF9B4 +D58DED07D9CC777719E2C973EDF779310890AF183F94254B2CA3277120A03222FAD58E4A +ED28AAB3DA49B5ACF246666A597BF2656CE2960FC95BC24CEAC5431F73074538B8715071 +FF284765EB54207CA22596B3BECAE73DFC68A4F9A287B8DE7DFC27D0F860771239436FB2 +587B07C1FCA6C74A020A819701431808AAB5B6291992D83DC28F2D943AD0DE2D94BEFBE8 +A15AFEB7057DD4A97B4C172CCCDB490E6F9FC265636A35A2DC556648B5F9F80D180FA320 +AC69A0A61A3954BCAD612FABC12D486A0F2FF0457073F61F2A74345B1ECA9DEDCF26EAD8 +D02D3F4678C7AA82907721A828984C6196464440B2255DB9171706819E0BCB7169EB6722 +912EBFDC6CD488FA34A5556F28D2B448A7187B1E15255202DC9DE4F609682B0B6D2F61E0 +4EFEF15CAE39FD3F6F7B32F226C759A17E6C611BBA79D93186C853BD59D73B19E514D770 +89CE29127F5B36F1C0D661597A6FBF85C15307F624630DB6564BC755145BD19088CBA598 +86B29328DA2452957E306EE08CD942AD6FE6697231EB43DBD8D37B4ADD0B4D8947A057B2 +1D9A133A7DEEB89C1D35B3F49F803700CAE8774A4F9BFD45CE309A4342E3B7DC36B6F76A +7B51A81B70E038E3E4999D6EE027DECBCA548FB5F4DE4C49981D4617133BB3E0919C4778 +B80894FF4437120F1035520C75F882591EFD511B6F47C166C7663EA2DEEE335DB1A3106A +5FE0C49565C2AAA0BE977DB611B07D38DC41E6DB8F959798286DC0CE835CE64459558D4A +20DF59F2E8A63E2DB701619617CE4DD55E82EB396D5D701B691533D0B20C3A0C20F5054F +72EDE3BDC2393ECED94EC52C25A755B58F4E2596702FCA68B64DC554DAC85CFD99478701 +BBF2A47966CF72E683B5934F0EA5DD86F35B1556026AF02BCADE75ED3C579CC1D9430956 +9A53EB8ACBBA2551B9BF06594F66229489319F5A5A94E51281FEF7BE86AF12D8A8A1CF43 +04ACD3B27D6B9A574F09E2C41D245D8873A78D1CDDF4CC88D96D9F714FEDE70ACA30B83A +797AD3DDA7D6E52A5AF906CAC560813DB2226BA5BBEA60932640ACEAA2E7B2D412068A2E +49FE781E2544FDF8C762D947871EAA0DCFC183676B5644AE02DB3CAFABFF140BBF755966 +C9BD319925746E320AFD5B157C55E3EDB4D0DC3FA112964D68BE2A5FF08E8B31BC9E510A +F6CAAFE84C0A103117913E2C9ED8FEFF96B941AC14AE07B1CEE2308E36F617DC33CCF32D +3A52F4F6561A784FF2C1144625133FA8E30F7A86E82F675F1EB56579077EF6AE086BC2C0 +B389CDB5C5999A1FF3E51BF766227A03DEFF391312065305E5C3BFA97FE7D5E2ABD0AA7F +609D8A0E524F99B416172F7A0D174196FB411F79A7CA6F8694DF4F5DC48BB58F39460131 +D47167AF47DD3A6AF1E12C75D947F4C130BAA07174DC577B49726123F34FE9C76411FE62 +8E354B43A5F54BE0F210C7523BF018DB36CAD6DB8063F14FC3FD1B4B69706D45E615C3E2 +9F4E1FF8943FA55F1B9B4411BD0DFFA260664CACF3C2C3D9CEEDC1274B71805FEA88C3EC +E5BBA17D17E6250494278450141FD4A514CE968C33093FE07E64F168388D141E52E46DFB +1E2A9F4BB5132C1E6FE25245FBBB3B1CB7CF24FE6A134382F9863D4683AD93338D3A6726 +BAC2C4174FCF4A523453EA28F2095CC1159AE0E0927380C93DE4B979E26D56881A2647FE +0C46D0B6B50B0CA3750D6974A8DE149E252ED68FE33B26E2F04F06FE6C3FEE1E7FD72C05 +135DA55508F10522A7A2D8AB07220E73283F978B50D75FF36E789094CBA1A8E342428B89 +3B9A664939AC711933A2A1C425291A9E95C396879EF54BB6F3DA82E88CA8C34E9CDC22F1 +BAF6588CD3C54DAF5A7873501EDA6A25B793F219D3D229F6A028D34A19A9ABEFF2AAE4B8 +E62A05421D9CC0F78E2709BEB6133A0708BC174F5D745A6CC53E6DEAD27A1E6CD77832E8 +87935BB8736AFA3736E4B4313D6D1B7EB464A02B0C6DC3BC7C84630C2E9DD020AF3F6694 +90BB8CF0185DF9239E0D27B20FBBA001DA7C30F0DAFC8AFBF45C02019E4AB0AAE458B083 +1051F65D0E398A75F52FC3D617A25CDC2EA1FACD7113E0EBA0262595AB5EF65C1D54CB71 +BD87CC35C9BB992E0A63ECB8A1448619148ADADB906DB75076E0DA42BC6501F6B6717C62 +71E3881CC2D6747D0A0BC7B6B982CDA89E2B9D9870C96A86D3A4E1FA0B04140131F302D4 +A36AB220399A6E551FB6051283E405556A1591E402FA9F04B87F1E3C2AD60DE3128EBAED +2CCDAC808AA1CC5E64052FBCDC1EC710A3551B3AD6E21D20FB112543EE0DE94DED4DD8C8 +6526F470C83B1DB3536D6DD8C8E021B7A9A82C23A31A6F09E15BFBBEE0A8971B3F471437 +F0873BC669016F219A728510C712415C515D3AE02BAD8467A1E0D911448C0CB280C70F26 +14BC2E52782C1CE5E79C783BF880D1B914E44FAD64E140666274D68560DECA2194D70377 +4EC76B35669FAC269409712901F0D3555B60175AC7799E31CAB70D06EA8D9C359C9DB9B6 +A3E02F6923C498617C041C28CD7E57486569429C3E4C89944E0EB150813854E3C2EEC4D7 +37E2DBB99287ECE4279F3E0D9D8EEFED11867F0E05E40DB8858CFC5DDBE873A174D756EF +5D5E0D5F251F0FC0BFA7F69EF8D20E34B1B3B5D45501DBDB453D82F56BC6271C281A8A1E +7D0D8C9B920256EF07F4AAC8FE2189485089F52D024BE36045E0BE613F0FFFE13D223B0B +2478A20B98E76A783A98E7AFC642AC9CB333D6D39AD4E08B2BDA75686951965AFEB5D211 +57CF3DC3B911A4E45144B3D9D4AA4CF13DA039CC95A9CC8DF44CF17F3D09A1823D65CD4B +29E2408B1C3FC6C1F3980378E1098255136F0D4BF90D0C4C042F1C86D40BB762E72C7EE1 +BC530755416A0DAC2B3DA0E7BEEBE7AEA9A39825EDEBD6CA316FEBB14C701BB7EA4F7800 +3DF2462E2E429FFC3EE8904D963A0017A606EA0E526EFF1E60BF825B2ED9CB42678B6F6C +E55A893A047A4E5E38F15349B777566334153DE574290C6043694C364A3CFFFD07180F5A +44CD991A0535D13C91FA1134BC457A455022614F3AFAB921A70603C47C96B5E466942AE5 +83621BA1544F2AABC4CF7C6E8B77F52FE39F5798E2FB9F180E3C86ABAC210C57A0226E38 +75885E3572BD47BE016C361E84754FCE64AC3345393F511C99BBCD70443D497D575BD81A +47373184CD09ECD9F4A55F1CB26E921A2B8BDDDBC8052EC0B8CC812CCC2353586B0451B4 +791EB68293CB3B4C41B46723D2F138D5BAA8AA4580A5660F0DD13F25BD665D4994908BBB +74182C783EDA6C5187C32B7D5DDACE8DB1571E7061A063AA56DEE4B0B6F5544437417E0F +5F07EEDA1263224E5E44B83CB057BF54725859FED215E5B528BEFCA470C8527F40A09AE0 +20CD42E31306D1E9095137CB6E7FA08191BBCD7176B87A372A97671B9CC090936EF7E4E7 +85F1C6B541387A701828AD82A958C34DBE426FB12A03AA3BA2C97535DA8526164DCC150B +67442F7D6765D16EBE7FAF904F42A8185DD30DE284916705D3D8826DF1D37E668F9669BB +343D3200509218C5F929E0DFAA7FE3B79646F62835C808BAC29CEF8CA6D8363F0AC7291F +E45A85DF8F0B9FC14C7182170AB1F51D9D9C33D8D98713CBF0931063EA95EBB031904EC5 +7FA914B7D7B254C3B178E174F807269B2BE5F340A3674FC03D7550017B70C0E53472442B +3FDD4D1D45437DBC5AD56D690D9098D9DCDB17AAE217F73B54BA5D965EE197EEC8823FE4 +783FB5A4693273C7142728AD3F78946C0A8B7D3714DEAFED570BA2A9DF9240B61ADA22AE +3F9B21FD1D73D4A474EA14EBFE6AC82B068D08EA2988E7C610EA5097B62DBECEDA5278F7 +27824E5BA9EA442B328C3B02E03C88511DA9C72A271027176EAC2C7B6392E9E99D8B42E1 +2CDD9991E43099C503DA5FB60E5D4F8FD3CB67FFAF46A1DD243D9DF13116880E727A9271 +BB778126C01AF95B75137A0E3831BFF257CA37DE0B3B4DF3C983D091F09519365B2B812A +0B6273D30B01515013C73AC3B8D9C4520B5267E734651E013B8002D09F3B5BA7984A588C +F6115DC9EB84C1C9AA0CBC9777D8923B3230E0A2963E08743E51CDEEDE33F7DDB10AFF69 +BAC8682A2B0885B8059661599B805B9684010A3B6DA56E23E265BC209158D3ABC69BD6C7 +6B13BA17F225D990CF0A42C1A37A5EC523FD80E60DD542322B42202D77F646FE34DB9AD7 +9908DF03C1C5C351E542294D245E1098989BCBEEED311FC5E7C8ADD52E52BF6F0F1331DD +7F874B30B0A16484EE328FEBB0CA559613500BFE6994EA8357ECAEDB310CEA3235A421E1 +85471BFDAA649E3CC9128A0409C454B3C951FFEFFE648F1ADAA14D5317929411AB7D78F2 +B888B63481346F415314E1967919783F8D143EC05B7BC2D5D9F7315F41F0331911FD0018 +44E301CEAC9579DC227E0DF9FE2D217AC8D7B014CCB01DE9AE852AD42FAEF07CD5CAACAC +324F3C00E330939FF4B5B677DA731FF712A6F8A10687D29A296B0E685A4F52F3009A4608 +8A935788703C71B584A8E855683278077851E1416171568CA50BCB4EBC8DE6C952FEC45D +37FC6EA2EE7E151A96452C332221961EAED2B6262431C4C7BFFDD59EAEB9E3DBB17C3EB7 +3D90F0F872289F8AC482B4913C0A05E698C91682C37503A38C841C25A8BA855E7C1CD3EF +5F1E025E58B2EB4599D76DEF57A60CF24E814B3166042F8084B08711D1C68DA4110BFA7D +E8D3FBBEB3DE32CD01E237A403F8581AC2A015106AD81FA0DF90301D6BD887631A83623B +4EEEBFEEDA012BD6C504B450A5F43137757C2EC7DB3662748B105F8B22EC030895E0F607 +5BBBF246422A7D0D6E8953CA66170A8947034CD6EE37EB7BBD0D9F02A538AA0F3D2D2076 +8C307F9558765FA715444282C823FFA3E95640778053A383886551D4F86D490FC156636E +A5A3BD258674262202F4F76746ADD02FE0DCCD540EBD60EAB42D01FE252DBEC93598D6E2 +0312F2F4704AB003FF956FDA5C2A88F716A4EEC93503FA913CA019456AD0A8F6368CF6E5 +AD1B7CE1BB20BF0CB453379DEB3423B0649A6380ED7D0B40768730D37A9A98B2339852AA +286809BC86757FAF3DD54C18C3CDE9E72FA874BE9D82655E0551DAF13FD665BD14DC7891 +12FCA109A1C73D4B0A7F230E2F9512D0DDC8029983A1984406A5F100567B88BA186329B5 +7A68539D43F67BE6263EFA278181688FA595ED3BC7C7483C4DCDDFFC01E641C231EBD842 +D21B48105397FC32D6A8D555015760029C2CAB13AC8D603CABF46867CABA01A99B95C92C +3C224E8F59B3B327A01AE685ACFE6D67F28FA6663F6E47466DD0A6665592546D08AB7C5C +EFD20D6D5115C775E033E0DAC75F2C6411D999DFB21172A8D0D3E427F768CF7535320DBB +6053BF3A17536AF6B2C00979FED18A593F71146F9DEA8B31639AE0586B24763DF3469507 +3D1172972B5E1CB82BC46A60ACB82FC66B05D9228C67F3FB25E2D91FD11B696C9FE505CB +9BD2B2D85D3A22595C338574978048050FD13A59C41B3B0CC2868DE4E017B53935793DAA +3F6DABDA50B06F8141511C3D5093069CD1ECADB90C42431B5188D912A5DF033B633AB3EE +67E4943935EA094071001B6F8FDFA00C0E8415358DDA77F2DDF4F7E2694CA6933C804849 +54A1DB8B5B6FE3A7A970DAFDDD1107FBC4C596C379881A6B148D21733CB2700FD9F4FDAA +6DC49C40A6675C0284FB931AB93CFDE9A94FFC23BF259230AE1724F22485864833541367 +D274CE18EC890E4376F48144950FBE566FD285330486F5F23BAD7AF0A636821A122A4970 +35D77B580B5862D776826AA3735AEAE9D5D7D04C4582778F9B0F713A906618632FB653EF +4FEA9BD993D11E0E51FF3A3DD50EFB462C4251A42D63863256FC819037BE597382C6BE60 +955D060340A268DCDA514793C845FF10EF0C72D6FF27BD1858B49D50516D48D6FD33AF71 +11CD37F5F7F0C4A4508BE16B80565557D025B529ABDAA2850E4EB6D8AA30ECF49B5D18CA +AB0BE944E0B95AA0BBE9F4CA91A56FBD41983A6703FA0FE415171CE8C11AF45004FAC49A +4346C206EBF58FFA74F22D21A1E069AC9DEBE6D36156C32E74A4ECD8BE2C0A6983D404C1 +07DE0A75C732AEA64C88389E15D474F8C0E7789B8707E2F46297012F4F51D07A10794D03 +195654BE0F7DF9A4F5F102C5A68CD37D129051620F807301FC8BD8252B4CEEE5EF78E803 +9D41B48CD3262419E9A4F93B678B9F471F4B221E7D165C1D2980CACA79F4E549D2ED61B5 +02E583516547A49E2804F1149855D77A0D86F3B1B429C56523FA773FA9452CD5B6340E64 +B04FDAE2E5B6B234D03E87E2FD39AFA134265000F7A9506F55505874D0B584C504DCD29E +CCCB8D71485AEC7BC34AB30453AE4E3B2720CBEB6A9C9FDD7FE7DD565902C6BF2118DA3E +95595C12A7744212827DF07AC5AA7B1E05D42FF38758A3C3105C5F0422030BB0102A9BEE +0E07E20AA089C118908BD7207E686EDC8FEC0580F7FDD106F202676424FE815EAB287182 +61FDE8A17F2662BDC02C0E109A020C57C8F37C4B606FA2AFB8C0993E2CD1A91AE5BBF801 +390AB8EB8841FEB2B066F565E497DECCC37DFDC2581DA9AE15E8C215DC41FC92AEB57757 +E92E18FBFE36E0E6AF6887671A9578C318C7FF50178B32CC9A046370946ABBE792708330 +D1C370012CFA2BF4A5DF75CF019ABD1882566333B0E637B9935426FB127699885121D83A +4DB8A43A648A459C83D623EFDF5A60F11ADD585EFF0579C91F8B5ACBE889D4993BA6FCBD +64318022C3310DB5CE4324954D78F06ACAA1FA4C8C4120DD41DC4EE2CCA72CA36FCC368C +A31323A17E4CFB07A0A02CA23F8518CE8ACE1548FD4B67F0A5C414C309DEE52E5327E09F +4B2A07EDAD8A309C54DBCFE3A59B9BFD3174BED78566F6642916B5B01CF4DDABF72BAB82 +60EB5945BFD987B96B80DF607C64747F5344A27DCBF4EB9797BA5D17B7635D0D936833F5 +0AD01CF4B9FFC273C05AD87745D79BA436590D9B50988311A06EAF7CE77B5492A542ED4D +129DEF268D2BB87D07DA19ABA6D4F78874A0A6960C9934670B9EDC47102EF929581A8698 +A9CD8F43E4F071577730D9D18AC416AB398124D9EBB91AB66A4CADBEDE5043EDF627CC88 +C68DED934ECCABBB9A7FC34DFB1B65ADD724BA67DAAEEBD04679816733D344635D997125 +7B2BA27D1F44A7D7E48F9C9A4A412030AF12FB89B15B07C3B18F9C6EB6AFED69D6A9951C +3C1563481B46E4AE5841D88BF8C64461CEE73A332AA07C89414B4380D0CFAD8D61C72E68 +6B34B0EA660EE0C8370A99398D9B0166F8A77FF24BE1AD496B0C0E8ED04734527A5A8C79 +64F2568C9B00E98F7165D0594080DFFF7CE5FF8C26097FAFEEE33307E282858726E675C2 +4B4C31AD2B5B1B855B73D553E77D3320E4D88BEFAB426B94EA33FC9AD8FA81B6636CD4BF +FC2D11BD1F52BC5BAA38C072AB771A9A107554A327EA10452F9C7624BC2DCD6DE2D43EB7 +0298DE357909FF66BE487285902388A024E120D587890FECE3A00376884947E1E6334BBD +79B4774980E8A110E7BB841F9289805FEED0DA0F4D4B8048F190DE68517EF34963FA1BC8 +F8C575012E01C280B647902BBC2B80365E9A66E28EC8698EAC50CFDF1C6D113827AFEB9A +45434209C921460BFF483BE373CAD65640FB3A8B7E5AC12CEAEDD5EE1B244FC42CCE85FE +4D34FB21BEF3EA9B959B6DB1624F05ACA4602052A78FF842BB1148ED529A460DCEFDAE01 +6A10B5B3C9D11ABD14C53020138A9624F0DFC3B1E445290EDCD7F2DBF4BE408EA8EC21D4 +4D9DB728B76DA63AF62EB7F89DC43144028D1098287566586F195B124B89799E3881AE23 +F89DD6610230B09D6B8BDE79BA206B87BCBC18DBE1BC155862D28CD742C38DF8CC906233 +09F933D073491984DA9D927635800B84A1C2350CD18D962DC9A2A235E2443F5EA72DA9F6 +45BE3240B03AB4D9D95C3B57CA05FE3A7011E12B182AAD81B426BB17D44D5C1EB10959DA +01563CA2260F6010ED7D37609ACF759EDF8C044860FBE3C89213394F03A309C04EE231EB +FD84191ECF14A020C7A4D7BF855213D927DBD921E2324BBABA6B7A06D69B4271C66F4FC7 +F15DD52ECEEB76C4C97A85CD59A38E1CDEE2F78354B0B71155227553FBBAE0EBF0D625EA +34B78125DABA3211CA9CF1D4AFA909080061588AF14CB97BC4DCC1E1A0BC04A40B107318 +1CAB643F064192A6074D3220EE050DE3A56D1558AC0F7DA0E2844EB48999EE9409F0F683 +92569D7E7DE78F070FA44C2E8ECDB09578598508EF3B97FA2B585A163EB540F2E8290244 +D60006EF558A5CCCB1D40CDED1CCEBD665A320CB82797F38DE80CF0DA15BB0E13B8CC180 +9D99437A5B25041EF68916C6E601B0432A2DB84C8DE1EBE4AD5A3EE34249E47CDA593424 +7C9E3F3251C59AEEB48BE773A6D775E6723F3B2AA55B2439CF841E1C729153B22550BD91 +F272DFD3EAA1336E94C8AEE4DEAA00C772BF05FFBE35BDE7AE2A0EAFC33A71DEC72B3179 +E4CE0DBFC083372451A7006B32357B94CD7975ADF21D5977D10444C80257874005F8A02D +317CA3C38DD0F156F191F88A8BCFE274976220F0D25BA30DC195F5AC0CA478FC1173A7CD +2A93B482916358E8B0ACEC25E51F975E210C895E1200FF2D29419EC300BB8284EACA5027 +69676CFA8099A110D1AA50B5A4523CBAF5FEEE90B605C5CADDFE233D235E008667D7C0C8 +B2BBEE796F1F78F4819A201131D4399FF2CC2D59B05F923780E775A9ECC284A68A2D76E3 +65E687530B96FC564DD173613D190EE8F1E6BAFC238FD9642D356E764860855820937E40 +44A41861BC40DCC84BD6F9969DEC343DC6F3F7C8FE9342793553B5C335CEF67084B9F1B7 +FDC790015B7F9D682EF547C986CBBC0606E0DE60E95AF386CF4A475902C58FC382C5A35A +2CAC908457D5B69C88E95BCCF40A9B12012DB3F548C3ED3A549BE0E5B0BD17B38022F2EF +2987ECC4A6EA46BBFAE4D6B330C3FA7DB68F0695F7A52C2E9BA1B97A6A2FB6ABA4B8EC07 +5E01D2C021D66FD6E47A4014E5AB39DAD64DA85D3171D7398BFF397E371C483283854453 +4E7815254A0612E9B79143E83555FFAB3438D5F56CC1B72BAD832D3F03F49675BFF38F9B +8F1A89D2E739F07B2FD36BFEE46B0F8E22EB6F23710D0BA81F3B421E9691306ED6D87F65 +4FA8C6ACAA3356D8AEF5BABD5F6E6231E64A772C550212A6EB17D9EFB987D124E63EB266 +72F2C1C00DF095C829BA7AE2EC7C7C26FEEEF5C7AF6DCB1C846F6B6DBF3F7AA0585F6396 +0A27CB026B55B06954B296E45841706AB1D655A5EE4B774A336B137EEBB2AF2F958123A3 +A9649E57BD61EAD0FD1B05C16C1AAD5AC103C0CB1BE0DA4BF4DF83A7F47814A64A11B90F +B0E449D75637E8C8366346E6839AE374FA3A2CCF4437F3F4C21B3649E8F25499556971F7 +210B267ABAF315E8B1D2120AD9D3110258BA296B3BA195931492AB8A28F1CCCB4AA607D4 +7DEE5BF92546FCACFF9D9243B8941D011F272431B2782CACBC99D9BEBC4CA43C90864DC8 +4C800605BDC071902BA524866FA1D98C709BF9200EA73C2FD8F41BEA226F37947CFE0B83 +1BD00F2237535653F63AAE9A6484A558FC74B7475EB0D895E62344F509D216A97B96B466 +24B8C4CDDE55B5E76D06AEBF9877562210AB2113912A2354E60C6986EB1077526250325B +B926BEACF55EB2D98858849EE63A44003D3FBDC186315D8AEF57F8F829EB61C4BAB6C9A6 +E3626F0F3D7E6BA066E31D3F322D060AB9990A619D26BF75C261C69F2B88A9C28C70007E +9B2C08AA5E8F73D00BC882F3680CC9A78E6D70DC8884A65D53E86B6A4030027F7D403CD5 +6106F3DAACACCBB4481C81FED3B7A711B04F016E18330367108EE6BD1A3121A9BD33EB35 +E824BFEE0D128D00208F3E1C860CC99AC8174444D75DF99CDEB40EB09C20355DCA68E13B +630DAFABCBB6BB51FA406C924F40FA40E3FD6DA0C673DF1A2F695E8EC2127D51B6F034EA +E96345AF0294778C6BDE553B2A9578927C484B51B4566B120F8A074C52318F06033716D2 +563658FCE1FC71C655D3319E3DAE16886B92DF451714283F5C1BC3FF960295B947D0D3ED +1A101F34565F24519FF5E7764E3C5F2304FC8F6F313CF6864E09FF079C93167E654A7FD2 +4F6550BB972F93C43FB9399A0E82D58A43B926F454F38447110891E0011904A776271E60 +FC7AD11E984AF84FB551AE9E7CB68466AF9AD82FAB71590A265A08A58C16046254ACB03E +98EFA92EF2EEC42B4733B1BD9FC767DFE45D4E74FE31B3EA3588746D5A6ED60F874E7C00 +88E2E423BF78909FCE19952A9BF46BAB57640CE2478015C7137D87D722254B3A70D848BB +177F0926A2E8DB72506A41C381B6C9D9F4B22700C5AF711F5EE5C7C1CA502483DEF489EA +0EE03CDD50292460C7352EA9B5B4A50FCA148F7FB3191432787A1D4EE5AA9080D95B810F +B13F5267F1486BF1A49740C61E0C6C885E3C5B9B28534CFE99F9C656CBC3500DFEA2C3C0 +68DF8B93243857CCB6D50EA01222C1CD2AC256063A27F29969BCCEB98B677F10FF3041A5 +D78B64EB9034C4D2B3EAB0BCBCC6C3A4E3F9F8EE0BC45A934C97F79E3ED5B9889285F535 +7B5AECE08D84E86C95B68CD40E4D747A33024028EB6D6CC22D05306803C5120BA4988696 +F91F4576E3BF631FE32273E3618F378FE44B56431230AD82B5F7FAD86941DFB3716D4598 +C9B3C3B92E0839F583D28577946992529A301525F1D784C6E8D21999972522D79AC7072E +DCE82D02F952750C4EF7BB486F202D22C5117C4AF3C61C182C177BD247A4F58A55764371 +235A5BC43A4BF5F2977EFB2B293246BB9A55B4E52C4CC35F4C5362395B69B56CB8E21F4F +230A12741F10EE5869AFF80FB230EDAE5BACC982A7B715287BE10A2C77CAB7DCB986463E +00C3CF475A746BAAF746FC1657BFA756A3EF1C5721A9E5129AF438C17CF2717AA26F3B55 +6E16EC7012EA595BE25CAC595AD380BDE9357F70CE740D44CED744EB001FA180E54CEA76 +A0F33436BEF0173CFBE3F450823F53702405E39AA9AE532ACB2D87F94B89385941573FE1 +B00E96F44433409EBC3B007A2BA87A026E9A99AB844F0826F837CEAF0ED515B75FE083EA +47AD5BCB8DCE6ADEB4DEBD9DDC83554336FB9B23FDBE3E9812E8D388DA8036B2EA0F0544 +5EE65BD22CEA0325423876C76D30F77443A1AD4B8640369327DCB70945C94E625CA480E5 +D18DB76FF293F7FB61730A67DEC184BFCB2CEC8A47476E40533B00EACA213C3A9162C02F +229EE91BAD96D2E7FC21930BA22596037E2BAA35AF874BDC4ABDC9DF92F2CA2CD38C5626 +4457D579CCA2C2D9A69E72B46BE5B19789934A526195CE74263C4E4EE29AA0F0897E1375 +F9914C3E39CC8E254031F58F1618565CAA96AFC2F8636856214A86A5BDC3B48F05FB5391 +797D5A8DFF2793D1C1346E54C7EE0E6170C82C5F826C58E46902D7AE72F4725410FC008A +D1DBFF2B0F6D269D5390F43663AF29E2138582F6B223C0C577428E2E320AD6E2D8EC8F9B +28F4358A71590309F5D75F86078B95A66DCDE939BB502BD0298E6690CC33832DAD2F7133 +EC7CBCF9EAE3134D91FDEB4BC8C98AE7C8020BF3B3D88D8F207880958F1DEFFD714A947C +1E2A6DBBBA6E150EBBB7576D612BAEEFBA83E85F20F4B5FD8CA126CE2E063A87005E4FC9 +4DF19C2EF01DBE2B45D5F255152BDB78BAA8506BA36190DD155AC40D4448F0DBB3A0C0AE +FBE24ADC1CC30F4E1412CBC6CD52DF405A4252F8557E8154730E483B8541E663E0BAE8C7 +816D95CA8B6D800446E4665EE726DBF0ED62395CBDE723ACFCF0EBA7D39697EF738A6F21 +CF591045F1CA5C3E68C2CD77143D7F694A7B9FE3348F70719B0F7D805E1BB83A1AC9F346 +1DA81E3167465C8ADDF6EB04F86193152EE00970D2066F79B191EE15E33606D83505C36F +9E8B05926BC156D236E865636E459EB06DC8A9AE6BF433511AAF8B2F37F0655488CD800D +BFC43897B1028A659F689618B15FBB801F303FE42402DA3F49CFDC8D03E5C28249400DC9 +44596A2BBF7F3BAD818203685C7C1B13C05CBB7E86EFB28B6C4D1C9D46DD08CA022E54C5 +4C6D84E0B15412F3BB3B7CFEA7A9A06BBCE4C69157ABBDD52FC5FACF0A23A53953C35191 +8379F3FF2F3BF089CF82158BD6E7013F5DC178EE34C55CB37A84C98C2F24A64B34978D95 +F82760C5382AEEC5761418A7D75704EF2EFA8EAD21B8EE44B87A8FFC59EAFE6B2CAA3D90 +CD2CD737421FEF85551E5E499847EF4B9D7D33F72A9B9E739CB294A16041EF1FAE98F726 +AA1460D1C782A2D3A717F925B4AE0E1A32FBA63A20692348F7BCA69DDF3FC0BF734930BE +518FC35FE0DE9F36E6C6AF15D770FB35B68AFC513969D9A0934131FB9A0A60B351E38659 +E3D6ED518CD1D9BFB40A16AC9E77CDEF94E5C3CF0FAE13076F4BCE2841C7EF7E0B364A1D +5B932335CE17861FEEE20D02237AA90A704EB6B74477BCA3B8BEBF8CE59E19E861832F0B +950FE683E1E5C05547F00BBD3478125768EBEADB91C6F3D2529FF871939CC7C10D0F07AF +58FCC9F8F9538870C3559DDF56BD94B5C1F239E44324C68F756B33989B482C45A7B78D76 +6E95E12F4E8853A430877E892A392C0228C567BBD42BE2E2FFA7F27578842D7B5D05B799 +C080B6E55B53D196FB2C4CFD7BF64115742FFC49465B2B62D80E877AA7E7D9D8811327C6 +6DB937B48FF75E410B5F639F02774678625F24CE25814E5718941D731B2F8F52A61CCEEF +66D7A63A4D74DA48992E4794B453734C9C3CB488DFBA825C094CD8B9729AD572DE4B4B7E +557644A0821BFDF2AEB7BF98C740C6F7BB79E0D80891BD9926DA4DAD346C785B381DF173 +23760CC55A8D050F73E8B8B751438037EFD9505DCFE058874FDE5AA5DEDF7B0B1978F714 +3F0981B964DB2F7A55B97C7ADF41DC95CA295C8DF2858BEFB21B94F5957715F982BCA5A8 +D6BD438C12C8E95ACC46E9720C7AF8A61A1D952F80E1D65769283FD18C2ADA03242F333C +527384FC8E5FC02B32B4802A8AFD6A0FBBD5678CAA927B5E970CAE60F72773BB4CE9E49A +0455728B49422E2AFCE32DE8528696E6ED42B350B80C39BE82CB53478FD8EA4B63DAE5AC +3ED27E83AFFCCC52E65675EED25001048297E293DADC529D37B5BFAD0C659292A7D89F81 +88A37651DED8312E33EB4F39EEBA2102712D108E8122F06AAC04528E3EC813EBE0D99EA5 +72E4EA566ABE4FF8FF53362FA3158FA52FC599728D97AA69A5C46FCBF2B0B75D2704F9E7 +CC7CDCCA951FE69E9C2B9B448D44E82D3DE480087E98D1A580354D4D0A8F893DFB7EE4D9 +30990BB3B886A2F0AE65B2F8C5FB109B5B7A69886E73E7883783FB030DA933B5853DDFDF +EC18E867FD17F24DF97CF72D95C7EC0897D20F2FAE74A9280DDAD0497CA6D099FA350C68 +1A46CCBD7B8E7AB3AD45658B8F8B3DAA18D6C5DF704A51DF6F2DB5F7FC218980B65BB446 +99569FF1D4081B16356114E4E72166A09ADF09827750DFB537E9F3CB07A29E2D4A435579 +8F9FCFA874A4772D04B7AF6306A75C68260ABCC1B2F59C447845735F8D9557A97635C2B5 +046B8AEC2815C5094D918D67638C10C7820BBD26EA458B076D5979E4DEE7DBD341097400 +2DED95CC963CA2D607FFA38BF2F6175E77ED9A8ECE8B81EDCD7FD6470E63E48A68C0BF40 +952AD9C1426B3FA70F59D03F317C1484FEEED313A9B21DD3410F3DAF2D664C8176FF63EE +2FF4D366A2E12AE43B34039BA38EF175253B582F457EE300E0F4AE056909C751F8E9F889 +EC08A1668980672230F7564C28C98BE3021A863086442F0D1B0169F98CA5460CFA959A93 +61E44F39FD8F5F1395C18B9DE0DABFDCB82717E34E836578901B33EC4CC2AF27E94609C6 +D78FDE2D2EE6D169036CAEE5530FC220D59A1BCE8DDDD67C2902E53E21493FF9DF4F06D6 +0787A3E6D31507E4A924BA17142C4421D2B87ADCC7A1D0861607A50C49E8359E0BCEEBDF +BF997E7988B54950D1B8104C504AF8B321D155FA250380D4753C739CC0C2866ACB76E1FB +D3A7CEB9C6DED0AEDCB16CB9C0FF78FC48A3B7B9CB117DDBB3F2EAFCA2A9462C3F125163 +6D130D50AC1C2E4381A5E89C22432DA5646E4D7191EB57F78AE5C8C63190C8A350D7A084 +54619FEADA6DEB239AC9CF577DE28BC967871FEECA21CBC24B7F5BC4656441B627A81771 +7B793E36D510ECD9835595B08C54504A35DCD31FB2354A2E3B9029FF9586BDDED0E8BBA6 +C0DBBEEF15BD4ABA2296F949104B44C7AF0FE063A14CC8498E52DA2497EBF940DE5F6AA3 +3788199C9ABC1A3EDE12C4CD6324EE6C6856BCF9C5B009C150A304BC37ED7581BEF3827B +ED0C87705C2EE399BBC1A2888BB0EB5BE6CE090C4EC75F44B77EC20C37D890E9225CA515 +0A3710734549550537F5E097610804FE488C0E67F063AE0B685D4AB5FF167D9462A87061 +3E240E17905E7A47119CEA30BB69011C3AAE24AF76EB189D7BCB06EE72CBB7C1225D366A +661A2DFF5F3E9E5C6AF1D81553146BE97DF02DCB92B690BE5C0D2C44E1A57FEC0BED0149 +9A6D08BCDC64AAC6568A1D3045616E470F23AEF55E642FDF155842FAFF49EFC7F6261F25 +662E6373E1A107326EE123240146DC3E8A7BE75E51FCB2931C8F42A6E76542B763192B1A +287CF88D28D0C897BECC7924801EC1D7B7B7E519DF69DFA0DADFDA635C9942F0AE4DA3AC +B6F1EFE8003E1192DE4EBB8C0656DC6BE46462C97C02B63B7A660B12B1E169416683BB75 +DD6AFD649F97018C8DBE0D4CA139D964A7FE98E7E86EC3F4E846C3DAE736F4C348D39E35 +C98D98B96E6A0436F5B5DD9ECA1DCCCA921879F11D42512810B55584A2F72607D20F801D +029534B9D3D7C2FA984005D00398FE7E549CE68EAA5B2B21D87EC383973C2D7A3A095293 +A510DF4F80074C4919883DF6091561EDD20B440E6FFDFAC0895B3D4EA594B7396B4B3AF3 +78559044AA7863D818DC89064CB7518D7448C749E66B56F9914E538EEFBAF56FE087CDDA +AA59C8A6146C282DF632571830B849A87E0A1089979BA0B38911386EC7834B8C3D212224 +D76CE946A6DE2B2C246A92CBB976736A586DAFE1B3D62DA86B7ED2C92D1B852FA2DA29E5 +7AE135B93A7110018E0968145A18CA917354614CB1937AD9EDE813A70B30CFB5AEBCA5ED +C158CF63704ACA8275356C4837B9CA53F4BFE2718FCD0F4502F90632E5F65FBB14C56351 +21B5A367A979E1515FB818FD72D9AE26CBDE09F79C244AE16E4AA13609878D0DC151915D +151AC0844AE2CD57426FC916E920ED93AD36F9412EEEDC7CBE6EDF7EE7DF16D52CE0AF4F +2E5470517F51B4D4DC734AE36A66D44BAB9531B8E2AA28A811F08F4283FAF1394E56FFC0 +9BC31790081146224C8A599F9209D59027843EC5C1DF4C9919B0513050868A107F9B48EA +8D68EDDC6947CBD4031CAEC69E35BA5F7F2CE967A9A645B064059A523A06E8BB5F33CBC2 +70D056A003D76AA7BA382CD149BE61990747C75F16D48EB550EB230CE7A87D8150AE1352 +C3A828660FEC741DF9A0F41677F8ACD0376724B7060B0DEA0478692B3E3EFBEC197768B0 +022B89CE385C383C478221B9128B577FEE85289F1AE5680F3F0BAA120916102059E3EB49 +74EE47955A35175C55EE172D41B79D47A1D69B679F08AE94B8CF805744C571B87A9B53DB +2C9F9573FE047343039413D96C6E757C9FEC200EDB3AFF4D330DABF5F2FD5A165C137BEA +4F975CB34D9B372E543A61C95408C284AF4ECB516028144A64CA94CD5B4282257E8820EF +1CE2CEFEF2B2254C7555950DBC6CE5E30176DBD5DB8DBCA2159961DCE778A703908A4E01 +BA33D7645C00261888C7A63D0893DB6EE0BC2165F002CE8B909264173D563EA04940844A +F99D5750540EA9AF7EE79B37173C4150F42CCD60053870250E45921EA215D6A318C232DF +9000542ED5479DCAB19B839D4F2BC2871F552FE440D7EAB59F1E46130D45E1322D1EB470 +AD5948C18BE73A0EC5028E37D6E7A0D2B0305683D244FC5E80207825FD8E587A74900042 +9C60722A87D9C0D96B32159A5E00120A9FB93A5F49014C86ADD51C4A1DE4D5120DC04763 +136663D080AE9A62F7136088200DC77777868075E545F8AFF504E55024DA59E61CC7D28F +0D2CF46A746EA11F9CC96E28A12F1C4E208D77BC61FC5F7C32CD6210AF8D5167D0781F33 +F55EB7C7BB8DCF35FEAEA7B268051C9BDE278D9AFDC8B1F832A96FEA08ADA9EEFD8B4D64 +525E223E0F8BE2D4492FF02DEFCE293DF9BC0B63FADFC0CF36D86408C198354D60810EC9 +A184885B1049D002D5250D46763042EF9466A3CC6D5D77F15DDED407743E5B0E66F07E2F +0D6B34DD74B03ABDD904746F47AC74EC694F2423AAD5AC1BA4D92CC812D14AD5BFBE7EED +E711C2FF2CA96229106E9B1EBCB7B247E9DF0D3497B50AFB597128670D3C37D33E8B3E81 +4CC5939FC944F0DA9F486517F19CF6DBBC50315F25BCDC9E2EC95BC5C32C3873FFBD02E1 +10C4EBDB28C5D812B259385DE0F27DCCEEF80D106CCF483FCCA045664F74BB6F3A93467B +F8CE0D96A004A1E0432B509E1E28CD71BEF3CC18FEB60DEC9C3C8B4C7DCDC14360C02604 +65A67941AF7445642F51288B5BBE76CBB54DCEBFE0FC2BB4F9DCEAD53743B355DBB7095C +4869B00D783D56AB252AD6242BAC1D7F71701B0BDCCA9788B29FEB31245E97BA0BBF6167 +570DE4DB44AB1823F301C2804D20BB08494685CEC27C481041C456C5D1024B7787385BA8 +F7799355810EA9BC21F6B14F7A4FC8F85276FFBEACADA152C746133E53A53F8788030D93 +5206C09FC2A130AAF5A6B28BF9F81A3AB72F910FFBBAAC14993777786D6F6B42FD005566 +B7D5C006BCC0DD10EC2D8EA90ED65F8EB52B488F5D5AD6AB2A46FF7C06B95523D79246CF +34576847ECC644C0A85F3D379DB1F97A246FE3B066D0A6F7B6BA63854EEAC4C82A92C3F4 +53A9A906DF74B5996B96D2A13A1F7EF9682D8F0669D4D241BA1012B13D69CE14263707E2 +22BBB0E36F19ADB165BEEAD76B323B55740716B85043EEF89D393EA418BFA7806FD23FAE +5D26CB811E5113DA77A37560F82AE3D2F4D8C4970AE092D0E56888D525D45563D0CB4DB3 +5317E01296570AB93CE8FBEE77BEB7E9DBDEE9F3208656C8B536F8E44F89203343DEF8D0 +C6CF20273522C4E2ED3AB104E4C98E0C773C991C89E16BAD8D6EF4D70EB69F9B9E7192D9 +36E057EEB0048168D2199D790379433974A70E9F418899D3822B0354596149DEF74FD653 +162778EC18B4AC9093ED9A6A3B3C76EEC9CDBF5A4A4ED23BF60E04E5D53A1CCE0360E178 +A682D70D86C5E5D8B4DB2BBCF7082558185084F8D8A22C96C7296DABE818F67FA9E5ECB6 +F5064065B7CFD19BADB214DAF76DC8EE0348E93849BCF1940962F297DB8181847B9FA9FA +6B443B870C7FFC99CAC69584C8CB64B01098EA4D3496EB66CB4A146766706945BE8AC9E5 +1F82AD6B2891A38D0065D37C2ABF340C05F8BEE47A35F3B01485CBD9B4C79D6DE4CE40C6 +E73806BA1CFEBA9C3A0816054A8A41B757375D6A0E013F96D8D168F0A18E44FCE3975699 +FAEE3089DA2C4C743E8F746C7CE589968319BF03874B6F577D2ADF4711B8BD42EB9A51C7 +256916C4258B3EE07BD2CF4431F1C835C2E1E86887E100703EAA07336E54673C3A3EB4F1 +B687442C6D4AEBF412398D1F1465B8FFDC4FEFD5ABD396EEA8FE981E585F3CA45798A874 +EC4D3D7D2BB31E4CD62898F6D6F27E87B2D2E8BB78BA524A54731D04E0A21C19C05C5F45 +357270669300949C580629390B2734F0F1A32C764E0BBCB8177DE0E5B8FE4E958E9651E8 +703C8AB58326FE0449A73AC645B2DE49E6FC099399003449124AEC31A8714834A8601652 +6198B6AEA7A2F0895EA9F9BBEB13311BB006F4F6452C8F23064057B7329D3B98C5C2ED39 +139FA2436C0B610542069B96D6A0027D4C3B79CC646C8E063C38C3EE4145236F955A60D7 +073D6B8DADBD102BE5EB88FEB9B889A0E7FDDE15B9F69F734EDC33F16BDCB9FB84481969 +6CA99D5D5BB5EA6B2C082EBAA52963C8454A0A1E475013829CBC977864B617A14DDDA328 +E086803BC06FEEBE32D8977F9A8376325B773199B29B1CB15CDFAE065B3A127D8D160E1C +472206B7E4497C9E91B5F487FAFF62724D86478741E6A2FF610256AB92AB688F2AB751DD +90D96090E98A2C94C59F0756709F828EDF55D4C7A56E329F3085A8F7CBC2765929BE87DF +11B087B08DA4D082594FB949640C24586FF1C8B505EDAF05C4BE22EF8574AADDC544C702 +C76D7A9096B206979CCF7AE4249552B38A2FA76F2A9E4EA55ECF7E7B4AC88F77B6FE203A +2D4780CAC541C94107DA1031658D2041ABBDA42FA36A744F55B1B79090B3FC71BA917778 +CCEA41B76A06564B753BA93BF518CDCC98192399E4960A870D13B48A5B18AAFBC7AC0527 +66F9727D135DB7FEB447986F1817A66EA426643E1D2A4127680EB0BE913BFBBF01BCC874 +92F6D772F4823ACB23F378CE68FCDD439A23947BF8AECFD88A8F8FF4E28526920B833CDA +DA3F234880E1CF5DCB0D1E333809B0BACE4D1A3CF36E122F5258E7B277125C9AC20AC18B +9323D1C8332E6CE51FF5C7CFD5201E85498BD05430993DD8E18A04C75200C6B883B0386A +8E81A4A6E3CC28E4D0744D8EAB410D60B93B82B64D387EE84A27DEF4115D554C338EB123 +40E9B6B62FAE4846FBE23DE6EFF018EA67317C8743F171AD6A008CC1190D6ACF47B5712E +607B1D6A6EBF3EC767F51A6D432CBE352E67FB4D976D852144289006679AAE4E5C582043 +3ED4A6F4DDB4F6056AF923B84B8436BDEBE43AA7FF0A84B71F469C7BF396E0EA95D31AE5 +23B41676AAAC68203F1214E08BDFA403EBDCFCBA37023A566A0BCF34D4237B6A86FAE988 +DDF9D5699021CFEFCF8BCC3862836220C39BCC82553FBA41585259B0494FA1FFD2C92C93 +C4380B885A55A0F4E829CE6EFFC72F6FE64B66E64A2E3B0E82043D164D0EFCBD3CE98D2B +8EC210F6570A60C92ED09E5B8BA6618BDA36F14BB1B1E6DCCEBE50E612A09660377A67D9 +3B19D79AC625693FAE271348044AD13EA26B4FE7D1520A814C2F7730537068C5C34984B5 +0B8BD7F836B957067E02A65B6D26456BE4334F180030082A26D89091E30D628BCA32307B +310C0078D3FCD2283D078740BDC955B4DE611BA1D09A04AE30EB30154C0573F459E75557 +A006418C7EA44ABAEF9382C182CC6AE260328551D722FF8D4B06D292E09215F79118A716 +77B0F6B4A7F15BAF61BBABDEFD83C92231DC7E4A491333DCE7B5D1FF92B6D79462D8B95C +E8300AE364B0D92F7C40797EBBC62F9847C796775385E343FDB02A0726FF6D5E118B8913 +F77E2DE8D7A93359530808B89BA7CE125C2DD1174D30F0EF295CFDC6E4B039283D23F235 +24D860B97851E7A59A8863959F75757E6F9F7BB8C5629675225CE1F9543F3EED0D931D2E +18A9206F709E5586CF19A965C5CDDE330517E19596DB1A817C3146433FB0220655949098 +0FF33A01F79C04CF7D46D80AEAE67F867DD572EFC12B469C9BE08D9ECCE54050A6331593 +4FBAFBD5E4F2348251582AA624E6743A0C8FA08FB3739A303D919A9796797642F6CD65D6 +7548C40C32912745452600D2093AD67A34D3219CB539CECB093009B13AA77CAE78AECB0D +A624DA455725B2707A8B27FB75411B96DD0F8F33A31CCA0D0DF08BB08679C6D2F06CF847 +23DDFCC89E54D68DBC2E8AF22D0E20F86317847D41BD78B463593DE423200FCEC1341B6B +A61B327CD89757825968B6D40BDCEB55BC00827EDF7994C12CFED6A4C16F5F3CE38747CC +8942C8CE454794209ADCE9A7D2608224AAAC684EE97DC956453071AAB23DAC8D28D1E2EA +13D28DAFF068BF11859F8E1B8E8C571EA30CCAD1333788647E250577D2E908F41ECA1B5C +1A2199B479F0D38731EFF6F8DDF3B86FD436D41F24306BE4D1771EF24B287EA32C5A60FC +BAD6655A20261020A3690E70DCAC494A6AF3214BAEED8C00CC86E861C4BA6F545F94194D +9FD1736A81A26ADB9BF05BBFED3157D6893014E87FCD8419D750AB2F51711D1D4FCCA860 +FFD22A121805E91AAE796708CF754C5030742FA9AE9CE22FD45089F532C769E906D2D74A +6C7DADF54ABB9F8CE74AA0E8B86F9CE77CA934DE33404BD07BE3CD88FF1D9C27DF034032 +554121F6214B95B17E1F8B2909C31B93E3BCD416DC76A4D150B7DC1A0D16B57A3E7207E5 +34BDF060F416E97B6C97AD7FC846F6A3CFDC92BAA822FCD90087A19C6C04BFB4BEEECF2C +E8B184E9D9A72005D2E2B306AB25E7708A36C3C6CE857244BAEEAED79DCC8420EE0DF1C7 +A3BAE477C4DC1EFD1CCDA761F230AC93BAD22F569758FAEA83B6FC12796C503856E171C2 +1B8DE2926E0000BD7BCB2087184865B43DA908765DB836C1397F86C4EF27C6B667D35B3E +ABE731CD32C0501DA20A26F086373E4CCA74922D3988B857A715B8C70F131A190A33D9D8 +C36E061A60E1B5C63C749AE965EBED843204279D515969A3A5A5C0616FBA3D7DCF19AA8F +B0B8FE4D5134EAD0CC503F0BBFA49E7C2110BDD4BE27DC7B67DD0F417AF8C33FEC671208 +9D5309074D1B15CD52FD2CF319D1A3B149D7A513AD9D7C0C1EF8CD2CD7031F082B27CFE3 +1CB2737CCA9492AEC194A92BB2E5FDF0A94A30836D1FDCB78D9AD2A3E4A289A7E58177B2 +9D92BA721571204A74441EDA8385B79E67E5AE5F52A2A181E8C22E3343A30AA03E2DF4AF +B65F91D82A7823D2A172196B613DB060917CB303C574522DFAD536167A501EC998004BBC +7DCFE97EE8AE4F169D604214B9746475C32B7E557223B20DE15E67DFBE2B4251DE61F732 +9BE3B01CA9D20CC06173FF97EF9C15C4109A1A6A321C4CFF59F448D7021A0A0E2ACBEB78 +C4C7417E652E46DB60BC50D79A8247146CCCD3D288F7DFDD1379154E6E67C3245B8D4F78 +394936ACA8A3BDD330219F916595035D95CF1AC043B3205981126CDB837EC4A69FD88C20 +EB20E8204E3C5388A84F25AC5E96F58BBD258326C4961CC39627359AC1BBD203C878FA14 +6466C407F206184AF3D5666E7A3D6A01A866523FB85A86CBC08C62ABA290248E9E23647E +4A3D39C6C1A4DB8EBFE9BE7D70B228A3D426D6F5F0B73EE30A462983D166782B02AC2B3D +CBF181470A396FC272782D83A2F6978586975FF35C955A2A15DDF14A0A152B91344856DE +24E10D9BCA853424AA1ECA78A8598A300F620C5D5DCAFC26E087A118219F6F17B1A468A8 +B3C2CA6E1113F428BFA8776F863D89B432CCD125F7E37002067D775FADA0365E6314B022 +E782134FCD614431D014018CE7E6A66092EE5113F3E94ABD5CC5EBB42B11DAA52D18C34C +3A8A973F1BB6AFA1C81BC36EED9595E5AC3ACBD580D6D499273CC5A04FF2FF51CBF886D2 +4A80DC14D0C7C69B04E77E3C0D9DF24D295128632562A1BACE9CB3D69332EB08490CBB94 +37A4CBEDA79BC03409C7EFC8B8C38072D37F9C2EEA32C59644EB148EA83C21534D28211B +E074DB78285632BE3DEBDE8524490B9CE18FD89374171B546D349828B5C2E9A497539CCE +B501FCD13C47F4C2C57E7B625963E7159A57A3C18FF6DE06B357E7D125574D6BC2A3B891 +A918E00AF3BBDF845E6E3BB21FFDC4F724085C73B147EC7C72AAFE2C7087133CF8759CE3 +5365425F272C61CF5F96B1490DEDE8E9FE77E6F7FAD03A79DF2E2A90E1A12263EE5E67B4 +4B1A7C1737E4B178FEE720652505F6C5AD062FBEAF7C8134E984B8FEEA448340FEE7E3B8 +54436EE0CF964B7F854AB52C1A7FC0CB455EA3B879034C34361FC56935B400E93022A073 +44F0552946915B6DF0464C8F7DA5EF0C6CC85A877BEAB9FFC4854252FC2D01C275E634B5 +2F4A439AD072ED4917A6132CEA7669CC1D91CFA66EBC689CCA482E9D5DAC4F2D4A138041 +82792ED95C8305E0BCD5B0D70C6E89F7F292FFF59D405B86A00765E0E2A42C18004366A4 +C9AA307E15395495BD16D691EB48649FC2E377B388B6F5A8D519D6CC18B4F2176FA9481A +BF4A0674FD8627F5A544C3954A4F51C234DD631301465BCFF18734190C48531D3C22A368 +3A8887D4C665D442C58CF05192C957A5B8D5246E925963FB22A4476E74122D5C5A45A64A +DDD5280D5BCE3DD52BA0C2C5BB01E25C6107BB785D48C5E37EC652343D5DF64124E0544E +58785F88A7677C2995B938923A3D31BFEBE629A0C0B10E89DC24AD5C5BB67CE96706620D +44122A38FE39966D83C60B29DCEACE2D5B7C62B8DD63A8C4933EC9C2DB8F0E1EA95C4325 +E6A392A6FA28BC9D8A4614B57D6454ACBE1D4855126AF4F741EA672C5DC8785B9510F1E7 +CD009ABC0DA119E418B9D1732893A71295FFB947382B621A35430765814A4D87BC9225F7 +C30315EE1C82AA20C6694A2BBAB918D6218A862B9606E868B7CE46ADD21F18FC192F3E53 +680F2300AF3404BDA02406D991FCBD977F993BE179ECE640101FF69DD7130AE252104759 +BE35F677641AA99B77998EC68F2C33A8BEB421CDD80A32C85187445EB30F882B11DAA52D +15208664CED636B5A8630DAC33A8F1A8ABF26A1E28B1E9C5A8BF20B535534D337780DF72 +2D36FB033EFAC9F460A030DBA78B9DA909984C36A8D3A206501585E2E7CFAEE68CFFA72F +3C55906EF2D704D8815FC8DA8CAD942581B20FE0532732DD02C2E7809FDD9EAE6CDE2B79 +F81DFFEDBF5B25B0F81E884877AD96AC10D4CDE1212BDF99DB3BE6B407AC12D6FF84909E +B43A9E47C76B6D10F728AC30B0AC9902AB6FC8F894FF1B8EC121C32DAB55C6A781D5AD57 +45F94D85EF8BCC8F2672EDA77E61499065D9C1C6CB105E0DA67E2562663B52D97CE325FD +4C0C6A01D33FB1D3DBE738088EB49F61BA3A7E70F567109226E247AFF09D9B0A2103C79B +33467BA06B94DB8BAC62F45935DBCBF027F1C7C36DD12E895077A646392EC61266C98961 +FAE84D5338D421424846807E904E1B276CACA31010E0B3E5F5A05E98B82A5576C060F452 +6CE73581B41C6BFB71867D47293EB5E120E0878CBD4F670B69EE75C203CACDA0B87CD4D8 +6A7FE930BE7BB0D0E004FC34C2A51B5304FE437BAE9F2A2615DD834E6D680A1EED495A87 +5362C820E355D56B2B5D2C70EF2756A992BABD7C94555961A2C39C5AFF95AE8B88DB2B33 +2D0F4551212BD258BD2D6C53A290657A3475E173AF1CC8A893337932D9B35FF9CD005B2E +7854D0997F23CB9D359D7462EC0827DAA520FAAB6B0A396695DFCA5758BFA64DDF4203ED +FE4F89457895CE06250121FD57536E08E898DC20F084890D65772A9E242F5A07A0CA75C9 +C3551E79784A8A3256455B6C88CDB8652ECB2A457D00B90E2C0DBAEEED508EE964DF1329 +B34B20E37D58D92B6AA15B5D5F56702C9EB9755025FC8FC393C430CCFA34180ED1BCF887 +05C6E3EFEE8A9D5C99EC0F48CBCC34F37FE10FDCC68B021E14A1D131FCF8D5C2F8FBF465 +8A60A554D418D590E03A268503D12C542393342599828553AD4589E8B0E6DFB2EC663AA3 +B6A37FB206C1B732C18A052A0F309DCA19DAE82D110FD3337A863206216B00317508BA1C +1859349EEEE49B9D25C897D29C4F28C3757D350B3000612D4C32AB5E072DC92700132514 +30C91CDE6C1035138C683763736103E836DB99ADC686EDE265182E8B02063D76441E6122 +F10EB88DC27F1273BEBC4219A5E6934C51E2A9FD36C7CAA59FC5A5D2049C0781FB48B30B +750640992D5CE69D1602543B81712E8514041B4991A115956C268DE747B0F136F8819023 +8D14DDE8DDEBB7E147057EFAB2D0F0002CCD0C6D997248A1AA973D284D6A04A3E009EEF4 +3F9E859CFB4833C7E485DF4786089D9061F6F4C1EC74BD179D01636788A88597B7F9742E +17C41DBEA3E371FC867274D265589AF7BEACF9748E7E21B73318BB6728F455EF9BB67165 +6C39614711B33B96FF3F74EAFFCE174F0CFD3704637E5CD8AAAA0127AC58C82CA7B20971 +670582631831E7E5EDB9A27C26C67165C891679515E0514E6D6CB7ADD9CAE98B9E578DA4 +7B521CE6E8A0AD1DE58A024F954A424B707C462C83F5B459D000E5195F45FC4DD186DDDE +4E305D1A2743BE9C41B337785B9D57EBEC790987B6E1D03EC686CD01C3E2E14D63E07AC8 +FBDF1D5D1B38A2BC1BFBAE604908BEA0990033F9F4FBBB8CAA310EA2C217EB5FDB8E0B08 +98F64639043595E8D09010D98F959A7BF315716FE1E05109992F33231C10B7296E284A87 +219767CAB7BC5DD096DC7E164E114FCB6CB16F078275B08936A7A036D17B96863A068423 +D4B72E67EA43483968214F6243E538AEFDD7B076B0B6F7CE98A914D2A2332751DA48BCC8 +0A950FD81DACC79DD6E3A2EC69B724FCB10CAAA58272FA64D625557153DC7C1683858F9C +00C98EC395D7A364E65B33A0A8FF31C7FC19CE7DFB5D77E2B5196C924039F2B4D4859C11 +F3E9D42760F5DDB4A3BC9B78C0CFD18F9B75F4756DDFE2D7C3C8C4A60E6ABD17A234CC78 +10A6AC5778570C86C63B27926FA00D01A204CB6E7EDDFA36476E7278B67789B17EAB6F9B +384465DC8EA130CFB75204A20E63D0A77F4F2148BF88AF8D86A7CC39FEFCEAFEB7CAF7B0 +65D7CFC437E55773A2F24A1F7156C4488FEE00627ECE1B4CD8F8536B91B477331073BEAC +A38423E177E3BD2F6E5E31673EEF7C4510D430BE12AEABD40D3E7116C4C91F47CF12E4DD +6500656EA37E109AB7F5982BEEBDE4C4E1AB125EB84B560F82716B4D672D13CB3D424596 +8B201C3B628AE15A0E35EDAE952720D3D7DC3C373E1589C1B94E758BA485AD155FB984F0 +7EE774778F52A84919E48959C071F7ADA4D5D64A81E8D5D792F9E8DE6C491EF9ED29EF53 +3CE191646D7EA108500A935EC3EC9B4092EDC5920FD07A5549EDA2F643175B7CC27F7AC1 +098BD65DEA60D6780634EAD4FA2117E74458703F9722C9BFAC8863D2BBF338EF586B4E34 +2583F1EE4907414A1FF2DD25BBD2F5F3B10EE054A6783DE20C414E7366BBB3068D0E3CCD +A8AC3FE053EE1B89F32EA80EAE51D9FE242D06752BECDEF0F9FCC48DD72BF764378C8628 +98B308C826837EEE3C1F745325F1D989D33650C5A11AB9F5C47C20993159CA359ABB6E14 +ABED7BD14F7AB1B604EA8179D2254BB6D2F9F08904B91C645844368329765045BC4B0EDD +D8A5256C878D64941DCF0EED82A61004E584A8BA9CF9ADF76F5CB0B2F26FA4A4E6499C45 +92ECBFBD4736242A8C64D6E692524B3E663CD47D0341637139F2029358BF07AB385466AC +BFBDA0A68E684D4132E529F4CA6E3017AB2EA78F4281C290E2EB2A948281C7C466AE758C +19FB86A7C335C50BC32E68FC5973E533DC14720A90E5AE57F8E8D87B0567F291C797A00A +B00F1488437F05B149E4CE5B182C5CF82C3B15097C269913088C9A493C976319BFB2C669 +553240D1025AB656ED019592AA7AA98DF352A6F0CD453FB20FDA9BC5E53B003528C1701A +94F06022EB7DC590D290D564DD37357DD75AFCA9704642DDA1E23E47FE3EAC9E6B5D22B8 +AA0912C8176CB668997D9B9946314647ECBAE379CC2E8A836F697E614CD975560278F0AE +74EA9A7C10F94564170B11426EB79670083D2F68E3336898E5D670AA4785929A2ECB553D +356F8AFD7B0F95E8AFE1947C638684800A8720AB299EF7538D6D56FB1B679FA5987BAC22 +A06F3716B089EA008B1DC55E3CD09A39F0A903B8EB764E5AA9C1AC0B5231C440F68D4E01 +C36BAFC2FF18F34087A5B90744D85B8DB03B3F8F3578E1605487328A11ED9C7E7AB8DB6B +580D7329026F14F24304B195893CC1D091D960730D2C45751109DE55DE39047015AA14B5 +C497C41867A5DA02E7091FB40E952E8ADDCB0117562A04E71739AE2F9F2CF315D510DD0A +063AEE64F428F29AF03B9436652EE54D68BB45FF0E3A373E5CDDC9AD707A989AEC860A32 +2AB8C2CBE68F36F2523B1145ADF788BDBE0F577AD7F5B082ADA4E4F798199883011BDDE0 +18783C3E8246D2829325798FD75CED42DE6FA551BAB1A8E0637BE3D487AF286EC8B42278 +14FF0E5BD8B32A0C524FF0A0C22C8735BF7145D82F6721E7774D2EAB4C28BCE0634A10CD +571490C14979ADB3126983F20925E30D7DE2AC03C146432D8B15DEFEF9504467604D9F02 +32F7E56163F09E9BE071FE10FC3CDB00F40004AF8B01239CE23B5F69E37B35D5DAFA76B7 +8576B031E3386C6099407C8042816A4EF9CE790110CF24C114EFDB9C8529A43C41168F10 +A17C2ACD6C4E299A9DE70657E70B16CEDF35EB41392648F09A02E1E4717400DE1A346671 +37A7CD6A6EBC5F48A19FF169A279F815BEAE49B489923AB6243E4C8AF35B4CA1EFBD8EA2 +D21211D869E0D3DA441860B6BC465EA8497507B8323CBC9B41AE6C774EFAA7224385FDA0 +CA5104978442A4279CA25C29401BBA1367CEF35A2BE9D24CADBD7BD9695BE9AF03BD8DA6 +A62111A9B59A24A4ACF6334807CABD977D251213079A7265437C822AE4893BF048B19907 +E997F038CBDD1FD0B412AA2817453698EF05EEF47AB03E9FA77751C57210969591876316 +C83D5052163EDC28DBACB472D2873919B63E9271310702DB9521E8C18020470A4DC60EC7 +A1007BC82BCCFABFA1F575011A9067817930AE0321659ABFCFB4CFD6EA7AA86AEC98D64A +1854B666D075107ADC85FCDC67D89C379741264E6554B7F60E19A5292D356E64538777EC +830B8F0931D34A61F9CFF3C37E187D99D5A2E7E876D1E8996F73FDCD7E614101F97B8BEC +A0744AC91DB473C0103B6820134BA545183483C05E1EF90B59B78305350080D2204D751C +C8AE8DD9462DD62F0FBCE507F6EF39AAD77024E89975AD12BF8F86130D9B76AC7BC4D4BA +BEB06B76BA3D77DAF45E769C732882DF011DD3E00845CC703EEDB8EDCAF7A6EF4FAB06ED +AAE69FA3A9436774577899367B202442BD6CD24377AAAB605114823C26D249CB0E130CF9 +60D8313DC983131AF766483BA063D7ABC0BC24EC06DA0720D4884F9421B9946AC15C30A2 +DFD1375F5CD56D83C8B94CA84D3467574641768C02ED50024DA171F856880506E3AA5840 +1E65B0B73B80BE8CAAC83A1012D1F244F4B99BB4BFF9F001FDA8F06946883B1F0657C3F0 +22900DC7E6EBF936A8D55CD5D0D66291E24240F8B997361BB943B5A9D36900ECE284CD7F +66047938301E2632D00CEC224B1811F43475B3EBD58006DE58DA2F91EBCE1833CC23C395 +C071663B9A91B8FF22C98D840700E3256087FE0A616FF9C2323FBE8CA67CEE432A2D2AC4 +D00407877B33CB35B83591CABBF8700623D58B8C745C6FD0CDB21A2C7B26BD8495AC72EC +A551C5B077D0EE92F5A67FBB4D438114D161566167535A3B8BD74EB10382D997C418428E +F88388B24D9D78C103572341D2BAF842DF6522087E28058CCC1A8A7858EAA41D1F588C55 +282E7AD9708396959DAD7EEA79291F5FA856A15E0DBA1758E9788685F3FE87AD15E29379 +8CA04AD209B10DE234315BC07132D32C82ED96B649EF7BD65B80A45FB3A48C5C3A994628 +118633137D02298916DA8E3EC7598B8FF27058EF911807A26F2189169D7D53A305F89659 +B6AD13AB05ED759A14FC3FA59F36902ABFDE6D02CA63BE37DE57EA0FB0ADE69626B8AFF2 +C4CE000A5AD361A7311FB0503F6C6EAF4E12E90DD26C2FF14CF944F1C7D370D1035DDDE5 +DDACF493116C4B10BEF55FD88CEBC22252BF641FE8E871D2A051F774A5D3D9921D1BA16B +26765180C16A4800F59B9A6B990340D78EF95CE32DC7F14F34A67FFA19474C8EA4641284 +DBA859874D070F5B345083E1AC095CA5348E0358FE7B10F3DB25027CA0C6F63D034974E4 +64ADDEF24654F73B0473208664323C568A2EE651373FB821BA60F3ED0844FB75754B1D3F +D47D3097CECD9D8AA2E3C12A286F3AE09EE3F27E136DCD543BC7BDD8F4E1831FB190FBCB +8B5EB2BB4C91830CDC404EF0F46DA4A9F41345181D0F74F39F36F5D1E2FB935D595E6331 +80AB43D32F82C5F339DEB75288209C1F7E006326239FAD725314A95ED40D51CC657E52C0 +CEC73AC090702C85B9F171C89B2C787F1E7B4EDAA41CFAA83E47CE0BDD74E9AD13E71539 +A19872ADC0B12C705E9B4B271016B208974D97623777A64FD6F4DC176B98B07F9BA07D8B +949DDE4A4236D3F19F360265D8E745845F2E6D74C1982803330033B524B6692E58EEB2E8 +D1A3EC8575839D85FD65EFBAB49938B9BFFCC0A23D8549BEFFC4FFD9B5644B205E17EFFB +A6D24813F3F490722DCC5401EC9BB107ABD77D11FDD60D882E20F1993F9F471BDE3DF47B +13D8BDC905A1EC61E9325D4F6CB62477FCF08BA409B7B1BADDDBD072A8FB38E26AC452FD +B77D07A223CCE2EF62F7F7365B8C9697413D77A188491448143F300B09DAC3F77EC6E287 +C372410597198B2E7AF074597B6AA4E86AEBB31E56BA401D0E6E94C40A4F6EEC7703C3EE +06EF6FF5DDFDFC2B7443D67C04D7311BCF21761DCEA797936EBA6098C91A973EAB0A9D6A +E81C1893C7CE1A8D2181DB792D20C29F3E6C5310DA2F4A25DECE6246ADE8B78C0593ED7C +62D5D6C89B6EA4AEA664A79DED2FC50F958F8B1C7B92942B4E58323F2BABCA0B77B79992 +4738A89BE91ACC5306B0B6E45D672069AEB3485A0B52E931993E600B2E65F969D17585B9 +23D1E5C75F44E2866DDAF942C6ED937C4B7BF2409F1BF6397FD27BB5DC7DD077F0F988AF +0677615675590C950D0F9A39EADB0FD85644D3996C41A5B45393BF9FD3EAA4435F9A99CC +5A35051000E4FB703F801E8B71115A0EA3BE19D5AACCF5B0833AA87FA7CD506C3131B6E0 +5B3B92A493B57268CA478EAB09E71B1DC304A329DC6E7453F4B3721CD13C2B670C19A764 +9CCB29BACB087E768F9A817E893A4A0A7EC4EE391DF074C947B2978A844D944A10E2229E +0BBD69B27AA210D58954353D1266F57823ECED7EAD0AB583F4F27CEDF3F92D1FCCF34BBD +ABD82B2BE6BF7F958EAB3F5921D8CEC898D7076524B12D68DB720BB81305F195EF87BA96 +264878A18F98FCB5136177EF743037D4F7141A15744FBA348614DEEAA97A3510FF277A18 +8081B35AB29A53ABCFF2AF1DA946971AA55A72022A6DD32A7F55C05EEC925CE21704A5F9 +C35D5CE2130C32A48EBB7C30EFC34419355761BCD0732AD4B351BD046C32805BB089A3EF +B013E4F54374E8AFEC10ECFFEE05982915D22E25A2158F5BEED6A95EC6005490FF895CA5 +DB459A2DB44108AC0A9602723619CC2E013155ABD1286C9CC50397CC7AD975A042833A03 +3C2F010A0208D2B5F7FCAC1F4661332E91F43507BC6C55396FFBA9E2965CCA72EA47E3D6 +A0EE5BA53A8DC8579A85383B394A043B26E15EBCE158D95F14C714793513A6E11C0B4FD9 +A02704707112AAB327416114A7E25F6487E6749A8BE860330104E85A2791DE3C98B6D6DA +8D9F251995C972404D1A0D4F044E828F03848565B821BA154D836BF8BCDE9B4F3968E32A +D031AEC5216746F5BB0C24B6EA06EC50E0AFB4BEB48CCE75B016708682FBC063DA14314E +37152516354E42C8A6AEABEC056F7D9B85CE992D20061F25C87125A9DEED6DBDEF357EA8 +68E970CC703B5C8E67F94C2084FED1C6FE0F9BC6D26D132D7A8AB5EAC1B2801ADA11C806 +1D005081A47B901204BFF62BBEC6E119C24E047088B44278CC47816306864CC85A242CC8 +0D2A4A10BACAA701E62980CBB93B59190E7ED184E280B0A20F8CA4749C6375EE133A0A79 +5215D020563EE1AF19A3C573BCF56533C2BE07D4669C21E22FD33530D408714E42371322 +E72A367B66EE7CF614BF7F4647E6FC1B9F9E18867CB630B159D965F6B4CE54BFAC489F10 +FD115E894741C99B40E2810CB37E6F9529CF01989C96E6242D67BDFAF52888F1AEBF1870 +AACAEEFED464733028168BA7FA51311F251B9EB544BB6BB6F5FA90A20BCA883E3804916A +C83A39F9381FEA3D8ADEEE8A62634D02F3C7FCD8F01268976A3B90C59BFB9AB1F7293C14 +48E00102EF69931EE40BC3FACCAC7014FD78DD06EB156C860DDFCD7963038197189A681A +AFD7B886C6E7E26C87D4293AE6B1B4E7884FEDEACC9A2B049119147417F3AEB87B33A413 +C4FBBE3D0E5FB7D61B114A85A9C6F4A95D123234A394615192765DD73865CE47E4E0402B +42D3A1410AA055B18FE654FEC978F28FDB9865B09227A98940613EB39D7B8E4CF55CBCE6 +C13A5ED3DE5F617B495CE502392AC8DCE6A7B8CC7AE9B37943DEF4E6D4015D3936DBE823 +79E1210BC38B20BECCAEEABA24BA09357AD20C0289D2DC03E4CBB007B8B49AC2F1A47CD0 +5037FA11C1E1F36ED2F1DED20FF9D5042D9F9300B5C79C1803A9CFD65D80BEFF3AFFE22D +A6A1A48AE94C7F647195C920B4FA1E025B960BF661D592FE4FEE71702A7093BCD4AC1510 +7CA7CD0BFF3E766CD241DD6059DB2EE8AC74EFDFE8EAAF57B8AF7AA57B41EDF431549CA5 +DEA22928192F8D1D14F3087C9653F3C8FADB30FB994C72FEFAF5AFA5EFFCEC3725285D25 +19B356ECF7F22D1C6101DBF3F476575476166E599DA264073283C19A8ACCEF9C0EE2C69D +D9F0FEE3E57CF25CF842D0D3CBA7204B63FF0C4FB0D364BFF2D43D04FAEA7BEAE5300B14 +319DEC628BE834B7F995DDB697963AC750576C154BA3B31C102BAB9BB93272D6799437AC +9CDD83275AA5A15164757D9D06F95CC444B756237352134AACD5BDA0C41FC0FD98DF9C74 +96D32139692846A141BEDA8E79E7279F1ACB7491ECBABD9FDD1AE69C61B22DCFDC81E440 +B2965F0D82C291D07806957E6D017B8EA7AF37F05F5331BBFEA70A3AB8B078C4F87F4D64 +CCB62D889852BAE9C0FED70BAEB159343A9F3E1F2BBFDE54D5E9353B39B65C16E2412234 +D4E7E1C96D282E1C8D1B38D9B9293FFCDB5EFD759D583C9EE63A407F08A6B212AAD91FA9 +FA501D1C725EA8B08AF2880F1BF0EB6CBF885B70953517189B8536EC2C7960C7E6D5CDE5 +22282682107CF85CB025FBFF2E88FDC5ED4EA44DF630359EDF17BCC33BAB47C302F193E6 +5EEE260DE65D388E935B2471A70A40B5DAAC06911ACD2E5BC9D2853A501EBFB39711151D +643E9E4F78CE0FE4678ACA19C3F7B45E4DE13696E35FDB7EB7AB60853A6CB942DB425AD5 +CCC11AD042773482E0DBEA11FB1D3810AD5DD26B175339603E4E8F32A14BF7E994ACD717 +AE314DC77EAB6061863F7DFE05D95FEAF8436FA218FC3F59EF8FCA198BE6CCAEB3D4F3CB +BAF8F585FE5997C4619EF19E53DC30BD017A67E318612FF82EA2553D060B7D406904327E +779B4980085565B8FD0D7B497FB4350AA989820067B13355329BFAD8D9281F0703A9049B +75DB584D5FC19F3015BC11EBFFC3BDE393117DEEAF11994DF5B62B5CAB0B16AE64DB714B +E1ACE83640FEC6AFB4D5A66D7DF0AE5DBF347EF96B535E8ED1839CB030703846EA3D2E78 +6721D7A3409C8C23E7B0A609525D8A675C88E069E4E39C4E06EC3CBF5D65F4FF176DCDF4 +2DE2AD6EFCF7D2EBFA8E3FFB2353676C39B167AF4BAE04624856DD334890E8446134DF7A +2435D76D4D76090E7B6914873A08688FAD94CD3CF36C10F983A211BC0A8B0276265CFB28 +A976E83092D7B210B997F392AB4B31AC6DD977276E3EA61B4095F5804ABA0E21D8681A5D +E660B5C095054FEB45E9CDEE557675F66C4380A89FCF51E51347BA633FF52CE6F3FD9596 +5B329DE8A88AEC6F101338F1E0ADFD99212B29B725A6C4997117FF445DE895963F2787B9 +0A892C0A22B2D244834CF54A73082597044AC27F5253BBD4B01C42A69B8DFE25299DF085 +8C545801C56453C0E3659CA5A6F4FA3622968F77EBD8E551C8B5FB354B8192F3978E4DE7 +52544D029EEC168734C623C3DBECF5B362328EEAB289EAC40B85EC5A36FA3F73CA1C9A61 +771E4B2DE1633636F3BFCECC3D70741DEDA306255AE27D4FDBB89B811BBFDEEF8867E490 +C1A731C51EBED996DF36340D570FE89004AE7FEB5F686E1129100685EE41086A245154C8 +1D80DC435DE1253923B72DE0C6B2EE3DDDDFE5C0CDE38F683E7CE4813425EB35F9AAD55D +3CD3E62314510DF6C2FC0EE94CC188DA028C82FD9BE6C8597B271FD0ECA5FA6AA0704A0E +9C1EA47EE0DAA990E98E4BCE43EC3ADDCDA75ABFFF6E6FB98AB71271A73C3DFDFAE883F3 +B37A0D2193BD185786280B4DC961470011902D56F511759FAA40308DCE49EA5DE8C073F5 +AB3A29630B93ED1D1EC77A97CB5B157F65B583A96D2D50FD6EE078CD6D7A7CC4A31DFE09 +23A866725740D3E39ABA8305BBE4D4196EFF98A37788B9E71EA6E120DF0E6B9F14BE583A +EF3F2058C22BAE7DC3B63BC150EA62ED03BC238C27E65DAFB0992DFE8C8F5879B75753E7 +375E76ED56BEDD1C983B9548818E6C2BB71E38BF3F771B65F84706D75FD761A14ADAAD2F +4BC97ACCC1191441BF0AF940FDF539F961C670AC4C8129C1DF1E479207F50D1E08478503 +409C4E9D165946571AC1CA1D7EF9D31546CA99C1AF6F7611E605A08EE2E49162EFE39E33 +726D6ECF05520DE13F634AAB828595C898678BD119D7F6BE976AE504AF22FCFAB6F930A0 +29E176F442504F3ABAAEF24723311428384D691A98DF4689C6930D8860FEF6E355163282 +700594922D73799A67D834F1551D7BE208615F590781651CEC7AB705EB278B3470D7371B +A90AC7F0FC6EA11A906030EADF328B63E21A135A4BE6C6C1670C9F795097749D994277D5 +3866BED00493512C771C973CFED9D7125A095FCC4ED15B97E3CF56398981A8ED0D26266E +5516FBE18D099AB62B457C6D8A1CACDBD04A3F64D4D95A6F65B7DB021DB83C43DFC24A27 +E772D8A805FDE4F4645178693D5CD29B7ED26821B4DD1AAB2D256693A99F612500A903C3 +65889A1266CEF14E112C91F2E2DF5B27A3D979E957C5F70C9AB7F64B88F2466ECA5DD0F4 +465D920F5E78A955878C261079CECD27783086379EC6BDA8CBAD8726167520DCEC08D65D +4A9BB2729462365F7E3B97E6432EC01F8833870F1877FAE22E893400A346BF8D8729727E +E7694035DDCEEF10B596B3CE9754E69560A1D8F61AE59FD3CFBD0D1CB94A14AA155C2CE5 +03D238912CA0DA82E700EED99544762C22B8CB36E4EE2C73738CF1721ADDF2091411F98F +2F7EB86C46E4DB9CF84EE208F6049F73B788BFE5B38328DB074752C8BF9B51327A7E40BE +F48A409C0B2377236D94327A0A1E36BF296A670F5E75AA2F4C0AC6815D20B635F02B6929 +D72C60CAAFBBA4DC377B5DD92E904EBC2BC2ABCBE404197C803F7878F33FAA8C66EA0062 +CBB1E24BE46D23AF9762C2050F85CF03084FDC271BC0910266FB693A4C5EE4057C2319D4 +3921EC66E5408A0D28DB2C094C92CE16A2A9802A3D075B12D15C0F4F4B603EA70D69D94C +102436EB6A835D4E9C0937298843750472396D20FD66A039871D21588EDF04E607E03A0F +E4671CF071D2A24DE7AF33D9C1E3124607854CCC014BB6980C4ACE3B73F1544846CBA010 +A86E003A464014699ADFC587294C8F64F80F1311F4E0B8CC1624B7CBABB7EDAC646C7351 +D67CDD61B352D8E21DFA5D802D5CBA52A364B019FA24579BA36A99414E3B018B8632031A +365F4A0E9E5CFEE1C936E546C11AC93A2B7EF433C2010FEB3B2F315D806F6D1F42FCDA3D +144DE40934AD30A14F3AA66539FD901C6A7A9173DD4B2EB6F0F546C43DB1BE141B1E3442 +E0E0DDDBFD1E6C582102C5D3CA9A856A7082530B3C84DAD4FE67C718D7AE874C0B59171E +2CB2F1BD37A1C4DBB3E767E0E844E6A189A828384D042D055A118DE26D9C5787CB81B102 +F8DDFE285F0D24E0CA87658F2DD9B553B1D52A37B0E0A1E18AAFE6EE4D0CA2E3CBBE5907 +16FB32D9030A6C60523FFCBEA0D682CFD92341BF5C533EB7084EB42EF42A0B6E7D172B14 +805780F54FDBEB03AFD73D2219C74CBC569573B5DA65CDF3CD11D8CD1E3E60DC1AFAF5C7 +417DC5C8BCCDF6E129DE171607901C35ED11B0299BF2104C08158EA843AE803B63CAB426 +842C3B4D93954728352468A44B6A02115782156AB7DE5FA01B7A2C7C3C69BD02999A4F89 +3600E0E79F60EBF221A40269A40904EC3DDE24A4FCCF92DCA20AF2614B11D85F2EF90015 +9C878BE4D889D1471E17AEBFDF34C29ABFBC8B1FE07BA33A5C6B51B3DA5887AF6C6EB0FA +A7F7AC8EE55FA82C66210012FF0EF781815EB18D1530008AD7EB0705E854B3FA44AA79C8 +EB7A91BC40EFD85DBB3AA61209C03D1C8D70A57AB608FC5EDA04465E8C6545DCF52C867D +6F2F5175EDF68957BA609B1A5E6F9FB15F628EA7F0D74186E278D45F89F981660029CDA0 +B1CAAEF12FDEF8C4686171A9FD08BB0226DB70C564766AF171C6D25A08C6669F71CE6749 +43F553CCBBDA80CD3C55F283F3068BC8070B96EA52D2853565E00DDD209166FD46C17B85 +604F4F4FBFAC1E7B3FBE13DFF9C2354E625FC87FB3EDE892C48BBF9D11A3FCDF65A29E76 +FCEBA941644FF4485A4E14E5749CAE0CA96819C9B637CFAE5B6CEB8BC390444763570362 +D8B397C3783EE5DFFD08EA0F09DDC3F1A29452B3287443D67C04D6ED1E61B2DB7921A52C +7D25073B58CBA2699AB8578FC49CA9D550D482F1BC7CD283BB8B02390DDEFDE7CFB447B3 +FE99D6FB4A225DF571790CFA6FF35BA51440BE6740510D7BF8CD55FE16E6F394FABBBFE7 +2D2070BF9CAFFD58FCA0A70BA2F898511477A950293A2197A3E8A7E3FE7AEFCA9DC6704C +0ACAF82C39784D0D800F52E775150D976F1BC9B9D91EA99E44FC9CC9EBC08DED6F939CB9 +86CE37724553657133AB4903D0950B235130395EFFC27F76466ACE37A323358C6F935EFB +E8109BDDCE9EA7B22F92DA7A5F5AC992B4FA798C0F670C0467A63FE7571F707053A11071 +F6BD8D93C1B32F1359A827222080AFF5940135A1DA02DFC6AE1113A93E5FC5BDE02F9739 +0FE65F8680B0999EF41AB024E35A88876DF86E413AAFBDDFAD693C0BCD4654FD8F5B9A51 +BEF91593357F8F16B7C59CF6DB3E5B6B5597B8F8EE953FDAB759EF5F42B8D7E0282CBCFD +DD13062501C683FD109D972DBAB823909E117A55B08E20776A79BA61CE6D84AD8995BE0D +4D2AD126F6C195AF54998FFB9131E1F3DFC61F6AAD217D0DC339BF8DCE17D074EF5537E4 +7EC63E4B707D0048543D939DCE6852DAF6DC1FCF95D689441B998C8A5EEFA7DFEB894B4A +90216B335464CA50BEAB87DBC6B3E23AEFD21DBA17B004D9BCD94357EDA82F2E388054DC +593050F7226E133A937F83462C4A91079B8E96029FA17A4162384ECF11F95D53F3984022 +B02C4C82A702F75C0C3F91FF94571981380466C8BCAB42C2D3A33C282E7E6F5A73EA38FC +7E296FCF8B1E4C24DB0E2F7F076F659EAED92DA4C9700B6746ECD85995746D648B9FCEB8 +FCF7DE89F299DF6A6D7DD11FAD78270D2F45D75FB0BE0FED1C1290B733212C1D1BFA80B5 +D17CAFD3F3FF5E504B3EA44727AF6F3F37DCED87DB486BAEFC2D7DD7DA55635F671895F0 +EE51D1102B1B491542C9F3CC8F1D1F14CAE5700DC1566B7B44ECDA0150ACB072820C480F +F92F348C108CE1F70BBB830CB9BC69A3F3E4E52D191BCC2BCE475734B38238725E3F3A01 +84AB62B13458F221C2C505587407B5623B23FE444ED5BEB0F37CA4265FEAEFA74CB365D7 +401CD4C247AF0DE67280316545EA659C2401A8D8F8279A8BEAB4FA83F9AFBFBA32794C7C +A7268F6BD3CEBC42895E3317C1E8ACC0D82735559AC7EA0378524E879BA243CD6F938C6A +6BA39385EE7944805C6E3D0CEC912D1D711D90459D032D0F29DDED3320E437A8809727F0 +E42B52CDF7B49A350D8DF3ACC7FA81AED6E290DC3D40BA6A7001ECE8222BFBF2E7D21AF5 +B5DDDE2E531A5042892CAF60BA4BADD60AD61E811BCD9D7608E00CEB90989E48DC676155 +EF3D790B8A4FC96A351DC301FEA7B959A8CB44F228B852CBCE8F9450E4D288E48C3A5D6C +616B9BE51F38E9ABE16CAE86549316ED8B58E9B0D81E7994BD83A314601CFEBB5413C580 +399D87BF9ADE8D90BB6CC68CC36972159CB55335D74EAAB882A1C3724A2707037E5098C2 +2A6655650DFBB2F87BAA1B3EFF8AC76397A226B95492C64E648FFCC08F8A552E333F1E65 +660AEEAFA3B0296CFC6B300D3C6FBDA01CEE297241588DB27E449C03F0386EDB5D4DACD1 +59BFE6C5915988099909AEFD10008CF1BE8EE8E9F1DCD980DCF0394503177FF49827A3B9 +D9FADC16F0890A6D330146809CB5F3823DB1F9FE042B95146D6880EEFD113174FE00681A +697ED8BCC6E6B61188903CB3CF5F6248EE181772F5F873B671812B8FA93C1089BBFEC5EF +0696EE1715FB37348E75AE88A096C1141D19E7AACC7A1DFB282D180E8A08A8C92610D2D4 +E3ABDEAB7DB34FA630A8F5151DF12269454146FF715DA88798240C01F82BCD3BCD81C558 +E6CA13767923803162A8EADC641182B71A205CBF91D93ABD4D194E327234F4FA56F4C496 +40BCDFCCB269A49F449929DE799A99D15460CB9C131CA83204DD513D68F10A07FDC0DCC4 +6B93F8D87EFDE4590E3FE360779B5082401493763FA73519E8CBCA4F815AD8A95BD10135 +3A1F379DBF7ABDACC2E5FD6CBD2AFE90044D86BCEE408AE8A32C89C224EB483256854C72 +E68653701EA2AB54C09F98A365FF042C4018A0DDACE380B54FE568F3C72FF16E73A594C0 +E9F3A228171F6EF548EEB0A2F52A1EF48CD81AE008B8251196854A03D4474EF064C3B9A8 +C92427F5C3297BFED28C85C235272303BBA92E37257868DA3D4CC651A8E8B007AB388337 +29587176479D1F6A95417EDC03D9AA5B6FC390DC64753B279206DF1037A26F38A56D8A5E +97DA5E3F416F12FA14484C939EBB24CCF60CE0CB682821439DBA8DD842E6AEF330609AD0 +756ED23585F99CA1BF6A9D1520682D939B38408BF49DE661E632FFE11A7B9286AF457698 +1F26E731E8576D259BE89AFD3E96A0872F1992FFC3D5687C5324822D09FE555153E1B03C +7C1FBDCF72E8B369BC26A0995C6B5F5C3F0B6505AF28033E46CCD32D396F1FCF2BBC314A +CAF1BB2CDCE7B5E89015E304E1ED36853C9B8C4550894C208398A4596EABD6A675EA1716 +2AD277A409A2809727CB0F7D02F74910093346FE37D14EE063F6D3B6EF9C682988ADFAD4 +75D07035999A7247440FC2DA98D5EF04D718281C8F36719ECF7701D2AEF8B845B983A1D8 +46AD41CE818E1427A23A2E5F842A4BE05A6E867653B6D4530E40B96288C1FB0C49F47CA0 +ED4CE1456C3582C385155F309A5EF60819E3E2EAAB741278811A9DFFBAB54762ABC5F045 +1841D0984BE8960BB21E8642071E442D5EB7491F2261C855151628787A4C699EDA1F05DD +C578A9CB506FE5308A90B3752D067DCE9E715F12F662C5303CB064B3F5FB46358CB4F803 +21D29935FC49B937C066A1AC82913863D01C1FA85156CD0869652350602D766CB27BE412 +1E50493C0AFAB232057614AF48CBD74C4685360FD02900F8780AA8F0827F2F7E0B0B0306 +80A4CF3969036081462D92FE2DDE06DB413B4E76550706B43AE982AE2467353B8059A32D +B35DC0D388D6264C573182970C2D0526A6F57AFB21DFC59D22F8D791A214F50D716428A4 +BD37D25A5958BFAE8DABA9E2438270B90440AC7DCD9D4D8A3AAE7E6F0D54FD15D1C8C1D2 +3E04E9BDA3CD2D97C1DE1E6499DD2B2C9D1B789D600EC6B2B9E24739D65D9C8114606645 +D8F2ED5178E3647DC8CE3827E53FFBDFD5948F7302AD1D70987FAF02E5FD03A1B9CCC6AF +C658B742C88DC2547B3A4EC4CC5414220EAE69E23F7BEC39DC476D24331422D0FF109416 +CDD40545F6802040ECE231B7840CD13B8611D88A25CD60BA268CEFFA145592ECF8CEC07D +A9846135D35E035CB55F46FD5B9AB7D60CCDE973A3A51AC2F0314471629CB80CE30E6ADD +71B6819EAE128437C1AA243E869CE668C8BCA434D5A1156A41581D27F3B52DD26BD4089C +A25EF40DF171EE2109A17BCBC93B05EAC8418F4E415B6AE72CD4211DAA97780F11A4FD11 +A96409AA6BF06A69E6ABF9D31FB157C698F9CD86DEDAB707BA74814C9C96BADB58EEAA87 +3B4D4BE0C4A6FEC42B9AA8A70F57DE8399EB5D574B132BCB2D3FBE7ABCB621BBC3E483E3 +378CEDBD2FC9B758AE746BE44EB4973581E0F402C1738FB987E7C7B32FA9E3DD3E822F7B +7B79A5D67E0E7C455ACBB780BC94AFB886122FEDE728272B619765C841DEEB915C501C9D +5E162E25835F660E33C017C88A2BC8D1E93D32CE0C43A83C17937B7E886810F774215EEC +57A17AFA1F89AAD6751ADE08A4EE4A6DE1208F3A35D927850042155EF6F44BBA6BABA143 +BD726F652D7F8EFB9EF14D281186F9A8BAE057F048D7914429B7BD0D95DECE36C48C6F17 +599FDC8F31FA2A0444C683962895C68AFF8B343B9CE4703A2761AC84B1B31946A7C8373E +A369BF33219296783C5A3465179E1BAFE1BF8443801C972CF6D28BADDA13F78986F6DA38 +8CE4453D5E7AC0CB518D5C889688F3E54C3C00BAFF896961357BE6B4B487064A9660E353 +E8CD453B5B828AC0F166B50E0C1CAD4CE97469403B22EB2C3FCA6A734706EF4CF7F9331B +53E13D0A5653473636154D94CCD625F8858B69ABC25762AE4FA1763BCEB2989CCCDD275E +ED8E95DC14500574276083F59BCA0A2BE8BB1A9A5510C63FB48939BB2ADE959B0342E759 +F556A6BEA0D78099719C9D4FB5D8741598522D483B77155C9030D252E28C2AD364C84364 +39A58ED8E27CCB1469CAAB4CD8B7293BFE89A7BB6B72C4EA5D7C29EBD5B2A9DD66BAE6F1 +9FA45E886E5A79B5FC7A65438695659213E0F4C7A6590911CA0C976668C7C2697C4F0A54 +4E3240D23DE40D53274415F5D6CA333CEE4E6E04EF7C42E84DC0B8F583F83185E1E1CA10 +D210AE0816DBFED7AA382EE1CE6EE1ED7B3F3AEB25DA4B1F3555F39BA2DA5B87B9F78B57 +9B65915E2440B09090E4E8FB0C342933AD8DC8BA3DE1340F00A037CBC4D1E775D3555532 +F828FBAD77499AD45D007BDE4AD065F462D727AAA69E314BFC1055C5FE9637676246DB67 +A6BBB7A78AAF4DD18611871835C218A45DD0852434ACCDEEC60AA4DC48D752FE4303AB75 +654E270D27E951410DC5354E85590305BD4B0631C90E369D992ACE973879CB962EC25EF8 +D01C2F4BC4155F409AA95E65B89D4D1AF4989B6BC3681E913CC4CD798AACE97678D4EB0F +131D6C2378314EFF41C585571F3901B0D7BBA1E30CD7ED9E4C706446D55B9E269FF75547 +AF498C716FC0A951DCEBC8BFCF05DB2375B79CC1EDC162ABA073F01C06C0D64E4D17A692 +98482F4B4C1747A08B78073D590F5291936AC3016D5C2CF84DD6D93CA7FBF9FC7C9BCD98 +4EC0E07F03D6E632100BC328068B2C9C8BAABBA4E0CBEEE49D37025FD0CD005FE50DE670 +F7BF621CBA9C4723F3D7A6D1BA5AECCEA901403C03B66F6F92D403E4D89C238D75946080 +404B79D35F8D5E0DCDFB0E22AEE8B6BC7D994D05B7AED76A40A22DF9339DE4CD937D54D1 +E09B6660992B6FBC6B36791D5AA53093E29C78BF59E0D137B06FEE0A553939725EC59380 +82954AEB8EE503154E8B56F4B45B6357402D78D1282BFFD0D38D8940F0B3AA1D48419ADC +33E11C96A48FF09E3A6CCBF7C88A0750868FD61D0BAA581E6A010BE41462FF3F71DE3B9D +6951D2771373AAB7360AB1A7EF6C04113553AA399FD21B02E1C90FD6FF8DB09B6F485CD2 +EEECFB5CE1C4E0F3675CD792BF28D726C065D5B8BEB92681072CBF17EFBA31BADD5AD401 +C3171B406ED57D757E59AE1C61AB425A580C179771334CDBB633428DDA41FFA7E6BA6668 +568930B3AAB9B51EA7E63845A2D50CDD60F8F60C3FAA5549626895644C1BC9DDAC415BF7 +96137F82FD0FBAA9F66269000CE1421BE1F617564FAC0CDD70AB2B2DDF5C804540182B4B +EA2608F4C00A220D73EA038B76AAE89BDB8B6496D3F8CFC7FA60701303795C1BA8EED486 +48BC6DBBE06A28E84D4151F85C790E5C6C7862B7B5E1ADAC6EF0C300B1AAE19F092A0D2A +160208C31B9D36A334511C10339995BBCB3C06D5A7E0658B6E7988FA3704C6E109EB3E60 +687983DEA045BCF7596F869A5FCF88A68982DA5FD4E26F72E758C60917094E7A0BB9E32C +B16880994E573A73F4CEE17243CFCBB4FD85F64A249B74454654E360DF55D6BBFE5DCBE9 +AEDFF628B1F054645AFF8DCB417683CAA103C4FB59E9FCDEC985F0CB8FE454B245C42F81 +BB62E1128B7581F1634D63FA0DB839B631A5C46A6AA19A0586FF8E1F36639B416C2E348C +2BC4A28C9A4BAA5274EAF37037C0E0B1F74715F5DC6040AA6BDF49175744A7B214F90355 +2CF60765D50B7A92B7CF05BE188C4934EC815F2F3C274D5DE6945E5A25631DD732EC10A5 +D1D5911919442FB0BA3B411A655B8E9B2937D2EE2B317A9F8656898B2BBA3C93BF7FF001 +FEEEB4701A01F6493C6AE310789AAAB18E543F822AE6389A95F8E07F6948D90DF226DC22 +3FF6584CF81705161648F245BF7A95ED126F084190D003824AF91827912987CC74BBD073 +5898D710810A4057B652E46548031A2473758D5157BE9F657D6AD6E598FD6EA797F66E6B +AADF37C84C671A8938BD6ABB7B9B3B793EC1B8A70C1284D8C31B180E68BFCA71428EE2FD +D10185264F9AE8049B64DC56132A74B609867D3B9D4815D1BBC83A6CDDE66504F2917544 +5FEB2E0203BE174203BF266862F83828A462BF880AB22EDB59CB180A8E0CC4259E4DEF1E +1F3114AF8C03DC00C7B1F39027EBCC62D308E1A99E9C0B4AF746DB1BFC872B10C8D1275A +93128F35E8883DBAE47AE1EEEC72ED408ADB618C32C9D780AFC63F1F4D3CA1784A0E483D +401BA2C3E2B8B9A13307028DC563727C72F97C2A7373F9B8B664782C69999D827E4EA508 +585A47401D5274B658CC683401DB1B0977A4214BF0E747116F3A2C06F75395A4A4A5D8D2 +68E17F8AE00E264098436DC1054456A72D426FF4DD84EF7AE9F4C49434CF6C9218E7B91C +EBA8EA88CBF22F4F2DBCA527FCD11EA79E4E5719E8FDBFF5ED895F5E640353DFD38F6D11 +BA785ADD90035A3D7BA68620F26CBEBAACC14E13C904F0FD147D0D6326D94B42748B7D72 +94BF4F97386309EBC593B8BB4AF0D09C2EC2C666CF0BC151CE7F7F763FEBF83F521CF115 +AE13A8C069F3188140C2E1208BCCF8D05A3A79FBBE8E58232A7438DE1EE565B56146C9AE +4DC0CA21A5F17B05229FE0373C3291266A413C382CFB63365ECD9F80DC6CFF7C37CDDB9A +98786B3130B61DDE400B3383D300974B9CA0BE9326C2843267B805D9C2BDB088156A7641 +704B203D0485852AB3017B851D63BB4876A3CA32AB30B87A3A9789D10DD76168B2FC0BE7 +2DC6037A9ED4315DFDAC2691ACBB975B777FA7460A851217B7328BA52876260F0E9A43E2 +962A80174051139EAAE4773184190EB46E72554267C0FD1B9388271B7DED405931F65479 +FCC4596027F11BEA64C684BCCA6896CBE3BA2CB2F71C1AA16B55F63D27CC239ADEF62E8F +090863B0659D8E41B45B65F91BA24BCCB6FF5F37A03320282156468CFE46F95612300B5D +1D811C58AE9DDD905174565900634F0E20AA6D7A15E43872300C876087B005CEFCDFBBD3 +10D23C04EA817DE15F350C4F90207637DDCD73BE0834A1651709EC3EBC1F7A73457ADED7 +68D88A2653796D132233C25030EC8E8159D128E2260D60F18097E68B95A56E3C590D4F0C +E778F72FB0A5E182264651B3B93BB5115BF14FB1D71AD9C9EF953344C4E7B04B16000DF7 +0D8500FB657C4D368B669D92638E0FB331EC3AFDC59E75730FACB442DFC31FD087174379 +B491511BC6727E4C31C2FF756C409508979DC47972A9C0369BB61A450BC888B21213DFCE +0FB400AAFE8B250112CFBDEE410B03F344E1C6E3A5743304D23BB7897D6DD6A052346AE1 +66C20F309083C0CC33B1B7D4909D8218AACB35134DF67F72752F697C4A6C568ABF2A6BA0 +6138D0DC6FF73066A5E9E559E0A25A0E4BAA0F0544D680C812E16F70CC0F3521491ED1F9 +747958D476519258AF9141DB94B1599F78D80AC9FB2AF393CC98B307DD3DBC5BE037C41A +CA0450771CD31D126F3577A82E0D32E1E114753962A635DFB27FA9BE95240B38D4B20E64 +651847E20DB85F80D062E80D1377EE0D6A751B5C5E5F89E6A9F09DA05C3BA03ADA1878EC +6EAA9FB0E3D4A8E707B0EF507256D60F76E25B61421A4DC14CAF733B03F43951CB3A4880 +7664484002BCC03695237E902217ED414DBC57A89802EBF93D4DF4ED83E5CCF8A79BA8C8 +92ACD02A4D1BC0BECB65C3D2CBFFB5B11CC143D37EE56A55338854EA43506FD200B7F350 +EC0DD9A283D0C46C5D3E728F920875DE6D3EAC17B025CFD20823D2C435C120D20F80F948 +6A37B71B68462D9C38AC003E66871047A6DDA56FD5CE319C209DDDE831FAC80D8C6BF498 +DC6B58592451BE41740BEA4766E0D71E540EF881A9110CA16E9ADF2ABD9FF296279AB2F5 +CFCFCF8020D42B01F4CEA91440C7634A4B901E5B2377D6F37174C692ADEF3337C616119C +AB1735338F2E3AE72B22DEF9735318CF8B69F23E110D8439365C67CABA3D2C16FC96FCD7 +5076AA46F4F5B0DCE6E2D5250E2026609A76C41410B8CF45DC8BCB815E45C07F0C248BAA +FE71A474EB9CAC749EDE8FED1AC13AEEB5549AC306B1ECF05DAE05E5A339ACCD9FC8E52A +4EDD4E2E5660CB8640D7DF392BF2CA1B0864C01472B4ED4A7649719276F3709FDF5B890B +6150DBEE2EF12390B63FAF9C65AE46AF648DA2CAA1AFEFA6982E07C63F810D044BB122DD +2AA67ED2E98BC3B7505BFAD72E05E228FEB9FFB56068FBBBA1E8193EF539DF257A1D3019 +3B2E42386E6017DEC0593454C76E13DAEC50FCB81BA6ECC997225B79DF89783784083F87 +BFB92457456F60D9424C93CEDD40D4D462359E7060282A5A54E3F8F54C86CF6740A8AE60 +C66DEF9B52513D70B64FB40671EB762780F36180F14724069D029D1B43DDB672A5A6A9C8 +9BBBB54CE48D4D25E61A670344B4D8DDC7E57ADADE6CA7A1BB5134276528D0450E5DA9C1 +B8DDE79D25D3DDF220204561E67855D168FD7ADD01F497AFD5D3E89DD83E069486F55B59 +B91823689873ABA14D5CEAC606FA8393F1B34582F871B6C4131B9C483A4BBED1CD69BA47 +37D050F57ADF9C806CECCDA795101376838E893016CC92DFEAD0699E6BE626FFFAC028E5 +462A1E7CA9AC3FD199B4C4FF894A3E695E18646BA33B900365CE6B810C7D53DFCBD7F8D0 +D6DF20F3B09ABD2C7E862A5C8280E55612343FB741297A6BB95FD9423C4E0602A8F8156E +365AB54540AD5449FEB3E4D13C94794F17A0BD06D9E26DC3833C87FAA477041D1394E0C5 +993507E130C4F60019FC0B4B74652B2BEF4A9603FDDB3A534001448A8F691C0A97267826 +1CDBCDF47FB4B0A7830B434F180625B451173BA129726834181EAEC346CDDF68F32A57D1 +5ECD44FEB77C2054908C6F6CD73DF94E4FEB47EAB786106F25CEC7020AC7BCE0C45F7935 +46E02937D310ADA5C46379838E266B25127413F0AAE1AC370E3C753C6A7539C8AE525CE8 +9BA7C49158D4205E10C054DF541B7472A0A6040E68897ED029F42E013E0B8EA547A7612B +157718C7ED485CFE6CF0500C88A0CA1C96A2320535EAAFEFA930325B59E551C8D57BBF90 +2A5A7785E69CA885CB7456ED7D063C93161B7F0AB5C4A33B19CD8F9260114B75BBA018E5 +CFD6EA1CA19DA6A157C632769EEA695B634311B4168E776F9B81AE354455AB0E9BB355BF +1AD45D85173062B1B2E66F2820512ECE3A912A5383AD544FD4B0269E30EE1D120EA034FE +5257DD2B857C4812CFCFF94EA3B8AD00E18C2AA887CD8E2801740C69E148DCEFB34B4897 +84D875555B9362A35304998FBA3FBFA98D6902DC326F0F407751DD3ED02C77F9B22D768D +B8C3BE360CED4964E0D413D9B288E403DC8E6D89EB0B68B4BD3959B151B45FA8BD1967B3 +70D20BC10CBBF7F626F1B4C3F125833567B9E88DA21EF2CA6C209DEC8EA977752467090C +0467D01B5B0EC2ABAD8596A3A342B120A7E3103B009E8BA2B95378DB329B917C95587A82 +EF5F72890BAAA37264BB4555F5C69D10A4E64A462ECA8B4A1BB166D88036BA071BC33DCE +3E79FC9F144BC2E446B720155812C06F10752D1391963AE98C4CB8B035C3C8E2F7CCC529 +ED8AC3A052DEFD0302D1F4D5A1BDA6B042C1D90CF84123DCE6A7C29B3AC8FEA16F07A210 +3B2C7098ACFE7FD92682FEDC1132EA886581B798496D59B5AA47CE3BF3A9C7CAC6345386 +F60ADD73B0D52642F4E87461B1C2792155D2123D0D7BA43904891ECB1573D871B973FD0B +52D76A445B55F960BCD3AC44BF762B7AE12DB4FBBB0409C102445C759E7738C4D3FE2BAF +B97DAEB3517F5FA545180AE55DD7D4A0BB03EECADD21902226EE99A7156689824D02FBFF +41FF30B9D94D14348BEAF7D3710725E9A8054DFFA2794D7D5A90482E9A49600885043C5B +E0E220ADE6CE0FA63C5826CADE8A8363440C47E6E7590CC8F5D445121E8F8B947D8DC4E5 +DB5301E89AEA62B903ABE3AADD4E93A49A83B0BEB040F7F2C320301042CC9D31CCCFFD70 +32DB766066FC83EE7109C6D8DA79610D5E1E94848556E4DE9FCF55DDF8BE524361A4D673 +6F09CB8AFF3347C41B9397538ECF26274DCE7A27E76301007A492E0C6BECDCA0B1C9D1E5 +345AA204F29F361FBAC0211BCB444F8D9B9637791F5D3B869A5117CCD73EC5124F1ECF23 +705209F4CA831C5AE5BE9EEEB390A8666BE40363642DABBE28D1E06182A95ED0F7D1177E +D3294B4C29D8D1FAAA210543C3850FBCBAC813C21AF5D62621623DA41A27F9DA0ED6B0C3 +A2AB61A913094FA2574C52FA1195521962C8D6B8DB2A10139A9C09AFAC133A8BBACF0A86 +01F38217602E70DB3651DBB083C791E7317694AD1F50FAE278155390264C32975838DE33 +CFB0ECA1B0BD993C2A02E1DC2F46293018DA3AE825AB81621894620054724C3A8D95ED48 +1E899F972E6537B21FFB8A4C55319D15A03ABE885C333BE19ADBC450D58C5DA2B76DA6E6 +2487A71FFD2A851F0551F17A00D165FFC44F204565FD24B0D11C2C21238F5D6F64277FDB +4D0704DD6271C69F4A5CE05258832BFBB7D303C00EBF68DEF694D77215084C74BD2D89C7 +8FCFA635F694723DC79E99D87F03ABD7A06BC1BD7643092790AE2D15D63D2C98288AD284 +7F48081116C31D98680BF2C03E4C2FE4DA45851E4FCB6FEEA80294ED5709A796716B134A +8EEE8ADE6C3709541E3D234F952B4B2ACD1422756B8765AAB9C32338736207BFD12DC05C +4D7496F1AC0797D5A3047F9449A8C5237C75EFFEB8E157B262A833BFFA03A26CA8AA1188 +84426DA94B43BD21B1028EB2A6A30F41179DA886DCBE99AAB28A1B329BFB743ABA0A2F4B +B4C400F1F3BD3C9A0109F63EE563AFBDC1591BF3CFDC863429A79F6E0A21A749A934EC7A +08541245B9F3CA401EADE0438C18B9FA2A78B618F38C611F6C053D2F6A0726CD20687DD3 +B09863DC0DBAF040D15DE51397DDEF2712F688D291B71DB3F59A7D87E2F44FFED1144981 +A11BB9824B1F4FB6C9A1CB11867A187796E5076C811A9E085EB5C202E0CDE461CA541CAC +D3FCDB4031FC78D7410C4D1DE558A5B697F03F9EED11F731678677448420B876AF142242 +574C740985FD2B6038AFCF1A81C4D89D00C73A09C93AFE68E5158B06B1E4A5122A371687 +93C5744583791291A8B8C2CCADC8C1BD233285F91C87566E36545ECBF3A8D5F9B3721292 +8BF2218F2242E3F19F91120CDF7D7B118392A4F3742911D47C4B6B2A61A7F79378DC8DB5 +9DB041A761DB0EFF44C948341C174E5C6660DD5D3E5517EEE0DD88A655F3F9524168CDB8 +AA2A506EED7498CD8A320E2FA42D10B1F16F8FAB5B5E85DEA6DA3005ADE58DB47E35C71A +C9527AEB0DB1B59D7DBD35A5E5C3643E17139FE1BAF662C7E88031D01A9BEAF71A18DC76 +F8AA4EE94C2575C438BCEDE9118D5124135A071E3DC0B103DB08D7277EB7E9BBCEE953F9 +77E01A009A031D4A204B87C0F0BB722508B76E4F4ECE45295A2FE89A1DCD981EBB4F9877 +246527356F2E8DDD3A67C8A39047F4DBD69B37112BDADAB6342FB6C522FA37CE74FD74B4 +D37D919B612C91586A2F1EC2E1AD95A5DA5F6FC0E260362765A262386FD8B9C27CE5FA84 +EF0B7CA9A77B1C41DDB5CB9450AB1366C00176A7D47DA6E4BDB2C1C548426B69987EEAE9 +66F4A937FA6597B2A1F2A690C3B467C57DC1A6E271B4B4FB7A60EFE602B5A2CDEA496F54 +073DF69EE58BD31963B17870B41EF97E852E286E1EF07D48FD2CEE44F51FBE8FAFE8B171 +82DF3D6343C85AAC1F58494274574A6231652AA194027CDDC257B942A7FA1E9002E9D75E +80EF552962CC5DD48735A14C8B81020C167319755636653041031E89BD815A299BEE48C1 +626BB77614622D88D310B0E19CB4A9E57C174BC369BF13C727FB452170D9E830ACCA78FC +F7F0148CA9BC1EAD7CA3BE325B60C676B3C5AAFF6FCA80FBB8737C7BDF51549439E06B38 +79D71DB53A757EC2C2D66FFE2CDD0C166E2981980AA2166112BDD1B14C19916A14403BBC +7E0FA36A3818F6B4D4711BADDA0B113F6EEE39916EC8952E6A7858BC65BB175488A6BB74 +6E78C5D7C565EB59ED211C5DDA7443653F6467C403F9725AE83953468488A6EA8237CA9D +538328329A8B23D3C96727A7BE68B59048E394D2BD3E9B5B97E6C88DB0D3B2CA42C1E845 +9B375667990B8B28CAE32BB63B8973E40533D1E5FCB26B2F680F985DF33F37AE6F32B9B4 +CDA270B0B060C8E511A0220EF06F0BE429D2B977A3782A086676AE58C244D74E364533D7 +467DDB36A7B93F27A9B729BB3F0087C01E6E38ABB26A2CCBD35F2AFA01C1A085535F4427 +521B968EF7DC76BA612329090FBCB6C99F73A61BF1B3D0975F2C7457666994C94C5E6FCD +4D4CCF29DA3E355CC64034655471885713804F44081F1F4C426670A0390BA6D2C25977A4 +91720310D0421B3D5FEB3C88BBD35B2D4132497904A74C3535A15B924023C464CD70D227 +F28490233A568AFE309F6908C0F369189803ABA18497C20B5E47D5D969DA3EFE03059316 +C0CC37688CC42783823A1618AA7C0AB924CF1D4B961CDA7DC6FAAD0E8F742D33ABC15730 +CF0E246173CD0A8F21466C9A4A9F86EE6ED508BCFA0E4AB5AB079F1EBA14D78E4B562F81 +4A1F870260F35D55D415CD2C10EDC209F23BD8A0A0ED6FB8EE11C30EBC2250559B02221F +7861C08C18BA12E748D7181EA7314E355E27EBBE1B3C00C69C549D4442998259D9966E9A +6C89F9D8796A0DA2745CE68C3D15368621F9AEDD74264565EFF245EC7D5E235D524D19A0 +6D1512B3A823AFE1944DEEE38E6C365D8EF2917C382A537FD94DEB1F7A959A69A3990033 +F48466A241B4B39E8AB9643677BF42BFA3080B8B389DC2BD74DD9CF7D2D466CAB7CC7EBD +33FDFC9CBBC0B2A0D3176B3D5D9C78B121705E9AC8DB4B76711A8D299D6EC76386C78241 +FBE1887604B50BDAA81187B0987D0B7A2108A32BAB0406AB8977F4EB25957E88F93D0CDC +E9121D49CD3FAB7EF4B4627A731C43E7198EBF05E662A2A81F46E0C55510B6D47A5363BF +63A34E483316B4FAB3BCBD0F190F554E8133E1F31745424E0B29C031D84F24A1250CC3DC +28384EEA40BDC069C457BD958A8D2ADDDE965903B436FE8BABA1D722F82B6BC781980B54 +86FC63E2F918716776F756BB91752A0F591F518CD941AD6453AC1D5ADB8016E17F0367EF +973A4F6DF74BDC2691457DB95EA4C5729031B8397663BD0C4388B8E514B279F0F003947F +9DEEA6E76F6C3D3BC3F64987B5AF5F7D520BC76119DD36265453DF598CFA741E9A404704 +4C2AE3E1E7472CC11BAA4D5A32304447DCE4A766DD19A50542BF90C3F1F93BA6669BCF83 +808634A13FD2AE46048C42A90A8D0768E3BEE2B902E564CF27FAE1AE71E5862A8554967B +1BC8FD84EDD3410EADF57CB3E4617B65B26A2B90CD6D47E7796217B51BA60D29D81F424A +4590B5A8FAB9B7404CD142CA01B5ECDACF659A4B4997BF1D1B6F9847D3BF5102CEB53754 +1410448BF07E8E49786A718F56FEE3966C4852147B9193233C8008A2D2DFB70448078B95 +81FA5F9CFBBABBBC5D7E6BED86C9E69E71FB53AC96FA096AA8E6E46B67BD96A58A18AC48 +854D5C6466329B0A9C7C910A0ADFEC02A784B3553FC43E4C2EA8E1382AB1D9C103CD1260 +E3709CD18400AF2936AF02BC37FC32054A73CBF36B98521FBCF62D4F25FC7E0F3989B25C +084FC5B84F16F1812B52D7AB115F0A80DA3D846A3DE4A83C512778B469CB887EDEA0FC37 +9581C927228B510F441071FC705C98024CC64E9BD21CD7DF90BAE4D271DCEB183FCBAE68 +DC78E977A8D23206CD3D7E3AEC0E8607E24A431C6E24F649370C897A65FECE2BD91C7D82 +F7A1CFA96AF95891FB8A2806CBBD2AF6DE7205E8E7269DD0E8703758F93D0BFE29CD178A +62BE495A0F7574EDF1679AC65A72C43131B63AA8507A225C447CB2D71E0974A1405E5CF2 +E13C7FE15F3FE046377500E9C4A1D0C2825E49B8AFFA5B54785B39D27D181B0AD38E0E1D +35C03186235676EB44E268F6308B17B45B2AA604CBBD05E33497F4788E969E01EC50A3E0 +F8A6CDD1CD8950505828E16F2B85AED36EAFC45D9466045D43AD9B3B3B2B92D5AE0A383C +4C0D8C27BBA70E4A6E7F4D134E4D684B9AD5BC57F19810F88F618F49C66DB98D76F950C5 +25AEDFFFF5641D0DA2532994BFA810022AEB15505DFEB561227DAF7FFC9B2E1578108ABD +66424877BAEC36FA8FCFCD8E23ABD236399F4AB2FCD5CB2DC84B80ECB9C6EEEE7271999D +37272C0F8D1A306814BA2D302F7A3D8C08EF5375B38450E852820875DD008B55CD50230F +9F1C513684B5A7E0BC1C992804AA638CBEDAB8D673556F9ABCAEA81059B0EDC0193FB823 +92E4D7B739E8B0053F84B7891434CDDF773E15DFD66122A300E0A561CBADBC15058310BC +C9E44582D513D63E90832C521CA6F7E6C70D3A9F461BC33908F1773575043419B5310F74 +1FC502C5E52D7CE3421D0BA35BFEFB54E477106DFA69677F822FEE85CFEAA54EDF1E641E +D5E73F733F3021A0CA6F5CD5EA5ED8C09B1F3B1CA953E92A4117839A678572DEADA59C50 +BF67C6367BB03CE4FBFEB71F652918939FF2B61C6A89E2278D42FB30BEAF2CE7E6ED6D59 +CC0B941DBB15F4BC70AF627817277ED59A95A3FA22FE35AAB686FF442237C1B4A9FDF6EF +62E4F90266EEDC96AF7F7D538DF26632B6189C2C74F62106734308EAF30D9A6E25A8FC26 +12180B467359D44B592BC4679DBE01856CE65D2E0FAC04DED5207CAF770198827720A708 +E0667AD7A3EE70879A25C40D468E307E01C4EA8B0FB67A854674010A90CC42CD6821F717 +19055EAB05AF9C9856C6FB31850960CDFF7CBA473C4098A45A1E15C533182D146B64D9D1 +BCC4EBE36F926B2D4BCA8737364CA448CEE8A27610425E06420404B99D7C2FF4E02A90F8 +583262933685471C74FC236671D814DE1F3016BBBEB1780E4DE6489CD71F5DC6DC2BCAD8 +D742B695074F28EB6A91DA6977D8BFEE0A7012DF751455F36459FDD63FE1D1317858A2A0 +EBCC845331CB6BC509661F464ABB2B3341D1AF150993D73D547DBE8E13A249B4CE85D9D8 +3F35B2B7AA450CE28CD22F826F69F7B1F7AC8D802D97FB20536ABDF8CD275E67C22674B3 +1C6B69C7C8410B93FA3FD167764F2DE0DB966B9BAE9168554D718E00A5017263D49F1CA3 +443F1C126EA11DE16A4D19BFC9BB8AC52A5471D755EBD49B535760254143E163B22940A8 +0F2AC318C264DCCEF794B02CE91CFFD152416C37AF6F7F1D151F4143FB808D10D635E811 +CBFEB3EF3C291F8CA480769FA0D3D80E1ABB4199DE5EDDFCF720D95B1F7E57B80D529A22 +49AE1E2DDCDD4CFB478E88CA5EDC7C4A97B7BF8D1DB4CF194227B699D1A5884FA7163E87 +7117F2A46897135F0202B6AD25EA7BE2AAFC933D1E3761F0DA9432A72BF4FA0755CF555B +7DC892A63879333E1D5C4614215138BD11967D5746163ADF35C13D81DDC09045989E9AFB +668CD3E34572836F7ED5981CE6ED895DBD5B7BB1AC7BD9A4A197FF9C400050A97F8684A5 +E9732512D1BA6C9F4EB27773CED4ED9E63DDE7DE003BA708798235CF66D0C7517AEDDBAB +F667F6AFC423511BC344A8CF07EB7C697072B9CDB4958C40685DD2C6317B20ED0CE5DF6C +204B8029D48783B1AE8EF5FABFFAFBB42BE9D26B4840C04FCF826CF6168DC1533BBD3452 +7D2AE02FF4237675F45ECF4C1994D45E0A15E6D03A3E399BF9B0821AACB73329636833A8 +B4937F8DF6DC557D20FB4C1A33D7E7A2411BF35BB0888ECBBAFC4F1DDDFDF71BCC627304 +C4F92B71BFF5D96A822DC9C71687C1FD37299C4BB76B7F2343741882ED86E05FDFD97CC8 +76EEEE402AC25F9B5945C48629A605632DB0E7D210CAE8C887718F10FF689AF3BC23E960 +A1872ADD99BDCB14CB388B4BED0C9730947ED47775DC9A2B028778ADD281B8A7107C7348 +FF35B6403BFBDBC3AEE99D2DF222D796BE4EEE6071ECA471DB5740647D136B49D2FA83EC +7C12E402BCBE75C7BE2CB2C058D041A3A390D60165866D1B84A5A21AD65E5B7313071ED0 +CF488AD4CB6D7BC4CE06B620262D4C3952BC443E10EEEF07FE3A1CC72F2921AFA14CE11A +40655EF499B2FEBAB39B530BB27682D3618705104D6A781ED1463EF6217F8DA8DB308E47 +2654FB4A1F5CB5A147B50FE10357E109DCFF49AC818F53621619B37A9FC57A5DAB97F829 +82D2A91D92888851F9C58DB754808668EA721894C859EBB4E09123B8E21AF0D4ED31092B +1E866C80FA135E73CB59677CD3E74925A82A6E8AB6A1E28E1735E2BBA3B79CC8D1D6531E +A41214CB887AA60C94B642AC36F9720A420E64F321A474FBB57576C2B0155450B51EB175 +D39DA3945AD41ACDB958DE15C25913F7C3D7C0AE3A6CB987835B26DEE2F92FB85E7B872F +1035CC7E7332A9418126BD493C892033FEB7A254B47623F8645C52D240C70F1FEDA77C1F +87A90806E9AAEF356EAC0758714EC5018B1B481B79B416A2D6DC92D7B22AE75894517C16 +C3DD09C667BBCBDD6C3D36AB00B636323B2B6116125F6319FB4C16A57764E8B879086C2D +F146DF03073509C72932A516FD7BF9F9B1936B643201F590D1D551C2C5D48BDC93785B5E +67F1E6EC0A5D14D59A190CF6894060C1953D2DB3C79F48844F7A0B0F0FDC3AEA8A53E33D +577B67E9213ABFB350929FEB36A97DE7658B441CBAB1F0E26B3FC5612202817A5C2F423A +AE4430703E9FEA99B861C4A8CC09F79AC6E6F53DCCEB0EE7847CBF73ECF35D4F5530082D +1AF3AC71BC3918496CE6AABC23D61A98D11BC6D7B40885FB6FF6AC67ECF47C6733390DCF +A88F9B9326B5D130874910D3E479ADA40777274C02847ACEF3AEE8E0DA0434C9B35859C0 +3D23BFCB376446EA2DE09F42AC3713F0673D7DE567E8A0A1B15A1DC88FC081530804B744 +2B0681289D586D9757631803ABE18DEAE727DBE5DC052A0A1F0E70480DA458FA96A010B9 +57E4D1CB0085713817AFEA72535EC98D71B4B9ECEBE04C51974D94F874B0E3E74D149C96 +BEB4CBDC17D81564C3C84A14F5130A08AC7B71F1A2B81CFF6682062EC4DC6D8E1BDC312E +ED6ACE315A2A28C772216C052947E079071314DD07BB321F1EC8322F00CE57D3B0E53E6A +7A2B9002F1ED47621CC255EAB1F3152D5CF2456764014A5DE60DD0CEBED98B584457377B +F67065F706978C6AA2914A68A942DF2B2742622007655BA8780AEF5086CE17B67B8B3AA7 +E432EAE81226FF8CEC95D0498BCC0FE737DEE690FEC30B80F8DD74F05B9B88794A54611B +C12F61CF8BBDD49F33C5690E1F03DE89937040BA0775FAEC6ED05026ECC6DC4D0A0EB441 +66ABCC55B3194DFC9213025725A8EA81A3290031FC365D3741922FA26E1499B93C2B59A4 +BC226A3F86FF1551DAB5F9F850ACD311DF36EE86E5B3EAA4579972223DAAF9E475F9BDA8 +4D95A89DBE06611D73BF0717D1FE0258086C1B97103CB62D8DCEA974B41388C00F176979 +E8EFBCF4FFE9144820AF24BCC47EE0597276455F92BD1FA21FE19E1D98E6E8D6BDD6AFAB +E61C7B650C109A61E1A3C6E92A6F2BD8C872A32DB437E2EFA5A19641608CF2D5E109952F +8B2D9C0F0B96322665B1698490E37E860900EC392CD42DD9AA6DE6F0E5A5EE7BCD34A538 +95D129885A10D9446993F5CFB6978DBA5B9BAB29773756B9867E4A2561AEA643414BA7E6 +00DA0932D0252E094EEFE73E2AB163397C2266CEC81ED1CB7724335E1FDE7CD753646810 +F94A631F2DCCED349080D4E9BA7E9585E3F52F77114012C081C806A447BA8AE735E406BC +532B46F55134817DC0B30496C6F5367A4DDB55FE033A236404D643C4C3DDF9D8DAC0F165 +C2B8BDA4194795FF0146830C21CC1E991300548E7A0A0B032BFBD828A960FCE987A5ACB5 +E2224DCCE6CEA1F7C6BE69248B6044ED317F1F3C028142B52DD60DDEA986214D93685E9A +F3A2D9F7899A614FB41BAE93640B9BD10CC3981505415BD61325AE4E2EDF73E7AFDBDA1A +D4DD09F759787DA42A474F1B6C134AA6FEE8CB1B5BE1E9AC6AA2D1E60F7FE74EB2FAE2A6 +BD8874F746D14A51F860741F5DCB208C461F8118A4741573CE37DFC57E8B6EEB1D369758 +7956D6255ABB0E047F04D5AF7E59DF62EE011BCB403ABE71C63490F9E3F28096149F866B +480EC82AB9BCF835EDB42F72B33526DC06CA515920C92FF73CA0C1A1F1F61FE8F373C486 +5DF775DAF6C7BE60F2DD4232B73801BE6BC491FA63205730E4974A531F1E75E74A9ACD2E +D4A9A9A45FEEA8414614B535372F94E55BF70152086AD2738807B85E0ABB2F5AF149C8C9 +9A9F38A6CF85E31358F8846145F428A89DA1C26DAFCFACAE7992CAC52BE50FBE0EE43CBB +2228490A00E9716E513C434DFDFC38263D773404743713BB490DE92A2C4F3E2E67032D40 +B31649A0672EB3E41079316EF1020DEE6DC23B95B093FBB87A0A88733645423F72CFCA9B +4B499F178EE31E5C8B8D432D5872CDC09713CF21DAAC84AFC235E8AF0F8DD6D6CE213937 +7314BABC357F9DDE5B3F2EF4843827A6F0D1DE9C8D0DB30E14F9C94FBA3A7726D6479706 +162D0071B70C19CF32BC2FD0113504C82EEC7669A66331267B4EB18C5F1902B6B2C78C3A +86E5AA1D2BEBB6AD05539A612C230DA216C24B40029A8CD96B8FF0FF000E816B6A7C4F70 +90E217124A1D6A78604D5A340C278BA9B16CD4B5518E0376B3C518E1493AFA9FDF83C36F +6F28785DEA18DD992EA6C2909ED188A31E933A0F5B521ED9C46E7A70BAD32D05AFDC381C +9EA3D56E2E8C48276A82F9EC08440D6468D0DE0577EA8D5171B678F3AC9F3BE2D5DC899A +4D945959C9990F334EEB92F34B88F256FFA564C591D5B18F79BCF9817E827BE4BA219423 +252095B90DB4347B2D54F2BE6D31B87B525D103680700F13CC1C0F72B0DCCFDC01F2E924 +B5E1442F21025659C39289B7B4AF03169F584C49D38EAC00B1910B823745054F00B322CD +174BE2AB28915D81A829B6C87486ED7EA4D44D6EDB6BD69C25112E0387FE9826C0F3F2BA +D1C6BE26E603730DF1C4CB227936404E138136082AD61492923E173484955187CE3DE172 +0FCDFE244D85D3C5716B7A4338A8130748567E0044D3D9DAD19A9785272819ADC5CC9876 +B764CA881499268F67D6FE0ED4C73D463BA920F27CC02D187573082A1793D228D2011E2F +59A15D7349B2EE7C9E7BE1AC231DCBE9DC98A2796F5FD4A5853B8BAF6F266520CEA0C42B +0AA848B977E9FBB93F77CC2F6224A339242BA2D7CC565373E3636DC0CFAD06B7C5C8FF10 +392C03A29675102DAA1E7BD4D45A2BCB6F6C73F8C3A6DA9D520F858EE0E4028FF39A7C8E +AD10A54E91112AD1A6BB7DFF7D3421533DE306FD859D5F750268EF950F4CBA3623B38703 +1FE153AB39B304EC57FC95710ADFFCAC53508224A7DFFF79AB8A24E4DF0846926EA4CDD5 +665E4F1734764B53C911EE8AB436EA08ABF1FC7BDFDD754D22C6CDD1D6EF1786C10688E2 +E2830A80A5AA37C08D1545C24EEA559618C927E4E5A1D6F83CE3CC7B100D4E04561B1BA3 +08A400644C6B49F4D5AA8EC1B5D769D16B28E1FB6DB45B118FD348D2A6F241766EC0BA04 +DD24F51F3F288D954D2C7E3B402361D6343C5A26F78D2C220E83D33662BB0CD33D84209F +7AED4D30489645AE647D045AB0BD56E20943BBC8642B2DCDDC09F955EFCD74F04337A15B +9DC924D48D1AF6AE222B76563139CC37966D32937FC5BA436843EB57761B9F052B0BE1F7 +132E40D0F0C783CC80B728B75FB600127673C0FFC2838A8B52AA3C957E978000314DC091 +9D1DE4DCF84280D7939ACCAAA46ED513080442D497C7CBB2EF36C43CB3BD66844691DB7B +2F1ACF8D9695E03F747E3C0CDC2105871F13D27C3FA07E30A27F5414960DC3A51AC1B569 +F30811EC03218F259BA3E4668F83F6670968C7DFB3E7CFF0D12CE126E4C27DE03595C823 +528C95F4B1C92AE796CD890EBE3DA9746B92A835817B6EAA2FCD276A77436225C44E89B3 +6A0066BB7AA1E94C3203AB45A6E2DAA5DEA3B0F0E068A251CBBF98D376CF76ECBEBCF3E2 +1F375D73BC558151341B01B27E16ABCD30F60FF9A91AF52808606625051C54ECFDD28E8C +90E211E0174A616C68BFC718DDF2656FA27BE3DF485F050BB57F96B7D1F6531CB2B73B46 +D21629F201D40C5A37B572428805651E2EC179424D8F5251A84384783A83D2C89B6833D6 +D0697FFEEEBFEA9C8CA21A627F50A1168EDE8C5E085B5930192973DD939E36F10AD90B9F +C02C0B116F922ABDB2A94213E4D9AB7903770FE69017FA7B28894A5CC4C66930FA7FE05D +35D664AFD098B8A76C9F2EF0A11E36B6D7362B62205AC9282D8082C15E1BA41E8A711DA1 +CFD28A83BEB3ACA3F7095FCE5880F18EE93F9EE03C706AF5547B198B4A08B9731A61141C +9A953B2A5A3DFEDA3545EAC5D7D8D556E72118187899AD1D13D51B44F1E422F4809BF42D +FF01E2F05B9BF68849A398CFC799771C1AFC256B7D333549A0A71FB7A8813D5028BB8F2F +397C1A68F22F3F1B9C2B7C2D4F4EB721E73D6E63BA651C802CE8E57F5CAE8C1F6C4AAEF7 +BFE00547D8344D7741BAE7BA30F21197146C8B31523C1C651420D130A2DBC055FD437CD4 +D92E7DD74D6F1A1027CC95CC028F44F2C5B95E72CD31F200B0A3584946E55B9A6A20163A +3EC73566552D848290C8EE0C821F08DC9F1AD94C9E94E8C5B865BEBE2047092AFCF291BC +EE941AF3156D6C8AE07E63B81F27937759F91A6C8795051BFC02164475850E295E6F40E8 +4DEC3874F6762DCDE08F738816A14E5D5423590D87B85F7E0E88EA234561903039FBC1F7 +70ED97405878F62A7AA078601FF5277CAAE4722171DF7954AF82DB007C56E59A7A59F133 +071E193E18D2D24EFBA31F3E598B9FDE11C0416579BA3AF70C8F7F0D069C3BF3FDCA150D +ECD1E82A3D7E1C11F13D37F27CA578A761A9E5EE2B425EAEB8298120429D457998BCD81E +81531F1F23CC05417FD802E9C1B7FA92F129CDB8F498C78F9B936FBDB2EBEE402AC25BF3 +CED327EACFFAFB1619E023F018E22F30FAB458228AFFC545AB15D66D4A0B08716E484F4C +FF688C67B70B3878ED20939A1EDFDF9D62FF19EBD66C9FEA31F18B6221208CF315DF5108 +CE58848845FE2386F9F916108102A8EEA1E6A4806535410FAC7AD182F6F317E0A864DA31 +35FB3C0802E830A039535E66BB3ADCEC299454B7966FEAA81861965F79C0578D5D48F3FE +5FBAD2239BBF5F107E5FF42EE8EF094D8586E8810522BAA1E231B4FBDD6CF6C62D3B36AA +8477D9273E95D66CF67F5061EB4E3EC2048518063703DFB7EFF5C2F5A3968FAA705225FE +9E088D592EEB980C54777F46BB385CD979BBFC34F3870583C13643D449A49D275E38FB4E +A31E0C69CC3CD31BD790FD0960EEE331BC1C7D47AEE5ECD11D6EF0FDAFFD1FA2C0F33C85 +31357F04EFCD25B6CA2E0800E7CC8B467D4EC22FCE69FA0F1245253B8B3E842C10276456 +ED5D4BA9B19B07B8AE60115D4F423228878C7E6461523A102F03E2C997C826B0E01A8C74 +737BBFCC420E2A864B051B219EB2F65AF711C8034EE858E8E41E93E80D519D7D5B78FDD0 +E4BC44CB9657C8DD9C37EB9ADC2E33E42B02DA3E069B9B20D7A727DE8070E17FB032C9C3 +4F5623EBABB58EE9097C85E0A2D93279EB7F6CCFB82CC798F06208D106AE7E811BB77F43 +E4F96EBDB0E29E9CC6CFFA79A00837A14A424A9E97B16F52CE9C0068C43523E286038ED8 +D91087DD7764B1DCC9FB73CB72A1AAFC3A09D353C64A8E3480D2C3E9D1F583E2437BC1C0 +529AE01639F1CB00AF09CFD84C38037DA70512DCB7242EA3BDADF8429ADEB743E5509292 +37BA921D7AEBE87A100E99B0D806D0AA4B3BA6740FBDAB5D1E0FE3716EE4957BDA0258F2 +70B527DFB9E2FE35FB0A6AB0FFB583B9529FB51BF336852ED0D4135E6408AD228714EA74 +D76CA630E0AE366233CD90CD586C9D8031173646A78B88F1F88B409110801D522DDE383E +93675E5993EC6C007C5ACF1AA8D0F10A85A144E189273AC6E135E986EBC2A85074D3C290 +1AD3BA21B44827EC7A55EFD8A429FDA1DAD0929E86FA7692CC46E7B312B441806598F2FD +6090A17540D1140AE17D9A96678347EFDF0B510A8BD31A07F26FDE43A5E012D76BB72FD8 +8A70CFE950A471C724288EA13FCF2A5A7A3D54B2D30BAAACDC818C588BDE628B30011DC2 +5CCFC66F6C7C5F780280D8E4C421A0C30749C2B33EB4AB3882CF161E116498C4204455C5 +B70C59800A0530493F63B843B3BCAAC5F025163431DF3FF39FF9330084D41A696DB77343 +7C3DBD4E794431B80E72838210F2BFDEA75DDE26997A6F28065DEAF13EB71B0B098C8209 +3121ECFE486A0CC366FD76927D530C3448FA16790C4A96F66274D5E7A71427AF984C5004 +620F3011223C4556D8D996A9415812F1868EC9744B1101FFD7876B0F0765CCA2E7BFCEFE +6AE75779A6AC7876D5435153A48C4B931D23F7AF10A71532249DD0BB4F52514EB90B98BA +7EFCB01C47BE21CF5C2C82827AECAB3666D9DB46D415C31870CC7934BA73C5736117F639 +45883151F82A1728E5E591DACEFFC0AEE8E0234EE158F45F8CE995953F2D52D0DB5D23F6 +E02079E115F3844925501E263EA3EA7C364DDB44BA125796D630202D46DE831E5FCA2BF2 +8709E4C2A8139444CB401254A0149E4DCBC69AE1438FDC782A6DD7D08134A27C1C32033D +B1707A8CB8F458B3FAC6643712117752FCBC008F2EEEA842035EDD4E50DFF848E20201AB +074E662074C5F57290E7FE6EC37D5C1C11EE8DCAD4BB3CFEF95193F16A3AC6CBE11EC609 +111C0C056856B5CBC8C5F59CE7FB37CD8F3B53FE0EE6DCAAF3C933B849FD60852EEADBEA +C506630B94EB9814AD4A9D31D2F355A3A176685CED59E6F2A6F61458311635006CCA9833 +BE5552DEA87A360F2FE23679A8C5E05A5A8C395FA909C7BC287C6587D2BA7C4C22DC3396 +0BCD0B32BA37DC1C1F59E730B8F1ED109E215993B16FA35C7859B8F8F299449CE26091CC +5E9A4893D1D1AC688865BEBC3805855B245A9E90F715B904B9761E3EFC7676E9DB688EAE +D6C5470282E8F065A2CF7CBE00FA66260F1AE895921852BBE6CCC06732EF7290620A1371 +3C98977827D534617AA33769F4A89CE899D29A6048516B0B9E764C4B7A668470CC188EBF +54D31E95714E4F85F3EEDD46DF34786702A088B30A31D55BBF6EC09153F5A170E28FC2C9 +F39EC3EC34BE68B1B13F39C7138B176B064210B8751043F03C35601891F31570D77B94FD +05420F77B5BBF0F15B62C06CD8E026D7402D53D5455D608D9A903482DF22066AA82B0927 +918EFC606CEA50534BBC94269A487505D937C2A0FA09DA28BA69A0B90EA305CA02332254 +5AABC58727B5169F010548A30B750484B8A6F33BFD0026BED604C56CE9CD713A05FD9816 +C1A8CF1FFE9A458AD7A3A0B0F4FD0E506608C58669AB9809DAE774920917406CA8E68F9B +E4C6B9D36C0A31494625FDF84661D20DB004C8E6C1CE34646992D7A2780AA7BD04B7C15D +8A696817A5D5F4A00D9C25E6695C383C273877B1F75544713AA173E9892ECFF80CF54382 +02A2513C677A4AF1C3BFF5B282C807A77F222ACF5AC497A36DF8BA7C537391827360220B +40F2AF6FCD3D3A9EB8847899F3FEEBCE598050D7CE593565F3CDDA813453B62983C0D90B +71BFE793AA1B2F0CE07F43C8D4DD8BF656EEF5C6C3CF0FE90C9891344FE3F4644ED8E98F +6C1E8C00726BC7B8D2AA8AD0681339EBD2B1BE983E36988BB22257DC27CE5E183AABA617 +D9AF549235E8EC30B37B85BC3F371764AED219FACE0CFEACF611FEFAB312466E6C02B341 +904ADF69B17706D8AB2EA734D8895813DF940ADD72547D373DCF82D1C484D7544B06AD93 +3C4D95655ACBF08429DC60D26DD8690BB9B865D0846FC0D32117612B8A8DA0D6955B38E6 +7B7EB2405F7177097ADD4CF54475866A52BB7FB9DBF8055D96586EC8C634DF0768B27E29 +92CA552A1E4B920C56DBF6E6C03A74745A0AF944DCE92093C8BAAED7B40F2185D776081F +5B3049BDF295D0C4EEC9E3CC12F9B19922A76724879D842C1851C16A9447296DDD5096FF +804D0DEA8530DC5D0AFAFFEEEC6B3057F16FADE808E85040E4275FA41A9B7770048508AC +6AAC18540E2D903789AEA54DE0AFD72E582F596734D44EE33A9A719620F0B17FF028CCC9 +A1DDC29D41D9714C27CCC48A06A49551D8F5754D8AAE52D92D31269C9696924D52A44EC3 +D483A0849738125FEE094ACDC8C09574D7FB5FDAAE0F44497115EF7C152453BF1B6EAD42 +44B784EB072BBBAAF2962F61879D74D8850B1C544ED2AD2483EC46F99CA7E5A281C38C40 +A5BFAB0500A37CADA0FA0DCD05838A4180C0DD8AABAE616FDA7CD77572EBAB61656158D2 +C27C2DA43871390F39B4D3E193CF95C19D2D2B8072857284405C68F5AE101A49F786502B +8040587DC7E2AD00DF02504FB119202E0FDFDE2DE00D4AFB2B67C8DAC5838050CF1C2D19 +C2D2F17FDA9BB90DA4F6DA74DCED5972E2F8221EA6A0AAE477190CF01D645D452F0E477D +436DFB6EFF88407904DD172E6CA5E132CBEDE212BEE43C446CEBBCC250D13467915BFAAC +24AE63D231CB519A0007AECCD201482201282B6C7BB3C4C45392D32D5E6F0A673FB8C27B +D70813CBB4285D3755BE80CA5EFF3B8CC0738C090F535004A14D6EEA4B56CDB2E70DD71F +98DB9A8041A2F80882BC5EA1AC8661C20632CA27198917A619646193B4A3EDD8CFA675EF +5F83AF3D18735EB811698BA7EB58563F0C706A2DC7D372369CE227DE737713C18948DC20 +5D9E574513D54ACF922CC559100D90AA3439E5B3D02E0ED2EA9005F75BF378CEFE680D93 +CDEA6ECCC4B3F43CA57B128FFD4ACF5020CA5258B2A03AB259EEE34B80590D44F58F3D18 +7190011DDC9B6FE1F5D9D8F1090EE4BDB4FB56272C579E33C7A3ED0AB39D96C1AA74E197 +7F30423B3E2AC868292F70B3DC9D2A1FEEE89FF3BBBB195E409C5F473BCDFE107769B6EF +E8371487FD8408D67313A1E0A6E2E448A0321C0FC931AFEABC4F648E4185DAC8DFA30D9A +87C0380046D38FBDBCA63BD498FF6F96FB141AC9D0CCF2D58971BDA0703CB600FEC9C22C +781DD3CF1D0604930CA0D8D9C35C247643892A82095F9F12196EBF4638132CC259278A69 +6BE54B1BA1B56DB1EE0F1C8FE42989AF69E38473B2A4317356A415E1FCCAB2463C80B5F9 +185D0B49D4188DE1B620BA6D108F3D3732BF34FAB723C1373FE6440296A18732444F56D2 +2E4666EB01FD9E25BB52F399EF53375C9280D7F6C3E774A8FE3EAA78EED6A94F85089E6C +FDDAAE0774DD926D148BFDA4563FDFFE56AEE78D03B9BADC66DF13351F3538D6220D5D3B +814D6F55C97A4509358DA25B47CB33923506BFE54ABC45FFCE8B35EC6EC9B5EF3AD16EBF +9FC871736AE364350BCE0C88152854A653BAC1ACA37600276DFBF99E9BB4B19E90A6F234 +A11071922039565046DB5A6912908CB86AD30FD7FE3660C06F05554A0C970AE20BB57E92 +448EBC532764FCCD1FD1F8B7E10FD0EA90E043C3064B246CF3E2299BCD5FCBB0B8BA8C1F +7A78688A0AE89D73DA9E7D94B20A3566F0870462FC72C6D7390CB82761F428AE82DDBB9B +DDEB99B653807E6257A2DB61EA8F4FB2C1D133EB3D8D6DDAD980E5DC555C4183B6F1C380 +B932C33ED0AF6426372558F6E01186A41CB25FB6CEA786229ACB9E61A133E138685C485F +505EEA8B5BCB465E5A697E2D6AFFDF040CCC78B8A7DD2F76EFCD0ECB1DB60B7F6996A75A +A0059F9458D34FB95925FFF126E616B6FF585B566CB41926564D8BD98D8353DF5725E722 +86E1B9D1DF3644A4C45E3318ED821CE90B2D0495E97C5033C8733756CD10C763C2BC5CD8 +0EE9043A531A0DE7DCE115224D0E272AD0CA70D3E206B070728E093BA13F03E8D419E50F +F85B3DAED2E7A581948541410B2469172006F0C24854049C0180D0DF6686E314757D9D4A +7F6D641D499DF6550A60ABA333DB90F4615BACB3C808FF6F58272CC252236B29FC67FFCA +5ED9063DF8100D915C5B8F10D7B1AD3E848E797F82E9B76786A4524AC083B09D91396DB9 +05F133D6E300AA5FFB1E1D161D00B4CBB09DFEB87CDA9527A23FD4591E2DF7E920A3F4F4 +26A7D3AB614E8D45DB0399550E166F01C4C4F660430642F813212E24C7CB24CBA11EBAA7 +B9F63BB00955F125A92658AFAC7044896843138F90299686F549A427A542B2588230C21A +09938ED97A7A6382FC70174F303673CE2AE93D8103F5E633298E1DA2C36908F6F6039FD8 +37747FDE7F714A66CD8871AEF65B8A68529FD63F87AF84F3AD411F820AE9BCB84A7EA4F4 +3838492DC675D80FD615CFC9D6EA741C6B91AB432C0CBFE06FFCC562D71C6440176F39F5 +3D810FD4D3810E22089724E8A7F53D295681C2E07334D656EA4D3F7AD037D3B9C760042F +86A0E2240343EFCAC8E2578DB30BECDF093CFBD0056110EF5834A1E683CD7D624B04AC43 +A663469E0D3AAEF64944EF7C43F8FBA221DC846E86A8866AC53384FD35D10FCF34EB7404 +BB38289451048BBBE520F6018C3F3B8F6FF3FDE4C5F33D89E44DBAF04AC4FC17A4196676 +F16B8A2F02FAC4B8933CE617FDF903113354619906A8637566B3E61FA8C849261A625CBD +87BA5F1EC6479E7B9423BA14D9CA0C68E11BEAF1D1E948DE44257986388E75DB6FD9AE41 +13C36EA637EBD0812F272EB8381437855C7B0F262728CC886BCB624437F8CA30F107427C +7D1103CB94B19CB2129FD2B388D62CAD6078EB7528810DC458907A14EA0CA0B0C28DABCD +988174387FC28FF98B7C9BCCEFA0407D138828621AF7815C13EC04F7FCAF82ACD3E8E773 +B886BBBE2C4F2818E39A2D7F964A29B9E977F53C7107EB586D628F85798E70489189808E +159E28A8D81FF9D642F3FA4FFDC2059947719184D1E83FD5EEAC7FEFD5DE2DFA8D808AAE +91FE63E94AAFAE17FEDDE11C1EE21085438581DE1F5EABB4FD2A2C3CE0010492612F5797 +163F19DCA534DDF49FB45D0381664FE5CDEF1CD0C319B6748AC4B8996DED871EECB3E223 +8E924F30CE315DEC278EB94C6206951B2D4E735463650B5020CA8CBC756618AE1D8781D7 +B22ADE2D20CF71A9ED08111EAAF4E3DB1F081CE992ED1F7BFFF2B883EFD95F51CE612CE5 +6588D7A8F342EFB74A989AAA55ABCE83A773333315FAF1AEF25CDC4F19FD2293A51AD64D +A070635BE2763AEC91BE2DC9F233D8968860E76352E6DA9F7E5EAF068E19CF1DDB22EB76 +FBE149738F247F4369273B6A901705B7DB396F662986D91803DE93D89B8312826CAF94A7 +80EB2EF254FD8F19710452E7EA41399D50177F4A8CD017EA2446C1295B6C1598BCF35060 +4288FB0A9C7CBE9D94E6517CECA11528D286CFBF0D621DA7D93C7D1029FE0C70F20ADA26 +E05A67C4E301A086770130934D6ADD3419070C6E2F0173AE4DA51F478DE9BBE3687D09A3 +A48D7FFCA601801BA38BB9D87F091DD410BD354C24C74E2E049407B8A3A98F90FFA8327A +6260CEEC0D9CFCB9BD04C3C08FEA15D0884A9017E239335985C85E17697F874DD3EDC192 +AB8542A11C8B5F50A2B737F27E9A4078D72ED0656D5AFD0EB04F76565CA2777930DC4B0E +62715FE6D2A8A78D8C0187FFF43BF6C434DBB5DB369F4045558E5F4F047554D4641D02DE +A9A78C9B3B64D32D3415CA488D399273879BB9BA3EB375F630F273DAB8EDC0B015A3728E +B55013B32BE513A0AC4769876686C9816035C2D199E955DF7A99CC07B680229F2E9C4302 +D5F7F4DD4B9C3BD69982E0DD8699EDC973E55A259376CBABBED36F28024A9EA504154EEF +B9F2C5649E7338C52CD19690D7BC56CD06D5882366EE32FE4B56D7703237F3D38A4D5C07 +F4B851534F597A1723BD364620757118169DFEA997B90D243990C23B6583EAA176021C29 +923483CC99E04537F611D02C44E99A05FA78A0EF13F05F695F38E3E631750BC0427F162D +96057F1A50A392131DD979868B617C037D26CB9A92F478C57E822C3E946B1A30388A3813 +39C0A4215EE9314A42BED741A0345B13D16F462E60E493EB57A775B3A01EBE558F8423B3 +047BCA02DCD80CD35A3AD41ACB26D75C92B1DEFF4CE5E8A8332AA185DF670FA87410E36C +D27F4064090E39970DE94F2A9476DFAA41225BB65C0103F5F2F277F932CB3B1F273464F3 +1C6E88064995D7C6DDA4C597ED8C8AA2174DD99D8769F818CBD824E04EB3458DD29A78B4 +1BACA60903E1BC1AC6527351EE55A550CF7BB448C3926E5AB461E374AAEBF86885B8D912 +23108CA0D5D57C333DFE6EAF41FB5C7071B83EDA33362E2090A76DF9832BB5DF1E3AAFFE +135801E3634415E1E8A561360B599DDC5F84F3DC12E3A4DA3E325A67DB748F6768D42289 +0520E9FCA4928178B888C4BB626D82D9B52DD2A8558BE9A3013B4492CD8F11CD4B8CA79D +771D9A9127EB7D3F8AC0E09CF86F94AE011B568EC3A12B6C8B930084C0982FF9400E5308 +23E79DE9CE44B754947CF6EB96BB9C9FA45869AEFC46A19F957B677E93E25D7CCECA4389 +35D70BC5C89EA5E2D1BC207365D7950B8227E70D4CBF3613A1ED87A7CF85485DAB70AC0F +3CD67859B72D6384000CA9B3831D32CC774B27AC9A2C21A4CAFD3493A2BFC37464066BA3 +4A4BB4BAFA36019452F8A580C4F27BB5D81BDFD8902B510FE95DDB23CC43AAF71E464CB1 +AA6120E3CC15775000BFD24AD031F000F787696A6A6FE9F2EB409B259E706BC64E2BB7A3 +286718CFDD3D1D2F3BBE7218949E69815A570AA59CE6545BC1A2036381515AD097A81D2F +51AC22395AECC7D208F77CA9ECF5F2C121A7854AEF87CD2170A1F9F7FE9657F2C5C77344 +F7F07A90FC698A63382D7E59D7EBC856553BC2C821A6664E3BFFF963C3671EB7CD32C9F5 +AAD7CF79F066B847C533DE4298824AF0DB3C96B780358DAD0F71CAA85AA876EE8C056864 +FC9F11FBAD9D966AC00667AE21F9DA3555D55D81283142FF4071541CEF9C87882323BC72 +454D5261D13BC65EC5113899474CFD4C05D13D8FCB5F3A49A4967B8C46817DA1E71F7EDF +3FC7375ADA580A715D37FB8D56B2A9EE3296D302AC10A9C5AF7DB8E92C39EFBDCF74D102 +C9939DB7F7C2293A9BF92E3A81C2A17B1C2048150935B977B85EB6AFBFA266ADF1D7CDE5 +8EEADD8B2D7D2EE4D9FF56CDD2CB1CBDBE229B03353D7370F9149ACBF086403B96B6E859 +952A34C0B58B4891E029FC505417DA6175CC8786CD4326548C65941E17587AAEF46006AA +01599C4D9C3D66BC8F7776B38822AABEC1D52E1B29702C498D6583AA9BC40F656DD6F74D +0528F562A31E90F620B7E96FAEA15F1F2F0B68FDDDB00D9FFCDB10635AA54C47AEB4FF60 +EB3E40FC4F82A0F73B8440023753309E443CA66CBB5C02CF7D77DDC5917078EDCF50BDEF +1341027323183AD881EEB8CE2CE4B983C611508E8911F098ED89DBF2ABBA49F1E7DDBE0D +6BFC1EE74A839F7CCCCF4A12339519C2EFDA56941A74044CF1B0222361ADF02CADA96F2B +94AF954304B3CB7635C2E7E6BABDAAD0CADF6127F63A07BE097E6C7FF598272D39D3EC65 +4EC2E9B795C1E6A65C50AC1D540130B16DB5D763B9923DAD3CC2D8DBA1D3D2158C01EF3D +0F41E368C49FE8AB6DE7774CEB1134B1FED9E8911F9C2F29B8A65D2F030B966444B96EA3 +48E804BB6343A01E2A5A4B3A39EDAC4EC5A8F9F8BCB4377B0A10820E5B5FCD84A1343A02 +CADC1D5EC78CEDA3EEBC08E795D41C30390EDDB0D6228C706CF39C2989618E1A2C86FE80 +32E093F244E65BBD5AE8EEB19AFA5EC0717D5A0365890E707DC35B2B56187314BC1EE8AA +F3CF2A8E90B5A04CC30BEA3E50101256E48D0DDAE0E8DE05D62DC3AF06655AE331010C67 +EF2377D07B7075866B905644D7003205A1D9380B56386E291962F5A8CC209C4D540CE82A +02B4E654BD66EDEF1DA488CF02B1F37ACA1566F5FF3E4A25E9DC0FBE6F1CCBF4315DB6EB +F3027B8751BA5BE3E68C3B428012CDD1F23ED25C9F09B53321698639D37C581873723846 +06606C0B4E522B57B592A205EA908633A20BBFE46689A9C749FCB2C1BA5D4B3EC7DBF4FA +C810240BD7D2CBF721EA3F824497D9B105348C6DF4E964AADFF293FB406A4678D7E1CD5D +24E189EAEA1CF128CAC24C3764922AC24104808451776ADDF427A8E1DE5227B82546F1CC +8FD56C60EA96726924AD39459785E481A86C59E43F2964C332FAF11BEB87EA9F7CB71920 +1E31DB06A94C12CFCFC4CB0E5925B81BD827842A8FF3021BCB63E9CE7BF8984006062267 +DB5F53DCFF1F1C08E053020257982E81CD41F6D55D6DC148CE7E1588146E2E7A721E0C63 +4451BA6D6B0BA5E1434EA112CBC5BC508BAC211A55498D30FEE9DA4BB5D39E19767CE082 +CE5E2737B404708070E8E6F325D8E9A705398C4D2704CD50AB6567411B18D49F2D55D690 +CBB1B4D50EF9893F8071E8423DEC6A6738A92E527446549C87D4BE374C6BAB141331BE47 +B0A1415937AF7A047BF16B2AEFAFEDF28D15B66C241E346884870E8F3ADCAE8A1403CC77 +1EBDBA2F12EC4BC01547238E69EEE4B08FBFAFC2E81CDE882C9D7558501B0BC04175CA89 +D1EA401ACD6AFC5AAC4128539AA1F3ABFA352F69A1322A7E505F68774598F26EF248F658 +D0EB1ED0278DC608903AE7D8DB3A2FFBB486057720D8F7B6039C2BD00FBD67B73E183EC0 +D539325173FE5D5F6443A6D98B967ADFF599124199825EC044717674D4EA3D0CB23058DF +D156708E37DA80BC192F0D51ACD25D144411F856E36B135403F818297025F27FBF7EEEED +1D964BD4F0BEA178AC1780B1FAC7D64C2BED556696F164B97CA0C400F8ECA0E508884249 +8F32B23F9AC97B52EC55580C0C7DF9EAA9B8DAAF266DC0A02C2F3AF10D756AFF097A7610 +9C299FDFFBAC8A6C3652285901A145DE49C093F4AC2BE72327C35E6F0756F18C9D219D28 +24230C2F226FB0E9E47291136B363658230009DD11F2A8F23BC2F90E7EBFB384E1BD8E75 +42295AE84096E3BCB7F7E7ECFB394FA8B2C9B4746455DB755A59613D085C34D07BCF89C7 +2EABB16DDBA4C2C09B48A5D21D75CD9529E4684F29479264C9DF6FF211B72559F0BE453C +C83C1FB4EAE42A8DBC18B2F0DA7DF4CEB2EA36129B469CB59D74C5A6897676B3855E9E28 +5F0BCD467538175CD6485237686CF42A046B714941BFC56FD1ABCDFD292B5368AE331149 +B401F69DD62B294FF941B1CCDDEC0DCD5507889C8310A6FB7D7F3A9F0713AF8E52A5077D +10ECCD6B5E24B260052A25E09C477D1F4A4710EF521C44F5765EF8DAEE3B7BA4E286D764 +59802F38D8E97D9A557963FCF5CE32A7DD5BF847703BC9314102928DA945BC4301440841 +94AB6BEB1EAF29A147BD1155D2A5E68517E4C347098D4D49AA10A359132C633B02E3AB33 +4BA68714EB41277EE78BDB1418DFC5A584F6541F3EC0EFC75E66263F61CF2DDDC5DE5648 +B14B8A275CAE0728A9B60FD75210FFB3EE02535815F68572A9C29DE316C7A6C991DA22B8 +08CD58C392DAA11A2390AD45CB6161063043C464DFEC11E8B068A0CF516E38BF736AA9FA +A03AE4EBC45C03A4064A4CF07B171499954D8F93A7598F3D51E953F91C7A70F35C88A384 +97839CB7F9CFCF788932B261AB359F8834660BB0CB5C69A4178BC3A6A98D6DB0C7C346F5 +E44ECE30B1C3E5EB4D203CED8B5DFB17F8211D672013A41F5760D90D593B7079D6F231D3 +03E9C3BFFFDF1E98B8F156BF47EF60F082FB02AB362582361B5274444E6C615A8ADAFA43 +71CBD86CAB86AA91D096EA244AF3C69C4A2F9D62A0F5BDB7649DEF309347F364469383E1 +4B72A52AB0B0DC030D8E785C81724959CD02E1BBDF43E6B92DCC1AB433576ED1F7B7157A +483C99F4662ECEE5116AFC2B28263AEAE6FC04C656B02E15D619275C7D79894320559E18 +B75EDEBFA7230375F5EB1A66DC3AFF798C6B67D05D8B49F28AEBB509364AFFA36EF12063 +8D958796CDB5409D5D3D8270B4E602A530EA46300695868F972A1E3764FD44BABAB416DB +AD0E3799FE67EA3A134F9841C79F89AF7FCF182A484627FC0A70A8528346E3C27F655232 +10ED76FDD4626CE3EC9F34F506F9A7F68C50B9434024B7C40A3D1ACE1E616694E442625B +FB49252EB156B12AACB84BB3985FBB8431A9BC0D1F071F7947ABC095FEB24EBDC9381FD4 +ED98028BE53D441AFA5534C9D27A3D21CCC2EA3B6A652E08CAD80B56751ECB06F18CC9B7 +CEC29919314FB5283AFE5A1951D3669B446F094550DAAD91C36CE3E5D30238C65D2E1D67 +5648C147047FDCF267AACDBBA50B1F9C7959C5F12DBB94B64FD02741211F297176F5F849 +412EDC12029643AE2AF2CAE8552C69A90BA2AB2DED3FC3D5D5E8987CB9B538FF90B693D4 +B842EF7D8AF1055F53FF8442AB5854E94BD016AD3F29CCE91F6D222C7E0D3EF3DE72AD41 +C2E179FC20B4E0E694E50082E944C77CA4D878BA6F19410FF616569C59E94AEC542AB9CE +BDBC0C9726DB1D56FE5B66463699266E4802B8572C7D2E45DAF827DC6FF7543A45A8B7FB +908AFA10A67EDA2CC08F677503D0D30D74BA3379234897DBAA955011163C4E0138858535 +1FFDBEB8804F00B6799ACE948E698EBBA5C391BA1D2FC74F20C448FC0BB8766BB3858B46 +2E06F751F2762A5B8DBC4D2B7B96FCB3EACB4757528964DC348C274F757178EB41BBDDE2 +E075E7F340C899F2253DA8D35B2C544792077D7CD7678698C2D8A3E36D440640FF920E74 +7036EE2E46227F170C5F311BA5D89C0EEEAE6BD2CD006C5D18BEEFD521894E5DD7E865A1 +B894E8D3E24AFC5A89D18773A7028DACEC61BDF9CFEA5FD37826AC0A7B51C7CFE3813A36 +8D62036C6B5CE16E56601864092F2997816C600AAF2DF34CB4832981CA5737A5EEE14F2C +08302588D473353CC126C39CB3F6829CF84358384005A577A7F8E9BEBBE001DCD4BE0538 +6490A8E7BBAB5DBB98B5548E478614B9CB730CFAA373114384BA850D00FC9B4DCFCB6B8C +A57D4288E62BDF5D36BBC888C6CF5F501BA8B6D8C5D69D5699D80AD979974F42420D114D +9BD3F2ED149514EF44BBB2746A00E3C633FFA966AD76B0AED0568E44B94C1F820869D86E +91A78A7C5DB8F454D313637FCD271D92FC20C9F578B21A969EC9B1C015D8FA455AB419B2 +B743CF348AE9BBF466F8FBD617E29374DD71A846A75441CC79C4B1030266EC8E46801E38 +CB9FAC30D2804203AE5CA81D0FAD237EC8D8EA6C544F8BA10B91C2D3A402E940D3092E16 +9D44A95F8292E2DA06C709302F69729A5C5042A009D319FC7049C50DA4653337A6BE5A22 +B325F1C64CAF8682D3D4904654D636DDA229F6F41FE01DFE8CCA48B171FAF8C099A92C28 +D3691CE8EAC30941176151B67198121ACCF7A6EF4FAB0843C385003036DA94117B66FFAA +0A6A8C007404A9C0781D60652E48D530A656B7E005C5053A8CB7483D1EECC4A85D907859 +982A74B1731BE0B8F4B1E91E4481A68057F9AEFD9438343C1229B0E676842A85641CF32E +364CE9EDBB8D4603CAF04A5B2111760E1E77370474393F89179413D5B9184938BB00DC79 +FA7602A1A591EAD89E9D7DE655378E10E301B4005D6B5BF682DF253B0D8A34004DE431B7 +C82C1741D9952B20F7312F6B44806226115791D0E38C6A5E855B2197DE0317858F25C62F +2177D7E6237CD2CCB630FBB13107B25EC2A75EEA8AFE6AE0642AF1F23D171E99AEECB731 +5034D2410795B40495BE25FC6EE051D78792D65BEF57BE88C0DD7A7C6221D0B7ABD88762 +9AB940664A7F4B6261069B5DBC95BDBFB9DEFC25D4DD38B184CEDFB2653553894B7EB379 +4CE19DAD9160266B97A32BFF96C0A1B7B6EC126F34DD8B242AE0FCCFB7DA22EA249A14C3 +E6208F2FF090AB21CE1EBA11D66D654B30CD73CA6B2258F67706792E63E52B1F9829313A +C0D6FDB303995546B77974C0B07F906944B68B50CBDD7DDA5DBEC4740FC6333D1E62984F +A9C13C623620B27680BCDEBEE51E3B5841643383374E04BC65E4CBFA38C91ABA62D7AF44 +C721491F6C78A9088DDE50BBFA9CDDA44E567D776559D3E11030CAEE6E5E7D07289CB58C +852AB6E55F52A6F5730A099C982DD11296E4E33CCF20BF6EBF16C1EF76785F13A1AF9EF1 +A52FF02C06A959B6839550F4FC30D277AD524E215E05B63A9C7B74E2FCACAEF3DE606002 +349C3FD26BA26FFDD6737BEC9C5DAB55F0A63AECC534DBDC2174490980A9AE98B00F6BE5 +2334C6090BDD9AA329F6A66F551B3E41A0DE3EC021C7916F521DB7CF1D5A6B7B9D72851D +285358554917F453CC15A1D73FD528AD12230892C6774001C56840F60EC5439F6F54F741 +96E6D3D74010F14A30DF85B16D23A7194634CDD9E4D2D74FA1ECB3DB09DE7D7FA438468E +D1AAA438A463FC988C4460B1C55FAAB585AA17837CE6597B162601010A04725655079C2B +627139B1A2AD607FC365CA845CE554AC4881BF87DA677B2B240AF10286A947D624EFC074 +1D7EDBF557FC7BF5409AFEEF4535C7A02D9F195B1A20D54C25BB918EC1DE3492D8301448 +81CC8EBA460A299805212312643D95AC08F93ADE8DA467C4286ABC575D17265D7B268809 +C055D44FBBC1672E34B73EC73F114FACCEF8817B3EACC68C88D07249769D0AFA2B797863 +B6ADDE44995C903A35A619EEDDB8F1D76E736C26EC4E8BBEB51B05DBDFD840C0DB53C766 +625664B8506BB1A66DE8A04041ED2F68663BD15E3B932234F37CFF8128E4B2AC1C191297 +D4202B56DE39AEC4006ABE003B7594062C26F206C124E1AD656B8598F190A335A0351034 +388C225B0B542D11E3CC96C0B72789349BBCD9C445C19265D32440F6248F2315A9024BBA +0CB6B71BD71DA2B06B57FB0483262A653161E6ACFB5E916C22B6DAE5847740A36A40A505 +668EFD5FB438F9F1779C02A19D2C14D6F1DB6B120C060D2ED8BDEE9733497FC9134A82E7 +42970EDA3F136E0740CCAA97EF05658BC1BC0F5855303168E2BCBBA37305459215393674 +3D51B4670061818712549FB6CC007C1F13B8C74A8AEB05B30D37E6587148A94CB7C1F27F +1B4B37D298DA91CAA996A180DB262FEE001AE974B819D288A619A8ECC8E442D4A2EE0D93 +B89A0FFB9A03EA573BB8D40676E9C67EAADAC5C0A807D7422AB90881515D4DE087893B8D +A0329DDA3C42689CAE4F29C791EF79B2965F6DBA3C25AB0CE23ACFCCBFAF41ED546B4A05 +0203147147ED047719FAE976A2B71A81A0EDC3DF0A3E03B4CB8208BD7AA6CD91151B1A31 +5AC3C27534D9D73F285CBC0F3D7E0C2CCE2DA1502BD04AE6789ABF17DC7CC9214C67F2E8 +5DE2A1A71AE65A91D7F139756A1A9F912D759CA02A433F0C44E12E8739C4C2BF217B8FF9 +55FB47DCC70B1790B3E906B9AEC41467E5E0E9CA0317BFD62F2A493EA5DF4103A385B56B +45290A56E816C06EBAEC8D38509777CEBB11CE12509834FB28FA7A19FAADE81BDBF0E427 +46EAD35477D51E467EFAFAC373E3E72012AC7AD85901AB832B8197A5EF7ACC5A9D6362DF +89CB52589A3CE810CBA525DC46E2C00680EB66CB4E20CC4872B5F6F9BE3636117140C3CA +545CC3926EE9005FFF15AB7848A95ACAB42E3B565AE93DC7A1CB80B2854EEE6F14422013 +D50C7BDD75E97822BA7C7D65FD383BDD5BE7DC9942888CB7C39CF56F17ECB0676B73D3A0 +2A37319899D89426DA1B299009379DB2C217DC43FC08F4A43E13BF8522A2275EBA64628A +78B877E2EFF40FBF2B5C628981B0E66643757F5F8412A5B48AF6CE0D230D57100D2F3446 +CA7C8EBF6F3EACC15C3115BA9BD61CF3D6309C18BECDE16EB18F6D008C5C5CA0FA426B52 +5CC0F33A5743D4FAC4830C4B7ADD35ED3BD7F7B072847D2D430DDF667A6FBE49A371BF0E +BBAD32173AB5928B86FE1F4E74116041E0F6E4F1041BFE588A17C7ECFF96EBCC224EF0E0 +8E3D8566BC221C1991BEE248920A4BF4E424FFD1BD34D1CA66F53DBD6A1AA33B33CE4EC3 +ECE8DF81BC73A54DC350A3939F07521808FD40C566B03124BC7300D28035F2162B76F6B7 +F7A26EFE392EBC35BD718DD1697BC9FA8214A1E137E28308F7C37854FCFC6BD031A851F5 +E54751C2C409A314A0AF104BC8D561A5A8E7C6B0BF4F1EDF9B42F577A9B9AA91D690DA70 +6BFD54903E6A1591588A845EAF9B49A8C5BF35B06AE495F4A8CA94D64163B2BC03482DA0 +BBA8B30CC65711C8B45AB4EBAF027958D578B94DCA70863767A0627B0751AD63EB628BED +CBD2C89DFC2A3BAAE500389F9D25F1EE6FAF3BD85B018296528A0B6049688B2CF7BB1941 +386D49D254EAA716D29051B9A5295E937F700C7D46872B6D593869A88576DAC22A2F8B3A +5076656122DD5178AA5FF49A84BBBE20DEE581FAAE017BDA5B7D4886BD8E90755D766EA4 +B2E825F73B8DCAFC4AA1A8263A179EC15E6E7EA656B1BBA6E19756324876082C9CBF9094 +CD62531D1BC54FFD2F9F9DEB6282DE12B66D570EE73905B0287CF19E628533EA058D5FCE +AB66B6DFADC6AF54995ACB056B8BF3AF89EB021073FA98A4B6803DF89CEAEA3874B09625 +67D46C4D830F0CCA68C7F24B20B94FF73A0D270D2247193214DE5E85775E15F5ABF0C88F +59931730842A814185AE10BCC62DC83846FE3031B140D6E0E05F4E5B6053F71781B10D05 +81904D48290FB4A157670B791271F7B1B32BDA4A71776B196767EA25D5A935CBE1626C6E +5B3D8E64F74F03DFC72FB5C63BF586540071EE17C883AE11F2D154EE9AC0B2F7F71D4D08 +CC170A9D5206AF1585BCC8AABC2C2C714DF83AD1FB773CBECCCC388E0D3769CDF84DE17A +83618678EF40D4171BAF7236BB081887A042DB575528027CDAC918086C6D8FF005639565 +F6676782F78AAA4EAD4ED8162A35E447C2D60A07E6222415B516C8FE60B9C0FD24E78996 +C1316D99AC6BF81AE6A7E53BDB0DF9AD231123474DC9A0105CBB4D98EC4ABB4F9BB4D3DF +9BEFC99537B06378E91C875FCE12910CA65C33C47F1D8A864D17D5C5B288D5BF6393C576 +ECB62660756C8746C2125A8434A5DEEF7480CBC48C21595A28BC9931AD897C754A87CC3F +608999E7FE39CE1F60C099357246117C8A074BC1E405EA7FAD3277CA45F5053C2EE050C4 +B93A1F85B90084A12D625DABAF2291ED36699134DB6BBF4AEAD7CFE27379AA6AA93B31A9 +AAAD3F8F998BA94D3CED13C1730326F08928C6A648CD010845C7CAB2B935ED2450239B20 +63D25104A1E9F4DC48BD8BDA6FEC274BE5807DD2355F6CDD587263837ABF3C8CF8466D3D +9C38D0302F1CE94C967BEF58E6B867C9FE138A7DAA9E7C791865A3E8BA65A254C7032E38 +FFAEAAAD4EE632983D975F167172AFD8FF70A1CF6C90C24B9C1C3E1CF51046BCA8C2F0C3 +D56B931C70848521756E221AECB2F0015B3476FB304B28C4B7966A3F693AC9E1C5D69C55 +8DE014A05981CC5E1AE6083A91594F0BF812B1348B5401E4170AC65CA29A7182073F0E18 +8BDFDA17EF3933750DE211D30CED8B11A1107DE4F12336FEEF5AFB522B2060BB745526FB +D06E42C1D4C7F529706078FF598EE48C9521793F53F770636FF6CE984FBBDA645DB8E631 +E041B10E43E836B1F8C58C4F2D4A7BDD4165FCD7B19243AC560E80A6FE7A3EB4FFDA465D +9ADF12EF99FD68D90139A58A53583CD9A0A574B8E0A604E84FCBDCCF67B8A2DE8D411996 +12EB00DBBB8448B80098B458B143C6D1CCEFA354EDD81B01BD6EE4A0ACF2AC0338BFE143 +06DF27EC691542D79715D36E06DE6D7C2D3C9C0A7DF0094CFF0B50FB21D67138DCB7D447 +B45EAC890C4C6E08852F9C00D6DFB9C60A24061A3014844C84BCCDB993E0B8206E5DCD85 +A97D0F1AA82F5AAC40B5D490BC1C60F05B33BFE6F6C07138A4BD1ED177C2FFD13278F53B +1B20218F1685385A604934223F259646450DEFF801D97C1D38E8621C612A4E49B9CC2279 +7DC683D7AFAFE54FFED9563E880B86C25982D6733EA3B8558461207C91F024640FEB1D2D +5A7F80D16FC694DDC1A59B7E30D1924ABA53497F37345B31D2429F6804AC66E9FCCCF4EB +9EE2BF2836E5B55F29D445762ADBF6BAA501E198FC7FDFA66F3474B116E9A77319AFB981 +7C2F4BE21CDCA0FCB65F07DCDB906AE92CC40B4A8E967D91A00E9110BC5E3289AEC2643C +02F77C6313DB7BCA506CB8BB3F3A434904BBBB46D7C724766DB3BB73422B659F7D5AD5FE +6DAD7B204230C92AEB30AE4E510478F620BE0E4D6AB477971A22A5C6AA66835513B1E2A2 +278BE747880EA3E1EFAD48ED0B7B5C320B833587A22D5C944F5ACA917C4C49FCA58CCF19 +BD800F5DD3246DFB9A772AEE6DB700127D07167F2D69CABC855BA8850571850D913A0606 +3DAB1EDBB6AEA9724368DABE65C57341467A58E819ACD98BCCCCC971E30F0488694579C6 +C4991EDEFF6DDD79693EA8BAD8AC9495D8884E5B09D163C7A0D343C031CB29F879CC5064 +B65AD297089E7AEC41026B5E055DC47A7C529ED28F3D27A191239D4E3EA911C84084B411 +13D7029A39E6C6A2E931727711F1F06B807841406515B7711A6B96E6AEF79E271C6E7D42 +7146AC3915D35E9C2D4C9E7C5689F7B0371BAADD037840BD034F4C411AB29B36D4314729 +E97666CCED8F1A5AFF6FA352AF6AD9D9343DA8E3F97A8C756B48675750D128A3862C19D9 +086B597EE751BB0D87A3B7A56866CB6AFD2CF8B1B322C9B2493D40BD5B89C4AD69F347D7 +26C22E0E39ECE377C995A611B54C0B2EE3B6CB16673F50779C212AF1AFB93DFB2C931A09 +39A1379C379E3F7327A687B5C4D8D909D3CCC5C3195935D8A09D5E5BFF12E61EFF4FC6E5 +F99A1460C5D1FBA82C84136BCD64D96AD968D6EC728DF4A85573E021734AC6C2100B6F67 +F4E648F5E284618A1868E773D9CC819AE8BB433FD388E971F211301B3ED077CC37FA4B58 +0B50F8BD2309D8E81936C050E3F0C8C7D81A80DA508533BF5FCAA977C17A572DD92CF1A6 +B7172AB4C66890E9F4FEC661AD629FA0FD23E9427C481408A637F9E649DDDC31668366C3 +692B524D9B4DA99938076EAB2343FEEA1560550B8E8CD18D3CB23BDB1AF30F60EFF18936 +46B26A09E5411F6C456917CFC6BF3F74B2079D0AA56935E672464F6444F2E17DB330F94D +FA7CFF92DB6C800B2311AB86A21658D431EA7C811E020538CA2335B9DFF550C077E83B29 +544FC63F5407B1C9CBC3E6E6259742EC85BAA006D2715D686619A94AC7EAE394915CA656 +B8DE89A462A85CA179C276B4F90C399167DF0D928518DA2A45B3125CD16AEFD65C85801F +BDA3D139B3B349AA86037B579B8FA94C713DBF1DB2A904652E89AA8281DD58D4CFE3434D +6C86F0BF7921486C9AE78F322DD841CB43AD7EEAFB5735DBF68D03DFD6640DEFBE22B305 +B33DE7C444D16D31C3EFBDC78547D77962EA985B734970BD6C4B729C7364348B1CC321A9 +46D096A078A45797F63B1734E968CA55B8E905160740F68676AD286C9F44E1A94D17F911 +0EF21F8EFCE27A76D1D7869FD19C5A9AC889675172335D312E8E1DF59ED55F8FC13D0E6D +9601039BAB9AEF7A4F3BA688E288A089B326E0B582384B9BD80A0BAFA1130E2034F95D21 +49DEA8E5F576EFE035C5E58CE82CCC0B3A95980097B2D4A80BE162C8E3760C3532697651 +2626F6C64864810E304D98D77F13BD535DD5BFCDAEFFFCEDC1CED370DB2EEF6D90E1F0F8 +D4C3FAEE71AD31B0F4798ACD68E1A5FD00A327846DE3AD55B0F493E534AE6E30D2DA7EDF +3F68459CA7192321B98C8DB02D3399F72A0216F822FB8D0B5B650B38586BF22197F78D31 +55B67843202DDEFF5B04D4230DB2FC50443C21C8C28E7AE0E399767E03BEE4590C4D47F9 +27210114B296F1E8263213544DA56D46BB179ADBA6DC415D6A46679A4A7494AE4B2F0812 +9C5D06F92D2D500F336304FE3454F07A2083D6B6BD5D5AB3D6F917F555C7F7124AAC6F38 +4262A051D865369A95DD8EB9DFE43DCBCE770D3C8BB6630AC2F8DAFCE58C5C4060BAC1B2 +EEBAE9E56AED8725DEBA7CE23DF18E1A52A5B87F39EF416565DA17A5BB6566A8129CFD77 +D3DA3E3583E6F59EAA14F7788C06D3492FC84F7C6BDA74C9FA885EBB7125E87760A1E848 +E9CAA638A813D6EBE8EA2A3E9ABA7DC8C392A066331D9EACDE6C6819AE12A85B096CBFE5 +29BA283C2CB73FC34472C5289914EF347AC8119139A3E6F0CFFB5772D5AB65B276C171EE +D565CF9B1E629AF962BBB00CD86FED8DCA3DA0BDE9ACB286C516114BDC1AE1AC41DD8453 +795253786205499EF2E971F3DFC51C72AC5225EF4E0D9DEA403F24002591D9F55276CC38 +0DCCFBEB33F7733A1DACEBF1AF33D55029C44364284F6CDC12ED12BBE809666607771634 +90828A6F10683FAC8C3C4DDF38A0CFD1D1FEDAFB7100FD9C02AC8796C7B3B2793D11C107 +DF10D22D9C294A3AD3897431EE593AB265D97450A6B2DC4917ADBF04B04F32F5802EE354 +4D3A95CDDE623A423213D0063B79F8F40EECC82F3C5985CD12B0A46F5AB9DD5175A9F3DA +06E40950ECD37DE39B5EA6205D9427EF43D5B0D090A62B669E437D0C31B6A03850EA8BCE +5D2D48C25EDA80913821DEE94881348DF1726A7D61ACD9520267B5C668F46B1660E87E27 +658B7D3C2F1C06ED70D97AB144D22A4CFF4A54D73F703A5AAFCB5AE2C7C5B33CAE3F0BD3 +29600C9BF8BAA060ACD3C4D5A72851A2A18AF29212B1E070EEFC452048CF312134436B5C +E91FBD2E526CF0A35F42C1D8092DA30270EFF9577ED231B303B472670B458C6B53B1C766 +09159D861584F0901E7C8DED964E9ADB0B424092B4B50C490BC8DF607EB9345C7AA94CEA +F430F8DD439472CBEBE11C26F9D7C7C5F8F04F6D3D97043E282CC848A1BFC73C095841C0 +ED64E7449BF4CD53A64F0B932C45B0770D6D18CCA6147E9F992A93275AC93D1B3B0F02B1 +9F117034AEA1F3F0F77D482A3DD8D5B2F69122E5B08C067D39A1C25D042D1EF4F47377AB +CE1C38418BD39E7400F10247FA13291E34BA3CE681CDBD28F3F14EEC90A21C76806DA1CB +25AB9B96031D1A472C1146004C4DF21E61E07087A8DB5C33DCEA85EBDE4587FB2FBCDC2C +5C6B92E61C72B067EB5F07233162AFD24FE6A2A9D0BD11F401610D5C5F91E46D36B2401D +A81BA2716D4AEDA19136E58A14F5A367942B70DED7DB1E0703609FB97F8C72C062934495 +DE54A6C45EE6C8B5F368F2817ACD4A10F14A846C1FF578084779649C4BD01D9CBA1E88E0 +1DB953307EE9BF10E6C17B020FCEEF709840DF73B4CE45D4C2583CF4B357C33DE67C8CFE +8FFE367E89759117EF10E08899F466D342E75083CAD4795950C026505BA8CDE648FEC333 +BC5842ABEDC3CFCD3B27E707D6EAC3D54FE7B9C964E28AE0FFC96A06802C5A8327FC2CBD +DBA565FE970FFE18008C9DAD42EA99FF7BCD0656362AFF37432A182C59988B0BF458C370 +725CF7D7F864747CDEFA9688FF6D2CDCB49052F349F9BAC9F8261B5FF65BCD2E531BA32F +7FD7D3F0E3042811B345E8676907FE71D4FA94437A3A42872285F010D909D468462942BA +696325E79D943D0E44992A20EA118ACF9CA5F1B20E52719854476111D6479B3842A9CEF7 +749437F57055B19C5FD6993F5737E8555B19161FEF7F3560C6FC498EE8148B6327EC40EF +7CABBF6B7A99D14A789F6F5431BA4714CDA494E29542EDDBB4A250ACAFB9802B6A3D8FE2 +1CAB7FA79D9682C1B1752DD2E671ED5E4574BFF967156A503753B65075653471F29E06BF +7342AB3284E9EAC6F14232F32C3B0266416738EB5A138DC33DB2FA3A74E649532B4BA7A9 +AD51E0278FE837ED68A9A5E40AA236314885AEC0DE2BB1811BCC18F0A75CBEF875D886AD +55A873B8D3FC81BA69DA0C68778CFC5F02C17A851EBACDCFC9A0682D514144CF47382163 +6B1A61CCD572575E6A81671DDAF8C442E4268041F8E03398A9EE0F63B352839BFC4D4720 +0F86CB77549091DAE5FEE2CEFB21F4B987496FB8F993E3CC18EA9CF06442403830E06738 +20BBF3E4690163AECDCF693BEACC77B5591FCE1D2DC11621BE67F9C439F7864BCF981F3B +8A9CC1F21424AB86102448FE45A42993737F7C09275C627CD601906B75CC9370AD491B59 +2777DD8683ACC7CC961D6CABAB46A2AA65D8FDA3E66DC5C75ECECD209FFBBB76263E036B +8F62EAD1B802D3662A23A28079CB47ABA48799F3DB0D7E46710675B2C434513E997D189E +0A9661186D9D623D5B47BB377E4B0CE197D80E9AEE04E55059C6292C52E00D0AD892FE67 +600AFA285DC92263DC1F15EEBCA803647789D4D420FFB53C0CE4A669B4B963D5F2FA6FFC +3B28AABD6D97AA2F92EA3FF8EDE7AB264CEB19062030F43D8438DA703B68D2615928E4F7 +9687B03BAD9F3447ADD3090BBE186FFD3E42CBA236104DD1D9A8E9357CAD999E889D313B +262A4232C5926869139EF1165172932601BA4CB406177E25E6150605DB931A70870F5BA5 +1DAB4D15D500B261F9D708174568422C714F30B696095757C66F7D2E6A5CFD146D90F21F +27F62393B532583B49558C8C6124F2F428794133E093D4FE09805FB2F18BED35D12CA321 +B79B0369E46FE3191F47B07D234866AD7EA52C50F4C0562597AD1F7D186060BE2339C324 +F154C2EDF64C7A40E8419E7542B8CA143E172E3C62471AC1F42342051B3FEA08368A31D2 +56A7D51FAE801A420FA30E5D479283A21B50AF52C6BB4196433D933FAEBE36EC577C59A9 +BF52F260443A622B637FD4F6BFD330F8DAE7E4374E16B8E98BE92E3404CA22763671CE0D +276981334084462B06763958C81E7D85C76223546F3ADA094E5597AC68967D96CD9E76B5 +0518144684C71739C488751FFFD3B9859E23DFAEBC15A0AAD8417416CD5B47656E8BA799 +BB2ADFA07B90E634895108D5F97BAB5B560F0608C1239F49967B34941B908AA695840FE8 +4519FA60763EF706ABAF2E0C7D407E5DF05807FCDACB17685226D6B5070522D4A6AAC8B8 +77891A1390386A074745E5F4875F625E9BBED05B54D04EB6A6D8352E7E4E47FB7EF432C0 +808D0C139EF7EF5220838D1CFA3A839B10B772D8F2A197E8FCD7EDFAB65B7234A7E1C0CE +D75C3120A58706A26004C2218744B095AF45009AD3036AEE08068311B20974C4A95C8CCD +4EC20B2B8B8EC4F2D6F9281968EB51ED0E377E3BEA2481810C3B0B289AE6A3EF50339AC3 +B7F06050B7705C260D942DFE3B104C13728A2140F9E137AE5E476FA67245FC92F1DFD28A +81CDE2EDB4978F971F668664658A674999A62287F74C8BCDF0C306C20FCE35EB1BB7318F +9D7BC39F215535A9796A7AE7D117A273DD5F1B0F5FC5F87863A817993C96CC2CC0FE3504 +44698065A0654D045BE4FAA60A218D260FB013868B18AD6DF01B793D298F0CE041671E71 +81893BB81310462FD1906C5F8137FF46937B206588D2715297D008E6AFB90DB28E3D64DE +73EFC4A6DDE7466A3D1BB402FC04AA80DF2BC39AFD30207230828FABCECFBED8E11598AD +CA43FE742EA8D1BA8CEBE4449495398E5DE432B8218E02A5340C854455069082EC8AA449 +63A13C0069F468BFC1D3D75D4458383E04268297EFAED1D02B91AE933DECE8DC3337DC99 +D7AD1DC4B999A3AD5E8953C7820BBE425470B21BB61ED6007F236467503327FF73979677 +918B34DBEBC181DB99526586BB6E9889DD810A0CA022C62FCA58F2D4D738A74BA24E2FA8 +29B80401DCB36889A4CA08B77377DEB0C4172DAE920E318DCE78DA14ABDB77EECFA5A1A2 +6FF51D6569AF1218C4256D4B4D206ABBFB1D2C7AC2102815EABF306CDE0615FBA775B5E3 +446A2095C406CC1BFC1BF4A53E65FFF0ED565B45AD332505AFE0F91C8569897834C06194 +6C745ED6618A60065F6E3B3B49A61BF3265F3BB1FCF8A25F4880DC771ABCE6BD03B48C77 +83BDC1CE678E423ADEFE9AB04D40097D8DB062DA0A248D1C81AC57FBCE032B232C6FD553 +8AC5AE7983412BC80D23EB71E4DC3B946FBFC4B98C4250BF8D57CC55D929B55C354A3F9D +1C5329F36B06CC099C2201E7FA501F75CC7D5579FFAF9F9C63C6DFEDE80B5387117EDB49 +9D3F1C72D650FC120FDFC8E42479469DBCD81AB244C316963CD6EA1C34DA43400C5A2B7F +E9F0B71EC4EA67255AAF6A2F49982441962CA30DCCDE6F7894520FD2B811619713D91DED +5D1FBCBB42B1368E7F8F4B8438C515B4661879D353096F880AE278905424DBE523DB7B41 +A5867878E478B85960607BD1C129E85249CA520BDAA479CFFCDA162E46DDE5EF6BED9684 +31F3289735FA2891C13C0C341159905F43BFA6412B6ACF04C2A11B87AD4B41A35385AB66 +68CF890B1E9A43598F03AE5A833A932E5C5A70E498C405CC56BD0BF1074EF1431980F575 +67D7C62291703308B41C4B94A99DB6F6F1F924E791025D5E2F56F3A0B60903FC0CC0B2DA +8CC5785C6FB239ABB091B7718A9BA16D5A33083289E8347CB56172FF037F6FE1A9F7EF4D +5D68E23A9A3B9F63C2045AE2B1758489AFBABE23DC1FB610B37DC573D2C0AAF544ACC904 +B69C7775244B1ADB77B51727FC66D02637CF2E9C596A05AB6BEB23295A093AA90DC3C3E8 +F17CEBB44AD7A8BFA8898D6BDA4F84DCA2A30FB5F0D151D8F6666690BC71002F31AF05EF +E033513CE82E8639B45CD235F24CDB7C7C3576149CE989FECDE2F51FC835CA9A023D889B +F6DAA3DB5A8AC49DEFF48266333B5B01130F954242A7D5A369CFE937D3AF1C4F2C64051E +59FC2AAA3871EA827C5B74C70C259FD4DC5DE81E2970519C433F1331D1D08F5DB9BBC9EE +80D1B7972C7F1514F7116E25DF3E382785504969CC0AB8DEF43F5F45676B2090DE9A775C +04B5A4613D38FA586F05753CC38A684BF33D2991F909CFE097F97696CA2C59CC20A6D89F +4710B1EF765EDC4D5A0B7BDD33D8E818D97C9A19848903D1684436488AA7E204F577BA24 +F1D1E0D39ACE2DCB56550281BB24BB686F605B7146660EBB47F8E329EA27F94319D795A3 +71D2D04F6B3DBC4A61D4A7A6B748A60B5D8F3586FF31AC143FB706770E4DAC9A6741EE88 +79870FD251625EE5E77853F6C5D2F621C26757FE64857FE4D0502F84C14825D9BEDAD55A +35C640D9999543CFA0467165E5AA8E50699A1C13589A862BD656A22A50EB6F479D5C79F4 +585212673DC2BA0DA86109FFA40F5FFA1F660F8C055D2E9B9668B2966DCDACF5F189D835 +C029F51B85111D9D48F507AE75A7BA53CA97B39A5287CA4709DBEB723E6D68BFCA745FCF +7DEA768DB0FE6140198D62E880E49E2997AB132521C94D259CFFAC9036B0F2C2E15E22AA +6151E9D4737FD36B9676450E6F7C9E7531FD2F4F307D6D548F37A3DCE2CA5A811EC19778 +12B37C5722AFE78E1425C2C1C06461C1508818C9536FC9117951719B8D431551B4793C81 +CA6938CB75BF746C247A9F48354B0A4BDFB2D6DF3E305218173503195BBBBDDA322153A8 +2085F0FB5ED657637791A4A7E1C1B23CE0F8AFA1ECAE76A3FBB3E6B7A2BDA2E2252B2E43 +4413F7B626AB00CB381737A2BC0837E33C3E25C63852B841E70722F7ECF6238890D63CCD +2C93F7A2CEF10AA710AFD333322F4907E87A12DEF07F5C7BE344E73CF12CB388BB6F049C +D9713EBD215989CEEA7473C00E40F79CC0038762139D9FE2B2BBB290C51A3B4B9090D039 +C22B1A620DC1C3128C0EAFF4C62A29AF0338C65B6730BDB7D5A6A7261C04816B7D11463A +935AA0D33802EC148CB8E7DF6B8FD0FB064BDEABD0DFC3AD5A80CDAE645B7FBBC59359EB +A0D70699CCB53887530C3AC4E796DDA9AA05F36CC0A6D0C2F616E761CDB1ECEC164974B5 +0C0D38697DF56BD7F7F1772771054F18E3F5EDEBCE00939E70A43766D0E99EADFEE152A2 +FEACA0BD0BDFEAD28E3437753ED58E345FC0D6F4E395667411D4246C460DA5D3BF2F5374 +EAEAE1DF1A76A592C4957BB9C4D406257388DE96591969B30D10DED2C5B647B66CC0BCF6 +146FEF353A20A3A2E40C1A7B7964033816D6A544399965E9C17FC44C524268B0228E209D +2276C1071535597E57EC3D9C4D8328CA914F54536B1F63C89325D6B26DAB4A5B1FB8260C +241331D1B55C91406537C5323ADD2E3CDDDC9E199CE067262690BFDCB5184E25795251EE +181E745001ADEAEE0A9442D57002D48D6B53E693C37E0BC64ADA28301235E9799D9D0AAA +B4A23F6D8B4EAA5AD3B6B40618330441F6A24E44B160715740198B551C2883CB17FAFFD0 +3B4CE68ACBE3F6B33E29987B5258C1F7DFB87DB89735F05AE7966FF1F2B6546AF2A56918 +3687B6DC7B1AD435DA0209B0AE7CA01A3A3359291B1435C0BF04BDBE2B8778E4EBEE35D3 +17EB5CC7A3F7C5B7743AE69B16A6B9C89491D121617C20CBFA52E93274E6BBC8C0E9924A +002CBDD7922F3437560E3747B93775FA549457CDCB2A9943AD403BF8AF05EB1CA0EE347E +E832C6A17A3A53EDD50EF553A0E8D6723D3DAACEB6F81CBDB5B78A5B207A98183C3650BE +A88F82AF734CE32FFB1118E54FBCBFA2C2705D65FD4A1B3A3734F188078A7B09738C3EE3 +A12FCE8B7221C3041224D324AD3C514EEE792E3D47B1E8DA34AC3E577163E7AAD2C85170 +7D630EDFF8403AA2720B09218E0013FACA789243FD76719860373949951B1907097E01F7 +2840CC3089FBF9A86B01E6E5A882444A3D167A302AEFFD3AA9463A68C7922104E365FEDB +9BE61D5EC0A3AC5722F2BCC5101BABC86333955964509096B6799F286BEE15441C3DCD84 +A846B35D0B027C48DDCBE123DD9D2DD6A4808F0B3F98BD4BE29E1001905D8606390EEB35 +396A3A981529655D67FF0539BD3E1FF2FABBA0D4393CA781FDE2864DA5D2A0FA6F78063C +03CA44F27436C3421683D242EF3952B8707863F6DE2E3C94ACFA9FC60EAF7C8D09BE2D27 +BAEAD24C01748E1EC790EF22AF24F1F7BF0AA1FACDFB5C8E0A9B3A1E9E53047E4E791D7B +9DBC38B9EE8EB0E5CAF79C84E81897A4B202C6A3F22438D9B043D982F605E5C73CB01CE9 +56E9DA66D7BB53F38BC43DD2962D6589AA47BA3E0AD6BB8E0557127CF8F6F83AAAA3597A +8B57BBCDEEB2223AA2EB36BC84C7BF53F3B7D9C221FE76629512D04EC454D92060750F55 +0E76BCBBFBF9566266A8D033931774C37CDBE5FA71FB43137E5592DD67945201E1D10467 +A3BC5C273DE16E64035C39E4A36D7AA7F4E8389A1FDBF891B00613396194EFDC5B77A9D0 +9AF9C1A4EAE52C87A096FDFF8699EB01E9EFD3F786A7D45AAF8D9D33B934CDFD85C495F2 +09009C628EE54F19A9F02CE631DDC692C3C56D2FF00B8F277A18D1F38A63C394C717A0A9 +0B01AD75390D853D63D0E0678C35022369BC8C985C8229C98CE6BFE1C40770461A5E26C7 +7A7AAB035D6AAA9B0394021020797E627E2E7D17B39FD2E7AC6FEB917A148FB996911869 +49A036A0E5B85D8BCC59570E4C689F2E802262ED26A13C18A57F99A74DA94491C5727246 +D3FA45A7964F212454E119A32738582CD4F5899ED604F76F0327CC1E5746A86CDADA7F97 +E11EBB6524AF8107F3A8F0B8E5F887B799DCF9F9481859EC4E5FF63AF0C294C2AF716EB1 +3EC7DCFB796E3CE4B4CDA1DD15186CDE479CE4EECD1FB27F5A05B69FBDF436EF246E8BD1 +A03FCEA5FB213D81F80D6ED7960896101E046D1101A7522F31AD1BF6C08C5ED8F6574F48 +2B6FFEBF34A2A157567F1B82BCE3A46C14A168B0F4658055BBBA2E9C29A4DF42764F95CE +0EE9645C6E0BFF33CBBF3436F7A4FAB4B2A5055FF1DCEC075431A99670E03248CBCAED63 +4457D0EFC6565472A356B1169775BF5156DDF85E03688FE2AA31A158A65A1D9AA4489CC5 +6FDA78AB85C35C42B1754180577244C5343C21E222DA72B8BFA097BB860E9F834B62AF9D +D50481FC4B1B9861A1C2A9F340237C949FF030096DC29FEB028A00A5AEE8507AA290848B +714C13145AB3F4EA42C8EBBE4A3CC737C487D0DA0CE29BEFBEEE34F5CBE03DC91E5E2053 +F114C70CBE94DEA1653A26DD4CD332F62AB71115DADB2C6B3339878B9997AC3AB5F5ADD4 +9F432AC706A5256DCC4592C30DF40C5C47A2FDC72851FBB0E4EEFDA227B72EAEA758DEA2 +341344315496A6F22D42FFC55B4E90821C251F0D8B5FD3E0802D04E10DCC31E5024D330B +25AD95CE31981E90BFECB17E786A10ABF9A19220DB82744A43BF5B4DE0FD8C54171EA498 +AD14E0972D6EA90B5CB9846354C855E2E13B369BCACBF8F1852CE60227AB27CC84B9D326 +68E851BCE4086558BA8106D9249C3785F3C59E43827307C87C72033501ED888E32325158 +879454289A07888F09EC7EF1D6F55B92363BC740E170085C4D16547007A66B6F0E1FDB4A +4FDE032A497377F8B309B5803CB7B450A246A0CAFDB2F8CEE254EC5F6BC7C1EA38BFDD79 +268969FE9DEB9FD896E40E479222BD480EA1AD9E5E0EF7780D3E48D62219E5518499D46E +DE92464609DCDD07B5C948792B71F1854C114259463E839A2DE74A11A7FD114EDE9329D9 +F1EE8BE5463AF8A04943BF77CF68B0F3CA2571D4BDC19B980F8919AFF6EC80758056F93C +76758F0AB6313052355085DF8F0BD62C7380AA3D32102F48F4F84C153295AB27F3F55694 +E3C6339B3E34166DB450373B9F326A1E108ECD95B0887A4CB8C54A811B398C0B37289C81 +676CD8D528C75437BB2DA5C83C0FCDA94588BD785E4F800E87FDE1F277AFBC3ED0C5680B +27DC483446A828114CC9B239D8D1C2D920CF149B097F9A78E35C0BAFA1B0AAE5730BA067 +B142087578ECDED1DD73E8541BACE5FB813E14483193467EF8585682295816C4E29E197E +ED404E94340398A95A470A9E06BAB7BE0F5FB22338A833F9157594C5030639AE0E69894D +49098CA950C39937BF17194797AAAB7E076A2087467A2D29683142D84B0810F1C603A95B +3A81C3225003834CC446ED0944654805AAA164B088489DE9F71701AF4DA42C675388EA82 +CB8368EB21003C19AA278FC474731F2D74A008F24792F651F110E23EFCAC719E2E9C0481 +10968EB515AC09006E062EBDCECDB6D93772EAB20D7C105DB828A891F2711DB786B575ED +484349390AB27A3A767D8092B7585C8CF32F5FDF2B9D78A27FB8E05C4C25D970602ACA43 +31FC692DC5C7F7C0FC5669DD8B150D7A4EB22218DFAA75E79263D106AE84AA8B573B722F +BAF6D7F79097AE4007A3E519C107AD00F63069BCA7314000DFF2B06E4A9DC82FD10B27FA +16775E13913364DA3020F7CDF748CFCEBB7117CC4251031F6795F4289C4A63088E985927 +B971471069135C4DC3BE1FC3912B02F933F26F72297FCBA9F21820493FB49A1A862991E6 +948A274C9C5954AA6BA752D4B4096C953E92D916369F9AD0DA5055521E3420ACAA45D436 +6D061135613BD328630FEDA1634FFCD8E2F23097218C2449520D986694B882081A791CB1 +78925494D19A7EC770AABFB956E69DAFCA7C72698AEB9DA304765F3D9E351022F02B0C37 +9E8897E597144B416A008212A0780DDFB9FC1D89063A05D216AFED272F8836E5356A8BCA +818D7F491044995DBB9574BFA5B9E346409B9C4F768B59F654E9D607F3D5A078F1F5C0DA +6EAA9123F369B3341B40BCBEF1EFD9D56DD82A15B550E105F03100B18C7647702879FE4C +7D61243D5688B2979BF250CB1E594B1A2B9212EB957DBD3D41C0029A06C9BBC302F6E969 +4E998A090296411D7871E35D9B367C1191A3F9A638BDE0784508A7B4475F768C24BCAB2B +AB375DA779894022D09EFC62788289D9E72B74F7C52F2AB389038D4BDD244E1CC79B01DF +79E905BF50CFF6A5C06E68FD894BB1CB7E513B33F34400DC38EF8EF6E39268635F66CF70 +D5EF4EBE5D4F36430233785252376CE73CC9E6F83BEF01F6D1C5AAECB6848CA50996581D +E069F69083ACF3090F29844580712073716A36392BB2FC1049EAA0E114976B098A344B66 +E0CCBDCE847B2D3B620DFFEF1ED2FC8FEB76D1766F76F3855F2C2DE7CF10F4DD4664B006 +2262CA279472C2FC0882A8F0B5A4DAE04D4293FA7E08D7639B3D7FCAEA1124A261BEA0C7 +560C6C52E61802C8502C66D4896EB0D8964E0ADE75283048DD0A1E243690D989A49FF16B +33740C7A49B820032167807CF695F91C55C0BA6D6AE7FC7368885C674B8BF30931870677 +03A60AD58F42F6766DBE60A74B2C2E7CBCE56EE68DD0D269FDF5765AA414157BC63F5CB9 +123E0532224DEDFEA2E668F3875AE4C5260F93398EF86BD5867E0E18B497FD85C4FF4A4A +3AADF54256544BCD7811B58134BFC41026132D8D30BF6903C2940157AF0568C9B6BB3009 +7577212F65BDEF06FF06760E38BD32AF61BCFA7E2324D68AB590F2E45A9761124928F6C5 +64BDDB6B51180CBF141F48EF9FF6DAAAFF2E379A2CCE80EC839A2EDB91827F9D1BA0AE40 +FD36DBA0E8ABCE564309F7DDAD96A5C7D87212F8D586F013ED189D6850322E4670CE2D07 +18CB688DAFCF1961FB0F4AFDA71382DE9CD976FC29B4CEBADDF073774D9B8AE9F2374C04 +F704860ACB17F8A16B4051EDBDA362CED1BE1BFD0700524188278DC8D6B22E0D585F26A7 +C4447076AE0998A76AECEB8454959F30BF5A4BEF1495D6549392AE39D97388B5AB14612A +D6472A6B625134E17B540AC0D514C1239ECCAE5C75C9F7ECFDDDF66320D00052D874E6AB +792FB1CF5F37BE8F34A14CFAF642917406C3C519EF56C92114E706BCA38731B52D68B9E1 +61BDADBD17A62D1074CBED9FC77F5558CD4970878E0349536745C3DDC0E6BB4CE878B2DF +361B4DCDC5FDEBE160168F4D0DC81436B008714A2EA3BB569961F07BCDAE095A44F578AE +6D0E6B5DC7CDD38FCC37177DF292411C89B4B64612C82029570C5A7B9B55F38E063BD3FD +E00421B42FA18751B624D59495604A52A0DE27FEBBF7689E0DEA085841050DEFB7C9FA52 +D3515731A1BD61D4BF5E82841B221EF88D921E1EFF65F731948CA481E500A46E84487BE4 +E3F9DAC68918F117B77A2B5B68181C914FB764CC5876D2A42CFE47F045F72E5E443B4921 +D0D63323C748984F622F00F63C886F404C671119FEC90A598084F85B4866A5C79E987C5D +BE5458A2A0FBCE0BA6ECB7433F9D75142DE04FBA357042FA9793BC9803E78E573A14E140 +BAE5E044DFB28D9BF672461BB3A3E50E1BFC83EDFC49A962DEA01047208F49C4CEC837A9 +D2318E35301D2B18DF1E8D828B58FCE8D5F1450E4CCF92BE5CA2B30516A4E585D6C83BF2 +80C7442A4F942584BCAF4C2CB5C2F56170817BF0535EBA87C75BDAA0190710A7E2D4029E +CC54559EE6424E26F0FF8E1C2D3D012B3FAC397B1A446918F1D299A19B7A28C4D7F146F0 +CA4E29B96D275B54C16B1AC37FAF498462C7BA8D2C11291175FD05A5B3E08290EED58ACF +680DB2202F229D7A69F982E644285FD1FAF320A0C88E35BEC245D249AFBCF6CAD552423B +EA2AB070F314FB9B3EE02ACDE1FFA602D19E1805F27D1AFCD58D6D227EA765E6630149C9 +59ABDC3067CC97A797C555FDC59B9E4DE3B0681898C970609B1B6B15A15A65EEE2DEECE7 +2BEFB1E2C7A2BE2B3FF19B2CCAE4937DA4B593A60FBE0E0DF3925043E677D44B5FF7B42F +73EB65150EC0533B294B675BD7D5CC6A7BB6A4F043FDF87940F8A8CD366BFC008273CDE7 +72EC15D7367371283EE5BC26CD6D46CE665661E16C691727CAB0833942367DE588BBF434 +06F4DD67988AD1C0D5C3D24DA8A833021F65E4E4393959434E03CCBBCC98699A8B1550E9 +C3192D3D3755F81C51E6CCF4C4E6575D9D4EA77261B987C8FC8CF67035D281D76041F70C +2B2FDC8FCD2719A93FBEEEDF54685031ED2E960D2CCF2B5DB0840B2554B1723A703C41CA +1E6169F96A1050CBA7A1554FF8A6D7E4BAB0B549664DB9B808FE7C5EA9ABA7B071E71125 +54D021BFF7345D1295333E876E28E14F2274CA0E5E4F3838B775890CC30909661D5B86CC +4F681967BC8B5B9169C6D8F1B30ACB914E1140C6A5AC5B6855EE83BF9F8C5AC875D93BA4 +1C62B9D44917BD3B46F65B23FA3044FE5A6F812DF1E77139253576ABA80A57B38D315E82 +CE42DBB3BEFA62E400A194B5F59DCBFE915D3B5DC010B4DB140127BBF0195434F5A43957 +881974EAA69CCEB2E588DA124EC3F7CD00F6BB81AC494088F061065C204A851B8890A5F4 +EBE9D680DEC34FC853FBC85E20E3D9DDA86549FE11396BE73B2978AA8A4C80BA94788D8E +D03D48C88C9E047CAB868D7DB3837EFD41267AFDF4808944506ED385295788CFBCBD89A9 +8DD84168F808E49BD346874FB281AC70FB138E100D914093C582E7C85F5EB6243A941DF8 +253B06BD01E8F75C693123BC20D17307B8E8839CDC5CD180FBBFAFFF702E0E9F6077237C +F81EBE9737C296BD5180F40EB79A41BDEB37FB0FCBE238F1B86F45D8F25B39FD7DD4DE88 +4F1D9659A27AA3F25CE066D8D84FC09932B8B2D3BC89941CADBA33F7AA87ADC13453C674 +E8AF9CF633ACC730085EC2A843949B9E5BED6AC3ACAEE21D620495A0DC04260AE555D15B +59143C29566D3331B26DD93469C682409BE8D37BC93424E115F7DCDC95EECD57953BBD28 +974F249FC98A73A384260A0568A69B382886A9AB09B6215E463319F8736865F700134E65 +1D78B9C819501DC01CE5C55A2D58F12D74988AF124CC6C7E213520C940F6F8CB4CDCA9A9 +DD2B569D06A967208EC37AD2F0BFBA7AB7DFE87AD7A5AF4B6E77E2C8F90C9A97D7EC58FD +2D7ADB97CB6AB5189AB4E5C29A1044887CBF775E09348A2FF946E9D7FAB0A13D7405937A +EA98600DF50B8FDB161DF14D091B58E925BF12EF3176F3EC504E1E75FB868CC46146389C +23DBFE0F908356283136F4A2A3AF2C197997302BB3E545907C3295AC0FD06D2069D602DD +052BFBEE41D7C926B303D4C1CB548EC9537A0F5FB5C31899FD160BD9EC390F2E0F6575AA +032A78BFB98714D731B0804898F148ADF072B3E714009932FC8ADB363B18B2B15627D3DB +B20DE94FE90B2CF68F85D7961E9035DE17AA5505254D50704903F28EF414D3CA13077AE5 +A0BEAF8F5E11FEF25C8484A34A1C39FA1E8CE92F42BEB83158BF26EB1944E6213E5B1531 +C7065B2F1449D3D444855727E691A501BE62F659322006FF9A22A5288260A785611791A4 +56E6915D344495E82303F067471E323B888A61ECFCEF90676C5F490A9DD6B6803C5789FC +A7B0B7A1C7EA4BDEF4463CD5304C626E8D714619CBDD4C4EAE61EA1D2386642DD4DC77CF +3351FA6ACEB1ECD55CE4308DFE9A09763EA427021D90972F2B8711A98C246FB448FB3FEB +9887A101F53321CE647B3B9CD077A31915269E6D049E48305F3B2E84351FA7C2394520FA +BD5EC8CDF9EFAA99573B1788E0C77FCA125F590C38939FDE67561BE1EB47575028ED1F4D +27A7094B0500824F6FEF2710FCC5768F506616AEAE73807BE2ED2E0DD4C1A337993C9A62 +C7601418A586D038E886E1E22843C38A9F34845DF71AEC30726E9AD413A84081F1E31A53 +73D5CFDF816D8F6CCD90C2B438BBF715F0EDE86DC31341A0899CC6374C573FCF2AF67A47 +5371828212D9AA17F18FF25801F83D0AE19A4712E24C2C024A7505A2FB269EB3E7DDF59E +7D95DAD916A5D35B7D16A82764DDBB3773CB0C6E3B1F2FDCC0553B26795C348B6C0DBFEA +E7CA7B74D90257D8AF4F9D4F3C776D858CFD230781D2D6F28CEB29BF4EC4D413DB9B47DE +E4B36F6CCE14C09A033D580D573C21B4A45DC172C0EA0DF41A0BD5CCCD6479166B30961E +A2094DF2262D9E81465ED2C66BBF8B28CC4A25CB7C259BEE2C2F0991614D161B25D4635B +C869B8008A2156BA56B48D6220DEBB6713A035003DEAA0160477F5BF7E336E90CCF67155 +0A55B6A015468E8A8FC8050C979178EBE2F7434E11E6A77E2F99A133F81FB87A75F42EC9 +AE9ED23A3DCB35312036CD819952BCA72525A39594C79C52568556C3A90E95C6E789A99B +04348DFF652C9A178C5F88EE957D2D037FBCF584AB699B276AC228DB743B4C4548EB54EC +38F6157163A870C35A4A7861ACC66118FD3EBAF43154C13A4FB8C52AFAF5F7FC67571D85 +F994E66BA3E8ADE5973138F61AFAC440C1EAD910FF8F79B11B73C697FF7D921266E48D51 +DA2FD0B438CCE7BFC1A1233FB8B5D812D8E18846B6401E9CB3A33C514693F19CC21A2500 +FCB0B0EF63EA74441BE9BB70477A63A641B639C54F93F4D4BB8E76D0E6F49D134FEC890A +B6E118D754ECDB3FBAD7FD4493AD9415ED13C05A0FFD949F3363CD400C5E2B547F1CD6FF +E503F2F4620579B69415F4BC356F943868F198B4243D250992B83BEBA3F07930F0F93366 +72AE171AD02B20606532EAA8F819AC8968430201EFF0FE42E8CAB1A10431FF0353827919 +847B2B20B0B60241ACD440C8917B4D0723D44A5FDBA7681E9541AB784B1A109473D3AAF2 +C035C27419CE30E5EE3C62F0EA884E4D4F164776DFF12D212629EA3AB2B103F000BE0A92 +298F4D73B79AF1929DF56280BAC6F03ED3F9DCFEF4B138F88758E14D4E90C95DBD9FFC40 +173E6F795689C812D24BB1791879326ABD3CD7FD2985FA950B73099AE1B86959E46C4709 +1278D31A41B159811140598A24861E34F2BF09ECE88BC36747DDD892AE3918C41A961D35 +28D8A8649E626FCDC9551E073855DBC34B57F6D198831CC189FE1C452FCAF8980998D621 +F31D2B9C7794DDC8B32FF3F8BE6934B03CE603020E7A37B51DB4E1FC33F625A8983B95C1 +853A1B1B4D4F4942562DB9A0FFAD4AD95A977DE81139687123317B757CE75ECDC8287609 +6D7797D50287BE38960290831474ACCE3F57676811A5DCEC78E91488C53167DA013E3797 +A9A8C05968C8888B2A55EF2032D66F6174B61CD24D0C62BC49250AE6D9B505371CB15160 +C591809EE7551D40D3CBF88D33F8A3A9412E6221D9E656D22083980999E405957E9D5A36 +64EF1F676EAAF5FA309D23C56C95541E7E51958358B436DC4CA542DF18398AB8E4D05FD2 +D24BC091DDD9F4F963A20791D88703056B5AAB84655B3739821EB288F1A1182F67154973 +AEE39C7E8CA894130CB0A9A811A1DE595BF12D04EA825F2A11A365CD1CA85D7C7F2DE801 +985F64094A9D168AE1F9CF287CE99031D0A1742DC08698572926219E0965501497C9D355 +6E9E32D23BD070BBBE905C512C864DCB8BD9E8AF46FF4CFDE9D86E8F34DECEDD99E8A745 +E72885340086FC17EBA499548D8C535CFAFB42D202DF4C91BF817BB786E577C7508CF99E +A088D9B070F5A5201D23CD76C9DFF960F0A77EE8CC94FB5CDB8707F8A7420B7FC2AA40D0 +6E04F60C595DD66DD436A4E2BD606121E423E0177B17E73CDC168DDB7806294A1A2DC177 +87C4296B2BB174D55D9255EC44CF850A68DA75BE1B577E8DC80B715876712DF29CBFB81E +80BE970CB01B9F8018C381EE021B57E01FD3A742CA387317883EB3F06FFA93E0473BDF27 +98D77D6B3A962CF9F42D181FB4AFE59DC053F2C059035649A646F22A927A4EFBA9E6D3A0 +2C7762AC72BC6827D49171F1F57C354FEE5E92E96A30156B8484BB3D9FE7A21B59008AB9 +9692940D35EDFC207A14D20D2FE364ED08F54A255D1F434B432F00C67863997266F64862 +D92AF31C3C7961692F6952157C8922AC8C8061E5CE8E4FE5E024C1324140354E9DC3A768 +B2092B0184FC1A46FAE459AFBC0069ED4C2CEE34ED7D756D65A7474B28FE5F56F6E69150 +6EA2272C75943E3CC9CE5FEB2346AA91136F5B306805EC51D6BC12E5D557F1F290E14CC6 +043CA5CD3D0EF095D4E62BF2068072ED630BF1451B8A35DB5783B6496DA31E98129FB96E +02175D288D2854C505E2403AC9AE94145AF6D327270DB865EFF70867894567B87FF7E5D0 +16848740741342E871BBD632ECF7673E1C3ED00255BB34A67D709E16EA1E0BD24F6510CC +C1097402E3994605B5CAD28A48DE6F37787A77488D8C62614F5FC3340E952066B61C9DE5 +1EAE3FBAD5D8B5AC64F8B261BBF06FC677A28EB58F4C8A08A136AF3FE387E24E6B100774 +24D077650EC787BC8498BE6D7A1DB54A690C768825ED63AC24E62E40D5CCB2AD05A2675B +301C895800F08F936C7175F6BB3A5CBB86536D5EF41B111F3EBAD9769324DA1D88C4E835 +223D976FBE5B9DA39161F6F3A7BA02031BC20EE1143E1FA73599CD30CD43F0552510F0A3 +67E8E0963D12B74C429E15BE22C0AAC2717AAF021D437A784CCFA60E8BE2ECBCD962B1BB +EC8CAD0439CDB73131D32363354CB9BBAE21B01A27830971D1D7B842E3145D5A400BAEE3 +76C639A3B5D2AD8D51B75F7FA86465DE401BB13FDE3407A093479B87B0E3B2BDF33E9569 +6501ABCD07786B1ECF72DA8083FA1D79873753B466A0423F1B504236B95C497F39F5D5A0 +0417B3D8AF9721E5F3B5ED2DFE47D9BD0930F4E9234F181CD24394891F7B554766BFEFE3 +CB4533E3D01DD656FBE2C170B82393C0F3BBCE9367C9D5735AF8317450C7F4B163CE95F2 +6F2F7DB25CD88EE9B01716DBF1FFDA7FF16D54EA39841BFD3EDAF3684D2298ED45C8486A +F5014230F331FCFB320D28D5A1A17D02D5593538946C8669B346F4693FADAC663FC608C6 +E091F481E1C39749D26AA37062D7D94115152B214506B91617E829833AE67807905C70A6 +8412293287EEB2286A27DC7D7B9AF75FD4E32DAA4641EFFA2A79A04DA0EFF958F411890C +A50246E5A1F53315ACE19B22C9C14B897272237374BDA4221E3FD18A7D4E26A09DE3D246 +D604FA90092F188E4D2C6C0144E6D49DE9BC8ED4561B9CD8EE8D308EAD97B6150056AC9B +9551CDC472A642A9DA02BAC20EC5B57698D68ABD0ABF1B0FB5231479D72CF429C39DB34E +A75AB17BA21AB31E9DE9E2584C2EEA8BDCA322F0D03291CEFFF011843BD70C43F49551B9 +B10DA24AFC0B79A87B6F493EF73E690A4A705DC8CDE5E2602EC6E99168357A69816EA5A4 +5945A242CC85BF5E7B665DB8276C11483E879A1F9A59E4FC8D6B700519ADD96909BC3EB0 +DDABA0BA75AE8809B6B802FA830E63583622109614A63B928AFE297D434A33BD0A12ED89 +0C15CAD72DBFA7EB5F30B12077EF47A6EC309ED1009141176F7932955588C053DF307C96 +B719564855ACC024859429DCF8DDFB3F7ADE1BD65C9B6A97BF5A56FAE58F41BE9ACC6AAA +B0356F58900CF66FBAB2E2439C031103D8600FCCB20D209DD510DFE90716F654C539D349 +99130FA43BABF53F8AE298F10CB073B797AA50E00FE9F88D9337CAC4DBB0FE101C28283E +6D4DB8FAE80B4A998525F647E7023AC5B9BAC987D5A9233541214BF0DCCE6C524BC1C56A +ED18B4F76F8010AEB8E1024082D22AB60BD9F338AF6228A09E7DFA8438F2ACC066D2CCD8 +853062A5818DA00F1747B6BAB166F40D7639DE8CA985C2808B0010608FC7923C7771F728 +FDAFB1F118E2640C2C42301C465F40817C13E20448F16AC7D42E39FBE359F744C12DC67E +99A4B92D9691E1F6D2096F11FE4F017A4C2B22E4C550DD25E3E31E8531CE8DE879451600 +4C9236E36E8009F5706C8BEE72F007538DA5918999B97C386DD6D62F7B433DD99B74B490 +263C2AA2D059D2DE95CC604A5442116DAE3264568FFE88A9B1E4801052084DC11101EB03 +E514E220E7BA851FDB7B5C8CF635B2496FF38CE6DAA23FEFE02C25B520473E5E07EB9354 +EC2CB7A7A75FEE158D51A7CBE8EC36DFCD038BC52E9FA6483A5F4815C132B2C40544B08D +8C8A80B1916609636C2B53FE27E2B4715852A6F035C139F9EFA33ABBA2550B8CEB8F9C0B +EF80BF543D1745FA88347997D01BEE8A8E2FD52FC40D3BFD3D438FCFA1CC5B4082ADB51A +5EBE54EE1C95DDAF8E5FF6FCC98C3336A292A0FA05CB5B48C122D6A3330898979AAD071A +4BAC19B03B03CBA077252506F8E68EBF004B962BB85B15A87FE5497E8F2E208117834E48 +62EBA7AEFBA9A8997F71142BD6F6550F3BB358738B182A9CDD411159DA92B0B3E49E4226 +627A196036ABEED57F176C72B30AE16C1C01B330577FE8FB0C0F7E09BF821BFB4F056A8C +B52D5797C0FA48A9625292440F76387FFF46837A2445688696830AF32EACB2B6096367EB +A8C8C42341D2F3EB5D5190D9F7241FB1EC16DF0D6D40FABACD1D7E99EEF4AD6118696165 +3354A8DE539F92DD3426A196A7DC33F92B170D57E48AA80902D9F31AC582A4B569D15C86 +A8E6FC94D75970BC6BCDF2C77318B1DBCC7E398B48FAC8D2E392E93CC37F0BE6186DD645 +EB077151C6F58EE8203B697010EFCA123FA904A4EA80388FFD88C126AF7F6656E66B5417 +8134B77DB4E0797C9213483E787939113C39215FB9F5B3B141512D962C500863C2F362C2 +3B73E9AB89571A003E413435A02FA3569228CC6C0D5EDED34373FC7EBDA1200537C1B72E +9FAEC2E74E5E6C3E13CEF1B8F332E7CE6CBDC4A17EB9CC265638AE57E28E34CE99CB44C4 +AF96FE97893390FF2583486F7D8B0B2D9B13A8DC0551E8AB85046C9E4091B6D5D5B193F8 +3EB3E2131A6EC9DCC9DE88F4B64E45AE7B5B6CF10D4F812C9C784BF65FD9E942951AD808 +FC9F010A0F45723593A354E578F8FEB67978485F40620C83EEF210B6678CF323437DDC88 +5436567D76EEF3A83448EA76A3306CDE9D5045FB2BCAC94A7A58B21C0166D5C4339566C4 +203535359326524E7AE47FD406959610B24FE98ACE978A82B5F644B112EF6A289C018244 +85AEF2D0C38178851D0D5A6612C861AB52B46597558EE8E588F95BC8D657B02AADE2AA25 +9BDDA214A736CB417F9564699D293A98C7A7615F47806B5424CD1FB7292AD1F2D7DF6837 +675AD97FDCFA6825F4E22A4C0930299B0CCF9BCC67806E4E6A8EEDF449D96634C19EAA00 +912240EADD63C8FB02A227B987A17964F5C867079495B383FAE560309FABE8BBA46C3F85 +E766A98E5B8A980DF3205AFEB8416B4610E6853409B658DE2A7A3C2C6A292FF33A46D9C0 +E34FABFD57E19C89A8F88D8C4798A96F4C8C3655808FF336C7DB56F52E0C6AC761DC0E0B +39E33065A02A8812D91AD303F3DA2C1D61913C76F1D2DE272503B223ED71DF65A5168433 +A7BB3C3547A7E6A5A190F200992B73151BB9EE0D8D55F9AAB9D2E73677D3AD16D20D553A +D7A7A1668B19F58E7BB9A5CF973A861645016DC2D07A39D5430D6D1644B88035B8575DDA +D2DB0E6C040FAD93BD0B8486715821F2D47814EBC7EACE1A5CB5D3A2E19352EEE008F258 +6192627BD0B3033199DACE43803176F7A19946985CF975DD1BB313DC58DDB80A2671637F +E89D6354DDE8F8825550F1F616DAFCE19CFA095A36BC49B8437C00DB2DFF9B82ED7226A8 +06020769A534706BD6180DDBEDEA953C98D639FBC8130732B42F0C512237F541ECD03603 +8EC9F5BEC45B45F87A324B60E13280A18A2F6F333C34CC254464F774DD53906B7FBC79C1 +CA8CABD58310D272CB49F4B3C83EF616A9743CE5C56BF52B00776EE469A45B18B8457CE9 +DEA7CD6378C87304224B578E213AD3D9E5FF6E642BEFBD59162DF73F0B631C8831132284 +39374839A1DBA4C4B4C4E30B7D411B5247F258F18A8723659A17A52F8194FD810318B32E +19DC9B355C028E98A36545D65073D0F8F4DFF0F9637C6F599C2F883B10FADE5077B49257 +F16D0ABC0DDD9356F6B10FCB64D6B6ED9888E0312B092DC9D154CE76AC14D14DB564EF77 +0EB48216D431D21672D50AA13307610DA45B3AC8FA46EE7F61D0C643E53B65CC659E91A6 +71BF448EF3FAD8D18794B383523AE67CE1903510BBE2B2D5CC5D29F3DAFF71A54E582E22 +420D62CD7CC8A4E093207432EE4FD0FA3B2E72E5E4E62B450C557BFD0A83C540C1FE9E80 +C62D150ACC0CBCE73BE88F13D7E4D9A3791C806B38D12315C043CC022AC8CD3C61331345 +5D19B2036306F132C074043CBFED8F1C1F60C74F074708D3755A6F28628B31C0D8068669 +C8BB86C6412F32C8D6772CFCEA101D1ECC32AEEBDBE423A7DE28BE36D54D61CED5FABCF2 +F0E731800ABB9B10E413129331BC441F80A6617F9A5E551CB4BF74893227C7D9DF21DC11 +6C7E796F8ADEB43D2D223B4647DC5D53E65786C5A0DE8F3CD5BC6662B051291E36D47414 +F94D999AD31C1D6916EB723436B41A72844806C0A8D4BA41A04F1848DF180A3C3E27D8BC +961FC8509CB3D4069B33C5E01F3C0B04D55AF2EC4CFC4DD7EEC9AC9426CC907DC70D9EC4 +E428D30D8B28A27EF202E3788C5D14B0AF13D750EB7A8C5C4E5141AB5A477BD660753B64 +EF5C871681283A0DA5AD98DB70A90D72BFDCA0E18450D3091EFAEBAD23EDECF3F016BCF3 +BFBF286FD52B5D38D3D02E8161F8485D3B9B78C485A196C5CA052DFF546E4CAAAA9F9F8D +925E6F4D842B599E1A482C92F8CC86789F192987C3750771A11076C35415FEA472B29595 +9A437980A15C2136D26C83DA0AD724B1E961251F80B9D751A89A004DBD66C2540F758AE9 +A8D9A87A40CEC4A048AD21AAB511A630EE7C6DB0BFC5516B18140B0FB30CCD128475CF08 +1B10D9E5DED0BE1ED477142BAE698358D9FE9090CF0DE3FFF6692A18E2AEFEE40CF40B0C +AC0CBFAFD61CA62667B8C6AF75F2C8C610189522E5C334C3EE4C5949629430D193846DB1 +3F2F49284722C3D93FA7553DB263182610D960D1154CE3E72E93D477003E26405DF8457E +919785328FD7A0EC5E75FEA4A69A4B83A0B1BF8A257C95DB99ACE02E4E1AB1C7381F70EE +AFF4424E5DBC89F8744C31CEF9E39CBE52AE7B222C3003ECE5CDB70CBC5705BF14A8DD96 +858B2D91BCD9048CF5499B557B47EC7EAD4F691D9C0ACB5AD0EDD67F18D0C60BCC5B26ED +977B54870AD334A5BC6FE43C10EFC67449DD1EE7E447AAEA62CBBD3708A5C53B50D9A422 +D90DED5D2DE9496DCBA55431336DD959C87DB3C827D74142F295A7FA2AFF3FF16B6B3A19 +1947BEB998BFBA0058C8A0C851E677368674FE190B2498042A1091F5DE30DF16380DD89D +0F8D076F0AEA1FC15F065FB5F094FD7DCB9BEA369B473A796441BB35C3F7D083CDBA9263 +3AECE8EE5EA3A475C84552463F714F38F73B83ACD3DC7FDC9731E55C25735B62EC439FD7 +421236A8ABF2E15F572D93F863CABB5104F2F71C5CD8360ED6A16F0EA6E20965EFFFAB3B +9AE5935C206A074C7C3A21F8B50E6E19950DC462F06515B3271974877B0C33B7D2F735C1 +06597443E2C5421CAE134AF0E035786DE9969914E2F0B8982F9496D64DBFE6DDD678B875 +9825EA82937D32C5D3DF19C9F35700C733C65D3AE498C2039D41BBDE6CE9D975E753A022 +67E5354D1739005A656DEA77ECEEAD9D8C3B85512D8BF6B1B5ABD84B6D05CAF87B254ACC +3F650BEA548DC6EF6B1467BEA6E424945B7A6656F5DBC695D3E5434E0B88E5BE68B5BDEA +9F91337F7A74A5E7AECF9EC30AA070AC66E8B1D8AA70408B0F11683BBDE539EE5DBF9D32 +9B1A1C8CC14407B0FD0BC4E282D2BB466E3CFCB7E2E375A0DD49FEC7A0ED1CB15EBCF2E7 +F96F1094AA840E618E69EC295ACE5999BE90F77C523822EF0C15585CD816D7918D2AB0DB +65CB72F1AB5CE5625C75B493E801D7A0DEE575BCF53E4F0BAA2290275470C5F6B49BCF03 +E4E8E31CE64D3A6A6C42ECE25B6BE2D2D8D8A821C4C727806944639CB4DC84777A2CE101 +8CE5EE0470D863ACDBA2B69B48EC7EBB23BC73760396F13BF6A60BB6D664D7B553C2AE9F +32EE16F06A114A3BC7289747FC6D85BA0332D23EC947B25D6C10750A83027A745C1737AF +E9BBDB080BEE663646BE3894B184F9B892CA8EF2B3AC255DD53388D87859F9EAF8BC82CD +B12EE266A079F78EA317C41C505CDFA41B1CDD8A63B884DE1EEFDA7B7DB1EF77D0E98742 +79C50B55DA61FF95BFA7076ADF6BD3586E2120666BBCC3E431CBB19963982E50B9B1F375 +55AD6DA4AB02B305E074972C7961D66C1D1327AB93813F7A7C6C860A81281795033C8AD2 +8FD44E1AF0668D8ED469DC184B612DAFC1529F3AE5D8420B703821A559D58D5C574C15F4 +9C6CB20FCA5AF432FAF63E73F23638129D3E80509C0BE0034458DDE29F5C88807FE1C90E +5BAC2CFD565D686945583260334165D27B08EF3C7839396EE421686BBFF67996E5FC31F7 +C4C96155412C4E51D5B6C97F6C47AE74BE984B347222CAD8B76EF218F34CB3BDCDBFF446 +C8E52F3E2A121903E260C844B093439194BD3078E158273B28A7674F0528C9306CD09C1F +8D612881D46B8D4AA4C33206EEF23F0DF150AB91D4EF3A55120E3CABF490A2FDC34F85DE +0B4C3E712D3DE425B3B0B5053CCF7729D8FF20207EE09D7ECA11A2685FD4AAE6275B9C0A +E26543A3F0C826FBAB318690FCB471623009FC751E656D31538951000A413132B4C95E2A +75C56BAD12A492F5F44C14016CE7751831A892BAF050422E459E71A614409DFF87BEAF8E +9D61471C279C9B2981C3A1D119678516111B965A060822114F9CDA77DF46059D434C6A0D +D4E57EACFDB4560FD29807C7160051BB778CDD807B3602F6CA02F699E8A42C7A6143B149 +2E78C8796116ACC803B5CEB308B9F8E9F11DCE649719618A9EF689919605EE6FA001E178 +4A008D1D5AA354777566B4F5D496ED915709E2FB39688745DFCC3AEB5D520B77C8066429 +6C67D95C50FB86B9DFBEBA2AD8234EA2C967A02B72DFA5BEA5BEB8DB4A30428FAC98FB5E +6FBECB93EABA637684F4A82447EC00D422DB058D521299658F7D392FC1B0130A9B995477 +7FC2011549660457BA46B01E4D7AD51D1829BBD0C80576E893816FF1355C006FD22876AE +654B0D851931E1BF3E80090B762846ADC7EFE333D7C6D529D6B50FA87347EB35438B18B6 +DAB4B45CD3202370F744013D15C01AF637A755734706E667AFF3A498F437465B45255BFE +C519F8BF9FC37A61707A8D70F26AC6C90C73AC9CBE1A2C7F9D607BFDC999B784C7D15BAD +C0CED80AEE87A20D3CD2C57834020350B4310B17E62B192D376EF6947C8EE477331DEA66 +CCF090F1787B19397BD8129449C47D5E03EEF8D4B8238105D626115DAE76062AB6A01E4A +874EE181607F505FAEB9F8743CC79A0C674B8E5BD9EB8D02A5653C8AD1E6CD5FCBE83D12 +A64399F646860E564F1E118C5F18ED59BE775F93A3CDD8F1D4630A48A43C0F2AC8DA9A45 +7562CC56B57A802A3F8543BED0A96363529DD39675BFF7DF6F532D190BFD5C6B8AB3988D +6D375A117DA0C00AA1C9AB60C5023D52793CAF943B7318DB12377D962E53DB536BE2A1B3 +0199D481CB100B3DFC30F3D01EC4EB8C9CA7CE497440C54A12F1EFA9B50ECF7C6AC073F5 +12AC731C94BD7C24209A1BD1340DD6CA5C787E42DC97E23B125B786D4AA2B149D05EA6AA +891AE6BA361D1A42665E123EFABCCE667BD894ED319B8CA398EB6A5E213F813FCC912F54 +205D51716450E1744CB2A5A8612EBDE46F35257AAE6D3AEC55D65E07C50736AB52295D2F +5FF8D43AF818B05071354B5A462DCA72E6A5E482A807802A1DC14132E50425E75C6CB612 +F558228B7659A6CC4F2BEE307FFA31A861D88C994C650DD0F1845A26EF0B8D975B9E2120 +D6C669DE20802B62F23867D708EE1FF1EA35CCD53F5CAEB8EDA12E12A58E9F90D150A692 +194564E1DBB173B1B3AE5795460A5D1204F1C02A960659A0C0063A7D5E7497A581B0972B +B235C90F7D2F89D6F1279AC5A0A15DCDC5B1391F5E5C94AA03320AFB4895AC4F31F28C29 +3D9F6790243F7070E0AE21864C7A42129AC0EEADAD9D11CD447C307ED64DB0BB41BC3BDE +C9EDA6638EFDBA140CA92B7AD459482B2F573E29B03381A23176CEC332BBD7219231554D +C5FE2C2C56676A137945671D5F55E080EF0306681C44B994A5FEB444A672512C424991FE +6D8D33D099D464B44C8365D37CCF13792CD726375A5DA9CFFB56A5628FD564DCC124D2DC +4FC1E2AC8C0CD8DBA8E27138B3B5DBF786AFF59096E52C999D6A26C5637F277FFEEF34F1 +841A3420594149463AF075107E62315AA0B2D78CCF9A72D1EB9CFD1E7900B0CF877BE2F1 +C7A0B60A1D995F2C5C37F7EDCD09998E7B7E3E2A2C90D4AF8F9DB1ED529B9C3DFA0531A4 +9359BD1C4BF3B82A095562D38C7F15C3FDAF09BC39B670A529B9B7EDA1683D2410856031 +5737EAEAD181EB46EC51BAB3FE026E532E65F7E76A368C7100DD7AE43F881B45DE624CAB +E5AEE7D7EAE8CE12230A0336A098760C71E0003321B6F512527AA59726B249BA92A18C1F +1508D2E3881C1E004B830F9F24A706153F4B4565AB16978D608184FE0FCF816F567911F0 +9BFB10C7FCFE2CDE6ABC0C83657809FB8BE214E5570ACA4CB31226DF4F590BC37EAC8226 +DDFD5DF293A15CEDA79699E59CE459F1BFC0B08DA76C1234F996BF4B2B345A18B1AEBC38 +C04218864D6A7ED071173DB25DC27B8FA8A6DA897D83085CDDD24B3F3F1CF936C74B61F8 +020620AA9114411700938AB9E9269C13F97723E29E86EB5F14D1E86D15E8C8D678EC3CFF +DA4577F97BE67A8D3F60F56CDF929524E00A400C35BF46F64134324791FCD6DFB72DA7E7 +8B7EAF388F8D3C860E8E295867BD9032E74239F627DC645D0F2E99C6F56E3DD919447CE5 +CD3126F491688A53F54FACAAE5A14C796CD964F693C8556103BF132E93E2D9816282CD3F +32B84CA3798DD4675F6CC06E0A26C443E8CC9AC465E57DBBEE15BB206798C8ABAE8BF0F5 +DF4F029FAD45DD95671892AA63338E63779E321AC933FA3FFC368412BD62387E45BF0808 +7C3594EA7E6628BF2921F2AD33C4A7AB22DD7EE3272150D07ED085C5EEF85F5CF78FC9B1 +468D9698273BCBF896DA6CD43E088F7AF97AD83BF300817D35F93D74FF285EB6ECB223C3 +9368103876A36B5D84C099136868530F1DCDA96B56560E6B0B18D2C66C7FED082850CA25 +E7947934A1B66176B5C332CB1DA71B6D49754A06873F8C37C2C64A16442F0D983F6B989D +8153F027A9C8FED72FBB1C2A7A56361BE460D85338E47D0DD878336B040E685C48993D7F +B6B12CEA753190E47BDE31F458FC098A286EE4EF94A0804EEF0324F92643B4EB5FF1767F +9D0A99B59B1CEAA7FCB5CF1AE8B5E70E3949B085287554E8BB456CBA6EAC53040C589860 +195605D082EBF7E46BC4A7D2284C6518D8F49D524712B15981CBEE064FF6BFAA6BE46386 +BB84F6C20D8D0EC6A18A6B74C30A4BCB0F2B81F100A6E78DC4EBA3E6B9788F424467BCCF +FD6C58F5DA79A9691CB6D74DCD537AA085D385318AD6EC7C2F04567BF97EC15A73E963F5 +37CE3F70338D0E3994E0C9412702FD7BAEEE2E7A35A65E57FECD397D3EE54C863E641E6E +AC90E91A8C0F00D839B5ED9D9B2D7D78088907ED499480BB50EB9EC1FC3608A8FC1A20D6 +0C1F86BB28318444201E7E9F0D812D71B125B467BFBACBEFE734A7635786A7AB03AECF40 +AC5A6262239EF8E0F538231D2ECCC1720CD40D56CDAF38AFC197BDB28AFC98F57FC9588A +F65EE7268ECB44AEC3F5DA1453F0B4021BDB7D7829043C2B1D55BDDCF4687FF7D5092824 +30AC8A512FCD528156758D24318A9CF77678F040D05FA800B1910B33B7E12213008CCE3D +B9A5E90F708B26AD23F82CF3088D030B0559A6598FCEA3392073693C64AD3BFEFF0A05C1 +C9BBADB073A756AF42D91F8D88F0839E32C317319AB514A6A24CED9082F6473E2B983EEA +6724C8D82ED94A9A2BC4F375DFD2C84CCF06F9EBEFC67D357441CD976F0CBAA0C8BC2DED +B2AD5B5CC894AA880A164B68E2F5031566D8785EB72CB183F23AABFED617A6A9B08F4B8A +203D029CC05C13537C2FD2C98FF701CBB7FCDCFFF2DD7C1B152D68FD70E9F15ABB7634A4 +CC1DD8BA1F5EE887060F223B792F7D204A338B8A3526841D45D872DF6DC3A9073E4A828F +B70D993043F881AA83A543EB448B726197AEAC9A78CD6456035E5DCACA540D559601B595 +580EAAB91811B756A069A6EBCB887120F245D9CC70C730BF1F7990D119BA7CB75B5278D9 +045BCACF83947457578586A93E32B03E95942B3C036A21DAF4C6F0C5852EB71499C3B9FD +EDF36F528E9A0124992798C4BCED2711E4A2BEDA7A7FEA0652962B4448818A141E81BDF1 +2F11F423BF5675CF46B506DBC8FF2C4695FD27FEC069DF0A43B7136791E0A3782FC4C296 +9E06336C4F6109809F6ED605A56D1330046925FB5F62032E0E4E2C3FED27427C8B766C2D +26738A0AC701E7FD89EA4C9136E5F82306DB83E2E9C2B0CFADCE967B2A8EBCEBD67544A1 +89614D6B61E9C77AA77E3E739C03D593E00B07EA925F6321FF5B8F3C0FDBC3948C6D649D +96529559EDDFF57ECA28B2C0FE35D90D010C10E6E1B826CA23415E17ED863ED5715E7B4C +075F0E1806E51DB91E55AC8B64DB7731E8A33C1E8F5C8FBE17309859E5DCB58D10D3F658 +05923AFEC306B4359EC6A6E8F9DE3500799B7C7B322204AE472ABC69EFC886C11DE790E3 +603304713B3312C9CFC76ED0E421E2A034CED3E88D53A8D80A3F28F2CCB9E3358B152EF4 +421447CAB89C002C355274B50ADBA185A44A746FA19D7D481F7CB902E73E4AD2A74A1CE6 +3D9978AC3BD8B0DFD03E09425481F63EE2CDAB4AE17CD75A3AB05F9246B3DDC3E0AF1D9E +CBB521D540C01CC26CA6F3AA5BB49C804D312BA93E92CF11F6BBAC18A0EF051C52C41191 +8C01263AB5901221AE0F1BA6C924B8F937B49985E6D5C17B54E39E649E6D023F0AA42BC1 +D75A384B05519BB0E4118DEB70D272542D60E64957B749BB76016A1D356C681227228948 +5D89E1CD945BF9DCB49A5B831C082755540A032087A2ED82D166E292303CB1180C49E739 +5E403D0C5E6931ED6E36B52FAFE37CDAE28183F15C8AFE3DCCFD9A48A4BC21669E4D3667 +0DF71C4E6087F5B3ED2FA7AE8B5AAEF2A27F063332527B09D712CA18521744D89F90E9D1 +3BCD7EB332AD7BA8055BB8A859C4C16591FC3CE1474E260A74E3160DE648F815383B0310 +DB2FB9A4587FE13A4E909A83594584CFD382F05EAF8654DF5B44E39496290A7EABC36381 +8978F6C05B5EB3838572EB0C64C1D81E9AA0906FCD84E62B68E2D3BA876D536E7794067C +9C2370FF2E2E46004062B260CBFC29CB5FA0219C2EC6C8AB8CC4418ED8FDDE6747F8EFA1 +76A6C6D1276845AEC38B41EAB3727BBA0462E2E809D76E0B5BCAC08FED585BA6E5D8D0AA +3A36FEE108F55C23879B62C0A425F176E3C8C9031BD8B3E1B6C3D8DC383FDE0E36B33901 +50296F6869A4FC7E095517136B547295D1DEBFA341EBAEF34A179B070EEB60AA91839D97 +AA51768827E4A1CD55C5303D1D99341537B13FACB6F490072D8139BBB060FA1A02C93D3E +08888E313859B439AF27A3E5E7709BDA43F851D13AB5B2EF395A931A99D0A2FD8C6088FB +33D318D8EE1F7C7EE2D2199A638E3858EEA06B3A167F69FA5AABEE4558773A75610E7E30 +F3062576A2A7FD3E9F08FDAE5F1931A7FAEF85496071AF8E16AEE74C0A756927E0720708 +7846DF0F9A7C5444D007729FB69042683DFD7DB0078199812F85FC9DFF1E45C77C104F91 +37787E3867D5AC37FD7E86D52AC67672D89F04782F980EE918C6152DFE7657C6798557CD +ABC854E81C980DE5AAD8E0BC259247F73B92572973D482BA7E4F619F50B0DC247ADD0997 +CE4E98A71E4A041F46CE605D32AD047D2E4260033C3FBF80525396507815EEF46960A904 +1B83CF32AFF7712BE97D636B4162190F2D13CACEC58BB25E89496122D23CFA6676E790CC +29F48483788C724531BB3EDBD557950162907B68541B51ED6DD74C06C2BFD5346CC819CC +8CD654F17C9E798168C90DDEEE78B6AE37709D35923AAC0EF066146D93C8179832E1A7F0 +44C4637E560853D227D3A14EA62E2428567E0CEBCAA3C43B0977DA30251BCB74E445E981 +6521CF8F1955A9BF920121E4FFD1E022FF42581269DAEEE779282512DD46BDA9F7BCCFEA +77886D52E0B6A9C64A37AE0564DD09B4868BD1C6860FBFBA2FF022C291AAF670DB7AC717 +D82F709B07DABA0158FA67C0BC0DE958FDA1A63ABD29864C005FFA7FDCF73AFFA597D16D +51A1E16FED7C1E8DB6972353AE498A9F1B0AC3B778675312C7F01A7533E1A53F31964A3D +372A140EAACBBF7EEF600F69D8C466905CC21CFD1D1EB70B2469788BCF405ED84412A5AD +04AE871A79DEE0797426510EA8F790993002857BF2BD33963EC10B329A596226AAD8745E +EEC9A84BDF4793293D941756C6A582D273467EE704A878C40A1F8E6F4130DBEE6E484582 +4B78AEA786EEDF2E119F0D563C969A64B29F13327C52D03A16CD690341B2E0CA3B622F15 +ECC91DE30A47C82390F5EC38D3A52C24D3F4ED18E8733C1635C25854F05C394686913404 +E6A11B597213B0D506EC7EF6B9A6F4755B5A71099AD0FC9FF11244D70A5B987603F59AC2 +A01F251D9CC39F24FB322ED3FE0A0014A412D7C9A94088C8C2FC99657219FC27B299FBC5 +4E08F729AA6C013BB76CD320B23DDE9D9D9B78A34E6424BA1EB1C95B5005A53F90D3A2FC +DED3AB361A9388D2EE3FF47F4F9BFB29A1375351FDA929DE5A89346D7BDE86588EA5F95C +CD052B256653437D4B9F98F82A4E9D860B9E6CF4616E80E743936059A3ECEE59298A2CA7 +D83610215D893D065D73A0079E6BA899593C2D46866E980DC125DDA38519F181E20B026F +86B1CC7ED4C00C954146B530CAA58C3C52BE08BCD25DE61A6D7F8BF7C7D1E325C4D2D610 +169CCA13C7AFFA18DD3907C06A0FFCC09C7033B9B721871E31E4A25DFF7FC74899E1886D +8F3BD163AD7C34FB6A948C0FF667D97C8E918D8E663490CC7BB6AAF3689689725C07569B +D17661CB0990AF49011A3C324CA124C4CF555C021041B7D301FAB7D36518B34771E424AD +B62E962D8B2C46863DB108E1316AC529A404741DCB27DF4A081965B96ECB7C4564550BE7 +78629AD19568AB733BA2A1599F585BF5132B5B5E59F51BCF1C284AC371799C898950667B +44E71E5FC7E221C927DA70742469E3BFC1813CF5EAE32F109A87BB258438A6B744D3D642 +5B3C42DC2C542A8382C3B7BE8A5C43DE7E4A123D4130D3ABF3E95568DE13C5A5421352A3 +5A083A98EE09EB0EC99C0C33EC688D2573E9969AE74329D3D6E925C568A5BE0811C333C3 +372551F2A32BD9E0FCE86D3D2E83379BD55634101F863DE3407564E3A1A73D8572341037 +A6E3AAFA61F7ACCAD510F7C17261408E8BCF0AA72436BCF21F69EF6D3128CDFF321A54BA +3014DBB6E3354197EA88BD4AB5EF052589E3635601EE76508DADC4E2DDD9B9710CD11963 +B8B611C5D089CF34D6DB9E94FA9696EBDFE31DA2AC089FB93B8F5CB31C301607F29494E7 +490278F0E378BFD712EA4AA99234E3205D0F4E0F0705F352B62574B884E571183CF1D44F +C911A617AA1F23AC0BBE3E088A84D04AC51349E3E92ED227268DCB4DDA76B2DE3B473331 +91087C2A70BC8B0554C3F21D5B5A303F6FD58CD4343F0EB68087715D0086C3938DFF43E6 +92F01DB8319C4C2DB1E2D0B41117431086D4C51B010420F52C94C4B2040FA0FF2ACC4A23 +8C44EDE007896F73FD591E491C9359598F5786978E481141D70BD1FF759CE62EDE7648C2 +9E1C59FA4F7F61A2ED8ADF9E4654F1BF161D7E19FD0CA8307993F2FCDB726E4C92412D6C +F260767375AD211B46CDF539D66B2CAD7410FEF73A289812B6DFE69F6E6F24A3E66653E6 +C1BC17BA415FDA7E4FD466433CF5AE80827D928EE9A2B4FFE178E37B01E8AF99A8A26490 +0AB2637E25B3B5F4CD857E7CDC2F589CCF52D546F217D9B48C894E11F57BCFD6B6CC54A9 +B2242A8A39FEC8578F3F7D9B726F977F78103E4C2429A3C9B96372F3622D7C6FAD2C660C +FC73A3BB8539853BB061AB6F1EF3E6447983CCC1131276693F0BC5C2938DDE7864776E92 +8C2AF847D27FACFB07656A2DCDA533FF094927D920E227E9618A47E949E20A61D97412BF +273AFB50BF67F54190D982231FEFD98ABB2676E59E106F5E3945BB9739A87DB7E0091FCE +97F86052A8C9E9A49753E66CC322C3051FA489096E2FA9C2E5DF52E439EED2B9D1A8D918 +E19A9C8F97FDC6B9A8982A1AFFAAC4E50899661D2BF6EE5EA6F1FF825114A1B3316BEC52 +EC64416C7161B920D7DE9C339DE346A2BE6792F82CBCFCE4FEE70F04DAAFE5FD13778B1E +D7F5F6BBC097FDCADD6808536570ACCCF31DEBCAAE581CE6D4C6364E58665C530026FD50 +1FC1B1414B0371D2BE2675E304B041C7E635DC98DEE3F1811EB0995FB3167480F31C8F8D +85E3B5F1054AB5B5721B7E8C3FFAFC18F50C8EB58A5CA56DDDF3FFBACE09BDCB27852DDE +9A1DB9A9C4A51092D145A41E07981235051BC56F9319F03FD37B28388FF4AD8007F98B67 +C7E8FA79B54EB9F249A0A383F7AB987B6EDF5508069528D49FA26659AF0203E73A13AD7B +3F64D294AFF49E42A76D493AEE50B099E049F8750AE058C2863FA2F4EF9EB18F6D2C11B5 +906194F7B480DBE6FE3D6610BD08AEE0078BBA1411B26DDF14B16A3DAEC2B18B29EDD557 +645FF36507654C2A86B7B2D18C5F886E8F02FA3092D35D4802AE25A6CDF17C469E85F67B +1964A75CF22A241F2580875F639ED480E7AAA04620C6C58B5C839F0B659D9D2AB6EE6E0C +80EEA564E9CF0F9F7F0E70410426047F0EE92451C92C483AE8F456FD95E21C7549392C5E +41018826DB42CE4709FEE1A86F6CF18A0DF73A96F8147AD819E5639F95E6CA508B9CD05F +D0BBCD49AA42A09A168987B7D8747E4D3CAFC699DC40EABBF633E2B6339A824058BDD026 +180BB7BBE9937EC7B87E853DE8308BEBA2D7B1156E0524DB6D983B9EA396B3BCB9A6E425 +8C55325437EFEC9AA659E57B07B838576B65B10A9B4A77304383D9540200A24ABE5663F7 +29C64D293498F678469024A1F552E508B49B610D3EF334279AE58F4BE914742752E9FE31 +1642DF1310E0E54CABB5CFF9CBC0A9FD8C81AC09D7762D9A989C2ECE1B24CED02D991D83 +1E6BBE94F7D981DC75EE82BE1AB6E1021046AB988E5147D3E037E447B1B38834F9FC48A3 +23A734D2DF86BF8313892964B6FD68CB8E4DC0B1EAAE8E85B137E34C22C8F6CF2A5DE4B4 +B914D13FE7C0E3B73AE8A998CD19BA81E3825ADBB97854B7B89C7FFD8E059340566B7348 +36E6FD18BA8B1B60EFD13DB954CF005A501D70673FA63F79FDFFC78571E075E0503A472D +A3AAADEE2A7EC2710E7E910C9B3866BEF6001C47235AF38A70553649D910DC9195389373 +A87A62E97BD65CCA58128204FAE813DEE989DC1E72D36AA9675A25ECF1B8FB2CA45DF4B0 +23887604842BD3626CC1DB5722382315912FBC9C383275F430A76AC081366D100F40E42B +7A4D3A3CDEC8C47E8C56C696A756EF3EC9B47CB9570EABDDD906EECC8F754C92B174562F +118BE4FF9E0E84E15BBE5323267155546449138A613D2767AD28F188442F1FD558F1D09D +2C296FEB0FD94EDFD259F9C0E11F255FA4C39DA709FF2AC75FC4259BAD43DD8B27127F04 +049683A5A26A38E27654DDFD99247AC366003DF016EFCF2D96C6B2F9858F21BCA07EB0ED +516C2BC8EE39B0C568FB5FD8886B21632AC942E7E02C7BB24E007A08E8F628D74EE676D6 + +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +{restore}if diff --git a/fonts/Monospace-Bold b/fonts/Monospace-Bold new file mode 100644 index 0000000000..5474cd6d67 --- /dev/null +++ b/fonts/Monospace-Bold @@ -0,0 +1,2354 @@ +%!PS-AdobeFont-1.0: Monospace-Bold 1.15 +%%DocumentSuppliedResources: font Monospace-Bold +%%Title: Monospace-Bold +%Version: 1.15 +%%CreationDate: Thu Oct 27 10:50:21 2005 +%%Creator: mike +%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +%Copyright: DejaVu changes are in public domain + +% Generated by FontForge 20051018 (http://fontforge.sf.net/) +%%EndComments + +FontDirectory/Monospace-Bold known{/Monospace-Bold findfont dup/UniqueID known{dup +/UniqueID get 4234665 eq exch/FontType get 1 eq and}{pop false}ifelse +{save true}{false}ifelse}{false}ifelse +11 dict begin +/FontType 1 def +/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def +/FontName /Monospace-Bold def +/FontBBox {-141 -1034 1457 2154 }readonly def +/UniqueID 4234665 def +/PaintType 0 def +/FontInfo 11 dict dup begin + /version (1.15) readonly def + /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def +% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +% DejaVu changes are in public domain + /FullName (Monospace Bold) readonly def + /FamilyName (Monospace) readonly def + /Weight (Bold) readonly def + /FSType 0 def + /ItalicAngle 0 def + /isFixedPitch true def + /UnderlinePosition -221 def + /UnderlineThickness 246 def + /ascent 1556 def +end readonly def +/Encoding 256 array + 0 1 255 { 1 index exch /.notdef put} for +dup 32/space put +dup 33/exclam put +dup 34/quotedbl put +dup 35/numbersign put +dup 36/dollar put +dup 37/percent put +dup 38/ampersand put +dup 39/quotesingle put +dup 40/parenleft put +dup 41/parenright put +dup 42/asterisk put +dup 43/plus put +dup 44/comma put +dup 45/hyphen 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/at put +dup 65/A put +dup 66/B put +dup 67/C put +dup 68/D put +dup 69/E put +dup 70/F put +dup 71/G put +dup 72/H put +dup 73/I put +dup 74/J put +dup 75/K put +dup 76/L put +dup 77/M put +dup 78/N put +dup 79/O put +dup 80/P put +dup 81/Q put +dup 82/R put +dup 83/S put +dup 84/T put +dup 85/U put +dup 86/V put +dup 87/W put +dup 88/X put +dup 89/Y put +dup 90/Z put +dup 91/bracketleft put +dup 92/backslash put +dup 93/bracketright put +dup 94/asciicircum put +dup 95/underscore put +dup 96/grave put +dup 97/a put +dup 98/b put +dup 99/c put +dup 100/d put +dup 101/e put +dup 102/f put +dup 103/g put +dup 104/h put +dup 105/i put +dup 106/j put +dup 107/k put +dup 108/l put +dup 109/m put +dup 110/n put +dup 111/o put +dup 112/p put +dup 113/q put +dup 114/r put +dup 115/s put +dup 116/t put +dup 117/u put +dup 118/v put +dup 119/w put +dup 120/x put +dup 121/y put +dup 122/z put +dup 123/braceleft put +dup 124/bar put +dup 125/braceright put +dup 126/asciitilde put +dup 160/nonbreakingspace put +dup 161/exclamdown put +dup 162/cent put +dup 163/sterling put +dup 164/currency put +dup 165/yen put +dup 166/brokenbar put +dup 167/section put +dup 168/dieresis put +dup 169/copyright put +dup 170/ordfeminine put +dup 171/guillemotleft put +dup 172/logicalnot put +dup 173/sfthyphen put +dup 174/registered put +dup 175/macron put +dup 176/degree put +dup 177/plusminus put +dup 178/twosuperior put +dup 179/threesuperior put +dup 180/acute put +dup 181/mu put +dup 182/paragraph put +dup 183/periodcentered put +dup 184/cedilla put +dup 185/onesuperior put +dup 186/ordmasculine put +dup 187/guillemotright put +dup 188/onequarter put +dup 189/onehalf put +dup 190/threequarters put +dup 191/questiondown put +dup 192/Agrave put +dup 193/Aacute put +dup 194/Acircumflex put +dup 195/Atilde put +dup 196/Adieresis put +dup 197/Aring put +dup 198/AE put +dup 199/Ccedilla put +dup 200/Egrave put +dup 201/Eacute put +dup 202/Ecircumflex put +dup 203/Edieresis put +dup 204/Igrave put +dup 205/Iacute put +dup 206/Icircumflex put +dup 207/Idieresis put +dup 208/Eth put +dup 209/Ntilde put +dup 210/Ograve put +dup 211/Oacute put +dup 212/Ocircumflex put +dup 213/Otilde put +dup 214/Odieresis put +dup 215/multiply put +dup 216/Oslash put +dup 217/Ugrave put +dup 218/Uacute put +dup 219/Ucircumflex put +dup 220/Udieresis put +dup 221/Yacute put +dup 222/Thorn put +dup 223/germandbls put +dup 224/agrave put +dup 225/aacute put +dup 226/acircumflex put +dup 227/atilde put +dup 228/adieresis put +dup 229/aring put +dup 230/ae put +dup 231/ccedilla put +dup 232/egrave put +dup 233/eacute put +dup 234/ecircumflex put +dup 235/edieresis put +dup 236/igrave put +dup 237/iacute put +dup 238/icircumflex put +dup 239/idieresis put +dup 240/eth put +dup 241/ntilde put +dup 242/ograve put +dup 243/oacute put +dup 244/ocircumflex put +dup 245/otilde put +dup 246/odieresis put +dup 247/divide put +dup 248/oslash put +dup 249/ugrave put +dup 250/uacute put +dup 251/ucircumflex put +dup 252/udieresis put +dup 253/yacute put +dup 254/thorn put +dup 255/ydieresis put +readonly def +currentdict end +currentfile eexec +11167FB533773667FB8D3EFE82119D83C5E325D3F9FA9CD7D01B1F3F3E52876279E4660D +B5D444F0B7CE226ED8DF687C9F94FD3D6282F90864241946A4B8E8575E48452B9C0794B0 +E485E0EE753D96B6C08DFAE68281203752A25CAF8EADA400FDB4F9AC57F07D7C3CED86D6 +7F5FCFCD9D4635282E9D92A5D9598F79FCB9FB1A677408CF7EDE532374FF6A6A9703662D +17B5D4F6CD9CF249432F8C76D70BD990DDA5FEBDB59A17FC8A068E1DCF23729F4CCF2C91 +59376F20EBE27AC7473D31BBE76EA67D9AC99ED58644032A828859BD9DDE391FC993707F +97CABF55422D4C37042F25E17BB78E63EABE7783BE0C56F59E74EFBE7783B90310E817D7 +A01D0AC31EA0C9B67EA7A3EAC553F3DCD76270BAFB428DC7AB7EE802E06EC54B705A5A6F +125250A008FA7375643EDFF171457F65345A08795AE0F1E5FAC5A9CCD3E258A9CF83382F +B3385DA7FEEB19F6D001A7B5A214115B01B441014E51A9BF8057017663645BCE7E2C6228 +940658CCE20121AE23DB19754C876CF1E7ABB40B2C949C0D45AEDCEF0165C46A0E720BD4 +6260D7AB7E8B5A77F64542DB42BB3C48EF0F9D026C8563478B4B80B60DE0005A3C61B5BE +DEF534F95EC79CDBCE5AE2CABEAE6289BE6D998B2E0B090DC31F890A264618C9E9473962 +3BCC88789A953C3C9BD07F5B1D7A1621B71A12FE379E85E6562D62C449F1EF7B467D126A +41D13410BF85D7735CB440A7363A7C9755F3BAA6554FDBF71FFBC2B9EC7EF2BCF0228D5A +98361A9F79AC87EB346D5AC82847C2FF02AAEAAB6C8272350A534C5BCBD678B28C6F7B97 +44BF3243F970909CBBE5E4116F2A1F56EF992D3EE51889C80FA54C5C9982BFD90C1ED83B +3D7A917C2588207D5A15D4316C408332591A8845B322124D17D41E10FABF2662439FC0FA +92B839F0A6AE2065D029FE012F75D7B4B0947202894211CD4786A74385DC0817DDC3A2FF +8EFD3EE4CE9F31AA40282C2A0E88D02ED77F991C910D3CC20F1A6C513E105A65117D6FF8 +B448255F66674BD2CD7B66EEA96CEE551D97B27E7B0BB692664DB358985F0DCB1E5FA9D7 +F92799971280852C5DB56F5E0788208521AB6B2589034B48624D393F005525342C7441E2 +67D1BD07BBF43C69DC7BEC5A47993AFF6F6A9747787AB8FF45BCDBE88FCF290DD28FB3D4 +2FB726AECC1832A03E970FEC71D7CA532B45C8C5BF64CEA9F6F9483D369EC9FC0D82E3C7 +A5863D816D35503EBDC1CE27C57258E0D773318E88B9006AA04541D8F14B4F23F7B3D23F +6B4E990457C5525DCA3B63EE75C3A53611FA30AEB04A33EAC156049E60651AE830726330 +C3530A1BE5F3CA8AB63BAD85DA0080A22FA54A6DE4AD3EE96BB9EC60D3EC4AEA7B5FC82F +8EC803B2C6198E5ABF9B67A82B24D8F5C672E6A825FE0481B1744DBC008B0B1110761F23 +ACF02284979F836FAC0BAA9216C35A5AB25B95197F282592E27C9FBD8D5EFB330B08A956 +B6079D05D4500F00518B164CECA074491CEFF09A99055371AD3D0A9F1DD2EF38B33A0FBF +6C83E4AB7584D24400671CD568DE38F6DAB1660578C65AFC0FB5AE268AB26D47F38CB9C7 +E48BD5A7D4F62199EF7180D923958A41F3FDCDB0A856375B3BBAF2C4C32752FB0B641240 +E50FD465CB53BEF09BB0D73D204B2064B3B6322A1D227E8D7B4FAB71BBD3E2FFC59712B1 +EEC12CFEAEAA8135895D705C6BD8DC5726A21888E25B675475D53431DE441B7177F41A30 +A216DC48B78D025AF5CFC53ECCF08C494EDDB4D460CADF0E325C81B932F4BE839E5B6F3A +3AF49B330AB3DD8637D9D0BD305C15D20FB84B14725D4269A78D316B2C2401698B125DEC +EFC2D7DC0206C6535846C435E5DDCD2294C5ECA8FE4C3342D032CDEC2398A43971E15CDC +CC308BA14659D338D478ED2C91DFEE282D221AF7150507F3F35054CBA77F7B68B102C7A3 +B0A94AAC5EB7ACC45F29A2B23A8BA397727E1533E78F84870A647D8D2F364F0A9D9CFB1A +F82AA4A2FA9D4A33E2F508BE63488D4505E4BF2B22029A24EBF8ED5BA75646FBA0B80D8E +B076A4028B10A89BA8735E03092071307C212B76BBAB410DD4783C8653F472A853105F4A +0900CD58BDAD0DE8967A8084D49E03CAE74D6724924E2D85411B0E712ED4410F59793490 +429E6271123A4A3B45BE180248BE5F2BF16BFECE9B005C9AF12523C38E6DEBAA9F1BF6D4 +AC2B193FEF981CD5E4ED3573521A82DDBDDBD61F43EFE8CF474FFE43D82DA07FD8A1A494 +6E8C187FC6C85663A05E65BE968841C923CC2AEDC5193F624FE2FA5B4F33232BC9361141 +60C54189960EDF10F1B44C91417CA26FB66E4A89B19AC2280C59CB7C3428A0251E34B5AB +90368B31EDDFAA2BA749EFBDB7C99EFB9C5E67E9C6C62438E73DEA816919881E804E3D8A +EF1D5108C4895E2E285618AD7DC3A42F1E28378335D46ECAD9B3058B165257BDDCEFD817 +350ED1B3E3ADF86C3BA4E9624C2E592A8216F4B2700BC88992913406E7DB2B5F5DF3174E +A6D7639B616AE160282DCFDC85CAE0C73F3E695B09EE0FF5752321EA51A914A7C89FD9FA +0E66B2F01EC9033EE9DBD246725CB36EEBD34EB3481FC21C4AD3AD26B394E858E3F4C3B9 +4CCF83497813A5CAA32C5FE41787FD97734992458BDDEA1A9CE2D7135A65B592B73FE851 +C2671A257B5518E2C008553432C6FA79BCA95000F31BF7F0AD101A30607D1D34987D89B0 +F3E1A190231908C2451B8FB0D18EC8F873AB09F1419D48B041A02BC4F819FA17E81C3289 +77EF1BCA4E86CDE766B795EC8A1B299F57DBB4C72660533C8A96AE701F9EFBF198FE4D5D +C66C3EAAB293D0D9D908236037C83A759F2156AAEA78B6AE37DF0AA85A5F89215171FC75 +3A323D43A3295A2462D8902458F15F6345815BECCD373E3EF4F0993F7D52AAD4E2030CB7 +2862D8FA6E6138B71ACC7D62E7261FBD56148C8DE661AE9844FE920ACC2503E278DF0B04 +F669145B9C8D435BD90C3DBA004C09B39227A5409965E6ED90E5082B923D69B0842FDB38 +0D742890F9A9FE4BB8F923FFED2581277AD8FB61E2F17BB90D1A7E4195D7EB3FF833FE3B +72E696C3DAE0A3A49918540BF1C6046FFF094E01680EA558415209926FBD70B3CB4B044F +DC5FC844150C311F9C1C031F4D5B99DEE4F72F2307B8EFF74735B1ED593465D0D7998E61 +DA4D497AF119FC332156B8D882B4005FC8850E4DA96B7AE93E1552AEDE068D0E2B266C45 +0753CD2DA48A059CEE49F1E86E2F77F701FB177FA32D5F93FE4D6A01275EEB54692AA6C8 +95EE530E862079535A543DE4067CD630A7D8CC83AB9E04377B8D3A05F23280A6E1D68356 +C76D531990EB15EA707C0E5BB5055F428997E2A731A4F7B5288E54B2C4B949833EC117F3 +0A0575603796041BE985C63F48CD55E76638E7E54BBCCC9D2C73ABE423C6A7159CCBF80C +8FD931FACC6D8257D9202645B3138E367E160CA3CF22E1C5ACE59AFC77BFDFC25A5D6DDF +E6C2F6B68D062D0490D05B05B55A7A0C6E56A52A2EADC106E3BB6410205CED012BB49DC3 +6EC89674C22C7D17E3A6AD10A2812095454DA4D44414F42A8678BEB35D372D3851EBC535 +888D9E937906CC0475986D2656E16D78B391E8E8D3E9C91D980D526C6470E79B728ACB9C +B9F63C6000B9E60AD76959F7B14F06B631778911EA9DB59D8B9BE7DECC68DEEF068032B9 +272227B91840B30B7506A3FD57306015EF686A174F48B734D9070498D2184773E7353A24 +51D3276238B8874FDEB7161D1A8506BEF79EC5245651C29B9251EE17F834D200E2219A3A +9CD838C9BB31182C00A52E06DA6EA4E446FCFB62C92284116E14C3D38973F1704D5EB2E7 +6E6F88F7444364046AB43C4D7D44A23FA47B5EA158949A3E1F15DE70F40812444C6F0F4D +A9940F2B3CD1B7B1450C1BFE7A6E111503CFA45FF012A6DED44CBA623FCEAF5262BBF810 +90A4FC1EE72D5EF3852987026F50770F7410E486F1D15D25888C8D88188647F8776CFBB0 +C7D4F02644BD13C84C592DCE82A56F08920B2FB13BAFB405154895458F55DEECAB846104 +7B157C02450E0E529A10559BD8CD9592FFBC923092C1EB0AAE96E5CE64A6D5B636988F69 +EF02E3F5B84451BA2F6CC360B647908FA940E844C3DAE8FAF73E9ED416D6B8A20660EAF0 +2C662828F3E137B0956B15AA9C129A312E753202D429FC734325F1F82A3D9058ADB87688 +4B979CAEFF660A8EF9191F4E0D2CCAE5E5458139A0AD0637319FF41CD7DE9877AB094F4A +3F27EC8F5C7D42B1D892B829E1DBBFA9295B8383B23658ED25DA227B9F625B89E26C854C +0130CEB1F82D24E53D5FCCE082433A4029B1B4A5905D25BA809EEA54895220DCAED1B2AE +879E7BEE3CFA3C71FFBC77AEF4A415C96F2CE40EF47E2080FB59AB00DB4E8D527D9E41D3 +8DE95CBE66EAC589F5831C4BF0BBE1455F4960FE388B84074DA43DF499BE3810C38A4BA1 +D23F3A6C331F09135931FF0A7D77160E3FC9CBF4937D5814A12848C17ED3F62FEE21B11E +43889F3947F67F66BE8DE7EFA954E2CF8BFFAA33DEE3F3C397FC572DDFD7E42578DC39AB +7CACDE5A30E25CB6D949E2C89B02E48F70CA2D0FBA47F19B72CCF99B4C71C69B1E1A381E +F620B2BF283FD34CE116F5C2DD1BB9DAF60BD431A6CD475ADA9F7490E17D5DB183763467 +0C167B8E958A4C476820EB53A778B9131FC7205BCA2EE3791B8FB54AB6996B82B65B8E60 +71529E0E3A721E6306EE6448EC9607C427F543EB8C6717D0BF598F619D36A3FD7C0E3DBB +E7B5D923DC8EF2BD288C55EF93640E4249E0E9E36E1FCC19CEC8619495B71D84236313E8 +C552ED0F230DBEE3C395269DE393EB34F630A5043B054154A47EE48BCFA1B3DF9D142315 +F1826809F0BADC495B2C7DC93D34155D843427BCF872288B49D2A0AB22AF861112C324F3 +4428FD31584D3B5E88ADD1EDD809DA66F90C756386198CA263562A95BAAA64B1CA36897C +1069CDE2D44EE87FC186A24C10C23B8F3DE59B41D1AD8E01EDF4C32EE70F053DAB84D24D +33A6024D7A86570D96B34892F8E299414E7084D99B3C3A89531A7861A39EAEAD9506B0C7 +017E3A730C91AF6857DECFCE2FFF482DB160369A16BD17456EB74258D2D39F7177998A85 +6694D74A57318BBE392EBBCD069FCC8EFB71AC1516E350FE4F936BECB2A8DC4280BF3A64 +27F1B741C4FD53AFB32EB78D9C06D74B5F71DD967E087F733D50655900E086D358B46C2E +8EA8CB494C0EBBCA4B0A9C74B48E0236F9CA651D73D2DB6FB1F1F6F7561194C8858F3FF4 +B3F46FED001DC472F71BD6E16EC1516605779FBC1FF81D6ED6996F955C001DB98BC8E7EF +16065AE3A00E7C65B4F080F78C5E0CBC9EF8D4E6A8A3E76258B31BD4F6766A4B00A37AA3 +E5BEC4C495D5B92E701B7423FF09FE895CA54F82D584942A93ADA1C7AC5576345DB685AC +6E04586E55C997FD31D13FAD4D2FEC0181A8A0BAD0CE863F9052735AE3F245F549B8F2C1 +A5486F65BC217A57D404832AE633EEEDE8806889AEACC54237FC2C493CABE98111D34EDA +6739E5CA8FA33EBD70757FDC1243E9F1D58D69796A7BE700CB9A39F69ED0D811D4D286D0 +80BCA0D9E78E54B63E640C53BD479106062953EDCD604D10F3FF50620AB8D1B79F1F873E +E47512F37296FA930C5FCECC28FC6025270DF4B2CBC428ABB88BA940AD55CCA0EBFDDF91 +3AE3271FBFA6DEE0B62D6B94F40053A11410D91A1CA9DB0E9947AB24EC592A9FF3F00FCE +F1C436A94332952DFD7825CFE35489E12C6A8A7521AA5B32B307A7BE5200E45E1FDC5588 +96F0A32E97E31CF40BBA08833E7D7EF78DDD5D48685B19943705D87E40C235C0EDCDC6E5 +93AEEB193C8957E5A05E17F4609FB3626BD14CB597362AA65699A50DF076A54FB1012403 +E32A3CD7761DFF0B3F41AAC0BD55C1148A24BBF31B4CA15608F12DA8F671D76E33E00AAE +450412798B7BF74C216E112883E9920B0EDD24701790AEB565D9BF4927BD3856493D6B56 +2C5A231DEFF338A986DEE08AE42A6FB978608C3B9A4A1D8E17164A08E2FDB5D1E1D38AA5 +5E2E4B4D2F5C0317ECE305DCBB207D7599943B1116A0AF9B917E1EE7FEDD285F249B212E +AA66724290030E1220C5E26EE5623636FB5897E0CE1E0DA00B8E716A963B4A9498E113A2 +C6E68B6D35503EFB27C4D82FE3B48A7005560DF04BC6AAA01EAA47070C81D60C40614920 +12654837A5317AF1D7F24404E050CDB6C3D1B1BA2480FC9940707A9984D507A3C078365D +30662300B4E28756F69F8B65F9212B4A0FE63448CAAB6331DA9E7DA65347370F03E51135 +591456D774040BDA4BF0D318161C082F69ED644E51EFE26EFC45CFA0391220B09BE1157C +3E4B55CF5203F2AFA61D7C0F6F281460A761987144ACA50A2834954890D9BC811B72D0D5 +FBE77F8D01496257522EC90143BDCBBC30EB08B9D15097E0AA0AC15F6F7FEEE91224BC4F +531A65905AE9337D97652775BD7C43740E29EB66AEDF91D658C2A2F9849A26457C8866F6 +F96D59E6721018ED0637D6126F08EF685174F130D9735CA45227B508B52FB7D9BCCA10D3 +BF16A889EEA13847DA7CAB63C73C0F068C3BBEA8E162295F884B7E28BA144E30450A823B +9025847C739B6EEAD71967F8DBCA0AC8FBBC2A7847BD7B957B8E44EC96CA2888B47F86DA +786EFEB0C741D7CB67CC25371E59148D4C3ED2C5349A1EBE6B9DC8744EBBA600856B22F5 +1832C41955FF582F4E0337809EEFC33FCDBF9C31723278A8D085F1404D16A573314F2876 +85C67FC651E691B1C12121B0E209E3E7A0FAC4272D58F16863202CC7594D0A6B10A4948B +1FEE719857ECEA0CFF0D0643154CE968A7E909A6CF9A9672B2159717E854044AA6A13F05 +A3581A47D624126498DF26635EA643734E2DD2A2EFF5D2F70BCDE6F39C9D54F0A1DC05D7 +8BE1C28495B0064C2A18A02859FD8B1F91DB7D29BBBE7401B1891CAEB5BE54468DBE8B76 +74C2257466643C14A9657C1E79627D8743C14B4CD25C03AE56AB0D1D5EF596474C7881FC +0706543A538D2017E48205664D7443834DE0344BB76CCBFB64824E753FEE37F39581FD32 +27AF8959D869EA87D806668DC29436C60A8C9DCE55349B7C992F821C28A28482843577A1 +44C905FED079A06273C7960BADCB5196F3C9E2DCC87C0B1E03C5B5CC64AFD58CC72DA649 +040DEBDA7ACDA5BE6DEB142FADDFD883DC4F004B7B7FC5A1A8A44AA9C4A6B3CC034D4F92 +CB6293FE7A3EAAADE9568655CC3CF1EF283B1ECD15EDA0A2E3CADE0C3148A5E449CD5D92 +557FC15E2A3B99F6CAB2DE4E3DDD038184E46F1914481C7E5B5A1862C899AAFC1A4965F0 +5C152968522019B3D635C2A67DA80CA60F264E6F75F419ACE6F48F32C5B6FEA7E340DB0C +5C25F7FA380B1A7D7F4534F0ADB02EA93B4901B581A9EE79D3710248F0A5E03BABC2A066 +5583642E51E78893B375950891A694ED7C18B2CE872619ABE151DC8710F5395E79E5FB02 +5F05A3BD9364756A54FB8B31C81C2285942F9FA6940BF3D676C16FBCCF34A433028A9A0B +18A39831E0F04F03D7A4465DAB80894AD108CCFD1F004013B9D619E0EB552DAA5BFE0EA5 +53FCC2D38EA0FAA38BC25AA6E954A2ABE35AEC8383E556D1067F2A8F4FEAF745DF55771A +95502B33A40807C7692BDA00A142A4EB394838F57880B4ADE4D21DA150CB60752D5A11E0 +A309F50D63AF0C59DB2D58EA0C827441997566E8AC0F39C354CE94175BBC62A265FCA7A1 +87B3BE75E83EC96FFFA43F6675D9374771E2AAB0FB1A14E9843F864852CDB0E23D30F1E2 +EF19FBBB4501D41F4878208E041A8B5C0A46B3352A2CD1F5BE78B3C89B58DE076CC603BF +04163F64660236214F9B029CBE96F0F4DE40C8919EE1FB5435FBDB25083FB3EBD505B0AB +CCDAE8CF4AEC0DA7D890621D68D0056FBCA5832892EBE9E2BB72A2BCBD224F1D3E8E7AB4 +771CAD9C6A4A0E40A6BFE15313E15EDED08DB8941E04094149B69FAAD438E8C7047C8A41 +ED0B10070C48F804C11FE88BCF655BA3636A4C7426584812DF512535225E8499D867F83C +86BD170854BE047A028889695FEE4E7FC63DBD109AE00664414FC96496F85DC4BB719BE6 +B7C5BC4D7289028A003CBDF447018981D0A8E11656A4D75D6F5145C5DE04CFD6234551DD +F89930E9267D1080FAE4F9C66B1BC736C7375B902FA53D9E8BCF2B5A7BC4B6341CD65F79 +9673CF52F26D649882A3A2EB1609DBF2D4A4F02DA65BB417EEEE635485BAD51E96EFD4A6 +BDF0861B1922D31BAE22AEBB9DF54E2C5ABA5B97ECCB069903B2AA28D790560A64E3B93C +E0D3FDC457944A22A390C874D655AEA7BEA5B305B1BCA2F13DC73F1E8DC7662E20FC276F +1D29E9D96E8EEF0E3B2B0FAEEF541CCAEBAF485019979872A72A8ABCF89071E28DF389D6 +8418B9EE2488F611AC58EBBC150F3E93AE1B3A1C5426EFC55B22E5A7D1DABF78E4C6D196 +757CA1120B657ACDD4EBD7276EBD4A67A7440B46FA59C59E2E6681FC2BBA58FC8A82804C +F8C4AC4032B09681B6CCA415C532B91CDF0B0400AA088C9044C3895F3BF46C611BA136EB +AF72086A9D2BC385201BBD78DF875CD8F7D67C0D4F26D3D9C6345C55FDCE9B26BAEA3963 +A7DB21622C3B3B3DD82DFC66FE74937EE3728FB20328B047463856F9BD4E1B1F0D088A3F +19408DF937A84D543A5BB17445979A37399586A368E99FC2542D8F401D0BF360CA619854 +EDD0BE31318865A20F221772253518E9E09BE9DF95901147411D4C0879D26D8F930E4B30 +3FFEBD5FBB076BD9BC5B0A4C99F0B85800F25994108428F98697DA6E7C14F1780BDECC94 +16B682AF9E92A7AA7DD0B33EB695DFF884D14BFED98D3D9F84E36ED4FB2DD86F1A42D8B4 +A2EAF46CA449E0ADD9BA067F2DE96897318BDB05A560BED7588999185585F81C9BAA0AA0 +9449C1BE1F14AA0C729E6B66622D18B8D5340B74BCD66B967E6F29365A5745012C881F6E +CB10CB82B46B7AC551B5ED79C41709AB70B4AB493C4BC6DA1CAE87011B5961A5FF4B0ACB +17A95F29D49FDE6830C3B2D170968738A8815149B242B4884161186079DD6A1217FE9CE7 +E60E7045A21B10138832AE5C880FD54FEC7B71974DC8704DEB006E01EF9F61F7FC22A117 +123D5A2EA6AC39CDFC6BBB6380404B8F98CCD1E4FF7CBBCACC4AA13F260C081D9AF5108E +518516A2C58B27CDF940B960FDD3D51AF3FA1BEAA90687FE8BD145E9984AD71187BE737B +6765F385FC7A58FA771C84759CA27F908038C2B7BDF81DDB6797A3EB4EB6E8ADD3FB9FF4 +E92692577747890EC0CF77796BCC291929FB27FA69F10AC7912D9A7E6FB84DE14D9D6D12 +115A8630F8CD3F26A86F291714B931D3822B8A07E9276659D5F36EFE72858A444557FE0A +3BDC70E9D52F941E790EE7B7454557B792002BB07AC33F10F2CD2E5E16E88018F6F79D54 +34E408572D30A3316C3F1BD36E1BA16A49C3623317C62ACCCFD869EA76921D729E70F2F4 +63FA8F0035EEDE8EAB1E7BEE4C389DF3BF6625DF10CBF19701381B68525BFE96C2CD919C +2922EE99525048392C1BCF26B3141B551E9DFE25A2D0E84348BC032C28ED8A118DB6A083 +B1AC44A0EC9184D101FCC6A9CC4F5F9756783376BCB2DC289982795796454835FDF5F325 +DB4DFE924D2C02458FEDED43FE8DAE2EC4BB61536CF755E7E920835455CCE84B5C0C791B +9CB6D494445F304B173628D8057F45E9860DC8DE045E351750C0E71B2B13F78AE4941AA2 +F3E2E8E05125DFE290AF817D87693AAB16345CF0CF6CBFF594371E9815A5F3360CD52D8F +095AE10808F33F86E07E4B8A2BB3486F93D04C88FCACC7907E359442D0CAFCC088657360 +6C54F56DDC5039A88396731AFC577DC3324A0D24AA9348245F660A496410E3286B81D6F8 +7999933D898C0FF0D3FCBA5F9D5CF3326B863E941236E31FEF86B7DEF1014D1C6CF86B92 +4FEBF9FDEBD3709805485B618DAD03D15B5C401B94B2F4500F2FBE72CFEC2A69164D6185 +DF5160441DF72FC509EB7C1C1322AA5658B09E1BCE9BC99763E7DE13057E836E57D24460 +DEFEA1CE7C2553BBE5F5CDCA7869B7153A0C5349A7D0B546F971FC63864BA7F00BFE51E3 +905A87F67398D568709D27E5A746970F72EF9C71ABE7CE96044ECF80352F712B605A6B10 +8426A06A27E13FD837C520096D15F9B1A44E6F955E3FACD91B643BF0EE74D3FD6E9A10CD +F05C01FBC7BEA26D8AE8565CB89BB2E52EC98A4F4898D146084CDF4E6509462D267CE81D +D7A0E6E2EFEAFA1BBF696803FD40F021716C2838C19D32F741FA334D228E2BD34DA2D561 +E6609CD823CE02EBB683A6F1EECD93C9103E5328143EFF6C9E05956969D2F25AC992FC76 +39B5C238FA4A3157B959B4AF11B6AA05823C015134836A6560EA7F07EC86117511E13B10 +75D0D2259D36E7B8065D930184C7DDB1AC2B42A566FEEA6927313BE91C7EAADA352D9E76 +43D467F94AD5ECAE37BC145278B4048AFDF432B2E2F219661CEE53E159490F1E0FB04DF6 +D42F4B322AC01E5732859AEC445D6E120091996DCE46602EFA8C01EB0E1D8BB6D0D12174 +E4990498577B86CCEF0EF5F7EE913A3A8D78EF9CE4F37B0BE1B5F40A4D0B00EADBD92C7A +5083E8D4B093D7BDA5B88E08D5DA4EBF7FBDEA06DFB8C5161A92548160163EB7AA97B603 +96D869524163EE546E1E35F764A4879D2DF056A5E77438D45D81F9356A4F8EA0D007E0B5 +DD2441879A48AEEDCB1A2F493C3E648EA138D4DC080022EC7A62E08373CF032F48C2F585 +0589F04122726500E8B29216CCCF6ABC2A04A726224F9B029A25DE8C5965A6ED3F6E3518 +B72C6A0A64802424E91DDBA855C20EC358F6FBD79C30CC6DA41C9C117B23139C150DDB33 +7FC090A907DCB0FA4DCF914E3CB53EDCF7DFB6D2A200F7C2E8401667D828605C64D9A62C +7360AECC44BC3951D2ABD75976528B0B98913A2741D0E160B48FC0458FF56DDAF4FCF5B0 +6A351BE0A90F851C44BEC636C0AC688226C8B0FD136F2B612BB66ACBA8FF149783F24B99 +A0FFBD405F655FE2DC577E01953716C44965782D86658859FA313876424484951448ED6C +E43106D4F8FAD95C3163A1AD47AB14DAEE015A257735B0B14BA8C1F807B54E54670BFB7E +9311D936086C6DDADE803F4E304B6E823A937E1A92C28C5A61D0FA1DA992DEF383ADC936 +E910075C9573B15ED356345ADF2EABFBBF8CB6D1D35DB404CB70DF440642562D8778E5E3 +1C547AA1DD408A97F44048AFF9317364BB3A8D35503CA5F0FA509CD0A20DE629DD243EDC +163402620ABBCC4E9D7E679A92E7FBC45CCD3923AEC1C20C8F15647B0E661F82C738FC61 +FB3C954B9097633B78D21C958491977377BA0FB845FA5357F3519572002CA6A88FCC39BD +CB51A2F2BA462905906DC5A76632708E41585A47368D650954826C722853A1B9364D3F21 +0A844A8AB86EF33C8176B76E891F2AEE7C1DD8C6B0A2B52CE2AB398533B6D862593D30BC +2BC3046C588E63E2C02F17A5336D7B03B8CDEE76F5B8A8AB32F431F9FD1FD85013779781 +274597F8B717CFA22066ED723769550D604ACA4772C711C672FA57A9A30E962E9ABBA798 +AC43517D02EC267E25CA09B5FF087C0498660A975A7BC1F726B9B0362E786A5E6DA97B9C +83C8B7BE172423C79CD95A2DAD481CAEF11924E4357833DF7692C22ECE4A7C92B6C84B8D +4E1332A9AC1C897DF2777C9A3C8AA4B77574A5BC296BD2BB4DB715609DEB685CE804B710 +D098CF51391D799C2F59017002C2F2018970BC614F4A4A246A49E795FC2627A5361A474C +4EEA15FD114C5E067D2F091A25E56A019A2DC6E00F9A3CEAE73F68C7387A2BA310AF9980 +8709635A5A2AFA101FBC0FF8AF9D7F7CC1E44FD2344BE0ED353D24E8624D464938BC13D4 +078B481D9B32937D75B52CFEDAC13FEA859123B76C50856986F05DAFA7AB1885ED53E88F +57CB20D166DA5B3723AF472A0C3BA1325015BE2097BA520E15E0CCE3FC8D3AEC37F3DED1 +671FDE5EF193849D5141B9956A68DC514D6A9FCD67AF25D8751AA32D114A58728CDF973B +05464EA3CA55ACBDBC0C2CE814CF10E8639273C33DAA263C217A8C6F1A8EB1BACCB6C7FF +E50DFE35E2919D0CDD7C099FE7313B8D610C90034EEF74908906ACE8631A193C5C6341DE +6A311DAC36AC2E9FA441E985249302F9273EFEA3FD5AC02111A0B697CBE2FF96B245D2B7 +0847404C184BFE1E3C883E66D90EA64C797597CDE06554DE22537638509E69D9E18030F9 +E2ACC66700F2429D8C5787837421EEB83B023FF531F48B40EBD3E58A13A0FDFB227C2A28 +C9A81C16A7554BD0831F68AEEC7A1E834BE1F90CC96D7E6C5B06A5EE89B231C183E2BAC8 +4840BE8EE0CD47E46517F6C46F27B3691E5D271781E612602AA935061867860C660E6BBE +E57583687BE3C61186D98BCF7EBC3A3AFB9B88C7C466DFA58BA37840A537F1206C522FA5 +DCD1C129B51AA8EBEA4F5883B7D1EAD667B178B56FE7D831DAF15C631F52197F7E92B34E +DD68CFC92859C49922404F21F4BBBE4643501E39AF897D93EC8B89FCAB6BB8912F42E805 +532691D4BBA96077BB351BB9070DC2D5C17D60374AA9C8CC6B6ACF929B77E252F71A6F61 +74FE8058A8DF23CFF45A046CF30031D87FBE2D408BDB0C9939FBF6F16CCA38D97AB8B19D +7278EF78814FA670EC235651A4703B229B50BA6B3EAEC8A22F41AF0CD01984238C34C2A7 +9E18A8E493F64F74EA3638FC4EF88B7D788648B4A2ABF02432988F9A3C871FCE7C59B339 +4E00539AB825DFDA2C420E378D1A20CD0FB6F060349ACBE266DB820841088A9FF50C2686 +F90561D8248881869D04A809E738761CD091B084610BA958A39CA3F19CBE38437DF0FE69 +D23264E56B4760044F11EC435631D06C6C7934427BAF1015C9BA4E370CFD16F1E892AC3D +7932504A52DC9D9576CDCE2C37AB393A55180156F6F583B753E117E42F6BA85A64155118 +2FE36FC5D5C4C80F88F8825E88CA9F5CEBA97FD8ACBFA3C87FC906F443361B71F6B2D875 +DEBFADDC1CF3EA8A7D099C30A4207CDCB3901C13FA35DA02FB95DD0E6EB587D46D739A27 +B2A325237F8D33B1413618E8FAF1C9C146581EA841E8B85174D1787BEBEE6E409FD6B64B +3B066F62CA10009B10FF02A9D708203C02EC1F3309653B617F053754EE9863EB202D7ED6 +F5E47D80B48D99040CD17B44646694D8BB68F39FD6EE4ED77606D35B4B668A16608AF657 +FEB98F826C291B26325B6EB8587CC3EDFF18FDC96C56241ED36A6115BAB6579D5CFEE016 +75D3E4F23ECEDE16AB09586B9F5A56511EAFE9BD38D5B36B0CA45F1992475C129798465D +0B7E94BE9B308E87794522507AC3AF7B29C91AE0C6ABEAB8989289F238509063C3E74CB9 +393F2934A5FA0EB173E2982F412875AB7F1ACBEBCFCEF7647203869322300D4C110D30EC +C61E846AD1FE42361F357830D5D6DE7DBCDA6154F8C5B6591EA2580F34C2C5422150BCC6 +E8076F510E571BF3633255677A1971CB0624BB1A6DE11FBE9CD1260FE400240C4C5CC59B +A1EC6CEE2E054995D33FB5ADC781D78A371A9116CD8F9DC09CFF2F3542BC1DC1B4E61D3A +7310C9674DC24DEC68073F4A979FFF96DAC759988735089B043BFCFDA203DA4F99D8E719 +1FDFDD18F3B53895F7AD46093B8A9D55CFD2E527A50F46DF23E0288FB8F61E2254DE6933 +DB7E78462CF03E7E454F6774415D3DF25926B9C7E48AE576B05FE164CDBFD3AF56FF9A94 +D0C08EB26C4514140BA55B503A52D98CEC90C721AC3D2E280288D0F73C2A5ACE87AD9798 +E15AED95526210EC6428D10C1422482799D1BF69DD623B1B16DE95592FCB6366B5E91C1A +3E03F6D086258AE19576E5E66F9E6A8C029E26FB7471ACE648E9A9FC74251ABF854772EE +B42D96D9C87EEB12785547AB30CFB71FE683C621CBE389225C1F0DD6CC7C24FB9E5AA117 +A4A9C83A78776C0198745A21B6E154A9D560BBA0D419092CF341F1606686D396C9F417CA +DBFAB2D360D2035196C85A204AC2F0F3B3EB17BD337E6E9D57BB414613A636E22E944FB2 +556D9046E9CCCFE0B82BF68E0148B17CABC0A926DF4885D2572D53435CF8CA462BBD9A53 +AE3673D6C6A7BB9E857B9E01CD95F2336EC1DB562088E8C2B4C6DA9F8E7F6506A6E69D06 +82785BEAFEE2B57C1BE191673F51C6E2DB711667E34518363119A27D7D3618AC791B920A +E66FDFEE50BFF094E587DF23A4C100EEA75AB4E1B3384F99966543D48A3FCAACFC76E5C2 +00DE81A2DF1C7D7E4FE1D8FF59FE187C6271A80B42C9CC854096BD3FCE15048E7AB421A0 +89C15E9574D535142E877C1D72BC5A1173D157A1B61768CD39FB88D574A1BC3C67BBFDE7 +02EE677084111B8ED795273745892D9260CED632285E633DE80F3DE62FBF73350D71D72B +84F5A18D3BD43386D05642FDF1FAB29CA63B82E1969679FAA6283160946E0E3C7B3519A3 +5D791580141D2F980023C39C122C2D102E4243502B517678C7A4E522753F91F4EAF73C75 +C644080E3509EDB077EE84E1DAFC06B25101FDF01F1FDEF68C326A6F67253E18A0336EFB +2375FA4F70A077A2D09471AFD31FF4DB23B1FFEFE8A0CE644E864BE68E05EE75192D65DE +9D14F9A385AA2B9C4E5BE385FF1E2C8C9ED1C9CF4D48AAE769AE7FD807280FE96EA290B7 +8DC5A9F78F89CE562183C8D8DF90E6AF14B20C0431617FBF64BA977EB5DC3BD63BF0B81C +AD3D586409EBB6211CCFC8CF02A74A30CB9B3D2BFA8F954E3F9590A664B16E4E3EE7092C +DE1D42C778AD283AA66B630DCD68C968B393C23CE8D76AA2A9B911AD24D3C73C02B2763A +088ED7A1CF3B4BD07C9A0DFF7B642708B13B8E9C32923FBF1531AFA279E162804C301BC2 +F69F4E24A05BC2D93BB622B5528D2263FEF2C8A4CC1D6F01C282FEF8A188484450FB1359 +DAE4530DDA82A2B5359165BEDF8FF28880034D8EAC5E7C03A8FDD59EEB8E2564B3889509 +27EDFD59C2CA931F4058C6406DB402B71CDD3EC21F2533903830DC407F814B86ED983E29 +991A94AF27C008B2B448972C6CB7FBC5C30D577774624318C371737D090F67F6C36FC195 +F7E2DB836CEE170DE9ABDB2D99FA06E340CB144F8E65A29F13DDB34D2D462B38C7CB6695 +09D77000F9044C659B941CDDE2CDD35D12D6FE94B502CE6C67824A695D42828E2D111AE0 +752383F579A86B38BFD3F173D34FD9937F11027F44748A8903342287B85AFB49BFE24240 +0049F4683217BD8974D21EF4E373EBE69221DE4FC036AD9CDE8D1986D16260F361255CDD +6357354CCC036EF8248802C5A9DD6BE470FD647A913409EB0AF9B629050604C166A70835 +3B78E1A2A179B3161553FDD55B036867914EFB8A9436F668860770DC512D8779E53883D4 +DCF5913BE9C0AA9D002788725BDDF0B5FDD0B3E49A4DB4F79E9D28FB4872CDE8999A0E62 +A6A7934A80F1DE7B84672A65513F4B1B845437DBA6DD1DF9ABF70DD356DE74C924213528 +F24124F153637EB9ECFE91AA71DB9A92C19B376F7E409F81BE121349E2D5173B821F018C +A19039FBD57F6F7012D5E4684D149E92FD9E1EA48F3037B162560E3F29C6AA8100C0A633 +D685733DBB08D30DE48A53E28A3D4776B715355EA7E690664BD3F1F77AED2343A05F748E +DB986519D8E92CB843BC8C62EB5F46E73D734D079464EBBC97693FB5A95FC3CD7EAD4A42 +AE6090F18938D286AAF8D0AD64C77E46822EEAFBB655A0995110AEA8C61C4F198EEB8E8C +CD40D1A4317508E96EF47F6C9F4E6D37D81F8296BEACA5FF63732C8FFB8798545E86539D +6FA3EFB324A89107534E638B54059790DAAF10234064B5C51B1B233F977777FFCF18AEEA +AC8E9691C9C4E5652B68D4BF4D262565AA53E2E639FA7DE00A6E8E81075DAE11D09DC355 +2DF890E2F4FB7BF42D94BEDD9FF9E708765DBB5E2D86984BB5E9FD3AA69529A7B4A547A1 +3E7DD7AF3DB740A8076FB06D05EDFE10D4F77467D4950E515CCA452D9FD9FB023B7F7AD7 +188060BC823B479ABE20DCA872E7028AB0F44C36DB113876703856A5C632AB2D5F6543D8 +98C9FC6EAD7609E3002A348619733FFB0C715F55842ECA2FA2A1B89DB93A3BA102504DC3 +BE1F54AAC59EC23E6EA3223912EAFC711DA3210451BB58AA7AB7F14B1621C61D9875C97F +D4DEF3435C6C8BF9BA8574E2D2CC43EA26E34C774953AA0790E650ADC9BF79D57D90F994 +C1EA2B452B4CC7A59463C7CD5675632250C7A51A13B494D7228EF4843C8C1A75E3E2DD33 +3B64FA9ABF7E79185E0CFE9E416B619BAB1F0E27524B1736A97629DB8A9723231E1BB587 +8F94C1A223CABA2435BFDCC4D2879FCCE344F6387E33DC32DD59D38388A7EB620A28153B +C3BD9BDC43B6918A64E00AC4B27B4BE4A1C7BBF0A6EAF2656E196F70526C7ADCE42B3A12 +DF7DF2DC001F96C1C9D6B74BBC11177772A906922EAA6D745CF0A63DEB2D8C0364D2BBB8 +0A0A2FDA0DCF6E4325742AE90BB62AEAC0DBF0962C8101216C67D0535E96A464BA2185CC +612AEB75F66FA580590C43D13C7C8C25B858F63AD20258BE0C77809A641A8F8A662B9C81 +0F4B3D1A53A80E062BF3F388A2AE1D4877BE988DEAFB3A5EE0743EE75CD07D7BD867606E +45AC6243C9C775429CED85E6E5CA20021C6603514D6A6B36C153CA063213F8894ADBE917 +891A1ECF868C64E7BCA2580A0180F6746F4B6016A5326D778EDBC993072DF8D6F78A53B0 +5CBDBD5EDA4C30CD8FA370F701F093A06904AFB9D82167C82E1D069047D37B9A437AD75D +9F7F6AB574925D167B6C4BEFEC85AD45CAE11BFC1396F5E6B39843E71660875105150AEE +F2290EFA830DF0B9817D30D52B75FCD43BD20D30ECCA85B20B32698600DD8A8D0BC107D0 +C77B43C87161B766C69F02E81D58DB7006C5D5660DDE997AB669060C70F8AC2FAC3E13E1 +BCBAAA34143320C795625287013C7EF306BAA36A61B9C71F91AEE7E543F4586A7D8BD432 +BE60AFE2EE0DDF5718B227784E7165C4D2C4610ABE9521854902526E553D0A0CBBC26EF6 +E109C7040C3E876F71581B2831BB782CED2D8ABA918859741B1F748E0B8F81B168C7AE91 +25957055231EF91B31C3C09E2FEFF6C1BA4CDAF73B07684306BDF5F735DE2980E24C91E0 +A96B53BF903A23A324E2C3DE3432762CC7995CF5435A07252D6B8053DFA0A02AAA0E52C8 +8AB643C591431E6D3271B7AA05C5B5EC445463AF4E13D37E419947E18F22EF9CDF1BD04E +2E7F106D231986C21CCF02D103253678E4F56EAE1078993E69B76D07F1DB6B7C91F2C754 +7D521E7FF0ED8DD23A6277AF86E4F67B1D9B4FEC627AA69470922186E477EF75A7D77EF9 +FC4A16ECF9A37597119B804C927377352CEF88AC515D6E914FC1EF5AEA7AF1F3D3802C82 +60305538E678EDDDFA87ACD3BAEF1A09F4F4AE1AC97CC0E7785F3DB18B6EEAE005FCFD6A +C2A611CB6F4D8671C08791B9FED03755A13B8AD33C3341CE9C4FA948103DC77EF727AE31 +0C00806D7639F922B967830BF717CACFAF26E2331C571CFE01B214ED596815C833CA2973 +1D3B159B691BE5722D8ECFC2FC07E0E2A12FA9E76AA3F13374310C58E8E7CB36C68DD1D4 +3E1EC626199B5B77D977E9786CD9102454834775BEE6EDAB046E7BF335BC4572544D9377 +D60C6C389934E35E40252BB891D295E8A64C12C3790DDB9AE563FBFAC83A3AE606116ABF +36E94DB1368234A61027B95C152985B30D67C03A99C6C6A6DCAB9AFF3A8B5766302685C2 +A6438B11F72D91D3B1D2DCD97832861DF613EF54D4858B02A73D37AFCB0BE38C44ECC588 +20F47EA30645B18817B79268694829B33EEB7990C52A4057BE22490C688ED1D4B0B8096E +F6E24114065FDA365D05F9804107459ABF86DB0E7F38378C018003F089E79764B45D087D +02DBDBE171A3F280F8BB673D13826CDCFC624AF331BA9732D81E16E522B551CFB43117A3 +D2FA42EE3159041494C5B94E66FC3D59C0AFCC0785C89F4810F772E72CF7133CC7C75A25 +BF0648BE3E0EDD3A724DDB9277D8956876F0718ED0FFF0D7CCE2A8CD683D2246EB26C7C5 +0EDA3D83BF795B55207FB1B8F9559D27194AA9B0DFB8900AC8227ECFB43EC08A7B325DDE +D23F0ABA4A1B771483E181383EE1AD282C1E69B5A9E652EB71934CB6065FFB8FBFDB8307 +785AF2FB59FBDC229974A8714C47302429B17F5B10492C7594D66BC8CE44A8C42755499A +F34DD4DF71DC73E2DDEB16DA14D446A0E0AEFAAFA47A5290E7ED5AB76C076B892156B159 +A5FD0E83D88CCCBEAE6395046A76559F8F33DBADD30F8D530A342297E4E6BC9E0A0C9F17 +60ECD67C3008E01E34E5F688377CF8B6DAC331FAF3974572242DB1850F972DAA8D73F9B4 +1A21CD8F3ACFAE89915EF1A2E369899F81826565A454B0E68C02625AD18E47742280439E +B28A956044CE0A1A6E71895528109927487B2E543BE901144FD3AFE5811E2D5937439E5E +29B6B5CDE26F27174D6DF8D026696953A6ACCB3E84AD623C1183484F38484C41E31D18FE +52BAF597742D38312C7F83A31DC53EF0FB87325CC73E13A9A8B467C07237D23FAD848035 +AE90BC164C363787E65E8E759BFB8A1D0E36205BD6F9B5D95788E2A8ADE9D6CD15E1437D +F89755AC4FA834643732D4F5AFB8B379C8A404EB2D5795FBA40A0344DDFE3E0BF2475616 +9AABA8F303DCD70653B3FC4F15565E9A3C53E2190F3F8EE18DF5C5E74A5EBA1375946280 +93BA397B914D8AF25792043641E70260C6DFFDDA2E09DEA65B3C58260635C4E3E0D4E384 +8D7CC744A7D0E00EFE5A4F35B392E536F2EEF714EC49168304DA679F87088CEECC5DDBA4 +EA30D04BDD075553947644E66E5D5F50643FFE8A48D3B16633CD2083F05755BD47B71767 +53983E6F4394FD61B4964F749977AE31C2D5C25C3C40D1B7E070C7A019EC00E3C55A3255 +EBC73C47F2A4BED7BF0387F9E494FA3E2327D76584727AD5E8198BD80A56B7EBA9B0D92A +D0310E640E53ACCD7DDD57F3A286A301FC3E1ACBE21A4E9C572BB15721A64648027EB8CA +13BE6FD4C97E304406554A623F3F9FC0F95497D97A325BBCB5735E2A67BAE21C6650F633 +05B25DA1E1DF9417597E09C8EAE3C3AFED656BE4A8021F5AFFCF55CCDED9BDCE2E7E195B +1BC94C800ED80960503D735684810117CDF144B739AA5F912E71530A244D4C9DD5BC1AA6 +4A6DBACBF7B11706973418E8C2E04CF96E21B56C41162C78FCE26B025FA9E920C9C7641A +1303D118AC0AFB7C87A371346C19944F5AB905B59AD125C892D213989989BCE2366CD210 +8A07518095BF0051EE471575E0189E41C7350F1DDC40526C34081730EDE9756CA029B128 +6C63DA99B0A4422DED67441301E7AC53A74190D24E9CC438FC2826339FF05E3B58F8FC83 +FB8F58B14DC842565BD87ADF791E8E4413030B60A484128B0A91F91EB8F69B90FAFEE2C8 +7326618D44D4845ED40A2DDA09B5CBE186E330D4BD84A49A28E3F5D1AA6B37773C12FEB6 +885436DA31DF8145CF2A993242E6F2177BC470F58DA16422C8BAF4FFAEBD8B0D4AD5D41C +A32147945C2158CB5113C64ABA334DA9EFE8A371332F1540E374E0AEBEAB6BDDFFD4545C +E156121E3348E6BC1D3120D4BA238EBBFE05AFA4FDFB3968494088F06109BD62AF8023B1 +1F8802FA6322E0F11C03C97C229C80C656EC7E96E4B5D7BC8040E0901BECB86D9A4A5C70 +52B867CB27F11307C4CF24BA0F56CF555DF0A8F247D5A98B1B04B19EE9B394B3FF9473B0 +2D943013C77EBEEF429D97B42BD8E25E251FD7BB352C3994DFF181324936F0AE8267CE8B +657D167E89F690B0079BB26351FC13A13F968BC5E99FD306DAFC454A5F1A7ED0F388CE57 +62AF1A627ED239CE9B4391FCA709030E0734D5D8E1F7F89B3BA991AB9D4AEA597C4B074A +69F44BC22323039A98347F49DF7A98BF48E617184A03E7276716DC5895B5628A004FCF5E +01C22F2304746521740C919F3BD418DE025AC898B104BF9D15DAFE189246D3FF215BE37C +E1134F41B0D0F0AD80719202E6E3691465AC0C9430C80028CBACD2B80A95A6C10F39A5F6 +12DD73AF2C3E4E0770FA137759F5ABFED0186BEAE50031C202975200B58CD5C7AF95E60A +DDB460008A52BB26F4847E6E290A2CCB1F984E97B899D7B63948411FB074178475CFC3DC +E212536D720C6F704C1458D45E5F2D7DA34903ECF51947DE98552CB2CC5705494121A96D +BABFF6E7B1CA155EC91D910DB288BA8DD87736EA60C2B5A35AD67E4C4B323F1CEFD5844F +1B6947FCC7A11305A1CF3CBE545C891CCB7A10F9685C9E2979F7DED90DD1D5C69B934635 +B1444A33B4CB56210DD269B7CE94BE1282EE7A2E2652CC743F33D25F1E83680DC05392F5 +31CE3343914C7E6C77D9A0AA13DA8E7A97B402924097FFF414076A8E055E76FEB93C4CBD +8841A560092F4ADCEAB9AD16D7EECD6696BB47AC93950A844B70386F77572A3766CF3AD2 +500DB126AD78931F8FA3D7DA41C1F3E8FC42CFAC03070E28707D0FCA1A6A837521BFC1C1 +86990ABEFB76BA56B8ED8475F19E3B6EB8AEB62EF86989559B76679FF475C79DEC1A0DD0 +FCFA1FE72E35E5A50086F49757FB1E65957488453EFEC4E973A48EEEA0F4D64054DC9667 +0AEF518AE6999EB2A61C1DC53795AD29A18F30369C3F4378B78DD76781E7B96C39D068E8 +819ACD8DDB59E4D0B60D42398E336838FAE48E164F7935EABCF60B8B6CDB887BA75245FB +F061E3756EBFC0ACA6E0FFE3CFE8D3F67FB75186DF4557165E1A492FD523C7343B1C2D37 +F05C4CEBC077B8DA778BE378F322AC5CC3B06C2A74687B0B3AF9D08D453753B5FC6E4289 +F362954B80C0E4DF1915E1719431244BF87E065B4A033E0B204E6072D006EB10DCB9F916 +0042925BB8A82EE47AB260686DF9EA59803AFD45C4D0B19234F6BE7913519D61B5E6250C +4E5BC6CF722B53B283F4D5E5D2AA7DE35B5C87FD62C9E9DFFD671BAE7E08E68E11710E80 +5448DE7D5D65F4AA2E27EF0FF16CA3E6569A53745123A9FD7F0DC8A57D1AAD7CAB961645 +F0BFA125101F21F64F0CEC860CE306F02FB0AF49F0C0C6D11B437FEA68992FAA2D6CDB42 +6686056F769470CDA1C158913715FDB4D4687D06545AC87BBD5283D8B9E1FD1B1B0F256D +7C675712C2A6622A179F5AC2ABCD06070A038068033D07E64E0C70DEAF9D61DB3F4EFEE9 +ACA908C30023FE3CB81597386872FB5D5557BD4461D513B6A62EFCBBD3062E67095F1DBB +3167E0338EAC1A52B38FED183AB520E882595FA77F561312F83C102B04486D2942CEE713 +92563D7E609E81354D6F8192CE3310890CFE69B41907B023C3451075383E4BCF6102A669 +4B0593D81EDC415CF7EE2C2803CE5810EDC28B09155F92CB20C139B43E07BFAB08978CD5 +65270BD77658B0D4259BBD9C3A2200B64F73ABE0D77CE6D491253C7590F98F3AA8AF8BD0 +5946A659EC1099D13E733C96A4D84405915B12D7A5399645D0C37C1944387D088FB083FD +22BDF34BB31B396F618C518DA593A9584F8ED6E9F299E72A6F0863B4A3C9F184B1AAFC98 +0CC313B225EE3384D2D814A4E96C744E0DC6A666114241DA125F1178D8F1D986B7D31548 +F9B6079DD38BDBC0AA94F135C44D8B7B6E9A0A0B63FB5BA59152E97F61515F49B906C9FD +42772EB4016B53417C5A2C8E881B0376656115231306FE3AEDEB6182220C2181DA354D5C +28E0D758C573C113542CB5346ABEA9B5BF0243146C186DC5AE0BD9505E5517A6224EA50C +315C9BCBF6707540621B95B9F0BCCA2DF5BF3E8021CE9DDD2A74B6DDB0E9F6DC8E3BFC11 +C0697E87E6C4C642D2172889DDF4C17FCD3E463B30D7A930E4B26BA7289702ED77F2AC66 +BC9ED957863A22905F0996D337CFAE61389D3C70ABE7444E8138BC1BC31F8E572C0CFAD6 +BE60B1AD639AD39BE03AD66728C1CE5B7F2DA53098008E10B82CC2BECEC7B45421F0BDA2 +183588B519182DD0C80B0EF409E2F34C38A7D205CACB19864507CCEF34C5B7A18B9FB51E +3AFBC0970A799FD34464F7AA8135C32914D4DBC466DE2922595EC4A255405D04139C0CD7 +F162674F39D8C01F1E6062B5C946F2F4F5E2F49ECDFE43D2642272377C5393E9717CE335 +11B8542FFF199FDA0867DDE128B387A39CAA79DAA1DA1388B88A5C921BED6709418DA595 +7C8D96831B6FFAB26238DD3D11181345B4AA07FEE3D76093BA5C069C9CFE9E823416B6ED +487308D542C84630AAEDDE0B59A256526169B820E56504014812661336692959ADEB6805 +C7091B7899F0EF46299C414925315D10A8C9652931AC7141FBD3DBB0C34476AB2808FF11 +9B10C17C796E67EF18A386F9E55E34E0D32701D1F77C78FB542D49C53337B9074D92DCC7 +0D4AE59389BF27E9CD453608A19855F6A976347AB95CEE2B07FFF6765F97E66978173C61 +61E38E6CC3BB2E278C61BDB601DB7835E9515D347F37A63EC6DADD2F72BCD46AA4FBC82E +EC40DC7ECB825867B98D6F457BE4502C98DA8756CB9285B7DD1C867B9FCCE8591EF331AF +44E38E3523AA39BF0922C6F59F1E9343AD34DD39DDF485FAC00B38EFF62E16CECB735ABF +903630A30396F2912163FA8B23E97F5B81E2B5B538C454967644E63B351B068EF4BA9B3E +70C65BF5BE8F0352F7C0E25EDB22716A632FD832D51AF2D26C880035D8017C02B0065DF8 +44E289E6D559125A31F76E256197DEEE1F2CE1D0BB7303A3CE177B692D3D0F8931A35048 +F86168DEEF39FEDD4860DBE06F21F21D35E8B982D299CC945E2C8E1D73D1891ACD1AE977 +9584F2F3E9B5621C6EEAFCF91E293996F35562C16AB5F35B6A0B55D9FA85FE3B08692C03 +E453B44C8E1438205A9F18DB136F954C7155DA1288BFB6927A4C308C86C682B78087FC5D +CD3976667B4CDFB90CF4E882B1C35D9515760DD4ECADABE73C3E9758E0A8A3B01BAA6A2F +091CFB987E893A722ED935642252512C3C3492FE736403EBFA8FD18FA9E9CC5B0E802E4A +CF77415626A072B3EA3C637D2F998B91B7A7274C2DB664F4A9D73595C2F47DD61E303403 +04E0DFCF9CF520E33AC7E0978B004641E5B6A88A0657F615C2FAC770AD1DF1E31BFF6E1B +8A32F32F0BE2A2649B9BF3F046D8ECF27A0AA62909D0A80262633733EFCB4C21A295120E +9B9D193A12073BB638C3BFE75AEAF1B3F43FBE3FBA8176DBFC8AB0CCD2E874DE912E3A7B +13421673D66744ACD888E2687051B8CBA461B90E7302963CC5DB88AE64303BE9BABD47BC +05A780E1545EB389973A5CF4CF9E53953DDD085E617213B10B3836101E98A0638C1CDCE7 +C9E0D9FE79D94FCA6472E2C9C9FAF3D7D9F260FC849EED1236AD5774045E52CB82B0F7A5 +FE589651B53D7E9FE4A8848A702D6D5D0A415337F6E8DC7148ECCF94B23AF1C11616158B +EB253C903DC963B61D2C27DDF6E13CDA799C54FF9762A1864E516B913C401713B8854414 +B4CA200EBFAA01F382C70F27589796D7EDD4A35334853B33347F231F24C1817657C93000 +2B59E0A2C4A9796822D5F7BFB3193DD9808398FDC53BC25F402AB126C1B2C83914888851 +037FF02EB53642AA0E6CCBF0ED5812527BB367DB4E67A6B8046DA7C215448808EAB80496 +FFADA52671C89E018CBC8D36CF78675E0A721FEE1112BF9C78D478024364E91CFE2468EF +B6A0BD9E1DA67863124D9F5F996EF1FED356C7FD2AA3DB3E3F6CA36262E896894FED244C +F3BFAD999C6F42F13D4AF617C03E29DD1F8ED75BD11F94B1BEA408ECFF117610EAFBF4FB +241AC338E6A8714A92F2A5AEDE86C493792743F648F2AF6E9A2C692A9669180F629947B2 +6474C03FB8B712031E24F7529143F432607D57E81CBB91A0DC6588EAD2DF8AB5C43C45EB +9DFA398AE8272E43503D987B36504181B2E9AF2357ECD3E6FDEC731B623D921F8D1D0A19 +027876125DC02D8FD29CD8521B36373D4498E2D2D9144C85BA8D5D9AF13BD5C8278F036D +ADADFACE6FFEFDADFB88D3CFF12B2CA14BBA16CA7267A4CAC32A0EDE215D7C0FC7EF3B6A +59A33CD5145E2D8E3530F94B5BECFF74357DBA205348FB22D4E3D40F77ACE73BF519CAE7 +5277729978A61B1B9B76E846EE15C8139B927EC9E2F8B684E0E5A30AF34A0027B9F2351A +B149CE2C8DC951CD54B4D6974E0BD74BA6C2F83BF680F0A01CB39D8B835C097E262A77D9 +55A699E86D30312427EDDD64EF7A3ABA1CCDEC22EFF658FBEB30B8FDF59A9C4185A55704 +530A1499CD700E1D6AD5DBDE3B662DAFEBDBB185C32C7E34406FA6B3878D5B564ACC5D9B +EDF6C7B42411081423FCD2BEB0AE7EE02272F547D551547A11F8CAF8D9F2CFD8FF3626E6 +3CCFFCF9277E6003911C54371677D671AB17424633B776DC98004EA4EA0917E085616ED1 +273E73F2FB891557CC5A9BB65FF704EE526EBF8B34359AF0381A61059E7B740D8069C128 +0F942C6410FE3ED272251F2653817FDDEF786B1F7BA9C6CE02C56C33D98E937EB303717A +1AA3FE1CE2D10A5D07F0E7DD4269F44488ED497E75C92657A2CBD792B9E3DEC8C073ED52 +661DC43A52A6A8218385FD37E1D7791E540F225AAA90480B69468660E05F5B826851F985 +8D127FF6ABA8E58C4F69961AD4896B4EAD41D14399A3F7588E04E63FC1435DBD45530015 +D9C5A1DE717D3923919C31B79898FF17D949F47D354CD81840DABDC5585E3ABF11E556F2 +9EFC55559AF05084F95A5900033AC0AA2FE370C49C71411B98B69DAD30D9D9F75DC90A04 +E59234156EB4B9DD2F923A2DF771818759BC86E763FF36898697F37343FE7197EF5ECCD5 +0933E2C446D7AD1AE945A87A3B7F62F8E14899729CEF06BCDBBF29D65ACA3EB4293CEF53 +501735F2DEE6CB331ADC94F27492130776C3E3B422975275C115A1E9882C6A4559A698D4 +46C5CBE11497CB48EE316810CE428A6A08BFFFB3D196DAD7BD4778F216055C79C325477C +92443E2978BE1EDFDE5836C722B96A070269D2D3A1438374BA6071FAD1FFC511BD8974A5 +803AFAA40E3509B10223D7924DF9215650E9F13E75293B799B4256B7DB4878F3936CFCBB +33D0A37E209A1E3EA8EE6A3455A84E28552DFD56BCCA0BFB10B7F7D25983D3865A9C617D +C85CECEF64CD8E470916B0111075DF6D051186CCCF48813C07E53D7DE553FA3B50B6F7D7 +EA60B3EF169527C6206D89C15436344E8C4AAA490C0D6F300D3A18EE3C50D30BE9ACB50D +5BAED6CA52732E7530C67CEFEC9ACE3659FF09897A62F22A6383F7B62289052485B2139C +48187D0FD3F64D65EF4E2678AB5133A09D448986C96C383FCA7E3518D91BD02A51BE54A2 +F7221ADC7317ECA49522C765BF38BE70EA692F063BEF59D5465E3D65DB466ECE7568BBB8 +526587C1A4FBCBA6D585509FC29F6223D68C4BA4AB48D83192EF4D323FCFCD2C399BA52F +776CF7CBC0F7B9F828A7441FC1540DF41FFE91718AC9CCE2EFD9D0E8D8FBCE8402B441A0 +AA2F95E4508D703E86875A48BC8C579A2CC0D3086B99290845A44B3E14B28D95246607D5 +ABD998C92B5CE660D40D31BBA97CAD73DB5ADA4613520BD4C4D19F34A9D3E57D66DB2090 +30CC7F57D5108AC7DF5F528C04A15B360C8CD1ACB78F090AC2518C1EA0D64F0DF393460E +25C7F07970E49ED6DAF204DD86A718DE11F8DEC66E247880CE1DF51FFD8A5797C63948A4 +80D37C43C508219F322B346B65ADB3A801FFB1033D409838FE05234432EFF0FE2127AB0B +EBC5890CB026BF94AAC5DD98E4153015B36D30B72E5192DD9D5EC6E8609423DDFF7339DE +5EAD4AE73019DFBF3BBD13FC154FCCE5F459FF033A826C7C4DE12ADE39CD85D3366B8CEA +64D4CC905F352424FE9120F447B75A51379885369A73600366055384C7BE79205D2B868A +1A6246C803C27D558DEE4EE108C013C6CFB8AC1016479E37C0FF0D4371ADE9EDBC986BE8 +A8861975C6761CF9DFB6F89244B2B447AA9E48E8EEBBFE1AD875AFE06D2BD72D0867FE65 +68D316B08DF35217AB5BC65200870036F850433BA2C26D1AF67C859E8DEA24AE44C6F303 +059B3AA2CC0F2DCBFA798E151627BB8CA785FEB783D59D10132725E44133655873FA414E +C6C9EB631DF1D0D3ABEF257BDFA9B1BBF6C17731195DB3B53EA289A0D3E63F41A330CBCE +863B1B6352A72A11F54C813595FA055BB5FF7F27735D4D3F5C87ED89FD18A4709B73CF8E +64F9793F12A0946B974A03C4BE4C1C2CEF752D57E323981438F021334D69737DB7B9A0CC +4CD5A93A3B9478DFEA4096D143BED8D3C4E19C7BE85436745B6BD0D54DE8DBCD1268E5AE +D92F8D23596A27B730088F4529D03E2C88966525D62C4A90D4869514362F605EBB9852AC +904758B83108A59E29BA45404380D86D51EC2567A3574A9C6889B22CC1C23063A782746A +02F43654B378E2C60A66F583FA666105EE8AC6C54C17AE79D0BDCAEFD951139FD96D45B8 +2F75F1928870A9876678588B6FF4B76F3062A0B895F8095ED27A8E620C2CA398EA161BF6 +9EEE9567D3C4CBE7ABC01D7AF30BFBB269CBBD0BCE7208BE1C94E95639E99337C56FBAF3 +AF87E956EBBBF2D87FFECC8B32220949A038C48BE761CAD77799F8191AC0975236C15458 +A7957630480517AC0F89026DC1B4AF3B005DA7DAEDBE41EA451D4B28516204427BACF5ED +968101E14C29396B7BBDAA67F10A602207F365E96CC6E050248C46BAE78348C4E016AB3F +1A1DB7E9BBDF6C8CD37615A12891667153DE23FC013ACBDE84E5E490FDBF9066C1CB00E0 +528714B54E71B5626E71D387B8FD41B21E2DD15CD595EEDD545A90E8F0D02388820B2A97 +527EF7DAA65732B6EE2F07E2936318FB75143DDE8F5FDE804346AEFF05637BF48A705A85 +B6F3863470ED141E118801AD9F47FB05BDC65AAF8F398BD3EB895C3AC5C94DB7CED1AE7D +1D7311DD67343AE0B5724A8827CC26E463AA76B00F4CD3168F1C92C64EAB1D001907B900 +6B1A12550668E688E2D0ED3355ED0271228CBBE4D56848F0B08EA24B00B5B20BAD06EE1B +C6606DAA509FDC41D2BE545F9FA650E8FBB0E78CC856A5331A8A6476FA3C44487B9F37AA +5DBDE9BE2A64C69CE8438170E2B40893AFFC0BE099EAB03E5034458D54BF9B64BEEF7167 +A25AEC8A1F7217E492E5674E4C8B343B9249B384BA88DCC4F8902FD4D535C0246E1609F5 +4285F84C2D4B489369576E74272255C329942F764CD4A51C730C99E7F5F8B7C52DD252C8 +500319E4CBE6C696C77CE1ED8BD05D22E4861CF9D156B95499B3718A47E5BEC9FD72E1DA +DBDBF137EFD6CF8BCE7D64A27B8C9BF6E24C929BF07F5A62BEC7BC760706D31B98DD8E87 +97559CF8E4357AC49FF6B47667228686A3AE789D68B059FBAB877F3F1BD00841A1F151E1 +EFA94F69BCF41D4F9DB5423430A2AD2BCD53BC87A5178F74EE469772FEFE1153C8454288 +31B12B8276E3E54162B64B393BBF23F1EAB4D1D385FFA5CB3C57809CAD0A453A10661D25 +685A9C56B41A53C3B1CE6E41418D8B8104A2BAF3667EC877C9B6269BCFCAACFAF695EAA6 +BF13891E52B4FBB7543F1BE26A867EE6B515DA051C3C7BA25BA135FC186D4379D9AB4949 +582692485409A5DC52BD6836D8CADC2A48A4F5B4FCDC69099C3EFC7166ED293A795DFDC7 +3FC01A91C9C15219723FEA15A4FAAC3511AE8D0DCCAA1FDDF7E2AF4CBA80E38FC6D2D8E5 +B9AFE27366ADFF0529348BE4E56484F0E31BFB7B9DA4F06626599FEAD323CA644677794F +541EC7888B181EB0AAED60E6F0E5FB4F2FE2564E2988D6441E58C2C0C1DE63CF65D625B1 +46FC422A0E0E77C43C8FA2CCD310B5694EC8CD1B9A3ABFFA25687D4013C0E5703094D5ED +37295E540A1B2B2E836FF73B23E8CDD190D1FC04DC6CB9D5947AA853F6748388D400B6FC +7DCCA73AFE6D1FBC61A7A3AEE4D24BA702A2F4493D484F19CDA1A850C95486E4E4D43F8A +A584D14F82AA0B3862E1FB06E941A90FEACC607D27AE58CF19399886879BAB287A429D5C +0C821C26C61F169F1B90CF77878968F56737041BE38776374546623553223E6E2A8682E7 +737528C915EBD41B263DF7E12E4A4C6967FAE40F90DA0D0410E0F22BDE01F018D63A8C23 +C157E72C6910157A63B33AAC9E5F3C58F771B8CD24F0E24C4EC17277C8B8DE5DDE52176F +A9740EAD3F62125BE32678C35005CD445EEAB9AA1E9A71FD11614426E171EE85F5D9A17C +536C87D58C5140A64B080966EC5A3E0AED8BACE84496BD019E6023AB562FBC1F28CBF296 +3FF98D715ACEF7BDDDFD65DB78CB3F0E16C440EE636A0D7C05CB97C085F7C5222ACC6305 +4DA8C3F7D950B0399B7250BCB66D0D520AB951530E728B4892779DF0FE56C9A27E279DD5 +02883DD2E2E4013D03491C52B21DCE600D68156106418DF5273C6F6FC9A3E1E9889DCE43 +17628702B21201E48D23A7E0EC5E1DAF104F3BA1F659B8FDCE301C3D7ACAE1B7CD6846BD +496B16BF6DAC876C117242B3088287DF82F260F960CF90849F515702F71EED275A40A579 +B0B8F707681B5FAB21A81FD992254AFC0D43E88D641445FDAE5D6874C4EC37B2BE38D5B4 +6DEB232B7100BCABA7ABBD53F5455EB07ECFA23B1703A2690869A8D0E60276830D7B4FAB +231FDF2784CC788CE61A4909B89C5B8A5791FC3160166BAB1BE25E57BFB2D162CFCF36D9 +CE524A56A15DC752BDEE0CFE605E5BA650ACCF0DE4286C70EDDFDF8527A02C3958B17C82 +1769E8EE3E46FCD93AFABBDAE4809836C56C242B0C6C63107AC6C3364B7C79BA5C62BF62 +EB6277B4F6905CB999C568AE118A690FCBDB37433DD2B360A7C66EB52DAEB0662D61DE6A +74637C6C8B373F9EF9A473486F3A4326ED5A442BD2566912C9531C5EA6BA89553FB67C16 +1933CA4D7FF5886F2F6B3ACEBF939B682968D4B0590B0D39A0871A78EF3885E47F892C16 +FE93101266B12AB988DB622F4E408C442937B56007334AE919983566CCF994B3084C0D42 +5EF94563A51CB142F0829F5398B647AAC6E0010DFCCCCC15BD0EA5A6CC90EF8F790980F1 +4C8A27B2792B3C83E1317CB932DB3B28F008D442D374AA75573F5A324D7C5D6DE8ABE5D2 +CF78A931DCCAD7831AC5A7A5D5DE80E475DB271F0CD21A47B1E7DB5233705ED0D421EC5A +2BEE73D5949400151866E065B28D6E1F6574E2D335BB542D16EDA5823886430390F9A0D2 +B937F7ABD1DA9E04894ABC066F8CF0B8BC196BC1465A378BA14D2284AE4DEA134DDD7440 +77DBA60CD0F9E478EAE5F7DC0D6309C9EA514D44C279700088581B29BC0136E2F4EA3E9B +64403DDB054736966C331AC20514637A3CAAD1B27C569045C444D48FFB63091B6D20CC67 +FA5034880794ACF58358861548044DACE9BF02B4A23925639B7A6A5DD4B6AEB2F18C1619 +DA2E4597905CF4A00ADA215FF258BF38FEE6923D67424DC1B05015C8D09DB1FB7F660C6D +E061FA2690AF2CA528AFDDEAEEBE6291D61955BE374DEBC8A915639DBC5382A17810993F +92E7EB5D2492E76F6142679171DB74170A6B390CBF7E13CD5307CF04D4C471BE0C7EFEEF +B36F609D765DAFF2E682983BB0CA6B70B713F1217C8F2272637C8AE97B3E15D5D451AAF0 +44FA166A93B277E334DB8EC58EA397CD013B53DE2D7944387712E80F086942728B9A4877 +C1193716F71ABCD563EA769AA555CA4C48FBAB634B1AACB77C7A576C4DEE78C5CCE3D3F6 +E483B076A4024292A35BC7080245E56B6D58926983C0D9C31206130B3B8AD5CCCF8A8659 +465C36D5C5FBEDD7B455EB4BAFF35AAAA12BEBFC6A7B40AA15B5B957625C37494177CBD3 +E3E59740FE558926927022C6411B9F07ED9BBC31AD206944E56146CA8BC0A9E8C9172C0C +0B7C46FCB490EBD02E86F69564B8030A3280E376839D680786A0A068DFCF0A3DA5048898 +69C9AF0362765CB583B785FE8C0FDCCE4F39527A7B73565CEC9E798FCE909941522819D4 +519A12043D35DCFA7D9188EDFEE780E04A868346C68A3ACE74B16641873B8985C1F0C263 +9BF63ED86CB556943932F9AC71096EC23E9584C8CEC8E95C52A493E4463B168BEB6F259E +71B2B22B53554E487A897256E37BD4C1D3B48DA9AA5C5CB8D5D85C61D6E1BE3A607BEF1A +A8ACD46A93FE3C07D0BB9EBBAAF0433C7E5C6D5040CF9F5AFFB1AD8104D1328005CC5B10 +A1993D3EEAF3C3BA4A0B1A260A72DDA6ABD5358DE5171F1DBAB667AC022F46D3BDE54809 +790CC4EA533392E6C039013D4B0FA21E36143CD9E708C89CB13E09D624551CF86BB79C3F +13868988903A7C5C744743FC8CC6B48219FBFFA584E016953F8CF342DCD69077D9387A34 +EEFAD0463AD98FCE21EE8342A3CC4B9CC10F6804EE9CAF70FD1C56CFEF02B7CF2D89CBAA +E45918EC9445AF3D1C43DFA501D9B3789314063A748A6907BEC153F294D6D046B9C76D01 +4CC021D3074C0A2D8E92B45EBF14C1C5AA39546A2362CB8A6FA0F5198AF84119260DA3D3 +A89AAF0A976B1D5A020ED16268C8F1908400DDB8E27F57DC2B00E3E4F0DF1777A934DD89 +311A8C7309C24A670A6A9E03C094B548D223C31521DD7FC2BEB3DEFAF7904EC0123FFBE5 +4E627D9AEF3AD29FBAC003520D0B165F3AE91AC94FD8F3FA9A6BF9FB81863D03BEF8506A +A74C7DC0B50BD327C6942905BD07FBD62E4C3B16A06070BDFBD80414CB9D5261A5F721CD +FC7D1F1A6811E1362F9372CBAA3C8DA63BB103B2C10BF6F2504306DB05835B80FB70BC39 +DEC4DB3ED1EC4C2B64CC907D751407B6B8379F449210D0BB68CA1C445ACEEBF9C31419B2 +C4C5B8780991D042AB3948A5C5C8005E0BE1859B13F8AE6D4AF62F00B415BE5BB641B964 +53F037C492B988D839B96AC0FE01DC0EA9E064FF06EFFEFA446F41AE8E44AE58355CBBE4 +57DBEE1EACEBE69E6686B687CFFE11DDF76C2EEEB6662B1A2A176BA63E8800A51160A6DB +886AC4C5868D17487273984BA2A47F39837F197D6A9B279D71157B6ECC2A72F83C1A5C45 +B17698F3183C00B6A61C732604E5520320309069628602318F4F68DF0BBC2BAC6E90D1DD +ADAA738EFDC3F63E8F24DEC44D41D2CA546AAB5A88FF61081C144DF568F35C21A887FBAD +C87166B58486340679B5F844DBDD772E9848400746A207BD04F470D2B2F14A36225FD693 +E1BC7CD6AA3BC7FE471C56B411B084FF8A67B0B42954C0915C7388BCC44DB2CBA0A70F4B +1692AC59029B8181D12F6A1F22170E04696799AECE8E6B4A96FE89B7A18A4B6684815BAB +D8D94F98302D44EA827914CFDE8CAC4CE48586630DDDE0FD1F9A57E8AB0EBD27F6A25186 +7986192B6D3F46C796247B1A220455A49745710E32F4D03B4F15636197C6F84967054365 +F7C0B1C20DADB63AA474551586EA5F055F8F3EBB1214ACB3128D4C6FA566C8E506DAD848 +6DC4A245D1977218241A5FC37AF7C03342EEEEEDB2EADED36EC0C43BA42F14E3E9601784 +5780F5C6E5262D96C0C50C87C9CE4E4666D1EF982FA7D4F99EB0A5EF4AB0456FEA1225A4 +E6873C1B6888ABEDCB0D84275EB400E73695564A15E338E00DC77981DE14FEFB40796373 +631102384B1A3C0EC239F19A2DEF2689F75F5D55E22AE9EA06A8A33424765D84E458AF21 +B8C99E6BBBE5517587FF76E7D02BC5AE43007F2228014951C93C50EE50EAB764BFC8A084 +86E97549CC9A8C53E442C8AF409C98382080D32974A105D60383E077138C34F887159B4D +5745F7B6443B446C5840BB92A3B0BC317EDB0CAC5310AEBF16285AD0C4DCDE6E27C0185E +9CA90D3086D6E11EB43E65F25F74377AE8BABC97E0D9ACFDC1339D0613600BF6E2F6FCBF +66A0AAAEBDF0E9B3241F57D08C17612666F8286FC17AD0CCC5AF7F355668E146C3FF61EC +07A85AD2A655DACD2CC58D5D0216CCE6F8621405AC7A4A160B6B2C9B6C5857D40A5BFABC +199AD07AE8BE3169A9182F81F80A094608F1C2B894A6CC33CE4DB65AC02E3528601A27B0 +FB7E14B2B97F6391B0CC8963A71C6794E74037CED7C0F2D9B7EA192C44A5C1EC78535F45 +A5A38F6C9E9E811B950B7D0B2BCC7AB21E8B10057E64A72CD86549B52D74C806C242FEAD +5751BBF62735377DF1C0582C89B0794D01FDA343EFA486AB2746A6780508206D0C42F020 +94F3B8ED6371412FD4CFF17DB123DD857DF02FEF68954C8A64FAE88C67351FFE15834360 +1F9DA7526CDD58BAFD5372A39BB7AF47A04BA972ED382B7CE3FDD92B98B9147EC77C5496 +773F33E58D6B9F48447D3BEB6B12CF2FA194EBD93B318014CA0EFE61E6299E097B394F88 +6D15B7DE6DBDD12A8B38C5D0F328FCA5798E951D950DED554353AFC64543CF6735456CA2 +72333B0797B4CF24D247BC76F9FD325A2044F01046343862E92591CF371C1A2F6118E36D +2AA1EECFFBE7115C525A722072311E353526224622B96265B29C10F6FA3E35B8B4AC8AB9 +084F74CA7C2E39C19361F97BADE96E7962B8356C92DCCE8B5AB85C48F569001F238D113E +8E0D83B793ABB238B8DBEDF30F33BE03ED480AE7672942C7F60FBB2B2ED85451DBEC08D6 +3F33AF72437E6598E90C52D62319A1F2018AAB1155506A96D4F2558004CAA6EC715D8EF5 +A34C7779ABAF2CC9A288DD88B96F0F3F1E45A6A7049348446526EF562DAB4EDDD8BB3030 +E913252DED80A8075C1C93E27509193CAEEDC132A3176490B03C53DACCC26417A5838515 +FD4A8093EAF7718341F9A6973474EBD66C63884BC78E318CF04B9D3449196110EB6BC018 +C1DB6CCBCA2ECD1016F1E884320B14B27BB8A15FB42E190C30E45965C32C21104F49FAA5 +B3F983C768BE7C909127C19EE6392D6E9E698D650CEFB7AE48B2442522D88C6D6FDA41DA +B8B3187F497DA1BDA3FDBC8B71A619063D9461393FFD5A072F237B7FAB49597636B7A41E +91DE676102B0FB2ECB4D5135C015B99419925667444BAB52923DE73287D3934DCB1BDE9E +72ECC4C55A55BB24A71B5A37960993BC88A0C66B82C2E2AD597EDAE4F74FE918106413E7 +233C832EAD1D2A2E515D734960730EDB2A8072D539E2C69CC5C9E569109B20670157AB44 +41BC249E8DAECBD9F2115663E7C88AD8C4067158B822CB278DBE410E8B1E3E79D4E20C6A +E8FBB5746390C823D5D818C3583A41A2D080DF439916FF23709C6E816F7DA9FCC60E5B6B +FD17813DC59636D33A2523AED576BCDFB0DC88725D6B6F286B2C3DD85E53D825DFAAC9A8 +8572519A254CB4435907A2A57EE96CE3078F80E24C0DB0FC3B047684460F5314B1EE091D +6CE4B884D06DEEBB7E1ADF4B44376699AEBD7A5F4AE19B5FF8022459E9E2D43117F4C1D7 +630028D14169FBCB72DDBE7E4BFB4B7EE1DCEEEB91623718BD1E5B9E16DD4F3ED2469BC3 +1BE0D51A530DE079DE096431EB3C624898333E4A271A79D33816881ECA7C355C1C0EDE72 +039E2800D050F507D05D8DC2A6F79C1E58D269B1CF397160A813A827B5D5060CE32B3454 +DBFD65339F3B75CEA60BE92A1848B7CA7EB730BFA278E8D549D3DC68E9EB32553FA32360 +4F516DCCC56EB0751383005BCA15849491D9A0BA4227295B88BD819FAE10216E1E2F7CCC +DE0FA17076C881DC4ED1E03F3004437849D059449BF180F4E5A547218D6CA90D235A179F +BE73FCDE7531099D073127D048B9D3050959CD6DB6FF19E57BB9F296536E33293F4856B8 +20A8E948E00F7FB3226F846EAB9F1A7DFCB11871E7B85C4A7BE6A023BDB2314FD77868FB +E02DA316769382443FDE43AD3979D243726923904918AB90A8405B0184189C7FD724DD7A +E4EA99A6E31C18B5A00448A8146A9897584A935118BBD8F7BA9EC471461E5D932434345B +630674C3ACD3C97E0A5C1E6FB286D9A3ECF40FA51AD7C1FF9992E0EFB3633F4FE8450FB2 +15947E2AA9E07D07A98723DFF9D31CF3C50C4796D98DEBE12BD475765D8AEA0180CCB73E +C33CC144FCE23D5D90282349CB17E9FA753A6B8D0F3FA480C5D6D4E11FB30393DC4A774A +6C568A6794F6C71DBB7A1E0D9F5BF8DAF1EC3CC18CB067FF86201124CA66FD8F7B884910 +DF8511ECA9F027A27CBD235BA14613E32213923BE966B04A79A6328431B07F762BD7AADB +CAC4E00EC767F91C3BDC7FB20329CBC2A91A98EF384CEAB49CE57F3A4D83C4A690E49D37 +BA278E9D39B92740923B3F3E5B8AA7743F2B8EFAA230C211884999091373843DBE82C2B2 +3FF81D8D7BDD75E9782C9F3BA1C587402A335ED42FE47F837366C61306807EB50BAB23F7 +196DD1080B0389BD1221115F17D9B51FC600C77D5B02D78F05ED65F895AD34CCEB36EFDD +8A3289F4AC4472CC5513E688B96053B6DB54198E0C0B51C3FA3723AB54F2615E0FD7B488 +B3DF35A895E558A05C100605A213129C0D8DF08C92A772450F2F1EE7806DF2B5C5DB82BC +4B72137716329403F9CCF85B592DDA02CD4FA4780D60E8B9BD7D079C59070046432F8A2D +8BCE7098D4A81E6933807B0D9EB617C2D8F7DC8E29A5C10030C93918378EC771EAC7FC78 +9BB4D5D1CB078D4B2F0F239039EF9F1B45D768CF1870089F76F54F86CF4BF7A443A1B333 +EBA476838752720F8ACF49C0147F62068606057E9E8F55D3C26BC0328216D6E55B9A18E8 +BD8FDC0AE1FBD60D1244AE9B060313ED36231A8610D0DB8BBF8B9D0C218082678F828853 +2BF2FCCB4E13251E1FB176AF17CFD1B4E74B195FD65493F74C9755562D91D83CDBBF8693 +161FD054345DC816F885596C6B5F423605D0DA925E27D8A44F6EC50E36C368B29AF9FA5F +7D634E4390814758A934E216DC092F352B49916F6F117EEC457AF1029FD0FA1B267BF519 +C85866DB602A67F6ADCB772EE699DF5FBE9799BD6B0CDFEBFAF2FFBA9E7D1C7A4E9A8D72 +B1730290E8EF082B6313E162E1C1EFFC7A404C28B4B3E4C9485041E941455CEC85C94BC6 +B727E5872EC049B0F6654CA3F21E107FFC105175C30BD172B8FEE93D16EB85F14DC911AA +E9CAB4579778040FCC18F15C35F5CB1DDAB8C393476B882571B1C81777835F011B5DC4D7 +91703453E60205ADB46E9F9049F980603DEFA613F14F370EC8729C5D365BC4D128C65114 +833F57FEAA89834597C2AAFCDB74C5CA0A35B6C380EB029CBCEF5B7BE1D253760653677A +78D18C6230986DA5EBC43888B7CD821C1EDC997A4A3574F695CFBECB60C7F07C5FC4B9CD +CC49ED481593019AB8400DAE0BCA31F101B5483B3DCC330631F1EC7F4E5D3EB5D6E38ABE +DE013DBDDD4FF6D9689C2F4F3E7D0F2FAD680B94B5375853A079678C3C2FD7CECE27C8F8 +7603BA3C73B1CA9CD33F9D114630E413F118161CE5C6B38C8C5827710231B9E8905FAD73 +DB3AC1FB0C7883FB8C0A96E05859265637903B41E662CC4D5FB36368E4400737C5F34F1F +465CB2065E90A9B453C7D2A3102CE69537616A15A462087234A358808EECECF2E1704E35 +0AF5A17DFC5D5E83798E98861B94A1170CB4DA8BCA63957EB1B7E0515CAAEC440A291161 +F6B81BA7DEC7270FD3F2C07B8629E1CE3FF15376660078185A05C41D4FBF99285413F001 +4CE1D20E4EB2EF6676D1AA2FA8A4DC9BD3AF6F664F9B4E4B3BCF606D14AEA0DBC253E9A8 +75AB27F3D5A7328850C2E90B6BDA2420E82BC0ADF07C005357514257694FD442A6E701EC +CC91B7E0845B17CC8F09892BA35CD5334DD73AA0424AE8A0E1CA52D2109E62EDE237177F +1B469CDCB95F1ED1934C09C1C71A9061D0C29059C00D7A6CC1DD2AA2DDC209164890161E +8B4532199F7A5503A4438B3769C9E1F8368764D4F5A5FC7CB397E27844ABC9F2498A6BBD +B6AA3C33125B52F692D2E4ED469E7B3ED78D60BA285131AA78F581FECEDADBFD2E7932A2 +D96A86944BC7D3F511558E3BFD8AE1250924162874186ED3D12210C79C044682F7BC3029 +D9A352D3533BD903F26A180686482129DE478F6A0FAD7DFCB9EF25F13260B9B0273645B6 +24583701E37773426743C9AD1569FCB3C69277C3958944EB211758D1787C86F9DB344713 +9F522EC5328337AA586BDE5B734EBC6F5F392F7BD9D6910F204C63E9529C9561FEEFF567 +800BCB0E900BB465DE21A576A809A13F3E4FB24A9223B41E52BC297040808840FC7FE337 +7B7B71A0318EFEA9A421FBCF3B797BE09579FC5559C3085163CCD30F2757E457A04923FF +DD33B439351FBA13AF5DF216A968D8F093540D70222A5F98CF9E6EE6FA6ABA02B3BFFFFF +1AD6B5A3E48298FDB66E69459C7E9646829B032E99DBC5B4C98731D868D14159E95224EA +9237CFDF32A20DA1A4CAFC0D55CB9DC4BAE3468A0A91EEACB9F6C76F677DC6BB83BABAC6 +7A7238F67F41F0A67EAE0578F56D3734C87304C0D3800E9B52DBCFF05F6EAA9440691225 +CAAB4C86856463B0E0ECE208CF4920871DB1EADA477879A4C64194DDC2325040FA104327 +FEE2F853DB4515C154B3B8A78419DC4B17C78F14BE6C7E8BB47388B11075474AEC54D6AA +C53AE725242BA69651DCDDBA6774C3DB95B947A044D009DE74575030C947F25274EB0A1D +331D25E53F231FE7C2B7817F44B6E98D0B845BD0A31DD9C8E3B6845CC80B259C0B850278 +5E0542CD65CDD0102FADBA33501C1251340F10AC63988FF53BAA60345A145455009B80E6 +D67C8722B22FBB74554A88B0284F641DA252B9A2556B5EC15DE1EB75C0F74CBEF4FF7CA9 +50B90497D23A935511F5B7EEA0B92BC686D71EA186B49B21E9183279379637F8BC3A3079 +3419AB94A6EAB55F602ED0D4EB20BF6AE82050C432FEA1EA3B5BF2A16B879E586C1130D6 +CD5682D7A1F51704EB03EEF129D7994D80183B70E3D60A5EE4CA8E21D4703605FC8E2CDC +03E1FD17A2B788FD74DA79A0942856C022E9ED417BE6F097328E22717AD8A4976A855FC1 +5B8CDCB66FCAD6E6D87021578F2A3D93CBA708390E849C1A96E234EB91F54F53299529BF +1BD1DC11722FB9DB27C98F2FB05D62DA1B7EA32CFEA033EF7C1C47B3FFCFD9A4BCBAEE4D +66C94E8488D397644A2735E9AC8E0A5B4C61504D43D85B27026F15059B0717A0E9C2A893 +FD1A0C53815951FE68958615A581D9F1C22DDB219C3C7213F20C496AA0D04E9B3957F71F +94A2A9E20FC1DE943A30D72E20E0DC0AD7D974164656FFA36F1940909464CA435D47546F +4E74ACC7817BB6842CF97FF285E4EABC7CFFC7A314983AD5DE3FA821AEBA7E95252B0524 +D423F8FE71FC1E4D8883876DAB19415FF39A330D8F1F2E9E728F2D47EA05397F8F6D4A17 +7BE4BE649DB34CD403FE663509DB51FA3DBB4F3DBF4C969DDE8E18CC54AEFDBB23E286F3 +EF0AD94165558C2E1E91854A7B2D547735A3BF9A4AD940C328709F99801FD5CE9EB34C2C +394BC530B2F79D6EB01FB151A20C03F64A76D6018699B09BABE16CCCFC516FE46A906633 +26E06B7BA28EE26134B52B96696BBA8A235103E8516FEDF892039A768C632C39CEDB3AAC +19D71D351AE1DBDC46ADA5D3D547084243A87FECF11DD3A99C79E08A17969322C177544A +A0A79990D1C52BDE6777A77DE02D9E9192A6D06D4B1D2FA19A95D1EB5B2F700A3D76D383 +D6D8E68D85759C829BA020BEA26587350B8BB4A22BB437999F0207B51E3C29508CE76AD0 +CF2FDDE225F0A1C2437E8607CD180CCE7A4975A535A9F1AE496A3A7D83A276C67BAA1981 +66BD3AACFA8CF66632E6D18D256F878143ED7EC542D7C29F16B0CE96D65201519B1A1C6F +941B4812CE4597C92727C2B1E3D41AB59F3B026C32230374B012491D5DC66E20871B0EFA +4A1989D8AB26B772A7BE6002E4FB4AF7F5DD5B0639FB0E59349A6AD7522240F19DEFAC33 +D0FD050E565E36E87C5CBF0D924A3EC16BCB31277F53770CDC95254C0B9DF1CBEA0D4386 +299D005AC2C1B4985DED85978FA75596D95488F9A16F77CD6572064B658D6FBB7F765CC3 +18C1032AB570E04589F6B56A67E0DA0D485062899BBB0E760E649B0485B13F76922AFF97 +59BF4651ABD8AE83EAB7544A2CF451E9BB18F0C4EEB431D46B65CC1B9049F243FE740FB0 +276059C3A80EAC689D5A511399334BBEFEE83FE0138D3F46FDE381EA63DD0A5AC4E36754 +BA7AC6784CF3A1428945483EC5DF805B846C2C758EEC2DF8A63B55EB7FC0762080071E10 +EEDAE6674E5539B69A6335C68F1FC10BF1F41157D082CB9376292CDD4362F14185D87F50 +369E7B562DD7F75DCBC86A5E8187192B61E3EC233F9E26230855498C1A580470CC20E233 +C8215A825640A89D8E21E4FC2A4EC8CE44778B4C96B217C0CDB6D2645FD5E4DC24D293C3 +84512BDF80C6B99FE14E429AB9C08E7AB2D752F44C1E826E91DF652505F6C84F050707B7 +9E222C6861D5302739CF4561C0A5FF82CCF7E7BB2B3F23360B8B0AFE8D3A272F6EAEB35F +5419938DA96A1EF1FB50DEFDB9C9895BAA791556F51D3BFDC373AC0FEE03560918977CB7 +851EDC56750C708883149FA8D939B5BC7F7035ED3E2F2CE7295765C0BC09FA3E18D350C9 +9B40E2810C1FD915C2AF3AF93855AEA12DBA06896A51C9B2443E2D9A9068FC76E353699C +B8A782C2126D7947101849809294F5763E150498F31BFE1D5D8AF704BB59176DA3DF2CF9 +0013ECB8E30250E5AF4152D892F4BE558D140613936DF6F9D43629B1594FBBA870B0FE5D +1BC168BC183C60BA2ACB3C9BE52F853AD4FC1B009801ADC0FB070C65084ECD3165874E91 +4915B5F188E4CC3BC03240CBE3224662D2B3AB7B3E177E6ED05C7EDC0E96600FF6527A4F +2A63179E47E74DD67A4D11BB1954DD479D7B66FA38BCBC85411B841D963417853482EDC6 +0753CBD2E0B0EA725170E33CF7B7F801BB348538360EF54A01CEB35AD465CFAF5ECA3EA0 +CE3DA1240E1C94A7F88375ABC46AFB407FED5EDBFDD79AF542956435D271EA685D9E8474 +ADBB88246355C959AE1408A5C4E9209FEF36253B0EA5DF070DF4BB364FFA3386A7FDA80C +046EE0F54552D258C3BF0C964718077914D4A43854FEB495FC4D421C2939978770ABD337 +3160C7D8C9D81F1F3ECF40D24885AD5F26805DFAFFBE9661031313540B02E71E1B9676F1 +5DA9BC5311178BE39B0FB98F3D7F1064B7E76FE3A15315E234C712AF8542E4E1CA1BC2E0 +8AE69382A34FAEFA2E0F67A6B62144B0C767A45C5DB57648171D43E8E07611E04E230C15 +5A16B786236833B51833EA22321EE4A3B2E273EA7D452957438428BBBBA25E31A5332106 +54AAB61F2302CE54F7B2A0128327D60ECDDE0E455FA05B16747F75D9A27638A174482ED5 +DD91C796158D9A20FB380971BC4E30FF0BC9B9556B4B53085044044AB9418C2144087A39 +3FF2988DAC87F5B872684A327B30E362978BB4903DE7A4C3967F62712B8EA2221CFE4BC8 +72E0EB73E63A06844ECC468DD8C9D2D774C3332553B9FFE6143545F214E3DCC512E15990 +9EA880363696C962E6912D26FEF0618B88BD1587CA13C3A82A423F19CF9347D55D005380 +3B1B91B352177813C3E20C5F04AB4B9A2AA11CD39E11125CEAC385C25299DE0B617D81AD +8091CE925DBF4675E7D70A515B83800F1115762A7E964FCAE0C61BEFEAE27CD77E39153B +DAA1C87FBAC70011B9A0F62A838A8122903AC09A39E53F56935778804BF3D025F664A9C4 +3E314ED0673FEA3ED9857079FC6A49A8B77617014A7054017601B5C6E75C8CD05F89C2DF +D8ED46914521C2D972BBE86480177A3A2B2DD174C77BE7FC9E0069568B392C124774A1D8 +DED4DB00F17024B55A5048A4F33C6EC5B0BB43EE3AAB650D9BE28160D4C0F128BE5FA21A +A29DC060CBDABAD9BDD6CE0B5A4B2051E038794AEA31C482C2B5586320652D940FC3D6A8 +012EBE0EABD7BC1491162F8FC1C40D07B904B5758515C1286DE71562A790E8A86B6D626D +6327F9C7EE4EAEF270D5A6081025B95DBB7F57C33B819CD417850311E3CA2899703649A2 +623255DF77C213A59602CB749F49A381C6101D27D7975ECB414D601B1F893AB8B8159410 +E92550514FE10C04C2D218C7B8EFAB3A007816C50B3CB724411558E8DC8520908C205239 +501DB6FF5B5CE1767C7EFAACE931987BE0797361B3565571F440FE447A168AB3360C3E36 +1E6DCF8F6482885ADEEED01DFA23F47C6B44E6268DAA6962225B10D37E57E20D9C55376B +9D6A880A90D535F91D3893FC09B5409F2D2A428BBBEF2D9DC4686BFF8A863A6CCAE5FCBC +5090B2B9841AD3205B0EFBFF72AABED459118C799C6B281B64500243BCF11D5531BB74F8 +A7F676670EA1342A41AC8FBCAF459C9D11D5673A0592AFF53ACD4B94904F7FB3759C59A2 +A7E5FC2126ABFB56535D0A6240CDB83223EDE4371D910931D7994AE05CDC24FD81FE8126 +5E40835FCED262A0DEE35F705E0668983D65A8CE7DB1177CA8B7BE0A73A99D4D3C44F401 +DD6CC8CC119FC36438F18A924D6DE1C2040D2BAFE336277A751D6D4D05A828AB3FB8BD48 +A7DE7C166360788AC8DD81662727B330D860166B2AE789181E4231B5AA3A205663024162 +C053F2213D30B5102B3C430F9B67E3FCE64FBA1BB617DE61D2A64FECEF8B6BE7D4074E75 +DD4AA701474CB17982EC4203E1754A19DE41874EE1818BD4F243869BEA6422CDAD1FDE4A +84A1410C9BC92A32525D6DC52EF3E90F5829CEA418542FCA02FDA62666386F628543CB04 +D08188E6B9B0092E6D00C6C75C5CA9436AD0597C741D4B2C63E585470994B5466C509B0F +D077B49D87DD6BBEAC8C6C4197B9C0789025B49BDD9534F42CCF987DF9B04B18D19F9343 +A91696E0E206F4DBDEB45D6D7697B49C4FF5584800CB512611EEC8415BFE1983BA96BB82 +3AC3E496D9D79C6426B97A1455E070695A27E407CCFCE7472F147EC95134B89BFFB87146 +982FB4756612EE55A782F303B54670333FC04E707FCB84D255B05D52AFAE8F473E8C4FF1 +F6E95EC1B820ACD2D3E980A1B778C4568693AFD446C6E416C48A45CBAD61564329C4ECB3 +A98B4ECFB3551D1F1C03717D29A5DB62C8F1B21D036714A94CE536D0E84E3E10800AB513 +91E05C62F2A9FFEB3A738E3262E1919FDF43EF49842F6EE5D309FDFFA0B74FF64262AB5E +813C8042B2F450A5CF7B547A8383039E7C14567EAFCE9644DAB0A54249EDCF4C24EFEF7B +B3EF129DF5A11E12A78FEBA6080680AF4476F4C0AFF6E8B27B07D6EBBF5B1FEB28341344 +3154B99A65CFE335224F382137E3AC87777A6719AC1CA6832B61AE8CD6A1931105707F0A +DDA25615B526EA2543F6FAFD00D70E4091B6D5D58C9CD62B19C70D7469F6FDCABAE2A517 +66C9B0DB0AB351973A4E2FDFF81DB1651DEDB905ACC447FAB2B2803E90DF264C96092528 +8211E23246BF45FD1AC67983A7FD5B371581B8BED06B9CF8E6AA6C4BC84771219E7404B5 +6DCD474D9B859D1891FC2231869763E6B8F0615D7AE7B83260DE84BA39D6D60F50BA70A9 +EA8FAC771A0F0A745932D00C1328806D938CAE671B94EEFF484E5FBE9A74A97CAD47358E +A3CE9F399407407FC199677DD7BB6B7B9B00AAE6EA1633EE18DDBD40FEFD138F8423B304 +4B9E9AB192B7C767D7D63AAC804F0D5309E0FE72A8259BF12DBE7A215B8FC8460C285C4E +26067E3C558163C1622617B082C6FC941F8563CF4ABECD0DBF79CD5DD86B492E3C46D0DA +BD16AC96ECD6B41212431FECB4EF59DC7DD3071CE030BD5DE690BCDDEA9A2594C50CF77D +53B223EEA513B40CEC7005C4F6B6DE2D3680EAFFB6FBE0DE70E7DB5C11F2BD4085C123A4 +73E5CA0785FE70E38E081B5971D4C390A87CF5DD83C8BD63C4307D22A1680792E27FC431 +8D403102A052645B4AAA9BEEE578CA28E2C15DFE12134BCCB2171C15A45C5D4D8ACC0EE4 +A2C8AF801D64D5979E52AC410A69277160104A386D747814F0DC0C178CCC2BB40E175992 +9D3F05ED411630ADFB8E4E57CD223E012F457A8A7C2BEF27BDFD41D3B39673ACEB92A48C +E3464A8720196A60E21C1736066FD19154C02D7BC22E821C76F4B89185FA39B48B00BB85 +AE14236DFF7E1EE1466C65A1B4B9453D8ACF727CDC0EA04D85E2A4F41976E4833C145444 +B0465FBCF96BEA9554304FBFBA4C39ED11F2E1D9588EAC200B31441889B081775BF75B6D +7AA3055C85ACFD57DCBDDC12257F565F1980DA3215AB29A2545B2FEB107C91A454DD3C32 +D7D620943472E7AEB5805E64EE7B1D3582A2DD74D439AF03C00478FC35EC9017F1A37B59 +A31A196CFBC38B4921A76E41E3A6E2C0E5059FC3848DEBAA378D87736B01C6710B5B0DAE +FB06D00BE44EE7C687DBF6CBAE699D88694891A95392324C6C49595C7113FD6D521A182E +FDB264432F3B661D4E86766A7DCA2E53F72F7FB78A0C436DF0D516EED141D796F3591226 +E617BAE549DFFAC4CFA0F555DF7DFAA525DA35DB699A892B09E654992F99F89CED6273C5 +9EB9C512BFA0465E61FDE63D312B1B2758E645893A19C82A81E5E0F5AE8E51621EAB69A4 +1D425F9F78B47ED5CEC857DA012E641D5C203532691F9177F4531EAE8E6A7D5A2B1B374B +B921CA70F41E7F32A8D83C54AE01DC76C88A96C1403FEB6942029A86B1306AB096F8A42C +2D7FE35C7E9F3DD494579CEF39755AAF7C74909CF5F7322C4FFB2C5A196658B7AB49056A +E3DCABCDFE40DB0912B5E15BBAE08B72D7AFA7D64265F4185401E6E723E151EACB8C7494 +819998FDEE918EE491E4F9D5F889378256F2F7858762A5E049A618ADF34DB73540486414 +1187E3CCF635097AFEE95F695F806BA1419D85C50FA033E4E9FCC155849677B3A20F6451 +D8E4E5AB1BFBD967B5F53C21A30EDF1286A0E19FC557598294586D5184D1CDF8BC83594E +17333A522E32233DAA8A6EB39A6330013C32A2E74F0EB6234B63D47A4C8D21E1618E5906 +5EB21FA9A926E01A78A60FBD71808A0B75F65786A9E3E08488FE89E433C287DED44763E4 +F317DAE0709D7D54EA969B751F4C62AC976693FCD366804E66B2BA8D955945B86D492E74 +F17C0484FA5C45D7F60DB0D4578C5725A88A9DEF8E5D31EA02411CAF6F703AF96F50FBBE +6739B57D4C1C318FE7D491C94565DEBC43078303D329E87078EF9B48D66C3E98ACCFEDC0 +A31761AF6854E5C4DAD36C809876D93C06D91416770CE8852B5E54AA22F6EF1A5BAD532B +E4F55FE7E2AB457F3242030F443975DFB0F2CDCDC1BFE629C8BAE7AF2D21C9BEB3EA10CD +E4EAC54AC081CD3C0AA161C52BFAC3A9E4F0FF77563D6FDDE73E44E926E1BDFAB4B1A11E +2B4A7E1D2CF9D6B9DE48D99DF99E0DA53F5A449B344AB2ABFB94BE9E60E6E9B328B58337 +A4D4BD60CBCE14C364A2A1D5C02410C2E8A98CFF3A48D23C752413A4FCCC5C044AC99451 +20B15B31CC5C7B5FC6D80866C1110B45F9B274326656CE6D74F3481B7D5DE8E5AA907509 +C15914FD27CE89F911641DFD588812A8292504EBDA5645E8C510F5E88EF44C573CE46D01 +EFBC6E3E1BE9600D77210B10330748F210F2CEE4841940A78AE1352654139757283F0FE8 +12040846B6B24F1D96EA06CEDF19F0E3359C8B30C3986C2E20F5801C7F74ACA621E8C4B2 +4C38B9888AE24013371F19C80165522AC90C40832C71E617E042ABFA071BAC4D87D91F86 +4209F5073D3E54A26FC2FC8F89DE3C1B121881665D48339FD2FE7B0ABEF5491941DD26D2 +B379900687DC8DAF6E35153F409DD58DA91742E93CFAFD431EDB7A32FF814048DCEF7459 +830CFFFCF958160B1B54525EFC46D8892C30561D0D7780625B0876D816A0099AF1EAE992 +AAB126289D55638559BBAF487E1A9E2F118B3D498C49767B28FA680BAE464632C94435FA +E32836F8093885A91F66CD5070B91558616853AB410AABF0DABCC02BB85344751A2B2911 +3847CBEDA65616487A853D9104D0E00012F179EEB06D9EC54CB50DCEE655CDEE79F89318 +F8212779CC310304A2F604402C8EB99DEDB3051CD1EC0D03309EBDB8C3B5A89E06C49957 +5E00904DA0106F87D58FAEEB8581EB47E982E29C5ABEEC747205A33C7B05A0CED74C3403 +0012BB647B5AB617AC8508E8A0F254E102406EF1EA86DC39CD9335FC8A5CCB1504757BC3 +AC11BCBE92800AED15E84FC3A6FD8BC6C27C4A13AD946DBC65E45B3C1F72D4D2C1793512 +9CAF2C6C238F1E57F428CA2CA51ED139015DD06B931A9FD41A8A759142F50D4A18D9E071 +3CC7607EF0337C7B401CC2E47F0DDE63B32BC1DF572F94991D1BF97F1BC17DCFAB95A834 +E34652C6BD93277754DBBB1DBAB6F0158CBB6E9304F9A1B5DBB370C3EEF6A0F937A0C7BF +789CBB57E308D2D3EC0A0F04BC3BAC016AE4CFEFD4A5F5FF9F2289460CC7E6FF27A7B421 +BA3BA86F2A48C2002C4C0379D90B50952B6A629ABEC22143A906752E0BB2DA15C36EF74E +DB102D691DECF27A7C252D866640FE74BB7BD351C4DB5C8E4956FD73CD6675FC53DCAFE2 +256AC5E46FEF1D0044B5A347682FAF71ED9CC08F231605BC342148E3CAD6A80ACEECC89F +767E814046DE67F5277CD737D09A62B499DFF7908242C6E5F17987573334AC66ABEE66D6 +1C61D14C3687DBEAA7BE38D248A7B8CC775C5B577305C3F41BAF7C7D64B43E7326133C2E +795F50EF42EB3F5817277E2690C8785064AB6BC61AB04F578549BF671D88E113DC704764 +91AC7787C2561DF6AE9F3BA5FA24F5F2C49B8B72833D030536BCF0AF10592FF37E223065 +ED6F4BF075F70A7D0ABA84CA427CCACF9A0CFE46A429FA64597C677C71A231C997AF401D +07FD7FD98F4A5826DAEC4D76B2E6A8DF68AB8EF09A0A6BD0097840364FBBBD4B93950A16 +CD68B07CDCE7C341AB8647A3338B1608D67CEA47D26EB1ACC0F94D928F2930C2CBEA594E +B773548213CF17642DF03784B9293BBB8BAB745893C2CA0F9450A337E448A282A285867E +0B0A2F5DD49A23D475709131946B03E8C2F7B2D21DD7F1EE583B22A73D81E5F72136802F +D917750E53E63031FFBA218DAF8B3DBEC561581706AED8A5CFB6593F5CC98BABB048587E +C9EE27EC04859B6C233474BA9FA8F8D909B17705C6F2BA0CEF169B46497E712C458354F9 +F0E1B72581F18BF74AE06CEEE0DC27FA684432625C579A29843D44973D4BCA13998DBEC3 +0375F1C05CCA91819C3F7C7F2A240B515AAA8403230F9367CF391F3538ED5BD391E70F24 +51B6CA9F969CCCBB58A05FB86E90BA4FDDAEDDA84A73CD40617486DF08FE7985A55F77A6 +B2CF450665F98F0D173D0DFA608A4E89CA6B7CF2F86134CA0B97FE3FA0856613C7E71D9A +4389BEBE6C1DDF23A7D617ECF980EB78AC5FE99665CEBDF1BB8C1CF29C345B94591CE29F +3E77AC66C3A9A1FB34526A1F335E71FC1AB62B4E8237E80CAA0265FDD418322B068FD4AB +0E603448CC61D57106F1BDDB5785AF5A18C211021FB6F91AEA6112BE9F34A75C6C428EE0 +8101FD9904EEF19996EDC2235F3CAE00B0FD20331597B63535D001A5A2951F4057C83A8C +04EC71AF466EB9EE31CAE51F453423FC327FCC256D71D4E2D956538C16231BC8E6A54FB2 +85E7D5A967CCDA56DEE48109FA4776F87466F0F62355CA0990097B2BF7F947C0198F13F6 +EA5321370A9CDDD612DEB3C91766A19B4228AD5A4D782D9C51BD3DDF268D53C24F6E4543 +52B2780CC5906D6D08A27AC49043FC1ADBFC07ECC113D815AF2BB5922E42776ADBAFA1D8 +E8608AEDDDA45E181521E5A8C39BFB2E9E72A7342D641574D84AAE3D23F114E2C675E50E +98C0C4D59107E15753F2E29B2EBAA4D40A0FCB785E0F20FE5EC3F4C42AF3445298625AD4 +656A42B95D3F3BA64495423BCE66806EAD119E6F949E5E0CB7D20D8B218FF77704BA5CCF +C6B96CDE2E22E2A1866F80C103C986D01BD96F2207438F8132ADF46C5E889C2752458D26 +050C2D2D9996A7E90414880A34BF4F6F7EA862ACC40E6446C8C64BA66314493C05D5552B +FFD967B26CAFB3238DFB04A14757FCF34B547F81448D5BE2C385775093FA69D2B5264954 +7552C28488251224E4571A0537F87370D575C6093047374077BCDD8315E40EADF2ED65B2 +9BE930D5A78E0E4F21ECB50582FE1501FF48EC392D1717D5037175395D726475E79B5EA6 +68150DA75B9FA24A530FEA3EB4D2E4D73A66C800452FA1053CCEFD77046B058693170362 +AA4EBD8C51C334C4C24AE69086BA5A9AB3E8540E0AC782324DF007DA127A7CC2EAAB55D7 +33201140FA9B632F11D41030ACEDF37F12D4E4801645CE624BA973671E41C1A11169592D +CC529462D2047E2A5D06FE543E5471D0A0FB591A9D3568D2B642C2DAF22BFAF136DC1635 +11611AE38717F04BCE872368BA82FF9256AAB0AAE93D52A286FC62802FFE2E8FF98414AD +A2E28D0C07D95FE5C9B025A9AAD8A355710C6085D45BCA501AFE400EE1F9B34545AECCE9 +8DF25A6C7330711288765392C4529746FACD974BD8CB996395FEB547A9D674F5E56D4841 +32A4B48D87A380C52E05C86083677D88696CD2CA221E676C8F950FEB61CC6CE37D055DDB +83089B0814A90EA5B3EDF692055D7DE2208F5F5151667ADD999A0301E9D2A017634D3C5F +8B645C726D0BEE71D4098E0739B44D565FF574FE93A250AAB0879413C38763AA3B294956 +BF0649C5495E92262A3EE9E3CDCEFD1DCED80221217ECCD09A04B2759C746D720C3E88E6 +22174A8E496228CE9BEB430557D8AC5A813670400BCF93AEE40CFC554A933EEABB239B80 +EE603F1617B3238E4EAF043699EC674D348997BD3105B8EFCD06E55F78AEA6AFE81EF9EC +836F4703650D803CD01DC38094F11CFF0B34734308908ED646E5B37BB9524C886DF94F83 +B2D470752A139E6A06ADAEB559E3D5A1F4EEB78F896AAE3D9836D4C7D4576877307821A0 +DCBC61D1318B937ADB53865F9F9B6B90659DC518108B81196CB6E81D676B1EAAF9B0F3F6 +FB499A99BCC7169E7F37E9808634E2A0CA9DF40F204F86FCD7BD135D177ADF005B5D9D9A +0690DAE940905664994FCA90777CB9B3C4591FC0881FD146A41E9EBE7B8F74DD407642F4 +5BD399C6EF5471E987E01A009F532C2E66305C890B0B582824B527ADEDF668456AF3776E +4634332C59C3133D8581D47EF6B45B636422CB5FA0B117FE1AE0361B93CAD6850624F353 +FD41296FE84391636A2EF92A3658E07B857DA4FC19889E760494957276BFF9543FEC23E5 +2A7C9174B581D299B52DD03AE726A95634C8BAC12F17B80B3B40BF98BE848CC4837C3CFE +FE2E3B64B5A8BDE695ED0BA15451AFC5F0576DB1E9E9F29F05D4DD02EC3AE44E15171CC5 +EC254176D86C83C062B7206966E7F0A8822816251C0AC4A746F661897E24D2A44AAE93E1 +259A4C582FA34DBD0B4952CEBD2753EDFCC37ED685FA00E67C455D03072C2A218647B582 +F58270B59936EFFE692E0F27DF5D73AEB8D2CE0970629D51B9EB91C0D2712CC3BC71640E +9ECA1D662FFA06E071D1E013695854792DDD672080A0AA42657C9664D6D850757DDBB167 +9FF6A837674A5DBF38B2A435C2AE04EB86D351FA0CB82F0D5F00A96D55976B44D6B6BF5A +75346A8CD71230B6A44268B73188A84C47F09EFD13CBEB51CCF7ECDE43A3BEC6933643A6 +68B023344E407CB2A6055EBD6E75A27B6FFEFBD095828A8C5B9A14FD78AF99BFCDFB0A27 +3313455D19B2036304167E9F8264FE47E1F5AC04EC94FFB3E1D6C90E1758758D2E811C7F +DF1EB0AF24EF89E907484BD07B8D825B98D99AEDF1FE0D67FC98A0159DD6492503B86C35 +FDBFA654E3CF4B00D0E4E50A77BAFC6D4CD69A668AB5D0436E9A2DA573E04EF308A6A928 +29F21A8419FF3B7689590D3787B3CDAC9B6A98FC0AC7B06DA9748F5765A25708C3E9DEB4 +1DF4EFD5BD9E0C1090BA956EB65087F5FA803CE15BD0FB4090EA9DA33F86512A67CF8775 +BA3C3D834FA4D6798CBE5D5439279DD0EE083DE2026B2EFE83C203C632193D30D390443F +A5D1D1288C2B7395BF91F3FA657BDD688A562EBBA50DF28EA5834DC1F9CE073B704D2DD8 +594620A53DA722209A6C4A9A906B552B562917A86373C43132B5997CCDFCFA398C35EAB2 +D275883CF4C5AF773B535BBA0CACB12ADBD2B3407C8F046F1D4F391EADA619AA2DB788A1 +93B7F6975889D7676AFB6EA09978E9590E75F7B106112D0B62063A21DC59110EA5E123A6 +51F2BB21FBD6C80083E5B3405835F9AB6DE5A7C579F8F7B006983B897E4C9224BA21EF0C +DB8546D2F477D280F554F98AABF7F6D7E890B327129F4D43E3BE119D1E9B1D42FA1A7F39 +0941803CC1752DF5A9198AC5AFC71DD6402095EE312A89D1466307F0353A610881A56891 +4EAF39DB13B984A78C1B9EF169EF8781DE0BE7B20698502E8F81BFC06DBF766B3CE28A43 +4801EB4FE9703BA5933AC6F0872CFFCDDADF1135D02714C30D5F54D36DF3415F416D66A7 +EA918A64E00AF9213CF9CFC63B200BBB4402E53DD95BC8B5AAC20E62964AA87173563396 +AFDEF06AC069AFBB08D6600AA3A61C23682551F73B2B7E4DD70392464C439FA6CEE41A1B +4EC280388A8DF86195788A9B766DCB0E1AD6AB7A1C66A1835D7AAA8FC92741104C6A5553 +C149A5BEB648BD3488C13494D9661FC8F9DD431E9EC1989CA9B35E67A2BC9FED7BC3E362 +6389B29B863DC77F8ED314B47B4B86C9E559A6E41366D47672D9E9314B192833D3752C70 +3A571CF80D6F165C660F42F58DB5CEF453943C7DD0D252476F678E44C6340B7E4D52C927 +5855FEA030BB191D34FBF80C039955C2AC6F0C38F6FFE281A52F13B62543DF45BBDEEC7B +A2CC3A125963D1524EFF639AFD013A472B336E43E9256C3EBC5910A05F641EA1ECB98857 +FDF7613E9A3790F9FBE16F8B1E9CAC2829EC0B651F00E1B6B56F0025ED82BFC5FE1D227E +3DC00ED525823F310A834A747ED0FB5F5DAB7EAB307D0906AECE8AEDC3808C53C3C9E954 +6771D79028ED61CE595EACA42B6ACB8C47B1417F1E88391C0CE35415C9FB29106F8EFF96 +82843119AF94F798D7079D40F21B94BB3061C2155A87075846A62B1E1292B465E946AE00 +A3EA7C2057244AC8C4D54A8618AD7B06A833E9C26BD2BF4A40CFC7F7D780DF4C31B0CBE7 +0657FBF4AEED88152E1FCA2956141559002CEA98E7299FD83BC9BF9CA0523697D9E188AB +2D883665C329A8A4803C8E66072DA31E615FF9254BA8CD94A5C6CA0EE7AAFF3108F48D79 +0523D58E98803CE03FC53E71DF394691240284E210C77595F292696975A206A43AA7FC7E +C0CEF778307863F56016C13EA6A26299FF417E0668692ABCD895E7CAF13A9C1BEE2B1E62 +0DF960006550CBCFCBBB006257051D7254425C49F840B8EE5A44A61E5AF465A3A831FC26 +A8A2062943955676AC4D5168EE2464067C056B1DCE6FE780108953F9FAFB6F89DC775E63 +6E3EBD3308468ED7B31CCB4D80142AE342D630B919584B2DD67E904A48C5CEEB65C1C84D +8D2964A4842E8C2A83129C91662137BE032B007A30A0A4D2B31ED3B1F44AD5275FF105BA +929ADE2B78FBE0F3F34E2E9A35568D96214AC1A347510E8E5EF0C9CCF08798C5B0C09DC7 +3FE817E2BD84AF14627A8210099509770C680C327ED697A255B28E81DF6B512060D47084 +B8AC21EF59C34AA36A9D14A093116EADC45F3F64AB297E114053081C8D6B135B36D25AF7 +7F2050648799554FE6BB50CB6E957E26A0C62788EB76901B438AA6422118463BCE7AB3F8 +C21E007C21A9434A0294650543B58F0925F664585BC875ACBFCF44F5BED0D8AFB0D8FD6E +215A03ECB350DA054FE30172E920C34E64AC011A655F5A782178DCB3F65FEFE0CAA68993 +DF30FAA2471396F6D74213C38A511773DC7E84A9831C2E8C4B51EFE3D8DD0674050B8DBC +F1E09ECA5BBCAB73780ACB37D46742594C6070EDC7F5C555FD50044208F6A26316F17B25 +1DDCC694443233702745485F3CA188CD3E1F833C99ED46EE525D31C6518A86B723E890CF +DE3A834170507C9F24F28A124DDC734BE002039E81148D73F8C86918DE78E07964001EFD +9A3EE31A0347EC258360D2CA6AEBE7EC4D5FE0A29D415DD78A13B8CB8DA84AC8E480FD48 +F4A9440EABFD6A1C4988A7D6FA7146CBC14FAEB8864C578A81D86C61C0D08AE6D50F5654 +DDCBD02D7D9D9AAA56C417D2A3C42AE47ED81350FF917E7D5D390D4BC8AB934353D902AD +98BBAE982ECABC933FD33310FEC3266BB373AF3B53D8880A8106253FA48D78899D0E6548 +A9EBCDED56B39BC0FA78BEA9A795BE60BD3D60C1DDF5375DE0800F1FD55AB46B49536F7B +5986E790A4FFAB8B81B7CEA21980D0634E7B2CC00D1D7A9A7C00A5CBAF65476A714ACE77 +99795EBC2A944A688BC40F2A23DF71B3826654EA7646D2338BF23E216A8EA59AE50DF2E1 +D6A05A86C25EDA267225592F695FFCEC993CFAE93452BB3F2C17470552564F2AB70AAC50 +D49ECC01A418903401B4BC6F3E0D3DAA9CD062AA1A8B93016BC008924F8AA7075ABDC5E0 +01A215A63EC8A8F1FF0E7F5A1102D2D5DBEEDE248904EE28590A4E48C98B4E97DCA69479 +08FEBD5BD880AA737D2A600A71D1CC35B20612F656EF4C125ECF75DC0E1BDB57BB09BB26 +332CD1B9AD52147CDD30D03EAAD4EDF4C7C2E4092C409701BBC8EC163E4C660EB018B0C3 +4D4844EBB910E0566DF844ED250624A6C8BAC481B32024FD4EABA3D4E8A67F83FA4E4927 +A15D64462B3004F5610EB847E9413CE174D64908B0464A144DB43FA1FC8356FBBC00D303 +74E22B3EBB141575D6EA036CF0B469597C57AAAC00F840EDF201E57C0D84929A34108847 +E90C97352CA858A6B1F76E1C772C1DA2A8362D02EC7C112E8755C7D720AC5A2BC528913B +37E0BDF15147DE30321647D8001FDCFA437709AF90ACF0E56196A9696C0054E67BC6630D +7D99F3092D8DFEF0C788715D9BC43788542693045A485D5231D731EA740BE448DBB72ABC +A34AA5B8B2A4EF6E91F61B0A8AD9666808888DD61A09CBF2FA30E812BF1B73EE2D387C6E +4821DA27733C60795C8EA0E806F74601EB9F3676284A37ECE9495CB87015F18DFB39B9E2 +93303261BE268AA644CC7793A6266C026A06BFDC3074E7A67C8F6B35729CE40D6C343C4B +95EB9C778F6D513CFAEBC5FBB8AC844D1982F300675B0920C098AB288D12423A3401B6BC +CE7725E619706B6241BE210CE68A5B3F068C7255C6A0959CCD3AA40627230F27057001DF +328A741F867833911AC3D24DBC1C79462012801A6E0897F2896AD1B5345F72BB639C799B +FB4C6EFCC57760C82015F6855099EF7C5DE59C5766BC6DD4F4A61110E8CD93BDD891A83F +D8DADC0AAF16032E8B02E69F1EF25EF7CA8C23815C38F7FEEC5E4A4F11BF1E0C2275FDE1 +B29CF45A585F47962E6137150F0AEAE31ABAE6DD3D66E54D8B7E6707445857348F6326A0 +9F403CAD72D93B038C91B7465347160DE4FB2F2F81B4BD24449CE03BA177C8E13B3D590E +A6F4C5CE396D238C642BAD4C5BD4C0B2EC8B935BF9D9A85F64D867799103E285264A5F53 +CBD2E0B0D69176ED284676494369C38711ABCC23E61961F6B46C576B407D273EE84E274A +E02EC5C8923ED2D5AE650450F5A1665CC148AA0FA6E26143BBAFA846E9263E49C9ABA1C9 +E4ACC9A7E6ED0865B42023F21A1F234F485C4F22B58925B336BF883906ECA1000F456773 +48250626716520CB2CA5DC9EED93F694A1CC6D7EE74CBDC660E3A033EEB0CCDADB32C5FE +9F5A4BB9BE18F13A6CC678213E631916E283D5B12DD6B9926279CAAF46A469CC3D4EF950 +D701A667C2BFE15292FC3A2ED9E1C916B90C9E25606ABF91FE44BBF18CB230EAEF6B0C30 +3E94C24F82957557840C11F4845C7F2C49337CB588FB9791EF1C40D4CA00CD5254426E84 +391C265D4B21E9FA474843065E306BF794BF3F798505285246B906CA4F343743C5539EFF +AFFF1F93CBC5DBCA989E64B2133EDC8DECB05FFE150469EC1433E3A3C0B49B7C14EF6069 +CCC488A1AC96C39203C010647ADC1BF32B69623D291608BBEEF2C5FDE603863C91029AE1 +B6287F8576F73922B5192BF1B226ADC2DD17D98B8D0558874DEBF7018C82A9E9AA9D89F7 +DE237D1DFDDE2BD43EFDCE2ADE67906EE2525A667883685DCF78BCBAE353486C96B3831F +C1E1C7DF12DDB8CF10895DABD16A1DFA87AF1FDF8F4A6DF019395D713269024BA721CA02 +C1E2E605BED8AB8C822CC84903A7E5BA090900F1A409F4B1D30F740325E4995A5C9FFDAB +1B8480D7B5B8CEE4F35206E13EC960650A2C1D0C4D7D7407A86E583EBA40267A67A8E87B +19D41649DDEBD7A73593AF94C2366CCC6F81BE9558CCC90CE95060ABA2BB508467640E6A +726ED96B571CE6F2AC68EC104D3C2D3AD54F8490DE638B77C93595E2B1A44B079F79B487 +B92C12B16B203F91DEC2E7183AE99D79DCE4BDE5B240767D52438DC5AED4ACC691683BB4 +3D2A1636C917B6E270F309D3B75D34FEBF8BA64B01FDDD848D52C30FFAEDE43EA21C9ECF +487A31ACC1B1405E615C9DB6A9B96BC45114E20FAD0CCA71B410BB14A39997E9653FB11A +666995E488B650EEA712FCA7206F5228061BD5BC385DAE9CF087449EF683F69F673F30C0 +33DDD590F086EDBC3A72F9B17F488E2B36A381141F355AA1AC81AD4C103101AF96259CE4 +30A0612CA3110A5953666DB362D982687010AB9B81A63256AF6E69AF6D8B3150FE860D29 +E0DE5D686096A3D523EB8CEB214DC73CDCF00D2E98BBC713C6D7883AFFA02188A5E8A8C1 +007EEE1B185AF14BF0D0E06BB144660A5891C8C7710B2B85CED49F14A5D5B028A8FB6464 +3CB3B42D1EC8C334D51A270A3A2D483B223C3D95C733D79A9EACD97F7BB32D28BB381D40 +399F0B9BF194521F189D37040DAFDC8723BF45FAD60D2527503894BCD4B0B746734915F4 +F5B04D4E5044631F40BC3758DCBBB2A2AB63D7B44EEED53991AFD2988E13A7A6C389641B +32819144DA32DDB3ED45873E6BA0604A9E682558C0BA2B139D29E4986037AD326BDF4079 +B6C071DC3607D52DA49F6BF8DCEF6F04C4AB860D660BC30E758518E16102642A190F89BF +D0078394DACB5052E74EFEDA5BC176A861D8C5D78C83A46B4D5230786068F12BCFE1E73E +4F7865D5B86144B26AA5490F229E6FF7CC5964AEB6631B08E2A4EBFCCEA10488CABAF2D1 +576155E6C862855CCF52C74834BE25DFABC0BC4FB7A1EA21B2AAAAE45D1455D844C6AC2C +C57D081149F6E40B1FE620B697424B85A7177F19BC63E93975A08CF009C4659EF47A3680 +488C43751FCD7D848FF55C472F02029253403CB04872EA4364DEE69934F6D049113FEBC0 +E3E5D978CB8A2423B9910E3901981DAB495C4F323C3E3036BA45B66BCEFB4DB5C7AE91B1 +7A4A956471BC552A1C109EF67D97069D3DD5663063262FF4270CEC1079BC4C4C2AF643C4 +FE0B5F3B39389C104D40B84035710A59AB041F67B5FE2E5D3CA3E720D1C7A3F104A74C05 +DAFEDF29777AD6FAFCEA4854B864DDFC878DAB7C42CE153FA01857AC1D5B1990EB73C82B +A01D3557E10D14742444761671084F1242C9D2EE9E211465F5F8F0333C77B123D6C03A92 +D0D8B91822D6E20DAD190F4D7A1FB12418D6FE63A2B1148CBE94328ACB42845E27928643 +444C3378FBBA83ADF56A3DF9ACF9C1F2A8F3F2F3814E26D9DE7494E2F709A57E373A594E +4F64FDFDA6BC3866E3F7BF58127F6337165826F3D20DCB22EE9D7DE5CC14D10DD3BEF093 +2B0D75E289E5A332700C2CC5EDC65CC61C592E19144A13A38E24B1FFF7F904CE261FB76A +31DE7360290C8B750D92E08A25DCBF3BE97529DD52F004AD59C6721FEF0EA46F1693C5D0 +992C517536B390C86F5E788995B35B6311E6EED72D15594717CF385DF042F8515455E808 +C54A0155E58D4277FFFE04CF0C16E1259F39E84292F592BF936FD50BE54ECAB54BD27CDC +4AFD246C35D901882765CFA13A381A4F888462CA5A775DBFCF37B864AADD8796ECB2E13B +4156BDA78E6E7308F3CA382B478A60C441B09483E6CCBD51E02E5664E8DEC087AAC030D1 +431A2301C1034BFE73EBB7F2744F689D09F424F22A48960C991526F7063B78EE26D0F997 +B917DBE51D7D291F54F1C22D3E9F9B8472CED7317B6E91F4BFD2E3623D6F3FD2401BA7CD +6F93918D2D629AB72C4060B6E72AAA295F0EAD79B0A7C651D5A9FE6348EFC9396664557C +0D5688F01962E8526CE7A55866CD56847F49BD43A674D6C22EA7EAC1A4D437D2A9BCFA53 +5361CD640DFE5189DEC2AF088359B13C6AE7027EA51DD1E757DFDA89A9BC23BBC1138839 +C549FEA71E42F497440214911982F115D3A9278D2119E0A17F0BB1F8A86B7A776C3EB940 +8819B2602C66C523FE07DC9AEB0E6D4AB6F39A308A6E8F755CFA0F41796159FC55B3A083 +F28494B4C0FC25322D17E6083E79394BA1F444CF84E5DD9D9721121277CAA3E0E380A7BF +93C2335695E2F34D05CC3C3FA3322A7C863A16A9A5AD4BF1C629BEBFC20FE361AA2C6CC4 +C0D3EAB00097D9D2344B8772B049CF951DCDB1C23C138B2D7DA551A22A53EA2F604D7BDE +8AB2D034ADB57A65DCA8CB55AC778F9649BBBAF8E7223096CDB9780455268FB9CD379AF1 +DDECC2F7C22A25683BA56EC7AC869150810D8A6A5B854A78DDA6C21C9FDBA227E26809CE +FD44A8E4593DFA5B9D170A19B9DC779F507FA0B28B5C8E3AC017005FDC519E8CB69B9385 +760AE1A8A111E763FB0C3B083BE1F083AA14DF9CC83142A1DFEE5312097BCD8DDD91F113 +0A3B920FEC7E9383B23F7A396BDF28BD1EBB48934BC490D133D594021C256B698BC4E93D +1E746522E485DD53C1B7980EDF066F7C7FF9F27FEC20ADDD1FEB09CFC81F2B0E0820B90F +FB40B66CEA152312DC5E7F8CF45AA0B45636859EA9DA112F76B714CD83CE2803D3BDBBC0 +A3FD5EAA7609A1E4A82DA08701A3AC0818DAD502DECE3A5C7D9B5D6DA50F8535AA1C3C91 +A9358EEBDDBDD94AAF1DDE610E9036E1D5E1F180D426A8B33B4E640BE49073C4B0C0639B +0A28D6E08D76DCFA2F4B409EA1EFF27437809073F29FED0E64506185022EB0A5F9A54BCF +ACB0F2BDD859222546338939F73C212749C36D6B0E9AF72EBD059C3838FAC738DFAA69B4 +FA87CFF491D877DFBAD90222DFE9564CDA37E5576BD66F635720F398EB6863C5143FDF5D +A4F07317547B86C5B335CE05755AAEEAA8A927933B252E82BEF3DE30DFDAC82D1354CB63 +028B03BF59AE93FF30771BC27B186C7A9F7AFA7525F719EC5EFAF2526524BAA29793D5ED +C1003A42ADC2A344D0E4210254F2DD33AC58649887FED4080AF18554646C01BF9BC54959 +D0C06E459CD818580444E37BD2852F44C8D6FA18F7DB6FC15174524EFDD0BC9867832DB2 +F837374BB8C9031A27B17A386E6D00BA61D49003665E1231D79E05EFF440E48FAEC9CCC3 +5985299B3FA94586B516C2317B1AC9C91005994A84466514D7EBD12AB998D4D99BA37C73 +EE3C723217B4D9BD5A0AAB12760886A8A99A4AAF038EE5626035CAAB42C6AD08EAD6CD2F +0FCF85C2CE2D6150A559250140D19610DDABB115D625C17455F928B55F762028E49E4769 +872B96F84031DA85ADE6F18D601F6D576C9CB68B8FF011B13DA0DDE4D6E35E5A3E6EEB73 +248161764FB3B122A4F40ACC83CFC073D4657C042248684EAC14C56615AB156BD549C964 +C8E5A5DD901BA9B583B4D176FAACDE48BA78601EC7BBDF45AC7319F7598A93B68088BC1F +B6B4F429609FDAAF3235BFEDF0AB25B6D2BC024B533E6E300165ADBE42C890F17B9FFF6E +45B5BAA3A14FB36D26E7DE60CE24F4893BE0E2CC7A780BEB1EAE0C6AA0EDCC3BF991E5B9 +A6F98F5F5428AFE21113C1D8DA34783DC47969B9669EC1F97EFD43FAAF5C02FDB722840C +108CBFEAC5E0BE99AB3E21CE4E622DFDF8C32250C10D68EB0B6788E5269479CC441B32AC +1FBFC5660164E498713F6A2809F1BFDD79E8340EBB90481932706B378FE8DE987D5BFA1C +B688817968E797903E558F8C7D0DEADA0B5F08D3D9D27C92E4DBE0F123261737DA41C264 +E59CBA14C0F60459CA59AC58D1A766EABC8E5CBCE3D94E1779099B56EBA27F5263DB950C +ECFF97261AC0BF39C4364FDE7BB1CF10DB8C3EF5763BB7976815D78C6F886ECC77F92BB4 +46D284D2948A94FA4E5E59D104858DD3ACEDD4088302B71E6A9DD709D47DF40DA7FF78EA +7A1E226F2C24E73D292B63100F1A6C98548019DE887E739A4DDB4E1D0676967C64723EF0 +F1CEDBA21FF8BA11539BA9F93E55FA54B3DA6B81C50899ADE4EF9369DADE1FA36E2A889A +A3C22215AB36718E57BC68FD115801B35CDCD592DB87FBDD9AB399896E4DF414835FCE3E +EE36D6ED5672E8113B19913958321650C8CCD69DA0D9D7E9C0607715534BA674118C8BB7 +CA7AF1A57328FA73270221F6A2D429D4424F1C13D8CD7C6FDE11B2A119C30EBBEB1DD394 +29B266261E39BDDD5F2446444A9AC581712FCA7B9073E1F4BE450445FC14EA0352D7633D +75C5C5F24DC0C99B888707A6E9DE9927EAAFF533868CC8ABF725EEB94A96699A0821DCEF +BB2A1DFD6D566446CF3CA7C80460C0772C5B7D47BA2D601D3EE74A5855AF4A35649D7DAF +0A87747B37F2B1BC2E13DA21A70EC7D78831B840EE91B89BC147C1A58DBA58FB3749F3CD +1216FF6DE2271EC85C84D07598EF77275ECECBAEC3C99F7686836A8480BA6BCC30B555A4 +0CD5506DEB52F16CC6B4F7FC8B2D8A508FE947505B6C4DE055A188D28FB639553C63D5DE +2FB330ADD822C7206651DC5E0C5259E6F3F489C0D57BCEC574BEB3E8CAD2BD4FAD239B9C +4E6C0F410805E831003F27A569B327A52A5B72446F83813FB2230FB670C2DAA0E36876E8 +82C612BA77B7C486DAB6B41AD9D41A5A8FA66E116F48F8A4573536008C9677D75EA140B2 +C11892F86AD1FC350E49C55069284311885787693154DC010F49927AAB51AD8C816BB00A +216DB9AC0739409ACEE53EFBE5429DC7FFCEB9F54909649F1CA3DAC3B450703DB8A4DD3B +170969E3381FBE10637C9E69A646C1E58EE791FA68E4350FA17BB704AC1C746591B940DE +618B5ECF8FE03DA7E6ECF7F208A004815161E7F680AA7EF1001D6E99526DCC4F9E8F7754 +A56EAF46E1E7CCA21E319FF7E44D531E4BB04B7138E6F6A522B58CCDBBF09EBB18287550 +66CC6E7D2660B9DAEE62164A62E49684BCB64D521F6062904D26D8DB101AE8733777CA16 +B20066E6E88C7BFB3C56156AECC89B449912B0C0F362C949FF0503D9C349003284CAF806 +952AE72AF962F13CAE5A87FDFCCEBB81F154487B260229A9904C44F027C776C4FA9BE776 +DD6D4FE4B8D8C9F52897F843CFD2B14BD3FDE0509659E8065F6790F2C95EC56FCFB366D4 +582422CC5011BDCD3466235BA9212F14F2FA0F377DF05784D75F45E5F863A27879B9BF1F +DDA7916CDA88995E2B52F93A7433CCA2173C1B3AFD83D736D4555A1BCDC83740E9E69A11 +9B5629B03F5A9D18047663D0A6154C4772AFBE9DB5DCC115263D91F95DF2CCA51A4A655B +FB0B99EA0BF628C0FFD5564E882303DE00B69D666F3FE93A2F2358E3BB4BF60B6F89A7F7 +9421015C3B64A82FA30A92D62B0D3564ED96AD8C228A30F4BBAEC782E3A01DF417CF9F5E +8B7BEBB8840BEC912AB7B35BE4EFF43E8891AC25F57DF8AECEFF1840C865A93FD1F6C3E5 +F0E48AFF008F52A23B5F3ED5612823AE23E084A84201F9BAAFA5C1D6670CA499BCD92FA3 +C51C0F5C2262941FFAAD5B4317068E78A1215B8F32E60E77196008D95FBE342426E61DB6 +7DF41434115C10B5E04DABD307EF04426DA652094C53EA304AE96BDD6DAC136E1B0913B4 +6874CECD3F1EC272BC4B5A3264A7C3D8881F2415165383BDAF1DCA39A1C53C3BD45E1665 +16EC26F583D1705592AA862D75CD754B66F0CC89EA5A06351BAB9FEF4A8B592D636C23A0 +7D82581D2E972AF42ECF8CFEFF5168695E998D8A756FBEA0FB03FF2FDBF1A3979767E0E2 +A15F041CF0870AC7105E8A2AF5FBB0E00F212C0430C407278400139624895C0B67AE7649 +207A1EE4A781EE6AF39E8C4A77FD75DB7992CB90D9AC239BED5A56105ADF5E224525B4EB +DE5D43734ED2BBBA28C8CDE0334C9393DF8CCA236FD8E15D5D970900F4DB12C02FA5E2A6 +837C40C097B24942820B116C7693B43F0870BEF05AEB81D73E2CC42E448712D37C22212C +280E111F738B765A74DF533182178E6CE806AAC22F5E270E1CFD406902C45BB6A58DE01A +9D75F874C698BD4A9EE40414A446B6E49C8D198583D4A0B51F8FFE1FB809B8E7EBA85242 +477A9C0AEE9DAA8F7E78A5B73DF068D38CE0A7B36D857862DC2CA4C0FAC20A0B9F7F6BCD +EEE7EC90079B59F46B7A354D1A8D6D4A71DF790E23C4E106EAEC1497DA2B5E36F3EB9E12 +4D049B5E3D92C68D388E1D9D8749E93D2AE063770EE9B9D9491E62223949D60B11AB8C97 +A87C3CD45D13D1B033272698389E80746211AC1E09ED156F7E3AAE2016B178CD4ACAB399 +0C849249133D5C2F855D55A31697C551581953F622621231DBF209EB003D04CFD33BC791 +7AA01C79C2AFCC2308263D0B886A9524FEF38FB01CC278A73A86B06A0467F6A8E57F488E +F20C22BCDDF368A4322F629D81680312B763585EADED366B810A95977066B421D630CAA9 +0A18AE200329931AF4A1F4DFA5830DB32425AB3B36A023ACD186B4F51AA3D021B44ECE3A +042C12DC54CEE0B038DA451724D8DA69CA2ECBC3C9E986263ACB791A659174BC940473FD +03CBD870A2079E225D78D7AA550A3F42FBC2F027F184F54903A1DEED269E6F2CEE48A7E0 +E9DE7018417C65A6DB9CC89A93B1297981530C330F7988161203354F17ED6184EC023C95 +584E45E8E88836C5263398540DCB7EEDDA5299BA8CDFC93E39287F425DB852EAC42A88CF +3145792AC6712403EB9BF1ADA24CC204F9757B4EFFACA94F74E5CB546569F0C21EA5DC63 +6A7C20A40C6FFF3B173D7C64DE1D6E47AAD74AEE3B27FF5E577CF3BABDAAF91BF166FE00 +65B36A224C4E83252D7820667A3D7A1EE57326683285F217FC893C374DE7F859DED7C50F +AD5A30931D50E568A12C43C746018C1C35306EAD324CB66B0F747BD24023CEBC636F21AA +B1A396FF13A2ED3321EA129F72CE2E2B9FA6E00CAB30CD5E8DBA1703962F33E9FB3CFB01 +E91BADEFD13500034B926A667F48ADC59A4CF6D07FD4E7EA96417B25B08FC1F284EF2B3A +D0A720A95E1AEB3834C453ABDB93F78CA55544597E02CFC6D818423FA15D5D7AA96D9EE7 +6FB33A9A708DF038B19E7ECF0E068B627C26E5A3C53DFDC0A9678C8AFC496078056F8902 +05A38FBA09155052F80832357B84CA86F3B9C399410FFED89BCAF4ACD808B6C7BE343571 +DD2E812C5CA964B8933141A33895804CA34F77074785B58913B2CCC2445B0D54F4D326EB +E5D8307C92E0AEBA068341A5A14D3AB5AA38D35C0C020F3AB33608BB9C7C28F7BD1022B1 +5ACAF78740EC7DB4AFA3F8917D5722CED290D5764E7FDEB6B0E9EE78A8E51F4F88FDB506 +87EAB486D0218B9DC1D29FACFB7BE25F4D85C1E8AF20B039E23F1E92C79FB13C7EEFAE44 +6567C47AAAC59487CA15B65D3D14CA2D8AC17A8F3ACD19C7B58C2BBCB22DC2F3DE7FF42C +A6EF389584E4F59CC35D84EF94F3ED5A604DF5CA83035B54817526302662BA6DB7202638 +B4BC47B6E907B0BC3FCF31D06943FF8E04C1344AE04F96583A8FE674A79615A76807E1F0 +FA1EDC93A9538ACBA48C054B4087CEED23E7B4F1750A7629C333102F38001A7A29DFA697 +A3DFAF60BB89908CD78AF393A469E54A41D31CBD35D2BD98E5C04DB8ABD7C6AF6A47F51E +2F9F4DB3CAD40A85C32ACEAD6C196981E16F90541929DFC9BDF8293ADDA1840EC116F3E1 +191AA907CC72F75FF0923BE2862199035CA1CD4C423171118BB8D250B5897EC9C2AB8C88 +D7FBB99AA99D6D194B33A9152E8C1750498EAAD12C4EB45C1604FB747BA3FCE8DA3EA4B9 +6861CAB69A1FD8D04011CDE1807BB405DFC1482CB2ED7D3AAA1F8714CC8163FD8F0B36BD +31AFCAEA934265898AA67B80877BDA58F3E701F78CF052AF02F08D3AA1FCE61EA12D53E7 +022B3824A1B700FDA87D31F3413929CC5D1D287B2B5C91F82D9F6DCBCB599D19B4220E27 +C3AAC4F0999C1723924CD7E9C06AFF56F27054FCD334BD9567217D5BB294CEDBCB77920E +A6FBA60BF77B255E5FBD2BAE7AA22D0AD45C8322A899C45D0B12B3EFEB4444B0CB284019 +33DADF209B797C0F2E77AEB82AE01F09E7897905A43ACB91D64BC3DFFA88A52F8FE2C901 +78A045A48573C28B02782D54B9BF615CB5FDD714342378CDE02AA661A18893B49723A650 +308A721D0D626460AF055C356B3503F6B4CAEA685B1495CF6AE66D14CA45996137D7E173 +7B1ADCC54A6F30E1E270F4507D9B4B10F647320ED3595D6C1B077C8DA047FE03665AE73E +68A82F78EF7C1DE60427BABED7396E6C412E44FC8D98AEA402C00A784D3A3FBC7793AA8C +C87A07101BBF6FA2C3178D93DBCF3E00C95F5C0E2ABEA7158330D7EADDECD7B5EE420BD1 +C4C40016AA88FAD7B44B6DCFD9729B136DD16F7B54470F0FBD3A671A13C5DA0A52258636 +1F2FF96985D9B5B582A1B0E51FF2A2BCB8EBB5018DE067019B6C3DE3A052440D893BE3DD +414D2FA37489D3E34FC6E97FF94D2A2CE6B460498B996D2E21E2EA92E937E68AA000BC8B +9349E5DFDA563D70EE336C181E9B12FCC65C40A2507685E03D2D4EFE013BA6D6B36D5D5F +03E7B0920B195FA23FA98993DBFC8F7DC4B7C6BC72C8280C78C150B99604C93323273001 +6078600837D5B179B1AF3FF5692963612F93A8BED3B2630E9EE9738B5F016B0D42D908F8 +9D67A5555DADA0529F1F0445FDDFB01953E264DD3AD489AC710CBDCADB39A99CFD9A0200 +2CE7F462BA691742EB31B0DBDF6F7F26FCEC9BE173A4D78CB40332EAD8A1793F70598EF7 +CDBEBC02F493DB8C654994F6150B43FB49CBB5E886A515828E25F83C8FE14E782C43E332 +B351A8E68094839AE4BE33E8D026CDCF79995EB0160FC1ED53C1835909A1F51407181A1D +82B529685DD92FE74A21862FEF7B2ED4962A360BA825B08E961380522CC75BAD11FB7F6B +15378AFC8BBE9521854926147E47A08D728CB679330AE15AB75213AE7793450108837607 +F592719EDC0420A2D9CCB8A9BD7D58D9C7E4775B753F2E928588DB470F6A23378968AE20 +380CF35131CA742AE80AB160434F7AA2A88B2FE42F54FBEDE83A99D5DDF22108250113B4 +34B8C3F8E46D57658C37E229B4791CDF9B2E2C5CB26A83F4B71739741EDF475222665072 +EEA39059AE36739F8CE47842BD9CCC13BABCF2888CB5AB13A12E83E3E1D0BB27C879D435 +684482F1ACBCA88855A0BA49E685B8EC66ADE40A153F64DD355CEFE3FA55F78E499A0303 +45CD4B0471B73FDDB5E5F3B7233F6204EEDE30D7DF03617F267636A4276F6EE6D065A405 +03081E2FD97C1738247526B2F1E374665F400980561ACA6BA65076EB0A23F4955268851A +3781AC4CE6687986945A3E0AFAC73DEDB76E2FA23BB33E094DF1FF05602E52A49E1B510B +5562EF0D58E45430AF43EEE073DDF0EC00614C0E2DF121C173E1ECE36B4D87D0FD9D13B2 +75A7C0C8F9B62B5032B77C8909097B3D4B7482A3623DD75BEF4EF27EDCD3E91F628DC448 +4E15D7D633B3415402E48B1B577EFAB6413CB65CBCA453F5EB78E778055798816D895A42 +22EBC77D51C992C56ECDB984D5DD94BFFD01E3EE1082F6D189E3A4D04D6FD2C206235A44 +2578CCBA9CF00D7D2CFC3BDB2D6CAC8AE35DD17F39E0AE8D0A84AA451789BF3C672F7F50 +CDE8F58C4AD3251B124722AC292A11FE426B0B51B2EE4EC7C65103F1128B54820C458E09 +7376F3295D30ACDD561EAD278082B7FDBF592F5261B0BA27A71B8474EC2815A8E62957FC +FEDA68BA3300AEBC9FCC1C5ED4ABFB2B91C08AAB32BBA60A669B9BAF89524FA6B3B63AA4 +6191B699D7DC81F8E21A990BBB3F906D4F93C3CADD734FE6BC866DE02D2EE1D119A71565 +752224235EB79D3668084A41D7CCB27C48595EA82BDED902BBD71818547D4E755DD372A5 +276B2EC7C66F730F79C111AB99493BF93BE7F252EDDF129D8F7B7DE6AB41E9F8861AB866 +51F4D928F6449852F6FDF2B84E2D8341D6E7CF35FFA7CFD875A02F83733D2F8EA7FD2448 +7A575976B07F5BC799DB0925F0D6967E0C18DD80906639AEB86B4098A732C969703C8DB6 +E9F1E849E75FC37714D4A745A08EA4B374CFEEEAB664116D809AC06A8B3FB1DF8F71BC8E +BB5AA0467A728A6446768BC45F128D5EE2596FA35BD65F90DBA5A78B5D02E2FA2EA43FCE +1D2987C8081EC335A63ADA5DE5F6A87020AECCF4ABE0D17D4AFFE79462708D14E3A5820B +BA2663912A5CEFBF01788B0BD19D08CA965E30C9B7FDD2B8156F23AF2653BA4D42E6AEEA +A4A812E561FC68A7316634CBDA855E683AFE67ADB8632345B8718289DA3D1F0B00234049 +08EBC15F22DEB99C37280695EAED4D3EDBC084D9FCE7214B85788B6DD81E5AC6B93B47A0 +4BD833CC79B0AA2D4FCC9707874F3C7149F5F751D1A52F59B014E604984C6B2CCF869B38 +A045E50B957DAA6EEE0A74305705DFF1D7EC14BA595E5EEFBE93903DD31B977525AFBCC5 +7C31113400041DADCB603614F882FD78B88D6931DC3FEDA881B6FE8081110CB885B8EEF4 +58DFD7D303B413024A16D40FBF7792785C2B5DBA567798CE9C99195EF294799EBA4CE802 +3D6B0B1C344C90002AB158D3617EACA713F48AB12C062E8BDD7D7C5EBCA6617547A915DA +48C5497DD8439BC2C304AA1ECB709867EAD1B4E37305A3FFB1A8E9D52462C769CE6928CD +CE5521F6C134C61F08832CD620385D38CDAD88BEB32B997D9C8EEFEA6F17135A47116412 +3EA3E64254752EAA4745350ADA708255901462AC021792ED74770B031C21C58A7F50A32F +ED93D45E5D9DCFC27891989CA4BB010E2DF384657530B1256ECFB2613F7FD59ED67E5288 +048E5994C2EB3DBE5D9E77536B967D7DFCC87376A5075C7CA33B7C36251001F0501137FB +62E0D60F991CE5E3992C3EA4DF89FE2B75048B35B95C5E6EDDC4130FEFF7586C58629AD0 +752666C8A3A1885096FB0ADA14524AAC57E72F66304EDF923F2547D6AFFC0823CB5A8EAC +CC46B4786B46D611FD42D633818CE9A23DED24AA2764AC6AE7884AFD1DE22A63AD5B105B +4042B44E44E8A5ECE975FFB6D14E1BF1924F4EFA0D0DAD4E2CA0F5B1473F6D9A7BFD42CA +966B065D46D3F97056CB9BBA064E62E6A1CE5836BE83371BA46B58BCADA103A2F0E72F68 +E361D46664551B3AD71FDCCC221DE21C3E78C33D597AF3E533EFCD4573E0C2EDE28FEB42 +6D9B7A423ED593E57D7D5FD7C5D97D0B8AA3C1B1F902E89201E28EA19D0D140F8DBB4BD1 +A62309913048A6A82494D26CBBF9DD4456109471043BEC23E4E3D52BC1A33BD7DA7CD67E +D13E738B1FCEAFF839598F54FACEA0EB1F7D3C5419C2BC588B16A1CCF8814C0AEAFE671D +DDB96353D32D1F86191490516C461A4666235CCDC5179B4324B7936E26916DA037699EE1 +622E25173E9E1286306E6034D667CF1510AD4789188F7D0772D2DB127665273683698804 +9B9EB1D8A2689D5C46B5B455492FD96281133AA54945D039BA684A89ADEDA43A9496F996 +EB442E2C020D4EABAC6750E320D8DDC7256BEADCEF54E609B20DF4A6E39CEED8B3D4CA98 +0FF47314CC3A3A3E978C4F8911D5AF92C7A0110902A8F5362DB47F19DBCFFB4789C90A34 +8CFA880D4CB23D284C57072C7880B016C2F4338288D32F641EFF0E1F2D04FBEC6D02C61E +B27A4146B19A5BCE213327C003B1DAC40740AA1E9FB73911F3777FD976F90FC42D91D5DB +7ABB08EB6A5E4D367DAB5B31347A726FE7F04854DBA180019823FDFB4A44479DC0F84952 +8BD0BFC0025117A8D6B36FA9F88A76DC36E4DF00A2E3D2BDC2FFBCFCA12E3F4CED77C1EA +B2AE53A27BE8D1E77A618343F6673CAD03754FC14543BBA5FA50E1D7A8DB2646042879E5 +0D1D259898D91048C8B8B0D421C3FAF3E875D7FA4D7EFA088B657442742D89D0923577C7 +7ACCC9D8319DE2640A2422AB011CC520245A59A1D86CCD5F9D5616A35BA2977AC7686BAA +AFE1A277F407594D6A60D5231EA34761A78C1AAED1A1A6AB100535435C615B8D89C4E078 +829B475470ADDC46331469053DA6B4DAB9F0B0344D97B744BBE1962200DA293864FD2936 +2A6F74DE71CA9A5A1A6E697CD643D33B89A7314A605E54CBE1CF0EC3AE3F11982EC3B0EB +5D9505D4BFC7402D6539038C6D5E0B27620F7FAC514CE55B230F9A7AD528ECBCFDCDCBA4 +AFBB51CBB1F892545F88C9C5AEE7D3B522ED35F53696EFA39D72B734086CF673DB0EC924 +556F1CBE7D12A8232E51F563E848D7C9170A2AB0AA5702DCF43AC2DA03403374BD85E3F0 +CBC2EC8D2A823A8ABFAD7FE39742DC1DA40DD0AA6E5E1CC84B3B80C909C2E6E01659194E +592493C1B1D39EBDA54FE9E501BC06D9F2D5B507B8A6A5A9A56DE260459DF378DB3C5348 +84C391C7BFBB36216286796C176220211850D52596BEDFF1455EB36F869D93F275BC2E02 +07CE5F8E5F07ABE7D6B59E6533462CED7C4288A61A5AA7E206986061233FFF0CCF6EF957 +D9FA5B99FB733BDBB3BA0C66508E483BAA1FD689D51B5175533DE2614ECE76F9BB8C5DE0 +DED71BB2F386E03D51CCAEAF84F0EFB290FCDF2C0219B1EC25CCCC33571E29739D8A0025 +FEDA1849B5EEE32D4DB59456B1CFCA8E8F7108003DBA2A20120DA0D7E3CE40FEA9193615 +2F1EE75A674D8C6624CB60E8A42B218AC9E41EBBB6771DB40D83262877AF2A369A20CF57 +BA61484D323FCFCAC034BBBCD8F92644830578DFA45421988048B1660C823CE8F291E099 +311CF62AE24CA332086F6C9CEE197DA96FD2EB0A8E49D2E7045AE7619916124FF5D85907 +DF15FB7951BE56AC6C10EC2A98AC525012A7A75F39B5A6DA63168608C5D1F8A4188F12B0 +F37049B2E1E70A225DCCE1432B0DC309215BC07A2D68A261664C3394CD4A800E30E77823 +E1D8D98B0002208B09873C0A3E6724B3A1A21C074232C400EFD5D526C213550F826EE84C +3FEAEADF6CCC9E7FEB9A91DE653D1F4CBAECF29E197FE8B9CE2201E39DBABB02299477F4 +791D5CBB3ABBB53077409E1C4D23E7E43B071E523414A00EB50E0A1BA6CA87896C9191EC +C6154FA8483509FCB65DB129EACF38D00481C70D5D4A1FA9A3B2E84B321222E1CEBAF617 +A8E7EDB4DF284FFC1429CDD667C52D8F2D79E97BBDEBFA0EBCD52A54C963797F9940942D +3D4D1E9962C34589D754761089F50A3BFE1F9F51C1F1F67560BBEDFD67680C61337F53D2 +7B2D18B4DE7DA691587FC93909CCC2BA2E853D4590936D3B989502BBBBD9929E370B59F5 +073D7EDA6875A191C5BBB8C0413CFF0444F16685442A6EB0F33EFFB569D3AB77151271B0 +B2C5E7078442F1568B5BEE33BDD450854289BFA1CCD81866AFA983921423678D8C9FB9A6 +D9E77A177CD5434BB12C4615DBC5A21317F9B6775EDE6E44A29AF506F119820B5197BD05 +207E0607F1083F0FA4F1E34E9EEC2AD41DF659EF2473724C7FE34AD74D33B15AC0877234 +224B88851D27BEC30033A417C61798F8C0C35123860ED2569A62BC7B2509CB0DF03E3A49 +9CA57311614D12AED1DC3FB1470726AD11CE5D420F4A94586435E7C18661CFF62BE322D9 +A395002F4DB83E37145BC240CB6E5FDCA11686656EECFB072B3422184AF75C8FAC2B6E7F +33C3BBCBBC8B894A05BE1B75BD64A3CCB485F7359C785C449AC4CA3EBF59496AAA7D0DAD +FF7BF3F8300AC6644BB4C8E7613C5A4C309EE67AF77701CC1DF39B0C01A296309FA6DF84 +3875E1A057BC7E5ECB644240AEC11AA4157F67136831E5449EDB5017C03509B78B35B016 +DB6C9DA02AFAA51337B3E6FC0091904D04B328D1D57F33CA77E5BDBD38AFA74A7444158B +20009EB4A2029AC86EF3076BFA6A97469DF182172D39D9BB16D5F15B526B61FBCA683306 +7097DF4ACCB7CFCABB675161A3EEC657E8A8DA7AB590CBB4EEE9999BD8BD3C2885E3C0DD +52E7850E680F9CC5048FE8B0BBB656CEDC82C07CB9FEF713BE8C5021CA593E445C034796 +B34DC2ACC85FD770DDBB7179F518BAC017B53293A52859A4220DFADC93FBD31F191E2467 +DEB59636682EA309C19F1C5FC8643D9D7BF9A9F928994D15BF645E83B37DDB833F0422FF +6422A9545FE2F0B2D959C8839BDA8F2D76E369AB05F324089853CE660EEFC774D714954F +EBDCD762E9490AB0B5CA9EF9B4DA51665C5CFE10AF8822C0831F80470467CF1F49B88E69 +4C75793F8BD37EEAB798D310F5115C5F5DF6D650D75981132E94140843F8440739AD7543 +82B6A4109CD818116DA0FAD8E0FB22903897A1D4C49284411F0BF018E880AEA118322543 +098F74BCA2C1EA19B2FED0C0D1D74329F4F23027D75C304C2BDC5355D5B5424F000090CE +EF554020B76DFF1EBF9EB929AC89CD76CD5D0E784207743F1C8C0B2275EF960766295992 +5C97D6D4EDFE071B4AFA15C5D9EB72A67C1FB72FC634337D827603AA7C37E62EB623F5C4 +5E23AB693ED30B6736149463A8A01AB28A087F8C80ABEDF20358899FC34F1B587B017B30 +99E8AA24D9054F66E79DDEC2AC82FBB0115923D68239EF1CCA2CE89E935EEE0C451301EE +075EE992B3183D0E149A65A12AC23DF90D4B05E79F8A0120123D972B919EC7DCA6F00711 +FAC4F842BE2B8384137E5858EC111C33348E85EBBC6C176169969F30841CE85A381EE1A5 +BAF76C017C559D955FCF8FF05A5CDB40E91AC7BD74CDCB519DCC657F3F3F54DCD402CF96 +FBB2C1EFAA5757CDEF80BC6575CE488E2DC246AE31A3E9634DF5337FAAE9259DEBB8C64B +5F190C04BED5616CADBA4C014A6290BA5D70D2619724A960D60989F52B79C09433DF6715 +54167E161E4A1455A02846FBD422E4270D03841B3B5888FB8399C1F9645B870ABD3F9199 +B8D81BEF3316A3004D07B378962BCB2A0D6531A948B59B7C46DECD179FD73C95D5EF6390 +A105F0B15BB743B0B7D0A23EB7F9065637B717840FB9A2F7FB7C5DB79DD08DD7E024BBDA +9453FCF5AE11747C590480EE6003F5330860DCB1219FA7458846C8F25B816BB245D50901 +F892E2489F34259C300EDD02B616FE650D5514AD5734B77C7BED0DC3E495C418B6A9EC0B +EC39E783C913F71D96E9B0A476CF3F2D0253F90BE85D186A823453B109C79AB859726BDF +85236314120C93F4D44B55EB5A0C11A2D4602149DC836A2F41AA9F096F4082E3B199BD2C +AA2653AE68087AA655B4113CBF54998BF44C8837E6DC8FDD599160C1B191C2B18AF7EDBC +2BCC5CEAD0E765C856E0A39E8E904A821DA88AB030ECBAF39CEB016FD34BCF6049F558B3 +EEE3C1EA53B87E7BC2CD8455209A708590ECBB9566A78262C6268FB2180C3C4825267A3F +BCAC25E204D05417C85E4C46BE30E4FC876D461967483D9ECC839024333A235C05E61545 +E52220B3E3CE601C4480A959F032244A1CF4204A36CA332EC0258A916D0E68B043F30949 +0DDBB75B000DDB359B315FC9BBDE10A42A3A7D6D506B21D1B48254F84FCA27774A98E249 +FCFCE9E96B7EB51D85A671987AD1F3B35C755667B64DA70EFAF67CE8B14A866AE04CA6E7 +EED0905E5FD17B98D75F91279E033C5FAE681AE10A17C818E79204D6AF3925D70AC627B3 +6B81D9D8D75232F308BE848BB67A87A561821201C796FDF6F39B031F5049490AE19E8DBE +A908EA44E378232A09032D368F1C22E1E7984FA82E14FE340911E786105AC959A5A52534 +C585F1A85C5DE7F78CDC5B43546C8CA3629906BC586B11DDDF157CF1031B182BA3D335A7 +A779F56FC0C037C2948DFD410B53FCDA94E73B53BB76C71B132405ECD8F0B4AB5262BA72 +230B7420F4E03F7BDA0162F59938DBE1220B5CEB12FF83C7C9606A67078C95075D827631 +1ACC893D484D548A52A547C96A30AE7A3B30FB715770CA5861556BEE0E9D8E837D385C7A +40D24B46DBB4A23A24ED5844F5ED69D58CFE897C8FB9555D41578C97234763E41E1E3062 +185FADD8A80EB9BF519D1A21C1EF6ED7D16F42F5F083046A63711E79E2B4646EFC2E656E +55355D7D3E6411B465B535043F9A6A57601D15F4B24D1AF71EB93A0C7C07C85FFC32871C +1DAF85DA374524B0554E196A18A149870C508BDC9FE22CEF54BEEDBC1820BF4B7DEFECA9 +062F3ADC6E93E560F7D37EF6AE086BFA66D02D82C8454FC5CEB362007AB53947B2A14059 +E449E45A379008271758E200F71807B3664771BFB9C46668BBE1A35AD7B208C9AE0CD84F +8ACFCCDEF782E5E6D3B21F236F004B41E7E6FDA292970F74127259DD470368EE2C17E7F3 +215DBF172A740F42F74BC74C8A5469974446122D11741EFE5CA3AC65D03154E425C85F6C +525B3CC38005CC7999643144C6BF34EE658BF922456FB08DA18CAF92332BA728EC95FAF5 +8BFF30FF9F1FF2BF14009A5E6B9536F6C5DF9CDA8C2F34842C8EC1FD510F878F1D3605F3 +47B6C95921C8700AFF9E75B7E2B404D13BF906CACB3A1B0529A3168C31C96ACC12723A00 +455229C1BAFE2DC474FC46E969F6A07CBC2D4C3D9C8C81D9BFD84A95756451670D128EBA +ED2CEF998B03950827D203804F46DD1F1CEBA6110E29A93DDD2C38E8D02769A9523842C8 +533F6EE2CA11FD585EA4FB551DED51FAC17FD30E0BAAC02D6206159911CA2BCB19CADDAA +4FA6F2911442CBE8A69FA4CF3CC4792CADFF5FB70D1A8441046F0103A36CDC7B8F82C115 +DDA815EF71DC8295D8BEE1D412DB942B2619D67A5C1F8B06DCC13BEDEC191D9E818E722B +ADE04C6C358A27D1EC9B5C0C198B9B235EB6DAE815C0561A8C29526AD3212B32A3D4FA35 +831008C5A9AD3B9A8D68903021B9513619868E2F8535DB856AFACC031B890ADE468A9903 +B716040C73E77CC57813869E1AD1FC706BC34DF7477FDFE9A0C21AD33C78AE789D829935 +51CF312B811250B8F6244A098EAABCB3A6EE2DCF7209F04AC039A4EF35867AF00F01657E +B517482EA86295127A388A8BF4B605ED4E13F03B2A3839990ACEF98156084F5BB2206344 +5941C560132D0349D52CB72C85B983DF6391B885C5C6048D5F74FBBF496C70FE021AA578 +280053474B6C1F9AEC55F6DA9DCCF3CAC7A7DEC6F743A81FA0DCF7621B484589330E3201 +8A1B7257F719BBD0161EC4ACAB731F2026B77298EFA4104EDBA6B299858184FD1D4C907D +B3A6D0192F8C7DF66D3B0C947AF0F91F7CB09320BC0D0B11CC026162450096809A8D1E8F +01A09E2D3C64E6C91E2B31AEC3F1607381714BAF0D00240FE58264BCFFDA303E87296DFF +1BF630DCF9AF3BDB5ECA30991897AED39EC4CF40070109746FBE9D6E5A24F70D8B2D050E +B63D55AC6D18153F3D5D04E10B704A2B47E7555627A84F394B3FFFB6AB7363A9DBBD11D9 +323050BE1C294A586CCBC043FF952C34582F4D4F8A9F6E71A246B47B7B87AFA9BDA0ACA3 +CC3ED5129B810A98883B1A449E5834344BCF7C09117052EC619C8512DDFC81A68CB6D179 +CB3D6F3BE24A1F29669B7C666A9A0C6148E54BAE665515F5490639C66BA808E40B615EBF +5B59D3CDEEA96951927E406F696745250F0A5A8B8850C3A3AA7F59CC3F18F3FC141DDECE +33CB43777CB6359B9015B27CCA83BB4EDA646BEBBEB1FE0BCD0E1114C0F983918DFF74B5 +57B7A614EC0FDB3D1FA926CC76D3B6F0527BADACC1C302DC6D4019E89EF7DD3195494638 +794543E29846DCA17B1724C3B2C09172B9402437E747F22F1C959AFD01C092E87ECC0CEF +C7C422538164E8E551775CB7660B90009EF7C910845385B97FFC2DD5E8DC1DD3C0B2128E +9553A042C74308F74DC7F04CA995F9B9870AD1E8F89382E9E9DE8600936F1E2180D59B2C +B8A3536BD7F2C47142C756D26411B6E5E34B03C49CFE87398C7334C786B729DA1F36028D +DD5A16009B6BCCA2DD6737C7C4C3CE7004B488B86507D095B567868A6ED59964EA34095A +DFE44C9FEB502977A1369EDBFBEDE949CF421C576859E181AE2CEABCE6C35A88F5050345 +FBAEE8E1FCD98F6DE17E66DAF5D5929046C074E8D85C4AFDC71367857E8A7B1AC3E526F1 +8B7DF5E90F2DCA4007344D0EE044E663D50BF80300A3F1F1DB03B14DF2CDA7A367F91A5D +AC834BE8E057EDCE5274252AB3FFC1D1DE90857EED51040A2FD881583184CDD2CDF4D629 +B907353B9F878AF4E46FD64C85360927664DAEB7371EEB887F5AEC4F76C6700824FC8E05 +53A785DE724528E12C1FA1A8D32059EAA3A99E6D481665DA762E6325A4310222D7DF3918 +E96FFB85B3C04D9E7CF4F3328FBC31F736E93559EEC6D60A878990E8108012A2785233E8 +2E57C735254C7B38E16C6C7E7179246054583C7299050C31496993555A1243826532B139 +71188CC8580B73C43CBFD1E8F23369F56EAE15FB0FA461BB771026722695A8F4C6BFFA3D +76BD2E85D3BBCF1F7F53D23639E39754A4D71B48F1A8C8A18C2004A05EBA0656E3E9884F +9FCC00D55514EE382FEDB40BA636BA174FE950F2B0BEBB9C926E77ED32B08ECB1F4D4499 +02387444393D3A97BD81109E56701374F13CC9774778ED60E3EAE3C78BB6E0B7ACC43B0E +5F29F3DF4610E97F86D7DE9CE585E2BC144E1193C123BDDBCFF83336625ADD90F1DEBBF9 +74CE0797BD5369D2E3C448BEF8AC728723EBF987B4F1CCCA1B3FF3C0CF8F0287E3F5430D +BC67542E10C560A28AB12B3513C1120D8975A6EE71DE0175AD8FB16C3DCE4B265DED2815 +F03C7FDD72E34A27215870758DB124A5D630723BAE250535FF92FFADB0ADA3C4D31D007F +562836EB114CB81FFE1E9F54756A3D1A8E3CE7DA8EAC4036555B6583937F6307017392F0 +FA28BE83A6C4AC9183B899DE736F86D05A91CCC5545B7AA2694841AA98ECC5712A76011C +9637D079BCD5295AE2999EC5C032F7ABEC0804E2A2510303EE071A9777E89E32804C51F6 +1458AF5736CFE2DCC50564CF3EFB629FDA6C39CCDBC5417AEAEDD0509A025B43A682B218 +8AD0D62B96ADD583B027B85C532A1F1C2CBDCCA5FD54A3ABA6EBEE74F2568BD9AC0E19BE +26C1C2436C4FF76B4F50F05A37A1A73A02D155C2DB4A849082AFDB1284F9566407CBF976 +F2D7C124BB538A0B26898CC818BFD9D34D41DA06677516C8D78B6C801B864DE2B7830E1F +868F33DA7E549639ACF55183CAEDFDEA0664AD59BBAF56FAE34AD40EAA21F539F916E41D +690419E36D2C268B7F72B86BE962AC175BED26F6411B70A92CCB9D7A27FF88929F0D13DA +90CC5948B6411F7B04586E283389D530C85CACF958D145C88A34E03781617B40171D3187 +430BB6102B6F1B2C9DE91D2D7BC2A8D5770736B9402415C966FF73EB321FE99505100C1E +47433619A68E08EBC593B85B638EFF1C484BAC03B045BE97A0E8AB48C929F3E801A3D057 +6415902C739C6F92B15E8AF8DA0DEC3450DF6AF7522ED6F316439B8C6FEF58F96BC9C096 +C6E5C9FA97C1524F6F4B84D614EA7B2217B7DFCA1AE90496066A04DDBBBEB49965526701 +3A7513B3453AD0543D475A82C2CDABEFBF7EE5FE95DF01DD6EB4E2F5B36E5AD98A5CB658 +87327AB12AB875E4D9D7CFD34C4F02325EC3E37553B4EE12DD5CE535B2F6C7651DC26A62 +CAED8B3A97A143029F3EF41678CAC2E5F2CC6EE9BD567FF58F32435045214B62BFB112F7 +14FD95F9BBB4F3B3FB620429E12CD2C52C55E483CCEEA72D524C4CF1D91E80F27ACAF36B +5BC7D386BFCF9D70D3CC730D5D2C9C75BAAEA9EE1FF093321AF65CCC73B6BA6F977249F6 +746D69E200645A4E40EAE0986FF0CF3F1B5572BF9536DCEA02B6925801D1C466129D45A2 +E927BDBF6D6F84C3548C78E70DAE806CAD180FC468F979685F845BB2311524539B1C7ACC +C9EF641183A100AB51C155E89961090E2349C601C6769CAC3B1C2537BE0CFD560B9B2369 +4E1B8E9083DF9261B17EF6475C0A42466B4DBC8C601CD82D6236729CB8C80FCB57E7AFA5 +D9D9B35F66E5B29251086BB760BE94831670D955DC8288817A9DBCF7A6ED48038596CD76 +BB2FA5541EF78AF5CE421CCFB286624BF3C98829323A7EE8CDDA3C5DE22044672C8D233A +C08521CA69962135FDDC8EA4139BCB13B64EC0DEA02C437BF522F41A8768ECC542D5EA8A +9F85417B598931410BC08259AF88E410B695A9A6EBD730853F2FDFE3FB00875F21E1EF5F +60D8D8F62E643A6F4D124FD84FD72FD21DCE57144CBEE5EED9C05796B3F59338903913F0 +CA0B073B074A44B1E1951353EE514CB41BF3D50DCFF683CD15836226EE9E73F55D4078F6 +5E3A288CF7F124ED183DDF2C0EDCA6C375160756DC3DC33757CBE85822FB2ADC859CA8CF +7CEAB1DF3A48E751A6604C3E4E53A9C9CB967813C3181D7E4C1DC954A26EA4B28E23E39D +C2564845970739B40AC5B267B4CC07C90E289EC9288AD379A7B684B97BFDB45F036BA95B +EEBB25A5BBFD3F0EFEE2ECDEEFADBEFE80BF2A8C01BA345B29DFA9B25B2D2234F358BB99 +2054FBDB728192CB5EAB19319257140E95B8F31E14BE579364136543A847989F4E410786 +A0A068E38A439250C3D61EBECB1AC741D529A5A74A546FF7BC9F2CEEB11CB98F4FA97BDA +C74A7EC4DE3948859D3091CE7D8992D2C094590B0AF2038429E30A6BF3C7533A900A4240 +E082BC40535E8A07E55E6FACA93FDCF4BE35823B30A2810DC991AEFE4320F927105101D8 +48A790904C823CBE8286DBC1D8E7CC50B1E5931640FBD0213B0FEB7AF7AC38CCC6B738CA +74B1FE58BF8B559A7D3AF0D2ABEF706671A977E737B5E49C4BBBE7B412FC8512C17661A8 +9827E24623F4428598A65FC5A79E77736EE2506E5A61DC3ED221F412AEF9FB3AFF6A79F2 +EF15CE24C810321A72FC6705FCFE24032801E3F61EC145D6A82C43DB8E5F9D20AE3FD7A6 +72477CEA2B6D04C24804AA1597A4A3E0B7E3E15D307D8A13D4311F4EA895199D208B23EF +DB35D975CA9D6D9A036F27FE597C41804A8B5EE10EBD4C16DD09C6228988A780CB315C53 +C2455FFAAB2D71FF87E67EE35A65AB2B8BCC351DCCD62BE2DC199B3574FCEDAD5809517B +8E3BB1B197078CD7F691B4D0474EA1F398AE3AF07263E8BD0842B8012EBE5F51CD5FF11C +35CBA2B275CAFC8D0B3D4FAD5B0931C03A3E0F79F31EED87ED8AE3C4F628FE1A1F2205B1 +55BAC7504D754C58BDC458A4B24F8A4E1401AD5B66E3547DCF9409C1C811CC2DF862062C +74A773A5B7686504B4C7396230D5F2F0A2BE098245EBA1758F20E0E5FE2C94E899AFB774 +4F29CF4D61334CDDD7C38BF479B0CC3DA8E67FB6D3150523C09A24286D86A9F4E1F5C2DC +CB18719F6087FD27EB5BBD9BEDE21B10C26BC38CD98952A128F4CF48F8651B97F6244F23 +E61EE0FBCB5D3BFD9C2E14792920066CA5E70449C4F13057DFD33A11B71C7991D29A7185 +CBDDFEDA7CFB85ABDB7F854F4342EA020DB708556762994759BBAD1E9F83E7F2961B017C +4EB56B73B37F019A8B91DF3EFEAEF75E016457A70AA33D31C9BCA76BA4B805646F8264A4 +6C15C2470F4903A99B0D0BF9B7B7D384F640FAE3DF6AC2ECB533DF89838B258D8128F5C9 +1DB7350B9BDF201455D5AAC7C08F39B643D8CCF26AF3563DBA05B5AE422388644CEC7ED2 +3EADA9060442A728F966D50989C477BD2E4BD4E206C8B014D2707DA596661CD7035B526B +61CBD0FE916D0D7B4B22ABD91B4902C44187E74D71647F7143FAC8E4E9907DBAFE15215B +6F20B82E09B29630E5F1CD15268481847192856F1BB23A00D7E6522090B3672286DCA1E3 +D2DE32FFC4C978F61180D497D9DF1C1CD48B1857CBD40EA172DA1438862A7A28F570B5B1 +73B53E1E81C6EC11A269001C6E6070CDD0156DE95E320F3B496036C1136F15EE35D79F2C +962280292A3678BC4DE5D1C2535F09571A5EFF5379BA71C9996B7003F27BE9C810C68D9E +8D55287AD3D1B570C57CCAFB53109C3EB5674920E6FE3AD170F783B1AF3BAC0BA5CA1598 +6218777F4EE1FD7738963D6DE1D8E1BF1353D5D96DE89C2DE3AD2015265D9077AEA8F26A +9A391A61A27CB0F9E8CE16A12D1C2128E8CB7AE0E861E3CB56769A07E812F1169A283C65 +A22F19881485367B098EF3B97BB9E41775BBE13F4E1560F2AA0FEBE4A31118F55142E590 +B51D5A0867B89F00D9D461D74DACADA920DB5452D80982761B357AFD2F613113854673B1 +3F0F1EAA566427323E2B35F2FED6339DC28170D90EF4F8E4E77506115BFB2FC891AAFAA6 +59611E9FC6F5384DC5096D54E09567BA8379C7D058CE8A3E203EA28DB122519E483A46D5 +F527919C4AA0F635F6F29C4AC9363EA96B0802002BD547E0C248AEFB8DAA0A75DAE5B8B2 +7C7B4716769521B4F3A8B68B0251CA46BA9B7FCD00B3D4A59002B249860669961FE8F4B6 +B594B68D781B24DEE41869F320C0CA419B596F3AE725B4089A388AC4F84A201392C1AE79 +D6AD6F13023E6412BF29DFBF33F00D8966E8C87FB883F97B1430DDD9EE0D0E8ECE00DACC +CDDE43F90351DC64D38EB3013CFCAC2792F613EB56CCF8553C3D9A4B2E9544058BCA3B86 +6F2E33A68CB60097D017252DF367F584DD224D38163B6BB1F5E8154C9590B8E3425FD89F +4575B5150F2C674CE5421E4930766BE7A55D1A01044D2FDA079E1E5CAD18F5F0B7897741 +EE1F4FAD109E503F44526746BB3B5C803047AAB46B1D2CE31F3E026853F52528C3CF6BBB +6BD36DFB524170B10BC85C070459CDD84D25C0EC712B5E8C8D1E6A736993351DA8261CA2 +81F4013542CB6BF8168AE8F04C55BD7EBFAE0EA6C3B45CD9698C7CD576793A1007E2B391 +0310CC96F4D2C5C0565CFF92468AAD585185BF6A19CA9D27D6E1440CD56CA0AD46F4D1DF +0DAD5F2A2C1D2B1ADD80030E38080DC4CCD773B7E7A74EE7F9A964BFAD960B2542E6EFB4 +64FFA0ED1C8828B8C266897C0F7AED40851746A573DBF08F602BCF9E1B339BE24BF35D0F +AE254E6D6170A224FB5225D8859F5C440F96359783D21940DE8553275485D0287DC71919 +A3D81FA8D8167DDA0F42E1CB15A19D673B896729B2A492531E9FB8811837318C24546170 +9F428D0E7B0A6C416FCA1B5B8849B86EB6ACB1B901E2D90E0939F3856934894315E3BDB8 +1DEEFF69B45C8C7871E73E6A20B64362FECA450D8BEA3878AAA0676BC8F9DFF37AFECA0C +C1096900829EF7DE769DCFA7FF9DF38C9C313829A5B9A7FF7707BC554F1B4FE54214371C +6681D624954BBBB90BA5AAA44175DC50C6BF1E8A618471C3D1D58471F2567084E503EFF8 +F4083B75F03B7848069ED9AD01AF51BC5A9C3F34E0EF36FFDD3D3DB350740A56231E8323 +60E8327F218D6E7F2490258F03B904CBC4763871F37E1B8C88D592876E0648184954B702 +CA5FF4851485BE6501DE9AF291D2D4A55CE425E405833285358EFB271ECA61CB37942EC9 +9D53EED6939D6E828C6B2E013E0ECE1A60736726F77775C299D6784E51B1863D304A9069 +F217C825FF94E4982C8B3CC30242232FA59A8274011712957B3F1DDF558CAF79DE460A9F +B15A2D1A3999EBCB3501BE97E719138CBFB37242A4883B3300E20CD21EDBBE0F0D8EDE3A +D6940338657BE43C6C04EA6C48BD51CE3D064B55EFC5DD632E1084BD01ADDF53C114D329 +438792E470EFAEEA5DFD2FC40553C736BF612A8AB8B0FFE6F16DE99FCA0A0B5026B2A50C +C15F0886047EBA1F115984B30050C579C1CA97D31BF4167448D89B3BC66EB4A099E4DE4A +89F186334430655C7A2709930DCF66404322FE8C1AEB3C7952A4DD19CB35C3F50802FD7E +E82D233FAE8EE5377A6211C0D55E5C188CC858D2A38990ED8B2E804FFD60DA6C477D90DE +24A93AE87BBA8558770C427EE99A8623F26EA053C077837CB691CD6BA6A22EE8C584594F +B5A8F2C75D5ADF7EBD927BD53B6F5809A0D6088C094EE056EAB006CB8C4BB2C035D57A55 +57C3BB319E4F0F9BA89129924EB53F7D349C0435A1ACFAABBFF97E9FEF3DB3DF03C21E47 +C5FBC852A8DD098CEA2C335CCDA04F2D2C9E7E38A327C7D78CCA84B96C432EA51C9A3CE2 +37BDEED3EA86D69716E5D60DAA77F31CADE9BB9FA1CFFB8A3A293A5B3FF9FEF03CF96BB7 +F259C3FC6EFC422FC55673819F3F4272A675B2ABCF8A4DB411090346889715D49FB199B9 +6AC6C2981257EA9211FA518AA5E582E35E0034AC42F607F587787EF3A6EA75C1C396FC99 +331D4DE3A906906D334CE8DCACAD9D6880B84BE0068ED1F365B9E7DF9D35E79412BAA94A +BDF0274B01E64B865E7D4532CD08516C8649BCFD7EE65685B27BD947156ECBBB358C110A +5D5767808E8D924F31464FD3BFBEB53FDE41411840C1B689963B2A5781467C9E44E681C3 +5CB292DFF210C75FB4014107B364F2D3B8D3394AFC8B14BA28585E1238DCD8395E05852F +C813E23F7A278E72C7463995EAB78999388E9F093C84F3FE3A164FACC9A0890FBE7CEAFB +0C988CC963B228D9939928E886095F772F12F8B05F4D66ABD8F3332BF5426002B905A049 +886BD5D9EBA35960612E1DFFC74FB5479E37A19A17BCB600E200FBD9437F1FF156028386 +FA46C79694EF0EDF059E63EEB766646DFFBF7385C0893EA15B3A1C982C051C49F4AF465C +A9E6E837C463F580B883A93C1E8BDD68EFE50FE6616A831DF101F184D2ACB6112A10720C +6D173FA6E5C494A271FE20AB7959234BA355301BF8276B34BD198A6F6415C094936BB323 +322CD5957A5BDF76EEC4EBAD015276DEF92868B49CA04FAB36BF6670CA237B4530BF5DE0 +B5774A3E67AAE1EFC2653CF7ACE86FDEB7C8D78B29D1B92170D47EAD57AC140DCB44DC34 +AF59FEBC88B667842227BAE500E6A1DBEBAB7750429B00703863C2D3B3BD0420D3660EBD +6C14592216F03A404E4E46458A9370BE3A92618924313DE6453AED7361D34CFB4369C789 +770D33E94993EDD582C6140423189EAF3CDD7A672D0DD00207B86A4D8FACE9976D83D81E +CECF00CE22D20B441038D424E3958FFFB7FF68D6214BFDA59085FA022DBA5C94071A3F72 +1221CE61C19B19542C3321030BF5CE4D8022B49573793EB824E9CB243D0E9EB6B89A34DC +744450FCDD335E607B45DDF26A57C7DBF83A8C0136ED272D908A0A469C9E61F3CE9EA255 +3D81B9E0B98F323928B0F44D62FF942276A4BF297FE225EDAE82A20680A011229F58DEA6 +9FCE234B22B2AEC35A208E23EC809A5F790F09E11FD738CF62168B1BC2F7DA9564B8D576 +11AAE9CA0094FBAA861B6114A66A4692291D5F4EDF5E230CA8E6526C55B62C8FCD46D435 +6407C7082BCA46845FB9A2865EE0CE8F860278152F0A849BDB8B85E481132797F49DD35B +247BBE4369FCB4A20FF77D6F791568CFD158CC1319F17868CEF028224D2AF3243EC6740C +93FE35E7372CF7E68F06DECC8160B7C04F7086F4A4FA66DB58100D6513000C4CC90BB363 +6BC1B6ADE24EA559EE3245CB74502FE440D7ED58AE19B182E0EB645D7BCC5D8CF1EC26BF +D8BAA713B6215595BF42FC097D5DAB7C030C522A694E027CF558BA7EBD711EA18249BDC3 +DF346537E5FF50755BF03D38A338EDF1974B21FD6E75548FB8E2CACD173F40EB5A9F15B2 +FFC720F0190ACEE2B6E5B040F7B89AB214DD89E1E8AA859BF436EE19C5DE800ABBEA049C +9B6FA77C93A833C02A11CE4E502D174403B582F617D388CD71407FA8C7060B9F3AE414B6 +63F4B524051CAEEFE1C919346B60DD19E9FEC14191B72DC49CF0FA248E568F6AD137EC5F +73BC3F3F79CFF305D88447E05B4BC7B25D20B5916787EB38D2BBA64411FE911BAF1C69F0 +FECE979BA0267D3A297E80FE07FB6F6330C3D4E9777C095B74DB138EA9BE483655FDC269 +A8759203B594DB7C9F6AB5909651C4A27B18E51CE5F695C2ACEE18DA6AE89A3BCFF95D65 +365BF11C14A5FB2BD261CF6ABA383FC467C81FFFD366672895BA37633C3A89739B397604 +0734CF9218B3710863906ED0002D0E756F66DDA0B38F40882E388DDAF61AA9EBCC87B0DB +E04F06F6CD3CA3F24EBC695C1CA0DFDE7DDA8864EDA643FB93E0AD976D5C1F36F65E7A0B +2B1767B0C302AC325B83FB1BB658381C387FBA199CD1C3EC7602CF0E19C96C10890DCEC5 +6166BD141F3061BB7A0654BEDC8DB922337942873A2F6E8E11FC291F8C16AF1A0C8221E9 +62106D02C4F575F4A9F61287E4C20D948E9E4CC7E74B99776EF3A27A0C2ADF127E60174E +4BFEA136B745DCA205A07EFBA484F7E0F76E5FA389DBEDDE4557C73C6B8BD6CFE9D0EF6E +E197EB8A5EB0468F5A80F6E71F9D65382067B3216C740744E671A533F046B48D61845500 +488CF8202A1E91176F97E50970BC00D58CFC9B1BAEC3435DE567CC6B5C601ED7BD437C25 +86E02997F7AFE95F1AD71CCEC4E9C2B9D8D17BDCB66A128122AC0E0CA37CE810AEBB216D +C4AB46AE69CB2AA97CAC99C1C6A5B112A1BC553658BFA93E931B4F28ECC6C0C43E18FCDA +5972FCB8882A86CA41349630542DAF536846B01DD5ADCC84FA4AE1CC58EC5B325C4EFFD4 +E32EC77120141D233E5C02CF7A52399AF39D64F4B9000B881F13070D85E8DB91DBD38A42 +08D5C6D8ED42A48272851DE276E5ACF698E6088343F852E0B139E724BBAE48A44EDD7A63 +B5772F61E178C2CBC38F728DC708FD792737E5A495FAA3335133C45CC887FCC94889DB5E +2DD34C1DC8B2901EF49320B2B8E7708A778A54A540CDF310ECAFE13653DAA2D6C9CAAA00 +7AAAC4D9CBD01F61F0E1D8F35C06019B1D6CCCEC5CD9A1A263CA630C8C14EC325F8E5718 +D4CC035FE652C2A2DCC53B7EB5AB33B43C7D1EDACA8F589C5966BD92DF8B62D56523BD33 +501CBFE506B9061B096C184C5504A61CD6B5E03A8338F5B16ECB0324A8785DF1EE193710 +B76D5301448B0C664F565ED0538257FCFBCB051683FC200D4AD675FC4CABAACBEF11BC38 +E95F474AF3FA7FB187E5876B1F04A26DAD7904E39F3D53A1D5FED70E523867C3E1A5B65D +BE0B1D6CA84EDEF3D0A24D042CA491D6BC39647EF390BA25E2F998ACE7386F8424E3E03D +6EAA815E717F835E3528069BC3A65CE58FDC49B602E0418A3972D9E5F6192AF89397AED8 +32CB25A607DDE31B69FB61164EA5633C019B3E4BC93078739879A2364CF42633C07D1BE2 +57AF2B07A1E5ED68B06BFB81CAC77F6D2EA4750266E8919E8911391688D4EADAB19B3E54 +4460DA693474250CA9A864C17B7BB5059C0D08B32400A51339C4ED7385D9C1DD1839D96C +8C0A6BE1CECD38544854E9698401E33EBF50C1DAAD1652D0EB978D8025D86E07C3DD64FC +92D362A13E173F1A5D015A43AC3CB57732C6A2A204B990635B607938D99422B450E54B7B +4CF6D22BE2F6B9E936611A0132538CD1D8AF62A260501B3696EFBB0EE006F658EFD8AFB4 +19C3C8957B3D9DA5F8758CCBD17734D80E2E207A58E8E97B2B9B78012FAA2C73CBE0061B +EB3F30CC034F7FE5D3251DA71BD8372BCC7F271B5DDF11167AB166C59F63B9923F043611 +52240DAC4CE6B15DD8FF9ED6F74FAB00A4D2D9F89BED255126AEC97ABE2D0C7D3947907B +0AF2FF6A641A43BFDE3126F54E213C03C54E01BE7DBA01F71E523FCAA4C02970BAFC51DE +EA7A8530D73D62B5F3F457AFB500C5734AF579603D2CAB9AE49281EED2CC8FF7101B4F45 +F619FE5FD48A83D934F6A0D394B07B1235AC8FA8F3DC3CCD9479D87398074DA6AFC3402F +21B31DE8621AAD29EFD4F9CAF0A9FA9D9A0D097625412B4FD723E1363E5729F40D8C02DF +8D222A48C23B2E25CDF4F69D283E006E0679F1BD904A9075FB0A8094C1BBC3400A2BEE5F +736CDCFE47991E539406DFC399BD0B76D3A5C8F91BC2BCD841E4AFBB521D46B8E0558F4F +A800637D47167FD2EF79F5251095FFA2F3BDB915015010FA689E4E87F921298735A30EAD +938B6BA40D4E58042A3065AB059C598A96DEE3AF09237FE8A6BE9CEF014AF36D91508C93 +F7A18393BC321C3A4110B160261477F6D9B6771DC8738D8259BC4FF1F2C1A657638CF4F5 +08AA9400D4AEF4ED4508BB30F35E38D968E008230DFE501A9612966F7E35B6D8DF26338D +B63BD1B88885992D8D3BC7EFCCD89622689192CF14C328C4E4DED3025E56F3E73FE2472A +144AF139106A197E00EDC57C2443686A234D214FEE4AA2E3EF978444D4A2BD1373423CE4 +E5F82099974FE66D53972F774F2BCE9003538CC59003D0DDAF9889FBF2519EA31F3A515F +8D2C0091937DCAD3FC757E18FBA1C37F8FCC69685E95932B3DE60F80837EAE690DCE306A +EB060698E560BD148CCCB42240665ABD523CB02FE18214AE45C44756E9D3A8183DED7506 +E560EDB4D43E3971712C3D23714B0F83D3BF19C7320FFEFD07E9E8CC573D97FED37FD3DA +5EE98331C70CEFDB6F6564D8EA0B985F1206239822A4644CF2D7ECDC63FC5D2014359891 +5916E41FB338545CECC1B9E37DBEFCED4A55DB485C86C56EA97DA572A2B74D2650C8C839 +1C57A1FC4F75913C8446846F26614E8C72080DE0FBC3FCF92864DF37F8A3C66109AA56BB +3CDD02BF5330C38BD39B081AFE90F775FA6C78BBFC51DC0FF37B9CAB4058888CB3D4DB26 +40D7224C0DBF9467C720CBB5F684B2A1CA8951B29182A3913EE398B8E77CB27868A439CF +9DD03BAA0B60DEF70FF776096D86E71394968B7D64CE289373BFC8BB2CC0BDF78E1178E3 +D6F5473427E7AB841223F963FBB2A5743A823367D9AC4A5ACD8BA483F5BB5AEA19B1E882 +670B74FF997E3321BE8A96D7C0435EB77A36F7AD6AD0C7B21F5C74895090908FCDDFA655 +628898D8FD6218A60C301D959265B430369C564E01CDCB05F42B520625FC0FA93F9736AC +7D5ABC70D1A25F6A6A95C1CF4A584B51E9CA9FBFC9F24EC4F2257B2AEBBD9581438668A9 +F84CE7E9919C84227D76B11B1BFB61788C69603F0106CE5FA226129EBAC295709495748D +7E1856EF2F1D5F19458B977506F64AA7E433E4E62662F10FFF43701F2A726C3F8CEB19CF +D467C3B4E835A99941C7E46101CE2C97683A17530F32808DE665326D6605984689241CD4 +5DDDBB5C964F3FCF7FD89D8B580D941B856613EB1A8E59052B296E8CAB02B561863B3671 +E0E73789B112F7DB5F0B2313B083D17166D05B65DCEE648210AB9D3F3DFFE60EC4649552 +2F101001B3FBAFE7BF2F0EDB70A95C572767FC1880F84A70DBEE39648A176BA8C7C87EDC +D424245F6F66C910AAC0C60E5078260A698AD823965D83268AC7A98EA0E7A23A7599470F +F6B2E6C6F32FD3714B210C775DFF039590A0A159BCD248E95CDE7A234CD8F64CCD5ED383 +D2E49F9FF4DB2BC7E7F8E1F45643BBA556CC2A8C7C0D32CCE2D17CE77C6C8B021AF086B5 +1F0649C7E2081705B2C0C57B205E8C6985C849B01EF956BD97F8862BE1B061733C8DECB3 +47F4AA8CCF7FADCC4C335D3917604DBA283DBC054C76199749C7748A48417624EAB6C930 +B403FCF33E8A48AE4D064E70CAF24F68AAF18D1F87E4A920E2796BAEEA34BD4F208C90AB +87D599E2A4A2427715819D7FD510ECBEA421E32FA9C3B672BB5329FF756B0E4B31C2B16C +ADB8ED6D90BF002B29D4B4F9AB7DB03B83EC9A165A3F1148A9C1958B8071F279440A019E +743A624CFD4166857D8DA38C230DBC91DEDCE97E006B242E14CF25EACDE17E7E2A6621F5 +662820DD295589E5BCFEBA6E737C3DEF3D3482D7737CDE224E3509858B999B66F6F365B7 +34C207A58FB6C0DCC099E1A50D95A7BA53E0E51EB4D6B55B681B37FDAC9543F143EE5B57 +292DE45AECC7F8528F70642A9ED6A987748EB0FCF8E4964131787205AAAE1D84B18E2736 +911C20659F9813B7F90F69F2B93360E2983CC40A3122DEA8263FAFD8DDCA7CDF12908042 +F5B2045B3AA8BB0336816C80F1C89F7141CB3C64C08E8879145B10696164E0872635D06C +186444A971B188D84C0B908CAA9D14DE8E69A758841AD6FA932A648E9694E399F234D090 +D365A315CEF4F66DB8E959A56FBEC35DF6A4E969A49FCAA95FA2797D401DC1B42BD82BE6 +5BDF85A7B8A3FDE93B698F10F675E8E0B7D2AB4B3DB8E0FA5D21184C9487BCDE17AB44BD +DDC9278A72C83EC2896B02DA5D91F2BF9FD44D56CB65B65DBE0D325427E6456E4046DB1C +5229F513A4EEEFC319A58334835FA5DDFB73D4C8E92C4A3A2F449939939E07BF9B3B2200 +1488481193B08870E0F077E47E7946186ACAEB9FA732474E2DA080AB573A4DD27BD99894 +F2EED2C80BC44C46596FB47502649BBD83744562DEC7224B1CC54CF28192D3C23956A7EA +96DBF54D85353CBBA1770E0FB58B6F1852409BCB1BDB61313C3C7C3A349591AEC393EAC1 +BD80E7CCB94C3604C5BA8B0828AF45182C683FF51D2D2C00570F6A172E2F9DEE877B03BB +45E866CD7E5A99E63B4141C4B12A21F62CFDD331137CD027F94DDF9F054C162D74FA1CC3 +94F404C707DA1F4BD2A8C1C762F243F14FC71E546EBB5733C43AB43FF23BA9C2CB9058CE +3F3808A129A03B6E13BF8DFFD23A1D02C839FB6ACDE2BAD2474EE64FF7AF05FB40E30A23 +6BE270B787D6FB1FFCC0C4D7625B13217071FE46C2DC56DA79F278C69E85D7856927D0FB +108EFF1E3AFBCB9CE54BE2F76DD439BB182D3DF1F2796DF6B5733959A950ECCFFE7E0B7C +6BDF71CCC7DA4FEB31D6FD79C506250FEDE21414A1A842747F350664CF53E6710808AD08 +A6FD26ABD8CC592F693BA372A5C0D0A6F4277A92553CC72CD6212865DA7D032D1904F1BF +668B0B37511CFBE3AAF595EFE422FB3007AE3022CEB6C87058941DDD0DBF6F9ABC5E8CC2 +6AF7BEFBC1F4B1A03636965919D070FAE1F7F9BF42FF16E9778708478A279DB9DDA512CD +B372E39B9C5C87CC7A6E55BAE1626E8AA3ED7BAB198149D33D8E79960DEE846CBD2ABA76 +1979C57754955E90D7533C0B38CE5851C926F0738CF4EF1BB2951DCEBAA0A0704870DD80 +FFDF92D2136C1F470FF5345C7A93F4DB72360B4DAE833E2614154FA43A2347FAF4ADEB0B +73C8FB0AE22A42F80B03C7207F75851AA036C76934BF67B10ED6A5B2000A2F300A9E1552 +FF9F4C66ED0FB34900CB8649CA50BE457B967184D0AE2BAAFFA2AF24881761BA01759D8B +EA601F2C09E5A15B1289A9BEB266392CF5CFF78EDDE664F3FD6B77A6C10BDAB1E57E4ADC +2EEA4F2897D2ECA99DBEDB2046C7E889EE2FB30F172EF290BD4E16FB68C14E88A58E3F70 +9895FC431776EC963284E03B6975ADB155128913F0A3C910E6D3F0AA11A1D6D67C0EF96C +145D63F6E629C61C934BE19A0EC8D5ECB08AB1305C5C53F41628E7AA2945D72A18F5CD78 +3DAEDA17DBC867BD813F81E2D828B09EE77EC5BD7943FAA62E9682214C65735152E0AFBC +E7808699369C181FAA4977771FD8D716DB2BEA0FA4CFDB606A2EE243E0F4B576A3C5FAE3 +8F67C4E29DC0D86EAEDBBA90803E2AB710F16BBE42748967150D969C2E07115A9B2A2507 +A87F7EBAC946F7178505BD9FB0E08D86DAAF88D8A5EDB321FC2E7915CB80E6C0C2B125EE +0FC6124990A00E685E157EC94D72CCE6169F852E0D19DDAFAD022C4DA4D19B979D33790A +E763E04F78D6449C7D3674A12D1C01BD73872284A3D7CE4B551CB80602FA4145DD2E4360 +1CDCF3D6567887A6B0A73B7E1B6BA01DC93C51E9FDA181B20835A75541320F1BA53EE871 +16D938FC03B909D4FC6558223DF057E3E6195C1E26D33B28AE7156B88D7B5A6A85ED8498 +48EF890A5402467A8B11E2DA4719C395D6F40E91535F1DE6C7FE1FA57705A8F1321E2D74 +69593D7E6FD067E07B51E7BCCB382B1B00B655116F3F382D990AFAF26347CC6FDA803727 +C1E13C6429D1F5D5E5D9D56EACCDB32E30AA10DDF5E0294E59123E4C2E020AF1D13A0F89 +99F30A49D8049E7D9B8676D2C13DD896FF4CB82995F6517462886B4D6DC37BE8B13D07BD +23CC78524F835DB22AAB29A1E6468E8607FE3C9E1B1CDA29B98623C87EF39A2DE0BE849C +438EEA208FAD0DF05BB478D8E54501EAB704ED405598D38D6A58628BFF784EE969725A1E +8BF897007D0D6F53025453714BE52FB6A5E4FFADE5563846F778B71FB0D225F8C9AE9985 +9CE14DF67AACCBFAC3AFACF1CC6FFB6BB517C87A382D1AC1615DFD97E52D3020E531B8D5 +C6318FB90D30C2CE9EB7EC0D2DD8FBC83A48BE41F22EFAB7B5CB7262E8BFC1196C69AA92 +EF1AA1D59DE9B1C55D5B7C0019D68F23323CEB4FA767550B090439C2D1867631A97CEF5E +7871494CBCD1EE56C0EBD4B2EC412EAFFD1783CF073E9B6575CE9642F704486C6CB319BB +19CD270D1EF9B63FE25255F6CD5D3B77B64FFF7B562742593E6DAB5EDC5E9E9467A1A478 +8BFE80F892B3DD660B1765B757CDF91B61E5AC7C7FA68857656473C32CDBCC21C3A0E812 +FBB939809D552C9394686F8CE36CFC3FE8994D26CF4917CF0F11E0DF8B806B5AC7B092A9 +255EA0364A9DF03B85D67BD2B4B4FABBC8161542814E432486F103F2DF6097DED715E2DB +B130A753D35EC68126DB76A2952575BAC3FABE2BE9FF73D18E60BA667575FE3327769770 +925F00FE13573F5050DE00CF24CD231CF619B2351371433DB15B1E97AFB39FDC4E07F1B8 +45449EF4CD86B3F0C0BA12D52A81D5386A9B3DDC62E588FA80D5A1E31FF503945EE0FCC6 +841AD3D4E56F9C801E84B01FE978E7684F451822423122221FDCF6702D48CD226DB839A0 +E095A31975298CF2FD71E6423F0FA5191D8BF7E27E6963A23F31131E68278485BBC5208B +6C5D2765BD053C47566A65DC4B173E1580183763326010D54652BCF7BF68FADE1E3B8B28 +E5C601E241431E665178E56C36AA1125B07D8E4E9627027D73CD5A664B40D82199E3622B +EB76FC104B2E5A6E009B4AEB180ADE287F763B73A6F8636C0CBAB936F79859941ADBA525 +72CC725A8834FB6247ACFDED0131BD5032ED40A04AB7C655AD7E954E4CEAB74524582D7C +142FEAEC28F549E36135C085A35DE07E782E72CA53BF7B2C8EE8C3D8346E2C2BA619924F +FD9E5FDF9564723BC0FBC215BA0F785532DEF5AE95939F027A62A402A7FECD77F064AF12 +9472A23D2118B569DE04888A8ACCFD6DA14E928A7C2FCE35531FF112F93202859771381D +6D161E6BCF5C6DE9B375DE8E983A64AE6AB75FD52D590B78C13885B46FBEFCABED5BAD69 +04C4624E71B29C4EF6B6C2564485210616C08A3C41C83BD947940BE454185EEB33B0F0D3 +680F9BEC8417063BF03100F3484678BD0F51869F3244EB71775D0397B8DB029D13A2A318 +2320FAC3561E7C994DF8F94EA306736B7059857552CBDA0E2DB4689A1572B509DC658E6F +5C7FDD812DBBFDDE644F980A58E05F14454F916D4458DB067719254EF77A887D71FA3385 +3D6A8D1FD29885E3F52C6E424EE0AC4E1E64180999A7266C896CC3140A3C59DE77DD941D +376EBFA09D7F3761704BAA2C738610F39E7FCA335BE7B36F9306795D5B2056C57FC42C84 +66BB9141ADE2ECD7A4ED5BF9251C3091D8B950B95CF07303B165A65A4CD198BFFA8DDB46 +1032A70916E66838CF2A76CF444ECBCB9ED23B3B32143C9A98A395E51CFC281106A7DAF3 +74AD4BDF3089EBE727C93E58025BD6C8D917065C4873A5DB3E90084716C5082F6CBAA4FC +E60176DA9B75DBC2DC5BEFDEAB261C915A7F68CD5F3296FA854324B661BE571A9CB98157 +9C6FE6A5EFFE43C9933EC292550619B794FEDB97CA0FBDADC4FC665D7955B43BD3B23A0F +1B76D78F7A1CED8FE598074469135890FE8789FADA3CFD4FB965A1FA62E55328EC450B3F +1E6B00FE274A494D25E94A2A95131D5E6C8DC6E27B65BEAFCE6095420696940A282C5AA5 +B9E66F243FA307C989352A1D557B83C5855C004D86A4BBEB11BE9F152693A77925B014E1 +6AD084959F78B2A136EA406231AB1509E43176B268B8EE14FBC281CE832FDC2475447A21 +49CD45645A78E4A0027060CAB18394DD5A3E7721B27AEB22C9E98AD563BB5FB2B0A0A759 +93F090DC2249F1CD8ED869E0316A2AD4EDB4C24B18B758AD2C746AA9E7544299C8170211 +6D591080B15C376BA8386FACF02BF9E84AB8C7470483A4D6921CA9A2F191A42BA49928BD +BA244CF5918E55F59E27D9CE90517F9485D91F1D5B02EC941BEB6AC9C7CE3E684E882D18 +7C9B3EC948A745932BBE4DAF8FA61A84FD7D1BE556891F8C339E63457FB447024A3EF140 +99E8FD37DB2AD623BA1476C883F62395E98C1B99F981F3FCE92A9DEE9D99627F5DA6753A +F46B1B69666048C981DE59BA35C0481FA33A17D511EEDD45D90AA7576573625F167C3BA4 +35B8FFEFBED92F368B92A0DC32975BB2C9C8B1A121CFC44075474B78B496E953D45B9762 +B2ECD85E0CE52B15510E80AE563235E400CBEAC6EDB602386FE1237ECF4D3C14C92280CF +F9768E60748AF4865981EDE419204FD2F18FC50E49245260BE2319DC1E624C2E59BFE1FB +CD04A3F5FAFD8D159E42B8E52E0B2279FA442E613AAE3DB6A1016579D3170F8F489E3793 +12A6E32F45128B15E01373AD0C1449D0E5F31D5DC50EED3EB856629EC2E51616F40C9DB2 +F4EB8BFC519F473A02BBF02FE0E8F86D0EBBDE611081C24B3ABE09239A9682D8D573580E +86D5FB31227823CABCA34D9BC918F38D9B3273223408871EE2D29133367C6048E0FCD93D +22144710814CEF24D9680041F020EC73546ABD22B6F521DADB8E1F6AD20AA8F33FDEDDAF +273CB366CC1F7FE33927075C911FC4D9D8175A7AA4E483C2F4AB658EBD523405F83F5CC7 +E328F3FFA5A66900508DE0682F4B4632880A3C807D606A2038F796B3A150F2202C538F3B +92DEAAE46528E1BA68E19E6FEB80CBF5155A91C16AA6FF5CA472B4444D0981D1D9F7C9E9 +FCCFF9E67FDFDD78AA2AB765E34C7BC29B2D8BB138AFFC8351FA98DA41C552F6C1479229 +5909A4EF7F4865E16BBE81EA742178C3E86B9D2B957DABD2D6A558921D4FC3429A30BA66 +13783DD39563547E9CD1FBAE6257DA11204DC8130C89C5B80541E0668752872C050A4320 +92BEE57ECC95266FB612532DD8D5465C938AE4979559CBFA8F2D7903E48CF9DEB397EA6F +31F274D48E8956D337310359199708CEA05DDD64CA417300ABA7EBE4CCB70DB7BB31FB45 +E2B9E0F15423FBB2EE5964278A536790F16ED4F9CE31F6DACE8C0FC489CA73D2457CF3CE +BB9BEBD0CFD2D1F11816BACCA5D4F9A84EDF8D7F09190C16F1B6D1766AF98A34E5A28693 +B555E507017C1B9A1B9D8D2F52E2899ECEBB6A341BDB98DB0885D97C5BB9D35EB6D18099 +594DA2A6257D5E4806D45CCA23CE2545697E3DF34B6E7558D080B030268AC56A576AEA44 +B4DA78A686340EA9B2249C58381347DE308439CBCB5988DB881340139156FFCA9A8961C6 +2004EB36FB0C77F8B762B388EAE846531CC38B75AEF785311A6F8AD5C0FDE8A61D89292D +AC55E1920923E91BBDBB40675A3D956163323406F2EAD0BC79E4E31C2C2B22B46D266657 +FD150611305CE08885360A76FF28F3DC837ACA58CAC71443120508A80F9F7086DAAC40A2 +9082706907B9751B19D67567FA243BB6595E1DF225DA36FC4F8D86712B1BEAA0D297AFB6 +D20AB0ECC8CAF709E991604552ADAD7F22F8F229527B60BCD4DD9786AA36A13328881677 +7E00F57F9E562B2CCF2D1F6F6968054D8C9B08FCA9E0DFA07C11BCDA281DE484968626FB +52B677BCAEF983444B24B0D959B66FBB9631AD4796C435888E09D90B1FE97274D8459A07 +9863D3DF6856A45BF8555999FD430FF9AF50FA060364A727503362129D627BCDDE83F679 +549FBE4258B08DF47BDC2BC161D5E61804588615C5CCC3CA6948C25DC854EDEF94A2315E +A89ADD8163BFEA9D72B430ADE3D9C17D69C9362D2827EEB15BFE3B8806A8CE373469DCA9 +13FE773C8B9DB720538BCC4D8D5481CA29661C00D1F5CAD55799F363AD2CD563EAAA70F0 +6E250629F63A0ACCD3AB2F89F579557B8299F1642663399DF9DEF3BEBE9F9FB3505E9581 +4D58D1335C9AB341F1928FB7553474865191AD7D8A89C8505B88C1C22BA7E3A88A512AEE +41B79569560C45B67497A6AED27FBBE40C8B2310157AED1078B9F352B79BCC93DDDE7803 +F479CAF0EB48AC801A0BB9EE972A258F110446154E8DF88DDC10523E8CA22A62285B6285 +E7B3A4AD23216701310C4152DCD1E39F771BF8305D35E0BD42432A0C03AF965756F25CE7 +0869B6DAFAFC69C8DB3631C918A7CB0A1A6E3248C5E1E665E926DAAFC9BED400CD4584AE +03DAEA56407CFFE84729215EEE16B10BF164B5AD7303A77423679FE14F6626C934A14587 +97A4ECA95603E5F4023CFA4262EA9E949CFF449EF9A82005B23631255E615B060E4BE2F5 +526E06676500DB126EA3D38E3562E1819BB68624010F5A984D446790AC8EBE11C5137500 +1814CCFDB10A27EB87382CF5788150D66B803F0833CD73063F2CDB1C2A56E12F8DF75310 +EDE85042D615FE028F68C668017A2A32594B89C428059DDE3FCDB18F9906C7E813DEA4EC +C3296C1A21BD4BD3C373E91E0D6B6582D99DF35F5091C09602547B864DFE966532EE4669 +49DEA26C0F7B42D8023F8EDA050D8482361EA43C52FFF4F54335284BEAC3F427B6C59058 +912C233525631F113FB15B888D5112759466A337C37A22346C6A4963E3CB53ACB141A59B +3BAF30349CA7D8827C2CEEB62EDBD851C2AD9BB8083DFBBF305ACE6868046BD93B59C2AC +75D6F3B1C243C6EF66533D2DADF52D81DF1397ADC532CE86363BAFD043F9B1B8E6B83547 +4E3BC3018912BE08A570BB4000BB13F249F38DF8C73906EE9ADC7D5630F04BECA0A86EB4 +52ABFECF46D03CBAF4BE02061EA50576A984FEDE9DE35DEDE1988DAF0A6308EC4B6BDFE2 +CB0C7198122C19F73CA7436955379985DDE2ECF851D83A425B4427A4A17AAC64D9E68691 +2645FEEA0A8A0F7A7C1CC0B3E96C519386EC14626AEF3E9E8718877DBDF45C9B8984F81C +99980A8F8F3C9618F34407CA7916D2C4741AB9B4F916763E1592BA2C2D5979E2256E2D17 +A77905EC38606C3645F1348E77ED501DCB783B8BF677E55415DF7373C47212BC59CB71A5 +4425410E29A19F74A9EA8AA508B19464BD0BD1958931B135DB014C6F358ACB880C189070 +E27188EDAA43009B515994E8F3481A9DFF6DB2D5D474F0957603B0A45A7E6ABA97640576 +11054B1ED7C692263C1B2BC424FC68615E9973A230849E771175432E48746AD8E3A15746 +1622190775BAF10F8BB66D2DF99170760B26DF8714BDF178334D0F90A615939C95DF51FF +D90B28F5BB67FA593ED31E035342E6F187DFAC21FEB26107E4ABC7F484AE11CAF85543EB +6FA887B4FEC65A760FA33E6AD078F420D4828B526B37B4AFCDF396459B6338896D7EE8DE +FA3E10C6087DD4E3F56CA302D955FABDF1EC04A5FE4F12CD40535879AF0AA992D40E53BE +2EFC1FD35E3DFA33EAFBBA4E851434334BD4551B4228BEB88C5F8D259864132E2B893C98 +2A9560ADB25C06487A75809CE201F001E426EAFDA88F9C7AC36F57B06B212F03AB8FD9D9 +6EB6122E968F3536977ABEF5E75AF5C9C30684D3D7833E3495F7F9BA021B5C4A1F76408F +B42837E068F91D9D2FB467802873702AF6216CFE60C42B1C8F70E7555AEFAE95B6D44C9B +967E68064CEED38C09BC1A3FC447FEA9902A26B6D5FCC8A42F47AD2FB2C4DAC61AA0ABFA +58515C45C912BACA7D3D32EB79DC14A4D8DAD9EC0CF8F4F213D3E109127FB7047D2DC47C +0DA7A5B790318A1E13163DB7DA71AD64BEC58BCF31A596DC90163B1C46C9175059B27DB2 +D858EB1AD055891E58C34233140240EDA5AD13695EC1FA606EC0CA9CD84293A75829B1DA +2DBB20D97F96D626D7E6D2332B664BF543849554B07ADAD02CF6DFA3BBA2D8D707810B0D +20BC441FCAD69B8D986480B1E191FF390FA02B76787CE41E3F779936A2EA8CC0167BA167 +E4E08204BB8F4D0CE908AFF57F1E9CEB3F00C1B863BF65443684BA425888ECA909B2A6AC +5436D996810370BE779C30D21941A101B2EBFD4F38DE2295CA0FD39AFEFC997377EFE1EA +C62A9347DE13284235061173CDBD0C97A06045EE97A193E79350B8762ADDDC2494A68628 +173A30563595266EE3AEAE1179EE7CCF47A7F9A84DA4B4120FF6B12FD8784BBB674404C9 +973DB36020A9A7EC459F263213846A56FB52BE79B8D1F52FD8EB086A761C665D94D01336 +D5029A5C9C7D7C1234BB170E90CBCF1AF8E5F5B21CCF7C11F9F2A28384B844B1F8F1E543 +393EA9DFDF15ABB11520408BA5242CE5B5AA7EDA7DD72D3D9B939AB2AA4257764929C8CF +5F6806A21D524DDBABA96FC46B942AA00F9485C1F071BC6C94E65A153045F88BACB20D69 +6EC1405D8880ED1456162625EF0EDA8ED6022F4E6BCB8800A23F762EA3853E45B4ADE7AD +4620E7CB83EB1CDBD40ABA6234EBE853B3378EBD4F077AF9E12E692995EE06D45CD4CAD5 +ECED7947A89DCE4A66F1B265BE66BCFAE487B41AC623ACDC6667018626CA450FA2E60512 +23B86144AC9A5169C29FFBAEEB9E1D65CDEF2A5BBD29DDA5021AB9F435C459A3809A5DD3 +6EDDD773C0530A1BE54910B014A6AFCC1D95E36A5C8C7D8DD1DD091D7B14E811D864B1E9 +41122A7867ADB016F949DFAE0BA06FBBBCE87C833C6B244AC48A7481C54FE756C2438B00 +9ABD319AF57D0F69874D274F96A12BD417E8CBA7E20FE608A73A88A935EFB77DBC198005 +1CFB9CBA94E196A412C45CAA4F890DD9334611CA1D8D6F6DFC3C180180F22683BB00B8B1 +0D78BF4D64DE288D2ECA95878C2BF266880E547D3826C5D1F3C6B4B0A3EF0345D8FA66C7 +EC77180BB59A6CA349687F18FF5FB5B10AFDD7A440E20F55650F258A10899BD9467DE2B2 +086D32150FF9242346A6546F9A1548436BEDD02049983A46A2CDB4BBA8BFA5F04D7BCD4D +35DEBB30496780236DBE224DA28218DF58037509FAAF6BE46DFE5A93C1F072F37D80FD97 +33FDCA1345C468C85CF501D4EE30D36EF5FD87837DDFBD703B8F6AC4AB3DCAAD7E7C5E54 +B6383A74F4533EB9FBA0BD8D1D1703590CE24FC3DA5E5BC929BB6EFAD09F02BBA5E30315 +2AB1CE32A6A2F61448A765D912A8DCD8A8E0003CC2BF739F4DBDB388320D990B9F00E04E +05AD6B650435F44CA9570D878D89CE782E06C68BA9024EB887C6FA18223F587338BDA034 +893624FB950E74209BBD763A9677FCDE1236B74CBCFDDBEDECB58DB1DC445BE8672ACEBB +05F0E677D133DDAD4607720462C63FD9409C29C75039A9EC34EF0BD89B3AC6045389A3E2 +136C9A6D502D335789CB74B7F369A6877C01CBA68278828D17C5B7C0DA4F385FA21DD8C4 +C68B9E17A35905DC4006DDD3D35186E31CFD74C26E7FDC450E6729F81FA36000E7EF2AE3 +9C4D80D9A94429DBBCCFC44A7044F424E90C5D156CE1696CFA2EA4742338359287297CAA +5D616C1F7C7E7E71CE9099028D6516FFAE321143EEA343250553B3249C2937C1797ABCEB +BFBBA9BDCCD5A15DFB20E3772660DBE2C410BAB6F4B1BBDC61AF96F88BF830C23564D4F8 +2FE22F6B22B63D06D1B40DDD976E19C8B361239546890888FAC5E7ACB15C4762C4871DEE +EF368A59B6BF8A359E29967FDC8A59E03E357D3B84843B20EAE12741CD9E2F2A3A32CFF9 +1DA33E881008CC686D03A1D55651986C00F7796559D4D8825AA811EE8810B921FE485D43 +1873E682B76E96ADF5A586B9C1C5A876AD507C51545009F09E2241835ABE9C6CBC76D88B +7BCA368487A11BD7654EA0B1EC5F8EFC9B587718C732037B875ABE9F5D44C82B29FEF550 +B80FC0FF7AF43A6CDDAD7A3E8024A09C04CC5570C1E91B97E7829AE7402C870E5496E8F4 +B12B0D9DD500DB6F8546F7C2F965387C37A701F2B43D236AFDD777537967741E88F7BEFC +9D9B3C7D6A86B1AB92919A48589CF276BB9F00DA2D7BE38F46C9E5B2365948E32A30D830 +0FA8980D7D7C6ED2252D9465EFF276856698108122833A0B3E774EFDF55A69070FBC7E53 +E955C4E02CA71323261353E8F5D1A4948ED41F4AD7E25585E6DFCF5553C9187632617F3F +9D2230A478E4BB63497500A3CD8AF78C780E700B14272AB399D2D2FD9979A9F422DD2B92 +8CDDFEED37A40A77F93A1BFB9ED9297B2BFCBF9FD40A44D2227F4C7EEE3066F1020EA335 +91BCB47A260B744919F0359E2AE3C619592C325474063675E5D85DAD5A00CC879EFE071E +68CA2CBD108FAB3849D312DDB823BBD18D7C3D61DE7A5E4AFEDB203D4056B43EE1D93CA5 +0BCC10AECAA08799E0888B637B6D122EFEDF40DEF30CA93485F424928F3CD6AC66D85035 +F8BEB418C560E00331294B1F57831C33F8ECBB2561837A5A0B0E5E2EA2DC3F72A1C09990 +11BD2F0A0916AD62A8DBA859AE63FD73491390CDE70B0C0B7D36354BAA08BD6014B790FB +33FB26BF6C2215E16379072959ACBEC5485642A7C7ADB0B826DF3390C36C9B28E724D2A5 +7F57EF0B1846B358669EDBBDA569EA1B28E9AFF2DB2A8DEFECDC073D954F3879175289ED +9F159376F3D1301EF514B47D3EDD5092C4618A80D20ED37D4EDFC8621CB7E4683AD8B2F5 +51D666B8F39C0CA193BE383B0DD31BD540408314871CDEB6117ECADF8E187D1D5ACF5239 +1F8B2B1C6E6F89A35022D0A2B8CE22B79B200AE116A4E9E097872CFCE5BFF8CE9DDE2E85 +087649207EBEEA22E07187C24404533EEDDDA851CA5E7C18657BAB75029DED2D381CF4AD +2D5D52A310EF4B8477008C11393D74B34F0FCA4026ED3C12C71941A6D77F501A649C8823 +2D9A1EA080561578DC7A1D591B8E922BA280977ACF3549A24125FBE9049C30CB9DC547E0 +766EEDD5C0210C248C4E7E435C81AF15B187F84C216BD842380436BC3467225938AAC1E1 +FF7CBC6E6C59BBD50767D3BCFE93564F1905AA38F1DDAE4A783E857D148289304F8DF194 +CCE5CFE440CEEDDC5F3CD1E1587F67DBC41DF3CB4F08AD19178CC4B77B1DA3CA02B6F40E +36984E0439E53877225B9F8576A9A2B57286D6F759A060956CD30B6E37473CBB55D76FA0 +2F4588E66305A1F40DACA56CBCD42883B960B6DE2F91DE519C80D8FBEDBE38024EC6F6FB +B6FBDD5323235130771153124CB95ABDF622F737A42078D8E81C9965B7324F231A072739 +5129FB30006987B2BB806D414672310FAAD37F3FD005EC54D6BD2170AAB9A21E52A9A7C8 +C6AF03F51488D34B06F22D93E72FA5BF7097918FF67DEF79A6D62CB216ADB114A01CDFF7 +DD387A0CC150E852D4D267187F6A6DD6B78C9E283C9D547DC6373A36F3252CC683CDE9D8 +EB7221146E8C54D1A90DE57003A0CA78440EBFBF35028112B431C508298BAB97DC45875C +D002FBC1E47BE8096D13D485E2604EEF44B0324B0F494D874A723D080A9A32B9668605E0 +18BDA773FFFE5566DDA289972B087D9E69268B2CC04CC1F22DEA738A2248F370328C7FE6 +D50DCC267BF736C8C3418626BACC805DC44F60A862413D4C76104D6AA64F813ED9766563 +3236CC8EB519A9C3A2D53D20658BD68463BFBB0B97A795A78280B0C05DFA3FAA5EC6E6E2 +879ED3817C5FFD07949528C3C60DC6A8F1C73B7B87975A101AD9097F694B7D3140B2EED4 +52E98F073ED4648992EE76954A712C1804DE95D1C1C98048E5ED790B3269BE49C7653292 +E69CB482E19611F24773F00E483B8541F7D1EF3CB9730F527FF6309EC105CDDC9BE9F9D9 +4C28B3520719E5AB1EACB85BFC4CA92ECE780476DFB3BA759550A261B675ED4E1C1325C2 +EAC510BCF993FA03281FFF75833EFDB168EAF8B2AB92AAB82B389E7086822363A74829F9 +FA36C1703081E55EAC5E6358866EAE8BC04C37770DC97392713F110C143B7CEEFFCDD84C +A6713C01B4AF3732DE935DCDC2223015E57FBF98DCC32ABA1A989176963124CD353DB3E1 +8998F5F322EBB591528544A4A4E0618076FB07540DADD6D00F8B66A60ED5496CBB703E59 +45EE138D7CD77C301CBF0814A7AEAC93127862431265081273C1E04B6C2B4DD0936D8F34 +98B2EDBF2E2E09397169EC99FB85AF23E929F4871EB8FED7AA77B2E22AD7AE6C86F15B07 +A01B8A1E3F8381CF2A7AA25FD49876DF2E0DB253DED331F7CC0A545BDFF42CACED8946D7 +9661F3A340952AE1CAC541F0F6E66682A22AEE604941AAFE270C3C2AF132C9925A01B35E +D770156A0AF4EF33B00DE099330D5A874F84A23621C6352DE80952305BF501442710DED6 +97682CB92BFFB645C2A48C49D47F8664BFDA17F5ED7A0F64CA28A05CA58F06A9296E6BFA +858B5A728B28E12C75D947DBDF779F738D67BE839FC0D80F3DECCF255898CB916E2BCFAD +74FE85DB8AA036791DEB28487B368F14F1FC79E54D4D94074F8FB530036B09CA8C44468A +A199990933422C6AAAD716F03358E8FCDE9DF706F0590037971AF1D705DCDB45085D8940 +31468CB922E90E44AAABFE7DB1D6D4BD37081491EF89F46FF4F7FEE501495112CF757202 +448FA93DCDA89464D7AABDDB7BEEFC9671BE5A929DE84677636F12F4BC22A59E22F57BE1 +E680B67FAA2F00FB39B6FC7A48E43DDAB93FE9DD75869375A874B7CD49D22C314D617848 +139D61022A79D94AE1FF9E07C7A7C3437709E09B92A8F33AEC386DD37374051F0387BBD5 +F366C3EA12F5AEA0569D15B22729E006748E900A17E5D4EDD52FCF4561925C7ECEE84B3C +F29BA83B03EC7ADE70040D898BD3EADCA66DF42045C795ADFCEDE3DFCDAFCC68391DF6BF +C9CF4A49A45550F6301B581D19B8A8F7CD9E06BE7A3C5358D6A319188A803E8A5CBF9877 +B8E53CBD98E3CF270330BE2BE853E5BEEC128633EBD5471D9E5AE1D67D28E17C752C5443 +E16B6E1AE341E83ED9B6CFCE88A12A7329525C0A3BD2D8AFEF72D727B3104F12BC874446 +FF1E5204DCFC9CE7F772855D63A2A8DE36D382346F8C43D7153B9BDA92AA04600267E704 +E9F43F3D625EE0EE228617C7ECFF39AE97806096BD66B914A43EEF2917100C2F0E1B2554 +C891D50C3A0037190C9AD8BB6563E004696DCE62881C1F6F8F05A96DDAF3F89CDBB780CF +6B7196124DC1730D05CF821CA85156F7EA996C7E3A44BE8D4EA29ECEB2E49CA7D676EA3C +874594DA4B8ED45B1568EACD8FF68963E24F2E05EAE0908D1E81165B872F3C6284181CD9 +A06996A7D247A1661D65DC5558E0CBFE14724BE1D44B08A1E06D880D87905E889AEB0ECE +71E3A9037621470305B423EE63C2BCB5B227B264A4CD5CF8573D8B320004D212B65A44E9 +A856A3631BA02C46868994BC9985F219C9DFCAD9591F2B76B34904DD221E7C9BD2DF06EA +B632E6CA2A24699AE6C9C6B4937A8293CA61D36F3193D888D5081E4CCB837D93438602EE +DB2D197BDBCD0A00534B493E250ADEBB1D79238C8F8076801EBE4A282C98750ED7BA28C5 +9B903A26553E03E5B1B99A2B1D13BB6624717357E3F368B65C8B2AB2606577E45345C971 +CE54702D072593814090A9EE9559DBB28B3A3F44328C33F652FF066F87F1B251EA5098F1 +1E970A3505B982A023147D7D8B077E626727B1AEFF6277BB306423D55070829D73895B67 +3E2E6F9A1F954B6EF69507E1BE86D6C594AE270D54C39B1645FDA847DC3D3267AC9E3190 +9A509C03DBFC0A063FE9FA2BDCF21199FF1397A93F13522702B339AF7E6CD121FC2E3D4A +22132ED26FB31F2EAB17B8DA9AEFD61386EA3EBB771A43B60EFFF3CA55238BE1A0852F8E +5B78DE572FF42616F1D4A64E40C722AF8E194464F506FB9A6F52E52ECDC7D31287373EDE +F46C5DEDA0CDAE20AD6C88D6315714304D8589D6A24DCD9A0491598AC69638C04A19C07D +CEEC1F8325317431B3892F270779A55F293085402C4B4085268AD69995186470A2E2A106 +44AEE77DBC20926ADA20F91B5BDCC0181BB34C18D1FB68A32808ACD569EA71E627FB5419 +EA3228DAE56414EA93250EA395BA750C60084D2BEDF6144E970B0C5C7CF40B05EDB70452 +7775F2D0A55E33BECD54B9F91807B097575929FA313EEA4B8EBA80F9499BE28AF2A3BF03 +CDFA19AFB30DAC150756F90B432083DF21C79616A054384D91F913520EC45133A30C84B1 +C1EFA0D1AA9B4FB33908CD93F76F6A8CD03F8714EB0E688DD3A5931BA940C68DA296B217 +BB6E1BA16FCC974E3E9F45A30B47EBC5CDCC6E2FC6AFDD826A1BB6851F68BB88C2879B21 +81BA06EB195D8775B8CA20B436B664BDEF465309FBFFAA48B0736069FD790DBA0047E4BE +7591F6B5849B2A1B891895EC40234269370FF1E66AF3D391300E07F7987D3B168C9F4770 +9AEA1367B53613F52EEAA64D8D296396EE3B6338B8479022B19A9992964200413F29C3C9 +9DDC50C2C61B92465E339B9A585CF0BD532B2F2F3B7BC3597AE2B89C686781AB7C1A2A44 +A6A897F1CEB49F63DB43D9DAC45F92880661E79D2C292CF910A3E75013D4D3EE05CC1A7F +7EFF6810E89660F47D06DF62507A067B1F37A100CA620992848EF811D2B0FFE0FB8A85AF +D58086E2BF8ABA3FF4435FCEFA66F460BB9919A7EF73B5FC511BB3D4C91BE3E90DDDF6B4 +4A2521451B568A167D4CAA98A2BC114B77B2184D15F98943660EC92BD6D0B5D79449FAE3 +089A4709F68872DCA3AC59ECC84A66EA19DB2FDFEDF7F8E57D90F6FB0E856931EE8EA3BE +8F3D692E4CBA21BFF24CC7DD3366D5F7E57A190F61502CBA9C274DEAED962E5EE3CE7B16 +2E34BA08806B7358D820009CB348B10F225EA9DCB92B0C0CCA4192C3437043132CA73E96 +6527062BA32227B2DA597C8E3E75436467F2D6895B5AAF1BCF55A02267E5FC21AAD0E8E7 +F2459C0B6EF0C372D72F697DD46475075C4172E50405703CD18C23A6D3E7ED6F526C3EDA +DC5AF40507AA9A76C86E8136CD695C955D7942553361E63FAAE9C23BF3A24F35F8F9B659 +90D7A6656AE186B1C596A8E3F69748427F0C09F5641F284B674F46CF3D0E2708419C1689 +F40A35DFACD95F8C6A1EE07E7AC8E9FAB58FEE8D52E81D486F5950685CD4EB36EBC16FA7 +C0F420D6ADE912042CD2AA3C60B2468A59DE0A5CDAD889180BF05405064ADE97876CE977 +D6F665803C8BE866AB0F1B08452A478408095AA3B8EB0FE8490AA682DD00CD3AD3592FBB +54CC977B46E3CE307E7D8EFBA586000BB17EB0F2EFD0B0EE61CE18ECD565DEE97E37CCFA +323BABB4D6354DA19CD9080C96D13A5E6AA1888B17970D7DA8D1B461822CD70CCCAB9F30 +D48F924C91DE9F3243FEABDE5C3C620CD32A5AEECD6BD20EF890F1457285ECFDBBD22BA3 +FAF661BA18BBC1E6EF81DAA2E2A7CBD7A058ADFF961B5A103D967C610530EB58E2D78DAA +17BEC7C9176EFE8EE633FC227BDA64E54A6533B6D56B787F5098C47824ACEECD50CF4C3F +172C3C7DAF7B6EC9FA8775C52609D08B073B784951D66C8AC33222604C634E99E99D28C8 +B45846715733EB3446CDDF659D1BE4B439CF32FC2841AD3DEC81A95B20B04790A669EE4A +A9B40DCB3BB6F0A68E5A2763A8CE7B72586CB6006FCB68C3EED89E54698EE5928F10F5D5 +616EDBF01C349C20E99261495735C1CAFF99E2B1FC986A36552A37D7B57C1D4EF460ED45 +FEF6967FAEDE8AE1B2C7AD835D31AC8160B760E7A36333B83843EE3F55BA19E2F6CD7D33 +9FF0657577CA58BAFA3AC0B7302E88871974DC65218E856338C81F00E4FB35F8DCCE6208 +D7F1BD45C3792D21C308A3CB7B50AFAD17EDFA027545355991E99C1EE99D85BBE5BBBCED +4E9C6334ACE88F82894B4B1F81F51DC6BBFB2621CF7ED7FAB3170A5DBF6F5E82BA316172 +60223D7049D20ECFED36DD022307D5ECEC358D4A8E7DE800F7D7C048FB265C96108B6D56 +EFBA19A79D37CA7DF37EA1F778B74CD5BE98A2B13BA7E69DE56365CAC9456A3C248D6828 +6BBAC51CFD6D73BED3BD7A7A7B9800B63D1A94882A52F322CC329F1BD691574732DCC32A +3425E83B88EEF053240D7C7C643A7FCB0DC7B452E1AF9131CB776D450EBEAC8F282B218F +D1540E4816E53C488F026A6934CD059DD5A09DB1DD8016815D066551BCFCD503CAE5FC7E +996E67351A6D681EB67D78F1174B3041096687912F43F6ABD7078C7792EC69A42ADB3F40 +95F326C049344123D0F93EF2D79DA7E77875AE9110F3E87FD87AD187B566DBB723E06877 +462C366B15BCBC0D244C2DA7D033E0BE800D3DEB29B295B6326AF0E5F151D50D6E1AFADA +88A3E0B990C1660004FE5B25F2BD607AC5A141ADCF984FD2EE49871B9BF5D5A1B3D96780 +B4E0AEEF7B4400AFBBDA0350A1586294FCFB5EC075978ECC7F6222AFBC50C6A0CA10DBD7 +8615D8128DE67FE07F2E3869900367476DA42C78AE359894BF443298166E7C935B310FF5 +E1BB2FA0677A947A7ECF0A89C3FBBD60D4D8104F220360D505EFA6AB9CE111C3137F6E51 +0616EA60ED8D1ADBB1B058BA22A6A76CCF8F0FBC04AAB81C6439F44D5659E937118995D9 +C299BC02E354FD4E62E10AE9D2D80CCC72780909F49E6732A61B131E7AAB8EC3D7EFC725 +A153D69D3204AD5F6A3AD6728C2B9E26D337E846A797A13CDB160D740D11FC38CCA2DB5D +E33074C7E5601C8573641E40BCEDD6B84CA7D15C1B86F42D4EC74C2CDAF65D5E22929717 +C6237AF09A0461AD9237F71C011BF36C00CC630E0C55D1B04D7D989EA011D282B77A4BC3 +C54B5440557303C245FAEC70FD1945A8556B8033269E6EA1C1DAAD39CF5A1BA9F6448684 +EC60E9809ED363B0134FD6F19F208FDB26A4A828EA42322550BD312044EAD339FD8DF100 +0E9F64428FF8C72C51FDAE3E7A69B6D0BFC9B2664D7864163ADF48D2F3EC3629063A39E0 +0B8B4DF52D2B855AC448BCFC2A3BED94D0CFC4A66FC6CB22D158C9B1FF632CE71DF9E1DB +CDDCB6AD62101DD1A776CA2A111B283E25D1CFD8B5F238E0FCB2008FC1DDA4EF6CC11C85 +96E38D6DC1CC624C11EFFF6DE5AD410B7773BA0C9C8B9E5F3B7C601222D810E921D55DF1 +575F452CEE78BAC9E306B0801234709349F8C7D603AA39CA94E878781D5355B6A534D5CA +06B774BA53AF73D36F60705629854BB39552ED6A4508A20633D2FDE04ADC59EFB86BCC91 +AABFC0BC1CC136BBD43D8934C54D3062D129F4AA3A37AAB7E870C6272D32D2E56D0F260A +75F6037AA30AE59A3A5C3417021026BA3DF9E6E55765F5B0933AECF62E28C342CE6C6687 +6FE4231A5AB35F194D7029849D8169BC54B94F34DCA13AFE4F5261102648C1FF98212831 +D76A892CB55AB502AAF52AD08635464A7C65AA6947F6CE69BE3C7984CD36057A31B2D8B1 +935122CC567A10025B6F4E305D40B600D3147961F914DFF15C07E6971A4B58E2D8F02F4D +54F50947094617BBDC1811AF2FFD72F5376BD65059737BE960D52C9B41F2FFFD1927F3CF +750FF71292AFE92B978F1A89EDB201F71D014FBC8D2758687039EEBF1ACFAB367C555381 +EA24C44F1E0EE7FAE39EBA4413FA3DE14F947FF5B3909323BD35193B6E2BEAB668B94A12 +40E61DC39EFB28634214B3A46CC0E00BD66D5B2D92B14A708098207C092B45351778E984 +E75DCC4AF44F9774821AE9FD16F44B733C611D708BA56895FD42150EC39E3A86E7253C70 +480114E55C14AB9F448CDE802540B710B1B22C0BF0CF557FE300A2BA25A0D841084A0178 +338EAE9D3DD9B19B062C76015CD0CE257D80DFDDF86C52FD7BDC4648EDF57FE1DD48C1C9 +AE6A3D17FC3CA05716E302BDF2F219B52E16CA97E63ACF67D27EBEC25BED0450B057D378 +9545B823DDCB91E9162D0B8BA526A918BA140A99E32287165394D51499E3CE10F75C9881 +BB3E3E6734B5380623496697FF66123076CAD8648A11D710988ABE094F9A11F4645E399B +91444EF95F0317E07B38A3D6FDA2241425A175F8495D25FA347425E419A78BFC62D17F92 +888986182D3DD448C236B84F46C7100EC23F321E73BF1839EF3500A0B147DA4B93CAB290 +CDEA0EC5567AD07078D426A98601D292966C172EEBCF61258B805CE42DEDCBF73995B8E1 +6580EE97FF610B938FCBC6D2DCC05D59E5D9F3BB90981F92C4545DEE34794CBD60FDCDFD +80449225D216246049948AF7B161D509D34F457F210116D1BDB10AFF53AEA6B51A49FB22 +FDF56471F610550D3133616E184B7D06539032DD560C4B5B54859C4232781326ADDF91C0 +98BFDC7B24A57BC4E69E97707CEA01F58D0E5B72919B202EB8852561D37FA219DE667986 +23D6CD0535C2CD0F642238D80452DF1482B1197076EA7CCDFC3C336B0FC883DE2FABB5DD +C80041A4104E575BFD65B4EED3BF9CDBDD4B83BCFC7295392850F8EB50C4D85DCF6AECB5 +C88F6EA597966AC63872251EDBF270A94512187EE6483D272D50B5E4B7F4556EB9B474E3 +85DC8A6152FEAB40CA34CCA515302C6FF2E66C42E731673962D2FE5320D577A67AF1B02C +A3697EA85E771565B97A476E388A5DA358B8A1D30DF2EF680288F20E3F5BAF340B44B7EB +5E531E569896FDD63DA9AE424B0CC244D99A0256488922A394F2E31FAAA47D95D90BCB0E +83429ED543041F2B8635F3033122F4E114096D497F6D993541A6CD7A6747232B88A3593A +71DDC13689EBB077B3552C366A4685B48DB7E9A0102F02A1C1A31662568DD1D4D3D95D9D +B2C491A04534833CA789145A6570F4B6E8FEEB77A9E9240FA9820695380C4A231D61A58E +F20C07FB1CE230170387CFA28C408D3251ACE1216FF77CA0D54A35591822489C0CF393B2 +4C26623EBC3A3A9C8DBCC5779A2EB09A8EE6F1EF3D97C107F9BF10252698367A16D05E84 +E0B41817D06814D26FF79AA87661C7C2D5487DE11BE2E4DDD7C926834DF8532652AC8DC4 +43FDD086A256005BFCD9C4D9F05D0EE9650FCA24327400BB5FD44F183227F62720787691 +75AF9CF033C19D7B4D2D52FEF89DC3BA145A1CF750AC8AA71EB65FA16FCB377F0492736F +33A408D699FA3A9472D422751E333B368FAB32C05E959591C3977F0A9B94E0EAC792E1DB +BC609E1315D59901672AE9A5ED9381FFB2864EDBF657D8EC8FE580409B0C8AF08892C00D +DA1D2D32CB52611060BFBDADCC73B272936A150A03EC52B4AB5A196C28394154DDBB879F +627E656510322DAF03F018E917A40C6C70371658095B7A9CA96575E976DE9D2E3719BE63 +33CE53FA1B970455CC734181CBDF92969555C42909B590908F43C81FBE180F043FF8EE57 +965D3B28C0FEBEEB075B2DE3444B117F6836E12234670651230446DFD71133C169B9D743 +1B26A1E5B251B4E7A170133FF9B403D3F345213A67C80EA3F48E12A2B564B97E5E570651 +070EA250C155D9F7F50D95BF852F1A337B152A2167BBA4F2E1FD348DEA9AC2B2DB341B06 +07422BAE29EFE1F7E1CC7EF9EB9C1CE879C0BC2B4D3E3BB126879C4BCC0F9219D89064CB +BB943487ADAD2E7A5E6A72FAC3C2002226C24462D7CAE7ABD0687F785028CC6E3C4F1026 +A994669C2320444BC35BC6CF8239FD0A4B4C663EEADF9FE60ED2E4ADD276680C5C84488E +2956D72DDD2A49BBC3367EB742CC9D69AE615CE4693636373743DE1FC06429C5D5F19E42 +A6285DF5394041362F5F43F219977A7B4101E8A3EF45502DD8E702D677423271333664ED +727310F0A2F12CB90332228BDA42FF040CA6359948EBBFEA768FE2E85F344E38A48A21DB +04C8C47CFC95B14DB8ADEA6A4994A366E8D46A4A1453880390130A157DA8B5D14B250893 +C3DDE306C62E466968F1EBFF0AB0224AC7F87B8746B816EC02F7FB710176EC2104662591 +4D2E5083ED6DDD42EB82AE75EFCA4B4017E00B80CF11CF347CF1D9A1F43C5A7E16A47CE1 +CF113A4ED121F109F763DE14B756E396C59E9412CB166FDED494706C7B9BB806387921A4 +C4A1FA6556D82F252E69C479D4314252A146F14A310B0D3861FAA13FBAEDABDE8B238342 +897C50E88A951A7C63670040DC49BEEC93CE42819BC79A5C974E968E523CDFF701B6A0C2 +C1E00D0A2C889BC270C0A94A58B8F44AE45AE3ACF02357A1A78AFE2E09755E0E48BE6221 +A06C91800234AE2E2687049E0372C8B0B2573BA6F044FB9827C1D6DD90234D91CC1BF4CC +FBF14E163DA400E2BE334A4D806B3A934CB6ED7674DE6267B3BA9BF4820C4D41FF661E7D +10E0EB3F7358BAD6C01B7E1EB1DEF5996678548E589A2FB993126E55BCD6BC1BB1F0D4C8 +1B1088A7688BF682E63D54F55CAF1C2EFA84B79974439C4F90B8D05DC7C300D450BFCA2C +240CE0D01156FF5EEA35C9542374BEEFFBFFB332E14526213ECF605DA61DDDE45AEED1B5 +C29217566ABCD452A266C8668369B6C4871FED4D830735A947A15BF41F0210235476E83B +EE843F80375DC95FD0D3D0480202033BCD2D83DEA1B0DBECB3D55EA6AFB96F5B6FC48B6A +7C1308346583BADC3B7AA668DD819F81E82747226FB67162B8F921790663FD7C0F7DBE63 +BFA878DA1434AE325EC02D786FECEC94696863A3235D048E80BD57857B7F0E6B84C2067D +F04AD7AF6AF06195B4FCD01D3257480979D79740D4A5EF82D2D5F6359890B1BDA818B8B7 +43620F6844689B7005B608ACC102444067FC7752EE4FCCCF24321872ED9437AF8D263AB4 +123213968A9801D2F9E902D540FBB430BFDE25C15A8185B42BBE510DF4E9F456286F28AD +DBEA5596EBDD910C7E375DD40500995C867C2E5BF9AAF54E57E730C3C1F199E78ADEA406 +8AF853A645C0DEDEC05C825DF25511FD40B0B6761547BB986AF1E878F905723580D7490D +026D2D7A49A2E553010593189A0980DFDB18122405110422806CE79E7088487F7FC5C80D +33217362356D42CCFFC9F51FC103A68A60E4CBFEEF0852C998FDF4A3CEED447A2D77A9D1 +16F88B6ED092FA4D25C59E731A03ECE98247E96B055EB4176B8BA5F795E6EE92F8DB0446 +540207D9FD913E00D20683128E3B99F3EFA0ABBB945606B30E0CAB0EB6B91D30EC381184 +E5046DD2DAD0A4B5D3C6ECCCFF402C1BF5B42E7AC1EB818BC76B92BDE97DB485A9E4660C +DC3F409129B5BD00E573E2B4DFE2E0113E288974DBF9AC6BEFE9CA8DD0F73C8443C906CC +4D21BC9ADFF2E9ACEFEF101A1087EC168EB9EDD54D55CF072F4DAADA363C28D9E2FE52EB +2A58F4BE72A494F370575246965A4C4670A7F4B47F118FE5BC17ADF7DDAA469EFD6A13D9 +8A148B02700D4D374EFA01E2C6502E6BE36F2FC25CFF1D6A4695110595BD358705674162 +54D33C3DDCBC891265EC7F0FC06BD7BDF70D7000328062F889C4BE68F4FAF0D2C2F5D8B5 +C61C40A3134433C222071270F466D9EEFAC22119C67A9EB2F626DF8CF62F028ED74CF733 +1181D642532801BFB127A1946362F2F8BC33B8651A565ABA0226943CA88FAA9F0D8CAD31 +7B7D2B0B0A5D10907355FEBAA4BFC717BBC99A604178B897CC8CD98A14531E9742FDF11F +8D17D2ED67DE68CF3E2DBC0FF6A23C876F3101DF942314DF0D06160643C4096C65B90E15 +4E2D0CC44AE46932068856CE3EBD03D8A74EE5BBFF74CCC54F0E1D3EB0756C29923686DA +2410B414A5CD43855C82BDAB7AE111E284FA77BACBCD412A438F59FA4006C11F4B45C502 +24F939A12289F846A43E1A5EF39DED94922AF63537D12EAE8E4641D5434BFD058FBF163E +586556CB1E13D15A5487091D9BD004C556CD533A25E40F97AEFB4AFA5A2079C87701E65C +96405AF89D0D7BB41FEC6C4AE2834F99B1426B47EEA08FF81B13AD5738DCF2013E45FF93 +38652EA8A36B8690ACF0997A1CC2501219AFBFCEEB79ADF018B5A55C8734924D5F6EA575 +F0DE17E3BB3AB11F8930DA1A8F3CACD9A0452145BA4F00BCBF072826F1B6F1B9FFEA2736 +7319B85F39FFA7EBA15305A338452211E2D011E566B2B5A822E478BE2852853A1A8D1270 +C9E5E6B80959DC2C1FA70F62765CB50154AE0FAABAF9BC997BFC4C54F63D4D2B948FAA26 +0ABAC11CF0677CA044B1783FB87D31B1960CB0B21024AD08580B0CD6BC4BE22BF8A144D9 +88063037F1D2F17552A15D47D21CFE1B88298BC7F715555783299A9FDD4D131F1645D195 +E6AC8EC0BBD1827548A0F971080AF1DC214CC3720969B735EB0858DEB89821FCBD047BEA +1F1F8B5F27C98785342D56C145D03A0469D92E932ADBF560D35D555893B0D2F795918DDB +D65386906E232A3545C916A9AA57403E5244686BD99006CBDA3E93BF9A22A2F172B58147 +4480A90190018CE07634573D67C93211A9577AAC8799CFE6FED8F9274D45ADA841A66CE1 +EB00BB0330615CF756DDF0D6B9DA2B59480E63F0A40DC2E635EBAE9C5ED7283188B89551 +96C155259DB91835ED78A3D3BF07EAF6CB3B3CF6F4C0633C764D8B76592FDE07B62D7DF6 +F5D16F26EAC7DD91E4296442225A5A02A2990B222BB8A1239B38F83A807F828683935682 +51A567B9F68558885FD32E58C4B22D467DC494F20A3428F68A18F0037E8CF4837FDD62D6 +EA3CB73E8ECDA81132256DD09F7CDE0CDCDBA85DF239F2671E0295031A3184F7A31F5F05 +A29A40534BB0E02C99089977172A469A12D331448D690EFA0E05099A960ECC3D9DCC4BE3 +1447F5D77CF9F59078307213D6666E6D9567AD8A341A10C93A6EE3C726FA3A730835E134 +C83E47BBFFB68A5B8ACA88414800FA1971F0B7162DF5EA90BCBDEC7B2C2916F4EB39FED7 +98DCE6D49E8D36A188A18596C02FA8F8B5B1C9C67BB8BB1369EC2FE51BD0E554F52517BD +5736CB8B581C4B083F891903EEC740B3F52F404BE51F26FBB90739620719C528DC56AA6F +185DE3A0145225AAF56C7B8B510F0B6C5BCE56F69DFC3AB39C5A9A6110C54B0C014BFED6 +06808B965E8B4CE61BC3CBE66BCB6AB0C53457E2EF94EAA1B05A3B9C459542579FC7FD69 +043E9A4A79E6688CF835BD981FF5935E7111EC2B4FFDFE1E05825BC54C55A06D737E1BF0 +5F332D6B958078B4F3BB7FB1952960F35C28AC9DE3B8A5443650A22DBD69F43F1008543F +AD0ADAFE7A2D4CC1158F6DFE38D5ED78CEA0E8B742D86AF575C3DD05E07339D95A52E7D0 +8F28B53F42E0EF55E488782D6DAC953C2B46C759D7AB0FD9D521B996B4F492C762250AEA +0371EDF1A6C892CC2AAE5E8CF85C9532294A7598152455F1229296BA051DD83CDC08920A +E0CDCD29814EFBFCD435FB171DC21C75B6765E2FEE6EBC57941C984E05C107F0B696839C +E94FF8D337BF520AB53FCA1CA456E5404EC1F05F71725E8545FE4DF3E612FC6C14403108 +2EDD3E5150943EF21E845230ED91BB60C95CA91F1389F299667673221A8680DE65D12BDB +1AFB6C7BE73520179FEAB41FF62A57B14FDE16CDE460F4FEFA016A555445C78CE88DD0EE +A01D49F22F4516E316BB4EB03E5C012291EA5A5314ADD2D16645075E84E50A11F7ADE384 +592EA0A2AFD06BF19D2AC55F9C7EF98FFE32747DBB496FE6A61F01BBF83E0AB9CAACBBA3 +3598EC42C422EE412EF1B1F1704E7E59F28C354F9F6F5B64E780EEE47370607120870DE6 +2623F01C4F8A46059E4DCDF4CCF5775F157DD756D45AE5AA6BD5EB415B04559796AB1270 +3CBAC585D4DE40AA03CF8DA7BA33D863EFAA0F7B990316A7351D9A533E2AB6576024DE45 +176D6823F31DC55A0CC29B5BDCFEC6C75F5D11D67BDFF15D083CA9CB9DF28DF02AE258EC +5611ED8D721FE60910CA5484A9F5DF3449F85D7F9900C61F4FB43617446E5E74E1849977 +0A0B686EBE371582B0F8B9D811F40D7B01296DD6D3DADFEB2FCE5DA4D93F97B38251626E +D3C9350AA320EB926688474DBBA786DF88FE9BB502AC65937890DF9BF4E1F20197F3CD40 +9B2F7766078FABDA9C535FE03BE36DF70FF23BA71CB322A9A18A88CE6ED79AB299A0B707 +6E180B8F282CEDE8551094B7D2AD13360CDD68E0F4B8488324C0ACE44BB04EF246B02BED +49DFA83A9C5219E88FF327CC0599177FCB71819B2EF4758D1D95911FEA16A6C50ED66FC4 +6B478A4DA493651F59A1F637C656AA6F8B11102EE41C33730E4BF7F400E6947A4F1E153E +2460624E874EB6BA5FDE3C2026964483783E1767F6E8AA12F646F3C47410F0040DD1207C +56F29EE16D2DD32C0FD73894A44E87E656D3582E3D615C6053E1B7B70E64279D617A958C +265B6BD1DE5F706ADF911D83972D46F929331C5BDAB2DCC47D10BA4D62D5B246F99A19F1 +E884117F99304249E8A87C6E6FA5083DC0F9E97626DA3E16AE4ED909D1B7E3A911B99E7D +9808528039AB0641948F10D793A2AEBC4686BD895773F143559DCFDCD6C09D4C1630E454 +0F112093F70B4C76C5D97D28E6FC8DFE2B2322E000404218CE03458E9196B95E63CD625E +61C03D7A4271A6A4AD5CB055F113D7F10C69E4F282B9D6EC5A60A901ED1EE9BAB97FD40D +33184163AA17A3F8EE9CADB38F047772FC8D39E3BFC7C9F5D0A3A277F7BB73C27516363C +BB23E8B0224234F7FC63206B19687CE91EE596D7F8921A5C7FB1CB746511BC9AEF5B6B74 +45CE95D7B58443C4FB4DCAB1F6819B94336058A708F936D38860AED70500373A4CC6A1CE +10F2BEF120E18CB10EF236457BD1529A5C6C2DBCBFB85F70F7DBDFCF25B9485E92C02108 +88CD2DD84215188B778BF35BF1381779ECC36974BCCBBC37D7999EDB9EC98C92D7C8BB3F +798BBEBDD852E320E3540C46C0371AF1CCC1F59D9C78A92F710C28A2B9707C8567A9AAE1 +1642EB8BFF1E9CE99B30A784DEAF11210C44EA275F137EBE69C197039E9D35A8E76C799A +E73B0D65EE4D1FD59E0E8B32030B6B4CE02E698F7090205E7B466C985ADEADB18CBCE64E +5074D90C4764823413CDA39DC16CE421D60F485FACA831FDC4EF6204894EB5B108734F3B +48E6AF64C0BF82E71AEC055DBD588D62AB4585555FCCF3982204397FB4BB4602B313EDB0 +B746734B8E6AF4FB59CA0457D45F6CA15966C3ADB050F7B83D75D43B2D54E8CF9604494B +7C712E0263E7154B31C205F51F1EFAE4FFBFCD5F522FD9E85AD6C6DEC091D7CD445F56F4 +A6D087280B252E7901A34EB4BA00206E4EDFD63FBDA45A17DFB1873BF8B6E82B4FCF7AB3 +CC1099EDE08FAE748854C9E468C9C8B8FFF239E366B4E8FC76048B0638F7FBB9DB80E711 +91F51D4CA50ABB65E361BE32D12605B10C8ACDCF2101D66928C9D95099C296B33651B44A +BF0EC9C0B7A6B686AC630264897CD3274A1E87AA8FD7182A124ACCE7CAFE4887E06A7B34 +FC7DF7973AEE69B8381047E2D254375C46BEBA1730FCC6FE4D6564DA9EA963D0B7D45475 +FBBB54BB12F389AE979D1F36E4FAE0EC7A1B2B7B86ECA42C85268E0953A461C8EE02C407 +FC387141C52866DB49D8BFCC065FD264E5F57423E3DBDF1270D2BB7DA6A860D22722E052 +3489A3A0B5F0E7E46DCBABBD89D3E4112A031B37576D35B95452B25B5CD04E18EF24FB0B +98A00B549599F3E924EBFC4FAEFCE504A1877F69375FFE7E9E7D2EE82CB2C80A87630A98 +88F13C26E568F5AF98F6D30A7C3E20695AFA9B2809FD646A8334AAC86B1020FE968085A5 +70ABD597C472F693F3EDCD5E88767D23293C1F64BA94029DA5921C251FBECA22F1BA47DA +142810A60CC9090E7996F3B09423D4D850C83F47B497E4C17718020B0DB9915933FD016A +D32B50CD62E6E20BC09646093ED3BA9F9D0AB09F5B6B01F69CC8F706B3CC3828B7794A67 +3F2C3CAD3A2EF13171C65111A9D34F0FBEA00FCD22C509FDD913C7DC144618BD743B3639 +1E4694442AA86AECC639CB1A857DEBB2D5DBBAC329C4E1AE4F095EBD6259D0EDC896A818 +829311503650962679D627D060C51C4A78E80BF764C7DF2121896E0B02E74B9E65CA2CD5 +5A6ABA7884C961B474FD4AB32172A6E070B29FBFBB424417D6D1F89F6A8BFCC880C82C9B +7C4F23739259076A57B3BEA79878839E3C0DA5FBC47A52B81724DBD303C58B027F1F1D43 +2DFE420EA7C773BC0884909AD03F7793F40878A46813EA207D855FD8D397DAE056F89394 +602DCB1174532DEDAA96C5907FB020BDB735AFEF6896EB193CB16A56A3274398A20A503D +B1B66729D094A21DD45E12511715FC962E0F3238630954BA513374FBCE28737B80CEF5B9 +802097BA8D3BF8BF5315838C014B08D9BBF849EB92459D04D0B735E487858E333E140CDF +71A6B463EBEFF3A86A5E1AB29902A14DB4C72DD9FDECB05F2EECDCC4314A600D6724FE39 +7478CFCC6478622A8441B88BBFF9AACE6FE02E7B96B09BAC4B90A65F04AA6126304339D7 +E450C24922FF6F3027FB0F6AE9C19BF3C633708255E1E9F06B8245485273A72DB47FF9F5 +E5AB05B1D8518691885AFB8DD3350D9305C4DB91FB120F666DEAC0AE0C64EB19106F386E +E8A848CBCC9091EC8FA9004353981D5C214D920A07B439E78EF98628E1C0CF014D54F271 +349676D7BB0E41418A67DB24F36B3D8953A73D18E95DA0645666B485DA0061B2D49480BD +C081AE8CE6C696BB8A7224E933FAECAEA2C09551F961556F7D1314A869D1E698DC887BFD +F0E57FE8459FB5B1EABC88F50FB6B3BE5B6DEED96854201D97A6A199F4C5E0929762832B +E47A897217131F32718E2FE87A2A5CAF8594242C504CF3C86C73B68C09B05DC02F428941 +F441110CEC6283 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +{restore}if diff --git a/fonts/Monospace-BoldOblique b/fonts/Monospace-BoldOblique new file mode 100644 index 0000000000..880b52fb09 --- /dev/null +++ b/fonts/Monospace-BoldOblique @@ -0,0 +1,2445 @@ +%!PS-AdobeFont-1.0: Monospace-BoldOblique 1.15 +%%DocumentSuppliedResources: font Monospace-BoldOblique +%%Title: Monospace-BoldOblique +%Version: 1.15 +%%CreationDate: Thu Oct 27 10:50:21 2005 +%%Creator: mike +%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +%Copyright: DejaVu changes are in public domain + +% Generated by FontForge 20051018 (http://fontforge.sf.net/) +%%EndComments + +FontDirectory/Monospace-BoldOblique known{/Monospace-BoldOblique findfont dup/UniqueID known{dup +/UniqueID get 4092906 eq exch/FontType get 1 eq and}{pop false}ifelse +{save true}{false}ifelse}{false}ifelse +11 dict begin +/FontType 1 def +/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def +/FontName /Monospace-BoldOblique def +/FontBBox {-173 -1034 1654 2157 }readonly def +/UniqueID 4092906 def +/PaintType 0 def +/FontInfo 11 dict dup begin + /version (1.15) readonly def + /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def +% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +% DejaVu changes are in public domain + /FullName (Monospace Bold Oblique) readonly def + /FamilyName (Monospace) readonly def + /Weight (Bold) readonly def + /FSType 0 def + /ItalicAngle -11 def + /isFixedPitch true def + /UnderlinePosition -221 def + /UnderlineThickness 246 def + /ascent 1556 def +end readonly def +/Encoding 256 array + 0 1 255 { 1 index exch /.notdef put} for +dup 32/space put +dup 33/exclam put +dup 34/quotedbl put +dup 35/numbersign put +dup 36/dollar put +dup 37/percent put +dup 38/ampersand put +dup 39/quotesingle put +dup 40/parenleft put +dup 41/parenright put +dup 42/asterisk put +dup 43/plus put +dup 44/comma put +dup 45/hyphen 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/at put +dup 65/A put +dup 66/B put +dup 67/C put +dup 68/D put +dup 69/E put +dup 70/F put +dup 71/G put +dup 72/H put +dup 73/I put +dup 74/J put +dup 75/K put +dup 76/L put +dup 77/M put +dup 78/N put +dup 79/O put +dup 80/P put +dup 81/Q put +dup 82/R put +dup 83/S put +dup 84/T put +dup 85/U put +dup 86/V put +dup 87/W put +dup 88/X put +dup 89/Y put +dup 90/Z put +dup 91/bracketleft put +dup 92/backslash put +dup 93/bracketright put +dup 94/asciicircum put +dup 95/underscore put +dup 96/grave put +dup 97/a put +dup 98/b put +dup 99/c put +dup 100/d put +dup 101/e put +dup 102/f put +dup 103/g put +dup 104/h put +dup 105/i put +dup 106/j put +dup 107/k put +dup 108/l put +dup 109/m put +dup 110/n put +dup 111/o put +dup 112/p put +dup 113/q put +dup 114/r put +dup 115/s put +dup 116/t put +dup 117/u put +dup 118/v put +dup 119/w put +dup 120/x put +dup 121/y put +dup 122/z put +dup 123/braceleft put +dup 124/bar put +dup 125/braceright put +dup 126/asciitilde put +dup 160/nonbreakingspace put +dup 161/exclamdown put +dup 162/cent put +dup 163/sterling put +dup 164/currency put +dup 165/yen put +dup 166/brokenbar put +dup 167/section put +dup 168/dieresis put +dup 169/copyright put +dup 170/ordfeminine put +dup 171/guillemotleft put +dup 172/logicalnot put +dup 173/sfthyphen put +dup 174/registered put +dup 175/macron put +dup 176/degree put +dup 177/plusminus put +dup 178/twosuperior put +dup 179/threesuperior put +dup 180/acute put +dup 181/mu put +dup 182/paragraph put +dup 183/periodcentered put +dup 184/cedilla put +dup 185/onesuperior put +dup 186/ordmasculine put +dup 187/guillemotright put +dup 188/onequarter put +dup 189/onehalf put +dup 190/threequarters put +dup 191/questiondown put +dup 192/Agrave put +dup 193/Aacute put +dup 194/Acircumflex put +dup 195/Atilde put +dup 196/Adieresis put +dup 197/Aring put +dup 198/AE put +dup 199/Ccedilla put +dup 200/Egrave put +dup 201/Eacute put +dup 202/Ecircumflex put +dup 203/Edieresis put +dup 204/Igrave put +dup 205/Iacute put +dup 206/Icircumflex put +dup 207/Idieresis put +dup 208/Eth put +dup 209/Ntilde put +dup 210/Ograve put +dup 211/Oacute put +dup 212/Ocircumflex put +dup 213/Otilde put +dup 214/Odieresis put +dup 215/multiply put +dup 216/Oslash put +dup 217/Ugrave put +dup 218/Uacute put +dup 219/Ucircumflex put +dup 220/Udieresis put +dup 221/Yacute put +dup 222/Thorn put +dup 223/germandbls put +dup 224/agrave put +dup 225/aacute put +dup 226/acircumflex put +dup 227/atilde put +dup 228/adieresis put +dup 229/aring put +dup 230/ae put +dup 231/ccedilla put +dup 232/egrave put +dup 233/eacute put +dup 234/ecircumflex put +dup 235/edieresis put +dup 236/igrave put +dup 237/iacute put +dup 238/icircumflex put +dup 239/idieresis put +dup 240/eth put +dup 241/ntilde put +dup 242/ograve put +dup 243/oacute put +dup 244/ocircumflex put +dup 245/otilde put +dup 246/odieresis put +dup 247/divide put +dup 248/oslash put +dup 249/ugrave put +dup 250/uacute put +dup 251/ucircumflex put +dup 252/udieresis put +dup 253/yacute put +dup 254/thorn put +dup 255/ydieresis put +readonly def +currentdict end +currentfile eexec +1CED864D422F76FD8FAEF6132F502482A3D8B4A45438351BEF76DE83DDF4E51528714B6A +2E0891A07E6A4C4AF06631204074926585455A5677B5DB36647E8D4B74F135293000FE37 +CEAC7E5D7112AD08238B10F0A7E8C6B22250EC0C3AE0CEC1B5D58D6CE79A5C9E8AA78533 +80CBA7928F215BFBAB9974AFFD4EAE72E2F13FA51DBB826B3345FF4EFECC42059C923D3D +744770EB5214390157686984CE97B7A323A282FB3942AC23170668648757127D1F629DE9 +F47CC4D8B96EB65B46A5F601947908C6623ED3C619000369C9E67729C539451F62FC5580 +9EE2C0DEDB3928CC0FDD6D955E88BDD03D1ACF344F28493FCB53D4FC1B863FA25220FE1A +1481C7750500555A9BD2D8D14147C9F8D44BF71EF40F09B0A188725D6B400C688671D7B5 +547DF767FF1075536B17074CB44E973ABC27A9494A2D5880537C8D53A2C7262E53EB25FF +C4C00E380FF2F8B0A0D33A03BD016174D197257B13A27D23E9EFE76CC0F6D8975A0015DA +DA093AA1B08F2BD290040DBD6674FF79F4718DA59796045B4D8091C39F6B407D5F2715C4 +E5CCF1F7A8909DC995C81CB305B02836E96488ABED0835D20FBD3507AEA8C9B51EB85BC7 +148CB611417A4A894FEB958C0CFC59F6359567D6A13A0D01A7AC80E9918450DE949D19BE +31C7FFE9CCB6A9980AC3CFE03409367CCF926A75F8CAF8C2BCE07AE51FA505E0EAEDB20C +4B530DFF7DABB79822CCAB90A5366E32840749B94EF996104D44B3E13E3EDA856C4CFD10 +3CE65A33CE8A22AFF27E081A93AEC929F7766C0F1F8C8A5414D3BB4C46F8E791D02C1710 +95FFE94019D62F166E3EDBD88B350E8211CFC504E546F14016DA01DFF478C25015A6530B +8D38CA3F7AF4DB3B8959EACC030207E8239C17E351E737F58960875256AE6BF5094C042B +F753341EDA79F533F602F673B803394FA140B5F9E0768413A9EA96961CA0002036751C33 +FEFB66DC4FF30585349AF7C9924B9C94E20DD44381028847816BE17FA4D554B30A78AF24 +11318819B1553C659F9866EAE2C775A9E06BB5E90AF8B32B1A7BB290EFFA41F5B5033C85 +401D3B85F125D61EE0B245E0FF52B1F46CA409A86A88A8E40CF38BB9940168BF936734B1 +F45EF8AFE5BDA9F613972D9F61EF5FE3F8D4D19690C2AFC60C3FC4681906BD2570945EC1 +8B6161A8A960546C23964E2B005EB85B4146C5EA93313E99557B8820C6690E945AE88661 +AAB10C0D47BD67CC00C03BA82A04407CD9B692351FBA25E75E4486A21D9A0542762D5A64 +F8B1B879A11EBFBCE426F221372C7DA133D7CC2B2C0F9E6F269B3DDD14A4167F184F76BB +F0A6AE68F88340051B93CCAC09BBCE3A674F684ADC4F2F5D121A3CDA013FD031637EADC3 +36D6EFF295A86B54867FCFE1F05BF5A73C737040BD3B1A0E924193B83B6BB378B2453D9A +A3D53B864E1EFA1822D4D2EAE2B310A42389ABF90F4D439E0DC7CF34E8B90439EE25C677 +00F9DD5CBFC6DD5681E3C79F26089F6D569E0F07CDBA2881D812766439FFC0894C0E191E +054AFA67FC1B1AAC7ACDC5B6D710F1D0D7D6EA32937FBD67CA71A1D5C5EF59A3C0D833C4 +5F78B126A88A81E73971B7E12AF16C4B23086F282FB309755696851DB9685FA9564AD878 +BB22CCFFF759CA65A594FFC2FAD61F774BB8450A09B08631B1E808E267E855F003A5B951 +D8B4BB325401E199F57345709782E2959757EAB5BE7AD6B5BFF17014E3A1A8382819CE75 +EAC4C68377FC032EC0D74603F25A2B1386F7FEEE876467D0DDEE2B2B9D03E25F32137D1B +4A8F90BBA322636C8571B6E215111579F95C346171C8BFE6777B081660877518D1B44917 +ECAEE307B68D51DF094AAD59DDA212747661AB31A9F31392C4EEDE462668675988A83172 +AD88BAFEEBBE500AFB2A4D9CDC985494CDB271AA0741C0709A2A4991B5EEC213F3BCF107 +E6EC214DEE85916ADD3440AA2A7D24F0645E254639EFD1AA093BAE93015A7FCCADE66817 +F4AFF9E5A10DC390AC33D707D8A8401F93D0318626FB23F8E6226B5C5230FAA6323C32AD +9F73A91ACC682BEF7AB3A99347316812A926E30DA8AD7CA702E52C73CC37D8A2F8D3D679 +D2F4F17419B85D061833B63DDCA501DB6E5FE81B5F8E601C59057D912CF9163D1DDB4237 +6D4CFAEDCF4E4F66600F71D7C31061A9846A0F153536DAD78AFC80AC89DFBB1CECE4D89A +DCC95F5E7E03A41A6BBDEAFB3372ACF32ED1D5DA6CF8A768812D69620806585686FF6658 +81AD1D1AB17E7282E6150A3EB40B400ECD78E202FA63A5508EC4D6FD78EC3998991D3829 +B4CAF3B7714AADF0AA04D5239F5BB40A7678938E493E6E58BA9AADAC797A8A7AFAF594E5 +82CE777C987C6E9B4EE421FD1E44B7C3DB349621789B8142C2773C049CD999E3BD26B634 +BC86CDCC6F930EAC04C71A25E8A2D1DE3539C8981723ABBFAF835B9615FA36A3D89E1502 +F46C09FE21AD93811C447461729A4283E1C865419A5437973C07F830FB3645906DE1EF79 +5A4D0DA6079B77C3D0CC1D1581EB24BD9644CBE0FF57D58295D3C1529F95B61F21B4480C +9B1FDD14B20A776EE20F18FDB5A595778724CD68D237057519E58622DB09E9F86D8FDC28 +1F5FC5BDA84BBB46836244A7510737F6FC411F39FC9A6EB3FCB5D9541C7B3410F60AA52E +FF65CD9C4D20B21CC0E16A7DF3800DABF3475105AFAF14D2CBFE8C4A0CB98910441699B4 +B7419F0F91E4E7E68F6AE3640B4E82A52856FEC5D51863D14CC9A7E54DFC3F18EA6FE05B +DDA764A8FFB62408BA412567BCD78692A562E309C2DBCD900AC231610AB97A7701B98440 +5EAB031BD3922A9B29AA0A38BA410AC99CCA246E324FA59BF265924EB41343043C2D8CCB +FFE1F6EE81437B8C256179A5A69D7C0BAE4F13C59D7356B0FC9878D14CC9F1882E68EFB5 +0B324F590A76A19F01520AFE617A6ED645A9BBB0D4AEF69A01099C2F7F93382700E3C7C1 +2862E5289B66EAAB1DBE13802C29D11452A82968592995686EB09AC67B64CAC41E9177B1 +1A21741097ED55CB5F383DCE927C5EE5FCC13B261589586DCB03ACF7E74C67606A71E235 +A335469B97FDB6DA8613437685ECE63BED792266DB50ECAFBF082DEFE04803CCCAC08B1F +47D3EEE82D635A9F97975EFD80A316371ADF86031250077B1CC0F403845FAA306ECCAC14 +A194E85663252D9FAEA449B2A2AC2C76EF828F9EEA8556CA4057EE0BEF356C1DCC76308F +05CD254A737EAFDF2912E74C38C3617EDAE3969A03B01AB3254C909B93979E6226E20D48 +69B44FE0F9D8002A02ED206544DD099567DDA0489BD957DC14818C7CC1264D405BCC9E9D +A31BA99C5A695E106794694B7FF847497FC8A7E961C57CE3959D71253007B8C2A6733FCC +B6E43863F782DC8D37C60A226D46AFB6176C9507C7837C1DD2E23559FA1377794CC32079 +90FD6E0EAB77096F8C4896081B5203495207EE8CFCE63AF48840778C1DE08A449953DF83 +D5EC0B82593EF1D059D2C5B9350F21AE58BAB03F57A4CCDD4D4CD8CAF475E0315CA8612A +C3E66CC597DFD5F4F53BC6788B84C1E2E8A8AD02FEE9D9D5F7471508D7E3F447F55EB1D9 +D54EE8207131F8FB5B2A394C0C08F35E8F93AC9E0D0F93A77C28F9FDE8990CAB8E3908FF +EB8DC0EFCC98F88315E0DA33B6C6B4B50B17661DE788C1A874BCD2407C3047DC79DD6650 +B6908207965CB5BF7E7B83A7030D30D3799F406C9875E3CFA9A42401CA2C7115B1446472 +4D38382EAD16C042B8F2B352F6A9FC7FBC2E488BE6A2D97FBC1E643FE4CDA2097253798A +D26DDBD706E4CBC5661BD87E5E488960F643A960E9DE3891163276B377FF96D9D2E93B81 +17DEC91E5D3BA80B14A699C56E8F48DA2EE0A8DFC2C981B106C70E0766CC379D97653EE5 +465EED2B6FEE0C1CD2F4776D30E08EEAFCC427D6420F516F9F0CB3C060659C4CADAAAD94 +40B3FF65406F49F4174C2B0C606A3B03A8BE0F7767139539BDC38B93965ED44BE4E2A53A +149EE0D512D37958A9BC369452B6A121DFA0BAAEC6E9F6E00533AD6EF857E662C7FF4AF4 +5B7732E3C5A037E3A752682EBA6976330FF3FC1CC6271EB7B2024D2B00386A8A5737F052 +F98A223E309E457645E4D1C91B59E827C451D0CF32DC3B3D725BF5E325F9D2CC1994C319 +2B4C1D05BDCB87122F41D6F72A762FA45509074D76A32974ED953C5257F9EA335152E96C +1EAD2DFC8B7A85B5DDA1975EA400EF5DEA8F43C82EF663D3E5E122D4EB1C67E7E16CEA46 +F12D63DFECB85A84C7B77637FD330F89503DB4B342124ADE972AA14D81F492A5695225D4 +39A6EDB80209D1A49A7B393D00C1B5429DEE9D81EE2E7570A5E244E6457612C61E3869BD +772FB5CCCE59811D7CF516105765ACE6B68061B1B411FE664C84A767F66238231C96159A +21C3CBFEDF73F3B56A25264CD5FCFE91C36977A683B369716D6525FDC97E5D2828F26961 +292D8D5F7279E6C0C87F89827B1ED97187E3EB9E3ED021F23DF98790F5095C6063E144B5 +34FB190D15B1DED675CF8CF5C8FDA3434844ED1BB8E1D93F43D5829E6603AB001D423EA8 +279972CCF3AFB4BF776483A41C607AF581B1031E6DA4D716B7876D7785FA7DA4C74DE445 +33EE4B832B5B27154617AE7C5E32F4CDBEFA77290FE45D80011C0E7BF5BDE91A63708F0A +FAC6D6AFF5FE1EEB23C187EF486BE3E8EB042616A4763634BE5B4CF31417D6B7A807A3F3 +C3A6F6C285A7C7BD46AB63CA1F9BBE01A4E8E98E4CB44D2F26CCB99A85402F0A474E531D +9675475FA6F06A7347FD8FA30BFA67ADACCECA881CF703E2E15D8585A9EFE607E311922B +D9F0F8B7715021C9A90986D4C0E681F024CD13CD38A34DC8415FB96E6DEBA849D1CFD157 +181439E3C004ACF2D5E7C40F2366A89977662CC8D0C0CE03E77F77696871B7BCF85DEF44 +9F1DFD9A9B4F68B870A1ACEAB20CD407A27C5B75533A08CDDF6D0C97650EC5FD4AC0208E +07C59FA798DFD38FB86AF3E71503F76634DFB15F6323927C87AFDFA9178D71391DC51E76 +75BC787B749BB53926B0BA5FDCFFB241AE27B036C586CCCCFA0896D78A63578A986E329B +DA9F0E5EB0C5C1DEF06FD3667910600941AA707EF6EA9ACCF721C8DCF7760BFA32E3D5CB +86E79CF66DE28D80CFF83950238BA7EAF551FC3A8E4EE0302C840E7FA11D2F1BBBEA8EEE +94C313EB4B47975CFDB214B3134711BCD1F2E3ABDF11E591E9EABFF57C226CA83B3DBAE9 +DD3FC6F2C3C4777E9B5479A7E904D0E1F7D36CDFF6B32323E4218F8CFD5EF467865B2636 +81FFD990E58EA69595D4D86F2122C52BBFB43650FA8145B1B6AF095541123E31E99B3981 +A701C47091FA0C752499D2754E3D6A2E3322730CFA4EABB60807FC81AB82D6A4C81949EE +75B45A30EFAD61F1984993AB44AE604BB045120D01CCC85B0EB54302E05AF8B5FAAEF675 +62057457ED730857620073F014DB40BDA7E41941A3FCB28A9EB2DA319C3193A90030F0CC +0DE63B94B68E7548B709AE50267036A770646EF39C64B31DB865D12A60E502DB4EB11C5F +F784708E3F670FEBB1888296C3753D690EB6D9ED17216471CD3C4D5FB8F3F6DA866E326C +58E8E892A3E6BF60ACD586D6CC8A0C984EB030E4C5E1883B78C4A04ABACD295FA292830F +2884504E35363BF69D7B2F16E43F5B94CF2CA934185C684B1F87108B58C0FA15F75F48AA +A03892283FD1FAB239D5A09BFA310E59F2244FEF8481E1494A263EC2E3D4CC5ABAE4E37B +D73F74559FF9B32EC960E5689C3E86033F1D20210FC448143FEF0C77809CF789F6B8A55C +F383BE3D85B82DEDFE4DC4480C508325A5D28216C097BEF9893103004E551D0516E05B33 +1408028C881732A82151E3572C279972EE0DA66503B2A7A7E450F1A4866B9FD0215B7BA4 +84C0E5B95276E6FCC43896D4222EC7ED7CA5A4D873D0E80523DA60CFED59C07C7704072B +8D988611AB4CE42D6F85CF336CD7FBDB4FD1B13BEF8D97BE6355EFBFC2F53E7D59E257B0 +F71B620746A03C7D7C5B2CCE57177F16490074171B8DC509297CD5E43B498F86C2BCB119 +8C408DC0DDC294DD2253FFC5B03DA71DBF93E8BF8E2AB316D852369AF766C92CB2C82CFF +4F9247BF252C7712AE3978F76F78AD8C9002426B3736257E92CED2337961A693797AD3A7 +3138CA2489CC0E2AF826E4DDEBBB1C1C2F07C6B98C721A0519A2CA6DBF7AA6CC5C1184AA +E5A05AD35274696A805327F95544D71747E356D5C1B83431FD8CE05F0378CA6BAA36E7F6 +8CCDA7246655D8866D21E21E63B23440457B8863118B7080AA83318B32D45756D17AAF29 +20A7DCA29679F76FEF9C33D543E54460506CF9254E16656E033D7558A09FE3BDAB6A283F +0A881A67E3FF025A92F37748527EC24A7337AAA5B6254A5F95FEE2380125D05A25A9BA64 +4E60FBC4C25C2AAC69CDAC16ED0D79188DEFF61692D56DD91481D11F6B6AF7C86CE24BA3 +761E2380974ED69FEBECB22EED4C4E244C635C52E0B162A79C948592CC6BFDDBCA26C8AD +D9A35E6EDC3D659EAFDE4C4F430133C337461E97D2460BB6C8C2550A500433C5F96EC312 +3044426764FD9EA134359F414F59105A3705DB72BB3199B0CF9240979119D7E0FC27BC13 +849501B45F654ED63F93B6D74590BDA5A019A93A397A59E9B8A41E5F61219F5884390F12 +321281D125799406F9E234F1133BEECAF2EA304AB4C313C902214FB7D7993723772C39CB +0127B4E82830DE0B9A7D60FB452F70F90ED4CD2D2628A132816ADED99B9F355D20313F71 +1B0586F2A20C90705BBE628F2C9720534FE780FF3EC15DE762EDFC86ECE91A1A9E530C54 +56A887921523806EFAB6E9E397838087921945D0EFDAD8EAD7D27E3C24B4BCEF2C8B92C9 +06A725065BB42F0DE1653DF32C802EE2EC33EBE5FFB0470AE8AEAEF3119ECA6FA4728AF2 +CEED07C5F5024A27EB62475A8254E8DD444685EBC545BCEFF63FBC285208350AF5065CDB +466FBAB8540D8679430793A202CDB44EEA4082A36797F4308F037F64739247389189E303 +F31A1AF0C1780FD9AADC74528533AC6EEACE64E043E09EC5BE365D706FBCB09338597286 +30962CBE409AEBA4142B80C11603B4276DF35E15E62CD9478711D2CC8454561B687C2463 +9F68BBE2659168C72BF87743E758D33649ABDF6A7A4F42F625B2F83A4F141CFFF14A661C +9DA1E1D045F6891F82EF2E548E11497164235049BD3E3CE707E99874DFCF2E912DC431F3 +7F9894E3C7BA894BF1677FA0F392BA9FB652BC93D898501C5E6B4E20FA8AC7CE6FDC9AC1 +D86723440BF06D420E78F5B32BEE9BE5DCAE455DF6EF63128622CD90C39B46CB9EE4F45D +72A5EB1512EDCB4DB7220E561160941421D6860979A039B9E5D5706126A3D65BB8F46740 +2332E34E1709298538D20F5BFD178A2AF0391E93672D1BDACAA87CAD9C13873C98B3BFE1 +D28D783690420FC7A88F50241EDF64BCAC2B64E2B0BEF2B5C646318674EAEB1A15D431D2 +1678A73D2165F9A356E648D47FB6B7B5A889391E194BF80550962C1E996DDE28AEBB2529 +6508102B534332948DE46D92DEA56C8D19A08FAD37A646BE88C0B6178F72FFA422F33D81 +D5C4F69504B96A0CC6FF3F4525E0F78BF4F1B27D7970FF1B2F9703952C823C0E99BBA0E6 +63E413EDA3C4ED453176723D3B91683DA70365774570A5E36C40CEFAF29BB91948820395 +B60D780E7EFF9BF0C7496905628CD5084A34D852EC665C81497DDAE2D38594C8556937E3 +FC505A281C3B582A9288EBC36E39B8A1148AE6B29B265016DBBEE8DDA7B0E9C7EFF37B87 +2E95507CCD7FEF306906F05B7FF2387A2AD253178616AFC3BE56667A9B1875C81D960245 +54B5B785D210EB8285BCA0D3462CB40CC8A7310567AB5C1ACFCF279EDC74DFC8863A0441 +897C6FC2C12B875832FC9CEAEF57543C65AE75987834B1C2ED9FCB266A9B8703C2F53E69 +3375F4BAC0C609D464FC164426B01930746D0C66516E02FA50A95B742A7117DD03D67414 +D40A0E37D0C9340181B3D689A09898DA6B4EBF8B9D022DEF18DCBB58D2AAE351488A28DF +8C01110345C31A7CCF136CAC367B7609DDF27B64326B1A93D69677314EB62E1603C7E522 +420000203B5A9014148875FFB716CDA3B0EE8558AB8A864DF11BD863A640FFE835E0D469 +F1587F32E5F329C2BAD5B2604B58204B7667397F349D4A5EC7D40F53AC32B5D493F8128C +295165B31A382D32383E1B45C12992EA246D677319AF5C09E2F540411404949A9825F62B +5A306FDE4A93720B5067B3433353F3473E078A92F433D8A3E7CDB486131A4EFBA06065A2 +97C4706E1C0049557496AAB1BEA12A9B7BC411608EF41ED6F3EF7288494B9B5B9728066A +F99B7AFDCF6C245C06FAB5FC1175D9816EB90FF3116A4040CD614F18ED3339C5828BC121 +550D55A8595E4E679F37A744926179453C7E27190D64F3284656CE7C0D334A7420275903 +F9C0889248ACDA0D646C1885FE98F4E2E9DA8353852DCDDC9A36DD4359723FBDD1FC3334 +E4F49C07F30DED223A031BB54AC966DA65C9979D32FA1F3E9B2F46EE773891A4CD8A9BD4 +EF1AF2763F1BB5A3F9067317D9B5BAB7C622F974A3DA0934EBA78E353E220C29FECF3541 +528AC86A4EE2F73AC9D38FEE530D517C00CF43377D607942F881613C9BE20B59D48AE852 +31E81B23EC531003D7505E6584FF64CE940DBF2DB3742B142A20B1C8B6AA07D9538D4E16 +B70AD1D7C07EE5BA566876C92F548A643A158096AE000A8C6E1948D46AF2FE91AA3587D9 +F39E0315C506F739461E8B73ADFD18B15285A15A6161491B7CD85F80C1C7240E35BA7FFA +40876F878B468DF1B50EC980FBC4C8C62BB16DC81A38A21ED69CD2AEA4A56B093BA9FC57 +1EEF14D429176852D4CB3762BA789C741EFC39C26606E93BD525C2850E99822BE0DA5CA8 +CB749B6A650ABE24C3667428E8DB1C790ACF96E0D4B48441B019D29D85AAD46F3FC6BB14 +8DC9DFFA73A5C6B041C48A60616850C31D1F648757E4ADD8AC4B6EACAA801A88D3043842 +6352AC493AD6D01C83BAA2B645217F62E167B30964B8493EBE3D5370EDECA3F75193416A +C763EC9318BB4A8651D858AFD090692FE0F3114698F8F7E729C5F0C20BE9EEF9E12AFA46 +8B77608629D6E5D5269898206BD5BB4D6BB72D97A959E793984D26012E4C5BF4B3D70C7F +43AB875FBC17E8CD19E0E56EE012782E73DC04B62B806142265938B4FB9B366B109921E5 +353E29F046F530734E2E312E953708B41884E50A0B4A7D2BA9A8132BE0FCF7FF5E37F0AE +7FB48513B73D346FCD60996A2ABC8659A8E93CF9A0E1135BBC4A438E71813F2C217744EA +4D42E3DB03AE3038CD53F8FEDDCDEDBAE5C69D7EBF6DD4A41A1510A12358D5DA5F98AC07 +DFB9C648B5A72AC100480E34D38B897E9390E223C1E057FC09AA828D2524CFEB0B36E2F4 +794FF8D66E9734AF0559123BB70725C1B466E5230C8BEDB01B073C10F4011D7C0F6F2814 +60A76371335A96AD7469C7C7012A3AF9E1BF900B64384B1FB1804CEA27DC37DCBB64B8EF +98BC8179AF176295DAE271D686E87D3B9DC68C138FB4F7E2FDD5962B35DC6FD46DD24242 +CC30107200FE6F7730D33F274B6E532FE791EBA9AA79E4049D3E406C74CE152AE8FD1BAA +96920AB1EB2CCEF4D3E3F58DD499C8458CAEC9FE7F1E91DFB25BEFB7EC37E53EA6A524F0 +6D22F8403643F13063D750BFE2CC05C32380A92172F9071F5B526764B3B98EA9246387A6 +09DB489CCAC4B35B07FCF17955B42ACEE5656DD90B6746EB8D11A8C43AAD98AE1EFF5751 +F313B455A66D646D83D4055FEF177C96DDB064BB5E6F880935CF01D146A8C792757F0CCC +25F3FF24869BA74D81DD1572901F099C6FEEC45992B8DBB77043A0527F628ABEE2DAEE4B +EAE37E89071761307BFE39AFF657DAC83DBAD2C5F602917213DB0C5D4A9604F37DF37C3C +49FF2FF5CB143505FCCB025002F292789FA6690B573DF46E2DD0DCCAF4F5E4369075E359 +5B999C19872053E9930701583E88627BCA93A11BF22CC6F45F440CE2FD768CD93B64ECD5 +4916B0764C459A2689A72E147AE9E66995BF88E4EB0DE2B9067D0FBAAA1658620F4B8F3C +5B469F5543F02D4DCFFBA5071BBA25C7D025C1635C5F5E2F72A850C3E5F63978689C3D55 +4F139D38F8F28E79D6C96AD77F03BB29A928F5C81FCAB3406BB16B427E26DD0394634FB1 +1134F07F316FAAEC79F04BAA0F2CC7D8BE3E76805500A40DB647A3AB774DD011C6D2D65F +03B4F2A45079ECE8831C28A4EB68F462561CF76650BD8000FB8971FF4ABD066FFA0C1E74 +6D21E35ACDE42E376A6C6488602674C537CDCF5F163101D4AEE68F0688E16337454C4CC6 +07D2BF89342B8F38438B6E4F142BC7496E17F12F7D241FE0653E8F1AA12BF5E2F91F6886 +20870CC5794A56888CC248E076DBC743CAB5B43D784D9C576755750C79F3116BAF053ED6 +659D9F02375AF7D017CE1DD368481271F3959A5F84F49B1D0C796F547A5DF8551908E48B +65E05E8DA081C69CFC95FD9889148A5594C1C839EC62D9D12A20B39D4163C193843F829E +6FA88926D80FBA23988EE8A69544A3B6D72D7B87716A963B4A9498E11893F19395D7DC37 +83FBE1AEDCB3ED86AFF660A4D3E25FA7F21848C1A8815334D443269EB21DBD8794A744B9 +7C9BA089AE6D1F3AC68615EC11DC1A6FDE19B1D732BE963890C6DE995CB4184614B3741B +A64842BA7486D4774D90FF43CAD4A6D8AB1BA46E0EB7A8812BB1D973F13DB24A043124FE +60C9C97151A8B582BDA433FFA3B9F734EEA35F1B86674150A50F75543D3BA208743F0978 +C6532B70CF70FD58BAE0B3EF4157279C6E9CA885CD1CEB3694A286993A238AFD737D34E0 +585C5396C21991883B928672AF8E7060F41EB9D955C2F3BBF7378E52964BB318920778EF +A1EF42EA6D8C53508A79C1DE7D85E0C9A292B820EF3FCF714BB533423A60BA1D5A084A35 +CE918A6867A12FD0C3B3BFD50BB025AA2B304EA290544A2758FACF6BC401A0391B070F24 +C3777E8D5DD438F24CCC919DA93C2D548A2279FAD56A845F4CE6A9912A77B202DCC77F45 +4A3B3BA11741E32D2D1C4F824978A078FEE972A6646FCB3843C655DB8FC065D66434DF6E +F46BBA42413CA88FAA9F0B2FFD2D753D6B891D8A6B75AE8189123A0DB91B971C00300F5B +CFC2387EAF61C367C981BFF3F0BFB148227E9A7DE7299DE595B027970CCBB78B0C524CC1 +DA29C98A769081FF8B2EAD1D01A97FB975C084784F33109CE38732F4B7BC2E89E38F7C22 +7E295B9D644CCDF0C3F899203C33DEEA916EE508679BC12117140BF786E118733EF50B94 +E8547E486E9BEEA26D42565201E05B4F7354989423115D89BEB2F1596F2458D7F248483D +7E1B4E359D679B0F4E1B2C73EC3C37373AEDC75723340A07B4BB35C820D69B0550BFE3B4 +24B44BF1C627C21EA62F4D81E59AE4FF9EE17315064544BA9908A49492439F5F4CA58F3B +82923CD1045F2A43449ED3BC3FE872A89A470857B1B0FFEB942D08B41E80EA5CD66FACE9 +94559A4A143270F8CCC95D2880C2206E0BA08216A85966E084F061B13887EEE5D335DEF2 +B872D0816C8923B106A629E90ABBC2016A819DB95E63CD4C7B56FE64A917915FB3E9E16A +E1E74DC608F123DC565D6AA5839F8FCEDCA33258DD1F2471C787E8DEF9FB417D33225428 +874680419E9DBB9479530B26C4385F3FBA517222155729798049856C640C8745A7212A4B +E7473EEF586E548BDD5ABFB34EFABE513FF7EC3E28CBD7521C8AB00FC7162D85E7D9515D +E56C53B4BC1FF18CAD6DCDF28317F32F5DC5A2D9F3B15616165F15D7757A05C4A7187384 +1261A65046B57EEFDB367EE48468EB4BEBD7A67368DF534C217E3CFB16F15CA97B986922 +B078C7B76E634EAC55BC29D2376AE295D49C9916F562ADD7823E23EC90CBE7395919DBB4 +6B5E21E56F9A5B204BF0662F68C49E9303623D847763A1AC888D00D7ABCF34C3401D2EE1 +59005343EE15EFB9D5A5A1D330A8D5EB442A1BB47C523A18F4733B76373FA37AF4234363 +03EC4BED56C72AB6316966E2FCB2363FF2D4CA597E68BCC3FE3F139C272C7454B85E9FD9 +E23D8B6A38159E91B587C2B5F01D75817B75315B989E85D71E52CA4F13497F8A11C207D0 +89FD55A01D3251D7553AF6BD067A65158DAA766E24AF513B5711A0AB231087315A3D97C1 +2B5E790F4488FDA7EDCD02DBC2FCE692DB6D56F16BBA576687769642F0169DC57DFD04F2 +FF63861E7C03F841F84AD6C096A57520694E536A26A19D977AF1DA8793C7434764FC12B5 +16BBCB418F59C91ED4BE658224960F0DB0C95879A591F94DC288FD475A32079D31E6C41E +808FA8D9968817012620E7F30F14B2C1C0A5BE47E647832CF3334F68F4CA0CF338223262 +1A0478FA29D7D90CFCF76D83F39E44A4A878000A6A252BDECE5DA448EEEF21A63695323E +9C69DAD5E67438DE4F7B20B6B0A035751A39FFBD912F4EFA1713546D0156C53BD3F3BFB3 +AD47F99BA96E0234178A7E980830ABDC6E8C5CE38CF0CC56570447291D422D9ACA5CD12D +D4444402FE14825BA95670755422399CE362805AFD38C923358F5DB8BF1078C3FC6AB6CA +E3B057B7760CD16F2EFADE9EA0D40D6296E4BDEB33AD023109148BAEB6307D20AD3F8A77 +F5063C8319ECF4E56586C12982AB630890FFB2158AD97B5AFDEC586DE615E8304FCA1C52 +0369FEBC2C9EEE9068A6DEAC05706FE7E024E8254C4CE5C7404DE853DAEA209E7D067F88 +571FEF20076CF19D6CACD0D29B43E04E132D40C0FEC8FD4FA9A7621BD18215BE346A0F5F +C6DC05175753865A2D987B947FEDE67B23FE2D3635C357633D57C90C41923F889541D703 +9399785BAA6EF2ADBFA1940227CFEF4448BA652201223FAC24CF955B98087C4CA2664263 +BE8746DFC29FA5DEA877AF83897FE2B068B061B5C05871FA675C449654E6AEAD3A8F896A +A3588948271FB7F9CD953144CD070DEF9F6CF516C8AD51B47B87766087329889670AB278 +9CF4A2552225A1C997BEE8C3D9FE338609022837E306282A21867ADCD56FA9763D34A547 +8C7C7570B19D04D6164EADCE146E617C85A122E9265746EF9A929CD2A9E341095C7E646D +95D437FD5BE233E352B27BD9A19D0FAE0FF524257DCDA23C6D5AADF460EE7358D4490D7B +9DBD68A72EBDF1D266BC974D7F56D3C89850C024CEE759D09214108D6916D34B407E62AD +89B402AC74F74EF4C0E96569977627C9BB63B6C6F536D1A9CB279B636EDE90A804F32254 +DC167ACDEAF8778B164E36ED23DB890438AEB44487E3355E536835BE443021621DCA9E4C +8C39A54F4B7C28716329997C1B0BE5CB5FFFC7E99724D5D8C829783D156155639D79DBF1 +FDBF3082B62BCD5A3A04BDD2D94BAFB7BB997ED0A6524DBB227EFB29BD49A240CBF7644B +AFA665795211AA5735F435336C88EEE7972E94505873F66EA6657AE8A1480119EC9896EC +EB6C9250F5BE682193B4CF0C9CBAF146D2A61C895BE6518CDEEA1E460EA8119433685E51 +87CC18A77BAFB8C8C411EEE0CC655631E7ECFDCE6C59B397C9D568D0EAF9C6C540E508AD +3CEC230FFC326F1D9570218D51591C335D89BED38711EDDACE3FDB2F667B1107EB410283 +61F09D4082975C1EC481504D446B0284D017F96B94FA8875B08B11CE175C1CDE5D0CC9BC +93202FF57BACADCAE11ED701021E7720B88A78AFDDD6D71409E4DE4EB766970C87E3D900 +76EAD2457BD9D819B99CC7B0AE137CC3E018F0EC1450E91D2ED5BDB94D86BB77BA4F291D +8DC1443FDD001C7EB25B09208B92FA8EA31CD9D0A6DB0059C0B4643D898CD15CDDCB211B +885155CCF420E1C62B867A923C1071D1B4495FC4914D957D3208D4C0EE082C898D74A063 +2B60AB2D9657B9F510BBE6A2B9AC95D1192350183541E598FCD52B811F4543A1CF25A85C +12F9B4E51CDBB6067286D7B6919EE8BEE3B3B6C55BA28AF9E7604D13148000CC0C1F2619 +DA17AFD8CE1DFE099B7039FE71D8F6439F0E046C72F76E2CE69E7D787C9AD548563517CB +72B57FBE712261D00FEC755C108E9020548F4B49D805FF248370459EB32985DFF1BFAA2C +E0EE93D945744965FD6945525C176FD953B5394E521DA5CE283F147FE0A538C74F326BA6 +60D9721EC2A777B3F9047EEE5535159EDA109AB7CD240520DB61BD088FC45F4A0EB42614 +4AFFD87C7C1DF28DA381BA980D2B144708F7E471230DE98BB691D78F4D8A72B8CB519474 +9D392D4CCD79A03DDFB93F8A8163BD07FECD4851EAF615A49607385852857FCE90F3E499 +3056B7E80244FA21F488EFB3341095E684F428574DDAF149AA105863626B4952129CC819 +06D28957E534DDB5C030E718CE15C9561A04BF18A0F3785CA6ADBB5E2CA74C9166D95FC5 +8537624A9B0663B9D4684E64D1C17BA9DE128EBE66E057FD3CE3B5C7AD929640C7B26B71 +48E82F21A36B86664317A1412DA80BDF4C867852BE5E650B772F6DA9919F32B96860783A +AB469C9C88A0BA958D3986121F396C4D2183D104DB5D0382A846DF7D40E195182CD24C79 +01C1A9E556EB8CCDE58C61E44E7E80F37568AB5858AB86FBFD0711552F0CEBC1F4A4FB1A +0D55986B73B49D49911008851EFB478C9E93BE7A1AD4E10FE0222432F64329B0B1577D3C +E603C0B50AEF8FDB39804ECF0B566C2757DF12F65F3AEFEDCAD98A6B9DE485E0E96F3974 +FC7B196065C86992DE0BA6D4CF123A0CDCB94CEEFB8420916000F18B643DCD6A48FA32D9 +F5FA37D93CDFAA1BE4D95FB3D597CAF2EE196814A3B2E30A494C70EA193DF6647D96DF61 +BFCE1C5043899E5D33176B746ED3F555AA0AC6A6057C0D1B2D283C33142114CE60DE0811 +A8816D22DDE6BC1854B6C8930A5FA6496769388FCF338446838C3FD937C391CE06946181 +83051E106A440443F143CCD973B24B9E5D27E384853212CA4AE98C16B49A4A311A7759D3 +41B4497DCE2627B7D6E4FFF124EDC45B2573371C034707AAC8CD3A3F9547534422428B11 +6F840382D0D36802DB6386A9E73B4E3E4D3BBC0FD636A9F21967B1D550D727CB401598DE +144B1E04B617FBBDE509F475F0F2181C0F0C6C3F49228D0859269839C52FC2018CDEBA3B +51108199DDC78BD12E55B48B557E07797FC27BD87D41FE591E26F284B3E80C3B6B4C227F +25562C846B64143CA3864C1974777D33EB196C29B3391D658208C62B8D0679C5A2380B4C +95CC97B4192EECE50BB950FA8387505E858D309FB172A852DE81ADE4F7B7D1AACEBFE2AD +6F0106EDED3D7EED9F3827929B54C17364D62141CF95137DBC1EE377FAEC39147CB344B0 +94AFBA1B7A0A82D41E1FC63DAB168534255D02890B465F496A2625CB78E683DF3B64060F +255876747A24DDC01E0074211C23F8E28DBD6A6A0FE90C42A35983A92EC58F0383124C88 +9FB29494FE686DA32A5140BFB5E34941EE0A436BC5777AC41D188069BAC81E7E5A76CD21 +3D5312E317771DBE5EC3A6A3DDE1BF1176C051E8949CD8AEA5B12D67B8EF50C3ACB62E11 +73B9C04AAD76EF38A14E2974394080439A18C0194676434BF803672E115B12401E2DB0AC +7DB89D1D784AECCCE8B0B1541D3494A3DD019EEE3600C839B16070F7373244891AA199D4 +5AE86ECC513C403991885AFB8DFE85B21C3290DE9277B6BE583EDF324C3DEDE193B1D568 +9977EF532122FE8592BE4B649B773685A6BB1EEB7C9A7B00F123A4DD784F52A0D0A88FC1 +292AAC4EED21D1669C7BF24448A28405A6D958F702620DF8DEDCD899B7D88D9E8FA886E3 +87E91ED91318B7C0FB7353FBA22DB282D8AE1EDE64EFE64DD31D2CEC0712454C66502976 +2944EEDCB22AE9D3ADA5D9AA6D49004F5FB72CD0C6594D7D51F56FD7DD5FEF94B0CF6CBA +C823B03E69EB1F5A067C384EEE3021A4EC292CE7A87CE3A068B51DA6C9BC7A5293553DF3 +21226509A3F95ABC67B047D344BA7595A2D6210E748968EAB2999E24CC2041D1FEB1B7D7 +CCDB4FD8E57E1DB84C47F072CF15CB9425FEB8CEBA0C6A7B807CCD6A640C2DA23990BACF +69E414FDE169EE9DCF25B85463CFB6B1212A980DF38301DD90961CA8B53AC3E6EE9FF9E1 +54A3DCA66C6644F75164B3DEF201C66BE4D54F108A27689C79B0384070151567A306DC4F +61E6A5400E74429CA8F6CD35DE63EE5D81D30EB252BC34D99255BBDD7333A73531B4176F +104318299AE0FC04EE26B4B3B70C39AE5D96A968229113A6C9605483A55AAE4E1B4FE4ED +C3E61E7E416F905BFC6E7B8B982919BDE420725B76E9F3D2C993DF2A9A71B62202595AB0 +A15C1DFE629AECF2BB6362843CC82646B95C88BB074CBD23361008B6A575B19E27A49D26 +CEF1C27B1DC89A9CFA5725E8C886D376166E813DFEC08ADEE5A31660B1882C4115D12B40 +2D62CB4CB1C938D07FCF89E61B352551AC0B0E37837EAF6AC464C58A79068B2C7FD4FC89 +D471C914D867EE903B948B64B0AB8E3F80CB1A70260E84418014FFDC90F20B07E7DF7751 +17432E151473F92B8D7FC93827D2A1F1A204EAB90CC4E493F962FEBD84B816359F4088D6 +3B9B33B4A2CCFCA49AE19EAD91C9A6D3079C1E0A167C874C16741F3A0243A88E45D1F144 +32B31A286B1112DDAB9E816DF3BBFAA348C75305099E610EB9CAEEE570506483383F3681 +C287B3ECC3CB25835A3594604EDC661BEB1E4EFCEDAD9E4B6B09587C4C2810550FA9CB99 +CF035064646F9DFECF48B98DB27A51B26EDBF083A7EA8BC696DE161CC10301FCEAB82E94 +FA5FB6707DA84B83D8007435F44B216B36EF71DA5E490ADE62D61DB7802070FEBEE23F42 +4BBF0521F693EA29A40ABE744C030FB428C52A4CABD3D5E43283958CF3924290884E1198 +E50DEA4BDA72BB3CF95A1FFC8508139A48AECE8FED2704BB2EB8851E3A7132DCD145203C +CA826F0453C71FC2581AAB287947A14425D928D75307080488E1A30224D933A090857214 +029F05EAC8F5724F146A5E5E6392DA33465082CF2FA942F83BDC6A6870C0585B1339679C +8619069983A6FD382142C46F2D63E4B129A62216936FFDCEB97A1C5A9575CCA5A1C421C7 +600AF4CF4640A41F6584D73B5B3AE1A8D98DCBB4F3AF7D2E7316588C1B3BD6FB3E1FA8CC +EC6C8A857374D1383B0C9D1D314A10EDECF095E3A4069E79A94DD59FE72639FB02413D68 +4FEB3ED14BA97F733516C88771DEC6C4F7AAC18160D7F1C85916ED3F69CC6181574D0C2F +AF7D3E1EFA05EB5084F4F9BF4DFC6A4DA0985918622D90860C8838C5B8EE35B059733381 +EA94BF0FFCEA70FC4EF0AF2BB2B5FC4BAEF9D0CEA3E8516323451D868F723D01E0B78749 +4A69738FB836BFEE328A0A4541A03012D44B4830F174B7E35B0A25086DF34532C428E41C +83F0814F0F0D52021F42037B4DF2A6759DAD05A346E019A0633745439D835620555BBA5E +136A950B9BB234C1B3450E58CACDD658FFFD69B8E87D4EAE015F5427452AE657736DE2E0 +D66DFF9E03E20E37B377AE912B90DF242285B89610A55386CB1BFD83652E6BA1DCA7D1AC +A79748D0C07475ACFC652460785F6D82D1EB593DCBCFF0157856D5799635FA3E129FC93C +71A23376E61DDE5014964C4554743312A14FBF83FE99739D6C9C45EA465A4B55EFE80045 +D1021AFDDA6E5E13925F3F69A19741615D56991688E0A794DB1534BB43F010A76D4E29C4 +ECD9A16A90A7588DA1C31500FD55E32B2ABA623524B1E4BD40259F5C746EA160C13416E9 +167D2A5507D8D484427C0C5153E0865241A7BE0C298ACB22E5A2BB24AC7F78DB58415206 +F1C435587D4ED941AB7335D0CFA0528409704BC8FDA106CEFD32B77F1D6A02DEE4B05FE7 +3DF87C5D95533B4983A7FD9C3FD2A3C109F9D1719C372B01073C33C5CDA6E20F91EE2F2D +AC11D4B111E070DD059698CF18553C4A9A8707046A420F9BC6A6C208906987F2F5883E1F +8EF30E5A9F78BD73AE6C563EB04FD51AC339900528D76C28AE2913FC28C4CF2F585876DA +472A01FE1934645BA0AEFD5102C2F36362DDFF6EE3B4A12B63CA06698F06A0F25487EE6A +28CEEC421948B856D0CD999682277ACB8EB94DD7D88F18FED1725C3F0A9545795ACA2B6E +9C44687395B6EF3B76806A500019CB2A70C07E571100B7FCF486E0D14340DEF49740B1E9 +65ED400EABD0F69E310CBCAE8714030F5776CFDB057AB354CC2F1053F84EB8008F455DC3 +9870CEB793F611999E33B32E64572D46CEB3E64E0881CA70C576E2FC07AC9349EBF26BC5 +6D4E84EA3C835070D0C52A41DF388C8FFC979174084133CCD6639B616A4A20DB37F2A437 +0EF7E9F11A14D28B18076E8321FA194D9070D1D8226B2911595E3567C156BB1624F63635 +24D1F3634A08E48178D1486C48243DF9156D63B32901417626676305F6ECF88998B46F1B +50AF077104C052E9A20EAE6924DE1DDBDC99FE3305F4BF802ACD8DEBAAF15A3F8879553C +B1F4B3D7839D6989775507FAC15DF1B0DC95F554B16E0DF685CBDBB41E4A852CF7DC8A96 +8DA449DD5966EED3F7802A7B12A95CEC94DAF052CADC2CA2D84D7A8FD9BD74F90F47991C +4FB5C5D9342C445E963AF1CAF3E5DF7AA4D483C9F8EF73CFE48C6A25889E3B5B71CA4E4B +0FF97995BC83939E986AD7F6B379CAD7FD04C46234D8F85A234A878939110DEBDEAE85DC +636BE2A646F64D9661844FFEF6D22FB15F5B38C129DDF372C3198992CB6C378E8C306739 +012DD4B486CC3148BA4498EA8C0149E59D4AF1E7A0C00E0F94D58CA91C0C4261F459A4B4 +2F8791E72A634D734A3F5DF66AF91FA8ECD4671C67ADDFFD2E2FD30FCC3EFBF0AEBCE786 +DC44B9316B000A73773D1C354964AA129D82722BE5C666D5DAAC7A087F1BDDEBE3FB9AA4 +CA53FB8684F87577A264E607053D5E321108EE9B8CE78600F1986C9F2510C8AE368BF871 +8C8AD6E2864E257E40602D3107ADF63FD9DA46BCDBDB77B5164C43C9F1D0A1E2A50C7C0F +7BC6B45BEC60EAF2FC74022B8F0463F39CBCCF2B38318C6EB370B7CC45AFB3C1350F2A4B +48629916CFF777829AE2904FA90C19C748BFC921ED3985BB03DFEC5E9E250321B75723CD +1AAFE40242C54B182846A979E80024A9E72029A7205F13157E57C5F40951623EF59EE581 +20E1C1F1EC93870BCDF45A74A731DC31CB5EE13F8C568E4C80C7D9ECE815610F215AE88F +7157CBCE990172AE920EBED45161194EF998C933252599CA45540855A0E4FEA0866C2D41 +8DA00464051D7C0E2E5932D7D80921BD7F6997C9FC550BDD83433D959768C0E35E8750BA +0AD159CC296B98CA650724BF9693E410AB6106B9D423AA2EE6A47DD102EAC9B74D66858E +FFA99A6422C9B5B2D466E817E8ABCD4E953A9DF9CBBFFE5748E6F47DCC8831566DCA5EB7 +26B68A5C1C575340F5D034E15209E7A6C5A3284F3720A5C197111539E4D3F4B3392D8F4F +C400E3CC89544B440BFB258003A6B7EBE045D625BB3166DF4869F2D8CF74EB7303F0AC40 +93C24843BBFCD9A617E2C7BD53572F0B61DF1BCF677B5439B97483C973AE56D0E206FAFC +1082F9B2D0D5F900F6575BD6E11FD0863577F4CB1277C1D156711DFFA1012EF22725D52D +0136939EF40B0F661853385E154C8660C3C472618E7115D705CD837DFB7C0EC85F8B0A59 +DD1564378A8CF2B03768B9CC5AD7ECA0DDDD4D405B0DACD6D13468C833DE9DC82271BC80 +E4A6357569407FB09C289458B2ED792D01A9BBC25ECADAA8F2955811145BD3D681834C23 +28C5E3760EA15AA03D3E0C4E67191EFA44E4A4928089E1224BFB0E79B5BA440E036007D5 +32CB8560DD157D60A5A690894208C9FCA54F32FBBF9C9BCB8A3A9ADCFCF2BCA1564290E9 +832C9E79304A223F60B7B58245E65D598EFC1FA06847E1AAAEC8BB3ACB454AB5EEB9265B +04589BB8FCB5F87576703AA3594B688F5001053D34F17FAE60486EA07E6CBAE2C6358DA6 +AA1E68A556A1E2B1B2DAEC2302FE04241CA53BAB74E4EF219ABB868FD624B519C70EAB34 +B5A953F17AEB07E867B4317B48B2DAC162B6A9EBFFF4910FFD8A96BDF6E501030928E380 +A6277590835C01A704FAF9C32907990804D0A1F70529C09742422B48586C8762D5E8871A +F91527187537526FA52601116969BCF7C4FF8A22446A184E9CAC17AF709489FA39D372A6 +6C3D580B183D1AFBD6A21736DE9A09F2968AE69FB587F4FBF7BF281DA926F6F55DB0430B +B45CFEBC493195A1B98F68A514C64483E30F22A7DAD69FA38ABC4B51110560DF23517214 +081F999A3F1D415D8993C940BC40C481F77402B51E7573801DBE672A8739BE239923B996 +23B97992EE35B62734095822B8331F69EEF8BD26FE6A6FCC0F6524CE9BEEFBF40D70DCAC +49BCA97837DD526C105AE9624303C120407740601B1808D28F311B42B2EC20E1FDABFF13 +2DC42A1EA01827AC85F44F4E24C9B72BC9EC17361053BFEEA913CA872A24FCAD6415C77E +59FBC9182B6E931C0580BAFE050432866D75828FBDC44889A794C63F0855E75CB056F36A +A4F5F72D64E5AC055EAC800972934F2534FBB67469E7E41FB8F5819D03ACCCDEE81EF213 +0E1A4FD88BC7074BFD5D83FEEC51C9D1AFA13EDAC699B3DE2595C88525891F2179D8A0A3 +650CC93EC86F1B79D135BCDF82E797480322E4115A5DF19F16DF7C2557D750347CBFF239 +979DBF0DD515FA7B9A12F57670103E579FE7E7A9E0608CA20D0CB3FD1862E99248035DF7 +008C5972B216D066B473085B42AE54AE3C4651E4961F412E7702535F351F4273A97414A5 +3FF91785AA3A90119E4B93B8BA0375207191A2EAF3600CBD3A2ECE12D8EAF640295AFFD8 +83A7779F6DDF812467E38DB5E6B5F1C1DF8B4A0B95BF02E5C5F896936CB4408BF19CB9F5 +58541953A868C07F1FEA9A3EE0CE28BA312C12336E4B1161A934DB4035DF951B428B0320 +5FCAF9201D34DCBA174888CA3EF9D8E708B7CCE5CC95ABA181B7D251BFD9D6B3D7358EDE +A8A32B7F85C3F2FAA6D2C8D08751CC807E719311621F76D554B7238E9BBE15F19A7102A3 +0F343CC0110F464BBE35CD3920EC3A3EAE89EEF21717ED7015359D47FD7BFD16CE001058 +0B6DCB1BBAC9FCB2EE435D6AF4284B0CFB140CFC4B7BAD83E8A5EDF7C27C3001225D1030 +0F48379F84B62D77D289B6F2CBAB0CB27B5B9F840EE86072FEE3A858A62753BB5550BE8B +A63CAA5AB5E3756451A79F6A65D6CAB3DB0FC739345392377CCA2661A58AF73837441681 +567C6E81C0C8944033A4F36D599CA915EFE4D03D95C245298D10FA0A5BC9E9569D84E13E +9653D44C827182AB29339203E578FB73FD1F1354142BF3D553A6720EA72318EE76E226D2 +AC788224721DD4522A247C18ECE489334991DCAE23D459656224ACD39B04DF5ED6A19375 +DA2C2113CB7B8696EB78522BAA320D94A6C04E9CCE17D07C833B6760173F99151D27C561 +61DFAF6BD81FC42872E3DC8BEF1472CD53E32271A997CEA4A057D8CB8DAE15FA7AB150C0 +D92A1A65CA400C436CA993854B8C18D78F1B593139F5F227ABB34E1590A37886467BB263 +14C735651C3245FBB4F620A013D98499BDCF3BFDD6F1923DD9701F295E50E4C3C74DCE02 +571B4F4CB40C06B325AE0D51CF1D9BA0892ED1DE29419E3B8D6BA907B54A96BB67C1EE59 +31E85906AD2C09A9A964401769446BBE07199EC8EA8E3947B5EC31AC7537F93C9CA4FCAD +771A110F2D3AC7CB6DBFBBC2855F2F360D8EBB53045AAB46D65D206F03E0F4C453FA6169 +1DD1171543A53B89A2353511525EA85A4A825F3BB6BBD2889CFB8696E89902EB0DDB58A2 +279D214EDD2E20E0DC1F06A02B09AE75B20DCD226D353ED6541007905383551B46C2802F +EEB4AB6DA75C2ABB220E8168268AA384B3D4F8D9CA591B6BADBC27E4CED9B4324B2C4C19 +80ED6D6F7792FFEA1BF7D9F4D5CF6E52120BBAD41C87C749C042EE247978B45A1B30DA2B +C2785D51B7E02482A095B8D8A3D2132F9C80ABA4508931AF7A99A07C0286144C4F666802 +A68D63210AD70C872F74D40F72547ABA3F4779DB29A4C86633E273B3DE4B5F52759E171F +C67D16C74D105780E2B85DAA2D13807660CAB1830AEB605CA7577743D01AB9D001A65C75 +95F576940C1D3E48C8F5FF569E6B17954E98284DAA7C062347F0C043D9B71AE0FE0554F1 +D2C8DDA86EE58CDB0D63C974812D902CA525FA81B3332E4A87A5261D6B3FF4FE11F44A1D +73804F9DEF69D93F195C05C8C16781252FB8DDE0C59687454BA4D7A3CF762DB5AD308A64 +6978CB14A6A8DC6570806D7016E3B7FC0FF01ADC1D983B8A720AA7882DC49442A7D94A6E +8F01E5DC1201D9D0747A7DE1500D7BAD256BB6992F5B5E1BEC1D88BA81C11F80F994653B +36586D1EA5B5F805B16438070875630DB4B42B0CD171B152FB6BA57E9A755F80F91AF208 +2832357ED13E723AEC166195D6D88DDDE42571059A5B8667D28F3CEEBF24002360F226B2 +9C6103C47D98A6A330FDB99A0326B702EEC1D3B8A118F98DDD07ADAF1B24470C8C465217 +172119E78D37FA0E679D3F4EB4BD103D821FD839127AF7A26042853B99C89049A7268D82 +DF8079A1D47144010BC562504310AEA3E2FE85D91CE43275B50FDA31256265A4C318E075 +2C7CC99FA1618BC3979A58399060CBD9C4C8C7D5455A63BBC4963336C5BC72ECB5245CB9 +FEB9D399E925F9C67EC1FFAF1B28A1071A58CAA3AF9ADAD934F4D1459FCCFB856644B2E6 +FA6FFE63D48676EEBFCFDC2CCD9EC64B71A30342D364A165AD365F82C9971C565291E1A4 +FB4A40806D264B5A3EA0EDD1DDD6972D5EE5A27D633D546EBD8D3B184D7740E519857AEA +F8E2108FA525B504780CA54567B09C188D5D960C2CB3AD7FF016955229DDD88BEAC3BB94 +C955A5A27029E2E76FDFCCFA2538DB7FDF8995A4A785630B22EB30AB37722535C95A432D +04B82EB054DD30227EEE30D77607A4C2BBFCB2F653CA8895DBEF75AEB36BC7A48DAAF131 +193DC36826ACB8F8F33048F223D6BB88DC9FF78BF729C07E70117D205D39EC03A0C89BDD +926E7CC6664ED8355F2EC41D9B3CA8B4B58A201BBE9535A5620FB6C100D97161F308B01F +5E9E22428400DC8F41D6CB367BA6E8CD890D0672E8506B4C6CB352AE06BAA26700E74856 +7FCBE12864C32480CA3A1CED87517146FEC7578E3DC027CF2A59A5A09A3CB76657362158 +5A1BD78D218EAC0B318D8C96F2594734AAFABDBB4C2B6927AD5299698366B1BAF03BCAB1 +E9BC91A11A33A1352BD8F7170AE64A116675C3ABB5840114D8E1208D851BA251C88A7764 +A90E769FA91AB807AC6777F777030BA02DED02C2C391B69282AAC1BD8B99F7F9BC778E98 +B2DAA85A3EF8E9DBDDB7887890B0B2310285DE0EDDB6B4628550AD5C2FCA48FEC21F1BDB +3C6384784EB6557DF3DBF585103EF3B0276C48154823C79224218011DAF0763BAB3A9CE8 +C412D7676245E96BDD47F2E79E126FFD8AD75139B3B37FB13DDEE30FFAE28F7327B859F3 +14E4514546B87FA7FD4FD545872FB0AE4F8AEAC3B882A23DAE3D98098BA60847B013CAC5 +6577FFE3D8A1FAE941DEDCCDC7101E7DFB0B17F0E11100A2947B73FD8A22341639966D6F +DAEFF59CF0508E01920C167369109507A6E7ECD9CCFC30F7AA87BA0C1C82BD959FF8C43F +234EC01C7E2B3AAF12F543FCF5C2A2077DF5E0E9E3A976F107BC8E8856427511FD5EA85A +BE944C72CBBB3DBF4C9870F2EF2FB3398449AED9E345A43E8A6B0A99EDAF4118C89A3612 +CA99B59D4BBF25800E147BCC6CC51D1B3239DBC3A15CE68ECE1F2CDD6D8732238A922C04 +AB8859F9255477B00DB497320B8017AC48BE9C10D2452A82BDCE5C37953D644D50761302 +FD40AF015C8FF79C82015EBD62EDEAF0C0AC637F54F436ACD2D0876390EF02E29A4E3B3F +59C7B3E1EDB64B75F0DAF5B401015114F226BC68E31187214A69EAE0261DD7DD59B033D9 +311A2F01E44FC47F13927C1C9921A5881F2172CAAC71B0FE038C1B6CE87B04EFA42DD4D3 +65F6249C359F8071BADA34F2BD0A2A2C7B6B8AFA6A1F765AF2A9E77942190D1929EFC2E5 +509B9066CFB90D5D2A4732088CFFCB20A56A3218B020F491688AFC95CF8240EE7B7C38AA +13CF17FDA80F40DBFD5F92D1185968B43A26D0E38D0C9F91E7226E5BDE34F083FA117E2A +EF3CA2FE14C63CF404CF833DFBC09E27D96F5A6C16FBDA79DCF00652DC6AB73C4F6548F2 +16C8B245B15D9B5B29746E53FAA0D95E4C0357A3BE36A6CD993AECB9A42828E934A36388 +FB546D8C9D3531EC7B729D44D8AB61975BC7135E5ED59FEE11F12CF5C9C59160DE698385 +778A751CC279F807DD68BD5CF994340A16FF47147F029468C24E6E7AB08C2C69E9A5C5B9 +8C62FF6197C8455BBDB7BE9D069BADCCBE86FEB495B52BF65CF17C4B1157210C98948036 +55444C22444519D8A72A2899C20138698BD646E94748B62C3CCEB35C56837BEF1BDE5B39 +AF2E40A4D73DD747F1429CB4A953F949B97D56DE8601E7F299C218FA0D367559A750802F +64DA3BC53F83A733B1379AA57CDB1D657C2EE623A9696CFB580CB63902F87B4786A55EA6 +2BDA6CF94FA9CA44F388138020463F5BEEA1E273BD5BED2E9B08B60558D6A2901929C23D +2E6A61351A5CFA65DF52819D002CF21CE650520436C9681C60D81582D5568A6A0536E236 +26A13B4CD55903D130BFD7EFF26E806768C8EEA16359FD842898B8DC539E3170D4FCF3B8 +72621BD4C65DFD9F7EDDC0B17BB478990673970D4D4A07C7170698D784360F7A6A53768E +D9B41AB73360FE08C21855615214C91BAEF2F6A5AB71CA45E4B52326EBFB99A0CD401A7E +2944424878194E14C2BF7D183EA1B4C0BF9A3B2157EDD6143E9E9B30891F1185C3E2942B +EC87C1EDE03B77FE7CE0D145C0D918D13EB28EE264DC78409D7FADFB03718C6DF7D50A71 +EB216B5735A990274C349119C8739E5505F23C7025A79F4A22FFCC532981D27A70B94A48 +CDEEDE1590A2A0FBE661ED24CEEEC4DFFADA11F6514A8D7C026D2D685B07F9DFAD07147F +C7EBD82D9A52AAB50D1B52945ADD441A5F3A6C809127457895402C1AA796582950808F4A +21BE6BD2FE25CB9576AE1640ECDE763FFCFFFDD8096C9AD89B8B2390A2275F224F2FFFEF +148E4E1F29DB6BEAE998065B0306535D588F901C3904FF47D1428DDF213BB0D9D558006B +B5F032CEC1BDF4F8997B304CE400EDB24EE46C97DA278E03B768C2A23C88878B9A79DA41 +68175815CD1336A71D57C6E07CC7B8596425C9F8214F0BC2D99400B9FD644C1F8CF0AD3B +795B074D9D9CF25C18D3847873744228A6AB058D5D213587F16740AB978CE10EC3274FB3 +DD411E0392432D67C9945091AA3D90F95C3AF2B808FFA37B6C6359EA023D1ACB7A007F4D +5AAD3D9EE2467F5FD642FF3AAB11451EDE32138525FD48DAC480E29A16561A7FAF95759D +F83FC7504396991BA3CE2072851D7B962FA387A40F62DA05B81B39CFA6123F5B2CF261B4 +C7A84DAF87238729FF71D6F3DCED7CC97CB9C373D6B150C035853167C49368F16E447A18 +0F7F9D4CC3978E3E6B5F3B4CC7FA3078883D4C8BAC0A94E9B69B7CCB94E6D5898EC61A06 +E5A960058E6A1696C0BE287F24869414CA8D16E761C120FF5116A19EBD39109B0E251664 +DB0A5722B4366151759BDBA4A74204893F585A940EB1BCC870873F6F4E08BC88A239F23F +FC51016CF6F8CA8830346363BBA0E1FF376EB66174CF31ED9AE04219301EBF61A1BB5E55 +A89EEC27A12666287AE6AEA4D45A3706FDED0A70326CB050B6D25FC56216F932C1294E54 +88E3C331627D85B34875E7B51E4E7AF724CDBABB1F14EB6F23088595F2BF26D88C04D4F2 +4B94D94DD47761AA0A9BF649B06F7A2D56D30FC432FB49B570A53280A341BAB378037DEF +7FDC3B284C83F7CEE6800CBA2E20844A4DF8F2F5400167D136F810A7A739195896E470F9 +5875E669A770691C885365FBBAD1BD8461B005DBDD60891F12D8D4C8D51C8605B3CFED8C +EFF997868478A6A9D642789127727FA231B4BADFF182AB67B8D19402633BCD4913957BE8 +8F95E11EFB60934E8F26BD79622385F5D1CC5F7F492BD69C8C4BE47D76EE6466880A1885 +F63C3F4C893032D90FA8CCAEF615340A8424B4B1752C9009DD1EE6E0A10A0BE83DCF2CF1 +E746AC5A62FB5809310D5F64A267028A7EF02493B6DF22012D036A19B4AE3A9ED9A5F9C1 +6EA82AFC6DF1DDD7E243B4464FDC28B63DF4CAB59A58949558B1C1B4DD96800A69D14E7F +9DA1E1FB6DDEF437C2D31493631E79A41AEF27721579C7B40AC30421726959CA6CFC3F65 +5B309D67F0D50DBD33DE84CCB5EEFDC4923A4200341A8B5F9541428A9B6B94CB973BE6A2 +F39DF0CC141B9CAC1D0F25FD087A176D68BF69C6D2BA5084B586B289B00346DADBB42774 +251ABF854004F12EE97092CBEC6BECA5B74F21DB1BB72C9BBD9C0E11CDB4F64F347FCBEE +AE58924610D8A5ECC6EEACAAD54B36117A2EA580B9D6FB9635EF4ECC1649D1AC8634CD74 +0D01BA7F6F2379AB2BE4425C02198E8E75FB46CC405F706C2E2CEE54582CC08A239A6DF9 +BBD208AD5AB256C5CA2230DDBBAB210FABE5D4582B22F0E66ADF21F4F755D8E16EB071A1 +3EB431CB00EBA9EE617E43AC2E0DF733151A82D3000DE349C9B9E44227CF001D50E6C62D +A792040A868EB92A635208145CF8C25F51B698BC3460273AE679D251A43D5D1ED8D5D759 +6743700F9B67ADF9E103EE9C2D1727808433DA9D16ABDAE228FB35FADED5D54816E066A1 +8EC29EF2242125D1687D60655B3EBBD8E6227D0CAEC0E0BDB7845914D063890125E568E3 +8B14160794781E8EB631115576CF5A7E9639B02A28CF363720067EB527988EA1D2DDA4DB +CD35790CD4F91A253D0A9814143492857A320088FB02B28ADE5CCB4BD7878682E2895B07 +7029BEA07B654A13EAC49FC3E9BE70BFEB73418204F9164A26E47632CB0FB20C643A3245 +4777AE40288C6942D4C0C88FAB77120BC73DEA4EF0AC703DFBBE9FE79796671938382F22 +8A9C5B45C48FA131C17BE362EBDEE57378738DBC29297A9B69A7854A6D702524A76573BF +F76434BE57EA370D43CCED36DD0223939D362102547E2B7896BEADA8F0B3243979B3B4B3 +4F43500473F7C712B5E3B25BBBCEDDD40797649305E5E7AF2B767CB21C93195FA3B2BFC1 +A5891A91CA879BDD643A4A3B384C7A55718BD872E01674336419D2B1EFCBD888FE8FE9EA +3F07C87A87BEF21E66F8B26D25841401C499B31DF68FF0491E660E40C79E5EC2312BBF1E +364F6177BDA9DA10DCB347E40C8F423B12700C4C47DA4B09A27CB14310C7EE8DBFA567DB +0BA6DF2499B5ECE65519504C42B6813E0B906ED94861EFEBD5281DC0531513893F7EBF2B +9F43022A81ACE291CA736570C6E099A8CCB59D8E7568AA5D18FBBA8986905D35E9B52D59 +1E36EC95612B25F371F2743890AA44974F54814A4BDCC23F5DC100B5584B09A746938953 +B5D519A50D3F1FCE6040918E3CA5E3DDCF5506055FF493A8AD4F8A081BC3524D88336AF1 +80888D96699045EE95F984547B4D9844C9B596CDFBAC8ADB0194B7141DAA0385470F2AD9 +F542FD1369E418C5B380CE40E2461D3B68E091021E21DDC50D96C5578D73B9E84227EA05 +8231936F4264834C133C58D71D347100684A1F3F5A5B461D669B92BD7A00745C98906EB3 +15ACF12D2E94B597940D85CA5B69506661133A6B11BC940ADB550FD9B3FC14499677212F +B6166E695839DCEA3F1442E2C9E32E28EFAD1678796946725A1C0C62A1EC5972933A8FA0 +D37AD1D8EFDCA892F53962F57906EDF22B55AAAA17562F2F876C0B5C85197FCD583E2A87 +6C28672FB7ACCB063154A1FFC37A33B104AA37C7417F46EE3D4B59BB4E4DDD58A2EFD829 +71275C35081723630CA67016C8BEB30A7441E0BC9A4973888F0A377D7A3ADDE25981BBB8 +036AA2D9B15B71D54A7BC6C8DF79E7D2D50E97F1DB6E796655F47B5E988653996F1D3885 +60BB63A3C364B5AD590A5DB33524282B3C6A7C228EFBFC222FA475FFF99E83EECDCC09C5 +406985D9B3C00199EE2A620A7F820D1DC40353E0A76B46DA672AE1CFE632FA3523C8B32E +2C0D7344DE9DEB24C7E311E981B216361C401B2C7E135028BA08D3B91D39099DEB9DBB2A +4050AD37B9B823815BC6AA107A3C7B935BF259D9FECE88232061E4796B425B5BAF4C5E8C +4E9190E159743D7F3E4AB2191B8EE8877D8936E5D324FB57E6936F8267C015CE6D04291B +200E1C964660503C96C4A4B782D09F4D3BA952B7EC7AD5B568D27E3A07B26486BC45F394 +128A011F68B0434829C59772C66A001A50FE3C5F2C4683BD81AD8C4B7F7A25127CDE5E2D +EC216243C2398A1551F8C1E37939FF94CEC8A9C1CBAC52BF6371DE25BE148EB39FCD9552 +3065F034E4F96B1C5D61120DC87D04E7DED973471C0A3FA1E1E6BE6E2F01DC0199399B87 +5EB88A3E4AA85EFC9D9F28B3DC52319D374AA64118E1383A8A577538C29859090DB65026 +4A866725524BEB3FBBBEF6AB74FE8F786D1FA8AD94BE90794AC7E72DB71DF74F577F169D +F3B310C2D69D729A2DD755AECBC0E463716BA5DCD4680D4D4F4164420F2B46DBCC60BE6D +A68DA2B2AF32608266241BDA6CF36E132D83D16092DFF4D138BED509909E250DFD9FAE30 +53BE12A825D3A91E404449013E219BC67A2B18E40D497125A2F39BD16824CA7D2A2E5173 +89D69D5D838BA27ABDA5012B426E58456B2399ECB1B4009CFDD6307F6D104647AAD6D083 +A562E7282007B3B2A0B6FB23F2EEBD0E7F643A9BC7075D893335DB246CCBD8A37DC6F1B9 +649AF15271717A769484B5531A1A7D99A43E90490F86C170193442D01EBF02842D349B7A +580D601534F1EA401D27D98455EC4A5800F4BF5893EE080441F6CD28226E4F6AEDDDB7EE +7CE77F2BB54FF006967504CCF02F4875EBA2448C00FF58DA77B50A4F4A007663B5B64B18 +702C96AA0E6F85410580F931BBF249E91AF47477EA284CD42572FEA81C462D7E0CB5F81D +EBB94225776D69B02F04D76B51BAF103B265139F85EBA00F47BACB0A1FAB9D39B648B5CF +06E58CF1CC43A431315953006CED0FF5701401B01CE4F335015EB6E41DE8D14F1B5C5757 +1371E7875B17C44B374184836C07D47F4FA44F8E49959BA63A4647F757B3837BD334D2A0 +423E620AC5E1C5B18C3A400A8CCB7119C3331812AD8863FC3A97B470293F83CFC37E8BDD +D2EEE4C5F88423740C93563603FCEC652CD447869112070497A5141CD7DC66F62EB445F2 +DAFE1378B286E730801959EC5FCED464E1BDB06D725970C08CA0ABB730C12C720E219519 +FEF20F96A1B0FA671565B45FCF41A40D5AFBAA092A09F72ED35FE94A98DCF5649F6AA3EB +FEE7ADE1E19B4429C4E1E76880C398246201CB067D8A734B23BD3118A8F5F7516E5B1452 +72CB0AD9F41ECD8FA61ED0CA87385B2B45B1BBA6CDBD7B9C9890F727BBAF5EA03273E387 +FBFE8D0143D1B215003C9EECFFC9970AD21B0A7E90F56E53B3409E102F89D95B3EC58DF1 +B1C8D48CCF22BEE22EDEDF25CA18A0461D2C582220ED664F198B93B388FD8CA9CAA6D8AC +95F10E458BE5480C767D6606675208E4C823FAD4A3B8E77915BD881C345B0A8C34F01B75 +2566AE58CF3BC97B215EAAA7189AD6BCE0A524C0998235A61713C538CBE9769E2350F670 +4BA790CF77CE5BABE376D5C2B2F9EB8D90B762BC59D9DEA5234ED14A949B002258212E36 +D5A22B4D847EA8C4171D74B78A5E225E3D956FE7F8B95FA133C50F864725C1B8F11C2D1B +3AA7D08C0745209E00B98BBE59E463D60C79122469F9ABB8A7CF777BD90999206C83F8CE +8C95C79993C20CA63CF556C821C8DD3D5124D2F293E5506D9CA515E026223D115DB59D8C +883FD825FA3EBB449524F1BE7811BE76856A063BAF9C09A3930417DB889B4DFC1563F688 +02F4AE1BA0EFE463FE884CFAFC0FECD0F4396B006B9230D9D3BBE6757318184EE7EB6FE7 +00E148C53CF3FB7DC90811F6D5CC8F9FFF975EC7DDA685B76D05C0320E7C3AB3479D00FA +927FB3E9E4363115D05E3D62AC3FD06310DFC6117117AD8BCF44233B05901E32D8A1BE67 +CA059C513BA968CA1EFE077CF8D651540EABC16EA1F61AB1D7F74F41EA52E1BAA0A19576 +5547168636187DE931C6F97C624391A212859C3A95F42DC367AACF13BBDD503FC1350FC2 +FC6259B290A18447FBF37284CE1F00DD81929B13F366C0C4FE86E834DFC7FBF5B4DE4D5A +33D014E3229A7957A112519134F0794825317A8D56EBA39ED15725CD940D974912D4A79D +C499D3B2DFD7FD67DC7E79F70A04D5AAF40FFA6A568AA4FE042FC2AE31E83F60671CAF60 +B8425E4F3959FADE3947B2DD3438C7B08D71A036B2ED959168D507274BC4C04BC9A9448C +0385531153595DF90BCCA1EDD889B3C9F3CE3FE63FC858AE51CACCA7160C3296038EDA20 +38625CE0DD5C236F6F18B3B41FB6D5953F18D5FD4F700A95B08BB10431090C652BFAD23B +D4A9211D0CF59E5C2D0AAC5708386D14F02858C820A191239D08E6121A77A83FE89BF056 +C42A6A56B55EA35DAD6696F64F3B702C21F4D97D87CB80ADF688E6F1094B00714820BA53 +65CD655C9DD5BC030FB2029972D15CA71610085A1A7CA47E290D5554413EB88B70D94881 +1BA89738DBC0C16EB47A3CB6190E191E67004BFBAB73A067501BD283CA816CAB52515721 +4CF005497DC884ED61CD5F5235EDFC207A0E8BE0696E7F93BC267C1CBD85BF4BFBDB755D +BEB88A7D4B978AC52B7D1AB8D828448F848EB6D2F839AE9F4BBF34E1BD5DE77FA93F23A9 +D111529C49A295893296D10F51BCF03327CF774BB1AC501BD8BCA58F3E82BEF79C39F434 +845435E9DADBEFA2AD5D79D8B0ADED3DAC9C1AD9E6A24B206C9DBBECD552B2E6DF97F864 +C8925A37EEF8718CD4D277949D389959D852977FCF96E2C46477CA973846DD65AF478490 +028CEF70A4290B22C4DD7514F1DB34820656EAABD1FCDB7A9BEE0C18E577D9F27CC50777 +D55B4EEA53E8F681F76D4791300A06C380E57B35FA48314BE3C4A70D1B73E743A2B264F7 +3E3C73CB25FD2D33D74064BA8803858C8353C1036E09EE4489433C92F43ACAE005051DF4 +A89628CD3B3EB9A569AE2DC5EB290715FB1028B2E32BA7BC4C48AF1FAFD94412BC7A036D +A31924EE68FEB3ED8DB8340154D5757AB86B7D5D37464D58A22B54E37FA9891FE1A54C01 +D7FA05BCED8CA937BBE67979068B177A777B2B315E6B1F77AB6930DE1372A95A0A1A01FE +C9405011F1F3AA2252EBA22A54C779661AFFD26FDFB10044D8B68277234762FA2ADF8EB6 +B53B75E663976FFBF7D43502184FA7CF047A8CDC2CF0220E542ED63EE9588C41E35496AC +39715683CED932BDAC827F5CCB9BE1D3BDDEE2D2C900AB23E2B54766DA16CC227E58E53F +788F5A8880B5FE8A7355DC73B6B26BF783F02E2CCD5F96794DCECAA0E7A603CAF330FF6B +D8D56153CB4272AACA3DCAA5932B7F754D23BE23B2282F6C2C59B2C1EE4410F342160BCA +093ED020E4EDD16C7E6E03FBDB06D510E6680A471E3B4E2C4319FC138B92A8EE4058A0D1 +8D7FCC51D9F16E9B74EC75CB482903BFD27C4A17654A6AD85D608558C6A717D47005A8DF +B52C28282EEF5B9F7DB1086D19021269438BA974CB8C34A8B85C5542519424FDA394E116 +61636091F18BA443113DB75E9FE5C5B8971E8749D15FAB20B90C10D3682102CCC30CFC3B +67DC2D519C96B9F607B6BAA01FBD8B78236BDCD6EC3536D15BB3A069272C646403BC64F6 +FD55E28988D01DBEEC75547D4D4A975761E5BDBD5E3D7601065C4F9657D3E492DB6A3558 +037943383B261335F01494978F46999DCD5584F7B5DEA427D20F20E29B1D80AEF1E279AB +F27AB8410172E203B3945F98FF87A2FEE2B89293BE2F5DBD88A200130143D79A5F8943A3 +D0895650BD6CC2FC5D5675B30B12B4E095F2475F7D8788EC9AA952FFC8DACB281EAEF931 +34A6F83920FF8E7C58441BE339ACCBBCD4C9BA4C8EB9A5F6A45614F991D9EB0A76B2C869 +944CBE0D6C0CA4C8BAD0B897328A4D354C60A31AD9EBC0F97835BF4CB7976BDB95152A1E +919144C60E884BC6E6857496C77C3C7AD9F52C53A9051238011D41F14687E5B3F666CCE4 +86D16F3CDFB9AEDE1CCB3452A68F5FD75FB96600750457E3C3FA6579BF938439AFC75386 +D1C0A1FE73AD6968DE195544F85CFC697793F1F66DE6CBD8137A918B2C24A99724C978F7 +46BF6AECA401F5D298CD1081970FA904F2E2CBB2D749526C2E14A43970B2B2CD28EE9178 +A58F60F7BE3F87967B4C1BEA2ED73DF6692862CE919E3B406480A69CAB794692D0FD1C6A +65FB1065BCB5AB47306164C0241A6177D8AD8E629C77F84A1AB5CA62B493C5C016AEA0C1 +E45AE05B54646CA6E134B776D09A11FE04953679CFF2777B01370F482CA655CBA8D1F91E +07D0106FE37E83267B5432ABB51D56C88EDC58A11D8D90FB5E82BC023C4521A6649B9388 +5BA6C0D139C3BDB8B0325CBC27AC4E8F673E53D84476E1632DD4A09E94D375B65B0FA682 +18609F5996F543A985FB6CA55D302D63F86F234F94C9A5A15B0333F722702682424DA956 +1E6614FFBF8A9293F5750E06BDBB05D3BF6F56865577FCC010643699D0AAD5633BE88939 +AE6324C36A7A5FD5F148162952C357C4FA5E8DCBAEEDD28D71A809ADFD563AB3C4CB790D +8FC41B81784B3E9C672A2F6A2230E90882EA374A579ED2BF72795E84B089635FC4F2B48C +D51C418BF26AA4939CFF22A0B37182836E70AC08C971EDFB46A31BA11480BB855D53A01F +5A0688B2CDB04B9C2CF22A63ABCDC965993AEE1DBE2BE79DA4D1BB595E24E87267FF1648 +D7F8E531B275C5499FD4202A948E2DD9FBC7CEF688566DBC53B886A2F9843F94CDECFC63 +78E6937D4CB278E11EE9E2957D8BA31145058010C98A752CF568AAD0FF5C4C67988868ED +19762F2F54D6D58A3747A6C5A052543ADAF50DE5AEC5DBFE6A2F78F08A50E5F65C328290 +B383524AD0A1A477A9815C8378DDC0CD7E8CDAF6F097E5DD40900B0DD7A7354A37B9D90E +7C4FFEBFD1DBFBE33B5EBCA7607243A53EA746FFB8CA2D88E73D2696281CB210E6D5A0D8 +46F669F24E3448DAF1DE413B6248564E718D903654ACEBCE09A7CA994306D924535F5792 +21C39D8E386B1573B9B7C26256419D8B52F4980018DCC0001DC87F590C378EC0DCBAB4B1 +8F362A7F64BD16DE2E647A4B0573D92F1300D5D8423A1FC658E708457646CA9585071B72 +E66A2D919AE292B460E816FDC8CCAD369EB90FBAF5BAC731FDE38CE2E45B755934264D8E +4EABBA7D6C0C91B4444BEC23D8FE44230223BD612D845BF57659A9594168655749D147AD +CD4182BA77EC41BA34595990446E1D093CA7264512C12DB9EDCC3A2E97B478DA4A2E7A81 +3CCE2592BB816CCED1196A40E76E4B0BD2EEEA1EA7BF331D497548FEE91A56C7C057C3CA +E25412546FAA9C1B8382F5F01004E506A0DF3BE419B38AA7196EFB6C9B469E49DD63572A +60FC9A5483CFB723FA04BAE4AD526E8C3B14E252750A79C13D07CC1A1A424B33586F7072 +F28D5C61DBE7F0EB9BF47110B4CB018190CF5BD564CE48B9775FEA3DC1FBB03206573E02 +C60969330F0DAC03A4EEF803D7F860C14C50D809EA5D5FB13001048D2CEC6B56C2423CAA +EA0FBBC4FDF550F0EA3D921F522A65CCB0E1F590106F163DE12D1410F35D72E7C6168D64 +829F8144C5B7CC9F902081954923AD742954477ADFDD4D321A593A41806C002B02D9DE03 +38DE6B6401408FB03D282489D23B6CD09A77EC31A7EBE000D54150B03A8610D0DB8BBF8B +9C7E94419C0E522521585F2B7C657CABEEEBA79F2C8FE57C86F593F805945E7DA313B826 +2DC421EFEBA8237EFCF9B054D12CBCD0A3BB32C4A5BAC3E8C105C32860E80FD83F095A20 +AA4497CB6F4A879E5F7AD6C2A8272E937A61BB95402F130A37261569D47A88D4ADB80A1B +1EE5FF03D8890B212E3508C408EF145C570FE2656ECAB9EF52657A04456B580344FD4F87 +2B5D5308DB567B1E957073892D8F83A2C8F93CCFC11D3965EA0B985B5521C997786CE86A +3D9E0A3407EC73E51BCBE2B53D11DD304F0B7469E34A5F6904F5B3807A62534D742DBD4D +3EED49B28F68BBAF5DB1E261ABD0C7739CC09A4779D5D2AB15ED9762FC6E72F78B71DFA3 +23C29D48F47E44A38D87168413E3F589B9470C79EF8A4EB6216F1F0F74FE2853E7EFF2EC +902018A4F6FAF4CFA75B646447DA90B8DD612A65ECD9504C751D331B3762DD369EB0D179 +CBB70EDADDF73E58919C65DE73497A87B4ACF06360FEE10E7593507C6663B0FD0308C95B +F21B9ADE7966A23FA4CD0648051F2CC20ADC25C8F983EC2DC97E2160BCC62CE3051273F6 +3D65913AFAC94E548B6BE0BECE2B704778A24C4348F128A4EF617A7F43AA327193B5BE44 +C2045CB1840DF5FB6CDCBE455EECA489E22F0FF715F4FD6D14A874031C58A8446730D0AE +D36887A4B33DC943FB6A9469AA781FB0E994AAE327A86408D63885662065330B6AC00AEA +FADA28C53CB4255EA1858ECD3869BD7A27EB5C9949530081E5E103DB50CB34534A4C63BB +78E91AC992D1D58F2D08E7706D25CE375CD041F049F762B4B20FA9052DB766881540D4FF +1BD7A4FB927F0A3ECD257938BE91A220D9FA4E00201CC64A1E9816E9D71E95931A5D018F +0AF2877F2737A7749BDF3C90A1694FB81EA9C970629EDEDB5EBF19A60EDA5D7419F3EC1C +A51FF1544B23800B0DDE96AD4E5E660AB20AA419182AC33ECE2A48675FB2D74770AAFDBD +6C300C6360B9B5FF14B7022BE140C05133BD0D848A605491C156D08EA88FD0C4D2334200 +B8437E6088DB32493099469000426A3CDCC627757C9DF0BFA4E9E0CD5D0C8F3E921B1E41 +48CB6D876F445CA4CB9FD7E7FFD4032B2A97EFB025B182A88CA72212186417A5C373B5A4 +3357E58EEAB3FD609C5DFDE96D4BA104C74D69AC17E20058D0B4E875A53F547DEACEBE20 +CF74242301FA39FA6FE6B0C22C5FBEF3DAE3B2727949C20CB8A1CA7A70C7A09E0BF76794 +BD67F51F3D3A1C2005E4DAA6CA87768747DB8A7ED1334F03D3C3EEBD796AF804DB774DBB +403B4B0F6820033CBC99BDDDBCCBBAF0FE7C56959608DA53BF83A56606CD524D3A80D591 +AEEA4658F0E252308551371D192F88F5D8D58D2B898C494FB23463837B8249B5EA5B1DA3 +12A1CCFDF4234C772102A6F0405227A48F6B216BEE7520409C77C77B8F962977F9DEC1FE +098EBC19A77E3B155DF2514D4E8087E0CE8D53B272735F463871AB02BEA13B9E402C2239 +73D2B968E55031BF9A929B6468599889CFC84ACC422439464277D86FC347D3681EF42838 +08CE24709A9A3ADF4621805A61E3AE1252051A00A8DE2ECE5DB8D6D415F2648E7FDF4219 +4F8A063187F64980D3216EA297178A6F87395F40DDF9DEC4D649D74736AEAFBA82E7D0C9 +05D44A8E2F02D356741C23DC37F482F54CE53DE8800BDDBCD170B8F089339C7CAFF13A4E +2D4C4EE33BAF718DAF51BDDA347FD8760F3297CC169112DFAFC9871CE42FF8C29D7A2168 +0C6E23A2FD776240694B44696F69D11454646066BD4B6ED7BF4CF3550BF0F32FCD0ED0BC +CE20286B8CB1645C308B74D0EF5CFF8927E1F2FAB0366BE55CD069AA7676E4592FD42342 +617A186D3C144D173DDF6E01F5E5E5A67A9648144BBD646BD3D76BE1AF70EEFBEF0361A0 +4BEFEB59E94AA5CE2400907C9FADCFC3633ABB62F24B0980093FEB72977CC3E44AEA7007 +B4721D8B35BA81A01C600FDFC070A29337FDD56DCBA7EF9DF7364E0230500F9B8A075625 +7B12FAA98EF15E011D6A6D02C84655D15AE62181FA4D0CE38A6FD6B2DE4F57B0B963095C +95536BD7A53D0FB7C1167F251A9C43DE263D68FAD27C6C10ADFB6D02BD1339CEE7DD6EC2 +FAA687A55AC07E279CCDD84F46A6DEEBBB380B1DE2897DC279C784A9E352683352B059B6 +15990972B53695F73097EE77081F23E15DA3B489A9B088C2D7C76B89948F31D68C3F3FC5 +0243D545C56B62CFBF55E1102D9C761E8A7B0F9A547F9B0935CD78E32AFCE9A451C2F455 +DF2DF4117955D9C9B30619FD8A9EF23827E70FF05B55511185288C06668B65BF67CD8C77 +CE1363B83499E455CDF30270842A22F23D101F7CE773BD709D2E9172B169E25C2AF2B64F +93DABC5C18CF61B30DE7ACF3B7D746EC1B725B90B767D24DB244DC37A42861250A52A287 +F2B7062AC268559A2C231F3A93E510527BDBC3DFC742B457D774C6FC8B023C02E783F2CB +C50C4D37DD81433BAE0A8A9CFA280E7008C47CD75E1A77242B5C1ADCAF70E3C0F870C126 +197091879369A7B31FEB8086E1733E377DF5AD77358D296D3C1CB2EB54B7DB9C8E5AB4E1 +005A775EFA44328FD755D84A064876CAA2E1016DA7DCC961F2101A8FCB699B73A23CB866 +51E728C07CB9EFF654EC83A5DAF21DCF2F777535680C32E4A88AA2D7D65F166B430CFE51 +9F252F51640D7443D75CCD2F5E8494D1210B3F5BEC029002C754BF6B506B5715601F5134 +B6D95060BAC8F6CFA2249FE4B5DA5B098873CCD2C5A6E983F6C62C3C0A9274899858AE7B +5364B4434187B91EFB705FAB6372E3A003D5361138EA6AC70C048E7E05E2F319AA81DE1A +8D1836CD2B049800B991CFEADF399960C02EAFA33CA1D987B161234EF3A67DC53B6FE467 +857D5897446EC2D4C5FE183320F28B74EF3900815A540EB68C325F038A564A23AE235D12 +A475030624FBEAB5A8A536D0011C89AD8557AA5307A5DD4E46AD91FA15B8D6A297DE7717 +0BC90F8C526B6B9496F1D4C83491DD2FDE4CCE06420D943C5104B0C56DC184D8293D9305 +9AD7C5F6251F7AE7C19BD13AC98FCCF587FA9A223082B43F04267535CBAF822F0DF7A642 +7370794C4CE3723238828BC3459A01D8B363A6B9342CB523A13CE1139525AF0C372F8AA9 +98A3E2962BF6728F815D33AA537B8E27ED9174ED4422ECA87BD9E0EFA86566C4314BCFCC +324D5FB4105E9A965CD258FB0A2B970FE0A21F951F3C86EDC5543B067E2CE337CDC04E30 +EE665A3725A4110E845D9025978D445DE6284A55197735A5C018D99CAAFE6597F3D58D37 +68EEAE6F5428AB3B23B5F2F9E8EFF5D6DDF1B4BEDC6D245E63F2E5DC0911E8CA2A9DB100 +CCC4EB9C54BEB0EEBB2E1027BFBD041DD39B27C151EA50EFCDA46F4273F74C85AA88B1A6 +7BA9A98C7C6D7C406D8B3F7892565B8856C77668B86A0BA9BF743C5884FB94CB729403E9 +28EA9C8ADB060911FC0E3DCB9B828FDC489FBC1F15FC2D75807EE98AFF5D841D88303A7E +4CB6DAEC1872D384214EC0E3039478DF79CBB7C12202F9F56F3206FE61B04AECBE1D7757 +0CB8A43D3E145B0ADA7CE219CBC99952BF54D734673632B68AEE6CDA8BA19BF7937100A5 +FA294B86F7439FB59E367CEED44FEA1F4CC2FBA570AC2C32FA6D9F67474BCA9318A84A31 +107CA7AE187454434340DB2F3A0B2B41E552EE49E828C20266B88BD04DBE61AC6FF59A8A +D065A704C18C315CE79A72B061A94558964300564DE5B41B0BA3A0493851A355ACB34BCE +7FA00DCDF05F3BB733C9C79BE3F83D6103171A648F81BB138B4996B606A7A8A997761548 +08F89BCC7C81BB14F916F8AECD873406778E51BB93E56C25DFEC6C3778AAD6B537E6F488 +D29898E17B5D38BE14ED70D79A62B9282DDF229114C0BF9830F2E18A4717C45BF1B29A76 +31B60D13A283C7F92EC4EA3D98D2331270030A14BF9A8E07D87E66BC034F830DEFFBB5D9 +9E95293C70571BBC4B65E1AA13DDC945815FA79746024F5751F8FFE718D97B8AF465BA54 +598EAD21B323C3CE47AF7BCBA58BCCCFFFA0FD2B463C85DE8D02378C86BA7D3F44C54165 +E00E64FDF7228570A6F94C2A1F8CC5D947A470552302D6B3850EF092D6923FFD39E01F7A +B0ACC7B6467877CC301A03136B93A57AC0949D62D3F3E63DFBAF695767877516DFA1CBAC +F68BED7E2AC83C1612F234CB12A368CEE9657C6519908C7B046494842013EF81A4986D38 +58EAAC69D84FF32CC5CCAE2E438DE88A426365EEE0FE9745DB5B7D494C3ADEE8C6C31EAC +CAEEFC174DE952E2D668BD28D621DF9C81BA0355E943BA3ADFF04721B586C659494D5A36 +985AF4AA408939371F448293A0C04CBE72C558E4DE12B36F823445A2267806836D265BC0 +8B279386DF1579512252A9CC6F69D83959FD3F1FC6057DBF5F28C644AD4862ADBF133C2D +5779D96F1EB234FE09E0FFC62EDE6D295F19F52A9A6124197CC250EBF77DECDD5F8B024A +D635E941AC0CB5CA59F6278FE2AE87F7A005A5A9FBDE7609B4DB903112DAB7B612969DF3 +F99F3D34D95467DCBA57E6755BC80C4D18EF9F440A2562DDED104A80D075F8D0C308B10C +E31B777B438DF32A77433152571170DD44AF096981632062E3F525ECB3697F3EDD316E15 +2E502A9B8B351710611DDB75B710D6CA9801ADFB57EEBE007527611D47C181C3BA7BADC3 +1210B9FAEF3608350D905791F025960862B0B06B4BFCCE7FD92EDA6D9B2FE67206ED53AD +E69BE630442EAB6BD2977E3BBFF487CB15A7127B40BFA161D8BA602AE211C8E3FCE684C0 +3E4B7E8148C2F61DD65E1D07355B37E62A6BFC70656B4C32FCDC5926EFE37AED5253F67F +DF9A556956D96848B81A6E11D005984DC36E99F1874803398FA37966B1A37B8282BF9093 +65A1B89C1E1CC37B02254B75C75D77A39F9D1DBFE7B79F70AD0DD6038D824A7DB8DBBD79 +B6A5302D5859D5925B79A210210103791C4212F579EE900CB3FAF002DB06E0ED6D5E74CB +71ED20AD85A257F1244C79A2B6E703DADBFFBFFD414C1EF6C7A7CC4B12F72811C0F0DFEA +A4DBCF715812A3E827C06AF347EE1D72F9FBE9BE3D061DB13CE123C71C8341C2F56762A4 +FD0C1CCCEF591D01E7608B097621C45DBCFA96348DA2F80839F0EB6026AF7C14E73E8506 +FC9C1F68C88CBEE385FC280F18D7817A8606FF3FDD506FABBCC72662B0DF81EE90727ED5 +90306DFE6119A9CBC84172C3D434DDE35039F91591837F903585245D0131DADCB710309C +596B7A8CF8839B2C347C2493234386F988A7066BE6B26F9EC504868915D71E1EB5E9AD4C +F2C5F71E761B50FCEB823CAD364F3E5F3B1D10BA4916D915ED0040A920C9C9ECF344E685 +2B805F4B1FC9062625BA815ABECC0EE80D708D0BD141681233E5A483FB2DE7DF9B13237B +649715BACEAB3F4BF6C6403F8460D190C77E4DAEF62F437361F6B9DA9B4787A68DEC88D4 +556111ACAB7C7BB5F2F1933291DF83425C10895A2B47330B661DDFA456F130D91EEE2A4E +F9AE28D45DCB80DB7322DD6D7E394D475AEE95D0DAC575AE569BF9D26CBA1CFEC9DF25CA +A1A701F60B297064A17CD878E101FD6A6F981905E50CD52A807B466465F0526BD502F249 +B8C4408C130D017E6238B5B5BFBFBA518BBF414E11E2D25926362F4EC5E83E6C26B19C04 +D68C4D6D891B10773EF156166D9CABB85F08A1C130D9D35351CC9E7E739460EAB51F3F8E +A011A2CB3354F759E9EB297219157F02BED05B78BCD8C73E3881C835A7D986A3877815FA +5ADB7713819D931FD05C53FC0C584C45763B6725094485EE3C48E246A1E8968C6DA8979A +2D12CF4A97A8822BA5A066F62333C313694562FBBD8ED26D32E8D09426D0AFE33BFF61CE +23F03ADFE9FFF17EC5063381102289356B1696475310DB04806487792F7EF42CCDB4B8F9 +9DE168D16AA56321F29B09EAEDAA9727CDE7DBBEB62F33EC6FF1E9A74696A7F4B15A2684 +968D5CF34F65E88601368BEA29104246000EF93B64098CBB9F26DB4EA1791C48E245109D +23F39C97F87BE05A31B4AEB6B7A8E49A4648F8A6AA3EB1B80E2A0014CC18A59B43441A81 +D78794CC162D367AC2E22C4985C0EC45B9E29F1D00EFCB898807DF65A3373208127922EE +E16DB24D335DA01050CED1BE9470624CCBBD978063F6C538F90CED1FF48A83E404FE5DD9 +2DC2DEDB2324409E78583E5C7874A9661480386FDC2FD62329D5BB33AE4B5ADE5FCB9BCD +B016857AE69032C019ACC0D16E07C92B252C2AD5E2AB2BC9A1BC074EB697D7842AC5F61F +6832A8942C6BB35E3802123DDF726304D74F10FE22E386C2AEEE158BEC56DBDD264A2321 +1A3D0B53183DB2F74A306D00758DF51ECAE68DD8944FAC719EF56190017CE10DA46066D8 +AA27F9D6B8BE4911E2FE16D77303A58EA4C184BA139F7D39C4B1BE8C72B8104D1FF671BB +DFB1C1F8E518CAD156D4ABB057B622287CEAEEB574F2C202462FE2575EA7D8CD820FB4C4 +B87F022D732D07DD009845BA831A6E2A248D5ADF9C179276905A494DD35E4F7E581141BF +AC76849B0F38B5A726049BFC2196C38B6EF6F7A0D38730CF3CF850A689553B7595070858 +97211A03A40B37BFB57363CCA5CDFB04E01759813DF0B67A693FADFD5692DBCBC543DC30 +65192915E654112AF3676DC58854D602C427315FDB2E0624D826BB60B5EBFB4CB190299F +930D0385629EAF0C0EB37F4C01C5C770BF1F0F825A2A4B6FE50D2DB566D5B7A819FAD0A0 +0E4A7E8686E9FA936C0315622C95735E251FAB0407814B0F2F848860B942A413C7F43239 +C413EFFB4B01C1CF1BB9AD882DF6A3B64B5B7C7F0EB4E707DC5012133AB2493E7C3A88DB +5D0A51394FC7D6E66ED529D16686537DE3FB1EA7116363C4F5945B344FDF031FDDECDACF +34F2458908AE0F62E2D200A9B147C1FBC1877FB41DF6979AFA02071312BEE01A786E5EE1 +FF1B4462913540CDB34B783D104BE4071888AAB52177898F5537712D8DA1B09BAA0F094E +8174BD25333D3043CEC70925961865785A6F81359B7A580D60134A293C8DF73F9896BD62 +809715A8C846915E7E636CEFD18125CDFF15E380A8901B0BD2B7CDFB80916D4839849795 +A7231BDBBFB9858A7834BAC1FF8B8365D9602985E8D8EDF33D04AF77E24525460278EF7F +03AFD42AEC3F4201F8C56C2F4885F0CE693EA5BF4F62A8CD61F3A7827A1C40FA52228ABC +8D19EE1089AB3E80336EF6070B9EB31781EB9C6F6E3BF3BAB61443BFB63C08BBADE7E842 +67C6A44128F33D7843DEBBA3BA7E723E91922C437D24A329E72547DE8ADE2C9676C2A078 +A12CAAEAE690A31FA18076FA77BCFD1EFB5762ACE44FDB97FB5219DCF9F542F87A959EA2 +F118162323B46DA8A0C116269D8301850EA28761CC0E5ED06ED48968EBBBACB891CE73FA +52B7C262C73DAE25843C00923D04893302DC2EA0EEC7A2CBBFD949A3B4135F5AEF66411D +CDE7856F7FDAA0E630C3BBD42305182E3475589B41461360EE1B72298D97825C499D9F49 +653AD3EACEDB5F9790BECB554A643AF9F1CD3455DD51E79FB0A6221C4FAF81BD822A1BE1 +AB8F8B18E4141787961546744132ECC7F19EB3E81863CB6B3FAB60D3963D6E6F106A2558 +589B07BA69CD18152F8A8B884BB24FF318A071CDC695F6D8DFF7D04E16F0AFE7BF2F03CE +F6977E0CA4B46C24E22FA22C0B9DA11EDE76B5B511B1DDB6CDE7C314EC86E2B79E1C4FE5 +357797A5EA3373FB14A212440F6CB0821AF449122D94828CC38E44AD6C7C7FA78B932192 +55ACF779D9634B75999314B31F79003E030054010133046C6CA9AF0FF33AEB9E7C63553F +F34203EEBF0E3F104453C1430A3642E79A4F5D708551C4751C9F4DF3862FA15814A10567 +69516410AA29695690A5DF3E7B407A2E5F05C8DB7AFA0132D5F43177388FCDB17B325990 +1AA479F19C138122AA2EC5674A7D41D85233345FAC3ECBEDE642BE5669128E17DDA2D86E +34088BB76C64685FF98F01D48175847E0F49E2404E9C5E9F9073F3796DC575468B53F9F7 +39F93EA3FDF18DAC9489FFBB9B18F150CED84E6A4241580023C622129B1A91A8079CA92B +1A8B26B955986833D3144BB4EA25866AD4B499247D44EF273ACB2F1637F195AE7E89541F +C6B70C8064F12B696A0C9BB09DED5F41E19914918F7F4834428A01350DDAFF763611C173 +12EB28618542E8EBF479BBF5B120E02ECCF7D3F9638979F0602194DC2512C682FC947B4C +CD5BE48F0CD4BAF3710BB42195ADC7DA9EAEC09E124D49E7CBAF579616DFAB94961998E1 +4EFD0128982A15580D1A2ACAFC740EAD92FAC43E7FEFB551EB9322A8EA302B573A6C4B90 +87041EEE1D7B60CF1E50A88F59EB46F1DE9F9760F21B8EB325E90B536AD68829FB965237 +5097A06AAC312372A7D3EA7134A53C253505997B4FB2BC25EC2ABC8BAFAEE96BEB6EE940 +A76AEDF4F00EDAE82434B3D5C8B854BFF71EC073A0DE2D98FDA384E4DDB1D84704BAB88E +DF057C84DE21A1F7C4FA509F1E22C7B8FF788DA95A7215DEE81784B7F47643CB85D08DAF +425E251EB72FE482CAB41D49389B323E66D27863D719D78C676EC91981B0E516C21942E4 +66804EED7E214B4EED83A1831D925019709A3EB1B2CE62491339DEA3A3890107CC5C486E +F7A861D7B023B2835A87F62008BCB96748B6037BE07D54A22AA4206C85BF24208016BFDF +EC4E68D8CA14CCFEC2CE496819159C153610C4521D312B8538FD3AEEC5FEB1021FE9595F +767ABEE99B952F0AF794FC4D7FB0BA7B8CD73B543ADF833989ECA557EF2FE9E80C786180 +FE2B6249F45440E94C98C00ED7B95EF5AED26A9058826EEFE0377F4CF786450929E290E1 +D89E70679A7BA87CB29FCBE1A79F24A2713D182F1BF990340FD0E00012A25801BC643A9D +DA70E046D123E7E64B884B0F8024639E055D6F7FAE5CC5108B68125C02EE9EC0C41368E5 +6F869A55ED15563BADF2F88086EAD3E67E8714AC03D2A12B7E99C2947D6422E5F11B74EA +2CC153B8409A2A03C0AE3AE784AB05475F3D086EBC28089DDCF12C8D4324A8659EDB40DD +5AE08B2752D196ADBD0E540590A414A6BC6931CD78CF0D78B23080B4D5C5D86B9E4E0EC5 +3D774845DF7C74D07F242655018AAA23E64165DD462F5D2A282B5165096732D55A3946BC +C00AEFA41085AB8F2B6BD34C065DA2C9C2999903FBF17E9E7E39E874981E9A850504F7D2 +A1B69C85F532C6749BC675FC181CA05F486858C0F22BFEC83F14D4754C3C42F0AE0ADB56 +9A48214A9DBB6D163E528E4DE29157A8E7089EFF2E2AA6AC85AAAE8925CA4A019DC38668 +418C964DDD2EE6F2B92BA48E10789DEC415FA94C81CB95093F71BA384081A7A01D3C2DBB +A934E37E27B4232C8A3802CAB57BE8BC899635B620F54FA5639EA9BFAA5294E57856664B +B3B3DFBE40DFA0E09A14ED2DBE9C47CB032A86D9482D29959E21FE32CEBAB87FBEA9D283 +7044E2161D62CCCF0A3E3195F874F78AE00DAC349EFCBA46A8419CE0A7788B1A2527DE7F +1908F9C67D4C59DFA016D21F61D3F29AA54763F81F2837C5D4DB2807F3E47EDF257588E8 +64FEDBD51B1C169035F1B64D80EE209C5A2315B961D33E4957E11A2225F0E8CA0BCC1E18 +9428EF1FC4BBFF887EDF1375E2768129D8558658D78D876F455FF4F0C65F35004AFBDEC0 +F99C007905DB17D92A64B5D1A390233820D41BEA0F2B732B12BAA6777E96A94F23CCFB02 +2AB8BF09CF9EE6960FFA056EBDB46B04B8F187D05CEB9CF0BA0F796BB494D5F511010E0E +14BE33E45C807F4FD23AB76B0F0E3969010DB86834D787B8E0F92689807033BEF513DED8 +EB3EADA76AEEAADBB191518A950F227A0ACBEDEB778F43FCB3A281F7B7C35F58BB1B3814 +49E40140D8059E950413B9CD3F93240629B030023DD6233C59ECA2035392E64869AF7FD9 +4116ED71B821F0AEE5A68CD691653C2D6DAAB8AFE466D5D7F1BC3ADD65C0AF0EAAAA1486 +DEF5F16684DFD78B7A41F7816CE8A787019D9ABD2F4E4253C9229A2DF73C22DF22B93A8E +4FFC4769448A3E00CF85A939424EC3856CBA520420BB7001372D2F703C5B36CCCFCC5BC0 +1619D9DC961BDB0D9A2FB18759149632141348364E794B15E7BC79420F0711382127B262 +292FBB7F4D0B37A7627E8EC5F5FC374B98B18FF02DB2F442D8DB5ED06F90C3BBB17D05A0 +5D7D11A6A7C2E62F15E7644ADDA44F1A3CC71B61645C7497C242DED8199E31DB0A247C08 +1739BBE040E7CC7299BF09DC0CE4CC6C59BA7D1867CD3CF518ED80959FD8B26748EBFE0F +DF816836E57738FEE205BE2941BF7F155FFF82EB877B7DEE42BAAF4BF2E2057453611C33 +B2FC235D7141ACBCF65F068F2A90A86B8D19B6A0D7223024B42CD6D71C04EE865279A1D1 +6A401D2393058EB9A16020EC8E69943F631333D3C08C9892F8FA620CACC3D1A4F411FB78 +A6CC30F441BE858EB8ED7A92164C59FAE8C5C6F275C2025FC60E326FC2F7CD6EC4612DC7 +1D58EC6E363D90BFD5A93F552F7C3A6DE059A13C14CA2C15D35E1E5E10775ADC9D925185 +1ECE6C1AD5BF430846F62165FB21A393838DC98C2501D598E83EE90B31378D4D92CFE8C9 +869538BA6614A71D3F29E455DDEF8321C2AD78CC2C0A832B3D0F1C09E3B5FA99B121C283 +0200791629A4094DE00EB9AEC55670263DEF10783A699D69BF861FEA783A51937E1BB83B +D96026CD631C7CC3C7EF3BB698700B307079EF2F28F52FC05FE409E020B5E044D1766C37 +55064E5B49FA1FCC37E6D8341525F9DC92B35455711091F1229AA39B397E9ED05EEE7797 +B9A9EFB8FC162EABECFD465756E8B747A3041355178430CB089E1CA3783DE19454F97E0B +3B24813D695BA962CE2046C8F2778B0A7808D046AC0713E1A6DAD26033D153421A24E667 +AA649DA942425C45875437F703E68F68AC5F5AF9B4E087FF4AB87DA00D174E090D834BB0 +14B00764C1CAA2AD4FA2B457858F2784BCA840C7A8BC929505056E3BF3FF533D94C9CE14 +76DA773403FC3F80E1A2335699A55079B6993B0FB187499392167930A874EB1954E6DA45 +C9591EEDC1E8247F237C8657B6FAD992B9426D584E116EBAD9B9F2214A8E850F541A208C +A8792F3980B4CF5E75970884DD7583FE277F82ADC1FF35E5F3FB216AB68C353B25F34C0C +F2C4A60B1E51EE88F7BA84FB1C23601FA2270049E573C05218BEEFD56DF0A648665DB6B7 +81C3B0B503202DC005B8F2F00430288086BC3B4D0625BA2966630F71DC0483FC43DC4AD4 +AFBEFCE65FB61CE89F07FF29B9A9007700503043B24CD9DD8BF9E4714CA99B9504BD7FBF +DAF7ADBAD4168CBEDD5EC802F2DFE773585C5162E564CF1C39BD04CDAA50C2032956EE47 +948EE6628F9EC006711877235813960C9926CBF2372B9329C3CCE4F4190FACCF33B25BE9 +BB4DDEB7E91E8D8ED843DF6F0352E51AE0670C4E0A91E78664D5F88F77F6B9EFFD25071A +F9BF35C2D572275E5FBC2461277DCB0DCE505C6DCDF913CE7A99DA563AC06E1C4B07D7BB +0A24BA8CDFEDD3C16107DA2195FF9677EB104C08C085D6364BCB745BDE0D313D93E318CD +F7929B299185C098642464F491E64EF9A2DC1DBC34153495AD62F886309CC6B6571D6177 +91D94AD5A337912569067DFA1311EA41D5455C24D3B60ED3E698E10978C10FFB9A7C2137 +92A6FC31939290392D8ACD3253593287DFFC13CC9D80870AF32A2B82AD21C49560FABC56 +48FE43EE74D71F0E6D8008100FDC812029C4F1FA3ABE01A4EE9D99A2FA574F93BBC6F17C +7301329B2363DF36FA029621D478A795F9D564EE356CEF0A1E60ED1DBF5FA08590D677D0 +9A1FFF7CF8D657D3D1CF2915BD56B44BCF420FF4A523162CA1791A56287BE773D74F7246 +F52C0D1E22AEA987241202665D0F5EA6391ABF31F16A5BE4353FFAAC2408A0680A33752C +D527145AE349CD781E339C8A9D87E5C0B1312F5B3C150FAFB4588ACC7D6357A5A3B4510A +556A7FAD44643F04BC6D42A23E83640091DC70FBE51B57A7E0EF1E2D6112624AA21136AA +A1B1C6DBC1D1515491F0EE3F9C4338B58E3D0603E1C12A0588118F9261139CE44B5183C2 +AEC863C7D7CAC0DD272FC5142FDD80FC668A6CE709CD7F297DEA655A767CB8A088474BDF +5EC4263121C7B3F154D8396B2470FF226A397257FE5D24EFBD3AE08CEB5CFE9194DC4C6C +147F24D3B36830FAB0AAF03DA1442C1E5E77951538CC9A022370A8C3E39273E4B8E3FB8D +28EE116FEB770A6F223CFFD7925C64CEDB8A7D66212CB443B2A0207EDF102672ADDF2084 +5C2D36FF281B33BD3408CF628D7637F1E92A5D2168DBB183BDF98D99E5A68D9995AE6123 +3675A1AE7BDBD80642E27D6271437F24D28884C90351E819D9785E556334E20EEAFCCDE9 +2929DF0BAC01FF12B56C2B4EED3E554F3ABC0096BC7E5D9409C923E9ABE6032B20784815 +DE1C1663D6EC86D7476A0E9698CD3B201F5F9CBFFBE604C4C2E823045473B0381B1968ED +20DC0D0EC89487B4FFF6F3F83A3D68EE78868FE5262235C3609C6756BE484D87923175F4 +80A084A25B5776FF76742A70F7A60D8B76C3E13409A38A258E3E334F66FEE4567A68BF1C +8CEC4A80CFA0361BF63B7A0D5A0819C85E1A9EC223C0569857D730688E6D177E4BEB8E31 +F873625E39573842035C5C6D66D923654A8FAD9421E1026987A9C825505DB5382184EFD3 +6C84BDA96B464796D72571760CADB46199643060A0552D8DF95A9E6C30787CBD2F57B0FA +D1FA43FBB1E488FBDAE8273BA4F191398652EC86743D32FD5708673AD1D39F62425934FC +AC949F047C873CB94E4A3CCE44A458EAF26953DE54F645CA7B35553204A0F5C7A32E92E5 +27785DE73A3E2A3A3FCB54EA4E395E73C5C89F64B77EE218F935AA4C42106A33C78D03A6 +90813236AEE3E50C2C44323B83401444174174DE4895D090CDB64274B70F557204C772E2 +D1C47C79C1EC238D5B345F7D9CBF27C6B98C5163E6D1D93F23F311DFD594658B903480F9 +A475D3A3D9BF909D042CD76AF8D574D71BA12EB33259C745D3FF5403E579F794EC95CA20 +9959A9CDF439138715101F9FFB3E867A2FEFC41EEE21AC816B7E48F340634714E98CFB91 +E97CDEC4C25CFF567676460102255E8BF37C8B4BFA821EF0165779094CC8ADEBE5778333 +9B9F4DC83DE0360DC52628543D41E0FC9EF2EA434DB9520C2CF5E74863D9BA197F8E7A97 +912643D24CD024E6468A188E0D1E903C48B9A996ECF5D9B64A64E026046E90F5C92CE2F1 +260BC6D4F298DA5A10B3620C4BEBB5C721B830ECC1DC8CDB86AAD6C20C9EB56DE6520D0E +29B6C3EB14A93D43B951CC2C690B277B426B84E4BBB4E1719278150A03C450A9FB44F6E9 +16DFC8986441969A50F06A4483EA651839C31E89A9E4644E96094DE5320CE79DA5499528 +AFDF9C150A4CB53A4EF9BAB6989BA5D0703A4F2F5D4CBC95719C0518DED3474F875DE58A +3A2C369EDF2BD851E5F2E0BCCD47A0452C8751E45DE47CC2C340EF4AB6F4F885B0C2C21C +8E8B252249C5B45EFA5B3E8A27CB39556A262F03A04639280ED71F8D01E12E4FF9D37C3D +3DF6164A4C300E495CEF60F368C4F5277FDC5B27E369483237780072A6709BB6B1E32F33 +53AEDF5A0B1A30EEEFFAEC01A0E9630E5A50BABC081DCF71997F181CC310023AED5BA74E +769DA4D3FA84951BA80EA57C39C805F1C4B42C7673403CDE1573E1641B76F1AE22E57954 +48B4C46AB50E3EA8B82FA89C9BEF737337168E18498C3653AC2BA51C757A15A8BE8B1675 +FCB325B5130E13C36A66E3056C8A0157DB84F7D6636EB06B83FE198579DF5135C77839D9 +548214B53BD51BFC1EBB8CF2E4B1ED77EAF56E953221F95D30D6F16DCF13A57664DB4DB2 +B45DBB6410A9963DEE6496DCADA35B5AEED478EC9297FCB64555373F4ABE73D92B97CDFC +0D83E4D2E80C6433533451BA99E9B2777492AB98DCB69C2AB9737E5A075FA29CB29307BD +315A4A67E7A5519B55CD6DC3E241AA0A067B0FFD337D72FB0B5B290982EE91CAC2504A02 +71315319A641ED197E14017EBCFF2B124E1D449C5A692BBD0E7486686DBEE2F15552583A +A52385CC9064ECC3873A1530112161BDE2008B484BB616459466E66985829F8415D83DB3 +4736B604DEB0E730A3ABA6D04ADE6666E303C40BA9B35FA5C753743239361A8AD23B80CD +AEEC9B8BF6CFE55D9EFAABE474D9BE5F06255EB903315DCD4E2D3469D08AE17F2813D7ED +F8B3B5D004347932D9B38955E27B786CCF0724784E0D545588B51460D9C2572C6E4C4B4F +9A01217FB8F2FBD0757BDC1882292CA04C24E7828D9A6F64B151A4EF2507C3D3EEB98F76 +77D041A5DCBED1BDB61B43034F4F6F5807953BE78631376E6D3AC14411587526E7DD2E68 +9D6241942A0C990123F2FB111F926A68B809DC5CA2CDED30262E71CFA275767F76D5514D +9B7A435A07670F011DDDDD31D8B944151A6A47C6EAF3AE44881252A078F261814A06492F +628BC815F32E0B889863A15409164250C9ECBFAE7A749AACEA6AAA3FBF9BBF40722DAE91 +167BFB833791D3426DF713F829F60F3F9638E1559B82C3704E048AC9879E4AF5C70C9641 +BBA5C04816B4EA6CDA7BE2DC728364587A5E7FFEB8DA7BDBFCB842FCEAF179244EC8B247 +7AB7337897FC0946AE494BC487510CA123CBFAB3B7EDCEE9DA82C37D55AAB651B887E6F0 +5A71F2331B1FF033A1D553186C786C224B1CA80D6693F4F6A948E338BE6CC540E86FEFED +280166B01B5B8F9B278A91E1BC632C3B06A4BC08530D8F1C89A6928E91B8E7C393C9AE2F +91F826E8AA3E11C72CBB0A552EA0261D5912A191127D351B12371E985C6DB66834869EBD +746F758FB0140C248852AECB41CC4972B6CEA24800F2528CFA99E667FD10EE57CF671099 +527AA11667321AE9277E4293811190986CEEFE93FB7C4A1F1A5884BD786B13F8B73A1A46 +19257501BEBE4E2A6BC3DF7BE7451D9364F00EF318111A8E4FC065022AF0EC88040267E7 +BA268C6FEFBA8AFB91120EFE066B8B23E40A0A0F209D3097881CC2B7141BDAF8FF7C5964 +4C029DDA226401B9B98C6A53AF6A93B39F6E3673A3054EEA3CF8CAFADAE0805018CFA969 +7E879B9C31521B340B288FC8910E5B6E061A027A4C69DA1BF038999D693108AFB70D0DBA +A90F3B2C073FE4251064E1FC887AD3708256487DA8EEE60795CF11DEAABF0CCD9CE8E372 +AD4CC8C8DC413B9D2019440173F6F83CC66ECA28C8029C1AB834DF7BF2AF0E0D86C66BA2 +6EF90A1761FBADC03C1FE598D954339A2970A5C9EC56236D9183E6155A511A272D005087 +14F8749B03A5A2B9DE2886B539F1A377FAB65ED3437D55988512B1B1C638015B0ECE68C5 +3AEC61020E34BD8E6AD7659399F0E1D8D23F5EE282BC764249B664D75FAFE67CB5A9DA4F +2094ECB30CB6B68D52AA665BBA751B446118C74148DF979A0FF173364D79202606AC2756 +8D41821B1E4D4175411CD766FCA1C25093E6CE9A37C2048755DB82D7448526B59766288C +9225108E8E86261B57C521991CDC273C0BD25EF4434670C80AF8DB7300F26A9701537DD3 +8FAD0BB2E9EB8F0FC9F2C8629BA97AA1980C39E9BE5740501BD4D57D71235C84C3EF6B4D +CA3D1EFCDF79B8D4EB7C29EC5AB15EC38B2104745E45235A1F37F19E921CB2213F1A91C1 +C392817E7D3AD3A6ED1EC8EE290CF5B1CFA2BF21DF8B9069F4496B7E80E7E96673B77EF3 +AD7B2FD6653510AB77BBF1AC8A07DDE48A8C2AD11EAF2CA95540A164C1B0834106FCED12 +E179477B185DF43148633CE3AF60539493D0C88173C0E63CB5A44790FE41C211966EE03D +424F492C2C87C04F0C28CAFEBEBEA7D11AC959E0C8A88776B4372E356C913943BFC88983 +1C8F95A399DFD02779301D05205EBB921C1F52AA522746CA533AC829EBF7235FBCB0AD82 +69A64B2C68748ED4843FB583151429A1E9537CB40960FFE9C9340CC11BEE00EC7005641E +964F4B0183C49262F3202EB6525EEC66CB68B27185B7DBE343FBFE8BBB34393DA1FBE929 +50702ABD341F45EEAF0EE66C848EAC04CFC854FC058A9418834B4F18E6D861AB31DC1C42 +DFA8D939921067BFF8815B708537A120CDB13E775802C57A0D0CCBC6ECD4CA0DDAD91F01 +97DDD9118990BD71A1CB241B88DDE7EA4F13236CBCD7CA64FC858CBF1E5A38C98C19E3AE +AC0B7B256BA7E15F0E49C84A437DF190A81D0E179B2AFD03A427F2F9AD83DD2A4EA893B5 +BCDA0F09C419FF0D0EE4A811886E2784800865CC8177D4E80FA005C014AD9B124D3D060B +526237FCAF98F23D1F7195F72CDE4E72B87FC4A872FA95441483FEC58EDE0C8B97909B95 +D5FF189C0D49053B187E0A1A8AB85DBB6D765EC78742E334378EDAD7F2FA77E9CED5F652 +295145D463126659E0F6BA982BDC32363FCEC79AAD13248135E6A28222BE0127D807306D +C94C817B649AC020B8B3DDB18CC5B05B83014A10DB5FB9AE6BE4A078FF056EF661B2F4BD +B422CD7E80AE9B6835330AFF67FF1024136EF097F4DD5344D37FD7562802B2A1713431D6 +FC1EFFEB21A02267D7F6B2552C97FBCD4BDE4214DB01C1376F07928CABFB1106B02FD2BA +BDC8C71D0278DCB64375613479FBD3D7D893D279A3FBE92BC92BD99B6FEF817344AC2DD6 +EEF172D3BB609E961180734E1B4C4F4B2D704BA4D1D3103BA4F62DAAD46DF7136070EB14 +549FE8C727CAF060D877D22E21F474F9627507EB1FE2A28534789407DB20FD6D6D9F5CB0 +7CCD392440EDA0E18E1A5EAA7B2C8BEB249A627EEA58DCA375DAE4EA816AEE7BE8BD92AC +AE63C97BA1DF13081EE64198B83926153C8AD6F1C86FA73986BFAA5F0EF5091A4B591BB3 +32ED4334E6D67A0288D390261E88FA39574FEB6F7B19B808DC87426BF13BFE2F76ED7103 +87A5283D27CEF752B20D831D8494A2E35DE7F68856AFB67B6EDC883C45840C6E83F1E9D9 +4E4351D50BB9A03B0F0B0527CCEED0081C96A029EF47F68A1BFB0A5DC673A0C8254216CB +D84693230437E107267B9244E2287BC6CBCDF73B24DB5B947D5738568471FA1FFAC537B2 +BF13C99D56230D49E12AAFDF51B03265A9A14529147FDE45C234282644C9BAD0C6892861 +029C9F27E4AE13F8278E135E89E81A7E552B11DCAD49507502B47B1580A6222672EE9C3D +A05B74A4719A849179B6C93BECD1F18FDC9CDB1EA52ADF96D29409B9B9DD63861A2C74F5 +1A99843FD141AC60A49FA6A134FF4C4328AA9D95BCE4B89B4BE4CFDC1DF3603DDB0D7DCD +E1A3FEC7059299A216BF88469B5C9B16C20680B14D414902E8A7D80E5429AA24D94EFDCF +500C1F1ED0F3853E2715598355B9440AFB9A8D06F6C038EBE0574B24E3A168E93833F462 +B24FA106DD40C967878248B2E1D58CB8E4646DE1F2B5BCF7FC02B4BC7DF7593737F583AF +03264E5C35FBF1227DEF2C4F6889C2F77C3B84638CB682645D0F2E99E0C4EF9ACEBB11CF +0F658F7D3163C488C6E642B5B03C1E40F69BC2293497374FB157F42111ED5B96E04040D1 +8C0020820B37A22DA38F4E21A64FFC24131CCA0F575529157E9A59EC6546004241A8F51E +9E85066AB22B72FA003CC868F965DFC34A2A0055FF86443CD3ABD3EDC30E9196C20629B2 +AF3A1A0C42C88C20449F889A39BDE45EEA0551AA0BF0E9641D7D1FE0F3C286C7EE34800C +20A72C954EEE657FB36E10ACDC18D165C8DEFEC48D154FBA121CF1066508A075A669612D +26B9309F2CD33B2109AE9E6B1EBD4391F7B66F625367766F8CF0B8BC2D201124CFD9920C +B61F71C4781B459ED271EED5937FBA4359FE1DDA7F3907ADD7C15ED021E7735985E6AA8E +F21011A13E5CED0B69877C636D293BB99AE7B9457E8C4B84C4EC695C5944622B5F47DEB5 +1F3D653C7ED73B53D16B504E761B8C105CBA84E45B408B415045310CFE8D693AAC924ED6 +C61A12C7B0CED04E630D8A04F8838F286E646960120FE35D0D13F9E273DB647A999F1580 +C1448CDA80B9489BB8E5E4507A7A5B5329A2E962EED597E4B7C4E6C72740EEB351A3364D +0B0689BC2658395E2B69A8FF0600EC50868404BAF6792A59983C6E372DDBEEA9953870AD +319849F018362B016EC38C0B7F947402449352CCCDE055068417434416F0475EC82A5441 +987A472F59AD152C56FE81F1501E88D0BA843083736F783C366CB18C8A787FCB60E6F8C4 +3B56BD458D9A42FBFFBE128C928DB06C7BF8F2C0FE209B25DBE0F28C1CBC8328C8E868E1 +F1DA76549F34B6FEC13E1400B2F9A66E00D89CAA99B2DDD6A0BFC73C09C7D774CC05629A +E23AF62DD1E58D3843EAE55452281A0DC2B31CFCE75A7FEAAB90041602CA5293EA58F8ED +C18635ED0234B9799A12388C2AA469FEE8CFE1B112F7BE610990CD51BB13D955CD02D571 +323F565D7BC240FE71E3A3A1B92BB9A1C7EC2EC6406F06AE7C0D14262319D389A7CD8D34 +D41313DE9B2336963A5EC892A8051BEEBED24ADCB1F0BBDE77C4E3AED1D777C0EF2F1AAB +DEE62B1967964C98CA08561EA234879DFB0F50BA067E1462CB63544786D56935ADCE3E7B +399B1B3D0098DC19E4EFC04922CCC28609390A7B163D66853C2C8FF94591CD1DF499DB82 +F0F6FB7FB6D3571735528F544C16786CFCC7FA10D28FFBDB6C455AF2A6E1F6BECC080B6B +EFAEA5D51607A260620EDD1DC6E8AAB588BFCAD39A98E028BD26DBCCB149D818E0B91BF0 +8AFB55C618FDEDC15ED7055521BC90689E61965FBF22172F584827852B6DCD8FD466953F +D16A806E20C5C96064F28BAC94F3A7818B18EAAD9BBDFA0FC302E663B989D97A76E925C1 +CD1307E43C97F88DD731AC971B862E99633A531788BDAA4847A1FD124660B00000007168 +72191B3F124402B990F3C379862AE823A3646762EF68A69D3AA91C56F50B10807C915447 +38AB8EB6C01618880F72A6C2DA6764158320CFBEFC9F23A0C1DB0AED395C70B28C4D47F9 +7C5018499E45AE5407C03CDFA41D02E18F7AE56346D872B03CD5FBDE0D0DBF11C1FD313D +E0A7856974BCBE0EB331CE51D190BFDE4C08BE9CFF6F2A32072454EBF4DDDD1E3B9CDE7F +9ED3B2C1C5C60A12813DD88D75CFA6A9CC4583764D40C7001764B69A739EC079E7ACA5C4 +1DDAD7D15C8807719EDCB3054D9DE3DA92912F019B50B62C8C4AE9488CD7D683565B2031 +DBE9E7573595ABA60602B6023C1D4DC8370A529873DFF92DE908CFBFAEE97B0273CE36AE +6C931F5282CD2341DAC0D6DC59A693FF4AE740E77322F8073471F6CB3CA99E7A530F5E82 +7E4C5185E015655F784855E4989F27CFB02AEFD20C3D0E9E4C1346ED248A6EBEE2BCEB80 +1B912CE4AE5475DCD5D0516397CC74589AD3D52E70A9DC423CAB42BE428CC2DFA56E2C9B +DB4F083F8A7B3B2B9063EAB3FC255A489707792141F87A2FCE77B89AF7099DAAE3EBBE9B +3655691A5538305B664C75DF2DCFCD53C87C38D9EDF8F7DF8A808851ED31E8348C77CA4F +3AEC6C2BE721FA3CE9D54B72B414A0992AC3A9DEFCF40579F59B0E30EE3A9B599772936D +5E5B921D5693FD702A30BDECC82AE6CC10132C2B6C697326CDB3201D35C4396887B5CD1F +1909A0C3A19BA71AAE02E8639B6AD1426866196F0F9F0DEAAF8BDC53720674296BD41161 +DAA21FA4534BA100FA41161734E310C6E88B8BACC050174028F4DF483785184B30AD1BD0 +2EEE2F93A187C5F48EB3ADB9D63AA4D52D76AB07B93CDA7F12F3C7D9E58DB297D2048375 +5E5C6D1B8F9C5C07A142E0A68177BD7AB073CFB934EF14D9616B15BA2B38AB4FA4B5877D +04F5308D74D642B46352FD84B4FFF058C282D308AD2AA99270964618A04C0E522AB7A4EA +123FEC9A47F13060E534C0C58C327B063D59CF96413E176031FB21F3AF9E3BF1BA6521EB +C71336E468A8FFD6AC2EEAED7ED016D2775AD2A7432534704B399BAD93E0A1FD5C8E6FDF +E8DE157ED4FBFA62C5F0D12DFE4C519713A76D6B2D35FFAC7C0B90ABAA8BEC8D2221FA39 +5685428736398AB87F9B73F7094E02A5019A360FB5E0A2857AB2439999377C9D4B1529B8 +D8DC1EE0B68D1A5AE1BE39949A8D53F9274D51650124E4BC873C07FF0786CA64EAE168E3 +B8E0210945249FA48059080232CBCB56A910E40D14A479F193BFBBD701384407A2DC56C9 +BEE9A4F3F011F02D0AE09C3F6EE0808336C70C6BD82525858EECB6521238C717469BE58B +6865E2E9867FC248A82B44142F5E825665F6780B03015A6CD2B1592F36B7F1C03D58DCE1 +9588FC260148D0DE42196BD052136CA1BD82BBC0AAAC6ADE4500B9F374DCE51779697BFE +670245D126066964B61D59864EB636C43D6ABA70429614DB400CAC2ED06D85D3E7C3D9DB +B5E2E7EAD6031B9798EDF30772FB9CA88F52D2A56C1CBA8F95202DA92870CA6EAD0358F2 +183C791783746255B2E87EA261A1D9C4B7B9B4174D412BDC01F4AC19DA76C423992291A0 +B0B85C1F62AAC83B253D8C251DDC43D921AE994E7122F7A49EDC473B0D9B71D8801A0D43 +B589E6C1395255D3515A637670589D6BF4CB75870D2BFF2491B7DF7EF95F04C0531C3C00 +6BA3CBFE26F52EB9D041DB138FEF272218451237E60685E66390659CB98F178E3BEB8834 +6B1E49C6D9EEE0677281D460E3AA55250A0D8D37DF9DDDE21F002A70E2F9A22F0AFAED24 +80C169B2BEF14DB7E75ED43E2317948F2F5F17A8A301E5DD65D1950AFFB85A1B4A26AA89 +104519AB57E70A3F506453128E1614BF850F371F29A9CA224B2B258C9830F3046D4F1C8D +3DCA9AAAC020617CEDB6FC6E1EDC69E17812FE92EA38C97ED91987A65C72FA48C353326C +DC7BD08632C96BF3C9A7C095391BCD9335E8F254E937A77855854EF20235319423D2DBC7 +DD2435B9EF9B9CE1046B95421A98E910196E802263650E5D2087E34E384ED7FABFB6DBDD +48342333407D7163A1B1031F841AD55FDBE7C1553CF17CF057652E243CDCFC8F86D8911C +C6DA2FA6BD522ED649C52DB102498790D6D55EF2AE27790595E8D8489EFC05F505566958 +33A31087D230F6041DEB7173D2BFFF6B59E643B532C2649D4902CA7FBD79F3347ED28EDE +D5EFC41B0B6CC97F6165806BABA7930768FE8E4B8313A5C9D69BF0B029CFF51B9470A22D +98A6257A6BC6B34F11536130A980D985E24F69E0846C395DA6C35C036940E609F9677B0D +EA2B923A92626EEC8E224E2BED76CBCCF6F2DC14CF8D90BDEC80E7088CA871846C68247D +C4912B6DBAD4C97A472C1FEB6B2B460929E374B23975046E6081E210116ECB0F3680D99F +E7BC4794EA19037638DFD2ABEB7365F2A7BDFA3C7766B3FF642F0639D897A3F0772EF880 +EAC10E1BA44C207039C64D2DE51AB6F71E703F36B24F9BCD0179853B815DBAB59057E8F4 +7C74B338BF128922C8057518CB7FA34AF8F590BDB76296E4258570F5CDCE24B4F9755C88 +F4F3CFAFFA1EF7EA5052A2C7D8A823D0A1EA7740A726FDD7B1D28D17B01A0EFCD601F20E +FEFB1688FBB375573F54EA1913230461B54B64174D7C99ED8A2DD269CB60B02050A2B300 +C0E7039663C388C4670BA295EC5BFAF496DFC11816ECFB433AB94380D1982DF52B362305 +289A0EA2205C91DAD93A6428491028D50A987C5501D0FEE5509196EFD2CD36D695B71289 +E2A4A96BB065C0D9242351C6A3732E49D51B5E472F9EF2524716B7478AB7460F43267CE5 +6B2DFBEE8D34E1BA79A57B175D8B9496BA2C806C2F6CDFDEB0DCCD0D813E79E766FB8548 +9087D61E7506F04102C2DCDE9B44EF10B38443F7207B707A265E1111FC0E411F04A64524 +3465AE5AD4FEC01561DFB4C1384B8FF54A0AEBBF189822B63ED986B8197B3B1085087B01 +B9EC606AF3C1CBEF701224ACAC1BAB4DE76FE28BC7F538DF318EBB3CDA0E9FB06214F497 +BC2926399C79CCC70A464C2B58D51A52BF06A5650D21929E4C2EE5AB624F5EFA25E64B63 +2ABBC3285A79C5576ABE016283D08E19246B77166612E83B2244A1BF5A7CAE45A691AA7D +BC31377285E78F094870584C23A2216453B9F0804BBF32FFDF810A2DEE41CB2743472A57 +D050F61E285D232C6EA0C2EAC1C0FECA0E489970C7B83D6F1D64B187BCBDF29815CAFF8B +8EC2AC2705DB255240A5A435A0B0AB6F2C9451C7E14FED26DA327D432A30B672CC7E0D99 +8653AEAA0DC7FB4161E604CEF7464934795E01C7CD625A2C7C4988CCD213C19CE963C6EC +F45078DD17A158FB2F9FD1241FE5FE0C45D05AF19E5C5D5AED76D297414EBF0E95E451F8 +B61EF47D7A80B240518FD2BD42C53B96BCB17F04B850CC889859887A2EBCA1499C10D034 +D545C5101EC917FD27B1F87B4460B8D5036A7072070ADB83573796D07A4C4C5348FA845E +C31C83BAAA79D880FC9965C08621C9BB6A982CACF2E9076CC88F14F4E2B1403A980AA310 +33CC1C16B108D3C390F95E87D6DA3FB4E9AEECA82F70424F82C243D0F0DB273FEFA8F57A +CB2994DF51CCD21C45A00F60EED00CB7C2CB6D131A57AD4CC98FA2BD0313E15AB964221A +6662B6319E305F2D2255741DA5465C9602E7AA3558B98B906B4AEC3AC8CBF877E51AE0A3 +CD1423A0AFD38716B0B74C7F492412AB575D9DA05634E20D34026A1E02B58806AE95378C +8018A42F273FE95E72C6E8BC54646FDC010E807B2E78AEE753E9A223B8B014CE464AB7BC +5C6FFB19A0687C0FD300BFA19FA2E9A65FD2A4BB8B5E6967289A70EB18821A32CA0751A5 +972A6F3E3054E10972F59A9DCDEFC5DB1E9FDD87003B98228BDDC733DF066CA5490A902F +2930EA9C937B586CDBD433532E6230F87773FFB354BDEEB778ACC289F3015C5158828790 +BD620956700DBDD6C2A9CC76FCA2868936D279495651B5798491478B1B77CE6656E8FB2A +69FDFCC2C8FE04C5C6AF6054C01678278164ACD9CB8C7BB41E0A4A4A3513283C38B03B6C +27E66FA995F58346B724189632494406D7B8E6CE243C5BF1CDE8C87AEB0E6F43C52D5D3D +4F3F9C876FB9ADA96302D73FD3DD51D82E1314024C5B1262CC009052C4E598A2B7D855B7 +BEF4FB97D65D8B26B69CA86C173CE21A159B3765FD48A6E978137FB2C7B9C4A39A94EB09 +A9825BCFB87EDB546D917F4BB3B618906C643280D3A33CC87311002B465D440C5FE3B8EA +1C3AFE1CBA90999683875070513E14D37D5AC6214D5E38748901D3740350CBABF87ACACA +FBE7CB2A97332D9BFED8B0A7EB95BCA79E8D4D6A80C1162A49C73961822A568D43BA71A4 +90E3571845A95B8AC2313098F7C3379DB959167CA17281F8FC7933F10BAF70A573981F5E +02810780D9780AE94EACC4F4A2D1BE14649E1B776175FB5EAF25DE613686161995472B24 +86AC004708550BCF2CE0CF3032A02BEA90E1163319C20894648844A936D39C7A266060A6 +093B59CBDD59E4FC67AF429BCBFB4037DEC87FD9CE0FC26D488C1987E0D6A79AB19A7601 +3C3286ADA28464BE78C5C591126978FE183EB480403432664318992C47600105BD1C223C +E78F8F5B3C1C56F298C28B700886B9E467E7ECBA6BFD0BCA114CC74CFE8252FD9FF4C39F +AD3071CC0E832A9F4BF89F9AE4FFA1FF02CE797052DDE080C175AE529C61B639D842BDBD +B8D349090DDA8F503C909349A69BDC6D972805B15D2E8D321E9296E3E0965E7BDB040FAD +CA90D1BE06E438AB653E7553EB43A4430E3AB1A43BEB97715FE97A8B76A7B5B1262DAA01 +DFF0259186017062090F6B9A35B9962DF2F7EB85B6D20A693B1D925DB4BF06996F60BDD4 +6C2381937E21B3299CF3BAA565727DFBFCD38BF24143D400CF99A7F3D09D17D5E1CBA49A +9C607D434EDDD31BC70D277CDDCC5CE03C001B53CB1D448A87DB676F6BE0681BF57F66C0 +43BA1BF6889DC9F054A544C4D498B74988D5DC13262AB95205386343ED6D3C077B058B57 +4C464D02E35DD342CF013B84CBA67538AE13A3F50BE444014ADF085E95D736139E1646AF +7C4A401E25B3511364DA040AEAFF801A664E71B0D2C6E46B510A97D5B75B2377E54BC7B8 +C4B368602743EB5856E4385C4FB3F364C54239B5794F69E39791CE5BD967BD03E212B8B6 +E14336AF3900878E5031993E3043B23376975A43CB032C9D9C1E485CF34F3A1F2055AEC7 +9A2D2E68CF82F1CA0DDF7200B9FE4172947540769AC5FA6AA53A87E6A79AE9CAC84C0FE5 +F0C0752F85329F95AB21AC314B7D32C538E70112C12A34DF2CE7127E5696F88CF65BD083 +5E57CF98FE8AE4873FD1EDC9F775E6920E87000CAF9C8B7FE3CA5A84A5AFE056CA8D5610 +69F8979E13055582F11FADFDE7BF60FA9EF36AEF0D85F29D94CE5C571574EE03FCE5E5BC +A5B2D3E4FA107FED636226B59D00CCE51BEB891DFE12F04BCEEC13606B051D5A50B08F93 +D0B3ECDE4EF0DE6E06829E559BB2AEBD02D0B7A1C505743ABBFE54A9682123C3695E86C7 +54465D3A60369CF9C3FA800658DC52000B8F6915A9F5549849EE092CFA885BD5FA96E6E3 +D04DE784BF6F17F333AC90FD8AFA98ED04F003E47A44893E943B6504791D21FFEE630A7D +026F82D0B903496D3E08DC35768EE6FF9AB617D29193A5FDF8A0976336297CA65BA71A1F +56E19EEBAF4AC438B9807AC1F4CB0DC9F740910E2BC32220D37A337FECB98301B0A203DB +739DC361838D4577296B9DF5E1DEF57DBFCA489801685288238CD8DA085C709663DE7F84 +127FC9E6C4FCDF327532C87635A6D7822D36583930BC9FA1746966A175670A2EE77D5FE5 +DB0F43189C37191F0ED80A333E8B117508E17C010FDDAA44820EF17FA9AFBDB754507F4E +1AC0D09A0FAFC80ADA11DA469995CD7FAF67CD8E29AB323C03B6A1DE80B684FC2AE84B46 +BFE4748300EF789A12A166FCD29ED3AED2FDC431BF9B3A450E2B15BDCE9F15C13E4C28FF +15E145C661B3EF6DF748C32129BD734087B8DF6A5C00B4765F2B518ED29FC53D283587F1 +2B62F177D14E3956A64C425AD811AE6833F2E095AC0F7BED54333095002EF33824F6A7C2 +3CD332BAEC7AB22642A5331A0C1656E3E2E4FA99825B5F1A04350BD96AD4E491F97E47C9 +F5FDEF0466EE0566D5F2ECBDC2C3B0DCA65728196BC139EDA445C7B5435E293F50C91CE5 +4FF3AB7112603BE44D41198C3A5BF2CA4BC460C0BD8D86073948C452AFD0A35CDF30CE1F +AB58276DC2A49CE15CB2C1EE44E0C3E07D73936CF675B1A40B1A2DA5C61BFE4E56C92FD7 +CFA03B2D6A9A108054AE303195132BBBCEAE17F83B7B9140BB11DC6D2A3B17A46CE4FD4E +0EEB5FDBF8028B1E7052C602C5E7BC63D6F6A9172032D538B495C3D8E3DB6FAFB0CEE41F +35884819BB65463B11378A7526B582A4D2EE1726615B66E8514B4173C47B399F86ADAF7F +E7F7C08A707A30AE31400B603A31951A7F617BC16E5905ADEA0197382CF2F799F8ABE8DA +134FC37C99767D4ADFD45502F189ECF7D08471186F4D29A054DED0C5AFA56A8AB3AD5F3C +71D784803E0237F41B764C6A91676BF4623E80803231960AF3B941EFD842235968071455 +F1BECCB46F437930B443A1C4F681AE595A7F7057496C5BF98FECFF07CE1B4E3653B7AF75 +2F647322BF2FD773C8C79B305EA2365EB878FEC55A277066560401CCA10AB996645BAE4E +728E34864C7F2F0ECECF66C0387B2DADBDA23EBC4C0B904C5D152C9856EA1FB76D10BFE0 +7213A87551081FDBEFC207AE33B860649D445724095B28D45354590E967DA4960814E184 +2ED400AA72982427E378092623D784272A07450265A89A88C13F0A71A03C4234EE525034 +2F5F28BAF685A2D8AD6C195B4CC3ED9DFC0E82910D692ADE7236347002251126C4CF7C82 +175624CC08445EC64357BE592FA06FFE3FB52720F4CCB0A78173F0BFE317F2C22EC52607 +C9479BFEDD6FF60EC8F1F613251BDDED25F2639E469B344B86ABF4BAA8A9E05C5AA49C91 +826B39636461E805364EA49E222129B12D357641D89411DC5081064473E78BE378BE642D +16B4CA3D926E508E5905AB84C588EF25E3AE064348C93A28880A02B0665C2486BB41BCBC +8CDB229607ECFD58E01D99D71BC1AE9DACE87D02D7567D570CE3BB7EBB5877A5E309B181 +0E75AB6AA6E2A72B9DAFDF89862C96141D72DAAA090F0EC8A239F1CB565C7B7523ADD890 +76109390815D4D128B26523BF36FFEEB3D1DEFB8C44460FE64C11F1183A99BBF9C5D7BAC +B644531BC4873EEF693B2E5401D764F0172127F873786FE8A95142DACBEE14E4B1E11E5E +13B3015B6344C9B27CAD49C457FFFDA86E0097D8533F76344AB561593CC09BDBC1758F07 +9F31AFC4BFCCFDC2D54B8FA7F1265E8AD350C44C940B8111B4A59D078423535205A22202 +92F892CC2A5AA50ABFA912D6FB0304EA164E191CCC659DA1E00B2DE5A6830B60D69AC9D3 +CEFEFC2CB0DC016B7FB41D5853A0BE141DC15CAE07A90E56187BAF3716B7A7CC839FB123 +69DCD8656F62C1E631FCED16D171A3521ACF60675FFD2911A20DFE45A57887984AE2C41C +A8C6C24A12445E167CAC1A3FAF610DDCC8649C6F6CF07AF89125C6F37C70B682BB77394D +F4F6E7A111A0ACA9CD25E1679891B3FE9FDB3EDDE1D3805DF7C42BC5FE4A6D91C7042F67 +6ECFE15B9A90AEA755B3E032C60A71554102A9FF4C2E9E467F0B7DB9CA0F2AC3CBC3CDFB +8DC2A7365807E409E75E89047415598A8720B25CD32FBC18C12EF6E1F9A193132C0DA8AB +134A567DE1BA0583E12BA2045A36C298ECC4F909510D29ACAE1EED825ADA28437F457BE1 +94FA7EA3ACD0119F438ED2A2A31BFC511BCC3CDBCDF34B6DE3DFC6F4836178D9BB35BF9A +C546AD2D1527D1B020D2A975E83848CC431CCDAB997A195E2AB6B3D5A8980D5824EDA901 +EDBD85AA2B82480CC76BA911F2D4F7E2675E69F4005412AB2E88861A7D925EBDE0799075 +F858F32B8BBEBE0F6138D4C8AEB2EA647046C533519867FCF286E04AB146CE6EF4080A8B +2026BDA70349038DE8C2B71B2B2834E57D4D486F95CAB49C4DDC2DD17D8C959101CD2DF3 +D9E4E9FEC4CC05B2490A90A30C898E8588CDEAC838565BD0B6B494F2DFA565A606789728 +0EAC877E47201EFF4329FE524BACE5E90E8525CA1F5206B83D1FBD284D1109651141B4F1 +CD1D1F5A0406B90E4FEB435BFFB60BEC00454F406B6CBCC3883F8D470226A8214207DA07 +76CEFA99D769166A8327F8543039B44FE297A1EC1611713846E67B20E0DF311F715E4CC0 +3D1AD8EE1D14FE0AA2D55D1C30F9C1F12C9D8BB8E5429FDC4247AD4718B634AE34213480 +45B9ABE0C2E231914402548748A388FFE3D5148DE9F9BE6CDC21DEE4B5F9FB0C3A52EE12 +A9B23D6815E76979C6266A811157E380AF6C7911D55DD522FB766932E2CD361406517268 +43C8C1EA841219D167757C201022045656A45FA93AEA1B404B16882F20BC30B36FC2DB62 +96DC200D567BA9B4D49366EC4D3AF556013DA5878F04B437257CCCD164EA4460E472DBFD +AF091AF1C2131C55FD31E7DE78BF0380C4B34C89528CE0A36ECEDEBFFB34DC33AF1006F7 +EAE6444F7F063BD1B1B9C88850B1997D3A24BD1650FF98744C9A0CD6F7246CE22A1A91AC +D1EA6FBD9237C32B80D6BF79B40A3E622E83DFF1366BC6B7B6295D5785BA00342C146BC2 +527FCF50B73C17B76D6B4B0B98BE03BAD8A67C7D547C866DB6FCAC78C69735F26DE9FE2C +D9504F5AF31727791158F17D129677F5F9BAEF97A1899A7DAEEA53E70EC6C822C3F893B7 +3A4C313551553E902E762BC58D8D1E9508D9D3355D5FC528DA87BC94DD9EE305ED737379 +CEAC96549D3E7E505A13F11EBBF0BEAD38601BE5BF68B1EBBC504F8D9B4219307F7DE93B +EA6B153F5BB35E2B50AE9309229698580334EA4590E06E41D834EF86DECDF64687DF0258 +6AB142A457531A9103D49D0D64FD583046A107210FF1FD544A8B07EA3DFCC04ED74BA498 +E927C72907E896B8E6C0C0FD016A42B6F45AD628761A78C405C51BC07DB9D90D54674B0C +62F43785115A94708879349142D612DACF210116A3EE5F0AE9EFFFB694C328C73EB4FA11 +56E38C4E25BFCF9F441C2B0A6752091DD9F9C2175495B973CCC0EBDCD43125CADBE4DFA9 +3E11EE051D6D46B0B8A8C4DD6443D392CB7801D131DD58696594B1FFA5DB9D70F46E1C7A +84B445E50922880FE987BF899BB603CA937D4DD3386C24D24AD31038CD9C5727AABF3DF3 +0FA105F554A39A091655147C8511B818A5932FA9B33C2B1DE319C5F704BD439ED6E1B8DD +FDBFFBBB038B350E1B8579A1B2F55B24FCAFCBB6905F24C82A3FCE3374F979405E69BD62 +6346E4531E130DA4358CC11FAC6E705228CD1D4BD865DE15F2C8629E77CE5152E3CE5207 +D42D9265A4F27C5FC3AF11712F1736F56CAE5DB347163DE798EA934C189E5FD6ADF49DD8 +4E9692559753CAE3584F3C43902F775B9534A4B541DF22DDDF723339562A5785E37CC808 +47E59091A5A339467B57F15902EBD2399B55A19E098ED661A475A559E465A502CA339B3C +64A55AA28D3DDF57133DE6FC6443B563A0D49F898E0CBF45E55748AEA9E7A215D26E07B2 +C8CEBD2D9D233D8E86D53D079691EA21DE11F9C4FE0D3C904C5FDCDF2301BE7C896C2FE1 +036C2B3D9EC21292BF87593E27BBDA40DB83CA23F65C56064816657C97DD53CFC7FB54E5 +353730E625C5B31F030BB0E1D09429E6C6496EBCB17C114667F9B8A31ED328AF0EE9E7F0 +1AD0E70AF25BF2BBE8F99A4AAE42A6466347CE5FECF91355D61A312C550AABF782CBF1CB +649FD914B4AB1EC2BBDC6EFD65621921858E9CEAD02447DAC2CCD4D9D880BCB1513A5AF0 +D931F417C1342554E7EFE9529B18CB931453AFA51E2830037D2DBA79C565EDF25A0A7059 +315E242D82F2A32DACB9D86C62658FFB7E5A11D00B59CF45B48C1682FE8FC4A4FA41746F +E6F734D86B7CA91C976D40B64601831546DF211405F1F44FB6B8FAD3E880B74B66A93783 +F12CBBA01B8D456A1BB0DB78EF455B230B53F95C4E7B13EAA9A8BD49F886CEDBD9066819 +085B30488B011B125737F16BB6B31908808E7B076BF88E2F23684929602C888BB3A51D29 +A3D8DF55B39A48E5115E686380452EC5784D09C44ACB5EB20ABF8DFA9DF66344BCFCF175 +A877296E511AC83765358D8C091B91A6C70AAEF9A66C2F36F6387D5795B60261381CAB7D +9A1EF15EE18683C485317692DC0CCC859F5DCF51C3930355BEE5592A9E5DEE4360E8151B +582E019C674501C0F27D1EEC05B1F55FE9F79C5FCA04AEC51BF01CF8BF5DEFA0C9DA4DF1 +0D923E6E56D35364023C84D9D71D68168A73ACA6A6CB8304C1A830C3CC7155D9C5141DBA +165A1C733FF5320A1D1028B7B543D2A1516071D0C02AC030E52BF79E464D8938294A7D92 +5874AE6FCB352EFD4790F6973A627FD2979C19FBF19D2870FAEB6BE729D34FED4C87264D +65FC15436A57DA96DC09C7CA864CEE0D98AE9C498F258C4599CC97A1B9095825760D06A5 +C53E257F54407EF4DEBE04606D65E3D09C01535736D3852089D8FC0D2CEB60BE19D959F0 +CE1858D5B4B72A953FDD1CAB16B1768236162A67C1B77CC4DF6393A480DA4223B65C9747 +67A08C86DD75BEBC418E370D5C2853523D68852E705A4BE611142EF56ED90583181D8559 +9AD285830BE0986BD8FABE86377F5529A5749A30C89A272711A694AE29E2700034B6B620 +5413F9BB288AA9B0BDE0E91CE8643E96C8A771FEFD1EFED94DF8D67CABBE928E3A845723 +BA2B85A2BF2BB4F784F2324040C42292BA0966DF1A495D7DA80B9B79F76D10F1A12D53E7 +A16B3175CBC39C1BE14A36CA1E3C7CABD9F8DA323243F0703C3BBABD48B1CD35BBF2755F +2508FD2D66FDDD1DC21D232CCDD7CA5E749A841F82EFF35249BD72B0820CC69FF176164E +EB3E885E1DA18762FCD40761FB5C91D692F2678BA2BC45CF1BECC0A8C28EFD62D1EE29BC +2CA29D922AF0A592E19AC004573F357ABCFA00916487664065D3864EFBC54AE0A70952EF +676B5087CDD43D9540C784DBAFA0C0ACB72E35CF6D82789E3352A16D379A4C26118C4B5B +8E5C7258B2B9082556A1B018085F19168CB7787CA06283382260FA3743D036EC4142DD7D +2654BF95651123718193310928CE49B532F6B26181B078228B97B4BACCD79F6A8DAF1004 +096284F2D45BA3BA14F1D0CAD558239BF696B1F2D6F6AA2D11693B497A7FF12BEB36F65C +C453320F8241820AFA96FB54E83DF38BEA9C7A004EE4965EB7104982F4D7847D397B9EA5 +9F93C61BD259C3BAA15323EDA020E35DD78B7FBE6D7CAFC5C34D9C8A60B079EA6A3123FF +B7352EA72DB9BF6C80E7D97AC188A9B8BEEE3C80819D35EDF1CE62AC4DA459EB208BFF41 +4A3EF9C4E3514F44EEDF60CB817EC66E3D698702B5DC889EE0C064A387C7487DD97B4EE1 +2792DAB796E4123E9D7F3191B22F2481A4602CFDE1E708EC6BFA63C771058B380EE6AD48 +2524F9F1FB75D470EC11226A138F4B9E5360AB443D5091B324271E8B251297D8236E3C5C +E92AB19E2005DB4A8BB12950E6A3C47C16229F300F8BDEB8A54211BA195589F6C8CE22C1 +A32B3610EF0E43458132703F86AB9CCAE7F99CD7DA69EEE32CB011EEED797C841ADED034 +4BE043DC76BC7E5F877620283E923259EC2100FB83832D104A256105EE8FA5742D7E252A +7539334AAACF79E4EFD98C32661AFCEEEB5A9CE44B2CEB765C6FC6B361E95CBAE60A8680 +D2741C9AC12B834BE5EE4F498B1FC7137BCDC32A225DBB86B1F342BE3FBB03A17624066D +2D652F7F7F8D431AE8DC401FA2FC64AC056A9F29DFFBDE1E07BA398624F3337B6001D1B4 +F54E9E67B059415D43144EA8DDECCB6B57022B678CE554EC7979BC4DE26BBDA16059A3F1 +16457844011864CEA021FC099B7FC141923CEE982E2915C6D0C28767027E139BBA2EB02D +49DD1B247EFC7A2A1504C4DCAF35305671CBB20B2BFEB0EAE475ED4AD53293B94A6E6AC8 +41FE1E9CACBADD1744428F6F992348A3B1D391CF65C86E2F1E57382D245C920C7CF3140D +6AF604F686019AF155ABC0B0BB9835FC49755277A5DF9E6F0A7B8E91EEE7A2287704D71B +64D4F6D0C927DF674B35A38E98CD7ED00B76966B2E44912BB1EB240C25AE3DE8E7668062 +55CFEBBE98D8A49657D1B230F8A9AFB157AB3BF74C8485F5A275B2C065797A9B3E1021DD +7FC20AF45DBB60346C53E3CEEE031619153CAE0CA4A3C25458D73EC46E8B7196CEFFAD73 +6243CD4F81D73A2A7D0C3F58DFDEACFD4330655FA5082CB75FAEA9B99D8BE6A0FFF920FA +9F8AA5CC2EFD3BD09C3B8A94BA03D1411D6AC5894A8402330D5564AF8E75AE549A11BD49 +E15B20F7879DAF938B09E430CE1B57EDD9346CA8AF022DE5548A4726D49E8DC439D7DE79 +7C006A7AA78B018A1D68E15AA83FAF97394FA4F0E1460DA5AA9710656AA1E294016F2F8F +D7B10DFCD2D10AB59308DE6108C3D44CA6B5B1A0A5408E6FDCBDE1B5CF86CD7A9F815146 +B9721F11ECF3EFF7640EAEE03D8D3B4B4F055C6EA18A7FF129F369A1FDEB7B71A3223890 +BCAE11DB2848941B6323221AD976E5986280844ECB67C4A1ACE6BC87517A2DDB2F928A01 +8727B99FDCF0D0CFF57A0BEB04C7DA62E41E9623AF0FA6EB651E0D1C9C72140CFF8A7A2B +BBA67EEF1AD2419BD5D399E09F2BAE43881E8AC834E46F6F1C96B6EB4DEEB32637DAFA37 +89C2BD92A4989F9AD822A6483D516A143EEF6DE93ACDFF3B118F8B80865EEA782EEF6DEF +D8E5E9252B378E3F09E770F38CF1A71A5CA9E872EEC7E1AB4AE8B4DCEA41630FD47B9602 +81A711304DDA075014AD733B83D5631276F636D4A470C1DB8F5B1E1AC5B005FE2B5B4D79 +346B39D86048D7066C0F5476FA7E8A8F7D48488F49507237719121AAE83EF6938AF31754 +5C848CE4E8A118A8093F5720CC4884D3886A5BEA6312782D229ECDC11D4AA1731A5B098E +DAFBB3EAF2C539FBFE55E96C1129EF344000D8DDD7C7CD53196B27AB252155A634FEA9D7 +971E3079ABD8F38DC7C166B5DC2D0B1C66D776BA678C5C57E8EFDD55EFA2F5B5FF8DADC6 +0F18A0026B3159C7FF28D5283E6835147CE4D5E5ECB6A8E537CDD7F8F7A0E7B6FC53292E +FE0F780D9B58293F527159A8440C09FD842877464711F7256DD732AB76D834EFD0C5557B +DE603FCF0E35B4025848595E585A7707A33F0693022B06FC2032659BA15DA56C183E51DE +A5A8921061E9ADC27AB380DCFC851ABBD9A51632F60EF08C2FCF84A86A89516D66DBB232 +A4EF10707682B9AF6A9B584766C8432FE43BD4D2111F81446E0D508817D6E6742261939E +36C71EE1945C10C1CF6FCA1236AE71A10957B57B1F8F69EDACBBB9898735D2071C073E43 +6585FE7EB0BC41E40DC59BCE6C311D84F9C41929DEE8317615033CE146B3C8DD7C1DFC28 +471226DCBB5A003FB6185793B313EACB67A443C60A2A7873EA4F13C0DEE9209D4829FBDE +5E93380F14C2F04448CCCE8C92A0494E4F5BE68792D35D019F1C4279D261579261B6A990 +6ED88C23D9D7993D36FB0F0ACC744B14FCA75D62AFBDBDDE020DB4EC979F9A816DB0AA8F +767A0CA4D561E00EE5917AA1FCCD701A8FA3BAC8AF96268B9E141D891F15B918882FBDF0 +4B611708AB3D464936D9AB17E781DE646C2BE7EBABF82F4D547F09719EB03FC702894480 +9E8C963D076BCF1DD1C29F3E6A57DDD550B4C50C940363F0015EC80F170B282BF9E9E8A8 +7E11B31975583D1B8678BE0F782DD2DA711A0EFDC5EFD9BCB47C4C458AE693207F67915B +388CF71C508BE8A2E3336692A068097AFC21A42DF45A12CCD4E6E005857D04328032A455 +070E65A5F1574DD06B48CB94508FC3DAB04FC0D777C24F1B8A32F5401919441A01C7FEA8 +90AB7C15FE2FCFE62713F42E9ADECCFA5114E46E8FE38448282A694BEC76034775C730DE +B2813ED4E2EB75C8D2CF9F6EAA42A82C5C711BE920E4497E4DC4F60ECD923B6F21FF8C9B +2AE3EB19CBB422FD027B4C8CC503F523E7B18DD1858D1DA08C9B0D0B9C9870D549436AE8 +D21746C86310CB94923304496CB2112D91AFEA2776A9CC7CD79D381AB7E251B6B13E8DCC +36DB7BDAB3AD9D22C7A9F6CEEE7C130E3753C4AFC946839697EFFDBC4005EACCDFEFC029 +9D259947810AFE57002A3FD3B9446977345BC5D5D53B6F9722C47DDA534BFF98C2433B0E +EA965E20ABEA481A9C81C612ED51CCC35A74CDB473AD0A5D2E42950AC1F66DE6393BC9B7 +B02B00441EF8CC421695854293874A7168496467FACB15062D50600824D18F65E3FB83DC +C5273D5743A84DB5CF9D38AAB1478BC6CC1F849ECDDD397DC56D1B1BA395684520D68729 +FF5132F4F7B48A17DD6FCC303871D6AA2F29CAEF2EF77E0C149829B9225746D43286D1D0 +940E765628810673F32809AE451309BDBAE942726E9A2D57711683B3C4D39F6DC393A20F +BF0A8F4F73E8A103B3D9B12572BA4B846A0A9EF3702546EB97A046264F067FDC72CCD091 +E357B618687BE9E5C7E667914F44EECBF3DA82C9464380981288AB2F9B058DB262EF5BB3 +0A4E0327AF77B82AAF49479A96A6CE7051D2277EEBF286FECA3B0CFB56E1A94B147620DF +BB6207691D8E751D5E468B36BD64C8220F2883A5DA60346EED5616F924660658111CE6A1 +0FE807C63FB67BECA2AC00D98C47B5F1CD6B9FCAA51848D97EAED90AFA582F925DB9DD91 +F77B73CE5BCFC0A8B21C4A75862B345ECD68545A4ED15FD4A3235429019E3C922537DFF6 +F0C2907B10D068D116EACC7E0C82EECD67C0A377E367500BAA0B47EE6444C4FA196C7DCB +F1B080A2531A96E2A874DDD02793E72C1D259C3004474DFC91F2BA21554D2DBA3E4613D6 +535691E6E4AC04940353EC25951DB2D4EB2FCE5D701249B835FFED7C78225A84A24D138F +631AB67295866BBBD000C1D5BD26B43EBBE4740716DA3D8293CE4E359792F7120811B32E +2B378B876D41E70631187CEF898EDE78C0A8986CA30889A8F53C2344384E3FEFFBE7AF07 +171E031BFA6536E2E6719D934F74B39169E1D912790256B06BAD12CC3AE588B2B2DF1C7B +ED6A3E99773C25BA78DAB1C8E902D65E4E55FA9005C4D80819AEB20723269B6C091AFEE9 +29D46C11C198A7BB0D4260EC9464156F655EB1D460DB7C72D932CA927D39EF98F35EB6DA +7F8143A443DA3D0E909E6B846DC2DFBED888DB41F2C03D9C9B61F31B2E8334DB7205FA8E +C2B94D71CCF61FDB51C66D8AF7A47417DEC7FFBD8A052779869E709F3B36BB74340E78D0 +3BED0A4618738C9D2C3C447C0D50BAFD176208820D1F314E21615B7A4397883F8D59E65E +80A814CB6E8FBA91B0C410A8B7E37188C1849AA206A66162902591AA90F18E0426C586AE +80F63CD8764DAB7FE811172A87AEE833E935F5F56AED5062E2B35F6077EA26AD8DBB1011 +745F36D936EE50A88144F211B37D8C169938EDBAF26E277DC7A921C0154317BB081A7537 +F0FC37CD6EBDB6F97130CCE08B85690E173D7158367C616412A63D0B8ABAEB47B1BE35D3 +23456EFCF7962953F630002DFEA23DF4672FEB5DA149B713FC91C94505596471E44D590C +54FC5D336DF319A98AA87DB9D313B9DB208DDAF46FD5469AF90F548E704DE24E3344B95D +6EED106864FAD4001FD8DE48DEB22C8AC3FAE18F7B176804DCE5AA2144A073FC9BFE4CAC +CD6CA534902429E28CBEECFA8D984A71E77B5662A1AD114F301F548F192B11ED7EB56BB3 +F8FE62001753FBF161D538878778501F917441F9C5DC3B39704BC1A234117157303EEB24 +EF453A1E05208A07B8AB22DA331527E0871EE7D713917E86C80D2FEC3B934E5B7540C672 +34D0FA0E4AEE6A5B1706F2F3AE147690A76815F5575A5C5B44682028A065FE8037E10526 +5F282058D027620C117A57CACB77AE153E8517134168668E79017166CC435DD24831DE0F +65872D49DF581C872FBD74E0E2502B9C0C741322E9CA72152E7DA26D84696366D3DB5C56 +943FE579F99CFE384EDEFEDFB30F7EF5ACFF5BB88327E5A63B796C7EA2461B21419592B3 +65DABD1DB63F6AFE1B959CD018163A48D82D0D36284F118263E9D2B8FA2E3104BAE034E1 +A1DEE263980EFDB385CD6D687D1092752D7E3A6C46D678BA2A2F3E208988AEF16EB2C67C +0C5DDFC85C6819746A034BE35F5C6DC967D64005E4104A7EC6C55CEE199CAD3F98D83A22 +E9A32D0B0F4E7DDC4BF81D77914EC3C3DA3AAF51424CE3B50AB293152EF0EC717F16815C +4ACCEA27FFF69DAD5AC1DD549C6CB01F23F3C5A3DA340CD914849991C554202076C37DBC +7FD48DF9DF23F5DDDBCEFE0114A2877C31385A184742AF5AB3007908A359240E9DBB0AC9 +501B7BAA815CC273D953E0D50802CAF8C00FCC054B10F0AB7C072C573FC4D3EF018754EA +32203E847125B73AD879F613804FFB9470CF39D0694155B3D5D500E3379A163C86CB1AD7 +85C3AD12B724AA4F203C212FC0FB7051CD0EEFA161920E515FC83EBE802800D1C851E085 +B069541D8E183032EE5FB6D8200376FF0FA5786796E7B33352601711A2323AB0F2CB64A9 +B71C936643B259BB73CAD6D04B33201FD772599DC49B9611533D53630A3C91A6DA4E3CFF +519BB469F2C23613B0D445D98377E8EEE6218E0CF7333EB5C4257AE30DC6F8FD35C5978D +4071F0D9464C260223902E3C76703BB2E3B3FDD9ACB3F6E43C3BBEDDDAA846A4893A6E6D +6E8D5AF8FD12DFCBEF1B5D8F537AEE87AD8AB3B486910F0013FA6239528F698F61B6A2FC +FA7CDF66B238222B989DD390A1647AFDB9AB7E287F5CD96B7E443C293B39C7C8A91A207D +E7F0A73A48387C9955747277BCA7E97EC37EF0741EDC541F9804C12F95F3325F2E80CCCE +0CA03C931C7FFFB7419BB3B2A3A67325DAE74C4D597C41E922B09ED70F411F7E29486C5A +3D94A857CC69502C6DFBB6E63780DC3908B989F01116B28CD8BA096CD0B09B3EF4AC8E64 +55FC7300CD8861EE2F1FEEFCC03D95FAE9DCA58000441A1D3419B77DA35E80CA40C0C49C +E1DAA21511AF32DDCCF3935CF78808330C469C4F12481571303335C945937C0080E56DF3 +ADAE10198495A9E04DA1AD8453A5C3B7D9E6E8A8F6F57BA249F0E9CCDFCD8D25C8E39BCE +2B158052D9112093EDB087E2DAAA0C835634BF21B6C767D7D622BFC669B78040109BD4E3 +673468377348A6EF3D0E6D1D7BE8A07BEAE0D72CC158FFD8904003E7D928F7F9B78097AB +A98804FF2BEEB62C695333EA76444009C03751DA71269219D0B30BE98C710803DC3C1159 +2CF0B2D8317B13358B3D96F2B79F801E303417DC8FFA4C1B5B246C5167410518BF7B122F +072E1C356BB87B6BAA4B36609C3CBC4FF578ABCB0A9B4241AC991354B9BE34E831FBDDA1 +D97665C37DD1AA4E2E2AF3D41D2E9561646C40D622883D790D6986C60A2E5B2D27D9370F +0F2E57DBCEBDB45A6244D1DDE4F64D30B94621B21EBDD2DD7F87E75E9BC4F47F1E94450F +AB7D3A2687C66FE4495A05AD81E2C0AB09B4814422272290A024FC55819E7DDB08666BB6 +FF9C9C4F1AB70697649197C550C48D221DD1BFFD20AD9B43F876F19CD818F3EBAD352B94 +03A050E79CA2A369363033508882A1B63D0755B43E01BBDFE55E7F6C171E1A6BB37365F5 +6241C6DF75D3E1B1364A655982D595C66A186310A5B2B3A4C99D39069337E0B7F3448D7E +E8AB0C5EF3AD79CD8D9C86C1E54392437C1077573076513C0DACCE6D16A3ECCED9C438BC +F7859B1ECB294B03260BA9D9890424DAA816587C4004FF0905C6026A04E130E3B59F1952 +02270BCEFD5B7CF306389D3F255EC17C85C6C53D597E11DB5C1E0902508F22044441EEA9 +A474CB66BC40D45A2E0DEF1C83FC4432E155567ED91D8A928D2986479F149E4AB3987D95 +93B419964BFCA0E042CCF7807B125F29E22A488BDB19285FCAB04AC29A564D599075B2E5 +B3CF0C6D53BCC23C1ED6A5206A6AE91E2F21AFDD4542D64A85F397B3CB0DC1F2A0C2AA87 +5C38974242DFB90B4CA67259D610BC8691037931C69D18242CF469FADC88CDC85FDEB881 +A431ADFD4071F3C856EE5BA0196D1A7F157887642EB50C8662ACF5BBD27C4038206FD907 +8AB7146AF5B02FBC3B84E61DC936C2B79F204C8765D6F366CE1DE4FAA944852EA71AA25E +BFD160E6286C927FC76EB19F4C5878B5D847FC5A941B8F2A1C7C38A0C310DDDB5D171E4D +0A1774ED965F237A5396E5A94F87367DB141DACB4448F67789C26DCE06FA01C92014ACD0 +1209D727E37A5C64067B2DC0F91530D8AAF59DE0D750B2A18BE91D7A3362EB026C438FAB +EB0AB75C8B2F4137D843BE8EF156CFA20563E291B34F19F97081D4E43F4A62DC72591D54 +289D839CD857540EFA38AE1A02A13EEE35A0A4A3576FF6AD5598A76B3E83FB67F5062FDA +4A2DA616282CEFC090E154EBEE481B906CC206AC6A5A9AA442265E95CA379785B96E76DC +D4095708AF8A65DC213E42581C59359F3B48EFE9F20AA85E04EBD4F8B4B8201607BC2CFF +FC71D43AB06A3D82E766054F2A54734A38A714058C7573B847C8A3A82304638F2579F037 +83B88E29709F5AED8F17F68BFED85C7589F5343D8A1B73935D693E70E49F67EBF2E85104 +F1A384F7D6BB00AB4067F816CB11C71C625136E073E4C98486A5972DF70B5537693FF55C +DA94FFF774F7C10120F4836B9E26941B8AD2E48B90D71ED129A48DB73DDC0E7CD569272F +33014FABEABE382BC029832CA1A7EEFBCBD24CB435B58703F1E9909FF7D30D37154F2D5A +29CFDBE1892DBAACC07E68544AD4A1E672DD620A5EA6F84B360D6B0C9D2A16600731892F +4BA194089DD0D829F7DDE7885C7FDB37B8DB601623B7B398070E617E2DB13AA6B7C7EDA1 +352570A133F0DD267E23EF4885DDD4B6A2EFAD3B55741CE7B36475A878228A200A49202D +13A9EC655051C1EC4FB61E9D3C1029D21C4B943A64479F82B247759FE49DBCD64EAD1605 +81159DDDF18584457D99949AF2F2EE4F2E3AED242C25919F51CB76A188867D5959D8AF10 +FCCC2DD8D2EBD266B751EDF244BB8284A4705E1A4649A050348AE54A048E515F29469FDD +B04A905C3B9C2B3744455C781BE4487DB56A085A9BDF8F8256FA4C1B37DFF3295F5418AE +C03ADCB277B3157A1DA2D7176E12B334A49E7CB311D6BEE45459160E34B024E8B68A1768 +E83A7B8D7E0D5167E4BC7EA55157A20C82EF009A2631CF53205E11B7D0E7675329822052 +C2FD7C1FA61D269A90B94A4F103E6FB3EF6B1B0304ECF573EEBB1A432F7AC539EB7D40CD +C2F67D1D3E87E6B66CC16B63E00EA442036DA83A7E3CC8F2946CA59FCC0C085D642DE6CF +7C8B642EE62B830ABCC7CDE13DEE8C11A4718ACE97C8D47BE41AF8DFB4A95D44EDD219FA +137541C53086519D6F32112A2507D37B2EB7D2FC10AE66CC5D5A2D6A4F8E6F084A95C923 +CB40B8437D3D51231B50C72DC5FEC25ADEAED8D72EA6FE59859CD3512F36A0A46D55607A +AA143A65CCA0203366C702554B905A093B2E845FD90002C689CFCFFF02586DBEBCB11688 +7FF863EA45DD0EED511F4CAF921015383CA0391E393A44419B34E82789A62502C19B3287 +DEF1F5B24C60F5677576902DCF76F00BC4D3A056875990D18BA69154154C76B2BAA38ACC +39C8C1D55892583B7C32CBE6411834223200F22B416709FCF635EA5016BC3CCAE42C68EF +AA30B0EE474890D25C9EB745915FB60F517600C7F380582C7BDF4B34FADC9C60CB139D03 +626F4DAC953F9446C02331E2804245F7AF2BABE7FD2636854AF0CC676792580B228AF541 +6172AFF0C2FD5730C2D71C9FA3E17D36F9AA4120E180D025B710EB9F95AD8AE31B66D872 +20F028D258A85409CDF37158F840C2F418A0470357AA99A825A9537D24BCEB415329EB6D +5D985445AB19B08ACFC1F58510119ED297B034334EEAEA319D0EF5F7DBE4836DF61041FE +071BCDF1644E9C2D924251049CEEB73548286CC1EA170F0895771CED237B33FA8EAF5571 +E22C890F0B552D319EDE4A59928F14FFDD911F08C17E939FC035D7AEEFCD77AB4A2E7C4D +91B25D75F5C6CE9122C27E0E4A033417F389CF8796EE0F55794001AD285C9285436E983C +94ACA66A8C8027689688D0FA18DB23BEEF57C73CE751FC6ED14FB4D9601080258B7D4885 +4CF3F9A8DC58E073B3D2961729AD90372490C0202095ABF65A8C95691D7A32DC000B6FB3 +EFE315D903FF04A6B366788B5A5FADA322BDC00BFE337DFEF5EA0B899E36CC226DCE1B75 +CC352F71064E7F05420E4C3D1102F55E082E04F1CDA182E5DFFB5EF1283E721CECC5978A +A1EFACAB70A21438B380BE3A972AF19381FCDFCC60FF173ABA8BC049D0D9F22DBD722FED +1711CCDF75C710D083B0F3A56338A7708DEA014BA01943086306885854CBBFB8E372AD75 +6A00B5CE723A2558D80EA8B34F987AF7828CC5457865D9299E3070077F8D04D94C569806 +97CCB42D01ECF928629FDDC07CF668E87ED8313BDAA0D5FD84B0B416FA83998B1ABC0B03 +A3E43B188B7D74287A1463CF2967C7FF64335B205A69E974789EF5741A6CA9A3B62FAE04 +37B957A01ADC30C6C1CEBFAA7044161B9A094377D57E4E990FEA040EE9E37414D70376A3 +66D16916752F4F51F45171892908A53A3F6EE0497A69CE4D4F4085B1BC10F65623456980 +DDCE8C933CAC5C779D518720F5B8F511C8FE4C53E23103A12B2FA4DD02938ECA2AE76C58 +000D38B2FA467C1E1A8A442F9EC4F02E0DABB0204F2AE527B6F7CC775DCD07DBD96C589A +B912F727B9B81FCDEC5B3761842E845FDB6CF3840CF0F183F2ECFD28A92BB4F5CCE7DE8A +ED8912F728E39646F57DDD2816BCB3BE81DBF41DB3D3837BDF55B60E083EEFCD1A012A38 +846E025EC9AF4CA745679C60F88F01E3AEE7B65599AB02836F7A1F192466F5F729483DD8 +7C2E1CC75A61F0D7171C85DB04073B9A319A2F2B76C632AF2ED220FD9D7A1F9010836070 +E0D864D1D31180C1B6E35B6CA08D7261CC843915F15F802B3613E14218DC9EB7548A5680 +C1A9E7A6AB73A75DB974B4359BC428F1CDD2BA5E7F4590DCD96F1C3BD35AAF8549463541 +2A28027140D352FD0D9EFD97CCE7A86729432B246EDBC0A54EDDD6E67636A6F908BA5BD5 +0A90F4F1365DEE1C1E8989C0AC6C4A64861096C1B1D3CFAE51DDDD96CC24C5C11275EC50 +5F8DBCB44E345EBEEAD458D458A177542F5EE64FEEACA55A61AF8738E6BF38A6C9B211DC +F7F2675EB86CF3711C97FF23FB5F5FEB1867467158BC75F7BF7414BA151937085005B8DA +A6D82F31DCA1007E8D3D317D13BDE2428072D2A3A2743EBD214348B15EC3504426FDF73E +3588BD1789A8FB8BCC1E1A021BF64D274EF0C9FAC95EB50E2D7A1768E82BDB5A4239DD1D +9DD8E1775D3BD4CC4C07523E74FA545D5D650E9BC87B80E41EAAAD235833D1CF3B6B9411 +4EC21687773049E082646C8F29641D858D9890B41FE8C54649F840A0B81166130722EFFC +A6446C5509D988E0B4A9AE8E8765E1DFEF579A6D658C4781BA3B3DACB899F0AC467B9C14 +C66C8930E9A8558C8A19AFD95FFF4A3DADD1DDF80245C2F5F91D23B39CAAF4D2BB1216F6 +4490CBDD7FEFED8406D62DDA4A4B0F0FD80487C9752A0948F74930FD47AAD59FFB8B5540 +DE795994B0B6F209699D1DBFE7B7A94DF25522C7BF57C77EE9530784756D2FD8D058B9F3 +BEE20B4BCD63C950F9A4A01F66680608D66AA87E2FE5FBCC265505325711299F6E8F54FD +1686C4B532C504753EA7BA292A91A0FEB9E5BD690F1FC1D1B16D3B9870CB2CD14F7454A0 +8F365FA3FF1F0A8A33F9476A7053BF19ADB66EE28825530115BF79F60AE108B28822EC6F +313C14E43C02FE8871307F481D8B00F0E7C847A3F239723F4003226EE84B31A72F19BE81 +CB986F92710E37B1F6F263403CBB97392DDC7550F03A1ED56165B3082314995D75A4588A +C4E503C6BFF1E642802E0C3F1058B45E370D3DEEC937533E1CCAB26BEA94E9F89F6C5DE7 +6701DA7753CD1FFE77A42B11765EC6F80520EE01878ACB37096CB9C091387AB3BD68205D +1CA6E5BDFFABB2550E6B942F65FA977D55A459DDBFE4E17581CC19FC3B589F976EC22F91 +8E95546F8A447EA621DC289B7B7D67CC9C246322B221E6EFF507C2DBD4A93E41C2F7AD94 +4BBBB57372F85E601FFB6984CA66A5B7E98650E84F498AF13C4B0EEB0038953B5A33DEA6 +9CAD47277A632B26BE464E87951E89B8E0C051BC34220EC245E6E31383B22980AC124D84 +3662E9A1C8663100520AEE44DA661F4307BE10122C14D706993A586C7400BA3C74F020B2 +047CCBE55A6DCCA5AD37AACF9ADC82A59060518FA39649A726CF23543CE91A1A1070FCFF +CA48C8C6A9B02CC28479D8F58040984250C0AA0F581DFC8A5F978EC3DEAD276FBF7722C0 +2C3E41D993368CC019110A5ABD10C1ACD5A5705160AF288A60BA2AFD20D22099265BD254 +28EDA9461AC8193680AD019787902636FF81AF8C0CFE7BF8C064850BAE2E652CAB330EAF +13508DC67B881361C4F29B45D9885BC4CE554493AB16F995A98D40B7DB137953488710E2 +03295B129EB42BE45B089F8F40D505380EC2EC7C1DDCA1940DB8678A1CA0232F3140FDC9 +C00FC77392237C66F9A0A8B88A7D7D7162F72A1319BB22E8DDF62DDE64C9796FEB38C360 +D00F5C94FB772344423AECC5B4491B100A2A93D716B57B5B44083101335682DC6BCAC0DC +B500EF88D04F4F955A1214F56508DFCE4299A8B5DDE9A997E431A55B0E8DB6CA1C332502 +200C5C5899731AF052BC28D2980C00DB0DAEA4CA5EAF199A5DBD0BF794AC18CBACC20981 +96FD0AC31CEB455C61991445EBE8AC899B9AE530847D5DF608D011437B2FB24E4A1C45F8 +05FE4FF8D4109B5394447D7C9FAE9F57EB904B7D6635C77377D84D628F0BB1898FD9DEB9 +3E82CC2ACF52553E9ADDEB1E275280C62E4E8AC9722C5E1CB54DE4C4DCCCE6166F7F70C1 +50747CE19775F12C19E4A81599CB9C57918A42BB0E9AA638429B13B606EFA7EE2FBD7632 +0275BA3CCEB743B7101BCDDB2CE5EDF843E8944E4D87E1BBEF47C9D5611E1805CA0F2850 +CF8A205D53F054DD143C3C90D9605C3B7AF045C553A6332D791209DE72E02C146312B25A +9A5F4AFDBCD83EB67685ACF487664FCF0CA5C455F5848E18A5ABCC174F55984E368335D7 +BC77BE4E2923147A111FC8CC57CBFD5BD87D09867347F01E11DA0780E4FDE4DDA54833CB +10ED212340A0180CDC5924F675AC6DAE629555524297FD133BBACC4F51BA326AB7D07DCE +2093D6DC8E6126DEDE9ECBA129DF931399C72CE690C0B119B117A14E3AFC18094DEF65C8 +4DE9705255D3D411BDC6958D872CBAB28C9586DA888066A2A00B05FB21B5DFE2B9B4C87A +A0C4D7B91EFC7E8076DC5817C35652903605B78FEBFF1B4783A170D8060FC151CE533755 +7B8B3B1EE083114F977201446CB8A5BFB5DDF0852365330CD5C82CFA9BB2DFA6BABDF675 +45586F4D28605BCCCD80BA8B59B501C629D6E6BD5D676665462D5DB2784C5D6D8A42B406 +11700F3A27FD143BC1EFD859F7705C795EEEA9FFE57E25AECCC5C7E270833AA9604C6248 +612C356B6D9937E3B770F3B4FD632A0D8778C5EE2CE62C4E780AF5CFAC1C7C564637044C +0C8C90B9BD886F9BDC287FA97D4B4F4E4E8D7816BB25DD740D8C9307B94DFC8E8E91F41A +189E20E2B438AFC4F42607744E8BF74F3106312D7480A71840D4994ECB0A7A088784AA68 +84BF4DA162D5C38A4EC6354D19F06313DF2D4167B57BD2E5F544490D711E4B97F8D5B68B +F4098D8C9F2D8B8256EA8CCE05D189DEF0E86938052C44D7DA68445A6AEB7AEFD865BC96 +592DD991DB7FF294AC7DD8241E23DE5C908046179B44B9E8A79472154E254D44BD9FFF4A +435B05DEB14C08377D2ABCB8A26F706A366335F2DBFBF5D59B9DA9C67CB396A17A40C874 +C28E4AB5E242B6AE244EF37D90C8699BF1F2D5F8CD1D3130C0CA72B7040991FA90B3C413 +699CEFA97113609A486483E2A72DDF26953094C4E2970A243DE23963F929C3CED76AB062 +8072F5AF6EE3F950DCF88F57F33CABA2C8E4598D4FA6AF46656512E180DEA02FE3BC8701 +C4EFD669BDB52129FEC53E6FC55499680208E6A874BE255EC21B8C75A9D0D8A2622A4CFA +7E6BB9E8986AD3EE513F341C595AB2A14784466170C4D6DC2E9BAC82B988CA2609FF4B01 +185CC5A2B639A028E4A378503F55C147E6F8B30CFE5380A7A07981C15BE3C7120257C67B +4B603314DC2B65A2E4036151713B934F460FBC1B052417B907F70FA06E2219F310E34443 +A17AD4524ADCD140341BF982EE4D8DE7D969AC5621129C600231B16E97B62B6F618CBBCB +638020E75A77DBE28CB0EC9E4221F5D573DEE815512CEBEA629E6761617E69BA730B1EE6 +14C96D5758E519783F0862FB4F5C10D444882A344972A91E12051B2B29DFEF503D8762AD +895871D7CD4CC8BE62E1315831FC25712EA1C4DAFE49CA332CCDB5AC2C2D67F6594D592D +221B7DE7E93261E9D34179DE194AB2F4F4DA9DF9EE3EFAFEA6F1193940AED5655FEFCEE9 +E38DB186C5B5DAC4B0AA13A89EA5E81303A681133ED154B164E3A1D416DF8623A38213E8 +049B876C7C22F625A57248C0B61E4DE518F982E11672AF1765984203B7B7A17C2CD7C7A3 +847B6FCE423541C14C6712572DBE3BB99D1144021286B4E3939560998BC16A6CB47F9905 +BD48B9E25D1B548F6AED304BAD2823E364DAC055423B76800ECDA7C554211DB47BD28200 +79FE362F799925A8BEC4B4770574290D0654CEC588933BE1845BE51FDA15760DAB3257C2 +67E89BA950E833DDF7D7FC37F54AFE1954B006E3C758ED7BF3B28217EF77FFE36196D8A0 +A81157CA87889D7239BCC205459C3A11B808545C8A256F97F3B7369EDD1CF5D916E71B0A +77BBC006A71865EB15837635FFAED75D3172D91BF820230392B102D1C6AE05F36AD0236C +90133DEAF1B0F7658B6121D1F2F293DBCC6524C89A3554827D44601BFAB910BB7C908B8A +7EB7E84221ADDE214CDEB6B74765F2E8148F013F4D6CFEC4C7BB344D82B176D665A98424 +CC385736C4E1D81808ED22869C8132E5EFBFCCDFD1DEF732C3604BB683E4728EB60386E4 +D03D08E76B36DB7D39F07F505FC13A336B7AFF4D9587D1EFA16105FFFEEEB8BC2406766A +D3742312A7DA69A7B666A178BE43DE659D46CFB1A0309EBEF7B886EA3B3B554EB7225644 +EEDCADBBA3978EA1EB59B35EEE61BF1396A61922DC59487016F66561EFCEA19F30295719 +156A8C9099F0C07B5C076DCEA85C4924ADB96095AF46C1F9BA08BFAD5A4DC49E95CAB635 +CF1DFAE9A1FDB81E27609EEBE67A9636AF703415EFBF5EF0EAF7C10B1B04F139E60FE96A +6BB3104555EF08139F1641575A227E86F0DF716C829AEB4BC5CA32128AE75286C6CE0147 +F4D6873FF3B94A6CA54F701B9494B380D65E691F988CF7C6D74BF67A42F169FE5AF96CDA +656683349FBD542386DB635D09CC032C6BD486D08ABCD17A69C7FBDB61378024D2866932 +47E834F7BE079A875D8243E46E1533BCD01EAD3BB390A727226935F1BB5A9A1C395C92FB +679D980E6E67EECF4DEB74D75C164D53DAA8AA3955A91C29F28AECFC65BA8D7572374DE4 +F35056460B36941E7E0BAB36B8C28E081A29D92526D2F19BE960DB6CB355003BEB9B3054 +2A56413F77FCFA28B73258A8F4D473C04F8876C2B32901F62FDCF97261B3CF09D0BD6087 +ADD051543706CDFEF061C5F909E6BACFB2DCA11F38DA994E7BE7373AC2877648A0628662 +00AEE5E012297FFFCF714986436209EAFF78C09FBD9C54160A4D4C0629FE3F85CE065438 +8A996B462D6F520EFEDF8EA2578FBD42753A2882BB3FFFE6F65A89D0A74E27F306BBED76 +1F35A13A1DBE04D998F5CD63054D98D5A209E82637FB48929F7C70C154F66B6E40DB0F74 +18C103D628A4BEB3BD0455D886D752D58009ACB9D52EEF4F119F22CE23AABF40C558BA77 +5363C68AEFA720A3B14576B1EFD95405666BDB2966B36C206DF8DC7C2797412602A7603E +C13F0F2FE5747134C666FC26974D7FE913158CBEDA9AD94535099E136A43B962A93F881D +880E205772643F2B60C8BCEC7E4612BF86F9C0FA3A2F13191C1A6C3D50B35D6E07F8ED98 +1B6D2F8DE15FD9709A8E541A0276CCA6542FF3B921CF5A5EB6FA0AFD68A952114C9A3F8E +3B3FF6CFB9EAAB6DBBC62F38461824B3D0831C5E560C6459E6453B629B95F9D2CD117AD6 +E038075BE1D25A833FCB17D3FF657B483AB6CB82FE2AF17EC4AF1FDCC3FD6942A0425826 +3DE038F6D17E3F79404D44819424A2A4C559D44241D5F577FD60A00990FC2D14C271DBA2 +177747C6DE94CBC7C9C72D0459752D7E9680CE0181DBB43180AF135BCEE65DEBE77C1687 +078AB912E9183A60EE6229F6B9ADBA395A5559739C3E29C8B0EB221A036BA888FABE661B +F4D4EE0B4B6D62C5A6C96EF3C57A8B104E14B9DF763CC16B81729D771B557C4CD2191384 +0B40201E52A80869810ACF32FF93C005CD90B15F8628832CC689542A4D4DE58B55B050B8 +3E246BF54510B53218A2C556758FCC89C07E5E7D892AB0B9264529368EF16CC4BD6348B9 +57F2D5AAA98E0F999D4D400E77CBE175D35F004A19AB64F00169769EFE8E7D287A7C024C +A1A0D3F915EFBB25CF9604BBDECDA184C0D81EEB197FFC04B2190687D6086DC57FC08F7F +2DA512C57A3B9CE44115F9A6A7434E203CAB798A8ED7A68D9DEC0919B0B7B334337B652C +34F200CA9C679806B47152B2325AA1D1275B62F78B8610CE4D37F7F7DDD281AE294B7DAB +508AFE5492C4A497DF7D37837D43ED2A3D91C04ABCA7B0F7414A451ED560D20B0164DB0F +227CC753A9CD526F8C57468912A3780F3E9A6D626405FB486F6945AED27C48661FE726AF +EDF3D69BC7ACF0CC657CFFD5347869D16AC4C6ED41F643C9BC981425125B563065DD7963 +22413E1EBADDAA6993AA9629CF048863BB3AAE34B44308D27C48B6F4F9E8E1CE6C471466 +678EE304328CCD8EF1DE777AE28EA758360EE7BE768332794871E18009B99351710E22F1 +83146E57B21C72EB728B83C9BC618904CC0094FDB26814C8667AFA12D26076575D26106B +1407B08EBAB89EEEE0CAF34616054550D610DB759C168E26C08557822B995606459FE74F +1D085225CF359A8092A9175FB03ECA2812D7467622F4F0132EB4B1DC6C40CC969842000C +3DDEDCDCFA0E8CA62B214E34F1051F468224AA8D0867170019FE82F745DB85ACE622A175 +E50A3A371D5580313E08E2BE5A6262A83CF8B6DF0A02F258F81C636D02F381AB20166A5C +AD53633533D61E534CFAB2899BFAC061ED7734EF53E7652C6D56186FC27D54991C8411CD +D2E9D048910765AF119118607413B556016B075BB4245947B9ECB4DE17C38172AF945904 +92630EF8789A3B7D973C9152A4EAA90AE6C984622AAC31DD7952553DB1289CD44C16A3F6 +7FCF7BB135F885F083A539D05DD1128322FBA172737E00842BD674AE3AD8CB68D95004F7 +0EB5E23E04182E56D4E9355FEF193B4606D4C3D6B9275521AC4EE52E7148DE5196E7F84E +A8E19C639D8D20F70EA1D413CE48295B47880A8535F8E0A626E913543AD381A8259FC5FA +593DBE84701260503BFDF27E719A99635B710F44EB5382AC3E6444E6B7C6D5931AD45866 +08F06FD25CFFC918DFB136AE01275EEA017BFD989D0236E7297EAE998B198FD2DCA030A3 +B851EF96074946664C4C12A680DF7A412475EF3E641DE2644A11F9FECF59332241712B76 +4E6F32AA42AB853E51078416EAE47704A0063CDE2E539A46DC16516C1E4680A8B1785BF6 +CFA86A558F74164390C3D35DB0CB7659910B6709393EBF9397920D1CA964859983FB49BF +7DF5472D866E654ED33A10B1726A5F3DA71B93CF1A21AD65ED51DEBE5625236470C49485 +AA53F0271E41C2A20553C67DC3388EB8C51EBF88E533B014FB9CCECD1CE071FEB8353D85 +E89DEDC7AC71C3873601B71CCC7BA3B5988DED9FF85CD350ED374EB8BBF2813854EACAE8 +3460EC71E78B7EFF1EDC8EB3E7AF2764C63760B38F6015B5299A1B1969251CF1E80B8E50 +4EC30439ABD13E9FE242520E37F523A1CE4008A75E490C2D5283F66FF5CEF6A97FE86B78 +4551D1B4BA916A12CD2BF1434FC74F43342297E4E6BC9E0A0C9F54ED31CDF86C93847E27 +B3C4DF7815D96E6DC9E88DF85BB7956FEC3DE7E867765E6986DCF54BE77F07AC3E36F27D +C4C0BCAE8CF485A549534819543CBBF33C6DC3B04766DBC4DBEEE029DF6D7AF91D1170E6 +1F7968397BBFA987A4C4BC74CE816AAC3646A02C8E216BF2CED3FBE06C98AD6C5168A570 +98AFDC8F3D4C59616DBA4D3DD61E7774F6583644B27E85A670EA442C9D575265A892A87D +07583509186E84C57EC343221FCB436F363AF502CB6CE631EC7711DBB3C37FCAD34D110E +B82FF2F7209B3F68EBCA22D918D3FE424215139DC75CA266904FD5F6D40269D39517051D +5B077D26B22F5D3F07CEB35444782EAC7DD819A401590F38571C148EBEA2E682E472DBFA +43103B2183117A9002D04D419A7DB18BE5365FE9F8E2F8498035A992ACC07EE86E1A2AAE +1258DC4B4C6F8D0D930B31FD0EEA876D0D726C7328DC4D5C76B6BEEE6190EB3B650F88D6 +45BC3FB7822F2DB69C2174C93E39A70320B47816BA3E8EA313BBF34C3EE729112A0C9254 +1D09C9BFDB31F939E8D03E31BD3263500F7B92E6072E1A418F7A70112C7C3609799A7203 +3A1809AAA623C58E93213D12DD3A8C37F3E156A7435A42D3AA20E62DC8D4D69BC694DB70 +533729E878603C0CFFEE8D5A4C1A7F29EB6E07799846CC096A8257643A9F85D5CC913E03 +E72C1030636E078D42761C2C3F0E1E84C205B4D8A3D17F63BE4D70ADC45F2DDF2B5121AA +A4AB3D909D1FE0179CF72BDEA0250B110CB4F74648535A1E9BE45A8844EB110F60C490AC +BAA48F32526582B619AF1DCEEA109B7DCCE048996547BE21D4DF519608B5ABDA68ABCDE7 +AADC339F5626E64C93110B21C112E12B5E75F15A8FF5B0DCDFE85A1E2F0968E721C242E0 +4B9543CE6D394F8D00B20A007EDA10672C511445DCD8470ED2413862E6809C15A2E9205D +E522936138B66C44D5BB9B20C908A6CC8D6F6DEDF3568E5EC6672107A24032130CB5D5CC +B8849075CC87FF04B7D8D5370E0294C87D20283B1E6D54679D4E73CBD1D7BE72B992E0C7 +0686C5BC456FC44BD468B6B1BB22D7DACC0FF36C94AC831D391CB9FCADE8F469A5F89414 +B22001501F06BA70414A074A4B7A6A0F2AA2AEA1DAE282C549ED6F656394D187E68940DD +EEAFD5414238578E2A5757134DA9B6730BEDDF727773B2EC1A17E4DEEEA30482475C93BC +484083883EAC5E0D7AA0DAC552FC82F99D6522FEFD818F8023B1F945FB86AB96713B3041 +03F2B5E3913A5D769D5033B2B23D69BB7F21E34B0E808A750A89885CDB2B65B490F7EE6F +DD0A636187F0271C9DA27274A01D4380A02BDECD5D7A5A1AE228C22532838CCA3750A8FF +48D831F27F3712E85B956F03F534D2A478F8F819EDE0071BF9132F78DC0F5B7D578FC0DA +B3BA0CAC5FD186610C32FF89D130E0AB9E9E2980D9069D4AF6EA32E2ABFFE99B09BF4FF6 +588E56A2A87DB9313742A901826BFD2C80526CA519010BC7290C8B3A9F47B917343D0698 +E17565724A7DB1207EBC6B16B449D9E8B67F7CF227AF62815C71E553F644B89ACC4B9EE3 +A8CB7073905DE06FB65E44E0A762AA5D3A109B5A9092658CFD43E64F634BC8C16945DE3C +267546354C88EA3C459AF00C4DA9214692BDA482D65130CB6ACAAA37CFAF3CB336090A42 +E7C67D0961B02F1B2C167726893D18FA3092EA8B2CD553480FCCBCE14BE635D0399225A5 +F65F995B463D640A43FBFD8892A6DD3E0B284455EACD55F2F973023DB12EC59EFAADE85F +55139137DD595514800B235421CCAC9B0CEF4701977406565B494E6AA763FDE3127B2695 +6F0E38CEE9988649FDC62BB0C46DA3D253ED787F2997F0285CF008F7E34586E304AC3AA4 +87316B18797A189483105B0B4F9C96BC191A337667B58678C725BCCC51A5DE3FC6564C2D +35432A453B0E92F550EE81A89AE84B79C3A0E22E6A23D0F2C263660AEE964EA461A40BE5 +8D2B1CEC1CD8342B764DF2A9901F20B0A7B44E5EAB40D3F0A0601794E5B42ECB812AE487 +4B96EFF33C2BA5801A2511B074F335AF4A530880F73F7A4344D22B2A9AAEC85B1D26C878 +201247E53901F4C41CEE45555EEBB174270919C0448DAC16160EB7AE2B09E96ABD9C09AE +B7A95C4B5226D8F3125DD27E6CF0CF6E2A0D5CD6BFB414ABBC6C4A382E5B7F34BF4BBFAB +013F885C4F224147075FDAACA41AF49F4D9034C22B0B9483DE0B075E641B5B3ABDAD073B +0374B79BF3A07FCD45C148C8374401B57421B9B57CCAA25D4C8CC7C9EC5BFAD5879CCC93 +665C1BE2826EBB24893C36F75F9617BE4A54E01FC7A2F52DC845C95AAB9505EE18E370CC +B5F6DFDD80DCDA36A05051C3478022A57E91F4A078F5B486F88C17763C285A2CDB6615BD +62544FBAC5F75939A9153D31ED2CB79ACA1FF6F2483EA35AA9CA0582C2F2DE156E8BEEB7 +EF12CF7453475E7460A3E92DC95BF6189CE2144B23D4FE778E29AD6120B5B93F441D6FFC +0310F8F22E39393A21F342A59688B6C11A66A3AF852AAA03C46A932587AA5D3685A3F4DF +B1B857FB12619686F7FC6C2430B9C24F1311DDBBCFC8FC294D84EF5E99FF22EF6BB4B2D2 +20B301EB713FA8C76EC566A253A5A7DD2323D70FF5B48F2CA57A9D3F94C737326D2CBBD2 +2D7FEE0100D039D28474A64372EEC52C616F800C2CC1B53BA93A18E153CB91E089EF0F12 +318E3A844F017EF68C496477D1EFBED61D215ABE6467563A625FC0563E2A113B6A58C7CA +75ABA028750E3444F6B19DBD850DA52880F3D8B765A8E9310A1F22502BF2ACD7A3E40191 +3A1D8B7B79BA0CD8D85225CC31474CBAF4479834FF184475C7FB6EACCDD0D5F1733FC56B +BFFEA34E08A0B7EC795FBCFD8149E900F00B6E207B6E9464880A5344C309FD2BBBC58D32 +68EF30C36BB5A5C892013E8832BA813AFE822D11B3E3ACFD02CA56421671DA938398F57D +11FD157449D3E423DB6A0A4EBCE845936F542BEB5B31406A6B5C8842783A5E19A6E8FDC7 +94D322239F4866F9EFD89CD88D9FF11C167AA63A9B6707DB1356D757C80623F10B31C661 +FE9D9F118208851FB3DDB8B0DD1937005B15D900B8B854C4571F3A9C1D0D67909E1AA591 +A59B2A45B5D8F481EF7B5DD6D4E6C8CD5FBA9C812F8BEB1C2A6E4BF8F51D7A507D6B6E18 +1991B5D4955FE3210612526CF495CDF2C3CD39A26F4BF6D98DD43C4D407D261C603B837F +E8E09B15F403D721FA990224D46FEA9D7931D4CAFE3181F21B3B47A1D3910913C3110A1A +45EE125EE773556E17EB3BC516E336B2C7733D8FE30FB7C22626BF7D94EDF00FD945EC44 +0D4570B85180A90BC46B280069BBF5B69A3DCEF13EF0F159B07FD5DE0289EAC807EFD6F8 +30A20CFE8DEF807947EC1442EDBC9C32701A9CE873748F33ABE5BBA35A85453DFAFC4CBA +2F01ADE4DECE86290C4DCDFD676DA97B69BAC7A8BD920C4345DDEC907CA183FBDDD2638E +D5432F9188CEA76B10E40260C4A8B559FBC422C41143432EC319E1727E8989EEF94B85A1 +8FE398A4928F6554DA075ECAF0A5B9305580853E010CB59142F847621234B4B7DAC52D86 +151E920633C2951731D4534A174CA7685E8F617EBA01DC1C756F91F8456DE200DD557AA6 +830A506DF674D90871943F822ABAC2867414D3B9D8D410E8BE29C00C7FBFA5B03858146B +DEEB557A662A30F1C858376DFADD19125C60CF5A73C1B4B0BA6B6218F1BAE096C21F004D +8716DBEC943156F291C61FA23F1FC37C20CA2CA6CD42A3A1223CC0DA7ECCC0D4C2604EF5 +796F53C1749E6B5E2E22F52A2BA077D324253BFAD6563AC2F6126B3F94E160D579BD0DE3 +8806C554406E63CC803A83D29E0DDE72B999D345E655899DD0E9873CA47C216C902A7443 +3F54D6D8BB3A716DFA65239FA2AF27DE88A97E521119041FC89312C4B23AC10861590A65 +871B7F0731BF11E3712182E7FD8AC4C94C366E93BE90243B0F5C29201E418CDF3DCD649F +0D9A0C1696B0EDCB31616DB976F4761FD47AFC1872CAE6802FB506DD67737DCC10A658C1 +DA0CD9A920A96E5CECB844A302FF0C312C5D7A8801203EFDED0049FF37E9887132A484C4 +1D332E72A6FCE3C3D48705D86F4187910AEAD72CED404526CDCE1B8A34C91FFE62BCC410 +64663903D557C5CEE087600C09E32C8EB537EA43F56C62E78DA50FD5F598C0FEC55BD912 +BADFA2F5DD75523FB189146F92B31FDF6BCDD1119867C6480B258FB96A916092301679EA +E82FE1D96EE14E382B00484A2F983FA5272B2B86280917EA80DA0449286CE2042B893755 +EC15ADDD93C432CD6989F9B6B8DE2A83A94F2B5FF22CC849DAB24A224DEA14A11BD68F10 +06FA67E62E6507B027F21A940F7E63A09BC9BC5299143AEA8B008665C9EB1F584D7070B2 +FD5B5E0C10FDE0AE740FC6C5FFBC1693FF4D2285D87392FEAC408409016980AAC25D93BA +3C3F5E1F432706E6122FE76519F584F96A552D58855495FE5F0F4919DF8285C668416523 +DA7F2703095BFB3621FE24F6F2C97C073FC5AED60F7A32CDDF72327A1A0D32D58BB98F97 +01FF1F6CE4ACB58F44090E39269DA552D9E242806BBBEE9B65A619728E863896C26AE155 +6CE6915DC42ADB2E3A386FC4CBE64EF8CDD835A84783991F9274DF20FB6B1FEC860E54AD +44F85774FD50E3B7817173C23DD46003BCE91605B7F861666F0774489635F4611060EA85 +8D66ADAA95B2BB066285F485B6CFC8FD3754B01CA01266D27BFD2712F4DECF25AB7FEDB2 +A4455070BB51804379A3D4D184E89B1D1BF94F870800CADAA95FB57B1227F0B691D253D4 +A85EFB1D8D182049259115AD8272544FBD0CD49E7A9F551E22F027272C60A1367CEA64CE +49A07AA8183B4B471D83072DF31DBD739B6F64158165F8941084E880C8CC46F06F3AC420 +B70E97D8A8B3DE6478633FBD016C258DDD12DE9062988CB9CEC82E21D9960971AFBFE9C8 +B2DB92E3F848653BF165A78118962E8DBE219E4FDCD68BA661541B0220B2AA0CAD74284C +8F28AC3E19638A0EB29903E703FC1145A0E9D33584455E5D1FA7BD6A733F8D8AA9AFF447 +583B0176258139CA3757A4FEA374425E9BE34B4683B392B6E334951FDF4E6047077B7011 +39F27A73FD2B4B115D8D408EA5E14636470794941040894AB66F19EFCFE812AB289C3315 +2EB58271E458B257F63715B3C05B454AAA50290F32AD47F089DABB1C480D92D69FF08211 +7C867A731F50E3EC9DA99D966AE570F584494A3A55EFA002D97D3A0EAD08DAD1494E57FD +61EF7BA94C4D0C3E85732A07994726452A69DB3C27DFAFEA6BD6A2D192264E6B4B846A30 +A6BB1625381511EE16BE4CD4D5C7CE332A8524AD748DE4ACC5E08F3167E99F63B785964D +B5871FCE8BB244F5DA0C7F00C5D198B13904D2B57A8399420AC2DF333B638F2A29B2E261 +D447F2AD9EA4F11128EDD65C6524A6B53412A7E92B1F3D7B4F7338A1CEB909357ADB0819 +57C48AD11E96AF967A60638E91B6FEEB4AD90C33F98AD1EA2B51F302B51D6D1ED82DBE81 +3DA68ECE9BD145FA28B7B6A5D6A9F7141439DFDA0E2D59530751F16B010326B54FCEEAEE +2E5644C6F693FECC5AFB1F64CCA65DE08A89584B90D0B6B5C5F4CF75F2C2B1CFD0D32B2B +F7101CE6BAEE7D0E845E975D44FDB3297D0944B9268E367A2608BF4BABFE4142B692CD16 +73AC17BBFB416A37580302558CAC6F7549CD60B75C9B5960A86E050612E9EE6DEAF19EE2 +6219E9C5D28AA076B3FA2504C1523269F093A0E00268E765CEF7DA0DF01AA3DAA12926B1 +A89D9BB8ABEA16CA2D2867790C7553E1E87F8CDA07810A4D94AEFFBC15FBF4D543BE0967 +B11D2FBD221D5BDDAF28718E4042000F5FBC07CD343FC7E6D9A94B8F6E9EB3B02D5BC584 +9AFA37ED5AEFAD28217ED06986DB0F51D4632CC5D1E2A49B950C3666815FB44BD4059294 +7401269A17539E88901FCE325629E59AD0CC15D6C3FF32D2497DC7A9797582D88C7F03CC +F2F230692DD463F4A471540737E6995FC32200E7BDAE53AC1465188312C2FB7B52ED98F9 +FE530B8F1CF8A6675FB9E603F58BE9CAC46585B6D305D888822806BC5FF084210489FB79 +2E511A939E01E69AD152624777EE98EA396DEC7D2C633290FBA60BBC153D9A0C1DC5A269 +740EF5CF4B2879A839932E1C8850D1EF95E8B5A0D719351EFC71D7AEEF92EF29D3C41D90 +86DDA4AAA9735908CFEB590E365B69B2D2FEF8193FB2CB24113859F3BD2E99F01F2B1B4E +080300193B5AB6F7711522EEC833D74A13F8686A6E585E7B6315FA28EA544B4EAE4EF62B +88B781FED5741046AC84484CDD1B670017F0D0D2F19D3EF24E984B14CD052E3B38553850 +6307817BA3938801B9E1D137447D979B5148AC1B822D49059EEB945AEC4DC1EBEC2FF6CD +DFB19A0370A02F9CAA30B6725A6CDCBCA72242B805E6559BFD292668FB5ECE523F0F44E0 +E75D483645B6988AFB0D5E8EC5688CB56B69A7B6A7F160ECC40894BAE45AD555571CC25B +A86E81C5931DC238346DACF3EA05C078D309693F1E812BA249D84F6AD605D073B22AC83A +F2749BF32A32C9115AC414D58A78D96A0F480C706266244B6A668486F54A16973E7A83B6 +36EB03E66507A277958C19D9AD4DE66BEE89B7463731F724DF5650CBE74EC300665131C4 +01BCC4D03891C6ABB61FADEDD7C83D56F35BAD5D731E0B3EA4F9C9A07FE5D3DCE21B5BAA +1C8E79B19E38CD61EB802B2C2F467D1A8129D45788B85C9F7B53232501ABC0768CF3830C +308A87783868ACC346DD0141702B517E5C07B5E29B238E55549F98EC3BBDB67EEC173ACB +0DD4B3550D958C7E777D39F9C21CAA5B51404C28DE12061DCA1CD427089D2AD99D23DF19 +B0729235CA955CBC5E4077A0FFBF3BB64ACF02204B706733BE9CB2EFBFDF21F62E4E7ED9 +34A78E626472A53747557AE2C209324D1F8278E31FF96305F0BB41DB5B165AED08AD9312 +F1FBF368E09C4A4004649E40D578DECB4A1F82EF4EAF76BD8CDA9C4C61EB1E187E7E319E +03EFEF18E4969C5DCAB53D8CF41AF5D4DB3D9CCBE23D1A126CB60B1864DEF1B702995622 +9BDFF2387711F1F06B807841406515B774B970666855333607B4DBEB4B670F6A452AD43D +FA2F83DF711AAEFD9FD74A307335AE574B4097AF88C2B4C928BDBF40F822BA98F7F8CBE6 +26DB9AF8DB0B6A309680C026E9FCAC9A541974056EEA1A0F9F71AF08237DC5FA78D8C38E +5E057DD2812E4591CA207000DD62CFF38CB97C8049B8CFDF0CE6BA900CCC85E02C758C1C +27B00DBC3FDDDE584457C872ED79218368C8D8F36079045A6B9AD62AAD7A53E2ABF1AA60 +4AB15BEEF2736FC7AABED55B17B8E665B58D03CC42F70EEA4AF5F1D82B4EA91ED721C498 +DE4DBFF06C3E58E0350BF931D27189680C68C68D73555F02B76F1A786B4FEAD6D6FF846E +370790C8529BEFE512A8AE178689A55C747FB7603D3F9A4BFC36FE91CF212CCC569CB895 +7680FD2D466A1C057C0022B4972841AE7746C47813AA324519B461AAACCAE87134DAA64F +093742B7B3B691274EA2148071E77E636AE14ECD0CC3C9CC7C18ADB23954FBE043DB23E4 +DA069CDD55E908173D71582A774B57793F5228274CA43C4EC01FE31CE14699656A9EB6AD +9468D7CA25467349B9F56CF2873A09467107F6B9C20147D2095B7294FCBB671EDF0B804D +76F6E1AA7CE9D7CF60CDF7F85AD1C410422A779B908F3E6F6C8571B6FC4F7F012FB99FEB +4292E9F354A3E9DAB81E22D4C75DA3BE9C8868BF2395D815D097010EF8A6A58CC91A6FBA +C59344E785465D4B91F7633D1718D16852CE793825CC4B422EC90C3216999A55400FE0F7 +CDC38A0F6360802991885FEB799FFDB3C1C87C0127CA781A22BFB9AA8A6D6E414DD2C31C +CA6304577E4D617A5388657632349D4F49D1582152E43683200FC465146137FF942F1888 +44975B7A2E508083B0261E8EACC54747310FFA32C00A0DF9B59F77A360349E259D9DB841 +47ED76941E8C8C6F053116A004C3998B7C84D94B60044480D048AB31F355B8F6768C189B +E4A024183988E8C3717BE19D29B4BAA4A94A3624C0DC4F8A7A99121DCC71EA32D2B8D6E3 +B4DAA6B632E8D64717D32CC76C1322BF2FA82D3C349E7FBFAC44BA0304E4AB4A8689D819 +CC3A0DD336BB7E45CA84991DE87CA3C615E3DDED468DC67E402BAFE01E096C61E0BE0645 +AD50A227015278116EAEBF7895E5513E4A811BB90E1D2E204F3E0E656B3F75D25008E84A +9FC4AE44628B7B38A484E23992C2C1EC229EE966480FCEEE199F0892689FA18B489F2C31 +F2F2196620809EF6E0524D99A86C627B053EA195870585D6B3C54C3B55C80E352482998A +2673772C4524BB4467A867FD953C07504C6154201CF96D422D0A3151342FC9C66DE45FD1 +29EEDFC9ADF67374A4C1CD2E76048EA9D4212A32F468E74007A6C3A8251DAAC735228DA0 +5C245346BFB1903F217D62F63087721672EC60B846652D9CE8AA2350919ACB2D8490C6B0 +5B63EC808D611BB1D7AC1CB102AD7350773DC8248384D1FCD72953CE507723529CD4202F +AAA080F519FABBFA48C620A1511A2FCDA8BA96E7784520AE0093AC58623AFCDAF0EEF6B2 +5DC8813512254752576AA9608DBADCA38F319EBF5164C1244FC3B6DF2523D8D8F19D23E3 +53C1C484FA52DA7B8D84D71100B076BC3082DDF29D6A14AE8BBC72B1626F882C1B98EB3D +F31DE2C5174A0AC1E5F2F82EB3CFA93EF6741473DA694CE020EAC6E1EF41636351E12946 +E3BA2B1D0246D059563F2BEDE7A67648AE6CA534F32E52FE7F4F2CC936F9EF70C8EF1597 +A073E36D237BD34A3CA8BAD7D01C54BA5012C690D680158A694D2CC0362B7FFB8A888A39 +F2CB418D7FDEC46B0E5F104A032581415B083A992D6E8CB4D0E9FA93ADDACCE7BA34D919 +9E579DC050DA9032B1C8ACE46D1E2D224556FC0FFDC35FED173D86FFFED1AAE13734D1DA +D2F06EDFC4FD311FC2279A79783B7C56928D5EA6F8FB4560776F99BABD3D228E8C62CCE6 +C06B7A122FC441CC5490C9085C8A469F524403B8ACF9A607651464467DE098CE068FC171 +55ED9489C819F31A3BA4E1EA3C728212D8C40CC1FDA9EC60AED881A93A411592719E4FFF +B035AA8F25B9DA96D536969496A96B05BACF2BF1C7BA6EC50759CE388EB3625683C753E0 +E3383877F4B2F74B1951730F51ACC3B0107B6DAE39AD2B17E78B4194F5C8D162CA37104A +E00F81F7E254B4D1104C01F404F41CEF92CBA628122589CED905CDE34196FE690EDE9CD9 +AEB0B9D7645D051E78CDDC34B58A64308A2CAE739A825F18525688E03E6138F5DA8D8898 +539F5E4BFC1C64DB496A16D9542674AD655EEA6DAB57AE3FD9058532AD0301CA47AD0B4C +6998716CEF388E0B2FAD6D14578958FFA3330E3759FB8EBC2C25C61EF372235135D2853F +CF308CF00441DEB973BB742C7CF4AB0C189B9FAB10C7969777928CC525D9C122781AEFEE +8B82537EB27D7B264F5CC973B096B13C688DA097128CA6467997A5401DCD797F08EBF73F +AFB5EFAE784C63F5D81CB073FA5DDA3B8F78FBCB37AD0CD54514F07C59B6FEDF0C86FC6C +C0C5E03D5B75B147D0EFE4A484A55555F7FB840BC2DDC488A1AE3C26A22A7975C57090C5 +D2A8E484E6E7831AA47BAD43DF7C1D5C92AFE866DCE8E0B81E5D36DAA24FEF28D44C5E67 +18B277E8CED636116EF9EFC5DD3F06241C40F23A6334BD4C7DB7523C565A669C19EF1578 +329B297AE7F4EB69E25EC5F9BA77635BDED28ED33E3D1FCC4EC257E4BAEBE188003E3AC6 +BB930837230D7625415B260E4CAA348690646BD20F33E1022E1926AC163A59CB3BAD761A +CF10756E27B6FF79801478D2B3F1CEA0B64835439C60AA4D861B7C4FF471A169482B751A +C64854226AD0E38528F72B72FD8472D83909464F26AD09804D05D3B6DFAAEFBF0D0AF345 +CE1BD364299B1646141C294AC917E55458DEAFDDF0A9734218D5F5685F0ADDEBE6231377 +006D9E3FB3FEC843050CE2050D818396BA57EBCBA3ACF483A42EAF1C434B35216305BBD3 +F9598DDE9BEE0B47A4B8984849063BA638D97AEF425CE3C5A82F3A4B2CCFCF9711B77599 +32D10869BA44FD4DE4D9EAA863C811DEBE27EB910C265492A45BAA73973E3D8849218608 +0B6285D62F797879D6E118341BBB8AA44D0FE79DD91FD58F988D53AD07C17AE0EDA91C84 +8F2E83031A8BE1569D1E7FF432BDC605E434CD52BDBD52BDFA689A6A52AA4204BBF90ED6 +5A206B03D55B8E275755DD2853D6D944AC74107C3160AD7E87324BE16F5B0D6FC37DC819 +8259AD5C06483BC15F983B4FA914BE907B9AE230E655EB1FBAE374EBFB84553420C34D61 +AB2523A8C838526A9C88A1467E0C27AE1C3DEC1B011D156C8D8C2AEA0B7ABDA324656AB1 +AC7D4F5CEC922426E9D5DCAD965E0D4D0C5F4A223230E157A22DDFA14FFECEB183168421 +CB6462B3109211D59D9F00AE30827E55F27C17A7248446A21F4107973B0BC987919E692E +1F76F7F540F7A4C440597B265290601FCCEF11BAAD4FAF3DDC4AE6218213F42F2BB253BC +E6B0EF2E6C3858988141C626DA7A65D7E48175E4DE032CF76619736AE7BBE01C026A3970 +EC79C5DFE931F076DB5F674C163E5367F03AE6E2E7271B273CE5EF0004D7AE89B63DB32C +0064FE4980ADCDE7357820F5943FF1B2AC49DBA19B2F124F15C7AEED84CA6F15C30A9A39 +3C7D492A0460E2000CDA313E9E420C5F5E47F959CC2329B6F8A1B7B818F0D44A2A176614 +D847F360F445A4168693257AE71D832577FD2E432EFF0E9322B3B4A404EE13501645466F +5CE3B19EA1016D089DF6F96E5377A68592B981E728FE3DFB2449C7F187B3DED6F5DB1D55 +14FAD8DC06D95B6B4377AD1F0BCF7B744EC490328CB734FB1A45506F9B6EA2B85E7CF093 +742CB10D1D5FB7664A9A7DA82C2C2DA07F43A95CDFD02B9EE4D954B2BBDA540689DE8A37 +62219CEDEDE4C78F7E314EB519996C0610ABD85C749012C63973AE84DE4BF8B6B1333024 +BB6E856DE3BED4C890DA1B7612689910607EBC32814DBBDBF179AC0E7C8C0A31B19775EA +14DDC7057CA38E53EE24A11CFF34A4E78672C14B215A8F7B70F3B6231E8C9E2206052580 +902E05AD3FFE970ED2228053898E3EE2605B4D4B364D463F0F3ADECA545BF39E0B14E0E3 +A7E5429E661A9718CC86D935E11FB2DC10FB436AAB75BE0AA27B8480AEA99AE6ACC68698 +7D69781BC4791A2A202B0289BADD16C29FD7A5C7C1146E51B4441F1BB5CBBB04D54C336D +B0AD62057F7F97AF8F7BFFAE47D1BD86D2936B8BABF25E91E41CD8917AAF282949F0D9EB +1D4ED2B89478BC159FD71E7207A65437B20D18144E4BEFA99C89983FBB71240EAAB20E62 +40E63F517EA139D1AC71946470F28E0BC26DFCFDD4533FA5BFC0C663F53C42BBFC16CB96 +8C0E61E2A6C4DB7B688ADD4E2F9D1010FA4B4E8E278236C66C7C1E5FE6B3EF982A970C22 +11006A98ABA967E7BCFA17176463E2509AA6218FE0A7CBEBD9F9151370FCC669EEA0AFA7 +265F498B879C4C94AD02327D680059C8F7A388260D1013DB99887C5BED8A68925C3D9E0D +56335F93A402BE584D1798266F41C5FF3C647DDD2C2D788A7A56C8278303C0E9F20F8595 +4F6B47B79B6CB9C6FC80AE76BABFEC2B750B5ECB267A6866AFC68A51F6FAC54B84B9FDE5 +54165EC7104F5626108754BF07116A75EDE93A35CBE84FE778DC3BD50A8421A959B512D7 +E7881889E5AD2DCAF9CEF64E86A98BF5384D4F341B53CED94D430F3DAEFB506EA693FA23 +6830EC178791B015ABE069A44CE20752334986A43EC06F8ED44B0796FA741F0B18BA5821 +10C4D7C3B9B681047FBCF17DCAE103ADA23C9D41955B2C0DF276D5DEAE83A941E8241B51 +DD9FAC40AE8FA3B9308470CCCE30E17C1C015019E1A69BE8A054194A1190B956F414D473 +DC5605BC7284C0025F01A715D7282736704B3E824BEC160772EA327572384DFFA650A292 +FEF417B2C4B395AF893BCA339134D3BDE3E4A8CE7D76E2556C59D7292003C5487DF76D55 +4549FE9977FDDE5460389F32D5663656528C257C2057EA3EB5D70D20F550824C71DE3212 +32A29241C8BE67ED9540B3F461A001C8F63898DCE28423A3F5CE806DEE0B50E8F5A76C86 +530491F67C48B8683996B6BBF6DBC1666BC6E9B2BF4624701A67B52F792333DC12CC6142 +B2568EBB0ADDD4F9F3443D45204B013E098E62C6ABE0FB14C2158574A7C0B24EDCFE3557 +2C5C30294889CDA3C7C1C67558AA3C05D012F516479DEFCAB7ADB890F9E96E9615634176 +5E8BDD3CA8E85DA76443A538AD530EAEB42E6876FC74AF2B6AC2526F64C8D323B5F5CFC3 +BAE26A4F30D4477EFBDF054BC83513705CE5830AF048CFEBFB4AADDF2E7483A4F1860D18 +7D318914C3622F4EA58942D5527484D2AF2D0AE2DF74A1975268F9ECE82E364F5A3B186E +39A4A10049D6358C044B6B05E9B90217D0A3BC0EBE473DF1A7CE2A4DA8D5648DE7BA58DF +0335B7A4C4DB44B2BC583DF0394BBF14541329B64142B6FF4E37F523DDAFD8C1067DBE8E +4770563B8AE958C26BB51920158795D0A4DE9DDD3C2874A572436749FF5535BDB59E8C83 +E421F605083516551E89A2FE34FB9B4AE55036A3D7ADC71F64281A3C54EAAC2670CB34E2 +AE94E71943719DDD21B8AA335EA3181896301B065FB0519AC8160BF9FE18957E5B72396E +240ED3A9779F04FBEDC858B2DFCA71863A17E73D53958AAC58CED0DD0026D562BE9F395B +49C12C0C29D4B84C28881D17B10F5026F8B208BAA6DA070F94110587A76E00282D3CC5BA +D88C3A9A714C063F8B325495644DCCEC332257733448C50A40DE95BA8E5AD73FBBE404AE +EA1B1F49DE4F9F1770B73ACB5E9CC4B5D1204A97335197B14DCB3DA403DA430EF0C2CB46 +E050B1E17FE0105A619BCAE09A33CA4DD54E84B8568299C1F2EB116C16D54DE40D9880D1 +B2FE45706CF0340CD591FB94B130BF0EEEB3F1EA675B032AA0A780F0E0E69A63E932E01F +43EB43DE97EF02CAD65BD2013569695789971D843DF14DEE9A32A1EF22BAAD4A4468AC40 +588EFF9BF91CE0C09C30DF0E2504AB95E85E70F6769679C12EC83204FF0C5CEC67A26CAE +748F530A80ED96E3C6D28F8F12F5B3A7A53B1BE5B096B0D186784402A3CC1D4EE4162128 +D0FF956979EF79DEEDB9732249CA150D159D1FF502E33E4A305F066A9617BCB637DEB999 +DE15A2DFCF9297E2E93F65D90A233B7F512882AB88439B26B9C672A08EC301262BD37164 +37191838D992F15154E96EA15454E4EE9E9D4C01CE2090120620F5E5A0849036975EDDE7 +9E207B17DFA344C8300D07BF024C89B9621F8FDA10A5032197BA4B6C127FC68C3D1397E2 +88219E9F151363321807084F8596DB0A24A8D6E41732C843C01843A9B4D9C1041D28C7F3 +F4DD289EAE019B6E8A3CA2952A8BFAAE3CFA6F0527BD3CC9544196A0DBBCAE1F095C3674 +B34358049CF212CD96530B9875DE99D93BFF4D87E544C7FF8E79F757ACBFC7DED0A8FB1B +4BD53D1E76FE95E930E3F329DF6310107223E4E576F38CECAEF561B5E95CAAEAD603B792 +F1B1BB7EBE2C73E7144AD8D50F0581AE74C9A811A52E986FB6E249F9290E515639900754 +C8FBF4ABD9F642970190D28CF4BEEFC7C39D1271DE2A357949A69BDC6D8343487BF6BD25 +1C1DBC1132B1FA6FDB4D3233ED570D9310F8C9DD92B7217EEDAE942A25DDD6D5C24BB4F3 +9809C658BCD0CE41C70709AB8899E4956D9615C1A2B1A627E47CCC17DA3454291667EE26 +AF97D99AECD1F7AAA7AEC910734786FC797D819AA8D539D10EE8DEF86E4499010310E241 +C9FCC7F3E2B0FCC692D9B2D8346717A5781E6AACF1A891E2E6E65225F35026AE348E0E16 +7475CE6A9A0C14FB588A483B9483AC475043907935061B48D03677ECFEB8377235E44F7F +581F02557B6F009E964A4C345494EF9EB4427ABF1D2DECCE71A87D55C57ED6E561CFB835 +8C8A38E387531A6D04AA87F5AA92D73B2DF8C972402001B9FA67DADE45F803540AD55272 +AAC3A49F23F910EBEE137F616544F86DC7E33CF672859A545677018279B5D1AB673640DB +4EB45C3049D2BAB6116D34B3CF6A88ADFCA5A657E93C32EF5912DBCE65C9527C068D03D5 +A23A29E934391FB4317CADA46B7CA8A4F0440CACC958028D20197C1F1C0D3CF39F107548 +5928CFC10177DC70FB5133A7ECC5C82C978858DC1CF44A53B4461E85B6591131B19806BE +EB57CF868D200A7F27567F124140D712AC0DF6D6FB8045671207AB0CA4735D4422EE8133 +3E0143072416E707CDEC20286F72E3070E374D79D95CE144AEEC86E6DC9001B991F15CDE +9EE7E8368B4BACF9DBA6E83848E5A3088C2858C71BB5841E990BEF89DE5ED42A6EF9F0B7 +8127DBF344A29104E9272D0ED77B5C32D245B17293C54F8D939E314350B42D95A3A2F4D7 +6FEC437F8CA935638E8558D7919ABD0DBD6323F83AF703B38E8445FDCACC8F1919D2BD4D +808D18FE28285B62FA958B34CFF05150BFC884F0A323F67CBEFB98B393607F500530A1BB +CD2E2C93D25EF97621F872091C13D1BACDCE7DF636FFA29B24C51111E7C10F0FBD250FD7 +0899B2D370B955A7B467F9C726CCA0C1B05938FAB3357BD97FFC32A78589BAD9B54CEB88 +E0C95CDF9387637A043394276D50FD4E6A6170DB7325B11EA2145BAD3643F51114332630 +229198CC4A68C207E61284CE848E0CB6F9F7FB24E72D5D0877F2697F39F7F9F713FE2360 +A199760E993836E477943388D08EF210C1C782E086639B507CA9CD5428FFF902EA82B280 +DD203279043B62ED9C93150CE5D365C3ABB3C353172273AFF2C75BCB68FADEC1964DAABA +777D83401AA12D8B5173796F691D8A2E9BE7FDA49421AB46A014EF1C566B78AA4889C684 +D45B5C9181DCD1B12D4BFCC354454B6A85C4FA25E74D55A1C6CCE8C4FB9ECAAF885BE22C +A5DBE8ECBCF909D4487E6C64DD9B489DF6BF4B1F2A38B7D18983B2E41696D55446FE1261 +11A0940EB96A23142770F5A17CD8D89E85C6CF269F6041B0F32467D1DE4C0335F543CC07 +492BD7BFD0209DFEEE502FEE06D2D0EA9A0F81CD36DBBFA8E386BF486338444DCA97AA8F +83FDC85A8A88A801854C22B3849467A660173E5E81C055E30CDC869B1BB9C367923A3491 +F51197DC9971B477FE060AAC5C91FF8D67677C3B08705254972D8CBB0DB05A10771844A8 +4391AC7B60179F20E345D2C9DFDFE1C42D947DB12F84F1CE05991AB56FE498345230BB3C +7F92A3AF86D20828D86E931BEBC818BE595D2E17D3F9E105E39649E89E13656F9461087A +36E1DB0DCD850BBCD07249227B65E494CE8C88BC106F7CEA5EFE48E482F66F5F6763A766 +0262501535FA5FC71CFA87BFDA2F8FD2BFF0553D2008EBF081BC56BBA010C00081EA5D80 +190C4FFD7A105FE500915F6F652A0A00FF97A7C825E8617077473C38B5D820C24F78E387 +A776A8904C265AE4CABF3D1845011DB66A4D732F842FFD7CA1F5FB53714D0EA9F43AD20D +280FEBA87134571F5405A57094243FB22E12635ADBF0D1900E93684D1D8B5EB04D9D01CE +A3CAD54C9B4666E336DC6EF82DA6915CEC1F11C89E249B0A5C460BE552BFB4AD545CEE0A +3A97B65EEBDE82FA1893442E7446C901C50838934D82DB73DB7780946506B966CA83A142 +5D1A82EA07C3941EB1942325E258A5F39BC9D7B8D84F7AC876C9E47B854BE1D40154A54A +DC42BBB5E5D318A6E8B2B985F2F87F5A2486F261CCB59F171111D04D29E38CCB692F21D4 +E5909148ABDA6CE4FCD577E3EB39D8199C63E1EE22443B0176D84D2EC501F16BD5B01826 +67DCD1C99DF0A8B3F27BEDD2917BB900484171D2AAA6E0B39FED994DEA6FBA6877EF4D94 +F552177A83541F4111D1EAFE83A5D102A011726403648B148DEFD8754E91E52BFA9A5F80 +273475A427EF5C5CA4D981A2D98AA00A4BEAA2779FF342B5EC0A452F860620B88AFBAE3E +1FFC666C05647B3E73CD54BF35FF47411585FC84CFD702FA116EBDEB396AF5D9C298C3CB +BD97E8EE08EAADB0C854F18D2AC5D08771ABBCE5B70895E8F04C3CCC49525BBA4407E081 +62A272E0F623578EF4502FE2DD325DD87021079967B1FD01B95E8A0CC6E65317D947B340 +7B42052106F27ECBF69B431C6D73F9CE9220BE91C38E1AA2F9779E128BDA6A76ADE5AB3E +B9744A6365A95368D5F7C9C297F5AF8C0E21B16FB8B8DDDE4AC3EE393BE599B2B3E3698D +38C84A69DA371E8C323EA53BB232F07A761473580CC3F0CBD5C73FFDAC3BAFBB1D9E7D77 +1CA641EFBB2A190E8DFCDAD040736BE41D29723711CE965926CA4A56C6E4C5FEE60C6634 +C3B3BBE74BB0ACB8BC0FF9C426679D863DC1745AC462037444B6631529D8A8BB22EF605E +53297B146FC90E7A751C5E151545E89281BCBC7271731E5B0362994090B2560A8E62858E +860FF9644008AD601B15FFD2BC3D25D06FA0D78F003AC39D89FE621C1E368BB9221E2C59 +15A56634D5EBB299635F48DFA2BD37431E224E38CED95C183604B9CC3C8B153434D6DBA9 +CA955106159337D2709025F848B5440990957B0F12D416F823A75EA2567DD02849BB9B98 +FD5F32844E8F24ABDE050C333DCD9C9E4DFFD97C22C0045740B6B3E94DD8964F1E601544 +4465655844C809A51B9658EFBBA085489139EBD2344E68FFCAF99BC6C50C68C0C03EC1E4 +0C378E68F1CD3A8C459D732377514B1CF1594627569C16F9441AB05F9B4D7B1A6AF79E5F +E62D1DAAF71234F31509DD947BF67EEBFA0FAD13B794D4292516AB84FB96F5DD8C6D65C6 +0B822B78E917D7BF5BA9F2A4C90D94625B0DD2E31AD0D12EB3AC5F882F72D07F88045B35 +55AF20B6AA3648EFD5CF73798F3CF86B139C909D1D253FDDCF78F0915EF8CEFF7FAD6CD3 +C784BB88B8F31D1DA52FC67500D064DE56C233C333CAFD866D102FAFA71A2B2FCD2715EB +47C5B65909EAFDC5250EDB78FDA4854EF0706F226C1191ED8E1ECD79A43BAF7154547059 +D567146000900625B22D3F7E356DFEBC00D4B6E6C1296A4E4038973B9156D5D748B6C0EF +0B82B459E24670C9A951629E57FA90935E710899C37A5310822E99AD7D7B32018DF94FF0 +E723CDFFDBA6BE5DE8FC147C794E9FBD12D3CC53C5E14A328F6FC6C6FA479A0E0F760253 +899B220E7ACFB537262764F994D680BD4A48F618E7FFE9E92FBB09ADA32A7656B14E53C6 +B43774A908AC61698B44B4FF91D6BBDA42D53DDF348CD277A2A07A0ED439FF4D94F769D7 +6FAFC6F19F7A307927FB233796CA701B40A1C3E93A98703802B5D41F8A57F0D699B7ADEF +AD6D130B06C3D34C8D2414A21C75D4FAD9EEF2791AAF7731033336E141E15CFBCD7C3923 +C663CB78D678F222738BB970C5ABDEC1C983D465F71D8189A9F1A031875460CB9E46FDEE +A4074549FDE7A01F209409850C6848DBD1C9EA058A28D224363CD796F106683166A00DF8 +F5239AE3288F9D0C14E05217849FA07DB6DE17148462C0AC9195FF3C20B76C452DC58273 +3B81BB7526C69124C4AEFC411FBC581C29E01494C28F40A9FA088AA7B727E5C6D8842122 +79BC38AF7593B2A53E8B0FAB585CEF88D5F497727EF2342F89EA4901DD5FC97AFC1BB805 +817AF7C8FB9E1055D8A2DE3DC09C09BB71A999CABB055C4E2600D91BD4A0A6FB2E9066DB +CDAD3FC26D0921B2B9ABDCF99D74CEEDAE954EE6AC80E6AF69EAD98BBF0F14788D973381 +5714B6C0BDA27CB3E7235065ECF910CF27DA939D6354D3CDB120FA8E0E1C28E48445BF7F +06CE9F6867641A9238175665ACA110E8908243CB693C60D369E1C12D39ADCB6350395F6E +7ACBB1FBA75E91D21C141394842D6D107CB412C754C0068DB283EEBF44046213B55C2BC2 +5E403DE803680684F0F5E2054548D3AA52D5EB1F4E8D32279697818359850B50DCAE5559 +B000B4D74C97AD069101159A5FC03C66FD88F44824E0D28681870E6FF118DB32ECD10A88 +1540C1B63BE33ED8EA640F50C47055797C2E6A04BE027BA3A2E8F9344FA48BE1EF0D3A58 +59F9CFF0FDFF085F78712C711D4AEDA295775AD416408D226C4DDDFED69F5FFDDBD3D6BB +590EFE0CBA5404FE99FC4AA90D53FD3CEA35AB8042784717D1EB67529B74825206798862 +08D744892CFE8944B9EDB4452072D39363878167C371C3BE4816955959F7773BB66AB794 +2A2EB43BA482610A388035F9542C3D321BF1B1FFE827812A6C9A2F22B17CE0D04BB34653 +02D0F9331F41370AEA4F1B09AC2AF71F588B250D4B777CE024E9280CFE9EB36D9CADCFBB +4C1BD4CCD1C035B15D736C6F49AC229909BC877036E6F584D4155E0D20AC99E41040AE3A +23A0645A1B3C8C9553840388140AC1B49585231B98797C1C19D483A6E69FF566E6DC0AEC +71807AC1F4D3DBEBB2F4A4F6576DBA8A0B1B8643C9BD1D97A912E90A737268F6A91E0A70 +FEE73DAEED851EDFC631701755AC7B2EA3EC8990EBFB3EEB64B75FF320BA84821750BE74 +F2F2C8097EE95B2402D6F4C31E1BB947A5F86168745F8BE621289CB65BB1AA299214F52F +80950D6AEE089AD94BA4D19B9767B4B3D3CA631DBC1B2A37B3BE026429532E717BCAEF7E +8BCE17D47F40F3665C00A0BD87BB6033CD56FA275BF4BD06CF4F2B0ED24A061064092815 +9D73667E820E4235F1C4E629610A1C260C43774831CD75A5375399644CA9C46BE2F516C6 +7B059743008E82085EC673CCCA702BF07B8A9F57BE338D2D0F8D2FF6090F3AA1BA20A9CF +C02EC2471992118F070FEFD45B3C0FC0B55162490FA9D9DD60A6732532F1AC45A4D5ADA8 +DAD9ED5D24080E2C94F6A30ACAB0F075A50EC19544623D14A5A9A783A61A75D6F6E6249B +7B4AD8EDDD1154ECCA8ACA427736DB27758A0D7AD3F79745FAEF53B171D96FC735281986 +C4214ED6754154011F4D0B1BF910142DA99D3BAFC74D8F2BFED52422BEAA5DE0BD18538F +1C8CA315FBE5510954227B90718FB84785E0ECD9243B7C991690D2A7ED913E5080A15D27 +927BF869EB1279474726B8317FBF9B77774B2A97C294D56D02C40087DAF596AC35C2BDBE +CE3CC534DC34CB2042F85F686F4FF4098890439464D56CD011FCB85BA87C6B51E9C0ABCC +EB9A96152F5137E6590DE02C9E9C24D133FF585394FC59779F64E1AEBED7A007A269482E +E8943604DD95A632EF16B0888DD6080EEDAFE8F386E05427DA25E6D15E38BAC599A57266 +C416F20DB2B81BFB7AF0F10223DF1E760C2B3EF6EC37AC447833E8220604CB3643CD2CE9 +53FD9E2D22F6053A7780F79DD161807B661E196C77DFED2AAA7ED10253943A7FA2C25602 +3586BF0508910EA8C688036557439C183A1E9B9165DC2BF055E58DDB25672E7E701B3CCA +056B592AE84DA9278C95328EEDECA8E7A4FB521D3646F3195D9A21517DF98B334AE2E201 +BC4D0D3162B6D0F53F801263DB7AB69F1D2998038804A2A8E96E588853D7BF448C3DED2F +CCB995EBD6520A2C6FED07E13EE3E546FFAC962C6C30F570B8BDE1ED758550150515C927 +2C6760A12A097D07A6A8AC10C5FBB66E29BF85A74AB804A6CC99FE01946620D14C3B8B6F +FEB0C74E4EA1A225D5B9B5DD45389FCFCBAE9D45AD3C7F3E875C0FAB231F7902B5C860F0 +2B4A13B39AE999E051B7B8D05BBED72B29ABF13ECC485FC1EBF0DCE452ECCFE6F230B2E6 +B778E45197B80EE42F4ED63DAAA570C4ABF8CE4B30AF7B694B70780F96BC9742F7F1D3CE +66AD5E473D8CD8002A436B078918949013B721329F9A931DF6F084FA5FB7C66BA81B6980 +0CC79452F5EE2991BFA84EA8689A5B7D20AEE04B0E5B0FFC03B8D8D1DF4F1D3FA29BD6F5 +433809C897B31F184AD02C8E9FEEFCA647EACE79EEA1DB444269C3F88EBB896B2A81995E +9030FD059C48589B1FECD0F98490152F1A1CCA7929F19951D345E342A805FE72B4A1B4BF +F2730AA22A41D1E07A890AA61F2B9B6607191C92D052A673B15FD49145611AF6754E4F32 +C12533BCF702626D7F1E44A7D7150640F09819CEAA1C0A2E2E8FCC3CB262CF29232A38B7 +F0EF66086AC8197B5226C5D69A6F57F16733BEC14D8E7A47509BE951DF1B810CCF6932FF +4DC57D208B13AB86C0E22569A6C11661C91711C35C61BDB6268C82E08AC53589A13FFB3C +F5EDBEC7E7A41CB81401DF66295606B544A9DF4924416423D6732B4631EB73266E370083 +16D0DA6106AC038C1406A5B6F8639BE3EE6C880F9DDE71085C6446F9F2815E2A6ADFCA93 +5A7BFDF4D5AFD5CC7C8C487D57B090A5CB7A7712E207FA7000E39CCB41AABB32923D5E1B +C8D7F2C05D9A3FFDAE5AB0BBA940A8A25114CE99B207FC2DB264D44472B188C5CB9F41C1 +913B880EF8108348BEB174712B2FC1192F37175C5060C9B1F63F729A4E94D0DA524E2DDC +ED8C1F460B782DC62F4C23C6C0FDDCFFA7E2F918CF417C2A4ADDDE53381F65E3DB52D291 +C72998809B59818B71BF922A04C053E2921679838CF482AC654E982A60D2C097C4A5B134 +34657AA08F5568536FFD2574AA4A88873C762371971480ABF1290A05AFDDF9C072DD721D +EF36CACA75F4AA4E28F965AC02A54735E167A7DABF06ABD1FB339E34848F1CEAE16D4744 +0107AD4A526B99C6396BDC4426B858BB7FE38037F46E180E3F8108C79E457904E0AA9BFF +6D3E9B2A89D3F40ACC279C87F0A1DA1245AC6E766F7FF56A7F7DB7352673036D8162CB5F +C666B6F2E944E19F78EF0B87EFAEFF4209A5F83A563A6954873F88B2CB402462804E2850 +C1C5379CF747707E54B6FE28163C31E581B5951E1A12169B1496CFFD8D862FE0126A0460 +7435B53E7E1453255BC1BF14B67D8275CE9DD068529E5314A28087EA792E841448B2720B +FCAC76DBA06A85D1FFA731D06757170CFA16D6758D5E371655C64747E1FBEFDA27115923 +C701004B5E38E32E4E9FFC294639B67A0A8BBB44D6050AD78A41747910AB112CC7D995CF +004B43B8C0AE28049672D0591392A2EF95A8021F2AB281DA86EC270D683060B8D9D6127A +CD4D5900209C117295822A9963D86D5B85D66E4502E5D2E03DF43DF5A162F502C454E971 +09A24B58B9BD864D5E11F8818811AAF0FE432527F897C7B9B1853DD7E73250BDC414A83A +85C6916FA701AB3B71AF0AA8429DB2A9F85BA74E49DDCAC5174C927F28C1970D0FCFF89B +ED30E83163D21EE4741659EBD12F2FDDC934E812ABF1A0A0CD1D2AF47DF045BF6C6CC15B +4E61D058650AAAB48CB9027757EBB21398C5899AB5876F13E23655A7AB3C19AB2D3BD7AE +55F808B6F4409012629F99A24FA15581F9EAB68177DD80DF8A78F0440E5FDDDE882A0976 +076F1B708C63FECE076193E53934681157F1EEAE0DB94A68289A3963775E0793C3FE3862 +9A6D3161E25A76A5CC1017884136E801A9EC1958AEAEEEB543BEE46B55FACAFC0A8B0814 +9121CFDAEDF975B4722D7EAC6768779DE79D4031D42622D3B2EC0A8DB5BB117DE455F37C +7E5A948088828127F042301446E89F67A6748440460844A5DACD816D728B00C725C771EA +647896AC27708EC7F9C858CD6E5264BA8DE4D1B2662CD161C0099FFA627070C7A228BE5B +F38052CFE6640BD91780ACB62158ED53E83CB21BB2DD3C2C40B70CAA21FCFF4BD6F07220 +67A644BE891798B0FCEB7FC5365ED584349903AE4BE36990F66113C3E3E2A12A2B822A5B +D334342AAA886A4C3460598A6D2C6C120369E27F5D8DC14D2C79C7B5215F0D6D0D7D7F69 +AD2A561C66C113DF9F60548A6725826E9C508BA07AAB59F3BFCC74D70D3D00546745392E +FDF15D348F0A5E36AD6C250CDD7D4AC53DD79991F36631371908BB9CDCF2089F4E37EF58 +E9A5AA78F3896AB9769C510A5965BFA79E40083388A56649126390F24312A4AC2D05C2B9 +A5CAA54F62628212354D6EFA8875F4B424732598FD8ADD1DA5459243D233D95F8840D51F +93847579566AE17644FCC7165E551BB9BFE7666E02F77CAE781D41D2EAD5388553E06363 +99653C07C45F603D6C017AC9DAAFA14339F25210A4A91DEC0DDED2501D38C15AD3371153 +CE2CB9E7A77DFA80BBAED85CD46D3495AF1D3BA9246885CCAB880908970E87B0BBAB6447 +A611956A2614BB89323FE3546868CD7C558C0BE2DF1F3649C0190BBDD38C8168DC698555 +2E913FA8BEC47F2ADA8211F4FC25EA75F5BF578FADF6707F051A0DDE5CC99C83DE55EAB3 +D81F40A05370B3609A9EE133982CAECB4108661833572E5360D31CB29916146F3D43C127 +E1DD71CA9413C462AEF379BAAC990E9C3BCF2C22E90F15AE7CF1DC3C52A44894E123881D +B6396ABA0C77AA2EA0BBD78C7312C9B9FC36271B058DAD3F57C44F57CB825908CB62B3A5 +CE1BA60AD20892AA2A559C53E8A883E9F9CBBA38D13E8E71A8C008861454A58087E729F1 +C50723854AE1F620D3E2D716697529BF345A269ADC240B8EB1593604E08A12E8C184EA2D +A26B206A5643EF0071D752A3D4982A507246F237880919ECE1538E34EFBB9D991129B948 +A0D37A10321F792A35C6602F5191D34100396E0E89C0CD41CF82D1A3E55FBF6575DC08EF +59485DDB2F33B1689738ECA78A59501F8A838D3BB960C025617D8C50855F31044D02F076 +8B5B1E6058737389AEC850E66C6F478F96C5C1D2F451841C30D6C1EFFC5B780D26A3BB24 +AA555A045DE634041EAE5F0572AB927AFA68877A77FF3AE277505B133BEF87C2899DD7CF +A9275F03B6B8461DD1791D0B0558E2E7A36295DAC3CAF878BC670E6B005FA34E78938F50 +DE3B75424769ADD07717737AB4E965A9565C1459C3197B545A64A5F22F7F3BC0A0641122 +85134DF7405EB961B367250242455D9896F92FD1B784AF5DF40C408B0F30A4689168029D +B522BFBE784FBCADE1D1301EACB5EB09DE63E20D5B313D2D04DE931862F08309633401FD +2117426434AB74A5A8480F6F9466E93FED5AF4DF1B3C81E5ED77DA855D1DCC9803DBFBEF +79994E045DCFA6FAF3BF1DEA57EB30FCFD0BE7A17855D82DEE77AD5F61C08DFF00958DFF +B5604F75DC8CC24623F582BCD220CDFE0D340A1C476D09289C5213DD812A0BAEAA492E8E +AF3436C2D490FB5104DF3139BA8D5DC7AF08BD1C9517206FCC738B626C3E29E590E2883C +30A4C745F59E54463086B20B76628FA4DD6E295144B43C87311DD11B559472034543C376 +65CD9B874ACEF7028F342E2B34CA04260ABF8C8E6193A64B94B6E1EA6DB6AC39FF3EC27D +A41A460DB7FB38555E272E1CDB792E682E887EB5C5AC5C0D4037C2BEE840A825AE864D34 +B205B65BA9E9B4D07A16FD1D285EB96E172E89A1024E5C0BEAAF1E37861ABE6767B98CDB +50C786E66AFC82AC474391C08F1FD549FAD7401F72E04B3A9A6C52C1B697E9D4E3E33122 +EEE5D0C72B03CCE96FC3D26966FC06C9BA4B7B838076796DC95CFA3FC222B3097C43BEE6 +251843EC7E8C81377481BA2C5F77C47C2BBC53FCBD8305C557C2FF07B9CEA70184E9DB31 +98CD10E6D6B9D3ECFF62AE429193DF88CF2A6548766C2DDAD04C3062D17BD5F4AE274043 +07735A6DD95F65E3CB850883474E57A0376F867507756D7FA74D0ABC7AC4ADD08E0AEF53 +39B613F64A33F92ED360B7C0A65F8F81290408D0B8752B7C03796629304BB83A455D51B7 +4C89ECDA38CBE83C5FFC54A7E5CAF3E2636865BEB3D6092CB7E4EFE6B13F710988F1B492 +9F4EA0676EA6B8495DF63F8BCFFCD47EE238221BA37F1C53B40A20D70347145DD5A04858 +4F1B55173B2808416CA7BDDA7775DC4F208742F7DE0382C97916342A192E47D3BE4454E6 +A2F80C8B72550D55E9B463299A2008334589CD4B5C19FD948BE6F9991EB7988F004E3BB4 +EDCFFD47BCF21276935650AACC3169B54109D8C02EE11D3B2670A7CD006DBC704EAD9F5D +3D1678C93199034AC92DD1959D25423A135441DAB773A78739663959C3AF3BE598102B4B +504DE19444E3BBACD584E15F6BB0D6AAC894FE5F86999096DF225232AA65B122511D3D0C +6AF2A7B25273CDCE5F4791416BD85DF4841C49ED8179DAA39FBE9E8A5D0A1BE58D67A0CD +CED550F9E02274A337EED7DFA9C3E23AB6AFF8F782AB4DBA173D8D0DF5A687070A4F8782 +DEFAC64D97487B10BB114338A16A081C64853076AB441E0598135A79028847D19229E650 +E96257DA27FA1C78F42302D996744BD5DDCAD26FD13F21B2D31ADD3878493ECDEDF6A257 +CA47BB5203286AD59910C8BE7604244C6E0041F3AC99029A5C61CF29A105FE4572BDBD01 +8B55B411B4CED2FB4F793F842CE40F2F8D07D8E10E79587970FD254F4106278DC7FC6E86 +6D7A1729C01D612A7FF65A63CF1C27CC79AA57699B0188285F474BA5BE90322DA6F653ED +3BD73542F9557352A042731F7448ECC6F931218E6B25ABC903E201F61BF1A7796135506A +DC2091CC49E8776202498C3C779C5A0DAA64C92D65FD3002E359062E1051FEC9DD47DDB2 +08AC3EC609544FC692BC2638E17AE95601E0153EEEAF7FF294CAB662116B455AEFA27744 +FA0AE2C7274442ED99491738BF4E832BD2991C59C2D94665FB6FE9EDD8BBD65EB2936F9F +8855722E84B50DD6EE83331138EF9779751C13E8757A54DDEE891507D2D00289B8667C6E +D9DF722391C9A4C7BBC146C735253EFC8E7B436134CEC60EE2ABC2F999EAF00352F141F6 +B3203DFD0FCEEF69B74CC180714A56B020B8832D291F17398E5B219300AB472699C5FFA8 +45878442020D780E1F2DD784AD116221769CB0C92A8B9864D646FC6DE853C19AFA0C9034 +6AAA5ECF81394BAB6F82035CF59E4CECA428E4D9513C5DE593D9B2A9EA127510CC68B5E8 +43A17803AC404DDDAC646E6E73C63C63001DA49CEDB5630B2E5A4231CD3F21DCABE8B3A0 +3ED509459FFFFB2457F1D5608E09448CA76E516407057805B82CAEE2B5FDF19BA480D93A +396EFE8199D04CF81E08E979C2C84EAEBC3CAD9DCF81189FF9A1ACF3FC19A88B30020EAD +5DE7A2EB7804FA0DA9BF71A339C3A304F51E47F11F9F0F754B04473A3ACADF6FFF079CD6 +C6F6B58A4BD5B340AADACEFDD5140B637EB3209BF8FB72B493643CFAF4900AAFC63A4EAF +D7B9A4A241ED10FC7CA1490304E2DDE4B22354B33253B41438CEDFA00E5146648B219E4C +E22D7BEA2EFA6A063DC8B1772371E3698C243C48CA4705352C3996DA94B1258B79C0B4D9 +63E69A95DD8318CBCB338354B91AF6852EE956A28F0DE835004D7F96C0E149DE50241951 +0621F7317209D1E1FD2172242E4B079FE328941BB0720194EFB48EAA04E59196EE8611D3 +325D1C12A3947C9E8453042F5F6F4B7B381BBDD7D927A8FABE70AE7282291265E7AEA516 +8E8D1BA24C71653323E26AA6344BC0D9F1717255E81D4C6A8B4AEE128C71F228D5775ED8 +257434AA754C770309C9FD1E8D1B69A12A78A726C80A9F74136FEE214D9EA87DD2E07F79 +53C78272BC75F22F54BA647413B5500051159EFC793BF1F44A6B8053414A331AE9AD43C2 +9AB2FDFA1107242078E6B581EA6DB98A73EDFB2AB8D733A91F8137C92E27ABB2ADBDF87D +E8B9086A12D3D9F7F5CD98D8393FD4D55F8FB26E849373C89C5FBE982C59A13FD4C655D0 +DD98A9056D4F4C36CF1611CE5B1931F38077D845F1D0CB9A32FA9E9560F3DE0D90B922E8 +EDCFF38CE0F00B53894EDE37276432C4786665233C4B72A2E770C1A6B137EBCD8275F64D +F1C19140C3A4186408993F112C44EAF2EB0D97FAD7503835AD56965D66B85B037984B561 +B125093AAECF14B8240026FD89389E6B1485C76EF24B838E1E67ACE175054E8EB18DAC7B +9FE59483EDB1EF741098E13D72AE7C263A8102336E6AA6492DF4C098FEF95D7B73F90CCD +3A77ECCD01816353DC819A90AEC7F58CB524B91D861D24DC8565ED19C3E44B91F6FB76C6 +E34B107A33EEA9BA30E8046DA880C4F6C7A5C3E58E45B4061E400F12F63219DB2DB438DE +57CB2ADEA50CE263FAAB683A5F993657C38A7301C8F0971A258465A2A03915341AF17D89 +B60A4A6E35153F4089E7394EBE36F3FA0E52D561C6954E60080A4CD4BC3DCB8C38E2F835 +A4F7EE9D8CC16A8FB6F205B4B9B9052517956A19D11038ABCBC28ADAED8AF15A274F634B +D4EE6FA279A872A087A53486CE9F0230F464B877E9CF8002765094E2E3B08F2F479F311A +A80699980FBD99914C09E6677161DACAE71884A21BB600BEB151D1698CBCB8F3C4CA9222 +8BEC63501DA8BD9819EB03006A427402FBC8C702E9F8CF2B0DCDC7BFCF0A5081A47BE7F6 +56366881FE8FB14E160E786A080B98A9CC17E0B52F93E31EAEAC7AF0FA0379C64F7EFC69 +5B80F3EBEB7745F3FABFCF0B4FA1AA56CFC3485B50C09783DE242F277D1054891CD9E78D +C67525BC2308F66F9CA11AA6AD31D48C3FE3FF0346ECD3648F803C50B86DAC19B0DD85DD +D09CA881CE34034530BBD51EB6075147CF0077AEC54690677B17334DE7DE56AFDFAA80A3 +D8F9700A9DB28A760C5DABFF102D5138EAD1E697D050D4BB9E6DDD28F0D2C669F0713049 +29534D421413BC278180F1172594DEE9DDBF4BACE639DBD04EA2497A4E72032C5C981038 +7749BA925E3E46CA02CCF1AC8C2931D1F538EED1B3B725C6C4AAC7D65DB7DFA4F86257D2 +69BA6B0CA4902214C3A37D0D2DD45E2427599F3C55FD813840A251F96DEF09C7E72D7007 +59A90A9F65B1DC63CB2020CEC0BCC6C54F428B8AEBC5FBA51EDEF53D88378F012C780D7F +A904DF1DA8B7148308BF2175B11B83281E132FB20AF80ACACB781EEB48894FE148F5FA96 +3AAECF094DB605BE46AE4EECDB1B8C1C64308F6F21239596B12DF0CFA846A09810F803BC +BA672B89004AD755D201D19CEBA6C99873EEDEC4929078513912D0815566BCBE3994F345 +68151B5B3375936A8825CA58392851D1A873DFC8BA308C58AC1F9EDBEAFAFDEE682C071A +BA64798C8486AF1510073C04773B4CDF2B77C3C4E3A3EC365FC4E08FC93B116F8F183947 +28029EE89EEC18724AC9D36A2BE1428D90F85557C4D2AD1442855DE6CF1D06C0BA192F79 +2D08D3AD3FB804AF6B68B3885556ADB4A4D11CC336B1B998344083129C66446868CB7657 +E8946E25AC33ADD0BD39D1D3396FA15B344B4BBA42C4F6265BA738A58FA31AFEA589A025 +428664B136A771A9B63606A6E63A29376255DDF52E89C2336454C3452110A4D0C73A27BD +D2A47D47744A3B9A4B84BC63349FF5C75A6CE2010E70B24A053C9BC8DB1089F4CB4047F0 +D102860A352BD4F0E9B2FE00C730CA3620434DBBB5180092CED4F7CBB8021E705F4C13BC +759B366A4D054B804EA3A8A9604674EC0DB26E93112CB244FEB1DA9CF920CB24DF6A0E7D +7F3B117B9E62ACAE126303EDFEACD893A8947CC822D84757FDD6460A0A344E31D1E8FE98 +FACAAFB39C49EEFDF56DD8014572563FBD5527097CC805E6B03066A81E6120337F83D1C7 +BAE66253655316248F0CE35FBD61A2372D7B8A1573D34211AD49C592716566EAFA3FFB23 +50B54A4FD1521FFB1DE011FCD82792B93D87788F8409AFD40C7448DF74CAB5343D62C534 +26F0120A12C601E35C4A17788FA6086B3B4C7C70F1043198C61E3EA717533971E8F78E56 +17C84A3B5EE522B4C7C33FB5F1B93089EE7EC6D3FA90EB7C886D04116C3C0947FC5F3B85 +45636538CBCAA1DDBA880A0D5A30FFFB07401B25CA5572D41426D4A6D98F3EE01AC1BFE6 +D40C58F4A2413631E59140F65AEBC0990A76BE20C2996D00053F353945CEC87AB8970B88 +20DF8527A018548EEBC55906E04B0A3A498877B2D1ABAEC069260F05541301AAFB158200 +DCD67355FC73930DD4B47DE9ED0501CE7E38823203CE6D714E5501DE6C9922187592236C +E424564D6FA776E1EABC1000B2A854D06860F6ED7668C4D5DB5CABF4E89D9E05166CDCBE +D679B2E1645790F968D0F12843561B95FC90B8CD75EE2D053CBAE61E215082E5609C1146 +32C8B81CF298E477C0427D4CC68E6FCDB88393BE8520CA93DF1E3B519980FB3523BB18B1 +99F1626457857CF7641AC66E257634B349B2D5A8728DD02A890391BF2EF8C6358E4BEFE1 +6A214068AA175A1E7FF734960FDDC28989AED8261D18B4D996372FDF4788AED732041886 +24521DBEB9985BECDA0A6CE64DEC42A2539CCD4F55323057B8AD70BBD5B05872B864FFFF +2D627668ACC1D8D1908C1E3E2C76D45DD2058C717C02D279B0AC4B2E526C657FF7C5DEB5 +3538D1B2116AAA957A6B16F0CF83430395996462F8183F71041D543C330183A941CC5E37 +8C348ADA81F946090676425EDD0EAD6EA996CBBDBF83B606D78B08684BBEBCFFED1D0875 +6CF352F872A71DFEB693608F24E3F4D663E53661B35A0BBEB3B630489FBEA39BCD26BB90 +0923FC711CDA89442435FE3A491FA23170B6223A577282C24FB7E895E2A0715D2B78F20F +F1F9B06AA9D754FBB32CBBBA06663C59B7A8B22E666B26F2B9D8C55179953581E756BEBB +82CB10E21A7F590C6569324ECC4C34DB4BFD9EFA84897068199ED8344A438A1FFA475534 +0EEB53B8E087515ABA25BA2B1414EE4F86E257387D4C0C7D010888AEF962069C57450925 +6C3F0625BFD6909356DD62C01875C69204C843E6BA873049D72ACEFBCD9106FD45B8E9B9 +8CED3AE42ADAE6A7BEFE925BF6421E88540D9E599CCBFB9E8DED2C5DE0B7AC4B331EAD42 +DEE8EDC35312B1062CAECCBC903CEB8F67897BEC2305B6C333FB766D92C6CDBD77CB4F31 +F63AE1C04A249361D2EF6E0BAAEB7FA3B87E0BE0E1E50C1F480AEE2DD2B6B4D7DD89A020 +8C9B43ED6F46F3883AB7E53869E3C2ED3DB0DBB1A05B1629E48B3D7F420F02FDA6B1CBB9 +3DEF237CDE1F7BD8C80AC7AE5388C30335378E0E374D0C41EB824BAF001A4C47C399F301 +13B442A2C1B27EC161CF528FC2B256579E3C96AD5F4575454449B3B5E1CBDB300A364C7E +6675B6B924B48E58A0629E729941C3830D23968002C56F84F53CF124E771FC83CCAA3363 +5A130FD70D9422B524BEBC6FFF2369A71DAABD932B9D4ABEE240F07A4DE04C280D9CDC39 +A52D9B09799279368965C40C32771BCBA0EA9BFD488BFC3D154B8E421391BC7081D27262 +B40B8B953C02432B8074CE466299EE8BA9A0BF0D47F797EB5A8300B1E80EB44EA0C0D51F +8577BBEFE06C2C31199B4B4483BDBC10B9821B7CBCCA73E4A96932ACB5DFA52B2F3F346A +444EED0B3B0E81E8B65867CAEC517B99B84F574AB31FFABC2E0DA312F12E549436538E9C +82417153110E8060C80101B8AB8955FBC6FCB64499BC6AA18EB6DFB9406304B2FA5A003A +650C15B78EF641381F9A474623E69167793F9896DC82AC4A01FE4E267E9713507AB69A60 +DA690E3F3031CB836256B21FC26BE0B340FBB84AFA550F7ED8C3D0DAB80AA2FEC258477D +6576F86E6D8FFB91F99917A1EFD4902BC12AECE66A5EBCC6585ADE4D96CDF5A78D10EED9 +4D543079A9F60B3650D17C81748189C5A1859982574E1E821E943AD2C59000D8CE586E64 +178DECF669143E9D12131FA2AB2516A3472C7B41DBE5E8D2812FC7DBBC2415055EC1EE77 +A1BC7FAEC22051FDFA79F47C5D511C3F55DEC0369CE994D574299A9E3AB915935C654D71 +F3FD4988F5265EB95349304260ACFB633722F5AE8F43D3EF4ED5A0D333AB72ED10C1BCDF +30A2C85CA9A4B10DF95613BB465C2757CD153E81A1CB4B6D6B7A723BF5FBDB791B38E900 +EE8CA0F36399A767FEEB1C239880F13643BFF60481776C3856A033436C14768B09134DD7 +2C79C88DB4A5E7AF3F76B4806DFA232841268CE4D3D6D8FCF5820EC52B713C9ECAF0320A +5E94C45E93A785D5F4DB8E5A1F43BB8AF4218EBC91BF88D10311EC6812F42BDAB8BA486E +77AB14763C2E489EED940D934AEB3840BDEDCB9307830202AD02B3E7E27E0358F8502DD0 +F01935DFA95F69B68F5CD4F90ED84AD59DEF5E62508CE3A5AF67B2FFE39D37C59E5251AB +5E26C96C0B08D593BDB3F7ED93F9BFAA609723BF87BA135847B8535611C5E4EA0BD324F8 +3B38289C3C5D54713A58DE72FADFB4B89E7F4C40261C1779B97CB9F9570530D5943A00EF +FE435F5541AA079CC0E8452EF366D9DC18B0A6A0454FF9AFF47957973F77B9806373C9A3 +D048558F532788AECECD659B8B2751958B3F454011DB88F3BEB0D50053DC70B0244AC1FD +20D70C444E1CB00399EC559D6A2513DBFC001689156FB89CCEDC3EA3C9B70BF2FDB3A1C0 +9CF814E7F1332B7C752DA6B2910663D3E0AB53E89A236ED66418A280FB4A561DF005B08F +885D58BEF1429418D81F67A00403D87E16519FACA45298D16ECD5CE1839D3BDBCD784710 +8622BCFBCE4C100602211E6762998BE4F6F211EB916468F587A4DCFCC2030FA5FCFE8018 +1299E339E35ECDC494D4314368270D837927C46EDC1299FA541480A07F085D583F2B9390 +EF3B4A2A8ECA8B28648D8132A0D5B37E353731056BAC85AE7491369809C4A06ED7B0CB7D +BB71404D67DCEADEF47603F7C1A3337AC93CA5510F022893466AF4C74C24428275C44E23 +0FFA5972C9D36359FCE3899A3D60EF63920F154DD39CCE56BA57E540C1A3497B3EFE96A5 +EEAEE028AC28D81A541F833A62C8F7AC492BF304C632A023C7A170F8B3ECAA4284CD01A5 +6F74B4A41F1FD464BF46C890325D17CF9C8ADB8AACDD9CCA20015374111DACDA8744BE20 +DD6C99E09B51AB2287016DD65383E8918B5557B78578CECCA7EAEFF8E9BE9E1B13A24613 +C953C5BB45BB74A5A935F32E708927D5FDC1805B5EB9745D35654E25BA50FBBD7DB58D7D +6F70E102C640B771CAF3C1C138AA9A828E79F377A1FC8913012E5547D3602B22B4C365DF +269CBE55BC4AA79FABC53F01EE7D809481DDD3EE602A7266B7280DAFDC68259CBA490414 +84E4EADF0F8E4CEA8A8CFF260B8F4C9C5A3F2ED699B4CC72DADF932F844E65C1BD385CC0 +F2EF81820D16CBD8CE2B27ACEC225FD1DB77723EA0F03B1CF07630B907C7494EB4CAA725 +18144B1E15B0B34E8F3890269BAFCAF6DF4EDF3861ECB5266C285085BF4E1C6FC0FBA7A2 +6504467B734692FC2C9797D1B6536FD42314CB0FBDC0B104EBCA6539F47A97E1C8974876 +9BF5EC71AF381DBAF9016B5A794EF38776FD9F811F31EB98010FB1FCBBF23A00794E2FC5 +9637254DF49FB9C0F459FDFA0AB0C8C040AD780D6CF3C9173472B8A6F041D3B30720C1C0 +324B977866A3F892FE9A12DE84A6F0D723ADC584A17C055F07F4BEC7486D6B064885E410 +B48509BBD815C3BC2D57F23515AC82551CE3D334424F3456944460013BC5B7B43AB19D7A +62C9C2431CAB250705DDA8CD0395FC754AF7E0B10BEC12EF69100A831CEB62F5C016142C +32B8A41F852F57BA1DF144C2A534C06559BA009A92E345305589796697EF28E097DC06FB +8465A9DBDE8F5C38BD9D0EFFC3712F9F070F1FD50BF691811F94E12F26D47AC350C01C96 +BDC13416E1272D457AD210AFD2822408337E8BA7E63FF468AE68983966BDE984F4894F2A +47E982E29C6855351180079ED4E9D53912764533F5EE35A93B31A4885855A31DCC719522 +8D266F9C539DF45036A97F920B717D08ECF274B66EBA30E223A49D67975E8962F617C107 +23261A6FA71061BF91EDC235B9288E4D856FF764A5E65AAA044865D0666523B24CA1AA3F +87A58577ADE42B6DD75960840BBE46C584818A5C7E4E0FC13D41E9E1062BF50260E86A39 +09C5C59BE2E8301ED90C22A42CD5DCC436AF0A0E8987853B1FBF316986DCF54BCE866D05 +1992116762A7E54B08DB4E6126604B30F6D304E3D1B8FC6E602E11D791648C024661CE90 +7A6808EEBC6E3E2C0CFF9A9C6DE679F7E0246CFAB927F1D1A642958267645432FD9861D4 +92DE7CD99824C0A7D93A27F279C0D9919E4D14BC0855F4B562447974B2ECD1171B848D17 +8216047A6834390D7704EB2D6B16EC16A478C69AAD1A4F766FDB6D609628AFFA7F34796D +0667AE68EAF4D3BF8C7316A99E5CAC797F0220A930B7F3005EC0C72A2A925DEFD27F2DE0 +8120030CD29A9F5553E5609363E34A9526327EB61AC707C48F +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +{restore}if diff --git a/fonts/Monospace-Oblique b/fonts/Monospace-Oblique new file mode 100644 index 0000000000..9322927701 --- /dev/null +++ b/fonts/Monospace-Oblique @@ -0,0 +1,2706 @@ +%!PS-AdobeFont-1.0: Monospace-Oblique 1.15 +%%DocumentSuppliedResources: font Monospace-Oblique +%%Title: Monospace-Oblique +%Version: 1.15 +%%CreationDate: Thu Oct 27 10:50:21 2005 +%%Creator: mike +%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +%Copyright: DejaVu changes are in public domain + +% Generated by FontForge 20051018 (http://fontforge.sf.net/) +%%EndComments + +FontDirectory/Monospace-Oblique known{/Monospace-Oblique findfont dup/UniqueID known{dup +/UniqueID get 4136343 eq exch/FontType get 1 eq and}{pop false}ifelse +{save true}{false}ifelse}{false}ifelse +11 dict begin +/FontType 1 def +/FontMatrix [0.000488281 0 0 0.000488281 0 0 ]readonly def +/FontName /Monospace-Oblique def +/FontBBox {-239 -1034 1512 2105 }readonly def +/UniqueID 4136343 def +/PaintType 0 def +/FontInfo 11 dict dup begin + /version (1.15) readonly def + /Notice (Copyright \050c\051 2003 by Bitstream, Inc. All Rights Reserved.\012DejaVu changes are in public domain\012) readonly def +% Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. +% DejaVu changes are in public domain + /FullName (Monospace Oblique) readonly def + /FamilyName (Monospace) readonly def + /Weight (Book) readonly def + /FSType 0 def + /ItalicAngle -11 def + /isFixedPitch true def + /UnderlinePosition -213 def + /UnderlineThickness 141 def + /ascent 1556 def +end readonly def +/Encoding 256 array + 0 1 255 { 1 index exch /.notdef put} for +dup 32/space put +dup 33/exclam put +dup 34/quotedbl put +dup 35/numbersign put +dup 36/dollar put +dup 37/percent put +dup 38/ampersand put +dup 39/quotesingle put +dup 40/parenleft put +dup 41/parenright put +dup 42/asterisk put +dup 43/plus put +dup 44/comma put +dup 45/hyphen 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/at put +dup 65/A put +dup 66/B put +dup 67/C put +dup 68/D put +dup 69/E put +dup 70/F put +dup 71/G put +dup 72/H put +dup 73/I put +dup 74/J put +dup 75/K put +dup 76/L put +dup 77/M put +dup 78/N put +dup 79/O put +dup 80/P put +dup 81/Q put +dup 82/R put +dup 83/S put +dup 84/T put +dup 85/U put +dup 86/V put +dup 87/W put +dup 88/X put +dup 89/Y put +dup 90/Z put +dup 91/bracketleft put +dup 92/backslash put +dup 93/bracketright put +dup 94/asciicircum put +dup 95/underscore put +dup 96/grave put +dup 97/a put +dup 98/b put +dup 99/c put +dup 100/d put +dup 101/e put +dup 102/f put +dup 103/g put +dup 104/h put +dup 105/i put +dup 106/j put +dup 107/k put +dup 108/l put +dup 109/m put +dup 110/n put +dup 111/o put +dup 112/p put +dup 113/q put +dup 114/r put +dup 115/s put +dup 116/t put +dup 117/u put +dup 118/v put +dup 119/w put +dup 120/x put +dup 121/y put +dup 122/z put +dup 123/braceleft put +dup 124/bar put +dup 125/braceright put +dup 126/asciitilde put +dup 160/nonbreakingspace put +dup 161/exclamdown put +dup 162/cent put +dup 163/sterling put +dup 164/currency put +dup 165/yen put +dup 166/brokenbar put +dup 167/section put +dup 168/dieresis put +dup 169/copyright put +dup 170/ordfeminine put +dup 171/guillemotleft put +dup 172/logicalnot put +dup 173/sfthyphen put +dup 174/registered put +dup 175/macron put +dup 176/degree put +dup 177/plusminus put +dup 178/twosuperior put +dup 179/threesuperior put +dup 180/acute put +dup 181/mu put +dup 182/paragraph put +dup 183/periodcentered put +dup 184/cedilla put +dup 185/onesuperior put +dup 186/ordmasculine put +dup 187/guillemotright put +dup 188/onequarter put +dup 189/onehalf put +dup 190/threequarters put +dup 191/questiondown put +dup 192/Agrave put +dup 193/Aacute put +dup 194/Acircumflex put +dup 195/Atilde put +dup 196/Adieresis put +dup 197/Aring put +dup 198/AE put +dup 199/Ccedilla put +dup 200/Egrave put +dup 201/Eacute put +dup 202/Ecircumflex put +dup 203/Edieresis put +dup 204/Igrave put +dup 205/Iacute put +dup 206/Icircumflex put +dup 207/Idieresis put +dup 208/Eth put +dup 209/Ntilde put +dup 210/Ograve put +dup 211/Oacute put +dup 212/Ocircumflex put +dup 213/Otilde put +dup 214/Odieresis put +dup 215/multiply put +dup 216/Oslash put +dup 217/Ugrave put +dup 218/Uacute put +dup 219/Ucircumflex put +dup 220/Udieresis put +dup 221/Yacute put +dup 222/Thorn put +dup 223/germandbls put +dup 224/agrave put +dup 225/aacute put +dup 226/acircumflex put +dup 227/atilde put +dup 228/adieresis put +dup 229/aring put +dup 230/ae put +dup 231/ccedilla put +dup 232/egrave put +dup 233/eacute put +dup 234/ecircumflex put +dup 235/edieresis put +dup 236/igrave put +dup 237/iacute put +dup 238/icircumflex put +dup 239/idieresis put +dup 240/eth put +dup 241/ntilde put +dup 242/ograve put +dup 243/oacute put +dup 244/ocircumflex put +dup 245/otilde put +dup 246/odieresis put +dup 247/divide put +dup 248/oslash put +dup 249/ugrave put +dup 250/uacute put +dup 251/ucircumflex put +dup 252/udieresis put +dup 253/yacute put +dup 254/thorn put +dup 255/ydieresis put +readonly def +currentdict end +currentfile eexec +12D37711F3EF58D4B0160CA0E8A8B30BEAB80C582DE4028394F513096550F71FA11E0919 +505AD6B7CD35BB9BC351DECCB83DC12688E510CD157D892C101B29A3F7371CD20D496932 +3EB249027679D3DB7582D953F033C85D9B05B2E5B9E3F8CC14BCEA62C23DCEDB24A737CE +0B749199BDC0ED14B3F80C24B773C7D94E0C32CB6CABC70B74F04C589AE25F78DAF2C485 +03C9800E9816B03D596C6E3855892618845E5102FF46233B460979463BD7A820DDD6835A +95C220225DFE27AA6BB31E99C60F679AC7C5A3363C40EF4C555EB47B0B8DB21ABCDD571D +28DE4719336D102E1E7D1EDCC5B3B0E60354D35EB856F234AB60D3C84342CB01D8747F93 +73140C128A546250AD327045F7903E144A248D16DBC150EBAAE66ED529E3E69214BF4A15 +12C2CA07FCF9A1CA5DD6D5A3577FF552FCE29E2CE9236A470FD258273428609693228B91 +5420FBA3ECF0A2406B4484196374D33A6C4ECFB322185AB88BAE99CB4FF8147A0C4D3274 +29B1B69D3985E21294AC5BF3777F72FD8986BCFF6374642612A36E01B5F19A4C313C684F +B4A10E6D366CE685E4D566655263E514862031506A3B886388753592B0F9A5D61EE9C644 +3E5E6BCD8E4FB03ECBF8955C142520D0F71F7E4DC8C45E335345B990BE35EEF99170556D +05A25CFF99E21151C7C1407675D515921EDD3FA3B98A58FBD14CDF1AB6AEFF424587D2F3 +CCBAA445F12ACC21F1AFB0EBA2D9D9EFED2C77A01C7B4FF0042E9BF457442297D0989DE2 +DC27042B646D45A9BCB9D9B80AAD373DC283EF83A52BBC4FF0B2E17194CF18618BEB8CCB +BA24F7B836924BAF4DA12D018EB41F3307ED0F6B29C51B20D92FE58C27CF5E7D8A3386EB +04685234F0D2D1704EFDE3C72CAEE80A17BFC25C4ECE7DA8A4F9044856A19794E13B9199 +279CDE03A30495084E75DB7C213CEA250A5DE3A17D168335FEF9BE57291A770F53502F9F +78ADC6BAA3223B013B120789D9672B286D7713F8AE9802A4424B889344D6D06B280F60AC +A1A81A0D8ED436C84543D86A866C981A4A8ABD3488FE907F39B32311E4C2EE313AE91061 +A1FE81235477F816259BA0D0151DCB3F28B2F59518B09E249369379B19E5DFC19EE63BEA +CBB0636880CB367BB50ACF4767E2A9E9BD7F0339D4128C54E622D4C39C5FB383438B4A73 +9BC3A717D1E3F8A8CE7AC4FB789C7531FCDF82C32E4C8591C3D707E6CEB702C2D210627C +558FB139108437B8E9D99B2F8532F76709E821391A07BB1A9305F62EE8F9E1EA1844FFAC +C5205E5428D155457F451A8177E75D61195BC5A9F564297E4C36C9D3F730D1ECDF921096 +C42A26E66BFDB9AE5682CE255B0DF1265A763798CAEA7A3138CAE6A7F6711899EE2FE701 +D825DF705F2BA8D8C6A6FC077C7F63C35D0CC5A183A03EEDB7A81D71092717E60CCD03D9 +D7EA295AE3407BFA22C26CF4D7689B46CB49FFCDC43F3BF5B3A49E53387FF86B4267B880 +361199FE0B20B7955DE33F541FFFA0DAD7917CD64ABBABF977ED46127DBCFCB179757EB8 +BC08D07CA46AAF440882C7ACC9B93C575C363FA81F381CCBA6B3ED329D349D8D7E3E1884 +8327A19CA6C83DDC89005AB7D6725D11AC8BD6F2C7CE8B10131F7A82484D03A3C6D854AD +4E173EC6852F0E46D46F6B85B2641AE69CA53069AE2B330F57223C297E09358F7DE81F08 +CAE980A507F685FB2156714E7E9E88D88FBCAACF86ED25335647B1238F31BDD5D820EE43 +821F5CF2F7D9A67586D99E9D4931AAA7C2D32FAEE392CD9FA4DB8F69D76C3BBB48A10CAF +BA3E78F64701913B414845FE6A5F78A24CF5CD29097FE21032C5FFB34F107F51B3D8C848 +2100FE54272E0E17B79419FC0AC8966CCB7AFCF723A8F721B06CC80CE0B07B92DFD20E93 +BF01ED0C72F6385A49524A7AF5EDF658FCEA7475FC6CA315926826FAD3A90FEB182B6651 +B1966E20F7300D288DB7A53402D5D8D0A748E3C0D21B9DD078FE8560B40C06B2A7037659 +A8603518F2A67C62BBD9A29F452723A8EFE6CFA2C356EDFACDC8AE936533498DB168588B +6B96C1FA3A2740E3BAF4470783C49202FB9D1A9A9DC3B375F1187CC1DFECBC616584EE00 +BD76FE39C6EF0B7A7ED422042C1EBD392A51BB458F920DC197915A74CE8E6635EAA0A772 +426427212311ADCEFEE54E075B8E03ABF3D4F7939D35809F0B6AAFFD9C08562B9E6BF8CB +B6E3303A1B3851920EEA8EA61B081D22A585403C8D25E645987434DA4A16E57A585B4097 +3FE63FF99E2BB9B860DEC906F8FC183A6C57570859D7E381A6CEDCECFD566DD50CA67801 +ACC6151D9C6D7D5A3A19C5A283EF37F1F418A469BA10E45EBAB0432A366C1549CB402F12 +DD99AC7F802EB9D2B56899BEEB60C65C6B22EEB9A00C680E94E8B190B1C3A395B6535C3A +3831D857819FC23F840B273D3133F1BF243EDCF846D8E308E04F6A38B5C73502F34C6680 +0AF88F2E920E39CE4C31DB700CE6A2777048E4B2509EDD822FB0036D888B86ADD2A01C8C +AD1EDAF950AA9EE999B4EECA0DBF02064602085C18FFF27707F09511AF5611DC76220CF9 +FA55BB850E7F4359A9B597ED3E3298B765D9AEA76484DCC7338551FAA0F1BB8CA3D0A628 +5BA8BD8E8342155B682CD6C8FBE6631D627C4616E80114385D6B52E2C827D5E7A2C1CDE2 +B32BF8686B1E6A3E8689D1C2191C6C3E9697633E65521500EC357746647364248682F2CC +37AE635B876025B85622049F99B824C32D060CC599FD4CDD9BB51530FAE7EA750DFB07AC +A3226EA764D547F7158AD27B0187FB701626E7364C72377402A88754F1D3B5842031E319 +9DC3FAB04D7A3C1FF486AC03EDE9CB78A5E911F56B06635ADF5867E64C2871317AA8B298 +3F0FEB5251C244D589A8C9BE5A9C6382F9B409CE2D4F19AF79FDD4157C326A43EC78BC27 +FA5384398C5F927955B2B67EE653CC6EFDCAF7C23C0D08B8C3DC41CB5844E057EE1A277F +8DC7FA99594391BA6DFF30FC9FEA550E58F39934675E587698AF82F00F428AC930567362 +B401C42AA7B9B4FEC9443E9AF5FB3E999A94ED088D97CB11E6955BC9E561D59EE34BA1ED +A6C9217EF560D154BA8F19865CB8C913F12986A48DE78E9D284C0885C8B69DB0CB47560F +D88FC212B29C91E004D18376A09A184ED29866DC4A179293A52A1BA548E6F8439B326A16 +2FA0CE6AED75A05FA30EF09A72CFE06124BDF8016C638725770D529A0163954177D45382 +3A74FD8E44B3773EA1280431E880CD2398A944C4D045AE91138244E0BC15343D6AD7225C +20406C0AA1A4257FB281C2FC949CC3D215F827F782F9F4BD121F67794A8F13F19FEA800B +6C7240E804D6FBACC9A2CDB6E7D24F6C61E89CB47C94D8E961ACB9355A12B42486447C02 +7AF9D7B1C4F0E4CAA8E28BE31684D721083208D76482B9BE451A4F0426F5DA9A2413D98F +CA9BFC29E1A8680172ECF33C7218D796D6447FB643974250FE831F4D5F0ED8ACD2B0E9E8 +DC6479E203625F2C5D62F96244773D954ED8F9B4D74A0D8426A9A61176EE6AA0DB4BB3FD +8E0F9F49119F2F2F1EDFAF9FCE35316F718A3DBCD0DA416574C87366E3321DAE1798F437 +7FF418523E807C3D80C80A5057F16781ED3CDE4EA1AF173093712B3F76DA73D0FE64E273 +C4309D9BF5CB0308A3BFCDC1D7BF1830D22C77414BEAF5868006615536737E20C438265E +74B43F267E748B834FB03691FE68D944561F1DEB1CA295E442C6EBC274B6D9A0D4C2BCC6 +5D6401049EBC97F0F7A5678389267B0D6C10757954FAD66FEB12875BF4349BBC775A0804 +00E25D70A165C7ABE5F5F4427DBE548C9701E20CE28356478DFFA5F08C30FC08228CD6F3 +C6B030734A683BC5196F3D29C43E80F96D4EE3DD54785633987F385340098B5498A7DC1E +07D42614FE6F1BA7068B0677345C695A494BBF150C8E4F91EAD66E387856CB09986439A4 +03A2EA248EDD1D00A4D490B9DC4BD11E36E155EBCA715B513D991A19548B417539B36308 +0D7E8E3ADECC1073EAF675C90D5897E13CA0AAAB196E8A48F867F0F71E5E5E24C36D5492 +E476ED92090842D327E4682E483F082FF71BD290542C19242F596801E9B67386498D3855 +BD5AFDF1A0A6AC211B38278F7ABDEB586EE5FD5ED91382EED8677D8A1792B270A46812DC +BA8A1379D5E5B7413CD43C6CB3E447E49F35CF2E7BC2E99229286B2A636F83C16BECF6E8 +63E23449DB08CD8FDF0F5F8EDE5A410131B866B55C6BBA8528C17072EAA042662D855A3E +5D164BA81ECD230EEFBD2A37F823D410469B05F3198B56400B89B6637BEDE2A19465F240 +338ABE767699529CECBBAEF4879AC00A6639589927A1CA91298FD051FF15223EC94FBB3C +1C61D1611D05E59ED9BE06C0C9DB3C311CDA93CFD321508D1187007207A02EE50F422383 +DCE98954FF609844A8AE9C29B56C1AAC1238D45FA35A3DA527E3FB618CAEC32EE156BFB6 +2E8F66F6FCA7EA0B9BCF0A144A05FD8FE25BFF681E3AE6784D6A670FA08776299E0ADA1B +A972D1E35CE0BDA9F06F8A8B96C8750CF25E24F69A0A49C65F7A9716FA4C5F3CEF3512F7 +AC82BE0C5F21A6876F73880FC7CEA205B4286929ED2513D38A5695208A5CD4DE401B214A +BE67DA7B8B2C63F5B06BB039D7294DC883723FB83F736A5EE8A02C9F968FCFE5556E52D7 +9E070ED53CF85FE574F52C9446E61BC83DDE8C5AB547B08E19561E6F4B84D422DE6DF197 +3B2572006AAE0CC1F19E342389DF278FF04BDC5CBE51E27FA51D696B123DA5B342648532 +FAD98EBE03894533AFE4BECE638CA5785DDC9D7ECEB71E59B01285978563920DBF542794 +6B13DF1BD0C0D349B77290CE840C17E9F71A7E34F3EF3472AB04E9DEC00BC4C258F522AB +15C73CF78CCB3A83D7A2047FA52A4C7196C4E750C14D77EBF5C799702BB84B646BF7F9A1 +2A6D27166F7AC9B7A2D6B6062627331C8435A64C04096FEEF7867334828680E41990E319 +334217DE53F32DD9FE73537D000A5493EBC0B5282FC1D72E0DFEEB51694F6B2DF87F3E80 +858DADF97EA3E4A864AC9AF980B1BA0159E7E046EF395143D2C2AAC26A0FC3A8F1ADB37B +6E3AF132D51D9ACBABDB4244AD14C837A30C3B9CA47CEA267845DFD9FD5A0522BB50BC0B +CADD7730E893A06E8F175DF29B4092EDAE7CB28F8FD389C14EACC8FFDC815355B9FB564A +F8C33D5871ECFC0CD0E33A0AAFD6F7323A3FD696B4EE641249BFDF82EAC73D0D823A5BC0 +EC34C42269F5699F129273CC384C8A17BEDC4BA4E384BE7D6213EB49FFFC5C98FBE27877 +85F64405CA64B5F2C10470B82BC1471F59C8EEEC668D88CF0441451E275328E3903A54D9 +216F0F70F63DCE071BA66B31E59EF5731CC778455222D441C0809C690AA9E70AEB6546AB +6B6D27A66004E67813F7509A3F2B2FFD717A77FBE48A7480FE4F2E0E9DF61D378D817928 +926F8F202341E945DDD9F747F6AA931A9369326C3AEECFAE75D289691683E6635E215E10 +9C76807AA3B71450BDEAC4AC8A55F7B6B7933745E2F3F2F3049CE858B10E17F8C236B247 +FAC04A7C3E6298C1A2036E14EE164AE8478FA4AE6F24A9E542D3D2B450E4EDEE099AA693 +16E89A308123CC5DF3E4822A5B57C7FEC21271BFA0168C3309ADF2DABEA0610FB18ABF69 +5622E7A1C371B3EC501D52A1DFB94AC84E30A500449867BEFCB5A07DC54A2F961F296DF4 +9829E92B8E0928315D60103EAF984847A6FF6185F8C1EEAC3A114F7588AD864F3A16B94E +3AE4E0738E13B6190AF3A27427DEA99F8A6491CF60C2F8F5C8A524CDDFC5AF2F7304DF82 +DD8E2F273DC82A9F0F7812297C485AE2B330DBE5B0C2E91922484FAC56649226FE104F57 +E88622612FD6CC084725C3C717D6B04432D13EC9DD5BDE98FA56EBFD2C7FC973AB611168 +C43379538659B695DEC62E8D58BEFCF44F9F0F52273D998C6BD8766BF4B26E479DA21563 +04B1248C80C58E7A9609B64934AD07C1945F03AD258D32D4D47B6C1A95D44B135F380A64 +C7ACDDD22D510DCD056A38C8400F21900F1692BF2210F6B161EB8C6E7702291C0CD2123F +6EDA46B95BAB323A99784F32A3FAADE6599CAF43F3CF39D43776A205B6024F6DCB27349E +C394FD27D389C1CED32138732AF2EDD4215A8E81A058BDF9797E0EE81D13B7773897EEAA +B71BF9D0D6D913DC0887442A470D5878766BC30C065E64456A88F88F754C3B6CC402BD8F +BE60B69F6CF942EC531A6768887DC1D6C08A690109E86D08D9470B9A684D751101A2821E +48805AD36D0E6D3BFF33FFC4994645AD2B599188B30649ADF04EF349B934E99E3D767C6F +95DB404233259FFA5BF4CD809B4E08F51653D72C2C24B7419B49585672244128A45AF33A +82BF11CF4B402B322D7DD20410A85B28CD32DBBCBAD192079514ED52996086747DEDB275 +8C8CD1F05B82B0BB80F5A0BD1C7A2F726B29F6D8DBDC9E199C494A8682D3A12F3430388E +845B4878CF87871AC6914DCE0E7AC20407F04B3A41EA5EE88C23AB19D61E5446ECA0CD77 +0D6992CA5DFEE0265BF81AD4EAF93BD5C068D1A0FB1704499AC8F16E26754ABBF318E528 +D7B12C0CE352E4FB67A1F6DBAF06C9EE5C0A04A926EB75A2E76E1050CF4300721B0F130C +E912C53166696D93B131CE8D487FE3B5A8450EC7A8961479FBF29E63DA9B03E79F2FE5C7 +14B57DAAB035A0D2A6A9BB5FED68F49C58360E5E974709D12AAD0680E1C0145526CE2C88 +36FC489C50D8D3FC5C0AE2C517030391268B306D231A9BB1E881928727235C693FC86B6F +A9A62D337FCD128CFE1BCACDABE9F384B90C10DF4967A447D53828F62E753D639E4432AF +361F680C212BFB50065241FD8403C80D5FD3F57A60643D586449C76238BAD444D1282943 +FBF39869CCADCDCD0815A484C494FA16930F3636FE854A1530277D1232303C0A86365066 +89FFD5E3C5AC028CDD18A3FB360C8973AEE50FA93127D6C7B3F323689F3075CEB2017BF8 +BF827381B96044E245DA2A845A536E053A1D5B540A8A27745547FF27CC9368EEACA827C7 +A47E56107A68B58A4ADC9B4A56C69C16A061F50C79A7034D317FA0F61A123D749AE3A140 +4D8A29EF631D5F925C8116256B40B81EAA31C326F4902BF46D68C5D6930EC624F3F50587 +9CB9DE9740CA93D36B8C84FF21E7E2AE48FAB457A8973106BA5A4A9D35D19AEAB1AE1E2E +8794C96BEA993A03C1CAC00697D95BF3287D7B14701DF8EF79683F2771A444D334E7074E +0B1602CC3D08293FCC6815946798BA56470783A0BCEEF3BBAE34D9ADDD47EC0E23E63505 +67965078615B540448EFE238DF5F70F1439123534B37B01D7189DFB6B21E783474B476F1 +9857F50753D49ACB4EA73BAFD9727E3EDB0ABD056CA73046DD3743451C0C2E54AC8646A9 +C1E269B570605A92E28FF146F6C9E49FEBC2B0D1946D673064640F610FC762ECBF415845 +E80463295D0EC0F6CDD35852CC9126E08DA99B91A75CF7EBD86466AE0C381E87E9D99BEA +1F6D35F3603AF79212C5146712B20727A4CA38A6CD684B5503BA1C18590EDF890902448D +ED527E7EB9A15623500BDA827261BEC6E0AFC5D644DD384BA6B3BBA29EF93FEAC2BA6C56 +82AAD04CA8FEC95DC915B8566A268801A7242DACB08C0A47122DFE37EFE10B721CF410A0 +471163142D46D3FEA4282739312E53BF815FA207F0DDFD7200FE6F7730D33F25ECCCE770 +2765D198251988F9D85E4828719243D6275E563E439F7F7162BDCC0BE33CF25EDA87DB8B +D51D0B64335C358ADAE488D997D3ED523C3187A50D1E287E00552844DC66F3417D145635 +3984699130F9B7E860359DE4B14195307288A8EED3BE2AE04339CE84BC1C1D02861C32BA +47C050474FA44D746FB2BCC7A1469C9246DF0725F6B854FA1AB68D68E96228E2CB7834E8 +01684DDB14552974A23ECA2254EF2B6D195650ABF1E2BD69B2BBE1BF520CA77E748C0152 +FC5665C36AEBD0002190FA221DD3115ECAF905114FA7222822523711E48DC71EF5FF7BC0 +9BF1C3DEA0283B5868357DBBFF7B4C6F91C47F941B40F03259AD826AE6FF057EF4B07B9A +058C4B7BDF58C6FE1D71FE9F5E96ACEDF8DB833A4CBE46BDF8009F0FBECA3314AFBB162F +0545C10E45F1F697A2B895849DE0EA02F2770349317E43BE527A3B1D808785CA305E06F6 +84935F0E7AA4E015A8A4FF3E8F7E6E5472D161EA42B964F48D1450F9E52D5CB33C5D84B1 +4138225527E6680BB40D7E73B2CB4BEC73EEF10629E9C614DDF422DCE8E4B6F64DFC4ECC +3C48660A9E1983F4A84E4EB254D5EDA7E1A6736D98D878502A6320CC661E4F47418B4D4A +9D0DD2A9733C000A0AD41583095DFF2D1AFDCF6ECF69C85E5C9BB3F202BDDFB142E6C18E +60B07D7EA40340938542A5EA036B354AB35FA8FA0B9391765A8C498B85F454AEC3F177F6 +8A122FFC8976D4AC99A370B3B7D706EB1BD36B3AE5D51C9482FFADA8DC7584795E8696F2 +81A0F0E3E9912BEA16AA15597B801EE5571F4BD4FB95052049A663FFF72DF8FC6FA0CBFD +A15889F230C5AA3B25F4DA1500DC0302010956C520A7F73E1A7A938E895784C05399030B +D4452FF0BA27AC1563BFF0BA19B2C5427E2E6B8A06BBAB6137DB007FC4692267B0D10ED3 +1C0341AAA6F3BF586940AACD797830468685029B2284346296F1500FE92FABCDAB796F35 +46274B8A69AEA68FBC6E1EBAE3957865D7DC284EA7A6CED43CFC91B1CFA4038F413DFB36 +491FBDB1902914D92F2E45BCE9EBCC1484C97058783BA2C17F42B57A180C0F4E35B71090 +CB0A51F6AAD0A5B01E9AA7B8E69FA463B54A124AC05B01A942526B070244A2ECB6DBA5F8 +01DB459733371F92936CDFB4F35F7DC4ACDFE02A4002186F98A1000FA168B6B409D152ED +D5BE9141CBE10E0EA1C17687E011FFA488E8D9DA7D75E847770AD67132F8DBA4DAB8E567 +54CE8BD5B72DEA699E2EDB0BC2868B71E012E631C747F23F5C221BE43E034DE187BDD469 +E712F4FFFF09597BDEA4E71E76693FC639F758606E99774C1FEDBB5F121AB9B0240D1AF3 +86B28EB0024E13C0CCB25457F4996665A9F68682995960BBBB9622C70E1910C36BF19E5D +AE05BA5AA16E07F1E26F00C5009F6D5BF8B2AB9A3A34ABCC391B1EED111BB98B0A357D67 +91EDB58EA4B24336B4C0CD8994CD552E29288AB0A7FBF948891C41639412F0F2B70FC00D +2C509270C53B5EA1306176290600581E0E7A793FF3C6A085B9C627F941E36C4D6D31154F +6CD00209EFB60C1AAE01636B10484C673C58881FF8B54AA1EDAACC309F1C72C434247C7D +ACA423249AFFC2ED1E53D1B862FB553E583C4694C99B6116AE9F6BAF64D2B512C9C624FD +EAD7A00D757B5526D4AC98137C875D0E0E051ACBDE4996DF3B4D5719114C22D5DCF02A06 +4DBF81847FB12C931C2D8F6E9C557666DD6AF7B28E7E763DA7BE334EB3FB89DC1D5D8F12 +6ABFCDB56CE31A41E098375CD932B9ED53E5DCFD6A943A983F071F8B6EC1C35DAC748BFD +32B8FAA674B8F902B433BF12F554D391B56A3C8E36B6AADCD9489CFF80136FC575D7E64A +957656B2C4FC270F23AD3790BCC95E85894C61108A9EDA8EC4D22E9846ABE07A528583E3 +3084991834D424B8D52EA04CF93C1275FBAF578710888BAB0E447C395F0988035DBF6B79 +D65169437CD509EFFF8D61A333C909BAD589AA1069281E3DD8A266D4809471F65218DFB9 +9CF1D4A6C4C07B0A508DE36F53D506B25268058512AADAD9E9EEA08EE51C0B12977CC9DA +DC195E944C659D2E847FA471A403D3069BCFAC82479AD29FCBEF4EF6C93EDEE4F0C0E44A +34F25718B7158938A3A9CE183D707D4F789A5BD28F331C23B3290AFC5E4504794654A814 +BCD943F786F603E24C01E81C1E8577047C3E85BB4D861278CE2E7E32193D1849A9A310C8 +419214AB037971D051A9355EADEE4F56DECF0B20C0AE7A396797480EE47FF822F96DFDB2 +39122A3C8F8A83B8B3E105B3950C8E5703BFC5E591437422FD417A71797DCD2872FDD9FF +28EFB8E20B2EC948F0D4EB1C67E7E16CEA436DEDE1B17E0C4A11F1E91D3CE839DEC8390A +FF3C58953D098B24597766D01BD59A89ADA6F1040482EBA4157EF2FE71B220551809013A +B5B47CFFA33546A676DFF72EC6D1A04D82750805E38EAEDFAD935833B94133FD5FF8A58A +5A01CD5715627E74E0856D1F8455F6379F2E8256CE604480CA874DBA0D06E190833A8015 +7BB75CA24E95175821FE790DF854F15E7EDE318E0C0171FAC8BEB5390B47D5814E4D1F13 +0FDCA640E0FDB9D0A5068E98158FE775AF2D0C7D9136087E00E07B67AFC8FF6DD8FD9CCE +ECA3ABCD3DD58DF9F14C032941B13E01BF6EA44844D52FBC037A47BD94310EC47A1F7B54 +B6BC07C7092D8946CF949C654EC1AA520804F8531C1534BFA935FAAD3B9D7EC925BB0C4E +2C7E8E205C09104B8FDD7F8AE970107E94EC5C2D5A7F28DD7C0BD6C911CCAD24CC303D5F +0C6C9A4A585247D5EBE57AC01E7D8E3A384DAE4803718C1C81D3035324BDCA7BB452A030 +89FDFEB64728A25EACA1F4AB96A6749C4BFD6DF72102371863F719D55825AE83673701D7 +C5139567073180C72C6CF38A0CBEBDDB043D2B412BFC25A08CBB18FDA0AE80554DC1082D +E4D70908AA0C667073F0CEC5655C947CDBE6C501B1E38BE843A5A8CB02312EB04CB098F0 +638ECBF704DEB82CB1AE8CFB27B368D95A72757162884704BC4A74DC7ECCCFD1842D8957 +BB1AF1B020A97A149AAC0E0BA7699703E9879E49F122A838BC7465161E9C4C62E02B38AA +396C1E65209428DC112B08AA731031B4198BF48048132ACA9B40FAAC94A236BD16BEB9C6 +83A511F57E22ECE0C6C63C0A3C5366FBC488DD3CCB19CA471ECD0B895B644C2735C8D008 +945C02FB39F91ED4D633C151251CAE4E82B18B55D978E6A7DAFD6F4D5497EFC807AE9AC4 +2BB5E96A8630756DD2EF1A7529AAB9DC1CD2A98C9F70ECC97D8D1F920A5EDAB809C7BEAD +04B8E0C3266E1C2601FCDC61B73007294ED1176FA5C5E94075A95BABC2589B04B2DC6A7F +2A244975EB7CED7636A6216A7CEBE34CE405D1C2BBDCF3D30D0B65AB3F92357B9AF56455 +2F36A611924DBC9C90AEF0F6DA64EBB58510AA8AD7BC633B8340A942721C69B39A01A69C +28E44C520708800484B236420555098D369EAF3A1251B128881C6A71F464B0DC77B9D1B0 +68B476024784DF5B722667126F0ED991F123124FEEF22BEE19DA1869CA12E0C94229BBA5 +B2CDCDE1BAD1DD53B2A713C4EFBDE270F0C8AB7F9AA27FA800DB025FA10B2FDBFE4B8A98 +A1283CDCF35BDB1A6291884C494FC6224B965B55742FC5DAC852C0D014CBE5D8E64406AA +5845853F669A1667A543E64D5F86444D0CC1C4F796B0F51C0BBEFC8A7195C72566851BFD +01D5A7F44A707448E67D202D89994F2BDA312FF16B5287D1D13E4FF8CA905D012B2DCC06 +42DD1A85636EE7981F13C099535D935C1A1FF5218CB190A58BAB01C2F502323676ED3AC6 +AA4485008B7D142EB15455355811F1FE8B7FBBE5D93534A4936308067A6F6C1D80F6A287 +696606946C8D61C244DFFFA6FAB178513EC0F1724B24B3F26F1725471AE031FF8E15109E +A992D90EFDEDF8796BE5C16425E1E1391680C229067BA9C69CDC20077C02364C6E62EEA2 +CC5A7EFAE6A9493FB1FCC5C93228AB5DBDA8A2BF8161FEC4492B02B4F29CE42BA9C5ACB6 +8708C055BA56CF6210662112EBAF899E62CDB2EB8A685EFBD1BE151B4F2CCA5DEBB90B5E +55FEC92DAABBFAF7C3778BA79A59B131682568FD96640F3794EB7C57A508DDEA025C7120 +89F193118946022A9024289B2FD5D6FBB8B8413B0DF5F65227DC12E99B7B657F846D798B +F5E74A3DCFFF1B9E1EADBE5A22268846CB5749B22A96CB7C2A7E1BF47E9E8F5FF7354314 +3112230BA9E8A3218442BB7DDA51AB8641BCC1A4F6D25B53A4ECDC171F1B384C6546F6D8 +7239CF09E6C8573BD593FBA1ED2C42443F6090EA7A5F4AF4781270BFD801F57F42A7C51B +AA65AFCADED310E6F29FFF5D641C2807B8CC4DF05D45CA5BB072F73E5A7364851C7DEFF5 +270D676F9F86E425D14171E3862B7FAAC43E181CE165BF319EF549BC8B5C3D3EC51017B5 +8FCC9817F9E527D8DD01F33C9B99A98F675312D26BB76FA0DFF8B239A1CC7AD1A5AA9333 +8AC724B6A4C9B5CADFBFF718A5593C51E476468BBCF2E5E77A151DD9DA236E5765CC545B +AD8D10D62B238BB574D665D0A6CEC479D1719D587C1362C2AF7C04793B2A7B20C297D5AC +0F96F6019E1648B603AD04F8817F6A6F5E568A775850DEE71372303059B137BB129580D7 +D10134DECD6D801AA62089EF6A573DE96E0958552DE214E3615A306B798B6D68314DBF57 +4305E2B09CE8816EA4515CD6D2FECD2EA452FC01F62464E73FA7006117556487B6F58197 +5EE9CA6DCA4480FB0B9450FA07B5FED7528ECC235BD8D3A24CA63382B0DDCADAC78384D1 +E5A6EA0646E3655E6C86C323CEED8F76A53677A70AC54CCFB97A3713E5209E1A0F9B6863 +289A62261BAD054A7A495C3D0F883735284B7ED4A624C39C8A03B93FA9BB91BB396C0E4F +E3A173A5100CC25ACD1E3967588C56F6F3E70AA6E9F5621E4B9F3A25C0ED1B89054EE11B +ED849B16F521BD9A143D0B29796D66BD57B4011EC290045DDE9C4800C2D0D1DE24501859 +50DEDB737635EDE2D1559E0BA7C0B361BBAC80FCE4E4B35746B8865813930ABAA5BEB288 +1D820EDA6A683CA4A94EECDB1BD0415D0586C844C66736751640C5E8055C6093FED9F84D +EADE6273926A863D231C9B461B41EFEB4D945D529AF5BF494858A5E5E0A0BF1B179B697A +F25A3E29991DA1DE79DF293961AB7CA49846941E82FC59B1C06B9BE8BA005138F6979DF2 +7909F57060DE9028ED61B1EDC811A60090CDEBD7781D628BAF2C540FC7B4783BB1763630 +96B50637075013D726F9D0EFA2ACF762929C06075D5992B5E386496B381858B6AB040CEC +184571C870023678728ED7332630969C86BF521693DE56D09D6D8B0B37511C7D714E9932 +6DD501DC3AF262A1837BEB8AE03DC161F61251A615103EFFFBA7757615F60F7AF5DFEE44 +5F9E832E4794299721776D643A4395D21F905685BA9038521F05E3C3E5BD1D3EF9C229CA +695BCA0132C4A64A71334D9E76C48F6F4D5901CBD9DAEBE194071FB0FE7D2C5C395DF93A +C1C64AA36EEDF18B1CA6E2B510E52A35091AE7673924F36F7AAEB981B9957A3EF3123C5E +05AFF67CDB142D00CD16E03754BF6C68CFA2D734333AD69B3A3296EC597C8B76CC3232AB +45ECC8B2C90253A7001485D49E6310FDB5DAD3E7EEB4305BE7DF36342C4B1E11E0945B5D +EB63198EE676FEB7D3382D0CA6EC11E11E8130AA9740FA070EB518CEAD8C85D8BE693FC7 +15B31D6CEB164254D322B7032075DE964C94AD8B28BA58A3A30EA9DE79234F4DE0CCE216 +DC09F22CFFC1E740B082DF65F10F9D9D173E1F4A996F16D5DDE396179B4CE389A555C3BF +BA3B9059418EE567C4DC661C151F9EBD8F2E006288A6CF3B86D8F260E15E77682FE2976F +14D4E69ECE6B15C1042EBDABA1D24D9758EC60EA675421D5556C26A83CAC3B003F8426F7 +98195AF444EE55CA608A69408D69B7B103FE873A1CBDE862A7F7C4B27E778D4ECEB1F596 +C4796B37DDA26AE61A4579506AC65F72BE3D01C2BFC79556913780F541E26E5316F6A56B +5C92DABA9B7B9A9E80BDD4FF1D3F27559F83021D89CE8497F665F2CF2FED3805F8CA7D36 +355E41188F853B192CC64320849EA08D09BC87D24DEFFA9196F75F00893DF4A069BB4340 +A9A451102003DC8FEDDDE6B648EE1675851310D15FE319BFD1E411DAC0402698598396EC +9B01FAA040F37D13D65D9F88120D6212C7BE51B98FECC29CBEFBA669EF8B73A39EF24D86 +8C692FBD3C55724FCC7BA3912B87998A4E50566ED69BB2742FCD60FD3BAD55EBFAAA0E9C +8BB15FD2BB7BD82D65E722297E9173E09D8C228A76755A3611170CE15924D3F2BC9FFDDE +B0F2CDFC4CE44B6507B03916E334B4FE336473D0DAD959DBF3B11684D09C67872EB406DC +E8AADD34D2A0FE88056B2184D2B07825749A3131CFBA4A6885CF4D84D914DEA0A4DEBD54 +F35F031C2B4C18D2C0E5DA80463FC86645A3B63209C53BD98B394398E506D8E34F0637C6 +BD702B6BAB0E45F12EA06112EDD4983034410D96D3EF907D32C71AD4953A8C90FB289510 +70AD7E985BE69AB6D180E110FDF29770905DDEC7DF995FF72724A275CE8CE825B9322B9E +B301DD7E90A6075123279F9EA89333E39457333EBDFC5F07AB1563003D0E766A010F2342 +A5E210C256CA182DF768439CCBFC43477E25E15BFDB3A224BC1C9D67B0A0EE160B7142B3 +58330DC30E49446C18969AB491CBEAA64AE611F587A3A7F7BD3B206CD034D0EFDC12C992 +4FC9F60EB7A7B7BDD94E900C5A58AAC8C17B3588A95D614197E1D5D1013888DCBD84F7C2 +51DDBDB5E1EE146350A94679DBE6A67BD7EFF924C402C23DB55C00664754CC9E4D3B1422 +16AEB7A712CE85947C4680102B651F83DFE71428028B258E722D827C2C347CE087C741CD +F0846675E34D56EF99E21854CA02AE9BF9B41B34E58A1D5144A6E9D698172FC2D8E8DC49 +098B77980978D67285DA23F821896D3ACFE7ACB6FD5DD87AE6D07F5FDE7AA553A869E594 +BC2EBEA2E0ABDD5E747FCF0F7D1381F9E121E97B11456F80215AC688AC777CFB9419D95C +DAB35AF315C5C83114FF51BD583F17EC51A911F255521B3DE63C5B0A016EDB98722E0B15 +FE68117B4406CAE3F29DF6CC813569882C169070F6F499DAD42E1ED6DEDBFD464D352B53 +0BB28FE2554FAFDD48FFB9E1A433E94681A5B9DB2AA285BC5CDA48C1BF7AE7999E5A6678 +D9ABB9A68BD4A60756C13ED1975E2107F6D1FC4FCB2E18FC25E68DD2E53A623D15B95541 +31F1DD74E82AF748119B40F6E4E703DEE1856BACBBFF672DF548327A95F3B52DD40105C3 +604A24047CD989DDDBBCCA27D28F3BCD681CD55AFAA1CC5F29B39FE1D6B59FBADAE71196 +CD83F5329C9B969A5BA06BA67AFC193C4BDA78A275C64E2D82F373EDB713498ACCA9FE26 +9FC4736828D55A98AB9FE487AF40164FC38085F9DE01332E3710F22EA52DA9CAA28DDB5E +3AA72EE9444F818DB13EAEE426543DAD3C78D48B513DFF77C18555DA53B33B04C8887199 +7B2C9E86E12E94AF3F379D196532D2CDB84741211A584B7560DEBA3C53CC78E240186671 +8D295EA11162384F00A727EA4B7EE6527DD7DFBBF5966FB4372A35BD2FA7BB7A6FCFE23D +AAB6570FA52506E3EF532E7E7930298FFBE47D48641C0E26D1BA636AEDCDE13DDFB3C822 +DC32C43759F016752DE8F256DF5B57EC3C623C05037F1E41C38C66D18A27610CA8BC0E5E +FE4FA49EB0E287E855990B9C83A103A1151727B192496B318A0730AC902D7C4B154155A9 +47AEF1B7255276631566EE5B995D9596517E42DE25FFC666FC0703336FCFCAA2B97031EF +9B95FD714ACB1A47A249DA377A6EC9338558939C6327B90B77249CFB4CE6FC947BF1E88F +17F20A194DDD37657E8D5BC31F624B6976A0078063FF707BADEF04391782C6660BCA4623 +17BC929F6411D2351B9DD2F67CE4BE04D251829BA6E5ABE574FB3D3D8D2858AC7B87F3E9 +951F0FAD71060D85DD3BF22DF505778932D2C7CEE2BD318C0E9601D085FD258C6ABC091F +EC3F44C639B2852EBB31BA5522AF78BEDDBBC52E804D5DDF23DD119B951551695BE44C23 +5DCD52729FE0FD451F9CEF413EE55AF45128E35BB451D654496CF1C8C2BEA6C95F87040D +928EE96A22AA91E8166577727896E7A26EA5298620E50832956DC5B4B95986C69079A1B6 +8F64DDDCC518AAEC30D9E908BEA76C19D54388435012C2F8ABAC88BD1F82A1083F729569 +0A4076112B601F35B1E104720EB73D88E0E62CC0FE278EAF5BE953AD8D44604C35D05A14 +7123538297A5B80677AE45EBE1620302B8248F2B0CCFA068CBF76C863CDCEDF677AFEF18 +F4934012F795C9CD39EED5915DDAD4F640BF75DC91CE77E4B449703C1FBED867745F67C9 +BC48C987BCE8B838D35930735744DB987AA4E8EDC83236D764D1237028F6AE8A6CCCA003 +692C28CD708F1C9F4B0468140AECAEEDC465455D8C69159ED0AD0D0B004A8B51ADFDEB3D +82220B8D2DBCC5E1CC0F550E44B83FA668B30044A2E9978A810D4EF995490065DCFDEE41 +E94DAA51D26F13EB8218220FCB1F0F32D5B5C15E715A4FCC605B2F8800F44B82633A83DE +FA4C3430104CE6650AF07AB2668E751DA4845205FD29B7B03F46B51DEDC3B6DB3E534E15 +AA0B33BD6E0D2C5F8442EF326828B9A3188EB15DB04F301A98E00710AC5CFBFB9B2B99BD +5AED103DE636341AB7B03E24016228C0DD81EC95D5A8B8EE1C44944858784C024BE6C8FB +D038801D2423D09711C5FAAB0E16C87D307B53FA9F874E6FBF1004E47C6A6907DF86BA73 +9DAAD79101866EF02234D746C72BC60A69F7BFC111C5C26B87440D836432E283EB0CB8A9 +39ACB06AF4FF3857EEC12A1BD1189514CD518060FC75DDB601F545CCC37676ABE3EDD86A +7FA54DA5C33D42861E585D05EFD8B41D42F7A9A904F48FD96E30EF9C74433B35B1EC9F3F +15607376F04695749F917ACA32779CE1CD986051E43C2EE748542E4C7CD50E3C30DD46B7 +C6F809D1051F977E7D351C67403B913BE5273A97429416656D83C0BE7C08CBEF00BB4651 +D0D5CE1E8885A32CBC72DD26CAB330BE9845425E048B1EE1AC7591F0F0CC9F73E1EBF665 +76591E3DD449304DAFDFB6A44C7BC4DCD9202AA223C9128A961792E3C0DFDA3515BCABBA +78F38651862266E779C228C596BBF3903F097765DA142C99E5185BE9DE2F01AFFF441965 +198BD1FBE9BB8D61BA6C685BEBCBD4381C20F71F8DEBEFF62D7946B04C7D357E54ECAF48 +A49EEF2ED25179C1C3FD45268363FA20D07A84D60484C712A43D224C57551FBDAF4973BE +EC02A16076184E3108DCADFA44B93710DB3388E633AFA06AFEC76802F05EFAE2CFC74A5B +AF3600A46B026AB514EFBB7184C75BD39FE9427F6F0F9D2435BE1B26BBD4816A72B8AB67 +DA7A6960F5A7A0E7FB1F83DCA6E3E8E8F1BB11E22D378FA743B7791E981D117A2E8126A0 +F3CF5C9B0C35BAF8B66211813FE63B029E2A3913CAAC2603AA4AC900EB8428FDF58DE83C +D998B69BCB6ABB67FAB1647806FE19FD695372D671EA0B6566719938456CC79D265C9791 +725AD53DF396BFA79E945F4AD42DEE0C69C995EE8DC3D8E85BF383DA9C1256AB133CECC2 +49A3BCBF384F53AD50B3A58606F4A92D68DF6C072E66997978A92EF5124DFAC8B3938E60 +94C0FAF7556D0F75925FE99AB3E80FEA8042A977931E75635051DC896059C30D7ADC38E8 +90131D3472CE1BBBBABF231728199245250B618AA5F830D20C8B1117E4406C97F59A9A76 +205946764DECECD486D1C217242CF8C58263535485E89344DEFAB9D94079EC177AF6DC31 +051EA610E81026B7569A061E99309A04CC3977C9BBA45E88B6AAEBF585B5C79E42548C23 +060E0E103CE6EA0897B43EAA35366DEFC5B1E5E673424D707F05C770F31218BF56855627 +8C9F75A113F5DB640C2EDB7F9D3138A5C314243030CE2BC58F4EFC9B546E407A1764118F +F9D2208C6219D088CD8A214CBC0C1DF55772A04DFABD89E08F7C98455E8A5F1F82BA749C +7C5C5E6CEDABDB9B3F6E1D717ED97A50D0906BD4682D9A529B3530F29113A35D5681980B +8D099BAC264E382DCFAB0419F3313453A080795E7CF66860ECCB8782191F4CB0EB2D2965 +F14D28EB35DBF1C95437674D84C1C331F4EE99C8DECD6946069B3A4A7DEEE0E48E817AF3 +08C28DF99E67A4413655CEB10BECCB27448530B1688517F0C5DBDB97A17C6F12C6AFBF55 +AB5AC791F5363E56AFDC38DAB07B7A47B9FBEA91427847C5EC1D584FF56E6F2735FCEC80 +DEB8D89F90090A11819D08591A37EC3948E36AFD44237CAB16533CFB51B50E1EBFC4A6D7 +BFA520FDA738662AE6C0214DBB2723FBFFC986E9DD47A493FC0090575CCDDD6C38EAA038 +3858C077F57E1DFDA8DA95C9A18D9432DA2C86DE069CB675D9C8189EF01C567CE476E0B5 +31FE688044569D34362235F894E746E6306C03E76E615571D9CE6FB31D63BF1DAF29AB76 +27C0D02D7760EFE583C8C2FAD4AF0A90AE91642F2F20725858CBC2FABB5A5A36F19A3C6E +455DDEBAF968A90312E83193605CE8E5454E396C2C59557EFA1BE1E0F8A0AADD060F77E3 +C642635484956025266155DE24655C44BB0B4D07099D81760DD0823EB9EBABBA27A559F4 +8803E6999B782A4D91C388B46E1EBA6E8BF7CE9080F46B539A507F5DD17AAA05D05A551C +B57918F3AF43390187E3765548F4E5A3360A95C80DD6AE1B26E1F90B8391A3872ECFBA2A +087415ABEBB9119CAA1D411EF7E0F0737AB30979A30B2ECBC8EA42F38B41421CFC94BFB1 +FD30BAEB6AE340D043A15138AC4A7FB12CC0AB80547DA81D91166B09CB56A5504C048DF4 +D4E1E7083B5EF010A38F4BD375A3918D25B05026FFEF87AC25AB554EE74AEED323B4AE63 +0F1320CC97909D2819A8EB0A90AB5F1147DD888AEC5D42C8C5F2B2728A80AE8673831189 +D76571F665756C2C01AD4F936EE0E607C27FA9B8E38BA5C67B52E7A50E09AFB2D0610A00 +863C59F7A1BF14A5D3FF8954CBBC3D13F709B433822DB8CA2E64BA1FDA4F9478A5AF24FC +A4427F49F39EBEDD3BA9DF9B2ACE9FCB01BCC9153A7DE685AC5284427B0C573A6E5D9013 +86834552B2356F11011083B65724EF7F8C7D7CA259E0C03793B9EEEDA5B6DA8376E72EB8 +033A415DE664EA5CF53B88655FC02AE5E530C6A90F443F740444956B60F6ED760294DBC1 +9F492DB3A5D4E532D0DBD9EE8139092D3E89D7CA7490400FA4EBE56334B1A17C9826AEB7 +74749C9193FBEE0414C7E7877E26B8274283F14A14AC7CA27139CBB8CB89A6D38DA283DD +3D421153DB2D917391215433E356E64E4A07F6D82EED542FBEDAFD11D0BD4EF3041C6865 +2ACBB1FE71C6B7B3850FF45176850FFD64D18D4D55BA5E74D037D3CDFC62563CE2929233 +1E42E636DEBE14DE81804C1A15903CFBE782409A1E8684819BE6AD86F1C0EABC03F4CCA3 +A959E0B6C57F02D29062A6F0E3E5978C4726C01F607307C16F5F64460E81042B8E2F6524 +EA16F9BC21AE861DEE4013959FBA74E40B750AEAD9607FF6D15D96F6C28F4E9398C70CF4 +1B654A2A337FC8AEC523F27F6C5F0DA4B2D4A3758A0DAC65BF2167DEA823C3D108D3661C +CC47D80C948444701335BC4DF8A8A8E433776FBBBDF0C97E985DA1311451CC85AF9E5BD2 +FFF576BC8E4A79C92A00678761D47D093A26796DE0316A80BA5CE0BB69E188F4C38E7BEE +45C8DE646991071844CBB503847613EC82BCD6950F44D64D8117B52E3A63402C09931410 +D7A1AA9A04F9815D52C3BB9FBC829F9DFA76ACD77BC751475979D82275B709AF02783A64 +A633CD8F213DDE9216664C22E9F9AE3370B282E9098B86D4FDE991FB9D16D04C0C7F5262 +D539102F6529D73F20D1996061515A8F1219B228502590166332AE7D27CC822ACCF92861 +5091818F53CE6A7F1C5A68CCC3D6C7BFC81167C3C2294C9591B71CEFFC88A245E16484DD +1080375D15B6A3BBDE47CD198D0BE312AE1F5F6EF6DE4A2CA38A717D7104466509C8593B +FA6B5DB6DF788C6952A28E25CA9E20D636EF9E84FE3CE4D3A4647464F79111A610A1AF84 +E0BD4B8F7BA06C3AF012C74C91DEC0C597E6F4C19546D258D9E53E7943D6694EE85C74B4 +93276817411892299BC02A2CFB065F5655DD87E69743313801CAF098FA1C56841174EF0D +4A7F27B2E91762069656895B9FCC9434434ED722BB9A532606688F303D0C514B31D179CB +DED0DFF008F09184FA548FE7C276989AF46C9C63000814F90372A1295717CE87B2D9EA55 +34C0A4D467A0F6A32482B8139AC4240E3569476BD4F8D5CA5CD62F28BD2FD820602FB678 +69D696EEFFF2C173D2C7EBA377390670908EA07A7E90BA16790314AA8A923B234C8ADA37 +25888BC9A631A4A5B308378369C29B79966AB44E3F4DF846B0438C31B6143C9C3A003C86 +A2119FC5FC1509BACEE7A9A1EF43945214A1E37879CABF18B7A18E8BFF45E9C5E7CF05C1 +81F2BF236310B0AC2B1D45E0F6E3961AFA34CD8597914B6D503F7F5BB964B7DDF195A95B +FD5F3FE49340767491F213D849B3299AE439801B84A2718489868599F29DB6849A5471D9 +043C6B4BCB4AAA48DC6CA3DCDBE782D3113463400F09399DB804AA81FAEA98C6C7FF513E +1CEFDDD822C4A5ED4F0EC1AD96EBC6A713BB82FAD69C3E914AE2CE2AD2DE8FA301364658 +0987D4836813D3DF7BA9A77601FE3DD487408794D7167D6297BB19C8ECA466D56F130AB5 +E0ACE40D575558A8221EF634AA1D43CB10B8CB8ABE6EB2EBF97C8ECBCA498BD740A73DF4 +0CDE64C2C0F2D1468C01047ECC2320A9FB6D965C83A2CC768323CD1FF3590D6DE86AAA5A +4ADF258AFA132E8D8C04AA614E11D26466CD9F265AAE7D8F3629857C73946C1CDE7EE21E +15C1ABC4A1F591DC1CBC14B66269525A664419D0C9AA2C4713790AF5E23B566EE38D0530 +886A48F041B8B009C5522B55E63813023C763C68545AEF0FBDF2674C94219D0233EE3D3D +165B31C9BD4B9F27649B860D935D77557035BDF4238B499C5CEE68E946454034E4841914 +987B718F237862C350178B8FCBFDDDE9E184B3EA11240ACAA8AB1880410F42E0C66D7A2F +CD1DF1A3E421353590D9880F7A5A0065314D2E892D45090526A1378ED18A694F6820EDAA +5599C2EAA34954D28B021848397DADFB07F7529EE0C975F5AEB815D91BB7CEACD2888F3C +9EB8BFC41EEF2883618CCBAA18890E36B6CD9973E0A0665387DDD9829DABD9DE59C20652 +6608C3FE3D5033C33DF477762D37F080E3CC292D9E18348B2200956458F0CE0987B39876 +733331F948C4F15C818AEB8F829C03DA8BE6EEB40AF79A1686AB9A289FFA67BE3A42C396 +D5D24246959921707E84C9D4BA448BD725D6DDF0F735C9ACA2FF7CC28B75A81100CB2B6E +05B75DECBC1204C68ADD1B324CD24F99E5ADF9DD3A41CDF704184E27303DA98C72037B29 +276445BE607B12363036C6EA298E2B47890FE0C3948DD0AA3D0FAC17ADA775F58FCC520C +3B289ABB6315218DD1D5A6F36198EF93C58096B8A4A97D6B49278A7E41E0ED9C9D28186C +C8B5D8DC860505D94B5BE90D1765C154C43238EEFD91F5A385B6FCDD19272F1E9E3E50D3 +83C523509B45D8A166727E8022861AB6D8A8DA71EF875A19362015DA1672CAB7E9D80E0F +93A00867BF6A4B2894CBC866BD744013E8FED49596E6D0CE6D18D5CF56CFFB2BBC53FCBD +9F2B1D7221A7F5B539AA962F74E002DFDB8A1425A881DA6D62DB3E1E43CD9C20C4B8C0BE +FCE4B01FADC43B7406529B30BDD270098761F3BEC88EA6AC40C5143AFF3B926512F2D560 +F381B90202556D8E3AAE54712179B1C33131D52A4423676F83EEB850FD9D3281F4E092C4 +A3B402DEA3D01774B5BC9AA527D7E2A28EA9E6097064DF15F9A0F5B1AAE25ABA18689AC4 +2F1E2F1BEFF552DC96BFF8798FCD5877FB4F4B5082AF6D3F24293C7D34344959BA691E53 +8575D64484F2B36F1223DBC2A9959793C29DAC7C28E334775A1081818099D1CA68B693D9 +ED1D3163BEE2611E01B87E8B443A0D8AD12F251752E7850C29F2A535971E4BF055EF7322 +652B71CDFA987F4A51269AE8783EBD530F6180AD15739754EADD4811134E25FF8D2C6FC8 +9FB63D240BA9E80CFAEA02523BAE484EEF08045792885AD55A5D77F4A6645001DF9A596C +877DF33EBA8E728567A4C4FE3D848C7C16E8A3B156AFFBCCAE51E668656929F9D061648B +27093B54604B900461B0E9ECF73718C3B5FB199592BC7C59466F041BA9963920E2174F59 +7F943A02728D5B7FF69735757F5071904A2F6FA79DFD8F35E96DD4F92ECAF58A184CD6F3 +C05E50A25BE5E77BB2856AF8C71C69BDB8EFCC82EE65BA7841387E9CD655FDCA5707DD67 +26B96EF73B36B83362698C5945C75AAFDBBDA1ECA470512B7E11CAC4FFA3C3C66A07BFB0 +1F927E762871045195410E088ECB16884172E616721D58A5F51B5CC0AD3B3858180E1A36 +76CE2B46D4D91D06B146F81BED26358E5301AFD2DBB78D60F9F1A6185B50BF7A18CD41C1 +DD9065950F64ACDE99EBDCA136676247E455813438395B2D3FFEB24A2DE4D8D742EBADC7 +CEA283AD867A1239C224B59D55BEB159D6E4F5E588AD01DD7D398AD7BA539E6F82F8AAAF +9F5F1A7444DEDCBFD014548440DF870D701E9485467492E832E235FDC1AA087952B7126A +017E73A40F8CF1EB23E9BE25B942B2CAD61746F5277B807FFCD1C99CE3B2EC69FE5A648E +92A04C71CDB188935DCFC4D261DCD29215431D80A7979C571CB7E1CCBB7E3627DDCE9717 +148CA0E8BD7F7F22BE4ECF15E8B6CF1B0B98D55A3285DC2819172495EFE082B32E72FD3A +91986A13CCEDC5D832C77A4B559175C53EEE61089B4580FC39F34997A4DF83E427FE668C +3D89C417FE22308176F895549F6E5BCE6EB9AC04675AA645BFB2D81A22CB7B30CA206A3F +01B9FDABC7055B295236A79DF2522E4BB918AB2643351186D695E56E61CFF970A4118686 +E85A4D2E34C515D0203848CD2E92566F38E1D0DA886DC2BBDABF5B3D7B4BDEC68C5FE6C1 +8EA7E92F5470CA95AA5CDDB9936632E9DDDBC7FDDB86D4E96CCE3E8C579874BEED51CBE4 +D861D6657AE53192DB369EA930F87A9CD2FD7F9361D7CD884062870D4149126AC714B191 +1AC77CAFDD1C48686AC3474BDB9ED4B73EF67193714A392C4B273E919AFFA7EFBE7C690C +82E547D56C79ACC4935BAD6C4F333FB5774FE84084EB940DD7E002410132F4A84894E2E7 +4661DC6CA73050FF3BFC04AA8959E9C91D2EABD7447839F3B32E1ACF1482E6DB7ECF37BB +EE26C27AC90BDAFE91F8D92534DAE644CFC38E2A2C540A3868B0E16A6DDB60B02628A94D +5702C1EC2211AFC1A9F7E888B90263734588B6FA7BD2CFFF5B56F91A70633C1353885C24 +8C5FDF9CA938673645E3D320D7C5566F4CF7C9C6E86C9945386A16FCB72D342D936B0E30 +6EBECF12E4F45A6CEC4947A71D674128FB0F72C198E4F4227CF98E2F3CDB7E7AB55AE127 +1C2A39C526CDDFB66A183B6589505CA7F5EE98C400A6C760441B01000F2ECE968EBA5DE5 +102C3974AD4716D7789E07AA39A3458740D9F55D5B35DC0B557CBA9661B6588B37F63173 +7579616AB866890E1AF0B90399F1F7E95E18703E6F723E70B2C00B6640EBB44353DC5A25 +D007F285A25B3241BD80CF83C220ADB9288AE09FA0DBACA187671CAE9C04B61AFA10337E +75FE9FF0A4BF03605D0FFE41DEEB2F2DB93CF868CC7155DE51819D14FE17986BD187DA95 +96C1904E8AECA0F6DEEE83C9D8CEBEF4C0D13D5D5A13E6F3839CF955A6AAE6F7F5DE124F +0174F811324CDDBFF0247214BA4A343959EECD37D67EAB103B4B9CBDE0FB77ECD1AC24A2 +C9FDB80D0C07AFE58C4839CF9D4CE6B78A1173AE2F05C51F17827754A8EF22B5FA54F3E5 +9ADD2A1103F898664DE8ACDB89929B04776F51E241134E9A77F071CA83DEF1E04EF457C7 +56A29D540B3ED164BAE4BA2C56967BCF5BA142CF8640CD829A952063BF1D9714AD903999 +F3B59167E2B440BA083635B6A11A652E94AA1135F9E00B0BEB10B533811FEBC64C7107EE +7A2B4CEB6D019A305F633A9229121A9E1097C289129181CA5EDFDB7F9EAC133C6025FEB9 +9C9BBA2BFA67603A7790A146174C061889EC6A77DAE40C6C4E002263203BD6BD05D3699C +7C21644A24D562DB3C2CEBDABD3DA2F607458CD4EDB1FF6F9275F767B8FF38AF5DDEA7FD +A18A1CC091BEDABC7C1A959031009969572A97AC1C6836F3C24F6960ADB94D89C5FFEE9B +3391C4671A09EA87B8675CE4D3C473E3B8A750671BC95439E75243100CCD0E0873A6A218 +C8E574583C968E46EC6115266614DCF130AF7F2CB1DB978B409846735D7B29F1F8042921 +7C32639EBF476E5B0EF1367F65F0600DD11C0142BA2386FB01479DED4F8AB419AB5A82DD +66295577726A4C30D92A8972B72D0EC338487B630E86FD7984A97502583B27F5D1BA3A0A +8236ED3B99EF2AFC4018CF8EA12D89158A04353B33FAB1E638F1817E72E8B6AD3C58A86E +0DF708B6F1EAB273E746FDA3A8013271F16D3F0DBA72A07FB48CA2E0815F5635EEF35FBF +27DF180FE2F9522E57CB690E4DF7BAB0C4F07D34BB8984D569340061B64C6D1B5B5E2090 +31A81A794634F445055CAFCE9E72BC0724EE4C9CE1F94D461E9619B3CFB47B5C404D15E0 +3C61B1F11D23808893679372E8BF24AA8D6D443F9A29C2908331F799593CBFD1AC2EAD9D +855295E0B486E8AD72F570B3D768D775D4EDE2B9E48FAB6EF2C3A72F458D8B2DC2D534A8 +55FC77ACB99BDA7B5FD432D848815D327BE30A97556203F1C4276993E1A83329E62E8288 +7ABC85C17622A83B380B8E0C381376DA627C5852F0A031B80E22273170CA4D1367B183FA +169F6EA37C541C3E4EC299A8F34835D56AAE798E69B233309FFA71761469CC4736E2D627 +073DB92380000DA1B9D6353AD27DB894F3DCA36918E7CA103B60B1AEC505D6BA9B22A92F +BD69B9B2EFFD277157AEBE234B579E82D829D06DC06E67A4AF366F76D9321CFEF7DB3167 +3024556E61DD0FF006848A044D80407DDD75F123B155681F47C15283A44286FAE9549D8E +49477A38347F5AC9940F511E0222BDF46263DE6DBE16990D0975C2279487BCAA41177833 +C54F854836CD22346F409021DD7424D157B2E6DC9CD664EABD2B5352B1326C1C046D6E91 +306E84D44B798DFACAFABCF352426442DA14795EE6EE5A1E451238E946943534A0E4D53F +5CFF56D8AA689FE7E45D8974C5CE1D4DD9608AA42A873D0A0257D8766E7DEE544C350556 +5E58D358F0AB8DC7038795861DDADC8B0387D823F3AB985FFAE915019CE53B91A2666F39 +73143D04434D1B572ACF9B335F0B921E1E49428DA8AB0BD8D09B351C8BCA247A86FF7253 +4EF78A5150BA14BDBA2D535D5A46017518104E810EC678C9202699159CD05060C1C9A5DF +7421F17177B9141550BC2B2D9F2BC5DA1346AF811667AA0F5DDE7F690B366F6FC9C3A488 +B88D827C24ADE4AF85A5D5CEC82BED8485EFADAB9D9CBFA07A879A9D6141EBCB10028BDB +83DC99174B710E444714AA5D275073EFD6C542654E303D4F61826E7C505FDECB175C31F3 +455A2E835D12123392DB79B22ADCB30658228C0142B6D271FEACA94A186539740AEE942D +11F4B10B00C6DA85D934FDA37B37332E61C66AB95EBB5473308E3F2E33F220CF1960202E +5A2A81C85E8E831D4A48A7A9CB178A3F59AEFC408EC69D76722CE9FE89F5B7F1A31C7606 +32EAFE6DB673C6E76B0E472B2F0844506A481EAB5479CF0C559F02718F76D41F78B2CED2 +19D72BD4D9CFA3F99F1B8869E0A8AE58F40DCFBEB1B8FDB98032C3430E7402B9B1A93141 +74557B5A1CA485CFCF20D6830140FE0FFDE105A08DDB301E2109E5E371C2EB2568481443 +51F989472D19D12AB51C7F23AD18B592118EBB0945747EBD9F4DABE0C8EF4F3B8AAF5FA0 +34B3FDB56EC249523B1A3C32BC4A6719AE510FB82BE0CC27D6D4FA2A806941EA8E3CDEB8 +A30F91078D22260FFD25E57D8B3BF7A743031731EB7396D5E9A949039FB9ED19E38D5C5C +644696E3EC29B78591F522484829BD1A58FA3595AB26E0566838DA3ECD428D905824B697 +3FBF19090E11E99B789B61C0BC97C86C7FFB32FAB5C7FE00EECB9C8C126C55C959A6B06B +C709F0923589F9E540E746AC6949DE143744799EBEF6761AB9DA2E06127C18617324286C +874740B4B5F82DEC59585397A4B75A5FCE31AB26478A7BF1AEE14AF3098F589C1FB7C010 +ADF80512E936F57CDE3B8E244B00A80054664EF33B5BA3E4FF2F43DE74496A57C0F13B65 +A60A2F4CE599BB104E72EDBF9BEDE7B943F9404760B7A79AC38AC19086516CB33AF7F962 +0157DAD4D4AA68B8C96A66AC15C526A1711081F56738F3238EF37EF609BEB0792D41941F +6F1C7D95E0391CFF720A51755979EBE6323C653EDAF0808644E41FACCC09C29E1A210B10 +881AA79E4D9714F33A96735C3B2D0B13EE6272BD4D157E7FADE7F6BE9825E5655E80A018 +5EB33917002B5342002CE5D24859B6EA11E571FBD6F1F753974F965E7B5A8E0B3BAA8AC4 +A6C6D56EC55E44BC9D42C8A9AA29249B420DADF448F6DE76D1DC62763D5B01A4030A7D78 +28BBF81417BB287B267F64F8676174097E43E99785609F9C542ED5D29121D5626A9C7461 +5B145C86C2AEE98A127B25A990D9D73987958DF6831FC937B06AEFEEE14583B91590C768 +7A9FC1CEA0EAAD6F29FFAE96F8ADAA658DE66B8567E8A9E56D866B8A9A08C3D389B3373A +AF2D0AABBAD35D8F3AAD5D04B69CD31F7BE8ACFF96CE6DB8C42E9F842E4254EB34C2DB18 +F0BD1D6EFF4ECDDCB5E77E92CE64F20260E68903EA705FBACBDAAC6CDD7FB431948F1504 +876DCAE96AA501F25FC5707CAE2DA29E995B6C4BC6CE6C641CED312FA02000D9057627ED +14D531443C740E7CA081652087E0360C095652A1CC56A27B7FA61B3420ABACDAF14E02AC +C80FD7B412A97CE4F33DAD5C747EF14281EBEFD492468839338802E42FBF554DA46DDE16 +88D26DB26DD3613986E9D28D14D4BAF9F739F93E8EC34A2BBA207294D8212D2CFE560918 +A72DDF5A537C4571281DAB8743A487D8C370D67C0EFD1698BFAB848E86D24DA2D213712B +BA731CA3F76B657051083119FDA759A58F8CEF458085052FB1440D6938E438774FF94EF8 +896FB0AC6A92DAEA2E7C00BD76000C5BA8BAB7E5282952B4F16BB9AE8265F8637118A4FB +F229CA87AE41C6ACDF9F8D318D6C3028A70BBB245DFB2E1137E3BE90284B26E8FF4CF77D +66231F1BAFF98284128D08E8FA4FA75981A22F45CC026B1906FAB73C2FC219D3F7253831 +17A24392036B26AEBF3495F3300F63AFB9F0FA950673F5584FB20CDB57EB0E947F31DD76 +945838D69875CD1A4E7D2AF5382044DFDE866E37CCE23F3D06B1F5A941FD06CC0550D64F +312A9D6A655414490AB1B1FD54E34748E1D408782FCF8FA6A611232CC7218B4A0EB93CD2 +09876191651777FB56BE434096B02918A658A7403E45F59A1CDDAC1BA53DD186DB8E35A6 +4078C11DC0DE5165205CBE612FF365C193BA540F5C6CDCAD0255E361622E94607400A330 +BCFABF835275473D4C7767015963CE0FB7DC88B4AEB660FBE4F86039E51DEA6DB4DD229F +73D4A0A322C6D349A4C8BB304B96B32DC129DDF372FC424D1815C4EC51C9B0743D6831E2 +6BB5E28E89DAFC8845F00E47992877FD57EE0C02A76FBE2FDE8802A176E8A03509AE57D2 +0CE44217026FE28F2E06435ABF13D27875C5B4C6057DB1E1F70163C1011972A9C0DECED7 +6C8B547B8202977D802062E4189713D7F579093F4B9A72C69516F1179DC3512584977589 +461AC3D1BE8BE1C05867EF6FDC26E3B82D9CF9D159DC0CC1F9D6F94166A60E6CB9FF3FA6 +0D2B136FB725DE769BC3A8B64722456F049421CB7F863A357B318A979C3513C9065F5CA5 +93022DF125C9DBFBB822B1F84936DC5314F17DDF2960FEE70CA3E7289409EA5AE6F15DA6 +0E407C6262D41D52C864705B7DD26AF2CB813689E24E9673686ACB1970FB41CAA49378F4 +31C53F3A08AC7AF4D13F7FA81B6C3F71FF999380205C74E1B29B5A4FBD349783DF613FE7 +E2CBC7AA7B424965C42EF2CA80C60E0EC6F7665BB3CBC009F0F5C6D4E8ED5CFEF0E5DB9E +3DC006C98706723B2BEC309ED20CF1CDC60D66BB478B87E8947419ABD499CCE74F80FE97 +89041D176C3BEDC9EEF152024E3678134EDF755D8C247E3332F7ECE95E649E73A54C5BAD +228A629F5F6C8EF48935C8591910230DC5D04C395325F0C211BEC315F26F84AE8DE9DC91 +A9B5796CA0ABCD4774CC3DE12C39C2FC257165DD8A7E458E87CB67B6A487F10C351C4881 +0A636E4109845E0C664C47A2E11F9C99BD72570B26E854B4BCBB49F4011CB2CA4464FA72 +6DD8C1F05C69527991D634487D48BC554A80DC32B334D3BF6D65F1AC32D0E764825C8760 +8B6317DCDC713644DA60322D68CE38FAB781D24E14B19E711BCDB629AF7DB032CC9C4393 +195992B6ED1AF8B84AA21B5E3BB12EBA01DAB58DCC2E9549747FD222454D0327C66D62E2 +7EEA7AD48B09DE56F0968E271E59E8965E16862B7968A14078BBA821C2A4487F877E3932 +1D56C51B010AFB2844BB7E4AA57E3AECEAF7213B1C70F6EB993706C4F2A613257027370F +CCA30A862ADC2D07E4619A8F753B13B94C275A14403C97CC131A924EEDF78933502A8E93 +344E91F5A238B236B228DC9FB65C60F8888DCA6B8A1EA897530D193537FF73E8DC70B3EC +4CE290AAAABFAC0EB4C9534C7F3EDE90E840A1CE7975204FE70B52ED5576B0956E62EE25 +7857BB5DEF2AFD8D46228E9625C5C0FE48311A07CA246ADFD9BA1435340914455C0CAA4E +92914E7AF31E25438AA05FA2656094BB31855A27BCDC45683EFF1291934C3C115D8CF919 +7A245EFEFE3F7FDEC037ECDFE70737A4D961CA634AE153B01F03B1A9F72B602A8358D258 +E03E54AF79090DB322ECE0CE33377E42E5373F443E851550E5D44F06C1C513173CD04D47 +9A9E70C9774780821872EFC100F5F5F34A1E0754E037F6F5917EF5126E5F12D46BDDC038 +2D11C217839C1DFE8D34BE69124B3934B22B4E8225BFCB2F265E197474B9349BAF2C1FCA +352EF3F4AFAF1074DDB24E8A70218C83DA835CC97F6C55B6FC10C199BC9EE1033F6F2890 +FEFC3998D9F2941E350297F56B377A0EB5BA47A8195331A7CF3BFE934A97B88F18A38551 +3EA97201C200B5419E83D8AE47D6D6F3E864CFCA8A874DEEA5CADECD31CECFD46771E9FA +7B24F3509E6B0B04F8C4C1C8E27DB0F2F9E0A422988B2D525670841C73E5D11F4B1DF7AE +9AE2D8A3B5C354446C86862C687A3C21CA35FF2E962FB591310B8C0213A914278B65C7C2 +83E1CC558F6091BF4B159428BA249CDC3395D72E1D5E998C88F379A5C0DBFFE5833349FD +5C61034AC1EEA717B26646D9024C3D8763F3B33E60A5BADFB514937B9AEA89009F5F6779 +8D5D92AB0CB3D57FB123DD852BA04E3C0AE9D8021F0735B69289822FE2727140AD5B911E +376B13EAFACC44BB0F0A8DB9079DF3F3720779B5BF1C02CE47463281F6E496AB7695291F +26C2E02A026A104C8EC76E0DE5D7272A3B83A947E3568DD72E8B2DA7869D1FF74F6E6C0C +70CF5EB3D5D650498D267117C37DD3FB5870C84FB972E5C52DC3E0CCE6FA398D4807F1ED +F253D014AFFE0C5EF86A8E431D1EB82D6D223809BCEA39DAF9AC1CD37243CF73E0635BB6 +6B8887C9C2B2C740F8373237B52A89E589D811C40C5170A7B7ADC6C5643F76C4D5031862 +961B7E211127BD0F716CAC04C4F8D8D0958FCF4D420947354D495BAB0C0D2D76030FA004 +910DC71A861857B1B073C6CC56691822B8749EC78741ED8EB2FE26F37E1F9A3B36947EAD +661BA045810DAE798DAB615C0FA2B242209D8EE04BA06A78FDA985402076CB3A893E5364 +2C998BBA5F530C8944EEBCCF46B9BA42AA25E0D859953A948E85A8022C68EBD496553B68 +2555030C9336F53FE11C84168F19533F5AA4BA9C94FD120491D55C1D3FAB459F80F70034 +48F1AAAD448969D1DDC31D65619CD33070EC9BBF9B4A53C180015AB0D807744FB32AC68A +DFD7986E082D57C22EAD0C5352E86911E8088BF50E5F9E1D70241959CD3C18145B258B50 +261CC153E7CAB9BD1E723209024540E123C2333D5A5C4C45ACA1358790816CC30F3D9BBD +8453E76263FC425F7C2E41F79B402DD79552BE2C837B3048BD534F90B3AE2CB1F15A559E +C00F1E783101866534B0039C433AF1DEA08C4CBAB477327EB3A56AD0F7AF75CDEE8D96A8 +0BF499251B400B85B4D157DB4E54184AEC11547522A187287E945DBC7E31CE99E8499737 +2675C3059133BAE517DC46AE28E735C72E31B30AAF58CE26BAD1FC878E54A72D0C44F980 +4C9D5D93947A846B01F61AD1325CFA2DE62664F181557BCB92050CD697A26133B06D6C6B +2B2CDF60CE774CC5EF0CE86EA4E4879ECFE1C9B03E3EC73E35D53F5A1DC2AC8105953D02 +277742EE13CC39195503F2F5C8C29CDA7E4D54AD44DF4BAF5006FB9C081A938A5B51EDF0 +A20A005D40125960D589531F23CBA7C55CCF78C72DDBC8E9D84BC2A0C95DC0134FC564CD +B08777FFD70A0EF725693F54E8C46CD77A5B9FDC91E83AD010DBA9802E3E140943706AA9 +2FE69EC2474E61FBFDDECD7FA0641290E709A9145D8ABF5DC42285CD98CEC24BA9A7345E +BAF82D4461F027FD8C609CDC0EFDB7696CDB4116EBB91F0FD74676DD5E5C880CC9531A26 +D0256575BC551C3CB40BC4382B30302AB0B891201F818BFDF6D4BC88DA3E4CCCD97DFA0B +C01A7FD9BF8DAA71C8D18B08E213AA8FC7ED8E3172F80615EB510FCD5AC5D508047BE71E +5C0E2F8E200E2BB4A8BD0C4ACE1D5CDFBBF09C74516F09AD40BB4DCB48310BD33D28B81F +B6D0D04144E925C43A7CEE48D7772344EEBCF29D226ACACF8E693C74A0C11DA4177FB477 +6148575C305615CC381612776C6C6ADF8A92408F434717F365CD54EC0507D77032A1EEB6 +6478EC198AAE86D1DD2719CB3AB7A34757C07DAC27ED8A2EE44C55EB3F7074DBC98738E6 +175EBE6393151DF9EEBFFA3B8F5CACE947311B9CAA3C9BD0FB3B359EB30A910D2128D437 +E9216956AE6574F55D25E0E5D8A8E0C96293CBE723960A373ECE00A392D78456EFD6E287 +D57562DB3BC3D2A7E767ABEA1D7231C4888B7F7DA7DB7ADF3EDDA0815CFF72C4A40E6CB1 +2D55239788BCDC55F9F4FA9772782128F15E16E71F33F6C5B75BE8DEF23D8B4E0DFD8173 +879DB3411147841801D556A6390538919D7D2608F5140F564EADF2DC08DF0AD03F8C126F +FC49829551BFBF7EF652359414F56CBB309705B39D719A5DACD7401D6AB251FCC278936F +5A0DAE9A899AB62B9A33FCF22092DA0984A4BBC5C90C6F0448D48BF510E9FC8C9B67C447 +1271E9ABCCBB65A4D92DD146C910AC34752CE16939378F0030039D7DC4187B66257475C6 +AB2E3883693090DF350A42D3ABEDE7E84B3EE9187FF09775889B28DF0C1F289AA28E9EFC +ECE418B40D7AE3EBDA065B2C1B0AFEC58B67199E52E33FA3A305708BE5A2B5C88795617C +DA1EF1314095D09920B6EAC7FFE58978DEDDA2F17E598278DA325949A4C14C5C0EB76029 +1E325DA7F4DD83F453B6DC912C790EEFF754F69B308DAE37ED42DEE308EFE13437599F15 +406532D885197F621DD87FEEFFBC70BD47AB8FA0FAE972242FBA4F7A7F09D01628F87645 +1D3A6B885B11F74B42C8FDE4DC02F0E677F0A7132B751720464BC97DE5BD08EE4170E7F5 +036BEEF0824340EAB34A358635B8279825717994AE76928D15502BBAC200294388F53B1B +C01EDEBC38390B986B27E68AEF3C05883E851BF71A6EC8A3DA59A3767D40005DD98704CB +EE22059B92062B96273D77BA9BCDC6D856102AC322CED73033E6E86DE0CF2B015570C46F +9BB93DD4979472A4BB5DF56ACA2F9636B6A11253421FA471BB93A5561874B43C99BC2EDF +333511242334B62A0BD58E9161260561B9CB3CED25518A3CF7691ABFA61980BD4E5B6FA0 +7ABB135421400F7086EB0C4FF44E220A7FE7D92A159BFC63E4D01700E719D56BB6F440E4 +142852FFBE5ECC6B6A1A66D20C7F07A5AE5909685A3A71922C7AB0D1C18A27BB6E6044CB +B8D2C5A86785378EF5CC4167479142722523E12132F03E5D408F69CDAAFA5C55FB6E8AF5 +8EFB0D41B8448A2E30C66C99B5524AF66BC0F8C5BDEF2B8F0877C5E316ADE6BF0FC19DDA +AF9F915CF3119AED62D21C33DCE3F7EFAFF5A7B0CDC005CE387D4B16C6030F751DF94863 +99BC7E769FAF52EAD494C8154AF2CA80A6982C7F5B2206D9D4B39B6E61956ADFC144723F +99BA540F0C9D1DE18921A04A3206DECFF8D04C727FC9E88DEA9C056E2179B22AD2607017 +9A901B66146D0951DDFD1B9E384EB181D7945A4F83F2A06EB41A2459903FB0AC43CBCA77 +1F62A2E9727007042980C7FF98F349CE0CDCFF6F3447C3AF2712CA82D6828DB71C48A1EE +E331572A4591BD9D3FA077E2F29D0DCF9C68CFE2B6A71FBAFB0E02C241582E09E3C848B2 +CB8AB75D633C42598FA07F85D5EC3F577079CF2F0E68162E66D83176EF3B23291D741AA5 +77D747220835A8B966049F3AA22CFC0D6B1F55EBB917EF80B50487FF81BA7ADDB90CC430 +CAD43AD6199CF4CDE68193659F7E4860F259EB99B56C0E62390597DE3E05983AD165982B +E8305FF7E77363A9CE624FBC98626C21F6723F61352E036656B96277E783D4E6BD0EDF58 +5611C8D7BB3132B9E7C21B65B6EC5E3BF908677F6A5C5DD76BB16CDE31232CF2DD3F437B +BCBA6901A99D9692EF82FF0F8CDF49DAB5A947DC27007F604C3D2CA84455F9F30A75BA00 +71B9C36D21B4080D1C9CD31712527B8A6B5D6C39C29690E92E036D49E186D640E2F45673 +789BE4F96524657EC01BBF37F792212AC8688FCB572D26D10ECB727A316DD79CAD673E6D +2897D77D5EA7723E541C0BD23F4CD3DC2A5B9E2EFA15A024E825CDCC81CCB5B588CE4B18 +1D6E90D3EC7CCD947D371B98CC18A30C33E90EB7A5C180A6D500758CADE6787D5E89779A +067C2DEC491D78466EFC113586C71C5B7E2697685BF5AF1C6806BD2FD63DD7A5202F3C50 +93EC7D2C129E0C3A8CC8950CCB2901894B1233AB3F71CA25E34BED65930899A695EBBC51 +2F28FE435C99ACDB6CFBF1836CFC762BA9FEF40EC118CA6B8ED46BBF94082D4CB52FA712 +397BC0C630D77283AF633364F319FBCCDF6756304CB60B8A14AC86F62AC180AADBCAC4E0 +077C3299BD7486A05378F35430E5E1FB84A01A7C4A0B48DCD72BA02699B8087B5858C7FD +A52A85F08BD02409CE14EF70619E0D344612BA9971C830A0FA719F6EA5F3ADDB460C1430 +4A987565651FC9D13B307E48B7BDD9EC6CE1459E6062C2267D20D5D17992A4B84027B410 +36DDBAA9670152215FA62B5054356BDFFFA7F623EDDFE2BB20A935AED52A2EC844973BB6 +BEB38FBD1D4B21B9D802569D6255049FD9175DAFB66E7FB6E30170D872BDD64BAA1B16FE +81AC65EE9053D339A0C009DC5364D958ABF3E87D38A4E9ADCE9037BF4FC62E8D3D1812EA +8028CCA0852526736660713DA8E3B4C0CF2940659E8BB23F3B553D4FCD40EDE971697C27 +E41F2A6C0C29139B2209D091003326D69A2F081AC4B7F61BE46AC6662574D463DB86338F +40BC2640EF0CAC42C1DEE896C41DC6DC5A86B1A0E5CED10D826660947B11AA1E9AA44692 +E63082D4527C7CF7ABCD388E7ADC0C1EA3E4845469B19505F5E5FD66B65C50F9AB02BBAA +73B8EAB789D7F226365500A2E9ECD9A220BE7BE3D04635E9C95CC1196749F6B07151AD92 +12ECA4122683808000AD54E24730571C9BACE4A563029DB9B921CFD536954CE064DA5D1B +B49D74C55D08B1753124965A402A52188F44A14D9C28449C665266E999D7605E719175C7 +6070B3A4A28B6ED3513322386B2B65689A4B65788A6BD0A869468B4F3544C6E6E6ECE246 +506B988CC39625ED5148E0F620482A198DFD8CDDECC485F003B7A752B1B46B00DE60FE76 +D86911A37A0C26EE72968C5783CDB1744192EFD434CE8BF0B1C45DCF7226F120E85C800D +0C97EFC7159B9CC14EE505042F371750E32F98485337BB26D4BB702BEDA217CAF9F0863D +733B2406270DA91A556BEA4D620A8155258DB0DC3C11EBCE82561957B2AC8204DDA993E7 +58CCEFA6989442B696635B7D29AAAE8E14396E72F838E305E79F25B5AD19D4310A368419 +E3F773930F2D6BAF2C8DAC2F2C7F3420594BD9E1AC2D6CD7A185F7F673984ED76D18B836 +388084525C12BAB5BFA4844121E86E4C747B283ACA5C61E672679AE73940CB44ACB61CD7 +18DC458AA1CFB314A0769445D0D06EBA26549A4EE1AF27005D27ADDADE65EF1FC6EE7BDC +CFA6881D20F2B22972FC4357BF445008069FC6AE550B2D9BA16D565667364E1800167E33 +0A36ED921DDF850A3F993F0B00B1C378004CB008A631D30FD498D676AC38783DE7103FE4 +F314BA9168C19B0FC49363EE43704A9A119B360B5203EDAA03E7DEE736D7E6E94CB80CA6 +42C856E2AF8D68315141E7E9E9F63B48A9F3AEE965F0B62483F3C5AF47CF61DC4EEDBAA9 +F70846E660A7FED078BD46445CE45ED58C63AC224AAC16885D3F4E3F94F0779E180693E8 +B4A15469CEB06D6ADBC5DEFD221406A8C48B95A72303F54DA54B745B504DFC5F522CE50A +EDC0D27842FDE517791D8389ABF07F352EA4A752D4DB20B50CDEF5CEF9C6C8EF510FEE9B +F1737412D9CDE528A66B37A4BB9272BF9C8292BAC9EC2F66E730C3D038E981638C503993 +FF43DDA2C59AD94337CA7B45FE8C270334D4B330682344E372B08A09BF9AFCA47B68656C +1428369C660EFF4392C79DA407B29373D09D4EA1157A8A8D1D81D38034DE3E7272DB3525 +4547B81EA3B0E2C89E60992C4E95D17968EEFA64BF116B4A9A2C0C0B242DF6A571CCBBB7 +6A58E80D84D48D18C5B2F75CA84A7B7AACAEB5548F2A13D95C8918C4EA6C8087F866DF76 +46538BDCF0B13A918A64E00AEDC53F222D8BA4AA75D90121FC69AA03E8B07E1FD92A67B5 +02B9BC301225181043E987D5930FC2E3C77553BE300959CD767FF441D019828837680A8D +DBAE996F1B3739EEBCA8CAE9AEDCE3E3784EDDCFA86EC38BD460F979CFF0347BBBD36DEA +F8DB645DC277536BF8F1BA745EB4A2127CA7B71253C6539A31299156F12E07E5C9591C45 +0C0E804503F8F4520C9FA55A490F6C827004FE2413123851B780FF78743B72C9E1499B81 +77773A6788D1101D8551E12C46BFAAC185F7B6C9916796B3A351DBACF4A69A515EA1F765 +67B5A62DD9D6FBDC9574F8CC8DD20EC6AF803477B8C78497EA757DB04EEDB5F3522B1CF2 +E4EDCF923B14A6E4AAC3413D841EB5ECBA4116CE6549E55BDCA1DA667AE75F9626998ECB +5D82C4D207BF45C16A728847E952E8200194A04288336F8FC2AAD5FEDD5D17287B77882C +42E5F956B9DEEFD55ECDD8354C0CA47BC0164B2294C4B2DED139084B4C1213B74CF02E17 +C4B43FFC034A2051CFAE1CF99D72492C567A750C704AB26AEEAD7A06D3D98616FDB0C0E3 +34D99387EBB43874FC89A225720BDFE02090EFFF13CAA7EAD31827B6DE1E98E450DAADD1 +515D7A65B28AF7057C7B26720025A8918D1A6810F2147D64230FF7925FB42A7AE373C210 +5C99311C02EA1B33361D538B7742BC02B68E238BB4B62A4785B27F071D3F1AF43BEDEE81 +F7717E213F352B861562C314EA8E03B8EDF986E488A1664547CFE7A59DB4B657FAFD0DAE +15ED435D89355108E44135142B60C2FFBEDF32F28DF01F02F2DE4C3C40E95CB0D8D64E23 +672A423743DDBDD3AED5E910E634C9BAA69C8F6B33C8D0DEBF5FA56D7E6D51E7EC3A8DE7 +14DA3A104DDF5FBF10EEFDF85520ED2B71F11EB46ED74F70BA58146EF447CF88E92D99BF +681D3DC3DB4AD32D0915FD7C458D3AE35A060C59FD3A8B0B7E99A3A7F8978CBF381A6235 +D7534A4D11472936DBFDCD33844B8E36205089FABA95BDADBB0B55F9C8814E5F283413A7 +08CC3D15F487E170DD7DFE8C471FE85C06383D444F65298EBA6FC3761D7F8D6F18916A16 +EA794043EFFCB72B5837672E8999904EEA79EBE0D3464CB48E9AEDCDDD2FD9CF7C111C57 +2C280A48DC5B83052ABEF370DC98EDB610EA5E43C5A9A8BBFCF10917003E4E25943534A0 +E4D281F2CF61C6E7C0C10AAEBF23B7CAB563CE25555B82462A71A2D0C511390117AFC3D9 +3C948C1F37F052C17EC23E87B3B43B4E874A723DBD01DC97602F498A1993D8E6A5AF7426 +9E487DF83C45F7F9DE891963DDC7099951AD3E59AC9E5586AFB026A66E6FF8B3A9DDBC51 +79E697BA2B46BC285AD67722E8087F813B774AA31E66BBD187AD9876315619C33138DA8D +834BC729A8948E617CD7A4B802D0F7FB484807D09CD337097462B9690533562506B7DC80 +7CE404B4A1C2899535B13540A75DD666E1ED18CF75D95A3FEB472B7A596A007455682108 +01948D18DF7E008D8086552D5F472341BEC1A3E2856B445C0099339B9FE2ACDCBFF172FC +5BFA8A63067E9EAF13AC8D6F0FEAB24FF4E326A252BAE6F48175927E7D45F2A84CCC0AAA +1400A922DFBB601E2129A649464C417901D7EE4B66B91A6DF5B787F9B6B758E2DDF58724 +37F4658116E04EFACCADA54863E874F314AC25C4D10858A2EAF9687A4C45AAFB755251B0 +E2A298855AA83D44F254C832073A4E065694BF538C63CCC8CB0C3AE89663E24906614A15 +2DB4E4EC5FCB83A229285C1CE0B52954FB21A166142D8F82B60997DD39ABEDB4D3A8680B +8BED2755297909B1D66724FF4B556FE99D26C655F7BF055A529562F4B1DFD7A16166CF1F +75606228E96A320CAD4C2589BC86C4940FE50CDFE12BD5EB50A5A2B0223A6358FE07FCD6 +C791193E83A8B66766BA2F2E3D15E3275C27ADF65E2088D058082ACD6B7AA272B26967F1 +7606DA71E7CA51EBF5662FB025419DC26D155113947B966933287A14F066AC40D7028A08 +07130DA33A7DFA24144A05BFFB1D979252E83F21A493F7149C33D7508523CD56C09F3963 +322C64BC63B8CCCD8FE84E0DB44917107B6567579983BE44F73C9E524F44956C93D85975 +E4531A3DC0FA9CDB9916DA0432E4EF9C48FC9FC482BC9744F6D818889C4B5D0B766D2243 +B50B9EA3F0D20DE6A86F7D0C0F4B58E3B526C2DD36E01BCBC6EB8364B15909C335D8FCA4 +7845F72F203AE4FE8F9D0FD1F1364DEBF7EF7CB08D6BFA764A7E79B9D76A412D879D2709 +0F4D54A848C5EFD424C553A5CE0486D29AC6F2C6B372DFE8DF265097F184F2B88CB3C690 +052719F268460D78153B97D77F824C82B466DAFF2630CB263115406B8B91C9FE8E9AE54C +A2C96C85789610964525453B9D902ACFE6EB379887C72B472189B9E7CD6033F2E57E9C90 +206E218B9834ED77760A12FA0A5A6F86D2C226E1DDA31A5CF2D0EFBC4AA20242D662A869 +CC6A8C5E4B3732A9985A2BC6DEF9A1FE49309CF5557695B66955CBC49938FF605AB6F57D +CC7D570CC84A8F10C50D2DEC2BF6746CA9F256725BA75D273325E24D04AAF0F2DD9AA3F5 +F282773B5CB4B5DB26ABE691245BE7A3FF07C4AF6817725B03419F1B72068A5EA81870C9 +93E040F4BC52C454FD43AC24E3A7B909582F2AB3584FA66031EABC8CEEDB7DE30D3FA311 +A41DAC1CC909AEA330FCFA89BEF8D0D5217172BE25BCB3DC180DAAC52B9A95E588ABEE17 +105E3DA435AD2698CF07035DD5C19C8DCD58480CCD20C1FF529D37B5BF95716DD5B36F74 +B58FE28847962E7C3E2ADD93C91B529C48233EADBC2668AF421CEAFC5D8C65DFCB6493E0 +5A86E7A5CDAC1CB839DF0E099E67A2F8A7CB966BE497C573A5506AB4944AF2FD770F5834 +ED14B897BBAD1F3218007AB429C3250F7EB284AA16149DE1E6B6B540B5AEC33C4BE0A12A +11C3D63B8574C6B2B4155629FC9C13EFADB572BF35C2939226A90310A067B4F47A8719B6 +63035EC0FA87AB6FE5515F1B1419C12F06BF3D49393481B7F45534B71FED5E1B8F8B6480 +28AED0652F5C7FC254C25858EDCC0B92C6E6145A8DECF4CC54C822A6EA80F62122A58FD3 +1BFC6FBD5DE46F258D4215FC361C0B8BA50E3D63E7423EBD6EBDEF07696D25A6FB25F44A +5D747225006F4AEEE6EC177CEAC8DDB0A7D9F536BC69B59A5AC650AF57F92798785D44E5 +79EE905CB999C568B7DB553BD63184F22E59FFBE661535B35770A1EFB0F6530B455DFC54 +1A4CA7E19136D9F3ED1A7C8F58752296CF5232C45902E6129AF4380E677A74D06E2A3A01 +9C72A32A8555E52F5113112FBC4A2A42BCE68F7F5484D650CD206B0787C1875E7BF15183 +3FCE25FFA474F67497605D6C6517BFF948E873E4AC2BDB6995045E489D6310C22F6B4582 +906FB0A5484C4BBCE8FA61D80E4277EF0D37D09B869C0A174B97BB3E127776A0FFA4D941 +B0BC194C78F189369E13D86645749416506452668810DFB0B4011A40E60CBF7CFA855CA0 +F36C517B959FD11587B9C6C6EDA0FA01FEBDA786B36F3E21948F878D6DCAFA94E10509FF +5F8DDF25EEE7CB8E058F0BE6FB4DA87C28F225763AEB26BA7BFD8A52467F096A759F4379 +C150E63BBE70940EBD573424ED3559B16F83D22068E16633D95A0267E18EF9391B9199B5 +80A91B7A74BBF60CF13E4EF71AD3FFF9ED5604D73BD0C5A15812A439A3FE6641F2DE8B52 +EF0BC70B7693FEA9CA49F93525D29B037AA40A33FC2199C3F29139FA63408048F29B7F3C +6EB0CCEAF6C51D4AD842A315257AEFFEE6D5A02C9A56A144B0AB2837402ECDFE10B85F84 +88A87D9512E0FDA5CA64AB541E1BE99C9B89EFE7D3F17874F7593FDFBDE867653562CFA9 +C06BC81560883D1F051CFB128310229768A77E87DAD9A45810446E4E116341AAA3D4B332 +68322B7DC8984E41EAA6826393C2319424202AFF4928CEFDC24D7EFF4B64533FBC25164C +E0083FC7DBF81E663C4E1746A7A7E4D7C0EC4CB4D9FD396508D6A96CD400C85212F522CA +F4F6290CC2843E2B632571FAE0ADFD99A7E3F9831B0EE07340BF0C7D6EDF95DEDAD7D492 +DCD83D871ECE63ADC0A50C3E76E5157D3872E0F78E036B3A36459E78484C9307B3DCB831 +A99D9411C1CF4EAE117D651BE3BC04C2AB067E512F0F89A566F275DBBEB231DB42A0A197 +C301F33F4E65EFDDAEF015999BBC1FB75E1F6A7925D3E2075E98E314BCC10C94877F0B0A +007708984B326817A532F7AAE87E026AA715FE64373BBEBAE99A0F83CD0C77173DB845C1 +028F25015FC3DA0488676715D3EC8D1149A90AE16F418218404CC465D4EE8BEDEEE36F47 +DFDC27D07FB5F4EC0BB8DB4601DCFD54A2BE85A9476000D20181311F5B6F4111CFE1A850 +DAC7C23D30B674627F1A852FAC1F0437D18E6B3CE4FC7911FE7255390E0739D2A83DEAC7 +02185389034889A8A437BF74BFC3A5BA6BB8735A8FEC009D55492F7D43C5C6F92E469260 +4723A88723FD31B20AFBD42C150EE51108B05E8F7027ED40735A1D63931FD3CD5833FA1E +C77980CFA0F7A8C47164639255AD00AEC0764BAEB2045025B7C6536309CC9A38291A1F6C +141D1A42F33BAF14C5844C13E8AFF8A7CB4AEC72E6039A60CC67F03DB21AAF2976BDA0A3 +9D92A848D743DAAA36C288ECBDFB46D53E958762B1FD0F570F40154838506B656A081473 +18FF01FFBE5D17C131949F5489E4C74EED3369A496D05E0C9256EE92D3424E95A30485F9 +A00B0595FDBF84B03BC9672A4816D2D290AD1DF00E54C668DFE765D9EC28815477D7FB69 +781C0A050660946AB8AB1E29EE5ECB2C1A272591CC48EDBB5EBF26D765E24F5CF4BF43ED +17E5BBB55C55DAF106C46E4D8241E4AA01AF7CCF79176FB4BEE78D5299C313E2DC300237 +D1E149743E16081CF124BBCD7D9325125C9C9AAD57E86A94D18CF62D4E0785F820A9B7F9 +E3AE3FAF0F7DB0262BE9BA917540B8CD3421643A01CB26F81555B05DA466F1136A7F3E80 +3461C2F063ABF750BC814579689D3CAA094035CA96298F7F264C6546143DA15C6E085DB5 +2065E8ECACDEB3ED4FC0D1AA4B01E3ED36211DE438DD1B3712EC858D66BD3779C96D4994 +234A8FD8C1340CA9EA51A2750A6B0C65EE1C54C321F4D060F7F5F07B49C9528AE0A1D45B +5549FD72B0A15BF903B1F70B92458817DB0FD9F1731E82885835A717B0A1304BC067338B +1638D51E99D5C23872D4CE5097B89635C3BF28D6D2FC96BBD80C26BEA1968B8A59C278A9 +8BA49B1E59E3584E54DA5998C5E70AF167DAE2710F7656169647D2781AD1C27766703FC9 +6C08A0739EC521182A77410F2E2A788B47C745B4B0A2313F49AC8802EA461F04F3D54FE5 +58D2B21E9348C19FF519939154AA3ED07E24D3C15971F380551408C897D618749CB38BAF +625434B73061407AC05E0D7B0885791153FC0AD5C3275C03F528FCEA3BE91D9CA9C3B402 +3C931D467854D68DDBC0FBAF70D38365C0C76344472A876E74C04CEA12DAB0A55E776BAB +CAEEFE1CB7E834BEE48DBC155599C4A0BC00E6B8746D7D0B9CDBABC463D8E2688F46F126 +520ACADDFAE65101EDA0F523C6B9503D8FD1A5B9F0B6DBF0C286358D92FDE66720F5AF47 +CA87A0B6E04E46BFBF21EBD5CDEA194B6425B5ECF81518178E0259E386F5F852C6870E7E +034582EC658F59C2E07428737B36B77B9AD3BD6D28EB1742453C5D4867FE879805A80331 +C6E52C0557E5D036DB1EE67E7274AF769DEBEB23121AD503E3023A8515FD5ADEA11AA020 +2BCFE0AE826A09874CCE19AD2A2A188C7331127751342E542258D3996DABBA1B6DF80323 +5B6A223DE4F193B862224F807F99C0749994F0C72CC784AF11C411D34D649FDA1C77CB0D +BE519001F9E757BD8035A0C9AEA86609B71A4622D5C78589502CD2DD58709544A76526F1 +603F205AACDCB62EEF46D9042A2C9E76B887826827C6F22D73760CDCDD0FBEB827BD2E1C +3B5B0726A08DD2AEB614FFFD02C36F9E8B404160C909B70414BC8DE600A5D56479B83015 +9B8E61AADC8C8AA077816ECB6317A9B16D30DD8D4499FFAEE87CE97F72453A37D187D91F +A0C29A65A8F9C88ED22CF19CC0B40324449CA4E7751D77A0D76669AD420216EBDA92CFFC +50454E7EDDC5C4DAF66B67675B576ED2C90EDD9F8182589ACEF1B034D2F848D0CBFAF84E +38B7C42D2670D0A5E382FA11AD3F2FD6BC79EA02C074644F35842D1DAEF70507A361A0DA +03F5517B789C5684461F698F2FB20A7801CA9EE12981B5A793A481F48E33B596832AE4EB +7AF3681CC464F6895127CF10D14477611CF8AA88D0F6888225DBE342A708BD62EED4FF31 +CCC1ADB38DAB151C94E9A1554980B3C077683DCC0513ED4C55D57BBBA0ADB8A5E79A1B4A +BE43C703948452C44F1734F1C433797315C644A8E76D13DDF5E0296143F61FAD14E16ADE +97BC12ACC5DDEE482231A9E9145E69D63CFE889A1BEE0907362C60ABF581EA8541E36ECB +30457098E7DA18D6FFD57901AEB7913C59AF691D1A1FD3DF485F7EE669A5915EABA6456F +955F2D2F7D56CE0E349EA743B3F44ED555AAEB7F2A71711E08FB67B9738928AB842F6111 +2B9126C7474753CFB458EBF75D817175179B3FA956F1D998C52FC9CEC7217440889D0481 +CB91C8A8D1D1C6967964C7DCE3D9EB0BE6598DA5708DBDEE4EDF76CE91E128732A8CF56E +C8BA08828E9B270A818F98FABCA757BF3C3855C6DB448F7A4A6853522F7541D46AF3818D +B905D64847078757E0110C0BE6AF4BFF722FBAF5D8A4138BFFF94C7678A10F9FD850998D +B710D5BBF763B8A70491CA4D53124CB95A953B080CC31174646AD474BBF5BDF057A1186D +B083E6E762C669E935A02D60EC62FB71B6990D25BE44E949C85D1582611D826197E8F617 +CF2FC506489E59CB380E2ECA368916347B1E1B59DC1AC765676B904A63D7F8CCB1F7E2B9 +B8290B30E53B28F6FBF55D191BFBCB51F3BDDA71C7A9B1152F686191B0AD05FEDD3FC37D +42AFD7B3021D255DB7A00E6C2B3E714BAF7E61BFE8B7A88BD5B6EDE4C1DCADCC30565AFA +1E2458F35E44CB6F7228BA384CC1B7A64CE912998D42572F45A30B2C4F919BB21F66E1AE +6C787773E419E1AC1AD41A3DDC044C1BEC45CA2D0382A11C1543683F9DE1302FEB0C9DF1 +8BF8B9F0272132E1CFEB54E38A8B90C3F5630A3EF083C73C4E83BF0C312F09D5352F41CA +7C8EBF842E7F46F3D97C4AB03040640B95D465D50789EFD68A12F1A450AF35844A7A2302 +3F25728A85EEA2D9D124C4B04AFA44205E110CF923A4D713552FFAEDAECFED8898AFF89D +BB682A961D1F815C3F978B9C190006959D4330D772C884F6B0C77B2D1FF722DD86448C76 +A68AF642A08994966D3C2836D7063A59B168AABF47179CDD6D6F902C601A89FEF38E5A69 +9753828649B3470B5A03A2B58AA910B758ADCD5739611894DAE786D5AA005A5826DBFE38 +8B0F4105BC76C0437FEE9CA6C861FFB1EEF6620B7562B44AA0D29D1DBFE7B7954971087F +E8D291A0DB5E4CB0512B104EA6044CB75C099716AABCB5EC89B14BD18F5D1A73E9A8DF5C +A593BDA22FA28D8837519C38432667684C7C23594AEA6B39E3A819B72A00652C205B02B6 +F8127CA0C7381B8D433B86E6DDAE2ED9482345792276F4604A9208AD8CABAE8B0A0BD0D2 +7D0D5955C20C6E4425E295F5AF9FCA7DF682FBDD5B8B107B5FDBCBB0D751B2D2BDA99314 +A9CC66F9E92FF5048E5A6AE2B8B03611C7000B0903491DA44123CCBBC67B1D4086C22ACD +08599534BC98EDEE0A73117ED20679CF3D9ED1506774C67526D9AF3DEC36B9FF799479DC +52A70429F79C8878509E8DFB756BDA3D76B31B9BBD77DAD3956B1D951C157F02EDF252E8 +D02AD799A9DED7B38B352FD0841B96DAB3A3562F68178448DD8F1F5FE40438933F97530D +0E6C918C571B921F9F7B054B798CA04426237F4085044F7395D0E4FE3CAB961348D11912 +E5FC311138A82F470FF3C8DF00B1B0563BE81C25AB58E95CC392203F9668BF187DF43482 +BCEA0456394E31DA0819AB3E71FB8E02FDD90E05A39D0D5B4EF919E958B862C3A96A1275 +F66C689964B85C4C60A9E6D44EC9900B85245C8CAC2847882497A97043255228B8C29529 +12EA890FF254BD8C584126DAD1B2AC1AACF528564883F0C15C41A8749EE4AEF5FB514940 +060D3397DDAB08DB2113F942B03375B4A2AAAF9501734C17DC220BC97E367C2160982356 +2ED3C739164B659C480317952AFF044A4550DF79113B4F7FDBEC7B332EDFCAB7DA5B4AA1 +469479B4490EA5462191AD1B336DB782BF7A2CBFD7D4B885E2083110511FDE57459457D6 +68D29B1E31E734B30E4EE6AC28E8D74A2DEDD48BA964776BECDED8A86934A88D60A85279 +9E9C65EE342F2555ACCC0E47202CE451274D76C6FAA943BDDB5C35855499141FA589F452 +C5F424280D5863C7ED7544701C4B0660AC835D58905E458947DC5C220540D1FEBB4F18BF +7649596ED3C3F8D76CD146E5B5995F406CDC2F8D1D0D7CD4FD1BFF5907BBA5AD0B475F85 +D4C75829E57476F12E1315742C875008A96A06A76627DD694E1EFC09D05159B101C8613B +F0FA5E027B1C7F089D07B48BAFB047E4A75B101B417F82FF32BAAB877D7798A2DFA48A40 +85C47A5DA67FF503552D60295D5C61803C2700879C685494886505DB291413B22C7CDD3E +9C36F74A88E53FD9AE6E4AD73025C80555094DD7D1A171A1F85833A390793DCC86DC25B3 +1BF605ED87669F1D4D44FE035636746A80865E4320BAB50B42B6A6037B1A7134AA8B42F6 +4A85B58C318E600D80E892B337786190C009CDA82D95786A6F723408E1F79C330221E753 +F1A30D90450D9FCE6539A7E4B2AD69557746FDE8E4E6207FDC9068C400244A0CBF276F84 +A2286A98A9B4A60457D3C1C2B1FFBEBBA67DA76E0B3D1027B914755CA8152E1CA4542714 +9F709EE182D12B9D653D960F7242567EFE61643037028C97B19D96BE9F5EDA4230A329B2 +78CA496D0C8894CF6FF8A410AA93EBD0F54CDA812CB5935DAC06DC7968F1FD4DA26B621B +CB0C9FDD45A51E5043E501E17A042CC421E80413C5861941796E1F0213C02A968CB5CF10 +EEA25AA24095839B12D6C260D99B5C42B65C40824D408464B30D6F9E02E8686294CEA8A9 +39AF573CFFCAE51DFCF51D229D3753F144CBB1ACFE9253F5E36CB4199CB5768E6E1CE224 +396923C6E1C9B1ACDAD64CE0DF19C102CCBE2F7D206EEE22350016B1DFD13EC06891C41A +353318C8744A912692209F590799C99741F3656DE0110C310E8F460C3B94C7F5EC4598D3 +786D7C297707C6CA9CD9AA80A18141C9937EA927FFD3586CA76ECA5E5335DF22CB4AFBC1 +8DAAA401CA2CB71E1E97BAA78CA4D1AB912028138B9901EEAA6E17263C540958263A509C +1E3C266138BC36DFB2B82E145C794AF0606D7B9724E40BD70E3B83D7B32E32E0BE470279 +C05473C3649009D96F47300ED3668B9F140E65746CEE1DEEE623734F93E1C309B3F5E5BA +EFA93C4E96DDB8E14DB661CC2D23995A845F8916079EB740DF80158A8740C15DE4B367F8 +85B1755C69254BEB14DBDEDA5279C0A4BD93D43B940AC1AB933C20EC96B8B833DAB56BD9 +15C46666D22E72B629E97EB44CD41B441F6E079E40FA868F3D74CE320D23402BED7C4A49 +4468869683DD4BF0C4B59BECAD9706D091FF749B749DFCCADAAA2907457760A7A2269285 +F31D4D815E0AF703CF9A0D671F4637881245B134D4E25A8DFB7E58F7DD06912E6FB27CB4 +1B137208E30C0BF65FC3C078E9AD98BA6A46E3D29F035FB6A430964B84D9CE91A03F6719 +614D8F12760A8EEA1999780E00AD8FEE24095D7FEF3BD669042F0D03010814916A66401A +3183CC41D8EA4423A97EFD187FC1D832146031D4837294C35EE6E1E0E8ABE8F68CEFB5D5 +97C10241B7D8D83F281221F1B84FBA400A586364C58E1B611CE0E2092E0734FA0EA881F4 +2A8E82E9B02C0A5BBB21940EB06554D01940FE87BD2BC7D03032646D583028436B495E6C +A8F58566A946BD076D693177F13DF96B3A43C1650085A23D199A4773C717DE2A19BD8C46 +C0D6487698620D89A1A07FA0205D14870AA43C6ABFA2599A84AB5CDD18A66F6540320B28 +A1A9904402F62213DD74DEF28E2260842BA1F5ECC26C2450352EC67BC2C956C325B1F996 +4051364A7592346F0C28DD2C52BA5123691B47B857284B4862961504778C8B5E06ABD1C6 +F37E2343C185BCB458D42DA166D9479F8E529BFAB0AC782010BE8E526F5E4C17BF9A6BDA +F8BD46522BB6A877C54ECCE890C389FCC576B605B65C7D17A483FDA2C826A6E8F27915FC +9E006666AD30D11B31AEF6DD8BB9FCEFB655F4D7DB73767FE1FACFE15CEF7FB27C3ACFE3 +4E761F9BACEDC1CDEC22B0F50619FF7AED2689F2EE768CB0BAFB857680B15D9CE8AB0A24 +36450529F86FE3A7CCCCFF0287092F18AD672F424DB6EDFD50AE8EDD481022EA1FFD016E +E3B4BC8583BCFB45436471B5B4340892F390E061E0F28B4019812B0CC299C3D70151F87F +15018D49097A50B1EB5B90A736ECBD060A802A30632C2A681FF14E1ED5AC77726CC1B76D +378180CBEC15DEBD4CA283F2441B1E02CF8CC7D91A212EF2E0B1F194C196D731EF43A420 +2E0A1BAE1C3C1F060688BCEC9C24B07984F8EC84242EF6660E7966DAED4AD845FC859DB0 +71F1EA8C7E9E5235058EC9C42ABB815C699A883344E95504F9C5F6BF340DF54AB9BDD438 +B8D63DEA04CBBCE565E3D78B71C6E2C04D4E1EA83DDB824C8AE8E9CC621CC1C75906F900 +D2152DF36AE9390162C3DDDD20E79F9402FFF7A1D66377037D2A5E8F9E0889F55C711DB6 +38AFACC568A1B4E4EA06E3A3B749DF4026A0EFD2AD56BD458D9A5837F046F81ADB9C1872 +71238A54CDB3290187DB1504008362EFBB553C0167B5B58DDD5DD0788B4806D02AFDACB7 +78DC36578DB5486BFF8FA27ED2705587C3B0A471DC74A47479EF2B7F0D35A77D9683CCCA +F64C5E79F57F96DA3EE6666053089561CC89A0AD22E9DDD5AAE38F6ABDA3476E5BF7EA15 +B4D782E42F6B1E778C9CD33436D1B2B72FE8B01E18E01C6558816D0ADE36FDF34B8D8F2A +A15E028CE59BD9DE568683CFCB8ED3CFA289CDF4525A46BB7B0A91A62491A09821633CE5 +C54994009761A3E6DD30D61612EF66F49E190A2EF1D189D75C9EAEF9CD21E505F9CF63B9 +5B399B25C2808CED1FC3F6BCD950156394711567792045A8C90A10A193650379B5F44F80 +B9D3C265064754B0390963D2A060AAD443CF6C377C6DD81E4B313D94CD22DE546C56CE4F +06FFB5C4D703D1CEB9E9957ACDA546D0B327450F212252B3686FA87442CA18B2B0D2C1E0 +F91CCD54AD769C78D4E719BBC32554B6F486ACC1EFF4C8A3DEC5C359821715C2B64C2CD8 +43D25F4899375AD2011C3A89914CBEA23970C20ABFC55AC3318BB03FE1B061CC5E1C6BCF +B4E5A9488F08845DC4B03A79CCD15CA393BFF66051555DA32B68BE66DB340662F445782E +EEBEE5CFDB73AE4F9864435B828D168F17B59E9ED6B1E4DBBEBED2075911DFEECF1D97F2 +C57D0D5EB64FCDF7BD4F2F390F0182C997AEA6B3D5C5AB9CA14A3928F6358CCE901D205A +ED5C22BC9838128C8631B69B02787A956865F15EBDB937DFBEBAC70381767AA7EF592146 +BE4EC825A96C8695E9DF2490962D6A9F877E260A19362995C03E00B44DAE22F3E1AFFECC +ECF056319ABDD8009FE30466EAD5BFF178E43BEE8445C0F3A4CFADC000CB29A66736B803 +46E6BBA25CB8EDADED812DE0D7962C2C05A0DAFFE6AE2604F628F823659537651DEE00FF +795ABFB6C2FAA5E2531A36DD12AA069E8E0EAD1C6737FAA3B412F97E6D5DAB28460AB7E8 +160E0656C551452575ED47630A545FDFBB6763F61CC4BE7BD81AFD6861AEF0B34044B583 +836311C2BD2F0A5C74A455962A1991DC75DFF5BD46265C8805FCABE04238795013F09F40 +D2F2F7C5D12F251752D938DC7C9BE00E5F7506E51E0EC4A7AED0FFBE5353DD0A6FC560E8 +3FEEEEAF01316D5386633AE96A5609FBA122684608F90C54E9E3C1700ACD31686FAF7BA4 +84AE837057BB3FBEB1B6C9AEE7412A74C5EC366F682BAE51CA425FB274D17C41D0DA1632 +751E2D58CB0837549DD2296065176FEE15365363284E0F4778575C464110F5CFB186E92C +B488958079B3DDF229F4448C19B24023C1EE9F226EED46316480F01DAE2D4A5EA42A3DB3 +85E3668A3CDFDAAB384BD79DF85A103A8E09561B4E826D3079658295512DDCDB7AC7ED56 +0966855109359E217E44805FB55FCC926CBBD27D34D5D1339D9306CEB6BF3468616AF144 +765C64DBCFA2BE91F92AD7DB47DC92CCB3297AA99593851BBD29C07E7011584945C5F390 +E048B582367C97BEDC1B31BBB1D2D8C038C05DD28E3915D6E35ECA809B335190DAB354AD +3D3EF2A5E3FFC5D8F0F7A87A8EE9C6F9E07154919054DCE87D8FFE62E279CC05A4DA0BD8 +B933A49F7FEFD11E241DC1E4786B73D15FABD2915541B9019AF06EA28A1DB0FC3ADDE1B8 +A370187BC285F66D544A23184D17E346CDD21C0B1ADAD499D78EE0258279A8FBB802EB50 +887CE8290DE6F29AB3F6D0884BF63AC982A21682CCA88BBA82A237F39AC8D1EC827CBB72 +559AF2F5E640B1E43AF7448258469187427A600608E5FFCFB50D3406D453D30B830D0B44 +B7BBDBF0A5F00A33A4BA6429C9D3460BD6DCA861970E123E67CDC85ED1A304FCD0C18B1B +19CA443F0B85423F4EA44E0A31DCD363CF59630319D2ABA44E822902062C4194D1B4A04D +DF98F54946C5769EDEA86028E88DADC98D785521AB79728C029FE0515C9BB6DBDCA26033 +1B28F70CE1445AEDCC0E267903013BA6F98A564E6FB70FAD1343200A4E3AFF261381434F +4C8E3DCC87F1482C99E9E2EFC4A0D7352DAC825045D1CB8E102D9FF018467759C808D863 +55C4D25B3D1097317FDD11BA90BED164B5204A40110751287F19926A82FDC6E8216584CF +CB1B805BA9237ADA8D5BED21A89F6628495EE78DBBEC0163316E7301AAF1315E00302F64 +D22A33EE587C3116003CFBE41718A07DC7CE295DF8D7CDF05245C46893759E0F2DD35507 +CCA29752106D0CF2DBC8CCF6ABA8826EA7B0455585B26DCBCF0F598A7DBA8FBF04879EE1 +82637DB44C1FD37E7A74481A333CBEFE4B413D8AB6A3F4DFFC471A611CC70C55618499B6 +5EF14ABA68839AB4656971DF193FBC70467BEB52171F3E140FF40BA1C77BF02500842784 +4A06AD4F0ADE586113BB339DDA9FA72FD99DA3B1FCD26D25E79B28069013D8FBF48897D5 +2B92448BECA722F486F3EF5C751FD6DFD0560987137C75E466FF9F2002B7CE576A9282B1 +ED5450AF132C858CC092E7CE3CEBF5C78E3DE84D130CB8E1C9A9D08495FA3918969D06A7 +8D10750170BC3ADBB4628BFFAEDB8F47A2197D95DB975DDE5FEB8FD97AAA479AEEC667A4 +8DC0D8D44C02F7B7497A394944AB7094F3396623AE275B60F32AE74A3ED40FAC1B465F26 +6A8FE9162EA850F4DE855DC492315E3DB9390000F84363328D4891009B8F10AB08F1E4FF +DFCD0B78719F59B0FEF3F2D7990F388EAFEB85C6F8383D3E50F3317EDD0B44AB566F798F +F7B1CF7C9CD522350CD1D92E56061D508E66FAB2756999B57075108DC7A0AAB4D77849E1 +00B8B7B5690763983245CE5B96853F7E1E90D5807B02C0E44FB50170AD7AFC8CA8229AD7 +941453154232B97C0CFFB5D710DD5B4AF78146FAEB62DC9E73F72BCD539713B683311ACB +BFBC5533E9800939175CDC5634FEF7D7BD135D6347EE83118C6FECD86799534165E063CA +5461B7AB4002D1972C22665FE8F75B4A6E7CD2D868311ACC98E29AED65A9DD734A55E7D9 +43A4F53D0602F79E2EEFD38BA394581DF5895435A9E8FA35DBF89F3F7E00E09EC5858D12 +6D0993DC87BB9331168488F7B12BA780D07450007F067B824CD0D7F0FCD3EF8D5DABA99E +BFD130AC89B20F0E2BFD4F8256D1B4041F90E3E145DF48A61BBE573394B2E70CF92F274F +4639A6910E6E6945DA69476BA89E1CE00241213B739E1C9A0A9B352DE885B04A47B10BFA +4A040533606F2585F78DAC66EA103984E5484A06D583AEE68BD0D8415B0F6CE4505E571F +3A21899D8CE43837035AECF430D1AB85A8AB0080BB31D421FC1818C32CC591417CBB595A +7FB281122ACC1742E7A7B6807AE5AF3F98C94B85ABC8FE8482F5CD9F7A0A18DA819D2A8E +A1841FB1255E3F4DCD1FC2BD3E182A45AFF9E888D7B3D49F4C5272722BF9CFBA654CEE4B +09C0C9897B4495BB6D38B00F0E4CF7891D61CE6542FD8F84C2590C62C47E967790F812E5 +D0DC81571ED64FB311336B154421EDCE032F253098D7360F2079719047F9A47F2AE63CA8 +DFBF90423BCC6630F75CA70936096BBB9719034946F340464563DCA8ED94EAC3837C497A +50315ABFF0CEDC6CB3B7B1C30A8442648734645999BA94AB7EAA67798AB5407CB484344B +86204DBB56D3627091D3709FAAE6CA20AB5733F556C40059E56B42DAF823CD0F5139B240 +7CB44AF4DDC58EB2499525536E01363B4E1A36331838E88C6F0BCF423F70DAA9ED12B5FC +98C606C301616A1DCE9DAB545FA0ECDD8B967DFD1C1F096D242CB1368A7075BF72E12B91 +A953923276693A46023276B9BCD24108A524C40026E305427EFBA8D9A8C87D1AEEEA0AA9 +F4BD27476FACEB36ACE046FD8A5AFE4123B6944DA5E7BBE7C4F608EB0DA74DF816ED7453 +6DD277F8E59F65AEA8541DA98E492DFD48504D645345E957129E2A60FC5BAB29BFFE74E6 +4D66EF0BEBA0B02A78BDFF4CDA36A04C20AD552AA92BB75D52A78745C7B47F7D399C17FD +C56C1588083E04035263D46D90144165184F0E630A4FB68874E4C715A3708E84A8C08142 +988557DE1FE684AEA24BED59A1AF602A04F7E916FECB96D2D2149E71642AAFE15B0E399D +3C66A5944B4B0BA234670AE5D78380041161A606B33BD1B38D9F53A592D3C021F6636731 +6110C7E4DF35E8BB85F649E568ADFF1736A1B27E5B13AFF8C4504230D877FDE932AEFC2F +F9E0BFC61BFA1541A6F2C6F53A22311DBA8A8067D67EC1A240E27F85FC0D46C4DD2F519D +7B72897EA5B38704848B4834AE19C7BD5E19E5C65BE109EB9B02CB0376E603B1B6BD18A3 +CF63B906F8BA66BB52B1BCAAFE70BD7A2A184424DC53C91582F47173486998947B074A87 +B49FB5148B6FF3FB34FCCD25CF2940042E7E90EF0E9DA4B520F123CFDABD3B3CD2DD8CA8 +039F6CB5E379D17FF8C3E7F9F597A25201332F0062A0E6A06CA14750DA000B4570B4B3D4 +859038CCA94E63854AD5DF2AEB672F92D99F6E5B03A8A174D64695141A12F8D6E0BAD839 +D104B24B2B02F83B30910AAE4978C9558D256F12A120EFCC8BBC9FE8122DA3BB72C7A77A +F47200C9C18DC6560B9D3B82AACB581A4F3735B4D2D215CCA7046DFCB3468917E96B6A67 +865B57BD51428A0221225C3A79D3D129B52497ED727331C1924340B127752929C29EEF01 +677C812CC6AEFCBFF1E3D24594D430E0164B6B933EC66A7FD00B4E701657F6766A186BCB +872F32AB18CEEBD3E14574AA775B3A73B3BA7BE94916FEA42716105E6326C21A59B62AD1 +681A9672934A3EE224B4E634B6B4DA3EF82969768B243092A98BCEAD10097659B9264DC7 +E83CA911201CF43984F4384DDD10F5E7741F78F3013591AE7541965489C0CE0B2C78228E +2148182930C04ACA997CB303C5C096147E25E0773262E62A8FBB81351EE809D416F63B48 +615E95245EFAE2FE041D10F0755A3FBED883200C13537A1FC5B1CA14BB847C8BA1049B6F +7CFD9784512E4D2582198F8594B4B689772DAA8EC2AC7969E3B20DAF8A17D36C91F1A5E7 +4FA921F611BFEE1982F590D8BC0613CA86B0338CA0F5FA6107B9CABEE94D143C98DAC455 +F64B2D213C5F3CE2F7430673D5E2224765ED4341D8FD04864F8861369ABE41DB25207682 +C81BFE06C3513FA019456A976CD751B29F4E65C7853DC7E5AA99539926284A316DAAC56F +64767BC4BEDACCE77C7D8C774F0896034ECF9B9E418203D94B94018D126ED69E431D792B +89FAD0AD799A0660B1282C226C03EA2E2EAD24432912D2D405A7A5130525AB9A4C6BE1B3 +CCF9094EE61401F04BAE9CDE3CFB0A0A1D33054F993EF6A6A8F1E026E744F19F19F8DD45 +01199F97E79F711C1C219532B448CCEDB409AA0EA129135C1791AF1BE7FECC1C9B1D89E0 +906EC96620278EF044C18228F5CBB67DBB36C7BD10DA5378224949CB6B2EDFAC66404F22 +42AF5508383B90080331ED71451BB59A8A2B91E05365884DDA3A23C9BA8A043C9A5E399E +5A4350138459B562729D850CAF38D18C4DD8B6F9D8D69402099C0791C82FD8F1937B1F8B +05E3D4E22DF453D2E8CE4248BB5A61CAC9E36908DD9049CA1EAA4E7773D54F9BF82D4447 +010C37DC6CB5A199B0BCA9AA3743592E651B69D1D4BD2563135944545A1DD8CA0B1928A4 +93361DEE737C834868A6CC2B6BA3A44E198D1EC12123BB95103C8699B4B76D7062ECADF3 +13FC6AFB6D364ACEE2091991D4045CA2A5E33C7BBFC82149C437FC423ABDEDD7E4BCA0F7 +BD1ACA371A129F11735758E0E88F453DB813998F91CDC3428B5D8FFDBAC983213F9C35C9 +C6B5B1DA85C0F0FF0089BFFE9269AA245A8F8BA47E373D2AEAF9F492835B1A3B3AD9AD49 +076B2DA90C516B95C8D603B758D285B811C97A3B28BD0DFD924F4F4A6C6B1C1E0F7E51EB +582914400A9B2610D008D43D9623BFA18A64B6160A72606CEF0A31DF88C7ECB3327A0F48 +3B0DBF54F1A02BD3DF36AADE1A65D4ABBCFC72149DA3992CFBF54D1DA3DAC66DB428DF19 +90F4C7923A23EFAB36FEA4B00661289D7FB382ACFBB03C6C82B58A46701FB75E36E1C697 +7026DF6B66554C2C36397230657BFF069FD03DFF9128A2240EBE1B838512F48F1482991D +E0AD6B6590DDB2052564F6798C1BB88C06D53C4D4C76A4BB1C35355468B3C71547D76010 +C8902F5DF9C07A43E99230DA6CC708BEEF6D3E976C07404DE4A1C7BBF11CEAD519AA6006 +EEFD89D2CC4351FC3E72415E8965B1785AD0E29EE59032F6D0487941940FD8EB73B9CE70 +704AE65D7C3E7E30FC066DAFAF38E2A19025F628E7FE6054694D7AD21ADA5B747E54AD1D +4DD57BFCADCDAD35E795A23BAA5171B8081EC9803B8FE6242AB1B421A20C6CD6A107572C +9DA40E22D64E0D053972699180A9B5062CF460A715CF99CFDA1861BA3876047D969CD8F5 +889104DC3CD6A91E6765BD2CCF49F21BAABCCCC6984D5DDC1F872F85A45D42C490352D53 +70695AA4420AC5E6A0CE1C5B72186FD1FDFC64CB7680ABAFFB390C494FDA8852E6523BB8 +E184A625027F79620D9712D570AA5E2DE15863B222F7F5880DCB462BBEC2B5198E005DD1 +17B6867C218FD965BEC790161999B8D27E7694909828261593BE4DCE97FE5868285EEDEF +EAB74A5707DC3C7824C1D4B170F729D9E04A3891E2C90FBA545FBB6F8883C60ADAEFD251 +6453F30B02B63D0438F927ADD8CABC0F78290C5D0433A1C611E4754BB72DB7A96364D9AB +8B698A63CFABED083D9DB7B3934DA6FED9C162D33BC52D95F98632C93A8B6611C5C3CFAD +B32DE2F520ACC68788CEB420269963C96B341D7702F7830FAE6CE78D23A99258FCBC3955 +9EA5748F18B560FBB1557019420217FC3FF9E1F98FA219728C74FFB024771CAB8A1675AB +F57B229870ABE51416A8D5906D27EBF989A3F4C6A94E0B9CC383C5F161B0079868B17D03 +2C992D39EEF4FF295EE6331E26022D098D1753BC6F949C0FA5567C8CBB382A92D13881F8 +734E4AFD1E7157D9ED6DE9EE7DA0B8A08F54B7C8121D9D4A5805373016BE8DAA8B2C20A2 +CCC748F20209A63A4A7988AAC44D829241E0033FE88CD314A751EA836287DB68B32C9F5D +0808946D8706556B3E597F70857C9C1ABC8728E256E9A34CA4D88D08A12AD64C1344E0A6 +7FCAF84A2E338B6734319ABB816F50BFAF49009AD63FCF1C9A4C7889485D7D6A3804A5C3 +52534EEE795E391609D1B6500321D29935FC49B937C061D556BBA407DF6A79C3372E1B91 +9539E5C21B816C060642188482BA31D8F3C4CAF759F7710E269235EB9F47C2699CB14C6E +0CB2DBA8CA246D4F8A4D95B4452A4AA20FED42E66C415FF1FB74BBB434FFF1831BECD82B +23B04ED0C66B5E1CCE3E166EC586CDB122D6FBDCDE2444230D932261DA28CA59BA47B23C +461E0EF7AD3E03C501EDD54727F14196906C9413FEA8E2DDB9C7B955B3A7B83D91DA4BD0 +2C7FD4A96FD70634E2069AD2189A546F0B4FCF0DCB00C0E5F3527A3F0FCAD178C8D2BC4F +4ABEB2250B4EEFBA149604B1A3D2178279E28B7E91E859E110510CD6C87D52E74CAF03AE +69A5D08D4F6A45B3DA591EC6198259C39E4ABA9D417336E18E0E07CFC28C84B466F034AF +A8541DDCFA4038288A6BA7A2503AA194DBAEBF3DEEF9BE93EFCDC351442B48AA8C0C9B67 +EAB4F75821E1FD55E60757D11BA394F8F336242890254F43F598650EE6EE730FA54E7EE7 +AF00FF3F55703D39B2623C7657E4CBB969AA8D7CE187C0119E485E391F57A6A42B2EBEB8 +F22B0F46012D822C8EC9ED9FB4085AE3C5FD36A9628B07B1A963337BA95E1EE89FD3ACBE +4921FAC06134DDBF72062F31B1D351020C16B886A36CA9D5EEAA6470CF5044C7B6710392 +1577D9D5CC9E49A36C30ADF473FE06CAF00A5DDB44475F74152D2E520A1975CD1C0A15F6 +A47893FEC6BC00E1A44E8F6A1651D39BEE76E67C83B735872BECCCF0F907207778C4664E +85C7D637FD201814BBC7D1C6200038B17F75E08B23F4AD0737259F9C07C47556FAE21B18 +1A110F056B1A612375A511FDAD2C291CF389622FD073F292ED09953B11E2A6626E6A4CDB +8B50B8F9C7147114DF64C9FD8CD2E064CD9A3EB95555FB2B8D6E8A4BCDDC54E97E9F0B5D +D3815077F6A825F924FCA5821E78BBB3E493F77CC71FCB3A5D9092453A0084AFA1ECF49C +384A274B9B2CE36C0B1413C473D041B4BE0080B561F7A03F5A1641A6FCD1959506EFE270 +88ACA5283BF1D38901F2E071BBA4B2E35BB79D9CE9CD3B776C7348EE014D21BE0421CBE0 +4026C044120006AE1816528B353850C3577F4A0CD8BBABA169DE487AFBDA975B850736F9 +1345BE2B5ED8D94DC2505B8D6218F3167050BFE7E723008CA3C29E3244509D0893C580F9 +4FAE8F724DEB1EE280AE8993C9502E9F40477FBAAE9C3F9DFD0A78FC38D537FC0BD23851 +8499DD3CC9E583C292D200B9A082008E52604EE8AABDF15DB108C8D5A693CD829C8812F1 +0CE53781E50A9D234AB33BE6693C3FB59B921DB35FDD87A393F137D0CE119CE835138F18 +7F2338E0AED3D973652DBB79D7761D39B8A819BCED55B483BEA6B5E971E06475D03E2B9B +B3B9D6677636111D4725EE36A077BE72347358A1EF91E5FFB77A0ED25542DD3FE9D7BC18 +596E2DF47A12A43F324444FE90226A63DC1CD5F265CD7EF81FE20A592D5A181B7AA251A8 +0CFDCDFA15B8A43A88F6889D2EDF93093DF25CC232BD1DB179536A1E3C46274F7F36A443 +86A764B04DFA73FF34D7BCF86C0A5122EA5332CA1D797DCCE9BDC7C8516BF80532BBDCEE +A7C2A883683CC3CBBF1E96490C2B7D21DA99A3D6A0ED78252B12E1C97CE41D2B837E948E +94BAB7BD87C929D8FAED67A8FAC5AF8E73F2518428646B0A70387CF9DF41DF0F4B5E7A5E +786909F6FF0CB78649EC9F653FE445B4D588370E86EFDCB1EDAAD1D2601725EDD7CB78E7 +E815A4B76528F51FB88CF25A44B187001C63988B6E32531DD4E961DF683D794C0AE3DF76 +D0C29D5A279E668E08501979650610050BE7FAA5B67B93E47C807D22B26CE24B9BEB46F5 +B09C4A4683ECE59E931850DFB86108AD5937DA19A2132BC076AEFADF3AE07F65451E7A69 +5A583E0741864156E31C4DB9795ED7BCEDEEAE6ACD259FBDEFD4B4F4F187726A7A247974 +7B22593130F566D3DFD71E500EDCA19CD8B7B7FB5EBAD025660F5D8B3F24A224D741BB9E +84942742D9D88E771B721E72859DF2CFFE2B288EABC083FAA26D815BA98A7A9F701395A9 +7A8058CDC1CF51740E293F51B6F0D61666A365235AE1296E1C9485A0043F651DF417CB94 +E53A1D79AA96CD5D8AFA0637EDC6CDAA761FD5F4E712745FAA66F74E7CA9D4C7929884D5 +32E12C92625B882AE1B60E0BFCB317DA1704F8A9337A42A8BE38DBDDEDC1E6FA9EB01F4C +FB0BA8A2B29D02D9DBE63D2D592348A645747C55A939E94753887A853D3DBE03C0BF8BB6 +C4892B94415E60C3B7927B3B7BDCF56B45189044192DD6CF8FD192C5929C1741B6E53FE0 +7B4CD9EF8409287D791BE417165B54D5FFEF0F742984E18340AA54EC8D3E0D7A479F269D +B8FBD0671C09E265CBE33A64CA9BF752D334803C09D32EA7EB774C32EC2E2D8706173E56 +C6A9690179F2191453DA57206855397146877BC55A562AF975C3715AA39F85C39A681FBE +F83A7377E88E569732533A5EA193CCB76318E9D6ADD7400BB9CFF14D698C4179033570C6 +D00D70E5EEF63015399E5F49C4DEBF22666D76B6D60F801D023FF4EE8D63A1DC0709481D +491F88979DC7AF7260BC0EE1CAD6A7A3EB0CE78C93865884383489F457F2AC5CE0C832F3 +F4B81820F37DDDB712560F066ED63777198E3491EBF087DA503CD59812FB082ED11E072C +1C1482D879AE9F461ABBD5D4BE7D8B50D50C55DDF9C49D64FF968207614A85DF8DD56502 +809FA54B200F7DD9A6D4262AD7F0CF61F87A69DEE18A9B8C67F1CC152A8509E64211A064 +F39F3CCE5894A8EC0E23C9A557DF5FD50E2A5CAA3338C1781D04CB638A47C7A5A6FF8230 +1867BFD856A6BF11BA8DF56963D17291AA202C991F7EC97B501F79CEEAE44474806A06C4 +00BA8E8C5AC49448ED4C248327E2CD223B9199ADA618FF99F8DB84065C36A8205F5D3356 +C690D972B139D97449C080821798A70E55801EB4532D0EA1C05DC635932D1848310C063E +05BB58B016A99FDD3102CF2BF2AFC5C6FAD3C031FA24F9BDAAC454529565E4EB52F838EB +D4A61A32FFB3A5768F3B1135629AFFB808AA85788B3BA755AA51A6580803B6CE45D94581 +849CF2FA75442E759F1A544237938E831F504BF6408034B034009BD82E623AA31B66D128 +2741C8692C56E3F251BE3D582C32A9B770D5DB3E9DA9BF50A527B37DD41C425623F3B787 +7186F26937B3E04E291EE805DCEDDFA214158DFE50A3ACCD0DABAB73F5F51BFCA200C466 +B9A786E7CFF65F4B24C29D39A844A6F6D6BE41C298C2BCCC5CBDBF3C3B731121F834E230 +C8AA3BF6E2C40EBFFF4723BC0B2AC407B93DBEBEDD49CD639EEC65777A5B6F94B8DC1C59 +05040D8E4B205068BDBD5F812058D4D8BC2E16114D22D81701D36665CEC878D148AE79B0 +F67957B5505708ED3D98FA55BAB6FD20E2C8BA1C326F514AF29CE979DF66BF1F71A579C2 +EEAA176A3632CE7F136885EF3D530C15DDB59C28CC8E820F55E31667E8D8555DF76807CE +3B37007E37A06AB32A21B2DD297C72785A88AD6F45784224D29241B013663073D8E1F7C1 +DD2BF95BF7C74B8743B31EF48655049EAD7BB13B87E648BF938059202183DD2970BCE1ED +3018733F8E5B7EF9255A29ACF581426DDB9224858BB380AC7BFFA1DC8D2589A83FAF5ACB +A4985D845B3F635046887AA62327FE0B0F020239E9FC7477821F7BD43EA2EBF1DC9CCF32 +FF6111507BF24557126C3BEAF30DCAFA051E3E9C26882BC3F4915F54AF9965505D89D11A +562EA74783739F0C788D0BE3547F16F9BD13F96D861B2DAB90A4BD23043D588D9B583C8E +15E9530D006DB4F17E0B4EA0A851397C4B781D707F98179B6E212A6FD87E2509B6AE4CF9 +EEEC87747374BB2144CE2E7A70B0F2C03A69493F9DD476675AF200F15EBEA4F7770001F5 +461B9079488E9FC1FE2EBC86DFE8CA2D2ACA5F746804F639228E813C8A1D1680F0A12499 +CE56678DFCF24FFC05C80F78989CDFB4F0CDA8E66428511E9BB0ACB8EC04161CC575AEA7 +522A229C75815C78B3248031DE073E0C5E538BD886F85555AA2E0A0456C2933A95E83AF7 +D16C8F8DA487452AC84487EC764A1A2EB1CC754F517FAD18C7F76769E67E3363D8881823 +6949A35827574BD65623CD4FE89C0F11AC2E050584CA49DEF1C513A8F7690652F963447E +DC79D866F8C42EC7F3092DF52EBCF6E64D19E44CE1403BBC3A29C56CAFA903D315D42058 +A01E6124B82F1093A3027891C49FF06C8C1638563F92BA051AA5F750FF5F6108F6C0071C +E9CA1CC669841592DE89A5383CEA9207C9DEF1A4FD137847A80630FECCE16A6454F4E857 +80A9B166DCFC50AD94E332CBC546CBC0A39507C8205050473351C6263B33FD705594E654 +06B19A80DBDD061D12BB89775D6BF4933B3FBF3BAF6B287A32EA01ED2B5B33C48715EF5F +4650C9B92EEDE15F46DC093FDE463578EB377697703D7ED7C0E576001487567316B333E9 +CCD75BCBA59E69E1AB62F39D0546EE67FD4C1339A93E01951F0C2A38A994406406D2C64B +D719DAF35CBB25BBC68E6DA6016ED0AD7E1930CB951C1CC22A8D82E144969FF25FF153F5 +D7A7A6608471BC31ED1F4B4E6E58173FDD83FCAC6FA079FE172CAB3BF667C0FAA4827244 +1445223D78002593602829313EEB37EF4EF8C96129E96484E36328213B9DD5F55B731167 +FA55DBCE903768321B2F375FF1323016F7A8C0B401BF8E2A983EBAC57AA4CE5668BBE152 +E1BAF5615559760ADAAFBBF1EA43703AAC9A74F21383017152EA311AC3D3F8762E1D8918 +887A0BD9E880D3C052A48B4EDEE667370097EFDE700B49D0A19F32AA3B43C9B58A3EC400 +DED3BA2829B90F54D8F0B3BECED9136941272DC0332FDDEAABBE38A0F8BE05287CB0D281 +DF55F4E8AB705B54DD026BC09E5831A64C728D9895D21E1FBD24D198ECD475CEEA216726 +E8BB15D4F8E946B5B097CC9C89E79470F0DEE451DB14D96C994DAFB07A0221BD48F79587 +DFC722BE7B360A93B98B42443494076BA779417DA3C17BFBE69B4B547A3EFAC6552E4D4B +9B03D51C863CCB46A8ED112C0B19608879DEAC918544B43B4199B2C0DA7B318FF13E0CF8 +47612E7279C334F681AC44CEBAB0D6E141506AB98322FE9F41430E69FA2F482CEFD68F3B +1280C9B6EA383C053F9474397E8800A6DB961655D18ABB68600F570C2D02E4750622174D +6A9AB48B05DDB2D56D74DAA537A642E1FBB63E55FDCD54615D08EAC22EF484FADB9862C8 +6FE2E6C300A367EECFE4337110796C21F60F9CA9D034917B1C98FA45EC79DA8DCDB216E4 +A3DD97F0C51F7828743AA768F2E442D2264DE35D7F191AE874B856C8473ECFF241A46AA3 +C2261E74BAEC485E0602ACDF8FF0A0077E84E6C8330951209C87E117DC57D6018E7D4EDB +E79E6F59C75D8D030B442B65B3513F74610B98C40E3C2D500D41ACECA44257F8E24B0B19 +4B6C8E20C51E61AE4F633F8586B52CF2D9438958C52F7DB15B499E69FE3BDC8E983CC34F +80B57FE1279254A228E7286CE78E771BF9436154847370D7DAEA0D995D9D7FC2F0637731 +29E076BF10576E480C1D82C29648A2AD8CD36814C67045E4A67737C22B5B5EA48387D991 +E35B8DB9695290D7CA13B1106C6FFE40A6EFF1DAF1A841F3A5F75B68D441687872E91EAD +4AE10D047756DECBFBE4F87262C2008D4ABEE51A0641AA309631D7E54258182E56901E59 +D1F6C7F15E8D3FB2CA70AE578B2CA08C65FFE542A479407F98D06F398DF54DCC16FBE30C +67FDD4A3227238EED53CFE2AE0088A1E2F9AA08917947C4CF795D3E464D55987C4DFD14E +EEE7C9EABC34C4F4C77B56C8E486BC35E38DCAB4E7FA1746C5854175AF400460BF82BDE3 +C9E066F4ABA7E1DAF6C04035AB86B1289E3702FF3DFE4FA431238AE487D486150A1C52D1 +047B1663D12962B478BB1E4B750FAA1E2A09ACE4AE89058F3E2B928167FEF099922EA552 +6435952A7ACECF1650B319BB3BB8734F9F54696B556BEA7EEC47E4A77D81280415E02DC2 +3F4D9A73F44AAA9646671EFEA5549FCC9A5915239DDA6E1C872F742B28A203AA88401DB7 +00C36DD78CEA2A9293E8768D5C59721D16A41000A2E1B230DFAF4A1BAC797DDB85BCC5A5 +A38BE413D0270D7259289AD4788D1D9769234BAE6CBA1DF835601A76CFA75C005C0EB325 +6A100B43C0AC0D0051084902D68F0517C91EA5F4161961644230055C97947D5756C62F12 +C550E113B2A88EC56345C965D81EDC09F62AE036C18AAD798250E5A0A07E607F3E2D0ED7 +B889CC2961339149DA012D74F290574735CF2706FAFF605861571D78FB92A8CDDC84C83C +BEBFC000D43211962C578111F8FB8E8506EB1871A518CC7313242FA11F8D51BFC3797637 +F5E1AC8EC1435B36D98BF1BF34C960C6CE650D5115A7A244ED7489BDB7F6514BE25372F0 +9E3F378CF95A0E462C0E0E1B4E84696F1977059079AA626D0F441D2CE7F4B52A49B14FA1 +19762B9FF8966772E936F0C6BBB0B24F7846FA1109562BB57A995AB8DA48C9EDD5E90FC3 +4C51EE9DFF7A2D4AC959320FE10B800C83E9B83FC89FA220F965DB0495A4EB5EB1AA21DE +5EB75C0CC0619C9C38F942CD525ABD40EAC721322D47D7117D750325AECC9A021D1A12D9 +D439AFC0425F9046622EA9F34FE1FAE58C428311D62DF1FACA2127AA627E91F5063FE47D +F727DEE5B989E1D4A89B900FA7A9CE3259A3A86D966609FC254CBE319DBF40FCB0515567 +A54AFDCA6CB575C49E893A136D1680BA06CD3C427E1D1DD707AEF67C44B89A4CCC1F40BD +64820463144AFF0DB7CF78F08BEC8C7DB7356EBE85A0DFFAD4D3DFA0F7F4AD70E7A5B49D +9E51D73AF08C7B65B9914071A837733C0819ED07223BCEC52D623D29CFC3463233DA8E44 +02C013306E90993BB54CD78043BFCE18E490443AB6D7567FDBB9C5ED761968B39DD21669 +EC5DBB5DC7205B279B3095460CEE2273600AD169C649D846A1DB9E6524A7FD5D9EA9C9F1 +A02CBF4D9874ABDDCCE5F70F7B3F408F6186A0CBF83EC8A342D7CCC022C55BCB472D5896 +069976044EE83A88622CB1C774EA75B34DE55D618E7D22D50ADD05328B59F9AA9B683EBF +4741311B7C07541228ED36A71F9175F4D0EFE9C11B0AAA03403F1BD623F43B4E8C8A9E5D +8D2B43F240C89DECE40B79C64DF6FDA815F08D51BACDD7D6932B73F74A3486993CDA0834 +3812F920486140EE379675C07291435631EEB4E03CB5DAB603EFE0545CF4130F9D7D421D +5114A4FEE9E4B2897BC6D232ADB685C55EDF8C2A8C47814A38B8C7BF34FB777360449448 +90946A15CDE17EF60BA40E77DAF5BECFDCA9A09FFCB93D0010A161BFDD40EBF7605EBA0A +50C3BFC9B8A48CFB895FA52EDDD86221D6EBEB0E9A3D8D0F80B88DA1B8099DCDD7703C53 +0C90F979DA5A2CF528B610B5645087D2CCF5D8F639E420AACF09F97231C3250DEFF28978 +43F44E473AEE74810B77D8449877E45AB5A30E29A4E98CD78F57A47A195C3CE22A5BDED9 +1B3C576D10D7467B3940542E70A7DFC92F4876E384131982D7680FE05A5812C80621EFC0 +A2F0BEA16B3D4D9C07B8AC4A540C803246CE437DA13FE610EF3211F81CB7801C642279E4 +9CF563ADD932DE6ECA45918DDBE97DA17B443C7BA15FCF39D91F9C4501B03E56B9F6DD75 +F3A47EFA6B7D9702EDF6C79C9183F37DFC805E5689F27B53D5487767B276AA037A210C02 +AE23A2C4C89E6CCDD49FF5FC857B2E8B8A9976C238456D000DBD35B00A9401657DF88913 +BE616D0800945CE1404968E78028B727B6DB6547F5155F4C5E0C97C3FEC8882EDFEF555E +98E76A3BEEBE09DBCDA40C2C35BC1A8C7A6B7812AFCB1468D527F723C947F56B9B1B4A45 +BC11CE5C3CA9D950E4729A242866E226A66E3D8F71D9AE73F0F8740E2974CAD28FE613C6 +B67BDFAEC416CF799EABCA17EC183A0FC013A16EA73B5156AD203C2D07898D20AC23D03E +C5E4534F153440C72D3DB5DAB3EF1AF626472D039892379A39E894B10BE22EB8296E209A +8C823E4999F6BF0A1D3CD90825C752A98AA190A2E19266329A49014C772510AFB6B85D23 +FC3811B1BE5CACAB09B5D46E3813DDFF41B8ABBF8E8ECC2CB14D48632DA2E5F5F748E14A +8877B8E5F2E2621014B93A7AF3113E3A8B3BCDDB1CAB7E7FEDEB79E1825E27151E7C74B4 +CBCB8B40A82F1F333AD206F18835FA8EE49BAF6E22E851DF09857DD303CA2CCDABE607FA +78740F70DD481DBD1EE04F730B5A3762082B1B47E69F39201D42A8E21F0F48CB5EF716F2 +4E3B4B20E53CAC08BF494E71495B4E95E46B6AC1802F01DBCFA8DBD1A3ED82894A5DC263 +700908A3AB700075586F3F3406496A1DBF40121744A9A1C51D3E135CBDBB5BA68D3BABA6 +21AAAB308EF3B0287A32AB2E584FECA9A3E00E0A3A7C038C225C51788C3D13232240EADD +63C8FB02A0471517FFC82E8E2AF6AC526F0A3DEE7726821ED3627638AD691FD4B240B9FF +613B72C089D11C22C610F9B9E244EDC11BFEBEB5B1C5E4B4A4362683363B14FCFFD748AD +339C432D31744B43591ED1DAC1721A9FAB9DA2B016070D89914C0EDDA9EFC894440C8B4F +3CE96EC4DEFCC4C57AF0DF67C40575095323A5D73D671D2A716A787DDC6837A6AF455F6E +B524888B98EE8E8F48FC9443899D3CC6FCF6EA214CF462BE414302FA0B39C1DB687B5186 +EC46781405BED3DD98FA23D796D197E9CA2287D4494E876F8AE61898792E3794AF5B3901 +815FBC50E7876043D1F14E61A6F998617EB751C113739F035F4E9DA35DD53DBAAA91056D +1EEC865258540B185DF50A01862EED02EE626051FBAE63DF6D94666EFAF4ECE522CC8066 +EBEC91734715C3919932E28169F49981D7316E982C287F716FFA8D61B939F8A47899D57A +C3D845FFDB0F21BBF2AFB9980EB0D4E180B4A22A902299FCA5B157AF5DDACDF2C9DD3E58 +2AEC6BBC869919860893B9FCFA4881FF8AD0D10066CCA51A0B63D478D1DD7BFDED04DF2F +58186AF02494A6EEE99FB66AF9F3B7C6A9E1BBA52AF2FA10596044F7A9D4B0CB337AD6AC +5BF8CDBB69390F7536B977311C6C9127F26DEE4378A17CC931587F77F14DDEAD5DDEE1E8 +B57FCBE1382D9529880BEE3DF9FDDC6A3F9C6056988E5FDD101A54459F6932133871851C +4871EF219571A1FC43A42BF14E8B029D8AD6EF458B59057FD6BA634ABA8D6C11EEF4BCD9 +402F47D4739BDDF22948A9D5E7754F621D27565CFC92BEBD62555B12BEE04955923A9E8D +6B0C3D336E8345FBDD40B8E7C9A43DB83A895EEDDE6211EB1360FB016A9DC23F5055839A +9A71775D8A45056735F14F87600916F187A53C323C86CDE455356176FB014584B4A04126 +3FA11150B2DEA71B44BB130243973600B3A9204C13304853D33A15CCC111C0F08360DA8A +A2C615A72FC79C1B128D04ABA0E92A138CBFB37253EE80A18BC9D92B5845E895A7DC4060 +41AB37F3D4827254BAC860D6EDE8C5912D8DAE2F943A4430269FC9F9894024C73C90D77F +0FC81E16F618BF7DFC1AF1CB2EC0972F62B30F5B37747A8AE2C7A2C7C34595B8F1DF513B +973BE2F1ED822FD4BD7D5B07BDDA6006019700257B103BA495F9148012C4CDB2C3180DE0 +B395BCACDE2FFFBC1C64DA5D7ED1738B68AE483E5007EF90C9A770D73988849F2D2D6EC7 +734422A7D0BD41042988E4F215A81B4D2545A2C84A1CB218825221D3E33D5D5A2DA7E91F +90B275B9F73571286905C58ACE35E0FCAEA9A9BAC32784C8CFF609B09114D6836AE6315E +4943E9AFAE0905E0516603C5CC2C54C364CDF9282DB7BA8DFE921D7B4833C48A8045A60E +ADFE47F9E1818BC4F97657007DEEAB9DCA84280E3014EEBF7D4D0D1DBFEDB072B20CC4C2 +BDC4414DA5070757F4EB8F65B1DC1D8C934F9BC20F516A9C6295724DCAB93A9CFB0D75CE +A6237E7F225DB1CBAA18C679E2C6F0121FC59D090E5DED3306F50DD0F92D5D9FA2003095 +CE6C5157C569F3E5FC02D4F3FA115B9B294C74CF95DDED62CF1E5490A6FBC97065247D4E +23D1E39B0EFEC6663C27674AFCEFBEA9E482909EF6B6B8E3AAB9FC169B0DCC8449B50A08 +221406F001A4D140579FA9338C675DAD54E854CF359452C07D07EC05F28301D94FCB46DA +0D0F5502DB24BBA0364EFF694A7F4E86FEB6845CD59493BCDE8BBC61A30FA209B890F097 +5600D91FD896E6E0DD0626B4BCA3487AE1C577320E0C251AEDCB44910510CE89CCFAAFAA +CB88770FA29636576011B67C6FBEA6A310AD45A006100C4473E844ED4DDF69341BDB9FC8 +3D37F678B9F7A2BEF245F823186C56AB3667795C79EC85D68B9A34E9779E29889E67DF20 +26B22D42C423C1425A678D8868543E96DFF0EA75C3666B0EC85A015B7048F5ADD08EFB1D +B674AF6D008808168A8EF8EAA7D43F942043F3508D6AAE60CAC9C9950B81C5ED863B6653 +0C98AEBE1942E63CBA37FA6E02DA11AB27F8579BBA5220635D424AE097A88C830B3D42BD +6B7D89F6F40F63B362E5215373F943ECEF08666D86D2D3AF045EDA7F9F796A5522608F6E +3FAD8953F166C11FD0688B127AC306770C934311A4890C48ED4EA8D12D04C5E2FF9B6DE1 +5253DFA7627F3600C89884B2B3861B364FEB31805A1D91B95D2DAAE9D16538DDCB94EBC1 +23F63ADE7C1B9D48E526EAEC0FFD822160DE068723170F5B753B5C10A0A79CD09ABF1E96 +A8811EB377BA65F37ECBC966A054A65FBE686C3BE9FA4573BF86865A5D997FFB690841A1 +F273016436C3D76351BAE06BA745BF00F27428B1113B5351567C9B254948D8A91F6927DA +381F993B0F941458CE5F5189091A65B5D90FEF01051919863C47FB4EB11D18CCF8E5C8AB +3E518A0923BF4AA13F83BB3FE88A4C3D680B7FD65D649E0159C6C9151FE7959E77699105 +B8E4E1B10C0C5B56C400325D32EB5716BD0FB13AFC7A424222B970A894C7D33BABF63B59 +EF13538F526CEA62F5856F1BB23A00D7E65220E5241D7EBCD0F84C44ED3EB468DA011023 +4358E69CB5AD8C0B53F2AC1D014358CA2C2A3C901AC5B2850DF73455D690D3944BB641E6 +995053A40D4A513425BE0A17D619DF7ED39076E9FF9163282CBABEB14BF7E4A49A5D93C8 +69B9F57C9D86AAD074633AA533F5734F2B98B0CFF7ACD4726BB1CB239032FBA59B3D0FEB +3F3C169C667807380CAF379766B5984B4CD3D71975B62EBEFF09056E62917083E35CAFD5 +6FEB1C7A89658F46733CDA47E99797EFB6E48332D24C1B9766F92D4D4AC4EF17CF6418BB +CD0694C26CD6B5421AFFDC33764719826667B6F88E604F982049D286A35B5EC47E07605C +A8D53448C6A436B183BAD32E8138CF289C5D0ECAE1A2818BC3CAFA0B02C9097BDF043F15 +8625F6B756D85C81A4B42865A4AF790BE63EB95C72BE08598898E801FABABC845EBBA1B4 +4D4ED41CFF1CD460612F8C2B249B1A206656B2CFC3910C57465343DCA6DF0DCDA3F6DE56 +8D6AD6F83DDFEE9DE523EC0BC45138BB80B7315D894B27D73C4C1DC582BBA0A8917E2E10 +F94369E0A956F61EE11CBB2B45ED6027D448538B36C471D2D3BB6BAF447B60F6023F55A3 +24A5C71573438FBF1A7B40A746A73F5E1B51FA3F38DC9A2806BCA0B8B6817B1A265826B3 +27D425929BDEAC8136A91329B43EAB1AF325960D105915D185E0522CAEF00A15A2014F6D +E29C3093AFF98028F5061818F8783B37FD1881ED44D6516EFBADD5D6B500D5502BFE6A5D +908A07BABD50514A1484901A51AF83C338624298070D04C1DC09D03E565C7D25726E37AC +1D1A9F5DB891126F9944BFA1080C7906A263BA892363087DFCBF6B92D9AF9CA1D7781A99 +9DD794B3385C18AD819D9558CEEBC46F9097E9B6CE6A00F1BD43C98730CB80D48937D0D7 +36862809C16C794C4435B41DFC392291E699EBE1AA54537375B6FBB27F1230B77A0A05F9 +2BFA166CDB8B180036DB3F48E4851A538C628C8D5D9CD556317A0CF0E6C28183E07249E6 +D6D47F35F1C3220596EF0CC1F0580ACB2B029B5A5B0C10DAEAD5D3F698CFEC641F16D80C +0225611726C1D8C4482A00038BEC8E0B9EF7263C32DF0F80E01473C41307FD9C10742079 +9F2E0486F5C937EBFA48B7B61DBA9094AFF525790B61C3858F76685675BC6ABD1B9E9A8C +A17C98CF85E49D6CB5A6B7CEE52D67EC249CC2681F802C06FFC639BF3A0EEF23AE39AF5D +C3E77F63D07EC30E4B3E06F74E707DBDE5B6DC0DC1A9DB02ECA2FBA6C87CDF278EA55812 +40495E2C138BE9CD3AE2A1A427151A5EE3CDCE28421B137B1427CC48EEE8EC1355B48FB2 +86F40371EB9DCAA5E163C65967FFD4FBDF7B358463D00AB081ECE83596C2EA2F3CBBD847 +6D6EEFF31FD8A0E3CF4B6362BE42331CC2737891CFA525B1CE62F2FA4B1F2FCBA54D0452 +B77579DD1C56DDDD6DFB2DCB816B47FEFE0E84D3A19FEAD6290FBF751BAA095C068334BD +77F0F04DEB6443DA99E84D250849045DBE0ED267F2789B475127E6C57059359EB08AA04D +3FCEE5B1E61EAFD90B19668647CC52FE842FB9D5A58E3E50E4CD7A2EBF1FC9DDF4CA4B0D +29AAAFC8344627C9BC74C49BD24774EB0CC6DA70B3F3BEE134F298528373CA8B96121B31 +2C5D02525A1166E8A644D04194DF8E1D9323FE92DAC4833CF0E08C716716069AAC65A421 +142B305E97E668A32B397244555BB14653C18384550BB417C05EC9343BE28E62845ECB49 +AE6AFD50A5619CD1F5779FE6AE1C2A2C10420F0E9426AF4614FE2E6E925214E0ED5C6133 +E9E44ABC962770A4E598E8D4300F9C93CC152C5067FFAE77FE9A171A5E463D1E9E5A332A +564281F49055D0A99F49A20368EA7C75285EF8215FC37FA69A66101EE4E2E32A1A2AA753 +8EE3FAE3D4C31F96C34A74677BC9221FB904F777F69D2B85825E09C8BEBC973E4AE85EFD +123507D5D428372188270978D9C7ACEE75DB5D1F1E2988832870B7EE4F5366DE20237EF3 +E526DC33E2A4FA186A43325779EE8253D76DD1C4FB007F1A2B8E0272334A5956C488ACB1 +1D09C8399B4181B626636F6EFED9A5086BDA64AFA3677A48D13464C2E0813421D96B08F5 +F3B7D2CBF5B2875A1C217F4677B026B21A07A8C61140B1A91D552A1947952448D7492460 +FCFAB5A22A7E9BFC577ADAFEE42FB8C0EAD717071E54493AA7BFAE960641332AFF9AD94F +9FA05A94FD5CB6014FBC8D274ABD58DE566F621672550D2453ED92AC8E317D6D28F5A443 +D211A3A65005F8A18006D2EC7749AC8F57FA4142BDD1D62EB99A2C4A2EA448AD5DECCAD8 +7B54EE483B40CE76CE2CC0239B0B50C8AF29E007A10FADC1863D9844B2380052383F333A +29A7168871919497C878D7DDFE5D22667C51FFF6C2926B3D219D3A3C02EDF6A9FAD14E90 +90D293156E00F6292F11808EF0E73CA26147998707EA4ABFF7B77A5E29ABACC005EF74DA +D402BB1AACE7CDFA12F93421506980C275BACC61B292DD800E07E1D640A187E73A0B682F +0005D5BD5F6E53171C376B1573B9F1FEF247AC3494D828991A9050C2B85870A9C2E08C14 +A92632C3553AFE16C771A3FF2DE42949E1AD0665A0BAC07C8B1C9622873C54DCAC6D642C +1F050F2CF566713BC4C09E28AD0E7CC6986CDCF68D5D8DAA0B20B6310E4198A1B95BB262 +7B1816093B84234255C361928DB4BC5AC3A67A487C540394E833E3D879B3C96ABD4ECC4C +95FE7718D1D6443C84458B694AD25EF8824F947569C001931C133D999D6DB574698BB17C +B86246A3559E4E4EFC079D0BC9FBE3A8668DF9311E7EFFE4316B47C4982168D69331CEFB +AB51A1BE03A6C2CCCCAFE7BFA2A836AB5819FC8E18E33C4CA59955247D0EF9AF810141E7 +B60D58D38A2A5F4686C1FBCC929A2601EEED2A4A4DE9AC90F726F1D1A16BDCCFF5280A6D +52B626B3D927E606189991FF548FAC99C1DAC6B894B4BAA370678060B1D6CE7D1F74E251 +920D7279E493017DFB862ACA5BA417A9A975E4D6736C2DEA7418CC1A07DD3812BBBE56C6 +F3CE5DBC16353009E547376D99F03FE9A087C29A1161F2629D00206C219300B1D09F4BF2 +AD8475A269466201C57EDB25D8A458E4FF1424FDF09B1879F5AC6512952D56EA719263D6 +F8BD77D3B5C04A2D9E27EEF0FF3F42484F667DD1B3E483C45DA8057AF1C3746820D7C663 +5C363BCBF2106DC618AA1F46C34E9562F33EE3D392A6072FA236BDFED8D8FFE526694AAD +A68AF0ED535F0E1E2CE19ECABC2FC66ACB07E44FDFF7111639117086B1876725BEA99E8B +D0CD8055DB154A8A7BE4165118C104A5C1B2629B4C948EF51A68C7A3B5ED70C2AB40F0A7 +53B75AF07F4248699B03A7654C366AA3A25121D8590E787FA902D5E29516BAD7C842C649 +41EB1350B2BAC0E28946943E0D5C227326D7B1C3939FA481245B19E7959B770DB9355DE2 +E5B6FB5F66E273BB9CC91527F87F35E95AAD29D867A0D35E9E6B1BE8F1EAA06FDEF2BF33 +E694D4747D525AFFF997EC367C1E1D0B55C2146BBE47581FF99824269E43B795FB02F80F +83B1BB3222C6A48B9651325E4A6274BE9047DABB7FC9F85751DC9239E82CBC5ECA22358C +8EB9DA76B9CBF92894268C49CDE4F67B6299CB46FAF1A8E42FD584BA74C47767613325EC +95CBE6A43BEA5FF97C7C2195E970504893EAC878AAEC0CC2E86CCEC442DB62FA15C4BEBF +35D8AD91711A689415A84DA6AD6D1E2646E363D143FFCE360B3E9D282A84559B1202AFC8 +41A603E80631FA5F1914411B13811ECAB8CEF64906B0361F5F558A22026F46FC88A389CD +E0B23523E884686C7D4D9FEB4C3D66BC410E2111A73988E73CE96CC26A9ABAF3C860D8F2 +658FD13A44F3DA9B5E53E348FA51B64299FCBF16D16E07CFD4C5446614FFAED07FFE9E25 +A10696029806CE3E23582A1FFC5B83185A0411E8353BE08D7AC131E2BC7B7A8EA6B36653 +82B2C4C217CA8A09ABADE43A7A5249643758B7FD0CEAB8A9AD8E8ADF1A9D13C2E5EAEBE6 +D29ED3734EDF200A92E19490CF4E42DFEA28AFEEA7FEBCBEC1645C6A101B51303BAFB113 +8D90761074D935F9F553787C1F653FFA3DE1A8808D185F38D57DB5E1B16C1EE5B1385C4F +3C9FAD7CB2460DEAD9DEB549303502AFF17660B9330D162C891F1039B68ED4682BE6BC89 +7800F158A24B07539CA9CFC6324D52054527406D915BC0932F1D7A86E2FD1F649386CA6C +6E27C50CB7A63862D606CDFC3ED8C6328A756AFB01865C264FA74B586E5A6D34CA48CC74 +24B5EE73BEACE92A3A4D97BFBAE51EDC60643B8FCF024EF05E263C0BF15AC37665BE3428 +86F6B507B63463EB2DBBB5B2EC5CA4F227F9D5CB0124BDCE2C0AB3D4358273910E916D43 +6FF95985D564BB420489DD1A0919C8100EA03EC5702A9925C68C86B4972C118B04016533 +BD9726054B7B563BEBBCD62CCC5A08F133ED0554872DE4188F1F15D52CB5592B1E35A319 +C6E5EFBC10CEC89E9DD78884E18FBCC408378351B276FB389136ABAC62515C1F5C3D3755 +3E0FF12DC19621DC4E6C148FC4F56F8FE32CDF567DA11F80ABB91D224D4AA7ECDA2A5035 +9825F25B2150EE449C101935B44549EB3E6830D551C551E1501D7CE5B3968B770016F605 +8F0CD392393DE4576167DF1061732E9F7A42464610BF841387941487AB1BDF04AD40EA13 +90A50F076215B6DBA43231647418BDBFD39FB143D43E0B8912F36348FC7A1CA96DEA49AF +416D8A6CE75EA49395667E19CABC2B8D43543A488B130A2D85386518D86987BDF99A26D8 +B4EE1E29A4BBB8AD0AD4A27B346FB5F9E8E5F180F0D5748FD98A64715954A3125A749A43 +EA2B18CD4DAD93656B8FD9CE27E5EED5BBC369C060BBB43B4038ACFEAE8D437A354CC373 +66B2715885DDE1BE0F5DCF688E5AFE08E163264DAC1BCCFE9666B01970F2F16B47772ECF +751055380EF0002FC3877CD3F89FB0D9E018A6541FB71AA3F6CE602C4DE2920386F01185 +E2CF256CD8F8EB24F460270B6CB8982C46CA5E58566ACF504EED68FEB0255B6D58B33687 +551FACECF40487D58D4DB520A1BF372DD3B66710DF6224E9B6D2EC15B31EB4E41A6CFD53 +42E3FF218807059B0EC60B96CA5F9F4CEBDB3ADA79C16624824F479F5FFF981B0E109BCF +8C15D2254FF75BCDBDD4AFFB96CEA4968C38611FC2204054673FA7AF01DADAF779AE58E6 +8600044320439E79D45D56352B704E5F12E56ED1788E0817DB76B80F134C9752F0082CC1 +D4205003C0B2E73BD54138B10E0A16CB57A0ECBD17DED50FCDF7BDD848576E87868A911C +C5F0B1C36BFDDCE813366DED05732C46C9DADA44D71E94C3C4A5030EF7061684CA509C70 +8A242B8A39D649530F379E81A1F5B4456A452038BE180E35889AB052D14823392AEE2379 +FF3564A86A2F50AFF40962F665F3C005CFF6992FB85040E6601D20135D7227F05892F344 +2578C821EE1F00E68E0475C0266FE10458A18634B226AF224A80FA07A1E3A29FF6AD2838 +CCCCEE4E5E9035220AE9F53C02DCA89F00418FDF632653C5C64BEED2209ED102489720BB +D735B06159B60BB162997140BB6AA99CD063B94A7DE5098A8CEE9A1AC5ECCB0E0D12D399 +27FF2FF621919638D4205E39DEED766108D63938FAB0DB2B2C9D1BDFCB14517C7E98369A +7BD3E31ACCCCEAFB954D92A22209C9E825CB38C9B5A529823B0A85BAC2605864B022BE5B +B8DAA6312E8DEFE04593F4E8D0284DBBA42CDFB7C189F280FF48B79891EEF4FCF59A413B +7CFAA37EF7A154DF78808E4AB8CDA33FC51F6E389227BA952469AD2D7BAC328342467482 +FE311D122B9AFE8A16E9B6F5551CBEE36A3EADD5FE7A524A556F3D7AB3217FD8C574DF32 +083E0D1EA61A8E01E3BE1392BD2955486E289C3E1727FE71C50D1B50E4B7D945C5555851 +AFE225EAC181B0EA541AF40AE45309B4BE2DE1BC9B36E0B7849D0844330F3850572B3869 +FCA1BFDA818FFE1CB7095423D611D85890BDAC15318028FE9F3033D1DCAD9381B9237247 +D65829AB81AFB878C7EF54CBB6CA38526AFFF404662434D7714FD8A5D0800C8FCDF69A5B +A6938079F41D08E80746259C7D7D24E149E2C55424223CCC1AB2008545CB8C5B51CEB8FE +DAC374E94A7836030F536F34A55352ED405D9C31AC2F82FF072B9B885968D534C9792F45 +1BC48E942D28CFF06246597246776530F72392C98D29CCDDBD9063EC24D559437B844430 +0D2D742E08C0126F4116198C72AD9D95E83A534A6D353FE873038825687C3AB0281600CD +FB2558D70450E14684F610E144A7568C471334FBEDE0CBFE913297A657321182AFD4045B +D5D205551C6F9B904781B32529C2AB0FE1DEE6269CF6009203027C9425262CA5AF2EB250 +493B9C1018F2907DCC656816D57FE4C987CBE7F7F1BF0EAF8AA40E23B456093B3DA29C21 +5CC7F911ABD9ED34866EAEA9E1E7998C4126CB3B44F7A8075C37640E0AABFF1B9B0EF003 +96A9CA8999EFEC2FDE533584B5F49BB4DB1E121B581E12F2392E7ABBCEB56B35E8D0E507 +980457C24100377B95668B167C6E5388760883BB173A6993A88104A3E08747F1B75F553E +65E448C8188A3942182FEF0593BDFDAD67691E125012714A0B4A61F5E918980E1A167A32 +D7CC3D46435CF3F2A84458F309661A2095792F79D1CA6378DF864A308E162F1D8B35CA85 +98045B55B19BFB7D18C05B0216F5A7B75167E7866537F3F8F6BFCEC95B946B4AB1B0B015 +E45ACFBA6F4E24FFBD0FC639591A95337ACD84FCA6A164857EAFFF41D00138A582E321A1 +D6205B3E73E2A55882FD873FDAD0F9D205D47F75055FA3863E5210EF6A56F8D12397E3BD +EDBBF54C8A328E62E03BE58D301B285E398A7AC55F6E08493099CCF7A70E79CA81E275BC +86805E22DC3126C98916CC09B06CCCEEC5B66469CCB92AA21B71A49A2596076818B17ADB +301590C5CA8635CFB881832F8621E6C15EF5D59F20F75098FBC0A7E79690CB5CB3F746FD +D8B0A8B92AC145E9303ACF6FC91820119325FF5D8BEDA62446311A73D89739E628B907DD +AD9B8CB60E076AC1092DE241A56495D0C1A5EBC43888BB8DD087BD6CDF38E1DE93630923 +CD7F57AF1604A42B70D2E073935E66025F44ABB3E8B620E065810AE1D2415D7A58175D06 +B7CB4C211499F9F9EC43B92C3E93DCDF03699D731DD288C1651A62A25AA9BAEB1B79AC89 +974C233D6ABEE67B4729A746A700348845A42953CD858ED53F385288ED83EC2B54C2F416 +3D4E2E5011485D9293567429D4BA52F1F4CCCD80BA8B59B501C629AE567F24C3AAFEAA0B +4612ECA7694CBDFF876C3B9B5391D6EC38DD10166C3CF3CFEB02DAF1EDFB661899D3EBC2 +556EAD791F18381618D14F7B7B115A35DC0E8E282B8D1B4C9E68B09E9C8589837660444C +89E477BA7BD0CDB39EA9FADEA33A9990458A06660A30EDB737BD11627B68DF9445A34D4E +4993BA9E24CEDF0FD6955CECA5C9C79A340AB31096FCE9FFD84B2F49C8D504F55F413860 +7BC83217782E1A269E662DE79C67506F14AF71EF7302282256C1894AFA5DEADE51BF4222 +F2D0F1F4FC1EA7E128D7645E07941187D5CF65EC19667F2D204222C6958BF58525124ECC +17C02EFB44881DBFC89A8D5D73A05295B71AD83BD9C54ACF1FF0C542D13DD9CD6957078B +FC5F8A0BA938AB3466F44919BD38C5A0B14E899208598792AC43F532D41C6B8C4393DBE4 +472B5339C02B620F6D49C0B0BA93BEAC6373539881206C1F8E5A0F4241D0116737C4EE62 +575A47D79F1DE2569516D24FCEE9B7829CD545FE71D3DAE6FCE4BD780437E597F5849135 +D69B7E51E2D6A83FD3A8E67FDB1825D2A56E4BD7D6ABC291D052997EEDFF0DD618211607 +1D1CE4B60708315358C989BDE51C97FF5F2B2141893287F822D6AE440A811FEB93E0E600 +AF51552FE111FA4AB014A89EF562FA552A8CFA6E5CFBE95D81B7E50C04BE883DA4E460E0 +83438DF33E15F8D759FCB651B18357B40094736416124FF1D59B4B7BE4940CC5875676CA +EE4A30F059BC59596E693595CC889B2627B3392C5EB267863CB753908FEF7712BA9ADC4B +E47B18FE8807AFF106669E8EED7E0DC5AEB3DA3FFD8AD8D8B841626B800B5B82292D8A56 +D5E9FA394EB1686C441CE523407401BB4044C4C5BC448888BF122AC6D703AD6333EABC52 +C999312CB3E16FE4FF2FC8859D8662CCD6E35DA8B02BD22E776020C3BDD774E9A24EB72F +7231F1B9B3A096E4A47AF15B4AAE20946F8358BCAB1D5E3FF566D361508DE82D46038A28 +BC879A9E75016FE30A8AFBCB1F2ABDECB4ABA14CAA2323A5DA6C57A712EC6CAFB1FEDF0C +235E50B30127F62CF88E77362F6CCA0810E29B35EE5B7BB29920BAF6FFAB5EB3FF5377CD +A310FBD9AF79001E8583748164CD7C4138DCBA043B67CA3993C385B9F054585517E4F73C +C5F63F46F78235501F636BA4BB41BD0CA9BCEF79F0CFBFA446E09EF8C6B915AD718CA59D +B97A78CEA2195C968842C94B36EBA1F3DADE4872E3FD7542D6E477EE9343CE5F801BAE59 +CBE5A2F66DA2177389308B526493A523A9496C7C928F021542A1D6676CB3207979AFD6CE +2E4B37B3E3621312782607BE9F9598D470564F6C3E502FA2067C1DB36C0928D7491F5119 +72EA2A488D3A4A0BAAAFC021FC89DEBE05D7E992122A5887ABD7C88AAF0B12E3A0E6457D +E7BDDDAE5C4449AD3D0EBC9B0BA6C5A72C2EF5048238A8595B33F570FE36F1C9A3ADC38A +1EC604428BECD165520FE81172BBD2DC01EE2A923F88DF8A6CD992DE1875FE3C122B42A8 +2F4CD38D5336DE782586385878CEF7124AF8454C75E92B4AA8786F40B0414497A099F755 +F1BA0AB892066BBE83E472880AD336EA7012100B03D06E9BC9904651AA7F93B107EFF61F +6A2F7CA20240BF1D3E83B3256398CBECC74F8882E40B3E10C0535ED23A8214E19464082A +DDF3F590F9CBB75F06820A1DAF1DBBA19CA4D57B7CDB841980BE2E879E8D83E74FBB3EF9 +7D644DFCA51DAD4F342534160CF07F8822082DF31D8A6282711D849DA3F583B32ACB48E3 +0C130028571B9565E61BBF8253E97435F60AC0C91934C5A3FFECA5155B25455D59C18CF4 +66AE7A467EB5799BF2488B1568340F368267625F1ACB7FA34A8E582B0528FDFF256154C2 +F4F2D0F61A03D13A58E01548646D6B4659B4613E83476159E8E597546BD1F7902FD0DFB1 +71390A36A8389E25388391BAE75567201CD1A6225F774AF5E3132222EB969BCE588E1E18 +15BC60934C8E132627D342B1F7D780F9B5DC657A975387202EE08E957F3D123B4C115F71 +CA9CD0A5ED37C7626C8596E9A4DA7FF5A114A85E545F89C3694F3FB28A5224CA6F930538 +9B76D686F13C370887F75F88F50C98974857520DD8806736D034C188403234F1CEC012A1 +17F9DC0B03346D88401DFEA09A28944CBDF75E79EC6B26F204CD6D4F7CF02FB3066E7085 +BC35AD0CF7CF47AF38524C05B13E51A8BECD2B4EB4E9AA3A7FBF08A1E71A61B2ABBBB10B +714A0E46FFDF3FFEE96BAE962C10B8FD824E700E3ED94FBB1E03AECF77CDF572F623ABF6 +9D1AF511F65408CCCF16BFB2F1A0895D5CF069A78A3ABF523D4053F8A4F6DA0F3C6247A4 +5F2F6F21C964B50EF4615BF41283B6C655E55397A6FBC23249D306151A4E5F57C26AB256 +345B45B3D81AB1AA64C80F09C6000ADE9948C42E03356C0377EE74E17281985B8ACBC958 +EB9289159091E36937DF725063C434D30DADEDC3007066C7302D0B12F8CCCDBAFC57BB30 +261918964E42F08D1345D4018BB1E84E31B0F57210033C0EF479D1ED0AD35CB7178B173C +6AF59A4824FE5FAA88AA847FF999B3152F7C12F7258F7C5DA155B8BC0F166D9B6AD20188 +3154BFCC9E3B9B267FF8831BFB906C6CBA7D05842E95129D60B562678A322B94BC988601 +E8E32A6C507F02005BB1CB8B220A6903B4F621ECA9FA513FA4ABA25D107A39ADD5D32593 +5D8875831F02E4556E6EF278C01E8A7FFFFCD1D5EB4689A2DD86D291F473120B984218F7 +DBCFD434EAB3EF19D1A67F4EE9D239FBC0BAE239D0C634D29950EEB6FC06F0481A10B225 +7B80E1F0395CCE4C4291A54A5154FF1B0896D2E0CAF112D0E534F014FCD73082FE9E8A67 +ED23FDD4F7C37651FDBEDF999D44D9BD7D57EF6038598BCE94ACC2B6C0BCE60433F834E3 +524E3FA6028B6D5DE7631B10A2BB1C77BAEE351FC7373C175D3878502C2DC5D40596ED3D +8940052DCDC8EBE7F1853D85B06AF9114FD739E558F0FCA26F3817A990605F9C9807F900 +A18C71248300BCFD22D7857C390431356FA4BF993357647D9A094763D668B7908CA93E2E +EAB15E34E48B1EAF8082C6FCBA7DA5E9848B33BC59D6B50C9CB5108F3C356A45A854338D +81881FC425875EC59D361ED95CE99FD7A279A807671C8141A000A5419E8B9549F3617114 +6077CAF18A152CD041F94E113DEE2932F1AD09D55359B7B39F4771F15521DE58C311D143 +AFA24A92D36037968DED5FA71402B34442F9820F31D1C608124C2B50EED276FD06CB04B2 +3D0579FAC4ACD7C674EC5E6527AA352E38B35B14FD647E645CBE09C5D3EBC76D35D02820 +C91A1E422057E99A86EFC9845EBD5735B8F61A957B44C33F7CA9502E08F39E24111E73DD +7C5BF59212BE06698913B89C221944A9E539B1E79038B3E2D2FC40DC4D9115256D8BEED0 +343FFE190D6242A3054711C86A20E0C4DFE2C270375DBD1009A6ED640D505F25F475E0A4 +DBC0D9840A68F2E657C1AD8AAD7A260AD74DFBDB32B2C6CCA9A49361755DFBC09935041C +BC531A5924CF763C29DBE8F169BBE77A261B1DFBF1504A04CE7C3EFBC0E36DB1CD256AB7 +F40C272E2C3C217779A2D45E1A33E504A32183552ECB71EB562040C03D276A91590A286D +2A90E7A292B21AC7FC70082F18903E2B3246A66D95C47F7FA0099524F38018566485DDE1 +4FBB810C07BBBC487546F0C2BB295D1BEC35D797B0A6AE0616ED8465BBF239A46FEFE3F2 +E20F85E3E383C16D6F97044B6E4E80DB26953D609F8AE0FDDC92A41FF2A7EA7744585B51 +27F7D1D756487DF4D75289DC3FB822A16E1A8063D5BD6B2D7201DBF78BF4A34FD17D8133 +F8662DD9704ABE347C405D6111474E69C5F22552E4C6EBAB4A6537B46FA2EFADB55485BE +A4359C8BE0B2A696BB946E89A5AB3EC81AB9B584E6EC841BCF4192EF82EFCEA357C90039 +3AD2705B9BEBC894E42369F7CDB749E1A174EE4CB77454CE86BAB1B631899C547321C9EE +0499149D87F3FF59D13335D54177268569DE1AD675BCDB9281C21ADADDF54B32E62B3EA1 +2FC565A670778959ACB4C4A36B6FEB86B174D3FFB0B2617B2A84EA37BA5B4DAE6B7F1DA7 +36C01E446799F135BD5573B086D61B5D902097E93C9460E586BC8C5FB863507F7938B02D +90EE19C51E00DEFF3764A3483F52777644D3F20C0B99A8807F25FD6080373B09C68B45A7 +BEA9F0731DE751BDF4147C690A9E767DB679A8F51849D094DC1E8209EF159084231610F4 +187ED2875D1E93A2C977C3F1C86614B60F81B31CFCF2086E91C3A09456F376DF76F6F4C5 +6F6D96CA852C7B749255150C5C16453A84B9FADBBF40273B18FF8E61F309B649BE8C8BE3 +75F739C6CABCC9FF39CFAB9997E77507A7EE5D521C769F6A9A03472C51AF83D6682700F3 +9D1114A04992A23768D8547D668A9C1302DFE2A2011E3B0A101ECA1A41A79C2AD80DA863 +CBC5D77DB3FDA136ABFA30603EFB15F99F848F18B2B55D3038E7E7F6B691350D3C0D6766 +4D0849BFE0CE481B1B732326AB02CE44BB2C15122A57D42264349E72BD47BE006DACE8F2 +A0ADAC696138227F9ECFFABC0466C2EB581211CC0A24061CDB43FBF37A4E8BA1434A35E0 +2AF6B5914D493F64328F8590CDCD38169368F805D5B64AC0F4B996ADA8879157AA0EE3EA +605553CAEFB6D31B01F66016C64F7188556D66F185A29164AAB1ADFC1FFE71934CEC127B +147F36AF98AA9A7877A7188EE0160EE26705D1AD9B5F86D8B6BEE71C1BA240FC2A903D65 +0C3C69CCCDDF00222CB01141C0F03958D9BD5524D8C31D4554073E2DB0169849487244D2 +2A28987A82DDAA0CD060C8A8740F1A11509152B4602A6D0DDC4456849FE5E402F9ED88E1 +DDF8E5AD854B5FC77575AD955C95BD033D69F4A2D2EA6B6EF587EB16ED3E0F52E7578FC7 +F22324AFB86353B1EA4C51179440F2CC64A37A92BDE6A88B24104CB8EC78C660A40E43E0 +27E0EB69D813A3C29C9C3614E6408532FA474CF9FC5AD498F8335DF4A04BAD633110405E +EE6A5E40D6BD7E23337B1B623735BC3130720DFD1FD1A86C4A90145EE483728278C48E5A +CCC333FBE140DDBE0A28168D6B2BDB902491E0340DC052C28FEBB140B85BF1FC4DC35582 +1752E935381556DFE0A1439A0BC810F9527331CA35508E3D0A451B3D285D37A25F1F949B +9C9ED1BEF8289E5AA1A3BA045CA7CB647F1C1A528D85938E04ACB1E7F08F5ED3D18C9E86 +7AB607E8BACF757C98BB71878979DE3862927977A0CE431174DF24872B21988D6AD35B07 +42C01ECC82FD805CBF22BA02CF596876EE1E135254A8BB6DAEEBB2BFF9911EFD7C3A25B8 +55B95EDAAB6F25A31BB29BDF2B0FC3E0F4479DD96BEF601E4DF77A459B73B69A9C55A87C +D63851038A7ABCC475BBA0365C4CEF17A742D1371131397AA139032620E16D89B3BB7A1F +7B018BDC6EC29A8FC02D6C6E943EC1B1A718DB6AC51BD7C5FDCBF2BF792CF9ADCE89D130 +DC5C200FE8625BB13A02F45E06A53B7D186838EEC83906E8298CF83CF5A28EBA36D67F56 +64EC006E350266F7D2C81ED295F572CAA52FCBCA9B605E421DF4E9393D1E775838992B7F +63BA394188312C75E64F9BF0217E6E31905945D27BACA0693E0660563A0BE2868E22A604 +C901BD00FD8E9088C4255B2583EEC2417AF39CBDB672845EF9BE24901D270059E7EF3C99 +0BDCED89538A8CCFA5A0BEBBEB671720576DD349566E591ED760FBFFEAD66148F05D37E2 +0833FDE02A4E85F2CE08B0E03DCEF68D454E135F8F07BF93724E0B7E0FE769A0AAC5B513 +F4A763347B10B50B88792E1CB3E6E948B75A8835DBCF188436153A2C2B44CB18D8996FEA +75324C8973D1F0E4A3942E2A05E43B3C4AA46EF7B54039542193CF76CAF775DFB15B31F0 +41AD173F8821FDDBD7275618B37F2693A29C9A990B7BDE96FC532242929F81B1B61025CA +717236C5D41ABD690EC853317D21B20C2CD6E9701202305CC34F5855934E03F1F58A0D32 +D73602B07ABB1904173E09D799769D7127B665537FD6FCBE10E725CF814B83475FB8E443 +027F490BB8488157A4208D031ED3992E2E0EE89C5E19AE11B16E95452F86B04C3E233A13 +02B300C9A21E2D920B49DB479AD034860B77C8C1279EF314FB4073B6077625270113848F +BFA4C6D1CC72D3DD8DAB5298D5A5BAF7E832FB36B13875D241286EB56495FA62909539F8 +9D043095F5B32E10F59B8204F0C598FCD78FBAE872D833662FE913E595E3A2073A41CB74 +5AF21AF5790DFC9D3CB011FEEC385B5DCED039630C8BEDF0790C235CF0174F3DF205DFC9 +A621B1A32351499845F888DCA445879AF5871EDD1572FB6B07B52A583A288434502D0333 +FF418B95580F4DE9B2F5BA2906F074AC91F566E5E394AA7695A161D01DEC146BFDE0448D +E6DD22D7A3C0BE7D02A29EBE15AD1F302299D673379CA3C2E500C573B8F81E0ADE5F59CB +BB8E0B5EDFFE4797C763D4FF7CE0117EE17E80CAC2A3EE7840C03867DC19B51885FC6ACB +FC0EC204489CD1A6ECACA8112FC1603C254E40049812D1BA5C561C1224BA56B97FD66DFF +C43D96FDD510AC6DF46A9C7AB22FDD5E9318C4A5F598E34A3E60989577333E2CF7AF6129 +FAEF2704C1C3B997691E484675D62AFCD81F86A6EF5FA4DAE7D4F690BDA5E35D0C3EAB49 +A377A2A0B6019DDDD8E293738FA7503120A91AE095F613B3F925BB4D433A67090AD6AA88 +37979DC1DBE9FD46CAB54F1D9AB5B9E20CEB07AA93346801BF8EE52977FE36EB1CC51587 +FE57ADAB168CF8A7B95665F65FEC3F3EA5920401402D8D22A3D4000DDCB5D06C5A901430 +865872360B37C1277EA4C31B32C16C9EDCC6162049204A9A028943915A7753F72452ABB9 +901712C494B0E175E27B99F6F34A232A826ABDA15D82D4FD0AD88BA50545A5D9A4E3A90F +51987EBFFF48CC52D8E7FBF1121DEDE46BCC71F7F3941EE02897013189FD60D9F41C2F3D +86A0C693DACAA72D68404118DBE5524D07B1D2EFFA1F54EF0D0205FDECE28BB1080F2112 +AD17E04A000C581BDBA02571C412DBC9BDF10FBFDE1CB328239362BB008ED70FE062B84C +E93030327374F47D62D4740DFD23B3F1FBAEEC619ED18446690E0339D2BCCDCFE3DA5D5A +215224657F8CB4587553B7344A4CCA78DF1D955679F3C308317D8EC48269D5E1A9917E0C +46BD6D7284BA185DEC43E31CE9B148CF708C722AB59CE7429617978F678E7B42B6DAFE8D +CA1690208AF9541B8EF5C8057A459A6D6BB3F0410DD1DAAE469A71B7A416CACE53E775AD +CA8787E88CEE3F57834B13D46A5DC1215DDFF7668A9CEC79FBBA1964F794F71D7BC2567B +10AAA3EFBC22781C66B3C89B7973748CC35978F844A5EE16CDD95BD4AF3C6C63C79577A1 +20B893398A583BDEFC646E917250AFE307E1FB053C3A8EFB26CD4F65D58DAE816549C502 +DCEFE24A4DDED6ABC44FDFBEA9A92B2F78F20710997E683F8D9BDB7C603A9204CD90E932 +7ADF5B551419354EF67AFF7225026D2703874F841A034FBCB33267D8794C1C1BB9B26F16 +04BBCEE30D6D2BA30AB3F8E03E0DB4D57190A570686C420FA4775B5F8D984C4C7505DF4D +309ED3BF16BB32B62241928BB3D978E10CEEC6AA72A00F786AC72F6ADC5E1BF1A234B6E2 +06FD0F6DB21BBB5D0D800BC43197CEBAE8AF770BBFAD4E41488AE5A8283EBD2E58BB4BC4 +5DBAE530D05418381BB610F5AD1AC375681618A7913CEFDB93815EAD3006729FD89DF4B2 +39E5DE1DCCB4BEC942EDBFCCC34C46704F5B31BEECC45558BD2E2DF554E6130112161BDA +86C779B47D9E79EE1A6C41A722F1C8710C5470F02B98B6A102A962E456827E7A8E9C2527 +5F9EF9B0D3420A3CF1F96B798CE32F47C076A1973AA532ED91B44B6627D5ECDB94E488CC +A0E54247BD99B1035769E7DCBC91BA655EBC0576E42738B7BAF5F7A19EFFFB78E0DD567B +51C9064ACCF00AA9D6AA5F8EE73AC3FDDC1F501DC67D9257629C767B9AE582A1BBEE8C0C +1B4BA4D5830FDC6C3A3D164EC1B30B8EA721ECDE61AECAF5DEDE7CE02F336A22E302D711 +AC6B83152A1B41C67A5D3EF767153F5FB882D0448B39B8507ECEEA86CE74EAACC8AC3E78 +E20FB23FD92C81D2EBD9014530F0AEED1595039D94AD48CCA8BE1C77233A9AC19CAF5A45 +CE5E96C5B2A962E8DC39339A2B10975C18C5B6162226221AD8BB4307F64E2B2C4F01FDF3 +1A6DC4966C9D6D2E3D5E92F0D21DF7779E35404C97B632DFF66716FBF8993294CA6B09BA +8F7F840DAC99DF3D75413A0F417416C7FEC264D6CC58355B1290692666A47E47F0BA3CFF +5DBC8EE2F4FA068D8059C1CF153C65BAEEC4F8196600B9D5C09DA14C8D5F87D88FC7DFEF +B797D33E292D4A6201AC0DFA4B50285805501F3AF1E2A48C3493FE2DB06589B0C045B0BE +5A2C5601F2F4644E6FBA9263BAEC6008760AD7833187540BDE0DA3EC762393EA778DF052 +BB978B708C7A2DAC5D62B2B4BC6EDA8DE77E548366C34411463BF5DACFAB701D0F64E937 +F5188E46151F8D47932243856F3727904404BD99EFC5F0AC5DD895CFD4067B7F338E2DF2 +BA69A84D26FCA6DA0ADF101669B9B502DA75D202F863D2AB8F821937F180352211F24835 +707B5D821DD71A74E4B9562370F2C61A228FA42F12983E32C15B13AF9F2D59CFE9FFE1D2 +4412F40E1BC6D90E8D943DFB8D5A36EFBDC7836025D6193A8B7AFDBA1EC3455F2EC95A6C +BCADD64C7D41322C98479EFF511BD4BD70C06EAED0DEFFA2790649282EDCC5F3ECFBB70E +7D62E1184DF3A46B154DD1AED7BA74CA7841DE08B4DB92DCF4F1C2EA54738F2BBD8A7B70 +0EC21D05AC8650A7F1802EF604A9DE97E8BCA273D26D97972ED752E3E9CA7D3FC11AF401 +D01398DEF5206AA94D0A79DE65F02C3E9A02C2DEAA900017DB7C0AD39F93BC2EB27F2E64 +3BF0FA8AE458C73B62B7709AB58D8AF25511B5C3FFDC5F45C4DF09400AB5E69054AB6BAE +57D427BFC6A6A65DCAC262E99797304D660B672E72BF8BEC5FCFD074A5D1E949634D1DDD +3399A80D693E3494DE56E1D0CCDD217FC6C6A2F4D6ECB7E3636E438ACD4E6B7166B27342 +2298824C5C547423EEBAA5FAFF2FF810A73C2BCC057F7FA1E96F21D665D377F727CA2FB8 +93307ADB216DB69824B72312242DE1105C4D7B048476E64C71F4C4659F084916660CD035 +85B922CB2EB7FE0E940A7A122313A85E0AAAA7A2699B4D1227D8A2F8F59B8FA5F6CFB63B +7ED2F9AAEFB6A71D186815A0CE5816A787E25288A9CCBCFA886423F776DE6C09B17858FF +CDBB8A52CD54BDDA98CE2BBE25849A2B4B113B6B7044431419512A00CBC8E5703E5A4A1F +954BABB0CA465884524BD70CE67D6FC9E2BD7E0615DF712866788A17AF26D842CEDC9EEB +B0A3061963958B9140BE41E74B7893265FAA57FE53140658DC931F0B897D0E857AE3A337 +F04D884ABE8D8E1DF1632DCFC2BB65E4BB2791B215957D5EDAD04A4D1F4372414D26CD68 +3CD89B893EF0CA895C2D36FF87A1CFB2E9F1A628CD59432046022B3E44BF2B5D5DE76F51 +5165FC2EBB07FBB23F262C07066D215DC73EDF780FFBC54502E57C69DDFC77D9896D3824 +D4749482FDBDEB40058FBF293BBEDC8C7AAFACCBEB160334D29AA7F61F34B929F020F8FF +17CE610B0E0D1823DF605B2E145C9E78AF8396E4AFB267C7679ACB0B7BCA258F7AEFBDA5 +E49F3C3A17F0290F9DC6C5F51F193E2DB779CF8081C733BA0D7FFBB9EA3A2FE3ABFB4782 +B2510CA124ADFE0BFBA82C46A0BFC430C2CFBFE41DC3DFC070FA9DB38F0D33982127C8CF +74AF1001B096849C8A518B6CA05445858EF78DE8B3B6F3019CEC8E10775EF9842DCB56AF +982AB270C89644AA55B486BCD8616B440105FA6C34298422C994EF6C30C1574ADEBC0F43 +85029231FF5FA84AAEFAD31442120059A7A1D24BB44D14844A039F366ABCA742A6279402 +7B53DD4431B167F07AC0EFC75ED8545431371D5FEEF2E51649D1AC862FD5E8C18ED86FC9 +9639B861D2B502A2B5F75062891ACAD88D39729CE2CB515DF3C49413A974476A515E3F15 +E071A6A82D5A51036FABDCFF62659D0B54DC1B9E68945E87A4CFC0E4D285D23BD9583126 +4D2B4E4515A7B34F83A077F848306AD71CDB2B5E6F701DF84AC82CE1096B987E2DA09727 +CBD0DACE976AB94EE6B133C09B787C80F275DA36605CF5955FC706A332E3140B43AF9C02 +9C23C489C5C15F77F076C6A21DF7B91E9249E93854406CDCF2EAA68DEA68BABDF5AFB702 +CD9457BC4FDEC0251834A5FE1EBC40D1C8F21C3C56B2558E1EBA3AFD3E0B53AC7793E078 +73F8A219C6057DBF6BC066367D953F44EBCE2704D2258344AD65CA865CAC50085E5E321F +B66E4404028E313876B65E5CCE58DDECD17DE76874030B63B267639147EBDA692745AE09 +775C4CC4C0B44469A01BA55B87913D834952541CC527D6D24238A5CAA83CDEAC1D7B5449 +7B6F9F57E0AEBCC7EE2DF0CECCFFC7FDB46DE41FA6E6D41AEC58E9A2CF359F9762ADC653 +5C52FE93E9FFE3225887009B596AC2B29336E0EEFF29738D4181D339F0FBEF72D29C750D +FE1318CA42C5393D639E7650AB689225BCE2072C88526B9AF5B970CAAB8331D89B888345 +BC5E839314B671E70CD895F56D945E8584A7A956EF105BCEC436117D4BDB3791A741B7BB +5B2F0033241EC02B40B75BBAA4C99D5F48FB370569C6E42B8747476E405B9D683D2FAADC +7C4A02FCB91C654F47C80AFFEE61D2310619E72C36695090BBBBFB5E0B7169B96BDBC9EC +4E8AD00B36B4FBB0B849CC04675277733D2FEF6A6EE9C83BE4900D02B95B516DD10A53FF +4431B3BE8C68AE823BA121DBC6C22470BEAE5AF5441CA8208D3DBBC3C444704E7644F8C6 +11B0890325648B2EC17FBAE41012E7D49566E5016D94336D4C701DE2805AA001E79C9032 +C64838049D8D065A171C11F06BE58A478B9299B3A517C73CE84EF38D07F291EDE3535CB8 +D769308C2252C63839CCAC3BC9E8A24E871D90398F3187E3557E40A24FB1C61FCA55BB70 +5EC3B1ADE33F0C6340338B197654B373EF588D43E710869321FCCE8A00596981C49B185C +DA92F64E0A65CD32D9448491EEEF78E4F410806EF4D6DC5F7804E99B87E640CFC46B6975 +AD18A05C470D233D23A20B4F85E8E008301D9763C4CB53A6CB6F380A439DDF64E4F69367 +446A0B57A0E98A6ADD0CF0CAEEC82BDEA2D130AA246EA0E4FA2E8DBB4459D5FFDFD7798F +842CA8BC7458DDAE4C28FF65568617C25E0CE82CE644B3F6445C7408E257FA1791199F5E +711023E5BC7E5AB961E867B06B83418954EF9A59EAC6566D572B4E97B5C6750A49636929 +562C6E0E2737F5B9BC06EBEF9FE62D9CF4FA509A42D192482B878757B319F886FA9EEF7A +563DE61A0BABBD76B9A9FC2009A9049FC6662C32434B6C8F4E410C2F5A146EB951D25138 +47D03A64A453B748A14D2A2FC9AE56A9585F1E6725ECFAAB26E99418F8F2F944AFFF32D8 +AFED5E292F40728B8804D91737AA9CDC05485F9F7031841B12F431355EA522C674101B83 +09CF71D8D27477286DC05428F7E8443EC7E4471CF97ABB18753524A79A1B331CAB1E3FE3 +6D19BFE3724777670FA07CAA0A501E1B5524E62C15D0B888414300EAB0DEA137D43A0B70 +FB6563163E0AE68D160B96B4A71817DCBD24BDD8FAD76ED2ACF5E0CE1DBB5AD9A1AD4B98 +997987FBB15346F93053314D53CF4BA6A9FC6B3EEC4E5DE20393D00A6D69FD55B98E3045 +C27469B46C39C40B0F5BF53DC1142AF67212F469FE7F7334A39CF19443C1243FAF6B05AD +1FDC50457F06D14F119EC724269EAC946793DA2CFF0C1AE736320C5F01B51F2780277D4F +A77680C81BCB7FA34A8F4F63F07CC619DB4BA4AE94420E532E6D06558D8B0D9299DF88E5 +479F1C82178C7FDB90830CEAB719A0EC4DA5E66DE2D4B97F11113E0DDA557353222E6329 +8F21D925AEE6FAF6121AD7F2E7F805F88901E53E353152729A737C197937EF857257BC70 +0890EABC66A8DDD6F4636DF744612B2E744BCA5D376D2CE87993132742B66FEA1AA5A4D1 +0A5DB79DC3EC04D88B5B5CCC988AD647B7719AFF1F2FDC55B7DD113655F19E6D47D2CFD7 +B2BDF4FD564A6798D3696B5BAD5F7A3E8609B9D9D0DDC4F32F2798052ECF1EF3793B16C1 +F489004AB008CA729064EA7193D2AAFFA934AC2DE6CB00FFC86A54B11426A97A5E161899 +4DD7FD85144308CC4C376272E86849BDB4351A9CB9BAC62C53FF3D06580CD2CAC229FDAC +CF8BABD15E1D7D81A2388597FCF2508AF5F8D189B5E5A86441E73002DCE94CF0DD953575 +470ED6D6AD57F62FAB4EEA0EE65C5C2FFB9FCFD5F850DEF261314A155A18AAD1B47EAB24 +FB7C0408B1C3DC80C6FF2D6CAA3348BF792803DDBD9258C694FA9A4FEB1D3BE1E22562D9 +46D3BF713B8ECC1532BACC2ACA978761621A122252F5CF0A658C06EFFD96B39B7EAA7C0C +E691FFE170A91871B6DED3BAB734E733ADC503B5AF97D595247FA80B81AF8ED77F99B192 +0731917779642446DA30FC7DD5A5661F9268302D2B812D750A3F144C89038A6F573B0C62 +EC227C3C5970D8EA34781CF49E56E1ADF0743CE23940279CCDD27AFB7BB7B740F579D9FA +B7BF912D52F35DFAA22B7D182C022E2FAB7BD0D90F7B6A03D0D6EBA225C70E07CC00F2A4 +599DC63A9218C17AB08927C0AFE57C6D3F0E7E2240A8E0C3CC6CD9854BE51B7F69040BB4 +ADEF206D2110DD52D5746D0085D583E67DF440125C26EB27BB8EC054A2AFEAAAB3139B53 +653E4C82D085D35BE137B6E30FA4C81EB3F968B12B2F4DB0AC653BB3E13BCBD9994C47DD +99727A7BB5908BFAACCA7EDEC566AB58DEE6B4CA521699CB6C3C7460440A522145347A0B +9B572D96702B497B8F9C3EE612B3445781F3FA7AAC78DA64950EFAF975623382BB6FF724 +3B1078C354E6F4CFE12BB8F374100D8E9033460B5911D4A18BAEE611272EB961EDABF97F +F350744757DA2435292D03C54CBA103EB72626EC2680077B5DA99E248BC7581F791F157D +0F0A359070827288F6961A8B42F98C948AAEE02CA29166EBED6F41CC2B14274CC8CBE8BE +70EACDEF5DED806EBEF4FDB794A1A9EF45E6BB01183CC4058DD5D6BF33CB6A195DC97AAB +72DAAA73A8922281DAEFEE6EFBE9E66F1B4C6D5A72830D9CBDAF7CC287ABB0753DBA936A +B515518C6C121E52BD84359EC983A7DEC5E395DBECDD837788A01387CA0CA84F6984A9DA +4D93CB543AA1101AF32021F2D2530300C6A16C7B27FC6D98E8E192AD089E9D10F10243A0 +1403222518D2B80A79360F81472FBAAFF0348BD16D8AD6888CF4971C2B61A8DA0A469009 +45F508DF6DE8F7A061EE437A227887D1C24BF05EA03A0B79CED06821B6A53F8275C885E9 +F5891E8DFFE67F22BDFE05507F478C90D8A90424097FA970E2B5C88820520C79AD9B539A +A10EF6701499CB72F33021E5066D86EF1B2AEE8165CAC5A97E3C20E24229C072A41B515D +3B1AD941352CA33927D63A7B0065AA432994EF31520C80F4FA3E68CA9CA548AAD31A64E8 +D383F59BFEBC0288E76332EDF7DCEDBABB3E068DF02D19FD7D0FDAD1BE7EF4947524554E +EA87550C141BF3EA6A20FF4834D2044AC7733FFCBF34EE678ACA19A3A8FE3D943C2B3505 +242111C2B6307A00989A20E8CB7E4267AECDC4E6F5F9CD70568C5AA8A4E899E404C7CEED +9989C788AFE029340B6A3D6376476181D19844598ED5CCF1AD2CF4A676FBFD17C0EF5BE4 +66CBA814647C2E0B5A2D85F3D3C8C16242848ACC70063D67918F800424305F2140A76BE5 +AC8A5CE0E32E26618F308EA578CDCB1CFED7CD12AFEABC6F6A236BE927BD11AD0A961943 +56C174C7881373770078D3D9BDF23CB838C5D64F923EC5831B791D5604931A8834AA6D95 +A79FC44C7DFC090CBBCB177A42A22E6897CE9376D17FE945E1E813AA473CC1530A7A834D +0EC298E73517624640BB35203A089D9483D047A87CA2646DBD18EB02BB9F0EE711FA83BB +BE07B54F1B7AFF9F36575BA99F81F75326F59D9EE26D4E4F642004285B6BAF192396F4C7 +731C5504593DF687B274EF80F27105F4569AF2EF4C5C5E88D476A73EC4444ABAD8E9AB3F +950C9CF21BD78ACE310C328F988CF22A7EC165E724DDA3F25D403B28A1B61F668C013524 +32458C657E8FA6CBD2E6E91106AF5B9C8EE170FD1FB323404E4101CC134FE8F0887AEEF2 +3013CCFDFFDCFD5FF60897B720A00204E8544F51735C976EC497BDDC085BD209F756C77E +296716650CC169558746490D024BD14FA54EB4E0CB75E8E91FA2E256F3DB4844308C7998 +A0EFE04FC6B14B73A43AE16D586C6683520A82286BA58D24ECEC212CDD93D2810EB4856B +13D432AA6CDF05600A12C7FEAF7B990E9E8CBB8AAE023FCBDF953180AF6913D0DE5B8660 +E23AC2B170320467ADC89CD584E9A366F063ACDFD5FD44E5BAB3B7167254ECFB222AB3FF +2187E43CBA6FB705317EE5DAA8D9F5DB83957CD64508A61EDA6B5D5BDEEFB2C6214DD059 +8AF10A03A486022A8DB111374E8442CA13D467BE84BB1001E7B9DBCAF50F767330FD3F62 +A310CDF232600D7DFAD998A0EA10EFFC49A702347E6C23BE9027C2BDE2E9A14CD55788CB +0C8B4891930AE2BB346CAC0A2CA7C904D2343316A6F4202E22D4E448049B18EBE76FE3D9 +7EC95EC99264B6F938108A36CDC5C4D7DB364F89E9371EABC18B1CE08CE519BB2C4973DC +4C0ECA366D8C6CC07A2DD320B997D5987297B330703D2A2DFE33EFAE86200B750D1A2D2F +762E43A94523A2136492B440F6551374F3591FCE4D37F7C192C592133B3315D3435A9DF0 +F2F3F621ADCDF53F9CEB8E7B332E701AFFF13641C88DF71858352BA45506D267877FDD8E +BEE4E80EBF692631C7C7133012E4CA6082B90533BE3082C34084385CD16C7A4B7123EDFB +66EE5F20C2C66226542B98B437C6925E7CB65C02F4C659DAB78FC4ED155C312DBCD5BC7A +F588D049D52655E57D3964D3BB713C6F7B33296292BB6273D626EFDB0CC6E0D346F8383F +315C275FC9FE745C9CC2416F3E1B896CE9D4621E0B1798959434E380E5672C9301474FE5 +C50B8344DC9BAD4ED7A57F965ECB1F9DBE601D2967701D4C083529B6DE730D9940D03381 +EFCD0F2E5632CD6948F1C7D3B624A248786D69E581B916263DF67B7AD6C34F034B3F48E4 +D26F64BBAD4B57E5E3E4B11BBE3EADF529E0473547DFA0781ABACA0F03AEAE3C14884A2B +47AEFD5174D2A5F45530A8C9A0B7C66DCA9CCB84AD031574B6D3FC3E6F1B0D794D061CC3 +3FBF13B5CFC934C0561396DC77DC2AA6FE3AB54B6215EE21A65582A8A9585AFA2CAF8194 +B3B887EA4C7F71696F93642371258BDD862C0CF23B819B194777DA8503A584CB26B849F9 +5CF461F3321BBCCBCA5DFCB054837FB3C288ACC2F394158F2263A8D4956ED155081F1A93 +B5180BFB3B694BFFD214C63D1CC0AC82521BA89EFE47A573D8FADF7C7B31CC98ACB47E9A +517CD04C18F8A8116592704192274FA9D817D49AFF1BF2EDA8273B04A86E308F51336DA5 +FC70705D6142F000986593A7BBD524A4A03F5A1831E7434B0700B89EC3D45BFC3CBE0841 +06E053FB46BED0AE359A76CFB808CCB22DE78B1A88415AC79249BA9F9BC5BE2C3041DAE1 +9F6B46545F534821E0BF703A6AC49F4DF2D24A4A90AED84C71F87799BCC37ED9FEADEF35 +97ABB6D731757C04C00002C40F34DA0F35E39F6330A1651F89C321627DF1D1289C1C6782 +35D205CDBDE6BE95F64A2510AD7CE06D51BFB98E7AEAAAD4E2AC15E631BF136E4082B01E +409BD78C495C88D3B62E3112B7B72268C4B1BF55E4FF2EB726ACD3A99148B0D0DC516294 +1E9B8C97C861AD1551703D9B1B17D1613F8BA6917B319BC2910728C5B46EF2CF9E1A06E3 +645C52A5D4F72494C1C18F858D211D2EE721FE457969D9A9BAECB4A0058780025142153E +9B94CF1B20B717D5F9AC5BA9271B4CD61628402FC3883ED1D43BB2EE931614D871E7814E +5ECC895E6CD9BB8A27F55004E7BB3E4A09B1D9C5D6B49140BA231B867F68F3A3C9981BF3 +9D9BCDDDB6330C8329FD52B1F1B6A7E392AD3EAA4D8E63BF3A895365FFAF54F297126CA6 +3FC07DB3763E7D2B79D2974BD0A380AAB25DB48F06BED0CD275640E5759C966A22E2437C +11E92131BDDA040BAEDA876D8861FC551F32591621A14BE6EEA790B77752FA636B8A627F +51428CD373F2ECC19DC714100A200E098E262FCDDCA6328A18B060219FF495AD46AB95DB +2E33D5A697E5D25CB5F0FCF988D62C9AC53E415735BF0DFFDEE23ECA22528B3D66DFF37C +77EDA16945BC694775901CFA106809ED3B59312B4A1023AB13738FF47921A0601D0A56A7 +4FB9F6B73F1564EFA5F2A31DB04365A577A1D9DF9FFFE6A4692E2ABF7DA3876BA90B7FB3 +168962EB38E03DC5E06E1633947848968BD649CE9B3064CDD5F88477195EDD4018F60FB3 +D2BA8190C9B2165FB5DB5AD79240CFBA8D4B2DC061F5392759EA162CE0FBDAB3D8EC991D +3238D835F27F6440F50942305538B3EB8B4C9CB46ADC7A0DEF82807C277B9CDAEB65B874 +1E3CCA532A619367426CAAFADE5756F0C22E6FBA7CA826E663ED6716308482C957703BA0 +FD4322B105202352E9091B44793A849E17B9D4931D7E4FFBAAFF32D1705FF5D82A878139 +0B5CBB1E5E00A02E80C299CC3C9612FFC9AE200C4F4B919E958039D4628480A7A0279EAA +DD0D28BD5E1D07BC18D66FA86EC9843665066045DC5DEE15146D9B4CEC6B0CA6EC946967 +3A464C46BCFF5451383B65B62D348907887BDD77931996B56645F118E9392215662998D8 +51AE73BC084FF9931D22E5012F6D18ABF618DFB01CFCBFE1A2C53B61B84D3B85A5D04196 +FC8A0E507A87560ECB8E2DB3CA84A2C97AFEE1005F6A44E00E3924527B1FCB8A3954C746 +D6F0E4266940814355AB8B57D3AB85A89EFFD1E384FD8E832E6A846D6B8DAF0C99C3803C +F9BC1CC4A1B611DB8B3B3F1763F6BB877952ADE48CD9BEDEF049137CC2F0D859CB4EB075 +2A1E581D835921533C868480469430E3AE90B9C965B4130B20E22A060A182827628CFA56 +FBED3BE7A4C078E939BD9F79D1A51017DB08B27472B813B5D94CE9CEDCEF61AD4AC1DFA2 +37261EB3360CAA70EB0AEBB1777928B2199791EB0F4E0DA70F0A59DDB0B7FBD49AEF255C +BF51C0F35AE0A242100AB96E0A2B51F82D5413FA7AA2C603F913066AB8AC55FD474829EE +82E5DBC360130AF5FAE5EE9159B5E09ECE9678DE75A50F49EA5C24FEA536658D48417F7B +5DC4737FAF73D41EA93B3889B9FE272D79788E337120691A76D0820E24F5657DF5CF2BA4 +BCE1799E533A991BC20CC52CEF9142186FBFB77E214A4311A243CFB5AD566995DE9CF7C4 +06D4235FA3ADE98D6C6CF3DAA3AF13106D38C4FBA7DD764FA38225DC7C41BEA8E87F6013 +8D320F004E832F52EE5D716F21C47ED0BE801523BB94D9691B393704380A58722C70E0CB +F70EAAF9B5CABA0D298A0152E246CF19A63DDFCE9D45E691EBD404B4EF6F14B3AB70329C +286C3CF24CED4D7591E4FC548ECB3B7864677028CD1073C949F6E334E528D62EB1EF23CD +E94DBB71E289FD419A9D51579BEE2F1E66C0EDBD29A32859F1E5CAB29264EC3D6AD03E0B +7BCA83FE20945CA48A4BF76C1F89B747DDD06BD000373561D123AB04AF26D1A785AB792A +95ECEA3DC6F5E36A143204A17492A6C3C9F974D73919F4830BC2ADF839B83753C3C58011 +BA6975CEE5655357AA6981C18EAB50DD25E4956D2912BDC0B401BF8E3E719D34D4543E00 +6570D7F59EE1E6E683B53B0DB9A8DD3C188FBF57C719C8E1A35EB957151D5CA1208DC55F +F81AE455B267013FE1515015206F1DA5E7F9F56C1F0A2FE55C1724CDE3E00C9FD055F198 +ED0E75DABCBCA26D558C90BEBAEF6F67D9DBE1758FA9C67FD49528CFA39AA21A4CB6D797 +C5E81AAAEADA6E7EC773F9C5ED0D2B0E722BBC8D449F5692E6FD2E90EB3673648EC34907 +8D99E469FEC7D6F63606E607BF946C78C1347CE1CF45DF42036AF0DEBA6AB19ECF358DD8 +C691742D3A0FB495C0947C3528B0AF579C16598750E475F169C1A36E8DCB33D2151CBE14 +52496F4F9414BC8EFFEB38D22714D2388B56035A4D431EF4D07D126CA898324F2BE44E42 +BDD930AD74363F011B2EA953CA48A7065C5E21B0B0E9C87FEDCFCA17AB6DEE77B167F31F +6E157B289EDC38F47D836250303B7A6662825E184A464B3B6BAF6A31627EEC2E932E617B +16806DAF25E7A6CEB17E89C602FBB0191592BDC0244293F46E0E698281FA9B697EA945FD +9063410A495A75AF971B7F50331D3FE964B3B2E7C6EA890198D4AB7D515F58936D7104AB +67013017B699EB3F3DF5F49744076536B951160156CB7F9D64B035C6BF0C3119ABACE506 +F15605840976E567A1ABA8B94B3B956A2982806AA50413B5F89514E0B065A6710FCF6173 +5C91FA417686324F69A98BD4EF2B0EB1A3CE20DEBAF35E592CFC68CB3F1640B91D20D415 +08DFC28FC3AD0143A8EB9BCDCD2D2BB45844D387845FEC9A6C9E26F495573F7435B6C62E +93DAC158FFDB41A137F5DAF1F8FA134C26A1A40BCB646E26A513C76A6EB07B559522863A +6373062B7C033FB23364CD9540C146CC7D0C1F33A137E5BE097F7FDE6281EB9B9C2F8203 +6DC40494242533C561CF736393C54CA3306FB4974FD76685D26BFA885CAF41AEE3B4230F +DF98BA4EC7646D3F25A8A337C557E4AD260C6246EECDBCF0BED340BFAE2A0BE007640D51 +A583D0747A5F354406DF9D3544CEE1A8E45E0C3ED5B5727171DE29E75ED1E06E4B878C08 +1EA5AF1FBC2CEEF821380656867929E482C13FE6D3FCECA67CC16450E0BDDC5996D7B281 +7E15F29F94780F3E4561A3F0D53DCAD7295D68013E2A12F73E2887F500C5C40497802B5C +69FE8CA2F4EBEC94CEF708EB00D4E44C73741A432687036ADDD9021FC35ED215E742BA4C +D8093F29B90132352A60AA49F1A6351C80D63BFCDD2C4E136F18D605FC406EEBD81FF609 +F396669F082D83B9E1C9573A21C8BFF715FA8401CD7B5DF1BB56C709A32AA27DA08F2BFC +4CC9D74491D7452C51C19D585407E97414FF616B8EB4FDB31672B93EF09B1478907D3B22 +8AFC23A38B48E0B1AEED91089548C135CF3BE546F737BBDAF3A3DB727B8AEED13A2CE344 +56ECCE70D653AEBF7B71EAC15074263FB58C10985830EAEE832E65609A6651374DFFB88A +CFD2FA6BB43ACAE247BBD826E54B6F6AB6DDFF4A51F5DCA90062BD3E033AC713FB95862B +540B9EF93991984FB86936A0841FD6491989B55980D917A53663A63952B9CCB826ADAB9B +DC71EAE0BD3B580E767F7CDAD1E0EE09C9A5F015610FF572B4778D19260E5C5154AEB615 +F494F6905F04B1420E9C4531A7F6A8840E79A83AA20DC7BC86C9F51B0D10F6F0DA001852 +FDFFB7E60D675CEEAD92F73756A91D67A760145DC0EF8565833F84C50D0E17A3A1F33676 +E467012444D09186160B317F0D6063194E46E5A484CEF017C919D3E063AE2E79171D937B +1536CA40EC4E4C71FB24CC038B20CE25504189986C5195E7C89D71DA60F40C8E34BD62EE +44018745746F174D3E30E8F2AC3CB4165474B456A8E4BD62244C4698B6C18630122561F4 +6A5776B7961FE532C7DCCED058CDF95197466C2D6B5ADCC3A2BB6487B5DFFF6E95612798 +18FB8D213AF93B346458431C42C697F3E98EF51A234B8D717718B7EC360F181BCCA72A74 +C99FC0BE536FBC7F71B32AC4F85035EAC720C49C03CAC855FA49D1BEEF2799B86D21F3DE +5F3BA47568811A2909D19CB06A3B62A285744DDAD31745AC58AB7D9BBFDAFF5E86EF4806 +5BA5BA3E78F6B85DED5261177F0B7D20B03ED496B3957A34A4ED1D493FF084653D014BE4 +1DEA598AD3EE6907A53828B49DF06C3BF1CEF5AB6946BF2E56D646077AFA325482FF16F7 +93656A895E24CB4263E382CDE6D67C5506FA7E0BD0B20BDFE0766803BC9DF615E456FCA4 +8BC2E2AD6E4348414F748F031E23854AE6FC92650A55DE479AFAD409836481881C04729F +DC49DF2D9FC46D2BFB3B68DA59CED1280D0A97C7BFFFEBFC72E9BBED16C24B734343C111 +4A999791D052352ED194974774876A84B7B9339B85E6566B1C721A535A378AF89D834374 +78DAA191261D4C83E12F372EB245CBB39AF956E9A28289BDA6399BD2390618BCF9AC4EDD +18CAA6EA6AF116C9560FA860C615467195720014657D4767D70F6817979FEED7A181CCAB +AF11554132B382423713EA8F05092EB14DFF6F06E1A813BBC84091E76038D6E3DA10DCFF +81E750DAAA2BF7BB75C4B1A3347DC8436E47D1B9780DA48842492B86E7D9DD848E1E8F62 +4BA0B054DBBE5328F208952E19707BDC6012F04A475D47D8C7EB6A64C2AFAE3A363CAD97 +936DF3D6347D8CF1862818495A6836AE1343272EB8F34BB4C3F9B0A631E922C920446DA8 +34E9C2F3551BF71677176A1F414188645F43BAD39FBC3453265C05EAF83C3F8B85CB80B4 +B3B5AC99B901E6E2C9A1C065848A814033FA6D5551954D4B36BE89E01C1CD16949005298 +CDA21D4BA36577A9784DAA57DFDFD0621EAEE192200CD5932A18442B6E925280A7B52D2E +8C7116DC0CAE26B92A9A81B5B6B62836E3857CD38F2F5AB075E642760C0B442725756915 +413B2636001AC3D87FBFABC43D6EDD8D111B01942EB7FA47D71AA4520026FB22834DF914 +791FDB207DF0897D89A0057B2BA1DBDDDDE182DD14C85EF10D35F6ED8CD2398171EE25C7 +9C54D90C059A566A0936B8716CA905803FBD950BC4595D9F4CB59C37574AAE4055D5B472 +DE1E6DD3A7C58CED64FFE344AF8B8698F8F1D2FBFEAAEA7F136EA0044472CDE262C7FC8A +0416A868086A5A9A2669B7C6B97482C570FB3192255D5DA008C9E13D1F5A4A3EDB7A5C35 +F71797DAC5B5F32A5C03C429198D56BC5B8BBFBF890C6A29A4DF397B2863B75FFD8DA751 +95F747DFC65379BA575CFE55A02C589CC8E62B8A8623FCC135E90ABD9900782B42378CA2 +C55BFCEED08EBCACB61C53C5678787DC29D2455EC3A379C1ECA2707DD3E8C008E26C42E6 +C48C8E3B9E0F667C541B963313F4FEF02BD67EFEFC63A1A0093A95F15FD139398A4CAC17 +83471AC10E3598688E1A6E261AE763A28C58E8A5B9CE4DD7B8971764340B9862AF36C89D +F6708F535653BA9CE2711624A646B1D1BE8AB250275A1718841830BFABA2A900AD276D4D +592A5D7164C6A7B00A62B08C7F27ACBC78C91E91298AA4B56D090B0A8546549B2BD2E3BB +6FB39B6CDC7EBFB5798FC9589DD707C01842E40FFD597F2BB1B3EE4408F9D38600804C82 +2ABEEDAD6AA6EA75BAEF32E3C33CDA01847303D9C142140FA1B6E71E2BD3C78F5ABEC001 +66B2D689A8C4B0A7A1C32F3AB9DE8CEB7D20B59524656606DB340F4B7727FB35D2176112 +F91C3AABAC27DE231F74AEE1F6CDB49E2844F40F5F01FC9E96465FAD1D10E1A921D81F9B +3F13CF82DC97DEE3462F58797B21E6DE4279A153669FE49D78CFEA9835D5A85ADE360B6B +4EBA9BB8E9FF8AFD2287EE69877FC6C5593A69114EB174AD40F150282B1939D8A3BCFDF9 +74A8864679AFA7619D7EF1F347AD39E2899DDA9EA99E112D15E809E899A2294CC42F4EC1 +251631ED566907E1947F95ED61DD306F67BE79407AF36F34DAECABF7057555BDBE1DF645 +433F5DC42894C3CCF54D21C17B64FBDDB881A2C27765017B51BFA8147BF24157E7CE1314 +79D5C001348767CF1E82A9A43BECDF2F173A42292C8145FDB705CCEFD9ED6CC945A4CB6F +6DAF4DDECB1DEBB0ABD084011D033F0A06F66D9E2C40DACDC790BD663A2436F50B3A91BB +27B40F6B05B4D84169CA16CA7C7E609957A918BD60284C78DA035DC6215AA76115F0FAF5 +4C90315EB8A8F3FF25734F79300F0E676D06836B5FD19BED6CC7DF74548575820A735D25 +89F676D0129D8A44EB47AC1B673657EFDCE874541E2179437B9393978525FBB93A1CDB32 +1D1E47B3B6FDE0924CAD789284CE6F18837E89CD0E1739CEDA90AF44ADA49DB336934144 +D8BED19D5090A3E79B6A96E303A45E0DF44E795A08E1B5612BD05BE52E0508D60E5979ED +B9BB44EB5851737FD5660B71661FC76DB3F9347FD7CFDD2E9C23AC26F805AD8E70A52F73 +B11DE295E3285A08BBEDFBD62C67A540400A01D6FD969896C8D5C46C7093646E530824E2 +C9DFF21E870EEF04CABCB2F62EAC60C1B62CE5403A1B5620DF7A3065B44C7D28366AC821 +86E49974DBA9CAD1249E3EDD876981C595BAC7D05F18D6430F31B96879DFE16021590211 +9F228B03E1378D8E9F7080D517F8C668CC27A9A60F74134827F37CC38C65E577D1DCEEDF +2A207906E90A51A72AC31C4431BBB18242DE354DCAF50978E619E8A06CA801937B522396 +AD588A1FDEB567116CDFF51876FA3640027CE40CBE18D9423F05EDA77E876433F496FF70 +0D89FD7B47B848C5336C80A5EC644FEDB3F4A9EA02AA43A6EEFCDD27762051D2DE2DA02F +A03CD491478948B3039FD532751EA70F56C254893A034971CA7F65BFF5662D4A61AF91BF +752BAB772A556644F711EEF61958DA954494C50941CE83C6B7B6B2859AE7E9754FABA903 +35437EFE4C7B2B36B99251E0C8122A16E4F9C883DC4CD72B5E2A854622B73E6E3C4DA098 +1B208CBCEF104F5777F2BAF65746B7EC51F3C51AD38A12089E4971BAED178A9302F20DC4 +88CEDEB2CD8BF9607912EBF7B0BFC3F226228C96C0C128C498FA351081022E47F62EFB15 +23545AA028A8CE0F56C85BE3186D6811E4B86B31EE3234C595D34164B27D40295D2C2DC8 +1BED866C6A0405C4742CDF5A2563524C93AB0D350CD8B3DF7D219379F302A3A1C12E0954 +09698ACDAC5A2A89B7F54C846A0378E44E923CFFDE69B53F62FC661571E22880B065261C +B0929D4E234503B81FCD8771685310EF5CFCB2210073EE65770F445B93EACC6DE6556C80 +59794A7499C2402066996593653192CE60E4907FED614060F4A9F68F0B949C33A7D5672C +60317CC5AD98FF3301C2176E6CEAB2EF6ACEF60B6FB96F553CD8CCB05C2B1EED6044CB83 +40DF43DB21B567EF0A5657704E4DE711FC3EA7933BAEE7744234A369326D1B0BDE34A8C7 +2E328F30FE150DFD111D75122F29CED31C666793100CC8B69A17CFE330BCA55848B86397 +F9DD4950D6DF2B4486E26AA8FFB58445EBB14BBCCA683F3DCF2AC64025ECA14151D278C2 +977A9E046EAA361E658451DF157386033AD47B48C674EBCCDB79B8032A7D8FC01C8AD15F +E1B9A410C5D4B51E20AC8E8DDAC4BF6020A2751114FB024A96B95E3053F38A3E9444CF7C +C666B514EFDCCC3E167CA0B5F8095EB8D4060937718F6D8705A15B3E515201D9CB804467 +25B98EA469785969D46E24F05EA3AFDB074901774745286056761846B80553F0D3460CF8 +29C7794E4A360D3C731448086638214DC101591F4531543E9DB6BBEB1B91DF1FB3D1C4EF +B13058C4B339935CFB4660CDB385C473BF7ABA5B5BC69083FEA6A17C6D04B23E9437C8ED +14C680DFC74453C4FF2A6BEED2BB7DE8B346EA2DEAE4435DF08305BCE245ED67E41DBBF2 +96E3E10562A55D667D3F9CD286FDC42624B4BAF764E3C3378C8135A99F314C1CAC47B3B2 +E1FB39499594B223CC03EAC5F75BA3D91D892883D2843B29397BE6E06842D48B75DF75E5 +480F6501AF694E0E76D228DF52219C15E7F33267A9D1C3515308EF73D3DB303FCB9497AB +FA1236E8DBE95DE4EC90A9592CE96949D0DC55EF858A18DD37AF76A51EB3B98BDE0ED83E +7F4C6297245315E685559B4AA1D37E47053657E710D0AA3CCD41ECCCECC286BD133B64A2 +E8583148702FA532121E1E7B058BA1D24E7DF660A9E130BB8BE6DD87D005CEBAB1C8E87C +34C3EA39378893ED7752DC543535761B4A237ABD04B53080196D79D692DE2E53B7167B6D +76DA2279335AC5BF986E1AEADD9EE3A100756B15353BECE08FA788CAB5F63BC7AD58C442 +4AB03866AE0E18D4DC71BDF4B58A79C75D616933A31BD5BC14A2743E4A1EB88D90DB1854 +F132A946B090E2A092F71CD84239403C0CAFE30A7900061AF680F855DA5E91B023830B93 +48050178113D7831EFB051CA8534A3FA88222FB85D1A1E9D99936C49DE0A1DD7C8383F29 +B9B2EE1CD7064488D60C7E76F4F2DB018A4B9C95CCBE2F9CD7DEDE9501BEAA9C0D08C590 +1F9211AEF3AAC99DEFBD5F9C431EAA31798BD7D3A3A5604892F44CB3B736E8F8F79202B1 +6E9ED3ED418EF08539CD3DD9E624BADD761A44835AC95D5D07F7D67B93EB70AD8E86E0EB +5AC1D4263F51E84583E424D0444B673747A8B353A780A6F8549F11A4962641A47CB1C3E3 +C4A241D244BA92AB05E6BA17BE0D6DC648C1F9D5F88EC20E103D1589D0E86D2B27CC077D +810BD20514BE94853BCCFEF33D7655EE94DB8559BE3FC78C539E70F84E20534E7A5D6930 +A02889A4A82BA058888AB3EC75769BF961283481CF006D73FFA088EE019BB4AA990FC858 +621437BFB2D79C49157B5757CDC8EEAAD540E02BE1404EEBDC0B7BF094B80789D03B5F7F +5756535B392A64F9617ED0856A7D167A78032855ADF1E672851A439D9DF57967EFC56D44 +FCC6D878C31CE7904C70433721C4E981F2643C08D96E4753850A4F427FA3D984E00832BD +53437FDAB0A491C81CD6CF81D8BF5247E01CAD335A6DC9A69962B5830DEE96B57C9B08A0 +A5F401CC9CE286D3FB2B24F8E77508E4182551B4EE7B8139B80B805B64923ACE685CD576 +BF57A5F538B3F03C38B7DDFDE686B8F79271F8E4E909960D6D36523D4A217E4036AD4C84 +1E228DEC38AD432162211F5BA65FE03E0796A29EB8A8C4DB9BEA37E5C15A4AFF900A3456 +723DD6CB1F8BE7C5372A815691A92B5F1DD97BFC89FA5EBCDCC61AE4EF0245684ED4FC18 +7631D4292A94C9E3BBA81159E3688CAF6FC988236FAD971D774B54626DA436D10BD42A1E +86036DB36914728E66B8EEA3B432126A5C1F0FF3928557A3D7583BE21007D81D40D8359D +83075211A8366B16613E1B40EB840DFCCED4063CF06117963EF200E0FC0A558B1B69DED6 +08A00C25C68AA7EA0D902047A0981330DB2788E994E2196FED97CE2E777C0213532CB19C +A28B07792F57F19433A14D1E6506958E8B6483D3651A1EA10D988C541CDA715DE138B612 +76926F9793C603B1836E4E9A4DE110A69D60E0F9BB0D5DB9F4B67209EFBE8D69D4C20B15 +0640052CD4367DDCE4722A87E9914B7DF541DEFA52278ECEB60572E0CC31AFC6C30ADEF7 +5898DB0B4A5D00F169688EC5212983AD3DCA6604CD2B3FD4A351EB4661F025716B2DCA8A +F52CE6D269979C1F7E7942F583B2CB678F8DC52CB250C603D48B206D5547816C220AF203 +609BFE7B53CE4C88178C95A4E8F2F8B4BACB1CA5EF4CC1E76347AA958F2789D441AA1193 +C56ED7B27A0099B3EEBAC6AA6302891D3F16A913D980522CDDD8E3303437EC9AFBC4858E +D3DD92E3E329B34B344718E4950DE3829812896AA20A9480582570DC88FD7F4AC2F46B24 +CDDD8EC6BE4862DE1412F427B698B83AF5A0EA767778564F3C3CA40EA60281099297E104 +E46E308BBF5EF23CCA84F9D6A6F773157582EE0F1BC477274999637E199E269DAD3D67BF +D3EBBE840CD906E73A31EC7EB044E41F6B72367F6EABF54DA9F1664A1664338E202105FE +E7F071026D12CEDC2D86D581C496B400D58CFCBB7B2A551BDABAFAC1125090DDDEFD4F55 +55B21AC1F6E5DDAE6700935C521AE129F886598539C41D07FE2680F25442BC29BDE2902A +07FEEEB0A14E4F0201483BDD99D4142194BA2FB991F76B35D0DC31526A417212E5151E31 +60F3AD665ED99E0C7E50A43F58B2D6A8A075A96DFAFEA84C12EAD776CC6A3445771DE987 +DD0775A8DA30A1D0B92ED1D1A8B3E0133198B33C58A9E79943083C1EF44C0AE8A12D3BF6 +7CE1EF00C97E220DF31245B47F4720DA1F1B66A11A1AECBC9183C654DCEE7A16D47A3503 +74458A7303ECAC951588D2DEFE51919ACE2093697639CF60467FE9E43DC30B9FD53D4C22 +DB1F7B81EC206548C1E6E6B6CFE038764C4702F62CC23C38AFBC762D24E7625804867B40 +1626B14B8E45C6D9641B591D868FBADB07FCBE00C193F2F13F174648665CDA538E8977FE +E8B54B74CD4F84BDF7A1D2D1E64539F146D3D116BEBBAAEA5FED99C5DE42526EEFBB78CB +F8AAEC9F769B94FEF470C60E0B2F79C7F99D8C9C7C32A68302B352496255FB3785F74B43 +B4A173961F9018930515E6D1A57897420C404F32B3A0E2CDBBF8B53DCCDA0F0954BF6F80 +2638FBACAE414DB6C63F60ABFF719EAC3831C7D5AE46AAA7BECE1B71875D46504E61C29A +3AFA16498509FC57DF4B4BF40CD4D8D59399EEF835D97EEF06B373F6E006EC22FC61BD13 +99EB69F248D991725232C1C5BBFFEBF0477A08BDD42F32FA43C5F5C06C2BF639E1C86F0D +8E49B70E134B038781A1E85AE2A16FD1364479A5A46EEB1191390F469D0C573079523D1E +F2B049171F9345AC5FAD682E4CAE51E1717FB19F8AAED47B7572EFD188806BD9FAE5AB42 +37683C9797DEB62E1FD9DD5CD1D477918D19D004AE0334E7F6A705C4B6D01FEDD05DA5FA +063F81B6C6842D81A774C04531F708045021B8F11243E2C3F3EF7FAF5BA95C117B9DD6E1 +AABBC678F5046CBB55FB58849B6500A1A9593AB0BE9E2CD823FD35F60A485C3DDA2A36E4 +D13984CFFDC0992E39CBE5CD18076A92820D874E2576C83A6B02384D33F07DF51788BBF8 +27DD031A3520EAA36248860261133BAB4441635E255AE14B59B37B35CACB94688809FC1E +DFAD40EB2307B2E0B8303BD47A15F736F58A4B7D8ACC44141E5E7D85D24B6CD12591633B +7A005A49120406ED1CE82835C70426862D94F10BE0A51C894074506444BC899136DCE869 +D20F94E6E1D67F579E94D83DBD0B2230E55B90E01088DDA3748DEB1A7FBEB2D9D5625149 +06F512CAB6655C97060CE906ABD62996B2F1EFB10585C49EB019986CD391C1250C9E290F +435A19B3035A30B415C614D64E396E5AF2970E36BB508E4AA4A030C9A38ED4D04B967E2C +F5BDFC66833DCC48BC43772864DC29337040BC9AFBBA5E6272CEB78222394AF8362D32AF +C1AA0E3359A4DCF2A98F14C1876631E2C98E8E29C41655F970963592C4BA3D028420B197 +559C882A42896CA2FCAE8919352A02C39BF565A6841E3B181234E3750125F983E415A065 +137F3C67B80FBF6390B53BEDBD3ABF8E11C807C89B1420C37C790BAFFDE9EFFDE9092673 +DFC748B14ADE1A7B9883C545C0C145DA0D404571F94F4A161F7A747EFC311D1F52C33CF5 +993D987161F2AF52920FE97AEFC3651767C8750FDB45920C972401A337517BB88B3B65EC +B1E6A67B6B0728E3A1E46B1FDCBBE1D3757D715F91AE74F3740D2329944246FFC50665A3 +87B472AB71CA71539C2D15C56AEE7951666BB869FDDB6D91FB4F90A00163E7F1F4634472 +46DC61B4B08ED312157BA05105B93F0F8DE781CFB59480E1B8596A3354C8783CEF52EFDC +74C9D143C16088448B8A9CBBCEC59900B16961E845CC92AAF400943EEDFE174CB3E465DA +6D92240D8CEED8557EC7631EA9D2B4F0758CDD9847D703A5623FC1C96D321482243A6E9C +853FA07459B8DF72F6D6CADDE4D92A8B110566984A4B8678B8CC8FF4B2F4665030FC2B47 +A0102CBB3D8F4E0C40D761D05BF4B9A684FCE51A5F750093AE65299413225E64BB20D6C3 +E287D934DD3040DEFDA92AFBA6E79483DF64FE3CB9B265F7CDDB2F5DEA767D5967CF0393 +B7405BE70F810DEF309C5D2EE786DBD819EA4A4253125AEA8DDE8F9AC42AB35E11773CC8 +434462261939FE3EE8F30383450E3C6CBB033FC839332F6B6092E724274A89C86BB4ECCE +2FF70EF35268E9EFD66F1A75222BAA8CC9F9F4BB4943CB28207C633004F31E0721FA48B7 +D1E9D10A0694EF6A58A1F01EAA6BE615F2B1BAC49B9CC0A77FE251B7CF5611ACB1A0BD53 +8ABF1BE4F584AABB038F4FE84606BD96CF25FE9146651587023F868B13557E4153F2FAE2 +070BE3D081C4CC5410E803F04FC2284EDEE54DD387DD61F0B3C2A1815B35DBE6FFE337D0 +7C50DFF344C2A4D9921DC7FD0FBA8CA06FB07CED571BE57E89C3E429B40F0D8EDE7B522A +32AF6249D1EB966D27A5424495A82F15DBC8FC90B8619C0363AFA45C26D60FBB408606D9 +A37B385582513B61641595F7328A1EC830E90BB7C8B186552E2F645E2F09553BAA432558 +DEAEDDD0591CA23F19E6B9D2143F0CFC9550A43DE70F69A66A89C4E505E02FDF77C87E3F +A3768B12B7B7137C5DF761978563CC1C81AF9B7721D1E21A7E18CFD583EE4BC928E75AE8 +3F4DEF7A587D0AF30DE0CF4D74872360DB3BCD6529906995C1294DB90C93B44EBFB95527 +3D0B704C529EE441EA8E1EE2E3B03B7BA50CEC0C34AC176EB56AADB692EE9A53C215AB0C +5736A3A4EC7E37F2ED5E4BDC7B82D0E35E06915E068FD974F225E70461D780906A7B7831 +AA07687C177FE71B84A4136C7A6BF2FE6408A9C7049795C49326069BF24244430A960ABC +ACE67533486D6D5C6CA89D71904C5C48D02969628A2184F6B36C5FFB64A671116196BBE7 +4FA57CA9CC66378C0CF086FBDF05DFA609BCED01EF21DB027551B888242BDD941C302340 +0C2622E8557A0E12DDF981313D1F5953B57835592C8828C102C16EC39D06B63F31C373A2 +5077672A1134EFE0D4437E8F38AB373B214EB5F2BE1F6D80A07E1AA296AB7F974EE1DD76 +EED4B86A3CBA0E3C9D9F1A12F5E58913054D4557C2CC1C2C147196C7CB1435CC90C5D7CB +D2379FE287CE562D9B7660E157E175ECCE8AA94B1173665484D19D65A9B191D4C09D43B7 +90D1DA313C09025020B2315B0112B8E059E01525EE0AF0189CE06A307801725A26B2B3D1 +F0A1BFA9056E1D7DF67B1A8E82946D5328AAB07A9D90E21F5163B1E3DD6D789068C8A1DB +553FCEA69C14609A69805B3333EB608E4744C58C454DE66723A7794D09DEF7C6C981DDF8 +1B84B3E498D055ECEB6E8372D331861437AA69AE7D9A0932F4E71B9930D6F2DC38161257 +A32B87A7D37D200A5B9B5B257C0C9833BF04F91496BBAE83E9AE742362D8E74E0A4AE5CA +029B5CA078EA6D8F00B1ABB84A08FF1C03BA539128A42166D06E09FA8AE71B74A216ECCC +82DB316C9589BC68456F8ECD9B4BEF1E12506D537B6BE4CBB15C969B05D2F220B6E2678F +4F2D497DFB72D8F9584FBF0D363547F84E1B28FEA0C869A090FADD5B90E36B88326F6589 +BCFD8FDAB3993532F04949DB9EC2D2F2F1360E2E75AE76A6796A2E7AFED4DAB1B7B10D54 +33AB4C76331AABAE0D3ACAAA62C1BC3F72662EC71B76568BF3450B45C2D09BECB562A49D +3428A9DEED6D956CE1AFD83D90A0FC021957B45B8C03CDE0579EDADAB4BA570B29809545 +3A1D56FB60FCF22C038803ED3908D09A5E4E3EACD180A6D355FD7EB96B05305E841DED98 +07F75F133A6CA5D3415D0376504634B8DC2AC7A5BB53F9A3A032A878DFFA224FAD7A22B6 +9416767480B814D12E7D316D07AE8AA5117C04503B2E194F5CE94EFEE005DA30AD9114C8 +BA99323CF76547C24D607E40B62C51D86B672675E6F0730ABDC9B7B186D7EFDC4BEE86A6 +6456C4074BAF42818B46DB83D70FC8D1CA702CBB672B38BF0E776B52755468462B2EA034 +DA32113FC26E122261018D3A125D174D301FF7B16B57A406CD70110AD35710C2B67B7330 +CEC7B6B33770572AA9227AC52B0D6C6D0E25515C5844FD5D24140E01F3A4099BE114B94F +DB65580BAB585F3561FC997C5DFC1A27A5AB4CC6DAB5DF46F3D575316C81A2049089FCD4 +1E4740F4D16EEB08F117EEED488A6A9DE20B498CB60E48EB5A0839134B9F102BFBBBA982 +74ECB5679EBC7CD178B6F179ED979AE8E9A41763A97B4E14A7AB6A2C1A446615786CA3FA +32BAC716808B486702635502AA9F336C101A6E6A5F3033F5A92E13B9DFEEA4E7E98422E3 +3D051264262DAF41BDE94B43E0A375A42C59702EF2C43445C5EC7B6002BDE7C342F52AC3 +A5844A0EE75F5670C8B80AEBDDB2FE3D28BD6961037C0C54BE5ED708F683D1494DDFBCDC +976AB35442BB049A5ABAD1246996AB4E56CB0DC9596EE6ED06D02BB2DF9A7C9CD5B07BDB +7AD345607291736909E194D93DC68A1C612945A264A81603A9D0DFD5435DDB97F42957BC +AB7D6B400E2943A3F455918135E6EFFB0AA5E9C3509860CB5727363AC596CA1D08979225 +814CBD4A22CB979E1A6F6B9BD0359E782E852F51DAB107EFB2C2F1CE5D69D5471704572B +65A8B8B45305088AF7FA401348962022C952067504E39F3E879025FBE8E5ADD940B6D4D1 +737101C3999B9C6F58B259219AF84F1C146AE2DDF02C492FB5F582E739F1D1A3A0752CBD +5C401C91BFA7BE13F936DDA112AD87ACFAA7DF7CDB341443967E8CE3091F024329934DA6 +AE431187CF6C1955744518EDEFA73ED94EF60764C59EC21CBB08EA73512314A7E0658DCD +B61CDF37259EDE297DDDD7022DF5174DE5FA5216E566D1AF3249DE12E3A4EEF90A125EB0 +5633B85E3A12463693D5E2D6C01F5353761DE77FC8BDEF35FE0432E1CE3254F0F50A1B77 +C2245BB6DAA558E893F89AD98296C328D37C816CA808943AC488BC0090A4DB29DB0EAE82 +C89337A7C3FD1B4000202C42489974411B7B63D69BCB12E7EE7173E51D1DA17D7C82E6D9 +F810E76A97A9F118F1989B9DF448249BA2AD095A9698BB74D744C9ABCADAD6260E069C9C +73B05D41228C475C1207FB4AA8A14562FDC889D6870F5D045073F18D8716944B52A7F9C5 +0005002C0D1032B7F3ED2F60E9B27D056D1BF9AE3B1C9B4AE9A76EFAB3EB926376080C14 +5100DBBA2FAFB47E119443AAC33CD4A49DBB8C0E8629C56B8427AA94A6E076EDD6A16574 +336E6AC1D23E04E9BDA3CD2C926604C4E8170A3B9599FBFA9D3C8BD6192020E0296968C2 +EFA8C621C0FB0AFD399FD8E14CCDD94D5C6406D6B1A2564507BC818467322EDC55C3A3EE +E343DC08142264D205F542C023F8C82CAFAF6DC194E2016202247696F03CAD55224FDBCB +0E8DD2C9DC53F5BA9DAB23C033C788CBA2382EEA7390EE61A9672345EE2749CCA136632B +34AA12A5FC16974E9EB835A5598ADA0898BA5C87757D5EADAB5D0F71E4B75B8B1D711128 +E277A973EC136CAFFEF269A28B00881991B33CC8C5DF618B95C049CD97D746978B6C3AC0 +CB9EF6A51BD9702D0C14AB484DA4AC2400BDC557CD5E57A2421ADEC7F2326370E6F5D5C2 +9DAC782AB9255D0F4D0C98E7F9E0D7D31B114B1BD18AA2510E4F4A97582A15F170C12EFE +80842C1D3FB9C74F40DDCC8517FB123EDCA605305E841DDB1E5AD5448DD4972A20045021 +196CC951B8C99E3F000CF984252686EBBDE5DA0593C8514F131FA94949AAE1AED3E780CB +0504CFAD74171757769C8B2F51D54DBDE3EEB48E75486B4A75E4431F8BCD1A985C4484BB +1B5CA35F1BFE7B3A7C41A42B66756A229A7A5A0DA6B7A5084EEF6B8AC804C17F1E88E5C3 +D0C1D55BD687A9803A1AA74A60C0360873B37C79B09A1B823C3C8AA322BFA2E9B77701D2 +BD815C11DF5C55C393B73F98B73A500EEE6CBDC9E4F5405C73C3B635D6D0CA58BB47D41B +25149C3962190A1CB6FE7A8D6D4E26A205733F42BE8A2B0A8B4573C92CC98FDD07318671 +F3D3D5C7C757DD5AC7350F64E70381D190A05C674AAA796DE36886AA50955B422BF5995B +6F8EAD32715151456AEF2AD3D16FA3120B0E95D817F9CCCF7B2A55D529272B1E1BC060B9 +9F6342A1229DD8EC1DDFE9B59DBDF216006E98EC1AA5A1F55EA3D7EDCE63ADE2D4A3BE57 +E45A1FFFC04D1C9F1466583BB2AD58AF695DB3DC075327144B35BC40EADC993BF3BB97EC +A3F7756324E46DC6F4A13CE5266433C90FDEF6F46D38A9CE9DBD993B941AABE630ACA87B +B14EE46C977EAF512A769611F269A17D6A7889F28F4D38CB9F20580F6F4F5324FBF8F6B4 +F6C101ED306407463004171F3C8EEC70B9A2FBAFE213D1450F9E368E56183F4449780F4C +20171C3354E3AFD7D31B9CD7979F57FE545B06F40AB613B5B91D21D9E50B7B01E057F02D +DE24F4720972007D62736223D8C3C442CA0BBC8F31D29387399CEEC87700982A394A11CC +C73E118113558A4D44BA30924C4310F7C83F2C6D3FF570FCB031C12322CBD38CF98053AF +BEC2E7DA168EAB3B646713AD5C3FB0CAC7BE1D7CC779FDBEDA2FB78CADFB0EDE7BC13C17 +531C20EFA0C63BC58AA447545EB89FE0271198D71AE26924F939A063521C082560D97EE9 +6130A6F6EB7CB75BADBA1A8A00736860986EC623DA35F8210E26B843345B941C0C0B262E +B8EEB95482CB4EB437431E541F1C2820699258B1D17229E1DC8D7B170742CA64773F8062 +330A53950E929080661E588C1E4B85B5235130D50876837EF131D3F01CB0508954F39838 +ED8A7F38E5E7AEC8A74FC71EFE42E03E01B3CE075AC305B223B03944F9C39193A9EB6334 +FE05EFB242FECDEB2CFB62E0852B8AE333A92B8CD54F33318B1B22A8FBE47619A40D2CE1 +226735134BD860754D2804FC482441D48F1239B2D53E0ABD6FA1D556E4551203DDC5C79A +F0169D0306F1BD451D9FAF5A200FAC1C833CD3E72E37AF7D95860D2D04A1FCAE8EDCC522 +255D759C135B7812CBD0A6EA9BDCC084E528A533B79FE9CE5BA00E86448CA798C6CA5B05 +5EF88EEB8EB276D2E84524D64468EA6D25F062CE4D47C1E15CD734BBD04308FF67DA439D +577A00E4824EBFCB2EA5A00B55655157AFA0DA8FBBBC520A39B37D9FAE15A2CC90DE8B11 +9F69965BD22F20B63A3DC8C71A15510F85AC76F3248D2E5593266D9874E3C099649F78A1 +85F07DC3D9C1CA1FB2FCDF2808945571904E3E37A00EAF493BFDF11E9B6D4DD951C76EB9 +9BA671641E4A3FFA7C16F3AF41ECE3EDAEB91B0D8065D2324856C13B02C6666AE0DE50A2 +EB8380E0CF9665C3005EBFBC1AC075D05713A70CDD5590E7B9A54CDAA5F5BD2463AE744A +A12F29C1C2D241712C3A80DC860C4BE572905586FCF974241213D073D3AFE446608B31B9 +E4F368D5627A50E0D55F22899B18E8BBD1DC96EA7EE8411650950B38E5E977E25A210070 +B8BCD0C109AAA5E1D838AFB35A25B0C32267672D34D5E1F139DFC10AE6D23F14B07190A6 +0DA8E6522D3050EACCE19A9D1C762BFF247CADBD1D1F172C006DB745A3F4D05D33957DFB +471AE4ACE69B8AE49D8257B8B88D36865C0301D3DBF8114850A2B05D2A8121B3335DD399 +067962216367A8E8CC834D69BF7E16D06B4C7F602F908DA3903FEAC017228C976741A421 +C49048140D1B8D484153AB948A01CD7113C0AB9BD5466F8A26557E9F984BEA514EBE72E8 +C38FAB5F634EAB033C960539945FFDCF63E1DF47A8C6BF4460F6DB6778BE2D90B90BAEF4 +6AADCACBC8D1DE9BA3E9D4A2A8EB70F5CC3F02ECF6D76BCFDCAB9BBD36DF52DF860D64E1 +F0958B74361BA4298D792AF1D119905FE6D3067BFA8146CE1633D5C4658847F3F9E18143 +F1AB4D35C953AA5105FF94FC0C345E478B5B1D4584CA7BC050A31740EDE0FAC5EFA57126 +2CDAE360AB92ACBFD23807A0394160A8EF0B0F320CE3685040D091289DBCE3454B1ED51C +83D8EDB2C86C71805DDBD584BB61E88A673ECD1535F5891EF7695F182F783B59ECBB0DA0 +B445D7AB5DF5C9BD042929611182301813145BAAC4D54644E93BC8FD2CEDE0207B5D60ED +FF95CE7CC60DA632FEA04F8BC518E4A5197BBE065062556EADE480A86B8A2E0C9F1BF739 +1102D97C4D6A33B05C2EC5F457306266572C06274ABA9EEDB8F3C4E405EB5F132AB3E947 +CFF44017C6D8B79980DDEB698BB03BEB0C864A0766EDE34FED65FA889C5F149736CB7640 +B13BDA9CC6D5BF72FBC3009CB4FF5A877CA3E973A2A08FF25B212B8665DC4D6630B6EB48 +0D6E1E8DCA6F34AC6EAA482A4C6AD1763E17665BDE15BC08806A3FF8BE68584C8EABDFB1 +1E415329EFD07459890671D21872E0B0CB2EE1577B4A9283F224E3D0CA7106ED0C91FFFB +4A3B8CBDB5E528C8D95D19741F16DF780F6D49FF6815351D0F0D92A0CD72FD14A19E1DB9 +97C3CC11BD6FB2AEB5281951D508A3EAAAFBB048B87AFC7CAB9BBE1D1C407D52978B6AC4 +6136E779209453BC2A6A86C198D1DFD8818526715228EBB5F411E1554004F48FDDD2607B +E0D3979B82E35B78985FAC19CC95022D1F0AB9358CFE21C27BAB89AE4B03CD35565BC65B +E6E25BBC43F5298B14000AC0867BAE57BCBC40E938C304F37D9AC390A90BB5ACC906599E +789066315EEC0C15FDEC2F6E637A3082C85B2ED6BCFD621F033396CF1B7330D97265F873 +C92A64271C6CD63635758B05C10F67831EE579EF0B4AEAC245BC87541C1E7561E24B5E01 +B323E220BF1170BE5A4319684883C910556AB899372CF97C572D1AA86A34D826D6D4A048 +AE28B9D3E63A00A6CD36A5C4472E1B7840FD3B09A16190BB63588E98921E17D4180AA540 +56457195934F082F0C0F7D104E9271FB8E7D0CECCD395BCFF6539B76EC3FDBB1363A56ED +366E8F9DD48A9349E4DD8A78C5B683E8365F3D0B4F2F8DE3D70B0B8825667406898EFF52 +A957499AE83E6FD2037CBDBE6B9265B0CB7323F86AD386F7A65CBFA93DD00255BBA82F96 +34A80487F68BC69000869F6CBDD217096BBE6BD9179DEEBE12422C308CE023854FBC077B +BF1B820172633D8F70B26A302EE6B64258FE46DA73AB8C384756200C95A5623D0F2A41E4 +7EE54394A784941A06F082C737B9C6C5855C5F11729D6777E38A6B5F061C8E324CD2469C +37B564AED2568502B980A054BA7007E8D9ED7733D3956BF5A3AD62C262CFA0BA9BFE0772 +7B67909D59A0084BBB85DE630245D514D86A920891417AB9FBC93863498E04E1DB27EC92 +6F5455BF6A5D09BB6C4968E10A177CA4B057E7D360F4646C986BDC5FB0C7ADA94D69F257 +96A37E10F1C62FE65D66790A0599D0A20ACD87AE4ECAD36C45678542E8D8E364DA954F9E +E832D403BAD839441AA6F7118FD8C18B5C36F20EA984755E672FD1C2DECC0F6764711C3E +7F6710BB8C7911BBDDB001B9CCBDD363B8CD618CF15ED57B63E5436047E7FB5BAE45D062 +D2EDEC99D9335118AC31D73AC1770FD0E5618608C7F42507753B5115520D4E220339B3B8 +AC54C83451996E8A489FA86B1E6C990A5000614688D4C29AD6EF8010131BEC1AD2670F9C +DBAC78485175F999CDFFB8572F30648EB8F49548850B6CBED30114EFB970C8A58E814239 +CB0C1A855ECB24E0E38A6F4AC9EA5D255A9EE180F41213F8168F03E4F646411AB5B4AFFB +B17C2533092A51313D3556E734FA0970E0760CE24A573A511EDF00457F348C5E465C1AF1 +198BCBA0CA6DB414B66EBF68E557E2EA72E80D7615B3A3017214BF1525A6CCCD1BBB3925 +C42E13E162797DC077B2674BCA2265F48F72407B24CA2002C2DBD2DAEFE4D0BF1B1D682E +40B74BAD6C4B69328848F208D5ECA1A49B6F59E89B306FC5C47E6C007A5B0E5380538B38 +1DAAB61199AF1857C9D0649570534B486FB5144D9588547716F848A8015C8C2D21995D4C +860802DFB07E4DF45E09C7D7FD5EE824CE4128ADF624250D69ACC87A0A10F647E7575DF1 +E7ADE6B0BCF063411797D563441EBCFB213F200A4CE96623BD6CF127727364E0450EFE99 +288E9A3B1FA4A1E776C9BC581931B72749EF0DF7D786F898CEB10158B705BD15B6A9ADC9 +9C7E2E3624905EC361BEEBA65E43FEDA49EB8F8A85187973C5D19FB54BDDCD79E42E2C08 +130865F10D7D600246548D33303B617CD6F81E0A11F4BC23DA3B167E5B2FBDA8BE051C49 +536C4B0940C61A954418AFAD8B0B19D85DEB12B1219DE27FF75797D0DA16F00F80AC113D +F19AE8BF86FCBB602F3BC696611935FDCB61F05EE17FDC36E0B1087187F80D5C3EAE1B17 +DC1BA5817CBA5C3CBAB6BD6455AA2C3B44B57494B8BD08859C1213B24A62755F7CCA048F +63F3F430CCEB00BBF39343F25AD4B6C62039A3F7B943344F86312E7566620694B77C5B69 +2AB977A7331B5F38D883F9B7C4F89E4A66F725E0EBD8E988AB9AAECF32D31C75A3E6849C +32E4F06196DB937008FFA15DA36CA90BECBE909AEF6CA20E2315C82BA27385D08720E1FC +BD5652AE843BE5F3D457B7F488E7AFDDDCD29BDF7ACEDF1075ED819674E47D0FC92DB7FE +0AFDE6D58685F855FFDF52CE51B9C2720A82712A4B7BD96DE3EA95CD1635ECF7663C1D54 +A885A6AE72D84462639C52F987138050CBF73A5504F66D1430DFACF226FF12069A80ABDD +0141CC2E05524BAC464CA4C59AF2912A2A4EA112F8C8A0BC4C908BD6C0BBA0123110F3E9 +CE3A216081892A19AC53FAD507E34110EFC7D4699A98849C5502F9DCD4418FA81EAC9481 +E4C20B4F46BE4DD134FFB03E47D6547D6540E1EA036167460F2922629E01ED36553AF423 +0050BBA670A4B74790B213D70D7ED543F9787E8920551C4703DB62110EF2E30DF12E91F6 +8AE86C3C6F9EB3043C162C0A0CFF7D4FA90CFDA5278D2B47D265D06CC33FCDDFDF3C68D3 +6BEDCBABB491F89962A46F90923C51EFEACB39FA22A36CDDEA38855682F126AEBEC06558 +94CE26C769392D71F1C4CBC34E3A4565EE74D67AB272327B457D346B756322FCA806938F +BFB118244CE3B164ABB58135A96B7E1211220995376CD058DDBC291AEFEE79A41501AA17 +BE5200BA08E047BF985A97A8DCC1640E279DD35938B57C186918F163012A4C947D665449 +5CAC149C96F6A40502ACF8BE05D671777DCD218EF7FFF41AF93A80418A2AB81FA89120BC +91A462F034E8801E1251BC3327321C7C0652ED3B26CB8B6CADF42AE3D97A8DB1A732E452 +FF187A97A2E03372667F91825FF3CC861B4122A1A0A3F4564323209DCB8FD2A886E95F58 +1539C74E4F5A0EC5B63DFB416F3859B46DCDBE7D724DACA0C5B6483FEABF3F36D6B13D2A +49DACF1EAC4FA6C7B161A22CD876F5D511C2C2FC96C8B3AE53311E2D9468874BBB9E6B4B +D18C5DA32F4E00923F59D2FC2079BD4BEDFA9E960249C650EADF2937CF7E339FD103CF71 +AF2549D4E9763E75A84744E73F70B669B6808258677265A9C2A48D95CF90D1E1585B4B60 +D19CA105909FE1D0EBCF533562ED6953C71C3CBD9CC474B6F6418A87C6B608E9D62CD3B4 +15565A14EAA18B23199A1521B101314B38A6662F5EE6390C9DEB538F5AF1BCC84DC9CA33 +E2D403FB1FB1A2E12D485D534F1A8A27447B5F9F13ECE527F7CD3CD9144AC5F137637659 +8199D0EE633CCD95797F4D55447D3105AA87498F1FC8B8750A440C46ABF820EF499F9D5A +2818FFC414EEABC029AD6F961CA43BF94BFAEEDB8962A6124A192E1343E16A5E20204016 +B5175FF8252310B60F276148849E8556BBBD44CB9E59F5992AC845CDB2BC3B33BD7F0816 +2C36B7D91BD17A37F77A7938A5209FE92DEAD16A595E91917F6E49ECAD8C7B01F1565089 +815BAD961827931E718DF2B1F9743B938ACA21B648916FA76C5C99BFAC1DA9526A8F8793 +733B8CB1123A12E1FAEFE75332D850FB7F296539E76031DDEA6851EA00D97F7B83945C3E +5C29D9B7F31B9A7B541B7640C17347CB2E39C15FDCF8C8B8ECE605239020783F333064E9 +ABBF3236976CC021E852C2D1C1A95D6DFD5746E076D14E75D2D31D0E93260802D9B4B846 +865DDE6FD59150562F6EF062B5DFE7C136978FB4A84ECB6AD463E199CB6ED2A9EDD7CBED +D8BB618DA4E68319C7F194C0DEE2AF19A36943837505AA05FCFA86550C704A7EF74227D6 +58BFB33945D1E1FF102C91F6378D54AF74F1CEB81BEE7A848B8C933E4F9AB1D6914D9010 +9FF6C47194AFE0004A7245ABA2CE53A6C0B8636FB445E1D27E631618DCEE6E1FAFA19B28 +A3FF71FE46241F832D43FA786CAA4B5125821F13BA3023B54DC4E59CBB027C1720432DED +5D53E05E2E830F53F6CEFFA0F17394A13EDC3ED8EE8493523394C5C73CA15C428E481D73 +FD4BAC226F9B923A1BC380535B19161F12034CC22DB93B335E1D603F8FAFF5BAF4410A02 +C8D0391C8B118EFBE289DD957956EF0CAC55D68F2069FF4D24ADE54DC83286E790F7EC12 +2EA9CE466BDD9175E8D50EF54A5219997A440C689634B35CB4C440327CD35CB05AE77E39 +87D742854CEC4E4784D4C1B06340295D19C1944BCF826E96FF84B4C80E173892B6DEAB45 +DFC0BF6CE1142215881A64D73D10AE8BB835CAFEED23A7810FB3FA4E8D811809BECD7062 +2C9C6CE8725C331F42F991BC35674C0E451EB19887FF4792D738D4E22E4BB897C03E79BA +7F79F5CBFC2FB014BB58DEFF61A4AF62F3029F6829CF1DF5BD69FB1C73C68E36F2B3B1B2 +30B1D436D6DCA96563DA655E275ABB2AFD15D313D000D8E3F0D3461421D52B2A22623249 +E155D6276A5E6E0B5746C1BAB10B628092CD035976220A0121A3D16BC6B6F222511DA119 +E245943C5E7D68E32308EFD355CA3438436A5942292295282CB1FCDAE8B7A3AD3CB39CCC +5A6DDC8FC771700383C268F4D676E9DBDC33C14688F23179089396251728AF49BE24D02A +7CA4B1AA3CC148FB87E7C87EE41FE22723009FE89BD2DC689DDC9F034931ED7802B014F1 +C20D8F53EC110CDF35B8360FB1C58C9AA0F366260F36D21232E89FA1314476FFBA7F3AB8 +935147AF814D3BFF97635B11AB9EA47F6EF5952ABE438B536CF0FF25848F7480DFF36F43 +7CE6BD8701F4394A80E4D62731086ADAEEC41E6017A8AB72F890E9ED036C13BE24A7F2D0 +ABF1999B865B61349C501A9024FD08A319FB8E5DBA6E7283E8FC0BE48B9672CECD1F1091 +23A155914F163FD67AA466048A46DE447257D86C493B90178F37A23D66D192E552E46CB8 +E3C6D39B4CF574DF2C38CA6C74D0881E6E5C068766AC2898185BB326890F530984F3F31F +57F80C0220E2CDC14CE937420869C037B4C197C44B59FF91FAD5DAA875A7802A293679A8 +2AF31176B3DBDCA9FB5BF5C40038E7F119C61B7554F35DA79D942B9BE756497B3C9B7A19 +E5BCFFFD7BDD046EED61780D4CC5A7F8E3A78B7B2414212870BA0D27FF3C01B2AB030EEB +8F036B48673D6AB3460BB45939214BAB345B8D1FD6D2CDD3CAB37376244A7AC0FA3DF861 +60A193EE77CCCA93B2D984FA9CF07A54E9207EE127EF5B877A561216609567F9BD907BB2 +11A7383579FAB14FFACCFCC0E260DDCE27377C32FC039FF52A5D8059E7D4CFC880B0D634 +51482FC24A8E711B3D962A0926F4A0FBDF29036E0499FE6F5D115B7A95A059D6FCC36C87 +03DB34BB67B65F511637D91C428EED31371E9E9A00FA82BAC36AE2FDD0ADAD995E0E96FB +C909C5AC04BB213EBB5865A2CCE6942DD92EC73AF8C7D554A4B32910C7CE57EE79D11ACB +26D7CADECC469CF16953A50DDB0FF9A909F0382FC342CB38E2F3D8EDD0DC5919433386D1 +14B708E1AE5F01C2F08B8C8741D67BD1F02B4934A76D79B095AF43B68958BDE13D0F570B +71128A40A050BFF9C5D944C09A4B5D8AD0758B497771699B4E577436B15E31EF7D804663 +F768B9F5C9829EFFD5B479E1A0813E49D48705EFCCBCB2B23A7F0C39DAC69E7E35D7F4BA +770945D9F36A39D251B6CB76C88AD374E177B0F9D703865A69CEB6C0157419E781888F73 +47D0D641C43FF3521C3F380E26ADA5237ADE8C5FEEC8AF046C1B46903941181D958F16D1 +908D95A62869DE2DFD0AAC4D7441238B2ED50CDF729B10961883EC733F806C587C2D8F7D +B205AA3E7F6E34D5A2A2003E8CFDD22A63DAC1B04A11D77A6830CED7D9DA87BBD9E8D278 +275D1626D31054A23E9283FEC3D634BA1544AC5AD0E28DBD03C5CABF697DEAAE65D6167D +0E2EC4BC6C3B91581AC32B45F7ABA1B825848552D1413D1B5111168959A23F54C5B8E5E1 +B49C4096D5F546388E1279891E01D1FFDF63940F7AA520570B408C9C2CDA7F5A4B058919 +53B35D7523EA69927469DC90F6D8E15782204AE32885DC6BE6107D5EEFB29F69FBFECE44 +70CEFB37D0093844BE3ED424EFF064CF724A54B6B720ED020E70ADAC6716787FEEA1F22C +84A5E59BC6A643A29F50E3B76E6658D5BD8CA3554EA68CBFACD0CA0882B8E3389EE7945B +AC71B219233EE299C4C8FFB3BEB77BD483DE2A89DE4E697FA3A057EC47448CB99A7F1696 +00BBE4735D36408548405A8D4CE4209445DD0C4FFAA271ADCD14DDAA1598D44247156649 +1009AFC9B40874D4499857EF50BA7038F25A2159AAF9AC535EE1BC83E515D1439057F042 +C62DCB063AF8F014090AC771CC83DDFFFE0336CD4F14E3B6397E7AA442FF3C385A5A4B59 +2080801CC0BD5EA5F608A7936BD16248E3CAA7B49A475BEC9720EE44A06921A93375F344 +013752C467DB023F3F01FA7F427121DE5C4AFF495A06932C52FAA62C043B22ADA265BC90 +61B7702F9E44E326B54A423A472D23817F6135E05C1DDE477A9E27F42F5555E8FC22060B +D53ECBCA45C31C09BACC68EEA5126EE5E73502F2CF42BC5916B95590B778D556C4DB817B +2780787590B62405840D01F6B5301260E1EF0856219246C2CA7FBFB307FA728241E9A08F +F8FE0F6E708228172358EB98895B3C3C7FBAB501BEA9911A6C6769456E491C89B2FBD751 +C9339E174850B679B47118416AF8E849438FA52C4E2A0D1D8AB94385FED3747F9A8E78E5 +47FA728DA9C44F5D2296072A8ED789FAFFD237802988A20A8C16F78A50D2AB87A2BF8EC2 +8503F757AC6E9E556686A37D84D7B9DD81345E70D212D3D83E7D074A2BD9191D05205B27 +56E74664E1C3169AA601EE6276EB238E3EB9586C37ED4089E5C7AF97021FDADB6AAAF8ED +54CF169A574A7A6066EA74B3A255CFE9B6FDC2EABF4915325BEC03173370C41B71A65C08 +C4C809A78F52E89A27514E2771572235B8CE4E21229953786A90542924444BF56C163D41 +BCBDA2BD5981499D1BBFC7F7FDCD4EBAE43341EE9EBC04A5B3E86ABAACEE27AAAAEEA722 +63298EF83E19321B7CF9B1FAE2520159C2731E6023FBDDC81296BD2303788705D7A6FF72 +5ACD9365879F3742C0A375E23B124F85E2E533F958EDD9CEF05698E4F7E2C035EE665851 +E1B9B324D381BECE9AE126892F2B51826E44B80DF026FED2832BE1414CDC410B142E9248 +380FB3EF59A1CB8944C21E3B8F0450293E6FCE004AC4B002989C877AC2648964D137D881 +7C37A778E0EB56D243F6606A883875808323739C0B55B5F82C5BBC389566B7C24604D9E1 +9070CD37A2199B77BD81C6C0E4317AA361CD7F3D4CB2EEACF59D09FCB317C2E5656DD9EE +54D8D9C2FE364E21FDCC38F9FBE33457A70B75A4F9BE1DF8B6577B9E103F2276B77BDCA6 +0AB499915F331113F04C81F9572AFD95245AD3573A195D9CD1AF7D26FAB028F7A821DE62 +8132A99E8B39D4597457CBA2281394CF68069397BFB22BCF992989D8AFAFF25129A9F9CE +040FCB4752291D822EBD224DAC909194EAA4A07FC65F1EDC6C2D376190875FB8D2D19820 +7F71663705D83FE18CCAB848C11C5E112193D753B6A2BD9183054AE6021629E7927E4064 +9CEB4114C9B59F9827B98A70052FB67B5C45360C9C272DCD0C7DAC2A515707F6B63B2718 +B53B84441A28F777122D848B490C796185AD91E8474267D48B36DA7E3A7F70FC0F9319D3 +F937FD90AB3859794AC608FB96E283ED974159234761B8A114C8856FA00353C44D5C3976 +54488B0CFDBBC5A243595E2950E2ADFF06568551EC636B7D18FC1E68130F6623EB109415 +5F58F46A636EB98B30DE84A313ED1ED0EC0C8032B21ECFD11F2292A31E24E702D4723F50 +632F9D91DFF52142CFE2749A16B5B81F0ECEF869A7486191A3A910AE94C24471231B733D +FD6645C3856F341C0E1ECC17432635133CF66336D3C2C4F103C3EFE59FC7E45545A0A5A0 +CA19C0DBBF2B8CD3CBB482CD5BA7EBCA2CD5AC9E0C201FA4ACE28F00EB491ECEC3871AA9 +C0A303D585F94FCE1365117A59BD2644CE990F0A04239ED4B52CB5A0639BE554A2FFB03A +B9BC1E6C7989680B41BE26D2B01EFFE47819E737BBDB28868E0CEA2FFE4C7300B82E3016 +3BEEAA5EC834B2A2509BE99FCA5B087861C63EE1F84AACFA6FD77543D91C9C2E525BE531 +C02FF04A1F50C50B1F9CA7157F8A7787DD417868E48A035904BDA647EACC821F0ABB4053 +F19B502075211F1E1BD2714EE43D1AE7E19F8D13354D331E1935BB1246544EFA1DE7390F +7A561A6CC3F48C222A9C6C0B3A89714A16B3F61B6E26E3238FD641D431C7F6EC8005ECB3 +113C00A96AD8842746CF3D457F0F951D90C797716C3E8A08059207DBBB40D9095D8074E1 +069E36841ECC7EBF2081F293C194A044F5FD536D0F3B6551AD3CEA2FB84A5A32E20E34E2 +CDC9AF5E6839C3521EBECE2F4B39788F313FAB6D0F089BE45A7F4FB021D15C2661BA55F8 +691E8A9E5AE18FA617E5AC262F24962132E051BA7DDBBD3C5E7B3256ED5BBF7A670E0091 +B3AA0F6860559521C858CE6FC640029FD9D5FE03D1CC485A27080DE3BA08A36DDF87C81E +CE731AF1CE3F87FB19F91E324FF044110AE7C39110F9787C7F69E9C09FFBE37BA8B3DD17 +9B1EA5E176D6562DAC43992B8B5AED68898B6D56189426727100A36D92E2CB96672F58EE +EF30E90EC2569CEE9DA1B590F16B88E5E55FAEE2477E36E9CECA4D4DD9E969FC0D27CB94 +B5C3E738635D3C9AB4A0191CB553399EBB25D1D43DDA545A732B66DCF18A913EB214AAE9 +A408BC1E04449C07E114142FC22AC8639359B2413F3ADF5303088B00DBCD6AAF1ED46964 +F749F420207CE7CB3A27A4C260E174E17C6892695B3167B65271C232F1C67BCAD83B0216 +278FAD19834B58E7E1A2813EAB45DAC586EDEF11FF9CFC828811CC290C4EA40017A4BBD8 +889D5373B0002C0DCE55B2EABAB80E58B4341F386781264AD72C9B251255C0983AEB350B +03410B4C7E7E2ABE655E3A7AAB548D49C1EC489006EF4167BE2EA41CAD999E4CD6328ED0 +726C61B51EDF0952909C38480A6E801ADC241B50A972D31C7AC63BEB3746172F1CAFFA20 +D6E1009B9B1E79308ED3CD70D3F2975B0D241D8CDFD191A934E83E0BF3A938E19B3C461F +566B19516C068AD6BA4DF7CB37EA8343DB1ECD5CAEE329432E15147CE61AC4EEC2866463 +557C05CD59FCE1659245B7D8AB628F2ED8B24F6AD0B1AD37797FC20C098445EA1F43E3B3 +388550D0AFD24C74AAB269C1FE7596CF8F010D665111305ECFDEF52E89C240510D5D83F8 +FFC38DD47A537F55F7F79CB460F36812A1E3C26E8A7DD6131DA076BFA93D6C03E6E4C279 +D720B41A9CCD6A58EE1BD43A3035CDCE464BDC7CEBD79B867F30B0D15400B897A5ED7324 +A4A75568BD1211D036A5710F23C7A2E1D3F7E45C929FDA7ED13EFBEC7604427BCF853F92 +D954E627D0ED842663CFB64A2A6358C86F80FFB6A955C17B04B096D76B03DA9660D93004 +C44AAB74C40F99C702BBF33C4FE471ED4E6A0ABF3B15B340708D5D16FAB80D1E51F7D1A3 +8C7AC19A871C5D47963CE3CB961AF75A47C09B7AE97A3EB1C16D64D12A0798D5CAB48F68 +0E6B2DD1F7BCF7FD97719CBD7FCA4BC1CF31640675AB798F7A7CCD4E4A109E0E00A806F5 +8888F7A7091A9B7CFD350599C9AA0E7F679AB200035F48A57172C499737631A4F442F3A1 +BF5A3E5A2B77E02B66768DB9E76AE46E403E0E4BFBC1F14256ECD89BDF623F266389DF28 +AAC38991DDD4743F4A3B8EAEA45BF38EEFD1B7D3998B9B8542E78EB9FEFCB9D256EA8EA7 +6B56BA2A4849598F03483C59ED550D3508D12B35E4B82C2703883BBAFC0885BAE8B1440C +D2E368939FFE45BFEB172FCC597F19B089FC567332C97C3567C9DA05A3B99DADAB2BA61E +B9CFC9C1407322118C7B7BE2686FB5DBF0D31C5116F2F232AC8C3B6B1ED3E36AE2E9A638 +1E714212A76D2733DCF8F2BA8C1BB345A8B3D98162EE87C308539AEC3EC8EDA6CFDC423F +BDF208A89A906314950C1877A12E14C1DCBE5033474850128DFECB859E33F6EE578BB384 +DDC252AF788BD61E95E5375D134D6457B0A4690D7239440FF37E9F67CF10D1EE312653A0 +22702614C537EE7FFC677F630A079A98139EAA23FA2764B1D37CF5360002711890C12374 +CE980C83FF11E102C7AC31E4D96862CD3B8A77FB59FB8F3932750F21929B00912332196F +D9AABC0E4703C7BBB695FB1EC820CB6F69B9869FB819DD43AB4000BF70FA0320B5D3D2DF +8801021F0B0A45EEBCA8BFE6B616DCA4641358A4A18CFC749B17058929CAEFE146183C73 +BFD0BC668BE2EB8CC7003FBFC5F79373DAA86E4D9B65953031DCED7595D7779FA985FB1F +176161B955D22591CD434DA21E63FD9DF743B49B16A5ABE84E74293B1CE2BB4E2481770C +9B90A6641984001AF9E6DFB280D37922ED6A77D3C92F9E0F82B4CEC5FE92CFDCDF708EA3 +47EE98261C07F434E88A2042877D47C813992A1DBED99A6898288156CA26C7E473988BE2 +F5EC8DDD0FEE7D552832B69523330C12C6F0A307CDA286454EEBEB0B236AF69390B6FD9D +3546DE7015FBA1D36B08769D5DF07FFCC8AAAC31825F0F515813221E1D467F126CB9BDCD +E95DF5C7D64FF789BDB3A3339130A974D96606CBB812C8AEE855F29C5BDD9BA49FBDD481 +14DB68A228B685F35B5C33A9CE2CA9E0C30690831780284D6A75C9F9D86CC5A492EA5264 +09E1A2736EABD5FEF257F027B7363F8BF39519DB2940A1DFF0B3DCEC5CFBEE09633B4DF2 +6C29184ABEC66BB894F685BCF2AAF1301B1AB15398050C86A84E87491489F15FD2907D7D +ADD73C36FD0F7A40E021077CDD8AAA237DC9CB5E13C00EB7E91353BC58E0B8870BB319F5 +074B651F0D5179AABF87D023AFE75B3AA68D62FB959A5B6EFEA8D204C09F72B038A8C5D0 +9977F1457ED158E3BB57CE63EC2EE4577DE42F9D91AA5ADF0460374A36C972C33616D040 +2D8C1257C018B736CAD8BC182ECF63CEA524C8B3835E9CBF7618D930717C9DF018778787 +B5BD608E6DDE644B3CEC092A232B66420872C1412751FE7A72D604B7C01CB200506DD521 +F45DAE82F0C7CD4AB3B8E2E1B5A9B3D13546DA5A45A3195DC9A550D428882299614F9E8D +47E1674C7A95FE4B8E5EDA9D9499614A78DC322870B32E916C14088CFA3A76BA4F7CE4B6 +5C979130800F2F2D998F48DC5A2EC1CD18496402265677FD28F48CB38145EBDB30D2BBFF +15CA9FAEC6802D7BDC7F1A281DB9A6553B7D3F757A1FAA6AB91C0D31757FBE705EFE4C71 +AB0749AEFFE6768B35A0AC03636F4757B38C2F4C0A78EAA3557473913AC1AD37B72E79FB +75E2DA3A4A7AA867032A952D519BC5FC9BB684D0F21A661DEBE79B1C1513A16D8E32EB13 +E8DBB3F132C87ECE0972BF63001E8B9DC6C3F445191D536F8983B142BD94DD8F41C8756E +EFDB106BDEE3224FA448DAC03ACA80AE79B7DA40347D3C3A643B915C51BFCB861438C546 +1A59FB26B538BDFBB8D7DE77955A8FE6016F770BAB928D277CD4C2B3FD3839FE75308F21 +826B36084E485927C5DB75AA7B6133F468C71D218307B40CFE1BB6AD24E3C2240EE17084 +AF6C1E0D83CCE1699FDDB4763BC15F722D0383F5F4638785268FC439EB0A8C6B5AF7B938 +957DD111A83BA935CCF13A9DCBCAC9188CA67EDF1A6D18A34C956DE87418EA5E4796E59B +D981015C8D276CF4D8884AE423314AD62781108BA767131E08302A926C44B858B792DC52 +FBD6D15B5E9C4CABAA159FB5BCA5CAD068A5A718613598B518D015D3B6C43A01A5540849 +EC15F399A1DDEA9BDC47B409B10067FCCDA5932FD02BEF518433D8E7C83BA8567A2248DC +2271BB39F07414DF7655BCA33FA7811592168ABD559F49EC0F7968E87130093E607C2F1F +087154DA681D1C92C1B5EB87BFFF15C7DB4F8E319E42BDEC5B95A2F816BFC0A0CE997CB8 +BCCEA3DF23280D4C922482CA09EDA8C31F9C5FD9C22480DE591A3649A29F0293F976F366 +7A66D3923D6BEBD0C1A1F06C11C2C4207B2981E91DF0C0ABC84CE8B7B23B4837C51E2A94 +A7E3AB209AB5B99D40F39B1DE342502818A23235455B56BDCED3ACD910CD92E9E71DEF41 +0E3A01D9B7156F9DE0FC8916AB29D79F5B093C1CDD19CC1FDD6FFBD050ED563CA3C60022 +404A2E53E9EA3186A3177A57FB4B726DAFA37A4FD45D2C191E3E771C0CDA22EFAD7915B2 +15CCBD2A35E04CDF4779FE80B980ADE2D2E71B8F936D905AD7382B08C43A3ED6BBC5578C +80417621C7A3A87079ADF2B635671C36A1F57B971FF2918E14E80549150AB492D9709508 +ED98B983A9D40188F93847967A10FD16DFFE2C1276EACD959435C36899210DBEA62023A7 +ED706126E4E5E005B7608F078E3F0A42E87C84B37215F883E0F078127D47C4B362CEE951 +69F92B2887F67A3F1D02BEBF0277BA479264E7AD5E1087F613330246606F4907D3BA39C4 +644B7F9BC608BAC3107D9C66FF7CD9E9D624703055DFE0262E96B17BF017579001A7EE29 +4F4217B697CD9A397D35D8CB781D9FE282D9082D273AB082CCD017D7843E1AE3A41613F1 +F69AE113E8A993C83FFDBEDEFA92A9101B54D1AFB5BC7B41F3AB3C610E60AC17861E45B7 +34D7706BF6971921CF0E5344DC613EB31AB4E31775D990CEC15AF459BE474959EB24CABD +ED3B7D6A6540AA81B806D326D7614808FA2039A6675AC11F4E90EED294E867A84116FB5D +89BEB45F738B1275BBB4106108FB19D6EA4CA71E3B0C2BEA1EAC19D27EB928EBACA9DD62 +75865C4B86025B626202116190ECF58F149257C62C70EEEC110B540C636BBF747801A21F +B32A82CCF24062325AEB3B5DFEDD49AE625635C34CC330A93F1029F3A3A731537A0BF076 +C938773406C1670F4976AD1AAA5D3629EFE797A1133A683FBEC7DB8C480B32CA888ABB6F +049CDD5D65EAB1E23EABAEF26756618BF3CBA5D62286C938D3F6F20C731DB6044B89AF92 +F58FE18DC156E0F0D7A548C6D838F57899D7A693A6D158E5B9A19D4CCE4CE574FA1F9570 +7092879FA2C3F4AC5F223E3E0A174B97BB2CBC7815A20FF509B43D6EA17D515BDD9B3CF9 +4827C88EB2AC1FD13192752DB92070FBF319E4DD93EC6C9287108E248BC3F814CF3F85A4 +F6EEDCF1B78BBEE9987BB0767968894F13E299C79F50E052B7627584F1C78BC8EA588B4C +FB6C1204AAD2D47B42955EEE8563913BDC8167B5E82B48F3243F218E8832BCEED22BEEB6 +1B434A2AA2E93CB5654868F0A7E049852EE328F6A555AE92CB23702AE1B71B5E6EDF1BDE +ED68CA1E96EDD0A9B214C02A429479FE612C312D8B8BBE3DFD711D25D816709B78125476 +4AC1676AEB53B4CE261AD842C485829A8DBB25956041C5BBACB27B75F0659622F2791718 +110991560C261EC4834C976182843A56DC1918191840DFE95A5FA00624A6C24228805545 +4E7EDDCC9CA865B10991C4B73BBC16BBF6F0F4D4058FE9163BAC69EFB2A3269FE9F2A092 +BE8F9D59D9AD9F434998B44AB3892EA4360C38BFB150DA95EEEBA94B419D9D126410188B +475E794541F41D5C9D12D96BEDA86DF04640E6D766F0276BA1D0EE6E3B47A758D8D2D6DA +90B97B6ACFFA7D7BFEDF0BF7101F32248C7C72560F770D52AFCDC8F285846E00F5B0A83F +346B85D71DD49927304D228E2BE7980904A813AD23D5EE752D210FA2EBF72200914C8AA8 +ACD6B586437EAC4287C0D3C569E1969E71797949592DD7E1A65096819C7F3ED6218F1D0E +6FAFF3597787C9AF1C875E66878D55C64B2140B873C14F9D344E80F6E1434D0814B3C55C +7FF47038B2DD9104B7E836E0804B3E4042F5E1627E4C871AF0C42B498BD34475CDFD89CE +72E8D6DEAE27C84CBC4270348B684D5DB84C025A0CDD01F010F345ED7C75251990AC320B +AFF49806BAC46C8E87895DAD7D223A89AACBC9745439B6FB5B8603010AB29F2F9D3EB3D8 +24E2471720BC1ED2EE9BB61682AD6328D642B131780AB02A598BA9806C8327C43E1880D8 +37C5CDEB36BFD7812569F2FCBDF7B68934689238D59AB7D111FBF5BAD7DB4E85148373C9 +6016A50269968F2DB4824C1BA985C6FF1AC4BBB99F57232795F390BEA26222E79BB218A2 +23E68505A11925BCB27A403E5D27C9FB0EAFB29B7B6396CC58431D267FDB5DA11A64662A +EF150E3C268732F5EAC6C2FDF28FA507531ECAEBD55F4B0AB89D8F4C4CD41EAA211EDFD6 +65091948FF530681FBE7919E476C4DBE1397C51E4AA2C4BA1F0BBA3ED714E766E2638ECE +21B08E93C2EE29FB886C75B9436D2ADEB232736CFB5BAEED34EB47FF78CE41C6444377DE +8B7970BB19E9B52F5422305F14BB7AF0BF98F46D1D1E17B13E679C99112388F39827338E +E36498823D40CAB56D7C2749AAFF144D3F89A703F2F416C34592AAA4C6C30A96F3287868 +CE6F6EAA22A55E06F5D353F441E62A851A138B6E26631EF586EFA6952D428AF7D71901A9 +7E5BA59D462E10388C233E191AEEA380D9E2E23579C4345DB63F7691D0378F950B9CD2C2 +C0C17A8CF6144A7E81CDB3A5DAF7F2AE6A5F92E6910CA0D7A50569EA890FF71DD49D5012 +BD3FA623A1331BDE94EA4D2CD2C538AF787632B6339925FD6CBFD8ECBA7CC464B31DFFCA +F79AB027945A2C1E9C058ED8F0F3221A0353961BB2B2EA75876B74EDDDAFB7ABFEA39F38 +36A8E19C9372D3CD704A19B301BAD2801B16BEFF75BCADC90D2EEA514A199105FDAB37EC +8A75B14E67B638CAF1ADFBAF70D38355A66B513BFEDBBA2CC6981C25E364297C873C908E +A288D930A8A18AF24C38B92F520DB5A41D708A438BC39356730D028198A08AD3430237FB +8EC675CE19EAF97C06CDF706B138EAD722EAD2C7C6108A4C474210CE38A7A4EB0FF573DA +59B024BED3579A7C870AFF17EB284527030EAD8F515D18EE490FD5D32545527F38BE7B7D +CE9C1D1283B1771AAD8953E6D89EBC068E1C42C8431D6EC365F736652C4D74C627BC0689 +A3F273D9D9D94FF32CC504AADE91D4E17105EBA804952F566F0849A34B4E150223E5ED27 +786FD43209CC4F4EE8F4DB98D2C1DB336AE17E745DD8EB3D95A9984A632475430B0E80AE +49A5118C73F0E060C7AC98A8F03E9E7BCA9492AE7D5CED0AA5F177E5EA1F6FFB5AA43A13 +76C8FAD9344ECD8E6B64EDA15AA52B37DDE5AEF3242C236D2C5B401000EE78D62A889665 +2553636E765463181099C47679428ED39AD2F77F8F35DC07A726666751D8DF804635DB17 +C4A81D61036E8CE9CE5E441226584EC469082C6C765909DCE05DD9C9D932F295EB587B37 +C7C32818BA4126B809ED89CEC7F14494720018DC93BC5F2635B5F1ADECFC9B4D2B028FFE +AC248B2663FCD7A43E5468B43FA11E3BC439A5B519DFCDDE7403AB81F0771A7D85BCDF08 +B2C1DF316723EBCB4FBCEAA61454F48D6A354FCAA92E58757D9CE79F92166468522C00BC +FFD765E0F3BCCE1C41E1717BDAD21746C86310CB9490510FCE6DB36CAD377215650FD82B +9E3FD5E1188EB4D87A216B9B475DF5B634C39C87DD4B89EBF8DD52E7850E680F9CC7E610 +774D1F96C682B067FDC4456954D74B9D1FF2C18CCB9FB0C059517D174974D58D3376C32A +53A2F6C1E6844152C3EB1E954A095D9EFCF72158B0C58A1B55EB29741FFD07F55030A9EC +945C351CEE57273FBD4ECFDA6EB2A4FC374E1763B50648C68678B5FB5CDA2DA8D87EC85F +738F2C2F2DFD4F93E44CD2BC2BB5B8103073EC603487DB06311F97BBFBACF934E3524EC4 +3006CC8A613AD9DDADE1023D0044F0C27F577900A62888C75FCA2B1F7DC59683028FE95F +78039BACCF4E9710D3594B1205B5B08AAB01B04827A82516467C561E80484C2AF83781E0 +F947645951BC5CA167AADE20C8AE192CF9F800C409971D09BD173FE2FB130D8C543F4B57 +D7170BF0146B6138A12D9B04B717CB244E68A023E96E30918A1CBBC4A17EB994398BD47D +CE04656333D38F705EE4ED3A75E569A68409CBD18DF1FD537ABAE8E5D4E67D45FE12CD4B +5ADE49AA221D208F8C0C93FA8D659A01F2B9AC7869AAB3A69C1DC5B48FB8A91039BBA6E8 +3FE9985115B0B304F0E5293FFE5BC54CC84840EF951EAE7E4A1F0D4D1231E0A2F505F54B +9CC2E373991495EED14DCF911DB949E4FA0016D5DD8D1126BE6A149AACD3B51F26347320 +A064FA81697B41AA19D5EBB8500022559BBCFFEA94E6F6F5C8755D9B669418107341FB18 +6855A75AAB2D1FBCCD70DE7120277E9B9D8C9BAE1CED962255F61D28EE29C001D0758578 +0B24E2F7B0CD7EBE33EE42A55A217C5832730B414D5109844A5E9934CA865AD2AE9127C7 +CAC28FE451C17A44C8C79395762EB7747B2DD7780DA0B2145CD2732B2D62724271FE4B5D +96B882BF2C73F1E2BB9D700B83CE16AE2D6AB9726E12B09872EA940C1FADFEF125F89D09 +1FE5580E48ABF5493F9D8CC50CCCE629D6F8ACAF3998943225C5D2D795A1A10E2C1AC6D8 +B057F4A8225F0B24E4D6410F4A38D75D14601250E427EBFDD43AAF5E5C1EE0CCDB6D4504 +E3F854ED2EF4E8BDFA1F7422AB86B17896E6D3D0B14B81C515B489C3BE5B471461D6901D +B39949A0B137BF9AF0C3A8124BB3FB4C1DC43A9ECCC48DB999E5FEB94B60DF942AE440AA +4E69A70EEE8860EE2CE8570ABFA7519AC16AA1991540596881033B01CDB54E4DB401430B +20696CD808C73AEBB6E61A5C41C96D7FC338E6E92A112ABF427C6E0EB23E278B3E5967BE +13998C6786382093F74E2B067D428E9877F44DF94F6FEC76109987F3D7F13CE7C4C24648 +61128BB2C51BC858F4B87C3B3938698B4CE4CEAC0A73D872D5A43269B11B95D85FDB1F49 +545527BB2AA699944776B9A623DF59DB1B3035A6177A713667D78F7457C950D2664BA6DB +1076009612A6806B24AB931A8466BE6EED4BC7776F1AB926213490BDA0F8E65E84B960D2 +625E6FC88744371574FC22DE9CAC8E37D0F0BEDACE16C034A588888EBA681CB89FB9D2E5 +3F04BAE4629739F91C372321D3F2653E4D24439E6B8AAFD71184436B86AA3D9C0B170A54 +728385BF8B6ECCDB25ED1D3363837400E80789F16FC73CD235568FE7F51385693E41555A +F53AB56069EBF4F2B5D0C7859E988DCCAA37F0AD98EB34169D3E9BF7C664BE123640569D +89F1C34BACC3B967853750B3627FD055A2AE8B2BBD6DDC2F6AC54BC7FF5122A540D0D200 +FF8FCF17DFD821E8034BFFEC18E1CD7DF35D4E1D80614347D92743B7CBE2910AD330A5B1 +C1D5DC95379F601A289069159AC6183E283257AB2C97C8BB3D6500B012BC6A9F47B0A57F +2639AAD56552486847B304AD088CB8AEB07D032C4C275029A69563E350F3D64A67A7B88D +561AB9C9DE1FC593DFC448FAD9E42063AF99A70DC8EFDB928FEFF2225FA1DE159DE073E6 +3A55D312B9B1810B375E116D79617D0F348EB2184E8A150E94223C792193E1A096646EE2 +A0D82C33EBB19E422988824963C50BAAA8598B9D51DB4149A366F621852EF0B17B4A41A2 +3436A438D8E65735F6B4D1E2EF89A12E4002AC8E585BC407EE6F34CD2D7046E042C463EE +EBC4971A00B9A5F29102455E787BC66620D627385BAA3812F6B0BCF03AF1728064E1A8B7 +D7F5574C5DC22F5C0472CBD0E351F430823302827B31BF2338D85F80DDCCD3EA5E49B9A8 +8B8BBE6B0132C8198DA4436F609C27D13E7E561F05E783F04630B3EC03272F33E3F08419 +D5B4C16B386DCA42D17E89D7ACF46F6F4A79BBA082700F7F98327F2C7E62D8B1E6BFAF8C +212819FB632C3DCB4AC92A8A0F94F350FB0BE0C89503CD0A52B3AE4817C2CA7193563FE9 +20CC6F4E24C116AB47AF0E3313702E1E96BD9817C1297C30FC7178314E401E4CB3847ACB +1CBB1A672D928C1945E6629F626F66A679E9E39263C3A6804BA6A7D18F0CD0F1E01FEAFA +7786ECD7026C94DD0310F20E8BF525CF5EB072E1EE59E66FDBF54880401F7F66A4C5D019 +297B0EF4C6D3478BFE76B93FACE72F5CDEFFABEBD78DD06E377787E873CB76C7F5130748 +E42599B216AF2254DDFC5AA8146EA01E76FFA094DD65EBF264C301F1311A53E86082E20A +9B5E98CADFA0A10BE2A96CA3D0A33104911C1EF4CAE7E4E7CE3F6A765952D3E72E914DEB +FC50474634A05EC92FA59914A798E42044484FB6F7E3E5D1AF45828422B971D5E7B91601 +848A2624DC276C47F14441338E47FF6F1741A38939A8B75ADC8702F0553ACD787BD49F4C +D4D2CA40759C000A619BE27C2923D72438EB49D684DBBE48DBC67AF1935C9833B9E25252 +1E2869C7E808FC1ACD822659AC94F94FF2E11174FB7A7D199EDE962C61672D9F5D2C93F1 +BC99052FB782D94B08617E3C7BF232D9EDD6FD466A2ED7E55318F6E789E4A09F636B91E9 +6EE41F556224A8108BE1CFB2A83A57BA6C8995B6F7A5BE1D454A18CBF2E71FFC4D23A3B4 +9A202FEFF154CCE053BFABCC83CE4FE091E31B4759761F3D535348EF85AE276108592DCA +9A84E1EA28786F871636712C1B85B412DFE705AC768AC8F5B65BD49CE921CDDB5C4D41DF +BB2A7F14263AD2295F25ACFBF3F621D19437F0DDCB174280EA65836E9DCE638364E04085 +29F239946EB500E4455E7B79A412EB03C72D7D18A1EFC6A5C86AA2987C43E3987A5EF3F4 +F35712C790EB5137ABC92B2DAE1CD4E06E21B0DC03E2503687BA0DB73A4DDDEFB41C3BF5 +199ED14731480556C59F1127993C587517CC2406EFA6529122D90D9A9E4C1400B97B5DA0 +3A17AC4C5E238267969046365CA9ADE8D7C76746091704DF72709098602891ED11EE7AF8 +FD7B26DDE5E9CBD0BAB0E2E8C2B6BD49F2FF4CD016EE88B55F087152E7B2E4F67D081FAB +847050548D26D0FE5365833D2A4791018284552C1F40D9ECE2605A3BE0EE2ED5DECE4D4D +A8D5D81ED6101786D8AF3E5EBEB78FBECD7D3B471FF8C6900E12D0F45671D44DA582421F +9BBD5759CDCC9FEE1991520E8F84BB8ACA4A370237E4C4FF92BE8EE6C307DFC47078E167 +DA4C7B2740B9A429012F4BB8519507F2A18F51BDD82168B9576E29531A5B26CD7B0FD7DB +6E346CAB301B33CEBEE1F3D61D73B7D6145F89985653445FA519F91597A0F984DADE3094 +7109124D39A2A7E6D1CFDAF96A73FA0849075111F1ABC010A6871CC05709441C20CEF9B9 +A9AD1A8B1C207D0FE1E7D9D238D0A65EDAFE0BB3802D68CBF0B4CC151A8B330DD04E07DE +C3329735761D7FDE1ACC1B0E86566891E6AE571EB4936A3BC13A3684A52CAF7B7BD84C73 +C68F436156F5A1F05A1898FEAD0F35CF7778CC824139B47484C71C4EE3625F86D1B12317 +7620B46984D92F7C1D38D392F8981CA76FD1678CFDD43FA5F2A5B5F92FEDFF593F699866 +F063DA7E0AD329FF3C45A2236A3F7A6D420E3A66B2BE1BFBF1CC584BE3B68BA2714DB085 +1B803EB1A075C6B1495099C0A5CC7C51369BE2A79E23D793BCD72A8BD7DEC3E180ABF90D +D5D4137A796716083BBDD2C75EAEE01531EABFBD93F8D442525DD798E799D7EA30AB15BD +9A20FE527E524FD7D6BD01884C12044BD7E81DE8293F50F63201D31838FDC0C7B20EEB93 +2372EA2F80F325EBE41BFC037B9FFB5150E421E2E785B5DDB910C3569DCE72A9441AA858 +D0325B3BF2FB3FE83A3D558A63AED58F48C5ACD609D5E1B048A6B519E061E601F4387F03 +7049B8CD97F402EED07DF88A9FB133E9DE42A205727495050C9C6B9D346E0B159C704A3B +99F4F4A11A7B530F48BA5EFE0C6141F6F973C844BD43119D3AF52E22D2C6B615E53FB90B +E1683719BC94124D51559326EDCFE600F75B0427CCE88D215A5B57F6DC59F504F2A7AC5B +2B90F94AD673C8872A03DCDEB8712634E1BA3CB2E227ED6535160B62FABBC22B7FBA8174 +70E62F61792B40AAA5454010B2B008FB1DB7C11038CB98C8CD5401C95DB173A4AFD3CC0F +7E5F19B6DFDC8BDF118786ECE351307B0E4C30233C0177781085FA1B2C5D1EF51BF9490B +B6D1CD1C18F0782098F9E484F9420D635C79D6AC0740B7AE70BBBFEAF8B8958BD921D2A9 +798546BDD7858F810FEB5D84CF411AA3827A50420FE741BC3812CDE1865F4A2EF6A25A4C +ED7EB24CCD38095AFE425D3B0A90539A1CD93DE3F35B020D047EFCE7E1C5C18633B419A2 +1167ACFD3CC3EE0629C0717AE994F151BEFF9EF0AF6E0F14358FBFBA8B61D669ADA8C47C +AA03859AD7E8C07FC39514A8A85E5C5D02B5DDB48725BC15B70AB80FF7F563D481106810 +D8DF1EE07EAF9DB56374124F654CCB454E3C7B0BB490E0D9CB50460E1857C32C95021954 +35C010736A65A00FC28A348ECD4B494F5FEF4D236FBCB951535C546F248F0BAA11F372DD +67F838667C2657A7ABC4631530F275D7A5ED73DEC263A1749630C251ED3F5B9708876730 +0ED8DBD0F588D874267EE87E8486B700B58DE87DA46980B752B5EAA853699AE65D50A6D5 +1A41D217244B8BC5C39D98272731E8D605EEABE0E6E487BC89F5962D2423DAF0C580D424 +719EBA7E9FC3C8C49AA2ED9BF1B679C51EC07D7C4F4401DA63B66AF7061BAE89C443718E +EEA6FBD03E21DDAD5A1B2C251FF101AADE3FF3243F71CA14F19F71E3CB8689BE24E506C3 +C2E9BF2ADC82BFDBAD0C07082B75EAE1ECD31A8B90B9A582FEC64B65A8DF81E54B867EEB +E71C191443897E25FAC6EDE419F11912D284F8819AF00617BB03330055E5C49023BD472E +B32FE903E2C3A3BD9452389DA13CB1E4662ABFE88ABCA6DF0E55878CADFE425B8BF42313 +9107696719E947249B70C02251E24CBB3F3E027245651181113F3C2DDA0FF61B1243B6C4 +CDB870D3E05B7DA867C1853A6F8E53CDDD654831048A6F58EEDE299A70E0C18C02600DA3 +7D1507535286BD1C167BF37F925C8468967709EDBF94DFE0BFCFF11F0B715C77BF1FF7D7 +0BD8258DBDEE61ED4785F85DF2C52157FEC3C01282226FCC96E0ED8CDC8874A209E54A9C +0E8EDA0887E0561CE0B3ECBAB1019F39132E6DA0FE6761379C4424EFC66C36EB4AD7D125 +B88A0A7C19ABABD4A60FBDF0CC1414A77837EB57609D6E4C5DA8A37D18B05B4F755776FC +1930C15DFA2B545D8DCC65B7C8C4A3B9A8DBFC8C64CF90C1047828084070516FF3897E5C +CD223CA4E5DE09834C960D0483F48156CB48B73EB3387A01208AC9991949027675AB9AAF +B3D1AE8791DDA72EEA9053C50218F89B65935D6E40979F583456658C00C593034A067B3F +5B9F7177E6032F1F6BC96AD544F8B98472724D7F48C91D08B4CE91B5EE736A22996CD971 +34E2D4221E0891CA4C8708A6059DB1C48350106A304F7000A1D165D44CCD6F6EE7EA5434 +4F5506C13BA5D12A04548D75D266E0A027DE905EB4DF15ECA1CDFA1D4EE0B9D650AFF4A6 +3ED6A0AD78D63938669B505CD5B799DDB4A3BAD89CAB921F18D26DC9B581B0E28EA395A2 +349B5909107EE11E9CC364961A335C913A34094E63C9163E45A5FF43D3B58E5101E8E2F0 +AFCE604BC96F676F942301846A6F3C54AF5A4D60F37B7A4C3BE982FDEE76F0B8 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +{restore}if diff --git a/init/cups-lpd.in b/init/cups-lpd.in new file mode 100644 index 0000000000..05fbba754e --- /dev/null +++ b/init/cups-lpd.in @@ -0,0 +1,12 @@ +service printer +{ + disable = yes + socket_type = stream + protocol = tcp + wait = no + user = @CUPS_USER@ + group = @CUPS_GROUP@ + passenv = + server = @CUPS_SERVERBIN@/daemon/cups-lpd + server_args = -o document-format=application/octet-stream +} diff --git a/init/cups.sh.in b/init/cups.sh.in new file mode 100755 index 0000000000..1922453c97 --- /dev/null +++ b/init/cups.sh.in @@ -0,0 +1,234 @@ +#!/bin/sh +# +# "$Id$" +# +# Startup/shutdown script for the Common UNIX Printing System (CUPS). +# +# Copyright 2007 by Apple Inc. +# Copyright 1997-2007 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "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 + +# +# Don't use TMPDIR environment variable from init script, as that can +# cause cupsd to set TempDir to a user's temporary directory instead +# of the default... +# + +unset TMPDIR + + +# +# Make sure we have the standard program directories in the path +# since some operating systems (this means YOU HP-UX!) don't +# provide a standard path on boot-up... +# + +if test "x$PATH" = x; then + PATH="/bin:/usr/bin:/sbin:/usr/sbin" +else + PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH" +fi + +export PATH + +# +# 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 + ;; + + start_msg) + # HP-UX non-standard... + echo "Starting CUPS Server" + ;; + + stop_msg) + # HP-UX non-standard... + echo "Starting CUPS Server" + ;; + + *) + echo "Usage: cups {reload|restart|start|status|stop}" + exit 1 + ;; +esac + +# +# Exit with no errors. +# + +exit 0 + + +# +# End of "$Id$". +# diff --git a/init/cups.xml.in b/init/cups.xml.in new file mode 100644 index 0000000000..211c086b7f --- /dev/null +++ b/init/cups.xml.in @@ -0,0 +1,214 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/init/org.cups.cups-lpd.plist.in b/init/org.cups.cups-lpd.plist.in new file mode 100644 index 0000000000..e1451207b3 --- /dev/null +++ b/init/org.cups.cups-lpd.plist.in @@ -0,0 +1,35 @@ + + + + + Disabled + + Label + org.cups.cups-lpd + ProgramArguments + + /usr/libexec/cups/daemon/cups-lpd + -o + document-format=application/octet-stream + + SHAuthorizationRight + system.preferences + Sockets + + Listeners + + SockServiceName + printer + SockType + stream + + + UserName + @CUPS_USER@ + inetdCompatibility + + Wait + + + + diff --git a/init/org.cups.cupsd.plist b/init/org.cups.cupsd.plist new file mode 100644 index 0000000000..2b9a7df9d5 --- /dev/null +++ b/init/org.cups.cupsd.plist @@ -0,0 +1,53 @@ + + + + + Label + org.cups.cupsd + EnableTransactions + + ExitTimeOut + 60 + KeepAlive + + PathState + + /private/var/spool/cups/cache/org.cups.cupsd + + + + ProgramArguments + + /usr/sbin/cupsd + -l + + ServiceIPC + + SHAuthorizationRight + system.preferences + Sockets + + Listeners + + + SockNodeName + ::1 + SockServiceName + ipp + + + SockNodeName + 127.0.0.1 + SockServiceName + ipp + + + SockPathMode + 49663 + SockPathName + /private/var/run/cupsd + + + + + diff --git a/install-sh b/install-sh new file mode 100755 index 0000000000..05fe96fe44 --- /dev/null +++ b/install-sh @@ -0,0 +1,222 @@ +#!/bin/sh +# +# "$Id: install-sh 8688 2009-05-27 16:42:40Z mike $" +# +# Install a program, script, or datafile. +# +# Copyright 2008-2009 by Apple Inc. +# +# This script is not compatible with BSD (or any other) install program, as it +# allows owner and group changes to fail with a warning and makes sure that the +# destination directory permissions are as specified - BSD install and the +# original X11 install script did not change permissions of existing +# directories. It also does not support the transform options since CUPS does +# not use them... +# +# Original script 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. + +# set DOITPROG to echo to test this script +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# Force umask to 022... +umask 022 + +# 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 + ;; + + *) + if [ x"$src" = x ]; then + src="$1" + else + dst="$1" + fi + shift + continue + ;; + esac +done + +if [ x"$src" = x ]; then + echo "install-sh: No input file specified" + exit 1 +fi + +if [ x"$dir_arg" != x ]; then + dst="$src" + src="" + + if [ -d "$dst" ]; then + instcmd=: + 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" -a ! -d "$src" ]; then + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ]; then + echo "install: No destination specified" + exit 1 + fi + + # If destination is a directory, append the input filename. + if [ -d "$dst" ]; then + dst="$dst/`basename $src`" + 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 $doit $mkdirprog "${pathcomp}"; fi + + pathcomp="${pathcomp}/" + done +fi + +if [ x"$dir_arg" != x ]; then + # Make a directory... + $doit $instcmd $dst || exit 1 + + # Allow chown/chgrp to fail, but log a warning + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst || echo "warning: Unable to change owner of $dst!"; fi + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst || echo "warning: Unable to change group of $dst!"; fi + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst || exit 1; fi +else + # Install a file... + dstfile="`basename $dst`" + + # Check the destination file - for libraries just use the "-x" option + # to strip... + case "$dstfile" in + *.a | *.dylib | *.sl | *.sl.* | *.so | *.so.*) + stripopt="-x" + ;; + *) + stripopt="" + ;; + esac + + # 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 || exit 1 + + # Update permissions and strip as needed, then move to the final name. + # If the chmod, strip, rm, or mv commands fail, remove the installed + # file... + if [ x"$stripcmd" != x ]; then $doit $stripcmd $stripopt "$dsttmp" || echo "warning: Unable to strip $dst!"; fi + if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp" || echo "warning: Unable to change owner of $dst!"; fi + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp" || echo "warning: Unable to change group of $dst!"; fi + + trap "rm -f ${dsttmp}" 0 && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; fi && + $doit $rmcmd -f "$dstdir/$dstfile" && + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" +fi + +exit 0 diff --git a/locale/Dependencies b/locale/Dependencies new file mode 100644 index 0000000000..79f710893c --- /dev/null +++ b/locale/Dependencies @@ -0,0 +1,10 @@ +# DO NOT DELETE THIS LINE -- make depend depends on it. + +checkpo.o: ../cups/string.h ../config.h ../cups/i18n.h ../cups/transcode.h +checkpo.o: ../cups/language.h ../cups/array.h ../cups/versioning.h +po2strings.o: ../cups/i18n.h ../cups/transcode.h ../cups/language.h +po2strings.o: ../cups/array.h ../cups/versioning.h ../cups/string.h +po2strings.o: ../config.h +translate.o: ../cups/string.h ../config.h ../cups/file.h ../cups/versioning.h +translate.o: ../cups/http.h ../cups/i18n.h ../cups/transcode.h +translate.o: ../cups/language.h ../cups/array.h diff --git a/locale/Makefile b/locale/Makefile new file mode 100644 index 0000000000..83ab1eac5a --- /dev/null +++ b/locale/Makefile @@ -0,0 +1,205 @@ +# +# "$Id$" +# +# Locale file makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1993-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + + +OBJS = checkpo.o po2strings.o strings2po.o translate.o +TARGETS = checkpo po2strings strings2po translate + + +# +# Make everything... +# + +all: $(TARGETS) + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + $(RM) $(TARGETS) $(OBJS) + + +# +# Update dependencies (without system header dependencies...) +# + +depend: + makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1 + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: $(INSTALL_LANGUAGES) + +install-languages: + $(INSTALL_DIR) -m 755 $(LOCALEDIR) + for loc in $(LANGUAGES) ; do \ + if test -f cups_$$loc.po; then \ + $(INSTALL_DIR) -m 755 $(LOCALEDIR)/$$loc ; \ + $(INSTALL_DATA) cups_$$loc.po $(LOCALEDIR)/$$loc/cups_$$loc.po ; \ + fi ; \ + done + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: $(UNINSTALL_LANGUAGES) + +uninstall-languages: + -for loc in $(LANGUAGES) ; do \ + $(RM) $(LOCALEDIR)/$$loc/cups_$$loc.po ; \ + done + + +# +# pot - Creates/updates the cups.pot template file, and merges changes +# into existing message catalogs. +# + +pot: + echo Updating cups.pot... + mv cups.pot cups.pot.bck + touch cups.pot + cd ..; xgettext -o locale/cups.pot -j -s --keyword=_ --no-wrap \ + --copyright-holder="Apple Inc." \ + --msgid-bugs-address="http://www.cups.org/str.php" \ + */*.c */*.cxx + (cat cups.header; \ + cat cups.pot | sed -e '1,6d' -e '1,$$s/PACKAGE VERSION/CUPS 1.4/' \ + -e '1,$$s/charset=CHARSET/charset=utf-8/'; \ + cat cups.footer) > cups.pot.N + mv cups.pot.N cups.pot + for loc in $(LANGUAGES) ; do \ + echo Merging changes into cups_$$loc.po... ; \ + msgmerge -o cups_$$loc.po -s -N --no-location cups_$$loc.po cups.pot ; \ + done + + +# +# checkpo - A simple utility to check PO files for correct translation +# strings. Dependency on static library is deliberate. +# +# checkpo filename.po [... filenameN.po] +# + +checkpo: checkpo.o ../cups/libcups.a + echo Linking $<... + $(CC) $(LDFLAGS) -o checkpo checkpo.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + +checkall: checkpo + for file in *.po; do \ + ./checkpo $$file; \ + done + + +# +# po2strings - A simple utility which uses iconv to convert GNU gettext +# message catalogs to Mac OS X .strings files. +# +# po2strings filename.po filename.strings +# + +po2strings: po2strings.o ../cups/libcups.a + echo Linking $<... + $(CC) $(LDFLAGS) -o po2strings po2strings.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# strings2po - A simple utility which uses iconv to convert Mac OS X +# .strings files to GNU gettext message catalogs. +# +# strings2po filename.strings filename.po +# + +strings2po: strings2po.o + echo Linking $<... + $(CC) $(LDFLAGS) -o strings2po strings2po.o + + +# +# translate - A simple utility which uses Google to translate the cups.pot +# file to one of several languages. +# +# translate outfile language +# + +translate: translate.o ../cups/libcups.a + echo Linking $<... + $(CC) $(LDFLAGS) -o translate translate.o ../cups/libcups.a \ + $(LIBGSSAPI) $(SSLLIBS) $(DNSSDLIBS) $(COMMONLIBS) $(LIBZ) + + +# +# Dependencies... +# + +include Dependencies + + +# +# End of "$Id$". +# diff --git a/locale/checkpo.c b/locale/checkpo.c new file mode 100644 index 0000000000..97cc987bbe --- /dev/null +++ b/locale/checkpo.c @@ -0,0 +1,376 @@ +/* + * "$Id$" + * + * Verify that translations in the .po file have the same number and type of + * printf-style format strings. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Usage: + * + * checkpo filename.po [... filenameN.po] + * + * Compile with: + * + * gcc -o checkpo checkpo.c `cups-config --libs` + * + * Contents: + * + * main() - Validate .po files. + * abbreviate() - Abbreviate a message string as needed. + * collect_formats() - Collect all of the format strings in the msgid. + * free_formats() - Free all of the format strings. + */ + +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static char *abbreviate(const char *s, char *buf, int bufsize); +static cups_array_t *collect_formats(const char *id); +static void free_formats(cups_array_t *fmts); + + +/* + * 'main()' - Validate .po files. + */ + +int /* O - Exit code */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + cups_array_t *po; /* .po file */ + _cups_message_t *msg; /* Current message */ + cups_array_t *idfmts, /* Format strings in msgid */ + *strfmts; /* Format strings in msgstr */ + char *idfmt, /* Current msgid format string */ + *strfmt; /* Current msgstr format string */ + int fmtidx; /* Format index */ + int status, /* Exit status */ + pass, /* Pass/fail status */ + untranslated; /* Untranslated messages */ + char idbuf[80], /* Abbreviated msgid */ + strbuf[80]; /* Abbreviated msgstr */ + + + if (argc < 2) + { + puts("Usage: checkpo filename.po [... filenameN.po]"); + return (1); + } + + /* + * Check every .po file on the command-line... + */ + + for (i = 1, status = 0; i < argc; i ++) + { + /* + * Use the CUPS .po loader to get the message strings... + */ + + if ((po = _cupsMessageLoad(argv[i], 0)) == NULL) + { + perror(argv[i]); + return (1); + } + + printf("%s: ", argv[i]); + fflush(stdout); + + /* + * Scan every message for a % string and then match them up with + * the corresponding string in the translation... + */ + + pass = 1; + untranslated = 0; + + for (msg = (_cups_message_t *)cupsArrayFirst(po); + msg; + msg = (_cups_message_t *)cupsArrayNext(po)) + { + if (!msg->str || !msg->str[0]) + { + untranslated ++; + continue; + } + else if (strchr(msg->id, '%')) + { + idfmts = collect_formats(msg->id); + strfmts = collect_formats(msg->str); + fmtidx = 0; + + for (strfmt = (char *)cupsArrayFirst(strfmts); + strfmt; + strfmt = (char *)cupsArrayNext(strfmts)) + { + if (isdigit(strfmt[1] & 255) && strfmt[2] == '$') + { + /* + * Handle positioned format stuff... + */ + + fmtidx = strfmt[1] - '1'; + strfmt += 3; + if ((idfmt = (char *)cupsArrayIndex(idfmts, fmtidx)) != NULL) + idfmt ++; + } + else + { + /* + * Compare against the current format... + */ + + idfmt = (char *)cupsArrayIndex(idfmts, fmtidx); + } + + fmtidx ++; + + if (!idfmt || strcmp(strfmt, idfmt)) + break; + } + + if (cupsArrayCount(strfmts) != cupsArrayCount(idfmts) || strfmt) + { + if (pass) + { + pass = 0; + puts("FAIL"); + } + + printf(" Bad translation string \"%s\"\n for \"%s\"\n", + abbreviate(msg->str, strbuf, sizeof(strbuf)), + abbreviate(msg->id, idbuf, sizeof(idbuf))); + fputs(" Translation formats:", stdout); + for (strfmt = (char *)cupsArrayFirst(strfmts); + strfmt; + strfmt = (char *)cupsArrayNext(strfmts)) + printf(" %s", strfmt); + fputs("\n Original formats:", stdout); + for (idfmt = (char *)cupsArrayFirst(idfmts); + idfmt; + idfmt = (char *)cupsArrayNext(idfmts)) + printf(" %s", idfmt); + putchar('\n'); + putchar('\n'); + } + + free_formats(idfmts); + free_formats(strfmts); + } + + /* + * Only allow \\, \n, \r, \t, \", and \### character escapes... + */ + + for (strfmt = msg->str; *strfmt; strfmt ++) + if (*strfmt == '\\' && + strfmt[1] != '\\' && strfmt[1] != 'n' && strfmt[1] != 'r' && + strfmt[1] != 't' && strfmt[1] != '\"' && !isdigit(strfmt[1] & 255)) + { + if (pass) + { + pass = 0; + puts("FAIL"); + } + + printf(" Bad escape \\%c in filter message \"%s\"\n" + " for \"%s\"\n\n", strfmt[1], + abbreviate(msg->str, strbuf, sizeof(strbuf)), + abbreviate(msg->id, idbuf, sizeof(idbuf))); + break; + } + + /* + * Make sure filter message prefixes are preserved... + */ + + if ((!strncmp(msg->id, "ALERT:", 6) && strncmp(msg->str, "ALERT:", 6)) || + (!strncmp(msg->id, "CRIT:", 5) && strncmp(msg->str, "CRIT:", 5)) || + (!strncmp(msg->id, "DEBUG:", 6) && strncmp(msg->str, "DEBUG:", 6)) || + (!strncmp(msg->id, "DEBUG2:", 7) && strncmp(msg->str, "DEBUG2:", 7)) || + (!strncmp(msg->id, "EMERG:", 6) && strncmp(msg->str, "EMERG:", 6)) || + (!strncmp(msg->id, "ERROR:", 6) && strncmp(msg->str, "ERROR:", 6)) || + (!strncmp(msg->id, "INFO:", 5) && strncmp(msg->str, "INFO:", 5)) || + (!strncmp(msg->id, "NOTICE:", 7) && strncmp(msg->str, "NOTICE:", 7)) || + (!strncmp(msg->id, "WARNING:", 8) && strncmp(msg->str, "WARNING:", 8))) + { + if (pass) + { + pass = 0; + puts("FAIL"); + } + + printf(" Bad prefix on filter message \"%s\"\n for \"%s\"\n\n", + abbreviate(msg->str, strbuf, sizeof(strbuf)), + abbreviate(msg->id, idbuf, sizeof(idbuf))); + } + } + + if (pass) + { + if ((untranslated * 10) >= cupsArrayCount(po)) + { + /* + * Only allow 10% of messages to be untranslated before we fail... + */ + + pass = 0; + puts("FAIL"); + printf(" Too many untranslated messages (%d of %d)\n\n", + untranslated, cupsArrayCount(po)); + } + else if (untranslated > 0) + printf("PASS (%d of %d untranslated)\n\n", untranslated, + cupsArrayCount(po)); + else + puts("PASS\n"); + } + + if (!pass) + status = 1; + + _cupsMessageFree(po); + } + + return (status); +} + + +/* + * 'abbreviate()' - Abbreviate a message string as needed. + */ + +static char * /* O - Abbreviated string */ +abbreviate(const char *s, /* I - String to abbreviate */ + char *buf, /* I - Buffer */ + int bufsize) /* I - Size of buffer */ +{ + char *bufptr; /* Pointer into buffer */ + + + for (bufptr = buf, bufsize -= 4; *s && bufsize > 0; s ++) + { + if (*s == '\n') + { + if (bufsize < 2) + break; + + *bufptr++ = '\\'; + *bufptr++ = 'n'; + bufsize -= 2; + } + else if (*s == '\t') + { + if (bufsize < 2) + break; + + *bufptr++ = '\\'; + *bufptr++ = 't'; + bufsize -= 2; + } + else if (*s >= 0 && *s < ' ') + { + if (bufsize < 4) + break; + + sprintf(bufptr, "\\%03o", *s); + bufptr += 4; + bufsize -= 4; + } + else + { + *bufptr++ = *s; + bufsize --; + } + } + + if (*s) + strcpy(bufptr, "..."); + else + *bufptr = '\0'; + + return (buf); +} + + +/* + * 'collect_formats()' - Collect all of the format strings in the msgid. + */ + +static cups_array_t * /* O - Array of format strings */ +collect_formats(const char *id) /* I - msgid string */ +{ + cups_array_t *fmts; /* Array of format strings */ + char buf[255], /* Format string buffer */ + *bufptr; /* Pointer into format string */ + + + fmts = cupsArrayNew(NULL, NULL); + + while ((id = strchr(id, '%')) != NULL) + { + if (id[1] == '%') + { + /* + * Skip %%... + */ + + id += 2; + continue; + } + + for (bufptr = buf; *id && bufptr < (buf + sizeof(buf) - 1); id ++) + { + *bufptr++ = *id; + + if (strchr("CDEFGIOSUXcdeifgopsux", *id)) + { + id ++; + break; + } + } + + *bufptr = '\0'; + cupsArrayAdd(fmts, strdup(buf)); + } + + return (fmts); +} + + +/* + * 'free_formats()' - Free all of the format strings. + */ + +static void +free_formats(cups_array_t *fmts) /* I - Array of format strings */ +{ + char *s; /* Current string */ + + + for (s = (char *)cupsArrayFirst(fmts); s; s = (char *)cupsArrayNext(fmts)) + free(s); + + cupsArrayDelete(fmts); +} + + +/* + * End of "$Id$". + */ diff --git a/locale/cups.footer b/locale/cups.footer new file mode 100644 index 0000000000..490c9d4ebd --- /dev/null +++ b/locale/cups.footer @@ -0,0 +1,5 @@ + + +# +# End of "$Id$". +# diff --git a/locale/cups.header b/locale/cups.header new file mode 100644 index 0000000000..e4d0e2b5d7 --- /dev/null +++ b/locale/cups.header @@ -0,0 +1,30 @@ +# +# "$Id$" +# +# Message catalog template for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 2005-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Notes for Translators: +# +# The following prefixes MUST NOT be translated: "ALERT:", "CRIT:", "INFO:", +# "NOTICE:", and "WARNING:". +# +# The "checkpo" program located in the "locale" source directory can be used +# to verify that your translations do not introduce formatting errors or other +# problems. Run with: +# +# cd locale +# ./checkpo cups_LL.po +# +# where "LL" is your locale. +# diff --git a/locale/cups.pot b/locale/cups.pot new file mode 100644 index 0000000000..5a65cde80f --- /dev/null +++ b/locale/cups.pot @@ -0,0 +1,6730 @@ +# +# "$Id$" +# +# Message catalog template for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 2005-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Notes for Translators: +# +# The following prefixes MUST NOT be translated: "ALERT:", "CRIT:", "INFO:", +# "NOTICE:", and "WARNING:". +# +# The "checkpo" program located in the "locale" source directory can be used +# to verify that your translations do not introduce formatting errors or other +# problems. Run with: +# +# cd locale +# ./checkpo cups_LL.po +# +# where "LL" is your locale. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: systemv/lpstat.c:1848 systemv/lpstat.c:1961 +msgid "\t\t(all)\n" +msgstr "" + +#: systemv/lpstat.c:1851 systemv/lpstat.c:1854 systemv/lpstat.c:1964 +#: systemv/lpstat.c:1967 +msgid "\t\t(none)\n" +msgstr "" + +#: berkeley/lpc.c:438 +#, c-format +msgid "\t%d entries\n" +msgstr "" + +#: systemv/lpstat.c:1829 systemv/lpstat.c:1942 +msgid "\tAfter fault: continue\n" +msgstr "" + +#: systemv/lpstat.c:1461 systemv/lpstat.c:1795 systemv/lpstat.c:1908 +msgid "\tAlerts:" +msgstr "" + +#: systemv/lpstat.c:1852 systemv/lpstat.c:1965 +msgid "\tBanner required\n" +msgstr "" + +#: systemv/lpstat.c:1853 systemv/lpstat.c:1966 +msgid "\tCharset sets:\n" +msgstr "" + +#: systemv/lpstat.c:1818 systemv/lpstat.c:1931 +msgid "\tConnection: direct\n" +msgstr "" + +#: systemv/lpstat.c:1809 systemv/lpstat.c:1922 +msgid "\tConnection: remote\n" +msgstr "" + +#: systemv/lpstat.c:1856 systemv/lpstat.c:1969 +msgid "\tDefault page size:\n" +msgstr "" + +#: systemv/lpstat.c:1855 systemv/lpstat.c:1968 +msgid "\tDefault pitch:\n" +msgstr "" + +#: systemv/lpstat.c:1857 systemv/lpstat.c:1970 +msgid "\tDefault port settings:\n" +msgstr "" + +#: systemv/lpstat.c:1790 systemv/lpstat.c:1903 +#, c-format +msgid "\tDescription: %s\n" +msgstr "" + +#: systemv/lpstat.c:1784 systemv/lpstat.c:1897 +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" + +#: systemv/lpstat.c:1850 systemv/lpstat.c:1963 +msgid "\tForms allowed:\n" +msgstr "" + +#: systemv/lpstat.c:1813 systemv/lpstat.c:1926 +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "" + +#: systemv/lpstat.c:1822 systemv/lpstat.c:1935 +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "" + +#: systemv/lpstat.c:1826 systemv/lpstat.c:1939 +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "" + +#: systemv/lpstat.c:1804 systemv/lpstat.c:1917 +#, c-format +msgid "\tLocation: %s\n" +msgstr "" + +#: systemv/lpstat.c:1828 systemv/lpstat.c:1941 +msgid "\tOn fault: no alert\n" +msgstr "" + +#: systemv/lpstat.c:1833 systemv/lpstat.c:1847 systemv/lpstat.c:1946 +#: systemv/lpstat.c:1960 +msgid "\tUsers allowed:\n" +msgstr "" + +#: systemv/lpstat.c:1840 systemv/lpstat.c:1953 +msgid "\tUsers denied:\n" +msgstr "" + +#: berkeley/lpc.c:440 +msgid "\tdaemon present\n" +msgstr "" + +#: berkeley/lpc.c:436 +msgid "\tno entries\n" +msgstr "" + +#: berkeley/lpc.c:408 berkeley/lpc.c:420 +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "" + +#: berkeley/lpc.c:433 +msgid "\tprinting is disabled\n" +msgstr "" + +#: berkeley/lpc.c:431 +msgid "\tprinting is enabled\n" +msgstr "" + +#: systemv/lpstat.c:1467 +#, c-format +msgid "\tqueued for %s\n" +msgstr "" + +#: berkeley/lpc.c:428 +msgid "\tqueuing is disabled\n" +msgstr "" + +#: berkeley/lpc.c:426 +msgid "\tqueuing is enabled\n" +msgstr "" + +#: systemv/lpstat.c:1777 systemv/lpstat.c:1890 +msgid "\treason unknown\n" +msgstr "" + +#: systemv/cupstestppd.c:551 +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" + +#: systemv/cupstestppd.c:512 systemv/cupstestppd.c:516 +msgid " REF: Page 15, section 3.1.\n" +msgstr "" + +#: systemv/cupstestppd.c:508 +msgid " REF: Page 15, section 3.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:524 +msgid " REF: Page 19, section 3.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:486 +msgid " REF: Page 20, section 3.4.\n" +msgstr "" + +#: systemv/cupstestppd.c:528 +msgid " REF: Page 27, section 3.5.\n" +msgstr "" + +#: systemv/cupstestppd.c:482 +msgid " REF: Page 42, section 5.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:520 +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:496 +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:491 +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:500 +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:504 +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr "" + +#: berkeley/lpq.c:546 +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr "" + +#: systemv/cupstestppd.c:668 +#, c-format +msgid " PASS Default%s\n" +msgstr "" + +#: systemv/cupstestppd.c:605 +msgid " PASS DefaultImageableArea\n" +msgstr "" + +#: systemv/cupstestppd.c:639 +msgid " PASS DefaultPaperDimension\n" +msgstr "" + +#: systemv/cupstestppd.c:710 +msgid " PASS FileVersion\n" +msgstr "" + +#: systemv/cupstestppd.c:754 +msgid " PASS FormatVersion\n" +msgstr "" + +#: systemv/cupstestppd.c:774 +msgid " PASS LanguageEncoding\n" +msgstr "" + +#: systemv/cupstestppd.c:794 +msgid " PASS LanguageVersion\n" +msgstr "" + +#: systemv/cupstestppd.c:846 +msgid " PASS Manufacturer\n" +msgstr "" + +#: systemv/cupstestppd.c:886 +msgid " PASS ModelName\n" +msgstr "" + +#: systemv/cupstestppd.c:906 +msgid " PASS NickName\n" +msgstr "" + +#: systemv/cupstestppd.c:966 +msgid " PASS PCFileName\n" +msgstr "" + +#: systemv/cupstestppd.c:1041 +msgid " PASS PSVersion\n" +msgstr "" + +#: systemv/cupstestppd.c:946 +msgid " PASS PageRegion\n" +msgstr "" + +#: systemv/cupstestppd.c:926 +msgid " PASS PageSize\n" +msgstr "" + +#: systemv/cupstestppd.c:1001 +msgid " PASS Product\n" +msgstr "" + +#: systemv/cupstestppd.c:1076 +msgid " PASS ShortNickName\n" +msgstr "" + +#: systemv/cupstestppd.c:3416 +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" + +#: systemv/cupstestppd.c:1449 +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr "" + +#: systemv/cupstestppd.c:1557 +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:1458 +msgid " WARN Default choices conflicting!\n" +msgstr "" + +#: systemv/cupstestppd.c:1420 +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" + +#: systemv/cupstestppd.c:1819 +msgid " WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" + +#: systemv/cupstestppd.c:1474 +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1801 +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr "" + +#: systemv/cupstestppd.c:1482 +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1824 +msgid " WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n" +msgstr "" + +#: systemv/cupstestppd.c:1466 +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:1495 +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1529 +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" + +#: systemv/cupstestppd.c:1520 +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" + +#: systemv/cupstestppd.c:1503 +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:2307 +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr "" + +#: systemv/cupstestppd.c:3571 +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#: systemv/cupstestppd.c:2377 +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" + +#: systemv/cupstestppd.c:3131 +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:3177 systemv/cupstestppd.c:3226 +#: systemv/cupstestppd.c:3265 +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2429 +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:2794 +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2500 +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:1897 +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:3081 +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:2484 systemv/cupstestppd.c:2556 +#: systemv/cupstestppd.c:2594 systemv/cupstestppd.c:2632 +#: systemv/cupstestppd.c:2670 systemv/cupstestppd.c:2708 +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2738 +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#: systemv/cupstestppd.c:1878 +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:3117 +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:3209 systemv/cupstestppd.c:3249 +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2569 +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:2607 +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:2645 +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:2683 +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:2721 +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:2926 +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#: systemv/cupstestppd.c:2911 +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#: systemv/cupstestppd.c:2088 systemv/cupstestppd.c:2129 +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:1983 +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:2458 +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:2828 +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:2529 +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr "" + +#: systemv/cupstestppd.c:1915 +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2074 systemv/cupstestppd.c:2115 +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:1967 +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" + +#: systemv/cupstestppd.c:3303 +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr "" + +#: systemv/cupstestppd.c:2989 +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#: systemv/cupstestppd.c:2353 +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" + +#: systemv/cupstestppd.c:3006 systemv/cupstestppd.c:3020 +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2964 +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#: systemv/cupstestppd.c:2856 +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2038 +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr "" + +#: systemv/cupstestppd.c:2020 +#, c-format +msgid " %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#: systemv/cupstestppd.c:2238 +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" + +#: systemv/cupstestppd.c:1243 +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" + +#: systemv/cupstestppd.c:659 +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" + +#: systemv/cupstestppd.c:595 +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" + +#: systemv/cupstestppd.c:631 +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" + +#: systemv/cupstestppd.c:1102 +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" + +#: systemv/cupstestppd.c:822 +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" + +#: systemv/cupstestppd.c:838 +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" + +#: systemv/cupstestppd.c:877 +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1033 +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:994 +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1068 +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1224 +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" + +#: systemv/cupstestppd.c:702 +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:746 +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1288 +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" + +#: systemv/cupstestppd.c:1302 +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" + +#: systemv/cupstestppd.c:3443 systemv/cupstestppd.c:3465 +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" + +#: systemv/cupstestppd.c:1361 +#, c-format +msgid " **FAIL** Default translation string for option %s choice %s contains 8-bit characters!\n" +msgstr "" + +#: systemv/cupstestppd.c:1334 +#, c-format +msgid " **FAIL** Default translation string for option %s contains 8-bit characters!\n" +msgstr "" + +#: systemv/cupstestppd.c:2176 +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" + +#: systemv/cupstestppd.c:2221 +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2198 +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" + +#: systemv/cupstestppd.c:679 +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" + +#: systemv/cupstestppd.c:580 +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" + +#: systemv/cupstestppd.c:616 +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" + +#: systemv/cupstestppd.c:720 +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:764 +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1153 +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" + +#: systemv/cupstestppd.c:784 +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:804 +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:856 +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:896 +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:916 +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:976 +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1051 +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:956 +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#: systemv/cupstestppd.c:1122 +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#: systemv/cupstestppd.c:936 +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" + +#: systemv/cupstestppd.c:1175 +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" + +#: systemv/cupstestppd.c:1011 +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1086 +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" + +#: systemv/cupstestppd.c:1569 +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr "" + +#: systemv/cupstestdsc.c:238 systemv/cupstestdsc.c:280 +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" + +#: systemv/cupstestdsc.c:309 +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" + +#: systemv/cupstestdsc.c:222 systemv/cupstestdsc.c:262 +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" + +#: systemv/cupstestdsc.c:180 +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" + +#: systemv/cupstestdsc.c:196 +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" + +#: systemv/cupstestdsc.c:366 +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" + +#: systemv/cupstestdsc.c:346 +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" + +#: systemv/cupstestdsc.c:376 +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" + +#: systemv/cupstestdsc.c:356 +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" + +#: systemv/cupstestppd.c:1571 +msgid " NO ERRORS FOUND\n" +msgstr "" + +#: systemv/cupstestdsc.c:399 +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr "" + +#: systemv/cupstestdsc.c:394 +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr "" + +#: systemv/cupstestdsc.c:386 +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr "" + +#: systemv/cupstestdsc.c:406 +msgid " Warning: file contains binary data!\n" +msgstr "" + +#: systemv/cupstestdsc.c:414 +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr "" + +#: systemv/cupstestdsc.c:410 +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr "" + +#: systemv/cupstestppd.c:577 systemv/cupstestppd.c:592 +#: systemv/cupstestppd.c:613 systemv/cupstestppd.c:628 +#: systemv/cupstestppd.c:656 systemv/cupstestppd.c:676 +#: systemv/cupstestppd.c:699 systemv/cupstestppd.c:717 +#: systemv/cupstestppd.c:743 systemv/cupstestppd.c:761 +#: systemv/cupstestppd.c:781 systemv/cupstestppd.c:801 +#: systemv/cupstestppd.c:819 systemv/cupstestppd.c:835 +#: systemv/cupstestppd.c:853 systemv/cupstestppd.c:874 +#: systemv/cupstestppd.c:893 systemv/cupstestppd.c:913 +#: systemv/cupstestppd.c:933 systemv/cupstestppd.c:953 +#: systemv/cupstestppd.c:973 systemv/cupstestppd.c:991 +#: systemv/cupstestppd.c:1008 systemv/cupstestppd.c:1030 +#: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1065 +#: systemv/cupstestppd.c:1083 systemv/cupstestppd.c:1099 +#: systemv/cupstestppd.c:1119 systemv/cupstestppd.c:1150 +#: systemv/cupstestppd.c:1172 systemv/cupstestppd.c:1221 +#: systemv/cupstestppd.c:1240 systemv/cupstestppd.c:1284 +#: systemv/cupstestppd.c:1298 systemv/cupstestppd.c:1330 +#: systemv/cupstestppd.c:1357 systemv/cupstestppd.c:1875 +#: systemv/cupstestppd.c:1894 systemv/cupstestppd.c:1912 +#: systemv/cupstestppd.c:1964 systemv/cupstestppd.c:1980 +#: systemv/cupstestppd.c:2017 systemv/cupstestppd.c:2035 +#: systemv/cupstestppd.c:2071 systemv/cupstestppd.c:2085 +#: systemv/cupstestppd.c:2112 systemv/cupstestppd.c:2126 +#: systemv/cupstestppd.c:2172 systemv/cupstestppd.c:2194 +#: systemv/cupstestppd.c:2217 systemv/cupstestppd.c:2234 +#: systemv/cupstestppd.c:2303 systemv/cupstestppd.c:2350 +#: systemv/cupstestppd.c:2374 systemv/cupstestppd.c:2425 +#: systemv/cupstestppd.c:2455 systemv/cupstestppd.c:2480 +#: systemv/cupstestppd.c:2496 systemv/cupstestppd.c:2526 +#: systemv/cupstestppd.c:2552 systemv/cupstestppd.c:2566 +#: systemv/cupstestppd.c:2590 systemv/cupstestppd.c:2604 +#: systemv/cupstestppd.c:2628 systemv/cupstestppd.c:2642 +#: systemv/cupstestppd.c:2666 systemv/cupstestppd.c:2680 +#: systemv/cupstestppd.c:2704 systemv/cupstestppd.c:2718 +#: systemv/cupstestppd.c:2735 systemv/cupstestppd.c:2790 +#: systemv/cupstestppd.c:2825 systemv/cupstestppd.c:2852 +#: systemv/cupstestppd.c:2907 systemv/cupstestppd.c:2922 +#: systemv/cupstestppd.c:2960 systemv/cupstestppd.c:3002 +#: systemv/cupstestppd.c:3016 systemv/cupstestppd.c:3077 +#: systemv/cupstestppd.c:3113 systemv/cupstestppd.c:3127 +#: systemv/cupstestppd.c:3173 systemv/cupstestppd.c:3205 +#: systemv/cupstestppd.c:3222 systemv/cupstestppd.c:3245 +#: systemv/cupstestppd.c:3261 systemv/cupstestppd.c:3299 +#: systemv/cupstestppd.c:3439 systemv/cupstestppd.c:3461 +#: systemv/cupstestppd.c:3567 +msgid " FAIL\n" +msgstr "" + +#: systemv/cupstestppd.c:462 +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" + +#: systemv/cupstestppd.c:473 +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" + +#: systemv/cupstestppd.c:1381 +msgid " PASS\n" +msgstr "" + +#: ppdc/sample.c:51 +msgid "#10 Envelope" +msgstr "" + +#: ppdc/sample.c:52 +msgid "#11 Envelope" +msgstr "" + +#: ppdc/sample.c:53 +msgid "#12 Envelope" +msgstr "" + +#: ppdc/sample.c:54 +msgid "#14 Envelope" +msgstr "" + +#: ppdc/sample.c:55 +msgid "#9 Envelope" +msgstr "" + +#: berkeley/lpq.c:552 +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "" + +#: berkeley/lpq.c:557 +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "" + +#: filter/bannertops.c:784 +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "" + +#: filter/bannertops.c:805 +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "" + +#: filter/bannertops.c:775 +#, c-format +msgid "%.2f x %.2f inches" +msgstr "" + +#: filter/bannertops.c:794 +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "" + +#: systemv/lpstat.c:754 +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "" + +#: scheduler/ipp.c:10415 +#, c-format +msgid "%s cannot be changed." +msgstr "" + +#: berkeley/lpc.c:194 +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "" + +#: berkeley/lpq.c:643 +#, c-format +msgid "%s is not ready\n" +msgstr "" + +#: berkeley/lpq.c:636 +#, c-format +msgid "%s is ready\n" +msgstr "" + +#: berkeley/lpq.c:639 +#, c-format +msgid "%s is ready and printing\n" +msgstr "" + +#: systemv/lpstat.c:757 +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" + +#: scheduler/ipp.c:701 +#, c-format +msgid "%s not supported!" +msgstr "" + +#: systemv/lpstat.c:767 +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "" + +#: systemv/lpstat.c:770 +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" + +#: berkeley/lpq.c:544 +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "" + +#: systemv/cancel.c:303 systemv/cancel.c:367 +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "" + +#: systemv/cupsaccept.c:73 +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "" + +#: berkeley/lpr.c:356 systemv/lp.c:603 +#, c-format +msgid "%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" + +#: systemv/lp.c:240 +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "" + +#: systemv/lp.c:227 +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" + +#: systemv/lp.c:523 +#, c-format +msgid "%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" + +#: systemv/lp.c:477 +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "" + +#: systemv/lp.c:497 +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "" + +#: systemv/lp.c:273 +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "" + +#: berkeley/lpr.c:251 +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "" + +#: berkeley/lpr.c:219 +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "" + +#: systemv/lpstat.c:238 +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "" + +#: systemv/lp.c:145 +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "" + +#: systemv/lp.c:175 +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "" + +#: systemv/lp.c:404 +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "" + +#: berkeley/lpr.c:111 +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "" + +#: berkeley/lpq.c:188 berkeley/lprm.c:130 systemv/cancel.c:130 +#: systemv/cupsaccept.c:131 systemv/lp.c:196 systemv/lpstat.c:298 +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "" + +#: systemv/lp.c:382 +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "" + +#: berkeley/lpr.c:275 +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "" + +#: systemv/lp.c:296 +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "" + +#: systemv/lp.c:456 +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "" + +#: systemv/lp.c:317 +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "" + +#: systemv/cupsaccept.c:150 +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "" + +#: systemv/lp.c:364 +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "" + +#: berkeley/lpq.c:117 berkeley/lpr.c:91 berkeley/lprm.c:110 +#: systemv/cancel.c:99 systemv/cupsaccept.c:108 systemv/lp.c:122 +#: systemv/lpadmin.c:471 systemv/lpstat.c:144 +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "" + +#: systemv/cancel.c:152 +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "" + +#: berkeley/lpr.c:134 +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "" + +#: systemv/lpstat.c:164 systemv/lpstat.c:178 +#, c-format +msgid "%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' option!\n" +msgstr "" + +#: berkeley/lpr.c:361 systemv/lp.c:608 +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "" + +#: systemv/lp.c:340 +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "" + +#: berkeley/lpr.c:365 systemv/lp.c:612 +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "" + +#: berkeley/lpr.c:317 systemv/lp.c:556 +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "" + +#: berkeley/lpr.c:299 systemv/lp.c:539 +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "" + +#: berkeley/lpr.c:410 systemv/lp.c:645 +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "" + +#: berkeley/lprm.c:93 berkeley/lprm.c:182 systemv/cancel.c:222 +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "" + +#: berkeley/lpq.c:157 +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "" + +#: berkeley/lpr.c:286 berkeley/lprm.c:148 systemv/cancel.c:164 +#: systemv/cupsaccept.c:174 systemv/lp.c:514 systemv/lpstat.c:459 +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "" + +#: systemv/cupsaccept.c:167 +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "" + +#: systemv/lp.c:216 +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "" + +#: scheduler/cupsfilter.c:558 +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "" + +#: systemv/lpstat.c:511 systemv/lpstat.c:550 +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "" + +#: scheduler/cupsfilter.c:539 +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "" + +#: systemv/lp.c:432 +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "" + +#: scheduler/cupsfilter.c:453 +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "" + +#: systemv/cupsaccept.c:208 +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "" + +#: berkeley/lpq.c:103 berkeley/lpr.c:77 berkeley/lprm.c:72 systemv/cancel.c:85 +#: systemv/cupsaccept.c:94 systemv/cupsaddsmb.c:91 systemv/lp.c:108 +#: systemv/lpadmin.c:277 systemv/lpinfo.c:94 systemv/lpmove.c:79 +#: systemv/lpstat.c:109 +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "" + +#: berkeley/lpq.c:304 scheduler/cupsfilter.c:1106 systemv/cupsaddsmb.c:149 +#: systemv/cupsaddsmb.c:175 +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "" + +#: systemv/cancel.c:245 systemv/cancel.c:326 +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "" + +#: scheduler/cupsfilter.c:419 +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "" + +#: ppdc/ppdc-file.cxx:50 ppdc/ppdmerge.cxx:99 +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "" + +#: scheduler/cupsfilter.c:603 +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "" + +#: ppdc/ppdmerge.cxx:113 +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#: scheduler/cupsfilter.c:384 +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "" + +#: berkeley/lpq.c:161 systemv/lpstat.c:565 +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "" + +#: scheduler/cupsfilter.c:430 +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "" + +#: scheduler/cupsfilter.c:1312 +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "" + +#: scheduler/cupsfilter.c:411 +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "" + +#: berkeley/lpr.c:148 +#, c-format +msgid "%s: Warning - '%c' format modifier not supported - output may not be correct!\n" +msgstr "" + +#: systemv/lp.c:485 +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "" + +#: systemv/lp.c:505 +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "" + +#: systemv/lp.c:182 +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "" + +#: systemv/lp.c:390 +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "" + +#: berkeley/lpq.c:245 +#, c-format +msgid "%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" + +#: berkeley/lpr.c:162 +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "" + +#: berkeley/lpq.c:250 +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "" + +#: ppdc/sample.c:281 +msgid "-1" +msgstr "" + +#: ppdc/sample.c:272 +msgid "-10" +msgstr "" + +#: ppdc/sample.c:364 +msgid "-100" +msgstr "" + +#: ppdc/sample.c:363 +msgid "-105" +msgstr "" + +#: ppdc/sample.c:271 +msgid "-11" +msgstr "" + +#: ppdc/sample.c:362 +msgid "-110" +msgstr "" + +#: ppdc/sample.c:361 +msgid "-115" +msgstr "" + +#: ppdc/sample.c:270 +msgid "-12" +msgstr "" + +#: ppdc/sample.c:360 +msgid "-120" +msgstr "" + +#: ppdc/sample.c:269 +msgid "-13" +msgstr "" + +#: ppdc/sample.c:268 +msgid "-14" +msgstr "" + +#: ppdc/sample.c:267 +msgid "-15" +msgstr "" + +#: ppdc/sample.c:280 +msgid "-2" +msgstr "" + +#: ppdc/sample.c:380 +msgid "-20" +msgstr "" + +#: ppdc/sample.c:379 +msgid "-25" +msgstr "" + +#: ppdc/sample.c:279 +msgid "-3" +msgstr "" + +#: ppdc/sample.c:378 +msgid "-30" +msgstr "" + +#: ppdc/sample.c:377 +msgid "-35" +msgstr "" + +#: ppdc/sample.c:278 +msgid "-4" +msgstr "" + +#: ppdc/sample.c:376 +msgid "-40" +msgstr "" + +#: ppdc/sample.c:375 +msgid "-45" +msgstr "" + +#: ppdc/sample.c:277 +msgid "-5" +msgstr "" + +#: ppdc/sample.c:374 +msgid "-50" +msgstr "" + +#: ppdc/sample.c:373 +msgid "-55" +msgstr "" + +#: ppdc/sample.c:276 +msgid "-6" +msgstr "" + +#: ppdc/sample.c:372 +msgid "-60" +msgstr "" + +#: ppdc/sample.c:371 +msgid "-65" +msgstr "" + +#: ppdc/sample.c:275 +msgid "-7" +msgstr "" + +#: ppdc/sample.c:370 +msgid "-70" +msgstr "" + +#: ppdc/sample.c:369 +msgid "-75" +msgstr "" + +#: ppdc/sample.c:274 +msgid "-8" +msgstr "" + +#: ppdc/sample.c:368 +msgid "-80" +msgstr "" + +#: ppdc/sample.c:367 +msgid "-85" +msgstr "" + +#: ppdc/sample.c:273 +msgid "-9" +msgstr "" + +#: ppdc/sample.c:366 +msgid "-90" +msgstr "" + +#: ppdc/sample.c:365 +msgid "-95" +msgstr "" + +#: ppdc/sample.c:282 +msgid "0" +msgstr "" + +#: ppdc/sample.c:283 +msgid "1" +msgstr "" + +#: ppdc/sample.c:355 +msgid "1 inch/sec." +msgstr "" + +#: ppdc/sample.c:144 +msgid "1.25x0.25\"" +msgstr "" + +#: ppdc/sample.c:145 +msgid "1.25x2.25\"" +msgstr "" + +#: ppdc/sample.c:403 +msgid "1.5 inch/sec." +msgstr "" + +#: ppdc/sample.c:146 +msgid "1.50x0.25\"" +msgstr "" + +#: ppdc/sample.c:147 +msgid "1.50x0.50\"" +msgstr "" + +#: ppdc/sample.c:148 +msgid "1.50x1.00\"" +msgstr "" + +#: ppdc/sample.c:149 +msgid "1.50x2.00\"" +msgstr "" + +#: ppdc/sample.c:292 +msgid "10" +msgstr "" + +#: ppdc/sample.c:414 +msgid "10 inches/sec." +msgstr "" + +#: ppdc/sample.c:1 +msgid "10 x 11\"" +msgstr "" + +#: ppdc/sample.c:2 +msgid "10 x 13\"" +msgstr "" + +#: ppdc/sample.c:3 +msgid "10 x 14\"" +msgstr "" + +#: ppdc/sample.c:394 +msgid "100" +msgstr "" + +#: ppdc/sample.c:305 +msgid "100 mm/sec." +msgstr "" + +#: ppdc/sample.c:395 +msgid "105" +msgstr "" + +#: ppdc/sample.c:293 +msgid "11" +msgstr "" + +#: ppdc/sample.c:415 +msgid "11 inches/sec." +msgstr "" + +#: ppdc/sample.c:396 +msgid "110" +msgstr "" + +#: ppdc/sample.c:397 +msgid "115" +msgstr "" + +#: ppdc/sample.c:294 +msgid "12" +msgstr "" + +#: ppdc/sample.c:416 +msgid "12 inches/sec." +msgstr "" + +#: ppdc/sample.c:4 +msgid "12 x 11\"" +msgstr "" + +#: ppdc/sample.c:398 +msgid "120" +msgstr "" + +#: ppdc/sample.c:306 +msgid "120 mm/sec." +msgstr "" + +#: ppdc/sample.c:215 +msgid "120x60dpi" +msgstr "" + +#: ppdc/sample.c:221 +msgid "120x72dpi" +msgstr "" + +#: ppdc/sample.c:295 +msgid "13" +msgstr "" + +#: ppdc/sample.c:204 +msgid "136dpi" +msgstr "" + +#: ppdc/sample.c:296 +msgid "14" +msgstr "" + +#: ppdc/sample.c:297 +msgid "15" +msgstr "" + +#: ppdc/sample.c:299 +msgid "15 mm/sec." +msgstr "" + +#: ppdc/sample.c:5 +msgid "15 x 11\"" +msgstr "" + +#: ppdc/sample.c:307 +msgid "150 mm/sec." +msgstr "" + +#: ppdc/sample.c:254 +msgid "150dpi" +msgstr "" + +#: ppdc/sample.c:339 +msgid "16" +msgstr "" + +#: ppdc/sample.c:340 +msgid "17" +msgstr "" + +#: ppdc/sample.c:341 +msgid "18" +msgstr "" + +#: ppdc/sample.c:216 +msgid "180dpi" +msgstr "" + +#: ppdc/sample.c:342 +msgid "19" +msgstr "" + +#: ppdc/sample.c:284 +msgid "2" +msgstr "" + +#: ppdc/sample.c:356 +msgid "2 inches/sec." +msgstr "" + +#: ppdc/sample.c:242 +msgid "2-Sided Printing" +msgstr "" + +#: ppdc/sample.c:150 +msgid "2.00x0.37\"" +msgstr "" + +#: ppdc/sample.c:151 +msgid "2.00x0.50\"" +msgstr "" + +#: ppdc/sample.c:152 +msgid "2.00x1.00\"" +msgstr "" + +#: ppdc/sample.c:153 +msgid "2.00x1.25\"" +msgstr "" + +#: ppdc/sample.c:154 +msgid "2.00x2.00\"" +msgstr "" + +#: ppdc/sample.c:155 +msgid "2.00x3.00\"" +msgstr "" + +#: ppdc/sample.c:156 +msgid "2.00x4.00\"" +msgstr "" + +#: ppdc/sample.c:157 +msgid "2.00x5.50\"" +msgstr "" + +#: ppdc/sample.c:158 +msgid "2.25x0.50\"" +msgstr "" + +#: ppdc/sample.c:159 +msgid "2.25x1.25\"" +msgstr "" + +#: ppdc/sample.c:160 +msgid "2.25x4.00\"" +msgstr "" + +#: ppdc/sample.c:161 +msgid "2.25x5.50\"" +msgstr "" + +#: ppdc/sample.c:162 +msgid "2.38x5.50\"" +msgstr "" + +#: ppdc/sample.c:404 +msgid "2.5 inches/sec." +msgstr "" + +#: ppdc/sample.c:163 +msgid "2.50x1.00\"" +msgstr "" + +#: ppdc/sample.c:164 +msgid "2.50x2.00\"" +msgstr "" + +#: ppdc/sample.c:165 +msgid "2.75x1.25\"" +msgstr "" + +#: ppdc/sample.c:166 +msgid "2.9 x 1\"" +msgstr "" + +#: ppdc/sample.c:343 +msgid "20" +msgstr "" + +#: ppdc/sample.c:300 +msgid "20 mm/sec." +msgstr "" + +#: ppdc/sample.c:308 +msgid "200 mm/sec." +msgstr "" + +#: ppdc/sample.c:205 +msgid "203dpi" +msgstr "" + +#: ppdc/sample.c:344 +msgid "21" +msgstr "" + +#: ppdc/sample.c:345 +msgid "22" +msgstr "" + +#: ppdc/sample.c:346 +msgid "23" +msgstr "" + +#: ppdc/sample.c:347 +msgid "24" +msgstr "" + +#: ppdc/sample.c:213 +msgid "24-Pin Series" +msgstr "" + +#: ppdc/sample.c:222 +msgid "240x72dpi" +msgstr "" + +#: ppdc/sample.c:348 +msgid "25" +msgstr "" + +#: ppdc/sample.c:309 +msgid "250 mm/sec." +msgstr "" + +#: ppdc/sample.c:349 +msgid "26" +msgstr "" + +#: ppdc/sample.c:350 +msgid "27" +msgstr "" + +#: ppdc/sample.c:351 +msgid "28" +msgstr "" + +#: ppdc/sample.c:352 +msgid "29" +msgstr "" + +#: ppdc/sample.c:285 +msgid "3" +msgstr "" + +#: ppdc/sample.c:357 +msgid "3 inches/sec." +msgstr "" + +#: ppdc/sample.c:167 +msgid "3.00x1.00\"" +msgstr "" + +#: ppdc/sample.c:168 +msgid "3.00x1.25\"" +msgstr "" + +#: ppdc/sample.c:169 +msgid "3.00x2.00\"" +msgstr "" + +#: ppdc/sample.c:170 +msgid "3.00x3.00\"" +msgstr "" + +#: ppdc/sample.c:171 +msgid "3.00x5.00\"" +msgstr "" + +#: ppdc/sample.c:172 +msgid "3.25x2.00\"" +msgstr "" + +#: ppdc/sample.c:173 +msgid "3.25x5.00\"" +msgstr "" + +#: ppdc/sample.c:174 +msgid "3.25x5.50\"" +msgstr "" + +#: ppdc/sample.c:175 +msgid "3.25x5.83\"" +msgstr "" + +#: ppdc/sample.c:176 +msgid "3.25x7.83\"" +msgstr "" + +#: ppdc/sample.c:134 +msgid "3.5\" Disk" +msgstr "" + +#: ppdc/sample.c:143 +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "" + +#: ppdc/sample.c:177 +msgid "3.50x1.00\"" +msgstr "" + +#: ppdc/sample.c:353 +msgid "30" +msgstr "" + +#: ppdc/sample.c:301 +msgid "30 mm/sec." +msgstr "" + +#: ppdc/sample.c:310 +msgid "300 mm/sec." +msgstr "" + +#: ppdc/sample.c:206 +msgid "300dpi" +msgstr "" + +#: ppdc/sample.c:381 +msgid "35" +msgstr "" + +#: ppdc/sample.c:218 +msgid "360dpi" +msgstr "" + +#: ppdc/sample.c:217 +msgid "360x180dpi" +msgstr "" + +#: ppdc/sample.c:286 +msgid "4" +msgstr "" + +#: ppdc/sample.c:358 +msgid "4 inches/sec." +msgstr "" + +#: ppdc/sample.c:178 +msgid "4.00x1.00\"" +msgstr "" + +#: ppdc/sample.c:186 +msgid "4.00x13.00\"" +msgstr "" + +#: ppdc/sample.c:179 +msgid "4.00x2.00\"" +msgstr "" + +#: ppdc/sample.c:180 +msgid "4.00x2.50\"" +msgstr "" + +#: ppdc/sample.c:181 +msgid "4.00x3.00\"" +msgstr "" + +#: ppdc/sample.c:182 +msgid "4.00x4.00\"" +msgstr "" + +#: ppdc/sample.c:183 +msgid "4.00x5.00\"" +msgstr "" + +#: ppdc/sample.c:184 +msgid "4.00x6.00\"" +msgstr "" + +#: ppdc/sample.c:185 +msgid "4.00x6.50\"" +msgstr "" + +#: ppdc/sample.c:382 +msgid "40" +msgstr "" + +#: ppdc/sample.c:302 +msgid "40 mm/sec." +msgstr "" + +#: ppdc/sample.c:383 +msgid "45" +msgstr "" + +#: ppdc/sample.c:287 +msgid "5" +msgstr "" + +#: ppdc/sample.c:408 +msgid "5 inches/sec." +msgstr "" + +#: ppdc/sample.c:384 +msgid "50" +msgstr "" + +#: ppdc/sample.c:385 +msgid "55" +msgstr "" + +#: ppdc/sample.c:288 +msgid "6" +msgstr "" + +#: ppdc/sample.c:409 +msgid "6 inches/sec." +msgstr "" + +#: ppdc/sample.c:187 +msgid "6.00x1.00\"" +msgstr "" + +#: ppdc/sample.c:188 +msgid "6.00x2.00\"" +msgstr "" + +#: ppdc/sample.c:189 +msgid "6.00x3.00\"" +msgstr "" + +#: ppdc/sample.c:190 +msgid "6.00x4.00\"" +msgstr "" + +#: ppdc/sample.c:191 +msgid "6.00x5.00\"" +msgstr "" + +#: ppdc/sample.c:192 +msgid "6.00x6.00\"" +msgstr "" + +#: ppdc/sample.c:193 +msgid "6.00x6.50\"" +msgstr "" + +#: ppdc/sample.c:386 +msgid "60" +msgstr "" + +#: ppdc/sample.c:303 +msgid "60 mm/sec." +msgstr "" + +#: ppdc/sample.c:233 +msgid "600dpi" +msgstr "" + +#: ppdc/sample.c:214 +msgid "60dpi" +msgstr "" + +#: ppdc/sample.c:220 +msgid "60x720dpi" +msgstr "" + +#: ppdc/sample.c:387 +msgid "65" +msgstr "" + +#: ppdc/sample.c:289 +msgid "7" +msgstr "" + +#: ppdc/sample.c:411 +msgid "7 inches/sec." +msgstr "" + +#: ppdc/sample.c:6 +msgid "7 x 9\"" +msgstr "" + +#: ppdc/sample.c:388 +msgid "70" +msgstr "" + +#: ppdc/sample.c:224 +msgid "720dpi" +msgstr "" + +#: ppdc/sample.c:389 +msgid "75" +msgstr "" + +#: ppdc/sample.c:290 +msgid "8" +msgstr "" + +#: ppdc/sample.c:412 +msgid "8 inches/sec." +msgstr "" + +#: ppdc/sample.c:7 +msgid "8 x 10\"" +msgstr "" + +#: ppdc/sample.c:194 +msgid "8.00x1.00\"" +msgstr "" + +#: ppdc/sample.c:195 +msgid "8.00x2.00\"" +msgstr "" + +#: ppdc/sample.c:196 +msgid "8.00x3.00\"" +msgstr "" + +#: ppdc/sample.c:197 +msgid "8.00x4.00\"" +msgstr "" + +#: ppdc/sample.c:198 +msgid "8.00x5.00\"" +msgstr "" + +#: ppdc/sample.c:199 +msgid "8.00x6.00\"" +msgstr "" + +#: ppdc/sample.c:200 +msgid "8.00x6.50\"" +msgstr "" + +#: ppdc/sample.c:390 +msgid "80" +msgstr "" + +#: ppdc/sample.c:304 +msgid "80 mm/sec." +msgstr "" + +#: ppdc/sample.c:391 +msgid "85" +msgstr "" + +#: ppdc/sample.c:291 +msgid "9" +msgstr "" + +#: ppdc/sample.c:413 +msgid "9 inches/sec." +msgstr "" + +#: ppdc/sample.c:8 +msgid "9 x 11\"" +msgstr "" + +#: ppdc/sample.c:9 +msgid "9 x 12\"" +msgstr "" + +#: ppdc/sample.c:219 +msgid "9-Pin Series" +msgstr "" + +#: ppdc/sample.c:392 +msgid "90" +msgstr "" + +#: ppdc/sample.c:393 +msgid "95" +msgstr "" + +#: berkeley/lpc.c:218 +msgid "?Invalid help command unknown\n" +msgstr "" + +#: cgi-bin/admin.c:2343 +msgid "A Samba password is required to export printer drivers!" +msgstr "" + +#: cgi-bin/admin.c:2339 +msgid "A Samba username is required to export printer drivers!" +msgstr "" + +#: scheduler/ipp.c:2390 +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "" + +#: scheduler/ipp.c:1013 +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "" + +#: ppdc/sample.c:10 +msgid "A0" +msgstr "" + +#: ppdc/sample.c:11 +msgid "A1" +msgstr "" + +#: ppdc/sample.c:24 +msgid "A10" +msgstr "" + +#: ppdc/sample.c:12 +msgid "A2" +msgstr "" + +#: ppdc/sample.c:13 +msgid "A3" +msgstr "" + +#: ppdc/sample.c:14 +msgid "A3 (Oversize)" +msgstr "" + +#: ppdc/sample.c:15 +msgid "A4" +msgstr "" + +#: ppdc/sample.c:16 +msgid "A4 (Oversize)" +msgstr "" + +#: ppdc/sample.c:17 +msgid "A4 (Small)" +msgstr "" + +#: ppdc/sample.c:18 +msgid "A5" +msgstr "" + +#: ppdc/sample.c:19 +msgid "A5 (Oversize)" +msgstr "" + +#: ppdc/sample.c:20 +msgid "A6" +msgstr "" + +#: ppdc/sample.c:21 +msgid "A7" +msgstr "" + +#: ppdc/sample.c:22 +msgid "A8" +msgstr "" + +#: ppdc/sample.c:23 +msgid "A9" +msgstr "" + +#: ppdc/sample.c:25 +msgid "ANSI A" +msgstr "" + +#: ppdc/sample.c:26 +msgid "ANSI B" +msgstr "" + +#: ppdc/sample.c:27 +msgid "ANSI C" +msgstr "" + +#: ppdc/sample.c:28 +msgid "ANSI D" +msgstr "" + +#: ppdc/sample.c:29 +msgid "ANSI E" +msgstr "" + +#: ppdc/sample.c:30 +msgid "ARCH A" +msgstr "" + +#: ppdc/sample.c:31 +msgid "ARCH B" +msgstr "" + +#: ppdc/sample.c:32 +msgid "ARCH C" +msgstr "" + +#: ppdc/sample.c:33 +msgid "ARCH D" +msgstr "" + +#: ppdc/sample.c:34 +msgid "ARCH E" +msgstr "" + +#: cgi-bin/classes.c:154 cgi-bin/printers.c:157 +msgid "Accept Jobs" +msgstr "" + +#: cups/http-support.c:1196 +msgid "Accepted" +msgstr "" + +#: cgi-bin/admin.c:480 +msgid "Add Class" +msgstr "" + +#: cgi-bin/admin.c:778 +msgid "Add Printer" +msgstr "" + +#: cgi-bin/admin.c:355 cgi-bin/admin.c:388 cgi-bin/admin.c:436 +#: cgi-bin/admin.c:446 +msgid "Add RSS Subscription" +msgstr "" + +#: ppdc/sample.c:126 +msgid "Address" +msgstr "" + +#: ppdc/sample.c:135 +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "" + +#: cgi-bin/admin.c:187 cgi-bin/admin.c:218 cgi-bin/admin.c:2761 +msgid "Administration" +msgstr "" + +#: ppdc/sample.c:400 +msgid "Always" +msgstr "" + +#: backend/socket.c:126 +msgid "AppSocket/HP JetDirect" +msgstr "" + +#: ppdc/sample.c:421 +msgid "Applicator" +msgstr "" + +#: scheduler/ipp.c:1135 +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "" + +#: scheduler/ipp.c:341 +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "" + +#: ppdc/sample.c:35 +msgid "B0" +msgstr "" + +#: ppdc/sample.c:37 +msgid "B1" +msgstr "" + +#: ppdc/sample.c:36 +msgid "B10" +msgstr "" + +#: ppdc/sample.c:38 +msgid "B2" +msgstr "" + +#: ppdc/sample.c:39 +msgid "B3" +msgstr "" + +#: ppdc/sample.c:40 +msgid "B4" +msgstr "" + +#: ppdc/sample.c:41 +msgid "B5" +msgstr "" + +#: ppdc/sample.c:42 +msgid "B6" +msgstr "" + +#: ppdc/sample.c:43 +msgid "B7" +msgstr "" + +#: ppdc/sample.c:44 +msgid "B8" +msgstr "" + +#: ppdc/sample.c:45 +msgid "B9" +msgstr "" + +#: cups/dest.c:317 +msgid "Bad NULL dests pointer" +msgstr "" + +#: cups/ppd.c:342 +msgid "Bad OpenGroup" +msgstr "" + +#: cups/ppd.c:344 +msgid "Bad OpenUI/JCLOpenUI" +msgstr "" + +#: cups/ppd.c:346 +msgid "Bad OrderDependency" +msgstr "" + +#: cups/http-support.c:1211 +msgid "Bad Request" +msgstr "" + +#: cups/snmp.c:1003 +msgid "Bad SNMP version number" +msgstr "" + +#: cups/ppd.c:347 +msgid "Bad UIConstraints" +msgstr "" + +#: scheduler/ipp.c:1433 +#, c-format +msgid "Bad copies value %d." +msgstr "" + +#: cups/ppd.c:355 +msgid "Bad custom parameter" +msgstr "" + +#: cups/http-support.c:1339 +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "" + +#: scheduler/ipp.c:2508 +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:2548 +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:9835 scheduler/ipp.c:11314 +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "" + +#: cups/util.c:930 +msgid "Bad filename buffer!" +msgstr "" + +#: ppdc/ppdc-import.cxx:265 +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "" + +#: scheduler/ipp.c:10431 +msgid "Bad job-priority value!" +msgstr "" + +#: scheduler/ipp.c:1463 +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:1447 +msgid "Bad job-sheets value type!" +msgstr "" + +#: scheduler/ipp.c:10461 +msgid "Bad job-state value!" +msgstr "" + +#: scheduler/ipp.c:3663 scheduler/ipp.c:4022 scheduler/ipp.c:6650 +#: scheduler/ipp.c:6792 scheduler/ipp.c:8067 scheduler/ipp.c:8322 +#: scheduler/ipp.c:9166 scheduler/ipp.c:9392 scheduler/ipp.c:9747 +#: scheduler/ipp.c:10323 +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:2129 scheduler/ipp.c:6197 +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:2093 scheduler/ipp.c:6161 +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:1479 +#, c-format +msgid "Bad number-up value %d." +msgstr "" + +#: cups/adminutil.c:303 +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "" + +#: scheduler/ipp.c:1496 +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "" + +#: scheduler/ipp.c:2592 +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:2640 +#, c-format +msgid "Bad printer-state value %d!" +msgstr "" + +#: scheduler/ipp.c:309 +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#: scheduler/ipp.c:294 +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "" + +#: cgi-bin/admin.c:1385 +msgid "Bad subscription ID!" +msgstr "" + +#: cgi-bin/admin.c:3301 cgi-bin/admin.c:3524 +msgid "Banners" +msgstr "" + +#: filter/bannertops.c:666 +msgid "Billing Information: " +msgstr "" + +#: ppdc/sample.c:258 +msgid "Bond Paper" +msgstr "" + +#: ppdc/sample.c:56 +msgid "C0 Envelope" +msgstr "" + +#: ppdc/sample.c:57 +msgid "C1 Envelope" +msgstr "" + +#: ppdc/sample.c:58 +msgid "C2 Envelope" +msgstr "" + +#: ppdc/sample.c:59 +msgid "C3 Envelope" +msgstr "" + +#: ppdc/sample.c:46 +msgid "C4" +msgstr "" + +#: ppdc/sample.c:60 +msgid "C4 Envelope" +msgstr "" + +#: ppdc/sample.c:47 +msgid "C5" +msgstr "" + +#: ppdc/sample.c:61 +msgid "C5 Envelope" +msgstr "" + +#: ppdc/sample.c:48 +msgid "C6" +msgstr "" + +#: ppdc/sample.c:63 +msgid "C6 Envelope" +msgstr "" + +#: ppdc/sample.c:62 +msgid "C65 Envelope" +msgstr "" + +#: ppdc/sample.c:64 +msgid "C7 Envelope" +msgstr "" + +#: ppdc/sample.c:226 +msgid "CMYK" +msgstr "" + +#: ppdc/sample.c:334 +msgid "CPCL Label Printer" +msgstr "" + +#: cgi-bin/admin.c:1386 cgi-bin/admin.c:1425 cgi-bin/admin.c:1435 +msgid "Cancel RSS Subscription" +msgstr "" + +#: cgi-bin/admin.c:1608 cgi-bin/admin.c:1772 cgi-bin/admin.c:1784 +#: cgi-bin/admin.c:1795 +msgid "Change Settings" +msgstr "" + +#: scheduler/ipp.c:2141 scheduler/ipp.c:6209 +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "" + +#: ppdc/sample.c:65 +msgid "Chou3 Envelope" +msgstr "" + +#: ppdc/sample.c:66 +msgid "Chou4 Envelope" +msgstr "" + +#: cgi-bin/classes.c:180 cgi-bin/classes.c:307 +msgid "Classes" +msgstr "" + +#: cgi-bin/printers.c:167 +msgid "Clean Print Heads" +msgstr "" + +#: ppdc/sample.c:253 +msgid "Color" +msgstr "" + +#: ppdc/sample.c:225 +msgid "Color Mode" +msgstr "" + +#: berkeley/lpc.c:209 +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" + +#: cups/snmp.c:1007 +msgid "Community name uses indefinite length" +msgstr "" + +#: cups/http-support.c:1184 +msgid "Continue" +msgstr "" + +#: ppdc/sample.c:336 +msgid "Continuous" +msgstr "" + +#: scheduler/ipp.c:8616 scheduler/ipp.c:8632 scheduler/ipp.c:9851 +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "" + +#: cups/localize.c:319 +msgid "Cover open." +msgstr "" + +#: cups/http-support.c:1193 +msgid "Created" +msgstr "" + +#: filter/bannertops.c:854 +msgid "Created On: " +msgstr "" + +#: cups/ppd.c:1072 cups/ppd.c:1112 cups/ppd.c:1326 cups/ppd.c:1429 +msgid "Custom" +msgstr "" + +#: ppdc/sample.c:330 +msgid "CustominCutInterval" +msgstr "" + +#: ppdc/sample.c:328 +msgid "CustominTearInterval" +msgstr "" + +#: ppdc/sample.c:314 +msgid "Cut" +msgstr "" + +#: ppdc/sample.c:422 +msgid "Cutter" +msgstr "" + +#: ppdc/sample.c:49 +msgid "DL" +msgstr "" + +#: ppdc/sample.c:67 +msgid "DL Envelope" +msgstr "" + +#: ppdc/sample.c:211 +msgid "Dark" +msgstr "" + +#: ppdc/sample.c:207 +msgid "Darkness" +msgstr "" + +#: cgi-bin/admin.c:2068 cgi-bin/admin.c:2079 cgi-bin/admin.c:2124 +msgid "Delete Class" +msgstr "" + +#: cgi-bin/admin.c:2153 cgi-bin/admin.c:2164 cgi-bin/admin.c:2209 +msgid "Delete Printer" +msgstr "" + +#: filter/bannertops.c:735 +msgid "Description: " +msgstr "" + +#: ppdc/sample.c:252 +msgid "DeskJet Series" +msgstr "" + +#: scheduler/ipp.c:1399 +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "" + +#: cups/localize.c:353 +msgid "Developer almost empty." +msgstr "" + +#: cups/localize.c:355 +msgid "Developer empty!" +msgstr "" + +#: systemv/lpinfo.c:305 +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" + +#: ppdc/sample.c:407 +msgid "Direct Thermal Media" +msgstr "" + +#: ppdc/sample.c:316 +msgid "Disabled" +msgstr "" + +#: scheduler/ipp.c:6697 +#, c-format +msgid "Document %d not found in job %d." +msgstr "" + +#: cups/localize.c:323 +msgid "Door open." +msgstr "" + +#: ppdc/sample.c:50 +msgid "Double Postcard" +msgstr "" + +#: filter/bannertops.c:820 +msgid "Driver Name: " +msgstr "" + +#: filter/bannertops.c:831 +msgid "Driver Version: " +msgstr "" + +#: ppdc/sample.c:247 +msgid "Duplexer" +msgstr "" + +#: ppdc/sample.c:201 +msgid "Dymo" +msgstr "" + +#: filter/pstops.c:446 +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "" + +#: filter/pstops.c:438 +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "" + +#: ppdc/sample.c:402 +msgid "EPL1 Label Printer" +msgstr "" + +#: ppdc/sample.c:405 +msgid "EPL2 Label Printer" +msgstr "" + +#: driver/rastertoescpx.c:1776 driver/rastertopclx.c:1801 +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#: filter/pstops.c:707 +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "" + +#: filter/pstops.c:2220 +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "" + +#: filter/pstops.c:1286 filter/pstops.c:1292 +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "" + +#: filter/pstops.c:1363 +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "" + +#: backend/scsi-irix.c:100 backend/scsi-linux.c:114 +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "" + +#: filter/pstext.c:276 filter/texttops.c:284 filter/texttops.c:295 +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "" + +#: filter/texttops.c:453 +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "" + +#: filter/textcommon.c:613 +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "" + +#: filter/textcommon.c:624 +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "" + +#: filter/pstext.c:320 filter/pstext.c:357 filter/texttops.c:348 +#: filter/texttops.c:384 +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "" + +#: filter/textcommon.c:635 +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "" + +#: filter/imagetoraster.c:458 +msgid "ERROR: Bad page setup!\n" +msgstr "" + +#: filter/pstext.c:334 filter/texttops.c:361 +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "" + +#: filter/pstext.c:371 filter/texttops.c:397 +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "" + +#: backend/ipp.c:749 +msgid "ERROR: Destination printer does not exist!\n" +msgstr "" + +#: filter/pstops.c:696 +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "" + +#: filter/pstops.c:648 +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "" + +#: backend/ipp.c:468 filter/pstops.c:303 +msgid "ERROR: Empty print file!\n" +msgstr "" + +#: backend/pap.c:838 +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "" + +#: ppdc/ppdc-catalog.cxx:338 ppdc/ppdc-catalog.cxx:350 +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "" + +#: backend/usb-darwin.c:377 backend/usb-darwin.c:435 backend/usb-darwin.c:500 +#: backend/usb-darwin.c:518 +msgid "ERROR: Fatal USB error!\n" +msgstr "" + +#: filter/hpgl-input.c:139 +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" + +#: filter/pstops.c:1771 +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "" + +#: filter/pstops.c:1842 +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "" + +#: filter/bannertops.c:222 +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "" + +#: ppdc/ppdc-catalog.cxx:415 +#, c-format +msgid "ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" + +#: filter/pstops.c:759 +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "" + +#: filter/pstops.c:762 +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "" + +#: backend/usb.c:200 +msgid "ERROR: No device URI found in argv[0] or in DEVICE_URI environment variable!\n" +msgstr "" + +#: filter/pstext.c:433 +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "" + +#: driver/rastertoescpx.c:1906 driver/rastertopclx.c:1931 +#: filter/rastertoepson.c:1129 filter/rastertohp.c:857 +#: filter/rastertolabel.c:1283 +msgid "ERROR: No pages found!\n" +msgstr "" + +#: backend/runloop.c:348 +msgid "ERROR: Out of paper!\n" +msgstr "" + +#: backend/ipp.c:1754 +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "" + +#: backend/ipp.c:1066 +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "" + +#: backend/pap.c:521 +msgid "ERROR: Printer not responding\n" +msgstr "" + +#: backend/ipp.c:581 backend/ipp.c:716 backend/lpd.c:848 backend/socket.c:310 +msgid "ERROR: Printer not responding!\n" +msgstr "" + +#: backend/pap.c:858 +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "" + +#: backend/lpd.c:1052 backend/lpd.c:1199 +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "" + +#: backend/lpd.c:1147 +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "" + +#: backend/pap.c:1694 +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" + +#: backend/ipp.c:1145 +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "" + +#: backend/ipp.c:1383 +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "" + +#: filter/pdftops.c:136 +msgid "ERROR: Unable to copy PDF file" +msgstr "" + +#: filter/pdftops.c:412 +msgid "ERROR: Unable to create pipe" +msgstr "" + +#: backend/lpd.c:772 +msgid "ERROR: Unable to create socket" +msgstr "" + +#: backend/ipp.c:1476 +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" + +#: backend/ipp.c:431 backend/ipp.c:1776 backend/lpd.c:446 filter/pstops.c:2719 +#: scheduler/cupsfilter.c:1121 systemv/lpadmin.c:1453 systemv/lpadmin.c:1842 +msgid "ERROR: Unable to create temporary file" +msgstr "" + +#: backend/ipp.c:1831 +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "" + +#: filter/pdftops.c:433 filter/pdftops.c:447 +msgid "ERROR: Unable to execute gs program" +msgstr "" + +#: filter/pdftops.c:430 filter/pdftops.c:445 +msgid "ERROR: Unable to execute pdftops program" +msgstr "" + +#: filter/pdftops.c:467 filter/pdftops.c:477 +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#: backend/ipp.c:1844 +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "" + +#: backend/pap.c:712 +msgid "ERROR: Unable to get PAP request" +msgstr "" + +#: backend/pap.c:701 +msgid "ERROR: Unable to get PAP response" +msgstr "" + +#: backend/ipp.c:1761 +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" + +#: backend/pap.c:302 +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "" + +#: backend/ipp.c:1232 +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "" + +#: backend/ipp.c:759 +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "" + +#: backend/ipp.c:422 backend/ipp.c:599 backend/lpd.c:437 backend/lpd.c:705 +#: backend/socket.c:268 +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "" + +#: backend/pap.c:688 +msgid "ERROR: Unable to look for PAP response" +msgstr "" + +#: backend/pap.c:322 +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "" + +#: backend/pap.c:451 +msgid "ERROR: Unable to make AppleTalk address" +msgstr "" + +#: filter/pstext.c:247 filter/texttops.c:248 +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "" + +#: filter/pstext.c:264 filter/texttops.c:268 +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "" + +#: driver/rastertoescpx.c:1791 driver/rastertopclx.c:1816 +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#: filter/bannertops.c:184 +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "" + +#: backend/parallel.c:249 backend/scsi-irix.c:140 backend/scsi-linux.c:154 +#: backend/serial.c:262 backend/usb-unix.c:146 +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "" + +#: filter/pstops.c:291 +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "" + +#: filter/gziptoany.c:74 +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "" + +#: filter/imagetops.c:313 filter/imagetoraster.c:635 +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "" + +#: backend/ipp.c:1492 backend/pap.c:249 backend/parallel.c:151 +#: backend/scsi.c:181 backend/serial.c:189 backend/socket.c:156 +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "" + +#: backend/usb.c:237 +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "" + +#: backend/lpd.c:487 +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "" + +#: driver/rastertoescpx.c:1806 driver/rastertopclx.c:1831 +#: filter/rastertoepson.c:1001 filter/rastertohp.c:726 +#: filter/rastertolabel.c:1148 +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#: backend/ipp.c:1484 +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" + +#: filter/texttops.c:200 +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "" + +#: filter/texttops.c:179 +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "" + +#: backend/serial.c:615 +msgid "ERROR: Unable to read print data" +msgstr "" + +#: backend/usb-darwin.c:602 backend/usb-darwin.c:644 +msgid "ERROR: Unable to read print data!\n" +msgstr "" + +#: backend/lpd.c:789 +msgid "ERROR: Unable to reserve port" +msgstr "" + +#: filter/pstops.c:563 +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "" + +#: filter/pstops.c:561 +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "" + +#: backend/lpd.c:603 +msgid "ERROR: Unable to send LPD command" +msgstr "" + +#: backend/pap.c:571 +msgid "ERROR: Unable to send PAP tickle request" +msgstr "" + +#: backend/pap.c:580 +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "" + +#: backend/scsi-irix.c:219 backend/scsi-linux.c:237 +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "" + +#: backend/usb-darwin.c:720 +msgid "ERROR: Unable to send print data!\n" +msgstr "" + +#: backend/lpd.c:1103 +msgid "ERROR: Unable to send print file to printer" +msgstr "" + +#: backend/lpd.c:1117 +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "" + +#: backend/ipp.c:1857 +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "" + +#: backend/ipp.c:1503 +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "" + +#: backend/usb-libusb.c:169 backend/usb-libusb.c:765 +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "" + +#: backend/lpd.c:1033 backend/lpd.c:1180 +msgid "ERROR: Unable to write control file" +msgstr "" + +#: backend/serial.c:691 +msgid "ERROR: Unable to write print data" +msgstr "" + +#: backend/runloop.c:122 backend/runloop.c:363 +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "" + +#: filter/imagetoraster.c:1197 filter/imagetoraster.c:1293 +#: filter/imagetoraster.c:1333 +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "" + +#: backend/ipp.c:443 backend/lpd.c:456 +msgid "ERROR: Unable to write to temporary file" +msgstr "" + +#: filter/gziptoany.c:96 +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" + +#: ppdc/ppdc-catalog.cxx:432 +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "" + +#: backend/ipp.c:346 +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "" + +#: backend/lpd.c:354 +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "" + +#: backend/lpd.c:326 +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "" + +#: ppdc/ppdc-catalog.cxx:460 +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "" + +#: backend/ipp.c:392 +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "" + +#: backend/lpd.c:340 +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "" + +#: backend/ipp.c:363 +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "" + +#: filter/pstops.c:2418 +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "" + +#: filter/pstops.c:2487 +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "" + +#: filter/pstops.c:2541 +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" + +#: filter/pstops.c:2574 +#, c-format +msgid "ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" + +#: filter/pstops.c:2624 +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" + +#: filter/pstops.c:2090 +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "" + +#: backend/ipp.c:1876 +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "" + +#: backend/ipp.c:1873 +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "" + +#: backend/ipp.c:609 backend/lpd.c:877 backend/socket.c:333 +msgid "ERROR: recoverable: Unable to connect to printer; will retry in 30 seconds...\n" +msgstr "" + +#: backend/pap.c:629 +msgid "ERROR: select() failed" +msgstr "" + +#: backend/lpd.c:940 +msgid "ERROR: unable to stat print file" +msgstr "" + +#: cgi-bin/admin.c:1823 cgi-bin/admin.c:1835 cgi-bin/admin.c:1889 +#: cgi-bin/admin.c:1896 cgi-bin/admin.c:1931 cgi-bin/admin.c:1944 +#: cgi-bin/admin.c:1968 cgi-bin/admin.c:2041 +msgid "Edit Configuration File" +msgstr "" + +#: cups/adminutil.c:348 +msgid "Empty PPD file!" +msgstr "" + +#: cgi-bin/admin.c:3545 +msgid "Ending Banner" +msgstr "" + +#: systemv/lppasswd.c:205 +msgid "Enter old password:" +msgstr "" + +#: systemv/lppasswd.c:234 +msgid "Enter password again:" +msgstr "" + +#: systemv/lppasswd.c:223 +msgid "Enter password:" +msgstr "" + +#: scheduler/client.c:2392 +msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket." +msgstr "" + +#: ppdc/sample.c:241 +msgid "Envelope Feed" +msgstr "" + +#: ppdc/sample.c:212 +msgid "Epson" +msgstr "" + +#: cgi-bin/admin.c:3588 +msgid "Error Policy" +msgstr "" + +#: systemv/lpinfo.c:109 systemv/lpmove.c:94 +msgid "Error: need hostname after '-h' option!\n" +msgstr "" + +#: ppdc/sample.c:326 +msgid "Every 10 Labels" +msgstr "" + +#: ppdc/sample.c:318 +msgid "Every 2 Labels" +msgstr "" + +#: ppdc/sample.c:319 +msgid "Every 3 Labels" +msgstr "" + +#: ppdc/sample.c:320 +msgid "Every 4 Labels" +msgstr "" + +#: ppdc/sample.c:321 +msgid "Every 5 Labels" +msgstr "" + +#: ppdc/sample.c:322 +msgid "Every 6 Labels" +msgstr "" + +#: ppdc/sample.c:323 +msgid "Every 7 Labels" +msgstr "" + +#: ppdc/sample.c:324 +msgid "Every 8 Labels" +msgstr "" + +#: ppdc/sample.c:325 +msgid "Every 9 Labels" +msgstr "" + +#: ppdc/sample.c:317 +msgid "Every Label" +msgstr "" + +#: cups/http-support.c:1239 +msgid "Expectation Failed" +msgstr "" + +#: cgi-bin/admin.c:2331 cgi-bin/admin.c:2350 +msgid "Export Printers to Samba" +msgstr "" + +#: systemv/cupstestdsc.c:176 systemv/cupstestdsc.c:193 +#: systemv/cupstestdsc.c:218 systemv/cupstestdsc.c:235 +#: systemv/cupstestdsc.c:259 systemv/cupstestdsc.c:277 +#: systemv/cupstestdsc.c:306 systemv/cupstestdsc.c:343 +#: systemv/cupstestdsc.c:353 systemv/cupstestdsc.c:363 +#: systemv/cupstestdsc.c:373 systemv/cupstestdsc.c:383 +#: systemv/cupstestdsc.c:391 +msgid "FAIL\n" +msgstr "" + +#: ppdc/sample.c:132 +msgid "File Folder" +msgstr "" + +#: ppdc/sample.c:141 +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "" + +#: scheduler/ipp.c:2528 +#, c-format +msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"." +msgstr "" + +#: ppdc/sample.c:92 +msgid "Folio" +msgstr "" + +#: cups/http-support.c:1218 +msgid "Forbidden" +msgstr "" + +#: cups/localize.c:345 +msgid "Fuser temperature high!" +msgstr "" + +#: cups/localize.c:347 +msgid "Fuser temperature low!" +msgstr "" + +#: cups/ppd.c:700 cups/ppd.c:1230 +msgid "General" +msgstr "" + +#: ppdc/sample.c:231 +msgid "Generic" +msgstr "" + +#: ppdc/sample.c:89 +msgid "German FanFold" +msgstr "" + +#: ppdc/sample.c:90 +msgid "German FanFold Legal" +msgstr "" + +#: cups/snmp.c:1017 +msgid "Get-Response-PDU uses indefinite length" +msgstr "" + +#: ppdc/sample.c:261 +msgid "Glossy Paper" +msgstr "" + +#: scheduler/ipp.c:3641 scheduler/ipp.c:3947 scheduler/ipp.c:6627 +#: scheduler/ipp.c:6769 scheduler/ipp.c:8044 scheduler/ipp.c:9143 +#: scheduler/ipp.c:9369 scheduler/ipp.c:9724 scheduler/ipp.c:10300 +msgid "Got a printer-uri attribute but no job-id!" +msgstr "" + +#: ppdc/sample.c:227 +msgid "Grayscale" +msgstr "" + +#: ppdc/sample.c:251 +msgid "HP" +msgstr "" + +#: ppdc/sample.c:133 +msgid "Hanging Folder" +msgstr "" + +#: ppdc/sample.c:142 +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "" + +#: backend/pap.c:296 +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "" + +#: backend/pap.c:511 +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "" + +#: backend/ipp.c:1359 +msgid "INFO: Canceling print job...\n" +msgstr "" + +#: backend/ipp.c:629 backend/lpd.c:896 backend/socket.c:354 +msgid "INFO: Connected to printer...\n" +msgstr "" + +#: backend/ipp.c:544 backend/lpd.c:729 backend/socket.c:274 +msgid "INFO: Connecting to printer...\n" +msgstr "" + +#: backend/lpd.c:1055 backend/lpd.c:1202 +msgid "INFO: Control file sent successfully\n" +msgstr "" + +#: backend/ipp.c:435 backend/lpd.c:450 +msgid "INFO: Copying print data...\n" +msgstr "" + +#: backend/lpd.c:1150 +msgid "INFO: Data file sent successfully\n" +msgstr "" + +#: driver/rastertoescpx.c:1887 driver/rastertopclx.c:1912 +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#: filter/imagetoraster.c:1140 +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "" + +#: filter/imagetoraster.c:621 +msgid "INFO: Loading image file...\n" +msgstr "" + +#: cups/http-support.c:1428 +msgid "INFO: Looking for printer...\n" +msgstr "" + +#: backend/pap.c:928 +msgid "INFO: Opening connection\n" +msgstr "" + +#: backend/socket.c:425 +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" + +#: backend/ipp.c:1044 backend/usb-unix.c:132 +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "" + +#: backend/parallel.c:236 backend/scsi-irix.c:147 backend/scsi-linux.c:161 +#: backend/serial.c:256 +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "" + +#: backend/usb-unix.c:437 +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "" + +#: backend/ipp.c:742 backend/ipp.c:1055 +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" + +#: backend/usb-unix.c:521 +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "" + +#: backend/runloop.c:357 +msgid "INFO: Printer is currently off-line.\n" +msgstr "" + +#: backend/runloop.c:243 +msgid "INFO: Printer is currently offline.\n" +msgstr "" + +#: backend/runloop.c:379 backend/usb-darwin.c:1254 +msgid "INFO: Printer is now online.\n" +msgstr "" + +#: backend/usb-darwin.c:1272 +msgid "INFO: Printer is offline.\n" +msgstr "" + +#: backend/parallel.c:242 backend/usb-unix.c:139 +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "" + +#: driver/rastertoescpx.c:1873 driver/rastertopclx.c:1895 +#: filter/rastertoepson.c:1080 filter/rastertohp.c:803 +#: filter/rastertolabel.c:1235 +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "" + +#: filter/imagetops.c:808 +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "" + +#: backend/socket.c:457 driver/rastertoescpx.c:1911 driver/rastertopclx.c:1936 +#: filter/rastertoepson.c:1134 filter/rastertohp.c:862 +#: filter/rastertolabel.c:1288 +msgid "INFO: Ready to print.\n" +msgstr "" + +#: backend/lpd.c:1174 +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "" + +#: backend/lpd.c:1027 +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "" + +#: backend/pap.c:564 +msgid "INFO: Sending data\n" +msgstr "" + +#: backend/lpd.c:1086 +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "" + +#: backend/lpd.c:1084 +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "" + +#: backend/usb-darwin.c:534 +msgid "INFO: Sending print data...\n" +msgstr "" + +#: backend/parallel.c:294 backend/socket.c:404 backend/usb-unix.c:201 +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "" + +#: backend/parallel.c:292 backend/socket.c:402 backend/usb-unix.c:199 +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "" + +#: backend/lpd.c:1098 +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "" + +#: driver/rastertoescpx.c:1859 driver/rastertopclx.c:1880 +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +#: backend/ipp.c:561 backend/ipp.c:823 backend/lpd.c:829 +#: backend/parallel.c:221 backend/scsi-irix.c:125 backend/scsi-linux.c:139 +#: backend/serial.c:241 backend/socket.c:293 backend/usb-unix.c:117 +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" + +#: backend/pap.c:309 +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "" + +#: backend/ipp.c:1170 +msgid "INFO: Waiting for job to complete...\n" +msgstr "" + +#: backend/usb-darwin.c:454 backend/usb-libusb.c:117 +msgid "INFO: Waiting for printer to become available...\n" +msgstr "" + +#: ppdc/sample.c:93 +msgid "ISO B0" +msgstr "" + +#: ppdc/sample.c:94 +msgid "ISO B1" +msgstr "" + +#: ppdc/sample.c:104 +msgid "ISO B10" +msgstr "" + +#: ppdc/sample.c:95 +msgid "ISO B2" +msgstr "" + +#: ppdc/sample.c:96 +msgid "ISO B3" +msgstr "" + +#: ppdc/sample.c:97 +msgid "ISO B4" +msgstr "" + +#: ppdc/sample.c:69 +msgid "ISO B4 Envelope" +msgstr "" + +#: ppdc/sample.c:98 +msgid "ISO B5" +msgstr "" + +#: ppdc/sample.c:99 +msgid "ISO B5 (Oversize)" +msgstr "" + +#: ppdc/sample.c:70 +msgid "ISO B5 Envelope" +msgstr "" + +#: ppdc/sample.c:100 +msgid "ISO B6" +msgstr "" + +#: ppdc/sample.c:71 +msgid "ISO B6 Envelope" +msgstr "" + +#: ppdc/sample.c:101 +msgid "ISO B7" +msgstr "" + +#: ppdc/sample.c:102 +msgid "ISO B8" +msgstr "" + +#: ppdc/sample.c:103 +msgid "ISO B9" +msgstr "" + +#: cups/ppd.c:350 +msgid "Illegal control character" +msgstr "" + +#: cups/ppd.c:351 +msgid "Illegal main keyword string" +msgstr "" + +#: cups/ppd.c:352 +msgid "Illegal option keyword string" +msgstr "" + +#: cups/ppd.c:353 +msgid "Illegal translation string" +msgstr "" + +#: cups/ppd.c:354 +msgid "Illegal whitespace character" +msgstr "" + +#: cups/localize.c:337 +msgid "Ink/toner almost empty." +msgstr "" + +#: cups/localize.c:339 +msgid "Ink/toner empty!" +msgstr "" + +#: cups/localize.c:341 +msgid "Ink/toner waste bin almost full." +msgstr "" + +#: cups/localize.c:343 +msgid "Ink/toner waste bin full!" +msgstr "" + +#: ppdc/sample.c:246 +msgid "Installable Options" +msgstr "" + +#: ppdc/sample.c:249 +msgid "Installed" +msgstr "" + +#: ppdc/sample.c:264 +msgid "IntelliBar Label Printer" +msgstr "" + +#: ppdc/sample.c:263 +msgid "Intellitech" +msgstr "" + +#: cups/localize.c:321 +msgid "Interlock open." +msgstr "" + +#: cups/http-support.c:1245 +msgid "Internal Server Error" +msgstr "" + +#: cups/ppd.c:341 +msgid "Internal error" +msgstr "" + +#: ppdc/sample.c:130 +msgid "Internet Postage 2-Part" +msgstr "" + +#: ppdc/sample.c:139 +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "" + +#: ppdc/sample.c:131 +msgid "Internet Postage 3-Part" +msgstr "" + +#: ppdc/sample.c:140 +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "" + +#: backend/ipp.c:206 +msgid "Internet Printing Protocol" +msgstr "" + +#: ppdc/sample.c:68 +msgid "Invite Envelope" +msgstr "" + +#: ppdc/sample.c:72 +msgid "Italian Envelope" +msgstr "" + +#: cups/ppd.c:1348 +msgid "JCL" +msgstr "" + +#: scheduler/ipp.c:9442 +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "" + +#: scheduler/ipp.c:3682 scheduler/ipp.c:4050 scheduler/ipp.c:6668 +#: scheduler/ipp.c:6810 scheduler/ipp.c:7921 scheduler/ipp.c:8085 +#: scheduler/ipp.c:8295 scheduler/ipp.c:8340 scheduler/ipp.c:9184 +#: scheduler/ipp.c:9410 scheduler/ipp.c:9765 scheduler/ipp.c:10341 +#, c-format +msgid "Job #%d does not exist!" +msgstr "" + +#: scheduler/ipp.c:4082 +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "" + +#: scheduler/ipp.c:4076 +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "" + +#: scheduler/ipp.c:4088 +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "" + +#: scheduler/ipp.c:8382 scheduler/ipp.c:10356 +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "" + +#: scheduler/ipp.c:9424 +#, c-format +msgid "Job #%d is not complete!" +msgstr "" + +#: scheduler/ipp.c:3697 +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "" + +#: scheduler/ipp.c:9198 +#, c-format +msgid "Job #%d is not held!" +msgstr "" + +#: scheduler/ipp.c:7899 +#, c-format +msgid "Job #%s does not exist!" +msgstr "" + +#: scheduler/ipp.c:6295 +#, c-format +msgid "Job %d not found!" +msgstr "" + +#: cgi-bin/ipp-var.c:1050 +msgid "Job Completed" +msgstr "" + +#: cgi-bin/ipp-var.c:1048 +msgid "Job Created" +msgstr "" + +#: filter/bannertops.c:623 +msgid "Job ID: " +msgstr "" + +#: cgi-bin/ipp-var.c:1054 +msgid "Job Options Changed" +msgstr "" + +#: cgi-bin/ipp-var.c:1052 +msgid "Job Stopped" +msgstr "" + +#: filter/bannertops.c:631 +msgid "Job UUID: " +msgstr "" + +#: scheduler/ipp.c:10439 +msgid "Job is completed and cannot be changed." +msgstr "" + +#: cgi-bin/jobs.c:197 +msgid "Job operation failed:" +msgstr "" + +#: scheduler/ipp.c:10475 scheduler/ipp.c:10494 scheduler/ipp.c:10505 +msgid "Job state cannot be changed." +msgstr "" + +#: scheduler/ipp.c:9289 +msgid "Job subscriptions cannot be renewed!" +msgstr "" + +#: cgi-bin/jobs.c:102 cgi-bin/jobs.c:113 cgi-bin/jobs.c:194 +msgid "Jobs" +msgstr "" + +#: ppdc/sample.c:73 +msgid "Kaku2 Envelope" +msgstr "" + +#: ppdc/sample.c:74 +msgid "Kaku3 Envelope" +msgstr "" + +#: backend/lpd.c:178 +msgid "LPD/LPR Host or Printer" +msgstr "" + +#: ppdc/sample.c:202 +msgid "Label Printer" +msgstr "" + +#: ppdc/sample.c:417 +msgid "Label Top" +msgstr "" + +#: scheduler/ipp.c:2150 scheduler/ipp.c:6218 +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "" + +#: ppdc/sample.c:127 +msgid "Large Address" +msgstr "" + +#: ppdc/sample.c:136 +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "" + +#: ppdc/sample.c:262 +msgid "LaserJet Series PCL 4/5" +msgstr "" + +#: ppdc/sample.c:208 +msgid "Light" +msgstr "" + +#: cups/ppd.c:349 +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "" + +#: cgi-bin/admin.c:2368 +msgid "List Available Printers" +msgstr "" + +#: filter/bannertops.c:744 +msgid "Location: " +msgstr "" + +#: ppdc/sample.c:244 +msgid "Long-Edge (Portrait)" +msgstr "" + +#: filter/bannertops.c:753 +msgid "Make and Model: " +msgstr "" + +#: ppdc/sample.c:240 +msgid "Manual Feed" +msgstr "" + +#: filter/bannertops.c:780 +msgid "Media Dimensions: " +msgstr "" + +#: filter/bannertops.c:800 +msgid "Media Limits: " +msgstr "" + +#: filter/bannertops.c:769 +msgid "Media Name: " +msgstr "" + +#: cups/ppd.c:747 cups/ppd.c:1285 +msgid "Media Size" +msgstr "" + +#: cups/ppd.c:751 cups/ppd.c:1289 ppdc/sample.c:234 +msgid "Media Source" +msgstr "" + +#: ppdc/sample.c:335 +msgid "Media Tracking" +msgstr "" + +#: cups/ppd.c:749 cups/ppd.c:1287 ppdc/sample.c:256 +msgid "Media Type" +msgstr "" + +#: cups/localize.c:310 +msgid "Media jam!" +msgstr "" + +#: cups/localize.c:327 +msgid "Media tray almost empty." +msgstr "" + +#: cups/localize.c:329 +msgid "Media tray empty!" +msgstr "" + +#: cups/localize.c:325 +msgid "Media tray missing!" +msgstr "" + +#: cups/localize.c:308 +msgid "Media tray needs to be filled." +msgstr "" + +#: ppdc/sample.c:209 +msgid "Medium" +msgstr "" + +#: cups/ppd.c:338 +msgid "Memory allocation error" +msgstr "" + +#: cups/ppd.c:339 +msgid "Missing PPD-Adobe-4.x header" +msgstr "" + +#: cups/ppd.c:348 +msgid "Missing asterisk in column 1" +msgstr "" + +#: scheduler/ipp.c:6690 +msgid "Missing document-number attribute!" +msgstr "" + +#: cups/adminutil.c:284 +#, c-format +msgid "Missing double quote on line %d!" +msgstr "" + +#: cgi-bin/admin.c:2080 cgi-bin/admin.c:2165 cgi-bin/admin.c:2801 +#: cgi-bin/admin.c:3055 cgi-bin/admin.c:3166 cgi-bin/admin.c:3844 +msgid "Missing form variable!" +msgstr "" + +#: scheduler/ipp.c:7090 +msgid "Missing notify-subscription-ids attribute!" +msgstr "" + +#: scheduler/ipp.c:3820 +msgid "Missing requesting-user-name attribute!" +msgstr "" + +#: scheduler/ipp.c:477 +msgid "Missing required attributes!" +msgstr "" + +#: cups/adminutil.c:265 +#, c-format +msgid "Missing value on line %d!" +msgstr "" + +#: cups/ppd.c:340 +msgid "Missing value string" +msgstr "" + +#: systemv/lpinfo.c:475 +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" + +#: cgi-bin/admin.c:480 +msgid "Modify Class" +msgstr "" + +#: cgi-bin/admin.c:778 +msgid "Modify Printer" +msgstr "" + +#: ppdc/sample.c:111 +msgid "Monarch" +msgstr "" + +#: ppdc/sample.c:75 +msgid "Monarch Envelope" +msgstr "" + +#: cgi-bin/ipp-var.c:421 cgi-bin/ipp-var.c:512 +msgid "Move All Jobs" +msgstr "" + +#: cgi-bin/ipp-var.c:360 cgi-bin/ipp-var.c:419 cgi-bin/ipp-var.c:510 +msgid "Move Job" +msgstr "" + +#: cups/http-support.c:1202 +msgid "Moved Permanently" +msgstr "" + +#: backend/ipp.c:1092 +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "" + +#: backend/ipp.c:1086 +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "" + +#: cups/ppd.c:337 +msgid "NULL PPD file pointer" +msgstr "" + +#: cups/snmp.c:1054 +msgid "Name OID uses indefinite length" +msgstr "" + +#: scheduler/ipp.c:1196 +msgid "Nested classes are not allowed!" +msgstr "" + +#: ppdc/sample.c:401 +msgid "Never" +msgstr "" + +#: ppdc/sample.c:228 +msgid "New Stylus Color Series" +msgstr "" + +#: ppdc/sample.c:230 +msgid "New Stylus Photo Series" +msgstr "" + +#: cups/ppd.c:1877 +msgid "No" +msgstr "" + +#: cups/http-support.c:1199 +msgid "No Content" +msgstr "" + +#: cups/util.c:1289 +msgid "No PPD name!" +msgstr "" + +#: cups/snmp.c:1048 +msgid "No VarBind SEQUENCE" +msgstr "" + +#: cups/adminutil.c:799 +msgid "No Windows printer drivers are installed!" +msgstr "" + +#: cups/request.c:509 cups/request.c:775 +msgid "No active connection" +msgstr "" + +#: scheduler/ipp.c:3998 +#, c-format +msgid "No active jobs on %s!" +msgstr "" + +#: scheduler/ipp.c:318 +msgid "No attributes in request!" +msgstr "" + +#: scheduler/ipp.c:3725 +msgid "No authentication information provided!" +msgstr "" + +#: cups/snmp.c:1005 +msgid "No community name" +msgstr "" + +#: scheduler/ipp.c:6490 +msgid "No default printer" +msgstr "" + +#: cgi-bin/ipp-var.c:432 scheduler/ipp.c:7666 +msgid "No destinations added." +msgstr "" + +#: cups/snmp.c:1035 +msgid "No error-index" +msgstr "" + +#: cups/snmp.c:1027 +msgid "No error-status" +msgstr "" + +#: scheduler/ipp.c:8582 scheduler/ipp.c:9817 +msgid "No file!?!" +msgstr "" + +#: cups/util.c:924 +msgid "No modification time!" +msgstr "" + +#: cups/snmp.c:1052 +msgid "No name OID" +msgstr "" + +#: cups/util.c:918 +msgid "No printer name!" +msgstr "" + +#: cups/util.c:1840 +msgid "No printer-uri found for class!" +msgstr "" + +#: cups/util.c:1855 +msgid "No printer-uri found!" +msgstr "" + +#: scheduler/ipp.c:6875 +msgid "No printer-uri in request!" +msgstr "" + +#: cups/snmp.c:1019 +msgid "No request-id" +msgstr "" + +#: scheduler/ipp.c:6103 +msgid "No subscription attributes in request!" +msgstr "" + +#: scheduler/ipp.c:7984 +msgid "No subscriptions found." +msgstr "" + +#: cups/snmp.c:1043 +msgid "No variable-bindings SEQUENCE" +msgstr "" + +#: cups/snmp.c:998 +msgid "No version number" +msgstr "" + +#: ppdc/sample.c:338 +msgid "Non-continuous (Mark sensing)" +msgstr "" + +#: ppdc/sample.c:337 +msgid "Non-continuous (Web sensing)" +msgstr "" + +#: ppdc/sample.c:210 +msgid "Normal" +msgstr "" + +#: cups/http-support.c:1221 +msgid "Not Found" +msgstr "" + +#: cups/http-support.c:1233 +msgid "Not Implemented" +msgstr "" + +#: ppdc/sample.c:248 +msgid "Not Installed" +msgstr "" + +#: cups/http-support.c:1208 +msgid "Not Modified" +msgstr "" + +#: cups/http-support.c:1236 +msgid "Not Supported" +msgstr "" + +#: scheduler/ipp.c:1527 +msgid "Not allowed to print." +msgstr "" + +#: ppdc/sample.c:112 +msgid "Note" +msgstr "" + +#: cups/http-support.c:1190 cups/ppd.c:335 +msgid "OK" +msgstr "" + +#: cups/localize.c:349 +msgid "OPC almost at end-of-life." +msgstr "" + +#: cups/localize.c:351 +msgid "OPC at end-of-life!" +msgstr "" + +#: ppdc/sample.c:243 +msgid "Off (1-Sided)" +msgstr "" + +#: ppdc/sample.c:332 +msgid "Oki" +msgstr "" + +#: cgi-bin/help.c:89 cgi-bin/help.c:130 cgi-bin/help.c:140 cgi-bin/help.c:171 +msgid "Online Help" +msgstr "" + +#: cups/adminutil.c:985 +#, c-format +msgid "Open of %s failed: %s" +msgstr "" + +#: cups/ppd.c:343 +msgid "OpenGroup without a CloseGroup first" +msgstr "" + +#: cups/ppd.c:345 +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "" + +#: cgi-bin/admin.c:3615 +msgid "Operation Policy" +msgstr "" + +#: cgi-bin/admin.c:3292 cgi-bin/admin.c:3352 +msgid "Options Installed" +msgstr "" + +#: filter/bannertops.c:674 +msgid "Options: " +msgstr "" + +#: cups/localize.c:317 +msgid "Out of toner!" +msgstr "" + +#: cups/ppd.c:753 cups/ppd.c:1291 +msgid "Output Mode" +msgstr "" + +#: cups/localize.c:333 +msgid "Output bin almost full." +msgstr "" + +#: cups/localize.c:335 +msgid "Output bin full!" +msgstr "" + +#: systemv/lpstat.c:1191 systemv/lpstat.c:1195 +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "" + +#: systemv/lpstat.c:1185 +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "" + +#: systemv/lpstat.c:1209 systemv/lpstat.c:1213 +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "" + +#: systemv/lpstat.c:1203 +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" + +#: cups/localize.c:331 +msgid "Output tray missing!" +msgstr "" + +#: systemv/cupstestdsc.c:403 +msgid "PASS\n" +msgstr "" + +#: ppdc/sample.c:232 +msgid "PCL Laser Printer" +msgstr "" + +#: ppdc/sample.c:77 +msgid "PRC1 Envelope" +msgstr "" + +#: ppdc/sample.c:86 +msgid "PRC10 Envelope" +msgstr "" + +#: ppdc/sample.c:114 +msgid "PRC16K" +msgstr "" + +#: ppdc/sample.c:78 +msgid "PRC2 Envelope" +msgstr "" + +#: ppdc/sample.c:79 +msgid "PRC3 Envelope" +msgstr "" + +#: ppdc/sample.c:115 +msgid "PRC32K" +msgstr "" + +#: ppdc/sample.c:116 +msgid "PRC32K (Oversize)" +msgstr "" + +#: ppdc/sample.c:80 +msgid "PRC4 Envelope" +msgstr "" + +#: ppdc/sample.c:81 +msgid "PRC5 Envelope" +msgstr "" + +#: ppdc/sample.c:82 +msgid "PRC6 Envelope" +msgstr "" + +#: ppdc/sample.c:83 +msgid "PRC7 Envelope" +msgstr "" + +#: ppdc/sample.c:84 +msgid "PRC8 Envelope" +msgstr "" + +#: ppdc/sample.c:85 +msgid "PRC9 Envelope" +msgstr "" + +#: cups/snmp.c:1015 +msgid "Packet does not contain a Get-Response-PDU" +msgstr "" + +#: cups/snmp.c:994 +msgid "Packet does not start with SEQUENCE" +msgstr "" + +#: ppdc/sample.c:331 +msgid "ParamCustominCutInterval" +msgstr "" + +#: ppdc/sample.c:329 +msgid "ParamCustominTearInterval" +msgstr "" + +#: cups/auth.c:158 +#, c-format +msgid "Password for %s on %s? " +msgstr "" + +#: systemv/cupsaddsmb.c:256 +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "" + +#: cgi-bin/classes.c:152 +msgid "Pause Class" +msgstr "" + +#: cgi-bin/printers.c:155 +msgid "Pause Printer" +msgstr "" + +#: ppdc/sample.c:419 +msgid "Peel-Off" +msgstr "" + +#: ppdc/sample.c:76 +msgid "Personal Envelope" +msgstr "" + +#: ppdc/sample.c:123 +msgid "Photo" +msgstr "" + +#: ppdc/sample.c:124 +msgid "Photo Labels" +msgstr "" + +#: ppdc/sample.c:257 +msgid "Plain Paper" +msgstr "" + +#: cgi-bin/admin.c:3310 cgi-bin/admin.c:3564 +msgid "Policies" +msgstr "" + +#: cgi-bin/admin.c:3317 cgi-bin/admin.c:3633 cgi-bin/admin.c:3646 +msgid "Port Monitor" +msgstr "" + +#: ppdc/sample.c:250 +msgid "PostScript Printer" +msgstr "" + +#: ppdc/sample.c:113 +msgid "Postcard" +msgstr "" + +#: ppdc/sample.c:266 +msgid "Print Density" +msgstr "" + +#: cups/notify.c:82 +msgid "Print Job:" +msgstr "" + +#: ppdc/sample.c:311 +msgid "Print Mode" +msgstr "" + +#: ppdc/sample.c:354 +msgid "Print Rate" +msgstr "" + +#: cgi-bin/printers.c:164 +msgid "Print Self-Test Page" +msgstr "" + +#: ppdc/sample.c:298 +msgid "Print Speed" +msgstr "" + +#: cgi-bin/ipp-var.c:787 +msgid "Print Test Page" +msgstr "" + +#: ppdc/sample.c:327 +msgid "Print and Cut" +msgstr "" + +#: ppdc/sample.c:315 +msgid "Print and Tear" +msgstr "" + +#: filter/bannertops.c:648 +msgid "Printed For: " +msgstr "" + +#: filter/bannertops.c:656 +msgid "Printed From: " +msgstr "" + +#: filter/bannertops.c:876 +msgid "Printed On: " +msgstr "" + +#: cgi-bin/ipp-var.c:1042 +msgid "Printer Added" +msgstr "" + +#: ppdc/sample.c:235 +msgid "Printer Default" +msgstr "" + +#: cgi-bin/ipp-var.c:1046 +msgid "Printer Deleted" +msgstr "" + +#: cgi-bin/ipp-var.c:1044 +msgid "Printer Modified" +msgstr "" + +#: filter/bannertops.c:614 +msgid "Printer Name: " +msgstr "" + +#: cgi-bin/ipp-var.c:1040 +msgid "Printer Paused" +msgstr "" + +#: ppdc/sample.c:265 +msgid "Printer Settings" +msgstr "" + +#: cups/localize.c:313 +msgid "Printer offline." +msgstr "" + +#: cups/notify.c:126 +msgid "Printer:" +msgstr "" + +#: cgi-bin/printers.c:189 cgi-bin/printers.c:317 +msgid "Printers" +msgstr "" + +#: cgi-bin/classes.c:158 cgi-bin/printers.c:161 +msgid "Purge Jobs" +msgstr "" + +#: ppdc/sample.c:117 +msgid "Quarto" +msgstr "" + +#: scheduler/ipp.c:1522 +msgid "Quota limit reached." +msgstr "" + +#: berkeley/lpq.c:507 +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" + +#: berkeley/lpq.c:503 +msgid "Rank Owner Pri Job Files Total Size\n" +msgstr "" + +#: cgi-bin/classes.c:156 cgi-bin/printers.c:159 +msgid "Reject Jobs" +msgstr "" + +#: ppdc/sample.c:399 +msgid "Reprint After Error" +msgstr "" + +#: cups/http-support.c:1224 +msgid "Request Entity Too Large" +msgstr "" + +#: cups/ppd.c:755 cups/ppd.c:1293 ppdc/sample.c:203 +msgid "Resolution" +msgstr "" + +#: cgi-bin/classes.c:150 +msgid "Resume Class" +msgstr "" + +#: cgi-bin/printers.c:152 +msgid "Resume Printer" +msgstr "" + +#: ppdc/sample.c:128 +msgid "Return Address" +msgstr "" + +#: ppdc/sample.c:137 +msgid "Return Address - 3/4 x 2\"" +msgstr "" + +#: ppdc/sample.c:420 +msgid "Rewind" +msgstr "" + +#: cups/adminutil.c:2167 +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "" + +#: backend/scsi-irix.c:70 backend/scsi-linux.c:83 +msgid "SCSI Printer" +msgstr "" + +#: cups/snmp.c:996 +msgid "SEQUENCE uses indefinite length" +msgstr "" + +#: cups/http-support.c:1205 +msgid "See Other" +msgstr "" + +#: backend/serial.c:784 backend/serial.c:943 backend/serial.c:1065 +#: backend/serial.c:1159 +#, c-format +msgid "Serial Port #%d" +msgstr "" + +#: cgi-bin/ipp-var.c:1056 +msgid "Server Restarted" +msgstr "" + +#: cgi-bin/ipp-var.c:1062 +msgid "Server Security Auditing" +msgstr "" + +#: cgi-bin/ipp-var.c:1058 +msgid "Server Started" +msgstr "" + +#: cgi-bin/ipp-var.c:1060 +msgid "Server Stopped" +msgstr "" + +#: cups/http-support.c:1242 +msgid "Service Unavailable" +msgstr "" + +#: cgi-bin/admin.c:2802 cgi-bin/admin.c:2848 cgi-bin/admin.c:3005 +#: cgi-bin/admin.c:3024 +msgid "Set Allowed Users" +msgstr "" + +#: cgi-bin/admin.c:3051 +msgid "Set As Server Default" +msgstr "" + +#: cgi-bin/admin.c:3151 +msgid "Set Class Options" +msgstr "" + +#: cgi-bin/admin.c:3151 cgi-bin/admin.c:3320 cgi-bin/admin.c:3675 +msgid "Set Printer Options" +msgstr "" + +#: cgi-bin/admin.c:3845 cgi-bin/admin.c:3889 cgi-bin/admin.c:3907 +msgid "Set Publishing" +msgstr "" + +#: ppdc/sample.c:129 +msgid "Shipping Address" +msgstr "" + +#: ppdc/sample.c:138 +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "" + +#: ppdc/sample.c:245 +msgid "Short-Edge (Landscape)" +msgstr "" + +#: ppdc/sample.c:259 +msgid "Special Paper" +msgstr "" + +#: ppdc/sample.c:312 +msgid "Standard" +msgstr "" + +#: cgi-bin/admin.c:3538 +msgid "Starting Banner" +msgstr "" + +#: ppdc/sample.c:118 +msgid "Statement" +msgstr "" + +#: ppdc/sample.c:223 +msgid "Stylus Color Series" +msgstr "" + +#: ppdc/sample.c:229 +msgid "Stylus Photo Series" +msgstr "" + +#: ppdc/sample.c:119 +msgid "Super A" +msgstr "" + +#: ppdc/sample.c:120 +msgid "Super B" +msgstr "" + +#: ppdc/sample.c:125 +msgid "Super B/A3" +msgstr "" + +#: cups/http-support.c:1187 +msgid "Switching Protocols" +msgstr "" + +#: ppdc/sample.c:121 +msgid "Tabloid" +msgstr "" + +#: ppdc/sample.c:122 +msgid "Tabloid (Oversize)" +msgstr "" + +#: ppdc/sample.c:313 +msgid "Tear" +msgstr "" + +#: ppdc/sample.c:418 +msgid "Tear-Off" +msgstr "" + +#: ppdc/sample.c:359 +msgid "Tear-Off Adjust Position" +msgstr "" + +#: scheduler/ipp.c:7337 +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "" + +#: scheduler/ipp.c:7324 +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "" + +#: cgi-bin/admin.c:644 +msgid "The class name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." +msgstr "" + +#: scheduler/ipp.c:2177 +msgid "The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" + +#: scheduler/ipp.c:2160 scheduler/ipp.c:6228 +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "" + +#: cgi-bin/admin.c:827 +msgid "The printer name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." +msgstr "" + +#: scheduler/ipp.c:1357 +msgid "The printer or class is not shared!" +msgstr "" + +#: scheduler/ipp.c:884 scheduler/ipp.c:1190 scheduler/ipp.c:3856 +#: scheduler/ipp.c:3964 scheduler/ipp.c:5759 scheduler/ipp.c:6062 +#: scheduler/ipp.c:6375 scheduler/ipp.c:6912 scheduler/ipp.c:7542 +#: scheduler/ipp.c:7598 scheduler/ipp.c:7911 scheduler/ipp.c:8153 +#: scheduler/ipp.c:8243 scheduler/ipp.c:8276 scheduler/ipp.c:8597 +#: scheduler/ipp.c:8988 scheduler/ipp.c:9068 scheduler/ipp.c:10209 +#: scheduler/ipp.c:10665 scheduler/ipp.c:10994 scheduler/ipp.c:11061 +#: scheduler/ipp.c:11344 +msgid "The printer or class was not found." +msgstr "" + +#: scheduler/ipp.c:990 scheduler/ipp.c:2367 +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "" + +#: scheduler/ipp.c:3801 +msgid "The printer-uri attribute is required!" +msgstr "" + +#: scheduler/ipp.c:974 +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" + +#: scheduler/ipp.c:2351 +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" + +#: cgi-bin/admin.c:385 +msgid "The subscription name may not contain spaces, slashes (/), question marks (?), or the pound sign (#)." +msgstr "" + +#: scheduler/ipp.c:6305 +msgid "There are too many subscriptions." +msgstr "" + +#: ppdc/sample.c:406 +msgid "Thermal Transfer Media" +msgstr "" + +#: filter/bannertops.c:640 +msgid "Title: " +msgstr "" + +#: cups/localize.c:315 +msgid "Toner low." +msgstr "" + +#: scheduler/ipp.c:1516 +msgid "Too many active jobs." +msgstr "" + +#: scheduler/ipp.c:1454 +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "" + +#: scheduler/ipp.c:2672 +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "" + +#: ppdc/sample.c:260 +msgid "Transparency" +msgstr "" + +#: ppdc/sample.c:255 +msgid "Tray" +msgstr "" + +#: ppdc/sample.c:236 +msgid "Tray 1" +msgstr "" + +#: ppdc/sample.c:237 +msgid "Tray 2" +msgstr "" + +#: ppdc/sample.c:238 +msgid "Tray 3" +msgstr "" + +#: ppdc/sample.c:239 +msgid "Tray 4" +msgstr "" + +#: cups/http-support.c:1227 +msgid "URI Too Long" +msgstr "" + +#: ppdc/sample.c:88 +msgid "US Executive" +msgstr "" + +#: ppdc/sample.c:91 +msgid "US Fanfold" +msgstr "" + +#: ppdc/sample.c:105 +msgid "US Ledger" +msgstr "" + +#: ppdc/sample.c:106 +msgid "US Legal" +msgstr "" + +#: ppdc/sample.c:107 +msgid "US Legal (Oversize)" +msgstr "" + +#: ppdc/sample.c:108 +msgid "US Letter" +msgstr "" + +#: ppdc/sample.c:109 +msgid "US Letter (Oversize)" +msgstr "" + +#: ppdc/sample.c:110 +msgid "US Letter (Small)" +msgstr "" + +#: backend/serial.c:797 +#, c-format +msgid "USB Serial Port #%d" +msgstr "" + +#: cgi-bin/admin.c:1933 cgi-bin/admin.c:1946 cgi-bin/admin.c:1970 +msgid "Unable to access cupsd.conf file:" +msgstr "" + +#: cgi-bin/admin.c:437 +msgid "Unable to add RSS subscription:" +msgstr "" + +#: cgi-bin/admin.c:710 +msgid "Unable to add class:" +msgstr "" + +#: scheduler/ipp.c:1560 +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "" + +#: cgi-bin/admin.c:959 cgi-bin/admin.c:1320 +msgid "Unable to add printer:" +msgstr "" + +#: scheduler/ipp.c:1302 +msgid "Unable to allocate memory for file types!" +msgstr "" + +#: cgi-bin/admin.c:1426 +msgid "Unable to cancel RSS subscription:" +msgstr "" + +#: cgi-bin/admin.c:3890 +msgid "Unable to change printer-is-shared attribute:" +msgstr "" + +#: cgi-bin/admin.c:3006 +msgid "Unable to change printer:" +msgstr "" + +#: cgi-bin/admin.c:1610 cgi-bin/admin.c:1774 +msgid "Unable to change server settings:" +msgstr "" + +#: cups/adminutil.c:941 cups/util.c:1652 +msgid "Unable to connect to host." +msgstr "" + +#: cups/adminutil.c:737 +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" + +#: cups/adminutil.c:702 +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" + +#: cups/adminutil.c:533 +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "" + +#: scheduler/ipp.c:2788 +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "" + +#: scheduler/ipp.c:2854 +msgid "Unable to copy PPD file!" +msgstr "" + +#: cups/adminutil.c:498 +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" + +#: cups/adminutil.c:621 +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" + +#: scheduler/ipp.c:2765 +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "" + +#: cups/util.c:607 cups/util.c:1711 +msgid "Unable to create printer-uri!" +msgstr "" + +#: cgi-bin/admin.c:1824 cgi-bin/admin.c:1836 +msgid "Unable to create temporary file:" +msgstr "" + +#: cgi-bin/admin.c:2127 +msgid "Unable to delete class:" +msgstr "" + +#: cgi-bin/admin.c:2212 +msgid "Unable to delete printer:" +msgstr "" + +#: cgi-bin/classes.c:245 cgi-bin/printers.c:254 +msgid "Unable to do maintenance command:" +msgstr "" + +#: cgi-bin/admin.c:1948 +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "" + +#: cgi-bin/ipp-var.c:361 +msgid "Unable to find destination for job!" +msgstr "" + +#: cups/http-support.c:1509 +msgid "Unable to find printer!\n" +msgstr "" + +#: cgi-bin/classes.c:435 +msgid "Unable to get class list:" +msgstr "" + +#: cgi-bin/classes.c:534 +msgid "Unable to get class status:" +msgstr "" + +#: cgi-bin/admin.c:1221 +msgid "Unable to get list of printer drivers:" +msgstr "" + +#: cgi-bin/admin.c:2856 +msgid "Unable to get printer attributes:" +msgstr "" + +#: cgi-bin/printers.c:452 +msgid "Unable to get printer list:" +msgstr "" + +#: cgi-bin/printers.c:554 +msgid "Unable to get printer status:" +msgstr "" + +#: cups/adminutil.c:576 cups/adminutil.c:780 +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" + +#: cups/adminutil.c:650 +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" + +#: cgi-bin/admin.c:709 +msgid "Unable to modify class:" +msgstr "" + +#: cgi-bin/admin.c:958 cgi-bin/admin.c:1319 +msgid "Unable to modify printer:" +msgstr "" + +#: cgi-bin/ipp-var.c:428 cgi-bin/ipp-var.c:517 +msgid "Unable to move job" +msgstr "" + +#: cgi-bin/ipp-var.c:430 cgi-bin/ipp-var.c:519 +msgid "Unable to move jobs" +msgstr "" + +#: cups/ppd.c:336 +msgid "Unable to open PPD file" +msgstr "" + +#: cgi-bin/admin.c:3202 +msgid "Unable to open PPD file:" +msgstr "" + +#: cgi-bin/admin.c:2582 +msgid "Unable to open cupsd.conf file:" +msgstr "" + +#: scheduler/ipp.c:6710 +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "" + +#: cgi-bin/ipp-var.c:790 +msgid "Unable to print test page:" +msgstr "" + +#: cups/adminutil.c:2203 +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "" + +#: cgi-bin/ipp-var.c:594 cgi-bin/ipp-var.c:614 +msgid "Unable to send command to printer driver!" +msgstr "" + +#: cups/adminutil.c:832 +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "" + +#: cgi-bin/admin.c:3791 +msgid "Unable to set options:" +msgstr "" + +#: cgi-bin/admin.c:3093 +msgid "Unable to set server default:" +msgstr "" + +#: cgi-bin/admin.c:1886 +msgid "Unable to upload cupsd.conf file:" +msgstr "" + +#: backend/usb-darwin.c:1953 backend/usb-darwin.c:1975 +msgid "Unable to use legacy USB class driver!\n" +msgstr "" + +#: cups/http-support.c:1215 +msgid "Unauthorized" +msgstr "" + +#: cgi-bin/admin.c:3491 +msgid "Units" +msgstr "" + +#: cups/http-support.c:1249 cups/ppd.c:360 +msgid "Unknown" +msgstr "" + +#: scheduler/ipp.c:10867 +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "" + +#: scheduler/ipp.c:10850 +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "" + +#: scheduler/ipp.c:418 +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:8563 scheduler/ipp.c:9798 +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:11297 +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "" + +#: scheduler/ipp.c:11325 +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "" + +#: scheduler/ipp.c:1420 scheduler/ipp.c:9932 +#, c-format +msgid "Unsupported format '%s'!" +msgstr "" + +#: scheduler/ipp.c:8697 scheduler/ipp.c:9915 +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "" + +#: cups/snmp.c:1113 +msgid "Unsupported value type" +msgstr "" + +#: cups/http-support.c:1230 +msgid "Upgrade Required" +msgstr "" + +#: systemv/lpadmin.c:805 +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" + +#: filter/pdftops.c:103 +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "" + +#: backend/ipp.c:212 backend/lpd.c:184 backend/pap.c:228 +#: backend/parallel.c:127 backend/scsi.c:157 backend/serial.c:165 +#: backend/socket.c:132 backend/usb.c:183 filter/bannertops.c:118 +#: filter/hpgl-main.c:148 filter/imagetops.c:115 filter/imagetoraster.c:207 +#: filter/pstops.c:255 filter/rastertoepson.c:988 filter/rastertohp.c:713 +#: filter/rastertolabel.c:1135 filter/textcommon.c:518 +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "" + +#: filter/gziptoany.c:53 +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "" + +#: scheduler/cupsfilter.c:1329 +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +#: systemv/cupsaddsmb.c:286 +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" + +#: systemv/cupsctl.c:202 +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" + +#: scheduler/main.c:2128 +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" + +#: scheduler/cupsfilter.c:1316 +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +#: systemv/cupstestdsc.c:430 +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript itself.\n" +msgstr "" + +#: systemv/cupstestppd.c:3483 +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +#: systemv/lpmove.c:132 +msgid "Usage: lpmove job/src dest\n" +msgstr "" + +#: systemv/lpoptions.c:540 +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" + +#: systemv/lppasswd.c:493 +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "" + +#: systemv/lppasswd.c:496 +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" + +#: berkeley/lpq.c:662 +msgid "Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" + +#: ppdc/ppdc.cxx:408 +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" + +#: ppdc/ppdhtml.cxx:173 +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" + +#: ppdc/ppdi.cxx:129 +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" + +#: ppdc/ppdmerge.cxx:370 +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" + +#: ppdc/ppdpo.cxx:254 +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" + +#: backend/snmp.c:224 +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "" + +#: cups/snmp.c:1065 +msgid "Value uses indefinite length" +msgstr "" + +#: cups/snmp.c:1050 +msgid "VarBind uses indefinite length" +msgstr "" + +#: cups/snmp.c:1000 +msgid "Version uses indefinite length" +msgstr "" + +#: backend/pap.c:328 +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "" + +#: backend/pap.c:1460 backend/usb-darwin.c:1816 +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "" + +#: backend/network.c:83 backend/pap.c:1293 backend/parallel.c:638 +#: backend/serial.c:1297 backend/usb-libusb.c:747 backend/usb-unix.c:583 +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "" + +#: filter/pstops.c:2237 +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" + +#: backend/pap.c:503 +msgid "WARNING: Printer not responding\n" +msgstr "" + +#: backend/pap.c:831 backend/pap.c:854 +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "" + +#: backend/lpd.c:618 +#, c-format +msgid "WARNING: Remote host did not respond with command status byte after %d seconds!\n" +msgstr "" + +#: backend/lpd.c:1042 backend/lpd.c:1189 +#, c-format +msgid "WARNING: Remote host did not respond with control status byte after %d seconds!\n" +msgstr "" + +#: backend/lpd.c:1134 +#, c-format +msgid "WARNING: Remote host did not respond with data status byte after %d seconds!\n" +msgstr "" + +#: backend/scsi-irix.c:210 backend/scsi-linux.c:228 +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "" + +#: filter/pstops.c:1096 +msgid "WARNING: This document does not conform to the Adobe Document Structuring Conventions and may not print correctly!\n" +msgstr "" + +#: backend/pap.c:492 +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "" + +#: backend/pap.c:637 +msgid "WARNING: Unable to send PAP status request" +msgstr "" + +#: backend/pap.c:867 +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "" + +#: backend/pap.c:872 +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "" + +#: filter/pstops.c:2245 +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "" + +#: filter/pstops.c:2230 +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "" + +#: backend/serial.c:380 +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "" + +#: backend/pap.c:1474 +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "" + +#: backend/ipp.c:588 backend/ipp.c:723 backend/lpd.c:855 backend/socket.c:317 +#, c-format +msgid "WARNING: recoverable: Network host '%s' is busy; will retry in %d seconds...\n" +msgstr "" + +#: cups/adminutil.c:804 +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "" + +#: cups/ppd.c:1875 +msgid "Yes" +msgstr "" + +#: scheduler/client.c:2402 +#, c-format +msgid "You must access this page using the URL https://%s:%d%s." +msgstr "" + +#: ppdc/sample.c:87 +msgid "You4 Envelope" +msgstr "" + +#: ppdc/sample.c:410 +msgid "ZPL Label Printer" +msgstr "" + +#: ppdc/sample.c:333 +msgid "Zebra" +msgstr "" + +#: cups/notify.c:102 +msgid "aborted" +msgstr "" + +#: cups/notify.c:99 +msgid "canceled" +msgstr "" + +#: cups/notify.c:105 +msgid "completed" +msgstr "" + +#: scheduler/cupsfilter.c:342 +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "" + +#: scheduler/ipp.c:6583 +msgid "cups-deviced failed to execute." +msgstr "" + +#: scheduler/ipp.c:7259 scheduler/ipp.c:7509 +msgid "cups-driverd failed to execute." +msgstr "" + +#: systemv/cupsaddsmb.c:236 +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "" + +#: systemv/cupsctl.c:153 +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "" + +#: systemv/cupsctl.c:196 +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "" + +#: systemv/cupsctl.c:198 +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "" + +#: scheduler/main.c:200 +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "" + +#: scheduler/main.c:232 scheduler/main.c:239 +msgid "cupsd: Unable to get current directory!\n" +msgstr "" + +#: scheduler/main.c:303 +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "" + +#: scheduler/main.c:296 +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "" + +#: scheduler/main.c:266 +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" + +#: scheduler/cupsfilter.c:1094 +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "" + +#: scheduler/cupsfilter.c:1088 +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "" + +#: scheduler/cupsfilter.c:350 +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "" + +#: scheduler/cupsfilter.c:1136 +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "" + +#: systemv/cupstestppd.c:389 +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "" + +#: systemv/cupstestppd.c:405 +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "" + +#: systemv/lpstat.c:1231 systemv/lpstat.c:1234 systemv/lpstat.c:1237 +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "" + +#: systemv/lpstat.c:1218 systemv/lpstat.c:1221 systemv/lpstat.c:1224 +#, c-format +msgid "device for %s: %s\n" +msgstr "" + +#: cups/snmp.c:1037 +msgid "error-index uses indefinite length" +msgstr "" + +#: cups/snmp.c:1029 +msgid "error-status uses indefinite length" +msgstr "" + +#: cups/notify.c:90 +msgid "held" +msgstr "" + +#: berkeley/lpc.c:214 +msgid "help\t\tget help on commands\n" +msgstr "" + +#: cups/notify.c:131 +msgid "idle" +msgstr "" + +#: scheduler/ipp.c:8232 +msgid "job-printer-uri attribute missing!" +msgstr "" + +#: systemv/lpadmin.c:141 systemv/lpadmin.c:453 +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "" + +#: systemv/lpadmin.c:750 +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "" + +#: systemv/lpadmin.c:491 +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "" + +#: systemv/lpadmin.c:442 +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "" + +#: systemv/lpadmin.c:130 +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "" + +#: systemv/lpadmin.c:643 +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "" + +#: systemv/lpadmin.c:550 +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "" + +#: systemv/lpadmin.c:659 +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "" + +#: systemv/lpadmin.c:212 +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "" + +#: systemv/lpadmin.c:257 +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "" + +#: systemv/lpadmin.c:704 +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "" + +#: systemv/lpadmin.c:338 +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "" + +#: systemv/lpadmin.c:358 +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "" + +#: systemv/lpadmin.c:391 +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "" + +#: systemv/lpadmin.c:174 +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "" + +#: systemv/lpadmin.c:584 +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "" + +#: systemv/lpadmin.c:1128 +msgid "lpadmin: No member names were seen!\n" +msgstr "" + +#: systemv/lpadmin.c:893 +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "" + +#: systemv/lpadmin.c:1142 +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "" + +#: systemv/lpadmin.c:185 systemv/lpadmin.c:402 systemv/lpadmin.c:595 +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "" + +#: systemv/lpadmin.c:115 +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:106 systemv/lpadmin.c:159 systemv/lpadmin.c:230 +#: systemv/lpadmin.c:291 systemv/lpadmin.c:310 systemv/lpadmin.c:376 +#: systemv/lpadmin.c:417 systemv/lpadmin.c:523 systemv/lpadmin.c:569 +#: systemv/lpadmin.c:615 systemv/lpadmin.c:677 systemv/lpadmin.c:723 +#: systemv/lpadmin.c:784 +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "" + +#: systemv/lpadmin.c:1851 +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "" + +#: systemv/lpadmin.c:1460 +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "" + +#: systemv/lpadmin.c:426 +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:732 +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:532 +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:319 +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:239 +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:624 +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:686 +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:793 +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" + +#: systemv/lpadmin.c:508 +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "" + +#: systemv/lpadmin.c:766 +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "" + +#: systemv/lpadmin.c:761 +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "" + +#: systemv/lpadmin.c:665 +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "" + +#: berkeley/lpc.c:81 berkeley/lpc.c:109 berkeley/lpc.c:145 +msgid "lpc> " +msgstr "" + +#: systemv/lpinfo.c:143 +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" + +#: systemv/lpinfo.c:196 +msgid "lpinfo: Expected language after --language!\n" +msgstr "" + +#: systemv/lpinfo.c:213 +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "" + +#: systemv/lpinfo.c:230 +msgid "lpinfo: Expected product string after --product!\n" +msgstr "" + +#: systemv/lpinfo.c:161 +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "" + +#: systemv/lpinfo.c:179 +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "" + +#: systemv/lpinfo.c:247 +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "" + +#: systemv/lpinfo.c:270 +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "" + +#: systemv/lpinfo.c:264 +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "" + +#: systemv/lpinfo.c:257 +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "" + +#: systemv/lpmove.c:141 +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "" + +#: systemv/lpmove.c:125 +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "" + +#: systemv/lpmove.c:103 +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "" + +#: systemv/lpoptions.c:154 systemv/lpoptions.c:172 systemv/lpoptions.c:248 +msgid "lpoptions: No printers!?!\n" +msgstr "" + +#: systemv/lpoptions.c:223 +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "" + +#: systemv/lpoptions.c:507 +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "" + +#: systemv/lpoptions.c:516 +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "" + +#: systemv/lpoptions.c:104 +msgid "lpoptions: Unknown printer or class!\n" +msgstr "" + +#: systemv/lppasswd.c:185 +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "" + +#: systemv/lppasswd.c:314 +msgid "lppasswd: Password file busy!\n" +msgstr "" + +#: systemv/lppasswd.c:447 +msgid "lppasswd: Password file not updated!\n" +msgstr "" + +#: systemv/lppasswd.c:414 +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "" + +#: systemv/lppasswd.c:264 +msgid "" +"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" +msgstr "" + +#: systemv/lppasswd.c:240 +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "" + +#: systemv/lppasswd.c:211 systemv/lppasswd.c:229 +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "" + +#: systemv/lppasswd.c:317 systemv/lppasswd.c:326 systemv/lppasswd.c:344 +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "" + +#: systemv/lppasswd.c:379 systemv/lppasswd.c:392 systemv/lppasswd.c:424 +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "" + +#: systemv/lppasswd.c:462 +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" + +#: systemv/lppasswd.c:475 +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "" + +#: systemv/lppasswd.c:404 +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "" + +#: systemv/lpstat.c:1039 +#, c-format +msgid "lpstat: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" + +#: systemv/lpstat.c:969 +#, c-format +msgid "members of class %s:\n" +msgstr "" + +#: berkeley/lpq.c:574 +msgid "no entries\n" +msgstr "" + +#: systemv/lpstat.c:1043 +msgid "no system default destination\n" +msgstr "" + +#: scheduler/ipp.c:6277 +msgid "notify-events not specified!" +msgstr "" + +#: scheduler/ipp.c:2114 scheduler/ipp.c:6182 +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "" + +#: scheduler/ipp.c:2104 scheduler/ipp.c:6172 +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "" + +#: scheduler/ipp.c:4145 scheduler/ipp.c:7107 scheduler/ipp.c:7813 +#: scheduler/ipp.c:9278 +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "" + +#: cups/notify.c:87 +msgid "pending" +msgstr "" + +#: ppdc/ppdc.cxx:107 ppdc/ppdpo.cxx:93 +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "" + +#: ppdc/ppdpo.cxx:135 +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:413 +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1798 +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1116 +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2035 +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2711 +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1700 +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:935 +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:958 +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:397 +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1096 +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:450 +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:438 +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:506 +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:495 +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:517 +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:698 +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2897 +#, c-format +msgid "ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:829 +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1080 +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1691 +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1208 +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2611 +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1504 +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1683 +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:356 +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3269 +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1061 +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3100 +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3133 +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3223 +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3286 +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1159 +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1248 +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1784 +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:482 +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1576 +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1610 +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1588 +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1767 +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1007 +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:575 +#, c-format +msgid "ppdc: Expected resolution/mediatype following ColorProfile on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1865 +#, c-format +msgid "ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:364 +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1104 +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2786 +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3389 +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:731 +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:375 +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1088 +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:230 +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:975 +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:967 +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:983 +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1630 +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1602 +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc.cxx:243 ppdc/ppdpo.cxx:123 +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "" + +#: ppdc/ppdc.cxx:179 +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "" + +#: ppdc/ppdc.cxx:120 +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2404 ppdc/ppdc-source.cxx:2636 +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2505 ppdc/ppdc-source.cxx:2540 +#: ppdc/ppdc-source.cxx:2570 +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-driver.cxx:722 +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1653 ppdc/ppdc-source.cxx:2874 +#: ppdc/ppdc-source.cxx:2960 ppdc/ppdc-source.cxx:3053 +#: ppdc/ppdc-source.cxx:3186 ppdc/ppdc-source.cxx:3319 +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1646 +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:708 +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2487 +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc.cxx:346 +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "" + +#: ppdc/ppdc.cxx:258 +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "" + +#: ppdc/ppdc.cxx:279 +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "" + +#: ppdc/ppdc.cxx:295 ppdc/ppdc.cxx:302 +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1732 +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2643 +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc.cxx:190 +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "" + +#: ppdc/ppdc.cxx:129 +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2056 +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2916 +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:909 +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3146 +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:3400 +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1017 +#, c-format +msgid "ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2166 +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc.cxx:352 +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "" + +#: ppdc/ppdc.cxx:142 +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "" + +#: ppdc/ppdmerge.cxx:138 +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "" + +#: ppdc/ppdmerge.cxx:178 +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "" + +#: ppdc/ppdmerge.cxx:162 +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "" + +#: systemv/lpstat.c:1769 +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "" + +#: systemv/lpstat.c:1758 +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "" + +#: systemv/lpstat.c:1763 +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "" + +#: systemv/lpstat.c:1881 +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "" + +#: systemv/lpstat.c:1867 +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "" + +#: systemv/lpstat.c:1874 +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "" + +#: cups/notify.c:93 cups/notify.c:134 +msgid "processing" +msgstr "" + +#: systemv/lp.c:660 +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "" + +#: cups/snmp.c:1021 +msgid "request-id uses indefinite length" +msgstr "" + +#: systemv/lpstat.c:2008 +msgid "scheduler is not running\n" +msgstr "" + +#: systemv/lpstat.c:2004 +msgid "scheduler is running\n" +msgstr "" + +#: cups/adminutil.c:2274 +#, c-format +msgid "stat of %s failed: %s" +msgstr "" + +#: berkeley/lpc.c:216 +msgid "status\t\tshow status of daemon and queue\n" +msgstr "" + +#: cups/notify.c:96 cups/notify.c:137 +msgid "stopped" +msgstr "" + +#: systemv/lpstat.c:1017 +#, c-format +msgid "system default destination: %s\n" +msgstr "" + +#: systemv/lpstat.c:1014 +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "" + +#: cups/notify.c:108 cups/notify.c:140 +msgid "unknown" +msgstr "" + +#: cups/notify.c:117 +msgid "untitled" +msgstr "" + +#: cups/snmp.c:1046 +msgid "variable-bindings uses indefinite length" +msgstr "" + + +# +# End of "$Id$". +# diff --git a/locale/cups_da.po b/locale/cups_da.po new file mode 100644 index 0000000000..6a2b9ef307 --- /dev/null +++ b/locale/cups_da.po @@ -0,0 +1,5663 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(alle)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(ingen)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d optegnelser\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tEfter fejl: Fortsæt\n" + +msgid "\tAlerts:" +msgstr "\tAdvarsler:" + +msgid "\tBanner required\n" +msgstr "\tBanner kræves\n" + +msgid "\tCharset sets:\n" +msgstr "\tTegnsæt:\n" + +msgid "\tConnection: direct\n" +msgstr "\tForbindelse: Direkte\n" + +msgid "\tConnection: remote\n" +msgstr "\tForbindelse: Ekstern\n" + +msgid "\tDefault page size:\n" +msgstr "\tStandardsidestørrelse:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tStandardhøjde:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tStandardportindstillinger:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tBeskrivelse: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tAktiv formular:\n" +"\tIndholdstyper: alle\n" +"\tPrintertyper: Ukendt\n" + +msgid "\tForms allowed:\n" +msgstr "\tFormularer tilladt:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tGrænseflade: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tGrænseflade: %s/grænseflader/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tGrænseflade: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tPlacering: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tVed fejl: Ingen advarsel\n" + +msgid "\tUsers allowed:\n" +msgstr "\tBrugere tilladt:\n" + +msgid "\tUsers denied:\n" +msgstr "\tBrugere ikke tilladt:\n" + +msgid "\tdaemon present\n" +msgstr "\tdaemon til stede\n" + +msgid "\tno entries\n" +msgstr "\tingen optegnelser\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tprinter er på enheden '%s', hastighed -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tudskrivning er slået fra\n" + +msgid "\tprinting is enabled\n" +msgstr "\tudskrivning er slået til\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tstår i kø til %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tkø er slået fra\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tkø er slået til\n" + +msgid "\treason unknown\n" +msgstr "\tårsag ukendt\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" DETALJEREDE RESULTATER AF TEST AF OVERENSSTEMMELSE\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Side 15, afsnit 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Side 15, afsnit 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Side 19, afsnit 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Side 20, afsnit 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Side 27, afsnit 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Side 42, afsnit 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Side 16-17, afsnit 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Side 42-45, afsnit 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Side 45-46, afsnit 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Side 48-49, afsnit 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Side 52-54, afsnit 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f byte\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\" er i konflikt med \"%s %s\"\n" +" (begrænsning=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s har ingen tilsvarende indstillinger!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s deler et almindeligt præfiks med %s\n" +" REF: Side 15, afsnit 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Standardvalg er i konflikt!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Nøgleordet til dupleksindstillingen %s virker muligvis ikke " +"som forventet og skal hedde Dupleks!\n" +" REF: Side 122, afsnit 5.17.\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN Arkiv indeholder en blanding af linjeskifttyperne CR, LF og CR " +"LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding kræves af PPD 4.3 spec.\n" +" REF: Side 56-57, afsnit 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Linje %d indeholder kun tom plads!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Manufacturer kræves af PPD 4.3 spec.\n" +" REF: Side 58-59, afsnit 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN PPD-arkiver, som ikke stammer fra Windows, må kun bruge " +"linjeskifttypen LF, ikke CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Forældet PPD-version %.1f!\n" +" REF: Side 42, afsnit 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName længere end 8.3 overtræder PPD-spec.\n" +" REF: Side 61-62, afsnit 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokoller indeholder PJL, men JCL-attributter er ikke " +"indstillet.\n" +" REF: Side 78-79, afsnit 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokoller indeholder både PJL og BCP; forventede TBCP.\n" +" REF: Side 78-79, afsnit 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName kræves af PPD 4.3 spec.\n" +" REF: Side 64-65, afsnit 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s eksisterer ikke!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Ugyldigt %s-valg %s!\n" +" REF: Side 122, afsnit 5.17.\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" +" %s Ugyldig UTF-8 \"%s\"-oversættelsesstreng til indstillingen %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Ugyldig UTF-8 \"%s\"-oversættelsesstreng til indstillingen %s, " +"valg %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Ugyldig cupsFilter-værdi \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Ugyldig cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Ugyldig cupsPreFilter-værdi \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Ugyldig cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Ugyldigt sprog \"%s\"!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Tom cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Manglende \"%s\"-oversættelsesstreng til indstillingen %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Manglende \"%s\"-oversættelsesstreng til indstillingen %s, valg %" +"s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Manglende valg *%s %s i UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Manglende valg *%s %s i cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Manglende cupsFilter-arkiv \"%s\"\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Manglende cupsICCProfile-arkiv \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Manglende cupsPreFilter-arkiv \"%s\"\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Manglende cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Manglende indstilling %s i UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Manglende indstilling %s i cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Ingen basisoversættelse af \"%s\" er inkluderet i arkiv!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s REQUIRED %s definerer ikke valget Ingen!\n" +" REF: Side 122, afsnit 5.17.\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s-talværdi kolliderer med %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s forårsager en sløjfe!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** %s navne på valg %s og %s adskilles kun af brugen af store/" +"små bogstaver!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s skal være 1284DeviceID!\n" +" REF: Side 72, afsnit 5.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** UGYLDIG Default%s %s\n" +" REF: Side 40, afsnit 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** UGYLDIGT DefaultImageableArea %s!\n" +" REF: Side 102, afsnit 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** UGYLDIG DefaultPaperDimension %s!\n" +" REF: Side 103, afsnit 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** UGYLDIG JobPatchFile-egenskab i arkiv\n" +" REF: Side 24, afsnit 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** UGYLDIG Manufacturer (skulle være \"HP\")\n" +" REF: Side 211, tabel D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** UGYLDIG Manufacturer (skulle være \"Oki\")\n" +" REF: Side 211, tabel D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** UGYLDIGT ModelName - \"%c\" ikke tilladt i streng.\n" +" REF: Side 59-60, afsnit 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** UGYLDIG PSVersion - ikke \"(string) int\".\n" +" REF: Side 62-64, afsnit 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** UGYLDIGT Product - ikke \"(string)\".\n" +" REF: Side 62, afsnit 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** UGYLDIGT ShortNickName - længere end 31 tegn.\n" +" REF: Side 64-65, afsnit 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Ugyldigt %s-valg %s!\n" +" REF: Side 84, afsnit 5.9.\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Ugyldig FileVersion \"%s\"\n" +" REF: Side 56, afsnit 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Ugyldig FormatVersion \"%s\"\n" +" REF: Side 56, afsnit 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** Ugyldig LanguageEncoding %s - skal være ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** Ugyldig LanguageVersion %s - skal være dansk!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FAIL** Standardkode til indstilling kunne ikke fortolkes: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** Standardoversættelsesstreng til indstillingen %s, valg %s, " +"indeholder 8 bit tegn!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** Standardoversættelsesstreng til indstillingen %s indeholder " +"8 bit tegn!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Gruppenavne %s og %s adskilles kun af brugen af store/små " +"bogstaver!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Flere forekomster af %s valg af navn %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Navne på indstillinger %s og %s adskilles kun af brugen af " +"store/små bogstaver!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** REQUIRED Default%s\n" +" REF: Side 40, afsnit 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Side 102, afsnit 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Side 103, afsnit 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Side 56, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Side 56, afsnit 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED ImageableArea til PageSize %s\n" +" REF: Side 41, afsnit 5.\n" +" REF: Side 102, afsnit 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Side 56-57, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Side 57-58, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Side 58-59, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED ModelName\n" +" REF: Side 59-60, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED NickName\n" +" REF: Side 60, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Side 61-62, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Side 62-64, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Side 100, afsnit 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageSize\n" +" REF: Side 41, afsnit 5.\n" +" REF: Side 99, afsnit 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageSize\n" +" REF: Side 99-100, afsnit 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED PaperDimension til PageSize %s\n" +" REF: Side 41, afsnit 5.\n" +" REF: Side 103, afsnit 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED Product\n" +" REF: Side 62, afsnit 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Side 64-65, afsnit 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d FEJL FUNDET\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Ugyldig %%%%BoundingBox: på linje %d!\n" +" REF: Side 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Ugyldig %%%%Page: på linje %d!\n" +" REF: Side 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Ugyldige %%%%Pages: på linje %d!\n" +" REF: Side 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Linje %d er på mere end 255 tegn (%d)!\n" +" REF: Side 25, Linjelængde\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" Manglende %!PS-Adobe-3.0 på første linje!\n" +" REF: Side 17, 3.1 Overensstemmende dokumenter\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Manglende %%EndComments-kommentar!\n" +" REF: Side 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Manglende eller ugyldig %%BoundingBox: kommentar!\n" +" REF: Side 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Manglende eller ugyldig %%Page: kommentarer!\n" +" REF: Side 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Manglende eller ugyldig %%Pages: kommentar!\n" +" REF: Side 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " INGEN FEJL FUNDET\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Så %d linjer, der overskred 255 tegn!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " For mange %%BeginDocument-kommentarer!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " For mange %%EndDocument-kommentarer!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Advarsel: Arkiv indeholder binære data!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Advarsel: Ingen %%EndComments-kommentar i arkiv!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Advarsel: Forældet DSC-version %.1f i arkiv!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** Kan ikke åbne PPD-arkiv - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** Kan ikke åbne PPD-arkiv - %s på linje %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10-kuvert" + +msgid "#11 Envelope" +msgstr "#11-kuvert" + +msgid "#12 Envelope" +msgstr "#12-kuvert" + +msgid "#14 Envelope" +msgstr "#14-kuvert" + +msgid "#9 Envelope" +msgstr "#9-kuvert" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f byte\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f byte\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f mm" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f til %.0f x %.0f mm" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f tommer" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f til %.2f x %.2f tommer" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s accepterer anmodninger siden %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s kan ikke ændres." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s er ikke implementeret af CUPS-versionen af lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s er ikke klar\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s er klar\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s er klar og udskriver\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s accepterer ikke anmodninger siden %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s ikke understøttet!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s accepterer anmodninger siden %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s accepterer ikke anmodninger siden %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [job %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s mislykkedes: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Ved ikke, hvad jeg skal gøre!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Fejl - %s-miljøvariabel navngiver ikke eksisterende destination \"%s\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Fejl - ugyldig job-id!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s: Fejl - kan ikke udskrive arkiver og ændre job på samme tid!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Fejl - kan ikke udskrive fra stdin, hvis der leveres arkiver eller en " +"job-id!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Fejl - forventede tegnsæt efter indstillingen '-S'!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Fejl - forventede indholdstype efter indstillingen '-T'!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Fejl - forventede kopier efter indstillingen '-n'!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Fejl - forventede antal kopier efter indstillingen '-#'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Fejl - forventede destination efter indstillingen '-P'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Fejl - forventede destination efter indstillingen '-b'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Fejl - forventede destination efter indstillingen '-d'!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Fejl - forventede formular efter indstillingen '-f'!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Error - forventede udsat navn efter indstillingen '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Error - forventede værtsnavn efter indstillingen '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Error - forventede værtsnavn efter indstillingen '-H'!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Error - forventede funktionsliste efter indstillingen '-y'!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Error - forventede navn efter indstillingen '-%c'!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Error - forventede alternativ streng efter indstillingen '-o'!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Error - forventede sideliste efter indstillingen '-P'!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Error - forventede prioritet efter indstillingen '-%c'!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Fejl - forventede årsagstekst efter indstillingen '-r'!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Error - forventede titel efter indstillingen '-t'!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Error - forventede brugernavn efter indstillingen '-U'!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Error - forventede brugernavn efter indstillingen '-u'!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Error - forventede værdi efter indstillingen '-%c'!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Fejl - skal have \"completed\", \"not-completed\" eller \"all\" efter " +"indstillingen '-W'!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Fejl - ingen tilgængelig standarddestination.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Fejl - prioritet skal være mellem 1 og 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Fejl - planlægger svarer ikke!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Fejl - for mange arkiver - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Fejl - kan ikke få adgang til \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Fejl - kan ikke sætte i kø fra stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Fejl - ukendt destination \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Fejl - ukendt destination \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Fejl - ukendt indstilling '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Fejl - ukendt indstilling '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Forventede job-id efter indstillingen '-i'!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filter \"%s\" ikke tilgængeligt: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Ugyldigt destinationsnavn på listen \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Ugyldig filterstreng \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Skal have job-id ('-i jobid') før '-H restart'!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Intet filter til konvertering fra %s/%s til %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Handling mislykkedes: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Beklager, der er ikke medkompileret krypteringsunderstøttelse!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Kan ikke oprette forbindelse til server\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Kan ikke kontakte server!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Kan ikke bestemme MIME-typen på \"%s\"!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Kan ikke åbne %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Kan ikke åbne PPD-arkiv: %s på linje %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Kan ikke læse MIME-database fra \"%s\" eller \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Ukendt destination \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Ukendt destination på MIME-typen \"%s/%s\"!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Ukendt indstilling '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Ukendt kilde på MIME-typen %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Advarsel - '%c'-formatmodifikation ikke understøttet - resultat muligvis " +"ikke korrekt!" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Advarsel - indstillingen tegnsæt ignoreret!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Advarsel - indstillingen indholdstype ignoreret!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Advarsel - indstillingen formular ignoreret!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Advarsel - indstillingen funktion ignoreret!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Fejl - %s-miljøvariabel navngiver ikke eksisterende destination \"%s\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: Fejl - forventede option=value efter indstillingen '-o'!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: Fejl - ingen tilgængelig standarddestination.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 tomme/sek." + +msgid "1.25x0.25\"" +msgstr "1,25 x 0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25 x 2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 tomme/sek." + +msgid "1.50x0.25\"" +msgstr "1,50 x 0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50 x 0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50 x 1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50 x 2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 tommer/sek." + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/sek." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 tommer/sek." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 tommer/sek." + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/sek." + +msgid "120x60dpi" +msgstr "120 x 60 dpi" + +msgid "120x72dpi" +msgstr "120 x 72 dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/sek." + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/sek." + +msgid "150dpi" +msgstr "150 dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 tommer/sek." + +msgid "2-Sided Printing" +msgstr "Dobbeltsidet udskrivning" + +msgid "2.00x0.37\"" +msgstr "2,00 x 0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00 x 0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00 x 1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00 x 1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00 x 2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00 x 3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00 x 4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00 x 5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25 x 0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25 x 1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25 x 4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25 x 5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38 x 5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 tommer/sek." + +msgid "2.50x1.00\"" +msgstr "2,50 x 1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50 x 2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75 x 1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/sek." + +msgid "200 mm/sec." +msgstr "200 mm/sek." + +msgid "203dpi" +msgstr "203 dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-bens serien" + +msgid "240x72dpi" +msgstr "240 x 72 dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/sek." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 tommer/sek." + +msgid "3.00x1.00\"" +msgstr "3,00 x 1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00 x 1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00 x 2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00 x 3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00 x 5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25 x 2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25 x 5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25 x 5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25 x 5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25 x 7,83\"" + +msgid "3.5\" Disk" +msgstr "3,5\" disk" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3,5\" disk - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50 x 1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/sek." + +msgid "300 mm/sec." +msgstr "300 mm/sek." + +msgid "300dpi" +msgstr "300 dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 dpi" + +msgid "360x180dpi" +msgstr "360 x 180 dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 tommer/sek." + +msgid "4.00x1.00\"" +msgstr "4,00 x 1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00 x 13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00 x 2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00 x 2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00 x 3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00 x 4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00 x 5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00 x 6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00 x 6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/sek." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 tommer/sek." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 tommer/sek." + +msgid "6.00x1.00\"" +msgstr "6,00 x 1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00 x 2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00 x 3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00 x 4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00 x 5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00 x 6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00 x 6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/sek." + +msgid "600dpi" +msgstr "600 dpi" + +msgid "60dpi" +msgstr "60 dpi" + +msgid "60x720dpi" +msgstr "60 x 720 dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 tommer/sek." + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 tommer/sek." + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00 x 1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00 x 2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00 x 3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00 x 4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00 x 5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00 x 6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00 x 6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/sek." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 tommer/sek." + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9-bens serien" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Ugyldig hjælpekommando ukendt\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Der kræves en Samba-adgangskode til eksport af printerarkiver!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "Der kræves et Samba-brugernavn til eksport af printerarkiver!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Der findes allerede en klasse kaldet \"%s\"!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Der findes allerede en printer kaldet \"%s\"!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (overstørrelse)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (overstørrelse)" + +msgid "A4 (Small)" +msgstr "A4 (beskåret)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (overstørrelse)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Accepter job" + +msgid "Accepted" +msgstr "Accepteret" + +msgid "Add Class" +msgstr "Tilføj klasse" + +msgid "Add Printer" +msgstr "Tilføj printer" + +msgid "Add RSS Subscription" +msgstr "Tilføj RSS-abonnement" + +msgid "Address" +msgstr "Adresse" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adresse - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administration" + +msgid "Always" +msgstr "Altid" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Bruger" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Forsøger at indstille %s-printer-state til ugyldig værdi %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Egenskabsgrupper er ikke i rækkefølge (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Ugyldig NULL dests-markør" + +msgid "Bad OpenGroup" +msgstr "Ugyldig OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Ugyldig OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Ugyldig OrderDependency" + +msgid "Bad Request" +msgstr "Ugyldig anmodning" + +msgid "Bad SNMP version number" +msgstr "Ugyldigt versionsnummer på SNMP" + +msgid "Bad UIConstraints" +msgstr "Ugyldig UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Ugyldig værdi for kopier %d." + +msgid "Bad custom parameter" +msgstr "Ugylidig speciel parameter" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Ugyldig enheds-URI \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Ugyldig device-uri \"%s\"!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Ugyldig device-uri-plan \"%s\"!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Ugyldigt document-format \"%s\"!" + +msgid "Bad filename buffer!" +msgstr "Ugyldig arkivnavnebuffer!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Ugyldig skriftattribut: %s\n" + +msgid "Bad job-priority value!" +msgstr "Ugyldig værdi for job-priority!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Ugyldig værdi for job-sheets \"%s\"!" + +msgid "Bad job-sheets value type!" +msgstr "Ugyldig værditype på job-sheets!" + +msgid "Bad job-state value!" +msgstr "Ugyldig værdi for job-state!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Ugyldig egenskab for job-uri \"%s\"!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Ugyldig notify-pull-method \"%s\"!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Ugyldig notify-recipient-uri URI \"%s\"!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Ugyldig værdi for number-up %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Ugyldig indstilling + valg på linje %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Ugyldige værdier for page-ranges %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Ugyldig port-monitor \"%s\"!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Ugyldig værdi for printer-state %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Ugyldigt versionsnummer på anmodning %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Ugyldig abonnements-id!" + +msgid "Banners" +msgstr "Bannere" + +msgid "Billing Information: " +msgstr "Faktureringsoplysninger: " + +msgid "Bond Paper" +msgstr "Bond-papir" + +msgid "C0 Envelope" +msgstr "C0-kuvert" + +msgid "C1 Envelope" +msgstr "C1-kuvert" + +msgid "C2 Envelope" +msgstr "C2-kuvert" + +msgid "C3 Envelope" +msgstr "C3-kuvert" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4-kuvert" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5-kuvert" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6-kuvert" + +msgid "C65 Envelope" +msgstr "C65-kuvert" + +msgid "C7 Envelope" +msgstr "C7-kuvert" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL-etiketprinter" + +msgid "Cancel RSS Subscription" +msgstr "Annuller RSS-abonnement" + +msgid "Change Settings" +msgstr "Skift indstillinger" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Tegnsættet \"%s\" understøttes ikke!" + +msgid "Chou3 Envelope" +msgstr "Chou3-kuvert" + +msgid "Chou4 Envelope" +msgstr "Chou4-kuvert" + +msgid "Classes" +msgstr "Klasser" + +msgid "Clean Print Heads" +msgstr "Rengør skrivehoveder" + +msgid "Color" +msgstr "Farve" + +msgid "Color Mode" +msgstr "Farvefunktion" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Kommandoer kan være forkortet. Kommandoer er:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Fællesnavn bruger uendelig længde" + +msgid "Continue" +msgstr "Fortsæt" + +msgid "Continuous" +msgstr "Fortsat" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Kunne ikke scanne typen \"%s\"!" + +msgid "Cover open." +msgstr "Dæksel åbent." + +msgid "Created" +msgstr "Oprettet" + +msgid "Created On: " +msgstr "Oprettet den: " + +msgid "Custom" +msgstr "Speciel" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Klip" + +msgid "Cutter" +msgstr "Klipper" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL-kuvert" + +msgid "Dark" +msgstr "Mørk" + +msgid "Darkness" +msgstr "Mørke" + +msgid "Delete Class" +msgstr "Slet klasse" + +msgid "Delete Printer" +msgstr "Slet printer" + +msgid "Description: " +msgstr "Beskrivelse: " + +msgid "DeskJet Series" +msgstr "DeskJet-serie" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Destinationen \"%s\" accepterer ikke job." + +msgid "Developer almost empty." +msgstr "Fremkalder næsten tom." + +msgid "Developer empty!" +msgstr "Fremkalder tom!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Enhed: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Direkte termisk medie" + +msgid "Disabled" +msgstr "Slået fra" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Dokument %d findes ikke i job %d." + +msgid "Door open." +msgstr "Dæksel åbent." + +msgid "Double Postcard" +msgstr "Dobbelt postkort" + +msgid "Driver Name: " +msgstr "Navn på printerarkiv: " + +msgid "Driver Version: " +msgstr "Version på printerarkiv: " + +msgid "Duplexer" +msgstr "Dupleksenhed" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Kan ikke tildele hukommelse til sideinfo: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Kan ikke tildele hukommelse til rækkefølge af sider: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1-etiketprinter" + +msgid "EPL2 Label Printer" +msgstr "EPL2-etiketprinter" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Ugyldig %%BoundingBox: Kommentar set!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Ugyldig %%IncludeFeature: Kommentar!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Ugyldig %%Page: Kommentar i arkiv!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Ugyldig %%PageBoundingBox: Kommentar i arkiv!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Ugyldigt SCSI-enhedsarkiv \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Ugyldigt tegnsætsarkiv %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Ugyldig type på tegnsæt %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Ugyldig kolonneværdi %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Ugyldig cpi-værdi %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Ugyldig linje til skriftbeskrivelse: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Ugyldig lpi-værdi %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Ugyldigt sidelayout!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Ugyldig tekstretning %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Ugyldig tekstbredde %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Destinationsprinter findes ikke!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Dubleret %%BoundingBox: Kommentar set!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Dublerede %%Pages: Kommentar set!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Tomt udskriftsarkiv!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Fejl %d under afsendelse af PAPSendData-anmodning: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: Forventede streng med anførselstegn på linje %d af %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Uoprettelig USB-fejl!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: Ugyldig HP-GL/2-kommando set, kan ikke udskrive arkiv!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: Manglende %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: Manglende %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Manglende værdi på linje %d i bannerarkiv!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Kræver en msgid-linje før evt. oversætterstrenge på linje %d i %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Ingen %%BoundingBox: Kommentar i header!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Ingen %%Pages: Kommentar i header!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Ingen enheds-URI fundet i argv[0] eller i DEVICE_URI-miljøvariabel!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Ingen skrifter i tegnsætsarkiv %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Ingen sider fundet!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Ikke mere papir!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER-miljøvariabel ikke defineret!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Udskriftsarkiv blev ikke accepteret (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Printer svarer ikke!\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Printer svarer ikke!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Printer sendte uventet EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Ekstern vært accepterede ikke kontrolarkiv (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Ekstern vært accepterede ikke dataarkiv (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Der opstod en timeout-fejl under afsendelse af data til printeren\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Kan ikke føje arkivet %d til job: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Kan ikke annullere jobbet %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Kan ikke kopiere PDF-arkiv" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Kan ikke oprette socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: Kan ikke oprette midlertidigt komprimeret udskriftsarkiv: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Kan ikke oprette midlertidigt arkiv" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Kan ikke udføre pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Kan ikke udføre gs-program" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Kan ikke udføre pdftops-program" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Kan ikke fork pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Kan ikke hente PAP-anmodning" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Kan ikke hente PAP-svar" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: Kan ikke hente PPD-arkiv til printeren \"%s\" - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Kan ikke hente AppleTalk-standardzone" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Kan ikke hente attributter til jobbet %d (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Kan ikke hente printerstatus (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Kan ikke finde printeren '%s'!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Kan ikke søge efter PAP-svar" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Kan ikke slå AppleTalk-printere op" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Kan ikke oprette AppleTalk-adresse" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Kan ikke åbne \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Kan ikke åbne %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Kan ikke åbne bannerarkiv \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Kan ikke åbne enhedsarkivet \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Kan ikke åbne arkivet \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Kan ikke åbne arkivet \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Kan ikke åbne billedarkiv til udskrivning!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Kan ikke åbne udskriftarkivet \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Kan ikke åbne udskriftsarkivet %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Kan ikke åbne udskriftarkivet %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: Kan ikke åbne midlertidigt komprimeret udskriftsarkiv: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Kan ikke udskrive %d tekstspalter!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Kan ikke udskrive %dx%d tekstside!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Kan ikke læse udskriftsdata" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Kan ikke læse udskriftsdata!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Kan ikke reservere port" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Kan ikke forsøge at forskyde %ld i arkiv - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Kan ikke forsøge at forskyde %lld i arkiv - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Kan ikke sende LPD-kommando" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Kan ikke sende PAP tickle-anmodning" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Kan ikke sende startanmodningen PAP send data" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Kan ikke sende udskriftsdata (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Kan ikke sende udskriftsdata!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Kan ikke sende udskriftsarkiv til printer" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: Kan ikke sende udpunkteringsnul til printer" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Kan ikke vente på pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Kan ikke skrive %d byte til \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Kan ikke skrive %d byte til printer!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Kan ikke skrive kontrolarkiv" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Kan ikke skrive udskriftsdata" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Kan ikke skrive udskriftsdata: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Kan ikke skrive rasterdata til driver!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Kan ikke skrive til midlertidigt arkiv" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: Kan ikke skrive ukomprimerede dokumentdata: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Uventet tekst på linje %d af %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Ukendt værdi i krypteringsindstilling \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Ukendt arkivrækkefølge \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Ukendt formattegn \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Ukendt beskedkatalogformat til \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Ukendt indstilling \"%s\" med værdien \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Ukendt udskriftsfunktion \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Ukendt værdi på versionsindstilling \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "" +"ERROR: Værdi for lysstyrke %s ikke understøttet, bruger lysstyrke=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Værdi for gamma %s ikke understøttet, bruger gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Værdi for number-up %d ikke understøttet, bruger number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Værdi for number-up-layout %s ikke understøttet, bruger number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Værdi for page-border %s ikke understøttet, bruger page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: doc_printf-overløb (%d byte) registreret, annullerer!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops afsluttede på signalet %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops afsluttede med status %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: Kan gendannes: Kan ikke oprette forbindelse til printer; prøver igen " +"om 30 sekunder...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() mislykkedes" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: Kan ikke stat udskriftsarkiv" + +msgid "Edit Configuration File" +msgstr "Rediger konfigurationsarkiv" + +msgid "Empty PPD file!" +msgstr "Tomt PPD-arkiv!" + +msgid "Ending Banner" +msgstr "Slutbanner" + +msgid "Enter old password:" +msgstr "Skriv gammel adgangskode:" + +msgid "Enter password again:" +msgstr "Skriv adgangskode igen:" + +msgid "Enter password:" +msgstr "Skriv adgangskode:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Skriv dit brugernavn og din adgangskode eller root-brugernavnet og -" +"adgangskoden for at få adgang til denne side. Hvis du bruger Kerberos-" +"godkendelse, skal du sikre dig, at du har en gyldig Kerberos-billet." + +msgid "Envelope Feed" +msgstr "Ilægning af kuvert" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Fejlpolitik" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "ERROR: Værtsnavn kræves efter indstillingen '-h'!\n" + +msgid "Every 10 Labels" +msgstr "Hver 10. etiket" + +msgid "Every 2 Labels" +msgstr "Hver 2. etiket" + +msgid "Every 3 Labels" +msgstr "Hver 3. etiket" + +msgid "Every 4 Labels" +msgstr "Hver 4. etiket" + +msgid "Every 5 Labels" +msgstr "Hver 5. etiket" + +msgid "Every 6 Labels" +msgstr "Hver 6. etiket" + +msgid "Every 7 Labels" +msgstr "Hver 7. etiket" + +msgid "Every 8 Labels" +msgstr "Hver 8. etiket" + +msgid "Every 9 Labels" +msgstr "Hver 9. etiket" + +msgid "Every Label" +msgstr "Alle etiketter" + +msgid "Expectation Failed" +msgstr "Forventning mislykkedes" + +msgid "Export Printers to Samba" +msgstr "Eksporter printere til Samba" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Arkivmappe" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Arkivmappe - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Arkivets enheds-URI'er er blevet slået fra! Du slår det til ved at se i " +"FileDevice-direktivet i \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "8,5 x 13\"" + +msgid "Forbidden" +msgstr "Forbudt" + +msgid "Fuser temperature high!" +msgstr "Fixertemperatur høj!" + +msgid "Fuser temperature low!" +msgstr "Fixertemperatur lav!" + +msgid "General" +msgstr "Generelt" + +msgid "Generic" +msgstr "Generel" + +msgid "German FanFold" +msgstr "Tysk FanFold" + +msgid "German FanFold Legal" +msgstr "Tysk FanFold, 8,5 x 14\"" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU bruger uendelig længde" + +msgid "Glossy Paper" +msgstr "Glittet papir" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Fik en printer-uri-egenskab, men ingen job-id!" + +msgid "Grayscale" +msgstr "Gråtoner" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Hængende mappe" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Hængende mappe - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk slået fra i Systemindstillinger\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk slået fra i Systemindstillinger.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Annullerer udskriftsjob...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Sluttet til printer...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Opretter forbindelse til printer...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Kontrolarkiv sendt\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Dataarkiv sendt\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Formaterer siden %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Indlæser billedarkivet...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Søger efter printer...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Åbner forbindelse\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Udskriftsarkiv sendt, venter på, at printer bliver færdig...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Printer i brug; prøver igen om 10 sekunder...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Printer i brug; prøver igen om 30 sekunder...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Printer i brug; prøver igen om 5 sekunder...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: Printer understøtter ikke IPP/%d.%d, prøver IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Printer i brug; prøver igen om 5 sekunder...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Printer er passiv.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Printer er passiv.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Printer er nu aktiv.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Printer er passiv.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Printer ikke tilsluttet; prøver igen om 30 sekunder...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Udskriver side %d, %d%% færdig...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Udskriver side %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Klar til at udskrive.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Sender kontrolarkiv (%lu byte)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Sender kontrolarkiv (%u byte)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Sender data\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Sender dataarkiv (%ld byte)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Sender dataarkiv (%lld byte)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Sender udskriftsdata...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Sendt udskriftsarkiv, %ld byte...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Sendt udskriftsarkiv, %lld byte...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Spoler LPR-job, %.0f%% færdig...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Kan ikke kontakte printer, sætter job i kø på næste printer i " +"klassen...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Bruger AppleTalk-standardzone \"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Venter på, at job bliver færdigt...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Venter på, at printer bliver tilgængelig...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4-kuvert" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (overstørrelse)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5-kuvert" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6-kuvert" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Ulovligt kontroltegn" + +msgid "Illegal main keyword string" +msgstr "Ulovlig streng til hovednøgleord" + +msgid "Illegal option keyword string" +msgstr "Ulovlig nøgleordsstreng til indstilling" + +msgid "Illegal translation string" +msgstr "Ulovlig oversættelsesstreng" + +msgid "Illegal whitespace character" +msgstr "Ulovlig tegn for tom plads" + +msgid "Ink/toner almost empty." +msgstr "Blæk/toner næsten tom." + +msgid "Ink/toner empty!" +msgstr "Blæk/toner tom!" + +msgid "Ink/toner waste bin almost full." +msgstr "Affaldsbeholder til blæk/toner næsten fuld." + +msgid "Ink/toner waste bin full!" +msgstr "Affaldsbeholder til blæk/toner fuld!" + +msgid "Installable Options" +msgstr "Ekstraudstyr" + +msgid "Installed" +msgstr "Installeret" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar-etiketprinter" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Sikkerhedsafbryder åben." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Intern fejl" + +msgid "Internet Postage 2-Part" +msgstr "Internet-porto 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet-porto 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Internet-porto 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet-porto 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internet Printing Protocol" + +msgid "Invite Envelope" +msgstr "Invite-kuvert" + +msgid "Italian Envelope" +msgstr "Italiensk kuvert" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Job #%d kan ikke startes igen - ingen arkiver!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Job #%d eksisterer ikke!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Job #%d er allerede afbrudt - kan ikke annullere." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Job #%d er allerede annulleret - kan ikke annullere." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Job #%d er allerede færdigt - kan ikke annullere." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Job #%d er færdigt og kan ikke ændres!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Job #%d er ikke færdigt!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Job #%d er ikke udsat til godkendelse!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Job #%d er ikke udsat!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Job #%s eksisterer ikke!" + +#, c-format +msgid "Job %d not found!" +msgstr "Job %d findes ikke!" + +msgid "Job Completed" +msgstr "Job færdigt" + +msgid "Job Created" +msgstr "Job oprettet" + +msgid "Job ID: " +msgstr "Job-id: " + +msgid "Job Options Changed" +msgstr "Jobindstillinger ændret" + +msgid "Job Stopped" +msgstr "Job stoppet" + +msgid "Job UUID: " +msgstr "Job-uuid: " + +msgid "Job is completed and cannot be changed." +msgstr "Job er færdigt og kan ikke ændres." + +msgid "Job operation failed:" +msgstr "Jobhandling mislykkedes:" + +msgid "Job state cannot be changed." +msgstr "Jobstatus kan ikke ændres." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Jobabonnementer kan ikke fornys!" + +msgid "Jobs" +msgstr "Job" + +msgid "Kaku2 Envelope" +msgstr "Kaku2-kuvert" + +msgid "Kaku3 Envelope" +msgstr "Kaku3-kuvert" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR-vært eller -printer" + +msgid "Label Printer" +msgstr "Etiketprinter" + +msgid "Label Top" +msgstr "Top af etiket" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Sproget \"%s\" understøttes ikke!" + +msgid "Large Address" +msgstr "Stor adresse" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Stor adresse - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "Lys" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Linje længere end det maksimalt tilladte (255 tegn)" + +msgid "List Available Printers" +msgstr "Vis tilgængelige printere" + +msgid "Location: " +msgstr "Placering: " + +msgid "Long-Edge (Portrait)" +msgstr "Lang kant (stående)" + +msgid "Make and Model: " +msgstr "Mærke og model: " + +msgid "Manual Feed" +msgstr "Manuel ilægning" + +msgid "Media Dimensions: " +msgstr "Mediestørrelser: " + +msgid "Media Limits: " +msgstr "Mediebegrænsninger: " + +msgid "Media Name: " +msgstr "Medienavn: " + +msgid "Media Size" +msgstr "Mediestørrelse" + +msgid "Media Source" +msgstr "Mediekilde" + +msgid "Media Tracking" +msgstr "Mediesporing" + +msgid "Media Type" +msgstr "Medietype" + +msgid "Media jam!" +msgstr "Mediestop!" + +msgid "Media tray almost empty." +msgstr "Mediebakke næsten tom." + +msgid "Media tray empty!" +msgstr "Mediebakke tom!" + +msgid "Media tray missing!" +msgstr "Mediebakke mangler!" + +msgid "Media tray needs to be filled." +msgstr "Mediebakke skal fyldes op." + +msgid "Medium" +msgstr "Medium" + +msgid "Memory allocation error" +msgstr "Fejl i hukommelsestildeling" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Manglende PPD-Adobe-4.x header" + +msgid "Missing asterisk in column 1" +msgstr "Manglende stjerne i kolonne 1" + +msgid "Missing document-number attribute!" +msgstr "Manglende document-number-attribut!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Manglende dobbelt anførselstegn i linje %d!" + +msgid "Missing form variable!" +msgstr "Manglende formularvariabel!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Manglende notify-subscription-ids-egenskab!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Manglende requesting-user-name-egenskab!" + +msgid "Missing required attributes!" +msgstr "Manglende nødvendige attributter!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Manglende værdi i linje %d!" + +msgid "Missing value string" +msgstr "Manglende værdistreng" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Rediger klasse" + +msgid "Modify Printer" +msgstr "Rediger printer" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch-kuvert" + +msgid "Move All Jobs" +msgstr "Flyt alle job" + +msgid "Move Job" +msgstr "Flyt job" + +msgid "Moved Permanently" +msgstr "Flyttet permanent" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Udskriftsarkiv accepteret - job-id %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Udskriftsarkiv accepteret - job-id ukendt.\n" + +msgid "NULL PPD file pointer" +msgstr "NULL PPD-arkivmarkør" + +msgid "Name OID uses indefinite length" +msgstr "Navn-oid bruger uendelig længde" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Aldrig" + +msgid "New Stylus Color Series" +msgstr "Ny Stylus Color Series" + +msgid "New Stylus Photo Series" +msgstr "Ny Stylus Photo Series" + +msgid "No" +msgstr "Nej" + +msgid "No Content" +msgstr "Intet indhold" + +msgid "No PPD name!" +msgstr "Intet PPD-navn!" + +msgid "No VarBind SEQUENCE" +msgstr "Ingen VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Der er ikke installeret nogen Windows-printerdrivere!" + +msgid "No active connection" +msgstr "Ingen aktiv forbindelse" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Ingen aktive job på %s!" + +msgid "No attributes in request!" +msgstr "Ingen attributter i anmodning!" + +msgid "No authentication information provided!" +msgstr "Ingen godkendelsesoplysninger leveret!" + +msgid "No community name" +msgstr "Intet fællesskabsnavn" + +msgid "No default printer" +msgstr "Ingen standardprinter" + +msgid "No destinations added." +msgstr "Ingen destinationer tilføjet." + +msgid "No error-index" +msgstr "Intet error-index" + +msgid "No error-status" +msgstr "Ingen error-status" + +msgid "No file!?!" +msgstr "Intet arkiv!?!" + +msgid "No modification time!" +msgstr "Intet ændringstidspunkt!" + +msgid "No name OID" +msgstr "Ingen navn-oid" + +msgid "No printer name!" +msgstr "Intet printernavn!" + +msgid "No printer-uri found for class!" +msgstr "Ingen printer-uri fundet til klasse!" + +msgid "No printer-uri found!" +msgstr "Ingen printer-uri fundet!" + +msgid "No printer-uri in request!" +msgstr "Ingen printer-uri i anmodning!" + +msgid "No request-id" +msgstr "Ingen request-id" + +msgid "No subscription attributes in request!" +msgstr "Ingen abonnementsattributter i anmodning!" + +msgid "No subscriptions found." +msgstr "Ingen abonnementer fundet." + +msgid "No variable-bindings SEQUENCE" +msgstr "Ingen variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "Intet versionsnummer" + +msgid "Non-continuous (Mark sensing)" +msgstr "Ikke fortsat (mærkefølsom)" + +msgid "Non-continuous (Web sensing)" +msgstr "Ikke fortsat (webfølsom)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "Ikke fundet" + +msgid "Not Implemented" +msgstr "Ikke implementeret" + +msgid "Not Installed" +msgstr "Ikke installeret" + +msgid "Not Modified" +msgstr "Ikke ændret" + +msgid "Not Supported" +msgstr "Ikke understøttet" + +msgid "Not allowed to print." +msgstr "Må ikke udskrive." + +msgid "Note" +msgstr "Bemærk" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC næsten slidt op." + +msgid "OPC at end-of-life!" +msgstr "OPC slidt op!" + +msgid "Off (1-Sided)" +msgstr "Fra (ensidet)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Hjælp på skærmen" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "åbning af %s mislykkedes: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup uden en CloseGroup først" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI uden en CloseUI/JCLCloseUI først" + +msgid "Operation Policy" +msgstr "Driftspolitik" + +msgid "Options Installed" +msgstr "Ekstraudstyr installeret" + +msgid "Options: " +msgstr "Ekstraudstyr: " + +msgid "Out of toner!" +msgstr "Ikke mere toner!" + +msgid "Output Mode" +msgstr "Udskriftsfunktion" + +msgid "Output bin almost full." +msgstr "Udbakke næsten fuld." + +msgid "Output bin full!" +msgstr "Udbakke fuld!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Udskrifter til printer %s er sendt til %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Udskrifter til printer %s er sendt til ekstern printer %s på %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Udskrifter til printer %s/%s er sendt til %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "Udskrifter til printer %s/%s er sendt til ekstern printer %s på %s\n" + +msgid "Output tray missing!" +msgstr "Udbakke mangler!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "PCL-laserprinter" + +msgid "PRC1 Envelope" +msgstr "PRC1-kuvert" + +msgid "PRC10 Envelope" +msgstr "PRC10-kuvert" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2-kuvert" + +msgid "PRC3 Envelope" +msgstr "PRC3-kuvert" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (overstørrelse)" + +msgid "PRC4 Envelope" +msgstr "PRC4-kuvert" + +msgid "PRC5 Envelope" +msgstr "PRC5-kuvert" + +msgid "PRC6 Envelope" +msgstr "PRC6-kuvert" + +msgid "PRC7 Envelope" +msgstr "PRC7-kuvert" + +msgid "PRC8 Envelope" +msgstr "PRC8-kuvert" + +msgid "PRC9 Envelope" +msgstr "PRC9-kuvert" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Pakke indeholder ikke en Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Pakke starter ikke med SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Adgangskode til %s på %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Adgangskode til %s kræves til adgang til %s via SAMBA: " + +msgid "Pause Class" +msgstr "Sæt klasse på pause" + +msgid "Pause Printer" +msgstr "Sæt printer på pause" + +msgid "Peel-Off" +msgstr "Aftrækkelig" + +msgid "Personal Envelope" +msgstr "Personlig kuvert" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Fotoetiketter" + +msgid "Plain Paper" +msgstr "Almindeligt papir" + +msgid "Policies" +msgstr "Politikker" + +msgid "Port Monitor" +msgstr "Portovervågning" + +msgid "PostScript Printer" +msgstr "PostScript-printer" + +msgid "Postcard" +msgstr "Postkort" + +msgid "Print Density" +msgstr "Tryktæthed" + +msgid "Print Job:" +msgstr "Udskriftsjob:" + +msgid "Print Mode" +msgstr "Udskriftsfunktion" + +msgid "Print Rate" +msgstr "Udskriftshastighed" + +msgid "Print Self-Test Page" +msgstr "Udskriv testside" + +msgid "Print Speed" +msgstr "Udskriftshastighed" + +msgid "Print Test Page" +msgstr "Udskriv testside" + +msgid "Print and Cut" +msgstr "Udskriv og klip" + +msgid "Print and Tear" +msgstr "Udskriv og riv af" + +msgid "Printed For: " +msgstr "Udskrevet til: " + +msgid "Printed From: " +msgstr "Udskrevet fra: " + +msgid "Printed On: " +msgstr "Udskrevet den: " + +msgid "Printer Added" +msgstr "Printer tilføjet" + +msgid "Printer Default" +msgstr "Printerstandard" + +msgid "Printer Deleted" +msgstr "Printer slettet" + +msgid "Printer Modified" +msgstr "Printer ændret" + +msgid "Printer Name: " +msgstr "Printernavn: " + +msgid "Printer Paused" +msgstr "Printer på pause" + +msgid "Printer Settings" +msgstr "Printerindstillinger" + +msgid "Printer offline." +msgstr "Printer passiv." + +msgid "Printer:" +msgstr "Printer:" + +msgid "Printers" +msgstr "Printere" + +msgid "Purge Jobs" +msgstr "Udrens job" + +msgid "Quarto" +msgstr "Kvartformat" + +msgid "Quota limit reached." +msgstr "Maks. kvote nået." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "Grad Ejer Job Arkiv(er) Str. i alt\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Grad Ejer Pri Job Arkiver Str. i alt\n" + +msgid "Reject Jobs" +msgstr "Afvis job" + +msgid "Reprint After Error" +msgstr "Udskriv igen efter fejl" + +msgid "Request Entity Too Large" +msgstr "Enhedsanmodning for stor" + +msgid "Resolution" +msgstr "Opløsning" + +msgid "Resume Class" +msgstr "Genoptag klasse" + +msgid "Resume Printer" +msgstr "Genoptag printer" + +msgid "Return Address" +msgstr "Returadresse" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Returadresse - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Spol tilbage" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Aktiv kommando: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI-printer" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE bruger uendelig længde" + +msgid "See Other" +msgstr "Se andet" + +#, c-format +msgid "Serial Port #%d" +msgstr "Seriel port #%d" + +msgid "Server Restarted" +msgstr "Server startet igen" + +msgid "Server Security Auditing" +msgstr "Kontrol af serversikkerhed" + +msgid "Server Started" +msgstr "Server startet" + +msgid "Server Stopped" +msgstr "Server stoppet" + +msgid "Service Unavailable" +msgstr "Service utilgængelig" + +msgid "Set Allowed Users" +msgstr "Indstil tilladte brugere" + +msgid "Set As Server Default" +msgstr "Indstil som serverstandard" + +msgid "Set Class Options" +msgstr "Foretag klasseindstillinger " + +msgid "Set Printer Options" +msgstr "Foretag printerindstillinger " + +msgid "Set Publishing" +msgstr "Indstil publicering" + +msgid "Shipping Address" +msgstr "Leveringsadresse" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Leveringsadresse - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Kort kant (liggende)" + +msgid "Special Paper" +msgstr "Specielt papir" + +msgid "Standard" +msgstr "Standard" + +msgid "Starting Banner" +msgstr "Starter banner" + +msgid "Statement" +msgstr "Udtalelse" + +msgid "Stylus Color Series" +msgstr "Stylus Color Series" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo Series" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Skifter protokoller" + +msgid "Tabloid" +msgstr "17 x 11\"" + +msgid "Tabloid (Oversize)" +msgstr "17 x 11\" (overstørrelse)" + +msgid "Tear" +msgstr "Riv" + +msgid "Tear-Off" +msgstr "Riv af" + +msgid "Tear-Off Adjust Position" +msgstr "Riv af, juster position" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "PPD-arkivet \"%s\" findes ikke." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "PPD-arkivet \"%s\" kunne ikke åbnes: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Klassenavnet må kun indeholde op til 127 tegn, der kan udskrives, og må ikke " +"indeholde mellemrum, skråstreger (/) og nummertegnet (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "Egenskaben notify-lease-duration kan ikke bruges med jobabonnementer." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Værdien for notify-user-data er for stor (%d > 63 oktetter)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Printernavnet må kun indeholde op til 127 tegn, der kan udskrives, og må " +"ikke indeholde mellemrum, skråstreger (/) og nummertegnet (#)." + +msgid "The printer or class is not shared!" +msgstr "Printeren eller klassen er ikke delt!" + +msgid "The printer or class was not found." +msgstr "Printeren eller klassen findes ikke." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Printer-uri \"%s\" indeholder ugyldige tegn." + +msgid "The printer-uri attribute is required!" +msgstr "Egenskaben printer-uri kræves!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "Printer-uri skal have formatet \"ipp://VÆRTSNAVN/klasser/KLASSENAVN\"." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"Printer-uri skal have formatet \"ipp://VÆRTSNAVN/printere/PRINTERNAVN\"." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Abonnementsnavnet må ikke indeholde mellemrum, skråstreger (/), " +"spørgsmålstegn (?) og nummertegnet (#)." + +msgid "There are too many subscriptions." +msgstr "Der er for mange abonnementer." + +msgid "Thermal Transfer Media" +msgstr "Termiske overførselsmedier" + +msgid "Title: " +msgstr "Titel: " + +msgid "Toner low." +msgstr "Toner lav." + +msgid "Too many active jobs." +msgstr "For mange aktive job." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "For mange job-sheets-værdier (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "For mange printer-state-reasons-værdier (%d > %d)!" + +msgid "Transparency" +msgstr "Gennemsigtighed" + +msgid "Tray" +msgstr "Bakke" + +msgid "Tray 1" +msgstr "Bakke 1" + +msgid "Tray 2" +msgstr "Bakke 2" + +msgid "Tray 3" +msgstr "Bakke 3" + +msgid "Tray 4" +msgstr "Bakke 4" + +msgid "URI Too Long" +msgstr "URI for lang" + +msgid "US Executive" +msgstr "7,25 x 10,5\"" + +msgid "US Fanfold" +msgstr "Amerikansk fanfold" + +msgid "US Ledger" +msgstr "17 x 11\"" + +msgid "US Legal" +msgstr "8,5 x 14\"" + +msgid "US Legal (Oversize)" +msgstr "8,5 x 14\" (overstørrelse)" + +msgid "US Letter" +msgstr "8,5 x 11\"" + +msgid "US Letter (Oversize)" +msgstr "8,5 x 11\" (overstørrelse)" + +msgid "US Letter (Small)" +msgstr "8,5 x 11\" (beskåret)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Seriel USB-port #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Kan ikke få adgang til arkivet cupsd.conf:" + +msgid "Unable to add RSS subscription:" +msgstr "Kan ikke tilføje RSS-abonnement:" + +msgid "Unable to add class:" +msgstr "Kan ikke tilføje klasse:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Kan ikke tilføje job til destinationen \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Kan ikke tilføje printer:" + +msgid "Unable to allocate memory for file types!" +msgstr "Kan ikke tildele hukommelse til arkivtyper!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Kan ikke annullere RSS-abonnement:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Kan ikke ændre egenskaben printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Kan ikke skifte printer:" + +msgid "Unable to change server settings:" +msgstr "Kan ikke ændre serverindstillinger:" + +msgid "Unable to connect to host." +msgstr "Kan ikke oprette forbindelse til vært." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Kan ikke kopiere 64 bit CUPS-printerarkiver (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "Kan ikke kopiere 64 bit Windows-printerarkiver (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Kan ikke kopiere CUPS-printerarkiver (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Kan ikke kopiere PPD-arkiv - %s!" + +msgid "Unable to copy PPD file!" +msgstr "Kan ikke kopiere PPD-arkiv!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Kan ikke kopiere Windows 2000-printerarkiver (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Kan ikke kopiere Windows 9x-printerarkiver (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Kan ikke kopiere grænsefladeinstruks - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Kan ikke oprette printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Kan ikke oprette midlertidigt arkiv:" + +msgid "Unable to delete class:" +msgstr "Kan ikke slette klasse:" + +msgid "Unable to delete printer:" +msgstr "Kan ikke slette printer:" + +msgid "Unable to do maintenance command:" +msgstr "Kan ikke udføre vedligeholdelseskommando:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Kan ikke redigere cupsd.conf-arkiver på mere end 1 MB!" + +msgid "Unable to find destination for job!" +msgstr "Kan ikke finde jobbets destination!" + +msgid "Unable to find printer!\n" +msgstr "Kan ikke finde printer!\n" + +msgid "Unable to get class list:" +msgstr "Kan ikke hente klasseliste:" + +msgid "Unable to get class status:" +msgstr "Kan ikke hente klassestatus:" + +msgid "Unable to get list of printer drivers:" +msgstr "Kan ikke hente liste over printerarkiver:" + +msgid "Unable to get printer attributes:" +msgstr "Kan ikke hente printerattributter:" + +msgid "Unable to get printer list:" +msgstr "Kan ikke hente printerliste:" + +msgid "Unable to get printer status:" +msgstr "Kan ikke hente printerstatus:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Kan ikke installere Windows 2000-printerarkiver (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Kan ikke installere Windows 9x-printerarkiver (%d)!" + +msgid "Unable to modify class:" +msgstr "Kan ikke ændre klasse:" + +msgid "Unable to modify printer:" +msgstr "Kan ikke ændre printer:" + +msgid "Unable to move job" +msgstr "Kan ikke flytte job" + +msgid "Unable to move jobs" +msgstr "Kan ikke flytte job" + +msgid "Unable to open PPD file" +msgstr "Kan ikke åbne PPD-arkiv" + +msgid "Unable to open PPD file:" +msgstr "Kan ikke åbne PPD-arkiv:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Kan ikke åbne arkivet cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Kan ikke åbne dokument %d i job %d!" + +msgid "Unable to print test page:" +msgstr "Kan ikke udskrive testside:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Kan ikke afvikle \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Kan ikke sende kommando til printerarkiv!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Kan ikke indstille Windows-printerarkiv (%d)!" + +msgid "Unable to set options:" +msgstr "Kan ikke foretageindstillinger:" + +msgid "Unable to set server default:" +msgstr "Kan ikke indstille serverstandard:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Kan ikke overføre arkivet cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Kan ikke bruge oprindeligt printerarkiv af USB-klasse!\n" + +msgid "Unauthorized" +msgstr "Ikke godkendt" + +msgid "Units" +msgstr "Enheder" + +msgid "Unknown" +msgstr "Ukendt" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Ukendt printer-error-policy \"%s\"." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Ukendt printer-op-policy \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Ikke understøttet tegnsæt \"%s\"!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Ikke understøttet komprimering \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Ikke understøttet komprimeringsegenskab %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Ikke understøttet format \"%s\"!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Ikke understøttet format \"%s\"!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Ikke understøttet format '%s/%s'!" + +msgid "Unsupported value type" +msgstr "Ikke understøttet værditype" + +msgid "Upgrade Required" +msgstr "Opgradering kræves" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Brug:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Brug: %s job user title copies options [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Brug: %s job-id user title copies options [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Brug: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Brug: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Indstillinger:\n" +" -E Krypter forbindelsen til serveren\n" +" -H samba-server Brug den navngivne SAMBA-server\n" +" -U samba-user Godkend vha. den navngivne SAMBA-bruger\n" +" -a Eksporter alle printere\n" +" -h cups-server Brug den navngivne CUPS-server\n" +" -v Vær detaljeret (vis kommandoer)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Brug: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Indstillinger:\n" +"\n" +" -E Slå kryptering til\n" +" -U brugernavn Angiv brugernavn\n" +" -h server[:port] Angiv serveradresse\n" +"\n" +" --[no-]debug-logging Slå fejlfindingslog til/fra\n" +" --[no-]remote-admin Slå ekstern administration til/fra\n" +" --[no-]remote-any Tillad/afvis adgang fra Internet\n" +" --[no-]remote-printers Vis/skjul eksterne printere\n" +" --[no-]share-printers Slå printerdeling til/fra\n" +" --[no-]user-cancel-any Brugere må/må ikke annullere alle job\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Brug: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Indlæs alternativt konfigurationsarkiv\n" +"-f Afvikl i forgrunden\n" +"-F Afvikl i baggrunden, men fjern\n" +"-h Vis denne brugsmeddelelse\n" +"-l Start cupsd fra startd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Brug: cupstestdsc [options] arkivnavn.ps [... arkivnavn.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Indstillinger:\n" +"\n" +" -h Vis programbrug\n" +"\n" +" Bemærk: Dette program godkender kun DSC-kommentarer, ikke selve " +"PostScript.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Brug: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Brug: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Brug: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Brug: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Brug: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Brug: ppdc [options] arkivnavn.drv [ ... arkivnavnN.drv ]\n" +"Indstillinger:\n" +" -D name=value Indstil navngiven variabel til værdi.\n" +" -I include-dir Tilføj inkluder bibliotek i søgesti.\n" +" -c catalog.po Indlæs det anførte beskedkatalog.\n" +" -d output-dir Angiv resultatbiblioteket.\n" +" -l lang[,lang,...] Angiv resultatsproget(-sprogene) (locale).\n" +" -m Brug ModelName-værdien som arkivnavnet.\n" +" -t Test PPD'er i stedet for at generere dem.\n" +" -v Vær detaljeret (flere v'er giver flere detaljer).\n" +" -z Komprimer PPD-arkiver vha. GNU zip.\n" +" --cr Afslut linjer med CR (Mac OS 9).\n" +" --crlf Afslut linjer med CR + LF (Windows).\n" +" --lf Afslut linjer med LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Brug: ppdhtml [options] arkivnavn.drv >arkivnavn.html\n" +" -D name=value Indstil navngiven variabel til værdi.\n" +"Indstillinger:\n" +" -I include-dir Tilføj inkluder bibliotek i søgesti.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Brug: ppdi [options] arkivnavn.ppd [ ... arkivnavnN.ppd ]\n" +"Indstillinger:\n" +" -I include-dir\n" +" -o arkivnavn.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Brug: ppdmerge [options] arkivnavn.ppd [ ... arkivnavnN.ppd ]\n" +"Indstillinger:\n" +" -o arkivnavn.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Brug: ppdpo [options] -o arkivnavn.po arkivnavn.drv [ ... arkivnavnN.drv ]\n" +"Indstillinger:\n" +" -D name=value Indstil navngiven variabel til værdi.\n" +" -I include-dir Tilføj inkluder bibliotek i søgesti.\n" +" -v Vær detaljeret (flere v'er giver flere detaljer).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Brug: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Værdi bruger uendelig længde" + +msgid "VarBind uses indefinite length" +msgstr "VarBind bruger uendelig længde" + +msgid "Version uses indefinite length" +msgstr "Version bruger uendelig længde" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Tilføjer kun de første %d fundne printere" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Boolesk forventet for indstillingen waiteof \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Kunne ikke læse anmodningen om side-channel!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" +"WARNING: Indstillingen \"%s\" kan ikke inkluderes via IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Printer svarer ikke!\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Printer sendte uventet EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Ekstern vært svarede ikke med kommandostatus-byte efter %d " +"sekunder!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Ekstern vært svarede ikke med kontrolstatus-byte efter %d " +"sekunder!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Ekstern vært svarede ikke med datastatus-byte efter %d sekunder!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: Timeout i SCSI-kommando (%d); prøver igen...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Dette dokument overholder ikke Adobe Document Structuring " +"Conventions og udskrives muligvis ikke korrekt!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Kan ikke åbne \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Kan ikke sende PAP status-anmodning" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Uventet PAP-pakke af typen %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Ukendt PAP-pakke af typen %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Ukendt valg \"%s\" til indstillingen \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Ukendt indstilling \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Ikke understøttet baudhastighed %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: tal forventet for indstillingen status \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: Kan gendannes: Netværksværten '%s' er i brug; prøver igen om %d " +"sekunder...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Advarsel - der er ikke installeret nogen Windows 2000-printerarkiver!" + +msgid "Yes" +msgstr "Ja" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Du skal åbne denne side vha. URL-adressen https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "You4-kuvert" + +msgid "ZPL Label Printer" +msgstr "ZPL-etiketprinter" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "afbrudt" + +msgid "canceled" +msgstr "annulleret" + +msgid "completed" +msgstr "færdig" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "" +"konverter: Brug indstillingen -f til at anføre et arkiv, der skal " +"konverteres.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced blev ikke udført." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd blev ikke udført." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Intet PPD-arkiv til printeren \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Kan ikke oprette forbindelse til server: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Ukendt indstilling \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Ukendt indstilling \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Forventede config-arkivnavn efter indstillingen \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Kan ikke hente aktuelt bibliotek!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Ukendt argument \"%s\" - afbryder!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Ukendt indstilling \"%c\" - afbryder!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: launchd(8)-understøttelse ikke medkompileret, afvikles i normal " +"funktion.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Ugyldigt dokumentnummer %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: Ugyldig job-id %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Der kan kun anføres et arkivnavn!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Kan ikke hente jobarkiv - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "" +"cupstestppd: Indstillingen -q er ikke kompatibel med indstillingen -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "" +"cupstestppd: Indstillingen -v er ikke kompatibel med indstillingen -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "enhed til %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "enhed til %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index bruger uendelig længde" + +msgid "error-status uses indefinite length" +msgstr "error-status bruger uendelig længde" + +msgid "held" +msgstr "udsat" + +msgid "help\t\tget help on commands\n" +msgstr "hjælp\t\tfå hjælp til kommandoer" + +msgid "idle" +msgstr "ledig" + +msgid "job-printer-uri attribute missing!" +msgstr "egenskaben job-printer-uri mangler!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Klassenavn må kun indeholde tegn, der kan udskrives!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: Forventede PPD efter indstillingen '-P'!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Forventede allow/deny:userlist efter indstillingen '-u'!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Forventede klasse efter indstillingen '-r'!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Forventede klassenavn efter indstillingen '-c'!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Forventede beskrivelse efter indstillingen '-D'!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Forventede enheds-URI efter indstillingen '-v'!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Forventede arkivtype(r) efter indstillingen '-I'!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Forventede værtsnavn efter indstillingen '-h'!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Forventede grænseflade efter indstillingen '-i'!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Forventede placering efter indstillingen '-L'!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Forventede model efter indstillingen '-m'!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Forventede navn=værdi efter indstillingen '-o'!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Forventede printer efter indstillingen '-p'!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Forventede printernavn efter indstillingen '-d'!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Forventede printer eller klasse efter indstillingen '-x'!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Ingen medlemsnavne set!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Printeren %s er allerede medlem af klassen %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Printeren %s er ikke medlem af klassen %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Printernavn må kun indeholde tegn, der kan udskrives!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke føje en printer til klassen:\n" +" Du skal først angive et printernavn!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Kan ikke oprette forbindelse til server: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Kan ikke åbne PPD-arkivet \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Kan ikke åbne arkivet \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke fjerne en printer fra klassen:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille PPD-arkivet:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille enheds-URI'en:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille grænsefladeinstruksen eller PPD-arkivet:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille grænsefladeinstruksen:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille printerbeskrivelsen:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille printerens placering:\n" +" Du skal først angive et printernavn!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke indstille printerens udstyr:\n" +" Du skal først angive et printernavn!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Ukendt indstilling for tillad/afvis \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Ukendt argument \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Ukendt indstilling '%c'!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Advarsel - listen indholdstype ignoreret!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: Forventede 1284-enheds-id-streng efter --device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Forventede sprog efter --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Forventede mærke og model efter --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Forventede produktstreng efter --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Forventede planliste efter --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Forventede planliste efter --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Forventede timeout efter --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Ukendt argument \"%s\"!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Ukendt indstilling '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Ukendt indstilling '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Kan ikke oprette forbindelse til server: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Ukendt argument \"%s\"!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Ukendt indstilling '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Ingen printere!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Kan ikke tilføje printer eller tilfælde: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Kan ikke hente PPD-arkivet til %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Kan ikke åbne PPD-arkivet til %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Ukendt printer eller klasse!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Det er kun root, der må tilføje og slette adgangskoder!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Adgangskodearkiv i brug!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Adgangskodearkiv ikke opdateret!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Beklager, adgangskoderne er ikke de samme!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Beklager, adgangskode afvist. Adgangskoden skal bestå af mindst 6 " +"tegn, må ikke indeholde dit brugernavn og skal indeholde mindst et bogstav " +"og et tal.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Beklager, adgangskoderne er ikke de samme!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Kan ikke kopiere adgangskodestreng: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Kan ikke åbne adgangskodearkiv: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Kan ikke skrive til adgangskodearkiv: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: kunne ikke sikkerhedskopiere gammelt adgangskodearkiv: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: kunne ikke omdøbe adgangskodearkiv: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: brugeren \"%s\" og gruppen \"%s\" findes ikke.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: Fejl - %s-miljøvariabel navngiver ikke eksisterende destination \"%s" +"\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "medlemmer af klassen %s:\n" + +msgid "no entries\n" +msgstr "ingen optegnelser" + +msgid "no system default destination\n" +msgstr "ingen standarddestination til system" + +msgid "notify-events not specified!" +msgstr "notify-events ikke anført!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI \"%s\" er allerede brugt!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI \"%s\" bruger ukendt skema!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d ikke i orden!" + +msgid "pending" +msgstr "afventer" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Tilføjer inkluder bibliotek \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Tilføjer/opdaterer ui-tekst fra %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Ugyldig booleesk værdi (%s) på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ugyldigt opløsningsnavn \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Ugyldigt statusnøgleord %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Ugyldig variabelerstatning ($%c) på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Valg fundet på linje %d af %s uden nogen indstilling!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Dubleret #po for lokalitet %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Forventede en filterdefinition på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Forventede et programnavn på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Forventede booleesk værdi på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Forventede tegnsæt efter Font på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Forventede valgkode på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Forventede valgnavn/-tekst på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Forventede farverækkefølge til ColorModel på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Forventede farveområde til ColorModel på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Forventede komprimering til ColorModel på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Forventede begrænsningsstreng til UIConstraints på linje %d af %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Forventede nøgleord til printerarkivtype efter DriverType på linje %d " +"af %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Forventede duplekstype efter Duplex på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Forventede kodning efter Font på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Forventede arkivnavn efter #po %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Forventede gruppenavn/-tekst på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Forventede inkluder arkivnavn på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Forventede heltal på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Forventede lokalitet efter #po på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter FileName på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter Font på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter Manufacturer på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter MediaSize på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter ModelName på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Forventede navn efter PCFileName på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Forventede navn/tekst efter %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Forventede navn/tekst efter Installable på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Forventede navn/tekst efter Resolution på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Forventede navn-/tekstkombination til ColorModel på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Forventede indstillingsnavn/-tekst på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Forventede indstillingssektion på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Forventede indstillingstype på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: Forventede tilsidesættelsesfelt efter Resolution på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Forventede rigtigt tal på linje %d af %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Forventede opløsnings-/medietype efter ColorProfile på linje %d af %" +"s.\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Forventede opløsnings-/medietype efter SimpleColorProfile på linje %d " +"af %s.\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Forventede vælger efter %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Forventede status efter Font på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Forventede streng efter Copyright på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Forventede streng efter Version på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Forventede to indstillingsnavne på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Forventede værdi efter %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Forventede version efter Font på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Ugyldigt #include/#po-arkivnavn \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Ugyldig omkostning for filter på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Ugyldig tom MIME-type for filter på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Ugyldigt tomt programnavn for filter på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ugyldig indstillingssektion \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ugyldig indstillingstype \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Indlæser oplysningsarkiv til printerarkiv \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Indlæser beskeder til lokalitet \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Indlæser beskeder fra \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: Manglende #endif i slutningen af \"%s\"!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: Manglende #if på linje %d af %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Intet beskedkatalog til lokalitet %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" +"ppdc: Indstilling %s omdefineret med en anden type på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Indstillingen constraint skal *name på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: For mange indlejrede #if-udsagn på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: Kan ikke oprette PPD-arkivet \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Kan ikke oprette resultatbibliotek %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Kan ikke oprette resultatrør: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Kan ikke udføre cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Kan ikke finde #po-arkiv %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: Kan ikke finde inkluder arkiv \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Kan ikke finde lokalisering for \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Kan ikke indlæse lokaliseringsarkivet \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Udefineret variabel (%s) på linje %d af %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Ukendt type printerarkiv %s på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ukendt duplekstype \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ukendt mediestørrelse \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Ukendt mærke \"%s\" set på linje %d af %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Ukendt udpunkteringstegn i rigtige tal \"%s\" på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Uafsluttet streng startende fra %c på linje %d af %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Skriver %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Skriver PPD-arkiver til bibliotek \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Ugyldig LanguageVersion \"%s\" in %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Ignorerer PPD-arkiv %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Kan ikke sikkerhedskopiere %s til %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "printeren %s slået fra siden %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "printeren %s er ledig. Slået til siden %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "printeren %s udskriver nu %s-%d. Slået til siden %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "printeren %s/%s slået fra siden %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "printeren %s/%s er ledig. Slået til siden %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "printeren %s/%s udskriver nu %s-%d. Slået til siden %s\n" + +msgid "processing" +msgstr "behandler" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "anmodnings-id er %s-%d (%d arkiv(er))\n" + +msgid "request-id uses indefinite length" +msgstr "request-id bruger uendelig længde" + +msgid "scheduler is not running\n" +msgstr "planlægger er ikke aktiv\n" + +msgid "scheduler is running\n" +msgstr "planlægger er aktiv\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "stat af %s mislykkedes: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tvis status for daemon og kø\n" + +msgid "stopped" +msgstr "stoppet" + +#, c-format +msgid "system default destination: %s\n" +msgstr "standarddestination til system: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "standarddestination til system: %s/%s\n" + +msgid "unknown" +msgstr "ukendt" + +msgid "untitled" +msgstr "uden navn" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings bruger uendelig længde" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN Manglende APDialogExtension-arkiv \"%s\"\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN Manglende APPrinterIconPath-arkiv \"%s\"\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Kan ikke åbne %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Kan ikke åbne %s - %s på linje %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 dpi gråtoner" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Manglende enheds-URI på kommandolinjen og ingen DEVICE_URI-" +#~ "miljøvariabel!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Kan ikke oprette midlertidigt arkiv - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Kan ikke oprette midlertidigt arkiv: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Kan ikke åbne midlertidigt arkiv" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops-filter gik ned på signalet %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops-filter afsluttede med status %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Ukendt printerfejl (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Brug: convert [ options ]\n" +#~ "\n" +#~ "Indstillinger:\n" +#~ "\n" +#~ " -f arkivnavn Indstil arkiv, der skal konverteres (otherwise " +#~ "stdin)\n" +#~ " -o arkivnavn Indstil arkiv, der skal genereres (otherwise " +#~ "stdout)\n" +#~ " -i mime/type Indstil indgående MIME-type (otherwise auto-" +#~ "typed)\n" +#~ " -j mime/type Indstil udgående MIME-type (otherwise application/" +#~ "pdf)\n" +#~ " -P arkivnavn.ppd Indstil PPD-arkiv\n" +#~ " -a 'name=value ...' Juster indstilling(er)\n" +#~ " -U brugernavn Indstil brugernavn til job\n" +#~ " -J titel Indstil titel\n" +#~ " -c kopier Indstil antal kopier\n" +#~ " -u Fjern PPD-arkiv når færdig\n" +#~ " -D Fjern indgående arkiv når færdig\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Brug: cupsfilter -m mime/type [ options ] arkivnavn\n" +#~ "\n" +#~ "Indstillinger:\n" +#~ "\n" +#~ " -c cupsd.conf Indstil cupsd.conf-arkiv til at bruge\n" +#~ " -j job-id[,N] Filter arkiv N fra det anførte job (standard er arkiv " +#~ "1)\n" +#~ " -n kopier Indstil antal kopier\n" +#~ " -o name=value Juster indstilling(er)\n" +#~ " -p arkivnan.ppd Indstil PPD-arkiv\n" +#~ " -t titel Indstil titel\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Brug: cupstestppd [options] arkivnavn1.ppd[.gz] [... arkivnavnN.ppd[." +#~ "gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Indstillinger:\n" +#~ "\n" +#~ " -R root-directory Indstil alternativ root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Udsted advarsler i stedet for fejl\n" +#~ " -q Afvikl i baggrunden\n" +#~ " -r Brug 'relaxed' åben funktion\n" +#~ " -v Vær en anelse detaljeret\n" +#~ " -vv Vær meget detaljseret\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Kan ikke oprette midlertidigt arkiv: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Kan ikke oprette midlertidigt arkiv - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Kan ikke oprette midlertidigt arkiv: %s\n" diff --git a/locale/cups_de.po b/locale/cups_de.po new file mode 100644 index 0000000000..3874e969de --- /dev/null +++ b/locale/cups_de.po @@ -0,0 +1,5703 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(alles)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(ohne)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d Einträge\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tNach Fehler: fortsetzen\n" + +msgid "\tAlerts:" +msgstr "\tWarnhinweise:" + +msgid "\tBanner required\n" +msgstr "\tBanner erforderlich\n" + +msgid "\tCharset sets:\n" +msgstr "\tZeichensätze:\n" + +msgid "\tConnection: direct\n" +msgstr "\tVerbindung: direkt\n" + +msgid "\tConnection: remote\n" +msgstr "\tVerbindung: enfernt\n" + +msgid "\tDefault page size:\n" +msgstr "\tStandardseitengröße:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tStandardzeilenhöhe:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tStandard-Anschlusseinstellungen:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tBeschreibung: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormular aktiviert:\n" +"\tInhaltstypen: beliebig\n" +"\tDruckertypen: unbekannt\n" + +msgid "\tForms allowed:\n" +msgstr "\tZugelassene Formulare:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tSchnittstelle: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tSchnittstelle: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tSchnittstelle: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tStandort: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tBei Fehler: kein Warnhinweis\n" + +msgid "\tUsers allowed:\n" +msgstr "\tZugelassene Benutzer:\n" + +msgid "\tUsers denied:\n" +msgstr "\tGesperrte Benutzer:\n" + +msgid "\tdaemon present\n" +msgstr "\tDaemon vorhanden\n" + +msgid "\tno entries\n" +msgstr "\tkeine Einträge\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tDrucker ist auf Geschwindigkeit des Geräts „%s“ -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tDrucken ist deaktiviert\n" + +msgid "\tprinting is enabled\n" +msgstr "\tDrucken ist aktiviert\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tWarteliste für %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tWarteliste ist deaktiviert\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tWarteliste ist aktiviert\n" + +msgid "\treason unknown\n" +msgstr "\tGrund unbekannt\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" AUSFÜHRLICHE KONFORMITÄTSTESTERGEBNISSE\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Seite 15, Abschnitt 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Seite 15, Abschnitt 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Seite 19, Abschnitt 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Seite 20, Abschnitt 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Seite 27, Abschnitt 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Seite 42, Abschnitt 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Seite 16–17, Abschnitt 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Seite 42–45, Abschnitt 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Seite 45–46, Abschnitt 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Seite 48–49, Abschnitt 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Seite 52–54, Abschnitt 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f Byte\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN Konflikt zwischen „%s %s“ und „%s %s“\n" +" (constraint=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s hat keine passenden Optionen!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s hat eine gemeinsames übliches Präfix mit %s\n" +" REF: Seite 15, Abschnitt 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Konflikt bei Standardauswahl!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Duplex-Option-Keyword „%s“ funktioniert u. U. nicht wie " +"erwartet – es sollte „Duplex“ heißen!\n" +" REF: Seite 122, Abschnitt 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN Datei enthält Mischung aus den Zeilenenden „CR“, „LF“ und " +"„CR LF“!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding benötigt von PPD 4.3 Spezifikation.\n" +" REF: Seite 56–57, Abschnitt 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Zeile %d enthält nur Leerzeichen!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Manufacturer benötigt von PPD 4.3 Spezifikation.\n" +" REF: Seite 58–59, Abschnitt 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN Windows-fremde PPD-Datei sollte nur Zeilenenden mit „LF“ " +"verwenden, nicht mit „CR LF“!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Veraltete PPD-Version %.1f!\n" +" REF: Seite 42, Abschnitt 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName ist länger als 8.3 und verstößt gegen die PPD-" +"Spezifikation.\n" +" REF: Seite 61–62, Abschnitt 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokolle enthalten PJL, aber JCL-Attribute sind nicht " +"festgelegt.\n" +" REF: Seite 78–79, Abschnitt 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokolle enthalten PJL sowie BCP; es wurde aber TBCP " +"erwartet.\n" +" REF: Seite 78–79, section 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName benötigt von PPD 4.3 Spezifikation.\n" +" REF: Seite 64–65, Abschnitt 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s existiert nicht!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Ungültig: %s Auswahl %s!\n" +" REF: Seite 122, Abschnitt 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Ungültiger UTF-8 „%s“ Übersetzungsstring für Option „%s“!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Ungültiger UTF-8 „%s“ Übersetzungsstring für Option „%s“, Auswahl " +"„%s“!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Ungültiger cupsFilter-Wert „%s“!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Ungültiges cupsICCProfile „%s“!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Ungültiger cupsPreFilter-Wert „%s“!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Ungültiges cupsUIConstraints „%s“: „%s“!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Ungültige Sprache „%s“!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Leeres cupsUIConstraints „%s“!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Fehlender „%s“-Übersetzungsstring für Option „%s“!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Fehlender „%s“-Übersetzungsstring für Option „%s“, Auswahl „%s“!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Fehlende Auswahl „*%s %s“ in UIConstraints „*%s %s *%s %s“!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Fehlende Auswahl „*%s %s“ in cupsUIConstraints „%s“: „%s“!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Fehlende cupsFilter-Datei „%s“\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Fehlende cupsICCProfile-Datei „%s“!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Fehlende cupsPreFilter-Datei „%s“\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Fehlender cupsUIResolver „%s“!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Fehlende Option „%s“ in UIConstraints „*%s %s *%s %s“!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Fehlende Option „%s“ in cupsUIConstraints „%s“: „%s“!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Keine Basisübersetzung „%s“ in der Datei enthalten!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s BENÖTIGT: „%s“ definiert Auswahl nicht als „None“!\n" +" REF: Seite 122, Abschnitt 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s Hash-Wert von cupsICCProfile „%s“ in Konflikt mit „%s“!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver „%s“ erzeugt eine Schleife!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FEHLER** %s-Auswahlnamen „%s“ und „%s“ unterscheiden sich nur durch " +"Groß-/Kleinschreibung!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FEHLER** „%s“ muss 1284DeviceID sein!\n" +" REF: Seite 72, Abschnitt 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: Default%s „%s“\n" +" REF: Seite 40, Abschnitt 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: DefaultImageableArea „%s“!\n" +" REF: Seite 102, Abschnitt 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: DefaultPaperDimension „%s“!\n" +" REF: Seite 103, Abschnitt 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: JobPatchFile-Attribut in Datei\n" +" REF: Seite 24, Abschnitt 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: Manufacturer (sollte „HP“ sein)\n" +" REF: Seite 211, Tabelle D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: Manufacturer (sollte „Oki“ sein)\n" +" REF: Seite 211, Tabelle D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: ModelName – „%c“ nicht zulässig im String.\n" +" REF: Seite 59–60, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: PSVersion – nicht „(string) int“.\n" +" REF: Seite 62–64, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: Product – nicht „(string)“.\n" +" REF: Seite 62, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FEHLER** UNGÜLTIG: ShortNickName – länger als 31 Zeichen.\n" +" REF: Seite 64–65, Abschnitt 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FEHLER** Ungültig: „%s“ Auswahl „%s“!\n" +" REF: Seite 84, Abschnitt 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEHLER** Ungültige FileVersion „%s“\n" +" REF: Seite 56, Abschnitt 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEHLER** Ungültige FormatVersion „%s“\n" +" REF: Seite 56, Abschnitt 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **FEHLER** Ungültiges LanguageEncoding „%s“ – muss „ISOLatin1“ sein!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **FEHLER** Ungültige LanguageVersion „%s“ – muss „Englisch“ sein!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FEHLER** Standardoptionscode kann nicht interpretiert werden: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FEHLER** Standard-Übersetzungsstring für Option „%s“ Auswahl „%s“ " +"enthält 8-Bit-Zeichen!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FEHLER** Standard-Übersetzungsstring für Option „%s“ enthält 8-Bit-" +"Zeichen!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FEHLER** Gruppennamen „%s“ und „%s“ unterscheiden sich nur durch " +"Groß-/Kleinschreibung!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FEHLER** Mehrere Vorkommen des „%s“-Auswahlnamens „%s“!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FEHLER** Optionnamen „%s“ und „%s“ unterscheiden sich nur durch " +"Groß-/Kleinschreibung!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FEHLER** BENÖTIGT: Default%s\n" +" REF: Seite 40, Abschnitt 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEHLER** BENÖTIGT: DefaultImageableArea\n" +" REF: Seite 102, Abschnitt 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEHLER** BENÖTIGT: DefaultPaperDimension\n" +" REF: Seite 103, Abschnitt 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: FileVersion\n" +" REF: Seite 56, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: FormatVersion\n" +" REF: Seite 56, Abschnitt 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEHLER** BENÖTIGT: ImageableArea für PageSize „%s“\n" +" REF: Seite 41, Abschnitt 5.\n" +" REF: Seite 102, Abschnitt 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: LanguageEncoding\n" +" REF: Seite 56–57, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: LanguageVersion\n" +" REF: Seite 57–58, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: Manufacturer\n" +" REF: Seite 58–59, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: ModelName\n" +" REF: Seite 59–60, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: NickName\n" +" REF: Seite 60, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: PCFileName\n" +" REF: Seite 61–62, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: PSVersion\n" +" REF: Seite 62–64, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FEHLER** BENÖTIGT: PageRegion\n" +" REF: Seite 100, Abschnitt 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FEHLER** BENÖTIGT: PageSize\n" +" REF: Seite 41, Abschnitt 5.\n" +" REF: Seite 99, Abschnitt 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FEHLER** BENÖTIGT: PageSize\n" +" REF: Seite 99–100, Abschnitt 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEHLER** BENÖTIGT: PaperDimension für PageSize „%s“\n" +" REF: Seite 41, Abschnitt 5.\n" +" REF: Seite 103, Abschnitt 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: Product\n" +" REF: Seite 62, Abschnitt 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FEHLER** BENÖTIGT: ShortNickName\n" +" REF: Seite 64–65, Abschnitt 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d FEHLER GEFUNDEN\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Ungültige %%%%BoundingBox: in Zeile %d!\n" +" REF: Seite 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Ungültige %%%%Page: in Zeile %d!\n" +" REF: Seite 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Ungültige %%%%Pages: in Zeile %d!\n" +" REF: Seite 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Zeile %d ist länger als 255 Zeichen (%d)!\n" +" REF: Seite 25, Line Length\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 fehlt in der ersten Zeile!\n" +" REF: Seite 17, 3.1 Conforming Documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" %%EndComments-Kommentar fehlt!\n" +" REF: Seite 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox fehlt oder ist ungültig: Kommentar!\n" +" REF: Seite 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page fehlt oder ist ungültig: Kommentare!\n" +" REF: Seite 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages fehlt oder ist ungültig: Kommentar!\n" +" REF: Seite 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " KEINE FEHLER GEFUNDEN\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " %d Zeilen mit über 255 Zeichen gefunden!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Zu viele %%BeginDocument-Kommentare!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Zu viele %%EndDocument-Kommentare!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Achtung: Datei enthält Binärdaten!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Achtung: kein %%EndComments-Kommentar in der Datei!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Achtung: veraltete DSC-Version %.1f in der Datei!\n" + +msgid " FAIL\n" +msgstr " FEHLER\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FEHLER\n" +" **FEHLER** PPD-Datei konnte nicht geöffnet werden – %s.\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FEHLER\n" +" **FEHLER** PPD-Datei konnte nicht geöffnet werden – %s in Zeile %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "US #10 Umschlag" + +msgid "#11 Envelope" +msgstr "US #11 Umschlag" + +msgid "#12 Envelope" +msgstr "US #12 Umschlag" + +msgid "#14 Envelope" +msgstr "US #14 Umschlag" + +msgid "#9 Envelope" +msgstr "US #9 Umschlag" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f Byte\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f Byte\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f Millimeter" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f bis %.0f x %.0f Millimeter" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f Zoll" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f bis %.2f x %.2f Zoll" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s akzeptiert Anfragen seit %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s kann nicht geändert werden." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s ist nicht implementiert in der CUPS-Version von lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s ist nicht bereit\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s ist bereit\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s ist bereit und druckt\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s akzeptiert keine Anfragen seit %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s nicht unterstützt!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s akzeptiert Anfragen seit %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s akzeptiert keine Anfragen seit %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [Druckauftrag %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s fehlgeschlagen: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Weiß nicht, was ich tun soll!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Fehler – %s Umgebungsvariablennamen nicht vorhanden für Ziel „%s“!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Fehler – ungültige Druckauftrags-ID!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Fehler – kann nicht gleichzeitig Dateien drucken und Druckaufträge " +"ändern!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Fehler – kann nicht von „stdin“, wenn Dateien oder eine Druckauftrags-ID " +"übergeben werden!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Fehler – Zeichensatz erwartet nach '-S'-Option!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Fehler – Inhaltstyp erwartet nach '-T'-Option!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Fehler – Kopien erwartet nach '-n'-Option!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Fehler – Kopienanzahl erwartet nach '-#'-Option!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Fehler – Ziel erwartet nach '-P'-Option!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Fehler – Ziel erwartet nach '-b'-Option!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Fehler – Ziel erwartet nach '-d'-Option!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Fehler – Form erwartet nach '-f'-Option!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Fehler – Name halten erwartet nach '-H'-Option!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Fehler – Hostname erwartet nach '-H'-Option!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Fehler – Hostname erwartet nach '-h'-Option!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Fehler – Modusliste erwartet nach '-y'-Option!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Fehler – Name erwartet nach '-%c'-Option!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Fehler – Optionsstring erwartet nach '-o'-Option!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Fehler – Seitenliste erwartet nach '-P'-Option!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Fehler – Priorität erwartet nach '-%c'-Option!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Fehler – Text mit Grund erwartet nach '-r'-Option!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Fehler – Titel erwartet nach '-t'-Option!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Fehler – Benutzername erwartet nach '-U'-Option!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Fehler – Benutzername erwartet nach '-u'-Option!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Fehler – Wert erwartet nach '-%c'-Option!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Fehler – benötigt „completed“, „not-completed“ oder „all“ nach '-W'-" +"Option!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Fehler – kein Standardziel verfügbar.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Fehler – Priorität muss zwischen 1 und 100 sein.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Fehler – Scheduler reagiert nicht!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Fehler – zu viele Dateien – „%s“\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Fehler – kein Zugriff auf „%s“ – %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Fehler – keine Warteliste für „stdin“ – %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Fehler – unbekanntes Ziel „%s“!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Fehler – unbekanntes Ziel „%s/%s“!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Fehler – unbekannte Option '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Fehler – unbekannte Option '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Druckauftrags-ID erwartet nach '-i'-Option!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filter „%s“ nicht verfügbar: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Ungültiger Zielname in Liste „%s“!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Ungültiger Filterstring „%s“\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Druckauftrags-ID ('-i jobid') benötigt vor '-H restart'!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Kein Filter für Konvertierung von %s/%s zu %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Aktion fehlgeschlagen: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Verschlüsselungsunterstützung nicht verfügbar!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Verbindung mit Server fehlgeschlagen\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Verbindungsaufbau zum Server fehlgeschlagen!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: MIME-Typ von „%s“ konnte nicht bestimmt werden!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: „%s“ konnte nicht geöffnet werden: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: PPD-Datei konnte nicht geöffnet werden – %s in Zeile %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: MIME-Datenbank von „%s“ oder „%s“ konnte nicht gelesen werden!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Unbekanntes Ziel „%s“!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Unbekannter Ziel-MIME-Typ „%s/%s“!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Unbekannte Option '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Unbekannter Quell-MIME-Typ „%s/%s“!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Achtung – '%c'-Format-Modifier nicht unterstützt – Ausgabe ist u. U. " +"nicht korrekt!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Achtung – Zeichensatzoption ignoriert!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Achtung – Inhaltstypoption ignoriert!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Achtung – Formoption ignoriert!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Achtung – Modusoption ignoriert!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Fehler – %s Umgebungsvariablennamen nicht vorhanden für Ziel „%s“!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: Fehler – „option=value“ erwartet nach '-o'-Option!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: Fehler – kein Standardziel verfügbar.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 Zoll/Sek." + +msgid "1.25x0.25\"" +msgstr "1,25x0,25 Zoll" + +msgid "1.25x2.25\"" +msgstr "1,25x2,25 Zoll" + +msgid "1.5 inch/sec." +msgstr "1,5 Zoll/Sek." + +msgid "1.50x0.25\"" +msgstr "1,50x0,25 Zoll" + +msgid "1.50x0.50\"" +msgstr "1,50x0,50 Zoll" + +msgid "1.50x1.00\"" +msgstr "1,50x1,00 Zoll" + +msgid "1.50x2.00\"" +msgstr "1,50x2,00 Zoll" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 Zoll/Sek." + +msgid "10 x 11\"" +msgstr "10 x 11 Zoll" + +msgid "10 x 13\"" +msgstr "10 x 13 Zoll" + +msgid "10 x 14\"" +msgstr "10 x 14 Zoll" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/Sek." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 Zoll/Sek." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 Zoll/Sek." + +msgid "12 x 11\"" +msgstr "12 x 11 Zoll" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/Sek." + +msgid "120x60dpi" +msgstr "120x60 dpi" + +msgid "120x72dpi" +msgstr "120x72 dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/Sek." + +msgid "15 x 11\"" +msgstr "15 x 11 Zoll" + +msgid "150 mm/sec." +msgstr "150 mm/Sek." + +msgid "150dpi" +msgstr "150 dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 Zoll/Sek." + +msgid "2-Sided Printing" +msgstr "Doppelseitig drucken" + +msgid "2.00x0.37\"" +msgstr "2,00x0,37 Zoll" + +msgid "2.00x0.50\"" +msgstr "2,00x0,50 Zoll" + +msgid "2.00x1.00\"" +msgstr "2,00x1,00 Zoll" + +msgid "2.00x1.25\"" +msgstr "2,00x1,25 Zoll" + +msgid "2.00x2.00\"" +msgstr "2,00x2,00 Zoll" + +msgid "2.00x3.00\"" +msgstr "2,00x3,00 Zoll" + +msgid "2.00x4.00\"" +msgstr "2,00x4,00 Zoll" + +msgid "2.00x5.50\"" +msgstr "2,00x5,50 Zoll" + +msgid "2.25x0.50\"" +msgstr "2,25x0,50 Zoll" + +msgid "2.25x1.25\"" +msgstr "2,25x1,25 Zoll" + +msgid "2.25x4.00\"" +msgstr "2,25x4,00 Zoll" + +msgid "2.25x5.50\"" +msgstr "2,25x5,50 Zoll" + +msgid "2.38x5.50\"" +msgstr "2,38x5,50 Zoll" + +msgid "2.5 inches/sec." +msgstr "2,5 Zoll/Sek." + +msgid "2.50x1.00\"" +msgstr "2,50x1,00 Zoll" + +msgid "2.50x2.00\"" +msgstr "2,50x2,00 Zoll" + +msgid "2.75x1.25\"" +msgstr "2,75x1,25 Zoll" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1 Zoll" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/Sek." + +msgid "200 mm/sec." +msgstr "200 mm/Sek." + +msgid "203dpi" +msgstr "203 dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-Pin Serie" + +msgid "240x72dpi" +msgstr "240x72 dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/Sek." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 Zoll/Sek." + +msgid "3.00x1.00\"" +msgstr "3,00x1,00 Zoll" + +msgid "3.00x1.25\"" +msgstr "3,00x1,25 Zoll" + +msgid "3.00x2.00\"" +msgstr "3,00x2,00 Zoll" + +msgid "3.00x3.00\"" +msgstr "3,00x3,00 Zoll" + +msgid "3.00x5.00\"" +msgstr "3,00x5,00 Zoll" + +msgid "3.25x2.00\"" +msgstr "3,25x2,00 Zoll" + +msgid "3.25x5.00\"" +msgstr "3,25x5,00 Zoll" + +msgid "3.25x5.50\"" +msgstr "3,25x5,50 Zoll" + +msgid "3.25x5.83\"" +msgstr "3,25x5,83 Zoll" + +msgid "3.25x7.83\"" +msgstr "3,25x7,83 Zoll" + +msgid "3.5\" Disk" +msgstr "3,5-Zoll-Diskette" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3,5-Zoll-Diskette – 2 1/8 x 2 3/4 Zoll" + +msgid "3.50x1.00\"" +msgstr "3,50x1,00 Zoll" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/Sek." + +msgid "300 mm/sec." +msgstr "300 mm/Sek." + +msgid "300dpi" +msgstr "300 dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 dpi" + +msgid "360x180dpi" +msgstr "360x180 dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 Zoll/Sek." + +msgid "4.00x1.00\"" +msgstr "4,00x1,00 Zoll" + +msgid "4.00x13.00\"" +msgstr "4,00x13,00 Zoll" + +msgid "4.00x2.00\"" +msgstr "4,00x2,00 Zoll" + +msgid "4.00x2.50\"" +msgstr "4,00x2,50 Zoll" + +msgid "4.00x3.00\"" +msgstr "4,00x3,00 Zoll" + +msgid "4.00x4.00\"" +msgstr "4,00x4,00 Zoll" + +msgid "4.00x5.00\"" +msgstr "4,00x5,00 Zoll" + +msgid "4.00x6.00\"" +msgstr "4,00x6,00 Zoll" + +msgid "4.00x6.50\"" +msgstr "4,00x6,50 Zoll" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/Sek." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 Zoll/Sek." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 Zoll/Sek." + +msgid "6.00x1.00\"" +msgstr "6,00x1,00 Zoll" + +msgid "6.00x2.00\"" +msgstr "6,00x2,00 Zoll" + +msgid "6.00x3.00\"" +msgstr "6,00x3,00 Zoll" + +msgid "6.00x4.00\"" +msgstr "6,00x4,00 Zoll" + +msgid "6.00x5.00\"" +msgstr "6,00x5,00 Zoll" + +msgid "6.00x6.00\"" +msgstr "6,00x6,00 Zoll" + +msgid "6.00x6.50\"" +msgstr "6,00x6,50 Zoll" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/Sek." + +msgid "600dpi" +msgstr "600 dpi" + +msgid "60dpi" +msgstr "60 dpi" + +msgid "60x720dpi" +msgstr "60x720 dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 Zoll/Sek." + +msgid "7 x 9\"" +msgstr "7 x 9 Zoll" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 Zoll/Sek." + +msgid "8 x 10\"" +msgstr "8 x 10 Zoll" + +msgid "8.00x1.00\"" +msgstr "8,00x1,00 Zoll" + +msgid "8.00x2.00\"" +msgstr "8,00x2,00 Zoll" + +msgid "8.00x3.00\"" +msgstr "8,00x3,00 Zoll" + +msgid "8.00x4.00\"" +msgstr "8,00x4,00 Zoll" + +msgid "8.00x5.00\"" +msgstr "8,00x5,00 Zoll" + +msgid "8.00x6.00\"" +msgstr "8,00x6,00 Zoll" + +msgid "8.00x6.50\"" +msgstr "8,00x6,50 Zoll" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/Sek." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 Zoll/Sek." + +msgid "9 x 11\"" +msgstr "9 x 11 Zoll" + +msgid "9 x 12\"" +msgstr "9 x 12 Zoll" + +msgid "9-Pin Series" +msgstr "9-Pin Serie" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Ungültiger Hilfebefehl ist unbekannt\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"Es wird ein Samba-Kennwort benötigt, um Druckertreiber exportieren zu können!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Es wird ein Samba-Benutzername benötigt, um Druckertreiber exportieren zu " +"können!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Es gibt bereits eine Klasse mit dem Namen „%s“!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Es gibt bereits einen Drucker mit dem Namen „%s“!" + +msgid "A0" +msgstr "DIN A0" + +msgid "A1" +msgstr "DIN A1" + +msgid "A10" +msgstr "DIN A10" + +msgid "A2" +msgstr "DIN A2" + +msgid "A3" +msgstr "DIN A3" + +msgid "A3 (Oversize)" +msgstr "A3 (Übergröße)" + +msgid "A4" +msgstr "DIN A4" + +msgid "A4 (Oversize)" +msgstr "A4 (Übergröße)" + +msgid "A4 (Small)" +msgstr "A4 (klein)" + +msgid "A5" +msgstr "DIN A5" + +msgid "A5 (Oversize)" +msgstr "A5 (Übergröße)" + +msgid "A6" +msgstr "DIN A6" + +msgid "A7" +msgstr "DIN A7" + +msgid "A8" +msgstr "DIN A8" + +msgid "A9" +msgstr "DIN A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Druckaufträge akzeptieren" + +msgid "Accepted" +msgstr "Akzeptiert" + +msgid "Add Class" +msgstr "Klasse hinzufügen" + +msgid "Add Printer" +msgstr "Drucker hinzufügen" + +msgid "Add RSS Subscription" +msgstr "RSS-Abo hinzufügen" + +msgid "Address" +msgstr "Adresse" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adresse – 1 1/8 x 3 1/2 Zoll" + +msgid "Administration" +msgstr "Verwaltung" + +msgid "Always" +msgstr "Immer" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applicator" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "" +"Versuch, den Druckerstatus für „%s“ auf den ungültigen Wert „%d“ zu setzen!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Attributgruppen sind durcheinander (%x < %x)!" + +msgid "B0" +msgstr "DIN B0" + +msgid "B1" +msgstr "DIN B1" + +msgid "B10" +msgstr "DIN B10" + +msgid "B2" +msgstr "DIN B2" + +msgid "B3" +msgstr "DIN B3" + +msgid "B4" +msgstr "DIN B4" + +msgid "B5" +msgstr "DIN B5" + +msgid "B6" +msgstr "DIN B6" + +msgid "B7" +msgstr "DIN B7" + +msgid "B8" +msgstr "DIN B8" + +msgid "B9" +msgstr "DIN B9" + +msgid "Bad NULL dests pointer" +msgstr "Ungültiger NULL-Dests-Pointer" + +msgid "Bad OpenGroup" +msgstr "Ungültige OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Ungültiges OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Ungültige OrderDependency" + +msgid "Bad Request" +msgstr "Ungültige Anfrage" + +msgid "Bad SNMP version number" +msgstr "Ungültige SNMP-Versionsnummer" + +msgid "Bad UIConstraints" +msgstr "Ungültige UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Ungültiger Kopienwert „%d“." + +msgid "Bad custom parameter" +msgstr "Ungültiger angepasster Parameter" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Ungültige Geräte-URI „%s“!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Ungültige Geräte-URI „%s“!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Ungültiges Geräte-URI-Schema „%s“!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Ungültiges Dokumentformat „%s“!" + +msgid "Bad filename buffer!" +msgstr "Ungültiger Dateinamen-Puffer!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Ungültiges Schriftattribut: %s\n" + +msgid "Bad job-priority value!" +msgstr "Ungültiger Wert für Druckauftragspriorität!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Ungültiger Wert „%s“ für Druckauftragslisten!" + +msgid "Bad job-sheets value type!" +msgstr "Ungültiger Wertetyp für Druckauftragslisten!" + +msgid "Bad job-state value!" +msgstr "Ungültiger Wert für Druckauftragsstatus!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Ungültiges Druckauftrags-URI-Attribut „%s“!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Ungültige Notify-Pull-Methode „%s“!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Ungültige Notify-Recipient-URI: URI „%s“!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Ungültiger Number-Up-Wert „%d“." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Ungültige Option + Auswahl in Zeile %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Ungültige Seitenbereichswerte %d–%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Ungültiger Port-Monitor „%s“!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Ungültiger Wert „%d“ für Druckerstatus!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Ungültige Anfrage-Versionsnummer %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Ungültige Subskriptions-ID!" + +msgid "Banners" +msgstr "Banner" + +msgid "Billing Information: " +msgstr "Rechnungsinformationen: " + +msgid "Bond Paper" +msgstr "Papier bündeln" + +msgid "C0 Envelope" +msgstr "DIN C0 Umschlag" + +msgid "C1 Envelope" +msgstr "DIN C1 Umschlag" + +msgid "C2 Envelope" +msgstr "DIN C2 Umschlag" + +msgid "C3 Envelope" +msgstr "DIN C3 Umschlag" + +msgid "C4" +msgstr "DIN C4" + +msgid "C4 Envelope" +msgstr "DIN C4 Umschlag" + +msgid "C5" +msgstr "DIN C5" + +msgid "C5 Envelope" +msgstr "DIN C5 Umschlag" + +msgid "C6" +msgstr "DIN C6" + +msgid "C6 Envelope" +msgstr "DIN C6 Umschlag" + +msgid "C65 Envelope" +msgstr "DIN C65 Umschlag" + +msgid "C7 Envelope" +msgstr "DIN C7 Umschlag" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL Etikettendrucker" + +msgid "Cancel RSS Subscription" +msgstr "RSS-Abo widerrufen" + +msgid "Change Settings" +msgstr "Einstellungen ändern" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Zeichensatz „%s“ nicht unterstützt!" + +msgid "Chou3 Envelope" +msgstr "Chou3 Umschlag" + +msgid "Chou4 Envelope" +msgstr "Chou4 Umschlag" + +msgid "Classes" +msgstr "Klassen" + +msgid "Clean Print Heads" +msgstr "Saubere Druckerköpfe" + +msgid "Color" +msgstr "Farbe" + +msgid "Color Mode" +msgstr "Farbmodus" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Befehle können abgekürzt werden. Befehle sind:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Community-Name hat unbestimmte Länge" + +msgid "Continue" +msgstr "Weiter" + +msgid "Continuous" +msgstr "Kontinuierlich" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Typ „%s“ konnte nicht durchsucht werden!" + +msgid "Cover open." +msgstr "Die Abdeckung ist offen." + +msgid "Created" +msgstr "Erstellt" + +msgid "Created On: " +msgstr "Erstellt am: " + +msgid "Custom" +msgstr "Eigene" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Abschneiden" + +msgid "Cutter" +msgstr "Abschneider" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL Umschlag" + +msgid "Dark" +msgstr "Dunkel" + +msgid "Darkness" +msgstr "Dunkelheit" + +msgid "Delete Class" +msgstr "Klasse löschen" + +msgid "Delete Printer" +msgstr "Drucker löschen" + +msgid "Description: " +msgstr "Beschreibung: " + +msgid "DeskJet Series" +msgstr "DeskJet Serie" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Ziel „%s“ akzeptiert keine Druckaufträge." + +msgid "Developer almost empty." +msgstr "Der Entwickler ist fast leer." + +msgid "Developer empty!" +msgstr "Der Entwickler ist leer!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Gerät: URI = %s\n" +" Klasse = %s\n" +" Info = %s\n" +" Hersteller und Modell = %s\n" +" Geräte-ID = %s\n" +" Standort = %s\n" + +msgid "Direct Thermal Media" +msgstr "Direct Thermal Media" + +msgid "Disabled" +msgstr "Deaktiviert" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Dokument „%d“ nicht gefunden in Druckauftrag „%d“." + +msgid "Door open." +msgstr "Die Tür ist offen." + +msgid "Double Postcard" +msgstr "Doppelpostkarte" + +msgid "Driver Name: " +msgstr "Treibername: " + +msgid "Driver Version: " +msgstr "Treiberversion: " + +msgid "Duplexer" +msgstr "Duplexer" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Speicher für Seiteninfo konnte nicht zugewiesen werden: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Speicher für Seiten-Array konnte nicht zugewiesen werden: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1 Etikettendrucker" + +msgid "EPL2 Label Printer" +msgstr "EPL2 Etikettendrucker" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Ungültige %%BoundingBox: Kommentar gesehen!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Ungültiges %%IncludeFeature: Kommentar!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Ungültige %%Page: Kommentar in Datei!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Ungültige %%PageBoundingBox: Kommentar in Datei!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Ungültige SCSI-Gerätedatei „%s“!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Ungültige Zeichensatzdatei „%s“\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Ungültiger Zeichensatztyp „%s“\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Ungültiger Spaltenwert „%d“!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Ungültiger cpi-Wert „%f“!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Ungültige Schriftbeschreibungszeile: „%s“\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Ungültiger lpi-Wert „%f“!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Ungültiges Seitenformat!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Ungültige Textrichtung „%s“\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Ungültige Textweite „%s“\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Zieldrucker existiert nicht!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Doppelte %%BoundingBox: Kommentar gesehen!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Doppelte %%Pages: Kommentar gesehen!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Leere Druckdatei!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Fehler „%d“ beim Senden der PAPSendData-Anfrage: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: String mit Anführungszeichen erwartet in Zeile %d von %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Schwerwiegender USB-Fehler!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Ungültiger HP-GL/2-Befehl aufgetreten; Datei konnte nicht gedruckt " +"werden!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: Fehlender %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: Fehlendes %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Wert fehlt in Zeile %d der Bannerdatei!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: msgid-Zeile benötigt vor allen Übersetzungsstrings in Zeile %d von %" +"s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Keine %%BoundingBox: Kommentar im Header!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Keine %%Pages: Kommentar im Header!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Keine Geräte-URI gefunden in „argv[0]“ oder in DEVICE_URI " +"Umgebungsvariable!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Keine Schriften in Zeichensatzdatei „%s“\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Keine Seiten gefunden!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Kein Papier mehr!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: DRUCKER: Umgebungsvariable nicht definiert!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Druckdatei wurde nicht akzeptiert (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Drucker reagiert nicht\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Drucker reagiert nicht!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Drucker sendete unerwartet EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Entfernter Host hat die Steuerungsdatei nicht akzeptiert (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Entfernter Host hat Datendatei nicht akzeptiert (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Beim Senden der Daten an den Drucker ist ein Fehler wegen " +"Zeitüberschreitung aufgetreten.\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "" +"ERROR: Datei „%d“ konnte nicht zu Druckauftrag hinzugefügt werden: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Druckauftrag „%d“ konnte nicht abgebrochen werden: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: PDF-Datei konnte nicht kopiert werden" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Socket konnte nicht erstellt werden" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: Temporäre komprimierte Druckdatei konnte nicht erstellt werden: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Temporäre Datei konnte nicht erstellt werden" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: pictwpstops konnte nicht ausgeführt werden: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: gs-Programm konnte nicht ausgeführt werden" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: pdftops-Programm konnte nicht ausgeführt werden" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Fork für pictwpstops konnte nicht ausgeführt werden: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: PAP-Anfrage konnte nicht empfangen werden" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: PAP-Antwort konnte nicht empfangen werden" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: PPD-Datei für Drucker „%s“ konnte nicht abgefragt werden – %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: AppleTalk-Standardzone konnte nicht abgefragt werden" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "" +"ERROR: Attribute für Druckauftrag „%d“ konnten nicht abgefragt werden (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Druckerstatus konnte nicht abgefragt werden (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Drucker „%s“ konnte nicht gefunden werden!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Abfrage der PAP-Antwort nicht möglich" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Suche nach AppleTalk-Druckern nicht möglich" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Erstellen der AppleTalk-Adresse nicht möglich" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: „%s“ konnte nicht geöffnet werden – %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: „%s“ konnte nicht geöffnet werden: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Bannerdatei „%s“ konnte nicht geöffnet werden – %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Gerätedatei „%s“ konnte nicht geöffnet werden – %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Datei „%s“ konnte nicht geöffnet werden – %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Datei „%s“ konnte nicht geöffnet werden: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Bilddatei konnte nicht zum Drucken geöffnet werden!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Druckdatei „%s“ konnte nicht geöffnet werden: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Druckdatei „%s“ konnte nicht geöffnet werden – %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Druckdatei „%s“ konnte nicht geöffnet werden: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: Temporäre komprimierte Druckdatei konnte nicht geöffnet werden: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: %d Textspalten konnten nicht gedruckt werden!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: %dx%d Textseite konnte nicht gedruckt werden!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Druckdaten konnten nicht gelesen werden" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Druckdaten konnten nicht gelesen werden!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Anschluss konnte nicht reserviert werden" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "" +"ERROR: Nach dem Versatz „%ld“ in der Datei konnte nicht gesucht werden – %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "" +"ERROR: Nach dem Versatz „%lld“ in der Datei konnte nicht gesucht werden – %" +"s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: LPD-Befehl konnte nicht gesendet werden" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: PAP-Rückkopplungsanfrage konnte nicht gesendet werden" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "" +"ERROR: Erste PAP-Anfrage zum Senden von Daten konnte nicht gesendet werden" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Druckdaten konnten nicht gesendet werden (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Druckdaten konnten nicht gesendet werden!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Druckdatei konnte nicht an den Drucker gesendet werden" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "" +"ERROR: Nachfolgende Nullen konnten nicht an den Drucker gesendet werden" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Warten auf pictwpstops nicht möglich: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: %d Byte konnten nicht auf „%s“ geschrieben werden: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: %d Byte konnten nicht auf den Drucker geschrieben werden!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Steuerungsdatei konnte nicht geschrieben werden" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Druckdaten konnten nicht geschrieben werden" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Druckdaten konnten nicht geschrieben werden: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Rasterdaten konnten nicht auf den Treiber geschrieben werden!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Temporäre Datei konnte nicht geschrieben werden" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" +"ERROR: Unkomprimierte Dokumentdaten konnten nicht geschrieben werden: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Unerwarteter Text in Zeile %d von %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Unbekannter Verschlüsselungsoptionswert „%s“!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Unbekannte Dateianordnung „%s“\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Unbekanntes Formatzeichen „%c“\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Unbekanntes Message-Catalog-Format für „%s“!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Unbekannte Option „%s“ mit Wert „%s“!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Unbekannter Druckmodus „%s“\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Unbekannter Versionsoptionswert „%s“!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "" +"ERROR: Nicht unterstützter Helligkeitswert „%s“; „brightness=100“ " +"verwenden!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Nicht unterstützter Gammawert „%s“; „gamma=1000“ verwenden!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" +"ERROR: Nicht unterstützter Number-Up-Wert „%d“; „number-up=1“ verwenden!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Nicht unterstützter Number-Up-Layout-Wert „%s“; „number-up-" +"layout=lrtb“ verwenden!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Nicht unterstützter Seitenrandwert „%s“; „page-border=none“ " +"verwenden!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: doc_printf-Overflow (%d Byte) festgestellt; abbrechen!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops-Filter ausgestiegen bei Signal „%d“!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops-Filter ausgestiegen mit Status „%d“!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: wiederherstellbar: Verbindung zum Drucker nicht möglich, erneuter " +"Versuch in 30 Sekunden …\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: Auswahl() fehlgeschlagen" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: „stat“ für Druckdatei nicht möglich" + +msgid "Edit Configuration File" +msgstr "Konfigurationsdatei bearbeiten" + +msgid "Empty PPD file!" +msgstr "Leere PPD-Datei!" + +msgid "Ending Banner" +msgstr "Banner beenden" + +msgid "Enter old password:" +msgstr "Altes Kennwort eingeben:" + +msgid "Enter password again:" +msgstr "Kennwort erneut eingeben:" + +msgid "Enter password:" +msgstr "Kennwort eingeben:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Geben Sie Ihren Benutzernamen und das Kennwort oder den root-Benutzernamen " +"und -Kennwort ein, um auf diese Seite zuzgreifen. Falls Sie die Kerberos-" +"Authentifizierung verwenden, stellen Sie sicher, dass Sie ein gültiges " +"Kerberos-Ticket haben." + +msgid "Envelope Feed" +msgstr "Umschlagzuführung" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Fehlerbehandlung" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Fehler: Hostname benötigt nach '-h'-Option!\n" + +msgid "Every 10 Labels" +msgstr "Alle 10 Etiketten" + +msgid "Every 2 Labels" +msgstr "Alle 2 Etiketten" + +msgid "Every 3 Labels" +msgstr "Alle 3 Etiketten" + +msgid "Every 4 Labels" +msgstr "Alle 4 Etiketten" + +msgid "Every 5 Labels" +msgstr "Alle 5 Etiketten" + +msgid "Every 6 Labels" +msgstr "Alle 6 Etiketten" + +msgid "Every 7 Labels" +msgstr "Alle 7 Etiketten" + +msgid "Every 8 Labels" +msgstr "Alle 8 Etiketten" + +msgid "Every 9 Labels" +msgstr "Alle 9 Etiketten" + +msgid "Every Label" +msgstr "Bei jedem Etikett" + +msgid "Expectation Failed" +msgstr "Erwartete Daten nicht erhalten" + +msgid "Export Printers to Samba" +msgstr "Drucker zu Samba exportieren" + +msgid "FAIL\n" +msgstr "FEHLER\n" + +msgid "File Folder" +msgstr "Dateiordner" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Dateiordner – 9/16 x 3 7/16 Zoll" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Dateigeräte-URIs wurden deaktiviert! Infos zum Aktivieren finden Sie im " +"FileDevice-Verzeichnis unter „%s/cupsd.conf“." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Verboten" + +msgid "Fuser temperature high!" +msgstr "Die Temperatur des Fixierers ist zu hoch!" + +msgid "Fuser temperature low!" +msgstr "Die Temperatur des Fixierers ist zu niedrig!" + +msgid "General" +msgstr "Allgemein" + +msgid "Generic" +msgstr "Allgemein" + +msgid "German FanFold" +msgstr "Deutsch Endlospapier" + +msgid "German FanFold Legal" +msgstr "Deutsch Endlospapier (Brief)" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU hat unbestimmte Länge" + +msgid "Glossy Paper" +msgstr "Glanzpapier" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Drucker-URI-Attribute vorhanden, aber keine Druckauftrags-ID!" + +msgid "Grayscale" +msgstr "Graustufen" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Hängeordner" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Hängeordner – 9/16 x 2 Zoll" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk wurde in den Systemeinstellungen deaktiviert.\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk wurde in den Systemeinstellungen deaktiviert.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Druckauftrag abbrechen …\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Mit Drucker verbunden …\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Mit Drucker verbinden …\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Steuerungsdatei erfolgreich übertragen\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Datendatei erfolgreich übertragen\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Seite %d formatieren …\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Bilddatei laden …\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Drucker suchen …\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Verbindung herstellen\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Druckdatei gesendet, warten auf Abschließen des Druckers …\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Drucker ist ausgelastet, erneuter Versuch in 10 Sekunden …\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Drucker ist ausgelastet, erneuter Versuch in 30 Sekunden …\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Drucker ist ausgelastet, erneuter Versuch in 5 Sekunden …\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: Drucker unterstützt IPP/%d.%d nicht, erneuter Versuch mit IPP/1.0 …\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Drucker ausgelastet, erneuter Versuch in 5 Sekunden …\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Drucker ist derzeit offline.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Drucker ist derzeit offline.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Drucker ist jetzt online.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Drucker ist offline.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Drucker nicht verbunden, erneuter Versuch in 30 Sekunden …\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Seite %d drucken, %d %% abgeschlossen …\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Seite %d drucken …\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Bereit zum Drucken\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Steuerungsdatei senden (%lu Byte)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Steuerungsdatei senden (%u Byte)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Daten senden\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Datendatei senden (%ld Byte)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Datendatei senden (%lld Byte)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Druckdaten senden …\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Druckdatei gesendet, %ld Byte …\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Druckdatei gesendet, %lld Byte …\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: LPR-Druckauftrag aufzeichnen, %.0f %% abgeschlossen …\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Verbindung zum Drucker nicht möglich; an den nächsten Drucker der " +"Klasse senden …\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Standard-AppleTalk-Zone „%s“ verwenden\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Warten, bis der Druckauftrag agbeschlossen ist …\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Warten, bis der Drucker verfügbar ist …\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 Umschlag" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (Übergröße)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 Umschlag" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 Umschlag" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Ungültiges Steuerungszeichen" + +msgid "Illegal main keyword string" +msgstr "Ungültiger Main-Keyword-String" + +msgid "Illegal option keyword string" +msgstr "Ungültiger Option-Keyword-String" + +msgid "Illegal translation string" +msgstr "Ungültiger Übersetzungsstring" + +msgid "Illegal whitespace character" +msgstr "Ungültiges Leerzeichen" + +msgid "Ink/toner almost empty." +msgstr "Tinte/Toner fast leer." + +msgid "Ink/toner empty!" +msgstr "Tinte/Toner leer!" + +msgid "Ink/toner waste bin almost full." +msgstr "Tinten/Toner-Abfallbehälter fast voll." + +msgid "Ink/toner waste bin full!" +msgstr "Tinten/Toner-Abfallbehälter voll!" + +msgid "Installable Options" +msgstr "Installationsoptionen" + +msgid "Installed" +msgstr "Installiert" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar Etikettendrucker" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Die Verriegelung ist offen." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Interner Fehler" + +msgid "Internet Postage 2-Part" +msgstr "Internet Postage 2-teilig" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet Postage 2-teilig – 2 1/4 x 7 1/2 Zoll" + +msgid "Internet Postage 3-Part" +msgstr "Internet Postage 3-teilig" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet Postage 3-teilig – 2 1/4 x 7 Zoll" + +msgid "Internet Printing Protocol" +msgstr "Internet-Druckerprotokoll" + +msgid "Invite Envelope" +msgstr "Einladung Umschlag" + +msgid "Italian Envelope" +msgstr "Italienisch Umschlag" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "" +"Druckauftrag Nr. %d kann nicht neu gestartet werden – keine Dateien " +"vorhanden!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Druckauftrag Nr. %d existiert nicht!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Druckauftrag Nr. %d wurde bereits abgebrochen – Abbruch nicht möglich." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Druckauftrag Nr. %d wurde bereits abgebrochen – Abbruch nicht möglich." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "" +"Druckauftrag Nr. %d wurde bereits abgeschlossen – Abbruch nicht möglich." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Druckauftrag Nr. %d ist abgeschlossen und kann nicht geändert werden!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Druckauftrag Nr. %d ist nicht abgeschlossen!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Druckauftrag Nr. %d benötigt keine Authentifizierung!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Druckauftrag Nr. %d wird nicht gehalten!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Druckauftrag Nr. %s existiert nicht!" + +#, c-format +msgid "Job %d not found!" +msgstr "Druckauftrag %d wurde nicht gefunden!" + +msgid "Job Completed" +msgstr "Druckauftrag abgeschlossen" + +msgid "Job Created" +msgstr "Druckauftrag erzeugt" + +msgid "Job ID: " +msgstr "Druckauftrags-ID: " + +msgid "Job Options Changed" +msgstr "Druckauftragsoptionen wurden geändert" + +msgid "Job Stopped" +msgstr "Druckauftrag gestoppt" + +msgid "Job UUID: " +msgstr "Druckauftrags-UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "Druckauftrag ist abgeschlossen und kann nicht geändert werden." + +msgid "Job operation failed:" +msgstr "Druckvorgang fehlgeschlagen:" + +msgid "Job state cannot be changed." +msgstr "Druckauftragsstatus kann nicht geändert werden." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Druckauftrags-Subskription kann nicht erneuert werden." + +msgid "Jobs" +msgstr "Druckaufträge" + +msgid "Kaku2 Envelope" +msgstr "Kaku2 Umschlag" + +msgid "Kaku3 Envelope" +msgstr "Kaku3 Umschlag" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR-Host oder -Drucker" + +msgid "Label Printer" +msgstr "Etikettendrucker" + +msgid "Label Top" +msgstr "Etikett (oben)" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Sprache „%s“ nicht unterstützt!" + +msgid "Large Address" +msgstr "Adresse (groß)" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Adresse (groß) – 1 4/10 x 3 1/2 Zoll" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Serie PCL 4/5" + +msgid "Light" +msgstr "Hell" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Zeile ist länger als maximal zulässig (255 Zeichen)" + +msgid "List Available Printers" +msgstr "Verfügbare Drucker anzeigen" + +msgid "Location: " +msgstr "Standort: " + +msgid "Long-Edge (Portrait)" +msgstr "Lange Kante (Hochformat)" + +msgid "Make and Model: " +msgstr "Hersteller und Modell: " + +msgid "Manual Feed" +msgstr "Manuelle Papierzufuhr" + +msgid "Media Dimensions: " +msgstr "Medienmaße: " + +msgid "Media Limits: " +msgstr "Mediendruckgrenzen: " + +msgid "Media Name: " +msgstr "Medienname: " + +msgid "Media Size" +msgstr "Mediengröße" + +msgid "Media Source" +msgstr "Medienquelle" + +msgid "Media Tracking" +msgstr "Medienführung" + +msgid "Media Type" +msgstr "Medienart" + +msgid "Media jam!" +msgstr "Papierstau im Medienfach!" + +msgid "Media tray almost empty." +msgstr "Das Medienfach ist fast leer." + +msgid "Media tray empty!" +msgstr "Das Medienfach ist leer!" + +msgid "Media tray missing!" +msgstr "Das Medienfach fehlt!" + +msgid "Media tray needs to be filled." +msgstr "Das Medienfach muss aufgefüllt werden." + +msgid "Medium" +msgstr "Medium" + +msgid "Memory allocation error" +msgstr "Fehler bei der Speicherzuteilung" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "PPD-Adobe-4.x Header fehlt" + +msgid "Missing asterisk in column 1" +msgstr "Sternchen in Spalte 1 fehlt" + +msgid "Missing document-number attribute!" +msgstr "Attribut „document-number“ fehlt!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Doppeltes Anführungszeichen in Zeile %d fehlt!" + +msgid "Missing form variable!" +msgstr "Formvariable fehlt!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Attribut „notify-subscription-ids“ fehlt!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Attribut „requesting-user-name“ fehlt!" + +msgid "Missing required attributes!" +msgstr "Benötigte Attribute fehlen!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Wert in Zeile %d fehlt!" + +msgid "Missing value string" +msgstr "Wertestring fehlt" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modell: Name = %s\n" +" Standardsprache = %s\n" +" Hersteller und Modell = %s\n" +" Geräte-ID = %s\n" + +msgid "Modify Class" +msgstr "Klasse verändern" + +msgid "Modify Printer" +msgstr "Drucker verändern" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "US Monarch Umschlag" + +msgid "Move All Jobs" +msgstr "Alle Druckaufträge bewegen" + +msgid "Move Job" +msgstr "Druckauftrag bewegen" + +msgid "Moved Permanently" +msgstr "Dauerhaft bewegt" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Druckdatei akzeptiert – Druckauftrags-ID %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Druckdatei akzeptiert – Druckauftrags-ID unbekannt.\n" + +msgid "NULL PPD file pointer" +msgstr "NULL PPD File Pointer" + +msgid "Name OID uses indefinite length" +msgstr "Name-OID hat unbestimmte Länge" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Niemals" + +msgid "New Stylus Color Series" +msgstr "New Stylus Color Serie" + +msgid "New Stylus Photo Series" +msgstr "New Stylus Photo Serie" + +msgid "No" +msgstr "Nein" + +msgid "No Content" +msgstr "Kein Inhalt" + +msgid "No PPD name!" +msgstr "Kein PPD-Name!" + +msgid "No VarBind SEQUENCE" +msgstr "Keine VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Es sind keine Windows-Druckertreiber installiert!" + +msgid "No active connection" +msgstr "Keine aktive Verbindung" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Keine aktiven Druckaufträge auf %s!" + +msgid "No attributes in request!" +msgstr "Keine Attribute abgerufen!" + +msgid "No authentication information provided!" +msgstr "Keine Authentifizierungs-Informationen übergeben!" + +msgid "No community name" +msgstr "Kein Community-Name" + +msgid "No default printer" +msgstr "Kein Standarddrucker" + +msgid "No destinations added." +msgstr "Keine Ziele hinzugefügt." + +msgid "No error-index" +msgstr "Kein Fehlerindex" + +msgid "No error-status" +msgstr "Kein Fehlerstatus" + +msgid "No file!?!" +msgstr "Keine Datei!?!" + +msgid "No modification time!" +msgstr "Kein Änderungsdatum!" + +msgid "No name OID" +msgstr "Kein Name-OID" + +msgid "No printer name!" +msgstr "Kein Druckername!" + +msgid "No printer-uri found for class!" +msgstr "Keine Drucker-URI gefunden für Klasse!" + +msgid "No printer-uri found!" +msgstr "Keine Drucker-URI gefunden!" + +msgid "No printer-uri in request!" +msgstr "Keine Drucker-URI abgerufen!" + +msgid "No request-id" +msgstr "Keine Anfrage-ID" + +msgid "No subscription attributes in request!" +msgstr "Keine Subskriptionsattribute abgerufen!" + +msgid "No subscriptions found." +msgstr "Keine Subskriptionen gefunden." + +msgid "No variable-bindings SEQUENCE" +msgstr "Keine „variable-bindings SEQUENCE“" + +msgid "No version number" +msgstr "Keine Versionsnummer" + +msgid "Non-continuous (Mark sensing)" +msgstr "Nicht fortlaufend (Mark-Sensing)" + +msgid "Non-continuous (Web sensing)" +msgstr "Nicht fortlaufend (Web-Sensing)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "Nicht gefunden" + +msgid "Not Implemented" +msgstr "Nicht implementiert" + +msgid "Not Installed" +msgstr "Nicht installiert" + +msgid "Not Modified" +msgstr "Nicht verändert" + +msgid "Not Supported" +msgstr "Nicht unterstützt" + +msgid "Not allowed to print." +msgstr "Drucken nicht erlaubt." + +msgid "Note" +msgstr "Hinweis" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "Die Bildtrommel (OPC) muss bald ausgetauscht werden." + +msgid "OPC at end-of-life!" +msgstr "Die Bildtrommel (OPC) muss ausgetauscht werden!" + +msgid "Off (1-Sided)" +msgstr "Aus (Einseitig)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Online-Hilfe" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "%s öffnen fehlgeschlagen: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup ohne CloseGroup zuerst" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI ohne CloseUI/JCLCloseUI zuerst" + +msgid "Operation Policy" +msgstr "Nutzungsrichtlinien" + +msgid "Options Installed" +msgstr "Installierte Optionen" + +msgid "Options: " +msgstr "Optionen: " + +msgid "Out of toner!" +msgstr "Der Toner ist leer!" + +msgid "Output Mode" +msgstr "Ausgabemodus" + +msgid "Output bin almost full." +msgstr "Das Ausgabefach ist fast voll." + +msgid "Output bin full!" +msgstr "Das Ausgabefach ist voll!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Ausgabe für Drucker „%s“ wird an „%s“ gesendet\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "" +"Ausgabe für Drucker „%s“ wird an den entfernten Drucker „%s“ auf „%s“ " +"gesendet\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Ausgabe für Drucker „%s/%s“ wird an „%s“ gesendet\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"Ausgabe für Drucker „%s/%s“ wird an den entfernten Drucker „%s“ auf „%s“ " +"gesendet\n" + +msgid "Output tray missing!" +msgstr "Das Ausgabefach fehlt!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "PCL Laserdrucker" + +msgid "PRC1 Envelope" +msgstr "PRC1 Umschlag" + +msgid "PRC10 Envelope" +msgstr "PRC10 Umschlag" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2 Umschlag" + +msgid "PRC3 Envelope" +msgstr "PRC3 Umschlag" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (Übergröße)" + +msgid "PRC4 Envelope" +msgstr "PRC4 Umschlag" + +msgid "PRC5 Envelope" +msgstr "PRC5 Umschlag" + +msgid "PRC6 Envelope" +msgstr "PRC6 Umschlag" + +msgid "PRC7 Envelope" +msgstr "PRC7 Umschlag" + +msgid "PRC8 Envelope" +msgstr "PRC8 Umschlag" + +msgid "PRC9 Envelope" +msgstr "PRC9 Umschlag" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Paket enthält kein Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Paket beginnt nicht mit SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Das Kennwort für „%s“ auf „%s“? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "" +"Das Kennwort für „%s“ wird benötigt für den Zugriff auf „%s“ über SAMBA: " + +msgid "Pause Class" +msgstr "Klasse anhalten" + +msgid "Pause Printer" +msgstr "Drucker anhalten" + +msgid "Peel-Off" +msgstr "Aufkleber" + +msgid "Personal Envelope" +msgstr "Persönlicher Umschlag" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Foto-Etiketten" + +msgid "Plain Paper" +msgstr "Standardpapier" + +msgid "Policies" +msgstr "Richtlinien " + +msgid "Port Monitor" +msgstr "Port-Monitor" + +msgid "PostScript Printer" +msgstr "PostScript-Drucker" + +msgid "Postcard" +msgstr "Postkarte" + +msgid "Print Density" +msgstr "Druckdichte" + +msgid "Print Job:" +msgstr "Druckauftrag:" + +msgid "Print Mode" +msgstr "Druckmodus" + +msgid "Print Rate" +msgstr "Druckrate" + +msgid "Print Self-Test Page" +msgstr "Selbsttestseite drucken" + +msgid "Print Speed" +msgstr "Druckgeschwindigkeit" + +msgid "Print Test Page" +msgstr "Testseite drucken" + +msgid "Print and Cut" +msgstr "Drucken und abschneiden" + +msgid "Print and Tear" +msgstr "Drucken und abziehen" + +msgid "Printed For: " +msgstr "Gedruckt für: " + +msgid "Printed From: " +msgstr "Gedruckt von: " + +msgid "Printed On: " +msgstr "Gedruckt am: " + +msgid "Printer Added" +msgstr "Drucker hinzugefügt" + +msgid "Printer Default" +msgstr "Standardeinstellung für Drucker" + +msgid "Printer Deleted" +msgstr "Drucker gelöscht" + +msgid "Printer Modified" +msgstr "Drucker geändert" + +msgid "Printer Name: " +msgstr "Druckername: " + +msgid "Printer Paused" +msgstr "Drucker angehalten" + +msgid "Printer Settings" +msgstr "Druckereinstellungen" + +msgid "Printer offline." +msgstr "Der Drucker ist offline." + +msgid "Printer:" +msgstr "Drucker:" + +msgid "Printers" +msgstr "Drucker" + +msgid "Purge Jobs" +msgstr "Druckaufträge aufräumen" + +msgid "Quarto" +msgstr "US Quarto" + +msgid "Quota limit reached." +msgstr "Kontingentgrenze erreicht." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Rang Eigentümer Druckauftrag Datei(en) " +"Gesamtgröße\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Rang Eigentümer Druckauftrag Dateien " +"Gesamtgröße\n" + +msgid "Reject Jobs" +msgstr "Druckaufträge ablehnen" + +msgid "Reprint After Error" +msgstr "Druckvorgang nach dem Fehler fortsetzen" + +msgid "Request Entity Too Large" +msgstr "Gesamte Anfrage zu groß" + +msgid "Resolution" +msgstr "Auflösung" + +msgid "Resume Class" +msgstr "Klasse fortsetzen" + +msgid "Resume Printer" +msgstr "Drucken fortsetzen" + +msgid "Return Address" +msgstr "Absender-Adresse" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Absender-Adresse – 3/4 x 2 Zoll" + +msgid "Rewind" +msgstr "Zurückdrehen" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Befehl ausführen: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI-Drucker" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE hat unbestimmte Länge" + +msgid "See Other" +msgstr "Siehe auch" + +#, c-format +msgid "Serial Port #%d" +msgstr "Serieller Anschluss Nr. %d" + +msgid "Server Restarted" +msgstr "Server neu gestartet" + +msgid "Server Security Auditing" +msgstr "Server Security Auditing" + +msgid "Server Started" +msgstr "Server gestartet" + +msgid "Server Stopped" +msgstr "Server gestoppt" + +msgid "Service Unavailable" +msgstr "Dienst nicht verfügbar" + +msgid "Set Allowed Users" +msgstr "Zugelassene Benutzer festlegen" + +msgid "Set As Server Default" +msgstr "Als Standardeinstellungen für Server festlegen" + +msgid "Set Class Options" +msgstr "Klassenoptionen festlegen" + +msgid "Set Printer Options" +msgstr "Druckeroptionen festlegen" + +msgid "Set Publishing" +msgstr "Veröffentlichung festlegen" + +msgid "Shipping Address" +msgstr "Lieferadresse" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Lieferadresse – 2 5/16 x 4 Zoll" + +msgid "Short-Edge (Landscape)" +msgstr "Kurze Kante (Querformat)" + +msgid "Special Paper" +msgstr "Spezialpapier" + +msgid "Standard" +msgstr "Standard" + +msgid "Starting Banner" +msgstr "Startbanner" + +msgid "Statement" +msgstr "US Statement" + +msgid "Stylus Color Series" +msgstr "Stylus Color Serie" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo Serie" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Protokoll wechseln" + +msgid "Tabloid" +msgstr "US Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "US Tabloid (Übergröße)" + +msgid "Tear" +msgstr "Abziehen" + +msgid "Tear-Off" +msgstr "Abziehen" + +msgid "Tear-Off Adjust Position" +msgstr "Abziehposition" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Die PPD-Datei „%s“ konnte nicht gefunden werden." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Die PPD-Datei „%s“ konnte nicht geöffnet werden: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Der Klassenname darf maximal 127 druckbare Zeichen haben und darf keine " +"Leerzeichen, Schrägstriche (/) oder Rautezeichen (#) enthalten." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Das Attribut „notify-lease-duration“ kann nicht mit Druckauftrags-" +"Subskriptionen verwendet werden." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Der Wert für „notify-user-data“ ist zu groß (%d > 63 Oktetts)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Der Druckername darf maximal 127 druckbare Zeichen haben und darf keine " +"Leerzeichen, Schrägstriche (/) oder Rautezeichen (#) enthalten." + +msgid "The printer or class is not shared!" +msgstr "Der Drucker oder die Klasse sind nicht freigegeben!" + +msgid "The printer or class was not found." +msgstr "Der Drucker oder die Klasse wurden nicht gefunden!" + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Die Drucker-URI „%s“ enthält ungültige Zeichen." + +msgid "The printer-uri attribute is required!" +msgstr "Das Drucker-URI-Attribut wird benötigt!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"Die Drucker-URI muss in der folgenden Form vorliegen: ipp://HOSTNAME/classes/" +"CLASSNAME" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"Die Drucker-URI muss in der folgenden Form vorliegen: ipp://HOSTNAME/" +"printers/PRINTERNAME" + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Der Subkriptionsname darf keine Leerzeichen, Schrägstriche (/), Fragezeichen " +"(?) oder Rautezeichen (#) enthalten." + +msgid "There are too many subscriptions." +msgstr "Es liegen zu viele Subskriptionen vor." + +msgid "Thermal Transfer Media" +msgstr "Thermal Transfer Media" + +msgid "Title: " +msgstr "Titel: " + +msgid "Toner low." +msgstr "Wenig Toner." + +msgid "Too many active jobs." +msgstr "Zu viele aktive Druckaufträge." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Zu viele job-sheets-Werte (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Zu viele printer-state-reasons-Werte (%d > %d)!" + +msgid "Transparency" +msgstr "Transparenz" + +msgid "Tray" +msgstr "Fach" + +msgid "Tray 1" +msgstr "Fach 1" + +msgid "Tray 2" +msgstr "Fach 2" + +msgid "Tray 3" +msgstr "Fach 3" + +msgid "Tray 4" +msgstr "Fach 4" + +msgid "URI Too Long" +msgstr "URI zu lang" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Endlospapier" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Lang" + +msgid "US Legal (Oversize)" +msgstr "US Lang (Übergröße)" + +msgid "US Letter" +msgstr "US Brief" + +msgid "US Letter (Oversize)" +msgstr "US Brief (Übergröße)" + +msgid "US Letter (Small)" +msgstr "US Brief (klein)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB Serieller Anschluss Nr. %d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Kein Zugriff auf Datei „cupsd.conf“:" + +msgid "Unable to add RSS subscription:" +msgstr "RSS-Abo konnte nicht hinzugefügt werden:" + +msgid "Unable to add class:" +msgstr "Klasse konnte nicht hinzugefügt werden:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Druckauftrag für das Ziel „%s“ konnte nicht hinzugefügt werden!" + +msgid "Unable to add printer:" +msgstr "Drucker konnte nicht hinzugefügt werden:" + +msgid "Unable to allocate memory for file types!" +msgstr "Der Speicher für die Dateitypen konnte nicht zugeordnet werden." + +msgid "Unable to cancel RSS subscription:" +msgstr "RSS-Abo konnte nicht widerrufen werden:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Attribut „printer-is-shared“ konnte nicht geändert werden:" + +msgid "Unable to change printer:" +msgstr "Drucker konnte nicht geändert werden:" + +msgid "Unable to change server settings:" +msgstr "Servereinstellungen konnten nicht geändert werden:" + +msgid "Unable to connect to host." +msgstr "Verbindungsaufbau zum Host fehlgeschlagen." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "64-Bit CUPS-Druckertreiberdateien konnten nicht kopiert werden (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"64-Bit Windows-Druckertreiberdateien konnten nicht kopiert werden (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "CUPS-Druckertreiberdateien konnten nicht kopiert werden (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "PPD-Datei konnte nicht kopiert werden – %s!" + +msgid "Unable to copy PPD file!" +msgstr "PPD-Datei konnte nicht kopiert werden!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Windows 2000 Druckertreiberdateien konnten nicht kopiert werden (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Windows 9x Druckertreiberdateien konnten nicht kopiert werden (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Schnittstellenskript konnte nicht kopiert werden – %s!" + +msgid "Unable to create printer-uri!" +msgstr "Drucker-URI konnte nicht erstellt werden!" + +msgid "Unable to create temporary file:" +msgstr "Temporäre Datei konnte nicht erstellt werden:" + +msgid "Unable to delete class:" +msgstr "Klasse konnte nicht gelöscht werden:" + +msgid "Unable to delete printer:" +msgstr "Drucker konnte nicht gelöscht werden:" + +msgid "Unable to do maintenance command:" +msgstr "Wartungsbefehl konnte nicht ausgeführt werden:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "„cupsd.conf“-Dateien größer als 1 MB können nicht bearbeitet werden!" + +msgid "Unable to find destination for job!" +msgstr "Ziel für den Druckauftrag konnte nicht gefunden werden!" + +msgid "Unable to find printer!\n" +msgstr "Drucker konnte nicht gefunden werden!\n" + +msgid "Unable to get class list:" +msgstr "Klassenliste konnte nicht abgerufen werden:" + +msgid "Unable to get class status:" +msgstr "Klassenstatus konnte nicht abgerufen werden:" + +msgid "Unable to get list of printer drivers:" +msgstr "Liste der Druckertreiber konnte nicht abgerufen werden:" + +msgid "Unable to get printer attributes:" +msgstr "Druckerattribute konnten nicht abgerufen werden:" + +msgid "Unable to get printer list:" +msgstr "Druckerliste konnte nicht abgerufen werden:" + +msgid "Unable to get printer status:" +msgstr "Druckerstatus konnte nicht abgerufen werden:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Windows 2000 Druckertreiberdateien konnten nicht installiert werden (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"Windows 9x Druckertreiberdateien konnten nicht installiert werden (%d)!" + +msgid "Unable to modify class:" +msgstr "Klasse konnte nicht verändert werden:" + +msgid "Unable to modify printer:" +msgstr "Drucker konnte nicht verändert werden:" + +msgid "Unable to move job" +msgstr "Druckauftrag konnte nicht bewegt werden" + +msgid "Unable to move jobs" +msgstr "Druckaufträge konnten nicht bewegt werden" + +msgid "Unable to open PPD file" +msgstr "Die PPD-Datei konnte nicht geöffnet werden" + +msgid "Unable to open PPD file:" +msgstr "Die PPD-Datei konnte nicht geöffnet werden:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Die Datei „cupsd.conf“ konnte nicht geöffnet werden:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Das Dokument „%d“ in Druckauftrag „%d“ konnte nicht geöffnet werden!" + +msgid "Unable to print test page:" +msgstr "Testseite konnte nicht gedruckt werden:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "„%s“ konnte nicht ausgeführt werden: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Befehl konnte nicht an den Druckertreiber gesendet werden!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Windows-Druckertreiber konnte nicht festgelegt werden (%d)!" + +msgid "Unable to set options:" +msgstr "Optionen konnten nicht festgelegt werden:" + +msgid "Unable to set server default:" +msgstr "Standardeinstellungen für Server konnten nicht festgelegt werden:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Die Datei „cupsd.conf“ konnte nicht hochgeladen werden:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Alte USB-Klasse-Treiber konnten nicht verwendet werden!\n" + +msgid "Unauthorized" +msgstr "Nicht berechtigt" + +msgid "Units" +msgstr "Einheiten" + +msgid "Unknown" +msgstr "Unbekannt" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Unbekannte printer-error-policy „%s“." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Unbekannte printer-op-policy „%s“." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Zeichensatz „%s“ nicht unterstützt!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Komprimierung „%s“ nicht unterstützt!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Komprimierungsattribut „%s“ nicht unterstützt!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Format „%s“ nicht unterstützt!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Format „%s“ nicht unterstützt!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Format „%s/%s“ nicht unterstützt!" + +msgid "Unsupported value type" +msgstr "Wertetyp nicht unterstützt" + +msgid "Upgrade Required" +msgstr "Aktualisierung erforderlich" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Usage: %s job user title copies options [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Usage: %s job-id user title copies options [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Usage: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Usage: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Usage: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Usage: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Wert hat unbestimmte Länge" + +msgid "VarBind uses indefinite length" +msgstr "VarBind hat unbestimmte Länge" + +msgid "Version uses indefinite length" +msgstr "Version hat unbestimmte Länge" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Nur die ersten %d gefundenen Drucker werden hinzugefügt" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Boolscher Wert erwartet für waiteof-Option „%s“\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Lesen der Side-Channel-Anfrage fehlgeschlagen!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" +"WARNING: Option „%s“ kann nicht mithilfe von „IncludeFeature“ eingeschlossen " +"werden!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Drucker reagiert nicht\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Drucker sendete unerwartet EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Entfernter Host hat nicht mit dem Befehlstatusbyte geantwortet nach " +"%d Sekunden!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Entfernter Host hat nicht mit dem Steuerungsstatusbyte geantwortet " +"nach %d Sekunden!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Entfernter Host hat nicht mit dem Datenstatusbyte geantwortet nach %" +"d Sekunden!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: Zeitüberschreitung bei SCSI-Befehl (%d); erneut versuchen …\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Dieses Dokument entspricht nicht den Dokumentstruktur-Konventionen " +"von Adobe und wird u. U. nicht korrekt gedruckt!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: „%s:%s“ konnte nicht geöffnet werden: %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: PAP-Statusanfrage konnte nicht gesendet werden" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Unerwartetes PAP-Paket des Typs „%d“\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Unbekanntes PAP-Paket des Typs „%d“\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Unbekannte Auswahl „%s“ für Option „%s“!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Unbekannte Option „%s“!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Baud-Rate „%s“ wird nicht unterstützt!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: Zahlwert erwartet für Statusoption „%s“\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: wiederherstellbar: Netzwerkhost „%s“ ist ausgelastet; erneuter " +"Versuch in %d Sekunden …\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Achtung: Es sind keine Windows 2000 Druckertreiber installiert!" + +msgid "Yes" +msgstr "Ja" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Auf diese Seite greifen Sie zu über die URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "You4 Umschlag" + +msgid "ZPL Label Printer" +msgstr "ZPL Etikettendrucker" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "abgebrochen" + +msgid "canceled" +msgstr "abgebrochen" + +msgid "completed" +msgstr "abgeschlossen" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "" +"konvertieren: Mit der -f Option eine Datei zum Konvertieren festlegen.\n" + +msgid "cups-deviced failed to execute." +msgstr "„cups-deviced“ konnte nicht ausgeführt werden." + +msgid "cups-driverd failed to execute." +msgstr "„cups-driverd“ konnte nicht ausgeführt werden." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: keine PPD-Datei für Drucker „%s“ – %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Verbindungsaufbau zum Server fehlgeschlagen: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: unbekannte Option „%s“!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: unbekannte Option „-%c“!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: „config filename“ erwartet nach '-c'-Option!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Aktueller Ordner konnte nicht gefunden werden!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: unbekanntes Argument „%s“ – abbrechen!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: unbekannte Option „%c“ – abbrechen!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: „launchd(8) support“ nicht übersetzt, in „normal mode“ ausführen.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: ungültige Dokumentnummer %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: ungültige Druckauftrags-ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Nur ein Dateiname kann angegeben werden!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Druckauftragsdatei konnte nicht geladen werden – %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: '-q'-Option ist nicht kompatibel mit der '-v'-Option.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: '-v'-Option ist nicht kompatibel mit der '-q'-Option.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "Gerät für %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "Gerät für %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "Fehlerindex hat unbestimmte Länge" + +msgid "error-status uses indefinite length" +msgstr "Fehlerstatus hat unbestimmte Länge" + +msgid "held" +msgstr "gehalten" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tget help on commands\n" + +msgid "idle" +msgstr "inaktiv" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-URI-Attribut fehlt!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Klassenname kann nur druckbare Zeichen enthalten!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: PPD erwartet nach '-P'-Option!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: „allow/deny:userlist“ erwartet nach '-u'-Option!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Klasse erwartet nach '-r'-Option!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Klassenname erwartet nach '-c'-Option!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Beschreibung erwartet nach '-D'-Option!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Geräte-URI erwartet nach '-v'-Option!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Dateityp(en) erwartet nach '-I'-Option!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Hostname erwartet nach '-h'-Option!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Schnittstelle erwartet nach '-i'-Option!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Standort erwartet nach '-L'-Option!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Modell erwartet nach '-m'-Option!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: name=value erwartet nach '-o'-Option!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Drucker erwartet nach '-p'-Option!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Druckername erwartet nach '-d'-Option!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Drucker oder Klasse erwartet nach '-x'-Option!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Keine zugehörigen Namen gefunden!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Drucker „%s“ gehört bereits zur Klasse „%s“.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Drucker „%s“ gehört bereits zur Klasse „%s“.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Druckername kann nur druckbare Zeichen enthalten!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Drucker konnte nicht zu der Klasse hinzugefügt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Verbindungsaufbau zum Server fehlgeschlagen: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: PPD-Datei „%s“ konnte nicht geöffnet werden – %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Datei „%s“ konnte nicht geöffnet werden: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Drucker konnte nicht aus der Klasse entfernt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Die PPD-Datei konnte nicht festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Die Geräte-URI konnte nicht festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Das Schnittstellenskript oder die PPD-Datei konnten nicht " +"festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Das Schnittstellenskript konnte nicht festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Die Druckerbeschreibung konnte nicht festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Der Druckerstandort konnte nicht festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Die Druckeroptionen konnten nicht festgelegt werden:\n" +" Legen Sie zuerst einen Druckernamen fest!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: unbekannte allow/deny-Option „%s“!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: unbekanntes Argument „%s“!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: unbekannte Option '%c'!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Achtung – Inhaltstypliste ignoriert!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: 1284 Geräte-ID String erwartet nach „--device-id“!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Sprache erwartet nach „--language“!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Hersteller und Modell erwartet nach „--make-and-model“!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Produktstring erwartet nach „--product“!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Schemaliste erwartet nach „--exclude-schemes“!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Schemaliste erwartet nach „--include-schemes“!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Zeitüberschreitung erwartet nach „--timeout“!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: unbekanntes Argument „%s“!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: unbekannte Option '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: unbekannte Option '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Verbindungsaufbau zum Server fehlgeschlagen: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: unbekanntes Argument „%s“!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: unbekannte Option '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Keine Drucker!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Drucker oder Instanz konnten nicht hinzugefügt werden: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: PPD-Datei für „%s“ konnte nicht geladen werden: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: PPD-Datei für „%s“ konnte nicht geöffnet werden!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Drucker oder Klasse unbekannt!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Nur „root“ kann Kennwörter hinzufügen und löschen!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Kennwortdatei wird gerade verwendet!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Kennwortdatei ist nicht aktualisiert!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Kennwörter stimmen nicht überein!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Kennwort abgelehnt.\n" +"Das Kennwort muss mindestens 6 Zeichen lang sein, darf nicht Ihren " +"Benutzernamen enthalten und muss mindestens einen Buchstaben und eine Zahl " +"enthalten.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Kennwörter stimmen nicht überein!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Kennwortstring konnte nicht kopiert werden: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Kennwortdatei konnte nicht geöffnet werden: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: In die Kennwortdatei konnte nicht geschrieben werden: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: Sichern der alten Kennwortdatei fehlgeschlagen: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: Kennwortdatei konnte nicht umbenannt werden: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: Benutzer „%s“ und Gruppe „%s“ existieren nicht.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: Fehler – %s Umgebungsvariablennamen nicht vorhanden für Ziel „%s“!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "gehört zu Klasse „%s“:\n" + +msgid "no entries\n" +msgstr "keine Einträge\n" + +msgid "no system default destination\n" +msgstr "kein System-Standardzielort\n" + +msgid "notify-events not specified!" +msgstr "„notify-events“ nicht festgelegt!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI „%s“ wird bereits verwendet!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI „%s“ verwendet unbekanntes Schema!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id „%d“ ist ungültig!" + +msgid "pending" +msgstr "ausstehend" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Ordner „%s“ hinzufügen …\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: UI-Text von „%s“ hinzufügen/aktualisieren …\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Ungültiger Boolscher Wert (%s) in Zeile %d von %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ungültiger aufzulösender Name „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Ungültiges Status-Keyword „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Ungültige Variablenersetzung ($%c) in Zeile %d von %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Auswahl in Zeile %d von %s gefunden ohne Option!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Duplikat #po für Locale „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Filterdefinition erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Programmname erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Boolschen Wert erwartet in Zeile %d von %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Zeichensatz nach Schrift erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Auswahlcode erwartet in Zeile %d von %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Auswahlname/-text erwartet in Zeile %d von %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Farbreihenfolge für ColorModel erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Farbraum für ColorModel erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Komprimierung für ColorModel erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Constraints String für UIConstraints erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Treibertyp-Keyword nach DriverType erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Duplextyp nach Duplex erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Codierung nach Schrift erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Dateiname nach #po %s erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Gruppenname/-text erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: „include filename“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: „integer“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Locale nach #po erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Name nach „%s“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Name nach FileName erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Name nach Font erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Name nach Manufacturer erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Name nach MediaSize erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Name nach ModelName erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Name nach PCFileName erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Name/Text nach „%s“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Name/Text nach Installable erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Name/Text nach Resolution erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Kombination aus Name/Text für ColorModel erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Optionsname/-text erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: „option section“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: „option type“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: „override field“ nach Resolution erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: „real number“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: „resolution/mediatype“ nach ColorProfile erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: „resolution/mediatype“ nach SimpleColorProfile erwartet in Zeile %d " +"von %s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: „selector“ nach „%s“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Status nach Font erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: „string“ nach Copyright erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: „string“ nach Version erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Zwei Optionsnamen erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: „value“ nach „%s“ erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Version nach Font erwartet in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: ungültiger #include/#po Dateiname „%s“!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Ungültiges „cost“ für Filter in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Ungültiger leerer MIME-Typ für Filter in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Ungültiger leerer Programmname für Filter in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ungültiger Optionsabschnitt „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ungültiger Optionstyp „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Treiberinfodatei „%s“ laden …\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Meldungen für Locale „%s“ laden …\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Meldungen von „%s“ laden …\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif fehlt am Ende von „%s“!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if fehlt in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Kein Message-Catalog verfügbar für Locale „%s“!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" +"ppdc: Option „%s“ neu definiert durch anderen Typ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Option „constraint must *name“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Zu viele verschachtelte #if in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: PPD-Datei „%s“ konnte nicht erstellt werden – %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Ausgabeordner „%s“ konnte nicht erstellt werden: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Ausgabekanäle konnten nicht erstellt werden: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: cupstestppd konnte nicht ausgeführt werden: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: #po-Datei „%s“ wurde nicht gefunden in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: include-Datei „%s“ wurde nicht gefunden in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Lokalisierung für „%s“ wurde nicht gefunden – %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Lokalisierungsdatei „%s“ konnte nicht geladen werden – %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Nicht defnierte Variable (%s) in Zeile %d von %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Unbekannter Treibertyp „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Unbekannter Duplextyp „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Unbekannte Mediengröße „%s“ in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Unbekannter Token „%s“ gefunden in Zeile %d von %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Unbekannte nachfolgende Zeichen in Real Number „%s“ in Zeile %d von %" +"s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Unvollständiger String beginnend mit %c in Zeile %d von %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: %s schreiben …\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: PPD-Dateien schreiben in Ordner „%s“ …\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Ungültige LanguageVersion „%s“ in %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: PPD-Datei „%s“ ignorieren …\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Backup von „%s“ auf %s fehlgeschlagen – %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "Drucker „%s“ deaktiviert seit %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "Drucker „%s“ ist inaktiv; aktiviert seit %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "Drucker „%s“ druckt gerade %s–%d; aktiviert seit %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "Drucker „%s/%s“ deaktiviert seit %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "Drucker „%s/%s“ ist inaktiv; aktiviert seit %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "Drucker „%s/%s“ druckt gerade %s–%d; aktiviert seit %s\n" + +msgid "processing" +msgstr "Bearbeiten" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "Anfrage-ID ist %s–%d (%d Datei(en))\n" + +msgid "request-id uses indefinite length" +msgstr "Anfrage-ID hat unbestimmte Länge" + +msgid "scheduler is not running\n" +msgstr "Scheduler ist nicht aktiv\n" + +msgid "scheduler is running\n" +msgstr "Scheduler ist aktiv\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "Status von %s fehlgeschlagen: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "Status\t\tStatus für Daemon und Warteliste anzeigen\n" + +msgid "stopped" +msgstr "Gestoppt" + +#, c-format +msgid "system default destination: %s\n" +msgstr "System-Standardzielort: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "System-Standardzielort: %s/%s\n" + +msgid "unknown" +msgstr "Unbekannt" + +msgid "untitled" +msgstr "Ohne Titel" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings hat unbestimmte Länge" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN APDialogExtension-Datei „%s“ fehlt\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN APPrinterIconPath-Datei „%s“ fehlt\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: „%s“ konnte nicht geöffnet werden – %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: „%s“ konnte nicht geöffnet werden – %s in Zeile %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI Graustufen" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Geräte-URI fehlt in der Befehlszeile und keine DEVICE_URI " +#~ "Umgebungsvariable vorhanden!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Temporäre Datei konnte nicht erstellt werden – %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Temporäre Datei konnte nicht erstellt werden: %s.\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Temporäre Datei konnte nicht geöffnet werden" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops-Filter fehlgeschlagen bei Signal „%d“!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops-Filter ausgestiegen mit Status „%d“!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Unbekannter Druckerfehler (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Temporäre Datei konnte nicht erstellt werden: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Temporäre Datei konnte nicht erstellt werden – %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Temporäre Datei konnte nicht erstellt werden: %s\n" diff --git a/locale/cups_es.po b/locale/cups_es.po new file mode 100644 index 0000000000..e71bc6aef0 --- /dev/null +++ b/locale/cups_es.po @@ -0,0 +1,5689 @@ +# +# "$Id$" +# +# Spanish message catalog for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 2005-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-07-02 20:00+0100\n" +"Last-Translator: Juan Pablo González Riopedre \n" +"Language-Team: Spanish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(todos)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(ninguno)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d entradas\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tTras fallo: continuar\n" + +msgid "\tAlerts:" +msgstr "\tAlertas:" + +msgid "\tBanner required\n" +msgstr "\tSe necesita un rótulo\n" + +msgid "\tCharset sets:\n" +msgstr "\tAjustes del juego de caracteres:\n" + +msgid "\tConnection: direct\n" +msgstr "\tConexión: directa\n" + +msgid "\tConnection: remote\n" +msgstr "\tConexión: remota\n" + +msgid "\tDefault page size:\n" +msgstr "\tTamaño de página predeterminado:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tPaso predeterminado:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tAjustes del puerto predeterminados:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDescripción: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormulario montado:\n" +"\tTipos de contenido: cualquiera\n" +"\tTipos de impresora: desconocido\n" + +msgid "\tForms allowed:\n" +msgstr "\tFormularios permitidos:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterfaz: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterfaz: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterfaz: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tUbicación: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tEn fallo: no alertar\n" + +msgid "\tUsers allowed:\n" +msgstr "\tUsuarios permitidos:\n" + +msgid "\tUsers denied:\n" +msgstr "\tUsuarios denegados:\n" + +msgid "\tdaemon present\n" +msgstr "\tdemonio presente\n" + +msgid "\tno entries\n" +msgstr "\tno hay entradas\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tla impresora está conectada a '%s' velocidad -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tla impresión está desactivada\n" + +msgid "\tprinting is enabled\n" +msgstr "\tla impresión está activada\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\ten cola para %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tla cola está desactivada\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tla cola está activada\n" + +msgid "\treason unknown\n" +msgstr "\trazón desconocida\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" RESULTADOS DETALLADOS DE LA PRUEBA DE CONFORMIDAD\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Página 15, sección 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Página 15, sección 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Página 19, sección 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Página 20, sección 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Página 27, sección 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Página 42, sección 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Páginas 16-17, sección 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Páginas 42-45, sección 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Páginas 45-46, sección 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Páginas 48-49, sección 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Páginas 52-54, sección 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f bytes\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASA %s predeterminado\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASA DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASA DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASA FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASA FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASA LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASA LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASA Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASA ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASA NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASA PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASA PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASA PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASA PageSize\n" + +msgid " PASS Product\n" +msgstr " PASA Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASA ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" ADVERTENCIA \"%s %s\" está en conflicto con \"%s %s\"\n" +" (restricción=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " ADVERTENCIA %s tiene opciones que no corresponden.\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" ADVERTENCIA %s comparte un prefijo común con %s\n" +" REF: Página 15, sección 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr "" +" ADVERTENCIA Las preferencias predeterminadas están en conflicto.\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" ADVERTENCIA La clave de opción Duplex %s puede que no funcione " +"como se espera y debería llamarse Duplex.\n" +" REF: Página 122, sección 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" ADVERTENCIA El archivo contiene una mezcla de líneas acabadas en " +"CR, LF y CR LF.\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" ADVERTENCIA Se necesita LanguageEncoding por especificación de " +"PPD 4.3.\n" +" REF: Páginas 56-57, sección 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " ADVERTENCIA La línea %d solo contiene espacios en blanco.\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" ADVERTENCIA Se necesita Manufacturer por especificación de PPD " +"4.3.\n" +" REF: Páginas 58-59, sección 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" ADVERTENCIA Los archivos PPD que no sean de Windows deben tener " +"líneas que acaben sólo en LF, no en CR LF.\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" ADVERTENCIA Versión de PPD %.1f anticuada.\n" +" REF: Página 42, sección 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" ADVERTENCIA PCFileName es mas largo que 8.3 violando la " +"especificación PPD.\n" +" REF: Páginas 61-62, sección 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" ADVERTENCIA Los protocolos contienen PJL pero no se especifican " +"los atributos JCL.\n" +" REF: Páginas 78-79, sección 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" ADVERTENCIA Los protocolos contienen a ambos, PJL y BCP; se " +"esperaba TBCP.\n" +" REF: Páginas 78-79, sección 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" ADVERTENCIA Se necesita ShortNickName por especificación de PPD " +"4.3.\n" +" REF: Páginas 64-65, sección 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s no existe.\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr " %s archivo %s \"%s\" tiene las mayúsculas equivocadas.\n" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Preferencia %s incorrecta %s.\n" +" REF: Página 122, sección 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" +" %s Cadena de traducción UTF-8 \"%s\" incorrecta para opción %s.\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Cadena de traducción UTF-8 \"%s\" incorrecta para opción %s, " +"preferencia %s.\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Valor cupsFilter \"%s\" incorrecto.\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s cupsICCProfile %s incorrecto.\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Valor cupsPreFilter \"%s\" incorrecto.\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s cupsUIConstraints %s: \"%s\" incorrecto.\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Idioma incorrecto \"%s\".\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr " %s %s mal escrito - debería ser %s.\n" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr " %s No puede proporcionar APScanAppPath y APScanAppBundleID.\n" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints %s vacío.\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Falta cadena de traducción \"%s\" para opción %s.\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Falta cadena de traducción \"%s\" para opción %s, preferencia %s.\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr " %s Falta el archivo APDialogExtension \"%s\"\n" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr " %s Falta el archivo APPrinterIconPath \"%s\"\n" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr " %s Falta el archivo APPrinterLowInkTool \"%s\"\n" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr " %s Falta el archivo APPrinterUtilityPath \"%s\"\n" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr " %s Falta el archivo APScanAppPath \"%s\"\n" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" %s Falta la opción NECESARIA PageRegion.\n" +" REF: Página 100, sección 5.14.\n" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" %s Falta la opción NECESARIA PageSize.\n" +" REF: Página 99, sección 5.14.\n" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Falta la preferencia *%s %s en UIConstraint \"*%s %s *%s %s\".\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" +" %s Falta la preferencia *%s %s en cupsUIConstraints %s: \"%s\".\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Falta archivo cupsFilter \"%s\"\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Falta el archivo cupsICCProfile \"%s\".\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Falta archivo cupsPreFilter \"%s\"\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Falta cupsUIResolver %s.\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Falta la opción %s en UIConstraints \"*%s %s *%s %s\".\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Falta la opción %s en cupsUIConstraints %s: \"%s\".\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s No hay traducción base \"%s\" incluida en el archivo.\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" +" %s Tamaño de nombre \"%s\" no estándar.\n" +" REF: Página 187, sección B.2.\n" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s NECESARIA %s no define la opción None.\n" +" REF: Página 122, sección 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr " %s Tamaño \"%s\" definido para %s pero no para %s.\n" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr " %s El tamaño \"%s\" tiene inesperadas dimensiones (%gx%g).\n" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s valor hash de cupsICCProfile %s colisiona con %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s genera un bucle.\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" +" %s cupsUIResolver %s no lista al menos dos opciones diferentes.\n" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FALLO** %s nombres de opción %s y %s se diferencian sólo en la " +"capitalización.\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FALLO** %s debe ser 1284DeviceID.\n" +" REF: Página 72, sección 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FALLO** Default%s %s INCORRECTO\n" +" REF: Página 40, sección 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FALLO** DefaultImageableArea %s INCORRECTO\n" +" REF: Página 102, sección 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FALLO** DefaultPaperDimension %s INCORRECTO.\n" +" REF: Página 103, sección 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FALLO** Atributo JobPatchFile en archivo, INCORRECTO\n" +" REF: Página 24, sección 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FALLO** Fabricante INCORRECTO (debería ser \"HP\")\n" +" REF: Página 211, tabla D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FALLO** Fabricante INCORRECTO (debería ser \"Oki\")\n" +" REF: Página 211, tabla D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FALLO** ModelName - \"%c\" INCORRECTO no permitido en la cadena.\n" +" REF: Páginas 59-60, sección 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FALLO** PSVersion INCORRECTO - no es \"(string) int\".\n" +" REF: Páginas 62-64, sección 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FALLO** Product INCORRECTO - no es \"(string)\".\n" +" REF: Página 62, sección 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FALLO** ShortNickName INCORRECTO - mayor de 31 caracteres.\n" +" REF: Páginas 64-65, sección 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FALLO** Preferencia %s incorrecta %s.\n" +" REF: Página 84, sección 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FALLO** FileVersion \"%s\" incorrecto\n" +" REF: Página 56, sección 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FALLO** FormatVersion \"%s\" incorrecto\n" +" REF: Página 56, sección 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **FALLO** LanguageEncoding %s incorrecto: debería ser ISOLatin1.\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FALLO** LanguageVersion %s incorrecto: debería ser Inglés.\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FALLO** El código de opción predeterminado no puede ser " +"interpretado: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FALLO** Cadena de traducción predeterminada para opción %s " +"preferencia %s contiene caracteres de 8-bits.\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FALLO** Cadena de traducción predeterminada para opción %s contiene " +"caracteres de 8-bits.\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FALLO** Nombres de grupo %s y %s se diferencian sólo en la " +"capitalización.\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FALLO** Múltiples apariciones de %s nombre de opción %s.\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FALLO** Nombres de opción %s y %s se diferencian sólo en la " +"capitalización.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FALLO** SE NECESITA Default%s\n" +" REF: Página 40, sección 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FALLO** SE NECESITA DefaultImageableArea\n" +" REF: Página 102, sección 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FALLO** SE NECESITA DefaultPaperDimension\n" +" REF: Página 103, sección 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA FileVersion\n" +" REF: Página 56, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA FormatVersion\n" +" REF: Página 56, sección 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FALLO** SE NECESITA ImageableArea para PageSize %s\n" +" REF: Página 41, sección 5.\n" +" REF: Página 102, sección 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA LanguageEncoding\n" +" REF: Páginas 56-57, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA LanguageVersion\n" +" REF: Páginas 57-58, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA Manufacturer\n" +" REF: Páginas 58-59, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA ModelName\n" +" REF: Páginas 59-60, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA NickName\n" +" REF: Página 60, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA PCFileName\n" +" REF: Páginas 61-62, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA PSVersion\n" +" REF: Páginas 62-64, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FALLO** SE NECESITA PageRegion\n" +" REF: Página 100, sección 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FALLO** SE NECESITA PageSize\n" +" REF: Página 41, sección 5.\n" +" REF: Página 99, sección 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FALLO** SE NECESITA PageSize\n" +" REF: Páginas 99-100, sección 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FALLO** SE NECESITA PaperDimension para PageSize %s\n" +" REF: Página 41, sección 5.\n" +" REF: Página 103, sección 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA Product\n" +" REF: Página 62, sección 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FALLO** SE NECESITA ShortNickName\n" +" REF: Página 64-65, sección 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERRORES ENCONTRADOS\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" %%%%BoundingBox: incorrecto en línea %d.\n" +" REF: Página 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" %%%%Page: incorrecto en línea %d.\n" +" REF: Página 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" %%%%Pages: incorrecto en línea %d.\n" +" REF: Página 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" La línea %d es más larga de 255 caracteres (%d).\n" +" REF: Página 25, Longitud de Línea\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" Falta %!PS-Adobe-3.0 en la primera línea.\n" +" REF: Página 17, 3.1 Conformidad de documentos\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Falta comentario %%EndComments.\n" +" REF: Página 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Falta comentario %%BoundingBox: o incorrecto.\n" +" REF: Página 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Falta comentario %%Page: o incorrecto.\n" +" REF: Página 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Falta comentario %%Pages: o incorrecto.\n" +" REF: Página 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " NO SE HAN ENCONTRADO ERRORES\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Se han visto %d líneas que exceden de 255 caracteres.\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Demasiados comentarios %%BeginDocument.\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Demasiados comentarios %%EndDocument.\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Advertencia: el archivo contiene datos binarios.\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Advertencia: no hay comentario %%EndComments en el archivo.\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Advertencia: versión DSC %.1f obsoleta en el archivo.\n" + +msgid " FAIL\n" +msgstr " FALLO\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FALLO\n" +" **FALLO** No se ha podido abrir el archivo PPD - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FALLO\n" +" **FALLO** No se ha podido abrir el archivo PPD - %s en la línea %d.\n" + +msgid " PASS\n" +msgstr " PASA\n" + +msgid "#10 Envelope" +msgstr "Sobre nº 10" + +msgid "#11 Envelope" +msgstr "Sobre nº 11" + +msgid "#12 Envelope" +msgstr "Sobre nº 12" + +msgid "#14 Envelope" +msgstr "Sobre nº 14" + +msgid "#9 Envelope" +msgstr "Sobre nº 9" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f milímetros" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f a %.0f x %.0f milímetros" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f pulgadas" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f a %.2f x %.2f pulgadas" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s aceptando peticiones desde %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s no puede ser cambiado." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s no está implementado en la versión de CUPS de lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s no está preparada\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s está preparada\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s está preparada e imprimiendo\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s no acepta peticiones desde %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "No se admite el uso de %s." + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s aceptando peticiones desde %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s no acepta peticiones desde %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [trabajo %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s ha fallado: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: No sé que hay que hacer.\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Error - %s nombres de variables de entorno no existen en destino \"%s" +"\".\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Error - ID de trabajo incorrecta.\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Error - no se pueden imprimir archivos y alterar trabajos al mismo " +"tiempo.\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Error - no se puede imprimir desde stdin si se proporcionan archivos o " +"una ID de trabajo.\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Error - se esperaba un juego de caracteres tras la opción '-S'.\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Error - se esperaba un tipo de contenido tras la opción '-T'.\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Error - se esperaba número de copias tras la opción '-n'.\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Error - se esperaba un número de copias tras la opción '-#'.\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Error - se esperaba un destino tras la opción '-P'.\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Error - se esperaba un destino tras la opción '-b'.\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Error - se esperaba un destino tras la opción '-d'.\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Error - se esperaba un formulario tras la opción '-f'.\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Error - se esperaba un nombre de retención tras la opción '-H'.\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Error - se esperaba un nombre de ordenador tras la opción '-H'.\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Error - se esperaba un nombre de ordenador tras la opción '-h'.\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Error - se esperaba una lista de modos tras la opción '-y'.\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Error - se esperaba un nombre tras la opción '%c'.\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Error - se esperaba una cadena de opciones tras la opción '-o'.\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Error - se esperaba una lista de páginas tras la opción '-P'.\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Error - se esperaba un valor de prioridad tras la opción '-%c'.\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Error - se esperaba un texto con una razón tras la opción '-r'.\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Error - se esperaba un título tras la opción '-t'.\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Error - se esperaba un nombre de usuario tras la opción '-U'.\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Error - se esperaba un nombre de usuario tras la opción '-u'.\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Error - se esperaba un valor tras la opción '%c'.\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Error - se necesita \"completed\", \"not completed\", o \"all\" tras la " +"opción '-W'.\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Error - destino predeterminado no disponible.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Error - la prioridad debe estar entre 1 y 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Error - el programa planificador de tareas no responde.\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Error - demasiados archivos - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Error - no se ha podido acceder a \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Error - no se ha podido poner en cola desde stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Error - destino \"%s\" desconocido.\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Error - destino \"%s/%s\" desconocido.\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Error - opción '%c' desconocida.\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Error: opción '%s' desconocida.\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s : Se esperaba una ID de trabajo tras la opción '-i'.\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filtro \"%s\" no disponible: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Nombre de destino no válido en la lista \"%s\".\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Cadena de filtro \"%s\" inválida\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "" +"%s: Se necesita un ID de trabajo ('-i id_trabajo') antes de '-H restart'.\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: No hay ningún filtro que convertir de %s/%s a %s/%s.\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: La operación ha fallado: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Lo siento, no está compilado con la opción de encriptación.\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: No se ha podido conectar al servidor\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: No se ha podido contactar con el servidor.\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: No se ha podido determinar el tipo MIME de \"%s\".\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: No se pudo abrir %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: No se pudo abrir archivo PPD: %s en línea %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "%s: No se ha podido abrir el archivo PPD: %s en la línea %d.\n" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: No se pudo leer base de datos MIME desde \"%s\" o \"%s\".\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Destino \"%s\" desconocido.\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Tipo MIME de destino %s/%s desconocido.\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Opción '%c' desconocida.\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Tipo MIME de origen %s/%s desconocido.\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Advertencia - no se admite el uso del modificador de formato '%c' - la " +"salida puede no ser correcta.\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Advertencia - opción de juego de caracteres no tenida en cuenta.\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Advertencia - opción de tipo de contenido no tenida en cuenta.\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Advertencia - opción de formulario no tenida en cuenta.\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Advertencia - opción de modo no tenida en cuenta.\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: error - %s nombres de variables de entorno no existen en destino \"%s" +"\".\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: error - se esperaba opción=valor tras la opción '-o'.\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: error - destino predeterminado no disponible.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 pulg./seg" + +msgid "1.25x0.25\"" +msgstr "1.25x0.25 pulg." + +msgid "1.25x2.25\"" +msgstr "1.25x2.25 pulg." + +msgid "1.5 inch/sec." +msgstr "1.5 pulg./seg" + +msgid "1.50x0.25\"" +msgstr "1.50x0.25 pulg." + +msgid "1.50x0.50\"" +msgstr "1.50x0.50 pulg." + +msgid "1.50x1.00\"" +msgstr "1.50x1.00 pulg." + +msgid "1.50x2.00\"" +msgstr "1.50x2.00 pulg." + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 pulg./seg" + +msgid "10 x 11\"" +msgstr "10 x 11 pulg." + +msgid "10 x 13\"" +msgstr "10 x 13 pulg." + +msgid "10 x 14\"" +msgstr "10 x 14 pulg." + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/seg" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 pulg./seg" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 pulg./seg" + +msgid "12 x 11\"" +msgstr "12 x 11 pulg." + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/seg" + +msgid "120x60dpi" +msgstr "120x60ppp" + +msgid "120x72dpi" +msgstr "120x72ppp" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136ppp" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/seg" + +msgid "15 x 11\"" +msgstr "15 x 11 pulg." + +msgid "150 mm/sec." +msgstr "150 mm/seg" + +msgid "150dpi" +msgstr "150ppp" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180ppp" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 pulg./seg" + +msgid "2-Sided Printing" +msgstr "Dúplex" + +msgid "2.00x0.37\"" +msgstr "2.00x0.37 pulg." + +msgid "2.00x0.50\"" +msgstr "2.00x0.50 pulg." + +msgid "2.00x1.00\"" +msgstr "2.00x1.00 pulg." + +msgid "2.00x1.25\"" +msgstr "2.00x1.25 pulg." + +msgid "2.00x2.00\"" +msgstr "2.00x2.00 pulg." + +msgid "2.00x3.00\"" +msgstr "2.00x3.00 pulg." + +msgid "2.00x4.00\"" +msgstr "2.00x4.00 pulg." + +msgid "2.00x5.50\"" +msgstr "2.00x5.50 pulg." + +msgid "2.25x0.50\"" +msgstr "2.25x0.50 pulg." + +msgid "2.25x1.25\"" +msgstr "2.25x1.25 pulg." + +msgid "2.25x4.00\"" +msgstr "2.25x4.00 pulg." + +msgid "2.25x5.50\"" +msgstr "2.25x5.50 pulg." + +msgid "2.38x5.50\"" +msgstr "2.38x5.50 pulg." + +msgid "2.5 inches/sec." +msgstr "2.5 pulg./seg" + +msgid "2.50x1.00\"" +msgstr "2.50x1.00 pulg." + +msgid "2.50x2.00\"" +msgstr "2.50x2.00 pulg." + +msgid "2.75x1.25\"" +msgstr "2.75x1.25 pulg." + +msgid "2.9 x 1\"" +msgstr "2.9 x 1 pulg." + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/seg" + +msgid "200 mm/sec." +msgstr "200 mm/seg" + +msgid "203dpi" +msgstr "203ppp" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-Pin Series" + +msgid "240x72dpi" +msgstr "240x72ppp" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/seg" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 pulg./seg" + +msgid "3.00x1.00\"" +msgstr "3.00x1.00 pulg." + +msgid "3.00x1.25\"" +msgstr "3.00x1.25 pulg." + +msgid "3.00x2.00\"" +msgstr "3.00x2.00 pulg." + +msgid "3.00x3.00\"" +msgstr "3.00x3.00 pulg." + +msgid "3.00x5.00\"" +msgstr "3.00x5.00 pulg." + +msgid "3.25x2.00\"" +msgstr "3.25x2.00 pulg." + +msgid "3.25x5.00\"" +msgstr "3.25x5.00 pulg." + +msgid "3.25x5.50\"" +msgstr "3.25x5.50 pulg." + +msgid "3.25x5.83\"" +msgstr "3.25x5.83 pulg." + +msgid "3.25x7.83\"" +msgstr "3.25x7.83 pulg." + +msgid "3.5\" Disk" +msgstr "Disco de 3.5 pulg." + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Disco de 3.5 pulg. - 2 1/8 x 2 3/4 pulg." + +msgid "3.50x1.00\"" +msgstr "3.50x1.00 pulg." + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/seg" + +msgid "300 mm/sec." +msgstr "300 mm/seg" + +msgid "300dpi" +msgstr "300ppp" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360ppp" + +msgid "360x180dpi" +msgstr "360x180ppp" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 pulg./seg" + +msgid "4.00x1.00\"" +msgstr "4.00x1.00 pulg." + +msgid "4.00x13.00\"" +msgstr "4.00x13.00 pulg." + +msgid "4.00x2.00\"" +msgstr "4.00x2.00 pulg." + +msgid "4.00x2.50\"" +msgstr "4.00x2.50 pulg." + +msgid "4.00x3.00\"" +msgstr "4.00x3.00 pulg." + +msgid "4.00x4.00\"" +msgstr "4.00x4.00 pulg." + +msgid "4.00x5.00\"" +msgstr "4.00x5.00 pulg." + +msgid "4.00x6.00\"" +msgstr "4.00x6.00 pulg." + +msgid "4.00x6.50\"" +msgstr "4.00x6.50 pulg." + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/seg" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 pulg./seg" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 pulg./seg" + +msgid "6.00x1.00\"" +msgstr "6.00x1.00 pulg." + +msgid "6.00x2.00\"" +msgstr "6.00x2.00 pulg." + +msgid "6.00x3.00\"" +msgstr "6.00x3.00 pulg." + +msgid "6.00x4.00\"" +msgstr "6.00x4.00 pulg." + +msgid "6.00x5.00\"" +msgstr "6.00x5.00 pulg." + +msgid "6.00x6.00\"" +msgstr "6.00x6.00 pulg." + +msgid "6.00x6.50\"" +msgstr "6.00x6.50 pulg." + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/seg" + +msgid "600dpi" +msgstr "600ppp" + +msgid "60dpi" +msgstr "60ppp" + +msgid "60x720dpi" +msgstr "60x720ppp" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 pulg./seg" + +msgid "7 x 9\"" +msgstr "7 x 9 pulg." + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720ppp" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 pulg./seg" + +msgid "8 x 10\"" +msgstr "8 x 10 pulg." + +msgid "8.00x1.00\"" +msgstr "8.00x1.00 pulg." + +msgid "8.00x2.00\"" +msgstr "8.00x2.00 pulg." + +msgid "8.00x3.00\"" +msgstr "8.00x3.00 pulg." + +msgid "8.00x4.00\"" +msgstr "8.00x4.00 pulg." + +msgid "8.00x5.00\"" +msgstr "8.00x5.00 pulg." + +msgid "8.00x6.00\"" +msgstr "8.00x6.00 pulg." + +msgid "8.00x6.50\"" +msgstr "8.00x6.50 pulg." + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/seg" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 pulg./seg" + +msgid "9 x 11\"" +msgstr "9 x 11 pulg." + +msgid "9 x 12\"" +msgstr "9 x 12 pulg." + +msgid "9-Pin Series" +msgstr "9-Pin Series" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Comando de ayuda inválido desconocido\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"Se requiere una contraseña Samba para exportar los controladores de " +"impresora." + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Se requiere un nombre de usuario Samba para exportar los controladores de " +"impresora." + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Ya existe una clase llamada \"%s\"." + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Ya existe una impresora llamada \"%s\"." + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (extragrande)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (extragrande)" + +msgid "A4 (Small)" +msgstr "A4 (pequeño)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (extragrande)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Aceptar trabajos" + +msgid "Accepted" +msgstr "Aceptado" + +msgid "Add Class" +msgstr "Añadir clase" + +msgid "Add Printer" +msgstr "Añadir impresora" + +msgid "Add RSS Subscription" +msgstr "Añadir subscripción RSS" + +msgid "Address" +msgstr "Dirección" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Dirección - 1 1/8 x 3 1/2 pulg." + +msgid "Administration" +msgstr "Administración" + +msgid "Always" +msgstr "Siempre" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Aplicador" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "" +"Se ha intentado cambiar el valor printer-state de %s a un valor incorrecto %" +"d." + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Los grupos de atributos están desordenados (%x < %x)." + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Puntero destino NULLincorrecto" + +msgid "Bad OpenGroup" +msgstr "OpenGroup incorrecto" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI incorrecto" + +msgid "Bad OrderDependency" +msgstr "OrderDependency incorrecto" + +msgid "Bad Request" +msgstr "Petición incorrecta" + +msgid "Bad SNMP version number" +msgstr "Número de versión SNMP incorrecto" + +msgid "Bad UIConstraints" +msgstr "UIConstraints incorrecto" + +#, c-format +msgid "Bad copies value %d." +msgstr "Valor de copias %d incorrecto." + +msgid "Bad custom parameter" +msgstr "Parámetro a medida incorrecto" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "URI de dispositivoi \"%s\" incorrecto.\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "device-uri \"%s\" incorrecto." + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Esquema device-uri \"%s\" incorrecto." + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "document-format \"%s\" incorrecto." + +msgid "Bad filename buffer!" +msgstr "Nombre de archivo del búfer incorrecto." + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Atributo de fuente: %s incorrecto\n" + +msgid "Bad job-priority value!" +msgstr "Valor job-priority incorrecto." + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Valor de job-sheets \"%s\" incorrecto." + +msgid "Bad job-sheets value type!" +msgstr "Tipo de valor de job-sheets incorrecto." + +msgid "Bad job-state value!" +msgstr "Valor job-state incorrecto." + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Atributo job-uri \"%s\" incorrecto." + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "notify-pull-method \"%s\" incorrecto." + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "URI notify-recipient-uri \"%s\" incorrecto." + +#, c-format +msgid "Bad number-up value %d." +msgstr "Valor number-up (páginas por hoja) %d incorrecto." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Opción + preferencia incorrectas en línea %d." + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Valores de page-ranges %d-%d incorrectos." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "port-monitor \"%s\" incorrecto." + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Valor printer-state %d incorrecto." + +#, c-format +msgid "Bad request ID %d!" +msgstr "ID %d de petición incorrecta." + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Petición incorrecta de número de versión %d.%d." + +msgid "Bad subscription ID!" +msgstr "ID de subscripción incorrecto." + +msgid "Banners" +msgstr "Rótulos" + +msgid "Billing Information: " +msgstr "Información de facturación: " + +msgid "Bond Paper" +msgstr "Papel de cartas" + +msgid "C0 Envelope" +msgstr "Sobre C0" + +msgid "C1 Envelope" +msgstr "Sobre C1" + +msgid "C2 Envelope" +msgstr "Sobre C2" + +msgid "C3 Envelope" +msgstr "Sobre C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Sobre C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Sobre C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Sobre C6" + +msgid "C65 Envelope" +msgstr "Sobre C65" + +msgid "C7 Envelope" +msgstr "Sobre C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Impresora de etiquetas CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Cancelar subscripción RSS" + +msgid "Change Settings" +msgstr "Cambiar configuración" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "No se admite el uso del juego de caracteres \"%s\"." + +msgid "Chou3 Envelope" +msgstr "Sobre Chou3" + +msgid "Chou4 Envelope" +msgstr "Sobre Chou4" + +msgid "Classes" +msgstr "Clases" + +msgid "Clean Print Heads" +msgstr "Limpiar cabezales de impresión" + +msgid "Color" +msgstr "Color" + +msgid "Color Mode" +msgstr "Modo de color" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Los comandos se pueden abreviar. Los comandos son:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Nombre de comunidad usa una longitud indefinida" + +msgid "Continue" +msgstr "Continuar" + +msgid "Continuous" +msgstr "Continuo" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "No se puede analizar el tipo \"%s\"." + +msgid "Cover open." +msgstr "Cubierta abierta." + +msgid "Created" +msgstr "Creado" + +msgid "Created On: " +msgstr "Creado en: " + +msgid "Custom" +msgstr "A medida" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Cortar" + +msgid "Cutter" +msgstr "Cortadora" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "Sobre DL" + +msgid "Dark" +msgstr "Oscuro" + +msgid "Darkness" +msgstr "Oscuridad" + +msgid "Delete Class" +msgstr "Borrar clase" + +msgid "Delete Printer" +msgstr "Borrar impresora" + +msgid "Description: " +msgstr "Descripción: " + +msgid "DeskJet Series" +msgstr "DeskJet Series" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "El destino %s no acepta trabajos." + +msgid "Developer almost empty." +msgstr "Revelador casi vacío." + +msgid "Developer empty!" +msgstr "Revelador vacío." + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Dispositivo: uri = %s\n" +" clase = %s\n" +" info = %s\n" +" marca y modelo = %s\n" +" id dispositivo= %s\n" +" ubicación = %s\n" + +msgid "Direct Thermal Media" +msgstr "Soporte térmico directo" + +msgid "Disabled" +msgstr "Deshabilitado" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "No se encuentra el documento %d en el trabajo %d." + +msgid "Door open." +msgstr "Puerta abierta." + +msgid "Double Postcard" +msgstr "Postal doble" + +msgid "Driver Name: " +msgstr "Nombre del controlador: " + +msgid "Driver Version: " +msgstr "Versión del controlador: " + +msgid "Duplexer" +msgstr "Unidad de impresión dúplex" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "" +"EMERG: No se ha podido asignar memoria para la información de página: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "" +"EMERG: No se ha podido asignar memoria para la secuencia de páginas: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Impresora de etiquetas EPL1" + +msgid "EPL2 Label Printer" +msgstr "Impresora de etiquetas EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "ERROR: %s job-id usuario título copias opciones [archivo]\n" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Se ha detectado un comentario %%BoundingBox: incorrecto.\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Comentario %%IncludeFeature: incorrecto.\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Comentario %%Page: incorrecto en el archivo.\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Comentario %%PageBoundingBox: incorrecto en el archivo.\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: archivo de dispositivo SCSI \"%s\" incorrecto.\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Archivo de juego de caracteres incorrecto %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Tipo de juego de caracteres incorrecto %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Valor de columnas %d incorrecto.\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Valor de cpi %f incorrecto.\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Línea de descripción tipográfica incorrecta: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Valor de lpi %f incorrecto.\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Ajuste de página incorrecto.\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Dirección de texto incorrecta %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Anchura de texto incorrecta %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: La impresora destino no existe.\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Se ha detectado un comentario %%BoundingBox: duplicado.\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Se ha detectado un comentario %%Pages: duplicado.\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Archivo de impresión vacío.\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Error %d enviando petición PAPSendData: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: Se esperaba una cadena entrecomillada en la línea %d de %s.\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Error fatal de USB.\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Se ha detectado un comando HP-GL/2 no válido; no se puede imprimir el " +"archivo.\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: Falta %%EndProlog.\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: Falta %%EndSetup.\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Falta el valor en la línea %d del archivo de rótulo.\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Se necesita una línea msgid antes de cualquier cadena de traducción " +"en línea %d de %s.\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: No hay comentario %%BoundingBox: en la cabecera.\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: No hay comentario %%Pages: en la cabecera.\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: No se ha encontrado el URI del dispositivo en argv[0] o en la " +"variable de entorno DEVICE_URI.\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: No hay fuentes en el archivo de juego de caracteres %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: No se han encontrado páginas.\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: No hay papel.\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: Variable de entorno PRINTER no definida.\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: No se ha aceptado la impresión del archivo (%s).\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: La impresora no responde\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: La impresora no responde.\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: La impresora envió un inesperado EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: El ordenador remoto no ha aceptado el archivo de control (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: El ordenador remoto no ha aceptado el archivo de datos (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Hay un error de tiempo de espera mientras se enviaban datos a la " +"impresora\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: No se ha podido añadir el archivo %d al trabajo: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: No se ha podido cancelar el trabajo %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: No se ha podido copiar el archivo PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "ERROR: No se ha podido crear el canal (pipe)" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: No se ha podido crear socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: No se ha podido crear el archivo de impresión temporal comprimido: %" +"s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: No se ha podido crear el archivo temporal" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: No se ha podido ejecutar pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: No se ha podido ejecutar el programa gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: No se ha podido ejecutar el programa pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "ERROR: No se ha podido ejecutar el programa pstops" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: No se ha podido bifurcar (fork) pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: No se ha podido obtener una petición PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: No se ha podido obtener una respuesta PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: No se ha podido obtener el archivo PPD para la impresora \"%s\" - %" +"s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: No se ha podido conseguir la zona AppleTalk predeterminada" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: No se han podido obtener los atributos del trabajo %d (%s).\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: No se ha podido obtener el estado de la impresora (%s).\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: No se ha podido localizar la impresora '%s'.\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: No se ha podido buscar una respuesta PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: No se han podido mirar las impresoras AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: No se ha podido crear la dirección AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: No se ha podido abrir \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: No se ha podido abrir %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "ERROR: No se ha podido abrir el archivo PPD.\n" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: No se ha podido abrir el archivo de rótulo \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: No se ha podido abrir el archivo de dispositivo \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: No se ha podido abrir el archivo \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: No se ha podido abrir el archivo \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: No se ha podido abrir el archivo de imagen para imprimirlo.\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: No se ha podido abrir el archivo de impresión \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: No se ha podido abrir el archivo de impresión %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: No se ha podido abrir el archivo de impresión %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "ERROR: No se ha podido abrir el archivo de trama de datos - %s\n" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: No se ha podido abrir el archivo de impresión temporal comprimido: %" +"s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: No se ha podido imprimir %d columnas de texto.\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: No se ha podido imprimir %dx%d páginas de texto.\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: No se han podido leer los datos de impresión" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: No se han podido leer los datos de impresión.\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: No se ha podido reservar puerto" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: No se ha podido alcanzar la posición %ld en el archivo - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: No se ha podido alcanzar la posición %lld en el archivo - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: No se ha podido enviar comando LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: No se ha podido enviar una petición PAP" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "" +"ERROR: No se ha podido enviar la petición inicial de datos de envío PAP" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: No se han podido enviar los datos de impresión (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: No se han podido enviar los datos de impresión.\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: No se ha podido imprimir el archivo en la impresora" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: No se ha podido enviar carácter nulo del final a la impresora" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: No se puede esperar por pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: No se han podido escribir %d bytes a \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: No se han podido escribir %d bytes a la impresora.\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: No se ha podido escribir el archivo de control" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: No se han podido escribir los datos de impresión" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: No se han podido escribir los datos de impresión: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "" +"ERROR: No se ha podido escribir la trama de datos (raster) al controlador.\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: No se ha podido escribir al archivo temporal" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" +"ERROR: No se han podido escribir los datos de documento sin comprimir: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Texto inesperado en la línea %d del %s.\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Valor de opción de encriptación \"%s\" desconocida.\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Orden de archivos \"%s\" desconocido\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Carácter de formato \"%c\" desconocido\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Formato del catálogo de mensajes para \"%s\" desconocido.\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Opción \"%s\" con valor \"%s\" desconocida.\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Modo de impresión \"%s\" desconocido\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Valor de opción de versión \"%s\" desconocida.\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Valor de brillo %s no permitido; usando brillo=100.\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Valor gamma %s no permitido; usando gamma=1000.\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" +"ERROR: Valor de number-up (páginas por hoja) %d no permitido; usando number-" +"up=1.\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Valor de number-up-layout (disposición de páginas por hoja) %s no " +"permitido; usando number-up-layout=lrtb.\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Valor de page-border (borde de página) %s no permitido; usando page-" +"border=none (ninguno).\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "" +"ERROR: Se ha detectado un desbordamiento de doc_printf (%d bytes); " +"cancelando.\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops se ha cerrado con la señal %d.\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops se ha cerrado con el estado %d.\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: recuperable: No se ha podido establecer conexión con la impresora; " +"reintento en 30 segundos...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() ha fallado" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: no se ha podido ejecutar 'stat' sobre el archivo de impresión" + +msgid "Edit Configuration File" +msgstr "Editar archivo de configuración" + +msgid "Empty PPD file!" +msgstr "Archivo PPD vacío." + +msgid "Ending Banner" +msgstr "Rótulo final" + +msgid "Enter old password:" +msgstr "Introduzca la contraseña antigua:" + +msgid "Enter password again:" +msgstr "Introduzca nuevamente la contraseña:" + +msgid "Enter password:" +msgstr "Introduzca la contraseña:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Introduzca su nombre de usuario y contraseña o el nombre de usuario y " +"contraseña de root para poder acceder a esta página. Si está usando " +"autentificación Kerberos, asegúrese de que tiene un ticket Kerberos válido." + +msgid "Envelope Feed" +msgstr "Alimentador de sobre" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Directiva de error" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Error: se necesita un nombre de ordenador tras la opción '-h'.\n" + +msgid "Every 10 Labels" +msgstr "Cada 10 etiquetas" + +msgid "Every 2 Labels" +msgstr "Cada 2 etiquetas" + +msgid "Every 3 Labels" +msgstr "Cada 3 etiquetas" + +msgid "Every 4 Labels" +msgstr "Cada 4 etiquetas" + +msgid "Every 5 Labels" +msgstr "Cada 5 etiquetas" + +msgid "Every 6 Labels" +msgstr "Cada 6 etiquetas" + +msgid "Every 7 Labels" +msgstr "Cada 7 etiquetas" + +msgid "Every 8 Labels" +msgstr "Cada 8 etiquetas" + +msgid "Every 9 Labels" +msgstr "Cada 9 etiquetas" + +msgid "Every Label" +msgstr "Cada etiqueta" + +msgid "Expectation Failed" +msgstr "Lo que se esperaba, falló." + +msgid "Export Printers to Samba" +msgstr "Exportar impresoras a Samba" + +msgid "FAIL\n" +msgstr "FALLO\n" + +msgid "File Folder" +msgstr "Carpeta de archivos" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Carpeta de archivosr - 9/16 x 3 7/16 pulg." + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Los URIs del dispositivo de archivo han sido deshabilitados. Para " +"habilitarlos, vea la directiva FileDevice en \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Prohibido" + +msgid "Fuser temperature high!" +msgstr "Temperatura del fusor alta." + +msgid "Fuser temperature low!" +msgstr "Temperatura del fusor baja." + +msgid "General" +msgstr "General" + +msgid "Generic" +msgstr "Genérico" + +msgid "German FanFold" +msgstr "FanFold alemán" + +msgid "German FanFold Legal" +msgstr "FanFold Legal alemán" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU usa una longitud indefinida" + +msgid "Glossy Paper" +msgstr "Papel satinado" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Se ha obtenido el atributo printer-uri pero no el job-id." + +msgid "Grayscale" +msgstr "Escale de grises" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Carpeta colgante" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Carpeta colgante - 9/16 x 2 pulg." + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk desactivado en Preferencias del sistema\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk desactivado en Preferencias del sistema.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Cancelando trabajo de impresión...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Conectado a la impresora...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Conectando a la impresora...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Archivo de control enviado correctamente\n" + +msgid "INFO: Copying print data...\n" +msgstr "INFO: Copiando datos de impresión...\n" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Archivo de datos enviado correctamente\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "INFO: Acabada la página %d...\n" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Formateando página %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Cargando archivo de imagen...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Buscando impresora...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Abriendo la conexión\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" +"INFO: Archivo de impresión enviado; esperando a que finalice la " +"impresora...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Impresora ocupada; reintento en 10 segundos...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Impresora ocupada; reintento en 30 segundos...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Impresora ocupada; reintento en 5 segundos...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: La impresora no es compatible con IPP/%d.%d, probando IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: La impresora está ocupada; reintento en 5 segundos...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: La impresora está actualmente fuera de línea.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: La impresora está sin conexión en estos momentos.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: La impresora ya tiene conexión.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: La impresora está sin conexión.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Impresora no conectada; reintento en 30 segundos...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Imprimiendo página %d, %d%% completado...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Imprimiendo página %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Lista para imprimir.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Enviando archivo de control (%lu bytes)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Enviando archivo de control (%u bytes)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Enviando datos\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Enviando archivo de datos (%ld bytes)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Enviando archivo de datos (%lld bytes)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Enviando datos de impresión...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Archivo de impresión enviado, %ld bytes...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Archivo de impresión enviado, %lld bytes...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Guardando trabajo LPR en cola, %.0f%% completado...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "INFO: Iniciando página %d...\n" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: No se ha podido contactar con la impresora; poniendo en cola en la " +"siguiente impresora de la clase...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Usando zona AppleTalk predeterminada \"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Esperando a que finalice el trabajo...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Esperando a que la impresora esté disponible...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "Sobre ISO B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (extragrande)" + +msgid "ISO B5 Envelope" +msgstr "Sobre ISO B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "Sobre ISO B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Carácter de control ilegal" + +msgid "Illegal main keyword string" +msgstr "Cadena de clave principal ilegal" + +msgid "Illegal option keyword string" +msgstr "Cadena de clave de opción ilegal" + +msgid "Illegal translation string" +msgstr "Cadena de traducción ilegal" + +msgid "Illegal whitespace character" +msgstr "Carácter de espacio en blanco ilegal" + +msgid "Ink/toner almost empty." +msgstr "Tinta/toner casi vacíos." + +msgid "Ink/toner empty!" +msgstr "Tinta/toner vacíos." + +msgid "Ink/toner waste bin almost full." +msgstr "Recipiente de residuos de tinta/tóner casi lleno." + +msgid "Ink/toner waste bin full!" +msgstr "Recipiente de residuos de tinta/tóner lleno." + +msgid "Installable Options" +msgstr "Opciones instalables" + +msgid "Installed" +msgstr "Instalada" + +msgid "IntelliBar Label Printer" +msgstr "Impresora de etiquetas IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Dispositivo de seguridad abierto." + +msgid "Internal Server Error" +msgstr "Error interno del servidor" + +msgid "Internal error" +msgstr "Error interno" + +msgid "Internet Postage 2-Part" +msgstr "Correo por Internet Parte-2" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Correo por Internet Parte-2 - 2 1/4 x 7 1/2 pulg." + +msgid "Internet Postage 3-Part" +msgstr "Correo por Internet Parte-3" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Correo por Internet Parte-3 - 2 1/4 x 7 pulg." + +msgid "Internet Printing Protocol" +msgstr "Protocolo de Impresión de Internet IPP" + +msgid "Invite Envelope" +msgstr "Sobre de invitación" + +msgid "Italian Envelope" +msgstr "Sobre Italiano" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "El trabajo #%d no puede ser reiniciado - no hay archivos." + +#, c-format +msgid "Job #%d does not exist!" +msgstr "El trabajo #%d no existe." + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "El trabajo #%d ya está anulado - no se puede cancelar." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "El trabajo #%d ya está cancelado - no se puede cancelar." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "El trabajo #%d ya ha sido completado - no se puede cancelar." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "El trabajo #%d ha terminado y no puede ser modificado." + +#, c-format +msgid "Job #%d is not complete!" +msgstr "El trabajo #%d no ha sido completado." + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "El trabajo #%d no está retenido para autentificación." + +#, c-format +msgid "Job #%d is not held!" +msgstr "El trabajo #%d no está retenido." + +#, c-format +msgid "Job #%s does not exist!" +msgstr "El trabajo #%s no existe." + +#, c-format +msgid "Job %d not found!" +msgstr "No se ha encontrado el trabajo %d." + +msgid "Job Completed" +msgstr "Trabajo completado" + +msgid "Job Created" +msgstr "Trabajo creado" + +msgid "Job ID: " +msgstr "ID del trabajo: " + +msgid "Job Options Changed" +msgstr "Opciones de trabajo cambiadas" + +msgid "Job Stopped" +msgstr "Trabajo detenido" + +msgid "Job UUID: " +msgstr "UUID del trabajo: " + +msgid "Job is completed and cannot be changed." +msgstr "El trabajo está terminado y no puede ser cambiado." + +msgid "Job operation failed:" +msgstr "La operación del trabajo ha fallado:" + +msgid "Job state cannot be changed." +msgstr "No se puede cambiar el estado del trabajo." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Las suscripciones de trabajos no han podido ser renovadas." + +msgid "Jobs" +msgstr "Trabajos" + +msgid "Kaku2 Envelope" +msgstr "Sobre Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Sobre Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Equipo o impresora LPD/LPR" + +msgid "Label Printer" +msgstr "Impresora de etiquetas" + +msgid "Label Top" +msgstr "Parte superior de la etiqueta" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "No se admite el uso del idioma \"%s\"." + +msgid "Large Address" +msgstr "Dirección grande" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Dirección grande - 1 4/10 x 3 1/2 pulg." + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "Ligero" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Línea más larga que el máximo permitido (255 caracteres)" + +msgid "List Available Printers" +msgstr "Listar impresoras disponibles" + +msgid "Location: " +msgstr "Ubicación: " + +msgid "Long-Edge (Portrait)" +msgstr "Lado largo (retrato)" + +msgid "Make and Model: " +msgstr "Marca y modelo: " + +msgid "Manual Feed" +msgstr "Alimentación manual" + +msgid "Media Dimensions: " +msgstr "Dimensiones del papel: " + +msgid "Media Limits: " +msgstr "Límites del papel: " + +msgid "Media Name: " +msgstr "Nombre del soporte: " + +msgid "Media Size" +msgstr "Tamaño de papel" + +msgid "Media Source" +msgstr "Fuente del papel" + +msgid "Media Tracking" +msgstr "Seguimiento del medio" + +msgid "Media Type" +msgstr "Tipo de papel" + +msgid "Media jam!" +msgstr "Atasco de papel." + +msgid "Media tray almost empty." +msgstr "Bandeja de papel casi vacía." + +msgid "Media tray empty!" +msgstr "Bandeja de papel vacía." + +msgid "Media tray missing!" +msgstr "Falta la bandeja de papel." + +msgid "Media tray needs to be filled." +msgstr "Hay que poner papel en la bandeja." + +msgid "Medium" +msgstr "Media" + +msgid "Memory allocation error" +msgstr "Error de reserva de memoria" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Falta cabecera PPD-Adobe-4.x" + +msgid "Missing asterisk in column 1" +msgstr "Falta un asterisco en la columna 1" + +msgid "Missing document-number attribute!" +msgstr "Falta el atributo document-number." + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Faltan dobles comillas en línea %d." + +msgid "Missing form variable!" +msgstr "Variable de formulario desaparecida." + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Atributo notify-subscription-ids desaparecido." + +msgid "Missing requesting-user-name attribute!" +msgstr "Falta el atributo requesting-user-name." + +msgid "Missing required attributes!" +msgstr "Faltan atributos necesarios." + +#, c-format +msgid "Missing value on line %d!" +msgstr "Falta un valor en la línea %d." + +msgid "Missing value string" +msgstr "Falta cadena de valores" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modelo: nombre = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Modificar clase" + +msgid "Modify Printer" +msgstr "Modificar impresora" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Sobre Monarch" + +msgid "Move All Jobs" +msgstr "Mover todos los trabajos" + +msgid "Move Job" +msgstr "Mover trabajo" + +msgid "Moved Permanently" +msgstr "Movido permanentemente" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Archivo de impresión aceptado: ID de trabajo %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Archivo de impresión aceptado: ID de trabajo desconocido.\n" + +msgid "NULL PPD file pointer" +msgstr "Puntero de archivo PPD NULO" + +msgid "Name OID uses indefinite length" +msgstr "Nombre OID usa una longitud indefinida" + +msgid "Nested classes are not allowed!" +msgstr "No se permiten clases anidadas." + +msgid "Never" +msgstr "Nunca" + +msgid "New Stylus Color Series" +msgstr "Nueva Stylus Color Series" + +msgid "New Stylus Photo Series" +msgstr "Nueva Stylus Photo Series" + +msgid "No" +msgstr "No" + +msgid "No Content" +msgstr "No hay contenido" + +msgid "No PPD name!" +msgstr "No hay nombre de PPD." + +msgid "No VarBind SEQUENCE" +msgstr "No hay Varbind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "No está instalado ningún controlador de impresora de Windows." + +msgid "No active connection" +msgstr "No hay conexión activa" + +#, c-format +msgid "No active jobs on %s!" +msgstr "No hay trabajos activos en %s." + +msgid "No attributes in request!" +msgstr "No hay atributos en la solicitud." + +msgid "No authentication information provided!" +msgstr "No se ha proporcionado información de autentificación." + +msgid "No community name" +msgstr "No hay nombre de comunidad" + +msgid "No default printer" +msgstr "No hay impresora predeterminada" + +msgid "No destinations added." +msgstr "No se han añadido destinos." + +msgid "No error-index" +msgstr "No hay error-index" + +msgid "No error-status" +msgstr "No hay error-status" + +msgid "No file!?!" +msgstr "¡¿¡No hay archivo!?!" + +msgid "No modification time!" +msgstr "No hay tiempo de modificación." + +msgid "No name OID" +msgstr "No hay nombre OID" + +msgid "No printer name!" +msgstr "No hay nombre de impresora." + +msgid "No printer-uri found for class!" +msgstr "No se encontró printer-uri para la clase." + +msgid "No printer-uri found!" +msgstr "No se encontró printer-uri." + +msgid "No printer-uri in request!" +msgstr "No hay printer-uri en la petición." + +msgid "No request-id" +msgstr "No hay request-id" + +msgid "No subscription attributes in request!" +msgstr "No hay atributos de subscripción en la solicitud." + +msgid "No subscriptions found." +msgstr "No se han encontrado subscripciones." + +msgid "No variable-bindings SEQUENCE" +msgstr "No hay variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "No hay número de versión" + +msgid "Non-continuous (Mark sensing)" +msgstr "No continuo (sensible a señal)" + +msgid "Non-continuous (Web sensing)" +msgstr "No continuo (sensible a web)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "No encontrado" + +msgid "Not Implemented" +msgstr "No implementado" + +msgid "Not Installed" +msgstr "No instalado" + +msgid "Not Modified" +msgstr "No modificado" + +msgid "Not Supported" +msgstr "No permitido" + +msgid "Not allowed to print." +msgstr "No se permite imprimir." + +msgid "Note" +msgstr "Nota" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC prácticamente agotado." + +msgid "OPC at end-of-life!" +msgstr "OPC agotado." + +msgid "Off (1-Sided)" +msgstr "Desactivado (1 cara)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Ayuda en línea" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "La apertura de %s ha fallado: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup sin un CloseGroup previo" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI sin un CloseUI/JCLCloseUI previo" + +msgid "Operation Policy" +msgstr "Directiva de operación" + +msgid "Options Installed" +msgstr "Opciones instaladas" + +msgid "Options: " +msgstr "Opciones: " + +msgid "Out of toner!" +msgstr "No hay toner." + +msgid "Output Mode" +msgstr "Modo de salida" + +msgid "Output bin almost full." +msgstr "Recipiente de salida casi lleno." + +msgid "Output bin full!" +msgstr "Recipiente de salida lleno." + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "La salida de la impresora %s se ha enviado a %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "" +"La salida de la impresora %s se ha enviado a la impresora remota %s en %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "La salida de la impresora %s/%s se ha enviado a %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"La salida de la impresora %s/%s se ha enviado a la impresora remota %s en %" +"s\n" + +msgid "Output tray missing!" +msgstr "Falta la bandeja de salida." + +msgid "PASS\n" +msgstr "PASA\n" + +msgid "PCL Laser Printer" +msgstr "Impresora Laser PCL" + +msgid "PRC1 Envelope" +msgstr "Sobre PRC1" + +msgid "PRC10 Envelope" +msgstr "Sobre PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Sobre PRC2" + +msgid "PRC3 Envelope" +msgstr "Sobre PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (extragrande)" + +msgid "PRC4 Envelope" +msgstr "Sobre PRC4" + +msgid "PRC5 Envelope" +msgstr "Sobre PRC5" + +msgid "PRC6 Envelope" +msgstr "Sobre PRC6" + +msgid "PRC7 Envelope" +msgstr "Sobre PRC7" + +msgid "PRC8 Envelope" +msgstr "Sobre PRC8" + +msgid "PRC9 Envelope" +msgstr "Sobre PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "El paquete no contiene un Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "El paquete no empieza por SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "¿Contraseña de %s en %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Se requiere la contraseña de %s para acceder a %s vía SAMBA: " + +msgid "Pause Class" +msgstr "Pausar clase" + +msgid "Pause Printer" +msgstr "Pausar impresora" + +msgid "Peel-Off" +msgstr "Despegar" + +msgid "Personal Envelope" +msgstr "Sobre personal" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Foto pequeña" + +msgid "Plain Paper" +msgstr "Papel normal" + +msgid "Policies" +msgstr "Reglas" + +msgid "Port Monitor" +msgstr "Monitor de puerto" + +msgid "PostScript Printer" +msgstr "Impresora PostScript" + +msgid "Postcard" +msgstr "Postal" + +msgid "Print Density" +msgstr "Densidad de impresión" + +msgid "Print Job:" +msgstr "Imprimir trabajo:" + +msgid "Print Mode" +msgstr "Modo de impresión" + +msgid "Print Rate" +msgstr "Tasa de impresión" + +msgid "Print Self-Test Page" +msgstr "Imprimir página de auto-prueba" + +msgid "Print Speed" +msgstr "Velocidad de impresión" + +msgid "Print Test Page" +msgstr "Imprimir página de prueba" + +msgid "Print and Cut" +msgstr "Imprimir y cortar" + +msgid "Print and Tear" +msgstr "Imprimir y romper" + +msgid "Printed For: " +msgstr "Impreso para: " + +msgid "Printed From: " +msgstr "Impreso desde: " + +msgid "Printed On: " +msgstr "Impreso en: " + +msgid "Printer Added" +msgstr "Impresora añadida" + +msgid "Printer Default" +msgstr "Predeterminado de la impresora" + +msgid "Printer Deleted" +msgstr "Impresora borrada" + +msgid "Printer Modified" +msgstr "Impresora modificada" + +msgid "Printer Name: " +msgstr "Nombre de la impresora: " + +msgid "Printer Paused" +msgstr "Impresora en pausa" + +msgid "Printer Settings" +msgstr "Configuración de la impresora" + +msgid "Printer offline." +msgstr "Impresora desconectada." + +msgid "Printer:" +msgstr "Impresora:" + +msgid "Printers" +msgstr "Impresoras" + +msgid "Purge Jobs" +msgstr "Purgar trabajos" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Se ha alcanzado el límite de cuota." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "Rango Propiet. Trabajo Archivo(s) Tamaño total\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Rango Propiet. Pri Trabajo Archivos Tamaño total\n" + +msgid "Reject Jobs" +msgstr "Rechazar trabajos" + +msgid "Reprint After Error" +msgstr "Volver a imprimir tras un error" + +msgid "Request Entity Too Large" +msgstr "La entidad requerida es demasiado larga" + +msgid "Resolution" +msgstr "Resolución" + +msgid "Resume Class" +msgstr "Reanudar clase" + +msgid "Resume Printer" +msgstr "Reanudar impresora" + +msgid "Return Address" +msgstr "Remite" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Remite - 3/4 x 2 pulg." + +msgid "Rewind" +msgstr "Rebobinar" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Ejecutando comando: %s %s -N -A '%s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "Impresora SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE usa una longitud indefinida" + +msgid "See Other" +msgstr "Ver otros" + +#, c-format +msgid "Serial Port #%d" +msgstr "Puerto serie #%d" + +msgid "Server Restarted" +msgstr "Servidor reiniciado" + +msgid "Server Security Auditing" +msgstr "Auditoría de seguridad del servidor" + +msgid "Server Started" +msgstr "Servidor iniciado" + +msgid "Server Stopped" +msgstr "Servidor parado" + +msgid "Service Unavailable" +msgstr "Servicio no disponible" + +msgid "Set Allowed Users" +msgstr "Establecer usuarios permitidos" + +msgid "Set As Server Default" +msgstr "Establecer como predeterminada del servidor" + +msgid "Set Class Options" +msgstr "Cambiar opciones clase" + +msgid "Set Printer Options" +msgstr "Cambiar opciones impresora" + +msgid "Set Publishing" +msgstr "Hacer pública" + +msgid "Shipping Address" +msgstr "Dirección de envío" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Dirección de envío - 2 5/16 x 4 pulg." + +msgid "Short-Edge (Landscape)" +msgstr "Lado corto (apaisado)" + +msgid "Special Paper" +msgstr "Papel especial" + +msgid "Standard" +msgstr "Estándar" + +msgid "Starting Banner" +msgstr "Rótulo inicial" + +msgid "Statement" +msgstr "Declaración" + +msgid "Stylus Color Series" +msgstr "Stylus Color Series" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo Series" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B (13 x 19 pulg.)" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Protocolos de conexión" + +msgid "Tabloid" +msgstr "Tabloide" + +msgid "Tabloid (Oversize)" +msgstr "Tabloide (extragrande)" + +msgid "Tear" +msgstr "Pestaña" + +msgid "Tear-Off" +msgstr "Pestaña desprendible" + +msgid "Tear-Off Adjust Position" +msgstr "Ajuste de posición de la pestaña desprendible" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "No se ha podido encontrar el archivo PPD \"%s\"." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "No se ha podido abrir el archivo PPD \"%s\": %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"El nombre de la clase sólo puede contener hasta 127 caracteres imprimibles y " +"no puede contener espacios, barras (/), o la almohadilla (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"El atributo notify-lease-duration no puede ser usado con subscripciones de " +"trabajos." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "El valor notify-user-data es demasiado grande (%d > 63 octetos)." + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"El nombre de la impresora sólo puede contener hasta 127 caracteres " +"imprimibles y no puede contener espacios, barras (/), o la almohadilla (#)." + +msgid "The printer or class is not shared!" +msgstr "La impresora o clase no está compartida." + +msgid "The printer or class was not found." +msgstr "No se ha encontrado la impresora o la clase." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "El printer-uri \"%s\" contiene caracteres incorrectos." + +msgid "The printer-uri attribute is required!" +msgstr "Se necesita el atributo printer-uri." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"El printer-uri debe ser de la forma \"ipp://NOMBRE_ORDENADOR/classes/" +"NOMBRE_CLASE\"." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"El printer-uri debe ser de la forma \"ipp://NOMBRE_ORDENADOR/printers/" +"NOMBRE_IMPRESORA\"." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"El nombre de la subscripción no puede contener espacios, barras (/), signos " +"de interrogación (?), o la almohadilla (#)." + +msgid "There are too many subscriptions." +msgstr "Hay demasiadas subscripciones." + +msgid "Thermal Transfer Media" +msgstr "Soporte de transferencia térmica" + +msgid "Title: " +msgstr "Título: " + +msgid "Toner low." +msgstr "Toner bajo." + +msgid "Too many active jobs." +msgstr "Demasiados trabajos activos." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Demasiados valores de job-sheets (%d > 2)." + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Demasiados valores printer-state-reasons (%d > %d)." + +msgid "Transparency" +msgstr "Transparencia" + +msgid "Tray" +msgstr "Bandeja" + +msgid "Tray 1" +msgstr "Bandeja 1" + +msgid "Tray 2" +msgstr "Bandeja 2" + +msgid "Tray 3" +msgstr "Bandeja 3" + +msgid "Tray 4" +msgstr "Bandeja 4" + +msgid "URI Too Long" +msgstr "URI demasiado largo" + +msgid "US Executive" +msgstr "Ejecutivo de EE.UU" + +msgid "US Fanfold" +msgstr "FanFold de EE.UU" + +msgid "US Ledger" +msgstr "Libro Mayor, 17 x 11 pulg." + +msgid "US Legal" +msgstr "Legal EE.UU." + +msgid "US Legal (Oversize)" +msgstr "Legal EE.UU. (extragrande)" + +msgid "US Letter" +msgstr "Carta EE.UU." + +msgid "US Letter (Oversize)" +msgstr "Carta EE.UU. (extragrande)" + +msgid "US Letter (Small)" +msgstr "Carta EE.UU. (pequeña)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Puerto serie USB #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "No se ha podido acceder al archivo cupsd.conf" + +msgid "Unable to add RSS subscription:" +msgstr "No se ha podido añadir la subscripción RSS:" + +msgid "Unable to add class:" +msgstr "No se ha podido añadir la clase:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "No se ha podido añadir el trabajo para el destino \"%s\"." + +msgid "Unable to add printer:" +msgstr "No se ha podido añadir la impresora:" + +msgid "Unable to allocate memory for file types!" +msgstr "No se ha podido reservar memoria para tipos de archivo." + +msgid "Unable to cancel RSS subscription:" +msgstr "No se ha podido cancelar la subscripción RSS:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "No se ha podido cambiar el atributo printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "No se ha podido cambiar la impresora:" + +msgid "Unable to change server settings:" +msgstr "No se ha podido cambiar la configuración del servidor:" + +msgid "Unable to connect to host." +msgstr "No se ha podido conectar al servidor." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" +"No se han podido copiar los archivos del controlador de impresora de 64-bit " +"de CUPS (%d)." + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"No se han podido copiar los archivos del controlador de impresora de 64-bit " +"de Windows (%d)." + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "" +"No se han podido copiar los archivos del controlador de impresora de CUPS (%" +"d)." + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "No se ha podido copiar el archivo PPD - %s." + +msgid "Unable to copy PPD file!" +msgstr "No se ha podido copiar el archivo PPD." + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"No se han podido copiar los archivos del controlador de impresora de Windows " +"2000 (%d)." + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" +"No se han podido copiar los archivos del controlador de impresora de Windows " +"9x (%d)." + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "No se ha podido copiar el script de interfaz - %s." + +msgid "Unable to create printer-uri!" +msgstr "No se ha podido crear printer-uri." + +msgid "Unable to create temporary file:" +msgstr "No se ha podido crear el archivo temporal:" + +msgid "Unable to delete class:" +msgstr "No se ha podido borrar la clase:" + +msgid "Unable to delete printer:" +msgstr "No se ha podido borrar la impresora:" + +msgid "Unable to do maintenance command:" +msgstr "No se ha podido realizar el comando de mantenimiento:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "No se pueden editar archivos cupsd.conf mayores de 1MB." + +msgid "Unable to find destination for job!" +msgstr "No se ha podido encontrar destino para el trabajo." + +msgid "Unable to find printer!\n" +msgstr "No se ha podido encontrar la impresora.\n" + +msgid "Unable to get class list:" +msgstr "No se ha podido obtener la lista de clases:" + +msgid "Unable to get class status:" +msgstr "No se ha podido obtener el estado de la clase:" + +msgid "Unable to get list of printer drivers:" +msgstr "No se ha podido obtener la lista de controladores de impresora:" + +msgid "Unable to get printer attributes:" +msgstr "No se han podido obtener los atributos de la impresora:" + +msgid "Unable to get printer list:" +msgstr "No se ha podido obtener la lista de impresoras:" + +msgid "Unable to get printer status:" +msgstr "No se ha podido obtener el estado de la impresora" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"No se han podido instalar los archivos del controlador de impresora de " +"Windows 2000 (%d)." + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"No se han podido instalar los archivos del controlador de impresora de " +"Windows 9x (%d)." + +msgid "Unable to modify class:" +msgstr "No se ha podido modificar la clase:" + +msgid "Unable to modify printer:" +msgstr "No se ha podido modificar la impresora:" + +msgid "Unable to move job" +msgstr "No se ha podido mover el trabajo" + +msgid "Unable to move jobs" +msgstr "No se han podido mover los trabajos" + +msgid "Unable to open PPD file" +msgstr "No se ha podido abrir el archivo PPD" + +msgid "Unable to open PPD file:" +msgstr "No se ha podido abrir el archivo PPD:" + +msgid "Unable to open cupsd.conf file:" +msgstr "No se ha podido abrir el archivo cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "No se ha podido abrir el documento %d del trabajo %d." + +msgid "Unable to print test page:" +msgstr "No se ha podido imprimir la página de prueba:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "No se ha podido ejecutar \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "No se ha podido enviar un comando al controlador de la impresora." + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "" +"No se ha podido configurar el controlador de impresora de Windows (%d)." + +msgid "Unable to set options:" +msgstr "No se han podido cambiar las opciones:" + +msgid "Unable to set server default:" +msgstr "No se han podido cambiar los ajustes predeterminados del servidor:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "No se ha podido copiar el archivo cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "No se ha podido usar el controlador de dispositivo USB obsoleto.\n" + +msgid "Unauthorized" +msgstr "No autorizado" + +msgid "Units" +msgstr "Unidades" + +msgid "Unknown" +msgstr "Desconocido" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "printer-error-policy \"%s\" incorrecto." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "printer-op-policy \"%s\" incorrecto." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Juego de caracteres \"%s\" no permitido." + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "No se admite el uso de la compresión \"%s\"." + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "No se admite el uso del atributo de compresión %s." + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "No se admite el uso del formato \"%s\"." + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "No se admite el uso del formato '%s'." + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "No se admite el uso del formato '%s/%s'." + +msgid "Unsupported value type" +msgstr "Tipo de valor no permitido" + +msgid "Upgrade Required" +msgstr "Se requiere actualización" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Uso:\n" +"\n" +" lpadmin [-h servidor] -d destino\n" +" lpadmin [-h servidor] -x destino\n" +" lpadmin [-h servidor] -p impresora [-c clase] [-i interfaz] [-m modelo]\n" +" [-r clase] [-v dispositivo] [-D descripción]\n" +" [-P archivo_ppd] [-o nombre=valor]\n" +" [-u allow:usuario,usuario] [-u deny:usuario,usuario]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Uso: %s trabajo usuario título copias opciones [archivo]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Uso: %s job-id usuario título copias opciones [archivo]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Uso: %s job-id usuario título copias opciones archivo\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" +"Uso: convert [ opciones ]\n" +"\n" +"Opciones:\n" +"\n" +" -e Usar cada filtro del archivo PPD\n" +" -f nombre_archivo Establecer el archivo a convertir (de lo " +"contrario, stdin)\n" +" -o nombre_archivo Establecer el archivo a generar (de lo " +"contrario, stdout)\n" +" -i tipo/mime Establecer el tipo MIME de entrada (de lo contrario, " +"auto-typed)\n" +" -j tipo/mime Establecer el tipo MIME de salida (de lo contrario, " +"application/pdf)\n" +" -P nombre_archivo.ppd Establecer el archivo PPD\n" +" -a 'nombre=valor ...' Establecer opciones\n" +" -U nombre_usuario Establecer un nombre de usuario para el " +"trabajo\n" +" -J título Establecer el título\n" +" -c copias Establecer el número de copias\n" +" -u Borrar el archivo PPD al finalizar\n" +" -D Borrar el archivo de entrada al finalizar\n" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Uso: cupsaddsmb [opciones] impresora1 ... impresoraN\n" +" cupsaddsmb [opciones] -a\n" +"\n" +"Opciones:\n" +" -E Hace que se use encriptación en la conexión con el " +"servidor\n" +" -H servidor_samba Usa el servidor SAMBA especificado\n" +" -U usuario_samba Autentifica usando el usuario SAMBA especificado\n" +" -a Exporta todas las impresoras\n" +" -h servidor_cups Usa el servidor CUPS especificado\n" +" -v Ser detallado (mostrar comandos)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Uso: cupsctl [opciones] [param=valor ... paramN=valorN]\n" +"\n" +"Opciones:\n" +"\n" +" -E Activar encriptación\n" +" -U nombre_usuario Especificar nombre de usuario\n" +" -h servidor[:puerto] Especificar la dirección del servidor\n" +"\n" +" --[no-]debug-logging Activar o desactivar el registro de depuración\n" +" --[no-]remote-admin Activar o desactivar la administración remota\n" +" --[no-]remote-any Permitir o impedir el acceso desde Internet\n" +" --[no-]remote-printers Mostrar u ocultar las impresoras remotas\n" +" --[no-]share-printers Activar o desactivar la compartición de " +"impresoras\n" +" --[no-]user-cancel-any Permitir o impedir a los usuarios cancelar " +"cualquier trabajo\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Uso: cupsd (-c archivo-configuración) (-f) (-F) (-h) (-l)\n" +"\n" +"-c archivo-configuración Carga un archivo de configuración alternativo\n" +"-f Se ejecuta en primer plano\n" +"-F Se ejecuta en primer plano pero separado\n" +"-h Muestra este mensaje de cómo se usa\n" +"-l Ejecuta cupsd desde launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" +"Uso: cupsfilter -m tipo/mime [ opciones ] nombre_archivo\n" +"\n" +"Opciones:\n" +"\n" +" -c cupsd.conf Establecer el archivo cupsd.conf a usar\n" +" -e Usar cada filtro del archivo PPD\n" +" -j job-id[,N] Filtrar el archivo N del trabajo especificado (el valor " +"predeterminado es el archivo 1)\n" +" -n copias Establecer el número de copias\n" +" -o nombre=valor Establecer opciones\n" +" -p nombre_archivo.ppd Establecer el archivo PPD\n" +" -t título Establecer el título\n" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Uso: cupstestdsc [opciones] nombre_archivo.ps [... nombre_archivo.ps]\n" +" cupstestdsc [opciones] -\n" +"\n" +"Opciones:\n" +"\n" +" -h Muestra cómo se usa el programa\n" +"\n" +" Nota: este programa sólo valida los comentarios DSC, no el PostScript en " +"sí mismo.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" +"Uso: cupstestppd [opciones] nombre_archivo1.ppd[.gz] [... nombre_archivoN.ppd" +"[.gz]]\n" +" programa | cupstestppd [opciones] -\n" +"\n" +"Opciones:\n" +"\n" +" -R directorio-raíz Establecer directorio raíz alternativo\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Emitir avisos (warnings) en vez de errores\n" +" -q Ejecución silenciosa\n" +" -r Usar modo abierto 'relajado'\n" +" -v Ser ligeramente detallado\n" +" -vv Ser muy detallado\n" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Uso: lpmove trabajo/fuente destino\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Uso: lpoptions [-h servidor] [-E] -d impresora\n" +" lpoptions [-h servidor] [-E] [-p impresora] -l\n" +" lpoptions [-h servidor] [-E] -p impresora -o opción[=valor] ...\n" +" lpoptions [-h servidor] [-E] -x impresora\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Usage: lppasswd [-g nombre_grupo]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Usage: lppasswd [-g nombre_grupo] [nombre_usuario]\n" +" lppasswd [-g nombre_grupo] -a [nombre_usuario]\n" +" lppasswd [-g nombre_grupo] -x [nombre_usuario]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Uso: lpq (-P dest) (-U nombre_usuario) (-h nombre_ordenador(:puerto)) (-l) " +"(+intervalo)\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Uso: ppdc [opciones] nombre_archivo.drv [ ... nombre_archivoN.drv ]\n" +"Options:\n" +" -D nombre=valor Establecer la variable nombre al valor.\n" +" -I include-dir Añadir el directorio include a la ruta de búsqueda.\n" +" -c catálogo.po Cargar el catálogo de mensajes especificado.\n" +" -d dir-salida Especificar el directorio de salida.\n" +" -l idioma[,idioma,...] Especificar el/los idioma(s) de salida.\n" +" -m Usar el valor ModelName como nombre de archivo.\n" +" -t Chequear el PPDs en vez de generarlo.\n" +" -v Ser detallado (más v's para más detalle).\n" +" -z Comprimir los archivos PPD usando GNU zip.\n" +" --cr Terminar las líneas con CR (Mac OS 9).\n" +" --crlf Terminar las líneas con CR + LF (Windows).\n" +" --lf Terminar las líneas con LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Uso: ppdhtml [opciones] nombre_archivo.drv >nombre_archivo.html\n" +"Opciones:\n" +" -D nombre=valor Establecer la variable nombre al valor.\n" +" -I include-dir Añadir el directorio include a la ruta de búsqueda.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Uso: ppdi [opciones] nombre_archivo.ppd [ ... nombre_archivoN.ppd ]\n" +"Opciones:\n" +" -I include-dir\n" +" -o nombre_archivo.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Uso: ppdmerge [opciones] nombre_archivo.ppd [ ... nombre_archivoN.ppd ]\n" +"Opciones:\n" +" -o nombre_archivo.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Uso: ppdpo [opciones] -o nombre_archivo.po nombre_archivo.drv [ ... " +"nombre_archivoN.drv ]\n" +"Opciones:\n" +" -D nombre=valor Establecer la variable nombre al valor.\n" +" -I include-dir Añadir el directorio include a la ruta de búsqueda.\n" +" -v Ser detallado (más v's para más detalle).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Uso: snmp [ordenador-o-dirección-ip]\n" + +msgid "Value uses indefinite length" +msgstr "Valor usa una longitud indefinida" + +msgid "VarBind uses indefinite length" +msgstr "VarBind usa una longitud indefinida" + +msgid "Version uses indefinite length" +msgstr "Versión usa una longitud indefinida" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Añadiendo sólo las primeras %d impresoras encontradas" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "" +"WARNING: Se esperaba un valor booleano para la opción waiteof \"%s\".\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: No se ha podido leer la petición del canal lateral.\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: La opción \"%s\" no puede incluirse con IncludeFeature.\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: La impresora no responde\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: La impresora envió un EOF inesperado\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: El ordenador remoto no ha respondido con el byte de estado del " +"comando después de %d segundos.\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: El ordenador remoto no ha respondido con el byte de estado de " +"control después de %d segundos.\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: El ordenador remoto no ha respondido con el byte de estado de los " +"datos después de %d segundos.\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "" +"WARNING: Agotado el tiempo de espera para el comando SCSI (%d); " +"reintentando...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Este documento no se ajusta a las Convenciones de Estructuración de " +"Documentos de Adobe y puede que no se imprima correctamente.\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: No se ha podido abrir \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: No se ha podido enviar la petición de estado PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Paquete PAP de tipo %d no esperado\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Paquete PAP de tipo %d desconocido\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Preferencia \"%s\" desconocida para la opción \"%s\".\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Opción \"%s\" desconocida.\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: No se admite el uso de la velocidad en baudios %s.\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: se esperaba un número para la opción de estado \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: recuperable: El ordenador de red '%s' está ocupado; reintento en %d " +"segundos...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "" +"Advertencia, no está instalado ningún controlador de impresora de Windows " +"2000." + +msgid "Yes" +msgstr "Si" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Debe acceder a esta página usando el URL https://" +"%s:%d%s." + +msgid "You4 Envelope" +msgstr "Sobre You4" + +msgid "ZPL Label Printer" +msgstr "Impresora de etiquetas ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "cancelado" + +msgid "canceled" +msgstr "cancelado" + +msgid "completed" +msgstr "completado" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: Use la opción -f para especificar el fichero a convertir.\n" + +msgid "cups-deviced failed to execute." +msgstr "Ha fallado al ejecutarse cups-deviced." + +msgid "cups-driverd failed to execute." +msgstr "Ha fallado al ejecutarse cups-driverd." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: No hay archivo PPD para la impresora \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: No se ha podido conectar al servidor: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Opción \"%s\" desconocida.\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Opción \"-%c\" desconocida.\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "" +"cupsd: Se esperaba un nombre de archivo de configuración tras la opción \"-c" +"\".\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: No se ha podido obtener el directorio actual.\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Argumento \"%s\" desconocido - cancelando.\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Opción \"%c\" desconocida - cancelando.\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: el uso de launchd(8) no ha sido compilado, ejecutándose en modo " +"normal.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Número de documento %d inválido.\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: ID de trabajo %d inválida.\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Solo se puede especificar un nombre de archivo.\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: No se ha podido obtener el archivo del trabajo - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: La opción -q es incompatible con la opción -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: La opción -v es incompatible con la opción -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "tipo de conexión para %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "tipo de conexión para %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index usa una longitud indefinida" + +msgid "error-status uses indefinite length" +msgstr "error-status usa una longitud indefinida" + +msgid "held" +msgstr "retenido" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tproporciona ayuda sobre los comandos\n" + +msgid "idle" +msgstr "inactiva" + +msgid "job-printer-uri attribute missing!" +msgstr "Falta el atributo job-printer-uri." + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "" +"lpadmin: El nombre de la clase sólo puede contener caracteres imprimibles.\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: Se esperaba un PPD tras la opción '-P'.\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Se esperaba allow/deny:lista_usuarios tras la opción '-u'.\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Se esperaba una clase tras la opción '-r'\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Se esperaba un nombre de clase tras la opción '-c'\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Se esperaba una descripción tras la opción '-D'.\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Se esperaba un URI de dispositivo tras la opción '-v'.\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Se esperaba tipo(s) de archivo(s) tras la opción '-l'.\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Se esperaba un nombre de ordenador tras la opción '-h'.\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Se esperaba una interfaz tras la opción '-i'.\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Se esperaba una ubicación tras la opción '-L'.\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Se esperaba un modelo tras la opción '-m'.\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Se esperaba un nombre=valor tras la opción '-o'.\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Se esperaba una impresora tras la opción '-p'.\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Se esperaba un nombre de impresora tras la opción '-d'\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Se esperaba una impresora o clase tras la opción '-x'.\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: No se han visto nombres de miembros.\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: La impresora %s ya es miembro de la clase %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: La impresora %s no es miembro de la clase %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "" +"lpadmin: El nombre de la impresora sólo puede contener caracteres " +"imprimibles.\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido añadir una impresora a la clase:\n" +" Debe especificar un nombre de impresora primero.\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: No se ha podido conectar al servidor: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: No se ha podido abrir el archivo PPD \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: No se ha podido abrir el archivo \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido quitar una impresora de la clase:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido establecer el archivo PPD:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido ajustar el URI de dispositivo:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido establecer el script de interfaz o el archivo PPD:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido establecer el script de interfaz:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido establecer la descripción de la impresora:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se ha podido establecer la ubicación de la impresora:\n" +" Primero debe especificar un nombre de impresora.\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: No se han podido establecer las opciones de impresora:\n" +" Primero debe especificar un nombre de impresora.\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Opción allow/deny desconocida \"%s\".\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Argumento '%s' desconocido.\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Opción '%c' desconocida.\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "" +"lpadmin: Advertencia - lista de tipo de contenido no tenida en cuenta.\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" +"lpinfo: Se esperaba una cadena ID de dispositivo 1284 tras --device-id.\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Se esperaba un idioma tras --language.\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Se esperaba marca y modelo tras --make-and-model.\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Se esperaba una cadena de producto tras --product.\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Se esperaba una lista de esquemas tras --exclude-schemes.\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Se esperaba una lista de esquemas tras --include-schemes.\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Se esperaba un tiempo tras --timeout.\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo Argumento '%s' desconocido.\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Opción '%c' desconocida.\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Opción desconocida '%s'.\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: No se ha podido conectar al servidor: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Argumento '%s' desconocido.\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Opción '%c' desconocida.\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: ¡¿¡No hay impresoras!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: No se ha podido añadir la impresora o la instancia: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: No se ha podido obtener el archivo PPD para %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: No se ha podido abrir el archivo PPD para %s.\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Impresora o clase desconocida.\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Solo el usuario root puede añadir o borrar contraseñas.\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Archivo de contraseñas ocupado.\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Archivo de contraseñas no actualizado.\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Lo siento, las contraseñas no coinciden.\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Lo siento, se ha rechazado la contraseña.\n" +"Su contraseña debe tener al menos 6 caracteres, no puede contener\n" +"su nombre de usuario, y debe tener al menos una letra y un número.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Lo siento, las contraseñas no coinciden.\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: No se ha podido copiar la cadena de contraseña: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: No se ha podido abrir el archivo de contraseñas: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: No se ha podido escribir en el archivo de contraseñas: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" +"lppasswd: falló al hacer una copia de seguridad del antiguo archivo de " +"contraseñas: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: falló al cambiar de nombre al archivo de contraseñas: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: el usuario \"%s\" y el grupo \"%s\" no existen.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: error - Los nombre de variable de entorno %s no existen en el " +"destino \"%s\".\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "miembros de la clase %s:\n" + +msgid "no entries\n" +msgstr "no hay entradas\n" + +msgid "no system default destination\n" +msgstr "no hay un destino predeterminado del sistema\n" + +msgid "notify-events not specified!" +msgstr "notify-events no especificado." + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "El URI notify-recipient-uri \"%s\" ya está usado." + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "El URI notify-recipient-uri \"%s\" usa un esquema desconocido." + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d incorrecto." + +msgid "pending" +msgstr "pendiente" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Añadiendo directorio include \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Añadiendo/actualizando texto UI desde %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Valor lógico (%s) incorrecto en línea %d de %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Resolución de nombre \"%s\" incorrecta en línea %d de %s.\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Clave de estado %s incorrecta en línea %d de %s.\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Sustitución de variable ($%c) errónea en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Selección encontrada en línea %d de %s sin opciones.\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: #po duplicado para código regional %s en línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Se esperaba una definición de filtro en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre de programa en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Se esperaba un valor lógico en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba un juego de caracteres tras Font en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Se esperaba un código apropiado en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Se esperaba un nombre/texto apropiado en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba un orden de color para ColorModel en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Se esperaba colorspace para ColorModel en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Se esperaba compresión para ColorModel en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba una cadena de restricciones para UIConstraints en la línea " +"%d de %s.\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba una clave de tipo de controlador tras DriverType en la " +"línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Se esperaba un tipo dúplex tras Duplex en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Se esperaba una codificación tras Font en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba un nombre de archivo tras #po %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre/texto de grupo en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre de archivo include en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Se esperaba un número entero en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Se esperaba un código regional tras #po en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras FileName en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras Font en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras Manufacturer en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras MediaSize en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras ModelName en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre tras PCFileName en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Se esperaba un nombre/texto tras %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba un nombre/texto tras Installable en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba un nombre/texto tras Resolution en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba una combinación nombre/texto para ColorModel en la línea %" +"d de %s.\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Se esperaba una opción de nombre/texto en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Se esperaba una sección de opciones en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Se esperaba un tipo de opción en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: Se esperaba un campo de anulación tras Resolution en la línea %d de %" +"s.\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Se esperaba un número real en la línea %d de %s.\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Se esperaba resolución/tipo de soporte tras ColorProfile en la línea %" +"d de %s.\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Se esperaba resolución/tipo de soporte tras SimpleColorProfile en la " +"línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Se esperaba un selector tras %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Se esperaba un estado tras Font en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Se esperaba una cadena tras Copyright en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Se esperaba una cadena tras Version en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Se esperaban dos nombres de opciones en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Se esperaba un valor tras %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Se esperaba una versión tras Font en la línea %d de %s'.\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Nombre de fichero #include/#po incorrecto \"%s\".\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Coste incorrecto para el filtro en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "" +"ppdc: Tipo MIME vacío incorrecto para el filtro en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" +"ppdc: Nombre de programa vacío incorrecto para el filtro en la línea %d de %" +"s.\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Sección de opción incorrecta \"%s\" en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tipo de opción incorrecta \"%s\" en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Cargando archivo de información de controlador \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Cargando mensajes del idioma \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Cargando mensajes desde \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: Falta un #endif al final de \"%s\".\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: Falta un #if en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: No se ha proporcionado catálogo de mensajes para el idioma %s.\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" +"ppdc: Opción %s definida en dos diferentes grupos en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" +"ppdc: Opción %s redefinida con un tipo diferente en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Opción de restricción debe *name en línea %d de %s.\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Demasiados #if anidados en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: No se ha podido crear el archivo PPD \"%s\" - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: No se ha podido crear el directorio de salida %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: No se han podido crear canales (pipes) de salida: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: No se ha podido ejecutar cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "" +"ppdc: No se ha podido encontrar el archivo #po %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: No se ha podido encontrar el archivo include \"%s\" en la línea %d de %" +"s.\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: No se ha podido encontrar localización para \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: No se ha podido cargar el archivo de localización \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Variable no definida (%s) en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Tipo de controlador desconocido %s en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tipo dúplex desconocido \"%s\" en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tamaño de papel desconocido \"%s\" en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Elemento desconocido \"%s\" visto en la línea %d de %s.\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Caracteres finales desconocidos en el número real \"%s\" en la línea %" +"d de %s.\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Cadena que comienza por %c sin terminar en la línea %d de %s.\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Escribiendo %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Escribiendo archivos PPD al directorio \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: LanguageVersion \"%s\" incorrecto en %s.\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Ignorando archivo PPD %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: No se ha podido hacer copia de seguridad de %s a %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "la impresora %s está deshabilitada desde %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "la impresora %s está inactiva. activada desde %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "la impresora %s está imprimiendo %s-%d. activada desde %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "la impresora %s/%s está desactivada desde %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "la impresora %s/%s está inactiva. activada desde %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "la impresora %s/%s está imprimiendo %s-%d. activada desde %s\n" + +msgid "processing" +msgstr "en proceso" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "la id solicitada es %s-%d (%d archivo(s))\n" + +msgid "request-id uses indefinite length" +msgstr "request-id usa una longitud indefinida" + +msgid "scheduler is not running\n" +msgstr "el planificador de tareas no se está ejecutando\n" + +msgid "scheduler is running\n" +msgstr "el planificador de tareas se está ejecutando\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "estado de %s ha fallado: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tmuestra el estado del demonio y la cola\n" + +msgid "stopped" +msgstr "parada" + +#, c-format +msgid "system default destination: %s\n" +msgstr "destino predeterminado del sistema: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "destino predeterminado del sistema: %s/%s\n" + +msgid "unknown" +msgstr "desconocido" + +msgid "untitled" +msgstr "sin título" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings usa una longitud indefinida" + diff --git a/locale/cups_eu.po b/locale/cups_eu.po new file mode 100644 index 0000000000..aaf10dd553 --- /dev/null +++ b/locale/cups_eu.po @@ -0,0 +1,7282 @@ +# translation of cups_1.4rc1_eu.po to Basque +# +# "$Id$" +# +# Message catalog template for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 2005-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +# +# Notes for Translators: +# +# The following prefixes MUST NOT be translated: "ALERT:", "CRIT:", "INFO:", +# "NOTICE:", and "WARNING:". +# +# The "checkpo" program located in the "locale" source directory can be used +# to verify that your translations do not introduce formatting errors or other +# problems. Run with: +# +# cd locale +# ./checkpo cups_LL.po +# +# where "LL" is your locale. +# +# Iñaki Larrañaga Murgoitio , 2009. +msgid "" +msgstr "" +"Project-Id-Version: cups_1.4rc1_eu\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-05 14:00-0700\n" +"PO-Revision-Date: 2009-07-03 19:34+0200\n" +"Last-Translator: Iñaki Larrañaga Murgoitio \n" +"Language-Team: Basque \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: systemv/lpstat.c:1848 systemv/lpstat.c:1961 +msgid "\t\t(all)\n" +msgstr "\t\t(denak)\n" + +#: systemv/lpstat.c:1851 systemv/lpstat.c:1854 systemv/lpstat.c:1964 +#: systemv/lpstat.c:1967 +msgid "\t\t(none)\n" +msgstr "\t\t(bat ere ez)\n" + +#: berkeley/lpc.c:438 +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d sarrera\n" + +#: systemv/lpstat.c:1829 systemv/lpstat.c:1942 +msgid "\tAfter fault: continue\n" +msgstr "\tHutsegitearen ostean: jarraitu\n" + +#: systemv/lpstat.c:1461 systemv/lpstat.c:1795 systemv/lpstat.c:1908 +msgid "\tAlerts:" +msgstr "\tAlertak:" + +#: systemv/lpstat.c:1852 systemv/lpstat.c:1965 +msgid "\tBanner required\n" +msgstr "\tTitularra behar da\n" + +#: systemv/lpstat.c:1853 systemv/lpstat.c:1966 +msgid "\tCharset sets:\n" +msgstr "\tKaraktere-jokoa:\n" + +#: systemv/lpstat.c:1818 systemv/lpstat.c:1931 +msgid "\tConnection: direct\n" +msgstr "\tKonexioa: zuzena\n" + +#: systemv/lpstat.c:1809 systemv/lpstat.c:1922 +msgid "\tConnection: remote\n" +msgstr "\tKonexioa: urrunekoa\n" + +#: systemv/lpstat.c:1856 systemv/lpstat.c:1969 +msgid "\tDefault page size:\n" +msgstr "\tOrrialde-tamaina lehenetsia:\n" + +#: systemv/lpstat.c:1855 systemv/lpstat.c:1968 +msgid "\tDefault pitch:\n" +msgstr "\tTarte lehenetsia:\n" + +#: systemv/lpstat.c:1857 systemv/lpstat.c:1970 +msgid "\tDefault port settings:\n" +msgstr "\tAtakaren ezarpen lehenetsiak:\n" + +#: systemv/lpstat.c:1790 systemv/lpstat.c:1903 +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDeskripzioa: %s\n" + +#: systemv/lpstat.c:1784 systemv/lpstat.c:1897 +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tInprimakia muntatuta:\n" +"\tEduki mota: edozer\n" +"\tInprimagailu motak: ezezaguna\n" + +#: systemv/lpstat.c:1850 systemv/lpstat.c:1963 +msgid "\tForms allowed:\n" +msgstr "\tBaimendutako inprimakiak:\n" + +#: systemv/lpstat.c:1813 systemv/lpstat.c:1926 +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterfazea: %s.ppd\n" + +#: systemv/lpstat.c:1822 systemv/lpstat.c:1935 +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterfazea: %s/interfaces/%s\n" + +#: systemv/lpstat.c:1826 systemv/lpstat.c:1939 +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterfazea: %s/ppd/%s.ppd\n" + +#: systemv/lpstat.c:1804 systemv/lpstat.c:1917 +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tKokalekua: %s\n" + +#: systemv/lpstat.c:1828 systemv/lpstat.c:1941 +msgid "\tOn fault: no alert\n" +msgstr "\tHutsegitean: alertarik ez\n" + +#: systemv/lpstat.c:1833 systemv/lpstat.c:1847 systemv/lpstat.c:1946 +#: systemv/lpstat.c:1960 +msgid "\tUsers allowed:\n" +msgstr "\tBaimendutako erabiltzaileak:\n" + +#: systemv/lpstat.c:1840 systemv/lpstat.c:1953 +msgid "\tUsers denied:\n" +msgstr "\tUkatutako erabiltzaileak:\n" + +#: berkeley/lpc.c:440 +msgid "\tdaemon present\n" +msgstr "\tdaemona badago\n" + +#: berkeley/lpc.c:436 +msgid "\tno entries\n" +msgstr "\tsarrerarik ez\n" + +#: berkeley/lpc.c:408 berkeley/lpc.c:420 +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tinprimagailua '%s' gailuan dago abiadura -1\n" + +#: berkeley/lpc.c:433 +msgid "\tprinting is disabled\n" +msgstr "\tinprimatzea desgaituta dago\n" + +#: berkeley/lpc.c:431 +msgid "\tprinting is enabled\n" +msgstr "\tinprimatzea gaituta dago\n" + +#: systemv/lpstat.c:1467 +#, c-format +msgid "\tqueued for %s\n" +msgstr "\t%s(e)n ilaratuta\n" + +#: berkeley/lpc.c:428 +msgid "\tqueuing is disabled\n" +msgstr "\tilaratzea desgaituta\n" + +#: berkeley/lpc.c:426 +msgid "\tqueuing is enabled\n" +msgstr "\tilaratzea gaituta\n" + +#: systemv/lpstat.c:1777 systemv/lpstat.c:1890 +msgid "\treason unknown\n" +msgstr "\tarrazoi ezezaguna\n" + +#: systemv/cupstestppd.c:551 +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" ADOSTASUNAREN PROBAREN EMAITZ XEHETUA\n" + +#: systemv/cupstestppd.c:512 systemv/cupstestppd.c:516 +msgid " REF: Page 15, section 3.1.\n" +msgstr " Erref.: 15. orrialdea, 3.1 atala.\n" + +#: systemv/cupstestppd.c:508 +msgid " REF: Page 15, section 3.2.\n" +msgstr " Erref.: 15. orrialdea, 3.2 atala.\n" + +#: systemv/cupstestppd.c:524 +msgid " REF: Page 19, section 3.3.\n" +msgstr " Erref.: 19. orrialdea, 3.3 atala.\n" + +#: systemv/cupstestppd.c:486 +msgid " REF: Page 20, section 3.4.\n" +msgstr " Erref.: 20. orrialdea, 3.4 atala.\n" + +#: systemv/cupstestppd.c:528 +msgid " REF: Page 27, section 3.5.\n" +msgstr " Erref.: 27. orrialdea, 3.5 atala.\n" + +#: systemv/cupstestppd.c:482 +msgid " REF: Page 42, section 5.2.\n" +msgstr " Erref.: 42. orrialdea, 5.2 atala.\n" + +#: systemv/cupstestppd.c:520 +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " Erref.: 16-17 orrialdeak, 3.2 atala.\n" + +#: systemv/cupstestppd.c:496 +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " Erref.: 42-45 orrialdeak, 5.2 atala.\n" + +#: systemv/cupstestppd.c:491 +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " Erref.: 45-46 orrialdeak, 5.2 atala.\n" + +#: systemv/cupstestppd.c:500 +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " Erref.: 48-49 orrialdeak, 5.2 atala.\n" + +#: systemv/cupstestppd.c:504 +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " Erref.: 52-54 orrialdeak, 5.2 atala.\n" + +#: berkeley/lpq.c:546 +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f byte\n" + +#: systemv/cupstestppd.c:668 +#, c-format +msgid " PASS Default%s\n" +msgstr " BALIOZKOA Lehenetsia%s\n" + +#: systemv/cupstestppd.c:605 +msgid " PASS DefaultImageableArea\n" +msgstr " BALIOZKOA DefaultImageableArea\n" + +#: systemv/cupstestppd.c:639 +msgid " PASS DefaultPaperDimension\n" +msgstr " BALIOZKOA DefaultPaperDimension\n" + +#: systemv/cupstestppd.c:710 +msgid " PASS FileVersion\n" +msgstr " BALIOZKOA FileVersion\n" + +#: systemv/cupstestppd.c:754 +msgid " PASS FormatVersion\n" +msgstr " BALIOZKOA FormatVersion\n" + +#: systemv/cupstestppd.c:774 +msgid " PASS LanguageEncoding\n" +msgstr " BALIOZKOA LanguageEncoding\n" + +#: systemv/cupstestppd.c:794 +msgid " PASS LanguageVersion\n" +msgstr " BALIOZKOA LanguageVersion\n" + +#: systemv/cupstestppd.c:846 +msgid " PASS Manufacturer\n" +msgstr " BALIOZKOA Manufacturer\n" + +#: systemv/cupstestppd.c:886 +msgid " PASS ModelName\n" +msgstr " BALIOZKOA ModelName\n" + +#: systemv/cupstestppd.c:906 +msgid " PASS NickName\n" +msgstr " BALIOZKOA NickName\n" + +#: systemv/cupstestppd.c:966 +msgid " PASS PCFileName\n" +msgstr " BALIOZKOA PCFileName\n" + +#: systemv/cupstestppd.c:1041 +msgid " PASS PSVersion\n" +msgstr " BALIOZKOA PSVersion\n" + +#: systemv/cupstestppd.c:946 +msgid " PASS PageRegion\n" +msgstr " BALIOZKOA PageRegion\n" + +#: systemv/cupstestppd.c:926 +msgid " PASS PageSize\n" +msgstr " BALIOZKOA PageSize\n" + +#: systemv/cupstestppd.c:1001 +msgid " PASS Product\n" +msgstr " BALIOZKOA Product\n" + +#: systemv/cupstestppd.c:1076 +msgid " PASS ShortNickName\n" +msgstr " BALIOZKOA ShortNickName\n" + +#: systemv/cupstestppd.c:3416 +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" ABISUA \"%s %s\" gatazkan dago honekin: \"%s %s\"\n" +" (murriztapena=\"%s %s %s %s\")\n" + +#: systemv/cupstestppd.c:1449 +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " ABISUA %s(e)k ez dagozkion aukerak ditu.\n" + +#: systemv/cupstestppd.c:1557 +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" ABISUA %s(e)k aurrizki amankomuna partekatzen du %s(r)ekin\n" +" Erref: 15. orrialdea, 3.2 atala.\n" + +#: systemv/cupstestppd.c:1458 +msgid " WARN Default choices conflicting!\n" +msgstr " ABISUA Aukera lehenetsiak gatazkan.\n" + +#: systemv/cupstestppd.c:1420 +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" ABISUA Duplex aukeraren %s gakoak baliteke behar ez bezala " +"funtzionatzea eta Duplex izena eduki beharko luke.\n" +" Erref: 122. orrialdea, 5.17 atala\n" + +#: systemv/cupstestppd.c:1819 +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" ABISUA Fitxategiak nahastutako CR, LF eta CR-LF lerro amaierak " +"ditu.\n" + +#: systemv/cupstestppd.c:1474 +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" ABISUA PPD 4.3 zehaztapenak LanguageEncoding behar du.\n" +" Erref: 56-57 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1801 +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " ABISUA %d lerroak zuriuneak soilik ditu.\n" + +#: systemv/cupstestppd.c:1482 +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" ABISUA PPD 4.3 zehaztapenak Manufacturer behar du.\n" +" Erref: 58-59 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1824 +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" ABISUA Windows-ekoak ez diren PPD fitxategien lerroak LFrekin " +"amaitu beharko lukete, ez CR-LFrekin\n" + +#: systemv/cupstestppd.c:1466 +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" ABISUA PPDren %.1f bertsio zaharkitua.\n" +" Erref: 42. orrialdea, 5.2 atala.\n" + +#: systemv/cupstestppd.c:1495 +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" ABISUA PCFileName 8.3 baino luzeagoa da, eta PPD zehaztapenaren " +"bortxaketa da.\n" +" Erref: 61-62 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1529 +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" ABISUA Protokoloek PJL dute, baina JCL atributuak ez daude " +"ezarrita.\n" +" Erref: 78-79 orrialdeak, 5.7 atala.\n" + +#: systemv/cupstestppd.c:1520 +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" ABISUA Protokoloek bai PJL bai BCP dituzte, baina TBCP espero " +"zen.\n" +" Erref: 78-79 orrialdeak, 5.7 atala.\n" + +#: systemv/cupstestppd.c:1503 +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" ABISUA PPD 4.3 zehaztapenak ShortNickName behar du.\n" +" Erref: 64-65 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:2307 +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s ez da existitzen.\n" + +#: systemv/cupstestppd.c:3571 +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr " %s %s \"%s\" fitxategiak okerreko kapitalizazioa du.\n" + +#: systemv/cupstestppd.c:2377 +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Okerreko %s(r)en %s hautaketa.\n" +" Erref: 122. orrialdea, 5.17 atala.\n" + +#: systemv/cupstestppd.c:3131 +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Okerreko \"%s\" UTF-8 itzulpeneko katea %s aukerarentzako.\n" + +#: systemv/cupstestppd.c:3177 systemv/cupstestppd.c:3226 +#: systemv/cupstestppd.c:3265 +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Okerreko \"%s\" UTF-8 itzulpeneko katea %s aukerarentzako, %s " +"hautaketa.\n" + +#: systemv/cupstestppd.c:2429 +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Okerreko cupsFilter-en \"%s\" balioa\n" + +#: systemv/cupstestppd.c:2794 +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Okerreko %s cupsICCProfile.\n" + +#: systemv/cupstestppd.c:2500 +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Okerreko cupsPreFilter-ren \"%s\" balioa.\n" + +#: systemv/cupstestppd.c:1897 +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Okerreko %s cupsUIConstraints: \"%s\".\n" + +#: systemv/cupstestppd.c:3081 +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Okerreko \"%s\" hizkuntza\n" + +#: systemv/cupstestppd.c:2484 systemv/cupstestppd.c:2556 +#: systemv/cupstestppd.c:2594 systemv/cupstestppd.c:2632 +#: systemv/cupstestppd.c:2670 systemv/cupstestppd.c:2708 +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr " %s %s(r)en okerreko ortografia - %s izan beharko luke.\n" + +#: systemv/cupstestppd.c:2738 +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr " %s Ezin dira APScanAppPath eta APScanAppBundleID eman.\n" + +#: systemv/cupstestppd.c:1878 +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s %s cupsUIConstraints hutsa\n" + +#: systemv/cupstestppd.c:3117 +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s \"%s\" itzulpeneko katea falta da %s aukeran\n" + +#: systemv/cupstestppd.c:3209 systemv/cupstestppd.c:3249 +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s \"%s\" itzulpeneko katea falta da %s aukeran, %s hautaketa.\n" + +#: systemv/cupstestppd.c:2569 +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr " %s APDialogExtension-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:2607 +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr " %s APPrinterIconPath-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:2645 +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr " %s APPrinterLowInkTool-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:2683 +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr " %s APPrinterUtilityPath-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:2721 +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr " %s APScanAppPath-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:2926 +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" %s BEHARREZKOA DEN PageRegion aukera falta da.\n" +" Erref: 100. orrialdea, 5.14 atala.\n" + +#: systemv/cupstestppd.c:2911 +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" %s BEHARREZKOA DEN PageSize aukera falta da.\n" +" Erref: 99. orrialdea, 5.14 atala.\n" + +#: systemv/cupstestppd.c:2088 systemv/cupstestppd.c:2129 +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s *%s %s aukera falta da \"*%s %s *%s %s\" UIConstraints-en\n" + +#: systemv/cupstestppd.c:1983 +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s *%s %s aukera falta da %s cupsUIConstraints-en: \"%s\"\n" + +#: systemv/cupstestppd.c:2458 +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s cupsFilter-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:2828 +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s cupsICCProfile-en \"%s\" fitxategia falta da.\n" + +#: systemv/cupstestppd.c:2529 +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s cupsPreFilter-en \"%s\" fitxategia falta da\n" + +#: systemv/cupstestppd.c:1915 +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s %s cupsUIResolver falta da\n" + +#: systemv/cupstestppd.c:2074 systemv/cupstestppd.c:2115 +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s %s aukera falta da \"*%s %s *%s %s\" UIConstraints-en\n" + +#: systemv/cupstestppd.c:1967 +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s %s aukera falta da %s cupsUIConstraints-en: \"%s\"\n" + +#: systemv/cupstestppd.c:3303 +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Ez da oinarrizko \"%s\" itzulpena sartu fitxategian.\n" + +#: systemv/cupstestppd.c:2989 +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" +" %s Tamaina ez estandarra dauka \"%s\" izenak.\n" +" Erref: 187. orrialdea, B.2 atala.\n" + +#: systemv/cupstestppd.c:2353 +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s BEHARREZKOA DEN %s(e)k ez du 'Bat ere ez' aukera definitzen.\n" +" Erref: 122. orrialdea, 5.17 atala.\n" + +#: systemv/cupstestppd.c:3006 systemv/cupstestppd.c:3020 +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" +" %s \"%s\" tamaina definituta %s(r)entzako, baina ez honentzako: %s.\n" + +#: systemv/cupstestppd.c:2964 +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr " %s \"%s\" tamainak ustekabeko dimentsioak ditu (%gx%g).\n" + +#: systemv/cupstestppd.c:2856 +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr "" +" %s cupsICCProfile-ren %s hash balioak beste honekin talka egiten du: %" +"s\n" + +#: systemv/cupstestppd.c:2038 +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s %s cupsUIResolver-ek begizta sortzen du\n" + +#: systemv/cupstestppd.c:2020 +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" +" %s %s cupsUIResolver-ek ez du gutxienez bi aukera desberdin " +"zerrendatu.\n" + +#: systemv/cupstestppd.c:2238 +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **HUTSEGITEA** %s aukeraren %s eta %s izenak letren kapitalizazioan " +"soilik desberdintzen dira.\n" + +#: systemv/cupstestppd.c:1243 +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **HUTSEGITEA** %s 1284DeviceID izan behar du\n" +" Erref: 72. orrialdea, 5.5 atala.\n" + +#: systemv/cupstestppd.c:659 +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO Default%s %s\n" +" Erref: 40. orrialdea, 4.5 atala.\n" + +#: systemv/cupstestppd.c:595 +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO DefaultImageableArea %s.\n" +" Erref: 102. orrialdea, 5.15 atala.\n" + +#: systemv/cupstestppd.c:631 +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO DefaultPaperDimension %s.\n" +" Erref: 103. orrialdea, 5.15 atala.\n" + +#: systemv/cupstestppd.c:1102 +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO JobPatchFile atributua fitxategian\n" +" Erref: 24. orrialdea, 3.4 atala.\n" + +#: systemv/cupstestppd.c:822 +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO Manufacturer (\"HP\" izan beharko luke)\n" +" Erref: 211. orrialdea, D.1 taula.\n" + +#: systemv/cupstestppd.c:838 +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO Manufacturer (\"Oki\" izan beharko luke)\n" +" Erref: 211. orrialdea, D.1 taula.\n" + +#: systemv/cupstestppd.c:877 +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO ModelName - \"%c\" ez dago baimenduta " +"katean.\n" +" Erref: 59-60 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1033 +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO PSVersion - ez da \"(string) int\".\n" +" Erref: 62-64 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:994 +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO Product - ez da \"(string)\".\n" +" Erref: 62. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1068 +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** OKERREKO ShortNickName - 31 karaktere baino luzeagoa.\n" +" Erref: 64-65 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1224 +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **HUTSEGITEA** Okerreko %s %s aukera\n" +" Erref: 84. orrialdea, 5.9 atala.\n" + +#: systemv/cupstestppd.c:702 +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** Okerreko \"%s\" FileVersion\n" +" Erref: 56. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:746 +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** Okerreko \"%s\" FormatVersion\n" +" Erref: 56. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1288 +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **HUTSEGITEA** Okerreko %s LanguageEncoding - ISOLatin1 izan behar " +"du\n" + +#: systemv/cupstestppd.c:1302 +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **HUTSEGITEA** Okerreko %s LanguageVersion - Ingelesa izan behar du\n" + +#: systemv/cupstestppd.c:3443 systemv/cupstestppd.c:3465 +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **HUTSEGITEA** Aukera lehenetsiaren kodea ezin da interpretatu: %s\n" + +#: systemv/cupstestppd.c:1361 +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **HUTSEGITEA** %s aukeraren %s hautaketaren itzulpen-kate lehenetsiak " +"8 biteko karaktereak ditu.\n" + +#: systemv/cupstestppd.c:1334 +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **HUTSEGITEA** %s aukeraren itzulpen-kate lehenetsiak 8 biteko " +"karaktereak ditu.\n" + +#: systemv/cupstestppd.c:2176 +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **HUTSEGITEA** %s eta %s talde-izenak letren kapitalizazioan soilik " +"desberdintzen dira.\n" + +#: systemv/cupstestppd.c:2221 +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr "" +" **HUTSEGITEA** %s aukeraren %s izenaren hainbat agerraldi daude.\n" + +#: systemv/cupstestppd.c:2198 +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **HUTSEGITEA** %s eta %s aukeren izenak letra kapitalizatuetan soilik " +"desberdintzen dira.\n" + +#: systemv/cupstestppd.c:679 +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **HUTSEGITEA** Default%s BEHARREZKOA DA\n" +" Erref: 40. orrialdea, 4.5 atala.\n" + +#: systemv/cupstestppd.c:580 +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **HUTSEGITEA** DefaultImageableArea BEHARREZKOA DA\n" +" Erref: 102. orrialdea, 5.15 atala.\n" + +#: systemv/cupstestppd.c:616 +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **HUTSEGITEA** DefaultPaperDimension BEHARREZKOA DA\n" +" Erref: 103. orrialdea, 5.15 atala.\n" + +#: systemv/cupstestppd.c:720 +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** FileVersion BEHARREZKOA DA\n" +" Erref: 56. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:764 +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** FormatVersion BEHARREZKOA DA\n" +" Erref: 56. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1153 +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **HUTSEGITEA** ImageableArea BEHARREZKOA DA %s PageSize-rentzako\n" +" Erref: 41. orrialdea, 5 atala.\n" +" Erref: 102. orrialdea, 5.15 atala.\n" + +#: systemv/cupstestppd.c:784 +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** LanguageEncoding BEHARREZKOA DA\n" +" Erref: 56-57 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:804 +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** LanguageVersion BEHARREZKOA DA\n" +" Erref: 57-58 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:856 +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** Manufacturer BEHARREZKOA DA\n" +" Erref: 58-59 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:896 +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** ModelName BEHARREZKOA DA\n" +" Erref: 59-60 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:916 +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** NickName BEHARREZKOA DA\n" +" Erref: 60. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:976 +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** PCFileName BEHARREZKOA DA\n" +" Erref: 61-62 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1051 +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** PSVersion BEHARREZKOA DA\n" +" Erref: 62-64 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:956 +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **HUTSEGITEA** PageRegion BEHARREZKOA DA\n" +" Erref: 100. orrialdea, 5.14 atala.\n" + +#: systemv/cupstestppd.c:1122 +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **HUTSEGITEA** REQUIRED BEHARREZKOA DA\n" +"ageSize\n" +" Erref: EF. orrialdea: atalasection 5.\n" +" Erref: EF. orrialdea: sec atalation 5.14.\n" + +#: systemv/cupstestppd.c:936 +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **HUTSEGITEA** PageSize BEHARREZKOA DA\n" +" Erref: 99-100 orrialdeak, 5.14 atala.\n" + +#: systemv/cupstestppd.c:1175 +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **HUTSEGITEA** PaperDimension BEHARREZKOA DA %s PageSize-rentzako\n" +" Erref: 41. orrialdea, 5 atala.\n" +" Erref: 103. orrialdea, 5.15 atala.\n" + +#: systemv/cupstestppd.c:1011 +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** Product BEHARREZKOA DA\n" +" Erref: 62. orrialdea, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1086 +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **HUTSEGITEA** ShortNickName BEHARREZKOA DA\n" +" Erref: 64-65 orrialdeak, 5.3 atala.\n" + +#: systemv/cupstestppd.c:1569 +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERRORE AURKITU DIRA\n" + +#: systemv/cupstestdsc.c:238 systemv/cupstestdsc.c:280 +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Okerreko %%%%BoundingBox: %d lerroan\n" +" Erref: 39. orrialdea, %%%%BoundingBox:\n" + +#: systemv/cupstestdsc.c:309 +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Okerreko %%%%Page: %d lerroan\n" +" Erref: 53. orrialdea, %%%%Page:\n" + +#: systemv/cupstestdsc.c:222 systemv/cupstestdsc.c:262 +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Okerreko %%%%Pages: %d lerroan\n" +" Erref: 43. orrialdea, %%%%Pages:\n" + +#: systemv/cupstestdsc.c:180 +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" %d lerroa 255 karaktere baino luzeagoa da (%d)!\n" +" Erref: 25. orrialdea, lerroaren luzera\n" + +#: systemv/cupstestdsc.c:196 +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 falta da aurreneko lerroan\n" +" Erref: 17. orrialdea, 3.1 Adostasunaren dokumentuak\n" + +#: systemv/cupstestdsc.c:366 +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" %%EndComments iruzkina falta da\n" +" Erref: 41. orrialdea, %%EndComments\n" + +#: systemv/cupstestdsc.c:346 +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox okerrekoa edo falta da: iruzkina\n" +" Erref: 39. orrialdea, %%BoundingBox:\n" + +#: systemv/cupstestdsc.c:376 +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page okerrekoa edo falta da: iruzkinak\n" +" Erref: 53. orrialdea, %%Page:\n" + +#: systemv/cupstestdsc.c:356 +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages okerrekoa edo falta da: iruzkina\n" +" Erref: 43. orrialdea, %%Pages:\n" + +#: systemv/cupstestppd.c:1571 +msgid " NO ERRORS FOUND\n" +msgstr " EZ DA ERRORERIK AURKITU\n" + +#: systemv/cupstestdsc.c:399 +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " 255 karaktere baino luzeagoak diren %d lerro aurkitu dira\n" + +#: systemv/cupstestdsc.c:394 +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " %%BeginDocument iruzkin gehiegi\n" + +#: systemv/cupstestdsc.c:386 +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " %%EndDocument iruzkin gehiegi\n" + +#: systemv/cupstestdsc.c:406 +msgid " Warning: file contains binary data!\n" +msgstr " Abisua: fitxategiak datu bitarrak ditu\n" + +#: systemv/cupstestdsc.c:414 +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Abisua: ez dago %%EndComments iruzkinik fitxategian\n" + +#: systemv/cupstestdsc.c:410 +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Abisua: DSC %.1f bertsio zaharkitua fitxategian\n" + +#: systemv/cupstestppd.c:577 systemv/cupstestppd.c:592 +#: systemv/cupstestppd.c:613 systemv/cupstestppd.c:628 +#: systemv/cupstestppd.c:656 systemv/cupstestppd.c:676 +#: systemv/cupstestppd.c:699 systemv/cupstestppd.c:717 +#: systemv/cupstestppd.c:743 systemv/cupstestppd.c:761 +#: systemv/cupstestppd.c:781 systemv/cupstestppd.c:801 +#: systemv/cupstestppd.c:819 systemv/cupstestppd.c:835 +#: systemv/cupstestppd.c:853 systemv/cupstestppd.c:874 +#: systemv/cupstestppd.c:893 systemv/cupstestppd.c:913 +#: systemv/cupstestppd.c:933 systemv/cupstestppd.c:953 +#: systemv/cupstestppd.c:973 systemv/cupstestppd.c:991 +#: systemv/cupstestppd.c:1008 systemv/cupstestppd.c:1030 +#: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1065 +#: systemv/cupstestppd.c:1083 systemv/cupstestppd.c:1099 +#: systemv/cupstestppd.c:1119 systemv/cupstestppd.c:1150 +#: systemv/cupstestppd.c:1172 systemv/cupstestppd.c:1221 +#: systemv/cupstestppd.c:1240 systemv/cupstestppd.c:1284 +#: systemv/cupstestppd.c:1298 systemv/cupstestppd.c:1330 +#: systemv/cupstestppd.c:1357 systemv/cupstestppd.c:1875 +#: systemv/cupstestppd.c:1894 systemv/cupstestppd.c:1912 +#: systemv/cupstestppd.c:1964 systemv/cupstestppd.c:1980 +#: systemv/cupstestppd.c:2017 systemv/cupstestppd.c:2035 +#: systemv/cupstestppd.c:2071 systemv/cupstestppd.c:2085 +#: systemv/cupstestppd.c:2112 systemv/cupstestppd.c:2126 +#: systemv/cupstestppd.c:2172 systemv/cupstestppd.c:2194 +#: systemv/cupstestppd.c:2217 systemv/cupstestppd.c:2234 +#: systemv/cupstestppd.c:2303 systemv/cupstestppd.c:2350 +#: systemv/cupstestppd.c:2374 systemv/cupstestppd.c:2425 +#: systemv/cupstestppd.c:2455 systemv/cupstestppd.c:2480 +#: systemv/cupstestppd.c:2496 systemv/cupstestppd.c:2526 +#: systemv/cupstestppd.c:2552 systemv/cupstestppd.c:2566 +#: systemv/cupstestppd.c:2590 systemv/cupstestppd.c:2604 +#: systemv/cupstestppd.c:2628 systemv/cupstestppd.c:2642 +#: systemv/cupstestppd.c:2666 systemv/cupstestppd.c:2680 +#: systemv/cupstestppd.c:2704 systemv/cupstestppd.c:2718 +#: systemv/cupstestppd.c:2735 systemv/cupstestppd.c:2790 +#: systemv/cupstestppd.c:2825 systemv/cupstestppd.c:2852 +#: systemv/cupstestppd.c:2907 systemv/cupstestppd.c:2922 +#: systemv/cupstestppd.c:2960 systemv/cupstestppd.c:3002 +#: systemv/cupstestppd.c:3016 systemv/cupstestppd.c:3077 +#: systemv/cupstestppd.c:3113 systemv/cupstestppd.c:3127 +#: systemv/cupstestppd.c:3173 systemv/cupstestppd.c:3205 +#: systemv/cupstestppd.c:3222 systemv/cupstestppd.c:3245 +#: systemv/cupstestppd.c:3261 systemv/cupstestppd.c:3299 +#: systemv/cupstestppd.c:3439 systemv/cupstestppd.c:3461 +#: systemv/cupstestppd.c:3567 +msgid " FAIL\n" +msgstr " HUTSEGITEA\n" + +#: systemv/cupstestppd.c:462 +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" HUTSEGITEA\n" +" **HUTSEGITEA** Ezin da PPD fitxategia ireki - %s\n" + +#: systemv/cupstestppd.c:473 +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" HUTSEGITEA\n" +" **HUTSEGITEA** Ezin da PPD fitxategia ireki - %s %d lerroan.\n" + +#: systemv/cupstestppd.c:1381 +msgid " PASS\n" +msgstr " BALIOZKOA\n" + +#: ppdc/sample.c:51 +msgid "#10 Envelope" +msgstr "10. gutunazala" + +#: ppdc/sample.c:52 +msgid "#11 Envelope" +msgstr "11. gutunazala" + +#: ppdc/sample.c:53 +msgid "#12 Envelope" +msgstr "12. gutunazala" + +#: ppdc/sample.c:54 +msgid "#14 Envelope" +msgstr "14. gutunazala" + +#: ppdc/sample.c:55 +msgid "#9 Envelope" +msgstr "9. gutunazala" + +#: berkeley/lpq.c:552 +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f byte\n" + +#: berkeley/lpq.c:557 +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f byte\n" + +#: filter/bannertops.c:784 +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f milimetro" + +#: filter/bannertops.c:805 +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f -> %.0f x %.0f milimetro" + +#: filter/bannertops.c:775 +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f hatz" + +#: filter/bannertops.c:794 +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f -> %.2f x %.2f hatz" + +#: systemv/lpstat.c:754 +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s(e)k eskaerak onartzen ditu %s unetik\n" + +#: scheduler/ipp.c:10409 +#, c-format +msgid "%s cannot be changed." +msgstr "%s ezin da aldatu." + +#: berkeley/lpc.c:194 +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s ez dago CUPSen lpc bertsioan garatuta.\n" + +#: berkeley/lpq.c:643 +#, c-format +msgid "%s is not ready\n" +msgstr "%s ez dago prest\n" + +#: berkeley/lpq.c:636 +#, c-format +msgid "%s is ready\n" +msgstr "%s prest dago\n" + +#: berkeley/lpq.c:639 +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s prest dago eta inprimatzen\n" + +#: systemv/lpstat.c:757 +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s(e)k ez du eskaerarik onartzen %s unetik\n" +"\t%s\n" + +#: scheduler/ipp.c:701 +#, c-format +msgid "%s not supported!" +msgstr "%s ez dago onartuta." + +#: systemv/lpstat.c:767 +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s-(e)k eskaerak onartzen ditu %s unetik\n" + +#: systemv/lpstat.c:770 +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s-(e)k ez ditu eskaerarik onartzen %s unetik\n" +"\t%s\n" + +#: berkeley/lpq.c:544 +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [%d lana localhost]\n" + +#: systemv/cancel.c:303 systemv/cancel.c:367 +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s(e)k huts egin du: %s\n" + +#: systemv/cupsaccept.c:73 +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: ez daki zer egin.\n" + +#: berkeley/lpr.c:356 systemv/lp.c:603 +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: errorea - Inguruneko %s aldagaiak existitzen ez den \"%s\" helburua " +"izendatzen du\n" + +#: systemv/lp.c:240 +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: errorea - lanaren okerreko IDa\n" + +#: systemv/lp.c:227 +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: errorea - ezin dira fitxategiak inprimatu eta aldi berean lanak aldatu\n" + +#: systemv/lp.c:523 +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: errorea - ezin da stdin-etik inprimatu fitxategiak edo lan baten IDa " +"ematen bada\n" + +#: systemv/lp.c:477 +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: errorea - '-S' aukeraren ondoren karaktere-jokoa espero zen\n" + +#: systemv/lp.c:497 +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: errorea - '-T' aukeraren ondoren eduki mota espero zen\n" + +#: systemv/lp.c:273 +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: errorea - '-n' aukeraren ondoren kopiak espero ziren\n" + +#: berkeley/lpr.c:251 +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: errorea - '-#' aukeraren ondoren kopien zenbatzailea espero zen\n" + +#: berkeley/lpr.c:219 +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: errorea - '-P' aukeraren ondoren helburua espero zen\n" + +#: systemv/lpstat.c:238 +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: errorea - '-b' aukeraren ondoren helburua espero zen\n" + +#: systemv/lp.c:145 +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: errorea - '-d' aukeraren ondoren helburua espero zen\n" + +#: systemv/lp.c:175 +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: errorea - '-f' aukeraren ondoren inprimakia espero zen\n" + +#: systemv/lp.c:404 +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: errorea - '-H' aukeraren ondoren eusteko izena espero zen\n" + +#: berkeley/lpr.c:111 +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: errorea - '-H' aukeraren ondoren ostalari-izena espero zen\n" + +#: berkeley/lpq.c:188 berkeley/lprm.c:130 systemv/cancel.c:130 +#: systemv/cupsaccept.c:131 systemv/lp.c:196 systemv/lpstat.c:298 +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: errorea - '-h' aukeraren ondoren ostalari-izena espero zen\n" + +#: systemv/lp.c:382 +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: errorea - '-y' aukeraren ondoren moduen zerrenda espero zen\n" + +#: berkeley/lpr.c:275 +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: errorea - '-%c' aukeraren ondoren izena espero zen\n" + +#: systemv/lp.c:296 +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: errorea - '-o' aukeraren ondoren aukera-katea espero zen\n" + +#: systemv/lp.c:456 +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: errorea - '-P' aukeraren ondoren orrialdeen zerrenda espero zen\n" + +#: systemv/lp.c:317 +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: errorea - '-%c' aukeraren ondoren lehentasuna espero zen\n" + +#: systemv/cupsaccept.c:150 +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: errorea - '-r' aukeraren ondoren arrazoiaren testua espero zen\n" + +#: systemv/lp.c:364 +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: errorea - '-t' aukeraren ondoren titulua espero zen\n" + +#: berkeley/lpq.c:117 berkeley/lpr.c:91 berkeley/lprm.c:110 +#: systemv/cancel.c:99 systemv/cupsaccept.c:108 systemv/lp.c:122 +#: systemv/lpadmin.c:471 systemv/lpstat.c:144 +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: errorea - '-U' aukeraren ondoren erabiltzaile-izena espero zen\n" + +#: systemv/cancel.c:152 +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: errorea - '-u' aukeraren ondoren erabiltzaile-izena espero zen\n" + +#: berkeley/lpr.c:134 +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: errorea - '-%c' aukeraren ondoren balio bat espero zen\n" + +#: systemv/lpstat.c:164 systemv/lpstat.c:178 +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: errorea - '-W' aukeraren ondoren \"completed\", \"not-completed\", edo " +"\"all\" egon behar du\n" + +#: berkeley/lpr.c:361 systemv/lp.c:608 +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: errorea - helburu lehenetsia ez dago eskuragarri\n" + +#: systemv/lp.c:340 +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: errorea - lehentasuna 1 eta 100 artean egon behar du\n" + +#: berkeley/lpr.c:365 systemv/lp.c:612 +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: errorea - antolatzaileak ez du erantzuten\n" + +#: berkeley/lpr.c:317 systemv/lp.c:556 +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: errorea - fitxategi gehiegi - \"%s\"\n" + +#: berkeley/lpr.c:299 systemv/lp.c:539 +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: errorea - ezin da \"%s\" atzitu - %s\n" + +#: berkeley/lpr.c:410 systemv/lp.c:645 +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: errorea - ezin da stdin-etik ilaratu - %s\n" + +#: berkeley/lprm.c:93 berkeley/lprm.c:182 systemv/cancel.c:222 +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: errorea - \"%s\" helburu ezezaguna\n" + +#: berkeley/lpq.c:157 +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: errorea - \"%s/%s\" helburu ezezaguna\n" + +#: berkeley/lpr.c:286 berkeley/lprm.c:148 systemv/cancel.c:164 +#: systemv/cupsaccept.c:174 systemv/lp.c:514 systemv/lpstat.c:459 +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: errorea - '%c' aukera ezezaguna\n" + +#: systemv/cupsaccept.c:167 +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: errorea - '%s' aukera ezezaguna\n" + +#: systemv/lp.c:216 +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: '-i' aukeraren ondoren lanaren IDa espero zen\n" + +#: scheduler/cupsfilter.c:558 +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: \"%s\" iragazkia ez dago erabilgarri: %s\n" + +#: systemv/lpstat.c:511 systemv/lpstat.c:550 +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: helburuaren izen baliogabea \"%s\" zerrendan\n" + +#: scheduler/cupsfilter.c:539 +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: \"%s\" iragazkiaren kate baliogabea\n" + +#: systemv/lp.c:432 +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: lanaren IDa ('-i lanIDa') behar da '-H restart'-en aurretik\n" + +#: scheduler/cupsfilter.c:453 +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: ez dago iragazkirik %s/%s -> %s/%s bihurtzeko\n" + +#: systemv/cupsaccept.c:208 +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: huts egin du eragiketak: %s\n" + +#: berkeley/lpq.c:103 berkeley/lpr.c:77 berkeley/lprm.c:72 systemv/cancel.c:85 +#: systemv/cupsaccept.c:94 systemv/cupsaddsmb.c:91 systemv/lp.c:108 +#: systemv/lpadmin.c:277 systemv/lpinfo.c:94 systemv/lpmove.c:79 +#: systemv/lpstat.c:109 +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: ez da enkriptatzeko euskarriarekin konpilatu\n" + +#: berkeley/lpq.c:304 scheduler/cupsfilter.c:1093 systemv/cupsaddsmb.c:149 +#: systemv/cupsaddsmb.c:175 +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: ezin da zerbitzariarekin konektatu\n" + +#: systemv/cancel.c:245 systemv/cancel.c:326 +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: ezin da zerbitzariarekin kontaktatu\n" + +#: scheduler/cupsfilter.c:419 +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: ezin da \"%s\"(r)en MIME mota zehaztu\n" + +#: ppdc/ppdc-file.cxx:50 ppdc/ppdmerge.cxx:99 +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: ezin da %s ireki: %s\n" + +#: scheduler/cupsfilter.c:603 +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: ezin da PPD fitxategia ireki: %s %d lerroan\n" + +#: ppdc/ppdmerge.cxx:113 +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "%s: ezin da PPD fitxategia ireki: %s %d lerroan\n" + +#: scheduler/cupsfilter.c:384 +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: ezin da MIMEen datu-basea irakurri \"%s\" edo \"%s\"(e)ndik\n" + +#: berkeley/lpq.c:161 systemv/lpstat.c:565 +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: \"%s\" helburu ezezaguna\n" + +#: scheduler/cupsfilter.c:430 +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: %s/%s MIME motaren helburu ezezaguna\n" + +#: scheduler/cupsfilter.c:1299 +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: '%c' aukera ezezaguna\n" + +#: scheduler/cupsfilter.c:411 +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: %s/%s MIME moten iturburu ezeaguna\n" + +#: berkeley/lpr.c:148 +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: abisua - '%c' formatuaren eraldatzailea ez dago onartuta - irteera ez da " +"zuzena izango\n" + +#: systemv/lp.c:485 +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: abisua - karaktere-jokoaren aukerari ezikusi egin zaio\n" + +#: systemv/lp.c:505 +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: abisua - edukiaren motaren aukerari ezikusi egin zaio\n" + +#: systemv/lp.c:182 +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: abisua - inprimakiaren aukerari ezikusi egin zaio\n" + +#: systemv/lp.c:390 +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: abisua - moduen aukerari ezikusi egin zaio\n" + +#: berkeley/lpq.c:245 +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: errorea - inguruneko %s aldagaiak existitzen ez den \"%s\" helburua " +"izandatzen du\n" + +#: berkeley/lpr.c:162 +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: errorea - '-o' aukeraren ondoren aukera=balioa espero zen\n" + +#: berkeley/lpq.c:250 +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: errorea - helburu lehenetsia ez dago eskuragarri\n" + +#: ppdc/sample.c:281 +msgid "-1" +msgstr "-1" + +#: ppdc/sample.c:272 +msgid "-10" +msgstr "-10" + +#: ppdc/sample.c:364 +msgid "-100" +msgstr "-100" + +#: ppdc/sample.c:363 +msgid "-105" +msgstr "-105" + +#: ppdc/sample.c:271 +msgid "-11" +msgstr "-11" + +#: ppdc/sample.c:362 +msgid "-110" +msgstr "-110" + +#: ppdc/sample.c:361 +msgid "-115" +msgstr "-115" + +#: ppdc/sample.c:270 +msgid "-12" +msgstr "-12" + +#: ppdc/sample.c:360 +msgid "-120" +msgstr "-120" + +#: ppdc/sample.c:269 +msgid "-13" +msgstr "-13" + +#: ppdc/sample.c:268 +msgid "-14" +msgstr "-14" + +#: ppdc/sample.c:267 +msgid "-15" +msgstr "-15" + +#: ppdc/sample.c:280 +msgid "-2" +msgstr "-2" + +#: ppdc/sample.c:380 +msgid "-20" +msgstr "-20" + +#: ppdc/sample.c:379 +msgid "-25" +msgstr "-25" + +#: ppdc/sample.c:279 +msgid "-3" +msgstr "-3" + +#: ppdc/sample.c:378 +msgid "-30" +msgstr "-30" + +#: ppdc/sample.c:377 +msgid "-35" +msgstr "-35" + +#: ppdc/sample.c:278 +msgid "-4" +msgstr "-4" + +#: ppdc/sample.c:376 +msgid "-40" +msgstr "-40" + +#: ppdc/sample.c:375 +msgid "-45" +msgstr "-45" + +#: ppdc/sample.c:277 +msgid "-5" +msgstr "-5" + +#: ppdc/sample.c:374 +msgid "-50" +msgstr "-50" + +#: ppdc/sample.c:373 +msgid "-55" +msgstr "-55" + +#: ppdc/sample.c:276 +msgid "-6" +msgstr "-6" + +#: ppdc/sample.c:372 +msgid "-60" +msgstr "-60" + +#: ppdc/sample.c:371 +msgid "-65" +msgstr "-65" + +#: ppdc/sample.c:275 +msgid "-7" +msgstr "-7" + +#: ppdc/sample.c:370 +msgid "-70" +msgstr "-70" + +#: ppdc/sample.c:369 +msgid "-75" +msgstr "-75" + +#: ppdc/sample.c:274 +msgid "-8" +msgstr "-8" + +#: ppdc/sample.c:368 +msgid "-80" +msgstr "-80" + +#: ppdc/sample.c:367 +msgid "-85" +msgstr "-85" + +#: ppdc/sample.c:273 +msgid "-9" +msgstr "-9" + +#: ppdc/sample.c:366 +msgid "-90" +msgstr "-90" + +#: ppdc/sample.c:365 +msgid "-95" +msgstr "-95" + +#: ppdc/sample.c:282 +msgid "0" +msgstr "0" + +#: ppdc/sample.c:283 +msgid "1" +msgstr "1" + +#: ppdc/sample.c:355 +msgid "1 inch/sec." +msgstr "1 hazt/seg" + +#: ppdc/sample.c:144 +msgid "1.25x0.25\"" +msgstr "1.25x0.25\"" + +#: ppdc/sample.c:145 +msgid "1.25x2.25\"" +msgstr "1.25x2.25\"" + +#: ppdc/sample.c:403 +msgid "1.5 inch/sec." +msgstr "1.5 hatz/seg" + +#: ppdc/sample.c:146 +msgid "1.50x0.25\"" +msgstr "1.50x0.25\"" + +#: ppdc/sample.c:147 +msgid "1.50x0.50\"" +msgstr "1.50x0.50\"" + +#: ppdc/sample.c:148 +msgid "1.50x1.00\"" +msgstr "1.50x1.00\"" + +#: ppdc/sample.c:149 +msgid "1.50x2.00\"" +msgstr "1.50x2.00\"" + +#: ppdc/sample.c:292 +msgid "10" +msgstr "10" + +#: ppdc/sample.c:414 +msgid "10 inches/sec." +msgstr "10 hatz/seg" + +#: ppdc/sample.c:1 +msgid "10 x 11\"" +msgstr "10 x 11\"" + +#: ppdc/sample.c:2 +msgid "10 x 13\"" +msgstr "10 x 13\"" + +#: ppdc/sample.c:3 +msgid "10 x 14\"" +msgstr "10 x 14\"" + +#: ppdc/sample.c:394 +msgid "100" +msgstr "100" + +#: ppdc/sample.c:305 +msgid "100 mm/sec." +msgstr "100 mm/seg" + +#: ppdc/sample.c:395 +msgid "105" +msgstr "105" + +#: ppdc/sample.c:293 +msgid "11" +msgstr "11" + +#: ppdc/sample.c:415 +msgid "11 inches/sec." +msgstr "11 hatz/seg" + +#: ppdc/sample.c:396 +msgid "110" +msgstr "110" + +#: ppdc/sample.c:397 +msgid "115" +msgstr "115" + +#: ppdc/sample.c:294 +msgid "12" +msgstr "12" + +#: ppdc/sample.c:416 +msgid "12 inches/sec." +msgstr "12 hatz/seg" + +#: ppdc/sample.c:4 +msgid "12 x 11\"" +msgstr "12 x 11\"" + +#: ppdc/sample.c:398 +msgid "120" +msgstr "120" + +#: ppdc/sample.c:306 +msgid "120 mm/sec." +msgstr "120 mm/seg" + +#: ppdc/sample.c:215 +msgid "120x60dpi" +msgstr "120x60dpi" + +#: ppdc/sample.c:221 +msgid "120x72dpi" +msgstr "120x72dpi" + +#: ppdc/sample.c:295 +msgid "13" +msgstr "13" + +#: ppdc/sample.c:204 +msgid "136dpi" +msgstr "136dpi" + +#: ppdc/sample.c:296 +msgid "14" +msgstr "14" + +#: ppdc/sample.c:297 +msgid "15" +msgstr "15" + +#: ppdc/sample.c:299 +msgid "15 mm/sec." +msgstr "15 mm/seg" + +#: ppdc/sample.c:5 +msgid "15 x 11\"" +msgstr "15 x 11\"" + +#: ppdc/sample.c:307 +msgid "150 mm/sec." +msgstr "150 mm/seg" + +#: ppdc/sample.c:254 +msgid "150dpi" +msgstr "150dpi" + +#: ppdc/sample.c:339 +msgid "16" +msgstr "16" + +#: ppdc/sample.c:340 +msgid "17" +msgstr "17" + +#: ppdc/sample.c:341 +msgid "18" +msgstr "18" + +#: ppdc/sample.c:216 +msgid "180dpi" +msgstr "180dpi" + +#: ppdc/sample.c:342 +msgid "19" +msgstr "19" + +#: ppdc/sample.c:284 +msgid "2" +msgstr "2" + +#: ppdc/sample.c:356 +msgid "2 inches/sec." +msgstr "2 hatz/seg" + +#: ppdc/sample.c:242 +msgid "2-Sided Printing" +msgstr "2 alboetatik inprimatzea" + +#: ppdc/sample.c:150 +msgid "2.00x0.37\"" +msgstr "2.00x0.37\"" + +#: ppdc/sample.c:151 +msgid "2.00x0.50\"" +msgstr "2.00x0.50\"" + +#: ppdc/sample.c:152 +msgid "2.00x1.00\"" +msgstr "2.00x1.00\"" + +#: ppdc/sample.c:153 +msgid "2.00x1.25\"" +msgstr "2.00x1.25\"" + +#: ppdc/sample.c:154 +msgid "2.00x2.00\"" +msgstr "2.00x2.00\"" + +#: ppdc/sample.c:155 +msgid "2.00x3.00\"" +msgstr "2.00x3.00\"" + +#: ppdc/sample.c:156 +msgid "2.00x4.00\"" +msgstr "2.00x4.00\"" + +#: ppdc/sample.c:157 +msgid "2.00x5.50\"" +msgstr "2.00x5.50\"" + +#: ppdc/sample.c:158 +msgid "2.25x0.50\"" +msgstr "2.25x0.50\"" + +#: ppdc/sample.c:159 +msgid "2.25x1.25\"" +msgstr "2.25x1.25\"" + +#: ppdc/sample.c:160 +msgid "2.25x4.00\"" +msgstr "2.25x4.00\"" + +#: ppdc/sample.c:161 +msgid "2.25x5.50\"" +msgstr "2.25x5.50\"" + +#: ppdc/sample.c:162 +msgid "2.38x5.50\"" +msgstr "2.38x5.50\"" + +#: ppdc/sample.c:404 +msgid "2.5 inches/sec." +msgstr "2.hatz/seg" + +#: ppdc/sample.c:163 +msgid "2.50x1.00\"" +msgstr "2.50x1.00\"" + +#: ppdc/sample.c:164 +msgid "2.50x2.00\"" +msgstr "2.50x2.00\"" + +#: ppdc/sample.c:165 +msgid "2.75x1.25\"" +msgstr "2.75x1.25\"" + +#: ppdc/sample.c:166 +msgid "2.9 x 1\"" +msgstr "2.9 x 1\"" + +#: ppdc/sample.c:343 +msgid "20" +msgstr "20" + +#: ppdc/sample.c:300 +msgid "20 mm/sec." +msgstr "20 mm/seg" + +#: ppdc/sample.c:308 +msgid "200 mm/sec." +msgstr "200 mm/seg" + +#: ppdc/sample.c:205 +msgid "203dpi" +msgstr "203dpi" + +#: ppdc/sample.c:344 +msgid "21" +msgstr "21" + +#: ppdc/sample.c:345 +msgid "22" +msgstr "22" + +#: ppdc/sample.c:346 +msgid "23" +msgstr "23" + +#: ppdc/sample.c:347 +msgid "24" +msgstr "24" + +#: ppdc/sample.c:213 +msgid "24-Pin Series" +msgstr "24 orrratzeko serieak" + +#: ppdc/sample.c:222 +msgid "240x72dpi" +msgstr "240x72dpi" + +#: ppdc/sample.c:348 +msgid "25" +msgstr "25" + +#: ppdc/sample.c:309 +msgid "250 mm/sec." +msgstr "250 mm/seg" + +#: ppdc/sample.c:349 +msgid "26" +msgstr "26" + +#: ppdc/sample.c:350 +msgid "27" +msgstr "27" + +#: ppdc/sample.c:351 +msgid "28" +msgstr "28" + +#: ppdc/sample.c:352 +msgid "29" +msgstr "29" + +#: ppdc/sample.c:285 +msgid "3" +msgstr "3" + +#: ppdc/sample.c:357 +msgid "3 inches/sec." +msgstr "3 hatz/seg" + +#: ppdc/sample.c:167 +msgid "3.00x1.00\"" +msgstr "3.00x1.00\"" + +#: ppdc/sample.c:168 +msgid "3.00x1.25\"" +msgstr "3.00x1.25\"" + +#: ppdc/sample.c:169 +msgid "3.00x2.00\"" +msgstr "3.00x2.00\"" + +#: ppdc/sample.c:170 +msgid "3.00x3.00\"" +msgstr "3.00x3.00\"" + +#: ppdc/sample.c:171 +msgid "3.00x5.00\"" +msgstr "3.00x5.00\"" + +#: ppdc/sample.c:172 +msgid "3.25x2.00\"" +msgstr "3.25x2.00\"" + +#: ppdc/sample.c:173 +msgid "3.25x5.00\"" +msgstr "3.25x5.00\"" + +#: ppdc/sample.c:174 +msgid "3.25x5.50\"" +msgstr "3.25x5.50\"" + +#: ppdc/sample.c:175 +msgid "3.25x5.83\"" +msgstr "3.25x5.83\"" + +#: ppdc/sample.c:176 +msgid "3.25x7.83\"" +msgstr "3.25x7.83\"" + +#: ppdc/sample.c:134 +msgid "3.5\" Disk" +msgstr "3.5\" diskoa" + +#: ppdc/sample.c:143 +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3.5\" diskoa - 2 1/8 x 2 3/4\"" + +#: ppdc/sample.c:177 +msgid "3.50x1.00\"" +msgstr "3.50x1.00\"" + +#: ppdc/sample.c:353 +msgid "30" +msgstr "30" + +#: ppdc/sample.c:301 +msgid "30 mm/sec." +msgstr "30 mm/seg" + +#: ppdc/sample.c:310 +msgid "300 mm/sec." +msgstr "300 mm/seg" + +#: ppdc/sample.c:206 +msgid "300dpi" +msgstr "300dpi" + +#: ppdc/sample.c:381 +msgid "35" +msgstr "35" + +#: ppdc/sample.c:218 +msgid "360dpi" +msgstr "360dpi" + +#: ppdc/sample.c:217 +msgid "360x180dpi" +msgstr "360x180dpi" + +#: ppdc/sample.c:286 +msgid "4" +msgstr "4" + +#: ppdc/sample.c:358 +msgid "4 inches/sec." +msgstr "4 hatz/seg" + +#: ppdc/sample.c:178 +msgid "4.00x1.00\"" +msgstr "4.00x1.00\"" + +#: ppdc/sample.c:186 +msgid "4.00x13.00\"" +msgstr "4.00x13.00\"" + +#: ppdc/sample.c:179 +msgid "4.00x2.00\"" +msgstr "4.00x2.00\"" + +#: ppdc/sample.c:180 +msgid "4.00x2.50\"" +msgstr "4.00x2.50\"" + +#: ppdc/sample.c:181 +msgid "4.00x3.00\"" +msgstr "4.00x3.00\"" + +#: ppdc/sample.c:182 +msgid "4.00x4.00\"" +msgstr "4.00x4.00\"" + +#: ppdc/sample.c:183 +msgid "4.00x5.00\"" +msgstr "4.00x5.00\"" + +#: ppdc/sample.c:184 +msgid "4.00x6.00\"" +msgstr "4.00x6.00\"" + +#: ppdc/sample.c:185 +msgid "4.00x6.50\"" +msgstr "4.00x6.50\"" + +#: ppdc/sample.c:382 +msgid "40" +msgstr "40" + +#: ppdc/sample.c:302 +msgid "40 mm/sec." +msgstr "40 mm/seg" + +#: ppdc/sample.c:383 +msgid "45" +msgstr "45" + +#: ppdc/sample.c:287 +msgid "5" +msgstr "5" + +#: ppdc/sample.c:408 +msgid "5 inches/sec." +msgstr "5 hatz/seg" + +#: ppdc/sample.c:384 +msgid "50" +msgstr "50" + +#: ppdc/sample.c:385 +msgid "55" +msgstr "55" + +#: ppdc/sample.c:288 +msgid "6" +msgstr "6" + +#: ppdc/sample.c:409 +msgid "6 inches/sec." +msgstr "6 hatz/seg" + +#: ppdc/sample.c:187 +msgid "6.00x1.00\"" +msgstr "6.00x1.00\"" + +#: ppdc/sample.c:188 +msgid "6.00x2.00\"" +msgstr "6.00x2.00\"" + +#: ppdc/sample.c:189 +msgid "6.00x3.00\"" +msgstr "6.00x3.00\"" + +#: ppdc/sample.c:190 +msgid "6.00x4.00\"" +msgstr "6.00x4.00\"" + +#: ppdc/sample.c:191 +msgid "6.00x5.00\"" +msgstr "6.00x5.00\"" + +#: ppdc/sample.c:192 +msgid "6.00x6.00\"" +msgstr "6.00x6.00\"" + +#: ppdc/sample.c:193 +msgid "6.00x6.50\"" +msgstr "6.00x6.50\"" + +#: ppdc/sample.c:386 +msgid "60" +msgstr "60" + +#: ppdc/sample.c:303 +msgid "60 mm/sec." +msgstr "60 mm/seg" + +#: ppdc/sample.c:233 +msgid "600dpi" +msgstr "600dpi" + +#: ppdc/sample.c:214 +msgid "60dpi" +msgstr "60dpi" + +#: ppdc/sample.c:220 +msgid "60x720dpi" +msgstr "60x720dpi" + +#: ppdc/sample.c:387 +msgid "65" +msgstr "65" + +#: ppdc/sample.c:289 +msgid "7" +msgstr "7" + +#: ppdc/sample.c:411 +msgid "7 inches/sec." +msgstr "7 hatz/seg" + +#: ppdc/sample.c:6 +msgid "7 x 9\"" +msgstr "7 x 9\"" + +#: ppdc/sample.c:388 +msgid "70" +msgstr "70" + +#: ppdc/sample.c:224 +msgid "720dpi" +msgstr "720dpi" + +#: ppdc/sample.c:389 +msgid "75" +msgstr "75" + +#: ppdc/sample.c:290 +msgid "8" +msgstr "8" + +#: ppdc/sample.c:412 +msgid "8 inches/sec." +msgstr "8 hatz/seg" + +#: ppdc/sample.c:7 +msgid "8 x 10\"" +msgstr "8 x 10\"" + +#: ppdc/sample.c:194 +msgid "8.00x1.00\"" +msgstr "8.00x1.00\"" + +#: ppdc/sample.c:195 +msgid "8.00x2.00\"" +msgstr "8.00x2.00\"" + +#: ppdc/sample.c:196 +msgid "8.00x3.00\"" +msgstr "8.00x3.00\"" + +#: ppdc/sample.c:197 +msgid "8.00x4.00\"" +msgstr "8.00x4.00\"" + +#: ppdc/sample.c:198 +msgid "8.00x5.00\"" +msgstr "8.00x5.00\"" + +#: ppdc/sample.c:199 +msgid "8.00x6.00\"" +msgstr "8.00x6.00\"" + +#: ppdc/sample.c:200 +msgid "8.00x6.50\"" +msgstr "8.00x6.50\"" + +#: ppdc/sample.c:390 +msgid "80" +msgstr "80" + +#: ppdc/sample.c:304 +msgid "80 mm/sec." +msgstr "80 mm/seg" + +#: ppdc/sample.c:391 +msgid "85" +msgstr "85" + +#: ppdc/sample.c:291 +msgid "9" +msgstr "9" + +#: ppdc/sample.c:413 +msgid "9 inches/sec." +msgstr "9 hatz/seg" + +#: ppdc/sample.c:8 +msgid "9 x 11\"" +msgstr "9 x 11\"" + +#: ppdc/sample.c:9 +msgid "9 x 12\"" +msgstr "9 x 12\"" + +#: ppdc/sample.c:219 +msgid "9-Pin Series" +msgstr "9 orratzeko serieak" + +#: ppdc/sample.c:392 +msgid "90" +msgstr "90" + +#: ppdc/sample.c:393 +msgid "95" +msgstr "95" + +#: berkeley/lpc.c:218 +msgid "?Invalid help command unknown\n" +msgstr "? laguntzako komando ezezagun baliogabea\n" + +#: cgi-bin/admin.c:2337 +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"Samba-ko pasahitza behar da inprimagailuaren kontrolatzaileak esportatzeko." + +#: cgi-bin/admin.c:2333 +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Samba-ko erabiltzaile-izena behar da inprimagailuaren kontrolatzaileak " +"esportatzeko." + +#: scheduler/ipp.c:2384 +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "\"%s\" izeneko klasea badago lehendik ere." + +#: scheduler/ipp.c:1013 +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "\"%s\" izeneko inprimagailua badago lehendik ere." + +#: ppdc/sample.c:10 +msgid "A0" +msgstr "A0" + +#: ppdc/sample.c:11 +msgid "A1" +msgstr "A1" + +#: ppdc/sample.c:24 +msgid "A10" +msgstr "A10" + +#: ppdc/sample.c:12 +msgid "A2" +msgstr "A2" + +#: ppdc/sample.c:13 +msgid "A3" +msgstr "A3" + +#: ppdc/sample.c:14 +msgid "A3 (Oversize)" +msgstr "A3 (handiagoa)" + +#: ppdc/sample.c:15 +msgid "A4" +msgstr "A4" + +#: ppdc/sample.c:16 +msgid "A4 (Oversize)" +msgstr "A4 (handiagoa)" + +#: ppdc/sample.c:17 +msgid "A4 (Small)" +msgstr "A4 (txikia)" + +#: ppdc/sample.c:18 +msgid "A5" +msgstr "A5" + +#: ppdc/sample.c:19 +msgid "A5 (Oversize)" +msgstr "A5 (handiagoa)" + +#: ppdc/sample.c:20 +msgid "A6" +msgstr "A6" + +#: ppdc/sample.c:21 +msgid "A7" +msgstr "A7" + +#: ppdc/sample.c:22 +msgid "A8" +msgstr "A8" + +#: ppdc/sample.c:23 +msgid "A9" +msgstr "A9" + +#: ppdc/sample.c:25 +msgid "ANSI A" +msgstr "ANSI A" + +#: ppdc/sample.c:26 +msgid "ANSI B" +msgstr "ANSI B" + +#: ppdc/sample.c:27 +msgid "ANSI C" +msgstr "ANSI C" + +#: ppdc/sample.c:28 +msgid "ANSI D" +msgstr "ANSI D" + +#: ppdc/sample.c:29 +msgid "ANSI E" +msgstr "ANSI E" + +#: ppdc/sample.c:30 +msgid "ARCH A" +msgstr "ARCH A" + +#: ppdc/sample.c:31 +msgid "ARCH B" +msgstr "ARCH B" + +#: ppdc/sample.c:32 +msgid "ARCH C" +msgstr "ARCH C" + +#: ppdc/sample.c:33 +msgid "ARCH D" +msgstr "ARCH D" + +#: ppdc/sample.c:34 +msgid "ARCH E" +msgstr "ARCH E" + +#: cgi-bin/classes.c:154 cgi-bin/printers.c:157 +msgid "Accept Jobs" +msgstr "Onartu lanak" + +#: cups/http-support.c:1195 +msgid "Accepted" +msgstr "Onartuta" + +#: cgi-bin/admin.c:480 +msgid "Add Class" +msgstr "Gehitu klasea" + +#: cgi-bin/admin.c:772 +msgid "Add Printer" +msgstr "Gehitu inprimagailua" + +#: cgi-bin/admin.c:355 cgi-bin/admin.c:388 cgi-bin/admin.c:436 +#: cgi-bin/admin.c:446 +msgid "Add RSS Subscription" +msgstr "Gehitu RSS harpidetza" + +#: ppdc/sample.c:126 +msgid "Address" +msgstr "Helbidea" + +#: ppdc/sample.c:135 +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Helbidea - 1 1/8 x 3 1/2\"" + +#: cgi-bin/admin.c:187 cgi-bin/admin.c:218 cgi-bin/admin.c:2755 +msgid "Administration" +msgstr "Administrazioa" + +#: ppdc/sample.c:400 +msgid "Always" +msgstr "Beti" + +#: backend/socket.c:126 +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +#: ppdc/sample.c:421 +msgid "Applicator" +msgstr "Aplikatzailea" + +#: scheduler/ipp.c:1135 +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "%s inprimagailuaren egoera okerreko %d balioarekin ezartzen saiatzen." + +#: scheduler/ipp.c:341 +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Taldeen atributuak ordenatik kanpo daude (%x < %x)" + +#: ppdc/sample.c:35 +msgid "B0" +msgstr "B0" + +#: ppdc/sample.c:37 +msgid "B1" +msgstr "B1" + +#: ppdc/sample.c:36 +msgid "B10" +msgstr "B10" + +#: ppdc/sample.c:38 +msgid "B2" +msgstr "B2" + +#: ppdc/sample.c:39 +msgid "B3" +msgstr "B3" + +#: ppdc/sample.c:40 +msgid "B4" +msgstr "B4" + +#: ppdc/sample.c:41 +msgid "B5" +msgstr "B5" + +#: ppdc/sample.c:42 +msgid "B6" +msgstr "B6" + +#: ppdc/sample.c:43 +msgid "B7" +msgstr "B7" + +#: ppdc/sample.c:44 +msgid "B8" +msgstr "B8" + +#: ppdc/sample.c:45 +msgid "B9" +msgstr "B9" + +#: cups/dest.c:317 +msgid "Bad NULL dests pointer" +msgstr "Okerreko helburuko NULL erakuslea" + +#: cups/ppd.c:342 +msgid "Bad OpenGroup" +msgstr "Okerreko OpenGroup" + +#: cups/ppd.c:344 +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Okerreko OpenUI/JCLOpenUI" + +#: cups/ppd.c:346 +msgid "Bad OrderDependency" +msgstr "Okerreko OrderDependency" + +#: cups/http-support.c:1210 +msgid "Bad Request" +msgstr "Okerreko eskaera" + +#: cups/snmp.c:1003 +msgid "Bad SNMP version number" +msgstr "Okerreko SNMP bertsio zenbakia" + +#: cups/ppd.c:347 +msgid "Bad UIConstraints" +msgstr "Okerreko UIConstraints" + +#: scheduler/ipp.c:1427 +#, c-format +msgid "Bad copies value %d." +msgstr "Okerreko kopien %d balioa." + +#: cups/ppd.c:355 +msgid "Bad custom parameter" +msgstr "Okerreko parametro pertsonalizatua" + +#: cups/http-support.c:1338 +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Okerreko gailuaren URIa: \"%s\"\n" + +#: scheduler/ipp.c:2502 +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Okerreko device-uri: \"%s\"." + +#: scheduler/ipp.c:2542 +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Okerreko device-uri eskema: \"%s\"." + +#: scheduler/ipp.c:9829 scheduler/ipp.c:11308 +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Okerreko document-format: \"%s\"." + +#: cups/util.c:930 +msgid "Bad filename buffer!" +msgstr "Okerreko fitxategi-izenaren buferra." + +#: ppdc/ppdc-import.cxx:265 +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Okerreko letra-atributua: %s\n" + +#: scheduler/ipp.c:10425 +msgid "Bad job-priority value!" +msgstr "Okerreko job-priority balioa." + +#: scheduler/ipp.c:1457 +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Okerreko job-sheets balioa: \"%s\"." + +#: scheduler/ipp.c:1441 +msgid "Bad job-sheets value type!" +msgstr "Okerreko job-sheets balio mota." + +#: scheduler/ipp.c:10455 +msgid "Bad job-state value!" +msgstr "Okerreko job-state balioa." + +#: scheduler/ipp.c:3657 scheduler/ipp.c:4016 scheduler/ipp.c:6644 +#: scheduler/ipp.c:6786 scheduler/ipp.c:8061 scheduler/ipp.c:8316 +#: scheduler/ipp.c:9160 scheduler/ipp.c:9386 scheduler/ipp.c:9741 +#: scheduler/ipp.c:10317 +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Okerreko job-uri atributua: \"%s\"." + +#: scheduler/ipp.c:2123 scheduler/ipp.c:6191 +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Okerreko notify-pull-method: \"%s\"." + +#: scheduler/ipp.c:2087 scheduler/ipp.c:6155 +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Okerreko notify-recipient-uri URIa: \"%s\"." + +#: scheduler/ipp.c:1473 +#, c-format +msgid "Bad number-up value %d." +msgstr "Okerreko number-up balioa: %d." + +#: cups/adminutil.c:303 +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Okerreko aukera + hautaketa %d. lerroan." + +#: scheduler/ipp.c:1490 +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Okerreko page-ranges balioak: %d-%d." + +#: scheduler/ipp.c:2586 +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Okerreko port-monitor: \"%s\"." + +#: scheduler/ipp.c:2634 +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Okerreko printer-state balioa: %d." + +#: scheduler/ipp.c:309 +#, c-format +msgid "Bad request ID %d!" +msgstr "Okerreko eskaeraren IDa: %d." + +#: scheduler/ipp.c:294 +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Okerreko eskaeraren bertsio zenbakia: %d.%d." + +#: cgi-bin/admin.c:1379 +msgid "Bad subscription ID!" +msgstr "Okerreko harpidetzaren IDa." + +#: cgi-bin/admin.c:3295 cgi-bin/admin.c:3518 +msgid "Banners" +msgstr "Titularrak" + +#: filter/bannertops.c:666 +msgid "Billing Information: " +msgstr "Fakturazioaren informazioa: " + +#: ppdc/sample.c:258 +msgid "Bond Paper" +msgstr "Tituluentzako papera" + +#: ppdc/sample.c:56 +msgid "C0 Envelope" +msgstr "C0 gainazala" + +#: ppdc/sample.c:57 +msgid "C1 Envelope" +msgstr "C1 gainazala" + +#: ppdc/sample.c:58 +msgid "C2 Envelope" +msgstr "C2 gainazala" + +#: ppdc/sample.c:59 +msgid "C3 Envelope" +msgstr "C3 gainazala" + +#: ppdc/sample.c:46 +msgid "C4" +msgstr "C4" + +#: ppdc/sample.c:60 +msgid "C4 Envelope" +msgstr "C4 gainazala" + +#: ppdc/sample.c:47 +msgid "C5" +msgstr "C5" + +#: ppdc/sample.c:61 +msgid "C5 Envelope" +msgstr "C5 gainazala" + +#: ppdc/sample.c:48 +msgid "C6" +msgstr "C6" + +#: ppdc/sample.c:63 +msgid "C6 Envelope" +msgstr "C6 gainazala" + +#: ppdc/sample.c:62 +msgid "C65 Envelope" +msgstr "C65 gainazala" + +#: ppdc/sample.c:64 +msgid "C7 Envelope" +msgstr "C7 gainazala" + +#: ppdc/sample.c:226 +msgid "CMYK" +msgstr "CMYK" + +#: ppdc/sample.c:334 +msgid "CPCL Label Printer" +msgstr "CPCL etiketen inprimagailua" + +#: cgi-bin/admin.c:1380 cgi-bin/admin.c:1419 cgi-bin/admin.c:1429 +msgid "Cancel RSS Subscription" +msgstr "Utzi RSS harpidetza" + +#: cgi-bin/admin.c:1602 cgi-bin/admin.c:1766 cgi-bin/admin.c:1778 +#: cgi-bin/admin.c:1789 +msgid "Change Settings" +msgstr "Aldatu ezarpenak" + +#: scheduler/ipp.c:2135 scheduler/ipp.c:6203 +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "\"%s\" karaktere-jokoa ez dago onartuta." + +#: ppdc/sample.c:65 +msgid "Chou3 Envelope" +msgstr "Chou3 gainazala" + +#: ppdc/sample.c:66 +msgid "Chou4 Envelope" +msgstr "Chou4 gainazala" + +#: cgi-bin/classes.c:180 cgi-bin/classes.c:307 +msgid "Classes" +msgstr "Klaseak" + +#: cgi-bin/printers.c:167 +msgid "Clean Print Heads" +msgstr "Garbitu inprimatze-buruak" + +#: ppdc/sample.c:253 +msgid "Color" +msgstr "Kolorea" + +#: ppdc/sample.c:225 +msgid "Color Mode" +msgstr "Koloreen modua" + +#: berkeley/lpc.c:209 +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Komandoa laburtu daitezke. Hauek dira komandoak:\n" +"\n" +"exit help quit status ?\n" + +#: cups/snmp.c:1007 +msgid "Community name uses indefinite length" +msgstr "Komunitatearen izenak definitu gabeko luzera darabil" + +#: cups/http-support.c:1183 +msgid "Continue" +msgstr "Jarraitu" + +#: ppdc/sample.c:336 +msgid "Continuous" +msgstr "Jarraia" + +#: scheduler/ipp.c:8610 scheduler/ipp.c:8626 scheduler/ipp.c:9845 +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Ezin izan da \"%s\" mota eskaneatu." + +#: cups/localize.c:319 +msgid "Cover open." +msgstr "Estalkia irekita." + +#: cups/http-support.c:1192 +msgid "Created" +msgstr "Sortuta" + +#: filter/bannertops.c:854 +msgid "Created On: " +msgstr "Sorrera-data:" + +#: cups/ppd.c:1072 cups/ppd.c:1112 cups/ppd.c:1326 cups/ppd.c:1429 +msgid "Custom" +msgstr "Pertsonalizatu" + +#: ppdc/sample.c:330 +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +#: ppdc/sample.c:328 +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +#: ppdc/sample.c:314 +msgid "Cut" +msgstr "Ebaki" + +#: ppdc/sample.c:422 +msgid "Cutter" +msgstr "Ebakigailua" + +#: ppdc/sample.c:49 +msgid "DL" +msgstr "DL" + +#: ppdc/sample.c:67 +msgid "DL Envelope" +msgstr "DL gutunazala" + +#: ppdc/sample.c:211 +msgid "Dark" +msgstr "Iluna" + +#: ppdc/sample.c:207 +msgid "Darkness" +msgstr "Iluntasuna" + +#: cgi-bin/admin.c:2062 cgi-bin/admin.c:2073 cgi-bin/admin.c:2118 +msgid "Delete Class" +msgstr "Ezabatu klasea" + +#: cgi-bin/admin.c:2147 cgi-bin/admin.c:2158 cgi-bin/admin.c:2203 +msgid "Delete Printer" +msgstr "Ezabatu inprimagailua" + +#: filter/bannertops.c:735 +msgid "Description: " +msgstr "Deskripzioa: " + +#: ppdc/sample.c:252 +msgid "DeskJet Series" +msgstr "DeskJet serieak" + +#: scheduler/ipp.c:1393 +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "\"%s\" helburuak ez du lanik onartzen." + +#: cups/localize.c:353 +msgid "Developer almost empty." +msgstr "Errebelatzailea ia hutsik." + +#: cups/localize.c:355 +msgid "Developer empty!" +msgstr "Errebelatzailea hutsik!" + +#: systemv/lpinfo.c:305 +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Gailua: URIa = %s\n" +" klasea = %s\n" +" informazioa = %s\n" +" marka eta modeloa = %s\n" +" gailuaren IDa = %s\n" +" kokalekua = %s\n" + +#: ppdc/sample.c:407 +msgid "Direct Thermal Media" +msgstr "Zuzeneko euskarri termikoa" + +#: ppdc/sample.c:316 +msgid "Disabled" +msgstr "Desgaituta" + +#: scheduler/ipp.c:6691 +#, c-format +msgid "Document %d not found in job %d." +msgstr "Ez da %d dokumentua aurkitu %d lanean." + +#: cups/localize.c:323 +msgid "Door open." +msgstr "Atea irekita." + +#: ppdc/sample.c:50 +msgid "Double Postcard" +msgstr "Postal bikoitza" + +#: filter/bannertops.c:820 +msgid "Driver Name: " +msgstr "Kontrolatzailearen izena:" + +#: filter/bannertops.c:831 +msgid "Driver Version: " +msgstr "Kontrolatzailearen bertsioa:" + +#: ppdc/sample.c:247 +msgid "Duplexer" +msgstr "Duplexatzailea" + +#: ppdc/sample.c:201 +msgid "Dymo" +msgstr "Dymo" + +#: filter/pstops.c:446 +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "" +"EMERG: ezin da memoriarik esleitu orrialdearen informazioarentzako: %s.\n" + +#: filter/pstops.c:438 +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: ezin da memoriarik esleitu orrialdeen arrayarentzako: %s.\n" + +#: ppdc/sample.c:402 +msgid "EPL1 Label Printer" +msgstr "EPL1 etiketen inprimagailua" + +#: ppdc/sample.c:405 +msgid "EPL2 Label Printer" +msgstr "EPL2 etiketen inprimagailua" + +#: driver/rastertoescpx.c:1776 driver/rastertopclx.c:1801 +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "ERROR: %s job-id erabiltzailea titulua kopiak aukerak [fitxategia]\n" + +#: filter/pstops.c:707 +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox: iruzkin okerra ikusi da\n" + +#: filter/pstops.c:2220 +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: %%IncludeFeature: iruzkin okerra\n" + +#: filter/pstops.c:1286 filter/pstops.c:1292 +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: %%Page: iruzkin okerra fitxategian\n" + +#: filter/pstops.c:1363 +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: %%PageBoundingBox: iruzkin okerra fitxategian\n" + +#: backend/scsi-irix.c:100 backend/scsi-linux.c:114 +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: SCSI gailuaren fitxategia okerra: \"%s\"\n" + +#: filter/pstext.c:276 filter/texttops.c:284 filter/texttops.c:295 +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: karaktere-jokoaren fitxategia okerra: %s\n" + +#: filter/texttops.c:453 +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: karaktere-jokoaren mota okerra: %s\n" + +#: filter/textcommon.c:613 +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: zutabeen balioa okerra: %d\n" + +#: filter/textcommon.c:624 +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: cpi-ren balioa okerra: %f\n" + +#: filter/pstext.c:320 filter/pstext.c:357 filter/texttops.c:348 +#: filter/texttops.c:384 +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: letra-deskripzioaren lerroa okerra: %s\n" + +#: filter/textcommon.c:635 +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: lpi balioa okerra: %f\n" + +#: filter/imagetoraster.c:460 +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: orrialdearen konfigurazioa okerra\n" + +#: filter/pstext.c:334 filter/texttops.c:361 +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: testuaren norabidea okerra: %s\n" + +#: filter/pstext.c:371 filter/texttops.c:397 +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: testuaren zabalera okerra: %s\n" + +#: backend/ipp.c:750 +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: helburuko inprimagailua ez da existitzen\n" + +#: filter/pstops.c:696 +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: bikoiztutako %%BoundingBox: iruzkina ikusi da\n" + +#: filter/pstops.c:648 +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: bikoiztutako %%Pages: iruzkina ikusi da\n" + +#: backend/ipp.c:472 filter/pstops.c:303 +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: inprimatzeko fitxategia hutsik dago.\n" + +#: backend/pap.c:838 +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: %d errorea PAPSendData eskaera bidaltzean: %s\n" + +#: ppdc/ppdc-catalog.cxx:338 ppdc/ppdc-catalog.cxx:350 +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: komatxoen arteko katea espero zen %2$s(r)en %1$d lerroan\n" + +#: backend/usb-darwin.c:367 backend/usb-darwin.c:425 backend/usb-darwin.c:490 +#: backend/usb-darwin.c:508 +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: USBaren errore larria\n" + +#: filter/hpgl-input.c:139 +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: baliogabeko HP-GL/2 komandoa ikusi da, ezin da fitxategia " +"inprimatu\n" + +#: filter/pstops.c:1771 +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog falta da\n" + +#: filter/pstops.c:1842 +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup falta da\n" + +#: backend/ipp.c:245 +msgid "" +"ERROR: Missing device URI on command-line and no DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: gailuaren URIa falta da komando-lerroan eta ez dago inguruneko " +"DEVICE_URI aldagairik\n" + +#: filter/bannertops.c:222 +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: balioa falta da titularraren fitxategiko %d lerroan\n" + +#: ppdc/ppdc-catalog.cxx:415 +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: msgid lerro bat behar da itzulpeneko edozein kateren aurretik %d " +"lerroan %s(e)n\n" + +#: filter/pstops.c:759 +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: ez dago %%BoundingBox: iruzkinik goiburuan\n" + +#: filter/pstops.c:762 +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: ez dago %%Pages: iruzkinik goiburuan\n" + +#: backend/usb.c:200 +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: ez da gailuaren URIrik aurkitu argv[0] argumentuan edo inguruneko " +"DEVICE_URI aldagaian\n" + +#: filter/pstext.c:433 +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "" +"ERROR: ez da letra-tiporik aurkitu karaktere-jokoaren %s fitxategian\n" + +#: driver/rastertoescpx.c:1906 driver/rastertopclx.c:1931 +#: filter/rastertoepson.c:1129 filter/rastertohp.c:857 +#: filter/rastertolabel.c:1283 +msgid "ERROR: No pages found!\n" +msgstr "ERROR: ez dira orrialderik aurkitu\n" + +#: backend/runloop.c:348 +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: ez dago paperik\n" + +#: backend/ipp.c:1743 +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: inguruneko PRINTER aldagaia ez dago definituta\n" + +#: backend/ipp.c:1064 +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: inprimatzeko fitxategia ez da onartu (%s)\n" + +#: backend/pap.c:521 +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: inprimagailuak ez du erantzuten\n" + +#: backend/ipp.c:586 backend/ipp.c:717 backend/lpd.c:846 backend/socket.c:313 +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: inprimagailuak ez du erantzuten\n" + +#: backend/pap.c:858 +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: inprimagailuak ustekabeko EOF bidali du\n" + +#: backend/lpd.c:1050 backend/lpd.c:1197 +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: urruneko ostalariak ez du kontrol-fitxategia onartu (%d)\n" + +#: backend/lpd.c:1145 +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: urruneko ostalariak ez du datuen fitxategia onartu (%d)\n" + +#: backend/pap.c:1694 +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: denbora-muga gainditu da inprimagailura datuak bidaltzean\n" + +#: backend/ipp.c:1140 +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: ezin da %d fitxategia lanari gehitu: %s\n" + +#: backend/ipp.c:1375 +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: ezin da %d lana bertan behera utzi: %s\n" + +#: filter/pdftops.c:136 +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: ezin da PDF fitxategia kopiatu" + +#: filter/pdftops.c:412 +msgid "ERROR: Unable to create pipe" +msgstr "ERROR: ezin da kanalizazioa sortu" + +#: backend/lpd.c:770 +msgid "ERROR: Unable to create socket" +msgstr "ERROR: ezin da socket-a sortu" + +#: backend/ipp.c:1465 +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: ezin da aldi baterako inprimatzeko konprimitutako fitxategia sortu: " +"%s\n" + +#: backend/ipp.c:435 backend/ipp.c:1765 backend/lpd.c:444 filter/pstops.c:2719 +#: scheduler/cupsfilter.c:1108 systemv/lpadmin.c:1453 systemv/lpadmin.c:1842 +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: ezin da aldi baterako fitxategia sortu" + +#: backend/ipp.c:1821 +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: ezin da pictwpstops exekutatu: %s\n" + +#: filter/pdftops.c:433 filter/pdftops.c:447 +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: ezin da gs programa exekutatu" + +#: filter/pdftops.c:430 filter/pdftops.c:445 +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: ezin da pdftops programa exekutatu" + +#: filter/pdftops.c:467 filter/pdftops.c:477 +msgid "ERROR: Unable to execute pstops program" +msgstr "ERROR: ezin da pstops programa exekutatu" + +#: backend/ipp.c:1834 +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: ezin da pictwpstops sardetu: %s\n" + +#: backend/pap.c:712 +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: ezin da PAP eskaera lortu" + +#: backend/pap.c:701 +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: ezin da PAP erantzuna lortu" + +#: backend/ipp.c:1750 +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: ezin da \"%s\" - \"%s\" inprimagailuaren PPD fitxategia lortu.\n" + +#: backend/pap.c:302 +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: ezin da AppleTalk zona lehenetsia lortu" + +#: backend/ipp.c:1227 +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: ezin da %d lanaren atributurik lortu (%s)\n" + +#: backend/ipp.c:760 +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: ezin da inprimagailuaren egoera lortu (%s)\n" + +#: backend/ipp.c:426 backend/ipp.c:604 backend/lpd.c:435 backend/lpd.c:702 +#: backend/socket.c:268 +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: ezin da '%s' inprimagailua aurkitu\n" + +#: backend/pap.c:688 +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: ezin da PAP erantzuna aurktitu" + +#: backend/pap.c:322 +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: ezin da AppleTalk inprimagailurik aurkitu" + +#: backend/pap.c:451 +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: ezin da AppleTalk helbiderik sortu" + +#: filter/pstext.c:247 filter/texttops.c:248 +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: ezin da \"%s\" - \"%s\" ireki\n" + +#: filter/pstext.c:264 filter/texttops.c:268 +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: ezin da %s ireki: %s\n" + +#: driver/rastertoescpx.c:1791 driver/rastertopclx.c:1816 +msgid "ERROR: Unable to open PPD file!\n" +msgstr "ERROR: ezin da PPD fitxategia ireki\n" + +#: filter/bannertops.c:184 +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: ezin da \"%s\" titularraren fitxategia ireki: %s\n" + +#: backend/parallel.c:249 backend/scsi-irix.c:140 backend/scsi-linux.c:154 +#: backend/serial.c:262 backend/usb-unix.c:146 +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: ezin da \"%s\" gailuaren fitxategia ireki: %s\n" + +#: filter/pstops.c:291 +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: ezin da \"%s\" fitxategia ireki: %s\n" + +#: filter/gziptoany.c:74 +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: ezin da \"%s\" fitxategia ireki: %s\n" + +#: filter/imagetops.c:313 filter/imagetoraster.c:637 +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: ezin da irudiaren fitxategia ireki inprimatzeko\n" + +#: backend/ipp.c:1481 backend/pap.c:249 backend/parallel.c:151 +#: backend/scsi.c:181 backend/serial.c:189 backend/socket.c:156 +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: ezin da \"%s\" inprimatzeko fitxategia ireki: %s\n" + +#: backend/usb.c:237 +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: ezin da %s inprimatzeko fitxategia ireki: %s\n" + +#: backend/lpd.c:485 +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: ezin da %s inprimatzeko fitxategia ireki: %s\n" + +#: driver/rastertoescpx.c:1806 driver/rastertopclx.c:1831 +#: filter/rastertoepson.c:1001 filter/rastertohp.c:726 +#: filter/rastertolabel.c:1148 +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "ERROR: ezin da bilbearen fitxategia ireki: %s\n" + +#: backend/ipp.c:1473 +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: ezin da aldi baterako konprimitutako inprimatzeko fitxategia ireki: " +"%s\n" + +#: filter/texttops.c:200 +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: ezin dira testuaren %d zutabe inprimatu\n" + +#: filter/texttops.c:179 +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: ezin da %dx%d testu orrialde inprimatu\n" + +#: backend/serial.c:615 +msgid "ERROR: Unable to read print data" +msgstr "ERROR: ezin da inprimatzeko daturik irakurri" + +#: backend/usb-darwin.c:592 backend/usb-darwin.c:625 +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: ezin da inprimatzeko daturik irakurri\n" + +#: backend/lpd.c:787 +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: ezin da ataka erreserbatu" + +#: filter/pstops.c:563 +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: ezin da fitxategiko %ld posizioan kokatu: %s\n" + +#: filter/pstops.c:561 +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: ezin da fitxategiko %lld posizioan kokatu: %s\n" + +#: backend/lpd.c:601 +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: ezin da LPD komandoa bidali" + +#: backend/pap.c:571 +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: ezin da PAP eskaera bidali" + +#: backend/pap.c:580 +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: ezin da PAPren hasierako datuak bidaltzeko eskaera bidali" + +#: backend/scsi-irix.c:219 backend/scsi-linux.c:237 +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: ezin da inprimatzeko daturik bidali (%d)\n" + +#: backend/usb-darwin.c:711 +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: ezin da inprimatzeko daturik bidali\n" + +#: backend/lpd.c:1101 +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: ezin da inprimatzeko fitxategia inprimagailura bidali" + +#: backend/lpd.c:1115 +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: ezin da NULL balioa bidali inprimagailura" + +#: backend/ipp.c:1847 +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: ezin da pictwpstops-ren zain egon: %s\n" + +#: backend/ipp.c:1492 +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: ezin dira %d byte idatzi \"%s\"(e)n: %s\n" + +#: backend/usb-libusb.c:169 backend/usb-libusb.c:765 +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: ezin dira %d byte idatzi inprimagailuan\n" + +#: backend/lpd.c:1031 backend/lpd.c:1178 +msgid "ERROR: Unable to write control file" +msgstr "ERROR: ezin da kontrol-fitxategia idatzi" + +#: backend/serial.c:691 +msgid "ERROR: Unable to write print data" +msgstr "ERROR: ezin da inprimatzeko daturik idatzi" + +#: backend/runloop.c:122 backend/runloop.c:363 +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: ezin da inprimatzeko daturik idatzi: %s\n" + +#: filter/imagetoraster.c:1199 filter/imagetoraster.c:1295 +#: filter/imagetoraster.c:1335 +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: ezin da bilbeko daturik idatzi kontrolatzailean\n" + +#: backend/ipp.c:447 backend/lpd.c:454 +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: ezin da aldi baterako fitxategian idatzi" + +#: filter/gziptoany.c:96 +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: ezin da deskonprimitutako dokumentuaren daturik idatzi: %s\n" + +#: ppdc/ppdc-catalog.cxx:432 +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: ustekabeko testua %2$s fitxategiko %1$d lerroan\n" + +#: backend/ipp.c:353 +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: enkriptatzeko aukeraren \"%s\" balioa ezezaguna\n" + +#: backend/lpd.c:355 +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: \"%s\" fitxategiaren ordena ezezaguna\n" + +#: backend/lpd.c:327 +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: \"%c\" karakterearen formatua ezezaguna\n" + +#: ppdc/ppdc-catalog.cxx:460 +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: mezuaren katalogo-formatua ezezaguna \"%s\"(r)entzako\n" + +#: backend/ipp.c:399 +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: \"%s\" aukera ezezaguna \"%s\" balioarekin\n" + +#: backend/lpd.c:341 +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: inprimatzeko \"%s\" modua ezezaguna\n" + +#: backend/ipp.c:370 +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: bertsioaren aukeraren \"%s\" balioa ezezaguna\n" + +#: filter/pstops.c:2418 +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: distiraren %s balioa onartu gabea. Distira=100 erabiltzen\n" + +#: filter/pstops.c:2487 +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: gammaren %s balioa onartu gabea. Gamma=100 erabiltzen\n" + +#: filter/pstops.c:2541 +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" +"ERROR: number-up parametroaren %d balioa onartu gabea. number-up=1 " +"erabiltzen\n" + +#: filter/pstops.c:2574 +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: number-up-layout parametroaren %s balioa onartu gabea. number-up-" +"layout=1 erabiltzen\n" + +#: filter/pstops.c:2624 +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: page-border parametroaren %s balioa onartu gabea. page-border=none " +"erabiltzen\n" + +#: filter/pstops.c:2090 +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "" +"ERROR: gainezkatutako doc_printf (%d byte) detektattua. Bertan behera " +"uzten\n" + +#: backend/ipp.c:1866 +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops %d seinalearekin irten da\n" + +#: backend/ipp.c:1863 +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops %d egoerarekin irten da\n" + +#: backend/ipp.c:614 backend/lpd.c:875 backend/socket.c:336 +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: berreskura daiteke. Ezin da inprimagailuarekin konektatu. 30 " +"segundo barru saiatuko da berriro...\n" + +#: backend/pap.c:629 +msgid "ERROR: select() failed" +msgstr "ERROR: huts egin du select()-ek" + +#: backend/lpd.c:938 +msgid "ERROR: unable to stat print file" +msgstr "ERROR: ezin da 'stat' exekutatu inprimatzeko fitxategiarentzako" + +#: cgi-bin/admin.c:1817 cgi-bin/admin.c:1829 cgi-bin/admin.c:1883 +#: cgi-bin/admin.c:1890 cgi-bin/admin.c:1925 cgi-bin/admin.c:1938 +#: cgi-bin/admin.c:1962 cgi-bin/admin.c:2035 +msgid "Edit Configuration File" +msgstr "Editatu konfigurazioko fitxategia" + +#: cups/adminutil.c:348 +msgid "Empty PPD file!" +msgstr "PPD fitxategia hutsik dago." + +#: cgi-bin/admin.c:3539 +msgid "Ending Banner" +msgstr "Titularraren amaiera" + +#: systemv/lppasswd.c:205 +msgid "Enter old password:" +msgstr "Sartu pasahitz zaharra:" + +#: systemv/lppasswd.c:234 +msgid "Enter password again:" +msgstr "Sartu pasahitza berriro:" + +#: systemv/lppasswd.c:223 +msgid "Enter password:" +msgstr "Sartu pasahitza:" + +#: scheduler/client.c:2392 +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Idatzi zure erabiltzaile-izena eta pasahitza, edo supererabiltzailearen " +"izena eta pasahitza, orrialde honetara sarbidetzeko. Kerberos " +"autentifikazioa erabiltzen ari bazara, ziurtatu zaitez baliozko Kerberos " +"txartela duzula." + +#: ppdc/sample.c:241 +msgid "Envelope Feed" +msgstr "Gutunazalen iturria" + +#: ppdc/sample.c:212 +msgid "Epson" +msgstr "Epson" + +#: cgi-bin/admin.c:3582 +msgid "Error Policy" +msgstr "Erroreen politika" + +#: systemv/lpinfo.c:109 systemv/lpmove.c:94 +msgid "Error: need hostname after '-h' option!\n" +msgstr "Errorea: ostalari-izena behar da '-h' aukeraren ondoren\n" + +#: ppdc/sample.c:326 +msgid "Every 10 Labels" +msgstr "10 etiketez behin" + +#: ppdc/sample.c:318 +msgid "Every 2 Labels" +msgstr "2 etiketez behin" + +#: ppdc/sample.c:319 +msgid "Every 3 Labels" +msgstr "3 etiketez behin" + +#: ppdc/sample.c:320 +msgid "Every 4 Labels" +msgstr "4 etiketez behin" + +#: ppdc/sample.c:321 +msgid "Every 5 Labels" +msgstr "5 etiketez behin" + +#: ppdc/sample.c:322 +msgid "Every 6 Labels" +msgstr "6 etiketez behin" + +#: ppdc/sample.c:323 +msgid "Every 7 Labels" +msgstr "7 etiketez behin" + +#: ppdc/sample.c:324 +msgid "Every 8 Labels" +msgstr "8 etiketez behin" + +#: ppdc/sample.c:325 +msgid "Every 9 Labels" +msgstr "9 etiketez behin" + +#: ppdc/sample.c:317 +msgid "Every Label" +msgstr "Etiketa bakoitzeko" + +#: cups/http-support.c:1238 +msgid "Expectation Failed" +msgstr "Espero zenak huts egin du" + +#: cgi-bin/admin.c:2325 cgi-bin/admin.c:2344 +msgid "Export Printers to Samba" +msgstr "Esportatu inprimagailuak Samba-ra" + +#: systemv/cupstestdsc.c:176 systemv/cupstestdsc.c:193 +#: systemv/cupstestdsc.c:218 systemv/cupstestdsc.c:235 +#: systemv/cupstestdsc.c:259 systemv/cupstestdsc.c:277 +#: systemv/cupstestdsc.c:306 systemv/cupstestdsc.c:343 +#: systemv/cupstestdsc.c:353 systemv/cupstestdsc.c:363 +#: systemv/cupstestdsc.c:373 systemv/cupstestdsc.c:383 +#: systemv/cupstestdsc.c:391 +msgid "FAIL\n" +msgstr "HUTSEGITEA\n" + +#: ppdc/sample.c:132 +msgid "File Folder" +msgstr "Fitxategien karpeta" + +#: ppdc/sample.c:141 +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Fitxategien karpeta - 9/16 x 3 7/16\"" + +#: scheduler/ipp.c:2522 +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Fitxategiaren gailuaren URIak desgaitu egin dira. Gaitzeko, ikus FileDevice " +"direktiba \"%s/cupsd.conf\" fitxategian." + +#: ppdc/sample.c:92 +msgid "Folio" +msgstr "Folioa" + +#: cups/http-support.c:1217 +msgid "Forbidden" +msgstr "Debekatua" + +#: cups/localize.c:345 +msgid "Fuser temperature high!" +msgstr "Fuser-aren tenperatura altua." + +#: cups/localize.c:347 +msgid "Fuser temperature low!" +msgstr "Fuser-aren tenperatura baxua." + +#: cups/ppd.c:700 cups/ppd.c:1230 +msgid "General" +msgstr "Orokorra" + +#: ppdc/sample.c:231 +msgid "Generic" +msgstr "Generikoa" + +#: ppdc/sample.c:89 +msgid "German FanFold" +msgstr "FanFold alemana" + +#: ppdc/sample.c:90 +msgid "German FanFold Legal" +msgstr "FanFold Legal alemana" + +#: cups/snmp.c:1017 +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU definitu gabeko luzera darabil" + +#: ppdc/sample.c:261 +msgid "Glossy Paper" +msgstr "Paper satinatua" + +#: scheduler/ipp.c:3635 scheduler/ipp.c:3941 scheduler/ipp.c:6621 +#: scheduler/ipp.c:6763 scheduler/ipp.c:8038 scheduler/ipp.c:9137 +#: scheduler/ipp.c:9363 scheduler/ipp.c:9718 scheduler/ipp.c:10294 +msgid "Got a printer-uri attribute but no job-id!" +msgstr "printer-uri atributua lortu da, baina ez job-id." + +#: ppdc/sample.c:227 +msgid "Grayscale" +msgstr "Gris-eskala" + +#: ppdc/sample.c:251 +msgid "HP" +msgstr "HP" + +#: ppdc/sample.c:133 +msgid "Hanging Folder" +msgstr "Esekitako karpeta" + +#: ppdc/sample.c:142 +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Esekitako karpeta - 9/16 x 2\"" + +#: backend/pap.c:296 +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk desgaituta sistemako hobespenetan\n" + +#: backend/pap.c:511 +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk desgaituta sistemako hobespenetan.\n" + +#: backend/ipp.c:1354 +msgid "INFO: Canceling print job...\n" +msgstr "INFO: inprimatzeko lana bertan behera uzten...\n" + +#: backend/ipp.c:634 backend/lpd.c:894 backend/socket.c:358 +msgid "INFO: Connected to printer...\n" +msgstr "INFO: inprimagailura konektatuta...\n" + +#: backend/ipp.c:549 backend/lpd.c:727 backend/socket.c:275 +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: inprimagailura konektatzen...\n" + +#: backend/lpd.c:1053 backend/lpd.c:1200 +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: kontrol-fitxategia ongi bidali da\n" + +#: backend/ipp.c:439 backend/lpd.c:448 +msgid "INFO: Copying print data...\n" +msgstr "INFO: inprimatzeko datuak kopiatzen...\n" + +#: backend/lpd.c:1148 +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: datuen fitxategia ongi bidali da\n" + +#: driver/rastertoescpx.c:1887 driver/rastertopclx.c:1912 +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "INFO: %d orrialdea amaituta...\n" + +#: filter/imagetoraster.c:1142 +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: %d orrialdeari formatua ematen...\n" + +#: filter/imagetoraster.c:623 +msgid "INFO: Loading image file...\n" +msgstr "INFO: irudiaren fitxategia kargatzen...\n" + +#: cups/http-support.c:1409 +msgid "INFO: Looking for printer...\n" +msgstr "INFO: inprimagailua bilatzen...\n" + +#: backend/pap.c:928 +msgid "INFO: Opening connection\n" +msgstr "INFO: konexioa irekitzen\n" + +#: backend/socket.c:429 +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" +"INFO: inprimatzeko fitxategia bidalita, inprimagailuak amaitu " +"zain...\n" + +#: backend/ipp.c:1042 backend/usb-unix.c:132 +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "" +"INFO: inprimagailua lanpetuta. 10 segundotan saiatu da berriro...\n" + +#: backend/parallel.c:236 backend/scsi-irix.c:147 backend/scsi-linux.c:161 +#: backend/serial.c:256 +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "" +"INFO: inprimagailua lanpetuta. 30 segundotan saiatu da berriro...\n" + +#: backend/usb-unix.c:437 +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "" +"INFO: inprimagailua lanpetuta. 5 segundotan saiatu da berriro...\n" + +#: backend/ipp.c:743 backend/ipp.c:1053 +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: inprimagailuak ez du IPP/%d.%d onartzen. Honekin saiatzen: " +"IPP/1.0...\n" + +#: backend/usb-unix.c:521 +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "" +"INFO: inprimagailua lanpetuta dago. 5 segundotan saiatu da " +"berriro...\n" + +#: backend/runloop.c:357 +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: inprimagailua unean lineaz kanpo dago.\n" + +#: backend/runloop.c:243 +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: inprimagailua unean linean dago.\n" + +#: backend/runloop.c:379 backend/usb-darwin.c:1245 +msgid "INFO: Printer is now online.\n" +msgstr "INFO: inprimagailua orain linean dago.\n" + +#: backend/usb-darwin.c:1263 +msgid "INFO: Printer is offline.\n" +msgstr "INFO: inprimagailua lineaz kanpo dago.\n" + +#: backend/parallel.c:242 backend/usb-unix.c:139 +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "" +"INFO: inprimagailua ez dago konektatuta. 30 segundo barru saiatuko da " +"berriro...\n" + +#: driver/rastertoescpx.c:1873 driver/rastertopclx.c:1895 +#: filter/rastertoepson.c:1080 filter/rastertohp.c:803 +#: filter/rastertolabel.c:1235 +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: %d orrialdea inprimatzen. %% %d osatuta...\n" + +#: filter/imagetops.c:808 +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: %d orrialdea inprimatzen...\n" + +#: backend/socket.c:461 driver/rastertoescpx.c:1911 driver/rastertopclx.c:1936 +#: filter/rastertoepson.c:1134 filter/rastertohp.c:862 +#: filter/rastertolabel.c:1288 +msgid "INFO: Ready to print.\n" +msgstr "INFO: inprimatzeko prest.\n" + +#: backend/lpd.c:1172 +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: kontrol-fitxategia bidaltzen (%lu byte)\n" + +#: backend/lpd.c:1025 +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: kontrol-fitxategia bidaltzen (%u byte)\n" + +#: backend/pap.c:564 +msgid "INFO: Sending data\n" +msgstr "INFO: datuen fitxategia bidaltzen\n" + +#: backend/lpd.c:1084 +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: datuen fitxategia bidaltzen (%ld byte)\n" + +#: backend/lpd.c:1082 +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: datuen fitxategia bidaltzen (%lld byte)\n" + +#: backend/usb-darwin.c:524 +msgid "INFO: Sending print data...\n" +msgstr "INFO: inprimatzeko datuak bidaltzen...\n" + +#: backend/parallel.c:294 backend/socket.c:408 backend/usb-unix.c:201 +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: inprimatzeko fitxategia bidalita, %ld byte...\n" + +#: backend/parallel.c:292 backend/socket.c:406 backend/usb-unix.c:199 +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: inprimatzeko fitxategia bidalita, %lld byte...\n" + +#: backend/lpd.c:1096 +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: LPR lana ilaran jartzen. %% %.0f osatuta...\n" + +#: driver/rastertoescpx.c:1859 driver/rastertopclx.c:1880 +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "INFO: %d orrialdea hasten...\n" + +#: backend/ipp.c:566 backend/ipp.c:824 backend/lpd.c:827 +#: backend/parallel.c:221 backend/scsi-irix.c:125 backend/scsi-linux.c:139 +#: backend/serial.c:241 backend/socket.c:296 backend/usb-unix.c:117 +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: ezin da inprimagailuarekin kontaktatu, klaseko hurrengo " +"inprimagailuan ilaratzen...\n" + +#: backend/pap.c:309 +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: \"%s\" AppleTalk zona lehenetsia erabiltzen\n" + +#: backend/ipp.c:1165 +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: lana osatzeko itxoiten...\n" + +#: backend/usb-darwin.c:444 backend/usb-libusb.c:117 +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: inprimagailua erabilgarri egon arte itxoiten...\n" + +#: ppdc/sample.c:93 +msgid "ISO B0" +msgstr "ISO B0" + +#: ppdc/sample.c:94 +msgid "ISO B1" +msgstr "ISO B1" + +#: ppdc/sample.c:104 +msgid "ISO B10" +msgstr "ISO B10" + +#: ppdc/sample.c:95 +msgid "ISO B2" +msgstr "ISO B2" + +#: ppdc/sample.c:96 +msgid "ISO B3" +msgstr "ISO B3" + +#: ppdc/sample.c:97 +msgid "ISO B4" +msgstr "ISO B4" + +#: ppdc/sample.c:69 +msgid "ISO B4 Envelope" +msgstr "ISO B4 gutunazala" + +#: ppdc/sample.c:98 +msgid "ISO B5" +msgstr "ISO B5" + +#: ppdc/sample.c:99 +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (handiagoa)" + +#: ppdc/sample.c:70 +msgid "ISO B5 Envelope" +msgstr "ISO B5 gutunazala" + +#: ppdc/sample.c:100 +msgid "ISO B6" +msgstr "ISO B6" + +#: ppdc/sample.c:71 +msgid "ISO B6 Envelope" +msgstr "ISO B6 gutunazala" + +#: ppdc/sample.c:101 +msgid "ISO B7" +msgstr "ISO B7" + +#: ppdc/sample.c:102 +msgid "ISO B8" +msgstr "ISO B8" + +#: ppdc/sample.c:103 +msgid "ISO B9" +msgstr "ISO B9" + +#: cups/ppd.c:350 +msgid "Illegal control character" +msgstr "Kontrol-karaktere ilegala" + +#: cups/ppd.c:351 +msgid "Illegal main keyword string" +msgstr "Gako-hitzaren kate nagusia ilegala" + +#: cups/ppd.c:352 +msgid "Illegal option keyword string" +msgstr "Aukeraren gako-hitzaren katea ilegala" + +#: cups/ppd.c:353 +msgid "Illegal translation string" +msgstr "Itzulpenaren katea ilegala" + +#: cups/ppd.c:354 +msgid "Illegal whitespace character" +msgstr "Zuriunea karakterea ilegala" + +#: cups/localize.c:337 +msgid "Ink/toner almost empty." +msgstr "Tinta/Tonerra ia hutsik." + +#: cups/localize.c:339 +msgid "Ink/toner empty!" +msgstr "Tinta/Tonerra hutsik!" + +#: cups/localize.c:341 +msgid "Ink/toner waste bin almost full." +msgstr "Tinta/Tonerraren zakarrontzia ia beteta." + +#: cups/localize.c:343 +msgid "Ink/toner waste bin full!" +msgstr "Tinta/Tonerraren zakarrontzia beteta!" + +#: ppdc/sample.c:246 +msgid "Installable Options" +msgstr "Aukera instalagarriak" + +#: ppdc/sample.c:249 +msgid "Installed" +msgstr "Instalatuta" + +#: ppdc/sample.c:264 +msgid "IntelliBar Label Printer" +msgstr "IntelliBar etiketen inprimagailua" + +#: ppdc/sample.c:263 +msgid "Intellitech" +msgstr "Intellitech" + +#: cups/localize.c:321 +msgid "Interlock open." +msgstr "Segurtasun-blokeoa irekita." + +#: cups/http-support.c:1244 +msgid "Internal Server Error" +msgstr "Zerbitzariaren barneko errorea" + +#: cups/ppd.c:341 +msgid "Internal error" +msgstr "Barneko errorea" + +#: ppdc/sample.c:130 +msgid "Internet Postage 2-Part" +msgstr "Interneteko posta 2. zatia" + +#: ppdc/sample.c:139 +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Interneteko posta 2. zatia - 2 1/4 x 7 1/2\"" + +#: ppdc/sample.c:131 +msgid "Internet Postage 3-Part" +msgstr "Interneteko posta 3. zatia" + +#: ppdc/sample.c:140 +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Interneteko posta 3. zatia - 2 1/4 x 7\"" + +#: backend/ipp.c:206 +msgid "Internet Printing Protocol" +msgstr "Interneten inPrimatzeko Protokoloa" + +#: ppdc/sample.c:68 +msgid "Invite Envelope" +msgstr "Gobidapeneko gutunazala" + +#: ppdc/sample.c:72 +msgid "Italian Envelope" +msgstr "Gutunazal italiarra" + +#: cups/ppd.c:1348 +msgid "JCL" +msgstr "JCL" + +#: scheduler/ipp.c:9436 +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "%d. lana ezin da berrabiatu. Ez dago fitxategirik." + +#: scheduler/ipp.c:3676 scheduler/ipp.c:4044 scheduler/ipp.c:6662 +#: scheduler/ipp.c:6804 scheduler/ipp.c:7915 scheduler/ipp.c:8079 +#: scheduler/ipp.c:8289 scheduler/ipp.c:8334 scheduler/ipp.c:9178 +#: scheduler/ipp.c:9404 scheduler/ipp.c:9759 scheduler/ipp.c:10335 +#, c-format +msgid "Job #%d does not exist!" +msgstr "%d. lana ez da existitzen." + +#: scheduler/ipp.c:4076 +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "%d. lana jadanik abortatuta dago, ezin da bertan behera utzi." + +#: scheduler/ipp.c:4070 +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "" +"%d. lana jadanik bertan behera utzita dago, ezin da bertan behera utzi." + +#: scheduler/ipp.c:4082 +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "%d. lana jadanik burututa dago, ezin da bertan behera utzi." + +#: scheduler/ipp.c:8376 scheduler/ipp.c:10350 +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "%d. lana jadanik burututa dago, eta ezin da aldatu." + +#: scheduler/ipp.c:9418 +#, c-format +msgid "Job #%d is not complete!" +msgstr "%d. lana ez dago burututa." + +#: scheduler/ipp.c:3691 +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "%d. lana ez dago atxikituta autentifikatzeko." + +#: scheduler/ipp.c:9192 +#, c-format +msgid "Job #%d is not held!" +msgstr "%d. lana ez dago atxikituta." + +#: scheduler/ipp.c:7893 +#, c-format +msgid "Job #%s does not exist!" +msgstr "%s. lana ez da existitzen." + +#: scheduler/ipp.c:6289 +#, c-format +msgid "Job %d not found!" +msgstr "%d lana ez da aurkitu." + +#: cgi-bin/ipp-var.c:1050 +msgid "Job Completed" +msgstr "Lana burututa" + +#: cgi-bin/ipp-var.c:1048 +msgid "Job Created" +msgstr "Lana sortuta" + +#: filter/bannertops.c:623 +msgid "Job ID: " +msgstr "Lanaren IDa: " + +#: cgi-bin/ipp-var.c:1054 +msgid "Job Options Changed" +msgstr "Lanaren aukerak aldatuta" + +#: cgi-bin/ipp-var.c:1052 +msgid "Job Stopped" +msgstr "Lana geldituta" + +#: filter/bannertops.c:631 +msgid "Job UUID: " +msgstr "Lanaren UUIDa:" + +#: scheduler/ipp.c:10433 +msgid "Job is completed and cannot be changed." +msgstr "Lana burututa dago eta ezin da aldatu." + +#: cgi-bin/jobs.c:197 +msgid "Job operation failed:" +msgstr "Lanaren eragiketak huts egin du:" + +#: scheduler/ipp.c:10469 scheduler/ipp.c:10488 scheduler/ipp.c:10499 +msgid "Job state cannot be changed." +msgstr "Lanaren egoera ezin da aldatu." + +#: scheduler/ipp.c:9283 +msgid "Job subscriptions cannot be renewed!" +msgstr "Lanaren harpidetzak ezin dira berritu." + +#: cgi-bin/jobs.c:102 cgi-bin/jobs.c:113 cgi-bin/jobs.c:194 +msgid "Jobs" +msgstr "Lanak" + +#: ppdc/sample.c:73 +msgid "Kaku2 Envelope" +msgstr "Kaku2 gutunazala" + +#: ppdc/sample.c:74 +msgid "Kaku3 Envelope" +msgstr "Kaku3 gutunazala" + +#: backend/lpd.c:178 +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR ostalaria edo inprimagailua" + +#: ppdc/sample.c:202 +msgid "Label Printer" +msgstr "Etiketen inprimagailua" + +#: ppdc/sample.c:417 +msgid "Label Top" +msgstr "Etiketaren goian" + +#: scheduler/ipp.c:2144 scheduler/ipp.c:6212 +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "\"%s\" hizkuntza ez dago onartuta." + +#: ppdc/sample.c:127 +msgid "Large Address" +msgstr "Helbide luzea" + +#: ppdc/sample.c:136 +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Helbide luzea - 1 4/10 x 3 1/2\"" + +#: ppdc/sample.c:262 +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet PCL 4/5 serieak" + +#: ppdc/sample.c:208 +msgid "Light" +msgstr "Argia" + +#: cups/ppd.c:349 +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Lerroa baimendutako gehienezkoa (255 karaktere) baino luzeagoa" + +#: cgi-bin/admin.c:2362 +msgid "List Available Printers" +msgstr "Inprimagailu erabilgarrien zerrenda" + +#: filter/bannertops.c:744 +msgid "Location: " +msgstr "Kokalekua: " + +#: ppdc/sample.c:244 +msgid "Long-Edge (Portrait)" +msgstr "Ertz-luzea (bertikala)" + +#: filter/bannertops.c:753 +msgid "Make and Model: " +msgstr "Marka eta modeloa: " + +#: ppdc/sample.c:240 +msgid "Manual Feed" +msgstr "Eskuzko iturria" + +#: filter/bannertops.c:780 +msgid "Media Dimensions: " +msgstr "Paperaren dimentsioak: " + +#: filter/bannertops.c:800 +msgid "Media Limits: " +msgstr "Paperaren mugak: " + +#: filter/bannertops.c:769 +msgid "Media Name: " +msgstr "Paperaren izena: " + +#: cups/ppd.c:747 cups/ppd.c:1285 +msgid "Media Size" +msgstr "Paperaren tamaina" + +#: cups/ppd.c:751 cups/ppd.c:1289 ppdc/sample.c:234 +msgid "Media Source" +msgstr "Paperaren iturria" + +#: ppdc/sample.c:335 +msgid "Media Tracking" +msgstr "Paperaren jarraipena" + +#: cups/ppd.c:749 cups/ppd.c:1287 ppdc/sample.c:256 +msgid "Media Type" +msgstr "Paper mota" + +#: cups/localize.c:310 +msgid "Media jam!" +msgstr "Paper gatazka!" + +#: cups/localize.c:327 +msgid "Media tray almost empty." +msgstr "Paperen erretilua is hutsik." + +#: cups/localize.c:329 +msgid "Media tray empty!" +msgstr "Paperen erretilua hutsik!" + +#: cups/localize.c:325 +msgid "Media tray missing!" +msgstr "Paperen erretilua falta da!" + +#: cups/localize.c:308 +msgid "Media tray needs to be filled." +msgstr "Paperen erretilua bete egin behar da." + +#: ppdc/sample.c:209 +msgid "Medium" +msgstr "Euskarria" + +#: cups/ppd.c:338 +msgid "Memory allocation error" +msgstr "Errorea memoria esleitzean" + +#: cups/ppd.c:339 +msgid "Missing PPD-Adobe-4.x header" +msgstr "PPD-Adobe-4.x goiburukoa falta da" + +#: cups/ppd.c:348 +msgid "Missing asterisk in column 1" +msgstr "Izartxoa falta da 1. zutabean" + +#: scheduler/ipp.c:6684 +msgid "Missing document-number attribute!" +msgstr "document-number atributua falta da." + +#: cups/adminutil.c:284 +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Komatxo bikoitzak falta dira %d lerroan." + +#: cgi-bin/admin.c:2074 cgi-bin/admin.c:2159 cgi-bin/admin.c:2795 +#: cgi-bin/admin.c:3049 cgi-bin/admin.c:3160 cgi-bin/admin.c:3838 +msgid "Missing form variable!" +msgstr "Inprimakiaren aldagaia falta da." + +#: scheduler/ipp.c:7084 +msgid "Missing notify-subscription-ids attribute!" +msgstr "notify-subscription-ids atributua falta da." + +#: scheduler/ipp.c:3814 +msgid "Missing requesting-user-name attribute!" +msgstr "requesting-user-name atributua falta da." + +#: scheduler/ipp.c:477 +msgid "Missing required attributes!" +msgstr "Beharrezko atributuak falta dira." + +#: cups/adminutil.c:265 +#, c-format +msgid "Missing value on line %d!" +msgstr "Balioa falta da %d lerroan." + +#: cups/ppd.c:340 +msgid "Missing value string" +msgstr "Balioaren katea falta da" + +#: systemv/lpinfo.c:475 +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modeloa: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +#: cgi-bin/admin.c:480 +msgid "Modify Class" +msgstr "Aldatu klasea" + +#: cgi-bin/admin.c:772 +msgid "Modify Printer" +msgstr "Aldatu inprimagailua" + +#: ppdc/sample.c:111 +msgid "Monarch" +msgstr "Monarch" + +#: ppdc/sample.c:75 +msgid "Monarch Envelope" +msgstr "Monarch gutunazala" + +#: cgi-bin/ipp-var.c:421 cgi-bin/ipp-var.c:512 +msgid "Move All Jobs" +msgstr "Aldatu lan guztiak lekuz" + +#: cgi-bin/ipp-var.c:360 cgi-bin/ipp-var.c:419 cgi-bin/ipp-var.c:510 +msgid "Move Job" +msgstr "Aldatu lana lekuz" + +#: cups/http-support.c:1201 +msgid "Moved Permanently" +msgstr "Betirako lekuz aldatuta" + +#: backend/ipp.c:1090 +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: inptimatzeko fitxategia onartuta - lanaren IDa: %d.\n" + +#: backend/ipp.c:1084 +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: inptimatzeko fitxategia onartuta - lanaren IDa: ezezaguna.\n" + +#: cups/ppd.c:337 +msgid "NULL PPD file pointer" +msgstr "PPD fitxategiaren erakusle NULUA" + +#: cups/snmp.c:1054 +msgid "Name OID uses indefinite length" +msgstr "Izenaren OIDak definitu gabeko luzera darabil" + +#: ppdc/sample.c:401 +msgid "Never" +msgstr "Inoiz ere ez" + +#: ppdc/sample.c:228 +msgid "New Stylus Color Series" +msgstr "Stylus Color serie berriak" + +#: ppdc/sample.c:230 +msgid "New Stylus Photo Series" +msgstr "Stylus Photo serie berriak" + +#: cups/ppd.c:1877 +msgid "No" +msgstr "Ez" + +#: cups/http-support.c:1198 +msgid "No Content" +msgstr "Edukirik ez" + +#: cups/util.c:1289 +msgid "No PPD name!" +msgstr "PPD izenik ez." + +#: cups/snmp.c:1048 +msgid "No VarBind SEQUENCE" +msgstr "'VarBind SEQUENCE'-rik ez" + +#: cups/adminutil.c:799 +msgid "No Windows printer drivers are installed!" +msgstr "Ez daude Windows-eko inprimagailuen kontrolatzailerik instalatuta!" + +#: cups/request.c:509 cups/request.c:775 +msgid "No active connection" +msgstr "Ez dago konexio aktiborik" + +#: scheduler/ipp.c:3992 +#, c-format +msgid "No active jobs on %s!" +msgstr "Ez dago lan aktiborik %s(e)n." + +#: scheduler/ipp.c:318 +msgid "No attributes in request!" +msgstr "Ez dago atributurik eskaeran." + +#: scheduler/ipp.c:3719 +msgid "No authentication information provided!" +msgstr "Ez da autentifikatzeko informaziorik eman." + +#: cups/snmp.c:1005 +msgid "No community name" +msgstr "Ez dago komunitatearen izenik" + +#: scheduler/ipp.c:6484 +msgid "No default printer" +msgstr "Ez dago inprimagailu lehenetsirik" + +#: cgi-bin/ipp-var.c:432 scheduler/ipp.c:7660 +msgid "No destinations added." +msgstr "Ez da helbururik gehitu." + +#: cups/snmp.c:1035 +msgid "No error-index" +msgstr "Ez dago error-index parametroa" + +#: cups/snmp.c:1027 +msgid "No error-status" +msgstr "Ez dago error-status parametroa" + +#: scheduler/ipp.c:8576 scheduler/ipp.c:9811 +msgid "No file!?!" +msgstr "Fitxategirik ez?" + +#: cups/util.c:924 +msgid "No modification time!" +msgstr "Ez dago aldaketa-ordurik." + +#: cups/snmp.c:1052 +msgid "No name OID" +msgstr "Ez dago izenaren OIDrik" + +#: cups/util.c:918 +msgid "No printer name!" +msgstr "Ez dago inprimagailuaren izenik." + +#: cups/util.c:1840 +msgid "No printer-uri found for class!" +msgstr "Ez da printer-uri aurkitu klasearentzako" + +#: cups/util.c:1855 +msgid "No printer-uri found!" +msgstr "Ez da printer-uri aurkitu." + +#: scheduler/ipp.c:6869 +msgid "No printer-uri in request!" +msgstr "Ez da printer-uri aurkitu eskaeran." + +#: cups/snmp.c:1019 +msgid "No request-id" +msgstr "Ez dago request-id" + +#: scheduler/ipp.c:6097 +msgid "No subscription attributes in request!" +msgstr "Ez dago harpidetzako atributurik eskaeran." + +#: scheduler/ipp.c:7978 +msgid "No subscriptions found." +msgstr "Ez da harpidetzarik aurkitu." + +#: cups/snmp.c:1043 +msgid "No variable-bindings SEQUENCE" +msgstr "Ez dago 'variable-bindings SEQUENCE'-rik" + +#: cups/snmp.c:998 +msgid "No version number" +msgstr "Ez dago bertsioaren zenbakirik" + +#: ppdc/sample.c:338 +msgid "Non-continuous (Mark sensing)" +msgstr "Ez da jarraia (markaren detekzioa)" + +#: ppdc/sample.c:337 +msgid "Non-continuous (Web sensing)" +msgstr "Ez da jarraia (web detekzioa)" + +#: ppdc/sample.c:210 +msgid "Normal" +msgstr "Arrunta" + +#: cups/http-support.c:1220 +msgid "Not Found" +msgstr "Ez da aurkitu" + +#: cups/http-support.c:1232 +msgid "Not Implemented" +msgstr "Ez dago garatuta" + +#: ppdc/sample.c:248 +msgid "Not Installed" +msgstr "Ez dago instalatuta" + +#: cups/http-support.c:1207 +msgid "Not Modified" +msgstr "Ez dago aldatuta" + +#: cups/http-support.c:1235 +msgid "Not Supported" +msgstr "EZ dago onartuta" + +#: scheduler/ipp.c:1521 +msgid "Not allowed to print." +msgstr "Inprimatzea ez dago baimenduta." + +#: ppdc/sample.c:112 +msgid "Note" +msgstr "Oharra" + +#: cups/http-support.c:1189 cups/ppd.c:335 +msgid "OK" +msgstr "Ados" + +#: cups/localize.c:349 +msgid "OPC almost at end-of-life." +msgstr "OPCa ia agortuta." + +#: cups/localize.c:351 +msgid "OPC at end-of-life!" +msgstr "OPCa agortuta." + +#: ppdc/sample.c:243 +msgid "Off (1-Sided)" +msgstr "Desaktibatuta (1 aldea)" + +#: ppdc/sample.c:332 +msgid "Oki" +msgstr "Oki" + +#: cgi-bin/help.c:89 cgi-bin/help.c:130 cgi-bin/help.c:140 cgi-bin/help.c:171 +msgid "Online Help" +msgstr "Lineako laguntza" + +#: cups/adminutil.c:985 +#, c-format +msgid "Open of %s failed: %s" +msgstr "Huts egin du %s irekitzean: %s" + +#: cups/ppd.c:343 +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup aurreko CloseGroup-rik gabe" + +#: cups/ppd.c:345 +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI aurreko CloseUI/JCLCloseUI-rik gabe" + +#: cgi-bin/admin.c:3609 +msgid "Operation Policy" +msgstr "Eragiketaren politika" + +#: cgi-bin/admin.c:3286 cgi-bin/admin.c:3346 +msgid "Options Installed" +msgstr "Instalatutako aukerak" + +#: filter/bannertops.c:674 +msgid "Options: " +msgstr "Aukerak: " + +#: cups/localize.c:317 +msgid "Out of toner!" +msgstr "Tonerra agortuta!" + +#: cups/ppd.c:753 cups/ppd.c:1291 +msgid "Output Mode" +msgstr "Irteeraren modua" + +#: cups/localize.c:333 +msgid "Output bin almost full." +msgstr "Irteerako ontzia ia beteta." + +#: cups/localize.c:335 +msgid "Output bin full!" +msgstr "Irteerako ontzia beteta!" + +#: systemv/lpstat.c:1191 systemv/lpstat.c:1195 +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "%s inprimagailuarentzako irteera %s(e)ra bidalita\n" + +#: systemv/lpstat.c:1185 +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "" +"%s inprimagailuarentzako irteera urruneko %s inprimagailura bidalita %s(e)n\n" + +#: systemv/lpstat.c:1209 systemv/lpstat.c:1213 +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "%s/%s inprimagailuarentzako irteera %s(e)ra bidalita\n" + +#: systemv/lpstat.c:1203 +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"%s/%s inprimagailuarentzako irteera urruneko %s inprimagailura bidalita %s(e)" +"n\n" + +#: cups/localize.c:331 +msgid "Output tray missing!" +msgstr "Irteerako erretilua falta da." + +#: systemv/cupstestdsc.c:403 +msgid "PASS\n" +msgstr "BALIOZKOA\n" + +#: ppdc/sample.c:232 +msgid "PCL Laser Printer" +msgstr "PCL laser inprimagailua" + +#: ppdc/sample.c:77 +msgid "PRC1 Envelope" +msgstr "PRC1 gutunazala" + +#: ppdc/sample.c:86 +msgid "PRC10 Envelope" +msgstr "PRC10 gutunazala" + +#: ppdc/sample.c:114 +msgid "PRC16K" +msgstr "PRC16K" + +#: ppdc/sample.c:78 +msgid "PRC2 Envelope" +msgstr "PRC2 gutunazala" + +#: ppdc/sample.c:79 +msgid "PRC3 Envelope" +msgstr "PRC3 gutunazala" + +#: ppdc/sample.c:115 +msgid "PRC32K" +msgstr "PRC32K" + +#: ppdc/sample.c:116 +msgid "PRC32K (Oversize)" +msgstr "PRC32K (handiagoa)" + +#: ppdc/sample.c:80 +msgid "PRC4 Envelope" +msgstr "PRC4 gutunazala" + +#: ppdc/sample.c:81 +msgid "PRC5 Envelope" +msgstr "PRC5 gutunazala" + +#: ppdc/sample.c:82 +msgid "PRC6 Envelope" +msgstr "PRC6 gutunazala" + +#: ppdc/sample.c:83 +msgid "PRC7 Envelope" +msgstr "PRC7 gutunazala" + +#: ppdc/sample.c:84 +msgid "PRC8 Envelope" +msgstr "PRC8 gutunazala" + +#: ppdc/sample.c:85 +msgid "PRC9 Envelope" +msgstr "PRC9 gutunazala" + +#: cups/snmp.c:1015 +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Paketeak ez dauka Get-Response-PDU" + +#: cups/snmp.c:994 +msgid "Packet does not start with SEQUENCE" +msgstr "Paketeak ez da SEQUENCErekin hasten" + +#: ppdc/sample.c:331 +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +#: ppdc/sample.c:329 +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#: cups/auth.c:158 +#, c-format +msgid "Password for %s on %s? " +msgstr "%s(r)en pasahitza %s(e)n?" + +#: systemv/cupsaddsmb.c:256 +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "%s(r)en pasahitza behar da %s(e)n SAMBA bidez sarbidetzeko: " + +#: cgi-bin/classes.c:152 +msgid "Pause Class" +msgstr "Pausatu klasea" + +#: cgi-bin/printers.c:155 +msgid "Pause Printer" +msgstr "Pausatu inprimagailua" + +#: ppdc/sample.c:419 +msgid "Peel-Off" +msgstr "Altxatu" + +#: ppdc/sample.c:76 +msgid "Personal Envelope" +msgstr "Gutunazal pertsonala" + +#: ppdc/sample.c:123 +msgid "Photo" +msgstr "Argazkia" + +#: ppdc/sample.c:124 +msgid "Photo Labels" +msgstr "Argakien etiketak" + +#: ppdc/sample.c:257 +msgid "Plain Paper" +msgstr "Paper soila" + +#: cgi-bin/admin.c:3304 cgi-bin/admin.c:3558 +msgid "Policies" +msgstr "Politikak" + +#: cgi-bin/admin.c:3311 cgi-bin/admin.c:3627 cgi-bin/admin.c:3640 +msgid "Port Monitor" +msgstr "Atakaren monitorea" + +#: ppdc/sample.c:250 +msgid "PostScript Printer" +msgstr "PostScript inprimagailua" + +#: ppdc/sample.c:113 +msgid "Postcard" +msgstr "Postala" + +#: ppdc/sample.c:266 +msgid "Print Density" +msgstr "Inprimatze-dentsitatea" + +#: cups/notify.c:82 +msgid "Print Job:" +msgstr "Inprimatzeko lana:" + +#: ppdc/sample.c:311 +msgid "Print Mode" +msgstr "Inprimatze modua" + +#: ppdc/sample.c:354 +msgid "Print Rate" +msgstr "Inprimatze-emaria" + +#: cgi-bin/printers.c:164 +msgid "Print Self-Test Page" +msgstr "Inprimatu auto-probako orrialdea" + +#: ppdc/sample.c:298 +msgid "Print Speed" +msgstr "Inprimatzeko abiadura" + +#: cgi-bin/ipp-var.c:787 +msgid "Print Test Page" +msgstr "Inprimatu probako orrialdea" + +#: ppdc/sample.c:327 +msgid "Print and Cut" +msgstr "Inprimatu eta ebaki" + +#: ppdc/sample.c:315 +msgid "Print and Tear" +msgstr "Inprimatu eta altxatu" + +#: filter/bannertops.c:648 +msgid "Printed For: " +msgstr "Honentzako inprimatuta: " + +#: filter/bannertops.c:656 +msgid "Printed From: " +msgstr "Hemendik inprimatuta: " + +#: filter/bannertops.c:876 +msgid "Printed On: " +msgstr "Inprimatze-data: " + +#: cgi-bin/ipp-var.c:1042 +msgid "Printer Added" +msgstr "Inprimagailua gehituta" + +#: ppdc/sample.c:235 +msgid "Printer Default" +msgstr "Inprimagailu lehenetsia" + +#: cgi-bin/ipp-var.c:1046 +msgid "Printer Deleted" +msgstr "Inprimagailua ezabatuta" + +#: cgi-bin/ipp-var.c:1044 +msgid "Printer Modified" +msgstr "Inprimagailua aldatuta" + +#: filter/bannertops.c:614 +msgid "Printer Name: " +msgstr "Inprimagailuaren izena: " + +#: cgi-bin/ipp-var.c:1040 +msgid "Printer Paused" +msgstr "Inprimagailua pausatuta" + +#: ppdc/sample.c:265 +msgid "Printer Settings" +msgstr "Inprimagailuaren ezarpenak" + +#: cups/localize.c:313 +msgid "Printer offline." +msgstr "Inprimagailua lineaz kanpo." + +#: cups/notify.c:126 +msgid "Printer:" +msgstr "Inprimagailua:" + +#: cgi-bin/printers.c:189 cgi-bin/printers.c:317 +msgid "Printers" +msgstr "Inprimagailuak" + +#: cgi-bin/classes.c:158 cgi-bin/printers.c:161 +msgid "Purge Jobs" +msgstr "Garbitu lanak" + +#: ppdc/sample.c:117 +msgid "Quarto" +msgstr "Laurdena" + +#: scheduler/ipp.c:1516 +msgid "Quota limit reached." +msgstr "Kuotaren mugara iritsita." + +#: berkeley/lpq.c:507 +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Errenk. Jabea Lana Fitxategiak Tamaina osoa\n" + +#: berkeley/lpq.c:503 +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Errenk. Jabea Lehent. Lana Fitxategiak Tamaina osoa\n" + +#: cgi-bin/classes.c:156 cgi-bin/printers.c:159 +msgid "Reject Jobs" +msgstr "Ukatu lanak" + +#: ppdc/sample.c:399 +msgid "Reprint After Error" +msgstr "Inprimatu berriro erroreen ostean" + +#: cups/http-support.c:1223 +msgid "Request Entity Too Large" +msgstr "Eskaeraren entitatea luzeegia" + +#: cups/ppd.c:755 cups/ppd.c:1293 ppdc/sample.c:203 +msgid "Resolution" +msgstr "Bereizmena" + +#: cgi-bin/classes.c:150 +msgid "Resume Class" +msgstr "Jarraitu klasea" + +#: cgi-bin/printers.c:152 +msgid "Resume Printer" +msgstr "Jarraitu inprimagailua" + +#: ppdc/sample.c:128 +msgid "Return Address" +msgstr "Itzulerako helbidea" + +#: ppdc/sample.c:137 +msgid "Return Address - 3/4 x 2\"" +msgstr "Itzulerako helbidea - 3/4 x 2\"" + +#: ppdc/sample.c:420 +msgid "Rewind" +msgstr "Birboninatu" + +#: cups/adminutil.c:2167 +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Komandoa exekutaten: %s %s -N -A %s -c '%s'\n" + +#: backend/scsi-irix.c:70 backend/scsi-linux.c:83 +msgid "SCSI Printer" +msgstr "SCSI inprimagailua" + +#: cups/snmp.c:996 +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCEk definitu gabeko luzera darabil" + +#: cups/http-support.c:1204 +msgid "See Other" +msgstr "Ikusi besteak" + +#: backend/serial.c:784 backend/serial.c:943 backend/serial.c:1065 +#: backend/serial.c:1159 +#, c-format +msgid "Serial Port #%d" +msgstr "Serieko %d. ataka" + +#: cgi-bin/ipp-var.c:1056 +msgid "Server Restarted" +msgstr "Zerbitzaria berrabiarazita" + +#: cgi-bin/ipp-var.c:1062 +msgid "Server Security Auditing" +msgstr "Zerbitzariko segurtasun auditoretza" + +#: cgi-bin/ipp-var.c:1058 +msgid "Server Started" +msgstr "Zerbitzaria abiarazita" + +#: cgi-bin/ipp-var.c:1060 +msgid "Server Stopped" +msgstr "Zerbitzaria geldituta" + +#: cups/http-support.c:1241 +msgid "Service Unavailable" +msgstr "Zerbitzaria ez dago eskuragarri" + +#: cgi-bin/admin.c:2796 cgi-bin/admin.c:2842 cgi-bin/admin.c:2999 +#: cgi-bin/admin.c:3018 +msgid "Set Allowed Users" +msgstr "Ezarri baimendutako erabiltzaileak" + +#: cgi-bin/admin.c:3045 +msgid "Set As Server Default" +msgstr "Ezarri zerbitzari lehenetsi gisa" + +#: cgi-bin/admin.c:3145 +msgid "Set Class Options" +msgstr "Ezarri klasearen aukerak" + +#: cgi-bin/admin.c:3145 cgi-bin/admin.c:3314 cgi-bin/admin.c:3669 +msgid "Set Printer Options" +msgstr "Ezarri inprimagailuaren aukerak" + +#: cgi-bin/admin.c:3839 cgi-bin/admin.c:3883 cgi-bin/admin.c:3901 +msgid "Set Publishing" +msgstr "Argitaratu" + +#: ppdc/sample.c:129 +msgid "Shipping Address" +msgstr "Bidaltzeko helbidea" + +#: ppdc/sample.c:138 +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Bidaltzeko helbidea - 2 5/16 x 4\"" + +#: ppdc/sample.c:245 +msgid "Short-Edge (Landscape)" +msgstr "Ertz laburra (horizontala)" + +#: ppdc/sample.c:259 +msgid "Special Paper" +msgstr "Paper berezia" + +#: ppdc/sample.c:312 +msgid "Standard" +msgstr "Estandarra" + +#: cgi-bin/admin.c:3532 +msgid "Starting Banner" +msgstr "Hasierako titularra" + +#: ppdc/sample.c:118 +msgid "Statement" +msgstr "Instrukzioa" + +#: ppdc/sample.c:223 +msgid "Stylus Color Series" +msgstr "Stylus Color serieak" + +#: ppdc/sample.c:229 +msgid "Stylus Photo Series" +msgstr "Stylus Photo serieak" + +#: ppdc/sample.c:119 +msgid "Super A" +msgstr "Super A" + +#: ppdc/sample.c:120 +msgid "Super B" +msgstr "Super B" + +#: ppdc/sample.c:125 +msgid "Super B/A3" +msgstr "Super B/A3" + +#: cups/http-support.c:1186 +msgid "Switching Protocols" +msgstr "Protokoloak aldatzen" + +#: ppdc/sample.c:121 +msgid "Tabloid" +msgstr "Tabloidea" + +#: ppdc/sample.c:122 +msgid "Tabloid (Oversize)" +msgstr "Tabloidea (handiagoa)" + +#: ppdc/sample.c:313 +msgid "Tear" +msgstr "Altxatu" + +#: ppdc/sample.c:418 +msgid "Tear-Off" +msgstr "Altxatu" + +#: ppdc/sample.c:359 +msgid "Tear-Off Adjust Position" +msgstr "Altxatze-posizioaren doiketa" + +#: scheduler/ipp.c:7331 +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Ezin izan da \"%s\" PPD fitxategia aurkitu." + +#: scheduler/ipp.c:7318 +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Ezin izan da \"%s\" PPD fitxategia ireki: %s" + +#: cgi-bin/admin.c:638 +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Klasearen izenak inprimagarriak diren 127 karaktere sooilik eduki ditzake, " +"eta ezin du zuriune, barrak (/) edo traolaren (#) ikurrik eduki." + +#: scheduler/ipp.c:2171 +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "notify-lease-duration atributua ezin da erabili lanen harpidetzekin." + +#: scheduler/ipp.c:2154 scheduler/ipp.c:6222 +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "notify-user-data balioa handiegia da (%d > 63 zortzikote)!" + +#: cgi-bin/admin.c:821 +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Inprimagailuaren izenak inprimagarriak diren 127 karaktere sooilik eduki " +"ditzake, eta ezin du zuriune, barrak (/) edo traolaren (#) ikurrik eduki." + +#: scheduler/ipp.c:1351 +msgid "The printer or class is not shared!" +msgstr "Inprimagailua edo klasea ez dago partekatuta." + +#: scheduler/ipp.c:884 scheduler/ipp.c:1190 scheduler/ipp.c:3850 +#: scheduler/ipp.c:3958 scheduler/ipp.c:5753 scheduler/ipp.c:6056 +#: scheduler/ipp.c:6369 scheduler/ipp.c:6906 scheduler/ipp.c:7536 +#: scheduler/ipp.c:7592 scheduler/ipp.c:7905 scheduler/ipp.c:8147 +#: scheduler/ipp.c:8237 scheduler/ipp.c:8270 scheduler/ipp.c:8591 +#: scheduler/ipp.c:8982 scheduler/ipp.c:9062 scheduler/ipp.c:10203 +#: scheduler/ipp.c:10659 scheduler/ipp.c:10988 scheduler/ipp.c:11055 +#: scheduler/ipp.c:11338 +msgid "The printer or class was not found." +msgstr "Inprimagailua edo klasea ez da aurkitu." + +#: scheduler/ipp.c:990 scheduler/ipp.c:2361 +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "\"%s\" printer-uri atributuak baliogabeko karaktereak ditu." + +#: scheduler/ipp.c:3795 +msgid "The printer-uri attribute is required!" +msgstr "printer-uri atributua behar da." + +#: scheduler/ipp.c:974 +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"printer-uri \"ipp://OSTALARIIZENA/classes/KLASEIZENA\" erakoa izan behar du." + +#: scheduler/ipp.c:2345 +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"printer-uri \"ipp://OSTALARIIZENA/printers/INPRIMAGAILUIZENA\" erakoa izan " +"behar du." + +#: cgi-bin/admin.c:385 +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Harpidetzaren izenak inprimagarriak ezin du zuriune, barrak (/), galdera " +"ikurra (?) edo traolaren (#) ikurrik eduki." + +#: scheduler/ipp.c:6299 +msgid "There are too many subscriptions." +msgstr "Harpidetza gehiegi daude." + +#: ppdc/sample.c:406 +msgid "Thermal Transfer Media" +msgstr "Transferentzia termikoaren euskarria" + +#: filter/bannertops.c:640 +msgid "Title: " +msgstr "Titulua: " + +#: cups/localize.c:315 +msgid "Toner low." +msgstr "Tonerra baxua." + +#: scheduler/ipp.c:1510 +msgid "Too many active jobs." +msgstr "Lan aktibo gehiegi." + +#: scheduler/ipp.c:1448 +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "job-sheets balio gehiegi (%d > 2)." + +#: scheduler/ipp.c:2666 +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "printer-state-reasons balio gehiegi (%d > %d)." + +#: ppdc/sample.c:260 +msgid "Transparency" +msgstr "Gardentasuna" + +#: ppdc/sample.c:255 +msgid "Tray" +msgstr "Erretilua" + +#: ppdc/sample.c:236 +msgid "Tray 1" +msgstr "1. erretilua" + +#: ppdc/sample.c:237 +msgid "Tray 2" +msgstr "2. erretilua" + +#: ppdc/sample.c:238 +msgid "Tray 3" +msgstr "3. erretilua" + +#: ppdc/sample.c:239 +msgid "Tray 4" +msgstr "4. erretilua" + +#: cups/http-support.c:1226 +msgid "URI Too Long" +msgstr "URIa luzeegia" + +#: ppdc/sample.c:88 +msgid "US Executive" +msgstr "US exekutiboa" + +#: ppdc/sample.c:91 +msgid "US Fanfold" +msgstr "US Fanfold" + +#: ppdc/sample.c:105 +msgid "US Ledger" +msgstr "US Ledger" + +#: ppdc/sample.c:106 +msgid "US Legal" +msgstr "US legala" + +#: ppdc/sample.c:107 +msgid "US Legal (Oversize)" +msgstr "US legala (handiagoa)" + +#: ppdc/sample.c:108 +msgid "US Letter" +msgstr "US gutuna" + +#: ppdc/sample.c:109 +msgid "US Letter (Oversize)" +msgstr "US gutuna (handiagoa)" + +#: ppdc/sample.c:110 +msgid "US Letter (Small)" +msgstr "US gutuna (txikia)" + +#: backend/serial.c:797 +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB zerieko %d. ataka" + +#: cgi-bin/admin.c:1927 cgi-bin/admin.c:1940 cgi-bin/admin.c:1964 +msgid "Unable to access cupsd.conf file:" +msgstr "Ezin da cupsd.conf fitxategia atzitu:" + +#: cgi-bin/admin.c:437 +msgid "Unable to add RSS subscription:" +msgstr "Ezin da RSS harpidetza gehitu:" + +#: cgi-bin/admin.c:704 +msgid "Unable to add class:" +msgstr "Ezin da klasea gehitu:" + +#: scheduler/ipp.c:1554 +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Ezin da lana gehitu \"%s\" helbururako." + +#: cgi-bin/admin.c:953 cgi-bin/admin.c:1314 +msgid "Unable to add printer:" +msgstr "Ezin da inprimagailua gehitu:" + +#: scheduler/ipp.c:1296 +msgid "Unable to allocate memory for file types!" +msgstr "Ezin da memoria esleitu fitxategi motentzako." + +#: cgi-bin/admin.c:1420 +msgid "Unable to cancel RSS subscription:" +msgstr "Ezin da RSS harpidetza bertan behera utzi:" + +#: cgi-bin/admin.c:3884 +msgid "Unable to change printer-is-shared attribute:" +msgstr "Ezin da printer-is-shared atributua aldatu:" + +#: cgi-bin/admin.c:3000 +msgid "Unable to change printer:" +msgstr "Ezin da inprimagailua aldatu:" + +#: cgi-bin/admin.c:1604 cgi-bin/admin.c:1768 +msgid "Unable to change server settings:" +msgstr "Ezin dira zerbitzariaren ezarpenak aldatu:" + +#: cups/adminutil.c:941 cups/util.c:1652 +msgid "Unable to connect to host." +msgstr "Ezin da ostalariarekin konektatu." + +#: cups/adminutil.c:737 +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" +"Ezin dira 64 bit-eko CUPSeko inprimagailuen kontrolatzaileen fitxategiak " +"kopiatu (%d)." + +#: cups/adminutil.c:702 +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Ezin dira 64 bit-eko Windows-eko inprimagailuen kontrolatzaileen fitxategiak " +"kopiatu (%d)." + +#: cups/adminutil.c:533 +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "" +"Ezin dira CUPSeko inprimagailuen kontrolatzaileen fitxategiak kopiatu (%d)." + +#: scheduler/ipp.c:2782 +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Ezin da PPD fitxategia kopiatu: %s." + +#: scheduler/ipp.c:2848 +msgid "Unable to copy PPD file!" +msgstr "Ezin da PPD fitxategia kopiatu." + +#: cups/adminutil.c:498 +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"Ezin dira Windows 2000ko inprimagailuen kontrolatzaileen fitxategiak kopiatu " +"(%d)." + +#: cups/adminutil.c:621 +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" +"Ezin dira Windows 9x sistemako inprimagailuen kontrolatzaileen fitxategiak " +"kopiatu (%d)." + +#: scheduler/ipp.c:2759 +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Ezin da interfazeko script-a kopiatu: %s." + +#: cups/util.c:607 cups/util.c:1711 +msgid "Unable to create printer-uri!" +msgstr "Ezin da printer-uri sortu." + +#: cgi-bin/admin.c:1818 cgi-bin/admin.c:1830 +msgid "Unable to create temporary file:" +msgstr "Ezin da aldi baterako fitxategia sortu:" + +#: cgi-bin/admin.c:2121 +msgid "Unable to delete class:" +msgstr "Ezin da klasea ezabatu:" + +#: cgi-bin/admin.c:2206 +msgid "Unable to delete printer:" +msgstr "Ezin da inprimagailua ezabatu:" + +#: cgi-bin/classes.c:245 cgi-bin/printers.c:254 +msgid "Unable to do maintenance command:" +msgstr "Ezin da mantenimenduko komandoa landu:" + +#: cgi-bin/admin.c:1942 +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Ezin dira 1 MB baino handiagoak diren cupsd.conf fitxategiak editatu." + +#: cgi-bin/ipp-var.c:361 +msgid "Unable to find destination for job!" +msgstr "Ezin da helburua aurkitu lanarentzako." + +#: cups/http-support.c:1480 +msgid "Unable to find printer!\n" +msgstr "Ezin da inprimagailua aurkitu.\n" + +#: cgi-bin/classes.c:435 +msgid "Unable to get class list:" +msgstr "Ezin da klaseen zerrenda lortu:" + +#: cgi-bin/classes.c:534 +msgid "Unable to get class status:" +msgstr "Ezin da klasearen egoera lortu:" + +#: cgi-bin/admin.c:1215 +msgid "Unable to get list of printer drivers:" +msgstr "Ezin da inprimagailuen kontrolatzaileen zerrenda lortu:" + +#: cgi-bin/admin.c:2850 +msgid "Unable to get printer attributes:" +msgstr "Ezin dira inprimagailuaren atributuak lortu:" + +#: cgi-bin/printers.c:452 +msgid "Unable to get printer list:" +msgstr "Ezin da inprimagailuen zerrenda lortu:" + +#: cgi-bin/printers.c:554 +msgid "Unable to get printer status:" +msgstr "Ezin da inprimagailuaren egoera lortu:" + +#: cups/adminutil.c:576 cups/adminutil.c:780 +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Ezin dira Windows 2000ko inprimagailuen kontrolatzaileen fitxategiak " +"instalatu (%d)." + +#: cups/adminutil.c:650 +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"Ezin dira Windows 9x sistemako inprimagailuen kontrolatzaileen fitxategiak " +"instalatu (%d)." + +#: cgi-bin/admin.c:703 +msgid "Unable to modify class:" +msgstr "Ezin da klasea eraldatu:" + +#: cgi-bin/admin.c:952 cgi-bin/admin.c:1313 +msgid "Unable to modify printer:" +msgstr "Ezin da inprimagailua eraldatu:" + +#: cgi-bin/ipp-var.c:428 cgi-bin/ipp-var.c:517 +msgid "Unable to move job" +msgstr "Ezin da lana lekuz aldatu" + +#: cgi-bin/ipp-var.c:430 cgi-bin/ipp-var.c:519 +msgid "Unable to move jobs" +msgstr "Ezin dira lanak lekuz aldatu" + +#: cups/ppd.c:336 +msgid "Unable to open PPD file" +msgstr "Ezin da PPD fitxategia ireki" + +#: cgi-bin/admin.c:3196 +msgid "Unable to open PPD file:" +msgstr "Ezin da PPD fitxategia ireki:" + +#: cgi-bin/admin.c:2576 +msgid "Unable to open cupsd.conf file:" +msgstr "Ezin da cupsd.conf fitxategia ireki:" + +#: scheduler/ipp.c:6704 +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Ezin da %d. dokumentua ireki %d. lanean." + +#: cgi-bin/ipp-var.c:790 +msgid "Unable to print test page:" +msgstr "Ezin da probako orrialdea inprimatu:" + +#: cups/adminutil.c:2198 +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Ezin da \"%s\" exekutatu: %s\n" + +#: cgi-bin/ipp-var.c:594 cgi-bin/ipp-var.c:614 +msgid "Unable to send command to printer driver!" +msgstr "Ezin da komandoa bidali inprimagailuaren kontrolatzaileari." + +#: cups/adminutil.c:832 +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Ezin da Windows-eko inprimagailuaren kontrolatzailea ezarri (%d)." + +#: cgi-bin/admin.c:3785 +msgid "Unable to set options:" +msgstr "Ezin dira aukerak ezarri:" + +#: cgi-bin/admin.c:3087 +msgid "Unable to set server default:" +msgstr "Ezain da zerbitzari lehenetsia ezarri:" + +#: cgi-bin/admin.c:1880 +msgid "Unable to upload cupsd.conf file:" +msgstr "Ezin da cupsd.conf fitxategia igo:" + +#: backend/usb-darwin.c:1944 backend/usb-darwin.c:1966 +msgid "Unable to use legacy USB class driver!\n" +msgstr "Ezin da USB klaseko kontrolatzaile zaharkitua erabili.\n" + +#: cups/http-support.c:1214 +msgid "Unauthorized" +msgstr "Autorizaziorik ez" + +#: cgi-bin/admin.c:3485 +msgid "Units" +msgstr "Unitateak" + +#: cups/http-support.c:1248 cups/ppd.c:360 +msgid "Unknown" +msgstr "Ezezaguna" + +#: scheduler/ipp.c:10861 +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "\"%s\" printer-error-policy ezezaguna." + +#: scheduler/ipp.c:10844 +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "\"%s\" printer-op-policy ezezaguna." + +#: scheduler/ipp.c:418 +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Onartu gabeko \"%s\" karaktere-jokoa." + +#: scheduler/ipp.c:8557 scheduler/ipp.c:9792 +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Onartu gabeko \"%s\" konpresioa." + +#: scheduler/ipp.c:11291 +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Onartu gabeko %s konpresio atributua." + +#: scheduler/ipp.c:11319 +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Onartu gabeko \"%s\" formatua." + +#: scheduler/ipp.c:1414 scheduler/ipp.c:9926 +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Onartu gabeko '%s' formatua." + +#: scheduler/ipp.c:8691 scheduler/ipp.c:9909 +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Onartu gabeko '%s/%s' formatua." + +#: cups/snmp.c:1113 +msgid "Unsupported value type" +msgstr "Onartu gabeko balio mota" + +#: cups/http-support.c:1229 +msgid "Upgrade Required" +msgstr "Eguneratu egin behar da" + +#: systemv/lpadmin.c:805 +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Erabilera:\n" +"\n" +" lpadmin [-h zerbitzaria] -d helburua\n" +" lpadmin [-h zerbitzaria] -x helburua\n" +" lpadmin [-h zerbitzaria] -p inprimagailua [-c klasea_gehitzeko] [-i " +"interfazea] [-m modeloa]\n" +" [-r klasea_kentzeko] [-v gailua] [-D deskripzioa]\n" +" [-P ppd-fitxategia] [-o izena=balioa]\n" +" [-u allow:erabiltzailea,erabiltzailea] [-u deny:" +"erabiltzailea,erabiltzailea]\n" +"\n" + +#: filter/pdftops.c:103 +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "" +"Erabilera: %s lana erabiltzailea titulua kopiak aukerak [fitxategi-izena]\n" + +#: backend/ipp.c:212 backend/lpd.c:184 backend/pap.c:228 +#: backend/parallel.c:127 backend/scsi.c:157 backend/serial.c:165 +#: backend/socket.c:132 backend/usb.c:183 filter/bannertops.c:118 +#: filter/hpgl-main.c:148 filter/imagetops.c:115 filter/imagetoraster.c:207 +#: filter/pstops.c:255 filter/rastertoepson.c:988 filter/rastertohp.c:713 +#: filter/rastertolabel.c:1135 filter/textcommon.c:518 +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "" +"Erabilera: %s lanaren_IDa erabiltzailea titulua kopiak aukerak [fitxategi-" +"izena]\n" + +#: filter/gziptoany.c:53 +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "" +"Erabilera: %s lanaren_IDa erabiltzailea titulua kopiak aukerak fitxategia\n" + +#: scheduler/cupsfilter.c:1316 +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" +"Erabilera: convert [ Aukerak ]\n" +"\n" +"Aukerak:\n" +" -e Erabili PPD fitxategiko iragazki bakoitza\n" +" -f fitxategi-izena Ezarri fitxategia bihurtzeko (bestela stdin)\n" +" -o fitxategi-izena Ezarri fitxategia sortzeko (bestela stdout)\n" +" -i mime/mota Ezarri sarrerako MIME mota (bestela mota " +"automatikoa)\n" +" -j mime/mota Ezarri irteerako MIME mota (bestela application/pdf)\n" +" -P fitxategi-izena.ppd Ezarri PPD fitxategia\n" +" -a 'izena=balioa ...' Ezarri aukerak\n" +" -U erabiltzaile-izena Ezarri lanaren erabiltzaile-izena\n" +" -J titulua Ezarri titulua\n" +" -c kopiak Ezarri kopia kopurua\n" +" -u Kendu PPD fitxategia amaitutakoan\n" +" -D Kendu sarrerako fitxategia amaitutakoan\n" + +#: systemv/cupsaddsmb.c:286 +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Erabilera: cupsaddsmb [aukerak] inprimagailua1 ... inprimagailuaN\n" +" cupsaddsmb [aukerak] -a\n" +"\n" +"Aukerak:\n" +" -E Enkriptatu zerbitzarirako konexioa\n" +" -H samba-zerbitzaria Erabili izendatutako SAMBA zerbitzaria\n" +" -U samba-erabiltzailea Autentifikatu izendatutako SAMBAko erabiltzailea " +"erabiliz\n" +" -a Esportatu inprimagailu guztiak\n" +" -h cups-zerbitzaria Erabili izendatutako CUPS zerbitzaria\n" +" -v Hitzez hitz (erakutsi komandoak)\n" + +#: systemv/cupsctl.c:202 +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Erabilera: cupsctl [aukerak] [param=balioa ... paramN=balioaN]\n" +"\n" +"Aukerak:\n" +"\n" +" -E Gaitu enkriptatzea\n" +" -U erabiltzaile-izena Zehaztu erabiltzaile-izena\n" +" -h zerbitzaria[:ataka] Zehaztu zerbitzariaren helbidea\n" +"\n" +" --[no-]debug-logging Txandakatu arazketaren erregistroak aktibatzea/" +"desaktibatzea\n" +" --[no-]remote-admin Txandakatu urruneko administrazioa aktibatzea/" +"desaktibatzea\n" +" --[no-]remote-any Baimendu/Saihestu atzitzea Internetetik\n" +" --[no-]remote-printers Erakutsi/Ezkutatu urruneko inprimagailuak\n" +" --[no-]share-printers Baimendu/Saihestu inprimagailua partekatzea\n" +" --[no-]user-cancel-any Baimendu/Saihestu erabiltzaileek edozer lan " +"bertan behera uztea\n" + +#: scheduler/main.c:2128 +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Erabilera: cupsd [-c konfigurazio-fitxategia] [-f] [-F] [-h] [-l]\n" +"\n" +"-c konfigurazio-fitxategia Kargatu konfigurazioko beste fitxategi bat\n" +"-f Exekutatu aurreko planoan\n" +"-F Exekutatu aurreko planoan baina bereiztuta\n" +"-h Erakutsi erabileraren mezu hau\n" +"-l Exekutatu cupsd launchd(8)-etik\n" + +#: scheduler/cupsfilter.c:1303 +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" +"Erabilera: cupsfilter -m mime/mota [ aukerak ] fitxategi-izena\n" +"\n" +"Aukerak:\n" +"\n" +" -c cupsd.conf Ezarri cupsd.conf fitxategia erabiltzeko\n" +" -e Erabili PPD fitxategiko iragazki bakoitza\n" +" -j lanaren-id[,N] Iragazi N fitxategia zehaztutako lanetik (lehenetsia " +"1. fitxategia da)\n" +" -n kopiak Ezarri kopia kopurua\n" +" -o izena=balioa Ezarri aukerak\n" +" -p fitxategi-izena.ppd Ezarri PPD fitxategia\n" +" -t titulua Ezarri titulua\n" + +#: systemv/cupstestdsc.c:430 +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Erabilera: cupstestdsc [aukerak] fitxategi-izena.ps [... fitxategi-izena." +"ps]\n" +" cupstestdsc [aukerak] -\n" +"\n" +"Aukerak:\n" +"\n" +" -h Erakutsi programaren erabilera\n" +"\n" +" Oharra: programa honek DSC iruzkinak soilik balidatzen ditu, ez " +"PostScript bera.\n" + +#: systemv/cupstestppd.c:3483 +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" +"Erabilera: cupstestppd [aukerak] fitxategia1.ppd[.gz] [... fitxategia.ppd[." +"gz]]\n" +" programa | cupstestppd [aukerak] -\n" +"\n" +"Aukerak:\n" +"\n" +" -R erroko-direktorioa Ezarri beste erro bat\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Igorri abisuak erroreen ordez\n" +" -q Exekutatu isilean\n" +" -r Erabili modu ireki 'lasaia'\n" +" -v Erakutsi xehetasun piskatekoa\n" +" -vv Xehetasun askokoa\n" + +#: systemv/lpmove.c:132 +msgid "Usage: lpmove job/src dest\n" +msgstr "Erabilera: lpmove lana/iturria helburua\n" + +#: systemv/lpoptions.c:540 +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Erabilera: lpoptions [-h zerbitzaria] [-E] -d inprimagailua\n" +" lpoptions [-h zerbitzaria] [-E] [-p inprimagailua] -l\n" +" lpoptions [-h zerbitzaria] [-E] -p inprimagailua -o aukera" +"[=balioa] ...\n" +" lpoptions [-h zerbitzaria] [-E] -x inprimagailua\n" + +#: systemv/lppasswd.c:493 +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Erabilera: lppasswd [-g talde-izena]\n" + +#: systemv/lppasswd.c:496 +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Erabilera: lppasswd [-g talde-izena] [erabiltzaile-izena]\n" +" lppasswd [-g talde-izena] -a [erabiltzaile-izena]\n" +" lppasswd [-g talde-izena] -x [erabiltzaile-izena]\n" + +#: berkeley/lpq.c:662 +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Erabilera: lpq [-P helb] [-U erab-izena] [-h ostalari-izena[:ataka]] [-l] " +"[+barrutia]\n" + +#: ppdc/ppdc.cxx:392 +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Erabilera: ppdc [aukerak] fitxategia.drv [ ... fitxategiaN.drv ]\n" +"\n" +"Aukerak:\n" +" -D izena=balioa Ezarri izendatutako aldagaia balioarekin.\n" +" -I include-dir Gehitu include direktorioa bilaketako bide-izenari.\n" +" -c katalogoa.po Kargatu zehaztutako mezuen katalogoa.\n" +" -d irteerako-dir Zehaztu irteerako direktorioa.\n" +" -l hizk[,hizk,...] Zehaztu irteerako hizkuntzak (lokalak).\n" +" -m Erabili ModelName balioa fitxategi-izen gisa.\n" +" -t Probatu PPDak, haiek sortu ordez.\n" +" -v Hitzez hitz (zenbat eta 'v' gehiago, xehetasun " +"gehiago).\n" +" -z Konprimitu PPD fitxategiak GNU zip erabiliz.\n" +" --cr Amaitu lerroak CRrekin (Mac OS 9).\n" +" --crlf Amaitu lerroak CR + LFrekin (Windows).\n" +" --lf Amaitu lerroak LFrekin (UNIX/Linux/Mac OS X).\n" + +#: ppdc/ppdhtml.cxx:173 +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Erabilera: ppdhtml [aukerak] fitxategia.drv >fitxategia.html\n" +" -D izena=balioa Ezarri izendatutako aldagaia balioarekin.\n" +"Aukerak:\n" +" -I include-dir Gehitu include direktorioa bilaketako bide-izenari.\n" + +#: ppdc/ppdi.cxx:129 +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Erabilera: ppdi [aukerak] fitxategia.ppd [ ... fitxategiaN.ppd ]\n" +"Aukerak:\n" +" -I include-dir\n" +" -o fitxategia.drv\n" + +#: ppdc/ppdmerge.cxx:370 +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Erabilera: ppdmerge [aukerak] fitxategia.ppd [ ... fitxategiaN.ppd ]\n" +"Aukerak:\n" +" -o fitxategia.ppd[.gz]\n" + +#: ppdc/ppdpo.cxx:254 +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Erabilera: ppdpo [aukerak] -o fitxategia.po fitxategia.drv [ ... fitxategiaN." +"drv ]\n" +"Aukerak:\n" +" -D izena=balioa Ezarri izendatutako aldagaia balioarekin.\n" +" -I include-dir Gehitu include direktorioa bilaketako bide-izenari.\n" +" -v Hitzez hitz (zenbat eta 'v' gehiago, xehetasun " +"gehiago).\n" + +#: backend/snmp.c:224 +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Erabilera: snmp [ostalari-edo-ip-helbidea]\n" + +#: cups/snmp.c:1065 +msgid "Value uses indefinite length" +msgstr "Balioak definitu gabeko luzera darabil" + +#: cups/snmp.c:1050 +msgid "VarBind uses indefinite length" +msgstr "VarBind-ek definitu gabeko luzera darabil" + +#: cups/snmp.c:1000 +msgid "Version uses indefinite length" +msgstr "Bertsioak definitu gabeko luzera darabil" + +#: backend/pap.c:328 +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: aurkitutako aurreneko %d inprimagailu gehitzen" + +#: backend/pap.c:1460 backend/usb-darwin.c:1807 +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: \"%s\" waitof aukeran boolear bat espero zen\n" + +#: backend/network.c:83 backend/pap.c:1293 backend/parallel.c:638 +#: backend/serial.c:1297 backend/usb-libusb.c:747 backend/usb-unix.c:583 +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: huts egin du albo-kanaleko eskaera irakurtzean\n" + +#: filter/pstops.c:2237 +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: \"%s\" aukera ezin da sartu IncludeFeature bidez\n" + +#: backend/pap.c:503 +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: inprimagailuak ez du erantzuten\n" + +#: backend/pap.c:831 backend/pap.c:854 +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: inprimagailuak ustekabeko EOF bidali du\n" + +#: backend/lpd.c:616 +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: urruneko ostalariak ez du erantzun komandoaren egoeraren bytearekin %" +"d segundo ondoren\n" + +#: backend/lpd.c:1040 backend/lpd.c:1187 +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: urruneko ostalariak ez du erantzun kotroleko egoeraren bytearekin %d " +"segundo ondoren\n" + +#: backend/lpd.c:1132 +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: urruneko ostalariak ez du erantzun datuen egoeraren bytearekin %d " +"segundo ondoren\n" + +#: backend/scsi-irix.c:210 backend/scsi-linux.c:228 +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "" +"WARNING: SCSI komandoak denboraren muga gainditu du (%d). Berriro " +"saiatzen...\n" + +#: filter/pstops.c:1096 +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: dokumentu hau ez dator bat Abode Document Structuring Conventions-" +"eko zehaztapenekin, eta ez da ongi inprimatuko.\n" + +#: backend/pap.c:492 +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: ezin da \"%s:%s\" ireki: %s\n" + +#: backend/pap.c:637 +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: ezin da PAP egoeraren eskaera bidali" + +#: backend/pap.c:867 +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: ustekabeko PAP paketea %d motakoa\n" + +#: backend/pap.c:872 +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: %d motako PAP pakete ezezaguna\n" + +#: filter/pstops.c:2245 +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: \"%s\" hautaketa ezezaguna \"%s\" aukeran\n" + +#: filter/pstops.c:2230 +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: \"%s\" aukera ezezaguna\n" + +#: backend/serial.c:380 +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: %s baudio-emaria onartu gabea\n" + +#: backend/pap.c:1474 +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: zenbakia espero en \"%s\" egoeraren aukeran\n" + +#: backend/ipp.c:593 backend/ipp.c:724 backend/lpd.c:853 backend/socket.c:320 +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: berreskuratu daiteke. Sareko '%s' ostalaria lanpetuta dago. Berriro " +"saiatuko da %d segundo barru...\n" + +#: cups/adminutil.c:804 +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "" +"Abisua, ez dago Windows 2000 sistemako inprimagailuen kontrolatzailerik " +"instalatuta." + +#: cups/ppd.c:1875 +msgid "Yes" +msgstr "Bai" + +#: scheduler/client.c:2402 +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Orrialde hau honako URLan atxitu deakezu: https://%s:%d%s." + +#: ppdc/sample.c:87 +msgid "You4 Envelope" +msgstr "You4 gutunazala" + +#: ppdc/sample.c:410 +msgid "ZPL Label Printer" +msgstr "ZPL etiketen inprimagailua" + +#: ppdc/sample.c:333 +msgid "Zebra" +msgstr "Zebra" + +#: cups/notify.c:102 +msgid "aborted" +msgstr "abortatuta" + +#: cups/notify.c:99 +msgid "canceled" +msgstr "bertan behera utzita" + +#: cups/notify.c:105 +msgid "completed" +msgstr "burututa" + +#: scheduler/cupsfilter.c:342 +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: erabili -f aukera bihurtzea nahi den fitxategia zehazteko.\n" + +#: scheduler/ipp.c:6577 +msgid "cups-deviced failed to execute." +msgstr "cups-deviced programak huts egin du exekutatzean." + +#: scheduler/ipp.c:7253 scheduler/ipp.c:7503 +msgid "cups-driverd failed to execute." +msgstr "cups-driverd programak huts egin du exekutatzean." + +#: systemv/cupsaddsmb.c:236 +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "" +"cupsaddsmb: ez dago PPD fitxategirik \"%s\" inprimagailuarentzako: %s\n" + +#: systemv/cupsctl.c:153 +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: ezin da zerbitzariarekin konektatu: %s\n" + +#: systemv/cupsctl.c:196 +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: \"%s\" aukera ezezaguna.\n" + +#: systemv/cupsctl.c:198 +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: \"-%c\" aukera ezezaguna.\n" + +#: scheduler/main.c:200 +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "" +"cupsd: konfigurazioko fitxategia espero zen \"-c\" aukeraren ondoren.\n" + +#: scheduler/main.c:232 scheduler/main.c:239 +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: ezin da uneko direktorioa lortu.\n" + +#: scheduler/main.c:303 +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: \"%s\" argumentu ezezaguna. Abortatzen.\n" + +#: scheduler/main.c:296 +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: \"%c\" aukera ezezaguna. Abortatzen.\n" + +#: scheduler/main.c:266 +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: ez da launchd(8) euskarriarekin konpilatu. Modu arruntean " +"exekutatzen.\n" + +#: scheduler/cupsfilter.c:1081 +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: baliogabeko %d dokumentu-zenbakia.\n" + +#: scheduler/cupsfilter.c:1075 +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: baliogabeko %d lanaren IDa.\n" + +#: scheduler/cupsfilter.c:350 +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: fitxategi-izen bakarra soilik zehaztu daiteke.\n" + +#: scheduler/cupsfilter.c:1123 +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: ezin da lanaren fitxategia lortu: %s\n" + +#: systemv/cupstestppd.c:389 +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: -q aukera ez da bateragarria -v aukerarekin.\n" + +#: systemv/cupstestppd.c:405 +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: -v aukera ez da bateragarria -q aukerarekin.\n" + +#: systemv/lpstat.c:1231 systemv/lpstat.c:1234 systemv/lpstat.c:1237 +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "%s/%s(r)en gailua: %s\n" + +#: systemv/lpstat.c:1218 systemv/lpstat.c:1221 systemv/lpstat.c:1224 +#, c-format +msgid "device for %s: %s\n" +msgstr "%s(r)en gailua: %s\n" + +#: cups/snmp.c:1037 +msgid "error-index uses indefinite length" +msgstr "'error-index'-ek definitu gabeko luzera darabil" + +#: cups/snmp.c:1029 +msgid "error-status uses indefinite length" +msgstr "'error-status'-ek definitu gabeko luzera darabil" + +#: cups/notify.c:90 +msgid "held" +msgstr "eutsita" + +#: berkeley/lpc.c:214 +msgid "help\t\tget help on commands\n" +msgstr "help\t\tkomandoei buruzko laguntza eskaintzen du\n" + +#: cups/notify.c:131 +msgid "idle" +msgstr "inaktibo" + +#: scheduler/ipp.c:8226 +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri atributua falta da." + +#: systemv/lpadmin.c:141 systemv/lpadmin.c:453 +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "" +"lpadmin: klasearen izenak karaktere inprimagarriak soilik eduki ditzake.\n" + +#: systemv/lpadmin.c:750 +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: PPDa espero zen '-P' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:491 +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "" +"lpadmin: Expected alerabiltzaile-zerrenda espero zen st afaukeraren " +"ondoren.\n" +"option!\n" + +#: systemv/lpadmin.c:442 +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: klasea espero zen '-r' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:130 +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: klasearen izena espero zen '-c' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:643 +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: deskripzioa espero zen '-D' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:550 +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: gailuaren URIa espero zen '-v' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:659 +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: fitxategi motak espero ziren '-I' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:212 +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: ostalari-izena espero zen '-h' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:257 +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: interfazea espero zen '-i' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:704 +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: kokalekua espero zen '-L' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:338 +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: modeloa espero zen '-m' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:358 +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: izena=balioa espero zen '-o' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:391 +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: inprimagailua espero zen '-p' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:174 +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: inprimagailuaren izena espero zen '-d' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:584 +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: inprimagailua edo klasea espero zen '-x' aukeraren ondoren.\n" + +#: systemv/lpadmin.c:1128 +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: ez da kideen izenik ikusi.\n" + +#: systemv/lpadmin.c:893 +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: %s inprimagailua jadanik %s klasearen kidea da.\n" + +#: systemv/lpadmin.c:1142 +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: %s inprimagailua ez da %s klaseko kidea.\n" + +#: systemv/lpadmin.c:185 systemv/lpadmin.c:402 systemv/lpadmin.c:595 +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "" +"lpadmin: inprimagailuaren izenak karaktere inprimagarriak soilik eduki " +"ditzake.\n" + +#: systemv/lpadmin.c:115 +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da inprimagailua klaseari gehitu:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:106 systemv/lpadmin.c:159 systemv/lpadmin.c:230 +#: systemv/lpadmin.c:291 systemv/lpadmin.c:310 systemv/lpadmin.c:376 +#: systemv/lpadmin.c:417 systemv/lpadmin.c:523 systemv/lpadmin.c:569 +#: systemv/lpadmin.c:615 systemv/lpadmin.c:677 systemv/lpadmin.c:723 +#: systemv/lpadmin.c:784 +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: ezin da zerbitzariarekin konektatu: %s\n" + +#: systemv/lpadmin.c:1851 +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: ezin da \"%s\" PPD fitxategia ireki: %s\n" + +#: systemv/lpadmin.c:1460 +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: ezin da \"%s\" fitxategia ireki: %s\n" + +#: systemv/lpadmin.c:426 +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da inprimagailua klasetik kendu:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:732 +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da PPD fitxategia ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:532 +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da gailuaren URIa ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:319 +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da interfazearen script-a edo PPD fitxategia ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:239 +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da interfazearen script-a ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:624 +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da inprimagailuaren deskripzioa ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:686 +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin da inprimagailuaren kokalekua ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:793 +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: ezin dira inprimagailuaren aukerak ezarri:\n" +" Aurrenik inprimagailuaren izena zehaztu behar duzu.\n" + +#: systemv/lpadmin.c:508 +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: \"%s\" allow/deny aukera ezezaguna.\n" + +#: systemv/lpadmin.c:766 +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: '%s' argumentu ezezaguna.\n" + +#: systemv/lpadmin.c:761 +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: '%c' aukera ezezaguna.\n" + +#: systemv/lpadmin.c:665 +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: abisua - edukiaren moten zerrendari ezikusi egin zaio.\n" + +#: berkeley/lpc.c:81 berkeley/lpc.c:109 berkeley/lpc.c:145 +msgid "lpc> " +msgstr "lpc> " + +#: systemv/lpinfo.c:143 +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" +"lpinfo: 1284 gailuaren IDaren katea espero zen --device-id aukeraren " +"ondoren.\n" + +#: systemv/lpinfo.c:196 +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: hizkuntza espero zen --language aukeraren ondoren.\n" + +#: systemv/lpinfo.c:213 +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "" +"lpinfo: marka eta modeloa espero ziren --make-and-model aukeraren ondoren.\n" + +#: systemv/lpinfo.c:230 +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: produktuaren katea espero zen --product aukeraren ondoren.\n" + +#: systemv/lpinfo.c:161 +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "" +"lpinfo: eskemen zerrenda espero zen --exclude-schemes aukeraren ondoren.\n" + +#: systemv/lpinfo.c:179 +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "" +"lpinfo: eskemen zerrenda espero zen --include-schemes aukeraren ondoren.\n" + +#: systemv/lpinfo.c:247 +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: denbora-muga espero zen --timeout aukeraren ondoren.\n" + +#: systemv/lpinfo.c:270 +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: '%s' argumentu ezezaguna.\n" + +#: systemv/lpinfo.c:264 +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: '%c' aukera ezezaguna.\n" + +#: systemv/lpinfo.c:257 +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: '%s' aukera ezezaguna.\n" + +#: systemv/lpmove.c:141 +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: ezin da zerbitzariarekin konektatu: %s\n" + +#: systemv/lpmove.c:125 +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: '%s' argumentu ezezaguna.\n" + +#: systemv/lpmove.c:103 +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: '%c' aukera ezezaguna.\n" + +#: systemv/lpoptions.c:154 systemv/lpoptions.c:172 systemv/lpoptions.c:248 +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: inprimagailurik ez?\n" + +#: systemv/lpoptions.c:223 +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: ezin da inprimagailua edo instantzia gehitu: %s\n" + +#: systemv/lpoptions.c:507 +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: ezin da PPD fitxategia lortu %s inprimagailuarentzako: %s\n" + +#: systemv/lpoptions.c:516 +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: ezin da PPD fitxategia ireki %s(r)entzako.\n" + +#: systemv/lpoptions.c:104 +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: inprimagailua edo klasea ezezaguna.\n" + +#: systemv/lppasswd.c:185 +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "" +"lppasswd: supererabiltzaileak (root) soilik gehitu edo ezabatu ditzake " +"pasahitzak.\n" + +#: systemv/lppasswd.c:314 +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: pasahitzen fitxategia lanpetuta.\n" + +#: systemv/lppasswd.c:447 +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: pasahitzen fitxategia ez da eguneratu.\n" + +#: systemv/lppasswd.c:414 +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: pasahitzak ez dira berdinak.\n" + +#: systemv/lppasswd.c:264 +msgid "" +"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" +msgstr "" +"lppasswd: pasahitza ukatu da.\n" +"Zure pasahitzak gutxiene 6 karaktere izan behar ditu, ezin du\n" +"zure erabiltzaile-izenik eduki, eta gutxienez hizki bat eta zenbaki bat " +"eduki behar du.\n" + +#: systemv/lppasswd.c:240 +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: pasahitzak ez datoz bat.\n" + +#: systemv/lppasswd.c:211 systemv/lppasswd.c:229 +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: ezin da pasahitzaren katea kopiatu: %s\n" + +#: systemv/lppasswd.c:317 systemv/lppasswd.c:326 systemv/lppasswd.c:344 +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: ezin da pasahitzen fitxategia ireki: %s\n" + +#: systemv/lppasswd.c:379 systemv/lppasswd.c:392 systemv/lppasswd.c:424 +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: ezin da pasahitzen fitxategian idatzi: %s\n" + +#: systemv/lppasswd.c:462 +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" +"lppasswd: huts egin du pasahitzen fitxategi zaharraren babeskopia egitean: %" +"s\n" + +#: systemv/lppasswd.c:475 +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: huts egin du pasahitzen fitxategia izenez aldatzean: %s\n" + +#: systemv/lppasswd.c:404 +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: \"%s\" erabiltzailea eta \"%s\" taldea ez dira existitzen.\n" + +#: systemv/lpstat.c:1039 +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: errorea . Inguruneko %s aldagaiak existitzen ez den \"%s\" helburua " +"izendatzen du.\n" + +#: systemv/lpstat.c:969 +#, c-format +msgid "members of class %s:\n" +msgstr "%s klasearen kideak:\n" + +#: berkeley/lpq.c:574 +msgid "no entries\n" +msgstr "sarrerarik ez\n" + +#: systemv/lpstat.c:1043 +msgid "no system default destination\n" +msgstr "ez dago sistemako helburu lehenetsirik.\n" + +#: scheduler/ipp.c:6271 +msgid "notify-events not specified!" +msgstr "notify-events ez da zehaztu." + +#: scheduler/ipp.c:2108 scheduler/ipp.c:6176 +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "\"%s\" notify-recipient-uri URIa jadanik erabilita dago." + +#: scheduler/ipp.c:2098 scheduler/ipp.c:6166 +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "\"%s\" notify-recipient-uri URIak eskema ezezaguna darabil." + +#: scheduler/ipp.c:4139 scheduler/ipp.c:7101 scheduler/ipp.c:7807 +#: scheduler/ipp.c:9272 +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "%d notify-subscription-id ez da ona." + +#: cups/notify.c:87 +msgid "pending" +msgstr "zain" + +#: ppdc/ppdc.cxx:107 ppdc/ppdpo.cxx:93 +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: \"%s\" include direktorioa gehitzen...\n" + +#: ppdc/ppdpo.cxx:135 +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: UIaren testua gehitzen/eguneratzen %s(e)tik...\n" + +#: ppdc/ppdc-source.cxx:413 +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: okerreko balio boolearra (%s) %d lerroan of(e)n %s.\n" + +#: ppdc/ppdc-source.cxx:1798 +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: okerreko \"%s\" bereizmen izena%d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1116 +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: okerreko %s egoeraren gako-hitza %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2035 +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: okerreko aldagaien ordezkaketa ($%c) %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2711 +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: hautaketa aurkituta %d lerroan aukerarik gabeko %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1700 +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: %s lokalaren #po-a bikoiztua %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:935 +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: iragazkiaren definizioa espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:958 +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: programaren izena espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:397 +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: balio boolearra espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1096 +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: karaktere-jokoa espero zen Font-en ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:450 +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: hautaketaren kodea espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:438 +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: hautaketaren izena/tesua espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:506 +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: koloreen ordena espero zen ColorModel-entzako %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:495 +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: kolore-espazioa espero zen ColorModel-entzako %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:517 +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: konpresioa espero zen ColorModel-entzako %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:698 +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: murriztapenen katea espero zen UIConstraints-entzako %d lerroan %s(e)" +"n.\n" + +#: ppdc/ppdc-source.cxx:2897 +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: kontrolatzaile motaren gako-hitza espero zen DriverType-ren ondoren %d " +"lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:829 +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: duplex mota espero zen Duplex-en ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1080 +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: kodeketa espero zen Font-en ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1691 +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: fitxategi-izena espero zen %s #po ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1208 +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: taldearen izena/testua espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2611 +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: include fitxategi-izena espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1504 +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: osoko zenbakia espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1683 +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: lokala espero zen espero zen #po ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:356 +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: izena espero zen %s(rÇ)en ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3269 +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: izena espero zen FileName ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1061 +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: izena espero zen Font ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3100 +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: izena espero zen Manufacturer ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3133 +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: izena espero zen MediaSize ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3223 +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: izena espero zen ModelName ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3286 +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: izena espero zen PCFileName ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1159 +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: izena/testua espero zen %s ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1248 +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: izena/testua espero zen Installable ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1784 +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: izena/testua espero zen Resolution ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:482 +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: izena/testuaren konbinazioa espero zen ColorModel-arentzako %d lerroan " +"%s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1576 +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: aukeraren izena/testua espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1610 +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: aukeraren atala espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1588 +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: aukera mota espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1767 +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: gainidazketaren eremua espero zen Resolution ondoren %d lerroan %s(e)" +"n.\n" + +#: ppdc/ppdc-source.cxx:1007 +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: zenbaki erreala espero zen %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:575 +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: bereizmena/euskarri mota espero zen ColorProfile ondoren %d lerroan %s" +"(e)n.\n" + +#: ppdc/ppdc-source.cxx:1865 +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: bereizmena/euskarri mota espero zen SimpleColorProfile ondoren %d " +"lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:364 +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: hautatzailea espero zen %s ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1104 +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: egoera espero zen Font ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2786 +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: katea espero zen Copyright ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3389 +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: katea espero zen Version ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:731 +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: aukeren bi izen espero ziren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:375 +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: balioa espero zen %s ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1088 +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: bertsioa espero zen Font ondoren %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:230 +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: baliogabeko #include/#po \"%s\" fitxategi-izena.\n" + +#: ppdc/ppdc-source.cxx:975 +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: baliogabeko iragazkiaren kostua %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:967 +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "" +"ppdc: baliogabeko MIME mota hutsa iragazkiarentzako %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:983 +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" +"ppdc: baliogabeko prorgramare izen hutsa iragazkiarentzako %d lerroan %s(e)" +"n.\n" + +#: ppdc/ppdc-source.cxx:1630 +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: baliogabeko aukeraren \"%s\" atala %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1602 +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: baliogabeko aukeraren \"%s\" mota %d lerroan %s(e)n.\n" + +#: ppdc/ppdc.cxx:243 ppdc/ppdpo.cxx:123 +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: kontrolatzailearen \"%s\" datu-fitxategia kargatzen...\n" + +#: ppdc/ppdc.cxx:179 +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: \"%s\" lokalaren mezuak kargatzen...\n" + +#: ppdc/ppdc.cxx:120 +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: mezuak \"%s\"(e)tik kargatzen...\n" + +#: ppdc/ppdc-source.cxx:2404 ppdc/ppdc-source.cxx:2636 +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif falta da \"%s\"(r)en amaieran.\n" + +#: ppdc/ppdc-source.cxx:2505 ppdc/ppdc-source.cxx:2540 +#: ppdc/ppdc-source.cxx:2570 +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if falta da %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-driver.cxx:722 +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: ez da mezuen katalogorik eman %s lokalarentzako.\n" + +#: ppdc/ppdc-source.cxx:1653 ppdc/ppdc-source.cxx:2874 +#: ppdc/ppdc-source.cxx:2960 ppdc/ppdc-source.cxx:3053 +#: ppdc/ppdc-source.cxx:3186 ppdc/ppdc-source.cxx:3319 +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "ppdc: %s aukera bi talde desberdinetan definituta %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1646 +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" +"ppdc: %s aukera berriro definituta mota desberdin batekin %d lerroan %s(e)" +"n.\n" + +#: ppdc/ppdc-source.cxx:708 +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "" +"ppdc: aukeraren murriztapenak *izena eduki behar du %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2487 +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: habiarazitako #if gehiegi %d lerroan %s(e)n.\n" + +#: ppdc/ppdc.cxx:347 +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: ezin da \"%s\" PPD fitxategia sortu: %s.\n" + +#: ppdc/ppdc.cxx:258 +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: ezin da %s irteerako direktorioa sortu: %s\n" + +#: ppdc/ppdc.cxx:279 +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: ezin dira irteerako kanalizazioak sortu: %s\n" + +#: ppdc/ppdc.cxx:296 ppdc/ppdc.cxx:303 +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: ezin da cupstestppd exekutatu: %s\n" + +#: ppdc/ppdc-source.cxx:1732 +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: ezin da %s #po fitxategia aurkitu %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2643 +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: ezin da \"%s\" include fitxategia aurkitu %d lerroan %s(e)n.\n" + +#: ppdc/ppdc.cxx:190 +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: ezin da lokalizazioa aurkitu \"%s\"(r)entzako: %s\n" + +#: ppdc/ppdc.cxx:129 +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: ezin da \"%s\" lokalizazioaren fitxategia kargatu: %s\n" + +#: ppdc/ppdc-source.cxx:2056 +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: definitu gabeko aldagaia (%s) %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:2916 +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: %s kontrolatzaile mota ezezaguna %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:909 +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: \"%s\" duplex mota ezezaguna %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3146 +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: \"%s\" euskarri-tamaina ezezaguna %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:3400 +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: \"%s\" token ezezaguna ikusi da %d lerroan %s(e)n.\n" + +#: ppdc/ppdc-source.cxx:1017 +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: amaierako karaktere ezezagunak \"%s\" zenbaki errealean %d lerroan %s" +"(e)n.\n" + +#: ppdc/ppdc-source.cxx:2166 +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: %c(r)ekin hasitako amaitu gabeko katea %d lerroan %s(e)n.\n" + +#: ppdc/ppdc.cxx:353 +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: %s inprimatzen...\n" + +#: ppdc/ppdc.cxx:142 +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: PPD fitxategiak \"%s\" direktorioan idazten...\n" + +#: ppdc/ppdmerge.cxx:138 +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: okerreko \"%s\" LanguageVersion %s(e)n\n" + +#: ppdc/ppdmerge.cxx:178 +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: %s PPD fitxategiari ezikusi egiten...\n" + +#: ppdc/ppdmerge.cxx:162 +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: ezin da %s(r)en babeskopia %s(e)n egin: %s\n" + +#: systemv/lpstat.c:1769 +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "printer %s desgaituta %s ostean\n" + +#: systemv/lpstat.c:1758 +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "%s inprimagailua inaktibo dago. Gaituta %s ostetik.\n" + +#: systemv/lpstat.c:1763 +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "" +"%s inprimagailua orain %s-%d inprimatzen ari da. Gaituta %s ostetik.\n" + +#: systemv/lpstat.c:1881 +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "%s/%s inprimagailua desgaituta %s ostetik\n" + +#: systemv/lpstat.c:1867 +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "%s/%s inprimagailua inaktibo dago. Gaituta %s ostetik.\n" + +#: systemv/lpstat.c:1874 +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "" +"%s/%s inprimagailua orain %s-%d inprimatzen ari da. Gaituta %s ostetik.\n" + +#: cups/notify.c:93 cups/notify.c:134 +msgid "processing" +msgstr "prozesatzen" + +#: systemv/lp.c:660 +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "eskaeraren IDa %s-%d da (%d fitxategi)\n" + +#: cups/snmp.c:1021 +msgid "request-id uses indefinite length" +msgstr "'request-id'-ek definitu gabeko luzera darabil" + +#: systemv/lpstat.c:2008 +msgid "scheduler is not running\n" +msgstr "antolatzailea ez da exekutatzen ari.\n" + +#: systemv/lpstat.c:2004 +msgid "scheduler is running\n" +msgstr "antolatzailea exekutatzen ari da.\n" + +#: cups/adminutil.c:2269 +#, c-format +msgid "stat of %s failed: %s" +msgstr "%s(e)n estatistikak huts egin du: %s" + +#: berkeley/lpc.c:216 +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\terakutsi daemon-aren eta ilararen egoera\n" + +#: cups/notify.c:96 cups/notify.c:137 +msgid "stopped" +msgstr "geldituta" + +#: systemv/lpstat.c:1017 +#, c-format +msgid "system default destination: %s\n" +msgstr "sistemako helburu lehenetsia: %s\n" + +#: systemv/lpstat.c:1014 +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "sistemako helburu lehenetsia: %s/%s\n" + +#: cups/notify.c:108 cups/notify.c:140 +msgid "unknown" +msgstr "ezezaguna" + +#: cups/notify.c:117 +msgid "untitled" +msgstr "izengabea" + +#: cups/snmp.c:1046 +msgid "variable-bindings uses indefinite length" +msgstr "'variable-bindings'-ek definitu gabeko luzera darabil" diff --git a/locale/cups_fi.po b/locale/cups_fi.po new file mode 100644 index 0000000000..97f5613959 --- /dev/null +++ b/locale/cups_fi.po @@ -0,0 +1,5679 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-12 15:10+0200\n" +"Last-Translator: Teppo Turtiainen \n" +"Language-Team: Finnish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(kaikki)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(ei mitään)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d tietuetta\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tVian jälkeen: jatka\n" + +msgid "\tAlerts:" +msgstr "\tVaroitukset:" + +msgid "\tBanner required\n" +msgstr "\tOtsikko vaaditaan\n" + +msgid "\tCharset sets:\n" +msgstr "\tMerkistöt:\n" + +msgid "\tConnection: direct\n" +msgstr "\tYhteys: suora\n" + +msgid "\tConnection: remote\n" +msgstr "\tYhteys: etä\n" + +msgid "\tDefault page size:\n" +msgstr "\tSivun oletuskoko:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tOletusmerkkiväli:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tPortin oletusasetukset:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tKuvaus: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tLomake liitetty:\n" +"\tSisältötyypit: mikä tahansa\n" +"\tTulostintyypit: tuntematon\n" + +msgid "\tForms allowed:\n" +msgstr "\tLomakkeet sallittu:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tLiitäntä: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tLiitäntä: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tLiitäntä: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tSijainti: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tVian aikana: ei varoitusta\n" + +msgid "\tUsers allowed:\n" +msgstr "\tKäyttäjät sallittu:\n" + +msgid "\tUsers denied:\n" +msgstr "\tKäyttäjät estetty:\n" + +msgid "\tdaemon present\n" +msgstr "\ttaustaprosessi käynnissä\n" + +msgid "\tno entries\n" +msgstr "\tei tietueita\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\ttulostin on laitteessa ”%s” nopeus -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\ttulostus on pois käytöstä\n" + +msgid "\tprinting is enabled\n" +msgstr "\ttulostus on käytössä\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tjonossa kohteelle %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tjonotus on pois käytöstä\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tjonotus on käytössä\n" + +msgid "\treason unknown\n" +msgstr "\tsyy tuntematon\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" YKSITYISKOHTAISET STANDARDIENMUKAISUUSTESTIN TULOKSET\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " VIITE: sivu 15, osa 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " VIITE: sivu 15, osa 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " VIITE: sivu 19, osa 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " VIITE: sivu 20, osa 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " VIITE: sivu 27, osa 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " VIITE: sivu 42, osa 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " VIITE: sivut 16 - 17, osa 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " VIITE: sivut 42 - 45, osa 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " VIITE: sivut 45 - 46, osa 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " VIITE: sivut 48 - 49, osa 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " VIITE: sivut 52 - 54, osa 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f tavua\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN ”%s %s” on ristiriidassa kohteen ”%s %s” kanssa\n" +" (rajoitus=”%s %s %s %s”)\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN Kohteella %s ei ole vastaavia valintoja!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s jakaa yleisen etuliitteen kohteen %s kanssa\n" +" VIITE: sivu 15, osa 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Oletusvaihtoehdot ovat ristiriidassa!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Kaksipuoleisuusvalinnan avainsana %s ei ehkä toimi " +"odotetulla tavalla ja sen pitäisi olla nimeltään Duplex!\n" +" VIITE: sivu 122, osa 5.17.\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN Tiedosto sisältää sekaisin CR-, LF- ja CR LF -" +"rivinvaihtoja!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding vaaditaan PPD 4.3 -määrityksessä.\n" +" VIITE: sivut 56 - 57, osa 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Rivi %d sisältää vain tyhjää!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Manufacturer vaaditaan PPD 4.3 -määrityksessä.\n" +" VIITE: sivut 58 - 59, osa 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN Muiden kuin Windowsin PPD-tiedostojen tulisi käyttää LF-" +"rivinvaihtoja eikä CR LF -rivinvaihtoja!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Vanhentunut PPD-versio %.1f!\n" +" VIITE: sivu 42, osa 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName on PPD-määrityksen vastaisesti pidempi kuin 8.3.\n" +" VIITE: sivut 61 - 62, osa 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokollat sisältävät PJL:ää, mutta JCL-attribuutteja ei " +"ole asetettu.\n" +" VIITE: sivut 78 - 79, osa 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokollat sisältävät sekä PJL:ää etä BCP:tä; TBCP:tä " +"odotettiin.\n" +" VIITE: sivut 78 - 79, osa 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName vaaditaan PPD 4.3 -määrityksessä.\n" +" VIITE: sivut 64 - 65, osa 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " Kohdetta %s %s %s ei ole olemassa!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Virheellinen %s vaihtoehto %s!\n" +" VIITE: sivu 122, osa 5.17.\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Virheellinen UTF-8 ”%s” käännösmerkkijono valinnalle %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Virheellinen UTF-8 ”%s” käännösmerkkijono valinnalle %s, " +"vaihtoehto %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Virheellinen cupsFilter-arvo ”%s”!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Virheellinen cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Virheellinen cupsPreFilter-arvo ”%s”!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Virheellinen cupsUIConstraints %s: ”%s”!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Virheellinen kieli ”%s”!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Tyhjä cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Käännösmerkkijono ”%s” valinnalle %s puuttuu!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Käännösmerkkijono ”%s” valinnalle %s puuttuu, vaihtoehto %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Vaihtoehto *%s %s kohteessa UIConstraints ”*%s %s *%s %s” " +"puuttuu!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" +" %s Vaihtoehto *%s %s kohteessa cupsUIConstraints %s: ”%s” puuttuu!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s cupsFilter-tiedosto ”%s” puuttuu!\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s cupsICCProfile-tiedosto ”%s” puuttuu!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s cupsPreFilter-tiedosto ”%s” puuttuu!\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s cupsUIResolver %s puuttuu!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Valinta %s kohteessa UIConstraints ”*%s %s *%s %s” puuttuu!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Valinta %s kohteessa cupsUIConstraints %s: ”%s” puuttuu!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Tiedostossa ei ole peruskäännöstä ”%s”!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s VAADITTU %s ei määrittele vaihtoehtoa None!\n" +" VIITE: sivu 122, osa 5.17.\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s hajautusarvo törmää kohteen %s kanssa!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s aiheuttaa silmukan!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Kohteen %s vaihtoehtojen nimet %s ja %s eroavat toisistaan " +"vain isojen ja pienten merkkien osalta!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s on oltava 1284DeviceID!\n" +" VIITE: sivu 72, osa 5.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** VIRHEELLINEN Default%s %s\n" +" VIITE: sivu 40, osa 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** VIRHEELLINEN DefaultImageableArea %s!\n" +" VIITE: sivu 102, osa 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** VIRHEELLINEN DefaultPaperDimension %s!\n" +" VIITE: sivu 103, osa 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** VIRHEELLINEN JobPatchFile-attribuutti tiedostossa\n" +" REF: sivu 24, osa 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** VIRHEELLINEN Manufacturer (tulisi olla ”HP”)\n" +" REF: sivu 211, taulukko D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** VIRHEELLINEN Manufacturer (tulisi olla ”Oki”)\n" +" REF: sivu 211, taulukko D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** VIRHEELLINEN ModelName - ”%c” ei ole sallittu " +"merkkijonossa.\n" +" VIITE: sivut 59 - 60, osa 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** VIRHEELLINEN PSVersion - ei ”(string) int”.\n" +" VIITE: sivut 62 - 64, osa 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** VIRHEELLINEN Product - ei ”(string)”.\n" +" VIITE: sivu 62, osa 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** VIRHEELLINEN ShortNickName - pidempi kuin 31 merkkiä.\n" +" VIITE: sivut 64 - 65, osa 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Virheellinen %s vaihtoehto %s!\n" +" VIITE: sivu 84, osa 5.9.\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Virheellinen FileVersion ”%s”\n" +" VIITE: Sivu 56, osa 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Virheellinen FormatVersion ”%s”\n" +" VIITE: Sivu 56, osa 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **FAIL** Virheellinen LanguageEncoding %s - pitää olla ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **FAIL** Virheellinen LanguageVersion %s - pitää olla English!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **FAIL** Oletusarvoista valintakoodia ei voida tulkita: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** Oletusarvoinen käännösmerkkijono valinnan %s vaihtoehdolle %" +"s sisältää 8-bittisiä merkkejä!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** Oletusarvoinen käännösmerkkijono valinnalle %s sisältää 8-" +"bittisiä merkkejä!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Ryhmien nimet %s ja %s eroavat toisistaan vain isojen ja " +"pienten merkkien osalta!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Useita esiintymiä kohteen %s vaihtoehtojen nimeä %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Vaihtoehtojen nimet %s ja %s eroavat toisistaan vain isojen " +"ja pienten merkkien osalta!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** VAADITAAN Default%s\n" +" VIITE: sivu 40, osa 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** VAADITAAN DefaultImageableArea\n" +" VIITE: sivu 102, osa 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** VAADITAAN DefaultPaperDimension\n" +" VIITE: sivu 103, osa 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN FileVersion\n" +" VIITE: sivu 56, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN FormatVersion\n" +" VIITE: sivu 56, osa 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** VAADITAAN ImageableArea PageSize-arvolle %s\n" +" VIITE: sivu 41, osa 5.\n" +" VIITE: sivu 102, osa 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN LanguageEncoding\n" +" VIITE: sivut 56 - 57, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN LanguageVersion\n" +" VIITE: sivut 57 - 58, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN Manufacturer\n" +" VIITE: sivut 58 - 59, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN ModelName\n" +" VIITE: sivut 59 - 60, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN NickName\n" +" VIITE: sivu 60, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN PCFileName\n" +" VIITE: sivut 61 - 62, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN PSVersion\n" +" VIITE: sivut 62 - 64, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** VAADITAAN PageRegion\n" +" VIITE: sivu 100, osa 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** VAADITAAN PageSize\n" +" VIITE: sivu 41, osa 5.\n" +" VIITE: sivu 99, osa 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** VAADITAAN PageSize\n" +" VIITE: sivut 99 - 100, osa 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** VAADITAAN PaperDimension PageSize-arvolle %s\n" +" VIITE: sivu 41, osa 5.\n" +" VIITE: sivu 103, osa 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN Product\n" +" VIITE: sivu 62, osa 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** VAADITAAN ShortNickName\n" +" VIITE: sivu 64 - 65, osa 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d VIRHETTÄ LÖYDETTIIN\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Virheellinen %%%%BoundingBox: rivillä %d!\n" +" VIITE: sivu 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Virheellinen %%%%Page: rivillä %d!\n" +" VIITE: sivu 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Virheellinen %%%%Pages: rivillä %d!\n" +" VIITE: sivu 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Rivi %d on pidempi kuin 255 merkkiä (%d)!\n" +" VIITE: sivu 25, Line Length\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 puuttuu ensimmäiseltä riviltä!\n" +" VIITE: sivu 17, 3.1 Conforming Documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" %%EndComments-kommentti puuttuu!\n" +" VIITE: sivu 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox:-kommentti puuttuu tai on virheellinen!\n" +" VIITE: sivu 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page:-kommentit puuttuvat tai ovat virheellisiä!\n" +" VIITE: sivu 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages:-kommentti puuttuu tai on virheellinen!\n" +" VIITE: sivu 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " VIRHEITÄ EI LÖYTYNYT\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " %d riviä ovat pidempiä kuin 255 merkkiä!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Liikaa %%BeginDocument-kommentteja!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Liikaa %%EndDocument-kommentteja!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Varoitus: tiedosto sisältää binääridataa!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Varoitus: tiedostossa ei ole %%EndComments-kommenttia!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Varoitus: tiedostossa on vanhentunut DSC-versio %.1f!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** PPD-tiedostoa ei voida avata - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** PPD-tiedostoa ei voida avata - %s rivillä %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10 Envelope" + +msgid "#11 Envelope" +msgstr "#11 Envelope" + +msgid "#12 Envelope" +msgstr "#12 Envelope" + +msgid "#14 Envelope" +msgstr "#14 Envelope" + +msgid "#9 Envelope" +msgstr "#9 Envelope" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f tavua\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f tavua\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f millimetriä" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f - %.0f x %.0f millimetriä" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f tuumaa" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f - %.2f x %.2f tuumaa" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s vastaanottaa pyyntöjä alkaen %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "Kohdetta %s ei voida muuttaa." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "Kohdetta %s ei ole toteutettu lpc:n CUPS-versiossa.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s ei ole valmis\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s on valmis\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s on valmis ja tulostaa\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s ei vastaanota pyyntöjä alkaen %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s ei ole tuettu!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s vastaanottaa pyyntöjä alkaen %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s ei vastaanota pyyntöjä alkaen %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [työ %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s epäonnistui: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: En tiedä mitä tehdä!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Virhe - %s ympäristömuuttujanimien kohdetta ”%s” ei ole olemassa!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Virhe - virheellinen työn tunnus!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Virhe - tiedostoja ei voida tulostaa ja työtä muuttaa samanaikaisesti!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Virhe - oletussyötevirrasta ei voida tulostaa, jos annetaan tiedostoja " +"tai työn tunnus!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Virhe - S-valitsimen jälkeen odotettiin merkistöä!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Virhe - T-valitsimen jälkeen odotettiin sisältötyyppiä!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Virhe - n-valitsimen jälkeen odotettiin kopioiden lukumäärää!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Virhe - #-valitsimen jälkeen odotettiin kopioiden lukumäärää!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Virhe - P-valitsimen jälkeen odotettiin kohdetta!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Virhe - b-valitsimen jälkeen odotettiin kohdetta!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Virhe - d-valitsimen jälkeen odotettiin kohdetta!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Virhe - f-valitsimen jälkeen odotettiin muotoa!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Virhe - H-valitsimen jälkeen odotettiin pidon nimeä!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Virhe - H-valitsimen jälkeen odotettiin palvelinnimeä!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Virhe - h-valitsimen jälkeen odotettiin palvelinnimeä!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Virhe - y-valitsimen jälkeen odotettiin tilaluetteloa!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Virhe - %c-valitsimen jälkeen odotettiin nimeä!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Virhe - o-valitsimen jälkeen odotettiin valintamerkkijonoa!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Virhe - P-valitsimen jälkeen odotettiin sivuluetteloa!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Virhe - %c-valitsimen jälkeen odotettiin tärkeyttä!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Virhe - r-valitsimen jälkeen odotettiin syytekstiä!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Virhe - t-valitsimen jälkeen odotettiin otsikkoa!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Virhe - U-valitsimen jälkeen odotettiin käyttäjätunnusta!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Virhe - u-valitsimen jälkeen odotettiin käyttäjätunnusta!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Virhe - %c-valitsimen jälkeen odotettiin arvoa!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Virhe - W-valitsimen jälkeen tarvitaan ”completed”, ”not-completed” tai " +"”all”!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Virhe - oletuskohdetta ei ole käytettävissä.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Virhe - tärkeyden on oltava 1 - 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Virhe - ajastin ei vastaa!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Virhe - liikaa tiedostoja - ”%s”\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Virhe - kohdetta ”%s” ei voida käyttää - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Virhe - oletussyötevirrasta ei voida laittaa jonoon - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Virhe - tuntematon kohde - ”%s”\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Virhe - tuntematon kohde - ”%s/%s”\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Virhe - tuntematon valitsin ”%c”!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Virhe - tuntematon valitsin ”%s”!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: i-valitsimen jälkeen odotettiin työn tunnusta!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Suodin ”%s” ei ole käytettävissä: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Virheellinen kohdenimi luettelossa ”%s”!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Virheellinen suodinmerkkijono ”%s”\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "" +"%s: Tarvitaan työn tunnus (”-i jobid”) ennen ”-H restart” -valitsinta!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Ei suodinta, jolla muuntaa muodosta %s/%s muotoon %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Toiminto epäonnistui: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Salaustukea ei ole käännetty mukaan!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Palvelimeen ei voida yhdistää\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Palvelinta ei tavoitettu!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Kohteen ”%s” MIME-tyyppiä ei voida määrittää!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Kohdetta %s ei voida avata: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: PPD-tiedostoa s ei voida avata: %s linjalla %d.\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: MIME-tietokantaa ei voida lukea kohteesta ”%s” tai ”%s”!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Tuntematon kohde - ”%s”\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Tuntematon kohde-MIME-tyyppi %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Tuntematon valitsin ”%c”!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Tuntematon lähde-MIME-tyyppi %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Varoitus - %c-muotovalitsinta ei tueta - tuloste saattaa olla " +"virheellinen!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Varoitus - merkistövalitsin jätettiin huomioimatta!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Varoitus - sisältötyyppivalitsin jätettiin huomioimatta!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Varoitus - lomakevalitsin jätettiin huomioimatta!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Varoitus - tilavalitsin jätettiin huomioimatta!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: virhe - %s ympäristömuuttujanimien kohdetta ”%s” ei ole olemassa!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: virhe - o-valitsimen jälkeen odotettiin valinta=arvo!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: virhe - oletuskohdetta ei ole käytettävissä.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 tuumaa/s" + +msgid "1.25x0.25\"" +msgstr "1,25 x 0,25 \"" + +msgid "1.25x2.25\"" +msgstr "1,25 x 2,25 \"" + +msgid "1.5 inch/sec." +msgstr "1,5 tuumaa/s" + +msgid "1.50x0.25\"" +msgstr "1,50 x 0,25 \"" + +msgid "1.50x0.50\"" +msgstr "1,50 x 0,50 \"" + +msgid "1.50x1.00\"" +msgstr "1,50 x 1,00 \"" + +msgid "1.50x2.00\"" +msgstr "1,50 x 2,00 \"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 tuumaa/s" + +msgid "10 x 11\"" +msgstr "10 x 11 \"" + +msgid "10 x 13\"" +msgstr "10 x 13 \"" + +msgid "10 x 14\"" +msgstr "10 x 14 \"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/s" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 tuumaa/s" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 tuumaa/s" + +msgid "12 x 11\"" +msgstr "12 x 11 \"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/s" + +msgid "120x60dpi" +msgstr "120 x 60 dpi" + +msgid "120x72dpi" +msgstr "120 x 72 dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/s" + +msgid "15 x 11\"" +msgstr "15 x 11 \"" + +msgid "150 mm/sec." +msgstr "150 mm/s" + +msgid "150dpi" +msgstr "150 dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 tuumaa/s" + +msgid "2-Sided Printing" +msgstr "Kaksipuolinen tulostus" + +msgid "2.00x0.37\"" +msgstr "2,00 x 0,37 \"" + +msgid "2.00x0.50\"" +msgstr "2,00 x 0,50 \"" + +msgid "2.00x1.00\"" +msgstr "2,00 x 1,00 \"" + +msgid "2.00x1.25\"" +msgstr "2,00 x 1,25 \"" + +msgid "2.00x2.00\"" +msgstr "2,00 x 2,00 \"" + +msgid "2.00x3.00\"" +msgstr "2,00 x 3,00 \"" + +msgid "2.00x4.00\"" +msgstr "2,00 x 4,00 \"" + +msgid "2.00x5.50\"" +msgstr "2,00 x 5,50 \"" + +msgid "2.25x0.50\"" +msgstr "2,25 x 0,50 \"" + +msgid "2.25x1.25\"" +msgstr "2,25 x 1,25 \"" + +msgid "2.25x4.00\"" +msgstr "2,25 x 4,00 \"" + +msgid "2.25x5.50\"" +msgstr "2,25 x 5,50 \"" + +msgid "2.38x5.50\"" +msgstr "2,38 x 5,50 \"" + +msgid "2.5 inches/sec." +msgstr "2,5 tuumaa/s" + +msgid "2.50x1.00\"" +msgstr "2,50 x 1,00 \"" + +msgid "2.50x2.00\"" +msgstr "2,50 x 2,00 \"" + +msgid "2.75x1.25\"" +msgstr "2,75 x 1,25 \"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1 \"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/s" + +msgid "200 mm/sec." +msgstr "200 mm/s" + +msgid "203dpi" +msgstr "203 dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-nastainen" + +msgid "240x72dpi" +msgstr "240 x 72 dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/s" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 tuumaa/s" + +msgid "3.00x1.00\"" +msgstr "3,00 x 1,00 \"" + +msgid "3.00x1.25\"" +msgstr "3,00 x 1,25 \"" + +msgid "3.00x2.00\"" +msgstr "3,00 x 2,00 \"" + +msgid "3.00x3.00\"" +msgstr "3,00 x 3,00 \"" + +msgid "3.00x5.00\"" +msgstr "3,00 x 5,00 \"" + +msgid "3.25x2.00\"" +msgstr "3,25 x 2,00 \"" + +msgid "3.25x5.00\"" +msgstr "3,25 x 5,00 \"" + +msgid "3.25x5.50\"" +msgstr "3,25 x 5,50 \"" + +msgid "3.25x5.83\"" +msgstr "3,25 x 5,83 \"" + +msgid "3.25x7.83\"" +msgstr "3,25 x 7,83 \"" + +msgid "3.5\" Disk" +msgstr "3,5 \" levy" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3,5 \" levy - 2 1/8 x 2 3/4 \"" + +msgid "3.50x1.00\"" +msgstr "3,50 x 1,00 \"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/s" + +msgid "300 mm/sec." +msgstr "300 mm/s" + +msgid "300dpi" +msgstr "300 dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 dpi" + +msgid "360x180dpi" +msgstr "360 x 180 dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 tuumaa/s" + +msgid "4.00x1.00\"" +msgstr "4,00 x 1,00 \"" + +msgid "4.00x13.00\"" +msgstr "4,00 x 13,00 \"" + +msgid "4.00x2.00\"" +msgstr "4,00 x 2,00 \"" + +msgid "4.00x2.50\"" +msgstr "4,00 x 2,50 \"" + +msgid "4.00x3.00\"" +msgstr "4,00 x 3,00 \"" + +msgid "4.00x4.00\"" +msgstr "4,00 x 4,00 \"" + +msgid "4.00x5.00\"" +msgstr "4,00 x 5,00 \"" + +msgid "4.00x6.00\"" +msgstr "4,00 x 6,00 \"" + +msgid "4.00x6.50\"" +msgstr "4,00 x 6,50 \"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/s" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 tuumaa/s" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 tuumaa/s" + +msgid "6.00x1.00\"" +msgstr "6,00 x 1,00 \"" + +msgid "6.00x2.00\"" +msgstr "6,00 x 2,00 \"" + +msgid "6.00x3.00\"" +msgstr "6,00 x 3,00 \"" + +msgid "6.00x4.00\"" +msgstr "6,00 x 4,00 \"" + +msgid "6.00x5.00\"" +msgstr "6,00 x 5,00 \"" + +msgid "6.00x6.00\"" +msgstr "6,00 x 6,00 \"" + +msgid "6.00x6.50\"" +msgstr "6,00 x 6,50 \"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/s" + +msgid "600dpi" +msgstr "600 dpi" + +msgid "60dpi" +msgstr "60 dpi" + +msgid "60x720dpi" +msgstr "60 x 720 dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 tuumaa/s" + +msgid "7 x 9\"" +msgstr "7 x 9 \"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 tuumaa/s" + +msgid "8 x 10\"" +msgstr "8 x 10 \"" + +msgid "8.00x1.00\"" +msgstr "8,00 x 1,00 \"" + +msgid "8.00x2.00\"" +msgstr "8,00 x 2,00 \"" + +msgid "8.00x3.00\"" +msgstr "8,00 x 3,00 \"" + +msgid "8.00x4.00\"" +msgstr "8,00 x 4,00 \"" + +msgid "8.00x5.00\"" +msgstr "8,00 x 5,00 \"" + +msgid "8.00x6.00\"" +msgstr "8,00 x 6,00 \"" + +msgid "8.00x6.50\"" +msgstr "8,00 x 6,50 \"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/s" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 tuumaa/s" + +msgid "9 x 11\"" +msgstr "9 x 11 \"" + +msgid "9 x 12\"" +msgstr "9 x 12 \"" + +msgid "9-Pin Series" +msgstr "9-nastainen" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Virheellinen ohje tuntematon komento\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Tulostinajureiden viemiseen tarvitaan Samba-salasana!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "Tulostinajureiden viemiseen tarvitaan Samba-käyttäjätunnus!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Luokka nimeltä ”%s” on jo olemassa!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Tulostin nimeltä ”%s” on jo olemassa!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (ylikokoinen)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (ylikokoinen)" + +msgid "A4 (Small)" +msgstr "A4 (pieni)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (ylikokoinen)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Hyväksy töitä" + +msgid "Accepted" +msgstr "Hyväksytty" + +msgid "Add Class" +msgstr "Lisää luokka" + +msgid "Add Printer" +msgstr "Lisää tulostin" + +msgid "Add RSS Subscription" +msgstr "Lisää RSS-tilaus" + +msgid "Address" +msgstr "Osoite" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Osoite - 1 1/8 x 3 1/2 \"" + +msgid "Administration" +msgstr "Ylläpito" + +msgid "Always" +msgstr "Aina" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applikaattori" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Yritettiin asettaa %s printer-state virheelliseen arvoon %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Attribuuttiryhmät ovat epäjärjestyksessä (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Virheellinen NULL dests -osoitin" + +msgid "Bad OpenGroup" +msgstr "Virheellinen OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Virheellinen OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Virheellinen OrderDependency" + +msgid "Bad Request" +msgstr "Virheellinen pyyntö" + +msgid "Bad SNMP version number" +msgstr "Virheellinen SNMP-versionumero" + +msgid "Bad UIConstraints" +msgstr "Virheellinen UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Virheellinen kopioiden määrä %d." + +msgid "Bad custom parameter" +msgstr "Virheellinen muokattu parametri" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Virheellinen laite-osoite ”%s”!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Virheellinen device-uri ”%s”!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Virheellinen device-uri-malli ”%s”!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Virheellinen document-format ”%s”!" + +msgid "Bad filename buffer!" +msgstr "Virheellinen tiedostonimipuskuri!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Virheellinen kirjasinattribuutti: %s\n" + +msgid "Bad job-priority value!" +msgstr "Virheellinen job-priority-arvo!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Virheellinen job-sheets-arvo ”%s”!" + +msgid "Bad job-sheets value type!" +msgstr "Virheellinen job-sheets-arvon tyyppi!" + +msgid "Bad job-state value!" +msgstr "Virheellinen job-state-arvo!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Virheellinen job-uri-attribuutti ”%s”!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Virheellinen notify-pull-method ”%s”!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Virheellinen notify-recipient-uri-osoite ”%s”!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Virheellinen number-up-arvo %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Virheellinen valinta ja vaihtoehto rivillä %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Virheelliset page-ranges-arvot %d - %d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Virheellinen port-monitor ”%s”!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Virheellinen printer-state-arvo %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Virheellinen pyynnön versionumero %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Virheellinen tilaustunnus!" + +msgid "Banners" +msgstr "Otsikot" + +msgid "Billing Information: " +msgstr "Laskutustiedot: " + +msgid "Bond Paper" +msgstr "Bond-paperi" + +msgid "C0 Envelope" +msgstr "C0 Envelope" + +msgid "C1 Envelope" +msgstr "C1 Envelope" + +msgid "C2 Envelope" +msgstr "C2 Envelope" + +msgid "C3 Envelope" +msgstr "C3 Envelope" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4 Envelope" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5 Envelope" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6 Envelope" + +msgid "C65 Envelope" +msgstr "C65 Envelope" + +msgid "C7 Envelope" +msgstr "C7 Envelope" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL-tarratulostin" + +msgid "Cancel RSS Subscription" +msgstr "Peru RSS-tilaus" + +msgid "Change Settings" +msgstr "Muuta asetuksia" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Merkistöä ”%s” ei tueta!" + +msgid "Chou3 Envelope" +msgstr "Chou3 Envelope" + +msgid "Chou4 Envelope" +msgstr "Chou4 Envelope" + +msgid "Classes" +msgstr "Luokat" + +msgid "Clean Print Heads" +msgstr "Puhdista tulostuspäät" + +msgid "Color" +msgstr "Väri" + +msgid "Color Mode" +msgstr "Väritila" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Komennot voidaan lyhentää. Komennot ovat:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Yhteisönimi käyttää määrittämätöntä pituutta" + +msgid "Continue" +msgstr "Jatka" + +msgid "Continuous" +msgstr "Jatkuva" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Tyyppiä ”%s” ei voitu skannata!" + +msgid "Cover open." +msgstr "Kansi avoinna." + +msgid "Created" +msgstr "Luotu" + +msgid "Created On: " +msgstr "Luotu: " + +msgid "Custom" +msgstr "Muokattu" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Leikkaa" + +msgid "Cutter" +msgstr "Leikkaaja" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL Envelope" + +msgid "Dark" +msgstr "Tumma" + +msgid "Darkness" +msgstr "Tummuus" + +msgid "Delete Class" +msgstr "Poista luokka" + +msgid "Delete Printer" +msgstr "Poista tulostin" + +msgid "Description: " +msgstr "Kuvaus: " + +msgid "DeskJet Series" +msgstr "DeskJet-sarja" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Kohde ”%s” ei vastaanota töitä." + +msgid "Developer almost empty." +msgstr "Kehite lähes loppu." + +msgid "Developer empty!" +msgstr "Kehite loppu!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Laite: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Suora lämpömedia" + +msgid "Disabled" +msgstr "Pois käytöstä" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Dokumenttia %d ei löytynyt työstä %d." + +msgid "Door open." +msgstr "Ovi avoinna." + +msgid "Double Postcard" +msgstr "Double Postcard" + +msgid "Driver Name: " +msgstr "Ajurin nimi: " + +msgid "Driver Version: " +msgstr "Ajurin versio: " + +msgid "Duplexer" +msgstr "Duplekseri" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: ei voida varata muistia sivutiedolle: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: ei voida varata muistia sivutaululle: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1-tarratulostin" + +msgid "EPL2 Label Printer" +msgstr "EPL2-tarratulostin" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Virheellinen %%BoundingBox:-kommentti havaittu!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Virheellinen %%IncludeFeature:-kommentti!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Virheellinen %%Page:-kommentti tiedostossa!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Virheellinen %%PageBoundingBox:-kommentti tiedostossa!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Virheellinen SCSI-laitetiedosto ”%s”!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Virheellinen merkistötiedosto %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Virheellinen merkistötyyppi %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Virheellinen sarakearvo %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Virheellinen cpi-arvo %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Virheellinen kirjasinkuvausrivi: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Virheellinen lpi-arvo %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Virheellinen arkin määrittely!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Virheellinen tekstin suunta %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Virheellinen tekstin leveys %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Kohdetulostinta ei ole olemassa!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Monistunut %%BoundingBox:-kommentti havaittu!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Monistunut %%Pages:-kommentti havaittu!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Tyhjä tulostustiedosto!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Virhe %d lähetettäessä PAPSendData-pyyntöä: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "" +"ERROR: Odotettiin lainausmerkin merkittyä merkkijonoa rivillä %d / %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Vakava USB-virhe!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Virheellinen HP-GL/2-komento havaittu, tiedostoa ei voida tulostaa!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog puuttuu!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup puuttuu!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Arvo puuttuu otsikkotiedoston riviltä %d!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Tarvitaan msgid-rivi ennen käännösmerkkijonoja rivillä %d / %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Otsakkeessa ei ole %%PageBoundingBox:-kommenttia!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Otsakkeessa ei ole %%Pages:-kommenttia!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Laitteen osoitetta ei löytynyt argv[0]:stä eikä DEVICE_URI-" +"ympäristömuuttujasta!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Merkistötiedostossa %s ei ole kirjasimia\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Sivuja ei löytynyt!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Paperi loppu!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER-ympäristömuuttujaa ei ole määritelty!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Tulostustiedostoa ei hyväksytty (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Tulostin ei vastaa\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Tulostin ei vastaa!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Tulostin lähetti odottamattoman EOF:n\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Etäpalvelin ei hyväksynyt ohjaustiedostoa (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Etäpalvelin ei hyväksynyt datatiedostoa (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: Lähetettäessä dataa tulostimelle tapahtui aikakatkaisuvirhe\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Tiedostoa %d ei voida lisätä työhön: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Työtä %d ei voida peruuttaa: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: PDF-tiedostoa ei voida kopioida" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Socketia ei voida luoda" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: Tilapäistä pakattua tulostustiedostoa ei voida luoda: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Tilapäistiedostoa ei voida luoda" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: pictwpstops:ia ei voida suorittaa: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: gs-ohjelmaa ei voida suorittaa" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: pdftops-ohjelmaa ei voida suorittaa" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: pictwpstops:ia ei voida forkata: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: PAP-pyyntöä ei voida hakea" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: PAP-vastausta ei voida hakea" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: Tulostimen ”%s” PPD-tiedostoa ei voida hakea - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Oletusarvoista AppleTalk-vyöhykettä ei voida hakea" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Työn %d ominaisuuksia ei voida hakea (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Tulostimen tilaa ei voida hakea (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Tulostinta ”%s” ei löytynyt!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: PAP-vastausta ei voida etsiä" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: AppleTalk-tulostimia ei voida etsiä" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: AppleTalk-osoitteita ei voida tehdä" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Kohdetta ”%s” ei voida avata - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Kohdetta %s ei voida avata: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Otsikkotiedostoa ”%s” ei voida avata - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Laitetiedostoa ”%s” ei voida avata: %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Tiedostoa ”%s” ei voida avata - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Tiedostoa ”%s” ei voida avata: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Kuvatiedostoa ei voida avata tulostusta varten!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Tulostustiedostoa ”%s” ei voida avata: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Tulostustiedostoa %s ei voida avata - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Tulostustiedostoa %s ei voida avata: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: Tilapäistä pakattua tulostustiedostoa ei voida avata: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: %d tekstisaraketta ei voida tulostaa!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: %d x %d tekstisivua ei voida tulostaa!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Tulostusdataa ei voida lukea" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Tulostusdataa ei voida lukea!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Porttia ei voida varata" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Tiedostossa ei voida siirtyä kohtaan %ld - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Tiedostossa ei voida siirtyä kohtaan %lld - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: LPD-komentoa ei voida lähettää" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: PAP tickle -pyyntöä ei voida lähettää" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Alkuperäistä PAP send data -pyyntöä ei voida lähettää" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Tulostusdataa ei voida lähettää (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Tulostusdataa ei voida lähettää!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Tulostustiedostoa ei voida lähettää tulostimelle" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: Loppu-NUL:ia ei voida lähettää tulostimelle" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: pictwpstops:ia ei voida odottaa: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: %d tavua ei voida kirjoittaa kohteeseen ”%s”: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: %d tavua ei voida kirjoittaa tulostimelle!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Ohjaustiedostoa ei voida kirjoittaa" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Tulostusdataa ei voida kirjoittaa" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Tulostusdataa ei voida kirjoittaa: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Rasteridataa ei voida kirjoittaa ajurille!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Tilapäistiedostoon ei voida kirjoittaa" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: Pakkaamatonta dokumenttidataa ei voida kirjoittaa: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Odottamatonta tekstiä rivillä %d / %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Tuntematon salausvalinnan arvo ”%s”!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Tuntematon tiedostojärjestys ”%s”\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Tuntematon muotomerkki ”%c”\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Tuntematon viestikatalogimuoto kohteelle ”%s”!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Tuntematon valinta ”%s” arvolla ”%s”!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Tuntematon tulostustila ”%s”\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Tuntematon versiovalinnan arvo ”%s”!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Ei-tuettu kirkkausarvo %s, käytetään kirkkaus=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Ei-tuettu gamma-arvo %s, käytetään gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Ei-tuettu number-up-arvo %d, käytetään number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Ei-tuettu number-up-layout-arvo %s, käytetään number-up-layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: Ei-tuettu page-border-arvo %s, käytetään page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: Havaittiin doc_printf-ylivuoto (%d tavua), keskeytetään!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops lopetti signaaliin %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops lopetti paluuarvolla %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: korjattavissa: Tulostimeen ei voida yhdistää, yritetään uudelleen 30 " +"sekunnin kuluttua...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() epäonnistui" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: tulostustiedostoa ei voida statata" + +msgid "Edit Configuration File" +msgstr "Muokkaa asetustiedostoa" + +msgid "Empty PPD file!" +msgstr "Tyhjä PPD-tiedosto!" + +msgid "Ending Banner" +msgstr "Loppuotsikko" + +msgid "Enter old password:" +msgstr "Syötä vanha salasana:" + +msgid "Enter password again:" +msgstr "Syötä salasana uudelleen:" + +msgid "Enter password:" +msgstr "Syötä salasana:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Syötä oma käyttäjätunnuksesi ja salasanasi tai rootin käyttäjätunnus ja " +"salasana tämän sivun käyttämistä varten. Jos käytät Kerberos-todentamista, " +"varmista, että sinulla on kelvollinen Kerberos-lippu." + +msgid "Envelope Feed" +msgstr "Kirjekuoren syöttö" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Virhekäytäntö" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Virhe: h-valitsimen jälkeen tarvitaan palvelinnimi!\n" + +msgid "Every 10 Labels" +msgstr "Joka 10. tarra" + +msgid "Every 2 Labels" +msgstr "Joka 2. tarra" + +msgid "Every 3 Labels" +msgstr "Joka 3. tarra" + +msgid "Every 4 Labels" +msgstr "Joka 4. tarra" + +msgid "Every 5 Labels" +msgstr "Joka 5. tarra" + +msgid "Every 6 Labels" +msgstr "Joka 6. tarra" + +msgid "Every 7 Labels" +msgstr "Joka 7. tarra" + +msgid "Every 8 Labels" +msgstr "Joka 8. tarra" + +msgid "Every 9 Labels" +msgstr "Joka 9. tarra" + +msgid "Every Label" +msgstr "Joka tarra" + +msgid "Expectation Failed" +msgstr "Odotus epäonnistui" + +msgid "Export Printers to Samba" +msgstr "Vie tulostimet Sambaan" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Arkistokansio" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Arkistokansio - 9/16 x 3 7/16 \"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Tiedostolaitteiden osoitteet on poistettu käytöstä! Voit ottaa ne käyttöön ”%" +"s/cupsd.conf”-tiedoston FileDevice-säännöllä." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Kielletty" + +msgid "Fuser temperature high!" +msgstr "Lämpövastuksen lämpötila on korkea!" + +msgid "Fuser temperature low!" +msgstr "Lämpövastuksen lämpötila on matala!" + +msgid "General" +msgstr "Yleiset" + +msgid "Generic" +msgstr "Yleinen" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU käyttää määrittämätöntä pituutta" + +msgid "Glossy Paper" +msgstr "Kiiltävä paperi" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Saatiin printer-uri-attribuutti, mutta ei job-id:tä!" + +msgid "Grayscale" +msgstr "Harmaasävy" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Riippukansio" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Riippukansio - 9/16 x 2 \"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk poistettu käytöstä järjestelmäasetuksissa\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk poistettu käytöstä järjestelmäasetuksissa.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Perutaan tulostustyötä...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Yhteydessä tulostimeen...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Yhdistetään tulostimeen...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Ohjaustiedoston lähetys onnistui\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Datatiedoston lähetys onnistui\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Muotoillaan sivua %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Ladataan kuvatiedostoa...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Etsitään tulostinta...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Avataan yhteyttä\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" +"INFO: Tulostustiedosto lähetetty, odotetaan tulostuksen valmistumista...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Tulostin varattu; yritetään uudelleen 10 sekunnin kuluttua...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Tulostin varattu; yritetään uudelleen 30 sekunnin kuluttua...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Tulostin varattu; yritetään uudelleen 5 sekunnin kuluttua...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: Tulostin ei tue IPP-versiota %d.%d. Yritetään IPP/1.0:aa...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "" +"INFO: Tulostin on varattu; yritetään uudelleen 5 sekunnin kuluttua...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Tulostin on tällä hetkellä offline.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Tulostin on tällä hetkellä offline.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Tulostin on nyt online.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Tulostin on offline.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "" +"INFO: Tulostinta ei ole yhdistetty; yritetään uudelleen 30 sekunnin " +"kuluttua...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Tulostetaan sivua %d, %d %% suoritettu...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Tulostetaan sivua %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Valmis tulostamaan.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Lähetetään ohjaustiedostoa (%lu tavua)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Lähetetään ohjaustiedostoa (%u tavua)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Lähetetään dataa\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Lähetetään datatiedostoa (%ld tavua)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Lähetetään datatiedostoa (%lld tavua)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Lähetetään tulostusdataa...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Lähetettiin tulostustiedosto, %ld tavua...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Lähetettiin tulostustiedosto, %lld tavua...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Lähetetään LPR-työtä, %.0f %% suoritettu...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Tulostimeen ei saada yhteyttä, jonotetaan luokan seuraavalle " +"tulostimelle...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Käytetään oletusarvoista AppleTalk-vyöhykettä ”%s”\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Odotetaan työn valmistumista...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Odotetaan, että tulostin tulee käytettäväksi...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 Envelope" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (ylikokoinen)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 Envelope" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 Envelope" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Virheellinen ohjausmerkki" + +msgid "Illegal main keyword string" +msgstr "Virheellinen pääavainsanan merkkijono" + +msgid "Illegal option keyword string" +msgstr "Virheellinen valinta-avainsanan merkkijono" + +msgid "Illegal translation string" +msgstr "Virheellinen käännösmerkkijono" + +msgid "Illegal whitespace character" +msgstr "Virheellinen tyhjä merkki" + +msgid "Ink/toner almost empty." +msgstr "Väriaine lähes loppu." + +msgid "Ink/toner empty!" +msgstr "Väriaine loppu!" + +msgid "Ink/toner waste bin almost full." +msgstr "Hukkavärisäiliö lähes täynnä." + +msgid "Ink/toner waste bin full!" +msgstr "Hukkavärisäiliö täynnä!" + +msgid "Installable Options" +msgstr "Asennettavat lisävarusteet" + +msgid "Installed" +msgstr "Asennettu" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar-tarratulostin" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Välilukko avoinna." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Sisäinen virhe" + +msgid "Internet Postage 2-Part" +msgstr "Internet-postimerkki kaksiosainen" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet-postimerkki kaksiosainen - 2 1/4 x 7 1/2 \"" + +msgid "Internet Postage 3-Part" +msgstr "Internet-postimerkki kolmiosainen" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet-postimerkki kolmiosainen - 2 1/4 x 7 \"" + +msgid "Internet Printing Protocol" +msgstr "Internet Printing Protocol" + +msgid "Invite Envelope" +msgstr "Kutsun kirjekuori" + +msgid "Italian Envelope" +msgstr "Italialainen kirjekuori" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Työtä %d ei voida aloittaa uudelleen - ei tiedostoja!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Työtä %d ei ole olemassa!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Työ %d on jo keskeytetty - ei voida perua." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Työ %d on jo peruttu - ei voida perua." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Työ %d on jo suoritettu - ei voida perua." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Työ %d on suoritettu eikä sitä voida muuttaa!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Työtä %d ei ole suoritettu!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Työtä %d ei pidetä todentamista varten!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Työtä %d ei pidetä!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Työtä %s ei ole olemassa!" + +#, c-format +msgid "Job %d not found!" +msgstr "Työtä %d ei löytynyt!" + +msgid "Job Completed" +msgstr "Työ suoritettu" + +msgid "Job Created" +msgstr "Työ luotu" + +msgid "Job ID: " +msgstr "Työn tunnus: " + +msgid "Job Options Changed" +msgstr "Työn valintoja muutettu" + +msgid "Job Stopped" +msgstr "Työ pysäytetty" + +msgid "Job UUID: " +msgstr "Työn UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "Työ on suoritettu eikä sitä voida muuttaa." + +msgid "Job operation failed:" +msgstr "Työtoiminto epäonnistui:" + +msgid "Job state cannot be changed." +msgstr "Työn tilaa ei voida muuttaa." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Työtilauksia ei voida uudistaa!" + +msgid "Jobs" +msgstr "Työt" + +msgid "Kaku2 Envelope" +msgstr "Kaku2 Envelope" + +msgid "Kaku3 Envelope" +msgstr "Kaku3 Envelope" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR-palvelin tai -tulostin" + +msgid "Label Printer" +msgstr "Tarratulostin" + +msgid "Label Top" +msgstr "Tarran yläpuoli" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Kieltä ”%s” ei tueta!" + +msgid "Large Address" +msgstr "Suuri osoite" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Suuri osoite - 1 4/10 x 3 1/2 \"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "Vaalea" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Rivi on pidempi kuin suurin sallittu (255 merkkiä)" + +msgid "List Available Printers" +msgstr "Luetteloi käytettävissä olevat tulostimet" + +msgid "Location: " +msgstr "Sijainti: " + +msgid "Long-Edge (Portrait)" +msgstr "Pitkä reuna (pysty)" + +msgid "Make and Model: " +msgstr "Merkki ja malli: " + +msgid "Manual Feed" +msgstr "Käsinsyöttö" + +msgid "Media Dimensions: " +msgstr "Median mitat: " + +msgid "Media Limits: " +msgstr "Median rajat: " + +msgid "Media Name: " +msgstr "Median nimi: " + +msgid "Media Size" +msgstr "Median koko" + +msgid "Media Source" +msgstr "Median lähde" + +msgid "Media Tracking" +msgstr "Median seuranta" + +msgid "Media Type" +msgstr "Median tyyppi" + +msgid "Media jam!" +msgstr "Mediatukos!" + +msgid "Media tray almost empty." +msgstr "Syöttöalusta lähes tyhjä." + +msgid "Media tray empty!" +msgstr "Syöttöalusta tyhjä!" + +msgid "Media tray missing!" +msgstr "Syöttöalusta puuttuu!" + +msgid "Media tray needs to be filled." +msgstr "Syöttöalusta on täytettävä." + +msgid "Medium" +msgstr "Keskikokoinen" + +msgid "Memory allocation error" +msgstr "Muistinvarausvirhe" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "PPD-Adobe-4.x-otsake puuttuu" + +msgid "Missing asterisk in column 1" +msgstr "Tähtimerkki puuttuu sarakkeesta 1" + +msgid "Missing document-number attribute!" +msgstr "Document-number-attribuutti puuttuu!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Kaksinkertainen lainausmerkki puuttuu riviltä %d!" + +msgid "Missing form variable!" +msgstr "Muotomuuttuja puuttuu!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "notify-subscription-ids-attribuutti puuttuu!" + +msgid "Missing requesting-user-name attribute!" +msgstr "requesting-user-name-attribuutti puuttuu!" + +msgid "Missing required attributes!" +msgstr "Vaadittuja attribuutteja puuttuu!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Arvo puuttuu riviltä %d!" + +msgid "Missing value string" +msgstr "Arvomerkkijono puuttuu" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Malli: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Muokkaa luokkaa" + +msgid "Modify Printer" +msgstr "Muokkaa tulostinta" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch Envelope" + +msgid "Move All Jobs" +msgstr "Siirrä kaikki työt" + +msgid "Move Job" +msgstr "Siirrä työ" + +msgid "Moved Permanently" +msgstr "Siirretty pysyvästi" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Tulostustiedosto hyväksytty - työn tunnus %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Tulostustiedosto hyväksytty - työn tunnus tuntematon.\n" + +msgid "NULL PPD file pointer" +msgstr "PPD-tiedoston osoitin NULL" + +msgid "Name OID uses indefinite length" +msgstr "Nimi-OID käyttää määrittelemätöntä pituutta" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Ei koskaan" + +msgid "New Stylus Color Series" +msgstr "Uusi Stylus Color Series" + +msgid "New Stylus Photo Series" +msgstr "Uusi Stylus Photo Series" + +msgid "No" +msgstr "Ei" + +msgid "No Content" +msgstr "Ei sisältöä" + +msgid "No PPD name!" +msgstr "Ei PPD-nimeä!" + +msgid "No VarBind SEQUENCE" +msgstr "Ei VarBind SEQUENCE:a" + +msgid "No Windows printer drivers are installed!" +msgstr "Windows-tulostinajureita ei ole asennettu!" + +msgid "No active connection" +msgstr "Ei aktiivista yhteyttä" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Kohteessa %s ei ole aktiivisia töitä!" + +msgid "No attributes in request!" +msgstr "Pyynnössä ei ole attribuutteja!" + +msgid "No authentication information provided!" +msgstr "Todentamistietoja ei annettu!" + +msgid "No community name" +msgstr "Ei yhteisönimeä" + +msgid "No default printer" +msgstr "Ei oletustulostinta" + +msgid "No destinations added." +msgstr "Kohteita ei lisätty." + +msgid "No error-index" +msgstr "Ei virheindeksiä" + +msgid "No error-status" +msgstr "Ei virhetilaa" + +msgid "No file!?!" +msgstr "Ei tiedostoa!?!" + +msgid "No modification time!" +msgstr "Ei muokkausaikaa!" + +msgid "No name OID" +msgstr "Ei nimi-OID:tä" + +msgid "No printer name!" +msgstr "Ei tulostimen nimeä!" + +msgid "No printer-uri found for class!" +msgstr "Luokalle ei löytynyt tulostinosoitetta!" + +msgid "No printer-uri found!" +msgstr "Tulostinosoitetta ei löytynyt!" + +msgid "No printer-uri in request!" +msgstr "Pyynnössä ei ole tulostinosoitetta!" + +msgid "No request-id" +msgstr "Ei pyyntötunnistetta" + +msgid "No subscription attributes in request!" +msgstr "Pyynnössä ei ole tilausattribuutteja!" + +msgid "No subscriptions found." +msgstr "Tilauksia ei löytynyt." + +msgid "No variable-bindings SEQUENCE" +msgstr "Ei variable-bindings SEQUENCE:a" + +msgid "No version number" +msgstr "Ei versionumeroa" + +msgid "Non-continuous (Mark sensing)" +msgstr "Ei-jatkuva (mark sensing)" + +msgid "Non-continuous (Web sensing)" +msgstr "Ei-jatkuva (web sensing)" + +msgid "Normal" +msgstr "Normaali" + +msgid "Not Found" +msgstr "Ei löytynyt" + +msgid "Not Implemented" +msgstr "Ei toteutettu" + +msgid "Not Installed" +msgstr "Ei asennettu" + +msgid "Not Modified" +msgstr "Ei muokattu" + +msgid "Not Supported" +msgstr "Ei tuettu" + +msgid "Not allowed to print." +msgstr "Tulostaminen ei ole sallittua." + +msgid "Note" +msgstr "Huomaa" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC:n käyttöikä päättymässä." + +msgid "OPC at end-of-life!" +msgstr "OPC:n käyttöikä päättynyt!" + +msgid "Off (1-Sided)" +msgstr "Pois (yksipuolinen)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Verkko-ohjeet" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "kohteen %s avaaminen epäonnistui: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup ilman edeltävää CloseGroup:ia" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI ilman edeltävää CloseUI/JCLCloseUI:ta" + +msgid "Operation Policy" +msgstr "Toimintakäytäntö" + +msgid "Options Installed" +msgstr "Valinnat asennettu" + +msgid "Options: " +msgstr "Valinnat: " + +msgid "Out of toner!" +msgstr "Väriaine loppu!" + +msgid "Output Mode" +msgstr "Tulostetila" + +msgid "Output bin almost full." +msgstr "Tulostusalusta lähes täynnä." + +msgid "Output bin full!" +msgstr "Tulostusalusta täynnä!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Tulostimen %s tuloste lähetetään kohteeseen %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Tulostimen %s tuloste lähetetään etätulostimelle %s kohteessa %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Tulostimen %s/%s tuloste lähetetään kohteeseen %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "Tulostimen %s/%s tuloste lähetetään etätulostimelle %s kohteessa %s\n" + +msgid "Output tray missing!" +msgstr "Tulostusalusta puuttuu!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "PCL-lasertulostin" + +msgid "PRC1 Envelope" +msgstr "PRC1 Envelope" + +msgid "PRC10 Envelope" +msgstr "PRC10 Envelope" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2 Envelope" + +msgid "PRC3 Envelope" +msgstr "PRC3 Envelope" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (ylikokoinen)" + +msgid "PRC4 Envelope" +msgstr "PRC4 Envelope" + +msgid "PRC5 Envelope" +msgstr "PRC5 Envelope" + +msgid "PRC6 Envelope" +msgstr "PRC6 Envelope" + +msgid "PRC7 Envelope" +msgstr "PRC7 Envelope" + +msgid "PRC8 Envelope" +msgstr "PRC8 Envelope" + +msgid "PRC9 Envelope" +msgstr "PRC9 Envelope" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Paketti ei sisällä Get-Response-PDU:ta" + +msgid "Packet does not start with SEQUENCE" +msgstr "Paketti ei ala SEQUENCE:lla" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Salasana kohteelle %s kohteessa %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "" +"Kohteelle %s tarvitaan salasana kohteen %s käyttämiseen Samban kautta: " + +msgid "Pause Class" +msgstr "Keskeytä luokka" + +msgid "Pause Printer" +msgstr "Keskeytä tulostin" + +msgid "Peel-Off" +msgstr "Irrotettava" + +msgid "Personal Envelope" +msgstr "Personal Envelope" + +msgid "Photo" +msgstr "Valokuva" + +msgid "Photo Labels" +msgstr "Valokuvatarrat" + +msgid "Plain Paper" +msgstr "Tavallinen paperi" + +msgid "Policies" +msgstr "Käytännöt" + +msgid "Port Monitor" +msgstr "Porttimonitori" + +msgid "PostScript Printer" +msgstr "PostScript-tulostin" + +msgid "Postcard" +msgstr "Postikortti" + +msgid "Print Density" +msgstr "Tulostustiheys" + +msgid "Print Job:" +msgstr "Tulosta työ:" + +msgid "Print Mode" +msgstr "Tulostustila" + +msgid "Print Rate" +msgstr "Tulostustaajuus" + +msgid "Print Self-Test Page" +msgstr "Tulosta itsetestisivu" + +msgid "Print Speed" +msgstr "Tulostusnopeus" + +msgid "Print Test Page" +msgstr "Tulosta testisivu" + +msgid "Print and Cut" +msgstr "Tulosta ja leikkaa" + +msgid "Print and Tear" +msgstr "Tulosta ja revi" + +msgid "Printed For: " +msgstr "Tulostettu kohteelle: " + +msgid "Printed From: " +msgstr "Tulostettu kohteesta: " + +msgid "Printed On: " +msgstr "Tulostettu: " + +msgid "Printer Added" +msgstr "Tulostin lisätty" + +msgid "Printer Default" +msgstr "Tulostimen oletus" + +msgid "Printer Deleted" +msgstr "Tulostin poistettu" + +msgid "Printer Modified" +msgstr "Tulostinta muokattu" + +msgid "Printer Name: " +msgstr "Tulostimen nimi: " + +msgid "Printer Paused" +msgstr "Tulostin keskeytetty" + +msgid "Printer Settings" +msgstr "Tulostinasetukset" + +msgid "Printer offline." +msgstr "Tulostin offline." + +msgid "Printer:" +msgstr "Tulostin:" + +msgid "Printers" +msgstr "Tulostimet" + +msgid "Purge Jobs" +msgstr "Poista työt" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Kiintiöraja saavutettu." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Sija Omistaja Työ Tiedostot Koko yhteensä\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Sija Omistaja Pri Työ Tiedostot Koko " +"yhteensä\n" + +msgid "Reject Jobs" +msgstr "Hylkää työt" + +msgid "Reprint After Error" +msgstr "Tulosta uudelleen virheen jälkeen" + +msgid "Request Entity Too Large" +msgstr "Pyydetty kohde liian suuri" + +msgid "Resolution" +msgstr "Tarkkuus" + +msgid "Resume Class" +msgstr "Jatka luokka" + +msgid "Resume Printer" +msgstr "Jatka tulostin" + +msgid "Return Address" +msgstr "Palautusosoite" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Palautusosoite - 3/4 x 2 \"" + +msgid "Rewind" +msgstr "Kelaa taaksepäin" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Suoritetaan komentoa: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI-tulostin" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE käyttää määrittämätöntä pituutta" + +msgid "See Other" +msgstr "Katso muu" + +#, c-format +msgid "Serial Port #%d" +msgstr "Sarjaportti %d" + +msgid "Server Restarted" +msgstr "Palvelin käynnistettiin uudelleen" + +msgid "Server Security Auditing" +msgstr "Palvelimen turvallisuustarkastus" + +msgid "Server Started" +msgstr "Palvelin käynnistetty" + +msgid "Server Stopped" +msgstr "Palvelin pysäytetty" + +msgid "Service Unavailable" +msgstr "Palvelu ei käytettävissä" + +msgid "Set Allowed Users" +msgstr "Aseta sallitut käyttäjät" + +msgid "Set As Server Default" +msgstr "Aseta palvelimen oletukseksi" + +msgid "Set Class Options" +msgstr "Aseta luokan valinnat" + +msgid "Set Printer Options" +msgstr "Aseta tulostimen valinnat" + +msgid "Set Publishing" +msgstr "Aseta julkaisu" + +msgid "Shipping Address" +msgstr "Lähetysosoite" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Lähetysosoite - 2 5/16 x 4 \"" + +msgid "Short-Edge (Landscape)" +msgstr "Lyhyt reuna (vaaka)" + +msgid "Special Paper" +msgstr "Erikoispaperi" + +msgid "Standard" +msgstr "Standardi" + +msgid "Starting Banner" +msgstr "Aloitetaan otsikkoa" + +msgid "Statement" +msgstr "Lausunto" + +msgid "Stylus Color Series" +msgstr "Stylus Color Series" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo Series" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Vaihdetaan protokollia" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (ylisuuri)" + +msgid "Tear" +msgstr "Revi" + +msgid "Tear-Off" +msgstr "Repäisy" + +msgid "Tear-Off Adjust Position" +msgstr "Repäisykohdan säätö" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "PPD-tiedostoa ”%s” ei löytynyt." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "PPD-tiedostoa ”%s” ei voitu avata: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Luokan nimi voi sisältää enintään 127 näkyvää merkkiä eikä voi sisältää " +"välilyöntejä, kauttaviivoja (/) eikä ristikkomerkkiä (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"notify-lease-duration-attribuuttia ei voida käyttää työtilausten kanssa." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "notify-user-data-arvon on liian suuri (%d > 63 oktettia)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Tulostimen nimi voi sisältää enintään 127 näkyvää merkkiä eikä voi sisältää " +"välilyöntejä, kauttaviivoja (/) eikä ristikkomerkkiä (#)." + +msgid "The printer or class is not shared!" +msgstr "Tulostinta tai luokkaa ei ole jaettu!" + +msgid "The printer or class was not found." +msgstr "Tulostinta tai luokkaa ei löytynyt." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "printer-uri ”%s” sisältää virheellisiä merkkejä." + +msgid "The printer-uri attribute is required!" +msgstr "printer-uri-attribuutti tarvitaan!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"printer-uri:n on oltava muotoa ”ipp://PALVELINNIMI/classes/LUOKANNIMI”." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"printer-uri:n on oltava muotoa ”ipp://PALVELINNIMI/printers/TULOSTIMENNIMI”." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Tilauksen nimi ei voi sisältää välilyöntejä, kauttaviivoja (/), " +"kysymysmerkkejä (?) eikä ristikkomerkkiä (#)." + +msgid "There are too many subscriptions." +msgstr "Tilauksia on liikaa." + +msgid "Thermal Transfer Media" +msgstr "Lämpösiirtomedia" + +msgid "Title: " +msgstr "Otsikko: " + +msgid "Toner low." +msgstr "Väriaine vähissä." + +msgid "Too many active jobs." +msgstr "Liikaa aktiivisia töitä." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Liikaa job-sheets-arvoja (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Liikaa printer-state-reasons-arvoja (%d > %d)!" + +msgid "Transparency" +msgstr "Kalvo" + +msgid "Tray" +msgstr "Alusta" + +msgid "Tray 1" +msgstr "Alusta 1" + +msgid "Tray 2" +msgstr "Alusta 2" + +msgid "Tray 3" +msgstr "Alusta 3" + +msgid "Tray 4" +msgstr "Alusta 4" + +msgid "URI Too Long" +msgstr "Osoite liian pitkä" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Legal" + +msgid "US Legal (Oversize)" +msgstr "US Legal (ylikokoinen)" + +msgid "US Letter" +msgstr "US Letter" + +msgid "US Letter (Oversize)" +msgstr "US Letter (ylikokoinen)" + +msgid "US Letter (Small)" +msgstr "US Letter (pieni)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB-sarjaportti %d" + +msgid "Unable to access cupsd.conf file:" +msgstr "cupsd.conf-tiedostoa ei voida käyttää:" + +msgid "Unable to add RSS subscription:" +msgstr "RSS-tilausta ei voida lisätä:" + +msgid "Unable to add class:" +msgstr "Luokkaa ei voida lisätä:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Työtä ei voida lisätä kohteelle ”%s”!" + +msgid "Unable to add printer:" +msgstr "Tulostinta ei voida lisätä:" + +msgid "Unable to allocate memory for file types!" +msgstr "Tiedostotyypeille ei voida varata muistia!" + +msgid "Unable to cancel RSS subscription:" +msgstr "RSS-tilausta ei voida perua:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "printer-is-shared-attribuuttia ei voida muuttaa:" + +msgid "Unable to change printer:" +msgstr "Tulostinta ei voida vaihtaa:" + +msgid "Unable to change server settings:" +msgstr "Palvelimen asetuksia ei voida muuttaa:" + +msgid "Unable to connect to host." +msgstr "Palvelimeen ei voida yhdistää." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "64-bittisiä CUPS-tulostinajuritiedostoja ei voida kopioida (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "64-bittisiä Windows-tulostinajuritiedostoja ei voida kopioida (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "CUPS-tulostinajuritiedostoja ei voida kopioida (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "PPD-tiedostoa ei voida kopioida - %s!" + +msgid "Unable to copy PPD file!" +msgstr "PPD-tiedostoa ei voida kopioida!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Windows 2000 -tulostinajuritiedostoja ei voida kopioida (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Windows 9x -tulostinajuritiedostoja ei voida kopioida (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Liitäntäskriptiä ei voida kopioida - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Tulostinosoitetta ei voida luoda!" + +msgid "Unable to create temporary file:" +msgstr "Tilapäistiedostoa ei voida luoda:" + +msgid "Unable to delete class:" +msgstr "Luokkaa ei voida poistaa:" + +msgid "Unable to delete printer:" +msgstr "Tulostinta ei voida poistaa:" + +msgid "Unable to do maintenance command:" +msgstr "Ylläpitokomentoa ei voida suorittaa:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "" +"cupsd.conf-tiedostoja, joka ovat suurempia kuin 1 Mt, ei voida muokata!" + +msgid "Unable to find destination for job!" +msgstr "Työlle ei löydy kohdetta!" + +msgid "Unable to find printer!\n" +msgstr "Tulostinta ei löytynyt!\n" + +msgid "Unable to get class list:" +msgstr "Luokkaluetteloa ei voida hakea:" + +msgid "Unable to get class status:" +msgstr "Luokan tilaa ei voida hakea:" + +msgid "Unable to get list of printer drivers:" +msgstr "Luetteloa tulostinajureista ei voida hakea:" + +msgid "Unable to get printer attributes:" +msgstr "Tulostimen attribuutteja ei voida hakea:" + +msgid "Unable to get printer list:" +msgstr "Tulostinluetteloa ei voida hakea:" + +msgid "Unable to get printer status:" +msgstr "Tulostimen tilaa ei voida hakea:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Windows 2000 -tulostinajuritiedostoja ei voida asentaa (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Windows 9x -tulostinajuritiedostoja ei voida asentaa (%d)!" + +msgid "Unable to modify class:" +msgstr "Luokkaa ei voida muokata:" + +msgid "Unable to modify printer:" +msgstr "Tulostinta ei voida muokata:" + +msgid "Unable to move job" +msgstr "Työtä ei voida siirtää" + +msgid "Unable to move jobs" +msgstr "Töitä ei voida siirtää" + +msgid "Unable to open PPD file" +msgstr "PPD-tiedostoa ei voida avata" + +msgid "Unable to open PPD file:" +msgstr "PPD-tiedostoa ei voida avata:" + +msgid "Unable to open cupsd.conf file:" +msgstr "cupsd.conf-tiedostoa ei voida avata:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Dokumenttia %d työssä %d ei voida avata!" + +msgid "Unable to print test page:" +msgstr "Testisivua ei voida tulostaa:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Kohdetta ”%s” ei voida suorittaa: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Komentoa ei voida lähettää tulostinajurille!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Windows-tulostinajuria ei voida asettaa (%d)!" + +msgid "Unable to set options:" +msgstr "Valintoja ei voida asettaa:" + +msgid "Unable to set server default:" +msgstr "Palvelimen oletusta ei voida asettaa:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "cupsd.conf-tiedostoa ei voida lähettää:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Vanhaa USB-luokka-ajuria ei voida käyttää!\n" + +msgid "Unauthorized" +msgstr "Valtuuttamaton" + +msgid "Units" +msgstr "Yksiköt" + +msgid "Unknown" +msgstr "Tuntematon" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Tuntematon printer-error-policy ”%s”." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Tuntematon printer-op-policy ”%s”." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Ei-tuettu merkistö ”%s”!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Ei-tuettu pakkausmenetelmä ”%s”!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Ei-tuettu pakkausattribuutti %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Ei-tuettu muoto ”%s”!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Ei-tuettu muoto ”%s”!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Ei-tuettu muoto ”%s/%s”!" + +msgid "Unsupported value type" +msgstr "Ei-tuettu arvotyyppi" + +msgid "Upgrade Required" +msgstr "Päivitys vaaditaan" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Käyttö:\n" +"\n" +" lpadmin [-h palvelin] -d kohde\n" +" lpadmin [-h palvelin] -x kohde\n" +" lpadmin [-h palvelin] -p tulostin [-c lisää-luokka] [-i liitäntä] [-m " +"malli]\n" +" [-r poista-luokka] [-v laite] [-D kuvaus]\n" +" [-P ppd-tiedosto] [-o nimi=arvo]\n" +" [-u allow:käyttäjä,käyttäjä] [-u deny:käyttäjä," +"käyttäjä]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Käyttö: %s työ käyttäjä otsikko kopioita valinnat [tiedostonimi]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Käyttö: %s job-id käyttäjä otsikko kopioita valinnat [tiedosto]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Käyttö: %s job-id käyttäjä otsikko kopioita valinnat tiedosto\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Käyttö: cupsaddsmb [valitsimet] tulostin1 ... tulostinN\n" +" cupsaddsmb [valitsimet] -a\n" +"\n" +"Valitsimet:\n" +" -E Salaa yhteys palvelimeen\n" +" -H samba-palvelin Käytä nimettyä SAMBA-palvelinta\n" +" -U samba-käyttäjä Todentaudu käyttäen nimettyä SAMBA-käyttäjää\n" +" -a Vie kaikki tulostimet\n" +" -h cups-palvelin Käytä nimettyä CUPS-palvelinta\n" +" -v Ole monisanainen (näytä komennot)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Käyttö: cupsctl [valitsimet] [param=arvo ... paramN=arvoN]\n" +"\n" +"Valitsimet:\n" +"\n" +" -E Ota salaus käyttöön\n" +" -U käyttäjätunnus Määrittele käyttäjätunnus\n" +" -h palvelin[:portti] Määrittele palvelimen osoite\n" +"\n" +" --[no-]debug-logging Laita virheiden kirjaaminen päälle tai pois " +"päältä\n" +" --[no-]remote-admin Laita etähallinta päälle tai pois päältä\n" +" --[no-]remote-any Salli tai estä pääsy internetistä\n" +" --[no-]remote-printers Näytä tai kätke etätulostimet\n" +" --[no-]share-printers Laita tulostinjako päälle tai pois päältä\n" +" --[no-]user-cancel-any Salli tai estä käyttäjien perua mikä tahansa " +"työ\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Käyttö: cupsd [-c määrittelytiedosto] [-f] [-F] [-h] [-l]\n" +"\n" +"-c määrittelytiedosto Lataa vaihtoehtoinen määrittelytiedosto\n" +"-f Suorita etualalla\n" +"-F Suorita etualalla, mutta irrota\n" +"-h Näytä tämä käyttöohje\n" +"-l Suorita cupsd launchd(8):sta\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Käyttö: cupstestdsc [valitsimet] tiedostonimi.ps [... tiedostonimi.ps]\n" +" cupstestdsc [valitsimet] -\n" +"\n" +"Valitsimet:\n" +"\n" +" -h Näytä ohjelman käyttö\n" +"\n" +" Huomaa: tämä ohjelma tarkistaa vain DSC-kommentit, ei itse " +"PostScriptiä.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Käyttö: lpmove työ/lähde kohde\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Käyttö: lpoptions [-h palvelin] [-E] -d tulostin\n" +" lpoptions [-h palvelin] [-E] [-p tulostin] -l\n" +" lpoptions [-h palvelin] [-E] -p tulostin -o valinta[=arvo] ...\n" +" lpoptions [-h palvelin] [-E] -x tulostin\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Käyttö: lppasswd [-g ryhmätunnus]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Käyttö: lppasswd [-g ryhmätunnus] [käyttäjätunnus]\n" +" lppasswd [-g ryhmätunnus] -a [käyttäjätunnus]\n" +" lppasswd [-g ryhmätunnus] -x [käyttäjätunnus]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Käyttö: lpq [-P kohde] [-U käyttäjätunnus] [-h palvelinnimi[:portti]] [-l] " +"[+aikaväli]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Käyttö: ppdc [valitsimet] tiedostonimi.drv [ ... tiedostonimiN.drv ]\n" +"Valitsimet:\n" +" -D nimi=arvo Aseta nimetty muuttuja arvoon.\n" +" -I include-hakemisto Lisää include-hakemisto hakupolkuun.\n" +" -c katalogi.po Lataa määritellyn viestikatalogin.\n" +" -d tulostehakemisto Määrittele tulostehakemisto.\n" +" -l kieli[,kieli,...] Määrittele tulostekieli (lokaali).\n" +" -m Käytä ModelName-arvoa tiedostonimenä.\n" +" -t Testaa PPD:t niiden luomisen sijasta.\n" +" -v Ole monisanainen (useammat v-kirjaimet lisäävät " +"monisanaisuutta).\n" +" -z Pakkaa PPD-tiedostot GNU zipillä.\n" +" --cr Päätä rivit CR:llä (Mac OS 9).\n" +" --crlf Päätä rivit CR + LF:llä (Windows).\n" +" --lf Päätä rivit LF:llä (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Käyttö: ppdhtml [valitsimet] tiedostonimi.drv > tiedostonimi.html\n" +" -D nimi=arvo Aseta nimetty muuttuja arvoon.\n" +"Valinnat:\n" +" -I include-hakemisto Lisää include-hakemisto hakupolkuun.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Käyttö: ppdi [valitsimet] tiedostonimi.ppd [ ... tiedostonimiN.ppd ]\n" +"Valitsimet:\n" +" -I include-hakemisto\n" +" -o tiedostonimi.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Käyttö: ppdmerge [valitsimet] tiedostonimi.ppd [ ... tiedostonimiN.ppd ]\n" +"Valitsimet:\n" +" -o tiedostonimi.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Käyttö: ppdpo [valitsimet] -o tiedostonimi.po tiedostonimi.drv [ ... " +"tiedostonimiN.drv ]\n" +"Valitsimet:\n" +" -D nimi=arvo Aseta nimetty muuttuja arvoon.\n" +" -I include-hakemisto Lisää include-hakemisto hakupolkuun.\n" +" -v Ole monisanainen (useammat v-kirjaimet lisäävät " +"monisanaisuutta).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Käyttö: snmp [palvelin-tai-ip-osoite]\n" + +msgid "Value uses indefinite length" +msgstr "Arvo käyttää määrittämätöntä pituutta" + +msgid "VarBind uses indefinite length" +msgstr "VarBind käyttää määrittämätöntä pituutta" + +msgid "Version uses indefinite length" +msgstr "Versio käyttää määrittämätöntä pituutta" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Lisätään vain %d ensimmäistä löydettyä tulostinta" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: waiteof-valinnalle ”%s” odotettiin totuusarvoa\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Sivukanavapyyntöä ei voitu lukea!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: Valintaa ”%s” ei voida sisällyttää IncludeFeature:n kautta!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Tulostin ei vastaa\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Tulostin lähetti odottamattoman EOF:n\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Etäpalvelin ei vastannut komentotilatavulla %d sekunnin jälkeen!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Etäpalvelin ei vastannut ohjaustilatavulla %d sekunnin jälkeen!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Etäpalvelin ei vastannut datatilatavulla %d sekunnin jälkeen!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI-komento aikakatkaistiin (%d); yritetään uudelleen...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Tämä dokumentti ei ole Adobe Document Structuring Conventions -" +"määrityksen mukainen eikä välttämättä tulostu oikein!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Kohdetta ”%s:%s” ei voida avata: %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: PAP status -pyyntöä ei voida lähettää" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Odottamaton PAP-paketti tyyppiä %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Tuntematon PAP-paketti tyyppiä %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Tuntematon vaihtoehto ”%s” valinnalle ”%s”!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Tuntematon valinta ”%s”!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Ei-tuettu siirtonopeus %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: tilavalinnalle ”%s” odotettiin numeroarvoa\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: korjattavissa: Verkkopalvelin ”%s” on varattu; yritetään uudelleen %" +"d sekunnin kuluttua...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Varoitus, Windows 2000 -tulostinajureita ei ole asennettu!" + +msgid "Yes" +msgstr "Kyllä" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Sivua on käytettävä käyttäen osoitetta https://%" +"s:%d%s." + +msgid "You4 Envelope" +msgstr "You4 Envelope" + +msgid "ZPL Label Printer" +msgstr "ZPL-tarratulostin" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "keskeytetty" + +msgid "canceled" +msgstr "peruttu" + +msgid "completed" +msgstr "suoritettu" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: Määrittele muunnettava tiedosto f-valitsimella.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced:n suorittaminen epäonnistui." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd:n suorittaminen epäonnistui." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Tulostimelle ”%s” ei ole PPD-tiedostoa - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Palvelimeen ei voida yhdistää: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Tuntematon valinta ”%s”!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Tuntematon valinta ”-%c”!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: c-valitsimen jälkeen odotettiin määrittelytiedoston nimeä!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Nykyistä hakemistoa ei voida hakea!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Tuntematon argumentti ”%s” - keskeytetään!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Tuntematon valinta ”%c” - keskeytetään!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: launchd(8)-tukea ei ole käännetty mukaan, toimitaan normaalitilassa.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Virheellinen dokumenttinumero %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: Virheellinen työtunnus %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Vain yksi tiedostonimi voidaan määritellä!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Työtiedostoa ei voida hakea - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: q-valitsin ei ole yhteensopiva v-valitsimen kanssa.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: v-valitsin ei ole yhteensopiva q-valitsimen kanssa.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "laite kohteelle %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "laite kohteelle %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index käyttää määrittämätöntä pituutta" + +msgid "error-status uses indefinite length" +msgstr "error-status käyttää määrittämätöntä pituutta" + +msgid "held" +msgstr "pidetty" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tsaat tietoja komennoista\n" + +msgid "idle" +msgstr "toimeton" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri-attribuutti puuttuu!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Luokan nimi voi sisältää vain näkyviä merkkejä!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: P-valitsimen jälkeen odotettiin PPD:tä!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "" +"lpadmin: u-valitsimen jälkeen odotettiin allow/deny:käyttäjäluettelo!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: r-valitsimen jälkeen odotettiin luokkaa!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: c-valitsimen jälkeen odotettiin luokan nimeä!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: D-valitsimen jälkeen odotettiin kuvausta!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: v-valitsimen jälkeen odotettiin laiteosoitetta!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: I-valitsimen jälkeen odotettiin tiedostotyyppejä!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: h-valitsimen jälkeen odotettiin palvelinnimeä!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: i-valitsimen jälkeen odotettiin liitäntää!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: L-valitsimen jälkeen odotettiin sijaintia!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: m-valitsimen jälkeen odotettiin mallia!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: o-valitsimen jälkeen odotettiin nimi=arvo!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: p-valitsimen jälkeen odotettiin tulostinta!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: d-valitsimen jälkeen odotettiin tulostimen nimeä!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: x-valitsimen jälkeen odotettiin tulostinta tai luokkaa!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Jäsennimiä ei havaittu!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Tulostin %s on jo luokan %s jäsen.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Tulostin %s ei ole luokan %s jäsen.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Tulostimen nimi voi sisältää vain näkyviä merkkejä!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tulostinta ei voida lisätä luokkaan:\n" +" Määrittele tulostimen nimi ensin!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Palvelimeen ei voida yhdistää: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: PPD-tiedostoa ”%s” ei voida avata - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Tiedostoa ”%s” ei voida avata: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tulostinta ei voida poistaa luokasta:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: PPD-tiedostoa ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Laiteosoitetta ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Liitäntäskriptiä tai PPD-tiedostoa ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Liitäntäskriptiä ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tulostimen kuvausta ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tulostimen sijaintia ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tulostimen valintoja ei voida asettaa:\n" +" Määrittele tulostimen nimi ensin!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Tuntematon allow/deny-valinta ”%s”!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Tuntematon argumentti ”%s”!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Tuntematon valinta ”%c”!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Varoitus - sisällöntyyppiluettelo jätettiin huomioimatta!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" +"lpinfo: --device-id:n jälkeen odotettiin 1284-laitetunnistemerkkijonoa!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: --language:n jälkeen odotettiin kieltä!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: --make-and-model:n jälkeen odotettiin merkkiä ja mallia!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: --product:n jälkeen odotettiin tuotemerkkijonoa!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: --exclude-schemes:n jälkeen odotettiin malliluetteloa!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: --include-schemes:n jälkeen odotettiin malliluetteloa!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: --timeout:n jälkeen odotettiin aikakatkaisua!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Tuntematon argumentti ”%s”!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Tuntematon valinta ”%c”!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Tuntematon valinta ”%s”!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Palvelimeen ei voida yhdistää: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Tuntematon argumentti ”%s”!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Tuntematon valinta ”%c”!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Ei tulostimia!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Tulostinta tai esiintymää ei voida lisätä: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: PPD-tiedostoa ei voida hakea kohteelle %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: PPD-tiedostoa ei voida avata kohteelle %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Tuntematon tulostin tai luokka!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Vain root voi lisätä tai poistaa salasanoja!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Salasanatiedosto on varattu!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Salasanatiedostoa ei päivitetty!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Salasana ei täsmää!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Salasana hylättiin.\n" +"Salasanan on oltava vähintään 6 merkkiä pitkä, se ei saa sisältää\n" +"käyttäjätunnustasi ja sen on sisällettävä vähintään yksi kirjain ja numero.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Salasanat eivät täsmää!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Salasanamerkkijonoa ei voida kopioida: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Salasanatiedostoa ei voida avata: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Salasanatiedostoon ei voida kirjoittaa: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: vanhaa salasanatiedostoa ei voitu varmuuskopioida: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: salasanatiedoston nimeä ei voitu muuttaa: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: käyttäjää ”%s” ja ryhmää ”%s” ei ole olemassa.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: virhe - %s ympäristömuuttujanimien kohdetta ”%s” ei ole olemassa!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "jäsen luokassa %s:\n" + +msgid "no entries\n" +msgstr "ei tietueita\n" + +msgid "no system default destination\n" +msgstr "ei järjestelmän oletuskohdetta\n" + +msgid "notify-events not specified!" +msgstr "notify-events:iä ei määritelty!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri-osoite ”%s” on jo käytössä!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri-osoite ”%s” käyttää tuntematonta mallia!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d ei kelpaa!" + +msgid "pending" +msgstr "odottaa" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Lisätään include-hakemistoa ”%s”...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Lisätään/päivitetään käyttöliittymätekstiä kohteesta %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Virheellinen totuusarvo (%s) rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Virheellinen tarkkuuden nimi ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Virheellinen tila-avainsana ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Virheellinen muuttujan korvaus ($%c) rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Riviltä %d / %s löytyi vaihtoehto ilman valintaa!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Kaksoiskappale #po lokaalille %s rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Odotettiin suodinmääritystä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Odotettiin ohjelman nimeä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Odotettiin totuusarvoa rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Odotettiin merkistöä Font:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Odotettiin vaihtoehtokoodia rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Odotettiin vaihtoehtonimeä/-tekstiä rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Odotettiin värijärjestystä ColorModel:ille rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Odotettiin väriavaruutta ColorModel:ille rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Odotettiin pakkausta ColorModel:ille rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Odotettiin rajoitusmerkkijonoa UIConstraints:ille rivillä %d / %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Odotettiin ajurintyypin avainsanaa DriverType:lle rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Odotettiin dupleksityyppiä Duplex:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Odotettiin koodausta Font:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Odotettiin tiedostonimeä #po:n %s jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Odotettiin ryhmänimeä/-tekstiä rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Odotettiin include-tiedoston nimeä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Odotettiin kokonaislukua rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Odotettiin lokaalia #po:n jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä kohteen %s jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä FileName:n jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä Font:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä Manufacturer:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä MediaSize:n jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä ModelName:n jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä PCFileName:n jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Odotettiin nimeä/tekstiä kohteen %s jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "" +"ppdc: Odotettiin nimeä/tekstiä Installable:n jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: Odotettiin nimeä/tekstiä Resolution:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Odotettiin nimi-/tekstiyhdistelmää ColorModel:ille rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Odotettiin valintanimeä/-tekstiä rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Odotettiin valintaosiota rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Odotettiin valintatyyppiä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: Odotettiin ohituskenttää Resolution:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Odotettiin reaalilukua rivillä %d / %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Odotettiin tarkkuutta/mediatyyppi ColorProfile:n jälkeen rivillä %d / %" +"s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Odotettiin tarkkuutta/mediatyyppi SimpleColorProfile:n jälkeen rivillä " +"%d / %s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Odotettiin valitsijaa kohteen %s jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Odotettiin tilaa Font:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Odotettiin merkkijonoa Copyright:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Odotettiin merkkijonoa Version:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Odotettiin kahta valintanimeä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Odotettiin arvoa kohteen %s jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Odotettiin versiota Font:in jälkeen rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Virheellinen #include/#po-tiedostonimi ”%s”!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Virheellinen hinta suotimelle rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Virheellinen tyhjä MIME-tyyppi suotimelle rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Virheellinen tyhjä ohjelman nimi suotimelle rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Virheellinen valintaosio ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Virheellinen valintatyyppi ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Ladataan ajurin tietotiedostoa ”%s”...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Ladataan viestejä lokaalille ”%s”...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Ladataan viestejä kohteesta ”%s”...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif puuttuu kohteen ”%s” lopusta!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if puuttuu riviltä %d / %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Ei viestikatalogia lokaalille %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: Valinta %s määritelty uudelleen eri tyypillä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Valintarajoituksen on tehtävä *name rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Liikaa sisäkkäisiä #if:ejä rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: PPD-tiedostoa ”%s” ei voida luoda - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Tulostushakemistoa %s ei voida luoda: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Tulostusputkia ei voida luoda: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: cupstestppd:ia ei voida suorittaa: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: #po-tiedostoa %s ei löytynyt riviltä %d / %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: include-tiedostoa ”%s” ei löytynyt riviltä %d / %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Lokalisointia kohteelle ”%s” ei löytynyt - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Lokalisointitiedostoa ”%s” ei voitu ladata - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Määrittelemätön muuttuja (%s) rivillä %d / %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Tuntematon ajurityyppi %s rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tuntematon dupleksityyppi ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tuntematon mediakoko ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Tuntematon token ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Tuntemattomia seuraavia merkkejä reaaliluvussa ”%s” rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Määrittelemätön merkkijono, joka alkaa %c, rivillä %d / %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Kirjoitetaan %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Kirjoitetaan PPD-tiedostoja hakemistoon ”%s”...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Virheellinen LanguageVersion ”%s” kohteessa %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Jätetään huomioimatta PPD-tiedosto %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Kohdetta %s ei voida varmuuskopioida kohteeseen %s - %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "tulostin %s poissa käytöstä alkaen %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "tulostin %s on toimettomana. käytössä alkaen %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "tulostin %s tulostaa %s-%d. käytössä alkaen %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "tulostin %s/%s poissa käytöstä alkaen %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "tulostin %s/%s on toimettomana. käytössä alkaen %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "tulostin %s/%s tulostaa %s-%d. käytössä alkaen %s\n" + +msgid "processing" +msgstr "käsitellään" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "pyynnön tunnus on %s-%d (%d tiedostoa)\n" + +msgid "request-id uses indefinite length" +msgstr "request-id käyttää määrittämätöntä pituutta" + +msgid "scheduler is not running\n" +msgstr "ajastin ei ole käynnissä\n" + +msgid "scheduler is running\n" +msgstr "ajastin on käynnissä\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "kohteen %s stat epäonnistui: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tnäytä taustaprosessin tila ja jono\n" + +msgid "stopped" +msgstr "pysäytetty" + +#, c-format +msgid "system default destination: %s\n" +msgstr "järjestelmän oletuskohde: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "järjestelmän oletuskohde: %s/%s\n" + +msgid "unknown" +msgstr "tuntematon" + +msgid "untitled" +msgstr "nimetön" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings käyttää määrittämätöntä pituutta" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN APDialogExtension-tiedosto ”%s” puuttuu\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN APPrinterIconPath-tiedosto ”%s” puuttuu\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Kohdetta %s ei voida avata - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Kohdetta %s ei voida avata - %s linjalla %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 dpi harmaasävy" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Laitteen osoite puuttuu komentoriviltä eikä DEVICE_URI-" +#~ "ympäristömuuttujaa ole määritelty!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Tilapäistiedostoa ei voida luoda - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Tilapäistiedostoa ei voida luoda: %s.\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Tilapäistiedostoa ei voida avata" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops-suodin kaatui signaaliin %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops-suodin lopetti signaaliin %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Tuntematon tulostinvirhe (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Käyttö: convert [ valitsimet ]\n" +#~ "\n" +#~ "Valitsimet:\n" +#~ "\n" +#~ " -f tiedostonimi Aseta muunnettava tiedosto (muussa tapauksessa " +#~ "stdin)\n" +#~ " -o tiedostonimi Aseta luotava tiedosto (muussa tapauksessa " +#~ "stdout)\n" +#~ " -i mime/tyyppi Aseta syötteen MIME-tyyppi (muussa tapauksessa " +#~ "määritetään automaattisesti)\n" +#~ " -j mime/tyyppi Aseta tulosteen MIME-tyyppi (muussa tapauksessa " +#~ "application/pdf)\n" +#~ " -P tiedostonimi.ppd Aseta PPD-tiedosto\n" +#~ " -a 'nimi=arvo ...' Aseta valintoja\n" +#~ " -U käyttäjätunnus Aseta työn käyttäjätunnus\n" +#~ " -J otsikko Aseta otsikko\n" +#~ " -c kopioita Aseta kopioiden määrä\n" +#~ " -u Poista PPD-tiedosto, kun valmis\n" +#~ " -D Poista syötetiedosto, kun valmis\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Käyttö: cupsfilter -m mime/tyyppi [ valitsimet ] tiedostonimi\n" +#~ "\n" +#~ "Valitsimet:\n" +#~ "\n" +#~ " -c cupsd.conf Aseta käytettävä cupsd.conf-tiedosto\n" +#~ " -j job-id[,N] Suodintiedosto N määritellystä työstä (oletus on " +#~ "tiedosto 1)\n" +#~ " -n kopiot Aseta kopioiden määrä\n" +#~ " -o nimi=arvo Aseta valintoja\n" +#~ " -p tiedostonimi.ppd Aseta PPD-tiedosto\n" +#~ " -t otsikko Aseta otsikko\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Käyttö: cupstestppd [valitsimet] tiedostonimi1.ppd[.gz] [... " +#~ "tiedostonimiN.ppd[.gz]]\n" +#~ " ohjelma | cupstestppd [valitsimet] -\n" +#~ "\n" +#~ "Valitsimet:\n" +#~ "\n" +#~ " -R juurihakemisto Aseta vaihtoehtoinen juuri\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Anna varoituksia virheiden sijasta\n" +#~ " -q Suorita hiljaa\n" +#~ " -r Käytä ”rentoa” avointa tilaa\n" +#~ " -v Ole monisanainen\n" +#~ " -vv Ole erittäin monisanainen\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Tilapäistiedostoa ei voida luoda: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Tilapäistiedostoa ei voida luoda - %s.\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Tilapäistiedostoa ei voida luoda: %s\n" diff --git a/locale/cups_fr.po b/locale/cups_fr.po new file mode 100644 index 0000000000..f345954acf --- /dev/null +++ b/locale/cups_fr.po @@ -0,0 +1,5783 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(tous)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(aucun)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d entrées\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tAprès une erreur : poursuivre\n" + +msgid "\tAlerts:" +msgstr "\tAlertes :" + +msgid "\tBanner required\n" +msgstr "\tBannière requise\n" + +msgid "\tCharset sets:\n" +msgstr "\tJeux de caractères :\n" + +msgid "\tConnection: direct\n" +msgstr "\tConnexion : directe\n" + +msgid "\tConnection: remote\n" +msgstr "\tConnexion : distante\n" + +msgid "\tDefault page size:\n" +msgstr "\tTaille de papier par défaut :\n" + +msgid "\tDefault pitch:\n" +msgstr "\tTon par défaut :\n" + +msgid "\tDefault port settings:\n" +msgstr "\tRéglages par défaut du port :\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDescription : %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormat monté :\n" +"\tType de contenu : any (quelconque)\n" +"\tType d’imprimantes : unknown (inconnu)\n" + +msgid "\tForms allowed:\n" +msgstr "\tFormats autorisés :\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterface : %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterface : %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterface : %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tEmplacement : %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tEn cas d’erreur : aucun avertissement\n" + +msgid "\tUsers allowed:\n" +msgstr "\tUtilisateurs autorisés :\n" + +msgid "\tUsers denied:\n" +msgstr "\tUtilisateurs refusés :\n" + +msgid "\tdaemon present\n" +msgstr "\tdaemon présent\n" + +msgid "\tno entries\n" +msgstr "\taucune entrée\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tl’imprimante correspond au périphérique « %s », débit -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tl’impression est désactivée\n" + +msgid "\tprinting is enabled\n" +msgstr "\tl’impression est activée\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tmis en file d’attente pour %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tla mise en file d’attente est désactivée\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tla mise en file d’attente est activée\n" + +msgid "\treason unknown\n" +msgstr "\traison inconnue\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" RÉSULTATS DÉTAILLÉS DU TEST DE CONFORMITÉ\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF : page 15, rubrique 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF : page 15, rubrique 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF : page 19, rubrique 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF : page 20, rubrique 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF : page 27, rubrique 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF : page 42, rubrique 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF : pages 16 et 17, rubrique 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF : pages 42 à 45, rubrique 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF : pages 45 et 46, rubrique 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF : pages 48 et 49, rubrique 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF : pages 52 à 54, rubrique 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f octets\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " VALIDE Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " VALIDE DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " VALIDE DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " VALIDE FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " VALIDE FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " VALIDE LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " VALIDE LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " VALIDE Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " VALIDE ModelName\n" + +msgid " PASS NickName\n" +msgstr " VALIDE NickName\n" + +msgid " PASS PCFileName\n" +msgstr " VALIDE PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " VALIDE PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " VALIDE PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " VALIDE PageSize\n" + +msgid " PASS Product\n" +msgstr " VALIDE Product\n" + +msgid " PASS ShortNickName\n" +msgstr " VALIDE ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" ATTN « %s %s » entre en conflit avec « %s %s ».\n" +" (constraint=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " ATTN Aucune option ne correspond à %s.\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" ATTN %s partage un préfixe avec %s\n" +" REF : page 15, rubrique 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " ATTN Choix par défaut en conflit.\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" ATTN Le mot-clé %s d’option duplex peut ne pas fonctionner comme " +"attendu et doit s’intituler Duplex.\n" +" REF : page 122, rubrique 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" ATTN Le fichier contient un mélange de fins de ligne CR, LF et CR " +"LF.\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" ATTN LanguageEncoding requis d’après les spécifications PPD 4.3\n" +" REF : pages 56 et 57, rubrique 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " ATTN La ligne %d ne contient que des espaces blancs.\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" ATTN Paramètre Manufacturer requis d’après les spécifications PPD " +"4.3\n" +" REF : pages 58 et 59, rubrique 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" ATTN Les fichiers PPD non-Windows doivent utiliser des fins de " +"ligne définis uniquement par LF et non CR LF.\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" ATTN Version PPD obsolète %.1f.\n" +" REF : page 42, rubrique 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" ATTN Le nom de fichier PCFileName ne respecte pas les " +"spécifications PPD pour le format 8.3\n" +" REF : pages 61 et 62, rubrique 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" ATTN La section Protocols contient PJL mais les attributs JCL ne " +"sont pas définis.\n" +" REF : pages 78 et 79, rubrique 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" ATTN La section Protocols contient PJL et BCP, mais TBCP est " +"attendu.\n" +" REF : pages 78 et 79, rubrique 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" ATTN ShortNickName requis d’après les spécifications PPD 4.3\n" +" REF : pages 64 et 65, rubrique 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s n’existe pas.\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Choix %s erroné %s.\n" +" REF  : page 122, rubrique 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" +" %s Chaîne de traduction UTF-8 « %s » incorrecte pour l’option %s.\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Chaîne de traduction UTF-8 « %s » incorrecte pour l’option %s, le " +"choix %s.\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Valeur cupsFilter « %s » incorrecte.\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s cupsICCProfile « %s »  incorrect.\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Valeur cupsPreFilter « %s » incorrecte.\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s cupsUIConstraints %s : « %s ».\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Langue « %s » incorrecte.\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints %s vide.\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Chaîne de traduction « %s » manquante pour l’option %s.\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Chaîne de traduction « %s » manquante pour l’option %s et le choix %" +"s.\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Choix manquant *%s %s dans UIConstraints « *%s %s *%s %s ».\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Choix manquant *%s %s dans cupsUIConstraints %s :« %s ».\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Fichier cupsFilter manquant « %s ».\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Fichier cupsICCProfile manquant « %s ».\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Fichier cupsPreFilter manquant « %s ».\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s cupsUIResolver manquant « %s ».\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Option %s manquante dans UIConstraints « *%s %s *%s %s ».\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Option %s manquante dans cupsUIConstraints %s : « %s ».\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr "" +" %s Aucune traduction de base « %s » n’est comprise dans le fichier.\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s %s requis ne définit pas le choix Aucun.\n" +" REF : page 122, rubrique 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr "" +" %s La valeur de hachage cupsICCProfile %s entre en collision avec %" +"s.\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s provoque une boucle.\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **ÉCHEC** Les noms de choix %s %s et %s diffèrent seulement par leurs " +"majuscules.\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **ÉCHEC** %s doit correspondre à 1284DeviceID.\n" +" REF : page 72, rubrique 5.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **ÉCHEC** Default%s %s erroné.\n" +" REF : page 40, rubrique 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **ÉCHEC** DefaultImageableArea %s erroné.\n" +" REF : page 102, rubrique 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **ÉCHEC** DefaultPaperDimension %s erroné.\n" +" REF : page 103, rubrique 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **ÉCHEC** Attribut JobPatchFile erroné dans le fichier.\n" +" REF : page 24, rubrique 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **ÉCHEC** Manufacturer erroné (doit être « HP »)\n" +" REF : page 211, tableau D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **ÉCHEC** Manufacturer incorrect (doit être « Oki »)\n" +" REF : page 211, tableau D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **ÉCHEC** ModelName erroné - « %c » interdit dans la chaîne.\n" +" REF : pages 59 et 60, rubrique 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **ÉCHEC** PSVersion erroné - différent de « (string) int ».\n" +" REF : pages 62 à 64, rubrique 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **ÉCHEC** Paramètre Product erroné - différent de « (string) ».\n" +" REF : page 62, rubrique 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **ÉCHEC** ShortNickName erroné - dépasse 31 caractères.\n" +" REF : pages 64 et 65, rubrique 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **ÉCHEC** Choix %s %s erroné.\n" +" REF : page 84, rubrique 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **ÉCHEC** FileVersion « %s » incorrect\n" +" REF : page 56, rubrique 5.3." + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **ÉCHEC** FormatVersion « %s » incorrect\n" +" REF : page 56, section 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **ÉCHEC** LanguageEncoding %s incorrect - doit correspondre à " +"ISOLatin1.\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **ÉCHEC** LanguageVersion %s incorrect - doit correspondre à " +"Anglais.\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **ÉCHEC** Le code de l’option par défaut ne peut pas être " +"interprété : %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **ÉCHEC** La chaîne de traduction par défaut pour l’option %s, choix %" +"s, contient des caractères 8 bits.\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **ÉCHEC** La chaîne de traduction par défaut pour l’option %s " +"contient des caractères 8 bits.\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **ÉCHEC** Les noms de groupe %s et %s diffèrent seulement par leurs " +"majuscules.\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **ÉCHEC** Plusieurs occurrences de %s, nom de choix %s.\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **ÉCHEC** Noms d’option %s et %s diffèrent seulement par leurs " +"majuscules.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **ÉCHEC** Default%s requis\n" +" REF : page 40, rubrique 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **ÉCHEC** DefaultImageableArea requis\n" +" REF : page 102, rubrique 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **ÉCHEC** DefaultPaperDimension requis\n" +" REF : page 103, rubrique 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **ÉCHEC** FileVersion requis\n" +" REF : page 56, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **ÉCHEC** FormatVersion requis\n" +" REF : page 56, rubrique 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **ÉCHEC** ImageableArea requis pour PageSize %s\n" +" REF : page 41, rubrique 5.\n" +" REF : page 102, rubrique 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **ÉCHEC** LanguageEncoding requis\n" +" REF : pages 56 et 57, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **ÉCHEC** LanguageVersion requis\n" +" REF : pages 57 et 58, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **ÉCHEC** Manufacturer requis\n" +" REF : pages 58 et 59, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **ÉCHEC** ModelName requis\n" +" REF : pages 59 et 60, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **ÉCHEC** NickName requis\n" +" REF : page 60, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **ÉCHEC** PCFileName requis\n" +" REF : pages 61 et 62, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **ÉCHEC** PSVersion requis\n" +" REF : pages 62 à 64, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **ÉCHEC** PageRegion requis\n" +" REF : page 100, rubrique 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **ÉCHEC** PageSize requis\n" +" REF : page 41, rubrique 5.\n" +" REF : page 99, rubrique 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **ÉCHEC** PageSize requis\n" +" REF : pages 99 et 100, rubrique 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **ÉCHEC** PaperDimension requis pour PageSize %s\n" +" REF : page 41, rubrique 5.\n" +" REF : page 103, rubrique 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **ÉCHEC** Product requis\n" +" REF : page 62, rubrique 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **ÉCHEC** ShortNickName requis\n" +" REF : page 64 et 65, rubrique 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr "%d ERREURS TROUVÉES\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" %%%%BoundingBox erroné : %d en ligne.\n" +" REF : page 39, %%%%BoundingBox :\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" %%%%Page erroné  : %d en ligne.\n" +" REF : page 53, %%%%Page :\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" %%%%Pages erroné : %d en ligne.\n" +" REF : page 43, %%%%Pages :\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" La ligne %d dépasse 255 caractères (%d).\n" +" REF : page 25, longueur de ligne\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 manquant à la première ligne.\n" +" REF : page 17, 3.1 Uniformisation des documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Commentaire %%EndComments manquant.\n" +" REF : page 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox manquant ou erroné : commentaire.\n" +" REF : page 39, %%BoundingBox :\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page manquant ou erroné : commentaires.\n" +" REF: page 53, %%Page :\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages manquant ou erroné : commentaire.\n" +" REF : page 43, %%Pages :\n" + +msgid " NO ERRORS FOUND\n" +msgstr " AUCUNE ERREUR RENCONTRÉE\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " %d lignes dépassant 255 caractères rencontrées.\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Commentaires %%BeginDocument trop nombreux.\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Commentaires %%EndDocument trop nombreux.\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Attention : le fichier contient des données binaires.\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Attention : pas de commentaire %%EndComments dans le fichier.\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Attention : version DSC obsolète %.1f dans le fichier.\n" + +msgid " FAIL\n" +msgstr " ÉCHEC\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" ÉCHEC\n" +" **ÉCHEC** Impossible d’ouvrir le fichier - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" ÉCHEC\n" +" **ÉCHEC** Impossible d’ouvrir le fichier - %s en ligne %d.\n" + +msgid " PASS\n" +msgstr " VALIDE\n" + +msgid "#10 Envelope" +msgstr "#10 Enveloppe" + +msgid "#11 Envelope" +msgstr "#11 Enveloppe" + +msgid "#12 Envelope" +msgstr "#12 Enveloppe" + +msgid "#14 Envelope" +msgstr "#14 Enveloppe" + +msgid "#9 Envelope" +msgstr "#9 Enveloppe" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f octets\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f octets\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f millimètres" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f à %.0f x %.0f millimètres" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f pouces" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f à %.2f x %.2f pouces" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s acceptant des requêtes depuis %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "Impossible de modifier « %s »." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s n’est pas implémenté par la version CUPS de lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s n’est pas prêt\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s est prêt\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s est prêt et en cours d’impression\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s n’acceptant pas de requêtes depuis %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s : opération non prise en charge." + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s%s acceptant des requêtes depuis %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s n’acceptant pas de requêtes depuis %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s : %-33.33s [tâche %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s : %s échoué : %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s : aucune décision possible.\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s : Erreur - %s destination non-existante des noms de variable " +"d’environnement « %s ».\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s : erreur - ID de tâche incorrect.\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s : erreur - ne peut pas imprimer les fichiers et modifier les tâches " +"simultanément.\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s : erreur - ne peut pas imprimer depuis stdin si les fichiers ou l’ID de " +"tâche sont fournis.\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s : erreur - jeu de caractères attendu après l’option « -S ».\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s : erreur - type de contenu attendu après l’option « -T ».\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s : erreur - copies attendues après l’option « -n ».\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s : erreur - nombre de copies attendu après l’option « -# ».\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s : erreur - destination attendue après l’option « -P ».\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s : erreur - destination attendue après l’option « -b ».\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s : erreur - destination attendue après l’option « -d ».\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s : erreur - formulaire attendu après l’option « -f ».\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s : erreur - nom de maintien attendu après l’option « -H ».\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s : erreur - nom d’hôte attendu après l’option « -H ».\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s : erreur - nom d’hôte attendu après l’option « -h ».\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s : erreur - liste des modes attendue après l’option « -y ».\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s : erreur - nom attendu après l’option « -%c ».\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s : erreur - chaîne d’option attendue après l’option « -o ».\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s : erreur - liste de pages attendue après l’option « -P ».\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s : erreur - priorité attendue après l’option « -%c ».\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s : erreur - raison attendue après l’option « -r ».\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s : erreur - titre attendu après l’option « -t ».\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s : erreur - nom d’utilisateur attendu après l’option « -U.\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s : erreur - nom d’utilisateur attendu après l’option « -u ».\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s : erreur - valeur attendue après l’option « -%c ».\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s : erreur - « terminé », « pas terminé » ou « tout » nécessaire après " +"l’option « -W ».\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s : erreur - aucune destination par défaut disponible.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s : erreur - la priorité doit être comprise entre 1 et 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Erreur - le programmateur ne répond pas.\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s : erreur - fichiers trop nombreux - « %s »\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s : erreur - impossible d’accéder à « %s » - %s" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "" +"%s : erreur - impossible de mettre en file d’attente depuis stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s : erreur - destination inconnue « %s ».\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s : erreur - destination inconnue « %s/%s ».\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s : erreur - option inconnue « -%c ».\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s : erreur - option inconnue « -%s ».\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s : erreur - ID de tâche attendu après l’option « -i ».\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s : filtre « %s » indisponible : %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s : nom de destination dans la liste « %s »  non valide.\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s : chaîne de filtre « %s » non valide" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "" +"%s : identifiant de tâche (« -i jobid ») nécessaire avant « -H restart ».\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s : aucun filtre pour convertir %s/%s en %s/%s.\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s : l’opération a échoué : %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "" +"%s : désolé, aucune prise en charge du chiffrement incluse dans la " +"compilation.\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s : Connexion impossible au serveur\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s : impossible de contacter le serveur.\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr " %s : impossible de déterminer le type MIME de « %s ».\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s : impossible d’ouvrir %s : %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s : impossible d’ouvrir le fichier PPD : %s à la ligne %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "" +"%s : impossible de lire la base de données MIME à partir de « %s » ou « %s ».\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s : destination inconnue « %s ».\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s : destination inconnue du type MIME %s/%s.\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s : option inconnue « %c ».\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s : source inconnue du type MIME %s/%s.\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s : avertissement - modification de format « %c » non prise en charge - la " +"sortie risque d’être incorrecte.\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s : avertissement - option du jeu de caractères ignorée.\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s : avertissement - option du type de contenu ignorée.\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s : avertissement - option de formulaire ignorée.\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s : avertissement - option de mode ignorée.\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s : erreur - %s destination non-existante des noms de variable " +"d’environnement « %s ».\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s : erreur - « option=valeur » attendu après l’option « -o ».\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s : erreur - aucune destination par défaut disponible.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 po/s" + +msgid "1.25x0.25\"" +msgstr "1,25 x 0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25 x 2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 po/s" + +msgid "1.50x0.25\"" +msgstr "1,50 x 0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50 x 0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50 x 1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50 x 2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 po/s" + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/s" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 po/s" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 po/s" + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/s" + +msgid "120x60dpi" +msgstr "120 x 60 ppp" + +msgid "120x72dpi" +msgstr "120 x 72 ppp" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 ppp" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/s" + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/s" + +msgid "150dpi" +msgstr "150 ppp" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 ppp" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 po/s" + +msgid "2-Sided Printing" +msgstr "Impression recto-verso" + +msgid "2.00x0.37\"" +msgstr "2,00 x 0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00 x 0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00 x 1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00 x 1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00 x 2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00 x 3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00 x 4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00 x 5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25 x 0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25 x 1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25 x 4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25 x 5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38 x 5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 po/s" + +msgid "2.50x1.00\"" +msgstr "2,50 x 1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50 x 2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75 x 1,25\"" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/s" + +msgid "200 mm/sec." +msgstr "200 mm/s" + +msgid "203dpi" +msgstr "203 ppp" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "Série 24 broches" + +msgid "240x72dpi" +msgstr "240 x 72 ppp" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/s" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 po/s" + +msgid "3.00x1.00\"" +msgstr "3,00 x 1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00 x 1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00 x 2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00 x 3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00 x 5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25 x 2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25 x 5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25 x 5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25 x 5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25 x 7,83\"" + +msgid "3.5\" Disk" +msgstr "Disque 3,5\"" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Disque 3,5\" - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50 x 1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/s" + +msgid "300 mm/sec." +msgstr "300 mm/s" + +msgid "300dpi" +msgstr "300 ppp" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 ppp" + +msgid "360x180dpi" +msgstr "360 x 180 ppp" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 po/s" + +msgid "4.00x1.00\"" +msgstr "4,00 x 1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00 x 13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00 x 2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00 x 2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00 x 3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00 x 4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00 x 5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00 x 6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00 x 6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/s" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 po/s" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 po/s" + +msgid "6.00x1.00\"" +msgstr "6,00 x 1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00 x 2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00 x 3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00 x 4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00 x 5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00 x 6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00 x 6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/s" + +msgid "600dpi" +msgstr "600 ppp" + +msgid "60dpi" +msgstr "60 ppp" + +msgid "60x720dpi" +msgstr "60 x 720 ppp" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 po/s" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 ppp" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 po/s" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00 x 1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00 x 2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00 x 3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00 x 4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00 x 5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00 x 6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00 x 6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/s" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 po/s" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "Série 9 broches" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Commande inconnue d’aide\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"Un mot de passe SAMBA est nécessaire pour exporter les gestionnaires " +"d’impression." + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Un nom d’utilisateur SAMBA est nécessaire pour exporter les gestionnaires " +"d’impression." + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Une classe porte déjà le nom de « %s »." + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Une imprimante porte déjà le nom de « %s »." + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (format supérieur)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (format supérieur)" + +msgid "A4 (Small)" +msgstr "A4 (petit format)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (format supérieur)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Accepter les tâches" + +msgid "Accepted" +msgstr "Accepté" + +msgid "Add Class" +msgstr "Ajouter une classe" + +msgid "Add Printer" +msgstr "Ajouter une imprimante" + +msgid "Add RSS Subscription" +msgstr "Ajouter abonnement RSS" + +msgid "Address" +msgstr "Adresse" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adresse - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administration" + +msgid "Always" +msgstr "Toujours" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applicator" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "" +"Tentative d’attribution d’une valeur erronée au paramètre « printer-state » %" +"s : %d." + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Les groupes d’attributs ne sont pas dans le bon ordre (%x < %x)." + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Pointeur de dests NULL incorrect" + +msgid "Bad OpenGroup" +msgstr "OpenGroup erroné" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI erroné" + +msgid "Bad OrderDependency" +msgstr "OrderDependency erroné" + +msgid "Bad Request" +msgstr "Requête incorrecte" + +msgid "Bad SNMP version number" +msgstr "Numéro de version SNMP incorrect" + +msgid "Bad UIConstraints" +msgstr "UIConstraints erroné" + +#, c-format +msgid "Bad copies value %d." +msgstr "Nombre de copies erroné : %d." + +msgid "Bad custom parameter" +msgstr "Paramètre personnalisé incorrect" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "URI de périphérique « %s » incorrect.\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "device-uri « %s » incorrect." + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Schéma de device-uri « %s » incorrect." + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "document-format « %s » incorrect." + +msgid "Bad filename buffer!" +msgstr "Tampon des noms de fichier incorrect." + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Attribut de police incorrect : %s\n" + +msgid "Bad job-priority value!" +msgstr "Valeur de job-priority incorrecte." + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Valeur de job-sheets « %s » incorrecte." + +msgid "Bad job-sheets value type!" +msgstr "Type de job-sheets incorrect." + +msgid "Bad job-state value!" +msgstr "Valeur de job-state incorrecte." + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Attribut de job-uri « %s » incorrect." + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Paramètre notify-pull-method « %s » incorrect." + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "URI de notify-recipient-uri « %s » incorrect." + +#, c-format +msgid "Bad number-up value %d." +msgstr "Valeur de number-up %d incorrecte." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Couple option/choix incorrect à la ligne %d.\n" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Intervalle de pages erroné : %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "port-monitor « %s » incorrect" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Valeur de printer-state %d incorrecte." + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Numéro de version de requête %d.%d incorrect." + +msgid "Bad subscription ID!" +msgstr "Identifiant d’abonnement incorrect." + +msgid "Banners" +msgstr "Bannières" + +msgid "Billing Information: " +msgstr "Informations de facturation : " + +msgid "Bond Paper" +msgstr "Papier pour titres" + +msgid "C0 Envelope" +msgstr "C0 Enveloppe" + +msgid "C1 Envelope" +msgstr "C1 Enveloppe" + +msgid "C2 Envelope" +msgstr "C2 Enveloppe" + +msgid "C3 Envelope" +msgstr "C3 Enveloppe" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4 Enveloppe" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5 Enveloppe" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6 Enveloppe" + +msgid "C65 Envelope" +msgstr "C65 Enveloppe" + +msgid "C7 Envelope" +msgstr "C7 Enveloppe" + +msgid "CMYK" +msgstr "CMJN" + +msgid "CPCL Label Printer" +msgstr "Imprimante pour étiquettes CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Annuler abonnement RSS" + +msgid "Change Settings" +msgstr "Modifier les paramètres" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Jeu de caractères « %s » non pris en charge." + +msgid "Chou3 Envelope" +msgstr "Chou3 Enveloppe" + +msgid "Chou4 Envelope" +msgstr "Chou4 Enveloppe" + +msgid "Classes" +msgstr "Classes" + +msgid "Clean Print Heads" +msgstr "Nettoyer les têtes d’impression" + +msgid "Color" +msgstr "Couleur" + +msgid "Color Mode" +msgstr "Mode de couleur" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Les commandes peuvent être abrégées. Celles-ci correspondent à :\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Le nom de la communauté s’avère être de longueur indéfinie" + +msgid "Continue" +msgstr "Continuer" + +msgid "Continuous" +msgstr "Continu" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Impossible d’analyser le type « %s »." + +msgid "Cover open." +msgstr "Couvercle ouvert." + +msgid "Created" +msgstr "Créé" + +msgid "Created On: " +msgstr "Créé le : " + +msgid "Custom" +msgstr "Personnalisation" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Couper" + +msgid "Cutter" +msgstr "Cutter" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL Enveloppe" + +msgid "Dark" +msgstr "Foncé" + +msgid "Darkness" +msgstr "Tons foncés" + +msgid "Delete Class" +msgstr "Supprimer la classe" + +msgid "Delete Printer" +msgstr "Supprimer l’imprimante" + +msgid "Description: " +msgstr "Description : " + +msgid "DeskJet Series" +msgstr "Série DeskJet" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "La destination « %s » n’accepte pas de tâche." + +msgid "Developer almost empty." +msgstr "Développeur presque vide." + +msgid "Developer empty!" +msgstr "Développeur vide." + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Périphérique : uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Papier pour impression thermique directe" + +msgid "Disabled" +msgstr "Désactivé" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Document %d introuvable dans la tâche %d." + +msgid "Door open." +msgstr "Capot ouvert." + +msgid "Double Postcard" +msgstr "Carte postale double" + +msgid "Driver Name: " +msgstr "Nom du gestionnaire : " + +msgid "Driver Version: " +msgstr "Version du gestionnaire : " + +msgid "Duplexer" +msgstr "Duplexeur" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "" +"EMERG: impossible d’allouer de la mémoire pour les informations de la page : " +"%s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "" +"EMERG: impossible d’allouer de la mémoire pour l’étalage des pages : %s\n" + +msgid "EPL1 Label Printer" +msgstr "Imprimante pour étiquettes EPL1" + +msgid "EPL2 Label Printer" +msgstr "Imprimante pour étiquettes EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox erroné : commentaire vu.\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: %%IncludeFeature erroné : commentaire.\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: %%Page erroné : commentaire dans le fichier.\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: %%PageBoundingBox erroné : commentaire dans le fichier.\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: fichier de périphérique SCSI « %s » erroné.\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: fichier de jeu de caractères %s erroné\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: type de jeu de caractères %s erroné\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: valeur de colonnes %d erronée.\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: valeur de cpi %f erronée.\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: ligne de description de police erronée : %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: valeur de lpi %f erronée.\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: format d’impression erroné.\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: direction de texte %s erronée\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: largeur de texte %s erronée\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: l’imprimante de destination n’existe pas.\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox en double : commentaire vu.\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: %%Pages en double : commentaire vu.\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: fichier d’impression vide.\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: erreur %d lors de l’envoi de la requête PAPSendData : %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: chaîne entre guillemets droits attendue à la ligne %d sur %s.\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: erreur USB fatale.\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: commande HP-GL/2 non valide détectée ; impossible d’imprimer le " +"fichier.\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog manquant.\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup manquant.\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: valeur manquante à la ligne %d du fichier de bannière.\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: une ligne msgid est obligatoire avant toute chaîne de traduction à la " +"ligne %d sur %s.\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: aucun %%BoundingBox : commentaire dans l’en-tête.\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: aucun %%Pages : commentaire dans l’en-tête.\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: aucun URI trouvé pour le périphérique, dans argv[0] ou la variable " +"d’environnement DEVICE_URI.\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "" +"ERROR: aucune police ne se trouve dans le fichier du jeu de caractères %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: aucune page trouvée.\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: plus de papier.\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: variable d’environnement d’imprimante non définie.\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: fichier d’impression non accepté (%s).\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: l’imprimante ne répond pas.\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: l’imprimante ne répond pas.\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: l’imprimante a envoyé un code EOF inattendu.\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: l’hôte à distance n’a pas accepté le fichier contrôle (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: l’hôte à distance n’a pas accepté le fichier de données (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: le délai d’attente a été dépassé lors de l’envoi de données à " +"l’imprimante.\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: impossible d’ajouter le fichier %d à la tâche : %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: impossible d’annuler la tâche %d : %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: impossible de copier le fichier PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: impossible de créer un socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: impossible de créer un fichier d’impression temporaire compressé : %" +"s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: impossible de créer un fichier temporaire." + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: impossible d’exécuter pictwpstops : %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: impossible d’exécuter le programme gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: impossible d’exécuter le programme pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: impossible d’effectuer le fork de pictwpstops : %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: impossible d’obtenir la requête PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: impossible d’obtenir la réponse PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: impossible d’obtenir le fichier PPD pour l’imprimante « %s » - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: impossible de déterminer la zone AppleTalk par défaut" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: impossible d’obtenir les attributs %d de la tâche (%s).\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: impossible de déterminer l’état de l’imprimante (%s).\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: impossible de localiser l’imprimante « %s ».\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: impossible de rechercher une réponse PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: impossible de rechercher des imprimantes AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: impossible de générer une adresse AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: impossible d’ouvrir « %s » - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: impossible d’ouvrir %s : %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier de bannière « %s » - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier « %s » de périphérique : %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier « %s » - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier « %s » : %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: impossible d’ouvrir le fichier image en vue de l’impression.\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier d’impression « %s » : %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier d’impression %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: impossible d’ouvrir le fichier d’impression %s : %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: impossible d’ouvrir le fichier d’impression temporaire compressé : %" +"s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: impossible d’imprimer %d colonnes de texte.\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: impossible d’imprimer la page de texte en %d x %d.\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: impossible de lire les données d’impression." + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: impossible de lire les données d’impression.\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: impossible de réserver le port" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "" +"ERROR: impossible de chercher jusqu’au décalage %ld dans le fichier - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "" +"ERROR: impossible de chercher jusqu’au décalage %lld dans le fichier - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: impossible d’envoyer la commande LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: impossible d’envoyer la requête de passage PAP" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: impossible d’envoyer la requête initiale de données d’envoi PAP" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: impossible d’envoyer les données d’impression (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: impossible d’envoyer les données d’impression.\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: impossible d’envoyer le fichier d’impression à l’imprimante" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: impossible d’envoyer la valeur Null de fin à l’imprimante" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: impossible d’attendre les pictwpstop : %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: impossible d’écrire %d octets sur « %s » : %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: impossible d’écrire %d octets vers l’imprimante.\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: impossible d’écrire le contenu du fichier de contrôle" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: impossible d’écrire les données d’impression" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: impossible d’écrire le contenu des données d’impression : %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: impossible d’écrire de données de trame dans le gestionnaire.\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: impossible d’écrire dans le fichier temporaire" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" +"ERROR: impossible d’écrire de données de document non compressées : %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: texte inattendu à la ligne %d sur %s.\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: valeur de l’option de chiffrement « %s » inconnue.\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: ordre de fichier « %s » inconnu\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: caractère de format « %c » inconnu\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: format du catalogue de messages inconnu pour « %s ».\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: option « %s » inconnue avec la valeur « %s ».\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: mode d’impression « %s » inconnu\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: inconnue version option value « %s ».\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: valeur de luminosité non prise en charge %s, brightness=100.\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: valeur de gamma non prise en charge %s, gamma=1000.\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: valeur number-up non prise en charge %d, number-up=1.\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: valeur de number-up-layout non prise en charge %s, number-up-" +"layout=lrtb.\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: valeur de page-border non prise en charge %s, page-border=none.\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "" +"ERROR: dépassement de capacité de doc_printf (%d octets) détecté, processus " +"en cours d’interruption.\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops a quitté au signal %d.\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops a indiqué l’état %d lors de sa fermeture.\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: problème réversible : impossible de se connecter à l’imprimante ; " +"nouvel essai dans 30 secondes…\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: la fonction select() a échoué" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: impossible de lancer le fichier d’impression" + +msgid "Edit Configuration File" +msgstr "Modifier le fichier de configuration" + +msgid "Empty PPD file!" +msgstr "Fichier PPD vide." + +msgid "Ending Banner" +msgstr "Fin de la bannière" + +msgid "Enter old password:" +msgstr "Ancien mot de passe :" + +msgid "Enter password again:" +msgstr "Confirmez le nouveau mot de passe :" + +msgid "Enter password:" +msgstr "Entrez le nouveau mot de passe :" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Entrez votre nom d’utilisateur et votre mot de passe ou bien identifiez-vous " +"en tant que « root » pour accéder à cette page. Si vous utilisez " +"l’authentification Kerberos, assurez-vous de disposer d’un ticket Kerberos " +"valide." + +msgid "Envelope Feed" +msgstr "Alimentation au format enveloppe" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Règles d’erreur" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Erreur : un nom d’hôte après l’option « -h » est nécessaire.\n" + +msgid "Every 10 Labels" +msgstr "Toutes les 10 étiquettes" + +msgid "Every 2 Labels" +msgstr "Toutes les 2 étiquettes" + +msgid "Every 3 Labels" +msgstr "Toutes les 3 étiquettes" + +msgid "Every 4 Labels" +msgstr "Toutes les 4 étiquettes" + +msgid "Every 5 Labels" +msgstr "Toutes les 5 étiquettes" + +msgid "Every 6 Labels" +msgstr "Toutes les 6 étiquettes" + +msgid "Every 7 Labels" +msgstr "Toutes les 7 étiquettes" + +msgid "Every 8 Labels" +msgstr "Toutes les 8 étiquettes" + +msgid "Every 9 Labels" +msgstr "Toutes les 9 étiquettes" + +msgid "Every Label" +msgstr "Chaque étiquette" + +msgid "Expectation Failed" +msgstr "Échec de la condition de valeur attendue" + +msgid "Export Printers to Samba" +msgstr "Exporter les imprimantes vers SAMBA" + +msgid "FAIL\n" +msgstr "ÉCHEC\n" + +msgid "File Folder" +msgstr "Dossier de fichier" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Dossier de fichier - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Les URI des périphériques de fichier ont été désactivés. Pour l’activer, " +"reportez-vous à la directive FileDevice dans « %s/cupsd.conf »." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Interdit" + +msgid "Fuser temperature high!" +msgstr "Température de l’unité-fusible élevée." + +msgid "Fuser temperature low!" +msgstr "Température de l’unité-fusible faible." + +msgid "General" +msgstr "Général" + +msgid "Generic" +msgstr "Générique" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Légal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU s’avère être de longueur indéfinie" + +msgid "Glossy Paper" +msgstr "Papier brillant" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Attribut « printer-uri » trouvé mais sans attribut « job-id »" + +msgid "Grayscale" +msgstr "Niveaux de gris" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Dossier suspendu" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Dossier suspendu - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk désactivé dans les Préférences Système.\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk désactivé dans les Préférences Système.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: annulation de la tâche d’impression…\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: connecté à l’imprimante…\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: connexion à l’imprimante…\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: fichier de contrôle envoyé correctement\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: fichier de données envoyé correctement\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: mise en forme de la page %d…\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: chargement du fichier image…\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: recherche de l’imprimante…\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: établissement de la connexion\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" +"INFO: fichier d’impression envoyé, en attente de la fin de la tâche " +"d’impression…\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: imprimante occupée ; nouvel essai dans 10 secondes…\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: imprimante occupée ; nouvel essai dans 30 secondes…\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: imprimante occupée ; nouvel essai dans 5 secondes…\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: imprimante ne prenant pas en charge IPP/%d.%d ; tentative avec " +"IPP/1.0…\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: imprimante occupée ; nouvel essai dans 5 secondes…\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: imprimante actuellement déconnectée.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: imprimante actuellement hors ligne.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: imprimante en ligne à présent.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: imprimante hors ligne.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: imprimante non connectée ; nouvel essai dans 30 secondes…\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: impression de la page %d, %d %% accompli…\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: impression de la page %d…\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: prêt pour l’impression.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: envoi du fichier de contrôle (%lu octets)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: envoi du fichier de contrôle (%u octets)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: envoi des données\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: envoi du fichier de données (%ld octets)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: envoi du fichier de données (%lld octets)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: envoi des données d’impression…\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: fichier d’impression envoyé, %ld octets…\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: fichier d’impression envoyé, %lld octets…\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: mise en attente de la tâche LPR, %.0f %% achevé…\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: impossible d’entrer en contact avec l’imprimante, mise en file " +"d’attente sur l’imprimante suivante par ordre de classe…\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: utilisation de la zone AppleTalk par défaut « %s »\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: en attente de la fin de la tâche…\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: attente de disponibilité de l’imprimante…\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 Enveloppe" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (format supérieur)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 Enveloppe" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 Enveloppe" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Caractère de contrôle interdit" + +msgid "Illegal main keyword string" +msgstr "Mot-clé essentiel interdit" + +msgid "Illegal option keyword string" +msgstr "Mot-clé d’option interdit" + +msgid "Illegal translation string" +msgstr "Traduction interdite" + +msgid "Illegal whitespace character" +msgstr "Caractère « espace blanc » interdit" + +msgid "Ink/toner almost empty." +msgstr "Encre/toner presque vide." + +msgid "Ink/toner empty!" +msgstr "Encre/toner vide." + +msgid "Ink/toner waste bin almost full." +msgstr "Poubelle d’encre/de toner presque remplie." + +msgid "Ink/toner waste bin full!" +msgstr "Poubelle d’encre/de toner remplie." + +msgid "Installable Options" +msgstr "Options installables" + +msgid "Installed" +msgstr "Installée" + +msgid "IntelliBar Label Printer" +msgstr "Imprimante pour étiquettes IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Dispositif de verrouillage ouvert." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Erreur interne" + +msgid "Internet Postage 2-Part" +msgstr "Affranchissement Internet en 2 parties" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Affranchissement Internet en 2 parties - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Affranchissement Internet en 3 parties" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Affranchissement Internet en 3 parties - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internet Printing Protocol" + +msgid "Invite Envelope" +msgstr "Enveloppe d’invitation" + +msgid "Italian Envelope" +msgstr "Enveloppe à l’italienne" + +msgid "JCL" +msgstr "JCL ( Langage de contrôle de tâche )" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "La tâche n°%d ne peut être redémarrée - aucun fichier." + +#, c-format +msgid "Job #%d does not exist!" +msgstr "La tâche n°%d n’existe pas." + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "La tâche n°%d est déjà abandonnée - impossible de l’annuler." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "La tâche n°%d est déjà annulée - impossible de l’annuler." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "La tâche n°%d est déjà terminée - impossible de l’annuler." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "La tâche n°%d est terminée et ne peut plus être modifiée." + +#, c-format +msgid "Job #%d is not complete!" +msgstr "La tâche n°%d n’est pas terminée." + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "La tâche n°%d n’est pas en attente d’authentification." + +#, c-format +msgid "Job #%d is not held!" +msgstr "La tâche n°%d n’est pas retenue." + +#, c-format +msgid "Job #%s does not exist!" +msgstr "La tâche n°%s n’existe pas." + +#, c-format +msgid "Job %d not found!" +msgstr "La tâche n°%d n’a pas été trouvée." + +msgid "Job Completed" +msgstr "terminée" + +msgid "Job Created" +msgstr "Tâche créée" + +msgid "Job ID: " +msgstr "Identifiant de tâche : " + +msgid "Job Options Changed" +msgstr "Options de la tâche modifiées" + +msgid "Job Stopped" +msgstr "arrêtée" + +msgid "Job UUID: " +msgstr "UUID de tâche : " + +msgid "Job is completed and cannot be changed." +msgstr "La tâche est terminée et ne peut être modifiée." + +msgid "Job operation failed:" +msgstr "L’opération sur la tâche a échoué :" + +msgid "Job state cannot be changed." +msgstr "L’état de la tâche ne peut être modifié." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Les abonnements de tâche ne peuvent être renouvelés." + +msgid "Jobs" +msgstr "Tâches" + +msgid "Kaku2 Envelope" +msgstr "Enveloppe Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Enveloppe Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Hôte ou imprimante LPD/LPR" + +msgid "Label Printer" +msgstr "Imprimante pour étiquettes" + +msgid "Label Top" +msgstr "Étiquette supérieure" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Langue « %s » non prise en charge." + +msgid "Large Address" +msgstr "Adresse étendue" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Adresse étendue - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet série PCL 4/5" + +msgid "Light" +msgstr "Clair" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Ligne dépassant la longueur maximale autorisée (255 caractères)" + +msgid "List Available Printers" +msgstr "Énumérer les imprimantes disponibles" + +msgid "Location: " +msgstr "Emplacement : " + +msgid "Long-Edge (Portrait)" +msgstr "Bord le plus long (Portrait)" + +msgid "Make and Model: " +msgstr "Marque et modèle : " + +msgid "Manual Feed" +msgstr "Alimentation manuelle" + +msgid "Media Dimensions: " +msgstr "Dimensions du papier : " + +msgid "Media Limits: " +msgstr "Limites du papier : " + +msgid "Media Name: " +msgstr "Nom du papier : " + +msgid "Media Size" +msgstr "Taille du papier" + +msgid "Media Source" +msgstr "Source du papier" + +msgid "Media Tracking" +msgstr "Crénage du papier" + +msgid "Media Type" +msgstr "Type de papier" + +msgid "Media jam!" +msgstr "Bourrage papier" + +msgid "Media tray almost empty." +msgstr "Bac à papier presque vide." + +msgid "Media tray empty!" +msgstr "Bac à papier vide." + +msgid "Media tray missing!" +msgstr "Bac manquant." + +msgid "Media tray needs to be filled." +msgstr "Le bac à papier doit être rempli." + +msgid "Medium" +msgstr "Moyen" + +msgid "Memory allocation error" +msgstr "Erreur d’allocation de mémoire" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Entête PPD-Adobe-4.x manquant" + +msgid "Missing asterisk in column 1" +msgstr "Astérisque manquant à la colonne 1" + +msgid "Missing document-number attribute!" +msgstr "Attribut « document-number » manquant." + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Caractère ˝ manquant à la ligne %d." + +msgid "Missing form variable!" +msgstr "Un champ du formulaire HTML n’a pas été rempli." + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Attribut notify-subscription-ids manquant" + +msgid "Missing requesting-user-name attribute!" +msgstr "Attribut « requesting-user-name » manquant" + +msgid "Missing required attributes!" +msgstr "Il manque des attributs indispensables." + +#, c-format +msgid "Missing value on line %d!" +msgstr "Valeur manquante à la ligne %d.\n" + +msgid "Missing value string" +msgstr "Chaîne de valeur manquante" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modèle : name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Modifier la classe" + +msgid "Modify Printer" +msgstr "Modifier l’imprimante" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Enveloppe Monarch" + +msgid "Move All Jobs" +msgstr "Transférer toutes les tâches" + +msgid "Move Job" +msgstr "Transférer la tâche" + +msgid "Moved Permanently" +msgstr "Transférées de façon permanente" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: fichier d’impression accepté - identifiant de tâche %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: fichier d’impression accepté - identifiant de tâche inconnu.\n" + +msgid "NULL PPD file pointer" +msgstr "Pointeur de fichier PPD NULL." + +msgid "Name OID uses indefinite length" +msgstr "L’OID du nom s’avère être de longueur indéfinie" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Jamais" + +msgid "New Stylus Color Series" +msgstr "Nouvelles série Stylus Color" + +msgid "New Stylus Photo Series" +msgstr "Nouvelles série Stylus Photo" + +msgid "No" +msgstr "Non" + +msgid "No Content" +msgstr "Aucun contenu" + +msgid "No PPD name!" +msgstr "Aucun nom PPD" + +msgid "No VarBind SEQUENCE" +msgstr "Aucune SEQUENCE VarBind" + +msgid "No Windows printer drivers are installed!" +msgstr "Aucun pilote d’impression Windows n’est installé." + +msgid "No active connection" +msgstr "Aucune connexion active" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Aucune tâche en cours sur « %s »." + +msgid "No attributes in request!" +msgstr "Aucun attribut dans la requête." + +msgid "No authentication information provided!" +msgstr "Aucune information d’authentification." + +msgid "No community name" +msgstr "Aucun nom de communauté" + +msgid "No default printer" +msgstr "Aucune imprimante par défaut" + +msgid "No destinations added." +msgstr "Aucune destination ajoutée." + +msgid "No error-index" +msgstr "Paramètre error-index absent" + +msgid "No error-status" +msgstr "Paramètre error-status absent" + +msgid "No file!?!" +msgstr "Aucun fichier !?!" + +msgid "No modification time!" +msgstr "Aucune heure de modification" + +msgid "No name OID" +msgstr "Aucun OID de nom" + +msgid "No printer name!" +msgstr "Aucun nom d’imprimante." + +msgid "No printer-uri found for class!" +msgstr "Paramètre printer-uri absent pour la classe." + +msgid "No printer-uri found!" +msgstr "Paramètre printer-uri absent." + +msgid "No printer-uri in request!" +msgstr "Paramètre printer-uri absent de la requête." + +msgid "No request-id" +msgstr "Paramètre request-id absent" + +msgid "No subscription attributes in request!" +msgstr "Aucun attribut d’abonnement dans la requête." + +msgid "No subscriptions found." +msgstr "Aucun abonnement trouvé." + +msgid "No variable-bindings SEQUENCE" +msgstr "Aucune SEQUENCE variable-bindings" + +msgid "No version number" +msgstr "Aucun numéro de version" + +msgid "Non-continuous (Mark sensing)" +msgstr "Non continu (détection de marque)" + +msgid "Non-continuous (Web sensing)" +msgstr "Non continu (détection Web)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "Introuvable" + +msgid "Not Implemented" +msgstr "Non implémentée" + +msgid "Not Installed" +msgstr "Non installée" + +msgid "Not Modified" +msgstr "Non modifiée" + +msgid "Not Supported" +msgstr "Non prise en charge" + +msgid "Not allowed to print." +msgstr "Impression interdite" + +msgid "Note" +msgstr "Remarque" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC presque en fin de vie." + +msgid "OPC at end-of-life!" +msgstr "OPC en fin de vie." + +msgid "Off (1-Sided)" +msgstr "Désactivé (recto)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Aide en ligne" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "L’ouverture de %s a échoué : %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup sans CloseGroup préalable" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI sans CloseUI/JCLCloseUI préalable" + +msgid "Operation Policy" +msgstr "Règles de fonctionnement" + +msgid "Options Installed" +msgstr "Options installées" + +msgid "Options: " +msgstr "Options : " + +msgid "Out of toner!" +msgstr "Plus de toner." + +msgid "Output Mode" +msgstr "Mode de sortie" + +msgid "Output bin almost full." +msgstr "Corbeille de sortie presque pleine." + +msgid "Output bin full!" +msgstr "Corbeille de sortie pleine." + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "La sortie de l’imprimante %s est envoyée à %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "" +"La sortie de l’imprimante %s est envoyée à l’imprimante distante %s sur %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "La sortie de l’imprimante %s/%s est envoyée à %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"La sortie de l’imprimante %s/%s est envoyée à l’imprimante distante %s sur %" +"s\n" + +msgid "Output tray missing!" +msgstr "Bac en sortie manquant." + +msgid "PASS\n" +msgstr "VALIDE\n" + +msgid "PCL Laser Printer" +msgstr "Imprimante laser PCL" + +msgid "PRC1 Envelope" +msgstr "Enveloppe PRC1" + +msgid "PRC10 Envelope" +msgstr "Enveloppe PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Enveloppe PRC2" + +msgid "PRC3 Envelope" +msgstr "Enveloppe PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (format supérieur)" + +msgid "PRC4 Envelope" +msgstr "Enveloppe PRC4" + +msgid "PRC5 Envelope" +msgstr "Enveloppe PRC5" + +msgid "PRC6 Envelope" +msgstr "Enveloppe PRC6" + +msgid "PRC7 Envelope" +msgstr "Enveloppe PRC7" + +msgid "PRC8 Envelope" +msgstr "Enveloppe PRC8" + +msgid "PRC9 Envelope" +msgstr "Enveloppe PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Le paquet ne contient aucun paramètre Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Le paquet ne commence pas par SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Mot de passe pour %s sur %s ? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Un mot de passe pour %s est nécessaire pour accéder à %s via SAMBA : " + +msgid "Pause Class" +msgstr "Suspendre la classe" + +msgid "Pause Printer" +msgstr "Suspendre l’imprimante" + +msgid "Peel-Off" +msgstr "Décoller" + +msgid "Personal Envelope" +msgstr "Enveloppe personnelle" + +msgid "Photo" +msgstr "Photo" + +msgid "Photo Labels" +msgstr "Étiquettes photo" + +msgid "Plain Paper" +msgstr "Papier vierge" + +msgid "Policies" +msgstr "Règles" + +msgid "Port Monitor" +msgstr "Moniteur de port" + +msgid "PostScript Printer" +msgstr "Imprimante PostScript" + +msgid "Postcard" +msgstr "Carte postale" + +msgid "Print Density" +msgstr "Densité d’impression" + +msgid "Print Job:" +msgstr "Tâche d’impression :" + +msgid "Print Mode" +msgstr "Mode d’impression" + +msgid "Print Rate" +msgstr "Taux d’impression" + +msgid "Print Self-Test Page" +msgstr "Imprimer une page d’autotest" + +msgid "Print Speed" +msgstr "Vitesse d’impression" + +msgid "Print Test Page" +msgstr "Imprimer la page de test" + +msgid "Print and Cut" +msgstr "Impression à découper" + +msgid "Print and Tear" +msgstr "Impression à détacher" + +msgid "Printed For: " +msgstr "Imprimé pour : " + +msgid "Printed From: " +msgstr "Imprimé de : " + +msgid "Printed On: " +msgstr "Imprimé sur : " + +msgid "Printer Added" +msgstr "ajoutée" + +msgid "Printer Default" +msgstr "par défaut" + +msgid "Printer Deleted" +msgstr "supprimée" + +msgid "Printer Modified" +msgstr "modifiée" + +msgid "Printer Name: " +msgstr "Nom de l’imprimante : " + +msgid "Printer Paused" +msgstr "en pause" + +msgid "Printer Settings" +msgstr "Réglages de l’imprimante" + +msgid "Printer offline." +msgstr "hors ligne." + +msgid "Printer:" +msgstr "Imprimante :" + +msgid "Printers" +msgstr "Imprimantes" + +msgid "Purge Jobs" +msgstr "Purger les tâches" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Quota atteint." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Classmt Proprio Tâche Fichier(s) Taille " +"totale\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Classmt Proprio Pri Tâche Fichiers Taille totale\n" + +msgid "Reject Jobs" +msgstr "Refuser les tâches" + +msgid "Reprint After Error" +msgstr "Réimprimer après erreur" + +msgid "Request Entity Too Large" +msgstr "Entité de requête trop volumineuse" + +msgid "Resolution" +msgstr "Résolution" + +msgid "Resume Class" +msgstr "Relancer la classe" + +msgid "Resume Printer" +msgstr "Relancer l’imprimante" + +msgid "Return Address" +msgstr "Renvoyer l’adresse" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Renvoyer l’adresse - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Rembobiner" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Commande en cours d’exécution : %s %s -N -A %s -c « %s »\n" + +msgid "SCSI Printer" +msgstr "Imprimante SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE s’avère être de longueur indéfinie" + +msgid "See Other" +msgstr "Autres" + +#, c-format +msgid "Serial Port #%d" +msgstr "Port série #%d" + +msgid "Server Restarted" +msgstr "Le serveur a redémarré" + +msgid "Server Security Auditing" +msgstr "Vérification de la sécurité du serveur" + +msgid "Server Started" +msgstr "Le serveur a démarré" + +msgid "Server Stopped" +msgstr "Le serveur s’est arrêté" + +msgid "Service Unavailable" +msgstr "Service indisponible" + +msgid "Set Allowed Users" +msgstr "Définir les autorisations" + +msgid "Set As Server Default" +msgstr "Définir comme valeur par défaut pour le serveur" + +msgid "Set Class Options" +msgstr "Définir les options de classe" + +msgid "Set Printer Options" +msgstr "Définir les options de l’imprimante" + +msgid "Set Publishing" +msgstr "Définir la publication" + +msgid "Shipping Address" +msgstr "Adresse de livraison" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Adresse de livraison - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Bord le plus court (paysage)" + +msgid "Special Paper" +msgstr "Papier spécial" + +msgid "Standard" +msgstr "Standard" + +msgid "Starting Banner" +msgstr "Début de la bannière" + +msgid "Statement" +msgstr "Déclaration" + +msgid "Stylus Color Series" +msgstr "Série Stylus Color" + +msgid "Stylus Photo Series" +msgstr "Série Stylus Photo" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Permuter les protocoles" + +msgid "Tabloid" +msgstr "Tabloïd" + +msgid "Tabloid (Oversize)" +msgstr "Tabloïd (format supérieur)" + +msgid "Tear" +msgstr "Détacher" + +msgid "Tear-Off" +msgstr "Détacher" + +msgid "Tear-Off Adjust Position" +msgstr "Position d’ajustement du détachement" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Le fichier PPD « %s » n’a pu être trouvé." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Le fichier PPD « %s » n’a pu être ouvert : %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Le nom de classe doit comporter au plus 127 caractères, tous imprimables, " +"sans espace, « / » et « # »." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"L’attribut « notify-lease-duration » ne peut pas être utilisé dans un " +"abonnement de tâche." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "" +"La valeur de l’attribut « notify-user-data » est trop grande (%d > 63 octets)." + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Le nom d’imprimante doit comporter au plus 127 caractères, tous imprimables, " +"sans espace, « / » et « # »." + +msgid "The printer or class is not shared!" +msgstr "L’imprimante ou la classe n’est pas partagée." + +msgid "The printer or class was not found." +msgstr "L’imprimante ou la classe n’a pas été trouvée." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Le paramètre printer-uri « %s » contient des caractères non valides." + +msgid "The printer-uri attribute is required!" +msgstr "L’attribut « job-printer-uri » est obligatoire." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"L’attribut « printer-uri » doit se présenter sous la forme « ipp://HOSTNAME/" +"classes/CLASSNAME »." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"L’attribut « printer-uri » doit se présenter sous la forme « ipp://HOSTNAME/" +"printers/PRINTERNAME »." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Le nom de l’abonnement ne doit pas contenir d’espace ni aucun des symboles " +"« / », « ? » et « # »." + +msgid "There are too many subscriptions." +msgstr "Les abonnements sont trop nombreux." + +msgid "Thermal Transfer Media" +msgstr "Papier pour transfert thermique" + +msgid "Title: " +msgstr "Titre : " + +msgid "Toner low." +msgstr "Niveau du toner faible." + +msgid "Too many active jobs." +msgstr "Trop de tâches en cours." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Valeurs job-sheets trop nombreuses (%d > 2)." + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Valeurs printer-state-reasons trop nombreuses (%d > %d)." + +msgid "Transparency" +msgstr "Transparence" + +msgid "Tray" +msgstr "Bac" + +msgid "Tray 1" +msgstr "Bac 1" + +msgid "Tray 2" +msgstr "Bac 2" + +msgid "Tray 3" +msgstr "Bac 3" + +msgid "Tray 4" +msgstr "Bac 4" + +msgid "URI Too Long" +msgstr "URI trop long" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Légal" + +msgid "US Legal (Oversize)" +msgstr "US Légal (format supérieur)" + +msgid "US Letter" +msgstr "US Lettre" + +msgid "US Letter (Oversize)" +msgstr "US Lettre (format supérieur)" + +msgid "US Letter (Small)" +msgstr "US Lettre (format inférieur)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Port série USB #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Impossible d’accéder au fichier cupsd.conf :" + +msgid "Unable to add RSS subscription:" +msgstr "Impossible d’ajouter d’abonnement RSS :" + +msgid "Unable to add class:" +msgstr "Impossible d’ajouter la classe :" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Impossible d’ajouter de tâche à la destination « %s »." + +msgid "Unable to add printer:" +msgstr "Impossible d’ajouter l’imprimante :" + +msgid "Unable to allocate memory for file types!" +msgstr "Impossible d’allouer de la mémoire pour les types de fichiers." + +msgid "Unable to cancel RSS subscription:" +msgstr "Impossible d’annuler l’abonnement RSS :" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Impossible de modifier l’attribut « printer-is-shared » :" + +msgid "Unable to change printer:" +msgstr "Impossible de modifier l’imprimante :" + +msgid "Unable to change server settings:" +msgstr "Impossible de modifier les réglages du serveur :" + +msgid "Unable to connect to host." +msgstr "Connexion à l’hôte impossible." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" +"Impossible de copier les fichiers des gestionnaires d’impression CUPS " +"64 bits (%d)." + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Impossible de copier les fichiers des pilotes d’impression Windows 64 bits (%" +"d)." + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "" +"Impossible de copier les fichiers du gestionnaire d’impression CUPS (%d)." + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Impossible de copier le fichier PPD - « %s »." + +msgid "Unable to copy PPD file!" +msgstr "Impossible de copier le fichier PPD." + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"Impossible de copier les fichiers des pilotes d’impression pour Windows 2000 " +"(%d)." + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" +"Impossible de copier les fichiers des pilotes d’impression pour Windows 9x (%" +"d)." + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Impossible de copier le script d’interface - « %s »." + +msgid "Unable to create printer-uri!" +msgstr "Impossible de créer le paramètre printer-uri." + +msgid "Unable to create temporary file:" +msgstr "Impossible de créer le fichier temporaire :" + +msgid "Unable to delete class:" +msgstr "Impossible de supprimer la classe :" + +msgid "Unable to delete printer:" +msgstr "Impossible de supprimer l’imprimante :" + +msgid "Unable to do maintenance command:" +msgstr "Impossible de lancer la commande de maintenance :" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "" +"Impossible de modifier des fichiers cupsd.conf de taille supérieure à 1 Mo." + +msgid "Unable to find destination for job!" +msgstr "Impossible de trouver la destination de la tâche." + +msgid "Unable to find printer!\n" +msgstr "Impossible de retrouver l’imprimante.\n" + +msgid "Unable to get class list:" +msgstr "Impossible d’obtenir la liste des classes :" + +msgid "Unable to get class status:" +msgstr "Impossible d’obtenir l’état de la classe :" + +msgid "Unable to get list of printer drivers:" +msgstr "Impossible d’obtenir la liste des gestionnaires d’impression :" + +msgid "Unable to get printer attributes:" +msgstr "Impossible de récupérer les attributs de l’imprimante :" + +msgid "Unable to get printer list:" +msgstr "Impossible d’obtenir la liste des imprimantes :" + +msgid "Unable to get printer status:" +msgstr "Impossible d’obtenir l’état de l’imprimante :" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Impossible d’installer les fichiers des pilotes d’impression pour Windows " +"2000 (%d)." + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"Impossible d’installer les fichiers des pilotes d’impression pour Windows 9x " +"(%d)." + +msgid "Unable to modify class:" +msgstr "Impossible de modifier la classe :" + +msgid "Unable to modify printer:" +msgstr "Impossible de modifier l’imprimante :" + +msgid "Unable to move job" +msgstr "Impossible de transférer la tâche." + +msgid "Unable to move jobs" +msgstr "Impossible de transférer les tâches." + +msgid "Unable to open PPD file" +msgstr "Impossible d’ouvrir le fichier PPD." + +msgid "Unable to open PPD file:" +msgstr "Impossible d’ouvrir le fichier PPD :" + +msgid "Unable to open cupsd.conf file:" +msgstr "Impossible d’ouvrir le fichier cupsd.conf :" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Impossible d’ouvrir le document %d dans la tâche %d." + +msgid "Unable to print test page:" +msgstr "Impossible d’imprimer la page de test :" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Impossible d’exécuter « %s » : %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Impossible d’envoyer la commande au gestionnaire de l’imprimante." + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "" +"Impossible d’installer les fichiers des pilotes d’impression pour Windows (%" +"d).\n" + +msgid "Unable to set options:" +msgstr "Impossible de définir les options :" + +msgid "Unable to set server default:" +msgstr "Impossible de définir la valeur par défaut pour le serveur :" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Impossible de transmettre le fichier cupsd.conf :" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Impossible d’exploiter l’ancien gestionnaire de la classe USB.\n" + +msgid "Unauthorized" +msgstr "Non autorisé" + +msgid "Units" +msgstr "Unités" + +msgid "Unknown" +msgstr "Inconnu" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Paramètre printer-error-policy « %s » inconnu." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Paramètre printer-op-policy « %s » inconnu." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Jeu de caractères « %s » non pris en charge." + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Compression « %s » non prise en charge" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Attribut de compression %s non pris en charge" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Format « %s » non pris en charge" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Format « %s » non pris en charge" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Format « %s/%s » non pris en charge" + +msgid "Unsupported value type" +msgstr "Type de valeur non pris en charge" + +msgid "Upgrade Required" +msgstr "Mise à niveau obligatoire" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Usage :\n" +"\n" +" lpadmin [-h serveur] -d destination\n" +" lpadmin [-h serveur] -x destination\n" +" lpadmin [-h serveur] -p imprimante [-c ajouter-classe] [-i interface] [-" +"m modèle]\n" +" [-r supprimer-classe] [-v périphérique] [-D " +"description]\n" +" [-P fichier-ppd] [-o nom=valeur]\n" +" [-u allow:utilisateur,utilisateur] [-u deny:" +"utilisateur,utilisateur]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Usage : %s tâche utilisateur titre copies options [nom_fichier]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Usage : %s id-tâche utilisateur titre copies options [fichier]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Usage : %s id-tâche utilisateur titre copies options fichier\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Usage : cupsaddsmb [options] imprimante1 … imprimanteN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options :\n" +" -E Chiffrer la connexion au serveur\n" +" -H serveur_samba Faire appel au serveur SAMBA indiqué\n" +" -U utilisateur_samba S’authentifier par le biais de l’utilisateur SAMBA " +"indiqué\n" +" -a Exporter toutes les imprimantes\n" +" -h serveur_cups Faire appel au serveur CUPS indiqué\n" +" -v Activer la verbosité (afficher les commandes)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Usage : cupsctl [options] [paramètre=valeur … paramètreN=valeurN]\n" +"\n" +"Options :\n" +"\n" +" -E Activer le chiffrement\n" +" -U nom_utilisateur Indiquer le nom de l’utilisateur\n" +" -h serveur[:port] Indiquer l’adresse du serveur\n" +"\n" +" --[no-]debug-logging Activer/désactiver le listage de débogage\n" +" --[no-]remote-admin Activer/désactiver l’administration à distance\n" +" --[no-]remote-any Autoriser/interdire l’accès à partir d’Internet\n" +" --[no-]remote-printers Afficher/masquer les imprimantes à distance\n" +" --[no-]share-printers Activer/désactiver le partage d’imprimante\n" +" --[no-]user-cancel-any Autoriser/interdire aux utilisateurs d’annuler " +"toute tâche\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Usage : cupsd [-c fichier_config] [-f] [-F] [-h] [-l]\n" +"\n" +"-c fichier_config Charger un autre fichier de configuration\n" +"-f Exécuter en premier plan\n" +"-F Exécuter en premier plan mais en mode détaché\n" +"-h Afficher le présent message d’usage des options\n" +"-l Exécuter cupsd à partir de launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Usage : cupstestdsc [options] nom_fichier.ps [… nom_fichier.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options :\n" +"\n" +" -h Afficher l’utilisation du programme\n" +"\n" +" Remarque : ce programme ne fait que valider les commentaires DSC et non " +"le PostScript en tant que tel.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Usage : lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Usage : lpoptions [-h serveur] [-E] -d imprimante\n" +" lpoptions [-h serveur] [-E] [-p imprimante] -l\n" +" lpoptions [-h serveur] [-E] -p imprimante -o option[=valeur] …\n" +" lpoptions [-h serveur] [-E] -x imprimante\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Usage : lppasswd [-g nom_groupe]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Usage : lppasswd [-g nom_groupe] [nom_utilisateur]\n" +" lppasswd [-g nom_groupe] -a [nom_utilisateur]\n" +" lppasswd [-g nom_groupe] -x [nom_utilisateur]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Usage : lpq [-P dest] [-U nom_utilisateur] [-h nom_hôte[:port]] [-l] " +"[+intervalle]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Usage : ppdc [options] nom_fichier.drv [ … nom_fichierN.drv ]\n" +"Options :\n" +" -D nom=valeur Définir la variable; dont le nom est indiqué; sur la " +"valeur fournie.\n" +" -I inclure-rép Inclure le répertoire au chemin de recherche.\n" +" -c catalogue.po Charger le catalogue indiqué de messages.\n" +" -d sortie-rép Préciser le répertoire de sortie.\n" +" -l langue[,langue,…] Préciser la ou les langues de sortie (locale).\n" +" -m Utiliser la valeur de ModelName comme nom de " +"fichier.\n" +" -t Tester les PPD au lieu de les générer.\n" +" -v Activer la verbosité (lettres V complémentaires pour " +"augmenter la verbosité).\n" +" -z Comprimer les fichiers PPD par la méthode de zip " +"GNU.\n" +" --cr Fin de lignes à l’aide de CR (Mac OS 9).\n" +" --crlf Fin de lignes à l’aide de CR + LF (Windows).\n" +" --lf Fin de lignes à l’aide de LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Usage : ppdhtml [options] nom_fichier.drv >nom_fichier.html\n" +" -D nom=valeur Définir la variable, dont le nom est précisé, sur la " +"valeur indiquée.\n" +"Options :\n" +" -I inclure-rép Inclure le répertoire au chemin de recherche.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Usage : ppdi [options] nom_fichier.ppd [ … nom_fichierN.ppd ]\n" +"Options :\n" +" -I inclure-rép\n" +" -o nom_fichier.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Usage : ppdmerge [options] nom_fichier.ppd [ … nom_fichierN.ppd ]\n" +"Options :\n" +" -o nom_fichier.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Usage : ppdpo [options] -o nom_fichier.po nom_fichier.drv [ … nom_fichierN." +"drv ]\n" +"Options :\n" +" -D nom=valeur Définir la variable, dont le nom est précisé, sur la " +"valeur indiquée.\n" +" -I inclure-rép Inclure le répertoire au chemin de recherche.\n" +" -v Activer la verbosité (lettres V complémentaires pour " +"augmenter la verbosité).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Usage : snmp [hôte-ou-adresse-ip]\n" + +msgid "Value uses indefinite length" +msgstr "La valeur s’avère être de longueur indéfinie" + +msgid "VarBind uses indefinite length" +msgstr "VarBind s’avère être de longueur indéfinie" + +msgid "Version uses indefinite length" +msgstr "La version s’avère être de longueur indéfinie" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: ajout limité aux %d premières imprimantes trouvées" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: valeur booléenne attendue pour l’option waiteof « %s »\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: échec de lecture de la requête de canal latéral.\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" +"WARNING: l’option « %s » ne peut être incluse par le biais d’IncludeFeature.\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: l’imprimante ne répond pas.\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "" +"WARNING: l’imprimante a envoyé le caractère EOF de manière inattendue\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: l’hôte à distance n’a pas répondu au bout de %d secondes par un " +"octet d’état de commande.\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: l’hôte à distance n’a pas répondu au bout de %d secondes par un " +"octet d’état de contrôle.\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: l’hôte à distance n’a pas répondu au bout de %d secondes par un " +"octet d’état de données.\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: la commande SCSI a expiré (%d) ; nouvel essai…\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: ce document n’est pas conforme aux normes Adobe (Adobe Document " +"Structuring Conventions) et risque de ne pas s’imprimer correctement.\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: impossible d’ouvrir « %s :%s » : %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: impossible d’envoyer la requête d’état PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: paquet PAP inattendu, de type %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: paquet PAP inconnu, de type %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: choix « %s » inconnu pour l’option « %s ».\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: option « %s » inconnue.\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: débit en bauds %s non pris en charge.\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: nombre attendu pour l’option d’état « %s »\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: problème réversible : l’hôte du réseau « %s » est occupé ; nouvel " +"essai dans %d secondes…\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "WARNING: aucun pilote d’impression pour Windows 2000 n’est installé." + +msgid "Yes" +msgstr "Oui" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Vous devez accéder à cette page par l’URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "Enveloppe You4" + +msgid "ZPL Label Printer" +msgstr "Imprimante pour étiquettes ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "abandonnée" + +msgid "canceled" +msgstr "annulée" + +msgid "completed" +msgstr "terminée" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert : utilisez l’option -f pour préciser un fichier à convertir.\n" + +msgid "cups-deviced failed to execute." +msgstr "L’exécution de « cups-deviced » a échoué." + +msgid "cups-driverd failed to execute." +msgstr "L’exécution de « cups-driverd » a échoué." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb : aucun fichier PPD pour l’imprimante « %s » - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl : connexion impossible au serveur : %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl : option « %s » inconnue\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl : option « -%c » inconnue\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "" +"cupsd : nom de fichier de configuration attendu après l’option « -c ».\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd : impossible de déterminer le répertoire actif.\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd : argument « %s » inconnu - interruption en cours…\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd : option inconnue « %c » - interruption en cours…\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd : prise en charge de launchd(8) non compilée dans le code ; exécution " +"en mode normal.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter : numéro de document %d non valide.\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter : identifiant %d de tâche non valide.\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter : un seul nom de fichier peut être spécifié.\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter : impossible d’obtenir le fichier de tâche - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd : l’option -q est incompatible avec l’option -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd : l’option -v est incompatible avec l’option -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "périphérique pour %s/%s : %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "périphérique pour %s : %s\n" + +msgid "error-index uses indefinite length" +msgstr "Le paramètre error-index s’avère être de longueur indéfinie" + +msgid "error-status uses indefinite length" +msgstr "Le paramètre error-status s’avère être de longueur indéfinie" + +msgid "held" +msgstr "retenue" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\taccéder à l’aide relative aux commandes\n" + +msgid "idle" +msgstr "inactive" + +msgid "job-printer-uri attribute missing!" +msgstr "Attribut « job-printer-uri » manquant." + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "" +"lpadmin : le nom d’une classe doit se limiter aux caractères imprimables.\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin : fichier PPD attendu après l’option « -P ».\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "" +"lpadmin : paramètre allow/deny:liste_utilisateurs attendu après l’option « -" +"u ».\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin : classe attendue après l’option « -r ».\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin : nom de classe attendu après l’option « -c ».\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin : description attendue après l’option « -D ».\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin : URI de périphérique attendu après l’option « -v ».\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin : type ou types de fichier attendu(s) après l’option « -I ».\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin : nom d’hôte attendu après l’option « -h ».\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin : interface attendue après l’option « -i ».\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin : emplacement attendu après l’option « -L ».\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin : modèle attendu après l’option « -m ».\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin : nom=valeur attendu après l’option « -o ».\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin : imprimante attendue après l’option « -p ».\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin : nom d’imprimante attendu après l’option « -d ».\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin : imprimante ou classe attendue après l’option « -x ».\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin : aucun nom de membre détecté.\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin : l’imprimante %s est déjà un membre de la classe %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin : l’imprimante %s n’est pas un membre de la classe %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "" +"lpadmin : le nom de l’imprimante doit se limiter aux caractères " +"imprimables.\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible d’ajouter d’imprimante à la classe :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin : connexion impossible au serveur : %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin : impossible d’ouvrir le fichier PPD « %s » - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin : impossible d’ouvrir le fichier « %s » : %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de retirer une imprimante de la classe :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir le fichier PPD :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir l’URI du périphérique :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir le script ou le fichier PPD interface :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir le script interface :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir la description de l’imprimante :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir l’emplacement de l’imprimante :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin : impossible de définir les options de l’imprimante :\n" +" Vous devez d’abord indiquer le nom d’une imprimante.\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin : option allow/deny « %s » inconnue.\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin : argument « %s » inconnu.\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin : option « %c » inconnue.\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin : avertissement - liste des types de contenu ignorée.\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" +"lpinfo : chaîne de l’identifiant du périphérique 1284 attendue après « --id-" +"périphérique ».\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo : langue attendue après « --language ».\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo : marque et modèle attendus après « --make-and-model »\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo : chaîne du produit attendue après « --product ».\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo : liste des schémas attendue après « --exclude-schemes ».\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo : liste des schémas attendue après « --include-schemes ».\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo : délai d’attente attendu après « --timeout ».\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo : argument « %s » inconnu.\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo : option « %c » inconnue.\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo : option « %s » inconnue.\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove : connexion impossible au serveur : %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove : argument « %s » inconnu.\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove : option « %c » inconnue.\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions : aucune imprimante !?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions : impossible d’ajouter d’imprimante ou d’instance : %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions : impossible d’obtenir le fichier PPD de %s : %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions : impossible d’ouvrir le fichier PPD de %s ».\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions : imprimante ou classe inconnue.\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "" +"lppasswd : seul l’utilisateur « root » est en mesure d’ajouter ou de " +"supprimer des mots de passe.\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd : fichier des mots de passe occupé.\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd : fichier des mots de passe non mis à jour.\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd : mot de passe non concordant.\n" + +msgid "" +"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" +msgstr "" +"lppasswd : mot de passe rejeté.\n" +"Votre mot de passe doit comporter au moins six caractères, au moins une " +"lettre et un chiffre,\n" +"et ne peut pas reprendre votre nom d’utilisateur.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd : les mots de passe ne concordent pas.\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd : impossible de copier la chaîne de mot de passe : %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd : impossible d’ouvrir le fichier des mots de passe : %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "" +"lppasswd : impossible d’écrire dans le fichier des mots de passe : %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" +"lppasswd : impossible d’effectuer de copie de sauvegarde de l’ancien fichier " +"des mots de passe : %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd : impossible de renommer le fichier des mots de passe : %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd : l’utilisateur « %s » et le groupe « %s » n’existent pas.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat : erreur - destination « %s » inexistante pour les noms de variables " +"d’environnement %s.\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "membres de la classe %s :\n" + +msgid "no entries\n" +msgstr "aucune entrée\n" + +msgid "no system default destination\n" +msgstr "aucune destination système par défaut\n" + +msgid "notify-events not specified!" +msgstr "Attribut « notify-events » non renseigné." + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "" +"L’URI « %s », indiquée par le paramètre notify-recipient-uri, est déjà " +"utilisée." + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "" +"L’URI « %s » du paramètre « notify-recipient-uri » utilise un mode inconnu." + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d erroné." + +msgid "pending" +msgstr "en attente" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc : inclusion du répertoire « %s »…\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "" +"ppdc : ajout/actualisation du texte de l’interface utilisateur à partir de %" +"s…\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc : valeur booléenne (%s) incorrecte à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc : nom de résolution « %s » incorrect à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc : mot-clé d’état %s incorrect à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "" +"ppdc : substitution de variables ($%c) incorrecte à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc : choix trouvé à la ligne %d sur %s, sans Option.\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc : #po en double pour la langue %s à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc : définition de filtre attendue à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc : nom de programme attendu à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc : valeur booléenne attendue à la ligne %d sur %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc : jeu de caractères attendu après Font à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc : code de choix attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc : nom/texte de choix attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc : ordre de couleurs attendu pour ColorModel à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc : espace de couleurs attendu pour ColorModel à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc : compression attendue pour ColorModel à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc : chaîne des contraintes attendue pour UIConstraints à la ligne %d de %" +"s.\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc : mot-clé attendu du type de gestionnaire après DriverType à la ligne %" +"d de %s.\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc : type de duplex attendu après Duplex à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc : encodage attendu après Font à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc : nom de fichier attendu après #po %s à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc : nom/texte de groupe attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc : nom de fichier d’inclusion attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc : nombre entier attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc : langue attendue après #po à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc : nom attendu après %s à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc : nom attendu après FileName à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc : nom attendu après Font à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc : nom attendu après Manufacturer à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc : nom attendu après MediaSize à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc : nom attendu après ModelName à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc : nom attendu après PCFileName à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc : nom/texte attendu après %s à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc : nom/texte attendu après Installable à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc : nom/texte attendu après Resolution à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc : association nom/texte attendue pour ColorModel à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc : nom/texte d’option attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc : section d’option attendue à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc : type d’option attendu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc : champ de remplacement attendu après Resolution à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc : nombre réel attendu à la ligne %d de %s.\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc : résolution/type de papier attendu après ColorProfile à la ligne %d de " +"%s.\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc : résolution/type de papier attendu après SimpleColorProfile à la ligne " +"%d de %s.\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc : sélecteur attendu après %s à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc : état attendu après Font à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc : chaîne attendue après Copyright à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc : chaîne attendue après Version à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc : deux noms d’option attendus à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc : valeur attendue après %s à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc : version attendue après Font à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc : nom de fichier #include/#po « %s » non valide\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc : coût pour le filtre à la ligne %d de %s non valide\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc : type MIME pour le filtre à la ligne %d de %s non valide\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" +"ppdc : nom de programme vide pour le filtre à la ligne %d de %s non valide\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc : section d’option « %s » à la ligne %d de %s non valide\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc : type d’option « %s » à la ligne %d de %s non valide\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc : chargement du fichier « %s » des informations de gestionnaire…\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc : chargement de messages pour la langue « %s »…\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc : chargement de messages de « %s »…\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc : #endif absent à la fin de « %s ».\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc : #if absent à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc : aucun catalogue de messages fourni pour la langue %s.\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc : option %s redéfinie sous un autre type à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc : contrainte d’option doit inclure *nom à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "" +"ppdc : instructions #if imbriquées trop nombreuses à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc : impossible de créer le fichier PPD « %s » - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc : impossible de créer le répertoire de sortie %s : %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc : impossible de créer les canaux de sortie : %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc : impossible d’exécuter cupstestppd : %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "" +"ppdc : impossible de retrouver le fichier #po %s à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc : impossible de retrouver le fichier d’inclusion « %s » à la ligne %d de " +"%s.\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc : impossible de déterminer la localisation de « %s » - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc : impossible de charger le fichier de localisation « %s » - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc : variable indéfinie (%s) à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc : type de gestionnaire %s inconnu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc : type de duplex « %s » inconnu à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc : taille du papier « %s » inconnue à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc : jeton « %s » inconnu détecté à la ligne %d de %s.\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc : caractères de fin, dans le nombre réel « %s », inconnus à la ligne %d " +"de %s.\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc : chaîne commençant par %c non terminée, à la ligne %d de %s.\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc : écriture de %s…\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc : écriture des fichiers PPD dans le répertoire « %s »…\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge : LanguageVersion « %s » incorrect dans %s.\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge : fichier PPD %s ignoré…\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "" +"ppdmerge : impossible d’effectuer de copie de sauvegarde de %s en %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "l’imprimante %s est désactivée depuis %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "l’imprimante %s est inactive, mais activée depuis %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "l’imprimante %s est en cours d’impression %s-%d (activée depuis %s)\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "l’imprimante %s/%s est désactivée depuis %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "l’imprimante %s/%s est inactive, mais activée depuis %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "" +"l’imprimante %s/%s est en cours d’impression %s-%d (activée depuis %s)\n" + +msgid "processing" +msgstr "en cours" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "l’identifiant de la requête est %s-%d (%d fichier(s))\n" + +msgid "request-id uses indefinite length" +msgstr "Le paramètre request-id s’avère être de longueur indéfinie" + +msgid "scheduler is not running\n" +msgstr "le programmateur n’est pas en cours d’exécution\n" + +msgid "scheduler is running\n" +msgstr "le programmateur s’exécute\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "stat sur %s a échoué : %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tafficher l’état du daemon et la file d’attente\n" + +msgid "stopped" +msgstr "arrêtée" + +#, c-format +msgid "system default destination: %s\n" +msgstr "destination système par défaut : %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "destination système par défaut : %s/%s\n" + +msgid "unknown" +msgstr "inconnu" + +msgid "untitled" +msgstr "sans titre" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings s’avère être de longueur indéfinie" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " ATTN Fichier APDialogExtension « %s » manquant\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " ATTN Fichier APPrinterIconPath « %s » manquant\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s : impossible d’ouvrir %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s : impossible d’ouvrir %s - %s à la ligne %d." + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 ppp (niveaux de gris)" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: URI du périphérique manquant sur la ligne de commande et aucune " +#~ "variable d’environnement DEVICE_URI.\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: impossible de créer un fichier temporaire - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: impossible de créer un fichier temporaire : %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: impossible d’ouvrir le fichier temporaire." + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "" +#~ "ERROR: le filtre pdftops a cessé de fonctionner à l’issue du signal %d.\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "" +#~ "ERROR: le filtre pdftops a indiqué l’état %d lors de sa fermeture.\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Erreur inconnue relative à l’imprimante (%s)" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Usage : convert [ options ]\n" +#~ "\n" +#~ "Options :\n" +#~ "\n" +#~ " -f nom_fichier Définir le fichier à convertir (dans le cas " +#~ "contraire, stdin)\n" +#~ " -o nom_fichier Définir le fichier à générer (dans le cas " +#~ "contraire, stdout)\n" +#~ " -i mime/type Définir le type MIME en entrée (dans le cas " +#~ "contraire, auto-typed)\n" +#~ " -j mime/type Définir le type MIME en sortie (dans le cas " +#~ "contraire, application/pdf)\n" +#~ " -P nom_fichier.ppd Définir le fichier PPD\n" +#~ " -a 'nom=valeur …' Définir la ou les options\n" +#~ " -U nom_utilisateur Définir le nom d’utilisateur pour la tâche\n" +#~ " -J titre Définir le titre\n" +#~ " -c copies Définir le nombre de copies\n" +#~ " -u Supprimer le fichier PPD une fois terminé\n" +#~ " -D Supprimer le fichier en entrée une fois terminé\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Usage : cupsfilter -m mime/type [ options ] nom_fichier\n" +#~ "\n" +#~ "Options :\n" +#~ "\n" +#~ " -c cupsd.conf Définir le fichier cupsd.conf à utiliser\n" +#~ " -j id-tâche[,N] Filtrer le fichier N sur la tâche indiquée (par " +#~ "défaut, fichier 1)\n" +#~ " -n copies Définir le nombre de copies\n" +#~ " -o nom=valeur Définir la ou les options\n" +#~ " -p nom_fichier.ppd Définir le fichier PPD\n" +#~ " -t titre Définir le titre\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Usage : cupstestppd [options] nom_fichier1.ppd[.gz] [… nom_fichierN.ppd[." +#~ "gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options :\n" +#~ "\n" +#~ " -R répertoire_root Définir un autre utilisateur root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Produire des avertissements plutôt que des " +#~ "erreurs\n" +#~ " -q Exécuter sans sortie à l’utilisateur\n" +#~ " -r Utiliser le mode d’ouverture « sans contrainte »\n" +#~ " -v Produire une légère verbosité\n" +#~ " -vv Produire une importante verbosité\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter : impossible de créer le fichier temporaire : %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin : impossible de créer un fichier temporaire - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin : impossible de créer un fichier temporaire : %s\n" diff --git a/locale/cups_id.po b/locale/cups_id.po new file mode 100644 index 0000000000..a8b8c76b84 --- /dev/null +++ b/locale/cups_id.po @@ -0,0 +1,7095 @@ +# translation of cups_id.po to Bahasa Indonesia +# +# "$Id$" +# +# Message catalog template for the Common UNIX Printing System (CUPS). +# +# Copyright 2007 by Apple Inc. +# Copyright 2005-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# +# Citra Paska , 2008, 2009. + +# +# Notes for Translators: +# +# The following prefixes MUST NOT be translated: "ALERT:", "CRIT:", "INFO:", +# "NOTICE:", and "WARNING:". +# +# The "checkpo" program located in the "locale" source directory can be used +# to verify that your translations do not introduce formatting errors or other +# problems. Run with: +# +# cd locale +# ./checkpo cups_LL.po +# +# where "LL" is your locale. +# +msgid "" +msgstr "" +"Project-Id-Version: cups_id\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-09-29 05:17+0700\n" +"Last-Translator: Citra Paska \n" +"Language-Team: Bahasa Indonesia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" + +#: systemv/lpstat.c:1848 systemv/lpstat.c:1961 +msgid "\t\t(all)\n" +msgstr "\t\t(semua)\n" + +#: systemv/lpstat.c:1851 systemv/lpstat.c:1854 systemv/lpstat.c:1964 +#: systemv/lpstat.c:1967 +msgid "\t\t(none)\n" +msgstr "\t\t(nihil)\n" + +#: berkeley/lpc.c:438 +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d entri\n" + +#: systemv/lpstat.c:1829 systemv/lpstat.c:1942 +msgid "\tAfter fault: continue\n" +msgstr "\tUsai kesalahan: lanjut\n" + +#: systemv/lpstat.c:1461 systemv/lpstat.c:1795 systemv/lpstat.c:1908 +msgid "\tAlerts:" +msgstr "\tPeringatan:" + +#: systemv/lpstat.c:1852 systemv/lpstat.c:1965 +msgid "\tBanner required\n" +msgstr "\tBanner diperlukan\n" + +#: systemv/lpstat.c:1853 systemv/lpstat.c:1966 +msgid "\tCharset sets:\n" +msgstr "\tSet karakter:\n" + +#: systemv/lpstat.c:1818 systemv/lpstat.c:1931 +msgid "\tConnection: direct\n" +msgstr "\tKoneksi: langsung\n" + +#: systemv/lpstat.c:1809 systemv/lpstat.c:1922 +msgid "\tConnection: remote\n" +msgstr "\tKoneksi: jarak jauh\n" + +#: systemv/lpstat.c:1856 systemv/lpstat.c:1969 +msgid "\tDefault page size:\n" +msgstr "\tUkuran halaman utama:\n" + +#: systemv/lpstat.c:1855 systemv/lpstat.c:1968 +msgid "\tDefault pitch:\n" +msgstr "\tTiti utama:\n" + +#: systemv/lpstat.c:1857 systemv/lpstat.c:1970 +msgid "\tDefault port settings:\n" +msgstr "\tPengaturan port utama:\n" + +#: systemv/lpstat.c:1790 systemv/lpstat.c:1903 +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDeskripsi: %s\n" + +#: systemv/lpstat.c:1784 systemv/lpstat.c:1897 +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormulir yang diakuisisi:\n" +"\tJenis isi: apa saja\n" +"\tJenis pencetak: tak dikenal\n" + +#: systemv/lpstat.c:1850 systemv/lpstat.c:1963 +msgid "\tForms allowed:\n" +msgstr "\tFormulir yang diperbolehkan:\n" + +#: systemv/lpstat.c:1813 systemv/lpstat.c:1926 +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tAntarmuka: %s.ppd\n" + +#: systemv/lpstat.c:1822 systemv/lpstat.c:1935 +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tAntarmuka: %s/interfaces/%s\n" + +#: systemv/lpstat.c:1826 systemv/lpstat.c:1939 +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tAntarmuka: %s/ppd/%s.ppd\n" + +#: systemv/lpstat.c:1804 systemv/lpstat.c:1917 +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tLokasi: %s\n" + +#: systemv/lpstat.c:1828 systemv/lpstat.c:1941 +msgid "\tOn fault: no alert\n" +msgstr "\tSaat gagal: tanpa peringatan\n" + +#: systemv/lpstat.c:1833 systemv/lpstat.c:1847 systemv/lpstat.c:1946 +#: systemv/lpstat.c:1960 +msgid "\tUsers allowed:\n" +msgstr "\tPengguna yang diperbolehkan:\n" + +#: systemv/lpstat.c:1840 systemv/lpstat.c:1953 +msgid "\tUsers denied:\n" +msgstr "\tPengguna yang dilarang:\n" + +#: berkeley/lpc.c:440 +msgid "\tdaemon present\n" +msgstr "\tjurik hadir\n" + +#: berkeley/lpc.c:436 +msgid "\tno entries\n" +msgstr "\ttidak ada entri\n" + +#: berkeley/lpc.c:408 berkeley/lpc.c:420 +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tpencetak pada perangkat '%s' kecepatan -1\n" + +#: berkeley/lpc.c:433 +msgid "\tprinting is disabled\n" +msgstr "\tproses cetak dinonaktifkan\n" + +#: berkeley/lpc.c:431 +msgid "\tprinting is enabled\n" +msgstr "\tproses cetak diaktifkan\n" + +#: systemv/lpstat.c:1467 +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tantrian untuk %s\n" + +#: berkeley/lpc.c:428 +msgid "\tqueuing is disabled\n" +msgstr "\tantrian dinonaktifkan\n" + +#: berkeley/lpc.c:426 +msgid "\tqueuing is enabled\n" +msgstr "\tantrian diaktifkan\n" + +#: systemv/lpstat.c:1777 systemv/lpstat.c:1890 +msgid "\treason unknown\n" +msgstr "\talasan tak dikenal\n" + +#: systemv/cupstestppd.c:551 +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" DETIL HASIL KECOCOKAN TES\n" + +#: systemv/cupstestppd.c:512 systemv/cupstestppd.c:516 +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Halaman 15, seksi 3.1.\n" + +#: systemv/cupstestppd.c:508 +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Halaman 15, seksi 3.2.\n" + +#: systemv/cupstestppd.c:524 +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Halaman 19, seksi 3.3.\n" + +#: systemv/cupstestppd.c:486 +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Halaman 20, seksi 3.4.\n" + +#: systemv/cupstestppd.c:528 +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Halaman 27, seksi 3.5.\n" + +#: systemv/cupstestppd.c:482 +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Halaman 42, seksi 5.2.\n" + +#: systemv/cupstestppd.c:520 +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Halaman 16-17, seksi 3.2.\n" + +#: systemv/cupstestppd.c:496 +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Halaman 42-45, seksi 5.2.\n" + +#: systemv/cupstestppd.c:491 +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Halaman 45-46, seksi 5.2.\n" + +#: systemv/cupstestppd.c:500 +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Halaman 48-49, seksi 5.2.\n" + +#: systemv/cupstestppd.c:504 +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Halaman 52-54, seksi 5.2.\n" + +#: berkeley/lpq.c:546 +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f bita\n" + +#: systemv/cupstestppd.c:668 +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +#: systemv/cupstestppd.c:605 +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +#: systemv/cupstestppd.c:639 +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +#: systemv/cupstestppd.c:710 +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +#: systemv/cupstestppd.c:754 +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +#: systemv/cupstestppd.c:774 +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +#: systemv/cupstestppd.c:794 +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +#: systemv/cupstestppd.c:846 +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +#: systemv/cupstestppd.c:886 +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +#: systemv/cupstestppd.c:906 +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +#: systemv/cupstestppd.c:966 +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +#: systemv/cupstestppd.c:1041 +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +#: systemv/cupstestppd.c:946 +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +#: systemv/cupstestppd.c:926 +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +#: systemv/cupstestppd.c:1001 +msgid " PASS Product\n" +msgstr " PASS Product\n" + +#: systemv/cupstestppd.c:1076 +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#: systemv/cupstestppd.c:3416 +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\" konflik dengan \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" + +#: systemv/cupstestppd.c:1449 +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s tidak memiliki opsi yang berkorespondensi!\n" + +#: systemv/cupstestppd.c:1557 +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s berbagi prefiks umum dengan %s\n" +" REF: Halaman 15, seksi 3.2.\n" + +#: systemv/cupstestppd.c:1458 +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Pilihan utama mengalam konflik!\n" + +#: systemv/cupstestppd.c:1420 +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Opsi kata kunci Duplex %s mungkin tidak bekerja seperti yang diharapkan dan seharusnya dinamai Duplex!\n" +" REF: Halaman 122, seksi 5.17\n" + +#: systemv/cupstestppd.c:1819 +msgid " WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr " WARN Berkas memiliki campuran CR, LF, dan CR LF pada akhir baris!\n" + +#: systemv/cupstestppd.c:1474 +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding diperlukan oleh spesifikasi PPD 4.3.\n" +" REF: Halaman 56-57, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1801 +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Baris %d hanya mengandung spasi!\n" + +#: systemv/cupstestppd.c:1482 +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Manufacturer diperlukan oleh spesifikasi PPD 4.3.\n" +" REF: Halaman 58-59, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1824 +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr " WARN Berkas PPD non-Windows seharusnya hanya berakhir baris LF, bukan CR LF!\n" + +#: systemv/cupstestppd.c:1466 +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN PPD versi %.1f telah usang!\n" +" REF: Halaman 42, seksi 5.2.\n" + +#: systemv/cupstestppd.c:1495 +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName lebih panjang dari 8.3 melanggar spesifikasi PPD.\n" +" REF: Halaman 61-62, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1529 +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols mengandung PJL tetapi atribut JCL tidak diset.\n" +" REF: Halaman 78-79, seksi 5.7.\n" + +#: systemv/cupstestppd.c:1520 +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols mengandung PJL dan BCP; diharapkan TBCP.\n" +" REF: Halaman 78-79, seksi 5.7.\n" + +#: systemv/cupstestppd.c:1503 +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName diperlukan oleh spesifikasi PPD 4.3.\n" +" REF: Halaman 64-65, seksi 5.3.\n" + +#: systemv/cupstestppd.c:2307 +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s tidak ada!\n" + +#: systemv/cupstestppd.c:3571 +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr " %s %s berkas \"%s\" memiliki kapitalisasi yang salah!\n" + +#: systemv/cupstestppd.c:2377 +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" + +#: systemv/cupstestppd.c:3131 +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s UTF-8 jelek \"%s\" string translasi untuk opsi %s!\n" + +#: systemv/cupstestppd.c:3177 systemv/cupstestppd.c:3226 +#: systemv/cupstestppd.c:3265 +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s UTF-8 jelek \"%s\" string translasi untuk opsi %s, pilihan %s!\n" + +#: systemv/cupstestppd.c:2429 +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Nilai cupsFilter jelek \"%s\"!\n" + +#: systemv/cupstestppd.c:2794 +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s cupsICCProfile jelek \"%s\"!\n" + +#: systemv/cupstestppd.c:2500 +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Nilai cupsPreFilter jelek \"%s\"!\n" + +#: systemv/cupstestppd.c:1897 +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s cupsUIConstraints jelek %s: \"%s\"!\n" + +#: systemv/cupstestppd.c:3081 +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Bahasa jelek \"%s\"!\n" + +#: systemv/cupstestppd.c:2484 systemv/cupstestppd.c:2556 +#: systemv/cupstestppd.c:2594 systemv/cupstestppd.c:2632 +#: systemv/cupstestppd.c:2670 systemv/cupstestppd.c:2708 +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr " %s Ejaan dari %s jelek - seharusnya %s!\n" + +#: systemv/cupstestppd.c:2738 +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr " %s Tidak dapat menyediakan APScanAppPath dan APScanAppBundleID!\n" + +#: systemv/cupstestppd.c:1878 +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints %s kosong!\n" + +#: systemv/cupstestppd.c:3117 +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Kehilangan \"%s\" string translasi untuk opsi %s!\n" + +#: systemv/cupstestppd.c:3209 systemv/cupstestppd.c:3249 +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s Kehilangan \"%s\" string translasi untuk opsi %s, pilihan %s!\n" + +#: systemv/cupstestppd.c:2569 +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr " %s Kehilangan berkas APDialogExtension \"%s\"\n" + +#: systemv/cupstestppd.c:2607 +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr " %s Kehilangan berkas APPrinterIconPath \"%s\"\n" + +#: systemv/cupstestppd.c:2645 +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr " %s Kehilangan berkas APPrinterLowInkTool \"%s\"\n" + +#: systemv/cupstestppd.c:2683 +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr " %s Kehilangan berkas APPrinterUtilityPath \"%s\"\n" + +#: systemv/cupstestppd.c:2721 +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr " %s Kehilangan berkas APScanAppPath \"%s\"\n" + +#: systemv/cupstestppd.c:2926 +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" %s Kehilangan opsi PageRegion yang DIPERLUKAN!\n" +" REF: Halaman 100, seksi 5.14.\n" + +#: systemv/cupstestppd.c:2911 +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" %s Kehilangan opsi PageSize yang DIPERLUKAN!\n" +" REF: Halaman 99, seksi 5.14.\n" + +#: systemv/cupstestppd.c:2088 systemv/cupstestppd.c:2129 +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Kehilangan pilihan *%s %s dalam UIConstraints \"*%s %s *%s %s\"!\n" + +#: systemv/cupstestppd.c:1983 +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Kehilangan pilihan *%s %s dalam cupsUIConstraints %s: \"%s\"!\n" + +#: systemv/cupstestppd.c:2458 +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Kehilangan berkas cupsFilter \"%s\"\n" + +#: systemv/cupstestppd.c:2828 +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Kehilangan berkas cupsICCProfile \"%s\"!\n" + +#: systemv/cupstestppd.c:2529 +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Kehilangan berkas cupsPreFilter \"%s\"\n" + +#: systemv/cupstestppd.c:1915 +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Kehilangan cupsUIResolver %s!\n" + +#: systemv/cupstestppd.c:2074 systemv/cupstestppd.c:2115 +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Kehilangan opsi %s dalam UIConstraints \"*%s %s *%s %s\"!\n" + +#: systemv/cupstestppd.c:1967 +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Kehilangan opsi %s dalam cupsUIConstraints %s: \"%s\"!\n" + +#: systemv/cupstestppd.c:3303 +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Tidak ada basis translasi \"%s\" yang disertakan pada berkas!\n" + +#: systemv/cupstestppd.c:2989 +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" +" %s Nama ukuran nonstandar \"%s\"!\n" +" REF: Halaman 187, seksi B.2.\n" + +#: systemv/cupstestppd.c:2353 +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" + +#: systemv/cupstestppd.c:3006 systemv/cupstestppd.c:3020 +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr " %s Ukuran \"%s\" ditentukan untuk %s bukan untuk %s!\n" + +#: systemv/cupstestppd.c:2964 +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr " %s Ukuran \"%s\" memiliki dimensi yang tak diharapkan (%gx%g)!\n" + +#: systemv/cupstestppd.c:2856 +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr "" + +#: systemv/cupstestppd.c:2038 +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr "" + +#: systemv/cupstestppd.c:2020 +#, c-format +msgid " %s cupsUIResolver %s does not list at least two different options!\n" +msgstr " %s cupsUIResolver %s tidak menyediakan setidaknya dua opsi berbeda!\n" + +#: systemv/cupstestppd.c:2238 +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr " **FAIL** %s nama yang dipilih %s dan %s berbeda hanya pada besar/kecilnya huruf!\n" + +#: systemv/cupstestppd.c:1243 +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s seharusnya 1284DeviceID!\n" +" REF: Halaman 72, seksi 5.5\n" + +#: systemv/cupstestppd.c:659 +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** Default%s %s JELEK\n" +" REF: Halaman 40, seksi 4.5.\n" + +#: systemv/cupstestppd.c:595 +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DefaultImageableArea %s JELEK!\n" +" REF: Halaman 102, seksi 5.15.\n" + +#: systemv/cupstestppd.c:631 +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DefaultPaperDimension %s JELEK!\n" +" REF: Halaman 103, seksi 5.15.\n" + +#: systemv/cupstestppd.c:1102 +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** Atribut JobPatchFile JELEK dalam berkas\n" +" REF: Halaman 24, seksi 3.4.\n" + +#: systemv/cupstestppd.c:822 +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** Manufacturer JELEK (seharusnya \"HP\")\n" +" REF: Halaman 211, tabel D.1.\n" + +#: systemv/cupstestppd.c:838 +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** Manufacturer JELEK (seharusnya \"Oki\")\n" +" REF: Halaman 211, tabel D.1.\n" + +#: systemv/cupstestppd.c:877 +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ModelName JELEK - \"%c\" tidak diperbolehkan dalam string.\n" +" REF: Halaman 59-60, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1033 +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** PSVersion JELEK - bukan \"(string) int\".\n" +" REF: Halaman 62-64, seksi 5.3.\n" + +#: systemv/cupstestppd.c:994 +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** Product JELEK - bukan \"(string)\".\n" +" REF: Halaman 62, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1068 +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ShortNickName JELEK - lebih dari 31 karakter.\n" +" REF: Halaman 64-65, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1224 +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" + +#: systemv/cupstestppd.c:702 +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FileVersion \"%s\" jelek\n" +" REF: Halaman 56, seksi 5.3.\n" + +#: systemv/cupstestppd.c:746 +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FormatVersion \"%s\" jelek\n" +" REF: Halaman 56, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1288 +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** LanguageEncoding %s jelek - seharusnya ISOLatin1!\n" + +#: systemv/cupstestppd.c:1302 +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** LanguageVersion %s jelek - seharusnya English!\n" + +#: systemv/cupstestppd.c:3443 systemv/cupstestppd.c:3465 +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **FAIL** Kode opsi utama tidak bisa diinterpretasikan: %s\n" + +#: systemv/cupstestppd.c:1361 +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr " **FAIL** String translasi utama untuk opsi %s pilihan %s mengandung karakter 8-bit!\n" + +#: systemv/cupstestppd.c:1334 +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** String translasi utama untuk opsi %s mengandung karakter 8-" +"bit!\n" + +#: systemv/cupstestppd.c:2176 +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr " **FAIL** Nama kelompok %s dan %s berbeda hanya besar/kecilnya huruf!\n" + +#: systemv/cupstestppd.c:2221 +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Terjadi ganda dari %s nama yang dipilih %s!\n" + +#: systemv/cupstestppd.c:2198 +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr " **FAIL** Nama opsi %s dan %s berbeda hanya besar/kecilnya huruf!\n" + +#: systemv/cupstestppd.c:679 +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** DIPERLUKAN Default%s\n" +" REF: Halaman 40, seksi 4.5.\n" + +#: systemv/cupstestppd.c:580 +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DIPERLUKAN DefaultImageableArea\n" +" REF: Halaman 102, seksi 5.15.\n" + +#: systemv/cupstestppd.c:616 +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DIPERLUKAN DefaultPaperDimension\n" +" REF: Halaman 103, seksi 5.15.\n" + +#: systemv/cupstestppd.c:720 +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN FileVersion\n" +" REF: Halaman 56, seksi 5.3.\n" + +#: systemv/cupstestppd.c:764 +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN FormatVersion\n" +" REF: Halaman 56, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1153 +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DIPERLUKAN ImageableArea untuk PageSize %s\n" +" REF: Halaman 41, seksi 5.\n" +" REF: Halaman 102, seksi 5.15.\n" + +#: systemv/cupstestppd.c:784 +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN LanguageEncoding\n" +" REF: Halaman 56-57, seksi 5.3.\n" + +#: systemv/cupstestppd.c:804 +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN LanguageVersion\n" +" REF: Halaman 57-58, seksi 5.3.\n" + +#: systemv/cupstestppd.c:856 +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN Manufacturer\n" +" REF: Halaman 58-59, seksi 5.3.\n" + +#: systemv/cupstestppd.c:896 +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN ModelName\n" +" REF: Halaman 59-60, seksi 5.3.\n" + +#: systemv/cupstestppd.c:916 +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN NickName\n" +" REF: Halaman 60, seksi 5.3.\n" + +#: systemv/cupstestppd.c:976 +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN PCFileName\n" +" REF: Halaman 61-62, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1051 +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN PSVersion\n" +" REF: Halaman 62-64, seksi 5.3.\n" + +#: systemv/cupstestppd.c:956 +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** DIPERLUKAN PageRegion\n" +" REF: Halaman 100, seksi 5.14.\n" + +#: systemv/cupstestppd.c:1122 +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** DIPERLUKAN PageSize\n" +" REF: Halaman 41, seksi 5.\n" +" REF: Halaman 99, seksi 5.14.\n" + +#: systemv/cupstestppd.c:936 +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** DIPERLUKAN PageSize\n" +" REF: Halaman 99-100, seksi 5.14.\n" + +#: systemv/cupstestppd.c:1175 +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DIPERLUKAN PaperDimension untuk PageSize %s\n" +" REF: Halaman 41, seksi 5.\n" +" REF: Halaman 103, seksi 5.15.\n" + +#: systemv/cupstestppd.c:1011 +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN Product\n" +" REF: Halaman 62, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1086 +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** DIPERLUKAN ShortNickName\n" +" REF: Halaman 64-65, seksi 5.3.\n" + +#: systemv/cupstestppd.c:1569 +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d KESALAHAN DITEMUKAN\n" + +#: systemv/cupstestdsc.c:238 systemv/cupstestdsc.c:280 +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" %%%%BoundingBox jelek: pada baris %d!\n" +" REF: Halaman 39, %%%%BoundingBox:\n" + +#: systemv/cupstestdsc.c:309 +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" + +#: systemv/cupstestdsc.c:222 systemv/cupstestdsc.c:262 +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" + +#: systemv/cupstestdsc.c:180 +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Baris %d lebih dari 255 karakter (%d)!\n" +" REF: Halaman 25, Line Length (Panjang Baris)\n" + +#: systemv/cupstestdsc.c:196 +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" Kehilangan %!PS-Adobe-3.0 pada baris pertama!\n" +" REF: Halaman 17, 3.1 Conforming Documents (Menyesuaikan Dokumen)\n" + +#: systemv/cupstestdsc.c:366 +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Kehilangan komentar %%EndComments!\n" +" REF: Halaman 41, %%EndComments\n" + +#: systemv/cupstestdsc.c:346 +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Kehilangan atau %%BoundingBox jelek: komentar!\n" +" REF: Halaman 39, %%BoundingBox:\n" + +#: systemv/cupstestdsc.c:376 +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Kehilangan atau %%Page jelek: komentar!\n" +" REF: Halaman 53, %%Page:\n" + +#: systemv/cupstestdsc.c:356 +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Kehilangan atau %%Pages jelek: komentar!\n" +" REF: Halaman 43, %%Pages:\n" + +#: systemv/cupstestppd.c:1571 +msgid " NO ERRORS FOUND\n" +msgstr " TIDAK ADA KESALAHAN\n" + +#: systemv/cupstestdsc.c:399 +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Menemukan %d baris yang melebihi 255 karakter!\n" + +#: systemv/cupstestdsc.c:394 +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Terlalu banyak komentar %%BeginDocument!\n" + +#: systemv/cupstestdsc.c:386 +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Terlalu banyak komentar %%EndDocument!\n" + +#: systemv/cupstestdsc.c:406 +msgid " Warning: file contains binary data!\n" +msgstr " Peringatan: berkas mengandung data biner!\n" + +#: systemv/cupstestdsc.c:414 +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Peringatan: tidak ada komentar %%EndComments dalam berkas!\n" + +#: systemv/cupstestdsc.c:410 +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Peringatan: DSC usang versi %.1f dalam berkas!\n" + +#: systemv/cupstestppd.c:577 systemv/cupstestppd.c:592 +#: systemv/cupstestppd.c:613 systemv/cupstestppd.c:628 +#: systemv/cupstestppd.c:656 systemv/cupstestppd.c:676 +#: systemv/cupstestppd.c:699 systemv/cupstestppd.c:717 +#: systemv/cupstestppd.c:743 systemv/cupstestppd.c:761 +#: systemv/cupstestppd.c:781 systemv/cupstestppd.c:801 +#: systemv/cupstestppd.c:819 systemv/cupstestppd.c:835 +#: systemv/cupstestppd.c:853 systemv/cupstestppd.c:874 +#: systemv/cupstestppd.c:893 systemv/cupstestppd.c:913 +#: systemv/cupstestppd.c:933 systemv/cupstestppd.c:953 +#: systemv/cupstestppd.c:973 systemv/cupstestppd.c:991 +#: systemv/cupstestppd.c:1008 systemv/cupstestppd.c:1030 +#: systemv/cupstestppd.c:1048 systemv/cupstestppd.c:1065 +#: systemv/cupstestppd.c:1083 systemv/cupstestppd.c:1099 +#: systemv/cupstestppd.c:1119 systemv/cupstestppd.c:1150 +#: systemv/cupstestppd.c:1172 systemv/cupstestppd.c:1221 +#: systemv/cupstestppd.c:1240 systemv/cupstestppd.c:1284 +#: systemv/cupstestppd.c:1298 systemv/cupstestppd.c:1330 +#: systemv/cupstestppd.c:1357 systemv/cupstestppd.c:1875 +#: systemv/cupstestppd.c:1894 systemv/cupstestppd.c:1912 +#: systemv/cupstestppd.c:1964 systemv/cupstestppd.c:1980 +#: systemv/cupstestppd.c:2017 systemv/cupstestppd.c:2035 +#: systemv/cupstestppd.c:2071 systemv/cupstestppd.c:2085 +#: systemv/cupstestppd.c:2112 systemv/cupstestppd.c:2126 +#: systemv/cupstestppd.c:2172 systemv/cupstestppd.c:2194 +#: systemv/cupstestppd.c:2217 systemv/cupstestppd.c:2234 +#: systemv/cupstestppd.c:2303 systemv/cupstestppd.c:2350 +#: systemv/cupstestppd.c:2374 systemv/cupstestppd.c:2425 +#: systemv/cupstestppd.c:2455 systemv/cupstestppd.c:2480 +#: systemv/cupstestppd.c:2496 systemv/cupstestppd.c:2526 +#: systemv/cupstestppd.c:2552 systemv/cupstestppd.c:2566 +#: systemv/cupstestppd.c:2590 systemv/cupstestppd.c:2604 +#: systemv/cupstestppd.c:2628 systemv/cupstestppd.c:2642 +#: systemv/cupstestppd.c:2666 systemv/cupstestppd.c:2680 +#: systemv/cupstestppd.c:2704 systemv/cupstestppd.c:2718 +#: systemv/cupstestppd.c:2735 systemv/cupstestppd.c:2790 +#: systemv/cupstestppd.c:2825 systemv/cupstestppd.c:2852 +#: systemv/cupstestppd.c:2907 systemv/cupstestppd.c:2922 +#: systemv/cupstestppd.c:2960 systemv/cupstestppd.c:3002 +#: systemv/cupstestppd.c:3016 systemv/cupstestppd.c:3077 +#: systemv/cupstestppd.c:3113 systemv/cupstestppd.c:3127 +#: systemv/cupstestppd.c:3173 systemv/cupstestppd.c:3205 +#: systemv/cupstestppd.c:3222 systemv/cupstestppd.c:3245 +#: systemv/cupstestppd.c:3261 systemv/cupstestppd.c:3299 +#: systemv/cupstestppd.c:3439 systemv/cupstestppd.c:3461 +#: systemv/cupstestppd.c:3567 +msgid " FAIL\n" +msgstr " GAGAL\n" + +#: systemv/cupstestppd.c:462 +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" GAGAL\n" +" **FAIL** Tidak bisa membuka berkas PPD - %s\n" + +#: systemv/cupstestppd.c:473 +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" GAGAL\n" +" **FAIL** Tidak bisa membuka berkas PPD - %s pada baris %d.\n" + +#: systemv/cupstestppd.c:1381 +msgid " PASS\n" +msgstr " LEWAT\n" + +#: ppdc/sample.c:51 +msgid "#10 Envelope" +msgstr "#10 Amplop" + +#: ppdc/sample.c:52 +msgid "#11 Envelope" +msgstr "#11 Amplop" + +#: ppdc/sample.c:53 +msgid "#12 Envelope" +msgstr "#12 Amplop" + +#: ppdc/sample.c:54 +msgid "#14 Envelope" +msgstr "#14 Amplop" + +#: ppdc/sample.c:55 +msgid "#9 Envelope" +msgstr "#9 Amplop" + +#: berkeley/lpq.c:552 +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bita\n" + +#: berkeley/lpq.c:557 +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bita\n" + +#: filter/bannertops.c:784 +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f milimeter" + +#: filter/bannertops.c:805 +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f hingga %.0f x %.0f milimeter" + +#: filter/bannertops.c:775 +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f inci" + +#: filter/bannertops.c:794 +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f hingga %.2f x %.2f inci" + +#: systemv/lpstat.c:754 +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s menerima permintaan sejak %s\n" + +#: scheduler/ipp.c:10415 +#, c-format +msgid "%s cannot be changed." +msgstr "%s tidak bisa diubah." + +#: berkeley/lpc.c:194 +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s tidak diimplementasikan oleh versi lpc CUPS.\n" + +#: berkeley/lpq.c:643 +#, c-format +msgid "%s is not ready\n" +msgstr "%s tidak siap\n" + +#: berkeley/lpq.c:636 +#, c-format +msgid "%s is ready\n" +msgstr "%s siap\n" + +#: berkeley/lpq.c:639 +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s siap dan sedang mencetak\n" + +#: systemv/lpstat.c:757 +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s tidak menerima permintaan sejak %s -\n" +"\t%s\n" + +#: scheduler/ipp.c:701 +#, c-format +msgid "%s not supported!" +msgstr "%s tidak didukung!" + +#: systemv/lpstat.c:767 +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s menerima permintaan sejak %s\n" + +#: systemv/lpstat.c:770 +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s tidak menerima permintaan sejak %s -\n" +"\t%s\n" + +#: berkeley/lpq.c:544 +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [tugas %d localhost]\n" + +#: systemv/cancel.c:303 systemv/cancel.c:367 +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s gagal: %s\n" + +#: systemv/cupsaccept.c:73 +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Tidak tahu apa yang hendak dikerjakan!\n" + +#: berkeley/lpr.c:356 systemv/lp.c:603 +#, c-format +msgid "%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: Kesalahan - Nama variabel lingkungan %s sebenarnya tidak ada \"%s\"!\n" + +#: systemv/lp.c:240 +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Kesalahan - ID tugas jelek!\n" + +#: systemv/lp.c:227 +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s: Kesalahan - tidak bisa mencetak dan mengubah tugas secara bersamaan!\n" + +#: systemv/lp.c:523 +#, c-format +msgid "%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Kesalahan - tidak bisa mencetak dari stdin apabila berkas atau ID tugas " +"disediakan!\n" + +#: systemv/lp.c:477 +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Kesalahan - diharapkan set karakter usai opsi '-S'!\n" + +#: systemv/lp.c:497 +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Kesalahan - diharapkan jenis konten usai opsi '-T'!\n" + +#: systemv/lp.c:273 +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Kesalahan - diharapkan banyaknya rangkap usai opsi '-n'!\n" + +#: berkeley/lpr.c:251 +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Kesalahan - diharapkan banyak hitungan rangkap usai opsi '-#'!\n" + +#: berkeley/lpr.c:219 +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Kesalahan - diharapkan target usai opsi '-P'!\n" + +#: systemv/lpstat.c:238 +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Kesalahan - diharapkan target usai opsi '-b'!\n" + +#: systemv/lp.c:145 +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Kesalahan - diharapkan target usai opsi '-d'!\n" + +#: systemv/lp.c:175 +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Kesalahan - diharapkan formulir usai opsi '-f'!\n" + +#: systemv/lp.c:404 +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Kesalahan - diharapkan nama yang ditahan usai opsi '-H'!\n" + +#: berkeley/lpr.c:111 +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Kesalahan - diharapkan nama host usai opsi '-H'!\n" + +#: berkeley/lpq.c:188 berkeley/lprm.c:130 systemv/cancel.c:130 +#: systemv/cupsaccept.c:131 systemv/lp.c:196 systemv/lpstat.c:298 +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Kesalahan - diharapkan nama host usai opsi '-h'!\n" + +#: systemv/lp.c:382 +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Kesalahan - diharapkan daftar modus usai opsi '-y'!\n" + +#: berkeley/lpr.c:275 +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Kesalahan - diharapkan nama usai opsi '-%c'!\n" + +#: systemv/lp.c:296 +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Kesalahan - diharapkan opsi string usai opsi '-o'!\n" + +#: systemv/lp.c:456 +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Kesalahan - diharapkan daftar halaman usai opsi '-P'!\n" + +#: systemv/lp.c:317 +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Kesalahan - diharapkan prioritas usai opsi '-%c'!\n" + +#: systemv/cupsaccept.c:150 +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Kesalahan - diharapkan teks alasan usai opsi '-r'!\n" + +#: systemv/lp.c:364 +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Kesalahan - diharapkan judul usai opsi '-t'!\n" + +#: berkeley/lpq.c:117 berkeley/lpr.c:91 berkeley/lprm.c:110 +#: systemv/cancel.c:99 systemv/cupsaccept.c:108 systemv/lp.c:122 +#: systemv/lpadmin.c:471 systemv/lpstat.c:144 +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Kesalahan - diharapkan nama pengguna usai opsi '-U'!\n" + +#: systemv/cancel.c:152 +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Kesalahan - diharapkan nama pengguna usai opsi '-u'!\n" + +#: berkeley/lpr.c:134 +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Kesalahan - diharapkan nilai usai opsi '-%c'!\n" + +#: systemv/lpstat.c:164 systemv/lpstat.c:178 +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Kesalahan - diperlukan \"completed\", \"not-completed\", atau \"all\" " +"usai opsi '-W'!\n" + +#: berkeley/lpr.c:361 systemv/lp.c:608 +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Kesalahan - tidak tersedia tujuan utama.\n" + +#: systemv/lp.c:340 +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Kesalahan - prioritas harus antara 1 dan 100.\n" + +#: berkeley/lpr.c:365 systemv/lp.c:612 +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Kesalahan - penjadwal tidak merespon!\n" + +#: berkeley/lpr.c:317 systemv/lp.c:556 +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Kesalahan - terlalu banyak berkas - \"%s\"\n" + +#: berkeley/lpr.c:299 systemv/lp.c:539 +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Kesalahan - tidak bisa mengakses \"%s\" - %s\n" + +#: berkeley/lpr.c:410 systemv/lp.c:645 +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "" + +#: berkeley/lprm.c:93 berkeley/lprm.c:182 systemv/cancel.c:222 +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Kesalahan - tujuan tak dikenal \"%s\"!\n" + +#: berkeley/lpq.c:157 +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Kesalahan - tujuan tak dikenal \"%s/%s\"!\n" + +#: berkeley/lpr.c:286 berkeley/lprm.c:148 systemv/cancel.c:164 +#: systemv/cupsaccept.c:174 systemv/lp.c:514 systemv/lpstat.c:459 +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Kesalahan - opsi tak dikenal '%c'!\n" + +#: systemv/cupsaccept.c:167 +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Kesalahan - opsi '%s' tak dikenal!\n" + +#: systemv/lp.c:216 +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Diharapkan ID tugas usai opsi '-i'!\n" + +#: scheduler/cupsfilter.c:558 +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Penyaring \"%s\" tak tersedia: %s\n" + +#: systemv/lpstat.c:511 systemv/lpstat.c:550 +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Nama tujuan tidak sah pada daftar \"%s\"!\n" + +#: scheduler/cupsfilter.c:539 +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: String penyaring \"%s\" tidak sah\n" + +#: systemv/lp.c:432 +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Memerlukan ID tugas ('-i jobid') sebelum '-H restart'!\n" + +#: scheduler/cupsfilter.c:453 +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Tidak ada penyaring untuk konversi dari %s/%s ke %s/%s!\n" + +#: systemv/cupsaccept.c:208 +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Operasi gagal: %s\n" + +#: berkeley/lpq.c:103 berkeley/lpr.c:77 berkeley/lprm.c:72 systemv/cancel.c:85 +#: systemv/cupsaccept.c:94 systemv/cupsaddsmb.c:91 systemv/lp.c:108 +#: systemv/lpadmin.c:277 systemv/lpinfo.c:94 systemv/lpmove.c:79 +#: systemv/lpstat.c:109 +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Maaf, tidak ada dukungan enkripsi yang dikompilasi serta!\n" + +#: berkeley/lpq.c:304 scheduler/cupsfilter.c:1106 systemv/cupsaddsmb.c:149 +#: systemv/cupsaddsmb.c:175 +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Tidak bisa terhubung ke server\n" + +#: systemv/cancel.c:245 systemv/cancel.c:326 +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Tidak bisa mengontak server!\n" + +#: scheduler/cupsfilter.c:419 +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Tidak bisa menentukan jenis MIME dari \"%s\"!\n" + +#: ppdc/ppdc-file.cxx:50 ppdc/ppdmerge.cxx:99 +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Tidak bisa membuka %s: %s\n" + +#: scheduler/cupsfilter.c:603 +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Tidak bisa membuka berkas PPD: %s pada baris %d\n" + +#: ppdc/ppdmerge.cxx:113 +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "%s: Tidak bisa membuka berkas PPD: %s pada baris %d.\n" + +#: scheduler/cupsfilter.c:384 +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Tak dapat membaca basis data MIME dari \"%s\" atau \"%s\"!\n" + +#: berkeley/lpq.c:161 systemv/lpstat.c:565 +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Tujuan tak dikenal \"%s\"!\n" + +#: scheduler/cupsfilter.c:430 +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Jenis MIME yang dituju tak dikenal %s/%s!\n" + +#: scheduler/cupsfilter.c:1312 +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Opsi tak dikenal '%c'!\n" + +#: scheduler/cupsfilter.c:411 +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Sumber jenis MIME tak dikenal %s/%s!\n" + +#: berkeley/lpr.c:148 +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Peringatan - format peubah '%c' tidak didukung - keluaran yang " +"dihasilkan mungkin tak tepat!\n" + +#: systemv/lp.c:485 +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Peringatan - opsi set karakter diabaikan!\n" + +#: systemv/lp.c:505 +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Peringatan - opsi jenis konten diabaikan!\n" + +#: systemv/lp.c:182 +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Peringatan - opsi formulir diabaikan!\n" + +#: systemv/lp.c:390 +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Peringatan - opsi modus diabaikan!\n" + +#: berkeley/lpq.c:245 +#, c-format +msgid "%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: kesalahan - nama variabel lingkungan %s merupakan tujuan yang tidak ada " +"\"%s\"!\n" + +#: berkeley/lpr.c:162 +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: kesalahan - diharapkan opsi=nilai usai opsi '-o'!\n" + +#: berkeley/lpq.c:250 +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: kesalahan - tidak ada tujuan utama.\n" + +#: ppdc/sample.c:281 +msgid "-1" +msgstr "-1" + +#: ppdc/sample.c:272 +msgid "-10" +msgstr "-10" + +#: ppdc/sample.c:364 +msgid "-100" +msgstr "-100" + +#: ppdc/sample.c:363 +msgid "-105" +msgstr "-105" + +#: ppdc/sample.c:271 +msgid "-11" +msgstr "-11" + +#: ppdc/sample.c:362 +msgid "-110" +msgstr "-110" + +#: ppdc/sample.c:361 +msgid "-115" +msgstr "-115" + +#: ppdc/sample.c:270 +msgid "-12" +msgstr "-12" + +#: ppdc/sample.c:360 +msgid "-120" +msgstr "-120" + +#: ppdc/sample.c:269 +msgid "-13" +msgstr "-13" + +#: ppdc/sample.c:268 +msgid "-14" +msgstr "-14" + +#: ppdc/sample.c:267 +msgid "-15" +msgstr "-15" + +#: ppdc/sample.c:280 +msgid "-2" +msgstr "-2" + +#: ppdc/sample.c:380 +msgid "-20" +msgstr "-20" + +#: ppdc/sample.c:379 +msgid "-25" +msgstr "-25" + +#: ppdc/sample.c:279 +msgid "-3" +msgstr "-3" + +#: ppdc/sample.c:378 +msgid "-30" +msgstr "-30" + +#: ppdc/sample.c:377 +msgid "-35" +msgstr "-35" + +#: ppdc/sample.c:278 +msgid "-4" +msgstr "-4" + +#: ppdc/sample.c:376 +msgid "-40" +msgstr "-40" + +#: ppdc/sample.c:375 +msgid "-45" +msgstr "-45" + +#: ppdc/sample.c:277 +msgid "-5" +msgstr "-5" + +#: ppdc/sample.c:374 +msgid "-50" +msgstr "-50" + +#: ppdc/sample.c:373 +msgid "-55" +msgstr "-55" + +#: ppdc/sample.c:276 +msgid "-6" +msgstr "-6" + +#: ppdc/sample.c:372 +msgid "-60" +msgstr "-60" + +#: ppdc/sample.c:371 +msgid "-65" +msgstr "-65" + +#: ppdc/sample.c:275 +msgid "-7" +msgstr "-7" + +#: ppdc/sample.c:370 +msgid "-70" +msgstr "-70" + +#: ppdc/sample.c:369 +msgid "-75" +msgstr "-75" + +#: ppdc/sample.c:274 +msgid "-8" +msgstr "-8" + +#: ppdc/sample.c:368 +msgid "-80" +msgstr "-80" + +#: ppdc/sample.c:367 +msgid "-85" +msgstr "-85" + +#: ppdc/sample.c:273 +msgid "-9" +msgstr "-9" + +#: ppdc/sample.c:366 +msgid "-90" +msgstr "-90" + +#: ppdc/sample.c:365 +msgid "-95" +msgstr "-95" + +#: ppdc/sample.c:282 +msgid "0" +msgstr "0" + +#: ppdc/sample.c:283 +msgid "1" +msgstr "1" + +#: ppdc/sample.c:355 +msgid "1 inch/sec." +msgstr "1 inci/det." + +#: ppdc/sample.c:144 +msgid "1.25x0.25\"" +msgstr "1,25x0,25\"" + +#: ppdc/sample.c:145 +msgid "1.25x2.25\"" +msgstr "1,25x2,25\"" + +#: ppdc/sample.c:403 +msgid "1.5 inch/sec." +msgstr "1,5 inci/det." + +#: ppdc/sample.c:146 +msgid "1.50x0.25\"" +msgstr "1,50x0,25\"" + +#: ppdc/sample.c:147 +msgid "1.50x0.50\"" +msgstr "1,50x0,50\"" + +#: ppdc/sample.c:148 +msgid "1.50x1.00\"" +msgstr "1,50x1,00\"" + +#: ppdc/sample.c:149 +msgid "1.50x2.00\"" +msgstr "1,50x2,00\"" + +#: ppdc/sample.c:292 +msgid "10" +msgstr "10" + +#: ppdc/sample.c:414 +msgid "10 inches/sec." +msgstr "10 inci/det." + +#: ppdc/sample.c:1 +msgid "10 x 11\"" +msgstr "10 x 11\"" + +#: ppdc/sample.c:2 +msgid "10 x 13\"" +msgstr "10 x 13\"" + +#: ppdc/sample.c:3 +msgid "10 x 14\"" +msgstr "10 x 14\"" + +#: ppdc/sample.c:394 +msgid "100" +msgstr "100" + +#: ppdc/sample.c:305 +msgid "100 mm/sec." +msgstr "100 mm/det." + +#: ppdc/sample.c:395 +msgid "105" +msgstr "105" + +#: ppdc/sample.c:293 +msgid "11" +msgstr "11" + +#: ppdc/sample.c:415 +msgid "11 inches/sec." +msgstr "11 inci/det." + +#: ppdc/sample.c:396 +msgid "110" +msgstr "110" + +#: ppdc/sample.c:397 +msgid "115" +msgstr "115" + +#: ppdc/sample.c:294 +msgid "12" +msgstr "12" + +#: ppdc/sample.c:416 +msgid "12 inches/sec." +msgstr "12 inci/det." + +#: ppdc/sample.c:4 +msgid "12 x 11\"" +msgstr "12 x 11\"" + +#: ppdc/sample.c:398 +msgid "120" +msgstr "120" + +#: ppdc/sample.c:306 +msgid "120 mm/sec." +msgstr "120 mm/det." + +#: ppdc/sample.c:215 +msgid "120x60dpi" +msgstr "120x60dpi" + +#: ppdc/sample.c:221 +msgid "120x72dpi" +msgstr "120x72dpi" + +#: ppdc/sample.c:295 +msgid "13" +msgstr "13" + +#: ppdc/sample.c:204 +msgid "136dpi" +msgstr "136dpi" + +#: ppdc/sample.c:296 +msgid "14" +msgstr "14" + +#: ppdc/sample.c:297 +msgid "15" +msgstr "15" + +#: ppdc/sample.c:299 +msgid "15 mm/sec." +msgstr "15 mm/det." + +#: ppdc/sample.c:5 +msgid "15 x 11\"" +msgstr "15 x 11\"" + +#: ppdc/sample.c:307 +msgid "150 mm/sec." +msgstr "150 mm/det." + +#: ppdc/sample.c:254 +msgid "150dpi" +msgstr "150dpi" + +#: ppdc/sample.c:339 +msgid "16" +msgstr "16" + +#: ppdc/sample.c:340 +msgid "17" +msgstr "17" + +#: ppdc/sample.c:341 +msgid "18" +msgstr "18" + +#: ppdc/sample.c:216 +msgid "180dpi" +msgstr "180dpi" + +#: ppdc/sample.c:342 +msgid "19" +msgstr "19" + +#: ppdc/sample.c:284 +msgid "2" +msgstr "2" + +#: ppdc/sample.c:356 +msgid "2 inches/sec." +msgstr "2 inci/det." + +#: ppdc/sample.c:242 +msgid "2-Sided Printing" +msgstr "2-Sisi Pencetakan" + +#: ppdc/sample.c:150 +msgid "2.00x0.37\"" +msgstr "2,00x0,37\"" + +#: ppdc/sample.c:151 +msgid "2.00x0.50\"" +msgstr "2,00x0,50\"" + +#: ppdc/sample.c:152 +msgid "2.00x1.00\"" +msgstr "2,00x1.00\"" + +#: ppdc/sample.c:153 +msgid "2.00x1.25\"" +msgstr "2,00x1,25\"" + +#: ppdc/sample.c:154 +msgid "2.00x2.00\"" +msgstr "2,00x2,00\"" + +#: ppdc/sample.c:155 +msgid "2.00x3.00\"" +msgstr "2,00x3,00\"" + +#: ppdc/sample.c:156 +msgid "2.00x4.00\"" +msgstr "2,00x4,00\"" + +#: ppdc/sample.c:157 +msgid "2.00x5.50\"" +msgstr "2,00x5,50\"" + +#: ppdc/sample.c:158 +msgid "2.25x0.50\"" +msgstr "2,25x0,50\"" + +#: ppdc/sample.c:159 +msgid "2.25x1.25\"" +msgstr "2,25x1,25\"" + +#: ppdc/sample.c:160 +msgid "2.25x4.00\"" +msgstr "2,25x4,00\"" + +#: ppdc/sample.c:161 +msgid "2.25x5.50\"" +msgstr "2,25x5,50\"" + +#: ppdc/sample.c:162 +msgid "2.38x5.50\"" +msgstr "2,38x5,50\"" + +#: ppdc/sample.c:404 +msgid "2.5 inches/sec." +msgstr "2,5 inci/det." + +#: ppdc/sample.c:163 +msgid "2.50x1.00\"" +msgstr "2,50x1,00\"" + +#: ppdc/sample.c:164 +msgid "2.50x2.00\"" +msgstr "2,50x2,00\"" + +#: ppdc/sample.c:165 +msgid "2.75x1.25\"" +msgstr "2,75x1,25\"" + +#: ppdc/sample.c:166 +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +#: ppdc/sample.c:343 +msgid "20" +msgstr "20" + +#: ppdc/sample.c:300 +msgid "20 mm/sec." +msgstr "20 mm/det." + +#: ppdc/sample.c:308 +msgid "200 mm/sec." +msgstr "200 mm/det." + +#: ppdc/sample.c:205 +msgid "203dpi" +msgstr "203dpi" + +#: ppdc/sample.c:344 +msgid "21" +msgstr "21" + +#: ppdc/sample.c:345 +msgid "22" +msgstr "22" + +#: ppdc/sample.c:346 +msgid "23" +msgstr "23" + +#: ppdc/sample.c:347 +msgid "24" +msgstr "24" + +#: ppdc/sample.c:213 +msgid "24-Pin Series" +msgstr "Seri 24-Pin" + +#: ppdc/sample.c:222 +msgid "240x72dpi" +msgstr "240x72dpi" + +#: ppdc/sample.c:348 +msgid "25" +msgstr "25" + +#: ppdc/sample.c:309 +msgid "250 mm/sec." +msgstr "250 mm/det." + +#: ppdc/sample.c:349 +msgid "26" +msgstr "26" + +#: ppdc/sample.c:350 +msgid "27" +msgstr "27" + +#: ppdc/sample.c:351 +msgid "28" +msgstr "28" + +#: ppdc/sample.c:352 +msgid "29" +msgstr "29" + +#: ppdc/sample.c:285 +msgid "3" +msgstr "3" + +#: ppdc/sample.c:357 +msgid "3 inches/sec." +msgstr "3 inci/det." + +#: ppdc/sample.c:167 +msgid "3.00x1.00\"" +msgstr "3,00x1,00\"" + +#: ppdc/sample.c:168 +msgid "3.00x1.25\"" +msgstr "3,00x1,25\"" + +#: ppdc/sample.c:169 +msgid "3.00x2.00\"" +msgstr "3,00x2,00\"" + +#: ppdc/sample.c:170 +msgid "3.00x3.00\"" +msgstr "3,00x3,00\"" + +#: ppdc/sample.c:171 +msgid "3.00x5.00\"" +msgstr "3,00x5,00\"" + +#: ppdc/sample.c:172 +msgid "3.25x2.00\"" +msgstr "3,25x2,00\"" + +#: ppdc/sample.c:173 +msgid "3.25x5.00\"" +msgstr "3,25x5,00\"" + +#: ppdc/sample.c:174 +msgid "3.25x5.50\"" +msgstr "3,25x5,50\"" + +#: ppdc/sample.c:175 +msgid "3.25x5.83\"" +msgstr "3,25x5,83\"" + +#: ppdc/sample.c:176 +msgid "3.25x7.83\"" +msgstr "3,25x7,83\"" + +#: ppdc/sample.c:134 +msgid "3.5\" Disk" +msgstr "Diska 3,5\"" + +#: ppdc/sample.c:143 +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Diska 3.5\" - 2 1/8 x 2 3/4\"" + +#: ppdc/sample.c:177 +msgid "3.50x1.00\"" +msgstr "3,50x1,00\"" + +#: ppdc/sample.c:353 +msgid "30" +msgstr "30" + +#: ppdc/sample.c:301 +msgid "30 mm/sec." +msgstr "30 mm/det." + +#: ppdc/sample.c:310 +msgid "300 mm/sec." +msgstr "300 mm/det." + +#: ppdc/sample.c:206 +msgid "300dpi" +msgstr "300dpi" + +#: ppdc/sample.c:381 +msgid "35" +msgstr "35" + +#: ppdc/sample.c:218 +msgid "360dpi" +msgstr "360dpi" + +#: ppdc/sample.c:217 +msgid "360x180dpi" +msgstr "360x180dpi" + +#: ppdc/sample.c:286 +msgid "4" +msgstr "4" + +#: ppdc/sample.c:358 +msgid "4 inches/sec." +msgstr "4 inci/det." + +#: ppdc/sample.c:178 +msgid "4.00x1.00\"" +msgstr "4,00x1,00\"" + +#: ppdc/sample.c:186 +msgid "4.00x13.00\"" +msgstr "4,00x13,00\"" + +#: ppdc/sample.c:179 +msgid "4.00x2.00\"" +msgstr "4,00x2,00\"" + +#: ppdc/sample.c:180 +msgid "4.00x2.50\"" +msgstr "4,00x2,50\"" + +#: ppdc/sample.c:181 +msgid "4.00x3.00\"" +msgstr "4,00x3,00\"" + +#: ppdc/sample.c:182 +msgid "4.00x4.00\"" +msgstr "4,00x4,00\"" + +#: ppdc/sample.c:183 +msgid "4.00x5.00\"" +msgstr "4,00x5,00\"" + +#: ppdc/sample.c:184 +msgid "4.00x6.00\"" +msgstr "4,00x6,00\"" + +#: ppdc/sample.c:185 +msgid "4.00x6.50\"" +msgstr "4,00x6,50\"" + +#: ppdc/sample.c:382 +msgid "40" +msgstr "40" + +#: ppdc/sample.c:302 +msgid "40 mm/sec." +msgstr "40 mm/det." + +#: ppdc/sample.c:383 +msgid "45" +msgstr "45" + +#: ppdc/sample.c:287 +msgid "5" +msgstr "5" + +#: ppdc/sample.c:408 +msgid "5 inches/sec." +msgstr "5 inci/det." + +#: ppdc/sample.c:384 +msgid "50" +msgstr "50" + +#: ppdc/sample.c:385 +msgid "55" +msgstr "55" + +#: ppdc/sample.c:288 +msgid "6" +msgstr "6" + +#: ppdc/sample.c:409 +msgid "6 inches/sec." +msgstr "6 inci/det." + +#: ppdc/sample.c:187 +msgid "6.00x1.00\"" +msgstr "6,00x1,00\"" + +#: ppdc/sample.c:188 +msgid "6.00x2.00\"" +msgstr "6,00x2,00\"" + +#: ppdc/sample.c:189 +msgid "6.00x3.00\"" +msgstr "6,00x3,00\"" + +#: ppdc/sample.c:190 +msgid "6.00x4.00\"" +msgstr "6,00x4,00\"" + +#: ppdc/sample.c:191 +msgid "6.00x5.00\"" +msgstr "6,00x5,00\"" + +#: ppdc/sample.c:192 +msgid "6.00x6.00\"" +msgstr "6,00x6,00\"" + +#: ppdc/sample.c:193 +msgid "6.00x6.50\"" +msgstr "6,00x6,50\"" + +#: ppdc/sample.c:386 +msgid "60" +msgstr "60" + +#: ppdc/sample.c:303 +msgid "60 mm/sec." +msgstr "60 mm/det." + +#: ppdc/sample.c:233 +msgid "600dpi" +msgstr "600dpi" + +#: ppdc/sample.c:214 +msgid "60dpi" +msgstr "60dpi" + +#: ppdc/sample.c:220 +msgid "60x720dpi" +msgstr "60x720dpi" + +#: ppdc/sample.c:387 +msgid "65" +msgstr "65" + +#: ppdc/sample.c:289 +msgid "7" +msgstr "7" + +#: ppdc/sample.c:411 +msgid "7 inches/sec." +msgstr "7 inci/det." + +#: ppdc/sample.c:6 +msgid "7 x 9\"" +msgstr "7 x 9\"" + +#: ppdc/sample.c:388 +msgid "70" +msgstr "70" + +#: ppdc/sample.c:224 +msgid "720dpi" +msgstr "720dpi" + +#: ppdc/sample.c:389 +msgid "75" +msgstr "75" + +#: ppdc/sample.c:290 +msgid "8" +msgstr "8" + +#: ppdc/sample.c:412 +msgid "8 inches/sec." +msgstr "8 inci/det." + +#: ppdc/sample.c:7 +msgid "8 x 10\"" +msgstr "8 x 10\"" + +#: ppdc/sample.c:194 +msgid "8.00x1.00\"" +msgstr "8,00x1,00\"" + +#: ppdc/sample.c:195 +msgid "8.00x2.00\"" +msgstr "8,00x2,00\"" + +#: ppdc/sample.c:196 +msgid "8.00x3.00\"" +msgstr "8,00x3,00\"" + +#: ppdc/sample.c:197 +msgid "8.00x4.00\"" +msgstr "8,00x4,00\"" + +#: ppdc/sample.c:198 +msgid "8.00x5.00\"" +msgstr "8,00x5,00\"" + +#: ppdc/sample.c:199 +msgid "8.00x6.00\"" +msgstr "8,00x6,00\"" + +#: ppdc/sample.c:200 +msgid "8.00x6.50\"" +msgstr "8,00x6,50\"" + +#: ppdc/sample.c:390 +msgid "80" +msgstr "80" + +#: ppdc/sample.c:304 +msgid "80 mm/sec." +msgstr "80 mm/det." + +#: ppdc/sample.c:391 +msgid "85" +msgstr "85" + +#: ppdc/sample.c:291 +msgid "9" +msgstr "9" + +#: ppdc/sample.c:413 +msgid "9 inches/sec." +msgstr "9 inci/det." + +#: ppdc/sample.c:8 +msgid "9 x 11\"" +msgstr "9 x 11\"" + +#: ppdc/sample.c:9 +msgid "9 x 12\"" +msgstr "9 x 12\"" + +#: ppdc/sample.c:219 +msgid "9-Pin Series" +msgstr "Seri 9-Pin" + +#: ppdc/sample.c:392 +msgid "90" +msgstr "90" + +#: ppdc/sample.c:393 +msgid "95" +msgstr "95" + +#: berkeley/lpc.c:218 +msgid "?Invalid help command unknown\n" +msgstr "" + +#: cgi-bin/admin.c:2343 +msgid "A Samba password is required to export printer drivers!" +msgstr "Diperlukan sandi Samba untuk mengekspor penggerak pencetak!" + +#: cgi-bin/admin.c:2339 +msgid "A Samba username is required to export printer drivers!" +msgstr "Diperlukan nama pengguna Samba untuk mengekspor penggerak pencetak!" + +#: scheduler/ipp.c:2390 +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Kelas bernama \"%s\" sudah ada!" + +#: scheduler/ipp.c:1013 +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Pencetak bernama \"%s\" sudah ada!" + +#: ppdc/sample.c:10 +msgid "A0" +msgstr "A0" + +#: ppdc/sample.c:11 +msgid "A1" +msgstr "A1" + +#: ppdc/sample.c:24 +msgid "A10" +msgstr "A10" + +#: ppdc/sample.c:12 +msgid "A2" +msgstr "A2" + +#: ppdc/sample.c:13 +msgid "A3" +msgstr "A3" + +#: ppdc/sample.c:14 +msgid "A3 (Oversize)" +msgstr "A3 (Besar)" + +#: ppdc/sample.c:15 +msgid "A4" +msgstr "A4" + +#: ppdc/sample.c:16 +msgid "A4 (Oversize)" +msgstr "A4 (Besar)" + +#: ppdc/sample.c:17 +msgid "A4 (Small)" +msgstr "A4 (Kecil)" + +#: ppdc/sample.c:18 +msgid "A5" +msgstr "A5" + +#: ppdc/sample.c:19 +msgid "A5 (Oversize)" +msgstr "A5 (Besar)" + +#: ppdc/sample.c:20 +msgid "A6" +msgstr "A6" + +#: ppdc/sample.c:21 +msgid "A7" +msgstr "A7" + +#: ppdc/sample.c:22 +msgid "A8" +msgstr "A8" + +#: ppdc/sample.c:23 +msgid "A9" +msgstr "A9" + +#: ppdc/sample.c:25 +msgid "ANSI A" +msgstr "ANSI A" + +#: ppdc/sample.c:26 +msgid "ANSI B" +msgstr "ANSI B" + +#: ppdc/sample.c:27 +msgid "ANSI C" +msgstr "ANSI C" + +#: ppdc/sample.c:28 +msgid "ANSI D" +msgstr "ANSI D" + +#: ppdc/sample.c:29 +msgid "ANSI E" +msgstr "ANSI E" + +#: ppdc/sample.c:30 +msgid "ARCH A" +msgstr "ARCH A" + +#: ppdc/sample.c:31 +msgid "ARCH B" +msgstr "ARCH B" + +#: ppdc/sample.c:32 +msgid "ARCH C" +msgstr "ARCH C" + +#: ppdc/sample.c:33 +msgid "ARCH D" +msgstr "ARCH D" + +#: ppdc/sample.c:34 +msgid "ARCH E" +msgstr "ARCH E" + +#: cgi-bin/classes.c:154 cgi-bin/printers.c:157 +msgid "Accept Jobs" +msgstr "Terima Tugas" + +#: cups/http-support.c:1196 +msgid "Accepted" +msgstr "Diterima" + +#: cgi-bin/admin.c:480 +msgid "Add Class" +msgstr "Tambah Kelas" + +#: cgi-bin/admin.c:778 +msgid "Add Printer" +msgstr "Tambah Pencetak" + +#: cgi-bin/admin.c:355 cgi-bin/admin.c:388 cgi-bin/admin.c:436 +#: cgi-bin/admin.c:446 +msgid "Add RSS Subscription" +msgstr "Tambah Subskripsi RSS" + +#: ppdc/sample.c:126 +msgid "Address" +msgstr "Alamat" + +#: ppdc/sample.c:135 +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Alamat - 1 1/8 x 3 1/2\"" + +#: cgi-bin/admin.c:187 cgi-bin/admin.c:218 cgi-bin/admin.c:2761 +msgid "Administration" +msgstr "Administrasi" + +#: ppdc/sample.c:400 +msgid "Always" +msgstr "Selalu" + +#: backend/socket.c:126 +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +#: ppdc/sample.c:421 +msgid "Applicator" +msgstr "Aplikator" + +#: scheduler/ipp.c:1135 +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "" + +#: scheduler/ipp.c:341 +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Kelompok atribut di luar jangkauan (%x < %x)!" + +#: ppdc/sample.c:35 +msgid "B0" +msgstr "B0" + +#: ppdc/sample.c:37 +msgid "B1" +msgstr "B1" + +#: ppdc/sample.c:36 +msgid "B10" +msgstr "B10" + +#: ppdc/sample.c:38 +msgid "B2" +msgstr "B2" + +#: ppdc/sample.c:39 +msgid "B3" +msgstr "B3" + +#: ppdc/sample.c:40 +msgid "B4" +msgstr "B4" + +#: ppdc/sample.c:41 +msgid "B5" +msgstr "B5" + +#: ppdc/sample.c:42 +msgid "B6" +msgstr "B6" + +#: ppdc/sample.c:43 +msgid "B7" +msgstr "B7" + +#: ppdc/sample.c:44 +msgid "B8" +msgstr "B8" + +#: ppdc/sample.c:45 +msgid "B9" +msgstr "B9" + +#: cups/dest.c:317 +msgid "Bad NULL dests pointer" +msgstr "" + +#: cups/ppd.c:342 +msgid "Bad OpenGroup" +msgstr "OpenGroup Jelek" + +#: cups/ppd.c:344 +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI Jelek" + +#: cups/ppd.c:346 +msgid "Bad OrderDependency" +msgstr "OrderDependency Jelek" + +#: cups/http-support.c:1211 +msgid "Bad Request" +msgstr "Permintaan Jelek" + +#: cups/snmp.c:1003 +msgid "Bad SNMP version number" +msgstr "Nomor versi SNMP jelek" + +#: cups/ppd.c:347 +msgid "Bad UIConstraints" +msgstr "UIConstraints Jelek" + +#: scheduler/ipp.c:1433 +#, c-format +msgid "Bad copies value %d." +msgstr "Nilai rangkap %d jelek." + +#: cups/ppd.c:355 +msgid "Bad custom parameter" +msgstr "Parameter ubahan jelek" + +#: cups/http-support.c:1339 +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "URI perangkat \"%s\" jelek!\n" + +#: scheduler/ipp.c:2508 +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "device-uri \"%s\" jelek!" + +#: scheduler/ipp.c:2548 +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Skema device-uri \"%s\" jelek!" + +#: scheduler/ipp.c:9835 scheduler/ipp.c:11314 +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "document-format \"%s\" jelek!" + +#: cups/util.c:930 +msgid "Bad filename buffer!" +msgstr "Nama berkas penyangga jelek!" + +#: ppdc/ppdc-import.cxx:265 +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Atribut huruf jelek: %s\n" + +#: scheduler/ipp.c:10431 +msgid "Bad job-priority value!" +msgstr "Nilai job-priority jelek!" + +#: scheduler/ipp.c:1463 +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Nilai job-sheets \"%s\" jelek!" + +#: scheduler/ipp.c:1447 +msgid "Bad job-sheets value type!" +msgstr "Jenis nilai job-sheets jelek!" + +#: scheduler/ipp.c:10461 +msgid "Bad job-state value!" +msgstr "Nilai job-state jelek!" + +#: scheduler/ipp.c:3663 scheduler/ipp.c:4022 scheduler/ipp.c:6650 +#: scheduler/ipp.c:6792 scheduler/ipp.c:8067 scheduler/ipp.c:8322 +#: scheduler/ipp.c:9166 scheduler/ipp.c:9392 scheduler/ipp.c:9747 +#: scheduler/ipp.c:10323 +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Atribut job-uri \"%s\" jelek!" + +#: scheduler/ipp.c:2129 scheduler/ipp.c:6197 +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "notify-pull-method \"%s\" jelek!" + +#: scheduler/ipp.c:2093 scheduler/ipp.c:6161 +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "URI notify-recipient-uri \"%s\" jelek!" + +#: scheduler/ipp.c:1479 +#, c-format +msgid "Bad number-up value %d." +msgstr "Nilai number-up %d jelek." + +#: cups/adminutil.c:303 +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Opsi + yang dipilih pada baris %d jelek!" + +#: scheduler/ipp.c:1496 +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Nilai page-ranges %d-%d jelek." + +#: scheduler/ipp.c:2592 +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "port-monitor \"%s\" jelek!" + +#: scheduler/ipp.c:2640 +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Nilai printer-state %d jelek!" + +#: scheduler/ipp.c:309 +#, c-format +msgid "Bad request ID %d!" +msgstr "ID permintaan %d jelek!" + +#: scheduler/ipp.c:294 +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "" + +#: cgi-bin/admin.c:1385 +msgid "Bad subscription ID!" +msgstr "ID subskripsi jelek!" + +#: cgi-bin/admin.c:3301 cgi-bin/admin.c:3524 +msgid "Banners" +msgstr "Pataka" + +#: filter/bannertops.c:666 +msgid "Billing Information: " +msgstr "Informasi Tagihan: " + +#: ppdc/sample.c:258 +msgid "Bond Paper" +msgstr "Kertas Surat" + +#: ppdc/sample.c:56 +msgid "C0 Envelope" +msgstr "C0 Amplop" + +#: ppdc/sample.c:57 +msgid "C1 Envelope" +msgstr "C1 Amplop" + +#: ppdc/sample.c:58 +msgid "C2 Envelope" +msgstr "C2 Amplop" + +#: ppdc/sample.c:59 +msgid "C3 Envelope" +msgstr "C3 Amplop" + +#: ppdc/sample.c:46 +msgid "C4" +msgstr "C4" + +#: ppdc/sample.c:60 +msgid "C4 Envelope" +msgstr "C4 Amplop" + +#: ppdc/sample.c:47 +msgid "C5" +msgstr "C5" + +#: ppdc/sample.c:61 +msgid "C5 Envelope" +msgstr "C5 Amplop" + +#: ppdc/sample.c:48 +msgid "C6" +msgstr "C6" + +#: ppdc/sample.c:63 +msgid "C6 Envelope" +msgstr "C6 Amplop" + +#: ppdc/sample.c:62 +msgid "C65 Envelope" +msgstr "C65 Amplop" + +#: ppdc/sample.c:64 +msgid "C7 Envelope" +msgstr "C7 Amplop" + +#: ppdc/sample.c:226 +msgid "CMYK" +msgstr "CMYK" + +#: ppdc/sample.c:334 +msgid "CPCL Label Printer" +msgstr "" + +#: cgi-bin/admin.c:1386 cgi-bin/admin.c:1425 cgi-bin/admin.c:1435 +msgid "Cancel RSS Subscription" +msgstr "Batal Subskripsi RSS" + +#: cgi-bin/admin.c:1608 cgi-bin/admin.c:1772 cgi-bin/admin.c:1784 +#: cgi-bin/admin.c:1795 +msgid "Change Settings" +msgstr "Ubah Pengaturan" + +#: scheduler/ipp.c:2141 scheduler/ipp.c:6209 +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Set karakter \"%s\" tidak didukung!" + +#: ppdc/sample.c:65 +msgid "Chou3 Envelope" +msgstr "Chou3 Amplop" + +#: ppdc/sample.c:66 +msgid "Chou4 Envelope" +msgstr "Chou4 Amplop" + +#: cgi-bin/classes.c:180 cgi-bin/classes.c:307 +msgid "Classes" +msgstr "Kelas" + +#: cgi-bin/printers.c:167 +msgid "Clean Print Heads" +msgstr "Bersihkan Kepala Pencetak" + +#: ppdc/sample.c:253 +msgid "Color" +msgstr "Warna" + +#: ppdc/sample.c:225 +msgid "Color Mode" +msgstr "Modus Warna" + +#: berkeley/lpc.c:209 +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Perintah bisa saja singkat. Perintahnya:\n" +"\n" +"exit help quit status ?\n" + +#: cups/snmp.c:1007 +msgid "Community name uses indefinite length" +msgstr "Nama komunitas memiliki panjang tak terdefinisi" + +#: cups/http-support.c:1184 +msgid "Continue" +msgstr "Lanjut" + +#: ppdc/sample.c:336 +msgid "Continuous" +msgstr "Terus-menerus" + +#: scheduler/ipp.c:8616 scheduler/ipp.c:8632 scheduler/ipp.c:9851 +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Tidak akan memindai jenis \"%s\"!" + +#: cups/localize.c:319 +msgid "Cover open." +msgstr "Penutup terbuka." + +#: cups/http-support.c:1193 +msgid "Created" +msgstr "Dibuat" + +#: filter/bannertops.c:854 +msgid "Created On: " +msgstr "Dibuat Pada: " + +#: cups/ppd.c:1072 cups/ppd.c:1112 cups/ppd.c:1326 cups/ppd.c:1429 +msgid "Custom" +msgstr "Ubahan" + +#: ppdc/sample.c:330 +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +#: ppdc/sample.c:328 +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +#: ppdc/sample.c:314 +msgid "Cut" +msgstr "Potong" + +#: ppdc/sample.c:422 +msgid "Cutter" +msgstr "Pemotong" + +#: ppdc/sample.c:49 +msgid "DL" +msgstr "DL" + +#: ppdc/sample.c:67 +msgid "DL Envelope" +msgstr "DL Amplop" + +#: ppdc/sample.c:211 +msgid "Dark" +msgstr "Gelap" + +#: ppdc/sample.c:207 +msgid "Darkness" +msgstr "Gelap" + +#: cgi-bin/admin.c:2068 cgi-bin/admin.c:2079 cgi-bin/admin.c:2124 +msgid "Delete Class" +msgstr "Hapus Kelas" + +#: cgi-bin/admin.c:2153 cgi-bin/admin.c:2164 cgi-bin/admin.c:2209 +msgid "Delete Printer" +msgstr "Hapus Pencetak" + +#: filter/bannertops.c:735 +msgid "Description: " +msgstr "Deskripsi: " + +#: ppdc/sample.c:252 +msgid "DeskJet Series" +msgstr "Seri Deskjet" + +#: scheduler/ipp.c:1399 +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Tujuan \"%s\" bukanlah tugas yang diterima." + +#: cups/localize.c:353 +msgid "Developer almost empty." +msgstr "Developer hampir kosong." + +#: cups/localize.c:355 +msgid "Developer empty!" +msgstr "Developer kosong!" + +#: systemv/lpinfo.c:305 +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Perangkat: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +#: ppdc/sample.c:407 +msgid "Direct Thermal Media" +msgstr "Media Termal Langsung" + +#: ppdc/sample.c:316 +msgid "Disabled" +msgstr "Dinonaktifkan" + +#: scheduler/ipp.c:6697 +#, c-format +msgid "Document %d not found in job %d." +msgstr "Dokumen %d tidak ditemukan di tugas %d." + +#: cups/localize.c:323 +msgid "Door open." +msgstr "Pintu terbuka." + +#: ppdc/sample.c:50 +msgid "Double Postcard" +msgstr "Kartu Pos Ganda" + +#: filter/bannertops.c:820 +msgid "Driver Name: " +msgstr "Nama Penggerak: " + +#: filter/bannertops.c:831 +msgid "Driver Version: " +msgstr "Versi Penggerak: " + +#: ppdc/sample.c:247 +msgid "Duplexer" +msgstr "Pendupleks" + +#: ppdc/sample.c:201 +msgid "Dymo" +msgstr "Dymo" + +#: filter/pstops.c:446 +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Tidak bisa mengalokasikan memori untuk halaman info: %s\n" + +#: filter/pstops.c:438 +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Tidak bisa mengalokasikan memori untuk larik halaman: %s\n" + +#: ppdc/sample.c:402 +msgid "EPL1 Label Printer" +msgstr "EPL1 Pencetak Label" + +#: ppdc/sample.c:405 +msgid "EPL2 Label Printer" +msgstr "EPL2 Pencetak Label" + +#: driver/rastertoescpx.c:1776 driver/rastertopclx.c:1801 +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#: filter/pstops.c:707 +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "" + +#: filter/pstops.c:2220 +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "" + +#: filter/pstops.c:1286 filter/pstops.c:1292 +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "" + +#: filter/pstops.c:1363 +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "" + +#: backend/scsi-irix.c:100 backend/scsi-linux.c:114 +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Berkas perangkat SCSI \"%s\" jelek!\n" + +#: filter/pstext.c:276 filter/texttops.c:284 filter/texttops.c:295 +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Berkas set karakter %s jelek\n" + +#: filter/texttops.c:453 +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Jenis set karakter %s jelek\n" + +#: filter/textcommon.c:613 +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Nilai kolom %d jelek!\n" + +#: filter/textcommon.c:624 +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Nilai cpi %f jelek!\n" + +#: filter/pstext.c:320 filter/pstext.c:357 filter/texttops.c:348 +#: filter/texttops.c:384 +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Baris deskripsi huruf: %s jelek\n" + +#: filter/textcommon.c:635 +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Nilai lpi %f jelek!\n" + +#: filter/imagetoraster.c:458 +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Pengaturan halaman jelek!\n" + +#: filter/pstext.c:334 filter/texttops.c:361 +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Arah teks %s jelek\n" + +#: filter/pstext.c:371 filter/texttops.c:397 +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Lebar teks %s jelek\n" + +#: backend/ipp.c:749 +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Pencetak yang dituju tidak ada!\n" + +#: filter/pstops.c:696 +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "" + +#: filter/pstops.c:648 +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "" + +#: backend/ipp.c:468 filter/pstops.c:303 +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Mencetak berkas kosong!\n" + +#: backend/pap.c:838 +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Kesalahan %d mengirim permintaan PAPSendData: %s\n" + +#: ppdc/ppdc-catalog.cxx:338 ppdc/ppdc-catalog.cxx:350 +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "" + +#: backend/usb-darwin.c:377 backend/usb-darwin.c:435 backend/usb-darwin.c:500 +#: backend/usb-darwin.c:518 +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Kesalahan fatal USB!\n" + +#: filter/hpgl-input.c:139 +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: Ketidaksahan HP-GL/2 komentar terlihat, tak bisa mencetak berkas!\n" + +#: filter/pstops.c:1771 +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "" + +#: filter/pstops.c:1842 +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "" + +#: filter/bannertops.c:222 +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Kehilangan nilai pada baris %d dari berkas pataka (banner)!\n" + +#: ppdc/ppdc-catalog.cxx:415 +#, c-format +msgid "ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "ERROR: Memerlukan baris msgid sebelum string translasi pada baris %d dari %s!\n" + +#: filter/pstops.c:759 +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "" + +#: filter/pstops.c:762 +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "" + +#: backend/usb.c:200 +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Tak ditemukan URI perangkat pada argv[0] atau dalam variabel " +"lingkungan DEVICE_URI!\n" + +#: filter/pstext.c:433 +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Tidak ada huruf pada berkas set karakter %s\n" + +#: driver/rastertoescpx.c:1906 driver/rastertopclx.c:1931 +#: filter/rastertoepson.c:1129 filter/rastertohp.c:857 +#: filter/rastertolabel.c:1283 +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Tidak ketemu halaman!\n" + +#: backend/runloop.c:348 +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Kehabisan kertas!\n" + +#: backend/ipp.c:1754 +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: Variabel lingkungan PRINTER belum ditentukan!\n" + +#: backend/ipp.c:1066 +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Berkas cetak tidak diterima (%s)!\n" + +#: backend/pap.c:521 +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Pencetak tidak merespon\n" + +#: backend/ipp.c:581 backend/ipp.c:716 backend/lpd.c:848 backend/socket.c:310 +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Pencetak tidak merespon!\n" + +#: backend/pap.c:858 +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Pencetak mengirim EOF yang tak diharapkan\n" + +#: backend/lpd.c:1052 backend/lpd.c:1199 +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Host jarak jauh tidak menerima berkas kontrol (%d)\n" + +#: backend/lpd.c:1147 +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Host jarak jauh tidak menerima data berkas (%d)\n" + +#: backend/pap.c:1694 +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: Kehabisan waktu saat mengirim data ke pencetak\n" + +#: backend/ipp.c:1145 +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Tidak bisa menambah berkas %d untuk tugas: %s\n" + +#: backend/ipp.c:1383 +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Tidak bisa membatalkan tugas %d: %s\n" + +#: filter/pdftops.c:136 +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Tidak bisa menyalin berkas PPD" + +#: filter/pdftops.c:412 +msgid "ERROR: Unable to create pipe" +msgstr "ERROR: Tidak bisa membuat pipa" + +#: backend/lpd.c:772 +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Tidak bisa membuat soket" + +#: backend/ipp.c:1476 +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: Tidak bisa membuat berkas cetak berkompresi temporer: %s\n" + +#: backend/ipp.c:431 backend/ipp.c:1776 backend/lpd.c:446 filter/pstops.c:2719 +#: scheduler/cupsfilter.c:1121 systemv/lpadmin.c:1453 systemv/lpadmin.c:1842 +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Tidak bisa membuat berkas temporer" + +#: backend/ipp.c:1831 +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Tidak bisa mengeksekusi pictwpstops: %s\n" + +#: filter/pdftops.c:433 filter/pdftops.c:447 +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Tidak bisa mengeksekusi program gs" + +#: filter/pdftops.c:430 filter/pdftops.c:445 +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Tidak bisa mengeksekusi program pdftops" + +#: filter/pdftops.c:467 filter/pdftops.c:477 +msgid "ERROR: Unable to execute pstops program" +msgstr "ERROR: Tidak bisa mengeksekusi program pstops" + +#: backend/ipp.c:1844 +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "" + +#: backend/pap.c:712 +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Tidak bisa memperoleh permintaan PAP" + +#: backend/pap.c:701 +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Tidak bisa memperoleh respon PAP" + +#: backend/ipp.c:1761 +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: Tidak bisa memperoleh berkas PPD untuk pencetak \"%s\" - %s.\n" + +#: backend/pap.c:302 +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Tidak bisa memperoleh zona baku AppleTalk" + +#: backend/ipp.c:1232 +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Tidak bisa memperoleh atribut tugas %d (%s)!\n" + +#: backend/ipp.c:759 +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Tidak bisa memperoleh status pencetak (%s)!\n" + +#: backend/ipp.c:422 backend/ipp.c:599 backend/lpd.c:437 backend/lpd.c:705 +#: backend/socket.c:268 +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Tidak bisa menentukan lokasi pencetak '%s'!\n" + +#: backend/pap.c:688 +msgid "ERROR: Unable to look for PAP response" +msgstr "" + +#: backend/pap.c:322 +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "" + +#: backend/pap.c:451 +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Tidak bisa membuat alamat AppleTalk" + +#: filter/pstext.c:247 filter/texttops.c:248 +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Tidak bisa membuka \"%s\" - %s\n" + +#: filter/pstext.c:264 filter/texttops.c:268 +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Tidak bisa membuka %s: %s\n" + +#: driver/rastertoescpx.c:1791 driver/rastertopclx.c:1816 +msgid "ERROR: Unable to open PPD file!\n" +msgstr "ERROR: Tidak bisa membuka berkas PPD!\n" + +#: filter/bannertops.c:184 +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "" + +#: backend/parallel.c:249 backend/scsi-irix.c:140 backend/scsi-linux.c:154 +#: backend/serial.c:262 backend/usb-unix.c:146 +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Tidak bisa membuka berkas perangkat \"%s\": %s\n" + +#: filter/pstops.c:291 +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Tidak bisa membuka berkas \"%s\" - %s\n" + +#: filter/gziptoany.c:74 +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Tidak bisa membuka berkas \"%s\": %s\n" + +#: filter/imagetops.c:313 filter/imagetoraster.c:635 +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Tidak bisa membuka berkas gambar untuk mencetak!\n" + +#: backend/ipp.c:1492 backend/pap.c:249 backend/parallel.c:151 +#: backend/scsi.c:181 backend/serial.c:189 backend/socket.c:156 +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Tidak bisa membuka berkas cetak \"%s\": %s\n" + +#: backend/usb.c:237 +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Tidak bisa membuka berkas cetak %s - %s\n" + +#: backend/lpd.c:487 +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Tidak bisa membuka berkas cetak %s: %s\n" + +#: driver/rastertoescpx.c:1806 driver/rastertopclx.c:1831 +#: filter/rastertoepson.c:1001 filter/rastertohp.c:726 +#: filter/rastertolabel.c:1148 +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#: backend/ipp.c:1484 +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: Tidak bisa membuka berkas cetak temporer berkompresi: %s\n" + +#: filter/texttops.c:200 +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "" + +#: filter/texttops.c:179 +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "" + +#: backend/serial.c:615 +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Tidak bisa membaca data yang hendak dicetak" + +#: backend/usb-darwin.c:602 backend/usb-darwin.c:644 +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Tidak bisa membaca data yang hendak dicetak!\n" + +#: backend/lpd.c:789 +msgid "ERROR: Unable to reserve port" +msgstr "" + +#: filter/pstops.c:563 +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Tidak bisa mencari letak %ld dalam berkas - %s\n" + +#: filter/pstops.c:561 +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Tidak bisa mencari letak %lld dalam berkas - %s\n" + +#: backend/lpd.c:603 +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Tidak bisa mengirim perintah LPD" + +#: backend/pap.c:571 +msgid "ERROR: Unable to send PAP tickle request" +msgstr "" + +#: backend/pap.c:580 +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "" + +#: backend/scsi-irix.c:219 backend/scsi-linux.c:237 +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Tidak bisa mengirim data yang hendak dicetak (%d)\n" + +#: backend/usb-darwin.c:720 +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Tidak bisa mengirim data yang hendak dicetak!\n" + +#: backend/lpd.c:1103 +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Tidak bisa mengirim data ke pencetak" + +#: backend/lpd.c:1117 +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "" + +#: backend/ipp.c:1857 +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Tidak bisa menunggu pictwpstops: %s\n" + +#: backend/ipp.c:1503 +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Tidak bisa menulis %d bita ke \"%s\": %s\n" + +#: backend/usb-libusb.c:169 backend/usb-libusb.c:765 +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Tidak bisa menulis %d bita ke pencetak!\n" + +#: backend/lpd.c:1033 backend/lpd.c:1180 +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Tidak bisa menulis berkas kontrol" + +#: backend/serial.c:691 +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Tidak bisa menulis data yang hendak dicetak" + +#: backend/runloop.c:122 backend/runloop.c:363 +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Tidak bisa menulis data yang hendak dicetak: %s\n" + +#: filter/imagetoraster.c:1197 filter/imagetoraster.c:1293 +#: filter/imagetoraster.c:1333 +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "" + +#: backend/ipp.c:443 backend/lpd.c:456 +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Tidak bisa menulis di berkas temporer" + +#: filter/gziptoany.c:96 +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" + +#: ppdc/ppdc-catalog.cxx:432 +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Teks tak diharapkan pada baris %d dari %s!\n" + +#: backend/ipp.c:346 +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Nilai opsi enkripsi \"%s\" tak dikenal!\n" + +#: backend/lpd.c:354 +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Urutan berkas \"%s\" tak dikenal\n" + +#: backend/lpd.c:326 +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Format karakter \"%c\" tak dikenal\n" + +#: ppdc/ppdc-catalog.cxx:460 +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Format katalog pesan \"%s\" tak dikenal!\n" + +#: backend/ipp.c:392 +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Opsi \"%s\" dengan nilai \"%s\" tak dikenal!\n" + +#: backend/lpd.c:340 +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Modus cetak \"%s\" tak dikenal\n" + +#: backend/ipp.c:363 +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Nilai opsi versi \"%s\" tak dikenal!\n" + +#: filter/pstops.c:2418 +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Nilai kecerahan %s tak didukung, gunakanlah brightness=100!\n" + +#: filter/pstops.c:2487 +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Nilai gama %s tak didukung, gunakanlah gamma=1000!\n" + +#: filter/pstops.c:2541 +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Nilai number-up %d tak didukung, gunakanlah number-up=1!\n" + +#: filter/pstops.c:2574 +#, c-format +msgid "ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Nilai number-up-layout %s tak didukung, gunakanlah number-up-" +"layout=lrtb!\n" + +#: filter/pstops.c:2624 +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: Nilai page-border %s tak didukung, gunakanlah page-border=none!\n" + +#: filter/pstops.c:2090 +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: Kelebihan doc_printf (%d bita) terdeteksi, dibatalkan!\n" + +#: backend/ipp.c:1876 +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops tertutup pada sinyal %d!\n" + +#: backend/ipp.c:1873 +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops tertutup dengan status %d!\n" + +#: backend/ipp.c:609 backend/lpd.c:877 backend/socket.c:333 +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: pemulihan: Tidak bisa menghubungi pencetak; akan mencoba ulang dalam 30 " +"detik...\n" + +#: backend/pap.c:629 +msgid "ERROR: select() failed" +msgstr "ERROR: select() gagal" + +#: backend/lpd.c:940 +msgid "ERROR: unable to stat print file" +msgstr "ERROR: tak dapat memulai berkas yang hendak dicetak" + +#: cgi-bin/admin.c:1823 cgi-bin/admin.c:1835 cgi-bin/admin.c:1889 +#: cgi-bin/admin.c:1896 cgi-bin/admin.c:1931 cgi-bin/admin.c:1944 +#: cgi-bin/admin.c:1968 cgi-bin/admin.c:2041 +msgid "Edit Configuration File" +msgstr "Sunting Berkas Konfigurasi" + +#: cups/adminutil.c:348 +msgid "Empty PPD file!" +msgstr "Berkas PPD kosong!" + +#: cgi-bin/admin.c:3545 +msgid "Ending Banner" +msgstr "Akhir Pataka" + +#: systemv/lppasswd.c:205 +msgid "Enter old password:" +msgstr "Masukkan sandi lama:" + +#: systemv/lppasswd.c:234 +msgid "Enter password again:" +msgstr "Masukkan lagi sandinya:" + +#: systemv/lppasswd.c:223 +msgid "Enter password:" +msgstr "Masukkan sandi:" + +#: scheduler/client.c:2392 +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Masukkan nama pengguna dan sandi Anda atau nama pengguna dan sandi root " +"untuk mengakses halaman ini. Apabila Anda menggunakan otentikasi Kerberos, " +"pastikan bahwa Anda memiliki tiket Kerberos yang sah." + +#: ppdc/sample.c:241 +msgid "Envelope Feed" +msgstr "Amplop Feed" + +#: ppdc/sample.c:212 +msgid "Epson" +msgstr "Epson" + +#: cgi-bin/admin.c:3588 +msgid "Error Policy" +msgstr "Polis Kesalahan" + +#: systemv/lpinfo.c:109 systemv/lpmove.c:94 +msgid "Error: need hostname after '-h' option!\n" +msgstr "Kesalahan: perlu nama host usai opsi '-h'!\n" + +#: ppdc/sample.c:326 +msgid "Every 10 Labels" +msgstr "Tiap 10 Label" + +#: ppdc/sample.c:318 +msgid "Every 2 Labels" +msgstr "Tiap 2 Label" + +#: ppdc/sample.c:319 +msgid "Every 3 Labels" +msgstr "Tiap 3 Label" + +#: ppdc/sample.c:320 +msgid "Every 4 Labels" +msgstr "Tiap 4 Label" + +#: ppdc/sample.c:321 +msgid "Every 5 Labels" +msgstr "Tiap 5 Label" + +#: ppdc/sample.c:322 +msgid "Every 6 Labels" +msgstr "Tiap 6 Label" + +#: ppdc/sample.c:323 +msgid "Every 7 Labels" +msgstr "Tiap 7 Label" + +#: ppdc/sample.c:324 +msgid "Every 8 Labels" +msgstr "Tiap 8 Label" + +#: ppdc/sample.c:325 +msgid "Every 9 Labels" +msgstr "Tiap 9 Label" + +#: ppdc/sample.c:317 +msgid "Every Label" +msgstr "Tiap Label" + +#: cups/http-support.c:1239 +msgid "Expectation Failed" +msgstr "" + +#: cgi-bin/admin.c:2331 cgi-bin/admin.c:2350 +msgid "Export Printers to Samba" +msgstr "Ekspor Pencetak melalui Samba" + +#: systemv/cupstestdsc.c:176 systemv/cupstestdsc.c:193 +#: systemv/cupstestdsc.c:218 systemv/cupstestdsc.c:235 +#: systemv/cupstestdsc.c:259 systemv/cupstestdsc.c:277 +#: systemv/cupstestdsc.c:306 systemv/cupstestdsc.c:343 +#: systemv/cupstestdsc.c:353 systemv/cupstestdsc.c:363 +#: systemv/cupstestdsc.c:373 systemv/cupstestdsc.c:383 +#: systemv/cupstestdsc.c:391 +msgid "FAIL\n" +msgstr "GAGAL\n" + +#: ppdc/sample.c:132 +msgid "File Folder" +msgstr "Map" + +#: ppdc/sample.c:141 +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Map - 9/16 x 3 7/16\"" + +#: scheduler/ipp.c:2528 +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Berkas URI perangkat telah dinonaktifkan! Untuk mengaktifkannya, lihatlah " +"petunjuk FileDevice dalam \"%s/cupsd.conf\"." + +#: ppdc/sample.c:92 +msgid "Folio" +msgstr "Folio" + +#: cups/http-support.c:1218 +msgid "Forbidden" +msgstr "Terlarang" + +#: cups/localize.c:345 +msgid "Fuser temperature high!" +msgstr "Suhu fusi tinggi!" + +#: cups/localize.c:347 +msgid "Fuser temperature low!" +msgstr "Suhu fusi rendah!" + +#: cups/ppd.c:700 cups/ppd.c:1230 +msgid "General" +msgstr "Umum" + +#: ppdc/sample.c:231 +msgid "Generic" +msgstr "Umum" + +#: ppdc/sample.c:89 +msgid "German FanFold" +msgstr "FanFold Jerman" + +#: ppdc/sample.c:90 +msgid "German FanFold Legal" +msgstr "FanFold Legal Jerman" + +#: cups/snmp.c:1017 +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU memiliki panjang tak terdefinisi" + +#: ppdc/sample.c:261 +msgid "Glossy Paper" +msgstr "Kertas Glosi" + +#: scheduler/ipp.c:3641 scheduler/ipp.c:3947 scheduler/ipp.c:6627 +#: scheduler/ipp.c:6769 scheduler/ipp.c:8044 scheduler/ipp.c:9143 +#: scheduler/ipp.c:9369 scheduler/ipp.c:9724 scheduler/ipp.c:10300 +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Memperoleh atribut printer-uri tetapi bukan job-id!" + +#: ppdc/sample.c:227 +msgid "Grayscale" +msgstr "Skala Abu-abu" + +#: ppdc/sample.c:251 +msgid "HP" +msgstr "HP" + +#: ppdc/sample.c:133 +msgid "Hanging Folder" +msgstr "Map Gantung" + +#: ppdc/sample.c:142 +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Map Gantung - 9/16 x 2\"" + +#: backend/pap.c:296 +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk ditiadakan pada Preferensi Sistem\n" + +#: backend/pap.c:511 +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk ditiadakan pada Preferensi Sistem.\n" + +#: backend/ipp.c:1359 +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Membatalkan tugas mencetak...\n" + +#: backend/ipp.c:629 backend/lpd.c:896 backend/socket.c:354 +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Terhubung ke pencetak...\n" + +#: backend/ipp.c:544 backend/lpd.c:729 backend/socket.c:274 +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Menghubungi pencetak...\n" + +#: backend/lpd.c:1055 backend/lpd.c:1202 +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Berkas kontrol berhasil dikirim\n" + +#: backend/ipp.c:435 backend/lpd.c:450 +msgid "INFO: Copying print data...\n" +msgstr "INFO: Menyalin data yang hendak dicetak...\n" + +#: backend/lpd.c:1150 +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Berkas data berhasil dikirim\n" + +#: driver/rastertoescpx.c:1887 driver/rastertopclx.c:1912 +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "INFO: Halaman selesai %d...\n" + +#: filter/imagetoraster.c:1140 +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Memformat halaman %d...\n" + +#: filter/imagetoraster.c:621 +msgid "INFO: Loading image file...\n" +msgstr "INFO: Memuat berkas gambar...\n" + +#: cups/http-support.c:1428 +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Mencari pencetak...\n" + +#: backend/pap.c:928 +msgid "INFO: Opening connection\n" +msgstr "INFO: Membuka hubungan\n" + +#: backend/socket.c:425 +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Berkas cetak dikirim, menunggu pencetak selesai mengerjakannya...\n" + +#: backend/ipp.c:1044 backend/usb-unix.c:132 +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Pencetak sibuk; dicoba ulang 10 detik lagi...\n" + +#: backend/parallel.c:236 backend/scsi-irix.c:147 backend/scsi-linux.c:161 +#: backend/serial.c:256 +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Pencetak sibuk; dicoba ulang 30 detik lagi...\n" + +#: backend/usb-unix.c:437 +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Pencetak sibuk; dicoba ulang 5 detik lagi...\n" + +#: backend/ipp.c:742 backend/ipp.c:1055 +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: Pencetak tidak mendukung IPP/%d.%d, mencoba IPP/1.0...\n" + +#: backend/usb-unix.c:521 +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Pencetak sibuk; dicoba ulang 5 detik lagi...\n" + +#: backend/runloop.c:357 +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Pencetak saat ini tak terhubung.\n" + +#: backend/runloop.c:243 +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Pencetak saat ini tak terhubung.\n" + +#: backend/runloop.c:379 backend/usb-darwin.c:1254 +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Pencetak saat ini terhubung.\n" + +#: backend/usb-darwin.c:1272 +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Pencetak saat ini tak terhubung.\n" + +#: backend/parallel.c:242 backend/usb-unix.c:139 +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Pencetak tak terhubung; dicoba ulang 30 detik lagi...\n" + +#: driver/rastertoescpx.c:1873 driver/rastertopclx.c:1895 +#: filter/rastertoepson.c:1080 filter/rastertohp.c:803 +#: filter/rastertolabel.c:1235 +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Mencetak halaman %d, %d%% selesai...\n" + +#: filter/imagetops.c:808 +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Mencetak halaman %d...\n" + +#: backend/socket.c:457 driver/rastertoescpx.c:1911 driver/rastertopclx.c:1936 +#: filter/rastertoepson.c:1134 filter/rastertohp.c:862 +#: filter/rastertolabel.c:1288 +msgid "INFO: Ready to print.\n" +msgstr "INFO: Siap mencetak.\n" + +#: backend/lpd.c:1174 +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Mengirim berkas kontrol (%lu bita)\n" + +#: backend/lpd.c:1027 +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Mengirim berkas kontrol (%u bita)\n" + +#: backend/pap.c:564 +msgid "INFO: Sending data\n" +msgstr "INFO: Mengirim data\n" + +#: backend/lpd.c:1086 +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Mengirim berkas data (%ld bita)\n" + +#: backend/lpd.c:1084 +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Mengirim berkas data (%lld bita)\n" + +#: backend/usb-darwin.c:534 +msgid "INFO: Sending print data...\n" +msgstr "INFO: Mengirim data yang hendak dicetak...\n" + +#: backend/parallel.c:294 backend/socket.c:404 backend/usb-unix.c:201 +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Mengirim berkas yang hendak dicetak, %ld bita...\n" + +#: backend/parallel.c:292 backend/socket.c:402 backend/usb-unix.c:199 +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Mengirim berkas yang hendak dicetak, %lld bita...\n" + +#: backend/lpd.c:1098 +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "" + +#: driver/rastertoescpx.c:1859 driver/rastertopclx.c:1880 +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "INFO: Memulai halaman %d...\n" + +#: backend/ipp.c:561 backend/ipp.c:823 backend/lpd.c:829 +#: backend/parallel.c:221 backend/scsi-irix.c:125 backend/scsi-linux.c:139 +#: backend/serial.c:241 backend/socket.c:293 backend/usb-unix.c:117 +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Tidak bisa menghubungi pencetak, diantrikan ke pencetak selanjutnya pada " +"kelas...\n" + +#: backend/pap.c:309 +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Menggunakan zona baku AppleTalk \"%s\"\n" + +#: backend/ipp.c:1170 +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Menunggu tugas diselesaikan...\n" + +#: backend/usb-darwin.c:454 backend/usb-libusb.c:117 +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Menunggu pencetak tersedia...\n" + +#: ppdc/sample.c:93 +msgid "ISO B0" +msgstr "ISO B0" + +#: ppdc/sample.c:94 +msgid "ISO B1" +msgstr "ISO B1" + +#: ppdc/sample.c:104 +msgid "ISO B10" +msgstr "ISO B10" + +#: ppdc/sample.c:95 +msgid "ISO B2" +msgstr "ISO B2" + +#: ppdc/sample.c:96 +msgid "ISO B3" +msgstr "ISO B3" + +#: ppdc/sample.c:97 +msgid "ISO B4" +msgstr "ISO B4" + +#: ppdc/sample.c:69 +msgid "ISO B4 Envelope" +msgstr "ISO B4 Amplop" + +#: ppdc/sample.c:98 +msgid "ISO B5" +msgstr "ISO B5" + +#: ppdc/sample.c:99 +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (Besar)" + +#: ppdc/sample.c:70 +msgid "ISO B5 Envelope" +msgstr "ISO B5 Amplop" + +#: ppdc/sample.c:100 +msgid "ISO B6" +msgstr "ISO B6" + +#: ppdc/sample.c:71 +msgid "ISO B6 Envelope" +msgstr "ISO B6 Amplop" + +#: ppdc/sample.c:101 +msgid "ISO B7" +msgstr "ISO B7" + +#: ppdc/sample.c:102 +msgid "ISO B8" +msgstr "ISO B8" + +#: ppdc/sample.c:103 +msgid "ISO B9" +msgstr "ISO B9" + +#: cups/ppd.c:350 +msgid "Illegal control character" +msgstr "Karakter kontrol ilegal" + +#: cups/ppd.c:351 +msgid "Illegal main keyword string" +msgstr "String kata kunci utama ilegal" + +#: cups/ppd.c:352 +msgid "Illegal option keyword string" +msgstr "String opsi kata kunci ilegal" + +#: cups/ppd.c:353 +msgid "Illegal translation string" +msgstr "String translasi ilegal" + +#: cups/ppd.c:354 +msgid "Illegal whitespace character" +msgstr "" + +#: cups/localize.c:337 +msgid "Ink/toner almost empty." +msgstr "Tinta/toner hampir kosong." + +#: cups/localize.c:339 +msgid "Ink/toner empty!" +msgstr "Tinta/toner kosong!" + +#: cups/localize.c:341 +msgid "Ink/toner waste bin almost full." +msgstr "Baki buangan tinta/toner hampir penuh." + +#: cups/localize.c:343 +msgid "Ink/toner waste bin full!" +msgstr "Baki buangan tinta/toner sudah penuh!" + +#: ppdc/sample.c:246 +msgid "Installable Options" +msgstr "" + +#: ppdc/sample.c:249 +msgid "Installed" +msgstr "" + +#: ppdc/sample.c:264 +msgid "IntelliBar Label Printer" +msgstr "Pencetak Label IntelliBar" + +#: ppdc/sample.c:263 +msgid "Intellitech" +msgstr "Intellitech" + +#: cups/localize.c:321 +msgid "Interlock open." +msgstr "" + +#: cups/http-support.c:1245 +msgid "Internal Server Error" +msgstr "Kesalahan Internal Server" + +#: cups/ppd.c:341 +msgid "Internal error" +msgstr "Kesalahan internal" + +#: ppdc/sample.c:130 +msgid "Internet Postage 2-Part" +msgstr "Perangko Internet 2-Bagian" + +#: ppdc/sample.c:139 +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Perangko Internet 2-Bagian - 2 1/4 x 7 1/2\"" + +#: ppdc/sample.c:131 +msgid "Internet Postage 3-Part" +msgstr "Perangko Internet 3-Bagian" + +#: ppdc/sample.c:140 +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Perangko Internet 3-Bagian - 2 1/4 x 7\"" + +#: backend/ipp.c:206 +msgid "Internet Printing Protocol" +msgstr "Protokol Cetak Internet" + +#: ppdc/sample.c:68 +msgid "Invite Envelope" +msgstr "Amplop Undangan" + +#: ppdc/sample.c:72 +msgid "Italian Envelope" +msgstr "Amplop Italia" + +#: cups/ppd.c:1348 +msgid "JCL" +msgstr "JCL" + +#: scheduler/ipp.c:9442 +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Tugas #%d tidak bisa dicetak ulang - tidak ada berkas!" + +#: scheduler/ipp.c:3682 scheduler/ipp.c:4050 scheduler/ipp.c:6668 +#: scheduler/ipp.c:6810 scheduler/ipp.c:7921 scheduler/ipp.c:8085 +#: scheduler/ipp.c:8295 scheduler/ipp.c:8340 scheduler/ipp.c:9184 +#: scheduler/ipp.c:9410 scheduler/ipp.c:9765 scheduler/ipp.c:10341 +#, c-format +msgid "Job #%d does not exist!" +msgstr "Tugas #%d tidak ada!" + +#: scheduler/ipp.c:4082 +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Tugas #%d telah dibatalkan - tidak bisa dibatalkan lagi." + +#: scheduler/ipp.c:4076 +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Tugas #%d sudah dibatalkan - tidak bisa dibatalkan lagi." + +#: scheduler/ipp.c:4088 +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Tugas #%d sudah diselesaikan - tidak bisa dibatalkan." + +#: scheduler/ipp.c:8382 scheduler/ipp.c:10356 +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Tugas #%d sudah diselesaikan dan tidak dapat diubah!" + +#: scheduler/ipp.c:9424 +#, c-format +msgid "Job #%d is not complete!" +msgstr "Tugas #%d tidak selesai!" + +#: scheduler/ipp.c:3697 +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Tugas #%d tidak ditahan untuk otentikasi!" + +#: scheduler/ipp.c:9198 +#, c-format +msgid "Job #%d is not held!" +msgstr "Tugas #%d tidak ditahan!" + +#: scheduler/ipp.c:7899 +#, c-format +msgid "Job #%s does not exist!" +msgstr "Tugas #%s tidak ada!" + +#: scheduler/ipp.c:6295 +#, c-format +msgid "Job %d not found!" +msgstr "Tugas %d tidak ketemu!" + +#: cgi-bin/ipp-var.c:1050 +msgid "Job Completed" +msgstr "Tugas Diselesaikan" + +#: cgi-bin/ipp-var.c:1048 +msgid "Job Created" +msgstr "Tugas Dibuat" + +#: filter/bannertops.c:623 +msgid "Job ID: " +msgstr "ID Tugas: " + +#: cgi-bin/ipp-var.c:1054 +msgid "Job Options Changed" +msgstr "Perubahan Opsi Tugas" + +#: cgi-bin/ipp-var.c:1052 +msgid "Job Stopped" +msgstr "Tugas Dihentikan" + +#: filter/bannertops.c:631 +msgid "Job UUID: " +msgstr "UUID Tugas: " + +#: scheduler/ipp.c:10439 +msgid "Job is completed and cannot be changed." +msgstr "Tugas sudah diselesaikan dan tidak bisa diubah." + +#: cgi-bin/jobs.c:197 +msgid "Job operation failed:" +msgstr "Operasi tugas gagal:" + +#: scheduler/ipp.c:10475 scheduler/ipp.c:10494 scheduler/ipp.c:10505 +msgid "Job state cannot be changed." +msgstr "Status tugas tidak bisa diubah." + +#: scheduler/ipp.c:9289 +msgid "Job subscriptions cannot be renewed!" +msgstr "Subkripsi tugas tidak bisa diperbaharui!" + +#: cgi-bin/jobs.c:102 cgi-bin/jobs.c:113 cgi-bin/jobs.c:194 +msgid "Jobs" +msgstr "Tugas" + +#: ppdc/sample.c:73 +msgid "Kaku2 Envelope" +msgstr "Kaku2 Amplop" + +#: ppdc/sample.c:74 +msgid "Kaku3 Envelope" +msgstr "Kaku3 Amplop" + +#: backend/lpd.c:178 +msgid "LPD/LPR Host or Printer" +msgstr "Host atau Pencetak LPD/LPR" + +#: ppdc/sample.c:202 +msgid "Label Printer" +msgstr "Pencetak Label" + +#: ppdc/sample.c:417 +msgid "Label Top" +msgstr "Label Atas" + +#: scheduler/ipp.c:2150 scheduler/ipp.c:6218 +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Bahasa \"%s\" tidak didukung!" + +#: ppdc/sample.c:127 +msgid "Large Address" +msgstr "Alamat Besar" + +#: ppdc/sample.c:136 +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Alamat Besar - 1 4/10 x 3 1/2\"" + +#: ppdc/sample.c:262 +msgid "LaserJet Series PCL 4/5" +msgstr "Seri LaserJet PCL 4/5" + +#: ppdc/sample.c:208 +msgid "Light" +msgstr "Cahaya" + +#: cups/ppd.c:349 +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Baris melebihi panjang yang diperbolehkan (255 karakter)" + +#: cgi-bin/admin.c:2368 +msgid "List Available Printers" +msgstr "Daftar Pencetak yang Tersedia" + +#: filter/bannertops.c:744 +msgid "Location: " +msgstr "Lokasi: " + +#: ppdc/sample.c:244 +msgid "Long-Edge (Portrait)" +msgstr "Sisi Panjang (Tegak)" + +#: filter/bannertops.c:753 +msgid "Make and Model: " +msgstr "Pembuat dan Model: " + +#: ppdc/sample.c:240 +msgid "Manual Feed" +msgstr "" + +#: filter/bannertops.c:780 +msgid "Media Dimensions: " +msgstr "Dimensi Media: " + +#: filter/bannertops.c:800 +msgid "Media Limits: " +msgstr "Batas Media: " + +#: filter/bannertops.c:769 +msgid "Media Name: " +msgstr "Nama Media: " + +#: cups/ppd.c:747 cups/ppd.c:1285 +msgid "Media Size" +msgstr "Ukuran Media" + +#: cups/ppd.c:751 cups/ppd.c:1289 ppdc/sample.c:234 +msgid "Media Source" +msgstr "Sumber Media" + +#: ppdc/sample.c:335 +msgid "Media Tracking" +msgstr "" + +#: cups/ppd.c:749 cups/ppd.c:1287 ppdc/sample.c:256 +msgid "Media Type" +msgstr "Jenis Media" + +#: cups/localize.c:310 +msgid "Media jam!" +msgstr "Media tersangkut!" + +#: cups/localize.c:327 +msgid "Media tray almost empty." +msgstr "Baki media hampir kosong." + +#: cups/localize.c:329 +msgid "Media tray empty!" +msgstr "Baki media kosong!" + +#: cups/localize.c:325 +msgid "Media tray missing!" +msgstr "Baki media hilang!" + +#: cups/localize.c:308 +msgid "Media tray needs to be filled." +msgstr "Baki media perlu diisi." + +#: ppdc/sample.c:209 +msgid "Medium" +msgstr "" + +#: cups/ppd.c:338 +msgid "Memory allocation error" +msgstr "Kesalahan alokasi memori" + +#: cups/ppd.c:339 +msgid "Missing PPD-Adobe-4.x header" +msgstr "Kehilangan tajuk PPD-Adobe-4.x" + +#: cups/ppd.c:348 +msgid "Missing asterisk in column 1" +msgstr "Kehilangan asterik pada kolom 1" + +#: scheduler/ipp.c:6690 +msgid "Missing document-number attribute!" +msgstr "Kehilangan atribut document-number!" + +#: cups/adminutil.c:284 +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Kehilangan tanda kutip pada baris %d!" + +#: cgi-bin/admin.c:2080 cgi-bin/admin.c:2165 cgi-bin/admin.c:2801 +#: cgi-bin/admin.c:3055 cgi-bin/admin.c:3166 cgi-bin/admin.c:3844 +msgid "Missing form variable!" +msgstr "Kehilangan variabel formulir!" + +#: scheduler/ipp.c:7090 +msgid "Missing notify-subscription-ids attribute!" +msgstr "Kehilangan atribut notify-subscription-ids!" + +#: scheduler/ipp.c:3820 +msgid "Missing requesting-user-name attribute!" +msgstr "Kehilangan atribut requesting-user-name!" + +#: scheduler/ipp.c:477 +msgid "Missing required attributes!" +msgstr "Kehilangan atribut yang diperlukan!" + +#: cups/adminutil.c:265 +#, c-format +msgid "Missing value on line %d!" +msgstr "Kehilangan nilai pada baris %d!" + +#: cups/ppd.c:340 +msgid "Missing value string" +msgstr "Kehilangan string nilai" + +#: systemv/lpinfo.c:475 +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +#: cgi-bin/admin.c:480 +msgid "Modify Class" +msgstr "Ubah Kelas" + +#: cgi-bin/admin.c:778 +msgid "Modify Printer" +msgstr "Ubah Pencetak" + +#: ppdc/sample.c:111 +msgid "Monarch" +msgstr "Monarki" + +#: ppdc/sample.c:75 +msgid "Monarch Envelope" +msgstr "Amplop Monarki" + +#: cgi-bin/ipp-var.c:421 cgi-bin/ipp-var.c:512 +msgid "Move All Jobs" +msgstr "Pindah Semua Tugas" + +#: cgi-bin/ipp-var.c:360 cgi-bin/ipp-var.c:419 cgi-bin/ipp-var.c:510 +msgid "Move Job" +msgstr "Pindah Tugas" + +#: cups/http-support.c:1202 +msgid "Moved Permanently" +msgstr "Dipindahkan Permanen" + +#: backend/ipp.c:1092 +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Berkas yang hendak dicetak diterima - ID tugas %d.\n" + +#: backend/ipp.c:1086 +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Berkas yang hendak dicetak diterima - ID tugas tak dikenal.\n" + +#: cups/ppd.c:337 +msgid "NULL PPD file pointer" +msgstr "" + +#: cups/snmp.c:1054 +msgid "Name OID uses indefinite length" +msgstr "Nama OID memiliki panjang tak terdefinisi" + +#: scheduler/ipp.c:1196 +msgid "Nested classes are not allowed!" +msgstr "Kelas bersarang tidak diperbolehkan!" + +#: ppdc/sample.c:401 +msgid "Never" +msgstr "Tidak Pernah" + +#: ppdc/sample.c:228 +msgid "New Stylus Color Series" +msgstr "Seri Stylus Color Baru" + +#: ppdc/sample.c:230 +msgid "New Stylus Photo Series" +msgstr "Seri Stylus Photo Baru" + +#: cups/ppd.c:1877 +msgid "No" +msgstr "Tidak" + +#: cups/http-support.c:1199 +msgid "No Content" +msgstr "Tak Ada Isi" + +#: cups/util.c:1289 +msgid "No PPD name!" +msgstr "Tidak ada nama PPD!" + +#: cups/snmp.c:1048 +msgid "No VarBind SEQUENCE" +msgstr "Tidak ada VarBind SEQUENCE" + +#: cups/adminutil.c:799 +msgid "No Windows printer drivers are installed!" +msgstr "Tidak ada penggerak pencetak Windows yang terpasang!" + +#: cups/request.c:509 cups/request.c:775 +msgid "No active connection" +msgstr "Tidak ada koneksi yang aktif" + +#: scheduler/ipp.c:3998 +#, c-format +msgid "No active jobs on %s!" +msgstr "Tidak ada tugas yang aktif pada %s!" + +#: scheduler/ipp.c:318 +msgid "No attributes in request!" +msgstr "Tidak ada atribut dalam permintaan!" + +#: scheduler/ipp.c:3725 +msgid "No authentication information provided!" +msgstr "Tidak ada informasi otentikasi yang tersedia!" + +#: cups/snmp.c:1005 +msgid "No community name" +msgstr "Tidak ada nama komunitas" + +#: scheduler/ipp.c:6490 +msgid "No default printer" +msgstr "Tidak ada pencetak utama" + +#: cgi-bin/ipp-var.c:432 scheduler/ipp.c:7666 +msgid "No destinations added." +msgstr "Tidak ada tujuan yang ditambah." + +#: cups/snmp.c:1035 +msgid "No error-index" +msgstr "Tidak ada error-index" + +#: cups/snmp.c:1027 +msgid "No error-status" +msgstr "Tidak ada error-status" + +#: scheduler/ipp.c:8582 scheduler/ipp.c:9817 +msgid "No file!?!" +msgstr "Tidak ada berkas!?!" + +#: cups/util.c:924 +msgid "No modification time!" +msgstr "Tidak ada waktu modifikasi!" + +#: cups/snmp.c:1052 +msgid "No name OID" +msgstr "Tidak ada nama OID" + +#: cups/util.c:918 +msgid "No printer name!" +msgstr "Tidak ada nama pencetak!" + +#: cups/util.c:1840 +msgid "No printer-uri found for class!" +msgstr "Tidak ditemukan printer-uri untuk kelas!" + +#: cups/util.c:1855 +msgid "No printer-uri found!" +msgstr "Tidak ditemukan printer-uri!" + +#: scheduler/ipp.c:6875 +msgid "No printer-uri in request!" +msgstr "Tidak ada printer-uri dalam permintaan!" + +#: cups/snmp.c:1019 +msgid "No request-id" +msgstr "Tidak ada request-id" + +#: scheduler/ipp.c:6103 +msgid "No subscription attributes in request!" +msgstr "Tidak ada atribut subskripsi dalam permintaan!" + +#: scheduler/ipp.c:7984 +msgid "No subscriptions found." +msgstr "Tidak ada subskripsi yang ditemukan." + +#: cups/snmp.c:1043 +msgid "No variable-bindings SEQUENCE" +msgstr "Tidak ada variable-bindings SEQUENCE" + +#: cups/snmp.c:998 +msgid "No version number" +msgstr "Tidak ada nomor versi" + +#: ppdc/sample.c:338 +msgid "Non-continuous (Mark sensing)" +msgstr "Tak bersambungan (Penanda)" + +#: ppdc/sample.c:337 +msgid "Non-continuous (Web sensing)" +msgstr "Tak bersambungan (Web)" + +#: ppdc/sample.c:210 +msgid "Normal" +msgstr "Normal" + +#: cups/http-support.c:1221 +msgid "Not Found" +msgstr "Tidak Ketemu" + +#: cups/http-support.c:1233 +msgid "Not Implemented" +msgstr "Tidak Diimplementasikan" + +#: ppdc/sample.c:248 +msgid "Not Installed" +msgstr "Tidak Terpasang" + +#: cups/http-support.c:1208 +msgid "Not Modified" +msgstr "Tidak Diubah" + +#: cups/http-support.c:1236 +msgid "Not Supported" +msgstr "Tidak Didukung" + +#: scheduler/ipp.c:1527 +msgid "Not allowed to print." +msgstr "Tidak diperbolehkan mencetak." + +#: ppdc/sample.c:112 +msgid "Note" +msgstr "Catatan" + +#: cups/http-support.c:1190 cups/ppd.c:335 +msgid "OK" +msgstr "Oke" + +#: cups/localize.c:349 +msgid "OPC almost at end-of-life." +msgstr "OPC nyaris di ujung hayat." + +#: cups/localize.c:351 +msgid "OPC at end-of-life!" +msgstr "OPC sudah di ujung hayat!" + +#: ppdc/sample.c:243 +msgid "Off (1-Sided)" +msgstr "Mati (1-Sisi)" + +#: ppdc/sample.c:332 +msgid "Oki" +msgstr "Oki" + +#: cgi-bin/help.c:89 cgi-bin/help.c:130 cgi-bin/help.c:140 cgi-bin/help.c:171 +msgid "Online Help" +msgstr "Bantuan Langsung" + +#: cups/adminutil.c:985 +#, c-format +msgid "Open of %s failed: %s" +msgstr "Gagal membuka %s: %s" + +#: cups/ppd.c:343 +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup tanpa CloseGroup lebih dulu" + +#: cups/ppd.c:345 +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI tanpa CloseUI/JCLCloseUI lebih dulu" + +#: cgi-bin/admin.c:3615 +msgid "Operation Policy" +msgstr "Polis Operasi" + +#: cgi-bin/admin.c:3292 cgi-bin/admin.c:3352 +msgid "Options Installed" +msgstr "Opsi yang Terpasang" + +#: filter/bannertops.c:674 +msgid "Options: " +msgstr "Opsi: " + +#: cups/localize.c:317 +msgid "Out of toner!" +msgstr "Kehabisan toner!" + +#: cups/ppd.c:753 cups/ppd.c:1291 +msgid "Output Mode" +msgstr "Modus Keluaran" + +#: cups/localize.c:333 +msgid "Output bin almost full." +msgstr "Baki keluaran hampir penuh." + +#: cups/localize.c:335 +msgid "Output bin full!" +msgstr "Baki keluaran penuh!" + +#: systemv/lpstat.c:1191 systemv/lpstat.c:1195 +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Keluaran untuk pencetak %s dikirim ke %s\n" + +#: systemv/lpstat.c:1185 +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Keluaran untuk pencetak %s dikirim ke pencetak jarak jauh %s pada %s\n" + +#: systemv/lpstat.c:1209 systemv/lpstat.c:1213 +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Keluaran untuk pencetak %s/%s dikirim ke %s\n" + +#: systemv/lpstat.c:1203 +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "Keluaran untuk pencetak %s/%s dikirim ke pencetak jarak jauh %s pada %s\n" + +#: cups/localize.c:331 +msgid "Output tray missing!" +msgstr "Baki keluaran hilang!" + +#: systemv/cupstestdsc.c:403 +msgid "PASS\n" +msgstr "LEWAT\n" + +#: ppdc/sample.c:232 +msgid "PCL Laser Printer" +msgstr "Pencetak Laser PCL" + +#: ppdc/sample.c:77 +msgid "PRC1 Envelope" +msgstr "PRC1 Amplop" + +#: ppdc/sample.c:86 +msgid "PRC10 Envelope" +msgstr "PRC10 Amplop" + +#: ppdc/sample.c:114 +msgid "PRC16K" +msgstr "PRC16K" + +#: ppdc/sample.c:78 +msgid "PRC2 Envelope" +msgstr "PRC2 Amplop" + +#: ppdc/sample.c:79 +msgid "PRC3 Envelope" +msgstr "PRC3 Amplop" + +#: ppdc/sample.c:115 +msgid "PRC32K" +msgstr "PRC32K" + +#: ppdc/sample.c:116 +msgid "PRC32K (Oversize)" +msgstr "PRC32K (Besar)" + +#: ppdc/sample.c:80 +msgid "PRC4 Envelope" +msgstr "PRC4 Amplop" + +#: ppdc/sample.c:81 +msgid "PRC5 Envelope" +msgstr "PRC5 Amplop" + +#: ppdc/sample.c:82 +msgid "PRC6 Envelope" +msgstr "PRC6 Amplop" + +#: ppdc/sample.c:83 +msgid "PRC7 Envelope" +msgstr "PRC7 Amplop" + +#: ppdc/sample.c:84 +msgid "PRC8 Envelope" +msgstr "PRC8 Amplop" + +#: ppdc/sample.c:85 +msgid "PRC9 Envelope" +msgstr "PRC9 Amplop" + +#: cups/snmp.c:1015 +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Paket tidak mengandung Get-Response-PDU" + +#: cups/snmp.c:994 +msgid "Packet does not start with SEQUENCE" +msgstr "Paket tidak dimulai dengan SEQUENCE" + +#: ppdc/sample.c:331 +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +#: ppdc/sample.c:329 +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#: cups/auth.c:158 +#, c-format +msgid "Password for %s on %s? " +msgstr "Sandi untuk %s pada %s? " + +#: systemv/cupsaddsmb.c:256 +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Sandi untuk %s diperlukan untuk mengakses %s via SAMBA: " + +#: cgi-bin/classes.c:152 +msgid "Pause Class" +msgstr "Tahan Kelas" + +#: cgi-bin/printers.c:155 +msgid "Pause Printer" +msgstr "Tahan Pencetak" + +#: ppdc/sample.c:419 +msgid "Peel-Off" +msgstr "" + +#: ppdc/sample.c:76 +msgid "Personal Envelope" +msgstr "Amplop Pribadi" + +#: ppdc/sample.c:123 +msgid "Photo" +msgstr "Foto" + +#: ppdc/sample.c:124 +msgid "Photo Labels" +msgstr "Label Foto" + +#: ppdc/sample.c:257 +msgid "Plain Paper" +msgstr "Kertas Biasa" + +#: cgi-bin/admin.c:3310 cgi-bin/admin.c:3564 +msgid "Policies" +msgstr "Kebijakan" + +#: cgi-bin/admin.c:3317 cgi-bin/admin.c:3633 cgi-bin/admin.c:3646 +msgid "Port Monitor" +msgstr "Port Monitor" + +#: ppdc/sample.c:250 +msgid "PostScript Printer" +msgstr "Pencetak PostScript" + +#: ppdc/sample.c:113 +msgid "Postcard" +msgstr "Kartu Pos" + +#: ppdc/sample.c:266 +msgid "Print Density" +msgstr "Densitas Cetak" + +#: cups/notify.c:82 +msgid "Print Job:" +msgstr "Tugas Cetak:" + +#: ppdc/sample.c:311 +msgid "Print Mode" +msgstr "Modus Cetak" + +#: ppdc/sample.c:354 +msgid "Print Rate" +msgstr "" + +#: cgi-bin/printers.c:164 +msgid "Print Self-Test Page" +msgstr "Cetak Halaman Uji-Mandiri" + +#: ppdc/sample.c:298 +msgid "Print Speed" +msgstr "Kecepatan Cetak" + +#: cgi-bin/ipp-var.c:787 +msgid "Print Test Page" +msgstr "Cetak Halaman Uji" + +#: ppdc/sample.c:327 +msgid "Print and Cut" +msgstr "Cetak dan Potong" + +#: ppdc/sample.c:315 +msgid "Print and Tear" +msgstr "" + +#: filter/bannertops.c:648 +msgid "Printed For: " +msgstr "Dicetak Untuk: " + +#: filter/bannertops.c:656 +msgid "Printed From: " +msgstr "Dicetak Dari: " + +#: filter/bannertops.c:876 +msgid "Printed On: " +msgstr "Dicetak Pada: " + +#: cgi-bin/ipp-var.c:1042 +msgid "Printer Added" +msgstr "Pencetak Ditambah" + +#: ppdc/sample.c:235 +msgid "Printer Default" +msgstr "Pencetak Utama" + +#: cgi-bin/ipp-var.c:1046 +msgid "Printer Deleted" +msgstr "Pencetak Dihapus" + +#: cgi-bin/ipp-var.c:1044 +msgid "Printer Modified" +msgstr "Pencetak Diubah" + +#: filter/bannertops.c:614 +msgid "Printer Name: " +msgstr "Nama Pencetak: " + +#: cgi-bin/ipp-var.c:1040 +msgid "Printer Paused" +msgstr "Pencetak Ditahan" + +#: ppdc/sample.c:265 +msgid "Printer Settings" +msgstr "Pengaturan Pencetak" + +#: cups/localize.c:313 +msgid "Printer offline." +msgstr "Pencetak tak terhubung." + +#: cups/notify.c:126 +msgid "Printer:" +msgstr "Pencetak:" + +#: cgi-bin/printers.c:189 cgi-bin/printers.c:317 +msgid "Printers" +msgstr "Pencetak" + +#: cgi-bin/classes.c:158 cgi-bin/printers.c:161 +msgid "Purge Jobs" +msgstr "Membersihkan Tugas" + +#: ppdc/sample.c:117 +msgid "Quarto" +msgstr "Kuarto" + +#: scheduler/ipp.c:1522 +msgid "Quota limit reached." +msgstr "Batas kuota telah dicapai." + +#: berkeley/lpq.c:507 +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "Urut Tuan Tgs Berkas Ukur Total\n" + +#: berkeley/lpq.c:503 +msgid "Rank Owner Pri Job Files Total Size\n" +msgstr "Urut Tuan Pri Tugas Berkas Ukuran Total\n" + +#: cgi-bin/classes.c:156 cgi-bin/printers.c:159 +msgid "Reject Jobs" +msgstr "Tolak Tugas" + +#: ppdc/sample.c:399 +msgid "Reprint After Error" +msgstr "Cetak Ulang Usai Kesalahan" + +#: cups/http-support.c:1224 +msgid "Request Entity Too Large" +msgstr "Entitas Pesanan Terlalu Besar" + +#: cups/ppd.c:755 cups/ppd.c:1293 ppdc/sample.c:203 +msgid "Resolution" +msgstr "Resolusi" + +#: cgi-bin/classes.c:150 +msgid "Resume Class" +msgstr "" + +#: cgi-bin/printers.c:152 +msgid "Resume Printer" +msgstr "" + +#: ppdc/sample.c:128 +msgid "Return Address" +msgstr "Alamat Pengembalian" + +#: ppdc/sample.c:137 +msgid "Return Address - 3/4 x 2\"" +msgstr "Alamat Pengembalian - 3/4 x 2\"" + +#: ppdc/sample.c:420 +msgid "Rewind" +msgstr "Ulang" + +#: cups/adminutil.c:2167 +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Menjalankan perintah: %s %s -N -A %s -c '%s'\n" + +#: backend/scsi-irix.c:70 backend/scsi-linux.c:83 +msgid "SCSI Printer" +msgstr "Pencetak SCSI" + +#: cups/snmp.c:996 +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE memiliki panjang tak terdefinisi" + +#: cups/http-support.c:1205 +msgid "See Other" +msgstr "Lihat Lainnya" + +#: backend/serial.c:784 backend/serial.c:943 backend/serial.c:1065 +#: backend/serial.c:1159 +#, c-format +msgid "Serial Port #%d" +msgstr "Port Serial #%d" + +#: cgi-bin/ipp-var.c:1056 +msgid "Server Restarted" +msgstr "Server Dijalankan Ulang" + +#: cgi-bin/ipp-var.c:1062 +msgid "Server Security Auditing" +msgstr "Audit Sekuritas Server" + +#: cgi-bin/ipp-var.c:1058 +msgid "Server Started" +msgstr "Server Dijalankan" + +#: cgi-bin/ipp-var.c:1060 +msgid "Server Stopped" +msgstr "Server Dihentikan" + +#: cups/http-support.c:1242 +msgid "Service Unavailable" +msgstr "Layanan Tak Tersedia" + +#: cgi-bin/admin.c:2802 cgi-bin/admin.c:2848 cgi-bin/admin.c:3005 +#: cgi-bin/admin.c:3024 +msgid "Set Allowed Users" +msgstr "Atur Pengguna yang Boleh" + +#: cgi-bin/admin.c:3051 +msgid "Set As Server Default" +msgstr "Atur Sebagai Baku Server" + +#: cgi-bin/admin.c:3151 +msgid "Set Class Options" +msgstr "Atur Opsi Kelas" + +#: cgi-bin/admin.c:3151 cgi-bin/admin.c:3320 cgi-bin/admin.c:3675 +msgid "Set Printer Options" +msgstr "Atur Opsi Pencetak" + +#: cgi-bin/admin.c:3845 cgi-bin/admin.c:3889 cgi-bin/admin.c:3907 +msgid "Set Publishing" +msgstr "Atur Penerbitan" + +#: ppdc/sample.c:129 +msgid "Shipping Address" +msgstr "Alamat Pengiriman" + +#: ppdc/sample.c:138 +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Alamat Pengiriman - 2 5/16 x 4\"" + +#: ppdc/sample.c:245 +msgid "Short-Edge (Landscape)" +msgstr "Sisi-Pendek (Mendatar)" + +#: ppdc/sample.c:259 +msgid "Special Paper" +msgstr "Kertas Khusus" + +#: ppdc/sample.c:312 +msgid "Standard" +msgstr "Standar" + +#: cgi-bin/admin.c:3538 +msgid "Starting Banner" +msgstr "Menjalankan Pataka" + +#: ppdc/sample.c:118 +msgid "Statement" +msgstr "Pernyataan" + +#: ppdc/sample.c:223 +msgid "Stylus Color Series" +msgstr "Seri Stylus Color" + +#: ppdc/sample.c:229 +msgid "Stylus Photo Series" +msgstr "Seri Stylus Photo" + +#: ppdc/sample.c:119 +msgid "Super A" +msgstr "Super A" + +#: ppdc/sample.c:120 +msgid "Super B" +msgstr "Super B" + +#: ppdc/sample.c:125 +msgid "Super B/A3" +msgstr "Super B/A3" + +#: cups/http-support.c:1187 +msgid "Switching Protocols" +msgstr "Berpindah Protokol" + +#: ppdc/sample.c:121 +msgid "Tabloid" +msgstr "Tabloid" + +#: ppdc/sample.c:122 +msgid "Tabloid (Oversize)" +msgstr "Tabloid (Besar)" + +#: ppdc/sample.c:313 +msgid "Tear" +msgstr "" + +#: ppdc/sample.c:418 +msgid "Tear-Off" +msgstr "" + +#: ppdc/sample.c:359 +msgid "Tear-Off Adjust Position" +msgstr "" + +#: scheduler/ipp.c:7337 +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Berkas PPD \"%s\" tak bisa ditemukan." + +#: scheduler/ipp.c:7324 +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Berkas PPD \"%s\" tak bisa dibuka: %s" + +#: cgi-bin/admin.c:644 +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Nama kelas paling banyak 127 karakter cetak dan tidak mengandung spasi, " +"garis miring (/), atau pun tanda pagar (#)." + +#: scheduler/ipp.c:2177 +msgid "The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "Atribut notify-lease-duration tak bisa digunakan bersama subskripsi tugas." + +#: scheduler/ipp.c:2160 scheduler/ipp.c:6228 +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Nilai notify-user-data terlalu besar (%d > 63 oktet)!" + +#: cgi-bin/admin.c:827 +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Nama pencetak paling banyak 127 karakter cetak dan tidak mengandung spasi, " +"garis miring (/), atau tanda pagar (#)." + +#: scheduler/ipp.c:1357 +msgid "The printer or class is not shared!" +msgstr "Pencetak atau kelas tidak dikongsikan!" + +#: scheduler/ipp.c:884 scheduler/ipp.c:1190 scheduler/ipp.c:3856 +#: scheduler/ipp.c:3964 scheduler/ipp.c:5759 scheduler/ipp.c:6062 +#: scheduler/ipp.c:6375 scheduler/ipp.c:6912 scheduler/ipp.c:7542 +#: scheduler/ipp.c:7598 scheduler/ipp.c:7911 scheduler/ipp.c:8153 +#: scheduler/ipp.c:8243 scheduler/ipp.c:8276 scheduler/ipp.c:8597 +#: scheduler/ipp.c:8988 scheduler/ipp.c:9068 scheduler/ipp.c:10209 +#: scheduler/ipp.c:10665 scheduler/ipp.c:10994 scheduler/ipp.c:11061 +#: scheduler/ipp.c:11344 +msgid "The printer or class was not found." +msgstr "Pencetak atau kelas tidak ditemukan." + +#: scheduler/ipp.c:990 scheduler/ipp.c:2367 +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Terdapat karakter tidak sah pada printer-uri \"%s\"." + +#: scheduler/ipp.c:3801 +msgid "The printer-uri attribute is required!" +msgstr "Atribut printer-uri diperlukan!" + +#: scheduler/ipp.c:974 +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"Bentuk printer-uri seharusnya menuruti format \"ipp://HOSTNAME/classes/" +"CLASSNAME\"." + +#: scheduler/ipp.c:2351 +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"Bentuk printer-uri seharusnya menuruti format \"ipp://HOSTNAME/printers/" +"PRINTERNAME\"." + +#: cgi-bin/admin.c:385 +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Nama subskripsi tidak bisa mengandung spasi, garis miring (/), tanda tanya " +"(?), atau tanda pagar (#)." + +#: scheduler/ipp.c:6305 +msgid "There are too many subscriptions." +msgstr "Terlalu banyak subskripsi." + +#: ppdc/sample.c:406 +msgid "Thermal Transfer Media" +msgstr "" + +#: filter/bannertops.c:640 +msgid "Title: " +msgstr "Judul: " + +#: cups/localize.c:315 +msgid "Toner low." +msgstr "Toner lemah." + +#: scheduler/ipp.c:1516 +msgid "Too many active jobs." +msgstr "Terlalu banyak tugas yang aktif." + +#: scheduler/ipp.c:1454 +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Terlalu banyak nilai job-sheets (%d > 2)!" + +#: scheduler/ipp.c:2672 +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Terlalu banyak nilai printer-state-reasons (%d > %d)!" + +#: ppdc/sample.c:260 +msgid "Transparency" +msgstr "Transparansi" + +#: ppdc/sample.c:255 +msgid "Tray" +msgstr "Baki" + +#: ppdc/sample.c:236 +msgid "Tray 1" +msgstr "Baki 1" + +#: ppdc/sample.c:237 +msgid "Tray 2" +msgstr "Baki 2" + +#: ppdc/sample.c:238 +msgid "Tray 3" +msgstr "Baki 3" + +#: ppdc/sample.c:239 +msgid "Tray 4" +msgstr "Baki 4" + +#: cups/http-support.c:1227 +msgid "URI Too Long" +msgstr "URI Terlalu Panjang" + +#: ppdc/sample.c:88 +msgid "US Executive" +msgstr "Eksekutif AS" + +#: ppdc/sample.c:91 +msgid "US Fanfold" +msgstr "Fanfold AS" + +#: ppdc/sample.c:105 +msgid "US Ledger" +msgstr "Ledger AS" + +#: ppdc/sample.c:106 +msgid "US Legal" +msgstr "Legal AS" + +#: ppdc/sample.c:107 +msgid "US Legal (Oversize)" +msgstr "Legal AS (Besar)" + +#: ppdc/sample.c:108 +msgid "US Letter" +msgstr "Kuarto AS" + +#: ppdc/sample.c:109 +msgid "US Letter (Oversize)" +msgstr "Kuarto AS (Besar)" + +#: ppdc/sample.c:110 +msgid "US Letter (Small)" +msgstr "Kuarto AS (Kecil)" + +#: backend/serial.c:797 +#, c-format +msgid "USB Serial Port #%d" +msgstr "Port Serial USB #%d" + +#: cgi-bin/admin.c:1933 cgi-bin/admin.c:1946 cgi-bin/admin.c:1970 +msgid "Unable to access cupsd.conf file:" +msgstr "Tidak bisa mengakses berkas cupsd.conf:" + +#: cgi-bin/admin.c:437 +msgid "Unable to add RSS subscription:" +msgstr "Tidak bisa menambah subskripsi RSS:" + +#: cgi-bin/admin.c:710 +msgid "Unable to add class:" +msgstr "Tidak bisa menambah kelas:" + +#: scheduler/ipp.c:1560 +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Tidak bisa menambah tugas untuk tujuan \"%s\"!" + +#: cgi-bin/admin.c:959 cgi-bin/admin.c:1320 +msgid "Unable to add printer:" +msgstr "Tidak bisa menambah pencetak:" + +#: scheduler/ipp.c:1302 +msgid "Unable to allocate memory for file types!" +msgstr "Tidak bisa mengalokasikan memori untuk jenis berkas!" + +#: cgi-bin/admin.c:1426 +msgid "Unable to cancel RSS subscription:" +msgstr "Tidak bisa membatalkan subskripsi RSS:" + +#: cgi-bin/admin.c:3890 +msgid "Unable to change printer-is-shared attribute:" +msgstr "Tidak bisa mengubah atribut printer-is-shared:" + +#: cgi-bin/admin.c:3006 +msgid "Unable to change printer:" +msgstr "Tidak bisa mengubah pencetak:" + +#: cgi-bin/admin.c:1610 cgi-bin/admin.c:1774 +msgid "Unable to change server settings:" +msgstr "Tidak bisa mengubah pengaturan server:" + +#: cups/adminutil.c:941 cups/util.c:1652 +msgid "Unable to connect to host." +msgstr "Tidak bisa terhubung ke host." + +#: cups/adminutil.c:737 +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Tidak bisa menyalin berkas penggerak pencetak CUPS 64-bit (%d)!" + +#: cups/adminutil.c:702 +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "Tidak bisa menyalin berkas penggerak pencetak Windows 64-bit (%d)!" + +#: cups/adminutil.c:533 +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Tidak bisa menyalin berkas penggerak pencetak CUPS (%d)!" + +#: scheduler/ipp.c:2788 +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Tidak bisa menyalin berkas PPD - %s!" + +#: scheduler/ipp.c:2854 +msgid "Unable to copy PPD file!" +msgstr "Tidak bisa menyalin berkas PPD!" + +#: cups/adminutil.c:498 +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Tidak bisa menyalin berkas penggerak pencetak Windows 2000 (%d)!" + +#: cups/adminutil.c:621 +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Tidak bisa menyalin berkas penggerak pencetak Windows 9x (%d)!" + +#: scheduler/ipp.c:2765 +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Tidak bisa menyalin skrip antarmuka - %s!" + +#: cups/util.c:607 cups/util.c:1711 +msgid "Unable to create printer-uri!" +msgstr "Tidak bisa membuat printer-uri!" + +#: cgi-bin/admin.c:1824 cgi-bin/admin.c:1836 +msgid "Unable to create temporary file:" +msgstr "Tidak bisa membuat berkas temporer:" + +#: cgi-bin/admin.c:2127 +msgid "Unable to delete class:" +msgstr "Tidak bisa menghapus kelas:" + +#: cgi-bin/admin.c:2212 +msgid "Unable to delete printer:" +msgstr "Tidak bisa menghapus pencetak:" + +#: cgi-bin/classes.c:245 cgi-bin/printers.c:254 +msgid "Unable to do maintenance command:" +msgstr "" + +#: cgi-bin/admin.c:1948 +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Tidak bisa menyunting berkas cupsd.conf lebih dari 1MB!" + +#: cgi-bin/ipp-var.c:361 +msgid "Unable to find destination for job!" +msgstr "Tidak bisa menemukan tujuan untuk tugas!" + +#: cups/http-support.c:1509 +msgid "Unable to find printer!\n" +msgstr "Tidak bisa menemukan pencetak!\n" + +#: cgi-bin/classes.c:435 +msgid "Unable to get class list:" +msgstr "Tidak bisa memperoleh daftar kelas:" + +#: cgi-bin/classes.c:534 +msgid "Unable to get class status:" +msgstr "Tidak bisa memperoleh status kelas:" + +#: cgi-bin/admin.c:1221 +msgid "Unable to get list of printer drivers:" +msgstr "Tidak bisa memperoleh daftar penggerak pencetak:" + +#: cgi-bin/admin.c:2856 +msgid "Unable to get printer attributes:" +msgstr "Tidak bisa memperoleh atribut pencetak:" + +#: cgi-bin/printers.c:452 +msgid "Unable to get printer list:" +msgstr "Tidak bisa memperoleh daftar pencetak:" + +#: cgi-bin/printers.c:554 +msgid "Unable to get printer status:" +msgstr "Tidak bisa memperoleh status pencetak:" + +#: cups/adminutil.c:576 cups/adminutil.c:780 +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Tidak bisa memasang berkas penggerak pencetak Windows 2000 (%d)!" + +#: cups/adminutil.c:650 +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Tidak bisa memasang berkas penggerak pencetak Windows 9x (%d)!" + +#: cgi-bin/admin.c:709 +msgid "Unable to modify class:" +msgstr "Tidak bisa mengubah kelas:" + +#: cgi-bin/admin.c:958 cgi-bin/admin.c:1319 +msgid "Unable to modify printer:" +msgstr "Tidak bisa mengubah pencetak" + +#: cgi-bin/ipp-var.c:428 cgi-bin/ipp-var.c:517 +msgid "Unable to move job" +msgstr "Tidak bisa memindahkan tugas" + +#: cgi-bin/ipp-var.c:430 cgi-bin/ipp-var.c:519 +msgid "Unable to move jobs" +msgstr "Tidak bisa memindahkan tugas" + +#: cups/ppd.c:336 +msgid "Unable to open PPD file" +msgstr "Tidak bisa membuka berkas PPD" + +#: cgi-bin/admin.c:3202 +msgid "Unable to open PPD file:" +msgstr "Tidak bisa membuka berkas PPD:" + +#: cgi-bin/admin.c:2582 +msgid "Unable to open cupsd.conf file:" +msgstr "Tidak bisa membuka berkas cupsd.conf:" + +#: scheduler/ipp.c:6710 +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Tidak bisa membuka dokumen %d pada tugas %d!" + +#: cgi-bin/ipp-var.c:790 +msgid "Unable to print test page:" +msgstr "Tidak bisa mencetak halaman uji:" + +#: cups/adminutil.c:2203 +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Tidak bisa menjalankan \"%s\": %s\n" + +#: cgi-bin/ipp-var.c:594 cgi-bin/ipp-var.c:614 +msgid "Unable to send command to printer driver!" +msgstr "" + +#: cups/adminutil.c:832 +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Tidak bisa mengeset penggerak pencetak Windows (%d)!" + +#: cgi-bin/admin.c:3791 +msgid "Unable to set options:" +msgstr "Tidak bisa mengeset opsi:" + +#: cgi-bin/admin.c:3093 +msgid "Unable to set server default:" +msgstr "" + +#: cgi-bin/admin.c:1886 +msgid "Unable to upload cupsd.conf file:" +msgstr "Tidak bisa mengunggah berkas cupsd.conf:" + +#: backend/usb-darwin.c:1953 backend/usb-darwin.c:1975 +msgid "Unable to use legacy USB class driver!\n" +msgstr "" + +#: cups/http-support.c:1215 +msgid "Unauthorized" +msgstr "Terlarang" + +#: cgi-bin/admin.c:3491 +msgid "Units" +msgstr "Unit" + +#: cups/http-support.c:1249 cups/ppd.c:360 +msgid "Unknown" +msgstr "Tak Dikenal" + +#: scheduler/ipp.c:10867 +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "printer-error-policy \"%s\" tak dikenal." + +#: scheduler/ipp.c:10850 +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "printer-op-policy \"%s\" tak dikenal." + +#: scheduler/ipp.c:418 +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Set karakter \"%s\" tak didukung!" + +#: scheduler/ipp.c:8563 scheduler/ipp.c:9798 +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Kompresi \"%s\" tak didukung!" + +#: scheduler/ipp.c:11297 +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Atribut kompresi %s tak didukung!" + +#: scheduler/ipp.c:11325 +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Format \"%s\" tak didukung!" + +#: scheduler/ipp.c:1420 scheduler/ipp.c:9932 +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Format '%s' tak didukung!" + +#: scheduler/ipp.c:8697 scheduler/ipp.c:9915 +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Format '%s/%s' tak didukung!" + +#: cups/snmp.c:1113 +msgid "Unsupported value type" +msgstr "Jenis nilai tak didukung" + +#: cups/http-support.c:1230 +msgid "Upgrade Required" +msgstr "Diperlukan Naik-Tingkat" + +#: systemv/lpadmin.c:805 +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Penggunaan:\n" +"\n" +" lpadmin [-h server] -d tujuan\n" +" lpadmin [-h server] -x tujuan\n" +" lpadmin [-h server] -p pencetak [-c tambah-kelas] [-i antarmuka] [-m " +"model]\n" +" [-r buang-kelas] [-v perangkat] [-D deskripsi]\n" +" [-P berkas-ppd] [-o nama=nilai]\n" +" [-u allow:pengguna,pengguna] [-u deny:pengguna," +"pengguna]\n" +"\n" + +#: filter/pdftops.c:103 +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Penggunaan: %s tugas pengguna judul salinan opsi [berkas]\n" + +#: backend/ipp.c:212 backend/lpd.c:184 backend/pap.c:228 +#: backend/parallel.c:127 backend/scsi.c:157 backend/serial.c:165 +#: backend/socket.c:132 backend/usb.c:183 filter/bannertops.c:118 +#: filter/hpgl-main.c:148 filter/imagetops.c:115 filter/imagetoraster.c:207 +#: filter/pstops.c:255 filter/rastertoepson.c:988 filter/rastertohp.c:713 +#: filter/rastertolabel.c:1135 filter/textcommon.c:518 +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Penggunaan: %s id-tugas pengguna judul rangkap opsi [berkas]\n" + +#: filter/gziptoany.c:53 +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Penggunaan: %s id-tugas pengguna judul rangkap opsi berkas\n" + +#: scheduler/cupsfilter.c:1329 +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +#: systemv/cupsaddsmb.c:286 +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Penggunaan: cupsaddsmb [opsi] pencetak1 ... pencetakN\n" +" cupsaddsmb [opsi] -a\n" +"\n" +"Opsi:\n" +" -E Mengenkripsi koneksi ke server\n" +" -H samba-server Menggunakan server SAMBA yang diberikan\n" +" -U samba-user Otentikasi menggunakan nama pengguna SAMBA yang " +"diberikan\n" +" -a Mengekspor semua pencetak\n" +" -h cups-server Menggunakan server CUPS yang ditentukan\n" +" -v Menjadi riuh (menampilkan perintah)\n" + +#: systemv/cupsctl.c:202 +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Penggunaan: cupsctl [opsi] [param=nilai ... paramN=nilaiN]\n" +"\n" +"Opsi:\n" +"\n" +" -E Mengaktifkan enkripsi\n" +" -U namapengguna Menentukan nama pengguna\n" +" -h server[:portal Menentukan alamat server\n" +"\n" +" --[no-]debug-logging Mengaktifkan/tidak pencatat debug\n" +" --[no-]remote-admin Mengaktifkan/tidak administrasi jarak jauh\n" +" --[no-]remote-any Biarkan/cegah akses dari Internet\n" +" --[no-]remote-printers Tampilkan/sembunyikan pencetak jarak jauh\n" +" --[no-]share-printers Mengaktifkan/tidak pencetak yang dikongsi\n" +" --[no-]user-cancel-any Biarkan/cegah pengguna biasa membatalkan tugas\n" + +#: scheduler/main.c:2128 +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Penggunaan: cupsd [-c berkas-konfigurasi] [-f] [-F] [-h] [-l]\n" +"\n" +"-c berkas-konfigurasi Memuat berkas konfigurasi alternatif\n" +"-f Berjalan pada latar depan\n" +"-F Berjalan pada latar depan tapi terpisah\n" +"-h Tampilkan pesan ini\n" +"-l Menjalankan cupsd dari launchd(8)\n" + +#: scheduler/cupsfilter.c:1316 +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" +"Penggunaan: cupsfilter -m mime/jenis [ opsi ] berkas\n" +"\n" +"Opsi:\n" +"\n" +" -c cupsd.conf Mengeset berkas cupsd.conf untuk digunakan\n" +" -e Menggunakan tiap penyaring dari berkas PPD\n" +" -j job-id[,N] Menyaring berkas N dari tugas yang diberikan (baku adalah berkas 1)\n" +" -n copies Mengeset banyaknya salinan\n" +" -o name=value Mengeset opsi\n" +" -p filename.ppd Mengeset berkas PPD\n" +" -t title Mengeset judul\n" + +#: systemv/cupstestdsc.c:430 +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Penggunaan: cupstestdsc [opsi] berkas.ps [... berkas.ps]\n" +" cupstestdsc [opsi] -\n" +"\n" +"Opsi:\n" +"\n" +" -h Menampilkan cara guna program\n" +"\n" +" Catatan: program ini hanya memvalidasi komentar DSC, bukan PostScript " +"itu sendiri.\n" + +#: systemv/cupstestppd.c:3483 +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" +"Penggunaan: cupstestppd [opsi] berkas1.ppd[.gz] [... berkasN.ppd[.gz]]\n" +" program | cupstestppd [opsi] -\n" +"\n" +"Opsi:\n" +"\n" +" -R direktori-root Mengeset root alternatif\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Menampilkan peringatan ketimbang kesalahan\n" +" -q Berjalan senyap\n" +" -r Menggunakan modus 'relaxed' terbuka\n" +" -v Menjadi riuh\n" +" -vv Menjadi sangat riuh\n" + +#: systemv/lpmove.c:132 +msgid "Usage: lpmove job/src dest\n" +msgstr "Penggunaan: lpmove tugas/sumber tujuan\n" + +#: systemv/lpoptions.c:540 +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Penggunaan: lpoptions [-h server] [-E] -d pencetak\n" +" lpoptions [-h server] [-E] [-p pencetak] -l\n" +" lpoptions [-h server] [-E] -p pencetak -o opsi[=nilai] ...\n" +" lpoptions [-h server] [-E] -x pencetak\n" + +#: systemv/lppasswd.c:493 +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Penggunaan: lppasswd [-g namakelompok]\n" + +#: systemv/lppasswd.c:496 +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Penggunaan: lppasswd [-g namakelompok] [namapengguna]\n" +" lppasswd [-g namakelompok] -a [namapengguna]\n" +" lppasswd [-g namakelompok] -x [namapengguna]\n" + +#: berkeley/lpq.c:662 +msgid "Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Penggunaan: lpq [-P tujuan] [-U namapengguna] [-h namahost[:portal]] [-l] " +"[+interval]\n" + +#: ppdc/ppdc.cxx:408 +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Penggunaan: ppdc [opsi] berkas.drv [ ... berkasN.drv ]\n" +"Opsi:\n" +" -D nama=nilai Atur nilai variabel bernama.\n" +" -I dir-inklusi Tambah direktori dalam jalur pencarian.\n" +" -c katalog.po Memuat katalog pesan yang diinginkan.\n" +" -d dir-keluaran Menentukan direktori keluaran.\n" +" -l bhsa[,bhsa,...] Menentukan bahasa keluaran (lokal).\n" +" -m Menggunakan nilai ModelName sebagai nama berkas.\n" +" -t Menguji PPD ketimbang membuatnya.\n" +" -v Menjadi riuh (tambahkan v lagi untuk lebih riuh).\n" +" -z Kompres berkas PPD dengan GNU zip.\n" +" --cr Akhiri baris dengan CR (Mac OS 9).\n" +" --crlf Akhiri baris dengan CR + LF (Windows).\n" +" --lf Akhiri baris dengan LF (UNIX/Linux/Mac OS X).\n" + +#: ppdc/ppdhtml.cxx:173 +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Penggunaan: ppdhtml [opsi] berkas.drv >berkas.html\n" +" -D nama=nilai Atur nilai variabel bernama.\n" +"Opsi:\n" +" -I dir-inklusi Tambah direktori dalam jalur pencarian.\n" + +#: ppdc/ppdi.cxx:129 +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Penggunaan: ppdi [opsi] berkas.ppd [ ... berkasN.ppd ]\n" +"Opsi:\n" +" -I direktori\n" +" -o berkas.drv\n" + +#: ppdc/ppdmerge.cxx:370 +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Penggunaan: ppdmerge [opsi] berkas.ppd [ ... berkasN.ppd ]\n" +"Opsi:\n" +" -o berkas.ppd[.gz]\n" + +#: ppdc/ppdpo.cxx:254 +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Penggunaan: ppdpo [opsi] -o berkas.po berkas.drv [ ... berkasN.drv ]\n" +"Opsi:\n" +" -D nama=nilai Mengeset nilai variabel bernama.\n" +" -I dir-inklusi Tambah direktori dalam jalur pencarian.\n" +" -v Menjadi riuh (tambahkan v lagi untuk lebih riuh).\n" + +#: backend/snmp.c:224 +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Penggunaan: snmp [host-atau-alamat-ip]\n" + +#: cups/snmp.c:1065 +msgid "Value uses indefinite length" +msgstr "Value memiliki panjang tak terdefinisi" + +#: cups/snmp.c:1050 +msgid "VarBind uses indefinite length" +msgstr "VarBind memiliki panjang tak terdefinisi" + +#: cups/snmp.c:1000 +msgid "Version uses indefinite length" +msgstr "Version memiliki panjang tak terdefinisi" + +#: backend/pap.c:328 +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Hanya menambah %d pencetak pertama yang ditemukan" + +#: backend/pap.c:1460 backend/usb-darwin.c:1816 +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Diharapkan boolean untuk opsi waiteof \"%s\"\n" + +#: backend/network.c:83 backend/pap.c:1293 backend/parallel.c:638 +#: backend/serial.c:1297 backend/usb-libusb.c:747 backend/usb-unix.c:583 +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Gagal membaca permintaan kanal sisi!\n" + +#: filter/pstops.c:2237 +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: Opsi \"%s\" tidak akan disertakan via IncludeFeature!\n" + +#: backend/pap.c:503 +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Pencetak tidak merespon!\n" + +#: backend/pap.c:831 backend/pap.c:854 +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Pencetak mengirim EOF yang tak diharapkan\n" + +#: backend/lpd.c:618 +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Host jarak jauh tidak merespon pada bita status perintah usai %d " +"detik!\n" + +#: backend/lpd.c:1042 backend/lpd.c:1189 +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Host jarak jauh tidak merespon pada bita kontrol status usai %d " +"detik!\n" + +#: backend/lpd.c:1134 +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Host jarak jauh tidak merespon pada bita status data usai %d " +"detik!\n" + +#: backend/scsi-irix.c:210 backend/scsi-linux.c:228 +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: Perintah SCSI kehabisan waktu (%d); mencoba ulang...\n" + +#: filter/pstops.c:1096 +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Dokumen ini tidak sesuai dengan Adobe Document Structuring " +"Conventions dan mungkin tidak tercetak dengan benar!\n" + +#: backend/pap.c:492 +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Tidak bisa membuka \"%s:%s\": %s\n" + +#: backend/pap.c:637 +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Tidak bisa mengirim permintaan status PAP" + +#: backend/pap.c:867 +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "" + +#: backend/pap.c:872 +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Paket PAP berjenis %d tak dikenal\n" + +#: filter/pstops.c:2245 +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Pilihan \"%s\" tak dikenal untuk opsi \"%s\"!\n" + +#: filter/pstops.c:2230 +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Opsi \"%s\" tak dikenal!\n" + +#: backend/serial.c:380 +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "" + +#: backend/pap.c:1474 +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: angka diharapkan untuk opsi status \"%s\"\n" + +#: backend/ipp.c:588 backend/ipp.c:723 backend/lpd.c:855 backend/socket.c:317 +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" + +#: cups/adminutil.c:804 +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Peringatan, tak ada penggerak pencetak Windows 2000 yang terpasang!" + +#: cups/ppd.c:1875 +msgid "Yes" +msgstr "Ya" + +#: scheduler/client.c:2402 +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Anda harus mengakses halaman ini melalui URL https://%s:%d%s." + +#: ppdc/sample.c:87 +msgid "You4 Envelope" +msgstr "You4 Amplop" + +#: ppdc/sample.c:410 +msgid "ZPL Label Printer" +msgstr "Pencetak Label ZPL" + +#: ppdc/sample.c:333 +msgid "Zebra" +msgstr "Zebra" + +#: cups/notify.c:102 +msgid "aborted" +msgstr "digagalkan" + +#: cups/notify.c:99 +msgid "canceled" +msgstr "dibatalkan" + +#: cups/notify.c:105 +msgid "completed" +msgstr "diselesaikan" + +#: scheduler/cupsfilter.c:342 +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "konversi: Gunakan opsi -f untuk menentukan berkas yang hendak dikonversi.\n" + +#: scheduler/ipp.c:6583 +msgid "cups-deviced failed to execute." +msgstr "cups-deviced gagal dieksekusi." + +#: scheduler/ipp.c:7259 scheduler/ipp.c:7509 +msgid "cups-driverd failed to execute." +msgstr "cups-driverd gagal dieksekusi." + +#: systemv/cupsaddsmb.c:236 +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Tidak ada berkas PPD untuk pencetak \"%s\" - %s\n" + +#: systemv/cupsctl.c:153 +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Tidak bisa menghubungi server: %s\n" + +#: systemv/cupsctl.c:196 +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Opsi tak dikenal \"%s\"!\n" + +#: systemv/cupsctl.c:198 +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Opsi tak dikenal \"-%c\"!\n" + +#: scheduler/main.c:200 +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Diharapkan nama berkas konfigurasi usai opsi \"-c\"!\n" + +#: scheduler/main.c:232 scheduler/main.c:239 +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Tidak bisa memperoleh direktori sekarang!\n" + +#: scheduler/main.c:303 +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Argumen \"%s\" tak dikenal - digagalkan!\n" + +#: scheduler/main.c:296 +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Opsi \"%c\" tak dikenal - digagalkan!\n" + +#: scheduler/main.c:266 +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: dukungan launchd(8) tidak dikompilasi serta, menjalankan dalam modus " +"normal.\n" + +#: scheduler/cupsfilter.c:1094 +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Jumlah dokumen %d tidak sah!\n" + +#: scheduler/cupsfilter.c:1088 +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: ID tugas %d tak sah!\n" + +#: scheduler/cupsfilter.c:350 +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Hanya satu nama berkas yang bisa ditentukan!\n" + +#: scheduler/cupsfilter.c:1136 +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Tidak bisa memperoleh berkas tugas - %s\n" + +#: systemv/cupstestppd.c:389 +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: Opsi -q tidak cocok dengan opsi -v.\n" + +#: systemv/cupstestppd.c:405 +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: Opsi -v tidak cocok dengan opsi -q.\n" + +#: systemv/lpstat.c:1231 systemv/lpstat.c:1234 systemv/lpstat.c:1237 +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "perangkat untuk %s/%s: %s\n" + +#: systemv/lpstat.c:1218 systemv/lpstat.c:1221 systemv/lpstat.c:1224 +#, c-format +msgid "device for %s: %s\n" +msgstr "perangkat untuk %s: %s\n" + +#: cups/snmp.c:1037 +msgid "error-index uses indefinite length" +msgstr "error-index memiliki panjang tak terdefinisi" + +#: cups/snmp.c:1029 +msgid "error-status uses indefinite length" +msgstr "error-status memiliki panjang tak terdefinisi" + +#: cups/notify.c:90 +msgid "held" +msgstr "ditahan" + +#: berkeley/lpc.c:214 +msgid "help\t\tget help on commands\n" +msgstr "bantuan\t\tmemperoleh bantuan dari baris perintah\n" + +#: cups/notify.c:131 +msgid "idle" +msgstr "menganggur" + +#: scheduler/ipp.c:8232 +msgid "job-printer-uri attribute missing!" +msgstr "Atribut job-printer-uri hilang!" + +#: systemv/lpadmin.c:141 systemv/lpadmin.c:453 +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Nama kelas hanya boleh diisi karakter cetak!\n" + +#: systemv/lpadmin.c:750 +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: Diharapkan PPD usai opsi '-P'!\n" + +#: systemv/lpadmin.c:491 +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Diharapkan allow/deny:daftarpengguna usai opsi '-u'!\n" + +#: systemv/lpadmin.c:442 +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Diharapkan kelas usai opsi '-r'!\n" + +#: systemv/lpadmin.c:130 +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Diharapkan nama kelas usai opsi '-c'!\n" + +#: systemv/lpadmin.c:643 +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Diharapkan deskripsi usai opsi '-D'!\n" + +#: systemv/lpadmin.c:550 +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Diharapkan URI perangkat usai opsi '-v'!\n" + +#: systemv/lpadmin.c:659 +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Diharapkan jenis berkas usai opsi '-I'!\n" + +#: systemv/lpadmin.c:212 +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Diharapkan nama host usai opsi '-h'!\n" + +#: systemv/lpadmin.c:257 +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Diharapkan antarmuka usai opsi '-i'!\n" + +#: systemv/lpadmin.c:704 +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Diharapkan lokasi usai opsi '-L'!\n" + +#: systemv/lpadmin.c:338 +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Diharapkan model usai opsi '-m'!\n" + +#: systemv/lpadmin.c:358 +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Diharapkan nama=nilai usai opsi '-o'!\n" + +#: systemv/lpadmin.c:391 +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Diharapkan pencetak usai opsi '-p'!\n" + +#: systemv/lpadmin.c:174 +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Diharapkan nama pencetak usai opsi '-d'!\n" + +#: systemv/lpadmin.c:584 +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Diharapkan pencetak atau kelas usai opsi '-x'!\n" + +#: systemv/lpadmin.c:1128 +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Tidak ada nama anggota yang terlihat!\n" + +#: systemv/lpadmin.c:893 +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Pencetak %s sudah menjadi anggota kelas %s.\n" + +#: systemv/lpadmin.c:1142 +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Pencetak %s bukanlah anggota kelas %s.\n" + +#: systemv/lpadmin.c:185 systemv/lpadmin.c:402 systemv/lpadmin.c:595 +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Nama pencetak hanya bisa mengandung karakter cetak!\n" + +#: systemv/lpadmin.c:115 +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa menambah pencetak ke kelas:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:106 systemv/lpadmin.c:159 systemv/lpadmin.c:230 +#: systemv/lpadmin.c:291 systemv/lpadmin.c:310 systemv/lpadmin.c:376 +#: systemv/lpadmin.c:417 systemv/lpadmin.c:523 systemv/lpadmin.c:569 +#: systemv/lpadmin.c:615 systemv/lpadmin.c:677 systemv/lpadmin.c:723 +#: systemv/lpadmin.c:784 +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Tidak bisa terkoneksi ke server: %s\n" + +#: systemv/lpadmin.c:1851 +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Tidak bisa membuka berkas PPD \"%s\" - %s\n" + +#: systemv/lpadmin.c:1460 +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Tidak bisa membuka berkas \"%s\": %s\n" + +#: systemv/lpadmin.c:426 +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa membuang pencetak dari kelas:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:732 +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset berkas PPD:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:532 +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset URI perangkat:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:319 +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset skrip antarmuka atau berkas PPD:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:239 +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset skrip antarmuka:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:624 +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset deskripsi pencetak:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:686 +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset lokasi pencetak:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:793 +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Tidak bisa mengeset opsi pencetak:\n" +" Anda harus menentukan nama pencetak lebih dulu!\n" + +#: systemv/lpadmin.c:508 +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Opsi boleh/larang tak dikenal \"%s\"!\n" + +#: systemv/lpadmin.c:766 +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Argumen tak dikenal '%s'!\n" + +#: systemv/lpadmin.c:761 +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Opsi tak dikenal '%c'!\n" + +#: systemv/lpadmin.c:665 +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Peringatan - jenis isi diabaikan!\n" + +#: berkeley/lpc.c:81 berkeley/lpc.c:109 berkeley/lpc.c:145 +msgid "lpc> " +msgstr "lpc> " + +#: systemv/lpinfo.c:143 +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" + +#: systemv/lpinfo.c:196 +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Diharapkan bahasa usai --language!\n" + +#: systemv/lpinfo.c:213 +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Diharapkan pembuat dan model usai --make-and-model!\n" + +#: systemv/lpinfo.c:230 +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Diharapkan string produk usai --product!\n" + +#: systemv/lpinfo.c:161 +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Diharapkan daftar skema usai --exclude-scemes!\n" + +#: systemv/lpinfo.c:179 +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Diharapkan daftar skema usai --include-schemes!\n" + +#: systemv/lpinfo.c:247 +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Diharapkan waktu habis usai --timeout!\n" + +#: systemv/lpinfo.c:270 +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Argumen tak dikenal '%s'!\n" + +#: systemv/lpinfo.c:264 +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Opsi tak dikenal '%c'!\n" + +#: systemv/lpinfo.c:257 +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Opsi tak dikenal '%s'!\n" + +#: systemv/lpmove.c:141 +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Tidak bisa terkoneksi ke server: %s\n" + +#: systemv/lpmove.c:125 +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Argumen tak dikenal '%s'!\n" + +#: systemv/lpmove.c:103 +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Opsi tak dikenal '%c'!\n" + +#: systemv/lpoptions.c:154 systemv/lpoptions.c:172 systemv/lpoptions.c:248 +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Tidak ada pencetak!?!\n" + +#: systemv/lpoptions.c:223 +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Tidak bisa menambah pencetak: %s\n" + +#: systemv/lpoptions.c:507 +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Tidak bisa mendapatkan berkas PPD untuk %s: %s\n" + +#: systemv/lpoptions.c:516 +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Tidak bisa membuka berkas PPD untuk %s!\n" + +#: systemv/lpoptions.c:104 +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Pencetak atau kelas tak dikenal!\n" + +#: systemv/lppasswd.c:185 +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Hanya root yang bisa menambah atau menghapus sandi!\n" + +#: systemv/lppasswd.c:314 +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Berkas sandi sedang sibuk!\n" + +#: systemv/lppasswd.c:447 +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Berkas sandi tidak diperbaharui!\n" + +#: systemv/lppasswd.c:414 +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Maaf, sandi tidak cocok!\n" + +#: systemv/lppasswd.c:264 +msgid "" +"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" +msgstr "" +"lppasswd: Maaf, sandi ditolak.\n" +"Sandi Anda harus setidaknya 6 karakter, tidak memuat\n" +"nama pengguna Anda, dan setidaknya memiliki satu huruf serta angka.\n" + +#: systemv/lppasswd.c:240 +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Maaf, sandi tidak cocok!\n" + +#: systemv/lppasswd.c:211 systemv/lppasswd.c:229 +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Tidak bisa menyalin string sandi: %s\n" + +#: systemv/lppasswd.c:317 systemv/lppasswd.c:326 systemv/lppasswd.c:344 +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Tidak bisa membuka berkas sandi: %s\n" + +#: systemv/lppasswd.c:379 systemv/lppasswd.c:392 systemv/lppasswd.c:424 +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Tidak bisa menulis ke berkas sandi: %s\n" + +#: systemv/lppasswd.c:462 +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: gagal mencadangkan berkas sandi yang lama: %s\n" + +#: systemv/lppasswd.c:475 +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: gagal mengubah nama berkas sandi: %s\n" + +#: systemv/lppasswd.c:404 +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: pengguna \"%s\" dan kelompok \"%s\" tidak ada.\n" + +#: systemv/lpstat.c:1039 +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: kesalahan - nama variabel lingkungan %s bukanlah tujuan yang ada \"%s" +"\"!\n" + +#: systemv/lpstat.c:969 +#, c-format +msgid "members of class %s:\n" +msgstr "anggota kelas %s:\n" + +#: berkeley/lpq.c:574 +msgid "no entries\n" +msgstr "tak ada entri\n" + +#: systemv/lpstat.c:1043 +msgid "no system default destination\n" +msgstr "tak ada tujuan sistem utama\n" + +#: scheduler/ipp.c:6277 +msgid "notify-events not specified!" +msgstr "notify-events tidak dispesifikasikan!" + +#: scheduler/ipp.c:2114 scheduler/ipp.c:6182 +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "URI notify-recipient-uri \"%s\" sudah dipakai!" + +#: scheduler/ipp.c:2104 scheduler/ipp.c:6172 +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "URI notify-recipient-uri \"%s\" memakai skema tak dikenal!" + +#: scheduler/ipp.c:4145 scheduler/ipp.c:7107 scheduler/ipp.c:7813 +#: scheduler/ipp.c:9278 +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d tidak baik!" + +#: cups/notify.c:87 +msgid "pending" +msgstr "tunda" + +#: ppdc/ppdc.cxx:107 ppdc/ppdpo.cxx:93 +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Menambahkan direktori \"%s\"...\n" + +#: ppdc/ppdpo.cxx:135 +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdf: Menambah/memperbaharui teks UI dari %s...\n" + +#: ppdc/ppdc-source.cxx:413 +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Nilai boolean jelek (%s) pada baris %d dari %s.\n" + +#: ppdc/ppdc-source.cxx:1798 +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Nama resolusi jelek \"%s\" pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1116 +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Kata kunci status jelek %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:2035 +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Subtitusi variabel jelek ($%c) pada baris %d dari %s.\n" + +#: ppdc/ppdc-source.cxx:2711 +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Ditemukan pilihan pada baris %d dari %s tanpa Option!\n" + +#: ppdc/ppdc-source.cxx:1700 +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Duplikat #po untuk lokal %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:935 +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Diharapkan definisi penyaring pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:958 +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama program pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:397 +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Diharapkan nilai boolean pada baris %d dari %s.\n" + +#: ppdc/ppdc-source.cxx:1096 +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:450 +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Diharapkan kode pilihan pada baris %d dari %s.\n" + +#: ppdc/ppdc-source.cxx:438 +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Diharapkan nama/teks pilihan pada baris %d dari %s.\n" + +#: ppdc/ppdc-source.cxx:506 +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Diharapkan urutan warna untuk ColorModel pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:495 +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Diharapkan ruang warna untuk ColorModel pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:517 +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Diharapkan kompresi untuk ColorModel pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:698 +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc: Diharapkan string konstrain untuk UIConstraints pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:2897 +#, c-format +msgid "ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "ppdc: Diharapkan kata kunci jenis penggerak diikuti DriverType pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:829 +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Diharapkan jenis dupleks usai Duplex pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1080 +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Diharapkan enkode usai Font pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1691 +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama berkas usai #po %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1208 +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama/teks kelompok pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:2611 +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama berkas yang disertakan pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1504 +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Diharapkan integer pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1683 +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Diharapkan lokal usai #po pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:356 +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3269 +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai FileName pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1061 +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai Font pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3100 +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai Manufacturer pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3133 +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai MediaSize pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3223 +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai ModelName pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3286 +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama usai PCFileName pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1159 +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama/teks usai %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1248 +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama/teks usai Installable pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1784 +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama/teks usai Resolution pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:482 +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "ppdc: Diharapkan nama/teks kombinasi untuk ColorModel pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1576 +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Diharapkan opsi nama/teks pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1610 +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Diharapkan opsi seksi pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1588 +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Diharapkan opsi jenis pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1767 +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1007 +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Diharapkan bilangan real pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:575 +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "ppdc: Diharapkan resolusi/jenis media diikuti ColorProfile pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1865 +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "ppdc: Diharapkan resolusi/jenis media diikuti SimpleColorProfile pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:364 +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Diharapan selektor usai %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1104 +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Diharapkan status usai Font pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:2786 +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Diharapkan string usai Copyright pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3389 +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Diharapkan string usai Version pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:731 +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Diharapkan dua opsi nama pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:375 +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Diharapkan nilai usai %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1088 +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Diharapkan versi usai Font pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:230 +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Nama berkas #include/#po \"%s\" tak sah!\n" + +#: ppdc/ppdc-source.cxx:975 +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Nilai tak sah bagi penyaring pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:967 +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Jenis MIME kosong tak sah untuk penyaring pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:983 +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Nama program korong tak sah untuk penyaring pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1630 +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Seksi opsi \"%s\" tak sah pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:1602 +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Jenis opsi \"%s\" tak sah pada baris %d dari %s!\n" + +#: ppdc/ppdc.cxx:243 ppdc/ppdpo.cxx:123 +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Memuat berkas informasi penggerak \"%s\"...\n" + +#: ppdc/ppdc.cxx:179 +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Memuat pesan untuk loakl \"%s\"...\n" + +#: ppdc/ppdc.cxx:120 +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Memuat pesan dari \"%s\"...\n" + +#: ppdc/ppdc-source.cxx:2404 ppdc/ppdc-source.cxx:2636 +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: Kehilangan #endif di akhir \"%s\"!\n" + +#: ppdc/ppdc-source.cxx:2505 ppdc/ppdc-source.cxx:2540 +#: ppdc/ppdc-source.cxx:2570 +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: Kehilangan #if pada baris %d dari %s!\n" + +#: ppdc/ppdc-driver.cxx:722 +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Tak tersedia katalog pesan untuk lokal %s!\n" + +#: ppdc/ppdc-source.cxx:1653 ppdc/ppdc-source.cxx:2874 +#: ppdc/ppdc-source.cxx:2960 ppdc/ppdc-source.cxx:3053 +#: ppdc/ppdc-source.cxx:3186 ppdc/ppdc-source.cxx:3319 +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1646 +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:708 +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2487 +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Terlalu banyak #if bersarang pada baris %d dari %s!\n" + +#: ppdc/ppdc.cxx:346 +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: Tidak bisa membuat berkas PPD \"%s\" - %s.\n" + +#: ppdc/ppdc.cxx:258 +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Tidak bisa membuat direktori keluaran %s: %s\n" + +#: ppdc/ppdc.cxx:279 +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Tidak bisa membuat pipa keluaran: %s\n" + +#: ppdc/ppdc.cxx:295 ppdc/ppdc.cxx:302 +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Tidak bisa mengeksekusi cupstestppd: %s\n" + +#: ppdc/ppdc-source.cxx:1732 +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Tidak bisa menemukan berkas #po %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:2643 +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tidak bisa menemukan berkas yang disertakan \"%s\" pada baris %d dari %s!\n" + +#: ppdc/ppdc.cxx:190 +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Tidak bisa menemukan lokalisasi bagi \"%s\" - %s\n" + +#: ppdc/ppdc.cxx:129 +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Tidak bisa memuat berkas lokalisasi \"%s\" - %s\n" + +#: ppdc/ppdc-source.cxx:2056 +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Variabel tak berdefinisi (%s) pada baris %d dari %s.\n" + +#: ppdc/ppdc-source.cxx:2916 +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Jenis penggerak tak dikenal %s pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:909 +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Jenis dupleks tak dikenal \"%s\" pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3146 +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ukuran media tak dikenal \"%s\" pada baris %d dari %s!\n" + +#: ppdc/ppdc-source.cxx:3400 +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:1017 +#, c-format +msgid "ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc-source.cxx:2166 +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "" + +#: ppdc/ppdc.cxx:352 +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Menulis %s...\n" + +#: ppdc/ppdc.cxx:142 +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Menulis berkas PPD ke direktori \"%s\"...\n" + +#: ppdc/ppdmerge.cxx:138 +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: LanguageVersion \"%s\" jelek pada %s!\n" + +#: ppdc/ppdmerge.cxx:178 +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Mengabaikan berkas PPD %s...\n" + +#: ppdc/ppdmerge.cxx:162 +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Tidak bisa mencadangkan %s ke %s- %s\n" + +#: systemv/lpstat.c:1769 +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "pencetak %s ditiadakan sejak %s -\n" + +#: systemv/lpstat.c:1758 +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "pencetak %s sedang menganggur. diaktifkan sejak %s\n" + +#: systemv/lpstat.c:1763 +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "pencetak %s saat ini tengah mencetak %s-%d. diaktifkan sejak %s\n" + +#: systemv/lpstat.c:1881 +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "pencetak %s/%s dinonaktifkan sejak %s -\n" + +#: systemv/lpstat.c:1867 +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "pencetak %s/%s sedang menganggur. diaktifkan sejak %s\n" + +#: systemv/lpstat.c:1874 +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "pencetak %s/%s saat ini tengah mencetak %s-%d. diaktifkan sejak %s\n" + +#: cups/notify.c:93 cups/notify.c:134 +msgid "processing" +msgstr "memproses" + +#: systemv/lp.c:660 +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "identitas permintaan adalah %s-%d (%d berkas)\n" + +#: cups/snmp.c:1021 +msgid "request-id uses indefinite length" +msgstr "request-id memiliki panjang tak terdefinisi" + +#: systemv/lpstat.c:2008 +msgid "scheduler is not running\n" +msgstr "penjadwal tidak berjalan\n" + +#: systemv/lpstat.c:2004 +msgid "scheduler is running\n" +msgstr "penjadwal tengah berjalan\n" + +#: cups/adminutil.c:2274 +#, c-format +msgid "stat of %s failed: %s" +msgstr "status dari %s gagal: %s" + +#: berkeley/lpc.c:216 +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tmenampilkan status daemon dan antrian\n" + +#: cups/notify.c:96 cups/notify.c:137 +msgid "stopped" +msgstr "dihentikan" + +#: systemv/lpstat.c:1017 +#, c-format +msgid "system default destination: %s\n" +msgstr "tujuan utama sistem: %s\n" + +#: systemv/lpstat.c:1014 +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "tujuan utama sistem: %s/%s\n" + +#: cups/notify.c:108 cups/notify.c:140 +msgid "unknown" +msgstr "tak dikenal" + +#: cups/notify.c:117 +msgid "untitled" +msgstr "tak berjudul" + +#: cups/snmp.c:1046 +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings memiliki panjang tak terdefinisi" + + +# +# End of "$Id$". +# diff --git a/locale/cups_it.po b/locale/cups_it.po new file mode 100644 index 0000000000..8c33980a8c --- /dev/null +++ b/locale/cups_it.po @@ -0,0 +1,5546 @@ +# Vincenzo Reale , 2009. +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2010-01-10 01:03+0100\n" +"Last-Translator: Vincenzo Reale \n" +"Language-Team: Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(tutti)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(nessuno)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d voci\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tDopo il fallimento: continua\n" + +msgid "\tAlerts:" +msgstr "\tAvvisi:" + +msgid "\tBanner required\n" +msgstr "\tBanner richiesto\n" + +msgid "\tCharset sets:\n" +msgstr "\tSet di caratteri:\n" + +msgid "\tConnection: direct\n" +msgstr "\tConnessione: diretta\n" + +msgid "\tConnection: remote\n" +msgstr "\tConnessione: remota\n" + +msgid "\tDefault page size:\n" +msgstr "\tDimensioni predefinite pagina:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tTono predefinito:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tImpostazioni predefinite porta:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDescrizione: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tModulo montato:\n" +"\tTipi di contenuto: qualsiasi\n" +"\tTipi di stampante: sconosciuti\n" + +msgid "\tForms allowed:\n" +msgstr "\tModuli consentiti:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterfaccia: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterfaccia: %s/interfacce/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterfaccia: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tPosizione: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tIn caso di fallimento: nessun avviso\n" + +msgid "\tUsers allowed:\n" +msgstr "\tUtenti autorizzati:\n" + +msgid "\tUsers denied:\n" +msgstr "\tUtenti non autorizzati:\n" + +msgid "\tdaemon present\n" +msgstr "\tpresente demone\n" + +msgid "\tno entries\n" +msgstr "\tnessuna voce\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tla stampante è sul dispositivo '%s' velocità -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tla stampa è disabilitata\n" + +msgid "\tprinting is enabled\n" +msgstr "\tla stampa è abilitata\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tin coda per %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tla coda è disabilitata\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tla coda è abilitata\n" + +msgid "\treason unknown\n" +msgstr "\tmotivo sconosciuto\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" RISULTATI DETTAGLIATI DEL TEST DI CONFORMITÀ\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " RIF: pagina 15, sezione 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " RIF: pagina 15, sezione 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " RIF: pagina 19, sezione 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " RIF: pagina 20, sezione 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " RIF: pagina 27, sezione 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " RIF: pagina 42, sezione 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " RIF: pagine 16-17, sezione 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " RIF: pagine 42-45, sezione 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " RIF: pagine 45-46, sezione 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " RIF: pagine 48-49, sezione 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " RIF: pagine 52-54, sezione 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f byte\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Produttore\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Prodotto\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\" è in conflitto con \"%s %s\"\n" +" (limitazione=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s non ha opzioni corrispondenti!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s condivide un prefisso comune con %s\n" +" RIF: pagina 15, sezione 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Conflitto tra le scelte predefinite!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN La parola chiave Duplex %s potrebbe non funzionare correttamente e dovrebbe essere Duplex!\n" +" RIF: pagina 122, sezione 5.17\n" + +msgid " WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr " WARN Il documento contiene un misto di interruzioni di riga CR, LF e CR LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding richiesto dalla specifica PPD 4.3.\n" +" RIF: pagine 56-57, sezione 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN La riga %d contiene solamente spazi bianchi!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Produttore richiesto dalla specifica PPD 4.3.\n" +" RIF: pagine 58-59, sezione 5.3.\n" + +msgid " WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n" +msgstr " WARN I documenti PPD per sistemi diversi da Windows dovrebbero usare solo interruzioni di riga LF, non CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Versione PPD %.1f obsoleta!\n" +" RIF: pagina 42, sezione 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName maggiore di 8.3 in violazione della specifica PPD.\n" +" RIF: pagine 61-62, sezione 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols contiene PJL, ma gli attributi JCL non sono impostati.\n" +" RIF: pagine 78-79, sezione 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols contiene sia PJL che BCP; atteso TBCP.\n" +" RIF: pagine 78-79, sezione 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName richiesto dalla specifica PPD 4.3.\n" +" RIF: pagine 64-65, sezione 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s non esiste!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr " %s %s il file \"%s\" ha una capitalizzazione errata!\n" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Errato %s scelta %s!\n" +" Rif: pagina 122, sezione 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Stringa traduzione UTF-8 \"%s\" errata per l'opzione %s!\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s Stringa traduzione UTF-8 \"%s\" errata per l'opzione %s, scelta %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Valore cupsFilter \"%s\" errato!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s cupsICCProfile %s errato!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Valore cupsPreFilter \"%s\" errato!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s cupsUIConstraints %s errato: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s lingua \"%s\" errata!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr " %s Ortografia non corretta di %s - dovrebbe essere %s!\n" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr " %s Impossibile fornire contemporaneamente APScanAppPath e APScanAppBundleID!\n" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints %s vuoto!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Manca stringa traduzione \"%s\" per l'opzione %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s Manca stringa traduzione \"%s\" per l'opzione %s, scelta %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr " %s File APDialogExtension \"%s\" mancante\n" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr " %s File APPrinterIconPath \"%s\" mancante\n" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr " %s File APPrinterLowInkTool \"%s\" mancante\n" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr " %s File APPrinterUtilityPath \"%s\" mancante\n" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr " %s File APScanAppPath \"%s\" mancante\n" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" %s Opzione RICHIESTA PageRegion mancante!\n" +" REF: Pagina 100, sezione 5.14.\n" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" %s Opzione RICHIESTA PageSize mancante!\n" +" REF: Pagina 99, sezione 5.14.\n" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Manca stringa traduzione *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Manca stringa traduzione *%s %s in cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Documento cupsFilter \"%s\" mancante!\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Documento cupsICCProfile \"%s\" mancante!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Documento cupsPreFilter \"%s\" mancante\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s cupsUIResolver %s mancante!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Manca opzione %s in UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Manca opzione %s in cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Nessuna traduzione base \"%s\" è compresa nel documento!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" +" %s Dimensione del nome \"%s\" non standard!\n" +" REF: Pagina 187, sezione B.2.\n" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s %s RICHIESTO non definisce la scelta Nessuno!\n" +" RIF: pagina 122, sezione 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr " %s Dimensione \"%s\" definita per %s ma non per %s.\n" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr " %s La misura \"%s\" ha dimensioni inattese (%gx%g)!\n" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s il valore hash cupsICCProfile %s si scontra con %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s causa un loop!\n" + +#, c-format +msgid " %s cupsUIResolver %s does not list at least two different options!\n" +msgstr " %s il cupsUIResolver %s non elenca almeno due diverse opzioni.\n" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr " **FAIL** %s i nomi di scelta %s e %s differiscono solo per maiuscole e minuscole!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s deve essere 1284DeviceID!\n" +" RIF: pagina 72, sezione 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** Default%s %s ERRATO\n" +" RIF: pagina 40, sezione 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DefaultImageableArea %s ERRATO!\n" +" RIF: pagina 102, sezione 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DefaultPaperDimension %s ERRATO!\n" +" RIF: pagina 103, sezione 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** Attributo JobPatchFile ERRATO nel documento\n" +" RIF: pagina 24, sezione 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** Produttore ERRATO (dovrebbe essere \"HP\")\n" +" RIF: pagina 211, tabella D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** Produttore ERRATO (dovrebbe essere \"Oki\")\n" +" RIF: pagina 211, tabella D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ModelName ERRATO: \"%c\" non consentito nella stringa.\n" +" RIF: pagine 59-60, sezione 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** PSVersion ERRATO: non è \"(string) int\".\n" +" RIF: pagine 62-64, sezione 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** Product ERRATO: non è \"(string)\".\n" +" RIF: pagine 62, sezione 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ShortNickName ERRATO: maggiore di 31 caratteri.\n" +" RIF: pagine 64-65, sezione 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Scelta %s Errata %s \n" +" RIF: pagina 84, sezione 5.9.\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FileVersion \"%s\" Errata \n" +" RIF: pagina 56, sezione 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FormatVersion \"%s\" Errata \n" +" RIF: pagina 56, sezione 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** LanguageEncoding %s: deve essere ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** LanguageVersion %s errata: deve essere inglese!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **FAIL** Impossibile interpretare il codice opzione di default: %s\n" + +#, c-format +msgid " **FAIL** Default translation string for option %s choice %s contains 8-bit characters!\n" +msgstr " **FAIL** La stringa di traduzione predefinita per l'opzione %s scelta %s contiene caratteri di 8-bit!\n" + +#, c-format +msgid " **FAIL** Default translation string for option %s contains 8-bit characters!\n" +msgstr " **FAIL** La stringa di traduzione predefinita per l'opzione %s contiene caratteri di 8-bit!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr " **FAIL** I nomi dei gruppi %s e %s differiscono solo per maiuscole e minuscole!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Varie occorrenze dei nomi di scelta %s %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr " **FAIL** i nomi delle opzioni %s e %s differiscono solo per maiuscole e minuscole!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** RICHIESTO Default%s\n" +" RIF: pagina 40, sezione 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** RICHIESTO DefaultImageableArea\n" +" RIF: pagina 102, sezione 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** RICHIESTO DefaultPaperDimension\n" +" RIF: pagina 103, sezione 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO FileVersion\n" +" RIF: pagina 56, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO FormatVersion\n" +" RIF: pagina 56, sezione 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** RICHIESTO ImageableArea per PageSize %s\n" +" RIF: pagina 41, sezione 5.\n" +" RIF: pagina 102, sezione 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO LanguageEncoding\n" +" RIF: pagine 56-57, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO LanguageVersion\n" +" RIF: pagine 57-58, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO Produttore\n" +" RIF: pagine 58-59, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO ModelName\n" +" RIF: pagine 59-60, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO NickName\n" +" RIF: pagina 60, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO PCFileName\n" +" RIF: pagine 61-62, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO PSVersion\n" +" RIF: pagine 62-64, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** RICHIESTO PageRegion\n" +" RIF: pagina 100, sezione 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** RICHIESTO PageSize\n" +" RIF: pagina 41, sezione 5.\n" +" RIF: pagina 99, sezione 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** RICHIESTO PageSize\n" +" RIF: pagine 99-100, sezione 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** RICHIESTO PaperDimension per PageSize %s\n" +" RIF: pagina 41, sezione 5.\n" +" RIF: pagina 103, sezione 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO prodotto\n" +" RIF: pagina 62, sezione 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** RICHIESTO ShortNickName\n" +" RIF: pagina 64-65, sezione 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERRORI RILEVATI\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" %%%%BoundingBox: errato alla riga %d!\n" +" RIF: pagina 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" %%%%Page: errato alla riga %d!\n" +" RIF: pagina 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" %%%%Pages: errato alla riga %d!\n" +" RIF: pagina 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" La riga %d eccede i 255 caratteri (%d)!\n" +" RIF: pagina 25, lunghezza della riga\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 mancante alla prima riga!\n" +" RIF: pagina 17, 3.1 uniformare documenti\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Commento %%EndComments mancante!\n" +" RIF: pagina 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Commento %%BoundingBox: mancante o errato!\n" +" RIF: pagina 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Commenti %%Page: mancante o errato!\n" +" RIF: pagina 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Commento %%Pages: mancante o errato!\n" +" RIF: pagina 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " NESSUN ERRORE RILEVATO\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Trovate %d righe che eccedono i 255 caratteri!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Troppi commenti %%BeginDocument!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Troppi commenti %%EndDocument!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Attenzione: il documento contiene dati binari!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Attenzione: nessun commento %%EndComments nel documento!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Attenzione: versione DSC %.1f obsoleta nel documento!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** Impossibile aprire il documento PPD: %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** Impossibile aprire il file PPD: %s alla riga %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "Busta num. 10" + +msgid "#11 Envelope" +msgstr "Busta num. 11" + +msgid "#12 Envelope" +msgstr "Busta num. 12" + +msgid "#14 Envelope" +msgstr "Busta num. 14" + +msgid "#9 Envelope" +msgstr "Busta num. 9" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f byte\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f byte\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f millimetri" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f a %.0f x %.0f millimetri" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f pollici" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f a %.2f x %.2f pollici" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s accetta richieste da %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s non può essere modificato." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s non è implementato dalla versione CUPS di lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s non è pronta\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s è pronta\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s è pronta e stampa\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s non accetta richieste da %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s non supportato!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s accetta richieste da %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s non accetta richieste da %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [operazione localhost %d]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s fallito: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: non so cosa fare!\n" + +#, c-format +msgid "%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: Errore: i nomi della variabile d'ambiente %s non esistono nella destinazione \"%s\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Errore: ID dell'operazione errato!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s: Errore: impossibile stampare documenti e modificare operazioni contemporaneamente!\n" + +#, c-format +msgid "%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "%s: Errore: impossibile stampare da stdin se vengono forniti documenti o ID dell'operazione!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Errore: atteso set di caratteri dopo l'opzione '-S'!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Errore: atteso tipo di contenuto dopo l'opzione '-T'!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Errore: attese copie dopo l'opzione '-n'!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Errore: atteso numero di copie dopo l'opzione '-#'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Errore: attesa destinazione dopo l'opzione '-P'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Errore: attesa destinazione dopo l'opzione '-b'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Errore: attesa destinazione dopo l'opzione '-d'!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Errore: atteso modulo dopo l'opzione '-f'!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Errore: atteso nome di blocco dopo l'opzione '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Errore: atteso hostname dopo l'opzione '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Errore: atteso hostname dopo l'opzione '-h'!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Errore: atteso elenco modalità dopo l'opzione '-y'!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Errore: atteso nome dopo l'opzione '-%c'!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Errore: attesa stringa di opzione dopo l'opzione '-o'!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Errore: atteso elenco delle pagine dopo l'opzione '-P'!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Errore: attesa priorità dopo l'opzione '-%c'!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Errore: atteso testo di motivazione dopo l'opzione '-r'!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Errore: atteso titolo dopo l'opzione '-t'!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Errore: atteso nome utente dopo l'opzione '-U'!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Errore: atteso nome utente dopo l'opzione '-u'!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Errore: atteso valore dopo l'opzione '-%c'!\n" + +#, c-format +msgid "%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' option!\n" +msgstr "%s: Errore: dopo l'opzione '-W', occorre \"completati\", \"non completati\" o \"tutti\"!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Errore: nessuna destinazione predefinita disponibile.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Errore: la priorità deve essere tra 1 e 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Errore: la stampa programmata non risponde!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Errore: troppi documenti - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Errore: impossibile accedere a \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Errore: impossibile effettuare la coda da stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Errore: destinazione \"%s\" sconosciuta!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Errore: destinazione \"%s/%s\" sconosciuta!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Errore: opzione '%c' sconosciuta!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Errore: opzione '%s' sconosciuta!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Atteso ID dell'operazione dopo l'opzione '-i'!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filtro \"%s\" non disponibile: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Nome di destinazione non valido nell'elenco \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Stringa filtro \"%s\" non valida\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: prima di '-H restart' è richiesto l'ID dell'operazione ('-i jobid')!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Nessun filtro per convertire da %s/%s a %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Operazione fallita; %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Spiacente, nessun supporto di codifica compilato!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Impossibile connettersi al server\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Impossibile contattare il server!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Impossibile determinare il tipo MIME di \"%s\"!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: impossibile aprire %s: - %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Impossibile aprire il documento PPD: %s alla riga %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "%s: Impossibile aprire il file PPD: %s alla riga %d.\n" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: impossibile leggere il database MIME da \"%s\" o \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Destinazione sconosciuta \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Errore: tipo MIME di destinazione %s/%s sconosciuto!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Opzione '%c' sconosciuta!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Tipo MIME sorgente %s/%s sconosciuto!\n" + +#, c-format +msgid "%s: Warning - '%c' format modifier not supported - output may not be correct!\n" +msgstr "%s: Attenzione: modificatore di formato '%c' non supportato; il risultato potrebbe non essere corretto!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Attenzione: opzione del set di caratteri ignorata!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Attenzione: opzione del tipo di contenuto ignorata!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Attenzione: opzione del modulo ignorata!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Attenzione: opzione modalità ignorata!\n" + +#, c-format +msgid "%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: Errore: i nomi della variabile d'ambiente %s non esistono nella destinazione \"%s\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: Errore: attesa opzione=valore dopo l'opzione '-o'!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: Errore: nessuna destinazione predefinita disponibile.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 poll./sec." + +msgid "1.25x0.25\"" +msgstr "1,25 x 0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25 x 2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 poll./sec." + +msgid "1.50x0.25\"" +msgstr "1,50 x 0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50 x 0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50 x 1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50 x 2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 poll./sec." + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/sec." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 poll./sec." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 poll./sec." + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/sec." + +msgid "120x60dpi" +msgstr "120 x 60 dpi" + +msgid "120x72dpi" +msgstr "120 x 72 dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/sec." + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/sec." + +msgid "150dpi" +msgstr "150 dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 poll./sec." + +msgid "2-Sided Printing" +msgstr "Stampa su due lati" + +msgid "2.00x0.37\"" +msgstr "2,00 x 0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00 x 0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00 x 1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00 x 1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00 x 2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00 x 3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00 x 4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00 x 5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25 x 0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25 x 1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25 x 4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25 x 5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38 x 5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 poll./sec." + +msgid "2.50x1.00\"" +msgstr "2,50 x 1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50 x 2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75 x 1,25\"" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/sec." + +msgid "200 mm/sec." +msgstr "200 mm/sec." + +msgid "203dpi" +msgstr "203 dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "Serie a 24 pin" + +msgid "240x72dpi" +msgstr "240 x 72 dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/sec." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 poll./sec." + +msgid "3.00x1.00\"" +msgstr "3,00 x 1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00 x 1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00 x 2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00 x 3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00 x 5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25 x 2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25 x 5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25 x 5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25 x 5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25 x 7,83\"" + +msgid "3.5\" Disk" +msgstr "Disco da 3,5\"" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Disco da 3,5\": 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50 x 1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/sec." + +msgid "300 mm/sec." +msgstr "300 mm/sec." + +msgid "300dpi" +msgstr "300 dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 dpi" + +msgid "360x180dpi" +msgstr "360 x 180 dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 poll./sec." + +msgid "4.00x1.00\"" +msgstr "4,00 x 1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00 x 13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00 x 2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00 x 2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00 x 3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00 x 4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00 x 5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00 x 6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00 x 6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/sec." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 poll./sec." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 poll./sec." + +msgid "6.00x1.00\"" +msgstr "6,00 x 1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00 x 2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00 x 3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00 x 4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00 x 5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00 x 6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00 x 6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/sec." + +msgid "600dpi" +msgstr "600 dpi" + +msgid "60dpi" +msgstr "60 dpi" + +msgid "60x720dpi" +msgstr "60 x 720 dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 poll./sec." + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 poll./sec." + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00 x 1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00 x 2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00 x 3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00 x 4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00 x 5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00 x 6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00 x 6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/sec." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 poll./sec." + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "Serie a 9 pin" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Sconosciuto comando aiuto non valido\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Per esportare i driver di stampa è necessaria una password Samba!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "Per esportare i driver di stampa è necessario un nome utente Samba!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Esiste già una classe chiamata \"%s\"!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Esiste già una stampante chiamata \"%s\"!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (senza margini)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (senza margini)" + +msgid "A4 (Small)" +msgstr "A4 (con margini)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (senza margini)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Accetta stampe" + +msgid "Accepted" +msgstr "Accettate" + +msgid "Add Class" +msgstr "Aggiungi classe" + +msgid "Add Printer" +msgstr "Aggiungi stampante" + +msgid "Add RSS Subscription" +msgstr "Aggiungi sottoscrizione RSS" + +msgid "Address" +msgstr "Indirizzo" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Indirizzo: 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Amministrazione" + +msgid "Always" +msgstr "Sempre" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applicatore" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Tentativo di impostare printer-state %s a un valore %d errato!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "I gruppi di attributi non sono ordinati (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Puntatore dest. NULL errato" + +msgid "Bad OpenGroup" +msgstr "OpenGroup errato" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI errato" + +msgid "Bad OrderDependency" +msgstr "OrderDependency errato" + +msgid "Bad Request" +msgstr "Richiesta errata" + +msgid "Bad SNMP version number" +msgstr "Numero versione SNMP errato" + +msgid "Bad UIConstraints" +msgstr "UIConstraints errato" + +#, c-format +msgid "Bad copies value %d." +msgstr "Valore copie %d errato." + +msgid "Bad custom parameter" +msgstr "Parametro personalizzato errato" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "URI dispositivo \"%s\" errato!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "uri dispositivo \"%s\" errato!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Schema device-uri \"%s\" errato!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "document-format \"%s\" errato!" + +msgid "Bad filename buffer!" +msgstr "Buffer nome documento errato!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Attributo font errato: %s\n" + +msgid "Bad job-priority value!" +msgstr "Valore job-priority errato!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Valore job-sheets \"%s\" errato!" + +msgid "Bad job-sheets value type!" +msgstr "Tipo valore job-sheets errato!" + +msgid "Bad job-state value!" +msgstr "Valore job-state errato!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Attributo job-uri \"%s\" errato!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "notify-pull-method \"%s\" errato!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "URI notify-recipient-uri \"%s\" errato!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Valore number-up %d errato." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Opzione + scelta errata alla riga %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Valori page-ranges %d-%d errati." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Port-monitor \"%s\" errato!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Valore printer-state %d errato!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "ID di richiesta errato %d." + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Numero versione richiesta %d.%d errato!" + +msgid "Bad subscription ID!" +msgstr "ID abbonamento errato!" + +msgid "Banners" +msgstr "Banner" + +msgid "Billing Information: " +msgstr "Informazioni pagamento: " + +msgid "Bond Paper" +msgstr "Carta normale" + +msgid "C0 Envelope" +msgstr "Busta C0" + +msgid "C1 Envelope" +msgstr "Busta C1" + +msgid "C2 Envelope" +msgstr "Busta C2" + +msgid "C3 Envelope" +msgstr "Busta C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Busta C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Busta C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Busta C6" + +msgid "C65 Envelope" +msgstr "Busta C65" + +msgid "C7 Envelope" +msgstr "Busta C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Stampante etichetta CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Annulla sottoscrizione RSS" + +msgid "Change Settings" +msgstr "Modifica impostazioni" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Set di caratteri \"%s\" non supportato!" + +msgid "Chou3 Envelope" +msgstr "Busta Chou3" + +msgid "Chou4 Envelope" +msgstr "Busta Chou4" + +msgid "Classes" +msgstr "Classi" + +msgid "Clean Print Heads" +msgstr "Pulisci testine stampante" + +msgid "Color" +msgstr "Colore" + +msgid "Color Mode" +msgstr "Modalità colore" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"I comandi possono essere abbreviati. I comandi sono:\n" +"\n" +"esci aiuto chiudi stato ?\n" + +msgid "Community name uses indefinite length" +msgstr "I nomi comunitari utilizzano una lunghezza indefinita" + +msgid "Continue" +msgstr "Continua" + +msgid "Continuous" +msgstr "Continuo" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Impossibile eseguire scansione del tipo \"%s\"!" + +msgid "Cover open." +msgstr "Coperchio aperto" + +msgid "Created" +msgstr "Creato" + +msgid "Created On: " +msgstr "Creato il: " + +msgid "Custom" +msgstr "Personalizzato" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Taglia" + +msgid "Cutter" +msgstr "Cutter" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "Busta DL" + +msgid "Dark" +msgstr "Scuro" + +msgid "Darkness" +msgstr "Oscurità" + +msgid "Delete Class" +msgstr "Elimina classe" + +msgid "Delete Printer" +msgstr "Elimina stampante" + +msgid "Description: " +msgstr "Descrizione: " + +msgid "DeskJet Series" +msgstr "Serie DeskJet" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "La destinazione \"%s\" non accetta operazioni." + +msgid "Developer almost empty." +msgstr "Developer quasi vuoto." + +msgid "Developer empty!" +msgstr "Developer vuoto!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Dispositivo: uri = %s\n" +" classe = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" posizione = %s\n" + +msgid "Direct Thermal Media" +msgstr "Media termico diretto" + +msgid "Disabled" +msgstr "Disabilitato" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Documento %d non trovato nell'operazione %d." + +msgid "Door open." +msgstr "Porta aperta" + +msgid "Double Postcard" +msgstr "Cartolina postale doppia" + +msgid "Driver Name: " +msgstr "Nome driver: " + +msgid "Driver Version: " +msgstr "Versione driver: " + +msgid "Duplexer" +msgstr "Duplexer" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: impossibile allocare memoria per info pagina: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: impossibile allocare memoria per matrice pagine: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Stampante etichette EPL1" + +msgid "EPL2 Label Printer" +msgstr "Stampante etichette EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "ERROR: %s job-id utente titolo copie opzioni [file]\n" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox errato: commento visto!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: %%IncludeFeature errato: commento!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: %%Page errato: commento nel documento!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: %%PageBoundingBox errato: commento nel documento!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: dispositivo SCSI \"%s\" errato!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: documento charset errato %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: tipo charset errato %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: valore colonne errato %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: valore cpi errato %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: riga descrizione font errata: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: valore lpi errato %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Formato di stampa errato!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: direzione testo errata %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: ampiezza testo errata %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: la stampante di destinazione non esiste!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox duplicato: commento visto!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: %%Pages duplicato: commento visto!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: documento di stampa vuoto!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: errore %d durante l'invio della richiesta PAPSendData: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: attesa stringa tra virgolette nella riga %d di %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: errore USB fatale!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: visto comando HP-GL/2 non valido, impossibile stampare documento!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog mancante!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup mancante!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: manca valore alla riga %d del documento banner!\n" + +#, c-format +msgid "ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "ERROR: occorre una riga msgid prima di ogni stringa di traduzione alla riga %d di %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: nessun %%BoundingBox: commento nell'intestazione!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: nessun %%Pages: commento nell'intestazione!\n" + +msgid "ERROR: No device URI found in argv[0] or in DEVICE_URI environment variable!\n" +msgstr "ERROR: nessun dispositivo URI trovato in argv[0] e nessuna variabile ambiente in DEVICE_URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: nessun font nel set di caratteri %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: nessuna pagina trovata!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: carta esaurita!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: variabile ambiente PRINTER non definita!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: il documento stampa non è stato accettato (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: la stampante non risponde\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: la stampante non risponde!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: la stampante ha inviato un EOF inatteso\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: l'host remoto non ha accettato il documento di controllo (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: l'host remoto non ha accettato il documento dati (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: si è verificato un errore di timeout durante l'invio di dati alla stampante\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: impossibile aggiungere il documento %d alla stampa: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: impossibile annullare la stampa %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: impossibile copiare il documento PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "ERROR: Impossibile creare il canale" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: impossibile creare il socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: impossibile creare il documento di stampa compresso temporaneo: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: impossibile creare il documento temporaneo" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: impossibile eseguire pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: impossibile eseguire il programma gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: impossibile eseguire il programma pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "ERROR: Impossibile eseguire il programma pstops" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: impossibile biforcare pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: impossibile ottenere richiesta PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: impossibile ottenere risposta PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: impossibile aprire il documento PPD per la stampante \"%s\" - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: impossibile ottenere zona di default AppleTalk" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: impossibile ottenere gli attributi (%2$s) della stampa %1$d!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: impossibile ottenere lo stato della stampante (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: impossibile individuare la stampante '%s'!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: impossibile cercare risposta PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: impossibile cercare stampanti AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: impossibile rendere indirizzo AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: impossibile aprire \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: impossibile aprire %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "ERROR: Impossibile aprire il file PPD.\n" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: impossibile aprire documento banner \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: impossibile aprire documento dispositivo \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: impossibile aprire documento \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: impossibile aprire documento \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: impossibile aprire il documento immagine per la stampa!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: impossibile aprire documento di stampa \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: impossibile aprire il documento di stampa %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: impossibile aprire il documento di stampa %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "ERROR: Impossibile aprire il file raster - %s\n" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: impossibile aprire il documento di stampa compresso temporaneo: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: impossibile stampare colonne di testo %d!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: impossibile stampare pagina di testo %dx%d!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: impossibile leggere i dati di stampa" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: impossibile leggere i dati di stampa!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: impossibile prenotare una porta" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: impossibile trovare distanza %ld nel documento - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: impossibile trovare distanza %lld nel documento - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: impossibile inviare comando LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: impossibile inviare richiesta PAP" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: impossibile inviare richiesta dati PAP iniziale" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: impossibile inviare i dati di stampa (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: impossibile inviare i dati di stampa!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: impossibile inviare il documento di stampa alla stampante" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: impossibile inviare trailing nul alla stampante" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: impossibile attendere per pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: impossibile scrivere %d byte su \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: impossibile scrivere %d byte sulla stampante!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: impossibile scrivere documento controllo" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: impossibile scrivere dati di stampa" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: impossibile scrivere dati di stampa: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: impossibile scrivere dati raster sul driver!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: impossibile scrivere documento temporaneo" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: impossibile scrivere dati documento non compressi: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: testo inatteso alla riga %d di %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: valore opzione di codifica sconosciuto \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: ordine documento sconosciuto \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: carattere formato sconosciuto \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: formato catalogo messaggio di \"%s\" sconosciuto!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: opzione \"%s\" con valore \"%s\" sconosciuta!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: modalità di stampa \"%s\" sconosciuta\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: valore opzione versione sconosciuto \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: valore luminosità %s non supportato, utilizzo luminosità=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: valore gamma %s non supportato, utilizzo gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: valore number-up %d non supportato, utilizzo number-up=1!\n" + +#, c-format +msgid "ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "ERROR: valore number-up-layout %s non supportato, utilizzo number-up-layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: valore page-border %s non supportato, utilizzo page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: rilevato overflow (%d byte) doc_printf, interrompo!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops si è chiuso al segnale %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops si è chiuso con stato %d!\n" + +msgid "ERROR: recoverable: Unable to connect to printer; will retry in 30 seconds...\n" +msgstr "ERROR: recuperabile: impossibile stabilire connessione con la stampante; riprovo fra 30 secondi...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: selezione() fallita" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: impossibile avviare documento di stampa" + +msgid "Edit Configuration File" +msgstr "Modifica documento di configurazione" + +msgid "Empty PPD file!" +msgstr "Documento PPD vuoto!" + +msgid "Ending Banner" +msgstr "Banner finale" + +msgid "Enter old password:" +msgstr "Inserisci la vecchia password:" + +msgid "Enter password again:" +msgstr "Inserisci di nuovo la password:" + +msgid "Enter password:" +msgstr "Inserisci la password:" + +msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket." +msgstr "Per accedere a questa pagina, inserisci il tuo nome utente e la password o il nome utente e la password di root." + +msgid "Envelope Feed" +msgstr "Feed busta" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Politica errori" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Errore: è necessario un nome host dopo l'opzione '-h'!\n" + +msgid "Every 10 Labels" +msgstr "Ogni 10 etichette" + +msgid "Every 2 Labels" +msgstr "Ogni 2 etichette" + +msgid "Every 3 Labels" +msgstr "Ogni 3 etichette" + +msgid "Every 4 Labels" +msgstr "Ogni 4 etichette" + +msgid "Every 5 Labels" +msgstr "Ogni 5 etichette" + +msgid "Every 6 Labels" +msgstr "Ogni 6 etichette" + +msgid "Every 7 Labels" +msgstr "Ogni 7 etichette" + +msgid "Every 8 Labels" +msgstr "Ogni 8 etichette" + +msgid "Every 9 Labels" +msgstr "Ogni 9 etichette" + +msgid "Every Label" +msgstr "Ogni etichetta" + +msgid "Expectation Failed" +msgstr "Attesa fallita" + +msgid "Export Printers to Samba" +msgstr "Esporta stampanti a Samba" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Cartella documento" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Cartella documento: 9/16 x 3 7/16\"" + +#, c-format +msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"." +msgstr "Gli URI del dispositivo documento sono stati disabilitati! Per abilitarli, consulta l'istruzione del FileDevice in \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Foglio" + +msgid "Forbidden" +msgstr "Vietato" + +msgid "Fuser temperature high!" +msgstr "Temperatura del fusibile elevata!" + +msgid "Fuser temperature low!" +msgstr "Temperatura del fusibile bassa!" + +msgid "General" +msgstr "Generale" + +msgid "Generic" +msgstr "Generico" + +msgid "German FanFold" +msgstr "Modulo continuo tedesco" + +msgid "German FanFold Legal" +msgstr "Modulo continuo legale tedesco" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU utilizza una lunghezza indefinita" + +msgid "Glossy Paper" +msgstr "Carta patinata" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Ottenuto un attributo printer-uri, ma nessun job-id!" + +msgid "Grayscale" +msgstr "Scala di grigi" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Cartella interruzione" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Cartella interruzione - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk disabilitata in Preferenze di Sistema.\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk disabilitata in Preferenze di Sistema.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: annullo lavoro di stampa...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: connesso alla stampante...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: connetto alla stampante...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: documento di controllo inviato con successo\n" + +msgid "INFO: Copying print data...\n" +msgstr "INFO: Copia dei dati di stampa...\n" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: documento dati inviato con successo\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "INFO: Pagina %d completata...\n" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: formatto pagina %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: carico documento immagine...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: cerco la stampante...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: apro la connessione\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: documento stampa inviato, attendo che la stampante finisca...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: stampante occupata; riprovo fra 10 secondi...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: stampante occupata; riprovo fra 30 secondi...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: stampante occupata; riprovo fra 5 secondi...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: la stampante non supporta IPP/%d.%d, provo IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: la stampante è occupata; riprovo fra 5 secondi...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: la stampante al momento non è in linea.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: la stampante al momento non è in linea.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: la stampante è adesso in linea.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: la stampante non è in linea.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: stampante non connessa; riprovo fra 30 secondi...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: stampo pagina %d, %d%% completato...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: stampo pagina %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: pronta per stampare.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: invio documento di controllo (%lu byte)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: invio documento di controllo (%u byte)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: invio dati\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: invio documento dati (%ld byte)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: invio documento dati (%lld byte)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: invio dati di stampa...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: inviato documento stampa, %ld byte...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: inviato documento stampa, %lld byte...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: eseguo lo spool della stampa LPR, %.0f%% completato...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "INFO: Pagina iniziale %d...\n" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "INFO: impossibile contattare la stampante, in coda sulla stampante successiva nella classe...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: uso una zona di default AppleTalk\"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: attendo che la stampa sia completata...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: attendo che la stampante sia disponibile...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "Busta ISO B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (senza margini)" + +msgid "ISO B5 Envelope" +msgstr "Busta ISO B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "Busta ISO B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Carattere di controllo non consentito" + +msgid "Illegal main keyword string" +msgstr "Stringa di parola chiave principale non consentita" + +msgid "Illegal option keyword string" +msgstr "Stringa di parola chiave opzionale non consentita" + +msgid "Illegal translation string" +msgstr "Stringa di traduzione non consentita" + +msgid "Illegal whitespace character" +msgstr "Carattere spazio bianco non consentito" + +msgid "Ink/toner almost empty." +msgstr "Inchiostro/toner quasi vuoto." + +msgid "Ink/toner empty!" +msgstr "Inchiostro/toner vuoto!" + +msgid "Ink/toner waste bin almost full." +msgstr "Cestino inchiostro/toner quasi pieno." + +msgid "Ink/toner waste bin full!" +msgstr "Cestino inchiostro/toner pieno!" + +msgid "Installable Options" +msgstr "Opzioni installabili" + +msgid "Installed" +msgstr "Installate" + +msgid "IntelliBar Label Printer" +msgstr "Stampante etichette IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Interblocco aperto." + +msgid "Internal Server Error" +msgstr "Errore interno del server" + +msgid "Internal error" +msgstr "Errore interno" + +msgid "Internet Postage 2-Part" +msgstr "Francobollo Internet 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Francobollo Internet 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Francobollo Internet 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Francobollo Internet 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "IPP (Internet Printing Protocol)" + +msgid "Invite Envelope" +msgstr "Busta invito" + +msgid "Italian Envelope" +msgstr "Busta standard italiana" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "La stampa #%d non può essere riavviata: nessun documento!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "La stampa #%d non esiste!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "La stampa #%d è già interrotta: impossibile annullare." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "La stampa #%d è già annullata: impossibile annullare." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "La stampa #%d è già completata: impossibile annullare." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "La stampa #%d è terminata e non può essere modificata!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "La stampa %d non è completa!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "La stampa #%d non è bloccata per l'autenticazione!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "La stampa #%d non è bloccata!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "La stampa #%s non esiste!" + +#, c-format +msgid "Job %d not found!" +msgstr "Stampa %d non trovata!" + +msgid "Job Completed" +msgstr "Stampa completata" + +msgid "Job Created" +msgstr "Stampa creata" + +msgid "Job ID: " +msgstr "ID stampa: " + +msgid "Job Options Changed" +msgstr "Opzioni di stampa modificate" + +msgid "Job Stopped" +msgstr "Stampa interrotta" + +msgid "Job UUID: " +msgstr "UUID stampa: " + +msgid "Job is completed and cannot be changed." +msgstr "La stampa è completata e non può essere modificata." + +msgid "Job operation failed:" +msgstr "Operazione stampa fallita:" + +msgid "Job state cannot be changed." +msgstr "Lo stato della stampa non può essere modificato." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Le sottoscrizioni delle stampe non possono essere rinnovate!" + +msgid "Jobs" +msgstr "Stampe" + +msgid "Kaku2 Envelope" +msgstr "Busta Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Busta Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Host o stampante LPD/LPR" + +msgid "Label Printer" +msgstr "Stampante etichette" + +msgid "Label Top" +msgstr "Etichetta superiore" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Lingua \"%s\" non supportata!" + +msgid "Large Address" +msgstr "Indirizzo esteso" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Indirizzo esteso: - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Serie PCL 4/5" + +msgid "Light" +msgstr "Luce" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Lunghezza riga superiore al limite massimo concesso (255 caratteri)" + +msgid "List Available Printers" +msgstr "Elenco stampanti disponibili" + +msgid "Location: " +msgstr "Posizione: " + +msgid "Long-Edge (Portrait)" +msgstr "Taglio largo (ritratto)" + +msgid "Make and Model: " +msgstr "Produzione e modello: " + +msgid "Manual Feed" +msgstr "Alimentazione manuale" + +msgid "Media Dimensions: " +msgstr "Dimensioni media: " + +msgid "Media Limits: " +msgstr "Limiti media: " + +msgid "Media Name: " +msgstr "Nome media: " + +msgid "Media Size" +msgstr "Dimensione media" + +msgid "Media Source" +msgstr "Sorgente media" + +msgid "Media Tracking" +msgstr "Rilevamento media" + +msgid "Media Type" +msgstr "Tipo media" + +msgid "Media jam!" +msgstr "Inceppamento supporto!" + +msgid "Media tray almost empty." +msgstr "Cassetto carta quasi vuoto." + +msgid "Media tray empty!" +msgstr "Cassetto carta vuoto!" + +msgid "Media tray missing!" +msgstr "Cassetto carta mancante!" + +msgid "Media tray needs to be filled." +msgstr "Bisogna riempire il cassetto carta." + +msgid "Medium" +msgstr "Media" + +msgid "Memory allocation error" +msgstr "Errore di allocazione della memoria" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Intestazione PPD-Adobe-4.x mancante" + +msgid "Missing asterisk in column 1" +msgstr "Asterisco mancante nella colonna 1" + +msgid "Missing document-number attribute!" +msgstr "Attributo document-number mancante!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Doppi apici mancanti alla riga %d!" + +msgid "Missing form variable!" +msgstr "Variabile modulo mancante" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Attributo notify-subscription-ids mancante!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Attributo requesting-user-name mancante!" + +msgid "Missing required attributes!" +msgstr "Attributi necessari mancanti!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Valore mancante alla riga %d!" + +msgid "Missing value string" +msgstr "Stringa di valore mancante" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modello: nome = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Modifica classe" + +msgid "Modify Printer" +msgstr "Modifica stampante" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Busta Monarch" + +msgid "Move All Jobs" +msgstr "Sposta tutte le stampe" + +msgid "Move Job" +msgstr "Sposta stampa" + +msgid "Moved Permanently" +msgstr "Spostamento permanente" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: documento di stampa accettato: ID stampa %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: documento di stampa accettato: ID stampa sconosciuto.\n" + +msgid "NULL PPD file pointer" +msgstr "Puntatore documento NULL PPD" + +msgid "Name OID uses indefinite length" +msgstr "Il nome OID utilizza una lunghezza indefinita" + +msgid "Nested classes are not allowed!" +msgstr "Le classi nidificate non sono consentite." + +msgid "Never" +msgstr "Mai" + +msgid "New Stylus Color Series" +msgstr "Nuova serie Stylus Color" + +msgid "New Stylus Photo Series" +msgstr "Nuova serie Stylus Photo" + +msgid "No" +msgstr "No" + +msgid "No Content" +msgstr "Nessun contenuto" + +msgid "No PPD name!" +msgstr "Nessun nome PPD!" + +msgid "No VarBind SEQUENCE" +msgstr "Nessuna SEQUENZA VarBind" + +msgid "No Windows printer drivers are installed!" +msgstr "Non è installato nessun driver di stampa Windows!" + +msgid "No active connection" +msgstr "Nessuna connessione attiva" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Nessuna stampa attiva su %s!" + +msgid "No attributes in request!" +msgstr "Nessun attributo nella richiesta!" + +msgid "No authentication information provided!" +msgstr "Nessuna informazione di autenticazione fornita!" + +msgid "No community name" +msgstr "Nessun nome comunitario" + +msgid "No default printer" +msgstr "Nessuna stampante predefinita" + +msgid "No destinations added." +msgstr "Nessuna destinazione aggiunta." + +msgid "No error-index" +msgstr "Nessun error-index" + +msgid "No error-status" +msgstr "Nessun error-status" + +msgid "No file!?!" +msgstr "Nessun documento!?!" + +msgid "No modification time!" +msgstr "Nessuna ora modifica!" + +msgid "No name OID" +msgstr "Nessun nome OID" + +msgid "No printer name!" +msgstr "Nessun nome stampante!" + +msgid "No printer-uri found for class!" +msgstr "Nessun printer-uri trovato per la classe!" + +msgid "No printer-uri found!" +msgstr "Nessun printer-uri trovato!" + +msgid "No printer-uri in request!" +msgstr "Nessun printer-uri nella richiesta!" + +msgid "No request-id" +msgstr "Nessun request-id" + +msgid "No subscription attributes in request!" +msgstr "Nessun attributo di sottoscrizione nella richiesta!" + +msgid "No subscriptions found." +msgstr "Nessuna sottoscrizione trovata." + +msgid "No variable-bindings SEQUENCE" +msgstr "Nessuna SEQUENZA variable-bindings" + +msgid "No version number" +msgstr "Nessun numero versione" + +msgid "Non-continuous (Mark sensing)" +msgstr "Non-continuous (rilevamento contrassegno)" + +msgid "Non-continuous (Web sensing)" +msgstr "Non-continuous (rilevamento web)" + +msgid "Normal" +msgstr "Normale" + +msgid "Not Found" +msgstr "Non trovato" + +msgid "Not Implemented" +msgstr "Non implementato" + +msgid "Not Installed" +msgstr "Non installato" + +msgid "Not Modified" +msgstr "Non modificato" + +msgid "Not Supported" +msgstr "Non supportato" + +msgid "Not allowed to print." +msgstr "Non autorizzata a stampare." + +msgid "Note" +msgstr "Nota" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC quasi alla fine del proprio ciclo di vita utile." + +msgid "OPC at end-of-life!" +msgstr "OPC alla fine del proprio ciclo di vita utile!" + +msgid "Off (1-Sided)" +msgstr "Off (su un lato)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Aiuto Online" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "Apertura di %s fallita: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup senza un CloseGroup precedente" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI senza un CloseUI/JCLCloseUI precedente" + +msgid "Operation Policy" +msgstr "Politica operativa" + +msgid "Options Installed" +msgstr "Opzioni installate" + +msgid "Options: " +msgstr "Opzioni: " + +msgid "Out of toner!" +msgstr "Toner esaurito!" + +msgid "Output Mode" +msgstr "Modalità di uscita" + +msgid "Output bin almost full." +msgstr "Vassoio di uscita quasi pieno." + +msgid "Output bin full!" +msgstr "Vassoio di uscita pieno!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "L'uscita per la stampante %s è inviata a %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "L'uscita per la stampante %s è inviata alla stampante remota %s su %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "L'uscita per la stampante %s/%s è inviata a %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "L'uscita per la stampante %s/%s è inviata alla stampante remota %s su %s\n" + +msgid "Output tray missing!" +msgstr "Vassoio di uscita mancante!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "Stampante laser PCL" + +msgid "PRC1 Envelope" +msgstr "Busta PRC1" + +msgid "PRC10 Envelope" +msgstr "Busta PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Busta PRC2" + +msgid "PRC3 Envelope" +msgstr "Busta PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (senza margini)" + +msgid "PRC4 Envelope" +msgstr "Busta PRC4" + +msgid "PRC5 Envelope" +msgstr "Busta PRC5" + +msgid "PRC6 Envelope" +msgstr "Busta PRC6" + +msgid "PRC7 Envelope" +msgstr "Busta PRC7" + +msgid "PRC8 Envelope" +msgstr "Busta PRC8" + +msgid "PRC9 Envelope" +msgstr "Busta PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Il pacchetto non contiene un Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Il pacchetto non inizia con una SEQUENZA" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Password per %s su %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Password per %s necessaria per accedere a %s via SAMBA: " + +msgid "Pause Class" +msgstr "Metti in pausa classe" + +msgid "Pause Printer" +msgstr "Metti in pausa stampante" + +msgid "Peel-Off" +msgstr "Stacca" + +msgid "Personal Envelope" +msgstr "Busta personale" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Etichette foto" + +msgid "Plain Paper" +msgstr "Carta normale" + +msgid "Policies" +msgstr "Politiche" + +msgid "Port Monitor" +msgstr "Monitor porta" + +msgid "PostScript Printer" +msgstr "Stampante PostScript" + +msgid "Postcard" +msgstr "Cartolina postale" + +msgid "Print Density" +msgstr "Densità di stampa" + +msgid "Print Job:" +msgstr "Stampa:" + +msgid "Print Mode" +msgstr "Modalità di stampa" + +msgid "Print Rate" +msgstr "Velocità di stampa" + +msgid "Print Self-Test Page" +msgstr "Pagina di autoverifica" + +msgid "Print Speed" +msgstr "Velocità di stampa" + +msgid "Print Test Page" +msgstr "Stampa pagina di prova" + +msgid "Print and Cut" +msgstr "Stampa e taglia" + +msgid "Print and Tear" +msgstr "Stampa e separa" + +msgid "Printed For: " +msgstr "Stampato per: " + +msgid "Printed From: " +msgstr "Stampato da: " + +msgid "Printed On: " +msgstr "Stampato su: " + +msgid "Printer Added" +msgstr "Aggiunta stampante" + +msgid "Printer Default" +msgstr "Stampate di default" + +msgid "Printer Deleted" +msgstr "Stampante eliminata" + +msgid "Printer Modified" +msgstr "Manutenzione stampanti" + +msgid "Printer Name: " +msgstr "Nome stampante: " + +msgid "Printer Paused" +msgstr "Stampante in pausa" + +msgid "Printer Settings" +msgstr "Impostazioni stampante" + +msgid "Printer offline." +msgstr "Stampante non in linea." + +msgid "Printer:" +msgstr "Stampante:" + +msgid "Printers" +msgstr "Stampanti" + +msgid "Purge Jobs" +msgstr "Libera stampe" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Limite di quota raggiunto." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "Posiz. Proprietario Stampa Doc. Dim. totali\n" + +msgid "Rank Owner Pri Job Files Total Size\n" +msgstr "Posiz. Proprietario Stampa Doc. Dim. totali\n" + +msgid "Reject Jobs" +msgstr "Scarta stampe" + +msgid "Reprint After Error" +msgstr "Ristampa dopo errore" + +msgid "Request Entity Too Large" +msgstr "Richiesta di dimensioni eccessive" + +msgid "Resolution" +msgstr "Risoluzione" + +msgid "Resume Class" +msgstr "Riprendi classe" + +msgid "Resume Printer" +msgstr "Riprendi stampante" + +msgid "Return Address" +msgstr "Indirizzo mittente" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Indirizzo mittente - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Riavvolgi" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Esecuzione del comando: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "Stampante SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENZA utilizza una lunghezza indefinita" + +msgid "See Other" +msgstr "Vedi altro" + +#, c-format +msgid "Serial Port #%d" +msgstr "Porta seriale#%d" + +msgid "Server Restarted" +msgstr "Server riavviato" + +msgid "Server Security Auditing" +msgstr "Auditing sicurezza server" + +msgid "Server Started" +msgstr "Server avviato" + +msgid "Server Stopped" +msgstr "Server interrotto" + +msgid "Service Unavailable" +msgstr "Servizio non disponibile" + +msgid "Set Allowed Users" +msgstr "Imposta utenti autorizzati" + +msgid "Set As Server Default" +msgstr "Imposta come server di default" + +msgid "Set Class Options" +msgstr "Imposta opzioni classe" + +msgid "Set Printer Options" +msgstr "Imposta opzioni stampante" + +msgid "Set Publishing" +msgstr "Imposta pubblicazione" + +msgid "Shipping Address" +msgstr "Indirizzo di spedizione" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Indirizzo di spedizione - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Lato corto (panoramica)" + +msgid "Special Paper" +msgstr "Carta speciale" + +msgid "Standard" +msgstr "Standard" + +msgid "Starting Banner" +msgstr "Banner iniziale" + +msgid "Statement" +msgstr "Istruzione" + +msgid "Stylus Color Series" +msgstr "Serie Stylus Color" + +msgid "Stylus Photo Series" +msgstr "Serie Stylus Photo" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Cambio protocolli" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (senza margini)" + +msgid "Tear" +msgstr "Separa" + +msgid "Tear-Off" +msgstr "Separa" + +msgid "Tear-Off Adjust Position" +msgstr "Posizione di regolazione separa" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Impossibile trovare il documento PPD \"%s\"." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Impossibile aprire il documento PPD \"%s\": %s" + +msgid "The class name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." +msgstr "Il nome della classe può contenere fino a 127 caratteri stampabili e non può contenere spazi, barre (/) o cancelletti (#)." + +msgid "The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "L'attributo notify-lease-duration non può essere usato con le sottoscrizioni delle stampe." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Il valore notify-user-data è troppo grande (%d > 63 ottetti)!" + +msgid "The printer name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." +msgstr "Il nome della stampante può contenere fino a 127 caratteri stampabili e non può contenere spazi, barre (/) o cancelletti (#)." + +msgid "The printer or class is not shared!" +msgstr "La stampante o la classe non è condivisa!" + +msgid "The printer or class was not found." +msgstr "La stampante o la classe non è stata trovata." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Printer-uri \"%s\" contiene caratteri non validi." + +msgid "The printer-uri attribute is required!" +msgstr "Attributo printer-uri richiesto!" + +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "È richiesto un printer-uri con formato \"ipp://HOSTNAME/classes/CLASSNAME\"." + +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "È richiesto un printer-uri con formato \"ipp://HOSTNAME/printers/PRINTERNAME\"." + +msgid "The subscription name may not contain spaces, slashes (/), question marks (?), or the pound sign (#)." +msgstr "Il nome della sottoscrizione non può contenere spazi, barre (/), punti interrogativi (?) o cancelletti (#)." + +msgid "There are too many subscriptions." +msgstr "Ci sono troppe sottoscrizioni." + +msgid "Thermal Transfer Media" +msgstr "Media trasferimento termico" + +msgid "Title: " +msgstr "Titolo: " + +msgid "Toner low." +msgstr "Toner basso." + +msgid "Too many active jobs." +msgstr "Troppe stampe attive." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Troppi valori job-sheets (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Troppi valori printer-state-reasons (%d > %d)!" + +msgid "Transparency" +msgstr "Trasparenza" + +msgid "Tray" +msgstr "Vassoio" + +msgid "Tray 1" +msgstr "Vassoio 1" + +msgid "Tray 2" +msgstr "Vassoio 2" + +msgid "Tray 3" +msgstr "Vassoio 3" + +msgid "Tray 4" +msgstr "Vassoio 4" + +msgid "URI Too Long" +msgstr "URI troppo lungo" + +msgid "US Executive" +msgstr "Executive USA" + +msgid "US Fanfold" +msgstr "Modulo continuo USA" + +msgid "US Ledger" +msgstr "Ledger USA" + +msgid "US Legal" +msgstr "Legale USA" + +msgid "US Legal (Oversize)" +msgstr "Legale USA (senza margini)" + +msgid "US Letter" +msgstr "Lettera USA" + +msgid "US Letter (Oversize)" +msgstr "Lettera USA (senza margini)" + +msgid "US Letter (Small)" +msgstr "Lettera USA (con margini)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Porta seriale#%d USB" + +msgid "Unable to access cupsd.conf file:" +msgstr "Impossibile accedere al documento cupsd.conf:" + +msgid "Unable to add RSS subscription:" +msgstr "Impossibile aggiungere la sottoscrizione RSS:" + +msgid "Unable to add class:" +msgstr "Impossibile aggiungere la classe:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Impossibile aggiungere la stampa alla destinazione \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Impossibile aggiungere la stampante:" + +msgid "Unable to allocate memory for file types!" +msgstr "Impossibile allocare memoria per tipi di documento!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Impossibile annullare la sottoscrizione RSS:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Impossibile modificare l'attributo printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Impossibile cambiare stampante:" + +msgid "Unable to change server settings:" +msgstr "Impossibile modificare le impostazioni del server:" + +msgid "Unable to connect to host." +msgstr "Impossibile connettersi all'host." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Impossibile copiare i documenti dei driver della stampante per CPU a 64 bit (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "Impossibile copiare i documenti dei driver della stampante per Windows a 64 bit (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Impossibile copiare i documenti CUPS dei driver della stampante (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Impossibile copiare il documento PPD: %s!" + +msgid "Unable to copy PPD file!" +msgstr "Impossibile copiare il documento PPD!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Impossibile copiare i documenti dei driver della stampante per Windows 2000 (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Impossibile copiare i documenti dei driver della stampante per Windows 9x (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Impossibile copiare lo script di interfaccia: %s!" + +msgid "Unable to create printer-uri!" +msgstr "Impossibile creare printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Impossibile creare il documento temporaneo:" + +msgid "Unable to delete class:" +msgstr "Impossibile eliminare la classe:" + +msgid "Unable to delete printer:" +msgstr "Impossibile eliminare la stampante:" + +msgid "Unable to do maintenance command:" +msgstr "Impossibile eseguire il comando di manutenzione:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Impossibile modificare i documenti cupsd.conf più grandi di 1 MB!" + +msgid "Unable to find destination for job!" +msgstr "Impossibile trovare una destinazione per la stampa!" + +msgid "Unable to find printer!\n" +msgstr "Impossibile trovare la stampante!\n" + +msgid "Unable to get class list:" +msgstr "Impossibile ottenere l'elenco delle classi:" + +msgid "Unable to get class status:" +msgstr "Impossibile ottenere lo stato della classe:" + +msgid "Unable to get list of printer drivers:" +msgstr "Impossibile ottenere l'elenco dei driver della stampante:" + +msgid "Unable to get printer attributes:" +msgstr "Impossibile ottenere gli attributi della stampante:" + +msgid "Unable to get printer list:" +msgstr "Impossibile ottenere l'elenco delle stampanti:" + +msgid "Unable to get printer status:" +msgstr "Impossibile ottenere lo stato della stampante:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Impossibile installare i documenti dei driver di stampa per Windows 2000 (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Impossibile installare i documenti dei driver di stampa per Windows 9x (%d)!" + +msgid "Unable to modify class:" +msgstr "Impossibile modificare la classe:" + +msgid "Unable to modify printer:" +msgstr "Impossibile modificare la stampante:" + +msgid "Unable to move job" +msgstr "Impossibile spostare la stampa" + +msgid "Unable to move jobs" +msgstr "Impossibile spostare le stampe" + +msgid "Unable to open PPD file" +msgstr "Impossibile aprire il documento PPD" + +msgid "Unable to open PPD file:" +msgstr "Impossibile aprire il documento PPD:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Impossibile aprire il documento cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Impossibile aprire il documento %d nella stampa %d!" + +msgid "Unable to print test page:" +msgstr "Impossibile stampare la pagina di prova:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Impossibile eseguire \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Impossibile inviare comandi al driver della stampante!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Impossibile configurare il driver della stampante per Windows (%d)!" + +msgid "Unable to set options:" +msgstr "Impossibile configurare le opzioni:" + +msgid "Unable to set server default:" +msgstr "Impossibile impostare il server di default:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Impossibile caricare il documento cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Impossibile utilizzare il driver della classe USB legacy!\n" + +msgid "Unauthorized" +msgstr "Non autorizzato" + +msgid "Units" +msgstr "Unità" + +msgid "Unknown" +msgstr "Sconosciuto" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Printer-error-policy \"%s\" sconosciuto." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Printer-op-policy \"%s\" sconosciuto." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Set di caratteri \"%s\" non supportato!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Compressione \"%s\" non supportata!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Attributo compressione %s non supportato!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Formato \"%s\" non supportato!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Formato '%s non supportato'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Formato '%s/%s' non supportato!" + +msgid "Unsupported value type" +msgstr "Tipo valore non supportato" + +msgid "Upgrade Required" +msgstr "Richiesto aggiornamento" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Utilizzo:\n" +"\n" +" lpadmin [-h server] -d destinazione\n" +" lpadmin [-h server] -x destinazione\n" +" lpadmin [-h server] -p stampante [-c add-class] [-i interfaccia] [-m modello]\n" +" [-r remove-class] [-v dispositivo] [-D descrizione]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u consenti:utente,utente] [-u non consentire:utente,utente]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Utilizzo: [nome documento] opzioni titolo copie utente stampa %s\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Utilizzo: [documento] opzioni titolo copie utente ID stampa %s\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Utilizzo: documento opzioni titolo copie utente ID stampa %s\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" +"Utilizzo: convert [ opzioni ]\n" +"\n" +"Opzioni:\n" +"\n" +" -e Utilizza ogni filtro dal file PPD\n" +" -f nomefile Imposta il file da convertire (altrimenti stdin)\n" +" -o nomefile Imposta il file da generare (altrimenti stdout)\n" +" -i tipo/mime Imposta il tipo MIME in ingresso (altrimenti auto-typed)\n" +" -j tipo/mime Imposta il tipo MIME di uscita (altrimenti application/pdf)\n" +" -P nomefile.ppd Imposta file PPD\n" +" -a 'nome=valore ...' Imposta opzione(i)\n" +" -U nomeutente Imposta il nome utente per la stampa\n" +" -J titolo Imposta il titolo\n" +" -c copie Imposta il numero di copie\n" +" -u Rimuove il file PPD al completamento\n" +" -D Rimuove il file in ingresso al completamento\n" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Utilizzo: cupsaddsmb [opzioni] stampante1 ... stampanteN\n" +" cupsaddsmb [opzioni] -a\n" +"\n" +"Opzioni:\n" +" -E Codifica la connessione al server\n" +" -H samba-server Utilizza il server SAMBA specificato\n" +" -U samba-user Effettua l'autenticazione utilizzando l'utente SAMBA specificato\n" +" -a Esporta tutte le stampanti\n" +" -h cups-server Utilizza il server CUPS specificato\n" +" -v Cerca di essere dettagliato (mostra comandi)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Utilizzo: cupsctl [opzioni] [param=value ... paramN=valueN]\n" +"\n" +"Opzioni:\n" +"\n" +" -E Abilita codifica\n" +" -U nome utente Specifica nome utente\n" +" -h server[:porta] Specifica indirizzo server\n" +"\n" +" --[no-]debug-logging Attiva o disattiva logging di debug\n" +" --[no-]remote-admin Attiva o disattiva amministrazione remota\n" +" --[no-]remote-any Consenti/impedisci accesso da Internet\n" +" --[no-]remote-printers Mostra/nascondi stampanti remote\n" +" --[no-]share-printers Attiva o disattiva condivisione stampanti\n" +" --[no-]-]user-cancel-any Consenti/impedisci agli utenti di annullare qualsiasi stampa\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Utilizzo: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Carica documento di configurazione alternativo\n" +"-f Esegui in primo piano\n" +"-F Esegui in primo piano, ma sganciato\n" +"-h Mostra questo messaggio relativo all'utilizzo\n" +"-l Esegui cupsd da launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" +"Utilizzo: cupsfilter -m tipo/mime [ opzioni ] nomefile\n" +"\n" +"Opzioni:\n" +"\n" +" -c cupsd.conf Imposta il file cupsd.conf da utilizzare\n" +" -e Usa ogni filtro dal file PPD\n" +" -j job-id[,N] Filtra il file N dalla stampa specificata (predefinito è il file 1)\n" +" -n copies Imposta il numero di copie\n" +" -o name=value Imposta opzione(i)\n" +" -p filename.ppd Imposta il file PPD\n" +" -t title Imposta il titolo\n" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript itself.\n" +msgstr "" +"Utilizzo: cupstestdsc [opzioni] nomedocumento.ps [... nomedocumento.ps]\n" +" cupstestdsc [opzioni] -\n" +"\n" +"Opzioni:\n" +"\n" +" -h Mostra l'utilizzo del programma\n" +"\n" +" Nota: questo programma convalida solo i commenti DSC, non il PostScript stesso.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" +"Utilizzo: cupstestppd [opzioni] nomefile1.ppd[.gz] [... nomefileN.ppd[.gz]]\n" +" programma | cupstestppd [opzioni] -\n" +"\n" +"Opzioni:\n" +"\n" +" -R cartella-radice Imposta radice alternativa\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n" +" Emette avvisi al posto degli errori\n" +" -q Esecuzione silenziosa\n" +" -r Modalità di apertura 'rilassata'\n" +" -v Abbastanza dettagliato\n" +" -vv Molto dettagliato\n" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Utilizzo: lpmove stampa/fonte dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Utilizzo: lpoptions [-h server] [-E] -d stampante\n" +" lpoptions [-h server] [-E] [-p stampante] -l\n" +" lpoptions [-h server] [-E] -p stampante -o opzione[=valore] ...\n" +" lpoptions [-h server] [-E] -x stampante\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Utilizzo: lppasswd [-g nomegruppo]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Utilizzo: lppasswd [-g nomegruppo] [nomeutente]\n" +" lppasswd [-g nomegruppo] -a [nomeutente]\n" +" lppasswd [-g nomegruppo] -x [nomeutente]\n" + +msgid "Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "Utilizzo: lpq [-P dest] [-U nomeutente] [-h nomehost[:porta]] [-l] [+intervallo]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Utilizzo: ppdc [opzioni] nomedocumento.drv [ ... nomedocumentoN.drv ]\n" +"Opzioni:\n" +" -D name=value Imposta la variabile specificata con il valore.\n" +" -I include-dir Aggiunge includi directory al percorso di ricerca.\n" +" -c catalog.po Carica il catalogo messaggi specificato.\n" +" -d output-dir Specifica la directory di output.\n" +" -l lingua[,lingua,...] Specifica la lingua(e) di output (impostazioni internazionali).\n" +" -m Utilizza il valore ModelName come nome documento.\n" +" -t Verifica PPD invece di generarli.\n" +" -v Cerca di essere abbastanza dettagliato (più v per ulteriori dettagli).\n" +" -z Comprime i documenti PPD utilizzando GNU zip.\n" +" --cr Termina le linee con CR (Mac OS 9).\n" +" --crlf Termina linee con CR + LF (Windows).\n" +" --lf Termina linee con LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Utilizzo: ppdhtml [opzioni] nomedocumento.drv >nomedocumento.html\n" +" -D name=value Imposta il nome specificato con il valore .\n" +"Opzioni:\n" +" -I include-dir Aggiunge includi directory al percorso di ricerca.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Utilizzo: ppdi [options] nomedocumento.ppd [ ... nomedocumentoN.ppd ]\n" +"Opzioni:\n" +" -I include-dir\n" +" -o nomedocumento.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Utilizzo: ppdmerge [opzioni] nomedocumento.ppd [ ... nomedocumentoN.ppd ]\n" +"Opzioni:\n" +" -o nomedocumento.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Utilizzo: ppdpo [opzioni] -o nomedocumento.po nomedocumento.drv [ ... nomedocumentoN.drv ]\n" +"Opzioni:\n" +" -D name=value Imposta la variabile specificata con il valore.\n" +" -I include-dir Aggiunge includi directory al percorso di ricerca.\n" +" -v Cerca di essere dettagliato (più v per ulteriori dettagli).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Utilizzo: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Il valore utilizza una lunghezza indefinita" + +msgid "VarBind uses indefinite length" +msgstr "VarBind utilizza una lunghezza indefinita" + +msgid "Version uses indefinite length" +msgstr "La versione utilizza una lunghezza indefinita" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: aggiungi solo le prime stampanti %d trovate" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: atteso booleano per l'opzione waiteof \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: impossibile leggere richiesta canale laterale!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: impossibile includere l'opzione \"%s\" tramite IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: la stampante non risponde\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: la stampante ha inviato un EOF inatteso!\n" + +#, c-format +msgid "WARNING: Remote host did not respond with command status byte after %d seconds!\n" +msgstr "WARNING: l'host remoto non ha risposto con byte stato comando dopo %d secondi!\n" + +#, c-format +msgid "WARNING: Remote host did not respond with control status byte after %d seconds!\n" +msgstr "WARNING: l'host remoto non ha risposto con byte stato controllo dopo %d secondi!\n" + +#, c-format +msgid "WARNING: Remote host did not respond with data status byte after %d seconds!\n" +msgstr "WARNING: l'host remoto non ha risposto con byte stato dati dopo %d secondi!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: comando SCSI scaduto (%d); riprovo...\n" + +msgid "WARNING: This document does not conform to the Adobe Document Structuring Conventions and may not print correctly!\n" +msgstr "WARNING: questo documento non è conforme alle convenzioni Adobe sulla struttura dei documenti (Adobe Document Structuring Conventions) e potrebbe non essere stampato correttamente!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: impossibile aprire documento \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: impossibile inviare richiesta PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: pacchetto PAP inatteso di tipo %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: pacchetto PAP sconosciuto di tipo %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: scelta sconosciuta \"%s\" per opzione \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: opzione sconosciuta \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: tasso baud %s non supportato!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: atteso numero per l'opzione status \"%s\"\n" + +#, c-format +msgid "WARNING: recoverable: Network host '%s' is busy; will retry in %d seconds...\n" +msgstr "WARNING: recuperabile: l'host del network '%s' è occupato; riprovo fra %d secondi...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Attenzione: non è installato nessun driver di stampa per Windows 2000!" + +msgid "Yes" +msgstr "Sì" + +#, c-format +msgid "You must access this page using the URL https://%s:%d%s." +msgstr "Devi accedere a questa pagina utilizzando l'URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "Busta You4" + +msgid "ZPL Label Printer" +msgstr "Stampante etichetta ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "interrotto" + +msgid "canceled" +msgstr "annullato" + +msgid "completed" +msgstr "completato" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: utilizza l'opzione -f per specificare un documento da convertire.\n" + +msgid "cups-deviced failed to execute." +msgstr "esecuzione di cups-deviced fallita." + +msgid "cups-driverd failed to execute." +msgstr "esecuzione di cups-driverd fallita." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: nessun documento PPD per la stampante \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: impossibile connettersi al server: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: opzione sconosciuta \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: opzione sconosciuta \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: atteso nome documento di configurazione dopo l'opzione \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: impossibile aprire la directory attuale!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: argomento sconosciuto \"%s\" - interruzione!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: opzione sconosciuta \"%c\" - interrompo!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: supporto launchd(8) non compilato, eseguo in modalità normale.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: numero documento %d non valido!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: ID stampa %d non valido!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: è possibile specificare solo un nome documento!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: impossibile aprire documento di stampa - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: l'opzione -q è incompatibile con l'opzione -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: l'opzione -v è incompatibile con l'opzione -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "dispositivo per %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "dispositivo per %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index utilizza una lunghezza indefinita" + +msgid "error-status uses indefinite length" +msgstr "error-status utilizza una lunghezza indefinita" + +msgid "held" +msgstr "bloccato" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tottieni aiuto riguardo ai comandi\n" + +msgid "idle" +msgstr "inattivo" + +msgid "job-printer-uri attribute missing!" +msgstr "attributo job-printer-uri mancante!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: il nome della classe può contenere solo caratteri stampabili!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: atteso PPD dopo l'opzione '-P'!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: atteso allow/deny:userlist dopo l'opzione '-u'!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: attesa classe dopo l'opzione '-r'!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: atteso nome classe dopo l'opzione '-c'!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: attesa descrizione dopo l'opzione '-D'!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: atteso URI di dispositivo dopo l'opzione '-v'!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: attesi tipi di documento dopo l'opzione '-I'!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: atteso nome host dopo l'opzione '-h'!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: attesa interfaccia dopo l'opzione '-i'!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: attesa posizione dopo l'opzione '-L'!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: atteso modello dopo l'opzione '-m'!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: atteso nome=valore dopo l'opzione '-o'!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: attesa stampante dopo l'opzione '-p'!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: atteso nome stampante dopo l'opzione '-d'!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: attesa stampante o classe dopo l'opzione '-x'!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: nessun nome utente trovato!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: la stampante %s è già un membro della classe %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: la stampante %s non è un membro della classe %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: il nome della stampante può contenere solo caratteri stampabili!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile aggiungere una stampante alla classe:\n" +" Devi specificare prima il nome di una stampante!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: impossibile connettersi al server: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: impossibile aprire documento PPD \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: impossibile aprire documento \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile rimuovere una stampante dalla classe:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare il documento PPD:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare URI dispositivo:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare lo script di interfaccia o il documento PPD:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare lo script di interfaccia:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare la descrizione della stampante:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare la posizione della stampante:\n" +" Devi specificare prima il nome di una stampante!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: impossibile impostare le opzioni della stampante:\n" +" Devi specificare prima il nome di una stampante!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: opzione consenti/non consentire \"%s\" sconosciuta!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: argomento '%s' sconosciuto!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: opzione '%c' sconosciuta!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: attenzione, elenco dei tipi di contenuto ignorato!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: attesa stringa ID dispositivo 1284 dopo --device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: attesa lingua dopo --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: attesi marca e modello dopo --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: attesa stringa prodotto dopo --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: atteso elenco schema dopo --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: atteso elenco schema dopo --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: atteso timeout dopo --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: argomento '%s' sconosciuto!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: opzione '%c' sconosciuta!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: opzione '%s' sconosciuta!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: impossibile connettersi al server: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: argomento '%s' sconosciuto!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: opzione '%c' sconosciuta!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: nessuna stampante!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: impossibile aggiungere una stampante o un'istanza: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: impossibile aprire il file PPD per %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: impossibile aprire il documento PPD per %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: stampante o classe sconosciuta!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: solo root può aggiungere o eliminare le password!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: il documento delle password è occupato!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: documento delle password non aggiornato!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: spiacente, la password non corrisponde!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: spiacente, password rifiutata.\n" +"La password deve essere di almeno 6 caratteri, non può contenere\n" +"il nome utente e deve contenere almeno una lettera e un numero.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: spiacente, le password non corrispondono!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: impossibile copiare la stringa della password: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: impossibile aprire il documento delle password: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: impossibile scrivere il documento delle password: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: copia di sicurezza del vecchio documento delle password fallita: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: rinomina del documento delle password fallita: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: l'utente \"%s\" e il gruppo \"%s\" non esistono.\n" + +#, c-format +msgid "lpstat: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "lpstat: errore: i nomi della variabile d'ambiente %s non esistono nella destinazione \"%s\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "membri della classe %s:\n" + +msgid "no entries\n" +msgstr "nessuna voce\n" + +msgid "no system default destination\n" +msgstr "nessuna destinazione predefinita di sistema\n" + +msgid "notify-events not specified!" +msgstr "notify-events non specificato!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI \"%s\" è già utilizzato!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI \"%s\" utilizza uno schema sconosciuto!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d non corretto!" + +msgid "pending" +msgstr "in sospeso" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: aggiungi includi directory \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: aggiungi/aggiorna testo UI da %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: valore booleano errato (%s) alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: nome risoluzione errato (%s) alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: chiave stato errata (%s) alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: sostituzione variabile errata ($%c) alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: scelta trovata alla riga %d di %s senza opzione!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: duplica #po per impostazioni internazionali %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: attesa una definizione filtro alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: atteso un nome applicazione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: atteso un valore booleano alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: atteso un set di caratteri dopo Font alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: atteso codice scelta alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: attesa scelta nome/testo alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: atteso ordine colore per ColorModel alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: atteso spazio colore per ColorModel alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: attesa compressione per ColorModel alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc: attesa stringa limitazioni per UIConstraints alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "ppdc: attesa parola chiave tipo driver dopo DriverType alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: atteso tipo duplex dopo Duplex alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: attesa codifica dopo Font alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: atteso nome documento dopo #po %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: atteso nome/testo gruppo alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: atteso nome documento alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: atteso intero alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: attese impostazioni internazionali dopo #po alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo FileName alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo Font alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo Produttore alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo MediaSize alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo ModelName alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: atteso nome dopo PCFileName alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: atteso nome/testo dopo %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: atteso nome/testo dopo Installabile alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: atteso nome/testo dopo Risoluzione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "ppdc: attesa combinazione nome/testo per ColorModel alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: attesa opzione nome/testo alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: attesa sezione opzione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: atteso tipo opzione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: atteso campo sostituzione dopo Risoluzione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: atteso numero reale alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected resolution/mediatype following ColorProfile on line %d of %s!\n" +msgstr "ppdc: atteso risoluzione/mediatype dopo ColorProfile alla riga %d of %s!\n" + +#, c-format +msgid "ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d of %s!\n" +msgstr "ppdc: atteso risoluzione/mediatype dopo SimpleColorProfile alla riga %d of %s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: atteso selettore dopo %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: atteso stato dopo Font alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: attesa stringa dopo Copyright alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: attesa stringa dopo Versione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: attesi due nomi opzione alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: atteso valore dopo %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: attesa versione dopo Font alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: nome documento #include/#po \"%s\" non valido!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: costo non valido per filtro alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: tipo MIME vuoto non valido per filtro alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: nome programma vuoto non valido per filtro alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: sezione opzione \"%s\" non valida alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: tipo opzione \"%s\" non valida alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: carico documento informazioni del driver \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: carico messaggi per impostazioni internazionali \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: carico messaggi da \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif mancante alla fine di \"%s\"!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if mancante alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: nessun catalogo messaggi fornito per impostazioni internazionali %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "ppdc: L'opzione %s è definita in due gruppi differenti alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: opzione %s ridefinita con un tipo diverso alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: l'opzione limitazione deve essere *indicata alla riga %d of %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: troppi #if' nidificati alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: impossibile creare il documento PPD \"%s\" - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: impossibile creare la directory di output %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: impossibile creare pipe di output: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: impossibile eseguire cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: impossibile trovare il documento #po %s alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: impossibile trovare includi documento \"%s\" alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: impossibile trovare localizzazione per \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: impossibile caricare documento di localizzazione per \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: variabile non definita (%s) alla riga %d di %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: tipo driver %s sconosciuto alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: tipo duplex \"%s\" sconosciuto alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: tipo media \"%s\" sconosciuto alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: token \"%s\" sconosciuto visto alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "ppdc: caratteri trailing sconosciuti nel numero reale \"%s\" alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: stringa non terminata che inizia con %c alla riga %d di %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: scrivo %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: scrivo documenti PPD nella directory \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: LanguageVersion \"%s\" errato in %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: ignoro documento %s PPD...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: impossibile eseguire copia di backup di %s su %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "la stampante %s è disabilitata da %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "la stampante %s è in attesa. Abilitata da %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "la stampante %s sta stampando %s-%d. Abilitata da %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "la stampante %s/%s è disabilitata da %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "la stampante %s/%s è in attesa. Abilitata da %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "la stampante %s/%s sta stampando %s-%d. Abilitata da %s\n" + +msgid "processing" +msgstr "elaborazione in corso" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "l'id richiesto è %s-%d (%d file)\n" + +msgid "request-id uses indefinite length" +msgstr "request-id utilizza una lunghezza indefinita" + +msgid "scheduler is not running\n" +msgstr "la stampa programmata non è in esecuzione\n" + +msgid "scheduler is running\n" +msgstr "la stampa programmata è in esecuzione\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "verifica di %s fallita: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "stato\t\tmostra lo stato del demone e della coda\n" + +msgid "stopped" +msgstr "interrotto" + +#, c-format +msgid "system default destination: %s\n" +msgstr "destinazione predefinita di sistema: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "destinazione predefinita di sistema: %s/%s\n" + +msgid "unknown" +msgstr "Sconosciuto" + +msgid "untitled" +msgstr "senza titolo" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings utilizza una lunghezza indefinita" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN Documento APDialogExtension mancante \"%s\"\n" +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN Documento APPrinterIconPath mancante \"%s\"\n" +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Impossibile aprire %s - %s\n" +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Errore: impossibile aprire %s - %s alla riga %d.\n" +#~ msgid "600 DPI Grayscale" +#~ msgstr "Scala di grigi a 600 DPI" +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: manca URI su linea di comando e nessuna variabile ambiente " +#~ "DEVICE_URI!\n" +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: impossibile creare il documento temporaneo: %s.\n" +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: impossibile creare il documento temporaneo: %s.\n" +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: impossibile aprire il documento temporaneo" +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: il filtro pdftops si è chiuso al segnale %d!\n" +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: il filtro pdftops si è chiuso con stato %d!\n" +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Errore della stampante sconosciuto (%s)!" +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Utilizzo: convert [ opzioni ]\n" +#~ "\n" +#~ "Opzioni:\n" +#~ "\n" +#~ " -f nome documento Imposta il documento da convertire " +#~ "(altrimenti stdin)\n" +#~ " -o nome documento Imposta il documento da generare (altrimenti " +#~ "stdout)\n" +#~ " -i mime/type Imposta il tipo MIME input (altrimenti auto-" +#~ "typed)\n" +#~ " -j mime/type Imposta il tipo MIME output (altrimenti " +#~ "application/pdf)\n" +#~ " -P filename.ppd Imposta il documento PPD\n" +#~ " -a 'nome=valore ...' Imposta opzione(i)\n" +#~ " -U nome utente Imposta il nome utente per la stampa\n" +#~ " -J titolo Imposta il titolo\n" +#~ " -c copie Imposta il numero di copie\n" +#~ " -u Rimuove il documento PPD terminata l'azione\n" +#~ " -D Rimuove il documento input terminata l'azione\n" +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Utilizzo: cupsfilter -m mime/type [ opzioni] filename\n" +#~ "\n" +#~ "Opzioni:\n" +#~ "\n" +#~ " -c cupsd.conf Imposta il documento cupsd.conf da utilizzare\n" +#~ " -j job-id[,N] Filtra il documento N dalla stampa specificata " +#~ "(l'opzione di default è documento 1)\n" +#~ " -n copies Imposta il numero di copie\n" +#~ " -o name=value Imposta l'opzione(i)\n" +#~ " -p filename.ppd Imposta il documento PPD\n" +#~ " -t title Imposta il titolo\n" +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Utilizzo: cupstestppd [opzioni] nomefile1.ppd[.gz] [... nomefileN.ppd[." +#~ "gz]]\n" +#~ " programma | cupstestppd [opzioni] -\n" +#~ "\n" +#~ "Opzioni:\n" +#~ "\n" +#~ " -R root-directory Configura root alternativa\n" +#~ " -W {tutti,nessuno,limitazioni,default,filtri,traduzioni}\n" +#~ " Avvisi per problemi invece di errori\n" +#~ " -q Esegui in silenzio\n" +#~ " -r Utilizza modalità di apertura 'rilassata'\n" +#~ " -v Cerca di essere abbastanza dettagliato\n" +#~ " -vv Cerca di essere molto dettagliato\n" +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: impossibile creare il documento temporaneo: %s\n" +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: impossibile creare il documento temporaneo - %s\n" +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: impossibile creare il documento temporaneo: %s\n" + diff --git a/locale/cups_ja.po b/locale/cups_ja.po new file mode 100644 index 0000000000..189378d546 --- /dev/null +++ b/locale/cups_ja.po @@ -0,0 +1,5527 @@ +# +# "$Id$" +# +# Message catalog template for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2009 by Apple Inc. +# Copyright 2005-2007 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +# +# Notes for Translators: +# +# The following prefixes MUST NOT be translated: "ALERT:", "CRIT:", "INFO:", +# "NOTICE:", and "WARNING:". +# +# The "checkpo" program located in the "locale" source directory can be used +# to verify that your translations do not introduce formatting errors or other +# problems. Run with: +# +# cd locale +# ./checkpo cups_LL.po +# +# where "LL" is your locale. +# +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-05 14:00-0700\n" +"PO-Revision-Date: 2009-02-20 16:43+0900\n" +"Last-Translator: OPFC TRANSCUPS \n" +"Language-Team: OPFC TRANSCUPS \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(すべて)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(なし)\n" + +msgid "\t%d entries\n" +msgstr "\t%d エントリー\n" + +msgid "\tAfter fault: continue\n" +msgstr "\t失敗後: 継続\n" + +msgid "\tAlerts:" +msgstr "\t警告:" + +msgid "\tBanner required\n" +msgstr "\tバナーが必要\n" + +msgid "\tCharset sets:\n" +msgstr "\t文字セット:\n" + +msgid "\tConnection: direct\n" +msgstr "\t接続: 直結\n" + +msgid "\tConnection: remote\n" +msgstr "\t接続: リモート\n" + +msgid "\tDefault page size:\n" +msgstr "\tデフォルト用紙サイズ:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tデフォルトピッチ:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tデフォルトポート設定:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\t説明: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\t設定されたフォーム:\n" +"\tコンテンツの種類: すべて\n" +"\tプリンターの種類: 不明\n" + +msgid "\tForms allowed:\n" +msgstr "\t許可されているフォーム:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tインターフェイス: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tインターフェイス: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tインターフェイス: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\t場所: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\t失敗時: 警告なし\n" + +msgid "\tUsers allowed:\n" +msgstr "\t許可されているユーザー:\n" + +msgid "\tUsers denied:\n" +msgstr "\t拒否されているユーザー:\n" + +msgid "\tdaemon present\n" +msgstr "\tデーモンは提供されています\n" + +msgid "\tno entries\n" +msgstr "\tエントリーがありません\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tデバイス '%s' 上のプリンター 速度 -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\t印刷は無効です\n" + +msgid "\tprinting is enabled\n" +msgstr "\t印刷は有効です\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\t%s にキューしました\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tキューは無効です\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tキューは有効です\n" + +msgid "\treason unknown\n" +msgstr "\t未知の理由\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" 適合テスト結果詳細\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " 参照: 15 ページ、セクション 3.1。\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " 参照: 15 ページ、セクション 3.2。\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " 参照: 19 ページ、セクション 3.3。\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " 参照: 20 ページ、セクション 3.4。\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " 参照: 27 ページ、セクション 3.5。\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " 参照: 42 ページ、セクション 5.2。\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " 参照: 16-17 ページ、セクション 3.2。\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " 参照: 42-45 ページ、セクション 5.2。\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " 参照: 45-46 ページ、セクション 5.2。\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " 参照: 48-49 ページ、セクション 5.2。\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " 参照: 52-54 ページ、セクション 5.2。\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f バイト\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " 合格 Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " 合格 DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " 合格 DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " 合格 FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " 合格 FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " 合格 LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " 合格 LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " 合格 Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " 合格 ModelName\n" + +msgid " PASS NickName\n" +msgstr " 合格 NickName\n" + +msgid " PASS PCFileName\n" +msgstr " 合格 PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " 合格 PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " 合格 PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " 合格 PageSize\n" + +msgid " PASS Product\n" +msgstr " 合格 Product\n" + +msgid " PASS ShortNickName\n" +msgstr " 合格 ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" 警告 \"%s %s\" は \"%s %s\" と競合します\n" +" (禁則=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " 警告 %s は相当するオプションがありません!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" 警告 %s は %s と一般プレフィックスを共有します。\n" +" 参照: 15 ページ、セクション 3.2。\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " 警告 デフォルトの選択肢が競合しています!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" 警告 Duplex オプションキーワード %s は期待通りに動作しないかもしれません。また、Duplex という名前であるべきです!\n" +" 参照: 122 ページ、セクション 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" 警告 ファイルが CR、LF、CR LF の行末を混在して含んでいます!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" 警告 LanguageEncoding は PPD 4.3 仕様で必須です。\n" +" 参照: 56-57 ページ、セクション 5.3。\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " 警告 %d 行が空白だけです!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" 警告 Manufacturer は PPD 4.3 仕様で必須です。\n" +" 参照: 58-59 ページ、セクション 5.3。\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, not CR LF!\n" +msgstr "" +" 警告 非 Windows PPD ファイルは、CR LF でなく LF のみを行末に使うべきです!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" 警告 PPD バージョン %.1f は現在使われていません!\n" +" 参照: 42 ページ、セクション 5.2。\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" 警告 8.3 文字より長い PCFileName は PPD 仕様違反です。\n" +" 参照: 61-62 ページ、セクション 5.3。\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" 警告 プロトコルが PJL を含んでいますが JCL 属性が設定されていませ" +"ん。\n" +" 参照: 78-79 ページ、セクション 5.7。\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" 警告 プロトコルが PJL と BCP の両方を含んでいます; TBCP を想定しま" +"す。\n" +" 参照: 78-79 ページ、セクション 5.7。\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" 警告 ShortNickName は PPD 4.3 仕様で必須です。\n" +" 参照: 64-65 ページ、セクション 5.3。\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s が存在しません!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr " %s %s ファイル \"%s\" は不正な大文字で始まるワードを含んでいます!\n" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s 不正な %s が %s を選んでいます!\n" +" 参照: 122 ページ、セクション 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s 不正な UTF-8 \"%s\" 翻訳文字列 (オプション %s 用)です!\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s 不正な UTF-8 \"%s\" 翻訳文字列 (オプション %s 、選択 %s)です!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s 不正な値が cupsFilter に設定されています \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s 不正な cupsICCProfile %sです!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s 不正な値が cupsPreFilter に設定されています \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 不正な cupsUIConstraints %s: \"%s\"です!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s 無効な言語 \"%s\"です!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr " %s %s の不正な綴りです - %s であるべきです!\n" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr " %s APScanAppPath と APScanAppBundleID は同時に指定できません!\n" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s 空の cupsUIConstraints %sです!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s \"%s\" 翻訳文字列 (オプション %s 用) が見つかりません!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s \"%s\" 翻訳文字列 (オプション %s 、選択 %s) が見つかりません!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr " %s APDialogExtension ファイル \"%s\" が見つかりません\n" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr " %s APPrinterIconPath ファイル \"%s\" が見つかりません\n" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr " %s APPrinterLowInkTool ファイル \"%s\" が見つかりません\n" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr " %s APPrinterUtilityPath ファイル \"%s\" が見つかりません\n" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr " %s APScanAppPath ファイル \"%s\" が見つかりません\n" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" %s 必須の PageRegion オプションが見つかりません!\n" +" 参照: 100 ページ、セクション 5.14。\n" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" %s 必須の PageSize オプションが見つかりません!\n" +" 参照: 99 ページ、セクション 5.14。\n" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s  選択 *%s %s が UIConstraints \"*%s %s *%s %s\" 内に見つかりません!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 選択 *%s %s が cupsUIConstraints %s: \"%s\" 内に見つかりません!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s cupsFilter ファイル \"%s\" が見つかりません!\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s cupsICCProfile ファイル \"%s\" が見つかりません!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s cupsPreFilter ファイル \"%s\" が見つかりません!\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s cupsUIResolver ファイル %s が見つかりません!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s オプション %s がUIConstraints \"*%s %s *%s %s\" に見つかりません!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s オプション %s がcupsUIConstraints %s に見つかりません!: \"%s\"\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s ファイルにベース翻訳文字列 \"%s\" がありません!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" +" %s サイズ名 \"%s\" は標準にありません!\n" +" 参照: 187 ページ、セクション B.2。\n" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s 必須の %s が選択肢 None を定義していません!\n" +" 参照: 122 ページ、セクション 5.17。\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr " %s サイズ \"%s\" は %s 向けに定義されていますが、%s にはありません!\n" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr " %s サイズ \"%s\" は規定外の寸法 (%gx%g) を持っています!\n" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfileのハッシュ値 %s が %s と一致しません!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolverの %s がループしています!\n" + +#, c-format +msgid " %s cupsUIResolver %s does not list at least two different options!\n" +msgstr " %s cupsUIResolver %s は最低でも二つの異なったオプションを持っていなければなりません!\n" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr " **失敗** %s が選択した %s と %s は大文字/小文字のみが違うだけです!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **失敗** %s は 1284DeviceID でなければなりません!\n" +" 参照: 72 ページ、セクション 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **失敗** 不正な Default%s %s\n" +" 参照: 40 ページ、セクション 4.5。\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失敗** %s は不正な DefaultImageableArea です!\n" +" 参照: 102 ページ、セクション 5.15。\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失敗** %s は不正な DefaultPaperDimension です!\n" +" 参照: 103 ページ、セクション 5.15。\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **失敗** ファイルに不正な JobPatchFile 属性があります\n" +" 参照: 24 ページ、セクション 3.4。\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **失敗** 不正な Manufacturer (\"HP\" でなければなりません)\n" +" 参照: 211 ページ、表 D.1。\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **失敗** 不正な Manufacturer (\"Oki\" でなければなりません)\n" +" 参照: 211 ページ、表 D.1。\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **失敗** 不正な ModelName - 文字列に \"%c\" は許可されていません。\n" +" 参照: 59-60 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **失敗** 不正な PSVersion - \"(文字列) 整数\" ではありません。\n" +" 参照: 62-64 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **失敗** 不正な Product - \"(文字列)\" ではありません。\n" +" 参照: 62 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **失敗** 不正な ShortNickName - 31 文字を超えています。\n" +" 参照: 64-65 ページ、セクション 5.3。\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **失敗** 不正な %s が %s を選んでいます!\n" +" 参照: 84 ページ、セクション 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** 不正なFileVersion \"%s\"\n" +" 参照: 56 ページ、セクション 5.3。\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** FormatVersion が違います \"%s\"\n" +" 参照: 56 ページ、セクション 5.3。\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **失敗** 無効な LanguageEncoding %s - ISOLatin1 でなければなりませ" +"ん!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **失敗** 無効な LanguageVersion %s - English でなければなりません!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **失敗** デフォルトのオプションコードが解釈できません: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **失敗** オプション %s、選択 %s のデフォルトの翻訳文字列が 8 ビット文" +"字を含んでいます!\n" + +#, c-format +msgid " **FAIL** Default translation string for option %s contains 8-bit characters!\n" +msgstr " **失敗** オプション %s のデフォルトの翻訳文字列が 8 ビット文字を含んでいます!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr " **失敗** グループ名 %s と %s は大文字/小文字が違うだけです!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **失敗** %s で複数のオプション %s が選択されています!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr " **失敗** オプション名 %s と %s は大文字/小文字が違うだけです!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **失敗** Default%s は必須\n" +" 参照: 40 ページ、セクション 4.5。\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失敗** DefaultImageableArea は必須\n" +" 参照: 102 ページ、セクション 5.15。\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失敗** DefaultPaperDimension は必須\n" +" 参照: 103 ページ、セクション 5.15。\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** FileVersion は必須\n" +" 参照: 56 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** FormatVersion は必須\n" +" 参照: 56 ページ、セクション 5.3。\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失敗** PageSize %s に ImageableArea は必須\n" +" 参照: 41 ページ、セクション 5。\n" +" 参照: 102 ページ、セクション 5.15。\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **失敗** LanguageEncoding は必須\n" +" 参照: 56-57 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **失敗** LanguageVersion は必須\n" +" 参照: 57-58 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **失敗** Manufacturer は必須\n" +" 参照: 58-59 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **失敗** ModelName は必須\n" +" 参照: 59-60 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **失敗** NickName は必須\n" +" 参照: 60 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **失敗** PCFileName は必須\n" +" 参照: 61-62 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **失敗** PSVersion は必須\n" +" 参照: 62-64 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **失敗** PageRegion は必須\n" +" 参照: 100 ページ、セクション 5.14。\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **失敗** PageSize は必須\n" +" 参照: 41 ページ、セクション 5。\n" +" 参照: 99 ページ、セクション 5.14。\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **失敗** PageSize は必須\n" +" 参照: 99-100 ページ、セクション 5.14。\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失敗** PageSize %s に PaperDimension は必須\n" +" 参照: 41 ページ、セクション 5。\n" +" 参照: 103 ページ、セクション 5.15。\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **失敗** Product は必須\n" +" 参照: 62 ページ、セクション 5.3。\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **失敗** ShortNickName は必須\n" +" 参照: 64-65 ページ、セクション 5.3。\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d 個のエラーが見つかりました\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" 不正な %%%%BoundingBox: (%d 行)!\n" +" 参照: 39 ページ、%%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" 不正な %%%%Page: (%d 行)!\n" +" 参照: 53 ページ、%%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" 不正な %%%%Pages: (%d 行)!\n" +" 参照: 43 ページ、%%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" %d 行が 255文字より長くなっています (%d)!\n" +" 参照: 25 ページ、Line Length\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" 先頭行に %!PS-Adobe-3.0 がありません!\n" +" 参照: 17 ページ、3.1 Conforming Documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" %%EndComments コメントが見つかりません!\n" +" 参照: 41 ページ、%%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox: コメントが見つからないか不正です!\n" +" 参照: 39 ページ、%%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page: コメントが見つからないか不正です!\n" +" 参照: 53 ページ、%%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages: コメントが見つからないか不正です!\n" +" 参照: 43 ページ、%%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " エラーは見つかりませんでした\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " 255文字を超える %d 行が見つかりました!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " %%BeginDocument コメントが多すぎます!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " %%EndDocument コメントが多すぎます!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " 警告: ファイルにバイナリデータが含まれています!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " 警告: ファイルに %%EndComments コメントがありません!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " 警告: ファイルは時代遅れの DSC バージョン %.1f です!\n" + +msgid " FAIL\n" +msgstr " 失敗\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" 失敗\n" +" **失敗** PPD ファイルを開けません - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" 失敗\n" +" **失敗** PPD ファイルを開けません - %s (%d 行)。\n" + +msgid " PASS\n" +msgstr " 合格\n" + +msgid "#10 Envelope" +msgstr "#10 封筒" + +msgid "#11 Envelope" +msgstr "#11 封筒" + +msgid "#12 Envelope" +msgstr "#12 封筒" + +msgid "#14 Envelope" +msgstr "#14 封筒" + +msgid "#9 Envelope" +msgstr "#9 封筒" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f バイト\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f バイト\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f ミリメートル" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f to %.0f x %.0f ミリメートル" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f インチ" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f to %.2f x %.2f インチ" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s は %s からリクエストを受け付けています\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s は変更できません。" + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s は lpc の CUPS バージョンでは実装されていません。\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s は準備ができていません\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s は準備ができています\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s は準備ができており印刷しています\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s は %s からリクエストを受け付けていません\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s はサポートされていません!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s は %s からリクエストを受け付けています\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s は %s からリクエストを受け付けていません\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s:%-33.33s [ジョブ %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s に失敗しました: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: 何が起きているか不明です!\n" + +#, c-format +msgid "%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: エラー - 環境変数 %s が存在しない宛先 \"%s\" を指しています!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: エラー - 不正なジョブ ID です!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: エラー - ファイルを印刷できず、ジョブを同時に変えることができません!\n" + +#, c-format +msgid "%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "%s: エラー - ファイルまたはジョブ ID が提供されている場合、標準入力から印刷できません。 \n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: エラー - '-S' オプションのあとには文字セットが必要です!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: エラー - '-T' オプションのあとにはコンテンツタイプが必要です!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: エラー - '-n' オプションのあとにはコピー数が必要です!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: エラー - '-#' オプションのあとにはコピー数が必要です!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: エラー - '-P' オプションのあとには宛先が必要です!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: エラー - '-b' オプションのあとに宛先が必要です!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: エラー - '-d' オプションのあとにはプリンター名が必要です!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: エラー - '-f' オプションのあとには用紙名が必要です!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: エラー - '-H' オプションのあとにはホールド名が必要です!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: エラー - '-H' オプションのあとにはホスト名が必要です!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: エラー - '-h' オプションのあとにはホスト名が必要です!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: エラー - '-y' オプションのあとにはモードリストが必要です!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: エラー - '-%c' オプションのあとには名前が必要です!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: エラー - '-o' オプションのあとには文字列が必要です!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: エラー - '-P' オプションのあとにはページリストが必要です!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: エラー - '-%c' オプションのあとには優先度が必要です!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: エラー - '-r' のあとには理由のテキストが必要です!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: エラー - '-t' オプションのあとにはタイトルが必要です!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: エラー - '-U' オプションのあとにはユーザ名が必要です!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: エラー - '-u' オプションのあとにはユーザ名が必要です!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: エラー - '-%c' オプションのあとには値が必要です!\n" + +#, c-format +msgid "%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' option!\n" +msgstr "%s: エラー - '-W' オプションのあとには、\"completed\"、\"not-completed\"、\"all\" のいずれかが必要です!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: エラー - 利用可能なデフォルトの宛先がありません。\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: エラー - 優先度は 1 から 100 の間である必要があります。\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: エラー - スケジューラが応答していません!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: エラー - ファイルが多すぎます - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: エラー - \"%s\" にアクセスできません - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: エラー - 標準入力からキューにデータを入力できません! - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: エラー - \"%s\" は未知の宛先です!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: エラー - \"%s/%s\" は未知の宛先です!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: エラー - '%c' は未知のオプションです!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: エラー - '%s' は未知のオプションです!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: '-i' オプションのあとにはジョブ ID が必要です!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: フィルター \"%s\" は利用できません: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: リスト \"%s\" に無効な宛先名があります!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: 無効なフィルター文字列です \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: '-H restart' の前にはジョブ ID ('-i ジョブID') が必要です!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: %s/%s から %s/%s に変換するフィルターがありません!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: 操作に失敗しました: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: すみません、暗号化サポートはコンパイル時に組み込まれていません!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: サーバーに接続できません\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: サーバーに連絡できません!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: \"%s\" の MIME タイプを判別できません!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: %sを開けません: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: PPD ファイルを開けません: %s の %d 行目\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "%s: PPD ファイルを開けません: %s の %d 行目\n" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "" +"%s: \"%s\" または \"%s\" から MIME データベースを読み取ることができません!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: \"%s\" は未知の宛先です!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: %s/%s は未知の宛先 MIME タイプです!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: '%c' は未知のオプションです!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: %s/%s は未知のソース MIME タイプです!\n" + +#, c-format +msgid "%s: Warning - '%c' format modifier not supported - output may not be correct!\n" +msgstr "%s: 警告 - '%c' 形式修飾子はサポートされていません - 出力は正しくないものになるかもしれません!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: 警告 - 文字セットオプションは無視されます!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: 警告 - コンテンツタイプオプションは無視されます!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: 警告 - 用紙オプションは無視されます!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: 警告 - モードオプションは無視されます!\n" + +#, c-format +msgid "%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: エラー - 環境変数 %s が存在しない宛先 \"%s\" を指しています!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: エラー - '-o' オプションのあとには オプション=値 が必要です!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: エラー - 利用可能なデフォルトの宛先がありません。\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 インチ/秒" + +msgid "1.25x0.25\"" +msgstr "1.25x0.25インチ" + +msgid "1.25x2.25\"" +msgstr "1.25x2.25インチ" + +msgid "1.5 inch/sec." +msgstr "1.5 インチ/秒" + +msgid "1.50x0.25\"" +msgstr "1.50x0.25インチ" + +msgid "1.50x0.50\"" +msgstr "1.50x0.50インチ" + +msgid "1.50x1.00\"" +msgstr "1.50x1.00インチ" + +msgid "1.50x2.00\"" +msgstr "1.50x2.00インチ" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 インチ/秒" + +msgid "10 x 11\"" +msgstr "10 x 11インチ" + +msgid "10 x 13\"" +msgstr "10 x 13インチ" + +msgid "10 x 14\"" +msgstr "10 x 14インチ" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 ミリメートル/秒" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 インチ/秒" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 インチ/秒" + +msgid "12 x 11\"" +msgstr "12 x 11インチ" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 ミリメートル/秒" + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 ミリメートル/秒" + +msgid "15 x 11\"" +msgstr "15 x 11インチ" + +msgid "150 mm/sec." +msgstr "150 ミリメートル/秒" + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 インチ/秒" + +msgid "2-Sided Printing" +msgstr "両面印刷" + +msgid "2.00x0.37\"" +msgstr "2.00x0.37インチ" + +msgid "2.00x0.50\"" +msgstr "2.00x0.50インチ" + +msgid "2.00x1.00\"" +msgstr "2.00x1.00インチ" + +msgid "2.00x1.25\"" +msgstr "2.00x1.25インチ" + +msgid "2.00x2.00\"" +msgstr "2.00x2.00インチ" + +msgid "2.00x3.00\"" +msgstr "2.00x3.00インチ" + +msgid "2.00x4.00\"" +msgstr "2.00x4.00インチ" + +msgid "2.00x5.50\"" +msgstr "2.00x5.50インチ" + +msgid "2.25x0.50\"" +msgstr "2.25x0.50インチ" + +msgid "2.25x1.25\"" +msgstr "2.25x1.25インチ" + +msgid "2.25x4.00\"" +msgstr "2.25x4.00インチ" + +msgid "2.25x5.50\"" +msgstr "2.25x5.50インチ" + +msgid "2.38x5.50\"" +msgstr "2.38x5.50インチ" + +msgid "2.5 inches/sec." +msgstr "2.5 インチ/秒" + +msgid "2.50x1.00\"" +msgstr "2.50x1.00インチ" + +msgid "2.50x2.00\"" +msgstr "2.50x2.00インチ" + +msgid "2.75x1.25\"" +msgstr "2.75x1.25インチ" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1インチ" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 ミリメートル/秒" + +msgid "200 mm/sec." +msgstr "200 ミリメートル/秒" + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24ピンシリーズ" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 ミリメートル/秒" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 インチ/秒" + +msgid "3.00x1.00\"" +msgstr "3.00x1.00インチ" + +msgid "3.00x1.25\"" +msgstr "3.00x1.25インチ" + +msgid "3.00x2.00\"" +msgstr "3.00x2.00インチ" + +msgid "3.00x3.00\"" +msgstr "3.00x3.00インチ" + +msgid "3.00x5.00\"" +msgstr "3.00x5.00インチ" + +msgid "3.25x2.00\"" +msgstr "3.25x2.00インチ" + +msgid "3.25x5.00\"" +msgstr "3.25x5.00インチ" + +msgid "3.25x5.50\"" +msgstr "3.25x5.50インチ" + +msgid "3.25x5.83\"" +msgstr "3.25x5.83インチ" + +msgid "3.25x7.83\"" +msgstr "3.25x7.83インチ" + +msgid "3.5\" Disk" +msgstr "3.5 インチDisk" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3.5インチ Disk - 2 1/8 x 2 3/4インチ" + +msgid "3.50x1.00\"" +msgstr "3.50x1.00インチ" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 ミリメートル/秒" + +msgid "300 mm/sec." +msgstr "300 ミリメートル/秒" + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 インチ/秒" + +msgid "4.00x1.00\"" +msgstr "4.00x1.00インチ" + +msgid "4.00x13.00\"" +msgstr "4.00x13.00インチ" + +msgid "4.00x2.00\"" +msgstr "4.00x2.00インチ" + +msgid "4.00x2.50\"" +msgstr "4.00x2.50インチ" + +msgid "4.00x3.00\"" +msgstr "4.00x3.00インチ" + +msgid "4.00x4.00\"" +msgstr "4.00x4.00インチ" + +msgid "4.00x5.00\"" +msgstr "4.00x5.00インチ" + +msgid "4.00x6.00\"" +msgstr "4.00x6.00インチ" + +msgid "4.00x6.50\"" +msgstr "4.00x6.50インチ" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 ミリメートル/秒" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 インチ/秒" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 インチ/秒" + +msgid "6.00x1.00\"" +msgstr "6.00x1.00\"" + +msgid "6.00x2.00\"" +msgstr "6.00x2.00\"" + +msgid "6.00x3.00\"" +msgstr "6.00x3.00\"" + +msgid "6.00x4.00\"" +msgstr "6.00x4.00\"" + +msgid "6.00x5.00\"" +msgstr "6.00x5.00\"" + +msgid "6.00x6.00\"" +msgstr "6.00x6.00\"" + +msgid "6.00x6.50\"" +msgstr "6.00x6.50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/秒" + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 インチ/秒" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 インチ/秒" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8.00x1.00\"" + +msgid "8.00x2.00\"" +msgstr "8.00x2.00\"" + +msgid "8.00x3.00\"" +msgstr "8.00x3.00\"" + +msgid "8.00x4.00\"" +msgstr "8.00x4.00\"" + +msgid "8.00x5.00\"" +msgstr "8.00x5.00\"" + +msgid "8.00x6.00\"" +msgstr "8.00x6.00\"" + +msgid "8.00x6.50\"" +msgstr "8.00x6.50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/秒" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 インチ/秒" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9-Pin Series" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?無効なヘルプコマンドです\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"プリンタードライバーをエクスポートするには Samba のパスワードが必要です!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"プリンタードライバーをエクスポートするには、Samba のユーザー名が必要です!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "\"%s\" という名前のクラスはすでに存在します!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "\"%s\" という名前のプリンターはすでに存在します!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (特大)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (特大)" + +msgid "A4 (Small)" +msgstr "A4 (小)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (特大)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "ジョブの受け付け" + +msgid "Accepted" +msgstr "受け付けました" + +msgid "Add Class" +msgstr "クラスの追加" + +msgid "Add Printer" +msgstr "プリンターの追加" + +msgid "Add RSS Subscription" +msgstr "RSS 購読を追加" + +msgid "Address" +msgstr "アドレス" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "アドレス - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "管理" + +msgid "Always" +msgstr "常に有効" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "アプリケーター" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "%s printer-state に 不正な値 %d を設定しようとしています!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "属性グループは範囲外です (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "不正な NULL 送信先ポインター" + +msgid "Bad OpenGroup" +msgstr "不正な OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "不正な OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "不正な OrderDependency" + +msgid "Bad Request" +msgstr "不正なリクエスト" + +msgid "Bad SNMP version number" +msgstr "不正な SNMP バージョン番号" + +msgid "Bad UIConstraints" +msgstr "不正な UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "%d は不正なコピー値です。" + +msgid "Bad custom parameter" +msgstr "不正なカスタムパラメーター" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "\"%s\" は無効なデバイス URI です!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "\"%s\" は無効な device-uri です!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "\"%s\" は無効な device-uri スキーマです!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "\"%s\" は不正な document-format です!" + +msgid "Bad filename buffer!" +msgstr "不正なファイル名バッファーです!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "不正なフォント属性: %s\n" + +msgid "Bad job-priority value!" +msgstr "不正な job-priority 値です!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "\"%s\" は不正な job-sheets 値です!" + +msgid "Bad job-sheets value type!" +msgstr "不正な job-sheets 値タイプ です!" + +msgid "Bad job-state value!" +msgstr "不正な job-state 値です!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "\"%s\" は無効な job-uri 属性です!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "\"%s\" は無効な notify-pull-method です!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "URI \"%s\" は不正な notify-recipient-uri です!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "%d は不正な number-up 値です。" + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "%d 行に不正なオプションと選択があります!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "%d-%d は不正な page-ranges 値です。" + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "\"%s\" は無効な port-monitor です!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "%d は無効な printer-state 値です!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "%d は無効なリクエストIDです!" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "バージョン番号 %d.%d は無効なリクエストです!" + +msgid "Bad subscription ID!" +msgstr "不正なサブスクリプション ID です!" + +msgid "Banners" +msgstr "バナー" + +msgid "Billing Information: " +msgstr "課金情報: " + +msgid "Bond Paper" +msgstr "ボンド紙" + +msgid "C0 Envelope" +msgstr "C0 封筒" + +msgid "C1 Envelope" +msgstr "C1 封筒" + +msgid "C2 Envelope" +msgstr "C2 封筒" + +msgid "C3 Envelope" +msgstr "C3 封筒" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4 封筒" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5 封筒" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6 封筒" + +msgid "C65 Envelope" +msgstr "C65 封筒" + +msgid "C7 Envelope" +msgstr "C7 封筒" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL ラベルプリンター" + +msgid "Cancel RSS Subscription" +msgstr "RSS 購読をキャンセル" + +msgid "Change Settings" +msgstr "設定の変更" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "文字セット \"%s\" はサポートされていません!" + +msgid "Chou3 Envelope" +msgstr "封筒 長形3号" + +msgid "Chou4 Envelope" +msgstr "封筒 長形4号" + +msgid "Classes" +msgstr "クラス" + +msgid "Clean Print Heads" +msgstr "プリントヘッドクリーニング" + +msgid "Color" +msgstr "カラー" + +msgid "Color Mode" +msgstr "カラーモード" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"コマンドは短縮できます。 コマンド:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "コミュニティ名の長さが不定" + +msgid "Continue" +msgstr "継続" + +msgid "Continuous" +msgstr "連続" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "タイプ \"%s\" を検査できませんでした!" + +msgid "Cover open." +msgstr "カバーが開いています。" + +msgid "Created" +msgstr "ジョブ作成" + +msgid "Created On: " +msgstr "ジョブ作成日: " + +msgid "Custom" +msgstr "カスタム" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "カット" + +msgid "Cutter" +msgstr "カッター" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL 封筒" + +msgid "Dark" +msgstr "濃い" + +msgid "Darkness" +msgstr "濃さ" + +msgid "Delete Class" +msgstr "クラスの削除" + +msgid "Delete Printer" +msgstr "プリンターの削除" + +msgid "Description: " +msgstr "説明: " + +msgid "DeskJet Series" +msgstr "DeskJet Series" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "宛先 \"%s\" はジョブを受け付けていません。" + +msgid "Developer almost empty." +msgstr "現像剤が無くなりかけています。" + +msgid "Developer empty!" +msgstr "現像剤が無くなりました!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"デバイス: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "感熱紙" + +msgid "Disabled" +msgstr "無効" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "ドキュメント %d がジョブ %d に見つかりません。" + +msgid "Door open." +msgstr "ドアが開いています。" + +msgid "Double Postcard" +msgstr "往復はがき" + +msgid "Driver Name: " +msgstr "ドライバー名: " + +msgid "Driver Version: " +msgstr "ドライバーバージョン: " + +msgid "Duplexer" +msgstr "両面オプション" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: ページ情報のメモリー割り当てができません: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: ページアレイのメモリー割り当てができません: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1 ラベルプリンター" + +msgid "EPL2 Label Printer" +msgstr "EPL2 ラベルプリンター" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "ERROR: %s ジョブID ユーザー タイトル コピー数 オプション [ファイル]\n" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: 不正な %%BoundingBox: コメントがあります!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: 不正な %%IncludeFeature: コメントです!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: 不正な %%Page: コメントがファイルにあります!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: 不正な %%PageBoundingBox: コメントがファイルにあります!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: 不正な SCSI デバイスファイル \"%s\" です!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: 不正な charset ファイル %s です\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: 不正な charset タイプ %s です\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: 不正な columns 値 %d です!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: 不正な cpi 値 %f です!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: 不正なフォント記述行: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: 不正な lpi 値 %f です!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: 不正なページ設定です!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: 不正な テキスト方向 %s です\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: 不正な テキスト幅 %s です\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: 送信先のプリンターが存在しません!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: 重複した %%BoundingBox: コメントがあります!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: 重複した %%Pages: コメントがあります!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: 空のプリントファイルです!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: エラー %d PAPSendData request の送信: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: %d 行: %s には引用符で囲まれた文字列が必要です!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: 致命的な USB エラーです!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: 無効な HP-GL/2 コマンドがあり、ファイルをプリントできません!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog が見つかりません!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup が見つかりません!\n" + +msgid "ERROR: Missing device URI on command-line and no DEVICE_URI environment variable!\n" +msgstr "ERROR: コマンドラインにデバイス URI が見つからず、環境変数 DEVICE_URI も見つかりません!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: バナーファイルの %d 行目に値が見つかりません!\n" + +#, c-format +msgid "ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "ERROR: %d 行: %s の翻訳文字列の前に msgid 行が必要です!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: %%BoundingBox: コメントがありません!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: %%Pages: コメントがヘッダーにありません!\n" + +msgid "ERROR: No device URI found in argv[0] or in DEVICE_URI environment variable!\n" +msgstr "ERROR: argv[0] または 環境変数 DEVICE_URI にデバイス URI が見つかりません!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: charset ファイル %s にフォントが見つかりません\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: ページが見つかりません!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: 用紙切れです!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER 環境変数が定義されていません!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: プリントファイルが受け付けられませんでした (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: プリンターが応答していません\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: プリンターが応答していません!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: プリンターが 想定外の EOF を送信しました\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "" +"ERROR: リモートホストがコントロールファイルを受け付けませんでした (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: リモートホストがデータファイルを受け付けませんでした (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: プリンターへのデータ送信中にタイムアウトエラーが発生しました\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: ファイル %d をジョブに追加できません: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: ジョブ %d をキャンセルできません: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: PDF ファイルをコピーできません" + +msgid "ERROR: Unable to create pipe" +msgstr "ERROR: pipe を生成できません" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: ソケットを作成できません" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: テンポラリーの圧縮プリントファイルを作成できません: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: テンポラリーファイルを作成できません" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: pictwpstops を実行できません: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: gs プログラムを実行できません" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: pdftops プログラムを実行できません" + +msgid "ERROR: Unable to execute pstops program" +msgstr "ERROR: pstops プログラムを実行できません" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: pictwpstops をフォークできません: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: PAP リクエストを取得できません" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: PAP レスポンスを取得できません" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: プリンター \"%s\" の PPD ファイルを取得できません - %s\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: デフォルトの AppleTalk ゾーンを取得できません" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: ジョブ %d の属性 (%s) を取得できません!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: プリンターのステータス (%s) を取得できません!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: プリンター '%s' が見つかりません\"!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: PAP レスポンスが見つかりません" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: AppleTalk プリンターが見つかりません" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: AppleTalk アドレスを作成できません" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: \"%s\" を開けません - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: %s を開けません: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "ERROR: PPD ファイルを開けません!" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: バナーファイル \"%s\" を開けません - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: デバイスファイル \"%s\" を開けません: %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: ファイル \"%s\" を開けません - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: ファイル \"%s\" を開けません: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: 印刷のためのイメージファイルを開けません!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: プリントファイル \"%s\" を開けません: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: プリントファイル %s を開けません - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: プリントファイル %s を開けません: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "ERROR: ラスターファイル %s を開けません\n" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: テンポラリーの圧縮プリントファイルを開けません: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: テキストカラム %d をプリントできません!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: テキストページ %dx%d をプリントできません!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: プリントデータを読み込めません" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: プリントデータを読み込めません!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: ポートを予約できません" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: ファイルでのオフセット %ld へシークできません - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: ファイルでのオフセット %lld へシークできません - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: LPD コマンドを送信できません" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: PAP tickle 要求を送信できません" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: PAP の初期データ送信要求を送信できません" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: プリントデータを送信できません (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: プリントデータを送信できません!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: プリントファイルをプリンターへ送信できません" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: 最後の NUL をプリンターへ送信できません" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: pictwpstops を待つことができません: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: %d バイトを \"%s\" に書き込めません: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: %d バイトをプリンターに書き込めません!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: コントロールファイルを書き込めません" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: プリントデータを書き込めません" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: プリントデータを書き込めません: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: ラスターデータをドライバーへ書き込めません!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: テンポラリーファイルへ書き込めません" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: 非圧縮ドキュメントデータを書き込めません: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: %d 行: %s は予期せぬテキストです!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: \"%s\" は未知の暗号オプション値です!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: \"%s\" は未知のファイルオーダーです\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: \"%c\" は未知の書式文字です\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: \"%s\" は未知のメッセージカタログの書式です!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: \"%s\" (値 \"%s\") は未知のオプションです!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: \"%s\" は未知のプリントモードです\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: \"%s\" は未知のバージョンオプション値です!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: %s はサポートされていない輝度値です。brightness=100 を使用します!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: %s はサポートされていないガンマ値です。gamma=1000 を使用します!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: %d はサポートされていない number-up 値です。number-up=1 を使用しま" +"す!\n" + +#, c-format +msgid "ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "ERROR: %s はサポートされていない number-up-layout 値です。number-up-layout=lrtb を使用します!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: %s はサポートされていない page-border 値です。page-border=none を使用します!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: doc_printf オーバーフロー (%d バイト) が検出され、中断しました!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops はシグナル %d で終了しました!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops は状態 %d で終了しました!\n" + +msgid "ERROR: recoverable: Unable to connect to printer; will retry in 30 seconds...\n" +msgstr "ERROR: 回復可能: プリンターに接続できません。30 秒後に再試行します...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() が失敗しました" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: プリントファイルの状態を取得できません" + +msgid "Edit Configuration File" +msgstr "設定ファイルの編集" + +msgid "Empty PPD file!" +msgstr "PPD ファイルが空です!" + +msgid "Ending Banner" +msgstr "終了バナー" + +msgid "Enter old password:" +msgstr "古いパスワードを入力:" + +msgid "Enter password again:" +msgstr "パスワードを再度入力:" + +msgid "Enter password:" +msgstr "パスワードを入力:" + +msgid "Enter your username and password or the root username and password to access this page. If you are using Kerberos authentication, make sure you have a valid Kerberos ticket." +msgstr "このページにアクセスするために、あなたのユーザー名とパスワード、あるいは root のユーザー名とパスワードを入力してください。Kerberos 認証を使用している場合、有効な Kerberos チケットがあることを確認してください。" + +msgid "Envelope Feed" +msgstr "封筒フィード" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "エラーポリシー" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Error: '-h' オプションのあとにはホスト名が必要です!\n" + +msgid "Every 10 Labels" +msgstr "10 ラベルごと" + +msgid "Every 2 Labels" +msgstr "2 ラベルごと" + +msgid "Every 3 Labels" +msgstr "3 ラベルごと" + +msgid "Every 4 Labels" +msgstr "4 ラベルごと" + +msgid "Every 5 Labels" +msgstr "5 ラベルごと" + +msgid "Every 6 Labels" +msgstr "6 ラベルごと" + +msgid "Every 7 Labels" +msgstr "7 ラベルごと" + +msgid "Every 8 Labels" +msgstr "8 ラベルごと" + +msgid "Every 9 Labels" +msgstr "9 ラベルごと" + +msgid "Every Label" +msgstr "すべてのラベル" + +msgid "Expectation Failed" +msgstr "Expectation Failed" + +msgid "Export Printers to Samba" +msgstr "Samba へプリンターをエクスポート" + +msgid "FAIL\n" +msgstr "失敗\n" + +msgid "File Folder" +msgstr "ファイルフォルダー" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "ファイルフォルダー - 9/16 x 3 7/16\"" + +#, c-format +msgid "File device URIs have been disabled! To enable, see the FileDevice directive in \"%s/cupsd.conf\"." +msgstr "ファイルデバイス URI は無効になっています! 有効にするには、\"%s/cupsd.conf\" の FileDevice ディレクティブを参照してください。" + +msgid "Folio" +msgstr "フォリオ" + +msgid "Forbidden" +msgstr "Forbidden" + +msgid "Fuser temperature high!" +msgstr "定着器の温度が上っています!" + +msgid "Fuser temperature low!" +msgstr "定着器の温度が下っています!" + +msgid "General" +msgstr "一般" + +msgid "Generic" +msgstr "汎用" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU は不確定の長さを使用しています" + +msgid "Glossy Paper" +msgstr "光沢紙" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "printer-uri 属性を取得しましたが、job-id を取得できませんでした!" + +msgid "Grayscale" +msgstr "グレースケール" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Hanging Folder" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Hanging Folder - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk がシステムプレファレンスで無効にされています\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk がシステムプレファレンスで無効にされています。\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: プリントジョブをキャンセルしています...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: プリンターに接続しました...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: プリンターに接続中...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: コントロールファイルが正常に送信されました\n" + +msgid "INFO: Copying print data...\n" +msgstr "INFO: 印刷データをコピーしています..." + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: データファイルが正常に送信されました\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "INFO: ページ %d を終了...\n" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: ページ %d をフォーマット中...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: イメージファイルをロード中...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: プリンターを探しています...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: コネクションを開いています\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: プリントファイルを送信し、プリンターが作業を完了するのを待っています...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: プリンターがビジー状態です。10 秒後に再試行します...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: プリンターがビジー状態です。30 秒後に再試行します...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: プリンターがビジー状態です。5 秒後に再試行します...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: プリンターが IPP/%d.%d をサポートしていません。IPP/1.0 を試します...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: プリンターがビジー状態です。5 秒後に再試行します...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: プリンターは現在オフラインです。\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: プリンターは現在オフラインです。\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: プリンターは現在オンラインです。\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: プリンターはオフラインです。\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: プリンターに接続できません。30 秒後に再試行します...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: ページ %d をプリント中、%d%% 完了しました...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: ページ %d をプリント中...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: プリントの準備ができています\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: コントロールファイルを送信中 (%lu バイト)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: コントロールファイルを送信中 (%u バイト)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: データを送信中\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: データファイルを送信中 (%ld バイト)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: データファイルを送信中 (%lld バイト)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: プリントデータを送信中...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: プリントファイルを送信、%ld バイト...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: プリントファイルを送信、%lld バイト...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: LPR ジョブをスプール中、%.0f%% 完了しました...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "INFO: ページ %d を開始...\n" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "INFO: プリンターと交信できません。クラス内の次のプリンターにキューします...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: デフォルトの AppleTalk ゾーン \"%s\" を使います\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: ジョブが完了するのを待っています...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: プリンターが使用可能になるのを待っています...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 封筒" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (特大)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 封筒" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 封筒" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "不正な制御文字" + +msgid "Illegal main keyword string" +msgstr "不正なメインキーワード文字列" + +msgid "Illegal option keyword string" +msgstr "不正なオプションキーワード文字列" + +msgid "Illegal translation string" +msgstr "不正な翻訳文字列" + +msgid "Illegal whitespace character" +msgstr "不正な空白文字" + +msgid "Ink/toner almost empty." +msgstr "インクまたはトナーがほとんどありません。" + +msgid "Ink/toner empty!" +msgstr "インクまたはトナーがありません!" + +msgid "Ink/toner waste bin almost full." +msgstr "廃インクまたは廃トナー容器がほとんど一杯です。" + +msgid "Ink/toner waste bin full!" +msgstr "廃インクまたは廃トナー容器が一杯です!" + +msgid "Installable Options" +msgstr "インストール可能オプション" + +msgid "Installed" +msgstr "インストールされています" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar ラベルプリンター" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "インターロックが開いています。" + +msgid "Internal Server Error" +msgstr "サーバー内部エラー" + +msgid "Internal error" +msgstr "内部エラー" + +msgid "Internet Postage 2-Part" +msgstr "Internet Postage 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Internet Postage 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet Postage 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "インターネット印刷プロトコル" + +msgid "Invite Envelope" +msgstr "招待状封筒" + +msgid "Italian Envelope" +msgstr "イタリア封筒" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "ジョブ番号 %d を再開できません - ファイルが見つかりません!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "ジョブ番号 %d は存在しません!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "ジョブ番号 %d はすでに中断されています - キャンセルできません。" + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "ジョブ番号 %d はすでにキャンセルされています - キャンセルできません。" + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "ジョブ番号 %d はすでに完了しています - キャンセルできません。" + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "ジョブ番号 %d はすでに終了し、変更できません!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "ジョブ番号 %d は完了していません!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "ジョブ番号 %d は認証のために保留されていません!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "ジョブ番号 %d は保留されていません!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "ジョブ番号 #%s は存在しません!" + +#, c-format +msgid "Job %d not found!" +msgstr "ジョブ番号 %d は見つかりません!" + +msgid "Job Completed" +msgstr "ジョブ完了" + +msgid "Job Created" +msgstr "ジョブ作成" + +msgid "Job ID: " +msgstr "ジョブ ID: " + +msgid "Job Options Changed" +msgstr "ジョブオプション変更" + +msgid "Job Stopped" +msgstr "ジョブ中止" + +msgid "Job UUID: " +msgstr "ジョブ UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "ジョブは完了し変更できません。" + +msgid "Job operation failed:" +msgstr "ジョブ操作失敗:" + +msgid "Job state cannot be changed." +msgstr "ジョブの状態を変更できません。" + +msgid "Job subscriptions cannot be renewed!" +msgstr "ジョブサブスクリプションが更新できません!" + +msgid "Jobs" +msgstr "ジョブ" + +msgid "Kaku2 Envelope" +msgstr "角 2 封筒" + +msgid "Kaku3 Envelope" +msgstr "角 3 封筒" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR ホストまたはプリンター" + +msgid "Label Printer" +msgstr "ラベルプリンター" + +msgid "Label Top" +msgstr "ラベルトップ" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "言語 \"%s\" はサポートされていません!" + +msgid "Large Address" +msgstr "ラージアドレス" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "ラージアドレス - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "薄い" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "1 行が最大値 (255 文字) を超えています" + +msgid "List Available Printers" +msgstr "使用可能なプリンターをリスト化" + +msgid "Location: " +msgstr "場所: " + +msgid "Long-Edge (Portrait)" +msgstr "長辺給紙 (縦向き)" + +msgid "Make and Model: " +msgstr "プリンタードライバー: " + +msgid "Manual Feed" +msgstr "手差し" + +msgid "Media Dimensions: " +msgstr "用紙の大きさ: " + +msgid "Media Limits: " +msgstr "用紙の印字領域: " + +msgid "Media Name: " +msgstr "用紙名:" + +msgid "Media Size" +msgstr "用紙サイズ" + +msgid "Media Source" +msgstr "給紙" + +msgid "Media Tracking" +msgstr "用紙の経路" + +msgid "Media Type" +msgstr "用紙種類" + +msgid "Media jam!" +msgstr "紙詰まりです!" + +msgid "Media tray almost empty." +msgstr "用紙トレイが空になりかけています。" + +msgid "Media tray empty!" +msgstr "用紙トレイが空になりました!" + +msgid "Media tray missing!" +msgstr "用紙トレイが見つかりません!" + +msgid "Media tray needs to be filled." +msgstr "用紙トレイに補充が必要です。" + +msgid "Medium" +msgstr "紙質" + +msgid "Memory allocation error" +msgstr "メモリ割り当てエラー" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "PPD-Adobe-4.x ヘッダがありません" + +msgid "Missing asterisk in column 1" +msgstr "1 列目にアスタリスクがありません" + +msgid "Missing document-number attribute!" +msgstr "document-number 属性がありません!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "%d 行に二重引用符がありません!" + +msgid "Missing form variable!" +msgstr "form 変数がありません!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "notify-subscription-ids 属性がありません!" + +msgid "Missing requesting-user-name attribute!" +msgstr "requesting-user-name 属性が設定されていません!" + +msgid "Missing required attributes!" +msgstr "必須の属性が設定されていません!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "%d 行に値がありません!" + +msgid "Missing value string" +msgstr "値文字列がありません" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"モデル: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "クラスの変更" + +msgid "Modify Printer" +msgstr "プリンターの変更" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch 封筒" + +msgid "Move All Jobs" +msgstr "すべてのジョブの移動" + +msgid "Move Job" +msgstr "ジョブの移動" + +msgid "Moved Permanently" +msgstr "別の場所へ移動しました" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: プリントファイルを受け付けました - ジョブ ID %d。\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: プリントファイルを受け付けました - ジョブ ID 不明。\n" + +msgid "NULL PPD file pointer" +msgstr "PPD ファイルポインターが NULL です" + +msgid "Name OID uses indefinite length" +msgstr "OID 名は限定的な長さを使用します" + +msgid "Never" +msgstr "Never" + +msgid "New Stylus Color Series" +msgstr "New Stylus Color シリーズ" + +msgid "New Stylus Photo Series" +msgstr "New Stylus Photo シリーズ" + +msgid "No" +msgstr "いいえ" + +msgid "No Content" +msgstr "中身がありません" + +msgid "No PPD name!" +msgstr "PPD の名前がありません!" + +msgid "No VarBind SEQUENCE" +msgstr "VarBind SEQUENCE がありません" + +msgid "No Windows printer drivers are installed!" +msgstr "Windows プリンタードライバーがインストールされていません!" + +msgid "No active connection" +msgstr "アクティブな接続はありません" + +#, c-format +msgid "No active jobs on %s!" +msgstr "%s にはアクティブなジョブはありません!" + +msgid "No attributes in request!" +msgstr "リクエストに属性がありません!" + +msgid "No authentication information provided!" +msgstr "認証情報が提供されていません!" + +msgid "No community name" +msgstr "コミュニティ名がありません" + +msgid "No default printer" +msgstr "デフォルトのプリンターはありません" + +msgid "No destinations added." +msgstr "追加された宛先はありません" + +msgid "No error-index" +msgstr "エラーインデックスがありません" + +msgid "No error-status" +msgstr "エラーステータスがありません" + +msgid "No file!?!" +msgstr "ファイルがありません!?!" + +msgid "No modification time!" +msgstr "変更時刻がありません!" + +msgid "No name OID" +msgstr "OID 名がありません" + +msgid "No printer name!" +msgstr "プリンター名がありません!" + +msgid "No printer-uri found for class!" +msgstr "クラスのプリンターURI が見つかりません!" + +msgid "No printer-uri found!" +msgstr "プリンターURI が見つかりません!" + +msgid "No printer-uri in request!" +msgstr "プリンターURI のリクエストがありません!" + +msgid "No request-id" +msgstr "リクエストID がありません" + +msgid "No subscription attributes in request!" +msgstr "リクエストにサブスクリプション属性がありません!" + +msgid "No subscriptions found." +msgstr "サブスクリプションが見つかりません。" + +msgid "No variable-bindings SEQUENCE" +msgstr "variable-bindings SEQUENCE がありません" + +msgid "No version number" +msgstr "バージョン名がありません" + +msgid "Non-continuous (Mark sensing)" +msgstr "非連続です (Mark sensing)" + +msgid "Non-continuous (Web sensing)" +msgstr "非連続です (Web sensing)" + +msgid "Normal" +msgstr "標準" + +msgid "Not Found" +msgstr "見つかりません" + +msgid "Not Implemented" +msgstr "実装されていません" + +msgid "Not Installed" +msgstr "インストールされていません" + +msgid "Not Modified" +msgstr "変更されていません" + +msgid "Not Supported" +msgstr "サポートされていません" + +msgid "Not allowed to print." +msgstr "印刷が許可されていません。" + +msgid "Note" +msgstr "注意" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC はもうすぐ交換が必要になります。" + +msgid "OPC at end-of-life!" +msgstr "OPC は交換時期です!" + +msgid "Off (1-Sided)" +msgstr "Off (片面)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "オンラインヘルプ" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "%s のオープンに失敗しました: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup の前にまず CloseGroup が必要です" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI の前にまず CloseUI/JCLCloseUI が必要です" + +msgid "Operation Policy" +msgstr "操作ポリシー" + +msgid "Options Installed" +msgstr "インストールされたオプション" + +msgid "Options: " +msgstr "オプション:" + +msgid "Out of toner!" +msgstr "トナー切れです!" + +msgid "Output Mode" +msgstr "出力モード" + +msgid "Output bin almost full." +msgstr "排紙トレイがほとんど一杯です。" + +msgid "Output bin full!" +msgstr "排紙トレイが一杯です!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "プリンター %s の出力は %s に送られます\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "プリンター %s の出力は、リモートプリンター %s (%s 上) に送られます\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "プリンター %s/%s の出力は %s に送られます\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "プリンター %s/%s の出力は、リモートプリンター %s (%s 上) に送られます\n" + +msgid "Output tray missing!" +msgstr "排紙トレイが見つかりません!" + +msgid "PASS\n" +msgstr "合格\n" + +msgid "PCL Laser Printer" +msgstr "PCL レーザープリンター" + +msgid "PRC1 Envelope" +msgstr "PRC1 封筒" + +msgid "PRC10 Envelope" +msgstr "PRC10 封筒" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2 封筒" + +msgid "PRC3 Envelope" +msgstr "PRC3 封筒" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (特大)" + +msgid "PRC4 Envelope" +msgstr "PRC4 封筒" + +msgid "PRC5 Envelope" +msgstr "PRC5 封筒" + +msgid "PRC6 Envelope" +msgstr "PRC6 封筒" + +msgid "PRC7 Envelope" +msgstr "PRC7 封筒" + +msgid "PRC8 Envelope" +msgstr "PRC8 封筒" + +msgid "PRC9 Envelope" +msgstr "PRC9 封筒" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "パケットが Get-Response-PDU を含んでいません" + +msgid "Packet does not start with SEQUENCE" +msgstr "パケットが SEQUENCE から始まりません" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "%s のパスワード (%s 上)? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "%s のパスワード (SAMBA 経由で %s にアクセスするのに必要):" + +msgid "Pause Class" +msgstr "クラスの休止" + +msgid "Pause Printer" +msgstr "プリンターの休止" + +msgid "Peel-Off" +msgstr "Peel-Off" + +msgid "Personal Envelope" +msgstr "パーソナル封筒" + +msgid "Photo" +msgstr "写真" + +msgid "Photo Labels" +msgstr "写真ラベル" + +msgid "Plain Paper" +msgstr "普通紙" + +msgid "Policies" +msgstr "ポリシー" + +msgid "Port Monitor" +msgstr "ポートモニター" + +msgid "PostScript Printer" +msgstr "ポストスクリプトプリンター" + +msgid "Postcard" +msgstr "ハガキ" + +msgid "Print Density" +msgstr "印刷密度" + +msgid "Print Job:" +msgstr "ジョブの印刷:" + +msgid "Print Mode" +msgstr "印刷モード" + +msgid "Print Rate" +msgstr "印刷レート" + +msgid "Print Self-Test Page" +msgstr "自己テストページの印刷" + +msgid "Print Speed" +msgstr "印刷速度" + +msgid "Print Test Page" +msgstr "テストページの印刷" + +msgid "Print and Cut" +msgstr "プリントしてカット" + +msgid "Print and Tear" +msgstr "プリントして切り取る" + +msgid "Printed For: " +msgstr "プリント対象:" + +msgid "Printed From: " +msgstr "プリント元:" + +msgid "Printed On: " +msgstr "プリント先:" + +msgid "Printer Added" +msgstr "追加されたプリンター" + +msgid "Printer Default" +msgstr "デフォルトのプリンター" + +msgid "Printer Deleted" +msgstr "削除されたプリンター" + +msgid "Printer Modified" +msgstr "変更されたプリンター" + +msgid "Printer Name: " +msgstr "プリンター名:" + +msgid "Printer Paused" +msgstr "プリンターの休止" + +msgid "Printer Settings" +msgstr "プリンター設定" + +msgid "Printer offline." +msgstr "プリンターはオフラインです。" + +msgid "Printer:" +msgstr "プリンター:" + +msgid "Printers" +msgstr "プリンター" + +msgid "Purge Jobs" +msgstr "ジョブの削除" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Quota の制限に達しました。" + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "ランク 所有者 ジョブ ファイル 合計サイズ\n" + +msgid "Rank Owner Pri Job Files Total Size\n" +msgstr "ランク 所有者 優先 ジョブ ファイル 合計サイズ\n" + +msgid "Reject Jobs" +msgstr "ジョブの拒否" + +msgid "Reprint After Error" +msgstr "エラー後の再印刷" + +msgid "Request Entity Too Large" +msgstr "要求するエンティティが大きすぎます" + +msgid "Resolution" +msgstr "解像度" + +msgid "Resume Class" +msgstr "クラスを再開する" + +msgid "Resume Printer" +msgstr "プリンターを再開する" + +msgid "Return Address" +msgstr "アドレスを戻す" + +msgid "Return Address - 3/4 x 2\"" +msgstr "アドレスを戻す ー 3/4 x 2\"" + +msgid "Rewind" +msgstr "戻る" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "コマンドを実行中: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI プリンター" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE は不定長を使用しています" + +msgid "See Other" +msgstr "残りを見てください" + +#, c-format +msgid "Serial Port #%d" +msgstr "シリアルポート #%d" + +msgid "Server Restarted" +msgstr "再起動されたサーバー" + +msgid "Server Security Auditing" +msgstr "サーバーのセキュリティーチェック" + +msgid "Server Started" +msgstr "開始されたサーバー" + +msgid "Server Stopped" +msgstr "停止されたサーバー" + +msgid "Service Unavailable" +msgstr "利用できないサービス" + +msgid "Set Allowed Users" +msgstr "許可するユーザーの設定" + +msgid "Set As Server Default" +msgstr "サーバーをデフォルトに設定" + +msgid "Set Class Options" +msgstr "クラスオプションを設定" + +msgid "Set Printer Options" +msgstr "プリンターオプションの設定" + +msgid "Set Publishing" +msgstr "公開の設定" + +msgid "Shipping Address" +msgstr "発送アドレス" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "発送アドレス - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "短辺 (横原稿)" + +msgid "Special Paper" +msgstr "スペシャルペーパー" + +msgid "Standard" +msgstr "標準" + +msgid "Starting Banner" +msgstr "開始バナー" + +msgid "Statement" +msgstr "記述" + +msgid "Stylus Color Series" +msgstr "Stylus Color シリーズ" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo シリーズ" + +msgid "Super A" +msgstr "スーパー A" + +msgid "Super B" +msgstr "スーパー B" + +msgid "Super B/A3" +msgstr "スーパー B/A3" + +msgid "Switching Protocols" +msgstr "プロトコルの変更" + +msgid "Tabloid" +msgstr "タブロイド" + +msgid "Tabloid (Oversize)" +msgstr "タブロイド (特大)" + +msgid "Tear" +msgstr "Tear" + +msgid "Tear-Off" +msgstr "Tear-Off" + +msgid "Tear-Off Adjust Position" +msgstr "Tear-Off 位置調節" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "PPD ファイル \"%s\" が見つかりません。" + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "PPD ファイル \"%s\" が開きませんでした: %s" + +msgid "The class name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." +msgstr "クラス名は 127 文字以内の表示可能文字から成り、空白、スラッシュ (/)、ポンド記号 (#) を含んではなりません。" + +msgid "The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "notify-lease-duration 属性は、ジョブサブスクリプションと一緒に使うことはできません。" + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "notify-user-data 値が大きすぎます (%d > 63 オクテット)!" + +msgid "The printer name may only contain up to 127 printable characters and may not contain spaces, slashes (/), or the pound sign (#)." +msgstr "プリンター名は 127 文字以内の表示可能文字から成り、空白、スラッシュ (/)、ポンド記号 (#) を含んではなりません。" + +msgid "The printer or class is not shared!" +msgstr "プリンターまたはクラスは共有できません!" + +msgid "The printer or class was not found." +msgstr "プリンターまたはクラスが見つかりませんでした。" + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "printer-uri \"%s\" には、無効な文字が含まれています。" + +msgid "The printer-uri attribute is required!" +msgstr "printer-uri 属性は必須です!" + +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "printer-uri は、\"ipp://ホスト名/classes/クラス名\" 形式でなければなりません。" + +msgid "The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "printer-uri は \"ipp://ホスト名/printers/プリンター名\" 形式でなければなりません。" + +msgid "The subscription name may not contain spaces, slashes (/), question marks (?), or the pound sign (#)." +msgstr "サブスクリプション名には、スペース、スラッシュ (/)、疑問府 (?)、ポンド記号 (#) を使用しないでください。" + +msgid "There are too many subscriptions." +msgstr "サブスクリプションが多すぎます。" + +msgid "Thermal Transfer Media" +msgstr "熱転写メディア" + +msgid "Title: " +msgstr "タイトル: " + +msgid "Toner low." +msgstr "トナーが少なくなっています。" + +msgid "Too many active jobs." +msgstr "アクティブなジョブが多すぎます。" + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "job-sheets 値が多すぎます (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "printer-state-reasons 値が多すぎます (%d > %d)!" + +msgid "Transparency" +msgstr "OHP シート" + +msgid "Tray" +msgstr "トレイ" + +msgid "Tray 1" +msgstr "トレイ 1" + +msgid "Tray 2" +msgstr "トレイ 2" + +msgid "Tray 3" +msgstr "トレイ 3" + +msgid "Tray 4" +msgstr "トレイ 4" + +msgid "URI Too Long" +msgstr "URI が長過ぎます" + +msgid "US Executive" +msgstr "US エグゼクティブ" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US レジャー" + +msgid "US Legal" +msgstr "US リーガル" + +msgid "US Legal (Oversize)" +msgstr "US リーガル (特大)" + +msgid "US Letter" +msgstr "US レター" + +msgid "US Letter (Oversize)" +msgstr "US レター (特大)" + +msgid "US Letter (Small)" +msgstr "US レター (小)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB シリアルポート #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "cupsd.conf ファイルにアクセスできません:" + +msgid "Unable to add RSS subscription:" +msgstr " RSS 購読を追加できません:" + +msgid "Unable to add class:" +msgstr "クラスを追加できません:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "宛先\"%s\"にジョブを追加できません!" + +msgid "Unable to add printer:" +msgstr "プリンターを追加ができません:" + +msgid "Unable to allocate memory for file types!" +msgstr "ファイルタイプ用にメモリを割り当てられません!" + +msgid "Unable to cancel RSS subscription:" +msgstr "RSS 購読をキャンセルできません:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "printer-is-shared 属性を変更することができません:" + +msgid "Unable to change printer:" +msgstr "プリンターを変更できません:" + +msgid "Unable to change server settings:" +msgstr "サーバーの設定を変更できません:" + +msgid "Unable to connect to host." +msgstr "ホストに接続できません" + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "64-bit 版の CUPS プリンタードライバーファイルをコピーできません (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "64-bit 版の Windows プリンタードライバーをコピーできません (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "複数の CUPS プリンタードライバーファイルをコピーできません (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "PPD ファイルをコピーできません! - %s" + +msgid "Unable to copy PPD file!" +msgstr "PPD ファイルをコピーできません!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "複数の Windows 2000 プリンタードライバーファイルをコピーできません (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "複数の Windows 9x プリンタードライバーファイルをコピーできません (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "インターフェイススクリプトをコピーできません! - %s" + +msgid "Unable to create printer-uri!" +msgstr "printer-uri を作成できません!" + +msgid "Unable to create temporary file:" +msgstr "テンポラリファイルを作成できません:" + +msgid "Unable to delete class:" +msgstr "クラスを削除できません:" + +msgid "Unable to delete printer:" +msgstr "プリンターを削除できません:" + +msgid "Unable to do maintenance command:" +msgstr "メンテナンスコマンドを実行できません:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "1MB 以上の cupsd.conf ファイルは編集できません!" + +msgid "Unable to find destination for job!" +msgstr "ジョブの宛先が見つかりません!" + +msgid "Unable to find printer!\n" +msgstr "プリンターが見つかりません!\n" + +msgid "Unable to get class list:" +msgstr "クラスリストを取得できません:" + +msgid "Unable to get class status:" +msgstr "クラスの状態を取得できません:" + +msgid "Unable to get list of printer drivers:" +msgstr "プリンタードライバーのリストを取得できません:" + +msgid "Unable to get printer attributes:" +msgstr "プリンター属性を取得できません:" + +msgid "Unable to get printer list:" +msgstr "プリンターリストを取得できません:" + +msgid "Unable to get printer status:" +msgstr "プリンターの状態を取得できません:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "複数の Windows 2000 プリンタードライバーファイルをインストールできません (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "複数の Windows 9x プリンタードライバーファイルをインストールできません (%d)!" + +msgid "Unable to modify class:" +msgstr "クラスを変更できません:" + +msgid "Unable to modify printer:" +msgstr "プリンターを変更できません:" + +msgid "Unable to move job" +msgstr "ジョブを移動できません" + +msgid "Unable to move jobs" +msgstr "複数のジョブを移動できません" + +msgid "Unable to open PPD file" +msgstr "PPD ファイルを読み込むことができません" + +msgid "Unable to open PPD file:" +msgstr "PPD ファイルを読み込むことができません:" + +msgid "Unable to open cupsd.conf file:" +msgstr "cupsd.conf ファイルを開けません:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "ドキュメント %d (ジョブ %d)を開けません!" + +msgid "Unable to print test page:" +msgstr "テストページを印刷できません:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "\"%s\" を実行できません: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "プリンタードライバーにコマンドを送信できません!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Windows プリンタードライバーを設定できません (%d)!" + +msgid "Unable to set options:" +msgstr "オプションを設定できません:" + +msgid "Unable to set server default:" +msgstr "サーバーをデフォルトに設定できません:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "cupsd.conf ファイルをアップロードできません:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "古いタイプの USB クラスドライバーは使用できません!\n" + +msgid "Unauthorized" +msgstr "不許可" + +msgid "Units" +msgstr "ユニット" + +msgid "Unknown" +msgstr "未知" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "\"%s\" は未知の printer-error-policy です。" + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "\"%s\" は未知の printer-op-policy です。" + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "\"%s\" はサポートされていない文字セットです!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "\"%s\" はサポートされていない圧縮形式です!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "%s はサポートされていない圧縮属性です!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "\"%s\" はサポートされていない形式です!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "'%s' はサポートされていない形式です!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "'%s/%s' はサポートされていない形式です!" + +msgid "Unsupported value type" +msgstr "サポートされていない型の値です" + +msgid "Upgrade Required" +msgstr "アップグレードが必要です" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"使い方:\n" +"\n" +" lpadmin [-h サーバー] -d 宛先\n" +" lpadmin [-h サーバー] -x 宛先\n" +" lpadmin [-h サーバー] -p プリンター [-c 追加クラス] [-i インターフェイ" +"ス]\n" +" [-m モデル] [-r 削除クラス] [-v デバイス]\n" +" [-D 宛先] [-P PPD ファイル] [-o 名前=値]\n" +" [-u allow:ユーザー,ユーザー] [-u deny:ユーザー,ユー" +"ザー]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "使い方: %s ジョブID ユーザー タイトル コピー数 オプション [ファイル名]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "使い方: %s ジョブID ユーザー タイトル コピー数 オプション [ファイル]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "使い方: %s ジョブID ユーザー タイトル コピー数 オプション ファイル\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" +"使い方: convert [オプション]\n" +"\n" +"オプション:\n" +"\n" +" -e PPD ファイルからすべてのフィルターを使用する\n" +" -f filename 変換するファイルを指定する (指定がなければ stdin となる)\n" +" -o filename 生成するファイルを指定する (指定がなければ stdout となる)\n" +" -i mime/type 入力の MIME タイプを指定する (指定がなければ自動タイプ)\n" +" -j mime/type 出力の MIME タイプを指定する (指定がなければ application/pdf)\n" +" -P filename.ppd PPD ファイルを指定する\n" +" -a 'name=value ...' オプションを指定する\n" +" -U username ジョブのユーザー名を指定する\n" +" -J title タイトルを指定する\n" +" -c copies 部数を指定する\n" +" -u 終了したときに PPD ファイルを削除する\n" +" -D 終了したときに入力ファイルを削除する\n" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"使い方: cupsaddsmb [オプション] プリンター ... プリンターN\n" +" cupsaddsmb [オプション] -a\n" +"\n" +"オプション:\n" +" -E サーバーとの接続を暗号化する\n" +" -H sambaサーバー 指定の SAMBA サーバーを使う\n" +" -U sambaユーザー 指定の SAMBA ユーザーを使って認証する\n" +" -a すべてのプリンターをエキスポートする\n" +" -h cupsサーバー 指定の CUPS サーバーを使う\n" +" -v 冗長にする (コマンドを表示する)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"使い方: cupsctl [オプション] [パラメータ=値 ... パラメータN=値N]\n" +"\n" +"オプション:\n" +"\n" +" -E 暗号化を有効にする\n" +" -U ユーザ名 ユーザー名を指定する\n" +" -h サーバー[:ポート] サーバーアドレスを指定する\n" +"\n" +" --[no-]debug-logging デバッグログの有効/無効を切り替える\n" +" --[no-]remote-admin リモート管理の有効/無効を切り替える\n" +" --[no-]remote-any インターネットからのアクセスを許可/禁止する\n" +" --[no-]remote-printers リモートプリンターを表示/非表示にする\n" +" --[no-]share-printers プリンター共有の有効/無効を切り替える\n" +" --[no-]user-cancel-any あらゆるジョブのキャンセルをユーザーに許可/禁止す" +"る\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"使い方: cupsd [-c 設定ファイル] [-f] [-F] [-h] [-l]\n" +"\n" +"-c 設定ファイル 別の設定ファイルをロードする\n" +"-f フォアグラウンドで実行する\n" +"-F フォアグラウンドで実行するがデタッチする\n" +"-h この使い方を表示する\n" +"-l launchd(8) から cupsd を実行する\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" +使い方: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf 使用する cupsd.conf ファイルの指定\n" +" -e PPD ファイルで指定されたすべてのフィルターを使用する\n" +" -j job-id[,N] フィルターファイル N を指定されたジョブから使用する (デフォルトは ファイル 1)\n" +" -n copies 印刷部数を指定する\n" +" -o name=value オプションを指定する\n" +" -p filename.ppd PPDファイルを指定する\n" +" -t title タイトルを指定する\n" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript itself.\n" +msgstr "" +"使い方: cupstestdsc [オプション] ファイル名.ps [... ファイル名.ps]\n" +" cupstestdsc [オプション] -\n" +"\n" +"オプション:\n" +"\n" +" -h プログラムの使い方を表示する\n" +"\n" +" 注意: このプログラムは DSC コメントを検証するだけで、PostScript 自身を検証するものではありません。\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" +使い方: cupstestppd [オプション] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [オプション] -\n" +"\n" +"オプション:\n" +"\n" +" -R root-directory 違うルートディレクトリを指定\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes,translations}\n" +" 指定されたものをエラーの代わりに警告として扱う\n" +" -q メッセージなしモードで動く\n" +" -r 「リラックス」オープンモードで開く\n" +" -v メッセージ多めモード\n" +" -vv メッセージ非常に多めモード\n" + +msgid "Usage: lpmove job/src dest\n" +msgstr "使い方: lpmove ジョブ/ソース 宛先\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"使い方: lpoptions [-h サーバー] [-E] -d プリンター\n" +"   lpoptions [-h サーバー] [-E] [-p プリンター] -l\n" +" lpoptions [-h サーバー] [-E] -p プリンター -o オプション[=値] ...\n" +" lpoptions [-h サーバー] [-E] -x プリンター\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "使い方: lppasswd [-g グループ名]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"使い方: lppasswd [-g グループ名] [ユーザ名]\n" +" lppasswd [-g グループ名] -a [ユーザ名]\n" +" lppasswd [-g グループ名] -x [ユーザ名]\n" + +msgid "Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"使い方: lpq [-P 宛先] [-U ユーザー名] [-h ホスト名[:ポート]] [-l] [+間隔]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"使い方: ppdc [オプション] ファイル名.drv [ ... ファイル名N.drv ]\n" +"オプション:\n" +" -D 変数名=値 変数名で指定した変数に値をセットする\n" +" -I include-dir include-dir で指定したディレクトリをサーチパスに追加\n" +" -c catalog.po 指定したメッセージカタログをロードする\n" +" -d output-dir 出力ディレクトリ(output-dir)を指定する\n" +" -l lang[,lang,...] 出力言語を指定する。(複数可能)\n" +" -m ModelName の値をファイル名として使用する\n" +" -t PPD を出力しないでテストする\n" +" -v 冗長出力を行う (v を追加してさらに冗長に)\n" +" -z PPD ファイルを GNU zip を使って圧縮する\n" +" --cr ラインの最後は CR (Mac OS 9 方式).\n" +" --crlf ラインの最後は CR + LF (Windows 方式).\n" +" --lf ラインの最後は LF (UNIX/Linux/Mac OS X 方式).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"使い方: ppdhtml [オプション] ファイル名.drv >ファイル名.html\n" +" -D 変数名=値 変数名で指定した変数に値をセットする\n" +"オプション:\n" +" -I include-dir include-dir で指定したディレクトリをサーチパスに追加\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"使い方: ppdi [オプション] ファイル名.ppd [ ... ファイル名N.ppd ]\n" +"オプション:\n" +" -I インクルードディレクトリ\n" +" -o ファイル名.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"使い方: ppdmerge [オプション] ファイル名.ppd [ ... ファイル名N.ppd ]\n" +"オプション:\n" +" -o ファイル名.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"使い方: ppdpo [オプション] -o ファイル名.po ファイル名.drv [ ... ファイル名N." +"drv ]\n" +"オプション:\n" +" -D 変数名=値 変数名で指定した変数に値をセットする\n" +" -I include-dir include-dir で指定したディレクトリをサーチパスに追加\n" +" -v 冗長出力を行う (v を追加してさらに冗長に)\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "使い方: snmp [ホストまたはIPアドレス]\n" + +msgid "Value uses indefinite length" +msgstr "値は不定長です" + +msgid "VarBind uses indefinite length" +msgstr "VarBind は不定長です" + +msgid "Version uses indefinite length" +msgstr "Version は不定長です" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: 発見した順番に %d 台のプリンターだけ追加します" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: 論理値は、waiteof オプション \"%s\" であるべきです\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: サイドチャンネルの読み出しに失敗しました!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: オプション \"%s\" は IncludeFeature 経由で含めることはできません!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: プリンターが反応しません\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: プリンターが意図しない EOF を返しました\n" + +#, c-format +msgid "WARNING: Remote host did not respond with command status byte after %d seconds!\n" +msgstr "WARNING: リモートホストは %d 秒経ってもコマンド・ステータス・バイトを返しませんでした!\n" + +#, c-format +msgid "WARNING: Remote host did not respond with control status byte after %d seconds!\n" +msgstr "WARNING: リモートホストは %d 秒経ってもコントロール・ステータス・バイトを返しませんでした!\n" + +#, c-format +msgid "WARNING: Remote host did not respond with data status byte after %d seconds!\n" +msgstr "WARNING: リモートホストは %d 秒経ってもデータ・ステータス・バイトを返しませんでした!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI コマンドはタイムアウトしました (%d)。再試行中...\n" + +msgid "WARNING: This document does not conform to the Adobe Document Structuring Conventions and may not print correctly!\n" +msgstr "WARNING: この書類は Adobe Document Structuring Conventions に適合しておらず、正しくプリントできない可能性があります!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: \"%s:%s\": %s を開けません\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: PAP ステータス・リクエストを送信できません" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: %d タイプの意図しない PAP パケット\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: 未知の PAP パケットのタイプ %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: \"%s\" (オプション \"%s\" 用) は未知の設定です!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: \"%s\" は未知のオプションです!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: %s はサポートしないボーレートです!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: ステータス・オプションの期待値は \"%s\"\n" + +#, c-format +msgid "WARNING: recoverable: Network host '%s' is busy; will retry in %d seconds...\n" +msgstr "WARNING: 回復可能: ネットワークホスト '%s' はビジー状態です (%d 秒後に再試行します...)\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "警告、Windows 2000 プリンタードライバーがインストールされていません!" + +msgid "Yes" +msgstr "はい" + +#, c-format +msgid "You must access this page using the URL https://%s:%d%s." +msgstr "このページには URL https://%s:%d%s を使ってアクセスする必要があります。" + +msgid "You4 Envelope" +msgstr "洋形 4 号" + +msgid "ZPL Label Printer" +msgstr "ZPL ラベル・プリンター" + +msgid "Zebra" +msgstr "ゼブラ" + +msgid "aborted" +msgstr "停止" + +msgid "canceled" +msgstr "キャンセル" + +msgid "completed" +msgstr "完了" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: 変換するファイルを指定するには、-f オプションを使ってください。\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced の実行に失敗しました。" + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd の実行に失敗しました。" + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: プリンター \"%s\" の PPD ファイルがありません - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: サーバー: %s に接続できません\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: \"%s\" は未知のオプションです!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: \"-%c\"は未知のオプションです!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: -c オプションのあとには設定ファイル名が必要です!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: カレント・ディレクトリを取得できません!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: \"%s\" は未知の引数です - 停止します!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: \"%c\" は未知のオプションです - 停止します!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: launchd(8) サポートがコンパイルされていないので、通常モードで動作します。\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: 不正な文書番号 %d です!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: 不正なジョブID %d です!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: ひとつのファイル名のみを指定できます!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: ジョブ・ファイルを取得できません - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: -q オプションは -v オプションと両立できません。\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: -v オプションは -q オプションと両立できません。\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "%s/%s のデバイス: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "%s のデバイス: %s\n" + +msgid "error-index uses indefinite length" +msgstr "エラー・インデックスは不定長です" + +msgid "error-status uses indefinite length" +msgstr "エラー・ステータスは不定長です" + +msgid "held" +msgstr "ホールド" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tコマンドのヘルプを取得\n" + +msgid "idle" +msgstr "待機中" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri 属性がありません!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: クラス名は表示可能文字のみで構成されなければなりません!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: '-P' オプションのあとに PPD が必要です!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: '-u' オプションのあとには allow/deny:ユーザーリスト が必要です!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: '-r' オプションのあとにはクラス名が必要です!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: '-c' オプションのあとにはクラス名が必要です!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: '-D' オプションのあとに説明が必要です!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: '-v' オプションのあとにはデバイス URI が必要です!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: '-I' オプションのあとにファイル形式が必要です!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: '-h' オプションのあとにはホスト名が必要です!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: '-i' オプションのあとにはインターフェイス名が必要です!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: '-L' オプションのあとに場所が必要です!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: '-m' オプションのあとにはモデル名が必要です!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: '-o' オプションのあとには 変数名=値 が必要です!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: '-p' オプションのあとにはプリンター名が必要です!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: '-d' オプションのあとにはプリンター名が必要です!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: '-x' オプションのあとにはプリンター名またはクラス名が必要です!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: メンバー名が見当たりません!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: プリンター %s はすでにクラス %s のメンバーです。\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: プリンター %s はクラス %s のメンバーではありません。\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: プリンター名には印字可能な文字のみ使用できます!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "lpadmin: クラスにプリンターを追加できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: サーバーに接続できません: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: PPD ファイル \"%s\" を開けません - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: ファイル \"%s\" を開けません: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: クラスからプリンターを削除できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: PPD ファイルを設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: デバイス URI を設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: インターフェイス・スクリプトまたは PPD ファイルを設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: インターフェイススクリプトを設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: プリンターの説明を設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: プリンターの場所が設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: プリンター・オプションを設定できません:\n" +" 先にプリンター名を指定する必要があります!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin:\"%s\" は未知の allow/deny オプションです!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: '%s' は未知の引数です!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: '%c' は未知のオプションです!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: 警告 - コンテンツタイプリストは無視されます!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" +"lpinfo: --device-id の後には、1284デバイスIDを指定する必要があります!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: --language の後には、言語を指定する必要があります!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "" +"lpinfo: --make-and-model の後には、メーカーとモデルを指定する必要がありま" +"す!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: --product の後には、製品名を指定する必要があります!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "" +"lpinfo: --exclude-schemes の後には、スキーマ・リストを指定する必要がありま" +"す!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "" +"lpinfo: --include-schemes の後には、スキーマ・リストを指定する必要がありま" +"す!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: --timeout の後には、タイムアウト値を指定する必要があります!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: 未知の引数 '%s'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: 未知のオプション '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: 未知のオプション '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: サーバーに接続できません: %s!\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: 未知の引数 '%s'!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: 未知のオプション '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: プリンターがありません!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: プリンターまたはインスタンスを追加できません: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: %s の PPD ファイルを開けません!: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: %s の PPD ファイルを開けません!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: 未知のプリンターまたはクラスです!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: root だけがパスワードの追加と削除を行えます!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: パスワードファイルがビジー状態です!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: パスワードファイルは更新されません!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: すみませんが、パスワードがマッチしません!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: すみませんが、パスワードは拒否されました。\n" +"パスワードは少なくとも 6 文字以上で、あなたのユーザー名を含んではならず、\n" +"少なくとも 1 つの英字および数値を含んでなければなりません。\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: すみませんが、パスワードがマッチしません!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: パスワード文字列をコピーできません: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: パスワードファイルを開けません: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: パスワードファイルに書き込めません: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: 古いパスワードファイルのバックアップに失敗しました: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: パスワードファイルの名前の変更に失敗しました: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: ユーザー \"%s\" およびグループ \"%s\" は存在しません。\n" + +#, c-format +msgid "lpstat: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "lpstat: エラー - 環境変数 %s が、存在しない宛先 \"%s\" を指しています!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "クラス %s のメンバー:\n" + +msgid "no entries\n" +msgstr "エントリーがありません\n" + +msgid "no system default destination\n" +msgstr "システムのデフォルトの宛先がありません\n" + +msgid "notify-events not specified!" +msgstr "notify-events が指定されていません!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI \"%s\" はすでに使われています!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI \"%s\" には未知のスキームが使われています!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d は良くありません!" + +msgid "pending" +msgstr "保留" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: ディレクトリー \"%s\" を追加しています...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: %s から UI テキストを追加または更新しています...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: 不正な boolean 値 (%s) があります。%d 行目、ファイル名 %s。\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: 不正な resolution 名 \"%s\" があります。%d 行目、ファイル名 %s !\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "" +"ppdc: 不正な status キーワード %s があります。%d 行目、ファイル名 %s !\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: 不正な数値置換 ($%c) があります。%d 行目、ファイル名 %s。\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s で、Option がないのに Choice が見つかりました!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "" +"ppdc: locale %s に対して #po が2重に定義されています。%d 行目、ファイル名 %" +"s !\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s においてフィルター定義が必要です!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s においてプログラム名が必要です!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: %d 行目、ファイル名 %s において boolean 値が必要です。\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Font の後に charset が必要です!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: %d 行目、ファイル名 %s において choice code が必要です。\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: %d 行目、ファイル名 %s において choice name/text が必要です。\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において ColorModel に対する color order が必要" +"です!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において ColorModel に対する colorspace が必要で" +"す!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において ColorModel に対する compression が必要" +"です!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において UIConstraints に対する constraint が必" +"要です!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において DriverType の後に driver type keyword " +"が必要です!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において Duplex の後に type が必要です!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Font の後に encoding が必要です!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: #po %s の後にファイル名が必要です! (%d 行目, ファイル %s)\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において group name/text が必要です!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において include ファイル名が必要です!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において整数指定が必要です!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において #po の後に locale が必要です!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: %s の後に name が必要です。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において FileName の後に name が必要です!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において Font の後に name が必要です!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Manufacturer の後に name が必要です!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において MediaSize の後に name が必要です!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において ModelName の後に name が必要です!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において PCFileName の後に name が必要です!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: %s の後に name/text が必要です。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Installable の後に name/text が必要で" +"す!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Resolution の後に name/text が必要で" +"す!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において ColorModel に対する name/text が必要で" +"す!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において option name/text が必要です!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において option section が必要です!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において option type が必要です!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Resolution の後に override field が必要" +"です!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において実数が必要です!\n" + +#, c-format +msgid "ppdc: Expected resolution/mediatype following ColorProfile on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において ColorProfile に続いて resolution/" +"mediatype が必要です!\n" + +#, c-format +msgid "ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において SimpleColorProfile に続いて resolution/" +"mediatype が必要です!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: %s の後に selector が必要です。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において Font の後に status が必要です!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Copyright の後に文字列が必要です!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Version の後に文字列が必要です!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において 2 つのオプション名が必要です!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: %s の後に value が必要です。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s において Font の後に version が必要です!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: 無効な #include/#po ファイル名です \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s においてフィルターに対する無効な cost がありま" +"す!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s においてフィルターに対する無効な空の MIME type " +"があります!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" +"ppdc: %d 行目、ファイル名 %s においてフィルターに対する無効な空の program " +"name があります!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: 無効な option section があります \"%s\"。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: 無効な option type があります \"%s\"。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: ドライバー情報ファイル \"%s\" を読み込んでいます...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: ロケール \"%s\" のメッセージを読み込んでいます...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: \"%s\" からメッセージを読み込んでいます...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: \"%s\" の最後に #endif が見つかりません!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において #if が見つかりません!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: ロケール %s に対するメッセージカタログが見つかりません!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "ppdc: オプション %s が行 %d、ファイル %s の 2 つの異なるグループで定義されています!\n" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: オプション %s は異なる型で再定義されています。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において Option constraint は *name で指定します!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: %d 行目、ファイル名 %s において #if のネストが多すぎます!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: PPD ファイル \"%s\" を作成できません - %s。\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: ディレクトリー \"%s\" を作成できません - %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: 出力 pipe が作成できません: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: cupstestppd を実行できません: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: #po ファイル %s が見つかりません。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: インクルードファイル %s が見つかりません。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: \"%s\" に対する地域化情報が見つかりません - %s \n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: \"%s\" に対する地域化情報を読み込めません - %s \n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: 変数 (%s) は未定義です。%d 行目、ファイル名 %s。\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: %s は未知のドライバータイプです。%d 行目、ファイル名 %s。\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: \"%s\" は未知の両面タイプです。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: \"%s\" は未知の用紙サイズです。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: 未知の token \"%s\" があります。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "ppdc: 実数に未知の終了文字 \"%s\" があります。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: %c で始まる文字に対して終端文字がありません。%d 行目、ファイル名 %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: %s を書き込んでいます...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: ディレクトリー \"%s\" に PPD ファイルを書き込んでいます...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: 不正な LanguageVersion \"%s\" が %s にあります!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: PPD ファイル %s を無視します...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: %s を %s にバックアップできません - %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "プリンター %s は %s から無効です -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "プリンター %s は待機中です。%s 以来有効です\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "プリンター %s は %s-%d を印刷しています。%s 以来有効です\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "プリンター %s/%s は %s から無効です -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "プリンター %s/%s は待機中です。%s 以来有効です\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "プリンター %s/%s は現在 %s-%d を印刷中です。%s 以来有効です\n" + +msgid "processing" +msgstr "処理中" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "リクエスト ID は %s-%d です (%d 個のファイル)\n" + +msgid "request-id uses indefinite length" +msgstr "リクエスト ID の長さが不定" + +msgid "scheduler is not running\n" +msgstr "スケジューラーは動作していません\n" + +msgid "scheduler is running\n" +msgstr "スケジューラーは動作中です\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "%s の状態取得に失敗しました: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tデーモンとキューの状態を表示\n" + +msgid "stopped" +msgstr "停止" + +#, c-format +msgid "system default destination: %s\n" +msgstr "システムのデフォルトの宛先: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "システムのデフォルトの宛先: %s/%s\n" + +msgid "unknown" +msgstr "未知" + +msgid "untitled" +msgstr "タイトルなし" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings の長さが不定" + + +# +# End of "$Id$". +# diff --git a/locale/cups_ko.po b/locale/cups_ko.po new file mode 100644 index 0000000000..e1e4bdb37e --- /dev/null +++ b/locale/cups_ko.po @@ -0,0 +1,5623 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(전체)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(없음)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d개의 엔트리\n" + +msgid "\tAfter fault: continue\n" +msgstr "\t결함 후: 계속\n" + +msgid "\tAlerts:" +msgstr "\t경고:" + +msgid "\tBanner required\n" +msgstr "\t배너 필요함\n" + +msgid "\tCharset sets:\n" +msgstr "\t문자 세트 설정:\n" + +msgid "\tConnection: direct\n" +msgstr "\t연결: 직접\n" + +msgid "\tConnection: remote\n" +msgstr "\t연결: 원격\n" + +msgid "\tDefault page size:\n" +msgstr "\t기본 페이지 크기:\n" + +msgid "\tDefault pitch:\n" +msgstr "\t기본 피치:\n" + +msgid "\tDefault port settings:\n" +msgstr "\t기본 포트 설정:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\t설명: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\t구성 마운트됨:\n" +"\t콘텐츠 유형: 모두\n" +"\t프린터 유형: 알 수 없음\n" + +msgid "\tForms allowed:\n" +msgstr "\t구성 허용됨:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\t인터페이스: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\t인터페이스: %s/인터페이스/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\t인터페이스: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\t위치: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\t결함 시: 경고 안 함\n" + +msgid "\tUsers allowed:\n" +msgstr "\t사용자 허용됨:\n" + +msgid "\tUsers denied:\n" +msgstr "\t사용자 거부됨:\n" + +msgid "\tdaemon present\n" +msgstr "\t데몬 표시\n" + +msgid "\tno entries\n" +msgstr "\t엔트리 없음\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\t프린터가 '%s' 스피드 -1 장비에 있습니다\n" + +msgid "\tprinting is disabled\n" +msgstr "\t프린트가 비활성화되었습니다\n" + +msgid "\tprinting is enabled\n" +msgstr "\t프린트가 활성화되었습니다\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\t%s에 대한 대기열\n" + +msgid "\tqueuing is disabled\n" +msgstr "\t대기열이 비활성화되었습니다\n" + +msgid "\tqueuing is enabled\n" +msgstr "\t대기열이 활성화되었습니다\n" + +msgid "\treason unknown\n" +msgstr "\t알 수 없는 이유\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" 적합 테스트 상세 결과\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: 15페이지, 섹션 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: 15페이지, 섹션 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: 19페이지, 섹션 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: 20페이지, 섹션 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: 27페이지, 섹션 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: 42페이지, 섹션 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: 16-17페이지, 섹션 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: 42-45페이지, 섹션 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: 45-46페이지, 섹션 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: 48-49페이지, 섹션 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: 52-54페이지, 섹션 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f바이트\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\"이(가) \"%s %s\"와(과) 충돌합니다\n" +" (제한=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s에 일치하는 옵션이 없습니다!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s이(가) %s와(과) 일반적인 접두어를 공유합니다\n" +" REF: 15페이지, 섹션 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN 기본 선택사항 충돌!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN 양면 옵션 키워드 %s이(가) 예상대로 동작하지 않을 수 있으며 이" +"름을 양면으로 해야 합니다!\n" +" REF: 122페이지, 섹션 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr " WARN 파일이 CR, LF 및 CR LF 줄 끝을 포함합니다!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN PPD 4.3 사양은 LanguageEncoding이 필요합니다.\n" +" REF: 56-57페이지, 섹션 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN %d번째 줄에는 여백만 있습니다!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN PPD 4.3 사양은 Manufacturer이 필요합니다.\n" +" REF: 58-59페이지, 섹션 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN 비 Windows PPD 파일은 줄 끝을 CR LF가 아닌 LF만 있는 줄 끝을 " +"사용해야 합니다!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN 이전 PPD 버전 %.1f!\n" +" REF: 42페이지, 섹션 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PPD 사양에 위반되는 8.3 이상의 PCFileName.\n" +" REF: 61-62페이지, 섹션 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN 프로토콜은 PJL을 포함하지만 JCL 속성은 설정되지 않았습니다.\n" +" REF: 78-79페이지, 섹션 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN 프로토콜은 PJL 및 BCP를 모두 포함합니다; TBCP 예상됨.\n" +" REF: 78-79페이지, 섹션 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN PPD 4.3 사양은 ShortNickName이 필요합니다.\n" +" REF: 64-65페이지, 섹션 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s이(가) 존재하지 않습니다!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s 잘못된 %s - 선택사항 %s!\n" +" REF: 122페이지, 섹션 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %1$s %3$s 옵션에 대한 잘못된 UTF-8 \"%2$s\" 번역 스트링!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %1$s %3$s 옵션, %4$s 선택사항에 대한 잘못된 UTF-8 \"%2$s\" 번역 스트" +"링!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s 잘못된 \"%s\" cupsFilter 값!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s 잘못된 %s cupsICCProfile!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s 잘못된 \"%s\" cupsPreFilter 값!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 잘못된 cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s 잘못된 \"%s\" 언어!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints %s이(가) 비어있음!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %1$s %3$s 옵션에 대한 \"%2$s\" 번역 스트링 유실됨!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %1$s %3$s 옵션, %4$s 선택사항에 대한 \"%2$s\" 번역 스트링 유실됨!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %1$s \"*%4$s %5$s *%6$s %7$s\" UIConstraints에 있는 *%2$s %3$s 선택사" +"항 유실됨!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" +" %1$s %4$s cupsUIConstraints에 있는 *%2$s %3$s 선택사항 유실됨: \"%5$s" +"\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s \"%s\" cupsFilter 파일이 유실됨\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s \"%s\" cupsICCProfile 파일이 유실됨!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s \"%s\" cupsPreFilter 파일 유실됨\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s %s cupsUIResolver 유실됨!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %1$s \"*%3$s %4$s *%5$s %6$s\" UIConstraints에 있는 %2$s 옵션 유실" +"됨!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" +" %1$s %3$s cupsUIConstraints에 있는 %2$s 옵션 유실됨: \"%4$s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s 파일에 \"%s\" 기초 번역이 포함되어 있지 않습니다!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s 선택사항 없음을 정의하지 않은 %s이(가) 필요!\n" +" REF: 122페이지, 섹션 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s 불필요한 %s cupsICCProfile 값이 %s와(과) 충돌함!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s %s cupsUIResolver가 루프를 유발함!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr " **FAIL** %s 선택사항 이름 %s 및 %s이(가) 경우별로만 다름!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s은(는) 1284DeviceID이어야 합니다!\n" +" REF: 72페이지, 섹션 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** 잘못된 Default%s %s\n" +" REF: 40페이지, 섹션 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** 잘못된 DefaultImageableArea %s!\n" +" REF: 102페이지, 섹션 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** 잘못된 DefaultPaperDimension %s!\n" +" REF: 103페이지, 섹션 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** 파일에 있는 잘못된 JobPatchFile 속성\n" +" REF: 24페이지, 섹션 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** 잘못된 Manufacturer(\"HP\"이어야 함)\n" +" REF: 211페이지, 표 D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** 잘못된 Manufacturer(\"Oki\"이어야 함)\n" +" REF: 211페이지, 표 D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** 잘못된 ModelName - \"%c\"은(는) 스트링에서 허용되지 않습니" +"다.\n" +" REF: 59-60페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** 잘못된 PSVersion - \"(string) int\"이(가) 아닙니다.\n" +" REF: 62-64페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** 잘못된 Product - \"(string)\"이(가) 아닙니다.\n" +" REF: 62페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** 잘못된 ShortNickName - 31자보다 깁니다.\n" +" REF: 64-65페이지, 섹션 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** 잘못된 %s - 선택사항 %s!\n" +" REF: 84페이지, 섹션 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** 잘못된 FileVersion \"%s\"\n" +" REF: 56페이지, 섹션 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** 잘못된 FormatVersion \"%s\"\n" +" REF: 56페이지, 섹션 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** 잘못된 LanguageEncoding %s - ISOLatin1이어야 합니다!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** 잘못된 LanguageVersion %s - 영어여야 합니다!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **FAIL** 기본 옵션 코드를 해석할 수 없습니다: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** %s 옵션 %s 선택사항에 대한 기본 번역 스트링이 8비트 문자를 포" +"함합니다!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** %s 옵션에 대한 기본 번역 스트링이 8비트 문자를 포함합니다!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr " **FAIL** %s 및 %s 그룹 이름이 경우별로만 다름!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** 다중 %s 항목이 %s 이름을 선택!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr " **FAIL** %s 및 %s 옵션 이름이 경우별로만 다름!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** Default%s 필요\n" +" REF: 40페이지, 섹션 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DefaultImageableArea 필요\n" +" REF: 102페이지, 섹션 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DefaultPaperDimension 필요\n" +" REF: 103페이지, 섹션 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FileVersion 필요\n" +" REF: 56페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FormatVersion 필요\n" +" REF: 56페이지, 섹션 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** %s PageSize에 대한 ImageableArea 필요\n" +" REF: 41페이지, 섹션 5.\n" +" REF: 102페이지, 섹션 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** LanguageEncoding 필요\n" +" REF: 56-57페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** LanguageVersion 필요\n" +" REF: 57-58페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** Manufacturer 필요\n" +" REF: 58-59페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ModelName 필요\n" +" REF: 59-60페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** NickName 필요\n" +" REF: 60페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** PCFileName 필요\n" +" REF: 61-62페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** PSVersion 필요\n" +" REF: 62-64페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** PageRegion 필요\n" +" REF: 100페이지, 섹션 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** PageSize 필요\n" +" REF: 41페이지, 섹션 5.\n" +" REF: 99페이지, 섹션 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** PageSize 필요\n" +" REF: 99-100페이지, 섹션 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** %s PageSize에 대한 PaperDimension 필요\n" +" REF: 41페이지, 섹션 5.\n" +" REF: 103페이지, 섹션 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** Product 필요\n" +" REF: 62페이지, 섹션 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ShortNickName 필요\n" +" REF: 64-65페이지, 섹션 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d개의 오류 발견\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" 잘못된 %%%%BoundingBox: %d번째 줄!\n" +" REF: 39페이지, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" 잘못된 %%%%Page: %d번째 줄!\n" +" REF: 53페이지, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" 잘못된 %%%%Pages: %d번째 줄!\n" +" REF: 43페이지, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" %d번째 줄이 255자보다 깁니다(%d)!\n" +" REF: 25페이지, 줄 길이\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" 첫번째 줄에 있는 %!PS-Adobe-3.0이 유실됨!\n" +" REF: 17페이지, 3.1 도큐멘트 구성하기\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" %%EndComments 설명 유실됨!\n" +" REF: 41페이지, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" 유실되었거나 잘못된 %%BoundingBox: 설명!\n" +" REF: 39페이지, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" 유실되었거나 잘못된 %%Page: 설명!\n" +" REF: 53페이지, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" 유실되었거나 잘못된 %%Page: 설명!\n" +" REF: 43페이지, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " 발견된 오류 없음\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " 255자를 초과하는 %d개의 줄 발견!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " 너무 많은 %%BeginDocument 설명!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " 너무 많은 %%EndDocument 설명!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " 경고: 파일에 바이너리 데이터가 포함되어 있습니다!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " 경고: 파일에 %%EndComments 설명이 없습니다!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " 경고: 파일에 이전 DSC 버전 %.1f가 있습니다!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** PPD 파일을 열 수 없음 - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** PPD 파일을 열 수 없음 - %s, %d번째 줄.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10 봉투" + +msgid "#11 Envelope" +msgstr "#11 봉투" + +msgid "#12 Envelope" +msgstr "#12 봉투" + +msgid "#14 Envelope" +msgstr "#14 봉투" + +msgid "#9 Envelope" +msgstr "#9 봉투" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f바이트\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f바이트\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0fmm" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f~%.0f x %.0fmm" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f인치" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f~%.2f x %.2f인치" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr " %2$s 이후에 %1$s 승인 요청\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s을(를) 변경할 수 없습니다." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "CUPS 버전의 lpc로는 %s이(가) 실행되지 않습니다.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s이(가) 준비되지 않음\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s이(가) 준비됨\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s이(가) 준비되었고 프린트 중\n" + +#, fuzzy, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%2$s 이후에 %1$s 승인 요청 안 함 -\n" +"\t%1$s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s이(가) 지원되지 않음!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%3$s 이후에 %1$s/%2$s 승인 요청\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%3$s 이후에 %1$s/%2$s 승인 요청 안 함 -\n" +"\t%4$s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [작업 %d 로컬호스트]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s 실패: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: 해야할 일을 모르겠음!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%1$s: 오류 - \"%3$s\" 대상에 존재하지 않는 %2$s 환경 변수 이름!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: 오류 - 잘못된 작업 ID!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s: 오류 - 파일을 프린트할 수 없고 작업을 동시에 대체할 수 없음!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: 오류 - 파일 또는 작업 ID가 제공되었다면 stdin에서 프린트할 수 없음!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: 오류 - '-S' 옵션 뒤에 문자 세트가 예상됨!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: 오류 - '-T' 옵션 뒤에 콘텐츠 유형이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: 오류 - '-n' 옵션 뒤에 복사 매수가 예상됨!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: 오류 - '-#' 옵션 뒤에 복사본 수가 예상됨!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: 오류 - '-P' 옵션 뒤에 대상이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: 오류 - '-b' 옵션 뒤에 대상이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: 오류 - '-d' 옵션 뒤에 대상이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: 오류 - '-f' 옵션 뒤에 구성이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: 오류 - '-H' 옵션 뒤에 유지 이름이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: 오류 - '-H' 옵션 뒤에 호스트 이름이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: 오류 - '-h' 옵션 뒤에 호스트 이름이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: 오류 - '-y' 옵션 뒤에 모드 목록이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: 오류 - '-%c' 옵션 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: 오류 - '-o' 옵션 뒤에 옵션 스트링이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: 오류 - '-P' 옵션 뒤에 페이지 목록이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: 오류 - '-%c' 옵션 뒤에 우선순위가 예상됨!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: 오류 - '-r' 옵션 뒤에 이유 텍스트가 예상됨!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: 오류 - '-t' 옵션 뒤에 제목이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: 오류 - '-U' 옵션 뒤에 사용자 이름이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: 오류 - '-u' 옵션 뒤에 사용자 이름이 예상됨!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: 오류 - '-%c' 옵션 뒤에 값이 예상됨!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: 오류 - '-W' 옵션 뒤에 \"completed\", \"not-completed\" 또는 \"all\"이 필" +"요!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: 오류 - 사용 가능한 기본 대상이 없습니다.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: 오류 - 우선순위는 1에서 100사이여야 합니다.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: 오류 - 일정이 응답하지 않음!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: 오류 - 너무 많은 파일 - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: 오류 - \"%s\"에 연결할 수 없음 - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: 오류 - stdin에서 대기할 수 없음 - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: 오류 - 알 수 없는 대상 \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: 오류 - 알 수 없는 대상 \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: 오류 - 알 수 없는 옵션 '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: 오류 - 알 수 없는 옵션 '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: '-i' 옵션 뒤에 작업 ID가 예상됨!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: \"%s\" 필터를 사용할 수 없음: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: \"%s\" 목록에 유효하지 않은 대상 이름!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: 유효하지 않은 필터 문자열 \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: '-H restart' 앞에 작업 ID('-i jobid') 필요!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: %s/%s에서 %s/%s까지 변환할 필터가 없음!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: 작동 실패: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: 죄송합니다, 컴파일된 암호화 지원이 없습니다!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: 서버에 연결할 수 없음\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: 서버에 연결할 수 없음!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: MIME 유형의 \"%s\"을(를) 결정할 수 없음!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: %s을(를) 열 수 없음: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: PPD 파일을 열 수 없음: %s, %d번째 줄\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: \"%s\" 또는 \"%s\"에서 MIME 데이터베이스를 읽을 수 없음!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: 알 수 없는 대상 \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: 알 수 없는 대상 MIME 유형 %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: 알 수 없는 옵션 '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: 알 수 없는 소스 MIME 유형 %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: 경고 - '%c' 포맷 조합 키가 지원되지 않음 - 출력이 올바르지 않을 수 있습니" +"다!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: 경고 - 문자 세트 옵션이 무시됨!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: 경고 - 콘텐츠 유형 옵션이 무시됨!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: 경고 - 구성 옵션이 무시됨!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: 경고 - 모드 옵션이 무시됨!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%1$s: 오류 - \"%3$s\" 대상에 존재하지 않는 %2$s 환경 변수 이름!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: 오류 - '-o' 옵션 뒤에 option=value가 예상됨!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: 오류 - 사용 가능한 기본 대상이 없습니다.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1인치/초" + +msgid "1.25x0.25\"" +msgstr "1.25x0.25\"" + +msgid "1.25x2.25\"" +msgstr "1.25x2.25\"" + +msgid "1.5 inch/sec." +msgstr "1.5인치/초" + +msgid "1.50x0.25\"" +msgstr "1.50x0.25\"" + +msgid "1.50x0.50\"" +msgstr "1.50x0.50\"" + +msgid "1.50x1.00\"" +msgstr "1.50x1.00\"" + +msgid "1.50x2.00\"" +msgstr "1.50x2.00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10인치/초" + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100mm/초" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11인치/초" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12인치/초" + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120mm/초" + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15mm/초" + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150mm/초" + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2인치/초" + +msgid "2-Sided Printing" +msgstr "양면 프린트 중" + +msgid "2.00x0.37\"" +msgstr "2.00x0.37\"" + +msgid "2.00x0.50\"" +msgstr "2.00x0.50\"" + +msgid "2.00x1.00\"" +msgstr "2.00x1.00\"" + +msgid "2.00x1.25\"" +msgstr "2.00x1.25\"" + +msgid "2.00x2.00\"" +msgstr "2.00x2.00\"" + +msgid "2.00x3.00\"" +msgstr "2.00x3.00\"" + +msgid "2.00x4.00\"" +msgstr "2.00x4.00\"" + +msgid "2.00x5.50\"" +msgstr "2.00x5.50\"" + +msgid "2.25x0.50\"" +msgstr "2.25x0.50\"" + +msgid "2.25x1.25\"" +msgstr "2.25x1.25\"" + +msgid "2.25x4.00\"" +msgstr "2.25x4.00\"" + +msgid "2.25x5.50\"" +msgstr "2.25x5.50\"" + +msgid "2.38x5.50\"" +msgstr "2.38x5.50\"" + +msgid "2.5 inches/sec." +msgstr "2.5인치/초" + +msgid "2.50x1.00\"" +msgstr "2.50x1.00\"" + +msgid "2.50x2.00\"" +msgstr "2.50x2.00\"" + +msgid "2.75x1.25\"" +msgstr "2.75x1.25\"" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20mm/초" + +msgid "200 mm/sec." +msgstr "200mm/초" + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24핀 시리즈" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250mm/초" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3인치/초" + +msgid "3.00x1.00\"" +msgstr "3.00x1.00\"" + +msgid "3.00x1.25\"" +msgstr "3.00x1.25\"" + +msgid "3.00x2.00\"" +msgstr "3.00x2.00\"" + +msgid "3.00x3.00\"" +msgstr "3.00x3.00\"" + +msgid "3.00x5.00\"" +msgstr "3.00x5.00\"" + +msgid "3.25x2.00\"" +msgstr "3.25x2.00\"" + +msgid "3.25x5.00\"" +msgstr "3.25x5.00\"" + +msgid "3.25x5.50\"" +msgstr "3.25x5.50\"" + +msgid "3.25x5.83\"" +msgstr "3.25x5.83\"" + +msgid "3.25x7.83\"" +msgstr "3.25x7.83\"" + +msgid "3.5\" Disk" +msgstr "3.5\" 디스크" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3.5\" 디스크 - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3.50x1.00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30mm/초" + +msgid "300 mm/sec." +msgstr "300mm/초" + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4인치/초" + +msgid "4.00x1.00\"" +msgstr "4.00x1.00\"" + +msgid "4.00x13.00\"" +msgstr "4.00x13.00\"" + +msgid "4.00x2.00\"" +msgstr "4.00x2.00\"" + +msgid "4.00x2.50\"" +msgstr "4.00x2.50\"" + +msgid "4.00x3.00\"" +msgstr "4.00x3.00\"" + +msgid "4.00x4.00\"" +msgstr "4.00x4.00\"" + +msgid "4.00x5.00\"" +msgstr "4.00x5.00\"" + +msgid "4.00x6.00\"" +msgstr "4.00x6.00\"" + +msgid "4.00x6.50\"" +msgstr "4.00x6.50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40mm/초" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5인치/초" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6인치/초" + +msgid "6.00x1.00\"" +msgstr "6.00x1.00\"" + +msgid "6.00x2.00\"" +msgstr "6.00x2.00\"" + +msgid "6.00x3.00\"" +msgstr "6.00x3.00\"" + +msgid "6.00x4.00\"" +msgstr "6.00x4.00\"" + +msgid "6.00x5.00\"" +msgstr "6.00x5.00\"" + +msgid "6.00x6.00\"" +msgstr "6.00x6.00\"" + +msgid "6.00x6.50\"" +msgstr "6.00x6.50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60mm/초" + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7인치/초" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8인치/초" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8.00x1.00\"" + +msgid "8.00x2.00\"" +msgstr "8.00x2.00\"" + +msgid "8.00x3.00\"" +msgstr "8.00x3.00\"" + +msgid "8.00x4.00\"" +msgstr "8.00x4.00\"" + +msgid "8.00x5.00\"" +msgstr "8.00x5.00\"" + +msgid "8.00x6.00\"" +msgstr "8.00x6.00\"" + +msgid "8.00x6.50\"" +msgstr "8.00x6.50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80mm/초" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9인치/초" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9핀 시리즈" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?유효하지 않은 도움말 명령을 알 수 없음\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "프린터 드라이버를 보내려면 Samba 암호가 필요함!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "프린터 드라이버를 보내려면 Samba 사용자 이름이 필요함!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "\"%s\"(이)라는 이름의 클래스가 이미 존재합니다!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "\"%s\"(이)라는 이름의 프린터가 이미 존재합니다!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3(대)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4(대)" + +msgid "A4 (Small)" +msgstr "A4(소)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5(대)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "작업 허용" + +msgid "Accepted" +msgstr "허용됨" + +msgid "Add Class" +msgstr "클래스 추가" + +msgid "Add Printer" +msgstr "프린터 추가" + +msgid "Add RSS Subscription" +msgstr "RSS 구독 추가" + +msgid "Address" +msgstr "주소" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "주소 - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "관리" + +msgid "Always" +msgstr "항상" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "적용자" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "%s 프린터 상태를 잘못된 %d 값으로 설정하려고 합니다!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "속성 그룹이 올바르지 않습니다(%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "잘못된 NULL dests 포인터" + +msgid "Bad OpenGroup" +msgstr "잘못된 OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "잘못된 OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "잘못된 OrderDependency" + +msgid "Bad Request" +msgstr "잘못된 요청" + +msgid "Bad SNMP version number" +msgstr "잘못된 SNMP 버전 번호" + +msgid "Bad UIConstraints" +msgstr "잘못된 UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "잘못된 복사 매수 값 %d." + +msgid "Bad custom parameter" +msgstr "잘못된 사용자 설정 매개변수" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "잘못된 장비 URI \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "잘못된 device-uri \"%s\"!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "잘못된 device-uri 설계 \"%s\"!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "잘못된 document-format \"%s\"!" + +msgid "Bad filename buffer!" +msgstr "잘못된 파일 이름 버퍼!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "잘못된 서체 속성: %s\n" + +msgid "Bad job-priority value!" +msgstr "잘못된 job-priority 값!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "잘못된 job-sheets 값\"%s\"!" + +msgid "Bad job-sheets value type!" +msgstr "잘못된 job-sheets 값 유형!" + +msgid "Bad job-state value!" +msgstr "잘못된 job-state 값!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "잘못된 job-uri 속성 \"%s\"!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "잘못된 notify-pull-method \"%s\"!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "잘못된 notify-recipient-uri URI \"%s\"!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "잘못된 number-up 값 %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "%d번째 줄에 있는 잘못된 옵션 + 선택사항!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "잘못된 page-ranges 값 %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "잘못된 port-monitor \"%s\"!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "잘못된 printer-state 값 %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "잘못된 요청 버전 숫자 %d.%d!" + +msgid "Bad subscription ID!" +msgstr "잘못된 구독 ID!" + +msgid "Banners" +msgstr "배너" + +msgid "Billing Information: " +msgstr "지불 정보: " + +msgid "Bond Paper" +msgstr "고급 종이" + +msgid "C0 Envelope" +msgstr "C0 봉투" + +msgid "C1 Envelope" +msgstr "C1 봉투" + +msgid "C2 Envelope" +msgstr "C2 봉투" + +msgid "C3 Envelope" +msgstr "C3 봉투" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4 봉투" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5 봉투" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6 봉투" + +msgid "C65 Envelope" +msgstr "C65 봉투" + +msgid "C7 Envelope" +msgstr "C7 봉투" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL 레이블 프린터" + +msgid "Cancel RSS Subscription" +msgstr "RSS 구독 취소" + +msgid "Change Settings" +msgstr "설정값 변경" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "\"%s\" 문자 세트가 지원되지 않음!" + +msgid "Chou3 Envelope" +msgstr "Chou3 봉투" + +msgid "Chou4 Envelope" +msgstr "Chou4 봉투" + +msgid "Classes" +msgstr "클래스" + +msgid "Clean Print Heads" +msgstr "프린트 머리말 지우기" + +msgid "Color" +msgstr "색상" + +msgid "Color Mode" +msgstr "색상 모드" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"명령이 생략될 수 있습니다. 명령은 다음과 같습니다:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "커뮤니티 이름 길이가 무제한입니다" + +msgid "Continue" +msgstr "계속" + +msgid "Continuous" +msgstr "계속" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "\"%s\" 유형을 검색할 수 없음!" + +msgid "Cover open." +msgstr "덮개가 열려 있음." + +msgid "Created" +msgstr "생성됨" + +msgid "Created On: " +msgstr "다음에 생성됨: " + +msgid "Custom" +msgstr "사용자화" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "오려두기" + +msgid "Cutter" +msgstr "자르기 도구" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL 봉투" + +msgid "Dark" +msgstr "어둡게" + +msgid "Darkness" +msgstr "어둠" + +msgid "Delete Class" +msgstr "클래스 삭제" + +msgid "Delete Printer" +msgstr "프린터 삭제" + +msgid "Description: " +msgstr "설명: " + +msgid "DeskJet Series" +msgstr "DeskJet 시리즈" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "\"%s\" 대상이 작업을 허용하지 않습니다." + +msgid "Developer almost empty." +msgstr "현상액이 거의 비었습니다." + +msgid "Developer empty!" +msgstr "현상액이 비어 있음!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"장비: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "직접 열 미디어" + +msgid "Disabled" +msgstr "비활성화됨" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "도큐멘트 %d을 작업 %d에서 찾을 수 없습니다." + +msgid "Door open." +msgstr "문이 열려 있음." + +msgid "Double Postcard" +msgstr "이중 엽서" + +msgid "Driver Name: " +msgstr "드라이버 이름: " + +msgid "Driver Version: " +msgstr "드라이버 버전: " + +msgid "Duplexer" +msgstr "양면 프린터" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: 페이지 정보에 메모리를 할당할 수 없습니다: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: 페이지 배열에 메모리를 할당할 수 없습니다: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1 레이블 프린터" + +msgid "EPL2 Label Printer" +msgstr "EPL2 레이블 프린터" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: 잘못된 %%BoundingBox: 설명이 보임!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: 잘못된 %%IncludeFeature: 설명!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: 잘못된 %%Page: 파일에 있는 설명!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: 잘못된 %%PageBoundingBox: 파일에 있는 설명!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: 잘못된 SCSI 장비 파일 \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: 잘못된 문자 세트 파일 %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: 잘못된 문자 세트 유형 %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: 잘못된 열 값 %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: 잘못된 cpi 값 %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: 잘못된 서체 설명 줄: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: 잘못된 lpi 값 %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: 잘못된 페이지 설정!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: 잘못된 텍스트 방향 %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: 잘못된 텍스트 길이 %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: 대상 프린터가 없습니다!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox 복제: 설명이 보임!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: %%Pages 복제: 설명이 보임!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: 빈 프린트 파일!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: %d 오류가 다음 PAPSendData 요청을 보내는 중: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: %2$s의 %1$d번째 줄에 인용 스트링이 예상됨!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: 심각한 USB 오류!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: 파일을 프린트할 수 없는, 유효하지 않은 HP-GL/2 명령이 보임!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog가 유실됨!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup이 유실됨!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: 배너 파일의 %d번째 줄 값이 유실됨!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: %2$s의 %1$d번째 줄에 있는 모든 번역 스트링 앞에 msgid 줄 필요!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: %%BoundingBox가 없음: 머리말에 설명!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: %%Pages가 없음: 머리말에 설명!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "ERROR: argv[0] 또는 DEVICE_URI 환경 변수에서 발견된 장비 URI가 없음!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: %s 문자 세트 파일에 서체 없음\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: 페이지 없음!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: 종이 없음!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER 환경 변수가 정의되지 않음!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: 프린트 파일이 허용되지 않음(%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: 프린터가 응답하지 않음\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: 프린터가 응답하지 않음!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: 프린터가 예기치 않은 EOF를 보냄\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: 원격 호스트가 제어 파일을 허용하지 않음(%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: 원격 호스트가 데이터 파일을 허용하지 않음(%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: 데이터를 프린터로 전송하는 동안 시간초과 오류가 발생했습니다\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: 작업에 %d 파일을 추가할 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: %d 작업을 취소할 수 없음: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: PDF 파일을 복사할 수 없음" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: 소켓을 생성할 수 없음" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: 임시 압축 프린트 파일을 생성할 수 없음: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: 임시 파일을 생성할 수 없음" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: pictwpstops를 실행할 수 없음: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: gs 프로그램을 실행할 수 없음" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: pdftops 프로그램을 실행할 수 없음" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: pictwpstops를 분리(fork)할 수 없음: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: PAP 요청을 얻을 수 없음" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: PAP 응답을 얻을 수 없음" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: \"%s\"프린터에 대한 PPD 파일을 얻을 수 없음 - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: 기본 AppleTalk 영역을 얻을 수 없음" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: 작업 %d 속성을 얻을 수 없음(%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: 프린터 상태를 알 수 없음(%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: '%s' 프린터를 찾을 수 없음!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: PAP 응답을 찾을 수 없음" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: AppleTalk 프린터를 찾을 수 없음" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: AppleTalk 주소를 생성할 수 없음" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: \"%s\"을(를) 열 수 없음 - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: %s을(를) 열 수 없음: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: \"%s\" 배너 파일을 열 수 없음 - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: \"%s\" 장비 파일을 열 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: \"%s\" 파일을 열 수 없음 - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: \"%s\" 파일을 열 수 없음: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: 이미지 파일을 열어서 프린트할 수 없음!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: \"%s\" 프린트 파일을 열 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: %s 프린트 파일을 열 수 없음 - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: %s 프린트 파일을 열 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: 임시로 압축한 프린트 파일을 열 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: %d개의 텍스트 열을 프린트할 수 없음!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: %dx%d 텍스트 페이지를 프린트할 수 없음!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: 프린트 데이터를 읽을 수 없음" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: 프린트 데이터를 읽을 수 없음!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: 포트를 예약할 수 없음" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: 파일에서 %ld 오프셋을 찾을 수 없음 - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: 파일에서 %lld 오프셋을 찾을 수 없음 - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: LPD 명령을 보낼 수 없음" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: PAP tickle 요청을 보낼 수 없음" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: 초기 PAP 전송 데이터 요청을 보낼 수 없음" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: 프린트 데이터를 보낼 수 없음(%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: 프린트 데이터를 보낼 수 없음!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: 프린트 파일을 프린터로 보낼 수 없음" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: 끝자리 nul을 프린터로 보낼 수 없음" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: pictwpstops를 기다릴 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: \"%2$s\"에 %1$d바이트를 쓸 수 없음: %3$s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: 프린터에 %d바이트를 쓸 수 없음!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: 제어 파일을 쓸 수 없음" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: 프린트 데이터를 쓸 수 없음" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: 프린트 데이터를 쓸 수 없음: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: 드라이버에 래스터 데이터를 쓸 수 없음!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: 임시 파일을 쓸 수 없음" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: 압축되지 않은 도큐멘트 데이터를 쓸 수 없음: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: %2$s의 %1$d번째 줄에 예기치 않은 텍스트!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: 알 수 없는 암호화 옵션 값 \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: 알 수 없는 파일 순서 \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: 알 수 없는 포맷 문자 \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: \"%s\"에 대한 알 수 없는 메시지 카탈로그 포맷!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: \"%2$s\" 값이 있는 알 수 없는 \"%1$s\" 옵션!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: 알 수 없는 \"%s\" 프린트 모드\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: 알 수 없는 \"%s\" 버전 옵션 값!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: brightness=100을 사용하는, 지원되지 않는 밝기 값 %s!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: gamma=1000을 사용하는, 지원되지 않는 감마 값 %s!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: number-up=1을 사용하는, 지원되지 않는 number-up 값 %d!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: number-up-layout=lrtb을 사용하는, 지원되지 않는 number-up-layout 값 %" +"s!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: page-border=none을 사용하는, 지원되지 않는 page-border 값 %s!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: doc_printf 오버플로우(%d바이트)가 발견됨, 중단 중!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops가 신호 %d에서 종료됨!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops가 상태 %d(으)로 종료됨!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "ERROR: 복원 가능: 프린터에 연결할 수 없음; 30초 후에 다시 시도...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() 실패" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: 프린트 파일을 시작할 수 없음" + +msgid "Edit Configuration File" +msgstr "구성 파일 편집" + +msgid "Empty PPD file!" +msgstr "PPD 파일이 비어있음!" + +msgid "Ending Banner" +msgstr "배너 종료 중" + +msgid "Enter old password:" +msgstr "이전 암호 입력:" + +msgid "Enter password again:" +msgstr "암호 다시 입력:" + +msgid "Enter password:" +msgstr "암호 입력:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"이 페이지에 연결하려면 사용자 이름 및 암호 또는 root 사용자 이름 및 암호를 입" +"력하십시오. Kerberos 인증을 사용하고 있다면, 유효한 Kerberos 티켓을 가지고 있" +"는지 확인하십시오." + +msgid "Envelope Feed" +msgstr "봉투 공급" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "오류 정책" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "오류: '-h' 옵션 뒤에 호스트 이름이 필요!\n" + +msgid "Every 10 Labels" +msgstr "10개 레이블마다" + +msgid "Every 2 Labels" +msgstr "2개 레이블마다" + +msgid "Every 3 Labels" +msgstr "3개 레이블마다" + +msgid "Every 4 Labels" +msgstr "4개 레이블마다" + +msgid "Every 5 Labels" +msgstr "5개 레이블마다" + +msgid "Every 6 Labels" +msgstr "6개 레이블마다" + +msgid "Every 7 Labels" +msgstr "7개 레이블마다" + +msgid "Every 8 Labels" +msgstr "8개 레이블마다" + +msgid "Every 9 Labels" +msgstr "9개 레이블마다" + +msgid "Every Label" +msgstr "모든 레이블" + +msgid "Expectation Failed" +msgstr "예상 실패" + +msgid "Export Printers to Samba" +msgstr "Samba로 프린터 보내기" + +msgid "FAIL\n" +msgstr "실패\n" + +msgid "File Folder" +msgstr "파일 폴더" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "파일 폴더 - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"파일 장비 URI가 비활성화되었습니다! 활성화하려면, \"%s/cupsd.conf\"에 있는 " +"FileDevice 지시문을 보십시오." + +msgid "Folio" +msgstr "2절지" + +msgid "Forbidden" +msgstr "금지됨" + +msgid "Fuser temperature high!" +msgstr "퓨저 온도가 높음!" + +msgid "Fuser temperature low!" +msgstr "퓨저 온도가 낮음!" + +msgid "General" +msgstr "일반" + +msgid "Generic" +msgstr "일반" + +msgid "German FanFold" +msgstr "독일 FanFold" + +msgid "German FanFold Legal" +msgstr "독일 FanFold 공문서" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU 길이가 무제한입니다" + +msgid "Glossy Paper" +msgstr "글로시 종이" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "printer-uri 속성을 얻었지만, job-id가 없습니다!" + +msgid "Grayscale" +msgstr "그레이 스케일" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "행잉 폴더" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "행잉 폴더 - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: 시스템 환경설정에서 AppleTalk가 비활성화됨\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: 시스템 환경설정에서 AppleTalk가 비활성화되었습니다.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: 프린트 작업 취소 중...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: 프린터에 연결됨...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: 프린트에 연결 중...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: 제어 파일을 성공적으로 보냄\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: 데이터 파일을 성공적으로 보냄\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: %d페이지 포맷 중...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: 이미지 파일 로드 중...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: 프린터 검색 중...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: 연결 열기\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: 프린트 파일을 보냈고, 프린터 작업 종료 대기 중...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: 프린터 사용 중; 10초 후에 다시 시도...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: 프린터 사용 중; 30초 후에 다시 시도...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: 프린터 사용 중; 5초 후에 다시 시도...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: 프린터가 IPP/%d.%d을 지원하지 않기 때문에, IPP/1.0을 시도 중...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: 프린터 사용 중; 5초 후에 다시 시도...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: 현재 프린터가 오프라인입니다.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: 현재 프린터가 오프라인입니다.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: 현재 프린터가 온라인입니다.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: 프린터가 오프라인입니다.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: 프린터가 연결되지 않음; 30초 후에 다시 시도...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: %d페이지 프린트 중, %d%% 완료...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: %d페이지 프린트 중...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: 프린트할 준비가 되었습니다.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: 제어 파일 보내는 중(%lu바이트)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: 제어 파일 보내는 중(%u바이트)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: 데이터 보내는 중\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: 데이터 파일 보내는 중(%ld바이트)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: 데이터 파일 보내는 중(%lld바이트)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: 프린트 데이터 보내는 중...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: 프린트 파일 보냄, %ld바이트...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: 프린트 파일 보냄, %lld바이트...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: LPR 작업 스풀 중, %.0f%% 완료...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: 프린터에 연결할 수 없기 때문에, 클래스에 있는 다음 프린터 대기 중...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: \"%s\" 기본 AppleTalk 영역 사용 중 \n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: 작업 완료 대기 중...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: 프린터 사용 대기 중...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 봉투" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5(대)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 봉투" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 봉투" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "올바르지 않은 제어 문자" + +msgid "Illegal main keyword string" +msgstr "올바르지 않은 주 키워드 스트링" + +msgid "Illegal option keyword string" +msgstr "올바르지 않은 옵션 키워드 스트링" + +msgid "Illegal translation string" +msgstr "올바르지 않은 번역 스트링" + +msgid "Illegal whitespace character" +msgstr "올바르지 않은 여백 문자" + +msgid "Ink/toner almost empty." +msgstr "잉크/토너가 거의 비었습니다." + +msgid "Ink/toner empty!" +msgstr "잉크/토너가 비었음!" + +msgid "Ink/toner waste bin almost full." +msgstr "잉크/토너 폐기소가 거의 찼습니다." + +msgid "Ink/toner waste bin full!" +msgstr "잉크/토너 폐기소가 찼음!" + +msgid "Installable Options" +msgstr "설치 가능한 옵션" + +msgid "Installed" +msgstr "설치됨" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar 레이블 프린터" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "연동 장치가 열려 있음." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "내부 오류" + +msgid "Internet Postage 2-Part" +msgstr "인터넷 우표 2부분" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "인터넷 우표 2부분 - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "인터넷 우표 3부분" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "인터넷 우표 3부분 - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "인터넷 프린트 프로토콜" + +msgid "Invite Envelope" +msgstr "초대 봉투" + +msgid "Italian Envelope" +msgstr "이탈리아 봉투" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "#%d 작업을 다시 시작할 수 없음 - 파일 없음!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "#%d 작업이 없음!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "#%d 작업이 이미 중단됨 - 취소할 수 없습니다." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "#%d 작업이 이미 취소됨 - 취소할 수 없습니다." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "#%d 작업이 이미 완료됨 - 취소할 수 없습니다." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "#%d 작업이 종료되었고 대체할 수 없음!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "#%d 작업이 왼료되지 않음!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "#%d 작업이 인증을 위해 유지되지 않음!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "#%d 작업이 유지되지 않음!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "#%s 작업이 존재하지 않음!" + +#, c-format +msgid "Job %d not found!" +msgstr "%d 작업이 발견되지 않음!" + +msgid "Job Completed" +msgstr "작업이 완료됨" + +msgid "Job Created" +msgstr "작업이 생성됨" + +msgid "Job ID: " +msgstr "작업 ID: " + +msgid "Job Options Changed" +msgstr "작업 옵션이 변경됨" + +msgid "Job Stopped" +msgstr "작업이 중단됨" + +msgid "Job UUID: " +msgstr "작업 UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "작업이 완료되었고 변경할 수 없습니다." + +msgid "Job operation failed:" +msgstr "작업 실행에 실패함:" + +msgid "Job state cannot be changed." +msgstr "작업 상태를 변경할 수 없습니다." + +msgid "Job subscriptions cannot be renewed!" +msgstr "작업 구독을 갱신할 수 없음!" + +msgid "Jobs" +msgstr "작업" + +msgid "Kaku2 Envelope" +msgstr "Kaku2 봉투" + +msgid "Kaku3 Envelope" +msgstr "Kaku3 봉투" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR 호스트 또는 프린터" + +msgid "Label Printer" +msgstr "레이블 프린터" + +msgid "Label Top" +msgstr "레이블 상단" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "\"%s\" 언어가 지원되지 않음!" + +msgid "Large Address" +msgstr "주소 크게" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "주소 크게 - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet 시리즈 PCL 4/5" + +msgid "Light" +msgstr "불빛" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "줄에 허용되는 최대 길이보다 김(255자)" + +msgid "List Available Printers" +msgstr "사용 가능한 프린터 목록" + +msgid "Location: " +msgstr "위치: " + +msgid "Long-Edge (Portrait)" +msgstr "가장자리 길게(세로)" + +msgid "Make and Model: " +msgstr "제조사 및 모델: " + +msgid "Manual Feed" +msgstr "수동 공급" + +msgid "Media Dimensions: " +msgstr "미디어 크기: " + +msgid "Media Limits: " +msgstr "미디어 제한: " + +msgid "Media Name: " +msgstr "미디어 이름: " + +msgid "Media Size" +msgstr "미디어 크기" + +msgid "Media Source" +msgstr "미디어 소스" + +msgid "Media Tracking" +msgstr "미디어 추적" + +msgid "Media Type" +msgstr "미디어 유형" + +msgid "Media jam!" +msgstr "미디어가 걸림!" + +msgid "Media tray almost empty." +msgstr "미디어 트레이가 거의 비었습니다." + +msgid "Media tray empty!" +msgstr "미디어 트레이가 비어 있음!" + +msgid "Media tray missing!" +msgstr "미디어 트레이가 유실됨!" + +msgid "Media tray needs to be filled." +msgstr "미디어 트레이를 채워야 합니다." + +msgid "Medium" +msgstr "중간" + +msgid "Memory allocation error" +msgstr "메모리 할당 오류" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "PPD-Adobe-4.x 머리말이 유실됨" + +msgid "Missing asterisk in column 1" +msgstr "1열에 있는 별표가 유실됨" + +msgid "Missing document-number attribute!" +msgstr "document-number 속성이 유실됨!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "%d번째 줄에 있는 큰 따옴표가 유실됨!" + +msgid "Missing form variable!" +msgstr "구성 변수가 유실됨!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "notify-subscription-ids 속성이 유실됨!" + +msgid "Missing requesting-user-name attribute!" +msgstr "requesting-user-name 속성이 유실됨!" + +msgid "Missing required attributes!" +msgstr "필요한 속성이 유실됨!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "%d번째 줄에 있는 값이 유실됨!" + +msgid "Missing value string" +msgstr "값 스트링이 유실됨" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"모델: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "클래스 수정" + +msgid "Modify Printer" +msgstr "프린터 수정" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch 봉투" + +msgid "Move All Jobs" +msgstr "모든 작업 이동" + +msgid "Move Job" +msgstr "작업 이동" + +msgid "Moved Permanently" +msgstr "영구적으로 이동" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: 프린트 파일이 허용됨 - 작업 ID %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: 프린트 파일이 허용됨 - 알 수 없는 작업 ID.\n" + +msgid "NULL PPD file pointer" +msgstr "NULL PPD 파일 포인터" + +msgid "Name OID uses indefinite length" +msgstr "이름 OID 길이가 무제한입니다" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "안 함" + +msgid "New Stylus Color Series" +msgstr "새로운 Stylus Color 시리즈" + +msgid "New Stylus Photo Series" +msgstr "새로운 Stylus Photo 시리즈" + +msgid "No" +msgstr "아니요" + +msgid "No Content" +msgstr "콘텐츠 없음" + +msgid "No PPD name!" +msgstr "PPD 이름 없음!" + +msgid "No VarBind SEQUENCE" +msgstr "VarBind SEQUENCE 없음" + +msgid "No Windows printer drivers are installed!" +msgstr "설치된 Windows 프린터 드라이버가 없음!" + +msgid "No active connection" +msgstr "활성 연결이 없음" + +#, c-format +msgid "No active jobs on %s!" +msgstr "%s에 활성 작업이 없음!" + +msgid "No attributes in request!" +msgstr "요청에 속성이 없음!" + +msgid "No authentication information provided!" +msgstr "제공된 인증 정보가 없음!" + +msgid "No community name" +msgstr "커뮤니티 이름 없음" + +msgid "No default printer" +msgstr "기본 프린터가 없음" + +msgid "No destinations added." +msgstr "추가된 대상이 없습니다." + +msgid "No error-index" +msgstr "error-index 없음" + +msgid "No error-status" +msgstr "error-status 없음" + +msgid "No file!?!" +msgstr "파일이 없음!?!" + +msgid "No modification time!" +msgstr "수정 시간 없음!" + +msgid "No name OID" +msgstr "이름 OID 없음" + +msgid "No printer name!" +msgstr "프린터 이름 없음!" + +msgid "No printer-uri found for class!" +msgstr "클래스에 대한 printer-uri 없음!" + +msgid "No printer-uri found!" +msgstr "printer-uri 없음!" + +msgid "No printer-uri in request!" +msgstr "요청에 printer-uri 없음!" + +msgid "No request-id" +msgstr "request-id 없음" + +msgid "No subscription attributes in request!" +msgstr "요청에 구독 속성이 없음!" + +msgid "No subscriptions found." +msgstr "발견된 구독이 없습니다." + +msgid "No variable-bindings SEQUENCE" +msgstr "variable-bindings SEQUENCE 없음" + +msgid "No version number" +msgstr "버전 번호 없음" + +msgid "Non-continuous (Mark sensing)" +msgstr "중단(마크 센싱)" + +msgid "Non-continuous (Web sensing)" +msgstr "중단(웹 센싱)" + +msgid "Normal" +msgstr "일반" + +msgid "Not Found" +msgstr "없음" + +msgid "Not Implemented" +msgstr "실행되지 않음" + +msgid "Not Installed" +msgstr "설치되지 않음" + +msgid "Not Modified" +msgstr "수정되지 않음" + +msgid "Not Supported" +msgstr "지원되지 않음" + +msgid "Not allowed to print." +msgstr "프린트가 허용되지 않습니다." + +msgid "Note" +msgstr "참고" + +msgid "OK" +msgstr "승인" + +msgid "OPC almost at end-of-life." +msgstr "OPC 수명이 거의 다 되었습니다." + +msgid "OPC at end-of-life!" +msgstr "OPC 수명이 다 되었음!" + +msgid "Off (1-Sided)" +msgstr "끔(한 쪽 방향)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "온라인 도움말" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "%s 열기 실패: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "우선 CloseGroup이 없는 OpenGroup" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "우선 CloseUI/JCLCloseUI가 없는 OpenUI/JCLOpenUI" + +msgid "Operation Policy" +msgstr "동작 정책" + +msgid "Options Installed" +msgstr "설치된 옵션" + +msgid "Options: " +msgstr "옵션: " + +msgid "Out of toner!" +msgstr "토너가 없음!" + +msgid "Output Mode" +msgstr "출력 모드" + +msgid "Output bin almost full." +msgstr "출력소 거의 찼습니다." + +msgid "Output bin full!" +msgstr "출력소가 찼습니다!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "%s 프린터 출력을 %s(으)로 보냄\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "%1$s 프린터 출력을 %3$s에 있는 %2$s 원격 프린터로 보냄\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "%s/%s 프린터 출력을 %s로 보냄\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "%1$s/%2$s 프린터 출력을 %4$s에 있는 %3$s 원격 프린터로 보냄\n" + +msgid "Output tray missing!" +msgstr "출력 트레이가 유실됨!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "PCL 레이저 프린터" + +msgid "PRC1 Envelope" +msgstr "PRC1 봉투" + +msgid "PRC10 Envelope" +msgstr "PRC10 봉투" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2 봉투" + +msgid "PRC3 Envelope" +msgstr "PRC3 봉투" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K(대)" + +msgid "PRC4 Envelope" +msgstr "PRC4 봉투" + +msgid "PRC5 Envelope" +msgstr "PRC5 봉투" + +msgid "PRC6 Envelope" +msgstr "PRC6 봉투" + +msgid "PRC7 Envelope" +msgstr "PRC7 봉투" + +msgid "PRC8 Envelope" +msgstr "PRC8 봉투" + +msgid "PRC9 Envelope" +msgstr "PRC9 봉투" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "패킷에 Get-Response-PDU가 없습니다" + +msgid "Packet does not start with SEQUENCE" +msgstr "패킷이 SEQUENCE로 시작하지 않습니다" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "%2$s의 %1$s 암호? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "SAMBA를 통해 %2$s에 연결하려면 필요한 %1$s의 암호: " + +msgid "Pause Class" +msgstr "클래스 일시정지" + +msgid "Pause Printer" +msgstr "프린터 일시정지" + +msgid "Peel-Off" +msgstr "착탈식" + +msgid "Personal Envelope" +msgstr "개인 봉투" + +msgid "Photo" +msgstr "사진" + +msgid "Photo Labels" +msgstr "사진 레이블" + +msgid "Plain Paper" +msgstr "일반 종이" + +msgid "Policies" +msgstr "정책" + +msgid "Port Monitor" +msgstr "포트 모니터" + +msgid "PostScript Printer" +msgstr "PostScript 프린터" + +msgid "Postcard" +msgstr "엽서" + +msgid "Print Density" +msgstr "프린트 해상도" + +msgid "Print Job:" +msgstr "프린트 작업:" + +msgid "Print Mode" +msgstr "프린트 모드" + +msgid "Print Rate" +msgstr "프린트 비율" + +msgid "Print Self-Test Page" +msgstr "프린트 자체 테스트 페이지" + +msgid "Print Speed" +msgstr "프린트 속도" + +msgid "Print Test Page" +msgstr "프린트 테스트 페이지" + +msgid "Print and Cut" +msgstr "프린트 및 자르기" + +msgid "Print and Tear" +msgstr "프린트 및 티어" + +msgid "Printed For: " +msgstr "다음이 프린트됨: " + +msgid "Printed From: " +msgstr "다음에서 프린트됨: " + +msgid "Printed On: " +msgstr "다음에서 프린트됨: " + +msgid "Printer Added" +msgstr "추가된 프린터" + +msgid "Printer Default" +msgstr "기본 프린터" + +msgid "Printer Deleted" +msgstr "삭제된 프린터" + +msgid "Printer Modified" +msgstr "수정된 프린터" + +msgid "Printer Name: " +msgstr "프린터 이름: " + +msgid "Printer Paused" +msgstr "중단된 프린터" + +msgid "Printer Settings" +msgstr "프린터 설정" + +msgid "Printer offline." +msgstr "프린터가 오프라인입니다." + +msgid "Printer:" +msgstr "프린터:" + +msgid "Printers" +msgstr "프린터" + +msgid "Purge Jobs" +msgstr "작업 비우기" + +msgid "Quarto" +msgstr "4절지" + +msgid "Quota limit reached." +msgstr "용량이 한계에 도달했습니다." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "단계 소유자 작업 파일 총 크기\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"단계 소유자 우선순위 작업 파일 총 크기\n" + +msgid "Reject Jobs" +msgstr "작업 거부" + +msgid "Reprint After Error" +msgstr "오류 시 다시 프린트" + +msgid "Request Entity Too Large" +msgstr "요청한 용량이 너무 큽니다" + +msgid "Resolution" +msgstr "해상도" + +msgid "Resume Class" +msgstr "클래스 다시 시작" + +msgid "Resume Printer" +msgstr "프린터 다시 시작" + +msgid "Return Address" +msgstr "주소 반환" + +msgid "Return Address - 3/4 x 2\"" +msgstr "주소 반환 - 3/4 x 2\"" + +msgid "Rewind" +msgstr "뒤로가기" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "실행 중인 명령: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI 프린터" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE 길이가 무제한입니다" + +msgid "See Other" +msgstr "기타 보기" + +#, c-format +msgid "Serial Port #%d" +msgstr "시리얼 포트 #%d" + +msgid "Server Restarted" +msgstr "서버 재시동됨" + +msgid "Server Security Auditing" +msgstr "서버 보안 감사" + +msgid "Server Started" +msgstr "서버 시동됨" + +msgid "Server Stopped" +msgstr "서버 중단됨" + +msgid "Service Unavailable" +msgstr "사용할 수 없는 서비스" + +msgid "Set Allowed Users" +msgstr "허용된 사용자 설정" + +msgid "Set As Server Default" +msgstr "서버 기본값으로 설정" + +msgid "Set Class Options" +msgstr "클래스 옵션 설정" + +msgid "Set Printer Options" +msgstr "프린터 옵션 설정" + +msgid "Set Publishing" +msgstr "발행 설정" + +msgid "Shipping Address" +msgstr "발송 주소" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "발송 주소 - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "가장자리 짧게(가로)" + +msgid "Special Paper" +msgstr "특수 종이" + +msgid "Standard" +msgstr "표준" + +msgid "Starting Banner" +msgstr "배너 시작 중" + +msgid "Statement" +msgstr "대차표" + +msgid "Stylus Color Series" +msgstr "Stylus Color 시리즈" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo 시리즈" + +msgid "Super A" +msgstr "수퍼 A" + +msgid "Super B" +msgstr "수퍼 B" + +msgid "Super B/A3" +msgstr "수퍼 B/A3" + +msgid "Switching Protocols" +msgstr "프로토콜 전환 중" + +msgid "Tabloid" +msgstr "타블로이드" + +msgid "Tabloid (Oversize)" +msgstr "타블로이드(대)" + +msgid "Tear" +msgstr "절취" + +msgid "Tear-Off" +msgstr "절취선" + +msgid "Tear-Off Adjust Position" +msgstr "절취선 조절 위치" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "\"%s\" PPD 파일을 찾을 수 없습니다." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "\"%s\" PPD 파일을 열 수 없습니다: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"클래스 이름은 최대 127자의 프린트 가능한 문자만을 포함할 수 있고 빈 칸, 슬래" +"시(/) 또는 파운드 기호(#)를 포함하지 않습니다." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "notify-lease-duration 속성을 작업 구독과 함께 사용할 수 없습니다." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "notify-user-data 값이 너무 큼!(%d > 63행)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"프린터 이름은 최대 127자의 프린트 가능한 문자만을 포함할 수 있고 빈 칸, 슬래" +"시(/) 또는 파운드 기호(#)를 포함하지 않습니다." + +msgid "The printer or class is not shared!" +msgstr "프린터 또는 클래스를 공유할 수 없음!" + +msgid "The printer or class was not found." +msgstr "프린터 또는 클래스가 없습니다." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "\"%s\" printer-uri가 유효하지 않은 문자를 포함합니다." + +msgid "The printer-uri attribute is required!" +msgstr "printer-uri 속성이 필요함!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "printer-uri는 \"ipp://HOSTNAME/classes/CLASSNAME\" 형태여야 합니다." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "printer-uri는 \"ipp://HOSTNAME/printers/PRINTERNAME\" 형태여야 합니다." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"구독 이름은 빈 칸, 슬래시(/), 물음표(?) 또는 파운드 기호(#)를 포함하지 않습니" +"다." + +msgid "There are too many subscriptions." +msgstr "구독이 너무 많습니다." + +msgid "Thermal Transfer Media" +msgstr "열 전송 미디어" + +msgid "Title: " +msgstr "제목: " + +msgid "Toner low." +msgstr "토너가 부족합니다." + +msgid "Too many active jobs." +msgstr "활성 작업이 너무 많습니다." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "job-sheets 값이 너무 많습니다(%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "printer-state-reasons 값이 너무 많습니다(%d > %d)!" + +msgid "Transparency" +msgstr "투명도" + +msgid "Tray" +msgstr "트레이" + +msgid "Tray 1" +msgstr "트레이 1" + +msgid "Tray 2" +msgstr "트레이 2" + +msgid "Tray 3" +msgstr "트레이 3" + +msgid "Tray 4" +msgstr "트레이 4" + +msgid "URI Too Long" +msgstr "URI가 너무 김" + +msgid "US Executive" +msgstr "US 행정 용지" + +msgid "US Fanfold" +msgstr "US 연속 용지" + +msgid "US Ledger" +msgstr "US 원장" + +msgid "US Legal" +msgstr "US 공문서" + +msgid "US Legal (Oversize)" +msgstr "US 공문서(대)" + +msgid "US Letter" +msgstr "US 편지지" + +msgid "US Letter (Oversize)" +msgstr "US 편지지(대)" + +msgid "US Letter (Small)" +msgstr "US 편지지(소)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB 시리얼 포트 #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "cupsd.conf 파일에 연결할 수 없음:" + +msgid "Unable to add RSS subscription:" +msgstr "RSS 구독을 추가할 수 없음:" + +msgid "Unable to add class:" +msgstr "클래스를 추가할 수 없음:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "\"%s\" 대상에 대한 작업을 추가할 수 없습니다!" + +msgid "Unable to add printer:" +msgstr "프린터를 추가할 수 없음:" + +msgid "Unable to allocate memory for file types!" +msgstr "파일 유형에 대한 메모리를 할당할 수 없습니다!" + +msgid "Unable to cancel RSS subscription:" +msgstr "RSS 구독을 취소할 수 없음:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "printer-is-shared 속성을 변경할 수 없음:" + +msgid "Unable to change printer:" +msgstr "프린터를 변경할 수 없음:" + +msgid "Unable to change server settings:" +msgstr "서버 설정값을 변경할 수 없음:" + +msgid "Unable to connect to host." +msgstr "호스트에 연결할 수 없음." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "64비트 CUPS 프린터 드라이버 파일을 복사할 수 없습니다(%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "64비트 Windows 프린터 드라이버 파일을 복사할 수 없습니다(%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "CUPS 프린터 드라이버 파일을 복사할 수 없습니다(%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "PPD 파일을 복사할 수 없음 - %s!" + +msgid "Unable to copy PPD file!" +msgstr "PPD 파일을 복사할 수 없습니다!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Windows 2000 프린터 드라이버 파일을 복사할 수 없습니다(%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Windows 9x 프린터 드라이버 파일을 복사할 수 없습니다(%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "인터페이스 스크립트를 복사할 수 없음 - %s!" + +msgid "Unable to create printer-uri!" +msgstr "printer-uri를 생성할 수 없습니다!" + +msgid "Unable to create temporary file:" +msgstr "임시 파일을 생성할 수 없음:" + +msgid "Unable to delete class:" +msgstr "클래스를 삭제할 수 없음:" + +msgid "Unable to delete printer:" +msgstr "프린터를 삭제할 수 없음:" + +msgid "Unable to do maintenance command:" +msgstr "명령을 유지할 수 없음:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "1MB보다 큰 cupsd.conf 파일은 편집할 수 없습니다!" + +msgid "Unable to find destination for job!" +msgstr "작업에 대한 대상을 찾을 수 없습니다!" + +msgid "Unable to find printer!\n" +msgstr "프린터를 찾을 수 없습니다!\n" + +msgid "Unable to get class list:" +msgstr "클래스 목록을 얻을 수 없음:" + +msgid "Unable to get class status:" +msgstr "클래스 상태를 알 수 없음:" + +msgid "Unable to get list of printer drivers:" +msgstr "프린터 드라이버 목록을 얻을 수 없음:" + +msgid "Unable to get printer attributes:" +msgstr "프린터 속성을 얻을 수 없음:" + +msgid "Unable to get printer list:" +msgstr "프린터 목록을 얻을 수 없음:" + +msgid "Unable to get printer status:" +msgstr "프린터 상태를 알 수 없습니다:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Windows 2000 프린터 드라이버 파일을 설치할 수 없습니다(%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Windows 9x 프린터 드라이버 파일을 설치할 수 없습니다(%d)!" + +msgid "Unable to modify class:" +msgstr "클래스를 수정할 수 없음:" + +msgid "Unable to modify printer:" +msgstr "프린터를 수정할 수 없음:" + +msgid "Unable to move job" +msgstr "작업을 이동할 수 없습니다" + +msgid "Unable to move jobs" +msgstr "작업을 이동할 수 없습니다" + +msgid "Unable to open PPD file" +msgstr "PPD 파일을 열 수 없습니다" + +msgid "Unable to open PPD file:" +msgstr "PPD 파일을 열 수 없음:" + +msgid "Unable to open cupsd.conf file:" +msgstr "cupsd.conf 파일을 열 수 없음:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "도큐멘트 %d을(를) 작업 %d에서 열 수 없습니다!" + +msgid "Unable to print test page:" +msgstr "테스트 페이지를 프린트할 수 없음:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "\"%s\"을(를) 실행할 수 없음: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "프린터 드라이버로 명령을 보낼 수 없습니다!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Windows 프린터 드라이버를 설정할 수 없습니다(%d)!" + +msgid "Unable to set options:" +msgstr "옵션을 설정할 수 없음:" + +msgid "Unable to set server default:" +msgstr "서버 기본값을 설정할 수 없음:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "cupsd.conf 파일을 업로드할 수 없습니다:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "레거시 USB 클래스 드라이버를 사용할 수 없음!\n" + +msgid "Unauthorized" +msgstr "인증되지 않음" + +msgid "Units" +msgstr "장비" + +msgid "Unknown" +msgstr "알 수 없음" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "알 수 없는 printer-error-policy \"%s\" ." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "알 수 없는 printer-op-policy \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "지원되지 않는 문자 세트 \"%s\"!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "지원되지 않는 압축 \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "지원되지 않는 압축 속성 %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "지원되지 않는 포맷 \"%s\"!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "지원되지 않는 포맷 '%s'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "지원되지 않는 포맷 '%s/%s'!" + +msgid "Unsupported value type" +msgstr "지원되지 않는 값 유형" + +msgid "Upgrade Required" +msgstr "업그레이드 필요함" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"사용법:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "사용법: %s job user title copies options [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "사용법: %s job-id user title copies options [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "사용법: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"사용법: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"옵션:\n" +" -E 서버 연결 암호화\n" +" -H samba-server SAMBA 서버 사용\n" +" -U samba-user 이름이 있는 SAMBA 사용자를 사용하여 인증\n" +" -a 모든 프린터 보내기\n" +" -h cups-server 이름이 있는 CUPS 서버 사용\n" +" -v 상세하게(명령 보기)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"사용법: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"옵션:\n" +"\n" +" -E 암호화 활성화\n" +" -U username 사용자 이름 지정\n" +" -h server[:port] 서버 주소 지정\n" +"\n" +" --[no-]debug-logging 디버그 로그 켜기/끄기\n" +" --[no-]remote-admin 원격 관리 켜기/끄기\n" +" --[no-]remote-any 인터넷 접근 허용/차단\n" +" --[no-]remote-printers 원격 프린터 보기/가리기\n" +" --[no-]share-printers 프린터 공유 켜기/끄기\n" +" --[no-]user-cancel-any 사용자가 모든 작업을 취소하는 것을 허용/차단\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"사용법: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file 대체 구성 파일 로드\n" +"-f 전면에 실행\n" +"-F 전면에 실행하지만 분리\n" +"-h 이 사용법 메시지 보기\\n-l launchd(8)에" +"서 cupsd 실행\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"사용법: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"옵션:\n" +"\n" +" -h 프로그램 사용법 보기\n" +"\n" +" 참고: 이 프로그램은 DSC 명령만을 유효화하고, PostScript 자체는 유효화하" +"지 않습니다.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "사용법: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"사용법: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "사용법: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"사용법: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"사용법: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"사용법: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"옵션:\n" +" -D name=value 이름이 정해진 변수를 값으로 설정합니다.\n" +" -I include-dir 포함 디렉토리를 검색 경로에 추가합니다.\n" +" -c catalog.po 지정된 메시지 카탈로그를 로드합니다.\n" +" -d output-dir 출력 디렉토리를 지정합니다.\n" +" -l lang[,lang,...] 출력 언어를 지정합니다(로컬).\n" +" -m 파일 이름으로 ModelName 값을 사용합니다.\n" +" -t PPD를 생성하는 대신 테스트합니다.\n" +" -v 자세하게(더 자세하게 하려면 v 추가).\n" +" -z GNU zip을 사용하여 PPD 파일을 압축합니다.\n" +" --cr CR로 줄을 끝냅니다(Mac OS 9).\n" +" --crlf CR + LF로 줄을 끝냅니다(Windows).\n" +" --lf LF로 줄을 끝냅니다(UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"사용법: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value 이름이 정해진 변수를 값으로 설정합니다.\n" +"옵션:\n" +" -I include-dir 포함 디렉토리를 검색 경로에 추가합니다.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"사용법: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"옵션:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"사용법: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"옵션:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"사용법: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"옵션:\n" +" -D name=value 이름이 정해진 변수를 값으로 설정합니다.\n" +" -I include-dir 포함 디렉토리를 검색 경로에 추가합니다.\n" +" -v 자세하게(더 자세하게 하려면 v 추가).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "사용법: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "값의 길이가 무제한입니다" + +msgid "VarBind uses indefinite length" +msgstr "VarBind의 길이가 무제한입니다" + +msgid "Version uses indefinite length" +msgstr "버전 길이가 무제한입니다" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: 발견된 첫번째 %d개 프린터만 추가 중" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: 불리언이 waiteof 옵션을 예상함 \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: 읽기 side-channel 요청에 실패함!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: IncludeFeature를 통해 \"%s\" 옵션을 포함할 수 없음!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: 프린터가 응답하지 않음\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: 프린터가 예기치 않은 EOF를 보냄\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "WARNING: %d초 후에 원격 호스트가 명령 상태 바이트에 응답하지 않음!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "WARNING: %d초 후에 원격 호스트가 제어 상태 바이트에 응답하지 않음!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "WARNING: %d초 후에 원격 호스트가 데이터 상태 바이트에 응답하지 않음!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI 명령 시간 초과(%d); 재시도 중...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: 이 도큐멘트는 Adobe Document Structuring Conventions을 실행하지 않" +"기 때문에 올바르게 프린트되지 않을 수 있음!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: \"%s:%s\"을(를) 열 수 없습니다: %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: PAP 상태 요청을 보낼 수 없습니다" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: %d 유형의 예기치 않은 PAP 패킷\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: %d 유형의 알 수 없는 PAP 패킷\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: \"%2$s\" 옵션에 대한 알 수 없는 \"%1$s\" 선택사항!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: 알 수 없는 \"%s\" 옵션!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: 지원되지 않는 보드율 %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: \"%s\" 상태 옵션에 대한 예상되는 번호\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: 복원 가능: '%s' 네트워크 호스트가 사용 중; %d초 후에 다시 시도...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "경고, 설치된 Windows 2000 프린터 드라이버가 없음!" + +msgid "Yes" +msgstr "예" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"https://%s:%d%s URL을 사용하여 이 페이지에 연" +"결해야 합니다." + +msgid "You4 Envelope" +msgstr "You4 봉투" + +msgid "ZPL Label Printer" +msgstr "ZPL 레이블 프린터" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "중단됨" + +msgid "canceled" +msgstr "취소됨" + +msgid "completed" +msgstr "완료됨" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: 변환할 파일을 지정하려면 -f 옵션을 사용합니다.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced 실행에 실패했습니다." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd 실행에 실패했습니다." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: \"%s\" 프린터에 대한 PPD 파일이 없음 - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: 다음 서버에 연결할 수 없습니다: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: 알 수 없는 옵션 \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: 알 수 없는 옵션 \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: \"-c\" 옵션 뒤에 구성 파일 이름이 예상됨!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: 현재 디렉토리를 얻을 수 없음!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: 알 수 없는 \"%s\" 변수 - 중단 중!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: 알 수 없는 \"%c\" 옵션 - 중단 중!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: launchd(8) 지원이 컴파일되지 않아서, 일반 모드로 실행합니다.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: 유효하지 않은 도큐멘트 번호 %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: 유효하지 않은 작업 ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: 하나의 사용자 이름만 지정됨!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: 작업 파일을 얻을 수 없음 - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: -q 옵션은 -v 옵션과 호환되지 않습니다.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: -v 옵션은 -q 옵션과 호환되지 않습니다.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "%s/%s에 대한 장비: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "%s에 대한 장비: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index 길이가 무제한입니다" + +msgid "error-status uses indefinite length" +msgstr "error-status 길이가 무제한입니다" + +msgid "held" +msgstr "유지됨" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\t명령에 대한 도움말 얻기\n" + +msgid "idle" +msgstr "대기" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri 속성이 유실됨!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: 클래스 이름은 프린트 가능한 문자만 포함할 수 있음!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: '-P' 옵션 뒤에 PPD가 예상됨!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: '-u' 옵션 뒤에 allow/deny:userlist가 예상됨!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: '-r' 옵션 뒤에 클래스가 예상됨!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: '-c' 옵션 뒤에 클래스 이름이 예상됨!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: '-D' 옵션 뒤에 설명이 예상됨!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: '-v' 옵션 뒤에 장비 URI가 예상됨!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: '-I' 옵션 뒤에 파일 유형이 예상됨!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: '-h' 옵션 뒤에 호스트 이름이 예상됨!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: '-i' 옵션 뒤에 인터페이스가 예상됨!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: '-L' 옵션 뒤에 위치가 예상됨!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: '-m' 옵션 뒤에 모델이 예상됨!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: '-o' 옵션 뒤에 name=value가 예상됨!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: '-p' 옵션 뒤에 프린터가 예상됨!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: '-d' 옵션 뒤에 프린터 이름이 예상됨!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: '-x' 옵션 뒤에 프린터 또는 클래스가 예상됨!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: 회원 이름이 보이지 않음!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: %s 프린터에 이미 %s 클래스 회원이 있습니다.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: %s 프린터에 %s 클래스 회원이 없습니다.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: 프린터 이름은 프린트 가능한 문자만 포함할 수 있음!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 클래스에 프린터를 추가할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: 서버에 연결할 수 없음: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: \"%s\" PPD 파일을 열 수 없음 - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: \"%s\" 파일을 열 수 없음: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 클래스에서 프린터를 제거할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: PPD 파일을 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 장비 URI를 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 인터페이스 스크립트 또는 PPD 파일을 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 인터페이스 스크립트를 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 프린터 설명을 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 프린터 위치를 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 프린터 옵션을 설정할 수 없음:\n" +" 먼저 프린터 이름을 지정해야 합니다!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: 알 수 없는 allow/deny 옵션 \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: 알 수 없는 '%s' 변수!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: 알 수 없는 '%c' 옵션!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: 경고 - 콘텐츠 유형 목록 무시됨!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: --device-id 뒤에 1284 장비 ID 스트링이 예상됨!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: --language 뒤에 언어가 예상됨!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: --make-and-model 뒤에 제조사 및 모델이 예상됨!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: --product 뒤에 제품 스트링이 예상됨!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: --exclude-schemes 뒤에 설계 목록이 예상됨!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: --include-schemess 뒤에 설계 목록이 예상됨!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: --timeout 뒤에 제한 시간이 예상됨!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: 알 수 없는 '%s' 변수!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: 알 수 없는 '%c' 옵션!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: 알 수 없는 '%s' 옵션!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: 서버에 연결할 수 없음: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: 알 수 없는 '%s' 변수!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: 알 수 없는 '%c' 옵션!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: 프린터가 없습니까!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: 프린터 또는 인스턴스를 추가할 수 없음: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: %s에 대한 PPD 파일을 얻을 수 없음: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: %s에 대한 PPD 파일을 열 수 없음!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: 알 수 없는 프린터 또는 클래스!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: root만 암호를 추가 또는 제거할 수 있음!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: 암호 파일 사용 중!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: 암호 파일이 업데이트되지 않음!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: 죄송합니다, 암호가 일치하지 않습니다!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: 죄송합니다, 암호가 거부되었습니다.\n" +"암호는 최소한 6자 이상이어야 하고, 사용자 이름을 포함해서는 안되며, \n" +"최소 하나 이상의 문자 및 숫자를 포함해야 합니다.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: 죄송합니다, 암호가 일치하지 않습니다!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: 암호 스트링을 복사할 수 없음: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: 암호 파일을 열 수 없음: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: 암호 파일에 쓸 수 없음: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: 이전 암호 파일을 백업하는데 실패함: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: 암호 파일 이름을 재설정하는데 실패함: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: \"%s\" 사용자 및 \"%s\" 그룹이 존재하지 않습니다.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "lpstat: 오류 - %s 환경 변수 이름이 존재하지 않는 대상 \"%s\" 이름임!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "%s 클래스 회원:\n" + +msgid "no entries\n" +msgstr "엔트리 없음\n" + +msgid "no system default destination\n" +msgstr "시스템 기본 대상 없음\n" + +msgid "notify-events not specified!" +msgstr "notify-events가 지정되지 않음!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri \"%s\" URI가 이미 사용 중임!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri \"%s\" URI가 알 수 없는 설계를 사용함!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "%d notify-subscription-id가 좋지 않습니다!" + +msgid "pending" +msgstr "보류 중" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: \"%s\" 포함 디렉토리 추가 중...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: %s에서 UI 텍스트 추가/업데이트 중...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: 잘못된 불리언 값(%1$s)이 %3$s의 %2$d번째 줄에 있음.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: 잘못된 \"%1$s\" 해상도 이름이 %3$s의 %2$d번째 줄에 있음!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: 잘못된 %1$s 상태 키워드가 %3$s의 %2$d번째 줄에 있음!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: 잘못된 변수 대체항목($%1$c)이 %3$s의 %2$d번째 줄에 있음.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: 선택사항이 %2$s의 %1$d번째 줄에서 옵션 없이 발견됨!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: 로컬 %1$s에 대한 중복된 #po가 %3$s의 %2$d번째 줄에 있음!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 필터 정의가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 프로그램 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 불리언 값이 예상됨.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Font 뒤에 문자 세트가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 선택사항 코드가 예상됨.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 선택사항 이름/텍스트가 예상됨.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 ColorModel에 대한 색상 순서가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 ColorModel에 대한 색상 공간이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 ColorModel에 대한 압축이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: %2$s의 %1$d번째 줄에 UIConstraints에 대한 제한 스트링이 예상됨!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: %2$s의 %1$d번째 줄, DriverType 뒤에 드라이버 유형 키워드가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Duplex 뒤에 양면 유형이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Font 뒤에 인코딩이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄, #po %1$s 뒤에 파일 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 그룹 이름/텍스트가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 포함 파일 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 정수가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, #po 뒤에 로컬 위치가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄, %1$s 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, FileName 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Font 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Manufacturer 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, MediaSize 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, ModelName 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, PCFileName 뒤에 이름이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄, %1$s 뒤에 이름/텍스트가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Installable 뒤에 이름/텍스트 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Resolution 뒤에 이름/텍스트 예상됨!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: %2$s의 %1$d번째 줄, ColorModel에 대해 이름/텍스트 조합이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 옵션 이름/텍스트가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 옵션 섹션이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄의 옵션 유형이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Resolution 뒤에 오버라이드 필드가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 실제 번호가 예상됨!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: %2$s의 %1$d번째 줄, ColorProfile 뒤에 해상도/미디어 유형이 예상됨!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: %2$s의 %1$d번째 줄, SimpleColorProfile 뒤에 해상도/미디어 유형이 예상" +"됨!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄, %1$s 뒤에 선택자가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Font 뒤에 상태가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Copyright 뒤에 스트링이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Version 뒤에 스트링이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 옵션 이름 2개가 예상됨!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄, %1$s 뒤에 값이 예상됨!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄, Font 뒤에 버전이 예상됨!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: 유효하지 않은 #include/#po 파일 이름 \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄의 필터에 대해 유효하지 않은 비용!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄의 필터에 대해 유효하지 않은 빈 MIME 유형!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" +"ppdc: %2$s의 %1$d번째 줄의 필터에 대해 유효하지 않은 빈 프로그램 이름!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 유효하지 않은 \"%1$s\" 옵션 섹션!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 유효하지 않은 \"%1$s\" 옵션 유형!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: \"%s\" 드라이버 정보 파일 로드 중...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: 로컬 \"%s\"에 대한 메시지 로드 중...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: \"%s\"에서 메시지 로드 중...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: \"%s\" 끝에서 #endif 유실됨!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에서 #if 유실됨!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: 로컬 %s에 대해 제공된 메시지 카탈로그 없음!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 %1$s 옵션이 다른 유형으로 재정의됨!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 있는 옵션 제한은 *name이어야 함!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: %2$s의 %1$d번째 줄에 너무 많이 중첩된 #if가 있음!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: \"%s\" PPD 파일을 생성할 수 없음 - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: %s 출력 디렉토리를 생성할 수 없음: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: 출력 파이프를 생성할 수 없음: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: cupstestppd를 실행할 수 없음: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에서 #po 파일 %1$s을(를) 찾을 수 없음!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에서 포함 파일 \"%1$s\"을(를) 찾을 수 없음!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: \"%s\"에 대한 현지화를 찾을 수 없음 - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: \"%s\"에 대한 현지화 파일을 로드할 수 없음 - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 변수(%1$s)가 정의되지 않음.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 알 수 없는 %1$s 드라이브 유형!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 알 수 없는 \"%1$s\" 양면 유형!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 알 수 없는 \"%1$s\" 미디어 크기!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 보이는 알 수 없는 \"%1$s\" 토큰!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: %3$s의 %2$d번째 줄에 있는 \"%1$s\" 실수에 알 수 없는 마지막 문자!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: %3$s의 %2$d번째 줄에 %1$c(으)로 시작하는 끝나지 않는 스트링!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: %s 쓰는 중...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: \"%s\" 디렉토리에 PPD 파일 쓰는 중...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: %2$s에 잘못된 \"%1$s\" LanguageVersion!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: %s PPD 파일 무시 중...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: %s을(를) %s(으)로 백업할 수 없음- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "%2$s 이후로 %1$s 프린터가 비활성화됨 -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "%s 프린터가 대기 중. %s 이후에 활성화됨\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "%s 프린터가 현재 %s-%d을(를) 프린트 중입니다. %s 이후에 활성화됨\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "%s/%s 프린터가 %s 이후에 비활성화됨 -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "%s/%s 프린터가 대기 중. %s 이후에 활성화됨\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "%s/%s 프린터가 현재 %s-%d을(를) 프린트 중입니다. %s 이후에 활성화됨\n" + +msgid "processing" +msgstr "처리 중" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "요청 id는 %s-%d(%d개의 파일)\n" + +msgid "request-id uses indefinite length" +msgstr "request-id 길이가 무제한입니다" + +msgid "scheduler is not running\n" +msgstr "일정이 실행되지 않음\n" + +msgid "scheduler is running\n" +msgstr "일정이 실행 중\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "%s 통계에 실패함: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "상태\t\t데몬 및 대기열 상태 보기\n" + +msgid "stopped" +msgstr "중단됨" + +#, c-format +msgid "system default destination: %s\n" +msgstr "시스템 기본 대상: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "시스템 기본 대상: %s/%s\n" + +msgid "unknown" +msgstr "알 수 없음" + +msgid "untitled" +msgstr "무제" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings의 길이가 무제한입니다" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN \"%s\" APDialogExtension 파일 유실됨\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN \"%s\" APPrinterIconPath 파일 유실됨\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: %s을(를) 열 수 없음 - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: %s을(를) 열 수 없음 - %s, %d번째 줄\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI 그레이 스케일" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: 명령 라인의 장비 URI가 유실되었고 DEVICE_URI 환경 변수가 없음!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: 임시 파일을 생성할 수 없음 - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: 임시 파일을 생성할 수 없음: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: 임시 파일을 열 수 없음" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops 필터가 신호 %d에서 충돌함!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops 필터가 상태 %d(으)로 종료됨!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "알 수 없는 프린터 오류(%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "사용법: convert [ options ]\n" +#~ "\n" +#~ "옵션:\n" +#~ "\n" +#~ " -f filename 변환할 파일 설정(또는 stdin)\n" +#~ " -o filename 생성할 파일 설정(또는 stdout)\n" +#~ " -i mime/type 입력 MIME 유형 설정(또는 자동 유형 설정)\n" +#~ " -j mime/type 출력 MIME 유형 설정(또는 응용 프로그램/pdf)\n" +#~ " -P filename.ppd PPD 파일 설정\n" +#~ " -a 'name=value ...' 옵션 설정(s)\n" +#~ " -U username 작업에 대한 사용자 이름 설정\n" +#~ " -J title 제목 설정\n" +#~ " -c copies 복사 장 수 설정\n" +#~ " -u 종료 시 PPD 파일 제거\n" +#~ " -D 종료 시 입력 파일 제거\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "사용법: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "옵션:\n" +#~ "\n" +#~ " -c cupsd.conf cupsd.conf 파일을 설정하여 사용\n" +#~ " -j job-id[,N] 특정 작업으로부터 파일 N 필터(기본은 파일 1)\n" +#~ " -n copies 복사 장 수 설정\n" +#~ " -o name=value 옵션 설정\n" +#~ " -p filename.ppd PPD 파일 설정\n" +#~ " -t title 제목 설정\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "사용법: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[." +#~ "gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "옵션:\n" +#~ "\n" +#~ " -R root-directory 대체 루트 설정\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " 오류대신 문제 경고\n" +#~ " -q 조용히 실행\n" +#~ " -r 'relaxed' 오픈 모드 사용\n" +#~ " -v 약간 자세하게\n" +#~ " -vv 매우 자세하게\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: 다음 임시 파일을 생성할 수 없습니다: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: 임시 파일을 생성할 수 없음 - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: 임시 파일을 생성할 수 없음: %s\n" diff --git a/locale/cups_nl.po b/locale/cups_nl.po new file mode 100644 index 0000000000..54c870dab6 --- /dev/null +++ b/locale/cups_nl.po @@ -0,0 +1,5726 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(alle)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(geen)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d onderdelen\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tNa storing: doorgaan\n" + +msgid "\tAlerts:" +msgstr "\tWaarschuwingen:" + +msgid "\tBanner required\n" +msgstr "\tBanner vereist\n" + +msgid "\tCharset sets:\n" +msgstr "\tCharset-sets:\n" + +msgid "\tConnection: direct\n" +msgstr "\tVerbinding: direct\n" + +msgid "\tConnection: remote\n" +msgstr "\tVerbinding: niet-lokaal\n" + +msgid "\tDefault page size:\n" +msgstr "\tStandaard paginagrootte:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tStandaardpitch:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tStandaard poortinstellingen:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tOmschrijving: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormulier geactiveerd:\n" +"\tInhoudstypes: alle\n" +"\tPrintertypes: onbekend\n" + +msgid "\tForms allowed:\n" +msgstr "\tFormulieren toegestaan:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterface: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterface: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterface: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tLocatie: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tBij storing: geen waarschuwing\n" + +msgid "\tUsers allowed:\n" +msgstr "\tGebruikers toegelaten:\n" + +msgid "\tUsers denied:\n" +msgstr "\tGebruikers geweigerd:\n" + +msgid "\tdaemon present\n" +msgstr "\tdaemon aanwezig\n" + +msgid "\tno entries\n" +msgstr "\tgeen onderdelen\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tprinter bevindt zich op apparaat &aops;%s&aops; snelheid -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tafdrukken is uitgeschakeld\n" + +msgid "\tprinting is enabled\n" +msgstr "\tafdrukken is ingeschakeld\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tgeplaatst in wachtrij voor %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tverplaatsen naar wachtrij is uitgeschakeld\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tverplaatsen naar wachtrij is ingeschakeld\n" + +msgid "\treason unknown\n" +msgstr "\tonbekende oorzaak\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" GEDETAILLEERDE RESULTATEN VOOR CONFORMANTIETEST\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Pagina 15, sectie 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Pagina 15, sectie 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Pagina 19, sectie 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Pagina 20, sectie 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Pagina 27, sectie 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Pagina 42, sectie 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Pagina 16-17, sectie 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Pagina 42-45, sectie 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Pagina 45-46, sectie 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Pagina 48-49, sectie 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Pagina 52-54, sectie 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f bytes\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\" conflicteert met \"%s %s\"\n" +" (beperking=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s heeft geen bijbehorende opties!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s deelt een gemeenschappelijke prefix met %s\n" +" REF: Pagina 15, sectie 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Standaardkeuzen conflicteren!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Sleutelwoord %s voor duplexoptie werkt mogelijk niet zoals " +"verwacht. Gebruik Duplex als sleutelwoord.\n" +" REF: Pagina 122, sectie 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN Bestand bevat een combinatie van CR-, LF- en CR LF-" +"regeleinden!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN &aops;LanguageEncoding&aops; vereist door PPD 4.3-" +"specificatie.\n" +" REF: Pagina 56-57, sectie 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Regel %d bevat alleen witruimte!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN &aops;Manufacturer&aops; vereist door PPD 4.3-specificatie.\n" +" REF: Pagina 58-59, sectie 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN PPD-bestanden voor andere systemen dan Windows mogen " +"uitsluitend LF als regeleinde gebruiken, niet CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Verouderde PPD-versie %.1f!\n" +" REF: Pagina 42, sectie 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName langer dan 8.3 komt niet overeen met PPD-" +"specificatie.\n" +" REF: Pagina 61-62, sectie 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols bevat PJL, maar JCL-attributen zijn niet " +"ingesteld.\n" +" REF: Pagina 78-79, sectie 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols bevat zowel PJL als BCP; verwachtte TBCP.\n" +" REF: Pagina 78-79, sectie 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN &aops;ShortNickName&aops; vereist door PPD 4.3-" +"specificatie.\n" +" REF: Pagina 64-65, sectie 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s bestaat niet!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Ongeldige %s keuze %s!\n" +" REF: Pagina 122, sectie 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Ongeldige UTF-8 \"%s\" vertaalreeks voor optie %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Ongeldige UTF-8 \"%s\" vertaalreeks voor optie %s, keuze %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Ongeldige waarde voor cupsFilter \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Ongeldig cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Ongeldige waarde voor cupsPreFilter \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Ongeldige cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Ongeldige taal \"%s\"!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Lege cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Ontbrekende \"%s\" vertaalreeks voor optie %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s Ontbrekende \"%s\" vertaalreeks voor optie %s, keuze %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Ontbrekende keuze *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Ontbrekende keuze *%s %s in cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Ontbrekend cupsFilter-bestand \"%s\"\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Ontbrekend cupsICCProfile-bestand \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Ontbrekend cupsPreFilter-bestand \"%s\"\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Ontbrekende cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Ontbrekende optie %s in UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Ontbrekende optie %s in cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Geen basisvertaling \"%s\" opgenomen in bestand!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s REQUIRED %s bevat geen definitie voor keuze None!\n" +" REF: Pagina 122, sectie 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s hash-waarde conflicteert met %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s veroorzaakt een lus!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** %s keuzenamen %s en %s verschillen alleen in " +"hoofdlettergebruik!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s moet 1284DeviceID zijn!\n" +" REF: Pagina 72, sectie 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** ONGELDIGE Default%s %s\n" +" REF: Pagina 40, sectie 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** ONGELDIGE DefaultImageableArea %s!\n" +" REF: Pagina 102, sectie 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** ONGELDIGE DefaultPaperDimension %s!\n" +" REF: Pagina 103, sectie 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** ONGELDIG JobPatchFile-attribuut in bestand\n" +" REF: Pagina 24, sectie 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** ONGELDIGE Manufacturer (moet zijn \"HP\")\n" +" REF: Pagina 211, tabel D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** ONGELDIGE Manufacturer (moet zijn \"Oki\")\n" +" REF: Pagina 211, tabel D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ONGELDIGE ModelName - \"%c\" niet toegestaan in tekenreeks.\n" +" REF: Pagina 59-60, sectie 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** ONGELDIGE PSVersion - niet \"(tekenreeks) int\".\n" +" REF: Pagina 62-64, sectie 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** ONGELDIG Product - niet \"(tekenreeks)\".\n" +" REF: Pagina 62, sectie 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ONGELDIGE ShortNickName - langer dan 31 tekens.\n" +" REF: Pagina 64-65, sectie 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Ongeldige %s keuze %s!\n" +" REF: Pagina 84, sectie 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Ongeldige FileVersion \"%s\"\n" +" REF: Pagina 56, sectie 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Ongeldige FormatVersion \"%s\"\n" +" REF: Pagina 56, sectie 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** Ongeldige LanguageEncoding %s - moet ISOLatin1 zijn!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** Ongeldige LanguageVersion %s - moet Engels zijn!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FAIL** Code voor standaardoptie kan niet worden geïnterpreteerd: %" +"s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** Standaardvertaalreeks voor optie %s keuze %s bevat 8-bits " +"tekens!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** Standaardvertaalreeks voor optie %s bevat 8-bits tekens!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Groepsnamen %s en %s verschillen alleen in " +"hoofdlettergebruik!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** %s keuzenaam %s komt meerdere keren voor!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Optienamen %s en %s verschillen alleen in " +"hoofdlettergebruik!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** REQUIRED Default%s\n" +" REF: Pagina 40, sectie 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Pagina 102, sectie 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Pagina 103, sectie 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Pagina 56, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Pagina 56, sectie 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED ImageableArea voor PageSize %s\n" +" REF: Pagina 41, sectie 5.\n" +" REF: Pagina 102, sectie 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pagina 56-57, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pagina 57-58, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pagina 58-59, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pagina 59-60, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED NickName\n" +" REF: Pagina 60, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pagina 61-62, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pagina 62-64, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Pagina 100, sectie 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pagina 41, sectie 5.\n" +" REF: Pagina 99, sectie 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pagina 99-100, sectie 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED PaperDimension voor PageSize %s\n" +" REF: Pagina 41, sectie 5.\n" +" REF: Pagina 103, sectie 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED Product\n" +" REF: Pagina 62, sectie 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Pagina 64-65, sectie 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d FOUTEN GEVONDEN" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Ongeldige %%%%BoundingBox: op regel %d!\n" +" REF: Pagina 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Ongeldige %%%%Page: op regel %d!\n" +" REF: Pagina 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Ongeldige %%%%Pages: op regel %d!\n" +" REF: Pagina 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Regel %d bevat meer dan 255 tekens (%d)!\n" +" REF: Pagina 25, Line Length\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" Ontbrekende %!PS-Adobe-3.0 op eerste regel!\n" +" REF: Pagina 17, 3.1 Conforming Documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Ontbrekend %%EndComments-commentaar!\n" +" REF: Pagina 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Ontbrekend of ongeldig %%BoundingBox-commentaar!\n" +" REF: Pagina 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Ontbrekend of ongeldig %%Page-commentaar!\n" +" REF: Pagina 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Ontbrekend of ongeldig %%Pages-commentaar!\n" +" REF: Pagina 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " GEEN FOUTEN GEVONDEN\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " %d Regels gevonden met meer dan 255 tekens!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Te veel %%BeginDocument-commentaren!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Te veel %%EndDocument-commentaren!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Waarschuwing: bestand bevat binaire gegevens!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Waarschuwing: bestand bevat geen %%EndComments-commentaar!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Waarschuwing: bestand bevat verouderde DSC versie %.1f!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** Kan PPD-bestand niet openen - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** Kan PPD-bestand niet openen - %s op regel %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10-envelop" + +msgid "#11 Envelope" +msgstr "#11-envelop" + +msgid "#12 Envelope" +msgstr "#12-envelop" + +msgid "#14 Envelope" +msgstr "#14-envelop" + +msgid "#9 Envelope" +msgstr "#9-envelop" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f millimeter" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f tot %.0f x %.0f millimeter" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f inch" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f tot %.2f x %.2f inch" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s accepteert verzoeken sinds %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s kan niet worden gewijzigd." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s is niet geïmplementeerd in de CUPS-versie van lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s is niet gereed\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s is gereed\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s is gereed en bezig met afdrukken\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s accepteert geen verzoeken sinds %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s niet ondersteund!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s accepteert verzoeken sinds %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s accepteert geen verzoeken sinds %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [taak %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s niet gelukt: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Ik weet niet wat ik moet doen!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Fout - %s niet-bestaande bestemming voor variabelenamen van omgeving \"%s" +"\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Fout - ongeldige taak-ID!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Fout - niet mogelijk om gelijktijdig bestanden af te drukken en taken te " +"wijzigen!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Fout - niet mogelijk om af te drukken vanuit stdin als bestanden of een " +"taak-ID zijn aangeleverd!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Fout - verwachtte tekenset na optie &aops;-S&aops;!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Fout - verwachtte inhoudstype na optie &aops;-T&aops;!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Fout - verwachtte aantal afdrukken na optie &aops;-n&aops;!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Fout - verwachtte aantal exemplaren na optie &aops;-#&aops;!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Fout - verwachtte bestemming na optie &aops;-P&aops;!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Fout - verwachtte bestemming na optie &aops;-b&aops;!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Fout - verwachtte bestemming na optie &aops;-d&aops;!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Fout - verwachtte formulier na optie &aops;-f&aops;!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Fout - verwachtte hold-naam na optie &aops;-H&aops;!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Fout - verwachtte hostnaam na optie &aops;-H&aops;!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Fout - verwachtte hostnaam na optie &aops;-h&aops;!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Fout - verwachtte moduslijst na optie &aops;-y&aops;!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Fout - verwachtte naam na optie &aops;-%c&aops;!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Fout - verwachtte optietekenreeks na optie &aops;-o&aops;!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Fout - verwachtte paginalijst na optie &aops;-P&aops;!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Fout - verwachtte prioriteit na optie &aops;-%c&aops;!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Fout - verwachtte verklaring na optie &aops;-r&aops;!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Fout - verwachtte titel na optie &aops;-t&aops;!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Fout - verwachtte gebruikersnaam na optie &aops;-U&aops;!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Fout - verwachtte gebruikersnaam na optie &aops;-u&aops;!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Fout - verwachtte waarde na optie &aops;-%c&aops;!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Fout - optie &aops;-W&aops; moet worden gevolgd door \"gereed\", \"niet " +"gereed\" of \"alle\"!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Fout - geen standaardbestemming beschikbaar.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Fout - prioriteit moet tussen 1 en 100 liggen.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Fout - taakplanner reageert niet!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Fout - te veel bestanden - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Fout - niet mogelijk om \"%s\" te benaderen - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Fout - in wachtrij plaatsen vanaf stdin is niet mogelijk - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Fout - onbekende bestemming \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Fout - onbekende bestemming \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Fout - onbekende optie &aops;%c&aops;!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Fout - onbekende optie '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Verwachtte taak-ID na optie &aops;-i&aops;!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filter \"%s\" niet beschikbaar: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Ongeldige bestemmingsnaam in lijst \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Ongeldige filtertekenreeks \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "" +"%s: Taak-ID (&aops;-i jobid&aops;) nodig voor &aops;-H restart&aops;!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Geen filter beschikbaar voor conversie van %s/%s naar %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Bewerking mislukt: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Sorry, geen ondersteuning voor encryptie opgenomen!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Kan geen verbinding tot stand brengen met server\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Kan geen contact maken met server!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Niet mogelijk om MIME-type van \"%s\" vast te stellen!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Niet mogelijk om %s te openen: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Niet mogelijk om PPD-bestand %s in regel %d te openen\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Niet mogelijk om MIME-database van \"%s\" of \"%s\" te lezen!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Onbekende bestemming \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Onbekend MIME-type voor bestemming %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Onbekende optie &aops;%c&aops;!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Onbekend MIME-type voor bron %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Waarschuwing - &aops;%c&aops; format modifier niet ondersteund - uitvoer " +"is mogelijk niet correct!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Waarschuwing - tekensetoptie genegeerd!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Waarschuwing - inhoudstype-optie genegeerd!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Waarschuwing - formulieroptie genegeerd!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Waarschuwing - modusoptie genegeerd!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: fout - %s niet-bestaande bestemming voor variabelenamen van omgeving \"%s" +"\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: fout - verwachtte optie=waarde na optie &aops;-o&aops;!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: fout - geen standaardbestemming beschikbaar.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 inch/sec." + +msgid "1.25x0.25\"" +msgstr "1,25x0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25x2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 inch/sec." + +msgid "1.50x0.25\"" +msgstr "1,50x0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50x0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50x1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50x2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 inch/sec." + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/sec." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 inch/sec." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 inch/sec." + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/sec." + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/sec." + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/sec." + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 inch/sec." + +msgid "2-Sided Printing" +msgstr "Dubbelzijdig afdrukken" + +msgid "2.00x0.37\"" +msgstr "2,00x0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00x0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00x1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00x1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00x2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00x3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00x4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00x5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25x0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25x1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25x4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25x5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38x5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 inch/sec." + +msgid "2.50x1.00\"" +msgstr "2,50x1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50x2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75x1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/sec." + +msgid "200 mm/sec." +msgstr "200 mm/sec." + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-pens serie" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/sec." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 inch/sec." + +msgid "3.00x1.00\"" +msgstr "3,00x1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00x1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00x2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00x3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00x5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25x2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25x5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25x5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25x5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25x7,83\"" + +msgid "3.5\" Disk" +msgstr "3,5-inch diskette" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3,5-inch diskette - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50x1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/sec." + +msgid "300 mm/sec." +msgstr "300 mm/sec." + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 inch/sec." + +msgid "4.00x1.00\"" +msgstr "4,00x1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00x13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00x2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00x2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00x3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00x4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00x5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00x6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00x6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/sec." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 inch/sec." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 inch/sec." + +msgid "6.00x1.00\"" +msgstr "6,00x1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00x2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00x3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00x4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00x5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00x6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00x6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/sec." + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 inch/sec." + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 inch/sec." + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00x1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00x2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00x3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00x4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00x5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00x6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00x6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/sec." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 inch/sec." + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9-pens serie" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Ongeldig en onbekend helpcommando\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"Voor het exporteren van printerstuurprogramma&aops;s is een Samba-wachtwoord " +"vereist!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Voor het exporteren van printerstuurprogramma&aops;s is een Samba-" +"gebruikersnaam vereist!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Er is al een klasse met de naam \"%s\"!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Er is al een printer met de naam \"%s\"!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (oversize)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (oversize)" + +msgid "A4 (Small)" +msgstr "A4 (klein)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (oversize)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Accepteer taken" + +msgid "Accepted" +msgstr "Geaccepteerd" + +msgid "Add Class" +msgstr "Voeg klasse toe" + +msgid "Add Printer" +msgstr "Voeg printer toe" + +msgid "Add RSS Subscription" +msgstr "Voeg RSS-abonnement toe" + +msgid "Address" +msgstr "Adres" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adres - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Beheer" + +msgid "Always" +msgstr "Altijd" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applicator" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Poging om %s printer-state in te stellen op ongeldige waarde %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Attribuutgroepen hebben verkeerde volgorde (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Ongeldige NULL-bestemmingspointer" + +msgid "Bad OpenGroup" +msgstr "Ongeldige OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Ongeldige OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Ongeldige OrderDependency" + +msgid "Bad Request" +msgstr "Ongeldig verzoek" + +msgid "Bad SNMP version number" +msgstr "Ongeldig SNMP-versienummer" + +msgid "Bad UIConstraints" +msgstr "Ongeldige UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Ongeldige waarde voor aantal exemplaren %d." + +msgid "Bad custom parameter" +msgstr "Ongeldige zelfingestelde parameter" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Ongeldige apparaat-URI \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Ongeldige device-uri \"%s\"!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Ongeldig device-uri-schema \"%s\"!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Ongeldige documentindeling \"%s\"!" + +msgid "Bad filename buffer!" +msgstr "Ongeldige bestandsnaambuffer!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Ongeldig lettertypeattribuut: %s\n" + +msgid "Bad job-priority value!" +msgstr "Ongeldige waarde voor job-priority!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Ongeldige waarde voor job-sheets \"%s\"!" + +msgid "Bad job-sheets value type!" +msgstr "Ongeldig waardetype voor job-sheets!" + +msgid "Bad job-state value!" +msgstr "Ongeldige waarde voor job-state!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Ongeldig job-uri-attribuut \"%s\"!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Ongeldige notify-pull-method \"%s\"!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Ongeldige URI voor notify-recipient-uri \"%s\"!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Ongeldige waarde voor number-up %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Ongeldige optie + keuze op regel %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Ongeldige waarden voor paginabereik %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Ongeldige port-monitor \"%s\"!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Ongeldige waarde voor printer-state %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Ongeldig versienummer voor verzoek %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Ongeldig abonnement-ID!" + +msgid "Banners" +msgstr "Banners" + +msgid "Billing Information: " +msgstr "Factuurgegevens: " + +msgid "Bond Paper" +msgstr "Bankpost" + +msgid "C0 Envelope" +msgstr "C0-envelop" + +msgid "C1 Envelope" +msgstr "C1-envelop" + +msgid "C2 Envelope" +msgstr "C2-envelop" + +msgid "C3 Envelope" +msgstr "C3-envelop" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4-envelop" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5-envelop" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6-envelop" + +msgid "C65 Envelope" +msgstr "C65-envelop" + +msgid "C7 Envelope" +msgstr "C7-envelop" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL-etikettenprinter" + +msgid "Cancel RSS Subscription" +msgstr "Zeg RSS-abonnement op" + +msgid "Change Settings" +msgstr "Wijzig instellingen" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Tekenset \"%s\" niet ondersteund!" + +msgid "Chou3 Envelope" +msgstr "Chou3-envelop" + +msgid "Chou4 Envelope" +msgstr "Chou4-envelop" + +msgid "Classes" +msgstr "Klassen" + +msgid "Clean Print Heads" +msgstr "Reinig printerkoppen" + +msgid "Color" +msgstr "Kleur" + +msgid "Color Mode" +msgstr "Kleurenmodus" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Commando&aops;s kunnen worden afgekort. Commando&aops;s zijn:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor community-naam" + +msgid "Continue" +msgstr "Ga door" + +msgid "Continuous" +msgstr "Doorlopend" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Kon type \"%s\" niet scannen!" + +msgid "Cover open." +msgstr "Printklep open." + +msgid "Created" +msgstr "Aangemaakt" + +msgid "Created On: " +msgstr "Aangemaakt op: " + +msgid "Custom" +msgstr "Zelfingesteld" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Afsnijden" + +msgid "Cutter" +msgstr "Snijmachine" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL-envelop" + +msgid "Dark" +msgstr "Donker" + +msgid "Darkness" +msgstr "Donkerte" + +msgid "Delete Class" +msgstr "Verwijder klasse" + +msgid "Delete Printer" +msgstr "Verwijder printer" + +msgid "Description: " +msgstr "Beschrijving: " + +msgid "DeskJet Series" +msgstr "DeskJet-serie" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Bestemming \"%s\" accepteert geen opdrachten." + +msgid "Developer almost empty." +msgstr "Ontwikkelaar bijna op." + +msgid "Developer empty!" +msgstr "Ontwikkelaar op!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Apparaat: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Direct Thermal-materiaal" + +msgid "Disabled" +msgstr "Uitgeschakeld" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Document %d is niet gevonden in taak %d." + +msgid "Door open." +msgstr "Deur open." + +msgid "Double Postcard" +msgstr "Dubbele briefkaart" + +msgid "Driver Name: " +msgstr "Naam stuurprogramma: " + +msgid "Driver Version: " +msgstr "Versie stuurprogramma: " + +msgid "Duplexer" +msgstr "Duplexer" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Niet mogelijk geheugen toe te kennen voor pagina-info: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Niet mogelijk geheugen toe te kennen voor paginareeks: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1-etikettenprinter" + +msgid "EPL2 Label Printer" +msgstr "EPL2-etikettenprinter" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Ongeldige %%BoundingBox: opmerking ontdekt!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Ongeldige %%IncludeFeature: opmerking!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Ongeldige %%Page: opmerking in bestand!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Ongeldige %%PageBoundingBox: opmerking in bestand!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Ongeldig SCSI-apparaatbestand \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Ongeldig tekensetbestand %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Ongeldig tekensettype %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Ongeldige kolomwaarde %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Ongeldige cpi-waarde %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Ongeldige regel voor lettertypeomschrijving: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Ongeldige lpi-waarde %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Ongeldige pagina-instelling!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Ongeldige tekstrichting %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Ongeldige tekstbreedte %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Printer die is gekozen als bestemming bestaat niet!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Dubbele %%BoundingBox: opmerking ontdekt!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Dubbele %%Pages: opmerking ontdekt!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Leeg afdrukbestand!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Fout %d bij versturen PAPSendData-verzoek: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "" +"ERROR: Verwachtte tekenreeks met aanhalingstekens in regel %d van %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Fatale USB-fout!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Ongeldig HP-GL/2-commando ontdekt, kan afdrukbestand niet openen!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: Ontbrekende %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: Ontbrekende %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Ontbrekende waarde in regel %d van bannerbestand!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: msgid-regel vereist voorafgaand aan vertaalreeksen in regel %d van %" +"s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Geen %%BoundingBox: opmerking in kopregel!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Geen %%Pages: opmerking in kopregel!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Geen apparaat-URI gevonden in argv[0] of in DEVICE_URI-" +"omgevingsvariabele!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Geen lettertypen in tekensetbestand %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Geen pagina&aops;s gevonden!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Papier is op!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER-omgevingsvariabele niet gedefinieerd!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Afdrukbestand niet geaccepteerd (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Printer reageert niet\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Printer reageert niet!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Printer heeft onverwacht einde-bestandteken verstuurd\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Niet-lokale host heeft stuurbestand niet geaccepteerd (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Niet-lokale host heeft gegevensbestand niet geaccepteerd (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Time-out-fout tijdens het versturen van gegevens naar de printer\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Niet mogelijk om bestand %d toe te voegen aan taak: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Niet mogelijk om afdruktaak %d te annuleren: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Niet mogelijk om PDF-bestand te kopiëren" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Niet mogelijk om socket aan te maken" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: Niet mogelijk om tijdelijk gecomprimeerd afdrukbestand te maken: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Niet mogelijk om tijdelijk bestand aan te maken" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Niet mogelijk om pictwpstops uit te voeren: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Niet mogelijk om gs-programma uit te voeren" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Niet mogelijk om pdftops-programma uit te voeren" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Niet mogelijk om pictwpstops te splitsen: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Niet mogelijk om PAP-verzoek op te vragen" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Niet mogelijk om PAP-reactie op te vragen" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: Niet mogelijk om PPD-bestand voor printer \"%s\" op te vragen - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Niet mogelijk om standaard-AppleTalk-zone op te vragen" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Niet mogelijk om taakattributen %d op te vragen (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Niet mogelijk om printerstatus op te vragen (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Niet mogelijk om printer &aops;%s&aops; te vinden!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Niet mogelijk om naar PAP-reactie te zoeken" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Niet mogelijk om naar AppleTalk-printers te zoeken" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Niet mogelijk om AppleTalk-adres aan te maken" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Niet mogelijk om \"%s\" te openen - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Niet mogelijk om %s te openen: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Niet mogelijk om bannerbestand \"%s\" te openen - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Niet mogelijk om apparaatbestand \"%s\" te openen: %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Niet mogelijk om bestand \"%s\" te openen - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Niet mogelijk om bestand \"%s\" te openen: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Niet mogelijk om beeldbestand te openen voor afdrukken!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Niet mogelijk om afdrukbestand \"%s\" te openen: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Niet mogelijk om afdrukbestand %s te openen - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Niet mogelijk om afdrukbestand %s te openen: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: Niet mogelijk om tijdelijk gecomprimeerd afdrukbestand te openen: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Niet mogelijk om %d tekstkolommen af te drukken!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Niet mogelijk om %dx%d tekstpagina af te drukken!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Niet mogelijk om afdrukgegevens te lezen" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Niet mogelijk om afdrukgegevens te lezen!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Niet mogelijk om poort te reserveren" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "" +"ERROR: Niet mogelijk om te proberen %ld in bestand te positioneren - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "" +"ERROR: Niet mogelijk om te proberen %lld in bestand te positioneren - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Niet mogelijk om LPD-commando te versturen" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Niet mogelijk om PAP-tickleverzoek te versturen" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "" +"ERROR: Niet mogelijk om initieel PAP-verzoek voor versturen gegevens te " +"versturen" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Niet mogelijk om afdrukgegevens te verzenden (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Niet mogelijk om afdrukgegevens te versturen!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Niet mogelijk om afdrukbestand naar printer te versturen" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "" +"ERROR: Niet mogelijk om afsluitende lege tekens naar printer te versturen" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Niet mogelijk om te wachten op pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Niet mogelijk om %d bytes te schrijven naar \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Niet mogelijk om %d bytes naar printer te schrijven!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Niet mogelijk om stuurbestand weg te schrijven" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Niet mogelijk om afdrukgegevens weg te schrijven" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Niet mogelijk om afdrukgegevens weg te schrijven: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "" +"ERROR: Niet mogelijk om rastergegevens weg te schrijven naar " +"stuurprogramma!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Niet mogelijk om naar tijdelijk bestand te schrijven" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" +"ERROR: Niet mogelijk om ongecomprimeerde documentgegevens weg te schrijven: %" +"s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Onverwachte tekst in regel %d van %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Onbekende waarde voor encryptie-optie \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Onbekende bestandsvolgorde \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Onbekend opmaakteken \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Onbekende berichtencatalogusstructuur voor \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Onbekende optie \"%s\" met waarde \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Onbekende afdrukmodus \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Onbekende waarde voor versie-optie \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "" +"ERROR: Niet-ondersteunde waarde voor helderheid %s, gebruikt " +"helderheid=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Niet-ondersteunde waarde voor gamma %s, gebruikt gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" +"ERROR: Niet-ondersteunde waarde voor number-up %d, gebruikt number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Niet-ondersteunde waarde voor number-up-layout %s, gebruikt number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Niet-ondersteunde waarde voor page-border %s, gebruikt page-" +"border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "" +"ERROR: doc_printf-overflow (%d bytes) ontdekt, afdrukken wordt geannuleerd!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops gestopt na signaal %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops gestopt met status %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: kan worden hersteld: niet mogelijk om verbinding te maken met " +"printer; nieuwe poging over 30 seconden...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() mislukt" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: stat van afdrukbestand niet mogelijk" + +msgid "Edit Configuration File" +msgstr "Bewerk configuratiebestand" + +msgid "Empty PPD file!" +msgstr "Leeg PPD-bestand!" + +msgid "Ending Banner" +msgstr "Eindebanner" + +msgid "Enter old password:" +msgstr "Voer oude wachtwoord in:" + +msgid "Enter password again:" +msgstr "Voer wachtwoord opnieuw in:" + +msgid "Enter password:" +msgstr "Voer wachtwoord in:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Voer uw gebruikersnaam en wachtwoord of de $%$root-gebruikersnaam en " +"bijbehorend wachtwoord in om deze pagina te benaderen. Maakt u gebruik van " +"Kerberos-toegangscontrole, controleer dan of u over een geldig Kerberos-" +"ticket beschikt." + +msgid "Envelope Feed" +msgstr "Envelopinvoer" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Foutenbeleid" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Fout: hostnaam nodig na optie &aops;-h&aops;!\n" + +msgid "Every 10 Labels" +msgstr "Elke 10 etiketten" + +msgid "Every 2 Labels" +msgstr "Elke 2 etiketten" + +msgid "Every 3 Labels" +msgstr "Elke 3 etiketten" + +msgid "Every 4 Labels" +msgstr "Elke 4 etiketten" + +msgid "Every 5 Labels" +msgstr "Elke 5 etiketten" + +msgid "Every 6 Labels" +msgstr "Elke 6 etiketten" + +msgid "Every 7 Labels" +msgstr "Elke 7 etiketten" + +msgid "Every 8 Labels" +msgstr "Elke 8 etiketten" + +msgid "Every 9 Labels" +msgstr "Elke 9 etiketten" + +msgid "Every Label" +msgstr "Elk etiket" + +msgid "Expectation Failed" +msgstr "Verwachting mislukt" + +msgid "Export Printers to Samba" +msgstr "Exporteer printers naar Samba" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Dossiermap" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Dossiermap - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"File device-URI&aops;s zijn uitgeschakeld! Raadpleeg als u de URI&aops;s " +"weer wilt inschakelen de richtlijn voor FileDevice in \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Verboden" + +msgid "Fuser temperature high!" +msgstr "Fusertemperatuur te hoog!" + +msgid "Fuser temperature low!" +msgstr "Fusertemperatuur te laag!" + +msgid "General" +msgstr "Algemeen" + +msgid "Generic" +msgstr "Generiek" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor Get-Response-PDU" + +msgid "Glossy Paper" +msgstr "Glanzend papier" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Printer-uri-attribuut gevonden, maar geen job-id!" + +msgid "Grayscale" +msgstr "Grijstinten" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Hangmap" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Hangmap - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk uitgeschakeld in Systeemvoorkeuren\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk uitgeschakeld in Systeemvoorkeuren.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Afdrukopdracht wordt geannuleerd...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Verbonden met printer...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Verbinden met printer...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Stuurbestand succesvol verzonden\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Gegevensbestand succesvol verzonden\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Bezig met indelen van pagina %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Bezig met laden van beeldbestand...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Zoeken naar printer...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Verbinding wordt geopend\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Afdrukbestand verzonden, wacht tot printer gereed is...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Printer is bezig; nieuwe poging over 10 seconden...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Printer is bezig; nieuwe poging over 30 seconden...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Printer is bezig; nieuwe poging over 5 seconden...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: Printer biedt geen ondersteuning voor IPP/%d.%d, probeert nu " +"IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Printer is bezig; nieuwe poging over 5 seconden...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Printer is momenteel offline.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Printer is momenteel offline.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Printer is nu online.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Printer is offline.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Geen verbinding met printer; nieuwe poging over 30 seconden...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Bezig met afdrukken van pagina %d, %d%% gereed...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Bezig met afdrukken van pagina %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Klaar om af te drukken.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Bezig met verzending van stuurbestand (%lu bytes)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Bezig met verzending van stuurbestand (%u bytes)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Bezig met verzenden van gegevens\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Bezig met verzenden van gegevensbestand (%ld bytes)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Bezig met verzenden van gegevensbestand (%lld bytes)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Afdrukgegevens worden verstuurd...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Afdrukbestand is verzonden, %ld bytes...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Afdrukbestand is verzonden, %lld bytes...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Bezig met spoolen van LPR-taak, %.0f%% gereed...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Kan geen contact maken met printer, taak wordt overgebracht naar " +"volgende printer in klasse...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Standaard-AppleTalk-zone \"%s\" wordt gebruikt\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Wacht tot afdrukopdracht is afgerond...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Wacht tot printer beschikbaar is...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4-envelop" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (oversize)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5-envelop" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6-envelop" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Ongeldig besturingsteken" + +msgid "Illegal main keyword string" +msgstr "Ongeldige tekenreeks voor hoofdsleutelwoord" + +msgid "Illegal option keyword string" +msgstr "Ongeldige tekenreeks voor optiesleutelwoord" + +msgid "Illegal translation string" +msgstr "Ongeldige tekenreeks voor vertaling" + +msgid "Illegal whitespace character" +msgstr "Ongeldig teken voor witruimte" + +msgid "Ink/toner almost empty." +msgstr "Inkt/toner bijna op." + +msgid "Ink/toner empty!" +msgstr "Inkt/toner op!" + +msgid "Ink/toner waste bin almost full." +msgstr "Opvangbak voor inkt/toner bijna vol." + +msgid "Ink/toner waste bin full!" +msgstr "Opvangbak voor inkt/toner vol!" + +msgid "Installable Options" +msgstr "Uitbreidingsmogelijkheden" + +msgid "Installed" +msgstr "Geïnstalleerd" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar-etikettenprinter" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Interlock open." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Interne fout" + +msgid "Internet Postage 2-Part" +msgstr "Internet Postage 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Internet Postage 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet Postage 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internet Printing Protocol" + +msgid "Invite Envelope" +msgstr "Invite-envelop" + +msgid "Italian Envelope" +msgstr "Italian-envelop" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Taak #%d kan niet worden herstart - geen bestanden!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Taak #%d bestaat niet!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Taak #%d is al afgebroken - kan niet worden geannuleerd." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Taak #%d is al geannuleerd - kan niet worden geannuleerd." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Taak #%d is al gereed - kan niet worden geannuleerd." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Taak #%d is gereed en kan niet worden gewijzigd!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Taak #%d is nog niet gereed!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Taak #%d wordt niet vastgehouden voor controle!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Taak #%d wordt niet vastgehouden!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Taak #%s bestaat niet!" + +#, c-format +msgid "Job %d not found!" +msgstr "Taak %d niet gevonden!" + +msgid "Job Completed" +msgstr "Taak gereed" + +msgid "Job Created" +msgstr "Taak aangemaakt" + +msgid "Job ID: " +msgstr "Taak-ID: " + +msgid "Job Options Changed" +msgstr "Taakopties gewijzigd" + +msgid "Job Stopped" +msgstr "Taak gestopt" + +msgid "Job UUID: " +msgstr "Taak-UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "Taak is gereed en kan niet worden gewijzigd." + +msgid "Job operation failed:" +msgstr "Verwerking van taak is mislukt:" + +msgid "Job state cannot be changed." +msgstr "Status van taak kan niet worden gewijzigd." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Taakabonnementen kunnen niet worden verlengd!" + +msgid "Jobs" +msgstr "Taken" + +msgid "Kaku2 Envelope" +msgstr "Kaku2-envelop" + +msgid "Kaku3 Envelope" +msgstr "Kaku3-envelop" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR-host of -printer" + +msgid "Label Printer" +msgstr "Etikettenprinter" + +msgid "Label Top" +msgstr "Bovenkant etiket" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Taal \"%s\" wordt niet ondersteund!" + +msgid "Large Address" +msgstr "Groot adres" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Groot adres - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet-serie PCL 4/5" + +msgid "Light" +msgstr "Licht" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Regel is langer dan toegestane maximum (255 tekens)" + +msgid "List Available Printers" +msgstr "Toon beschikbare printers" + +msgid "Location: " +msgstr "Locatie: " + +msgid "Long-Edge (Portrait)" +msgstr "Lange kant (staand)" + +msgid "Make and Model: " +msgstr "Merk en model: " + +msgid "Manual Feed" +msgstr "Handmatige invoer" + +msgid "Media Dimensions: " +msgstr "Afmetingen materiaal: " + +msgid "Media Limits: " +msgstr "Min. en max. afmetingen: " + +msgid "Media Name: " +msgstr "Materiaalnaam: " + +msgid "Media Size" +msgstr "Materiaalgrootte" + +msgid "Media Source" +msgstr "Bron voor materiaal" + +msgid "Media Tracking" +msgstr "Materiaaldetectie" + +msgid "Media Type" +msgstr "Materiaaltype" + +msgid "Media jam!" +msgstr "Materiaal is vastgelopen!" + +msgid "Media tray almost empty." +msgstr "Materiaallade is bijna leeg." + +msgid "Media tray empty!" +msgstr "Materiaallade is leeg!" + +msgid "Media tray missing!" +msgstr "Materiaallade ontbreekt!" + +msgid "Media tray needs to be filled." +msgstr "Materiaallade moet worden bijgevuld." + +msgid "Medium" +msgstr "Materiaal" + +msgid "Memory allocation error" +msgstr "Geheugentoewijzingsfout" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Ontbrekende PPD-Adobe-4.x-kopregel" + +msgid "Missing asterisk in column 1" +msgstr "Ontbrekende asterisk in kolom 1" + +msgid "Missing document-number attribute!" +msgstr "Document-number-attribuut ontbreekt!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Ontbrekend dubbel aanhalingsteken op regel %d!" + +msgid "Missing form variable!" +msgstr "Ontbrekende formuliervariabele!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Notify-subscription-ids-attribuut ontbreekt!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Requesting-user-name-attribuut ontbreekt!" + +msgid "Missing required attributes!" +msgstr "Vereiste attributen ontbreken!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Ontbrekende waarde op regel %d!" + +msgid "Missing value string" +msgstr "Ontbrekende tekenreeks voor waarde" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Wijzig klasse" + +msgid "Modify Printer" +msgstr "Wijzig printer" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch-envelop" + +msgid "Move All Jobs" +msgstr "Verplaats alle taken" + +msgid "Move Job" +msgstr "Verplaats taak" + +msgid "Moved Permanently" +msgstr "Definitief verplaatst" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Afdrukbestand geaccepteerd - taak-ID %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Afdrukbestand geaccepteerd - taak-ID onbekend.\n" + +msgid "NULL PPD file pointer" +msgstr "NULL-pointer voor PPD-bestand" + +msgid "Name OID uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor naam-OID" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Nooit" + +msgid "New Stylus Color Series" +msgstr "Nieuwe Stylus Color-serie" + +msgid "New Stylus Photo Series" +msgstr "Nieuwe Stylus Photo-serie" + +msgid "No" +msgstr "Nee" + +msgid "No Content" +msgstr "Geen inhoud" + +msgid "No PPD name!" +msgstr "Geen PPD-naam!" + +msgid "No VarBind SEQUENCE" +msgstr "Geen VarBind-SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Er zijn geen Windows-printerstuurprogramma&aops;s geïnstalleerd!" + +msgid "No active connection" +msgstr "Geen actieve verbinding" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Geen actieve taken op %s!" + +msgid "No attributes in request!" +msgstr "Verzoek bevat geen attributen!" + +msgid "No authentication information provided!" +msgstr "Geen informatie verstrekt voor toegangscontrole!" + +msgid "No community name" +msgstr "Geen community-naam" + +msgid "No default printer" +msgstr "Geen standaardprinter" + +msgid "No destinations added." +msgstr "Geen bestemmingen toegevoegd." + +msgid "No error-index" +msgstr "Geen error-index" + +msgid "No error-status" +msgstr "Geen error-status" + +msgid "No file!?!" +msgstr "Geen bestand!?!" + +msgid "No modification time!" +msgstr "Geen bewerkingstijdstip!" + +msgid "No name OID" +msgstr "Geen naam-OID" + +msgid "No printer name!" +msgstr "Geen printernaam!" + +msgid "No printer-uri found for class!" +msgstr "Geen printer-uri gevonden voor klasse!" + +msgid "No printer-uri found!" +msgstr "Geen printer-uri gevonden!" + +msgid "No printer-uri in request!" +msgstr "Verzoek bevat geen printer-uri!" + +msgid "No request-id" +msgstr "Geen verzoek-ID" + +msgid "No subscription attributes in request!" +msgstr "Verzoek bevat geen attributen voor abonnement!" + +msgid "No subscriptions found." +msgstr "Geen abonnementen gevonden." + +msgid "No variable-bindings SEQUENCE" +msgstr "Geen variable-bindings-SEQUENCE" + +msgid "No version number" +msgstr "Geen versienummer" + +msgid "Non-continuous (Mark sensing)" +msgstr "Niet-doorlopend (markeringssensor)" + +msgid "Non-continuous (Web sensing)" +msgstr "Niet-doorlopend (afstandssensor)" + +msgid "Normal" +msgstr "Normaal" + +msgid "Not Found" +msgstr "Niet gevonden" + +msgid "Not Implemented" +msgstr "Niet geïmplementeerd" + +msgid "Not Installed" +msgstr "Niet geïnstalleerd" + +msgid "Not Modified" +msgstr "Niet gewijzigd" + +msgid "Not Supported" +msgstr "Niet ondersteund" + +msgid "Not allowed to print." +msgstr "Afdrukken niet toegestaan." + +msgid "Note" +msgstr "Opmerking" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC bijna aan einde levensduur." + +msgid "OPC at end-of-life!" +msgstr "OPC aan einde levensduur!" + +msgid "Off (1-Sided)" +msgstr "Uit (enkelzijdig)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Online Help" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "Openen van %s mislukt: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup zonder eerst een CloseGroup" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI zonder eerst een CloseUI/JCLCloseUI" + +msgid "Operation Policy" +msgstr "Gebruiksbeleid" + +msgid "Options Installed" +msgstr "Geïnstalleerde opties" + +msgid "Options: " +msgstr "Opties: " + +msgid "Out of toner!" +msgstr "Toner is op!" + +msgid "Output Mode" +msgstr "Uitvoermodus" + +msgid "Output bin almost full." +msgstr "Uitvoerbak is bijna vol." + +msgid "Output bin full!" +msgstr "Uitvoerbak is vol!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Uitvoer voor printer %s wordt gestuurd naar %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "" +"Uitvoer voor printer %s wordt gestuurd naar niet-lokale printer %s op %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Uitvoer voor printer %s/%s wordt gestuurd naar %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"Uitvoer voor printer %s/%s wordt gestuurd naar niet-lokale printer %s op %s\n" + +msgid "Output tray missing!" +msgstr "Uitvoerbak ontbreekt!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "PCL-laserprinter" + +msgid "PRC1 Envelope" +msgstr "PRC1-envelop" + +msgid "PRC10 Envelope" +msgstr "PRC10-envelop" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2-envelop" + +msgid "PRC3 Envelope" +msgstr "PRC3-envelop" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (oversize)" + +msgid "PRC4 Envelope" +msgstr "PRC4-envelop" + +msgid "PRC5 Envelope" +msgstr "PRC5-envelop" + +msgid "PRC6 Envelope" +msgstr "PRC6-envelop" + +msgid "PRC7 Envelope" +msgstr "PRC7-envelop" + +msgid "PRC8 Envelope" +msgstr "PRC8-envelop" + +msgid "PRC9 Envelope" +msgstr "PRC9-envelop" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Pakket bevat geen Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Pakket begint niet met SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Wachtwoord voor %s op %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Wachtwoord voor %s vereist om %s te benaderen via SAMBA: " + +msgid "Pause Class" +msgstr "Onderbreek klasse" + +msgid "Pause Printer" +msgstr "Onderbreek printer" + +msgid "Peel-Off" +msgstr "Zelfklevend" + +msgid "Personal Envelope" +msgstr "Personal-envelop" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Foto-etiketten" + +msgid "Plain Paper" +msgstr "Gewoon papier" + +msgid "Policies" +msgstr "Beleid" + +msgid "Port Monitor" +msgstr "Poortmonitor" + +msgid "PostScript Printer" +msgstr "PostScript-printer" + +msgid "Postcard" +msgstr "Briefkaart" + +msgid "Print Density" +msgstr "Afdrukdichtheid" + +msgid "Print Job:" +msgstr "Afdruktaak:" + +msgid "Print Mode" +msgstr "Afdrukmodus" + +msgid "Print Rate" +msgstr "Afdrukdoorvoer" + +msgid "Print Self-Test Page" +msgstr "Druk zelftestpagina af" + +msgid "Print Speed" +msgstr "Afdruksnelheid" + +msgid "Print Test Page" +msgstr "Druk testpagina af" + +msgid "Print and Cut" +msgstr "Afdrukken en afsnijden" + +msgid "Print and Tear" +msgstr "Afdrukken en afscheuren" + +msgid "Printed For: " +msgstr "Afgedrukt voor: " + +msgid "Printed From: " +msgstr "Afgedrukt vanaf: " + +msgid "Printed On: " +msgstr "Afgedrukt op: " + +msgid "Printer Added" +msgstr "Printer toegevoegd" + +msgid "Printer Default" +msgstr "Printerstandaard" + +msgid "Printer Deleted" +msgstr "Printer verwijderd" + +msgid "Printer Modified" +msgstr "Printer gewijzigd" + +msgid "Printer Name: " +msgstr "Printernaam: " + +msgid "Printer Paused" +msgstr "Printer onderbroken" + +msgid "Printer Settings" +msgstr "Printerinstellingen" + +msgid "Printer offline." +msgstr "Printer offline." + +msgid "Printer:" +msgstr "Printer:" + +msgid "Printers" +msgstr "Printers" + +msgid "Purge Jobs" +msgstr "Maak takenlijst leeg" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Quotumlimiet bereikt." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Positie Eigenaar Taak Bestand(en) Totale " +"grootte\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Positie Eigenaar Prioriteit Taak " +"Bestanden Totale grootte\n" + +msgid "Reject Jobs" +msgstr "Weiger taken" + +msgid "Reprint After Error" +msgstr "Druk opnieuw af na fout" + +msgid "Request Entity Too Large" +msgstr "Request Entity te groot" + +msgid "Resolution" +msgstr "Resolutie" + +msgid "Resume Class" +msgstr "Hervat klasse" + +msgid "Resume Printer" +msgstr "Hervat printer" + +msgid "Return Address" +msgstr "Adres afzender" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Adres afzender - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Oprollen" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Commando wordt uitgevoerd: %s %s -N -A %s -c &aops;%s&aops;\n" + +msgid "SCSI Printer" +msgstr "SCSI-printer" + +msgid "SEQUENCE uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor SEQUENCE" + +msgid "See Other" +msgstr "Zie andere" + +#, c-format +msgid "Serial Port #%d" +msgstr "Seriële poort #%d" + +msgid "Server Restarted" +msgstr "Server herstart" + +msgid "Server Security Auditing" +msgstr "Serverbeveiligingscontrole" + +msgid "Server Started" +msgstr "Server gestart" + +msgid "Server Stopped" +msgstr "Server gestopt" + +msgid "Service Unavailable" +msgstr "Voorziening niet beschikbaar" + +msgid "Set Allowed Users" +msgstr "Stel aantal toegestane gebruikers in" + +msgid "Set As Server Default" +msgstr "Stel in als serverstandaard" + +msgid "Set Class Options" +msgstr "Stel klasseopties in" + +msgid "Set Printer Options" +msgstr "Stel printeropties in" + +msgid "Set Publishing" +msgstr "Stel publicatie in" + +msgid "Shipping Address" +msgstr "Afleveradres" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Afleveradres - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Korte kant (liggend)" + +msgid "Special Paper" +msgstr "Speciaal papier" + +msgid "Standard" +msgstr "Standaard" + +msgid "Starting Banner" +msgstr "Startbanner" + +msgid "Statement" +msgstr "Statement" + +msgid "Stylus Color Series" +msgstr "Stylus Color-serie" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo-serie" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Schakelen tussen protocollen" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (oversize)" + +msgid "Tear" +msgstr "Scheuren" + +msgid "Tear-Off" +msgstr "Afscheuren" + +msgid "Tear-Off Adjust Position" +msgstr "Pas positie voor afscheuren aan" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Het PPD-bestand \"%s\" kon niet worden gevonden." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Het PPD-bestand \"%s\" kon niet worden geopend: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"De klassenaam mag maximaal 127 afdrukbare tekens en geen spaties, schuine " +"strepen (/) of hekjes (#) bevatten." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Het attribuut &aops;notify-lease-duration&aops; kan niet worden gebruikt bij " +"taakabonnementen." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "De waarde voor notify-user-data is te groot (%d > 63 octetten)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"De printernaam mag maximaal 127 afdrukbare tekens en geen spaties, schuine " +"strepen (/) of hekjes (#) bevatten." + +msgid "The printer or class is not shared!" +msgstr "" +"De printer of klasse is niet toegankelijk voor gemeenschappelijk gebruik!" + +msgid "The printer or class was not found." +msgstr "De printer of klasse kon niet worden gevonden." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "De printer-uri \"%s\" bevat ongeldige tekens." + +msgid "The printer-uri attribute is required!" +msgstr "Het attribuut &aops;printer-uri&aops; is vereist!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"De printer-uri moet de vorm \"ipp://HOSTNAAM/klassen/KLASSENAAM\" hebben." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"De printer-uri moet de vorm \"ipp://HOSTNAAM/printers/PRINTERNAAM\" hebben." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"De abonnementsnaam mag geen spaties, schuine strepen (/), vraagtekens (?) of " +"hekjes (#) bevatten." + +msgid "There are too many subscriptions." +msgstr "Er zijn te veel abonnementen." + +msgid "Thermal Transfer Media" +msgstr "Thermal Transfer-materiaal" + +msgid "Title: " +msgstr "Titel: " + +msgid "Toner low." +msgstr "Toner is bijna op." + +msgid "Too many active jobs." +msgstr "Te veel actieve taken." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Te veel waarden voor job-sheets (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Te veel waarden voor printer-state-reasons (%d > %d)!" + +msgid "Transparency" +msgstr "Transparantie" + +msgid "Tray" +msgstr "Lade" + +msgid "Tray 1" +msgstr "Lade 1" + +msgid "Tray 2" +msgstr "Lade 2" + +msgid "Tray 3" +msgstr "Lade 3" + +msgid "Tray 4" +msgstr "Lade 4" + +msgid "URI Too Long" +msgstr "URI te lang" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Legal" + +msgid "US Legal (Oversize)" +msgstr "US Legal (oversize)" + +msgid "US Letter" +msgstr "US Letter" + +msgid "US Letter (Oversize)" +msgstr "US Letter (oversize)" + +msgid "US Letter (Small)" +msgstr "US Letter (klein)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB-seriële poort #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Niet mogelijk om toegang te krijgen tot cupsd.conf-bestand:" + +msgid "Unable to add RSS subscription:" +msgstr "Niet mogelijk om RSS-abonnement toe te voegen:" + +msgid "Unable to add class:" +msgstr "Niet mogelijk om klasse toe te voegen:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Niet mogelijk om taak toe te voegen voor bestemming \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Niet mogelijk om printer toe te voegen:" + +msgid "Unable to allocate memory for file types!" +msgstr "Niet mogelijk om geheugen toe te wijzen voor bestandstypen!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Niet mogelijk om RSS-abonnement op te zeggen:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Niet mogelijk om attribuut &aops;printer-is-shared&aops; te wijzigen:" + +msgid "Unable to change printer:" +msgstr "Niet mogelijk om printer te wijzigen:" + +msgid "Unable to change server settings:" +msgstr "Niet mogelijk om serverinstellingen te wijzigen:" + +msgid "Unable to connect to host." +msgstr "Niet mogelijk om verbinding met host te maken." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" +"Niet mogelijk om 64-bits CUPS-printerstuurprogramma&aops;s te kopiëren (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Niet mogelijk om 64-bits Windows-printerstuurprogramma&aops;s te kopiëren (%" +"d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Niet mogelijk om CUPS-printerstuurprogramma&aops;s te kopiëren (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Niet mogelijk om PPD-bestand te kopiëren - %s!" + +msgid "Unable to copy PPD file!" +msgstr "Niet mogelijk om PPD-bestand te kopiëren!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"Niet mogelijk om Windows 2000-printerstuurprogramma&aops;s te kopiëren (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" +"Niet mogelijk om Windows 9x-printerstuurprogramma&aops;s te kopiëren (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Niet mogelijk om interfacescript te kopiëren - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Niet mogelijk om printer-uri aan te maken!" + +msgid "Unable to create temporary file:" +msgstr "Niet mogelijk om tijdelijk bestand aan te maken:" + +msgid "Unable to delete class:" +msgstr "Niet mogelijk om klasse te verwijderen:" + +msgid "Unable to delete printer:" +msgstr "Niet mogelijk om printer te verwijderen:" + +msgid "Unable to do maintenance command:" +msgstr "Niet mogelijk om onderhoudscommando op te geven:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Niet mogelijk om cupsd.conf-bestanden van meer dan 1 MB te bewerken!" + +msgid "Unable to find destination for job!" +msgstr "Bestemming voor taak kon niet worden gevonden!" + +msgid "Unable to find printer!\n" +msgstr "Printer is niet gevonden!\n" + +msgid "Unable to get class list:" +msgstr "Niet mogelijk om klasselijst weer te geven:" + +msgid "Unable to get class status:" +msgstr "Niet mogelijk om klassestatus weer te geven:" + +msgid "Unable to get list of printer drivers:" +msgstr "Niet mogelijk om lijst van printerstuurprogramma&aops;s weer te geven:" + +msgid "Unable to get printer attributes:" +msgstr "Niet mogelijk om printerattributen weer te geven:" + +msgid "Unable to get printer list:" +msgstr "Niet mogelijk om printerlijst weer te geven:" + +msgid "Unable to get printer status:" +msgstr "Niet mogelijk om printerstatus weer te geven:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Niet mogelijk om Windows 2000-printerstuurprogramma&aops;s te installeren (%" +"d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"Niet mogelijk om Windows 9x-printerstuurprogramma&aops;s te installeren (%d)!" + +msgid "Unable to modify class:" +msgstr "Niet mogelijk om klasse te wijzigen:" + +msgid "Unable to modify printer:" +msgstr "Niet mogelijk om printer te wijzigen:" + +msgid "Unable to move job" +msgstr "Niet mogelijk om taak te verplaatsen" + +msgid "Unable to move jobs" +msgstr "Niet mogelijk om taken te verplaatsen" + +msgid "Unable to open PPD file" +msgstr "Niet mogelijk om PPD-bestand te openen" + +msgid "Unable to open PPD file:" +msgstr "Niet mogelijk om PPD-bestand te openen:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Niet mogelijk om cupsd.conf-bestand te openen:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Niet mogelijk om document %d in taak %d te openen!" + +msgid "Unable to print test page:" +msgstr "Niet mogelijk om testpagina af te drukken:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Niet mogelijk om \"%s\" uit te voeren: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Niet mogelijk om commando naar printerstuurprogramma te versturen!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Niet mogelijk om Windows-printerstuurprogramma in te stellen (%d)!" + +msgid "Unable to set options:" +msgstr "Niet mogelijk om opties in te stellen:" + +msgid "Unable to set server default:" +msgstr "Niet mogelijk om serverstandaard in te stellen:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Niet mogelijk om cupsd.conf file-bestand te uploaden:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Niet mogelijk om verouderd USB-stuurprogramma te gebruiken!\n" + +msgid "Unauthorized" +msgstr "Onbevoegd" + +msgid "Units" +msgstr "Eenheden" + +msgid "Unknown" +msgstr "Onbekend" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Onbekend printerfoutbeleid \"%s\"." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Onbekend printergebruiksbeleid \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Niet-ondersteunde tekenset \"%s\"!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Niet-ondersteunde compressie \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Niet-ondersteund compressie-attribuut %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Niet-ondersteunde indeling \"%s\"!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Niet-ondersteunde indeling '%s'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Niet-ondersteunde indeling '%s/%s'!" + +msgid "Unsupported value type" +msgstr "Niet-ondersteund waardetype" + +msgid "Upgrade Required" +msgstr "Upgrade vereist" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Gebruik:\n" +"\n" +" lpadmin [-h server] -d bestemming\n" +" lpadmin [-h server] -x bestemming\n" +" lpadmin [-h server] -p printer [-c voeg klasse toe] [-i interface] [-m " +"model]\n" +" [-r verwijder klasse] [-v apparaat] [-D " +"omschrijving]\n" +" [-P ppd-bestand] [-o naam=waarde]\n" +" [-u sta toe:gebruiker,gebruiker] [-u weiger:gebruiker," +"gebruiker]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Gebruik: %s job user title copies options [bestandsnaam]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Gebruik: %s job-id user title copies options [bestand]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Gebruik: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Gebruik: cupsaddsmb [opties] printer1 ... printerN\n" +" cupsaddsmb [opties] -a\n" +"\n" +"Opties:\n" +" -E Gebruik encryptie voor verbinding met server\n" +" -H samba-server Gebruik genoemde SAMBA-server\n" +" -U samba-gebruiker Controleer toegang via genoemde SAMBA-gebruiker\n" +" -a Exporteer alle printers\n" +" -h cups-server Gebruik genoemde CUPS-server\n" +" -v Gebruik verbose-modus (toon commando&aops;s)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Gebruik: cupsctl [opties] [param=waarde ... paramN=waardeN]\n" +"\n" +"Opties:\n" +"\n" +" -E Schakel encryptie in\n" +" -U gebruikersnaam Geef gebruikersnaam op\n" +" -h server[:poort] Geef serveradres op\n" +"\n" +" --[no-]debug-logging Schakel debug-logging in/uit\n" +" --[no-]remote-admin Schakel beheer op afstand in/uit\n" +" --[no-]remote-any Maak toegang via het internet mogelijk/" +"onmogelijk\n" +" --[no-]remote-printers Toon/verberg niet-lokale printers\n" +" --[no-]share-printers Schakel gemeenschappelijk printergebruik in/uit\n" +" --[no-]user-cancel-any Maak annuleren van taken door gebruikers " +"mogelijk/onmogelijk\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Gebruik: cupsd [-c config-bestand] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Laad alternatief configuratiebestand\n" +"-f Voer uit op voorgrond\n" +"-F Voer uit op voorgrond, losgekoppeld\n" +"-h Toon dit gebruiksbericht\n" +"-l Voer cupsd uit vanaf launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Gebruik: cupstestdsc [opties] bestandsnaam.ps [... bestandsnaam.ps]\n" +" cupstestdsc [opties] -\n" +"\n" +"Opties:\n" +"\n" +" -h Toon programmagebruik\n" +"\n" +" Opmerking: dit programma valideert alleen het DSC-commentaar, niet de " +"PostScript-code.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Gebruik: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Gebruik: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o optie[=waarde] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Gebruik: lppasswd [-g groepsnaam]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Gebruik: lppasswd [-g groepsnaam] [gebruikersnaam]\n" +" lppasswd [-g groepsnaam] -a [gebruikersnaam]\n" +" lppasswd [-g groepsnaam] -x [gebruikersnaam]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Gebruik: lpq [-P bestemming] [-U gebruikersnaam] [-h hostnaam[:poort]] [-l] " +"[+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Gebruik: ppdc [opties] bestandsnaam.drv [ ... bestandsnaamN.drv ]\n" +"Opties:\n" +" -D naam=waarde Stel benoemde variabele in op waarde.\n" +" -I include-dir Voeg include-directory toe aan zoekpad.\n" +" -c catalogus.po Laad de opgegeven berichtencatalogus.\n" +" -d uitvoer-dir Geef de uitvoerdirectory op.\n" +" -l taal[,taal,...] Geef de uitvoertaal/-talen (taalversie) op.\n" +" -m Gebruik de ModelName-waarde als bestandsnaam.\n" +" -t Test PPD&aops;s in plaats van ze te genereren.\n" +" -v Gebruik verbose-modus (meer v's voor uitgebreidere " +"modus).\n" +" -z Comprimeer PPD-bestanden met GNU-zip.\n" +" --cr Sluit regels af met CR (Mac OS 9).\n" +" --crlf Sluit regels af met CR + LF (Windows).\n" +" --lf Sluit regels af met LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Gebruik: ppdhtml [opties] bestandsnaam.drv >bestandsnaam.html\n" +" -D naam=waarde Stel benoemde variabele in op waarde.\n" +"Opties:\n" +" -I include-dir Voeg include-directory toe aan zoekpad.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Gebruik: ppdi [opties] bestandsnaam.ppd [ ... bestandsnaamN.ppd ]\n" +"Opties:\n" +" -I include-dir\n" +" -o bestandsnaam.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Gebruik: ppdmerge [opties] bestandsnaam.ppd [ ... bestandsnaamN.ppd ]\n" +"Opties:\n" +" -o bestandsnaam.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Gebruik: ppdpo [opties] -o bestandsnaam.po bestandsnaam.drv [ ... " +"bestandsnaamN.drv ]\n" +"Opties:\n" +" -D naam=waarde Stel benoemde variabele in op waarde.\n" +" -I include-dir Voeg include-directory toe aan zoekpad.\n" +" -v Gebruik verbose-modus (meer v's voor uitgebreidere " +"modus).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Gebruik: snmp [host- of ip-adres]\n" + +msgid "Value uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor waarde" + +msgid "VarBind uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor VarBind" + +msgid "Version uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor versie" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Alleen de eerste %d gevonden printers worden toegevoegd" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Verwachtte Boolean voor optie &aops;waiteof&aops; \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Kon zijkanaalverzoek niet lezen!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" +"WARNING: Optie \"%s\" kan niet worden ingevoegd met behulp van " +"IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Printer reageert niet\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Printer heeft onverwacht einde-bestandteken verstuurd\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Niet-lokale host heeft niet binnen %d seconden gereageerd met " +"commandostatusbyte!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Niet-lokale host heeft niet binnen %d seconden gereageerd met " +"besturingsstatusbyte!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Niet-lokale host heeft niet binnen %d seconden gereageerd met " +"gegevensstatusbyte!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI-commando niet tijdig verwerkt (%d); nieuwe poging...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Dit document beantwoordt niet aan de Adobe Document Structuring " +"Conventions en wordt mogelijk niet goed afgedrukt!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Niet mogelijk om \"%s:%s\" te openen: %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Niet mogelijk om PAP-statusverzoek te versturen" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Onverwacht PAP-pakket van type %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Onbekend PAP-pakket van type %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Onbekende keuze \"%s\" voor optie \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Onbekende optie \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Niet-ondersteunde baudsnelheid %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: Verwachtte getal voor statusoptie \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: Herstelbare fout: netwerkhost &aops;%s&aops; is bezig; nieuwe " +"poging over %d seconden...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Let op: geen Windows 2000-printerstuurprogramma&aops;s geïnstalleerd!" + +msgid "Yes" +msgstr "Ja" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"U dient deze pagina te benaderen via de URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "You4-envelop" + +msgid "ZPL Label Printer" +msgstr "ZPL-etikettenprinter" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "afgebroken" + +msgid "canceled" +msgstr "geannuleerd" + +msgid "completed" +msgstr "gereed" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "" +"convert: Gebruik de optie -f om het bestand op te geven dat u wilt " +"converteren.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced niet uitgevoerd." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd niet uitgevoerd." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Geen PPD-bestand voor printer \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "" +"cupsctl: Niet mogelijk om verbinding met server tot stand te brengen: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Onbekende optie \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Onbekende optie \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Verwachtte config-bestandsnaam na optie \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Niet mogelijk om huidige directory op te vragen!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Onbekend argument \"%s\" - bewerking wordt afgebroken!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Onbekende optie \"%c\" - bewerking wordt afgebroken!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: Geen ondersteuning voor launchd(8) opgenomen, bewerking wordt " +"uitgevoerd in normale modus.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Ongeldig documentnummer %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: Ongeldige taak-ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: U kunt slechts één bestandsnaam opgeven!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Niet mogelijk om taakbestand op te vragen - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "" +"cupstestppd: De optie -q kan niet worden gebruikt in combinatie met de optie " +"-v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "" +"cupstestppd: De optie -v kan niet worden gebruikt in combinatie met de optie " +"-q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "apparaat voor %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "apparaat voor %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor error-index" + +msgid "error-status uses indefinite length" +msgstr "Onbepaalde lengte gebruikt voor error-status" + +msgid "held" +msgstr "vastgehouden" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\thulpinformatie voor commando&aops;s opvragen\n" + +msgid "idle" +msgstr "niet in gebruik" + +msgid "job-printer-uri attribute missing!" +msgstr "Job-printer-uri-attribuut ontbreekt!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Klassenaam mag alleen afdrukbare tekens bevatten!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: Verwachtte PPD na optie &aops;-P&aops;!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Verwachtte allow/deny:userlist na optie &aops;-u&aops;!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Verwachtte klasse na optie &aops;-r&aops;!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Verwachtte klassenaam na optie &aops;-c&aops;!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Verwachtte omschrijving na optie &aops;-D&aops;!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Verwachtte apparaat-URI na optie &aops;-v&aops;!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Verwachtte bestandstype(n) na optie &aops;-I&aops;!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Verwachtte hostnaam na optie &aops;-h&aops;!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Verwachtte interface na optie &aops;-i&aops;!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Verwachtte locatie na optie &aops;-L&aops;!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Verwachtte model na optie &aops;-m&aops;!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Verwachtte naam=waarde na optie &aops;-o&aops;!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Verwachtte printer na optie &aops;-p&aops;!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Verwachtte printernaam na optie &aops;-d&aops;!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Verwachtte printer of klasse na optie &aops;-x&aops;!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Geen lidnamen ontdekt!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Printer %s is al lid van klasse %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Printer %s is geen lid van klasse %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Printernaam mag alleen afdrukbare tekens bevatten!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om printer aan klasse toe te voegen:\n" +" U moet eerst een printernaam opgeven!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "" +"lpadmin: Niet mogelijk om verbinding tot stand te brengen met server: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Niet mogelijk om PPD-bestand \"%s\" te openen - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Niet mogelijk om bestand \"%s\" te openen: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om printer uit klasse te verwijderen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om het PPD-bestand in te stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om de apparaat-URI in te stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om het interfacescript of het PPD-bestand in te " +"stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om het interfacescript in te stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om de printerbeschrijving in te stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om de printerlocatie in te stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Niet mogelijk om de printeropties in te stellen:\n" +" U moet eerst een printernaam opgeven!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Onbekende optie voor toestaan/weigeren \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Onbekend argument &aops;%s&aops;!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Onbekende optie &aops;%c&aops;!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Waarschuwing - inhoudstypelijst genegeerd!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: Verwachtte tekenreeks met 1284-apparaat-ID na --device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Verwachtte taal na --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Verwachtte merk en model na --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Verwachtte producttekenreeks na --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Verwachtte schemalijst na --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Verwachtte schemalijst na --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Verwachtte time-out na --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Onbekend argument &aops;%s&aops;!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Onbekende optie &aops;%c&aops;!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Onbekende optie &aops;%s&aops;!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "" +"lpmove: Niet mogelijk om verbinding met server tot stand te brengen: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Onbekend argument &aops;%s&aops;!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Onbekende optie &aops;%c&aops;!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Geen printers!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Niet mogelijk om printer of instance toe te voegen: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Niet mogelijk om PPD-bestand voor %s op te vragen: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Niet mogelijk om PPD-bestand voor %s te openen!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Onbekende printer of klasse!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Alleen root kan wachtwoorden toevoegen of verwijderen!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Wachtwoordbestand is in gebruik!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Wachtwoordbestand niet bijgewerkt!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Wachtwoord komt helaas niet overeen!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Dit wachtwoord is helaas niet toegestaan.\n" +"Uw wachtwoord moet uit minimaal 6 tekens bestaan, waarvan minimaal één " +"letter en één cijfer, en mag niet uw gebruikersnaam bevatten.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Wachtwoorden komen helaas niet overeen!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Niet mogelijk om wachtwoordreeks te kopiëren: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Niet mogelijk om wachtwoordbestand te openen: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Niet mogelijk om wachtwoordbestand weg te schrijven: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: Kon geen reservekopie maken van oude wachtwoordbestand: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: Kon wachtwoordbestand geen andere naam geven: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: Gebruiker \"%s\" en groep \"%s\" bestaan niet.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: fout - %s niet-bestaande bestemming voor variabelenamen van omgeving " +"\"%s\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "leden van klasse %s:\n" + +msgid "no entries\n" +msgstr "geen onderdelen\n" + +msgid "no system default destination\n" +msgstr "geen bestemming voor systeemstandaard\n" + +msgid "notify-events not specified!" +msgstr "notify-events niet gespecificeerd!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI \"%s\" wordt al gebruikt!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI \"%s\" gebruikt onbekend schema!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d niet goed!" + +msgid "pending" +msgstr "in bewerking" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Include-directory \"%s\" wordt toegevoegd...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Interfacetekst van %s wordt toegevoegd/bijgewerkt...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Ongeldige Booleaanse waarde (%s) in regel %d van %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ongeldige resolutienaam \"%s\" in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Ongeldig statussleutelwoord %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Ongeldige variabelevervanging ($%c) in regel %d van %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Keuze gevonden in regel %d van %s zonder optie!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Dubbele #po voor taalversie %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Verwachtte een filterdefinitie in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Verwachtte een programmanaam in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Verwachtte Booleaanse waarde in regel %d van %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Verwachtte tekenset na Font in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Verwachtte keuzecode in regel %d van %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Verwachtte keuzenaam/-tekst in regel %d van %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Verwachtte kleurvolgorde voor ColorModel in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Verwachtte kleurruimte voor ColorModel in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Verwachtte compressie voor ColorModel in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Verwachtte beperkingenreeks voor UIConstraints in regel %d van %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Verwachtte sleutelwoord voor stuurprogrammatype na DriverType in regel " +"%d van %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Verwachtte duplextype na Duplex in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Verwachtte codering na Font in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Verwachtte bestandsnaam na #po %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Verwachtte groepsnaam/-tekst in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Verwachtte include-bestandsnaam in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Verwachtte geheel getal in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Verwachtte taalversie na #po in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na FileName in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na Font in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na Manufacturer in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na MediaSize in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na ModelName in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam na PCFileName in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam/tekst na %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam/tekst na Installable in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Verwachtte naam/tekst na Resolution in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Verwachtte naam/tekst-combinatie voor ColorModel in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Verwachtte optienaam/-tekst in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Verwachtte optiesectie in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Verwachtte optietype in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: Verwachtte override-veld na Resolution in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Verwachtte reëel getal in regel %d van %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Verwachtte resolutie/materiaaltype na ColorProfile in regel %d van %" +"s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Verwachtte resolutie/materiaaltype na SimpleColorProfile in regel %d " +"van %s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Verwachtte selector na %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Verwachtte status na Font in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Verwachtte tekenreeks na Copyright in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Verwachtte tekenreeks na Version in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Verwachtte twee optienamen in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Verwachtte waarde na %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Verwachtte versie na Font in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Ongeldige #include/#po-bestandsnaam \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Ongeldige kosten voor filter in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Ongeldig leeg MIME-type voor filter in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Ongeldige lege programmanaam voor filter in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ongeldige optiesectie \"%s\" in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ongeldig optietype \"%s\" in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Bestand met stuurprogrammagegevens \"%s\" wordt geladen...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Berichten voor taalversie \"%s\" worden geladen...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Berichten worden geladen uit \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif ontbreekt aan einde van \"%s\"!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if ontbreekt in regel %d van %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Geen berichtencatalogus opgegeven voor taalversie %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" +"ppdc: Optie %s opnieuw gedefinieerd met een ander type in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Optiebeperking moet *name in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Te veel geneste #if's in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: Niet mogelijk om PPD-bestand \"%s\" aan te maken - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Niet mogelijk om uitvoerdirectory %s aan te maken: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Niet mogelijk om uitvoerpipes aan te maken: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Niet mogelijk om cupstestppd uit te voeren: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: #po-bestand %s niet gevonden in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: include-bestand \"%s\" niet gevonden in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: geen lokalisatie gevonden voor \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Niet mogelijk om lokalisatiebestand \"%s\" te laden - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Niet-gedefinieerde variabele (%s) in regel %d van %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Onbekend type stuurprogramma %s in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Onbekend duplextype \"%s\" in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Onbekende materiaalgrootte \"%s\" in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Onbekend token \"%s\" in regel %d van %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Onbekende afsluitende tekens in reëel getal \"%s\" in regel %d van %" +"s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "" +"ppdc: Niet-afgesloten tekenreeks die begint met %c in regel %d van %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: %s wordt weggeschreven...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: PPD-bestanden worden naar directory \"%s\" geschreven...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Ongeldige LanguageVersion \"%s\" in %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: PPD-bestand %s wordt genegeerd...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Niet mogelijk om reservekopie van %s te bewaren als %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "printer %s uitgeschakeld sinds %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "printer %s is niet in gebruik. ingeschakeld sinds %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "printer %s is bezig met afdrukken %s-%d. ingeschakeld sinds %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "printer %s/%s uitgeschakeld sinds %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "printer %s/%s is niet in gebruik. ingeschakeld sinds %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "printer %s/%s is bezig met afdrukken %s-%d. ingeschakeld sinds %s\n" + +msgid "processing" +msgstr "taak wordt verwerkt" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "verzoek-ID is %s-%d (%d bestand(en))\n" + +msgid "request-id uses indefinite length" +msgstr "onbepaalde lengte gebruikt voor request-id" + +msgid "scheduler is not running\n" +msgstr "taakplanner is niet actief\n" + +msgid "scheduler is running\n" +msgstr "taakplanner is actief\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "stat van %s mislukt: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\ttoon status van daemon en wachtrij\n" + +msgid "stopped" +msgstr "gestopt" + +#, c-format +msgid "system default destination: %s\n" +msgstr "bestemming voor systeemstandaard: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "bestemming voor systeemstandaard: %s/%s\n" + +msgid "unknown" +msgstr "onbekend" + +msgid "untitled" +msgstr "naamloos" + +msgid "variable-bindings uses indefinite length" +msgstr "onbepaalde lengte gebruikt voor variable-bindings" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN APDialogExtension-bestand \"%s\" ontbreekt\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN APPrinterIconPath-bestand \"%s\" ontbreekt\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Niet mogelijk om %s - %s te openen\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Niet mogelijk om %s - %s in regel %d te openen.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600-DPI grijstinten" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Ontbrekende apparaat-URI op commandoregel en geen DEVICE_URI-" +#~ "omgevingsvariabele!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Niet mogelijk om tijdelijk bestand - %s te maken.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Niet mogelijk om tijdelijk bestand te maken: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Niet mogelijk om tijdelijk bestand te openen" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops-filter vastgelopen op signaal %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops-filter gestopt met status %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Onbekende printerfout (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Gebruik: convert [ opties ]\n" +#~ "\n" +#~ "Opties:\n" +#~ "\n" +#~ " -f bestandsnaam Stel te converteren bestand in (anders stdin)\n" +#~ " -o bestandsnaam Stel te genereren bestand in (anders stdout)\n" +#~ " -i mime/type Stel MIME-type voor invoer in (anders auto-typed)\n" +#~ " -j mime/type Stel MIME-type voor uitvoer in (anders application/" +#~ "pdf)\n" +#~ " -P bestandsnaam.ppd Stel PPD-bestand in\n" +#~ " -a 'naam=waarde ...' Stel optie(s) in\n" +#~ " -U gebruikersnaam Stel gebruikersnaam voor taak in\n" +#~ " -J titel Stel titel in\n" +#~ " -c aantal Stel aantal exemplaren in\n" +#~ " -u Verwijder het PPD-bestand na conversie\n" +#~ " -D Verwijder het invoerbestand na conversie\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Gebruik: cupsfilter -m mime/type [ opties ] bestandsnaam\n" +#~ "\n" +#~ "Opties:\n" +#~ "\n" +#~ " -c cupsd.conf Stel in welk cupsd.conf-bestand moet worden gebruikt\n" +#~ " -j taak-ID[,N] Filter bestand N uit opgegeven taak (standaard is " +#~ "bestand 1)\n" +#~ " -n aantal Stel aantal exemplaren in\n" +#~ " -o naam=waarde Stel optie(s) in\n" +#~ " -p bestandsnaam.ppd Stel PPD-bestand in\n" +#~ " -t titel Stel titel in\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Gebruik: cupstestppd [opties] bestandsnaam1.ppd[.gz] [... bestandsnaamN." +#~ "ppd[.gz]]\n" +#~ " program | cupstestppd [opties] -\n" +#~ "\n" +#~ "Opties:\n" +#~ "\n" +#~ " -R root-directory Stel alternatieve root in\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Toon waarschuwingen in plaats van fouten\n" +#~ " -q Voer uit zonder meldingen\n" +#~ " -r Gebruik &aops;relaxed&aops; open modus\n" +#~ " -v Gebruik beperkte verbose-modus\n" +#~ " -vv Gebruik uitgebreide verbose-modus\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Niet mogelijk om tijdelijk bestand aan te maken: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Niet mogelijk om tijdelijk bestand aan te maken - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Niet mogelijk om tijdelijk bestand aan te maken: %s\n" diff --git a/locale/cups_no.po b/locale/cups_no.po new file mode 100644 index 0000000000..5357678791 --- /dev/null +++ b/locale/cups_no.po @@ -0,0 +1,5642 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(alle)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(ingen)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d oppføringer\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tEtter feil: fortsett\n" + +msgid "\tAlerts:" +msgstr "\tVarsling:" + +msgid "\tBanner required\n" +msgstr "\tKrever banner\n" + +msgid "\tCharset sets:\n" +msgstr "\tTegnsettsamlinger:\n" + +msgid "\tConnection: direct\n" +msgstr "\tTilkobling: direkte\n" + +msgid "\tConnection: remote\n" +msgstr "\tTilkobling: ekstern\n" + +msgid "\tDefault page size:\n" +msgstr "\tStandard sidestørrelse:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tStandard avstand:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tStandard portinnstillinger:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tBeskrivelse: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tAktivert skjema:\n" +"\tInnholdstyper: alle\n" +"\tSkrivertyper: ukjent\n" + +msgid "\tForms allowed:\n" +msgstr "\tTillatte skjemaer:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tGrensesnitt: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tGrensesnitt: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tGrensesnitt: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tPlassering: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tVed feil: ingen varsling\n" + +msgid "\tUsers allowed:\n" +msgstr "\tBrukere tillatt:\n" + +msgid "\tUsers denied:\n" +msgstr "\tBrukere avslått:\n" + +msgid "\tdaemon present\n" +msgstr "\tdaemon til stede\n" + +msgid "\tno entries\n" +msgstr "\tingen oppføringer\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tskriver er på enhet «%s», hastighet -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tutskrift er deaktivert\n" + +msgid "\tprinting is enabled\n" +msgstr "\tutskrift er aktivert\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\ti kø for %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tutskriftskø er deaktivert\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tutskriftskø er aktivert\n" + +msgid "\treason unknown\n" +msgstr "\tukjent grunn\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" DETALJERTE RESULTATER FRA SAMSVARSTEST\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Side 15, del 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Side 15, del 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Side 19, del 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Side 20, del 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Side 27, del 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Side 42, del 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Sider 16–17, del 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Sider 42–45, del 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Sider 45–46, del 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Sider 48–49, del 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Sider 52–54, del 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f byte\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN «%s %s» er i strid med «%s %s»\n" +" (constraint=«%s %s %s %s»)\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s har ingen relaterte valg!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s har samme prefiks som %s\n" +" REF: Side 15, del 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Standardinnstillinger stemmer ikke overens!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Det er mulig at dupleksvalgnøkkelordet %s ikke fungerer som " +"forventet og skal ha navnet Duplex!\n" +" REF: Side 122, del 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr " WARN Filen inneholder CR-, LF- og CR LF-linjeskift!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding kreves av PPD 4.3-spesifikasjonen.\n" +" REF: Sider 56–57, del 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Linjen %d inneholder kun mellomrom!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Manufacturer kreves av PPD 4.3-spesifikasjonen.\n" +" REF: Sider 58–59, del 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN PPD-filer som ikke er i Windows-format, bør kun bruke " +"linjeskift med LF, ikke CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Foreldet PPD-versjon %.1f!\n" +" REF: Side 42, del 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName er lengre enn 8.3, noe som er et brudd på PPD-" +"spesifikasjonen.\n" +" REF: Sider 61–62, del 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokoller inneholder PJL, men JCL-attributter er ikke " +"angitt.\n" +" REF: Sider 78–79, del 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protokoller inneholder både PJL og BCP. Forventet TBCP.\n" +" REF: Sider 78–79, del 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName kreves av PPD 4.3-spesifikasjonen.\n" +" REF: Sider 64–65, del 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s finnes ikke!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Ugyldig %s-valg %s!\n" +" REF: Side 122, del 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Ugyldig UTF-8 «%s»-oversettelsesstreng for valget %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Ugyldig UTF-8 «%s»-oversettelsesstreng for valget %s, innstillingen " +"%s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Ugyldig cupsFilter-verdi «%s»!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Ugyldig cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Ugyldig cupsPreFilter-verdi «%s»!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Ugyldig cupsUIConstraints %s: «%s»!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Ugyldig språk «%s»!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Tom cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s «%s»-oversettelsesstreng for valget %s mangler!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s «%s»-oversettelsesstreng for valget %s, innstillingen %s mangler!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Valget *%s %s i UIConstraints «*%s %s *%s %s» mangler!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Valget *%s %s i cupsUIConstraints %s mangler: «%s»!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s cupsFilter-filen «%s» mangler\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s cupsICCProfile-filen «%s» mangler!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s cupsPreFilter-filen «%s» mangler\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s cupsUIResolver %s mangler!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Valget %s i UIConstraints «*%s %s *%s %s» mangler!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Valget %s i cupsUIConstraints %s mangler: «%s»!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Filen inneholder ingen grunnoversettelse «%s»!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s OBLIGATORISK %s definerer ikke innstillingen Ingen!\n" +" REF: Side 122, del 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s-hashverdi er i konflikt med %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s forårsaker en sløyfe!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FEIL** Den eneste forskjellen mellom %s-valgnavnene %s og %s er " +"store og små bokstaver!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FEIL** %s må være 1284DeviceID!\n" +" REF: Side 72, del 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FEIL** UGYLDIG Default%s %s\n" +" REF: Side 40, del 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEIL** UGYLDIG DefaultImageableArea %s!\n" +" REF: Side 102, del 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEIL** UGYLDIG DefaultPaperDimension %s!\n" +" REF: Side 103, del 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FEIL** UGYLDIG JobPatchFile-attributt i fil\n" +" REF: Side 24, del 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FEIL** UGYLDIG Manufacturer (skal være «HP»)\n" +" REF: Side 211, tabell D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FEIL** UGYLDIG Manufacturer (skal være «Oki»)\n" +" REF: Side 211, tabell D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FEIL** UGYLDIG ModelName – «%c» er ikke tillatt i strengen.\n" +" REF: Sider 59–60, del 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FEIL** UGYLDIG PSVersion – er ikke «(string) int».\n" +" REF: Sider 62–64, del 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FEIL** UGYLDIG Product – er ikke «(string)».\n" +" REF: Side 62, del 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FEIL** UGYLDIG ShortNickName – mer enn 31 tegn.\n" +" REF: Sider 64–65, del 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FEIL** Ugyldig %s-valg %s!\n" +" REF: Side 84, del 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEIL** Ugyldig FileVersion «%s»\n" +" REF: Side 56, del 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEIL** Ugyldig FormatVersion «%s»\n" +" REF: Side 56, del 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FEIL** Ugyldig LanguageEncoding %s – må være ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FEIL** Ugyldig LanguageVersion %s – må være English!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **FEIL** Kan ikke tolke standard valgkode: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FEIL** Standard oversettelsesstreng for valget %s, innstillingen %s " +"inneholder 8-bitstegn!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FEIL** Standard oversettelsesstreng for valget %s inneholder 8-" +"bitstegn!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FEIL** Den eneste forskjellen mellom gruppenavnene %s og %s er " +"store og små bokstaver!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FEIL** Flere forekomster av %s-valgnavnet %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FEIL** Den eneste forskjellen mellom valgnavnene %s og %s er store " +"og små bokstaver!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FEIL** OBLIGATORISK Default%s\n" +" REF: Side 40, del 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEIL** OBLIGATORISK DefaultImageableArea\n" +" REF: Side 102, del 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEIL** OBLIGATORISK DefaultPaperDimension\n" +" REF: Side 103, del 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK FileVersion\n" +" REF: Side 56, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK FormatVersion\n" +" REF: Side 56, del 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEIL** OBLIGATORISK ImageableArea for PageSize %s\n" +" REF: Side 41, del 5.\n" +" REF: Side 102, del 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK LanguageEncoding\n" +" REF: Sider 56–57, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK LanguageVersion\n" +" REF: Sider 57–58, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK Manufacturer\n" +" REF: Sider 58–59, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK ModelName\n" +" REF: Sider 59–60, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK NickName\n" +" REF: Side 60, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK PCFileName\n" +" REF: Sider 61–62, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK PSVersion\n" +" REF: Sider 62–64, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FEIL** OBLIGATORISK PageRegion\n" +" REF: Side 100, del 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FEIL** OBLIGATORISK PageSize\n" +" REF: Side 41, del 5.\n" +" REF: Side 99, del 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FEIL** OBLIGATORISK PageSize\n" +" REF: Sider 99–100, del 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEIL** OBLIGATORISK PaperDimension for PageSize %s\n" +" REF: Side 41, del 5.\n" +" REF: Side 103, del 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK Product\n" +" REF: Side 62, del 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FEIL** OBLIGATORISK ShortNickName\n" +" REF: Sider 64–65, del 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " FANT %d FEIL\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Ugyldig %%%%BoundingBox: på linje %d!\n" +" REF: Side 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Ugyldig %%%%Page: på linje %d!\n" +" REF: Side 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Ugyldig %%%%Pages: på linje %d!\n" +" REF: Side 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Linje %d inneholder mer enn 255 tegn (%d)!\n" +" REF: Side 25, Line Length\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 mangler på første linje!\n" +" REF: Side 17, 3.1 Conforming Documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" %%EndComments-kommentar mangler!\n" +" REF: Side 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox:-kommentar mangler eller er ugyldig!\n" +" REF: Side 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page-kommentarer mangler eller er ugyldig!\n" +" REF: Side 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages-kommentar mangler eller er ugyldig!\n" +" REF: Side 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " FANT INGEN FEIL\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Fant %d linjer som er lengre enn 255 tegn!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " For mange %%BeginDocument-kommentarer!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " For mange %%EndDocument-kommentarer!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Advarsel: filen inneholder binærdata!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Advarsel: ingen %%EndComments-kommentar i fil!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Advarsel: foreldet DSC-versjon %.1f i fil!\n" + +msgid " FAIL\n" +msgstr " FEIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FEIL\n" +" **FEIL** Kan ikke åpne PPD-fil – %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FEIL\n" +" **FEIL** Kan ikke åpne PPD-fil – %s på linje %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10-konvolutt" + +msgid "#11 Envelope" +msgstr "#11-konvolutt" + +msgid "#12 Envelope" +msgstr "#12-konvolutt" + +msgid "#14 Envelope" +msgstr "#14-konvolutt" + +msgid "#9 Envelope" +msgstr "#9-konvolutt" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f byte\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f byte\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f millimeter" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f til %.0f x %.0f millimeter" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f tommer" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f til %.2f x %.2f tommer" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s mottar forespørsler siden %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s kan ikke endres." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s er ikke implementert av CUPS-versjonen av lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s er ikke klar\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s er klar\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s er klar og skriver ut\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s mottar ikke forespørsler siden %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s støttes ikke!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s mottar forespørsler siden %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s mottar ikke forespørsler siden %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [jobb %d lokal vert]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s mislyktes: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Vet ikke hva som skal gjøres!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: Feil – %s-miljøvariabel oppgir målet «%s» som ikke eksisterer!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Feil – ugyldig jobb-ID!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s: Feil – kan ikke skrive ut filer og endre jobber samtidig!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Feil – kan ikke skrive ut fra stdin hvis det er oppgitt filer eller en " +"jobb-ID!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Feil – forventet tegnsett etter «-S»-valg!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Feil – forventet innholdstype etter «-T»-valg!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Feil – forventet eksemplarer etter «-n»-valg!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Feil – forventet antall eksemplarer etter «-#»-valg!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Feil – forventet mål etter «-P»-valg!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Feil – forventet mål etter «-b»-valg!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Feil – forventet mål etter «-d»-valg!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Feil – forventet skjema etter «-f»-valg!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Feil – forventet holdnavn etter «-H»-valg!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Feil – forventet vertsnavn etter «-H»-valg!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Feil – forventet vertsnavn etter «-h»-valg!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Feil – forventet modusliste etter «-y»-valg!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Feil – forventet navn etter «%c»-valg!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Feil – forventet valgstreng etter «-o»-valg!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Feil – forventet sideliste etter «-P»-valg!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Feil – forventet prioritet etter «%c»-valg!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Feil – forventet begrunnelsestekst etter «-r»-valg!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Feil – forventet tittel etter «-t»-valg!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Feil – forventet brukernavn etter «-U»-valg!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Feil – forventet brukernavn etter «-u»-valg!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Feil – forventet verdi etter «%c»-valg!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Feil – trenger «completed», «not-completed» eller «all» etter «-W»-valg!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Feil – ingen standardmål tilgjengelig.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Feil – prioritet må være mellom 1 og 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Feil – planlegger svarer ikke!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Feil – for mange filer – «%s»\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Feil – får ikke tilgang til «%s» – %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Feil – kan ikke legge i kø fra stdin – %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Feil – ukjent mål «%s»!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Feil – ukjent mål «%s/%s»!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Feil – ukjent valg «%c»!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Feil – ukjent valg «%s»!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Forventet jobb-ID etter «-i»-valg!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filteret «%s» er ikke tilgjengelig: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Ugyldig målnavn i liste «%s»!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Ugyldig filterstreng «%s»\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Trenger jobb-ID («-i jobid») før «-H restart»!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Mangler filter for å konvertere fra %s/%s til %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Handling mislyktes: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Støtte for kryptering er ikke kompilert inn!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Kan ikke koble til tjener\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Får ikke kontakt med tjener!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Kan ikke bestemme MIME-typen til «%s»!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Kan ikke åpne %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Kan ikke åpne PDF-fil: %s på linje %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Kan ikke lese MIME-database fra «%s» eller «%s»!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Ukjent mål «%s»!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Ukjent MIME-type for mål %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Ukjent valg «%c»!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Ukjent kilde-MIME-type for mål %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Advarsel «%c»-formatmodifikator støttes ikke – det er mulig at utdata " +"ikke er korrekt!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Advarsel – ignorerte tegnsettvalg!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Advarsel – ignorerte innholdstypevalg!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Advarsel – ignorerte skjemavalg!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Advarsel – ignorerte modusvalg!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: feil – %s-miljøvariabel oppgir målet «%s» som ikke eksisterer!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: feil – forventet option=value etter «-o»-valg!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: feil – ingen standardmål tilgjengelig.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 tomme/sek" + +msgid "1.25x0.25\"" +msgstr "1,25 x 0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25 x 2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 tommer/sek" + +msgid "1.50x0.25\"" +msgstr "1,50 x 0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50 x 0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50 x 1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50 x 2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 tommer/sek" + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/sek" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 tommer/sek" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 tommer/sek" + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/sek" + +msgid "120x60dpi" +msgstr "120 x 60 dpi" + +msgid "120x72dpi" +msgstr "120 x 72 dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/sek" + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/sek" + +msgid "150dpi" +msgstr "150 dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 tommer/sek" + +msgid "2-Sided Printing" +msgstr "Tosidig utskrift" + +msgid "2.00x0.37\"" +msgstr "2,00 x 0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00 x 0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00 x 1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00 x 1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00 x 2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00 x 3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00 x 4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00 x 5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25 x 0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25 x 1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25 x 4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25 x 5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38 x 5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 tommer/sek" + +msgid "2.50x1.00\"" +msgstr "2,50 x 1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50 x 2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75 x 1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/sek" + +msgid "200 mm/sec." +msgstr "200 mm/sek" + +msgid "203dpi" +msgstr "203 dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-pinners serie" + +msgid "240x72dpi" +msgstr "240 x 72 dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/sek" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 tommer/sek" + +msgid "3.00x1.00\"" +msgstr "3,00 x 1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00 x 1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00 x 2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00 x 3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00 x 5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25 x 2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25 x 5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25 x 5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25 x 5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25 x 7,83\"" + +msgid "3.5\" Disk" +msgstr "3,5-tommers disk" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3,5-tommers disk – 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50 x 1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/sek" + +msgid "300 mm/sec." +msgstr "300 mm/sek" + +msgid "300dpi" +msgstr "300 dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 dpi" + +msgid "360x180dpi" +msgstr "360 x 180 dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 tommer/sek" + +msgid "4.00x1.00\"" +msgstr "4,00 x 1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00 x 13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00 x 2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00 x 2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00 x 3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00 x 4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00 x 5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00 x 6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00 x 6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/sek" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 tommer/sek" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 tommer/sek" + +msgid "6.00x1.00\"" +msgstr "6,00 x 1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00 x 2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00 x 3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00 x 4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00 x 5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00 x 6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00 x 6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/sek" + +msgid "600dpi" +msgstr "600 dpi" + +msgid "60dpi" +msgstr "60 dpi" + +msgid "60x720dpi" +msgstr "60 x 720 dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 tommer/sek" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 tommer/sek" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00 x 1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00 x 2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00 x 3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00 x 4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00 x 5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00 x 6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00 x 6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/sek" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 tommer/sek" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9-pinners serie" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Ugyldig hjelpekommando ukjent\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Et Samba-passord kreves for å eksportere skriverdrivere!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "Et Samba-brukernavn kreves for å eksportere skriverdrivere!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Det finnes allerede en klasse med navnet «%s»!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Det finnes allerede en skriver med navnet «%s»!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (overdimensjonert)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (overdimensjonert)" + +msgid "A4 (Small)" +msgstr "A4 (lite)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (overdimensjonert)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Motta jobber" + +msgid "Accepted" +msgstr "Mottatt" + +msgid "Add Class" +msgstr "Legg til klasse" + +msgid "Add Printer" +msgstr "Legg til skriver" + +msgid "Add RSS Subscription" +msgstr "Legg til RSS-abonnement" + +msgid "Address" +msgstr "Adresse" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adresse – 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administrering" + +msgid "Always" +msgstr "Alltid" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applikator" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Prøv å sette %s printer-state til den ugyldige verdien %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Attributtgrupper er ikke i rekkefølge (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Ugyldig NULL-målpeker" + +msgid "Bad OpenGroup" +msgstr "Ugyldig OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Ugyldig ad OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Ugyldig OrderDependency" + +msgid "Bad Request" +msgstr "Ugyldig forespørsel" + +msgid "Bad SNMP version number" +msgstr "Ugyldig SNMP-versjonsnummer" + +msgid "Bad UIConstraints" +msgstr "Ugyldig UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Ugyldig kopiverdi %d." + +msgid "Bad custom parameter" +msgstr "Ugyldig, tilpasset parameter" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Ugyldig device-URI «%s»!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Ugyldig device-uri «%s»!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Ugyldig device-uri-oppsett «%s»!\n" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Ugyldig document-format «%s»!" + +msgid "Bad filename buffer!" +msgstr "Ugyldig filnavnbuffer!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Ugyldig fontattributt: %s\n" + +msgid "Bad job-priority value!" +msgstr "Ugyldig job-priority-verdi!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Ugyldig job-sheets-verdi «%s»!" + +msgid "Bad job-sheets value type!" +msgstr "Ugyldig job-sheets-verditype!" + +msgid "Bad job-state value!" +msgstr "Ugyldig job-state-verdi!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Ugyldig job-uri-attributt «%s»!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Ugyldig notify-pull-method «%s»!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Ugyldig notify-recipient-uri-URI «%s»!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Ugyldig number-up-verdi %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Ugyldig valg og alternativ på linje %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Ugyldig page-ranges-verdier %d–%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Ugyldig port-monitor «%s»!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Ugyldig printer-state-verdi %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Ugyldig versjonsnummer for forespørsel %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Ugyldig abonnements-ID!" + +msgid "Banners" +msgstr "Bannere" + +msgid "Billing Information: " +msgstr "Faktureringsinformasjon: " + +msgid "Bond Paper" +msgstr "Tykt papir" + +msgid "C0 Envelope" +msgstr "C0-konvolutt" + +msgid "C1 Envelope" +msgstr "C1-konvolutt" + +msgid "C2 Envelope" +msgstr "C2-konvolutt" + +msgid "C3 Envelope" +msgstr "C3-konvolutt" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4-konvolutt" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5-konvolutt" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6-konvolutt" + +msgid "C65 Envelope" +msgstr "C65-konvolutt" + +msgid "C7 Envelope" +msgstr "C7-konvolutt" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL-etikettskriver" + +msgid "Cancel RSS Subscription" +msgstr "Avbryt RSS-abonnement" + +msgid "Change Settings" +msgstr "Endre innstillinger" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Tegnsett «%s» støttes ikke!" + +msgid "Chou3 Envelope" +msgstr "Chou3-konvolutt" + +msgid "Chou4 Envelope" +msgstr "Chou4-konvolutt" + +msgid "Classes" +msgstr "Klasser" + +msgid "Clean Print Heads" +msgstr "Rengjør skrivehoder" + +msgid "Color" +msgstr "Farge" + +msgid "Color Mode" +msgstr "Fargemodus" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Kommandoer kan være forkortet. Kommandoer er :\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Gruppenavn bruker uendelig lengde" + +msgid "Continue" +msgstr "Fortsett" + +msgid "Continuous" +msgstr "Kontinuerlig" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Kunne ikke skanne type «%s»!" + +msgid "Cover open." +msgstr "Deksel åpent." + +msgid "Created" +msgstr "Opprettet" + +msgid "Created On: " +msgstr "Opprettet på: " + +msgid "Custom" +msgstr "Tilpasset" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Klipp" + +msgid "Cutter" +msgstr "Kutter" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL-konvolutt" + +msgid "Dark" +msgstr "Mørk" + +msgid "Darkness" +msgstr "Mørkhet" + +msgid "Delete Class" +msgstr "Slett klasse" + +msgid "Delete Printer" +msgstr "Slett skriver" + +msgid "Description: " +msgstr "Beskrivelse: " + +msgid "DeskJet Series" +msgstr "DeskJet-serie" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Målet «%s» mottar ikke jobber." + +msgid "Developer almost empty." +msgstr "Fremkaller nesten tom." + +msgid "Developer empty!" +msgstr "Fremkaller tom!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Enhet: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Direkte varme-medium" + +msgid "Disabled" +msgstr "Deaktivert" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Fant ikke dokumentet %d i jobben %d." + +msgid "Door open." +msgstr "Dør åpen." + +msgid "Double Postcard" +msgstr "Dobbelt postkort" + +msgid "Driver Name: " +msgstr "Drivernavn: " + +msgid "Driver Version: " +msgstr "Driverversjon: " + +msgid "Duplexer" +msgstr "Duplekser" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Kan ikke tildele hukommelse for sideinfo: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Kan ikke tildele hukommelse for sidesett: %s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1-etikettskriver" + +msgid "EPL2 Label Printer" +msgstr "EPL2-etikettskriver" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Fant ugyldig %%BoundingBox:-kommentar!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Ugyldig %%IncludeFeature:-kommentar!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Ugyldig %%Page:-kommentar i fil!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Ugyldig %%PageBoundingBox:-kommentar i fil!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Ugyldig SCSI-enhetsfil «%s»!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Ugyldig tegnsettfil %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Ugyldig tegnsettype %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Ugyldig kolonneverdi %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Ugyldig cpi-verdi %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Ugyldig fontbeskrivelseslinje: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Ugyldig lpi-verdi %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Ugyldig sideoppsett!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Ugyldig tekstretning %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Ugyldig tekstbredde %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Målskriver finnes ikke!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Fant duplisert %%BoundingBox:-kommentar!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Fant duplisert %%Pages:-kommentar!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Tom utskriftsfil!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Feil %d ved sending av PAPSendData-forespørsel: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: Forventet streng i anførselstegn på linje %d av %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Kritisk USB-feil!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: Fant ugyldig HP-GL/2-kommando, kan ikke skrive ut fil!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog mangler!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup mangler!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Mangler verdi på linje %d i bannerfil!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Krever en msgid-linje før oversettelsesstreng på linje %d av %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Ingen %%BoundingBox:-kommentar i header!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Ingen %%Pages:-kommentar i header!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Fant ingen enhets-URI i argv[0] eller i DEVICE_URI-miljøvariabel!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Ingen fonter i tegnsettfil %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Fant ingen sider!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Tom for papir!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER-miljøvariabel er ikke definert!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Utskriftsfil ble ikke akseptert (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Skriver svarer ikke\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Skriver svarer ikke!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Skriver sendte uventet EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Ekstern vert godtok ikke kontrollfil (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Ekstern vert godtok ikke datafil (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Det oppsto en tidsavbruddfeil under sending av data til skriveren\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Kan ikke legge til filen %d i jobb: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Kan ikke avbryte jobb %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Kan ikke kopiere PDF-fil" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Kan ikke opprette socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: Kan ikke opprette midlertidig, komprimert utskriftsfil: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Kan ikke opprette midlertidig fil" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Kan ikke utføre pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Kan ikke utføre gs-program" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Kan ikke utføre pdftops-program" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Kan ikke forgrene pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Kan ikke hente PAP-forespørsel" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Kan ikke hente PAP-svar" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: Kan ikke hente PPD-fil for skriveren «%s» – %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Kan ikke hente standard AppleTalk-sone" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Kan ikke hente %d-attributter for jobb (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Kan ikke hente skriverstatus (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Finner ikke skriveren «%s»!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Kan ikke søke etter PAP-svar" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Kan ikke søke etter AppleTalk-skrivere" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Kan ikke lage AppleTalk-adresse" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Kan ikke åpne «%s» – %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Kan ikke åpne %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Kan ikke åpne bannerfilen «%s» – %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Kan ikke åpne enhetsfilen «%s»: %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Kan ikke åpne filen «%s» – %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Kan ikke åpne filen «%s»: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Kan ikke åpne bildefil for utskrift!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Kan ikke åpne utskriftsfilen «%s»: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Kan ikke åpne utskriftsfilen %s – %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Kan ikke åpne utskriftsfilen %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: Kan ikke åpne midlertidig, komprimert utskriftsfil: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Kan ikke skrive ut %d tekstkolonner!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Kan ikke skrive ut %d x %d tekstside!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Kan ikke lese utskriftsdata" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Kan ikke lese utskriftsdata!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Kan ikke reservere port" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Kan ikke søke for å forskyve %ld i fil – %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Kan ikke søke for å forskyve %lld i fil – %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Kan ikke sende LPD-kommando" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Kan ikke sende PAP-tickleforespørsel" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Kan ikke sende innledende PAP-forespørsel om sending av data" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Kan ikke sende utskriftsdata (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Kan ikke sende utskriftsdata!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Kan ikke sende utskriftsfil til skriver" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: Kan ikke sende «trailing nul» til skriver" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Kan ikke vente på pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Kan ikke skrive %d byte til «%s»: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Kan ikke skrive %d byte til skriver!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Kan ikke skrive kontrollfil" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Kan ikke skrive utskriftsdata" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Kan ikke skrive utskriftsdata: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Kan ikke skrive rasterdata til driver!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Kan ikke skrive til midlertidig fil " + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: Kan ikke skrive ukomprimert dokumentdata: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Uventet tekst på linje %d av %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Ukjent krypteringsvalgverdi «%s»!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Ukjent filrekkefølge «%s»\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Ukjent formattegn «%c»\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Ukjent meldingskatalogformat for «%s»!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Ukjent valg «%s» med verdien «%s»!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Ukjent utskriftsmodus «%s»\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Ukjent versjonsvalgverdi «%s»!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Lysstyrkeverdien %s støttes ikke, bruker brightness=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Gammaverdien %s støttes ikke, bruker gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Number-up-verdien %d støttes ikke, bruker number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Number-up-layout-verdien %s støttes ikke, bruker number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: Page-border-verdien %s støttes ikke, bruker page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: fant doc_printf-overflyt (%d byte), avbryter!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops avsluttet på signalet %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops avsluttet med statusen %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: gjenopprettbar: Kan ikke koble til skriver. Prøver på nytt om 30 " +"sekunder...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() mislyktes" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: kan ikke statte utskriftsfilen" + +msgid "Edit Configuration File" +msgstr "Rediger konfigurasjonsfil" + +msgid "Empty PPD file!" +msgstr "Tom PPD-fil!" + +msgid "Ending Banner" +msgstr "Sluttbanner" + +msgid "Enter old password:" +msgstr "Oppgi det gamle passordet:" + +msgid "Enter password again:" +msgstr "Oppgi passordet igjen:" + +msgid "Enter password:" +msgstr "Oppgi passordet:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Oppgi brukernavnet og passordet ditt eller rotbrukernavnet og -passordet for " +"å få tilgang til denne siden. Hvis du bruker Kerberos-godkjenning, forsikrer " +"du deg om at du har en gyldig Kerberos-billett." + +msgid "Envelope Feed" +msgstr "Konvoluttmating" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Feilkriterier" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Feil: krever vertsnavn etter «-h»-valg!\n" + +msgid "Every 10 Labels" +msgstr "Hver 10. etikett" + +msgid "Every 2 Labels" +msgstr "Hver 2. etikett" + +msgid "Every 3 Labels" +msgstr "Hver 3. etikett" + +msgid "Every 4 Labels" +msgstr "Hver 4. etikett" + +msgid "Every 5 Labels" +msgstr "Hver 5. etikett" + +msgid "Every 6 Labels" +msgstr "Hver 6. etikett" + +msgid "Every 7 Labels" +msgstr "Hver 7. etikett" + +msgid "Every 8 Labels" +msgstr "Hver 8. etikett" + +msgid "Every 9 Labels" +msgstr "Hver 9. etikett" + +msgid "Every Label" +msgstr "Hver etikett" + +msgid "Expectation Failed" +msgstr "Forventning mislyktes" + +msgid "Export Printers to Samba" +msgstr "Eksporter skrivere til Samba" + +msgid "FAIL\n" +msgstr "FEIL\n" + +msgid "File Folder" +msgstr "Filmappe" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Filmappe – 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Enhets-URIer for filer er deaktivert! Hvis du vil aktivere funksjonen, leser " +"du FileDevice-direktivet i «%s/cupsd.conf»." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Forbudt" + +msgid "Fuser temperature high!" +msgstr "Fikseringsenhetens temperatur er høy!" + +msgid "Fuser temperature low!" +msgstr "Fikseringsenhetens temperatur er lav!" + +msgid "General" +msgstr "Generelt" + +msgid "Generic" +msgstr "Generisk" + +msgid "German FanFold" +msgstr "Tysk FanFold" + +msgid "German FanFold Legal" +msgstr "Tysk FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU bruker uendelig lengde" + +msgid "Glossy Paper" +msgstr "Glanset papir" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Fikk et printer-uri-attributt, men ingen jobb-ID!" + +msgid "Grayscale" +msgstr "Gråskala" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Hengende mappe" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Hengende mappe – 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk deaktivert i Systemvalg\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk deaktivert i Systemvalg.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Avbryter utskriftsjobb...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Koblet til skriver...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Kobler til skriver...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Kontrollfil sendt\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Datafil sendt\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Formaterer side %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Laster inn bildefil...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Søker etter skriver...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Åpner forbindelse\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Utskriftsfil sendt, venter på at skriveren skal bli ferdig...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Skriveren er opptatt. Prøver på nytt om 10 sekunder...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Skriveren er opptatt. Prøver på nytt om 30 sekunder...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Skriveren er opptatt. Prøver på nytt om 5 sekunder...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: Skriveren støtter ikke IPP/%d.%d, prøver IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Skriveren er opptatt. Prøver på nytt om 5 sekunder...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Skriveren er ikke tilgjengelig.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Skriveren er ikke tilgjengelig.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Skriveren er tilgjengelig.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Skriveren er ikke tilgjengelig.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "" +"INFO: Skriveren er ikke tilgjengelig. Prøver på nytt om 30 sekunder...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Skriver ut side %d, %d%% fullført...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Skriver ut side %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Klar til utskrift.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Sender kontrollfil (%lu byte)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Sender kontrollfil (%u byte)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Sender data\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Sender datafil (%ld byte)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Sender datafil (%lld byte)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Sender utskriftsdata...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Utskriftsfil sendt, %ld byte...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Utskriftsfil sendt, %lld byte...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Legger LPR-jobb i utskriftskø, %.0f%% fullført...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Får ikke kontakt med skriver, legger i kø på neste skriver i " +"klassen...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Bruker standard AppleTalk-sone «%s»\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Venter på at jobben skal bli ferdig...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Venter på at skriveren skal bli tilgjengelig...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4-konvolutt" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (overdimensjonert)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5-konvolutt" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6-konvolutt" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Ulovlig kontrolltegn" + +msgid "Illegal main keyword string" +msgstr "Ulovlig streng for hovednøkkelord" + +msgid "Illegal option keyword string" +msgstr "Ulovlig streng for valgnøkkelord" + +msgid "Illegal translation string" +msgstr "Ulovlig oversettelsesstreng" + +msgid "Illegal whitespace character" +msgstr "Ulovlig mellomromstegn" + +msgid "Ink/toner almost empty." +msgstr "Blekk/toner nesten tom." + +msgid "Ink/toner empty!" +msgstr "Blekk/toner tom!" + +msgid "Ink/toner waste bin almost full." +msgstr "Avfallsbeholder for blekk/toner nesten full." + +msgid "Ink/toner waste bin full!" +msgstr "Avfallsbeholder for blekk/toner full!" + +msgid "Installable Options" +msgstr "Installerbare valg" + +msgid "Installed" +msgstr "Installert" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar-etikettskriver" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Sikkerhetsenhet åpen." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Intern feil" + +msgid "Internet Postage 2-Part" +msgstr "Internet Postage 2 deler" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet Postage 2 deler – 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Internet Postage 3 deler" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet Postage 3 deler – 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internett-utskriftsprotokoll" + +msgid "Invite Envelope" +msgstr "Invitasjonskonvolutt" + +msgid "Italian Envelope" +msgstr "Italiensk konvolutt" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Kan ikke starte jobb nr. %d på nytt – ingen filer!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Jobb nr. %d finnes ikke!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Jobb nr. %d er allerede kansellert – kan ikke avbryte." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Jobb nr. %d er allerede avbrutt – kan ikke avbryte." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Jobb nr. %d er allerede fullført – kan ikke avbryte." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Jobb nr. %d er fullført og kan ikke endres!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Jobb nr. %d er ikke fullført!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Jobb nr. %d holdes ikke for godkjenning!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Jobb nr. %d holdes ikke!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Jobben #%s finnes ikke!" + +#, c-format +msgid "Job %d not found!" +msgstr "Fant ikke jobben %d!" + +msgid "Job Completed" +msgstr "Jobb fullført" + +msgid "Job Created" +msgstr "Jobb opprettet" + +msgid "Job ID: " +msgstr "Jobb-ID: " + +msgid "Job Options Changed" +msgstr "Jobbvalg endret" + +msgid "Job Stopped" +msgstr "Jobb stoppet" + +msgid "Job UUID: " +msgstr "Jobb-UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "Jobben er fullført og kan ikke endres." + +msgid "Job operation failed:" +msgstr "Jobbhandling mislyktes:" + +msgid "Job state cannot be changed." +msgstr "Jobbstatus kan ikke endres." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Jobbabonnementer kan ikke fornyes!" + +msgid "Jobs" +msgstr "Jobber" + +msgid "Kaku2 Envelope" +msgstr "Kaku2-konvolutt" + +msgid "Kaku3 Envelope" +msgstr "Kaku3-konvolutt" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR-vert eller -skriver" + +msgid "Label Printer" +msgstr "Etikettskriver" + +msgid "Label Top" +msgstr "Etikettopp" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Språket «%s» støttes ikke!" + +msgid "Large Address" +msgstr "Stor adresse" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Stor adresse – 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet-serie PCL 4/5" + +msgid "Light" +msgstr "Lys" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Linjen er lengre enn det som er tillatt (255 tegn)" + +msgid "List Available Printers" +msgstr "Vis tilgjengelige skrivere" + +msgid "Location: " +msgstr "Plassering: " + +msgid "Long-Edge (Portrait)" +msgstr "Langside (stående)" + +msgid "Make and Model: " +msgstr "Merke og modell: " + +msgid "Manual Feed" +msgstr "Manuell mating" + +msgid "Media Dimensions: " +msgstr "Mediestørrelse: " + +msgid "Media Limits: " +msgstr "Mediebegrensninger: " + +msgid "Media Name: " +msgstr "Medienavn: " + +msgid "Media Size" +msgstr "Papirstørrelse" + +msgid "Media Source" +msgstr "Papirkilde" + +msgid "Media Tracking" +msgstr "Mediesporing" + +msgid "Media Type" +msgstr "Papirtype" + +msgid "Media jam!" +msgstr "Papirstopp!" + +msgid "Media tray almost empty." +msgstr "Arkskuff nesten tom." + +msgid "Media tray empty!" +msgstr "Arkskuff tom!" + +msgid "Media tray missing!" +msgstr "Arkskuff mangler!" + +msgid "Media tray needs to be filled." +msgstr "Arkskuffen må fylles." + +msgid "Medium" +msgstr "Medium" + +msgid "Memory allocation error" +msgstr "Feil med hukommelsestildeling" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "PPD-Adobe-4.x-header mangler" + +msgid "Missing asterisk in column 1" +msgstr "Stjerne mangler i kolonne 1" + +msgid "Missing document-number attribute!" +msgstr "document-number-attributt mangler!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Dobbelt anførselstegn mangler på linje %d!" + +msgid "Missing form variable!" +msgstr "Skjemavariabel mangler!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Notify-subscription-ids-attributt mangler!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Requesting-user-name-attributt mangler!" + +msgid "Missing required attributes!" +msgstr "Nødvendige attributter mangler!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Verdi mangler på linje %d!" + +msgid "Missing value string" +msgstr "Verdistreng mangler" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modell: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Endre klasse" + +msgid "Modify Printer" +msgstr "Endre skriver" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch-konvolutt" + +msgid "Move All Jobs" +msgstr "Flytt alle jobber" + +msgid "Move Job" +msgstr "Flytt jobb" + +msgid "Moved Permanently" +msgstr "Flyttet permanent" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Utskriftsfil godtatt – jobb-ID %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Utskriftsfil godtatt – jobb-ID ukjent.\n" + +msgid "NULL PPD file pointer" +msgstr "NULL PPD-filpeker" + +msgid "Name OID uses indefinite length" +msgstr "Navn-OID bruker uendelig lengde" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Aldri" + +msgid "New Stylus Color Series" +msgstr "Ny Stylus Color-serie" + +msgid "New Stylus Photo Series" +msgstr "Ny Stylus Photo-serie" + +msgid "No" +msgstr "Nei" + +msgid "No Content" +msgstr "Uten innhold" + +msgid "No PPD name!" +msgstr "Uten PPD-navn!" + +msgid "No VarBind SEQUENCE" +msgstr "Ingen VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Ingen Windows-skriverdrivere er installert!" + +msgid "No active connection" +msgstr "Ingen aktive tilkoblinger" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Ingen aktive jobber på %s!" + +msgid "No attributes in request!" +msgstr "Ingen attributter i forespørsel!" + +msgid "No authentication information provided!" +msgstr "Ingen godkjenningsinformasjon oppgitt!" + +msgid "No community name" +msgstr "Ingen gruppenavn" + +msgid "No default printer" +msgstr "Ingen standardskriver" + +msgid "No destinations added." +msgstr "Ingen mål lagt til." + +msgid "No error-index" +msgstr "Ingen error-index" + +msgid "No error-status" +msgstr "Ingen error-status" + +msgid "No file!?!" +msgstr "Ingen fil!?!" + +msgid "No modification time!" +msgstr "Uten endringstidspunkt!" + +msgid "No name OID" +msgstr "Uten navn-OID" + +msgid "No printer name!" +msgstr "Ingen skrivernavn!" + +msgid "No printer-uri found for class!" +msgstr "Fant ikke printer-uri for klasse!" + +msgid "No printer-uri found!" +msgstr "Fant ikke printer-uri!" + +msgid "No printer-uri in request!" +msgstr "Ingen printer-uri i forespørsel!" + +msgid "No request-id" +msgstr "Ingen request-id" + +msgid "No subscription attributes in request!" +msgstr "Ingen abonnementsattributter i forespørsel!" + +msgid "No subscriptions found." +msgstr "Fant ingen abonnementer." + +msgid "No variable-bindings SEQUENCE" +msgstr "Ingen variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "Uten versjonsnummer" + +msgid "Non-continuous (Mark sensing)" +msgstr "Ikke fortløpende (merkeregistrering)" + +msgid "Non-continuous (Web sensing)" +msgstr "Ikke fortløpende (webregistrering)" + +msgid "Normal" +msgstr "Vanlig" + +msgid "Not Found" +msgstr "Ikke funnet" + +msgid "Not Implemented" +msgstr "Ikke implementert" + +msgid "Not Installed" +msgstr "Ikke installert" + +msgid "Not Modified" +msgstr "Ikke modifisert" + +msgid "Not Supported" +msgstr "Ikke støttet" + +msgid "Not allowed to print." +msgstr "Utskrift ikke tillatt." + +msgid "Note" +msgstr "Merk" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC er nesten oppbrukt." + +msgid "OPC at end-of-life!" +msgstr "OPC oppbrukt!" + +msgid "Off (1-Sided)" +msgstr "Av (énsidig)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Internett-basert hjelp" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "Åpning av %s mislyktes: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup uten CloseGroup først" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI uten CloseUI/JCLCloseUI først" + +msgid "Operation Policy" +msgstr "Handlingskriterier" + +msgid "Options Installed" +msgstr "Valg installert" + +msgid "Options: " +msgstr "Valg: " + +msgid "Out of toner!" +msgstr "Tomt for toner!" + +msgid "Output Mode" +msgstr "Utdatamodus" + +msgid "Output bin almost full." +msgstr "Ut-beholder nesten full." + +msgid "Output bin full!" +msgstr "Ut-beholder full!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Utdata for skriveren %s er sendt til %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Utdata for skriveren %s er sendt til den eksterne skriveren %s på %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Utdata for skriveren %s/%s er sendt til %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"Utdata for skriveren %s/%s er sendt til den eksterne skriveren %s på %s\n" + +msgid "Output tray missing!" +msgstr "Utmatingsbrett mangler!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "PCL-laserskriver" + +msgid "PRC1 Envelope" +msgstr "PRC1-konvolutt" + +msgid "PRC10 Envelope" +msgstr "PRC10-konvolutt" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2-konvolutt" + +msgid "PRC3 Envelope" +msgstr "PRC3-konvolutt" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (overdimensjonert)" + +msgid "PRC4 Envelope" +msgstr "PRC4-konvolutt" + +msgid "PRC5 Envelope" +msgstr "PRC5-konvolutt" + +msgid "PRC6 Envelope" +msgstr "PRC6-konvolutt" + +msgid "PRC7 Envelope" +msgstr "PRC7-konvolutt" + +msgid "PRC8 Envelope" +msgstr "PRC8-konvolutt" + +msgid "PRC9 Envelope" +msgstr "PRC9-konvolutt" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Pakken inneholder ikke en Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Pakken begynner ikke med SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Passord for %s på %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Passord for %s kreves for å få tilgang til %s via SAMBA: " + +msgid "Pause Class" +msgstr "Sett klasse på pause" + +msgid "Pause Printer" +msgstr "Sett skriver på pause" + +msgid "Peel-Off" +msgstr "Fjern papir" + +msgid "Personal Envelope" +msgstr "Personlig konvolutt" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Fotoetiketter" + +msgid "Plain Paper" +msgstr "Vanlig papir" + +msgid "Policies" +msgstr "Kriterier" + +msgid "Port Monitor" +msgstr "Portovervåking" + +msgid "PostScript Printer" +msgstr "PostScript-skriver" + +msgid "Postcard" +msgstr "Postkort" + +msgid "Print Density" +msgstr "Utskriftstetthet" + +msgid "Print Job:" +msgstr "Utskriftsjobb:" + +msgid "Print Mode" +msgstr "Utskriftsmodus" + +msgid "Print Rate" +msgstr "Utskriftshastighet" + +msgid "Print Self-Test Page" +msgstr "Skriv ut testside" + +msgid "Print Speed" +msgstr "Utskriftshastighet" + +msgid "Print Test Page" +msgstr "Skriv ut testside" + +msgid "Print and Cut" +msgstr "Skriv ut og klipp" + +msgid "Print and Tear" +msgstr "Skriv ut og riv" + +msgid "Printed For: " +msgstr "Skrevet ut for: " + +msgid "Printed From: " +msgstr "Skrevet ut fra: " + +msgid "Printed On: " +msgstr "Skrevet ut på: " + +msgid "Printer Added" +msgstr "Skriver lagt til" + +msgid "Printer Default" +msgstr "Skriverstandard" + +msgid "Printer Deleted" +msgstr "Skriver slettet" + +msgid "Printer Modified" +msgstr "Skriver endret" + +msgid "Printer Name: " +msgstr "Skrivernavn: " + +msgid "Printer Paused" +msgstr "Skriver satt på pause" + +msgid "Printer Settings" +msgstr "Skriverinnstillinger" + +msgid "Printer offline." +msgstr "Skriver ikke tilgjengelig." + +msgid "Printer:" +msgstr "Skriver:" + +msgid "Printers" +msgstr "Skrivere" + +msgid "Purge Jobs" +msgstr "Tøm jobber" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Begrensning nådd." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Rangering Eier Jobb Fil(er) Samlet " +"størrelse\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Rangering Eier Prioritet Jobb Filer " +"Samlet størrelse\n" + +msgid "Reject Jobs" +msgstr "Avslå jobber" + +msgid "Reprint After Error" +msgstr "Skriv ut på nytt etter feil" + +msgid "Request Entity Too Large" +msgstr "Forespørselsobjektet er for stort" + +msgid "Resolution" +msgstr "Oppløsning" + +msgid "Resume Class" +msgstr "Fortsett med klasse" + +msgid "Resume Printer" +msgstr "Fortsett med skriver" + +msgid "Return Address" +msgstr "Avsenderadresse" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Avsenderadresse – 3/4 x 2\"" + +msgid "Rewind" +msgstr "Spol tilbake" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Utfører kommando: %s %s -N -A %s -c «%s»\n" + +msgid "SCSI Printer" +msgstr "SCSI-skriver" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE bruker uendelig lengde" + +msgid "See Other" +msgstr "Se andre" + +#, c-format +msgid "Serial Port #%d" +msgstr "Serieport nr. %d" + +msgid "Server Restarted" +msgstr "Tjener startet på nytt" + +msgid "Server Security Auditing" +msgstr "Sikkerhetsgjennomgang for tjener" + +msgid "Server Started" +msgstr "Tjener startet" + +msgid "Server Stopped" +msgstr "Tjener stoppet" + +msgid "Service Unavailable" +msgstr "Tjeneste ikke tilgjengelig" + +msgid "Set Allowed Users" +msgstr "Angi tillatte brukere" + +msgid "Set As Server Default" +msgstr "Bruk som tjenerstandard" + +msgid "Set Class Options" +msgstr "Angi klassevalg" + +msgid "Set Printer Options" +msgstr "Angi skrivervalg" + +msgid "Set Publishing" +msgstr "Angi publisering" + +msgid "Shipping Address" +msgstr "Leveringsadresse" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Leveringsadresse – 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Kortside (liggende)" + +msgid "Special Paper" +msgstr "Spesialpapir" + +msgid "Standard" +msgstr "Standard" + +msgid "Starting Banner" +msgstr "Startbanner" + +msgid "Statement" +msgstr "Melding" + +msgid "Stylus Color Series" +msgstr "Stylus Color-serie" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo-serie" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Bytter protokoll" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (overdimensjonert)" + +msgid "Tear" +msgstr "Riv" + +msgid "Tear-Off" +msgstr "Riv av" + +msgid "Tear-Off Adjust Position" +msgstr "Riv av, juster plassering" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Fant ikke PPD-filen «%s»." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Kunne ikke åpne PPD-filen «%s»: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Klassenavnet kan kun inneholde opptil 127 tegn som kan skrives ut, og kan " +"ikke inneholde mellomrom, skråstrek (/) eller firkanttegn (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Notify-lease-duration-attributtet kan ikke brukes med jobbabonnementer." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Notify-user-data-verdien er for stor (%d > 63 oktetter)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Skrivernavnet kan kun inneholde opptil 127 tegn som kan skrives ut, og kan " +"ikke inneholde mellomrom, skråstrek (/) eller firkanttegn (#)." + +msgid "The printer or class is not shared!" +msgstr "Skriveren eller klassen er ikke delt!" + +msgid "The printer or class was not found." +msgstr "Fant ikke skriveren eller klassen." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Printer-uri «%s» inneholder ugyldige tegn." + +msgid "The printer-uri attribute is required!" +msgstr "Printer-uri-attributtet kreves!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "Printer-uri må ha formatet «ipp://VERTSNAVN/klasser/KLASSENAVN»." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "Printer-uri må ha formatet «ipp://VERTSNAVN/skrivere/SKRIVERNAVN»." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Abonnementsnavnet kan ikke inneholde mellomrom, skråstrek (/), spørsmålstegn " +"(?) eller firkanttegn (#)." + +msgid "There are too many subscriptions." +msgstr "For mange abonnementer." + +msgid "Thermal Transfer Media" +msgstr "Varmeoverføringsmedium" + +msgid "Title: " +msgstr "Tittel: " + +msgid "Toner low." +msgstr "Lite toner." + +msgid "Too many active jobs." +msgstr "For mange aktive jobber." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "For mange job-sheets-verdier (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "For mange printer-state-reasons-verdier (%d > %d)!" + +msgid "Transparency" +msgstr "Gjennomsiktighet" + +msgid "Tray" +msgstr "Skuff" + +msgid "Tray 1" +msgstr "Skuff 1" + +msgid "Tray 2" +msgstr "Skuff 2" + +msgid "Tray 3" +msgstr "Skuff 3" + +msgid "Tray 4" +msgstr "Skuff 4" + +msgid "URI Too Long" +msgstr "URI for lang" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Legal" + +msgid "US Legal (Oversize)" +msgstr "US Legal (overdimensjonert)" + +msgid "US Letter" +msgstr "US Letter" + +msgid "US Letter (Oversize)" +msgstr "US Letter (overdimensjonert)" + +msgid "US Letter (Small)" +msgstr "US Letter (lite)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB-serieport nr. %d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Får ikke tilgang til cupsd.conf-fil:" + +msgid "Unable to add RSS subscription:" +msgstr "Kan ikke legge til RSS-abonnement:" + +msgid "Unable to add class:" +msgstr "Kan ikke legge til klasse:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Kan ikke legge til jobb for målet «%s»!" + +msgid "Unable to add printer:" +msgstr "Kan ikke legge til skriver:" + +msgid "Unable to allocate memory for file types!" +msgstr "Kan ikke tildele hukommelse for filtyper!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Kan ikke avslutte RSS-abonnement:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Kan ikke endre printer-is-shared-attributt:" + +msgid "Unable to change printer:" +msgstr "Kan ikke endre skriver:" + +msgid "Unable to change server settings:" +msgstr "Kan ikke endre tjenerinnstillinger:" + +msgid "Unable to connect to host." +msgstr "Kan ikke koble til vert" + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Kan ikke kopiere 64-bits CUPS-skriverdriverfiler (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "Kan ikke kopiere 64-bits Windows-skriverdriverfiler (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Kan ikke kopiere CUPS-skriverdriverfiler (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Kan ikke kopiere PPD-fil – %s!" + +msgid "Unable to copy PPD file!" +msgstr "Kan ikke kopiere PPD-fil!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Kan ikke kopiere Windows 2000-skriverdriverfiler (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Kan ikke kopiere Windows 9x-skriverdriverfiler (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Kan ikke kopiere grensesnittsprosedyre – %s!" + +msgid "Unable to create printer-uri!" +msgstr "Kan ikke opprette printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Kan ikke opprette midlertidig fil:" + +msgid "Unable to delete class:" +msgstr "Kan ikke slette klasse:" + +msgid "Unable to delete printer:" +msgstr "Kan ikke slette skriver:" + +msgid "Unable to do maintenance command:" +msgstr "Kan ikke utføre vedlikeholdskommando:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Kan ikke redigere cupsd.conf-filer som er større enn 1 MB!" + +msgid "Unable to find destination for job!" +msgstr "Finner ikke mål for jobb!" + +msgid "Unable to find printer!\n" +msgstr "Finner ikke skriver!\n" + +msgid "Unable to get class list:" +msgstr "Kan ikke hente klasseliste:" + +msgid "Unable to get class status:" +msgstr "Kan ikke hente klassestatus:" + +msgid "Unable to get list of printer drivers:" +msgstr "Kan ikke hente liste over skriverdrivere:" + +msgid "Unable to get printer attributes:" +msgstr "Kan ikke hente skriverattributter:" + +msgid "Unable to get printer list:" +msgstr "Kan ikke hente skriverliste:" + +msgid "Unable to get printer status:" +msgstr "Kan ikke hente skriverstatus:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Kan ikke installere Windows 2000-skriverdriverfiler (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Kan ikke installere Windows 9x-skriverdriverfiler (%d)!" + +msgid "Unable to modify class:" +msgstr "Kan ikke endre klasse:" + +msgid "Unable to modify printer:" +msgstr "Kan ikke endre skriver:" + +msgid "Unable to move job" +msgstr "Kan ikke flytte jobb" + +msgid "Unable to move jobs" +msgstr "Kan ikke flytte jobber" + +msgid "Unable to open PPD file" +msgstr "Kan ikke åpne PPD-fil" + +msgid "Unable to open PPD file:" +msgstr "Kan ikke åpne PPD-fil:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Kan ikke åpne cupsd.conf-fil:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Kan ikke åpne dokumentet %d i jobben %d!" + +msgid "Unable to print test page:" +msgstr "Kan ikke skrive ut testside:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Kan ikke starte «%s»: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Kan ikke sende kommando til skriverdriver!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Kan ikke angi Windows-skriverdriver (%d)!" + +msgid "Unable to set options:" +msgstr "Kan ikke angi valg:" + +msgid "Unable to set server default:" +msgstr "Kan ikke angi tjenerstandard:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Kan ikke laste opp cupsd.conf-fil:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Kan ikke bruke eldre driver for USB-klasse!\n" + +msgid "Unauthorized" +msgstr "Uautorisert" + +msgid "Units" +msgstr "Enheter" + +msgid "Unknown" +msgstr "Ukjent" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Ukjent printer-error-policy «%s»." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Ukjent printer-op-policy «%s»." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Tegnsettet «%s» støttes ikke!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Komprimeringen «%s» støttes ikke!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Komprimeringsattributtet %s støttes ikke!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Formatet «%s» støttes ikke!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Formatet «%s» støttes ikke!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Formatet «%s/%s» støttes ikke!" + +msgid "Unsupported value type" +msgstr "Verditypen støttes ikke" + +msgid "Upgrade Required" +msgstr "Oppgradering kreves" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Bruk:\n" +"\n" +" lpadmin [-h tjener] -d mål\n" +" lpadmin [-h tjener] -x mål\n" +" lpadmin [-h tjener] -p skriver [-c legg til klasse] [-i grensesnitt] [-m " +"modell]\n" +" [-r fjern klasse] [-v enhet] [-D beskrivelse]\n" +" [-P ppd-fil] [-o navn=verdi]\n" +" [-u tillat:bruker,bruker] [-u avslå:bruker,bruker]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Bruk: %s jobb-id bruker tittel kopier valg [filnavn]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Bruk: %s jobb-id bruker tittel kopier valg [fil]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Bruk: %s jobb-id bruker tittel kopier valg fil\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Bruk: cupsaddsmb [valg] printer1 ... printerN\n" +" cupsaddsmb [valg] -a\n" +"\n" +"Valg:\n" +" -E Krypter forbindelsen til tjeneren\n" +" -H samba-tjener Bruk den angitte SAMBA-tjeneren\n" +" -U samba-bruker Godkjenn ved hjelp av den angitte SAMBA-brukeren\n" +" -a Eksporter alle skrivere\n" +" -h cups-tjener Bruk den angitte CUPS-tjeneren\n" +" -v Vær detaljert (vis kommandoer)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Bruk: cupsctl [valg] [param=value ... paramN=valueN]\n" +"\n" +"Valg:\n" +"\n" +" -E Aktiver kryptering\n" +" -U brukernavn Angi brukernavn\n" +" -h tjener[:port] Angi tjeneradresse\n" +"\n" +" --[no-]debug-logging Aktiver eller deaktiver feilsøkingslogging\n" +" --[no-]remote-admin Aktiver eller deaktiver ekstern administrering\n" +" --[no-]remote-any Tillat eller forhindre tilgang fra Internett\n" +" --[no-]remote-printers Vis eller skjul eksterne skrivere\n" +" --[no-]share-printers Aktiver eller deaktiver skriverdeling\n" +" --[no-]user-cancel-any Tillat eller forhindre at brukere kan avbryte en " +"hvilken som helst jobb\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Bruk: cupsd [-c konfigurasjonsfil] [-f] [-F] [-h] [-l]\n" +"\n" +"-c konfigurasjonsfil Last inn alternativ konfigurasjonsfil\n" +"-f Kjør i forgrunnen\n" +"-F Kjør i forgrunnen, men skill\n" +"-h Vis denne bruksmeldingen\n" +"-l Kjør cupsd fra launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Bruk: cupstestdsc [valg] filename.ps [... filename.ps]\n" +" cupstestdsc [valg] -\n" +"\n" +"Valg:\n" +"\n" +" -h Vis programbruk\n" +"\n" +" Merk: dette programmet validerer DSC-kommentarer, ikke selve PostScript-" +"innholdet.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Bruk: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Bruk: lpoptions [-h tjener] [-E] -d skriver\n" +" lpoptions [-h tjener] [-E] [-p skriver] -l\n" +" lpoptions [-h tjener] [-E] -p skriver -o valg[=verdi] ...\n" +" lpoptions [-h tjener] [-E] -x skriver\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Bruk: lppasswd [-g gruppenavn]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Bruk: lppasswd [-g gruppenavn] [brukernavn]\n" +" lppasswd [-g gruppenavn] -a [brukernavn]\n" +" lppasswd [-g gruppenavn] -x [brukernavn]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Bruk: lpq [-P mål] [-U brukernavn] [-h vertsnavn[:port]] [-l] [+intervall]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Bruk: ppdc [valg] filename.drv [ ... filenameN.drv ]\n" +"Valg:\n" +" -D navn=verdi Bruk verdi for angitt variabel.\n" +" -I include-dir Legg til inkluderingskatalog i søkebane.\n" +" -c catalog.po Last inn angitt meldingskatalog.\n" +" -d output-dir Angi utdatakatalog.\n" +" -l lang[,lang,...] Angi utdataspråk (nasjonal innstilling).\n" +" -m Bruk ModelName-verdi som filnavn.\n" +" -t Test PPD-er i stedet for å generere dem.\n" +" -v Vær detaljert (flere v-er gir høyere detaljnivå).\n" +" -z Komprimer PPD-filer ved hjelp av GNU zip.\n" +" --cr Bruk CR-linjeskift (Mac OS 9).\n" +" --crlf Bruk CR + LF-linjeskift (Windows).\n" +" --lf Bruk LF-linjeskift (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Bruk: ppdhtml [valg] filename.drv >filename.html\n" +" -D navn=verdi Bruk verdi for angitt variabel.\n" +"Valg:\n" +" -I include-dir Legg til inkluderingskatalog i søkebane.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Bruk: ppdi [valg] filename.ppd [ ... filenameN.ppd ]\n" +"Valg:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Bruk: ppdmerge [valg] filename.ppd [ ... filenameN.ppd ]\n" +"Valg:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Bruk: ppdpo [valg] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Valg:\n" +" -D navn=verdi Bruk verdi for angitt variabel.\n" +" -I include-dir Legg til inkluderingskatalog i søkebane.\n" +" -v Vær detaljert (flere v-er gir høyere detaljnivå).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Bruk: snmp [vert eller ip-adresse]\n" + +msgid "Value uses indefinite length" +msgstr "Verdi bruker uendelig lengde" + +msgid "VarBind uses indefinite length" +msgstr "VarBind bruker uendelig lengde" + +msgid "Version uses indefinite length" +msgstr "Versjon bruker uendelig lengde" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Legger til kun de %d første skriverne som ble funnet" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Boolsk forventet for waiteof-valget «%s»\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Kunne ikke lese sidekanalforspørsel!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: Valget «%s» kan ikke inkluderes via IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Skriver svarer ikke\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Skriver sendte uventet EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Ekstern vert svarte ikke med kommandostatusbyte etter %d sekunder!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Ekstern vert svarte ikke med kontrollstatusbyte etter %d sekunder!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Ekstern vert svarte ikke med datastatusbyte etter %d sekunder!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI-kommando ble tidsavbrutt (%d). Prøver på nytt...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Dette dokumentet er ikke i overensstemmelse med Adobes konvensjoner " +"for dokumentstruktur, og det er mulig at dokumentet ikke skrives ut riktig!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Kan ikke åpne «%s:%s»: %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Kan ikke sende PAP-statusforespørsel" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Uventet PAP-pakke av typen %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Ukjent PAP-pakke av typen %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Ukjent innstilling «%s» for valget «%s»!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Ukjent valg «%s»!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Modulasjonshastigheten %s støttes ikke!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: tall forventet for statusvalget «%s»\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: gjenopprettbar: Nettverksverten «%s» er opptatt. Prøver på nytt om %" +"d sekunder...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Advarsel: Ingen Windows 2000-skriverdrivere er installert!" + +msgid "Yes" +msgstr "Ja" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Du må få tilgang til denne siden ved hjelp av URLen https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "You4-konvolutt" + +msgid "ZPL Label Printer" +msgstr "ZPL-etikettskriver" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "kansellert" + +msgid "canceled" +msgstr "avbrutt" + +msgid "completed" +msgstr "fullført" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "konverter: Bruk valget -f for å angi en fil som skal konverteres.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced ble ikke utført." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd ble ikke utført." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Ingen PPD-fil for skriveren «%s» – %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Kan ikke koble til tjener: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Ukjent valg «%s»!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Ukjent valg «-%c»!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Forventet config-filnavn etter «-c»-valg!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Kan ikke hente nåværende katalog!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Ukjent argument «%s» – avbryter!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Ukjent valg «%c» – avbryter!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: launchd(8)-støtte er ikke kompilert inn, bruker vanlig modus.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Ugyldig dokumentnummer %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: Ugyldig jobb-ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Kun ett filnavn kan spesifiseres!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Kan ikke hente jobbfil – %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: Valget -q er ikke kompatibelt med valget -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: Valget -v er ikke kompatibelt med valget -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "enhet for %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "enhet for %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index bruker uendelig lengde" + +msgid "error-status uses indefinite length" +msgstr "error-status bruker uendelig lengde" + +msgid "held" +msgstr "holdt" + +msgid "help\t\tget help on commands\n" +msgstr "hjelp\t\thent hjelp ved kommandoer\n" + +msgid "idle" +msgstr "inaktiv" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri-attributt mangler!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Klassenavn kan kun inneholde tegn som kan skrives ut!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: Forventet PPD etter «-P»-valg!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Forventet tillat/avslå:brukerliste etter «-u»-valg!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Forventet klasse etter «-r»-valg!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Forventet klassenavn etter «-c»-valg!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Forventet beskrivelse etter «-D»-valg!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Forventet enhets-URI etter «-v»-valg!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Forventet filtype etter «-I»-valg!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Forventet vertsnavn etter «-h»-valg!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Forventet grensesnitt etter «-i»-valg!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Forventet sted etter «-L»-valg!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Forventet modell etter «-m»-valg!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Forventet navn=verdi etter «-o»-valg!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Forventet skriver etter «-p»-valg!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Forventet skrivernavn etter «-d»-valg!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Forventet skriver eller klasse etter «-x»-valg!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Fant ingen medlemsnavn!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Skriveren %s er allerede medlem av klassen %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Skriveren %s er ikke medlem av klassen %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Skrivernavn kan kun inneholde tegn som kan skrives ut!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke legge til skriver i klassen:\n" +" Du må angi et skrivernavn først!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Kan ikke koble til tjener: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Kan ikke åpne PPD-filen «%s» – %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Kan ikke åpne filen «%s»: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke fjerne en skriver fra klassen:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi PPD-fil:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi enhets-URI:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi grensesnittsprosedyre eller PPD-fil:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi grensesnittsprosedyre:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi beskrivelse av skriver:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi skriverplassering:\n" +" Du må angi et skrivernavn først!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kan ikke angi skrivervalg:\n" +" Du må angi et skrivernavn først!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Ukjent tillat/avslå-valg «%s»!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Ukjent argument «%s»!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Ukjent valg «%c»!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Advarsel – ignorerte innholdstypeliste!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: Forventet 1284-enhets-ID-streng etter --device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Forventet språk etter --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Forventet merke og modell etter --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Forventet produktstreng etter --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Forventet oppsettliste etter --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Forventet oppsettliste etter --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Forventet tisdsavbrudd etter --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Ukjent argument «%s»!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Ukjent valg «%c»!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Ukjent valg «%s»!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Kan ikke koble til tjener: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Ukjent argument «%s»!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Ukjent valg «%c»!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Ingen skrivere!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Kan ikke legge til skriver eller forekomst: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Kan ikke hente PPD-fil for %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Kan ikke åpne PPD-fil for %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Ukjent skriver eller klasse!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Kun rot kan legge til og slette passord!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Passordfil er opptatt!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Passordfil er ikke oppdatert!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Beklager. Passordet stemmer ikke!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Beklager. Passordet ble ikke godtatt.\n" +"Passordet må være på minst 6 tegn og kan ikke inneholde\n" +"brukernavet ditt. Det må også inneholde must én bokstav og ett tall.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Beklager. Passordene er ikke like!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Kan ikke kopiere passordstreng: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Kan ikke åpne passordfil: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Kan ikke skrive til passordfil: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: kunne ikke sikkerhetskopiere gammel passordfil: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: kunne ikke endre navn på passordfil: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: brukeren «%s» og gruppen «%s» finnes ikke.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: feil – %s-miljøvariabel oppgir målet «%s» som ikke eksisterer!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "medlemmer av klassen %s:\n" + +msgid "no entries\n" +msgstr "ingen oppføringer\n" + +msgid "no system default destination\n" +msgstr "ingen standardmål for system\n" + +msgid "notify-events not specified!" +msgstr "notify-events ikke angitt!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri-URI «%s» er i bruk!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri-URI «%s» bruker et ukjent oppsett!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d er ubrukelig!" + +msgid "pending" +msgstr "ventende" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Legger til inkluderingskatalog «%s»...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Legger til / oppdaterer UI-tekst fra %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Ugyldig boolsk verdi (%s) på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ugyldig oppløsningsnavn «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Ugyldig statusnøkkelord %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Ugyldig variabelutskifting ($%c) på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Fant alternativ på linje %d av %s uten valg!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Duplikat #po for nasjonal innstilling %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Forventet filterdefinisjon på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Forventet programnavn på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Forventet boolsk verdi på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Forventet tegnsett etter Font på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Forventet valgkode på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Forventet valgnavn/-tekst på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Forventet fargerekkefølge for ColorModel på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Forventet fargeområde for ColorModel på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Forventet komprimering for ColorModel på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc: Forventet restriksjoner for UIConstraints på linje %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Forventet nøkkelord for drivertype etter DriverType på linje %d av %" +"s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Forventet duplekstype etter Duplex på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Forventet koding etter Font på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Forventet filnavn etter #po %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Forventet gruppenavn/-tekst på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Forventet inkluderingsfilnavn på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Forventet heltall på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Forventet nasjonal innstilling etter #po på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter FileName på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter Font på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter Manufacturer på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter MediaSize på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter ModelName på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Forventet navn etter PCFileName på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Forventet navn/tekst etter %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Forventet navn/tekst etter Installable på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Forventet navn/tekst etter Resolution på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Forventet navn/tekst-kombinasjon for ColorModel på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Forventet valgnavn/-tekst på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Forventet valgdel på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Forventet valgtype på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: Forventet overstyringsfelt etter Resolution på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Forventet reelt tall på linje %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Forventet oppløsning/papirtype etter ColorProfile på linje %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Forventet oppløsning/papirtype etter SimpleColorProfile på linje %d av " +"%s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Forventet velger etter %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Forventet status etter Font på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Forventet streng etter Copyright på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Forventet streng etter Version på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Forventet to valgnavn på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Forventet verdi etter %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Forventet versjon etter Font på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Ugyldig #include/#po filnavn «%s»!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Ugyldig kostnad for filter på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Ugyldig, tom MIME-type for filter på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Ugyldig, tomt programnavn for filter på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ugyldig valgdel «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ugyldig valgtype «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Laster inn driverinformasjonsfil «%s»...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Laster inn meldinger for nasjonal innstilling «%s»...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Laster inn meldinger fra «%s»...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: Mangler #endif ved slutten av «%s»!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: Mangler #if på linje %d av %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Ingen meldingskatalog oppgitt for nasjonal innstilling %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "" +"ppdc: Valg %s definert på nytt med forskjellig type på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Valgrestriksjon må *navn på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: For mange nestede #if-er på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: Kan ikke opprette PPD-filen «%s» – %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Kan ikke opprette utdatakatalog %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Kan ikke opprette utdatakanaler: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Kan ikke utføre cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Finner ikke #po-filen %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: Finner ikke inkluderingsfilen «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Finner ikke lokalisering for «%s» – %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Finner ikke lokaliseringsfilen «%s» – %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Udefinert variabel (%s) på linje %d av %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Ukjent drivertype %s på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ukjent duplekstype «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ukjent papirstørrelse «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Ukjent kjennetegn «%s» funnet på linje %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Ukjente etterfølgende tegn i det reelle tallet «%s» på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Uavsluttet streng begynner med %c på linje %d av %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Skriver %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Skriver PPD-filer til katalog «%s»...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Ugyldig LanguageVersion «%s» i %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Ignorerer PPD-fil %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Kan ikke sikkerhetskopiere %s til %s – %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "skriveren %s er deaktivert siden %s –\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "skriveren %s er inaktiv. aktivert siden %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "skriveren %s skriver nå ut %s–%d. aktivert siden %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "skriveren %s/%s er deaktivert siden %s –\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "skriveren %s/%s er inaktiv. aktivert siden %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "skriveren %s/%s skriver nå ut %s–%d. aktivert siden %s\n" + +msgid "processing" +msgstr "behandler" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "request-id er %s–%d (%d fil(er))\n" + +msgid "request-id uses indefinite length" +msgstr "request-id bruker uendelig lengde" + +msgid "scheduler is not running\n" +msgstr "planlegger er ikke i gang\n" + +msgid "scheduler is running\n" +msgstr "planlegger er i gang\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "status for %s mislyktes: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tvis status for daemon og kø\n" + +msgid "stopped" +msgstr "stoppet" + +#, c-format +msgid "system default destination: %s\n" +msgstr "standardmål for system: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "standardmål for system: %s/%s\n" + +msgid "unknown" +msgstr "ukjent" + +msgid "untitled" +msgstr "uten navn" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings bruker uendelig lengde" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN APDialogExtension-filen «%s» mangler\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN APPrinterIconPath-filen «%s» mangler\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Kan ikke åpne %s – %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Kan ikke åpne %s – %s på linje %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI gråskala" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Mangler enhets-URI på kommandolinje, og ingen DEVICE_URI-" +#~ "miljøvariabel!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Kan ikke opprette midlertidig fil – %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Kan ikke opprette midlertidig fil: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Kan ikke åpne midlertidig fil" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops-filter krasjet på signal %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops-filter avsluttet med statusen %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Ukjent skriverfeil (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Bruk: konverter [ valg ]\n" +#~ "\n" +#~ "Valg:\n" +#~ "\n" +#~ " -f filnavn Angi at fil skal konverteres (stdin hvis ikke)\n" +#~ " -o filnavn Angi at fil skal genereres (stdout hvis ikke)\n" +#~ " -i mime/type Angi MIME-type for inndata (auto-typed hvis ikke)\n" +#~ " -j mime/type Angi MIME-type for utdata (application/pdf hvis " +#~ "ikke)\n" +#~ " -P filename.ppd Angi PPD-fil\n" +#~ " -a 'navn=verdi ...' Angi valg\n" +#~ " -U brukernavn Angi brukernavn for jobb\n" +#~ " -J tittel Angi tittel\n" +#~ " -c eksemplarer Angi antall eksemplarer\n" +#~ " -u Fjern PPD-fil når ferdig\n" +#~ " -D Fjern inndatafil når ferdig\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Bruk: cupsfilter -m mime/type [ valg ] filnavn\n" +#~ "\n" +#~ "Valg:\n" +#~ "\n" +#~ " -c cupsd.conf Angi hvilken cupsd.conf-fil som skal brukes\n" +#~ " -j jobb-id[,N] Filtrer filen N fra angitt jobb (standard er fil 1)\n" +#~ " -n eksemplarer Angi antall eksemplarer\n" +#~ " -o navn=verdi Angi valg\n" +#~ " -p filename.ppd Angi PPD-fil\n" +#~ " -t tittel Angi tittel\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Bruk: cupstestppd [valg] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [valg] -\n" +#~ "\n" +#~ "Valg:\n" +#~ "\n" +#~ " -R rotkatalog Angi alternativ rot\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Gi advarsler i stedet for feil\n" +#~ " -q Kjør stille\n" +#~ " -r Bruk «avslappet» åpen modus\n" +#~ " -v Vær litt detaljert\n" +#~ " -vv Vær veldig detaljert\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Kan ikke opprette midlertidig fil: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Kan ikke opprette midlertidig fil – %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Kan ikke opprette midlertidig fil: %s\n" diff --git a/locale/cups_pl.po b/locale/cups_pl.po new file mode 100644 index 0000000000..3a7c45288d --- /dev/null +++ b/locale/cups_pl.po @@ -0,0 +1,5691 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(wszystko)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(brak)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d wpisów\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tPo niepowodzeniu: kontynuuj\n" + +msgid "\tAlerts:" +msgstr "\tAlarmy:" + +msgid "\tBanner required\n" +msgstr "\tBanner jest wymagany\n" + +msgid "\tCharset sets:\n" +msgstr "\tZestawy znaków:\n" + +msgid "\tConnection: direct\n" +msgstr "\tPołączenie: bezpośrednie\n" + +msgid "\tConnection: remote\n" +msgstr "\tPołączenie: zdalne\n" + +msgid "\tDefault page size:\n" +msgstr "\tDomyślny rozmiar strony:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tDomyślny stopień:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tDomyślne ustawienia portu:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tOpis: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormularz zamontowany od:\n" +"\tRodzaje zawartości: dowolne\n" +"\tRodzaje drukarek: nieznane\n" + +msgid "\tForms allowed:\n" +msgstr "\tDozwolone formularze:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterfejs: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterfejs: %s/interfejsy/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterfejs: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tPołożenie: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tPrzy niepowodzeniu: brak alarmu\n" + +msgid "\tUsers allowed:\n" +msgstr "\tDozwoleni użytkownicy:\n" + +msgid "\tUsers denied:\n" +msgstr "\tZabronieni użytkownicy:\n" + +msgid "\tdaemon present\n" +msgstr "\tdemon jest obecny\n" + +msgid "\tno entries\n" +msgstr "\tbrak wpisów\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tdrukarka jest urządzeniem \"%s\" prędkość -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tdrukowanie jest wyłączone" + +msgid "\tprinting is enabled\n" +msgstr "\tdrukowanie jest włączone\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tw kolejce dla%s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tkolejka jest wyłączona\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tkolejka jest włączona\n" + +msgid "\treason unknown\n" +msgstr "\tnieznana przyczyna\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" SZCZEGÓŁOWE WYNIKI TESTU ZGODNOŚCI\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: strona 15, sekcja 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: strona 15, sekcja 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: strona 19, sekcja 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: strona 20, sekcja 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: strona 27, sekcja 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: strona 42, sekcja 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: strony 16-17, sekcja 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: strony 42-45, sekcja 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: strony 45-46, sekcja 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: strony 48-49, sekcja 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: strony 52-54, sekcja 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f bajtów\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " SUKCES Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " SUKCES DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " SUKCES DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " SUKCES FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " SUKCES FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " SUKCES LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " SUKCES LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " SUKCES Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " SUKCES ModelName\n" + +msgid " PASS NickName\n" +msgstr " SUKCES NickName\n" + +msgid " PASS PCFileName\n" +msgstr " SUKCES PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " SUKCES PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " SUKCES PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " SUKCES PageSize\n" + +msgid " PASS Product\n" +msgstr " SUKCES Product\n" + +msgid " PASS ShortNickName\n" +msgstr " SUKCES ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" OSTRZEŻENIE \"%s %s\" jest w konflikcie z \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " OSTRZEŻENIE %s nie posiada odpowiadających opcji!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" OSTRZEŻENIE %s współdzieli wspólny przedrostek z %s\n" +" REF: strona 15, sekcja 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " OSTRZEŻENIE Konflikt domyślnych wyborów!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" OSTRZEŻENIE Podwójna opcja słowo kluczowe %s może nie działać w " +"spodziewany sposób i powinno nosić nazwę Podwójne!\n" +" REF: strona 122, sekcja 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" OSTRZEŻENIE Plik zawiera mieszaninę zakończeń wierszy CR, LF i CR " +"LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" OSTRZEŻENIE LanguageEncoding jest wymagane przez specyfikację PPD " +"4.3.\n" +" REF: strony 56-57, sekcja 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " OSTRZEŻENIE Wiersz %d zawiera wyłącznie białe spacje!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" OSTRZEŻENIE Manufacturer jest wymagane przez specyfikację PPD " +"4.3.\n" +" REF: strony 58-59, sekcja 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" OSTRZEŻENIE Pliki PPD nie przeznaczone dla Windows powinny używać " +"tylko zakończeń wierszy LF, nie CR LF!" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" OSTRZEŻENIE Przestarzała wersja PPD %.1f!\n" +" REF: strona 42, sekcja 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" OSTRZEŻENIE PCFileName dłuższa niż 8.3 narusza specyfikację PPD.\n" +" REF: strony 61-62, sekcja 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" OSTRZEŻENIE Protokoły zawierają PJL, ale cechy JCL nie są " +"ustawione.\n" +" REF: strony 78-79, sekcja 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" OSTRZEŻENIE Protokoły zawierają zarówno PJL jak i BCP, oczekiwano " +"TBCP.\n" +" REF: strony 78-79, sekcja 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" OSTRZEŻENIE ShortNickName jest wymagana przez specyfikację PPD " +"4.3.\n" +" REF: strony 64-65, sekcja 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s nie istnieje!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Zły wybór %s, %s!\n" +" REF: strona 122, sekcja 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" +" %s Nieprawidłowy UTF-8 łańcucha tekstowegi tłumaczenia \"%s\" dla " +"opcji %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Nieprawidłowy UTF-8 łańcucha tekstowego tłumaczenia \"%s\" dla " +"opcji %s, wybór %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Błędna wartość cupsFilter \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Nieprawidłowy profil cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Błędna wartość cupsPreFilter \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Błędna wartość cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Błędny język \"%s\"!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Puste cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr "" +" %s Brakujący łańcuch tekstowy tłumaczenia \"%s\" dla opcji %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Brakujący łańcuch tekstowy tłumaczenia \"%s\" dla opcji %s, wybór %" +"s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Brakujący wybór *%s %s w UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Brakujący wybór *%s %s w cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Brakujący plik cupsFilter \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Brakujący plik cupsICCProfile \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Brakujący plik cupsPreFilter \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Brakujący cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Brakująca opcja %s w UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Brakująca opcja %s w cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Brak podstawowego tłumaczenia \"%s\" zawartego w pliku!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s WYMAGANE %s nie defuniuje wyboru Brak!\n" +" REF: strona 122, sekcja 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s skrót koliduje z %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s powoduje pętlę!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **PROBLEM** %s nazwy wyborów %s i %s różnią się tylko wielkością " +"liter!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **PROBLEM** %s musi być 1284DeviceID!\n" +" REF: strona 72, sekcja 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość Default%s %s\n" +" REF: strona 40, sekcja 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość DefaultImageableArea %s!\n" +" REF: strona 102, sekcja 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość DefaultPaperDimension %s!\n" +" REF: strona 103, sekcja 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość właściwości JobPatchFile w pliku\n" +" REF: strona 24, sekcja 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość Manufacturer (powinno być \"HP\")\n" +" REF: strona 211, tablica D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość Manufacturer (powinno być \"Oki\")\n" +" REF: strona 211, tablica D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **PROBLEM** BŁĘDNA wartość ModelName - \"%c\" nie jest zezwolone w " +"ciągu znaków.\n" +" REF: strony 59-60, sekcja 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **PROBLEM** BŁĘDNE PSVersion - nie jest \"(string) int\".\n" +" REF: strony 62-64, sekcja 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **PROBLEM** BŁĘDNE Product - nie jest \"(string)\".\n" +" REF: strona 62, sekcja 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **PROBLEM** BŁĘDNE ShortNickName - dłuższe niż 31 znaków.\n" +" REF: strony 64-65, sekcja 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **PROBLEM** Błędny %s wybór %s!\n" +" REF: strona 84, sekcja 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **PROBLEM** Nieprawidłowe FileVersion \"%s\"\n" +" REF: strona 56, sekcja 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **PROBLEM** Nieprawidłowe FormatVersion \"%s\"\n" +" REF: strona 56, sekcja 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **PROBLEM** Błędna wartość LanguageEncoding %s - musi być ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **PROBLEM** Błędna wartość LanguageVersion %s - musi być angielski!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **PROBLEM** Nie można zinterpretować domyślnego kodu opcji: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **PROBLEM** Domyślny łańcuch tekstowy tłumaczenia dla opcji %s wyboru " +"%s zawiera 8 bitowe znaki!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **PROBLEM** Nie można zinterpretować domyślnego kodu opcji: %s\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **PROBLEM** Nazwy grup %s i %s różnią się tylko wielkością liter!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Wielokrotne wystąpienia nazwy wyboru %s, %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **PROBLEM** Nazwy opcji %s i %s różnią się tylko wielkością liter!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **PROBLEM** WYMAGANE Default%s\n" +" REF: strona 40, sekcja 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **PROBLEM** WYMAGANE DefaultImageableArea\n" +" REF: strona 102, sekcja 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **PROBLEM** WYMAGANE DefaultPaperDimension\n" +" REF: strona 103, sekcja 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE FileVersion\n" +" REF: strona 56, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE FormatVersion\n" +" REF: strona 56, sekcja 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **PROBLEM** WYMAGANE ImageableArea for PageSize %s\n" +" REF: strona 41, sekcja 5.\n" +" REF: strona 102, sekcja 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE LanguageEncoding\n" +" REF: strony 56-57, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE LanguageVersion\n" +" REF: strony 57-58, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** WYMAGANE Manufacturer\n" +" REF: strony 58-59, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** WYMAGANE ModelName\n" +" REF: strony 59-60, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE NickName\n" +" REF: strona 60, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE PCFileName\n" +" REF: strony 61-62, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE PSVersion\n" +" REF: strony 62-64, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **PROBLEM** WYMAGANE PageRegion\n" +" REF: strona 100, sekcja 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **PROBLEM** WYMAGANE PageSize\n" +" REF: strona 41, sekcja 5.\n" +" REF: strona 99, sekcja 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **PROBLEM** WYMAGANE PageSize\n" +" REF: strony 99-100, sekcja 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **PROBLEM** WYMAGANE PaperDimension dla PageSize %s\n" +" REF: strona 41, sekcja 5.\n" +" REF: strona 103, sekcja 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE Product\n" +" REF: strona 62, sekcja 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **PROBLEM** WYMAGANE ShortNickName\n" +" REF: strony 64-65, sekcja 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " ZNALEZIONO %d BŁĘDÓW\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Błędna wartość %%%%BoundingBox: w wierszu %d!\n" +" REF: strona 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Błędna wartość %%%%Page: w wierszu %d!\n" +" REF: strona 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Błędna wartość %%%%Pages: w wierszu %d!\n" +" REF: strona 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Wiersz %d jest dłuższy niż 255 znaków (%d)!\n" +" REF: strona 25, Długość wiersza\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" Brakujące %!PS-Adobe-3.0 w pierwszym wierszu!\n" +" REF: strona 17, 3.1 Podporządkowywanie dokumentów\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Brakujący komentarz %%EndComments!\n" +" REF: strona 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Brakujący lub błędny komentarz %%BoundingBox:!\n" +" REF: strona 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Brakujące lub błędne komentarze %%Page:!\n" +" REF: strona 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Brakujący lub błędny komentarz %%Pages:!\n" +" REF: strona 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " NIE ZNALEZIONO BŁĘDÓW\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Znaleziono %d wierszy przekraczających 255 znaków!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Zbyt wiele komentarzy %%BeginDocument!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Zbyt wiele komentarzy %%EndDocument!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Ostrzeżenie: plik zawiera dane binarne!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Ostrzeżenie: brak komentarza %%EndComments w pliku!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Ostrzeżenie: przestarzała wersja DSC %.1f w pliku!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **PROBLEM** Nie można otworzyć pliku PPD - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" PROBLEM\n" +" **PROBLEM** Nie można otworzyć pliku PPD - %s w wierszu %d.\n" + +msgid " PASS\n" +msgstr " SUKCES\n" + +msgid "#10 Envelope" +msgstr "Koperta #10" + +msgid "#11 Envelope" +msgstr "Koperta #11" + +msgid "#12 Envelope" +msgstr "Koperta #12" + +msgid "#14 Envelope" +msgstr "Koperta #14" + +msgid "#9 Envelope" +msgstr "Koperta #9" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bajtów" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bajtów\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f mm" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f do %.0f x %.0f mm" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f cali" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f do %.2f x %.2f cali" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s akceptuje żądania od %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s nie może zostać zmienione." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s nie jest zaimplementowane przez lpc w wersji CUPS.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s nie jest gotowe\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s jest gotowe\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s jest gotowe i drukuje\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s nie akceptuje żądań od %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s jest nieobsługiwane!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s akceptuje żądania od %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s nie akceptuje żądań od %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [zlecenie %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s nie powiodło się: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: nie wiem co robić!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: błąd - %s nazw zmiennych środowiskowych z nieistniejącym celem \"%s\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: błąd - błędny ID zlecenia!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: błąd - nie można jednocześnie drukować plików i zmieniać zlecenia!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: błąd - nie można drukować ze standardowego wejścia, jeśli dostarczone są " +"pliki lub ID zlecenia!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: błąd - oczekiwany zestaw znaków po opcji \"-S\"!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: błąd - oczekiwany typ zawartości po opcji \"-T\"!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: błąd - oczekiwane kopie po opcji \"-n\"!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: błąd - oczekiwany licznik kopii po opcji \"-#\"!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: błąd - oczekiwany cel po opcji \"-P\"!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: błąd - oczekiwany cel po opcji \"-b\"!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: błąd - oczekiwany cel po opcji \"-d\"!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: błąd - oczekiwana forma po opcji \"-f\"!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: błąd - oczekiwana wstrzymana nazwa po opcji \"-H\"!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: błąd - oczekiwana nazwa komputera po opcji \"-H\"!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: błąd - oczekiwana nazwa komputera po opcji \"-h\"!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: błąd - oczekiwana lista trybów po opcji \"-y\"!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: błąd - oczekiwana nazwa po opcji \"-%c\"!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: błąd - oczekiwany łańcuch tekstowy opcji po opcji \"-o\"!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: błąd - oczekiwana lista stron po opcji \"-P\"!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: błąd - oczekiwany priorytet po opcji \"-%c\"!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: błąd - oczekiwany tekst przyczyny po opcji \"-r\"!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: błąd - oczekiwany tytuł po opcji \"-t\"!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: błąd - oczekiwana nazwa użytkownika po opcji \"-U\"!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: błąd - oczekiwana nazwa komputera po opcji \"-u\"!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: błąd - oczekiwana wartość po opcji \"-%c\"!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: błąd - wymagane jest \"completed\", \"not-completed\" lub \"all\" po -" +"W!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: błąd - brak dostępnego domyślnego celu.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: błąd - priorytet musi być między 1 a 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: błąd - planista nie odpowiada!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: błąd - za dużo plików - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: błąd - nie można uzyskać dostępu do \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: błąd - nie można wykonać kolejki z stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: błąd - nieznany cel \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: błąd - nieznany cel \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: błąd - nieznana opcja \"%c\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: błąd - nieznana opcja '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: oczekiwany ID zlecenia po opcji \"-i\"!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: filtr \"%s\" jest niedostępny: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: nieprawidłowa nazwa celu na liście \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: nieprawidłowy łańcuch filtra \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: wymagany jest ID zlecenia (\"-i id_zlecenia\") po \"-H restart\"!" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: brak filtra do konwersji z %s/%s na %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: operacja nie powiodła się: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: niestety, nie wkompilowano obsługi szyfowania!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: nie można połączyć się z serwerem\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: nie można skontaktować się z serwerem!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: nie można określić typu MIME \"%s\"!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: nie można otworzyć %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: nie można otworzyć pliku PPD: %s on line %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: nie można odczytać bazy danych MIME z \"%s\" lub \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: nieznany cel \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: nieznany cel rodzaju MIME %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: nieznana opcja \"%c\"!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: nieznane źródło rodzaju MIME %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: ostrzeżenie - modyfikator formatu \"%c\" jest nieobsługiwany - wyjście " +"może nie być prawidłowe!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: ostrzeżenie - opcja zestawu znaków została zignorowana!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: ostrzeżenie - opcja rodzaju zawartości została zignorowana!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: ostrzeżenie - opcja formularza została zignorowana!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: ostrzeżenie - opcja trybu została zignorowana!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: błąd - %s nazw zmiennych środowiskowych z nieistniejącym celem \"%s\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: błąd - oczekiwana opcja=wartość po opcji \"-o\"!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: błąd - brak dostępnego domyślnego celu.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 cal/sek." + +msgid "1.25x0.25\"" +msgstr "1,25x0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25x2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 cala/sek." + +msgid "1.50x0.25\"" +msgstr "1,50x0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50x0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50x1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50x2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 cali/sek." + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/sek." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 cali/sek." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 cali/sek." + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/sek." + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/sek." + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/sek." + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 cale/sek." + +msgid "2-Sided Printing" +msgstr "druk obustronny" + +msgid "2.00x0.37\"" +msgstr "2,00x0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00x0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00x1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00x1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00x2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00x3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00x4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00x5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25x0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25x1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25x4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25x5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38x5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 cala/sek." + +msgid "2.50x1.00\"" +msgstr "2,50x1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50x2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75x1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/sek." + +msgid "200 mm/sec." +msgstr "200 mm/sek." + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24 igłowa" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/sek." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 cale/sek." + +msgid "3.00x1.00\"" +msgstr "3,00x1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00x1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00x2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00x3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00x5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25x2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25x5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25x5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25x5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25x7,83\"" + +msgid "3.5\" Disk" +msgstr "dysk 3.5\"" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "dysk 3.5\" - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50x1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/sek." + +msgid "300 mm/sec." +msgstr "300 mm/sek." + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 cale/sek." + +msgid "4.00x1.00\"" +msgstr "4,00x1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00x13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00x2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00x2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00x3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00x4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00x5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00x6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00x6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/sek." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 cali/sek." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 cali/sek." + +msgid "6.00x1.00\"" +msgstr "6,00x1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00x2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00x3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00x4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00x5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00x6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00x6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/sek." + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 cali/sek." + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 cali/sek." + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00x1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00x2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00x3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00x4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00x5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00x6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00x6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/sek." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 cali/sek." + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9 igłowa" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Nieprawidłowe, nieznane polecenie pomocy\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Hasło Samby jest wymagany, aby wyeksportować sterowniki drukarek!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Nazwa użytkownika Samby jest wymagana, aby wyeksportować sterowniki drukarek!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Klasa o nazwie \"%s\" już istnieje!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Drukarka o nazwie \"%s\" już istnieje!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (oversize)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (oversize)" + +msgid "A4 (Small)" +msgstr "A4 (mały)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (oversize)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Zaakceptuj zlecenia" + +msgid "Accepted" +msgstr "Zaakceptowane" + +msgid "Add Class" +msgstr "Dodaj klasę" + +msgid "Add Printer" +msgstr "Dodaj drukarkę" + +msgid "Add RSS Subscription" +msgstr "Dodaj subskrypcję RSS" + +msgid "Address" +msgstr "Adres" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adres - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administracja" + +msgid "Always" +msgstr "Zawsze" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Aplikator" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Próba ustawienia błędnej wartości %2$d printer-state %1$s!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Grupy właściwości są nieuporządkowane (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Błędny PUSTY wskaźnik dests" + +msgid "Bad OpenGroup" +msgstr "Błędne OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Błędne OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Błędne OrderDependency" + +msgid "Bad Request" +msgstr "Błędne żądanie" + +msgid "Bad SNMP version number" +msgstr "Błędny numer wersji SNMP" + +msgid "Bad UIConstraints" +msgstr "Błędne OrderDependency" + +#, c-format +msgid "Bad copies value %d." +msgstr "Błędna wartość kopii %d." + +msgid "Bad custom parameter" +msgstr "Błędny własny parametr" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Błędny URI urządzenia \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Błędne device-uri \"%s\"!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Błędny schemat device-uri \"%s\"!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Błędne document-format \"%s\"!" + +msgid "Bad filename buffer!" +msgstr "Błędny bufor nazwy pliku!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Błędny atrybut czcionki: %s\n" + +msgid "Bad job-priority value!" +msgstr "Błędna wartość job-priority!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Błędna wartość job-sheets \"%s\"!" + +msgid "Bad job-sheets value type!" +msgstr "Błędny rodzaj wartości job-sheets!" + +msgid "Bad job-state value!" +msgstr "Błędna wartość job-state!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Błędna właściwość job-uri \"%s\"!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Błędne notify-pull-method \"%s\"!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Błędne notify-recipient-uri URI \"%s\"!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Błędna wartość kopii %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Błędna opcja + wybór w wierszu %d!\n" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Błędne wartości %d-%d page-ranges." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Błędne port-monitor \"%s\"!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Błędna wartość printer-state %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Błędny numer wersji żądania %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Błędne ID subskrypcji." + +msgid "Banners" +msgstr "Bannery" + +msgid "Billing Information: " +msgstr "Fakturowanie: " + +msgid "Bond Paper" +msgstr "Papier uszlachetniony" + +msgid "C0 Envelope" +msgstr "Koperta C0" + +msgid "C1 Envelope" +msgstr "Koperta C1" + +msgid "C2 Envelope" +msgstr "Koperta C2" + +msgid "C3 Envelope" +msgstr "Koperta C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Koperta C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Koperta C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Koperta C6" + +msgid "C65 Envelope" +msgstr "Koperta C65" + +msgid "C7 Envelope" +msgstr "Koperta C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Drukarka etykiet CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Wycofaj subskrypcję RSS" + +msgid "Change Settings" +msgstr "Zmień ustawienia" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Zestaw znaków \"%s\" jest nieobsługiwany!" + +msgid "Chou3 Envelope" +msgstr "Koperta Chou3" + +msgid "Chou4 Envelope" +msgstr "Koperta Chou4" + +msgid "Classes" +msgstr "Klasy" + +msgid "Clean Print Heads" +msgstr "Czyść głowice drukarki" + +msgid "Color" +msgstr "Kolor" + +msgid "Color Mode" +msgstr "Tryb koloru" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Polecenia mogą być skracane. Poleceniami są:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Community name używa nieograniczonej długości" + +msgid "Continue" +msgstr "Dalej" + +msgid "Continuous" +msgstr "Ciągły" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Nie można przeskanować rodzaju \"%s\"!" + +msgid "Cover open." +msgstr "Pokrywa jest otwarta." + +msgid "Created" +msgstr "Utworzono" + +msgid "Created On: " +msgstr "Utworzono: " + +msgid "Custom" +msgstr "Własne" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Wytnij" + +msgid "Cutter" +msgstr "Do cięcia" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "Koperta DL" + +msgid "Dark" +msgstr "Ciemne" + +msgid "Darkness" +msgstr "Ciemność" + +msgid "Delete Class" +msgstr "Usuń klasę" + +msgid "Delete Printer" +msgstr "Usuń drukarkę" + +msgid "Description: " +msgstr "Opis: " + +msgid "DeskJet Series" +msgstr "Seria DeskJet" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Cel \"%s\" nie akceptuje zadań." + +msgid "Developer almost empty." +msgstr "Wywoływacz jest niemal pusty." + +msgid "Developer empty!" +msgstr "Wywoływacz jest pusty!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Urządzenie: uri = %s\n" +" klasa = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" lokalizacja = %s\n" + +msgid "Direct Thermal Media" +msgstr "Materiał bezpośredni termiczny" + +msgid "Disabled" +msgstr "Wyłączone" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Dokument %d nie znaleziony w zleceniu %d." + +msgid "Door open." +msgstr "Drzwi otwarte." + +msgid "Double Postcard" +msgstr "Podwójna pocztówka" + +msgid "Driver Name: " +msgstr "Nazwa sterownika: " + +msgid "Driver Version: " +msgstr "Wersja sterownika: " + +msgid "Duplexer" +msgstr "Do druku obustronnego" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Nie można przydzielić pamięci dla informacji strony: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Nie można przydzielić pamięci dla tablicy stron: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Drukarka etykiet EPL1" + +msgid "EPL2 Label Printer" +msgstr "Drukarka etykiet EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: znaleziono nieprawidłowy komentarz %%BoundingBox:!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: nieprawidłowy komentarz %%IncludeFeature:!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: nieprawidłowy komentrza %%Page: w pliku!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: nieprawidłowy komentarz %%PageBoundingBox: w pliku!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Błędny plik urządzenia SCSI \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: nieprawidłowy plik zestawu znaków %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: nieprawidłowy rodzaj zestawu znaków %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: nieprawidłowa wartość kolumn %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: nieprawidłowa wartość cpi %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: nieprawidłowy wiersz opisu czcionki: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: nieprawidłowa wartość lpi %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: nieprawidłowe ustawienie strony!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: nieprawidłowy kierunek tekstu %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: nieprawidłowa szerokość tekstu %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: docelowa drukarka nie istnieje!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: znaleziono wielokrotny komentarz %%BoundingBox:!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: znaleziono wielokrotny komentarz %%Pages:!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: pusty plik druku!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: błąd %d podczas wysyłania żądania PAPSendData: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: spodziewany cytowany znak w linii %d w %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: błąd krytyczny USB!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: znaleziono nieprawidłowy komentarz HP-GL/2, nie można wydrukować " +"pliku!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: brakujący %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: brakujący %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: brakująca wartość w linii %d pliku bannera!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: potrzebna linia msgid przed ciągami tłumaczeń w linii %d w %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: brak komentarza %%BoundingBox: w nagłówku!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: brak komentarza %%Pages: w nagłówku!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: nie znaleziono URI urządzenia w argv[0] lub w zmiennej środowiska " +"DEVICE_URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: brak czcionek w pliku zestawu znaków %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: nie znaleziono żadnych stron!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: brak papieru!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: zmienna środowiska PRINTER nie została określona!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: plik wydruku nie został zaakceptowany (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: drukarka nie odpowiada\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: drukarka nie odpowiada!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: drukarka wysłała niespodziewany EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: serwer zdalny nie zaakceptował pliku kontrolnego (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: serwer zdalny nie zaakceptował pliku danych (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: wystąpił błąd upływu limitu czasu podczas wysyłania danych do " +"drukarki\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: nie można dodać pliku %d do zlecenia: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: nie można anulować zlecenia %d: %s/n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: nie można skopiować pliku PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: nie można utworzyć gniazda" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: nie można utworzyć skompresowanego tymczasowego pliku wydruku: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: nie można utworzyć pliku tymczasowego" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: nie można wykonać pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: nie można wykonać programu gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: nie można wykonać programu pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: nie można rozdzielić pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: nie można uzyskać żądania PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: nie można uzyskać odpowiedzi PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: brak pliku PPD dla drukarki \"%s\" - %s\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: nie można uzyskać domyślnej strefy AppleTalk" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: nie można uzyskać cech zlecenia %d (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: nie można uzyskać stanu drukarki (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: nie można znaleźć drukarki \"%s\"!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: nie można wyszukać odpowiedzi PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: nie można znaleźć drukarek AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: nie można utworzyć adresu AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: nie można otworzyć \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: nie można otworzyć %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: nie można otworzyć pliku bannera \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: nie można otworzyć pliku urządzenia \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: nie można otworzyć pliku \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: nie można otworzyć pliku \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: nie można otworzyć do druku pliku obrazka!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: nie można otworzyć pliku wydruku \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: nie można otworzyć pliku wydruku %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: nie można otworzyć pliku wydruku %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: nie można otworzyć tymczasowego skompresowanego pliku wydruku: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: nie można wydrukować %d łamów tekstu!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: nie można wydrukować %dx%d strony tekstu!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: nie można odczytać danych druku" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: nie można odczytać danych druku!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: nie można zarezerwować portu" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: nie można przejść do wiersza %ld w pliku - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: nie można przejść do wiersza %lld w pliku - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: nie można wysłać polecenia LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: nie można wysłać żądania PAP tickle" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: nie można wysłać początkowego żądania wysyłania danych PAP" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: nie można wysłać danych drukowania (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: nie można wysłać danych druku!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: nie można wysłać pliku do drukarki" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: nie można wysłać początkowego zera do drukarki" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: nie można czekać na pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: nie można zapisać %d bajtów do \"%s\":%s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: nie można zapisać %d bajtów do drukarki!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: nie można zapisać pliku kontrolnego" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: nie można zapisać danych druku" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: nie można zapisać danych druku: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: nie można zapisać zrastrowanych danych do sterownika!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: nie można zapisać do pliku tymczasowego" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: nie można zapisać nieskompresowanych danych dokumentu: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: niespodziewany tekst w linii %d w %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: nieznana wartość opcji szyfrowania \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: nieznany porządek plików \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: nieznany znak formatujący \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: nieznany format katalogu wiadomości \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: nieznana opcja \"%s\" o wartości \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: nieznany tryb druku \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: nieznana wartość opcji wersji \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: nieobsługiwana wartość jasności %s, korzystam z jasności=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: nieobsługiwana wartość gamma %s, korzystam z gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" +"ERROR: nieobsługiwana wartość liczby kopii %d, korzystam z liczby kopii=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: nieobsługiwana liczba powtórzeń makiety %s, korzystam z liczby " +"powtórzeń makiety=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: nieobsługiwana wartość ramki strony %s, korzystam z ramki " +"strony=brak!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: wykryto przepełnienie doc_printf (%d bajtów), przerywam!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: zakończono pictwpstops po sygnale %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: zakończono pictwpstops ze stanem %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: usuwalny: nie można się połączyć z drukarką; ponowienie próby nastąpi " +"za 30 sekund…\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: nieudane select()" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: nie można utworzyć statusu pliku drukowania" + +msgid "Edit Configuration File" +msgstr "Edytuj plik konfiguracji" + +msgid "Empty PPD file!" +msgstr "Pusty plik PPD!" + +msgid "Ending Banner" +msgstr "Baner końcowy" + +msgid "Enter old password:" +msgstr "Podaj stare hasło:" + +msgid "Enter password again:" +msgstr "Powtórz hasło:" + +msgid "Enter password:" +msgstr "Podaj hasło:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Wprowadź swoje nazwę użytkownika i hasło lub nazwę i hasło użytkownika root, " +"aby uzyskać dostęp do tej strony. Jeżeli korzystasz z uwierzytelnienia " +"Kerberos, upewnij się, że posiadasz prawidłowy bilet Kerberos." + +msgid "Envelope Feed" +msgstr "Podajnik kopert" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Zasady obsługi błędów" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Błąd: wymagana jest nazwa serwera po opcji \"-h\"!\n" + +msgid "Every 10 Labels" +msgstr "Co 10 etykiet" + +msgid "Every 2 Labels" +msgstr "Co 2 etykiety" + +msgid "Every 3 Labels" +msgstr "Co 3 etykiety" + +msgid "Every 4 Labels" +msgstr "Co 4 etykiety" + +msgid "Every 5 Labels" +msgstr "Co 5 etykiet" + +msgid "Every 6 Labels" +msgstr "Co 6 etykiet" + +msgid "Every 7 Labels" +msgstr "Co 7 etykiet" + +msgid "Every 8 Labels" +msgstr "Co 8 etykiet" + +msgid "Every 9 Labels" +msgstr "Co 9 etykiet" + +msgid "Every Label" +msgstr "Co etykietę" + +msgid "Expectation Failed" +msgstr "Oczekiwana wartość nie do zwrócenia" + +msgid "Export Printers to Samba" +msgstr "Wyeksportuj drukarki do Samby" + +msgid "FAIL\n" +msgstr "PROBLEM\n" + +msgid "File Folder" +msgstr "Folder" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Folder - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"URI pliku urządzenia zostało wyłączone! Aby włączyć, zobacz dyrektywę " +"FileDevice w \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Zabronione" + +msgid "Fuser temperature high!" +msgstr "Wysoka temperatura wygrzewacza!" + +msgid "Fuser temperature low!" +msgstr "Niska temperatura wygrzewacza!" + +msgid "General" +msgstr "Ogólne" + +msgid "Generic" +msgstr "Ogólne" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU używa nieskończonej długości" + +msgid "Glossy Paper" +msgstr "Papier błyszczący" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Otrzymano właściwość printer-uri, ale bez job-id!" + +msgid "Grayscale" +msgstr "Szarości" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Wiszący folder" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Wiszący folder - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk wyłączone w Preferencjach systemowych\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk wyłączone w Preferencjach systemowych.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: przerywam zlecenie drukowania…\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: połączony z drukarką...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: łączę z drukarką...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: udane wysłanie pliku kontrolnego\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: udane wysłanie pliku danych\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: formatuję stronę %d…\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: wczytuję plik obrazka…\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: szukam drukarki...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: otwieram połączenie\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: wysłano plik drukowania, czekam na zakończenie pracy drukarki…\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: drukarka jest zajęta; ponowię próbę za 10 sekund…\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: drukarka jest zajęta; ponowię próbę za 30 sekund…\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: drukarka jest zajęta; ponowę próbę za 5 sekund…\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: drukarka nie obsługuje IPP/%d.%d, próbuję IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: drukarka jest zajęta; ponowię próbę za 5 sekund…\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: drukarka jest wyłączona.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: drukarka nie jest obecnie w trybie gotowości.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: drukarka jest w trybie gotowości.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: drukarka nie jest w trybie gotowości.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: drukarka nie jest podłączona; ponowię próbę za 30 sekund…\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: drukuję stronę %d, %d%% zakończonych…\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: drukuję stronę %d…\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: gotowy do drukowania.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: wysyłam plik kontrolny (%lu bajtów)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: wysyłam plik kontrolny (%u bajtów)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: wysyłam dane\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: wysyłam plik danych (%ld bajtów)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: wysyłam plik danych (%lld bajtów)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: wysyłam dane wydruku...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: wysyłam plik drukowania, %ld bajtów…\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: wysyłam plik drukowania, %lld bajtów…\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Składuję zlecenie LPR, %.0f%% zakończono…\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: nie można skontaktować się z drukarką, ustawiam w kolejce następnej " +"drukarki tej klasy…\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: używam domyślnej strefy AppleTalk \"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: czekam na zakończenie zlecenia…\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: czekam, aż drukarka stanie się dostępna...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "Koperta ISO B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (Oversize)" + +msgid "ISO B5 Envelope" +msgstr "Koperta ISO B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "Koperta ISO B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Niedozwolony znak kontrolny" + +msgid "Illegal main keyword string" +msgstr "Niedozwolony główny łańcuch słowa kluczowego" + +msgid "Illegal option keyword string" +msgstr "Niedozwolony łańcuch słowa kluczowego opcji" + +msgid "Illegal translation string" +msgstr "Niedozwolony łańcuch tłumaczenia" + +msgid "Illegal whitespace character" +msgstr "Niedozwolony biały znak" + +msgid "Ink/toner almost empty." +msgstr "Tusz lub toner jest niemal pusty." + +msgid "Ink/toner empty!" +msgstr "Tusz lub toner skończył się!" + +msgid "Ink/toner waste bin almost full." +msgstr "Zbiornik zużytego atramentu lub tonera jest niemal pełny." + +msgid "Ink/toner waste bin full!" +msgstr "Zbiornik zużytego atramentu lub tonera jest pełny!" + +msgid "Installable Options" +msgstr "Opcje instalowane" + +msgid "Installed" +msgstr "Zainstalowane" + +msgid "IntelliBar Label Printer" +msgstr "Drukarka etykiet IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Rygiel jest otwarty." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Błąd wewnętrzny" + +msgid "Internet Postage 2-Part" +msgstr "Etykieta Internet Postage, dwuczęściowa" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Etykieta Internet Postage, dwuczęściowa - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Etykieta Internet Postage, trzyczęściowa" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Etykieta Internet Postage, trzyczęściowa - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internetowy protokół druku" + +msgid "Invite Envelope" +msgstr "Koperta zaproszenia" + +msgid "Italian Envelope" +msgstr "Koperta włoska" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Zlecenie #%d nie może zostać ponownie uruchomione - brak plików!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Zlecenie #%d nie istnieje!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Zlecenie #%d zostało już przerwane - nie można anulować." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Zlecenie #%d zostało już anulowane - nie można anulować." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Zlecenie #%d zostało już zakończone - nie można anulować." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Zlecenie #%d zostało zakończone i nie może zostać zmienione!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Zlecenie #%d nie zostało zakończone!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Zlecenie #%d nie zostało wstrzymane do uwierzytelnienia!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Zlecenie #%d nie zostało wstrzymane!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Zlecenie #%s nie istnieje!" + +#, c-format +msgid "Job %d not found!" +msgstr "Nie znaleziono zlecenia %d!" + +msgid "Job Completed" +msgstr "zlecenie zakończone" + +msgid "Job Created" +msgstr "utworzono zlecenie" + +msgid "Job ID: " +msgstr "ID zlecenia: " + +msgid "Job Options Changed" +msgstr "zmieniono opcje zlecenia" + +msgid "Job Stopped" +msgstr "zlecenie zatrzymane" + +msgid "Job UUID: " +msgstr "UUID zlecenia: " + +msgid "Job is completed and cannot be changed." +msgstr "Zlecenie zostało zakończone i nie może zostać zmienione." + +msgid "Job operation failed:" +msgstr "Operacja zlecenia nie powiodła się:" + +msgid "Job state cannot be changed." +msgstr "Stan zlecenia nie może zostać zmieniony." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Subskrypcje zlecenia nie mogą zostać ponowione!" + +msgid "Jobs" +msgstr "Zlecenia" + +msgid "Kaku2 Envelope" +msgstr "Koperta Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Koperta Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Host lub drukarka LPD/LPR" + +msgid "Label Printer" +msgstr "Drukarka etykiet" + +msgid "Label Top" +msgstr "Wierzch etykiety" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Język \"%s\" jest nieobsługiwany!" + +msgid "Large Address" +msgstr "Duży adres" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Duży adres - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "Lekki" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Wiersz dłuższy niż maksymalnie dozwolony (255 znaków)" + +msgid "List Available Printers" +msgstr "Pokaż dostępne drukarki" + +msgid "Location: " +msgstr "Miejsce: " + +msgid "Long-Edge (Portrait)" +msgstr "Portretowy" + +msgid "Make and Model: " +msgstr "Marka i model: " + +msgid "Manual Feed" +msgstr "Ręczne podawanie papieru" + +msgid "Media Dimensions: " +msgstr "Wymiary nośnika: " + +msgid "Media Limits: " +msgstr "Ograniczenia nośnika: " + +msgid "Media Name: " +msgstr "Nazwa nośnika: " + +msgid "Media Size" +msgstr "Rozmiar nośnika" + +msgid "Media Source" +msgstr "Źródło nośnika" + +msgid "Media Tracking" +msgstr "Śledzenie nośnika" + +msgid "Media Type" +msgstr "Rodzaj nośnika" + +msgid "Media jam!" +msgstr "Zacięcie nośnika!" + +msgid "Media tray almost empty." +msgstr "Podajnik nośnika jest niemal pusty." + +msgid "Media tray empty!" +msgstr "Podajnik nośnika jest pusty!" + +msgid "Media tray missing!" +msgstr "Brak podajnika nośnika!" + +msgid "Media tray needs to be filled." +msgstr "Trzeba napełnić podajnik nośnika." + +msgid "Medium" +msgstr "Średni" + +msgid "Memory allocation error" +msgstr "Błąd przydziału pamięci" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Brakujący nagłówek PPD-Adobe-4.x" + +msgid "Missing asterisk in column 1" +msgstr "Brakująca gwiazdka w kolumnie 1" + +msgid "Missing document-number attribute!" +msgstr "Brakujący atrybut document-number!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Brakujący cudzysłów w wierszu %d!" + +msgid "Missing form variable!" +msgstr "Brakująca zmienna formularza!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Brakująca cecha notify-subscription-ids!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Brakuje cecha requesting-user-name!" + +msgid "Missing required attributes!" +msgstr "Brakuje wymaganych cech!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Brakująca wartość w wierszu %d!" + +msgid "Missing value string" +msgstr "Brakujący łańcuch wartości" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Zmień klasę" + +msgid "Modify Printer" +msgstr "Zmień drukarkę" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Koperta Monarch" + +msgid "Move All Jobs" +msgstr "Przenieś wszystkie zlecenia" + +msgid "Move Job" +msgstr "Przenieś zlecenie" + +msgid "Moved Permanently" +msgstr "Trwale przeniesione" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: zaakceptowano plik druku - ID zlecenia %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: zaakceptowano plik drukowania - nieznane ID zlecenia.\n" + +msgid "NULL PPD file pointer" +msgstr "PUSTY wskaźnik pliku PPD" + +msgid "Name OID uses indefinite length" +msgstr "OID nazwy używa nieskończonej długości" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Nigdy" + +msgid "New Stylus Color Series" +msgstr "New Stylus Color Series" + +msgid "New Stylus Photo Series" +msgstr "New Stylus Photo Series" + +msgid "No" +msgstr "Nie" + +msgid "No Content" +msgstr "Brak zawartości" + +msgid "No PPD name!" +msgstr "Brak nazwy PPD!" + +msgid "No VarBind SEQUENCE" +msgstr "Brak VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Brak zainstalowanych sterowników drukarek dla Windows!" + +msgid "No active connection" +msgstr "Brak aktywnego połączenia" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Brak aktywnych zadań na %s!" + +msgid "No attributes in request!" +msgstr "Brak cech w żądaniu!" + +msgid "No authentication information provided!" +msgstr "Nie dostarczono informacji o uwierzytelnianiu!" + +msgid "No community name" +msgstr "Brak community name" + +msgid "No default printer" +msgstr "Brak domyślnej drukarki" + +msgid "No destinations added." +msgstr "Nie dodano celów." + +msgid "No error-index" +msgstr "Brak error-index" + +msgid "No error-status" +msgstr "Brak error-status" + +msgid "No file!?!" +msgstr "Brak pliku?!?" + +msgid "No modification time!" +msgstr "Brak czasu zmiany!" + +msgid "No name OID" +msgstr "Brak OID nazwy" + +msgid "No printer name!" +msgstr "Brak nazwy drukarki!" + +msgid "No printer-uri found for class!" +msgstr "Nie znaleziono printer-uri dla tej klasy!" + +msgid "No printer-uri found!" +msgstr "Nie znaleziono printer-uri!" + +msgid "No printer-uri in request!" +msgstr "Żądanie nie zawiera printer-uri!" + +msgid "No request-id" +msgstr "Brak request-id" + +msgid "No subscription attributes in request!" +msgstr "Brak cech subskrypcji w żądaniu!" + +msgid "No subscriptions found." +msgstr "Błędne ID subskrypcji." + +msgid "No variable-bindings SEQUENCE" +msgstr "Brak variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "Brak nazwy wersji" + +msgid "Non-continuous (Mark sensing)" +msgstr "Nieciągły (Mark sensing)" + +msgid "Non-continuous (Web sensing)" +msgstr "Nieciągły (Web sensing)" + +msgid "Normal" +msgstr "Zwykły" + +msgid "Not Found" +msgstr "Nie znaleziono" + +msgid "Not Implemented" +msgstr "Niezaimplementowane" + +msgid "Not Installed" +msgstr "Niezainstalowane" + +msgid "Not Modified" +msgstr "Niezmienione" + +msgid "Not Supported" +msgstr "Nieobsługiwane" + +msgid "Not allowed to print." +msgstr "Brak zgody na druk." + +msgid "Note" +msgstr "Notatka" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC jest niemal zużyty." + +msgid "OPC at end-of-life!" +msgstr "OPC jest zużyty!" + +msgid "Off (1-Sided)" +msgstr "Jednostronny" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Pomoc internetowa" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "Otwarcie %s nie powiodło się: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup nie poprzedzony przez CloseGroup" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI nie poprzedzony przez CloseUI/JCLCloseUI" + +msgid "Operation Policy" +msgstr "Polityka operacji" + +msgid "Options Installed" +msgstr "Zainstalowane opcje" + +msgid "Options: " +msgstr "Opcje: " + +msgid "Out of toner!" +msgstr "Brak tonera!" + +msgid "Output Mode" +msgstr "Tryb wyjścia" + +msgid "Output bin almost full." +msgstr "Odbiornik jest niemal pełny." + +msgid "Output bin full!" +msgstr "Odbiornik jest pełny!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Wyjście dla drukarki %s zostało wysłane do %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Wyjście dla drukarki %s zostało wysłane do zdalnej drukarki %s na %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Wyjście dla drukarki %s/%s zostało wysłane do %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"Wyjście dla drukarki %s/%s zostało wysłane do zdalnej drukarki %s na %s\n" + +msgid "Output tray missing!" +msgstr "Brak odbiornika!" + +msgid "PASS\n" +msgstr "SUKCES\n" + +msgid "PCL Laser Printer" +msgstr "Drukarka laserowa PCL" + +msgid "PRC1 Envelope" +msgstr "Koperta PRC1" + +msgid "PRC10 Envelope" +msgstr "Koperta PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Koperta PRC2" + +msgid "PRC3 Envelope" +msgstr "Koperta PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (oversize)" + +msgid "PRC4 Envelope" +msgstr "Koperta PRC4" + +msgid "PRC5 Envelope" +msgstr "Koperta PRC5" + +msgid "PRC6 Envelope" +msgstr "Koperta PRC6" + +msgid "PRC7 Envelope" +msgstr "Koperta PRC7" + +msgid "PRC8 Envelope" +msgstr "Koperta PRC8" + +msgid "PRC9 Envelope" +msgstr "Koperta PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Pakiet nie zawiera Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Pakiet nie rozpoczyna się od SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Hasło dla %s na %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Wymagane jest hasło dla %s, aby uzyskać dostęp do %s przez Sambę:" + +msgid "Pause Class" +msgstr "Wstrzymanie klasy" + +msgid "Pause Printer" +msgstr "Wstrzymanie drukarki" + +msgid "Peel-Off" +msgstr "Peel-Off" + +msgid "Personal Envelope" +msgstr "Koperta osobista" + +msgid "Photo" +msgstr "Zdjęcie" + +msgid "Photo Labels" +msgstr "Etykiety zdjęć" + +msgid "Plain Paper" +msgstr "Zwykły papier" + +msgid "Policies" +msgstr "Zasady" + +msgid "Port Monitor" +msgstr "Monitor portów" + +msgid "PostScript Printer" +msgstr "Drukarka PostScriptowa" + +msgid "Postcard" +msgstr "Kartka pocztowa" + +msgid "Print Density" +msgstr "Gęstość druku" + +msgid "Print Job:" +msgstr "Zlecenie drukowania:" + +msgid "Print Mode" +msgstr "Tryb drukowania" + +msgid "Print Rate" +msgstr "Prędkość drukowania" + +msgid "Print Self-Test Page" +msgstr "Drukuj stronę testową" + +msgid "Print Speed" +msgstr "Prędkość druku" + +msgid "Print Test Page" +msgstr "Wydrukuj stronę próbną" + +msgid "Print and Cut" +msgstr "Drukuj i obetnij" + +msgid "Print and Tear" +msgstr "Drukuj i oderwij" + +msgid "Printed For: " +msgstr "Druk dla: " + +msgid "Printed From: " +msgstr "Druk z: " + +msgid "Printed On: " +msgstr "Druk na: " + +msgid "Printer Added" +msgstr "Dodano drukarkę" + +msgid "Printer Default" +msgstr "Domyślna drukarka" + +msgid "Printer Deleted" +msgstr "Usunięto drukarkę" + +msgid "Printer Modified" +msgstr "Zmieniono drukarkę" + +msgid "Printer Name: " +msgstr "Nazwa drukarki: " + +msgid "Printer Paused" +msgstr "Drukarka wstrzymana" + +msgid "Printer Settings" +msgstr "Ustawienia drukarki" + +msgid "Printer offline." +msgstr "Drukarka nie gotowa." + +msgid "Printer:" +msgstr "Drukarka:" + +msgid "Printers" +msgstr "Drukarki" + +msgid "Purge Jobs" +msgstr "Wyczyść zlecenia" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Przekroczono limit miejsca." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Kolejność Właściciel Zlecenie Pliki " +"Całkowity rozmiar\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Kolejność Właściciel Drukowanie Zlecenie " +"Pliki Całkowity rozmiar\n" + +msgid "Reject Jobs" +msgstr "Odrzuć zlecenia" + +msgid "Reprint After Error" +msgstr "Drukuj ponownie po błędzie" + +msgid "Request Entity Too Large" +msgstr "Encja zapytania zbyt długa" + +msgid "Resolution" +msgstr "Rozdzielczość" + +msgid "Resume Class" +msgstr "Wznowienie klasy" + +msgid "Resume Printer" +msgstr "Wznowienie drukarki" + +msgid "Return Address" +msgstr "Adres nadawcy" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Adres nadawcy - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Przewiń" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Uruchamiam polecenie: %s %s -N -A %s -c \"%s\"\n" + +msgid "SCSI Printer" +msgstr "Drukarka SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE używa nieskończonej długości" + +msgid "See Other" +msgstr "Zobacz inne" + +#, c-format +msgid "Serial Port #%d" +msgstr "Port szeregowy #%d" + +msgid "Server Restarted" +msgstr "Uruchomiono serwer ponownie" + +msgid "Server Security Auditing" +msgstr "Sprawdzenie bezpieczeństwa serwera" + +msgid "Server Started" +msgstr "Uruchomiono serwer" + +msgid "Server Stopped" +msgstr "Zatrzymano serwer" + +msgid "Service Unavailable" +msgstr "Usługa niedostępna" + +msgid "Set Allowed Users" +msgstr "Ustaw dozwolonych użytkowników" + +msgid "Set As Server Default" +msgstr "Ustaw jako domyślne serwera" + +msgid "Set Class Options" +msgstr "Ustaw opcje klasy" + +msgid "Set Printer Options" +msgstr "Ustaw opcje drukarki" + +msgid "Set Publishing" +msgstr "Ustaw publikowanie" + +msgid "Shipping Address" +msgstr "Adres wysyłki" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Adres wysyłki - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Poziome" + +msgid "Special Paper" +msgstr "Papier specjalny" + +msgid "Standard" +msgstr "Standardowy" + +msgid "Starting Banner" +msgstr "Uruchamiam baner" + +msgid "Statement" +msgstr "Stwierdzenie" + +msgid "Stylus Color Series" +msgstr "Stylus Color Series" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo Series" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Przełączanie protokołów" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (oversize)" + +msgid "Tear" +msgstr "Tear" + +msgid "Tear-Off" +msgstr "Tear-Off" + +msgid "Tear-Off Adjust Position" +msgstr "Korekcja pozycji odrywania" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Nie można znaleźć pliku PPD \"%s\"." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Nie można otworzyć pliku PPD \"%s\": %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Nazwa klasy może zawierać tylko do 127 drukowalnych znaków i nie może " +"zawierać spacji, ukośników (/) lub znaku #." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Cecha notify-lease-duration nie może być używana z subskrypcjami zadań." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Wartość notify-user-data jest za duża (%d > 63 oktety)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Nazwa drukarki może zawierać tylko do 127 drukowalnych znaków i nie może " +"zawierać spacji, ukośników (/) lub znaku #." + +msgid "The printer or class is not shared!" +msgstr "Drukarka lub klasa nie jest udostępniana!" + +msgid "The printer or class was not found." +msgstr "Drukarka lub klasa nie została znaleziona." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "printer-uri \"%s\" zawiera nieprawidłowe znaki." + +msgid "The printer-uri attribute is required!" +msgstr "Wymagana jest cecha printer-uri!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"printer-uri musi być w formie \"ipp://NAZWA_KOMPUTERA/classes/NAZWA_KLASY\"." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"printer-uri musi być w formie \"ipp://NAZWA_KOMPUTERA/printers/NAZWA_DRUKARKI" +"\"." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Nazwa subskrypcji nie może zawierać spacji, ukośników (/), pytajników (?) " +"lub znaku #." + +msgid "There are too many subscriptions." +msgstr "Jest zbyt wiele subskrypcji." + +msgid "Thermal Transfer Media" +msgstr "Nośnik druku termicznego" + +msgid "Title: " +msgstr "Tytuł: " + +msgid "Toner low." +msgstr "Niski poziom tonera." + +msgid "Too many active jobs." +msgstr "Za dużo aktywnych zadań." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Zbyt wiele wartości job-sheets (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Zbyt wiele wartości printer-state-reasons (%d > %d)!" + +msgid "Transparency" +msgstr "Przezroczystość" + +msgid "Tray" +msgstr "Podajnik" + +msgid "Tray 1" +msgstr "Podajnik 1" + +msgid "Tray 2" +msgstr "Podajnik 2" + +msgid "Tray 3" +msgstr "Podajnik 3" + +msgid "Tray 4" +msgstr "Podajnik 4" + +msgid "URI Too Long" +msgstr "Zbyt długi URI" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Legal" + +msgid "US Legal (Oversize)" +msgstr "US Legal (Oversize)" + +msgid "US Letter" +msgstr "US Letter" + +msgid "US Letter (Oversize)" +msgstr "US Letter (Oversize)" + +msgid "US Letter (Small)" +msgstr "US Letter (Small)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Port szeregowy USB #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Nie można uzyskać dostępu do pliku cupsd.conf:" + +msgid "Unable to add RSS subscription:" +msgstr "Nie można dodać subskrypcji RSS:" + +msgid "Unable to add class:" +msgstr "Nie można dodać klasy:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Nie można dodać zlecenia do celu \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Nie można dodać drukarki:" + +msgid "Unable to allocate memory for file types!" +msgstr "Nie można przydzielić pamięci dla rodzaju plików!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Nie można wycofać subskrypcji RSS:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Nie można zmienić cechy printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Nie można zmienić drukarki:" + +msgid "Unable to change server settings:" +msgstr "Nie można zmienić ustawień serwera:" + +msgid "Unable to connect to host." +msgstr "Nie można połączyć się z hostem." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Nie można skopiować 64 bitowych plików sterowników drukarek CUPS (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Nie można skopiować 64 bitowych plików sterowników drukarek Windows (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Nie można skopiować plików sterowników drukarek CUPS (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Nie można skopiować pliku PPD - %s!" + +msgid "Unable to copy PPD file!" +msgstr "Nie można skopiować pliku PPD!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Nie można skopiować plików sterowników drukarek Windows 2000 (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Nie można skopiować plików sterowników drukarek Windows 9x (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Nie można skopiować skryptu interfejsu - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Nie można utworzyć printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Nie można utworzyć pliku tymczasowego:" + +msgid "Unable to delete class:" +msgstr "Nie można usunąć klasy:" + +msgid "Unable to delete printer:" +msgstr "Nie można usunąć drukarki:" + +msgid "Unable to do maintenance command:" +msgstr "Nie można wykonać polecenia konserwacji:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Nie można zmienić plików cupsd.conf większych niż 1MB!" + +msgid "Unable to find destination for job!" +msgstr "Nie można znaleźć celu dla zlecenia!" + +msgid "Unable to find printer!\n" +msgstr "Nie można znaleźć drukarki!\n" + +msgid "Unable to get class list:" +msgstr "Nie można uzyskać listy klas:" + +msgid "Unable to get class status:" +msgstr "Nie można uzyskać statusu klasy:" + +msgid "Unable to get list of printer drivers:" +msgstr "Nie można uzyskać listy sterowników drukarek:" + +msgid "Unable to get printer attributes:" +msgstr "Nie można uzyskać cech drukarki:" + +msgid "Unable to get printer list:" +msgstr "Nie można uzyskać listy drukarek:" + +msgid "Unable to get printer status:" +msgstr "Nie można uzyskać statusu drukarki:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Nie można zainstalować plików sterowników drukarek Windows 2000 (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Nie można zainstalować plików sterowników drukarek Windows 9x (%d)!" + +msgid "Unable to modify class:" +msgstr "Nie można zmienić klasy:" + +msgid "Unable to modify printer:" +msgstr "Nie można zmienić drukarki:" + +msgid "Unable to move job" +msgstr "Nie można przenieść zlecenia" + +msgid "Unable to move jobs" +msgstr "Nie można przenieść zadań" + +msgid "Unable to open PPD file" +msgstr "Nie można otworzyć pliku PPD" + +msgid "Unable to open PPD file:" +msgstr "Nie można otworzyć pliku PPD:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Nie można otworzyć pliku cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Nie można otworzyć dokumentu %d w zleceniu %d!" + +msgid "Unable to print test page:" +msgstr "Nie można wydrukować strony testowej:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Nie można uruchomić \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Nie można wysłać polecenia do sterownika drukarki!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Nie można ustawić sterownika drukarki Windows (%d)!" + +msgid "Unable to set options:" +msgstr "Nie można ustawić opcji:" + +msgid "Unable to set server default:" +msgstr "Nie można ustalić domyślnych parametrów serwera:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Nie można wysłać pliku cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Nie można użyć starszego sterownika USB!\n" + +msgid "Unauthorized" +msgstr "Brak uwierzytelnienia" + +msgid "Units" +msgstr "Jednostki" + +msgid "Unknown" +msgstr "Nieznane" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Nieznane printer-error-policy \"%s\"!" + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Nieznane printer-op-policy \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Nieobsługiwany zestaw znaków \"%s\"!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Nieobsługiwana kompresja \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Nieobsługiwana cecha kompresji %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Nieobsługiwany format \"%s\"!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Nieobsługiwany format \"%s\"!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Nieobsługiwany format \"%s/%s\"!" + +msgid "Unsupported value type" +msgstr "Nieobsługiwany rodzaj wartości" + +msgid "Upgrade Required" +msgstr "Wymagane uaktualnienie" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Użycie:\n" +"\n" +" lpadmin [-h serwer] -d cel\n" +" lpadmin [-h serwer] -x cel\n" +" lpadmin [-h serwer] -p drukarka [-c dodaj-klasę] [-i interfejs] [-m " +"model]\n" +" [-r usuń-klasę] [-v urządzenie] [-D opis]\n" +" [-P plik-ppd] [-o nazwa=wartość]\n" +" [-u zezwól:użytkownik,użytkownik] [-u zabroń:" +"użytkownik,użytkownik]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Użycie: %s zlecenie użytkownik tytuł liczba_kopii opcje [plik]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Użycie: %s id_zlecenia użytkownik tytuł liczba_kopii opcje [plik]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Użycie: %s id_zlecenia użytkownik tytuł liczba_kopii opcje plik\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Użycie: cupsaddsmb [opcje] drukarka1 ... drukarkaN\n" +" cupsaddsmb [opcje] -a\n" +"\n" +"Opcje:\n" +" -E Szyfruj połączenie z serwerem\n" +" -H serwer_samba Użyj nazwy serwera SAMBA\n" +" -U użytkownik_samba Uwierzytelnienie nazwą użytkownika SAMBA\n" +" -a Eksportuj wszystkie drukarki\n" +" -h serwer_cups Użyj nazwy serwera CUPS\n" +" -v Podgląd (wyświetla polecenia)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Użycie: cupsctl [opcje] [param=wartość ... paramN=wartośćN]\n" +"\n" +"Opcje:\n" +"\n" +" -E Włącz szyfrowanie\n" +" -U nazwa_użytkownika Określ nazwę użytkownika\n" +" -h serwer[:port] Określ adres serwera\n" +"\n" +" --[no-]debug-logging Włącz lub wyłącz dziennik błędów\n" +" --[no-]remote-admin Włącz lub wyłącz zdalną administrację\n" +" --[no-]remote-any Pozwól lub zabroń dostęp przez Internet\n" +" --[no-]remote-printers Pokaż lub ukryj zdalne drukarki\n" +" --[no-]share-printers Włącz lub wyłącz udostępnianie drukarek\n" +" --[no-]user-cancel-any Pozwól lub zabroń użytkownikom anulowanie " +"dowolnego zlecenia\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Użycie: cupsd [-c plik-konfiguracji] [-f] [-F] [-h] [-l]\n" +"\n" +"-c plik-konfiguracji Wczytuje alternatywny plik konfiguracji\n" +"-f Uruchamia na pierwszym planie\n" +"-F Uruchamia na pierwszym planie, ale odłączone\n" +"-h Wyświetla wiadomości o użyciu\n" +"-l Uruchamia cupsd z launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Użycie: cupstestdsc [opcje] nazwapliku.ps [... nazwapliku.ps]\n" +" cupstestdsc [opcje] -\n" +"\n" +"Opcje:\n" +"\n" +" -h Wyświetla użycie programu\n" +"\n" +" Uwaga: ten program sprawdza tylko komentarze DSC, nie PostScriptowe.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Użycie: lpmove zlecenie/źródło cel\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Użycie: lpoptions [-h serwer] [-E] -d drukarka\n" +" lpoptions [-h serwer] [-E] [-p drukarka] -l\n" +" lpoptions [-h serwer] [-E] -p drukarka -o opcja[=wartość] ...\n" +" lpoptions [-h serwer] [-E] -x drukarka\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Użycie: lppasswd [-g nazwagrupy]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Użycie: lppasswd [-g nazwagrupy] [nazwaużytkownika]\n" +" lppasswd [-g nazwagrupy] -a [nazwaużytkownika]\n" +" lppasswd [-g nazwagrupy] -x [nazwaużytkownika]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Użycie: lpq [-P cel] [-U nazwaużytkownika] [-h nazwakomputera[:port]] [-l] " +"[+przerwanie]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Użycie: ppdc [opcje] plik.drv [ ... plikN.drv ]\n" +"Opcje:\n" +" -D nazwa=wartość Przypisuje wartość nazwanej zmiennej.\n" +" -I katalog-dołączeń Dodaje katalog do ścieżki wyszukiwania.\n" +" -c katalog.po Wczytuje podany katalog komunikatów.\n" +" -d katalog-wyjściowy Wybiera katalog wyjściowy.\n" +" -l język[,język,...] Ustala języki wyjścia (locale).\n" +" -m Używa nazwy ModelName jako nazwy pliku.\n" +" -t Testuje pliki PPD zamiast je generować.\n" +" -v Dodatkowe informacje (im więcej opcji v, tym więcej " +"informacji).\n" +" -z Kompresuje plik PPD za pomocą GNU zip.\n" +" --cr Znaki końca wiersza to CR (Mac OS 9).\n" +" --crlf Znaki końca wiersza to CR+LF (Windows).\n" +" --lf Znaki końca wiersza to LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Użycie: ppdhtml [opcje] plik.drv >plik.html\n" +" -D nazwa=wartość Przypisuje wartość nazwanej zmiennej.\n" +"Opcje:\n" +" -I katalog-dołączeń Dodaje katalog do ścieżki wyszukiwania.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Użycie: ppdi [opcje] plik.ppd [ ... plikN.ppd ]\n" +"Opcje:\n" +" -I katalog-dołączeń\n" +" -o plik.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Użycie: ppdmerge [opcje] plik.ppd [ ... plikN.ppd ]\n" +"Opcje:\n" +" -o plik.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Użycie: ppdpo [opcje] -o plik.po plik.drv [ ... plikN.drv ]\n" +"Opcje:\n" +" -D nazwa=wartość Przypisuje nazwanej zmiennej podaną wartość.\n" +" -I katalog-dołączeń Dodaje katalog do ścieżki wyszukiwania.\n" +" -v Dodatkowe informacje (im więcej opcji v, tym więcej " +"informacji).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Użycie: snmp [serwer_lub_adres_ip]\n" + +msgid "Value uses indefinite length" +msgstr "Wartość używa nieskończonej długości" + +msgid "VarBind uses indefinite length" +msgstr "VarBind używa nieskończonej długości" + +msgid "Version uses indefinite length" +msgstr "Version używa nieskończonej długości" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: dodaję tylko pierwszych %d znalezionych drukarek" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: dla opcji waiteof oczekiwano wartości logicznej \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: nie można odczytać żądania z kanału bocznego!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" +"WARNING: Opcja \"%s\" nie może zostać dołączona za pomocą IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: drukarka nie odpowiada\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: drukarka wysłała niespodziewany EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Serwer zdalny nie odpowiada bajtem statusu polecenia po %d " +"sekundach!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: zdalny serwer nie odpowiada bajtem statusu kontroli po %d " +"sekundach!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: zdalny serwer nie odpowiada bajtem statusu danych po %d sekundach!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: Upłynął czas oczekiwania polecenia SCSI (%d); ponawiam…\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Ten dokument nie jest zgodny z Konwencją struktury dokumentu Adobe " +"i może nie zostać wydrukowany prawidłowo!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: nie można otworzyć \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: nie da się wysłać żądania statusu PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: niespodziewany pakiet PAP typu %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: nieznany pakiet PAP typu %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Nieznany wybór \"%s\" dla opcji \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Nieznana opcja \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Nieobsługiwana częstotliwość bodów %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: spodziewana liczba dla opcji statusu \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: usuwalny: Serwer sieciowy '%s' jest zajęty; ponowię za %d " +"sekund...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Ostrzeżenie, brak zainstalowanych sterowników drukarek Windows 2000!" + +msgid "Yes" +msgstr "Tak" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Aby uzyskać dostęp do tej strony, użyj URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "Koperta You4" + +msgid "ZPL Label Printer" +msgstr "Drukarka etykiet ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "przerwane" + +msgid "canceled" +msgstr "anulowane" + +msgid "completed" +msgstr "zakończone" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: użyj opcji -f, aby wskazać plik do konwersji.\n" + +msgid "cups-deviced failed to execute." +msgstr "Nie powiodło się wykonanie cups-deviced." + +msgid "cups-driverd failed to execute." +msgstr "Nie powiodło się wykonanie cups-driverd." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: brak pliku PPD dla drukarki \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: nie można się połączyć z serwerem: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Nieznana opcja \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Nieznana opcja \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: oczekiwana nazwa pliku konfiguracji po opcji \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: nie da się uzyskać bieżącego katalogu!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: nieznany argument \"%s\" - przerywam!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: nieznana opcja \"%c\" - przerywam!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: obsługa launchd(8) nie została wkompilowana, uruchamianie w normalnym " +"trybie.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: nieprawidłowy numer dokumentu %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: nieprawidłowy kod zlecenia %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Może być określona tylko jedna nazwa pliku!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: nie da się uzyskać pliku zlecenia - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: opcja -q jest niezgodna z opcją -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: opcja -v jest niezgodna z opcją -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "urządzenie dla %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "urządzenie dla %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index używa nieskończonej długości" + +msgid "error-status uses indefinite length" +msgstr "error-status używa nieskończonej długości" + +msgid "held" +msgstr "wstrzymane" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tpomoc na temat poleceń\n" + +msgid "idle" +msgstr "bezczynna" + +msgid "job-printer-uri attribute missing!" +msgstr "Brakuje cechy job-printer-uri!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: nazwa klasy może zawierać tylko drukowalne znaki!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: oczekiwany PPD po opcji \"-P\"!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: oczekiwane allow/deny:userlist po opcji \"-u\"!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: oczekiwana klasa po opcji \"-r\"!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: oczekiwana nazwa klasy po opcji \"-c\"!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: oczekiwany opis po pocji \"-D\"!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: oczekiwane URI urządzenia po opcji \"-v\"!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: oczekiwane typy plików po opcji \"-I\"!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: oczekiwana nazwa komputera po opcji \"-h\"!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: oczekiwany interfejs po opcji \"-i\"!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: oczekiwane położenie po opcji \"-L\"!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: oczekiwany model po opcji \"-m\"!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: oczekiwana nazwa=wartość po opcji \"-o\"!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: oczekiwana drukarka po opcji \"-p\"!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: oczekiwana nazw drukarki po opcji \"-d\"!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: oczekiwana drukarka lub klasa po opcji \"-x\"!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: nie zobaczono żadnych nazw elementów!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: drukarka %s jest już elementem klasy %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: drukarka %s nie jest elementem klasy %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: nazwa drukarki może zawierać tylko drukowalne znaki!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można dodać drukarki do klasy:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: nie można połączyć się do serwera: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: nie można otworzyć pliku PPD \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: nie można otworzyć pliku \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można usunąć drukarki z klasy:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można ustawić pliku PPD:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można ustawić URI urządzenia:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można ustawić skryptu interfejsu lub pliku PPD:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można ustawić skryptu interfejsu:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Unable to set the printer description:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można ustawić położenia drukarki:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: nie można ustawić opcji drukarki:\n" +" Najpierw musi zostać określona nazwa drukarki!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: nieznana opcja zezwól/zabroń \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: nieznany argument \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: nieznana opcja \"%c\"!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "" +"lpadmin: ostrzeżenie - lista rodzajów zawartości została zignorowana!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: po --device-id spodziewany jest ciąg ID urządzenia 1284!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: po --language spodziewany jest język!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: po --make-and-model spodziewana jest marka i model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "" +"lpinfo: po --product spodziewany jest ciąg identyfikujący producenta!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: po --exclude-schemes spodziewana jest lista schematów!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: po --include-schemes spodziewana jest lista schematów!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: po --timeout spodziewany jest limit czasu!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: nieznany argument \"%s\"!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: nieznana opcja \"%c\"!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: nieznana opcja '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: nie można połączyć się z serwerem: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: nieznany argument \"%s\"!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: nieznana opcja \"%c\"!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: brak drukarek?!?\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: nie można dodać drukarki lub przykładu: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: nie można otworzyć pliku PPD dla %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: nie można otworzyć pliku PPD dla %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: nieznana drukarka lub klasa!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: tylko root może dodać lub usunąć hasła!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: plik hasła jest zajęty!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: plik hasła nie został zaktualizowany!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: przepraszam, hasła się nie zgadzają!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: przepraszam, hasło zostało odrzucone.\n" +"Hasło musi mieć co najmniej 6 znaków, nie może zawierać nazwy\n" +"użytkownika i musi zawierać co najmniej jedną literę i liczbę.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: przepraszam, hasła się nie zgadzają!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: nie można skopiować łańcucha hasła: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: nie można otworzyć pliku hasła: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: nie można zapisać do pliku hasła: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" +"lppasswd: utworzenie kopii zapasowej starego pliku hasła nie powiodło się: %" +"s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: zmiana nazwy pliku hasła nie powiodła się: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: użytkownik \"%s\" i grupa \"%s\" nie istnieją.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: błąd - %s nazw zmiennych środowiskowych z nieistniejącym celem \"%s" +"\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "elementy klasy %s:\n" + +msgid "no entries\n" +msgstr "brak wpisów\n" + +msgid "no system default destination\n" +msgstr "brak domyślnego celu systemowego\n" + +msgid "notify-events not specified!" +msgstr "notify-even jest nieokreślone!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI \"%s\" jest już użyte!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "URI notify-recipient-uri \"%s\" wykorzystuje nieznany schemat!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "%d notify-subscription-id nie dobre!" + +msgid "pending" +msgstr "oczekujące" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: dodaję katalog dołączeń \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: dodaję/uaktualniam tekst UI z %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: nieprawidłowa wartość logiczna (%s), linia %d w %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: nieprawidłowa nazwa rozdzielczości \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: nieprawidłowe słowo kluczowe statusu %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: nieprawidłowe zastąpienie zmiennej ($%c), linia %d w %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: w linii %d %s jest wybór bez opcji!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: powielone #po dla %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest definicja filtra!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest nazwa programu!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: w linii %d %s spodziewana jest wartość logiczna.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewany jest zestaw znaków po Font!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: w linii %d %s spodziewany jest kod wyboru.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: w linii %d %s spodziewana jest nazwa/tekst wyboru.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: w linii %d %s spodziewana jest kolejność kolorów dla ColorModel!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: w linii %d %s spodziewana jest przestrzeń kolorów dla ColorModel!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest kompresja dla ColorModel!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewany ciąg ograniczenia dla UIConstraints!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: w linii %d %s spodziewane słowo kluczowe określające typ sterownika po " +"DriverType!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "" +"ppdc: w linii %d %s spodziewany jest typ druku obustronnego po Duplex!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewane jest kodowanie po Font!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa pliku po #po dla %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest nazwa grupy/tekst.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest nazwa dołączanego pliku.\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest liczba całkowita.\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: spodziewane jest locale po #po dla, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po FileName, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po Font, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po Manufacturer, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po MediaSize, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po ModelName, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa po PCFileName, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa/tekst po %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa/tekst po Installable, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: spodziewana jest nazwa/tekst po Resolution, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: w linii %d %s spodziewana jest kombinacja nazwa/tekst dla ColorModel!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest nazwa opcji/tekst.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest nazwa opcji/tekst.\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewany jest typ opcji/tekst.\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: spodziewane jest pole zastąpienia po Resolution, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewana jest liczba rzeczywista.\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: w linii %d %s spodziwana jest rozdzielczość/typ nośnika po " +"ColorProfile!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: w linii %d %s spodziwana jest rozdzielczość/typ nośnika po " +"SimpleColorProfile!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: spodziewany jest wybieracz po %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: spodziewany jest status po Font, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: spodziewany jest ciąg znaków po Copyright, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: spodziewany jest ciąg znaków po Version, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: w linii %d %s spodziewane są dwie nazwy opcji!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: spodziewana jest wartość po %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: spodziewana jest wersja po Fon, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: nieprawidłowa nazwa pliku #include/#po \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: nieprawidłowy koszt filtru w linii %d %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: nieprawidłowy typ MIME dla filtru w linii %d %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: nieprawidłowa pusta nazwa programu dla filtru w linii %d %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: nieprawidłowy wybór opcji \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: nieprawidłowy typ opcji \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: wczytuję plik informacyjny sterownika \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: wczytuję komunikaty locale \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: wczytuję komunikaty z \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: na końcu \"%s\" brakuje #endif!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: w linii %d %s brakuje #if!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: brak katalogu komunikatów w locale %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: opcja %s zdefiniowana ponownie jako inny typ, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: ograniczenie opcji wymaga *name w linii %d %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: w linii %d %s jest zbyt dużo zagnieżdżonych instrukcji #if!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: nie można utworzyć pliku PPD \"%s\" - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: nie można utworzyć katalogu wyjścia %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: nie można utworzyć potoku wyjścia: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: nie można wykonać cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: nie można znaleźć pliku #po %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: nie można znaleźć pliku dołączenia \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: nie można znaleźć lokalizacji dla \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: nie można wczytać lokalizacji dla \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: niezdefiniowana zmienna (%s), linia %d w %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: nieznany typ sterownika %s, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: nieznany typ obustronny \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: nieznana wielkość nośnika \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: nieznany znacznik \"%s\", linia %d w %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: nieznane znaki wiodące w liczbie rzeczywistej \"%s\", linia %d w %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "" +"ppdc: niezakończony ciąg znaków, rozpoczynający się od %c, linia %d w %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: zapisuję %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: zapisuję pliki PPD do katalogu \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: nieprawidłowa wersja LanguageVersion \"%s\" w %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: ignoruję plik PPD %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: nie można wykonać kopii zapasowej %s w %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "drukarka %s jest wyłączona od %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "drukarka %s jest bezczynna. włączona od %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "drukarka %s drukuje teraz %s-%d. włączona od %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "drukarka %s/%s jest wyłączona od %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "drukarka %s/%s jest bezczynna. włączona od %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "drukarka %s/%s drukuje teraz %s-%d. włączona od %s\n" + +msgid "processing" +msgstr "przetwarzane" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "ID żądania to %s-%d (%d plików)\n" + +msgid "request-id uses indefinite length" +msgstr "request-id używa nieskończonej długości" + +msgid "scheduler is not running\n" +msgstr "planista nie jest uruchomiony" + +msgid "scheduler is running\n" +msgstr "planista jest uruchomiony\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "użycie stat z %s nie powiodło się: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\twyświetla stan demonów i kolejki\n" + +msgid "stopped" +msgstr "zlecenie zatrzymane" + +#, c-format +msgid "system default destination: %s\n" +msgstr "domyślny cel systemowy: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "domyślny cel systemowy: %s/%s\n" + +msgid "unknown" +msgstr "nieznane" + +msgid "untitled" +msgstr "nienazwane" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings używa nieskończonej długości" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " OSTRZEŻENIE Brakujący plik APDialogExtension \"%s\"\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " OSTRZEŻENIE Brakujący plik APPrinterIconPath \"%s\"\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: nie można otworzyć %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: nie można otworzyć %s - %s on line %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI (szarości)" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: brak URI urządzenia w wierszu poleceń i zmiennej środowiska " +#~ "DEVICE_URI!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: nie można utworzyć pliku tymczasowego - %s\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: nie można utworzyć pliku tymczasowego: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: nie można otworzyć pliku tymczasowego" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: filtr pdftops przerwał działanie po sygnale %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: filtr pdftops zakończył działanie ze stanem %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Nieznany błąd drukarki (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Użycie: convert [ opcje ]\n" +#~ "\n" +#~ "Opcje:\n" +#~ "\n" +#~ " -f plik Wybiera plik do konwersji (gdy pominięte, przyjmuje " +#~ "stdin)\n" +#~ " -o plik Wybiera plik do wygenerowania (gdy pominięte, " +#~ "przyjmuje stdout)\n" +#~ " -i typ/MIME Typ MIME na wejściu (gdy pominięte, przyjmowany " +#~ "automatycznie)\n" +#~ " -j typ/MIME Typ MIME na wyjściu (gdy pominięte, przyjmowany " +#~ "application/pdf)\n" +#~ " -P plik.ppd Plik PPD\n" +#~ " -a 'nazwa=wartość ...' Wybiera opcje\n" +#~ " -U użytkownik Wybiera nazwę użytkownika dla zlecenia\n" +#~ " -J tytuł Ustala tytuł\n" +#~ " -c kopie Ustala liczbę kopii\n" +#~ " -u Usuń plik PPD po zakończeniu\n" +#~ " -D Usuń plik wejściowy po zakończeniu\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Użycie: cupsfilter -m typ/mime [ opcje ] plik\n" +#~ "\n" +#~ "Opcje:\n" +#~ "\n" +#~ " -c cupsd.conf Wybiera plik cupsd.conf do użycia\n" +#~ " -j job-id[,N] Filtruje plik N z podanego zlecenia (domyślnie plik " +#~ "1)\n" +#~ " -n kopie Ustala liczbę kopii\n" +#~ " -o nazwa=wartość Ustala opcje\n" +#~ " -p plik.ppd Wybiera plik PPD\n" +#~ " -t tytuł Ustala tytuł\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Użycie: cupstestppd [options] plik1.ppd[.gz] [... plikN.ppd[.gz]]\n" +#~ " program | cupstestppd [opcje] -\n" +#~ "\n" +#~ "Opcje:\n" +#~ "\n" +#~ " -R katalog-główny Ustala inny katalog główny\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Zwraca ostrzeżenia zamiast błędów\n" +#~ " -q Działa bez komunikatów\n" +#~ " -r Używaj trybu otwarcia relaxed\n" +#~ " -v Mniej komunikatów\n" +#~ " -vv Dużo komunikatów\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: nie udało się utworzyć pliku tymczasowego: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: nie można utworzyć pliku tymczasowego - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: nie można utworzyć pliku tymczasowego: %s\n" diff --git a/locale/cups_pt.po b/locale/cups_pt.po new file mode 100644 index 0000000000..9a03538e80 --- /dev/null +++ b/locale/cups_pt.po @@ -0,0 +1,5709 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(tudo)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(sem)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d entradas\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tApós falha: continuar\n" + +msgid "\tAlerts:" +msgstr "\tAlertas:" + +msgid "\tBanner required\n" +msgstr "\tFaixa publicitária requerida\n" + +msgid "\tCharset sets:\n" +msgstr "\tConjuntos charset:\n" + +msgid "\tConnection: direct\n" +msgstr "\tLigação: directa\n" + +msgid "\tConnection: remote\n" +msgstr "\tLigação: remota\n" + +msgid "\tDefault page size:\n" +msgstr "\tTamanho de página predefinido:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tPitch predefinido:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tPredefinições de porta:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDescrição: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormato montado:\n" +"\tTipos de conteúdo: qualquer\n" +"\tTipos de impressora: desconhecido\n" + +msgid "\tForms allowed:\n" +msgstr "\tFormatos permitidos:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterface: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterface: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterface: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tLocalização: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tEm falha: sem alerta\n" + +msgid "\tUsers allowed:\n" +msgstr "\tUtilizadores permitidos:\n" + +msgid "\tUsers denied:\n" +msgstr "\tUtilizadores negados:\n" + +msgid "\tdaemon present\n" +msgstr "\tdaemon presente\n" + +msgid "\tno entries\n" +msgstr "\tsem entradas\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\timpressora está no periférico '%s' velocidade -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\timpressão desactivada\n" + +msgid "\tprinting is enabled\n" +msgstr "\timpressão activada\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tem fila para %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tcolocação em fila desactivada\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tcolocação em fila activada\n" + +msgid "\treason unknown\n" +msgstr "\tmotivo desconhecido\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" RESULTADOS DETALHADOS DO TESTE DE CONFORMIDADE\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Página 15, secção 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Página 15, secção 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Página 19, secção 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Página 20, secção 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Página 27, secção 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Página 42, secção 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Páginas 16-17, secção 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Páginas 42-45, secção 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Páginas 45-46, secção 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Páginas 48-49, secção 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Páginas 52-54, secção 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f bytes\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Predefinição%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Fabricante\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Produto\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\" em conflito com \"%s %s\"\n" +" (restrição=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s não tem opções correspondentes!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s partilha um prefixo comum com %s\n" +" REF: Página 15, secção 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Escolhas predefinidas em conflito!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Palavra-chave de opção de frente e verso %s pode não " +"funcionar como previsto e deve ter o nome Duplex!\n" +" REF: Página 122, secção 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN Ficheiro contém um misto de fins de linha CR, LF e CR LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding requerido por espec. de PPD 4.3\n" +" REF: Páginas 56-57, secção 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Linha %d só contém espaço em branco!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Fabricante requerido por espec. de PPD 4.3\n" +" REF: Páginas 58-59, secção 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN Ficheiros PPD não Windows devem utilizar fins de linha com " +"LF, e não CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Versão de PPD obsoleta %.1f!\n" +" REF: Página 42, secção 5.2" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName superior a 8.3 viola espec. de PPD\n" +" REF: Páginas 61-62, secção 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocolos contêm PJL, mas atributos JCL não estão " +"especificados.\n" +" REF: Páginas 78-79, secção 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocolos contêm PJL e BCP; TBCP esperados.\n" +" REF: Páginas 78-79, secção 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName requerido por espec. de PPD 4.3\n" +" REF: Páginas 64-65, secção 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s não existe!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Escolha %s inválida %s!\n" +" REF: Página 122, secção 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Cadeia de tradução UTF-8 \"%s\" inválida para opção %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Cadeia de tradução UTF-8 \"%s\" inválida para opção %s, escolha %" +"s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Valor cupsFilter inválido \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s CupsICCProfile inválido %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Valor cupsPreFilter inválido \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s CupsUIConstraints inválido %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Idioma inválido \"%s\"!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s CupsUIConstraints vazio %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Cadeia de tradução inexistente \"%s\" para opção %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Cadeia de tradução inexistente \"%s\" para opção %s, escolha %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr "" +" %s Escolha inexistente *%s %s em UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr "" +" %s Escolha inexistente *%s %s em cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Ficheiro cupsFilter inexistente \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Ficheiro cupsICCProfile inexistente \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Ficheiro cupsPreFilter inexistente \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s CupsUIResolver inexistente %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Opção inexistente %s em UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Opção inexistente %s em cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Sem tradução base \"%s\" incluída no ficheiro!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s REQUERIDO %s não define a escolha Sem!\n" +" REF: Página 122, secção 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s valor hash colide com %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s causa um loop!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** %s os nomes da escolha %s e %s divergem apenas pela " +"utilização de maiúsculas/minúsculas!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s deve ser 1284DeviceID!\n" +" REF: Página 72, secção 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** Predefinição%s %s inválida\n" +" REF: Página 40, secção 4.5\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DefaultImageableArea %s inválida!\n" +" REF: Página 102, secção 5.15\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DefaultPaperDimension %s inválida!\n" +" REF: Página 103, secção 5.15\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** Atributo JobPatchFile inválido no ficheiro!\n" +" REF: Página 24, secção 3.4\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** Fabricante inválido (deve ser \"HP\")\n" +" REF: Página 211, tabela D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** Fabricante inválido (deve ser \"Oki\")\n" +" REF: Página 211, tabela D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ModelName inválido - \"%c\" não permitido na cadeia.\n" +" REF: Páginas 59-60, secção 5.3\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** PSVersion inválida - não \"(cadeia) int\".\n" +" REF: Páginas 62-64, secção 5.3\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** Produto inválido - não \"(cadeia)\".\n" +" REF: Página 62, secção 5.3\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ShortNickName inválido - superior a 31 car.\n" +" REF: Páginas 64-65, secção 5.3\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Escolha %s inválida %s!\n" +" REF: Página 84, secção 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Versão de ficheiro inválida \"%s\"\n" +" REF: Página 56, secção 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Versão de formato inválida \"%s\"\n" +" REF: Página 56, secção 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** LanguageEncoding %s inválida - deve ser ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** LanguageVersion %s inválida - deve ser Inglês!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FAIL** Impossível interpretar código de opção predefinida: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** Cadeia de tradução predefinida para opção %s escolha %s " +"contém caracteres de 8 bits!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** Cadeia de tradução predefinida para opção %s contém " +"caracteres de 8 bits!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Os nomes dos grupos%s e %s divergem apenas pela utilização " +"de maiúsculas/minúsculas!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Múltiplos casos de %s nome da escolha %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Os nomes das opções %s e %s divergem apenas pela utilização " +"de maiúsculas/minúsculas!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** Predefinição%s requerida\n" +" REF: Página 40, secção 4.5\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** DefaultImageableArea requerida\n" +" REF: Página 102, secção 5.15\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** DefaultPaperDimension requerida\n" +" REF: Página 103, secção 5.15\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FileVersion requerida\n" +" REF: Página 56, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FormatVersion requerida\n" +" REF: Página 56, secção 5.3\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** ImageableArea requerida para PageSize %s\n" +" REF: Página 41, secção 5.\n" +" REF: Página 102, secção 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** LanguageEncoding requerida\n" +" REF: Páginas 56-57, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** LanguageVersion requerida\n" +" REF: Páginas 57-58, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** Fabricante requerido\n" +" REF: Páginas 58-59, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ModelName requerido\n" +" REF: Páginas 59-60, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** NickName requerido\n" +" REF: Página 60, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** PCFileName requerido\n" +" REF: Páginas 61-62, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** PSVersion requerida\n" +" REF: Páginas 62-64, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** PageRegion requerida\n" +" REF: Página 100, secção 5.14\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** PageSize requerido\n" +" REF: Página 41, secção 5.\n" +" REF: Página 99, secção 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** PageSize requerido\n" +" REF: Páginas 99-100, secção 5.14\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** PaperDimension requerida para PageSize %s\n" +" REF: Página 41, secção 5.\n" +" REF: Página 103, secção 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** Produto requerido\n" +" REF: Página 62, secção 5.3\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ShortNickName requerido\n" +" REF: Páginas 64-65, secção 5.3\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERROS ENCONTRADOS\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" %%%%BoundingBox: inválida na linha %d!\n" +" REF: Página 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" %%%%Page: inválida na linha %d!\n" +" REF: Página 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" %%%%Pages: inválidas na linha %d!\n" +" REF: Página 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Linha %d tem mais de 255 caracteres (%d)!\n" +" REF: Página 25, Comprimento da Linha\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 inexistente na primeira linha!\n" +" REF: Página 17, 3.1 Documentos de Conformidade\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Comentário %%EndComments inexistente!\n" +" REF: Página 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Comentário %%BoundingBox: inexistente ou inválido!\n" +" REF: Página 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Comentários %%Page: inexistentes ou inválidos!\n" +" REF: Página 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Comentário %%Pages: inexistente ou inválido!\n" +" REF: Página 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " SEM ERROS\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Detectadas %d linhas que excedem 255 caracteres!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Demasiados comentários %%BeginDocument!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Demasiados comentários %%EndDocument!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Aviso: ficheiro contém dados binários!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Aviso: sem comentário %%EndComments no ficheiro!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Aviso: versão obsoleta de DSC %.1f no ficheiro!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** Impossível abrir ficheiro PPD - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** Impossível abrir ficheiro PPD - %s na linha %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "Envelope n.º 10" + +msgid "#11 Envelope" +msgstr "Envelope n.º 11" + +msgid "#12 Envelope" +msgstr "Envelope n.º 12" + +msgid "#14 Envelope" +msgstr "Envelope n.º 14" + +msgid "#9 Envelope" +msgstr "Envelope n.º 9" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f milímetros" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f a %.0f x %.0f milímetros" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f polegadas" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f a %.2f x %.2f polegadas" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s aceita pedidos desde %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "Não é possível alterar %s." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s não é implementado pela versão CUPS de lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s não está preparada\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s está preparada\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s está preparada e a imprimir\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s não aceita pedidos desde %s-\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s não suportado!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s aceita pedidos desde %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s não aceita pedidos desde %s-\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [trabalho %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s falhou: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Não sei que fazer!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Erro - nomes de variáveis de ambiente %s inexistentes no destino \"%s" +"\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Erro - ID de trabalho inválido!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Erro - não é possível imprimir ficheiros e alterar trabalhos em " +"simultâneo!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Erro - não é possível imprimir a partir de stdin se fornecidos ficheiros " +"ou ID do trabalho!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Erro - conjunto de caracteres esperado após opção '-S'!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Erro - tipo de conteúdo esperado após opção '-T'!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Erro - cópias esperadas após opção '-n'!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Erro - contagem de cópias esperadas após opção '-#'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Erro - destino esperado após opção '-P'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Erro - destino esperado após opção '-b'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Erro - destino esperado após opção '-d'!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Erro - formato esperado após opção '-f'!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Erro - nome para reter esperado após opção '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Erro - nome de host esperado após opção '-h'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Erro - nome de host esperado após opção '-h'!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Erro - lista de modo esperada após opção '-y'!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Erro - nome esperado após opção '-%c'!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Erro - cadeia de opção esperada após opção '-o'!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Erro - lista de página esperada após opção '-P'!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Erro - prioridade esperada após opção '-%c'!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Erro - texto de motivo esperado após opção '-r'!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Erro - título esperado após opção '-t'!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Erro - nome de utilizador esperado após opção '-u'!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Erro - nome de utilizador esperado após opção '-u'!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Erro - valor esperado após opção '-%c'!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Erro - necessário \"concluído\", \"não concluído\" ou \"tudo\" após " +"opção '-W'!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Erro - sem destino predefinido disponível.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Erro - prioridade deve ser entre 1 e 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Erro - programador não responde!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Erro - demasiados ficheiros - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Erro - não é possível aceder a \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "" +"%s: Erro - não é possível criar fila de espera a partir de stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Erro - destino desconhecido \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Erro - destino desconhecido \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Erro - opção desconhecida '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Erro - opção desconhecida '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: ID de trabalho esperado após opção '-i'!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filtro \"%s\" não disponível: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Nome de destino inválido na lista \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Cadeia de filtro inválida \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Necessário ID do trabalho ('-i jobid') antes de '-H reiniciar'!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Sem filtro para converter de %s/%s para %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Operação falhou: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Sem suporte de encriptação compilado!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Não é possível ligar ao servidor\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Não é possível contactar o servidor!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Não é possível determinar tipo MIME de \"%s\"!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Não é possível abrir %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Não é possível abrir o ficheiro PDF: %s na linha %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "" +"%s: Não é possível ler a base de dados MIME a partir de \"%s\" ou \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Destino desconhecido \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Destino desconhecido de tipo MIME %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Opção desconhecida '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Origem desconhecida de tipo MIME %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Aviso - modificador de formato '%c' não suportado - saída pode ser " +"incorrecta!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Aviso - opção de conjunto de caracteres ignorada!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Aviso - opção de tipo de conteúdo ignorada!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Aviso - opção de formato ignorada!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Aviso - opção de modo ignorada!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Erro - nomes de variáveis de ambiente %s inexistentes no destino \"%s" +"\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: Erro - opção=valor esperada após opção '-o'!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: Erro - sem destino predefinido disponível.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 pol./seg." + +msgid "1.25x0.25\"" +msgstr "1,25x0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25x2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 pol./seg." + +msgid "1.50x0.25\"" +msgstr "1,50x0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50x0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50x1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50x2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 pol./seg." + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/seg." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 pol./seg." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 pol./seg." + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/seg." + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/seg." + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/seg." + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 pol./seg." + +msgid "2-Sided Printing" +msgstr "Impressão dos 2 lados" + +msgid "2.00x0.37\"" +msgstr "2,00x0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00x0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00x1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00x1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00x2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00x3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00x4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00x5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25x0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25x1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25x4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25x5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38x5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 pol./seg." + +msgid "2.50x1.00\"" +msgstr "2,50x1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50x2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75x1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/seg." + +msgid "200 mm/sec." +msgstr "200 mm/seg." + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "Série de 24 pinos" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/seg." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 pol./seg." + +msgid "3.00x1.00\"" +msgstr "3,00x1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00x1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00x2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00x3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00x5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25x2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25x5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25x5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25x5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25x7,83\"" + +msgid "3.5\" Disk" +msgstr "Disco de 3,5\"" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Disco de 3,5\" - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50x1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/seg." + +msgid "300 mm/sec." +msgstr "300 mm/seg." + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 pol./seg." + +msgid "4.00x1.00\"" +msgstr "4,00x1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00x13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00x2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00x2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00x3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00x4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00x5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00x6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00x6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/seg." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 pol./seg." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 pol./seg." + +msgid "6.00x1.00\"" +msgstr "6,00x1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00x2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00x3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00x4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00x5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00x6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00x6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/seg." + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 pol./seg." + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 pol./seg." + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00x1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00x2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00x3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00x4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00x5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00x6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00x6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/seg." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 pol./seg." + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "Série de 9 pinos" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Comando de ajuda inválido desconhecido\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Palavra-passe Samba requerida para exportar recursos de impressora!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Nome de utilizador Samba requerido para exportar recursos de impressora!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Já existe uma classe com o nome \"%s\"!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Já existe uma impressora com o nome \"%s\"!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (extra grande)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (extra grande)" + +msgid "A4 (Small)" +msgstr "A4 (pequeno)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (extra grande)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Aceitar trabalhos" + +msgid "Accepted" +msgstr "Aceite(s)" + +msgid "Add Class" +msgstr "Adicionar classe" + +msgid "Add Printer" +msgstr "Adicionar impressora" + +msgid "Add RSS Subscription" +msgstr "Adicionar subscrição RSS" + +msgid "Address" +msgstr "Endereço" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Endereço - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administração" + +msgid "Always" +msgstr "Sempre" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Aplicador" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Tentativa de definir %s printer-state como valor inválido %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Grupos de atributos desordenados (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Ponteiro dests NULL inválido" + +msgid "Bad OpenGroup" +msgstr "OpenGroup inválido" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI inválidos" + +msgid "Bad OrderDependency" +msgstr "OrderDependency inválida" + +msgid "Bad Request" +msgstr "Pedido inválido" + +msgid "Bad SNMP version number" +msgstr "Número de versão SNMP inválido" + +msgid "Bad UIConstraints" +msgstr "UIConstraints inválidas" + +#, c-format +msgid "Bad copies value %d." +msgstr "Valor de cópias inválido %d." + +msgid "Bad custom parameter" +msgstr "Parâmetro personalizado inválido" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "URI de periférico inválido \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Device-uri \"%s\" inválido!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Esquema uri de periférico inválido \"%s\"!\n" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Document-format \"%s\" inválido!" + +msgid "Bad filename buffer!" +msgstr "Buffer de nome de ficheiro inválido!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Atributo de tipo de letra inválido: %s\n" + +msgid "Bad job-priority value!" +msgstr "Valor job-priority inválido!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Valor job-sheets \"%s\" inválido!" + +msgid "Bad job-sheets value type!" +msgstr "Tipo de valor job-sheets inválido!" + +msgid "Bad job-state value!" +msgstr "Valor job-state inválido!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Atributo job-uri \"%s\" inválido!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Notify-pull-method \"%s\" inválido!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Notify-recipient-uri URI \"%s\" inválido!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Valor number-up inválido %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Opção + escolha inválidas na linha %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Valores page-ranges inválidos %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Port-monitor \"%s\" inválido!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Valor printer-state inválido %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Número de versão pedido inválido %d.%d!" + +msgid "Bad subscription ID!" +msgstr "ID de subscrição inválido!" + +msgid "Banners" +msgstr "Faixas publicitárias" + +msgid "Billing Information: " +msgstr "Informação de facturação: " + +msgid "Bond Paper" +msgstr "Papel de escritura" + +msgid "C0 Envelope" +msgstr "Envelope C0" + +msgid "C1 Envelope" +msgstr "Envelope C1" + +msgid "C2 Envelope" +msgstr "Envelope C2" + +msgid "C3 Envelope" +msgstr "Envelope C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Envelope C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Envelope C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Envelope C6" + +msgid "C65 Envelope" +msgstr "Envelope C65" + +msgid "C7 Envelope" +msgstr "Envelope C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Impressora de etiquetas CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Cancelar subscrição RSS" + +msgid "Change Settings" +msgstr "Alterar definições" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Conjunto de caracteres \"%s\" não suportado!" + +msgid "Chou3 Envelope" +msgstr "Envelope Chou3" + +msgid "Chou4 Envelope" +msgstr "Envelope Chou4" + +msgid "Classes" +msgstr "Classes" + +msgid "Clean Print Heads" +msgstr "Limpar cabeças de impressão" + +msgid "Color" +msgstr "Cor" + +msgid "Color Mode" +msgstr "Modo de cor" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"É possível abreviar comandos. Comandos são:\n" +"\n" +"sair ajuda sair estado ?\n" + +msgid "Community name uses indefinite length" +msgstr "Nome comunitário com comprimento indefinido" + +msgid "Continue" +msgstr "Continuar" + +msgid "Continuous" +msgstr "Contínuo" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Não é possível procurar o tipo \"%s\"!" + +msgid "Cover open." +msgstr "Tampa aberta." + +msgid "Created" +msgstr "Criação" + +msgid "Created On: " +msgstr "Criação: " + +msgid "Custom" +msgstr "Personalizar" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Cortar" + +msgid "Cutter" +msgstr "Cortador" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "Envelope DL" + +msgid "Dark" +msgstr "Escuro" + +msgid "Darkness" +msgstr "Escurecimento" + +msgid "Delete Class" +msgstr "Apagar classe" + +msgid "Delete Printer" +msgstr "Apagar impressora" + +msgid "Description: " +msgstr "Descrição: " + +msgid "DeskJet Series" +msgstr "Série DeskJet" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Destino \"%s\" não está a aceitar trabalhos." + +msgid "Developer almost empty." +msgstr "Programador quase vazio." + +msgid "Developer empty!" +msgstr "Programador vazio!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Periférico: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Suporte térmico directo" + +msgid "Disabled" +msgstr "Inactivo" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "O documento %d não foi encontrado no trabalho %d." + +msgid "Door open." +msgstr "Porta aberta." + +msgid "Double Postcard" +msgstr "Postal duplo" + +msgid "Driver Name: " +msgstr "Nome do controlador: " + +msgid "Driver Version: " +msgstr "Versão do controlador: " + +msgid "Duplexer" +msgstr "Duplexer" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Não é possível alocar memória para info de página: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Não é possível alocar memória para matriz de páginas: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Impressora de etiquetas EPL1" + +msgid "EPL2 Label Printer" +msgstr "Impressora de etiquetas EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Detectado comentário %%BoundingBox: inválido!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Detectado comentário %%IncludeFeature: inválido!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Comentário %%Page: inválido no ficheiro!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Comentário %%PageBoundingBox: inválido no ficheiro!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Ficheiro de periférico SCSI inválido \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Ficheiro charset inválido %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Tipo charset inválido %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Valor de colunas inválido %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Valor cpi inválido %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Linha de descrição de tipo de letra inválida: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Valor lpi inválido %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Configuração de página inválida!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Orientação de texto inválida %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Largura de texto inválida %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: A impressora de destino não existe!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Detectado comentário %%BoundingBox: em duplicado!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Detectado comentário %%Pages: em duplicado!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Ficheiro de impressão vazio!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Erro %d ao enviar o pedido PAPSendData: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: Esperada cadeia entre aspas na linha %d de %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Erro fatal de USB!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Detectado comando HP-GL/2 inválido; impossível imprimir ficheiro!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog inexistente!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup inexistente!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "" +"ERROR: Valor inexistente na linha %d do ficheiro da faixa publicitária!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: É necessária uma linha msgid antes de quaisquer cadeias de tradução " +"na linha %d de %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Sem comentário %%BoundingBox: no cabeçalho!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Sem comentário %%Pages: no cabeçalho!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Sem URI de periférico em argv[0] ou na variável de ambiente " +"DEVICE_URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Tipos de letra inexistentes no ficheiro charset %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Sem páginas!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Sem papel!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: Variável de ambiente PRINTER não definida!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: O ficheiro de impressão não foi aceite (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: A impressora não responde\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: A impressora não responde!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: A impressora enviou um EOF inesperado\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: O host remoto não aceitou ficheiro de controlo (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: O host remoto não aceitou o ficheiro de dados (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Ocorreu um erro de tempo limite excedido ao enviar dados para a " +"impressora\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Não é possível adicionar o ficheiro %d ao trabalho: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Não é possível cancelar o trabalho %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Não é possível copiar o ficheiro PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Não é possível criar o socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: Não é possível criar o ficheiro de impressão comprimido temporário: %" +"s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Não é possível criar o ficheiro temporário" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Não é possível executar pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Não é possível executar o programa gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Não é possível executar o programa pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Não é possível separar pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Não é possível obter pedidos PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Não é possível obter a resposta PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: Não é possível obter o ficheiro PPD para a impressora \"%s\" - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Não é possível obter a zona AppleTalk predefinida" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Não é possível obter os atributos do trabalho %d (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Não é possível obter o estado da impressora (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Não é possível localizar a impressora '%s'!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Não é possível procurar a resposta PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Não é possível procurar impressoras AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Não é possível criar o endereço AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Não é possível abrir \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Não é possível abrir %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "" +"ERROR: Não é possível abrir o ficheiro da faixa publicitária \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Não é possível abrir o ficheiro de periférico \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Não é possível abrir o ficheiro \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Não é possível abrir o ficheiro \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Não é possível abrir o ficheiro de imagem para impressão!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Não é possível abrir o ficheiro de impressão \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Não é possível abrir o ficheiro de impressão %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Não é possível abrir o ficheiro de impressão %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: Não é possível abrir o ficheiro de impressão comprimido temporário: %" +"s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Não é possível imprimir %d colunas de texto!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Não é possível imprimir %dx%d página de texto!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Não é possível ler os dados de impressão" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Não é possível ler os dados de impressão!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Não é possível reservar a porta" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Não é possível atingir offset %ld no ficheiro - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Não é possível atingir offset %lld no ficheiro - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Não é possível enviar o comando LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Não é possível enviar o pedido de carga PAP" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Não é possível enviar o pedido de dados PAP inicial" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Não é possível enviar dados de impressão (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Não é possível enviar os dados de impressão!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Não é possível enviar o ficheiro de impressão para a impressora" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: Não é possível enviar trailing nul para a impressora" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Não é possível aguardar por pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Não é possível escrever %d bytes em \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Não é possível escrever %d bytes na impressora!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Não é possível escrever o ficheiro de controlo" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Não é possível escrever os dados de impressão" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Não é possível escrever dados de impressão: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Não é possível escrever dados de retícula no recurso!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Não é possível escrever no ficheiro temporário" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" +"ERROR: Não é possível escrever dados de documento não comprimidos: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Texto inesperado na linha %d de %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Valor de opção de encriptação desconhecido \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Ordem de ficheiro desconhecida \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Caracteres de formato desconhecido \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Formato desconhecido do catálogo de mensagens para \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Opção desconhecida \"%s\" com valor \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Modo de impressão desconhecido \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Valor de opção de versão desconhecido \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Valor de brilho não suportado %s ao utilizar brilho=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Valor gama não suportado %s ao utilizar gama=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Valor number-up não suportado %d ao utilizar number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Valor number-up-layout não suportado %s ao utilizar number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Valor page-border não suportado %s ao utilizar page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: Detectado excesso doc_printf (%d bytes); a interromper!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops saiu ao sinal %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops saiu com o estado %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: recuperável: Não é possível ligar à impressora; nova tentativa dentro " +"de 30 segundos...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() falhou" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: Não é possível fazer stat do ficheiro de impressão" + +msgid "Edit Configuration File" +msgstr "Editar ficheiro de configuração" + +msgid "Empty PPD file!" +msgstr "Ficheiro PPD vazio!" + +msgid "Ending Banner" +msgstr "Terminar faixa publicitária" + +msgid "Enter old password:" +msgstr "Introduza palavra-passe antiga:" + +msgid "Enter password again:" +msgstr "Introduza palavra-passe novamente:" + +msgid "Enter password:" +msgstr "Introduza palavra-passe:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Introduza o seu nome de utilizador e palavra-passe ou o nome de utilizador e " +"palavra-passe da raiz para aceder a esta página. Se utilizar a autenticação " +"Kerberos, certifique-se que tem um ticket de Kerberos válido." + +msgid "Envelope Feed" +msgstr "Alimentação de envelopes" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Política de Erros" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Erro: necessário nome de host após opção '-h'!\n" + +msgid "Every 10 Labels" +msgstr "A cada 10 etiquetas" + +msgid "Every 2 Labels" +msgstr "A cada 2 etiquetas" + +msgid "Every 3 Labels" +msgstr "A cada 3 etiquetas" + +msgid "Every 4 Labels" +msgstr "A cada 4 etiquetas" + +msgid "Every 5 Labels" +msgstr "A cada 5 etiquetas" + +msgid "Every 6 Labels" +msgstr "A cada 6 etiquetas" + +msgid "Every 7 Labels" +msgstr "A cada 7 etiquetas" + +msgid "Every 8 Labels" +msgstr "A cada 8 etiquetas" + +msgid "Every 9 Labels" +msgstr "A cada 9 etiquetas" + +msgid "Every Label" +msgstr "Todas as etiquetas" + +msgid "Expectation Failed" +msgstr "A expectativa não se concretizou" + +msgid "Export Printers to Samba" +msgstr "Exportar Impressoras para Samba" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Pasta de ficheiros" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Pasta de ficheiros - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"URIs do periférico do ficheiro foram desactivados! Para activar, consulte a " +"directiva FileDevice em \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Fólio" + +msgid "Forbidden" +msgstr "Proibido" + +msgid "Fuser temperature high!" +msgstr "Temperatura do fusor elevada!" + +msgid "Fuser temperature low!" +msgstr "Temperatura do fusor baixa!" + +msgid "General" +msgstr "Geral" + +msgid "Generic" +msgstr "Genérico" + +msgid "German FanFold" +msgstr "FanFold alemão" + +msgid "German FanFold Legal" +msgstr "FanFold legal alemão" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU com comprimento indefinido" + +msgid "Glossy Paper" +msgstr "Papel brilhante" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Obtive um atributo printer-uri, mas não job-id!" + +msgid "Grayscale" +msgstr "Níveis de cinzento" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Pasta suspensa" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Pasta suspensa - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk inactivo nas Preferências do Sistema\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk inactivo nas Preferências do Sistema.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: A cancelar trabalho de impressão...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Ligado à impressora...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: A ligar à impressora...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Ficheiro de controlo enviado com êxito\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Ficheiro de dados enviado com êxito\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: A formatar página %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: A carregar ficheiro de imagem...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: A procurar a impressora...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: A abrir a ligação\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" +"INFO: Ficheiro de impressão enviado; a aguardar conclusão da impressora...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Impressora ocupada; nova tentativa dentro de 10 segundos...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Impressora ocupada; nova tentativa dentro de 30 segundos...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Impressora ocupada; nova tentativa dentro de 5 segundos...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: A impressora não suporta IPP/%d.%d, a tentar IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "" +"INFO: A impressora está ocupada; nova tentativa dentro de 5 segundos...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: A impressora está actualmente sem ligação.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: A impressora está actualmente sem ligação.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: A impressora tem agora ligação.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: A impressora está sem ligação.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "" +"INFO: Impressora sem ligação; nova tentativa dentro de 30 segundos...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: A imprimir página %d, %d%% concluído...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: A imprimir página %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Preparada para imprimir.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: A enviar ficheiro de controlo (%lu bytes)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: A enviar ficheiro de controlo (%u bytes)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: A enviar dados\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: A enviar ficheiro de dados (%ld bytes)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: A enviar ficheiro de dados (%lld bytes)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: A enviar dados de impressão...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Ficheiro de impressão enviado, %ld bytes...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Ficheiro de impressão enviado, %lld bytes...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: A processar trabalho LPR, %.0f%% concluído...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Não é possível contactar a impressora; a colocar em fila na próxima " +"impressora na classe...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: A utilizar a zona AppleTalk predefinida \"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: A aguardar conclusão do trabalho...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: A aguardar até que a impressora fique disponível...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO Envelope B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (extra grande)" + +msgid "ISO B5 Envelope" +msgstr "ISO Envelope B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO Envelope B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Carácter de controlo ilegal" + +msgid "Illegal main keyword string" +msgstr "Cadeia de palavra-chave principal ilegal" + +msgid "Illegal option keyword string" +msgstr "Cadeia de palavra-chave de opção ilegal" + +msgid "Illegal translation string" +msgstr "Cadeia de tradução ilegal" + +msgid "Illegal whitespace character" +msgstr "Carácter de espaço em branco ilegal" + +msgid "Ink/toner almost empty." +msgstr "Tinta/toner quase vazio." + +msgid "Ink/toner empty!" +msgstr "Tinta/toner vazio!" + +msgid "Ink/toner waste bin almost full." +msgstr "Receptáculo de tinta/toner quase cheio." + +msgid "Ink/toner waste bin full!" +msgstr "Receptáculo de tinta/toner cheio!" + +msgid "Installable Options" +msgstr "Opções instaláveis" + +msgid "Installed" +msgstr "Instalado" + +msgid "IntelliBar Label Printer" +msgstr "Impressora de etiquetas IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Bloqueio aberto." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Erro interno" + +msgid "Internet Postage 2-Part" +msgstr "Envio pela Internet em 2 partes" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Envio pela Internet em 2 partes - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Envio pela Internet em 3 partes" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Envio pela Internet em 3 partes - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Protocolo de impressão via Internet" + +msgid "Invite Envelope" +msgstr "Envelope de convite" + +msgid "Italian Envelope" +msgstr "Envelope italiano" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Não é possível reiniciar o trabalho #%d - sem ficheiros!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Trabalho #%d não existe!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Trabalho #%d já interrompido - impossível cancelar." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Trabalho #%d já cancelado - impossível cancelar." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Trabalho #%d já concluído - impossível cancelar." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Trabalho #%d concluído; não é possível alterar!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Trabalho #%d não concluído!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Trabalho #%d não retido para autenticação!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Trabalho #%d não retido!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Trabalho #%s não existe!" + +#, c-format +msgid "Job %d not found!" +msgstr "Trabalho %d não encontrado!" + +msgid "Job Completed" +msgstr "Trabalho concluído" + +msgid "Job Created" +msgstr "Trabalho criado" + +msgid "Job ID: " +msgstr "ID do trabalho: " + +msgid "Job Options Changed" +msgstr "Opções de trabalho alteradas" + +msgid "Job Stopped" +msgstr "Trabalho parado" + +msgid "Job UUID: " +msgstr "UUID do trabalho: " + +msgid "Job is completed and cannot be changed." +msgstr "Trabalho concluído; não é possível alterar." + +msgid "Job operation failed:" +msgstr "Operação de trabalho falhou:" + +msgid "Job state cannot be changed." +msgstr "Não é possível alterar o estado do trabalho." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Não é possível renovar as subscrições do trabalho!" + +msgid "Jobs" +msgstr "Trabalhos" + +msgid "Kaku2 Envelope" +msgstr "Envelope Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Envelope Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Host ou impressora LPD/LPR" + +msgid "Label Printer" +msgstr "Impressora de etiquetas" + +msgid "Label Top" +msgstr "Parte superior da etiqueta" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Idioma \"%s\" não suportado!" + +msgid "Large Address" +msgstr "Endereço grande" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Endereço grande - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Série PCL 4/5" + +msgid "Light" +msgstr "Claro" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Linha excede máximo permitido (255 caracteres)" + +msgid "List Available Printers" +msgstr "Apresentar impressoras disponíveis" + +msgid "Location: " +msgstr "Localização: " + +msgid "Long-Edge (Portrait)" +msgstr "Margem longa (vertical)" + +msgid "Make and Model: " +msgstr "Marca e modelo: " + +msgid "Manual Feed" +msgstr "Alimentação manual" + +msgid "Media Dimensions: " +msgstr "Dimensões do suporte: " + +msgid "Media Limits: " +msgstr "Limites do suporte: " + +msgid "Media Name: " +msgstr "Nome do suporte: " + +msgid "Media Size" +msgstr "Tamanho do suporte" + +msgid "Media Source" +msgstr "Origem do suporte" + +msgid "Media Tracking" +msgstr "Controlo do suporte" + +msgid "Media Type" +msgstr "Tipo de suporte" + +msgid "Media jam!" +msgstr "Suporte encravado!" + +msgid "Media tray almost empty." +msgstr "Tabuleiro de suporte quase vazio." + +msgid "Media tray empty!" +msgstr "Tabuleiro de suporte vazio!" + +msgid "Media tray missing!" +msgstr "Tabuleiro de suporte inexistente!" + +msgid "Media tray needs to be filled." +msgstr "É necessário encher o tabuleiro de suporte." + +msgid "Medium" +msgstr "Médio" + +msgid "Memory allocation error" +msgstr "Erro de alocação de memória" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Cabeçalho PPD-Adobe-4.x inexistente" + +msgid "Missing asterisk in column 1" +msgstr "Asterisco inexistente na coluna 1" + +msgid "Missing document-number attribute!" +msgstr "Atributo document-number inexistente!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Aspas inexistentes na linha %d!" + +msgid "Missing form variable!" +msgstr "Variável de formato inexistente!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Atributo notify-subscription-ids inexistente!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Atributo requesting-user-name inexistente!" + +msgid "Missing required attributes!" +msgstr "Atributos necessários inexistentes!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Valor inexistente na linha %d!" + +msgid "Missing value string" +msgstr "Cadeia de valor inexistente" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modelo: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Modificar classe" + +msgid "Modify Printer" +msgstr "Modificar impressora" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Envelope Monarch" + +msgid "Move All Jobs" +msgstr "Mover todos os trabalhos" + +msgid "Move Job" +msgstr "Mover trabalho" + +msgid "Moved Permanently" +msgstr "Mudou-se permanentemente" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Ficheiro de impressão aceite - ID do trabalho %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Ficheiro de impressão aceite - ID do trabalho desconhecido.\n" + +msgid "NULL PPD file pointer" +msgstr "Ponteiro do ficheiro PPD NULL" + +msgid "Name OID uses indefinite length" +msgstr "Nome OID com comprimento indefinido" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Nunca" + +msgid "New Stylus Color Series" +msgstr "Nova série a cores Stylus" + +msgid "New Stylus Photo Series" +msgstr "Nova série fotográfica Stylus" + +msgid "No" +msgstr "Não" + +msgid "No Content" +msgstr "Sem conteúdo" + +msgid "No PPD name!" +msgstr "Sem nome PPD!" + +msgid "No VarBind SEQUENCE" +msgstr "Sem SEQUÊNCIA VarBind" + +msgid "No Windows printer drivers are installed!" +msgstr "Sem controladores de impressora Windows instalados!" + +msgid "No active connection" +msgstr "Nenhuma ligação activa" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Sem trabalhos activos em %s!" + +msgid "No attributes in request!" +msgstr "Sem atributos no pedido!" + +msgid "No authentication information provided!" +msgstr "Sem informações de autenticação fornecidas!" + +msgid "No community name" +msgstr "Sem nome comunitário" + +msgid "No default printer" +msgstr "Sem impressora predefinida" + +msgid "No destinations added." +msgstr "Sem destinos adicionados." + +msgid "No error-index" +msgstr "Sem error-index" + +msgid "No error-status" +msgstr "Sem error-status" + +msgid "No file!?!" +msgstr "Sem ficheiro?!" + +msgid "No modification time!" +msgstr "Tempo de modificação inexistente!" + +msgid "No name OID" +msgstr "Sem OID de nome" + +msgid "No printer name!" +msgstr "Nome de impressão inexistente!" + +msgid "No printer-uri found for class!" +msgstr "Nenhum printer-uri para a classe!" + +msgid "No printer-uri found!" +msgstr "Nenhum printer-uri encontrado!" + +msgid "No printer-uri in request!" +msgstr "Nenhum printer-uri no pedido!" + +msgid "No request-id" +msgstr "Sem request-id" + +msgid "No subscription attributes in request!" +msgstr "Sem atributos de subscrição no pedido!" + +msgid "No subscriptions found." +msgstr "Sem subscrições." + +msgid "No variable-bindings SEQUENCE" +msgstr "Sem SEQUÊNCIA variable-bindings" + +msgid "No version number" +msgstr "Sem número de versão" + +msgid "Non-continuous (Mark sensing)" +msgstr "Não contínuo (leitura de marcas)" + +msgid "Non-continuous (Web sensing)" +msgstr "Não contínuo (leitura Web)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "Não encontrado" + +msgid "Not Implemented" +msgstr "Não implementado" + +msgid "Not Installed" +msgstr "Não instalado" + +msgid "Not Modified" +msgstr "Não modificado" + +msgid "Not Supported" +msgstr "Não suportado" + +msgid "Not allowed to print." +msgstr "Sem permissão para imprimir." + +msgid "Note" +msgstr "Nota" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC quase em fim de vida." + +msgid "OPC at end-of-life!" +msgstr "OPC em fim de vida!" + +msgid "Off (1-Sided)" +msgstr "Inactivo (1 lado)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Ajuda online" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "abertura de %s falhou: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup sem um CloseGroup primeiro" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI sem um CloseUI/JCLCloseUI primeiro" + +msgid "Operation Policy" +msgstr "Política de Operação" + +msgid "Options Installed" +msgstr "Opções instaladas" + +msgid "Options: " +msgstr "Opções: " + +msgid "Out of toner!" +msgstr "Sem toner!" + +msgid "Output Mode" +msgstr "Modo de saída" + +msgid "Output bin almost full." +msgstr "Receptáculo de saída quase cheio." + +msgid "Output bin full!" +msgstr "Receptáculo de saída cheio!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Saída de impressora %s enviada para %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Saída de impressora %s enviada para impressora remota %s em %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Saída de impressora %s/%s enviada para %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "Saída de impressora %s/%s enviada para impressora remota %s em %s\n" + +msgid "Output tray missing!" +msgstr "Tabuleiro de saída inexistente!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "Impressora Laser PCL" + +msgid "PRC1 Envelope" +msgstr "Envelope PRC1" + +msgid "PRC10 Envelope" +msgstr "Envelope PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Envelope PRC2" + +msgid "PRC3 Envelope" +msgstr "Envelope PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (extra grande)" + +msgid "PRC4 Envelope" +msgstr "Envelope PRC4" + +msgid "PRC5 Envelope" +msgstr "Envelope PRC5" + +msgid "PRC6 Envelope" +msgstr "Envelope PRC6" + +msgid "PRC7 Envelope" +msgstr "Envelope PRC7" + +msgid "PRC8 Envelope" +msgstr "Envelope PRC8" + +msgid "PRC9 Envelope" +msgstr "Envelope PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "O pacote não contém Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "O pacote não começa por SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Palavra-passe para %s em %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Palavra-passe para %s requerida para aceder a %s via SAMBA: " + +msgid "Pause Class" +msgstr "Colocar a classe em pausa" + +msgid "Pause Printer" +msgstr "Colocar a impressora em pausa" + +msgid "Peel-Off" +msgstr "Destacar" + +msgid "Personal Envelope" +msgstr "Envelope pessoal" + +msgid "Photo" +msgstr "Fotografia" + +msgid "Photo Labels" +msgstr "Etiquetas de fotografias" + +msgid "Plain Paper" +msgstr "Papel normal" + +msgid "Policies" +msgstr "Políticas" + +msgid "Port Monitor" +msgstr "Monitor da porta" + +msgid "PostScript Printer" +msgstr "Impressora PostScript" + +msgid "Postcard" +msgstr "Postal" + +msgid "Print Density" +msgstr "Densidade de impressão" + +msgid "Print Job:" +msgstr "Imprimir trabalho:" + +msgid "Print Mode" +msgstr "Modo de impressão" + +msgid "Print Rate" +msgstr "Taxa de impressão" + +msgid "Print Self-Test Page" +msgstr "Imprimir página de teste automático" + +msgid "Print Speed" +msgstr "Velocidade de impressão" + +msgid "Print Test Page" +msgstr "Imprimir página de teste" + +msgid "Print and Cut" +msgstr "Imprimir e cortar" + +msgid "Print and Tear" +msgstr "Imprimir e rasgar" + +msgid "Printed For: " +msgstr "Impresso para: " + +msgid "Printed From: " +msgstr "Impresso a partir de: " + +msgid "Printed On: " +msgstr "Impresso a: " + +msgid "Printer Added" +msgstr "Impressora adicionada" + +msgid "Printer Default" +msgstr "Impressora predefinida" + +msgid "Printer Deleted" +msgstr "Impressora apagada" + +msgid "Printer Modified" +msgstr "Impressora modificada" + +msgid "Printer Name: " +msgstr "Nome da impressora: " + +msgid "Printer Paused" +msgstr "Impressora em pausa" + +msgid "Printer Settings" +msgstr "Definições da impressora" + +msgid "Printer offline." +msgstr "Impressora sem ligação." + +msgid "Printer:" +msgstr "Impressora:" + +msgid "Printers" +msgstr "Impressoras" + +msgid "Purge Jobs" +msgstr "Limpar trabalhos" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Quota atingida." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Classificação Proprietário Trabalho Ficheiro" +"(s) Tamanho total\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Classificação Proprietário Pri Trabalho " +"Ficheiros Tamanho total\n" + +msgid "Reject Jobs" +msgstr "Rejeitar trabalhos" + +msgid "Reprint After Error" +msgstr "Voltar a imprimir após o erro" + +msgid "Request Entity Too Large" +msgstr "Entidade do pedido demasiado extensa" + +msgid "Resolution" +msgstr "Resolução" + +msgid "Resume Class" +msgstr "Retomar classe" + +msgid "Resume Printer" +msgstr "Retomar impressora" + +msgid "Return Address" +msgstr "Endereço de devolução" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Endereço de devolução - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Retroceder" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Comando em execução: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "Impressora SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE com comprimento indefinido" + +msgid "See Other" +msgstr "Ver outros" + +#, c-format +msgid "Serial Port #%d" +msgstr "Porta de série n.º %d" + +msgid "Server Restarted" +msgstr "Servidor reiniciado" + +msgid "Server Security Auditing" +msgstr "Auditoria de segurança do servidor" + +msgid "Server Started" +msgstr "Servidor iniciado" + +msgid "Server Stopped" +msgstr "Servidor parado" + +msgid "Service Unavailable" +msgstr "Serviço indisponível" + +msgid "Set Allowed Users" +msgstr "Definir utilizadores permitidos" + +msgid "Set As Server Default" +msgstr "Definir como servidor predefinido" + +msgid "Set Class Options" +msgstr "Definir opções de classe" + +msgid "Set Printer Options" +msgstr "Definir opções de impressora" + +msgid "Set Publishing" +msgstr "Definir publicação" + +msgid "Shipping Address" +msgstr "Endereço de envio" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Endereço de envio - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Margem estreita (horizontal)" + +msgid "Special Paper" +msgstr "Papel especial" + +msgid "Standard" +msgstr "Padrão" + +msgid "Starting Banner" +msgstr "Iniciar faixa publicitária" + +msgid "Statement" +msgstr "Declaração" + +msgid "Stylus Color Series" +msgstr "Série a cores Stylus" + +msgid "Stylus Photo Series" +msgstr "Série fotográfica Stylus" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "A mudar de protocolo" + +msgid "Tabloid" +msgstr "Tablóide" + +msgid "Tabloid (Oversize)" +msgstr "Tablóide (extra grande)" + +msgid "Tear" +msgstr "Rasgar" + +msgid "Tear-Off" +msgstr "Descartar" + +msgid "Tear-Off Adjust Position" +msgstr "Descartar posição de ajuste" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Não é possível localizar o ficheiro PPD \"%s\"." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Não é possível abrir o ficheiro PPD \"%s\": %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"O nome de classe pode ter o máximo de 127 caracteres imprimíveis e não pode " +"ter espaços, barras (/) ou cardinal (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Não é possível utilizar o atributo notify-lease-duration com subscrições de " +"trabalho." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "O valor notify-user-data é demasiado grande (%d > 63 octetos)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"O nome de impressora pode ter o máximo de 127 caracteres imprimíveis e não " +"pode ter espaços, barras (/) ou cardinal (#)." + +msgid "The printer or class is not shared!" +msgstr "Impressora ou classe não partilhadas!" + +msgid "The printer or class was not found." +msgstr "Impressora ou classe não localizadas." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "O atributo printer-uri \"%s\" contém caracteres inválidos." + +msgid "The printer-uri attribute is required!" +msgstr "Necessário atributo printer-uri!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"O atributo printer-uri deve ser do formato \"ipp://HOSTNAME/classes/CLASSNAME" +"\"." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"O atributo printer-uri deve ser do formato \"ipp://HOSTNAME/printers/" +"PRINTERNAME\"." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"O nome de subscrição não pode ter espaços, barras (/), pontos de " +"interrogação (?) ou cardinal (#)." + +msgid "There are too many subscriptions." +msgstr "Existem demasiadas subscrições." + +msgid "Thermal Transfer Media" +msgstr "Suporte de transferência térmica" + +msgid "Title: " +msgstr "Título: " + +msgid "Toner low." +msgstr "Pouco toner." + +msgid "Too many active jobs." +msgstr "Demasiados trabalhos activos." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Demasiados valores job-sheets (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Demasiados valores printer-state-reasons (%d > %d)!" + +msgid "Transparency" +msgstr "Transparência" + +msgid "Tray" +msgstr "Bandeja" + +msgid "Tray 1" +msgstr "Bandeja 1" + +msgid "Tray 2" +msgstr "Bandeja 2" + +msgid "Tray 3" +msgstr "Bandeja 3" + +msgid "Tray 4" +msgstr "Bandeja 4" + +msgid "URI Too Long" +msgstr "URI demasiado longo" + +msgid "US Executive" +msgstr "Executivo EUA" + +msgid "US Fanfold" +msgstr "Fanfold EUA" + +msgid "US Ledger" +msgstr "Livro de contas EUA" + +msgid "US Legal" +msgstr "Legal EUA" + +msgid "US Legal (Oversize)" +msgstr "Legal EUA (extra grande)" + +msgid "US Letter" +msgstr "Carta EUA" + +msgid "US Letter (Oversize)" +msgstr "Carta EUA (extra grande)" + +msgid "US Letter (Small)" +msgstr "Carta EUA (pequena)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Porta de série USB n.º %d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Não é possível aceder ao ficheiro cupsd.conf:" + +msgid "Unable to add RSS subscription:" +msgstr "Não é possível adicionar a subscrição RSS:" + +msgid "Unable to add class:" +msgstr "Não é possível adicionar a classe:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Não é possível adicionar o trabalho ao destino \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Não é possível adicionar a impressora:" + +msgid "Unable to allocate memory for file types!" +msgstr "Não é possível alocar memória para tipos de ficheiros!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Não é possível cancelar a subscrição RSS:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Não é possível alterar o atributo printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Não é possível alterar a impressora:" + +msgid "Unable to change server settings:" +msgstr "Não é possível alterar as definições do servidor:" + +msgid "Unable to connect to host." +msgstr "Não é possível ligar ao host." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" +"Não é possível copiar os ficheiros de controladores de impressora CUPS de 64 " +"bits (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Não é possível copiar os ficheiros de controladores de impressora Windows de " +"64 bits (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Não é possível copiar ficheiros de recurso de impressora CUPS (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Não é possível copiar o ficheiro PPD - %s!" + +msgid "Unable to copy PPD file!" +msgstr "Não é possível copiar o ficheiro PPD!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"Não é possível copiar os ficheiros de controladores de impressora Windows " +"2000 (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" +"Não é possível copiar os ficheiros de controladores de impressora Windows 9x " +"(%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Não é possível copiar o script de interface - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Não é possível criar printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Não é possível criar o ficheiro temporário:" + +msgid "Unable to delete class:" +msgstr "Não é possível apagar a classe:" + +msgid "Unable to delete printer:" +msgstr "Não é possível apagar a impressora:" + +msgid "Unable to do maintenance command:" +msgstr "Não é possível executar o comando de manutenção:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Não é possível editar ficheiros cupsd.conf com mais de 1MB!" + +msgid "Unable to find destination for job!" +msgstr "Não é possível localizar o destino para o trabalho!" + +msgid "Unable to find printer!\n" +msgstr "Não é possível encontrar a impressora!\n" + +msgid "Unable to get class list:" +msgstr "Não é possível obter a lista de classes:" + +msgid "Unable to get class status:" +msgstr "Não é possível obter o estado da classe:" + +msgid "Unable to get list of printer drivers:" +msgstr "Não é possível obter a lista de recursos da impressora:" + +msgid "Unable to get printer attributes:" +msgstr "Não é possível obter os atributos da impressora:" + +msgid "Unable to get printer list:" +msgstr "Não é possível obter a lista de impressoras:" + +msgid "Unable to get printer status:" +msgstr "Não é possível obter o estado da impressora:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Não é possível instalar os ficheiros de controladores de impressora Windows " +"2000 (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"Não é possível instalar os ficheiros de controladores de impressora Windows " +"9x (%d)!" + +msgid "Unable to modify class:" +msgstr "Não é possível modificar a classe:" + +msgid "Unable to modify printer:" +msgstr "Não é possível modificar a impressora:" + +msgid "Unable to move job" +msgstr "Não é possível mover o trabalho" + +msgid "Unable to move jobs" +msgstr "Não é possível mover os trabalhos" + +msgid "Unable to open PPD file" +msgstr "Não é possível abrir o ficheiro PPD" + +msgid "Unable to open PPD file:" +msgstr "Não é possível abrir o ficheiro PPD:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Não é possível abrir o ficheiro cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Não é possível abrir o documento %d no trabalho %d!" + +msgid "Unable to print test page:" +msgstr "Não é possível imprimir a página de teste:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Não é possível executar \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Não é possível enviar o comando para o controlador de impressora!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Não é possível definir o controlador de impressora Windows (%d)!" + +msgid "Unable to set options:" +msgstr "Não é possível definir opções:" + +msgid "Unable to set server default:" +msgstr "Não é possível definir como servidor predefinido:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Não é possível carregar o ficheiro cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Não é possível usar o controlador de classe USB!\n" + +msgid "Unauthorized" +msgstr "Não autorizado" + +msgid "Units" +msgstr "Unidades" + +msgid "Unknown" +msgstr "Desconhecido" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Printer-error-policy desconhecida \"%s\"." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Printer-op-policy desconhecida \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Conjunto de caracteres \"%s\" não suportado!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Compressão não suportada \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Atributo de compressão não suportado %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Formato não suportado \"%s\"!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Formato não suportado '%s'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Formato não suportado %s/%s'!" + +msgid "Unsupported value type" +msgstr "Tipo de valor não suportado" + +msgid "Upgrade Required" +msgstr "Requer actualização" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Utilização:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "" +"Utilização: opções de cópias de título de utilizador %s job-id [nome do " +"ficheiro]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "" +"Utilização: opções de cópias de título de utilizador %s job-id [ficheiro]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "" +"Utilização: ficheiro de opções de cópias de título de utilizador %s job-id\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Utilização: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Opções:\n" +" -E Encriptar a ligação ao servidor\n" +" -H samba-server Utilizar o servidor SAMBA\n" +" -U samba-user Autenticar utilizando utilizador SAMBA\n" +" -a Exportar todas as impressoras\n" +" -h cups-server Utilizar o servidor CUPS\n" +" -v Verboso (mostrar comandos)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Utilização: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Opções:\n" +"\n" +" -E Activar encriptação\n" +" -U username Especificar nome de utilizador\n" +" -h server[:port] Especificar endereço de servidor\n" +"\n" +" --[no-]debug-logging Activar/desactivar registo da depuração\n" +" --[no-]remote-admin Activar/desactivar administração remota\n" +" --[no-]remote-any Permitir/impedir acesso a partir da Internet\n" +" --[no-]remote-printers Mostrar/ocultar impressoras remotas\n" +" --[no-]share-printers Activar/desactivar partilha de impressora\n" +" --[no-]user-cancel-any Permitir/impedir utilizadores de cancelar " +"trabalhos\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Utilização: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Carregar ficheiro de configuração alternativa\n" +"-f Executar em primeiro plano\n" +"-F Executar em primeiro plano, mas separar\n" +"-h Mostrar esta mensagem de utilização\n" +"-l Executar cupsd a partir de launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Utilização: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Opções:\n" +"\n" +" -h Mostrar utilização de programa\n" +"\n" +" Nota: este programa só valida comentários DSC, não o próprio " +"PostScript.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Utilização: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Utilização: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Utilização: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Utilização: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Utilização: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] " +"[+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Utilização: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Opções:\n" +" -D name=value Definir variável designada como valor.\n" +" -I include-dir Adicionar incluir directório ao caminho de pesquisa.\n" +" -c catalog.po Carregar o catálogo de mensagens especificado.\n" +" -d output-dir Especificar o directório de saída.\n" +" -l lang[,lang,...] Especificar o(s) idioma(s) (locale).\n" +" -m Utilizar o valor ModelName como nome de ficheiro.\n" +" -t Testar PPDs em vez de os gerar.\n" +" -v Ser verboso (mais \"v\" para mais verbosidade).\n" +" -z Comprimir ficheiros PPD utilizando o zip GNU.\n" +" --cr Terminar linhas em CR (Mac OS 9).\n" +" --crlf Terminar linhas em CR + LF (Windows).\n" +" --lf Terminar linhas em LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Utilização: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Definir variável designada como valor.\n" +"Opções:\n" +" -I include-dir Adicionar incluir directório ao caminho de pesquisa.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Utilização: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Opções:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Utilização: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Opções:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Utilização: ppdpo [options] -o filename.po filename.drv [ ... filenameN." +"drv ]\n" +"Opções:\n" +" -D name=value Definir variável designada como valor.\n" +" -I include-dir Adicionar incluir directório ao caminho de pesquisa.\n" +" -v Ser verboso (mais \"v\" para mais verbosidade).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Utilização: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Valor com comprimento indefinido" + +msgid "VarBind uses indefinite length" +msgstr "VarBind com comprimento indefinido" + +msgid "Version uses indefinite length" +msgstr "Versão com comprimento indefinido" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: A adicionar apenas as primeiras %d impressoras encontradas" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Booleano esperado para opção waiteof \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Falha ao ler pedido de side-channel!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: Não é possível incluir a opção \"%s\" via IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: a impressora não responde\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: A impressora enviou um EOF inesperado\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Host remoto não respondeu com byte de estado de comando após %d " +"segundos!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Host remoto não respondeu com byte de estado de controlo após %d " +"segundos!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Host remoto não respondeu com byte de estado de dados após %d " +"segundos!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: Comando SCSI sem resposta (%d); a tentar de novo...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Este documento não está de acordo com ADSC e pode não ser impresso " +"correctamente!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Não é possível abrir o ficheiro \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Não é possível enviar o pedido de estado PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Pacote PAP inesperado do tipo %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Pacote PAP desconhecido do tipo %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Escolha desconhecida \"%s\" para opção \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Opção desconhecida \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Taxa baud não suportada %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: número esperado para opção status \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: recuperável: host de rede '%s' ocupado; nova tentativa dentro de %d " +"segundos...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Aviso, sem controladores de impressora Windows 2000 instalados!" + +msgid "Yes" +msgstr "Sim" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Deve aceder a esta página utilizando o URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "Envelope You4" + +msgid "ZPL Label Printer" +msgstr "Impressora de etiquetas ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "interrompido" + +msgid "canceled" +msgstr "cancelado" + +msgid "completed" +msgstr "concluído" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "" +"convert: Utilize a opção -f para especificar um ficheiro para converter.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced falhou a execução." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd falhou a execução." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Sem ficheiro PPD para impressora \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Não é possível ligar ao servidor: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Opção desconhecida \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Opção desconhecida \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Nome de ficheiro config esperado após opção \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Não é possível obter o directório actual!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Argumento desconhecido \"%s\" - a interromper!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Opção desconhecida \"%c\" - a interromper!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: suporte launchd(8) não compilado; execução em modo normal.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Número de documento inválido %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: ID de trabalho inválido %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Só pode ser especificado um nome de ficheiro!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Não é possível obter o ficheiro do trabalho - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: Opção -q incompatível com opção -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: Opção -v incompatível com opção -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "periférico para %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "periférico para %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index com comprimento indefinido" + +msgid "error-status uses indefinite length" +msgstr "error-status com comprimento indefinido" + +msgid "held" +msgstr "reter" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tobter ajuda sobre comandos\n" + +msgid "idle" +msgstr "inactivo" + +msgid "job-printer-uri attribute missing!" +msgstr "atributo job-printer-uri inexistente!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Nome de classe só pode ter caracteres imprimíveis!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: PPD esperado após opção '-P'!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "" +"lpadmin: Permitir/negar:lista de utilizadores esperado após opção '-u'!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Classe esperada após opção '-r'!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Nome de classe esperado após opção '-c'!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Descrição esperada após opção '-D'!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: URI de periférico esperado após opção '-v'!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Tipo(s) de ficheiro esperados após opção '-I'!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Nome de host esperado após opção '-h'!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Interface esperada após opção '-i'!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Localização esperada após opção '-L'!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Modelo esperado após opção '-m'!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Nome=valor esperado após opção '-o'!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Impressora esperada após opção '-p'!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Nome de impressora esperado após opção '-d'!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Impressora ou classe esperadas após opção '-x'!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Sem nomes de membro detectados!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Impressora %s já é membro da classe %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Impressora %s não é membro da classe %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Nome de impressora só pode ter caracteres imprimíveis!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível adicionar impressora à classe:\n" +" Especifique primeiro um nome de impressora!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Não é possível ligar ao servidor: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Não é possível abrir o ficheiro PPD \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Não é possível abrir o ficheiro \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível remover a impressora da classe:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir o ficheiro PPD:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir o URI do periférico:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir o script de interface ou ficheiro PPD:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir o script de interface:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir a descrição da impressora:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir a localização da impressora:\n" +" Especifique primeiro um nome de impressora!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível definir as opções da impressora:\n" +" Especifique primeiro um nome de impressora!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Opção permitir/negar desconhecida \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Argumento desconhecido '%s'!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Opção desconhecida '%c'!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Aviso - lista de tipo de conteúdo ignorada!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: Esperada cadeia ID de periférico 1284 após --device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Esperado idioma após --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Esperados marca e modelo após --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Esperada cadeia de produto após --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Esperada lista de esquema após --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Esperada lista de esquema após --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Esperado limite de tempo excedido após --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Argumento desconhecido '%s'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Opção desconhecida '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Opção desconhecida '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Não é possível ligar ao servidor: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Argumento desconhecido '%s'!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Opção desconhecida '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Sem impressoras!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Não é possível adicionar impressora ou instância: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Não é possível obter o ficheiro PPD para %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Não é possível abrir o ficheiro PPD para %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Impressora ou classe desconhecidas!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Só raiz pode adicionar ou apagar palavras-passe!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Ficheiro de palavra-passe ocupado!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Ficheiro de palavra-passe não actualizado!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Palavra-passe não corresponde!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Palavra-passe rejeitada.\n" +"A palavra-passe deve ter o mínimo de 6 caracteres, sem conter\n" +"o nome de utilizador, e deve ter pelo menos uma letra e um número.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Palavras-passe não correspondem!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Não é possível copiar a cadeia de palavra-passe: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Não é possível abrir o ficheiro de palavra-passe: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Não é possível escrever no ficheiro de palavra-passe: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" +"lppasswd: falha ao efectuar cópia de segurança de ficheiro de palavra-passe " +"antigo: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: falha ao alterar nome de ficheiro de palavra-passe: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: utilizador \"%s\" e grupo \"%s\" não existem.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: erro - nomes de variáveis de ambiente %s inexistentes no destino \"%s" +"\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "membros da classe %s:\n" + +msgid "no entries\n" +msgstr "sem entradas\n" + +msgid "no system default destination\n" +msgstr "sem destino predefinido de sistema\n" + +msgid "notify-events not specified!" +msgstr "notify-events não especificados!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI \"%s\" já está em utilização!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI \"%s\" utiliza esquema desconhecido!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d incorrecto!" + +msgid "pending" +msgstr "pendente" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: A adicionar incluir directório \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: A adicionar/actualizar texto UI de %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Valor boolean inválido (%s) na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Nome de resolução inválido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Palavra-chave de estado inválida %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Substituição de variável inválida ($%c) na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Encontrada escolha na linha %d de %s sem Opção!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Duplicar #po para o locale %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Esperada uma definição de filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Esperado um nome de programa na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Esperado valor boolean na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Esperado charset após Tipo de Letra na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Esperado código de escolha na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Esperado nome/texto de escolha na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Esperada ordem de cor para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Esperado espaço de cor para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Esperada compressão para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Esperada cadeia de restrições para UIConstraints na linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Esperada palavra-chave do tipo de controlador após DriverType na linha " +"%d de %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Esperado tipo duplex após Duplex na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Esperada codificação após Tipo de Letra na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Esperado nome de ficheiro após #po %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Esperado nome/texto de grupo na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Esperado incluir nome de ficheiro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Esperado número inteiro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Esperado locale após #po na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Esperado nome após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Esperado nome após FileName na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Esperado nome após Tipo de Letra na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Esperado nome após Fabricante na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Esperado nome após MediaSize na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Esperado nome após ModelName na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Esperado nome após PCFileName na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Esperado nome/texto após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Esperado nome/texto após Instalável na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Esperado nome/texto após Resolução na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Esperada combinação nome/texto para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Esperado nome/texto da opção na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Esperada secção de opção na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Esperado tipo de opção na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: Esperado substituir campo após Resolução na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Esperado número real na linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Esperada resolução/tipo de suporte após ColorProfile na linha %d de %" +"s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Esperada resolução/tipo de suporte após SimpleColorProfile na linha %d " +"de %s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Esperado selector após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Esperado estado Tipo de Letra na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Esperada cadeia após Copyright na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Esperada cadeia após Versão na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Esperados dois nomes de opção na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Esperado valor após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Esperada versão após Tipo de Letra na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Nome de ficheiro #include/#po inválido \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Custo inválido de filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Tipo MIME vazio inválido de filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Nome de programa vazio inválido de filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Secção de opção inválida \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tipo de opção inválido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: A carregar ficheiro de informação de controlador \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: A carregar mensagens do locale \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: A carregar mensagens de \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif inexistente no final de \"%s\"!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if inexistente na linha %d de %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "" +"ppdc: Não foi fornecido qualquer catálogo de mensagem para o locale %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: Opção %s redefinida com um tipo diferente na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Restrição de opção tem *name na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Demasiados #if aninhados na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: Não é possível criar o ficheiro PPD \"%s\" - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Não é possível criar o directório de saída %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Não é possível criar dutos de saída de dados: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Não é possível executar cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Não é possível encontrar #po ficheiro %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Não é possível encontrar incluir ficheiro \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Não é possível encontrar a localização de \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Não é possível carregar o ficheiro de localização \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Variável indefinida (%s) na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Tipo de controlador desconhecido %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tipo de duplex desconhecido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Tamanho de suporte desconhecido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Token desconhecido \"%s\" visto na linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Caracteres de controlo desconhecidos no número real \"%s\" na linha %d " +"de %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Cadeia não terminada começando por %c na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: A escrever %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: A escrever ficheiros PPD no directório \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: LanguageVersion inválida \"%s\" em %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: A ignorar o ficheiro PPD %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Não é possível efectuar a cópia de segurança %s em %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "impressora %s desactivada desde %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "impressora %s inactiva. activada desde %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "impressora %s agora a imprimir %s-%d. activada desde %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "impressora %s/%s desactivada desde %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "impressora %s/%s inactiva. activada desde %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "impressora %s/%s agora a imprimir %s-%d. activada desde %s\n" + +msgid "processing" +msgstr "a processar" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "id de pedido é %s-%d (%d ficheiro(s))\n" + +msgid "request-id uses indefinite length" +msgstr "request-id com comprimento indefinido" + +msgid "scheduler is not running\n" +msgstr "programador não está em execução\n" + +msgid "scheduler is running\n" +msgstr "programador em execução\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "estatística de %s falhou: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tmostra estado de daemon e fila\n" + +msgid "stopped" +msgstr "parado" + +#, c-format +msgid "system default destination: %s\n" +msgstr "destino predefinido de sistema: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "destino predefinido de sistema: %s/%s\n" + +msgid "unknown" +msgstr "desconhecido" + +msgid "untitled" +msgstr "sem nome" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings com comprimento indefinido" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN Ficheiro APDialogExtension inexistente \"%s\"\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN Ficheiro APPrinterIconPath inexistente \"%s\"\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Não é possível abrir %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Não é possível abrir %s - %s na linha %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "Níveis de cinzento 600 DPI" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: URI de periférico inexistente em command-line e sem variável de " +#~ "ambiente DEVICE_URI!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Não é possível criar ficheiro o temporário - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Não é possível criar o ficheiro temporário: %s.\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Não é possível abrir o ficheiro temporário" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: Filtro pdftops falhou ao sinal %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: Filtro pdftops saiu com o estado %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Erro de impressora desconhecido (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Utilização: convert [ options ]\n" +#~ "\n" +#~ "Opções:\n" +#~ "\n" +#~ " -f filename Definir ficheiro a ser convertido (caso contrário " +#~ "stdin)\n" +#~ " -o filename Definir ficheiro a ser gerado (caso contrário " +#~ "stdout)\n" +#~ " -i mime/type Definir tipo MIME de entrada (caso contrário auto-" +#~ "typed)\n" +#~ " -j mime/type Definir tipo MIME de saída (caso contrário " +#~ "application/pdf)\n" +#~ " -P filename.ppd Definir ficheiro PPD\n" +#~ " -a 'name=value ...' Definir opção(ões)\n" +#~ " -U username Definir nome de utilizador do trabalho\n" +#~ " -J title Definir título\n" +#~ " -c copies Definir número de cópias\n" +#~ " -u Remover o ficheiro PPD ao terminar\n" +#~ " -D Remover o ficheiro de entrada ao terminar\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Utilização: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Opções:\n" +#~ "\n" +#~ " -c cupsd.conf Definir ficheiro cupsd.conf a utilizar\n" +#~ " -j job-id[,N] Filtrar ficheiro N do trabalho especificado (a " +#~ "predefinição é ficheiro 1)\n" +#~ " -n copies Definir número de cópias\n" +#~ " -o name=value Definir opção(ões)\n" +#~ " -p filename.ppd Definir ficheiro PPD\n" +#~ " -t title Definir título\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Utilização: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[." +#~ "gz]]\n" +#~ " programa | cupstestppd [options] -\n" +#~ "\n" +#~ "Opções:\n" +#~ "\n" +#~ " -R root-directory Especificar raiz alternativa\n" +#~ " -W {tudo, sem, restrições, predefinições, duplex, filtros, " +#~ "traduções}\n" +#~ " Emitir avisos em vez de erros\n" +#~ " -q Executar silenciosamente\n" +#~ " -r Utilizar modo aberto 'descontraído'\n" +#~ " -v Ligeiramente verboso\n" +#~ " -vv Muito verboso\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Não é possível criar o ficheiro temporário: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Não é possível criar o ficheiro temporário - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Não é possível criar o ficheiro temporário: %s\n" diff --git a/locale/cups_pt_BR.po b/locale/cups_pt_BR.po new file mode 100644 index 0000000000..f8b14f5062 --- /dev/null +++ b/locale/cups_pt_BR.po @@ -0,0 +1,5708 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(todos)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(nenhum)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d entradas\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tApós falha: continuar\n" + +msgid "\tAlerts:" +msgstr "\tAlertas:" + +msgid "\tBanner required\n" +msgstr "\tBanner requisitado\n" + +msgid "\tCharset sets:\n" +msgstr "\tConjunto de caracteres:\n" + +msgid "\tConnection: direct\n" +msgstr "\tConexão: direta\n" + +msgid "\tConnection: remote\n" +msgstr "\tConexão: remota\n" + +msgid "\tDefault page size:\n" +msgstr "\tTamanho de página padrão:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tTom padrão:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tAjustes de porta padrão:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tDescrição: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tFormato montado:\n" +"\tTipos de conteúdo: qualquer\n" +"\tTipos de impressora: desconhecido\n" + +msgid "\tForms allowed:\n" +msgstr "\tFormatos permitidos:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tInterface: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tInterface: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tInterface: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tLocalização: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tNa falha: nenhum alerta\n" + +msgid "\tUsers allowed:\n" +msgstr "\tUsuários permitidos:\n" + +msgid "\tUsers denied:\n" +msgstr "\tUsuários negados:\n" + +msgid "\tdaemon present\n" +msgstr "\tapresentação de daemon\n" + +msgid "\tno entries\n" +msgstr "\tnenhuma entrada\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\ta impressora está no dispositivo '%s' velocidade -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\ta impressão está desativada\n" + +msgid "\tprinting is enabled\n" +msgstr "\ta impressão está ativada\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tenfileirado para %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\to enfileiramento está desativado\n" + +msgid "\tqueuing is enabled\n" +msgstr "\to enfileiramento está ativado\n" + +msgid "\treason unknown\n" +msgstr "\tmotivo desconhecido\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Página 15, seção 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Página 15, seção 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Página 19, seção 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Página 20, seção 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Página 27, seção 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Página 42, seção 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Página 16-17, seção 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Página 42-45, seção 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Página 45-46, seção 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Página 48-49, seção 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Página 52-54, seção 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f bytes\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Padrão%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Fabricante\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Produto\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN \"%s %s\" entra em conflito com \"%s %s\"\n" +" (restrição=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s não possui opções correspondentes!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s compartilha um prefixo comum com %s\n" +" REF: Página 15, seção 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Conflito de opções padrão!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Talvez a opção dúplex do teclado %s não funcione como " +"esperado e deve ser denominada Dúplex!\n" +" REF: Página 122, seção 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN O arquivo contém um mix de terminações de linha CR, LF e CR " +"LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding solicitado por PPD 4.3 spec.\n" +" REF: Páginas 56-57, seção 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN A linha %d contém apenas espaços em branco!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN Fabricante solicitado por PPD 4.3 spec.\n" +" REF: Páginas 58-59, seção 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN Os arquivos PPD que não sejam do Windows devem usar linhas " +"que terminem apenas com LF, e não com CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Versão PPD obsoleta%.1f!\n" +" REF: Página 42, seção 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName maior que 8.3 em violação de PPD spec.\n" +" REF: Páginas 61-62, seção 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Os protocolos contém PJL, mas os atributos JCL não estão " +"definidos.\n" +" REF: Páginas 78-79, seção 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Os protocolos contêm PJL e BCP; TBCP esperado.\n" +" REF: Páginas 78-79, seção 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName solicitado por PPD 4.3 spec.\n" +" REF: Páginas 64-65, seção 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s não existe!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Escolha %s inválida %s!\n" +" REF: Página 122, seção 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" +" %s UTF-8 Inválido \"%s\" seqüência de caracteres de tradução para a " +"opção %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s UTF-8 Inválido \"%s\" seqüência de caracteres de tradução para " +"opção %s, escolha %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Valor de cupsFilter inválido \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s cupsICCProfile Inválido %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Valor de cupsPreFilter inválido \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s cupsUIConstraints Inválido %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Idioma inválido \"%s\"!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints Vazio %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr "" +" %s Ausente \"%s\" seqüência de caracteres de tradução para a opção %" +"s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Ausente \"%s\" seqüência de caracteres de tradução para a opção %" +"s, escolha %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Escolha ausente *%s %s em UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Escolha ausente *%s %s em cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Arquivo cupsFilter ausente \"%s\"\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Arquivo cupsICCProfile ausente \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Arquivo cupsPreFilter ausente \"%s\"\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s cupsUIResolver ausente %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Opção ausente %s em UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Opção ausente %s em cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Nenhuma tradução base de \"%s\" está incluída no arquivo!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s REQUIRED %s não define a opção Nenhum!\n" +" REF: Página 122, seção 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s o valor hash de cupsICCProfile %s colide com %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s provoca um loop!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** %s os nomes de seleção %s e %s se diferenciam apenas por " +"maiúscula ou minúscula!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s deve ser 1284DeviceID!\n" +" REF: Página 72, seção 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** BAD Padrão%s %s\n" +" REF: Página 40, seção 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Página 102, seção 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Página 103, seção 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** BAD atributo JobPatchFile no arquivo\n" +" REF: Página 24, seção 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** BAD Fabricante (deve ser \"HP\")\n" +" REF: Página 211, tabela D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** BAD Fabricante (deve ser \"Oki\")\n" +" REF: Página 211, tabela D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** BAD ModelName - \"%c\" não permitido na seqüência de " +"caracteres.\n" +" REF: Páginas 59-60, seção 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** BAD PSVersion - não \"(seqüência de caracteres) int\".\n" +" REF: Páginas 62-64, seção 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** BAD Produto - não \"(seqüência de caracteres)\".\n" +" REF: Página 62, seção 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** BAD ShortNickName - maior que 31 caracteres.\n" +" REF: Páginas 64-65, seção 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Escolha %s inválida %s!\n" +" REF: Página 84, seção 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FileVersion Inválida \"%s\"\n" +" REF: Página 56, seção 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** FormatVersion Inválido \"%s\"\n" +" REF: Página 56, seção 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FAIL** LanguageEncoding %s inválido - deve ser ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FAIL** LanguageVersion %s inválido - deve ser inglês!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FAIL** O código de opção padrão não pode ser interpretado: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** Seqüência de caracteres de tradução padrão para opção %s " +"escolha %s contém caracteres de 8 bits!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** Seqüência de caracteres de tradução padrão para opção %s " +"contém caracteres de 8 bits!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Os nomes dos grupos %s e %s se diferenciam apenas por " +"maiúscula ou minúscula!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Ocorrências múltiplas de %s nome de seleção %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Os nomes das opções %s e %s se diferenciam apenas por " +"maiúscula ou minúscula!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** REQUIRED Padrão%s\n" +" REF: Página 40, seção 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Página 102, seção 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Página 103, seção 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Página 56, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Página 56, seção 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED ImageableArea para PageSize %s\n" +" REF: Página 41, seção 5.\n" +" REF: Página 102, seção 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Páginas 56-57, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Páginas 57-58, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED Fabricante\n" +" REF: Páginas 58-59, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED ModelName\n" +" REF: Páginas 59-60, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED NickName\n" +" REF: Página 60, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Páginas 61-62, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Páginas 62-64, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Página 100, seção 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageSize\n" +" REF: Página 41, seção 5.\n" +" REF: Página 99, seção 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** REQUIRED PageSize\n" +" REF: Páginas 99-100, seção 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** REQUIRED PaperDimension para PageSize %s\n" +" REF: Página 41, seção 5.\n" +" REF: Página 103, seção 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED Produto\n" +" REF: Página 62, seção 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Página 64-65, seção 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d ERROS ENCONTRADOS\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" %%%%BoundingBox inválido: na linha %d!\n" +" REF: Página 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" %%%%Página inválida: na linha %d!\n" +" REF: Página 53, %%%%Página:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" %%%%Páginas inválidas: na linha %d!\n" +" REF: Página 43, %%%%Páginas:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" A linha %d é maior do que 255 caracteres (%d)!\n" +" REF: Página 25, Comprimento de Linha\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 ausente na primeira linha!\n" +" REF: Página 17, 3.1 Documentos Conformes\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Comentário %%EndComments ausente!\n" +" REF: Página 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox ausente ou inválido: comentário!\n" +" REF: Página 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Página ausente ou inválida: comentários!\n" +" REF: Página 53, %%Página:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Páginas ausentes ou inválidas: comentário!\n" +" REF: Página 43, %%Páginas:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " NENHUM ERRO ENCONTRADO\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Visualizadas %d linhas que excedem 255 caracteres!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Muitos comentários %%BeginDocument!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Muitos comentários %%EndDocument!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Aviso: o arquivo contém dados binários!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Aviso: nenhum comentário %%EndComments no arquivo!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Aviso: versão DSC obsoleta %.1f no arquivo!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** Não é possível abrir o arquivo - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** Não é possível abrir o arquivo PPD - %s na linha %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10 Envelope" + +msgid "#11 Envelope" +msgstr "#11 Envelope" + +msgid "#12 Envelope" +msgstr "#12 Envelope" + +msgid "#14 Envelope" +msgstr "#14 Envelope" + +msgid "#9 Envelope" +msgstr "#9 Envelope" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f milímetros" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f a %.0f x %.0f milímetros" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f polegadas" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f a %.2f x %.2f polegadas" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s aceitando solicitações desde %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s não pode ser alterado." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s não está implementado pela versão CUPS de lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s não está pronto\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s está pronto\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s está pronto e imprimindo\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s não está aceitando solicitações desde %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s não é compatível!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s está aceitando solicitações desde %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s não está aceitando solicitações desde %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [trabalho %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s falhou: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Não sei o que fazer!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Erro - %s nomes de variáveis de ambiente de destino não existente \"%s" +"\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Erro - ID de trabalho inválido!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Erro - não é possível imprimir arquivos e alterar trabalhos " +"simultaneamente!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Erro - não é possível imprimir a partir de stdin se os arquivos ou um ID " +"de trabalho forem fornecidos!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Erro - conjunto de caracteres esperado após opção '-S'!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Erro - tipo de conteúdo esperado após opção '-T'!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Erro - cópias esperadas após opção '-n'!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Erro - contagem de cópias esperadas após opção '-#'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Erro - destino esperado após opção '-P'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Erro - destino esperado após opção '-b'!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Erro - destino esperado após opção '-d'!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Erro - formulário esperado após opção '-f'!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Erro - nome mantido esperado após opção '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Erro - nome de host esperado após opção '-H'!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Erro - nome de host esperado após opção '-H'!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Erro - lista de modo esperado após opção '-y'!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Erro - nome esperado após opção '-%c'!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "" +"%s: Erro - seqüência de caracteres de opção esperada após opção '-o'!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Erro - lista de página esperada após opção '-P'!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Erro - prioridade esperada após opção '-%c'!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Erro - texto de motivo esperado após opção '-r'!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Erro - título esperado após opção '-t'!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Erro - nome de usuário esperado após opção '-U'!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Erro - nome de usuário esperado após opção '-U'!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Erro - valor esperado após opção '-%c'!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Erro - necessária opções \"completo\", \"incompleto\" ou \"todos\" após " +"opção '-W'!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Erro - nenhum destino padrão disponível.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Erro - prioridade deve estar entre 1 e 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Erro - programador não responde!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Erro - muitos arquivos - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Erro - não foi possível acessar \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "" +"%s: Erro - não foi possível fazer a fila a partir da mensagem padrão - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Erro - destino desconhecido \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Erro - destino desconhecido \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Erro - opção desconhecida '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Erro - opção desconhecida '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: ID de trabalho esperada após opção '-i'!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filtro \"%s\" não disponível: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Nome de destino inválido na lista \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Seqüência de caracteres inválida \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: ID de trabalho necessária ('-i jobid') antes de 'reinício -H'!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Nenhum filtro para converter de %s/%s para %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Falha de operação: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Desculpe, não há compatibilidade de encriptação compilada!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Não é possível conectar ao servidor\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Não é possível contactar ao servidor!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Não é possível determinar o tipo MIME de \"%s\"!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Não é possível abrir %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Não é possível abrir um arquivo PPD: %s on-line %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Não é possível ler o banco de dados MIME de \"%s\" ou \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Destino desconhecido \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Tipo MIME de destino desconhecido %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Opção desconhecida '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Tipo MIME de fonte desconhecida %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Aviso - '%c' modificador de formato não compatível - a saída pode não " +"ser correta!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Aviso - opção de conjunto de caracteres foi ignorada!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Aviso - opção de tipo de conteúdo foi ignorada!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Aviso - opção de formulário foi ignorada!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Aviso - opção de modo foi ignorada!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: erro - %s nomes de variáveis de ambiente de destino não existente \"%s" +"\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: erro - option=value esperado após opção '-o'!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: erro - nenhum destino padrão disponível.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 polegada/s" + +msgid "1.25x0.25\"" +msgstr "1.25x0.25\"" + +msgid "1.25x2.25\"" +msgstr "1.25x2.25\"" + +msgid "1.5 inch/sec." +msgstr "1.5 polegada/s" + +msgid "1.50x0.25\"" +msgstr "1.50x0.25\"" + +msgid "1.50x0.50\"" +msgstr "1.50x0.50\"" + +msgid "1.50x1.00\"" +msgstr "1.50x1.00\"" + +msgid "1.50x2.00\"" +msgstr "1.50x2.00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 polegadas/s" + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/s" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 polegadas/s" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 polegadas/s" + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/s" + +msgid "120x60dpi" +msgstr "120x60ppp" + +msgid "120x72dpi" +msgstr "120x72ppp" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136ppp" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/s" + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/s" + +msgid "150dpi" +msgstr "150ppp" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180ppp" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 polegadas/s" + +msgid "2-Sided Printing" +msgstr "Impressão Frente e Verso" + +msgid "2.00x0.37\"" +msgstr "2.00x0.37\"" + +msgid "2.00x0.50\"" +msgstr "2.00x0.50\"" + +msgid "2.00x1.00\"" +msgstr "2.00x1.00\"" + +msgid "2.00x1.25\"" +msgstr "2.00x1.25\"" + +msgid "2.00x2.00\"" +msgstr "2.00x2.00\"" + +msgid "2.00x3.00\"" +msgstr "2.00x3.00\"" + +msgid "2.00x4.00\"" +msgstr "2.00x4.00\"" + +msgid "2.00x5.50\"" +msgstr "2.00x5.50\"" + +msgid "2.25x0.50\"" +msgstr "2.25x0.50\"" + +msgid "2.25x1.25\"" +msgstr "2.25x1.25\"" + +msgid "2.25x4.00\"" +msgstr "2.25x4.00\"" + +msgid "2.25x5.50\"" +msgstr "2.25x5.50\"" + +msgid "2.38x5.50\"" +msgstr "2.38x5.50\"" + +msgid "2.5 inches/sec." +msgstr "2.5 polegadas/s" + +msgid "2.50x1.00\"" +msgstr "2.50x1.00\"" + +msgid "2.50x2.00\"" +msgstr "2.50x2.00\"" + +msgid "2.75x1.25\"" +msgstr "2.75x1.25\"" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/s" + +msgid "200 mm/sec." +msgstr "200 mm/s" + +msgid "203dpi" +msgstr "203ppp" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "Séries de 24 pinos" + +msgid "240x72dpi" +msgstr "240x72ppp" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/s" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 polegadas/s" + +msgid "3.00x1.00\"" +msgstr "3.00x1.00\"" + +msgid "3.00x1.25\"" +msgstr "3.00x1.25\"" + +msgid "3.00x2.00\"" +msgstr "3.00x2.00\"" + +msgid "3.00x3.00\"" +msgstr "3.00x3.00\"" + +msgid "3.00x5.00\"" +msgstr "3.00x5.00\"" + +msgid "3.25x2.00\"" +msgstr "3.25x2.00\"" + +msgid "3.25x5.00\"" +msgstr "3.25x5.00\"" + +msgid "3.25x5.50\"" +msgstr "3.25x5.50\"" + +msgid "3.25x5.83\"" +msgstr "3.25x5.83\"" + +msgid "3.25x7.83\"" +msgstr "3.25x7.83\"" + +msgid "3.5\" Disk" +msgstr "Disco de 3.5\"" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Disco de 3.5\" - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3.50x1.00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/s" + +msgid "300 mm/sec." +msgstr "300 mm/s" + +msgid "300dpi" +msgstr "300ppp" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360ppp" + +msgid "360x180dpi" +msgstr "360x180ppp" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 polegadas/s" + +msgid "4.00x1.00\"" +msgstr "4.00x1.00\"" + +msgid "4.00x13.00\"" +msgstr "4.00x13.00\"" + +msgid "4.00x2.00\"" +msgstr "4.00x2.00\"" + +msgid "4.00x2.50\"" +msgstr "4.00x2.50\"" + +msgid "4.00x3.00\"" +msgstr "4.00x3.00\"" + +msgid "4.00x4.00\"" +msgstr "4.00x4.00\"" + +msgid "4.00x5.00\"" +msgstr "4.00x5.00\"" + +msgid "4.00x6.00\"" +msgstr "4.00x6.00\"" + +msgid "4.00x6.50\"" +msgstr "4.00x6.50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/s" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 polegadas/s" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 polegadas/s" + +msgid "6.00x1.00\"" +msgstr "6.00x1.00\"" + +msgid "6.00x2.00\"" +msgstr "6.00x2.00\"" + +msgid "6.00x3.00\"" +msgstr "6.00x3.00\"" + +msgid "6.00x4.00\"" +msgstr "6.00x4.00\"" + +msgid "6.00x5.00\"" +msgstr "6.00x5.00\"" + +msgid "6.00x6.00\"" +msgstr "6.00x6.00\"" + +msgid "6.00x6.50\"" +msgstr "6.00x6.50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/s" + +msgid "600dpi" +msgstr "600ppp" + +msgid "60dpi" +msgstr "60ppp" + +msgid "60x720dpi" +msgstr "60x720ppp" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 polegadas/s" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720ppp" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 polegadas/s" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8.00x1.00\"" + +msgid "8.00x2.00\"" +msgstr "8.00x2.00\"" + +msgid "8.00x3.00\"" +msgstr "8.00x3.00\"" + +msgid "8.00x4.00\"" +msgstr "8.00x4.00\"" + +msgid "8.00x5.00\"" +msgstr "8.00x5.00\"" + +msgid "8.00x6.00\"" +msgstr "8.00x6.00\"" + +msgid "8.00x6.50\"" +msgstr "8.00x6.50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/s" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 polegadas/s" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "Séries de 9 pinos" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Comando de ajuda inválido desconhecido\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "" +"Uma senha do Samba é solicitada para exportar os drivers da impressora!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "" +"Um nome de usuário do Samba é solicitado para exportar os drivers da " +"impressora!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Uma classe chamada \"%s\" já existe!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Uma impressora chamada \"%s\" já existe!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (Excessivamente grande)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (Excessivamente grande)" + +msgid "A4 (Small)" +msgstr "A4 (Pequeno)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (Excessivamente grande)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCO A" + +msgid "ARCH B" +msgstr "ARCO B" + +msgid "ARCH C" +msgstr "ARCO C" + +msgid "ARCH D" +msgstr "ARCO D" + +msgid "ARCH E" +msgstr "ARCO E" + +msgid "Accept Jobs" +msgstr "Aceitar Trabalhos" + +msgid "Accepted" +msgstr "Aceito" + +msgid "Add Class" +msgstr "Adicionar Classe" + +msgid "Add Printer" +msgstr "Adicionar Impressora" + +msgid "Add RSS Subscription" +msgstr "Adicionar Inscrição RSS" + +msgid "Address" +msgstr "Endereço" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Endereço - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administração" + +msgid "Always" +msgstr "Sempre" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Aplicador" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "" +"Tentativa de configurar o estado da impressora %s para valor inválido %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Os grupos de atributos estão fora de ordem (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Cursor NULL dests inválido" + +msgid "Bad OpenGroup" +msgstr "OpenGroup Inválido" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI Inválido" + +msgid "Bad OrderDependency" +msgstr "OrderDependency Inválido" + +msgid "Bad Request" +msgstr "Pedido Inválido" + +msgid "Bad SNMP version number" +msgstr "Número de versão SNMP inválido" + +msgid "Bad UIConstraints" +msgstr "UIConstraints Inválido" + +#, c-format +msgid "Bad copies value %d." +msgstr "Valor de cópias inválidas %d." + +msgid "Bad custom parameter" +msgstr "Parâmetro personalizado inválido" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Dispositivo URI inválido \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "dispositivo uri inválido \"%s\"!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Esquema device-uri inválido \"%s\"!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "formato de documento inválido \"%s\"!" + +msgid "Bad filename buffer!" +msgstr "Armazenamento intermediário do nome do arquivo inválido!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Atributo de fonte inválido: %s\n" + +msgid "Bad job-priority value!" +msgstr "Valor de job-priority inválido!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Valor job-sheets inválido \"%s\"!" + +msgid "Bad job-sheets value type!" +msgstr "Tipo de valor job-sheets inválido!" + +msgid "Bad job-state value!" +msgstr "Valor de job-state inválido!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Atributo de job-uri inválido \"%s\"!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "notify-pull-method inválido \"%s\"!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "notify-recipient-uri URI inválido \"%s\"!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Valor de number-up inválido %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "opção + escolha inválida na linha %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Valores de page-ranges inválidos %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "port-monitor inválido \"%s\"!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Valor de printer-state inválido %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Número de versão de solicitação inválido %d.%d!" + +msgid "Bad subscription ID!" +msgstr "ID de inscrição inválido!" + +msgid "Banners" +msgstr "Banners" + +msgid "Billing Information: " +msgstr "Informações de Cobrança: " + +msgid "Bond Paper" +msgstr "Papel Bond" + +msgid "C0 Envelope" +msgstr "Envelope C0" + +msgid "C1 Envelope" +msgstr "Envelope C1" + +msgid "C2 Envelope" +msgstr "Envelope C2" + +msgid "C3 Envelope" +msgstr "Envelope C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Envelope C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Envelope C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Envelope C6" + +msgid "C65 Envelope" +msgstr "Envelope C65" + +msgid "C7 Envelope" +msgstr "Envelope C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Impressora de Etiqueta CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Cancelar Inscrição RSS" + +msgid "Change Settings" +msgstr "Alterar Configurações" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Conjunto de caracteres \"%s\" não compatível!" + +msgid "Chou3 Envelope" +msgstr "Envelope Chou3" + +msgid "Chou4 Envelope" +msgstr "Envelope Chou4" + +msgid "Classes" +msgstr "Classes" + +msgid "Clean Print Heads" +msgstr "Limpar Cabeçotes de Impressão" + +msgid "Color" +msgstr "Cor" + +msgid "Color Mode" +msgstr "Modo de Cor" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Os comandos podem ser abreviados. Os comandos são:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Nome de comunidade usa comprimento indefinido" + +msgid "Continue" +msgstr "Continuar" + +msgid "Continuous" +msgstr "Contínuo" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Não foi possível escanear tipo \"%s\"!" + +msgid "Cover open." +msgstr "Tampa aberta." + +msgid "Created" +msgstr "Criado" + +msgid "Created On: " +msgstr "Criado em: " + +msgid "Custom" +msgstr "Personalizar" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Cortar" + +msgid "Cutter" +msgstr "Guilhotina" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "Envelope DL" + +msgid "Dark" +msgstr "Escuro" + +msgid "Darkness" +msgstr "Escuridão" + +msgid "Delete Class" +msgstr "Apagar Classe" + +msgid "Delete Printer" +msgstr "Apagar Impressora" + +msgid "Description: " +msgstr "Descrição: " + +msgid "DeskJet Series" +msgstr "DeskJet Series" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "O destino \"%s\" não está aceitando trabalhos." + +msgid "Developer almost empty." +msgstr "Desenvolvedor quase vazio." + +msgid "Developer empty!" +msgstr "Desenvolvedor vazio!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Dispositivo: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Mídia Termal Direta" + +msgid "Disabled" +msgstr "Desativado" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Documento %d não encontrado no trabalho %d." + +msgid "Door open." +msgstr "Porta aberta." + +msgid "Double Postcard" +msgstr "Cartão-Postal Duplo" + +msgid "Driver Name: " +msgstr "Nome do Driver: " + +msgid "Driver Version: " +msgstr "Versão do Driver: " + +msgid "Duplexer" +msgstr "Duplexer" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Não é possível alocar memória para informação de página: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Não é possível alocar memória para matriz de páginas: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Impressora de Etiquetas EPL1" + +msgid "EPL2 Label Printer" +msgstr "Impressora de Etiquetas EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox inválido: comentário visto!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: %%IncludeFeature inválido: comentário!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: %%Página inválido: comentário no arquivo!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: %%PageBoundingBox inválido: comentário no arquivo!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Arquivo de dispositivo SCSI inválido \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Arquivo de conjunto de caracteres inválido %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Tipo de conjunto de caracteres inválido %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Valor de colunas inválido %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Valor cpi inválido %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Linha de descrição de fonte inválida: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Valor lpi inválido %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Configuração de página inválida!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Direção de texto inválida %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Largura de texto inválida %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Impressora de destino inexistente!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Duplicar %%BoundingBox: comentário visto!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Duplicar %%Páginas: comentário visto!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Arquivo de impressão vazio!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Erro %d ao enviar pedido PAPSendData: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: Seqüência de caracteres on-line esperada %d de %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Erro grave de USB!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Comentário visto HP-GL/2 inválido, não é possível imprimir o " +"arquivo!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: %%EndProlog ausente!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: %%EndSetup ausente!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Valor ausente na linha %d do arquivo de banner!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Necessária uma linha msgid antes de quaisquer seqüências de " +"caracteres na linha %d de %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Nenhum %%BoundingBox: comentário no cabeçalho!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Nenhum %%Pages: comentário no cabeçalho!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Nenhum dispositivo URI encontrado em argv[0] ou em variável de " +"ambiente DEVICE_URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Nenhuma fonte no arquivo de conjunto de caracteres %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Nenhuma página encontrada!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Sem papel!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: Variável de ambiente PRINTER não definido!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: O arquivo de impressão não foi aceito (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: A impressora não responde\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: A impressora não responde!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: A impressora enviou um EOF inesperado\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Host remoto não aceitou o arquivo de controle (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Host remoto não aceitou o arquivo de dados (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Houve um erro de tempo esgotado ao enviar os dados à impressora\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Não é possível adicionar o arquivo %d ao trabalho: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Não é possível cancelar o trabalho %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Não foi possível copiar o arquivo PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Não foi possível criar soquete" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "" +"ERROR: Não é possível criar o arquivo de impressão comprimido temporário: %" +"s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Não é possível criar o arquivo temporário" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Não é possível executar pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Não é possível executar o programa gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Não é possível executar o programa pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Não é possível forçar pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Não é possível obter o pedido PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Não é possível obter a resposta PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "" +"ERROR: Não é possível obter o arquivo PPD para a impressora \"%s\" - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Não é possível obter a zona AppleTalk" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Não é possível obter os atributos %d do trabalho (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Não é possível obter o estado de impressão (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Não é possível localizar a impressora '%s'!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Não é possível procurar a resposta PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Não é possível buscar impressoras AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Não é possível criar o endereço AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Não é possível abrir \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Não é possível abrir %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Não é possível abrir o arquivo de banner \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Não é possível abrir o arquivo de dispositivo \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Não é possível abrir o arquivo \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Não é possível abrir o arquivo \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Não é possível abrir o arquivo de imagem para impressão!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Não é possível abrir o arquivo de impressão \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Não é possível abrir o arquivo de impressão %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Não é possível abrir o arquivo de impressão %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "" +"ERROR: Não é possível abrir o arquivo de impressão comprimido temporário: %" +"s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Não é possível imprimir %d colunas de texto!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Não é possível imprimir %dx%d página de texto!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Não é possível ler os dados de impressão" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Não é possível ler os dados de impressão!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Não é possível reservar porta" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Não é possível localizar o deslocamento %ld no arquivo- %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Não é possível localizar o deslocamento %lld no arquivo - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Não é possível enviar um comando LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Não é possível enviar um pedido tickle de PAP" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Não é possível enviar o pedido de dados de envio PAP inicial" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Não é possível enviar dados de impressão (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Não é possível enviar dados de impressão!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Não é possível enviar o arquivo de impressão à impressora" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "" +"ERROR: Não é possível enviar o valor nulo do fim da seqüência à impressora" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Não é possível aguardar pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Não é possível gravar %d bytes para \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Não é possível gravar %d bytes na impressora!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Não é possível gravar no arquivo de controle" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Não é possível gravar dados de impressão" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Não é possível gravar os dados de impressão: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Não é possível gravar os dados brutos para o driver!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Não é possível gravar no arquivo temporário" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "" +"ERROR: Não é possível gravar os dados de documentos não comprimidos: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Texto inesperado na linha %d de %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Valor de opção de encriptação desconhecido \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Ordem de arquivo desconhecida \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Caractere de formato desconhecido \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Formato de catálogo de mensagem desconhecida para \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Opção desconhecida \"%s\" com valor \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Modo de impressão desconhecido \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Valor de opção de versão desconhecido \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Valor de brilho não compatível %s, usando brilho=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Valor de gama não compatível %s, usando gama=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Valor de number-up não compatível %d, usando number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Valor de number-up-layout não compatível %s, usando number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Valor de page-border não compatível %s, usando page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: Sobrecarga de doc_printf (%d bytes) detectado, anulando!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops saíram no sinal %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops saíram com estado %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: recuperável: Não é possível conectar-se à impressora; nova tentativa " +"em 30 segundos...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: Seleção() falhou" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: Não foi possível iniciar o arquivo de impressão" + +msgid "Edit Configuration File" +msgstr "Editar Arquivo de Configuração" + +msgid "Empty PPD file!" +msgstr "Arquivo PPD vazio!" + +msgid "Ending Banner" +msgstr "Finalizando Banner" + +msgid "Enter old password:" +msgstr "Digite a senha antiga:" + +msgid "Enter password again:" +msgstr "Digite a senha novamente:" + +msgid "Enter password:" +msgstr "Digite a senha:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Digite o seu nome de usuário e a sua senha ou o nome de usuário e a senha de " +"root para acessar esta página. Se estiver usando a autenticação Kerberos, " +"certifique-se de possuir uma entrada Kerberos válida." + +msgid "Envelope Feed" +msgstr "Alimentação de Envelopes" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Política de Erro" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Error: necessário um nome de host após a opção '-h'!\n" + +msgid "Every 10 Labels" +msgstr "A cada 10 etiquetas" + +msgid "Every 2 Labels" +msgstr "A cada 2 etiquetas" + +msgid "Every 3 Labels" +msgstr "A cada 3 etiquetas" + +msgid "Every 4 Labels" +msgstr "A cada 4 etiquetas" + +msgid "Every 5 Labels" +msgstr "A cada 5 etiquetas" + +msgid "Every 6 Labels" +msgstr "A cada 6 etiquetas" + +msgid "Every 7 Labels" +msgstr "A cada 7 etiquetas" + +msgid "Every 8 Labels" +msgstr "A cada 8 etiquetas" + +msgid "Every 9 Labels" +msgstr "A cada 9 etiquetas" + +msgid "Every Label" +msgstr "Todas as Etiquetas" + +msgid "Expectation Failed" +msgstr "Falha de Expectativa" + +msgid "Export Printers to Samba" +msgstr "Exportar Impressoras para Samba" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Pasta de Arquivo" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Pasta de Arquivo - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"URIs de dispositivo de arquivo foram desativados! Para ativá-los, consulte a " +"diretiva FileDevice em \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Fólio" + +msgid "Forbidden" +msgstr "Esquecido" + +msgid "Fuser temperature high!" +msgstr "Temperatura do fuser alta!" + +msgid "Fuser temperature low!" +msgstr "Temperatura do fuser baixa!" + +msgid "General" +msgstr "Geral" + +msgid "Generic" +msgstr "Genérico" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU usa comprimento indefinido" + +msgid "Glossy Paper" +msgstr "Papel Brilhante" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Obtido um atributo printer-uri, mas não um job-id!" + +msgid "Grayscale" +msgstr "Escala de Cinzas" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Pasta Suspensa" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Pasta Suspensa - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk desativado nas Preferências do Sistema\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk desativado nas Preferências do Sistema.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Cancelando trabalho de impressão...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Conectado à impressora...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Conectando à impressora...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Arquivo de controle enviado com êxito\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Arquivo de dados enviado com êxito\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Formatando página %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Carregando arquivo de imagem...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Buscando impressora...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Abrindo conexão\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "" +"INFO: Arquivo de impressão enviado, aguardando conclusão da impressora...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Impressora ocupada; nova tentativa em 10 segundos...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Impressora ocupada; nova tentativa em 30 segundos...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Impressora ocupada; nova tentativa em 5 segundos...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: A impressora não é compatível com IPP/%d.%d, tentando IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: A impressora está ocupada; nova tentativa em 5 segundos...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: A impressora está atualmente desligada.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: A impressora está desligada atualmente.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: A impressora está conectada agora.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: A impressora está desligada.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Impressora não conectada; nova tentativa em 30 segundos...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Imprimindo página %d, %d%% concluído...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Imprimindo página %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Pronta para imprimir.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Enviando arquivo de controle (%lu bytes)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Enviando arquivo de controle (%u bytes)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Enviando dados\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Enviando arquivo de dados (%ld bytes)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Enviando arquivo de dados (%lld bytes)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Enviando dados de impressão...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Arquivo de impressão enviado, %ld bytes...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Arquivo de impressão enviado, %lld bytes...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Armazenando trabalho LPR, %.0f%% concluído...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Não foi possível contactar a impressora, enfileirando na próxima " +"impressora na classe...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Usando zona AppleTalk padrão \"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Aguardando conclusão do trabalho...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Esperando que a impressora esteja disponível...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "Envelope ISO B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (Exces. grande)" + +msgid "ISO B5 Envelope" +msgstr "Envelope ISO B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "Envelope ISO B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Caractere de controle ilegal" + +msgid "Illegal main keyword string" +msgstr "Seqüência de caracteres de palavra-chave principal ilegal" + +msgid "Illegal option keyword string" +msgstr "Seqüência de caracteres de palavra-chave de opção ilegal" + +msgid "Illegal translation string" +msgstr "Seqüência de caracteres de tradução ilegal" + +msgid "Illegal whitespace character" +msgstr "Seqüência de caracteres de espaço em branco ilegal" + +msgid "Ink/toner almost empty." +msgstr "Tinta/toner quase vazios." + +msgid "Ink/toner empty!" +msgstr "Tinta/toner vazios!" + +msgid "Ink/toner waste bin almost full." +msgstr "Recipiente de tinta/toner quase cheio." + +msgid "Ink/toner waste bin full!" +msgstr "Recipiente de tinta/toner cheio!" + +msgid "Installable Options" +msgstr "Opções Instaláveis" + +msgid "Installed" +msgstr "Instalado" + +msgid "IntelliBar Label Printer" +msgstr "Impressora de Etiquetas IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Conexão aberta." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Erro interno" + +msgid "Internet Postage 2-Part" +msgstr "Porte de Internet 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Porte de Internet 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Porte de Internet 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Porte de Internet 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Protocolo de Impressão da Internet" + +msgid "Invite Envelope" +msgstr "Envelope de Convite" + +msgid "Italian Envelope" +msgstr "Envelope Italiano" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "O trabalho #%d não pode ser reiniciado - nenhum arquivo!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "O trabalho #%d não existe!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "O trabalho #%d já foi anulado - não é possível cancelar." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "O trabalho #%d já foi cancelado - não é possível cancelar." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "O trabalho #%d já está concluído - não é possível cancelar." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "O trabalho #%d está finalizado e não pode ser alterado!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "O trabalho #%d não está concluído!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "O trabalho #%d não está parado para autenticação!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "O trabalho #%d não está parado!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "O trabalho #%s não existe!" + +#, c-format +msgid "Job %d not found!" +msgstr "Trabalho %d não encontrado!" + +msgid "Job Completed" +msgstr "Trabalho Concluído" + +msgid "Job Created" +msgstr "Trabalho Criado" + +msgid "Job ID: " +msgstr "ID de Trabalho: " + +msgid "Job Options Changed" +msgstr "Opções de Trabalho Alteradas" + +msgid "Job Stopped" +msgstr "Trabalho Parado" + +msgid "Job UUID: " +msgstr "UUID de Trabalho: " + +msgid "Job is completed and cannot be changed." +msgstr "O trabalho está concluído e não pode ser alterado." + +msgid "Job operation failed:" +msgstr "Falha de operação de trabalho:" + +msgid "Job state cannot be changed." +msgstr "O estado do trabalho não pode ser alterado." + +msgid "Job subscriptions cannot be renewed!" +msgstr "As inscrições do trabalho não podem ser renovadas!" + +msgid "Jobs" +msgstr "Trabalhos" + +msgid "Kaku2 Envelope" +msgstr "Envelope Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Envelope Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Host ou Impressora LPD/LPR" + +msgid "Label Printer" +msgstr "Impressora de Etiquetas" + +msgid "Label Top" +msgstr "Parte Superior da Etiqueta" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Idioma \"%s\" não compatível!" + +msgid "Large Address" +msgstr "Endereço Grande" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Endereço Grande - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "Claro" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Linha maior do que o máximo permitido (255 caracteres)" + +msgid "List Available Printers" +msgstr "Listar Impressoras Disponíveis" + +msgid "Location: " +msgstr "Localização: " + +msgid "Long-Edge (Portrait)" +msgstr "Margem Grande (Vertical)" + +msgid "Make and Model: " +msgstr "Fazer e Modelar: " + +msgid "Manual Feed" +msgstr "Alimentação Manual" + +msgid "Media Dimensions: " +msgstr "Dimensões dos Meios: " + +msgid "Media Limits: " +msgstr "Limites dos Meios: " + +msgid "Media Name: " +msgstr "Nome dos Meios: " + +msgid "Media Size" +msgstr "Tamanho de Mídia" + +msgid "Media Source" +msgstr "Fonte de Mídia" + +msgid "Media Tracking" +msgstr "Rastreamento dos Meios" + +msgid "Media Type" +msgstr "Tipo de Mídia" + +msgid "Media jam!" +msgstr "Atolamento de mídia!" + +msgid "Media tray almost empty." +msgstr "Bandeja de mídia quase vazia." + +msgid "Media tray empty!" +msgstr "Bandeja de mídia vazia!" + +msgid "Media tray missing!" +msgstr "Bandeja de mídia ausente!" + +msgid "Media tray needs to be filled." +msgstr "A bandeja de mídia necessita ser preenchida." + +msgid "Medium" +msgstr "Médio" + +msgid "Memory allocation error" +msgstr "Erro de alocação de memória" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Cabeçalho PPD-Adobe-4.x ausente" + +msgid "Missing asterisk in column 1" +msgstr "Asterisco ausente na coluna 1" + +msgid "Missing document-number attribute!" +msgstr "Atributo document-number ausente!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Aspas ausentes na linha %d!" + +msgid "Missing form variable!" +msgstr "Variável de formato ausente!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Atributo notify-subscription-ids ausente!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Atributo requesting-user-name ausente!" + +msgid "Missing required attributes!" +msgstr "Atributos necessários ausentes!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Valor ausente na linha %d!" + +msgid "Missing value string" +msgstr "Seqüência de caracteres de valor ausente" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modelo: nome = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Modificar Classe" + +msgid "Modify Printer" +msgstr "Modificar Impressora" + +msgid "Monarch" +msgstr "Monarca" + +msgid "Monarch Envelope" +msgstr "Envelope Monarca" + +msgid "Move All Jobs" +msgstr "Mover Todos os Trabalhos" + +msgid "Move Job" +msgstr "Mover Trabalho" + +msgid "Moved Permanently" +msgstr "Movido Permanentemente" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Arquivo de impressão aceito - ID de trabalho %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Arquivo de impressão aceito - ID de trabalho desconhecido.\n" + +msgid "NULL PPD file pointer" +msgstr "Ponteiro de arquivo NULL PPD" + +msgid "Name OID uses indefinite length" +msgstr "OID do nome usa comprimento indefinido" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Nunca" + +msgid "New Stylus Color Series" +msgstr "New Stylus Color Series" + +msgid "New Stylus Photo Series" +msgstr "New Stylus Photo Series" + +msgid "No" +msgstr "Não" + +msgid "No Content" +msgstr "Sem Conteúdo" + +msgid "No PPD name!" +msgstr "Nenhum nome PPD!" + +msgid "No VarBind SEQUENCE" +msgstr "Nenhuma VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Nenhum driver de impressora do Windows instalado!" + +msgid "No active connection" +msgstr "Nenhuma conexão ativa" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Nenhum trabalho ativo em %s!" + +msgid "No attributes in request!" +msgstr "Nenhum atributo na solicitação!" + +msgid "No authentication information provided!" +msgstr "Nenhuma informação de autenticação fornecida!" + +msgid "No community name" +msgstr "Nenhum nome de comunidade" + +msgid "No default printer" +msgstr "Nenhuma impressora padrão" + +msgid "No destinations added." +msgstr "Nenhum destino adicionado." + +msgid "No error-index" +msgstr "Nenhum error-index" + +msgid "No error-status" +msgstr "Nenhum error-status" + +msgid "No file!?!" +msgstr "Nenhum arquivo!?!" + +msgid "No modification time!" +msgstr "Nenhuma hora de modificação!" + +msgid "No name OID" +msgstr "Nenhum OID de nome" + +msgid "No printer name!" +msgstr "Nenhum nome de impressora!" + +msgid "No printer-uri found for class!" +msgstr "Nenhum printer-uri encontrado para a classe!" + +msgid "No printer-uri found!" +msgstr "Nenhum printer-uri encontrado!" + +msgid "No printer-uri in request!" +msgstr "Nenhum printer-uri em pedido!" + +msgid "No request-id" +msgstr "Nenhum request-id" + +msgid "No subscription attributes in request!" +msgstr "Nenhum atributo de inscrição na solicitação!" + +msgid "No subscriptions found." +msgstr "Nenhuma inscrição encontrada." + +msgid "No variable-bindings SEQUENCE" +msgstr "Nenhuma variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "Nenhum número de versão" + +msgid "Non-continuous (Mark sensing)" +msgstr "Descontínuo (Leitura de marcas)" + +msgid "Non-continuous (Web sensing)" +msgstr "Descontínuo (Leitura Web)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "Não Encontrado" + +msgid "Not Implemented" +msgstr "Não Implementado" + +msgid "Not Installed" +msgstr "Não Instalado" + +msgid "Not Modified" +msgstr "Não Modificado" + +msgid "Not Supported" +msgstr "Incompatível" + +msgid "Not allowed to print." +msgstr "Não permitido para impressão." + +msgid "Note" +msgstr "Nota" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC quase no final." + +msgid "OPC at end-of-life!" +msgstr "OPC no final!" + +msgid "Off (1-Sided)" +msgstr "Desligado (Frente)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Ajuda On-line" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "falha na abertura de %s: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup sem um CloseGroup primeiro" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI sem um CloseUI/JCLCloseUI primeiro" + +msgid "Operation Policy" +msgstr "Política de Operação" + +msgid "Options Installed" +msgstr "Opções Instaladas" + +msgid "Options: " +msgstr "Opções: " + +msgid "Out of toner!" +msgstr "Sem toner!" + +msgid "Output Mode" +msgstr "Modo de Saída" + +msgid "Output bin almost full." +msgstr "Recipiente de saída quase cheio." + +msgid "Output bin full!" +msgstr "Recipiente de saída cheio!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "A saída para impressora %s foi enviada a %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "A saída para impressora %s foi enviada à impressora remota %s em %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "A saída para impressora %s/%s foi enviada a %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "" +"A saída para impressora %s/%s foi enviada para a impressora remota %s em %s\n" + +msgid "Output tray missing!" +msgstr "Bandeja de saída ausente!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "Impressora Laser PCL" + +msgid "PRC1 Envelope" +msgstr "Envelope PRC1" + +msgid "PRC10 Envelope" +msgstr "Envelope PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Envelope PRC2" + +msgid "PRC3 Envelope" +msgstr "Envelope PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (Exces. grande)" + +msgid "PRC4 Envelope" +msgstr "Envelope PRC4" + +msgid "PRC5 Envelope" +msgstr "Envelope PRC5" + +msgid "PRC6 Envelope" +msgstr "Envelope PRC6" + +msgid "PRC7 Envelope" +msgstr "Envelope PRC7" + +msgid "PRC8 Envelope" +msgstr "Envelope PRC8" + +msgid "PRC9 Envelope" +msgstr "Envelope PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "O pacote não contém uma Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "O pacote não começa com SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Senha para %s em %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "A senha para %s requerida para acessar %s através do SAMBA: " + +msgid "Pause Class" +msgstr "Interromper Classe" + +msgid "Pause Printer" +msgstr "Colocar Impressora em Pausa" + +msgid "Peel-Off" +msgstr "Soltar" + +msgid "Personal Envelope" +msgstr "Envelope Pessoal" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Etiquetas de Foto" + +msgid "Plain Paper" +msgstr "Papel Normal" + +msgid "Policies" +msgstr "Políticas" + +msgid "Port Monitor" +msgstr "Monitor da Porta" + +msgid "PostScript Printer" +msgstr "Impressora PostScript" + +msgid "Postcard" +msgstr "Cartão-Postal" + +msgid "Print Density" +msgstr "Densidade da Impressão" + +msgid "Print Job:" +msgstr "Imprimir Trabalho:" + +msgid "Print Mode" +msgstr "Modo de Impressão" + +msgid "Print Rate" +msgstr "Taxa de Impressão" + +msgid "Print Self-Test Page" +msgstr "Imprimir Página de Autoteste" + +msgid "Print Speed" +msgstr "Velocidade de Impressão" + +msgid "Print Test Page" +msgstr "Imprimir Página de Teste" + +msgid "Print and Cut" +msgstr "Imprimir e Cortar" + +msgid "Print and Tear" +msgstr "Imprimir e Romper" + +msgid "Printed For: " +msgstr "Impresso para: " + +msgid "Printed From: " +msgstr "Impresso de: " + +msgid "Printed On: " +msgstr "Impresso em: " + +msgid "Printer Added" +msgstr "Impressora Adicionada" + +msgid "Printer Default" +msgstr "Padrão de Impressora" + +msgid "Printer Deleted" +msgstr "Impressora Apagada" + +msgid "Printer Modified" +msgstr "Impressora Modificada" + +msgid "Printer Name: " +msgstr "Nome de Impressora: " + +msgid "Printer Paused" +msgstr "Impressora em Pausa" + +msgid "Printer Settings" +msgstr "Ajustes da Impressora" + +msgid "Printer offline." +msgstr "Impressora desconectada." + +msgid "Printer:" +msgstr "Impressora:" + +msgid "Printers" +msgstr "Impressoras" + +msgid "Purge Jobs" +msgstr "Ignorar Trabalhos" + +msgid "Quarto" +msgstr "Quarto" + +msgid "Quota limit reached." +msgstr "Limite de quota alcançado." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Rank Proprietário Trabalho Arquivo(s) " +"Tamanho Total\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Rank Proprietário Imp Trabalho Arquivos " +"Tamanho Total\n" + +msgid "Reject Jobs" +msgstr "Rejeitar Trabalhos" + +msgid "Reprint After Error" +msgstr "Imprimir Novamente Após Erro" + +msgid "Request Entity Too Large" +msgstr "Entidade do Pedido Muito Grande" + +msgid "Resolution" +msgstr "Resolução" + +msgid "Resume Class" +msgstr "Retomar Classe" + +msgid "Resume Printer" +msgstr "Retomar Impressora" + +msgid "Return Address" +msgstr "Endereço de Devolução" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Endereço de Devolução - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Retroceder" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Executando comando: %s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "Impressora SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE usa comprimento indefinido" + +msgid "See Other" +msgstr "Ver Outro" + +#, c-format +msgid "Serial Port #%d" +msgstr "Porta serial nº%d" + +msgid "Server Restarted" +msgstr "Servidor Reiniciado" + +msgid "Server Security Auditing" +msgstr "Auditoria de Segurança de Servidor" + +msgid "Server Started" +msgstr "Servidor Iniciado" + +msgid "Server Stopped" +msgstr "Servidor Parado" + +msgid "Service Unavailable" +msgstr "Serviço Não Disponível" + +msgid "Set Allowed Users" +msgstr "Definir Usuários Permitidos" + +msgid "Set As Server Default" +msgstr "Definir como Padrão de Servidor" + +msgid "Set Class Options" +msgstr "Definir Opções de Classe" + +msgid "Set Printer Options" +msgstr "Definir Opções de Impressão" + +msgid "Set Publishing" +msgstr "Definir Publicação" + +msgid "Shipping Address" +msgstr "Endereço de Remessa" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Endereço de Remessa - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Margem Pequena (Horizontal)" + +msgid "Special Paper" +msgstr "Papel Especial" + +msgid "Standard" +msgstr "Padrão" + +msgid "Starting Banner" +msgstr "Iniciando Banner" + +msgid "Statement" +msgstr "Instrução" + +msgid "Stylus Color Series" +msgstr "Stylus Color Series" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo Series" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Alternando Protocolos" + +msgid "Tabloid" +msgstr "Tablóide" + +msgid "Tabloid (Oversize)" +msgstr "Tablóide (Exces. grande)" + +msgid "Tear" +msgstr "Rasgar" + +msgid "Tear-Off" +msgstr "Remover" + +msgid "Tear-Off Adjust Position" +msgstr "Remover Posição de Ajuste" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "O arquivo PPD \"%s\" não pôde ser encontrado." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "O arquivo PPD \"%s\" não pôde ser aberto: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"O nome de classe pode conter apenas até 127 caracteres imprimíveis e não " +"pode conter espaços, barras (/) ou o sinal de quadrado (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"O atributo notify-lease-duration não pode ser usado com as inscrições de " +"trabalho." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "O valor notify-user-data é muito grande (%d > 63 octetos)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"O nome da impressora somente pode conter até 127 caracteres imprimíveis e " +"não pode conter espaços, barras (/) ou o sinal de quadrado (#)." + +msgid "The printer or class is not shared!" +msgstr "A impressora ou a classe não estão compartilhadas!" + +msgid "The printer or class was not found." +msgstr "A impressora ou a classe não foram encontradas." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "O printer-uri \"%s\" contém caracteres inválidos." + +msgid "The printer-uri attribute is required!" +msgstr "O atributo printer-uri é necessário!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"O printer-uri deve ser do formato \"ipp://HOSTNAME/classes/CLASSNAME\"." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"O printer-uri deve ser do formato \"ipp://HOSTNAME/printers/PRINTERNAME\"." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"O nome de inscrição pode não conter espaços, barras (/), pontos de " +"interrogação (?) ou o sinal de quadrado (#)." + +msgid "There are too many subscriptions." +msgstr "Há muitas assinaturas." + +msgid "Thermal Transfer Media" +msgstr "Mídia de Transferência Termal" + +msgid "Title: " +msgstr "Título: " + +msgid "Toner low." +msgstr "Toner baixo." + +msgid "Too many active jobs." +msgstr "Muitos trabalhos ativos." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Muitos valores de job-sheets (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Muitos valores de printer-state-reasons (%d > %d)!" + +msgid "Transparency" +msgstr "Transparência" + +msgid "Tray" +msgstr "Bandeja" + +msgid "Tray 1" +msgstr "Bandeja 1" + +msgid "Tray 2" +msgstr "Bandeja 2" + +msgid "Tray 3" +msgstr "Bandeja 3" + +msgid "Tray 4" +msgstr "Bandeja 4" + +msgid "URI Too Long" +msgstr "URI Muito Extenso" + +msgid "US Executive" +msgstr "Executivo EUA" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "Duplo Carta EUA" + +msgid "US Legal" +msgstr "Legal EUA" + +msgid "US Legal (Oversize)" +msgstr "Legal EUA (Muito Grande)" + +msgid "US Letter" +msgstr "Carta EUA" + +msgid "US Letter (Oversize)" +msgstr "Carta EUA (Muito Grande)" + +msgid "US Letter (Small)" +msgstr "Carta EUA (Pequeno)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Porta Serial USB nº%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Não é possível acessar cupsd.conf file:" + +msgid "Unable to add RSS subscription:" +msgstr "Não é possível adicionar a inscrição RSS:" + +msgid "Unable to add class:" +msgstr "Não é possível adicionar a classe:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Não é possível adicionar o trabalho para o destino \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Não é possível adicionar a impressora:" + +msgid "Unable to allocate memory for file types!" +msgstr "Não é possível alocar memória para os tipos de arquivo!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Não é possível cancelar a inscrição RSS:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Não é possível alterar o atributo printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Não é possível alterar a impressora:" + +msgid "Unable to change server settings:" +msgstr "Não é possível alterar as configurações do servidor:" + +msgid "Unable to connect to host." +msgstr "Não é possível conectar ao host." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "" +"Não é possível copiar arquivos de driver de impressora CUPS de 64-bit (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Não é possível copiar arquivos do driver da impressora Windows de 64-bit (%" +"d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Não é possível copiar os arquivos do driver de impressora CUPS (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Não é possível copiar o arquivo PPD - %s!" + +msgid "Unable to copy PPD file!" +msgstr "Não é possível copiar o arquivo PPD!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"Não é possível copiar os arquivos do driver de impressora do Windows 2000 (%" +"d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "" +"Não é possível copiar os arquivos do driver de impressora do Windows 9x (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Não é possível copiar o roteiro de interface - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Não é possível criar printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Não é possível criar o arquivo temporário:" + +msgid "Unable to delete class:" +msgstr "Não é possível apagar a classe:" + +msgid "Unable to delete printer:" +msgstr "Não é possível apagar a impressora:" + +msgid "Unable to do maintenance command:" +msgstr "Não é possível fazer um comando de manutenção:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Não é possível editar os arquivos cupsd.conf maiores que 1MB!" + +msgid "Unable to find destination for job!" +msgstr "Não é possível buscar o destino para o trabalho!" + +msgid "Unable to find printer!\n" +msgstr "Não é possível encontrar a impressora!\n" + +msgid "Unable to get class list:" +msgstr "Não é possível obter a lista de classe:" + +msgid "Unable to get class status:" +msgstr "Não é possível obter o estado de classe:" + +msgid "Unable to get list of printer drivers:" +msgstr "Não é possível obter uma lista de drivers de impressora:" + +msgid "Unable to get printer attributes:" +msgstr "Não é possível obter os atributos de impressora:" + +msgid "Unable to get printer list:" +msgstr "Não é possível obter a lista de impressão:" + +msgid "Unable to get printer status:" +msgstr "Não é possível obter o estado da impressora:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Não é possível instalar os arquivos de drivers de impressora do Windows 2000 " +"(%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "" +"Não é possível instalar os arquivos de drivers de impressora do Windows 9x (%" +"d)!" + +msgid "Unable to modify class:" +msgstr "Não é possível modificar a classe:" + +msgid "Unable to modify printer:" +msgstr "Não é possível modificar a impressora:" + +msgid "Unable to move job" +msgstr "Não é possível mover o trabalho" + +msgid "Unable to move jobs" +msgstr "Não é possível mover os trabalhos" + +msgid "Unable to open PPD file" +msgstr "Não é possível abrir o arquivo PPD" + +msgid "Unable to open PPD file:" +msgstr "Não é possível abrir o arquivo PPD:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Não é possível abrir o arquivo cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Não é possível abrir o documento %d no trabalho %d!" + +msgid "Unable to print test page:" +msgstr "Não é possível imprimir uma página de teste:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Não é possível executar \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Não é possível enviar o comando ao driver da impressora!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Não é possível configurar o driver de impressora do Windows (%d)!" + +msgid "Unable to set options:" +msgstr "Não é possível definir as opções:" + +msgid "Unable to set server default:" +msgstr "Não é possível definir o padrão do servidor:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Não é possível carregar o arquivo cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Não é possível usar o driver de classe USB de legado!\n" + +msgid "Unauthorized" +msgstr "Não autorizado" + +msgid "Units" +msgstr "Unidades" + +msgid "Unknown" +msgstr "desconhecido" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "printer-error-policy desconhecido \"%s\"." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "printer-op-policy desconhecido \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Conjunto de caracteres incompatíveis \"%s\"!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Compressão não compatível \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Atributo de compressão não compatível %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Formato não compatível \"%s\"!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Formato não compatível '%s'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Formato não compatível '%s/%s'!" + +msgid "Unsupported value type" +msgstr "Tipo de valor incompatível" + +msgid "Upgrade Required" +msgstr "Atualização Requerida" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "" +"Usage: %s opções de cópias de título do usuário do trabalho [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Usage: opções de cópias de título de usuário %s job-id [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Usage: arquivo de opções de cópias de título de usuário %s job-id \n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Opções:\n" +" -E Encriptar a conexão ao servidor\n" +" -H samba-server Usar o servidor SAMBA denominado\n" +" -U samba-user Autenticar usando o usuário do SAMBA denominado\n" +" -a Exportar todas as impressoras\n" +" -h cups-server Usar o servidor CUPS denominado\n" +" -v Ser detalhado (mostrar comandos)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Opções:\n" +"\n" +" -E Ativar encriptação\n" +" -U username Especificar username\n" +" -h server[:port] Especificar endereço do servidor\n" +"\n" +" --[no-]debug-logging Ativar/desativar registro de depuração\n" +" --[no-]remote-admin Ativar/desativar administração remota\n" +" --[no-]remote-any Permitir/evitar acesso a partir da Internet\n" +" --[no-]remote-printers Mostrar/ocultar impressoras remotas\n" +" --[no-]share-printers Ativar/desativar compartilhamento de impressora\n" +" --[no-]user-cancel-any Permitir/evitar que usuários cancelem qualquer " +"trabalho\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Carregar arquivo de configuração alternativa\n" +"-f Executar em segundo plano\n" +"-F Executar em segundo plano, porém destacar\n" +"-h Mostrar esta mensagem de uso\n" +"-l Executar cupsd a partir de launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Opções:\n" +"\n" +" -h Mostrar utilização do programa\n" +"\n" +" Nota: este programa apenas valida os comentários DSC, não o próprio " +"PostScript.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Usage: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Usage: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Opções:\n" +" -D name=value Definir variável denominada ao valor.\n" +" -I include-dir Adicionar diretório de inclusão ao caminho da busca.\n" +" -c catalog.po Carregar o catálogo da mensagem especificada.\n" +" -d output-dir Especificar o diretório de saída.\n" +" -l lang[,lang,...] Especificar o(s) idioma(s) de saída (local).\n" +" -m Usar o valor ModelName como nome de arquivo.\n" +" -t Testar PPDs em vez de gerá-los.\n" +" -v Ser detalhado (mais v's para maior detalhamento).\n" +" -z Comprimir arquivos PPD usando GNU zip.\n" +" --cr Terminar linhas com CR (Mac OS 9).\n" +" --crlf Terminar linhas com CR + LF (Windows).\n" +" --lf Terminar linhas com LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Definir variável denominada ao valor.\n" +"Options:\n" +" -I include-dir Adicionar diretório de inclusão ao caminho da busca.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Opções:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Opções:\n" +" -D name=value Definir variável denominada ao valor.\n" +" -I include-dir Adicionar diretório de inclusão ao caminho da busca.\n" +" -v Ser detalhado (mais v's para maior detalhamento).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Usage: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Valor usa comprimento indefinido" + +msgid "VarBind uses indefinite length" +msgstr "VarBind usa comprimento indefinido" + +msgid "Version uses indefinite length" +msgstr "Versão usa comprimento indefinido" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Adicionando somente as primeiras %d impressoras encontradas" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Boleano esperado para opção waiteof \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Falha ao ler o pedido side-channel!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "" +"WARNING: A opção \"%s\" não pode ser incluída através de IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: A impressora não responde\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: A impressora enviou um EOF inesperado\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: O host remoto não repondeu com o byte de estado de comando após %d " +"segundos!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: O host remoto não repondeu com o byte de estado de controle após %d " +"segundos!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: O host remoto não repondeu com o byte de estado de dados após %d " +"segundos!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "" +"WARNING: Tempo esgotado para comando SCSI (%d); tentando novamente...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Este documento não está de acordo com o Adobe Document Structuring " +"Conventions e pode não ser impresso corretamente!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Não é possível abrir \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Não é possível enviar o pedido de estado PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Pacote PAP do tipo %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Pacote PAP desconhecido do tipo %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Escolha desconhecida \"%s\" para a opção \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Opção desconhecida \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Taxa de transmissão não compatível %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: número esperado para a opção de estado \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: recuperável: O host de rede '%s' está ocupado; tentará novamente em " +"%d segundos...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Warning, nenhum driver de impressora do Windows 2000 está instalado!" + +msgid "Yes" +msgstr "Sim" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Você deve acessar esta página usando a URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "Envelope You4" + +msgid "ZPL Label Printer" +msgstr "Impressora de Etiquetas ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "anulado" + +msgid "canceled" +msgstr "cancelado" + +msgid "completed" +msgstr "concluído" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: use a opção -f para especificar um arquivo para converter.\n" + +msgid "cups-deviced failed to execute." +msgstr "falha de cups-deviced ao executar." + +msgid "cups-driverd failed to execute." +msgstr "falha de cups-driverd ao executar." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Nenhum arquivo PPD para a impressora \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: não é possível conectar ao servidor: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Opção desconhecida \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Opção desconhecida \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Nome de arquivo de configuração esperado após a opção \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: não é possível obter o diretório atual!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Argumento desconhecido \"%s\" - anulando!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Opção desconhecida \"%c\" - anulando!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: suporte launchd(8) não compilado, executando em modo normal.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: número de documento inválido %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: ID de trabalho inválido %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Apenas um filename pode ser especificado!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: não é possível obter o arquivo de trabalho - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: A opção -q é incompatível com a opção -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: A opção -v é incompatível com a opção -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "dispositivo para %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "dispositivo para %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index usa comprimento indefinido" + +msgid "error-status uses indefinite length" +msgstr "error-status usa comprimento indefinido" + +msgid "held" +msgstr "mantido" + +msgid "help\t\tget help on commands\n" +msgstr "ajuda\t\tobter ajuda sobre os comandos\n" + +msgid "idle" +msgstr "ocioso" + +msgid "job-printer-uri attribute missing!" +msgstr "Atributo job-printer-uri ausente!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: O nome de classe pode conter apenas caracteres imprimíveis!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: PPD esperado após a opção '-P'!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Permitir/negar esperado:userlist após a opção '-u'!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Classe esperada após opção '-r'!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Nome de classe esperado após a opção '-c'!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Descrição esperada após a opção '-D'!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: URI de dispositivo esperado após a opção '-v'!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Tipo(s) de arquivo esperado após a opção '-I'!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Hostname esperado após a opção '-h'!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Interface esperada após a opção '-i'!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Localização esperada após a opção '-L'!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Modelo esperado após a opção '-m'!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: name=value esperado após a opção '-o'!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Impressora esperada após a opção '-p'!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Nome de impressora esperada após a opção '-d'!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Impressora ou classe esperada após a opção '-x'!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Nenhum nome de membro foi visto!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: A impressora %s já é um membro de classe %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: A impressora %s não é um membro de classe %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "" +"lpadmin: O nome da impressora pode conter apenas caracteres imprimíveis!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível adicionar uma impressora à classe:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Não é possível conectar-se ao servidor: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Não é possível abrir um arquivo PPD \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Não é possível abrir o arquivo \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível remover uma impressora da classe:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar o arquivo PPD:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar o URI de dispositivo:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar o roteiro de interface ou arquivo PPD:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar o roteiro de interface:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar a descrição da impressora:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar a localização da impressora:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Não é possível configurar as opções da impressora:\n" +" Você deve especificar um nome de impressora primeiro!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Opção permitir/negar desconhecida \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Argumento desconhecido '%s'!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Opção desconhecida '%c'!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Aviso - lista de tipo de conteúdo ignorada!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "" +"lpinfo: seqüência de caracteres de ID de dispositivo 1284 esperada após --" +"device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: idioma esperado após --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: modelar e fazer esperado após --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: seqüência de caracteres de produto esperada após --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: lista de esquema esperada após --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: lista de esquema esperada após --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: tempo esgotado esperado após --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Argumento desconhecido '%s'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Opção desconhecida '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: opção desconhecida '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Não é possível conectar-se ao servidor: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Argumento desconhecido '%s'!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Opção desconhecida '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Nenhuma impressora!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Não é possível adicionar impressora ou instância: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Não é possível obter o arquivo PPD para %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Não é possível abrir o arquivo PPD para %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Impressora ou classe desconhecidas!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Apenas o root pode adicionar ou apagar senhas!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Arquivo de senha ocupado!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Arquivo de senha não atualizado!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Desculpe, a senha não coincide!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Desculpe, senha rejeitada.\n" +"A sua senha deve ter pelo menos 6 caracteres, não pode conter\n" +"o seu nome de usuário e deve possuir pelo menos uma letra e um número.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Desculpe, as senhas não coincidem!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "" +"lppasswd: Não é possível copiar a seqüência de caracteres da senha: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Não é possível abrir o arquivo de senha: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Não é possível gravar para o arquivo de senha: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: falha ao fazer backup do arquivo de senha antigo: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: falha ao renomear o arquivo de senha: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: usuário \"%s\" e grupo \"%s\" não existem.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: erro - %s destino não existente de nomes de variáveis de ambiente \"%" +"s\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "membros de classe %s:\n" + +msgid "no entries\n" +msgstr "nenhuma entrada\n" + +msgid "no system default destination\n" +msgstr "nenhum destino padrão de sistema\n" + +msgid "notify-events not specified!" +msgstr "notify-events não especificado!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "URI notify-recipient-uri \"%s\" já foi usado!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI \"%s\" usa um esquema desconhecido!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d não confiável!" + +msgid "pending" +msgstr "pendente" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: adicionando diretório de inclusão \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: adicionando/atualizando texto UI de %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: valor booleano inválido (%s) na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: nome de resolução inválido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: palavra-chave de estado inválido %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: substituição de variável inválida ($%c) na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: escolha encontrada na linha %d de %s com nenhuma Opção!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: duplicar #po para local %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: definição de filtro esperada na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: nome de programa esperado na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: valor booleano esperado na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: conjunto de caracteres depois de Font na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: código de escolha esperado na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: nome/texto de escolha esperado na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: ordem de cor esperada para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: colorspace esperada para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: compressão esperada para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: seqüência de caracteres de restrição esperada para UIConstraints na " +"linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: palavra-chave do tipo de driver esperado após DriverType na linha %d " +"de %s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: tipo de dúplex esperado após Duplex na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: codificação esperada após Font na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: nome de arquivo esperado após #po %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: nome/texto de grupo esperado na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: nome de arquivo de inclusão esperado na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: número inteiro esperado na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: localidade esperada após #po na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Nome esperado após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Nome esperado após FileName na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Nome esperado após Font na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Nome esperado após Manufacturer na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: nome esperado após MediaSize na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: nome esperado após ModelName na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: nome esperado após PCFileName na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: nome/texto esperado após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: nome/texto esperado após Installable na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: nome/texto esperado após Resolution na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: combinação de nome/texto esperado para ColorModel na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: nome/texto de opção esperado na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: seção de opção esperada na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: tipo de opção esperada na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: campo de substituição esperado após Resolution na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: número real esperado na linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: resolução/tipo de mídia esperado após ColorProfile na linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: resolução/tipo de mídia esperado após SimpleColorProfile na linha %d " +"de %s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: seletor esperado após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: estado esperado após Font na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "" +"ppdc: seqüência de caracteres esperada após Copyright na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "" +"ppdc: seqüência de caracteres esperada após Version na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: dois nomes de opção esperados na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: valor esperado após %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: versão esperada após Font na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: nome de arquivo #include/#po inválido \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: custo inválido para filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: tipo MIME vazio inválido para filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: nome de programa vazio inválido para filtro na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: seção de opção inválida \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: tipo de opção inválida \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: carregando arquivo de informações de driver \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: carregando mensagens para localidade \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: carregando mensagens de \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: #endif ausente no final de \"%s\"!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: #if ausente na linha %d de %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: nenhum catálogo de mensagem fornecido para a localidade %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: opção %s redefinida com um tipo diferente na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: a restrição da opção deve *name na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: muitos aninhados #if's na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: não é possível criar um arquivo PPD \"%s\" - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: não é possível criar o diretório de saída %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: não é possível criar canais de saída: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: não é possível executar cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Não é possível buscar o arquivo #po %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Não é possível buscar o arquivo de inclusão \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Não é possível buscar a localização para \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Não é possível carregar o arquivo de localização \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Variável indefinida (%s) na linha %d de %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: tipo de driver desconhecido %s na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: tipo de dúplex desconhecido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: tamanho de mídia desconhecido \"%s\" na linha %d de %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: token desconhecido \"%s\" visto na linha %d de %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: caracteres delimitadores desconhecidos em número real \"%s\" na linha %" +"d de %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "" +"ppdc: seqüência de caracteres não finalizados começando com %c na linha %d " +"de %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: gravando %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: gravando arquivos PPD no diretório \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: LanguageVersion inválido \"%s\" em %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: ignorando arquivo PPD %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: não é possível fazer o backup de %s em %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "impressora %s desativada desde %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "impressora %s está ociosa. ativada desde %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "impressora %s agora está imprimindo %s-%d. ativada desde %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "impressora %s/%s desativada desde %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "impressora %s/%s está ociosa. ativada desde %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "impressora %s/%s agora está imprimindo %s-%d. ativada desde %s\n" + +msgid "processing" +msgstr "processando" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "id solicitado é %s-%d (%d arquivo(s))\n" + +msgid "request-id uses indefinite length" +msgstr "request-id usa comprimento indefinido" + +msgid "scheduler is not running\n" +msgstr "o programador não está executando\n" + +msgid "scheduler is running\n" +msgstr "o programador está executando\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "falha de stat de %s: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "estado status\t\tshow de daemon e da fila\n" + +msgid "stopped" +msgstr "parado" + +#, c-format +msgid "system default destination: %s\n" +msgstr "destino padrão de sistema: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "destino padrão de sistema: %s/%s\n" + +msgid "unknown" +msgstr "desconhecido" + +msgid "untitled" +msgstr "sem título" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings usa comprimento indefinido" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN Arquivo APDialogExtension ausente \"%s\"\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN Arquivo APPrinterIconPath ausente \"%s\"\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Não é possível abrir %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Não é possível abrir %s - %s on-line %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 ppp da escala de cinza" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: URI de dispositivo ausente URI em command-line e nenhuma variável " +#~ "de ambiente DEVICE_URI!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Não é possível criar o arquivo temporário - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Não é possível criar o arquivo temporário: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Não é possível abrir o arquivo temporário" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: O filtro pdftops bloqueou no sinal %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: O filtro pdftops saiu com estado %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Erro de impressora desconhecido (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Usage: converter [ options ]\n" +#~ "\n" +#~ "Opções:\n" +#~ "\n" +#~ " -f filename Definir arquivo para conversão (senão stdin)\n" +#~ " -o filename Definir para ser gerado (senão stdout)\n" +#~ " -i mime/type Definir tipo MIME de entrada (senão auto-typed)\n" +#~ " -j mime/type Definir tipo MIME de saída (senão application/" +#~ "pdf)\n" +#~ " -P filename.ppd Definir arquivo PPD\n" +#~ " -a 'name=value ...' Definir opção(ões)\n" +#~ " -U username Definir nome do usuário para trabalho\n" +#~ " -J title Definir título\n" +#~ " -c copies Definir número de cópias\n" +#~ " -u Remover o arquivo PPD ao terminar\n" +#~ " -D Remover o arquivo de entrada ao terminar\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Opções:\n" +#~ "\n" +#~ " -c cupsd.conf Definir arquivo cupsd.conf para uso\n" +#~ " -j job-id[,N] Arquivo de filtro N do trabalho especificado (o padrão " +#~ "é o arquivo 1)\n" +#~ " -n cópias Definir número de cópias\n" +#~ " -o name=value Definir opção(ões)\n" +#~ " -p filename.ppd Definir arquivo PPD\n" +#~ " -t title Definir título\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Opções:\n" +#~ "\n" +#~ " -R root-directory Definir raiz alternada\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Expedir avisos em vez de erros\n" +#~ " -q Executar silenciosamente\n" +#~ " -r Usar modo aberto 'relaxed'\n" +#~ " -v Ser levemente detalhado\n" +#~ " -vv Ser bastante detalhado\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: não é possível criar um arquivo temporário: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Não é possível criar um arquivo temporário - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Não é possível criar um arquivo temporário: %s\n" diff --git a/locale/cups_ru.po b/locale/cups_ru.po new file mode 100644 index 0000000000..0880284300 --- /dev/null +++ b/locale/cups_ru.po @@ -0,0 +1,5686 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(все)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(нет)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\tзаписей: %d\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tПосле ошибки: продолжить\n" + +msgid "\tAlerts:" +msgstr "\tПредупреждения:" + +msgid "\tBanner required\n" +msgstr "\tТребуется баннер\n" + +msgid "\tCharset sets:\n" +msgstr "\tНабор символов устанавливает:\n" + +msgid "\tConnection: direct\n" +msgstr "\tПодключение: прямое\n" + +msgid "\tConnection: remote\n" +msgstr "\tПодключение: удаленное\n" + +msgid "\tDefault page size:\n" +msgstr "\tРазмер страницы по умолчанию:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tВысота по умолчанию:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tНастройки порта по умолчанию:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tОписание: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tФорма подключения:\n" +"\tТипы контента: любые\n" +"\tТипы принтеров: неизвестно\n" + +msgid "\tForms allowed:\n" +msgstr "\tРазрешенные формы:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tИнтерфейс: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tИнтерфейс: %s/интерфейсы/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tИнтерфейс: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tРасположение: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tПри ошибке: не выводить предупреждение\n" + +msgid "\tUsers allowed:\n" +msgstr "\tРазрешенные пользователи:\n" + +msgid "\tUsers denied:\n" +msgstr "\tЗапрещенные пользователи:\n" + +msgid "\tdaemon present\n" +msgstr "\tдемон присутствует\n" + +msgid "\tno entries\n" +msgstr "\tнет записей\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tпринтер на скорости -1 устройства «%s»\n" + +msgid "\tprinting is disabled\n" +msgstr "\tпечать отключена\n" + +msgid "\tprinting is enabled\n" +msgstr "\tпечать включена\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tочередь для %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tочередь отключена\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tочередь включена\n" + +msgid "\treason unknown\n" +msgstr "\tпричина неизвестна\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" ПОДРОБНЫЕ РЕЗУЛЬТАТЫ ТЕСТА СООТВЕТСТВИЯ\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Стр. 15, раздел 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Стр. 15, раздел 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Стр. 19, раздел 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Стр. 20, раздел 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Стр. 27, раздел 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Стр. 42, раздел 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Стр. 16-17, раздел 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Стр. 42-45, раздел 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Стр. 45-46, раздел 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Стр. 48-49, раздел 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Стр. 52-54, раздел 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f байт\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " PASS Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " PASS DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " PASS DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " PASS FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " PASS FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " PASS LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " PASS LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " PASS Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " PASS ModelName\n" + +msgid " PASS NickName\n" +msgstr " PASS NickName\n" + +msgid " PASS PCFileName\n" +msgstr " PASS PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " PASS PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " PASS PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " PASS PageSize\n" + +msgid " PASS Product\n" +msgstr " PASS Product\n" + +msgid " PASS ShortNickName\n" +msgstr " PASS ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN «%s %s» конфликтует с «%s %s»\n" +" (constraint=«%s %s %s %s»)\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s не содержит соответствующих параметров!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s использует общий префикс совместно с %s\n" +" REF: Стр. 15, раздел 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN Значения, используемые по умолчанию, конфликтуют!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Ключевое слово параметра дуплекса %s может привести к " +"некорректным результатам. Используйте имя «Duplex»!\n" +" REF: Стр. 122, раздел 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" WARN Файл содержит комбинацию окончаний строки CR, LF и CR LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding требуется спецификацией PPD 4.3.\n" +" REF: Стр. 56-57, раздел 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN Строка %d содержит только пробелы!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN LanguageEncoding требуется спецификацией PPD 4.3.\n" +" REF: Стр. 58-59, раздел 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN PPD-файлы не из Windows должны использовать строки только с " +"окончанием LF, а не с CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN Устаревшая версия PPD %.1f!\n" +" REF: Стр. 42, раздел 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName длиннее чем 8.3 нарушает спецификацию PPD.\n" +" REF: Стр. 61-62, раздел 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN Protocols содержит PJL, но атрибуты JCL не настроены.\n" +" REF: Стр. 78-79, раздел 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN ShortNickName требуется спецификацией PPD 4.3.\n" +" REF: Стр. 64-65, раздел 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s не существует!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Неверный %s выбор %s!\n" +" REF: Стр. 122, раздел 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s Неверный перевод UTF-8 «%s» для параметра %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s Неверный перевод UTF-8 «%s» для параметра %s, выбора %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Неверное значение cupsFilter «%s»!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Неверный cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Неверное значение cupsPreFilter «%s»!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Неверный cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Неверный язык «%s»!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Пустой cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Перевод «%s» отсутствует для параметра %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s Перевод «%s» отсутствует для параметра %s, выбора %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Выбор *%s %s отсутствует в UIConstraints «*%s %s *%s %s»!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Выбор *%s %s отсутствует в cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Файл cupsFilter отсутствует «%s»\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Файл cupsICCProfile отсутствует «%s»!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Файл cupsFilter «%s» отсутствует\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Отсутствует cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Параметр %s отсутствует в UIConstraints «*%s %s *%s %s»!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Параметр %s отсутствует в cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Основной перевод «%s» не включен в файл!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" ТРЕБУЕТСЯ %s: %s не определяет выбор «Нет»!\n" +" REF: Стр. 122, раздел 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " Хеш-значение %s cupsICCProfile %s конфликтует с %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s создает цикл!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Для выбора %s имена %s и %s различаются только регистром " +"символов!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FAIL** %s должно соответствовать 1284DeviceID!\n" +" REF: Стр. 72, раздел 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ Default%s %s\n" +" REF: Стр. 40, раздел 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ DefaultImageableArea %s!\n" +" REF: Стр. 102, раздел 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ DefaultPaperDimension %s!\n" +" REF: Стр. 103, раздел 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ JobPatchFile атрибут в файле\n" +" REF: Стр. 24, раздел 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ Manufacturer (должен быть «HP»)\n" +" REF: Стр. 211, таблица D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ Manufacturer (должен быть «Oki»)\n" +" REF: Стр. 211, таблица D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** НЕВЕРНОЕ ModelName – «%c» не разрешено в строке.\n" +" REF: Стр. 59-60, раздел 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** НЕВЕРНАЯ PSVersion – не «(string) int».\n" +" REF: Стр. 62-64, раздел 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ Product – не «(string)».\n" +" REF: Стр. 62, раздел 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FAIL** НЕВЕРНЫЙ ShortNickName – длиннее чем 31 симв.\n" +" REF: Стр. 64-65, раздел 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FAIL** Неверный %s выбор %s!\n" +" REF: Стр. 84, раздел 5,9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Неверная FileVersion \"%s\"\n" +" REF: Стр. 56, раздел 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** Неверная FormatVersion \"%s\"\n" +" REF: Стр. 56, раздел 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr "" +" **FAIL** Неверный LanguageEncoding %s – должно быть ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr "" +" **FAIL** Неверный LanguageVersion %s – должен быть английский!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr "" +" **FAIL** Не удается интерпретировать код параметра по умолчанию: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FAIL** Стандартный перевод для параметра %s выбора %s содержит 8-" +"битовые символы!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FAIL** Стандартный перевод для параметра %s содержит 8-битовые " +"символы!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Имена групп %s и %s различаются только регистром символов!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FAIL** Для выбора %s имя %s встречается несколько раз!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FAIL** Имена параметров %s и %s различаются только регистром " +"символов!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ Default%s\n" +" REF: Стр. 40, раздел 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ DefaultImageableArea\n" +" REF: Стр. 102, раздел 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ DefaultPaperDimension\n" +" REF: Стр. 103, раздел 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ FileVersion\n" +" REF: Стр. 56, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ FormatVersion\n" +" REF: Стр. 56, раздел 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ ImageableArea для PageSize %s\n" +" REF: Стр. 41, раздел 5.\n" +" REF: Стр. 102, раздел 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ LanguageEncoding\n" +" REF: Стр. 56-57, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ LanguageVersion\n" +" REF: Стр. 57-58, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ Manufacturer\n" +" REF: Стр. 58-59, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ ModelName\n" +" REF: Стр. 59-60, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ NickName\n" +" REF: Стр. 60, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ PCFileName\n" +" REF: Стр. 61-62, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ PSVersion\n" +" REF: Стр. 62-64, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ PageRegion\n" +" REF: Стр. 100, раздел 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ PageSize\n" +" REF: Стр. 41, раздел 5.\n" +" REF: Стр. 99, раздел 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ PageSize\n" +" REF: Стр. 99-100, раздел 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ PaperDimension для PageSize %s\n" +" REF: Стр. 41, раздел 5.\n" +" REF: Стр. 103, раздел 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ Product\n" +" REF: Стр. 62, раздел 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FAIL** ТРЕБУЕТСЯ ShortNickName\n" +" REF: Стр. 64-65, раздел 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " ОБНАРУЖЕНО ОШИБОК: %d\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Неверный %%%%BoundingBox: в строке %d!\n" +" REF: Стр. 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Неверная %%%%Page: в строке %d!\n" +" REF: Стр. 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Неверные %%%%Pages: в строке %d!\n" +" REF: Стр. 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Строка %d длиннее 255 символов (%d)!\n" +" REF: Стр. 25, Длина строки\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" %!PS-Adobe-3.0 отсутствует в первой строке!\n" +" REF: Стр. 17, 3.1 Соответствующие документы\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Комментарий %%EndComments отсутствует!\n" +" REF: Стр. 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Отсутствующий или неверный %%BoundingBox: комментарий!\n" +" REF: Стр. 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Отсутствующая или неверная %%Page: комментарий!\n" +" REF: Стр. 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Отсутствующие или неверные %%Pages: комментарий!\n" +" REF: Стр. 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " ОШИБОК НЕ ОБНАРУЖЕНО\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Обнаружено строк длиннее 255 символов: %d!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " Слишком много комментариев %%BeginDocument!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " Слишком много комментариев %%EndDocument!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " WARNING: файл содержит бинарные данные!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " WARNING: нет комментария %%EndComments в файле!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " WARNING: устаревшая версия DSC %.1f в файле!\n" + +msgid " FAIL\n" +msgstr " FAIL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FAIL\n" +" **FAIL** Не удается открыть PPD-файл – %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FAIL\n" +" **FAIL** Не удается открыть PPD-файл – %s в строке %d.\n" + +msgid " PASS\n" +msgstr " PASS\n" + +msgid "#10 Envelope" +msgstr "#10 Envelope" + +msgid "#11 Envelope" +msgstr "#11 Envelope" + +msgid "#12 Envelope" +msgstr "#12 Envelope" + +msgid "#14 Envelope" +msgstr "#14 Envelope" + +msgid "#9 Envelope" +msgstr "#9 Envelope" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f байт\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f байт\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f мм" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f — %.0f x %.0f мм" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f дюймов" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f-%.2f x %.2f дюймов" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s принимает запросы с момента %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s не может быть изменен." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s не выполнено версией CUPS для lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s не готов\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s готов\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s готов и печатает\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s не принимает запросы с момента %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s не поддерживается!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s принимает запросы с момента %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s не принимает запросы с момента %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [задание %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: ошибка %s: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Дальнейшие действия неизвестны!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: Ошибка – %s переменная окружения указывает несуществующее назначение «%" +"s»!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Ошибка – неверный ID задания!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "" +"%s: Ошибка – невозможно одновременно печатать файлы и изменять задания!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Ошибка – не удается печатать из stdin, если предоставлены файлы или ID " +"задания!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Ошибка – после параметра «-S» должен идти набор символов!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Ошибка – после параметра «-T» должен быть указан тип контента!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "" +"%s: Ошибка – после параметра «-n» должно быть указано количество копий!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Ошибка – после параметра «-#» должен быть указан номер копии!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Ошибка – после параметра «-P» должно быть указано назначение!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Ошибка – после параметра «-b» должно быть указано назначение!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Ошибка – после параметра «-d» должно быть указано назначение!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Ошибка – после параметра «-f» должна быть указана форма!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Ошибка – после параметра «-H» должно быть указано имя хоста!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Ошибка – после параметра «-H» должно быть указано имя хоста!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Ошибка – после параметра «-h» должно быть указано имя хоста!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Ошибка – после параметра «-y» должен быть указан список режимов!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Ошибка – после параметра «-%c» должно быть указано имя!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "" +"%s: Ошибка – после параметра «-o» должна быть указана строка параметра!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Ошибка – после параметра «-P» должен идти список страниц!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Ошибка – после параметра «-%c» должен быть указан приоритет!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Ошибка – после параметра «-r» должен идти текст причины!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Ошибка – после параметра «-t» должен быть указан заголовок!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "" +"%s: Ошибка – после параметра «-U» должно быть указано имя пользователя!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "" +"%s: Ошибка – после параметра «-u» должно быть указано имя пользователя!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Ошибка – после параметра «-%c» должно быть указано значение!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Ошибка – требуется «завершено», «не завершено» или «все» после параметра «-" +"W»!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Ошибка – нет доступного назначения по умолчанию.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Ошибка – приоритет должен быть от 1 до 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Ошибка – планировщик не отвечает!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Ошибка – слишком много файлов – «%s»\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Ошибка – не удается получить доступ к «%s» – %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Ошибка – не удается поставить в очередь из stdin - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Ошибка – неизвестное назначение «%s»!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Ошибка – неизвестное назначение «%s/%s»!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Ошибка – неизвестный параметр «%c»!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Ошибка – неизвестный параметр «%s»!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: После параметра «-i» должен быть указан ID задания!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Фильтр «%s» недоступен: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Неверное имя назначения в списке «%s»!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Неверная строка фильтра «%s»\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Требуется ID задания («-i jobid») перед «-H restart»!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Нет фильтра для преобразования из %s/%s в %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Операция не удалась: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Нет скомпилированной поддержки шифрования!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Не удается подключиться к серверу\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Не удается установить связь с сервером!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Не удается определить тип MIME «%s»!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Не удается открыть %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Не удается открыть PPD-файл: %s в строке %d.\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Не удается прочитать базу данных MIME в «%s» или «%s»!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Неизвестное назначение «%s»!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Неизвестный MIME-тип назначения %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Неизвестный параметр «%c»!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Неизвестный MIME-тип источника %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Внимание – модификатор формата «%c» не поддерживается – вывод может быть " +"неправильным!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Внимание – параметр набора символов пропущен!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Внимание – параметр типа контента пропущен!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Внимание – параметр формы пропущен!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Внимание – параметр режима пропущен!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "" +"%s: ошибка – переменная окружения %s указывает несуществующее назначение «%" +"s»!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "" +"%s: ошибка – после параметра «-o» должна идти запись вида option=value!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: ошибка – нет доступного назначения по умолчанию.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 дюйм/с" + +msgid "1.25x0.25\"" +msgstr "1,25x0,25\"" + +msgid "1.25x2.25\"" +msgstr "1,25x2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 дюйма/с" + +msgid "1.50x0.25\"" +msgstr "1,50x0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50x0,50\"" + +msgid "1.50x1.00\"" +msgstr "1,50x1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50x2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 дюймов/с" + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 мм/с" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 дюймов/с" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 дюймов/с" + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 мм/с" + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 мм/с" + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 мм/с" + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 дюйма/с" + +msgid "2-Sided Printing" +msgstr "двусторонняя печать" + +msgid "2.00x0.37\"" +msgstr "2,00x0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00x0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00x1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00x1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00x2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00x3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00x4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00x5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25x0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25x1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25x4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25x5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38x5,50\"" + +msgid "2.5 inches/sec." +msgstr "2,5 дюйма/с" + +msgid "2.50x1.00\"" +msgstr "2,50x1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50x2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75x1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 мм/с" + +msgid "200 mm/sec." +msgstr "200 мм/с" + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "Тип 24-Pin" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 мм/с" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 дюйма/с" + +msgid "3.00x1.00\"" +msgstr "3,00x1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00x1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00x2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00x3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00x5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25x2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25x5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25x5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25x5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25x7,83\"" + +msgid "3.5\" Disk" +msgstr "Диск 3.5\"" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "Диск 3.5\" - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50x1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 мм/с" + +msgid "300 mm/sec." +msgstr "300 мм/с" + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 дюйма/с" + +msgid "4.00x1.00\"" +msgstr "4,00x1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00x13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00x2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00x2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00x3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00x4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00x5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00x6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00x6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 мм/с" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 дюймов/с" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 дюймов/с" + +msgid "6.00x1.00\"" +msgstr "6,00x1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00x2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00x3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00x4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00x5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00x6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00x6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 мм/с" + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 дюймов/с" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 дюймов/с" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00x1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00x2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00x3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00x4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00x5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00x6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00x6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 мм/с" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 дюймов/с" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "Тип 9-Pin" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Неверная команда справки неизвестна\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Для экспорта драйверов принтера требуется пароль Samba!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "Для экспорта драйверов принтера требуется имя пользователя Samba!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "Класс с именем «%s» уже существует!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "Принтер с именем «%s» уже существует!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (расширенный)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (расширенный)" + +msgid "A4 (Small)" +msgstr "A4 (уменьшенный)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (расширенный)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Принять задания" + +msgid "Accepted" +msgstr "Принято" + +msgid "Add Class" +msgstr "Добавить класс" + +msgid "Add Printer" +msgstr "Добавить принтер" + +msgid "Add RSS Subscription" +msgstr "Добавить подписку на RSS" + +msgid "Address" +msgstr "Адрес" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Адрес - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Администрация" + +msgid "Always" +msgstr "Всегда" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Исполнительное устройство" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Попытка установить %s printer-state на неверное значение %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Группы атрибутов не действуют (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Неверный указатель NULL dests" + +msgid "Bad OpenGroup" +msgstr "Неверное значение OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Неверное значение OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Неверное значение OrderDependency" + +msgid "Bad Request" +msgstr "Неверный запрос" + +msgid "Bad SNMP version number" +msgstr "Неверный номер версии SNMP" + +msgid "Bad UIConstraints" +msgstr "Неверное значение UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Неверное значение количества копий %d." + +msgid "Bad custom parameter" +msgstr "Неверный индивидуальный параметр" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Неверный URI устройства «%s»!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Неверное значение device-uri «%s»!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Неверная схема device-uri «%s»!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Неверное значение document-format «%s»!" + +msgid "Bad filename buffer!" +msgstr "Ошибка в буфере filename!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Неверный атрибут шрифта: %s\n" + +msgid "Bad job-priority value!" +msgstr "Неверное значение job-priority!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Неверное значение job-sheets «%s»!" + +msgid "Bad job-sheets value type!" +msgstr "Неверный тип значения job-sheets!" + +msgid "Bad job-state value!" +msgstr "Неверное значение job-state!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Неверный атрибут job-uri «%s»!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Неверное значение notify-pull-method «%s»!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Неверный URI notify-recipient-uri «%s»!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Неверное значение number-up %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Неверный параметр + выбор в строке %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Неверные значения page-ranges %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Неверное значение port-monitor «%s»!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Неверное значение printer-state %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Неверный номер версии запроса %d.%d!" + +msgid "Bad subscription ID!" +msgstr "Неверный ID подписки!" + +msgid "Banners" +msgstr "Баннеры" + +msgid "Billing Information: " +msgstr "Реквизиты для выставления счета: " + +msgid "Bond Paper" +msgstr "Документная бумага" + +msgid "C0 Envelope" +msgstr "Конверт C0" + +msgid "C1 Envelope" +msgstr "Конверт C1" + +msgid "C2 Envelope" +msgstr "Конверт C2" + +msgid "C3 Envelope" +msgstr "Конверт C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Конверт C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Конверт C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Конверт C6" + +msgid "C65 Envelope" +msgstr "Конверт C65" + +msgid "C7 Envelope" +msgstr "Конверт C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Принтер для печати этикеток CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Отменить подписку на RSS" + +msgid "Change Settings" +msgstr "Изменить настройки" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Набор символов «%s» не поддерживается!" + +msgid "Chou3 Envelope" +msgstr "Конверт Chou3" + +msgid "Chou4 Envelope" +msgstr "Конверт Chou4" + +msgid "Classes" +msgstr "Классы" + +msgid "Clean Print Heads" +msgstr "Очистить головки принтера" + +msgid "Color" +msgstr "Цвет" + +msgid "Color Mode" +msgstr "Цветной режим" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Команды могут быть сокращены. Команды:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Для имени сообщества длина не установлена" + +msgid "Continue" +msgstr "Продолжить" + +msgid "Continuous" +msgstr "Непрерывно" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Не удалось сканировать тип «%s»!" + +msgid "Cover open." +msgstr "Крышка открыта." + +msgid "Created" +msgstr "Создано" + +msgid "Created On: " +msgstr "Дата создания: " + +msgid "Custom" +msgstr "Индивидуальный" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Обрезать" + +msgid "Cutter" +msgstr "Резак" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "Конверт DL" + +msgid "Dark" +msgstr "Темный" + +msgid "Darkness" +msgstr "Затемненность" + +msgid "Delete Class" +msgstr "Удалить класс" + +msgid "Delete Printer" +msgstr "Удалить принтер" + +msgid "Description: " +msgstr "Описание: " + +msgid "DeskJet Series" +msgstr "Серия DeskJet" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Назначение «%s» не принимает задания." + +msgid "Developer almost empty." +msgstr "Проявитель почти закончился." + +msgid "Developer empty!" +msgstr "Проявитель закончился!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Устройство: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "Носитель для прямой термопечати" + +msgid "Disabled" +msgstr "Отключено" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Документ %d в задании %d не найден." + +msgid "Door open." +msgstr "Дверца открыта." + +msgid "Double Postcard" +msgstr "Двойная открытка" + +msgid "Driver Name: " +msgstr "Имя драйвера: " + +msgid "Driver Version: " +msgstr "Версия драйвера: " + +msgid "Duplexer" +msgstr "Дуплексер" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Не удается выделить память для информации страницы: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Не удается выделить память для массива страниц: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Принтер для печати этикеток EPL1" + +msgid "EPL2 Label Printer" +msgstr "Принтер для печати этикеток EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Неверный %%BoundingBox: комментарий просмотрен!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Неверный %%IncludeFeature: комментарий!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Неверная %%Page: комментарий в файле!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Неверный %%PageBoundingBox: комментарий в файле!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Неверный файл устройства SCSI «%s»!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Неверный файл набора символов %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Неверный тип набора символов %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Неверное значение количества столбцов %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Неверное значение cpi %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Неверная строка описания шрифта: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Неверное значение lpi %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Неверные параметры страницы!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Неверное направление текста %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Неверная ширина текста %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Целевой принтер не существует!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Дубликат %%BoundingBox: комментарий просмотрен!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Дубликат %%Pages: комментарий просмотрен!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Пустой файл печати!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Ошибка %d при отправке запроса PAPSendData: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: В строке %d из %s должна быть строка в кавычках!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Критический сбой USB!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "" +"ERROR: Обнаружена неверная команда HP-GL/2, не удается напечатать файл!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: Отсутствует %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: Отсутствует %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Отсутствует значение в строке %d в файле баннера!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Требуется строка msgid перед строкой перевода в строке %d из %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Нет %%BoundingBox: комментарий в заголовке!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Нет %%Pages: комментарий в заголовке!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Не обнаружено URI устройства в argv[0] или переменной окружения " +"DEVICE_URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Отсутствуют шрифты в файле набора символов %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Страницы не найдены!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Нет бумаги!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: Переменная окружения PRINTER не указана!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Файл печати не принят (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Принтер не отвечает\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Принтер не отвечает!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Принтер преждевременно передал индикатор EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Удаленный хост не принял контрольный файл (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Удаленный хост не принял файл данных (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "" +"ERROR: Сбой, связанный со временем ожидания при отправке данных на принтер\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Не удается добавить файл %d к заданию: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Не удается отменить задание %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Не удается копировать файл PDF" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Не удается создать сокет" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: Не удается создать временный сжатый файл печати: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Не удается создать временный файл" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Не удается выполнить pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Не удается запустить программу gs" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Не удается запустить программу pdftops" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Не удается разветвить pictwpstops: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Не удается получить запрос PAP" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Не удается получить ответ PAP" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: Не удается получить PPD-файл для принтера «%s» – %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Не удается определить стандартную зону AppleTalk" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Не удается получить атрибуты задания %d (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Не удается получить статус принтера (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Не удается обнаружить принтер «%s»!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Не удается провести поиск ответа PAP" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Не удается провести поиск принтеров AppleTalk" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Не удается ставить адрес AppleTalk" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Не удается открыть «%s» – %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Не удается открыть %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Не удается открыть файл баннера «%s» – %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Не удается открыть файл устройства «%s»: %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Не удается открыть файл «%s» – %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Не удается открыть файл «%s»: %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Не удается открыть файл изображения для печати!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Не удается открыть файл печати «%s»: %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Не удается открыть файл печати %s – %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Не удается открыть файл печати %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: Не удается открыть временный сжатый файл печати: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Не удается напечатать столбцы с текстом (%d)!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Не удается напечатать страницу с текстом %dx%d!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Не удается считать данные печати" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Не удается считать данные печати!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Не удается зарезервировать порт" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Не удается перейти к смещению %ld в файле – %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Не удается перейти к смещению %lld в файле – %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Не удается отправить команду LPD" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Не удается отправить контрольный запрос PAP" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Не удается отправить исходный запрос PAP на отправку данных" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Не удается отправить данные печати (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Не удается отправить данные печати!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Не удается отправить файл печати на принтер" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: Не удается отправить конечное нулевое значение на принтер" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Не удается подождать pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Не удается записать %d байт на «%s»: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Не удается записать %d байт на принтер!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Не удается записать контрольный файл" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Не удается записать данные печати" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Не удается записать данные печати: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Не удается записать растровые данные на драйвер!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Не удается записать данные во временный файл" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: Не удается записать несжатые данные документа: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Непредвиденный текст в строке %d из %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Неизвестное значение параметра шифрования «%s»!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Неизвестный порядок файлов «%s»\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Символ неизвестного формата «%c»\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Неизвестный формат каталога сообщений для «%s»!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Неизвестный параметр «%s» со значением «%s»!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Неизвестный режим печати «%s»\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Неизвестное значение параметра версии «%s»!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "" +"ERROR: Неподдерживаемое значение яркости %s, используется brightness=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Неподдерживаемое значение гаммы %s, используется gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "" +"ERROR: Неподдерживаемое значение number-up %d, используется number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Неподдерживаемое значение number-up-layout %s, используется number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Неподдерживаемое значение page-border %s, используется page-" +"border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: Обнаружено переполнение doc_printf (%d байт), отменяю!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: Фильтр pictwpstops закрыт по сигналу %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: Фильтр pictwpstops закрыт со статусом %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: Восстанавливаемо: не удается подключиться к принтеру; попытка будет " +"повторена через 30 секунд…\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: Сбой оператора select()" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: Не удается установить файл печати" + +msgid "Edit Configuration File" +msgstr "Редактировать файл конфигурации" + +msgid "Empty PPD file!" +msgstr "Пустой PPD-файл!" + +msgid "Ending Banner" +msgstr "Конечный баннер" + +msgid "Enter old password:" +msgstr "Введите старый пароль:" + +msgid "Enter password again:" +msgstr "Введите пароль снова:" + +msgid "Enter password:" +msgstr "Введите пароль:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Введите свое имя пользователя и пароль или данные учетной записи root, чтобы " +"получить доступ к этой странице. Если используется проверка подлинности " +"Kerberos, необходимо также иметь действительный билет Kerberos." + +msgid "Envelope Feed" +msgstr "Подача конвертов" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Политика ошибок" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "ERROR: Требуется имя хоста после параметра «-h»!\n" + +msgid "Every 10 Labels" +msgstr "Каждые 10 этикеток" + +msgid "Every 2 Labels" +msgstr "Каждые 2 этикетки" + +msgid "Every 3 Labels" +msgstr "Каждые 3 этикетки" + +msgid "Every 4 Labels" +msgstr "Каждые 4 этикетки" + +msgid "Every 5 Labels" +msgstr "Каждые 5 этикеток" + +msgid "Every 6 Labels" +msgstr "Каждые 6 этикеток" + +msgid "Every 7 Labels" +msgstr "Каждые 7 этикеток" + +msgid "Every 8 Labels" +msgstr "Каждые 8 этикеток" + +msgid "Every 9 Labels" +msgstr "Каждые 9 этикеток" + +msgid "Every Label" +msgstr "Каждая этикетка" + +msgid "Expectation Failed" +msgstr "Сбой ожидания" + +msgid "Export Printers to Samba" +msgstr "Экспортировать принтеры в Samba" + +msgid "FAIL\n" +msgstr "FAIL\n" + +msgid "File Folder" +msgstr "Каталог файла" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Каталог файла - 9 16/8 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"URI-адреса файлового устройства отключены! Чтобы включить их, используйте " +"директиву FileDevice в «%s/cupsd.conf»." + +msgid "Folio" +msgstr "Фолио" + +msgid "Forbidden" +msgstr "Запрещено" + +msgid "Fuser temperature high!" +msgstr "Высокая температура термофиксатора!" + +msgid "Fuser temperature low!" +msgstr "Низкая температура термофиксатора!" + +msgid "General" +msgstr "Основные" + +msgid "Generic" +msgstr "Общее" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Для Get-Response-PDU длина не установлена" + +msgid "Glossy Paper" +msgstr "Глянцевая бумага" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Получен атрибут printer-uri, но не job-id!" + +msgid "Grayscale" +msgstr "Оттенки серого" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Папка подвесного хранения" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Папка подвесного хранения - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk отключен в Системных настройках\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk отключен в Системных настройках.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Отмена задания печати…\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Подключен к принтеру…\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Подключение к принтеру…\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Контрольный файл успешно отправлен\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Файл данных успешно отправлен\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Форматирование страницы %d…\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Загрузка файла изображения…\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Поиск принтера...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Установка соединения\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Файл печати отправлен, ожидание окончания работы принтера…\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Принтер занят; попытка будет повторена через 10 секунд…\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Принтер занят; попытка будет повторена через 30 секунд…\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Принтер занят; попытка будет повторена через 5 секунд…\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "" +"INFO: Принтер не поддерживает IPP/%d.%d; попытка использовать IPP/1.0…\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Принтер занят; попытка будет повторена через 5 секунд…\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: В данный момент принтер не подключен к сети.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: В данный момент принтер не подключен к сети.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Принтер подключен к сети.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Принтер не подключен к сети.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Принтер не подключен; попытка будет повторена через 30 секунд…\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Печать страницы %d, %d%% завершена…\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Печать страницы %d…\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Готов к печати.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Отправка контрольного файла (%lu байт)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Отправка контрольного файла (%u байт)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Отправка данных\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Отправка файла данных (%ld байт)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Отправка файла данных (%lld байт)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Отправка данных печати…\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Отправлен файл печати, %ld байт…\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Отправлен файл печати, %lld байт…\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Спулинг задания LPR, %.0f%% выполнено…\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Не удается установить связь с принтером, постановка в очередь на " +"следующем принтере в классе…\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Используется стандартная зона AppleTalk «%s»\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Ожидание окончания выполнения задания…\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Ожидание доступа к принтеру...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "Конверт ISO B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (расширенный)" + +msgid "ISO B5 Envelope" +msgstr "Конверт ISO B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "Конверт ISO B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Недействительный контрольный символ" + +msgid "Illegal main keyword string" +msgstr "Недействительная основная строка ключевых слов" + +msgid "Illegal option keyword string" +msgstr "Недействительная строка ключевых слов параметра" + +msgid "Illegal translation string" +msgstr "Недействительный перевод" + +msgid "Illegal whitespace character" +msgstr "Недействительный символ пробела" + +msgid "Ink/toner almost empty." +msgstr "Чернила/тонер заканчиваются." + +msgid "Ink/toner empty!" +msgstr "Чернила/тонер закончились!" + +msgid "Ink/toner waste bin almost full." +msgstr "Корзина чернил/тонера почти полный." + +msgid "Ink/toner waste bin full!" +msgstr "Корзина чернил/тонера полная!" + +msgid "Installable Options" +msgstr "Параметры, разрешенные к установке" + +msgid "Installed" +msgstr "Установлено" + +msgid "IntelliBar Label Printer" +msgstr "Принтер для печати этикеток IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Открыт замок." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Внутренняя ошибка" + +msgid "Internet Postage 2-Part" +msgstr "Наклейки Internet Postage 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Наклейки Internet Postage 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Наклейки Internet Postage 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Наклейки Internet Postage 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Протокол интернет-печати" + +msgid "Invite Envelope" +msgstr "Конверт Invite Envelope" + +msgid "Italian Envelope" +msgstr "Конверт Italian Envelope" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Задание #%d не может быть перезапущено – нет файлов!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Задание #%d не существует!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Задание #%d уже прервано – не удается отменить." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Задание #%d уже отменено – не удается отменить." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Задание #%d уже завершено – не удается отменить." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Задание #%d завершено и не может быть изменено!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Задание #%d не завершено!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Задание #%d не задержано для идентификации!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Задание #%d не задержано!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Задание #%s не существует!" + +#, c-format +msgid "Job %d not found!" +msgstr "Задание #%d не найдено!" + +msgid "Job Completed" +msgstr "Задание завершено" + +msgid "Job Created" +msgstr "Задание создано" + +msgid "Job ID: " +msgstr "ID задания: " + +msgid "Job Options Changed" +msgstr "Параметры задания изменены" + +msgid "Job Stopped" +msgstr "Задание остановлено" + +msgid "Job UUID: " +msgstr "UUID задания: " + +msgid "Job is completed and cannot be changed." +msgstr "Задание завершено и не может быть изменено." + +msgid "Job operation failed:" +msgstr "Сбой операции задания:" + +msgid "Job state cannot be changed." +msgstr "Состояние задания не может быть изменено." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Подписки на задание не могут быть обновлены!" + +msgid "Jobs" +msgstr "Задания" + +msgid "Kaku2 Envelope" +msgstr "Конверт Kaku2" + +msgid "Kaku3 Envelope" +msgstr "Конверт Kaku3" + +msgid "LPD/LPR Host or Printer" +msgstr "Хост или принтер LPD/LPR" + +msgid "Label Printer" +msgstr "Принтер для печати этикеток" + +msgid "Label Top" +msgstr "Верхний край этикетки" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Язык «%s» не поддерживается!" + +msgid "Large Address" +msgstr "Полный адрес" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Полный адрес - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "Серия LaserJet, PCL 4/5" + +msgid "Light" +msgstr "Светлый" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Строка длиннее разрешенного предела (255 символов)" + +msgid "List Available Printers" +msgstr "Список доступных принтеров" + +msgid "Location: " +msgstr "Местоположение: " + +msgid "Long-Edge (Portrait)" +msgstr "По длинной стороне (книжная)" + +msgid "Make and Model: " +msgstr "Марка и модель: " + +msgid "Manual Feed" +msgstr "Ручная подача" + +msgid "Media Dimensions: " +msgstr "Размеры бумаги: " + +msgid "Media Limits: " +msgstr "Ограничения бумаги: " + +msgid "Media Name: " +msgstr "Название бумаги: " + +msgid "Media Size" +msgstr "Размер бумаги" + +msgid "Media Source" +msgstr "Источник бумаги" + +msgid "Media Tracking" +msgstr "Контроль подачи бумаги" + +msgid "Media Type" +msgstr "Тип бумаги" + +msgid "Media jam!" +msgstr "Затор бумаги!" + +msgid "Media tray almost empty." +msgstr "Лоток с бумагой почти пуст." + +msgid "Media tray empty!" +msgstr "Лоток с бумагой пуст!" + +msgid "Media tray missing!" +msgstr "Лоток с бумагой отсутствует!" + +msgid "Media tray needs to be filled." +msgstr "Необходимо вставить бумагу в лоток." + +msgid "Medium" +msgstr "Средний" + +msgid "Memory allocation error" +msgstr "Ошибка распределения памяти" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Отсутствует заголовок PPD-Adobe-4.x" + +msgid "Missing asterisk in column 1" +msgstr "Отсутствует звездочка в колонке 1" + +msgid "Missing document-number attribute!" +msgstr "Отсутствует атрибут document-number!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Отсутствуют двойные кавычки в строке %d!" + +msgid "Missing form variable!" +msgstr "Отсутствует переменная формы!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Отсутствует атрибут notify-subscription-ids!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Отсутствует атрибут requesting-user-name!" + +msgid "Missing required attributes!" +msgstr "Отсутствуют обязательные атрибуты!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Отсутствует значение в строке %d!" + +msgid "Missing value string" +msgstr "Отсутствует строка значения" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Изменить класс" + +msgid "Modify Printer" +msgstr "Изменить принтер" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Конверт Monarch" + +msgid "Move All Jobs" +msgstr "Переместить все задания" + +msgid "Move Job" +msgstr "Переместить задание" + +msgid "Moved Permanently" +msgstr "Перемещено окончательно" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Файл печати принят – ID задания %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Файл печати принят – ID задания неизвестен.\n" + +msgid "NULL PPD file pointer" +msgstr "Указатель PPD-файла установлен на NULL" + +msgid "Name OID uses indefinite length" +msgstr "Для имени OID длина не установлена" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Никогда" + +msgid "New Stylus Color Series" +msgstr "Серия Stylus Color нового поколения" + +msgid "New Stylus Photo Series" +msgstr "Серия Stylus Photo нового поколения" + +msgid "No" +msgstr "Нет" + +msgid "No Content" +msgstr "Нет контента" + +msgid "No PPD name!" +msgstr "Нет имени PPD!" + +msgid "No VarBind SEQUENCE" +msgstr "Нет последовательности VarBind" + +msgid "No Windows printer drivers are installed!" +msgstr "Нет установленных драйверов принтера Windows!" + +msgid "No active connection" +msgstr "Нет рабочего подключения" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Нет активных заданий на %s!" + +msgid "No attributes in request!" +msgstr "Нет атрибутов в запросе!" + +msgid "No authentication information provided!" +msgstr "Нет информации для проверки подлинности!" + +msgid "No community name" +msgstr "Нет имени сообщества" + +msgid "No default printer" +msgstr "Нет принтера по умолчанию" + +msgid "No destinations added." +msgstr "Нет добавленных назначений." + +msgid "No error-index" +msgstr "Нет значения error-index" + +msgid "No error-status" +msgstr "Нет значения error-status" + +msgid "No file!?!" +msgstr "Нет файла!?!" + +msgid "No modification time!" +msgstr "Не указано время изменения!" + +msgid "No name OID" +msgstr "Нет имени OID" + +msgid "No printer name!" +msgstr "Нет имени принтера!" + +msgid "No printer-uri found for class!" +msgstr "Не указан адрес printer-uri для класса!" + +msgid "No printer-uri found!" +msgstr "Не указан адрес printer-uri!" + +msgid "No printer-uri in request!" +msgstr "Нет адреса printer-uri в запросе!" + +msgid "No request-id" +msgstr "Нет идентификатора request-id" + +msgid "No subscription attributes in request!" +msgstr "Нет атрибутов подписки в запросе!" + +msgid "No subscriptions found." +msgstr "Подписки не найдены." + +msgid "No variable-bindings SEQUENCE" +msgstr "Нет последовательности variable-bindings" + +msgid "No version number" +msgstr "Нет номера версии" + +msgid "Non-continuous (Mark sensing)" +msgstr "С прерыванием (опознавание маркеров)" + +msgid "Non-continuous (Web sensing)" +msgstr "С прерыванием (опознавание сети)" + +msgid "Normal" +msgstr "Нормальный" + +msgid "Not Found" +msgstr "Не найдено" + +msgid "Not Implemented" +msgstr "Не реализовано" + +msgid "Not Installed" +msgstr "Не установлено" + +msgid "Not Modified" +msgstr "Не изменено" + +msgid "Not Supported" +msgstr "Не поддерживается" + +msgid "Not allowed to print." +msgstr "Не разрешено печатать." + +msgid "Note" +msgstr "Примечание" + +msgid "OK" +msgstr "ОК" + +msgid "OPC almost at end-of-life." +msgstr "OPC почти в end-of-life." + +msgid "OPC at end-of-life!" +msgstr "OPC в end-of-life!" + +msgid "Off (1-Sided)" +msgstr "Выкл. (односторонняя печать)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Интерактивная справка" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "Не удалось открыть %s: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup без предыдущего CloseGroup" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI без предыдущего CloseUI/JCLCloseUI" + +msgid "Operation Policy" +msgstr "Политика операций" + +msgid "Options Installed" +msgstr "Параметры установлены" + +msgid "Options: " +msgstr "Параметры: " + +msgid "Out of toner!" +msgstr "Недостаточно тонера!" + +msgid "Output Mode" +msgstr "Режим вывода" + +msgid "Output bin almost full." +msgstr "Выходной лоток почти заполнен." + +msgid "Output bin full!" +msgstr "Выходной лоток заполнен!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Вывод для принтера %s отправлен на %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Вывод для принтера %s отправлен на удаленный принтер %s на %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Вывод для принтера %s/%s отправлен на %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "Вывод для принтера %s/%s отправлен на удаленный принтер %s на %s\n" + +msgid "Output tray missing!" +msgstr "Выходной лоток отсутствует!" + +msgid "PASS\n" +msgstr "PASS\n" + +msgid "PCL Laser Printer" +msgstr "Лазерный принтер PCL" + +msgid "PRC1 Envelope" +msgstr "Конверт PRC1" + +msgid "PRC10 Envelope" +msgstr "Конверт PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Конверт PRC2" + +msgid "PRC3 Envelope" +msgstr "Конверт PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (расширенный)" + +msgid "PRC4 Envelope" +msgstr "Конверт PRC4" + +msgid "PRC5 Envelope" +msgstr "Конверт PRC5" + +msgid "PRC6 Envelope" +msgstr "Конверт PRC6" + +msgid "PRC7 Envelope" +msgstr "Конверт PRC7" + +msgid "PRC8 Envelope" +msgstr "Конверт PRC8" + +msgid "PRC9 Envelope" +msgstr "Конверт PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "В пакете нет Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Нет индикатора SEQUENCE в начале пакета" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Пароль для %s на %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Для доступа к %s через SAMBA требуется пароль для %s: " + +msgid "Pause Class" +msgstr "Приостановить класс" + +msgid "Pause Printer" +msgstr "Приостановить принтер" + +msgid "Peel-Off" +msgstr "Съемный слой" + +msgid "Personal Envelope" +msgstr "Индивидуальный конверт" + +msgid "Photo" +msgstr "Фото" + +msgid "Photo Labels" +msgstr "Фотоэтикетки" + +msgid "Plain Paper" +msgstr "Обычная бумага" + +msgid "Policies" +msgstr "Политики" + +msgid "Port Monitor" +msgstr "Мониторинг порта" + +msgid "PostScript Printer" +msgstr "Принтер PostScript" + +msgid "Postcard" +msgstr "Открытка" + +msgid "Print Density" +msgstr "Плотность печати" + +msgid "Print Job:" +msgstr "Задание печати:" + +msgid "Print Mode" +msgstr "Режим печати" + +msgid "Print Rate" +msgstr "Скорость печати" + +msgid "Print Self-Test Page" +msgstr "Напечатать пробную страницу" + +msgid "Print Speed" +msgstr "Скорость печати" + +msgid "Print Test Page" +msgstr "Напечатать пробную страницу" + +msgid "Print and Cut" +msgstr "Напечатать и обрезать" + +msgid "Print and Tear" +msgstr "Напечатать и оборвать" + +msgid "Printed For: " +msgstr "Напечатано для: " + +msgid "Printed From: " +msgstr "Напечатано из: " + +msgid "Printed On: " +msgstr "Дата печати: " + +msgid "Printer Added" +msgstr "Принтер добавлен" + +msgid "Printer Default" +msgstr "Принтер выбран по умолчанию" + +msgid "Printer Deleted" +msgstr "Принтер удален" + +msgid "Printer Modified" +msgstr "Принтер изменен" + +msgid "Printer Name: " +msgstr "Имя принтера: " + +msgid "Printer Paused" +msgstr "Принтер приостановлен" + +msgid "Printer Settings" +msgstr "Параметры принтера" + +msgid "Printer offline." +msgstr "Принтер в режиме не подключен к сети." + +msgid "Printer:" +msgstr "Принтер:" + +msgid "Printers" +msgstr "Принтеры" + +msgid "Purge Jobs" +msgstr "Удалить задания" + +msgid "Quarto" +msgstr "Кватро" + +msgid "Quota limit reached." +msgstr "Предел квоты достигнут." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Ранг Владелец Задание Файл(ы) Общий размер\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Ранг Владелец Задание печати Файл(ы) Общий " +"размер\n" + +msgid "Reject Jobs" +msgstr "Отклонить задания" + +msgid "Reprint After Error" +msgstr "Повторить печать после ошибки" + +msgid "Request Entity Too Large" +msgstr "Слишком большое содержимое запроса" + +msgid "Resolution" +msgstr "Разрешение" + +msgid "Resume Class" +msgstr "Возобновить работу класса" + +msgid "Resume Printer" +msgstr "Возобновить работу принтера" + +msgid "Return Address" +msgstr "Обратный адрес" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Обратный адрес - 3/4 x 2\"" + +msgid "Rewind" +msgstr "Вернуться в начало" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Запущенная команда: %s %s -N -A %s -c «%s»\n" + +msgid "SCSI Printer" +msgstr "Принтер SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "Для SEQUENCE длина не установлена" + +msgid "See Other" +msgstr "Посмотреть другие" + +#, c-format +msgid "Serial Port #%d" +msgstr "Последовательный порт #%d" + +msgid "Server Restarted" +msgstr "Сервер перезагружен" + +msgid "Server Security Auditing" +msgstr "Проверка безопасности сервера" + +msgid "Server Started" +msgstr "Сервер загружен" + +msgid "Server Stopped" +msgstr "Сервер остановлен" + +msgid "Service Unavailable" +msgstr "Служба недоступна" + +msgid "Set Allowed Users" +msgstr "Указать допущенных пользователей" + +msgid "Set As Server Default" +msgstr "Использовать данный сервер по умолчанию" + +msgid "Set Class Options" +msgstr "Настроить параметры класса" + +msgid "Set Printer Options" +msgstr "Настроить параметры принтера" + +msgid "Set Publishing" +msgstr "Настроить публикацию" + +msgid "Shipping Address" +msgstr "Адрес доставки" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Адрес доставки - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "По короткой стороне (альбомная)" + +msgid "Special Paper" +msgstr "Особая бумага" + +msgid "Standard" +msgstr "Стандартный" + +msgid "Starting Banner" +msgstr "Запуск баннера" + +msgid "Statement" +msgstr "Оператор" + +msgid "Stylus Color Series" +msgstr "Серия Stylus Color" + +msgid "Stylus Photo Series" +msgstr "Серия Stylus Photo" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Протоколы переключения" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (расширенный)" + +msgid "Tear" +msgstr "Оборвать" + +msgid "Tear-Off" +msgstr "Место отрыва" + +msgid "Tear-Off Adjust Position" +msgstr "Откорректировать положение места отрыва" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "Не удается найти PPD-файл «%s»." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "Не удалось открыть PPD-файл «%s»: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Имя класса может содержать максимально 127 печатных символов и не может " +"содержать пробелы, дроби (/) или знак «решетки» (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Атрибут notify-lease-duration не может использоваться с подписками на " +"задание." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Значение notify-user-data слишком длинное (%d > 63 октетов)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Имя принтера может содержать максимально 127 печатных символов и не может " +"содержать пробелы, дроби (/) или знак «решетки» (#)." + +msgid "The printer or class is not shared!" +msgstr "Нет общего доступа к принтеру или классу!" + +msgid "The printer or class was not found." +msgstr "Принтер или класс не найден." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "printer-uri «%s» содержит недопустимые символы." + +msgid "The printer-uri attribute is required!" +msgstr "Требуется атрибут printer-uri!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "printer-uri должен иметь форму «ipp://HOSTNAME/classes/CLASSNAME»." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "printer-uri должен иметь форму «ipp://HOSTNAME/printers/PRINTERNAME»." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +"Имя подписки не может содержать пробелы, дроби (/), вопросительные знаки (?) " +"или знак «решетки» (#)." + +msgid "There are too many subscriptions." +msgstr "Слишком много подписок." + +msgid "Thermal Transfer Media" +msgstr "Носитель для печати методом термопереноса" + +msgid "Title: " +msgstr "Заголовок: " + +msgid "Toner low." +msgstr "Тонер заканчивается." + +msgid "Too many active jobs." +msgstr "Слишком много активных заданий." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "Слишком много значений job-sheets (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "Слишком много значений printer-state-reasons (%d > %d)!" + +msgid "Transparency" +msgstr "Прозрачность" + +msgid "Tray" +msgstr "Лоток" + +msgid "Tray 1" +msgstr "Лоток 1" + +msgid "Tray 2" +msgstr "Лоток 2" + +msgid "Tray 3" +msgstr "Лоток 3" + +msgid "Tray 4" +msgstr "Лоток 4" + +msgid "URI Too Long" +msgstr "Слишком длинный адрес URI" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Legal" + +msgid "US Legal (Oversize)" +msgstr "US Legal (расширенный)" + +msgid "US Letter" +msgstr "US Letter" + +msgid "US Letter (Oversize)" +msgstr "US Letter (расширенный)" + +msgid "US Letter (Small)" +msgstr "US Letter (уменьшенный)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "Последовательный порт USB #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Не удается получить доступ к файлу «cupsd.conf»:" + +msgid "Unable to add RSS subscription:" +msgstr "Не удается добавить подписку RSS:" + +msgid "Unable to add class:" +msgstr "Не удается добавить класс:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Не удается добавить задание для назначения «%s»!" + +msgid "Unable to add printer:" +msgstr "Не удается добавить принтер:" + +msgid "Unable to allocate memory for file types!" +msgstr "Не удается выделить память для типов файлов!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Не удается отменить подписку RSS:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Не удается изменить атрибут printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Не удается изменить принтер:" + +msgid "Unable to change server settings:" +msgstr "Не удается изменить настройки сервера:" + +msgid "Unable to connect to host." +msgstr "Не удается подключиться к хосту." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Не удается копировать 64-битовые файлы драйвера принтера CUPS (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "" +"Не удается копировать 64-битовые файлы драйвера принтера для Windows (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Не удается копировать файлы драйвера принтера CUPS (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Не удается копировать PPD-файл – %s!" + +msgid "Unable to copy PPD file!" +msgstr "Не удается копировать PPD-файл!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "Не удается копировать файлы драйвера принтера Windows 2000 (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Не удается копировать файлы драйвера принтера Windows 9x (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Не удается копировать скрипт интерфейса – %s!" + +msgid "Unable to create printer-uri!" +msgstr "Не удается создать printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Не удается создать временный файл:" + +msgid "Unable to delete class:" +msgstr "Не удается удалить класс:" + +msgid "Unable to delete printer:" +msgstr "Не удается удалить принтер:" + +msgid "Unable to do maintenance command:" +msgstr "Не удается выполнить команду обслуживания:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Невозможно редактировать файлы «cupsd.conf» больше 1 МБ!" + +msgid "Unable to find destination for job!" +msgstr "Не удается найти назначение для задания!" + +msgid "Unable to find printer!\n" +msgstr "Не удается найти принтер!\n" + +msgid "Unable to get class list:" +msgstr "Не удается получить список класса:" + +msgid "Unable to get class status:" +msgstr "Не удается получить статус класса:" + +msgid "Unable to get list of printer drivers:" +msgstr "Не удается получить список драйверов принтера:" + +msgid "Unable to get printer attributes:" +msgstr "Не удается получить атрибуты принтера:" + +msgid "Unable to get printer list:" +msgstr "Не удается получить список принтеров:" + +msgid "Unable to get printer status:" +msgstr "Не удается получить статус принтера:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "Не удается установить файлы драйвера принтера Windows 2000 (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Не удается установить файлы драйвера принтера Windows 9x (%d)!" + +msgid "Unable to modify class:" +msgstr "Не удается изменить класс:" + +msgid "Unable to modify printer:" +msgstr "Не удается изменить принтер:" + +msgid "Unable to move job" +msgstr "Не удается переместить задание" + +msgid "Unable to move jobs" +msgstr "Не удается переместить задания" + +msgid "Unable to open PPD file" +msgstr "Не удается открыть PPD-файл" + +msgid "Unable to open PPD file:" +msgstr "Не удается открыть PPD-файл:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Не удается открыть файл «cupsd.conf»:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Не удается открыть документ %d в задании %d!" + +msgid "Unable to print test page:" +msgstr "Не удается напечатать пробную страницу:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Не удается запустить «%s»: %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Не удается отправить команду драйверу принтера!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Не удается настроить драйвер принтера Windows (%d)!" + +msgid "Unable to set options:" +msgstr "Не удается настроить параметры:" + +msgid "Unable to set server default:" +msgstr "Не удается назначить сервер используемым по умолчанию:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Не удается загрузить файл «cupsd.conf»:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Не удается использовать устаревший драйвер класса USB!\n" + +msgid "Unauthorized" +msgstr "Не санкционировано" + +msgid "Units" +msgstr "Единицы" + +msgid "Unknown" +msgstr "Неизвестный" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Неизвестная политика printer-error-policy «%s»." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Неизвестная политика printer-op-policy «%s»." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Неподдерживаемый набор символов «%s»!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Неподдерживаемое сжатие «%s»!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Неподдерживаемый атрибут сжатия %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Неподдерживаемый формат «%s»!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "Неподдерживаемый формат «%s»!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Неподдерживаемый формат «%s/%s»!" + +msgid "Unsupported value type" +msgstr "Неподдерживаемый тип значения" + +msgid "Upgrade Required" +msgstr "Требуется обновление" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Синтаксис:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Синтаксис: %s job user title copies options [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Синтаксис: %s job-id user title copies options [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Синтаксис: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Синтаксис: cupsaddsmb [options] принтер1 ... принтерN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Параметры:\n" +" -E Подключение к серверу шифруется\n" +" -H samba-server Используется названный сервер SAMBA\n" +" -U samba-user Выполняется проверка подлинности с использованием " +"указанного пользователя SAMBA\n" +" -a Экспортируются все принтеры\n" +" -h cups-server Используется названный сервер CUPS\n" +" -v Подробное отображение (показать команды)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Синтаксис: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Параметры:\n" +"\n" +" -E Включается шифрование\n" +" -U username Указывается имя пользователя\n" +" -h server[:port] Указывается адрес сервера\n" +"\n" +" --[no-]debug-logging Включается/отключается ведение журнала отладки\n" +" --[no-]remote-admin Включается/отключается удаленное " +"администрирование\n" +" --[no-]remote-any Разрешается/запрещается доступ из Интернета\n" +" --[no-]remote-printers Отображаются/скрываются удаленные принтеры\n" +" --[no-]share-printers Включается/отключается совместное использование " +"принтеров\n" +" --[no-]user-cancel-any Пользователям разрешается/запрещается отменять " +"задания\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Синтаксис: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Загружается альтернативный файл конфигурации\n" +"-f Задание имеет высокий приоритет\n" +"-F Задание имеет высокий приоритет и выделяется\n" +"-h Отображается данное сообщение\n" +"-l cupsd запускается из launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Синтаксис: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Параметры:\n" +"\n" +" -h Отображается справка по использованию программы\n" +"\n" +" Примечание: данная программа проверяет только комментарии DSC, а не сам " +"PostScript.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Синтаксис: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Синтаксис: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"{>Синтаксис: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Синтаксис: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] " +"[+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Синтаксис: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Параметры:\n" +" -D name=value Указанной переменной присваивается значение.\n" +" -I include-dir Добавляется каталог в путь поиска.\n" +" -c catalog.po Загружается указанный каталог сообщений.\n" +" -d output-dir Указывается каталог для выходных данных.\n" +" -l lang[,lang,...] Указывается язык (регион) для выходных данных.\n" +" -m В качестве имени файла используется значение " +"ModelName.\n" +" -t Вместо создания PPD-файлов выполняется их проверка.\n" +" -v Режим подробного отображения (чем больше букв v, тем " +"выше уровень детализации).\n" +" -z Файлы PPD сжимаются с использованием GNU zip.\n" +" --cr Строки заканчиваются на CR (Mac OS 9).\n" +" --crlf Строки заканчиваются на CR + LF (Windows).\n" +" --lf Строки заканчиваются на LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Синтаксис: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Указанной переменной присваивается значение.\n" +"Параметры:\n" +" -I include-dir Добавляется каталог в путь поиска.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Синтаксис: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Параметры:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Синтаксис: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Параметры:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Синтаксис: ppdpo [options] -o filename.po filename.drv [ ... filenameN." +"drv ]\n" +"Параметры:\n" +" -D name=value Указанной переменной присваивается значение.\n" +" -I include-dir Добавляется каталог в путь поиска.\n" +" -v Подробный режим (чем больше букв v, тем выше уровень " +"детализации).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Синтаксис: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Для значения длина не установлена" + +msgid "VarBind uses indefinite length" +msgstr "Для VarBind длина не установлена" + +msgid "Version uses indefinite length" +msgstr "Для Version длина не установлена" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Будут добавлены только первые найденные принтеры (%d)" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Параметр waiteof «%s» должен иметь булево значение\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Не удалось прочитать запрос бокового канала!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: Параметр «%s» не может быть включен через IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Принтер не отвечает\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Принтер преждевременно передал индикатор EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Удаленный хост не ответил байтом command-статуса после %d секунд!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Удаленный хост не ответил байтом control-статуса после %d секунд!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Удаленный хост не ответил байтом data-статуса после %d секунд!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: Время команды SCSI истекло (%d). Повтор попытки…\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Этот документ не соответствует Adobe Document Structuring " +"Conventions и может быть напечатан неправильно!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Не удается открыть «%s:%s»: %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Не удается отправить запрос статуса PAP" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Непредвиденный PAP-пакет типа %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Неизвестный PAP-пакет типа %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Неизвестный выбор «%s» для параметра «%s»!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Неизвестный параметр «%s»!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Неподдерживаемая скорость передачи данных в бодах %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: Параметр статуса «%s» должен иметь числовое значение\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: Восстанавливаемо. Хост сети «%s» занят. Попытка будет повторена " +"через %d сек…\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Внимание! Нет установленных драйверов принтера Windows 2000!" + +msgid "Yes" +msgstr "Да" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Вы должны получить доступ к этой странице с помощью URL https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "Конверт You4" + +msgid "ZPL Label Printer" +msgstr "Принтер для печати этикеток ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "отменено" + +msgid "canceled" +msgstr "отменено" + +msgid "completed" +msgstr "завершено" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert: Используйте параметр -f для указания конвертируемого файла.\n" + +msgid "cups-deviced failed to execute." +msgstr "Не удалось выполнить cups-deviced." + +msgid "cups-driverd failed to execute." +msgstr "Не удалось выполнить cups-driverd." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Нет PPD-файла для принтера «%s» – %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Не удается подключиться к серверу: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Неизвестный параметр «%s»!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Неизвестный параметр «-%c»!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Ожидаемое имя файла конфигурации после параметра «-c»!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Не удается определить текущий каталог!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Неизвестный аргумент «%s» – отмена!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Неизвестный параметр «%c» – отмена!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "" +"cupsd: Поддержка launchd(8) не скомпилирована, работа в нормальном режиме.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Недопустимый номер документа %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: Недопустимый ID задания %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Только одно имя файла может быть указано!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Не удается получить файл задания - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd: Параметр «-q» несовместим с параметром «-v».\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd: Параметр «-v» несовместим с параметром «-q».\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "устройство для %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "устройство для %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "Для error-index длина не установлена" + +msgid "error-status uses indefinite length" +msgstr "Для error-status длина не установлена" + +msgid "held" +msgstr "задержано" + +msgid "help\t\tget help on commands\n" +msgstr "справка\t\tполучить справку о командах\n" + +msgid "idle" +msgstr "свободен" + +msgid "job-printer-uri attribute missing!" +msgstr "Атрибут job-printer-uri отсутствует!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Имя класса может содержать только печатные символы!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: После параметра «-P» должен быть указан PPD!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: После параметра «-u» должен быть указан allow/deny:userlist!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: После параметра «-r» должен быть указан класс!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: После параметра «-c» должно быть указано имя класса!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: После параметра «-D» должно идти описание!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: После параметра «-v» должен быть указан URI устройства!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: После параметра «-I» должны быть указаны типы файлов!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: После параметра «-h» должно быть указано имя хоста!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: После параметра «-i» должен быть указан интерфейс!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: После параметра «-L» должно быть указано местоположение!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: После параметра «-m» должна быть указана модель!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "" +"lpadmin: После параметра «-o» должно быть указано значение вида name=value!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: После параметра «-p» должен быть указан принтер!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: После параметра «-d» должно быть указано имя принтера!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: После параметра «-x» должен быть указан принтер или класс!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Имена участников не обнаружены!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Принтер %s уже является членом класса %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Принтер %s не является членом класса %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Имя принтера может содержать только печатные символы!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается добавить принтер к классу:\n" +" Необходимо сначала указать имя принтера!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Не удается подключиться к серверу: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Не удается открыть PPD-файл «%s» – %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Не удается открыть файл «%s»: %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается удалить принтер из класса:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить PPD-файл:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить URI устройства:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить скрипт интерфейса или PPD-файл:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить скрипт интерфейса:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить описание принтера:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить размещение принтера:\n" +" Необходимо сначала указать имя принтера!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Не удается настроить параметры принтера:\n" +" Необходимо сначала указать имя принтера!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: Неизвестный параметр allow/deny «%s»!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Неизвестный аргумент «%s»!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Неизвестный параметр «%c»!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Внимание – список типов контента пропущен!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: После --device-id должна идти строка ID устройства 1284!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: После –language должен быть указан язык!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: После --make-and-model должна быть указана марка и модель!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: После –product должна идти строка продукта!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: После --exclude-schemes должен идти список схем!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: После --ixclude-schemes должен идти список схем!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: После –timeout должно быть указано время ожидания!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Неизвестный аргумент «%s»!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Неизвестный параметр «%c»!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Неизвестный параметр «%s»!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Не удается подключиться к серверу: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Неизвестный аргумент «%s»!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Неизвестный параметр «%c»!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Нет принтеров!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Не удается добавить принтер или представитель класса: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Не удается получить PPD-файл для %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Не удается открыть PPD-файл для %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Неизвестный принтер или класс!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "" +"lppasswd: Только пользователь root может добавлять или удалять пароли!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Файл пароля занят!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Файл пароля не обновлен!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Пароль не подходит!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Пароль отклонен.\n" +"Пароль должен состоять как минимум из 6 символов, не может содержать\n" +"Ваше имя пользователя и должен содержать по крайней мере одну букву и " +"цифру.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Пароль не подходит!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Не удается копировать строку пароля: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Не удается открыть файл пароля: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Не удается записать файл пароля: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: Не удалось создать рез. копию старого файла пароля: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: Не удалось переименовать файл пароля: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: Пользователь «%s» и группа «%s» не существуют.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "" +"lpstat: Ошибка – %s переменная окружения указывает несуществующее назначение " +"«%s»!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "члены класса %s:\n" + +msgid "no entries\n" +msgstr "нет записей\n" + +msgid "no system default destination\n" +msgstr "нет назначения системы по умолчанию\n" + +msgid "notify-events not specified!" +msgstr "notify-events не указаны!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "URI-адрес notify-recipient-uri «%s» уже используется!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "URI-адрес notify-recipient-uri «%s» использует неизвестную схему!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d неверный!" + +msgid "pending" +msgstr "задержка" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Добавляю каталог «%s»...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Добавляю/обновляю текст интерфейса из %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Недопустимое булево значение (%s) в строке %d из %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Недопустимое имя разрешения «%s» в строке %d из %s.\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Недопустимое ключевое слово статуса %s в строке %d из %s.\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Недопустимая замена переменной ($%c) в строке %d из %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "" +"ppdc: В строке %d из %s обнаружено значение, не привязанное к параметру!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Дубликат #po для региона %s в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть определение фильтра!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть имя программы!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: В строке %d из %s должно быть булево значение.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "" +"ppdc: После Font в строке %d из %s должен быть указан набор символов!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: В строке %d из %s должен быть код выбора.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: В строке %d из %s должно быть имя/текст выбора.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: После ColorModel в строке %d из %s должна быть указана цветовая " +"схема!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Для ColorModel в строке %d из %s должно быть указано пространство " +"цветов!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Для ColorModel в строке %d из %s должно быть указано сжатие!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "" +"ppdc: Для UIConstraints в строке %d из %s должна быть указана строка " +"ограничений!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: После DriverType в строке %d из %s должно быть указано ключевое слово " +"типа драйвера!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "" +"ppdc: После Duplex в строке %d из %s должен быть указан тип дуплекса!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: После Font в строке %d из %s должна быть указана кодировка!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: После #po %s в строке %d из %s должно быть указано имя файла!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть указано имя группы/текст!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть указано имя файла!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть целое число!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: После #po в строке %d из %s должен быть указан регион!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: После %s в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: После FileName в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: После Font в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: После Manufacturer в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: После MediaSize в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: После ModelName в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: После PCFileName в строке %d из %s должно быть имя!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: После %s в строке %d из %s должно быть имя/текст!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: После Installable в строке %d из %s должно быть имя/текст!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: После Resolution в строке %d из %s должно быть имя/текст!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "ppdc: После ColorModel в строке %d из %s должно быть имя/текст!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть указано имя параметра/текст!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должен быть раздел параметров!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должен быть указан тип параметра!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "" +"ppdc: После Resolution в строке %d из %s должно быть поле переопределения!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должно быть действительное число!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: После ColorProfile в строке %d из %s должно быть указано разрешение/" +"тип носителя!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: После SimpleColorProfile в строке %d из %s должно быть указано " +"разрешение/тип носителя!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: После %s в строке %d из %s должен быть селектор!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: После Font в строке %d из %s должен быть указан статус!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: После Copyright в строке %d из %s должна быть строка!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: После Version в строке %d из %s должна быть строка!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: В строке %d из %s должны быть два имени параметра!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: После %s в строке %d из %s должно быть значение!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: После Font в строке %d из %s должна быть указана версия!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Неверное имя файла #include/#po «%s»!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Затраты на фильтр в строке %d из %s указаны неверно!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Недопустимый пустой MIME-тип для фильтра в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "" +"ppdc: Недопустимое пустое имя программы для фильтра в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Неверный раздел параметров «%s» в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Неверный тип параметра «%s» в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Загружаю файл с информацией о драйвере «%s»...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Загружаю сообщения для региона «%s»...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Загружаю сообщения из «%s»...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: Отсутствует #endif в конце «%s»!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: Отсутствует #if в строке %d из %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Не указан каталог сообщений для региона %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: Для параметра %s определен другой тип в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "" +"ppdc: Для ограничения параметра должно быть указано *name в строке %d из %" +"s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: Слишком много вложенных операторов #if в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "lpadmin: Не удается создать PPD-файл «%s» – %s\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Не удается создать каталог для выходных данных %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Не удается создать конвейеры для выходных данных: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Не удается выполнить cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Не удается найти файл #po %s в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: Не удается найти файл «%s» в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Не удается найти локализацию для «%s» - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Не удается загрузить файл локализации «%s» - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Не определена переменная (%s) в строке %d из %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Неизвестный тип драйвера %s в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Неизвестный тип дуплекса «%s» в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Неизвестный размер носителя «%s» в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Неизвестный маркер «%s» в строке %d из %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "" +"ppdc: Неизвестные конечные символы в вещественном числе «%s» в строке %d из %" +"s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Не завершена строка, начинающаяся с %c в строке %d из %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Записываю %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Записываю PPD-файлы в каталог «%s»...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Неверное значение LanguageVersion «%s» в %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Пропускаю PPD-файл %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Невозможно создать резервную копию %s на %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "принтер %s отключен с момента %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "принтер %s свободен. Включен с момента %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "принтер %s сейчас печатает %s-%d. Включен с момента %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "принтер %s/%s отключен с момента %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "принтер %s/%s свободен. Включен с момента %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "принтер %s/%s сейчас печатает %s-%d. Включен с момента %s\n" + +msgid "processing" +msgstr "обработка" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "id запроса %s-%d (%d файл.)\n" + +msgid "request-id uses indefinite length" +msgstr "Для request-id длина не определена" + +msgid "scheduler is not running\n" +msgstr "планировщик не запущен\n" + +msgid "scheduler is running\n" +msgstr "планировщик запущен\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "не удалось установить %s: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "статус\t\tпоказать статус демона и очереди\n" + +msgid "stopped" +msgstr "остановлен" + +#, c-format +msgid "system default destination: %s\n" +msgstr "назначение системы по умолчанию: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "назначение системы по умолчанию: %s/%s\n" + +msgid "unknown" +msgstr "неизвестный" + +msgid "untitled" +msgstr "новый" + +msgid "variable-bindings uses indefinite length" +msgstr "Для variable-bindings длина не установлена" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN Файл APDialogExtension отсутствует «%s»\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN Файл APPrinterIconPath отсутствует «%s»\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Не удается открыть %s – %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Не удается открыть %s – %s в строке %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600dpi, оттенки серого" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Отсутствует идентификатор URI устройства в командной строке и " +#~ "переменная окружения DEVICE_URI!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Не удается создать временный файл – %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Не удается создать временный файл: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Не удается открыть временный файл" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: Сбой фильтра pdftops при сигнале %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: Фильтр pictwpstops закрыт со статусом %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Неизвестная ошибка принтера (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Синтаксис: convert [ options ]\n" +#~ "\n" +#~ "Параметры:\n" +#~ "\n" +#~ " -f filename Указывается конвертируемый файл (в противном " +#~ "случае stdin)\n" +#~ " -o filename Указывается создаваемый файл (в противном случае " +#~ "stdout)\n" +#~ " -i mime/type Указывается MIME-тип данных на входе (в противном " +#~ "случае auto-typed)\n" +#~ " -j mime/type Указывается MIME-тип данных на выходе (в противном " +#~ "случае application/pdf)\n" +#~ " -P filename.ppd Указывается PPD-файл\n" +#~ " -a 'name=value ...' Указываются параметры\n" +#~ " -U username Указывается имя пользователя для задания\n" +#~ " -J title Указывается заголовок\n" +#~ " -c copies Указывается количество копий\n" +#~ " -u PPD-файл удаляется после выполнения команды\n" +#~ " -D Файл, поступивший на вход, удаляется после " +#~ "выполнения команды\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Синтаксис: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Параметры:\n" +#~ "\n" +#~ " -c cupsd.conf Используется файл cupsd.conf\n" +#~ " -j job-id[,N] Из указанного задания выбирается файл N (по умолчанию " +#~ "файл 1)\n" +#~ " -n copies Задается количество копий\n" +#~ " -o name=value Задаются параметры\n" +#~ " -p filename.ppd Задается PPD-файл\n" +#~ " -t title Задается заголовок\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Синтаксис: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[." +#~ "gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Параметры:\n" +#~ "\n" +#~ " -R root-directory Задается альтернативный корневой каталог\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Вместо ошибок выдаются предупреждения\n" +#~ " -q Команда выполняется в «тихом» режиме\n" +#~ " -r Используется открытый режим\n" +#~ " -v Режим более подробного отображения\n" +#~ " -vv Режим максимально подробного отображения\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Не удается создать временный файл: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Не удается создать временный файл – %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Не удается создать временный файл: %s\n" diff --git a/locale/cups_sv.po b/locale/cups_sv.po new file mode 100644 index 0000000000..71fa1209df --- /dev/null +++ b/locale/cups_sv.po @@ -0,0 +1,5655 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(alla)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(ingen)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d poster\n" + +msgid "\tAfter fault: continue\n" +msgstr "\tEfter fel: fortsätt\n" + +msgid "\tAlerts:" +msgstr "\tVarningar:" + +msgid "\tBanner required\n" +msgstr "\tBanner krävs\n" + +msgid "\tCharset sets:\n" +msgstr "\tTeckenkodningar:\n" + +msgid "\tConnection: direct\n" +msgstr "\tAnslutning: direkt\n" + +msgid "\tConnection: remote\n" +msgstr "\tAnslutning: fjärr\n" + +msgid "\tDefault page size:\n" +msgstr "\tFörvalt pappersformat:\n" + +msgid "\tDefault pitch:\n" +msgstr "\tStandardavstånd mellan bildpunkter:\n" + +msgid "\tDefault port settings:\n" +msgstr "\tStandardportinställningar:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\tBeskrivning: %s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\tAktiv skrivarmall:\n" +"\tInnehållstyper: alla\n" +"\tSkrivartyper: okänt\n" + +msgid "\tForms allowed:\n" +msgstr "\tTillåtna format:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\tGränssnitt: %s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\tGränssnitt: %s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\tGränssnitt: %s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\tPlats: %s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\tVid fel: ingen varning\n" + +msgid "\tUsers allowed:\n" +msgstr "\tTillåtna användare:\n" + +msgid "\tUsers denied:\n" +msgstr "\tNekade användare:\n" + +msgid "\tdaemon present\n" +msgstr "\tdemon närvarande\n" + +msgid "\tno entries\n" +msgstr "\tinga poster\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\tskrivare finns på enheten ”%s” hastighet -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\tutskrifter är avaktiverade\n" + +msgid "\tprinting is enabled\n" +msgstr "\tutskrifter är aktiverade\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\tköad för %s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\tköläggning är avaktiverad\n" + +msgid "\tqueuing is enabled\n" +msgstr "\tköläggning är aktiverad\n" + +msgid "\treason unknown\n" +msgstr "\tokänd anledning\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" DETALJERADE TESTRESULTAT\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: Sida 15, sektion 3.1.\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: Sida 15, sektion 3.2.\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: Sida 19, sektion 3.3.\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: Sida 20, sektion 3.4.\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: Sida 27, sektion 3.5.\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: Sida 42, sektion 5.2.\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: Sidorna 16-17, sektion 3.2.\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: Sidorna 42-45, sektion 5.2.\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: Sidorna 45-46, sektion 5.2.\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: Sidorna 48-49, sektion 5.2.\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: Sidorna 52-54, sektion 5.2.\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f byte\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " OK Standard%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " OK DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " OK DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " OK FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " OK FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " OK LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " OK LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " OK Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " OK ModelName\n" + +msgid " PASS NickName\n" +msgstr " OK NickName\n" + +msgid " PASS PCFileName\n" +msgstr " OK PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " OK PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " OK PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " OK PageSize\n" + +msgid " PASS Product\n" +msgstr " OK Product\n" + +msgid " PASS ShortNickName\n" +msgstr " OK ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" VARN \"%s %s\" är i konflikt med \"%s %s\"\n" +" (begränsare=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " VARN %s har inga motsvarande alternativ!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" VARN %s delar ett vanligt prefix med %s\n" +" REF: Sida 15, sektion 3.2.\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " VARN Standardval är i konflikt!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" VARN Nyckelordet %s för duplexalternativet kanske inte fungerar " +"som det ska och bör vara Duplex!\n" +" REF: Sida 122, sektion 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr "" +" VARN Filen innehåller en blandning av radslut med CR, LF och CR " +"LF!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" VARN LanguageEncoding krävs av PPD 4.3-spec.\n" +" REF: Sidorna 56-57, sektion 5.3.\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " VARN Rad %d innehåller endast mellanslag!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" VARN Manufacturer krävs av PPD 4.3-spec.\n" +" REF: Sidorna 58-59, sektion 5.3.\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" VARN Icke-Windows PPD-filer bör använda radslut med endast LF, " +"inte CR LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" VARN Föråldrad PPD-version %.1f!\n" +" REF: Sida 42, sektion 5.2.\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" VARN PCFileName längre än 8.3 i strid med PPD-spec.\n" +" REF: Sidorna 61-62, sektion 5.3.\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" VARN Protokollen innehåller PJL men JCL-attributen är inte " +"inställda.\n" +" REF: Sidorna 78-79, sektion 5.7.\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" VARN Protokollen innehåller både PJL och BCP, förväntade TBCP.\n" +" REF: Sidorna 78-79, sektion 5.7.\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" VARN ShortNickName krävs av PPD 4.3-spec.\n" +" REF: Sidorna 64-65, sektion 5.3.\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s finns inte!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s Felaktigt %s val %s!\n" +" REF: Sida 122, sektion 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr "" +" %s Felaktig UTF-8-översättningssträng ”%s” för alternativet %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Felaktig UTF-8-översättningssträng ”%s” för alternativet %s, valet " +"%s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s Felaktigt cupsFilter-värde \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s Felaktig cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s Felaktigt cupsFilter-värde \"%s\"!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Felaktig cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s Felaktigt språk \"%s\"!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s Tom cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s Saknad översättningssträng ”%s” för alternativet %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr "" +" %s Saknad översättningssträng ”%s” för alternativet %s, valet %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Valet *%s %s saknas i UIConstraints \"*%s %s *%s %s”!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Valet *%s %s saknas i cupsUIConstraints %s: \"%s”!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s Felaktigt cupsFilter-värde \"%s\"\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s Saknad cupsICCProfile-fil \"%s\"!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s Saknad cupsPreFilter-fil \"%s\"\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s Saknad cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s Alternativet %s saknas i UIConstraints \"*%s %s *%s %s\"!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s Alternativet %s saknas i cupsUIConstraints %s: \"%s\"!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s Ingen grundöversättning \"%s\" finns i filen!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s KRÄVER %s definierar inte valet None!\n" +" REF: Sida 122, sektion 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s hashvärde står i konflikt med %s!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s orsakade en loop!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr "" +" **FEL** %s namnen %s och %s skiljer sig endast i fråga om stor eller " +"liten bokstav!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **FEL** %s måste vara 1284DeviceID!\n" +" REF: Sida 72, sektion 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FEL** FELAKTIG standard%s %s\n" +" REF: Sida 40, sektion 4.5.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEL** FELAKTIG DefaultImageableArea %s!\n" +" REF: Sida 102, sektion 5.15.\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEL** FELAKTIG DefaultPaperDimension %s!\n" +" REF: Sida 103, sektion 5.15.\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **FEL** FELAKTIGT JobPatchFile-attribut i fil\n" +" REF: Sida 24, sektion 3.4.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FEL** FELAKTIG Manufacturer (ska vara \"HP\")\n" +" REF: Sida 211, tabell D.1.\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **FEL** FELAKTIG Manufacturer (ska vara \"Oki\")\n" +" REF: Sida 211, tabell D.1.\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FEL** FELAKTIG ModelName- \"%c\" tillåts inte i sträng.\n" +" REF: Sidorna 59-60, sektion 5.3.\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FEL** FELAKTIG PSVersion - inte \"(string) int\".\n" +" REF: Sidorna 62-64, sektion 5.3.\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FEL** FELAKTIG Product - inte \"(string)\".\n" +" REF: Sida 62, sektion 5.3.\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **FEL** FELAKTIG ShortNickName - längre än 31 tecken.\n" +" REF: Sidorna 64-65, sektion 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **FEL** Felaktigt %s-val %s!\n" +" REF: Sida 84, sektion 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEL** Felaktig FileVersion \"%s\"\n" +" REF: Sida 56, sektion 5.3.\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEL** Felaktig FormatVersion \"%s\"\n" +" REF: Sida 56, sektion 5.3.\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **FEL** Felaktig språkkodning %s - måste vara ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **FEL** Felaktigt språk %s - måste vara engelska!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **FEL** Förvald alternativkod kan inte tolkas: %s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr "" +" **FEL** Standardöversättningssträng för alternativet %s val %s " +"innehåller 8-bitars tecken!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr "" +" **FEL** Standardöversättningssträng för alternativet %s innehåller 8-" +"bitars tecken!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr "" +" **FEL** Gruppnamnen %s och %s skiljer sig endast i fråga om stor " +"eller liten bokstav!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **FEL** Flera förekomster av %s namn %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr "" +" **FEL** Alternativnamnen %s och %s skiljer sig endast i fråga om stor " +"eller liten bokstav!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **FEL** Standard%s KRÄVS\n" +" REF: Sida 40, sektion 4.5.\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEL** KRÄVER DefaultImageableArea\n" +" REF: Sida 102, sektion 5.15.\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEL** KRÄVER DefaultPaperDimension\n" +" REF: Sida 103, sektion 5.15.\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER FileVersion\n" +" REF: Sida 56, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER FormatVersion\n" +" REF: Sida 56, sektion 5.3.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **FEL** KRÄVER ImageableArea för PageSize %s\n" +" REF: Sida 41, sektion 5.\n" +" REF: Sida 102, sektion 5.15.\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER LanguageEncoding\n" +" REF: Sidorna 56-57, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER LanguageVersion\n" +" REF: Sidorna 57-58, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER Manufacturer\n" +" REF: Sidorna 58-59, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER ModelName\n" +" REF: Sidorna 59-60, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER NickName\n" +" REF: Sida 60, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER PCFileName\n" +" REF: Sidorna 61-62, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER PSVersion\n" +" REF: Sidorna 62-64, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **FEL** KRÄVER PageRegion\n" +" REF: Sida 100, sektion 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **FEL** KRÄVER PageSize\n" +" REF: Sida 41, sektion 5.\n" +" REF: Sida 99, sektion 5.14.\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **FEL** KRÄVER PageSize\n" +" REF: Sidorna 99-100, sektion 5.14.\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **FEL** KRÄVER PaperDimension för PageSize %s\n" +" REF: Sida 41, sektion 5.\n" +" REF: Sida 103, sektion 5.15.\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER Product\n" +" REF: Sida 62, sektion 5.3.\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **FEL** KRÄVER ShortNickName\n" +" REF: Sidorna 64-65, sektion 5.3.\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " %d FEL HITTADES\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" Felaktig %%%%BoundingBox: på rad %d!\n" +" REF: Sida 39, %%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" Felaktig %%%%Page: på rad %d!\n" +" REF: Sida 53, %%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" Felaktiga %%%%Pages: på rad %d!\n" +" REF: Sida 43, %%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" Rad %d är längre än 255 tecken (%d)!\n" +" REF: Sida 25, Line Length\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" Saknar %!PS-Adobe-3.0 på första raden!\n" +" REF: Sida 17, 3.1 Conforming Documents\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" Saknar %%EndComments-kommentar!\n" +" REF: Sida 41, %%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" Saknad eller felaktig %%BoundingBox: kommentar!\n" +" REF: Sida 39, %%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" Saknad eller felaktig %%Page: kommentar!\n" +" REF: Sida 53, %%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" Saknad eller felaktig %%Pages: kommentar!\n" +" REF: Sida 43, %%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " INGA FEL HITTADES\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " Såg %d rader som översteg 255 tecken!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " För många %%BeginDocument-kommentarer!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " För många %%EndDocument-kommentarer!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " Varning: filen innehåller binärdata!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " Varning: ingen %%EndComments-kommentar i fil!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " Varning: föråldrad DSC-version %.1f i fil!\n" + +msgid " FAIL\n" +msgstr " FEL\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" FEL\n" +" **FEL** Kunde inte öppna PPD-fil - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" FEL\n" +" **FEL** Kunde inte öppna PPD-fil - %s på rad %d.\n" + +msgid " PASS\n" +msgstr " OK\n" + +msgid "#10 Envelope" +msgstr "#10 Envelope" + +msgid "#11 Envelope" +msgstr "#11 Envelope" + +msgid "#12 Envelope" +msgstr "#12 Envelope" + +msgid "#14 Envelope" +msgstr "#14 Envelope" + +msgid "#9 Envelope" +msgstr "#9 Envelope" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f byte\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f byte\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f millimeter" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f to %.0f x %.0f millimeter" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f tum" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f to %.2f x %.2f tum" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s accepterar begäran sedan %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s kan inte ändras." + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s är inte införd i CUPS-versionen av lpc.\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s är inte klar\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s är klar\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s är klar och skriver ut\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s accepterar inte begäran sedan %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s stöds inte!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s accepterar begäran sedan %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s accepterar inte begäran sedan %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s: %-33.33s [utskrift %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s: %s misslyckades: %s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s: Vet inte vad som ska göras!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: Fel - miljövariabeln %s namnger icke-existerande mål \"%s\"!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s: Fel - felaktigt utskrifts-ID!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s: Fel - kan inte skriva ut filer och ändra utskrifter samtidigt!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "" +"%s: Fel - kan inte skriva ut från standard in om filer eller ett utskrifts-" +"ID anges!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s: Fel - förväntade teckenkodning efter alternativet ”-S”!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s: Fel - förväntade innehållstyp efter alternativet ”-T”!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s: Fel - förväntade exemplar efter alternativet ”-n”!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s: Fel - förväntade antal exemplar efter alternativet ”-#”!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s: Fel - förväntade mål efter alternativet ”-P”!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s: Fel - förväntade mål efter alternativet ”-b”!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s: Fel - förväntade mål efter alternativet ”-d”!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s: Fel - förväntade format efter alternativet ”-f”!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s: Fel - förväntade kvarhållningsnamn efter alternativet ”-H”!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s: Fel - förväntade värdnamn efter alternativet ”-H”!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s: Fel - förväntade värdnamn efter alternativet ”-h”!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s: Fel - förväntade lägeslista efter alternativet ”-y”!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s: Fel - förväntade namn efter alternativet ”-%c”!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s: Fel - förväntade alternativsträng efter alternativet ”-o”!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s: Fel - förväntade sidlista efter alternativet ”-P”!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s: Fel - förväntade prioritet efter alternativet ”-%c”!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s: Fel - förväntade anledningstext efter alternativet ”-r”!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s: Fel - förväntade titel efter alternativet ”-t”!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s: Fel - förväntade användarnamn efter alternativet ”-U”!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s: Fel - förväntade användarnamn efter alternativet ”-U”!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s: Fel - förväntade värde efter alternativet ”-%c”!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s: Fel - behöver ”completed”, ”not-completed” eller ”all” efter " +"alternativet ”-W”!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s: Fel - inget standardmål tillgängligt.\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s: Fel - prioritet måste vara mellan 1 och 100.\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s: Fel - schemaläggare svarar inte!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s: Fel - för många filer - \"%s\"\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s: Fel - kunde inte komma åt \"%s\" - %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s: Fel - kunde inte köa från standard in - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s: Fel - okänt mål \"%s\"!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s: Fel - okänt mål \"%s/%s\"!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s: Fel - okänt alternativ ”%c”!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s: Fel - okänt alternativ ”%s”!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s: Förväntade utskrifts-ID efter alternativet ”-i”!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s: Filter \"%s\" inte tillgängligt: %s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s: Ogiltigt målnamn i listan \"%s\"!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s: Ogiltig filtersträng \"%s\"\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s: Behöver utskrifts-ID (”-i jobid”) före ”-H restart”!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s: Filter saknas för konvertering från %s/%s till %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s: Åtgärd misslyckades: %s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s: Tyvärr, inget stöd för kryptering har byggts in!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s: Kunde inte ansluta till server\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s: Kunde inte kontakta server!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s: Kan inte avgöra MIME-typ hos \"%s\"!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s: Kan inte öppna %s: %s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s: Kan inte öppna PPD-fil: %s på rad %d\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s: Kan inte läsa MIME-databas från \"%s\" eller \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s: Okänt mål \"%s\"!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s: Okänd mål-MIME-typ %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s: Okänt alternativ ”%c”!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s: Okänd käll-MIME-typ %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "" +"%s: Varning - ”%c” formatmodifieraren stöds inte - utmatning kanske inte " +"blir korrekt!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s: Varning - alternativet för teckenkodning ignorerades!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s: Varning - alternativet för innehållstyp ignorerades!" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s: Varning - formuläralternativ ignorerades!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s: Varning - lägesalternativ ignorerades!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s: fel - miljövariabeln %s namnger icke-existerande mål \"%s\"!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s: förväntade option=value efter alternativet ”-o”!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s: Fel - inget standardmål tillgängligt.\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 tum/sek." + +msgid "1.25x0.25\"" +msgstr "1,25 x 0,25" + +msgid "1.25x2.25\"" +msgstr "1,25 x 2,25\"" + +msgid "1.5 inch/sec." +msgstr "1,5 tum/sek." + +msgid "1.50x0.25\"" +msgstr "1,50 x 0,25\"" + +msgid "1.50x0.50\"" +msgstr "1,50 x 0,50" + +msgid "1.50x1.00\"" +msgstr "1,50 x 1,00\"" + +msgid "1.50x2.00\"" +msgstr "1,50 x 2,00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 tum/sek." + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 mm/sek." + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 tum/sek." + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 tum/sek." + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 mm/sek." + +msgid "120x60dpi" +msgstr "120 x 60 dpi" + +msgid "120x72dpi" +msgstr "120 x 72 dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136 dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 mm/sek." + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 mm/sek." + +msgid "150dpi" +msgstr "150 dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180 dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 tum/sek." + +msgid "2-Sided Printing" +msgstr "Dubbelsidig utskrift" + +msgid "2.00x0.37\"" +msgstr "2,00 x 0,37\"" + +msgid "2.00x0.50\"" +msgstr "2,00 x 0,50\"" + +msgid "2.00x1.00\"" +msgstr "2,00 x 1,00\"" + +msgid "2.00x1.25\"" +msgstr "2,00 x 1,25\"" + +msgid "2.00x2.00\"" +msgstr "2,00 x 2,00\"" + +msgid "2.00x3.00\"" +msgstr "2,00 x 3,00\"" + +msgid "2.00x4.00\"" +msgstr "2,00 x 4,00\"" + +msgid "2.00x5.50\"" +msgstr "2,00 x 5,50\"" + +msgid "2.25x0.50\"" +msgstr "2,25 x 0,50\"" + +msgid "2.25x1.25\"" +msgstr "2,25 x 1,25\"" + +msgid "2.25x4.00\"" +msgstr "2,25 x 4,00\"" + +msgid "2.25x5.50\"" +msgstr "2,25 x 5,50\"" + +msgid "2.38x5.50\"" +msgstr "2,38 x 5,50\"" + +msgid "2.5 inches/sec." +msgstr "2.5 tum/sek." + +msgid "2.50x1.00\"" +msgstr "2,50 x 1,00\"" + +msgid "2.50x2.00\"" +msgstr "2,50 x 2,00\"" + +msgid "2.75x1.25\"" +msgstr "2,75 x 1,25\"" + +msgid "2.9 x 1\"" +msgstr "2,9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 mm/sek." + +msgid "200 mm/sec." +msgstr "200 mm/sek." + +msgid "203dpi" +msgstr "203 dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "Serier med 24 pin" + +msgid "240x72dpi" +msgstr "240 x 72 dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 mm/sek." + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 tum/sek." + +msgid "3.00x1.00\"" +msgstr "3,00 x 1,00\"" + +msgid "3.00x1.25\"" +msgstr "3,00 x 1,25\"" + +msgid "3.00x2.00\"" +msgstr "3,00 x 2,00\"" + +msgid "3.00x3.00\"" +msgstr "3,00 x 3,00\"" + +msgid "3.00x5.00\"" +msgstr "3,00 x 5,00\"" + +msgid "3.25x2.00\"" +msgstr "3,25 x 2,00\"" + +msgid "3.25x5.00\"" +msgstr "3,25 x 5,00\"" + +msgid "3.25x5.50\"" +msgstr "3,25 x 5,50\"" + +msgid "3.25x5.83\"" +msgstr "3,25 x 5,83\"" + +msgid "3.25x7.83\"" +msgstr "3,25 x 7,83\"" + +msgid "3.5\" Disk" +msgstr "3.5\" Disk" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3,5\" Disk - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3,50 x 1,00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 mm/sek." + +msgid "300 mm/sec." +msgstr "300 mm/sek." + +msgid "300dpi" +msgstr "300 dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360 dpi" + +msgid "360x180dpi" +msgstr "360 x 180 dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 tum/sek." + +msgid "4.00x1.00\"" +msgstr "4,00 x 1,00\"" + +msgid "4.00x13.00\"" +msgstr "4,00 x 13,00\"" + +msgid "4.00x2.00\"" +msgstr "4,00 x 2,00\"" + +msgid "4.00x2.50\"" +msgstr "4,00 x 2,50\"" + +msgid "4.00x3.00\"" +msgstr "4,00 x 3,00\"" + +msgid "4.00x4.00\"" +msgstr "4,00 x 4,00\"" + +msgid "4.00x5.00\"" +msgstr "4,00 x 5,00\"" + +msgid "4.00x6.00\"" +msgstr "4,00 x 6,00\"" + +msgid "4.00x6.50\"" +msgstr "4,00 x 6,50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 mm/sek." + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 tum/sek." + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 tum/sek." + +msgid "6.00x1.00\"" +msgstr "6,00 x 1,00\"" + +msgid "6.00x2.00\"" +msgstr "6,00 x 2,00\"" + +msgid "6.00x3.00\"" +msgstr "6,00 x 3,00\"" + +msgid "6.00x4.00\"" +msgstr "6,00 x 4,00\"" + +msgid "6.00x5.00\"" +msgstr "6,00 x 5,00\"" + +msgid "6.00x6.00\"" +msgstr "6,00 x 6,00\"" + +msgid "6.00x6.50\"" +msgstr "6,00 x 6,50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 mm/sek." + +msgid "600dpi" +msgstr "600 dpi" + +msgid "60dpi" +msgstr "60 dpi" + +msgid "60x720dpi" +msgstr "60 x 720 dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 tum/sek." + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720 dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 tum/sek." + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8,00 x 1,00\"" + +msgid "8.00x2.00\"" +msgstr "8,00 x 2,00\"" + +msgid "8.00x3.00\"" +msgstr "8,00 x 3,00\"" + +msgid "8.00x4.00\"" +msgstr "8,00 x 4,00\"" + +msgid "8.00x5.00\"" +msgstr "8,00 x 5,00\"" + +msgid "8.00x6.00\"" +msgstr "8,00 x 6,00\"" + +msgid "8.00x6.50\"" +msgstr "8,00 x 6,50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 mm/sek." + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 tum/sek." + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "Serier med 9 pin" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?Ogiltigt hjälpkommando okänt\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "Ett Samba-lösenord krävs för att exportera skrivardrivrutiner" + +msgid "A Samba username is required to export printer drivers!" +msgstr "Ett Samba-användarnamn krävs för att exportera skrivardrivrutiner!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "En klass med namnet \"%s\" finns redan!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "En skrivare med namnet \"%s\" finns redan!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3 (större)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4 (större)" + +msgid "A4 (Small)" +msgstr "A4 (mindre)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5 (större)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "Acceptera utskrifter" + +msgid "Accepted" +msgstr "Accepterade" + +msgid "Add Class" +msgstr "Lägg till klass" + +msgid "Add Printer" +msgstr "Lägg till skrivare" + +msgid "Add RSS Subscription" +msgstr "Lägg till RSS-prenumeration" + +msgid "Address" +msgstr "Adress" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "Adress - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "Administration" + +msgid "Always" +msgstr "Alltid" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "Applikator" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "Försök att ställa in %s printer-state till felaktigt värde %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "Attributgrupper har fel ordning (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "Felaktig NULL- destinationspekare" + +msgid "Bad OpenGroup" +msgstr "Felaktig OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "Felaktig OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "Felaktig OrderDependency" + +msgid "Bad Request" +msgstr "Felaktig begäran" + +msgid "Bad SNMP version number" +msgstr "Felaktigt SNMP-versionsnummer" + +msgid "Bad UIConstraints" +msgstr "Felaktig UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "Felaktigt värde för exemplar %d." + +msgid "Bad custom parameter" +msgstr "Felaktig anpassad parameter" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "Felaktig device URI \"%s\"!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "Felaktig device-uri \"%s\"!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "Felaktigt device-uri-system\"%s\"!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "Felaktigt document-format \"%s\"!" + +msgid "Bad filename buffer!" +msgstr "Felaktig buffring av filnamn!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "Felaktigt teckensnittsattribut: %s\n" + +msgid "Bad job-priority value!" +msgstr "Felaktigt värde för utskriftsprioritet!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "Felaktigt värde för utskriftsark \"%s\"!" + +msgid "Bad job-sheets value type!" +msgstr "Felaktigt värde för typ av utskriftsark!" + +msgid "Bad job-state value!" +msgstr "Felaktigt värde för utskriftsstatus!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "Felaktigt attribut för job-uri \"%s\"!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "Felaktig notify-pull-method \"%s\"!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "Felaktig URI för notify-recipient \"%s\"!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "Felaktigt värde för exemplar %d." + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "Felaktigt alternativ + val på rad %d!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "Felaktiga värden för sidintervall %d-%d." + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "Felaktig portövervakare \"%s\"!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "Felaktigt värde för skrivarstatus %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "Felaktigt versionsnummer %d.%d för begäran!" + +msgid "Bad subscription ID!" +msgstr "Felaktigt prenumerations-ID!" + +msgid "Banners" +msgstr "Banners" + +msgid "Billing Information: " +msgstr "Faktureringsinformation: " + +msgid "Bond Paper" +msgstr "Fint papperr" + +msgid "C0 Envelope" +msgstr "Kuvert C0" + +msgid "C1 Envelope" +msgstr "Kuvert C1" + +msgid "C2 Envelope" +msgstr "Kuvert C2" + +msgid "C3 Envelope" +msgstr "Kuvert C3" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "Kuvert C4" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "Kuvert C5" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "Kuvert C6" + +msgid "C65 Envelope" +msgstr "Kuvert C65" + +msgid "C7 Envelope" +msgstr "Kuvert C7" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "Etikettskrivare CPCL" + +msgid "Cancel RSS Subscription" +msgstr "Avbryt RSS-prenumeration" + +msgid "Change Settings" +msgstr "Ändra inställningar" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "Teckenkodningen \"%s\" stöds inte!" + +msgid "Chou3 Envelope" +msgstr "Chou3-kuvert" + +msgid "Chou4 Envelope" +msgstr "Chou4-kuvert" + +msgid "Classes" +msgstr "Klasser" + +msgid "Clean Print Heads" +msgstr "Rengör skrivarhuvuden" + +msgid "Color" +msgstr "Färg" + +msgid "Color Mode" +msgstr "Färgläge" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"Kommandon kan förkortas. Kommandon är:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "Gruppnamn använder obegränsad längd" + +msgid "Continue" +msgstr "Fortsätt" + +msgid "Continuous" +msgstr "Kontinuerlig" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "Kunde inte skanna typen \"%s\"!" + +msgid "Cover open." +msgstr "Lock öppet." + +msgid "Created" +msgstr "Skapad" + +msgid "Created On: " +msgstr "Skapad den: " + +msgid "Custom" +msgstr "Anpassad" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "Beskär" + +msgid "Cutter" +msgstr "Beskärare" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL-kuvert" + +msgid "Dark" +msgstr "Mörk" + +msgid "Darkness" +msgstr "Mörkhet" + +msgid "Delete Class" +msgstr "Ta bort klass" + +msgid "Delete Printer" +msgstr "Ta bort skrivare" + +msgid "Description: " +msgstr "Beskrivning: " + +msgid "DeskJet Series" +msgstr "DeskJet-serier" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "Mål \"%s\" tar inte emot utskrifter." + +msgid "Developer almost empty." +msgstr "Tonern nästan slut." + +msgid "Developer empty!" +msgstr "Tonern är slut!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"Enhet: uri = %s\n" +" klass = %s\n" +" info = %s\n" +" tillverkning-och-modell = %s\n" +" enhets-id = %s\n" +" plats = %s\n" + +msgid "Direct Thermal Media" +msgstr "Termiska direktmedia" + +msgid "Disabled" +msgstr "Avaktiverad" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "Dokument %d hittades inte i utskrift %d." + +msgid "Door open." +msgstr "Lucka öppen." + +msgid "Double Postcard" +msgstr "Dubbelt vykort" + +msgid "Driver Name: " +msgstr "Drivrutinnamn: " + +msgid "Driver Version: " +msgstr "Drivrutinversion: " + +msgid "Duplexer" +msgstr "Duplexr" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: Kunde inte tilldela minne för sidinfo: %s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: Kunde inte tilldela minne för sidordning: %s\n" + +msgid "EPL1 Label Printer" +msgstr "Etikettskrivare EPL1" + +msgid "EPL2 Label Printer" +msgstr "Etikettskrivare EPL2" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: Felaktig %%BoundingBox: kommentar sedd!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: Felaktig %%IncludeFeature: kommentar!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: Felaktig %%Page: kommentar i fil!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: Felaktig %%PageBoundingBox: kommentar i fil!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: Felaktig SCSI-enhetsfil \"%s\"!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: Felaktig teckenkodningsfil %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: Felaktig teckenkodningstyp %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: Felaktigt kolumnvärde %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: Felaktigt cpi-värde %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: Felaktig typsnittsbeskrivning rad: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: Felaktigt lpi-värde %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: Felaktigt utskriftsformat!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: Felaktig textriktning %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: Felaktig textbredd %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: Målskrivaren finns inte!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: Duplikat av %%BoundingBox: kommentar sedd!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: Duplikat av %%Pages: kommentar sedd!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: Tom utskriftsfil!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: Fel %d vid sändning av PAPSendData- begäran: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: Förväntad sträng inom citationstecken på rad %d av %s!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: Allvarligt USB-fel!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: Ogiltigt HP-GL/2-kommando sett, kan inte skriva ut filen!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: Saknad %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: Saknad %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: Saknar värde på rad %d i bannerfil!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: Ingen %%BoundingBox: kommentar i sidhuvud!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: Inga %%Pages: kommentar i sidhuvud!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "" +"ERROR: Ingen enhets-URI hittades i argv[0] eller i miljövariabeln " +"DEVICE_URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: Inga typsnitt i teckenkodningsfil %s\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: Inga sidor hittades!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: Slut på papper!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER-miljövariabeln är inte definierad!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: Utskriftsfilen accepterades inte (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: Skrivaren svarar inte\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: Skrivaren svarar inte\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: Skrivare skickade oväntat EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: Fjärrvärden accepterade inte styrfilen (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: Fjärrvärden accepterade inte datafilen (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: Ett tidsgränsfel uppstod vid sändning av data till skrivare\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: Kunde inte lägga till filen %d i utskriften: %s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: Kunde inte avbryta utskriften %d: %s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: Kunde inte kopiera PDF-fil" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: Kunde inte skapa sockel" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: Kunde inte skapa en temporär komprimerad utskriftsfil: %s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: Kunde inte skapa temporär fil" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: Kunde inte utföra pictwpstops: %s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: Kunde inte exekvera gs-program" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: Kunde inte exekvera pdftops-program" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: Kunde inte grena process: %s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: Kunde inte hämta PAP-förfrågan" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: Kunde inte hämta PAP-svar" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: Ingen PPD-fil för skrivaren \"%s\" - %s.\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: Kunde inte hämta förvald AppleTalk-zon" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: Kunde inte hämta utskriftsattribut %d (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: Kunde inte hämta skrivarstatus (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: Kunde inte hitta skrivaren ”%s”!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: Kunde inte söka PAP-svar" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: Kunde inte söka AppleTalk-skrivare" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: Kunde inte göra AppleTalk-adress" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: Kunde inte öppna \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: Kunde inte öppna %s: %s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: Kunde inte öppna bannerfil \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: Kunde inte öppna enhetsfil \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: Kunde inte öppna fil \"%s\" - %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: Kunde inte öppna fil \"%s\": %s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: Kunde inte öppna bildfilen för utskrift!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: Kunde inte öppna utskriftsfilen \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: Kunde inte öppna utskriftsfilen %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: Kunde inte öppna utskriftsfilen %s: %s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: Kunde inte öppna temporär komprimerad utskriftsfil: %s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: Kunde inte skriva ut %d textkolumner!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: Kunde inte skriva ut %dx%d textsida!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: Kunde inte läsa utskriftsdata" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: Kunde inte läsa utskriftsdata!" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: Kunde inte reservera porten" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: Kunde inte skapa offset %ld i fil - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: Kunde inte skapa offset %lld i fil - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: Kunde inte skicka LPD-kommando" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: Kunde inte skicka PAP-tickle-förfrågan" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: Kunde inte skicka första PAP-send-data-förfrågan" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: Kunde inte skicka utskriftsdata (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: Kunde inte skicka utskriftsdata!" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: Kunde inte skicka utskriftsfil till skrivare" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: Kunde inte skicka avslutande nullvärden till skrivare" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: Kunde inte vänta på pictwpstops: %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: Kunde inte skriva %d byte till \"%s\": %s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: Kunde inte skriva %d byte till skrivare!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: Kunde inte skriva styrfil" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: Kunde inte skriva utskriftsdata" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: Kunde inte skriva utskriftsdata: %s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: Kunde skriva rasterdata till skrivaren!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: Kunde inte skriva till temporär fil" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: Kunde inte skriva okomprimerade dokumentdata: %s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: Oväntad text på rad %d av %s!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: Okänt krypteringsalternativvärde \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: Okänd filordning \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: Okänt formattecken \"%c\"\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: Okänt meddelandekatalogformat för \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: Okänt alternativ \"%s\" med värde \"%s\"!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: Okänt utskriftsläge \"%s\"\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: Okänt versionsalternativvärde \"%s\"!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: Värdet %s för ljusstyrka stöds inte, använder ljusstyrka=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: Värdet %s för gamma stöds inte, använder gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: Värdet %d för number-up stöds inte, använder number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: Värdet %s för number-up-layout stöds inte, använder number-up-" +"layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "" +"ERROR: Värdet %s för sidmarginal stöds inte, använder page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: doc_printf overflow (%d byte) upptäckt, stoppar!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops avslutade med signalen %d!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops avslutades med status %d!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "" +"ERROR: kan återställas: Kan inte ansluta till skrivaren, försöker igen om 30 " +"sekunder...\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() kunde inte utföras" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: kan inte få status för utskriftsfilen" + +msgid "Edit Configuration File" +msgstr "Redigera konfigurationsfil" + +msgid "Empty PPD file!" +msgstr "Tom PPD-fil!" + +msgid "Ending Banner" +msgstr "Slutbanner" + +msgid "Enter old password:" +msgstr "Ange gammalt lösenord:" + +msgid "Enter password again:" +msgstr "Ange lösenord igen:" + +msgid "Enter password:" +msgstr "Ange lösenord:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"Ange ditt användarnamn och lösenord eller root-användarnamnet och lösenord " +"för att komma åt denna sida. Om du använder Kerberos-autentisering, " +"kontrollera att du har en giltig Kerberos-biljett." + +msgid "Envelope Feed" +msgstr "Kuvertmatare" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "Felpolicy" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "Fel: behöver värdnamn efter alternativet ”-h”!\n" + +msgid "Every 10 Labels" +msgstr "Var tionde etikett" + +msgid "Every 2 Labels" +msgstr "Varannan etikett" + +msgid "Every 3 Labels" +msgstr "Var tredje etikett" + +msgid "Every 4 Labels" +msgstr "Var fjärde etikett" + +msgid "Every 5 Labels" +msgstr "Var femte etikett" + +msgid "Every 6 Labels" +msgstr "Var sjätte etikett" + +msgid "Every 7 Labels" +msgstr "Var sjunde etikett" + +msgid "Every 8 Labels" +msgstr "Var åttonde etikett" + +msgid "Every 9 Labels" +msgstr "Var nionde etikett" + +msgid "Every Label" +msgstr "Alla etiketter" + +msgid "Expectation Failed" +msgstr "Ej förväntad respons" + +msgid "Export Printers to Samba" +msgstr "Exportera skrivare till Samba" + +msgid "FAIL\n" +msgstr "FEL\n" + +msgid "File Folder" +msgstr "Filmapp" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "Filmapp - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"Filenhets URI:er har blivit avaktiverade! För att aktivera, se direktivet " +"FileDevice i \"%s/cupsd.conf\"." + +msgid "Folio" +msgstr "Folio" + +msgid "Forbidden" +msgstr "Förbjudet" + +msgid "Fuser temperature high!" +msgstr "Hög fixeringstemperatur!" + +msgid "Fuser temperature low!" +msgstr "Låg fixeringstemperatur!" + +msgid "General" +msgstr "Allmänt" + +msgid "Generic" +msgstr "Generisk" + +msgid "German FanFold" +msgstr "German FanFold" + +msgid "German FanFold Legal" +msgstr "German FanFold Legal" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU använder obegränsad längd" + +msgid "Glossy Paper" +msgstr "Blankt papper" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "Attribut för printer-uri finns, men inget utskrifts-ID!" + +msgid "Grayscale" +msgstr "Gråskala" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "Hängmapp" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "Hängmapp- 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk avaktiverat i Systeminställningar\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk avaktiverat i Systeminställningar.\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: Avbryter utskrift...\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: Ansluten till skrivare...\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: Ansluter till skrivare...\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: Styrfil har skickats\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: Datafil har skickats\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: Formaterar sidan %d...\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: Läser in bildfil...\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: Söker skrivare...\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: Öppnar anslutning\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: Utskriftsfil skickad, väntar på skrivaren...\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: Skrivaren är upptagen, försöker igen om 10 sekunder...\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: Skrivaren är upptagen, försöker igen om 30 sekunder...\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: Skrivaren är upptagen, försöker igen om 5 sekunder...\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: Skrivaren stöder inte IPP/%d.%d, försöker med IPP/1.0...\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: Skrivaren är upptagen, försöker igen om 5 sekunder...\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: Skrivaren är frånkopplad just nu.\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: Skrivaren är frånkopplad just nu.\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: Skrivaren är online nu.\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: Skrivaren är frånkopplad.\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: Skrivaren är inte ansluten, försöker igen om 30 sekunder...\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: Skriver ut sidan %d, %d %% klart...\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: Skriver ut sidan %d...\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: Klar för utskrifter.\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: Skickar styrfil (%lu byte)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: Skickar styrfil (%u byte)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: Skickar data\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: Skickar datafil (%ld byte)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: Skickar datafil (%lld byte)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: Skickar utskriftsdata...\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: Skickar utskriftsfil, %ld byte...\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: Skickar utskriftsfil, %lld byte...\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: Buffrar LPR-utskrift, %.0f %% klart...\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "" +"INFO: Kan inte kontakta skrivaren, köar för nästa skrivare i klassen...\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: Använder förvald AppleTalk-zon \"%s\"\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: Väntar på att utskrift ska bli klar...\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: Väntar på att skrivaren ska bli tillgänglig...\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "Kuvert ISO B4" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5 (större)" + +msgid "ISO B5 Envelope" +msgstr "Kuvert ISO B5" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "Kuvert ISO B6" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "Otillåtet styrtecken" + +msgid "Illegal main keyword string" +msgstr "Otillåten huvudnyckelordssträng" + +msgid "Illegal option keyword string" +msgstr "Otillåten alternativnyckelordssträng" + +msgid "Illegal translation string" +msgstr "Otillåten översättningssträng" + +msgid "Illegal whitespace character" +msgstr "Otillåtet blanktecken" + +msgid "Ink/toner almost empty." +msgstr "Bläck/toner är nästan slut." + +msgid "Ink/toner empty!" +msgstr "Bläck/toner är slut!" + +msgid "Ink/toner waste bin almost full." +msgstr "Avfallsbehållaren för bläck/toner nästan full." + +msgid "Ink/toner waste bin full!" +msgstr "Avfallsbehållaren för bläck/toner är full!" + +msgid "Installable Options" +msgstr "Installerbara alternativ" + +msgid "Installed" +msgstr "Installerad" + +msgid "IntelliBar Label Printer" +msgstr "Eikettskrivare från IntelliBar" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Spärrmekanism öppen." + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "Internt fel" + +msgid "Internet Postage 2-Part" +msgstr "Internet Postage 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Internet Postage 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet Postage 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internet Printing Protocol" + +msgid "Invite Envelope" +msgstr "Invite-kuvert" + +msgid "Italian Envelope" +msgstr "Italienskt kuvert" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "Utskrift #%d kan inte startas om - inga filer!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "Utskrift #%d finns inte!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "Utskrift #%d är redan avbruten - kan inte avbryta." + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "Utskrift #%d är redan avbruten - kan inte avbryta." + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "Utskrift #%d är redan klar - kan inte avbryta." + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "Utskrift #%d är klar och kan inte ändras!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "Utskrift #%d är inte klar!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "Utskrift #%d hålls inte kvar för autentisering!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "Utskrift #%d hålls inte kvar" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "Utskrift #%s finns inte!" + +#, c-format +msgid "Job %d not found!" +msgstr "Utskrift %d hittades inte!" + +msgid "Job Completed" +msgstr "Utskriften är klar" + +msgid "Job Created" +msgstr "Utskrift skapad" + +msgid "Job ID: " +msgstr "Uskrifts-ID: " + +msgid "Job Options Changed" +msgstr "Utskriftsalternativ ändrades" + +msgid "Job Stopped" +msgstr "Utskriften har stoppats" + +msgid "Job UUID: " +msgstr "Utskriftens UUID: " + +msgid "Job is completed and cannot be changed." +msgstr "Utskriften är klar och kan inte ändras." + +msgid "Job operation failed:" +msgstr "Utskriftsåtgärd misslyckades:" + +msgid "Job state cannot be changed." +msgstr "Utskriftsstatus kan inte ändras." + +msgid "Job subscriptions cannot be renewed!" +msgstr "Utskriftsprenumerationer kan inte förnyas!" + +msgid "Jobs" +msgstr "Utskrifter" + +msgid "Kaku2 Envelope" +msgstr "Kaku2-kuvert" + +msgid "Kaku3 Envelope" +msgstr "Kaku3-kuvert" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR-värd eller skrivare" + +msgid "Label Printer" +msgstr "Etikettskrivare" + +msgid "Label Top" +msgstr "Etikettens överdel" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "Språket \"%s\" stöds inte!" + +msgid "Large Address" +msgstr "Large Address" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "Large Address - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet Series PCL 4/5" + +msgid "Light" +msgstr "Lätt" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "Rad överskrider maxlängd (255 tecken)" + +msgid "List Available Printers" +msgstr "Senast tillgängliga skrivare" + +msgid "Location: " +msgstr "Plats: " + +msgid "Long-Edge (Portrait)" +msgstr "Långsida (porträtt)" + +msgid "Make and Model: " +msgstr "Tillverkning och modell: " + +msgid "Manual Feed" +msgstr "Manuell matning" + +msgid "Media Dimensions: " +msgstr "Mediemått: " + +msgid "Media Limits: " +msgstr "Mediegränser: " + +msgid "Media Name: " +msgstr "Medienamn: " + +msgid "Media Size" +msgstr "Mediestorlek" + +msgid "Media Source" +msgstr "Mediekälla" + +msgid "Media Tracking" +msgstr "Mediespårning" + +msgid "Media Type" +msgstr "Medietyp" + +msgid "Media jam!" +msgstr "Medietrassel!" + +msgid "Media tray almost empty." +msgstr "Mediefack nästan tomt." + +msgid "Media tray empty!" +msgstr "Mediefack tomt!" + +msgid "Media tray missing!" +msgstr "Mediefack saknas!" + +msgid "Media tray needs to be filled." +msgstr "Mediefacket måste fyllas på." + +msgid "Medium" +msgstr "Medium" + +msgid "Memory allocation error" +msgstr "Minnestilldelningsfel" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "Saknar PPD-Adobe-4.x-huvud" + +msgid "Missing asterisk in column 1" +msgstr "Saknar asterisk i kolumn 1" + +msgid "Missing document-number attribute!" +msgstr "Saknar attribut för dokumentnummer!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "Saknar dubbla citationstecken på rad %d!" + +msgid "Missing form variable!" +msgstr "Saknar formatvariabel!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "Saknar attributet notify-subscription-ids!" + +msgid "Missing requesting-user-name attribute!" +msgstr "Saknar attributet requesting-user-name!" + +msgid "Missing required attributes!" +msgstr "Saknar nödvändiga attribut!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "Saknar värde på rad %d!" + +msgid "Missing value string" +msgstr "Saknar värdesträng" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"Modell: namn = %s\n" +" natural_language = %s\n" +" tillverkare-och-modell = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "Ändra klass" + +msgid "Modify Printer" +msgstr "Ändra skrivare" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch-kuvert" + +msgid "Move All Jobs" +msgstr "Flytta alla utskrifter" + +msgid "Move Job" +msgstr "Flytta utskrift" + +msgid "Moved Permanently" +msgstr "Flyttad permanent" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: Utskriftsfil accepterad - utskrifts-ID %d.\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: Utskriftsfil accepterad - utskrifts-ID okänt.\n" + +msgid "NULL PPD file pointer" +msgstr "NULL PPD-filspekare" + +msgid "Name OID uses indefinite length" +msgstr "OID-namn använder obegränsad längd" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "Aldrig" + +msgid "New Stylus Color Series" +msgstr "Nya Stylus Color-serier" + +msgid "New Stylus Photo Series" +msgstr "Nya Stylus Photo-serier" + +msgid "No" +msgstr "Nej" + +msgid "No Content" +msgstr "Inget innehåll" + +msgid "No PPD name!" +msgstr "Inget PPD-namn!" + +msgid "No VarBind SEQUENCE" +msgstr "Ingen VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "Inga skrivardrivrutiner för Windows är installerade!" + +msgid "No active connection" +msgstr "Ingen aktiv anslutning" + +#, c-format +msgid "No active jobs on %s!" +msgstr "Inga aktiva utskrifter på %s!" + +msgid "No attributes in request!" +msgstr "Inga attribut i begäran!" + +msgid "No authentication information provided!" +msgstr "Ingen autentiseringsinformation angiven!" + +msgid "No community name" +msgstr "Inget gruppnamn" + +msgid "No default printer" +msgstr "Ingen förvald skrivare" + +msgid "No destinations added." +msgstr "Inga mål tillagda." + +msgid "No error-index" +msgstr "Inget felindex" + +msgid "No error-status" +msgstr "Ingen felstatus" + +msgid "No file!?!" +msgstr "Ingen fil!?!" + +msgid "No modification time!" +msgstr "Ingen ändringstid!" + +msgid "No name OID" +msgstr "Inget OID-namn" + +msgid "No printer name!" +msgstr "Inget skrivarnamn!" + +msgid "No printer-uri found for class!" +msgstr "Ingen printer-uri hittades för klass!" + +msgid "No printer-uri found!" +msgstr "Inget printer-uri hittades!" + +msgid "No printer-uri in request!" +msgstr "Inga printer-uri i begäran!" + +msgid "No request-id" +msgstr "Inget order-ID" + +msgid "No subscription attributes in request!" +msgstr "Inga prenumerationsattribut i begäran!" + +msgid "No subscriptions found." +msgstr "Inga prenumerationer hittades." + +msgid "No variable-bindings SEQUENCE" +msgstr "Ingen variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "Inget versionsnummer" + +msgid "Non-continuous (Mark sensing)" +msgstr "Non-continuous (Mark sensing)" + +msgid "Non-continuous (Web sensing)" +msgstr "Non-continuous (Web sensing)" + +msgid "Normal" +msgstr "Normal" + +msgid "Not Found" +msgstr "Hittades inte" + +msgid "Not Implemented" +msgstr "Inte implementerad" + +msgid "Not Installed" +msgstr "Inte installerad" + +msgid "Not Modified" +msgstr "Inte ändrad" + +msgid "Not Supported" +msgstr "Stöds inte" + +msgid "Not allowed to print." +msgstr "Ingen förvald skrivare." + +msgid "Note" +msgstr "Anm" + +msgid "OK" +msgstr "OK" + +msgid "OPC almost at end-of-life." +msgstr "OPC nästan vid slutpunkten." + +msgid "OPC at end-of-life!" +msgstr "OPC vid slutpunkten!" + +msgid "Off (1-Sided)" +msgstr "Av (1-sidig)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "Hjälp på webben" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "Kunde inte öppna %s: %s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup utan en CloseGroup först" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI utan en CloseUI/JCLCloseUI först" + +msgid "Operation Policy" +msgstr "Åtgärdspolicy" + +msgid "Options Installed" +msgstr "Alternativ installerade" + +msgid "Options: " +msgstr "Alternativ: " + +msgid "Out of toner!" +msgstr "Slut på toner!" + +msgid "Output Mode" +msgstr "Utmatningsläge" + +msgid "Output bin almost full." +msgstr "Utmatningsfack nästan fullt." + +msgid "Output bin full!" +msgstr "Utmatningsfack fullt!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "Utmatning för skrivaren %s skickas till %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "Utmatning för skrivaren %s skickas till fjärrskrivaren %s på %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "Utmatning för skrivaren %s/%s skickas till %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "Utmatning för skrivaren %s/%s skickas till fjärrskrivaren %s på %s\n" + +msgid "Output tray missing!" +msgstr "Utmatningsfack saknas!" + +msgid "PASS\n" +msgstr "OK\n" + +msgid "PCL Laser Printer" +msgstr "Laserskrivare PCL" + +msgid "PRC1 Envelope" +msgstr "Kuvert PRC1" + +msgid "PRC10 Envelope" +msgstr "Kuvert PRC10" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "Kuvert PRC2" + +msgid "PRC3 Envelope" +msgstr "Kuvert PRC3" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K (större)" + +msgid "PRC4 Envelope" +msgstr "Kuvert PRC4" + +msgid "PRC5 Envelope" +msgstr "Kuvert PRC5" + +msgid "PRC6 Envelope" +msgstr "Kuvert PRC6" + +msgid "PRC7 Envelope" +msgstr "Kuvert PRC7" + +msgid "PRC8 Envelope" +msgstr "Kuvert PRC8" + +msgid "PRC9 Envelope" +msgstr "Kuvert PRC9" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "Paket innehåller inte Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "Paket börjar inte med SEQUENCE" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "Lösenord för %s på %s? " + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "Lösenord för %s krävs för att nå %s via SAMBA: " + +msgid "Pause Class" +msgstr "Pausa klass" + +msgid "Pause Printer" +msgstr "Pausa skrivare" + +msgid "Peel-Off" +msgstr "Peel-Off" + +msgid "Personal Envelope" +msgstr "Personligt kuvert" + +msgid "Photo" +msgstr "Foto" + +msgid "Photo Labels" +msgstr "Fotoetiketter" + +msgid "Plain Paper" +msgstr "Vanligt papper" + +msgid "Policies" +msgstr "Policier" + +msgid "Port Monitor" +msgstr "Portövervakare" + +msgid "PostScript Printer" +msgstr "PostScript-skrivare" + +msgid "Postcard" +msgstr "Vykort" + +msgid "Print Density" +msgstr "Svärta" + +msgid "Print Job:" +msgstr "Utskrift:" + +msgid "Print Mode" +msgstr "Utskriftsläge" + +msgid "Print Rate" +msgstr "Utskriftshastighet" + +msgid "Print Self-Test Page" +msgstr "Skriv ut självtestsida" + +msgid "Print Speed" +msgstr "Utskriftshastighet" + +msgid "Print Test Page" +msgstr "Skriv ut testsida" + +msgid "Print and Cut" +msgstr "Skriv ut och beskär" + +msgid "Print and Tear" +msgstr "Skriv ut riv" + +msgid "Printed For: " +msgstr "Utskriven för: " + +msgid "Printed From: " +msgstr "Utskriven från: " + +msgid "Printed On: " +msgstr "Utskriven den: " + +msgid "Printer Added" +msgstr "Skrivare tillagd" + +msgid "Printer Default" +msgstr "Skrivarstandard" + +msgid "Printer Deleted" +msgstr "Skrivare borttagen" + +msgid "Printer Modified" +msgstr "Skrivare ändrad" + +msgid "Printer Name: " +msgstr "Skrivarnamn: " + +msgid "Printer Paused" +msgstr "Utskrift pausad" + +msgid "Printer Settings" +msgstr "Skrivarinställningar" + +msgid "Printer offline." +msgstr "Skrivare frånkopplad." + +msgid "Printer:" +msgstr "Skrivare:" + +msgid "Printers" +msgstr "Skrivare" + +msgid "Purge Jobs" +msgstr "Rensa utskrifter" + +msgid "Quarto" +msgstr "Kvartsark" + +msgid "Quota limit reached." +msgstr "Kvotgräns nådd." + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "" +"Prioritet Ägare Utskrift Fil(er) Total " +"storlek\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"Prioritet Ägare Utskrift Filer Total " +"storlek\n" + +msgid "Reject Jobs" +msgstr "Neka utskrifter" + +msgid "Reprint After Error" +msgstr "Skriv ut igen efter fel" + +msgid "Request Entity Too Large" +msgstr "Enheten är för stor" + +msgid "Resolution" +msgstr "Upplösning" + +msgid "Resume Class" +msgstr "Återuppta klass" + +msgid "Resume Printer" +msgstr "Återuppta skrivare" + +msgid "Return Address" +msgstr "Returadress" + +msgid "Return Address - 3/4 x 2\"" +msgstr "Returadress- 3/4 x 2\"" + +msgid "Rewind" +msgstr "Bakåt" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "Kör kommando: %s %s -N -A %s -c ”%s”\n" + +msgid "SCSI Printer" +msgstr "Skrivare SCSI" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE använder obegränsad längd" + +msgid "See Other" +msgstr "Visa andra" + +#, c-format +msgid "Serial Port #%d" +msgstr "Serieport #%d" + +msgid "Server Restarted" +msgstr "Servern har startats om" + +msgid "Server Security Auditing" +msgstr "Säkerhetskontroll av servern" + +msgid "Server Started" +msgstr "Servern har startat" + +msgid "Server Stopped" +msgstr "Servern har stoppats" + +msgid "Service Unavailable" +msgstr "Tjänst otillgänglig" + +msgid "Set Allowed Users" +msgstr "Ställ in tillåtna användare" + +msgid "Set As Server Default" +msgstr "Ställ in som serverförval" + +msgid "Set Class Options" +msgstr "Ställ in klassalternativ" + +msgid "Set Printer Options" +msgstr "Ställ in skrivaralternativ" + +msgid "Set Publishing" +msgstr "Ställ in publicering" + +msgid "Shipping Address" +msgstr "Leveransadress" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "Leveransadress - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "Kortsida (landskap)" + +msgid "Special Paper" +msgstr "Specialpapper" + +msgid "Standard" +msgstr "Standard" + +msgid "Starting Banner" +msgstr "Startbanner" + +msgid "Statement" +msgstr "Utsaga" + +msgid "Stylus Color Series" +msgstr "Stylus Color-serier" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo-serier" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "Byter protokoll" + +msgid "Tabloid" +msgstr "Tabloid" + +msgid "Tabloid (Oversize)" +msgstr "Tabloid (större)" + +msgid "Tear" +msgstr "Riv" + +msgid "Tear-Off" +msgstr "Riv-av" + +msgid "Tear-Off Adjust Position" +msgstr "Justeringsposition för avrivning" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "PPD-filen \"%s\" hittades inte." + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "PPD-filen \"%s\" kunde inte öppnas: %s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Klassnamnet får endast innehålla upp till 127 skrivbara tecken och får inte " +"innehålla blanksteg, snedstreck (/) eller fyrkantstecknet (#)." + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "" +"Attributet notify-lease-duration kan inte användas med " +"utskriftsprenumerationer." + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "Värdet för notify-user-data är för stort (%d > 63 oktetter)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"Skrivarnamnet får endast innehålla upp till 127 skrivbara tecken och får " +"inte innehålla blanksteg, snedstreck (/) eller fyrkantstecknet (#)." + +msgid "The printer or class is not shared!" +msgstr "Skrivaren eller klassen är inte delad!" + +msgid "The printer or class was not found." +msgstr "Skrivaren eller klassen hittades inte." + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "Printer-uri \"%s\" innehåller ogiltiga tecken." + +msgid "The printer-uri attribute is required!" +msgstr "Attributet printer-uri krävs!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "" +"Printer-uri måste vara i formatet \"ipp://VÄRDNAMN/classes/KLASSNAMN\"." + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "" +"Printer-uri måste vara i formatet \"ipp://VÄRDNAMN/printers/SKRIVARNAMN\"." + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "" +""Klassnamnet får endast innehålla upp till 127 skrivbara tecken och får " +"inte innehålla blanksteg, snedstreck (/), frågetecken (?) eller " +"fyrkantstecknet (#)." + +msgid "There are too many subscriptions." +msgstr "Det finns för många prenumerationer." + +msgid "Thermal Transfer Media" +msgstr "Termiska överföringsmedia" + +msgid "Title: " +msgstr "Titel: " + +msgid "Toner low." +msgstr "Toner låg." + +msgid "Too many active jobs." +msgstr "För många aktiva utskrifter." + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "För många värden för utskriftsark (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "För många värden för skrivarstatus (%d > %d)!" + +msgid "Transparency" +msgstr "Genomskinlighet" + +msgid "Tray" +msgstr "Fack" + +msgid "Tray 1" +msgstr "Fack 1" + +msgid "Tray 2" +msgstr "Fack 2" + +msgid "Tray 3" +msgstr "Fack 3" + +msgid "Tray 4" +msgstr "Fack 4" + +msgid "URI Too Long" +msgstr "För lång URI" + +msgid "US Executive" +msgstr "US Executive" + +msgid "US Fanfold" +msgstr "US Fanfold" + +msgid "US Ledger" +msgstr "US Ledger" + +msgid "US Legal" +msgstr "US Legal" + +msgid "US Legal (Oversize)" +msgstr "US Legal (större)" + +msgid "US Letter" +msgstr "US Letter" + +msgid "US Letter (Oversize)" +msgstr "US Letter (större)" + +msgid "US Letter (Small)" +msgstr "US Letter (mindre)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB-serieport #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "Kunde inte nå filen cupsd.conf:" + +msgid "Unable to add RSS subscription:" +msgstr "Kunde inte lägga till RSS-prenumeration:" + +msgid "Unable to add class:" +msgstr "Kunde inte lägga till klass:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "Kunde inte lägga till utskrift för målet \"%s\"!" + +msgid "Unable to add printer:" +msgstr "Kunde inte lägga till skrivare:" + +msgid "Unable to allocate memory for file types!" +msgstr "Kunde inte tilldela minne för filtyper!" + +msgid "Unable to cancel RSS subscription:" +msgstr "Kunde inte avbryta RSS-prenumeration:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "Kunde inte ändra attributet printer-is-shared:" + +msgid "Unable to change printer:" +msgstr "Kunde inte ändra skrivare:" + +msgid "Unable to change server settings:" +msgstr "Kunde inte ändra serverinställningar:" + +msgid "Unable to connect to host." +msgstr "Kunde inte ansluta till värd." + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "Kunde inte kopiera filer för 64-bitars CUPS-skrivardrivrutin (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "Kunde inte kopiera filer för 64-bitars Windows-skrivardrivrutin (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "Kunde inte kopiera filer för CUPS-skrivardrivrutin (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "Kunde inte kopiera PPD-fil - %s!" + +msgid "Unable to copy PPD file!" +msgstr "Kunde inte kopiera PPD-fil!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "" +"Kunde inte kopiera filer för skrivardrivrutiner till 2000 Windows (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "Kunde inte kopiera filer för Windows 9x-skrivardrivrutin (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "Kunde inte kopiera gränssnittsskript - %s!" + +msgid "Unable to create printer-uri!" +msgstr "Kunde inte skapa printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "Kunde inte skapa temporär fil:" + +msgid "Unable to delete class:" +msgstr "Kunde inte ta bort klass:" + +msgid "Unable to delete printer:" +msgstr "Kunde inte ta bort skrivare:" + +msgid "Unable to do maintenance command:" +msgstr "Kunde inte utföra underhållskommando:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "Kunde inte redigera cupsd.conf-filer större än 1 MB!" + +msgid "Unable to find destination for job!" +msgstr "Kunde inte hitta mål för utskrift!" + +msgid "Unable to find printer!\n" +msgstr "Kunde inte hitta skrivare!\n" + +msgid "Unable to get class list:" +msgstr "Kunde inte hämta klasslista:" + +msgid "Unable to get class status:" +msgstr "Kunde inte hämta klasstatus:" + +msgid "Unable to get list of printer drivers:" +msgstr "Kunde inte hämta listan med skrivardrivrutiner:" + +msgid "Unable to get printer attributes:" +msgstr "Kunde inte hämta skrivarattribut:" + +msgid "Unable to get printer list:" +msgstr "Kunde inte hämta skrivarlista:" + +msgid "Unable to get printer status:" +msgstr "Kunde inte hämta skrivarstatus:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "" +"Kunde inte installera filer för skrivardrivrutiner till 2000 Windows (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "Kunde inte installera filer för Windows 9x-skrivardrivrutin (%d)!" + +msgid "Unable to modify class:" +msgstr "Kunde inte ändra klass:" + +msgid "Unable to modify printer:" +msgstr "Kunde inte ändra skrivare:" + +msgid "Unable to move job" +msgstr "Kunde inte flytta utskrift" + +msgid "Unable to move jobs" +msgstr "Kunde inte flytta utskrifter" + +msgid "Unable to open PPD file" +msgstr "Kunde inte öppna PPD-fil" + +msgid "Unable to open PPD file:" +msgstr "Kunde inte öppna PPD-fil:" + +msgid "Unable to open cupsd.conf file:" +msgstr "Kunde inte öppna filen cupsd.conf:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "Kunde inte öppna dokument %d i utskrift %d!" + +msgid "Unable to print test page:" +msgstr "Kunde inte skriva ut testsida:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "Kunde inte köra \"%s\": %s\n" + +msgid "Unable to send command to printer driver!" +msgstr "Kunde inte skicka kommando till skrivardrivrutin!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "Kunde inte ställa in Windows-skrivardrivrutin (%d)!" + +msgid "Unable to set options:" +msgstr "Kunde inte ställa in alternativ:" + +msgid "Unable to set server default:" +msgstr "Kunde inte ställa in serverstandard:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "Kunde inte skicka upp filen cupsd.conf:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "Kunde inte använda tidigare USB-klassdrivrutin!\n" + +msgid "Unauthorized" +msgstr "Ej auktoriserad" + +msgid "Units" +msgstr "Enheter" + +msgid "Unknown" +msgstr "Okänd" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "Okänd printer-error-policy \"%s\"." + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "Okänd printer-op-policy \"%s\"." + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "Ogiltig teckenuppsättning \"%s\"!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "Ogiltig komprimering \"%s\"!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "Ogiltigt komprimeringsattribut %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "Formatet \"%s\" stöds inte!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr " Formatet ”%s” stöds inte!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "Formatet ”%s/%s” stöds inte!" + +msgid "Unsupported value type" +msgstr "Ogiltig värdetyp" + +msgid "Upgrade Required" +msgstr "Uppgradering krävs" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Användning:\n" +"\n" +" lpadmin [-h server] -d mål\n" +" lpadmin [-h server] -x mål\n" +" lpadmin [-h server] -p skrivare [-c lägg-till-klass] [-i gränssnitt] [-m " +"modell]\n" +" [-r radera-klass] [-v enhet] [-D beskrivning]\n" +" [-P ppd-fil] [-o name=value]\n" +" [-u tillåt:användare,användare] [-u neka:användare," +"användare]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Användning: %s job user title copies options [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Användning: %s job-id user title copies options [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Användning: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Användning: cupsaddsmb [alternativ] printer1 ... printerN\n" +" cupsaddsmb [alternativ] -a\n" +"\n" +"Alternativ:\n" +" -E Kryptera anslutningen till servernr\n" +" -H samba-server Använd den som heter SAMBA server\n" +" -U samba-användare Autentisera med den som heter SAMBA användare \n" +" -a Exportera alla skrivare\n" +" -h cups-server Använd den som heter CUPS server\n" +" -v Visa utförligt (visa kommandon)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Användning: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Alternativ:\n" +"\n" +" -E Aktivera kryptering\n" +" -U username Ange användarnamn\n" +" -h server[:port] Ange serveradress\n" +"\n" +" --[no-]debug-logging Slå av/på loggning vid felsökning\n" +" --[no-]remote-admin Slå av/på fjärradministrering\n" +" --[no-]remote-any Tillåt/förhindra åtkomst från Internet\n" +" --[no-]remote-printers Visa/göm fjärrskrivare\n" +" --[no-]share-printers Slå av/på skrivardelning\n" +" --[no-]user-cancel-any Tillåt/förhindra att användare kan avbryta " +"utskrifter\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Användning: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Läs upp alternativ konfigurationsfil\n" +"-f Kör i förgrunden\n" +"-F Kör i förgrunden men koppla bort\n" +"-h Visa det här användningsmeddelandet\n" +"-l Kör cupsd från launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Användning: cupstestdsc [alternativ] filnamn.ps [... filnamn.ps]\n" +" cupstestdsc [alternativ] -\n" +"\n" +"Alternativ:\n" +"\n" +" -h Visa programanvändning\n" +"\n" +" Obs: det här programmet verifierar DSC-kommentarer, men inte " +"PostScript.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Användning: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Användning: lpoptions [-h server] [-E] -d skrivare\n" +" lpoptions [-h server] [-E] [-p skrivare] -l\n" +" lpoptions [-h server] [-E] -p skrivare -o alternativ[=value] ...\n" +" lpoptions [-h server] [-E] -x skrivare\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Användning: lppasswd [-g gruppnamn]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Användning: lppasswd [-g gruppnamn] [användarnamn]\n" +" lppasswd [-g gruppnamn] -a [användarnamn]\n" +" lppasswd [-g gruppnamn] -x [användarnamn]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Användning: lpq [-P dest] [-U användarnamn] [-h värdnamn[:port]] [-l] " +"[+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Användning: ppdc [alternativ] filnamn.drv [ ... filnamnN.drv ]\n" +"Alternativ:\n" +" -D name=value Ange namngiven variabel till värde.\n" +" -I include-dir Lägg till inkluderingsfiler till sökväg.\n" +" -c catalog.po Läs upp angiven meddelandekatalog.\n" +" -d output-dir Ange utdatakatalog.\n" +" -l lang[,lang,...] Ange språk för utdata (språkversion).\n" +" -m Använd värdet för modellnamn som filnamn.\n" +" -t Testa PPD-filer istället för att skapa fler.\n" +" -v Visa utförligt (ju fler v:n desto mer detaljerat).\n" +" -z Komprimera PPD-filer med GNU zip.\n" +" --cr Avsluta rader med CR (Mac OS 9).\n" +" --crlf Avsluta rader med CR + LF (Windows).\n" +" --lf Avsluta rader med LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Användning: ppdhtml [alternativ] filnamn.drv >filnamn.html\n" +" -D name=value Ange namngiven variabel till värde.\n" +"Alternativ:\n" +" -I include-dir Lägg till inkluderingsfiler till sökväg.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Användning: ppdi [alternativ] filnamn.ppd [ ... filnamnN.ppd ]\n" +"Alternativ:\n" +" -I include-dir\n" +" -o filnamn.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Användning: ppdmerge [alternativ] filnamn.ppd [ ... filnamnN.ppd ]\n" +"Alternativ:\n" +" -o filnamn.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Användning: ppdpo [alternativ] -o filnamn.po filnamn.drv [ ... filnamnN." +"drv ]\n" +"Alternativ:\n" +" -D name=value Ange namngiven variabel till värde.\n" +" -I include-dir Lägg till inkluderingsfiler till sökväg.\n" +" -v Visa utförligt (ju fler v:n desto mer detaljerat).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Användning: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Värde använder obegränsad längd" + +msgid "VarBind uses indefinite length" +msgstr "VarBind använder obegränsad längd" + +msgid "Version uses indefinite length" +msgstr "Version använder obegränsad längd" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: Lägger endast till de första %d som hittas" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Boolesk förväntat för alternativet waiteof \"%s\"\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: Kunde inte läsa sidkanalsbegäran!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: Alternativet \"%s\" kan inte inkluderas via IncludeFeature!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: Skrivaren svarar inte\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: Skrivare skickade oväntat EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Fjärrvärden svarade inte med kommandostatusbyte efter %d sekunder!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Fjärrvärden svarade inte med kontrollstatusbyte efter %d sekunder!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "" +"WARNING: Fjärrvärden svarade inte med datastatusbyte efter %d sekunder!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI-kommando nådde en maxtidsgräns (%d), försöker igen...\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: Det här dokumentet följer inte Adobes dokumentspecifikationer och " +"kanske inte skrivs ut på rätt sätt!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: Kunde inte öppna \"%s:%s\": %s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: Kunde inte skicka begäran för PAP-status" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: Oväntat PAP-paket av typen %d\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: Okänt PAP-paket av typen %d\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: Okänt val \"%s\" för alternativet \"%s\"!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: Okänt alternativ \"%s\"!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: Formatet %s stöds inte!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: siffra förväntad för statusalternativ \"%s\"\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "" +"WARNING: kan återställas: Nätverksvärden ”%s” är upptagen, försöker igen om %" +"d sekunder...\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "Varning, inga skrivardrivrutiner för Windows 2000 är installerade!" + +msgid "Yes" +msgstr "Ja" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"Du måste öppna sidan med url:en https://%s:%d%s." + +msgid "You4 Envelope" +msgstr "You4-kuvert" + +msgid "ZPL Label Printer" +msgstr "Etikettskrivare ZPL" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "stoppad" + +msgid "canceled" +msgstr "stoppad" + +msgid "completed" +msgstr "klar" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "" +"konvertera: Använd alternativet -f till att ange den fil som ska " +"konverteras.\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced misslyckades med att starta." + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd misslyckades med att starta." + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb: Ingen PPD-fil för skrivaren \"%s\" - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl: Kunde inte ansluta till server: %s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl: Okänt alternativ \"%s\"!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl: Okänt alternativ \"-%c\"!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd: Förväntat konfigurationsfilnamn efter alternativet \"-c\"!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd: Kunde inte hämta aktuell katalog!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd: Okänt argument \"%s\" - stoppar!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd: Okänt alternativ \"%c\" - stoppar!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd: Stöd för launchd(8) inte inbyggt, kör i normalt läge.\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter: Ogiltigt dokumentnummer %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter: Ogiltigt utskrifts-ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter: Bara ett filnamn kan anges!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter: Kunde inte hämta utskriftsfil - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "" +"cupstestppd: Alternativet -q är inte kompatibelt med alternativet -v.\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "" +"cupstestppd: Alternativet -v är inte kompatibelt med alternativet -q.\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "enhet för %s/%s: %s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "enhet för %s: %s\n" + +msgid "error-index uses indefinite length" +msgstr "felindex använder obegränsad längd" + +msgid "error-status uses indefinite length" +msgstr "felstatus använder obegränsad längd" + +msgid "held" +msgstr "hålls kvar" + +msgid "help\t\tget help on commands\n" +msgstr "help\t\tfå hjälp om kommandon\n" + +msgid "idle" +msgstr "overksam" + +msgid "job-printer-uri attribute missing!" +msgstr "Attributet job-printer-uri saknas!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: Klassnamn kan endast innehålla skrivbara tecken!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: Förväntat PPD efter alternativet ”-P”!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: Förväntad allow/deny:userlist efter alternativet ”-u”!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: Förväntad klass efter alternativet ”-r”!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: Förväntat klassnamn efter alternativet ”-c”!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: Förväntad beskrivning efter alternativet ”-D”!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: Förväntad enhets-URI efter alternativet ”-v”!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: Förväntade filtyp(er) efter alternativet ”-I”!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: Förväntat värdnamn efter alternativet ”-h”!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: Förväntat gränssnitt efter alternativet ”-i”!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: Förväntad plats efter alternativet ”-L”!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: Förväntad modell efter alternativet ”-m”!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: Förväntad name=value efter alternativet ”-o”!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: Förväntad skrivare efter alternativet ”-p”!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: Förväntat skrivarnamn efter alternativet ”-d”!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: Förväntad skrivare eller klass efter alternativet ”-x”!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: Inga medlemsnamn sågs!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: Skrivaren %s är redan medlem av klassen %s.\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: Skrivaren %s är inte en medlem av klassen %s.\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: Skrivarnamn kan endast innehålla skrivbara tecken!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte lägga till en skrivare till klassen:\n" +" Du måste ange ett skrivarnamn först!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: Kunde inte ansluta till server: %s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: Kunde inte öppna PPD-fil \"%s\" - %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: Kunde inte öppna filen \"%s\": %s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ta bort en skrivare från klassen:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in PPD-filen:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in enhets-URI:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in gränssnittsskriptet eller PPD-fil:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in gränssnittsskriptet:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in skrivarbeskrivningen:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in skrivarens plats:\n" +" Du måste ange ett skrivarnamn först!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: Kunde inte ställa in skrivaralternativen:\n" +" Du måste ange ett skrivarnamn först!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: : Okänt tillåta/neka-alternativ \"%s\"!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: Okänt argument ”%s”!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: Okänt alternativ ”%c”!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: Varning - innehållstyplista ignorerades!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo: Förväntad 1284 device ID string efter--device-id!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo: Förväntat språk efter --language!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo: Förväntad tillverkning och modell efter --make-and-model!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo: Förväntad produktsträng efter --product!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo: Förväntad schemalista efter --exclude-schemes!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo: Förväntad schemalista efter --include-schemes!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo: Förväntat tidsgränsfel efter --timeout!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo: Okänt argument ”%s”!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo: Okänt alternativ ”%c”!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo: Okänt alternativ ”%s”!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove: Kunde inte ansluta till server: %s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove: Okänt argument ”%s”!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove: Okänt alternativ ”%c”!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions: Inga skrivare!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions: Kunde inte lägga till skrivare eller instans: %s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions: Kunde inte hämta PPD-fil för %s: %s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions: Kunde inte öppna PPD-fil för %s!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions: Okänd skrivare eller klass!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: Endast rot kan lägga till eller ta bort lösenord!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: Lösenordsfil upptagen!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: Lösenordsfil inte uppdaterad!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: Tyvärr, lösenord stämmer inte!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: Tyvärr, lösenord stämmer inte.\n" +"Lösenordet måste vara minst 6 tecken långt, får inte innehålla\n" +"ditt användarnamn, och måste innehålla åtminstone en bokstav och siffra.\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: Tyvärr, lösenorden stämmer inte överens!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: Kunde inte kopiera lösenordssträng: %s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: Kunde inte öppna lösenordsfil: %s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: Kunde inte skriva till lösenordsfil: %s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "" +"lppasswd: misslyckades med att säkerhetskopiera gamla lösenordsfilen: %s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: misslyckades med att byta namn på lösenordsfilen: %s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: användare \"%s\" och grupp \"%s\" finns inte.\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "lpstat: fel - miljövariabeln %s namnger icke-existerande mål \"%s\"!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "medlemmar av klassen %s:\n" + +msgid "no entries\n" +msgstr "inga objekt\n" + +msgid "no system default destination\n" +msgstr "inget systemstandardmål\n" + +msgid "notify-events not specified!" +msgstr "notify-events inte angivet!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "URI för notify-recipient-uri \"%s\" används redan!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "URI för notify-recipient-uri \"%s\" använder okänt schema!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d inte bra!" + +msgid "pending" +msgstr "väntar" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc: Lägger till inkluderingskatalog \"%s\"...\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc: Lägger till/uppdaterar UI-text från %s...\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc: Felaktigt booleskt värde (%s) på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc: Felaktigt upplösningsnamn \"%s\" på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc: Felaktigt statuslösenord %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc: Felaktig variabelersättning ($%c) på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc: Val hittades på rad %d of %s utan alternativ!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc: Dublicera #po för språk %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc: Förväntad filterdefinition på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc: Förväntat programnamn på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc: Förväntat booleskt värde på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc: Förväntad teckenkodning efter typsnitt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc: Förväntad valkod på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc: Förväntad namn-/textkod på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc: Förväntad färgordning för ColorModel på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc: Förväntad färgrymd för ColorModel på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc: Förväntad komprimering för ColorModel på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc: Förväntad regelsträng för UIConstraints på rad %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "" +"ppdc: Förväntat lösenord för drivrutinstyp efter DriverType på rad %d av %" +"s!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc: Förväntad duplextyp efter Duplex på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc: Förväntad kodning efter typsnitt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc: Förväntat filnamn efter #po %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc: Förväntat gruppnamn/-text på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc: Förväntat inkluderingsfilnamn på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc: Förväntat heltal på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc: Förväntad språkversion #po på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter filnamn på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter typsnitt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter tillverkare på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter mediestorlek på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter modellnamn på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc: Förväntat namn efter PC-filnamn på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc: Förväntat namn/text efter %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc: Förväntat namn/text efter installerbart på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc: Förväntat namn/text efter upplösning på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "" +"ppdc: Förväntat namn-/textkombination för ColorModel på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc: Förväntat alternativnamn/-text på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc: Förväntat alternativavsnitt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc: Förväntad alternativtyp på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc: Förväntat ersättningsfält efter upplösning på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc: Förväntat reellt tal på rad %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "" +"ppdc: Förväntad upplösning/medietyp efter ColorProfile på rad %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc: Förväntad upplösning/medietyp efter SimpleColorProfile på rad %d av %" +"s!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc: Förväntad väljare efter %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc: Förväntad status efter typsnitt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc: Förväntad sträng efter upphovsrätt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc: Förväntad sträng efter version på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc: Förväntade två alternativnamn på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc: Förväntat värde efter %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc: Förväntad version efter typsnitt på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc: Ogiltigt #include/#po filnamn \"%s\"!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc: Ogiltig kostnad för filter på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc: Ogiltig tom MIME-typ för filter på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc: Ogiltigt tomt programnamn för filter på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ogiltigt alternativavsnitt \"%s\" på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Ogiltig alternativtyp \"%s\" på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc: Läser in fil med drivrutinsinformation \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc: Läser in meddelanden för språk \"%s\"...\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc: Läser in meddelanden från \"%s\"...\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc: Saknad #endif i slutet av \"%s\"!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc: Saknad #if på rad %d av %s!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc: Ingen meddelandekatalog angiven för språkversionen %s!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc: Alternativ %s definieras om med en annan typ på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc: Alternativregel måste *name på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc: För många nästlade #if”s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc: Kunde inte skapa PPD-fil \"%s\" - %s.\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc: Kunde inte skapa utdatakatalog %s: %s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc: Kunde inte skapa utdatarör: %s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc: Kunde inte köra cupstestppd: %s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc: Kunde inte hitta #po fil %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc: Kunde inte hitta inkluderingsfil \"%s\" på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc: Kunde inte hitta lokalisering för \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc: Kunde inte läsa in lokaliseringsfil för \"%s\" - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc: Odefinierad variabel (%s) på rad %d av %s.\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc: Okänd drivrutinstyp %s på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc: Okänd duplextyp \"%s\" på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc: Okänd mediestorlek \"%s\" på rad %d of %s!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc: Okänd symbol \"%s\" sågs på rad %d av %s!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "ppdc: Okända avslutande tecken i reellt tal \"%s\" på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc: Oavslutad sträng börjar med %c på rad %d av %s!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc: Skriver %s...\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc: Skriver PPD-filer till katalogen \"%s\"...\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge: Felaktig LanguageVersion \"%s\" i %s!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge: Ignorerar PPD-fil %s...\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge: Kan inte säkerhetskopiera %s till %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "skrivare %s avaktiverad sedan %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "skrivare %s är overksam. aktiverad sedan %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "skrivare %s skriver ut %s-%d. avaktiverad sedan %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "skrivare %s/%s avaktiverad sedan %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "skrivare %s/%s är overksam. aktiverad sedan %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "skrivare %s/%s skriver ut %s-%d. aktiverad sedan %s\n" + +msgid "processing" +msgstr "bearbetar" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "ID för begäran är %s-%d (%d fil(er))\n" + +msgid "request-id uses indefinite length" +msgstr "order-ID använder obegränsad längd" + +msgid "scheduler is not running\n" +msgstr "schemaläggare körs inte\n" + +msgid "scheduler is running\n" +msgstr "schemaläggare körs\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "status för %s misslyckades: %s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "status\t\tvisa status för demon och kö\n" + +msgid "stopped" +msgstr "stoppad" + +#, c-format +msgid "system default destination: %s\n" +msgstr "systemstandardmål: %s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "systemstandardmål: %s/%s\n" + +msgid "unknown" +msgstr "okänd" + +msgid "untitled" +msgstr "namnlös" + +msgid "variable-bindings uses indefinite length" +msgstr "variabelbindningar använder obegränsad längd" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " VARN Saknad APDialogExtension-fil ”%s”\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " VARN Saknad APPrinterIconPath-fil ”%s”\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s: Kan inte öppna %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s: Kan inte öppna %s - %s på rad %d.\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI gråskala" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "" +#~ "ERROR: Saknad enhets-URI i kommandoraden och ingen miljövariabel för " +#~ "DEVICE_URI!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: Kunde inte skapa temporär fil - %s.\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: Kunde inte skapa temporär fil: %s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: Kunde inte öppna temporär fil" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops-filter kraschade på signal %d!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops-filter avslutades med status %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "Okänt skrivarfel (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Användning: konvertera [ alternativ ]\n" +#~ "\n" +#~ "Alternativ:\n" +#~ "\n" +#~ " -f filnamn Ange fil att konvertera (annars standard in)\n" +#~ " -o filnamn Ange fil att generera (annars standard ut)\n" +#~ " -i MIME/typ Ange MIME-typ för indata (annars automatiskt)\n" +#~ " -j MIME/typ Ange MIME-typ för utdata (annars program/pdf)\n" +#~ " -P filnamn.ppd Ange PPD-fil\n" +#~ " -a ”name=value ...” Ange alternativ\n" +#~ " -U användarnamn Ange användarnamn för utskrift\n" +#~ " -J titel Ange titel\n" +#~ " -c kopior Ange antal kopior\n" +#~ " -u Radera PPD-filen när det är klart\n" +#~ " -D Radera indatafilen när det är klart\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Användning: cupsfilter -m MIME/typ [ alternativ ] filnamn\n" +#~ "\n" +#~ "Alternativ:\n" +#~ "\n" +#~ " -c cupsd.conf Ange cupsd.conf-fil för användning\n" +#~ " -j utskrifts-ID[,N] Filtrera fil N från angiven utskrift (fil 1 är " +#~ "förvald)\n" +#~ " -n kopior Ange antal kopior\n" +#~ " -o name=value Ange alternativ)\n" +#~ " -p filnamn.ppd Ange PPD-fil\n" +#~ " -t titel Ange titel\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Användning: cupstestppd [alternativ] filnamn1.ppd[.gz] [... filnamnN.ppd[." +#~ "gz]]\n" +#~ " program | cupstestppd [alternativ] -\n" +#~ "\n" +#~ "Alternativ:\n" +#~ "\n" +#~ " -R root-directory Ange alternativ rot\n" +#~ " -W {alla,ingen,regler,standard,duplex,filter,översättningar}\n" +#~ " Skicka varningar istället för fel\n" +#~ " -q Kör ljudlöst\n" +#~ " -r Använd öppet läge\n" +#~ " -v Visa mindre utförligt\n" +#~ " -vv Visa mycket utförligt\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter: Kunde inte skapa temporär fil: %s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: Kunde inte skapa tempfil - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: Kunde inte skapa tempfil: %s\n" diff --git a/locale/cups_zh.po b/locale/cups_zh.po new file mode 100644 index 0000000000..bc5696f535 --- /dev/null +++ b/locale/cups_zh.po @@ -0,0 +1,5586 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(全部)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(无)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d 个条目\n" + +msgid "\tAfter fault: continue\n" +msgstr "\t发生故障后:继续\n" + +msgid "\tAlerts:" +msgstr "\t警报:" + +msgid "\tBanner required\n" +msgstr "\t需要标题\n" + +msgid "\tCharset sets:\n" +msgstr "\t字符集集合:\n" + +msgid "\tConnection: direct\n" +msgstr "\t连接:直接\n" + +msgid "\tConnection: remote\n" +msgstr "\t连接:远程\n" + +msgid "\tDefault page size:\n" +msgstr "\t默认页面大小:\n" + +msgid "\tDefault pitch:\n" +msgstr "\t默认间距:\n" + +msgid "\tDefault port settings:\n" +msgstr "\t默认端口设置:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\t描述:%s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\t已装载的表格:\n" +"\t内容类型:任何\n" +"\t打印机类型:未知\n" + +msgid "\tForms allowed:\n" +msgstr "\t允许的形式:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\t接口:%s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\t接口:%s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\t接口:%s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\t位置:%s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\t发生故障时:无警报\n" + +msgid "\tUsers allowed:\n" +msgstr "\t允许的用户:\n" + +msgid "\tUsers denied:\n" +msgstr "\t拒绝的用户:\n" + +msgid "\tdaemon present\n" +msgstr "\t监控程序已存在\n" + +msgid "\tno entries\n" +msgstr "\t无条目\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\t打印机在设备 '%s' 上,速度 -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\t打印已停用\n" + +msgid "\tprinting is enabled\n" +msgstr "\t打印已启用\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\t已排队进行%s\n" + +msgid "\tqueuing is disabled\n" +msgstr "\t队列已停用\n" + +msgid "\tqueuing is enabled\n" +msgstr "\t队列已启用\n" + +msgid "\treason unknown\n" +msgstr "\t原因未知\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" 详细的一致性测试结果\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " REF: 页 15,节 3.1。\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " REF: 页 15,节 3.2。\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " REF: 页 19,节 3.3。\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " REF: 页 20,节 3.4。\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " REF: 页 27,节 3.5。\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " REF: 页 42,节 5.2。\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " REF: 页 16-17,节 3.2。\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " REF: 页 42-45,节 5.2。\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " REF: 页 45-46,节 5.2。\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " REF: 页 48-49,节 5.2。\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " REF: 页 52-54,节 5.2。\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f 字节\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " 通过 Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " 通过 DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " 通过 DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " 通过 FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " 通过 FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " 通过 LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " 通过 LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " 通过 Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " 通过 ModelName\n" + +msgid " PASS NickName\n" +msgstr " 通过 NickName\n" + +msgid " PASS PCFileName\n" +msgstr " 通过 PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " 通过 PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " 通过 PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " 通过 PageSize\n" + +msgid " PASS Product\n" +msgstr " 通过 Product\n" + +msgid " PASS ShortNickName\n" +msgstr " 通过 ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" WARN “%s %s”与“%s %s”有冲突\n" +" (constraint=\"%s %s %s %s\")\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " WARN %s 没有相应的选项!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" WARN %s 与 %s 共享一个公共前缀\n" +" REF: 第 15 页,第 3.2 节。\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " WARN 默认选择有冲突!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" WARN Duplex 选项关键词 %s 可能无法像期望那样工作,且应当命名为 " +"Duplex!\n" +" REF: 页 122,节 5.17。\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr " WARN 文件混有 CR、LF 和 CR LF 行尾!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" WARN PPD 4.3 规范要求 LanguageEncoding。\n" +" REF: 页 56-57,节 5.3。\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " WARN 行 %d 仅包含空白!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" WARN PPD 4.3 规范要求 Manufacturer。\n" +" REF: 第 58-59 页,第 5.3 节。\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" WARN 非 Windows PPD 文件应当仅使用以 LF 结尾的行,而不是以 CR LF " +"结尾的行!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" WARN 过时的 PPD 版本 %.1f!\n" +" REF: 页 42,节 5.2。\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" WARN PCFileName 长于 8.3,不符合 PPD 规范。\n" +" REF: 页 61-62,节 5.3。\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN 协议含有 PJL,但 JCL 属性未设定。\n" +" REF: 页 78-79,节 5.7。\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" WARN 协议含有 PJL 和 BCP;还期待 TBCP。\n" +" REF: 页 78-79,节 5.7。\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" WARN PPD 4.3 规范要求 ShortNickName。\n" +" REF: 页 64-65,节 5.3。\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s 不存在!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s 错误的 %s 选择 %s!\n" +" REF: 第 122 页,第 5.17 节。\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s 错误的 UTF-8“%s”转换字符串(用于选项“%s”)!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s 错误的 UTF-8“%s”转换字符串(用于选项“%s”),选择“%s”!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s 错误的 cupsFilter 值“%s”!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s 错误的 cupsICCProfile %s!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s 错误的 cupsPreFilter 值“%s”!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 错误的 cupsUIConstraints %s:“%s”!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s 错误的语言“%s”!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s 空的 cupsUIConstraints %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s 缺少“%s”转换字符串(用于选项“%s”)!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s 缺少“%s”转换字符串(用于选项“%s”),选择“%s”!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s 缺少选择 *%s %s(在 UIConstraints“*%s %s *%s %s”中)!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 缺少选择 *%s %s(在 cupsUIConstraints“%s”中):“%s”!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s 缺少 cupsFilter 文件“%s”\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s 缺少 cupsICCProfile 文件“%s”!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s 缺少 cupsPreFilter 文件“%s”\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s 缺少 cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s 缺少选项 %s(在 UIConstraints“*%s %s *%s %s”中)!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 缺少选项 %s(在 cupsUIConstraints“%s”中):“%s”!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s 文件中不包括基本转换“%s”!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s 所请求的 %s 没有定义选择 None!\n" +" REF: 第 122 页,第 5.17 节。\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s 散列值与 %s 冲突!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s 导致了一个循环!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr " **失败** %s 选择名称 %s 和 %s 只会根据情况而不同!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **失败** %s 必须是 1284DeviceID!\n" +" REF: 页 72,节 5.5。\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **失败** 错误的 Default%s %s\n" +" REF: 第 40 页,第 4.5 节。\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失败** 错误的 DefaultImageableArea %s!\n" +" REF: 页 102,节 5.15。\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失败** 错误的 DefaultPaperDimension %s!\n" +" REF: 页 103,节 5.15。\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **失败** 文件中错误的 JobPatchFile 属性\n" +" REF: 第 24 页,第 3.4 节。\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **失败** 错误的 Manufacturer(应该是“HP”)\n" +" REF: 第 211 页,表 D.1。\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **失败** 错误的 Manufacturer(应该是“Oki”)\n" +" REF: 第 211 页,表 D.1。\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **失败** 错误的 ModelName -“%c”,字符串中不允许。\n" +" REF: 页 59-60,节 5.3。\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **失败** 错误的 PSVersion - 不是“(string) int”。\n" +" REF: 页 62-64,节 5.3。\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **失败** 错误的 Product - 不是“(string) int”。\n" +" REF: 页 62,节 5.3。\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **失败** 错误的 ShortNickName - 多于 31 个字符。\n" +" REF: 页 64-65,节 5.3。\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **失败** 错误的 %s 选择 %s!\n" +" REF: 第 84 页,第 5.9 节。\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失败** 错误的 FileVersion“%s”\n" +" REF: 第 56 页,第 5.3 节。\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失败** 错误的 FormatVersion“%s”\n" +" REF: 第 56 页,第 5.3 节。\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **失败** 错误的 LanguageEncoding %s - 必须是 ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **失败** 错误的 LanguageVersion %s - 必须是 English!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **失败** 不能解释默认选项编码:%s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr " **失败** 选项 %s 选择 %s 的默认转换字符串含有 8 位字符!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr " **失败** 选项 %s 的默认转换字符串含有 8 位字符!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr " **失败** 组别名称 %s 和 %s 只会根据情况而不同!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **失败** 多次出现 %s 选择名称 %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr " **失败** 选项名称 %s 和 %s 只会根据情况而不同!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **失败** 要求 Default%s\n" +" REF: 页 40,节 4.5。\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失败** 要求 DefaultImageableArea\n" +" REF: 页 102,节 5.15。\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失败** 要求 DefaultPaperDimension\n" +" REF: 页 103,节 5.15。\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失败** 要求 FileVersion\n" +" REF: 页 56,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失败** 要求 FormatVersion\n" +" REF: 页 56,节 5.3。\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失败** 要求 PageSize %s 的 ImageableArea\n" +" REF: 第 41 页,第 5 节。\n" +" REF: 页 102,节 5.15。\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **失败** 要求 LanguageEncoding\n" +" REF: 页 56-57,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **失败** 要求 LanguageVersion\n" +" REF: 页 57-58,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **失败** 要求 Manufacturer\n" +" REF: 页 58-59,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **失败** 要求 ModelName\n" +" REF: 页 59-60,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **失败** 要求 NickName\n" +" REF: 页 60,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **失败** 要求 PCFileName\n" +" REF: 页 61-62,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **失败** 要求 PSVersion\n" +" REF: 页 62-64,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **失败** 要求 PageRegion\n" +" REF: 页 100,节 5.14。\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **失败** 要求 PageSize\n" +" REF: 第 41 页,第 5 节。\n" +" REF: 页 99,节 5.14。\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **失败** 要求 PageSize\n" +" REF: 页 99-100,节 5.14。\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失败** 要求 PageSize %s 的 PaperDimension\n" +" REF: 第 41 页,第 5 节。\n" +" REF: 页 103,节 5.15。\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **失败** 要求 Product\n" +" REF: 页 62,节 5.3。\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **失败** 要求 ShortNickName\n" +" REF: 页 64-65,节 5.3。\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " 发现 %d 个错误\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" 错误的 %%%%BoundingBox:在行 %d!\n" +" REF: 页 39,%%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" 错误的 %%%%Page:在行 %d!\n" +" REF: 页 53,%%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" 错误的 %%%%Pages:在行 %d!\n" +" REF: 页 43,%%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" 行 %d 多于 255 个字符 (%d)!\n" +" REF: 页 25,行长度\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" 首行缺少 %!PS-Adobe-3.0!\n" +" REF: 页 17,3.1 符合文稿\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" 缺少 %%EndComments 批注!\n" +" REF: 页 41,%%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" 缺少或错误的 %%%%BoundingBox:批注!\n" +" REF: 页 39,%%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" 缺少或错误的 %%Page:批注!\n" +" REF: 页 53,%%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" 缺少或错误的 %%Pages:批注!\n" +" REF: 页 43,%%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " 未发现错误\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " 发现 %d 行超过 255 个字符!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " 太多 %%BeginDocument 批注!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " 太多 %%EndDocument 批注!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " WARNING: 文件含有二进制数据!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " WARNING: 文件中没有 %%EndComments 批注!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " WARNING: 文件中的 DSC 版本 %.1f 过时!\n" + +msgid " FAIL\n" +msgstr " 失败\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" 失败\n" +" **失败** 无法打开 PPD 文件 - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" 失败\n" +" **失败** 无法打开 PPD 文件 - %s 在第 %d 行。\n" + +msgid " PASS\n" +msgstr " 通过\n" + +msgid "#10 Envelope" +msgstr "10 号信封" + +msgid "#11 Envelope" +msgstr "11 号信封" + +msgid "#12 Envelope" +msgstr "12 号信封" + +msgid "#14 Envelope" +msgstr "14 号信封" + +msgid "#9 Envelope" +msgstr "9 号信封" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f 字节\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f 字节\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f 亳米" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f 至 %.0f x %.0f 亳米" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f 英寸" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f 至 %.2f x %.2f 英寸" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s 正在接受请求,时间从 %s\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "%s 不能更改。" + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s 未被 lpc 的 CUPS 版本实施。\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s 未准备就绪\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s 准备就绪\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s 已准备就绪,正在打印\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s 没有在接受请求,时间从 %s -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "%s 不被支持!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s 正在接受请求,时间从 %s\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s 没有在接受请求,时间从 %s -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s:%-33.33s [作业 %d 本地主机]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s:%s 失败:%s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s:不知道要做什么!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s:错误 - %s 个环境变量名称不存在目的位置“%s”!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s:错误 - 错误的作业 ID!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s:错误 - 不能同时打印文件和更改作业!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "%s:错误 - 如果文件或作业 ID 已提供,则不能从 stdin 打印!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s:错误 - '-S' 选项后期望字符集!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s:错误 - '-T' 选项后期望内容类型!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s:错误 - '-n' 选项后期望份数!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s:错误 - '-#' 选项后期望份数!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s:错误 - '-P' 选项后期望目的位置!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s:错误 - '-b' 选项后期望目的位置!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s:错误 - '-d' 选项后期望目的位置!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s:错误 - '-f' 选项后期望形式!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s:错误 - '-H' 选项后期望保留名称!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s:错误 - '-H' 选项后期望主机名称!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s:错误 - '-H' 选项后期望主机名称!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s:错误 - '-y' 选项后期望模式列表!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s:错误 - '-%c' 选项后期望名称!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s:错误 - '-o' 选项后期望选项字符串!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s:错误 - '-P' 选项后期望页面列表!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s:错误 - '-%c' 选项后期望优先级!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s:错误 - '-r' 选项后期望原因文本!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s:错误 - '-t' 选项后期望标题!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s:错误 - '-U' 选项后期望用户名称!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s:错误 - '-U' 选项后期望用户名称!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s:错误 - '-%c' 选项后期望值!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "%s:错误 -“-W”选项后需要“completed”、“not-completed”或“all”\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s:错误 - 没有默认目的位置。\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s:错误 - 优先级必须在 1 到 100 之间。\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s:错误 - 调度程序无响应!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s:错误 - 太多文件 -“%s”\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s:错误 - 无法访问“%s”- %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s:错误 - 无法从 stdin 排队 - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s:错误 - 未知目的位置“%s”!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s:错误 - 未知目的位置“%s/%s”!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s:错误 - 未知选项 '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s:错误 - 未知选项“%s”!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s:'-i' 选项后期望作业 ID!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s:滤镜“%s”不可用:%s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s:列表“%s”中的目的位置名称无效!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s:无效的滤镜字符串“%s”\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s:'-H restart' 之前需要作业 ID ('-i jobid')!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s:无滤镜可从 %s/%s 转换成 %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s:操作失败:%s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s:对不起,未编译加密支持!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s:无法连接到服务器\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s:无法联系服务器!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s:无法确定“%s”的 MIME 类型!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s:无法打开 %s:%s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s:无法打开 PPD 文件:%s 在第 %d 行\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s:无法从“%s”或“%s”读取 MIME 数据库!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s:未知目的位置“%s”!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s:未知目的 MIME 类型 %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s:未知选项 '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s:未知的源 MIME 类型 %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "%s:警告 - “%c”格式修饰符不支持 - 输出可能不正确!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s:警告 - 字符集选项被忽略!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s:警告 - 内容类型选项被忽略!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s:警告 - 形式选项被忽略!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s:警告 - 模式选项被忽略!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s:错误 - %s 个环境变量名称不存在目的位置“%s”!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s:错误 - '-o' 选项后期望 option=value!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s:错误 - 没有默认目的位置。\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 英寸/秒" + +msgid "1.25x0.25\"" +msgstr "1.25x0.25 英寸" + +msgid "1.25x2.25\"" +msgstr "1.25x2.25 英寸" + +msgid "1.5 inch/sec." +msgstr "1.5 英寸/秒" + +msgid "1.50x0.25\"" +msgstr "1.50x0.25 英寸" + +msgid "1.50x0.50\"" +msgstr "1.50x0.50 英寸" + +msgid "1.50x1.00\"" +msgstr "1.50x1.00 英寸" + +msgid "1.50x2.00\"" +msgstr "1.50x2.00 英寸" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 英寸/秒" + +msgid "10 x 11\"" +msgstr "10 x 11 英寸" + +msgid "10 x 13\"" +msgstr "10 x 13 英寸" + +msgid "10 x 14\"" +msgstr "10 x 14 英寸" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 毫米/秒" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 英寸/秒" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 英寸/秒" + +msgid "12 x 11\"" +msgstr "12 x 11 英寸" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 毫米/秒" + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 毫米/秒" + +msgid "15 x 11\"" +msgstr "15 x 11 英寸" + +msgid "150 mm/sec." +msgstr "150 毫米/秒" + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 英寸/秒" + +msgid "2-Sided Printing" +msgstr "双面打印" + +msgid "2.00x0.37\"" +msgstr "2.00x0.37 英寸" + +msgid "2.00x0.50\"" +msgstr "2.00x0.50 英寸" + +msgid "2.00x1.00\"" +msgstr "2.00x1.00 英寸" + +msgid "2.00x1.25\"" +msgstr "2.00x1.25 英寸" + +msgid "2.00x2.00\"" +msgstr "2.00x2.00 英寸" + +msgid "2.00x3.00\"" +msgstr "2.00x3.00 英寸" + +msgid "2.00x4.00\"" +msgstr "2.00x4.00 英寸" + +msgid "2.00x5.50\"" +msgstr "2.00x5.50 英寸" + +msgid "2.25x0.50\"" +msgstr "2.25x0.50 英寸" + +msgid "2.25x1.25\"" +msgstr "2.25x1.25 英寸" + +msgid "2.25x4.00\"" +msgstr "2.25x4.00 英寸" + +msgid "2.25x5.50\"" +msgstr "2.25x5.50 英寸" + +msgid "2.38x5.50\"" +msgstr "2.38x5.50 英寸" + +msgid "2.5 inches/sec." +msgstr "2.5 英寸/秒" + +msgid "2.50x1.00\"" +msgstr "2.50x1.00 英寸" + +msgid "2.50x2.00\"" +msgstr "2.50x2.00 英寸" + +msgid "2.75x1.25\"" +msgstr "2.75x1.25 英寸" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1 英寸" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 毫米/秒" + +msgid "200 mm/sec." +msgstr "200 毫米/秒" + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24 针系列" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 毫米/秒" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 英寸/秒" + +msgid "3.00x1.00\"" +msgstr "3.00x1.00 英寸" + +msgid "3.00x1.25\"" +msgstr "3.00x1.25 英寸" + +msgid "3.00x2.00\"" +msgstr "3.00x2.00 英寸" + +msgid "3.00x3.00\"" +msgstr "3.00x3.00 英寸" + +msgid "3.00x5.00\"" +msgstr "3.00x5.00 英寸" + +msgid "3.25x2.00\"" +msgstr "3.25x2.00 英寸" + +msgid "3.25x5.00\"" +msgstr "3.25x5.00 英寸" + +msgid "3.25x5.50\"" +msgstr "3.25x5.50 英寸" + +msgid "3.25x5.83\"" +msgstr "3.25x5.83 英寸" + +msgid "3.25x7.83\"" +msgstr "3.25x7.83 英寸" + +msgid "3.5\" Disk" +msgstr "3.5 英寸磁盘" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3.5 英寸磁盘 - 2 1/8 x 2 3/4 英寸" + +msgid "3.50x1.00\"" +msgstr "3.50x1.00 英寸" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 毫米/秒" + +msgid "300 mm/sec." +msgstr "300 毫米/秒" + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 英寸/秒" + +msgid "4.00x1.00\"" +msgstr "4.00x1.00 英寸" + +msgid "4.00x13.00\"" +msgstr "4.00x13.00 英寸" + +msgid "4.00x2.00\"" +msgstr "4.00x2.00 英寸" + +msgid "4.00x2.50\"" +msgstr "4.00x2.50 英寸" + +msgid "4.00x3.00\"" +msgstr "4.00x3.00 英寸" + +msgid "4.00x4.00\"" +msgstr "4.00x4.00 英寸" + +msgid "4.00x5.00\"" +msgstr "4.00x5.00 英寸" + +msgid "4.00x6.00\"" +msgstr "4.00x6.00 英寸" + +msgid "4.00x6.50\"" +msgstr "4.00x6.50 英寸" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 毫米/秒" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 英寸/秒" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 英寸/秒" + +msgid "6.00x1.00\"" +msgstr "6.00x1.00 英寸" + +msgid "6.00x2.00\"" +msgstr "6.00x2.00 英寸" + +msgid "6.00x3.00\"" +msgstr "6.00x3.00 英寸" + +msgid "6.00x4.00\"" +msgstr "6.00x4.00 英寸" + +msgid "6.00x5.00\"" +msgstr "6.00x5.00 英寸" + +msgid "6.00x6.00\"" +msgstr "6.00x6.00 英寸" + +msgid "6.00x6.50\"" +msgstr "6.00x6.50 英寸" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 毫米/秒" + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 英寸/秒" + +msgid "7 x 9\"" +msgstr "7 x 9 英寸" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 英寸/秒" + +msgid "8 x 10\"" +msgstr "8 x 10 英寸" + +msgid "8.00x1.00\"" +msgstr "8.00x1.00 英寸" + +msgid "8.00x2.00\"" +msgstr "8.00x2.00 英寸" + +msgid "8.00x3.00\"" +msgstr "8.00x3.00 英寸" + +msgid "8.00x4.00\"" +msgstr "8.00x4.00 英寸" + +msgid "8.00x5.00\"" +msgstr "8.00x5.00 英寸" + +msgid "8.00x6.00\"" +msgstr "8.00x6.00 英寸" + +msgid "8.00x6.50\"" +msgstr "8.00x6.50 英寸" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 毫米/秒" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 英寸/秒" + +msgid "9 x 11\"" +msgstr "9 x 11 英寸" + +msgid "9 x 12\"" +msgstr "9 x 12 英寸" + +msgid "9-Pin Series" +msgstr "9 针系列" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?未知的无效帮助命令\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "导出打印机驱动程序需要 Samba 密码!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "导出打印机驱动程序需要 Samba 用户名称!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "名称为“%s”的类已经存在!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "名称为“%s”的打印机已经存在!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3(大号)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4(大号)" + +msgid "A4 (Small)" +msgstr "A4(小号)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5(大号)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "接受作业" + +msgid "Accepted" +msgstr "已接受" + +msgid "Add Class" +msgstr "添加类" + +msgid "Add Printer" +msgstr "添加打印机" + +msgid "Add RSS Subscription" +msgstr "添加 RSS 订阅" + +msgid "Address" +msgstr "地址" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "地址 - 1 1/8 x 3 1/2 英寸" + +msgid "Administration" +msgstr "管理" + +msgid "Always" +msgstr "始终" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "涂敷器" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "尝试将 %s 打印机状态设定为错误值 %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "属性组顺序混乱 (%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "错误的 NULL dests 指针" + +msgid "Bad OpenGroup" +msgstr "错误的 OpenGroup" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "错误的 OpenUI/JCLOpenUI" + +msgid "Bad OrderDependency" +msgstr "错误的 OrderDependency" + +msgid "Bad Request" +msgstr "错误的请求" + +msgid "Bad SNMP version number" +msgstr "错误的 SNMP 版本号" + +msgid "Bad UIConstraints" +msgstr "错误的 UIConstraints" + +#, c-format +msgid "Bad copies value %d." +msgstr "错误的份数值 %d。" + +msgid "Bad custom parameter" +msgstr "错误的自定参数" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "错误的设备 URI“%s”!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "错误的 device-uri“%s”!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "错误的 device-uri 方案“%s”!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "错误的 document-format“%s”!" + +msgid "Bad filename buffer!" +msgstr "错误的文件名称缓冲区!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "错误的字体属性:%s\n" + +msgid "Bad job-priority value!" +msgstr "错误的 job-priority 值!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "错误的 job-sheets 值“%s”!" + +msgid "Bad job-sheets value type!" +msgstr "错误的 job-sheets 值类型!" + +msgid "Bad job-state value!" +msgstr "错误的 job-state 值!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "错误的 job-uri 属性“%s”!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "错误的 notify-pull-method“%s”!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "错误的 notify-recipient-uri URI“%s”!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "错误的 number-up 值 %d。" + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "行 %d 中错误的 option + choice!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "错误的 page-ranges 值 %d-%d。" + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "错误的 port-monitor“%s”!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "错误的 printer-state 值 %d!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "错误的请求版本号 %d.%d!" + +msgid "Bad subscription ID!" +msgstr "错误的订阅 ID!" + +msgid "Banners" +msgstr "标题" + +msgid "Billing Information: " +msgstr "帐单信息:" + +msgid "Bond Paper" +msgstr "半透明纸" + +msgid "C0 Envelope" +msgstr "C0 信封" + +msgid "C1 Envelope" +msgstr "C1 信封" + +msgid "C2 Envelope" +msgstr "C2 信封" + +msgid "C3 Envelope" +msgstr "C3 信封" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4 信封" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5 信封" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6 信封" + +msgid "C65 Envelope" +msgstr "C65 信封" + +msgid "C7 Envelope" +msgstr "C7 信封" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL 标签打印机" + +msgid "Cancel RSS Subscription" +msgstr "取消 RSS 订阅" + +msgid "Change Settings" +msgstr "更改设置" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "字符集“%s”不被支持!" + +msgid "Chou3 Envelope" +msgstr "Chou3 信封" + +msgid "Chou4 Envelope" +msgstr "Chou4 信封" + +msgid "Classes" +msgstr "类" + +msgid "Clean Print Heads" +msgstr "清洁打印头" + +msgid "Color" +msgstr "彩色" + +msgid "Color Mode" +msgstr "彩色模式" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"命令可能是缩写。命令是:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "团体名称使用不定长度" + +msgid "Continue" +msgstr "继续" + +msgid "Continuous" +msgstr "连续" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "未能扫描类型“%s”!" + +msgid "Cover open." +msgstr "机盖打开。" + +msgid "Created" +msgstr "创建" + +msgid "Created On: " +msgstr "创建于:" + +msgid "Custom" +msgstr "自定" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "切纸" + +msgid "Cutter" +msgstr "切纸器" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL 信封" + +msgid "Dark" +msgstr "暗" + +msgid "Darkness" +msgstr "暗" + +msgid "Delete Class" +msgstr "删除类" + +msgid "Delete Printer" +msgstr "删除打印机" + +msgid "Description: " +msgstr "描述:" + +msgid "DeskJet Series" +msgstr "DeskJet 系列" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "目的位置“%s”没有接受作业。" + +msgid "Developer almost empty." +msgstr "显影剂差不多快要空了。" + +msgid "Developer empty!" +msgstr "显影剂已空!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"设备:uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" + +msgid "Direct Thermal Media" +msgstr "热敏介质" + +msgid "Disabled" +msgstr "停用" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "找不到文稿 %d(在作业 %d 中)。" + +msgid "Door open." +msgstr "打印机门打开。" + +msgid "Double Postcard" +msgstr "双面明信片" + +msgid "Driver Name: " +msgstr "驱动程序名称:" + +msgid "Driver Version: " +msgstr "驱动程序版本:" + +msgid "Duplexer" +msgstr "双面打印器" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: 无法为页面信息分配内存:%s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: 无法为页面序列分配内存:%s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1 标签打印机" + +msgid "EPL2 Label Printer" +msgstr "EPL2 标签打印机" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: 错误的 %%BoundingBox:发现批注!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: 错误的 %%IncludeFeature:批注!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: 错误的 %%Page:文件中的批注!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: 错误的 %%PageBoundingBox:文件中的批注!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: 错误的 SCSI 设备文件“%s”!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: 错误的字符集文件 %s\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: 错误的字符集类型 %s\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: 错误的列值 %d!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: 错误的 cpi 值 %f!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: 错误的字体描述行:%s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: 错误的 lpi 值 %f!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: 错误的页面设置!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: 错误的文本方向 %s\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: 错误的文本宽度 %s\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: 目的位置打印机不存在!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: 重复的 %%BoundingBox:发现批注!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: 重复的 %%Pages!发现批注!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: 空打印文件!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: 发送 PAPSendData 请求时发生错误 %d:%s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: %2$s 的第 %1$d 行期望引号字符串!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: 致命的 USB 错误!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: 发现无效的 HP-GL/2 命令,无法打印文件!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: 缺少 %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: 缺少 %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: 标题文件的第 %d 行缺少值!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "ERROR: %2$s 的第 %1$d 行上的任何转换字符串前面均需要有 msgid 行!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: 无 %%BoundingBox:标头中的批注!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: 无 %%Pages:标头中的批注!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "ERROR: 在 argv[0] 或 DEVICE_URI 环境变量中找不到设备 URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: 字符集文件 %s 中没有字体\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: 找不到页面!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: 缺纸!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: PRINTER 环境变量未定义!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: 打印文件不被接受 (%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: 打印机没有响应\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: 打印机没有响应!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: 打印机发送了意外的 EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: 远程主机不接受控制文件 (%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: 远程主机不接受数据文件 (%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: 将数据发送到打印机时发生了超时错误\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: 无法将文件 %d 添加到作业:%s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: 无法取消作业 %d:%s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: 无法拷贝 PDF 文件" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: 无法创建套接字" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: 无法创建临时的压缩打印文件:%s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: 无法创建临时文件" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: 无法执行 pictwpstops:%s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: 无法执行 gs 程序" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: 无法执行 pdftops 程序" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: 无法 fork pictwpstops:%s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: 无法获得 PAP 请求" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: 无法获得 PAP 响应" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: 无法获得用于打印机“%s”的 PPD 文件 - %s。\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: 无法获得默认的 AppleTalk 区域" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: 无法获得作业 %d 属性 (%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: 无法获得打印机状态 (%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: 找不到打印机 '%s' 的位置!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: 无法查找 PAP 响应" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: 无法查找 AppleTalk 打印机" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: 无法确定 AppleTalk 地址" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: 无法打开“%s”- %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: 无法打开 %s:%s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: 无法打开标题文件“%s” - %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: 无法打开设备文件“%s”:%s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: 无法打开文件“%s”- %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: 无法打开文件“%s”:%s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: 无法打开图像文件进行打印!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: 无法打开打印文件“%s”:%s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: 无法打开打印文件 %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: 无法打开打印文件 %s:%s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: 无法打开临时的压缩打印文件:%s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: 无法打印 %d 个文本栏!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: 无法打印 %dx%d 页文本页面!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: 无法读取打印数据" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: 无法读取打印数据!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: 无法保留端口" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: 无法搜寻到文件中的偏移 %ld - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: 无法搜寻到文件中的偏移 %lld - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: 无法发送 LPD 命令" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: 无法发送 PAP 反馈请求" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: 无法发送初始 PAP 发送数据请求" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: 无法发送打印数据 (%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: 无法发送打印数据!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: 无法将打印文件发送到打印机" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: 无法将尾空发送到打印机" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: 无法等待 pictwpstops:%s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: 无法将 %d 字节写入“%s”:%s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: 无法将 %d 字节写入打印机!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: 无法写入控制文件" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: 无法写入打印数据" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: 无法写入打印数据:%s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: 无法将光栅数据写入驱动程序!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: 无法写入到临时文件" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: 无法写入未压缩的文稿数据:%s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: %2$s 的第 %1$d 行有意外的文本!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: 未知的加密选项值“%s”!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: 未知的文件顺序“%s”\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: 未知的格式字符“%c”\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: “%s”的信息目录格式未知!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: 未知选项“%s”,其值为“%s”!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: 未知打印模式“%s”\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: 未知的版本选项值“%s”!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: 不被支持的亮度值 %s,使用 brightness=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: 不被支持的灰度系数值 %s,使用 gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: 不被支持的 number-up 值 %d,使用 number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: 不被支持的 number-up-layout 值 %s,使用 number-up-layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: 不被支持的 page-border 值 %s,使用 page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: 检测到 doc_printf 溢出(%d 字节),正在中止!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops 因信号 %d 退出!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops 因状态 %d 退出!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "ERROR: 可恢复:无法连接到打印机;将在 30 秒钟后重试…\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() 失败" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: 无法获得打印文件的状态" + +msgid "Edit Configuration File" +msgstr "编辑配置文件" + +msgid "Empty PPD file!" +msgstr "空 PPD 文件!" + +msgid "Ending Banner" +msgstr "结束标题" + +msgid "Enter old password:" +msgstr "输入旧密码:" + +msgid "Enter password again:" +msgstr "再次输入密码:" + +msgid "Enter password:" +msgstr "输入密码:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"请输入您的用户名称和密码或者 root 用户的用户名称和密码来访问此页面。如果您正" +"在使用 Kerberos 鉴定,请确定您拥有的 Kerberos 票据是有效的。" + +msgid "Envelope Feed" +msgstr "信封送纸" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "错误策略" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "ERROR: '-h' 选项后需要主机名称!\n" + +msgid "Every 10 Labels" +msgstr "每 10 个标签" + +msgid "Every 2 Labels" +msgstr "每 2 个标签" + +msgid "Every 3 Labels" +msgstr "每 3 个标签" + +msgid "Every 4 Labels" +msgstr "每 4 个标签" + +msgid "Every 5 Labels" +msgstr "每 5 个标签" + +msgid "Every 6 Labels" +msgstr "每 6 个标签" + +msgid "Every 7 Labels" +msgstr "每 7 个标签" + +msgid "Every 8 Labels" +msgstr "每 8 个标签" + +msgid "Every 9 Labels" +msgstr "每 9 个标签" + +msgid "Every Label" +msgstr "每个标签" + +msgid "Expectation Failed" +msgstr "预期失败" + +msgid "Export Printers to Samba" +msgstr "将打印机导出为 Samba" + +msgid "FAIL\n" +msgstr "失败\n" + +msgid "File Folder" +msgstr "文件夹" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "文件夹 - 9/16 x 3 7/16 英寸" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"文件设备 URI 已被停用!要启用,请参阅“%s/cupsd.conf”中的 FileDevice 指令。" + +msgid "Folio" +msgstr "对开本" + +msgid "Forbidden" +msgstr "禁止" + +msgid "Fuser temperature high!" +msgstr "加热鼓温度过高!" + +msgid "Fuser temperature low!" +msgstr "加热鼓温度过低!" + +msgid "General" +msgstr "通用" + +msgid "Generic" +msgstr "通用" + +msgid "German FanFold" +msgstr "德国 FanFold" + +msgid "German FanFold Legal" +msgstr "德国 FanFold 法定用纸" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU 使用不定长度" + +msgid "Glossy Paper" +msgstr "光面纸" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "获得 printer-uri 属性而不是 job-id!" + +msgid "Grayscale" +msgstr "灰度" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "吊夹" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "吊夹 - 9/16 x 2 英寸" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: AppleTalk 已在“系统偏好设置”中停用\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: AppleTalk 已在“系统偏好设置”中停用。\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: 正在取消打印作业…\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: 已连接到打印机…\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: 正在连接到打印机…\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: 控制文件已成功发送\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: 数据文件已成功发送\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: 正在格式化页面 %d…\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: 正在载入图像文件…\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: 正在查找打印机…\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: 正在打开连接\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: 打印文件已发送,正在等侍打印机结束打印…\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: 打印机正忙;将在 10 秒钟后重试…\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: 打印机正忙;将在 30 秒钟后重试…\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: 打印机正忙;将在 5 秒钟后重试…\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: 打印机不支持 IPP/%d.%d,正在尝试 IPP/1.0…\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: 打印机正忙;将在 5 秒钟后重试…\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: 打印机当前已脱机。\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: 打印机当前已脱机。\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: 打印机现在联机。\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: 打印机已脱机。\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: 打印机未连接;将在 30 秒钟后重试…\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: 正在打印第 %d 页,已完成 %d%%…\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: 正在打印第 %d 页…\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: 准备打印。\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: 正在发送控制文件(%lu 字节)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: 正在发送控制文件(%u 字节)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: 正在发送数据\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: 正在发送数据文件(%ld 字节)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: 正在发送数据文件(%lld 字节)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: 正在发送打印数据…\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: 已发送打印文件,%ld 字节…\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: 已发送打印文件,%lld 字节…\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: 正在缓冲 LPR 作业,已完成 %.0f%%…\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "INFO: 无法联系打印机,正在排队等待类中的下一个打印机…\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: 正在使用默认的 AppleTalk 区域“%s”\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: 正在等待作业完成…\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: 正在等待打印机可用…\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 信封" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5(大号)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 信封" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 信封" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "非法控制字符" + +msgid "Illegal main keyword string" +msgstr "非法主关键词字符串" + +msgid "Illegal option keyword string" +msgstr "非法选项关键词字符串" + +msgid "Illegal translation string" +msgstr "非法转换字符串" + +msgid "Illegal whitespace character" +msgstr "非法空白字符" + +msgid "Ink/toner almost empty." +msgstr "墨水/碳粉差不多快要空了。" + +msgid "Ink/toner empty!" +msgstr "墨水/碳粉已空!" + +msgid "Ink/toner waste bin almost full." +msgstr "墨水/碳粉废物箱差不多快要满了。" + +msgid "Ink/toner waste bin full!" +msgstr "墨水/碳粉废物箱已满!" + +msgid "Installable Options" +msgstr "可安装的选项" + +msgid "Installed" +msgstr "已安装" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar 标签打印机" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "互锁打开。" + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "内部错误" + +msgid "Internet Postage 2-Part" +msgstr "Internet 邮寄 2 部分" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet 邮寄 2 部分 - 2 1/4 x 7 1/2 英寸" + +msgid "Internet Postage 3-Part" +msgstr "Internet 邮寄 3 部分" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet 邮寄 3 部分 - 2 1/4 x 7 英寸" + +msgid "Internet Printing Protocol" +msgstr "Internet 打印协议" + +msgid "Invite Envelope" +msgstr "邀请信封" + +msgid "Italian Envelope" +msgstr "意大利信封" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "作业 #%d 不能重新开始 - 无文件!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "作业 #%d 不存在!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "作业 #%d 已经中止 - 不能取消。" + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "作业 #%d 已经取消 - 不能取消。" + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "作业 #%d 已经完成 - 不能取消。" + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "作业 #%d 已结束,不能更改!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "作业 #%d 没有完成!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "作业 #%d 没有等待进行签定!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "作业 #%d 没有等待!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "作业 #%s 不存在!" + +#, c-format +msgid "Job %d not found!" +msgstr "作业 %d 找不到!" + +msgid "Job Completed" +msgstr "作业已完成" + +msgid "Job Created" +msgstr "作业已创建" + +msgid "Job ID: " +msgstr "作业 ID:" + +msgid "Job Options Changed" +msgstr "作业选项已更改" + +msgid "Job Stopped" +msgstr "作业已停止" + +msgid "Job UUID: " +msgstr "作业 UUID:" + +msgid "Job is completed and cannot be changed." +msgstr "作业已完成,不能更改。" + +msgid "Job operation failed:" +msgstr "作业操作失败:" + +msgid "Job state cannot be changed." +msgstr "作业状态不能更改。" + +msgid "Job subscriptions cannot be renewed!" +msgstr "作业订阅不能续订!" + +msgid "Jobs" +msgstr "作业" + +msgid "Kaku2 Envelope" +msgstr "Kaku2 信封" + +msgid "Kaku3 Envelope" +msgstr "Kaku3 信封" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR 主机或打印机" + +msgid "Label Printer" +msgstr "标签打印机" + +msgid "Label Top" +msgstr "标签顶部" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "语言“%s”不被支持!" + +msgid "Large Address" +msgstr "长地址" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "长地址 - 1 4/10 x 3 1/2 英寸" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet 系列 PCL 4/5" + +msgid "Light" +msgstr "指示灯" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "行多于所允许的最大字符数(255 个字符)" + +msgid "List Available Printers" +msgstr "列出可用的打印机" + +msgid "Location: " +msgstr "位置:" + +msgid "Long-Edge (Portrait)" +msgstr "长边(纵向)" + +msgid "Make and Model: " +msgstr "制造和型号:" + +msgid "Manual Feed" +msgstr "手动送纸" + +msgid "Media Dimensions: " +msgstr "介质尺寸:" + +msgid "Media Limits: " +msgstr "介质限制:" + +msgid "Media Name: " +msgstr "介质名称:" + +msgid "Media Size" +msgstr "介质大小" + +msgid "Media Source" +msgstr "介质来源" + +msgid "Media Tracking" +msgstr "介质跟踪" + +msgid "Media Type" +msgstr "介质类型" + +msgid "Media jam!" +msgstr "卡纸!" + +msgid "Media tray almost empty." +msgstr "介质盒差不多快要空了。" + +msgid "Media tray empty!" +msgstr "介质盒已空!" + +msgid "Media tray missing!" +msgstr "缺少介质盒!" + +msgid "Media tray needs to be filled." +msgstr "介质盒需要装纸。" + +msgid "Medium" +msgstr "中等" + +msgid "Memory allocation error" +msgstr "内存分配错误" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "缺少 PPD-Adobe-4.x 标头" + +msgid "Missing asterisk in column 1" +msgstr "栏 1 缺少星号" + +msgid "Missing document-number attribute!" +msgstr "缺少 document-number 属性!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "行 %d 缺少双引号!" + +msgid "Missing form variable!" +msgstr "缺少形式变量!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "缺少 notify-subscription-ids 属性!" + +msgid "Missing requesting-user-name attribute!" +msgstr "缺少 requesting-user-name 属性!" + +msgid "Missing required attributes!" +msgstr "缺少要求的属性!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "行 %d 缺少值!" + +msgid "Missing value string" +msgstr "缺少值字符串" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"型号:name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "修改类" + +msgid "Modify Printer" +msgstr "修改打印机" + +msgid "Monarch" +msgstr "皇家用纸" + +msgid "Monarch Envelope" +msgstr "皇家信封" + +msgid "Move All Jobs" +msgstr "移动所有作业" + +msgid "Move Job" +msgstr "移动作业" + +msgid "Moved Permanently" +msgstr "永久移动" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: 打印文件已接受 - 作业 ID %d。\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: 打印文件已接受 - 作业 ID 未知。\n" + +msgid "NULL PPD file pointer" +msgstr "空 PPD 文件指针" + +msgid "Name OID uses indefinite length" +msgstr "名称 OID 使用不定长度" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "永不" + +msgid "New Stylus Color Series" +msgstr "新 Stylus Color 系列" + +msgid "New Stylus Photo Series" +msgstr "新 Stylus Photo 系列" + +msgid "No" +msgstr "否" + +msgid "No Content" +msgstr "无内容" + +msgid "No PPD name!" +msgstr "无 PPD 名称!" + +msgid "No VarBind SEQUENCE" +msgstr "无 VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "未安装 Windows 打印机驱动程序!" + +msgid "No active connection" +msgstr "无活跃连接" + +#, c-format +msgid "No active jobs on %s!" +msgstr "%s 上没有活跃的作业!" + +msgid "No attributes in request!" +msgstr "请求中没有属性!" + +msgid "No authentication information provided!" +msgstr "未提供鉴定信息!" + +msgid "No community name" +msgstr "无团体名称" + +msgid "No default printer" +msgstr "无默认打印机" + +msgid "No destinations added." +msgstr "未添加目的位置。" + +msgid "No error-index" +msgstr "无错误索引" + +msgid "No error-status" +msgstr "无错误状态" + +msgid "No file!?!" +msgstr "无文件!?!" + +msgid "No modification time!" +msgstr "无修改时间!" + +msgid "No name OID" +msgstr "无名称 OID" + +msgid "No printer name!" +msgstr "无打印机名称!" + +msgid "No printer-uri found for class!" +msgstr "找不到类的 printer-uri!" + +msgid "No printer-uri found!" +msgstr "找不到 printer-uri!" + +msgid "No printer-uri in request!" +msgstr "请求中没有 printer-uri!" + +msgid "No request-id" +msgstr "无 request-id" + +msgid "No subscription attributes in request!" +msgstr "请求中没有订阅属性!" + +msgid "No subscriptions found." +msgstr "找不到订阅。" + +msgid "No variable-bindings SEQUENCE" +msgstr "无 variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "无版本号" + +msgid "Non-continuous (Mark sensing)" +msgstr "非连续(标记感应)" + +msgid "Non-continuous (Web sensing)" +msgstr "非连续(Web 感应)" + +msgid "Normal" +msgstr "正常" + +msgid "Not Found" +msgstr "找不到" + +msgid "Not Implemented" +msgstr "未完成" + +msgid "Not Installed" +msgstr "未安装" + +msgid "Not Modified" +msgstr "未修改" + +msgid "Not Supported" +msgstr "不支持" + +msgid "Not allowed to print." +msgstr "不允许打印。" + +msgid "Note" +msgstr "注释" + +msgid "OK" +msgstr "好" + +msgid "OPC almost at end-of-life." +msgstr "OPC 的使用寿命差不多快要到了。" + +msgid "OPC at end-of-life!" +msgstr "OPC 的使用寿命已到!" + +msgid "Off (1-Sided)" +msgstr "关闭(单面)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "网上帮助" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "打开 %s 失败:%s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup 没有 CloseGroup 优先" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI 没有 CloseUI/JCLCloseUI 优先" + +msgid "Operation Policy" +msgstr "操作策略" + +msgid "Options Installed" +msgstr "选项已安装" + +msgid "Options: " +msgstr "Options: " + +msgid "Out of toner!" +msgstr "碳粉不足!" + +msgid "Output Mode" +msgstr "输出模式" + +msgid "Output bin almost full." +msgstr "出纸箱差不多快要满了。" + +msgid "Output bin full!" +msgstr "出纸箱已满!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "打印机 %s 的输出已发送到 %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "打印机 %s 的输出已发送到远程打印机 %s(在 %s 上)\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "打印机 %s 的输出已发送到 %s/%s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "打印机 %s/%s 的输出已发送到远程打印机 %s(在 %s 上)\n" + +msgid "Output tray missing!" +msgstr "缺少输出盒!" + +msgid "PASS\n" +msgstr "通过\n" + +msgid "PCL Laser Printer" +msgstr "PCL 激光打印机" + +msgid "PRC1 Envelope" +msgstr "PRC1 信封" + +msgid "PRC10 Envelope" +msgstr "PRC10 信封" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2 信封" + +msgid "PRC3 Envelope" +msgstr "PRC3 信封" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K(大号)" + +msgid "PRC4 Envelope" +msgstr "PRC4 信封" + +msgid "PRC5 Envelope" +msgstr "PRC5 信封" + +msgid "PRC6 Envelope" +msgstr "PRC6 信封" + +msgid "PRC7 Envelope" +msgstr "PRC7 信封" + +msgid "PRC8 Envelope" +msgstr "PRC8 信封" + +msgid "PRC9 Envelope" +msgstr "PRC9 信封" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "包不包含 Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "包不以 SEQUENCE 开始" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "%s(在 %s 上)的密码?" + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "需要 %s 的密码才能通过 SAMBA 访问 %s:" + +msgid "Pause Class" +msgstr "暂停类" + +msgid "Pause Printer" +msgstr "打印机暂停打印" + +msgid "Peel-Off" +msgstr "剥离" + +msgid "Personal Envelope" +msgstr "个人信封" + +msgid "Photo" +msgstr "照片" + +msgid "Photo Labels" +msgstr "照片标签" + +msgid "Plain Paper" +msgstr "普通纸张" + +msgid "Policies" +msgstr "策略" + +msgid "Port Monitor" +msgstr "端口监视器" + +msgid "PostScript Printer" +msgstr "PostScript 打印机" + +msgid "Postcard" +msgstr "明信片" + +msgid "Print Density" +msgstr "打印密度" + +msgid "Print Job:" +msgstr "打印作业:" + +msgid "Print Mode" +msgstr "打印模式" + +msgid "Print Rate" +msgstr "打印速率" + +msgid "Print Self-Test Page" +msgstr "打印自测试页面" + +msgid "Print Speed" +msgstr "打印速度" + +msgid "Print Test Page" +msgstr "打印测试页" + +msgid "Print and Cut" +msgstr "打印和切纸" + +msgid "Print and Tear" +msgstr "打印和撕纸" + +msgid "Printed For: " +msgstr "打印人:" + +msgid "Printed From: " +msgstr "打印自:" + +msgid "Printed On: " +msgstr "打印于:" + +msgid "Printer Added" +msgstr "打印机已添加" + +msgid "Printer Default" +msgstr "打印机默认" + +msgid "Printer Deleted" +msgstr "打印机已删除" + +msgid "Printer Modified" +msgstr "打印机已修改" + +msgid "Printer Name: " +msgstr "打印机名称:" + +msgid "Printer Paused" +msgstr "打印机已暂停" + +msgid "Printer Settings" +msgstr "打印机设置" + +msgid "Printer offline." +msgstr "打印机已脱机。" + +msgid "Printer:" +msgstr "打印机:" + +msgid "Printers" +msgstr "打印机" + +msgid "Purge Jobs" +msgstr "消除作业" + +msgid "Quarto" +msgstr "四开" + +msgid "Quota limit reached." +msgstr "已达到配额限制。" + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "顺序 所有者 作业 文件 总大小\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"顺序 所有者 优先级 作业 文件 总大小\n" + +msgid "Reject Jobs" +msgstr "拒绝作业" + +msgid "Reprint After Error" +msgstr "出错后重新打印" + +msgid "Request Entity Too Large" +msgstr "请求实体太大" + +msgid "Resolution" +msgstr "分辨率" + +msgid "Resume Class" +msgstr "继续类" + +msgid "Resume Printer" +msgstr "打印机继续打印" + +msgid "Return Address" +msgstr "寄信人地址" + +msgid "Return Address - 3/4 x 2\"" +msgstr "寄信人地址 - 3/4 x 2 英寸" + +msgid "Rewind" +msgstr "倒回" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "运行命令:%s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI 打印机" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE 使用不定长度" + +msgid "See Other" +msgstr "请参阅其他" + +#, c-format +msgid "Serial Port #%d" +msgstr "串口 #%d" + +msgid "Server Restarted" +msgstr "服务器已重新启动" + +msgid "Server Security Auditing" +msgstr "服务器安全性审核" + +msgid "Server Started" +msgstr "服务器已启动" + +msgid "Server Stopped" +msgstr "服务器已停止" + +msgid "Service Unavailable" +msgstr "服务不可用" + +msgid "Set Allowed Users" +msgstr "设定允许的用户" + +msgid "Set As Server Default" +msgstr "设定为服务器默认" + +msgid "Set Class Options" +msgstr "设定类选项" + +msgid "Set Printer Options" +msgstr "设定打印机选项" + +msgid "Set Publishing" +msgstr "设定出版" + +msgid "Shipping Address" +msgstr "送货地址" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "送货地址 - 2 5/16 x 4 英寸" + +msgid "Short-Edge (Landscape)" +msgstr "短边(横向)" + +msgid "Special Paper" +msgstr "专用纸张" + +msgid "Standard" +msgstr "标准" + +msgid "Starting Banner" +msgstr "启动标题" + +msgid "Statement" +msgstr "报表" + +msgid "Stylus Color Series" +msgstr "Stylus Color 系列" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo 系列" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "交换协议" + +msgid "Tabloid" +msgstr "小报用纸" + +msgid "Tabloid (Oversize)" +msgstr "小报用纸(大号)" + +msgid "Tear" +msgstr "撕纸" + +msgid "Tear-Off" +msgstr "撕纸" + +msgid "Tear-Off Adjust Position" +msgstr "撕纸调整位置" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "PPD 文件“%s”未能找到。" + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "PPD 文件“%s”未能打开。%s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"类名称可能最多包含 127 个可打印的字符,且不能包含空格、斜线 (/) 或磅符号 " +"(#)。" + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "notify-lease-duration 属性不能配合作业订阅使用。" + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "notify-user-data 值太大(%d > 63 个八位字节)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"打印机名称可能最多包含 127 个可打印的字符,且不能包含空格、斜线 (/) 或磅符号 " +"(#)。" + +msgid "The printer or class is not shared!" +msgstr "打印机或类没有共享!" + +msgid "The printer or class was not found." +msgstr "打印机或类找不到。" + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "printer-uri“%s”含有无效字符。" + +msgid "The printer-uri attribute is required!" +msgstr "需要 printer-uri 属性。" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "printer-uri 必须是“ipp://HOSTNAME/classes/CLASSNAME”形式。" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "printer-uri 必须是“ipp://HOSTNAME/classes/PRINTERNAME”形式。" + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "订阅名称可能不包含空格、斜线 (/)、问号 (?) 或磅符号 (#)。" + +msgid "There are too many subscriptions." +msgstr "有太多订阅。" + +msgid "Thermal Transfer Media" +msgstr "热转印介质" + +msgid "Title: " +msgstr "标题:" + +msgid "Toner low." +msgstr "碳粉不足。" + +msgid "Too many active jobs." +msgstr "太多活跃的作业。" + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "太多 job-sheets 值 (%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "太多 printer-state-reasons 值 (%d > %d)!" + +msgid "Transparency" +msgstr "透明度" + +msgid "Tray" +msgstr "纸盒" + +msgid "Tray 1" +msgstr "纸盒 1" + +msgid "Tray 2" +msgstr "纸盒 2" + +msgid "Tray 3" +msgstr "纸盒 3" + +msgid "Tray 4" +msgstr "纸盒 4" + +msgid "URI Too Long" +msgstr "URI 太长" + +msgid "US Executive" +msgstr "美国行政用纸" + +msgid "US Fanfold" +msgstr "美国 Fanfold" + +msgid "US Ledger" +msgstr "美国总帐用纸" + +msgid "US Legal" +msgstr "美国法定用纸" + +msgid "US Legal (Oversize)" +msgstr "美国法定用纸(大号)" + +msgid "US Letter" +msgstr "美国信纸" + +msgid "US Letter (Oversize)" +msgstr "美国信纸(大号)" + +msgid "US Letter (Small)" +msgstr "美国信纸(小号)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB 串口 #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "无法访问 cupsd.conf 文件:" + +msgid "Unable to add RSS subscription:" +msgstr "无法添加 RSS 订阅:" + +msgid "Unable to add class:" +msgstr "无法添加类:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "无法为目的位置“%s”添加作业!" + +msgid "Unable to add printer:" +msgstr "无法添加打印机:" + +msgid "Unable to allocate memory for file types!" +msgstr "无法为文件类型分配内存!" + +msgid "Unable to cancel RSS subscription:" +msgstr "无法取消 RSS 订阅:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "无法更改 printer-is-shared 属性:" + +msgid "Unable to change printer:" +msgstr "无法更改打印机:" + +msgid "Unable to change server settings:" +msgstr "无法更改服务器设置:" + +msgid "Unable to connect to host." +msgstr "无法连接到主机。" + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "无法拷贝 64 位 CUPS 打印机驱动程序文件 (%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "无法拷贝 64 位 Windows 打印机驱动程序文件 (%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "无法拷贝 CUPS 打印机驱动程序文件 (%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "无法拷贝 PPD 文件 - %s!" + +msgid "Unable to copy PPD file!" +msgstr "无法拷贝 PPD 文件!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "无法拷贝 Windows 2000 打印机驱动程序文件 (%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "无法拷贝 Windows 9x 打印机驱动程序文件 (%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "无法拷贝接口脚本 - %s!" + +msgid "Unable to create printer-uri!" +msgstr "无法创建 printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "无法创建临时文件:" + +msgid "Unable to delete class:" +msgstr "无法删除类:" + +msgid "Unable to delete printer:" +msgstr "无法删除打印机:" + +msgid "Unable to do maintenance command:" +msgstr "无法执行维护命令:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "无法编辑大于 1MB 的 cupsd.conf 文件!" + +msgid "Unable to find destination for job!" +msgstr "找不到作业的目的位置!" + +msgid "Unable to find printer!\n" +msgstr "找不到打印机\n" + +msgid "Unable to get class list:" +msgstr "无法获得类列表:" + +msgid "Unable to get class status:" +msgstr "无法获得类状态:" + +msgid "Unable to get list of printer drivers:" +msgstr "无法获得打印机驱动程序的列表:" + +msgid "Unable to get printer attributes:" +msgstr "无法获得打印机属性:" + +msgid "Unable to get printer list:" +msgstr "无法获得打印机列表:" + +msgid "Unable to get printer status:" +msgstr "无法获得打印机状态:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "无法安装 Windows 2000 打印机驱动程序文件 (%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "无法安装 Windows 9x 打印机驱动程序文件 (%d)!" + +msgid "Unable to modify class:" +msgstr "无法修改类:" + +msgid "Unable to modify printer:" +msgstr "无法修改打印机:" + +msgid "Unable to move job" +msgstr "无法移动作业" + +msgid "Unable to move jobs" +msgstr "无法移动作业" + +msgid "Unable to open PPD file" +msgstr "无法打开 PPD 文件" + +msgid "Unable to open PPD file:" +msgstr "无法打开 PPD 文件:" + +msgid "Unable to open cupsd.conf file:" +msgstr "无法打开 cupsd.conf 文件:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "无法打开文稿 %d(在作业 %d 中)!" + +msgid "Unable to print test page:" +msgstr "无法打印测试页:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "无法运行“%s”:%s\n" + +msgid "Unable to send command to printer driver!" +msgstr "无法将命令发送到打印机驱动程序!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "无法获得 Windows 打印机驱动程序 (%d)!" + +msgid "Unable to set options:" +msgstr "无法设定选项:" + +msgid "Unable to set server default:" +msgstr "无法设定服务器默认值:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "无法上传 cupsd.conf 文件:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "无法使用传统 USB 类驱动程序!\n" + +msgid "Unauthorized" +msgstr "未授权" + +msgid "Units" +msgstr "单位" + +msgid "Unknown" +msgstr "未知" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "未知 printer-error-policy“%s”。" + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "未知 printer-op-policy“%s”。" + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "不支持的字符集“%s”!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "不被支持的压缩“%s”!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "不被支持的压缩属性 %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "不被支持的格式“%s”!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "不被支持的格式 '%s'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "不被支持的格式 '%s/%s'!" + +msgid "Unsupported value type" +msgstr "不支持的值类型" + +msgid "Upgrade Required" +msgstr "要求升级" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "Usage: %s job user title copies options [filename]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "Usage: %s job-id user title copies options [file]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "Usage: %s job-id user title copies options file\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "Usage: lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "Usage: lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "Usage: snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "Value 使用不定长度" + +msgid "VarBind uses indefinite length" +msgstr "VarBind 使用不定长度" + +msgid "Version uses indefinite length" +msgstr "Version 使用不定长度" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: 仅添加找到的前 %d 台打印机" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: Boolean 期望 waiteof 选项“%s”\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: 读取面通道请求失败!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: 不能通过 IncludeFeature 包括选项“%s”!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: 打印机没有响应\n" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: 打印机发送了意外的 EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "WARNING: %d 秒钟后,远程主机没有响应命令状态字节!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "WARNING: %d 秒钟后,远程主机没有响应控制状态字节!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "WARNING: %d 秒钟后,远程主机没有响应数据状态字节!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI 命令超时 (%d);正在重试…\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "" +"WARNING: 此文稿不符合 Adobe Document Structuring Conventions 的要求,可能无法" +"正确打印!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: 无法打开“%s:%s”:%s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: 无法发送 PAP 状态请求" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: 意外的 PAP 包(类型 %d)\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: 未知的 PAP 包(类型 %d)\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: 未知选择“%s”(用于选项“%s”)!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: 未知选项“%s”!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: 不被支持的波特率 %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: 状态选项“%s”期望数字\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "WARNING: 可恢复:网络主机“%s”正忙;将在 %d 秒钟后重试…\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "警告,未安装 Windows 2000 打印机驱动程序!" + +msgid "Yes" +msgstr "是" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"您必须使用 URL https://%s:%d%s 访问此页面。" + +msgid "You4 Envelope" +msgstr "You4 信封" + +msgid "ZPL Label Printer" +msgstr "ZPL 标签打印机" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "已中止" + +msgid "canceled" +msgstr "已取消" + +msgid "completed" +msgstr "已完成" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "转换:使用 -f 选项来指定要转换的文件。\n" + +msgid "cups-deviced failed to execute." +msgstr "cups-deviced 执行失败。" + +msgid "cups-driverd failed to execute." +msgstr "cups-driverd 执行失败。" + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb:无 PPD 文件可用于打印机“%s”- %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl:无法连接到服务器:%s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl:未知选项“%s”!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl:未知选项“-%c”!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd:“-c”选项后期望配置文件名称!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd:无法获得当前目录!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd:未知自变量“%s”- 正在中止!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd:未知选项“%c”- 正在中止!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd:launchd(8) 支持未编译,正在以正常模式运行。\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter:无效的文稿编号 %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter:无效的作业 ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter:只能指定一个文件名称!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter:无法获得作业文件 - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd:-q 选项与 -v 选项不兼容。\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd:-v 选项与 -q 选项不兼容。\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "用于 %s/%s 设备:%s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "用于 %s 的设备:%s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index 使用不定长度" + +msgid "error-status uses indefinite length" +msgstr "error-status 使用不定长度" + +msgid "held" +msgstr "保留" + +msgid "help\t\tget help on commands\n" +msgstr "帮助\t\t获得命令帮助\n" + +msgid "idle" +msgstr "闲置" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri 属性丢失!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin: 类名称只能含有可打印字符!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin: '-P' 选项后期望 PPD!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin: '-u' 选项后期望 allow/deny:userlist!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin: '-r' 选项后期望类。\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin: '-c' 选项后期望类名称!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin: '-D' 选项后期望描述!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin: '-v' 选项后期望设备 URI!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin: '-I' 选项后期望文件类型!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin: '-h' 选项后期望主机名称!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin: '-i' 选项后期望接口!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin: '-L' 选项后期望位置!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin: '-m' 选项后期望型号!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin: '-o' 选项后期望 name=value!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin: '-p' 选项后期望打印机!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin: '-d' 选项后期望打印机名称!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin: '-x' 选项后期望打印机或类!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin: 会发现成员名称!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin: 打印机 %s 已经是类 %s 的成员。\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin: 打印机 %s 不是类 %s 的成员。\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin: 打印机名称只能含有可打印字符!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法将打印机添加到类:\n" +" 您必须先指定一个打印机名称!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin: 无法连接到服务器:%s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin: 无法打开 PPD 文件“%s”- %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin: 无法打开文件“%s”:%s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法从类中去掉打印机:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定 PPD 文件:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定设备 URI:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定接口脚本或 PPD 文件:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定接口脚本:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定打印机描述:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定打印机位置:\n" +" 您必须先指定一个打印机名称!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin: 无法设定打印机选项:\n" +" 您必须先指定一个打印机名称!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin: 未知的允许/拒绝选项“%s”!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin: 未知自变量 '%s'!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin: 未知选项 '%c'!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin: 警告 - 内容类型列表被忽略!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo:--device-id 后期望的 1284 设备 ID 字符串!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo:--language 后期望的语言!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo:--make-and-model 后期望的制造和型号!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo:--product 后期望的产品字符串!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo:--exclude-schemes 后期望的方案列表!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo:--include-schemes 后期望的方案列表!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo:--timeout 后期望的超时!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo:未知自变量 '%s'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo:未知选项 '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo:未知选项“%s”!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove:无法连接到服务器:%s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove:未知自变量 '%s'!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove:未知选项 '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions:无打印机!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions:无法添加打印机或实例:%s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions:无法获得 %s 的 PPD 文件:%s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions:无法打开 %s 的 PPD 文件!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions:未知打印机或类!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd: 仅根用户才可以添加或删除密码!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd: 密码文件正忙!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd: 密码文件未更新!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd: 对不起,密码不匹配!\n" + +msgid "" +"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" +msgstr "" +"lppasswd: 对不起,密码被拒绝。\n" +"您的密码必须至少有 6 个字符长,不能包含\n" +"您的用户名称,并且必须至少包含 1 个字母和 1 个数字。\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd: 对不起,密码不匹配!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd: 无法拷贝密码字符串:%s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd: 无法打开密码文件:%s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd: 无法写入密码文件:%s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd: 备份旧密码文件失败:%s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd: 给密码文件重新命名失败:%s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd: 用户“%s”和组“%s”不存在。\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "lpstat: 错误 - %s 个环境变量名称不存在目的位置“%s”!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "类 %s 的成员:\n" + +msgid "no entries\n" +msgstr "无条目\n" + +msgid "no system default destination\n" +msgstr "无系统默认目的位置\n" + +msgid "notify-events not specified!" +msgstr "notify-events 未指定!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI“%s”已经在使用!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI“%s”使用未知方案!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d 不好!" + +msgid "pending" +msgstr "挂起" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc:正在添加包括目录“%s”…\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc:正在从 %s 添加/更新 UI 文本…\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc:错误的布尔值 (%1$s),在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc:错误的分辨率名称“%1$s”,在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc:错误的关键词 %1$s,在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc:错误的变量替换 ($%1$c),在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc:在 %2$s 的第 %1$d 行找到选择,但没有选项!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc:地点 %1$s 的 #po 重复(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望滤镜定义!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望程序名称!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望布尔值。\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Font 后面期望字符集!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望选择代码。\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望选择名称/文本。\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望 ColorModel 的颜色顺序!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望 ColorModel 的颜色空间!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望 ColorModel 的压缩!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望 UIConstraints 的约束字符串!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 DriverType 后面期望驱动程序类型关键词!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Duplex 后面期望双面类型!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Font 后面期望编码!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc:#po %1$s 后面期望文件名称(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望组别名称/文本。\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望包括文件名称!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望整数!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 #po 后面期望地点!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 后面期望名称(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 FileName 后面期望名称!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Font 后面期望名称!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Manufacturer 后面期望名称!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 MediaSize 后面期望名称!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 ModelName 后面期望名称!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 PCFileName 后面期望名称!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 后面期望名称/文本(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Installable 后面期望名称/文本!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Resolution 后面期望名称/文本!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望 ColorModel 的名称/文本组合!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望选项名称/文本!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望选项区!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望选项类型!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Resolution 后面期望覆盖字段!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望实数!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 ColorProfile 后面期望分辨率/介质类型!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc:%2$s 的第 %1$d 行上的 SimpleColorProfile 后面期望分辨率/介质类型!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 后面期望选择器(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Font 后面期望状态!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Copyright 后面期望字符串!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Version 后面期望字符串!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行期望两个选项名称!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 后面期望值(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上的 Font 后面期望版本!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc:无效的 #include/#po 文件名称“%s”!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行有无效的滤镜成本!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行有无效的滤镜空 MIME 类型!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行有无效的滤镜空程序名称!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc:无效的选项区“%1$s”,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc:无效的选项类型“%1$s”,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc:正在载入驱动程序信息文件“%s”…\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc:正在载入地点“%s”的信息…\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc:正在从“%s”载入信息…\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc:“%s”的末尾丢失 #endif!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行丢失 #if!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc:没有为地点 %s 提供信息目录!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc:选项 %1$s 被重新定义为不同的类型(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc:选项约束必须在 %2$s 的第 %1$d 行上指定的 *name 中!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行嵌套的 #if 太多!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc:无法创建 PPD 文件“%s” - %s。\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc:无法创建输出目录 %s:%s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc:无法创建输出管道:%s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc:无法执行 cupstestppd:%s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc:找不到 #po 文件 %1$s(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc:找不到包括文件“%1$s”(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc:找不到“%s”的本地化文件 - %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc:无法载入本地化文件“%s” - %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc:未定义的变量 (%1$s),在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc:未知的驱动程序类型 %1$s,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc:未知的双面类型“%1$s”,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc:未知的介质大小“%1$s”,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc:未知的令牌“%1$s”,出现在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "ppdc:实数“%1$s”中有未知的末尾字符(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc:未结束的字符串以 %1$c 开头(在 %3$s 的第 %2$d 行)!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc:正在写入 %s…\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc:正在将 PPD 文件写入目录“%s”…\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge:错误的 LanguageVersion“%s”(在 %s 中)!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge:正在忽略 PPD 文件 %s…\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge:无法将 %s 备份到 %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "打印机 %s 已停用,时间从 %s -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "打印机 %s 闲置,启用时间从 %s\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "打印机 %s 现在正在打印 %s-%d,启用时间从 %s\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "打印机 %s/%s 已停用,时间从 %s -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "打印机 %s/%s 闲置,启用时间从 %s\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "打印机 %s/%s 现在正在打印 %s-%d,启用时间从 %s\n" + +msgid "processing" +msgstr "正在处理" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "请求 id 是 %s-%d(%d 个文件)\n" + +msgid "request-id uses indefinite length" +msgstr "request-id 使用不定长度" + +msgid "scheduler is not running\n" +msgstr "调度程序没有运行\n" + +msgid "scheduler is running\n" +msgstr "调度程序正在运行\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "获得 %s 的状态失败:%s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "状态\t\t显示监控程序和队列的状态\n" + +msgid "stopped" +msgstr "已停止" + +#, c-format +msgid "system default destination: %s\n" +msgstr "系统默认目的位置:%s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "系统默认目的位置:%s/%s\n" + +msgid "unknown" +msgstr "未知" + +msgid "untitled" +msgstr "未命名" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings 使用不定长度" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " WARN 缺少 APDialogExtension 文件“%s”\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " WARN 缺少 APPrinterIconPath 文件“%s”\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s:无法打开 %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s:无法打开 %s - %s(在第 %d 行)。\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI 灰度" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "ERROR: 命令行上缺少设备 URI,且无 DEVICE_URI 环境变量!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: 无法创建临时文件 - %s。\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: 无法创建临时文件:%s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: 无法打开临时文件" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops 滤镜在信号 %d 处崩溃!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops 滤镜退出,状态为 %d!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "未知打印机错误 (%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter:无法创建临时文件:%s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin: 无法创建临时文件 - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin: 无法创建临时文件:%s\n" diff --git a/locale/cups_zh_TW.po b/locale/cups_zh_TW.po new file mode 100644 index 0000000000..970f638e4f --- /dev/null +++ b/locale/cups_zh_TW.po @@ -0,0 +1,5583 @@ +msgid "" +msgstr "" +"Project-Id-Version: CUPS 1.4\n" +"Report-Msgid-Bugs-To: http://www.cups.org/str.php\n" +"POT-Creation-Date: 2009-06-18 15:43-0700\n" +"PO-Revision-Date: 2009-02-16 12:00-0800\n" +"Last-Translator: Apple Inc.\n" +"Language-Team: Apple Inc.\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "\t\t(all)\n" +msgstr "\t\t(全部)\n" + +msgid "\t\t(none)\n" +msgstr "\t\t(無)\n" + +#, c-format +msgid "\t%d entries\n" +msgstr "\t%d 個項目\n" + +msgid "\tAfter fault: continue\n" +msgstr "\t出錯後:繼續\n" + +msgid "\tAlerts:" +msgstr "\tWARNING: " + +msgid "\tBanner required\n" +msgstr "\t需要標語:\n" + +msgid "\tCharset sets:\n" +msgstr "\t字元集:\n" + +msgid "\tConnection: direct\n" +msgstr "\t連線:直接\n" + +msgid "\tConnection: remote\n" +msgstr "\t連線:遠端\n" + +msgid "\tDefault page size:\n" +msgstr "\t預設頁面大小:\n" + +msgid "\tDefault pitch:\n" +msgstr "\t預設音高:\n" + +msgid "\tDefault port settings:\n" +msgstr "\t預設連接埠設定:\n" + +#, c-format +msgid "\tDescription: %s\n" +msgstr "\t描述:%s\n" + +msgid "" +"\tForm mounted:\n" +"\tContent types: any\n" +"\tPrinter types: unknown\n" +msgstr "" +"\t已裝載的表單:\n" +"\t內容類型:任意\n" +"\t印表機類型:未知\n" + +msgid "\tForms allowed:\n" +msgstr "\t允許的表單:\n" + +#, c-format +msgid "\tInterface: %s.ppd\n" +msgstr "\t介面:%s.ppd\n" + +#, c-format +msgid "\tInterface: %s/interfaces/%s\n" +msgstr "\t介面:%s/interfaces/%s\n" + +#, c-format +msgid "\tInterface: %s/ppd/%s.ppd\n" +msgstr "\t介面:%s/ppd/%s.ppd\n" + +#, c-format +msgid "\tLocation: %s\n" +msgstr "\t位置:%s\n" + +msgid "\tOn fault: no alert\n" +msgstr "\t出錯時:無提示\n" + +msgid "\tUsers allowed:\n" +msgstr "\t允許的使用者:\n" + +msgid "\tUsers denied:\n" +msgstr "\t拒絕的使用者:\n" + +msgid "\tdaemon present\n" +msgstr "\t現有的服務程式\n" + +msgid "\tno entries\n" +msgstr "\t無項目\n" + +#, c-format +msgid "\tprinter is on device '%s' speed -1\n" +msgstr "\t印表機為設備 '%s' 的速度 -1\n" + +msgid "\tprinting is disabled\n" +msgstr "\t已停用列印\n" + +msgid "\tprinting is enabled\n" +msgstr "\t已啟用列印\n" + +#, c-format +msgid "\tqueued for %s\n" +msgstr "\t%s 已佇列\n" + +msgid "\tqueuing is disabled\n" +msgstr "\t已停用佇列\n" + +msgid "\tqueuing is enabled\n" +msgstr "\t已啟用佇列\n" + +msgid "\treason unknown\n" +msgstr "\t原因未知\n" + +msgid "" +"\n" +" DETAILED CONFORMANCE TEST RESULTS\n" +msgstr "" +"\n" +" 詳細的相似度測試結果\n" + +msgid " REF: Page 15, section 3.1.\n" +msgstr " 參考:第 15 頁,章節 3.1。\n" + +msgid " REF: Page 15, section 3.2.\n" +msgstr " 參考:第 15 頁,章節 3.2。\n" + +msgid " REF: Page 19, section 3.3.\n" +msgstr " 參考:第 19 頁,章節 3.3。\n" + +msgid " REF: Page 20, section 3.4.\n" +msgstr " 參考:第 20 頁,章節 3.4。\n" + +msgid " REF: Page 27, section 3.5.\n" +msgstr " 參考:第 27 頁,章節 3.5。\n" + +msgid " REF: Page 42, section 5.2.\n" +msgstr " 參考:第 42 頁,章節 5.2。\n" + +msgid " REF: Pages 16-17, section 3.2.\n" +msgstr " 參考:第 16-17 頁,章節 3.2。\n" + +msgid " REF: Pages 42-45, section 5.2.\n" +msgstr " 參考:第 42-45 頁,章節 5.2。\n" + +msgid " REF: Pages 45-46, section 5.2.\n" +msgstr " 參考:第 45-46 頁,章節 5.2。\n" + +msgid " REF: Pages 48-49, section 5.2.\n" +msgstr " 參考:第 48-49 頁,章節 5.2。\n" + +msgid " REF: Pages 52-54, section 5.2.\n" +msgstr " 參考:第 52-54 頁,章節 5.2。\n" + +#, c-format +msgid " %-39.39s %.0f bytes\n" +msgstr " %-39.39s %.0f byte\n" + +#, c-format +msgid " PASS Default%s\n" +msgstr " 通過 Default%s\n" + +msgid " PASS DefaultImageableArea\n" +msgstr " 通過 DefaultImageableArea\n" + +msgid " PASS DefaultPaperDimension\n" +msgstr " 通過 DefaultPaperDimension\n" + +msgid " PASS FileVersion\n" +msgstr " 通過 FileVersion\n" + +msgid " PASS FormatVersion\n" +msgstr " 通過 FormatVersion\n" + +msgid " PASS LanguageEncoding\n" +msgstr " 通過 LanguageEncoding\n" + +msgid " PASS LanguageVersion\n" +msgstr " 通過 LanguageVersion\n" + +msgid " PASS Manufacturer\n" +msgstr " 通過 Manufacturer\n" + +msgid " PASS ModelName\n" +msgstr " 通過 ModelName\n" + +msgid " PASS NickName\n" +msgstr " 通過 NickName\n" + +msgid " PASS PCFileName\n" +msgstr " 通過 PCFileName\n" + +msgid " PASS PSVersion\n" +msgstr " 通過 PSVersion\n" + +msgid " PASS PageRegion\n" +msgstr " 通過 PageRegion\n" + +msgid " PASS PageSize\n" +msgstr " 通過 PageSize\n" + +msgid " PASS Product\n" +msgstr " 通過 Product\n" + +msgid " PASS ShortNickName\n" +msgstr " 通過 ShortNickName\n" + +#, c-format +msgid "" +" WARN \"%s %s\" conflicts with \"%s %s\"\n" +" (constraint=\"%s %s %s %s\")\n" +msgstr "" +" 警告 “%s %s”與“%s %s”衝突\n" +" (限制=“%s %s %s %s”)\n" + +#, c-format +msgid " WARN %s has no corresponding options!\n" +msgstr " 警告 %s 沒有對應的選項!\n" + +#, c-format +msgid "" +" WARN %s shares a common prefix with %s\n" +" REF: Page 15, section 3.2.\n" +msgstr "" +" 警告 %s 與 %s 共用一般的前置碼\n" +" 參考:第 15 頁,章節 3.2。\n" + +msgid " WARN Default choices conflicting!\n" +msgstr " 警告 預設的選項衝突!\n" + +#, c-format +msgid "" +" WARN Duplex option keyword %s may not work as expected and should " +"be named Duplex!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" 警告 兩用裝紙匣選項的關鍵字 %s 不能如預期運作,而應該命名為 " +"Duplex!\n" +" 參考:第 122 頁,章節 5.17\n" + +msgid "" +" WARN File contains a mix of CR, LF, and CR LF line endings!\n" +msgstr " 警告 檔案包含 CR、LF 和 CR LF 的行結尾!\n" + +msgid "" +" WARN LanguageEncoding required by PPD 4.3 spec.\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" 警告 PPD 4.3 規格要求有 LanguageEncoding\n" +" 參考:第 56-57 頁,章節 5.3。\n" + +#, c-format +msgid " WARN Line %d only contains whitespace!\n" +msgstr " 警告 第 %d 行只包含空白!\n" + +msgid "" +" WARN Manufacturer required by PPD 4.3 spec.\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" 警告 PD 4.3 規格要求有 Manufacturer\n" +" 參考:第 58-59 頁,章節 5.3。\n" + +msgid "" +" WARN Non-Windows PPD files should use lines ending with only LF, " +"not CR LF!\n" +msgstr "" +" 警告 非 Windows PPD 檔案應該使用僅含有 LF 的行結尾,而不是 CR " +"LF!\n" + +#, c-format +msgid "" +" WARN Obsolete PPD version %.1f!\n" +" REF: Page 42, section 5.2.\n" +msgstr "" +" 警告 PPD 版本 %.1f 已過時!\n" +" 參考:第 42 頁,章節 5.2。\n" + +msgid "" +" WARN PCFileName longer than 8.3 in violation of PPD spec.\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" 警告 PCFileName 長度大於 8.3,這違反了 PPD 規格。\n" +" 參考:第 61-62 頁,章節 5.3。\n" + +msgid "" +" WARN Protocols contains PJL but JCL attributes are not set.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" 警告 通訊協定包含 PJL,但未設定 JCL 屬性。\n" +" 參考:第 78-79 頁,章節 5.7。\n" + +msgid "" +" WARN Protocols contains both PJL and BCP; expected TBCP.\n" +" REF: Pages 78-79, section 5.7.\n" +msgstr "" +" 警告 通訊協定同時包含 PJL 和 BCP;應該為 TBCP。\n" +" 參考:第 78-79 頁,章節 5.7。\n" + +msgid "" +" WARN ShortNickName required by PPD 4.3 spec.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" 警告 PPD 4.3 規格要求有 ShortNickName\n" +" 參考:第 64-65 頁,章節 5.3。\n" + +#, c-format +msgid " %s %s %s does not exist!\n" +msgstr " %s %s %s 不存在!\n" + +#, c-format +msgid " %s %s file \"%s\" has the wrong capitalization!\n" +msgstr "" + +#, c-format +msgid "" +" %s Bad %s choice %s!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s %s 選項 %s 錯誤!\n" +" 參考:第 122 頁,章節 5.17\n" + +#, c-format +msgid " %s Bad UTF-8 \"%s\" translation string for option %s!\n" +msgstr " %s 下列項目的 UTF-8“%s”轉換字串ERROR: 選項 %s!\n" + +#, c-format +msgid "" +" %s Bad UTF-8 \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s 下列項目的 UTF-8“%s”轉換字串ERROR: 選項 %s,選項 %s!\n" + +#, c-format +msgid " %s Bad cupsFilter value \"%s\"!\n" +msgstr " %s cupsFilter 值“%s”錯誤!\n" + +#, c-format +msgid " %s Bad cupsICCProfile %s!\n" +msgstr " %s cupsICCProfile %s 錯誤!\n" + +#, c-format +msgid " %s Bad cupsPreFilter value \"%s\"!\n" +msgstr " %s cupsPreFilter 值“%s”錯誤!\n" + +#, c-format +msgid " %s Bad cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s cupsUIConstraints %s:“%s”錯誤!\n" + +#, c-format +msgid " %s Bad language \"%s\"!\n" +msgstr " %s 語言“%s”錯誤!\n" + +#, c-format +msgid " %s Bad spelling of %s - should be %s!\n" +msgstr "" + +#, c-format +msgid " %s Cannot provide both APScanAppPath and APScanAppBundleID!\n" +msgstr "" + +#, c-format +msgid " %s Empty cupsUIConstraints %s!\n" +msgstr " %s cupsUIConstraints %s 為空白!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s!\n" +msgstr " %s 下列項目的“%s”轉換字串遺失:選項 %s!\n" + +#, c-format +msgid " %s Missing \"%s\" translation string for option %s, choice %s!\n" +msgstr " %s 下列項目的“%s”轉換字串遺失:選項 %s,選項 %s!\n" + +#, c-format +msgid " %s Missing APDialogExtension file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterIconPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterLowInkTool file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APPrinterUtilityPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid " %s Missing APScanAppPath file \"%s\"\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageRegion option!\n" +" REF: Page 100, section 5.14.\n" +msgstr "" + +#, c-format +msgid "" +" %s Missing REQUIRED PageSize option!\n" +" REF: Page 99, section 5.14.\n" +msgstr "" + +#, c-format +msgid " %s Missing choice *%s %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s 下列項目中遺失選項 *%s %s:UIConstraints“*%s %s *%s %s”!\n" + +#, c-format +msgid " %s Missing choice *%s %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 下列項目中遺失選項 *%s %s:cupsUIConstraints %s:“%s”!\n" + +#, c-format +msgid " %s Missing cupsFilter file \"%s\"\n" +msgstr " %s 遺失 cupsFilter 檔案“%s”\n" + +#, c-format +msgid " %s Missing cupsICCProfile file \"%s\"!\n" +msgstr " %s 遺失 cupsICCProfile 檔案“%s”!\n" + +#, c-format +msgid " %s Missing cupsPreFilter file \"%s\"\n" +msgstr " %s 遺失 cupsPreFilter 檔案“%s”\n" + +#, c-format +msgid " %s Missing cupsUIResolver %s!\n" +msgstr " %s 遺失 cupsUIResolver %s!\n" + +#, c-format +msgid " %s Missing option %s in UIConstraints \"*%s %s *%s %s\"!\n" +msgstr " %s 下列項目中遺失選項 %s:UIConstraints“*%s %s *%s %s”!\n" + +#, c-format +msgid " %s Missing option %s in cupsUIConstraints %s: \"%s\"!\n" +msgstr " %s 下列項目中遺失選項 %s:cupsUIConstraints %s:“%s”!\n" + +#, c-format +msgid " %s No base translation \"%s\" is included in file!\n" +msgstr " %s 檔案中不包括基礎轉換“%s”!\n" + +#, c-format +msgid "" +" %s Non-standard size name \"%s\"!\n" +" REF: Page 187, section B.2.\n" +msgstr "" + +#, c-format +msgid "" +" %s REQUIRED %s does not define choice None!\n" +" REF: Page 122, section 5.17\n" +msgstr "" +" %s REQUIRED %s 未定義選項 None!\n" +" 參考:第 122 頁,章節 5.17\n" + +#, c-format +msgid " %s Size \"%s\" defined for %s but not for %s!\n" +msgstr "" + +#, c-format +msgid " %s Size \"%s\" has unexpected dimensions (%gx%g)!\n" +msgstr "" + +#, c-format +msgid " %s cupsICCProfile %s hash value collides with %s!\n" +msgstr " %s cupsICCProfile %s 雜湊值與 %s 衝突!\n" + +#, c-format +msgid " %s cupsUIResolver %s causes a loop!\n" +msgstr " %s cupsUIResolver %s 造成迴圈!\n" + +#, c-format +msgid "" +" %s cupsUIResolver %s does not list at least two different options!\n" +msgstr "" + +#, c-format +msgid " **FAIL** %s choice names %s and %s differ only by case!\n" +msgstr " **失敗** %s 選項名稱 %s 和 %s 僅在某些情況下不同!\n" + +#, c-format +msgid "" +" **FAIL** %s must be 1284DeviceID!\n" +" REF: Page 72, section 5.5\n" +msgstr "" +" **失敗** %s 必須為 1284DeviceID!\n" +" 參考:第 72 頁,章節 5.5\n" + +#, c-format +msgid "" +" **FAIL** BAD Default%s %s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **失敗** Default%s %s 錯誤\n" +" 參考:第 40 頁,章節 4.5。\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultImageableArea %s!\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失敗** DefaultImageableArea %s 錯誤!\n" +" 參考:第 102 頁,章節 5.15。\n" + +#, c-format +msgid "" +" **FAIL** BAD DefaultPaperDimension %s!\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失敗** DefaultPaperDimension %s 錯誤!\n" +" 參考:第 103 頁,章節 5.15。\n" + +msgid "" +" **FAIL** BAD JobPatchFile attribute in file\n" +" REF: Page 24, section 3.4.\n" +msgstr "" +" **失敗** 檔案中的 JobPatchFile 屬性錯誤\n" +" 參考:第 24 頁,章節 3.4。\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"HP\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **失敗** Manufacturer 錯誤(應該為“HP”)\n" +" 參考:第 211 頁,表格 D.1。\n" + +msgid "" +" **FAIL** BAD Manufacturer (should be \"Oki\")\n" +" REF: Page 211, table D.1.\n" +msgstr "" +" **失敗** Manufacturer 錯誤(應該為“Oki”)\n" +" 參考:第 211 頁,表格 D.1。\n" + +#, c-format +msgid "" +" **FAIL** BAD ModelName - \"%c\" not allowed in string.\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **失敗** ModelName 錯誤 - 字串中不允許“%c”。\n" +" 參考:第 59-60 頁,章節 5.3。\n" + +msgid "" +" **FAIL** BAD PSVersion - not \"(string) int\".\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **失敗** PSVersion 錯誤 - 不是“(string) int”。\n" +" 參考:第 62-64 頁,章節 5.3。\n" + +msgid "" +" **FAIL** BAD Product - not \"(string)\".\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **失敗** Product 錯誤 - 不是“(string)”。\n" +" 參考:第 62 頁,章節 5.3。\n" + +msgid "" +" **FAIL** BAD ShortNickName - longer than 31 chars.\n" +" REF: Pages 64-65, section 5.3.\n" +msgstr "" +" **失敗** ShortNickName 錯誤 - 長度大於 31 個字元。\n" +" 參考:第 64-65 頁,章節 5.3。\n" + +#, c-format +msgid "" +" **FAIL** Bad %s choice %s!\n" +" REF: Page 84, section 5.9\n" +msgstr "" +" **失敗** %s 選項 %s 錯誤!\n" +" 參考:第 84 頁,章節 5.9\n" + +#, c-format +msgid "" +" **FAIL** Bad FileVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** FileVersion“%s”錯誤\n" +" 參考:第 56 頁,章節 5.3。\n" + +#, c-format +msgid "" +" **FAIL** Bad FormatVersion \"%s\"\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** FormatVersion“%s”錯誤\n" +" 參考:第 56 頁,章節 5.3。\n" + +#, c-format +msgid " **FAIL** Bad LanguageEncoding %s - must be ISOLatin1!\n" +msgstr " **失敗** LanguageEncoding %s 錯誤 - 必須為 ISOLatin1!\n" + +#, c-format +msgid " **FAIL** Bad LanguageVersion %s - must be English!\n" +msgstr " **失敗** LanguageVersion %s 錯誤 - 必須為英語!\n" + +#, c-format +msgid " **FAIL** Default option code cannot be interpreted: %s\n" +msgstr " **失敗** 無法解譯預設選項代碼:%s\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s choice %s contains " +"8-bit characters!\n" +msgstr " **失敗** 選項 %s 選項 %s 的預設轉換字串包含 8 位元字元!\n" + +#, c-format +msgid "" +" **FAIL** Default translation string for option %s contains 8-bit " +"characters!\n" +msgstr " **失敗** 選項 %s 的預設轉換字串包含 8 位元字元!\n" + +#, c-format +msgid " **FAIL** Group names %s and %s differ only by case!\n" +msgstr " **失敗** 群組名稱 %s 和 %s 僅在某些情況下不同!\n" + +#, c-format +msgid " **FAIL** Multiple occurrences of %s choice name %s!\n" +msgstr " **失敗** 出現了多個 %s 選項名稱 %s!\n" + +#, c-format +msgid " **FAIL** Option names %s and %s differ only by case!\n" +msgstr " **失敗** 選項名稱 %s 和 %s 僅在某些情況下不同!\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED Default%s\n" +" REF: Page 40, section 4.5.\n" +msgstr "" +" **失敗** 需要 Default%s\n" +" 參考:第 40 頁,章節 4.5。\n" + +msgid "" +" **FAIL** REQUIRED DefaultImageableArea\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失敗** 需要 DefaultImageableArea\n" +" 參考:第 102 頁,章節 5.15。\n" + +msgid "" +" **FAIL** REQUIRED DefaultPaperDimension\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失敗** 需要 DefaultPaperDimension\n" +" 參考:第 103 頁,章節 5.15。\n" + +msgid "" +" **FAIL** REQUIRED FileVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** 需要 FileVersion\n" +" 參考:第 56 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED FormatVersion\n" +" REF: Page 56, section 5.3.\n" +msgstr "" +" **失敗** 需要 FormatVersion\n" +" 參考:第 56 頁,章節 5.3。\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED ImageableArea for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 102, section 5.15.\n" +msgstr "" +" **失敗** PageSize %s 需要 ImageableArea\n" +" 參考:第 41 頁,章節 5。\n" +" 參考:第 102 頁,章節 5.15。\n" + +msgid "" +" **FAIL** REQUIRED LanguageEncoding\n" +" REF: Pages 56-57, section 5.3.\n" +msgstr "" +" **失敗** 需要 LanguageEncoding\n" +" 參考:第 56-57 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED LanguageVersion\n" +" REF: Pages 57-58, section 5.3.\n" +msgstr "" +" **失敗** 需要 LanguageVersion\n" +" 參考:第 57-58 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED Manufacturer\n" +" REF: Pages 58-59, section 5.3.\n" +msgstr "" +" **失敗** 需要 Manufacturer\n" +" 參考:第 58-59 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED ModelName\n" +" REF: Pages 59-60, section 5.3.\n" +msgstr "" +" **失敗** 需要 ModelName\n" +" 參考:第 59-60 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED NickName\n" +" REF: Page 60, section 5.3.\n" +msgstr "" +" **失敗** 需要 NickName\n" +" 參考:第 60 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PCFileName\n" +" REF: Pages 61-62, section 5.3.\n" +msgstr "" +" **失敗** 需要 PCFileName\n" +" 參考:第 61-62 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PSVersion\n" +" REF: Pages 62-64, section 5.3.\n" +msgstr "" +" **失敗** 需要 PSVersion\n" +" 參考:第 62-64 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED PageRegion\n" +" REF: Page 100, section 5.14.\n" +msgstr "" +" **失敗** 需要 PageRegion\n" +" 參考:第 100 頁,章節 5.14。\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Page 41, section 5.\n" +" REF: Page 99, section 5.14.\n" +msgstr "" +" **失敗** 需要 PageSize\n" +" 參考:第 41 頁,章節 5。\n" +" 參考:第 99 頁,章節 5.14。\n" + +msgid "" +" **FAIL** REQUIRED PageSize\n" +" REF: Pages 99-100, section 5.14.\n" +msgstr "" +" **失敗** 需要 PageSize\n" +" 參考:第 99-100 頁,章節 5.14。\n" + +#, c-format +msgid "" +" **FAIL** REQUIRED PaperDimension for PageSize %s\n" +" REF: Page 41, section 5.\n" +" REF: Page 103, section 5.15.\n" +msgstr "" +" **失敗** PageSize %s 需要 PaperDimension\n" +" 參考:第 41 頁,章節 5。\n" +" 參考:第 103 頁,章節 5.15。\n" + +msgid "" +" **FAIL** REQUIRED Product\n" +" REF: Page 62, section 5.3.\n" +msgstr "" +" **失敗** 需要 Product\n" +" 參考:第 62 頁,章節 5.3。\n" + +msgid "" +" **FAIL** REQUIRED ShortNickName\n" +" REF: Page 64-65, section 5.3.\n" +msgstr "" +" **失敗** 需要 ShortNickName\n" +" 參考:第 64-65 頁,章節 5.3。\n" + +#, c-format +msgid " %d ERRORS FOUND\n" +msgstr " 發現 %d 個錯誤\n" + +#, c-format +msgid "" +" Bad %%%%BoundingBox: on line %d!\n" +" REF: Page 39, %%%%BoundingBox:\n" +msgstr "" +" 第 %d 行的 %%%%BoundingBox: 錯誤!\n" +" 參考:第 39 頁,%%%%BoundingBox:\n" + +#, c-format +msgid "" +" Bad %%%%Page: on line %d!\n" +" REF: Page 53, %%%%Page:\n" +msgstr "" +" 第 %d 行的 %%%%Page: 錯誤!\n" +" 參考:第 53 頁,%%%%Page:\n" + +#, c-format +msgid "" +" Bad %%%%Pages: on line %d!\n" +" REF: Page 43, %%%%Pages:\n" +msgstr "" +" 第 %d 行的 %%%%Pages: 錯誤!\n" +" 參考:第 43 頁,%%%%Pages:\n" + +#, c-format +msgid "" +" Line %d is longer than 255 characters (%d)!\n" +" REF: Page 25, Line Length\n" +msgstr "" +" 第 %d 行長度大於 255 個字元(%d)!\n" +" 參考:第 25 頁,行長度\n" + +msgid "" +" Missing %!PS-Adobe-3.0 on first line!\n" +" REF: Page 17, 3.1 Conforming Documents\n" +msgstr "" +" 第一行遺失 %!PS-Adobe-3.0!\n" +" 參考:第 17 頁,3.1 確認文件\n" + +#, c-format +msgid "" +" Missing %%EndComments comment!\n" +" REF: Page 41, %%EndComments\n" +msgstr "" +" 遺失 %%EndComments 註解!\n" +" 參考:第 41 頁,%%EndComments\n" + +#, c-format +msgid "" +" Missing or bad %%BoundingBox: comment!\n" +" REF: Page 39, %%BoundingBox:\n" +msgstr "" +" %%BoundingBox﹕ 註解遺失或錯誤!\n" +" 參考:第 39 頁,%%BoundingBox:\n" + +#, c-format +msgid "" +" Missing or bad %%Page: comments!\n" +" REF: Page 53, %%Page:\n" +msgstr "" +" %%Page: 註解遺失或錯誤!\n" +" 參考:第 53 頁,%%Page:\n" + +#, c-format +msgid "" +" Missing or bad %%Pages: comment!\n" +" REF: Page 43, %%Pages:\n" +msgstr "" +" %%Pages: 註解遺失或錯誤!\n" +" 參考:第 43 頁,%%Pages:\n" + +msgid " NO ERRORS FOUND\n" +msgstr " 未發現錯誤\n" + +#, c-format +msgid " Saw %d lines that exceeded 255 characters!\n" +msgstr " 發現 %d 行超出 255 個字元!\n" + +#, c-format +msgid " Too many %%BeginDocument comments!\n" +msgstr " %%BeginDocument 註解太多!\n" + +#, c-format +msgid " Too many %%EndDocument comments!\n" +msgstr " %%EndDocument 註解太多!\n" + +msgid " Warning: file contains binary data!\n" +msgstr " WARNING: 檔案包含二進位資料!\n" + +#, c-format +msgid " Warning: no %%EndComments comment in file!\n" +msgstr " WARNING: 檔案中沒有 %%EndComments 註解!\n" + +#, c-format +msgid " Warning: obsolete DSC version %.1f in file!\n" +msgstr " WARNING: 檔案中的 DSC 版本 %.1f 已過時!\n" + +msgid " FAIL\n" +msgstr " 失敗\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s\n" +msgstr "" +" 失敗\n" +" **失敗** 無法打開 PPD 檔案 - %s\n" + +#, c-format +msgid "" +" FAIL\n" +" **FAIL** Unable to open PPD file - %s on line %d.\n" +msgstr "" +" 失敗\n" +" **失敗** 無法打開 PPD 檔案 - 第 %2$d 行的 %1$s。\n" + +msgid " PASS\n" +msgstr " 通過\n" + +msgid "#10 Envelope" +msgstr "#10 信封" + +msgid "#11 Envelope" +msgstr "#11 信封" + +msgid "#12 Envelope" +msgstr "#12 信封" + +msgid "#14 Envelope" +msgstr "#14 信封" + +msgid "#9 Envelope" +msgstr "#9 信封" + +#, c-format +msgid "%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n" +msgstr "%-6s %-10.10s %-4d %-10d %-27.27s %.0f byte\n" + +#, c-format +msgid "%-7s %-7.7s %-7d %-31.31s %.0f bytes\n" +msgstr "%-7s %-7.7s %-7d %-31.31s %.0f byte\n" + +#, c-format +msgid "%.0f x %.0f millimeters" +msgstr "%.0f x %.0f 公釐" + +#, c-format +msgid "%.0f x %.0f to %.0f x %.0f millimeters" +msgstr "%.0f x %.0f to %.0f x %.0f 公釐" + +#, c-format +msgid "%.2f x %.2f inches" +msgstr "%.2f x %.2f 英吋" + +#, c-format +msgid "%.2f x %.2f to %.2f x %.2f inches" +msgstr "%.2f x %.2f to %.2f x %.2f 英吋" + +#, c-format +msgid "%s accepting requests since %s\n" +msgstr "%s 自 %s 後接受請求\n" + +#, c-format +msgid "%s cannot be changed." +msgstr "無法更改 %s。" + +#, c-format +msgid "%s is not implemented by the CUPS version of lpc.\n" +msgstr "%s 未由 CUPS 版本 lpc 執行。\n" + +#, c-format +msgid "%s is not ready\n" +msgstr "%s 尚未備妥\n" + +#, c-format +msgid "%s is ready\n" +msgstr "%s 已備妥\n" + +#, c-format +msgid "%s is ready and printing\n" +msgstr "%s 已備妥列印\n" + +#, c-format +msgid "" +"%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s 自 %s 後不接受請求 -\n" +"\t%s\n" + +#, c-format +msgid "%s not supported!" +msgstr "不支援 %s!" + +#, c-format +msgid "%s/%s accepting requests since %s\n" +msgstr "%s/%s 自 %s 後接受請求\n" + +#, c-format +msgid "" +"%s/%s not accepting requests since %s -\n" +"\t%s\n" +msgstr "" +"%s/%s 自 %s 後不接受請求 -\n" +"\t%s\n" + +#, c-format +msgid "%s: %-33.33s [job %d localhost]\n" +msgstr "%s:%-33.33s [作業 %d localhost]\n" + +#, c-format +msgid "%s: %s failed: %s\n" +msgstr "%s:%s 失敗:%s\n" + +#, c-format +msgid "%s: Don't know what to do!\n" +msgstr "%s:不知道要執行的動作!\n" + +#, c-format +msgid "" +"%s: Error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s:錯誤 - %s 環境變數名稱中有不存在的目的地“%s”!\n" + +#, c-format +msgid "%s: Error - bad job ID!\n" +msgstr "%s:錯誤 - 作業 ID 錯誤!\n" + +#, c-format +msgid "%s: Error - cannot print files and alter jobs simultaneously!\n" +msgstr "%s:錯誤 - 無法列印檔案並同時更改作業!\n" + +#, c-format +msgid "" +"%s: Error - cannot print from stdin if files or a job ID are provided!\n" +msgstr "%s:錯誤 - 在提供檔案或作業 ID 的情況下無法從 stdin 進行列印!\n" + +#, c-format +msgid "%s: Error - expected character set after '-S' option!\n" +msgstr "%s:錯誤 - '-S' 選項後面預期為字元集!\n" + +#, c-format +msgid "%s: Error - expected content type after '-T' option!\n" +msgstr "%s:錯誤 - '-T' 選項後面預期為內容類型!\n" + +#, c-format +msgid "%s: Error - expected copies after '-n' option!\n" +msgstr "%s:錯誤 - '-n' 選項後面預期為份數!\n" + +#, c-format +msgid "%s: Error - expected copy count after '-#' option!\n" +msgstr "%s:錯誤 - '-#' 選項後面預期為複本計數!\n" + +#, c-format +msgid "%s: Error - expected destination after '-P' option!\n" +msgstr "%s:錯誤 - '-P' 選項後面預期為目的地!\n" + +#, c-format +msgid "%s: Error - expected destination after '-b' option!\n" +msgstr "%s:錯誤 - '-b' 選項後面預期為目的地!\n" + +#, c-format +msgid "%s: Error - expected destination after '-d' option!\n" +msgstr "%s:錯誤 - '-d' 選項後面預期為目的地!\n" + +#, c-format +msgid "%s: Error - expected form after '-f' option!\n" +msgstr "%s:錯誤 - '-f' 選項後面預期為表單!\n" + +#, c-format +msgid "%s: Error - expected hold name after '-H' option!\n" +msgstr "%s:錯誤 - '-H' 選項後面預期為保留名稱!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-H' option!\n" +msgstr "%s:錯誤 - '-H' 選項後面預期為主機名稱!\n" + +#, c-format +msgid "%s: Error - expected hostname after '-h' option!\n" +msgstr "%s:錯誤 - '-h' 選項後面預期為主機名稱!\n" + +#, c-format +msgid "%s: Error - expected mode list after '-y' option!\n" +msgstr "%s:錯誤 - '-y' 選項後面預期為模式列表!\n" + +#, c-format +msgid "%s: Error - expected name after '-%c' option!\n" +msgstr "%s:錯誤 - '-%c' 選項後面預期為名稱!\n" + +#, c-format +msgid "%s: Error - expected option string after '-o' option!\n" +msgstr "%s:錯誤 - '-o' 選項後面預期為選項字串!\n" + +#, c-format +msgid "%s: Error - expected page list after '-P' option!\n" +msgstr "%s:錯誤 - '-P' 選項後面預期為頁面列表!\n" + +#, c-format +msgid "%s: Error - expected priority after '-%c' option!\n" +msgstr "%s:錯誤 - '-%c' 選項後面預期為優先順序!\n" + +#, c-format +msgid "%s: Error - expected reason text after '-r' option!\n" +msgstr "%s:錯誤 - '-r' 選項後面預期為原因文字!\n" + +#, c-format +msgid "%s: Error - expected title after '-t' option!\n" +msgstr "%s:錯誤 - '-t' 選項後面預期為標題!\n" + +#, c-format +msgid "%s: Error - expected username after '-U' option!\n" +msgstr "%s:錯誤 - '-U' 選項後面預期為使用者名稱!\n" + +#, c-format +msgid "%s: Error - expected username after '-u' option!\n" +msgstr "%s:錯誤 - '-u' 選項後面預期為使用者名稱!\n" + +#, c-format +msgid "%s: Error - expected value after '-%c' option!\n" +msgstr "%s:錯誤 - '-%c' 選項後面預期為值!\n" + +#, c-format +msgid "" +"%s: Error - need \"completed\", \"not-completed\", or \"all\" after '-W' " +"option!\n" +msgstr "" +"%s:錯誤 - &aops;-W&aops; 選項後面需要“completed”、“not-completed”或“all”!\n" + +#, c-format +msgid "%s: Error - no default destination available.\n" +msgstr "%s:錯誤 - 無可用的預設目的地。\n" + +#, c-format +msgid "%s: Error - priority must be between 1 and 100.\n" +msgstr "%s:錯誤 - 優先順序必須介於 1 和 100 之間。\n" + +#, c-format +msgid "%s: Error - scheduler not responding!\n" +msgstr "%s:錯誤 - 排程器沒有回應!\n" + +#, c-format +msgid "%s: Error - too many files - \"%s\"\n" +msgstr "%s:錯誤 - 檔案太多 -“%s”\n" + +#, c-format +msgid "%s: Error - unable to access \"%s\" - %s\n" +msgstr "%s:錯誤 - 無法存取“%s”- %s\n" + +#, c-format +msgid "%s: Error - unable to queue from stdin - %s\n" +msgstr "%s:錯誤 - 無法從 stdin 佇列 - %s\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s\"!\n" +msgstr "%s:錯誤 - 未知的目的地“%s”!\n" + +#, c-format +msgid "%s: Error - unknown destination \"%s/%s\"!\n" +msgstr "%s:錯誤 - 未知的目的地“%s/%s”!\n" + +#, c-format +msgid "%s: Error - unknown option '%c'!\n" +msgstr "%s:錯誤 - 未知的選項 '%c'!\n" + +#, c-format +msgid "%s: Error - unknown option '%s'!\n" +msgstr "%s:錯誤 - 未知的選項 '%s'!\n" + +#, c-format +msgid "%s: Expected job ID after '-i' option!\n" +msgstr "%s:'-i' 選項後面預期為作業 ID!\n" + +#, c-format +msgid "%s: Filter \"%s\" not available: %s\n" +msgstr "%s:無法使用濾鏡“%s”:%s\n" + +#, c-format +msgid "%s: Invalid destination name in list \"%s\"!\n" +msgstr "%s:列表“%s”中的目的地名稱無效!\n" + +#, c-format +msgid "%s: Invalid filter string \"%s\"\n" +msgstr "%s:過濾字串“%s”無效\n" + +#, c-format +msgid "%s: Need job ID ('-i jobid') before '-H restart'!\n" +msgstr "%s:&aops;-H restart&aops; 前面需要作業 ID('-i jobid')!\n" + +#, c-format +msgid "%s: No filter to convert from %s/%s to %s/%s!\n" +msgstr "%s:沒有濾鏡要從 %s/%s 轉換為 %s/%s!\n" + +#, c-format +msgid "%s: Operation failed: %s\n" +msgstr "%s:作業失敗:%s\n" + +#, c-format +msgid "%s: Sorry, no encryption support compiled in!\n" +msgstr "%s:抱歉,未編譯入加密支援!\n" + +#, c-format +msgid "%s: Unable to connect to server\n" +msgstr "%s:無法連接伺服器\n" + +#, c-format +msgid "%s: Unable to contact server!\n" +msgstr "%s:無法聯絡伺服器!\n" + +#, c-format +msgid "%s: Unable to determine MIME type of \"%s\"!\n" +msgstr "%s:無法確定“%s”的 MIME 類型!\n" + +#, c-format +msgid "%s: Unable to open %s: %s\n" +msgstr "%s:無法打開 %s:%s\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d\n" +msgstr "%s:無法打開 PPD 檔案:%s 在第 %d 行\n" + +#, c-format +msgid "%s: Unable to open PPD file: %s on line %d.\n" +msgstr "" + +#, c-format +msgid "%s: Unable to read MIME database from \"%s\" or \"%s\"!\n" +msgstr "%s:無法從“%s”或“%s”讀取 MIME 資料庫!\n" + +#, c-format +msgid "%s: Unknown destination \"%s\"!\n" +msgstr "%s:未知的目的地“%s”!\n" + +#, c-format +msgid "%s: Unknown destination MIME type %s/%s!\n" +msgstr "%s:未知的目的地 MIME 類型 %s/%s!\n" + +#, c-format +msgid "%s: Unknown option '%c'!\n" +msgstr "%s:未知的選項 '%c'!\n" + +#, c-format +msgid "%s: Unknown source MIME type %s/%s!\n" +msgstr "%s:未知的來源 MIME 類型 %s/%s!\n" + +#, c-format +msgid "" +"%s: Warning - '%c' format modifier not supported - output may not be " +"correct!\n" +msgstr "%s:警告 - 不支援 '%c' 格式修飾符 - 輸出可能不正確!\n" + +#, c-format +msgid "%s: Warning - character set option ignored!\n" +msgstr "%s:警告 - 已忽略字元集選項!\n" + +#, c-format +msgid "%s: Warning - content type option ignored!\n" +msgstr "%s:警告 - 已忽略內容類型選項!\n" + +#, c-format +msgid "%s: Warning - form option ignored!\n" +msgstr "%s:警告 - 已忽略表單選項!\n" + +#, c-format +msgid "%s: Warning - mode option ignored!\n" +msgstr "%s:警告 - 已忽略模式選項!\n" + +#, c-format +msgid "" +"%s: error - %s environment variable names non-existent destination \"%s\"!\n" +msgstr "%s:錯誤 - %s 環境變數名稱中有不存在的目的地“%s”!\n" + +#, c-format +msgid "%s: error - expected option=value after '-o' option!\n" +msgstr "%s:錯誤 - &aops;-o&aops; 選項後面預期為 option=value!\n" + +#, c-format +msgid "%s: error - no default destination available.\n" +msgstr "%s:錯誤 - 沒有可用的預設目的地。\n" + +msgid "-1" +msgstr "-1" + +msgid "-10" +msgstr "-10" + +msgid "-100" +msgstr "-100" + +msgid "-105" +msgstr "-105" + +msgid "-11" +msgstr "-11" + +msgid "-110" +msgstr "-110" + +msgid "-115" +msgstr "-115" + +msgid "-12" +msgstr "-12" + +msgid "-120" +msgstr "-120" + +msgid "-13" +msgstr "-13" + +msgid "-14" +msgstr "-14" + +msgid "-15" +msgstr "-15" + +msgid "-2" +msgstr "-2" + +msgid "-20" +msgstr "-20" + +msgid "-25" +msgstr "-25" + +msgid "-3" +msgstr "-3" + +msgid "-30" +msgstr "-30" + +msgid "-35" +msgstr "-35" + +msgid "-4" +msgstr "-4" + +msgid "-40" +msgstr "-40" + +msgid "-45" +msgstr "-45" + +msgid "-5" +msgstr "-5" + +msgid "-50" +msgstr "-50" + +msgid "-55" +msgstr "-55" + +msgid "-6" +msgstr "-6" + +msgid "-60" +msgstr "-60" + +msgid "-65" +msgstr "-65" + +msgid "-7" +msgstr "-7" + +msgid "-70" +msgstr "-70" + +msgid "-75" +msgstr "-75" + +msgid "-8" +msgstr "-8" + +msgid "-80" +msgstr "-80" + +msgid "-85" +msgstr "-85" + +msgid "-9" +msgstr "-9" + +msgid "-90" +msgstr "-90" + +msgid "-95" +msgstr "-95" + +msgid "0" +msgstr "0" + +msgid "1" +msgstr "1" + +msgid "1 inch/sec." +msgstr "1 英吋∕秒" + +msgid "1.25x0.25\"" +msgstr "1.25x0.25\"" + +msgid "1.25x2.25\"" +msgstr "1.25x2.25\"" + +msgid "1.5 inch/sec." +msgstr "1.5 英吋∕秒" + +msgid "1.50x0.25\"" +msgstr "1.50x0.25\"" + +msgid "1.50x0.50\"" +msgstr "1.50x0.50\"" + +msgid "1.50x1.00\"" +msgstr "1.50x1.00\"" + +msgid "1.50x2.00\"" +msgstr "1.50x2.00\"" + +msgid "10" +msgstr "10" + +msgid "10 inches/sec." +msgstr "10 英吋∕秒" + +msgid "10 x 11\"" +msgstr "10 x 11\"" + +msgid "10 x 13\"" +msgstr "10 x 13\"" + +msgid "10 x 14\"" +msgstr "10 x 14\"" + +msgid "100" +msgstr "100" + +msgid "100 mm/sec." +msgstr "100 公釐∕秒" + +msgid "105" +msgstr "105" + +msgid "11" +msgstr "11" + +msgid "11 inches/sec." +msgstr "11 英吋∕秒" + +msgid "110" +msgstr "110" + +msgid "115" +msgstr "115" + +msgid "12" +msgstr "12" + +msgid "12 inches/sec." +msgstr "12 英吋∕秒" + +msgid "12 x 11\"" +msgstr "12 x 11\"" + +msgid "120" +msgstr "120" + +msgid "120 mm/sec." +msgstr "120 公釐∕秒" + +msgid "120x60dpi" +msgstr "120x60dpi" + +msgid "120x72dpi" +msgstr "120x72dpi" + +msgid "13" +msgstr "13" + +msgid "136dpi" +msgstr "136dpi" + +msgid "14" +msgstr "14" + +msgid "15" +msgstr "15" + +msgid "15 mm/sec." +msgstr "15 公釐∕秒" + +msgid "15 x 11\"" +msgstr "15 x 11\"" + +msgid "150 mm/sec." +msgstr "150 公釐∕秒" + +msgid "150dpi" +msgstr "150dpi" + +msgid "16" +msgstr "16" + +msgid "17" +msgstr "17" + +msgid "18" +msgstr "18" + +msgid "180dpi" +msgstr "180dpi" + +msgid "19" +msgstr "19" + +msgid "2" +msgstr "2" + +msgid "2 inches/sec." +msgstr "2 英吋∕秒" + +msgid "2-Sided Printing" +msgstr "雙面列印" + +msgid "2.00x0.37\"" +msgstr "2.00x0.37\"" + +msgid "2.00x0.50\"" +msgstr "2.00x0.50\"" + +msgid "2.00x1.00\"" +msgstr "2.00x1.00\"" + +msgid "2.00x1.25\"" +msgstr "2.00x1.25\"" + +msgid "2.00x2.00\"" +msgstr "2.00x2.00\"" + +msgid "2.00x3.00\"" +msgstr "2.00x3.00\"" + +msgid "2.00x4.00\"" +msgstr "2.00x4.00\"" + +msgid "2.00x5.50\"" +msgstr "2.00x5.50\"" + +msgid "2.25x0.50\"" +msgstr "2.25x0.50\"" + +msgid "2.25x1.25\"" +msgstr "2.25x1.25\"" + +msgid "2.25x4.00\"" +msgstr "2.25x4.00\"" + +msgid "2.25x5.50\"" +msgstr "2.25x5.50\"" + +msgid "2.38x5.50\"" +msgstr "2.38x5.50\"" + +msgid "2.5 inches/sec." +msgstr "2.5 英吋∕秒" + +msgid "2.50x1.00\"" +msgstr "2.50x1.00\"" + +msgid "2.50x2.00\"" +msgstr "2.50x2.00\"" + +msgid "2.75x1.25\"" +msgstr "2.75x1.25\"" + +msgid "2.9 x 1\"" +msgstr "2.9 x 1\"" + +msgid "20" +msgstr "20" + +msgid "20 mm/sec." +msgstr "20 公釐∕秒" + +msgid "200 mm/sec." +msgstr "200 公釐∕秒" + +msgid "203dpi" +msgstr "203dpi" + +msgid "21" +msgstr "21" + +msgid "22" +msgstr "22" + +msgid "23" +msgstr "23" + +msgid "24" +msgstr "24" + +msgid "24-Pin Series" +msgstr "24-Pin 系列" + +msgid "240x72dpi" +msgstr "240x72dpi" + +msgid "25" +msgstr "25" + +msgid "250 mm/sec." +msgstr "250 公釐∕秒" + +msgid "26" +msgstr "26" + +msgid "27" +msgstr "27" + +msgid "28" +msgstr "28" + +msgid "29" +msgstr "29" + +msgid "3" +msgstr "3" + +msgid "3 inches/sec." +msgstr "3 英吋∕秒" + +msgid "3.00x1.00\"" +msgstr "3.00x1.00\"" + +msgid "3.00x1.25\"" +msgstr "3.00x1.25\"" + +msgid "3.00x2.00\"" +msgstr "3.00x2.00\"" + +msgid "3.00x3.00\"" +msgstr "3.00x3.00\"" + +msgid "3.00x5.00\"" +msgstr "3.00x5.00\"" + +msgid "3.25x2.00\"" +msgstr "3.25x2.00\"" + +msgid "3.25x5.00\"" +msgstr "3.25x5.00\"" + +msgid "3.25x5.50\"" +msgstr "3.25x5.50\"" + +msgid "3.25x5.83\"" +msgstr "3.25x5.83\"" + +msgid "3.25x7.83\"" +msgstr "3.25x7.83\"" + +msgid "3.5\" Disk" +msgstr "3.5 吋磁碟" + +msgid "3.5\" Disk - 2 1/8 x 2 3/4\"" +msgstr "3.5 吋磁碟 - 2 1/8 x 2 3/4\"" + +msgid "3.50x1.00\"" +msgstr "3.50x1.00\"" + +msgid "30" +msgstr "30" + +msgid "30 mm/sec." +msgstr "30 公釐∕秒" + +msgid "300 mm/sec." +msgstr "300 公釐∕秒" + +msgid "300dpi" +msgstr "300dpi" + +msgid "35" +msgstr "35" + +msgid "360dpi" +msgstr "360dpi" + +msgid "360x180dpi" +msgstr "360x180dpi" + +msgid "4" +msgstr "4" + +msgid "4 inches/sec." +msgstr "4 英吋∕秒" + +msgid "4.00x1.00\"" +msgstr "4.00x1.00\"" + +msgid "4.00x13.00\"" +msgstr "4.00x13.00\"" + +msgid "4.00x2.00\"" +msgstr "4.00x2.00\"" + +msgid "4.00x2.50\"" +msgstr "4.00x2.50\"" + +msgid "4.00x3.00\"" +msgstr "4.00x3.00\"" + +msgid "4.00x4.00\"" +msgstr "4.00x4.00\"" + +msgid "4.00x5.00\"" +msgstr "4.00x5.00\"" + +msgid "4.00x6.00\"" +msgstr "4.00x6.00\"" + +msgid "4.00x6.50\"" +msgstr "4.00x6.50\"" + +msgid "40" +msgstr "40" + +msgid "40 mm/sec." +msgstr "40 公釐∕秒" + +msgid "45" +msgstr "45" + +msgid "5" +msgstr "5" + +msgid "5 inches/sec." +msgstr "5 英吋∕秒" + +msgid "50" +msgstr "50" + +msgid "55" +msgstr "55" + +msgid "6" +msgstr "6" + +msgid "6 inches/sec." +msgstr "6 英吋∕秒" + +msgid "6.00x1.00\"" +msgstr "6.00x1.00\"" + +msgid "6.00x2.00\"" +msgstr "6.00x2.00\"" + +msgid "6.00x3.00\"" +msgstr "6.00x3.00\"" + +msgid "6.00x4.00\"" +msgstr "6.00x4.00\"" + +msgid "6.00x5.00\"" +msgstr "6.00x5.00\"" + +msgid "6.00x6.00\"" +msgstr "6.00x6.00\"" + +msgid "6.00x6.50\"" +msgstr "6.00x6.50\"" + +msgid "60" +msgstr "60" + +msgid "60 mm/sec." +msgstr "60 公釐∕秒" + +msgid "600dpi" +msgstr "600dpi" + +msgid "60dpi" +msgstr "60dpi" + +msgid "60x720dpi" +msgstr "60x720dpi" + +msgid "65" +msgstr "65" + +msgid "7" +msgstr "7" + +msgid "7 inches/sec." +msgstr "7 英吋∕秒" + +msgid "7 x 9\"" +msgstr "7 x 9\"" + +msgid "70" +msgstr "70" + +msgid "720dpi" +msgstr "720dpi" + +msgid "75" +msgstr "75" + +msgid "8" +msgstr "8" + +msgid "8 inches/sec." +msgstr "8 英吋∕秒" + +msgid "8 x 10\"" +msgstr "8 x 10\"" + +msgid "8.00x1.00\"" +msgstr "8.00x1.00\"" + +msgid "8.00x2.00\"" +msgstr "8.00x2.00\"" + +msgid "8.00x3.00\"" +msgstr "8.00x3.00\"" + +msgid "8.00x4.00\"" +msgstr "8.00x4.00\"" + +msgid "8.00x5.00\"" +msgstr "8.00x5.00\"" + +msgid "8.00x6.00\"" +msgstr "8.00x6.00\"" + +msgid "8.00x6.50\"" +msgstr "8.00x6.50\"" + +msgid "80" +msgstr "80" + +msgid "80 mm/sec." +msgstr "80 公釐∕秒" + +msgid "85" +msgstr "85" + +msgid "9" +msgstr "9" + +msgid "9 inches/sec." +msgstr "9 英吋∕秒" + +msgid "9 x 11\"" +msgstr "9 x 11\"" + +msgid "9 x 12\"" +msgstr "9 x 12\"" + +msgid "9-Pin Series" +msgstr "9-Pin 系列" + +msgid "90" +msgstr "90" + +msgid "95" +msgstr "95" + +msgid "?Invalid help command unknown\n" +msgstr "?無效的輔助說明指令未知\n" + +msgid "A Samba password is required to export printer drivers!" +msgstr "需要 Samba 密碼,才能輸出印表機驅動程式!" + +msgid "A Samba username is required to export printer drivers!" +msgstr "需要 Samba 使用者名稱,才能輸出印表機驅動程式!" + +#, c-format +msgid "A class named \"%s\" already exists!" +msgstr "名為“%s”的類別已存在!" + +#, c-format +msgid "A printer named \"%s\" already exists!" +msgstr "名為“%s”的印表機已存在!" + +msgid "A0" +msgstr "A0" + +msgid "A1" +msgstr "A1" + +msgid "A10" +msgstr "A10" + +msgid "A2" +msgstr "A2" + +msgid "A3" +msgstr "A3" + +msgid "A3 (Oversize)" +msgstr "A3(超大型)" + +msgid "A4" +msgstr "A4" + +msgid "A4 (Oversize)" +msgstr "A4(超大型)" + +msgid "A4 (Small)" +msgstr "A4(小型)" + +msgid "A5" +msgstr "A5" + +msgid "A5 (Oversize)" +msgstr "A5(超大型)" + +msgid "A6" +msgstr "A6" + +msgid "A7" +msgstr "A7" + +msgid "A8" +msgstr "A8" + +msgid "A9" +msgstr "A9" + +msgid "ANSI A" +msgstr "ANSI A" + +msgid "ANSI B" +msgstr "ANSI B" + +msgid "ANSI C" +msgstr "ANSI C" + +msgid "ANSI D" +msgstr "ANSI D" + +msgid "ANSI E" +msgstr "ANSI E" + +msgid "ARCH A" +msgstr "ARCH A" + +msgid "ARCH B" +msgstr "ARCH B" + +msgid "ARCH C" +msgstr "ARCH C" + +msgid "ARCH D" +msgstr "ARCH D" + +msgid "ARCH E" +msgstr "ARCH E" + +msgid "Accept Jobs" +msgstr "接受作業" + +msgid "Accepted" +msgstr "已接受" + +msgid "Add Class" +msgstr "加入類別" + +msgid "Add Printer" +msgstr "新增印表機" + +msgid "Add RSS Subscription" +msgstr "新增 RSS 訂閱" + +msgid "Address" +msgstr "地址" + +msgid "Address - 1 1/8 x 3 1/2\"" +msgstr "地址 - 1 1/8 x 3 1/2\"" + +msgid "Administration" +msgstr "管理" + +msgid "Always" +msgstr "總是" + +msgid "AppSocket/HP JetDirect" +msgstr "AppSocket/HP JetDirect" + +msgid "Applicator" +msgstr "噴頭" + +#, c-format +msgid "Attempt to set %s printer-state to bad value %d!" +msgstr "嘗試將 %s 印表機狀態設為錯誤的值 %d!" + +#, c-format +msgid "Attribute groups are out of order (%x < %x)!" +msgstr "屬性群組有問題(%x < %x)!" + +msgid "B0" +msgstr "B0" + +msgid "B1" +msgstr "B1" + +msgid "B10" +msgstr "B10" + +msgid "B2" +msgstr "B2" + +msgid "B3" +msgstr "B3" + +msgid "B4" +msgstr "B4" + +msgid "B5" +msgstr "B5" + +msgid "B6" +msgstr "B6" + +msgid "B7" +msgstr "B7" + +msgid "B8" +msgstr "B8" + +msgid "B9" +msgstr "B9" + +msgid "Bad NULL dests pointer" +msgstr "NULL dests 指標錯誤" + +msgid "Bad OpenGroup" +msgstr "OpenGroup 錯誤" + +msgid "Bad OpenUI/JCLOpenUI" +msgstr "OpenUI/JCLOpenUI 錯誤" + +msgid "Bad OrderDependency" +msgstr "OrderDependency 錯誤" + +msgid "Bad Request" +msgstr "請求錯誤" + +msgid "Bad SNMP version number" +msgstr "SNMP 版本號碼錯誤" + +msgid "Bad UIConstraints" +msgstr "UIConstraints 錯誤" + +#, c-format +msgid "Bad copies value %d." +msgstr "列印份數值 %d 錯誤。" + +msgid "Bad custom parameter" +msgstr "自定參數錯誤" + +#, c-format +msgid "Bad device URI \"%s\"!\n" +msgstr "設備 URI“%s”錯誤!\n" + +#, c-format +msgid "Bad device-uri \"%s\"!" +msgstr "device-uri“%s”錯誤!" + +#, c-format +msgid "Bad device-uri scheme \"%s\"!" +msgstr "device-uri 架構“%s”錯誤!" + +#, c-format +msgid "Bad document-format \"%s\"!" +msgstr "document-format“%s”錯誤!" + +msgid "Bad filename buffer!" +msgstr "檔名緩衝區錯誤!" + +#, c-format +msgid "Bad font attribute: %s\n" +msgstr "字體屬性ERROR: %s\n" + +msgid "Bad job-priority value!" +msgstr "job-priority 值錯誤!" + +#, c-format +msgid "Bad job-sheets value \"%s\"!" +msgstr "job-sheets 值“%s”錯誤!" + +msgid "Bad job-sheets value type!" +msgstr "job-sheets 值類型錯誤!" + +msgid "Bad job-state value!" +msgstr "job-state 值錯誤!" + +#, c-format +msgid "Bad job-uri attribute \"%s\"!" +msgstr "job-uri 屬性“%s”錯誤!" + +#, c-format +msgid "Bad notify-pull-method \"%s\"!" +msgstr "notify-pull-method“%s”錯誤!" + +#, c-format +msgid "Bad notify-recipient-uri URI \"%s\"!" +msgstr "notify-recipient-uri URI“%s”錯誤!" + +#, c-format +msgid "Bad number-up value %d." +msgstr "number-up 值 %d 錯誤。" + +#, c-format +msgid "Bad option + choice on line %d!" +msgstr "第 %d 行的 option + choice 錯誤!" + +#, c-format +msgid "Bad page-ranges values %d-%d." +msgstr "page-ranges 值 %d-%d 錯誤。" + +#, c-format +msgid "Bad port-monitor \"%s\"!" +msgstr "port-monitor“%s”錯誤!" + +#, c-format +msgid "Bad printer-state value %d!" +msgstr "printer-state 值 %d 錯誤!" + +#, c-format +msgid "Bad request ID %d!" +msgstr "" + +#, c-format +msgid "Bad request version number %d.%d!" +msgstr "請求版本號碼 %d.%d 錯誤!" + +msgid "Bad subscription ID!" +msgstr "訂閱 ID 錯誤!" + +msgid "Banners" +msgstr "標語" + +msgid "Billing Information: " +msgstr "文件封面INFO: " + +msgid "Bond Paper" +msgstr "證券紙" + +msgid "C0 Envelope" +msgstr "C0 信封" + +msgid "C1 Envelope" +msgstr "C1 信封" + +msgid "C2 Envelope" +msgstr "C2 信封" + +msgid "C3 Envelope" +msgstr "C3 信封" + +msgid "C4" +msgstr "C4" + +msgid "C4 Envelope" +msgstr "C4 信封" + +msgid "C5" +msgstr "C5" + +msgid "C5 Envelope" +msgstr "C5 信封" + +msgid "C6" +msgstr "C6" + +msgid "C6 Envelope" +msgstr "C6 信封" + +msgid "C65 Envelope" +msgstr "C65 信封" + +msgid "C7 Envelope" +msgstr "C7 信封" + +msgid "CMYK" +msgstr "CMYK" + +msgid "CPCL Label Printer" +msgstr "CPCL 標籤印表機" + +msgid "Cancel RSS Subscription" +msgstr "取消 RSS 訂閱" + +msgid "Change Settings" +msgstr "更改設定" + +#, c-format +msgid "Character set \"%s\" not supported!" +msgstr "不支援字元集“%s”!" + +msgid "Chou3 Envelope" +msgstr "Chou3 信封" + +msgid "Chou4 Envelope" +msgstr "Chou4 信封" + +msgid "Classes" +msgstr "類別" + +msgid "Clean Print Heads" +msgstr "乾淨的列印頭" + +msgid "Color" +msgstr "顏色" + +msgid "Color Mode" +msgstr "顏色模式" + +msgid "" +"Commands may be abbreviated. Commands are:\n" +"\n" +"exit help quit status ?\n" +msgstr "" +"指令可以簡寫。指令為:\n" +"\n" +"exit help quit status ?\n" + +msgid "Community name uses indefinite length" +msgstr "社群名稱使用的長度不確定" + +msgid "Continue" +msgstr "繼續" + +msgid "Continuous" +msgstr "連續" + +#, c-format +msgid "Could not scan type \"%s\"!" +msgstr "無法掃描類型“%s”!" + +msgid "Cover open." +msgstr "機蓋已打開。" + +msgid "Created" +msgstr "已製作" + +msgid "Created On: " +msgstr "製作日期:" + +msgid "Custom" +msgstr "自定" + +msgid "CustominCutInterval" +msgstr "CustominCutInterval" + +msgid "CustominTearInterval" +msgstr "CustominTearInterval" + +msgid "Cut" +msgstr "剪下" + +msgid "Cutter" +msgstr "剪下程式" + +msgid "DL" +msgstr "DL" + +msgid "DL Envelope" +msgstr "DL 信封" + +msgid "Dark" +msgstr "暗" + +msgid "Darkness" +msgstr "暗" + +msgid "Delete Class" +msgstr "刪除類別" + +msgid "Delete Printer" +msgstr "刪除印表機" + +msgid "Description: " +msgstr "描述:" + +msgid "DeskJet Series" +msgstr "DeskJet 系列" + +#, c-format +msgid "Destination \"%s\" is not accepting jobs." +msgstr "目的地“%s”不接受作業。" + +msgid "Developer almost empty." +msgstr "顯像劑即將耗盡。" + +msgid "Developer empty!" +msgstr "顯像劑已耗盡!" + +#, c-format +msgid "" +"Device: uri = %s\n" +" class = %s\n" +" info = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +" location = %s\n" +msgstr "" +"設備:uri = %s\n" +" 類別 = %s\n" +" 資訊 = %s\n" +" 製造和型號 = %s\n" +" 設備 ID = %s\n" +" 位置 = %s\n" + +msgid "Direct Thermal Media" +msgstr "直接熱感媒體" + +msgid "Disabled" +msgstr "已停用" + +#, c-format +msgid "Document %d not found in job %d." +msgstr "文件 %d 在作業 %d 中找不到。" + +msgid "Door open." +msgstr "機門已打開。" + +msgid "Double Postcard" +msgstr "雙明信片" + +msgid "Driver Name: " +msgstr "驅動程式名稱:" + +msgid "Driver Version: " +msgstr "驅動程式版本:" + +msgid "Duplexer" +msgstr "Duplexer" + +msgid "Dymo" +msgstr "Dymo" + +#, c-format +msgid "EMERG: Unable to allocate memory for page info: %s\n" +msgstr "EMERG: 無法為頁面資訊分配記憶體:%s\n" + +#, c-format +msgid "EMERG: Unable to allocate memory for pages array: %s\n" +msgstr "EMERG: 無法為頁面陣列分配記憶體:%s\n" + +msgid "EPL1 Label Printer" +msgstr "EPL1 標籤印表機" + +msgid "EPL2 Label Printer" +msgstr "EPL2 標籤印表機" + +#, c-format +msgid "ERROR: %s job-id user title copies options [file]\n" +msgstr "" + +#, c-format +msgid "ERROR: Bad %%BoundingBox: comment seen!\n" +msgstr "ERROR: %%BoundingBox ERROR: 發現有註解!\n" + +#, c-format +msgid "ERROR: Bad %%IncludeFeature: comment!\n" +msgstr "ERROR: %%IncludeFeature ERROR: 註解!\n" + +#, c-format +msgid "ERROR: Bad %%Page: comment in file!\n" +msgstr "ERROR: %%Page ERROR: 檔案中的註解!\n" + +#, c-format +msgid "ERROR: Bad %%PageBoundingBox: comment in file!\n" +msgstr "ERROR: %%PageBoundingBox ERROR: 檔案中的註解!\n" + +#, c-format +msgid "ERROR: Bad SCSI device file \"%s\"!\n" +msgstr "ERROR: SCSI 設備檔案“%s”錯誤!\n" + +#, c-format +msgid "ERROR: Bad charset file %s\n" +msgstr "ERROR: 字元集檔案 %s 錯誤\n" + +#, c-format +msgid "ERROR: Bad charset type %s\n" +msgstr "ERROR: 字元集類型 %s 錯誤\n" + +#, c-format +msgid "ERROR: Bad columns value %d!\n" +msgstr "ERROR: 直欄值 %d 錯誤!\n" + +#, c-format +msgid "ERROR: Bad cpi value %f!\n" +msgstr "ERROR: cpi 值 %f 錯誤!\n" + +#, c-format +msgid "ERROR: Bad font description line: %s\n" +msgstr "ERROR: 字體描述行ERROR: %s\n" + +#, c-format +msgid "ERROR: Bad lpi value %f!\n" +msgstr "ERROR: lpi 值 %f 錯誤!\n" + +msgid "ERROR: Bad page setup!\n" +msgstr "ERROR: 頁面設定錯誤!\n" + +#, c-format +msgid "ERROR: Bad text direction %s\n" +msgstr "ERROR: 文字方向 %s 錯誤\n" + +#, c-format +msgid "ERROR: Bad text width %s\n" +msgstr "ERROR: 文字寬度 %s 錯誤\n" + +msgid "ERROR: Destination printer does not exist!\n" +msgstr "ERROR: 目的印表機不存在!\n" + +#, c-format +msgid "ERROR: Duplicate %%BoundingBox: comment seen!\n" +msgstr "ERROR: 重複的 %%BoundingBox:發現有註解!\n" + +#, c-format +msgid "ERROR: Duplicate %%Pages: comment seen!\n" +msgstr "ERROR: 重複的 %%Pages:發現有註解!\n" + +msgid "ERROR: Empty print file!\n" +msgstr "ERROR: 列印檔案為空!\n" + +#, c-format +msgid "ERROR: Error %d sending PAPSendData request: %s\n" +msgstr "ERROR: %d 傳送 PAPSendData 請求時發生ERROR: %s\n" + +#, c-format +msgid "ERROR: Expected quoted string on line %d of %s!\n" +msgstr "ERROR: %2$s 的第 %1$d 行預期為引言字串!\n" + +msgid "ERROR: Fatal USB error!\n" +msgstr "ERROR: 嚴重的 USB 錯誤!\n" + +msgid "ERROR: Invalid HP-GL/2 command seen, unable to print file!\n" +msgstr "ERROR: 發現無效的 HP-GL/2 指令,無法列印檔案!\n" + +#, c-format +msgid "ERROR: Missing %%EndProlog!\n" +msgstr "ERROR: 遺失 %%EndProlog!\n" + +#, c-format +msgid "ERROR: Missing %%EndSetup!\n" +msgstr "ERROR: 遺失 %%EndSetup!\n" + +#, c-format +msgid "ERROR: Missing value on line %d of banner file!\n" +msgstr "ERROR: 標語檔案的第 %d 行遺失值!\n" + +#, c-format +msgid "" +"ERROR: Need a msgid line before any translation strings on line %d of %s!\n" +msgstr "ERROR: 在 %2$s 第 %1$d 行的任何轉換字串前面都需要 msgid 行!\n" + +#, c-format +msgid "ERROR: No %%BoundingBox: comment in header!\n" +msgstr "ERROR: 沒有 %%BoundingBox:標題中的註解!\n" + +#, c-format +msgid "ERROR: No %%Pages: comment in header!\n" +msgstr "ERROR: 沒有 %%Pages:標題中的註解!\n" + +msgid "" +"ERROR: No device URI found in argv[0] or in DEVICE_URI environment " +"variable!\n" +msgstr "ERROR: 在 argv[0] 或 DEVICE_URI 環境變數中找不到設備 URI!\n" + +#, c-format +msgid "ERROR: No fonts in charset file %s\n" +msgstr "ERROR: 字元集檔案 %s 中沒有字體\n" + +msgid "ERROR: No pages found!\n" +msgstr "ERROR: 找不到頁面!\n" + +msgid "ERROR: Out of paper!\n" +msgstr "ERROR: 缺紙!\n" + +msgid "ERROR: PRINTER environment variable not defined!\n" +msgstr "ERROR: 未定義 PRINTER 環境變數!\n" + +#, c-format +msgid "ERROR: Print file was not accepted (%s)!\n" +msgstr "ERROR: 不接受列印檔案(%s)!\n" + +msgid "ERROR: Printer not responding\n" +msgstr "ERROR: 印表機未回應\n" + +msgid "ERROR: Printer not responding!\n" +msgstr "ERROR: 印表機未回應!\n" + +msgid "ERROR: Printer sent unexpected EOF\n" +msgstr "ERROR: 印表機傳送了非預期的 EOF\n" + +#, c-format +msgid "ERROR: Remote host did not accept control file (%d)\n" +msgstr "ERROR: 遠端主機未接受控制檔案(%d)\n" + +#, c-format +msgid "ERROR: Remote host did not accept data file (%d)\n" +msgstr "ERROR: 遠端主機未接受資料檔(%d)\n" + +msgid "ERROR: There was a timeout error while sending data to the printer\n" +msgstr "ERROR: 將資料傳送到印表機時發生逾時錯誤\n" + +#, c-format +msgid "ERROR: Unable to add file %d to job: %s\n" +msgstr "ERROR: 無法將檔案 %d 加入作業:%s\n" + +#, c-format +msgid "ERROR: Unable to cancel job %d: %s\n" +msgstr "ERROR: 無法取消作業 %d:%s\n" + +msgid "ERROR: Unable to copy PDF file" +msgstr "ERROR: 無法拷貝 PDF 檔案" + +msgid "ERROR: Unable to create pipe" +msgstr "" + +msgid "ERROR: Unable to create socket" +msgstr "ERROR: 無法製作 socket" + +#, c-format +msgid "ERROR: Unable to create temporary compressed print file: %s\n" +msgstr "ERROR: 無法製作暫時的壓縮列印檔案:%s\n" + +msgid "ERROR: Unable to create temporary file" +msgstr "ERROR: 無法製作暫存檔" + +#, c-format +msgid "ERROR: Unable to exec pictwpstops: %s\n" +msgstr "ERROR: 無法執行 pictwpstops:%s\n" + +msgid "ERROR: Unable to execute gs program" +msgstr "ERROR: 無法執行 gs 程式" + +msgid "ERROR: Unable to execute pdftops program" +msgstr "ERROR: 無法執行 pdftops 程式" + +msgid "ERROR: Unable to execute pstops program" +msgstr "" + +#, c-format +msgid "ERROR: Unable to fork pictwpstops: %s\n" +msgstr "ERROR: 無法分開 pictwpstops:%s\n" + +msgid "ERROR: Unable to get PAP request" +msgstr "ERROR: 無法取得 PAP 請求" + +msgid "ERROR: Unable to get PAP response" +msgstr "ERROR: 無法取得 PAP 回應" + +#, c-format +msgid "ERROR: Unable to get PPD file for printer \"%s\" - %s.\n" +msgstr "ERROR: 無法取得印表機“%s”的 PPD 檔案 - %s。\n" + +msgid "ERROR: Unable to get default AppleTalk zone" +msgstr "ERROR: 無法取得預設的 AppleTalk 區域" + +#, c-format +msgid "ERROR: Unable to get job %d attributes (%s)!\n" +msgstr "ERROR: 無法取得作業 %d 屬性(%s)!\n" + +#, c-format +msgid "ERROR: Unable to get printer status (%s)!\n" +msgstr "ERROR: 無法取得印表機狀態(%s)!\n" + +#, c-format +msgid "ERROR: Unable to locate printer '%s'!\n" +msgstr "ERROR: 找不到印表機 '%s'!\n" + +msgid "ERROR: Unable to look for PAP response" +msgstr "ERROR: 無法尋找 PAP 回應" + +msgid "ERROR: Unable to lookup AppleTalk printers" +msgstr "ERROR: 無法尋找 AppleTalk 印表機" + +msgid "ERROR: Unable to make AppleTalk address" +msgstr "ERROR: 無法設定 AppleTalk 地址" + +#, c-format +msgid "ERROR: Unable to open \"%s\" - %s\n" +msgstr "ERROR: 無法打開“%s”- %s\n" + +#, c-format +msgid "ERROR: Unable to open %s: %s\n" +msgstr "ERROR: 無法打開 %s:%s\n" + +msgid "ERROR: Unable to open PPD file!\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open banner file \"%s\" - %s\n" +msgstr "ERROR: 無法打開標語檔案“%s”- %s\n" + +#, c-format +msgid "ERROR: Unable to open device file \"%s\": %s\n" +msgstr "ERROR: 無法打開設備檔案“%s”:%s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\" - %s\n" +msgstr "ERROR: 無法打開檔案“%s”- %s\n" + +#, c-format +msgid "ERROR: Unable to open file \"%s\": %s\n" +msgstr "ERROR: 無法打開檔案“%s”:%s\n" + +msgid "ERROR: Unable to open image file for printing!\n" +msgstr "ERROR: 無法打開要列印的影像檔!\n" + +#, c-format +msgid "ERROR: Unable to open print file \"%s\": %s\n" +msgstr "ERROR: 無法打開列印檔案“%s”:%s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s - %s\n" +msgstr "ERROR: 無法打開列印檔案 %s - %s\n" + +#, c-format +msgid "ERROR: Unable to open print file %s: %s\n" +msgstr "ERROR: 無法打開列印檔案 %s:%s\n" + +#, c-format +msgid "ERROR: Unable to open raster file - %s\n" +msgstr "" + +#, c-format +msgid "ERROR: Unable to open temporary compressed print file: %s\n" +msgstr "ERROR: 無法打開暫時的壓縮列印檔案:%s\n" + +#, c-format +msgid "ERROR: Unable to print %d text columns!\n" +msgstr "ERROR: 無法列印 %d 文字直欄!\n" + +#, c-format +msgid "ERROR: Unable to print %dx%d text page!\n" +msgstr "ERROR: 無法列印 %dx%d 文字頁面!\n" + +msgid "ERROR: Unable to read print data" +msgstr "ERROR: 無法讀取列印資料" + +msgid "ERROR: Unable to read print data!\n" +msgstr "ERROR: 無法讀取列印資料!\n" + +msgid "ERROR: Unable to reserve port" +msgstr "ERROR: 無法保留連接埠" + +#, c-format +msgid "ERROR: Unable to seek to offset %ld in file - %s\n" +msgstr "ERROR: 無法在檔案中尋找偏移 %ld - %s\n" + +#, c-format +msgid "ERROR: Unable to seek to offset %lld in file - %s\n" +msgstr "ERROR: 無法在檔案中尋找偏移 %lld - %s\n" + +msgid "ERROR: Unable to send LPD command" +msgstr "ERROR: 無法傳送 LPD 指令" + +msgid "ERROR: Unable to send PAP tickle request" +msgstr "ERROR: 無法傳送 PAP tickle 請求" + +msgid "ERROR: Unable to send initial PAP send data request" +msgstr "ERROR: 無法傳送初始 PAP 傳送資料請求" + +#, c-format +msgid "ERROR: Unable to send print data (%d)\n" +msgstr "ERROR: 無法傳送列印資料(%d)\n" + +msgid "ERROR: Unable to send print data!\n" +msgstr "ERROR: 無法傳送列印資料!\n" + +msgid "ERROR: Unable to send print file to printer" +msgstr "ERROR: 無法將列印檔案傳送至印表機" + +msgid "ERROR: Unable to send trailing nul to printer" +msgstr "ERROR: 無法將 trailing nul 傳送至印表機" + +#, c-format +msgid "ERROR: Unable to wait for pictwpstops: %s\n" +msgstr "ERROR: 無法等待 pictwpstops:%s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to \"%s\": %s\n" +msgstr "ERROR: 無法將 %d 位元組寫入至“%s”:%s\n" + +#, c-format +msgid "ERROR: Unable to write %d bytes to printer!\n" +msgstr "ERROR: 無法將 %d 位元組寫入至印表機!\n" + +msgid "ERROR: Unable to write control file" +msgstr "ERROR: 無法寫入控制檔案" + +msgid "ERROR: Unable to write print data" +msgstr "ERROR: 無法寫入列印資料" + +#, c-format +msgid "ERROR: Unable to write print data: %s\n" +msgstr "ERROR: 無法寫入列印資料:%s\n" + +msgid "ERROR: Unable to write raster data to driver!\n" +msgstr "ERROR: 無法將水平掃瞄線資料寫入驅動程式!\n" + +msgid "ERROR: Unable to write to temporary file" +msgstr "ERROR: 無法寫入暫存檔" + +#, c-format +msgid "ERROR: Unable to write uncompressed document data: %s\n" +msgstr "ERROR: 無法寫入未壓縮的文件資料:%s\n" + +#, c-format +msgid "ERROR: Unexpected text on line %d of %s!\n" +msgstr "ERROR: %2$s 的第 %1$d 行有非預期的文字!\n" + +#, c-format +msgid "ERROR: Unknown encryption option value \"%s\"!\n" +msgstr "ERROR: 未知的加密選項值“%s”!\n" + +#, c-format +msgid "ERROR: Unknown file order \"%s\"\n" +msgstr "ERROR: 未知的檔案順序“%s”\n" + +#, c-format +msgid "ERROR: Unknown format character \"%c\"\n" +msgstr "ERROR: 未知的格式字元“%c”\n" + +#, c-format +msgid "ERROR: Unknown message catalog format for \"%s\"!\n" +msgstr "ERROR: “%s”的訊息目錄格式未知!\n" + +#, c-format +msgid "ERROR: Unknown option \"%s\" with value \"%s\"!\n" +msgstr "ERROR: 未知的選項“%s”,值為“%s”!\n" + +#, c-format +msgid "ERROR: Unknown print mode \"%s\"\n" +msgstr "ERROR: 未知的列印模式“%s”\n" + +#, c-format +msgid "ERROR: Unknown version option value \"%s\"!\n" +msgstr "ERROR: 未知的版本選項值“%s”!\n" + +#, c-format +msgid "ERROR: Unsupported brightness value %s, using brightness=100!\n" +msgstr "ERROR: 不受支援的亮度值 %s,使用 brightness=100!\n" + +#, c-format +msgid "ERROR: Unsupported gamma value %s, using gamma=1000!\n" +msgstr "ERROR: 不受支援的 gamma 值 %s,使用 gamma=1000!\n" + +#, c-format +msgid "ERROR: Unsupported number-up value %d, using number-up=1!\n" +msgstr "ERROR: 不受支援的 number-up 值 %d,使用 number-up=1!\n" + +#, c-format +msgid "" +"ERROR: Unsupported number-up-layout value %s, using number-up-layout=lrtb!\n" +msgstr "" +"ERROR: 不受支援的 number-up-layout 值 %s,使用 number-up-layout=lrtb!\n" + +#, c-format +msgid "ERROR: Unsupported page-border value %s, using page-border=none!\n" +msgstr "ERROR: 不受支援的 page-border 值 %s,使用 page-border=none!\n" + +#, c-format +msgid "ERROR: doc_printf overflow (%d bytes) detected, aborting!\n" +msgstr "ERROR: 偵測到 doc_printf 溢位(%d 位元組),正在中斷!\n" + +#, c-format +msgid "ERROR: pictwpstops exited on signal %d!\n" +msgstr "ERROR: pictwpstops 在遇到訊號 %d 時結束!\n" + +#, c-format +msgid "ERROR: pictwpstops exited with status %d!\n" +msgstr "ERROR: pictwpstops 以狀態 %d 結束!\n" + +msgid "" +"ERROR: recoverable: Unable to connect to printer; will retry in 30 " +"seconds...\n" +msgstr "ERROR: 可回復:無法連接印表機;30 秒內將重試⋯\n" + +msgid "ERROR: select() failed" +msgstr "ERROR: select() 失敗" + +msgid "ERROR: unable to stat print file" +msgstr "ERROR: 無法開始列印檔案" + +msgid "Edit Configuration File" +msgstr "編輯配置檔案" + +msgid "Empty PPD file!" +msgstr "PPD 檔案為空!" + +msgid "Ending Banner" +msgstr "結束標語" + +msgid "Enter old password:" +msgstr "輸入新密碼:" + +msgid "Enter password again:" +msgstr "請再輸入密碼:" + +msgid "Enter password:" +msgstr "輸入密碼:" + +msgid "" +"Enter your username and password or the root username and password to access " +"this page. If you are using Kerberos authentication, make sure you have a " +"valid Kerberos ticket." +msgstr "" +"請輸入您的使用者名稱和密碼或 root 使用者名稱和密碼來存取此頁面。如果您是使用 " +"Kerberos 認證,請確定具備有效的 Kerberos 票券。" + +msgid "Envelope Feed" +msgstr "信封送紙器" + +msgid "Epson" +msgstr "Epson" + +msgid "Error Policy" +msgstr "錯誤的原則" + +msgid "Error: need hostname after '-h' option!\n" +msgstr "ERROR: '-h' 選項後面需要主機名稱!\n" + +msgid "Every 10 Labels" +msgstr "每 10 個標籤" + +msgid "Every 2 Labels" +msgstr "每 2 個標籤" + +msgid "Every 3 Labels" +msgstr "每 3 個標籤" + +msgid "Every 4 Labels" +msgstr "每 4 個標籤" + +msgid "Every 5 Labels" +msgstr "每 5 個標籤" + +msgid "Every 6 Labels" +msgstr "每 6 個標籤" + +msgid "Every 7 Labels" +msgstr "每 7 個標籤" + +msgid "Every 8 Labels" +msgstr "每 8 個標籤" + +msgid "Every 9 Labels" +msgstr "每 9 個標籤" + +msgid "Every Label" +msgstr "每一個標籤" + +msgid "Expectation Failed" +msgstr "與預期不符" + +msgid "Export Printers to Samba" +msgstr "將印表機輸出至 Samba" + +msgid "FAIL\n" +msgstr "失敗\n" + +msgid "File Folder" +msgstr "檔案夾" + +msgid "File Folder - 9/16 x 3 7/16\"" +msgstr "檔案夾 - 9/16 x 3 7/16\"" + +#, c-format +msgid "" +"File device URIs have been disabled! To enable, see the FileDevice directive " +"in \"%s/cupsd.conf\"." +msgstr "" +"已停用檔案設備 URI!若要啟用,請參閱“%s/cupsd.conf”中的 FileDevice 指示。" + +msgid "Folio" +msgstr "對開紙" + +msgid "Forbidden" +msgstr "已禁止" + +msgid "Fuser temperature high!" +msgstr "加熱器溫度高!" + +msgid "Fuser temperature low!" +msgstr "加熱器溫度低!" + +msgid "General" +msgstr "一般" + +msgid "Generic" +msgstr "通用" + +msgid "German FanFold" +msgstr "德式折疊式報表紙(German FanFold)" + +msgid "German FanFold Legal" +msgstr "德式折疊式法定報表紙(German FanFold Legal)" + +msgid "Get-Response-PDU uses indefinite length" +msgstr "Get-Response-PDU 使用的長度不確定" + +msgid "Glossy Paper" +msgstr "鏡面紙" + +msgid "Got a printer-uri attribute but no job-id!" +msgstr "已取得 printer-uri 屬性,但沒有 job-id!" + +msgid "Grayscale" +msgstr "灰階" + +msgid "HP" +msgstr "HP" + +msgid "Hanging Folder" +msgstr "懸掛的檔案夾" + +msgid "Hanging Folder - 9/16 x 2\"" +msgstr "懸掛的檔案夾 - 9/16 x 2\"" + +msgid "INFO: AppleTalk disabled in System Preferences\n" +msgstr "INFO: 已在“系統偏好設定”中停用 AppleTalk\n" + +msgid "INFO: AppleTalk disabled in System Preferences.\n" +msgstr "INFO: 已在“系統偏好設定”中停用 AppleTalk。\n" + +msgid "INFO: Canceling print job...\n" +msgstr "INFO: 正在取消列印作業⋯\n" + +msgid "INFO: Connected to printer...\n" +msgstr "INFO: 已連接印表機⋯\n" + +msgid "INFO: Connecting to printer...\n" +msgstr "INFO: 正在連接印表機⋯\n" + +msgid "INFO: Control file sent successfully\n" +msgstr "INFO: 已成功傳送控制檔案\n" + +msgid "INFO: Copying print data...\n" +msgstr "" + +msgid "INFO: Data file sent successfully\n" +msgstr "INFO: 已成功傳送資料檔\n" + +#, c-format +msgid "INFO: Finished page %d...\n" +msgstr "" + +#, c-format +msgid "INFO: Formatting page %d...\n" +msgstr "INFO: 正在格式化頁面 %d⋯\n" + +msgid "INFO: Loading image file...\n" +msgstr "INFO: 正在載入影像檔⋯\n" + +msgid "INFO: Looking for printer...\n" +msgstr "INFO: 正在尋找印表機⋯\n" + +msgid "INFO: Opening connection\n" +msgstr "INFO: 正在打開連線\n" + +msgid "INFO: Print file sent, waiting for printer to finish...\n" +msgstr "INFO: 已傳送列印檔案,正在等待印表機完成工作⋯\n" + +msgid "INFO: Printer busy; will retry in 10 seconds...\n" +msgstr "INFO: 印表機忙碌中;10 秒內將重試⋯\n" + +msgid "INFO: Printer busy; will retry in 30 seconds...\n" +msgstr "INFO: 印表機忙碌中;30 秒內將重試⋯\n" + +msgid "INFO: Printer busy; will retry in 5 seconds...\n" +msgstr "INFO: 印表機忙碌中;5 秒內將重試⋯\n" + +#, c-format +msgid "INFO: Printer does not support IPP/%d.%d, trying IPP/1.0...\n" +msgstr "INFO: 印表機不支援 IPP/%d.%d,正在嘗試 IPP/1.0⋯\n" + +msgid "INFO: Printer is busy; will retry in 5 seconds...\n" +msgstr "INFO: 印表機忙碌中;5 秒內將重試⋯\n" + +msgid "INFO: Printer is currently off-line.\n" +msgstr "INFO: 印表機目前已離線。\n" + +msgid "INFO: Printer is currently offline.\n" +msgstr "INFO: 印表機目前已離線。\n" + +msgid "INFO: Printer is now online.\n" +msgstr "INFO: 印表機已回到線上。\n" + +msgid "INFO: Printer is offline.\n" +msgstr "INFO: 印表機已離線。\n" + +msgid "INFO: Printer not connected; will retry in 30 seconds...\n" +msgstr "INFO: 未連接印表機;30 秒內將重試⋯\n" + +#, c-format +msgid "INFO: Printing page %d, %d%% complete...\n" +msgstr "INFO: 正在列印頁面 %d,%d%% 已完成⋯\n" + +#, c-format +msgid "INFO: Printing page %d...\n" +msgstr "INFO: 正在列印頁面 %d⋯\n" + +msgid "INFO: Ready to print.\n" +msgstr "INFO: 準備好進行列印。\n" + +#, c-format +msgid "INFO: Sending control file (%lu bytes)\n" +msgstr "INFO: 正在傳送控制檔案(%lu 位元組)\n" + +#, c-format +msgid "INFO: Sending control file (%u bytes)\n" +msgstr "INFO: 正在傳送控制檔案(%u 位元組)\n" + +msgid "INFO: Sending data\n" +msgstr "INFO: 正在傳送資料\n" + +#, c-format +msgid "INFO: Sending data file (%ld bytes)\n" +msgstr "INFO: 正在傳送資料檔(%ld 位元組)\n" + +#, c-format +msgid "INFO: Sending data file (%lld bytes)\n" +msgstr "INFO: 正在傳送資料檔(%lld 位元組)\n" + +msgid "INFO: Sending print data...\n" +msgstr "INFO: 正在傳送列印資料⋯\n" + +#, c-format +msgid "INFO: Sent print file, %ld bytes...\n" +msgstr "INFO: 已傳送列印檔案,%ld 位元組⋯\n" + +#, c-format +msgid "INFO: Sent print file, %lld bytes...\n" +msgstr "INFO: 已傳送列印檔案,%lld 位元組⋯\n" + +#, c-format +msgid "INFO: Spooling LPR job, %.0f%% complete...\n" +msgstr "INFO: 正在緩衝列印作業,%.0f%% 已完成⋯\n" + +#, c-format +msgid "INFO: Starting page %d...\n" +msgstr "" + +msgid "INFO: Unable to contact printer, queuing on next printer in class...\n" +msgstr "INFO: 無法聯絡印表機,正在佇列等待類別中的下一個印表機⋯\n" + +#, c-format +msgid "INFO: Using default AppleTalk zone \"%s\"\n" +msgstr "INFO: 使用預設的 AppleTalk 區域“%s”\n" + +msgid "INFO: Waiting for job to complete...\n" +msgstr "INFO: 正在等待作業完成⋯\n" + +msgid "INFO: Waiting for printer to become available...\n" +msgstr "INFO: 正在等待印表機成為可用狀態⋯\n" + +msgid "ISO B0" +msgstr "ISO B0" + +msgid "ISO B1" +msgstr "ISO B1" + +msgid "ISO B10" +msgstr "ISO B10" + +msgid "ISO B2" +msgstr "ISO B2" + +msgid "ISO B3" +msgstr "ISO B3" + +msgid "ISO B4" +msgstr "ISO B4" + +msgid "ISO B4 Envelope" +msgstr "ISO B4 信封" + +msgid "ISO B5" +msgstr "ISO B5" + +msgid "ISO B5 (Oversize)" +msgstr "ISO B5(超大型)" + +msgid "ISO B5 Envelope" +msgstr "ISO B5 信封" + +msgid "ISO B6" +msgstr "ISO B6" + +msgid "ISO B6 Envelope" +msgstr "ISO B6 信封" + +msgid "ISO B7" +msgstr "ISO B7" + +msgid "ISO B8" +msgstr "ISO B8" + +msgid "ISO B9" +msgstr "ISO B9" + +msgid "Illegal control character" +msgstr "不合法的控制字元" + +msgid "Illegal main keyword string" +msgstr "不合法的主要關鍵字串" + +msgid "Illegal option keyword string" +msgstr "不合法的選項關鍵字串" + +msgid "Illegal translation string" +msgstr "不合法的轉換字串" + +msgid "Illegal whitespace character" +msgstr "不合法的空白字元" + +msgid "Ink/toner almost empty." +msgstr "墨水或碳粉即將耗盡。" + +msgid "Ink/toner empty!" +msgstr "墨水或碳粉已耗盡!" + +msgid "Ink/toner waste bin almost full." +msgstr "墨水或碳粉廢料槽將滿。" + +msgid "Ink/toner waste bin full!" +msgstr "墨水或碳粉廢料槽已滿!" + +msgid "Installable Options" +msgstr "可安裝的選項" + +msgid "Installed" +msgstr "已安裝" + +msgid "IntelliBar Label Printer" +msgstr "IntelliBar 標籤印表機" + +msgid "Intellitech" +msgstr "Intellitech" + +msgid "Interlock open." +msgstr "Interlock 已打開。" + +msgid "Internal Server Error" +msgstr "" + +msgid "Internal error" +msgstr "內部錯誤" + +msgid "Internet Postage 2-Part" +msgstr "Internet Postage 2-Part" + +msgid "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" +msgstr "Internet Postage 2-Part - 2 1/4 x 7 1/2\"" + +msgid "Internet Postage 3-Part" +msgstr "Internet Postage 3-Part" + +msgid "Internet Postage 3-Part - 2 1/4 x 7\"" +msgstr "Internet Postage 3-Part - 2 1/4 x 7\"" + +msgid "Internet Printing Protocol" +msgstr "Internet 列印通訊協定" + +msgid "Invite Envelope" +msgstr "邀請信封" + +msgid "Italian Envelope" +msgstr "義大利信封" + +msgid "JCL" +msgstr "JCL" + +#, c-format +msgid "Job #%d cannot be restarted - no files!" +msgstr "無法重新啟動作業 #%d - 沒有檔案!" + +#, c-format +msgid "Job #%d does not exist!" +msgstr "作業 #%d 不存在!" + +#, c-format +msgid "Job #%d is already aborted - can't cancel." +msgstr "已中止作業 #%d - 無法取消。" + +#, c-format +msgid "Job #%d is already canceled - can't cancel." +msgstr "已取消作業 #%d - 無法取消。" + +#, c-format +msgid "Job #%d is already completed - can't cancel." +msgstr "已完成作業 #%d - 無法取消。" + +#, c-format +msgid "Job #%d is finished and cannot be altered!" +msgstr "已完成作業 #%d 且無法更改!" + +#, c-format +msgid "Job #%d is not complete!" +msgstr "未完成作業 #%d!" + +#, c-format +msgid "Job #%d is not held for authentication!" +msgstr "未暫停作業 #%d 進行認證!" + +#, c-format +msgid "Job #%d is not held!" +msgstr "未暫停作業 #%d!" + +#, c-format +msgid "Job #%s does not exist!" +msgstr "作業 #%s 不存在!" + +#, c-format +msgid "Job %d not found!" +msgstr "找不到作業 %d!" + +msgid "Job Completed" +msgstr "已完成作業" + +msgid "Job Created" +msgstr "已建立作業" + +msgid "Job ID: " +msgstr "作業 ID:" + +msgid "Job Options Changed" +msgstr "已更改作業選項" + +msgid "Job Stopped" +msgstr "已停止作業" + +msgid "Job UUID: " +msgstr "作業 UUID:" + +msgid "Job is completed and cannot be changed." +msgstr "作業已完成且無法更改。" + +msgid "Job operation failed:" +msgstr "作業操作失敗:" + +msgid "Job state cannot be changed." +msgstr "無法更改作業狀態。" + +msgid "Job subscriptions cannot be renewed!" +msgstr "無法更新作業訂閱!" + +msgid "Jobs" +msgstr "作業" + +msgid "Kaku2 Envelope" +msgstr "Kaku2 信封" + +msgid "Kaku3 Envelope" +msgstr "Kaku3 信封" + +msgid "LPD/LPR Host or Printer" +msgstr "LPD/LPR 主機或印表機" + +msgid "Label Printer" +msgstr "標籤印表機" + +msgid "Label Top" +msgstr "標籤頂端" + +#, c-format +msgid "Language \"%s\" not supported!" +msgstr "不支援語言“%s”!" + +msgid "Large Address" +msgstr "大型地址" + +msgid "Large Address - 1 4/10 x 3 1/2\"" +msgstr "大型地址 - 1 4/10 x 3 1/2\"" + +msgid "LaserJet Series PCL 4/5" +msgstr "LaserJet 系列 PCL 4/5" + +msgid "Light" +msgstr "不明顯" + +msgid "Line longer than the maximum allowed (255 characters)" +msgstr "允許行長度大於最大值(255 個字元)" + +msgid "List Available Printers" +msgstr "列出可用印表機" + +msgid "Location: " +msgstr "位置:" + +msgid "Long-Edge (Portrait)" +msgstr "沿長邊(直式)" + +msgid "Make and Model: " +msgstr "製造和型號:" + +msgid "Manual Feed" +msgstr "手動送紙" + +msgid "Media Dimensions: " +msgstr "媒體尺寸:" + +msgid "Media Limits: " +msgstr "媒體限制:" + +msgid "Media Name: " +msgstr "媒體名稱:" + +msgid "Media Size" +msgstr "媒體大小" + +msgid "Media Source" +msgstr "媒體來源" + +msgid "Media Tracking" +msgstr "媒體軌跡" + +msgid "Media Type" +msgstr "媒體類型" + +msgid "Media jam!" +msgstr "媒體卡紙!" + +msgid "Media tray almost empty." +msgstr "媒體送紙匣即將用完。" + +msgid "Media tray empty!" +msgstr "媒體送紙匣為空!" + +msgid "Media tray missing!" +msgstr "找不到媒體送紙匣!" + +msgid "Media tray needs to be filled." +msgstr "媒體送紙匣需要添加紙張。" + +msgid "Medium" +msgstr "中" + +msgid "Memory allocation error" +msgstr "記憶體分配錯誤" + +msgid "Missing PPD-Adobe-4.x header" +msgstr "遺失 PPD-Adobe-4.x 標題" + +msgid "Missing asterisk in column 1" +msgstr "直欄 1 中遺失星號" + +msgid "Missing document-number attribute!" +msgstr "遺失 document-number 屬性!" + +#, c-format +msgid "Missing double quote on line %d!" +msgstr "第 %d 行遺失雙引號!!" + +msgid "Missing form variable!" +msgstr "遺失表單變數!" + +msgid "Missing notify-subscription-ids attribute!" +msgstr "遺失 notify-subscription-ids 屬性!" + +msgid "Missing requesting-user-name attribute!" +msgstr "遺失 requesting-user-name 屬性!" + +msgid "Missing required attributes!" +msgstr "遺失必要的屬性!" + +#, c-format +msgid "Missing value on line %d!" +msgstr "第 %d 行遺失值!" + +msgid "Missing value string" +msgstr "遺失值字串" + +#, c-format +msgid "" +"Model: name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" +msgstr "" +"型號:name = %s\n" +" natural_language = %s\n" +" make-and-model = %s\n" +" device-id = %s\n" + +msgid "Modify Class" +msgstr "修改類別" + +msgid "Modify Printer" +msgstr "修改印表機" + +msgid "Monarch" +msgstr "Monarch" + +msgid "Monarch Envelope" +msgstr "Monarch 信封" + +msgid "Move All Jobs" +msgstr "移動所有作業" + +msgid "Move Job" +msgstr "移動作業" + +msgid "Moved Permanently" +msgstr "永久地移動" + +#, c-format +msgid "NOTICE: Print file accepted - job ID %d.\n" +msgstr "NOTICE: 已接受列印檔案 - 作業 ID %d。\n" + +msgid "NOTICE: Print file accepted - job ID unknown.\n" +msgstr "NOTICE: 已接受列印檔案 - 作業 ID 未知。\n" + +msgid "NULL PPD file pointer" +msgstr "NULL PPD 檔案指標" + +msgid "Name OID uses indefinite length" +msgstr "名稱 OID 使用的長度不確定" + +msgid "Nested classes are not allowed!" +msgstr "" + +msgid "Never" +msgstr "永不" + +msgid "New Stylus Color Series" +msgstr "新 Stylus Color 系列" + +msgid "New Stylus Photo Series" +msgstr "新 Stylus Photo 系列" + +msgid "No" +msgstr "否" + +msgid "No Content" +msgstr "無內容" + +msgid "No PPD name!" +msgstr "沒有 PPD 名稱!" + +msgid "No VarBind SEQUENCE" +msgstr "沒有 VarBind SEQUENCE" + +msgid "No Windows printer drivers are installed!" +msgstr "未安裝 Windows 印表機驅動程式!" + +msgid "No active connection" +msgstr "沒有已啟用的連線" + +#, c-format +msgid "No active jobs on %s!" +msgstr "%s 上沒有已啟用的作業!" + +msgid "No attributes in request!" +msgstr "請求中沒有屬性!" + +msgid "No authentication information provided!" +msgstr "未提供認證資訊!" + +msgid "No community name" +msgstr "沒有社群名稱" + +msgid "No default printer" +msgstr "沒有預設印表機" + +msgid "No destinations added." +msgstr "未加入目的地。" + +msgid "No error-index" +msgstr "沒有錯誤索引" + +msgid "No error-status" +msgstr "沒有錯誤狀態" + +msgid "No file!?!" +msgstr "沒有檔案!?!" + +msgid "No modification time!" +msgstr "沒有修改時間!" + +msgid "No name OID" +msgstr "沒有名稱 OID" + +msgid "No printer name!" +msgstr "沒有印表機名稱!" + +msgid "No printer-uri found for class!" +msgstr "找不到類別的 printer-uri!" + +msgid "No printer-uri found!" +msgstr "找不到 printer-uri!" + +msgid "No printer-uri in request!" +msgstr "請求中沒有 printer-uri!" + +msgid "No request-id" +msgstr "沒有 request-id" + +msgid "No subscription attributes in request!" +msgstr "請求中沒有訂閱屬性!" + +msgid "No subscriptions found." +msgstr "找不到訂閱。" + +msgid "No variable-bindings SEQUENCE" +msgstr "沒有 variable-bindings SEQUENCE" + +msgid "No version number" +msgstr "沒有版本號碼" + +msgid "Non-continuous (Mark sensing)" +msgstr "不連續(標示感應)" + +msgid "Non-continuous (Web sensing)" +msgstr "不連續(Web 感應)" + +msgid "Normal" +msgstr "正常" + +msgid "Not Found" +msgstr "找不到" + +msgid "Not Implemented" +msgstr "尚未完成" + +msgid "Not Installed" +msgstr "尚未安裝" + +msgid "Not Modified" +msgstr "尚未修改" + +msgid "Not Supported" +msgstr "不受支援" + +msgid "Not allowed to print." +msgstr "不允許列印。" + +msgid "Note" +msgstr "注意" + +msgid "OK" +msgstr "確定" + +msgid "OPC almost at end-of-life." +msgstr "OPC 壽命即將耗盡。" + +msgid "OPC at end-of-life!" +msgstr "OPC 壽命耗盡。" + +msgid "Off (1-Sided)" +msgstr "關(單面)" + +msgid "Oki" +msgstr "Oki" + +msgid "Online Help" +msgstr "線上輔助說明" + +#, c-format +msgid "Open of %s failed: %s" +msgstr "打開 %s 失敗:%s" + +msgid "OpenGroup without a CloseGroup first" +msgstr "OpenGroup 之前沒有先 CloseGroup" + +msgid "OpenUI/JCLOpenUI without a CloseUI/JCLCloseUI first" +msgstr "OpenUI/JCLOpenUI 之前沒有先 CloseUI/JCLCloseUI" + +msgid "Operation Policy" +msgstr "操作政策" + +msgid "Options Installed" +msgstr "已安裝的選項" + +msgid "Options: " +msgstr "選項:" + +msgid "Out of toner!" +msgstr "碳粉已耗盡!" + +msgid "Output Mode" +msgstr "輸出模式" + +msgid "Output bin almost full." +msgstr "輸出槽將滿。" + +msgid "Output bin full!" +msgstr "輸出槽已滿!" + +#, c-format +msgid "Output for printer %s is sent to %s\n" +msgstr "已將印表機 %s 的輸出傳送至 %s\n" + +#, c-format +msgid "Output for printer %s is sent to remote printer %s on %s\n" +msgstr "已將印表機 %s 的輸出傳送至遠端印表機 %s(位於 %s 上)\n" + +#, c-format +msgid "Output for printer %s/%s is sent to %s\n" +msgstr "已將印表機 %s/%s 的輸出傳送至 %s\n" + +#, c-format +msgid "Output for printer %s/%s is sent to remote printer %s on %s\n" +msgstr "已將印表機 %s/%s 的輸出傳送至遠端印表機 %s(位於 %s 上)\n" + +msgid "Output tray missing!" +msgstr "找不到輸出紙匣!" + +msgid "PASS\n" +msgstr "通過\n" + +msgid "PCL Laser Printer" +msgstr "PCL 雷射印表機" + +msgid "PRC1 Envelope" +msgstr "PRC1 信封" + +msgid "PRC10 Envelope" +msgstr "PRC10 信封" + +msgid "PRC16K" +msgstr "PRC16K" + +msgid "PRC2 Envelope" +msgstr "PRC2 信封" + +msgid "PRC3 Envelope" +msgstr "PRC3 信封" + +msgid "PRC32K" +msgstr "PRC32K" + +msgid "PRC32K (Oversize)" +msgstr "PRC32K(超大型)" + +msgid "PRC4 Envelope" +msgstr "PRC4 信封" + +msgid "PRC5 Envelope" +msgstr "PRC5 信封" + +msgid "PRC6 Envelope" +msgstr "PRC6 信封" + +msgid "PRC7 Envelope" +msgstr "PRC7 信封" + +msgid "PRC8 Envelope" +msgstr "PRC8 信封" + +msgid "PRC9 Envelope" +msgstr "PRC9 信封" + +msgid "Packet does not contain a Get-Response-PDU" +msgstr "封包不包含 Get-Response-PDU" + +msgid "Packet does not start with SEQUENCE" +msgstr "封包不是以 SEQUENCE 開頭" + +msgid "ParamCustominCutInterval" +msgstr "ParamCustominCutInterval" + +msgid "ParamCustominTearInterval" +msgstr "ParamCustominTearInterval" + +#, c-format +msgid "Password for %s on %s? " +msgstr "需要 %s(位於 %s 上)的密碼?" + +#, c-format +msgid "Password for %s required to access %s via SAMBA: " +msgstr "需要 %s 的密碼才能透過 SAMBA 存取 %s:" + +msgid "Pause Class" +msgstr "暫停類別" + +msgid "Pause Printer" +msgstr "暫停印表機" + +msgid "Peel-Off" +msgstr "去皮" + +msgid "Personal Envelope" +msgstr "個人信封" + +msgid "Photo" +msgstr "照片" + +msgid "Photo Labels" +msgstr "照片標籤" + +msgid "Plain Paper" +msgstr "一般紙張" + +msgid "Policies" +msgstr "政策" + +msgid "Port Monitor" +msgstr "連接埠監視器" + +msgid "PostScript Printer" +msgstr "PostScript 印表機" + +msgid "Postcard" +msgstr "明信片" + +msgid "Print Density" +msgstr "列印密度" + +msgid "Print Job:" +msgstr "列印作業:" + +msgid "Print Mode" +msgstr "列印模式" + +msgid "Print Rate" +msgstr "列印速率" + +msgid "Print Self-Test Page" +msgstr "列印自我測試頁面" + +msgid "Print Speed" +msgstr "列印速度" + +msgid "Print Test Page" +msgstr "列印測試頁面" + +msgid "Print and Cut" +msgstr "列印並剪下" + +msgid "Print and Tear" +msgstr "列印並撕開" + +msgid "Printed For: " +msgstr "列印對象:" + +msgid "Printed From: " +msgstr "列印自:" + +msgid "Printed On: " +msgstr "列印日期:" + +msgid "Printer Added" +msgstr "已加入印表機" + +msgid "Printer Default" +msgstr "預設印表機" + +msgid "Printer Deleted" +msgstr "已刪除印表機" + +msgid "Printer Modified" +msgstr "已修改印表機" + +msgid "Printer Name: " +msgstr "印表機名稱:" + +msgid "Printer Paused" +msgstr "印表機已暫停" + +msgid "Printer Settings" +msgstr "印表機設定" + +msgid "Printer offline." +msgstr "印表機已離線。" + +msgid "Printer:" +msgstr "印表機:" + +msgid "Printers" +msgstr "印表機" + +msgid "Purge Jobs" +msgstr "清除作業" + +msgid "Quarto" +msgstr "四開紙" + +msgid "Quota limit reached." +msgstr "已達到四開紙限制。" + +msgid "Rank Owner Job File(s) Total Size\n" +msgstr "等級 持有人 作業 檔案 大小總計\n" + +msgid "" +"Rank Owner Pri Job Files Total Size\n" +msgstr "" +"等級 持有人 優先作業 檔案 大小總計\n" + +msgid "Reject Jobs" +msgstr "退出作業" + +msgid "Reprint After Error" +msgstr "發生錯誤後重新列印" + +msgid "Request Entity Too Large" +msgstr "請求的實體過大" + +msgid "Resolution" +msgstr "解析度" + +msgid "Resume Class" +msgstr "繼續類別" + +msgid "Resume Printer" +msgstr "繼續印表機" + +msgid "Return Address" +msgstr "寄件人地址" + +msgid "Return Address - 3/4 x 2\"" +msgstr "寄件人地址 - 3/4 x 2\"" + +msgid "Rewind" +msgstr "倒轉" + +#, c-format +msgid "Running command: %s %s -N -A %s -c '%s'\n" +msgstr "執行指令:%s %s -N -A %s -c '%s'\n" + +msgid "SCSI Printer" +msgstr "SCSI 印表機" + +msgid "SEQUENCE uses indefinite length" +msgstr "SEQUENCE 使用的長度不確定" + +msgid "See Other" +msgstr "參閱其他" + +#, c-format +msgid "Serial Port #%d" +msgstr "序列埠 #%d" + +msgid "Server Restarted" +msgstr "重新啟動伺服器" + +msgid "Server Security Auditing" +msgstr "伺服器安全性審定" + +msgid "Server Started" +msgstr "已啟動伺服器" + +msgid "Server Stopped" +msgstr "已停止伺服器" + +msgid "Service Unavailable" +msgstr "服務無法使用" + +msgid "Set Allowed Users" +msgstr "設定允許的使用者" + +msgid "Set As Server Default" +msgstr "設為伺服器預設值" + +msgid "Set Class Options" +msgstr "設定類別選項" + +msgid "Set Printer Options" +msgstr "設定印表機選項" + +msgid "Set Publishing" +msgstr "設定發佈" + +msgid "Shipping Address" +msgstr "運送地址" + +msgid "Shipping Address - 2 5/16 x 4\"" +msgstr "運送地址 - 2 5/16 x 4\"" + +msgid "Short-Edge (Landscape)" +msgstr "沿短邊(橫式)" + +msgid "Special Paper" +msgstr "特殊紙張" + +msgid "Standard" +msgstr "標準" + +msgid "Starting Banner" +msgstr "起始標語" + +msgid "Statement" +msgstr "敘述" + +msgid "Stylus Color Series" +msgstr "Stylus Color 系列" + +msgid "Stylus Photo Series" +msgstr "Stylus Photo 系列" + +msgid "Super A" +msgstr "Super A" + +msgid "Super B" +msgstr "Super B" + +msgid "Super B/A3" +msgstr "Super B/A3" + +msgid "Switching Protocols" +msgstr "切換通訊協定" + +msgid "Tabloid" +msgstr "小報用紙(Tabloid)" + +msgid "Tabloid (Oversize)" +msgstr "小報用紙-超大型(Tabloid-Oversize)" + +msgid "Tear" +msgstr "撕開" + +msgid "Tear-Off" +msgstr "撕下" + +msgid "Tear-Off Adjust Position" +msgstr "撕下調整位置" + +#, c-format +msgid "The PPD file \"%s\" could not be found." +msgstr "找不到 PPD 檔案“%s”。" + +#, c-format +msgid "The PPD file \"%s\" could not be opened: %s" +msgstr "無法打開 PPD 檔案“%s”:%s" + +msgid "" +"The class name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"類別名稱只能包含最多 127 個可列印字元,而且不能包含空格、斜線(/)或井字號" +"(#)。" + +msgid "" +"The notify-lease-duration attribute cannot be used with job subscriptions." +msgstr "notify-lease-duration 屬性不能與作業訂閱搭配使用。" + +#, c-format +msgid "The notify-user-data value is too large (%d > 63 octets)!" +msgstr "notify-user-data 值太大(%d > 63 八位元組)!" + +msgid "" +"The printer name may only contain up to 127 printable characters and may not " +"contain spaces, slashes (/), or the pound sign (#)." +msgstr "" +"印表機名稱只能包含最多 127 個可列印的字元,而且不能包含空格、斜線(/)或井字" +"號(#)。" + +msgid "The printer or class is not shared!" +msgstr "未共享印表機或類別!" + +msgid "The printer or class was not found." +msgstr "找不到印表機或類別。" + +#, c-format +msgid "The printer-uri \"%s\" contains invalid characters." +msgstr "printer-uri“%s”包含無效的字元。" + +msgid "The printer-uri attribute is required!" +msgstr "需要 printer-uri 屬性!" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/classes/CLASSNAME\"." +msgstr "printer-uri 格式必須為“ipp://HOSTNAME/classes/CLASSNAME”。" + +msgid "" +"The printer-uri must be of the form \"ipp://HOSTNAME/printers/PRINTERNAME\"." +msgstr "printer-uri 格式必須為“ipp://HOSTNAME/printers/PRINTERNAME”。" + +msgid "" +"The subscription name may not contain spaces, slashes (/), question marks " +"(?), or the pound sign (#)." +msgstr "訂閱名稱不能包含空格、斜線(/)、問號(?)或井字號(#)。" + +msgid "There are too many subscriptions." +msgstr "訂閱數量太多。" + +msgid "Thermal Transfer Media" +msgstr "熱感傳送媒體" + +msgid "Title: " +msgstr "標題:" + +msgid "Toner low." +msgstr "碳粉過少。" + +msgid "Too many active jobs." +msgstr "已啟用的作業太多。" + +#, c-format +msgid "Too many job-sheets values (%d > 2)!" +msgstr "太多 job-sheets 值(%d > 2)!" + +#, c-format +msgid "Too many printer-state-reasons values (%d > %d)!" +msgstr "太多 printer-state-reasons 值(%d > %d)!" + +msgid "Transparency" +msgstr "透明度" + +msgid "Tray" +msgstr "裝紙匣" + +msgid "Tray 1" +msgstr "裝紙匣 1" + +msgid "Tray 2" +msgstr "裝紙匣 2" + +msgid "Tray 3" +msgstr "裝紙匣 3" + +msgid "Tray 4" +msgstr "裝紙匣 4" + +msgid "URI Too Long" +msgstr "URI 太長" + +msgid "US Executive" +msgstr "美式行政用紙(US Executive)" + +msgid "US Fanfold" +msgstr "美式折疊式報表紙(US Fanfold)" + +msgid "US Ledger" +msgstr "美式帳目報表紙(US Ledger)" + +msgid "US Legal" +msgstr "美式法定紙(US Legal)" + +msgid "US Legal (Oversize)" +msgstr "美式法定紙-超大型(US Legal-Oversize)" + +msgid "US Letter" +msgstr "美式信紙(US Letter)" + +msgid "US Letter (Oversize)" +msgstr "美式信紙-超大型(US Letter-Oversize)" + +msgid "US Letter (Small)" +msgstr "美式信紙-小型(US Letter-Small)" + +#, c-format +msgid "USB Serial Port #%d" +msgstr "USB 序列埠 #%d" + +msgid "Unable to access cupsd.conf file:" +msgstr "無法存取 cupsd.conf 檔案:" + +msgid "Unable to add RSS subscription:" +msgstr "無法加入 RSS 訂閱:" + +msgid "Unable to add class:" +msgstr "無法加入類別:" + +#, c-format +msgid "Unable to add job for destination \"%s\"!" +msgstr "無法為目的地“%s”加入作業!" + +msgid "Unable to add printer:" +msgstr "無法新增印表機:" + +msgid "Unable to allocate memory for file types!" +msgstr "無法為檔案類型分配記憶體!" + +msgid "Unable to cancel RSS subscription:" +msgstr "無法取消 RSS 訂閱:" + +msgid "Unable to change printer-is-shared attribute:" +msgstr "無法更改 printer-is-shared 屬性:" + +msgid "Unable to change printer:" +msgstr "無法更改印表機:" + +msgid "Unable to change server settings:" +msgstr "無法更改伺服器設定:" + +msgid "Unable to connect to host." +msgstr "無法連接主機。" + +#, c-format +msgid "Unable to copy 64-bit CUPS printer driver files (%d)!" +msgstr "無法拷貝 64 位元 CUPS 印表機驅動程式檔案(%d)!" + +#, c-format +msgid "Unable to copy 64-bit Windows printer driver files (%d)!" +msgstr "無法拷貝 64 位元 Windows 印表機驅動程式檔案(%d)!" + +#, c-format +msgid "Unable to copy CUPS printer driver files (%d)!" +msgstr "無法拷貝 CUPS 印表機驅動程式檔案(%d)!" + +#, c-format +msgid "Unable to copy PPD file - %s!" +msgstr "無法拷貝 PPD 檔案 - %s!" + +msgid "Unable to copy PPD file!" +msgstr "無法拷貝 PPD 檔案!" + +#, c-format +msgid "Unable to copy Windows 2000 printer driver files (%d)!" +msgstr "無法拷貝 Windows 2000 印表機驅動程式檔案(%d)!" + +#, c-format +msgid "Unable to copy Windows 9x printer driver files (%d)!" +msgstr "無法拷貝 Windows 9x 印表機驅動程式檔案(%d)!" + +#, c-format +msgid "Unable to copy interface script - %s!" +msgstr "無法拷貝介面工序指令 - %s!" + +msgid "Unable to create printer-uri!" +msgstr "無法製作 printer-uri!" + +msgid "Unable to create temporary file:" +msgstr "無法製作暫存檔:" + +msgid "Unable to delete class:" +msgstr "無法刪除類別:" + +msgid "Unable to delete printer:" +msgstr "無法刪除印表機:" + +msgid "Unable to do maintenance command:" +msgstr "無法執行維護指令:" + +msgid "Unable to edit cupsd.conf files larger than 1MB!" +msgstr "無法編輯大小超過 1MB 的 cupsd.conf 檔案!" + +msgid "Unable to find destination for job!" +msgstr "找不到作業的目的地!" + +msgid "Unable to find printer!\n" +msgstr "找不到印表機!\n" + +msgid "Unable to get class list:" +msgstr "無法取得類別列表:" + +msgid "Unable to get class status:" +msgstr "無法取得類別狀態:" + +msgid "Unable to get list of printer drivers:" +msgstr "無法取得印表機驅動程式的列表:" + +msgid "Unable to get printer attributes:" +msgstr "無法取得印表機屬性:" + +msgid "Unable to get printer list:" +msgstr "無法取得印表機列表:" + +msgid "Unable to get printer status:" +msgstr "無法取得印表機狀態:" + +#, c-format +msgid "Unable to install Windows 2000 printer driver files (%d)!" +msgstr "無法安裝 Windows 2000 印表機驅動程式檔案(%d)!" + +#, c-format +msgid "Unable to install Windows 9x printer driver files (%d)!" +msgstr "無法安裝 Windows 9x 印表機驅動程式檔案(%d)!" + +msgid "Unable to modify class:" +msgstr "無法修改類別:" + +msgid "Unable to modify printer:" +msgstr "無法修改印表機:" + +msgid "Unable to move job" +msgstr "無法移動作業" + +msgid "Unable to move jobs" +msgstr "無法移動作業" + +msgid "Unable to open PPD file" +msgstr "無法打開 PPD 檔案" + +msgid "Unable to open PPD file:" +msgstr "無法打開 PPD 檔案:" + +msgid "Unable to open cupsd.conf file:" +msgstr "無法打開 cupsd.conf 檔案:" + +#, c-format +msgid "Unable to open document %d in job %d!" +msgstr "無法打開文件 %d(在作業 %d 中)!" + +msgid "Unable to print test page:" +msgstr "無法列印測試頁面:" + +#, c-format +msgid "Unable to run \"%s\": %s\n" +msgstr "無法執行“%s”:%s\n" + +msgid "Unable to send command to printer driver!" +msgstr "無法將指令傳送至印表機驅動程式!" + +#, c-format +msgid "Unable to set Windows printer driver (%d)!" +msgstr "無法設定 Windows 印表機驅動程式(%d)!" + +msgid "Unable to set options:" +msgstr "無法設定選項:" + +msgid "Unable to set server default:" +msgstr "無法設定伺服器預設值:" + +msgid "Unable to upload cupsd.conf file:" +msgstr "無法上傳 cupsd.conf 檔案:" + +msgid "Unable to use legacy USB class driver!\n" +msgstr "無法使用繼承的 USB 類別驅動程式!\n" + +msgid "Unauthorized" +msgstr "未授權" + +msgid "Units" +msgstr "單位" + +msgid "Unknown" +msgstr "未知" + +#, c-format +msgid "Unknown printer-error-policy \"%s\"." +msgstr "未知的 printer-error-policy“%s”。" + +#, c-format +msgid "Unknown printer-op-policy \"%s\"." +msgstr "未知的 printer-op-policy“%s”。" + +#, c-format +msgid "Unsupported character set \"%s\"!" +msgstr "不受支援的字元集“%s”!" + +#, c-format +msgid "Unsupported compression \"%s\"!" +msgstr "不受支援的壓縮“%s”!" + +#, c-format +msgid "Unsupported compression attribute %s!" +msgstr "不受支援的壓縮屬性 %s!" + +#, c-format +msgid "Unsupported format \"%s\"!" +msgstr "不受支援的格式“%s”!" + +#, c-format +msgid "Unsupported format '%s'!" +msgstr "不受支援的格式 '%s'!" + +#, c-format +msgid "Unsupported format '%s/%s'!" +msgstr "不受支援的格式 '%s/%s'!" + +msgid "Unsupported value type" +msgstr "不受支援的值類型" + +msgid "Upgrade Required" +msgstr "需要升級" + +msgid "" +"Usage:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" +msgstr "" +"使用:\n" +"\n" +" lpadmin [-h server] -d destination\n" +" lpadmin [-h server] -x destination\n" +" lpadmin [-h server] -p printer [-c add-class] [-i interface] [-m model]\n" +" [-r remove-class] [-v device] [-D description]\n" +" [-P ppd-file] [-o name=value]\n" +" [-u allow:user,user] [-u deny:user,user]\n" +"\n" + +#, c-format +msgid "Usage: %s job user title copies options [filename]\n" +msgstr "使用:%s 作業使用者標題拷貝選項 [檔名]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options [file]\n" +msgstr "使用:%s job-id 使用者標題拷貝選項 [檔案]\n" + +#, c-format +msgid "Usage: %s job-id user title copies options file\n" +msgstr "使用:%s job-id 使用者標題拷貝選項檔案\n" + +msgid "" +"Usage: convert [ options ]\n" +"\n" +"Options:\n" +"\n" +" -e Use every filter from the PPD file\n" +" -f filename Set file to be converted (otherwise stdin)\n" +" -o filename Set file to be generated (otherwise stdout)\n" +" -i mime/type Set input MIME type (otherwise auto-typed)\n" +" -j mime/type Set output MIME type (otherwise application/pdf)\n" +" -P filename.ppd Set PPD file\n" +" -a 'name=value ...' Set option(s)\n" +" -U username Set username for job\n" +" -J title Set title\n" +" -c copies Set number of copies\n" +" -u Remove the PPD file when finished\n" +" -D Remove the input file when finished\n" +msgstr "" + +msgid "" +"Usage: cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"Options:\n" +" -E Encrypt the connection to the server\n" +" -H samba-server Use the named SAMBA server\n" +" -U samba-user Authenticate using the named SAMBA user\n" +" -a Export all printers\n" +" -h cups-server Use the named CUPS server\n" +" -v Be verbose (show commands)\n" +msgstr "" +"使用:cupsaddsmb [options] printer1 ... printerN\n" +" cupsaddsmb [options] -a\n" +"\n" +"選項:\n" +" -E 加密與伺服器的連線\n" +" -H samba-server 使用已命名的 SAMBA 伺服器\n" +" -U samba-user 使用已命名的 SAMBA 使用者進行認證\n" +" -a 輸出所有印表機\n" +" -h cups-server 使用已命名的 CUPS 伺服器\n" +" -v 列出明細(顯示指令)\n" + +msgid "" +"Usage: cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"Options:\n" +"\n" +" -E Enable encryption\n" +" -U username Specify username\n" +" -h server[:port] Specify server address\n" +"\n" +" --[no-]debug-logging Turn debug logging on/off\n" +" --[no-]remote-admin Turn remote administration on/off\n" +" --[no-]remote-any Allow/prevent access from the Internet\n" +" --[no-]remote-printers Show/hide remote printers\n" +" --[no-]share-printers Turn printer sharing on/off\n" +" --[no-]user-cancel-any Allow/prevent users to cancel any job\n" +msgstr "" +"使用:cupsctl [options] [param=value ... paramN=valueN]\n" +"\n" +"選項:\n" +"\n" +" -E 啟用加密\n" +" -U username 指定使用者名稱\n" +" -h server[:port] 指定伺服器位址\n" +"\n" +" --[no-]debug-logging 開啟/關閉除錯記錄\n" +" --[no-]remote-admin 開啟/關閉遠端管理\n" +" --[no-]remote-any 允許∕不允許從 Internet 存取\n" +" --[no-]remote-printers 顯示∕隱藏遠端印表機\n" +" --[no-]share-printers 開啟/關閉印表機共享\n" +" --[no-]user-cancel-any 允許∕不允許使用者取消任何作業\n" + +msgid "" +"Usage: cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file Load alternate configuration file\n" +"-f Run in the foreground\n" +"-F Run in the foreground but detach\n" +"-h Show this usage message\n" +"-l Run cupsd from launchd(8)\n" +msgstr "" +"使用:cupsd [-c config-file] [-f] [-F] [-h] [-l]\n" +"\n" +"-c config-file 載入替用配置檔案\n" +"-f 在前景執行\n" +"-F 在前景執行但與之分離\n" +"-h 顯示本用法訊息\n" +"-l 從 launchd(8) 執行 cupsd\n" + +msgid "" +"Usage: cupsfilter -m mime/type [ options ] filename\n" +"\n" +"Options:\n" +"\n" +" -c cupsd.conf Set cupsd.conf file to use\n" +" -e Use every filter from the PPD file\n" +" -j job-id[,N] Filter file N from the specified job (default is file 1)\n" +" -n copies Set number of copies\n" +" -o name=value Set option(s)\n" +" -p filename.ppd Set PPD file\n" +" -t title Set title\n" +msgstr "" + +msgid "" +"Usage: cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"Options:\n" +"\n" +" -h Show program usage\n" +"\n" +" Note: this program only validates the DSC comments, not the PostScript " +"itself.\n" +msgstr "" +"使用:cupstestdsc [options] filename.ps [... filename.ps]\n" +" cupstestdsc [options] -\n" +"\n" +"選項:\n" +"\n" +" -h 顯示程式用法\n" +"\n" +" NOTICE: 此程式僅驗證 DSC 註解,而不是 PostScript 本身。\n" + +msgid "" +"Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +" program | cupstestppd [options] -\n" +"\n" +"Options:\n" +"\n" +" -R root-directory Set alternate root\n" +" -W {all,none,constraints,defaults,duplex,filters,profiles,sizes," +"translations}\n" +" Issue warnings instead of errors\n" +" -q Run silently\n" +" -r Use 'relaxed' open mode\n" +" -v Be slightly verbose\n" +" -vv Be very verbose\n" +msgstr "" + +msgid "Usage: lpmove job/src dest\n" +msgstr "使用:lpmove job/src dest\n" + +msgid "" +"Usage: lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" +msgstr "" +"使用:lpoptions [-h server] [-E] -d printer\n" +" lpoptions [-h server] [-E] [-p printer] -l\n" +" lpoptions [-h server] [-E] -p printer -o option[=value] ...\n" +" lpoptions [-h server] [-E] -x printer\n" + +msgid "Usage: lppasswd [-g groupname]\n" +msgstr "使用:lppasswd [-g groupname]\n" + +msgid "" +"Usage: lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" +msgstr "" +"使用:lppasswd [-g groupname] [username]\n" +" lppasswd [-g groupname] -a [username]\n" +" lppasswd [-g groupname] -x [username]\n" + +msgid "" +"Usage: lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" +msgstr "" +"使用:lpq [-P dest] [-U username] [-h hostname[:port]] [-l] [+interval]\n" + +msgid "" +"Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -c catalog.po Load the specified message catalog.\n" +" -d output-dir Specify the output directory.\n" +" -l lang[,lang,...] Specify the output language(s) (locale).\n" +" -m Use the ModelName value as the filename.\n" +" -t Test PPDs instead of generating them.\n" +" -v Be verbose (more v's for more verbosity).\n" +" -z Compress PPD files using GNU zip.\n" +" --cr End lines with CR (Mac OS 9).\n" +" --crlf End lines with CR + LF (Windows).\n" +" --lf End lines with LF (UNIX/Linux/Mac OS X).\n" +msgstr "" +"使用:ppdc [options] filename.drv [ ... filenameN.drv ]\n" +"選項:\n" +" -D name=value 為已命名的變數設定值。\n" +" -I include-dir 將包含的目錄加入搜尋路徑。\n" +" -c catalog.po 載入指定的訊息目錄。\n" +" -d output-dir 指定輸出目錄。\n" +" -l lang[,lang,...] 指定輸出語言(區域環境設定)。\n" +" -m 使用 ModelName 值作為檔名。\n" +" -t 測試而不是產生 PPD。\n" +" -v 列出明細(v 越多就越詳盡)。\n" +" -z 使用 GNU zip 壓縮 PPD 檔案。\n" +" --cr 以 CR 作為行結尾(Mac OS 9)。\n" +" --crlf 以 CR + LF 作為行結尾(Windows)。\n" +" --lf 以 LF 作為行結尾(UNIX/Linux/Mac OS X)。\n" + +msgid "" +"Usage: ppdhtml [options] filename.drv >filename.html\n" +" -D name=value Set named variable to value.\n" +"Options:\n" +" -I include-dir Add include directory to search path.\n" +msgstr "" +"使用:ppdhtml [options] filename.drv >filename.html\n" +" -D name=value 為已命名的變數設定值。\n" +"選項:\n" +" -I include-dir 將包含的目錄加入搜尋路徑。\n" + +msgid "" +"Usage: ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -I include-dir\n" +" -o filename.drv\n" +msgstr "" +"使用:ppdi [options] filename.ppd [ ... filenameN.ppd ]\n" +"選項:\n" +" -I include-dir\n" +" -o filename.drv\n" + +msgid "" +"Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"Options:\n" +" -o filename.ppd[.gz]\n" +msgstr "" +"使用:ppdmerge [options] filename.ppd [ ... filenameN.ppd ]\n" +"選項:\n" +" -o filename.ppd[.gz]\n" + +msgid "" +"Usage: ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"Options:\n" +" -D name=value Set named variable to value.\n" +" -I include-dir Add include directory to search path.\n" +" -v Be verbose (more v's for more verbosity).\n" +msgstr "" +"使用:ppdpo [options] -o filename.po filename.drv [ ... filenameN.drv ]\n" +"選項:\n" +" -D name=value 為已命名的變數設定值。\n" +" -I include-dir 將包含的目錄加入搜尋路徑。\n" +" -v 列出明細(v 越多就越詳盡)。\n" + +msgid "Usage: snmp [host-or-ip-address]\n" +msgstr "使用:snmp [host-or-ip-address]\n" + +msgid "Value uses indefinite length" +msgstr "值使用的長度不確定" + +msgid "VarBind uses indefinite length" +msgstr "VarBind 使用的長度不確定" + +msgid "Version uses indefinite length" +msgstr "版本使用的長度不確定" + +#, c-format +msgid "WARNING: Adding only the first %d printers found" +msgstr "WARNING: 僅加入找到的前 %d 個印表機" + +#, c-format +msgid "WARNING: Boolean expected for waiteof option \"%s\"\n" +msgstr "WARNING: waiteof 選項“%s”預期為布林類型\n" + +msgid "WARNING: Failed to read side-channel request!\n" +msgstr "WARNING: 無法讀取 side-channel 請求!\n" + +#, c-format +msgid "WARNING: Option \"%s\" cannot be included via IncludeFeature!\n" +msgstr "WARNING: 無法透過 IncludeFeature 併入選項“%s”!\n" + +msgid "WARNING: Printer not responding\n" +msgstr "WARNING: 印表機未回應!" + +msgid "WARNING: Printer sent unexpected EOF\n" +msgstr "WARNING: 印表機傳送了非預期的 EOF\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with command status byte after %d " +"seconds!\n" +msgstr "WARNING: 遠端主機未在 %d 秒後對指令狀態位元組產生回應!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with control status byte after %d " +"seconds!\n" +msgstr "WARNING: 遠端主機未在 %d 秒後對控制狀態位元組產生回應!\n" + +#, c-format +msgid "" +"WARNING: Remote host did not respond with data status byte after %d " +"seconds!\n" +msgstr "WARNING: 遠端主機未在 %d 秒後對資料狀態位元組產生回應!\n" + +#, c-format +msgid "WARNING: SCSI command timed out (%d); retrying...\n" +msgstr "WARNING: SCSI 指令逾時(%d);正在重試⋯\n" + +msgid "" +"WARNING: This document does not conform to the Adobe Document Structuring " +"Conventions and may not print correctly!\n" +msgstr "WARNING: 此文件未遵循“Adobe 文件結構慣例”,而且不能正確地列印!\n" + +#, c-format +msgid "WARNING: Unable to open \"%s:%s\": %s\n" +msgstr "WARNING: 無法打開“%s:%s”:%s\n" + +msgid "WARNING: Unable to send PAP status request" +msgstr "WARNING: 無法傳送 PAP 狀態請求!" + +#, c-format +msgid "WARNING: Unexpected PAP packet of type %d\n" +msgstr "WARNING: 類型 %d 的非預期 PAP 封包\n" + +#, c-format +msgid "WARNING: Unknown PAP packet of type %d\n" +msgstr "WARNING: 類型 %d 的未知 PAP 封包\n" + +#, c-format +msgid "WARNING: Unknown choice \"%s\" for option \"%s\"!\n" +msgstr "WARNING: 未知的選項“%s”(針對選項“%s”)!\n" + +#, c-format +msgid "WARNING: Unknown option \"%s\"!\n" +msgstr "WARNING: 未知的選項“%s”!\n" + +#, c-format +msgid "WARNING: Unsupported baud rate %s!\n" +msgstr "WARNING: 不受支援的傳輸速率 %s!\n" + +#, c-format +msgid "WARNING: number expected for status option \"%s\"\n" +msgstr "WARNING: 狀態選項“%s”預期為數字\n" + +#, c-format +msgid "" +"WARNING: recoverable: Network host '%s' is busy; will retry in %d " +"seconds...\n" +msgstr "WARNING: 可回復:網路主機 '%s' 忙碌中;%d 內將重試⋯\n" + +msgid "Warning, no Windows 2000 printer drivers are installed!" +msgstr "警告,未安裝 Windows 2000 印表機驅動程式!" + +msgid "Yes" +msgstr "是" + +#, c-format +msgid "" +"You must access this page using the URL https://%" +"s:%d%s." +msgstr "" +"您必須使用 URL https://%s:%d%s 存取此頁面。" + +msgid "You4 Envelope" +msgstr "You4 信封" + +msgid "ZPL Label Printer" +msgstr "ZPL 標籤印表機" + +msgid "Zebra" +msgstr "Zebra" + +msgid "aborted" +msgstr "已中止" + +msgid "canceled" +msgstr "已取消" + +msgid "completed" +msgstr "已完成" + +msgid "convert: Use the -f option to specify a file to convert.\n" +msgstr "convert:使用 -f 選項來指定要轉換的檔案。\n" + +msgid "cups-deviced failed to execute." +msgstr "無法執行 cups-deviced。" + +msgid "cups-driverd failed to execute." +msgstr "無法執行 cups-driverd。" + +#, c-format +msgid "cupsaddsmb: No PPD file for printer \"%s\" - %s\n" +msgstr "cupsaddsmb:沒有適用於印表機“%s”的 PPD 檔案 - %s\n" + +#, c-format +msgid "cupsctl: Unable to connect to server: %s\n" +msgstr "cupsctl:無法連接伺服器:%s\n" + +#, c-format +msgid "cupsctl: Unknown option \"%s\"!\n" +msgstr "cupsctl:未知的選項“%s”!\n" + +#, c-format +msgid "cupsctl: Unknown option \"-%c\"!\n" +msgstr "cupsctl:未知的選項“-%c”!\n" + +msgid "cupsd: Expected config filename after \"-c\" option!\n" +msgstr "cupsd:“-c”選項後面預期為配置檔案名稱!\n" + +msgid "cupsd: Unable to get current directory!\n" +msgstr "cupsd:無法取得目前的目錄!\n" + +#, c-format +msgid "cupsd: Unknown argument \"%s\" - aborting!\n" +msgstr "cupsd:未知的參數“%s”- 正在中止!\n" + +#, c-format +msgid "cupsd: Unknown option \"%c\" - aborting!\n" +msgstr "cupsd:未知的選項“%c”- 正在中止!\n" + +msgid "cupsd: launchd(8) support not compiled in, running in normal mode.\n" +msgstr "cupsd:未編譯入 launchd(8) 支援,在正常模式下執行。\n" + +#, c-format +msgid "cupsfilter: Invalid document number %d!\n" +msgstr "cupsfilter:無效的文件編號 %d!\n" + +#, c-format +msgid "cupsfilter: Invalid job ID %d!\n" +msgstr "cupsfilter:無效的作業 ID %d!\n" + +msgid "cupsfilter: Only one filename can be specified!\n" +msgstr "cupsfilter:只能指定一個檔名!\n" + +#, c-format +msgid "cupsfilter: Unable to get job file - %s\n" +msgstr "cupsfilter:無法取得作業檔案 - %s\n" + +msgid "cupstestppd: The -q option is incompatible with the -v option.\n" +msgstr "cupstestppd:-q 選項與 -v 選項不相容。\n" + +msgid "cupstestppd: The -v option is incompatible with the -q option.\n" +msgstr "cupstestppd:-v 選項與 -q 選項不相容。\n" + +#, c-format +msgid "device for %s/%s: %s\n" +msgstr "%s/%s 的設備:%s\n" + +#, c-format +msgid "device for %s: %s\n" +msgstr "%s 的設備:%s\n" + +msgid "error-index uses indefinite length" +msgstr "error-index 使用的長度不確定" + +msgid "error-status uses indefinite length" +msgstr "error-status 使用的長度不確定" + +msgid "held" +msgstr "暫停" + +msgid "help\t\tget help on commands\n" +msgstr "輔助說明\t\t取得指令的輔助說明\n" + +msgid "idle" +msgstr "閒置" + +msgid "job-printer-uri attribute missing!" +msgstr "job-printer-uri 屬性遺失!" + +msgid "lpadmin: Class name can only contain printable characters!\n" +msgstr "lpadmin:類別名稱只能包含可列印的字元!\n" + +msgid "lpadmin: Expected PPD after '-P' option!\n" +msgstr "lpadmin:'-P' 選項後面預期為 PPD!\n" + +msgid "lpadmin: Expected allow/deny:userlist after '-u' option!\n" +msgstr "lpadmin:&aops;-u&aops; 選項後面預期為 allow/deny:userlist!\n" + +msgid "lpadmin: Expected class after '-r' option!\n" +msgstr "lpadmin:&aops;-r&aops; 選項後面預期為類別!\n" + +msgid "lpadmin: Expected class name after '-c' option!\n" +msgstr "lpadmin:&aops;-c&aops; 選項後面預期為類別名稱!\n" + +msgid "lpadmin: Expected description after '-D' option!\n" +msgstr "lpadmin:&aops;-D&aops; 選項後面預期為描述!\n" + +msgid "lpadmin: Expected device URI after '-v' option!\n" +msgstr "lpadmin:&aops;-v&aops; 選項後面預期為設備 URI!\n" + +msgid "lpadmin: Expected file type(s) after '-I' option!\n" +msgstr "lpadmin:&aops;-I&aops; 選項後面預期為檔案類型!\n" + +msgid "lpadmin: Expected hostname after '-h' option!\n" +msgstr "lpadmin:&aops;-h&aops; 選項後面預期為主機名稱!\n" + +msgid "lpadmin: Expected interface after '-i' option!\n" +msgstr "lpadmin:&aops;-i&aops; 選項後面預期為介面!\n" + +msgid "lpadmin: Expected location after '-L' option!\n" +msgstr "lpadmin:'-L' 選項後面預期為位置!\n" + +msgid "lpadmin: Expected model after '-m' option!\n" +msgstr "lpadmin:'-m' 選項後面預期為型號!\n" + +msgid "lpadmin: Expected name=value after '-o' option!\n" +msgstr "lpadmin:&aops;-o&aops; 選項後面預期為 name=value!\n" + +msgid "lpadmin: Expected printer after '-p' option!\n" +msgstr "lpadmin:'-p' 選項後面預期為印表機!\n" + +msgid "lpadmin: Expected printer name after '-d' option!\n" +msgstr "lpadmin:'-d' 選項後面預期為印表機名稱!\n" + +msgid "lpadmin: Expected printer or class after '-x' option!\n" +msgstr "lpadmin:'-x' 選項後面預期為印表機或類別!\n" + +msgid "lpadmin: No member names were seen!\n" +msgstr "lpadmin:未發現會員名稱!\n" + +#, c-format +msgid "lpadmin: Printer %s is already a member of class %s.\n" +msgstr "lpadmin:印表機 %s 已經是類別 %s 的成員。\n" + +#, c-format +msgid "lpadmin: Printer %s is not a member of class %s.\n" +msgstr "lpadmin:印表機 %s 不是類別 %s 的成員。\n" + +msgid "lpadmin: Printer name can only contain printable characters!\n" +msgstr "lpadmin:印表機名稱只能包含可列印的字元!\n" + +msgid "" +"lpadmin: Unable to add a printer to the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法將印表機加入到類別:\n" +" 您必須現指定印表機名稱!\n" + +#, c-format +msgid "lpadmin: Unable to connect to server: %s\n" +msgstr "lpadmin:無法連接伺服器:%s\n" + +#, c-format +msgid "lpadmin: Unable to open PPD file \"%s\" - %s\n" +msgstr "lpadmin:無法打開 PPD 檔案“%s”- %s\n" + +#, c-format +msgid "lpadmin: Unable to open file \"%s\": %s\n" +msgstr "lpadmin:無法打開檔案“%s”:%s\n" + +msgid "" +"lpadmin: Unable to remove a printer from the class:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法從類別中移除印表機:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定 PPD 檔案:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the device URI:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定設備 URI:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the interface script or PPD file:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定 PPD 檔案的介面工序指令:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the interface script:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定介面工序指令:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the printer description:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定印表機描述:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the printer location:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定印表機位置:\n" +" 您必須先指定印表機名稱!\n" + +msgid "" +"lpadmin: Unable to set the printer options:\n" +" You must specify a printer name first!\n" +msgstr "" +"lpadmin:無法設定印表機選項:\n" +" 您必須先指定印表機名稱!\n" + +#, c-format +msgid "lpadmin: Unknown allow/deny option \"%s\"!\n" +msgstr "lpadmin:未知的 allow/deny 選項“%s”!\n" + +#, c-format +msgid "lpadmin: Unknown argument '%s'!\n" +msgstr "lpadmin:未知的參數 '%s'!\n" + +#, c-format +msgid "lpadmin: Unknown option '%c'!\n" +msgstr "lpadmin:未知的選項 '%c'!\n" + +msgid "lpadmin: Warning - content type list ignored!\n" +msgstr "lpadmin:警告 - 已忽略內容類型列表!\n" + +msgid "lpc> " +msgstr "lpc> " + +msgid "lpinfo: Expected 1284 device ID string after --device-id!\n" +msgstr "lpinfo:--device-id 後面預期為 1284 設備 ID 字串!\n" + +msgid "lpinfo: Expected language after --language!\n" +msgstr "lpinfo:--language 後面預期為語言!\n" + +msgid "lpinfo: Expected make and model after --make-and-model!\n" +msgstr "lpinfo:--make-and-model 後面預期為製造和型號!\n" + +msgid "lpinfo: Expected product string after --product!\n" +msgstr "lpinfo:--product 後面預期為產品字串!\n" + +msgid "lpinfo: Expected scheme list after --exclude-schemes!\n" +msgstr "lpinfo:--exclude-schemes 後面預期為架構列表!\n" + +msgid "lpinfo: Expected scheme list after --include-schemes!\n" +msgstr "lpinfo:--include-schemes 後面預期為架構列表!\n" + +msgid "lpinfo: Expected timeout after --timeout!\n" +msgstr "lpinfo:--timeout 後面預期為逾時!\n" + +#, c-format +msgid "lpinfo: Unknown argument '%s'!\n" +msgstr "lpinfo:未知的參數 '%s'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%c'!\n" +msgstr "lpinfo:未知的選項 '%c'!\n" + +#, c-format +msgid "lpinfo: Unknown option '%s'!\n" +msgstr "lpinfo:未知的選項 '%s'!\n" + +#, c-format +msgid "lpmove: Unable to connect to server: %s\n" +msgstr "lpmove:無法連接伺服器:%s\n" + +#, c-format +msgid "lpmove: Unknown argument '%s'!\n" +msgstr "lpmove:未知的參數 '%s'!\n" + +#, c-format +msgid "lpmove: Unknown option '%c'!\n" +msgstr "lpmove:未知的選項 '%c'!\n" + +msgid "lpoptions: No printers!?!\n" +msgstr "lpoptions:沒有印表機!?!\n" + +#, c-format +msgid "lpoptions: Unable to add printer or instance: %s\n" +msgstr "lpoptions:無法新增印表機或實例:%s\n" + +#, c-format +msgid "lpoptions: Unable to get PPD file for %s: %s\n" +msgstr "lpoptions:無法取得 %s 的 PPD 檔案:%s\n" + +#, c-format +msgid "lpoptions: Unable to open PPD file for %s!\n" +msgstr "lpoptions:無法打開 %s 的 PPD 檔案!\n" + +msgid "lpoptions: Unknown printer or class!\n" +msgstr "lpoptions:未知的印表機或類別!\n" + +msgid "lppasswd: Only root can add or delete passwords!\n" +msgstr "lppasswd:只有 root 使用者才能加入或刪除密碼!\n" + +msgid "lppasswd: Password file busy!\n" +msgstr "lppasswd:密碼檔案忙碌中!\n" + +msgid "lppasswd: Password file not updated!\n" +msgstr "lppasswd:未更新密碼檔案!\n" + +msgid "lppasswd: Sorry, password doesn't match!\n" +msgstr "lppasswd:抱歉,密碼不相符!\n" + +msgid "" +"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" +msgstr "" +"lppasswd:抱歉,密碼遭到拒絕。\n" +"您的密碼長度至少必須為 6 個字元,不能包含\n" +"使用者名稱,而且至少必須包含一個字母和數字。\n" + +msgid "lppasswd: Sorry, passwords don't match!\n" +msgstr "lppasswd:抱歉,密碼不相符!\n" + +#, c-format +msgid "lppasswd: Unable to copy password string: %s\n" +msgstr "lppasswd:無法拷貝密碼字串:%s\n" + +#, c-format +msgid "lppasswd: Unable to open password file: %s\n" +msgstr "lppasswd:無法打開密碼檔案:%s\n" + +#, c-format +msgid "lppasswd: Unable to write to password file: %s\n" +msgstr "lppasswd:無法寫入密碼檔案:%s\n" + +#, c-format +msgid "lppasswd: failed to backup old password file: %s\n" +msgstr "lppasswd:無法備份舊的密碼檔案:%s\n" + +#, c-format +msgid "lppasswd: failed to rename password file: %s\n" +msgstr "lppasswd:無法重新命名密碼檔案:%s\n" + +#, c-format +msgid "lppasswd: user \"%s\" and group \"%s\" do not exist.\n" +msgstr "lppasswd:使用者“%s”和群組“%s”不存在。\n" + +#, c-format +msgid "" +"lpstat: error - %s environment variable names non-existent destination \"%s" +"\"!\n" +msgstr "lpstat:錯誤 - %s 環境變數名稱中有不存在的目的地“%s”!\n" + +#, c-format +msgid "members of class %s:\n" +msgstr "類別 %s 的成員:\n" + +msgid "no entries\n" +msgstr "沒有項目\n" + +msgid "no system default destination\n" +msgstr "沒有系統預設目的地\n" + +msgid "notify-events not specified!" +msgstr "未指定 notify-events!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" is already used!" +msgstr "notify-recipient-uri URI“%s”已被使用!" + +#, c-format +msgid "notify-recipient-uri URI \"%s\" uses unknown scheme!" +msgstr "notify-recipient-uri URI“%s”使用的是未知的架構!" + +#, c-format +msgid "notify-subscription-id %d no good!" +msgstr "notify-subscription-id %d 不合適!" + +msgid "pending" +msgstr "等待中" + +#, c-format +msgid "ppdc: Adding include directory \"%s\"...\n" +msgstr "ppdc:正在加入包含的目錄“%s”⋯\n" + +#, c-format +msgid "ppdc: Adding/updating UI text from %s...\n" +msgstr "ppdc:正在從 %s 加入/更新 UI 文字⋯\n" + +#, c-format +msgid "ppdc: Bad boolean value (%s) on line %d of %s.\n" +msgstr "ppdc:錯誤的布林值(%1$s),在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Bad resolution name \"%s\" on line %d of %s!\n" +msgstr "ppdc:錯誤的解析度名稱“%1$s”,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Bad status keyword %s on line %d of %s!\n" +msgstr "ppdc:錯誤的狀態關鍵字 %1$s,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Bad variable substitution ($%c) on line %d of %s.\n" +msgstr "ppdc:錯誤的變數替代($%1$c),在 %3$s 的第 %2$d 行。\n" + +#, c-format +msgid "ppdc: Choice found on line %d of %s with no Option!\n" +msgstr "ppdc:在 %2$s 的第 %1$d 行發現沒有“選項”的選擇!\n" + +#, c-format +msgid "ppdc: Duplicate #po for locale %s on line %d of %s!\n" +msgstr "ppdc:環境變數 %1$s 的 #po 重複,在 %3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Expected a filter definition on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有過濾定義!\n" + +#, c-format +msgid "ppdc: Expected a program name on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有程式名稱!\n" + +#, c-format +msgid "ppdc: Expected boolean value on line %d of %s.\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有布林值。\n" + +#, c-format +msgid "ppdc: Expected charset after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Font 後面預期為字元集!\n" + +#, c-format +msgid "ppdc: Expected choice code on line %d of %s.\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有選項代碼。\n" + +#, c-format +msgid "ppdc: Expected choice name/text on line %d of %s.\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有選項名稱/文字。\n" + +#, c-format +msgid "ppdc: Expected color order for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有 ColorModel 的顏色體系!\n" + +#, c-format +msgid "ppdc: Expected colorspace for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有 ColorModel 的色彩空間!\n" + +#, c-format +msgid "ppdc: Expected compression for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有 ColorModel 的壓縮度!\n" + +#, c-format +msgid "ppdc: Expected constraints string for UIConstraints on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有 UIConstraints 的限制字串!\n" + +#, c-format +msgid "" +"ppdc: Expected driver type keyword following DriverType on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 DriverType 後面預期有驅動程式類型關鍵字!\n" + +#, c-format +msgid "ppdc: Expected duplex type after Duplex on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Duplex 後面預期有兩用裝紙匣類型!\n" + +#, c-format +msgid "ppdc: Expected encoding after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Font 後面預期為編碼!\n" + +#, c-format +msgid "ppdc: Expected filename after #po %s on line %d of %s!\n" +msgstr "ppdc:#po %1$s 後面預期為檔名,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Expected group name/text on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有群組名稱/文字!\n" + +#, c-format +msgid "ppdc: Expected include filename on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有包含的檔名!\n" + +#, c-format +msgid "ppdc: Expected integer on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有整數!\n" + +#, c-format +msgid "ppdc: Expected locale after #po on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 #po 後面預期有環境變數!\n" + +#, c-format +msgid "ppdc: Expected name after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 後面預期有名稱,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Expected name after FileName on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 FileName 後面預期為名稱!\n" + +#, c-format +msgid "ppdc: Expected name after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Font 後面預期為名稱!\n" + +#, c-format +msgid "ppdc: Expected name after Manufacturer on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Manufacturer 後面預期為名稱!\n" + +#, c-format +msgid "ppdc: Expected name after MediaSize on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 MediaSize 後面預期為名稱!\n" + +#, c-format +msgid "ppdc: Expected name after ModelName on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 ModelName 後面預期為名稱!\n" + +#, c-format +msgid "ppdc: Expected name after PCFileName on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 PCFileName 後面預期為名稱!\n" + +#, c-format +msgid "ppdc: Expected name/text after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 後面預期為名稱/文字,在 %3$s 的第 %2$d 行上。\n" + +#, c-format +msgid "ppdc: Expected name/text after Installable on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Installable 後面預期為名稱/文字!\n" + +#, c-format +msgid "ppdc: Expected name/text after Resolution on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Resolution 後面預期為名稱/文字!\n" + +#, c-format +msgid "ppdc: Expected name/text combination for ColorModel on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有 ColorModel 的名稱/文字組合!\n" + +#, c-format +msgid "ppdc: Expected option name/text on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有選項名稱/文字!\n" + +#, c-format +msgid "ppdc: Expected option section on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有選項部分!\n" + +#, c-format +msgid "ppdc: Expected option type on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有選項類型!\n" + +#, c-format +msgid "ppdc: Expected override field after Resolution on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Resolution 後面預期有覆蓋欄位!\n" + +#, c-format +msgid "ppdc: Expected real number on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有實數!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following ColorProfile on line %d of %" +"s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 ColorProfile 後面預期有解析度∕媒體類型!\n" + +#, c-format +msgid "" +"ppdc: Expected resolution/mediatype following SimpleColorProfile on line %d " +"of %s!\n" +msgstr "" +"ppdc:%2$s 的第 %1$d 行上 SimpleColorProfile 後面預期有解析度∕媒體類型!\n" + +#, c-format +msgid "ppdc: Expected selector after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 後面預期有選擇器,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Expected status after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Font 後面預期為狀態!\n" + +#, c-format +msgid "ppdc: Expected string after Copyright on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Copyright 後面預期有字串!\n" + +#, c-format +msgid "ppdc: Expected string after Version on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Version 後面預期有字串!\n" + +#, c-format +msgid "ppdc: Expected two option names on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上預期有兩個選項名稱!\n" + +#, c-format +msgid "ppdc: Expected value after %s on line %d of %s!\n" +msgstr "ppdc:%1$s 後面預期有值,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Expected version after Font on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上 Font 後面預期有版本!\n" + +#, c-format +msgid "ppdc: Invalid #include/#po filename \"%s\"!\n" +msgstr "ppdc:無效的 #include/#po 檔名“%s”!\n" + +#, c-format +msgid "ppdc: Invalid cost for filter on line %d of %s!\n" +msgstr "ppdc:%2$s 第 %1$d 行上的過濾成本無效!\n" + +#, c-format +msgid "ppdc: Invalid empty MIME type for filter on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上用於過濾的空 MIME 類型無效!\n" + +#, c-format +msgid "ppdc: Invalid empty program name for filter on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行上用於過濾的空程式名稱無效!\n" + +#, c-format +msgid "ppdc: Invalid option section \"%s\" on line %d of %s!\n" +msgstr "ppdc:無效的選項部分“%1$s”,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Invalid option type \"%s\" on line %d of %s!\n" +msgstr "ppdc:無效的選項類型“%1$s”,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Loading driver information file \"%s\"...\n" +msgstr "ppdc:正在載入驅動程式資訊檔案“%s”⋯\n" + +#, c-format +msgid "ppdc: Loading messages for locale \"%s\"...\n" +msgstr "ppdc:正在為環境變數“%s”載入訊息⋯\n" + +#, c-format +msgid "ppdc: Loading messages from \"%s\"...\n" +msgstr "ppdc:正在從“%s”載入訊息⋯\n" + +#, c-format +msgid "ppdc: Missing #endif at end of \"%s\"!\n" +msgstr "ppdc:“%s”末端遺失 #endif!\n" + +#, c-format +msgid "ppdc: Missing #if on line %d of %s!\n" +msgstr "ppdc:%2$s 的第 %1$d 行中遺失 #if!\n" + +#, c-format +msgid "ppdc: No message catalog provided for locale %s!\n" +msgstr "ppdc:沒有針對環境變數 %s 提供的訊息目錄!\n" + +#, c-format +msgid "ppdc: Option %s defined in two different groups on line %d of %s!\n" +msgstr "" + +#, c-format +msgid "ppdc: Option %s redefined with a different type on line %d of %s!\n" +msgstr "ppdc:在 %3$s 的第 %2$d: 行上,以不同的類型重複定義了選項 %1$s!\n" + +#, c-format +msgid "ppdc: Option constraint must *name on line %d of %s!\n" +msgstr "ppdc:%2$s 第 %1$d 行上的選項限制形式必須為 *name!\n" + +#, c-format +msgid "ppdc: Too many nested #if's on line %d of %s!\n" +msgstr "ppdc:%2$s 第 %1$d 行上的巢狀 #if 太多!\n" + +#, c-format +msgid "ppdc: Unable to create PPD file \"%s\" - %s.\n" +msgstr "ppdc:無法製作 PPD 檔案“%s”- %s。\n" + +#, c-format +msgid "ppdc: Unable to create output directory %s: %s\n" +msgstr "ppdc:無法製作輸出目錄 %s:%s\n" + +#, c-format +msgid "ppdc: Unable to create output pipes: %s\n" +msgstr "ppdc:無法製作輸出路徑:%s\n" + +#, c-format +msgid "ppdc: Unable to execute cupstestppd: %s\n" +msgstr "ppdc:無法執行 cupstestppd:%s\n" + +#, c-format +msgid "ppdc: Unable to find #po file %s on line %d of %s!\n" +msgstr "ppdc:在下列行中找不到 #po 檔案 %1$s:%3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Unable to find include file \"%s\" on line %d of %s!\n" +msgstr "ppdc:在下列行中找不到包含檔案“%1$s”:%3$s 的第 %2$d 行!\n" + +#, c-format +msgid "ppdc: Unable to find localization for \"%s\" - %s\n" +msgstr "ppdc:找不到本地化的“%s”- %s\n" + +#, c-format +msgid "ppdc: Unable to load localization file \"%s\" - %s\n" +msgstr "ppdc:無法載入本地化檔案“%s”- %s\n" + +#, c-format +msgid "ppdc: Undefined variable (%s) on line %d of %s.\n" +msgstr "ppdc:未定義的變數(%1$s),在 %3$s 的第 %2$d 行上。\n" + +#, c-format +msgid "ppdc: Unknown driver type %s on line %d of %s!\n" +msgstr "ppdc:未知的驅動程式類型 %1$s,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Unknown duplex type \"%s\" on line %d of %s!\n" +msgstr "ppdc:未知的兩用類型“%1$s”,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Unknown media size \"%s\" on line %d of %s!\n" +msgstr "ppdc:未知的媒體大小“%1$s”,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Unknown token \"%s\" seen on line %d of %s!\n" +msgstr "ppdc:發現未知的代號“%1$s”,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "" +"ppdc: Unknown trailing characters in real number \"%s\" on line %d of %s!\n" +msgstr "ppdc:實數“%1$s”中有未知的尾字元,在 %3$s 的第 %2$d 行上!\n" + +#, c-format +msgid "ppdc: Unterminated string starting with %c on line %d of %s!\n" +msgstr "ppdc:%3$s 的第 %2$d 行上有以 %1$c 開頭的未終止字串!\n" + +#, c-format +msgid "ppdc: Writing %s...\n" +msgstr "ppdc:正在寫入 %s⋯\n" + +#, c-format +msgid "ppdc: Writing PPD files to directory \"%s\"...\n" +msgstr "ppdc:正在將 PPD 檔案寫入目錄“%s”⋯\n" + +#, c-format +msgid "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n" +msgstr "ppdmerge:錯誤的 LanguageVersion“%s”,在 %s 中!\n" + +#, c-format +msgid "ppdmerge: Ignoring PPD file %s...\n" +msgstr "ppdmerge:正在忽略 PPD 檔案 %s⋯\n" + +#, c-format +msgid "ppdmerge: Unable to backup %s to %s- %s\n" +msgstr "ppdmerge:無法將 %s 備份到 %s- %s\n" + +#, c-format +msgid "printer %s disabled since %s -\n" +msgstr "印表機 %s 已停用,自 %s 後 -\n" + +#, c-format +msgid "printer %s is idle. enabled since %s\n" +msgstr "印表機 %s 處於閒置狀態,自 %s 後啟用\n" + +#, c-format +msgid "printer %s now printing %s-%d. enabled since %s\n" +msgstr "印表機 %s 正在列印 %s-%d。自 %s 後啟用\n" + +#, c-format +msgid "printer %s/%s disabled since %s -\n" +msgstr "印表機 %s/%s 自 %s 後停用 -\n" + +#, c-format +msgid "printer %s/%s is idle. enabled since %s\n" +msgstr "印表機 %s/%s 處於閑置狀態。自 %s 後啟用\n" + +#, c-format +msgid "printer %s/%s now printing %s-%d. enabled since %s\n" +msgstr "印表機 %s/%s 正在列印 %s-%d。自 %s 後啟用\n" + +msgid "processing" +msgstr "正在處理" + +#, c-format +msgid "request id is %s-%d (%d file(s))\n" +msgstr "請求 ID 為 %s-%d(%d 個檔案)\n" + +msgid "request-id uses indefinite length" +msgstr "request-id 使用的長度不確定" + +msgid "scheduler is not running\n" +msgstr "排程器並沒有執行\n" + +msgid "scheduler is running\n" +msgstr "排程器正在執行中\n" + +#, c-format +msgid "stat of %s failed: %s" +msgstr "啟動 %s 失敗:%s" + +msgid "status\t\tshow status of daemon and queue\n" +msgstr "狀態\t\t顯示服務程式和佇列的狀態\n" + +msgid "stopped" +msgstr "已停止" + +#, c-format +msgid "system default destination: %s\n" +msgstr "系統預設目的地:%s\n" + +#, c-format +msgid "system default destination: %s/%s\n" +msgstr "系統預設目的地:%s/%s\n" + +msgid "unknown" +msgstr "未知" + +msgid "untitled" +msgstr "未命名" + +msgid "variable-bindings uses indefinite length" +msgstr "variable-bindings 使用的長度不確定" + +#~ msgid " WARN Missing APDialogExtension file \"%s\"\n" +#~ msgstr " 警告 遺失 APDialogExtension 檔案“%s”\n" + +#~ msgid " WARN Missing APPrinterIconPath file \"%s\"\n" +#~ msgstr " 警告 遺失 APPrinterIconPath 檔案“%s”\n" + +#~ msgid "%s: Unable to open %s - %s\n" +#~ msgstr "%s:無法打開 %s - %s\n" + +#~ msgid "%s: Unable to open %s - %s on line %d.\n" +#~ msgstr "%s:無法打開 %s - %s 在第 %d 行。\n" + +#~ msgid "600 DPI Grayscale" +#~ msgstr "600 DPI 灰階" + +#~ msgid "" +#~ "ERROR: Missing device URI on command-line and no DEVICE_URI environment " +#~ "variable!\n" +#~ msgstr "ERROR: 指令行遺失設備 URI 且沒有 DEVICE_URI 環境變數!\n" + +#~ msgid "ERROR: Unable to create temporary file - %s.\n" +#~ msgstr "ERROR: 無法製作暫存檔 - %s。\n" + +#~ msgid "ERROR: Unable to create temporary file: %s\n" +#~ msgstr "ERROR: 無法製作暫存檔:%s\n" + +#~ msgid "ERROR: Unable to open temporary file" +#~ msgstr "ERROR: 無法打開暫存檔" + +#~ msgid "ERROR: pdftops filter crashed on signal %d!\n" +#~ msgstr "ERROR: pdftops 濾鏡在遇到訊號 %d 時當機!\n" + +#~ msgid "ERROR: pdftops filter exited with status %d!\n" +#~ msgstr "ERROR: pdftops 濾鏡以狀態 %d 結束!\n" + +#~ msgid "Unknown printer error (%s)!" +#~ msgstr "未知的印表機錯誤(%s)!" + +#~ msgid "" +#~ "Usage: convert [ options ]\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -f filename Set file to be converted (otherwise stdin)\n" +#~ " -o filename Set file to be generated (otherwise stdout)\n" +#~ " -i mime/type Set input MIME type (otherwise auto-typed)\n" +#~ " -j mime/type Set output MIME type (otherwise application/pdf)\n" +#~ " -P filename.ppd Set PPD file\n" +#~ " -a 'name=value ...' Set option(s)\n" +#~ " -U username Set username for job\n" +#~ " -J title Set title\n" +#~ " -c copies Set number of copies\n" +#~ " -u Remove the PPD file when finished\n" +#~ " -D Remove the input file when finished\n" +#~ msgstr "" +#~ "使用:convert [ options ]\n" +#~ "\n" +#~ "選項:\n" +#~ "\n" +#~ " -f filename 設定要轉換的檔案(否則為 stdin)\n" +#~ " -o filename 設定要產生的檔案(否則為 stdout)\n" +#~ " -i mime/type 設定輸入 MIME 類型(否則為 auto-typed)\n" +#~ " -j mime/type 設定輸出 MIME 類型(否則為 application/pdf)\n" +#~ " -P filename.ppd 設定 PPD 檔案\n" +#~ " -a 'name=value ...' 設定選項\n" +#~ " -U username 設定作業的使用者名稱\n" +#~ " -J title 設定標題\n" +#~ " -c copies 設定份數\n" +#~ " -u 完成時移除 PPD 檔案\n" +#~ " -D 完成時移除輸入檔案\n" + +#~ msgid "" +#~ "Usage: cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -c cupsd.conf Set cupsd.conf file to use\n" +#~ " -j job-id[,N] Filter file N from the specified job (default is file " +#~ "1)\n" +#~ " -n copies Set number of copies\n" +#~ " -o name=value Set option(s)\n" +#~ " -p filename.ppd Set PPD file\n" +#~ " -t title Set title\n" +#~ msgstr "" +#~ "使用:cupsfilter -m mime/type [ options ] filename\n" +#~ "\n" +#~ "選項:\n" +#~ "\n" +#~ " -c cupsd.conf 設定要使用的 cupsd.conf 檔案\n" +#~ " -j job-id[,N] 從指定的作業過濾檔案 N(預設為檔案 1)\n" +#~ " -n copies 設定份數\n" +#~ " -o name=value 設定選項\n" +#~ " -p filename.ppd 設定 PPD 檔案\n" +#~ " -t title 設定標題\n" + +#~ msgid "" +#~ "Usage: cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "Options:\n" +#~ "\n" +#~ " -R root-directory Set alternate root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " Issue warnings instead of errors\n" +#~ " -q Run silently\n" +#~ " -r Use 'relaxed' open mode\n" +#~ " -v Be slightly verbose\n" +#~ " -vv Be very verbose\n" +#~ msgstr "" +#~ "使用:cupstestppd [options] filename1.ppd[.gz] [... filenameN.ppd[.gz]]\n" +#~ " program | cupstestppd [options] -\n" +#~ "\n" +#~ "選項:\n" +#~ "\n" +#~ " -R root-directory 設定替用 root\n" +#~ " -W {all,none,constraints,defaults,duplex,filters,translations}\n" +#~ " 發出警告而不是錯誤\n" +#~ " -q 靜音執行\n" +#~ " -r 使用 'relaxed' 打開模式\n" +#~ " -v 列出明細\n" +#~ " -vv 列出詳盡明細\n" + +#~ msgid "cupsfilter: Unable to create temporary file: %s\n" +#~ msgstr "cupsfilter:無法製作暫存檔:%s\n" + +#~ msgid "lpadmin: Unable to create temporary file - %s\n" +#~ msgstr "lpadmin:無法製作暫存檔 - %s\n" + +#~ msgid "lpadmin: Unable to create temporary file: %s\n" +#~ msgstr "lpadmin:無法製作暫存檔:%s\n" diff --git a/locale/locale.txt b/locale/locale.txt new file mode 100644 index 0000000000..f9abe72d67 --- /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 . +The HTTP status messages use the status codes defined in . + +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/po2strings.c b/locale/po2strings.c new file mode 100644 index 0000000000..c2717bab41 --- /dev/null +++ b/locale/po2strings.c @@ -0,0 +1,172 @@ +/* + * "$Id$" + * + * Convert GNU gettext .po files to Apple .strings file (UTF-16 BE text file). + * + * Usage: + * + * po2strings filename.strings filename.po + * + * Compile with: + * + * gcc -o po2strings po2strings.c `cups-config --libs` + * + * Contents: + * + * main() - Convert .po file to .strings. + * write_string() - Write a string to the .strings file. + */ + +#include +#include +#include +#include + + +/* + * The .strings file format is simple: + * + * // comment + * "id" = "str"; + * + * Both the id and str strings use standard C quoting for special characters + * like newline and the double quote character. + */ + +/* + * Local functions... + */ + +static void write_string(FILE *strings, const char *s); + + +/* + * main() - Convert .po file to .strings. + */ + +int /* O - Exit code */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + FILE *strings; /* .strings file */ + cups_array_t *po; /* .po file */ + char iconv[1024]; /* iconv command */ + _cups_message_t *msg; /* Current message */ + const char *srcfile, /* Source file */ + *dstfile; /* Destination file */ + int use_msgid; /* Use msgid strings for msgstr? */ + + + srcfile = NULL; + dstfile = NULL; + use_msgid = 0; + + + for (i = 1; i < argc; i ++) + if (!strcmp(argv[i], "-m")) + use_msgid = 1; + else if (argv[i][0] == '-') + { + puts("Usage: po2strings [-m] filename.po filename.strings"); + return (1); + } + else if (srcfile == NULL) + srcfile = argv[i]; + else if (dstfile == NULL) + dstfile = argv[i]; + else + { + puts("Usage: po2strings [-m] filename.po filename.strings"); + return (1); + } + + if (!srcfile || !dstfile) + { + puts("Usage: po2strings [-m] filename.po filename.strings"); + return (1); + } + + /* + * Use the CUPS .po loader to get the message strings... + */ + + if ((po = _cupsMessageLoad(srcfile, 1)) == NULL) + { + perror(srcfile); + return (1); + } + + /* + * Cheat by using iconv to write the .strings file with a UTF-16 encoding. + * The .po file uses UTF-8... + */ + + snprintf(iconv, sizeof(iconv), "iconv -f utf-8 -t utf-16 >'%s'", dstfile); + if ((strings = popen(iconv, "w")) == NULL) + { + perror(argv[2]); + _cupsMessageFree(po); + return (1); + } + + for (msg = (_cups_message_t *)cupsArrayFirst(po); + msg; + msg = (_cups_message_t *)cupsArrayNext(po)) + { + write_string(strings, msg->id); + fputs(" = ", strings); + write_string(strings, use_msgid ? msg->id : msg->str); + fputs(";\n", strings); + } + + printf("%s: %d messages.\n", argv[2], cupsArrayCount(po)); + + pclose(strings); + _cupsMessageFree(po); + + return (0); +} + + +/* + * 'write_string()' - Write a string to the .strings file. + */ + +static void +write_string(FILE *strings, /* I - .strings file */ + const char *s) /* I - String to write */ +{ + putc('\"', strings); + + while (*s) + { + switch (*s) + { + case '\n' : + fputs("\\n", strings); + break; + case '\t' : + fputs("\\t", strings); + break; + case '\\' : + fputs("\\\\", strings); + break; + case '\"' : + fputs("\\\"", strings); + break; + default : + putc(*s, strings); + break; + } + + s ++; + } + + putc('\"', strings); +} + + +/* + * End of "$Id$". + */ diff --git a/locale/strings2po.c b/locale/strings2po.c new file mode 100644 index 0000000000..8df9059be4 --- /dev/null +++ b/locale/strings2po.c @@ -0,0 +1,175 @@ +/* + * "$Id$" + * + * Convert Apple .strings file (UTF-16 BE text file) to GNU gettext .po files. + * + * Usage: + * + * strings2po filename.strings filename.po + * + * Compile with: + * + * gcc -o strings2po strings2po.c + * + * Contents: + * + * main() - Convert .strings file to .po. + * read_strings() - Read a line from a .strings file. + * write_po() - Write a line to the .po file. + */ + +#include +#include + + +/* + * The .strings file format is simple: + * + * // comment + * "id" = "str"; + * + * Both the id and str strings use standard C quoting for special characters + * like newline and the double quote character. + */ + +/* + * Local functions... + */ + +static int read_strings(FILE *strings, char *buffer, size_t bufsize, + char **id, char **str); +static void write_po(FILE *po, const char *what, const char *s); + + +/* + * main() - Convert .strings file to .po. + */ + +int /* O - Exit code */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *strings, /* .strings file */ + *po; /* .po file */ + char iconv[1024], /* iconv command */ + buffer[8192], /* Line buffer */ + *id, /* ID string */ + *str; /* Translation string */ + int count; /* Number of messages converted */ + + + if (argc != 3) + { + puts("Usage: strings2po filename.strings filename.po"); + return (1); + } + + /* + * Cheat by using iconv to convert the .strings file from UTF-16 to UTF-8 + * which is what we need for the .po file (and it makes things a lot + * simpler...) + */ + + snprintf(iconv, sizeof(iconv), "iconv -f utf-16 -t utf-8 '%s'", argv[1]); + if ((strings = popen(iconv, "r")) == NULL) + { + perror(argv[1]); + return (1); + } + + if ((po = fopen(argv[2], "w")) == NULL) + { + perror(argv[2]); + pclose(strings); + return (1); + } + + count = 0; + + while (read_strings(strings, buffer, sizeof(buffer), &id, &str)) + { + count ++; + write_po(po, "msgid", id); + write_po(po, "msgstr", str); + } + + pclose(strings); + fclose(po); + + printf("%s: %d messages.\n", argv[2], count); + + return (0); +} + + +/* + * 'read_strings()' - Read a line from a .strings file. + */ + +static int /* O - 1 on success, 0 on failure */ +read_strings(FILE *strings, /* I - .strings file */ + char *buffer, /* I - Line buffer */ + size_t bufsize, /* I - Size of line buffer */ + char **id, /* O - Pointer to ID string */ + char **str) /* O - Pointer to translation string */ +{ + char *bufptr; /* Pointer into buffer */ + + + while (fgets(buffer, bufsize, strings)) + { + if (buffer[0] != '\"') + continue; + + *id = buffer + 1; + + for (bufptr = buffer + 1; *bufptr && *bufptr != '\"'; bufptr ++) + if (*bufptr == '\\') + bufptr ++; + + if (*bufptr != '\"') + continue; + + *bufptr++ = '\0'; + + while (*bufptr && *bufptr != '\"') + bufptr ++; + + if (!*bufptr) + continue; + + bufptr ++; + *str = bufptr; + + for (; *bufptr && *bufptr != '\"'; bufptr ++) + if (*bufptr == '\\') + bufptr ++; + + if (*bufptr != '\"') + continue; + + *bufptr = '\0'; + + return (1); + } + + return (0); +} + + +/* + * 'write_po()' - Write a line to the .po file. + */ + +static void +write_po(FILE *po, /* I - .po file */ + const char *what, /* I - Type of string */ + const char *s) /* I - String to write */ +{ + fprintf(po, "%s \"%s\"\n", what, s); +} + + +/* + * End of "$Id$". + */ diff --git a/locale/translate.c b/locale/translate.c new file mode 100644 index 0000000000..8188d1d566 --- /dev/null +++ b/locale/translate.c @@ -0,0 +1,443 @@ +/* + * "$Id$" + * + * HTTP-based translation program for the Common UNIX Printing System (CUPS). + * + * This program uses Google to translate the CUPS template (cups.pot) to + * several different languages. The translation isn't perfect, but it's + * a start (better than working from scratch.) + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Main entry. + * save_messages() - Save messages to a .po file. + * translate_messages() - Translate messages using Google. + * write_string() - Write a quoted string to a file. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +int save_messages(cups_array_t *cat, const char *filename); +int translate_messages(cups_array_t *cat, const char *lang); +int write_string(cups_file_t *fp, const char *s); + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_array_t *cat; /* Message catalog */ + + + if (argc != 3) + { + fputs("Usage: translate cups_language.po language\n", stderr); + return (1); + } + + if (access(argv[1], 0)) + cat = _cupsMessageLoad("cups.pot", 1); + else + cat = _cupsMessageLoad(argv[1], 1); + + if (!cat) + { + puts("Unable to load message catalog."); + return (1); + } + + if (!translate_messages(cat, argv[2])) + { + puts("Unable to translate message catalog."); + return (1); + } + + if (!save_messages(cat, argv[1])) + { + puts("Unable to save message catalog."); + return (1); + } + + return (0); +} + + +/* + * 'save_messages()' - Save messages to a .po file. + */ + +int /* O - 1 on success, 0 on error */ +save_messages(cups_array_t *cat, /* I - Message catalog */ + const char *filename) /* I - File to save to */ +{ + _cups_message_t *m; /* Current message */ + cups_file_t *fp; /* File pointer */ + + + /* + * Open the message catalog... + */ + + if ((fp = cupsFileOpen(filename, "w")) == NULL) + return (0); + + /* + * Save the messages to a file... + */ + + for (m = (_cups_message_t *)cupsArrayFirst(cat); + m; + m = (_cups_message_t *)cupsArrayNext(cat)) + { + if (cupsFilePuts(fp, "msgid \"") < 0) + break; + + if (!write_string(fp, m->id)) + break; + + if (cupsFilePuts(fp, "\"\nmsgstr \"") < 0) + break; + + if (m->str) + { + if (!write_string(fp, m->str)) + break; + } + + if (cupsFilePuts(fp, "\"\n") < 0) + break; + } + + cupsFileClose(fp); + + return (!m); +} + + +/* + * 'translate_messages()' - Translate messages using Google. + */ + +int /* O - 1 on success, 0 on error */ +translate_messages(cups_array_t *cat, /* I - Message catalog */ + const char *lang) /* I - Output language... */ +{ + /* + * Google provides a simple translation/language tool for translating + * from one language to another. It is far from perfect, however it + * can be used to get a basic translation done or update an existing + * translation when no other resources are available. + * + * Translation requests are sent as HTTP POSTs to + * "http://translate.google.com/translate_t" with the following form + * variables: + * + * Name Description Value + * -------- ---------------------------------- ---------------- + * hl Help language? "en" + * ie Input encoding "UTF8" + * langpair Language pair "en|" + language + * oe Output encoding "UTF8" + * text Text to translate translation string + */ + + int ret; /* Return value */ + _cups_message_t *m; /* Current message */ + int tries; /* Number of tries... */ + http_t *http; /* HTTP connection */ + http_status_t status; /* Status of POST request */ + char *idptr, /* Pointer into msgid */ + buffer[65536], /* Input/output buffer */ + *bufptr, /* Pointer into buffer */ + *bufend, /* Pointer to end of buffer */ + length[16]; /* Content length */ + int bytes; /* Number of bytes read */ + + + /* + * Connect to translate.google.com... + */ + + puts("Connecting to translate.google.com..."); + + if ((http = httpConnect("translate.google.com", 80)) == NULL) + { + perror("Unable to connect to translate.google.com"); + return (0); + } + + /* + * Scan the current messages, requesting a translation of any untranslated + * messages... + */ + + for (m = (_cups_message_t *)cupsArrayFirst(cat), ret = 1; + m; + m = (_cups_message_t *)cupsArrayNext(cat)) + { + /* + * Skip messages that are already translated... + */ + + if (m->str && m->str[0]) + continue; + + /* + * Encode the form data into the buffer... + */ + + snprintf(buffer, sizeof(buffer), + "hl=en&ie=UTF8&langpair=en|%s&oe=UTF8&text=", lang); + bufptr = buffer + strlen(buffer); + bufend = buffer + sizeof(buffer) - 5; + + for (idptr = m->id; *idptr && bufptr < bufend; idptr ++) + if (*idptr == ' ') + *bufptr++ = '+'; + else if (*idptr < ' ' || *idptr == '%') + { + sprintf(bufptr, "%%%02X", *idptr & 255); + bufptr += 3; + } + else if (*idptr != '&') + *bufptr++ = *idptr; + + *bufptr++ = '&'; + *bufptr = '\0'; + + sprintf(length, "%d", (int)(bufptr - buffer)); + + /* + * Send the request... + */ + + printf("\"%s\" = ", m->id); + fflush(stdout); + + tries = 0; + + do + { + httpClearFields(http); + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, + "application/x-www-form-urlencoded"); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length); + + if (httpPost(http, "/translate_t")) + { + httpReconnect(http); + httpPost(http, "/translate_t"); + } + + httpWrite2(http, buffer, bufptr - buffer); + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + + if (status != HTTP_OK && status != HTTP_ERROR) + httpFlush(http); + + tries ++; + } + while (status == HTTP_ERROR && tries < 10); + + if (status == HTTP_OK) + { + /* + * OK, read the translation back... + */ + + bufptr = buffer; + bufend = buffer + sizeof(buffer) - 1; + + while ((bytes = httpRead2(http, bufptr, bufend - bufptr)) > 0) + bufptr += bytes; + + if (bytes < 0) + { + /* + * Read error, abort! + */ + + puts("READ ERROR!"); + ret = 0; + break; + } + + *bufptr = '\0'; + + /* + * Find the div containing translation + */ + + if ((bufptr = strstr(buffer, "
')) == NULL) + { + /* + * textarea doesn't end, abort! + */ + + puts("DIV SHORT DATA!"); + ret = 0; + break; + } + + bufptr ++; + + if ((bufend = strstr(bufptr, "
")) == NULL) + { + /* + * textarea doesn't close, abort! + */ + + puts("/DIV SHORT DATA!"); + ret = 0; + break; + } + + *bufend = '\0'; + + /* + * Copy the translation... + */ + + m->str = strdup(bufptr); + + /* + * Convert character entities to regular chars... + */ + + for (bufptr = strchr(m->str, '&'); + bufptr; + bufptr = strchr(bufptr + 1, '&')) + { + if (!strncmp(bufptr, "<", 4)) + { + *bufptr = '<'; + _cups_strcpy(bufptr + 1, bufptr + 4); + } + else if (!strncmp(bufptr, ">", 4)) + { + *bufptr = '>'; + _cups_strcpy(bufptr + 1, bufptr + 4); + } + else if (!strncmp(bufptr, "&", 5)) + _cups_strcpy(bufptr + 1, bufptr + 5); + } + + printf("\"%s\"\n", m->str); + } + else if (status == HTTP_ERROR) + { + printf("NETWORK ERROR (%s)!\n", strerror(httpError(http))); + ret = 0; + break; + } + else + { + printf("HTTP ERROR %d!\n", status); + ret = 0; + break; + } + } + + httpClose(http); + + return (ret); +} + + +/* + * 'write_string()' - Write a quoted string to a file. + */ + +int /* O - 1 on success, 0 on failure */ +write_string(cups_file_t *fp, /* I - File to write to */ + const char *s) /* I - String */ +{ + while (*s) + { + switch (*s) + { + case '\n' : + if (cupsFilePuts(fp, "\\n") < 0) + return (0); + break; + + case '\r' : + if (cupsFilePuts(fp, "\\r") < 0) + return (0); + break; + + case '\t' : + if (cupsFilePuts(fp, "\\t") < 0) + return (0); + break; + + case '\\' : + if (cupsFilePuts(fp, "\\\\") < 0) + return (0); + break; + + case '\"' : + if (cupsFilePuts(fp, "\\\"") < 0) + return (0); + break; + + default : + if ((*s & 255) < ' ') + { + if (cupsFilePrintf(fp, "\\%o", *s) < 0) + return (0); + } + else if (cupsFilePutChar(fp, *s) < 0) + return (0); + break; + } + + s ++; + } + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 0000000000..dedfc597f5 --- /dev/null +++ b/man/Makefile @@ -0,0 +1,234 @@ +# +# "$Id$" +# +# Man page makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 2007-2008 by Apple Inc. +# Copyright 1993-2006 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Apple Inc. 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 +# file is missing or damaged, see the license at "http://www.cups.org/". +# + +include ../Makedefs + + +# +# Man pages... +# + +MAN1 = cancel.$(MAN1EXT) \ + cups-config.$(MAN1EXT) \ + cupstestdsc.$(MAN1EXT) \ + cupstestppd.$(MAN1EXT) \ + lp.$(MAN1EXT) \ + lpoptions.$(MAN1EXT) \ + lppasswd.$(MAN1EXT) \ + lpq.$(MAN1EXT) \ + lprm.$(MAN1EXT) \ + lpr.$(MAN1EXT) \ + lpstat.$(MAN1EXT) \ + ppdc.$(MAN1EXT) \ + ppdhtml.$(MAN1EXT) \ + ppdi.$(MAN1EXT) \ + ppdmerge.$(MAN1EXT) \ + ppdpo.$(MAN1EXT) +MAN5 = classes.conf.$(MAN5EXT) \ + client.conf.$(MAN5EXT) \ + cups-snmp.conf.$(MAN5EXT) \ + cupsd.conf.$(MAN5EXT) \ + mailto.conf.$(MAN5EXT) \ + mime.convs.$(MAN5EXT) \ + mime.types.$(MAN5EXT) \ + ppdcfile.$(MAN5EXT) \ + printers.conf.$(MAN5EXT) \ + subscriptions.conf.$(MAN5EXT) +MAN7 = backend.$(MAN7EXT) \ + filter.$(MAN7EXT) \ + notifier.$(MAN7EXT) +MAN8 = cupsaccept.$(MAN8EXT) \ + cupsaddsmb.$(MAN8EXT) \ + cupsctl.$(MAN8EXT) \ + cupsfilter.$(MAN8EXT) \ + cups-deviced.$(MAN8EXT) \ + cups-driverd.$(MAN8EXT) \ + cups-lpd.$(MAN8EXT) \ + cups-polld.$(MAN8EXT) \ + cupsd.$(MAN8EXT) \ + cupsenable.$(MAN8EXT) \ + lpadmin.$(MAN8EXT) \ + lpinfo.$(MAN8EXT) \ + lpmove.$(MAN8EXT) \ + lpc.$(MAN8EXT) + + +# +# Make everything... +# + +all: $(MAN1) $(MAN5) $(MAN7) $(MAN8) html + + +# +# Make library targets... +# + +libs: + + +# +# Make unit tests... +# + +unittests: + + +# +# Clean all config and object files... +# + +clean: + $(RM) mantohtml mantohtml.o + $(RM) $(MAN1) $(MAN5) $(MAN7) $(MAN8) + for file in $(MAN1); do \ + $(RM) ../doc/help/man-`basename $$file .$(MAN1EXT)`.html; \ + done + for file in $(MAN5); do \ + $(RM) ../doc/help/man-`basename $$file .$(MAN5EXT)`.html; \ + done + for file in $(MAN7); do \ + $(RM) ../doc/help/man-`basename $$file .$(MAN7EXT)`.html; \ + done + for file in $(MAN8); do \ + $(RM) ../doc/help/man-`basename $$file .$(MAN8EXT)`.html; \ + done + + +# +# Dummy depend target... +# + +depend: + + +# +# Install all targets... +# + +install: all install-data install-headers install-libs install-exec + + +# +# Install data files... +# + +install-data: all + $(INSTALL_DIR) -m 755 $(MANDIR)/man1 + for file in $(MAN1); do \ + echo Installing $$file in $(MANDIR)/man1...; \ + $(INSTALL_MAN) $$file $(MANDIR)/man1; \ + done + $(INSTALL_DIR) -m 755 $(MANDIR)/man5 + for file in $(MAN5); do \ + echo Installing $$file in $(MANDIR)/man5...; \ + $(INSTALL_MAN) $$file $(MANDIR)/man5; \ + done + $(INSTALL_DIR) -m 755 $(MANDIR)/man7 + for file in $(MAN7); do \ + echo Installing $$file in $(MANDIR)/man7...; \ + $(INSTALL_MAN) $$file $(MANDIR)/man7; \ + done + $(INSTALL_DIR) -m 755 $(AMANDIR)/man$(MAN8DIR) + for file in $(MAN8); do \ + echo Installing $$file in $(AMANDIR)/man$(MAN8DIR)...; \ + $(INSTALL_MAN) $$file $(AMANDIR)/man$(MAN8DIR); \ + done + for file in accept cupsreject reject; do \ + $(RM) $(AMANDIR)/man$(MAN8DIR)/$$file.$(MAN8EXT); \ + $(LN) cupsaccept.$(MAN8EXT) $(AMANDIR)/man$(MAN8DIR)/$$file.$(MAN8EXT); \ + done + $(RM) $(AMANDIR)/man$(MAN8DIR)/cupsdisable.$(MAN8EXT) + $(LN) cupsenable.$(MAN8EXT) $(AMANDIR)/man$(MAN8DIR)/cupsdisable.$(MAN8EXT) + + +# +# Install programs... +# + +install-exec: + + +# +# Install headers... +# + +install-headers: + + +# +# Install libraries... +# + +install-libs: + + +# +# Uninstall files... +# + +uninstall: + for file in $(MAN1); do \ + $(RM) $(MANDIR)/man1/$$file; \ + done + -$(RMDIR) $(MANDIR)/man1 + for file in $(MAN5); do \ + $(RM) $(MANDIR)/man5/$$file; \ + done + -$(RMDIR) $(MANDIR)/man5 + for file in $(MAN7); do \ + $(RM) $(MANDIR)/man7/$$file; \ + done + -$(RMDIR) $(MANDIR)/man7 + for file in $(MAN8); do \ + $(RM) $(AMANDIR)/man$(MAN8DIR)/$$file; \ + done + $(RM) $(AMANDIR)/man$(MAN8DIR)/accept.$(MAN8EXT) + $(RM) $(AMANDIR)/man$(MAN8DIR)/cupsreject.$(MAN8EXT) + $(RM) $(AMANDIR)/man$(MAN8DIR)/reject.$(MAN8EXT) + $(RM) $(AMANDIR)/man$(MAN8DIR)/cupsdisable.$(MAN8EXT) + -$(RMDIR) $(AMANDIR)/man$(MAN8DIR) + + +# +# Make html versions of man pages... +# + +html: $(MAN1) $(MAN5) $(MAN7) $(MAN8) mantohtml + echo Converting man pages to HTML... + for file in $(MAN1); do \ + echo " $$file..."; \ + ./mantohtml `basename $$file .$(MAN1EXT)`.man >../doc/help/man-`basename $$file .$(MAN1EXT)`.html; \ + done + for file in $(MAN5); do \ + echo " $$file..."; \ + ./mantohtml `basename $$file .$(MAN5EXT)`.man >../doc/help/man-`basename $$file .$(MAN5EXT)`.html; \ + done + for file in $(MAN7); do \ + echo " $$file..."; \ + ./mantohtml `basename $$file .$(MAN7EXT)`.man >../doc/help/man-`basename $$file .$(MAN7EXT)`.html; \ + done + for file in $(MAN8); do \ + echo " $$file..."; \ + ./mantohtml `basename $$file .$(MAN8EXT)`.man >../doc/help/man-`basename $$file .$(MAN8EXT)`.html; \ + done + +mantohtml: mantohtml.o + $(CC) $(ARCHFLAGS) $(LDFLAGS) -o $@ mantohtml.o + + +# +# End of "$Id$". +# diff --git a/man/backend.man b/man/backend.man new file mode 100644 index 0000000000..31642400dd --- /dev/null +++ b/man/backend.man @@ -0,0 +1,183 @@ +.\" +.\" "$Id: backend.man 8622 2009-05-13 16:28:43Z mike $" +.\" +.\" Backend man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH backend 7 "CUPS" "12 May 2009" "Apple Inc." + +.SH NAME +backend \- cups backend transmission interfaces + +.SH SYNOPSIS +.B backend +.br +.B backend +job user title num-copies options [ +.I filename +] + +.SH DESCRIPTION +Backends are a special type of \fIfilter(7)\fR which is used to +send print data to and discover different devices on the system. + +.LP +Like filters, 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 as required by the physical +interface. + +.LP +The command name (argv[0]) is set to the device URI of the destination printer. +Starting with CUPS 1.1.22, any authentication information in argv[0] is removed, +so backend developers are urged to use the DEVICE_URI environment variable +whenever authentication information is required. The CUPS API includes a +\fIcupsBackendDeviceURI\fR function for retrieving the correct device URI. + +.LP +Back-channel data from the device should be relayed to the job +filters by writing to file descriptor 3. The CUPS API includes +the \fIcupsBackChannelWrite\fR function for this purpose. + +.SH DEVICE DISCOVERY +When run with no arguments, the backend should list the devices +and schemes it supports or is advertising to stdout. The output +consists of zero or more lines consisting of any of the following +forms: + +.nf + device-class scheme "Unknown" "device-info" + device-class device-uri "device-make-and-model" "device-info" + device-class device-uri "device-make-and-model" "device-info" "device-id" + device-class device-uri "device-make-and-model" "device-info" "device-id" "device-location" +.fi + +.LP +The \fIdevice-class\fR field is one of the following values: + +.TP 5 +direct +.br +The device-uri refers to a specific direct-access device with no +options, such as a parallel, USB, or SCSI device. + +.TP 5 +file +.br +The device-uri refers to a file on disk. + +.TP 5 +network +.br +The device-uri refers to a networked device and conforms to the +general form for network URIs. + +.TP 5 +serial +.br +The device-uri refers to a serial device with configurable baud +rate and other options. If the device-uri contains a baud value, +it represents the maximum baud rate supported by the device. + +.LP +The \fIscheme\fR field provides the URI scheme that is supported +by the backend. Backends should use this form only when the +backend supports any URI using that scheme. The \fIdevice-uri\fR +field specifies the full URI to use when communicating with the +device. + +.LP +The \fIdevice-make-and-model\fR field specifies the make and +model of the device, e.g. "Acme Foojet 2000". If the make and +model is not known, you must report "Unknown". + +.LP +The \fIdevice-info\fR field specifies additional information +about the device. Typically this includes the make and model +along with the port number or network address, e.g. "Acme Foojet +2000 USB #1". + +.LP +The optional \fIdevice-id\fR field specifies the IEEE-1284 device +ID string for the device, which is used to select a matching +driver. + +.LP +The optional \fIdevice-location\fR field specifies the physical location of +the device, which is often used to pre-populate the printer-location attribute +when adding a printer. + +.SH PERMISSIONS +Backends without world execute permissions are run as the root +user. Otherwise, the backend is run using the unprivileged user +account, typically "lp". + +.SH EXIT CODES +The following exit codes are defined for backends; C API +constants defined in the header file are defined +in parenthesis: + +.TP 5 +0 (CUPS_BACKEND_OK) +.br +The print file was successfully transmitted to the device or +remote server. + +.TP 5 +1 (CUPS_BACKEND_FAILED) +.br +The print file was not successfully transmitted to the device or +remote server. The scheduler will respond to this by canceling +the job, retrying the job, or stopping the queue depending on the +state of the error-policy attribute. + +.TP 5 +2 (CUPS_BACKEND_AUTH_REQUIRED) +.br +The print file was not successfully transmitted because valid +authentication information is required. The scheduler will +respond to this by holding the job and adding the +authentication-required job-reasons keyword. + +.TP 5 +3 (CUPS_BACKEND_HOLD) +.br +The print file was not successfully transmitted because it cannot +be printed at this time. The scheduler will respond to this by +holding the job. + +.TP 5 +4 (CUPS_BACKEND_STOP) +.br +The print file was not successfully transmitted because it cannot +be printed at this time. The scheduler will respond to this by +stopping the queue. + +.TP 5 +5 (CUPS_BACKEND_CANCEL) +.br +The print file was not successfully transmitted because one or +more attributes are not supported. The scheduler will respond to +this by canceling the job. + +.PP +All other exit code values are reserved. + +.SH SEE ALSO +\fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, \fIfilter(7)\fR, +.br +http://localhost:631/help + +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: backend.man 8622 2009-05-13 16:28:43Z mike $". +.\" diff --git a/man/cancel.man b/man/cancel.man new file mode 100644 index 0000000000..2086d0cce8 --- /dev/null +++ b/man/cancel.man @@ -0,0 +1,75 @@ +.\" +.\" "$Id: cancel.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" cancel man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cancel 1 "CUPS" "20 March 2006" "Apple Inc." +.SH NAME +cancel - cancel jobs +.SH SYNOPSIS +.B cancel +[ -E ] [ -U +.I username +] [ -a ] [ -h +.I hostname[:port] +] [ -u +.I username +] [ +.I id +] [ +.I destination +] [ +.I destination-id +] +.SH DESCRIPTION +\fIcancel\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 \fIcancel\fR: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-U username +.br +Specifies the username to use when connecting to the server. +.TP 5 +-a +.br +Cancel all jobs on the named destination, or all jobs on all +destinations if none is provided. +.TP 5 +-h hostname[:port] +.br +Chooses an alternate server. +.TP 5 +-u username +.br +Cancels jobs owned by \fIusername\fR. +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to +contain any printable character except SPACE, TAB, "/", or "#". +Also, printer and class names are \fInot\fR case-sensitive. +.SH NOTES +Administrators wishing to prevent unauthorized cancellation of +jobs via the \fI-u\fR option should require authentication for +Cancel-Jobs operations in \fIcupsd.conf(5)\fR. +.SH SEE ALSO +\fIlp(1)\fR, \fIlpmove(8)\fR, \fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cancel.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/classes.conf.man b/man/classes.conf.man new file mode 100644 index 0000000000..db8e83a7b1 --- /dev/null +++ b/man/classes.conf.man @@ -0,0 +1,110 @@ +.\" +.\" "$Id: classes.conf.man 8581 2009-04-29 22:54:48Z mike $" +.\" +.\" classes.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH classes.conf 5 "CUPS" "29 April 2009" "Apple Inc." +.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 + ... +.br +Defines a specific printer class. +.TP 5 + ... +.br +Defines a default printer class. +.TP 5 +Accepting Yes +.TP 5 +Accepting No +.br +Specifies whether the printer is accepting new jobs. +.TP 5 +AllowUser [ user @group ... ] +.br +Allows specific users and groups to print to the printer. +.TP 5 +DenyUser [ user @group ... ] +.br +Prevents specific users and groups from printing to the printer. +.TP 5 +Info text +.br +Specifies human-readable text describing the printer. +.TP 5 +JobSheets banner banner +.br +Specifies the banner pages to use for the printer. +.TP 5 +KLimit number +.br +Specifies the job-k-limit value for the printer. +.TP 5 +Location text +.br +Specifies human-readable text describing the location of the printer. +.TP 5 +OpPolicy name +.br +Specifies the operation policy for the printer. +.TP 5 +PageLimit number +.br +Specifies the job-page-limit value for the printer. +.TP 5 +Printer +.br +Specifies a printer that is a member of the printer class. +.TP 5 +QuotaPeriod seconds +.br +Specifies the job-quota-period value for the printer. +.TP 5 +Shared Yes +.TP 5 +Shared No +.br +Specifies whether the printer is shared. +.TP 5 +State idle +.TP 5 +State stopped +.br +Specifies the initial state of the printer (Idle or Stopped) +.TP 5 +StateMessage text +.br +Specifies the message associated with the state. +.TP 5 +StateTime seconds +.br +Specifies the date/time associated with the state. +.SH SEE ALSO +\fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, \fImime.convs(5)\fR, +\fImime.types(5)\fR, \fIprinters.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: classes.conf.man 8581 2009-04-29 22:54:48Z mike $". +.\" diff --git a/man/client.conf.man.in b/man/client.conf.man.in new file mode 100644 index 0000000000..ce2cdc06a2 --- /dev/null +++ b/man/client.conf.man.in @@ -0,0 +1,49 @@ +.\" +.\" "$Id$" +.\" +.\" client.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH client.conf 5 "CUPS" "25 February 2006" "Apple Inc." +.SH NAME +client.conf \- client configuration file for cups +.SH DESCRIPTION +The \fIclient.conf\fR file configures the CUPS client and is +normally located in the \fI@CUPS_SERVERROOT@\fR or \fI~/.cups\fR +directory. Each line in the file can be a configuration +directive, a blank line, or a comment. Comment lines start with +the # character. +.SH DIRECTIVES +The following directives are understood by the client. Consult the +on-line help for detailed descriptions: +.TP 5 +Encryption IfRequested +.TP 5 +Encryption Never +.TP 5 +Encryption Required +.br +Specifies the level of encryption that is required for a particular +location. +.TP 5 +ServerName hostname-or-ip-address[:port] +.TP 5 +ServerName /domain/socket +.br +Specifies the address and optionally the port to use when +connecting to the server +.SH SEE ALSO +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cups-config.man b/man/cups-config.man new file mode 100644 index 0000000000..f5e83dd9e2 --- /dev/null +++ b/man/cups-config.man @@ -0,0 +1,117 @@ +.\" +.\" "$Id: cups-config.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" cups-config man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cups-config 1 "CUPS" "23 October 2008" "Apple Inc." +.SH NAME +cups-config \- get cups api, compiler, directory, and link information. +.SH SYNOPSIS +.B cups-config +--api-version +.br +.B cups-config +--build +.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. +.SH OPTIONS +.TP 5 +--api-version +.br +Displays the current API version (major.minor). +.TP 5 +--build +.br +Displays a system-specific build number. +.TP 5 +--cflags +.br +Displays the necessary compiler options. +.TP 5 +--datadir +.br +Displays the default CUPS data directory. +.TP 5 +--help +.br +Displays the program usage message. +.TP 5 +--image +.br +When used with \fI--libs\fR, adds the CUPS imaging library to the +list of displayed libraries. +.TP 5 +--ldflags +.br +Displays the necessary linker options. +.TP 5 +--libs +.br +Displays the necessary librarys to link to. +.TP 5 +--serverbin +.br +Displays the default CUPS binary directory, +where filters and backends are stored. +.TP 5 +--serverroot +.br +Displays the default CUPS configuration file directory. +.TP 5 +--static +.br +When used with \fI--libs\fR, shows the static libraries instead +of the default (shared) libraries. +.TP 5 +--version +.br +Displays the full version number of the CUPS installation +(major.minor.patch). +.SH SEE ALSO +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cups-config.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cups-deviced.man.in b/man/cups-deviced.man.in new file mode 100644 index 0000000000..70647a07fa --- /dev/null +++ b/man/cups-deviced.man.in @@ -0,0 +1,44 @@ +.\" +.\" "$Id$" +.\" +.\" cups-deviced man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cups-deviced 8 "CUPS" "16 June 2008" "Apple Inc." +.SH NAME +cups-deviced \- cups device daemon +.SH SYNOPSIS +.B cups-deviced +.I request-id limit user-id options +.SH DESCRIPTION +\fIcups-deviced\fR polls the backends in +\fI@CUPS_SERVERBIN@/backend\fR for a list of available devices. +It is run by \fIcupsd(8)\fR in response to a +\fICUPS-Get-Devices\fR request. The output format is an IPP +response message. The \fIrequest-id\fR argument is the request ID +from the original IPP request, typically 1. The \fIlimit\fR +argument is the limit value from the original IPP request - 0 +means no limit. The \fIuser-id\fR argument is the +requesting-user-name value from the original IPP request. +Finally, the \fIoptions\fR argument is a space-delimited list of +attributes ("name=value name=value \...") that were passed in +with the request. Currently \fIcups-deviced\fR looks for the +\fIrequested-attributes\fR attribute and tailors the output +accordingly. +.SH SEE ALSO +backend(7), cupsd(8), cupsd.conf(5), +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cups-driverd.man.in b/man/cups-driverd.man.in new file mode 100644 index 0000000000..ddef4ae4b3 --- /dev/null +++ b/man/cups-driverd.man.in @@ -0,0 +1,122 @@ +.\" +.\" "$Id$" +.\" +.\" cups-driverd man page for CUPS. +.\" +.\" Copyright 2007-2011 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cups-driverd 8 "CUPS" "6 January 2011" "Apple Inc." +.SH NAME +cups-driverd \- cups driver daemon +.SH SYNOPSIS +.B cups-driverd +cat +.I ppd-name +.br +.B cups-driverd +list +.I request_id limit options +.SH DESCRIPTION +\fIcups-driverd\fR shows or lists PPD files. It is run in +response to CUPS-Add-Modify-Printer or CUPS-Get-Devices requests. +The first form ("cups-driverd cat ppd-name") writes the named PPD +file to stdout. The output format is an uncompressed PPD file. +.LP +The second form lists the available manufacturers or PPD files to +stdout as indicated by the \fIoptions\fR argument. The output +format is an IPP response message. The \fIrequest_id\fR argument +is the request ID from the original IPP request, typically 1. The +\fIlimit\fR argument is the limit value from the original IPP +request - 0 means no limit. Finally, the \fIoptions\fR argument +is a space-delimited list of attributes ("name=value name=value +\&...") that were passed in with the request. Currently +\fIcups-driverd\fR looks for the \fIppd-make\fR and +\fIrequested-attributes\fR attributes and tailors the output +accordingly. +.SH DRIVERS +Drivers can be static PPD files under the +\fI@CUPS_DATADIR@/model\fR directory or programs under the +\fI@CUPS_SERVERBIN@/driver\fR directory. Static PPD files must +conform to the Adobe PPD File Format Specification version 4.3 +and may be compressed using the \fIgzip(1)\fR program. Driver +programs must implement the command-line interface shown in the +next section. +.SS DRIVER PROGRAMS +Driver programs provide a interface to dynamically-generated PPD +files. The following arguments are currently defined: +.TP 5 +drivername list +.br +Lists the supported PPD files to stdout. +.TP 5 +drivername cat ppdname +.br +Writes the named PPD file to stdout. +.PP +Driver programs MUST NOT query hardware or make other long-term operations that +would delay the return of a driver list. See the NOTES section below for +specific recommendations. +.SS LISTING FILES (drivername list) +When run with the single argument "list", the program must list +the available PPD files it can generate to stdout using the +following format: +.nf + "drivername:ppdname" language "make" "make and model" + "drivername:ppdname" language "make" "make and model" "1284 device id" + "drivername:ppdname" language "make" "make and model" "1284 device id" "(PPD product)" + "drivername:ppdname" language "make" "make and model" "1284 device id" "(PPD product)" "PostScript version" + "drivername:ppdname" language "make" "make and model" "1284 device id" "(PPD product)" "PostScript version" "type" +.fi +.LP +\fIDrivername\fR is the name of the driver program. \fIPpdname\fR +is the name used to select the given driver. \fILanguage\fR is +the locale associated with the default language of the PPD file, +typically "en". \fIMake\fR is the Manufacturer name from the PPD +file. \fIMake and model\fR is the NickName name from the PPD +file. \fI1284 device id\fR is the 1284DeviceId from the PPD file, +if any. \fI(PPD product)\fR is the Product string as it would appear in the PPD +file or from a PostScript query. \fIPostScript version\fR is the PSVersion +string as it would appear in the PPD file or from a PostScript query. \fIType\fR +is "postscript" for PostScript printers, "pdf" for PDF printers, "raster" for +raster printers, or "fax" for facsimile devices. +.SS WRITING FILES (drivername cat ppdname) +When the driver program is run with the "cat ppdname" arguments, +it must write the named PPD file to stdout, uncompressed. If the +named PPD file does not exist, the driver program must not write +any output to stdout and report the error to stderr instead. +.SS DRIVER ERROR MESSAGES +Error messages can be relayed back to \fIcupsd\fR by writing them +to stderr. The following prefixes are recognized: +.TP 5 +DEBUG: [drivername] +.br +Debugging messages +.TP 5 +ERROR: [drivername] +.br +Error messages +.TP 5 +INFO: [drivername] +.br +Informational messages +.SH NOTES +Due to performance considerations, driver programs have been officially +deprecated and should not be used for new development. Currently only the +CUPS web interface and \fIlpinfo(8)\fR command will request lists from all +driver programs. +.SH SEE ALSO +cupsd(8), cupsd.conf(5), cupstestppd(1), lpinfo(8), +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2011 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cups-lpd.man.in b/man/cups-lpd.man.in new file mode 100644 index 0000000000..4bfcc46f22 --- /dev/null +++ b/man/cups-lpd.man.in @@ -0,0 +1,124 @@ +.\" +.\" "$Id$" +.\" +.\" cups-lpd man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cups-lpd 8 "CUPS" "4 August 2008" "Apple Inc." +.SH NAME +cups-lpd \- receive print jobs and report printer status to lpd clients +.SH SYNOPSIS +.B cups-lpd +[ -h +.I hostname[:port] +] [ -n ] [ -o +.I option=value +] +.SH DESCRIPTION +\fIcups-lpd\fR is the CUPS Line Printer Daemon ("LPD") +mini-server that supports legacy client systems that use the LPD +protocol. \fIcups-lpd\fR does not act as a standalone network +daemon but instead operates using the Internet "super-server" +\fIinetd(8)\fR or \fIxinetd(8)\fR. If you are using \fIinetd\fR, +add the following line to the \fIinetd.conf\fR file to enable the +\fIcups-lpd\fR mini-server: +.br +.nf + + printer stream tcp nowait lp @CUPS_SERVERBIN@/daemon/cups-lpd cups-lpd \\ + -o document-format=application/octet-stream +.fi +.LP +.LP +\fBNote:\fR If you are using Solaris 10 or higher, you must run +the \fIinetdconv(1m)\fR program to register the changes to the +inetd.conf file. +.LP +If you are using the newer \fIxinetd(8)\fR daemon, create a file +named \fI/etc/xinetd.d/cups\fR containing the following lines: +.br +.nf + + service printer + { + socket_type = stream + protocol = tcp + wait = no + user = lp + group = sys + passenv = + server = @CUPS_SERVERBIN@/daemon/cups-lpd + server_args = -o document-format=application/octet-stream + } +.fi +.SH OPTIONS +.TP 5 +-h hostname[:port] +.br +Sets the CUPS server (and port) to use. +.TP 5 +-n +.br +Disables reverse address lookups; normally \fIcups-lpd\fR will +try to discover the hostname of the client via a reverse DNS +lookup. +.TP 5 +-o name=value +.br +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; the examples in the previous section set the +"document-format" option to "application/octet-stream" which +forces autodetection of the print file format. +.SH PERFORMANCE +\fIcups-lpd\fR performs well with small numbers of clients and +printers. However, since a new process is created for each +connection and since each process must query the printing system +before each job submission, it does not scale to larger +configurations. We highly recommend that large configurations +use the native IPP support provided by CUPS instead. +.SH SECURITY +\fIcups-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(5)\fR files used by TCP +wrappers. Therefore, running \fIcups-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. +.LP +\fIcups-lpd\fR is not enabled by the standard CUPS distribution. +Please consult with your operating system vendor to determine +whether it is enabled on your system. +.SH COMPATIBILITY +\fIcups-lpd\fR does not enforce the restricted source port +number specified in RFC 1179, as using restricted ports does not +prevent 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 +\fIcups(1)\fR, \fIcupsd(8)\fR, \fIinetconv(1m)\fR, +\fIinetd(8)\fR, \fIxinetd(8)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cups-polld.man b/man/cups-polld.man new file mode 100644 index 0000000000..0d40b5f159 --- /dev/null +++ b/man/cups-polld.man @@ -0,0 +1,38 @@ +.\" +.\" "$Id: cups-polld.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" cups-polld man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cups-polld 8 "CUPS" "12 February 2006" "Apple Inc." +.SH NAME +cups-polld \- cups printer polling daemon +.SH SYNOPSIS +.B cups-polld +.I address ipp-port interval browse-port +.SH DESCRIPTION +\fIcups-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) on the specified browse port for reception +by \fIcupsd(8)\fR. +.PP +This program is started automatically by \fIcupsd\fR for every +\fIBrowsePoll\fR directive found in the \fIcupsd.conf(5)\fR file. +.SH SEE ALSO +\fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cups-polld.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cups-snmp.conf.man b/man/cups-snmp.conf.man new file mode 100644 index 0000000000..706f1ce813 --- /dev/null +++ b/man/cups-snmp.conf.man @@ -0,0 +1,73 @@ +.\" +.\" "$Id: cups-snmp.conf.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" snmp.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH snmp.conf 5 "CUPS" "31 July 2006" "Apple Inc." +.SH NAME +snmp.conf \- snmp configuration file for cups +.SH DESCRIPTION +The \fIsnmp.conf\fR file configures the CUPS SNMP printer +discovery backend and is normally located in the \fI/etc/cups\fR +directory. Each line in the file can be a configuration +directive, a blank line, or a comment. Comment lines start with +the # character. +.LP +The SNMP backend uses the SNMPv1 protocol to discover network +printers, collecting information from the Host MIB along with +intelligent port probes to determine the correct device URI and +make and model for each printer. Future versions of CUPS will +likely support the new Port Monitor MIB as well. +.SH DIRECTIVES +The following directives are understood by the SNMP backend. +Consult the on-line help for detailed descriptions: +.TP 5 +Address @IF(\fIname\fR) +.TP 5 +Address @LOCAL +.TP 5 +Address \fIaddress\fR +.br +Sends SNMP broadcast queries to the specified address(es). The +default address is "@LOCAL" which broadcasts to all LAN +interfaces. +.TP 5 +Community \fIname\fR +.br +Specifies a SNMP community to query. The default community is +"public". +.TP 5 +DebugLevel \fIN\fR +.br +Sets the debug logging level to \fIN\fR; 0 disables debug +logging, 1 enables basic logging, 2 displays SNMP values, and 3 +displays raw hex data. +.TP 5 +HostNameLookups on +.TP 5 +HostNameLookups off +.br +Specifies whether the addresses of printers should be converted +to hostnames or left as numeric IP addresses. The default is +"off". +.TP 5 +MaxRunTime \fIseconds\fR +.br +Specifies the maximum number of seconds that the SNMP backend +will scan the network for printers. +.SH SEE ALSO +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cups-snmp.conf.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cupsaccept.man b/man/cupsaccept.man new file mode 100644 index 0000000000..50523faa87 --- /dev/null +++ b/man/cupsaccept.man @@ -0,0 +1,79 @@ +.\" +.\" "$Id: cupsaccept.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" accept/reject man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsaccept 8 "CUPS" "12 February 2006" "Apple Inc." +.SH NAME +cupsaccept/cupsreject \- accept/reject jobs sent to a destination +.SH SYNOPSIS +.B cupsaccept +[ -E ] [ -U +.I username +] [ -h +.I hostname[:port] +] destination(s) +.br +.B cupsreject +[ -E ] [ -U +.I username +] [ -h +.I hostname[:port] +] [ -r +.I reason +] destination(s) +.SH DESCRIPTION +\fIcupsaccept\fR instructs the printing system to accept print jobs to the +specified destinations. +.LP +\fIcupsreject\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". +.SH OPTIONS +The following options are supported by both \fIcupsaccept\fR and +\fIcupsreject\fR: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-U username +.br +Sets the username that is sent when connecting to the server. +.TP 5 +-h hostname[:port] +.br +Chooses an alternate server. +.TP 5 +-r "reason" +.br +Sets the reason string that is shown for a printer that is +rejecting jobs. +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to +contain any printable character except SPACE, TAB, "/", or "#". +Also, printer and class names are \fInot\fR case-sensitive. +.LP +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 +\fIcancel(1)\fR, \fIcupsenable(8)\fR, \fIlp(1)\fR, +\fIlpadmin(8)\fR, \fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cupsaccept.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cupsaddsmb.man.in b/man/cupsaddsmb.man.in new file mode 100644 index 0000000000..dd10ebaace --- /dev/null +++ b/man/cupsaddsmb.man.in @@ -0,0 +1,214 @@ +.\" +.\" "$Id$" +.\" +.\" cupsaddsmb man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsaddsmb 8 "CUPS" "25 July 2007" "Apple Inc." +.SH NAME +cupsaddsmb \- export printers to samba for windows clients + +.SH SYNOPSIS +.B cupsaddsmb +[ -H +.I samba-server +] [ -U +.I samba-user[%samba-password] +] [ -h +.I cups-server[:port] +] [ -v ] -a +.br +.B cupsaddsmb +[ -H +.I samba-server +] [ -U +.I samba-user[%samba-password] +] [ -h +.I cups-server[:port] +] [ -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 Windows printer +driver files described below. + +.SH OPTIONS +\fIcupsaddsmb\fR supports the following options: +.TP 5 +-H samba-server +.br +Specifies the SAMBA server which defaults to the CUPS server. +.TP 5 +-U samba-user[%samba-password] +.br +Specifies the SAMBA print admin username which defaults to your +current username. If the username contains a percent (%) +character, then the text following the percent is treated as the +SAMBA password to use. +.TP 5 +-a +.br +Exports all known printers. Otherwise only the named printers are +exported. +.TP 5 +-h cups-server[:port] +.br +Specifies a different CUPS server to use. +.TP 5 +-v +.br +Specifies that verbose information should be shown. This 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 the SAMBA \fIsmb.conf(5)\fR 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 + + [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 MICROSOFT POSTSCRIPT DRIVERS FOR WINDOWS +The base driver for Windows 2000 and higher is the Microsoft +PostScript driver, which is available on any system running +Windows 2000 or higher in the +%WINDIR%\\SYSTEM32\\SPOOL\\DRIVERS\\W32X86\\3 folder for 32-bit +drivers and +%WINDIR%\\SYSTEM32\\SPOOL\\DRIVERS\\X64\\3 folder for 64-bit +drivers. +.LP +The CUPS printer driver is preferred over the Microsoft driver +since it supports the page-label, job-billing, and +job-hold-until options fully on all printers. However, currently +only Windows 2000 and higher is supported by the Microsoft +driver, so you will also need to get the Adobe driver to support +Windows 95, 98, and Me clients. The Adobe and Microsoft drivers +for Windows 2000 are identical. +.LP +Once you have extracted the driver files, copy the 32-bit drivers +to the \fI@CUPS_DATADIR@/drivers\fR directory and the 64-bit +drivers to the \fI@CUPS_DATADIR@/drivers/x64\fR directory exactly +as named below: +.nf + + [Windows 2000 and higher] + ps5ui.dll + pscript.hlp + pscript.ntf + pscript5.dll +.fi +.LP +\fBNote:\fR Unlike Windows, case is significant - make sure that +you use the lowercase filenames shown above, otherwise +\fIcupsaddsmb\fR will fail to export the drivers. + +.SH CUPS POSTSCRIPT DRIVERS FOR WINDOWS +\fIcupsaddsmb\fR can use the CUPS v6 PostScript printer driver +for Windows, which is available for download from the CUPS web +site. +.LP +The CUPS printer driver is preferred over the Adobe and +Microsoft drivers since it supports the page-label, job-billing, +and job-hold-until options fully on all printers. However, +currently only Windows 2000 and higher is supported by the CUPS +driver, so you will also need to get the Adobe driver to support +Windows 95, 98, and Me clients. +.LP +Once you have extracted the driver files, copy the 32-bit drivers +to the \fI@CUPS_DATADIR@/drivers\fR directory and the 64-bit +drivers to the \fI@CUPS_DATADIR@/drivers/x64\fR directory exactly +as named below: +.nf + + [Windows 2000 and higher] + cups6.inf (from www.cups.org) + cups6.ini (from www.cups.org) + cupsps6.dll (from www.cups.org) + cupsui6.dll (from www.cups.org) + ps5ui.dll (from your Windows system) + pscript.hlp (from your Windows system) + pscript.ntf (from your Windows system) + pscript5.dll (from your Windows system) +.fi +.LP +\fBNote:\fR Unlike Windows, case is significant - make sure that +you use the lowercase filenames shown above, otherwise +\fIcupsaddsmb\fR will fail to export the drivers. + +.SH ADOBE POSTSCRIPT DRIVERS FOR WINDOWS 95, 98, AND ME +\fIcupsaddsmb\fR can use the Adobe PostScript printer driver for +Windows 95, 98, and ME, which are available for download from the +Adobe web site (http://www.adobe.com). +.LP +The Adobe driver does not support the page-label, job-billing, or +job-hold-until options. +.LP +Once you have installed the driver on a Windows system, copy the +following files to the \fI@CUPS_DATADIR@/drivers\fR directory +exactly as named below: +.nf + + [Windows 95, 98, and Me] + ADFONTS.MFM + ADOBEPS4.DRV + ADOBEPS4.HLP + ICONLIB.DLL + PSMON.DLL +.fi +.LP +\fBNote:\fR Unlike Windows, case is significant - make sure that +you use the UPPERCASE filenames shown above, otherwise +\fIcupsaddsmb\fR will fail to export the drivers. + +.SH KNOWN ISSUES +Getting the full set of Windows driver files should be easier. + +.SH SEE ALSO +\fIsmbd(8)\fR, \fIsmb.conf(5)\fR, +http://localhost:631/help +.br +http://www.cups.org/windows/ + +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cupsctl.man b/man/cupsctl.man new file mode 100644 index 0000000000..8746433627 --- /dev/null +++ b/man/cupsctl.man @@ -0,0 +1,107 @@ +.\" +.\" "$Id: cupsctl.man 9470 2011-01-11 07:05:58Z mike $" +.\" +.\" cupsctl man page for CUPS. +.\" +.\" Copyright 2007-2011 by Apple Inc. +.\" Copyright 2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsctl 8 "CUPS" "10 January 2011" "Apple Inc." +.SH NAME +cupsctl \- configure cupsd.conf options +.SH SYNOPSIS +.B cupsctl +[ -E ] [-U +.I username +] [ -h +.I server[:port] +] [ --[no-]debug-logging ] [ --[no-]remote-admin ] [ --[no-]remote-any ] +[ --[no-]remote-printers ] [ --[no-]share-printers ] [ --[no-]user-cancel-any ] +[ +.I name=value +] +.SH DESCRIPTION +\fIcupsctl\fR updates or queries the \fBcupsd.conf\fR file for a server. When +no changes are requested, the current configuration values are written to the +standard output in the format "name=value", one per line. +.SH OPTIONS +The following options are recognized: +.TP 5 +-E +.br +Enables encryption on the connection to the scheduler. +.TP 5 +-U \fIusername\fR +.br +Specifies an alternate username to use when authenticating with the scheduler. +.TP 5 +-h \fIserver[:port]\fR +.br +Specifies the server address. +.TP 5 +--[no-]debug-logging +.br +Enables or disables debug logging in the \fBerror_log\fR file. +.TP 5 +--[no-]remote-admin +.br +Enables or disables remote administration. +.TP 5 +--[no-]remote-any +.br +Enables or disables printing from any address, e.g. the Internet. +.TP 5 +--[no-]remote-printers +.br +Enables or disables the display of remote printers shared via the CUPS, LDAP, +or SLP protocols. +.TP 5 +--[no-]share-printers +.br +Enables or disables sharing of local printers with other computers. +.TP 5 +--[no-]user-cancel-any +.br +Allows or prevents users from canceling jobs owned by others. +.SH EXAMPLES +Display the current settings: +.nf + cupsctl +.fi +.LP +Enable debug logging: +.nf + cupsctl --debug-logging +.fi +.LP +Get the current debug logging state: +.nf + cupsctl | grep '^_debug_logging' | awk -F= '{print $2}' +.fi +.LP +Disable printer sharing: +.nf + cupsctl --no-shared-printers +.fi +.LP +Enable printing using the file: pseudo-device: +.nf + cupsctl FileDevice=Yes +.fi +.SH KNOWN ISSUES +You cannot set the Listen or Port directives using \fIcupsctl\fR. +.SH SEE ALSO +\fIcupsd.conf(5)\fR, \fIcupsd(8)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2011 by Apple Inc. +.\" +.\" End of "$Id: cupsctl.man 9470 2011-01-11 07:05:58Z mike $". +.\" diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in new file mode 100644 index 0000000000..d1cedec044 --- /dev/null +++ b/man/cupsd.conf.man.in @@ -0,0 +1,714 @@ +.\" +.\" "$Id$" +.\" +.\" cupsd.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2010 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsd.conf 5 "CUPS" "28 January 2010" "Apple Inc." +.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@CUPS_SERVERROOT@\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(8)\fR. Consult the +on-line help for detailed descriptions: +.TP 5 +AccessLog filename +.TP 5 +AccessLog syslog +.br +Defines the access log filename. +.TP 5 +AccessLogLevel config +.TP 5 +AccessLogLevel actions +.TP 5 +AccessLogLevel all +.br +Specifies the logging level for the AccessLog file. +.TP 5 +Allow all +.TP 5 +Allow none +.TP 5 +Allow host.domain.com +.TP 5 +Allow *.domain.com +.TP 5 +Allow ip-address +.TP 5 +Allow ip-address/netmask +.TP 5 +Allow ip-address/mm +.TP 5 +Allow @IF(name) +.TP 5 +Allow @LOCAL +.br +Allows access from the named hosts or addresses. +.TP 5 +AuthClass User +.TP 5 +AuthClass Group +.TP 5 +AuthClass System +.br +Specifies the authentication class (User, Group, System) - +\fBthis directive is deprecated\fR. +.TP 5 +AuthGroupName group-name +.br +Specifies the authentication group - \fBthis directive is +deprecated\fR. +.TP 5 +AuthType None +.TP 5 +AuthType Basic +.TP 5 +AuthType BasicDigest +.TP 5 +AuthType Digest +.TP 5 +AuthType Negotiate +.br +Specifies the authentication type (None, Basic, BasicDigest, Digest, Negotiate) +.TP 5 +AutoPurgeJobs Yes +.TP 5 +AutoPurgeJobs No +.br +Specifies whether to purge job history data automatically when +it is no longer required for quotas. +.TP 5 +BrowseAddress ip-address +.TP 5 +BrowseAddress @IF(name) +.TP 5 +BrowseAddress @LOCAL +.br +Specifies a broadcast address for outgoing printer information packets. +.TP 5 +BrowseAllow all +.TP 5 +BrowseAllow none +.TP 5 +BrowseAllow host.domain.com +.TP 5 +BrowseAllow *.domain.com +.TP 5 +BrowseAllow ip-address +.TP 5 +BrowseAllow ip-address/netmask +.TP 5 +BrowseAllow ip-address/mm +.TP 5 +BrowseAllow @IF(name) +.TP 5 +BrowseAllow @LOCAL +.br +Allows incoming printer information packets from the named host or address. +.TP 5 +BrowseDeny all +.TP 5 +BrowseDeny none +.TP 5 +BrowseDeny host.domain.com +.TP 5 +BrowseDeny *.domain.com +.TP 5 +BrowseDeny ip-address +.TP 5 +BrowseDeny ip-address/netmask +.TP 5 +BrowseDeny ip-address/mm +.TP 5 +BrowseDeny @IF(name) +.TP 5 +BrowseDeny @LOCAL +.br +Denies incoming printer information packets from the named host or address. +.TP 5 +BrowseInterval seconds +.br +Specifies the maximum interval between printer information broadcasts. +.TP 5 +BrowseLDAPBindDN +.br +Specifies the LDAP domain name to use when registering printers. +.TP 5 +BrowseLDAPCACertFile +.br +Specifies the SSL certificate authority file to use. +.TP 5 +BrowseLDAPDN +.br +Specifies the LDAP domain name to use when discovering printers. +.TP 5 +BrowseLDAPPassword +.br +Specifies the password to use when accessing the LDAP server. +.TP 5 +BrowseLDAPServer +.br +Specifies the LDAP server to use. +.TP 5 +BrowseOrder allow,deny +.TP 5 +BrowseOrder deny,allow +.br +Specifies the order of printer information access control (allow,deny or deny,allow) +.TP 5 +BrowsePoll host-or-ip-address +.br +Specifies a server to poll for printer information. +.TP 5 +BrowsePort port +.br +Specifies the port to listen to for printer information packets. +.TP 5 +BrowseProtocols [All] [CUPS] [DNSSD] [LDAP] [SLP] +.br +Specifies the protocols to use for printer browsing. +.TP 5 +BrowseLocalProtocols [All] [CUPS] [DNSSD] [LDAP] [SLP] +.br +Specifies the protocols to use for local printer browsing. +.TP 5 +BrowseRemoteProtocols [All] [CUPS] [DNSSD] [LDAP] [SLP] +.br +Specifies the protocols to use for remote printer browsing. +.TP 5 +BrowseRelay from-address to-address +.br +Specifies that printer information packets should be relayed from one host or +network to another. +.TP 5 +BrowseShortNames Yes +.TP 5 +BrowseShortNames No +.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 seconds +.br +Specifies the maximum interval between printer information updates before +remote printers will be removed from the list of available printers. +.TP 5 +BrowseWebIF Yes +.TP 5 +BrowseWebIF No +.br +Specifies whether the CUPS web interface is advertised via DNS-SD. +.TP 5 +Browsing Yes +.TP 5 +Browsing No +.br +Specifies whether or not remote printer browsing should be enabled. +.TP 5 +Classification banner +.br +Specifies the security classification of the server. +.TP 5 +ClassifyOverride Yes +.TP 5 +ClassifyOverride No +.br +Specifies whether to allow users to override the classification +of individual print jobs. +.TP 5 +ConfigFilePerm mode +.br +Specifies the permissions for all configuration files that the scheduler +writes. +.TP 5 +DataDir path +.br +Specified the directory where data files can be found. +.TP 5 +DefaultAuthType Basic +.TP 5 +DefaultAuthType BasicDigest +.TP 5 +DefaultAuthType Digest +.TP 5 +DefaultAuthType Negotiate +.br +Specifies the default type of authentication to use. +.TP 5 +DefaultEncryption Never +.TP 5 +DefaultEncryption IfRequested +.TP 5 +DefaultEncryption Required +.br +Specifies the type of encryption to use for authenticated requests. +.TP 5 +DefaultLanguage locale +.br +Specifies the default language to use for text and web content. +.TP 5 +DefaultPaperSize Auto +.TP 5 +DefaultPaperSize None +.TP 5 +DefaultPaperSize sizename +.br +Specifies the default paper size for new print queues. "Auto" uses a locale- +specific default, while "None" specifies there is no default paper size. +.TP 5 +DefaultPolicy policy-name +.br +Specifies the default access policy to use. +.TP 5 +DefaultShared Yes +.TP 5 +DefaultShared No +.br +Specifies whether local printers are shared by default. +.TP 5 +Deny all +.TP 5 +Deny none +.TP 5 +Deny host.domain.com +.TP 5 +Deny *.domain.com +.TP 5 +Deny ip-address +.TP 5 +Deny ip-address/netmask +.TP 5 +Deny ip-address/mm +.TP 5 +Deny @IF(name) +.TP 5 +Deny @LOCAL +.br +Denies access to the named host or address. +.TP 5 +DirtyCleanInterval seconds +.br +Specifies the delay for updating of configuration and state files. A value of 0 +causes the update to happen as soon as possible, typically within a few +milliseconds. +.TP 5 +DocumentRoot directory +.br +Specifies the root directory for the internal web server documents. +.TP 5 +Encryption IfRequested +.TP 5 +Encryption Never +.TP 5 +Encryption Required +.br +Specifies the level of encryption that is required for a particular +location. +.TP 5 +ErrorLog filename +.TP 5 +ErrorLog syslog +.br +Specifies the error log filename. +.TP 5 +FatalErrors none +.TP 5 +FatalErrors all -kind [... -kind] +.TP 5 +FatalErrors kind [... kind] +.br +Specifies which errors are fatal, causing the scheduler to exit. "Kind" is +"browse", "config", "listen", "log", or "permissions". +.TP 5 +FileDevice Yes +.TP 5 +FileDevice No +.br +Specifies whether the file pseudo-device can be used for new +printer queues. +.TP 5 +FilterLimit limit +.br +Specifies the maximum cost of filters that are run concurrently. +.TP 5 +FilterNice nice-value +.br +Specifies the scheduling priority ("nice" value) of filters that +are run to print a job. +.TP 5 +FontPath directory[:directory:...] +.br +Specifies the search path for fonts. +.TP 5 +Group group-name-or-number +.br +Specifies the group name or ID that will be used when executing +external programs. +.TP 5 +HideImplicitMembers Yes +.TP 5 +HideImplicitMembers No +.br +Specifies whether to hide members of implicit classes. +.TP 5 +HostNameLookups On +.TP 5 +HostNameLookups Off +.TP 5 +HostNameLookups Double +.br +Specifies whether or not to do reverse lookups on client addresses. +.TP 5 +ImplicitAnyClasses Yes +.TP 5 +ImplicitAnyClasses No +.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 Yes +.TP 5 +ImplicitClasses No +.br +Specifies whether or not to create implicit classes from identical +remote printers. +.TP 5 +Include filename +.br +Includes the named file. +.TP 5 +JobKillDelay seconds +.br +Specifies the number of seconds to wait before killing the filters and backend +associated with a canceled or held job. +.TP 5 +JobRetryInterval seconds +.br +Specifies the interval between retries of jobs in seconds. +.TP 5 +JobRetryLimit count +.br +Specifies the number of retries that are done for jobs. +.TP 5 +KeepAlive Yes +.TP 5 +KeepAlive No +.br +Specifies whether to support HTTP keep-alive connections. +.TP 5 +KeepAliveTimeout seconds +.br +Specifies the amount of time that connections are kept alive. +.TP 5 + ... +.br +Specifies the IPP operations that are being limited inside a policy. +.TP 5 + ... +.TP 5 + ... +.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 +Listen ip-address:port +.TP 5 +Listen *:port +.TP 5 +Listen /path/to/domain/socket +.br +Listens to the specified address and port or domain socket path. +.TP 5 + ... +.br +Specifies access control for the named location. +.TP 5 +LogDebugHistory #-messages +.br +Specifies the number of debugging messages that are logged when an error +occurs in a print job. +.TP 5 +LogFilePerm mode +.br +Specifies the permissions for all log files that the scheduler writes. +.TP 5 +LogLevel alert +.TP 5 +LogLevel crit +.TP 5 +LogLevel debug2 +.TP 5 +LogLevel debug +.TP 5 +LogLevel emerg +.TP 5 +LogLevel error +.TP 5 +LogLevel info +.TP 5 +LogLevel none +.TP 5 +LogLevel notice +.TP 5 +LogLevel warn +.br +Specifies the logging level for the ErrorLog file. +.TP 5 +LogTimeFormat standard +.TP 5 +LogTimeFormat usecs +.br +Specifies the format of the date and time in the log files. +.TP 5 +MaxClients number +.br +Specifies the maximum number of simultaneous clients to support. +.TP 5 +MaxClientsPerHost number +.br +Specifies the maximum number of simultaneous clients to support from a +single address. +.TP 5 +MaxCopies number +.br +Specifies the maximum number of copies that a user can print of each job. +.TP 5 +MaxJobs number +.br +Specifies the maximum number of simultaneous jobs to support. +.TP 5 +MaxJobsPerPrinter number +.br +Specifies the maximum number of simultaneous jobs per printer to support. +.TP 5 +MaxJobsPerUser number +.br +Specifies the maximum number of simultaneous jobs per user to support. +.TP 5 +MaxLogSize number-bytes +.br +Specifies the maximum size of the log files before they are +rotated (0 to disable rotation) +.TP 5 +MaxRequestSize number-bytes +.br +Specifies the maximum request/file size in bytes (0 for no limit) +.TP 5 +MultipleOperationTimeout seconds +.br +Specifies the maximum amount of time to allow between files in a multiple file +print job. +.TP 5 +Order allow,deny +.TP 5 +Order deny,allow +.br +Specifies the order of HTTP access control (allow,deny or deny,allow) +.TP 5 +PageLog filename +.TP 5 +PageLog syslog +.br +Specifies the page log filename. +.TP 5 +PageLogFormat format string +.br +Specifies the format of page log lines. +.TP 5 +PassEnv variable [... variable] +.br +Passes the specified environment variable(s) to child processes. +.TP 5 + ... +.br +Specifies access control for the named policy. +.TP 5 +Port number +.br +Specifies a port number to listen to for HTTP requests. +.TP 5 +PreserveJobFiles Yes +.TP 5 +PreserveJobFiles No +.br +Specifies whether or not to preserve job files after they are printed. +.TP 5 +PreserveJobHistory Yes +.TP 5 +PreserveJobHistory No +.br +Specifies whether or not to preserve the job history after they are +printed. +.TP 5 +Printcap +.TP 5 +Printcap filename +.br +Specifies the filename for a printcap file that is updated +automatically with a list of available printers (needed for +legacy applications); specifying Printcap with no filename +disables printcap generation. +.TP 5 +PrintcapFormat bsd +.TP 5 +PrintcapFormat plist +.TP 5 +PrintcapFormat solaris +.br +Specifies the format of the printcap file. +.TP 5 +PrintcapGUI +.TP 5 +PrintcapGUI gui-program-filename +.br +Specifies whether to generate option panel definition files on +some operating systems. When provided with no program filename, +disables option panel definition files. +.TP 5 +ReloadTimeout seconds +.br +Specifies the amount of time to wait for job completion before +restarting the scheduler. +.TP 5 +RemoteRoot user-name +.br +Specifies the username that is associated with unauthenticated root +accesses. +.TP 5 +RequestRoot directory +.br +Specifies the directory to store print jobs and other HTTP request +data. +.TP 5 +Require group group-name-list +.TP 5 +Require user user-name-list +.TP 5 +Require valid-user +.br +Specifies that user or group authentication is required. +.TP 5 +RIPCache bytes +.br +Specifies the maximum amount of memory to use when converting images +and PostScript files to bitmaps for a printer. +.TP 5 +Satisfy all +.TP 5 +Satisfy any +.br +Specifies whether all or any limits set for a Location must be +satisfied to allow access. +.TP 5 +ServerAdmin user@domain.com +.br +Specifies the email address of the server administrator. +.TP 5 +ServerAlias hostname +.br +Specifies an alternate name that the server is known by. The special name "*" +allows any name to be used. +.TP 5 +ServerBin directory +.br +Specifies the directory where backends, CGIs, daemons, and filters may +be found. +.TP 5 +ServerCertificate filename +.br +Specifies the encryption certificate to use. +.TP 5 +ServerKey filename +.br +Specifies the encryption key to use. +.TP 5 +ServerName hostname-or-ip-address +.br +Specifies the fully-qualified hostname of the server. +.TP 5 +ServerRoot directory +.br +Specifies the directory where the server configuration files can be found. +.TP 5 +ServerTokens Full +.TP 5 +ServerTokens Major +.TP 5 +ServerTokens Minimal +.TP 5 +ServerTokens Minor +.TP 5 +ServerTokens None +.TP 5 +ServerTokens OS +.TP 5 +ServerTokens ProductOnly +.br +Specifies what information is included in the Server header of HTTP +responses. +.TP 5 +SetEnv variable value +.br +Set the specified environment variable to be passed to child processes. +.TP 5 +SSLListen +.br +Listens on the specified address and port for encrypted connections. +.TP 5 +SSLOptions None +.TP 5 +SSLOptions NoEmptyFragments +.br +Sets SSL/TLS protocol options for encrypted connections. +.TP 5 +SSLPort +.br +Listens on the specified port for encrypted connections. +.TP 5 +SystemGroup group-name [group-name ...] +.br +Specifies the group(s) to use for System class authentication. +.TP 5 +TempDir directory +.br +Specifies the directory where temporary files are stored. +.TP 5 +Timeout seconds +.br +Specifies the HTTP request timeout in seconds. +.TP 5 +User user-name +.br +Specifies the user name or ID that is used when running external programs. +.SH SEE ALSO +\fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fImime.convs(5)\fR, +\fImime.types(5)\fR, \fIprinters.conf(5)\fR, +\fIsubscriptions.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cupsd.man.in b/man/cupsd.man.in new file mode 100644 index 0000000000..18bcc4d877 --- /dev/null +++ b/man/cupsd.man.in @@ -0,0 +1,72 @@ +.\" +.\" "$Id$" +.\" +.\" cupsd man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsd 8 "CUPS" "9 March 2009" "Apple Inc." +.SH NAME +cupsd \- cups scheduler +.SH SYNOPSIS +.B cupsd +[ -c +.I config-file +] [ -f ] [ -F ] [ -h ] [ -l ] [ -t ] +.SH DESCRIPTION +\fIcupsd\fR is the scheduler for CUPS. It implements a printing system based +upon the Internet Printing Protocol, version 2.1. If no options are specified +on the command-line then the default configuration file +\fI@CUPS_SERVERROOT@/cupsd.conf\fR will be used. +.SH OPTIONS +.TP 5 +-c config-file +.br +Uses the named configuration file. +.TP 5 +-f +.br +Run \fIcupsd\fR in the foreground; the default is to run in the +background as a "daemon". +.TP 5 +-F +.br +Run \fIcupsd\fR in the foreground but detach the process from the +controlling terminal and current directory. This is useful for +running \fIcupsd\fR from \fIinit(8)\fR. +.TP 5 +-h +.br +Shows the program usage. +.TP 5 +-l +.br +This option is passed to \fIcupsd\fR when it is run from +\fIlaunchd(8)\fR. +.TP 5 +-t +.br +Test the configuration file for syntax errors. +.SH COMPATIBILITY +\fIcupsd\fR implements all of the required IPP/2.1 attributes and +operations. It also implements several CUPS-specific administration +operations. +.SH SEE ALSO +\fIbackend(7)\fR, \fIclasses.conf(5)\fR, \fIcups-deviced(8)\fR, +\fIcups-driverd(8)\fR, \fIcups-lpd(8)\fR, \fIcups-polld(8)\fR, +\fIcupsd.conf(5)\fR, \fIfilter(7)\fR, \fIlaunchd(8)\fR, +\fImime.convs(5)\fR, \fImime.types(5)\fR, \fIprinters.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/cupsenable.man b/man/cupsenable.man new file mode 100644 index 0000000000..24a59728f6 --- /dev/null +++ b/man/cupsenable.man @@ -0,0 +1,94 @@ +.\" +.\" "$Id: cupsenable.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" cupsenable/cupsdisable man page for the Common UNIX Printing System +.\" (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsenable 8 "CUPS" "9 October 2008" "Apple Inc." +.SH NAME +cupsdisable, cupsenable \- stop/start printers and classes +.SH SYNOPSIS +.B cupsdisable +[ -E ] [-U +.I username +] [ -c ] [ -h +.I server[:port] +] [ -r +.I reason +] [ --hold ] destination(s) +.br +.B cupsenable +[ -E ] [-U +.I username +] [ -c ] [ -h +.I server[:port] +] [ --release ] destination(s) +.SH DESCRIPTION +\fIcupsenable\fR starts the named printers or classes. +.LP +\fIcupsdisable\fR stops the named printers or classes. The +following options may be used: +.TP 5 +-E +.br +Forces encryption of the connection to the server. +.TP 5 +-U username +.br +Uses the specified username when connecting to the server. +.TP 5 +-c +.br +Cancels all jobs on the named destination. +.TP 5 +-h server[:port] +.br +Uses the specified server and port. +.TP 5 +--hold +.br +Holds remaining jobs on the named printer. Useful for allowing the current +job to complete before performing maintenance. +.TP 5 +-r "reason" +.br +Sets the message associated with the stopped state. If no reason is specified +then the message is set to "Reason Unknown". +.TP 5 +--release +.br +Releases pending jobs for printing. Use after running \fIcupsdisable\fR with +the \fI--hold\fR option to resume printing. +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to +contain any printable character except SPACE, TAB, "/", or "#". +Also, printer and class names are \fInot\fR case-sensitive. +.LP +The System V versions of these commands are \fIdisable\fR and +\fIenable\fR. They have been renamed to avoid conflicts with the +\fIbash(1)\fR build-in commands of the same name. +.LP +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 +\fIcupsaccept(8)\fR, \fIcupsreject(8)\fR, \fIcancel(1)\fR, \fIlp(1)\fR, +\fIlpadmin(8)\fR, \fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. + +.\" +.\" End of "$Id: cupsenable.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cupsfilter.man b/man/cupsfilter.man new file mode 100644 index 0000000000..4b199f9f0a --- /dev/null +++ b/man/cupsfilter.man @@ -0,0 +1,86 @@ +.\" +.\" "$Id: cupsfilter.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" cupsfilter man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupsfilter 8 "CUPS" "26 February 2009" "Apple Inc." +.SH NAME +cupsfilter \- convert a file to another format using cups filters +.SH SYNOPSIS +.B cupsfilter +[ -c +.I config-file +] [ -e ] -j +.I job-id[,N] +[ -m +.I mime/type +] [ -n +.I copies +] [ -o +.I name=value +] [ -p +.I filename.ppd +] [ -t +.I title +] +.I filename +.SH DESCRIPTION +\fIcupsfilter\fR is a front-end to the CUPS filter subsystem which allows you +to convert a file to a specific format, just as if you had printed the file +through CUPS. By default, \fIcupsfilter\fR generates a PDF file. +.SH OPTIONS +.TP 5 +-c config-file +.br +Uses the named cupsd.conf configuration file. +.TP 5 +-e +.br +Use every filter from the PPD file. +.TP 5 +-j job-id[,N] +.br +Converts document N from the specified job. If N is omitted, document 1 is +converted. +.TP 5 +-m mime/type +.br +Specifies the destination file type. The default file type is application/pdf. +Use printer/foo to convert to the printer format defined by the filters in the +PPD file. +.TP 5 +-n copies +.br +Specifies the number of copies to generate. +.TP 5 +-o name=value +.br +Specifies options to pass to the CUPS filters. +.TP 5 +-p filename.ppd +.br +Specifies the PPD file to use. +.TP 5 +-t title +.br +Specifies the document title. +.SH KNOWN ISSUES +\fIcupsfilter\fR currently does not use the filters defined in the PPD file. +This will be addressed in a future CUPS release. +.SH SEE ALSO +\fIcupsd.conf(5)\fR +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cupsfilter.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cupstestdsc.man b/man/cupstestdsc.man new file mode 100644 index 0000000000..cbfbd25fbe --- /dev/null +++ b/man/cupstestdsc.man @@ -0,0 +1,50 @@ +.\" +.\" "$Id: cupstestdsc.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" cupstestdsc man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupstestdsc 1 "CUPS" "20 March 2006" "Apple Inc." +.SH NAME +cupstestdsc \- test conformance of postscript files +.SH SYNOPSIS +.B cupstestdsc +[ -h ] filename.ps [ ... +.I filenameN.ps +] +.br +.B cupstestdsc +[ -h ] - +.SH DESCRIPTION +\fIcupstestdsc\fR tests the conformance of PostScript files to +the Adobe PostScript Language Document Structuring Conventions +Specification version 3.0. The results of testing and any other +output are sent to the standard output. The second form of the +command reads PostScript from the standard input. +.SH LIMITATIONS +\fIcupstestdsc\fR only validates the DSC comments in a PostScript +file and does not attempt to validate the PostScript code itself. +Developers must ensure that the PostScript they generate follows +the rules defined by Adobe. Specifically, all pages must be +independent of each other, code outside page descriptions may not +affect the graphics state (current font, color, transform matrix, +etc.), and device-specific commands such as setpagedevice should +not be used. +.SH SEE ALSO +http://localhost:631/help +.br +Adobe PostScript Language Document Structuring Conventions +Specification, Version 3.0. +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cupstestdsc.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/cupstestppd.man b/man/cupstestppd.man new file mode 100644 index 0000000000..f580e18ece --- /dev/null +++ b/man/cupstestppd.man @@ -0,0 +1,165 @@ +.\" +.\" "$Id: cupstestppd.man 9120 2010-04-23 18:56:34Z mike $" +.\" +.\" cupstestppd man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH cupstestppd 1 "CUPS" "19 November 2009" "Apple Inc." +.SH NAME +cupstestppd \- test conformance of ppd files +.SH SYNOPSIS +.B cupstestppd +[ -I +.I category +] [ -R +.I rootdir +] [ -W +.I category +] [ -q ] [-r] [ -v[v] ] filename.ppd[.gz] [ ... filenameN.ppd[.gz] ] +.br +.B cupstestppd +[ -R +.I rootdir +] [ -W +.I category +] [ -q ] [-r] [ -v[v] ] - +.SH DESCRIPTION +\fIcupstestppd\fR tests the conformance of PPD files to the +Adobe PostScript Printer Description file format specification +version 4.3. It can also be used to list the supported options +and available fonts in a PPD file. The results of testing and +any other output are sent to the standard output. +.LP +The first form of \fIcupstestppd\fR tests one or more PPD files +on the command-line. The second form tests the PPD file provided +on the standard input. +.SH OPTIONS +\fIcupstestppd\fR supports the following options: +.TP 5 +-I filename +.br +Ignores all PCFileName warnings. +.TP 5 +-I filters +.br +Ignores all filter errors. +.TP 5 +-I profiles +.br +Ignores all profile errors. +.TP 5 +-R rootdir +.br +Specifies an alternate root directory for the filter, pre-filter, +and other support file checks. +.TP 5 +-W constraints +.br +Report all UIConstraint errors as warnings. +.TP 5 +-W defaults +.br +Except for size-related options, report all default option errors as warnings. +.TP 5 +-W filters +.br +Report all filter errors as warnings. +.TP 5 +-W profiles +.br +Report all profile errors as warnings. +.TP 5 +-W sizes +.br +Report all media size errors as warnings. +.TP 5 +-W translations +.br +Report all translation errors as warnings. +.TP 5 +-W all +.br +Report all of the previous errors as warnings. +.TP 5 +-W none +.br +Report all of the previous errors as errors. +.TP 5 +-q +.br +Specifies that no information should be displayed. +.TP 5 +-r +.br +Relaxes the PPD conformance requirements so that common +whitespace, control character, and formatting problems are not +treated as hard errors. +.TP 5 +-v +.br +Specifies that detailed conformance testing results should be +displayed rather than the concise PASS/FAIL/ERROR status. +.TP 5 +-vv +.br +Specifies that all information in the PPD file should be +displayed in addition to the detailed conformance testing +results. +.LP +The \fI-q\fR, \fI-v\fR, and \fI-vv\fR options are mutually exclusive. +.SH EXIT STATUS +\fIcupstestppd\fR returns zero on success and non-zero on error. The +error codes are as follows: +.TP 5 +1 +.br +Bad command-line arguments or missing PPD filename. +.TP 5 +2 +.br +Unable to open or read PPD file. +.TP 5 +3 +.br +The PPD file contains format errors that cannot be skipped. +.TP 5 +4 +.br +The PPD file does not conform to the Adobe PPD specification. +.SH EXAMPLES +The following command will test all PPD files under the current +directory and print the names of each file that does not +conform: +.nf + + find . -name \\*.ppd \\! -exec cupstestppd -q '{}' \\; -print + +.fi +The next command tests all PPD files under the current directory +and print detailed conformance testing results for the files +that do not conform: +.nf + + find . -name \\*.ppd \\! -exec cupstestppd -q '{}' \\; \\ + -exec cupstestppd -v '{}' \\; + +.fi +.SH SEE ALSO +\fIlpadmin(8)\fR, +.br +http://localhost:631/help +.br +Adobe PostScript Printer Description File Format Specification, Version 4.3. +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: cupstestppd.man 9120 2010-04-23 18:56:34Z mike $". +.\" diff --git a/man/filter.man b/man/filter.man new file mode 100644 index 0000000000..f3c41289bb --- /dev/null +++ b/man/filter.man @@ -0,0 +1,256 @@ +.\" +.\" "$Id: filter.man 8622 2009-05-13 16:28:43Z mike $" +.\" +.\" filter man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2007 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH filter 7 "CUPS" "13 May 2009" "Apple Inc." +.SH NAME +filter \- cups file conversion filter interface +.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 \fBmust\fR 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 \fBmust\fR be sent to the +standard output. +.LP +The command name (argv[0]) is set to the name of the destination printer but is +also available in the PRINTER environment variable. + +.SH OPTIONS +Options passed on the command-line typically do not include the default choices +the printer's PPD file. In addition, some options may be specified in multiple +ways - "landscape" is a synonym for "orientation-requested=4", "media" is a +synonym for "PageSize", "PageRegion", "InputSlot", and "MediaType", and "sides" +is a synonym for the various "Duplex" options. Non-raster filters \fBmust\fR +support both explicit and implicit specification of PPD options - use the +ppdMarkDefaults and cupsMarkOptions functions in the CUPS library to use the +correct mapping, and ppdFindMarkedChoice to get the user-selected choice. +.LP +Raster filters should use option choices set through the raster page header, as +those reflect the options in effect for a given page. Options specified on the +command-line determine the default values for the entire job, which can be +overridden on a per-page basis. + +.SH LOG MESSAGES +Messages sent to stderr are generally logged to +printer-state-message attribute and the current \fIErrorLog\fR. +Each line begins with a standard prefix: + +.TP 5 +ALERT: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "alert" log level. + +.TP 5 +ATTR: attribute=value [attribute=value] +.br +Sets the named job attribute(s). Typically this will be used to +set the job-remote-id attribute. + +.TP 5 +CRIT: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "critical" log level. + +.TP 5 +DEBUG: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "debug" log level. + +.TP 5 +DEBUG2: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "debug2" log level. + +.TP 5 +EMERG: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "emergency" log level. + +.TP 5 +ERROR: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "error" log level. + +.TP 5 +INFO: message +.br +Sets the printer-state-message attribute. If the current \fILogLevel\fR +is set to "debug2", also adds the specified message to the +current \fIErrorLog\fR using the "info" log level. + +.TP 5 +NOTICE: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "notice" log level. + +.TP 5 +PAGE: page-number #-copies +.TP 5 +PAGE: total #-pages +.br +Adds an entry to the current \fIPageLog\fR. The first form adds +#-copies to the job-media-sheets-completed attribute. The second +form sets the job-media-sheets-completed attribute to #-pages. + +.TP 5 +PPD: Keyword=Value ... KeywordN=Value +.br +Sets the named keywords in the printer's PPD file. This is typically +used to update default option keywords such as DefaultPageSize and +the various installable options in the PPD file. + +.TP 5 +STATE: printer-state-reason [printer-state-reason ...] +.TP 5 +STATE: + printer-state-reason [printer-state-reason ...] +.TP 5 +STATE: - printer-state-reason [printer-state-reason ...] +.br +Sets, adds, or removes printer-state-reason keywords to the +current queue. Typically this is used to indicate media, ink, and +toner conditions on a printer. + +.TP 5 +WARNING: message +.br +Sets the printer-state-message attribute and adds the specified +message to the current \fIErrorLog\fR using the "warning" log level. + +.SH ENVIRONMENT VARIABLES +The following environment variables are defined by the CUPS +server when executing the filter: + +.TP 5 +CHARSET +.br +The default text character set, typically utf-8. + +.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_CACHEDIR +.br +The directory for semi-persistent cache files can be found. + +.TP 5 +CUPS_DATADIR +.br +The directory where data files can be found. + +.TP 5 +CUPS_FILETYPE +.br +The type of file being printed: "job-sheet" for a banner page and "document" +for a regular print file. + +.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 +FINAL_CONTENT_TYPE +.br +The MIME type associated with the printer (e.g. +application/vnd.cups-postscript). + +.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. + +.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.2). + +.TP 5 +TZ +.br +The timezone of the server. + +.TP 5 +USER +.br +The user executing the filter, typically "lp" or "root"; consult the +\fIcupsd.conf(5)\fR file for the current setting. + +.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 +\fIlpadmin(8)\fR command using the \fI-i\fR option. +.SH SEE ALSO +\fIbackend(7)\fR, \fIcupsd(8)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: filter.man 8622 2009-05-13 16:28:43Z mike $". +.\" diff --git a/man/lp.man b/man/lp.man new file mode 100644 index 0000000000..b541db9ca7 --- /dev/null +++ b/man/lp.man @@ -0,0 +1,262 @@ +.\" +.\" "$Id: lp.man 9665 2011-03-31 18:54:19Z mike $" +.\" +.\" lp man page for CUPS. +.\" +.\" Copyright 2007-2011 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lp 1 "CUPS" "31 March 2011" "Apple Inc." +.SH NAME +lp - print files +.SH SYNOPSIS +.B lp +[ -E ] [ -U +.I username +] [ -c ] [ -d +.I destination[/instance] +] [ -h +.I hostname[:port] +] [ -m ] [ -n +.I num-copies +] [ -o +.I option[=value] +] [ -q +.I priority +] [ -s ] [ -t +.I title +] [ -H +.I handling +] [ -P +.I page-list +] [ -- ] [ +.I file(s) +] +.br +.B lp +[ -E ] [ -U +.I username +] [ -c ] [ -h +.I hostname[:port] +] [ -i +.I job-id +] [ -n +.I num-copies +] [ -o +.I option[=value] +] [ -q +.I priority +] [ -t +.I title +] [ -H +.I handling +] [ -P +.I page-list +] +.SH DESCRIPTION +\fIlp\fR submits files for printing or alters a pending job. Use +a filename of "-" to force printing from the standard input. +.SH THE DEFAULT DESTINATION +CUPS provides many ways to set the default destination. The "LPDEST" and +"PRINTER" environment variables are consulted first. If neither are set, +the current default set using the \fIlpoptions(1)\fR command is used, +followed by the default set using the \fIlpadmin(8)\fR command. +.SH OPTIONS +The following options are recognized by \fIlp\fR: +.TP 5 +-- +.br +Marks the end of options; use this to print a file whose name +begins with a dash (-). +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-U username +.br +Specifies the username to use 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 destination +.br +Prints files to the named printer. +.TP 5 +-h hostname[:port] +.br +Chooses an alternate server. +.TP 5 +-i job-id +.br +Specifies an existing job to modify. +.TP 5 +-m +.br +Sends an email when the job is completed. +.TP 5 +-n copies +.br +Sets the number of copies to print from 1 to 100. +.TP 5 +-o "name=value [name=value ...]" +.br +Sets one or more job options. +.TP 5 +-q priority +.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 "name" +.br +Sets the job name. +.TP 5 +-u username +.br +Submits jobs as \fIusername\fR. +.TP 5 +-H hh:mm +.TP 5 +-H hold +.TP 5 +-H immediate +.TP 5 +-H restart +.TP 5 +-H resume +.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 UTC time value (HH:MM) will hold the job until the specified UTC (not local) +time. Use a value of \fIresume\fR with the \fI-i\fR option to resume a held job. +Use a value of \fIrestart\fR with the \fI-i\fR option to restart +a completed job. +.TP 5 +-P page-list +.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). The page numbers refer to the output pages and +not the document's original pages - options like "number-up" can +affect the numbering of the pages. +.SH COMMON JOB OPTIONS +Aside from the printer-specific options reported by the +\fIlpoptions(1)\fR command, the following generic options are +available: +.TP 5 +-o media=size +.br +Sets the page size to \fIsize\fR. Most printers support at least +the size names "a4", "letter", and "legal". +.TP 5 +-o landscape +.TP 5 +-o orientation-requested=4 +.br +Prints the job in landscape (rotated 90 degrees). +.TP 5 +-o sides=one-sided +.TP 5 +-o sides=two-sided-long-edge +.TP 5 +-o sides=two-sided-short-edge +.br +Prints on one or two sides of the paper. The value +"two-sided-long-edge" is normally used when printing portrait +(unrotated) pages, while "two-sided-short-edge" is used for +landscape pages. +.TP 5 +-o fitplot +.br +Scales the print file to fit on the page. +.TP 5 +-o number-up=2 +.TP 5 +-o number-up=4 +.TP 5 +-o number-up=6 +.TP 5 +-o number-up=9 +.TP 5 +-o number-up=16 +.br +Prints multiple document pages on each output page. +.TP 5 +-o scaling=number +.br +Scales image files to use up to \fInumber\fR percent of the page. +Values greater than 100 cause the image file to be printed across +multiple pages. +.TP 5 +-o cpi=N +.br +Sets the number of characters per inch to use when printing a +text file. The default is 10. +.TP 5 +-o lpi=N +.br +Sets the number of lines per inch to use when printing a text +file. The default is 6. +.TP 5 +-o page-bottom=N +.TP 5 +-o page-left=N +.TP 5 +-o page-right=N +.TP 5 +-o page-top=N +.br +Sets the page margins when printing text files. The values are in +points - there are 72 points to the inch. +.SH EXAMPLES +Print a double-sided legal document to a printer called "foo": +.nf + lp -d foo -o media=legal -o sides=two-sided-long-edge filename +.fi +.LP +Print an image across 4 pages: +.nf + lp -d bar -o scaling=200 filename +.fi +.LP +Print a text file with 12 characters per inch, 8 lines per inch, and +a 1 inch left margin: +.nf + lp -d bar -o cpi=12 -o lpi=8 -o page-left=72 filename +.fi +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to +contain any printable character except SPACE, TAB, "/", or "#". +Also, printer and class names are \fInot\fR case-sensitive. +.LP +The "q" option accepts a different range of values than the +Solaris lp command, matching the IPP job priority values (1-100, +100 is highest priority) instead of the Solaris values (0-39, 0 +is highest priority). +.SH SEE ALSO +\fIcancel(1)\fR, \fIlpadmin(8)\fR, \fIlpmove(8)\fR, \fIlpoptions(1)\fR, +\fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2011 by Apple Inc. +.\" +.\" End of "$Id: lp.man 9665 2011-03-31 18:54:19Z mike $". +.\" diff --git a/man/lpadmin.man b/man/lpadmin.man new file mode 100644 index 0000000000..0926259eea --- /dev/null +++ b/man/lpadmin.man @@ -0,0 +1,208 @@ +.\" +.\" "$Id: lpadmin.man 9473 2011-01-11 16:28:51Z mike $" +.\" +.\" lpadmin man page for CUPS. +.\" +.\" Copyright 2007-2011 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpadmin 8 "CUPS" "7 January 2011" "Apple Inc." +.SH NAME +lpadmin \- configure cups printers and classes +.SH SYNOPSIS +.B lpadmin +[ -E ] [-U +.I username +] [ -h +.I server[:port] +] -d +.I destination +.br +.B lpadmin +[ -E ] [-U +.I username +] [ -h +.I server[:port] +] -p +.I destination option(s) +.br +.B lpadmin +[ -E ] [-U +.I username +] [ -h +.I server[:port] +] -x +.I destination +.SH DESCRIPTION +\fIlpadmin\fR configures printer and class queues provided by +CUPS. It can also be used to set the server 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 (\fI-d\fR) 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 with the +\fIlpoptions(1)\fR command. +.LP +The second form of the command (\fI-p\fR) configures the named +printer or class. The additional options are described below. +.LP +The third form of the command (\fI-x\fR) 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 class +.br +Adds the named \fIprinter\fR to \fIclass\fR. If \fIclass\fR does +not exist it is created automatically. +.TP 5 +-i interface +.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 model +.br +Sets a standard System V interface script or PPD file for the printer from the +\fImodel\fR directory or using one of the driver interfaces. Use the \fI-m\fR +option with the \fIlpinfo(8)\fR command to get a list of supported models. +.TP 5 +-o job-k-limit=value +.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 job-page-limit=value +.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 job-quota-period=value +.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 +-o job-sheets-default=banner +.TP 5 +-o job-sheets-default=banner,banner +.br +Sets the default banner page(s) to use for print jobs. +.TP 5 +-o name=value +.br +Sets a PPD option for the printer. PPD options can be listed using the \fI-l\fR +option with the \fIlpoptions(1)\fR command. +.TP 5 +-o name-default=value +.br +Sets a default server-side option for the destination. Any print-time +option can be defaulted, e.g. "-o cpi-default=17" to set the default +"cpi" option value to 17. +.TP 5 +-o port-monitor=name +.br +Sets the binary communications program to use when printing, +"none", "bcp", or "tbcp". The default program is "none". The +specified port monitor must be listed in the printer's PPD file. +.TP 5 +-o printer-error-policy=name +.br +Sets the error policy to be used when the printer backend is +unable to send the job to the printer. The name must be one of +"abort-job", "retry-job", "retry-current-job", or "stop-printer". The default +error policy is "stop-printer" for printers and "retry-current-job" for +classes. +.TP 5 +-o printer-is-shared=true/false +.br +Sets the destination to shared/published or unshared/unpublished. +Shared/published destinations are publicly announced by the server +on the LAN based on the browsing configuration in +\fBcupsd.conf\fR, while unshared/unpublished destinations are not +announced. The default value is "true". +.TP 5 +-o printer-op-policy=name +.br +Sets the IPP operation policy associated with the destination. The +name must be defined in the \fBcupsd.conf\fR in a Policy section. +The default operation policy is "default". +.TP 5 +-r class +.br +Removes the named \fIprinter\fR from \fIclass\fR. If the +resulting class becomes empty it is removed. +.TP 5 +-u allow:user,user,@group +.TP 5 +-u deny:user,user,@group +.TP 5 +-u allow:all +.TP 5 +-u deny:none +.br +Sets user-level access control on a destination. Names starting with +"@" are interpreted as UNIX groups. The latter two forms turn +user-level access control off. +.TP 5 +-v "device-uri" +.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 \fIfile:///file/name\fR. Use the \fI-v\fR option with the +\fIlpinfo(8)\fR command to get a list of supported device URIs and schemes. +.TP 5 +-D "info" +.br +Provides a textual description of the destination. +.TP 5 +-E +.br +Enables the destination and accepts jobs; this is the same as running the +\fIcupsaccept(8)\fR and \fIcupsenable(8)\fR programs on the destination. +.TP 5 +-L "location" +.br +Provides a textual location of the destination. +.TP 5 +-P ppd-file +.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, TAB, "/", or "#". +Also, printer and class names are \fInot\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 +\fIcupsaccept(8)\fR, \fIcupsenable(8)\fR, \fIlpinfo(8)\fR, +\fIlpoptions(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2011 by Apple Inc. +.\" +.\" End of "$Id: lpadmin.man 9473 2011-01-11 16:28:51Z mike $". +.\" diff --git a/man/lpc.man b/man/lpc.man new file mode 100644 index 0000000000..22a60505ce --- /dev/null +++ b/man/lpc.man @@ -0,0 +1,71 @@ +.\" +.\" "$Id: lpc.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpc man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpc 8 "CUPS" "3 November 2008" "Apple Inc." +.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 +exit +.br +Exits the command interpreter. +.TP 5 +help [command] +.TP 5 +? [command] +.br +Displays a short help message. +.TP 5 +quit +.br +Exits the command interpreter. +.TP 5 +status [queue] +.br +Displays the status of one or more printer or class queues. +.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 or LPRng commands. +.SH SEE ALSO +\fIcancel(1)\fR, \fIcupsaccept(8)\fR, \fIcupsenable(8)\fR, +\fIlp(1)\fR, \fIlpr(1)\fR, \fIlprm(1)\fR, \fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lpc.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/lpinfo.man b/man/lpinfo.man new file mode 100644 index 0000000000..8606579c89 --- /dev/null +++ b/man/lpinfo.man @@ -0,0 +1,115 @@ +.\" +.\" "$Id: lpinfo.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpinfo man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpinfo 8 "CUPS" "5 December 2008" "Apple Inc." +.SH NAME +lpinfo \- show available devices or drivers +.SH SYNOPSIS +.B lpinfo +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] [ -l ] [ --device-id +.I device-id-string +] [ --exclude-schemes +.I scheme-list +] [ --include-schemes +.I scheme-list +] [ --language +.I locale +] [ --make-and-model +.I name +] [ --product +.I name +] -m +.br +.B lpinfo +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] [ -l ] [ --exclude-schemes +.I scheme-list +] [ --include-schemes +.I scheme-list +] [ --timeout +.I seconds +] -v +.SH DESCRIPTION +\fIlpinfo\fR lists the available devices or drivers known to the +CUPS server. The first form (\fI-m\fR) lists the available +drivers, while the second form (\fI-v\fR) lists the available +devices. +.SH OPTIONS +\fIlpinfo\fR accepts the following options: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-U username +.br +Sets the username to use when connecting to the server. +.TP 5 +-h server[:port] +.br +Selects an alternate server. +.TP 5 +-l +.br +Shows a "long" listing of devices or drivers. +.TP 5 +--device-id device-id-string +.br +Specifies the IEEE-1284 device ID to match when listing drivers with the +\fI-m\fR option. +.TP 5 +--exclude-schemes scheme-list +.br +Specifies a comma-separated list of device or PPD schemes that should be +excluded from the results. Static PPD files use the "file" scheme. +.TP 5 +--include-schemes scheme-list +.br +Specifies a comma-separated list of device or PPD schemes that should be +included in the results. Static PPD files use the "file" scheme. +.TP 5 +--language locale +.br +Specifies the language to match when listing drivers with the \fI-m\fR option. +.TP 5 +--make-and-model name +.br +Specifies the make and model to match when listing drivers with the \fI-m\fR +option. +.TP 5 +--product name +.br +Specifies the product to match when listing drivers with the \fI-m\fR option. +.TP 5 +--timeout seconds +.br +Specifies the timeout when listing devices with the \fI-v\fR option. +.SH COMPATIBILITY +The \fIlpinfo\fR command is unique to CUPS. +.SH SEE ALSO +\fIlpadmin(8)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lpinfo.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/lpmove.man b/man/lpmove.man new file mode 100644 index 0000000000..635cedea65 --- /dev/null +++ b/man/lpmove.man @@ -0,0 +1,66 @@ +.\" +.\" "$Id: lpmove.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpmove man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpmove 8 "CUPS" "12 February 2006" "Apple Inc." +.SH NAME +lpmove \- move a job or all jobs to a new destination +.SH SYNOPSIS +.B lpmove +[ -E ] [ -h +.I server[:port] +] [ -U +.I username +] +.I job destination +.br +.B lpmove +[ -E ] [ -h +.I server[:port] +] [ -U +.I username +] +.I source destination +.SH DESCRIPTION +\fBlpmove\fR moves the specified \fIjob\fR or all jobs from +\fIsource\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 +.SH OPTIONS +The \fIlpmove\fR command supports the following options: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-U username +.br +Specifies an alternate username. +.TP 5 +-h server[:port] +.br +Specifies an alternate server. +.SH SEE ALSO +\fIcancel(1)\fR, \fIlp(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lpmove.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/lpoptions.man.in b/man/lpoptions.man.in new file mode 100644 index 0000000000..40946858fd --- /dev/null +++ b/man/lpoptions.man.in @@ -0,0 +1,135 @@ +.\" +.\" "$Id$" +.\" +.\" lpoptions man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpoptions 1 "CUPS" "29 August 2008" "Apple Inc." +.SH NAME +lpoptions \- display or set printer options and defaults +.SH SYNOPSIS +.B lpoptions +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] -d +.I destination[/instance] +[ -o +.I option[=value] +] ... [ -o +.I option[=value] +] +.br +.B lpoptions +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] [ -p +.I destination[/instance] +] -l +.br +.B lpoptions +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] [ -o +.I option[=value] +] ... [ -o +.I option[=value] +] [ -p +.I destination[/instance] +] -r +.I option +.br +.B lpoptions +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] -x +.I destination[/instance] +.SH DESCRIPTION +\fIlpoptions\fR displays or sets printer options and defaults. +\fIlpoptions\fR shows the default printer options when run with no +arguments. Other options include: +.TP 5 +-E +.br +Enables encryption when communicating with the CUPS server. +.TP 5 +-U username +.br +Uses an alternate username. +.TP 5 +-d destination[/instance] +.br +Sets the user default printer to \fIdestination\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 server[:port] +.br +Uses an alternate server. +.TP 5 +-l +.br +Lists the printer specific options and their current settings. +.TP 5 +-o option[=value] +.br +Specifies a new option for the named destination. +.TP 5 +-p destination[/instance] +.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 option +.br +Removes the specified option for the named destination. +.TP 5 +-x destination[/instance] +.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 \fIlpoptions\fR command are used by the +\fIlp(1)\fR and \fIlpr(1)\fR commands when submitting jobs. +.SH ROOT ACCOUNT OPTIONS +When run by the root user, \fIlpoptions\fR gets and sets default +options and instances for \fIall users\fR in the +@CUPS_SERVERROOT@/lpoptions file. +.SH COMPATIBILITY +The \fIlpoptions\fR command is unique to CUPS. +.SH FILES +~/.cups/lpoptions - user defaults and instances created by non-root +users. +.br +@CUPS_SERVERROOT@/lpoptions - system-wide defaults and instances +created by the root user. +.SH SEE ALSO +\fIcancel(1)\fR, \fIlp(1)\fR, \fIlpadmin(8)\fR, \fIlpr(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id$". +.\" diff --git a/man/lppasswd.man b/man/lppasswd.man new file mode 100644 index 0000000000..7c0ce980e4 --- /dev/null +++ b/man/lppasswd.man @@ -0,0 +1,68 @@ +.\" +.\" "$Id: lppasswd.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpadmin man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lppasswd 1 "CUPS" "22 February 2008" "Apple Inc." +.SH NAME +lppasswd \- add, change, or delete digest passwords. +.SH SYNOPSIS +.B lppasswd +[ +.I username +] +.br +.B lppasswd +-a [ -g +.I groupname +] +.I username +.br +.B lppasswd +-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. +.SH OPTIONS +\fIlppasswd\fR supports the following options: +.TP 5 +-g groupname +.br +Specifies a group other than the default system group. +.SH SECURITY ISSUES +By default, the \fIlppasswd\fR program is not installed to allow ordinary +users to change their passwords. To enable this, the \fIlppasswd\fR command +must be made setuid to root with the command: +.br +.nf +chmod u+s lppasswd +.fi +.PP +While every attempt has been made to make \fIlppasswd\fR secure against +exploits that could grant super-user privileges to unprivileged users, +paranoid system administrators may wish to use Basic authentication with +accounts managed by PAM instead. +.SH SEE ALSO +\fIlp(1)\fR, \fIlpr(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lppasswd.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/lpq.man b/man/lpq.man new file mode 100644 index 0000000000..ce5f0927db --- /dev/null +++ b/man/lpq.man @@ -0,0 +1,72 @@ +.\" +.\" "$Id: lpq.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpq man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpq 1 "CUPS" "16 June 2008" "Apple Inc." +.SH NAME +lpq \- show printer queue status +.SH SYNOPSIS +.B lpq +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] [ -P +.I destination[/instance] +] [ -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 \fI+interval\fR option allows you to continuously report the +jobs in the queue until the queue is empty; the list of jobs is +shown once every \fIinterval\fR seconds. +.SH OPTIONS +\fIlpq\fR supports the following options: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-P destination[/instance] +.br +Specifies an alternate printer or class name. +.TP 5 +-U username +.br +Specifies an alternate username. +.TP 5 +-a +.br +Reports jobs on all printers. +.TP 5 +-h server[:port] +.br +Specifies an alternate server. +.TP 5 +-l +.br +Requests a more verbose (long) reporting format. +.SH SEE ALSO +\fIcancel(1)\fR, \fIlp(1)\fR, \fIlpr(1)\fR, \fIlprm(1)\fR, +\fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lpq.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/lpr.man b/man/lpr.man new file mode 100644 index 0000000000..ab8c4ae103 --- /dev/null +++ b/man/lpr.man @@ -0,0 +1,122 @@ +.\" +.\" "$Id: lpr.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpr man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpr 1 "CUPS" "29 August 2008" "Apple Inc." +.SH NAME +lpr \- print files +.SH SYNOPSIS +.B lpr +[ -E ] [ -H +.I server[:port] +] [ -U +.I username +] [ -P +.I destination[/instance] +] [ -# +.I num-copies +[ -h ] [ -l ] [ -m ] [ -o +.I option[=value] +] [ -p] [ -q ] [ -r ] [ -C/J/T +.I title +] [ +.I file(s) +] +.SH DESCRIPTION +\fIlpr\fR submits files for printing. Files named on the command +line are sent to the named printer (or the default destination if no +destination is specified). If no files are listed on the command-line, +\fIlpr\fR reads the print file from the standard input. +.SH THE DEFAULT DESTINATION +CUPS provides many ways to set the default destination. The "LPDEST" and +"PRINTER" environment variables are consulted first. If neither are set, +the current default set using the \fIlpoptions(1)\fR command is used, +followed by the default set using the \fIlpadmin(8)\fR command. +.SH OPTIONS +The following options are recognized by \fIlpr\fR: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-H server[:port] +.br +Specifies an alternate server. +.TP 5 +-C "name" +.TP 5 +-J "name" +.TP 5 +-T "name" +.br +Sets the job name. +.TP 5 +-P destination[/instance] +.br +Prints files to the named printer. +.TP 5 +-U username +.br +Specifies an alternate username. +.TP 5 +-# \fIcopies\fR +.br +Sets the number of copies to print from 1 to 100. +.TP 5 +-h +.br +Disables banner printing. This option is equivalent to "-o +job-sheets=none". +.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 "-o raw". +.TP 5 +-m +.br +Send an email on job completion. +.TP 5 +-o option[=value] +.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 "-o prettyprint" and is only useful when +printing text files. +.TP 5 +-q +.br +Hold job for printing. +.TP 5 +-r +.br +Specifies that the named print files should be deleted after +printing them. +.SH COMPATIBILITY +The "c", "d", "f", "g", "i", "n", "t", "v", and "w" options +are not supported by CUPS and produce a warning message if used. +.SH SEE ALSO +\fIcancel(1)\fR, \fIlp(1)\fR, \fIlpadmin(8)\fR, \fIlpoptions(1)\fR, +\fIlpq(1)\fR, \fIlprm(1)\fR, \fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lpr.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/lprm.man b/man/lprm.man new file mode 100644 index 0000000000..62a3bef551 --- /dev/null +++ b/man/lprm.man @@ -0,0 +1,65 @@ +.\" +.\" "$Id: lprm.man 8801 2009-08-29 06:05:14Z mike $" +.\" +.\" lprm man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lprm 1 "CUPS" "28 August 2009" "Apple Inc." +.SH NAME +lprm \- cancel print jobs +.SH SYNOPSIS +.B lprm +[ -E ] [ -U +.I username +] [ -h +.I server[:port] +] [ -P +.I destination[/instance] +] [ - ] [ +.I job ID(s) +] +.SH DESCRIPTION +\fIlprm\fR cancels print jobs that have been queued for printing. +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. +.SH OPTIONS +The \fIlprm\fR command supports the following options: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-P destination[/instance] +.br +Specifies the destination printer or class. +.TP 5 +-U username +.br +Specifies an alternate username. +.TP 5 +-h server[:port] +.br +Specifies an alternate server. +.SH COMPATIBILITY +The CUPS version of \fIlprm\fR is compatible with the standard +Berkeley \fIlprm\fR command. +.SH SEE ALSO +\fIcancel(1)\fR, \fIlp(1)\fR, \fIlpq(1)\fR, \fIlpr(1)\fR, +\fIlpstat(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lprm.man 8801 2009-08-29 06:05:14Z mike $". +.\" diff --git a/man/lpstat.man b/man/lpstat.man new file mode 100644 index 0000000000..0b8511c7c1 --- /dev/null +++ b/man/lpstat.man @@ -0,0 +1,143 @@ +.\" +.\" "$Id: lpstat.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" lpstat man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH lpstat 1 "CUPS" "10 September 2008" "Apple Inc." +.SH NAME +lpstat \- print cups status information +.SH SYNOPSIS +.B lpstat +[ -E ] [ -H ] [ -U +.I username +] [ -h +.I hostname[:port] +] [ -l ] [ -W +.I which-jobs +] [ -a [ +.I destination(s) +] ] [ -c [ +.I class(es) +] ] [ -d ] [ -o [ +.I destination(s) +] ] [ -p [ +.I printer(s) +] ] [ -r ] [ -R ] [ -s ] [ -t ] [ -u [ +.I user(s) +] ] [ -v [ +.I printer(s) +] ] +.SH DESCRIPTION +\fIlpstat\fR displays status information about the current +classes, jobs, and printers. When run with no arguments, +\fIlpstat\fR will list jobs queued by the current user. +.SH OPTIONS +The \fIlpstat\fR command supports the following options: +.TP 5 +-E +.br +Forces encryption when connecting to the server. +.TP 5 +-H +.br +Shows the server hostname and port. +.TP 5 +-R +.br +Shows the ranking of print jobs. +.TP 5 +-U username +.br +Specifies an alternate username. +.TP 5 +-W which-jobs +.br +Specifies which jobs to show, \fIcompleted\fR or +\fInot-completed\fR (the default). This option \fImust\fR appear +before the \fI-o\fR option and/or any printer names, otherwise +the default (not-completed) value will be used in the request to +the scheduler. +.TP 5 +-a [printer(s)] +.br +Shows the accepting state of printer queues. If no printers are +specified then all printers are listed. +.TP 5 +-c [class(es)] +.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 server[:port] +.br +Specifies an alternate server. +.TP 5 +-l +.br +Shows a long listing of printers, classes, or jobs. +.TP 5 +-o [destination(s)] +.br +Shows the jobs queue on the specified destinations. If no destinations are +specified all jobs are shown. +.TP 5 +-p [printer(s)] +.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 the CUPS server is running. +.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 "-v" options. +.TP 5 +-t +.br +Shows all status information. This is equivalent to using the "-r", +"-d", "-c", "-v", "-a", "-p", and "-o" options. +.TP 5 +-u [user(s)] +.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 [printer(s)] +.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, TAB, "/", and "#". +Also, printer and class names are \fInot\fR case-sensitive. +.LP +The "-h", "-E", "-U", and "-W" options are unique to CUPS. +.LP +The Solaris "-f", "-P", and "-S" options are silently ignored. +.SH SEE ALSO +\fIcancel(1)\fR, \fIlp(1)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: lpstat.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/mailto.conf.man b/man/mailto.conf.man new file mode 100644 index 0000000000..8c62284eb8 --- /dev/null +++ b/man/mailto.conf.man @@ -0,0 +1,60 @@ +.\" +.\" "$Id: mailto.conf.man 8421 2009-03-09 21:59:55Z mike $" +.\" +.\" mailto.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 2007-2009 by Apple Inc. +.\" Copyright 1997-2006 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Apple Inc. 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 +.\" file is missing or damaged, see the license at "http://www.cups.org/". +.\" +.TH mailto.conf 5 "CUPS" "12 July 2006" "Apple Inc." +.SH NAME +mailto.conf \- configuration file for cups email notifier +.SH DESCRIPTION +The \fImailto.conf\fR file defines the local mail server and +email notification preferences for CUPS. +.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 +Cc \fIcc-address@domain.com\fR +.br +Specifies an additional recipient for all email notifications. +.TP 5 +From \fIfrom-address@domain.com\fR +.br +Specifies the sender of email notifications. +.TP 5 +Sendmail \fIsendmail command and options\fR +.br +Specifies the sendmail command to use when sending email +notifications. Only one \fISendmail\fR or \fISMTPServer\fR line +may be present in the \fImailto.conf\fR file. If multiple lines +are present, only the last one is used. +.TP 5 +SMTPServer \fIservername\fR +.br +Specifies a SMTP server to send email notifications to. Only one +\fISendmail\fR or \fISMTPServer\fR line may be present in the +\fImailto.conf\fR file. If multiple lines are present, only the +last one is used. +.TP 5 +Subject \fIsubject-prefix\fR +.br +Specifies a prefix string for the subject line of an email notification. +.SH SEE ALSO +\fIclasses.conf(5)\fR, \fIcupsd(8)\fR, \fIcupsd.conf(5)\fR, +\fImime.convs(5)\fR, \fImime.types(5)\fR, \fIprinters.conf(5)\fR, +.br +http://localhost:631/help +.SH COPYRIGHT +Copyright 2007-2009 by Apple Inc. +.\" +.\" End of "$Id: mailto.conf.man 8421 2009-03-09 21:59:55Z mike $". +.\" diff --git a/man/mantohtml.c b/man/mantohtml.c new file mode 100644 index 0000000000..7286fd1926 --- /dev/null +++ b/man/mantohtml.c @@ -0,0 +1,715 @@ +/* + * "$Id$" + * + * Man page to HTML conversion program. + * + * Copyright 2007-2009 by Apple Inc. + * Copyright 2004-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. 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 + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * Contents: + * + * main() - Convert a man page to HTML. + * putc_entity() - Put a single character, using entities as needed. + * strmove() - Move characters within a string. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include + + +/* + * Local functions... + */ + +static void putc_entity(int ch, FILE *fp); +static void strmove(char *d, const char *s); + + +/* + * 'main()' - Convert a man page to HTML. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line args */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *infile, /* Input file */ + *outfile; /* Output file */ + char line[1024], /* Line from file */ + *lineptr, /* Pointer into line */ + *endptr, /* Pointer to end of current */ + endchar, /* End character */ + *paren, /* Pointer to parenthesis */ + name[1024]; /* Man page name */ + int section, /* Man page section */ + pre, /* Preformatted */ + font, /* Current font */ + blist, /* In a bullet list? */ + list, /* In a list? */ + linenum; /* Current line number */ + const char *post; /* Text to add after the current line */ + static const char /* Start/end tags for fonts */ + * const start_fonts[] = { "", "", "" }, + * const end_fonts[] = { "", "", "" }; + + /* + * Check arguments... + */ + + if (argc > 3) + { + fputs("Usage: mantohtml [filename.man [filename.html]]\n", stderr); + return (1); + } + + /* + * Open files as needed... + */ + + if (argc > 1) + { + if ((infile = fopen(argv[1], "r")) == NULL) + { + perror(argv[1]); + return (1); + } + } + else + infile = stdin; + + if (argc > 2) + { + if ((outfile = fopen(argv[2], "w")) == NULL) + { + perror(argv[2]); + fclose(infile); + return (1); + } + } + else + outfile = stdout; + + /* + * Read from input and write the output... + */ + + fputs("\n" + "\n" + "\n" + "\n" + "\t\n", outfile); + + blist = 0; + font = 0; + list = 0; + linenum = 0; + pre = 0; + post = NULL; + section = -1; + + while (fgets(line, sizeof(line), infile)) + { + linenum ++; + + if (line[0] == '.') + { + /* + * Strip leading whitespace... + */ + + while (line[1] == ' ' || line[1] == '\t') + strmove(line + 1, line + 2); + + /* + * Process man page commands... + */ + + if (!strncmp(line, ".TH ", 4) && section < 0) + { + /* + * Grab man page title... + */ + + sscanf(line + 4, "%s%d", name, §ion); + + fprintf(outfile, + "\t%s(%d)\n" + "\n" + "\n" + "

%s(%d)

\n" + "%s", + name, section, name, section, start_fonts[font]); + } + else if (section < 0) + continue; + else if (!strncmp(line, ".SH ", 4) || !strncmp(line, ".SS ", 4)) + { + /* + * Grab heading... + */ + + int first = 1; + + fputs(end_fonts[font], outfile); + + if (blist) + { + fputs("\n\n", outfile); + blist = 0; + } + + if (list) + { + if (list == 1) + fputs("\n", outfile); + else if (list) + fputs("\n", outfile); + + fputs("\n", outfile); + list = 0; + } + + line[strlen(line) - 1] = '\0'; /* Strip LF */ + + if (line[2] == 'H') + fputs("

", outfile); + + for (lineptr = line + 4; *lineptr; lineptr ++) + if (*lineptr == '\"') + continue; + else if (*lineptr == ' ') + { + putc_entity(' ', outfile); + + first = 1; + } + else + { + if (first) + putc_entity(*lineptr, outfile); + else + putc_entity(tolower(*lineptr), outfile); + + first = 0; + } + + if (line[2] == 'H') + fprintf(outfile, "

\n%s", start_fonts[font]); + else + fprintf(outfile, "

Overview